Mercurial > hg > dmlib
diff tools/lib64gfx.c @ 1668:1741717b1ae5
Big overhaul to the enc/dec operator system to be more flexible.
author | Matti Hamalainen <ccr@tnsp.org> |
---|---|
date | Thu, 31 May 2018 00:04:01 +0300 |
parents | 7555c8803529 |
children | 09adf5328510 |
line wrap: on
line diff
--- a/tools/lib64gfx.c Wed May 30 21:10:57 2018 +0300 +++ b/tools/lib64gfx.c Thu May 31 00:04:01 2018 +0300 @@ -89,7 +89,7 @@ for (int i = 0; i < D64_MAX_ENCDEC_OPS; i++) { const DMC64EncDecOp *op = fmtGetEncDecOp(fmt, i); - if (op->type == DT_LAST) + if (op->type == DO_LAST) break; if (op->bank > nbanks) @@ -603,33 +603,46 @@ { switch (op->type) { - case DT_COLOR_RAM: - case DT_BITMAP_RAM: - case DT_SCREEN_RAM: - case DT_CHAR_DATA: - if (op->bank < 0 || op->bank > img->nbanks) + case DO_COPY: + case DO_SET_MEM: + case DO_SET_OP: + switch (op->subject) { - return dmError(DMERR_INTERNAL, - "Invalid bank %d / %d definition in generic encode/decode operator %d @ #%d.\n", - op->bank, img->nbanks, op->type, i); + case DS_COLOR_RAM: + case DS_BITMAP_RAM: + case DS_SCREEN_RAM: + case DS_CHAR_DATA: + if (op->bank < 0 || op->bank > img->nbanks) + { + return dmError(DMERR_INTERNAL, + "Invalid bank %d / %d definition in generic encode/decode operator %d @ #%d.\n", + op->bank, img->nbanks, op->type, i); + } + break; + + case DS_EXTRA_DATA: + if (op->bank < 0 || op->bank >= C64_MAX_EXTRA_DATA) + { + return dmError(DMERR_INTERNAL, + "Invalid bank %d definition in generic encode/decode operator %d @ #%d.\n", + op->bank, op->type, i); + } + break; } break; - case DT_EXTRA_DATA: - if (op->bank < 0 || op->bank >= C64_MAX_EXTRA_DATA) - { - return dmError(DMERR_INTERNAL, - "Invalid bank %d definition in generic encode/decode operator %d @ #%d.\n", - op->bank, op->type, i); - } + // Just list the allowed ops here + case DO_DEC_FUNC: + case DO_ENC_FUNC: + case DO_CHAR_CFG: + case DO_LAST: break; - } - if (op->type < 0 || op->type >= DT_LAST) - { - return dmError(DMERR_INTERNAL, - "Invalid encode/decode operator type %d @ #%d.\n", - op->type, i); + default: + return dmError(DMERR_INTERNAL, + "Invalid op type %d in generic encode/decode operator @ #%d.\n", + op->type, i); + break; } return DMERR_OK; @@ -638,33 +651,38 @@ BOOL dmC64GetOpSize(const DMC64EncDecOp *op, const DMC64ImageFormat *fmt, size_t *size) { + // Default to size of 0 + *size = 0; + switch (op->type) { - case DT_SCREEN_RAM: - case DT_COLOR_RAM: - *size = fmt->chHeight * fmt->chWidth; - break; + case DO_COPY: + case DO_SET_MEM: + case DO_SET_OP: + switch (op->subject) + { + case DS_SCREEN_RAM: + case DS_COLOR_RAM: + *size = fmt->chHeight * fmt->chWidth; + break; - case DT_BITMAP_RAM: - *size = fmt->chHeight * fmt->chWidth * 8; - break; - - case DT_CHAR_DATA: - *size = C64_MAX_CHARS * C64_CHR_SIZE; - break; + case DS_BITMAP_RAM: + *size = fmt->chHeight * fmt->chWidth * 8; + break; - case DT_COLOR_REG: - *size = 1; - break; + case DS_CHAR_DATA: + *size = C64_MAX_CHARS * C64_CHR_SIZE; + break; - case DT_DEC_FUNCTION: - case DT_ENC_FUNCTION: - case DT_EXTRA_DATA: - *size = op->size; - break; - - default: - *size = 0; + case DS_D020: + case DS_BGCOL: + case DS_D021: + case DS_D022: + case DS_D023: + case DS_D024: + *size = 1; + break; + } } // If the operator specified size is larger, use it. @@ -675,6 +693,20 @@ } +void dmC64GetOpMemBlockAndName(const DMC64Image *img, const int subject, const int bank, const DMC64MemBlock **blk, char **blkname) +{ + switch (subject) + { + case DS_COLOR_RAM : *blk = &img->color[bank]; *blkname = "Color RAM"; break; + case DS_SCREEN_RAM : *blk = &img->screen[bank]; *blkname = "Screen RAM"; break; + case DS_BITMAP_RAM : *blk = &img->bitmap[bank]; *blkname = "Bitmap RAM"; break; + case DS_CHAR_DATA : *blk = &img->charData[bank]; *blkname = "Character data"; break; + case DS_EXTRA_DATA : *blk = &img->extraData[bank]; *blkname = "Extra data"; break; + default: *blk = NULL; *blkname = NULL; break; + } +} + + int dmC64DecodeGenericBMP(DMC64Image *img, const Uint8 *buf, const size_t len, const DMC64ImageFormat *fmt) { @@ -699,9 +731,10 @@ DMC64MemBlock *blk = NULL; char *blkname = NULL; size_t size; + Uint8 value; // Check for last operator - if (op->type == DT_LAST) + if (op->type == DO_LAST) break; // Check operation validity @@ -712,18 +745,18 @@ if (!dmC64GetOpSize(op, fmt, &size)) { return dmError(DMERR_INVALID_DATA, - "Decode op SIZE out of bounds, op #%d type=%d, offs=%d ($%04x), " + "Decode op SIZE out of bounds, op #%d type=%d, subj=%d, offs=%d ($%04x), " "bank=%d, size=%d ($%04x) vs. allocated %d ($%04x)\n", - i, op->type, op->offs, op->offs, op->bank, size, size, op->size, op->size); + i, op->type, op->subject, op->offs, op->offs, op->bank, size, size, op->size, op->size); } // Is the operation inside the bounds? if (op->offs + size > len + 1) { return dmError(DMERR_INVALID_DATA, - "Decode DATA out of bounds, op #%d type=%d, offs=%d ($%04x), " + "Decode DATA out of bounds, op #%d type=%d, subj=%d, offs=%d ($%04x), " "bank=%d, size=%d ($%04x) @ %d ($%04x)\n", - i, op->type, op->offs, op->offs, op->bank, size, size, len, len); + i, op->type, op->subject, op->offs, op->offs, op->bank, size, size, len, len); } src = buf + op->offs; @@ -731,65 +764,80 @@ // Perform operation switch (op->type) { - case DT_COLOR_RAM: - case DT_SCREEN_RAM: - case DT_BITMAP_RAM: - case DT_CHAR_DATA: - case DT_EXTRA_DATA: - switch (op->type) - { - case DT_COLOR_RAM : blk = &img->color[op->bank]; blkname = "Color RAM"; break; - case DT_SCREEN_RAM : blk = &img->screen[op->bank]; blkname = "Screen RAM"; break; - case DT_BITMAP_RAM : blk = &img->bitmap[op->bank]; blkname = "Bitmap RAM"; break; - case DT_CHAR_DATA : blk = &img->charData[op->bank]; blkname = "Character data"; break; - case DT_EXTRA_DATA : blk = &img->extraData[op->bank]; blkname = "Extra data"; break; - } - if ((dmC64MemBlockAlloc(blk, size)) != DMERR_OK) + case DO_COPY: + case DO_SET_MEM: + case DO_SET_OP: + switch (op->subject) { - return dmError(DMERR_MALLOC, - "Could not allocate '%s' block! " - "op #%d, offs=%d ($%04x), bank=%d, size=%d ($%04x) @ %d ($%04x)\n", - blkname, i, op->offs, op->offs, op->bank, size, size, len, len); - } - memcpy(blk->data, src, size); - break; + case DS_COLOR_RAM: + case DS_SCREEN_RAM: + case DS_BITMAP_RAM: + case DS_CHAR_DATA: + case DS_EXTRA_DATA: + // XXX BZZZT .. a nasty cast here --v + dmC64GetOpMemBlockAndName(img, op->subject, op->bank, (const DMC64MemBlock **) &blk, &blkname); + if ((dmC64MemBlockAlloc(blk, size)) != DMERR_OK) + { + return dmError(DMERR_MALLOC, + "Could not allocate '%s' block! " + "op #%d, offs=%d ($%04x), bank=%d, size=%d ($%04x) @ %d ($%04x)\n", + blkname, i, op->offs, op->offs, op->bank, size, size, len, len); + } + switch (op->type) + { + case DO_COPY: + memcpy(blk->data, src, size); + break; + + case DO_SET_MEM: + memset(blk->data, *src, size); + break; + + case DO_SET_OP: + memset(blk->data, op->offs, size); + break; + } + break; - case DT_COLOR_REG: - switch (op->size) - { - case DC_D020: img->d020 = *src; break; - case DC_BGCOL: - case DC_D021: img->bgcolor = *src; break; - case DC_D022: img->d022 = *src; break; - case DC_D023: img->d023 = *src; break; - case DC_D024: img->d024 = *src; break; + case DS_D020: + case DS_BGCOL: + case DS_D021: + case DS_D022: + case DS_D023: + case DS_D024: + switch (op->type) + { + case DO_COPY: + case DO_SET_MEM: + value = *src; + break; + + case DO_SET_OP: + value = op->offs; + break; + + } + switch (op->subject) + { + case DS_D020: img->d020 = value; break; + case DS_BGCOL: + case DS_D021: img->bgcolor = value; break; + case DS_D022: img->d022 = value; break; + case DS_D023: img->d023 = value; break; + case DS_D024: img->d024 = value; break; + } + break; + default: return dmError(DMERR_INTERNAL, - "Unhandled DT_COLOR_REG mode %d in " + "Unhandled subject %d in " "op #%d, offs=%d ($%04x), bank=%d, size=%d ($%04x) @ %d ($%04x)\n", - op->size, i, op->offs, op->offs, op->bank, size, size, len, len); + op->subject, i, op->offs, op->offs, op->bank, size, size, len, len); } break; - case DT_COLOR_SET: - switch (op->size) - { - case DC_D020: img->d020 = op->offs; break; - case DC_BGCOL: - case DC_D021: img->bgcolor = op->offs; break; - case DC_D022: img->d022 = op->offs; break; - case DC_D023: img->d023 = op->offs; break; - case DC_D024: img->d024 = op->offs; break; - default: - return dmError(DMERR_INTERNAL, - "Unhandled DT_COLOR_SET mode %d in " - "op #%d, offs=%d ($%04x), bank=%d, size=%d ($%04x) @ %d ($%04x)\n", - op->size, i, op->offs, op->offs, op->bank, size, size, len, len); - } - break; - - case DT_CHAR_CONFIG: - switch (op->offs) + case DO_CHAR_CFG: + switch (op->subject) { case D64_CHCFG_SCREEN: break; @@ -804,13 +852,13 @@ default: return dmError(DMERR_INTERNAL, - "Unhandled DT_CHAR_CONFIG mode %d in ", + "Unhandled DO_CHAR_CFG mode %d in ", "op #%d, bank=%d, size=%d ($%04x) @ %d ($%04x)\n", - op->offs, i, op->bank, size, size, len, len); + op->subject, i, op->bank, size, size, len, len); } break; - case DT_DEC_FUNCTION: + case DO_DEC_FUNC: if (op->decFunction == NULL) { return dmError(DMERR_INTERNAL, @@ -866,9 +914,10 @@ size_t size, chksize; const DMC64MemBlock *blk = NULL; char *blkname = NULL; + Uint8 value; // Check for last operator - if (op->type == DT_LAST) + if (op->type == DO_LAST) break; // Check operation validity @@ -899,60 +948,98 @@ buf->len = chksize; // Perform operation - Uint8 *dst = buf->data + op->offs; + Uint8 *dst; + dst = buf->data + op->offs; switch (op->type) { - case DT_COLOR_RAM: - case DT_SCREEN_RAM: - case DT_BITMAP_RAM: - case DT_CHAR_DATA: - case DT_EXTRA_DATA: - switch (op->type) - { - case DT_COLOR_RAM : blk = &img->color[op->bank]; blkname = "Color RAM"; break; - case DT_SCREEN_RAM : blk = &img->screen[op->bank]; blkname = "Screen RAM"; break; - case DT_BITMAP_RAM : blk = &img->bitmap[op->bank]; blkname = "Bitmap RAM"; break; - case DT_CHAR_DATA : blk = &img->charData[op->bank]; blkname = "Character data"; break; - case DT_EXTRA_DATA : blk = &img->extraData[op->bank]; blkname = "Extra data"; break; - } - if (blk->data == NULL) - { - res = dmError(DMERR_NULLPTR, - "'%s' block is NULL in " - "op #%d, offs=%d ($%04x), bank=%d, size=%d ($%04x) @ %d ($%04x)\n", - blkname, i, op->offs, op->offs, op->bank, size, size, buf->len, buf->len); - goto err; - } - if (size > blk->size) + case DO_COPY: + case DO_SET_MEM: + case DO_SET_OP: + switch (op->subject) { - res = dmError(DMERR_INTERNAL, - "'%s' size mismatch %d <> %d in " - "op #%d, offs=%d ($%04x), bank=%d, size=%d ($%04x) @ %d ($%04x)\n", - blkname, op->size, blk->size, i, op->offs, op->offs, op->bank, size, size, buf->len, buf->len); - goto err; - } - memcpy(dst, blk->data, size); - break; + case DS_COLOR_RAM: + case DS_SCREEN_RAM: + case DS_BITMAP_RAM: + case DS_CHAR_DATA: + case DS_EXTRA_DATA: + dmC64GetOpMemBlockAndName(img, op->subject, op->bank, &blk, &blkname); + if (blk->data == NULL) + { + res = dmError(DMERR_NULLPTR, + "'%s' block is NULL in " + "op #%d, offs=%d ($%04x), bank=%d, size=%d ($%04x) @ %d ($%04x)\n", + blkname, i, op->offs, op->offs, op->bank, size, size, buf->len, buf->len); + goto err; + } + if (size > blk->size) + { + res = dmError(DMERR_INTERNAL, + "'%s' size mismatch %d <> %d in " + "op #%d, offs=%d ($%04x), bank=%d, size=%d ($%04x) @ %d ($%04x)\n", + blkname, op->size, blk->size, i, op->offs, op->offs, op->bank, size, size, buf->len, buf->len); + goto err; + } + switch (op->type) + { + case DO_COPY: + memcpy(dst, blk->data, size); + break; + + case DO_SET_MEM: + // This operation makes no sense + res = dmError(DMERR_INTERNAL, + "'%s' block DO_SET_MEM (which makes no sense) in " + "op #%d, offs=%d ($%04x), bank=%d, size=%d ($%04x) @ %d ($%04x)\n", + blkname, op->size, blk->size, i, op->offs, op->offs, op->bank, size, size, buf->len, buf->len); + goto err; - case DT_COLOR_REG: - switch (op->size) - { - case DC_D020: *dst = img->d020; break; - case DC_BGCOL: - case DC_D021: *dst = img->bgcolor; break; - case DC_D022: *dst = img->d022; break; - case DC_D023: *dst = img->d023; break; - case DC_D024: *dst = img->d024; break; + case DO_SET_OP: + memset(dst, op->offs, size); + break; + } + break; + + case DS_D020: + case DS_BGCOL: + case DS_D021: + case DS_D022: + case DS_D023: + case DS_D024: + switch (op->subject) + { + case DS_D020: value = img->d020; break; + case DS_BGCOL: + case DS_D021: value = img->bgcolor; break; + case DS_D022: value = img->d022; break; + case DS_D023: value = img->d023; break; + case DS_D024: value = img->d024; break; + } + switch (op->type) + { + case DO_COPY: + case DO_SET_MEM: + *dst = value; + break; + + case DO_SET_OP: + // This operation makes no sense + res = dmError(DMERR_INTERNAL, + "'%s' block DO_SET_OP (which makes no sense) in " + "op #%d, offs=%d ($%04x), bank=%d, size=%d ($%04x) @ %d ($%04x)\n", + blkname, op->size, blk->size, i, op->offs, op->offs, op->bank, size, size, buf->len, buf->len); + goto err; + } + break; + default: - res = dmError(DMERR_INTERNAL, - "Unhandled DT_COLOR_REG mode %d in " + return dmError(DMERR_INTERNAL, + "Unhandled subject %d in " "op #%d, offs=%d ($%04x), bank=%d, size=%d ($%04x) @ %d ($%04x)\n", - op->size, i, op->offs, op->offs, op->bank, size, size, buf->len, buf->len); - goto err; + op->subject, i, op->offs, op->offs, op->bank, size, size, buf->len, buf->len); } break; - case DT_ENC_FUNCTION: + case DO_ENC_FUNC: if (op->encFunction == NULL) { res = dmError(DMERR_INTERNAL,