Mercurial > hg > dmlib
comparison tools/gfxconv.c @ 1823:02f604264bc4
Improve C64 image format up/down conversion. Might actually work for some formats now.
author | Matti Hamalainen <ccr@tnsp.org> |
---|---|
date | Fri, 22 Jun 2018 12:21:54 +0300 |
parents | 4f141426eb31 |
children | 5639142e0b87 |
comparison
equal
deleted
inserted
replaced
1822:9bec535956fd | 1823:02f604264bc4 |
---|---|
979 DMC64Image *dst; | 979 DMC64Image *dst; |
980 | 980 |
981 if (pdst == NULL || dstFmt == NULL || src == NULL || srcFmt == NULL) | 981 if (pdst == NULL || dstFmt == NULL || src == NULL || srcFmt == NULL) |
982 return DMERR_NULLPTR; | 982 return DMERR_NULLPTR; |
983 | 983 |
984 // Allocate the destination image | |
984 if ((dst = *pdst = dmC64ImageAlloc(dstFmt)) == NULL) | 985 if ((dst = *pdst = dmC64ImageAlloc(dstFmt)) == NULL) |
985 return DMERR_MALLOC; | 986 return DMERR_MALLOC; |
986 | 987 |
987 if (src->type == dst->type) | 988 // Copy rest of the structure .. |
988 { | 989 dst->d020 = src->d020; |
990 dst->bgcolor = src->bgcolor; | |
991 dst->d022 = src->d022; | |
992 dst->d023 = src->d023; | |
993 dst->d024 = src->d024; | |
994 | |
995 // Do per opcode copies | |
996 for (int i = 0; i < D64_MAX_ENCDEC_OPS; i++) | |
997 { | |
998 const DMC64EncDecOp *op = fmtGetEncDecOp(dstFmt, i); | |
999 DMC64MemBlock *srcBlk = NULL, *dstBlk = NULL; | |
1000 char *blkname = NULL; | |
1001 size_t size; | |
1002 | |
1003 if (op->type == DO_LAST) | |
1004 break; | |
1005 | |
1006 dmC64GetOpSize(op, dstFmt, &size); | |
1007 switch (op->type) | |
1008 { | |
1009 case DO_COPY: | |
1010 case DO_SET_MEM: | |
1011 case DO_SET_MEM_HI: | |
1012 case DO_SET_MEM_LO: | |
1013 case DO_SET_OP: | |
1014 dmC64GetOpMemBlockAndName(src, op->subject, op->bank, (const DMC64MemBlock **) &srcBlk, &blkname); | |
1015 dmC64GetOpMemBlockAndName(dst, op->subject, op->bank, (const DMC64MemBlock **) &dstBlk, &blkname); | |
1016 if (srcBlk != NULL && srcBlk->data != NULL && srcBlk->size >= size) | |
1017 { | |
1018 // The block exists in source and is of sufficient size, so copy it | |
1019 dmMsg(2, "Copying block '%s' op #%d, offs=%d ($%04x), bank=%d, size=%d ($%04x)\n", | |
1020 blkname, i, op->offs, op->offs, op->bank, size, size); | |
1021 dmC64MemBlockCopy(dstBlk, srcBlk); | |
1022 } | |
1023 else | |
1024 switch (op->subject) | |
1025 { | |
1026 case DS_COLOR_RAM: | |
1027 case DS_SCREEN_RAM: | |
1028 case DS_BITMAP_RAM: | |
1029 case DS_CHAR_DATA: | |
1030 case DS_EXTRA_DATA: | |
1031 if ((dmC64MemBlockAlloc(dstBlk, size)) != DMERR_OK) | |
1032 { | |
1033 return dmError(DMERR_MALLOC, | |
1034 "Could not allocate '%s' block! " | |
1035 "op #%d, offs=%d ($%04x), bank=%d, size=%d ($%04x)\n", | |
1036 blkname, i, op->offs, op->offs, op->bank, size, size); | |
1037 } | |
1038 if (srcBlk->data == NULL) | |
1039 { | |
1040 dmMsg(2, "Creating block '%s' op #%d, offs=%d ($%04x), bank=%d, size=%d ($%04x)\n", | |
1041 blkname, i, op->offs, op->offs, op->bank, size, size); | |
1042 } | |
1043 switch (op->type) | |
1044 { | |
1045 case DO_COPY: | |
1046 // If some data exists, copy it. Rest is zero. | |
1047 // Otherwise just set to zero. | |
1048 if (srcBlk->data != NULL) | |
1049 memcpy(dstBlk->data, srcBlk->data, srcBlk->size); | |
1050 break; | |
1051 | |
1052 case DO_SET_MEM: | |
1053 // Leave allocate data to zero. | |
1054 break; | |
1055 | |
1056 case DO_SET_OP: | |
1057 dmMemset(dstBlk->data, op->offs, size); | |
1058 break; | |
1059 | |
1060 default: | |
1061 return dmError(DMERR_INTERNAL, | |
1062 "Unhandled op type %d in " | |
1063 "op #%d, offs=%d ($%04x), bank=%d, size=%d ($%04x) @ %d ($%04x)\n", | |
1064 op->type, i, op->offs, op->offs, op->bank, size, size); | |
1065 } | |
1066 break; | |
1067 } | |
1068 break; | |
1069 } | |
1070 } | |
1071 | |
1072 // Try to do some simple fixups | |
1073 if ((dst->type & D64_FMT_FLI) && (src->type & D64_FMT_FLI) == 0) | |
1074 { | |
1075 dmMsg(1, "Upconverting multicolor to FLI.\n"); | |
989 for (int i = 0; i < dst->nbanks; i++) | 1076 for (int i = 0; i < dst->nbanks; i++) |
990 { | 1077 { |
991 dmC64MemBlockCopy(&dst->color[i], &src->color[i]); | 1078 dmC64MemBlockCopy(&dst->color[i], &src->color[0]); |
992 dmC64MemBlockCopy(&dst->screen[i], &src->screen[i]); | 1079 dmC64MemBlockCopy(&dst->screen[i], &src->screen[0]); |
993 dmC64MemBlockCopy(&dst->bitmap[i], &src->bitmap[i]); | 1080 dmC64MemBlockCopy(&dst->bitmap[i], &src->bitmap[0]); |
994 } | 1081 } |
995 } | 1082 } |
996 else | 1083 else |
997 { | 1084 if ((src->type & D64_FMT_FLI) && (dst->type & D64_FMT_FLI) == 0) |
998 // Try to do some simple fixups | 1085 { |
999 if ((dst->type & D64_FMT_FLI) && (src->type & D64_FMT_FLI) == 0) | 1086 dmMsg(1, "Downconverting FLI to multicolor.\n"); |
1000 { | |
1001 dmMsg(1, "Upconverting multicolor to FLI.\n"); | |
1002 for (int i = 0; i < dst->nbanks; i++) | |
1003 { | |
1004 dmC64MemBlockCopy(&dst->color[i], &src->color[0]); | |
1005 dmC64MemBlockCopy(&dst->screen[i], &src->screen[0]); | |
1006 dmC64MemBlockCopy(&dst->bitmap[i], &src->bitmap[0]); | |
1007 } | |
1008 } | |
1009 | |
1010 for (int i = 0; i < D64_MAX_ENCDEC_OPS; i++) | |
1011 { | |
1012 const DMC64EncDecOp *op = fmtGetEncDecOp(dstFmt, i); | |
1013 size_t size; | |
1014 | |
1015 // Check for last operator | |
1016 if (op->type == DO_LAST) | |
1017 break; | |
1018 | |
1019 // Check size | |
1020 if (!dmC64GetOpSize(op, dstFmt, &size)) | |
1021 return DMERR_INVALID_DATA; | |
1022 | |
1023 // Perform operation | |
1024 switch (op->type) | |
1025 { | |
1026 case DO_COPY: | |
1027 switch (op->subject) | |
1028 { | |
1029 case DS_EXTRA_DATA: | |
1030 dmC64MemBlockAlloc(&dst->extraData[op->bank], size); | |
1031 break; | |
1032 } | |
1033 break; | |
1034 } | |
1035 } | |
1036 } | 1087 } |
1037 | 1088 |
1038 return DMERR_OK; | 1089 return DMERR_OK; |
1039 } | 1090 } |
1040 | 1091 |