this repo has no description
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

play with some interesting macros

Nesbox e26c21ec 3ac7a66b

+727 -715
+63 -63
include/tic80.h
··· 29 29 extern "C" { 30 30 #endif 31 31 32 - #define TIC80_WIDTH 240 33 - #define TIC80_HEIGHT 136 34 - #define TIC80_FULLWIDTH_BITS 8 35 - #define TIC80_FULLWIDTH (1 << TIC80_FULLWIDTH_BITS) 36 - #define TIC80_FULLHEIGHT (TIC80_FULLWIDTH*9/16) 37 - #define TIC80_KEY_BUFFER 4 38 - #define TIC80_SAMPLERATE 44100 39 - #define TIC80_FRAMERATE 60 32 + #define TIC80_WIDTH 240 33 + #define TIC80_HEIGHT 136 34 + #define TIC80_FULLWIDTH_BITS 8 35 + #define TIC80_FULLWIDTH (1 << TIC80_FULLWIDTH_BITS) 36 + #define TIC80_FULLHEIGHT (TIC80_FULLWIDTH*9/16) 37 + #define TIC80_KEY_BUFFER 4 38 + #define TIC80_SAMPLERATE 44100 39 + #define TIC80_FRAMERATE 60 40 40 41 41 typedef enum { 42 42 TIC80_PIXEL_COLOR_ARGB8888 = (1 << 8) | 32, ··· 47 47 48 48 typedef struct 49 49 { 50 - struct 51 - { 52 - void (*trace)(const char* text, u8 color); 53 - void (*error)(const char* info); 54 - void (*exit)(); 55 - } callback; 50 + struct 51 + { 52 + void (*trace)(const char* text, u8 color); 53 + void (*error)(const char* info); 54 + void (*exit)(); 55 + } callback; 56 56 57 - struct 58 - { 59 - s16* samples; 60 - s32 count; 61 - } sound; 57 + struct 58 + { 59 + s16* samples; 60 + s32 count; 61 + } sound; 62 62 63 - u32* screen; 64 - tic80_pixel_color_format screen_format; 65 - 63 + u32* screen; 64 + tic80_pixel_color_format screen_format; 65 + 66 66 } tic80; 67 67 68 68 typedef union 69 69 { 70 - struct 71 - { 72 - bool up:1; 73 - bool down:1; 74 - bool left:1; 75 - bool right:1; 76 - bool a:1; 77 - bool b:1; 78 - bool x:1; 79 - bool y:1; 80 - }; 70 + struct 71 + { 72 + bool up:1; 73 + bool down:1; 74 + bool left:1; 75 + bool right:1; 76 + bool a:1; 77 + bool b:1; 78 + bool x:1; 79 + bool y:1; 80 + }; 81 81 82 - u8 data; 82 + u8 data; 83 83 } tic80_gamepad; 84 84 85 85 typedef union 86 86 { 87 - struct 88 - { 89 - tic80_gamepad first; 90 - tic80_gamepad second; 91 - tic80_gamepad third; 92 - tic80_gamepad fourth; 93 - }; 87 + struct 88 + { 89 + tic80_gamepad first; 90 + tic80_gamepad second; 91 + tic80_gamepad third; 92 + tic80_gamepad fourth; 93 + }; 94 94 95 - u32 data; 95 + u32 data; 96 96 } tic80_gamepads; 97 97 98 98 typedef struct 99 99 { 100 - u8 x; 101 - u8 y; 102 - 103 - union 104 - { 105 - struct 106 - { 107 - u16 left:1; 108 - u16 middle:1; 109 - u16 right:1; 100 + u8 x; 101 + u8 y; 102 + 103 + union 104 + { 105 + struct 106 + { 107 + u16 left:1; 108 + u16 middle:1; 109 + u16 right:1; 110 110 111 - s16 scrollx:6; 112 - s16 scrolly:6; 111 + s16 scrollx:6; 112 + s16 scrolly:6; 113 113 114 - u16 temp:1; 115 - }; 114 + u16 temp:1; 115 + }; 116 116 117 - u16 btns; 118 - }; 117 + u16 btns; 118 + }; 119 119 } tic80_mouse; 120 120 121 121 typedef u8 tic_key; 122 122 123 123 typedef union 124 124 { 125 - tic_key keys[TIC80_KEY_BUFFER]; 126 - u32 data; 125 + tic_key keys[TIC80_KEY_BUFFER]; 126 + u32 data; 127 127 } tic80_keyboard; 128 128 129 129 typedef struct 130 130 { 131 - tic80_gamepads gamepads; 132 - tic80_mouse mouse; 133 - tic80_keyboard keyboard; 131 + tic80_gamepads gamepads; 132 + tic80_mouse mouse; 133 + tic80_keyboard keyboard; 134 134 135 135 } tic80_input; 136 136
+3 -3
src/api.h
··· 121 121 #define OVR_FN "OVR" 122 122 123 123 #define TIC_CALLBACK_LIST(macro) \ 124 - macro(TIC_FN, TIC_FN "()", "Main function. It's called at 60 fps (60 times every second).") \ 124 + macro(TIC_FN, TIC_FN "()", "Main function. It's called at " DEF2STR(TIC80_FRAMERATE) \ 125 + "fps (" DEF2STR(TIC80_FRAMERATE) " times every second).") \ 125 126 macro(SCN_FN, SCN_FN "(row)", "Allows you to execute code between the drawing of each scanline, " \ 126 127 "for example, to manipulate the palette.") \ 127 128 macro(OVR_FN, OVR_FN "()", "Called after each frame;" \ ··· 159 160 \ 160 161 "Clear the screen.\n" \ 161 162 "When called this function clear all the screen using the color passed as argument.\n" \ 162 - "If no parameter is passed first color (0) is used.\n" \ 163 - "\nTips: Use a color over 15 to see some special fill pattern.", \ 163 + "If no parameter is passed first color (0) is used.", \ 164 164 1, \ 165 165 void, \ 166 166 tic_mem*, u8 color) \
+1 -1
src/core/core.c
··· 375 375 #undef TIC_SYNC_DEF 376 376 count, 377 377 all = (1 << count) - 1, 378 - noscreen = BIT_CLEAR(all, sync_screen) 378 + noscreen = BITCLEAR(all, sync_screen) 379 379 }; 380 380 381 381 // don't sync empty screen
+24 -20
src/defines.h
··· 22 22 23 23 #pragma once 24 24 25 - #define COUNT_OF(x) ((sizeof(x)/sizeof(0[x])) / ((size_t)(!(sizeof(x) % sizeof(0[x]))))) 26 - #define MIN(a,b) ((a) < (b) ? (a) : (b)) 27 - #define MAX(a,b) ((a) > (b) ? (a) : (b)) 28 - #define CLAMP(v,a,b) (MIN(MAX(v,a),b)) 29 - #define SWAP(a, b, type) do { type temp = a; a = b; b = temp; } while (0) 30 - #define ZEROMEM(p) memset(&p, 0, sizeof p) 31 - #define MOVE(...) memmove(malloc(sizeof __VA_ARGS__), &__VA_ARGS__, sizeof __VA_ARGS__) 32 - #define DEF2STR2(x) #x 33 - #define DEF2STR(x) DEF2STR2(x) 34 - #define STRLEN(str) (sizeof str - 1) 35 - #define FOR(type,it,list) for(type it = list, *__end__ = it + COUNT_OF(list); it != __end__; ++it) 36 - #define FREE(ptr) do { if(ptr) free(ptr); } while (0) 37 - 38 - #define BIT_SET(a,b) ((a) | (1ULL<<(b))) 39 - #define BIT_CLEAR(a,b) ((a) & ~(1ULL<<(b))) 40 - #define BIT_FLIP(a,b) ((a) ^ (1ULL<<(b))) 41 - #define BIT_CHECK(a,b) (!!((a) & (1ULL<<(b)))) 25 + #define COUNT_OF(x) ((sizeof(x)/sizeof(0[x])) / ((size_t)(!(sizeof(x) % sizeof(0[x]))))) 26 + #define MIN(a,b) ((a) < (b) ? (a) : (b)) 27 + #define MAX(a,b) ((a) > (b) ? (a) : (b)) 28 + #define CLAMP(v,a,b) (MIN(MAX(v,a),b)) 29 + #define SWAP(a, b, type) do { type temp = a; a = b; b = temp; } while (0) 30 + #define ZEROMEM(p) memset(&p, 0, sizeof p) 31 + #define MOVE(...) memmove(malloc(sizeof __VA_ARGS__), &__VA_ARGS__, sizeof __VA_ARGS__) 32 + #define DEF2STR2(x) #x 33 + #define DEF2STR(x) DEF2STR2(x) 34 + #define STRLEN(str) (sizeof str - 1) 35 + #define CONCAT2(a, b) a ## b 36 + #define CONCAT(a, b) CONCAT2(a, b) 37 + #define MACROVAR(name) CONCAT(name, __LINE__) 38 + #define DEFER(start, end) for(int MACROVAR(_i_) = (start,0); !MACROVAR(_i_); ++MACROVAR(_i_), end) 39 + #define SCOPE(exp) for(int MACROVAR(_i_) = 0; !MACROVAR(_i_); ++MACROVAR(_i_), exp) 40 + #define FOR(type,it,list) for(type it = list, *MACROVAR(_end_) = it + COUNT_OF(list); it != MACROVAR(_end_); ++it) 41 + #define FREE(ptr) do { if(ptr) free(ptr); } while (0) 42 42 43 - #define BIT_SET_LV(a,b) ((a) |= (1ULL<<(b))) 44 - #define BIT_CLEAR_LV(a,b) ((a) &= ~(1ULL<<(b))) 45 - #define BIT_FLIP_LV(a,b) ((a) ^= (1ULL<<(b))) 43 + #define BITSET(a,b) ((a) | (1ULL<<(b))) 44 + #define BITCLEAR(a,b) ((a) & ~(1ULL<<(b))) 45 + #define BITFLIP(a,b) ((a) ^ (1ULL<<(b))) 46 + #define BITCHECK(a,b) (!!((a) & (1ULL<<(b)))) 47 + #define _BITSET(a,b) ((a) |= (1ULL<<(b))) 48 + #define _BITCLEAR(a,b) ((a) &= ~(1ULL<<(b))) 49 + #define _BITFLIP(a,b) ((a) ^= (1ULL<<(b)))
+282 -282
src/ext/gif.c
··· 29 29 30 30 static gif_image* readGif(GifFileType *gif) 31 31 { 32 - gif_image* image = NULL; 32 + gif_image* image = NULL; 33 33 34 - s32 error = 0; 34 + s32 error = 0; 35 35 36 - if(gif) 37 - { 38 - if(gif->SHeight > 0 && gif->SWidth > 0) 39 - { 40 - s32 size = gif->SWidth * gif->SHeight * sizeof(GifPixelType); 41 - GifPixelType* screen = (GifPixelType*)malloc(size); 36 + if(gif) 37 + { 38 + if(gif->SHeight > 0 && gif->SWidth > 0) 39 + { 40 + s32 size = gif->SWidth * gif->SHeight * sizeof(GifPixelType); 41 + GifPixelType* screen = (GifPixelType*)malloc(size); 42 42 43 - if(screen) 44 - { 45 - memset(screen, gif->SBackGroundColor, size); 43 + if(screen) 44 + { 45 + memset(screen, gif->SBackGroundColor, size); 46 46 47 - GifRecordType record = UNDEFINED_RECORD_TYPE; 47 + GifRecordType record = UNDEFINED_RECORD_TYPE; 48 48 49 - do 50 - { 51 - if(DGifGetRecordType(gif, &record) == GIF_ERROR) 52 - { 53 - error = gif->Error; 54 - break; 55 - } 49 + do 50 + { 51 + if(DGifGetRecordType(gif, &record) == GIF_ERROR) 52 + { 53 + error = gif->Error; 54 + break; 55 + } 56 56 57 - switch (record) 58 - { 59 - case IMAGE_DESC_RECORD_TYPE: 60 - { 61 - if(DGifGetImageDesc(gif) == GIF_ERROR) 62 - error = gif->Error; 57 + switch (record) 58 + { 59 + case IMAGE_DESC_RECORD_TYPE: 60 + { 61 + if(DGifGetImageDesc(gif) == GIF_ERROR) 62 + error = gif->Error; 63 63 64 - s32 row = gif->Image.Top; 65 - s32 col = gif->Image.Left; 66 - s32 width = gif->Image.Width; 67 - s32 height = gif->Image.Height; 64 + s32 row = gif->Image.Top; 65 + s32 col = gif->Image.Left; 66 + s32 width = gif->Image.Width; 67 + s32 height = gif->Image.Height; 68 68 69 - if (gif->Image.Left + gif->Image.Width > gif->SWidth || 70 - gif->Image.Top + gif->Image.Height > gif->SHeight) 71 - error = E_GIF_ERR_OPEN_FAILED; 69 + if (gif->Image.Left + gif->Image.Width > gif->SWidth || 70 + gif->Image.Top + gif->Image.Height > gif->SHeight) 71 + error = E_GIF_ERR_OPEN_FAILED; 72 72 73 - if (gif->Image.Interlace) 74 - { 75 - s32 InterlacedOffset[] = { 0, 4, 2, 1 }; 76 - s32 InterlacedJumps[] = { 8, 8, 4, 2 }; 73 + if (gif->Image.Interlace) 74 + { 75 + s32 InterlacedOffset[] = { 0, 4, 2, 1 }; 76 + s32 InterlacedJumps[] = { 8, 8, 4, 2 }; 77 77 78 - for (s32 i = 0; i < 4; i++) 79 - for (s32 j = row + InterlacedOffset[i]; j < row + height; j += InterlacedJumps[i]) 80 - { 81 - if(DGifGetLine(gif, screen + j * gif->SWidth + col, width) == GIF_ERROR) 82 - { 83 - error = gif->Error; 84 - break; 85 - } 86 - } 87 - } 88 - else 89 - { 90 - for (s32 i = 0; i < height; i++, row++) 91 - { 92 - if(DGifGetLine(gif, screen + row * gif->SWidth + col, width) == GIF_ERROR) 93 - { 94 - error = gif->Error; 95 - break; 96 - } 97 - } 98 - } 99 - } 100 - break; 78 + for (s32 i = 0; i < 4; i++) 79 + for (s32 j = row + InterlacedOffset[i]; j < row + height; j += InterlacedJumps[i]) 80 + { 81 + if(DGifGetLine(gif, screen + j * gif->SWidth + col, width) == GIF_ERROR) 82 + { 83 + error = gif->Error; 84 + break; 85 + } 86 + } 87 + } 88 + else 89 + { 90 + for (s32 i = 0; i < height; i++, row++) 91 + { 92 + if(DGifGetLine(gif, screen + row * gif->SWidth + col, width) == GIF_ERROR) 93 + { 94 + error = gif->Error; 95 + break; 96 + } 97 + } 98 + } 99 + } 100 + break; 101 101 102 - case EXTENSION_RECORD_TYPE: 103 - { 104 - s32 extCode = 0; 105 - GifByteType* extension = NULL; 102 + case EXTENSION_RECORD_TYPE: 103 + { 104 + s32 extCode = 0; 105 + GifByteType* extension = NULL; 106 106 107 - if (DGifGetExtension(gif, &extCode, &extension) == GIF_ERROR) 108 - error = gif->Error; 109 - else 110 - { 111 - while (extension != NULL) 112 - { 113 - if(DGifGetExtensionNext(gif, &extension) == GIF_ERROR) 114 - { 115 - error = gif->Error; 116 - break; 117 - } 118 - } 119 - } 120 - } 121 - break; 122 - case TERMINATE_RECORD_TYPE: 123 - break; 124 - default: break; 125 - } 107 + if (DGifGetExtension(gif, &extCode, &extension) == GIF_ERROR) 108 + error = gif->Error; 109 + else 110 + { 111 + while (extension != NULL) 112 + { 113 + if(DGifGetExtensionNext(gif, &extension) == GIF_ERROR) 114 + { 115 + error = gif->Error; 116 + break; 117 + } 118 + } 119 + } 120 + } 121 + break; 122 + case TERMINATE_RECORD_TYPE: 123 + break; 124 + default: break; 125 + } 126 126 127 - if(error != E_GIF_SUCCEEDED) 128 - break; 129 - } 130 - while(record != TERMINATE_RECORD_TYPE); 127 + if(error != E_GIF_SUCCEEDED) 128 + break; 129 + } 130 + while(record != TERMINATE_RECORD_TYPE); 131 131 132 - if(error == E_GIF_SUCCEEDED) 133 - { 132 + if(error == E_GIF_SUCCEEDED) 133 + { 134 134 135 - image = (gif_image*)malloc(sizeof(gif_image)); 135 + image = (gif_image*)malloc(sizeof(gif_image)); 136 136 137 - if(image) 138 - { 139 - memset(image, 0, sizeof(gif_image)); 140 - image->buffer = screen; 141 - image->width = gif->SWidth; 142 - image->height = gif->SHeight; 137 + if(image) 138 + { 139 + memset(image, 0, sizeof(gif_image)); 140 + image->buffer = screen; 141 + image->width = gif->SWidth; 142 + image->height = gif->SHeight; 143 143 144 - ColorMapObject* colorMap = gif->Image.ColorMap ? gif->Image.ColorMap : gif->SColorMap; 144 + ColorMapObject* colorMap = gif->Image.ColorMap ? gif->Image.ColorMap : gif->SColorMap; 145 145 146 - image->colors = colorMap->ColorCount; 146 + image->colors = colorMap->ColorCount; 147 147 148 - s32 size = image->colors * sizeof(gif_color); 149 - image->palette = malloc(size); 148 + s32 size = image->colors * sizeof(gif_color); 149 + image->palette = malloc(size); 150 150 151 - memcpy(image->palette, colorMap->Colors, size); 152 - } 153 - } 154 - else free(screen); 155 - } 156 - } 151 + memcpy(image->palette, colorMap->Colors, size); 152 + } 153 + } 154 + else free(screen); 155 + } 156 + } 157 157 158 - DGifCloseFile(gif, &error); 159 - } 158 + DGifCloseFile(gif, &error); 159 + } 160 160 161 - return image; 161 + return image; 162 162 } 163 163 164 164 typedef struct 165 165 { 166 - const void* data; 167 - s32 pos; 166 + const void* data; 167 + s32 pos; 168 168 } GifBuffer; 169 169 170 170 static s32 readBuffer(GifFileType* gif, GifByteType* data, s32 size) 171 171 { 172 - GifBuffer* buffer = (GifBuffer*)gif->UserData; 172 + GifBuffer* buffer = (GifBuffer*)gif->UserData; 173 173 174 - memcpy(data, (const u8*)buffer->data + buffer->pos, size); 175 - buffer->pos += size; 174 + memcpy(data, (const u8*)buffer->data + buffer->pos, size); 175 + buffer->pos += size; 176 176 177 - return size; 177 + return size; 178 178 } 179 179 180 180 gif_image* gif_read_data(const void* data, s32 size) 181 181 { 182 - GifBuffer buffer = {data, 0}; 183 - GifFileType *gif = DGifOpen(&buffer, readBuffer, NULL); 182 + GifBuffer buffer = {data, 0}; 183 + GifFileType *gif = DGifOpen(&buffer, readBuffer, NULL); 184 184 185 - return readGif(gif); 185 + return readGif(gif); 186 186 } 187 187 188 188 static bool writeGif(GifFileType* gif, s32 width, s32 height, const u8* data, const gif_color* palette, u8 bpp) 189 189 { 190 - bool result = false; 191 - s32 error = 0; 190 + bool result = false; 191 + s32 error = 0; 192 192 193 - if(gif) 194 - { 195 - s32 colors = 1 << bpp; 196 - ColorMapObject* colorMap = GifMakeMapObject(colors, NULL); 193 + if(gif) 194 + { 195 + s32 colors = 1 << bpp; 196 + ColorMapObject* colorMap = GifMakeMapObject(colors, NULL); 197 197 198 - memcpy(colorMap->Colors, palette, colors * sizeof(GifColorType)); 198 + memcpy(colorMap->Colors, palette, colors * sizeof(GifColorType)); 199 199 200 - if(EGifPutScreenDesc(gif, width, height, bpp, 0, colorMap) != GIF_ERROR) 201 - { 202 - if(EGifPutImageDesc(gif, 0, 0, width, height, false, NULL) != GIF_ERROR) 203 - { 204 - GifByteType* ptr = (GifByteType*)data; 205 - for (s32 i = 0; i < height; i++, ptr += width) 206 - { 207 - if (EGifPutLine(gif, ptr, width) == GIF_ERROR) 208 - { 209 - error = gif->Error; 210 - break; 211 - } 212 - } 200 + if(EGifPutScreenDesc(gif, width, height, bpp, 0, colorMap) != GIF_ERROR) 201 + { 202 + if(EGifPutImageDesc(gif, 0, 0, width, height, false, NULL) != GIF_ERROR) 203 + { 204 + GifByteType* ptr = (GifByteType*)data; 205 + for (s32 i = 0; i < height; i++, ptr += width) 206 + { 207 + if (EGifPutLine(gif, ptr, width) == GIF_ERROR) 208 + { 209 + error = gif->Error; 210 + break; 211 + } 212 + } 213 213 214 - result = error == E_GIF_SUCCEEDED; 215 - } 216 - } 214 + result = error == E_GIF_SUCCEEDED; 215 + } 216 + } 217 217 218 - EGifCloseFile(gif, &error); 219 - GifFreeMapObject(colorMap); 220 - } 218 + EGifCloseFile(gif, &error); 219 + GifFreeMapObject(colorMap); 220 + } 221 221 222 - return result; 222 + return result; 223 223 } 224 224 225 225 static s32 writeBuffer(GifFileType* gif, const GifByteType* data, s32 size) 226 226 { 227 - GifBuffer* buffer = (GifBuffer*)gif->UserData; 227 + GifBuffer* buffer = (GifBuffer*)gif->UserData; 228 228 229 - memcpy((u8*)buffer->data + buffer->pos, data, size); 230 - buffer->pos += size; 229 + memcpy((u8*)buffer->data + buffer->pos, data, size); 230 + buffer->pos += size; 231 231 232 - return size; 232 + return size; 233 233 } 234 234 235 235 bool gif_write_data(const void* buffer, s32* size, s32 width, s32 height, const u8* data, const gif_color* palette, u8 bpp) 236 236 { 237 - s32 error = 0; 238 - GifBuffer output = {buffer, 0}; 239 - GifFileType* gif = EGifOpen(&output, writeBuffer, &error); 237 + s32 error = 0; 238 + GifBuffer output = {buffer, 0}; 239 + GifFileType* gif = EGifOpen(&output, writeBuffer, &error); 240 240 241 - bool result = writeGif(gif, width, height, data, palette, bpp); 241 + bool result = writeGif(gif, width, height, data, palette, bpp); 242 242 243 - *size = output.pos; 243 + *size = output.pos; 244 244 245 - return result; 245 + return result; 246 246 } 247 247 248 248 void gif_close(gif_image* image) 249 249 { 250 - if(image) 251 - { 252 - if(image->buffer) free(image->buffer); 253 - if(image->palette) free(image->palette); 250 + if(image) 251 + { 252 + if(image->buffer) free(image->buffer); 253 + if(image->palette) free(image->palette); 254 254 255 - free(image); 256 - } 255 + free(image); 256 + } 257 257 } 258 258 259 259 static bool AddLoop(GifFileType *gif) 260 260 { 261 - { 262 - const char *nsle = "NETSCAPE2.0"; 263 - const char subblock[] = { 264 - 1, // always 1 265 - 0, // little-endian loop counter: 266 - 0 // 0 for infinite loop. 267 - }; 261 + { 262 + const char *nsle = "NETSCAPE2.0"; 263 + const char subblock[] = { 264 + 1, // always 1 265 + 0, // little-endian loop counter: 266 + 0 // 0 for infinite loop. 267 + }; 268 268 269 - EGifPutExtensionLeader(gif, APPLICATION_EXT_FUNC_CODE); 270 - EGifPutExtensionBlock(gif, 11, nsle); 271 - EGifPutExtensionBlock(gif, 3, subblock); 272 - EGifPutExtensionTrailer(gif); 273 - } 269 + EGifPutExtensionLeader(gif, APPLICATION_EXT_FUNC_CODE); 270 + EGifPutExtensionBlock(gif, 11, nsle); 271 + EGifPutExtensionBlock(gif, 3, subblock); 272 + EGifPutExtensionTrailer(gif); 273 + } 274 274 275 - return true; 275 + return true; 276 276 } 277 277 278 278 static const u8* toColor(const u8* ptr, gif_color* color) 279 279 { 280 - color->r = *ptr++; 281 - color->g = *ptr++; 282 - color->b = *ptr++; 283 - ptr++; 280 + color->r = *ptr++; 281 + color->g = *ptr++; 282 + color->b = *ptr++; 283 + ptr++; 284 284 285 - return ptr; 285 + return ptr; 286 286 } 287 287 288 288 bool gif_write_animation(const void* buffer, s32* size, s32 width, s32 height, const u8* data, s32 frames, s32 fps, s32 scale) 289 289 { 290 - bool result = false; 290 + bool result = false; 291 291 292 - s32 swidth = width*scale, sheight = height*scale; 293 - s32 frameSize = width * height; 292 + s32 swidth = width*scale, sheight = height*scale; 293 + s32 frameSize = width * height; 294 294 295 - enum{Bpp = 8, PalSize = 1 << Bpp, PalStructSize = PalSize * sizeof(gif_color)}; 295 + enum{Bpp = 8, PalSize = 1 << Bpp, PalStructSize = PalSize * sizeof(gif_color)}; 296 296 297 - s32 error = 0; 298 - GifBuffer output = {buffer, 0}; 299 - GifFileType* gif = EGifOpen(&output, writeBuffer, &error); 297 + s32 error = 0; 298 + GifBuffer output = {buffer, 0}; 299 + GifFileType* gif = EGifOpen(&output, writeBuffer, &error); 300 300 301 - if(gif) 302 - { 303 - EGifSetGifVersion(gif, true); 301 + if(gif) 302 + { 303 + EGifSetGifVersion(gif, true); 304 304 305 - if(EGifPutScreenDesc(gif, swidth, sheight, Bpp, 0, NULL) != GIF_ERROR) 306 - { 307 - if(AddLoop(gif)) 308 - { 309 - gif_color* palette = (gif_color*)malloc(PalStructSize); 310 - u8* screen = malloc(frameSize); 311 - u8* line = malloc(swidth); 305 + if(EGifPutScreenDesc(gif, swidth, sheight, Bpp, 0, NULL) != GIF_ERROR) 306 + { 307 + if(AddLoop(gif)) 308 + { 309 + gif_color* palette = (gif_color*)malloc(PalStructSize); 310 + u8* screen = malloc(frameSize); 311 + u8* line = malloc(swidth); 312 312 313 - for(s32 f = 0; f < frames; f++) 314 - { 315 - enum {DelayUnits = 100, MinDelay = 2}; 313 + for(s32 f = 0; f < frames; f++) 314 + { 315 + enum {DelayUnits = 100, MinDelay = 2}; 316 316 317 - s32 frame = (f * fps * MinDelay * 2 + 1) / (2 * DelayUnits); 317 + s32 frame = (f * fps * MinDelay * 2 + 1) / (2 * DelayUnits); 318 318 319 - if(frame >= frames) 320 - break; 319 + if(frame >= frames) 320 + break; 321 321 322 - s32 colors = 0; 323 - const u8* ptr = data + frameSize*frame*sizeof(u32); 324 - 325 - { 326 - memset(palette, 0, PalStructSize); 327 - memset(screen, 0, frameSize); 322 + s32 colors = 0; 323 + const u8* ptr = data + frameSize*frame*sizeof(u32); 324 + 325 + { 326 + memset(palette, 0, PalStructSize); 327 + memset(screen, 0, frameSize); 328 328 329 - for(s32 i = 0; i < frameSize; i++) 330 - { 331 - if(colors >= PalSize) break; 329 + for(s32 i = 0; i < frameSize; i++) 330 + { 331 + if(colors >= PalSize) break; 332 332 333 - gif_color color; 334 - toColor(ptr + i*sizeof(u32), &color); 333 + gif_color color; 334 + toColor(ptr + i*sizeof(u32), &color); 335 335 336 - bool found = false; 337 - for(s32 c = 0; c < colors; c++) 338 - { 339 - if(memcmp(&palette[c], &color, sizeof(gif_color)) == 0) 340 - { 341 - found = true; 342 - screen[i] = c; 343 - break; 344 - } 345 - } 336 + bool found = false; 337 + for(s32 c = 0; c < colors; c++) 338 + { 339 + if(memcmp(&palette[c], &color, sizeof(gif_color)) == 0) 340 + { 341 + found = true; 342 + screen[i] = c; 343 + break; 344 + } 345 + } 346 346 347 - if(!found) 348 - { 349 - // TODO: check for last color in palette and try to find closest color 350 - screen[i] = colors; 351 - memcpy(&palette[colors], &color, sizeof(gif_color)); 352 - colors++; 353 - } 354 - } 355 - } 347 + if(!found) 348 + { 349 + // TODO: check for last color in palette and try to find closest color 350 + screen[i] = colors; 351 + memcpy(&palette[colors], &color, sizeof(gif_color)); 352 + colors++; 353 + } 354 + } 355 + } 356 356 357 - { 358 - GraphicsControlBlock gcb = 359 - { 360 - .DisposalMode = DISPOSE_DO_NOT, 361 - .UserInputFlag = false, 362 - .DelayTime = MinDelay, 363 - .TransparentColor = -1, 364 - }; 357 + { 358 + GraphicsControlBlock gcb = 359 + { 360 + .DisposalMode = DISPOSE_DO_NOT, 361 + .UserInputFlag = false, 362 + .DelayTime = MinDelay, 363 + .TransparentColor = -1, 364 + }; 365 365 366 - u8 ext[4]; 367 - EGifGCBToExtension(&gcb, ext); 368 - EGifPutExtension(gif, GRAPHICS_EXT_FUNC_CODE, sizeof ext, ext); 369 - } 366 + u8 ext[4]; 367 + EGifGCBToExtension(&gcb, ext); 368 + EGifPutExtension(gif, GRAPHICS_EXT_FUNC_CODE, sizeof ext, ext); 369 + } 370 370 371 - ColorMapObject* colorMap = GifMakeMapObject(PalSize, NULL); 372 - memset(colorMap->Colors, 0, PalStructSize); 373 - memcpy(colorMap->Colors, palette, colors * sizeof(GifColorType)); 371 + ColorMapObject* colorMap = GifMakeMapObject(PalSize, NULL); 372 + memset(colorMap->Colors, 0, PalStructSize); 373 + memcpy(colorMap->Colors, palette, colors * sizeof(GifColorType)); 374 374 375 - if(EGifPutImageDesc(gif, 0, 0, swidth, sheight, false, colorMap) != GIF_ERROR) 376 - { 377 - for(s32 y = 0; y < height; y++) 378 - { 379 - for(s32 x = 0, pos = y*width; x < width; x++, pos++) 380 - { 381 - u8 color = screen[pos]; 382 - for(s32 s = 0, pos = x*scale; s < scale; s++, pos++) 383 - line[pos] = color; 384 - } 375 + if(EGifPutImageDesc(gif, 0, 0, swidth, sheight, false, colorMap) != GIF_ERROR) 376 + { 377 + for(s32 y = 0; y < height; y++) 378 + { 379 + for(s32 x = 0, pos = y*width; x < width; x++, pos++) 380 + { 381 + u8 color = screen[pos]; 382 + for(s32 s = 0, pos = x*scale; s < scale; s++, pos++) 383 + line[pos] = color; 384 + } 385 385 386 - for(s32 s = 0; s < scale; s++) 387 - { 388 - if (EGifPutLine(gif, line, swidth) == GIF_ERROR) 389 - { 390 - error = gif->Error; 391 - break; 392 - } 393 - } 386 + for(s32 s = 0; s < scale; s++) 387 + { 388 + if (EGifPutLine(gif, line, swidth) == GIF_ERROR) 389 + { 390 + error = gif->Error; 391 + break; 392 + } 393 + } 394 394 395 - if(error != E_GIF_SUCCEEDED) break; 396 - } 395 + if(error != E_GIF_SUCCEEDED) break; 396 + } 397 397 398 - *size = output.pos; 398 + *size = output.pos; 399 399 400 - result = error == E_GIF_SUCCEEDED; 401 - } 400 + result = error == E_GIF_SUCCEEDED; 401 + } 402 402 403 - GifFreeMapObject(colorMap); 403 + GifFreeMapObject(colorMap); 404 404 405 - if(!result) 406 - break; 407 - } 405 + if(!result) 406 + break; 407 + } 408 408 409 - free(line); 410 - free(screen); 411 - free(palette); 412 - } 413 - } 409 + free(line); 410 + free(screen); 411 + free(palette); 412 + } 413 + } 414 414 415 - EGifCloseFile(gif, &error); 415 + EGifCloseFile(gif, &error); 416 416 417 - *size = output.pos; 418 - } 417 + *size = output.pos; 418 + } 419 419 420 - return result; 420 + return result; 421 421 }
+8 -8
src/ext/gif.h
··· 26 26 27 27 typedef struct 28 28 { 29 - u8 r; 30 - u8 g; 31 - u8 b; 29 + u8 r; 30 + u8 g; 31 + u8 b; 32 32 }gif_color; 33 33 34 34 typedef struct 35 35 { 36 - u8* buffer; 36 + u8* buffer; 37 37 38 - gif_color* palette; 38 + gif_color* palette; 39 39 40 - s32 width; 41 - s32 height; 40 + s32 width; 41 + s32 height; 42 42 43 - s32 colors; 43 + s32 colors; 44 44 } gif_image; 45 45 46 46 gif_image* gif_read_data(const void* buffer, s32 size);
+157 -157
src/ext/md5.c
··· 46 46 * architectures that lack an AND-NOT instruction, just like in Colin Plumb's 47 47 * implementation. 48 48 */ 49 - #define F(x, y, z) ((z) ^ ((x) & ((y) ^ (z)))) 50 - #define G(x, y, z) ((y) ^ ((z) & ((x) ^ (y)))) 51 - #define H(x, y, z) (((x) ^ (y)) ^ (z)) 52 - #define H2(x, y, z) ((x) ^ ((y) ^ (z))) 53 - #define I(x, y, z) ((y) ^ ((x) | ~(z))) 49 + #define F(x, y, z) ((z) ^ ((x) & ((y) ^ (z)))) 50 + #define G(x, y, z) ((y) ^ ((z) & ((x) ^ (y)))) 51 + #define H(x, y, z) (((x) ^ (y)) ^ (z)) 52 + #define H2(x, y, z) ((x) ^ ((y) ^ (z))) 53 + #define I(x, y, z) ((y) ^ ((x) | ~(z))) 54 54 55 55 /* 56 56 * The MD5 transformation for all four rounds. 57 57 */ 58 58 #define STEP(f, a, b, c, d, x, t, s) \ 59 - (a) += f((b), (c), (d)) + (x) + (t); \ 60 - (a) = (((a) << (s)) | (((a) & 0xffffffff) >> (32 - (s)))); \ 61 - (a) += (b); 59 + (a) += f((b), (c), (d)) + (x) + (t); \ 60 + (a) = (((a) << (s)) | (((a) & 0xffffffff) >> (32 - (s)))); \ 61 + (a) += (b); 62 62 63 63 /* 64 64 * SET reads 4 input bytes in little-endian byte order and stores them in a ··· 77 77 */ 78 78 #if defined(__i386__) || defined(__x86_64__) || defined(__vax__) 79 79 #define SET(n) \ 80 - (*(MD5_u32plus *)&ptr[(n) * 4]) 80 + (*(MD5_u32plus *)&ptr[(n) * 4]) 81 81 #define GET(n) \ 82 - SET(n) 82 + SET(n) 83 83 #else 84 84 #define SET(n) \ 85 - (ctx->block[(n)] = \ 86 - (MD5_u32plus)ptr[(n) * 4] | \ 87 - ((MD5_u32plus)ptr[(n) * 4 + 1] << 8) | \ 88 - ((MD5_u32plus)ptr[(n) * 4 + 2] << 16) | \ 89 - ((MD5_u32plus)ptr[(n) * 4 + 3] << 24)) 85 + (ctx->block[(n)] = \ 86 + (MD5_u32plus)ptr[(n) * 4] | \ 87 + ((MD5_u32plus)ptr[(n) * 4 + 1] << 8) | \ 88 + ((MD5_u32plus)ptr[(n) * 4 + 2] << 16) | \ 89 + ((MD5_u32plus)ptr[(n) * 4 + 3] << 24)) 90 90 #define GET(n) \ 91 - (ctx->block[(n)]) 91 + (ctx->block[(n)]) 92 92 #endif 93 93 94 94 /* ··· 97 97 */ 98 98 static const void *body(MD5_CTX *ctx, const void *data, unsigned long size) 99 99 { 100 - const unsigned char *ptr; 101 - MD5_u32plus a, b, c, d; 102 - MD5_u32plus saved_a, saved_b, saved_c, saved_d; 100 + const unsigned char *ptr; 101 + MD5_u32plus a, b, c, d; 102 + MD5_u32plus saved_a, saved_b, saved_c, saved_d; 103 103 104 - ptr = (const unsigned char *)data; 104 + ptr = (const unsigned char *)data; 105 105 106 - a = ctx->a; 107 - b = ctx->b; 108 - c = ctx->c; 109 - d = ctx->d; 106 + a = ctx->a; 107 + b = ctx->b; 108 + c = ctx->c; 109 + d = ctx->d; 110 110 111 - do { 112 - saved_a = a; 113 - saved_b = b; 114 - saved_c = c; 115 - saved_d = d; 111 + do { 112 + saved_a = a; 113 + saved_b = b; 114 + saved_c = c; 115 + saved_d = d; 116 116 117 117 /* Round 1 */ 118 - STEP(F, a, b, c, d, SET(0), 0xd76aa478, 7) 119 - STEP(F, d, a, b, c, SET(1), 0xe8c7b756, 12) 120 - STEP(F, c, d, a, b, SET(2), 0x242070db, 17) 121 - STEP(F, b, c, d, a, SET(3), 0xc1bdceee, 22) 122 - STEP(F, a, b, c, d, SET(4), 0xf57c0faf, 7) 123 - STEP(F, d, a, b, c, SET(5), 0x4787c62a, 12) 124 - STEP(F, c, d, a, b, SET(6), 0xa8304613, 17) 125 - STEP(F, b, c, d, a, SET(7), 0xfd469501, 22) 126 - STEP(F, a, b, c, d, SET(8), 0x698098d8, 7) 127 - STEP(F, d, a, b, c, SET(9), 0x8b44f7af, 12) 128 - STEP(F, c, d, a, b, SET(10), 0xffff5bb1, 17) 129 - STEP(F, b, c, d, a, SET(11), 0x895cd7be, 22) 130 - STEP(F, a, b, c, d, SET(12), 0x6b901122, 7) 131 - STEP(F, d, a, b, c, SET(13), 0xfd987193, 12) 132 - STEP(F, c, d, a, b, SET(14), 0xa679438e, 17) 133 - STEP(F, b, c, d, a, SET(15), 0x49b40821, 22) 118 + STEP(F, a, b, c, d, SET(0), 0xd76aa478, 7) 119 + STEP(F, d, a, b, c, SET(1), 0xe8c7b756, 12) 120 + STEP(F, c, d, a, b, SET(2), 0x242070db, 17) 121 + STEP(F, b, c, d, a, SET(3), 0xc1bdceee, 22) 122 + STEP(F, a, b, c, d, SET(4), 0xf57c0faf, 7) 123 + STEP(F, d, a, b, c, SET(5), 0x4787c62a, 12) 124 + STEP(F, c, d, a, b, SET(6), 0xa8304613, 17) 125 + STEP(F, b, c, d, a, SET(7), 0xfd469501, 22) 126 + STEP(F, a, b, c, d, SET(8), 0x698098d8, 7) 127 + STEP(F, d, a, b, c, SET(9), 0x8b44f7af, 12) 128 + STEP(F, c, d, a, b, SET(10), 0xffff5bb1, 17) 129 + STEP(F, b, c, d, a, SET(11), 0x895cd7be, 22) 130 + STEP(F, a, b, c, d, SET(12), 0x6b901122, 7) 131 + STEP(F, d, a, b, c, SET(13), 0xfd987193, 12) 132 + STEP(F, c, d, a, b, SET(14), 0xa679438e, 17) 133 + STEP(F, b, c, d, a, SET(15), 0x49b40821, 22) 134 134 135 135 /* Round 2 */ 136 - STEP(G, a, b, c, d, GET(1), 0xf61e2562, 5) 137 - STEP(G, d, a, b, c, GET(6), 0xc040b340, 9) 138 - STEP(G, c, d, a, b, GET(11), 0x265e5a51, 14) 139 - STEP(G, b, c, d, a, GET(0), 0xe9b6c7aa, 20) 140 - STEP(G, a, b, c, d, GET(5), 0xd62f105d, 5) 141 - STEP(G, d, a, b, c, GET(10), 0x02441453, 9) 142 - STEP(G, c, d, a, b, GET(15), 0xd8a1e681, 14) 143 - STEP(G, b, c, d, a, GET(4), 0xe7d3fbc8, 20) 144 - STEP(G, a, b, c, d, GET(9), 0x21e1cde6, 5) 145 - STEP(G, d, a, b, c, GET(14), 0xc33707d6, 9) 146 - STEP(G, c, d, a, b, GET(3), 0xf4d50d87, 14) 147 - STEP(G, b, c, d, a, GET(8), 0x455a14ed, 20) 148 - STEP(G, a, b, c, d, GET(13), 0xa9e3e905, 5) 149 - STEP(G, d, a, b, c, GET(2), 0xfcefa3f8, 9) 150 - STEP(G, c, d, a, b, GET(7), 0x676f02d9, 14) 151 - STEP(G, b, c, d, a, GET(12), 0x8d2a4c8a, 20) 136 + STEP(G, a, b, c, d, GET(1), 0xf61e2562, 5) 137 + STEP(G, d, a, b, c, GET(6), 0xc040b340, 9) 138 + STEP(G, c, d, a, b, GET(11), 0x265e5a51, 14) 139 + STEP(G, b, c, d, a, GET(0), 0xe9b6c7aa, 20) 140 + STEP(G, a, b, c, d, GET(5), 0xd62f105d, 5) 141 + STEP(G, d, a, b, c, GET(10), 0x02441453, 9) 142 + STEP(G, c, d, a, b, GET(15), 0xd8a1e681, 14) 143 + STEP(G, b, c, d, a, GET(4), 0xe7d3fbc8, 20) 144 + STEP(G, a, b, c, d, GET(9), 0x21e1cde6, 5) 145 + STEP(G, d, a, b, c, GET(14), 0xc33707d6, 9) 146 + STEP(G, c, d, a, b, GET(3), 0xf4d50d87, 14) 147 + STEP(G, b, c, d, a, GET(8), 0x455a14ed, 20) 148 + STEP(G, a, b, c, d, GET(13), 0xa9e3e905, 5) 149 + STEP(G, d, a, b, c, GET(2), 0xfcefa3f8, 9) 150 + STEP(G, c, d, a, b, GET(7), 0x676f02d9, 14) 151 + STEP(G, b, c, d, a, GET(12), 0x8d2a4c8a, 20) 152 152 153 153 /* Round 3 */ 154 - STEP(H, a, b, c, d, GET(5), 0xfffa3942, 4) 155 - STEP(H2, d, a, b, c, GET(8), 0x8771f681, 11) 156 - STEP(H, c, d, a, b, GET(11), 0x6d9d6122, 16) 157 - STEP(H2, b, c, d, a, GET(14), 0xfde5380c, 23) 158 - STEP(H, a, b, c, d, GET(1), 0xa4beea44, 4) 159 - STEP(H2, d, a, b, c, GET(4), 0x4bdecfa9, 11) 160 - STEP(H, c, d, a, b, GET(7), 0xf6bb4b60, 16) 161 - STEP(H2, b, c, d, a, GET(10), 0xbebfbc70, 23) 162 - STEP(H, a, b, c, d, GET(13), 0x289b7ec6, 4) 163 - STEP(H2, d, a, b, c, GET(0), 0xeaa127fa, 11) 164 - STEP(H, c, d, a, b, GET(3), 0xd4ef3085, 16) 165 - STEP(H2, b, c, d, a, GET(6), 0x04881d05, 23) 166 - STEP(H, a, b, c, d, GET(9), 0xd9d4d039, 4) 167 - STEP(H2, d, a, b, c, GET(12), 0xe6db99e5, 11) 168 - STEP(H, c, d, a, b, GET(15), 0x1fa27cf8, 16) 169 - STEP(H2, b, c, d, a, GET(2), 0xc4ac5665, 23) 154 + STEP(H, a, b, c, d, GET(5), 0xfffa3942, 4) 155 + STEP(H2, d, a, b, c, GET(8), 0x8771f681, 11) 156 + STEP(H, c, d, a, b, GET(11), 0x6d9d6122, 16) 157 + STEP(H2, b, c, d, a, GET(14), 0xfde5380c, 23) 158 + STEP(H, a, b, c, d, GET(1), 0xa4beea44, 4) 159 + STEP(H2, d, a, b, c, GET(4), 0x4bdecfa9, 11) 160 + STEP(H, c, d, a, b, GET(7), 0xf6bb4b60, 16) 161 + STEP(H2, b, c, d, a, GET(10), 0xbebfbc70, 23) 162 + STEP(H, a, b, c, d, GET(13), 0x289b7ec6, 4) 163 + STEP(H2, d, a, b, c, GET(0), 0xeaa127fa, 11) 164 + STEP(H, c, d, a, b, GET(3), 0xd4ef3085, 16) 165 + STEP(H2, b, c, d, a, GET(6), 0x04881d05, 23) 166 + STEP(H, a, b, c, d, GET(9), 0xd9d4d039, 4) 167 + STEP(H2, d, a, b, c, GET(12), 0xe6db99e5, 11) 168 + STEP(H, c, d, a, b, GET(15), 0x1fa27cf8, 16) 169 + STEP(H2, b, c, d, a, GET(2), 0xc4ac5665, 23) 170 170 171 171 /* Round 4 */ 172 - STEP(I, a, b, c, d, GET(0), 0xf4292244, 6) 173 - STEP(I, d, a, b, c, GET(7), 0x432aff97, 10) 174 - STEP(I, c, d, a, b, GET(14), 0xab9423a7, 15) 175 - STEP(I, b, c, d, a, GET(5), 0xfc93a039, 21) 176 - STEP(I, a, b, c, d, GET(12), 0x655b59c3, 6) 177 - STEP(I, d, a, b, c, GET(3), 0x8f0ccc92, 10) 178 - STEP(I, c, d, a, b, GET(10), 0xffeff47d, 15) 179 - STEP(I, b, c, d, a, GET(1), 0x85845dd1, 21) 180 - STEP(I, a, b, c, d, GET(8), 0x6fa87e4f, 6) 181 - STEP(I, d, a, b, c, GET(15), 0xfe2ce6e0, 10) 182 - STEP(I, c, d, a, b, GET(6), 0xa3014314, 15) 183 - STEP(I, b, c, d, a, GET(13), 0x4e0811a1, 21) 184 - STEP(I, a, b, c, d, GET(4), 0xf7537e82, 6) 185 - STEP(I, d, a, b, c, GET(11), 0xbd3af235, 10) 186 - STEP(I, c, d, a, b, GET(2), 0x2ad7d2bb, 15) 187 - STEP(I, b, c, d, a, GET(9), 0xeb86d391, 21) 172 + STEP(I, a, b, c, d, GET(0), 0xf4292244, 6) 173 + STEP(I, d, a, b, c, GET(7), 0x432aff97, 10) 174 + STEP(I, c, d, a, b, GET(14), 0xab9423a7, 15) 175 + STEP(I, b, c, d, a, GET(5), 0xfc93a039, 21) 176 + STEP(I, a, b, c, d, GET(12), 0x655b59c3, 6) 177 + STEP(I, d, a, b, c, GET(3), 0x8f0ccc92, 10) 178 + STEP(I, c, d, a, b, GET(10), 0xffeff47d, 15) 179 + STEP(I, b, c, d, a, GET(1), 0x85845dd1, 21) 180 + STEP(I, a, b, c, d, GET(8), 0x6fa87e4f, 6) 181 + STEP(I, d, a, b, c, GET(15), 0xfe2ce6e0, 10) 182 + STEP(I, c, d, a, b, GET(6), 0xa3014314, 15) 183 + STEP(I, b, c, d, a, GET(13), 0x4e0811a1, 21) 184 + STEP(I, a, b, c, d, GET(4), 0xf7537e82, 6) 185 + STEP(I, d, a, b, c, GET(11), 0xbd3af235, 10) 186 + STEP(I, c, d, a, b, GET(2), 0x2ad7d2bb, 15) 187 + STEP(I, b, c, d, a, GET(9), 0xeb86d391, 21) 188 188 189 - a += saved_a; 190 - b += saved_b; 191 - c += saved_c; 192 - d += saved_d; 189 + a += saved_a; 190 + b += saved_b; 191 + c += saved_c; 192 + d += saved_d; 193 193 194 - ptr += 64; 195 - } while (size -= 64); 194 + ptr += 64; 195 + } while (size -= 64); 196 196 197 - ctx->a = a; 198 - ctx->b = b; 199 - ctx->c = c; 200 - ctx->d = d; 197 + ctx->a = a; 198 + ctx->b = b; 199 + ctx->c = c; 200 + ctx->d = d; 201 201 202 - return ptr; 202 + return ptr; 203 203 } 204 204 205 205 void MD5_Init(MD5_CTX *ctx) 206 206 { 207 - ctx->a = 0x67452301; 208 - ctx->b = 0xefcdab89; 209 - ctx->c = 0x98badcfe; 210 - ctx->d = 0x10325476; 207 + ctx->a = 0x67452301; 208 + ctx->b = 0xefcdab89; 209 + ctx->c = 0x98badcfe; 210 + ctx->d = 0x10325476; 211 211 212 - ctx->lo = 0; 213 - ctx->hi = 0; 212 + ctx->lo = 0; 213 + ctx->hi = 0; 214 214 } 215 215 216 216 void MD5_Update(MD5_CTX *ctx, const void *data, unsigned long size) 217 217 { 218 - MD5_u32plus saved_lo; 219 - unsigned long used, available; 218 + MD5_u32plus saved_lo; 219 + unsigned long used, available; 220 220 221 - saved_lo = ctx->lo; 222 - if ((ctx->lo = (saved_lo + size) & 0x1fffffff) < saved_lo) 223 - ctx->hi++; 224 - ctx->hi += size >> 29; 221 + saved_lo = ctx->lo; 222 + if ((ctx->lo = (saved_lo + size) & 0x1fffffff) < saved_lo) 223 + ctx->hi++; 224 + ctx->hi += size >> 29; 225 225 226 - used = saved_lo & 0x3f; 226 + used = saved_lo & 0x3f; 227 227 228 - if (used) { 229 - available = 64 - used; 228 + if (used) { 229 + available = 64 - used; 230 230 231 - if (size < available) { 232 - memcpy(&ctx->buffer[used], data, size); 233 - return; 234 - } 231 + if (size < available) { 232 + memcpy(&ctx->buffer[used], data, size); 233 + return; 234 + } 235 235 236 - memcpy(&ctx->buffer[used], data, available); 237 - data = (const unsigned char *)data + available; 238 - size -= available; 239 - body(ctx, ctx->buffer, 64); 240 - } 236 + memcpy(&ctx->buffer[used], data, available); 237 + data = (const unsigned char *)data + available; 238 + size -= available; 239 + body(ctx, ctx->buffer, 64); 240 + } 241 241 242 - if (size >= 64) { 243 - data = body(ctx, data, size & ~(unsigned long)0x3f); 244 - size &= 0x3f; 245 - } 242 + if (size >= 64) { 243 + data = body(ctx, data, size & ~(unsigned long)0x3f); 244 + size &= 0x3f; 245 + } 246 246 247 - memcpy(ctx->buffer, data, size); 247 + memcpy(ctx->buffer, data, size); 248 248 } 249 249 250 250 #define OUT(dst, src) \ 251 - (dst)[0] = (unsigned char)(src); \ 252 - (dst)[1] = (unsigned char)((src) >> 8); \ 253 - (dst)[2] = (unsigned char)((src) >> 16); \ 254 - (dst)[3] = (unsigned char)((src) >> 24); 251 + (dst)[0] = (unsigned char)(src); \ 252 + (dst)[1] = (unsigned char)((src) >> 8); \ 253 + (dst)[2] = (unsigned char)((src) >> 16); \ 254 + (dst)[3] = (unsigned char)((src) >> 24); 255 255 256 256 void MD5_Final(unsigned char *result, MD5_CTX *ctx) 257 257 { 258 - unsigned long used, available; 258 + unsigned long used, available; 259 259 260 - used = ctx->lo & 0x3f; 260 + used = ctx->lo & 0x3f; 261 261 262 - ctx->buffer[used++] = 0x80; 262 + ctx->buffer[used++] = 0x80; 263 263 264 - available = 64 - used; 264 + available = 64 - used; 265 265 266 - if (available < 8) { 267 - memset(&ctx->buffer[used], 0, available); 268 - body(ctx, ctx->buffer, 64); 269 - used = 0; 270 - available = 64; 271 - } 266 + if (available < 8) { 267 + memset(&ctx->buffer[used], 0, available); 268 + body(ctx, ctx->buffer, 64); 269 + used = 0; 270 + available = 64; 271 + } 272 272 273 - memset(&ctx->buffer[used], 0, available - 8); 273 + memset(&ctx->buffer[used], 0, available - 8); 274 274 275 - ctx->lo <<= 3; 276 - OUT(&ctx->buffer[56], ctx->lo) 277 - OUT(&ctx->buffer[60], ctx->hi) 275 + ctx->lo <<= 3; 276 + OUT(&ctx->buffer[56], ctx->lo) 277 + OUT(&ctx->buffer[60], ctx->hi) 278 278 279 - body(ctx, ctx->buffer, 64); 279 + body(ctx, ctx->buffer, 64); 280 280 281 - OUT(&result[0], ctx->a) 282 - OUT(&result[4], ctx->b) 283 - OUT(&result[8], ctx->c) 284 - OUT(&result[12], ctx->d) 281 + OUT(&result[0], ctx->a) 282 + OUT(&result[4], ctx->b) 283 + OUT(&result[8], ctx->c) 284 + OUT(&result[12], ctx->d) 285 285 286 - memset(ctx, 0, sizeof(*ctx)); 286 + memset(ctx, 0, sizeof(*ctx)); 287 287 }
+4 -4
src/ext/md5.h
··· 30 30 typedef unsigned int MD5_u32plus; 31 31 32 32 typedef struct { 33 - MD5_u32plus lo, hi; 34 - MD5_u32plus a, b, c, d; 35 - unsigned char buffer[64]; 36 - MD5_u32plus block[16]; 33 + MD5_u32plus lo, hi; 34 + MD5_u32plus a, b, c, d; 35 + unsigned char buffer[64]; 36 + MD5_u32plus block[16]; 37 37 } MD5_CTX; 38 38 39 39 extern void MD5_Init(MD5_CTX *ctx);
+3 -3
src/ext/png.c
··· 177 177 static inline void bitcpy(u8* dst, u32 to, const u8* src, u32 from, u32 size) 178 178 { 179 179 for(s32 i = 0; i < size; i++, to++, from++) 180 - BIT_CHECK(src[from >> 3], from & 7) 181 - ? BIT_SET_LV(dst[to >> 3], to & 7) 182 - : BIT_CLEAR_LV(dst[to >> 3], to & 7); 180 + BITCHECK(src[from >> 3], from & 7) 181 + ? _BITSET(dst[to >> 3], to & 7) 182 + : _BITCLEAR(dst[to >> 3], to & 7); 183 183 } 184 184 185 185 static inline s32 ceildiv(s32 a, s32 b)
+12 -12
src/ext/png.h
··· 32 32 33 33 typedef union 34 34 { 35 - struct 36 - { 37 - u8 r; 38 - u8 g; 39 - u8 b; 40 - u8 a; 41 - }; 35 + struct 36 + { 37 + u8 r; 38 + u8 g; 39 + u8 b; 40 + u8 a; 41 + }; 42 42 43 - u8 data[4]; 43 + u8 data[4]; 44 44 45 - u32 value; 45 + u32 value; 46 46 } png_rgba; 47 47 48 48 typedef struct ··· 52 52 53 53 union 54 54 { 55 - png_rgba* pixels; 56 - u32* values; 57 - u8* data; 55 + png_rgba* pixels; 56 + u32* values; 57 + u8* data; 58 58 }; 59 59 } png_img; 60 60
+1 -1
src/studio/project.c
··· 147 147 148 148 s32 tic_project_save(const char* name, void* data, const tic_cartridge* cart) 149 149 { 150 - const char* comment = projectComment(name); 150 + const char* comment = projectComment(name); 151 151 char* stream = data; 152 152 char* ptr = saveTextSection(stream, cart->code.data); 153 153 char tag[16];
+165 -160
src/studio/screens/console.c
··· 691 691 s32 size = 0; 692 692 void* data = fs_read(path, &size); 693 693 694 - if(data) 694 + if(data) SCOPE(free(data)) 695 695 { 696 696 tic_cartridge* cart = newCart(); 697 697 698 - if(cart) 698 + SCOPE(free(cart)) 699 699 { 700 700 if(tic_project_load(console->rom.name, data, size, cart)) 701 701 { ··· 704 704 studioRomLoaded(); 705 705 } 706 706 else printError(console, "\nproject updating error :("); 707 - 708 - free(cart); 709 707 } 710 - free(data); 711 - 712 - } 708 + } 713 709 } 714 710 } 715 711 ··· 727 723 LoadByHashData* loadByHashData = data; 728 724 Console* console = loadByHashData->console; 729 725 726 + tic_cartridge* cart = newCart(); 727 + 728 + SCOPE(free(cart)) 730 729 { 731 - tic_cartridge* cart = newCart(); 732 730 tic_cart_load(cart, buffer, size); 733 731 loadCartSection(console, cart, loadByHashData->section); 734 732 onCartLoaded(console, loadByHashData->name); 735 - free(cart); 736 733 } 737 734 738 735 if (loadByHashData->callback) ··· 854 851 ? tic_fs_loadroot(console->fs, name, &size) 855 852 : tic_fs_load(console->fs, name, &size); 856 853 857 - if(data) 854 + if(data) SCOPE(free(data)) 858 855 { 859 856 tic_cartridge* cart = newCart(); 860 857 861 - tic_cart_load(cart, data, size); 862 - loadCartSection(console, cart, section); 863 - onCartLoaded(console, name); 864 - 865 - free(cart); 866 - free(data); 858 + SCOPE(free(cart)) 859 + { 860 + tic_cart_load(cart, data, size); 861 + loadCartSection(console, cart, section); 862 + onCartLoaded(console, name); 863 + } 867 864 } 868 865 else if(tic_tool_has_ext(param, PngExt) && tic_fs_exists(console->fs, param)) 869 866 { 870 867 png_buffer buffer; 871 868 buffer.data = tic_fs_load(console->fs, param, &buffer.size); 872 - tic_cartridge* cart = loadPngCart(buffer); 873 869 874 - if(cart) 870 + SCOPE(free(buffer.data)) 875 871 { 876 - loadCartSection(console, cart, section); 877 - onCartLoaded(console, param); 878 - free(cart); 872 + tic_cartridge* cart = loadPngCart(buffer); 873 + 874 + if(cart) SCOPE(free(cart)) 875 + { 876 + loadCartSection(console, cart, section); 877 + onCartLoaded(console, param); 878 + } 879 + else printError(console, "\npng cart loading error"); 879 880 } 880 - else printError(console, "\npng cart loading error"); 881 - 882 - free(buffer.data); 883 881 } 884 882 else 885 883 { ··· 889 887 { 890 888 void* data = tic_fs_load(console->fs, name, &size); 891 889 892 - if(data) 890 + if(data) SCOPE(free(data)) 893 891 { 894 892 tic_cartridge* cart = newCart(); 895 - tic_project_load(name, data, size, cart); 896 - loadCartSection(console, cart, section); 897 - onCartLoaded(console, name); 898 - free(cart); 893 + 894 + SCOPE(free(cart)) 895 + { 896 + tic_project_load(name, data, size, cart); 897 + loadCartSection(console, cart, section); 898 + onCartLoaded(console, name); 899 + } 899 900 } 900 901 else printError(console, "\nproject loading error"); 901 902 902 - free(data); 903 903 } 904 904 else printError(console, "\nfile not found"); 905 905 } ··· 1265 1265 tic_fs* fs = console->fs; 1266 1266 u8* data = (u8*)newCart(); 1267 1267 1268 - printBack(console, "\nadded carts:\n\n"); 1268 + SCOPE(free(data)) 1269 + { 1270 + printBack(console, "\nadded carts:\n\n"); 1269 1271 1270 1272 #if defined(TIC_BUILD_WITH_LUA) 1271 - static const u8 demofire[] = 1272 - { 1273 - #include "../build/assets/fire.tic.dat" 1274 - }; 1275 1273 1276 - static const u8 demop3d[] = 1277 - { 1278 - #include "../build/assets/p3d.tic.dat" 1279 - }; 1274 + static const u8 demofire[] = 1275 + { 1276 + #include "../build/assets/fire.tic.dat" 1277 + }; 1280 1278 1281 - static const u8 demosfx[] = 1282 - { 1283 - #include "../build/assets/sfx.tic.dat" 1284 - }; 1279 + static const u8 demop3d[] = 1280 + { 1281 + #include "../build/assets/p3d.tic.dat" 1282 + }; 1285 1283 1286 - static const u8 demopalette[] = 1287 - { 1288 - #include "../build/assets/palette.tic.dat" 1289 - }; 1284 + static const u8 demosfx[] = 1285 + { 1286 + #include "../build/assets/sfx.tic.dat" 1287 + }; 1290 1288 1291 - static const u8 demofont[] = 1292 - { 1293 - #include "../build/assets/font.tic.dat" 1294 - }; 1289 + static const u8 demopalette[] = 1290 + { 1291 + #include "../build/assets/palette.tic.dat" 1292 + }; 1295 1293 1296 - static const u8 demomusic[] = 1297 - { 1298 - #include "../build/assets/music.tic.dat" 1299 - }; 1294 + static const u8 demofont[] = 1295 + { 1296 + #include "../build/assets/font.tic.dat" 1297 + }; 1298 + 1299 + static const u8 demomusic[] = 1300 + { 1301 + #include "../build/assets/music.tic.dat" 1302 + }; 1300 1303 1301 - static const u8 demoquest[] = 1302 - { 1303 - #include "../build/assets/quest.tic.dat" 1304 - }; 1304 + static const u8 demoquest[] = 1305 + { 1306 + #include "../build/assets/quest.tic.dat" 1307 + }; 1305 1308 1306 - static const u8 demotetris[] = 1307 - { 1308 - #include "../build/assets/tetris.tic.dat" 1309 - }; 1309 + static const u8 demotetris[] = 1310 + { 1311 + #include "../build/assets/tetris.tic.dat" 1312 + }; 1310 1313 1311 - static const u8 demobenchmark[] = 1312 - { 1313 - #include "../build/assets/benchmark.tic.dat" 1314 - }; 1314 + static const u8 demobenchmark[] = 1315 + { 1316 + #include "../build/assets/benchmark.tic.dat" 1317 + }; 1315 1318 1316 - static const u8 demobpp[] = 1317 - { 1318 - #include "../build/assets/bpp.tic.dat" 1319 - }; 1319 + static const u8 demobpp[] = 1320 + { 1321 + #include "../build/assets/bpp.tic.dat" 1322 + }; 1320 1323 1321 - #define DEMOS_LIST(macro) \ 1322 - macro(fire) \ 1323 - macro(font) \ 1324 - macro(music) \ 1325 - macro(p3d) \ 1326 - macro(palette) \ 1327 - macro(quest) \ 1328 - macro(sfx) \ 1329 - macro(tetris) \ 1330 - macro(benchmark) \ 1331 - macro(bpp) 1324 + #define DEMOS_LIST(macro) \ 1325 + macro(fire) \ 1326 + macro(font) \ 1327 + macro(music) \ 1328 + macro(p3d) \ 1329 + macro(palette) \ 1330 + macro(quest) \ 1331 + macro(sfx) \ 1332 + macro(tetris) \ 1333 + macro(benchmark) \ 1334 + macro(bpp) 1332 1335 1333 - static const struct Demo {const char* name; const u8* data; s32 size;} Demos[] = 1334 - { 1335 - #define DEMOS_DEF(name) {#name ".tic", demo ## name, sizeof demo ## name}, 1336 - DEMOS_LIST(DEMOS_DEF) 1337 - #undef DEMOS_DEF 1338 - }; 1336 + static const struct Demo {const char* name; const u8* data; s32 size;} Demos[] = 1337 + { 1338 + #define DEMOS_DEF(name) {#name ".tic", demo ## name, sizeof demo ## name}, 1339 + DEMOS_LIST(DEMOS_DEF) 1340 + #undef DEMOS_DEF 1341 + }; 1339 1342 1340 - #undef DEMOS_LIST 1343 + #undef DEMOS_LIST 1341 1344 1342 - FOR(const struct Demo*, demo, Demos) 1343 - { 1344 - tic_fs_save(fs, demo->name, data, tic_tool_unzip(data, sizeof(tic_cartridge), demo->data, demo->size), true); 1345 - printFront(console, demo->name); 1346 - printLine(console); 1347 - } 1345 + FOR(const struct Demo*, demo, Demos) 1346 + { 1347 + tic_fs_save(fs, demo->name, data, tic_tool_unzip(data, sizeof(tic_cartridge), demo->data, demo->size), true); 1348 + printFront(console, demo->name); 1349 + printLine(console); 1350 + } 1348 1351 #endif 1349 1352 1350 1353 #if defined(TIC_BUILD_WITH_LUA) 1351 - static const u8 luamark[] = 1352 - { 1353 - #include "../build/assets/luamark.tic.dat" 1354 - }; 1354 + static const u8 luamark[] = 1355 + { 1356 + #include "../build/assets/luamark.tic.dat" 1357 + }; 1355 1358 #endif 1356 1359 1357 1360 #if defined(TIC_BUILD_WITH_MOON) 1358 - static const u8 moonmark[] = 1359 - { 1360 - #include "../build/assets/moonmark.tic.dat" 1361 - }; 1361 + static const u8 moonmark[] = 1362 + { 1363 + #include "../build/assets/moonmark.tic.dat" 1364 + }; 1362 1365 #endif 1363 1366 1364 1367 #if defined(TIC_BUILD_WITH_FENNEL) 1365 - static const u8 fennelmark[] = 1366 - { 1367 - #include "../build/assets/luamark.tic.dat" 1368 - }; 1368 + static const u8 fennelmark[] = 1369 + { 1370 + #include "../build/assets/luamark.tic.dat" 1371 + }; 1369 1372 #endif 1370 1373 1371 1374 #if defined(TIC_BUILD_WITH_JS) 1372 - static const u8 jsmark[] = 1373 - { 1374 - #include "../build/assets/jsmark.tic.dat" 1375 - }; 1375 + static const u8 jsmark[] = 1376 + { 1377 + #include "../build/assets/jsmark.tic.dat" 1378 + }; 1376 1379 #endif 1377 1380 1378 1381 #if defined(TIC_BUILD_WITH_SQUIRREL) 1379 - static const u8 squirrelmark[] = 1380 - { 1381 - #include "../build/assets/squirrelmark.tic.dat" 1382 - }; 1382 + static const u8 squirrelmark[] = 1383 + { 1384 + #include "../build/assets/squirrelmark.tic.dat" 1385 + }; 1383 1386 #endif 1384 1387 1385 1388 #if defined(TIC_BUILD_WITH_WREN) 1386 - static const u8 wrenmark[] = 1387 - { 1388 - #include "../build/assets/wrenmark.tic.dat" 1389 - }; 1389 + static const u8 wrenmark[] = 1390 + { 1391 + #include "../build/assets/wrenmark.tic.dat" 1392 + }; 1390 1393 #endif 1391 1394 1392 - static const struct Mark {const char* name; const u8* data; s32 size;} Marks[] = 1393 - { 1394 - #define SCRIPT_DEF(name, ...) {#name "mark.tic", name ## mark, sizeof name ## mark}, 1395 - SCRIPT_LIST(SCRIPT_DEF) 1396 - #undef SCRIPT_DEF 1397 - }; 1395 + static const struct Mark {const char* name; const u8* data; s32 size;} Marks[] = 1396 + { 1397 + #define SCRIPT_DEF(name, ...) {#name "mark.tic", name ## mark, sizeof name ## mark}, 1398 + SCRIPT_LIST(SCRIPT_DEF) 1399 + #undef SCRIPT_DEF 1400 + }; 1398 1401 1399 - static const char* Bunny = "bunny"; 1402 + static const char* Bunny = "bunny"; 1403 + 1404 + tic_fs_makedir(fs, Bunny); 1405 + tic_fs_changedir(fs, Bunny); 1400 1406 1401 - tic_fs_makedir(fs, Bunny); 1402 - tic_fs_changedir(fs, Bunny); 1407 + FOR(const struct Mark*, mark, Marks) 1408 + { 1409 + tic_fs_save(fs, mark->name, data, tic_tool_unzip(data, sizeof(tic_cartridge), mark->data, mark->size), true); 1410 + printFront(console, Bunny); 1411 + printFront(console, "/"); 1412 + printFront(console, mark->name); 1413 + printLine(console); 1414 + } 1403 1415 1404 - FOR(const struct Mark*, mark, Marks) 1405 - { 1406 - tic_fs_save(fs, mark->name, data, tic_tool_unzip(data, sizeof(tic_cartridge), mark->data, mark->size), true); 1407 - printFront(console, Bunny); 1408 - printFront(console, "/"); 1409 - printFront(console, mark->name); 1410 - printLine(console); 1416 + tic_fs_dirback(fs); 1411 1417 } 1412 1418 1413 - tic_fs_dirback(fs); 1414 - 1415 - free(data); 1416 1419 commandDone(console); 1417 1420 } 1418 1421 ··· 1665 1668 const tic_cartridge* cart = &tic->cart; 1666 1669 1667 1670 png_img img = {TIC_SPRITESHEET_SIZE, TIC_SPRITESHEET_SIZE, malloc(TIC_SPRITESHEET_SIZE * TIC_SPRITESHEET_SIZE * sizeof(png_rgba))}; 1668 - 1669 - const tic_palette* pal = getBankPalette(false); 1670 - for(s32 i = 0; i < TIC_SPRITESHEET_SIZE * TIC_SPRITESHEET_SIZE; i++) 1671 - img.values[i] = tic_rgba(&pal->colors[getSpritePixel(base, i % TIC_SPRITESHEET_SIZE, i / TIC_SPRITESHEET_SIZE)]); 1672 1671 1673 - png_buffer png = png_write(img); 1672 + SCOPE(free(img.data)) 1673 + { 1674 + const tic_palette* pal = getBankPalette(false); 1675 + for(s32 i = 0; i < TIC_SPRITESHEET_SIZE * TIC_SPRITESHEET_SIZE; i++) 1676 + img.values[i] = tic_rgba(&pal->colors[getSpritePixel(base, i % TIC_SPRITESHEET_SIZE, i / TIC_SPRITESHEET_SIZE)]); 1674 1677 1675 - onFileExported(console, filename, tic_fs_save(console->fs, filename, png.data, png.size, true)); 1678 + png_buffer png = png_write(img); 1676 1679 1677 - free(png.data); 1678 - free(img.data); 1680 + SCOPE(free(png.data)) 1681 + { 1682 + onFileExported(console, filename, tic_fs_save(console->fs, filename, png.data, png.size, true)); 1683 + } 1684 + } 1679 1685 } 1680 1686 1681 1687 static void *ticMemmem(const void* haystack, size_t hlen, const void* needle, size_t nlen) ··· 1715 1721 u8* data = NULL; 1716 1722 void* cart = newCart(); 1717 1723 1718 - if(cart) 1724 + SCOPE(free(cart)) 1719 1725 { 1720 1726 s32 cartSize = tic_cart_save(&tic->cart, cart); 1721 1727 1722 1728 s32 zipSize = sizeof(tic_cartridge); 1723 1729 u8* zipData = (u8*)malloc(zipSize); 1724 1730 1725 - if(zipData) 1731 + SCOPE(free(zipData)) 1726 1732 { 1727 1733 if((zipSize = tic_tool_zip(zipData, zipSize, cart, cartSize))) 1728 1734 { ··· 1748 1754 *size = finalSize; 1749 1755 } 1750 1756 } 1751 - 1752 - free(zipData); 1753 1757 } 1754 - 1755 - free(cart); 1756 1758 } 1757 1759 1758 1760 return data; ··· 1865 1867 { 1866 1868 struct zip_t *zip = zip_open(zipPath, ZIP_DEFAULT_COMPRESSION_LEVEL, 'a'); 1867 1869 1868 - if(zip) 1870 + if(zip) SCOPE(zip_close(zip)) 1869 1871 { 1870 1872 void* cart = newCart(); 1871 1873 1872 - if(cart) 1874 + SCOPE(free(cart)) 1873 1875 { 1874 1876 s32 cartSize = tic_cart_save(&tic->cart, cart); 1875 1877 ··· 1880 1882 zip_entry_close(zip); 1881 1883 } 1882 1884 else errorOccured = true; 1883 - 1884 - free(cart); 1885 1885 } 1886 - else errorOccured = true; 1887 - 1888 - zip_close(zip); 1889 1886 } 1890 1887 else errorOccured = true; 1891 1888 } ··· 2441 2438 "new", 2442 2439 NULL, 2443 2440 "creates a new `Hello World` cartridge.", 2444 - "new [lua|moon|js|wren|fennel|squirrel]", 2441 + "new [" 2442 + #define SCRIPT_DEF(name, ...) #name "|" 2443 + SCRIPT_LIST(SCRIPT_DEF) 2444 + #undef SCRIPT_DEF 2445 + "...]", 2445 2446 onNewCommand 2446 2447 }, 2447 2448 { ··· 3105 3106 3106 3107 static void appendHistory(Console* console, const char* value) 3107 3108 { 3109 + if(console->history.size) 3110 + if(strcmp(console->history.items[console->history.index = console->history.size - 1], value) == 0) 3111 + return; 3112 + 3108 3113 console->history.index = console->history.size++; 3109 3114 console->history.items = realloc(console->history.items, sizeof(char*) * console->history.size); 3110 3115 console->history.items[console->history.index] = strdup(value);
+4 -1
src/studio/studio.c
··· 1173 1173 break; 1174 1174 case TIC_RUN_MODE: 1175 1175 case TIC_SURF_MODE: 1176 - impl.console->done(impl.console); 1177 1176 impl.prevMode = TIC_CODE_MODE; 1178 1177 break; 1179 1178 default: impl.prevMode = prev; break; ··· 1181 1180 1182 1181 switch(mode) 1183 1182 { 1183 + case TIC_CONSOLE_MODE: 1184 + if (prev == TIC_SURF_MODE) 1185 + impl.console->done(impl.console); 1186 + break; 1184 1187 case TIC_WORLD_MODE: initWorldMap(); break; 1185 1188 case TIC_RUN_MODE: initRunMode(); break; 1186 1189 case TIC_SURF_MODE: impl.surf->resume(impl.surf); break;