this repo has no description
0
fork

Configure Feed

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

added some UI animations to the code/sprite/map editors and surf

nesbox d790b953 f24c4b2f

+836 -367
+1 -1
src/core/core.h
··· 158 158 159 159 struct ClipRect 160 160 { 161 - u8 l, t, r, b; 161 + s32 l, t, r, b; 162 162 } clip; 163 163 164 164 bool initialized;
+1 -1
src/defines.h
··· 37 37 #define CONCAT2(a, b) a ## b 38 38 #define CONCAT(a, b) CONCAT2(a, b) 39 39 #define MACROVAR(name) CONCAT(name, __LINE__) 40 - #define SCOPE(exp) for(int MACROVAR(_i_) = 0; !MACROVAR(_i_); ++MACROVAR(_i_), exp) 40 + #define SCOPE(...) for(int MACROVAR(_i_) = 0; !MACROVAR(_i_); ++MACROVAR(_i_), __VA_ARGS__) 41 41 #define FOR(type,it,list) for(type it = list, *MACROVAR(_end_) = it + COUNT_OF(list); it != MACROVAR(_end_); ++it) 42 42 #define RFOR(type,it,list) for(type it = list + (COUNT_OF(list) - 1), *MACROVAR(_end_) = list; it >= MACROVAR(_end_); --it) 43 43 #define FREE(ptr) do { if(ptr) free(ptr); } while (0)
+99 -32
src/studio/editors/code.c
··· 32 32 #define CODE_EDITOR_WIDTH (TIC80_WIDTH - BOOKMARK_WIDTH) 33 33 #define CODE_EDITOR_HEIGHT (TIC80_HEIGHT - TOOLBAR_SIZE - STUDIO_TEXT_HEIGHT) 34 34 #define TEXT_BUFFER_HEIGHT (CODE_EDITOR_HEIGHT / STUDIO_TEXT_HEIGHT) 35 + #define OUTLINE_WIDTH (13 * TIC_FONT_WIDTH) 35 36 36 37 #if defined(TIC80_PRO) 37 38 # define MAX_CODE sizeof(tic_code) ··· 1331 1332 updateOutlineCode(code); 1332 1333 } 1333 1334 1335 + static bool isIdle(Code* code) 1336 + { 1337 + return code->anim.movie == &code->anim.idle; 1338 + } 1339 + 1334 1340 static void setCodeMode(Code* code, s32 mode) 1335 1341 { 1336 - if(code->mode != mode) 1342 + if(isIdle(code) && code->mode != mode) 1337 1343 { 1344 + code->anim.movie = resetMovie(&code->anim.show); 1345 + 1338 1346 strcpy(code->popup.text, ""); 1339 1347 1340 1348 code->popup.prevPos = code->cursor.position; ··· 1749 1757 1750 1758 static void drawPopupBar(Code* code, const char* title) 1751 1759 { 1752 - enum {TextX = BOOKMARK_WIDTH, TextY = TOOLBAR_SIZE + 1}; 1760 + s32 pos = code->anim.pos; 1761 + 1762 + enum {TextX = BOOKMARK_WIDTH}; 1753 1763 1754 - tic_api_rect(code->tic, 0, TOOLBAR_SIZE, TIC80_WIDTH, TIC_FONT_HEIGHT + 1, tic_color_grey); 1764 + 1765 + tic_api_rect(code->tic, 0, TOOLBAR_SIZE + pos, TIC80_WIDTH, TIC_FONT_HEIGHT + 1, tic_color_grey); 1766 + 1767 + s32 textY = (TOOLBAR_SIZE + 1) + pos; 1755 1768 1756 1769 if(code->shadowText) 1757 - tic_api_print(code->tic, title, TextX+1, TextY+1, tic_color_black, true, 1, code->altFont); 1770 + tic_api_print(code->tic, title, TextX+1, textY+1, tic_color_black, true, 1, code->altFont); 1758 1771 1759 - tic_api_print(code->tic, title, TextX, TextY, tic_color_white, true, 1, code->altFont); 1772 + tic_api_print(code->tic, title, TextX, textY, tic_color_white, true, 1, code->altFont); 1760 1773 1761 1774 if(code->shadowText) 1762 - tic_api_print(code->tic, code->popup.text, TextX + (s32)strlen(title) * getFontWidth(code) + 1, TextY+1, tic_color_black, true, 1, code->altFont); 1775 + tic_api_print(code->tic, code->popup.text, TextX + (s32)strlen(title) * getFontWidth(code) + 1, textY+1, tic_color_black, true, 1, code->altFont); 1763 1776 1764 - tic_api_print(code->tic, code->popup.text, TextX + (s32)strlen(title) * getFontWidth(code), TextY, tic_color_white, true, 1, code->altFont); 1777 + tic_api_print(code->tic, code->popup.text, TextX + (s32)strlen(title) * getFontWidth(code), textY, tic_color_white, true, 1, code->altFont); 1765 1778 1766 - drawCursor(code, TextX+(s32)(strlen(title) + strlen(code->popup.text)) * getFontWidth(code), TextY, ' '); 1779 + drawCursor(code, TextX+(s32)(strlen(title) + strlen(code->popup.text)) * getFontWidth(code), textY, ' '); 1767 1780 } 1768 1781 1769 1782 static void updateFindCode(Code* code, char* pos) ··· 2049 2062 2050 2063 drawCode(code, false); 2051 2064 drawStatus(code); 2052 - drawOutlineBar(code, TIC80_WIDTH - 13 * TIC_FONT_WIDTH, 2*(TIC_FONT_HEIGHT+1)); 2065 + drawOutlineBar(code, (TIC80_WIDTH - OUTLINE_WIDTH) + code->anim.outline, 2*(TIC_FONT_HEIGHT+1)); 2053 2066 drawPopupBar(code, "FUNC:"); 2054 2067 } 2055 2068 ··· 2106 2119 drawBitIcon(tic_icon_shadow2, x, y, tic_color_black); 2107 2120 } 2108 2121 2122 + static void drawRunButton(Code* code, s32 x, s32 y) 2123 + { 2124 + tic_mem* tic = code->tic; 2125 + 2126 + enum {Size = TIC_FONT_WIDTH}; 2127 + tic_rect rect = {x, y, Size, Size}; 2128 + 2129 + bool over = false; 2130 + if(checkMousePos(&rect)) 2131 + { 2132 + setCursor(tic_cursor_hand); 2133 + showTooltip("RUN [ctrl+r]"); 2134 + over = true; 2135 + 2136 + if(checkMouseClick(&rect, tic_mouse_left)) 2137 + runGame(); 2138 + } 2139 + 2140 + drawBitIcon(tic_icon_run, x, y, over ? tic_color_grey : tic_color_light_grey); 2141 + } 2142 + 2109 2143 static void drawCodeToolbar(Code* code) 2110 2144 { 2111 2145 tic_api_rect(code->tic, 0, 0, TIC80_WIDTH, TOOLBAR_SIZE, tic_color_white); 2112 2146 2113 - static u8 Icons[] = {tic_icon_run, tic_icon_hand, tic_icon_find, tic_icon_goto, tic_icon_outline}; 2114 - static const char* Tips[] = {"RUN [ctrl+r]", "DRAG [right mouse]", "FIND [ctrl+f]", "GOTO [ctrl+g]", "OUTLINE [ctrl+o]"}; 2147 + static u8 Icons[] = {tic_icon_hand, tic_icon_find, tic_icon_goto, tic_icon_outline}; 2148 + static const char* Tips[] = {"DRAG [right mouse]", "FIND [ctrl+f]", "GOTO [ctrl+g]", "OUTLINE [ctrl+o]"}; 2115 2149 2116 2150 enum {Count = COUNT_OF(Icons)}; 2117 2151 enum {Size = 7}; ··· 2131 2165 2132 2166 if(checkMouseClick(&rect, tic_mouse_left)) 2133 2167 { 2134 - switch(i) 2135 - { 2136 - case TEXT_RUN_CODE: 2137 - runGame(); 2138 - break; 2139 - default: 2140 - { 2141 - s32 mode = TEXT_EDIT_MODE + i; 2142 - 2143 - if(code->mode == mode) code->escape(code); 2144 - else setCodeMode(code, mode); 2145 - } 2146 - } 2168 + if(code->mode == i) code->escape(code); 2169 + else setCodeMode(code, i); 2147 2170 } 2148 2171 } 2149 2172 2150 - bool active = i == code->mode - TEXT_EDIT_MODE && i != 0; 2173 + bool active = i == code->mode && isIdle(code); 2151 2174 if (active) 2152 2175 { 2153 2176 tic_api_rect(code->tic, rect.x, rect.y, Size, Size, tic_color_grey); 2154 2177 drawBitIcon(Icons[i], rect.x, rect.y + 1, tic_color_black); 2155 - } 2178 + } 2179 + 2156 2180 drawBitIcon(Icons[i], rect.x, rect.y, active ? tic_color_white : (over ? tic_color_grey : tic_color_light_grey)); 2157 2181 } 2158 2182 2159 2183 drawFontButton(code, TIC80_WIDTH - (Count+3) * Size, 1); 2160 2184 drawShadowButton(code, TIC80_WIDTH - (Count+2) * Size, 0); 2185 + drawRunButton(code, TIC80_WIDTH - (Count+1) * Size, 0); 2161 2186 2162 2187 drawToolbar(code->tic, false); 2163 2188 } 2164 2189 2165 2190 static void tick(Code* code) 2166 2191 { 2192 + processAnim(code->anim.movie, code); 2193 + 2167 2194 if(code->cursor.delay) 2168 2195 code->cursor.delay--; 2169 2196 2170 2197 switch(code->mode) 2171 2198 { 2172 - case TEXT_RUN_CODE: runGame(); break; 2173 2199 case TEXT_DRAG_CODE: textDragTick(code); break; 2174 2200 case TEXT_EDIT_MODE: textEditTick(code); break; 2175 2201 case TEXT_FIND_MODE: textFindTick(code); break; ··· 2189 2215 case TEXT_EDIT_MODE: 2190 2216 break; 2191 2217 case TEXT_DRAG_CODE: 2192 - code->mode = TEXT_EDIT_MODE; 2218 + setCodeMode(code, TEXT_EDIT_MODE); 2193 2219 break; 2194 2220 default: 2221 + code->anim.movie = resetMovie(&code->anim.hide); 2222 + 2195 2223 code->cursor.position = code->popup.prevPos; 2196 2224 code->cursor.selection = code->popup.prevSel; 2197 2225 code->popup.prevSel = code->popup.prevPos = NULL; 2198 - 2199 - code->mode = TEXT_EDIT_MODE; 2200 2226 2201 2227 updateEditor(code); 2202 2228 } ··· 2214 2240 } 2215 2241 } 2216 2242 2243 + static void emptyDone() {} 2244 + 2245 + static void setIdle(void* data) 2246 + { 2247 + Code* code = data; 2248 + code->anim.movie = resetMovie(&code->anim.idle); 2249 + } 2250 + 2251 + static void setEditMode(void* data) 2252 + { 2253 + Code* code = data; 2254 + code->anim.movie = resetMovie(&code->anim.idle); 2255 + setCodeMode(code, TEXT_EDIT_MODE); 2256 + } 2257 + 2258 + static void freeAnim(Code* code) 2259 + { 2260 + FREE(code->anim.show.items); 2261 + FREE(code->anim.hide.items); 2262 + } 2263 + 2217 2264 void initCode(Code* code, tic_mem* tic, tic_code* src) 2218 2265 { 2219 2266 bool firstLoad = code->state == NULL; 2220 - if(code->state != NULL) 2221 - free(code->state); 2267 + FREE(code->state); 2268 + freeAnim(code); 2222 2269 2223 2270 if(code->history) history_delete(code->history); 2224 2271 ··· 2250 2297 .matchedDelim = NULL, 2251 2298 .altFont = firstLoad ? getConfig()->theme.code.altFont : code->altFont, 2252 2299 .shadowText = getConfig()->theme.code.shadow, 2300 + .anim = 2301 + { 2302 + .idle = {.done = emptyDone,}, 2303 + 2304 + .show = MOVIE_DEF(STUDIO_ANIM_TIME, setIdle, 2305 + { 2306 + {-TOOLBAR_SIZE, 0, STUDIO_ANIM_TIME, &code->anim.pos, AnimEaseIn}, 2307 + {OUTLINE_WIDTH, 0, STUDIO_ANIM_TIME, &code->anim.outline, AnimEaseIn}, 2308 + }), 2309 + 2310 + .hide = MOVIE_DEF(STUDIO_ANIM_TIME, setEditMode, 2311 + { 2312 + {0, -TOOLBAR_SIZE, STUDIO_ANIM_TIME, &code->anim.pos, AnimEaseIn}, 2313 + {0, OUTLINE_WIDTH, STUDIO_ANIM_TIME, &code->anim.outline, AnimEaseIn}, 2314 + }), 2315 + }, 2253 2316 .event = onStudioEvent, 2254 2317 .update = update, 2255 2318 }; 2256 2319 2320 + code->anim.movie = resetMovie(&code->anim.idle); 2321 + 2257 2322 packState(code); 2258 2323 code->history = history_create(code->state, sizeof(CodeState) * TIC_CODE_SIZE); 2259 2324 ··· 2262 2327 2263 2328 void freeCode(Code* code) 2264 2329 { 2330 + freeAnim(code); 2331 + 2265 2332 history_delete(code->history); 2266 2333 free(code->state); 2267 2334 free(code);
+14 -2
src/studio/editors/code.h
··· 82 82 83 83 enum 84 84 { 85 - TEXT_RUN_CODE, 86 - TEXT_EDIT_MODE, 87 85 TEXT_DRAG_CODE, 88 86 TEXT_FIND_MODE, 89 87 TEXT_GOTO_MODE, 90 88 TEXT_OUTLINE_MODE, 89 + TEXT_EDIT_MODE, 91 90 } mode; 92 91 93 92 struct ··· 115 114 const char* matchedDelim; 116 115 bool altFont; 117 116 bool shadowText; 117 + 118 + struct 119 + { 120 + s32 pos; 121 + s32 outline; 122 + 123 + Movie* movie; 124 + 125 + Movie idle; 126 + Movie show; 127 + Movie hide; 128 + 129 + } anim; 118 130 119 131 void(*tick)(Code*); 120 132 void(*escape)(Code*);
+124 -22
src/studio/editors/map.c
··· 117 117 return x; 118 118 } 119 119 120 - static bool sheetVisible(Map* map) 120 + static inline bool isIdle(Map* map) 121 121 { 122 - tic_mem* tic = map->tic; 123 - return tic_api_key(tic, tic_key_shift) || map->sheet.show; 122 + return map->anim.movie == &map->anim.idle; 123 + } 124 + 125 + static inline bool sheetVisible(Map* map) 126 + { 127 + return map->anim.pos.sheet >= 0; 124 128 } 125 129 126 130 static s32 drawSheetButton(Map* map, s32 x, s32 y) ··· 137 141 over = true; 138 142 showTooltip("SHOW TILES [shift]"); 139 143 140 - if(checkMouseClick(&rect, tic_mouse_left)) 144 + if(isIdle(map) && checkMouseClick(&rect, tic_mouse_left)) 141 145 { 142 - map->sheet.show = !map->sheet.show; 146 + map->anim.movie = resetMovie(sheetVisible(map) ? &map->anim.hide : &map->anim.show); 147 + map->sheet.keep = true; 143 148 } 144 149 } 145 150 146 - drawBitIcon(sheetVisible(map) ? tic_icon_up : tic_icon_down, rect.x, rect.y, over ? tic_color_grey : tic_color_light_grey); 151 + drawBitIcon(sheetVisible(map) ? tic_icon_up : tic_icon_down, rect.x, rect.y, 152 + over ? tic_color_grey : tic_color_light_grey); 147 153 148 154 return x; 149 155 } ··· 296 302 297 303 showTooltip(i ? "SPRITES" : "TILES"); 298 304 299 - if(checkMouseClick(&rect, tic_mouse_left)) 305 + if(isIdle(map) && checkMouseClick(&rect, tic_mouse_left)) 300 306 { 307 + Anim* anim = map->anim.bank.items; 308 + anim->start = (i - map->sheet.blit.bank) * TIC_SPRITESHEET_SIZE; 309 + map->anim.movie = resetMovie(&map->anim.bank); 310 + 301 311 map->sheet.blit.bank = i; 302 312 } 303 313 } ··· 329 339 330 340 SHOW_TOOLTIP("PAGE %i", i); 331 341 332 - if(checkMouseClick(&rect, tic_mouse_left)) 342 + if(isIdle(map) && checkMouseClick(&rect, tic_mouse_left)) 333 343 { 344 + Anim* anim = map->anim.page.items; 345 + anim->start = (i - map->sheet.blit.page) * TIC_SPRITESHEET_SIZE; 346 + map->anim.movie = resetMovie(&map->anim.page); 347 + 334 348 map->sheet.blit.page = i; 335 349 } 336 350 } ··· 382 396 383 397 static void drawSheetVBank1(Map* map, s32 x, s32 y) 384 398 { 385 - if(!sheetVisible(map))return; 386 - 387 399 tic_mem* tic = map->tic; 388 400 const tic_blit* blit = &map->sheet.blit; 389 401 390 402 tic_rect rect = {x, y, TIC_SPRITESHEET_SIZE, TIC_SPRITESHEET_SIZE}; 391 403 392 - tic_api_rectb(map->tic, rect.x - 1, rect.y - 1, rect.w + 2, rect.h + 2, tic_color_white); 404 + tic_api_rectb(map->tic, rect.x - 1, rect.y - 1 + map->anim.pos.sheet, rect.w + 2, rect.h + 2, tic_color_white); 393 405 394 406 for(s32 i = 1; i < rect.h; i += 4) 395 407 { ··· 412 424 s32 bw = map->sheet.rect.w * TIC_SPRITESIZE + 2; 413 425 s32 bh = map->sheet.rect.h * TIC_SPRITESIZE + 2; 414 426 415 - tic_api_rectb(map->tic, bx, by, bw, bh, tic_color_white); 427 + tic_api_rectb(map->tic, bx, by + map->anim.pos.sheet, bw, bh, tic_color_white); 416 428 } 417 429 } 418 430 ··· 432 444 { 433 445 tic_mem* tic = map->tic; 434 446 435 - if(!sheetVisible(map))return; 436 - 437 447 tic_rect rect = {x, y, TIC_SPRITESHEET_SIZE, TIC_SPRITESHEET_SIZE}; 438 448 439 - if(checkMousePos(&rect)) 449 + if(isIdle(map) && sheetVisible(map) && checkMousePos(&rect)) 440 450 { 441 451 setCursor(tic_cursor_hand); 442 452 ··· 467 477 } 468 478 else 469 479 { 470 - if(map->sheet.drag) 471 - map->sheet.show = false; 480 + if(map->sheet.keep && map->sheet.drag) 481 + map->anim.movie = resetMovie(&map->anim.hide); 472 482 473 483 map->sheet.drag = false; 474 484 } 475 485 } 476 486 477 - initBlitMode(map); 478 - tic_api_spr(tic, 0, x, y, TIC_SPRITESHEET_COLS, TIC_SPRITESHEET_COLS, NULL, 0, 1, tic_no_flip, tic_no_rotate); 479 - resetBlitMode(map->tic); 487 + tic_api_clip(tic, x, y + map->anim.pos.sheet, TIC_SPRITESHEET_SIZE, TIC_SPRITESHEET_SIZE); 488 + 489 + tiles2ram(&tic->ram, getBankTiles()); 490 + 491 + tic_blit blit = map->sheet.blit; 492 + SCOPE(resetBlitMode(map->tic), tic_api_clip(tic, 0, 0, TIC80_WIDTH, TIC80_HEIGHT)) 493 + { 494 + tic_point start = 495 + { 496 + x - blit.page * TIC_SPRITESHEET_SIZE + map->anim.pos.page, 497 + y - blit.bank * TIC_SPRITESHEET_SIZE + map->anim.pos.bank 498 + }, pos = start; 499 + 500 + for(blit.bank = 0; blit.bank < TIC_SPRITE_BANKS; ++blit.bank, pos.y += TIC_SPRITESHEET_SIZE, pos.x = start.x) 501 + { 502 + for(blit.page = 0; blit.page < blit.pages; ++blit.page, pos.x += TIC_SPRITESHEET_SIZE) 503 + { 504 + tic->ram.vram.blit.segment = tic_blit_calc_segment(&blit); 505 + tic_api_spr(tic, 0, pos.x, pos.y + map->anim.pos.sheet, TIC_SPRITESHEET_COLS, TIC_SPRITESHEET_COLS, NULL, 0, 1, tic_no_flip, tic_no_rotate); 506 + } 507 + } 508 + } 480 509 } 481 510 482 511 static void drawCursorPos(Map* map, s32 x, s32 y) ··· 1189 1218 { 1190 1219 tic_mem* tic = map->tic; 1191 1220 1221 + if(isIdle(map)) 1222 + { 1223 + if(tic_api_key(tic, tic_key_shift)) 1224 + { 1225 + if(!sheetVisible(map)) 1226 + { 1227 + map->anim.movie = resetMovie(&map->anim.show); 1228 + map->sheet.keep = false; 1229 + } 1230 + } 1231 + else 1232 + { 1233 + if(!map->sheet.keep && sheetVisible(map)) 1234 + map->anim.movie = resetMovie(&map->anim.hide); 1235 + } 1236 + } 1237 + 1192 1238 if(tic->ram.input.keyboard.data == 0) return; 1193 1239 1194 1240 bool ctrl = tic_api_key(tic, tic_key_ctrl); ··· 1242 1288 tic_mem* tic = map->tic; 1243 1289 map->tickCounter++; 1244 1290 1291 + processAnim(map->anim.movie, map); 1292 + 1293 + // process scroll 1294 + if(tic->ram.input.mouse.scrolly > 0) 1295 + { 1296 + setStudioMode(TIC_WORLD_MODE); 1297 + return; 1298 + } 1299 + 1245 1300 processKeyboard(map); 1246 1301 1247 1302 drawMapReg(map); ··· 1312 1367 memcpy(&tic->ram.vram.palette, getBankPalette(false), sizeof(tic_palette)); 1313 1368 } 1314 1369 1370 + static void emptyDone() {} 1371 + 1372 + static void setIdle(void* data) 1373 + { 1374 + Map* map = data; 1375 + map->anim.movie = resetMovie(&map->anim.idle); 1376 + } 1377 + 1378 + static void freeAnim(Map* map) 1379 + { 1380 + FREE(map->anim.show.items); 1381 + FREE(map->anim.hide.items); 1382 + FREE(map->anim.bank.items); 1383 + FREE(map->anim.page.items); 1384 + } 1385 + 1315 1386 void initMap(Map* map, tic_mem* tic, tic_map* src) 1316 1387 { 1388 + enum {SheetStart = -(TIC_SPRITESHEET_SIZE + TOOLBAR_SIZE)}; 1389 + 1317 1390 if(map->history) history_delete(map->history); 1318 - 1391 + freeAnim(map); 1392 + 1319 1393 *map = (Map) 1320 1394 { 1321 1395 .tic = tic, ··· 1330 1404 }, 1331 1405 .sheet = 1332 1406 { 1333 - .show = false, 1334 1407 .rect = {0, 0, 1, 1}, 1335 1408 .start = {0, 0}, 1336 1409 .drag = false, ··· 1353 1426 .start = {0, 0}, 1354 1427 }, 1355 1428 .history = history_create(src, sizeof(tic_map)), 1429 + .anim = 1430 + { 1431 + .pos.sheet = SheetStart, 1432 + 1433 + .idle = {.done = emptyDone,}, 1434 + 1435 + .show = MOVIE_DEF(STUDIO_ANIM_TIME, setIdle, 1436 + { 1437 + {SheetStart, 0, STUDIO_ANIM_TIME, &map->anim.pos.sheet, AnimEaseIn}, 1438 + }), 1439 + 1440 + .hide = MOVIE_DEF(STUDIO_ANIM_TIME, setIdle, 1441 + { 1442 + {0, SheetStart, STUDIO_ANIM_TIME, &map->anim.pos.sheet, AnimEaseIn}, 1443 + }), 1444 + 1445 + .bank = MOVIE_DEF(STUDIO_ANIM_TIME, setIdle, 1446 + { 1447 + {0, 0, STUDIO_ANIM_TIME, &map->anim.pos.bank, AnimEaseIn}, 1448 + }), 1449 + 1450 + .page = MOVIE_DEF(STUDIO_ANIM_TIME, setIdle, 1451 + { 1452 + {0, 0, STUDIO_ANIM_TIME, &map->anim.pos.page, AnimEaseIn}, 1453 + }), 1454 + }, 1356 1455 .event = onStudioEvent, 1357 1456 .scanline = scanline, 1358 1457 }; 1458 + 1459 + map->anim.movie = resetMovie(&map->anim.idle); 1359 1460 1360 1461 normalizeMap(&map->scroll.x, &map->scroll.y); 1361 1462 tic_blit_update_bpp(&map->sheet.blit, TIC_DEFAULT_BIT_DEPTH); ··· 1363 1464 1364 1465 void freeMap(Map* map) 1365 1466 { 1467 + freeAnim(map); 1366 1468 history_delete(map->history); 1367 1469 free(map); 1368 1470 }
+20 -1
src/studio/editors/map.h
··· 52 52 53 53 struct 54 54 { 55 - bool show; 55 + bool keep; 56 56 tic_rect rect; 57 57 tic_point start; 58 58 bool drag; ··· 82 82 u8* paste; 83 83 84 84 struct History* history; 85 + 86 + struct 87 + { 88 + struct 89 + { 90 + s32 sheet; 91 + s32 bank; 92 + s32 page; 93 + } pos; 94 + 95 + Movie* movie; 96 + 97 + Movie idle; 98 + Movie show; 99 + Movie hide; 100 + Movie bank; 101 + Movie page; 102 + 103 + } anim; 85 104 86 105 void (*tick)(Map*); 87 106 void (*event)(Map*, StudioEvent);
+91 -22
src/studio/editors/sprite.c
··· 57 57 58 58 static void initTileSheet(Sprite* sprite) 59 59 { 60 + sprite->blit.page %= sprite->blit.pages; 60 61 sprite->sheet = tic_tilesheet_get((( sprite->blit.pages + sprite->blit.page) << 1) + sprite->blit.bank, (u8*)sprite->src); 61 62 } 62 63 63 64 static void updateIndex(Sprite* sprite) 64 65 { 65 - sprite->blit.page %= sprite->blit.pages; 66 66 sprite->index = sprite->y * sprite->blit.pages * TIC_SPRITESHEET_COLS + sprite->x; 67 67 // index has changed, clear selection 68 68 clearCanvasSelection(sprite); 69 69 } 70 70 71 - static void leftViewport(Sprite* sprite) 71 + static inline bool isIdle(Sprite* sprite) 72 72 { 73 - if (sprite->blit.page > 0) sprite->blit.page--; 74 - updateIndex(sprite); 75 - initTileSheet(sprite); 73 + return sprite->anim.movie == &sprite->anim.idle; 76 74 } 77 75 78 - static void rightViewport(Sprite* sprite) 76 + static void selectViewportPage(Sprite* sprite, u8 page) 79 77 { 80 - if (sprite->blit.page < sprite->blit.pages-1) sprite->blit.page++; 81 - updateIndex(sprite); 82 - initTileSheet(sprite); 78 + if(isIdle(sprite)) 79 + { 80 + Anim* anim = sprite->anim.page.items; 81 + anim->start = (page - sprite->blit.page) * TIC_SPRITESHEET_SIZE; 82 + sprite->anim.movie = resetMovie(&sprite->anim.page); 83 + 84 + sprite->blit.page = page; 85 + updateIndex(sprite); 86 + initTileSheet(sprite); 87 + } 83 88 } 84 89 85 - static void selectViewportPage(Sprite* sprite, u8 page) 90 + static void leftViewport(Sprite* sprite) 86 91 { 87 - sprite->blit.page = page; 88 - updateIndex(sprite); 89 - initTileSheet(sprite); 92 + s32 page = sprite->blit.page + sprite->blit.pages - 1; 93 + selectViewportPage(sprite, page % sprite->blit.pages); 94 + } 95 + 96 + static void rightViewport(Sprite* sprite) 97 + { 98 + s32 page = sprite->blit.page + sprite->blit.pages + 1; 99 + selectViewportPage(sprite, page % sprite->blit.pages); 90 100 } 91 101 92 102 static s32 getIndexPosX(Sprite* sprite) ··· 1290 1300 { 1291 1301 tic_mem* tic = sprite->tic; 1292 1302 tiles2ram(&tic->ram, sprite->src); 1293 - tic->ram.vram.blit.segment = tic_blit_calc_segment(&sprite->blit); 1294 - tic_api_spr(tic, 0, x, y, TIC_SPRITESHEET_COLS, TIC_SPRITESHEET_COLS, NULL, 0, 1, tic_no_flip, tic_no_rotate); 1295 - tic->ram.vram.blit.segment = TIC_DEFAULT_BLIT_MODE; 1303 + 1304 + tic_blit blit = sprite->blit; 1305 + SCOPE(tic->ram.vram.blit.segment = TIC_DEFAULT_BLIT_MODE) 1306 + { 1307 + tic_point start = 1308 + { 1309 + x - blit.page * TIC_SPRITESHEET_SIZE + sprite->anim.pos.page, 1310 + y - blit.bank * TIC_SPRITESHEET_SIZE + sprite->anim.pos.bank 1311 + }, pos = start; 1312 + 1313 + for(blit.bank = 0; blit.bank < TIC_SPRITE_BANKS; ++blit.bank, pos.y += TIC_SPRITESHEET_SIZE, pos.x = start.x) 1314 + { 1315 + for(blit.page = 0; blit.page < blit.pages; ++blit.page, pos.x += TIC_SPRITESHEET_SIZE) 1316 + { 1317 + tic->ram.vram.blit.segment = tic_blit_calc_segment(&blit); 1318 + tic_api_spr(tic, 0, pos.x, pos.y, TIC_SPRITESHEET_COLS, TIC_SPRITESHEET_COLS, NULL, 0, 1, tic_no_flip, tic_no_rotate); 1319 + } 1320 + } 1321 + } 1296 1322 } 1297 1323 1298 1324 static void flipSpriteHorz(Sprite* sprite) ··· 1554 1580 1555 1581 static void switchBanks(Sprite* sprite) 1556 1582 { 1557 - sprite->blit.bank = !sprite->blit.bank; 1583 + if(isIdle(sprite)) 1584 + { 1585 + s32 bank = (sprite->blit.bank + 1) % TIC_SPRITE_BANKS; 1586 + Anim* anim = sprite->anim.bank.items; 1587 + anim->start = (bank - sprite->blit.bank) * TIC_SPRITESHEET_SIZE; 1588 + sprite->anim.movie = resetMovie(&sprite->anim.bank); 1558 1589 1559 - updateIndex(sprite); 1560 - initTileSheet(sprite); 1590 + sprite->blit.bank = bank; 1591 + 1592 + updateIndex(sprite); 1593 + initTileSheet(sprite); 1594 + } 1561 1595 } 1562 1596 1563 1597 static void drawTab(tic_mem* tic, s32 x, s32 y, s32 w, s32 h, u8 icon, bool active, bool over) ··· 1856 1890 { 1857 1891 tic_mem* tic = sprite->tic; 1858 1892 1893 + processAnim(sprite->anim.movie, sprite); 1894 + 1859 1895 // process scroll 1860 1896 { 1861 1897 tic80_input* input = &tic->ram.input; ··· 1877 1913 1878 1914 processKeyboard(sprite); 1879 1915 1916 + drawSheet(sprite, SheetX, SheetY); 1880 1917 drawCanvas(sprite, CanvasX, CanvasY); 1881 1918 drawPalette(sprite, PaletteX, PaletteY); 1882 - drawSheet(sprite, SheetX, SheetY); 1883 1919 1884 1920 VBANK(tic, 1) 1885 1921 { ··· 1944 1980 } 1945 1981 } 1946 1982 1983 + static void emptyDone() {} 1984 + 1985 + static void setIdle(void* data) 1986 + { 1987 + Sprite* sprite = data; 1988 + sprite->anim.movie = resetMovie(&sprite->anim.idle); 1989 + } 1990 + 1991 + static void freeAnim(Sprite* sprite) 1992 + { 1993 + FREE(sprite->anim.bank.items); 1994 + FREE(sprite->anim.page.items); 1995 + } 1996 + 1947 1997 void initSprite(Sprite* sprite, tic_mem* tic, tic_tiles* src) 1948 1998 { 1949 1999 if(sprite->select.back == NULL) sprite->select.back = (u8*)malloc(CANVAS_SIZE*CANVAS_SIZE); 1950 2000 if(sprite->select.front == NULL) sprite->select.front = (u8*)malloc(CANVAS_SIZE*CANVAS_SIZE); 1951 2001 if(sprite->history) history_delete(sprite->history); 1952 - 2002 + freeAnim(sprite); 2003 + 1953 2004 *sprite = (Sprite) 1954 2005 { 1955 2006 .tic = tic, ··· 1979 2030 }, 1980 2031 .mode = SPRITE_DRAW_MODE, 1981 2032 .history = history_create(src, TIC_SPRITES * sizeof(tic_tile)), 2033 + .anim = 2034 + { 2035 + .idle = {.done = emptyDone,}, 2036 + 2037 + .bank = MOVIE_DEF(STUDIO_ANIM_TIME, setIdle, 2038 + { 2039 + {0, 0, STUDIO_ANIM_TIME, &sprite->anim.pos.bank, AnimEaseIn}, 2040 + }), 2041 + 2042 + .page = MOVIE_DEF(STUDIO_ANIM_TIME, setIdle, 2043 + { 2044 + {0, 0, STUDIO_ANIM_TIME, &sprite->anim.pos.page, AnimEaseIn}, 2045 + }), 2046 + }, 1982 2047 .event = onStudioEvent, 1983 - .scanline = scanline, 2048 + .scanline = scanline, 1984 2049 }; 2050 + 2051 + sprite->anim.movie = resetMovie(&sprite->anim.idle); 2052 + 1985 2053 switchBitMode(sprite, TIC_DEFAULT_BIT_DEPTH); 1986 2054 } 1987 2055 1988 2056 void freeSprite(Sprite* sprite) 1989 2057 { 2058 + freeAnim(sprite); 1990 2059 free(sprite->select.back); 1991 2060 free(sprite->select.front); 1992 2061 history_delete(sprite->history);
+16
src/studio/editors/sprite.h
··· 72 72 73 73 struct History* history; 74 74 75 + struct 76 + { 77 + struct 78 + { 79 + s32 bank; 80 + s32 page; 81 + } pos; 82 + 83 + Movie* movie; 84 + 85 + Movie idle; 86 + Movie bank; 87 + Movie page; 88 + 89 + } anim; 90 + 75 91 void (*tick)(Sprite*); 76 92 void (*event)(Sprite*, StudioEvent); 77 93 void (*scanline)(tic_mem* tic, s32 row, void* data);
+7
src/studio/editors/world.c
··· 81 81 { 82 82 tic_mem* tic = world->tic; 83 83 84 + // process scroll 85 + if(tic->ram.input.mouse.scrolly < 0) 86 + { 87 + setStudioMode(TIC_MAP_MODE); 88 + return; 89 + } 90 + 84 91 if(keyWasPressed(tic_key_tab)) setStudioMode(TIC_MAP_MODE); 85 92 86 93 memcpy(&tic->ram.vram, world->preview, PREVIEW_SIZE);
+14 -24
src/studio/screens/menu.c
··· 82 82 enum{TextMargin = 2, ItemHeight = TIC_FONT_HEIGHT + TextMargin * 2}; 83 83 enum{Hold = KEYBOARD_HOLD, Period = ItemHeight}; 84 84 85 - static s32 linear(s32 d) 86 - { 87 - return d; 88 - } 89 - 90 - static s32 easein(s32 d) 91 - { 92 - return d * d; 93 - } 94 - 95 85 static void emptyDone() {} 96 86 97 87 static void menuUpDone(void* data) ··· 381 371 382 372 .start = MOVIE_DEF(10, startDone, 383 373 { 384 - {-10, 0, 10, &menu->anim.top, linear}, 385 - {10, 0, 10, &menu->anim.bottom, linear}, 386 - {0, 10, 10, &menu->anim.cursor, linear}, 387 - {-TIC80_WIDTH, 0, 10, &menu->anim.offset, linear}, 374 + {-10, 0, 10, &menu->anim.top, AnimLinear}, 375 + {10, 0, 10, &menu->anim.bottom, AnimLinear}, 376 + {0, 10, 10, &menu->anim.cursor, AnimLinear}, 377 + {-TIC80_WIDTH, 0, 10, &menu->anim.offset, AnimLinear}, 388 378 }), 389 379 390 - .up = MOVIE_DEF(9, menuUpDone, {{0, -9, 9, &menu->anim.pos, easein}}), 391 - .down = MOVIE_DEF(9, menuDownDone, {{0, 9, 9, &menu->anim.pos, easein}}), 380 + .up = MOVIE_DEF(9, menuUpDone, {{0, -9, 9, &menu->anim.pos, AnimEaseIn}}), 381 + .down = MOVIE_DEF(9, menuDownDone, {{0, 9, 9, &menu->anim.pos, AnimEaseIn}}), 392 382 393 383 .close = MOVIE_DEF(10, closeDone, 394 384 { 395 - {0, -10, 10, &menu->anim.top, linear}, 396 - {0, 10, 10, &menu->anim.bottom, linear}, 397 - {10, 0, 10, &menu->anim.cursor, linear}, 398 - {0, TIC80_WIDTH, 10, &menu->anim.offset, linear}, 385 + {0, -10, 10, &menu->anim.top, AnimLinear}, 386 + {0, 10, 10, &menu->anim.bottom, AnimLinear}, 387 + {10, 0, 10, &menu->anim.cursor, AnimLinear}, 388 + {0, TIC80_WIDTH, 10, &menu->anim.offset, AnimLinear}, 399 389 }), 400 390 401 391 .back = MOVIE_DEF(10, backDone, 402 392 { 403 - {0, -10, 10, &menu->anim.top, linear}, 404 - {0, 10, 10, &menu->anim.bottom, linear}, 405 - {10, 0, 10, &menu->anim.cursor, linear}, 406 - {0, TIC80_WIDTH, 10, &menu->anim.offset, linear}, 393 + {0, -10, 10, &menu->anim.top, AnimLinear}, 394 + {0, 10, 10, &menu->anim.bottom, AnimLinear}, 395 + {10, 0, 10, &menu->anim.cursor, AnimLinear}, 396 + {0, TIC80_WIDTH, 10, &menu->anim.offset, AnimLinear}, 407 397 }), 408 398 }, 409 399 };
+155 -229
src/studio/screens/surf.c
··· 39 39 #define MAIN_OFFSET 4 40 40 #define MENU_HEIGHT 10 41 41 #define ANIM 10 42 + #define PAGE 5 42 43 #define COVER_WIDTH 140 43 44 #define COVER_HEIGHT 116 44 45 #define COVER_Y 5 ··· 52 53 53 54 static const char* PngExt = PNG_EXT; 54 55 55 - typedef struct 56 - { 57 - s32 start; 58 - s32 end; 59 - s32 duration; 60 - 61 - s32* val; 62 - } SurfAnim; 63 - 64 - typedef struct SurfMovie SurfMovie; 65 - 66 - struct SurfMovie 67 - { 68 - SurfAnim** items; 69 - 70 - s32 time; 71 - s32 duration; 72 - s32 count; 73 - 74 - SurfMovie* next; 75 - void (*done)(Surf* surf); 76 - }; 77 - 78 - static struct 79 - { 80 - s32 topBarY; 81 - s32 bottomBarY; 82 - s32 menuX; 83 - s32 menuHeight; 84 - s32 coverFade; 85 - } AnimVar; 86 - 87 - static SurfAnim topBarShowAnim = {0, MENU_HEIGHT, ANIM, &AnimVar.topBarY}; 88 - static SurfAnim bottomBarShowAnim = {0, MENU_HEIGHT, ANIM, &AnimVar.bottomBarY}; 89 - static SurfAnim topBarHideAnim = {MENU_HEIGHT, 0, ANIM, &AnimVar.topBarY}; 90 - static SurfAnim bottomBarHideAnim = {MENU_HEIGHT, 0, ANIM, &AnimVar.bottomBarY}; 91 - static SurfAnim menuLeftHideAnim = {0, -TIC80_WIDTH, ANIM, &AnimVar.menuX}; 92 - static SurfAnim menuRightHideAnim = {0, TIC80_WIDTH, ANIM, &AnimVar.menuX}; 93 - static SurfAnim menuHideAnim = {MENU_HEIGHT, 0, ANIM, &AnimVar.menuHeight}; 94 - static SurfAnim menuLeftShowAnim = {TIC80_WIDTH, 0, ANIM, &AnimVar.menuX}; 95 - static SurfAnim menuRightShowAnim = {-TIC80_WIDTH, 0, ANIM, &AnimVar.menuX}; 96 - static SurfAnim menuShowAnim = {0, MENU_HEIGHT, ANIM, &AnimVar.menuHeight}; 97 - static SurfAnim coverFadeInAnim = {COVER_FADEOUT, COVER_FADEIN, ANIM, &AnimVar.coverFade}; 98 - static SurfAnim coverFadeOutAnim = {COVER_FADEIN, COVER_FADEOUT, ANIM, &AnimVar.coverFade}; 99 - 100 - static SurfAnim* MenuModeShowMovieItems[] = 101 - { 102 - &topBarShowAnim, 103 - &bottomBarShowAnim, 104 - &menuRightShowAnim, 105 - &menuShowAnim, 106 - &coverFadeInAnim, 107 - }; 108 - 109 - static SurfAnim* MenuModeHideMovieItems[] = 110 - { 111 - &topBarHideAnim, 112 - &bottomBarHideAnim, 113 - &menuLeftHideAnim, 114 - &menuHideAnim, 115 - &coverFadeOutAnim, 116 - }; 117 - 118 - static SurfAnim* MenuLeftHideMovieItems[] = 119 - { 120 - &menuLeftHideAnim, 121 - &menuHideAnim, 122 - }; 123 - 124 - static SurfAnim* MenuRightHideMovieItems[] = 125 - { 126 - &menuRightHideAnim, 127 - &menuHideAnim, 128 - }; 129 - 130 - static SurfAnim* MenuLeftShowMovieItems[] = 131 - { 132 - &menuLeftShowAnim, 133 - &menuShowAnim, 134 - }; 135 - 136 - static SurfAnim* MenuRightShowMovieItems[] = 137 - { 138 - &menuRightShowAnim, 139 - &menuShowAnim, 140 - }; 141 - 142 - static SurfMovie EmptyState; 143 - static SurfMovie MenuModeState; 144 - 145 - #define DECLARE_MOVIE(NAME, NEXT) static SurfMovie NAME ## State = \ 146 - { \ 147 - .items = NAME ## MovieItems, \ 148 - .count = COUNT_OF(NAME ## MovieItems), \ 149 - .duration = ANIM, \ 150 - .next = & NEXT ## State, \ 151 - } 152 - 153 - DECLARE_MOVIE(MenuModeShow, MenuMode); 154 - DECLARE_MOVIE(MenuModeHide, Empty); 155 - DECLARE_MOVIE(MenuLeftShow, MenuMode); 156 - DECLARE_MOVIE(MenuRightShow, MenuMode); 157 - DECLARE_MOVIE(MenuLeftHide, MenuLeftShow); 158 - DECLARE_MOVIE(MenuRightHide, MenuRightShow); 159 - 160 56 typedef struct SurfItem SurfItem; 161 57 162 58 struct SurfItem ··· 182 78 fs_done_callback done; 183 79 void* data; 184 80 } AddMenuItemData; 185 - 186 - static void resetSurfMovie(Surf* surf, SurfMovie* movie, void (*done)(Surf* surf)) 187 - { 188 - surf->state = movie; 189 - 190 - for(s32 i = 0; i < movie->count; i++) 191 - { 192 - SurfAnim* anim = movie->items[i]; 193 - *anim->val = anim->start; 194 - } 195 - 196 - movie->time = 0; 197 - movie->done = done; 198 - } 199 81 200 82 static void drawTopToolbar(Surf* surf, s32 x, s32 y) 201 83 { ··· 225 107 tic_api_print(tic, Label, TipX + Gap, y+2, tic_color_white, true, 1, false); 226 108 } 227 109 228 - tic_api_spr(tic, 13, TipX + SelectWidth, y + 1, 1, 1, &colorkey, 1, 1, tic_no_flip, tic_no_rotate);//&getConfig()->cart->bank0.tiles, 110 + tic_api_spr(tic, 13, TipX + SelectWidth, y + 1, 1, 1, &colorkey, 1, 1, tic_no_flip, tic_no_rotate); 229 111 { 230 112 static const char Label[] = "BACK"; 231 113 tic_api_print(tic, Label, TipX + Gap + SelectWidth, y +3, tic_color_black, true, 1, false); ··· 284 166 285 167 enum {Height = MENU_HEIGHT}; 286 168 287 - tic_api_rect(tic, 0, y + (MENU_HEIGHT - AnimVar.menuHeight)/2, TIC80_WIDTH, AnimVar.menuHeight, tic_color_red); 169 + tic_api_rect(tic, 0, y + (MENU_HEIGHT - surf->anim.val.menuHeight) / 2, TIC80_WIDTH, surf->anim.val.menuHeight, tic_color_red); 288 170 289 - for(s32 i = 0; i < surf->menu.count; i++) 171 + s32 ym = y - surf->menu.pos * MENU_HEIGHT + (MENU_HEIGHT - TIC_FONT_HEIGHT) / 2 - surf->anim.val.pos; 172 + for(s32 i = 0; i < surf->menu.count; i++, ym += Height) 290 173 { 291 174 const char* name = surf->menu.items[i].label; 292 175 293 - s32 ym = Height * i + y - surf->menu.pos*MENU_HEIGHT - (surf->menu.anim * surf->menu.anim_target) + (MENU_HEIGHT - TIC_FONT_HEIGHT)/2; 294 - 295 - if (ym > (-(TIC_FONT_HEIGHT + 1)) && ym <= TIC80_HEIGHT) { 176 + if (ym > (-(TIC_FONT_HEIGHT + 1)) && ym <= TIC80_HEIGHT) 177 + { 296 178 tic_api_print(tic, name, x + MAIN_OFFSET, ym + 1, tic_color_black, false, 1, false); 297 179 tic_api_print(tic, name, x + MAIN_OFFSET, ym, tic_color_white, false, 1, false); 298 180 } ··· 404 286 } 405 287 406 288 surf->menu.pos = 0; 407 - surf->menu.anim = 0; 408 289 } 409 290 410 291 static void updateMenuItemCover(Surf* surf, s32 pos, const u8* cover, s32 size) ··· 579 460 char* last; 580 461 } GoBackDirDoneData; 581 462 582 - static void initItems(Surf* surf) 583 - { 584 - initItemsAsync(surf, NULL, NULL); 585 - } 586 - 587 463 static void onGoBackDirDone(void* data) 588 464 { 589 465 GoBackDirDoneData* goBackDirDoneData = data; ··· 614 490 615 491 free(goBackDirDoneData->last); 616 492 free(goBackDirDoneData); 493 + 494 + surf->anim.movie = resetMovie(&surf->anim.goback.show); 617 495 } 618 496 619 - static void onGoBackDir(Surf* surf) 497 + static void onGoBackDir(void* data) 620 498 { 499 + Surf* surf = data; 621 500 char last[TICNAME_MAX]; 622 501 tic_fs_dir(surf->fs, last); 623 502 ··· 627 506 initItemsAsync(surf, onGoBackDirDone, MOVE(goBackDirDoneData)); 628 507 } 629 508 630 - static void onGoToDir(Surf* surf) 509 + static void onGoToDirDone(void* data) 631 510 { 511 + Surf* surf = data; 512 + surf->anim.movie = resetMovie(&surf->anim.gotodir.show); 513 + } 514 + 515 + static void onGoToDir(void* data) 516 + { 517 + Surf* surf = data; 632 518 SurfItem* item = getMenuItem(surf); 633 519 634 520 tic_fs_changedir(surf->fs, item->name); 635 - initItems(surf); 521 + initItemsAsync(surf, onGoToDirDone, surf); 636 522 } 637 523 638 524 static void goBackDir(Surf* surf) ··· 643 529 if(strcmp(dir, "") != 0) 644 530 { 645 531 playSystemSfx(2); 646 - resetSurfMovie(surf, &MenuRightHideState, onGoBackDir); 532 + 533 + surf->anim.movie = resetMovie(&surf->anim.goback.hide); 647 534 } 648 535 } 649 536 ··· 656 543 else 657 544 { 658 545 playSystemSfx(2); 659 - resetSurfMovie(surf, &MenuLeftHideState, onGoToDir); 546 + surf->anim.movie = resetMovie(&surf->anim.gotodir.hide); 660 547 } 661 548 } 662 549 ··· 665 552 runGame(); 666 553 } 667 554 668 - static void onPlayCart(Surf* surf) 555 + static void onPlayCart(void* data) 669 556 { 557 + Surf* surf = data; 670 558 SurfItem* item = getMenuItem(surf); 671 559 672 560 if (item->hash) ··· 695 583 696 584 if(cart) 697 585 { 698 - resetSurfMovie(surf, &MenuModeHideState, onPlayCart); 586 + surf->anim.movie = resetMovie(&surf->anim.play); 699 587 free(cart); 700 588 } 701 589 } 702 590 } 703 - else resetSurfMovie(surf, &MenuModeHideState, onPlayCart); 591 + else surf->anim.movie = resetMovie(&surf->anim.play); 704 592 } 705 593 706 - static void processSurfAnim(Surf* surf) 594 + static void move(Surf* surf, s32 dir) 707 595 { 708 - enum{Frames = MENU_HEIGHT}; 709 - 710 - { 711 - if(surf->state->time > surf->state->duration) 712 - { 713 - if(surf->state->done) 714 - surf->state->done(surf); 715 - 716 - if(surf->state->next) 717 - resetSurfMovie(surf, surf->state->next, NULL); 718 - } 719 - 720 - for(s32 i = 0; i < surf->state->count; i++) 721 - { 722 - SurfAnim* anim = surf->state->items[i]; 723 - 724 - if(surf->state->time < anim->duration) 725 - { 726 - *anim->val = anim->start + (anim->end - anim->start) * surf->state->time / anim->duration; 727 - } 728 - else 729 - { 730 - *anim->val = anim->end; 731 - } 732 - } 733 - 734 - surf->state->time++; 735 - 736 - } 737 - 738 - if(surf->menu.anim > 0) 739 - { 740 - surf->menu.anim++; 741 - 742 - if(surf->menu.anim >= Frames) 743 - { 744 - s32 old_pos = surf->menu.pos; 745 - 746 - surf->menu.anim = 0; 747 - surf->menu.pos += surf->menu.anim_target; 596 + surf->menu.target = (surf->menu.pos + surf->menu.count + dir) % surf->menu.count; 748 597 749 - if(surf->menu.pos < 0) 750 - { 751 - if(old_pos == 0) 752 - surf->menu.pos = surf->menu.count - 1; 753 - else 754 - surf->menu.pos = 0; 755 - } 756 - else if(surf->menu.pos >= surf->menu.count) 757 - { 758 - if(old_pos == surf->menu.count - 1) 759 - surf->menu.pos = 0; 760 - else 761 - surf->menu.pos = surf->menu.count - 1; 598 + Anim* anim = surf->anim.move.items; 599 + anim->end = (surf->menu.target - surf->menu.pos) * MENU_HEIGHT; 762 600 763 - } 764 - } 765 - } 601 + surf->anim.movie = resetMovie(&surf->anim.move); 766 602 } 767 603 768 604 static void processGamepad(Surf* surf) ··· 782 618 if(tic_api_btnp(tic, Up, Hold, Period) 783 619 || tic_api_keyp(tic, tic_key_up, Hold, Period)) 784 620 { 785 - surf->menu.anim = 1; 786 - surf->menu.anim_target = -1; 787 - 621 + move(surf, -1); 788 622 playSystemSfx(2); 789 623 } 790 624 else if(tic_api_btnp(tic, Down, Hold, Period) 791 625 || tic_api_keyp(tic, tic_key_down, Hold, Period)) 792 626 { 793 - surf->menu.anim = 1; 794 - surf->menu.anim_target = 1; 795 - 627 + move(surf, +1); 796 628 playSystemSfx(2); 797 629 } 798 630 else if(tic_api_btnp(tic, Left, Hold, Period) 799 631 || tic_api_keyp(tic, tic_key_left, Hold, Period) 800 632 || tic_api_keyp(tic, tic_key_pageup, Hold, Period)) 801 633 { 802 - surf->menu.anim = 1; 803 - surf->menu.anim_target = -5; 634 + s32 dir = -PAGE; 635 + 636 + if(surf->menu.pos == 0) dir = -1; 637 + else if(surf->menu.pos <= PAGE) dir = -surf->menu.pos; 638 + 639 + move(surf, dir); 804 640 } 805 641 else if(tic_api_btnp(tic, Right, Hold, Period) 806 642 || tic_api_keyp(tic, tic_key_right, Hold, Period) 807 643 || tic_api_keyp(tic, tic_key_pagedown, Hold, Period)) 808 644 { 809 - surf->menu.anim = 1; 810 - surf->menu.anim_target = 5; 645 + s32 dir = +PAGE, last = surf->menu.count - 1; 646 + 647 + if(surf->menu.pos == last) dir = +1; 648 + else if(surf->menu.pos + PAGE >= last) dir = last - surf->menu.pos; 649 + 650 + move(surf, dir); 811 651 } 812 652 813 653 if(tic_api_btnp(tic, A, -1, -1) ··· 844 684 845 685 } 846 686 687 + static inline bool isIdle(Surf* surf) 688 + { 689 + return surf->anim.movie == &surf->anim.idle; 690 + } 691 + 847 692 static void tick(Surf* surf) 848 693 { 694 + processAnim(surf->anim.movie, surf); 695 + 849 696 if(!surf->init) 850 697 { 851 - initItems(surf); 852 - 853 - resetSurfMovie(surf, &MenuModeShowState, NULL); 854 - 698 + initItemsAsync(surf, NULL, NULL); 699 + surf->anim.movie = resetMovie(&surf->anim.show); 855 700 surf->init = true; 856 701 } 857 - 858 - surf->ticks++; 859 702 860 703 tic_mem* tic = surf->tic; 861 704 tic_api_cls(tic, TIC_COLOR_BG); 862 705 863 - studio_menu_anim(surf->tic, surf->ticks); 864 - 865 - if (surf->menu.count > 0) 866 - { 867 - processSurfAnim(surf); 706 + studio_menu_anim(surf->tic, surf->ticks++); 868 707 869 - if (surf->state == &MenuModeState) 870 - { 871 - processGamepad(surf); 872 - } 873 - } 708 + if (isIdle(surf) && surf->menu.count > 0) 709 + processGamepad(surf); 874 710 875 711 if (getStudioMode() != TIC_SURF_MODE) return; 876 712 ··· 891 727 892 728 if(surf->menu.count > 0) 893 729 { 894 - drawMenu(surf, AnimVar.menuX, (TIC80_HEIGHT - MENU_HEIGHT)/2); 730 + drawMenu(surf, surf->anim.val.menuX, (TIC80_HEIGHT - MENU_HEIGHT)/2); 895 731 } 896 732 else if(!surf->loading) 897 733 { ··· 900 736 tic_api_print(tic, Label, (TIC80_WIDTH - size) / 2, (TIC80_HEIGHT - TIC_FONT_HEIGHT)/2, tic_color_white, true, 1, false); 901 737 } 902 738 903 - drawTopToolbar(surf, 0, AnimVar.topBarY - MENU_HEIGHT); 904 - drawBottomToolbar(surf, 0, TIC80_HEIGHT - AnimVar.bottomBarY); 739 + drawTopToolbar(surf, 0, surf->anim.val.topBarY - MENU_HEIGHT); 740 + drawBottomToolbar(surf, 0, TIC80_HEIGHT - surf->anim.val.bottomBarY); 905 741 } 906 742 } 907 743 908 744 static void resume(Surf* surf) 909 745 { 910 - resetSurfMovie(surf, &MenuModeShowState, NULL); 746 + surf->anim.movie = resetMovie(&surf->anim.show); 911 747 } 912 748 913 749 static void scanline(tic_mem* tic, s32 row, void* data) ··· 923 759 if(row == 0) 924 760 { 925 761 memcpy(&tic->ram.vram.palette, item->palette, sizeof(tic_palette)); 926 - fadePalette(&tic->ram.vram.palette, AnimVar.coverFade); 762 + fadePalette(&tic->ram.vram.palette, surf->anim.val.coverFade); 927 763 } 928 764 929 765 return; ··· 933 769 studio_menu_anim_scanline(tic, row, NULL); 934 770 } 935 771 772 + static void emptyDone() {} 773 + 774 + static void setIdle(void* data) 775 + { 776 + Surf* surf = data; 777 + surf->anim.movie = resetMovie(&surf->anim.idle); 778 + } 779 + 780 + static void setLeftShow(void* data) 781 + { 782 + Surf* surf = data; 783 + surf->anim.movie = resetMovie(&surf->anim.gotodir.show); 784 + } 785 + 786 + static void freeAnim(Surf* surf) 787 + { 788 + FREE(surf->anim.show.items); 789 + FREE(surf->anim.play.items); 790 + FREE(surf->anim.move.items); 791 + FREE(surf->anim.gotodir.show.items); 792 + FREE(surf->anim.gotodir.hide.items); 793 + FREE(surf->anim.goback.show.items); 794 + FREE(surf->anim.goback.hide.items); 795 + } 796 + 797 + static void moveDone(void* data) 798 + { 799 + Surf* surf = data; 800 + surf->menu.pos = surf->menu.target; 801 + surf->anim.val.pos = 0; 802 + surf->anim.movie = resetMovie(&surf->anim.idle); 803 + } 804 + 936 805 void initSurf(Surf* surf, tic_mem* tic, struct Console* console) 937 806 { 807 + freeAnim(surf); 808 + 938 809 *surf = (Surf) 939 810 { 940 811 .tic = tic, ··· 943 814 .net = console->net, 944 815 .tick = tick, 945 816 .ticks = 0, 946 - .state = &EmptyState, 947 817 .init = false, 948 818 .loading = true, 949 819 .resume = resume, 950 820 .menu = 951 821 { 952 822 .pos = 0, 953 - .anim = 0, 954 823 .items = NULL, 955 824 .count = 0, 956 825 }, 826 + .anim = 827 + { 828 + .idle = {.done = emptyDone,}, 829 + 830 + .show = MOVIE_DEF(ANIM, setIdle, 831 + { 832 + {0, MENU_HEIGHT, ANIM, &surf->anim.val.topBarY, AnimEaseIn}, 833 + {0, MENU_HEIGHT, ANIM, &surf->anim.val.bottomBarY, AnimEaseIn}, 834 + {-TIC80_WIDTH, 0, ANIM, &surf->anim.val.menuX, AnimEaseIn}, 835 + {0, MENU_HEIGHT, ANIM, &surf->anim.val.menuHeight, AnimEaseIn}, 836 + {COVER_FADEOUT, COVER_FADEIN, ANIM, &surf->anim.val.coverFade, AnimEaseIn}, 837 + }), 838 + 839 + .play = MOVIE_DEF(ANIM, onPlayCart, 840 + { 841 + {MENU_HEIGHT, 0, ANIM, &surf->anim.val.topBarY, AnimEaseIn}, 842 + {MENU_HEIGHT, 0, ANIM, &surf->anim.val.bottomBarY, AnimEaseIn}, 843 + {0, -TIC80_WIDTH, ANIM, &surf->anim.val.menuX, AnimEaseIn}, 844 + {MENU_HEIGHT, 0, ANIM, &surf->anim.val.menuHeight, AnimEaseIn}, 845 + {COVER_FADEIN, COVER_FADEOUT, ANIM, &surf->anim.val.coverFade, AnimEaseIn}, 846 + }), 847 + 848 + .move = MOVIE_DEF(9, moveDone, {{0, 0, 9, &surf->anim.val.pos, AnimLinear}}), 849 + 850 + .gotodir = 851 + { 852 + .show = MOVIE_DEF(ANIM, setIdle, 853 + { 854 + {TIC80_WIDTH, 0, ANIM, &surf->anim.val.menuX, AnimEaseIn}, 855 + {0, MENU_HEIGHT, ANIM, &surf->anim.val.menuHeight, AnimEaseIn}, 856 + }), 857 + 858 + .hide = MOVIE_DEF(ANIM, onGoToDir, 859 + { 860 + {0, -TIC80_WIDTH, ANIM, &surf->anim.val.menuX, AnimEaseIn}, 861 + {MENU_HEIGHT, 0, ANIM, &surf->anim.val.menuHeight, AnimEaseIn}, 862 + }), 863 + }, 864 + 865 + .goback = 866 + { 867 + .show = MOVIE_DEF(ANIM, setIdle, 868 + { 869 + {-TIC80_WIDTH, 0, ANIM, &surf->anim.val.menuX, AnimEaseIn}, 870 + {0, MENU_HEIGHT, ANIM, &surf->anim.val.menuHeight, AnimEaseIn}, 871 + }), 872 + 873 + .hide = MOVIE_DEF(ANIM, onGoBackDir, 874 + { 875 + {0, TIC80_WIDTH, ANIM, &surf->anim.val.menuX, AnimEaseIn}, 876 + {MENU_HEIGHT, 0, ANIM, &surf->anim.val.menuHeight, AnimEaseIn}, 877 + }), 878 + }, 879 + }, 957 880 .scanline = scanline, 958 881 }; 959 882 883 + surf->anim.movie = resetMovie(&surf->anim.idle); 884 + 960 885 tic_fs_makedir(surf->fs, TIC_CACHE); 961 886 } 962 887 963 888 void freeSurf(Surf* surf) 964 889 { 890 + freeAnim(surf); 965 891 resetMenu(surf); 966 892 free(surf); 967 893 }
+34 -3
src/studio/screens/surf.h
··· 32 32 struct tic_fs* fs; 33 33 struct tic_net* net; 34 34 struct Console* console; 35 - struct SurfMovie* state; 36 35 37 36 bool init; 38 37 bool loading; ··· 41 40 struct 42 41 { 43 42 s32 pos; 44 - s32 anim; 45 - s32 anim_target; 43 + s32 target; 46 44 struct SurfItem* items; 47 45 s32 count; 48 46 } menu; 47 + 48 + struct 49 + { 50 + struct 51 + { 52 + s32 topBarY; 53 + s32 bottomBarY; 54 + s32 menuX; 55 + s32 menuHeight; 56 + s32 coverFade; 57 + s32 pos; 58 + } val; 59 + 60 + Movie* movie; 61 + 62 + Movie idle; 63 + Movie show; 64 + Movie play; 65 + Movie move; 66 + 67 + struct 68 + { 69 + Movie show; 70 + Movie hide; 71 + } gotodir; 72 + 73 + struct 74 + { 75 + Movie show; 76 + Movie hide; 77 + } goback; 78 + 79 + } anim; 49 80 50 81 void(*tick)(Surf* surf); 51 82 void(*resume)(Surf* surf);
+207 -28
src/studio/studio.c
··· 53 53 #include "argparse.h" 54 54 55 55 #include <ctype.h> 56 - #include <math.h> 57 56 58 - 59 - 60 - #define OPTION_VALUES(...) \ 61 - .values = (const char*[])__VA_ARGS__, \ 62 - .count = COUNT_OF(((const char*[])__VA_ARGS__)) 57 + #define _USE_MATH_DEFINES 58 + #include <math.h> 63 59 64 60 #if defined(BUILD_EDITORS) 65 61 66 62 #define FRAME_SIZE (TIC80_FULLWIDTH * TIC80_FULLHEIGHT * sizeof(u32)) 67 - #define POPUP_DUR (TIC80_FRAMERATE*2) 68 63 69 64 static const char VideoGif[] = "video%i.gif"; 70 65 static const char ScreenGif[] = "screen%i.gif"; 71 66 72 67 #endif 73 68 74 - 69 + static void emptyDone() {} 75 70 76 71 StudioImplementation impl = 77 72 { ··· 94 89 .chained = true, 95 90 }, 96 91 92 + .anim = 93 + { 94 + .pos = 95 + { 96 + .popup = -TOOLBAR_SIZE, 97 + }, 98 + .idle = {.done = emptyDone,} 99 + }, 100 + 97 101 .popup = 98 102 { 99 - .counter = 0, 100 103 .message = "\0", 101 104 }, 102 105 ··· 649 652 650 653 #endif 651 654 652 - static inline s32 lerp(s32 a, s32 b, s32 d0, s32 d1) 655 + static inline s32 lerp(s32 a, s32 b, float d) 656 + { 657 + return (b - a) * d + a; 658 + } 659 + 660 + static inline float bounceOut(float x) 661 + { 662 + const float n1 = 7.5625; 663 + const float d1 = 2.75; 664 + 665 + if (x < 1 / d1) return n1 * x * x; 666 + else if (x < 2 / d1) return n1 * (x -= 1.5 / d1) * x + 0.75; 667 + else if (x < 2.5 / d1) return n1 * (x -= 2.25 / d1) * x + 0.9375; 668 + else return n1 * (x -= 2.625 / d1) * x + 0.984375; 669 + } 670 + 671 + static inline float animEffect(AnimEffect effect, float x) 653 672 { 654 - return (b - a) * d0 / d1 + a; 673 + const float c1 = 1.70158; 674 + const float c2 = c1 * 1.525; 675 + const float c3 = c1 + 1; 676 + const float c4 = (2 * M_PI) / 3; 677 + const float c5 = (2 * M_PI) / 4.5; 678 + 679 + switch(effect) 680 + { 681 + case AnimLinear: 682 + return x; 683 + 684 + case AnimEaseIn: 685 + return x * x; 686 + 687 + case AnimEaseOut: 688 + return 1 - (1 - x) * (1 - x); 689 + 690 + case AnimEaseInOut: 691 + return x < 0.5 ? 2 * x * x : 1 - pow(-2 * x + 2, 2) / 2; 692 + 693 + case AnimEaseInCubic: 694 + return x * x * x; 695 + 696 + case AnimEaseOutCubic: 697 + return 1 - pow(1 - x, 3); 698 + 699 + case AnimEaseInOutCubic: 700 + return x < 0.5 ? 4 * x * x * x : 1 - pow(-2 * x + 2, 3) / 2; 701 + 702 + case AnimEaseInQuart: 703 + return x * x * x * x; 704 + 705 + case AnimEaseOutQuart: 706 + return 1 - pow(1 - x, 4); 707 + 708 + case AnimEaseInOutQuart: 709 + return x < 0.5 ? 8 * x * x * x * x : 1 - pow(-2 * x + 2, 4) / 2; 710 + 711 + case AnimEaseInQuint: 712 + return x * x * x * x * x; 713 + 714 + case AnimEaseOutQuint: 715 + return 1 - pow(1 - x, 5); 716 + 717 + case AnimEaseInOutQuint: 718 + return x < 0.5 ? 16 * x * x * x * x * x : 1 - pow(-2 * x + 2, 5) / 2; 719 + 720 + case AnimEaseInSine: 721 + return 1 - cos((x * M_PI) / 2); 722 + 723 + case AnimEaseOutSine: 724 + return sin((x * M_PI) / 2); 725 + 726 + case AnimEaseInOutSine: 727 + return -(cos(M_PI * x) - 1) / 2; 728 + 729 + case AnimEaseInExpo: 730 + return x == 0 ? 0 : pow(2, 10 * x - 10); 731 + 732 + case AnimEaseOutExpo: 733 + return x == 1 ? 1 : 1 - pow(2, -10 * x); 734 + 735 + case AnimEaseInOutExpo: 736 + return x == 0 737 + ? 0 738 + : x == 1 739 + ? 1 740 + : x < 0.5 741 + ? pow(2, 20 * x - 10) / 2 742 + : (2 - pow(2, -20 * x + 10)) / 2; 743 + 744 + case AnimEaseInCirc: 745 + return 1 - sqrt(1 - pow(x, 2)); 746 + 747 + case AnimEaseOutCirc: 748 + return sqrt(1 - pow(x - 1, 2)); 749 + 750 + case AnimEaseInOutCirc: 751 + return x < 0.5 752 + ? (1 - sqrt(1 - pow(2 * x, 2))) / 2 753 + : (sqrt(1 - pow(-2 * x + 2, 2)) + 1) / 2; 754 + 755 + case AnimEaseInBack: 756 + return c3 * x * x * x - c1 * x * x; 757 + 758 + case AnimEaseOutBack: 759 + return 1 + c3 * pow(x - 1, 3) + c1 * pow(x - 1, 2); 760 + 761 + case AnimEaseInOutBack: 762 + return x < 0.5 763 + ? (pow(2 * x, 2) * ((c2 + 1) * 2 * x - c2)) / 2 764 + : (pow(2 * x - 2, 2) * ((c2 + 1) * (x * 2 - 2) + c2) + 2) / 2; 765 + 766 + case AnimEaseInElastic: 767 + return x == 0 768 + ? 0 769 + : x == 1 770 + ? 1 771 + : -pow(2, 10 * x - 10) * sin((x * 10 - 10.75) * c4); 772 + 773 + case AnimEaseOutElastic: 774 + return x == 0 775 + ? 0 776 + : x == 1 777 + ? 1 778 + : pow(2, -10 * x) * sin((x * 10 - 0.75) * c4) + 1; 779 + 780 + case AnimEaseInOutElastic: 781 + return x == 0 782 + ? 0 783 + : x == 1 784 + ? 1 785 + : x < 0.5 786 + ? -(pow(2, 20 * x - 10) * sin((20 * x - 11.125) * c5)) / 2 787 + : (pow(2, -20 * x + 10) * sin((20 * x - 11.125) * c5)) / 2 + 1; 788 + 789 + case AnimEaseInBounce: 790 + return 1 - bounceOut(1 - x); 791 + 792 + case AnimEaseOutBounce: 793 + return bounceOut(x); 794 + 795 + case AnimEaseInOutBounce: 796 + return x < 0.5 797 + ? (1 - bounceOut(1 - 2 * x)) / 2 798 + : (1 + bounceOut(2 * x - 1)) / 2; 799 + } 800 + 801 + return x; 655 802 } 656 803 657 804 static void animTick(Movie* movie) 658 805 { 659 806 for(Anim* it = movie->items, *end = it + movie->count; it != end; ++it) 660 - *it->value = lerp(it->start, it->end, it->factor(movie->tick), it->factor(it->time)); 807 + *it->value = lerp(it->start, it->end, animEffect(it->effect, (float)movie->tick / it->time)); 661 808 } 662 809 663 810 void processAnim(Movie* movie, void* data) ··· 682 829 683 830 static void drawPopup() 684 831 { 685 - if(impl.popup.counter > 0) 832 + if(impl.anim.movie != &impl.anim.idle) 686 833 { 687 - impl.popup.counter--; 834 + enum{Width = TIC80_WIDTH, Height = TIC_FONT_HEIGHT + 1}; 688 835 689 - s32 anim = 0; 690 - 691 - enum{Dur = TIC80_FRAMERATE/2, Width = TIC80_WIDTH, Height = TIC_FONT_HEIGHT+1}; 692 - 693 - if(impl.popup.counter < Dur) 694 - anim = -((Dur - impl.popup.counter) * Height / Dur); 695 - else if(impl.popup.counter >= (POPUP_DUR - Dur)) 696 - anim = (((POPUP_DUR - Dur) - impl.popup.counter) * Height / Dur); 697 - 698 - tic_api_rect(impl.studio.tic, 0, anim, Width, Height, tic_color_red); 836 + tic_api_rect(impl.studio.tic, 0, impl.anim.pos.popup, Width, Height, tic_color_red); 699 837 tic_api_print(impl.studio.tic, impl.popup.message, 700 838 (s32)(Width - strlen(impl.popup.message) * TIC_FONT_WIDTH)/2, 701 - anim + 1, tic_color_white, true, 1, false); 839 + impl.anim.pos.popup + 1, tic_color_white, true, 1, false); 702 840 703 841 // render popup message 704 842 { ··· 706 844 const tic_bank* bank = &getConfig()->cart->bank0; 707 845 u32* dst = tic->screen + TIC80_MARGIN_LEFT + TIC80_MARGIN_TOP * TIC80_FULLWIDTH; 708 846 709 - for(s32 i = 0, y = 0; y < (Height + anim); y++, dst += TIC80_MARGIN_RIGHT + TIC80_MARGIN_LEFT) 847 + for(s32 i = 0, y = 0; y < (Height + impl.anim.pos.popup); y++, dst += TIC80_MARGIN_RIGHT + TIC80_MARGIN_LEFT) 710 848 for(s32 x = 0; x < Width; x++) 711 849 *dst++ = tic_rgba(&bank->palette.vbank0.colors[tic_tool_peek4(tic->ram.vram.screen.data, i++)]); 712 - } 850 + } 713 851 } 714 852 } 715 853 ··· 848 986 849 987 static void showPopupMessage(const char* text) 850 988 { 851 - impl.popup.counter = POPUP_DUR; 852 989 memset(impl.popup.message, '\0', sizeof impl.popup.message); 853 990 strncpy(impl.popup.message, text, sizeof(impl.popup.message) - 1); 854 991 855 992 for(char* c = impl.popup.message; c < impl.popup.message + sizeof impl.popup.message; c++) 856 993 if(*c) *c = toupper(*c); 994 + 995 + impl.anim.movie = resetMovie(&impl.anim.show); 857 996 } 858 997 #endif 859 998 ··· 1845 1984 tic_mem* tic = impl.studio.tic; 1846 1985 1847 1986 #if defined(BUILD_EDITORS) 1987 + processAnim(impl.anim.movie, &impl); 1848 1988 checkChanges(); 1849 1989 tic_net_start(impl.net); 1850 1990 #endif ··· 1953 2093 freeConsole (impl.console); 1954 2094 freeWorld (impl.world); 1955 2095 freeSurf (impl.surf); 2096 + 2097 + FREE(impl.anim.show.items); 2098 + FREE(impl.anim.hide.items); 2099 + 1956 2100 #endif 1957 2101 1958 2102 freeStart (impl.start); ··· 2003 2147 return args; 2004 2148 } 2005 2149 2150 + #if defined(BUILD_EDITORS) 2151 + 2152 + static void setIdle(void* data) 2153 + { 2154 + StudioImplementation* studio = data; 2155 + studio->anim.movie = resetMovie(&studio->anim.idle); 2156 + } 2157 + 2158 + static void setPopupWait(void* data) 2159 + { 2160 + StudioImplementation* studio = data; 2161 + studio->anim.movie = resetMovie(&studio->anim.wait); 2162 + } 2163 + 2164 + static void setPopupHide(void* data) 2165 + { 2166 + StudioImplementation* studio = data; 2167 + studio->anim.movie = resetMovie(&studio->anim.hide); 2168 + } 2169 + 2170 + #endif 2171 + 2006 2172 Studio* studioInit(s32 argc, char **argv, s32 samplerate, const char* folder) 2007 2173 { 2008 2174 setbuf(stdout, NULL); ··· 2059 2225 impl.console = calloc(1, sizeof(Console)); 2060 2226 impl.world = calloc(1, sizeof(World)); 2061 2227 impl.surf = calloc(1, sizeof(Surf)); 2228 + 2229 + impl.anim.show = (Movie)MOVIE_DEF(STUDIO_ANIM_TIME, setPopupWait, 2230 + { 2231 + {-TOOLBAR_SIZE, 0, STUDIO_ANIM_TIME, &impl.anim.pos.popup, AnimEaseIn}, 2232 + }); 2233 + 2234 + impl.anim.wait = (Movie){.time = TIC80_FRAMERATE * 2, .done = setPopupHide}; 2235 + impl.anim.hide = (Movie)MOVIE_DEF(STUDIO_ANIM_TIME, setIdle, 2236 + { 2237 + {0, -TOOLBAR_SIZE, STUDIO_ANIM_TIME, &impl.anim.pos.popup, AnimEaseIn}, 2238 + }); 2239 + 2240 + impl.anim.movie = resetMovie(&impl.anim.idle); 2062 2241 #endif 2063 2242 2064 2243 impl.start = calloc(1, sizeof(Start));
+37 -1
src/studio/studio.h
··· 48 48 #define STUDIO_TEXT_BUFFER_WIDTH (TIC80_WIDTH / STUDIO_TEXT_WIDTH) 49 49 #define STUDIO_TEXT_BUFFER_HEIGHT (TIC80_HEIGHT / STUDIO_TEXT_HEIGHT) 50 50 #define STUDIO_TEXT_BUFFER_SIZE (STUDIO_TEXT_BUFFER_WIDTH * STUDIO_TEXT_BUFFER_HEIGHT) 51 + #define STUDIO_ANIM_TIME 8 51 52 52 53 #define TIC_COLOR_BG tic_color_black 53 54 ··· 253 254 void tiles2ram(tic_ram* ram, const tic_tiles* src); 254 255 void fadePalette(tic_palette* pal, s32 value); 255 256 257 + typedef enum 258 + { 259 + AnimLinear, 260 + AnimEaseIn, 261 + AnimEaseOut, 262 + AnimEaseInOut, 263 + AnimEaseInCubic, 264 + AnimEaseOutCubic, 265 + AnimEaseInOutCubic, 266 + AnimEaseInQuart, 267 + AnimEaseOutQuart, 268 + AnimEaseInOutQuart, 269 + AnimEaseInQuint, 270 + AnimEaseOutQuint, 271 + AnimEaseInOutQuint, 272 + AnimEaseInSine, 273 + AnimEaseOutSine, 274 + AnimEaseInOutSine, 275 + AnimEaseInExpo, 276 + AnimEaseOutExpo, 277 + AnimEaseInOutExpo, 278 + AnimEaseInCirc, 279 + AnimEaseOutCirc, 280 + AnimEaseInOutCirc, 281 + AnimEaseInBack, 282 + AnimEaseOutBack, 283 + AnimEaseInOutBack, 284 + AnimEaseInElastic, 285 + AnimEaseOutElastic, 286 + AnimEaseInOutElastic, 287 + AnimEaseInBounce, 288 + AnimEaseOutBounce, 289 + AnimEaseInOutBounce, 290 + } AnimEffect; 291 + 256 292 typedef struct 257 293 { 258 294 s32 start; ··· 261 297 262 298 s32 *value; 263 299 264 - s32(*factor)(s32 d); 300 + AnimEffect effect; 265 301 } Anim; 266 302 267 303 typedef struct
+16 -1
src/studio/studio_impl.h
··· 140 140 141 141 struct 142 142 { 143 - s32 counter; 143 + struct 144 + { 145 + s32 popup; 146 + } pos; 147 + 148 + Movie* movie; 149 + 150 + Movie idle; 151 + Movie show; 152 + Movie wait; 153 + Movie hide; 154 + 155 + } anim; 156 + 157 + struct 158 + { 144 159 char message[STUDIO_TEXT_BUFFER_WIDTH]; 145 160 } popup; 146 161