diff --git a/CMakeLists.txt b/CMakeLists.txt index f7b4024..ec7b3a6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -74,7 +74,7 @@ if(ENABLE_TESTS) ${DUSK_LIBRARY_TARGET_NAME} ) else() - set(DUSK_BINARY_TARGET_NAME "${DUSK_LIBRARY_TARGET_NAME}" CACHE INTERNAL ${DUSK_CACHE_TARGET}) + set(DUSK_LIBRARY_TARGET_NAME "${DUSK_BINARY_TARGET_NAME}" CACHE INTERNAL ${DUSK_CACHE_TARGET}) add_executable(${DUSK_BINARY_TARGET_NAME} ${DUSK_SOURCES_DIR}/null.c) endif() diff --git a/src/asset/type/assetpaletteimage.c b/src/asset/type/assetpaletteimage.c index af22153..3baada1 100644 --- a/src/asset/type/assetpaletteimage.c +++ b/src/asset/type/assetpaletteimage.c @@ -8,6 +8,7 @@ #include "assetpaletteimage.h" #include "assert/assert.h" #include "display/texture.h" +#include "display/palette/palettelist.h" errorret_t assetPaletteImageLoad(void *data, void *output) { assertNotNull(data, "Data pointer cannot be NULL."); @@ -19,6 +20,9 @@ errorret_t assetPaletteImageLoad(void *data, void *output) { // Fix endian assetData->width = le32toh(assetData->width); assetData->height = le32toh(assetData->height); + + const palette_t *pal = PALETTE_LIST[assetData->paletteIndex]; + assertNotNull(pal, "Palette index is out of bounds"); textureInit( texture, @@ -27,7 +31,7 @@ errorret_t assetPaletteImageLoad(void *data, void *output) { TEXTURE_FORMAT_PALETTE, (texturedata_t){ .palette = { - .palette = assetData->paletteIndex, + .palette = pal, .data = assetData->palette } } diff --git a/src/display/texture.c b/src/display/texture.c index 36fe58a..57f8174 100644 --- a/src/display/texture.c +++ b/src/display/texture.c @@ -9,6 +9,7 @@ #include "assert/assert.h" #include "util/memory.h" #include "util/math.h" +#include "util/string.h" #include "display/palette/palettelist.h" const texture_t *TEXTURE_BOUND = NULL; @@ -55,70 +56,35 @@ void textureInit( assertNotNull(data.alpha.data, "Alpha texture data cannot be NULL"); #if PSP // PSP kinda broken with alpha textures, so we convert it to paletted - // texture here. - uint8_t colorCount = 0; - uint8_t alphas[UINT8_MAX] = { 0 }; - uint8_t colorIndex[width * height]; + // texture here. We also crunch the amount of alpha values. + #define PSP_ALPHA_PALETTE_CRUNCH 4 + #define PSP_ALPHA_PALETTE_COUNT (256 / PSP_ALPHA_PALETTE_CRUNCH) + + color_t paletteColors[PSP_ALPHA_PALETTE_COUNT]; + for(uint8_t i = 0; i < PSP_ALPHA_PALETTE_COUNT; i++) { + paletteColors[i].r = 0xFF; + paletteColors[i].g = 0xFF; + paletteColors[i].b = 0xFF; + paletteColors[i].a = i * PSP_ALPHA_PALETTE_CRUNCH; + } + + // Generate indexes, crunching the alpha values to fit. + uint8_t indexes[width * height]; for(int32_t i = 0; i < width * height; i++) { - uint8_t alpha = data.alpha.data[i]; - - // Already in the palette? - bool_t exists = false; - uint8_t j = 0; - for(j = 0; j < colorCount; j++) { - if(alphas[j] != alpha) continue; - exists = true; - break; - } - - // if found use existing index, otherwise add to palette - if(exists) { - colorIndex[i] = j; - continue; - } - - - // Should never happen given the format, but just in case: - assertTrue( - colorCount < UINT8_MAX, - "Too many unique alpha values for paletted texture" - ); - colorIndex[i] = colorCount; - alphas[colorCount] = alpha; - colorCount++; + uint8_t alpha = data.alpha.data[i] / PSP_ALPHA_PALETTE_CRUNCH;; + indexes[i] = alpha; } - // Pad color count to power of two for PSP - uint8_t paddedColorCount = mathNextPowTwo(colorCount); - printf( - "Converted alpha texture to paletted format with %u unique alpha values (padded to %u)\n", - colorCount, paddedColorCount - ); + palette_t palette = { + .colorCount = PSP_ALPHA_PALETTE_COUNT, + .colors = paletteColors + }; - // Create a palette with the unique alpha values - texture->palette = (color4b_t*)memoryAllocate( - sizeof(color4b_t) * paddedColorCount - ); - memoryZero(texture->palette, sizeof(color4b_t) * paddedColorCount); - for(uint8_t i = 0; i < colorCount; i++) { - texture->palette[i].r = 0; - texture->palette[i].g = 0; - texture->palette[i].b = 0; - texture->palette[i].a = alphas[i]; - } - - printf("Uploading paletted texture to GPU\n"); - texture->format = TEXTURE_FORMAT_PALETTE; - glTexImage2D( - GL_TEXTURE_2D, - 0, GL_COLOR_INDEX8_EXT, - width, height, - 0, GL_COLOR_INDEX8_EXT, - GL_UNSIGNED_BYTE, (void*)colorIndex - ); - glColorTableEXT( - GL_TEXTURE_2D, GL_RGBA, paddedColorCount, GL_RGBA, - GL_UNSIGNED_BYTE, (const void*)texture->palette + return textureInit( + texture, width, height, TEXTURE_FORMAT_PALETTE, + (texturedata_t){ + .palette = { .palette = &palette, .data = indexes } + } ); #else glTexImage2D( @@ -131,14 +97,9 @@ void textureInit( case TEXTURE_FORMAT_PALETTE: assertNotNull(data.palette.data, "Palette texture data cannot be NULL"); - assertTrue( - data.palette.palette < PALETTE_LIST_COUNT, - "Palette index out of range" - ); + assertNotNull(data.palette.palette, "Palette cannot be NULL"); // Get and validate the palette. - const palette_t *pal = PALETTE_LIST[data.palette.palette]; - assertNotNull(pal, "Palette cannot be NULL"); GLenum err = glGetError(); if(err != GL_NO_ERROR) { assertUnreachable("GL Error before setting color table"); @@ -153,10 +114,14 @@ void textureInit( GLint mask = 0; glGetIntegerv(GL_CONTEXT_PROFILE_MASK, &mask); if(mask & GL_CONTEXT_CORE_PROFILE_BIT) { - GLint n=0; glGetIntegerv(GL_NUM_EXTENSIONS, &n); - for(GLint i=0; icolorCount, + index < data.palette.palette->colorCount, "Palette index out of range" ); - formatted[i] = pal->colors[index]; + formatted[i] = data.palette.palette->colors[index]; } glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, @@ -184,7 +149,8 @@ void textureInit( #if PSP // PSP requires the color table itself to be a power of two assertTrue( - pal->colorCount == mathNextPowTwo(pal->colorCount), + data.palette.palette->colorCount == + mathNextPowTwo(data.palette.palette->colorCount), "Palette color count must be a power of 2 for PSP" ); #endif @@ -198,8 +164,8 @@ void textureInit( ); glColorTableEXT( - GL_TEXTURE_2D, GL_RGBA, pal->colorCount, GL_RGBA, - GL_UNSIGNED_BYTE, (const void*)pal->colors + GL_TEXTURE_2D, GL_RGBA, data.palette.palette->colorCount, GL_RGBA, + GL_UNSIGNED_BYTE, (const void*)data.palette.palette->colors ); } @@ -393,12 +359,6 @@ void textureDispose(texture_t *texture) { #if DISPLAY_SDL2 glDeleteTextures(1, &texture->id); - #if PSP - if(texture->palette) { - memoryFree(texture->palette); - texture->palette = NULL; - } - #endif #elif DOLPHIN switch(texture->format) { case TEXTURE_FORMAT_RGBA: diff --git a/src/display/texture.h b/src/display/texture.h index a4d942e..1df6eb1 100644 --- a/src/display/texture.h +++ b/src/display/texture.h @@ -8,6 +8,7 @@ #pragma once #include "display/color.h" #include "display/displaydefs.h" +#include "display/palette/palette.h" typedef enum { #if DISPLAY_SDL2 @@ -24,9 +25,6 @@ typedef enum { typedef struct { #if DISPLAY_SDL2 GLuint id; - #if PSP - color4b_t *palette; - #endif #elif DOLPHIN GXTexObj texObj; union { @@ -47,7 +45,7 @@ typedef union { } rgba; struct { - uint8_t palette; + const palette_t *palette; uint8_t *data; } palette; diff --git a/src/dusk.h b/src/dusk.h index d430aa7..601521a 100644 --- a/src/dusk.h +++ b/src/dusk.h @@ -35,7 +35,9 @@ #include #include #else - #define le32toh(x) (x) + #ifndef le32toh + #define le32toh(x) (x) + #endif #endif typedef bool bool_t;