Mercurial > hg > dmlib
changeset 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 | 9bec535956fd |
children | adf9f05c26e1 |
files | tools/gfxconv.c |
diffstat | 1 files changed, 93 insertions(+), 42 deletions(-) [+] |
line wrap: on
line diff
--- a/tools/gfxconv.c Fri Jun 22 12:20:46 2018 +0300 +++ b/tools/gfxconv.c Fri Jun 22 12:21:54 2018 +0300 @@ -981,58 +981,109 @@ if (pdst == NULL || dstFmt == NULL || src == NULL || srcFmt == NULL) return DMERR_NULLPTR; + // Allocate the destination image if ((dst = *pdst = dmC64ImageAlloc(dstFmt)) == NULL) return DMERR_MALLOC; - if (src->type == dst->type) + // Copy rest of the structure .. + dst->d020 = src->d020; + dst->bgcolor = src->bgcolor; + dst->d022 = src->d022; + dst->d023 = src->d023; + dst->d024 = src->d024; + + // Do per opcode copies + for (int i = 0; i < D64_MAX_ENCDEC_OPS; i++) { + const DMC64EncDecOp *op = fmtGetEncDecOp(dstFmt, i); + DMC64MemBlock *srcBlk = NULL, *dstBlk = NULL; + char *blkname = NULL; + size_t size; + + if (op->type == DO_LAST) + break; + + dmC64GetOpSize(op, dstFmt, &size); + switch (op->type) + { + case DO_COPY: + case DO_SET_MEM: + case DO_SET_MEM_HI: + case DO_SET_MEM_LO: + case DO_SET_OP: + dmC64GetOpMemBlockAndName(src, op->subject, op->bank, (const DMC64MemBlock **) &srcBlk, &blkname); + dmC64GetOpMemBlockAndName(dst, op->subject, op->bank, (const DMC64MemBlock **) &dstBlk, &blkname); + if (srcBlk != NULL && srcBlk->data != NULL && srcBlk->size >= size) + { + // The block exists in source and is of sufficient size, so copy it + dmMsg(2, "Copying block '%s' op #%d, offs=%d ($%04x), bank=%d, size=%d ($%04x)\n", + blkname, i, op->offs, op->offs, op->bank, size, size); + dmC64MemBlockCopy(dstBlk, srcBlk); + } + else + switch (op->subject) + { + case DS_COLOR_RAM: + case DS_SCREEN_RAM: + case DS_BITMAP_RAM: + case DS_CHAR_DATA: + case DS_EXTRA_DATA: + if ((dmC64MemBlockAlloc(dstBlk, size)) != DMERR_OK) + { + return dmError(DMERR_MALLOC, + "Could not allocate '%s' block! " + "op #%d, offs=%d ($%04x), bank=%d, size=%d ($%04x)\n", + blkname, i, op->offs, op->offs, op->bank, size, size); + } + if (srcBlk->data == NULL) + { + dmMsg(2, "Creating block '%s' op #%d, offs=%d ($%04x), bank=%d, size=%d ($%04x)\n", + blkname, i, op->offs, op->offs, op->bank, size, size); + } + switch (op->type) + { + case DO_COPY: + // If some data exists, copy it. Rest is zero. + // Otherwise just set to zero. + if (srcBlk->data != NULL) + memcpy(dstBlk->data, srcBlk->data, srcBlk->size); + break; + + case DO_SET_MEM: + // Leave allocate data to zero. + break; + + case DO_SET_OP: + dmMemset(dstBlk->data, op->offs, size); + break; + + default: + return dmError(DMERR_INTERNAL, + "Unhandled op type %d in " + "op #%d, offs=%d ($%04x), bank=%d, size=%d ($%04x) @ %d ($%04x)\n", + op->type, i, op->offs, op->offs, op->bank, size, size); + } + break; + } + break; + } + } + + // Try to do some simple fixups + if ((dst->type & D64_FMT_FLI) && (src->type & D64_FMT_FLI) == 0) + { + dmMsg(1, "Upconverting multicolor to FLI.\n"); for (int i = 0; i < dst->nbanks; i++) { - dmC64MemBlockCopy(&dst->color[i], &src->color[i]); - dmC64MemBlockCopy(&dst->screen[i], &src->screen[i]); - dmC64MemBlockCopy(&dst->bitmap[i], &src->bitmap[i]); + dmC64MemBlockCopy(&dst->color[i], &src->color[0]); + dmC64MemBlockCopy(&dst->screen[i], &src->screen[0]); + dmC64MemBlockCopy(&dst->bitmap[i], &src->bitmap[0]); } } else + if ((src->type & D64_FMT_FLI) && (dst->type & D64_FMT_FLI) == 0) { - // Try to do some simple fixups - if ((dst->type & D64_FMT_FLI) && (src->type & D64_FMT_FLI) == 0) - { - dmMsg(1, "Upconverting multicolor to FLI.\n"); - for (int i = 0; i < dst->nbanks; i++) - { - dmC64MemBlockCopy(&dst->color[i], &src->color[0]); - dmC64MemBlockCopy(&dst->screen[i], &src->screen[0]); - dmC64MemBlockCopy(&dst->bitmap[i], &src->bitmap[0]); - } - } - - for (int i = 0; i < D64_MAX_ENCDEC_OPS; i++) - { - const DMC64EncDecOp *op = fmtGetEncDecOp(dstFmt, i); - size_t size; - - // Check for last operator - if (op->type == DO_LAST) - break; - - // Check size - if (!dmC64GetOpSize(op, dstFmt, &size)) - return DMERR_INVALID_DATA; - - // Perform operation - switch (op->type) - { - case DO_COPY: - switch (op->subject) - { - case DS_EXTRA_DATA: - dmC64MemBlockAlloc(&dst->extraData[op->bank], size); - break; - } - break; - } - } + dmMsg(1, "Downconverting FLI to multicolor.\n"); } return DMERR_OK;