From 4e43b99dc289d2b2653a53b9f4c66c3f20862b62 Mon Sep 17 00:00:00 2001 From: idle Date: Fri, 10 Jul 2026 21:02:23 -0500 Subject: [PATCH 1/6] Sprite features now has option to show hitboxes in blue or white color --- src/defines.asm | 12 +++ src/main.asm | 2 +- src/mainmenu.asm | 73 ++++++++++++++ src/spritefeat.asm | 223 +++++++++++++++++++++++++---------------- src/symbols.asm | 4 + web/data/changelog.mdx | 1 + web/data/config.json | 2 +- 7 files changed, 231 insertions(+), 86 deletions(-) diff --git a/src/defines.asm b/src/defines.asm index 2d360864..e2ab59ee 100644 --- a/src/defines.asm +++ b/src/defines.asm @@ -352,6 +352,10 @@ !ram_cm_sprites_spacetime = !WRAM_MENU_START+$90 !ram_cm_sprites_xray = !WRAM_MENU_START+$92 +!ram_cm_sprites_samus_hitbox = !WRAM_MENU_START+$94 +!ram_cm_sprites_samus_proj = !WRAM_MENU_START+$96 +!ram_cm_sprites_enemy_hitbox = !WRAM_MENU_START+$98 +!ram_cm_sprites_enemy_proj = !WRAM_MENU_START+$9A !ram_cm_ctrl_add_shortcut_slot = !WRAM_MENU_START+$90 !ram_cm_ctrl_last_pri = !WRAM_MENU_START+$92 @@ -1384,6 +1388,14 @@ endif !SPRITE_HUD_XRAY = #$0200 !SPRITE_HUD_XRAY_INVERTED = #$FDFF !SPRITE_OOB_X_WRAP = #$0400 +!SPRITE_SAMUS_HITBOX_WHITE = #$1000 +!SPRITE_SAMUS_HITBOX_INVERTED = #$EFFF +!SPRITE_SAMUS_PROJ_WHITE = #$2000 +!SPRITE_SAMUS_PROJ_INVERTED = #$DFFF +!SPRITE_ENEMY_HITBOX_WHITE = #$4000 +!SPRITE_ENEMY_HITBOX_INVERTED = #$BFFF +!SPRITE_ENEMY_PROJ_WHITE = #$8000 +!SPRITE_ENEMY_PROJ_INVERTED = #$7FFF !UPDATE_TIMERS_CTRL_SHORTCUT_TYPE = $05 diff --git a/src/main.asm b/src/main.asm index f304dfad..02533b4b 100644 --- a/src/main.asm +++ b/src/main.asm @@ -17,7 +17,7 @@ lorom !VERSION_MAJOR = 2 !VERSION_MINOR = 7 !VERSION_BUILD = 7 -!VERSION_REV = 1 +!VERSION_REV = 2 table ../resources/normal.tbl print "" diff --git a/src/mainmenu.asm b/src/mainmenu.asm index 543a0370..c0f7e476 100644 --- a/src/mainmenu.asm +++ b/src/mainmenu.asm @@ -142,6 +142,14 @@ if !PRESERVE_WRAM LDA !ram_sprite_feature_flags : AND !SPRITE_HUD_XRAY XBA : LSR : STA !ram_cm_sprites_xray endif + LDA !ram_sprite_feature_flags : AND !SPRITE_SAMUS_HITBOX_WHITE + XBA : LSR #4 : STA !ram_cm_sprites_samus_hitbox + LDA !ram_sprite_feature_flags : AND !SPRITE_SAMUS_PROJ_WHITE + XBA : ASL #3 : XBA : STA !ram_cm_sprites_samus_proj + LDA !ram_sprite_feature_flags : AND !SPRITE_ENEMY_HITBOX_WHITE + XBA : ASL #2 : XBA : STA !ram_cm_sprites_enemy_hitbox + LDA !ram_sprite_feature_flags : AND !SPRITE_ENEMY_PROJ_WHITE + XBA : ASL : XBA : STA !ram_cm_sprites_enemy_proj JMP action_mainmenu } @@ -1830,6 +1838,11 @@ SpritesMenu: dw #sprites_show_samusproj_hitbox dw #sprites_show_enemyproj_hitbox dw #sprites_show_proj_as_32x32 + dw #$FFFF + dw #sprites_samus_hitbox_color + dw #sprites_samus_proj_color + dw #sprites_enemy_hitbox_color + dw #sprites_enemy_proj_color if !PRESERVE_WRAM dw #$FFFF dw #sprites_hud_spacetime @@ -1865,6 +1878,66 @@ sprites_show_enemyproj_hitbox: sprites_show_proj_as_32x32: %cm_toggle_bit("32x32 Projectile Boxes", !ram_sprite_feature_flags, !SPRITE_32x32_PROJ, #0) +sprites_samus_hitbox_color: + dw !ACTION_CHOICE + dl #!ram_cm_sprites_samus_hitbox + dw #.routine + db #$28, "Samus Hitbox Co", #$FF + db #$28, "lor BLUE", #$FF + db #$28, "lor WHITE", #$FF + db #$FF + .routine + LDA !ram_sprite_feature_flags : AND !SPRITE_SAMUS_HITBOX_INVERTED + STA !ram_sprite_feature_flags + LDA !ram_cm_sprites_samus_hitbox : XBA : ASL #4 + ORA !ram_sprite_feature_flags : STA !ram_sprite_feature_flags + RTL + +sprites_samus_proj_color: + dw !ACTION_CHOICE + dl #!ram_cm_sprites_samus_proj + dw #.routine + db #$28, "Samus Projectil", #$FF + db #$28, "e BLUE", #$FF + db #$28, "e WHITE", #$FF + db #$FF + .routine + LDA !ram_sprite_feature_flags : AND !SPRITE_SAMUS_PROJ_INVERTED + STA !ram_sprite_feature_flags + LDA !ram_cm_sprites_samus_proj : XBA : LSR #3 : XBA + ORA !ram_sprite_feature_flags : STA !ram_sprite_feature_flags + RTL + +sprites_enemy_hitbox_color: + dw !ACTION_CHOICE + dl #!ram_cm_sprites_enemy_hitbox + dw #.routine + db #$28, "Enemy Hitbox Co", #$FF + db #$28, "lor BLUE", #$FF + db #$28, "lor WHITE", #$FF + db #$FF + .routine + LDA !ram_sprite_feature_flags : AND !SPRITE_ENEMY_HITBOX_INVERTED + STA !ram_sprite_feature_flags + LDA !ram_cm_sprites_enemy_hitbox : XBA : LSR #2 : XBA + ORA !ram_sprite_feature_flags : STA !ram_sprite_feature_flags + RTL + +sprites_enemy_proj_color: + dw !ACTION_CHOICE + dl #!ram_cm_sprites_enemy_proj + dw #.routine + db #$28, "Enemy Projectil", #$FF + db #$28, "e BLUE", #$FF + db #$28, "e WHITE", #$FF + db #$FF + .routine + LDA !ram_sprite_feature_flags : AND !SPRITE_ENEMY_PROJ_INVERTED + STA !ram_sprite_feature_flags + LDA !ram_cm_sprites_enemy_proj : XBA : LSR : XBA + ORA !ram_sprite_feature_flags : STA !ram_sprite_feature_flags + RTL + if !PRESERVE_WRAM sprites_hud_spacetime: dw !ACTION_CHOICE diff --git a/src/spritefeat.asm b/src/spritefeat.asm index 927d3462..8edd8025 100644 --- a/src/spritefeat.asm +++ b/src/spritefeat.asm @@ -1,5 +1,8 @@ ; ; Features using sprites to draw information +; Sprite Attributes - xxxxxxxx yyyyyyyy tttttttt YXPPpppt +; x=X pos, y=Y pos, Y=Y flip, X=X flip +; P=Priority, p=Palette, t=Tile number ; @@ -191,11 +194,8 @@ draw_sprite_oob: LDA $C3 : CLC : ADC #$04 : ASL #4 : SEC : SBC $C7 STA !OAM_LOW+$1,Y - ; Sprite Attributes - xxxxxxxx yyyyyyyy YXPPpppt tttttttt - ; x=X pos, y=Y pos (low nibbles only), Y=Y flip, X=X flip - ; P=Priority, p=Palette, t=Tile number - ; Priority bits set, palette = 101 - LDA #%00111010 : STA !OAM_LOW+$3,Y + ; Sprite attributes + LDA #$3A : STA !OAM_LOW+$3,Y %a16() @@ -259,8 +259,7 @@ draw_sprite_oob: %a16() .end - JSR draw_oob_samus_hitbox - RTS + JMP draw_oob_samus_hitbox } draw_sprite_x_wrap: @@ -359,11 +358,8 @@ draw_sprite_x_wrap: LDA $C3 : CLC : ADC #$04 : ASL #4 : SEC : SBC $C7 STA !OAM_LOW+$1,Y - ; Sprite Attributes - xxxxxxxx yyyyyyyy YXPPpppt tttttttt - ; x=X pos, y=Y pos (low nibbles only), Y=Y flip, X=X flip - ; P=Priority, p=Palette, t=Tile number - ; Priority bits set, palette = 101 - LDA #%00111010 : STA !OAM_LOW+$3,Y + ; Sprite Attributes + LDA #$3A : STA !OAM_LOW+$3,Y %a16() @@ -506,8 +502,7 @@ draw_samus_hitbox: { LDA !SAMUS_Y : SEC : SBC !LAYER1_Y : PHA ; Y coord LDA !SAMUS_X : SEC : SBC !LAYER1_X : PHA ; X coord - - LDA #$0000 + TDC %a8() LDY !OAM_STACK_POINTER ; X coord @@ -524,19 +519,25 @@ draw_samus_hitbox: STA !OAM_LOW+$9,Y : STA !OAM_LOW+$D,Y PLA ; discard high byte - ; Sprite Attributes - xxxxxxxx yyyyyyyy YXPPpppt tttttttt - ; x=X pos, y=Y pos, Y=Y flip, X=X flip - ; P=Priority, p=Palette, t=Tile number - LDA #%00111010 : STA !OAM_LOW+$3,Y ; top left - LDA #%01111010 : STA !OAM_LOW+$7,Y ; top right - LDA #%10111010 : STA !OAM_LOW+$B,Y ; bottom left - LDA #%11111010 : STA !OAM_LOW+$F,Y ; bottom right + ; Sprite Attributes + %a16() + LDA !ram_sprite_feature_flags : BIT !SPRITE_SAMUS_HITBOX_WHITE : BEQ .blue + LDA #$3047 : STA !OAM_LOW+$2,Y ; top left + ORA #$4000 : STA !OAM_LOW+$6,Y ; top right + ORA #$8000 : STA !OAM_LOW+$E,Y ; bottom right + AND #$BFFF : STA !OAM_LOW+$A,Y ; bottom left + + ; inc oam stack + TYA : CLC : ADC #$0010 : STA !OAM_STACK_POINTER + RTS - LDA #$47 ; tile number (8/9 bits) - STA !OAM_LOW+$2,Y : STA !OAM_LOW+$6,Y - STA !OAM_LOW+$A,Y : STA !OAM_LOW+$E,Y + .blue + LDA #$3A47 : STA !OAM_LOW+$2,Y ; top left + ORA #$4000 : STA !OAM_LOW+$6,Y ; top right + ORA #$8000 : STA !OAM_LOW+$E,Y ; bottom right + AND #$BFFF : STA !OAM_LOW+$A,Y ; bottom left - %a16() + ; inc oam stack TYA : CLC : ADC #$0010 : STA !OAM_STACK_POINTER RTS } @@ -544,6 +545,14 @@ draw_samus_hitbox: ; draw hitboxes around first 12 enemies draw_enemy_hitbox: { + LDA !ram_sprite_feature_flags : BIT !SPRITE_ENEMY_HITBOX_WHITE : BEQ .blue + LDA #$0047 : STA $CB + BRA .start + + .blue + LDA #$0A47 : STA $CB + + .start LDX #$0000 ; X = enemy index LDY !OAM_STACK_POINTER ; Y = OAM stack pointer @@ -593,14 +602,13 @@ draw_enemy_hitbox: STA !OAM_LOW+$9,Y : STA !OAM_LOW+$D,Y PLA ; discard high byte - ; Sprite Attributes - xxxxxxxx yyyyyyyy YXPPpppt tttttttt - ; x=X pos, y=Y pos (low nibbles only), Y=Y flip, X=X flip - ; P=Priority, p=Palette, t=Tile number - %ai16() - LDA #$3A47 : STA !OAM_LOW+$2,Y ; %00111010 top-left - LDA #$7A47 : STA !OAM_LOW+$6,Y ; %01111010 top-right - LDA #$BA47 : STA !OAM_LOW+$A,Y ; %10111010 bottom-left - LDA #$FA47 : STA !OAM_LOW+$E,Y ; %11111010 bottom-right + ; Sprite Attributes + %a16() + LDA $CB + ORA #$3000 : STA !OAM_LOW+$2,Y ; top left + ORA #$4000 : STA !OAM_LOW+$6,Y ; top right + ORA #$8000 : STA !OAM_LOW+$E,Y ; bottom right + AND #$BFFF : STA !OAM_LOW+$A,Y ; bottom left ; inc oam stack TYA : CLC : ADC #$0010 : STA !OAM_STACK_POINTER : TAY @@ -616,6 +624,14 @@ draw_enemy_hitbox: ; draw hitboxes around enemies that use extended spritemaps draw_ext_spritemap_hitbox: { + LDA !ram_sprite_feature_flags : BIT !SPRITE_ENEMY_HITBOX_WHITE : BEQ .blue + LDA #$0047 : STA $CB + BRA .start + + .blue + LDA #$0A47 : STA $CB + + .start LDX #$0000 ; X = enemy index LDY !OAM_STACK_POINTER ; Y = OAM stack pointer @@ -710,14 +726,13 @@ draw_ext_spritemap_hitbox: LDA $1C : CLC : ADC $1A : SEC : SBC #$08 STA !OAM_LOW+$9,Y : STA !OAM_LOW+$D,Y - ; Sprite Attributes - xxxxxxxx yyyyyyyy YXPPpppt tttttttt - ; x=X pos, y=Y pos, Y=Y flip, X=X flip - ; P=Priority, p=Palette, t=Tile number - %ai16() - LDA #$3A47 : STA !OAM_LOW+$2,Y ; %00111010 top-left - LDA #$7A47 : STA !OAM_LOW+$6,Y ; %01111010 top-right - LDA #$BA47 : STA !OAM_LOW+$A,Y ; %10111010 bottom-left - LDA #$FA47 : STA !OAM_LOW+$E,Y ; %11111010 bottom-right + ; Sprite Attributes + %a16() + LDA $CB + ORA #$3000 : STA !OAM_LOW+$2,Y ; top left + ORA #$4000 : STA !OAM_LOW+$6,Y ; top right + ORA #$8000 : STA !OAM_LOW+$E,Y ; bottom right + AND #$BFFF : STA !OAM_LOW+$A,Y ; bottom left ; inc oam stack TYA : CLC : ADC #$0010 : STA !OAM_STACK_POINTER : TAY @@ -754,6 +769,14 @@ draw_enemyproj_hitbox: ; 5 would be ideal, but 7 works better with MB ketchup beam !min_four_corners_radius = #$0007 + LDA !ram_sprite_feature_flags : BIT !SPRITE_ENEMY_PROJ_WHITE : BEQ .blue + LDA #$0047 : STA $CB + BRA .start + + .blue + LDA #$0A47 : STA $CB + + .start LDX #$FFFE : STX $12 : STX $14 ; X = projectile index LDY !OAM_STACK_POINTER ; Y = OAM stack pointer @@ -807,9 +830,11 @@ draw_enemyproj_hitbox: STA !OAM_LOW+$5,Y PLA - %ai16() - LDA #$3A47 : STA !OAM_LOW+$2,Y ; %00111010 top-left - LDA #$FA47 : STA !OAM_LOW+$6,Y ; %11111010 bottom-right + ; Sprite Attributes + %a16() + LDA $CB + ORA #$3000 : STA !OAM_LOW+$2,Y ; top left + ORA #$C000 : STA !OAM_LOW+$6,Y ; bottom right ; inc OAM stack ; vanilla routines use AND #$01FF to wrap the stack after 1FCh @@ -837,14 +862,13 @@ draw_enemyproj_hitbox: PLA ; discard high byte .setAttributes - ; Sprite Attributes - xxxxxxxx yyyyyyyy YXPPpppt tttttttt - ; x=X pos, y=Y pos (low nibbles only), Y=Y flip, X=X flip - ; P=Priority, p=Palette, t=Tile number - %ai16() - LDA #$3A47 : STA !OAM_LOW+$2,Y ; %00111010 top-left - LDA #$7A47 : STA !OAM_LOW+$6,Y ; %01111010 top-right - LDA #$BA47 : STA !OAM_LOW+$A,Y ; %10111010 bottom-left - LDA #$FA47 : STA !OAM_LOW+$E,Y ; %11111010 bottom-right + ; Sprite Attributes + %a16() + LDA $CB + ORA #$3000 : STA !OAM_LOW+$2,Y ; top left + ORA #$4000 : STA !OAM_LOW+$6,Y ; top right + ORA #$8000 : STA !OAM_LOW+$E,Y ; bottom right + AND #$BFFF : STA !OAM_LOW+$A,Y ; bottom left ; inc OAM stack ; vanilla routines use AND #$01FF to wrap the stack after 1FCh @@ -898,6 +922,14 @@ draw_enemyproj_hitbox: ; draw hitboxes around Samus projectiles draw_samusproj_hitbox: { + LDA !ram_sprite_feature_flags : BIT !SPRITE_SAMUS_PROJ_WHITE : BEQ .blue + LDA #$0047 : STA $CB + BRA .start + + .blue + LDA #$0A47 : STA $CB + + .start LDX #$FFFE ; X = projectile index LDY !OAM_STACK_POINTER ; Y = OAM stack pointer @@ -943,14 +975,13 @@ draw_samusproj_hitbox: PLA ; discard high byte .setAttributes - ; Sprite Attributes - xxxxxxxx yyyyyyyy YXPPpppt tttttttt - ; x=X pos, y=Y pos (low nibbles only), Y=Y flip, X=X flip - ; P=Priority, p=Palette, t=Tile number - %ai16() - LDA #$3A47 : STA !OAM_LOW+$2,Y ; %00111010 top-left - LDA #$7A47 : STA !OAM_LOW+$6,Y ; %01111010 top-right - LDA #$BA47 : STA !OAM_LOW+$A,Y ; %10111010 bottom-left - LDA #$FA47 : STA !OAM_LOW+$E,Y ; %11111010 bottom-right + ; Sprite Attributes + %a16() + LDA $CB + ORA #$3000 : STA !OAM_LOW+$2,Y ; top left + ORA #$4000 : STA !OAM_LOW+$6,Y ; top right + ORA #$8000 : STA !OAM_LOW+$E,Y ; bottom right + AND #$BFFF : STA !OAM_LOW+$A,Y ; bottom left ; inc OAM stack ; vanilla routines use AND #$01FF to wrap the stack after 1FCh @@ -1012,7 +1043,14 @@ draw_custom_boss_hitbox: .mother_brain ; check which phase MB is in, 2 = 2nd phase LDA $7E7800 : CMP #$0002 : BMI .end + LDA !ram_sprite_feature_flags : BIT !SPRITE_ENEMY_HITBOX_WHITE : BEQ .mb_blue + LDA #$0047 : STA $CB + BRA .mb_start + + .mb_blue + LDA #$0A47 : STA $CB + .mb_start ; load hitbox enable bitflags LDA $7E7808 : BEQ .end : STA $C1 LDX #$0000 : LDY !OAM_STACK_POINTER ; X = enemy index @@ -1110,14 +1148,23 @@ draw_custom_boss_hitbox: LDA $16 : DEC : STA !OAM_LOW+$1,Y : STA !OAM_LOW+$5,Y LDA $1A : STA !OAM_LOW+$9,Y : STA !OAM_LOW+$D,Y - ; Sprite Attributes - xxxxxxxx yyyyyyyy YXPPpppt tttttttt - ; x=X pos, y=Y pos (low nibbles only), Y=Y flip, X=X flip - ; P=Priority, p=Palette, t=Tile number - %ai16() - LDA #$3A47 : STA !OAM_LOW+$2,Y ; %00111010 top-left - LDA #$7A47 : STA !OAM_LOW+$6,Y ; %01111010 top-right - LDA #$BA47 : STA !OAM_LOW+$A,Y ; %10111010 bottom-left - LDA #$FA47 : STA !OAM_LOW+$E,Y ; %11111010 bottom-right + ; Sprite Attributes + %a16() + LDA !ram_sprite_feature_flags : BIT !SPRITE_ENEMY_HITBOX_WHITE : BEQ .kraid_blue + LDA #$3047 : STA !OAM_LOW+$2,Y ; top left + ORA #$4000 : STA !OAM_LOW+$6,Y ; top right + ORA #$8000 : STA !OAM_LOW+$E,Y ; bottom right + AND #$BFFF : STA !OAM_LOW+$A,Y ; bottom left + + ; inc oam stack + TYA : CLC : ADC #$0010 : STA !OAM_STACK_POINTER + RTS + + .kraid_blue + LDA #$3A47 : STA !OAM_LOW+$2,Y ; top left + ORA #$4000 : STA !OAM_LOW+$6,Y ; top right + ORA #$8000 : STA !OAM_LOW+$E,Y ; bottom right + AND #$BFFF : STA !OAM_LOW+$A,Y ; bottom left ; inc oam stack TYA : CLC : ADC #$0010 : STA !OAM_STACK_POINTER @@ -1159,14 +1206,23 @@ draw_custom_boss_hitbox: STA !OAM_LOW+$9,Y : STA !OAM_LOW+$D,Y PLA ; discard high byte - ; Sprite Attributes - xxxxxxxx yyyyyyyy YXPPpppt tttttttt - ; x=X pos, y=Y pos (low nibbles only), Y=Y flip, X=X flip - ; P=Priority, p=Palette, t=Tile number - %ai16() - LDA #$3A47 : STA !OAM_LOW+$2,Y ; %00111010 top-left - LDA #$7A47 : STA !OAM_LOW+$6,Y ; %01111010 top-right - LDA #$BA47 : STA !OAM_LOW+$A,Y ; %10111010 bottom-left - LDA #$FA47 : STA !OAM_LOW+$E,Y ; %11111010 bottom-right + ; Sprite Attributes + %a16() + LDA !ram_sprite_feature_flags : BIT !SPRITE_ENEMY_HITBOX_WHITE : BEQ .ridley_blue + LDA #$3047 : STA !OAM_LOW+$2,Y ; top left + ORA #$4000 : STA !OAM_LOW+$6,Y ; top right + ORA #$8000 : STA !OAM_LOW+$E,Y ; bottom right + AND #$BFFF : STA !OAM_LOW+$A,Y ; bottom left + + ; inc oam stack + TYA : CLC : ADC #$0010 : STA !OAM_STACK_POINTER + RTS + + .ridley_blue + LDA #$3A47 : STA !OAM_LOW+$2,Y ; top left + ORA #$4000 : STA !OAM_LOW+$6,Y ; top right + ORA #$8000 : STA !OAM_LOW+$E,Y ; bottom right + AND #$BFFF : STA !OAM_LOW+$A,Y ; bottom left ; inc oam stack TYA : CLC : ADC #$0010 : STA !OAM_STACK_POINTER @@ -1192,14 +1248,13 @@ DrawMBHitbox: LDA $1C : CLC : ADC $1A : SEC : SBC #$08 STA !OAM_LOW+$9,Y : STA !OAM_LOW+$D,Y - ; Sprite Attributes - xxxxxxxx yyyyyyyy YXPPpppt tttttttt - ; x=X pos, y=Y pos, Y=Y flip, X=X flip - ; P=Priority, p=Palette, t=Tile number - %ai16() - LDA #$3A47 : STA !OAM_LOW+$2,Y ; %00111010 top-left - LDA #$7A47 : STA !OAM_LOW+$6,Y ; %01111010 top-right - LDA #$BA47 : STA !OAM_LOW+$A,Y ; %10111010 bottom-left - LDA #$FA47 : STA !OAM_LOW+$E,Y ; %11111010 bottom-right + ; Sprite Attributes + %a16() + LDA $CB + ORA #$3000 : STA !OAM_LOW+$2,Y ; top left + ORA #$4000 : STA !OAM_LOW+$6,Y ; top right + ORA #$8000 : STA !OAM_LOW+$E,Y ; bottom right + AND #$BFFF : STA !OAM_LOW+$A,Y ; bottom left ; inc oam stack TYA : CLC : ADC #$0010 : STA !OAM_STACK_POINTER : TAY diff --git a/src/symbols.asm b/src/symbols.asm index 0f0e4369..85d33047 100644 --- a/src/symbols.asm +++ b/src/symbols.asm @@ -328,6 +328,10 @@ ram_cm_zebes_seconds = !ram_cm_zebes_seconds ; !WRAM_MENU_START+$92 ram_cm_sprites_spacetime = !ram_cm_sprites_spacetime ; !WRAM_MENU_START+$90 ram_cm_sprites_xray = !ram_cm_sprites_xray ; !WRAM_MENU_START+$92 +ram_cm_sprites_samus_hitbox = !ram_cm_sprites_samus_hitbox ; !WRAM_MENU_START+$94 +ram_cm_sprites_samus_proj = !ram_cm_sprites_samus_proj ; !WRAM_MENU_START+$96 +ram_cm_sprites_enemy_hitbox = !ram_cm_sprites_enemy_hitbox ; !WRAM_MENU_START+$98 +ram_cm_sprites_enemy_proj = !ram_cm_sprites_enemy_proj ; !WRAM_MENU_START+$9A ram_cm_ctrl_add_shortcut_slot = !ram_cm_ctrl_add_shortcut_slot ; !WRAM_MENU_START+$90 ram_cm_ctrl_last_pri = !ram_cm_ctrl_last_pri ; !WRAM_MENU_START+$92 diff --git a/web/data/changelog.mdx b/web/data/changelog.mdx index 2e7a1a80..83304e76 100644 --- a/web/data/changelog.mdx +++ b/web/data/changelog.mdx @@ -57,6 +57,7 @@ - Prevent shinetune from showing L# when dash pressed near beginning of movement (2.7.7) - Fix crash when OOB x-ray aiming up, and add 0% common RAM watch addresses (2.7.7.1) - Add OOB show X wraparound option (2.7.7.1) +- Sprite features now has option to show hitboxes in blue or white color (2.7.7.2) # Version 2.6.x - Optimize kraid rock projectiles to reduce lag when Kraid rises (2.6.0) diff --git a/web/data/config.json b/web/data/config.json index 2ae1165e..39160fee 100644 --- a/web/data/config.json +++ b/web/data/config.json @@ -1,6 +1,6 @@ { "name": "Super Metroid Practice Hack", - "version": "2.7.7.1", + "version": "2.7.7.2", "variants": ["NTSC", "PAL"], "base": { "NTSC": { From 20cd0f63bb6975a35d08e3d422c336833f71b27f Mon Sep 17 00:00:00 2001 From: idle Date: Sun, 12 Jul 2026 00:51:33 -0500 Subject: [PATCH 2/6] Add option to overwrite hitbox blue and/or grapple beam color --- resources/cm_gfx.bin | Bin 4096 -> 4096 bytes resources/cm_gfx2.bin | Bin 4096 -> 4096 bytes src/customizemenu.asm | 33 +++--- src/defines.asm | 14 ++- src/init.asm | 5 + src/macros.asm | 11 +- src/main.asm | 2 +- src/mainmenu.asm | 255 +++++++++++++++++++++++++++++++++++------- src/menu.asm | 63 ++++++++--- src/spritefeat.asm | 37 ++++++ src/symbols.asm | 7 +- 11 files changed, 347 insertions(+), 80 deletions(-) diff --git a/resources/cm_gfx.bin b/resources/cm_gfx.bin index 1d8653102bb77dcd86dee5400a3020f766906d1c..1a7a007be1d56229827d4808342da7e924be909e 100644 GIT binary patch delta 20 bcmZorXi(VTz&TlvQ)IFmr|ss6ocU}3Knexi delta 20 bcmZorXi(VTz&SaD({^$Kr^x1socU}3M4|>c diff --git a/resources/cm_gfx2.bin b/resources/cm_gfx2.bin index a271803061667fa187ae36328d1c315a15381224..37b3698de38c7183fed28d070815793f0b2bccb0 100644 GIT binary patch delta 20 bcmZorXi(VTz&TlvQ)IFmr|ss6ocU}3Knexi delta 20 bcmZorXi(VTz&SaD({^$Kr^x1socU}3M4|>c diff --git a/src/customizemenu.asm b/src/customizemenu.asm index 930942f0..602b76b3 100644 --- a/src/customizemenu.asm +++ b/src/customizemenu.asm @@ -321,7 +321,7 @@ mc_dynamic_custompalettes_menu: dw #mc_choosecustomtext mc_custompalettes_menu: - %cm_submenu("Customize Menu Palette", #CustomPalettesMenu) + %cm_jsl("Customize Menu Palette", mc_prepare_custom_palettes_menu, #CustomPalettesMenu) mc_choosecustomtext: %cm_jsl("Choose CUSTOM to customize", #.routine, #$0000) @@ -609,6 +609,13 @@ mc_customheader: .done RTL +mc_prepare_custom_palettes_menu: + TDC : STA !ram_cm_dummy_off + INC : STA !ram_cm_dummy_on + LDA #$00FF : STA !ram_cm_dummy_num + %setmenubank() + JML action_submenu + CustomPalettesMenu: dw #custompalettes_text dw #custompalettes_seltext @@ -624,44 +631,44 @@ CustomPalettesMenu: dw #$FFFF dw #$FFFF dw #$FFFF - dw #$FFFF %examplemenu() ; inserts dummy menu items for display purposes + dw #$FFFF dw #mc_custompalettes_test_menu dw #$0000 %cm_header("CUSTOMIZE MENU PALETTE") custompalettes_text: - %palettemenu("Text", PalettesMenu_text, !sram_palette_text) + %palettemenu("Text", PalettesMenu_text, !sram_palette_text, #$2894) custompalettes_seltext: - %palettemenu("Selected Text", PalettesMenu_seltext, !sram_palette_seltext) + %palettemenu("Selected Text", PalettesMenu_seltext, !sram_palette_seltext, #$3894) custompalettes_seltextbg: - %palettemenu("Selected Text Background", PalettesMenu_seltextbg, !sram_palette_seltextbg) + %palettemenu("Selected Text Background", PalettesMenu_seltextbg, !sram_palette_seltextbg, #$381F) custompalettes_headerline: - %palettemenu("Header Outline", PalettesMenu_headerline, !sram_palette_headeroutline) + %palettemenu("Header Outline", PalettesMenu_headerline, !sram_palette_headeroutline, #$2891) custompalettes_numfill: - %palettemenu("Number Field Text", PalettesMenu_numfill, !sram_palette_numfill) + %palettemenu("Number Field Text", PalettesMenu_numfill, !sram_palette_numfill, #$2C94) custompalettes_numline: - %palettemenu("Number Field Outline", PalettesMenu_numline, !sram_palette_numoutline) + %palettemenu("Number Field Outline", PalettesMenu_numline, !sram_palette_numoutline, #$2C91) custompalettes_numsel: - %palettemenu("Selected Num-Field Text", PalettesMenu_numsel, !sram_palette_numsel) + %palettemenu("Selected Num-Field Text", PalettesMenu_numsel, !sram_palette_numsel, #$3C94) custompalettes_numselline: - %palettemenu("Selected Num-Field Outline", PalettesMenu_numselline, !sram_palette_numseloutline) + %palettemenu("Selected Num-Field Outline", PalettesMenu_numselline, !sram_palette_numseloutline, #$3C91) custompalettes_toggleon: - %palettemenu("Toggle ON", PalettesMenu_toggleon, !sram_palette_toggleon) + %palettemenu("Toggle ON", PalettesMenu_toggleon, !sram_palette_toggleon, #$3891) custompalettes_border: - %palettemenu("Toggle OFF + Border", PalettesMenu_border, !sram_palette_border) + %palettemenu("Toggle OFF + Border", PalettesMenu_border, !sram_palette_border, #$2491) custompalettes_background: - %palettemenu("Background", PalettesMenu_background, !sram_palette_background) + %palettemenu("Background", PalettesMenu_background, !sram_palette_background, #$241F) custompalettes_hex_red: %cm_numfield_color("Hexadecimal Red", !ram_cm_custompalette_red, #MixRGB) diff --git a/src/defines.asm b/src/defines.asm index e2ab59ee..b3c0fb4c 100644 --- a/src/defines.asm +++ b/src/defines.asm @@ -356,6 +356,9 @@ !ram_cm_sprites_samus_proj = !WRAM_MENU_START+$96 !ram_cm_sprites_enemy_hitbox = !WRAM_MENU_START+$98 !ram_cm_sprites_enemy_proj = !WRAM_MENU_START+$9A +!ram_cm_sprites_palette_blue = !WRAM_MENU_START+$9C +!ram_cm_sprites_palette_green = !WRAM_MENU_START+$9E +!ram_cm_sprites_palette_red = !WRAM_MENU_START+$A0 !ram_cm_ctrl_add_shortcut_slot = !WRAM_MENU_START+$90 !ram_cm_ctrl_last_pri = !WRAM_MENU_START+$92 @@ -414,7 +417,7 @@ ; and is reset to zero when loading a savestate ; Reserve 48 bytes for CGRAM cache -; Currently first 28 bytes plus last 2 bytes are used +; Currently first 32 bytes plus last 2 bytes are used !ram_cgram_cache = !WRAM_MENU_START+$D0 ; $30 bytes @@ -473,7 +476,7 @@ ; SRAM ; ----- -!SRAM_VERSION = #$001F +!SRAM_VERSION = #$0020 !SRAM_START = $702000 !SRAM_SIZE = #$1000 @@ -560,6 +563,8 @@ !sram_fast_teleport = !SRAM_START+$AA !sram_update_timers_ctrl_input = !SRAM_START+$AC !sram_update_timers_options = !SRAM_START+$AE +!sram_sprite_features_blue_color = !SRAM_START+$B0 +!sram_sprite_features_grapple_color = !SRAM_START+$B2 ; ^ FREE SPACE ^ up to +$CE @@ -715,6 +720,9 @@ !CTRL_L = #$0020 !CTRL_R = #$0010 +!VANILLA_SPRITE_PALETTE_5_BLUE_COLOR = #$7D08 +!VANILLA_SPRITE_PALETTE_5_GRAPPLE_COLOR = #$7F91 + !PLM_DELETE = $AAE3 !MUSIC_ROUTINE = $808FC1 @@ -996,6 +1004,7 @@ !SAMUS_POWER_BOMB_X = $0CE2 !SAMUS_POWER_BOMB_Y = $0CE4 !OFFSCREEN_HDMA_INDEX = $0D1E +!GRAPPLE_BEAM_FUNCTION = $0D32 !CURRENT_BLOCK_INDEX = $0DC4 !SAMUS_VERTICAL_COLLISION_RESULT = $0DC6 !SAMUS_X_SPEED_KILLED = $0DCE @@ -1333,6 +1342,7 @@ endif !ACTION_MANAGE_PRESETS = #$002A !ACTION_CATEGORY_PRESET = #$002C !ACTION_ADJUST_ITEM = #$002E +!ACTION_COLOR_BAR = #$0030 !SAFEWORD = #$5AFE diff --git a/src/init.asm b/src/init.asm index a9ef2676..23a40c32 100644 --- a/src/init.asm +++ b/src/init.asm @@ -166,6 +166,7 @@ init_sram_routine_table: dw init_sram_upgrade_1Cto1D dw init_sram_upgrade_1Dto1E dw init_sram_upgrade_1Eto1F + dw init_sram_upgrade_1Fto20 dw init_sram_fail init_sram: @@ -315,6 +316,10 @@ endif JSR init_reset_rng_control INC : STA !sram_hard_reset_clears_rng + .upgrade_1Fto20 + LDA !VANILLA_SPRITE_PALETTE_5_BLUE_COLOR : STA !sram_sprite_features_blue_color + LDA !VANILLA_SPRITE_PALETTE_5_GRAPPLE_COLOR : STA !sram_sprite_features_grapple_color + LDA !SRAM_VERSION : STA !sram_initialized RTS diff --git a/src/macros.asm b/src/macros.asm index 27af89f2..1eac33da 100644 --- a/src/macros.asm +++ b/src/macros.asm @@ -428,7 +428,7 @@ macro examplemenu() dw #mc_dummy_num endmacro -macro palettemenu(title, label, addr) +macro palettemenu(title, label, addr, color_tile) ; menu tables for customizing menu color palettes %cm_jsl("", #palettemenu_setup, <label>) @@ -443,7 +443,7 @@ macro palettemenu(title, label, addr) dw #$FFFF dw <label>_hex_word dw #$FFFF - dw #$FFFF + dw <label>_color_bar dw #$FFFF dw #$FFFF dw #$FFFF @@ -458,7 +458,12 @@ macro palettemenu(title, label, addr) .set STA <addr> JML SplitRGB -} + +<label>_color_bar: + .dm_actionIndex + dw !ACTION_COLOR_BAR + .dm_colorTile + dw <color_tile> endmacro macro setupRGB(addr) diff --git a/src/main.asm b/src/main.asm index 02533b4b..047d606e 100644 --- a/src/main.asm +++ b/src/main.asm @@ -17,7 +17,7 @@ lorom !VERSION_MAJOR = 2 !VERSION_MINOR = 7 !VERSION_BUILD = 7 -!VERSION_REV = 2 +!VERSION_REV = 10 table ../resources/normal.tbl print "" diff --git a/src/mainmenu.asm b/src/mainmenu.asm index c0f7e476..aa804373 100644 --- a/src/mainmenu.asm +++ b/src/mainmenu.asm @@ -1839,10 +1839,7 @@ SpritesMenu: dw #sprites_show_enemyproj_hitbox dw #sprites_show_proj_as_32x32 dw #$FFFF - dw #sprites_samus_hitbox_color - dw #sprites_samus_proj_color - dw #sprites_enemy_hitbox_color - dw #sprites_enemy_proj_color + dw #sprites_color_customization if !PRESERVE_WRAM dw #$FFFF dw #sprites_hud_spacetime @@ -1878,6 +1875,67 @@ sprites_show_enemyproj_hitbox: sprites_show_proj_as_32x32: %cm_toggle_bit("32x32 Projectile Boxes", !ram_sprite_feature_flags, !SPRITE_32x32_PROJ, #0) +sprites_color_customization: + %cm_submenu("Hitbox Color Customization", #SpritesColorMenu) + +if !PRESERVE_WRAM +sprites_hud_spacetime: + dw !ACTION_CHOICE + dl #!ram_cm_sprites_spacetime + dw #.routine + db #$28, "Spacetime HUD", #$FF + db #$28, " VANILLA", #$FF + db #$28, " PRESERVED", #$FF + db #$FF + .routine + LDA !ram_sprite_feature_flags : AND !SPRITE_HUD_SPACETIME_INVERTED + STA !ram_sprite_feature_flags + LDA !ram_cm_sprites_spacetime : XBA + ORA !ram_sprite_feature_flags : STA !ram_sprite_feature_flags + RTL + +sprites_hud_xray: + dw !ACTION_CHOICE + dl #!ram_cm_sprites_xray + dw #.routine + db #$28, "X-Ray HUD", #$FF + db #$28, " VANILLA", #$FF + db #$28, " PRESERVED", #$FF + db #$FF + .routine + LDA !ram_sprite_feature_flags : AND !SPRITE_HUD_XRAY_INVERTED + STA !ram_sprite_feature_flags + LDA !ram_cm_sprites_xray : XBA : ASL + ORA !ram_sprite_feature_flags : STA !ram_sprite_feature_flags + RTL +endif ; PRESERVE_WRAM + +sprites_oob_viewer: + %cm_toggle_bit("OoB Tile Viewer", !ram_sprite_feature_flags, !SPRITE_OOB_WATCH, .routine) + .routine + LDA !ram_sprite_feature_flags : BIT !SPRITE_OOB_WATCH : BEQ .skip_oob + JML upload_sprite_oob_tiles + .skip_oob + RTL + +sprites_oob_show_x_wrap: + %cm_toggle_bit("OoB Show X Wraparound", !ram_sprite_feature_flags, !SPRITE_OOB_X_WRAP, #0) + +SpritesColorMenu: + dw #sprites_samus_hitbox_color + dw #sprites_samus_proj_color + dw #sprites_enemy_hitbox_color + dw #sprites_enemy_proj_color + dw #$FFFF + dw #sprites_blue_color + dw #sprites_blue_color_bar + dw #$FFFF + dw #sprites_grapple_color + dw #sprites_grapple_color_bar + dw #$0000 + %cm_header("SPRITE FEATURES") + %cm_footer("GRAPPLE OVERWRITES BLUE") + sprites_samus_hitbox_color: dw !ACTION_CHOICE dl #!ram_cm_sprites_samus_hitbox @@ -1938,48 +1996,161 @@ sprites_enemy_proj_color: ORA !ram_sprite_feature_flags : STA !ram_sprite_feature_flags RTL -if !PRESERVE_WRAM -sprites_hud_spacetime: - dw !ACTION_CHOICE - dl #!ram_cm_sprites_spacetime - dw #.routine - db #$28, "Spacetime HUD", #$FF - db #$28, " VANILLA", #$FF - db #$28, " PRESERVED", #$FF - db #$FF - .routine - LDA !ram_sprite_feature_flags : AND !SPRITE_HUD_SPACETIME_INVERTED - STA !ram_sprite_feature_flags - LDA !ram_cm_sprites_spacetime : XBA - ORA !ram_sprite_feature_flags : STA !ram_sprite_feature_flags - RTL +sprites_blue_color: + %cm_jsl("Customize Blue Color", #sprites_blue_color_setup, SpritesBlueColorMenu) -sprites_hud_xray: - dw !ACTION_CHOICE - dl #!ram_cm_sprites_xray - dw #.routine - db #$28, "X-Ray HUD", #$FF - db #$28, " VANILLA", #$FF - db #$28, " PRESERVED", #$FF - db #$FF - .routine - LDA !ram_sprite_feature_flags : AND !SPRITE_HUD_XRAY_INVERTED - STA !ram_sprite_feature_flags - LDA !ram_cm_sprites_xray : XBA : ASL - ORA !ram_sprite_feature_flags : STA !ram_sprite_feature_flags - RTL -endif ; PRESERVE_WRAM +sprites_blue_color_bar: + dw !ACTION_COLOR_BAR + dw #$3091 -sprites_oob_viewer: - %cm_toggle_bit("OoB Tile Viewer", !ram_sprite_feature_flags, !SPRITE_OOB_WATCH, .routine) +sprites_grapple_color: + %cm_jsl("Customize Grapple Color", #sprites_grapple_color_setup, SpritesGrappleColorMenu) + +sprites_grapple_color_bar: + dw !ACTION_COLOR_BAR + dw #$301F + +sprites_blue_color_setup: + LDA !sram_sprite_features_blue_color : AND #$7C00 + XBA : LSR #2 : STA !ram_cm_sprites_palette_blue + LDA !sram_sprite_features_blue_color : AND #$03E0 + LSR #5 : STA !ram_cm_sprites_palette_green + LDA !sram_sprite_features_blue_color : AND #$001F + STA !ram_cm_sprites_palette_red + JML action_submenu + +SpritesBlueColorMenu: + dw #sprites_blue_hex_red + dw #sprites_blue_hex_green + dw #sprites_blue_hex_blue + dw #$FFFF + dw #sprites_blue_dec_red + dw #sprites_blue_dec_green + dw #sprites_blue_dec_blue + dw #$FFFF + dw #sprites_blue_hex_word + dw #$FFFF + dw #sprites_blue_color_bar + dw #$FFFF + dw #sprites_blue_reset + dw #$0000 + %cm_header("CUSTOMIZE BLUE COLOR") + %cm_footer("THREE WAYS TO EDIT COLORS") + +sprites_blue_hex_red: + %cm_numfield_color("Hexadecimal Red", !ram_cm_sprites_palette_red, #sprites_blue_mix_rgb) + +sprites_blue_hex_green: + %cm_numfield_color("Hexadecimal Green", !ram_cm_sprites_palette_green, #sprites_blue_mix_rgb) + +sprites_blue_hex_blue: + %cm_numfield_color("Hexadecimal Blue", !ram_cm_sprites_palette_blue, #sprites_blue_mix_rgb) + +sprites_blue_mix_rgb: + ; mix 5-bit RGB values into 15-bit BGR format + LDA !ram_cm_sprites_palette_blue : XBA : ASL #2 + STA !sram_sprite_features_blue_color + LDA !ram_cm_sprites_palette_green : ASL #5 + ORA !sram_sprite_features_blue_color : STA !sram_sprite_features_blue_color + LDA !ram_cm_sprites_palette_red + ORA !sram_sprite_features_blue_color : STA !sram_sprite_features_blue_color + JML refresh_cgram_long + +sprites_blue_dec_red: + %cm_numfield("Decimal Red", !ram_cm_sprites_palette_red, 0, 31, 1, 2, #sprites_blue_mix_rgb) + +sprites_blue_dec_green: + %cm_numfield("Decimal Green", !ram_cm_sprites_palette_green, 0, 31, 1, 2, #sprites_blue_mix_rgb) + +sprites_blue_dec_blue: + %cm_numfield("Decimal Blue", !ram_cm_sprites_palette_blue, 0, 31, 1, 2, #sprites_blue_mix_rgb) + +sprites_blue_hex_word: + %cm_numfield_hex_word("SNES 15-bit BGR", !sram_sprite_features_blue_color, #$7FFF, .routine) + .reset + TYA : STA !sram_sprite_features_blue_color .routine - LDA !ram_sprite_feature_flags : BIT !SPRITE_OOB_WATCH : BEQ .skip_oob - JML upload_sprite_oob_tiles - .skip_oob - RTL + ; split 15-bit BGR format into 5-bit red, green, and blue + AND #$7C00 : XBA : LSR #2 : STA !ram_cm_sprites_palette_blue + LDA !sram_sprite_features_blue_color : AND #$03E0 + LSR #5 : STA !ram_cm_sprites_palette_green + LDA !sram_sprite_features_blue_color : AND #$001F + STA !ram_cm_sprites_palette_red + JML refresh_cgram_long + +sprites_blue_reset: + %cm_jsl("Reset Blue Color", #sprites_blue_hex_word_reset, !VANILLA_SPRITE_PALETTE_5_BLUE_COLOR) + +sprites_grapple_color_setup: + LDA !sram_sprite_features_grapple_color : AND #$7C00 + XBA : LSR #2 : STA !ram_cm_sprites_palette_blue + LDA !sram_sprite_features_grapple_color : AND #$03E0 + LSR #5 : STA !ram_cm_sprites_palette_green + LDA !sram_sprite_features_grapple_color : AND #$001F + STA !ram_cm_sprites_palette_red + JML action_submenu -sprites_oob_show_x_wrap: - %cm_toggle_bit("OoB Show X Wraparound", !ram_sprite_feature_flags, !SPRITE_OOB_X_WRAP, #0) +SpritesGrappleColorMenu: + dw #sprites_grapple_hex_red + dw #sprites_grapple_hex_green + dw #sprites_grapple_hex_blue + dw #$FFFF + dw #sprites_grapple_dec_red + dw #sprites_grapple_dec_green + dw #sprites_grapple_dec_blue + dw #$FFFF + dw #sprites_grapple_hex_word + dw #$FFFF + dw #sprites_grapple_color_bar + dw #$FFFF + dw #sprites_grapple_reset + dw #$0000 + %cm_header("CUSTOMIZE GRAPPLE COLOR") + %cm_footer("THREE WAYS TO EDIT COLORS") + +sprites_grapple_hex_red: + %cm_numfield_color("Hexadecimal Red", !ram_cm_sprites_palette_red, #sprites_grapple_mix_rgb) + +sprites_grapple_hex_green: + %cm_numfield_color("Hexadecimal Green", !ram_cm_sprites_palette_green, #sprites_grapple_mix_rgb) + +sprites_grapple_hex_blue: + %cm_numfield_color("Hexadecimal Blue", !ram_cm_sprites_palette_blue, #sprites_grapple_mix_rgb) + +sprites_grapple_mix_rgb: + ; mix 5-bit RGB values into 15-bit BGR format + LDA !ram_cm_sprites_palette_blue : XBA : ASL #2 + STA !sram_sprite_features_grapple_color + LDA !ram_cm_sprites_palette_green : ASL #5 + ORA !sram_sprite_features_grapple_color : STA !sram_sprite_features_grapple_color + LDA !ram_cm_sprites_palette_red + ORA !sram_sprite_features_grapple_color : STA !sram_sprite_features_grapple_color + JML refresh_cgram_long + +sprites_grapple_dec_red: + %cm_numfield("Decimal Red", !ram_cm_sprites_palette_red, 0, 31, 1, 2, #sprites_grapple_mix_rgb) + +sprites_grapple_dec_green: + %cm_numfield("Decimal Green", !ram_cm_sprites_palette_green, 0, 31, 1, 2, #sprites_grapple_mix_rgb) + +sprites_grapple_dec_blue: + %cm_numfield("Decimal Blue", !ram_cm_sprites_palette_blue, 0, 31, 1, 2, #sprites_grapple_mix_rgb) + +sprites_grapple_hex_word: + %cm_numfield_hex_word("SNES 15-bit BGR", !sram_sprite_features_grapple_color, #$7FFF, .routine) + .reset + TYA : STA !sram_sprite_features_grapple_color + .routine + ; split 15-bit BGR format into 5-bit red, green, and blue + AND #$7C00 : XBA : LSR #2 : STA !ram_cm_sprites_palette_blue + LDA !sram_sprite_features_grapple_color : AND #$03E0 + LSR #5 : STA !ram_cm_sprites_palette_green + LDA !sram_sprite_features_grapple_color : AND #$001F + STA !ram_cm_sprites_palette_red + JML refresh_cgram_long + +sprites_grapple_reset: + %cm_jsl("Reset Grapple Color", #sprites_grapple_hex_word_reset, !VANILLA_SPRITE_PALETTE_5_GRAPPLE_COLOR) ; -------------- diff --git a/src/menu.asm b/src/menu.asm index 5486be25..4118d262 100644 --- a/src/menu.asm +++ b/src/menu.asm @@ -471,12 +471,14 @@ cm_transfer_custom_cgram: LDA $7EC01A : STA !ram_cgram_cache+$0A LDA $7EC01C : STA !ram_cgram_cache+$0C LDA $7EC01E : STA !ram_cgram_cache+$0E - LDA $7EC032 : STA !ram_cgram_cache+$10 - LDA $7EC034 : STA !ram_cgram_cache+$12 - LDA $7EC036 : STA !ram_cgram_cache+$14 - LDA $7EC03A : STA !ram_cgram_cache+$16 - LDA $7EC03C : STA !ram_cgram_cache+$18 - LDA $7EC03E : STA !ram_cgram_cache+$1A + LDA $7EC022 : STA !ram_cgram_cache+$10 + LDA $7EC026 : STA !ram_cgram_cache+$12 + LDA $7EC032 : STA !ram_cgram_cache+$14 + LDA $7EC034 : STA !ram_cgram_cache+$16 + LDA $7EC036 : STA !ram_cgram_cache+$18 + LDA $7EC03A : STA !ram_cgram_cache+$1A + LDA $7EC03C : STA !ram_cgram_cache+$1C + LDA $7EC03E : STA !ram_cgram_cache+$1E JSL PrepMenuPalette @@ -488,6 +490,8 @@ cm_transfer_custom_cgram: LDA !ram_cm_palette_background : STA $7EC00E : STA $7EC016 : STA $7EC01E LDA !ram_cm_palette_numoutline : STA $7EC01A LDA !ram_cm_palette_numfill : STA $7EC01C + LDA !sram_sprite_features_blue_color : STA $7EC022 + LDA !sram_sprite_features_grapple_color : STA $7EC026 LDA !ram_cm_palette_toggleon : STA $7EC032 LDA !ram_cm_palette_seltext : STA $7EC034 LDA !ram_cm_palette_seltextbg : STA $7EC036 : STA $7EC03E @@ -510,13 +514,20 @@ cm_transfer_original_cgram: LDA !ram_cgram_cache+$0A : STA $7EC01A LDA !ram_cgram_cache+$0C : STA $7EC01C LDA !ram_cgram_cache+$0E : STA $7EC01E - LDA !ram_cgram_cache+$10 : STA $7EC032 - LDA !ram_cgram_cache+$12 : STA $7EC034 - LDA !ram_cgram_cache+$14 : STA $7EC036 - LDA !ram_cgram_cache+$16 : STA $7EC03A - LDA !ram_cgram_cache+$18 : STA $7EC03C - LDA !ram_cgram_cache+$1A : STA $7EC03E - + LDA !ram_cgram_cache+$10 : STA $7EC022 + LDA !ram_cgram_cache+$12 : STA $7EC026 + LDA !ram_cgram_cache+$14 : STA $7EC032 + LDA !ram_cgram_cache+$16 : STA $7EC034 + LDA !ram_cgram_cache+$18 : STA $7EC036 + LDA !ram_cgram_cache+$1A : STA $7EC03A + LDA !ram_cgram_cache+$1C : STA $7EC03C + LDA !ram_cgram_cache+$1E : STA $7EC03E + + LDA !sram_sprite_features_blue_color : STA $7EC3BE + LDA !GAMEMODE : CMP #$0008 : BNE .transfer + LDA !sram_sprite_features_blue_color : STA $7EC1BE + + .transfer JML transfer_cgram_long } @@ -795,6 +806,7 @@ cm_draw_action_table: dw draw_manage_presets dw draw_category_preset dw draw_adjust_item + dw draw_color_bar draw_toggle: { @@ -1859,6 +1871,19 @@ draw_adjust_item: RTS } +draw_color_bar: +{ + ; Grab and draw the value + %item_index_to_vram_index() + LDA [!DP_CurrentMenu] + LDY #$0032 + + .loop + STA !ram_tilemap_buffer,X : INX #2 + DEY #2 : BPL .loop + RTS +} + cm_hex2dec_draw5: ; Converts a hex number into a five digit decimal number ; expects value to be drawn in !DP_DrawValue @@ -2000,7 +2025,7 @@ menu_ctrl_2_input_display: RTS .table - dw #$A100, #$B800, #$AC00, #$B200, #$9400, #$9400, #$9400, #$9400 + dw #$A100, #$B800, #$AC00, #$B200, #$1F00, #$1F00, #$1F00, #$1F00 dw #$A200, #$B900, #$8300, #$8200, #$F900, #$F980, #$FF40, #$FF00 } @@ -2019,12 +2044,12 @@ menu_ctrl_1_input_display: .no_draw INY : ASL : BNE .loop - LDA #$9400 : ORA !DP_Palette : XBA + LDA #$1F00 : ORA !DP_Palette : XBA STA !ram_tilemap_buffer,X RTS .table - dw #$8F00, #$8E00, #$8D00, #$8C00, #$9400, #$9400, #$9400, #$9400 + dw #$8F00, #$8E00, #$8D00, #$8C00, #$1F00, #$1F00, #$1F00, #$1F00 dw #$8700, #$8600, #$8500, #$8400, #$8100, #$8180, #$8040, #$8000 } @@ -3028,6 +3053,7 @@ cm_move: .checkCtrlShortcut STA !DP_CurrentMenu : LDA [!DP_CurrentMenu] + CMP !ACTION_COLOR_BAR : BEQ .repeat CMP !ACTION_CTRL_SHORTCUT : BNE .checkDynamic ; grab the shortcut slot @@ -3117,7 +3143,7 @@ cm_execute_action_table: dw execute_numfield_word dw execute_numfield_hex_word dw execute_numfield_signed - dw execute_nop + dw execute_nop ; readonly dw execute_numfield_color dw execute_numfield_sound dw execute_choice @@ -3127,11 +3153,12 @@ cm_execute_action_table: dw execute_jsl dw execute_submenu dw execute_custom_preset - dw execute_nop + dw execute_nop ; ram watch dw execute_dynamic dw execute_manage_presets dw execute_category_preset dw execute_adjust_item + dw execute_nop ; color bar execute_nop: RTS diff --git a/src/spritefeat.asm b/src/spritefeat.asm index 8edd8025..3ea1bc00 100644 --- a/src/spritefeat.asm +++ b/src/spritefeat.asm @@ -6,6 +6,13 @@ ; +org $80A0C6 + JSL load_common_target_colors + +; Ceres does not need to overwrite sprite 5 blue color +org $828130 + BRA $02 + ; Hook Gamemode 7 to upload tiles after loading if needed org $828B26 JSL update_sprite_tiles_loading @@ -15,6 +22,27 @@ org $828B26 org $828B98 JSL update_sprite_features +; Load target colors except load custom sprite 5 blue color +org $82E138 +load_common_target_colors: +{ + %ai16() + LDX #$001E + .first_loop + LDA $9A81A0,X : STA $7EC3A0,X + DEX #2 : BPL .first_loop + LDA !sram_sprite_features_blue_color : STA $7EC3BE + LDX #$001E + .second_loop: + LDA $7EC1C0,X : STA $7EC3C0,X + LDA $9AFC00,X : STA $7EC300,X + DEX #2 : BPL .second_loop + RTL +warnpc $82E169 + +org $82E4D0 + JSL load_common_target_colors + ; Add hitbox graphic to free sprite VRAM slot org $9ADAE0 @@ -23,6 +51,15 @@ hook_standard_sprite_tiles: db $FF, $FF, $80, $80, $80, $80, $80, $80, $80, $80, $80, $80, $80, $80, $80, $80 +; Grapple routine loads custom grapple color +org $9BC686 + LDA !sram_sprite_features_grapple_color : STA $7EC1BE + LDA #$C703 : STA !GRAPPLE_BEAM_FUNCTION + LDA #$0005 : JSL $80903F + TDC : INC +warnpc $9BC69D + + %startfree(87) ; This runs every frame before any other sprites are drawn, this is needed so we can get priority over everything else diff --git a/src/symbols.asm b/src/symbols.asm index 85d33047..ab5e45ba 100644 --- a/src/symbols.asm +++ b/src/symbols.asm @@ -332,6 +332,9 @@ ram_cm_sprites_samus_hitbox = !ram_cm_sprites_samus_hitbox ; !WRAM_MENU_START+$9 ram_cm_sprites_samus_proj = !ram_cm_sprites_samus_proj ; !WRAM_MENU_START+$96 ram_cm_sprites_enemy_hitbox = !ram_cm_sprites_enemy_hitbox ; !WRAM_MENU_START+$98 ram_cm_sprites_enemy_proj = !ram_cm_sprites_enemy_proj ; !WRAM_MENU_START+$9A +ram_cm_sprites_palette_blue = !ram_cm_sprites_palette_blue ; !WRAM_MENU_START+$9C +ram_cm_sprites_palette_green = !ram_cm_sprites_palette_green ; !WRAM_MENU_START+$9E +ram_cm_sprites_palette_red = !ram_cm_sprites_palette_red ; !WRAM_MENU_START+$A0 ram_cm_ctrl_add_shortcut_slot = !ram_cm_ctrl_add_shortcut_slot ; !WRAM_MENU_START+$90 ram_cm_ctrl_last_pri = !ram_cm_ctrl_last_pri ; !WRAM_MENU_START+$92 @@ -390,7 +393,7 @@ ram_cm_dummy_num = !ram_cm_dummy_num ; !WRAM_MENU_START+$AE ; and is reset to zero when loading a savestate ; Reserve 48 bytes for CGRAM cache -; Currently first 28 bytes plus last 2 bytes are used +; Currently first 32 bytes plus last 2 bytes are used ram_cgram_cache = !ram_cgram_cache ; !WRAM_MENU_START+$D0 ; $30 bytes ; ----------------- @@ -523,6 +526,8 @@ sram_speed_booster_physics = !sram_speed_booster_physics ; !SRAM_START+$A8 sram_fast_teleport = !sram_fast_teleport ; !SRAM_START+$AA sram_update_timers_ctrl_input = !sram_update_timers_ctrl_input ; !SRAM_START+$AC sram_update_timers_options = !sram_update_timers_options ; !SRAM_START+$AE +sram_sprite_features_blue_color = !sram_sprite_features_blue_color ; !SRAM_START+$B0 +sram_sprite_features_grapple_color = !sram_sprite_features_grapple_color ; !SRAM_START+$B2 ; ^ FREE SPACE ^ up to +$CE From ea3a2fd3c37d3b87e10571274e3fa01328e36d34 Mon Sep 17 00:00:00 2001 From: idle <idlechild123@gmail.com> Date: Sun, 12 Jul 2026 08:27:23 -0500 Subject: [PATCH 3/6] Clean up menu and apply color setting to OOB Samus hitbox --- resources/spritegfx.pal | Bin 0 -> 768 bytes src/main.asm | 2 +- src/mainmenu.asm | 10 +++++++--- src/spritefeat.asm | 24 +++++++++++++----------- web/data/help.mdx | 2 ++ 5 files changed, 23 insertions(+), 15 deletions(-) create mode 100644 resources/spritegfx.pal diff --git a/resources/spritegfx.pal b/resources/spritegfx.pal new file mode 100644 index 0000000000000000000000000000000000000000..810acf453f5b5c9be77ede2cb1dddae44d00ed88 GIT binary patch literal 768 zcmeIvA&!GU6oBFX3Y>rxSB2mJkO``WWD_)^2^N7sGGYY|O|l7U3<gz&-~yz$I?4^; z2-8V>0+N+|{?GgJ9`JbR=bhUxe}WyYxczWN=co(Uvr;P0b0Ng(bP+=Ho&UXn#I|kM zb$#EDq9{p{EX&HWtn0dM+rIC|ah&IQUDtizwbp@@Hn`wJ1PNqNLJckSFv1Kg=9OrW zfmv`MkTT#{fKhGRwk*puO~WvBUDq^CRaHe%q-h$*aTtc4=Q)mJS(fn|)dmYpFhB<l VR8T+)F@)fO1J=iXBzXG|1TW39ehdHr literal 0 HcmV?d00001 diff --git a/src/main.asm b/src/main.asm index 047d606e..dfa2c774 100644 --- a/src/main.asm +++ b/src/main.asm @@ -17,7 +17,7 @@ lorom !VERSION_MAJOR = 2 !VERSION_MINOR = 7 !VERSION_BUILD = 7 -!VERSION_REV = 10 +!VERSION_REV = 11 table ../resources/normal.tbl print "" diff --git a/src/mainmenu.asm b/src/mainmenu.asm index aa804373..a35ef890 100644 --- a/src/mainmenu.asm +++ b/src/mainmenu.asm @@ -1839,7 +1839,8 @@ SpritesMenu: dw #sprites_show_enemyproj_hitbox dw #sprites_show_proj_as_32x32 dw #$FFFF - dw #sprites_color_customization + dw #sprites_customize_hitbox_color + dw #sprites_customize_grapple_color if !PRESERVE_WRAM dw #$FFFF dw #sprites_hud_spacetime @@ -1875,8 +1876,11 @@ sprites_show_enemyproj_hitbox: sprites_show_proj_as_32x32: %cm_toggle_bit("32x32 Projectile Boxes", !ram_sprite_feature_flags, !SPRITE_32x32_PROJ, #0) -sprites_color_customization: - %cm_submenu("Hitbox Color Customization", #SpritesColorMenu) +sprites_customize_hitbox_color: + %cm_submenu("Customize Hitbox Color", #SpritesColorMenu) + +sprites_customize_grapple_color: + %cm_submenu("Customize Grapple Color", #SpritesColorMenu) if !PRESERVE_WRAM sprites_hud_spacetime: diff --git a/src/spritefeat.asm b/src/spritefeat.asm index 3ea1bc00..8d88e51b 100644 --- a/src/spritefeat.asm +++ b/src/spritefeat.asm @@ -471,22 +471,24 @@ draw_oob_samus_hitbox: STA !OAM_LOW+$9,Y : STA !OAM_LOW+$D,Y PLA ; discard high byte - LDA #%00111010 - STA !OAM_LOW+$3,Y ; Sprite 1 ATTR - STA !OAM_LOW+$7,Y ; Sprite 2 ATTR - STA !OAM_LOW+$B,Y ; Sprite 3 ATTR - STA !OAM_LOW+$F,Y ; Sprite 4 ATTR + ; Sprite Attributes + %a16() + LDA !ram_sprite_feature_flags : BIT !SPRITE_SAMUS_HITBOX_WHITE : BEQ .blue + LDA #$30DC + BRA .draw - LDA #$DC : STA !OAM_LOW+$2,Y - LDA #$DD : STA !OAM_LOW+$6,Y - LDA #$EC : STA !OAM_LOW+$A,Y - LDA #$ED : STA !OAM_LOW+$E,Y + .blue + LDA #$3ADC + + .draw + STA !OAM_LOW+$2,Y ; top left + INC : STA !OAM_LOW+$6,Y ; top right + EOR #$0031 : STA !OAM_LOW+$A,Y ; bottom left + INC : STA !OAM_LOW+$E,Y ; bottom right ; Normally the high sprite bits are cleared to zero so this shouldn't be needed for 8x8 sprites, ; but the hitbox drawing code will overwrite 1-3 extra sprite bits to gain speed so instead we ; compensate for it here to just have to do it once - - %ai16() PHY ; Sprite number TYA : LSR #2 : TAX : PHX diff --git a/web/data/help.mdx b/web/data/help.mdx index e149d862..9129f8a1 100644 --- a/web/data/help.mdx +++ b/web/data/help.mdx @@ -149,6 +149,8 @@ If you experience crashes or severe glitches when using savestates, your platfor | - Samus Projectile Hitbox | Toggles an overlay of Samus projectile hitboxes that are drawn on top of Samus projectile sprites. | - Enemy Projectile Hitbox | Toggles an overlay of enemy projectile hitboxes that are drawn on top of enemy projectile sprites. | - 32x32 Projectile Boxes | Toggles an overlay of the 32x32 grid used for projectile vs projectile collisions. Requires either Samus or Enemy Projectile Hitboxes to be active. +| - Customize Hitbox Color | Option to toggle hitboxes to blue or white color palette. Also allows the blue palette color to be changed. +| - Customize Grapple Color | Option to change the grapple color. The reason this is here is, when grapple beam is fired, the hitbox blue palette color is overwritten by the grapple beam color and remains this way until the next room. | - Spacetime HUD | Option to preserve the InfoHUD when using spacetime beam | - X-Ray HUD | Option to preserve the InfoHUD when using x-ray out of bounds | - OoB Tile Viewer | This enables an overlay that shows the tiles near Samus at all times, disconnected from the camera. This allows you to navigate OOB (Out of Bounds) areas where neither Samus nor the actual tiles are visible in-game. Samus hitbox is drawn at the center of the overlay to show the position relative to the tiles. From da048897a7470407d4e6df920ab2722b26e063b7 Mon Sep 17 00:00:00 2001 From: idle <idlechild123@gmail.com> Date: Sun, 12 Jul 2026 23:25:00 -0500 Subject: [PATCH 4/6] Fix Ceres elevator presets on PAL --- src/presets.asm | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/presets.asm b/src/presets.asm index 478554b7..1f765491 100644 --- a/src/presets.asm +++ b/src/presets.asm @@ -90,8 +90,13 @@ endif ; Create Ceres elevator projectiles if needed LDA !GAMEMODE : CMP #$001F : BNE .doneCeresProjectiles +if !FEATURE_PAL + LDY #$A3C3 : JSL $868027 + LDY #$A3D1 : JSL $868027 +else LDY #$A387 : JSL $868027 LDY #$A395 : JSL $868027 +endif .doneCeresProjectiles LDA #$0008 : STA !GAMEMODE From 1e035cba22363ec65dab3714fd9c8ba2335d172a Mon Sep 17 00:00:00 2001 From: idle <idlechild123@gmail.com> Date: Sun, 12 Jul 2026 23:38:27 -0500 Subject: [PATCH 5/6] Restore Ceres sprite 5 black color when riding elevator --- src/presets.asm | 1 + src/spritefeat.asm | 29 +++++++++++++++++++++++++---- 2 files changed, 26 insertions(+), 4 deletions(-) diff --git a/src/presets.asm b/src/presets.asm index 1f765491..4e4b0133 100644 --- a/src/presets.asm +++ b/src/presets.asm @@ -90,6 +90,7 @@ endif ; Create Ceres elevator projectiles if needed LDA !GAMEMODE : CMP #$001F : BNE .doneCeresProjectiles + TDC : STA $7EC3BE if !FEATURE_PAL LDY #$A3C3 : JSL $868027 LDY #$A3D1 : JSL $868027 diff --git a/src/spritefeat.asm b/src/spritefeat.asm index 8d88e51b..1190bf21 100644 --- a/src/spritefeat.asm +++ b/src/spritefeat.asm @@ -9,10 +9,6 @@ org $80A0C6 JSL load_common_target_colors -; Ceres does not need to overwrite sprite 5 blue color -org $828130 - BRA $02 - ; Hook Gamemode 7 to upload tiles after loading if needed org $828B26 JSL update_sprite_tiles_loading @@ -43,6 +39,31 @@ warnpc $82E169 org $82E4D0 JSL load_common_target_colors +if !FEATURE_PAL +org $86A3AE +else +org $86A372 +endif + LDA #delete_ceres_concealer_projectile_instruction + + +%startfree(86) + +delete_ceres_concealer_projectile_instruction: + dw delete_ceres_concealer_projectile + +delete_ceres_concealer_projectile: +{ + LDA !sram_sprite_features_blue_color : STA $7EC1BE + + ; Vanilla delete projectile routine + STZ !ENEMY_PROJ_ID,X + PLA + RTS +} + +%endfree(86) + ; Add hitbox graphic to free sprite VRAM slot org $9ADAE0 From a882689d0d4fe170a12ea262119135cc6a48be5f Mon Sep 17 00:00:00 2001 From: idle <idlechild123@gmail.com> Date: Sun, 12 Jul 2026 23:38:48 -0500 Subject: [PATCH 6/6] Release 2.7.8 --- src/main.asm | 4 ++-- web/data/changelog.mdx | 2 ++ web/data/config.json | 2 +- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/main.asm b/src/main.asm index dfa2c774..31ed01de 100644 --- a/src/main.asm +++ b/src/main.asm @@ -16,8 +16,8 @@ lorom !VERSION_MAJOR = 2 !VERSION_MINOR = 7 -!VERSION_BUILD = 7 -!VERSION_REV = 11 +!VERSION_BUILD = 8 +!VERSION_REV = 0 table ../resources/normal.tbl print "" diff --git a/web/data/changelog.mdx b/web/data/changelog.mdx index 83304e76..8e3c4e7f 100644 --- a/web/data/changelog.mdx +++ b/web/data/changelog.mdx @@ -58,6 +58,8 @@ - Fix crash when OOB x-ray aiming up, and add 0% common RAM watch addresses (2.7.7.1) - Add OOB show X wraparound option (2.7.7.1) - Sprite features now has option to show hitboxes in blue or white color (2.7.7.2) +- Sprite features now has option to change blue color and/or grapple color (2.8.0) +- Identify build features in crash handler and fixed Ceres elevator presets on PAL (2.8.0) # Version 2.6.x - Optimize kraid rock projectiles to reduce lag when Kraid rises (2.6.0) diff --git a/web/data/config.json b/web/data/config.json index 39160fee..3d36788f 100644 --- a/web/data/config.json +++ b/web/data/config.json @@ -1,6 +1,6 @@ { "name": "Super Metroid Practice Hack", - "version": "2.7.7.2", + "version": "2.7.8", "variants": ["NTSC", "PAL"], "base": { "NTSC": {