From 76ffdf36776044b0ce4e467462336cb68edc65b1 Mon Sep 17 00:00:00 2001 From: Scott Duensing Date: Fri, 19 Jan 2024 20:17:23 -0600 Subject: [PATCH] Some reorganizing. imageconvert sprite support started. --- .gitignore | 5 +- build-tools.sh | 14 +- examples/cube-pre/build.sh | 2 +- examples/cube/build.sh | 2 +- examples/kuptest/build.sh | 2 +- examples/lines/build.sh | 2 +- examples/pgztest/build.sh | 2 +- examples/tilemap/build.sh | 2 +- examples/tilemap/makemap.c | 21 +- f256lib/sprite.c | 32 ++- imageconvert/imageconvert.c | 167 --------------- {header => tools/header}/header.c | 13 +- tools/imageconvert/imageconvert.c | 236 +++++++++++++++++++++ {imageconvert => tools/shared}/stb_image.h | 0 tools/shared/util.c | 91 ++++++++ tools/shared/util.h | 43 ++++ 16 files changed, 418 insertions(+), 216 deletions(-) delete mode 100644 imageconvert/imageconvert.c rename {header => tools/header}/header.c (97%) create mode 100644 tools/imageconvert/imageconvert.c rename {imageconvert => tools/shared}/stb_image.h (100%) create mode 100644 tools/shared/util.c create mode 100644 tools/shared/util.h diff --git a/.gitignore b/.gitignore index 69a62e8..aba9957 100644 --- a/.gitignore +++ b/.gitignore @@ -12,6 +12,7 @@ software/ *.elf *.lst *.hex +*.sym *.o makemap @@ -36,8 +37,8 @@ skia/ aseprite/ aseprite-source/ intelFPGA_lite/ -header/header -imageconvert/imageconvert +/header +/imageconvert include/ # Dumb QtCreator junk diff --git a/build-tools.sh b/build-tools.sh index 7afd6ad..05d0321 100755 --- a/build-tools.sh +++ b/build-tools.sh @@ -22,12 +22,16 @@ # SOFTWARE. # - -pushd header - cc header.c -o header -lm +pushd tools/shared + cc -c util.c popd -pushd imageconvert - cc imageconvert.c -o imageconvert -lm +pushd tools/header + cc header.c ../shared/util.o -o ../../header -lm +popd + + +pushd tools/imageconvert + cc imageconvert.c ../shared/util.o -o ../../imageconvert -lm popd diff --git a/examples/cube-pre/build.sh b/examples/cube-pre/build.sh index 0b5ef2d..a438691 100755 --- a/examples/cube-pre/build.sh +++ b/examples/cube-pre/build.sh @@ -41,7 +41,7 @@ ${CLANG} -o ${PROJECT} ${PROJECT}.o f256.o mv -f ${PROJECT} ${PROJECT}.bin -${F256}/header/header \ +${F256}/header \ pgz 24 \ ${PROJECT}.pgz \ ${START} \ diff --git a/examples/cube/build.sh b/examples/cube/build.sh index 640e977..b3573b0 100755 --- a/examples/cube/build.sh +++ b/examples/cube/build.sh @@ -42,7 +42,7 @@ ${CLANG} -o ${PROJECT} ${PROJECT}.o f256.o mv -f ${PROJECT} ${PROJECT}.bin -${F256}/header/header \ +${F256}/header \ pgz 24 \ ${PROJECT}.pgz \ ${START} \ diff --git a/examples/kuptest/build.sh b/examples/kuptest/build.sh index 486a5fa..f85b4a7 100755 --- a/examples/kuptest/build.sh +++ b/examples/kuptest/build.sh @@ -34,7 +34,7 @@ echo "__f256_start = ${START};" > ${SETTINGS} mos-f256k-clang -o kuptest -Os kuptest.c mv -f kuptest kuptest.bin -${F256}/header/header \ +${F256}/header \ kup \ kuptest.bin kuptest.kup \ 1 ${START} \ diff --git a/examples/lines/build.sh b/examples/lines/build.sh index 755e1b5..ae81392 100755 --- a/examples/lines/build.sh +++ b/examples/lines/build.sh @@ -41,7 +41,7 @@ ${CLANG} -o ${PROJECT} ${PROJECT}.o f256.o mv -f ${PROJECT} ${PROJECT}.bin -${F256}/header/header \ +${F256}/header \ pgz 24 \ ${PROJECT}.pgz \ ${START} \ diff --git a/examples/pgztest/build.sh b/examples/pgztest/build.sh index 440b54a..6fb15f9 100755 --- a/examples/pgztest/build.sh +++ b/examples/pgztest/build.sh @@ -41,7 +41,7 @@ ${CLANG} -o ${PROJECT} ${PROJECT}.o f256.o mv -f ${PROJECT} ${PROJECT}.bin -${F256}/header/header \ +${F256}/header \ pgz 24 \ ${PROJECT}.pgz \ ${START} \ diff --git a/examples/tilemap/build.sh b/examples/tilemap/build.sh index 8f59461..4d8df97 100755 --- a/examples/tilemap/build.sh +++ b/examples/tilemap/build.sh @@ -41,7 +41,7 @@ ${CLANG} -o ${PROJECT} ${PROJECT}.o f256.o mv -f ${PROJECT} ${PROJECT}.bin -${F256}/header/header \ +${F256}/header \ pgz 24 \ ${PROJECT}.pgz \ ${START} \ diff --git a/examples/tilemap/makemap.c b/examples/tilemap/makemap.c index f84a9e2..80c7b5b 100644 --- a/examples/tilemap/makemap.c +++ b/examples/tilemap/makemap.c @@ -38,24 +38,7 @@ #include #include - -char *replaceExtension(char *org, char *new_ext) { - char *ext; - char *tmp = strdup(org); - size_t newSize; - char *newName; - - ext = strrchr(tmp , '.'); - if (ext) *ext = 0; - - newSize = strlen(tmp) + strlen(new_ext) + 1; - newName = malloc(newSize); - sprintf(newName, "%s%s", tmp, new_ext); - - free(tmp); - - return newName; -} +#include "../../tools/shared/util.h" int main(int argc, char *argv[]) { @@ -78,7 +61,7 @@ int main(int argc, char *argv[]) { return 2; } - filename = replaceExtension(argv[1], ".tiles"); + filename = utilReplaceExtension(argv[1], ".tiles"); printf("Creating %s...\n", filename); out = fopen(filename, "wb"); if (out == NULL) { diff --git a/f256lib/sprite.c b/f256lib/sprite.c index 5dba3d7..4103bbe 100644 --- a/f256lib/sprite.c +++ b/f256lib/sprite.c @@ -29,16 +29,36 @@ #define OFF_SPR_POS_Y_L 6 -void spriteDefine(byte s, uint32_t address, byte size, byte CLUT, byte layer) { - uint16_t sprite = VKY_SP0_CTRL + (s << 3); +static byte _spriteCtl[64]; - POKE(sprite, (size << 5) | (layer << 3) | (CLUT << 1)); + +void spriteDefine(byte s, uint32_t address, byte size, byte CLUT, byte layer) { + uint16_t sprite = VKY_SP0_CTRL + (s * 8); + byte sz; + + switch (size) { + case 8: + sz = 3; + break; + case 16: + sz = 2; + break; + case 24: + sz = 1; + break; + case 32: + sz = 0; + break; + } + + _spriteCtl[s] = (sz << 5) | (layer << 3) | (CLUT << 1); + POKE(sprite, _spriteCtl[s]); POKEA(sprite + OFF_SPR_ADL_L, address); } void spriteSetPosition(byte s, uint16_t x, uint16_t y) { - uint16_t sprite = VKY_SP0_CTRL + (s << 3); + uint16_t sprite = VKY_SP0_CTRL + (s * 8); POKEW(sprite + OFF_SPR_POS_X_L, x); POKEW(sprite + OFF_SPR_POS_Y_L, y); @@ -46,9 +66,9 @@ void spriteSetPosition(byte s, uint16_t x, uint16_t y) { void spriteSetVisible(byte s, bool v) { - uint16_t sprite = VKY_SP0_CTRL + (s << 3); + uint16_t sprite = VKY_SP0_CTRL + (s * 8); - POKE(sprite, (PEEK(sprite) & 0xfe) | v); + POKE(sprite, _spriteCtl[s] | v); } diff --git a/imageconvert/imageconvert.c b/imageconvert/imageconvert.c deleted file mode 100644 index c968389..0000000 --- a/imageconvert/imageconvert.c +++ /dev/null @@ -1,167 +0,0 @@ -/* - * Copyright (c) 2024 Scott Duensing, scott@kangaroopunch.com - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - - -#include -#include -#include - -#define STB_IMAGE_IMPLEMENTATION -#include "stb_image.h" - - -typedef unsigned char byte; - -typedef struct colorS { - byte r; - byte g; - byte b; -} colorT; - - -char *replaceExtension(char *org, char *new_ext) { - char *ext; - char *tmp = strdup(org); - size_t newSize; - char *newName; - - ext = strrchr(tmp , '.'); - if (ext) *ext = 0; - - newSize = strlen(tmp) + strlen(new_ext) + 1; - newName = malloc(newSize); - sprintf(newName, "%s%s", tmp, new_ext); - - free(tmp); - - return newName; -} - - -int main(int argc, char *argv[]) { - - int x; - int y; - int w; - int h; - int n; - int colors = 0; - byte found; - byte *data; - byte *p; - colorT c; - colorT palette[256]; - char *filename; - FILE *out; - - if (argc != 2) { - printf("Usage: %s [imagefile]\n", argv[0]); - return 1; - } - - data = stbi_load(argv[1], &w, &h, &n, 3); - if (data == NULL) { - printf("Unable to load %s!\n", argv[1]); - return 2; - } - - // Build palette. - printf("Building palette...\n"); - p = data; - for (y=0; y 256) { - free(data); - printf("More than 256 colors in the image. Aborting.\n"); - return 3; - } - } - } - } - - // Write out F256 CLUT. - filename = replaceExtension(argv[1], ".clut"); - printf("Writing %d color palette %s...\n", colors, filename); - out = fopen(filename, "wb"); - if (out == NULL) { - printf("Unable to write %s. Aborting.\n", filename); - free(data); - free(filename); - return 4; - } - for (n=0; n #include #include -#include #include +#include "../shared/util.h" + /* * This program assumes it is being run on a little endian machine. */ -int utilStricmp(char *a, char *b) { - for (;; a++, b++) { - int d = tolower((unsigned char)*a) - tolower((unsigned char)*b); - if (d != 0 || !*a) { - return d; - } - } -} - - int main(int argc, char *argv[]) { FILE *in = NULL; FILE *out = NULL; diff --git a/tools/imageconvert/imageconvert.c b/tools/imageconvert/imageconvert.c new file mode 100644 index 0000000..a4647dc --- /dev/null +++ b/tools/imageconvert/imageconvert.c @@ -0,0 +1,236 @@ +/* + * Copyright (c) 2024 Scott Duensing, scott@kangaroopunch.com + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + + +#include +#include + +#define STB_IMAGE_IMPLEMENTATION +#include "../shared/stb_image.h" + +#include "../shared/util.h" + + +int writeImage(byte *data, colorT *palette, int colors, char *filename, int xs, int ys, int width, int height) { + int x; + int y; + int n; + byte *p; + colorT c; + FILE *out; + + printf("Writing %dx%d indexed image %s...\n", width, height, filename); + out = fopen(filename, "wb"); + if (out == NULL) { + printf("Unable to write %s. Aborting.\n", filename); + return 5; + } + for (y=ys; y 4) { + printf("Usage: %s [type] [imagefile]\n", argv[0]); + printf("Where: [type] is the output type:\n"); + printf(" - image (creates CLUT and indexed image)\n"); + printf(" - sprite (creates CLUT and indexed sprites)\n"); + return 1; + } + + outputType = argv[1]; + inputImage = argv[2]; + + // Are we making sprites? + if (utilStricmp(outputType, "sprite") == 0) { + okay = false; + if (argc == 4) { + inputImage = argv[3]; + spriteSize = atoi(argv[2]); + if (spriteSize == 8 || spriteSize == 16 || spriteSize == 24 || spriteSize == 32) { + okay = true; + } + } + if (!okay) { + printf("Usage: %s sprite [size] [imagefile]\n", argv[0]); + printf("Where: [size] is 8, 16, 24, or 32\n"); + return 6; + } + } + + // Load image, check for valid size. + data = stbi_load(inputImage, &w, &h, &n, 3); + if (data == NULL) { + printf("Unable to load %s!\n", inputImage); + return 2; + } + if (spriteSize > 0) { + // Sprites must be multiples of 8, 16, 24, or 32. + okay = false; + if (((int)(w / 8) == (w / 8.0)) && ((int)(h / 8) == (h / 8.0))) okay = true; + if (((int)(w / 16) == (w / 16.0)) && ((int)(h / 16) == (h / 16.0))) okay = true; + if (((int)(w / 24) == (w / 24.0)) && ((int)(h / 24) == (h / 24.0))) okay = true; + if (((int)(w / 32) == (w / 32.0)) && ((int)(h / 32) == (h / 32.0))) okay = true; + if (!okay) { + printf("Height and width must be divisible 8, 16, 24, or 32!\n"); + return 8; + } + } else { + // Images are more lax - we'll let anything of the right width through. + if (w != 320) { + free(data); + printf("Images must be 320 pixels in width!\n"); + return 7; + } + } + + // Build palette. + printf("Building palette...\n"); + p = data; + for (y=0; y 256) { + free(data); + printf("More than 256 colors in the image. Aborting.\n"); + return 3; + } + } + } + } + + // Write out F256 CLUT. + filename = utilReplaceExtension(inputImage, ".clut"); + printf("Writing %d color palette %s...\n", colors, filename); + out = fopen(filename, "wb"); + if (out == NULL) { + printf("Unable to write %s. Aborting.\n", filename); + free(data); + free(filename); + return 4; + } + for (n=0; n +#include +#include +#include +#include + +#include "util.h" + + +char *utilCreateString(char *format, ...) { + va_list args; + char *string; + + va_start(args, format); + string = utilCreateStringVArgs(format, args); + va_end(args); + + return string; +} + + +__attribute__((__format__(__printf__, 1, 0))) +char *utilCreateStringVArgs(char *format, va_list args) { + va_list argsCopy; + int32_t size = 0; + char *buffer = NULL; + + va_copy(argsCopy, args); + size = vsnprintf(NULL, 0, format, argsCopy) + 1; + va_end(argsCopy); + buffer = calloc(1, (size_t)size); + if (buffer) { + vsnprintf(buffer, (size_t)size, format, args); + } + + return buffer; +} + + +char *utilReplaceExtension(char *org, char *new_ext) { + char *ext; + char *tmp = strdup(org); + size_t newSize; + char *newName; + + ext = strrchr(tmp , '.'); + if (ext) *ext = 0; + + newSize = strlen(tmp) + strlen(new_ext) + 1; + newName = malloc(newSize); + sprintf(newName, "%s%s", tmp, new_ext); + + free(tmp); + + return newName; +} + + +int utilStricmp(char *a, char *b) { + for (;; a++, b++) { + int d = tolower((unsigned char)*a) - tolower((unsigned char)*b); + if (d != 0 || !*a) { + return d; + } + } +} + + diff --git a/tools/shared/util.h b/tools/shared/util.h new file mode 100644 index 0000000..54e3207 --- /dev/null +++ b/tools/shared/util.h @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2024 Scott Duensing, scott@kangaroopunch.com + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + + +#ifndef UTIL_H +#define UTIL_H + + +typedef unsigned char byte; + +typedef struct colorS { + byte r; + byte g; + byte b; +} colorT; + + +char *utilCreateString(char *format, ...); +char *utilCreateStringVArgs(char *format, va_list args); +char *utilReplaceExtension(char *org, char *new_ext); +int utilStricmp(char *a, char *b); + + +#endif // UTIL_H