]> git.bts.cx Git - benzene.git/commitdiff
Sprites
authorBen Sherratt <redacted>
Sun, 19 May 2024 18:50:10 +0000 (19:50 +0100)
committerBen Sherratt <redacted>
Sun, 19 May 2024 18:50:10 +0000 (19:50 +0100)
src/bz/game/scene.c
src/bz/gfx/aseprite.c
src/bz/gfx/aseprite.h
src/bz/gfx/gfx.c
src/bz/gfx/gfx_internal.h
src/bz/memory/arena.c
src/bz/memory/arena_internal.h

index 907fccb03e72b55a1c54bc051ba8ff59524895f9..f00ace6252ae1ab63c4c869d8d2a532d669d7d67 100644 (file)
@@ -180,15 +180,17 @@ BZSceneID bzGameSceneSwitch(BZMemoryArenaID arena, BZAudioPlaybackEngineID audio
 
        const char *spritesheetName = json_object_get_string(sceneJsonObject, "spritesheet");
        if (spritesheetName != NULL) {
 
        const char *spritesheetName = json_object_get_string(sceneJsonObject, "spritesheet");
        if (spritesheetName != NULL) {
-               size_t imageWidth, imageHeight;
-               void *imageData = bzGfxLoadAsepriteImage(arena, &imageWidth, &imageHeight, spritesheetName); // FIXME, temp arena
-               bzGfxPrepareSpritesheet(arena, imageWidth, imageHeight, imageData);
+               size_t imageFrames, imageWidth, imageHeight;
+               void *imageData = bzGfxLoadAsepriteImage(arena, &imageFrames, &imageWidth, &imageHeight, spritesheetName); // FIXME, temp arena
+               bzGfxPrepareSpritesheet(arena, imageFrames, imageWidth, imageHeight, imageData);
                //free(imageData);
        }
 
        const char *fontName = json_object_get_string(sceneJsonObject, "font");
                //free(imageData);
        }
 
        const char *fontName = json_object_get_string(sceneJsonObject, "font");
-       BZFont *font = bzGfxLoadFont(arena, fontName); // FIXME, temp arena??
-       bzGfxPrepareFont(arena, font);
+       if (fontName != NULL) {
+               BZFont *font = bzGfxLoadFont(arena, fontName); // FIXME, temp arena??
+               bzGfxPrepareFont(arena, font);
+       }
 
        JSON_Array *actorDefinitionsArray = json_object_get_array(sceneJsonObject, "actors");
        size_t actorDefinitionsArrayCount = json_array_get_count(actorDefinitionsArray);
 
        JSON_Array *actorDefinitionsArray = json_object_get_array(sceneJsonObject, "actors");
        size_t actorDefinitionsArrayCount = json_array_get_count(actorDefinitionsArray);
index 69dc446fbef8b1bbe2b2b178501ed3fde6737130..046ca246488f378ba191537b92f8ed693c254d37 100644 (file)
@@ -1,12 +1,15 @@
 #include <bz/gfx/aseprite_internal.h>
 
 #include <bz/gfx/aseprite_internal.h>
 
+#include <bz/debug/assert.h>
+#include <bz/debug/log.h>
 #include <bz/math/math.h>
 #include <bz/memory/allocator.h>
 #include <bz/renderer/palette_internal.h>
 #include <bz/resources/resource.h>
 #include <bz/types/identifier_internal.h>
 #include <bz/math/math.h>
 #include <bz/memory/allocator.h>
 #include <bz/renderer/palette_internal.h>
 #include <bz/resources/resource.h>
 #include <bz/types/identifier_internal.h>
-#include <stdio.h> // Apparently stb_image.h need this??
+#include <stdio.h> // Apparently stb_image.h needs this??
 #include <stb_image.h>
 #include <stb_image.h>
+#include <string.h> // memset
 
 #include <assert.h> // Static assertions
 
 
 #include <assert.h> // Static assertions
 
@@ -23,8 +26,6 @@ typedef double   ASE_DOUBLE;
 typedef uint64_t ASE_QWORD;
 typedef int64_t  ASE_LONG64;
 
 typedef uint64_t ASE_QWORD;
 typedef int64_t  ASE_LONG64;
 
-
-
 struct PACKED_STRUCT ASE_STRING {
        ASE_WORD length;
        //ASE_BYTE characters[];
 struct PACKED_STRUCT ASE_STRING {
        ASE_WORD length;
        //ASE_BYTE characters[];
@@ -53,14 +54,14 @@ struct PACKED_STRUCT ASE_RECT {
 typedef struct ASE_RECT ASE_RECT;
 static_assert(sizeof(ASE_RECT) == 16, "ASE_RECT is wrong size");
 
 typedef struct ASE_RECT ASE_RECT;
 static_assert(sizeof(ASE_RECT) == 16, "ASE_RECT is wrong size");
 
-struct PACKED_STRUCT ASE_PIXEL_RBZA {
+struct PACKED_STRUCT ASE_PIXEL_RBGA {
        ASE_BYTE r;
        ASE_BYTE g;
        ASE_BYTE b;
        ASE_BYTE a;
 };
        ASE_BYTE r;
        ASE_BYTE g;
        ASE_BYTE b;
        ASE_BYTE a;
 };
-typedef struct ASE_PIXEL_RBZA ASE_PIXEL_RBZA;
-static_assert(sizeof(ASE_PIXEL_RBZA) == 4, "ASE_PIXEL_RBZA is wrong size");
+typedef struct ASE_PIXEL_RBGA ASE_PIXEL_RBGA;
+static_assert(sizeof(ASE_PIXEL_RBGA) == 4, "ASE_PIXEL_RBGA is wrong size");
 
 struct PACKED_STRUCT ASE_PIXEL_GRAYSCALE {
        ASE_BYTE v;
 
 struct PACKED_STRUCT ASE_PIXEL_GRAYSCALE {
        ASE_BYTE v;
@@ -119,6 +120,25 @@ struct PACKED_STRUCT ASE_Chunk {
 typedef struct ASE_Chunk ASE_Chunk;
 static_assert(sizeof(ASE_Chunk) == 6, "ASE_Chunk is wrong size");
 
 typedef struct ASE_Chunk ASE_Chunk;
 static_assert(sizeof(ASE_Chunk) == 6, "ASE_Chunk is wrong size");
 
+enum ASE_ChunkTypes {
+       ASE_ChunkType_LayerChunk = 0x2004,
+       ASE_ChunkType_CelChunk = 0x2005,
+       ASE_ChunkType_CelExtraChunk = 0x2006,
+       ASE_ChunkType_ColorProfileChunk = 0x2007,
+       ASE_ChunkType_ExternalFilesChunk = 0x2008,
+       ASE_ChunkType_TagsChunk = 0x2018,
+       ASE_ChunkType_PaletteChunk = 0x2019,
+       ASE_ChunkType_UserDataChunk = 0x2020,
+       ASE_ChunkType_SliceChunk = 0x2022,
+       ASE_ChunkType_TilesetChunk = 0x2023,
+
+       // Ignore these, deprecated or unused...
+       ASE_ChunkType_OldPaletteChunk1 = 0x0004,
+       ASE_ChunkType_OldPaletteChunk2 = 0x0011,
+       ASE_ChunkType_MaskChunk = 0x2016,
+       ASE_ChunkType_PathChunk = 0x2017,
+};
+
 #if 0
 struct PACKED_STRUCT ASE_Chunk_OldPalette {
        ASE_WORD numPackets;
 #if 0
 struct PACKED_STRUCT ASE_Chunk_OldPalette {
        ASE_WORD numPackets;
@@ -158,6 +178,10 @@ struct PACKED_STRUCT ASE_Chunk_Layer {
 typedef struct ASE_Chunk_Layer ASE_Chunk_Layer;
 static_assert(sizeof(ASE_Chunk_Layer) == 18, "ASE_Chunk_Layer is wrong size");
 
 typedef struct ASE_Chunk_Layer ASE_Chunk_Layer;
 static_assert(sizeof(ASE_Chunk_Layer) == 18, "ASE_Chunk_Layer is wrong size");
 
+enum ASE_Chunk_Layer_BlendModes {
+       ASE_Chunk_Layer_BlendMode_Normal = 0, // Should always be this
+};
+
 struct PACKED_STRUCT ASE_Chunk_Layer_Tileset {
        ASE_DWORD tilesetIndex;
 };
 struct PACKED_STRUCT ASE_Chunk_Layer_Tileset {
        ASE_DWORD tilesetIndex;
 };
@@ -176,6 +200,13 @@ struct PACKED_STRUCT ASE_Chunk_Cel {
 typedef struct ASE_Chunk_Cel ASE_Chunk_Cel;
 static_assert(sizeof(ASE_Chunk_Cel) == 16, "ASE_Chunk_Cel is wrong size");
 
 typedef struct ASE_Chunk_Cel ASE_Chunk_Cel;
 static_assert(sizeof(ASE_Chunk_Cel) == 16, "ASE_Chunk_Cel is wrong size");
 
+enum ASE_Chunk_Cel_CelTypes {
+       ASE_Chunk_Cel_CelType_RawImage = 0,
+       ASE_Chunk_Cel_CelType_LinkedCel = 1,
+       ASE_Chunk_Cel_CelType_CompressedImage = 2,
+       ASE_Chunk_Cel_CelType_CompressedTilemap = 3,
+};
+
 struct PACKED_STRUCT ASE_Chunk_Cel_RawImage {
        ASE_WORD pixelWidth;
        ASE_WORD pixelHeight;
 struct PACKED_STRUCT ASE_Chunk_Cel_RawImage {
        ASE_WORD pixelWidth;
        ASE_WORD pixelHeight;
@@ -255,6 +286,13 @@ struct PACKED_STRUCT ASE_Chunk_ExternalFiles_Entry {
 typedef struct ASE_Chunk_ExternalFiles_Entry ASE_Chunk_ExternalFiles_Entry;
 static_assert(sizeof(ASE_Chunk_ExternalFiles_Entry) == 14, "ASE_Chunk_ExternalFiles_Entry is wrong size");
 
 typedef struct ASE_Chunk_ExternalFiles_Entry ASE_Chunk_ExternalFiles_Entry;
 static_assert(sizeof(ASE_Chunk_ExternalFiles_Entry) == 14, "ASE_Chunk_ExternalFiles_Entry is wrong size");
 
+enum ASE_Chunk_ExternalFiles_Entry_Types {
+       ASE_Chunk_ExternalFiles_EntryType_ExternalPalette = 0,
+       ASE_Chunk_ExternalFiles_EntryType_ExternalTileset = 1,
+       ASE_Chunk_ExternalFiles_EntryType_PropertiesExtension = 2,
+       ASE_Chunk_ExternalFiles_EntryType_TileManagement = 3,
+};
+
 struct PACKED_STRUCT ASE_Chunk_Mask {
        ASE_SHORT positionX;
        ASE_SHORT positionY;
 struct PACKED_STRUCT ASE_Chunk_Mask {
        ASE_SHORT positionX;
        ASE_SHORT positionY;
@@ -311,7 +349,34 @@ struct PACKED_STRUCT ASE_Chunk_Palette_Entry_Name {
 typedef struct ASE_Chunk_Palette_Entry_Name ASE_Chunk_Palette_Entry_Name;
 static_assert(sizeof(ASE_Chunk_Palette_Entry_Name) == 2, "ASE_Chunk_Palette_Entry_Name is wrong size");
 
 typedef struct ASE_Chunk_Palette_Entry_Name ASE_Chunk_Palette_Entry_Name;
 static_assert(sizeof(ASE_Chunk_Palette_Entry_Name) == 2, "ASE_Chunk_Palette_Entry_Name is wrong size");
 
-void *bzGfxLoadAsepriteImage(BZMemoryArenaID arena, size_t *widthOut, size_t *heightOut, const char *identifierFmt, ...) {
+static bool readASEHeader(ASE_Header *headerOut, BZResourceID handle) {
+       bzAssert(headerOut != NULL);
+       bzResourcesReadBytes(handle, headerOut, sizeof(ASE_Header));
+       bzAssert(headerOut->magicNumber == 0xA5E0);
+       return true;
+}
+
+static bool readASEFrame(ASE_Frame *frameOut, ASE_DWORD *numChunksOut, BZResourceID handle) {
+       bzAssert(frameOut != NULL);
+       bzAssert(numChunksOut != NULL);
+
+       bzResourcesReadBytes(handle, frameOut, sizeof(ASE_Frame));
+
+       ASE_DWORD numChunks = frameOut->___numChunks;
+
+       if (numChunks == 0xFFFF) {
+               numChunks = frameOut->numChunks;
+               if (numChunks == 0) {
+                       numChunks = frameOut->___numChunks; // See docs.
+               }
+       }
+
+       *numChunksOut = numChunks;
+
+       return true;
+}
+
+void *bzGfxLoadAsepriteImage(BZMemoryArenaID arena, size_t *framesOut, size_t *widthOut, size_t *heightOut, const char *identifierFmt, ...) {
        bzMakeIdentifier(identifier, identifierFmt);
 
        BZResourceID handle = bzResourcesOpenResource("sprite", "assets/sprites/%s.aseprite", identifier);
        bzMakeIdentifier(identifier, identifierFmt);
 
        BZResourceID handle = bzResourcesOpenResource("sprite", "assets/sprites/%s.aseprite", identifier);
@@ -320,9 +385,7 @@ void *bzGfxLoadAsepriteImage(BZMemoryArenaID arena, size_t *widthOut, size_t *he
        //PHYSFS_readBytes(handle, data, length);
        
        ASE_Header header;
        //PHYSFS_readBytes(handle, data, length);
        
        ASE_Header header;
-       bzResourcesReadBytes(handle, &header, sizeof(header));
-       
-       bzAssert(header.magicNumber == 0xA5E0);
+       readASEHeader(&header, handle);
 
        size_t pixelDataSize;
        switch (header.depth) {
 
        size_t pixelDataSize;
        switch (header.depth) {
@@ -335,7 +398,7 @@ void *bzGfxLoadAsepriteImage(BZMemoryArenaID arena, size_t *widthOut, size_t *he
                        break;
 
                case 32:
                        break;
 
                case 32:
-                       pixelDataSize = sizeof(ASE_PIXEL_RBZA);
+                       pixelDataSize = sizeof(ASE_PIXEL_RBGA);
                        break;
        
                default:
                        break;
        
                default:
@@ -343,32 +406,65 @@ void *bzGfxLoadAsepriteImage(BZMemoryArenaID arena, size_t *widthOut, size_t *he
                        break;
        }
 
                        break;
        }
 
-       uint8_t *outData = (uint8_t *)bzMemoryAlloc(arena, header.width * header.height * pixelDataSize);
+       uint8_t *outData = (uint8_t *)bzMemoryAlloc(arena, header.frames * header.width * header.height * pixelDataSize); // Side by side loading needs to happen...
+       *framesOut = (size_t)header.frames;
        *widthOut = (size_t)header.width;
        *heightOut = (size_t)header.height;
 
        *widthOut = (size_t)header.width;
        *heightOut = (size_t)header.height;
 
-       for (ASE_WORD frame = 0; frame < header.frames; ++frame) {
+       bzMemoryArenaPushWatermark(arena);
+       size_t zBufferSize = header.width * header.height * sizeof(ASE_SHORT);
+       ASE_SHORT *zBuffer = (ASE_SHORT *)bzMemoryAlloc(arena, zBufferSize);
+
+       size_t frameImageSize = header.width * header.height * pixelDataSize;
+
+       for (ASE_WORD frameIdx = 0; frameIdx < header.frames; ++frameIdx) {
                ASE_Frame frame;
                ASE_Frame frame;
-               bzResourcesReadBytes(handle, &frame, sizeof(frame));
+               ASE_DWORD numChunks = 0;
+               readASEFrame(&frame, &numChunks, handle);
+               bzLog("FRAME %d: %d chunks", frameIdx, numChunks);
+
+               memset(zBuffer, 0, zBufferSize);
+
+               bool layerVisible[16];
+               size_t nextLayer = 0;
+
+               size_t layerStartOffset[16];
 
 
-               for (ASE_DWORD chunk = 0; chunk < frame.numChunks; ++chunk) {
+               for (ASE_DWORD chunk = 0; chunk < numChunks; ++chunk) {
                        size_t chunkStartPosition = bzResourcesTell(handle);
 
                        ASE_Chunk chunk;
                        bzResourcesReadBytes(handle, &chunk, sizeof(chunk));
 
                        switch (chunk.type) {
                        size_t chunkStartPosition = bzResourcesTell(handle);
 
                        ASE_Chunk chunk;
                        bzResourcesReadBytes(handle, &chunk, sizeof(chunk));
 
                        switch (chunk.type) {
-                               case 0x2005: {
+                               case ASE_ChunkType_LayerChunk: {
+                                       bzLog("LAYER %d: %d chunks", frameIdx, numChunks);
+
+
+                                       ASE_Chunk_Layer layer;
+                                       bzResourcesReadBytes(handle, &layer, sizeof(layer));
+
+                                       layerVisible[nextLayer] = (layer.flags & 1) > 0;
+                                       ++nextLayer;
+
+                                       bzResourcesSeek(handle, chunkStartPosition + chunk.chunkSize);
+                                       break;
+                               }
+
+                               case ASE_ChunkType_CelChunk: {
+                                       bzLog("CELL %d: %d chunks", frameIdx, numChunks);
                                        ASE_Chunk_Cel cel;
                                        bzResourcesReadBytes(handle, &cel, sizeof(cel));
 
                                        ASE_Chunk_Cel cel;
                                        bzResourcesReadBytes(handle, &cel, sizeof(cel));
 
-                                       if (cel.celType == 2) {
+/////                                  ASE_Chunk_Cel_CelType_LinkedCel aaaahhh
+
+                                       if (layerVisible[cel.layerIndex] && cel.celType == ASE_Chunk_Cel_CelType_CompressedImage) {
                                                bzMemoryArenaPushWatermark(arena);
 
                                                ASE_Chunk_Cel_CompressedImage image;
                                                bzResourcesReadBytes(handle, &image, sizeof(image));
 
                                                bzMemoryArenaPushWatermark(arena);
 
                                                ASE_Chunk_Cel_CompressedImage image;
                                                bzResourcesReadBytes(handle, &image, sizeof(image));
 
-                                               size_t compressedSize = chunk.chunkSize - sizeof(ASE_Chunk_Cel_CompressedImage) - sizeof(ASE_Chunk);
+                                               size_t compressedSize = chunk.chunkSize - sizeof(ASE_Chunk_Cel_CompressedImage) - sizeof(ASE_Chunk_Cel) - sizeof(ASE_Chunk);
                                                int8_t *compressedData = bzMemoryAlloc(arena, compressedSize); // If we do this on the stack (alloca) the Playdate will explode!
                                                bzResourcesReadBytes(handle, compressedData, compressedSize);
 
                                                int8_t *compressedData = bzMemoryAlloc(arena, compressedSize); // If we do this on the stack (alloca) the Playdate will explode!
                                                bzResourcesReadBytes(handle, compressedData, compressedSize);
 
@@ -381,16 +477,21 @@ void *bzGfxLoadAsepriteImage(BZMemoryArenaID arena, size_t *widthOut, size_t *he
                                                                size_t outX = cel.positionX + x;
                                                                size_t outY = cel.positionY + y;
 
                                                                size_t outX = cel.positionX + x;
                                                                size_t outY = cel.positionY + y;
 
-                                                               for (size_t i = 0; i < pixelDataSize; ++i) {
-                                                                       outData[(outY * header.width + outX) * pixelDataSize + i] = imagePixelData[(y * image.pixelWidth + x) * pixelDataSize + i];
+                                                               ASE_SHORT *currentZ = &zBuffer[outY * header.width + outX];
+
+                                                               if (*currentZ <= cel.zIndex) {
+                                                                       for (size_t i = 0; i < pixelDataSize; ++i) {
+                                                                               uint8_t pixelData = imagePixelData[(y * image.pixelWidth + x) * pixelDataSize + i];
+                                                                               if (pixelData > 0) { // FIXME, alpha...
+                                                                                       outData[frameIdx * frameImageSize + (outY * header.width + outX) * pixelDataSize + i] = pixelData;
+                                                                               }
+                                                                       }
+                                                                       *currentZ = cel.zIndex;
                                                                }
                                                        }
                                                }
 
                                                bzMemoryArenaPopWatermark(arena);
                                                                }
                                                        }
                                                }
 
                                                bzMemoryArenaPopWatermark(arena);
-
-                                               // FIXME
-                                               //bzResourcesSeek(handle, chunkStartPosition + chunk.chunkSize);
                                        } else {
                                                // Skip this chunk...
                                                bzResourcesSeek(handle, chunkStartPosition + chunk.chunkSize);
                                        } else {
                                                // Skip this chunk...
                                                bzResourcesSeek(handle, chunkStartPosition + chunk.chunkSize);
@@ -407,6 +508,8 @@ void *bzGfxLoadAsepriteImage(BZMemoryArenaID arena, size_t *widthOut, size_t *he
                }
        }
        
                }
        }
        
+       bzMemoryArenaPopWatermark(arena);
+
        bzResourcesCloseResource(handle);
 
        return outData;
        bzResourcesCloseResource(handle);
 
        return outData;
@@ -416,9 +519,7 @@ size_t bzGfxLoadAsepritePalette(uint32_t *colorsOut, size_t maxColors, const cha
        BZResourceID handle = bzResourcesOpenResource("palette", "assets/palettes/%s", filename);
        
        ASE_Header header;
        BZResourceID handle = bzResourcesOpenResource("palette", "assets/palettes/%s", filename);
        
        ASE_Header header;
-       bzResourcesReadBytes(handle, &header, sizeof(header));
-       
-       bzAssert(header.magicNumber == 0xA5E0);
+       readASEHeader(&header, handle);
 
        size_t colorCount = 0;
 
 
        size_t colorCount = 0;
 
@@ -426,14 +527,23 @@ size_t bzGfxLoadAsepritePalette(uint32_t *colorsOut, size_t maxColors, const cha
                ASE_Frame frame;
                bzResourcesReadBytes(handle, &frame, sizeof(frame));
 
                ASE_Frame frame;
                bzResourcesReadBytes(handle, &frame, sizeof(frame));
 
-               for (ASE_DWORD chunk = 0; chunk < frame.numChunks; ++chunk) {
+               ASE_DWORD numChunks = frame.___numChunks;
+
+               if (numChunks == 0xFFFF) {
+                       numChunks = frame.numChunks;
+                       if (numChunks == 0) {
+                               numChunks = frame.___numChunks; // See docs.
+                       }
+               }
+
+               for (ASE_DWORD chunk = 0; chunk < numChunks; ++chunk) {
                        size_t chunkStartPosition = bzResourcesTell(handle);
 
                        ASE_Chunk chunk;
                        bzResourcesReadBytes(handle, &chunk, sizeof(chunk));
 
                        switch (chunk.type) {
                        size_t chunkStartPosition = bzResourcesTell(handle);
 
                        ASE_Chunk chunk;
                        bzResourcesReadBytes(handle, &chunk, sizeof(chunk));
 
                        switch (chunk.type) {
-                               case 0x2019: {
+                               case ASE_ChunkType_PaletteChunk: {
                                        ASE_Chunk_Palette palette;
                                        bzResourcesReadBytes(handle, &palette, sizeof(palette));
 
                                        ASE_Chunk_Palette palette;
                                        bzResourcesReadBytes(handle, &palette, sizeof(palette));
 
index a5d540cecdc08443eb947b465a3a4cddf4aa9345..e6cdc9bba546c2bdcb803199814066354b37e304 100644 (file)
@@ -9,7 +9,7 @@
 extern "C" {
 #endif
 
 extern "C" {
 #endif
 
-extern void *bzGfxLoadAsepriteImage(BZMemoryArenaID arena, size_t *widthOut, size_t *heightOut, const char *identifierFmt, ...);
+extern void *bzGfxLoadAsepriteImage(BZMemoryArenaID arena, size_t *framesOut, size_t *widthOut, size_t *heightOut, const char *identifierFmt, ...);
 
 #ifdef __cplusplus
 }
 
 #ifdef __cplusplus
 }
index 0f26e3bdb0193a74843996e9d6a2688bb2adedd0..ccfdc2c0d847f929058d6b935df102ad7387a203 100644 (file)
@@ -72,12 +72,23 @@ static BZMatrix globalViewMatrix = { .a = 1, .b = 0, .c = 0, .d = 1, .x = 0, .y
 
 //uint32_t intermediateBuffer[canvasHeight][canvasWidth];
 
 
 //uint32_t intermediateBuffer[canvasHeight][canvasWidth];
 
-#define SS_WIDTH 128
-#define SS_HEIGHT 128
-#define kSpriteSheetStrideShift 7
-
+//#define SS_WIDTH 128
+//#define SS_HEIGHT 128
+//#define kSpriteSheetStrideShift 7
 //static uint8_t spritesheet[SS_HEIGHT][SS_WIDTH];
 //static uint8_t spritesheet[SS_HEIGHT][SS_WIDTH];
-static uint8_t *spritesheet = NULL;
+//static uint8_t *spritesheet = NULL;
+
+struct BZSpritesheet {
+       size_t width;
+       size_t height;
+       size_t spriteWidth;
+       size_t spriteHeight;
+       size_t spriteCount;
+       uint8_t data[];
+};
+typedef struct BZSpritesheet BZSpritesheet;
+
+static BZSpritesheet *spritesheet = NULL;
 
 static BZFont *currentFont;
 
 
 static BZFont *currentFont;
 
@@ -131,13 +142,19 @@ void bzGfxPrepareCanvasBuffer(BZMemoryArenaID arena, size_t width, size_t height
        bzLog("Data: %d %d %d %d", canvasWidth, canvasMemorySize, bufferStrideShift, bufferStride);
 }
 
        bzLog("Data: %d %d %d %d", canvasWidth, canvasMemorySize, bufferStrideShift, bufferStride);
 }
 
-void bzGfxPrepareSpritesheet(BZMemoryArenaID arena, size_t width, size_t height, void *data) {
+void bzGfxPrepareSpritesheet(BZMemoryArenaID arena, size_t frames, size_t width, size_t height, void *data) {
        uint8_t *imageData = (uint8_t *)data;
        uint8_t *imageData = (uint8_t *)data;
-       bzLog("Preparing spritesheet %dx%d", width, height);
+       bzLog("Preparing spritesheet %dx%dx%d", frames, width, height);
 
 
-       size_t spritesheetMemorySize = width * height * sizeof(uint8_t);
-       spritesheet = bzMemoryAlloc(arena, spritesheetMemorySize);
-       memcpy(spritesheet, data, spritesheetMemorySize);
+       size_t spritesheetDataSize = frames * width * height * sizeof(uint8_t);
+       spritesheet = bzMemoryAlloc(arena, sizeof(BZSpritesheet) + spritesheetDataSize);
+       
+       spritesheet->width = width;
+       spritesheet->height = height * frames;
+       spritesheet->spriteCount = frames;
+       spritesheet->spriteWidth = width;
+       spritesheet->spriteHeight = height;
+       memcpy(&spritesheet->data, data, spritesheetDataSize);
 }
 
 void bzGfxPrepareFont(BZMemoryArenaID arena, void *font) {
 }
 
 void bzGfxPrepareFont(BZMemoryArenaID arena, void *font) {
@@ -241,8 +258,9 @@ void bzPSet(BZCoordinate x, BZCoordinate y, BZPaletteColor c) {
 
 BZPaletteColor bzSGet(int x, int y) {
        bzAssert(spritesheet != NULL);
 
 BZPaletteColor bzSGet(int x, int y) {
        bzAssert(spritesheet != NULL);
-       if (x >= 0 && x < SS_WIDTH && y >=0 && y < SS_HEIGHT) {
-               return spritesheet[(y << kSpriteSheetStrideShift) + x];
+       if (x >= 0 && x < spritesheet->width && y >=0 && y < spritesheet->height) {
+               return spritesheet->data[y * spritesheet->width + x];
+               //return spritesheet->data[(y << kSpriteSheetStrideShift) + x];
        } else {
                return 0;
        }
        } else {
                return 0;
        }
@@ -550,11 +568,17 @@ void bzSpr(size_t n, BZCoordinate x, BZCoordinate y) {
 }
 
 void bzSprExt(size_t n, BZCoordinate x, BZCoordinate y, BZCoordinate w, BZCoordinate h, bool flipX, bool flipY) {
 }
 
 void bzSprExt(size_t n, BZCoordinate x, BZCoordinate y, BZCoordinate w, BZCoordinate h, bool flipX, bool flipY) {
-       int px = (n % 16) * 8;
-       int py = (n / 16) * 8;
-       int pw = w * 8;
-       int ph = h * 8;
+       int px = 0;//(n % 16) * 8;
+       int py = n * spritesheet->spriteHeight;//(n / 16) * 8;
+       int pw = w * spritesheet->spriteWidth;
+       int ph = h * spritesheet->spriteHeight;
        bzSSprExt(px, py, pw, ph, x, y, pw, ph, flipX, flipY);
        bzSSprExt(px, py, pw, ph, x, y, pw, ph, flipX, flipY);
+
+//     int px = (n % 16) * 8;
+//     int py = (n / 16) * 8;
+//     int pw = w * 8;
+//     int ph = h * 8;
+//     bzSSprExt(px, py, pw, ph, x, y, pw, ph, flipX, flipY);
 }
 
 void bzSSpr(BZCoordinate sx, BZCoordinate sy, BZCoordinate sw, BZCoordinate sh, BZCoordinate dx, BZCoordinate dy) {
 }
 
 void bzSSpr(BZCoordinate sx, BZCoordinate sy, BZCoordinate sw, BZCoordinate sh, BZCoordinate dx, BZCoordinate dy) {
@@ -572,7 +596,7 @@ void bzSSprExt(BZCoordinate sx, BZCoordinate sy, BZCoordinate sw, BZCoordinate s
 
                for (size_t y = 0; y < osh - (clipTop + clipBottom); ++y) {
                        for (size_t x = 0; x < osw - (clipLeft + clipRight); ++x) {
 
                for (size_t y = 0; y < osh - (clipTop + clipBottom); ++y) {
                        for (size_t x = 0; x < osw - (clipLeft + clipRight); ++x) {
-                               int color = gPalettes[spritesheet[((clipTop+osy+y) << kSpriteSheetStrideShift) + clipLeft+osx+x]];
+                               int color = gPalettes[spritesheet->data[(clipTop+osy+y) * spritesheet->width + clipLeft+osx+x]];
                                if (color > 0) bzBufferSet(currentBuffer, xMinOut+x, yMinOut+y, color); // FIXME, scaled up and 0 check removal??
                        }
                }
                                if (color > 0) bzBufferSet(currentBuffer, xMinOut+x, yMinOut+y, color); // FIXME, scaled up and 0 check removal??
                        }
                }
index c03c73aea52ab0683f326f1148f10a37afaa0c02..9c84b60c7739d8b2b1f25a59ef1cc58b9193224b 100644 (file)
@@ -12,7 +12,7 @@ extern "C" {
 extern void bzGfxPreparePalettes(BZMemoryArenaID arena, size_t paletteCount, size_t colorCount);
 extern void bzGfxPrepareCanvasBuffer(BZMemoryArenaID arena, size_t width, size_t height);
 
 extern void bzGfxPreparePalettes(BZMemoryArenaID arena, size_t paletteCount, size_t colorCount);
 extern void bzGfxPrepareCanvasBuffer(BZMemoryArenaID arena, size_t width, size_t height);
 
-extern void bzGfxPrepareSpritesheet(BZMemoryArenaID arena, size_t width, size_t height, void *data);
+extern void bzGfxPrepareSpritesheet(BZMemoryArenaID arena, size_t frames, size_t width, size_t height, void *data);
 extern void bzGfxPrepareFont(BZMemoryArenaID arena, void *font);
 
 extern void bzGfxComposite(void);
 extern void bzGfxPrepareFont(BZMemoryArenaID arena, void *font);
 
 extern void bzGfxComposite(void);
index 079bb8f7a9328df57caf70007a8793eca0ec35ed..42ffc98089f64871c0b047ec979fc0e990492c33 100644 (file)
@@ -1,6 +1,7 @@
 #include <bz/memory/arena_internal.h>
 
 #include <bz/memory/allocator.h>
 #include <bz/memory/arena_internal.h>
 
 #include <bz/memory/allocator.h>
+#include <bz/types/identifier_internal.h>
 #include <stdalign.h>
 #include <stddef.h>
 #include <string.h> // memset... :rolleyes:
 #include <stdalign.h>
 #include <stddef.h>
 #include <string.h> // memset... :rolleyes:
@@ -28,7 +29,9 @@ static size_t allocateSize(size_t size) {
 BZMemoryArenaID bzMemoryArenaCreate(BZMemoryArenaID hostArena, size_t size, const char *nameFmt, ...) {
        bzAssert(size == allocateSize(size));
        if (nextUserArena < kMaxUserArenas) {
 BZMemoryArenaID bzMemoryArenaCreate(BZMemoryArenaID hostArena, size_t size, const char *nameFmt, ...) {
        bzAssert(size == allocateSize(size));
        if (nextUserArena < kMaxUserArenas) {
-               return bzMemoryArenaAllocate(&userArenas[++nextUserArena], hostArena, size);
+               BZMemoryArenaID arena = bzMemoryArenaAllocate(&userArenas[++nextUserArena], hostArena, size);
+               bzInsertIdentifier(((char *)arena->identifier), nameFmt);
+               return arena;
        } else {
                bzError("Too many arenas");
                return NULL;
        } else {
                bzError("Too many arenas");
                return NULL;
@@ -107,7 +110,7 @@ void *_bzMemoryAlloc(BZMemoryArenaID arena, size_t size, const char *filename, s
                arena->allocationOffsetBottom += fullSize;
        }
        
                arena->allocationOffsetBottom += fullSize;
        }
        
-       bzAssertMessage(ptr != NULL, "Arena is out of memory, failed %s:%d", filename, lineNumber);
+       bzAssertMessage(ptr != NULL, "Arena '%s' is out of memory, failed %s:%d", arena->identifier, filename, lineNumber);
 
        return ptr;
 }
 
        return ptr;
 }
index 8eab3ba249f4d89632ec3284d338b4b025519880..339e443f4ec022cea4f9847c4d7ed41c5fbbc362 100644 (file)
@@ -3,6 +3,8 @@
 
 #include <bz/memory/arena.h>
 
 
 #include <bz/memory/arena.h>
 
+#include <bz/types/identifier.h>
+
 #ifdef __cplusplus
 extern "C" {
 #endif
 #ifdef __cplusplus
 extern "C" {
 #endif
@@ -10,6 +12,8 @@ extern "C" {
 #define MAX_WATERMARKS 16
 
 struct BZMemoryArena {
 #define MAX_WATERMARKS 16
 
 struct BZMemoryArena {
+       char *identifier[kBZMaxIdentifierLength];
+
        size_t maxSize;
        uint8_t *memory;
        bool zeroOut;
        size_t maxSize;
        uint8_t *memory;
        bool zeroOut;