From 980a0b5c3d7245d29a74edc16253bfed14b72f0d Mon Sep 17 00:00:00 2001 From: flarn2006 Date: Tue, 13 Apr 2021 21:50:07 -0400 Subject: [PATCH 1/5] Change struct sprite::flags to an unsigned int --- src/sprite_struct.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sprite_struct.h b/src/sprite_struct.h index 3ec05f557..bb6d809f6 100644 --- a/src/sprite_struct.h +++ b/src/sprite_struct.h @@ -33,7 +33,7 @@ struct sprite int ref_x; int ref_y; char color; - char flags; + unsigned int flags; unsigned int width; unsigned int height; signed int col_x; From cd99bdc2ab05d8ed418486c9c8415e95d4ad5bbc Mon Sep 17 00:00:00 2001 From: flarn2006 Date: Tue, 13 Apr 2021 21:50:20 -0400 Subject: [PATCH 2/5] add SPRn_AUTOOFF --- src/counter.c | 11 +++++++++++ src/sprite.h | 1 + src/world.c | 13 +++++++++++++ 3 files changed, 25 insertions(+) diff --git a/src/counter.c b/src/counter.c index 04b886ad6..704d12193 100644 --- a/src/counter.c +++ b/src/counter.c @@ -955,6 +955,16 @@ static void spr_unbound_write(struct world *mzx_world, } } +static void spr_autooff_write(struct world *mzx_world, + const struct function_counter *counter, const char *name, int value, int id) +{ + int spr_num = strtol(name + 3, NULL, 10) & (MAX_SPRITES - 1); + if(value) + (mzx_world->sprite_list[spr_num])->flags |= SPRITE_AUTO_OFF; + else + (mzx_world->sprite_list[spr_num])->flags &= ~SPRITE_AUTO_OFF; +} + static void spr_height_write(struct world *mzx_world, const struct function_counter *counter, const char *name, int value, int id) { @@ -2730,6 +2740,7 @@ static const struct function_counter builtin_counters[] = { "smzx_palette", V269, smzx_palette_read, NULL }, { "smzx_r!", V269, smzx_r_read, smzx_r_write }, { "spacelock", V284, NULL, spacelock_write }, + { "spr!_autooff", V292, NULL, spr_autooff_write }, { "spr!_ccheck", V265, NULL, spr_ccheck_write }, { "spr!_cheight", V265, spr_cheight_read, spr_cheight_write }, { "spr!_clist", V265, NULL, spr_clist_write }, diff --git a/src/sprite.h b/src/sprite.h index 7223401c5..030972766 100644 --- a/src/sprite.h +++ b/src/sprite.h @@ -37,6 +37,7 @@ enum SPRITE_CHAR_CHECK2 = (1 << 5), // CHAR_CHECK flag 2 (see below) SPRITE_VLAYER = (1 << 6), // References the vlayer SPRITE_UNBOUND = (1 << 7), // Uses pixel positioning and collision + SPRITE_AUTO_OFF = (1 << 8), // Turn off sprite when switching to a new board // Internal flag combination for pixel collision. SPRITE_PIXCHECK = SPRITE_UNBOUND | SPRITE_CHAR_CHECK | SPRITE_CHAR_CHECK2, diff --git a/src/world.c b/src/world.c index 6eee4efb3..1e6cfea00 100644 --- a/src/world.c +++ b/src/world.c @@ -3209,6 +3209,7 @@ static void v1_load_globals_from_board(struct world *mzx_world) void change_board(struct world *mzx_world, int board_id) { + int i; // Set the current board during gameplay. struct board *cur_board = mzx_world->current_board; @@ -3231,6 +3232,18 @@ void change_board(struct world *mzx_world, int board_id) cur_board = mzx_world->current_board; + // Turn off any sprites that have the SPRITE_AUTO_OFF flag set + for (i=0; isprite_list[i]; + if (spr->flags & SPRITE_AUTO_OFF) + { + if (spr->flags & SPRITE_INITIALIZED) + --mzx_world->active_sprites; + spr->flags &= ~(SPRITE_INITIALIZED | SPRITE_AUTO_OFF); + } + } + // Does this board need a duplicate? (2.90+) if(mzx_world->version >= V290 && cur_board->reset_on_entry) { From 95bc8c5b730890dc04caa2edba1dbdc141facbaa Mon Sep 17 00:00:00 2001 From: flarn2006 Date: Wed, 14 Apr 2021 09:34:16 -0400 Subject: [PATCH 3/5] Don't clear SPR_AUTO_OFF when it takes effect --- src/world.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/world.c b/src/world.c index 1e6cfea00..4a1e64e5b 100644 --- a/src/world.c +++ b/src/world.c @@ -3236,11 +3236,10 @@ void change_board(struct world *mzx_world, int board_id) for (i=0; isprite_list[i]; - if (spr->flags & SPRITE_AUTO_OFF) + if (spr->flags & SPRITE_AUTO_OFF && spr->flags & SPRITE_INITIALIZED) { - if (spr->flags & SPRITE_INITIALIZED) - --mzx_world->active_sprites; - spr->flags &= ~(SPRITE_INITIALIZED | SPRITE_AUTO_OFF); + --mzx_world->active_sprites; + spr->flags &= ~SPRITE_INITIALIZED; } } From 0e43627eba4fdc9c473b0c5b222b313b9060c394 Mon Sep 17 00:00:00 2001 From: flarn2006 Date: Wed, 14 Apr 2021 09:36:49 -0400 Subject: [PATCH 4/5] Add SPRn_AUTOOFF to counter_list.txt --- docs/counter_list.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/counter_list.txt b/docs/counter_list.txt index 60938e1f9..2b5a02ef7 100644 --- a/docs/counter_list.txt +++ b/docs/counter_list.txt @@ -132,6 +132,7 @@ name r/w g/n/f/b i "SPR_COLLISIONS" r b * "SPR_NUM" r w b * "SPR_YORDER" w f * +"SPRn_AUTOOFF" w f * "SPRn_CCHECK" w f * "SPRn_CHEIGHT" r w b * "SPRn_CLIST" w f * From afe8d1c2ff192b5350bfb949562dcc774d691b89 Mon Sep 17 00:00:00 2001 From: AliceLR Date: Thu, 21 Dec 2023 19:37:17 -0700 Subject: [PATCH 5/5] Rename to SPRn_OFFONEXIT, add test, other tweaks. --- docs/changelog.txt | 4 ++++ docs/counter_list.txt | 8 +++++-- docs/fileform.html | 3 ++- src/counter.c | 32 ++++++++++++++++--------- src/editor/debug.c | 1 + src/game_update.c | 16 +++++++++++-- src/sprite.h | 2 +- src/world.c | 12 ---------- testworlds/2.93/011 SPRn_OFFONEXIT.mzx | Bin 0 -> 4718 bytes 9 files changed, 49 insertions(+), 29 deletions(-) create mode 100644 testworlds/2.93/011 SPRn_OFFONEXIT.mzx diff --git a/docs/changelog.txt b/docs/changelog.txt index 9a0ca15e7..65dabdd75 100644 --- a/docs/changelog.txt +++ b/docs/changelog.txt @@ -23,6 +23,10 @@ USERS + Added new counters VIEWPORT_X, VIEWPORT_Y, VIEWPORT_WIDTH, and VIEWPORT_HEIGHT to read the current board's viewport settings. (Sparkette) ++ Added a new counter SPRn_OFFONEXIT. When enabled for a sprite, + that sprite will be automatically turned off when exiting the + board (same as setting SPRn_OFF). This occurs even if the new + board and the previous board are the same. (Sparkette) + Added an "About MegaZeux" dialog, accessible from the main menu. This menu contains extended version information, and displays license information for MegaZeux and the 3rd party diff --git a/docs/counter_list.txt b/docs/counter_list.txt index 2b5a02ef7..5b980bc20 100644 --- a/docs/counter_list.txt +++ b/docs/counter_list.txt @@ -132,7 +132,6 @@ name r/w g/n/f/b i "SPR_COLLISIONS" r b * "SPR_NUM" r w b * "SPR_YORDER" w f * -"SPRn_AUTOOFF" w f * "SPRn_CCHECK" w f * "SPRn_CHEIGHT" r w b * "SPRn_CLIST" w f * @@ -140,7 +139,9 @@ name r/w g/n/f/b i "SPRn_CX" r w b * "SPRn_CY" r w b * "SPRn_HEIGHT" r w b * -"SPRn_OFF" w f * +"SPRn_OFF" r w f * +"SPRn_OFFONEXIT" r w f * +"SPRn_OFFSET" r w b * "SPRn_OVERLAID" w f * "SPRn_OVERLAY" w f * "SPRn_REFX" r w b * @@ -148,10 +149,13 @@ name r/w g/n/f/b i "SPRn_SETVIEW" w f * "SPRn_STATIC" w b * "SPRn_SWAP" w f * +"SPRn_TCOL" r w b * +"SPRn_UNBOUND" r w f * "SPRn_VLAYER" w f * "SPRn_WIDTH" r w b * "SPRn_X" r w b * "SPRn_Y" r w b * +"SPRn_Z" r w b * "SQRTn" r f * "TAN" r f * "THISX" r b * diff --git a/docs/fileform.html b/docs/fileform.html index 630d4cca4..69d779c72 100644 --- a/docs/fileform.html +++ b/docs/fileform.html @@ -2687,7 +2687,7 @@

Sprite Properties (.SAV only)

| `0x0004` | Sprite reference X | int(ds) | Each sprite | `0x0005` | Sprite reference Y | int(ds) | Each sprite | `0x0006` | Sprite color | int(b) | Each sprite -| `0x0007` | Sprite flags | int(b) | Each sprite(2) +| `0x0007` | Sprite flags | int(d) | Each sprite(2) | `0x0008` | Sprite width | int(d) | Each sprite | `0x0009` | Sprite height | int(d) | Each sprite | `0x000A` | Sprite collision X | int(ds) | Each sprite @@ -2724,6 +2724,7 @@

Sprite Properties (.SAV only)

| `0x20` | Sprite ccheck 2 is enabled | `0x40` | Sprite references the vlayer | `0x80` | Sprite is unbound +| `0x100`| Sprite off-on-exit is enabled For unbound sprites, if both the ccheck 1 and ccheck 2 flags are set, sprite ccheck 3 is enabled instead. diff --git a/src/counter.c b/src/counter.c index 704d12193..434f993b8 100644 --- a/src/counter.c +++ b/src/counter.c @@ -828,6 +828,16 @@ static int spr_off_read(struct world *mzx_world, return 0; } +static int spr_offonexit_read(struct world *mzx_world, + const struct function_counter *counter, const char *name, int id) +{ + int spr_num = strtol(name + 3, NULL, 10) & (MAX_SPRITES - 1); + if((mzx_world->sprite_list[spr_num])->flags & SPRITE_OFF_ON_EXIT) + return 1; + + return 0; +} + static int spr_cwidth_read(struct world *mzx_world, const struct function_counter *counter, const char *name, int id) { @@ -955,16 +965,6 @@ static void spr_unbound_write(struct world *mzx_world, } } -static void spr_autooff_write(struct world *mzx_world, - const struct function_counter *counter, const char *name, int value, int id) -{ - int spr_num = strtol(name + 3, NULL, 10) & (MAX_SPRITES - 1); - if(value) - (mzx_world->sprite_list[spr_num])->flags |= SPRITE_AUTO_OFF; - else - (mzx_world->sprite_list[spr_num])->flags &= ~SPRITE_AUTO_OFF; -} - static void spr_height_write(struct world *mzx_world, const struct function_counter *counter, const char *name, int value, int id) { @@ -1074,6 +1074,16 @@ static void spr_off_write(struct world *mzx_world, } } +static void spr_offonexit_write(struct world *mzx_world, + const struct function_counter *counter, const char *name, int value, int id) +{ + int spr_num = strtol(name + 3, NULL, 10) & (MAX_SPRITES - 1); + if(value) + (mzx_world->sprite_list[spr_num])->flags |= SPRITE_OFF_ON_EXIT; + else + (mzx_world->sprite_list[spr_num])->flags &= ~SPRITE_OFF_ON_EXIT; +} + static void spr_swap_write(struct world *mzx_world, const struct function_counter *counter, const char *name, int value, int id) { @@ -2740,7 +2750,6 @@ static const struct function_counter builtin_counters[] = { "smzx_palette", V269, smzx_palette_read, NULL }, { "smzx_r!", V269, smzx_r_read, smzx_r_write }, { "spacelock", V284, NULL, spacelock_write }, - { "spr!_autooff", V292, NULL, spr_autooff_write }, { "spr!_ccheck", V265, NULL, spr_ccheck_write }, { "spr!_cheight", V265, spr_cheight_read, spr_cheight_write }, { "spr!_clist", V265, NULL, spr_clist_write }, @@ -2749,6 +2758,7 @@ static const struct function_counter builtin_counters[] = { "spr!_cy", V265, spr_cy_read, spr_cy_write }, { "spr!_height", V265, spr_height_read, spr_height_write }, { "spr!_off", V265, spr_off_read, spr_off_write }, + { "spr!_offonexit", V293, spr_offonexit_read, spr_offonexit_write }, { "spr!_offset", V290, spr_offset_read, spr_offset_write }, { "spr!_overlaid", V265, NULL, spr_overlaid_write }, { "spr!_overlay", V269c, NULL, spr_overlaid_write }, diff --git a/src/editor/debug.c b/src/editor/debug.c index 29c414d47..d64786387 100644 --- a/src/editor/debug.c +++ b/src/editor/debug.c @@ -446,6 +446,7 @@ static const char *sprite_var_list[] = "cheight", "ccheck", // no read "off", + "offonexit", "offset", "overlay", // no read "static", // no read diff --git a/src/game_update.c b/src/game_update.c index 974e948c8..8e9b762f1 100644 --- a/src/game_update.c +++ b/src/game_update.c @@ -952,6 +952,7 @@ boolean update_resolve_target(struct world *mzx_world, char *level_id = src_board->level_id; char *level_color = src_board->level_color; char *level_under_id = src_board->level_under_id; + int i; if(mzx_world->target_where != TARGET_NONE) { @@ -961,8 +962,8 @@ boolean update_resolve_target(struct world *mzx_world, boolean load_assets = false; // TELEPORT or ENTRANCE. - // Destroy message, bullets, spitfire? + // Destroy message, bullets, spitfire? if(mzx_world->clear_on_exit) { int offset; @@ -977,6 +978,18 @@ boolean update_resolve_target(struct world *mzx_world, } } + // Sprites can also optionally be disabled on exit. + for(i = 0; i < MAX_SPRITES; i++) + { + struct sprite *spr = mzx_world->sprite_list[i]; + + if((spr->flags & SPRITE_INITIALIZED) && (spr->flags & SPRITE_OFF_ON_EXIT)) + { + spr->flags &= ~SPRITE_INITIALIZED; + mzx_world->active_sprites--; + } + } + // Load board mzx_world->under_player_id = (char)SPACE; mzx_world->under_player_param = 0; @@ -1003,7 +1016,6 @@ boolean update_resolve_target(struct world *mzx_world, // Find target x/y if(mzx_world->target_where == TARGET_ENTRANCE) { - int i; int tmp_x[5]; int tmp_y[5]; int x, y, offset; diff --git a/src/sprite.h b/src/sprite.h index 030972766..4f2616f64 100644 --- a/src/sprite.h +++ b/src/sprite.h @@ -37,7 +37,7 @@ enum SPRITE_CHAR_CHECK2 = (1 << 5), // CHAR_CHECK flag 2 (see below) SPRITE_VLAYER = (1 << 6), // References the vlayer SPRITE_UNBOUND = (1 << 7), // Uses pixel positioning and collision - SPRITE_AUTO_OFF = (1 << 8), // Turn off sprite when switching to a new board + SPRITE_OFF_ON_EXIT = (1 << 8), // Turn off sprite when switching boards // Internal flag combination for pixel collision. SPRITE_PIXCHECK = SPRITE_UNBOUND | SPRITE_CHAR_CHECK | SPRITE_CHAR_CHECK2, diff --git a/src/world.c b/src/world.c index 4a1e64e5b..6eee4efb3 100644 --- a/src/world.c +++ b/src/world.c @@ -3209,7 +3209,6 @@ static void v1_load_globals_from_board(struct world *mzx_world) void change_board(struct world *mzx_world, int board_id) { - int i; // Set the current board during gameplay. struct board *cur_board = mzx_world->current_board; @@ -3232,17 +3231,6 @@ void change_board(struct world *mzx_world, int board_id) cur_board = mzx_world->current_board; - // Turn off any sprites that have the SPRITE_AUTO_OFF flag set - for (i=0; isprite_list[i]; - if (spr->flags & SPRITE_AUTO_OFF && spr->flags & SPRITE_INITIALIZED) - { - --mzx_world->active_sprites; - spr->flags &= ~SPRITE_INITIALIZED; - } - } - // Does this board need a duplicate? (2.90+) if(mzx_world->version >= V290 && cur_board->reset_on_entry) { diff --git a/testworlds/2.93/011 SPRn_OFFONEXIT.mzx b/testworlds/2.93/011 SPRn_OFFONEXIT.mzx new file mode 100644 index 0000000000000000000000000000000000000000..5c3f3819267e8d68ff4db785ee36a209f835748a GIT binary patch literal 4718 zcmb_f3s_S}7M?&LkWdp93@uQvfXF*R@v+K7P_(WJEa0OG=1WK*!AKwpM1cxwt6QPg zw^dLoD5xj`5quy@HC9v}pSq&r14V@@f}c+otYl~I4I6TS`tA4a?69A4L^9TMzGzf0_19Yp^YE5<1Ma|vwCp5oZxYT{-%$d5HE46iJD^J&5y;hI? z`AJ(+T9$vH=*Zzig#`yG=Ee*r!`S>){XD8h&Cx`vIqFCahZ6}KhojaQ{`%%UmaSg4 zFqxMe<>KeE)Y->*nP0Nc*P~g((L&d1)@d@-Yt*G>WpMpeQ;T61rr9}r_dzWTTlUYJ znXVSYI3AH{jA3*OsF=BB>$dHE-3T_D;kZA|MgU{DBqozN5@f)^&`sFy6^h`1MhA40 z{x9fo0(SIAG&CH5B28H1(S`vgtQ&(9V2=~613?^hJY#j#37@8n(>*%ts0&VMFvMsh zMFTgS3V}OLYk&tK+mj$1f^aj?E(2Z}2txtmb#y`o6@NzW3^%qg`lxmsoJAdBV&%91 zI7ZZn*u`2c6@Ll0AVJ})J~3wa`N%495oe-E+#t?Jw3shfbTs;A+RV1DeqF~O#m>xA zE;Vc0Xz6+KjLikXHHrX-lwff z^1fX3Ou^oJFn@OIb!T733XeBFytG>n)8=2BT`yVxarc!@Rdj<}_}=q{^)n<-FIs0^ z4s;d;3b&6C_?$~kuDrRbCH8oG&xU2eO&dEqdcso5Bc3yk1s1yPeHL`=K||o*z3vs? zR!?%?nD=5qY5tN`t@a<&-8g|2p4nx7N!vJY9zSfV`{#_2+s=;7@}0Y)%GGvp-n*g) z{Nv?sW@zre64#vG-=uN&xapl$>vS+O+dcJB+Y--RC!>NRCfz74NL+9<^wP3d@{W*9 z@4D8iVU=Tls7bF+5}b7Ssp#8N>6MM zEGnYWt#adns55^!x9{}nnfR}eeRa9Mhv##S9BIGVmVBo7dQe40c6CE&kBxWN#L=fN zMjrnZ*Hyk<;nH4}SzNR*CqTQRwxB4li>6Ms%1<`mX<0ZiqI6fX|NEH2vVZJSx8J!O zIkxQ7+ssRxs(R(GDO)U`cs5D1wvO2vc*5hu7|Yu!x`36?Kd@b<$m5w$K=k?SYUlO~?tHur7U zDna9irB`#CYl>syn)6FWc0!|eK;M3M?H={tqkB3Fd)wQZdyf0B?l}Kun(f<%x%Rn_ z^OC+{vQ-JjwV3Lg=I$N6ewPDsn>Q5s#hE%}Kd$+0XLb6R`zGs_C(^RlY__=mzWSu`MdqXCu0}gMZKt-? zy=qrg+NYGMzS@;vJWG4u2v5`hrDbs5F#Ap`k3jmQizzE{qNSwf2kDF&jkWmC- z;{;d}kp;9w7SNKj0MZ8xlK{Mi@mXhrxDW)!12#AO z-yNT#5SKsXHS}Ri@7oY`)1z(*JM^JIB1}&s^SPC;$H;sMawOVN-pn`MVlp2LEo_E- zw#_rgkob}$LS*pg`Jmnbe1qss8cgq@@z>cTy|QRA2AiSYLFCB>lgC}Ygkc1W0MvE< zlXJcBkiZ>;s4gQ?po`JAgXI@^04>nk(`k-MiBc*8)_NnN4G>45aq|q(fhm*Z@o)!1XwL#YHg&{ODvY&);2A=C@C3}i~#U6j*Im}si z7Ib^x1x)#jD}D5Wy*}g0fx>-0@7oc2`Ls~JLLm}@5&gDXXh3*4U_uAe;)vMNhSB?N zJqj2`JnJ?Se71<8JLz_`6CN5H7K6u&mc=V2@kt`wXB0r=@f0e40EqZ_tTs16W$N+K`qX#U*0b(+MT-4|R84v)|GZ{e6;Cg_@tS_IF zG30En$Gp^G68gE9@D({D>M@q)gr0$`Cuey*#)rVboKLoGXpB&Y`Cn|y(qRVLMy>?( xww)j_ur46mHnb1!_hAO?0CI((*F#0=i_3-eLg-u*R6GC{{CUF7>dHh<{{g83wkiMs literal 0 HcmV?d00001