├── .github
└── workflows
│ └── release-zip.yml
├── .gitignore
├── README.md
├── Readme.html
├── amk_resources
├── music
│ └── 01 Miss (no intro).txt
└── sfx
│ └── Death Prelude.txt
├── changelog.txt
├── credits.txt
├── docs
├── _template.html
├── api.html
├── extra.html
├── faq.html
├── files.html
├── getting_started.html
├── hijack_map.html
├── img
│ ├── icon.png
│ ├── insert_object.png
│ ├── midway_object.png
│ ├── multiple_midway_$00.png
│ ├── multiple_midway_$01.png
│ ├── multiple_midway_$02.png
│ └── multiple_midway_$03.png
├── index.html
├── midway_instruction.html
├── objectool_info.html
├── ram_map.html
├── settings_global.html
├── settings_local.html
├── sram_bwram_info.html
├── sram_tables.html
├── style.css
├── troubleshooting.html
└── uninstall.html
├── retry_install.bat
└── src
├── gamemode
├── retry_gm00.asm
├── retry_gm06.asm
├── retry_gm07.asm
├── retry_gm0C.asm
├── retry_gm0D.asm
├── retry_gm0F.asm
├── retry_gm10.asm
├── retry_gm11.asm
├── retry_gm12.asm
├── retry_gm13.asm
├── retry_gm14.asm
├── retry_gm15.asm
├── retry_gm16.asm
└── retry_gm19.asm
├── library
└── retry.asm
├── retry_config
├── code
│ ├── api.asm
│ ├── check_incompatibilities.asm
│ ├── fade_to_level.asm
│ ├── fade_to_overworld.asm
│ ├── game_over.asm
│ ├── gm14_end
│ │ ├── death_routine.asm
│ │ ├── prompt_oam.asm
│ │ └── set_checkpoint.asm
│ ├── hijacks
│ │ ├── custom_midway.asm
│ │ ├── death_counter.asm
│ │ ├── hex_edits.asm
│ │ ├── hurry_up.asm
│ │ ├── initial_facing_fix.asm
│ │ ├── item_box_fix.asm
│ │ ├── multiple_midways.asm
│ │ ├── remove_status_bar.asm
│ │ ├── sram.asm
│ │ ├── switch_palace_message_fix.asm
│ │ ├── vanilla_boss_gm13.asm
│ │ └── vanilla_midway.asm
│ ├── in_level.asm
│ ├── include
│ │ ├── misc.asm
│ │ ├── rom.asm
│ │ └── tables.asm
│ ├── level_init_1.asm
│ ├── level_init_2.asm
│ ├── level_init_3.asm
│ ├── level_transition.asm
│ ├── load_overworld.asm
│ ├── nmi.asm
│ ├── prompt.asm
│ ├── shared.asm
│ ├── sprite_status_bar.asm
│ ├── startup.asm
│ └── time_up.asm
├── extra.asm
├── gfx
│ ├── bonus_stars.bin
│ ├── coins.bin
│ ├── digits.bin
│ ├── indicator.bin
│ ├── item_box_16x16.bin
│ ├── item_box_8x8.bin
│ ├── letters1.bin
│ ├── letters2.bin
│ ├── lives.bin
│ └── timer.bin
├── legacy
│ └── tables.asm
├── ram.asm
├── settings_global.asm
├── settings_local.asm
└── sram_tables.asm
└── retry_unpatch.asm
/.github/workflows/release-zip.yml:
--------------------------------------------------------------------------------
1 | name: Create Zip on Release
2 |
3 | on:
4 | release:
5 | types: [published]
6 |
7 | jobs:
8 | build-zip:
9 | name: Build Release Zip
10 | runs-on: ubuntu-latest
11 |
12 | steps:
13 | - name: Checkout Code
14 | uses: actions/checkout@v3
15 |
16 | - name: Define Exclusions and Create Zip
17 | run: |
18 | # rsync exclusions
19 | EXCLUDES=(
20 | ".git*"
21 | ".gitkeep"
22 | ".gitignore"
23 | ".github"
24 | "README.md"
25 | "docs/_template.html"
26 | )
27 |
28 | # Create args for rsync
29 | EXCLUDE_ARGS=""
30 | for item in "${EXCLUDES[@]}"; do
31 | EXCLUDE_ARGS+="--exclude=${item} "
32 | done
33 |
34 | # Create zip with rsync
35 | mkdir out
36 | rsync -av --progress ./ ./out/ ${EXCLUDE_ARGS} --exclude=out
37 | (
38 | cd out || exit 1
39 | zip -r ../retry-system_${{ github.event.release.tag_name }}.zip .
40 | )
41 |
42 | # Clean up
43 | rm -rf ./out
44 |
45 | - name: Install GitHub CLI
46 | run: |
47 | sudo apt-get install -y gh
48 |
49 | - name: Upload Release Asset
50 | env:
51 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
52 | run: |
53 | gh release upload ${{ github.event.release.tag_name }} retry-system_${{ github.event.release.tag_name }}.zip
54 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | *.zip
3 | *~
4 | *.smc
5 | *.sfc
6 |
7 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | ## Retry System
2 |
3 | This patch is meant as a spiritual successor to worldpeace's [Retry patch](https://www.smwcentral.net/?p=section&a=details&id=26078). While having the same functionalities, it features cleaner and more documented code, new features and a lot less hijacks, which makes it compatible with much more patches than before. Requires [UberASM Tool](https://www.smwcentral.net/?p=section&a=details&id=19982).
4 |
5 | See [Documentation](https://kkevinm.github.io/retry-system/) for more details.
6 |
--------------------------------------------------------------------------------
/Readme.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/amk_resources/music/01 Miss (no intro).txt:
--------------------------------------------------------------------------------
1 | #SPC
2 | {
3 | #author "Koji Kondo"
4 | #title "Miss!"
5 | #game "Super Mario World"
6 | }
7 |
8 | #samples
9 | {
10 | "EMPTY.brr"
11 | "EMPTY.brr"
12 | "EMPTY.brr"
13 | "default/03 SMW @3.brr" ; death
14 | "EMPTY.brr"
15 | "EMPTY.brr"
16 | "EMPTY.brr"
17 | "EMPTY.brr"
18 | "EMPTY.brr"
19 | "EMPTY.brr"
20 | "default/0A SMW @9.brr"
21 | "EMPTY.brr"
22 | "default/0C SMW @13.brr"
23 | }
24 |
25 | #option TempoImmunity
26 | #option NoLoop
27 | #option smwvtable
28 |
29 | #0
30 |
31 | $F0 y10
32 | t52 @9 q6E o6
33 | d+=12 e=12 d+=12 e=12 c=12 o5
34 | g=12 g+=12 a=12 d+=12 e=12 c=12 o4
35 | g=12 g+=12 a=12 d+=12 e=12 c=48 o3
36 | c=48
37 |
38 | #2
39 | @9 y10 q4E r=24 o4
40 | e=24 r=24 d=24 r=24 c=24 r=24 o3
41 | b=24 g=24 r=24 o2
42 | g=24 r=24
43 |
44 | #3
45 | @9 y10 q6E o3
46 | c=24 q4E o4 c=24 q6E o2
47 | a+=24 q4E o3
48 | a+=24 q6E o2
49 | a=24 q4E o3
50 | a=24 q6E o2
51 | g=24 q4E o3
52 | g=24 q6E o2
53 | c=24 r=24 c=48
54 |
55 |
56 | #amk 2
57 |
--------------------------------------------------------------------------------
/amk_resources/sfx/Death Prelude.txt:
--------------------------------------------------------------------------------
1 | $DA $02 $04 $30 $B4 $B2 $B4
2 |
--------------------------------------------------------------------------------
/credits.txt:
--------------------------------------------------------------------------------
1 | - Kevin: main programming and mantaining of the repository, with contributions by:
2 | - worldpeace: original Retry patch.
3 | - lx5: bugfixes to the original Retry patch, BW-RAM+ code.
4 | - imamelia, 0x400: ObjecTool code.
5 | - Thomas: death counter code.
6 | - Lui: remove status bar code.
7 | - dtothefourth: a couple new features ideas.
8 | - AmperSam: documentation help, 8x8 item box gfx, lives counter gfx, release workflow script, testing and feedback.
9 | - MiracleWater: Retry indicator idea and gfx, testing and feedback.
10 | - BabaYegha, Fyre150, Abdu, margot, simon.caio, LouisDoucet, SJandCharlieTheCat, Koopster, schema_tuna, Alex, Selicre, Mega, worldpeace, NixKillsMyths, mmBeefStew: testing and feedback.
11 |
--------------------------------------------------------------------------------
/docs/_template.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 | Return to main page
13 |
14 |
15 |
--------------------------------------------------------------------------------
/docs/api.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Retry API - Retry System UberASM
5 |
6 |
7 |
8 |
9 |
10 |
11 | Retry API
12 | "Retry API" refers to a collection of routines that Retry provides that you can call from your UberASM files if needed.
13 | NOTE: calling these routines from files in the "library" folder will result in an error, at least when using the standard UberASMTool.
14 |
15 | Index
16 |
25 |
26 |
27 | Respawn in level
28 | JSL retry_api_respawn_in_level
29 | Call this to make the player respawn in the current level at the last checkpoint. This has the same effect as dying and hitting Retry, or dying with instant Retry enabled, but skipping everything related to death (animation, music, prompt, etc.).
30 |
31 | Inputs: N/A
32 | Outputs: N/A
33 | Preconditions: A/X/Y 8 bits
34 | Postconditions: A/X/Y 8 bits
35 |
36 |
37 |
38 | Save game
39 | JSL retry_api_save_game
40 | Call this to save the game, which will also save the addresses defined in the sram_tables.asm
file.
41 |
42 | Inputs: N/A
43 | Outputs: N/A
44 | Preconditions: N/A
45 | Postconditions: A/X/Y 8 bits, DB/X/Y preserved
46 |
47 |
48 |
49 | Reset level checkpoint
50 | JSL retry_api_reset_level_checkpoint
51 | Call this to reset the checkpoint in the current level. Entering the level again or respawning will load the main sublevel's entrance. Note that this won't reflect to SRAM until the game is saved.
52 |
53 | Inputs: N/A
54 | Outputs: N/A
55 | Preconditions: A/X/Y 8 bits
56 | Postconditions: A/X/Y 8 bits, DB/X/Y preserved
57 |
58 |
59 |
60 | Reset all checkpoints
61 | JSL retry_api_reset_all_checkpoints
62 | Call this to reset the checkpoint for every level in the game, effectively making it as if it were a fresh game. Note that this won't reflect to SRAM until the game is saved.
63 |
64 | Inputs: N/A
65 | Outputs: N/A
66 | Preconditions: N/A
67 | Postconditions: A/X/Y size preserved, DB/X/Y preserved
68 |
69 |
70 |
71 |
72 | NOTE : this routine has no effect unless !sprite_status_bar = 1
in settings_global.asm
.
73 | Call this in UberASM level init code to configure graphics for the sprite status bar items (item box, timer, coin counter, lives counter, bonus stars counter) for a specific level. Calling this will override the default settings found in settings_global.asm
, in case you want to hide some or all of the elements in some level or if you need to change their tile or palette.
74 | Each item's configuration is set with a 16 bit value $PTTT
. The first digit P
will be the item's palette, starting from palette 8 with P = 8
and ending with palette F with P = F
. TTT
will determine the tile number: you can see this in Lunar Magic's "8x8 Tile Editor" if you hover over the desired tile (more specifically, the upper left 8x8 tile of the 16x16 tile you want to use). In the bottom bar you'll see "Tile 0xYYY": then, TTT = YYY - $400
. For example, the Smiling Coin tile is "Tile 0x4C2", which results in TTT = $4C2 - $400 = $0C2
. So, for example, to reserve that tile and use palette F, the full value will be $F0C2
.
75 | If an item's value is $0000
, the item will simply not be displayed.
76 | Note that you can also just write the $PTTT
value to the RAM address for a specific item yourself, this routine is just a shorthand so set all values at the same time. To see the RAM addresses names, see RAM Info .
77 |
78 | Inputs: each item's $PTTT
value is specified, in order, after the JSL (see example)
79 | Outputs: N/A
80 | Preconditions: A/X/Y 16 bits
81 | Postconditions: A/X/Y size preserved, DB/X/Y preserved
82 | Usage (example):
83 |
84 | JSL retry_api_configure_sprite_status_bar
85 | dw $B080 ; Item box: palette B, tile 0x80
86 | dw $8088 ; Timer: palette 8, tile 0x88
87 | dw $80C2 ; Coin counter: palette 8, tile 0xC2
88 | dw $904E ; Lives counter: palette 9, tile 0x4E
89 | dw $90CE ; Bonus stars counter: palette 9, tile 0xCE
90 | ... <- your code will continue here after the JSL
91 |
92 |
93 |
94 |
95 |
96 | Get Retry type
97 | Routine to get the current Retry type, i.e. if currently the level is set to have Retry prompt, instant Retry or no Retry.
98 |
99 | Inputs: N/A
100 | Outputs: A = Retry type
101 | This value can have one of the following values:
102 |
103 | $01
: Retry prompt enabled & play the vanilla death song when the player dies
104 | $02
: Retry prompt enabled & play only the death sfx when the player dies
105 | $03
: instant Retry enabled
106 | $04
: Retry disabled
107 |
108 |
109 | Preconditions: A 8 bits
110 | Postconditions: A/X/Y size preserved, DB/X/Y preserved
111 | Usage: JSL retry_api_get_retry_type
112 |
113 |
114 |
115 | Get SRAM variable address
116 | Routine to get the address in SRAM for a specific variable. By "variable" it's meant any of the RAM addresses that are saved to SRAM specified in the sram save table. The returned address will be coherent with the current save file loaded when this routine is called (so, make sure to not call it before a save file is loaded!).
117 | This could be useful to read/write values in SRAM directly, for example if you need to update some SRAM value without the game being saved.
118 | Note that if you call this on the title screen (for example, if you need to display something based on some value saved in the three files), you will need to set $010A
to the value of the save file you want to check (0
for save file 1, 1
for save file 2, 2
for save file 3) before calling this.
119 | NOTE : this will always return "variable not found" if !sram_feature = 0
.
120 |
143 |
144 | Return to main page
145 |
146 |
147 |
--------------------------------------------------------------------------------
/docs/extra.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Retry Extra Settings - Retry System UberASM
5 |
6 |
7 |
8 |
9 |
10 |
11 | Retry Extra Settings
12 | The Retry system can be configured to run additional code at specific times when inserted into the routines available in the retry_config/extra.asm file.
13 |
14 | On SA-1 ROMs, most of these routines still run on the SNES CPU.
15 |
16 |
17 | Routine
18 | Purpose
19 |
20 |
21 | reset
22 |
23 | Called when the level is reset by the retry system or when entering from the overworld. Unlike UberASM level init routine, this won't be executed during regular level transitions.
24 |
25 |
26 |
27 | death
28 |
29 | This routine will be executed everytime the player dies.
30 |
31 |
32 |
33 | midway
34 |
35 | This routine will be called every time the player touches a midway (vanilla or custom midway object).
36 |
37 |
38 |
39 | room_checkpoint
40 |
41 | This routine will be called every time the player gets a checkpoint through a room transition.
42 | Remember you can check for $13BF
and $010B
to know in which trans/sub-level you are.
43 |
44 |
45 |
46 | prompt_exit
47 |
48 | This routine will be called every time the player selects "exit" on the retry prompt.
49 |
50 |
51 |
52 | save_file
53 |
54 | This routine will be called every time the game is saved (before anything gets saved).
55 | Remember that you can check for the current save file in $010A
.
56 | On SA-1 ROMs, this may run on either CPU, depending on what's calling the save routine.
57 |
58 |
59 |
60 | load_file
61 |
62 | This routine will be called every time an existing save file is loaded (before anything gets loaded).
63 | Remember that you can check for the current save file in $010A
.
64 |
65 |
66 |
67 | load_new_file
68 |
69 | This routine will be called every time a new save file is loaded (before anything gets reset).
70 | Remember that you can check for the current save file in $010A
.
71 |
72 |
73 |
74 | game_over
75 |
76 | This routine will be called during the game over screen.
77 | This is called after the save file data is loaded from SRAM (only the data put before .not_game_over
in retry_config/sram_tables.asm ) but before all the data is saved again to SRAM.
78 | This can be useful if you want to initialize some addresses for the game over and/or have them saved to SRAM.
79 |
80 |
81 |
82 | door_animation
83 |
84 | Called when Mario enters a door, every frame during the fade out. This could be useful since the door animation is the only one that can't be intercepted
85 | with level ASM or sprite ASM (since it immediately goes to the fading gamemode).
86 | If you need some level-specific action here, you can check the sublevel number in $010B
(16 bit).
87 | If you need to only run the code for 1 frame, you can check for $0DB0
equal to 0.
88 |
89 |
90 |
91 |
92 | All these routines are called in 8-bit A/X/Y mode and DBR is already set. Don't worry about overwriting registers, they'll be restored afterwards (except for direct page). All the routines must end with RTS
.
93 |
94 |
95 | Return to main page
96 |
97 |
98 |
--------------------------------------------------------------------------------
/docs/faq.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Frequently Asked Questions - Retry System UberASM
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 | Frequently Asked Questions
14 |
15 |
16 | Q: Can I insert this in a ROM where I've already inserted worldpeace's Retry patch?
17 | A: No, doing so will result in an error when running UberASM Tool. First, you need to remove the original patch: either try to use the Unpatcher tool (at your own risk) or port your hack over to a new ROM.
18 |
19 |
20 | Q: I noticed that you don't lose lives when dying/retrying a level. Is it possible to change that?
21 | A: Yes. If you want to disable infinite lives, you can use the !infinite_lives
global setting (see Global Settings - Quality of Life Settings ). If you want to keep infinite lives just for specific levels, you can do so using the %no_lose_lives
local setting (see Local Settings - %no_lose_lives ).
22 |
23 |
24 | Q: Can I give the player a checkpoint automatically when entering a level?
25 | A: Yes. Look at the Local Settings - %checkpoint page.
26 |
27 |
28 | Q: Can I change the prompt type in specific sublevels?
29 | A: Yes. Look at the Local Settings - %retry page.
30 |
31 |
32 | Q: I saw some hacks use a different sound effect when dying. How do I change that?
33 | A: You can do so with the !death_sfx
option in settings_global.asm (see Global Settings - SFX for details). You can also find a custom death sfx file that replicates the vanilla death music intro under amk_resources/sfx (see AddmusicK Resources for details).
34 |
35 |
36 | Q: Can I change the prompt type in specific situations (not necessarily on a sublevel basis)?
37 | A: Yes. Additionally to the effect
table, there's the !ram_prompt_override
address that, when set, will replace both the table and the default option (see retry_config/ram.asm and RAM Map ).
38 | For example, you could use it to let the player choose the prompt type as they want (you still have to implement that, though, as this only handles setting the prompt type).
39 |
Note that this address by default is never reset outside of title screen load.
40 |
41 |
42 | Q: Can I keep the Retry prompt but remove the black box?
43 | A: Yes. Look at !no_prompt_box
in retry_config/settings_global.asm . You can also remove it only under certain circumstances by setting !ram_disable_box
to 1 (for more info, see retry_config/ram.asm and RAM Map ). For example, you can do it in a Level ASM init to make a level not have the option.
44 | Note that this address by default is never reset outside of title screen load.
45 |
46 |
47 | Q: Can I keep the Retry prompt but remove the "exit" option?
48 | A: Yes. Look at !no_exit_option
in retry_config/settings_global.asm . You can also remove it only under certain circumstances by setting !ram_disable_exit
to 1 (for more info, see retry_config/ram.asm and RAM Map ). For example, you can do it in a Level ASM init to make a level not have the option.
49 | Note that this address by default is never reset outside of title screen load.
50 |
51 |
52 | Q: Can I change where the prompt is shown on the screen?
53 | A: Yes. Look at !text_x_pos
and !text_y_pos
in retry_config/settings_global.asm . For example, using !text_x_pos = $08
and !text_y_pos = $D0
will place it on the lower left corner of the screen.
54 | Additionally, you can also change it at runtime by writing to the !ram_prompt_x_pos
and !ram_prompt_y_pos
addresses (see RAM Map for more info).
55 |
Either way, if you want to change it you should disable the Retry box (either by setting !no_prompt_box = 1
or by writing to !ram_disable_box
at runtime) as its position can't be changed easily.
56 |
57 |
58 |
59 | Return to main page
60 |
61 |
62 |
63 |
--------------------------------------------------------------------------------
/docs/files.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Files - Retry System UberASM
5 |
6 |
7 |
8 |
9 |
10 |
11 | Files
12 |
13 |
14 | Contents
15 |
20 |
21 |
22 | AddmusicK Resources
23 | Inside the amk_resources folder you can find a custom a custom SFX file (amk_resources/sfx/Death Prelude.txt ) and a custom death music file (amk_resources/music/01 Miss (no intro).txt ). These can be used to keep a vanilla-feeling sound on death with Retry enabled.
24 | The SFX is the intro to the vanilla death music, and it is recommended to use as the Retry death SFX. To do so, insert it as any other SFX in AddmusicK: move the txt file inside AMK's 1DFC folder, then add it as a new entry in the Addmusic_sound effects.txt file under SFX1DFC
. To configure Retry to play this SFX on death, in settings_global.asm change !death_sfx
to the value you used in Addmusic_sound effects.txt , and set !death_sfx_addr = $1DFC
.
25 | The music file is the vanilla death jingle but with the initial part removed (the part that is played in the custom SFX provided here). This can be used as an alternative death jingle for when choosing "Exit" in the Retry prompt: normally this plays the vanilla death jingle, but it might be weird to replay the death SFX part of it, so you can insert this alternative variant in your Addmusic_list.txt and configure Retry to play that only when using "Exit". To do so, change !death_jingle_alt
in settings_global.asm to the number you inserted it as in AMK's list. Note that you shouldn't insert this as a global song.
26 |
27 |
28 |
31 |
32 | Graphics
33 | The graphic files used by Retry can be found in the retry_config/gfx folder. Note that these are uploaded dynamically to the sprite GFX pages when needed, so you don't need to insert them yourself in your GFX files, but you're free to edit them with tools like YY-CHR if you so wish (they're all 4bpp files).
34 |
35 |
36 | File
37 | Purpose
38 | Default Palette
39 |
40 |
41 | letters1.bin
42 | Retry prompt letters used in the prompt when !no_prompt_box = 0
43 | 8
44 |
45 |
46 | letters2.bin
47 | Retry prompt letters used in the prompt when !no_prompt_box = 1
48 | 8
49 |
50 |
51 | coins.bin
52 | Two 8x8 tiles used by the sprite status bar coin counters (the first is used by the coin counter, the second by the Dragon Coin counter).
53 | 8
54 |
55 |
56 | digits.bin
57 | Numbers used by the sprite status bar timer and coin counter
58 | Any
59 |
60 |
61 | indicator.bin
62 | Single 8x8 tile used by the retry indicator
63 | 9
64 |
65 |
66 | item_box_8x8.bin
67 | Single 8x8 tile used to draw the smaller Item Box
68 | B
69 |
70 |
71 | item_box_16x16.bin
72 | Four 8x8 tiles used to draw the full Item Box
73 | B
74 |
75 |
76 | timer.bin
77 | Single 8x8 tile used for the sprite status bar timer icon
78 | 8
79 |
80 |
81 | lives.bin
82 | Two 8x8 tile used for the sprite status bar lives counter icon (the first is used for Mario, the second for Luigi)
83 | 9
84 |
85 |
86 | bonus_stars.bin
87 | Single 8x8 tile used for the sprite status bar bonus stars counter icon
88 | 9
89 |
90 |
91 |
92 |
93 | Return to main page
94 |
95 |
96 |
--------------------------------------------------------------------------------
/docs/getting_started.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Getting Started - Retry System UberASM
5 |
6 |
7 |
8 |
9 |
10 |
24 |
25 | Getting Started
26 | This section will help install the Retry System for your project.
27 |
28 | Contents
29 |
35 |
36 |
37 |
38 | The first step is to download UberASM Tool , which is the tool used to insert Retry and many other resources. Note that you need to use UberASM Tool version 2.0 or higher to insert Retry.
39 |
40 |
41 | Copy Retry Files into Project
42 | Now that you have UberASM Tool, you'll need to copy the Retry files into it.
43 | Inside the main folder you can find the retry_install.bat file, which will do all the copying for you. Just double click it, and then drag and drop your UberASM Tool folder inside the terminal window that pops up. After that, the script will copy all the files in your folder, and you should see a success message. Additionally, if Retry was already present in your UberASM Tool folder, the script will backup up its files in a separate retry_old_backup folder, in case you need to port your settings from the previous version (feel free to delete this folder afterwards).
44 | If you instead want to do it manually, follow these steps:
45 |
46 | Copy the retry.asm file from the src/library folder into UberASM Tool's library folder.
47 | Copy all the files from the src/gamemode folder into UberASM Tool's gamemode folder.
48 | Copy the src/retry_config into UberASM Tool's top folder.
49 |
50 | After running the script or copying the files manually, your UberASM Tool folder structure should look like this:
51 |
52 |
UberASM Tool Folder
53 | ├─ asm
54 | ├─ gamemode
55 | │└─ retry_gm*.asm
56 | ├─ level
57 | ├─ library
58 | │└─ retry.asm
59 | ├─ other
60 | ├─ overworld
61 | ├─ retry_config
62 | ├─ retry_old_backup (only present if old Retry backed up by install script)
63 | ├─ routines (only present in UberASM Tool 2.0+)
64 | ├─ ...
65 |
66 |
67 |
68 |
69 |
70 | Insert Files with UberASM Tool
71 | Now that the Retry files are in place, you need to tell UberASM Tool to insert them in your rom.
72 |
95 |
96 |
97 | Further Steps
98 | Now Retry is inserted in your rom, so if you start a new game and die in a level, you should see the Retry prompt pop up (since it is the default configuration). To customize it, you need to edit the configuration files in the retry_config folder. When you make changes, you can just run UberASM Tool again to see them applied in the game.
99 | For more information about the customization options, check out the Configuration section.
100 |
101 | Return to main page
102 |
103 |
104 |
--------------------------------------------------------------------------------
/docs/hijack_map.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Hijack Map - Retry System UberASM
5 |
6 |
7 |
8 |
9 |
10 |
11 | Retry Hijack Map
12 | While this version of the Retry System mostly uses UberASM Tool code to run, it still requires some hijacks for some functions that cannot be achieved otherwise. These hijacks are inserted automatically when inserting UberASM Tool, and they can be removed with the provided src/retry_unpatch.asm file if you need to remove Retry from your rom (see Uninstalling Retry for details).
13 | If you're experiencing game crashes or weird problems after inserting some other patch, you can check here if there are conflicting hijacks with Retry, although that should be pretty rare compared to the old Retry patch which had much more frequent resource conflicts.
14 |
15 |
16 |
17 | Address
18 | Size
19 | Description
20 |
21 |
22 | $009E25
23 | 1
24 | Changes how many lives the save file starts with.
25 |
26 |
27 | $05B31B
28 | 2
29 | Fixes a bug where some sprite tiles disappear when closing a message box.
30 |
31 |
32 | $00D0D8
33 | 5
34 | Disables the vanilla life loss code. It is equivalent to the infinite lives patch found on SMWCentral.
35 |
36 |
37 | $008E5B
38 | 4
39 | Sets a flag used by Retry when the "hurry up" effect happens. This hijack is also used by the "Individual Dragon Coins Save" patch to check for the presence of Retry in the rom.
40 |
41 |
42 | $05DA1C
43 | 4
44 | Fixes the initial sprite facing position and the "No Yoshi Sign 2" castle intro being forced for some levels. Depending on the values of !initial_facing_fix
and !no_yoshi_intro_fix
, this may be a JML or just a hex edit.
45 |
46 |
47 | $00C572
48 | 4
49 | Fixes being able to drop the item in reserve while Mario is dead. Depending on the value of !item_box_fix
, this may be a JML or just a hex edit to restore the original code.
50 |
51 |
52 | $0DA415
53 | 4
54 |
55 | If !use_custom_midway_bar = 1
, this inserts code to handle Retry's custom midway objects.
56 | If !use_custom_midway_bar = 0
, this restores the original code (only the first time the setting is changed, and only if Objectool is present in the rom).
57 |
58 |
59 |
60 | $05D842
61 | 4
62 | Makes sure to load in the correct entrance when entering a level from the Overworld, depending on the level's last reached checkpoint.
63 |
64 |
65 | $05D9DA
66 | 4
67 | Makes sure to load in the correct entrance when loading the midway entrance of a level, depending on the sublevel's checkpoint setting.
68 |
69 |
70 | $05D9EC
71 | 4
72 | Makes sure to load Mario at the correct position when a checkpoint is a vanilla midway entrance.
73 |
74 |
75 | $05DAA3
76 | 4
77 | Fixes a bug when loading a secondary entrance in a level with a "No Yoshi Intro" from the Overworld.
78 |
79 |
80 | $008F49
81 | 4
82 |
83 | If !status_death_counter = 1
, this writes the death counter in the status bar.
84 | If !status_death_counter = 0
, it restores the original code (only the first time the setting is changed to 0).
85 |
86 |
87 |
88 | $008C89
89 | 12
90 |
91 | If !status_death_word = 1
, it changes the status bar tilemap to show "DEATHS" instead of "MARIO".
92 | If !status_death_word = 0
, it restores the original tilemap but only the first time that !status_death_counter
is changed to 0.
93 |
94 |
95 |
96 | $0081F4
97 | 3
98 |
99 | If !remove_vanilla_status_bar = 1
, disables code to draw the vanilla status bar in normal levels.
100 | If !remove_vanilla_status_bar = 0
, it restores the original code (only the first time the setting is changed to 0).
101 |
102 |
103 |
104 | $008275
105 | 5
106 |
107 | If !remove_vanilla_status_bar = 1
, disables code to enable the vanilla status bar IRQ.
108 | If !remove_vanilla_status_bar = 0
, it restores the original code (only the first time the setting is changed to 0).
109 |
110 |
111 |
112 | $0082E8
113 | 3
114 |
115 | If !remove_vanilla_status_bar = 1
, disables code to draw the vanilla status bar in mode 7 levels.
116 | If !remove_vanilla_status_bar = 0
, it restores the original code (only the first time the setting is changed to 0).
117 |
118 |
119 |
120 | $00985A
121 | 3
122 |
123 | If !remove_vanilla_status_bar = 1
, disables code to setup the initial vanilla status bar tilemap in mode 7 levels.
124 | If !remove_vanilla_status_bar = 0
, it restores the original code (only the first time the setting is changed to 0).
125 |
126 |
127 |
128 | $00A5A8
129 | 3
130 |
131 | If !remove_vanilla_status_bar = 1
, disables code to setup the initial vanilla status bar tilemap in normal levels.
132 | If !remove_vanilla_status_bar = 0
, it restores the original code (only the first time the setting is changed to 0).
133 |
134 |
135 |
136 | $00FFD8
137 | 1
138 |
139 | If !sram_feature = 1
and SA-1 is not patched, it sets the SRAM size to 8KB (unless the SRAM size was already set to a bigger size by some other patch).
140 | If !sram_feature = 0
and SA-1 is not patched, is sets the SRAM size back to 2KB (unless the SRAM size was already set to a bigger size by some other patch).
141 |
142 |
143 |
144 | $009BCB
145 | 4
146 |
147 | If !sram_feature = 1
, makes sure to save the addresses in Retry's save
table to SRAM/BW-RAM whenever the game is saved.
148 | If !sram_feature = 0
, it restores the original code (only the first time the setting is changed to 0).
149 |
150 |
151 |
152 | $009CF5
153 | 4
154 |
155 | If !sram_feature = 1
, makes sure to load the addresses in Retry's save
table from SRAM/BW-RAM whenever the save file is loaded, or to load the values in Retry's sram_default
table whenever a new save file is started.
156 | If !sram_feature = 0
, it restores the original code (only the first time the setting is changed to 0).
157 |
158 |
159 |
160 | $009856
161 | 4
162 | Makes sure some of Retry's code is run during level load for vanilla mode 7 bosses.
163 |
164 |
165 | $00F2D8
166 | 4
167 | Makes sure vanilla midways set the proper checkpoint depending on the current sublevel's settings, and prevents getting a mushroom at the midway if !midway_powerup = 0
.
168 |
169 |
170 | $0DA691
171 | 4
172 | Makes sure to spawn or not spawn the midway bar object at level load depending on the current checkpoint.
173 |
174 |
175 | $05B30E
176 | 4
177 | Fixes a bug where the switch palace message boxes sprites become glitched if drawing sprites in UberASM Tool's 2.0 "end" label.
178 |
179 |
180 |
181 | Return to main page
182 |
183 |
184 |
--------------------------------------------------------------------------------
/docs/img/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kkevinm/retry-system/4b1bea10675012a8e471574675489a8723252fb2/docs/img/icon.png
--------------------------------------------------------------------------------
/docs/img/insert_object.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kkevinm/retry-system/4b1bea10675012a8e471574675489a8723252fb2/docs/img/insert_object.png
--------------------------------------------------------------------------------
/docs/img/midway_object.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kkevinm/retry-system/4b1bea10675012a8e471574675489a8723252fb2/docs/img/midway_object.png
--------------------------------------------------------------------------------
/docs/img/multiple_midway_$00.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kkevinm/retry-system/4b1bea10675012a8e471574675489a8723252fb2/docs/img/multiple_midway_$00.png
--------------------------------------------------------------------------------
/docs/img/multiple_midway_$01.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kkevinm/retry-system/4b1bea10675012a8e471574675489a8723252fb2/docs/img/multiple_midway_$01.png
--------------------------------------------------------------------------------
/docs/img/multiple_midway_$02.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kkevinm/retry-system/4b1bea10675012a8e471574675489a8723252fb2/docs/img/multiple_midway_$02.png
--------------------------------------------------------------------------------
/docs/img/multiple_midway_$03.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kkevinm/retry-system/4b1bea10675012a8e471574675489a8723252fb2/docs/img/multiple_midway_$03.png
--------------------------------------------------------------------------------
/docs/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Readme - Retry System UberASM
5 |
6 |
7 |
8 |
9 |
10 |
11 | Retry System UberASM
12 | The Retry System is a useful patch for both Kaizo hacks and generally hard hacks, as its primary function is to enable fast level reloading to skip going to the Overworld everytime the player dies (similarly to games like Super Meat Boy).
13 | This package is a spiritual successor of the original Retry patch made by worldpeace , to expand its capabilities and to make it compatible with more resources as a consequence of it being primarily a UberASM resource.
14 |
15 |
16 | Help & Getting Started
17 | To get started using this on your project, check out the "Getting Started" page.
18 |
21 | For some helpful general information, check out the following pages.
22 |
26 | If you have additional questions or problems, you can PM me on SMW Central (Kevin ) or DM me on Discord (kkevinm
). Please make sure you have read this documentation carefully, and tried to solve the problem on your own first, before contacting me.
27 |
28 |
29 | Configuration
30 | The Retry System can be configured in a lot of ways, from basic general settings, to level specific settings, to more nuanced options for advanced users.
31 | All the configuration files you can edit can be found in the retry_config folder and include some comments on how to use them and what they can do, but you can read more in depth explanation for each file below.
32 |
39 | You can edit the files in the retry_config/code folder (which contains all the source code) to change the retry but this is not recommended unless you know exactly what you're doing.
40 |
41 |
42 | Multiple Midways
43 | The Retry system also provides for multiple level midways, both as midway objects and automatic midways on level entrance, and many more features. Read how to configure this feature at the following link.
44 |
47 |
48 |
49 | Other Information
50 | For other information, check out the following pages.
51 |
58 |
59 |
60 |
61 |
--------------------------------------------------------------------------------
/docs/midway_instruction.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Setting up Multiple Midways - Retry System UberASM
5 |
6 |
7 |
8 |
9 |
10 |
11 | Setting up Multiple Midways
12 |
13 | Inserting the Midway Bar Object in Lunar Magic
14 | While in Layer 1 or Layer 2 editing mode, open the manual object insertion window either by pressing Insert , or via the menu: Edit > Insert manual... .
15 |
16 | The custom midway object is inserted into your ROM as 2D and this value goes in the Command field of this dialog.
17 |
18 | Respawn Location
19 | To change where Mario will respawn after collecting this midway, you will set a 4-digit value in the Extension Field . The value put here will dictate the entrance type as well as either the level number or a secondary entrance number where Mario will respawn.
20 |
21 | 0000-1FFF
respawn at secondary entrance , this is just a valid 4-digit secondary entrance number (ranges 0000-1FFF)
22 | 2000-3FFF
respawn at secondary entrance with water , the value is 2000 + secondary entrance number.*
23 | 4000-41FF
respawn at main entrance, 4000 + 3-digit level number (ranges 000-1FF).
24 | 5000-51FF
respawn at midway entrance, 5000 + level number.
25 |
26 | *This is obsolete in Lunar Magic 3.00+
27 | Keep in mind some values will need leading zeroes to work correctly, e.g. respawning at secondary entrance 12C would be 012C
and not 12C
.
28 | Note: some of these settings can be used to make a midway respawn a player in any place in the game not just within the same level or connected sublevels.
29 | Once inserted, it will appear in Lunar Magic as a green square, but will appear as the normal Midway Tape object in-game.
30 |
31 |
32 |
33 | Multiple Midway Options in Retry System
34 | The retry system has a per-level configuration setting for midways (see Local settings - %checkpoint for details), which sets the behavior of midways bars and level entrances in the specified sublevel.
35 |
36 |
Using the %checkpoint
instruction in settings_local.asm you can set the midway behaviour, for each and every sublevel, with the one of following values:
37 |
38 | 0
: Vanilla behaviour. The midway bar in the corresponding sublevel will lead to the midway entrance of the main level.
39 | 1
: The midway bar in a given sublevel will lead to the midway entrance of this same sublevel (instead of the to main level).
40 | 2
: Any entrance into a sublevel, from an exit-enabled object in another level, will save as a checkpoint and respawning will lead to the corresponding entrance where the checkpoint was gathered. This does not change midway bar behaviour.
41 | 3
: This option enables both the effects of 1
(midway bar) and 2
(level entrances).
42 |
43 | Note: this setting can be used in conjunction with the midway objects detailed above.
44 |
45 | Examples
46 |
47 |
48 |
49 |
50 |
51 | Return to main page
52 |
53 |
54 |
--------------------------------------------------------------------------------
/docs/objectool_info.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | ObjecTool Information - Retry System UberASM
6 |
7 |
8 |
9 |
10 |
11 |
12 | ObjecTool Information
13 | If you want to insert custom objects using the ObjecTool patch, and you're using Retry's Custom Midway Object feature (!use_custom_midway_bar = 1
in the settings) you'll need to make an edit before inserting the patch.
14 | Open objectool.asm and remove these lines (they're towards the top of the file):
15 |
16 |
17 | org $0DA415|!bank ; x6A615 (hijack normal object loading routine)
18 | autoclean JML NewNormObjects ; E2 30 AD 31 19
19 | NOP ;
20 |
21 |
22 | After doing this, just patch objectool.asm .
23 |
24 | One thing to keep in mind is that Retry will use slots 00-41 and 50-51 of the Custom Normal Objects (i.e., objects with id 2D) for its custom midway bars, meaning that you can't use them in ObjecTool.
25 | You're free to use Custom Normal Objects 42-4F and 52-FF , as well as all Custom Extended Objects available.
26 |
27 | Additionally, if you want to remove Retry's custom midway bar while keeping ObjecTool, you'll need to place back the code that you removed in objectool.asm (and make sure you run Retry with !use_custom_midway_bar = 0
).
28 | Return to main page
29 |
30 |
31 |
--------------------------------------------------------------------------------
/docs/settings_local.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Local Settings - Retry System UberASM
5 |
6 |
7 |
8 |
9 |
10 |
11 | Local Retry Settings
12 | Local settings are those Retry options that can be configured on a level-specific basis. These options must be inserted in the retry_config/settings_local.asm
file. If you used older version of Retry, these are equivalent to the various tables you had to change the values of, but made simpler by not having to manage big tables of hex data.
13 | If you still prefer the table approach, you can set !use_legacy_tables = 1
in settings_global.asm
and edit the tables in legacy/tables.asm
as you're used to. In this case, ignore this document and the settings_local.asm
file.
14 |
15 |
16 | Overview
17 | This approach of configuring the level-specific settings uses instructions that enable some setting for a specified level number. Each instruction must be put on a separate line in the asm file.
18 | There are various instruction types, but most times you'll probably only use one or two of them for any given level, if any.
19 | The instruction types are the following:
20 |
21 |
22 | %checkpoint(level, value)
23 | %retry(level, value)
24 | %checkpoint_retry(level, checkpoint, retry)
25 | %sfx_echo(level)
26 | %no_reset_rng(level)
27 | %no_room_cp_sfx(level)
28 | %no_lose_lives(level)
29 | %settings(level, checkpoint, retry, sfx_echo, no_reset_rng, no_room_cp_sfx, no_lose_lives)
30 |
31 |
32 |
33 | %checkpoint(level, value)
34 | This allows you to configure the checkpoint behavior for the specified level. value
can have one of the following values:
35 |
36 | 0
: vanilla checkpoint. The midway bar in the corresponding sublevel will lead to the midway entrance of the main level.
37 | 1
: the midway bar in the corresponding sublevel will lead to the midway entrance of the sublevel.
38 | 2
: any main/secondary/midway entrance through door/pipe/etc. whose destination is the corresponding sublevel will trigger a checkpoint like midway bars, and the checkpoint will lead to this entrance.
39 | 3
: this enables both the effects of 1
and 2
.
40 |
41 | If this option isn't specified for a level, then it will default to 0
(vanilla checkpoint behavior).
42 | Examples:
43 |
44 | %checkpoint($105,2)
: sublevel $105 will have automatic checkpoints on any entrance to it.
45 | %checkpoint($025,3)
: sublevel $025 will have automatic checkpoints on any entrance to it and its midway will lead to sublevel $025's midway entrance instead of the main level's midway entrance.
46 |
47 | Note that you can also use custom midway objects (that look like vanilla midway bars) to have multiple midways. See Custom Midway Instructions for more information.
48 |
49 |
50 | %retry(level, value)
51 | This allows to override the Retry type for the specified level. value
can have one of the following values:
52 |
53 | 0
: follow the global setting (!default_prompt_type
in settings_global.asm
).
54 | 1
: enable Retry prompt and play the death jingle when the player dies. Recommended if you want the music to restart on each death.
55 | 2
: enable Retry prompt and only play the death sfx when the player dies (music won't be interrupted).
56 | 3
: enable instant Retry and only play only the deaht sfx (the fastest option, as if "Retry" is chosen automatically in the Retry prompt).
57 | 4
: Retry disabled (as if "Exit" is chosen automatically in the Retry prompt). Use this to have the vanilla death sequence.
58 |
59 | If this option isn't specified for a level, then it will default to 0
(follow the global setting).
60 | Examples:
61 |
62 | %retry($001,2)
: sublevel $001 will have Retry prompt with death sfx.
63 | %retry($069,3)
: sublevel $069 will have instant Retry.
64 | %retry($1FF,4)
: sublevel $1FF will have no Retry.
65 |
66 |
67 |
68 | %checkpoint_retry(level, checkpoint, retry)
69 | This is a shorthand to configure the checkpoint and Retry type for a level with the same instruction. checkpoint
follows the %checkpoint
format and retry
follows the %retry
format.
70 | Examples:
71 |
72 | %checkpoint_retry($101,1,1)
: sublevel $101 will have the sublevel midway bar behavior and Retry prompt with death jingle.
73 | %checkpoint_retry($102,2,0)
: sublevel $102 will have automatic checkpoints on entrance and follow the global Retry setting.
74 |
75 |
76 |
77 | %sfx_echo(level)
78 | This will enable SFX echo in the specified sublevel. Note that this option only works if AddmusicK is used in the ROM, and the SFX uses the same echo as the music (if the music has no echo, then the SFX also won't have echo).
79 | Examples:
80 |
81 | %sfx_echo($105)
: sublevel $105 will have SFX echo enabled.
82 |
83 |
84 |
85 | %no_reset_rng(level)
86 | Normally Retry resets the RNG seed every time a level is reloaded, to make setups consistent between deaths. Using this option will make the RNG not reset when retrying in this sublevel.
87 | Examples:
88 |
89 | %no_reset_rng($105)
: sublevel $105 won't have the RNG reset when reloading it with Retry.
90 |
91 |
92 |
93 | %no_room_cp_sfx(level)
94 | If a level uses the checkpoint type 2
or 3
, then a SFX is played when the automatic checkpoint is triggered (the SFX is defined by !room_cp_sfx
in settings_global.asm
).
95 | If you use this, then the automatic checkpoints in the specified sublevel won't have any SFX. If !room_cp_sfx = 0
, you can ignore this.
96 | Examples:
97 |
98 | %no_room_cp_sfx($105)
: sublevel $105 won't have any SFX when getting an entrance checkpoint.
99 |
100 |
101 |
102 | %no_lose_lives(level)
103 | If infinite lives is disabled (!infinite_lives = 0
in settings_global.asm
), you can prevent life loss in specific sublevels using this option (for example for tutorial rooms or cutscenes).
104 | If !infinite_lives = 1
, you can ignore this.
105 | Examples:
106 |
107 | %no_lose_lives($105)
: dying in sublevel $105 won't reduce lives.
108 |
109 |
110 |
111 | %settings(level, checkpoint, retry, sfx_echo, no_reset_rng, no_room_cp_sfx, no_lose_lives)
112 | This is a shorthand to configure all the settings for the specified level at the same time.
113 | The arguments are:
114 |
115 | level
: the sublevel number.
116 | checkpoint
: same as value
in %checkpoint
.
117 | retry
: same as value
in %retry
.
118 | sfx_echo
: if 0
, SFX echo is disabled in the sublevel. Otherwise, it is enabled.
119 | no_reset_rng
: if 0
, RNG is reset when retrying in the sublevel. Otherwise, it is not reset.
120 | no_room_cp_sfx
: if 0
, automatic checkpoints in the sublevel will play the SFX. Otherwise, they won't play the SFX.
121 | no_lose_lives
: if 0
, life loss is enabled in the sublevel (if infinite lives is disabled globally). Otherwise, it is disabled.
122 |
123 |
124 | Return to main page
125 |
126 |
127 |
--------------------------------------------------------------------------------
/docs/sram_bwram_info.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | SRAM & BW-RAM Information - Retry System UberASM
5 |
6 |
7 |
8 |
9 |
10 |
11 | SRAM & BW-RAM Information
12 |
13 | As the standard Retry patch, this Retry includes a built-in SRAM expansion patch that's used by default to save the custom checkpoints and death counter. Differently from the normal Retry, the patch also works on SA-1 (using BW-RAM instead of SRAM, but the result is the same), so this can be effectively used as an alternative to the SRAM/BW-RAM Plus patch and the likes.
14 | If you've already patched SRAM/BW-RAM Plus, this feature will be turned off automatically (they can't coexist). Unlike SRAM Plus, this patch should also work on SNES Classic, so you should use it if you care about compatibility with that console. Also, the maximum amount of bytes you can save per save file is 2389 bytes.
15 |
16 | Q: How do I add my own addresses to the save tables?
17 |
18 | Open retry_config/sram_tables.asm and go to the save
table. There, you can add your own addresses to save (more info in the file). Similarly to SRAM/BW-RAM Plus, for each address you put in the table, you also need to specify its default value(s) for when a new save file is loaded in the sram_defaults
tables.
19 |
20 | Some examples of addresses that may be useful (you can find more at SMW Central's RAM Map ):
21 |
22 |
23 | ; 1-UP checkpoints flags.
24 | dl $7E1F3C : dw 12 ; $401F3C on SA-1.
25 |
26 | ; 5 Dragon Coins collected flags.
27 | dl $7E1F2F : dw 12 ; $401F2F on SA-1.
28 |
29 | ; Individual Dragon Coin Save patch tables. If you use that patch, you should include these.
30 | dl $7E1F2F : dw 12 ; $401F2F on SA-1.
31 | dl $7FA660 : dw $0300 ; $40A660 on SA-1.
32 |
33 |
34 | (For all of these, the default values need to be all $00).
35 |
36 | Q: I'm using SRAM/BW-RAM Plus and I want to save Retry's stuff with them. How do I do it?
37 | A: If you really need to use those, then you can add these to the sram_table
/bw_ram_table
:
38 |
39 |
40 | dl !ram_checkpoint : dw 192
41 | dl !ram_death_counter : dw 5
42 |
43 |
44 | Note: to have the Retry ram defines available in the patch, copy the contents of retry_config/ram.asm at the top of the SRAM+/BW-RAM+ table file. Also, if you're not using the death counter, you can omit the second line.
45 |
46 | Then add these tables to the sram_defaults
/bw_ram_defaults
:
47 |
48 |
49 | ; Checkpoints.
50 | dw $0000,$0001,$0002,$0003,$0004,$0005,$0006,$0007
51 | dw $0008,$0009,$000A,$000B,$000C,$000D,$000E,$000F
52 | dw $0010,$0011,$0012,$0013,$0014,$0015,$0016,$0017
53 | dw $0018,$0019,$001A,$001B,$001C,$001D,$001E,$001F
54 | dw $0020,$0021,$0022,$0023,$0024,$0101,$0102,$0103
55 | dw $0104,$0105,$0106,$0107,$0108,$0109,$010A,$010B
56 | dw $010C,$010D,$010E,$010F,$0110,$0111,$0112,$0113
57 | dw $0114,$0115,$0116,$0117,$0118,$0119,$011A,$011B
58 | dw $011C,$011D,$011E,$011F,$0120,$0121,$0122,$0123
59 | dw $0124,$0125,$0126,$0127,$0128,$0129,$012A,$012B
60 | dw $012C,$012D,$012E,$012F,$0130,$0131,$0132,$0133
61 | dw $0134,$0135,$0136,$0137,$0138,$0139,$013A,$013B
62 |
63 | ; Death counter.
64 | db $00,$00,$00,$00,$00
65 |
66 |
67 | Note: if you omitted the death counter in the previous table, then do it here too.
68 |
69 | Return to main page
70 |
71 |
72 |
--------------------------------------------------------------------------------
/docs/sram_tables.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Save & SRAM Tables - Retry System UberASM
5 |
6 |
7 |
8 |
9 |
10 |
11 | Save & SRAM Tables
12 | The Retry System has a built-in saving system. You can configure what addresses it saves by editing two tables in retry_config/sram_tables.asm .
13 | Save (SRAM) Table
14 | This table can be used to save custom values to SRAM, so they can persist when the console is turned off. By default it saves the custom checkpoint ram (so multiple midways will save properly) and the death counter.
15 |
16 | save:
17 | dl !ram_checkpoint : dw 192
18 | ; Feel free to add your own stuff here.
19 |
20 | .not_game_over:
21 | dl !ram_death_counter : dw 5
22 | ; Feel free to add your own stuff here.
23 |
24 | Each line is formatted as follows:
25 |
26 | dl $XXXXXX : dw $YYYY
27 |
28 | Where $XXXXXX
is what RAM address to save. Make sure it's always 3 bytes long (i.e. use $7E0019 instead of $19 or $0019) and $YYYY
is how many bytes to save at that address (remove the $ to use a decimal value).
29 | For example, adding dl $7E1F3C : dw 12
will make the 1-Up checkpoints for all levels save. Make sure to always put a colon between the two elements!
30 | The addresses you put under .not_game_over
will be saved like usual, but they won't be reloaded from SRAM when getting a game over. This can be useful if you want some things to retain even if the player got a game over before being able to save them.
31 |
32 |
33 | New Save Table
34 | Here you specify the "default" values of the addresses you want to save, for when a new save file is started.
35 |
36 | sram_defaults:
37 | ; Default checkpoint values (don't edit this!).
38 | dw $0000,$0001,$0002,$0003,$0004,$0005,$0006,$0007
39 | dw $0008,$0009,$000A,$000B,$000C,$000D,$000E,$000F
40 | dw $0010,$0011,$0012,$0013,$0014,$0015,$0016,$0017
41 | dw $0018,$0019,$001A,$001B,$001C,$001D,$001E,$001F
42 | dw $0020,$0021,$0022,$0023,$0024,$0101,$0102,$0103
43 | dw $0104,$0105,$0106,$0107,$0108,$0109,$010A,$010B
44 | dw $010C,$010D,$010E,$010F,$0110,$0111,$0112,$0113
45 | dw $0114,$0115,$0116,$0117,$0118,$0119,$011A,$011B
46 | dw $011C,$011D,$011E,$011F,$0120,$0121,$0122,$0123
47 | dw $0124,$0125,$0126,$0127,$0128,$0129,$012A,$012B
48 | dw $012C,$012D,$012E,$012F,$0130,$0131,$0132,$0133
49 | dw $0134,$0135,$0136,$0137,$0138,$0139,$013A,$013B
50 | ; Feel free to add your own stuff here.
51 |
52 | .not_game_over:
53 | ; Initial death counter value (don't edit this!).
54 | db $00,$00,$00,$00,$00
55 |
56 | ; Feel free to add your own stuff here.
57 |
58 |
59 | You can do db $XX,$XX,...
for 1 byte values, dw $XXXX,$XXXX,...
for 2 bytes values and dl $XXXXXX,$XXXXXX,...
for 3 bytes values.
60 | The amount of values of each entry should correspond to the dw $YYYY
value in the save table (for example, the checkpoint values are 192, and the death counter values are 5).
61 | Remember, if you have some addresses after .not_game_over
in the save:
table, put their default values after .not_game_over
here also, in the same order.
62 |
63 |
64 |
65 | Notes
66 |
67 | For each address you add to save:
table, you need to add the default values in the sram_defaults:
table below.
68 | If using SA-1, for addresses in $7E0000-$7E1FFF
you must change the bank to $40 ($400000-$401FFF
). Additionally, a lot of other addresses might be remapped to different locations (see SA-1 docs for more info).
69 | If using FastROM, using $000000-$001FFF
instead of $7E0000-$7E1FFF
will make the save/load process a bit faster.
70 |
71 |
72 |
73 | Return to main page
74 |
75 |
76 |
--------------------------------------------------------------------------------
/docs/style.css:
--------------------------------------------------------------------------------
1 | body {
2 | max-width: 800px;
3 | margin: 0 auto;
4 | padding: 2em;
5 | padding-bottom: 4em;
6 | font-family: Arial, sans-serif;
7 | font-size: 1em;
8 | }
9 | body.wide {
10 | max-width: 1024px;
11 | }
12 |
13 | p, li, th, td {
14 | line-height: 140%;
15 | }
16 |
17 |
18 | pre {
19 | font-size: 1.09em;
20 | padding: 8px 16px;
21 | background: rgba(0, 0, 0, 0.05);
22 | color: rgba(0, 0, 0, 0.6);
23 | border-radius: 3px;
24 | user-select: all;
25 | line-height: 1.3;
26 | }
27 |
28 | u.dir,
29 | code {
30 | font-size: 1.09em;
31 | padding: 2px 3px;
32 | background: rgba(0,0,0,.05);
33 | border-radius: 2px;
34 | }
35 |
36 | u.dir {
37 | text-decoration: none;
38 | font-family: monospace;
39 | }
40 |
41 | blockquote {
42 | font-style: italic;
43 | }
44 | table {
45 | width: 100%;
46 | margin: 1em 0;
47 | border-collapse: collapse;
48 | text-align: center;
49 | }
50 | th {
51 | background-color: rgba(0,0,0,.05);
52 | font-size: 0.93em;
53 | }
54 | td,th {
55 | border: 1px solid rgba(0,0,0,.15);
56 | padding: 4px 8px;
57 | }
58 | td.has-table > table {
59 | margin-bottom: 0;
60 | }
61 |
62 | .left-align {
63 | text-align: left;
64 | }
65 |
66 | .right-align {
67 | text-align: right;
68 | }
69 |
70 | .center-align {
71 | text-align: center;
72 | }
73 |
74 | img {
75 | margin: 20px auto;
76 | max-width: 800px;
77 | display: block;
78 | }
79 |
80 | ul li {
81 | margin: 4px 0;
82 | }
83 |
84 | hr {
85 | background: rgba(0,0,0,.1);
86 | height: 1px;
87 | border: none;
88 | margin: 2em 0;
89 | }
90 |
--------------------------------------------------------------------------------
/docs/troubleshooting.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Troubleshooting - Retry System UberASM
5 |
6 |
7 |
8 |
9 |
10 |
11 | Troubleshooting
12 |
13 |
14 | Q: I applied a FG gradient code, and it appears above the Retry prompt as well!
15 | A: You need to make a slight edit to the HDMA code. You should see something like this:
16 |
17 |
18 | LDA #$17
19 | STA $212C
20 | LDA #$00
21 | STA $212E
22 |
23 |
24 | Change that to:
25 |
26 |
27 | LDA #$17
28 | STA $212C
29 | LDA #$17 ;<- change here
30 | STA $212E
31 |
32 |
33 |
34 |
35 | Q: I'm making the music in a level fade out using the following code (with AddmusicK) but the music doesn't reload when dying!
36 |
37 |
38 | LDA #$FF
39 | STA $1DFB|!addr
40 |
41 |
42 | A: You want to also store #$FF
to $0DDA
, like this:
43 |
44 |
45 | LDA #$FF
46 | STA $1DFB|!addr
47 | STA $0DDA|!addr ;<- change here
48 |
49 |
50 |
51 | Q: When dying after getting the goal post or beating a boss, the music doesn't restart when respawning!
52 | A: One common cause for this is a bug with AddmusicK that happens when you change certain songs to #$00
in the asm/tweaks.asm (or asm/UserDefines.asm ) file, specifically: !Miss
, !BossClear
, !StageClear
, !Keyhole
or !IrisOut
(maybe also !SwitchPalace
, !RescueEgg
and !StaffRoll
). This can cause issues like the one mentioned here or the P-Switch/Star timers acting weirdly when activated
53 | To fix this, open AMK's asm/SNES/patch.asm file and remove all instances of codes like this:
54 |
55 |
56 | CMP !SongThatYouChangedTo0
57 | BEQ Something
58 |
59 |
60 | For example, if you changed !IrisOut
to #$00
, then you'd remove these codes (you can CTRL+F !IrisOut
to find all instances in the file):
61 |
62 |
63 | CMP !IrisOut
64 | BEQ ++
65 |
66 |
67 | CMP !IrisOut
68 | BEQ LevelEndMusicChange
69 |
70 |
71 | CMP !IrisOut
72 | BEQ Okay
73 |
74 |
75 | Run AddmusicK after applying the changes and the issue should be fixed. If it still happens but you didn't change the tweaks/UserDefines file, then DM me the issue.
76 |
77 |
78 | Q: I'm using the "Single Screen" UberASM code, and sprites keep moving while Mario is dead!
79 | A: To fix, add this code at the very start of the Single Screen's main code:
80 |
81 |
82 | LDA $71
83 | CMP #$09
84 | BNE +
85 | RTL
86 | +
87 |
88 |
89 |
90 |
91 | Q: When I enter a level from the overworld, it brings me to the bonus game!
92 | A: After inserting Retry for the first time, don't load a save state that you made before inserting it and make sure to start from a new save file.
93 |
94 |
95 | Q: I use a custom midway block/sprite, but it doesn't seem to work!
96 | By default Retry only works with the vanilla midway tile, but it's fairly straightforward to make it work with your own blocks/sprites. Retry has a specific RAM address that can be used to set the midway in the current level (according to the checkpoint
setting in retry_config/settings_local.asm ). The address is !ram_set_checkpoint
to have it always available in sprites/blocks, you can copy the contents of "ram.asm" into PIXI's asm/sa1def.asm , GPS's defines.asm and UberASM Tool's other/macro_library.asm .
97 | The system works as follows: if you set the low byte (!ram_set_checkpoint
) to #$00
, it will trigger the current level's midway. If the checkpoint table for this sublevel is 0, it means it will give you the midway for the main level. While if it's 2 or 3, it will give you the midway for the current sublevel.
98 | You can also set a completely custom entrance for the checkpoint, similarly to how Retry's custom midway objects work. To do this, you need to set the entire 16 bit address (!ram_set_checkpoint
and !ram_set_checkpoint+1
) to the entrance value you want to use. This value follows the format of $7E19B8 and $7E19D8 (where $7E19B8 should go in the first byte of the address, $7E19D8 in the second). For more info, check those addresses in SMWCentral's RAM Map. In practice, your midway block sprite should have a piece of code like this, to set the vanilla midway:
99 |
100 |
101 |
102 | LDA #$01
103 | STA $13CE
104 |
105 |
106 | To add multiple midway support, you'd just need to add this after it:
107 |
108 |
109 | LDA #$00
110 | STA !ram_set_checkpoint
111 |
112 |
113 | To make the midway take you to an arbitrary entrance, you need to set a different value depending on what entrance it is. For example, to make it use secondary exit number $0169, you'd use this code:
114 |
115 |
116 | REP #$20
117 | LDA #$0169 ; Secondary exit number.
118 | ORA #$0200 ; Set the "secondary exit" bit in the high byte (like $7E19D8).
119 | STA !ram_set_checkpoint
120 | SEP #$20
121 |
122 |
123 | Additionally, you can also reset the current level's checkpoint by setting !ram_set_checkpoint to #$80. This will respawn Mario in the current level's main entrance when dying.
124 |
125 |
126 | if !save_on_checkpoint = 1, using this method will also make the game save.
127 | if using the "Individual Dragon Coins Save" patch, using this method will also make the current Dragon Coins save (when !Midpoint = 1 in that patch).
128 | this address is only checked while in a level, but you can also set it in other situations (in this case, the checkpoint will be registered the first time a level is entered).
129 |
130 |
131 |
132 | Q: I patched the 32x32 Player Tilemap patch / lx5's Custom Powerups / lx5's Dynamic Spriteset System (DSS) / DKCR Status Bar (or other sprite status bars) and I get glitched graphics when dying! What do I do?
133 | A: Those patches have a high chance of using the same spots in SP1 for their dynamic tiles as the Retry prompt. To fix it, open retry_config/settings_global.asm and towards the bottom you'll see a bunch of !tile_...
defines. You need to edit some of those to other free spots in SP1 that aren't used by other patches.
134 |
135 |
136 | Q: I'm using !prompt_freeze = 0 to make sprites move while Mario is dead, but it also causes autoscrollers to keep going. How do I stop them?
137 | A: vanilla autoscrollers should already stop when dying with this options turned on, while custom autoscrollers need to be handled on a case-by-case basis by adding a check for Mario's state. This is usually simple to fix by adding a code like this at the beginning of your custom autoscroller's main code:
138 |
139 |
140 | LDA $71
141 | CMP #$09
142 | BNE .run
143 | RTL
144 | .run:
145 |
146 |
147 | (if your autoscroller code is in a routine that ends with RTS, use RTS instead of RTL before .run
).
148 |
149 | Return to main page
150 |
151 |
152 |
--------------------------------------------------------------------------------
/docs/uninstall.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Uninstall - Retry System UberASM
5 |
6 |
7 |
8 |
9 |
10 |
11 | Uninstalling Retry
12 | If you wish to uninstall the Retry System, and you're not using a tool like Callisto that can rebuild the rom from scratch easily, it is easy to do following these steps:
13 |
14 | Delete the retry.asm file from UberASM Tool's library folder.
15 | Delete all the retry_gmXX.asm files from UberASM Tool's gamemode folder.
16 | Delete the retry_config folder from UberASM Tool's top folder.
17 | In UberASM Tool's list.txt file, remove all the lines with retry_gmXX.asm under gamemode: .
18 | Run UberASM Tool.
19 | Patch the retry_unpatch.asm file found in the src folder using Asar .
20 |
21 | Return to main page
22 |
23 |
24 |
--------------------------------------------------------------------------------
/retry_install.bat:
--------------------------------------------------------------------------------
1 | @echo off
2 | setlocal EnableDelayedExpansion
3 |
4 | set /p uber_folder="UberASM Tool folder where to install: "
5 | set uber_folder=!uber_folder:"=!
6 | set retry_folder=.\src
7 |
8 | echo.
9 |
10 | if exist "!retry_folder!\gamemode" if exist "!retry_folder!\library" if exist "!retry_folder!\retry_config" (
11 | goto :retry_exist
12 | )
13 |
14 | set /p retry_folder="Retry src folder to install: "
15 | set retry_folder=!retry_folder:"=!
16 |
17 | if not exist "!retry_folder!" (
18 | echo Error: !retry_folder! does not exist^^!
19 | goto :end
20 | )
21 |
22 | if exist "!retry_folder!\gamemode" if exist "!retry_folder!\library" if exist "!retry_folder!\retry_config" (
23 | goto :retry_exist
24 | )
25 |
26 | echo Error: !retry_folder! is not a Retry src folder^^!
27 | goto :end
28 |
29 | :retry_exist
30 |
31 | set backup_folder=retry_old_backup
32 |
33 | if not exist "!uber_folder!" (
34 | echo Error: !uber_folder! does not exist^^!
35 | goto :end
36 | )
37 |
38 | if exist "!uber_folder!\gamemode" if exist "!uber_folder!\library" if exist "!uber_folder!\list.txt" (
39 | goto :ok
40 | )
41 | echo Error: !uber_folder! is not a UberASM Tool folder^^!
42 | goto :end
43 |
44 | :ok
45 |
46 | if exist "!uber_folder!\gamemode\retry_gm*.asm" (
47 | goto :backup_old
48 | )
49 | if exist "!uber_folder!\library\retry.asm" (
50 | goto :backup_old
51 | )
52 | if exist "!uber_folder!\retry_config" (
53 | goto :backup_old
54 | )
55 |
56 | :install
57 |
58 | echo.
59 | echo Installing Retry...
60 |
61 | copy "!retry_folder!\gamemode\retry_gm*.asm" "!uber_folder!\gamemode" > nul
62 | copy "!retry_folder!\library\retry.asm" "!uber_folder!\library" > nul
63 | mkdir "!uber_folder!\retry_config" > nul
64 | xcopy /e /v "!retry_folder!\retry_config" "!uber_folder!\retry_config" > nul
65 |
66 | echo.
67 | echo Retry files copied successfully^^!
68 |
69 | echo.
70 | echo To complete the installation, copy these lines in your "list.txt" under gamemode:
71 | echo.
72 | echo 00 retry_gm00.asm
73 | echo 06 retry_gm06.asm
74 | echo 07 retry_gm07.asm
75 | echo 0C retry_gm0C.asm
76 | echo 0D retry_gm0D.asm
77 | echo 0F retry_gm0F.asm
78 | echo 10 retry_gm10.asm
79 | echo 11 retry_gm11.asm
80 | echo 12 retry_gm12.asm
81 | echo 13 retry_gm13.asm
82 | echo 14 retry_gm14.asm
83 | echo 15 retry_gm15.asm
84 | echo 16 retry_gm16.asm
85 | echo 19 retry_gm19.asm
86 |
87 | goto :end
88 |
89 | :backup_old
90 |
91 | echo Previous Retry installation found. Backing up old version...
92 |
93 | if exist "!uber_folder!\!backup_folder!" (
94 | echo.
95 | echo Warning: old Retry backup found^^!
96 | echo If you wish to continue the installation, the old backup will be removed and replaced with the current Retry backup.
97 | set /p delete_backup_confirm="Continue? [y/n] "
98 | set delete_backup_confirm=!delete_backup_confirm:"=!
99 |
100 | if "!delete_backup_confirm!"=="y" (
101 | goto :remove_old
102 | )
103 | if "!delete_backup_confirm!"=="Y" (
104 | goto :remove_old
105 | )
106 | echo.
107 | echo Installation aborted.
108 | goto :end
109 |
110 | :remove_old
111 | rmdir /s /q "!uber_folder!\!backup_folder!" > nul
112 |
113 | echo.
114 | echo Old backup deleted successfully
115 | )
116 |
117 | mkdir "!uber_folder!\!backup_folder!" > nul
118 |
119 | if exist "!uber_folder!\gamemode\retry_gm*.asm" (
120 | mkdir "!uber_folder!\!backup_folder!\gamemode" > nul
121 | copy "!uber_folder!\gamemode\retry_gm*.asm" "!uber_folder!\!backup_folder!\gamemode" > nul
122 | del "!uber_folder!\gamemode\retry_gm*.asm" > nul
123 | )
124 |
125 | if exist "!uber_folder!\library\retry.asm" (
126 | mkdir "!uber_folder!\!backup_folder!\library" > nul
127 | copy "!uber_folder!\library\retry.asm" "!uber_folder!\!backup_folder!\library" > nul
128 | del "!uber_folder!\library\retry.asm" > nul
129 | )
130 |
131 | if exist "!uber_folder!\retry_config" (
132 | mkdir "!uber_folder!\!backup_folder!\retry_config" > nul
133 | xcopy /e /v "!uber_folder!\retry_config" "!uber_folder!\!backup_folder!\retry_config" > nul
134 | rmdir /s /q "!uber_folder!\retry_config" > nul
135 | )
136 |
137 | echo.
138 | echo Previous version backed up at !uber_folder!\!backup_folder!
139 |
140 | goto :install
141 |
142 | :end
143 |
144 | echo.
145 |
146 | pause
147 |
--------------------------------------------------------------------------------
/src/gamemode/retry_gm00.asm:
--------------------------------------------------------------------------------
1 | init:
2 | jsl retry_startup_init
3 | rtl
4 |
--------------------------------------------------------------------------------
/src/gamemode/retry_gm06.asm:
--------------------------------------------------------------------------------
1 | init:
2 | jsl retry_level_init_3_init
3 | rtl
4 |
5 | main:
6 | jsl retry_level_init_3_main
7 | rtl
8 |
--------------------------------------------------------------------------------
/src/gamemode/retry_gm07.asm:
--------------------------------------------------------------------------------
1 | main:
2 | jsl retry_in_level_main
3 | rtl
4 |
5 | end:
6 | jsl retry_in_level_end
7 | rtl
8 |
--------------------------------------------------------------------------------
/src/gamemode/retry_gm0C.asm:
--------------------------------------------------------------------------------
1 | init:
2 | jsl retry_load_overworld_init
3 | rtl
4 |
--------------------------------------------------------------------------------
/src/gamemode/retry_gm0D.asm:
--------------------------------------------------------------------------------
1 | init:
2 | jsl retry_fade_to_overworld_init
3 | rtl
4 |
--------------------------------------------------------------------------------
/src/gamemode/retry_gm0F.asm:
--------------------------------------------------------------------------------
1 | init:
2 | jsl retry_fade_to_level_init
3 | rtl
4 |
5 | main:
6 | jsl retry_fade_to_level_main
7 | rtl
8 |
--------------------------------------------------------------------------------
/src/gamemode/retry_gm10.asm:
--------------------------------------------------------------------------------
1 | init:
2 | jsl retry_level_transition_init
3 | rtl
4 |
--------------------------------------------------------------------------------
/src/gamemode/retry_gm11.asm:
--------------------------------------------------------------------------------
1 | init:
2 | jsl retry_level_init_1_init
3 | jsl retry_level_transition_init
4 | rtl
5 |
--------------------------------------------------------------------------------
/src/gamemode/retry_gm12.asm:
--------------------------------------------------------------------------------
1 | init:
2 | jsl retry_level_init_2_init
3 | rtl
4 |
--------------------------------------------------------------------------------
/src/gamemode/retry_gm13.asm:
--------------------------------------------------------------------------------
1 | init:
2 | jsl retry_level_init_3_init
3 | rtl
4 |
5 | main:
6 | jsl retry_level_init_3_main
7 | rtl
8 |
--------------------------------------------------------------------------------
/src/gamemode/retry_gm14.asm:
--------------------------------------------------------------------------------
1 | main:
2 | jsl retry_in_level_main
3 | rtl
4 |
5 | nmi:
6 | jsl retry_nmi_level
7 | rtl
8 |
9 | end:
10 | jsl retry_in_level_end
11 | rtl
12 |
--------------------------------------------------------------------------------
/src/gamemode/retry_gm15.asm:
--------------------------------------------------------------------------------
1 | init:
2 | jsl retry_time_up_init
3 | rtl
4 |
--------------------------------------------------------------------------------
/src/gamemode/retry_gm16.asm:
--------------------------------------------------------------------------------
1 | init:
2 | jsl retry_level_transition_init
3 | jsl retry_game_over_init
4 | rtl
5 |
--------------------------------------------------------------------------------
/src/gamemode/retry_gm19.asm:
--------------------------------------------------------------------------------
1 | init:
2 | jsl retry_level_transition_init
3 | rtl
4 |
--------------------------------------------------------------------------------
/src/library/retry.asm:
--------------------------------------------------------------------------------
1 | namespace nested off
2 |
3 | ; Macros to load files easily.
4 | macro incsrc(folder,file)
5 | namespace
6 | incsrc "../retry_config//.asm"
7 | namespace off
8 | endmacro
9 |
10 | macro incbin(folder,file)
11 | incbin "../retry_config//.bin"
12 | endmacro
13 |
14 | ;=====================================
15 | ; Load shared settings and defines.
16 | ;=====================================
17 | %incsrc(code/include,misc)
18 | %incsrc(code/include,rom)
19 | %incsrc("",ram)
20 | %incsrc("",settings_global)
21 |
22 | ;=====================================
23 | ; Check incompatibilities.
24 | ;=====================================
25 | %incsrc(code,check_incompatibilities)
26 |
27 | ;=====================================
28 | ; Load the Retry tables.
29 | ;=====================================
30 | if !use_legacy_tables
31 | %incsrc(legacy,tables)
32 | else
33 | %incsrc(code/include,tables)
34 | %incsrc("",settings_local)
35 | endif
36 | if !sram_feature
37 | %incsrc("",sram_tables)
38 | endif
39 |
40 | ;=====================================
41 | ; Load the letters gfx.
42 | ;=====================================
43 | retry_gfx:
44 | .box:
45 | %incbin(gfx,letters1)
46 | .no_box:
47 | %incbin(gfx,letters2)
48 | if !sprite_status_bar
49 | .digits:
50 | %incbin(gfx,digits)
51 | .coins:
52 | %incbin(gfx,coins)
53 | .timer:
54 | %incbin(gfx,timer)
55 | .lives:
56 | %incbin(gfx,lives)
57 | .bonus_stars:
58 | %incbin(gfx,bonus_stars)
59 | .item_box:
60 | if !8x8_item_box_tile
61 | %incbin(gfx,item_box_8x8)
62 | else
63 | %incbin(gfx,item_box_16x16)
64 | endif
65 | if !draw_retry_indicator
66 | .indicator:
67 | %incbin(gfx,indicator)
68 | endif
69 | endif
70 |
71 | ;=====================================
72 | ; Load the ASM files.
73 | ;=====================================
74 | %incsrc(code,shared)
75 | %incsrc("",extra)
76 | %incsrc(code,startup)
77 | %incsrc(code,fade_to_level)
78 | %incsrc(code,level_init_1)
79 | %incsrc(code,level_init_2)
80 | %incsrc(code,level_init_3)
81 | %incsrc(code,level_transition)
82 | %incsrc(code,in_level)
83 | %incsrc(code,prompt)
84 | %incsrc(code,nmi)
85 | %incsrc(code,load_overworld)
86 | %incsrc(code,fade_to_overworld)
87 | %incsrc(code,game_over)
88 | %incsrc(code,time_up)
89 | %incsrc(code,sprite_status_bar)
90 | %incsrc(code,api)
91 |
92 | ;=====================================
93 | ; Load the hijacks.
94 | ;=====================================
95 | %incsrc(code/hijacks,hex_edits)
96 | %incsrc(code/hijacks,multiple_midways)
97 | %incsrc(code/hijacks,vanilla_midway)
98 | %incsrc(code/hijacks,custom_midway)
99 | %incsrc(code/hijacks,sram)
100 | %incsrc(code/hijacks,hurry_up)
101 | %incsrc(code/hijacks,death_counter)
102 | %incsrc(code/hijacks,initial_facing_fix)
103 | %incsrc(code/hijacks,item_box_fix)
104 | %incsrc(code/hijacks,remove_status_bar)
105 | %incsrc(code/hijacks,vanilla_boss_gm13)
106 | %incsrc(code/hijacks,switch_palace_message_fix)
107 |
--------------------------------------------------------------------------------
/src/retry_config/code/api.asm:
--------------------------------------------------------------------------------
1 | ;================================================
2 | ; Routines that can be called by external UberASM files
3 | ;================================================
4 |
5 | ;================================================
6 | ; Routine to respawn in the level (at the current checkpoint),
7 | ; effectively the same as dying and hitting Retry, or dying with
8 | ; instant Retry enabled.
9 | ;
10 | ; Inputs: N/A
11 | ; Outputs: N/A
12 | ; Pre: A/X/Y 8 bits
13 | ; Post: A/X/Y 8 bits
14 | ; Example: JSL retry_api_respawn_in_level
15 | ;================================================
16 | respawn_in_level:
17 | jml in_level_main_dying_respawn
18 |
19 | ;================================================
20 | ; Routine to save the game, which will also save the addresses
21 | ; defined in the sram_tables.asm file.
22 | ;
23 | ; Inputs: N/A
24 | ; Outputs: N/A
25 | ; Pre: N/A
26 | ; Post: A/X/Y 8 bits, DB/X/Y preserved
27 | ; Example: JSL retry_api_save_game
28 | ;================================================
29 | save_game:
30 | jsr shared_save_game
31 | rtl
32 |
33 | ;================================================
34 | ; Routine to remove the current level's checkpoint, meaning
35 | ; entering it again will load the main sublevel's entrance.
36 | ; Only makes sense to be called during a level gamemode.
37 | ;
38 | ; Inputs: N/A
39 | ; Outputs: N/A
40 | ; Pre: A/X/Y 8 bits
41 | ; Post: A/X/Y 8 bits, DB/X/Y preserved
42 | ; Example: JSL retry_api_reset_level_checkpoint
43 | ;================================================
44 | reset_level_checkpoint:
45 | jsr shared_reset_checkpoint
46 | rtl
47 |
48 | ;================================================
49 | ; Routine to remove all levels checkpoints, effectively resetting
50 | ; their state as if it were a new game. If you're saving the CPs
51 | ; to SRAM, you'll need to call the save game routine afterwards to
52 | ; also reset the CPs state in SRAM.
53 | ;
54 | ; Inputs: N/A
55 | ; Outputs: N/A
56 | ; Pre: N/A
57 | ; Post: A/X/Y size preserved, DB/X/Y preserved
58 | ; Example: JSL retry_api_reset_all_checkpoints
59 | ;================================================
60 | reset_all_checkpoints:
61 | ; A/X/Y 8 bits
62 | phx : phy : php
63 | sep #$30
64 |
65 | ; Initialize the checkpoint ram table.
66 | ldx #$BE
67 | ldy #$5F
68 | - tya : cmp #$25 : bcc +
69 | clc : adc #$DC
70 | + sta !ram_checkpoint,x
71 | lda #$00 : adc #$00 : sta !ram_checkpoint+1,x
72 | lda $1EA2|!addr,y : and #~$40 : sta $1EA2|!addr,y
73 | dex #2
74 | dey : bpl -
75 |
76 | ; Initialize respawn RAM in case it's called inside a level.
77 | %lda_13BF() : asl : tax
78 | rep #$20
79 | lda !ram_checkpoint,x : sta !ram_respawn
80 |
81 | ; Initialize "set checkpoint" handle to $FFFF.
82 | lda #$FFFF : sta !ram_set_checkpoint
83 |
84 | ; Restore X/Y/P
85 | plp : ply : plx
86 | rtl
87 |
88 | ;================================================
89 | ; Routine to configure which tiles will be used by the sprite status
90 | ; bar. You can configure these elements: item box, timer, coin
91 | ; counter, lives counter and bonus stars counter. Each element needs a
92 | ; 16x16 sprite tile to be reserved.
93 | ; This routine should be called in UberASM level init code, to overwrite
94 | ; the default settings from "settings_global.asm", in case you want
95 | ; to hide some or all of the elements in some level or if you need to
96 | ; change their tile or palette.
97 | ; Each element needs a 16 bit value that determines which 16x16 tile
98 | ; it will use and what palette to use. The first digit is the palette
99 | ; row to use (8-F), while the other 3 digits are the tile number
100 | ; (000-1FF). If an element is set to $0000, it won't be displayed.
101 | ;
102 | ; Inputs: for each item, in order, you write the value after the JSL
103 | ; in the format described above (see example)
104 | ; Outputs: N/A
105 | ; Pre: N/A
106 | ; Post: A/X/Y 8 bit and clobbered, DB preserved
107 | ; Example:
108 | ; JSL retry_api_configure_sprite_status_bar
109 | ; dw $B080 ; Item box: palette B, tile 0x80
110 | ; dw $8088 ; Timer: palette 8, tile 0x88
111 | ; dw $80C2 ; Coin counter: palette 8, tile 0xC2
112 | ; dw $0000 ; Lives counter: hidden
113 | ; dw $0000 ; Bonus stars counter: hidden
114 | ; ... <- your code will continue here after the JSL
115 | ;================================================
116 | configure_sprite_status_bar:
117 | if !sprite_status_bar
118 | phb
119 | ; Set DBR equal to caller routine bank
120 | sep #$30
121 | lda $04,s : pha : plb
122 | ; Use Y to read address after the routine call
123 | rep #$30
124 | lda $02,s : tay
125 | ; Copy the values from after the JSL to sprite status bar ram
126 | lda $0001,y : and #$7FFF : sta !ram_status_bar_item_box_tile
127 | lda $0003,y : and #$7FFF : sta !ram_status_bar_timer_tile
128 | lda $0005,y : and #$7FFF : sta !ram_status_bar_coins_tile
129 | lda $0007,y : and #$7FFF : sta !ram_status_bar_lives_tile
130 | lda $0009,y : and #$7FFF : sta !ram_status_bar_bonus_stars_tile
131 | plb
132 | endif
133 | ; Make sure the code returns at the right place
134 | rep #$20
135 | lda $01,s : clc : adc.w #2*5 : sta $01,s
136 | sep #$30
137 | rtl
138 |
139 | ;================================================
140 | ; Routine to get the current Retry type, i.e. if currently the level is
141 | ; set to have Retry prompt, instant Retry or no Retry.
142 | ; The returned value has this format:
143 | ; - $01 = Retry prompt enabled & play the vanilla death song when the player dies
144 | ; - $02 = Retry prompt enabled & play only the death sfx when the player dies
145 | ; - $03 = instant Retry enabled
146 | ; - $04 = Retry disabled
147 | ;
148 | ; Inputs: N/A
149 | ; Outputs: A = Retry type
150 | ; Pre: A 8 bits
151 | ; Post: A/X/Y size preserved, DB/X/Y preserved
152 | ; Example: JSL retry_api_get_retry_type
153 | ;================================================
154 | get_retry_type:
155 | jsr shared_get_prompt_type
156 | rtl
157 |
158 | ;================================================
159 | ; Routine to get the address in SRAM for a specific variable.
160 | ; By "variable" it's meant any of the RAM addresses that are saved to SRAM
161 | ; specified in the sram save table. The returned address will be coherent
162 | ; with the current save file loaded when this routine is called (so, make
163 | ; sure to not call it before a save file is loaded!).
164 | ; This could be useful to read/write values in SRAM directly, for example
165 | ; if you need to update some SRAM value without the game being saved.
166 | ; Note: this will always return "variable not found" if !sram_feature = 0.
167 | ;
168 | ; Inputs: variable address to search for in ROM right after the JSL
169 | ; This means the call should look like this:
170 | ; JSL retry_api_get_sram_variable_address
171 | ; dl
172 | ; Outputs: Carry set = variable not found
173 | ; Carry clear = variable found -> SRAM address stored in $00-$02
174 | ; In this case the value in SRAM can be accessed indirectly with the
175 | ; LDA/STA [$00] and LDA/STA [$00],y instructions.
176 | ; Pre: N/A
177 | ; Post: A/X/Y 8 bit and clobbered, DB preserved
178 | ; Example:
179 | ; JSL retry_api_get_sram_variable_address
180 | ; dl retry_ram_death_counter ; Variable to search for
181 | ; BCS not_found
182 | ; found:
183 | ; LDY #$01
184 | ; LDA #$09
185 | ; STA [$00],y ; Set second death counter digit in SRAM to 9
186 | ; not_found:
187 | ; ...
188 | ;================================================
189 | get_sram_variable_address:
190 | if !sram_feature
191 | phb
192 | ; Set DBR equal to caller routine bank
193 | sep #$30
194 | lda $04,s : pha : plb
195 | ; Use Y to read address after the routine call
196 | rep #$30
197 | lda $02,s : tay
198 | stz $00
199 | ldx #$0000
200 | .loop:
201 | ; Check if the current SRAM variables corresponds to the input
202 | lda.l sram_tables_save+0,x : cmp $0001,y : bne .next
203 | lda.l sram_tables_save+1,x : cmp $0002,y : bne .next
204 | .found:
205 | ; If so, add the calculated offset to the save file SRAM address
206 | jsr sram_get_sram_addr
207 | clc : adc $00 : sta $00
208 | sep #$20
209 | lda.b #!sram_addr>>16 : sta $02
210 | ; Clear carry (address found)
211 | clc
212 | bra .return
213 | .next:
214 | ; Update the SRAM offset with the current variable size
215 | lda.l sram_tables_save+3,x : clc : adc $00 : sta $00
216 | ; Go to the next SRAM variable
217 | txa : clc : adc #$0005
218 | ; If at the end of the SRAM table, end
219 | cmp.w #sram_tables_sram_defaults-sram_tables_save : bcs .not_found
220 | tax
221 | bra .loop
222 | .not_found:
223 | ; Set carry (address not found)
224 | sec
225 | .return:
226 | plb
227 | ; Make sure the code returns at the right place
228 | rep #$20
229 | lda $01,s : inc #3 : sta $01,s
230 | sep #$30
231 | rtl
232 | else
233 | ; Make sure the code returns at the right place
234 | rep #$20
235 | lda $01,s : clc : adc #$0003 : sta $01,s
236 | ; Set carry (address not found)
237 | sep #$31
238 | endif
239 | rtl
240 |
--------------------------------------------------------------------------------
/src/retry_config/code/check_incompatibilities.asm:
--------------------------------------------------------------------------------
1 | ;if read1($05D9E3) != $5C
2 | ; error "You must save a level in Lunar Magic with the \"Separate midway entrance\" option checked before applying this. Insertion aborted."
3 | ;endif
4 |
5 | if read1($0FF0A0) == $FF
6 | error "You must save at least one level in Lunar Magic before inserting this patch. Insertion aborted."
7 | endif
8 |
9 | if read1($00A28A) == $5C && read1($05D8E6) == $5C
10 | error "This patch is not compatible with worldpeace's retry patch. Insertion aborted."
11 | endif
12 |
13 | if read1($05DAA3) == $5C
14 | error "This patch is not compatible with the Multiple Midway Points patch. Insertion aborted."
15 | endif
16 |
17 | ; Warn if SRAM/BW-RAM plus are patched in already and !sram_feature = 1 (also force it to 0).
18 | if !sram_feature && not(!sa1) && !sram_plus
19 | print "Warning: SRAM Plus was detected in your ROM. Retry's save feature won't be inserted."
20 | !sram_feature = 0
21 | endif
22 |
23 | if !sram_feature && !sa1 && !bwram_plus
24 | print "Warning: BW-RAM Plus was detected in your ROM. Retry's save feature won't be inserted."
25 | !sram_feature = 0
26 | endif
27 |
28 | ; UberASM Tool 2.0 is now required
29 | %require_uber_ver(2,0)
30 |
--------------------------------------------------------------------------------
/src/retry_config/code/fade_to_level.asm:
--------------------------------------------------------------------------------
1 | ; Gamemode 0F
2 |
3 | init:
4 | if !sprite_status_bar
5 | jsr sprite_status_bar_init_ram
6 | endif
7 |
8 | ; If respawning or doing a level transition, skip.
9 | lda $141A|!addr : bne .transition
10 |
11 | if !enter_level_sfx != $00
12 | ; If not loading the level from a No Yoshi intro, play the SFX.
13 | lda $71 : cmp #$0A : beq +
14 | lda.b #!enter_level_sfx : sta !enter_level_sfx_addr|!addr
15 | lda.b #!enter_level_delay : sta $0DB1|!addr
16 | +
17 | endif
18 |
19 | if !pipe_entrance_freeze == 2
20 | ; Reset the $9D backup.
21 | lda #$00 : sta !ram_9D_backup
22 | endif
23 | bra main
24 |
25 | .transition:
26 | ; Check if we're respawning from Retry.
27 | lda !ram_is_respawning : beq .not_respawning
28 |
29 | .respawning:
30 | if !pipe_entrance_freeze == 2
31 | ; If yes, store the $9D backup to $9D.
32 | ; This makes pipe entrances consistent in how sprites behave during them.
33 | lda !ram_9D_backup : sta $9D
34 | endif
35 | bra main
36 |
37 | .not_respawning:
38 | if !pipe_entrance_freeze == 2
39 | ; If it's a normal transition, backup $9D...
40 | lda $9D : sta !ram_9D_backup
41 | endif
42 |
43 | ; ...and backup the current entrance value for later.
44 | ; (if warping to Yoshi Wings, change the entrance to the correct level
45 | ; and set the Yoshi Wings flag in the checkpoint RAM).
46 | lda $1B95|!addr : beq +
47 | %jsl_to_rts_db($05DBAC,$058125)
48 | lda $19D8|!addr,x : and #$FE : ora $010C|!addr : ora #$80
49 | bra ++
50 | + jsr shared_get_screen_number
51 | lda $19D8|!addr,x
52 | ++ sta !ram_door_dest+1
53 | lda $19B8|!addr,x : sta !ram_door_dest+0
54 |
55 | main:
56 | if !fast_transitions
57 | ; Reset the mosaic timer.
58 | stz $0DB1|!addr
59 | endif
60 |
61 | ; If in the door animation, call the extra routine.
62 | lda $71 : cmp #$0D : bne .return
63 | phb : phk : plb
64 | php
65 | jsr extra_door_animation
66 | plp
67 | plb
68 |
69 | .return:
70 | rtl
71 |
--------------------------------------------------------------------------------
/src/retry_config/code/fade_to_overworld.asm:
--------------------------------------------------------------------------------
1 | ; Gamemode 0D
2 |
3 | ; Tile used for empty space. By default it's the border "filled" tile.
4 | !empty_tile = $FE
5 | !empty_props = l3_prop(6,0)
6 |
7 | init:
8 |
9 | ; Draw the death counter in the Overworld.
10 | .death_counter:
11 | if !ow_death_counter
12 | ; Set the DBR to $7F to use the stripe table with ,y.
13 | %set_dbr(!stripe_table)
14 |
15 | ; Write the stripe image header.
16 | rep #$30
17 | ldy.w !stripe_index
18 | lda.w #str_header1(!ow_death_counter_x_pos,!ow_death_counter_y_pos)
19 | sta.w !stripe_table,y
20 | iny #2
21 | lda.w #str_header2((5*2)-1,0)
22 | sta.w !stripe_table,y
23 | iny #2
24 |
25 | ; Loop through all digits in the death counter
26 | ; and write them to the stripe image table.
27 | ldx #$0000
28 | sep #$20
29 | stz $00
30 |
31 | ..stripe_loop:
32 | ; If the current digit is zero, turn it into an empty tile,
33 | ; but only if no non-zero digit has been reached yet.
34 | lda.l !ram_death_counter,x : bne ...normal
35 | cpx.w #$0005-1 : beq ...normal
36 | lsr $00 : bcs ...normal
37 | lda.b #!empty_tile : sta.w !stripe_table,y
38 | lda.b #!empty_props
39 | bra +
40 |
41 | ...normal:
42 | clc : adc.b #!ow_digit_0 : sta.w !stripe_table,y
43 | lda #$01 : sta $00
44 | lda.b #!ow_death_counter_props
45 | + sta.w !stripe_table+1,y
46 |
47 | ...next:
48 | iny #2
49 | inx
50 | cpx #$0005 : bcc ..stripe_loop
51 |
52 | ...end:
53 | ; Write the terminator and update the stripe index.
54 | lda #$FF : sta.w !stripe_table,y
55 | sty.w !stripe_index
56 | sep #$10
57 |
58 | plb
59 | endif
60 |
61 | rtl
62 |
--------------------------------------------------------------------------------
/src/retry_config/code/game_over.asm:
--------------------------------------------------------------------------------
1 | ; Gamemode 16
2 |
3 | init:
4 | ; Skip if it's not the "GAME OVER" screen.
5 | lda $143B|!addr : cmp #$14 : bne .return
6 |
7 | if !sram_feature
8 | ; Reload the save file.
9 | jsl sram_load_game_over
10 | endif
11 |
12 | ; Call the extra routine.
13 | phb : phk : plb
14 | php
15 | jsr extra_game_over
16 | plp
17 | plb
18 |
19 | ; If applicable, save the game.
20 | if !save_after_game_over
21 | jsr shared_save_game
22 | endif
23 |
24 | .return:
25 | rtl
26 |
--------------------------------------------------------------------------------
/src/retry_config/code/gm14_end/death_routine.asm:
--------------------------------------------------------------------------------
1 | ;=====================================
2 | ; death_sfx routine
3 | ;
4 | ; Handles death music/sfx when dying, death counter and other stuff.
5 | ; This runs just before AMK, so we can kill the death song before it starts.
6 | ;=====================================
7 | death_routine:
8 | if not(!infinite_lives)
9 | ; Check if all lives were lost.
10 | lda $0DBE|!addr : bpl .no_game_over
11 |
12 | ; Check if the death sequence has finished.
13 | lda $1496|!addr : bne .game_over_return
14 |
15 | .game_over:
16 | ; If yes, go to game over
17 | %jsl_to_rts_db($00D0DD,$0084CF)
18 |
19 | ..return:
20 | rts
21 |
22 | .no_game_over:
23 | endif
24 |
25 | ; If the reload level flag is set...
26 | lda !ram_is_dying : bit #$40 : beq .no_reload
27 |
28 | ; Make sure Mario's animation timer is 0.
29 | stz $1496|!addr
30 |
31 | .reload:
32 | if !title_death_behavior != 0
33 | ; (Check if we need to reload a level or the title screen)
34 | bit #$20 : beq ..level
35 |
36 | ..title:
37 | ; ...reload the title screen!
38 | lda #$02 : sta $0100|!addr
39 | rts
40 |
41 | ..level:
42 | endif
43 | ; ...reload the level!
44 | lda #$0F : sta $0100|!addr
45 | rts
46 |
47 | .no_reload:
48 | ; Only update death counter and call the death routine once
49 | ; but handle the death song every frame to avoid issues with custom codes that call $00F606 every frame.
50 | cmp #$00 : bne .handle_song
51 |
52 | .first_frame:
53 | ; Set the dying flag.
54 | inc : sta !ram_is_dying
55 |
56 | ; Update the death counter.
57 | ldx #$04
58 | - lda !ram_death_counter,x : inc : sta !ram_death_counter,x
59 | cmp #10 : bcc +
60 | lda #$00 : sta !ram_death_counter,x
61 | dex : bpl -
62 |
63 | ; If we got here, it means the counter overflowed back to 0, so set it to 99999.
64 | ldx #$04
65 | lda #$09
66 | - sta !ram_death_counter,x
67 | dex : bpl -
68 | +
69 | ; Call the custom death routine.
70 | php : phb
71 | jsr extra_death
72 | plb : plp
73 |
74 | ; Kill score sprites if the option is enabled and Retry prompt is enabled.
75 | if !no_score_sprites_on_death
76 | jsr shared_get_prompt_type : cmp #$03 : bcs +
77 | ldx.b #$06-1
78 | - stz $16E1|!addr,x
79 | dex : bpl -
80 | +
81 | endif
82 |
83 | ; Reset some stuff related to lx5's Custom Powerups.
84 | if !custom_powerups == 1
85 | stz.w ($170B|!addr)+$08
86 | stz.w ($170B|!addr)+$09
87 | lda #$00 : sta !projectile_do_dma
88 |
89 | ldx #$07
90 | - lda $170B|!addr,x : cmp #$12 : bne +
91 | stz $170B|!addr,x
92 | + dex : bpl -
93 |
94 | lda !item_box_disable : ora #$02 : sta !item_box_disable
95 | endif
96 |
97 | if not(!infinite_lives)
98 | ; Don't decrement lives on the title screen.
99 | lda $0100|!addr : cmp #$0B : bcc .no_lose_lives
100 |
101 | ; Check if we need to decrement lives.
102 | jsr shared_get_bitwise_mask
103 | and.l tables_lose_lives,x : beq .no_lose_lives
104 |
105 | ; If yes, decrement them and don't reset music if about to game over.
106 | dec $0DBE|!addr : bmi .return
107 |
108 | .no_lose_lives:
109 | endif
110 |
111 | .handle_song:
112 | ; If the music is sped up, play the death song to make it normal again.
113 | lda !ram_hurry_up : bne .return
114 |
115 | ; If "Exit" was selected, don't disable the death music.
116 | lda !ram_prompt_phase : cmp #$05 : bcs .return
117 |
118 | ; Check if we have to disable the death music.
119 | jsr shared_get_prompt_type
120 | cmp #$02 : bcc .return
121 | cmp #$04 : bcs .return
122 |
123 | .no_death_song:
124 | ; Don't play the death song.
125 | stz $1DFB|!addr
126 |
127 | ; Undo the $0DDA change.
128 | ; This ensures the song won't be reloaded if it's the same after respawning.
129 | lda !ram_music_backup : sta $0DDA|!addr
130 |
131 | ; Only play the death SFX once per death.
132 | lda !ram_is_dying : bmi .return
133 | ora #$80 : sta !ram_is_dying
134 |
135 | ; Play the death SFX.
136 | if !death_sfx != $00
137 | lda.b #!death_sfx : sta !death_sfx_addr|!addr
138 | endif
139 |
140 | .return:
141 | rts
142 |
--------------------------------------------------------------------------------
/src/retry_config/code/gm14_end/prompt_oam.asm:
--------------------------------------------------------------------------------
1 | if not(!no_prompt_draw)
2 |
3 | ; Check if palette values make sense.
4 | assert !letter_palette >= $08 && !letter_palette <= $0F, "Error: \!letter_palette should be between $08 and $0F."
5 | assert !cursor_palette >= $08 && !cursor_palette <= $0F, "Error: \!cursor_palette should be between $08 and $0F."
6 |
7 | ; Convert palettes from row number to YXPPCCCT format.
8 | !l_props #= ($30|((!letter_palette-8)<<1))
9 | !c_props #= ($30|((!cursor_palette-8)<<1))
10 |
11 | ; Function to add the T bit in the YXPPCCCT properties for tiles in page 1
12 | function props(prop,tile) = ((prop)|((tile>>8)&1))
13 |
14 | ;=====================================
15 | ; prompt_oam routine
16 | ;
17 | ; This routine draws the Retry prompt tiles on the screen.
18 | ; The prompt will be drawn using as few OAM slots as possible:
19 | ; - If box and exit are enabled, 15 slots will be used (16 if using the oscillating cursor).
20 | ; - If box is disabled but exit is enabled, 11 slots will be used.
21 | ; - If box is enabled but exit is disabled, 8 slots will be used (9 if using the oscillating cursor).
22 | ; - If box and exit are disabled, 6 slots will be used.
23 | ; Before drawing, all the currently used OAM slots are moved at the end of the OAM table, then the new tiles are written from the start.
24 | ; This ensures that in most cases Retry won't overwrite other sprites, and that it will always have max priority w.r.t. other sprite tiles
25 | ; (so that other sprites will always go behind the prompt).
26 | ;=====================================
27 | prompt_oam:
28 | ; Get as many free slots as possible at the start of $0200.
29 | ; Skip this in Reznor/Morton/Roy's rooms to avoid glitching their BGs.
30 | lda $0D9B|!addr : cmp #$C0 : beq +
31 | jsr defrag_oam
32 | +
33 | ; Store the "hide cursor" mask in $00.
34 | if !cursor_setting == 1
35 | lda $1B91|!addr : eor #$1F : and #$18 : bne +
36 | lda #$03
37 | bra ++
38 | +
39 | elseif !cursor_setting == 2
40 | lda $1B91|!addr : lsr #!cursor_oscillate_speed : and #$07 : tax
41 | lda.w .cursor_x_offset,x : sta $02
42 | endif
43 | ldx $1B92|!addr
44 | lda.w .hide_cursor_mask,x
45 | ++ sta $00
46 |
47 | ; Draw "RETRY"
48 | ldy #$00 : sty $01
49 | ldx.b #letters_retry-letters
50 | if !prompt_wave
51 | stz $03
52 | lda $1B92|!addr : bne +
53 | inc $03
54 | +
55 | endif
56 | jsr oam_draw
57 | jsr handle_cursor
58 |
59 | ; Draw "EXIT" if exit is enabled
60 | lda !ram_disable_exit : bne .no_exit
61 | sty $01
62 | ldx.b #letters_exit-letters
63 | if !prompt_wave
64 | stz $03
65 | lda $1B92|!addr : beq +
66 | inc $03
67 | +
68 | endif
69 | jsr oam_draw
70 | lsr $00
71 | jsr handle_cursor
72 |
73 | .no_exit:
74 | ; Draw filler tiles if the box is enabled
75 | lda !ram_disable_box : bne .no_box
76 | ldx.b #letters_box-letters
77 | lda !ram_disable_exit : beq +
78 | ldx.b #letters_box_no_exit-letters
79 | + jsr oam_draw
80 |
81 | .no_box:
82 | ; Make sure $0400 is up to date
83 | jsr shared_update_0400
84 | rts
85 |
86 | .hide_cursor_mask:
87 | db $02,$01
88 |
89 | if !cursor_setting == 2
90 | .cursor_x_offset:
91 | db -1,0,1,2,3,2,1,0
92 | endif
93 |
94 | ;=====================================
95 | ; handle_cursor routine
96 | ;
97 | ; This routine handles hiding the cursor when applicable, as well as setting its OAM size
98 | ; and offsetting its X position when !cursor_setting == 2.
99 | ; If the box is enabled, the cursor will be 16x16, and hidden by replacing it with a black tile.
100 | ; Otherwise, the cursor will be 8x8, and hidden by moving it offscreen.
101 | ;
102 | ; Inputs:
103 | ; $00 = LSB set if the cursor should be hidden
104 | ; $01 = OAM index of the cursor
105 | ; $02 = X offset of the cursor (when !cursor_setting == 2)
106 | ;=====================================
107 | handle_cursor:
108 | ; Set the OAM size.
109 | lda $01 : lsr #2 : tax
110 | lda !ram_disable_box : beq +
111 | lda #$00
112 | bra ++
113 | + lda #$02
114 | ++ sta $0420|!addr,x
115 |
116 | ; Hide and offset the cursor.
117 | ldx $01
118 | lda $00 : and #$01 : bne .hide
119 |
120 | if !cursor_setting == 2
121 | ; If the box is enabled...
122 | lda !ram_disable_box : bne +
123 |
124 | ; Draw an additional black tile under the cursor.
125 | rep #$20
126 | lda $0200|!addr,x : sta $0200|!addr,y
127 | lda.w #(!l_props<<8)|(!tile_blk) : sta $0202|!addr,y
128 | sep #$20
129 |
130 | ; Make the black tile 16x16 and increase the OAM index.
131 | phy
132 | tya : lsr #2 : tay
133 | lda #$02 : sta $0420|!addr,y
134 | ply
135 | iny #4
136 | +
137 | ; Apply the X offset to the cursor
138 | lda $0200|!addr,x : clc : adc $02 : sta $0200|!addr,x
139 |
140 | ; Make the cursor 8x8.
141 | txa : lsr #2 : tax
142 | stz $0420|!addr,x
143 | endif
144 | rts
145 |
146 | .hide:
147 | lda !ram_disable_box : beq +
148 | lda #$F0 : sta $0201|!addr,x
149 | rts
150 | + lda.b #!tile_blk : sta $0202|!addr,x
151 | .return:
152 | rts
153 |
154 | ;=====================================
155 | ; erase_tiles routine
156 | ;
157 | ; This routine hides the Retry prompt tiles.
158 | ;=====================================
159 | erase_tiles:
160 | ; Erase the prompt's OAM tiles when in Reznor/Morton/Roy/Ludwig's rooms.
161 | ; This avoids the BG from glitching out when the prompt disappears.
162 | lda $0D9B|!addr : cmp #$C0 : bne .return
163 |
164 | ; Find how many tiles we need to erase.
165 | lda.b #(letters_retry_end-letters_retry)/5 : sta $00
166 |
167 | lda !ram_disable_exit : bne +
168 | lda $00 : clc : adc.b #(letters_exit_end-letters_exit)/5 : sta $00
169 | +
170 | lda !ram_disable_box : bne +
171 | lda $00 : clc : adc.b #(letters_box_end-letters_box)/5
172 | if !cursor_setting == 2
173 | inc
174 | endif
175 | sta $00
176 | +
177 | ; Put all the tiles offscreen.
178 | lda $00 : dec : asl #2 : tay
179 | lda #$F0
180 | .loop:
181 | sta $0201|!addr,y
182 | dey #4 : bpl .loop
183 | .return:
184 | rts
185 |
186 | ;=====================================
187 | ; oam_draw routine
188 | ;
189 | ; This routine draws one part of the Retry prompt on the screen.
190 | ; Inputs:
191 | ; X = index in the letters table
192 | ; Y = OAM index
193 | ;=====================================
194 | oam_draw:
195 | if !prompt_wave
196 | stz $0F
197 | endif
198 |
199 | ; Load X/Y position based on black box enabled flag
200 | lda !ram_disable_box : beq +
201 | lda !ram_prompt_x_pos : sta $0D
202 | lda !ram_prompt_y_pos : sta $0E
203 | bra .loop
204 | + lda.b #!default_text_x_pos : sta $0D
205 | lda.b #!default_text_y_pos : sta $0E
206 |
207 | .loop:
208 | ; Return if we reached the $FF terminator.
209 | lda.w letters,x : cmp #$FF : beq .return
210 |
211 | ; Store the X,Y positions and tile OAM properties.
212 | clc : adc $0D : sta $0200|!addr,y
213 | lda.w letters+1,x : clc : adc $0E : sta $0201|!addr,y
214 | if !prompt_wave
215 | ; Make the letters wave
216 | lda $03 : beq +
217 | lda.w letters+2,x : cmp.b #!tile_curs : beq +
218 | phx
219 | lda $1B91|!addr : lsr #!prompt_wave_speed
220 | clc : adc $0F : and #$07 : tax
221 | lda.w .y_offset,x : clc : adc $0201|!addr,y : sta $0201|!addr,y
222 | plx
223 | inc $0F
224 | +
225 | endif
226 | rep #$20
227 | lda.w letters+2,x : sta $0202|!addr,y
228 | sep #$20
229 |
230 | ; Store the OAM size.
231 | phy
232 | tya : lsr #2 : tay
233 | lda.w letters+4,x : sta $0420|!addr,y
234 | ply
235 |
236 | ; Go to the next tile.
237 | inx #5
238 | iny #4
239 | bra .loop
240 | .return:
241 | rts
242 |
243 | if !prompt_wave
244 | .y_offset:
245 | db -3,-2,-1,0,1,0,-1,-2
246 | endif
247 |
248 | ;=====================================
249 | ; OAM info for each tile (X,Y,T,P,S)
250 | ;=====================================
251 | letters:
252 | .retry:
253 | db $00,$00,!tile_curs,props(!c_props,!tile_curs),$00 ; Black/Cursor
254 | db $10,$00,!tile_r, props(!l_props,!tile_r), $00 ; R
255 | db $18,$00,!tile_e, props(!l_props,!tile_e), $00 ; E
256 | db $20,$00,!tile_t, props(!l_props,!tile_t), $00 ; T
257 | db $28,$00,!tile_r, props(!l_props,!tile_r), $00 ; R
258 | db $30,$00,!tile_y, props(!l_props,!tile_y), $00 ; Y
259 | ..end:
260 | db $FF
261 |
262 | .exit:
263 | db $00,$10,!tile_curs,props(!c_props,!tile_curs),$00 ; Black/Cursor
264 | db $10,$10,!tile_e, props(!l_props,!tile_e), $00 ; E
265 | db $18,$10,!tile_x, props(!l_props,!tile_x), $00 ; X
266 | db $20,$10,!tile_i, props(!l_props,!tile_i), $00 ; I
267 | db $28,$10,!tile_t, props(!l_props,!tile_t), $00 ; T
268 | ..end:
269 | db $FF
270 |
271 | .box:
272 | db $E0,$10,!tile_blk, props(!l_props,!tile_blk), $02 ; Black
273 | db $F0,$10,!tile_blk, props(!l_props,!tile_blk), $02 ; Black
274 | ..no_exit:
275 | db $E0,$00,!tile_blk, props(!l_props,!tile_blk), $02 ; Black
276 | db $F0,$00,!tile_blk, props(!l_props,!tile_blk), $02 ; Black
277 | ..end:
278 | db $FF
279 |
280 | ;=====================================
281 | ; defrag_oam routine
282 | ;
283 | ; This routine puts all used slots in OAM at the end of the table in contiguous spots.
284 | ; The result is that all free slots will be at the beginning of the table.
285 | ; This allows the letters to be drawn with max priority w.r.t. everything else, and to not overwrite other tiles.
286 | ; Returns with Y = $01FC and X = last free OAM slot.
287 | ;=====================================
288 | defrag_oam:
289 | ; Since we scan both $0200 and $0300, we need 16 bit indexes.
290 | rep #$10
291 | ; Y: index in the original OAM table.
292 | ldy #$01FC
293 | ; X: index in the rearranged table.
294 | ldx #$01FC
295 |
296 | ; First we find the first free slot from the end of the table.
297 | ; This prevents the main loop from hiding tiles when the end of the OAM table is filled.
298 | lda #$F0
299 |
300 | .setup_loop:
301 | cmp $0201|!addr,y : beq .main_loop
302 | dex #4
303 | dey #4
304 | bpl .setup_loop
305 |
306 | ..end:
307 | ; If we get here it means that the entire OAM table is full, so just return.
308 | sep #$10
309 | rts
310 |
311 | ; Now we move all the used slots in adjacent spots at the end of the OAM table.
312 | .main_loop:
313 | ; If the slot is free, go to the next one.
314 | cmp $0201|!addr,y : beq ..next
315 |
316 | ; Otherwise, copy the Y slot in the X slot...
317 | rep #$20
318 | lda $0200|!addr,y : sta $0200|!addr,x
319 | lda $0202|!addr,y : sta $0202|!addr,x
320 |
321 | ; ...and mark the Y slot as free.
322 | lda #$F0F0 : sta $0200|!addr,y
323 |
324 | phx : phy
325 |
326 | ; Compute the indexes in $0420.
327 | tya : lsr #2 : tay
328 | txa : lsr #2 : tax
329 |
330 | ; Copy the entry in $0420 as well.
331 | sep #$20
332 | lda $0420|!addr,y : sta $0420|!addr,x
333 |
334 | ply : plx
335 |
336 | ; Go to the next slot in the rearranged table.
337 | dex #4
338 |
339 | ; Reload value to compare $0201 to.
340 | lda #$F0
341 |
342 | ..next:
343 | ; Go to the next slot in the original table, and loop back if not the end.
344 | dey #4 : bpl .main_loop
345 |
346 | .end:
347 | sep #$10
348 | rts
349 |
350 | endif
351 |
--------------------------------------------------------------------------------
/src/retry_config/code/gm14_end/set_checkpoint.asm:
--------------------------------------------------------------------------------
1 | ;=====================================
2 | ; set_checkpoint routine
3 | ;=====================================
4 | set_checkpoint:
5 | ; If the reset value is not set, set the checkpoint.
6 | lda !ram_set_checkpoint : cmp #$80 : bne .set
7 |
8 | .reset:
9 | ; Otherwise, reset the checkpoint.
10 | jsr shared_reset_checkpoint
11 | stz $13CE|!addr
12 |
13 | if !save_on_checkpoint
14 | jsr shared_save_game
15 | endif
16 |
17 | ; Always reload the samples, just to be safe.
18 | lda #$FF : sta !ram_music_backup
19 | bra .return
20 |
21 | .set:
22 | ; Save individual dcsave buffers.
23 | ; Needed because we skip over $00F2DD, where the routine is called.
24 | jsr shared_dcsave_midpoint
25 |
26 | ; Set midway flag, just to be safe.
27 | lda #$01 : sta $13CE|!addr
28 |
29 | ; Check if it's a normal or custom midway.
30 | lda !ram_set_checkpoint+1 : cmp #$FF : bne ..custom_destination
31 |
32 | ..normal_midway:
33 | ; If it's the intro level, skip.
34 | lda $0109|!addr : beq ...no_intro
35 | cmp.b #!intro_level+$24 : bne .return
36 |
37 | ...no_intro:
38 | ; Check if this midway sets the midway entrance for the sublevel or the main level.
39 | jsr shared_get_checkpoint_value
40 | cmp #$01 : beq ...sub_midway
41 | cmp #$03 : bcs ...sub_midway
42 |
43 | ...main_midway:
44 | jsr calc_entrance
45 | bra +
46 | ...sub_midway:
47 | jsr calc_entrance_2
48 | +
49 | lda $0DDA|!addr : sta !ram_music_backup
50 | bra .return2
51 |
52 | ..custom_destination:
53 | ; Set the checkpoint destination.
54 | rep #$20
55 | lda !ram_set_checkpoint : sta !ram_respawn
56 | sep #$20
57 |
58 | ; If we're in the Yoshi Wings level, set the flag if applicable.
59 | ldy $1B95|!addr : beq +
60 | xba : bit #$0A : bne +
61 | ora #$80 : sta !ram_respawn+1
62 | +
63 | ; Always reload the samples, just to be safe.
64 | lda #$FF : sta !ram_music_backup
65 |
66 | .return2:
67 | ; Save the midway entrance as a checkpoint.
68 | jsr shared_hard_save
69 |
70 | .return:
71 | ; Reset the set_checkpoint address.
72 | lda #$FF : sta !ram_set_checkpoint : sta !ram_set_checkpoint+1
73 | rts
74 |
75 | ;=====================================
76 | ; calc_entrance routine
77 | ;=====================================
78 | calc_entrance:
79 | ; If it's not the intro level, skip.
80 | %lda_13BF() : tax : bne .no_intro
81 |
82 | ; Set intro sublevel number as respawn point.
83 | jsr shared_get_intro_sublevel
84 | sta !ram_respawn
85 | sep #$20
86 | bra .check_midway
87 |
88 | .no_intro:
89 | ; Convert $13BF value to sublevel number.
90 | cmp #$25 : bcc +
91 | clc : adc #$DC
92 | + sta !ram_respawn
93 | lda #$00 : adc #$00
94 | ..store_entrance_high:
95 | sta !ram_respawn+1
96 |
97 | .check_midway:
98 | ; If the midway flag is not set, return.
99 | lda $1EA2|!addr,x : and #$40 : bne ..midway
100 | lda $13CE|!addr : beq .return
101 |
102 | ..midway:
103 | ; Set the midway flag in the respawn entrance.
104 | lda !ram_respawn+1 : ora #$08 : sta !ram_respawn+1
105 |
106 | .return:
107 | rts
108 |
109 | .2:
110 | ; Get $13BF value in X.
111 | %lda_13BF() : tax
112 |
113 | ; Set current sublevel number as the respawn point.
114 | lda $010B|!addr : sta !ram_respawn
115 | lda $010C|!addr : bra .no_intro_store_entrance_high
116 |
--------------------------------------------------------------------------------
/src/retry_config/code/hijacks/custom_midway.asm:
--------------------------------------------------------------------------------
1 | ;=====================================
2 | ; This inserts the custom midway objects.
3 | ; Main custom object code taken from ObjecTool 0.5 by 0x400 and imamelia.
4 | ; Custom midway code by worldpeace.
5 | ;=====================================
6 |
7 | if !use_custom_midway_bar
8 |
9 | pushpc
10 |
11 | org $0DA415
12 | jml new_norm_objects
13 |
14 | pullpc
15 |
16 | new_norm_objects:
17 | sep #$30
18 |
19 | ; Check if it's a custom normal object.
20 | lda $5A : cmp #$2D : beq .custom
21 |
22 | .not_custom:
23 | lda $1931|!addr
24 | jml $0DA41A|!bank
25 |
26 | .custom:
27 | ; Store the first new settings byte.
28 | ldy #$00
29 | lda [$65],y : sta $5A
30 |
31 | ; Store the second new settings byte.
32 | iny
33 | lda [$65],y : sta $58
34 |
35 | ; Add 2 to the pointer so it ends up in the correct place.
36 | ; SMW expects them to have 3 bytes but this has 5 bytes.
37 | iny
38 | tya : clc : adc $65 : sta $65
39 | lda $66 : adc #$00 : sta $66
40 |
41 | ; If ObjecTool is inserted...
42 | lda.l !rom_objectool_byte : cmp #$5C : bne .no_objectool
43 |
44 | ; ...jump to its code if the custom object number is $42-$4F or $52-$FF.
45 | lda $5A : cmp #$42 : bcc .no_objectool
46 | cmp #$50 : beq .no_objectool
47 | cmp #$51 : beq .no_objectool
48 |
49 | ; Jump to ObjecTool's custom normal objects code.
50 | ; This jumps in the middle of the NewNormObjects routine, right before PHB : PHK : PLB,
51 | ; assuming the code won't change in future updates.
52 | rep #$20
53 | lda.l !rom_objectool_normal_code_address : clc : adc.w #68 : sta $00
54 | sep #$20
55 | lda.l !rom_objectool_normal_code_address+2 : sta $02
56 | jml [$0000|!dp]
57 |
58 | .no_objectool:
59 | ; If midways are overridden, don't spawn it.
60 | lda !ram_midways_override : and #$7F : bne .return
61 |
62 | ; We only care about object 2D.
63 | jsr custom_midway
64 |
65 | .return:
66 | ; Jump back to an rts.
67 | jml $0DA53C|!bank
68 |
69 | custom_midway:
70 | ; Backup $59 ($58-$59 used for entrance info).
71 | lda $59 : pha
72 | stz $59
73 |
74 | ; Check which type of entrance it's set in the extra bytes.
75 | lda $5A : cmp #$50 : bcs .midway_entrance
76 | cmp #$40 : bcs .main_entrance
77 | cmp #$20 : bcs .secondary_water_entrance
78 |
79 | .secondary_entrance:
80 | and #$01 : ora #$02
81 | bra +
82 |
83 | .secondary_water_entrance:
84 | and #$01 : ora #$0A
85 | + sta $59
86 | lda $5A : and #$1E : asl #3 : tsb $59
87 | bra .end
88 |
89 | .main_entrance:
90 | and #$01
91 | bra +
92 |
93 | .midway_entrance:
94 | and #$01 : ora #$08
95 | + sta $59
96 |
97 | .end:
98 | ; If there's already enough custom midway objects, return.
99 | lda !ram_cust_obj_num : cmp.b #!max_custom_midway_num : bcs .return
100 |
101 | ; Update the custom midway objects counter.
102 | inc : sta !ram_cust_obj_num
103 |
104 | dec : asl : tax
105 | lda $57
106 | rep #$20
107 | and #$00FF : clc : adc $6B
108 |
109 | ; Store index to $7EC800.
110 | sec : sbc #$C800 : sta !ram_cust_obj_data,x
111 |
112 | ; Store entrance info.
113 | lda $58 : sta !ram_cust_obj_entr,x
114 |
115 | ; If this is the midway that triggered the current checkpoint, don't make it spawn.
116 | lda !ram_respawn : eor $58 : and #$FBFF
117 | sep #$20
118 | beq .return
119 |
120 | .spawn_midway:
121 | ldy $57
122 | lda #$38 : sta [$6B],y
123 | lda #$00 : sta [$6E],y
124 | lda $57 : and #$0F : beq .return
125 | dey
126 | lda #$35 : sta [$6B],y
127 | lda #$00 : sta [$6E],y
128 |
129 | .return
130 | ; Restore $59.
131 | pla : sta $59
132 | rts
133 |
134 | else
135 |
136 | ; Restore code, in case settings are changed.
137 | if read1($0DA415) == $5C && read1(!rom_objectool_byte) != $5C
138 |
139 | pushpc
140 |
141 | org $0DA415
142 | sep #$30
143 | lda $1931|!addr
144 |
145 | pullpc
146 |
147 | endif
148 |
149 | endif
150 |
--------------------------------------------------------------------------------
/src/retry_config/code/hijacks/death_counter.asm:
--------------------------------------------------------------------------------
1 | ; Position to write the counter to in the status bar.
2 | !counter_status_bar = $0F15|!addr
3 |
4 | ; YXPCCCT properties of the "DEATHS" word.
5 | ; The first number is the palette, the second is the GFX page (0 or 1).
6 | ; If you want to change the word itself, look at the table below.
7 | !death_word_props = l3_prop(6,0)
8 |
9 | if !status_death_word
10 |
11 | pushpc
12 |
13 | ; Here you can edit which tiles are drawn to the status bar.
14 | ; The first value in l3_tile is the tile number.
15 | org $008C89
16 | dw l3_tile($0D,!death_word_props) ; D
17 | dw l3_tile($0E,!death_word_props) ; E
18 | dw l3_tile($0A,!death_word_props) ; A
19 | dw l3_tile($1D,!death_word_props) ; T
20 | dw l3_tile($11,!death_word_props) ; H
21 | dw l3_tile($1C,!death_word_props) ; S
22 |
23 | pullpc
24 |
25 | elseif read1($008F49) == $5C
26 |
27 | pushpc
28 |
29 | ; Restore the original tilemap.
30 | ; Here I assume that people won't turn on the "DEATHS" display without also turning on the death counter display.
31 | org $008C89
32 | db $30,$28,$31,$28,$32,$28,$33,$28,$34,$28,$FC,$38
33 |
34 | pullpc
35 |
36 | endif
37 |
38 | if !status_death_counter
39 |
40 | pushpc
41 |
42 | org $008F49
43 | jml status_death_counter
44 |
45 | pullpc
46 |
47 | status_death_counter:
48 | ldx #$04
49 | .tiles_loop:
50 | lda !ram_death_counter,x : sta !counter_status_bar,x
51 | dex : bpl .tiles_loop
52 | .hide_loop:
53 | inx
54 | lda !ram_death_counter,x : bne .return
55 | cpx #$04 : beq .return
56 | lda #$FC : sta !counter_status_bar,x
57 | bra .hide_loop
58 | .return:
59 | jml $008F5B|!bank
60 |
61 | else
62 |
63 | pushpc
64 |
65 | ; Restore the hijack if settings are changed.
66 | if read1($008F49) == $5C
67 | org $008F49
68 | lda $0DBE|!addr
69 | inc
70 | endif
71 |
72 | pullpc
73 |
74 | endif
75 |
--------------------------------------------------------------------------------
/src/retry_config/code/hijacks/hex_edits.asm:
--------------------------------------------------------------------------------
1 | pushpc
2 |
3 | ; Change initial life counter.
4 | org $009E25
5 | db !initial_lives-1
6 |
7 | ; Fix for old initial sprite facing fix.
8 | if read1($01AD33) == $94
9 | org $01AD33
10 | db $D1
11 | endif
12 |
13 | if read1($01AD3A) == $95
14 | org $01AD3A
15 | db $D2
16 | endif
17 |
18 | ; Fix Message Box erasing some sprite tiles when closing.
19 | org $05B31B
20 | rts : db $69
21 |
22 | ; Prevent vanilla decrementing lives.
23 | org $00D0D8
24 | nop #3
25 | bra $09
26 |
27 | pullpc
28 |
--------------------------------------------------------------------------------
/src/retry_config/code/hijacks/hurry_up.asm:
--------------------------------------------------------------------------------
1 | pushpc
2 |
3 | ; We could probably handle this with UberASM alone,
4 | ; but the dcsave patch uses this jml to check if Retry is installed, so we'll replicate that.
5 | org $008E5B
6 | jml hurry_flag
7 |
8 | pullpc
9 |
10 | hurry_flag:
11 | if not(!disable_hurry_up)
12 | ; Restore original code.
13 | lda #$FF : sta $1DF9|!addr
14 |
15 | ; Set the hurry up flag.
16 | lda #$01 : sta !ram_hurry_up
17 | endif
18 |
19 | ; Return to the original code.
20 | jml $008E60|!bank
21 |
22 | if !disable_hurry_up
23 | ; The dcsave patch uses read3($008E5B)+8 to read the Retry freeram
24 | ; so we need to preserve that. 4 bytes already used for the JML.
25 | dd $69696969
26 | dl !ram_hurry_up
27 | endif
28 |
--------------------------------------------------------------------------------
/src/retry_config/code/hijacks/initial_facing_fix.asm:
--------------------------------------------------------------------------------
1 | pushpc
2 |
3 | if !initial_facing_fix
4 |
5 | org $05DA1C
6 | jml initial_facing_fix
7 |
8 | else
9 |
10 | ; Restore the original code.
11 | ; Don't force "No Yoshi Sign 2" intro if the fix is enabled.
12 | org $05DA1C
13 | if not(!no_yoshi_intro_fix)
14 | cmp #$52
15 | bcc $04
16 | else
17 | bra $06
18 | nop #2
19 | endif
20 |
21 | endif
22 |
23 | pullpc
24 |
25 | if !initial_facing_fix
26 |
27 | initial_facing_fix:
28 | ; Copy the next frame position to the current frame's.
29 | ; This fixes the direction for sprites using the SubHorzPosBnk1 routine.
30 | rep #$10
31 | ldx $94 : stx $D1
32 | ldx $96 : stx $D3
33 | sep #$10
34 |
35 | ; Restore the original code.
36 | ; Don't force "No Yoshi Sign 2" intro if the fix is enabled.
37 | if not(!no_yoshi_intro_fix)
38 | cmp #$52 : bcc +
39 | jml $05DA20|!bank
40 | +
41 | endif
42 | jml $05DA24|!bank
43 |
44 | endif
45 |
--------------------------------------------------------------------------------
/src/retry_config/code/hijacks/item_box_fix.asm:
--------------------------------------------------------------------------------
1 | pushpc
2 |
3 | if !item_box_fix
4 |
5 | org $00C572
6 | jml item_box_fix
7 |
8 | else
9 |
10 | if read1($00C572) == $5C
11 |
12 | org $00C572
13 | lda $15
14 | and #$08
15 |
16 | endif
17 | endif
18 |
19 | pullpc
20 |
21 | if !item_box_fix
22 |
23 | item_box_fix:
24 | ; Don't drop the item if Mario is dead.
25 | lda $71 : cmp #$09 : bne +
26 | jml $00C58F|!bank
27 | +
28 | ; Restore original code.
29 | lda $15 : and #$08
30 | jml $00C576|!bank
31 |
32 | endif
33 |
--------------------------------------------------------------------------------
/src/retry_config/code/hijacks/multiple_midways.asm:
--------------------------------------------------------------------------------
1 | pushpc
2 |
3 | ; Hijack level loading routine to load correct sublevel.
4 | org $05D842
5 | jml mmp_main
6 |
7 | ; Make midway entrances work correctly.
8 | org $05D9DA
9 | jml midway_entrance
10 |
11 | ; Make vanilla midway entrances work correctly
12 | org $05D9EC
13 | jml vanilla_midway_destination_fix
14 |
15 | ; Make secondary exits compatible with "No Yoshi" intros.
16 | org $05DAA3
17 | jsl no_yoshi
18 |
19 | pullpc
20 |
21 | ; Write a small identifier string in ROM.
22 | db "Retry patch v!version by KevinM"
23 |
24 | mmp_main:
25 | ; If not entering from the overworld, return.
26 | lda $141A|!addr : bne .return
27 |
28 | ; If it's a secondary exit, return.
29 | lda $1B93|!addr : bne .return
30 |
31 | ; If it's not the intro level, skip.
32 | lda $0109|!addr : beq .no_intro
33 |
34 | .intro:
35 | ; Filter title screen.
36 | cmp.b #!intro_level+$24 : bne ..return
37 |
38 | ; If the midway is set, load the level (use the backup since $1EA2 is reset earlier).
39 | lda $1EA2|!addr : and #$40 : bne ..midway
40 |
41 | ; Load the intro level.
42 | lda.b #!intro_level+$24 : bra ..return
43 |
44 | ..midway:
45 | ; Set to load level 0.
46 | ldx #$00
47 | ldy #$00
48 | bra .midway
49 |
50 | ..return:
51 | ; Return to level loading routine, after sta $13BF.
52 | jml $05D8A2|!bank
53 |
54 | .no_intro:
55 | ; Reset layer 1 and 2 X positions.
56 | rep #$20
57 | stz $1A
58 | stz $1E
59 | sep #$20
60 |
61 | ; Get current translevel number.
62 | jsr shared_get_translevel
63 | tay
64 | asl : tax
65 |
66 | ; If no midway was gotten, return.
67 | lda $1EA2|!addr,y : and #$40 : beq .return
68 |
69 | .midway:
70 | ; If we should load a secondary exit, branch.
71 | lda !ram_checkpoint+1,x : bit #$02 : bne .secondary_exit
72 |
73 | ; If we should load the Yoshi Wings level, do it.
74 | bit #$80 : beq +
75 | bit #$0A : bne +
76 | lda #$02 : sta $1B95|!addr
77 | dec : sta $0DC1|!addr
78 | +
79 | ; Store level number to load.
80 | rep #$20
81 | lda !ram_checkpoint,x : and #$01FF : sta $0E
82 |
83 | ; Return to level loading routine, after sta $0E/$0F.
84 | jml $05D8B7|!bank
85 |
86 | .return:
87 | ; Return to the beginning of level loading routine.
88 | jml $05D847|!bank
89 |
90 | .secondary_exit:
91 | ; Set entrance number.
92 | ora #$04 : sta $19D8|!addr
93 | lda !ram_checkpoint,x : sta $19B8|!addr
94 | stz $95
95 | stz $97
96 |
97 | ; Return to sublevel loading routine.
98 | jml $05D7B3|!bank
99 |
100 | midway_entrance:
101 | if !dynamic_ow_levels
102 | %lda_13BF() : tax
103 | lda $1EA2|!addr,x
104 | endif
105 |
106 | ; Restore original code.
107 | and #$40 : sta $13CF|!addr
108 |
109 | ; If no checkpoint was gotten, continue as normal.
110 | beq .normal
111 |
112 | .checkpoint:
113 | ; Check if the checkpoint destination is a midway entrance.
114 | phx
115 | txa : asl : tax
116 | lda.l !ram_checkpoint+1,x
117 | plx
118 | and #$0A : cmp #$08 : beq .midway
119 |
120 | .normal:
121 | jml $05D9EC|!bank
122 |
123 | .midway:
124 | lda $1EA2|!addr,x : and #$40
125 | ldx $1B93|!addr : bne .normal
126 | jml $05D9DE|!bank
127 |
128 | vanilla_midway_destination_fix:
129 | ; Skip if entering from the Overworld.
130 | lda $141A|!addr : beq .orig2
131 |
132 | ; Skip if not respawning in the level from Retry.
133 | lda !ram_is_respawning : beq .orig2
134 |
135 | ; Skip if the respawn entrance is not a midway entrance.
136 | lda !ram_respawn+1 : and #$0A : cmp #$08 : beq .midway
137 |
138 | .orig2:
139 | jmp .orig
140 |
141 | .midway:
142 | ; Get the destination level number in Y.
143 | rep #$30
144 | lda !ram_respawn : and #$01FF : tay
145 | sep #$20
146 |
147 | ; Check if the LM midway entrance patch is enabled.
148 | lda.l !rom_lm_midway_entrance_hack_byte : cmp #$22 : beq ..lm_midway_hack
149 |
150 | ..vanilla:
151 | ; If no separate entrances used, we just need to store the correct screen number.
152 | lda $F400,y : lsr #4 : sta $01
153 | jmp .orig
154 |
155 | ..lm_midway_hack:
156 | ; Backup $03 and $05
157 | pei ($03)
158 | pei ($05)
159 |
160 | ; Get the midway data pointer in $03
161 | lda.l $05D9E6|!bank : sta $05
162 | rep #$20
163 | lda.l $05D9E4|!bank : clc : adc #$000A : sta $03
164 | lda [$03] : pha
165 | inc $03
166 | lda [$03] : sta $04
167 | pla : sta $03
168 | sep #$20
169 |
170 | ; Set the screen number of midway entrance
171 | lda [$03],y : and #$10 : sta $01
172 | lda $F400,y : lsr #4 : ora $01 : sta $01
173 |
174 | ; Separate midway -> already set correctly
175 | lda [$03],y : bit #$20 : bne ..return
176 |
177 | ; Correct slippery/water flag for vanilla midway
178 | lda #$C0 : trb $192A|!addr
179 | lda $DE00,y : and #$C0 : ora $192A|!addr : sta $192A|!addr
180 |
181 | ; Correct the camera position for vanilla midway
182 | lda #$00 : xba
183 | lda $F400,y : sta $02
184 | and #$03 : tax
185 | lda $D70C,x : sta $20
186 | lda $02 : and #$0C : lsr #2 : tax
187 | lda $D708,x : sta $1C
188 |
189 | ; Correct the position if X/Y pos method 2 is used
190 | lda $D97D : cmp #$22 : bne ..return
191 |
192 | ; (now compatible with LM 3.00's routine at $05DD30)
193 | lda $D980 : sta $05
194 | rep #$20
195 | lda $D97E : clc : adc #$0004 : sta $03
196 | sep #$20
197 | jsl .jml
198 |
199 | ..return:
200 | ; Restore $03 and $05
201 | rep #$20
202 | pla : sta $05
203 | pla : sta $03
204 | sep #$20
205 |
206 | .orig:
207 | rep #$10
208 | lda $01
209 | jml $05D9F0|!bank
210 |
211 | .jml:
212 | jml [$0003|!dp]
213 |
214 | no_yoshi:
215 | ; Reset secondary exits flag.
216 | stz $1B93|!addr
217 |
218 | ; Restore original code.
219 | lda.l $05D78A|!bank,x
220 | rtl
221 |
--------------------------------------------------------------------------------
/src/retry_config/code/hijacks/remove_status_bar.asm:
--------------------------------------------------------------------------------
1 | ; Adapted from Lui's "Remove Status Bar" patch
2 |
3 | if !remove_vanilla_status_bar
4 |
5 | pushpc
6 |
7 | org $0081F4
8 | bra $01 : db $69
9 |
10 | org $008275
11 | jml nmi_hijack : db $69
12 |
13 | org $0082E8
14 | bra $01 : db $69
15 |
16 | org $00985A
17 | bra $01 : db $69
18 |
19 | org $00A5A8
20 | bra $01 : db $69
21 |
22 | pullpc
23 |
24 | nmi_hijack:
25 | lda $0D9B|!addr : bne .special
26 | if !sa1
27 | ldx #$81
28 | else
29 | lda #$81 : sta $4200
30 | endif
31 | lda $22 : sta $2111
32 | lda $23 : sta $2111
33 | lda $24 : sta $2112
34 | lda $25 : sta $2112
35 | lda $3E : sta $2105
36 | lda $40 : sta $2131
37 | jml $0082B0|!bank
38 | .special:
39 | jml $00827A|!bank
40 |
41 | else
42 |
43 | pushpc
44 |
45 | if read1($0081F4+2) == $69
46 | org $0081F4
47 | jsr $8DAC
48 | endif
49 |
50 | if read1($008275+4) == $69
51 | org $008275
52 | lda $0D9B|!addr
53 | beq $18
54 | endif
55 |
56 | if read1($0082E8+2) == $69
57 | org $0082E8
58 | jsr $8DAC
59 | endif
60 |
61 | if read1($00985A+2) == $69
62 | org $00985A
63 | jsr $8CFF
64 | endif
65 |
66 | if read1($00A5A8+2) == $69
67 | org $00A5A8
68 | jsr $8CFF
69 | endif
70 |
71 | pullpc
72 |
73 | endif
74 |
--------------------------------------------------------------------------------
/src/retry_config/code/hijacks/sram.asm:
--------------------------------------------------------------------------------
1 | ; This file handles expanding the normal SRAM and saving custom addresses to it.
2 | ; It works on both lorom (SRAM) and SA-1 (BW-RAM).
3 |
4 | ; Bank byte of the SRAM/BW-RAM address.
5 | !sram_bank = (!sram_addr>>16)
6 | !sram_defaults_bank = (tables_sram_defaults>>16)
7 |
8 | ; How big is the save table.
9 | !save_table_size = (tables_sram_defaults-tables_save)
10 | !save_table_size_game_over = (tables_save_not_game_over-tables_save)
11 |
12 | if !sram_feature
13 |
14 | pushpc
15 |
16 | ; Change SRAM size in the header.
17 | if read1($00FFD8) < !sram_size
18 | org $00FFD8
19 | db !sram_size
20 | endif
21 |
22 | ; Hijack save game routine.
23 | org $009BCB
24 | jml save_game
25 |
26 | ; Hijack load game routine.
27 | org $009CF5
28 | jml load_game
29 |
30 | pullpc
31 |
32 | ; Some helper macros.
33 | macro transfer(src,dst)
34 | pla
35 | mvn ,
36 | bra ..next
37 | endmacro
38 |
39 | macro next_iteration()
40 | lda $02 : clc : adc $04 : sta $02
41 | plb : plx
42 | txa : clc : adc #$0005 : tax
43 | cpx $06 : bcc .loop
44 | endmacro
45 |
46 | ;=====================================
47 | ; save_game routine
48 | ;=====================================
49 | save_game:
50 | ; Set the DBR.
51 | phk : plb
52 |
53 | ; Call the custom save routine.
54 | php : phb
55 | jsr extra_save_file
56 | plb : plp
57 |
58 | jsr get_sram_addr : sta $02
59 | lda.w #!save_table_size : sta $06
60 | ldx #$0000
61 | .loop:
62 | lda.w tables_save,x : sta $00
63 | phx : phb
64 | lda.w tables_save+3,x : sta $04
65 | dec : pha
66 | lda.w tables_save+2,x
67 | ldx $00
68 | ldy $02
69 | and #$00FF : beq ..use_00
70 | cmp #$007E : beq ..use_7E
71 | if !sa1
72 | cmp #$007F : beq ..use_7F
73 | cmp #$0040 : beq ..use_40
74 | ..use_41:
75 | %transfer($41,!sram_bank)
76 | ..use_40:
77 | %transfer($40,!sram_bank)
78 | endif
79 | ..use_7F:
80 | %transfer($7F,!sram_bank)
81 | ..use_7E:
82 | %transfer($7E,!sram_bank)
83 | ..use_00:
84 | %transfer($00|!bank8,!sram_bank)
85 | ..next:
86 | %next_iteration()
87 | .end:
88 | sep #$30
89 |
90 | ; Restore original code and jump back.
91 | plb
92 | ldx $010A|!addr
93 | jml $009BCF|!bank
94 |
95 | ;=====================================
96 | ; load_game routine
97 | ;=====================================
98 | load_game:
99 | ; Load or init the file
100 | beq +
101 | jmp init_file
102 | +
103 | ; Preserve DB, X, Y, P.
104 | phb : phk : plb
105 | phx : phy : php
106 |
107 | ; Call the custom load routine.
108 | sep #$30
109 | php : phb
110 | jsr extra_load_file
111 | plb : plp
112 |
113 | ; Set the save table size.
114 | rep #$30
115 | lda.w #!save_table_size : sta $06
116 |
117 | ; Load the save file.
118 | jsr load_file
119 |
120 | ; Restore DBR, P, X and Y.
121 | plp : ply : plx
122 | plb
123 |
124 | ; Restore original code and jump back.
125 | phx
126 | stz $0109|!addr
127 | jml $009CFB|!bank
128 |
129 | load_game_over:
130 | ; Preserve DB, X, Y, P.
131 | phb : phk : plb
132 | phx : phy : php
133 |
134 | ; Set the save table size.
135 | rep #$30
136 | lda.w #!save_table_size_game_over : sta $06
137 |
138 | ; Load the save file.
139 | jsr load_file
140 |
141 | ; Restore DBR, P, X and Y.
142 | plp : ply : plx
143 | plb
144 | rtl
145 |
146 | load_file:
147 | jsr get_sram_addr : sta $02
148 | ldx #$0000
149 | .loop:
150 | lda.w tables_save,x : tay
151 | phx : phb
152 | lda.w tables_save+3,x : sta $04
153 | dec : pha
154 | lda.w tables_save+2,x
155 | ldx $02
156 | and #$00FF : beq ..use_00
157 | cmp #$007E : beq ..use_7E
158 | if !sa1
159 | cmp #$007F : beq ..use_7F
160 | cmp #$0040 : beq ..use_40
161 | ..use_41:
162 | %transfer(!sram_bank,$41)
163 | ..use_40:
164 | %transfer(!sram_bank,$40)
165 | endif
166 | ..use_7F:
167 | %transfer(!sram_bank,$7F)
168 | ..use_7E:
169 | %transfer(!sram_bank,$7E)
170 | ..use_00:
171 | %transfer(!sram_bank,$00|!bank8)
172 | ..next:
173 | %next_iteration()
174 | .end:
175 | rts
176 |
177 | init_file:
178 | ; Preserve X and Y.
179 | phx : phy
180 |
181 | ; Set 8 bit X/Y for the custom routine.
182 | sep #$10
183 |
184 | ; Set DBR.
185 | phb : phk : plb
186 |
187 | ; Call the custom load routine.
188 | php : phb
189 | jsr extra_load_new_file
190 | plb : plp
191 |
192 | rep #$30
193 | lda.w #tables_sram_defaults : sta $02
194 | lda.w #!save_table_size : sta $06
195 | ldx #$0000
196 | .loop:
197 | lda.w tables_save,x : tay
198 | phx : phb
199 | lda.w tables_save+3,x : sta $04
200 | dec : pha
201 | lda.w tables_save+2,x
202 | ldx $02
203 | and #$00FF : beq ..use_00
204 | cmp #$007E : beq ..use_7E
205 | if !sa1
206 | cmp #$007F : beq ..use_7F
207 | cmp #$0040 : beq ..use_40
208 | ..use_41:
209 | %transfer(!sram_defaults_bank,$41)
210 | ..use_40:
211 | %transfer(!sram_defaults_bank,$40)
212 | endif
213 | ..use_7F:
214 | %transfer(!sram_defaults_bank,$7F)
215 | ..use_7E:
216 | %transfer(!sram_defaults_bank,$7E)
217 | ..use_00:
218 | %transfer(!sram_defaults_bank,$00|!bank8)
219 | ..next:
220 | %next_iteration()
221 | ..end:
222 | ; Initialize the intro level checkpoint.
223 | jsr shared_get_intro_sublevel
224 | sta !ram_checkpoint
225 |
226 | ; Keep 16 bit X/Y for the original code.
227 | sep #$20
228 |
229 | ; Restore DBR, Y and X.
230 | plb : ply : plx
231 |
232 | ; Jump back.
233 | jml $009D22|!bank
234 |
235 | ;=====================================
236 | ; get_sram_addr routine.
237 | ;
238 | ; Small routine to get the low and high byte of the destination address into $02.
239 | ;=====================================
240 | get_sram_addr:
241 | rep #$30
242 | lda $010A|!addr : and #$00FF : asl : tax
243 | lda.l .sram_addr,x
244 | rts
245 |
246 | .sram_addr:
247 | dw !sram_addr,!sram_addr+!file_size,!sram_addr+(2*!file_size)
248 |
249 | else
250 |
251 | ; Restore code, in case settings are changed.
252 | if not(!sram_plus) && not(!bwram_plus)
253 |
254 | pushpc
255 |
256 | if read1($00FFD8) == !sram_size
257 | org $00FFD8
258 | db $01
259 | endif
260 |
261 | if read1($009BCB) == $5C
262 | org $009BCB
263 | plb
264 | ldx $010A|!addr
265 | endif
266 |
267 | if read1($009CF5) == $5C
268 | org $009CF5
269 | bne $2B
270 | phx
271 | stz $0109|!addr
272 | endif
273 |
274 | pullpc
275 |
276 | endif
277 |
278 | endif
279 |
--------------------------------------------------------------------------------
/src/retry_config/code/hijacks/switch_palace_message_fix.asm:
--------------------------------------------------------------------------------
1 | ; This fixes the switch palace message sprite tiles having the wrong size
2 | ; when drawing sprites using UberASM Tool's gamemode 14 end label.
3 | ; This happens because vanilla only sets $0400 but not $0420.
4 |
5 | pushpc
6 |
7 | org $05B30E
8 | jsl switch_palace_message_fix
9 |
10 | pullpc
11 |
12 | switch_palace_message_fix:
13 | phy
14 | sep #$20
15 | tya : lsr #2 : tay
16 | lda #$00 : sta $0420|!addr,y
17 | rep #$20
18 | ply
19 | dey #4
20 | rtl
21 |
--------------------------------------------------------------------------------
/src/retry_config/code/hijacks/vanilla_boss_gm13.asm:
--------------------------------------------------------------------------------
1 | ;============================================
2 | ; This hijacks runs the level_init_3 code during the
3 | ; vanilla mode 7 bosses level loading.
4 | ; This is needed because gamemode 13 UberASM code
5 | ; isn't run when loading these levels.
6 | ;============================================
7 |
8 | pushpc
9 |
10 | org $009856
11 | jsl vanilla_boss_gm13
12 |
13 | pullpc
14 |
15 | vanilla_boss_gm13:
16 | ; Restore original code
17 | lda #$20 : sta $44
18 |
19 | ; Run gamemode 13 code
20 | jmp level_init_3_init
21 |
--------------------------------------------------------------------------------
/src/retry_config/code/hijacks/vanilla_midway.asm:
--------------------------------------------------------------------------------
1 | ;=====================================
2 | ; Hijack to the midway interaction routine to correctly handle checkpoints.
3 | ; Also handles skipping the midway powerup if applicable.
4 | ;=====================================
5 |
6 | pushpc
7 |
8 | org $00F2D8
9 | jml midway_main
10 |
11 | org $0DA691
12 | jml midway_spawn
13 |
14 | pullpc
15 |
16 | ;=====================================
17 | ; midway_main routine
18 | ;
19 | ; Handles giving the correct checkpoint when touching a midway.
20 | ;=====================================
21 | midway_main:
22 | ; Get the index of this tile in the map16 table.
23 | phx
24 | rep #$20
25 | pei ($04)
26 | jsr get_tile_index
27 | sep #$20
28 |
29 | ; If there's no custom midways in this sublevel, skip.
30 | lda !ram_cust_obj_num : dec : bmi .not_custom
31 |
32 | ; Loop through all custom midways IDs to see if this one is custom.
33 | asl : tax
34 | rep #$20
35 | .find_custom_midway_loop:
36 | lda !ram_cust_obj_data,x : cmp $04 : bne ..next
37 | jmp .custom
38 | ..next:
39 | dex #2 : bpl .find_custom_midway_loop
40 | sep #$20
41 |
42 | .not_custom:
43 | ; Signal that we have to set a normal midway.
44 | lda #$00 : sta !ram_set_checkpoint
45 | bra .return
46 |
47 | .custom:
48 | ; Set the respawn entrance value.
49 | lda !ram_cust_obj_entr,x : sta !ram_set_checkpoint
50 |
51 | .return:
52 | ; Restore $04.
53 | rep #$20
54 | pla : sta $04
55 | sep #$20
56 |
57 | ; Call the custom midway routine.
58 | ; (we already did PHX earlier).
59 | phy : php : phb : phk : plb
60 | jsr extra_midway
61 | plb : plp : ply : plx
62 |
63 | ; Only run the powerup code if applicable.
64 | ; If using the "SMB2-Styled" Health Bar patch, this should prevent healing
65 | ; at midways unless the flag is set.
66 | lda !ram_midway_powerup : beq +
67 | jml $00F2E0|!bank
68 | + jml $00F2E8|!bank
69 |
70 | ;=====================================
71 | ; Routine to get a block's $7EC800 index in $04 (16 bit).
72 | ; It should be run during the block interaction process.
73 | ;=====================================
74 | get_tile_index:
75 | phy : phx : php
76 | sep #$30
77 | lda $5B : lsr : bcs .vert
78 |
79 | .horz:
80 | lda $1933|!addr : beq +
81 | lda $9B : ora #$10
82 | bra ++
83 | + lda $9B
84 | ++ tax
85 |
86 | lda.l !rom_lm_version : cmp #$33
87 | rep #$20
88 | bcc +
89 | lda $13D7|!addr
90 | bra ++
91 | + lda #$01B0
92 | ++ sta $04
93 |
94 | jsr .multiply
95 |
96 | lda $9A : and #$00F0 : lsr #4
97 | clc : adc $04 : sta $04
98 | lda $98 : and #$FFF0
99 | clc : adc $04 : sta $04
100 |
101 | plp : plx : ply
102 | rts
103 |
104 | .vert:
105 | lda $1933|!addr : beq +
106 | lda $9B : clc : adc #$0E
107 | bra ++
108 | + lda $9B
109 | ++ asl : ora $99 : sta $05
110 |
111 | lda $9A : lsr #4 : sta $04
112 | lda $98 : and #$F0 : tsb $04
113 |
114 | plp : plx : ply
115 | rts
116 |
117 | ;=====================================
118 | ; Input:
119 | ; X: a, 8bit, unsigned.
120 | ; $04: b, 16bit, unsigned.
121 | ; output:
122 | ; $04: a*b, 16bit (least significant), unsigned.
123 | ;=====================================
124 | .multiply
125 | pei ($00)
126 | pei ($02)
127 | sep #$20
128 |
129 | stz $02
130 |
131 | if !sa1 == 0
132 | stx $4202
133 | lda $04 : sta $4203
134 | nop #3
135 | rep #$20
136 | lda $4216 : sta $00
137 | sep #$20
138 |
139 | ;stx $4202
140 | lda $05 : sta $4203
141 | rep #$20
142 | lda $01 : clc : adc $4216 : sta $01
143 | else
144 | stz $2250
145 |
146 | rep #$20
147 | txa : and #$00FF : sta $2251
148 | lda $04 : and #$00FF : sta $2253
149 | bra $00
150 | lda $2306 : sta $00
151 |
152 | stz $2250
153 | txa : and #$00FF : sta $2251
154 | lda $05 : and #$00FF : sta $2253
155 | lda $01 : clc : adc $2306 : sta $01
156 | endif
157 |
158 | lda $00 : sta $04
159 | pla : sta $02
160 | pla : sta $00
161 | rts
162 |
163 | ;=====================================
164 | ; midway_spawn routine
165 | ;
166 | ; Handles spawning the midway if the current checkpoint wasn't from itself.
167 | ;=====================================
168 | midway_spawn:
169 | ; If midways are overridden, don't spawn it.
170 | lda !ram_midways_override : and #$7F : bne .no_spawn
171 |
172 | ; Filter title screen, etc.
173 | lda $0109|!addr : beq .no_intro
174 | cmp.b #!intro_level+$24 : bne .spawn
175 |
176 | .no_intro:
177 | lda $1EA2|!addr,x : and #$40 : bne .checkpoint
178 | lda $13CE|!addr : bne .checkpoint
179 |
180 | .spawn:
181 | jml $0DA69E|!bank
182 |
183 | .checkpoint:
184 | ; Check if the checkpoint is for the main or sublevel.
185 | jsr shared_get_checkpoint_value
186 | cmp #$01 : bcs ..sublevel
187 |
188 | ..main:
189 | %lda_13BF() : bne ...no_intro
190 | jsr shared_get_intro_sublevel
191 | bra +
192 |
193 | ...no_intro:
194 | rep #$20
195 | and #$00FF : cmp #$0025 : bcc +
196 | clc : adc #$00DC
197 | bra +
198 |
199 | ..sublevel:
200 | rep #$20
201 | lda $010B|!addr
202 | + ora #$0C00 : eor !ram_respawn : and #$FBFF
203 | sep #$20
204 | bne .spawn
205 |
206 | .no_spawn:
207 | jml $0DA6B0|!bank
208 |
--------------------------------------------------------------------------------
/src/retry_config/code/include/misc.asm:
--------------------------------------------------------------------------------
1 | ; Miscellaneous stuff used by Retry.
2 | ; You usually shouldn't edit this file.
3 |
4 | ; Retry version number to write in ROM.
5 | !version = "0.8.1"
6 |
7 | ; What button exits the level while the game is paused (by default, select).
8 | !exit_level_buttons_addr = $16
9 | !exit_level_buttons_bits = $20
10 |
11 | ; Level number of the intro level (automatically adjusted to $01C5 when necessary).
12 | !intro_level = $00C5
13 |
14 | ; Read death time from ROM.
15 | !death_time #= read1($00F61C)
16 |
17 | ; Check which channel is used for windowing HDMA, for SA-1 v1.35 (H)DMA remap compatibility.
18 | ; It will be 7 on lorom or with SA-1 <1.35, and 1 with SA-1 >=1.35.
19 | !window_mask #= read1($0092A1)
20 | !window_channel #= log2(!window_mask)
21 |
22 | ; DMA channel used to upload the Retry prompt tiles.
23 | ; You should never need to edit this.
24 | !prompt_channel = 2
25 |
26 | ; Where in VRAM the prompt tiles will be uploaded to.
27 | ; You should never need to edit this.
28 | !sprite_vram = $6000
29 |
30 | ; Default amount of Yoshi Coins per level, used for the sprite status bar.
31 | ; Note that usually this is not used, as the value is read from the ROM.
32 | ; In case of patches editing the area around $00F346 (except for the
33 | ; "Per Level Yoshi Coins Amount" patch) then this value will be used.
34 | !default_dc_amount = 5
35 |
36 | ; Default X/Y position values for the Retry prompt text.
37 | ; These values are used when the black box is enabled, otherwise the values
38 | ; in setting.asm (or in the respective RAM addresses if used) are used.
39 | ; These are not recommended to be changed unless you also change the
40 | ; black box windowing configuration.
41 | !default_text_x_pos = $58
42 | !default_text_y_pos = $6F
43 |
44 | ; Stripe image table defines.
45 | !stripe_index = $7F837B
46 | !stripe_table = $7F837D
47 |
48 | ; Address for the custom midway amount.
49 | !ram_cust_obj_num = !ram_cust_obj_data+(!max_custom_midway_num*4)
50 |
51 | ; Address for the custom midway entrance value.
52 | !ram_cust_obj_entr = !ram_cust_obj_data+(!max_custom_midway_num*2)
53 |
54 | ; Define the custom sprites load table address.
55 | %define_sprite_table(sprite_load_table, $7FAF00, $418A00)
56 |
57 | ; SRAM size in the ROM header. Actual size is (2^!sram_size) KB.
58 | ; Not used on SA-1 roms.
59 | !sram_size = $03
60 |
61 | ; How big (in bytes) each save file is in SRAM/BW-RAM.
62 | !file_size = $0955
63 |
64 | ; SRAM/BW-RAM address to save to.
65 | if !sa1
66 | !sram_addr = $41A000
67 | else
68 | !sram_addr = $700400
69 | endif
70 |
71 | ; OW translevel number table.
72 | if !sa1
73 | !7ED000 = $40D000
74 | else
75 | !7ED000 = $7ED000
76 | endif
77 |
78 | ; Detect the SRAM Plus patch.
79 | if read1($009B42) == $04
80 | !sram_plus = 1
81 | else
82 | !sram_plus = 0
83 | endif
84 |
85 | ; Detect the BW-RAM Plus patch.
86 | if read1($009BD2) == $5C
87 | !bwram_plus = 1
88 | else
89 | !bwram_plus = 0
90 | endif
91 |
92 | ; Detects lx5's Custom Powerups.
93 | if read2($00D067) == $DEAD
94 | !custom_powerups = 1
95 | else
96 | !custom_powerups = 0
97 | endif
98 |
99 | ; Detects the "Level Depending on Ram" and similar patches.
100 | if read1($05DCDD) == $22 || read1($05DCE2) == $22
101 | !dynamic_ow_levels = 1
102 | else
103 | !dynamic_ow_levels = 0
104 | endif
105 |
106 | ; Detects if SA-1 MaxTile is inserted.
107 | if read1($00FFD5) == $23 && read3($0084C0) == $5A123 && read1($0084C3) >= 140
108 | !maxtile = 1
109 | !maxtile_buffer_max = $6180
110 | !maxtile_buffer_high = $6190
111 | !maxtile_buffer_normal = $61A0
112 | !maxtile_buffer_low = $61B0
113 | else
114 | !maxtile = 0
115 | endif
116 |
--------------------------------------------------------------------------------
/src/retry_config/code/include/rom.asm:
--------------------------------------------------------------------------------
1 | ; Defines for useful ROM addresses
2 | ; Most of them are used to check for the presence and hijack different tools and patches.
3 | !rom_death_pose #= $00D0B9|!bank
4 | !rom_death_song #= $00F60B|!bank
5 | !rom_timer_ticks #= $008D8B|!bank
6 | !rom_green_star_block_count #= $0091AC|!bank
7 | !rom_yoshi_tongue_extend_speed #= $01F319|!bank
8 | !rom_lm_version #= $0FF0B4|!bank
9 | !rom_lm_get_screen_routine #= $03BCDC|!bank
10 | !rom_objectool_byte #= $0DA106|!bank
11 | !rom_objectool_normal_code_address #= $0DA107|!bank
12 | !rom_amk_byte #= $008075|!bank
13 | !rom_dcsave_byte #= $05D7AB|!bank
14 | !rom_dcsave_init_address #= $05D7AC|!bank
15 | !rom_dcsave_midpoint_byte #= $00CA2B|!bank
16 | !rom_dcsave_midpoint_address #= $00CA2C|!bank
17 | !rom_sprite_load_orig #= $01AC9F|!bank
18 | !rom_initial_submap #= $009EF0|!bank
19 | !rom_sprite_19_fix_byte #= $01E762|!bank
20 | !rom_sumo_bro_lightning_y_speed #= $02DEB6|!bank
21 | !rom_dc_amount_cmp_byte #= $00F349|!bank
22 | !rom_dc_perlevel_patch_byte #= $00F346|!bank
23 | !rom_lm_midway_entrance_hack_byte #= $05D9E3|!bank
24 |
--------------------------------------------------------------------------------
/src/retry_config/code/include/tables.asm:
--------------------------------------------------------------------------------
1 | checkpoint_effect:
2 | fillbyte $00 : fill $200
3 |
4 | sfx_echo:
5 | fillbyte $00 : fill $40
6 |
7 | reset_rng:
8 | fillbyte $FF : fill $40
9 |
10 | disable_room_cp_sfx:
11 | fillbyte $00 : fill $40
12 |
13 | lose_lives:
14 | fillbyte $FF : fill $40
15 |
16 | macro _check_level(level, macro_name)
17 | if < 0 || > $1FF
18 | error "Error: % level values needs to be between $000 and $1FF!"
19 | endif
20 | endmacro
21 |
22 | macro _define_bitwise_index(level)
23 | !__idx #= ()>>3
24 | endmacro
25 |
26 | function _bitwise_table_value(level) = (1<<(7-((level)&7)))
27 |
28 | macro checkpoint(level, val)
29 | %_check_level(, "checkpoint")
30 | if < 0 || > 3
31 | error "Error: %checkpoint value needs to be between 0 and 3!"
32 | endif
33 |
34 | !__idx #=
35 | !{_checkpoint_effect_!{__idx}} ?= 0
36 | !{_checkpoint_effect_!{__idx}} #= !{_checkpoint_effect_!{__idx}}|()
37 |
38 | pushpc
39 |
40 | org tables_checkpoint_effect+!__idx
41 | db !{_checkpoint_effect_!{__idx}}
42 |
43 | pullpc
44 | endmacro
45 |
46 | macro retry(level, val)
47 | %_check_level(, "retry")
48 | if < 0 || > 4
49 | error "Error: %retry value needs to be between 0 and 4!"
50 | endif
51 |
52 | !__idx #=
53 | !{_checkpoint_effect_!{__idx}} ?= 0
54 | !{_checkpoint_effect_!{__idx}} #= !{_checkpoint_effect_!{__idx}}|(()<<4)
55 |
56 | pushpc
57 |
58 | org tables_checkpoint_effect+!__idx
59 | db !{_checkpoint_effect_!{__idx}}
60 |
61 | pullpc
62 | endmacro
63 |
64 | macro sfx_echo(level)
65 | %_check_level(, "sfx_echo")
66 |
67 | %_define_bitwise_index()
68 | !{_sfx_echo_!{__idx}} ?= 0
69 | !{_sfx_echo_!{__idx}} #= !{_sfx_echo_!{__idx}}|_bitwise_table_value()
70 |
71 | pushpc
72 |
73 | org tables_sfx_echo+!__idx
74 | db !{_sfx_echo_!{__idx}}
75 |
76 | pullpc
77 | endmacro
78 |
79 | macro no_reset_rng(level)
80 | %_check_level(, "no_reset_rng")
81 |
82 | %_define_bitwise_index()
83 | !{_no_reset_rng_!{__idx}} ?= 0
84 | !{_no_reset_rng_!{__idx}} #= !{_no_reset_rng_!{__idx}}|_bitwise_table_value()
85 |
86 | pushpc
87 |
88 | org tables_reset_rng+!__idx
89 | db !{_no_reset_rng_!{__idx}}^$FF
90 |
91 | pullpc
92 | endmacro
93 |
94 | macro no_room_cp_sfx(level)
95 | %_check_level(, "no_room_cp_sfx")
96 |
97 | %_define_bitwise_index()
98 | !{no_room_cp_sfx_!{__idx}} ?= 0
99 | !{no_room_cp_sfx_!{__idx}} #= !{no_room_cp_sfx_!{__idx}}|_bitwise_table_value()
100 |
101 | pushpc
102 |
103 | org tables_disable_room_cp_sfx+!__idx
104 | db !{no_room_cp_sfx_!{__idx}}
105 |
106 | pullpc
107 | endmacro
108 |
109 | macro no_lose_lives(level)
110 | %_check_level(, "no_lose_lives")
111 |
112 | %_define_bitwise_index()
113 | !{_no_lose_lives_!{__idx}} ?= 0
114 | !{_no_lose_lives_!{__idx}} #= !{_no_lose_lives_!{__idx}}|_bitwise_table_value()
115 |
116 | pushpc
117 |
118 | org tables_lose_lives+!__idx
119 | db !{_no_lose_lives_!{__idx}}^$FF
120 |
121 | pullpc
122 | endmacro
123 |
124 | macro checkpoint_retry(level, checkpoint, retry)
125 | %checkpoint(, )
126 | %retry(, )
127 | endmacro
128 |
129 | macro settings(level, checkpoint, retry, sfx_echo, no_reset_rng, no_room_cp_sfx, no_lose_lives)
130 | %checkpoint_retry(, , )
131 | if != 0
132 | %sfx_echo()
133 | endif
134 | if != 0
135 | %no_reset_rng()
136 | endif
137 | if != 0
138 | %no_room_cp_sfx()
139 | endif
140 | if != 0
141 | %no_lose_lives()
142 | endif
143 | endmacro
144 |
--------------------------------------------------------------------------------
/src/retry_config/code/level_init_1.asm:
--------------------------------------------------------------------------------
1 | ; Gamemode 11
2 |
3 | init:
4 | ; Reset frame counters and layer 1 and 2 X positions.
5 | rep #$20
6 | stz $13
7 | stz $1A
8 | stz $1E
9 | sep #$20
10 |
11 | ; Reset the custom midway object counter.
12 | lda #$00 : sta !ram_cust_obj_num
13 |
14 | ; Don't trigger the prompt by accident, and reset the death flag.
15 | sta !ram_prompt_phase
16 | sta !ram_is_dying
17 |
18 | ; Check if we entered from the overworld.
19 | lda $141A|!addr : bne .skip
20 |
21 | ; The game sets $13BF a bit later so we need to do it ourselves
22 | ; (unless it's right after a "No Yoshi" cutscene).
23 | lda $71 : cmp #$0A : bne +
24 | %lda_13BF()
25 | bra ++
26 | + jsr shared_get_translevel
27 | ++ asl : tax
28 |
29 | ; Don't trigger Yoshi init.
30 | lda #$00 : sta !ram_is_respawning
31 |
32 | ; Reset hurry up flag.
33 | sta !ram_hurry_up
34 |
35 | ; Call the custom reset routine.
36 | phx : php
37 | phb : phk : plb
38 | jsr extra_reset
39 | plb
40 | plp : plx
41 |
42 | ; Set the destination from the level's checkpoint value.
43 | rep #$20
44 | lda !ram_checkpoint,x : sta !ram_respawn
45 | sep #$20
46 |
47 | .skip:
48 | ; Reset Yoshi, but only if respawning, not during the Yoshi Wings entrance
49 | ; and not parked outside of a Castle/Ghost House.
50 | lda !ram_is_respawning : beq +
51 | lda $1B95|!addr : bne +
52 | if !counterbreak_yoshi != 1 && !counterbreak_yoshi != 2
53 | lda $1B9B|!addr : bne +
54 | endif
55 | stz $0DC1|!addr
56 | +
57 | rtl
58 |
--------------------------------------------------------------------------------
/src/retry_config/code/level_init_2.asm:
--------------------------------------------------------------------------------
1 | ; Gamemode 12
2 |
3 | init:
4 | ; Reset the "play CP sfx" flag.
5 | lda #$00 : sta !ram_play_sfx
6 |
7 | ; Set layer 2 interaction offsets
8 | ; (prevents layer 2 interaction from glitching on level load)
9 | jsl $05BC72|!bank
10 |
11 | ; Check if we entered from the overworld.
12 | lda $141A|!addr : beq .return
13 |
14 | ; Check if it's a normal room transition.
15 | lda !ram_is_respawning : bne .return
16 |
17 | .room_transition:
18 | ; Otherwise, check if we should count this entrance as a checkpoint.
19 | jsr shared_get_checkpoint_value
20 | cmp #$02 : bcc .return
21 |
22 | ; If entrance checkpoints are overridden, skip it.
23 | lda !ram_midways_override : bmi .return
24 |
25 | ..set_checkpoint:
26 | ; Set the checkpoint to the current entrance.
27 | rep #$20
28 | lda !ram_door_dest : sta !ram_respawn
29 | sep #$20
30 |
31 | ; Update the checkpoint value.
32 | jsr shared_hard_save
33 |
34 | ; Call the custom checkpoint routine.
35 | php : phb : phk : plb
36 | jsr extra_room_checkpoint
37 | plb : plp
38 |
39 | ; Set the "play CP sfx" flag if applicable.
40 | if !room_cp_sfx != $00
41 | jsr shared_get_bitwise_mask
42 | and.l tables_disable_room_cp_sfx,x : bne +
43 | lda #$01 : sta !ram_play_sfx
44 | +
45 | endif
46 |
47 | ; Save individual dcsave buffers.
48 | jsr shared_dcsave_midpoint
49 |
50 | .return:
51 | rtl
52 |
--------------------------------------------------------------------------------
/src/retry_config/code/level_init_3.asm:
--------------------------------------------------------------------------------
1 | ; Gamemode 6, 13
2 |
3 | init:
4 | if !pipe_entrance_freeze < 2
5 | ; If in the pipe entrance animation, lock/unlock sprites.
6 | lda $71 : cmp #$05 : bcc +
7 | cmp #$07 : bcs +
8 | lda.b #!pipe_entrance_freeze : sta $9D
9 | +
10 | endif
11 |
12 | ; If goal walk is in progress, reset the music to play.
13 | ; This ensures the song will be reloaded if dying and respawning in the same sublevel.
14 | lda $1493|!addr : beq +
15 | lda #$FF : sta $0DDA|!addr
16 | +
17 | ; Play the silent checkpoint SFX if applicable.
18 | if !room_cp_sfx != $00
19 | lda !ram_play_sfx : beq +
20 | lda.b #!room_cp_sfx : sta !room_cp_sfx_addr|!addr
21 | +
22 | endif
23 |
24 | ; If AMK is inserted, send the disable/enable SFX echo command
25 | ; depending on the current sublevel's sfx_echo setting.
26 | ; Also set a flag in RAM if SFX echo is enabled.
27 | lda.l !rom_amk_byte : cmp #$5C : bne +
28 | ldy #$05
29 | jsr shared_get_bitwise_mask
30 | and.l tables_sfx_echo,x : beq ++
31 | iny
32 | lda !ram_play_sfx : ora #$80 : sta !ram_play_sfx
33 | ++ sty $1DFA|!addr
34 | +
35 | ; Reset DSX sprites.
36 | if !reset_dsx
37 | stz $06FE|!addr
38 | endif
39 |
40 | ; Reset vanilla Boo rings.
41 | if !reset_boo_rings == 2
42 | rep #$20
43 | stz $0FAE|!addr
44 | stz $0FB0|!addr
45 | sep #$20
46 | endif
47 |
48 | ; Reset timer frame counter
49 | lda.l !rom_timer_ticks : sta $0F30|!addr
50 |
51 | ; If not entering from the overworld, skip.
52 | lda $141A|!addr : bne .room_transition
53 |
54 | ; Backup the timer value.
55 | rep #$20
56 | lda $0F31|!addr : sta !ram_timer+0
57 | sep #$20
58 | lda $0F33|!addr : sta !ram_timer+2
59 |
60 | .room_transition:
61 | ; Check if we're respawning or in a transition checkpoint.
62 | lda !ram_is_respawning : bne ..respawning
63 | jsr shared_get_checkpoint_value
64 | cmp #$02 : bcc .normal
65 |
66 | ..respawning:
67 | ; Fix issues with the "level ender" sprite.
68 | stz $1493|!addr
69 | stz $13C6|!addr
70 |
71 | ; Reset mode 7 values.
72 | rep #$20
73 | stz $36
74 | stz $38
75 | stz $3A
76 | stz $3C
77 | sep #$20
78 |
79 | ; Backup the music that should play.
80 | lda $0DDA|!addr : sta !ram_music_to_play
81 |
82 | .normal:
83 | ; Reset the respawning flag.
84 | lda #$00 : sta !ram_is_respawning
85 |
86 | if !sprite_status_bar
87 | ; Initialize and draw the status bar during the fadein
88 | jsr sprite_status_bar_init
89 | jsr sprite_status_bar_main
90 | endif
91 |
92 | main:
93 | if !fast_transitions
94 | ; Reset the mosaic timer.
95 | stz $0DB1|!addr
96 | endif
97 |
98 | rtl
99 |
--------------------------------------------------------------------------------
/src/retry_config/code/level_transition.asm:
--------------------------------------------------------------------------------
1 | ; Gamemode 10, 11, 16, 19
2 |
3 | init:
4 | ; Disable HDMA.
5 | stz $0D9F|!addr
6 | rtl
7 |
--------------------------------------------------------------------------------
/src/retry_config/code/load_overworld.asm:
--------------------------------------------------------------------------------
1 | ; Gamemode 0C
2 |
3 | init:
4 |
5 | ; Reset various counters.
6 | .counterbreak:
7 | if !counterbreak_yoshi == 1 || !counterbreak_yoshi == 3
8 | stz $13C7|!addr
9 | stz $187A|!addr
10 | endif
11 |
12 | if !counterbreak_powerup == 1 || !counterbreak_powerup == 3
13 | ; Reset powerup.
14 | stz $19
15 | endif
16 |
17 | if !counterbreak_item_box == 1 || !counterbreak_powerup == 3
18 | ; Reset item box.
19 | stz $0DC2|!addr
20 | endif
21 |
22 | if !counterbreak_coins == 1 || !counterbreak_coins == 3
23 | ; Reset coin counter.
24 | stz $0DBF|!addr
25 | endif
26 |
27 | if !counterbreak_bonus_stars == 1 || !counterbreak_bonus_stars == 3
28 | ; Reset bonus stars counter.
29 | stz $0F48|!addr
30 | stz $0F49|!addr
31 | endif
32 |
33 | if !counterbreak_score == 1 || !counterbreak_score == 3
34 | ; Reset score counter.
35 | rep #$20
36 | stz $0F34|!addr
37 | stz $0F36|!addr
38 | stz $0F38|!addr
39 | sep #$20
40 | endif
41 |
42 | ; Reset the current level's checkpoint if the level was beaten.
43 | .reset_checkpoint:
44 | ; Skip if the level wasn't just beaten.
45 | lda $0DD5|!addr : beq ..skip
46 | bmi ..skip
47 |
48 | ; Remove the checkpoint for the current level.
49 | jsr shared_reset_checkpoint
50 |
51 | ..skip:
52 | rtl
53 |
--------------------------------------------------------------------------------
/src/retry_config/code/nmi.asm:
--------------------------------------------------------------------------------
1 | ; Gamemode 14
2 |
3 | ;=====================================
4 | ; nmi routine
5 | ;
6 | ; I know that uploading each tile individually is slow, but it makes it easy
7 | ; to change where the tiles are uploaded to for the user, and easier to manage
8 | ; the case where the "exit" option is left out.
9 | ;=====================================
10 |
11 | level:
12 | if !sprite_status_bar
13 | ; Update the sprite status bar graphics.
14 | jsr sprite_status_bar_nmi
15 | endif
16 |
17 | if !no_prompt_draw
18 | rtl
19 | else
20 | ; Skip if it's not time to upload the tiles.
21 | lda !ram_update_request : bne .upload
22 | rtl
23 |
24 | .upload:
25 | ; Only upload on this frame.
26 | dec : sta !ram_update_request
27 |
28 | ; With 5+ cycle iterations it saves time over doing lda.l.
29 | phb : phk : plb
30 |
31 | ; Loop to upload all the tiles.
32 | ; If the exit option is disabled, we skip the XI tiles.
33 | lda !ram_disable_exit : beq +
34 | lda #$01
35 | + tay
36 | ldx.w .index,y
37 |
38 | ; Push GFX address depending on the box being enabled or not.
39 | ; Additionally the size to upload for the cursor is pushed as well.
40 | lda !ram_disable_box : beq +
41 | lda #$02
42 | + tay
43 | rep #$20
44 | lda.w .cursor_size,y : pha
45 | lda.w .gfx_addr,y : pha
46 |
47 | ; These values are the same for all uploads, so put them out of the loop.
48 | ldy.b #$80 : sty $2115
49 | lda.w #$1801 : sta.w prompt_dma($4300)
50 | ldy.b #retry_gfx>>16 : sty.w prompt_dma($4304)
51 | ldy.b #1<>16 : sta.w window_dma($4304)
271 | rts
272 |
273 | ; Windowing table to use normally
274 | .window:
275 | ; all cover / layer123 cover
276 | db $5D : db $FF,$00,$FF,$00
277 | db $12 : db $38,$C8,$FF,$00
278 | db $08 : db $90,$C8,$38,$C8
279 | db $08 : db $38,$C8,$FF,$00
280 | db $08 : db $88,$C8,$38,$C8
281 | db $0D : db $38,$C8,$FF,$00
282 | db $4C : db $FF,$00,$FF,$00
283 | db $00
284 |
285 | ; Windowing table to use when exit is disabled
286 | .window_no_exit:
287 | ; all cover / layer123 cover
288 | db $5D : db $FF,$00,$FF,$00
289 | db $12 : db $38,$C8,$FF,$00
290 | db $08 : db $90,$C8,$38,$C8
291 | db $1D : db $38,$C8,$FF,$00
292 | db $4C : db $FF,$00,$FF,$00
293 | db $00
294 |
--------------------------------------------------------------------------------
/src/retry_config/code/shared.asm:
--------------------------------------------------------------------------------
1 | ;================================================
2 | ; Shared routines and macros.
3 | ;================================================
4 |
5 | ;================================================
6 | ; Macro to push the current code's DB to the stack
7 | ; and set the DBR to label's bank.
8 | ; Note: remember to PLB when finished!
9 | ;================================================
10 | macro set_dbr(label)
11 | ?- pea.w (>>16)|((?-)>>16<<8)
12 | plb
13 | endmacro
14 |
15 | ;================================================
16 | ; Macro to JSL to a routine that ends in RTS.
17 | ;================================================
18 | macro jsl_to_rts(routine, rtl)
19 | phk : pea.w (?+)-1
20 | pea.w -1
21 | jml |!bank
22 | ?+
23 | endmacro
24 |
25 | ;================================================
26 | ; Macro to JSL to a routine that ends in RTS.
27 | ; Also sets up the DBR to the routine's bank.
28 | ;================================================
29 | macro jsl_to_rts_db(routine, rtl)
30 | %set_dbr()
31 | %jsl_to_rts(,)
32 | plb
33 | endmacro
34 |
35 | ;================================================
36 | ; Macro to load the current level number ($13BF).
37 | ; Calls the appropriate routine if dynamic OW levels are used.
38 | ;================================================
39 | macro lda_13BF()
40 | if !dynamic_ow_levels
41 | jsr shared_get_new_13BF
42 | else
43 | lda $13BF|!addr
44 | endif
45 | endmacro
46 |
47 | ;================================================
48 | ; Functions for (H)DMA address conversion
49 | ;================================================
50 | function dma(addr,ch) = ((addr)+((ch)*$10))
51 | function window_dma(addr) = dma(addr,!window_channel)
52 | function prompt_dma(addr) = dma(addr,!prompt_channel)
53 |
54 | ;================================================
55 | ; Utility functions for tilemap and stripe image management.
56 | ;================================================
57 | function xb(x) = (((x)&$FF)<<8)|(((x)>>8)&$FF)
58 | function l3_prop(pal,page) = ($20|(((pal)&7)<<2)|((page)&1))
59 | function l3_tile(tile,pal) = ((tile)|((pal)<<8))
60 | function str_header1(x,y) = xb($5000|((y)<<5)|(x))
61 | function str_header2(len,rle) = xb((((rle)&1)<<14)|(len))
62 |
63 | ;================================================
64 | ; Utility functions for VRAM and graphics.
65 | ;================================================
66 | function vram_addr(offset) = (!sprite_vram+(offset*$10))
67 | function gfx_size(num) = (num*$20)
68 |
69 | ;================================================
70 | ; Routine to get the prompt type for the current level.
71 | ;================================================
72 | get_prompt_type:
73 | ; If in title screen, override the normal settings.
74 | lda $0100|!addr : cmp #$07 : bne .level
75 |
76 | .title:
77 | if !title_death_behavior < 2
78 | lda #$04
79 | else
80 | lda #$03
81 | endif
82 | rts
83 |
84 | .level:
85 | ; If the override address is set, skip the rest.
86 | lda !ram_prompt_override : bne .not_default
87 |
88 | ; Otherwise, if the effect for this level is set, skip the default.
89 | jsr get_effect_value
90 | cmp #$00 : bne .not_default
91 |
92 | ; Otheriwse, use the default value.
93 | lda.b #!default_prompt_type+1
94 |
95 | .not_default:
96 | rts
97 |
98 | ;================================================
99 | ; Get translevel number the player is standing on the overworld.
100 | ;================================================
101 | get_translevel:
102 | lda $0109|!addr : beq .no_intro
103 | lda #$00 : sta $13BF|!addr
104 | rts
105 | .no_intro:
106 | ldy $0DD6|!addr
107 | lda $1F17|!addr,y : lsr #4 : sta $00
108 | lda $1F19|!addr,y : and #$F0 : ora $00 : sta $00
109 | lda $1F1A|!addr,y : asl : sta $01
110 | lda $1F18|!addr,y : and #$01 : ora $01
111 | ldy $0DB3|!addr
112 | ldx $1F11|!addr,y : beq +
113 | clc : adc #$04
114 | + sta $01
115 | rep #$10
116 | ldx $00
117 | lda !7ED000,x : sta $13BF|!addr
118 | sep #$10
119 | if !dynamic_ow_levels
120 | jmp get_new_13BF_no_intro
121 | else
122 | rts
123 | endif
124 |
125 | ;================================================
126 | ; Get correct $13BF value for current level
127 | ; (for patches that change level number dynamically).
128 | ;================================================
129 | if !dynamic_ow_levels
130 | get_new_13BF:
131 | lda $0109|!addr : beq .no_intro
132 | lda #$00
133 | rts
134 | .no_intro:
135 | phb
136 | lda #$05 : pha : plb
137 | tya
138 | jsl $05DCDC|!bank
139 | plb
140 | lda $0E
141 | cpy #$00 : beq +
142 | clc : adc #$24
143 | + rts
144 | endif
145 |
146 | ;================================================
147 | ; Routine to save the current level's custom checkpoint value and set the midway flag.
148 | ;================================================
149 | hard_save:
150 | ; Filter title screen, etc.
151 | lda $0109|!addr : beq .no_intro
152 | cmp.b #!intro_level+$24 : beq .no_intro
153 | rts
154 |
155 | .no_intro:
156 | phx
157 |
158 | ; We won't rely on $13CE anymore, so set the midway flag in $1EA2.
159 | %lda_13BF() : tax
160 | lda $1EA2|!addr,x : ora #$40 : sta $1EA2|!addr,x
161 |
162 | ; Set the level's custom checkpoint.
163 | rep #$30
164 | txa : and #$00FF : asl : tax
165 | lda !ram_respawn : sta !ram_checkpoint,x
166 | sep #$30
167 |
168 | plx
169 | if !save_on_checkpoint
170 | jmp save_game
171 | else
172 | rts
173 | endif
174 |
175 | ;================================================
176 | ; Routine to remove the current level's checkpoint.
177 | ; Note: $13CE isn't cleared because it's also used in the OW loading routine.
178 | ;================================================
179 | reset_checkpoint:
180 | phx
181 | phy
182 | %lda_13BF() : tay
183 | rep #$30
184 | and #$00FF : asl : tax
185 | lsr : cmp #$0025 : bcc +
186 | clc : adc #$00DC
187 | + sta !ram_checkpoint,x
188 | sta !ram_respawn
189 | sep #$30
190 | lda $1EA2|!addr,y : and #~$40 : sta $1EA2|!addr,y
191 | ply
192 | plx
193 | rts
194 |
195 | ;================================================
196 | ; Routine to save the game.
197 | ;================================================
198 | save_game:
199 | phx
200 | phy
201 |
202 | ; Set up vanilla SRAM buffer.
203 | phb
204 | rep #$30
205 | ldx.w #$1EA2|!addr
206 | ldy.w #$1F49|!addr
207 | lda.w #$008C
208 | mvn $00,$00
209 | sep #$30
210 | plb
211 |
212 | ; Save to SRAM/BW-RAM.
213 | jsl $009BC9|!bank
214 |
215 | ply
216 | plx
217 | rts
218 |
219 | ;================================================
220 | ; Routines to reset and save the dcsave buffers.
221 | ;================================================
222 | dcsave:
223 | .init:
224 | ; Return if dcsave isn't installed.
225 | lda.l !rom_dcsave_byte : cmp #$5C : bne .return
226 |
227 | ; Load the address to the dcsave init wrapper routine.
228 | rep #$20
229 | lda.l !rom_dcsave_init_address : clc : adc #$0011 : sta $0D
230 | sep #$20
231 | lda.l !rom_dcsave_init_address+2 : sta $0F
232 |
233 | ; Call the dcsave routine.
234 | if !sa1
235 | %invoke_sa1(.jml)
236 | else
237 | jsl .jml
238 | endif
239 | rts
240 |
241 | .midpoint:
242 | ; Return if dcsave isn't installed.
243 | lda.l !rom_dcsave_byte : cmp #$5C : bne .return
244 |
245 | ; Only save if !Midpoint = 1.
246 | lda.l !rom_dcsave_midpoint_byte : cmp #$22 : bne .return
247 |
248 | ; Load the address to the dcsave save buffer routine.
249 | rep #$20
250 | lda.l !rom_dcsave_midpoint_address : sta $0D
251 | sep #$20
252 | lda.l !rom_dcsave_midpoint_address+2 : sta $0F
253 |
254 | ; Call the dcsave routine.
255 | jsl .jml
256 |
257 | .return:
258 | rts
259 |
260 | .jml:
261 | jml [$000D|!dp]
262 |
263 | ;================================================
264 | ; Routine to get the checkpoint value for the current sublevel.
265 | ; Returns the value in A (8 bit).
266 | ; You should use cmp #$00 to check for 0 after calling this.
267 | ; X,Y and P are preserved.
268 | ;================================================
269 | get_checkpoint_value:
270 | phx
271 | php
272 | rep #$10
273 | ldx $010B|!addr
274 | lda.l tables_checkpoint_effect,x
275 | and #$0F
276 | plp
277 | plx
278 | rts
279 |
280 | ;================================================
281 | ; Routine to get the effect value for the current sublevel.
282 | ; Returns the value in A (8 bit).
283 | ; You should use cmp #$00 to check for 0 after calling this.
284 | ; X,Y and P are preserved.
285 | ;================================================
286 | get_effect_value:
287 | phx
288 | php
289 | rep #$10
290 | ldx $010B|!addr
291 | lda.l tables_checkpoint_effect,x
292 | lsr #4
293 | and #$0F
294 | plp
295 | plx
296 | rts
297 |
298 | ;================================================
299 | ; Routine to get the index and mask to a bitwise sublevel table.
300 | ; Returns the index to the table in X, and the mask in A (8 bit).
301 | ; A/X/Y should be in 8-bit mode when calling this. Y is preserved.
302 | ;================================================
303 | get_bitwise_mask:
304 | lda $010B|!addr : and #$07 : tax
305 | lda.l .mask_table,x : pha
306 | rep #$20
307 | lda $010B|!addr : lsr #3 : tax
308 | sep #$20
309 | pla
310 | rts
311 |
312 | .mask_table:
313 | db $80,$40,$20,$10,$08,$04,$02,$01
314 |
315 | ;================================================
316 | ; Routine to get current screen number in X.
317 | ; If Lunar Magic 3.0+ is used, it may overwrite Y.
318 | ;================================================
319 | get_screen_number:
320 | lda.l !rom_lm_version : cmp #$33 : bcc .no_lm3
321 | lda.l !rom_lm_get_screen_routine : cmp #$FF : beq .no_lm3
322 | .lm3:
323 | jsl !rom_lm_get_screen_routine
324 | rts
325 | .no_lm3:
326 | ldx $95
327 | lda $5B : lsr : bcc .return
328 | ldx $97
329 | .return:
330 | rts
331 |
332 | ;================================================
333 | ; Routine that returns the intro sublevel in A.
334 | ; Output: A 16 bit, intro sublevel in A.
335 | ;================================================
336 | get_intro_sublevel:
337 | rep #$20
338 | lda.l !rom_initial_submap : and #$00FF : beq .normal
339 | lda.l !rom_sprite_19_fix_byte : cmp #$EAEA : bne .normal
340 | .modified:
341 | lda.w #!intro_level|$0100
342 | rts
343 | .normal:
344 | lda.w #!intro_level
345 | rts
346 |
347 | ;================================================
348 | ; Routine that updates the OAM table at $0400 using
349 | ; the decompressed mirror at $0420.
350 | ; Useful if you need to draw sprites during fadein.
351 | ;================================================
352 | update_0400:
353 | %jsl_to_rts_db($008494,$0084CF)
354 | rts
355 |
--------------------------------------------------------------------------------
/src/retry_config/code/startup.asm:
--------------------------------------------------------------------------------
1 | ; Gamemode 00
2 |
3 | init:
4 | ; Set the DBR to the freeram's bank for faster stores.
5 | %set_dbr(!retry_freeram)
6 |
7 | ; Initialize the retry ram to 0.
8 | rep #$30
9 | ldx.w #!ram_checkpoint-!retry_freeram-2
10 | - stz.w !retry_freeram,x
11 | dex #2 : bpl -
12 |
13 | ; Initialize "set checkpoint" handle to $FFFF.
14 | lda #$FFFF : sta.w !ram_set_checkpoint
15 |
16 | ; Initialize the checkpoint ram table.
17 | ldx #$00BE
18 | ldy #$005F
19 | - tya : cmp #$0025 : bcc +
20 | clc : adc #$00DC
21 | + sta.w !ram_checkpoint,x
22 | dex #2
23 | dey : bpl -
24 |
25 | ; Set the intro level checkpoint (level 0 = intro).
26 | jsr shared_get_intro_sublevel
27 | sta.w !ram_checkpoint
28 |
29 | sep #$30
30 |
31 | ; Initialize "No exit" flag.
32 | lda.b #!no_exit_option : sta.w !ram_disable_exit
33 |
34 | ; Initialize "No prompt box" flag.
35 | lda.b #!no_prompt_box : sta.w !ram_disable_box
36 |
37 | ; Initialize prompt position.
38 | lda.b #!text_x_pos : sta.w !ram_prompt_x_pos
39 | lda.b #!text_y_pos : sta.w !ram_prompt_y_pos
40 |
41 | ; Initialize "midway powerup" flag.
42 | lda.b #!midway_powerup : sta.w !ram_midway_powerup
43 |
44 | if !sprite_status_bar
45 | ; Initialize sprite status bar ram for intro level.
46 | jsr sprite_status_bar_init_ram
47 | endif
48 |
49 | plb
50 | rtl
51 |
--------------------------------------------------------------------------------
/src/retry_config/code/time_up.asm:
--------------------------------------------------------------------------------
1 | ; Gamemode 15
2 |
3 | init:
4 | if !time_up_fix
5 | ; Skip if it's not the "TIME UP!" screen.
6 | lda $143B|!addr : cmp #$1D : bne .return
7 |
8 | ; Check if the level timer was set to 0.
9 | lda !ram_timer+0 : ora !ram_timer+1 : ora !ram_timer+2
10 | and #$0F : bne .return
11 |
12 | ; If so, go to the Overworld directly.
13 | lda #$0B : sta $0100|!addr
14 | endif
15 |
16 | .return:
17 | rtl
18 |
--------------------------------------------------------------------------------
/src/retry_config/extra.asm:
--------------------------------------------------------------------------------
1 | ;=====================================
2 | ; All these routines are called in 8-bit A/X/Y mode and DBR is already set.
3 | ; Don't worry about overwriting registers, they'll be restored afterwards (except for direct page :P).
4 | ; All the routines must end with rts.
5 | ;=====================================
6 |
7 | ;=====================================
8 | ; This routine will be called when the level is reset by the retry system or when entering from the overworld.
9 | ; Unlike UberASM level init routine, this won't be executed during regular level transitions.
10 | ; NOTE: on SA-1 roms, this runs on the SNES cpu.
11 | ;=====================================
12 | reset:
13 | ; Feel free to put your code here.
14 |
15 |
16 |
17 | rts
18 |
19 | ;=====================================
20 | ; This routine will be executed everytime the player dies.
21 | ; NOTE: on SA-1 roms, this runs on the SNES cpu.
22 | ;=====================================
23 | death:
24 | ; Feel free to put your code here.
25 |
26 |
27 |
28 | rts
29 |
30 | ;=====================================
31 | ; This routine will be called every time the player touches a midway (vanilla or custom midway object).
32 | ; NOTE: on SA-1 roms, this runs on the SA-1 cpu.
33 | ;=====================================
34 | midway:
35 | ; Feel free to put your code here.
36 |
37 |
38 |
39 | rts
40 |
41 | ;=====================================
42 | ; This routine will be called every time the player gets a checkpoint through a room transition.
43 | ; Remember you can check for $13BF and $010B to know in which trans/sub-level you are.
44 | ; NOTE: on SA-1 roms, this runs on the SNES cpu.
45 | ;=====================================
46 | room_checkpoint:
47 | ; Feel free to put your code here.
48 |
49 |
50 |
51 | rts
52 |
53 | ;=====================================
54 | ; This routine will be called every time the player selects "exit" on the retry prompt.
55 | ; NOTE: on SA-1 roms, this runs on the SNES cpu.
56 | ;=====================================
57 | prompt_exit:
58 | ; Feel free to put your code here.
59 |
60 |
61 |
62 | rts
63 |
64 | ;=====================================
65 | ; This routine will be called every time the game is saved (before anything gets saved).
66 | ; Remember that you can check for the current save file in $010A.
67 | ; NOTE: on SA-1 roms, this may run on either cpu depending on what's calling the save routine.
68 | ;=====================================
69 | save_file:
70 | ; Feel free to put your code here.
71 |
72 |
73 |
74 | rts
75 |
76 | ;=====================================
77 | ; This routine will be called every time an existing save file is loaded (before anything gets loaded).
78 | ; Remember that you can check for the current save file in $010A.
79 | ; NOTE: on SA-1 roms, this runs on the SNES cpu.
80 | ;=====================================
81 | load_file:
82 | ; Feel free to put your code here.
83 |
84 |
85 |
86 | rts
87 |
88 | ;=====================================
89 | ; This routine will be called every time a new save file is loaded (before anything gets reset).
90 | ; Remember that you can check for the current save file in $010A.
91 | ; NOTE: on SA-1 roms, this runs on the SNES cpu.
92 | ;=====================================
93 | load_new_file:
94 | ; Feel free to put your code here.
95 |
96 |
97 |
98 | rts
99 |
100 | ;=====================================
101 | ; This routine will be called during the game over screen.
102 | ; This is called after the save file data is loaded from SRAM (only the data put before ".not_game_over" in "tables.asm") but before all the data is saved again to SRAM.
103 | ; This can be useful if you want to initialize some addresses for the game over and/or have them saved to SRAM.
104 | ; NOTE: on SA-1 roms, this runs on the SNES cpu.
105 | ;=====================================
106 | game_over:
107 | ; Feel free to put your code here.
108 |
109 |
110 |
111 | rts
112 |
113 | ;=====================================
114 | ; This routine will be called when Mario enters a door, every frame during the fade out.
115 | ; This could be useful since the door animation is the only one that can't be intercepted
116 | ; with level ASM or sprite ASM (since it immediately goes to the fading gamemode).
117 | ; If you need some level-specific action here, you can check the sublevel number in $010B (16 bit).
118 | ; If you need to only run the code for 1 frame, you can check for $0DB0 equal to 0.
119 | ; NOTE: on SA-1 roms, this runs on the SNES cpu.
120 | ;=====================================
121 | door_animation:
122 | ; Feel free to put your code here.
123 |
124 |
125 |
126 | rts
127 |
--------------------------------------------------------------------------------
/src/retry_config/gfx/bonus_stars.bin:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kkevinm/retry-system/4b1bea10675012a8e471574675489a8723252fb2/src/retry_config/gfx/bonus_stars.bin
--------------------------------------------------------------------------------
/src/retry_config/gfx/coins.bin:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kkevinm/retry-system/4b1bea10675012a8e471574675489a8723252fb2/src/retry_config/gfx/coins.bin
--------------------------------------------------------------------------------
/src/retry_config/gfx/digits.bin:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kkevinm/retry-system/4b1bea10675012a8e471574675489a8723252fb2/src/retry_config/gfx/digits.bin
--------------------------------------------------------------------------------
/src/retry_config/gfx/indicator.bin:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kkevinm/retry-system/4b1bea10675012a8e471574675489a8723252fb2/src/retry_config/gfx/indicator.bin
--------------------------------------------------------------------------------
/src/retry_config/gfx/item_box_16x16.bin:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kkevinm/retry-system/4b1bea10675012a8e471574675489a8723252fb2/src/retry_config/gfx/item_box_16x16.bin
--------------------------------------------------------------------------------
/src/retry_config/gfx/item_box_8x8.bin:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kkevinm/retry-system/4b1bea10675012a8e471574675489a8723252fb2/src/retry_config/gfx/item_box_8x8.bin
--------------------------------------------------------------------------------
/src/retry_config/gfx/letters1.bin:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kkevinm/retry-system/4b1bea10675012a8e471574675489a8723252fb2/src/retry_config/gfx/letters1.bin
--------------------------------------------------------------------------------
/src/retry_config/gfx/letters2.bin:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kkevinm/retry-system/4b1bea10675012a8e471574675489a8723252fb2/src/retry_config/gfx/letters2.bin
--------------------------------------------------------------------------------
/src/retry_config/gfx/lives.bin:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kkevinm/retry-system/4b1bea10675012a8e471574675489a8723252fb2/src/retry_config/gfx/lives.bin
--------------------------------------------------------------------------------
/src/retry_config/gfx/timer.bin:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kkevinm/retry-system/4b1bea10675012a8e471574675489a8723252fb2/src/retry_config/gfx/timer.bin
--------------------------------------------------------------------------------
/src/retry_config/ram.asm:
--------------------------------------------------------------------------------
1 | ;=====================================
2 | ; RAM addresses used by retry.
3 | ; You usually don't need to change these.
4 | ;=====================================
5 |
6 | ;=====================================
7 | ; What freeram to use.
8 | ; 241 + (!max_custom_midway_num*4) bytes are used.
9 | ; On SA-1, only !retry_freeram_sa1 is used.
10 | ;=====================================
11 | !retry_freeram = $7FB400
12 | !retry_freeram_sa1 = $40A400
13 |
14 | ;=====================================
15 | ; What freeram is used by AMK. Shouldn't need to be changed usually.
16 | ;=====================================
17 | !amk_freeram = $7FB000
18 |
19 | ;=====================================
20 | ; Don't change from here.
21 | ;=====================================
22 | if read1($00FFD5) == $23
23 | !retry_freeram = !retry_freeram_sa1
24 | endif
25 |
26 | macro retry_ram(name,offset)
27 | !ram_ #= !retry_freeram+
28 | !retry_ram_ #= !ram_
29 |
30 | base !ram_
31 | ram_:
32 | base off
33 | endmacro
34 |
35 | namespace off
36 |
37 | ; Use the same offsets as the retry patch to keep compatibility with other resources.
38 | ; The way to read these is: each row defines a Retry freeram address, where the name is the name to append to "!retry_ram_", and the number is the offset from !retry_freeram.
39 | ; For example, "%retry_ram(is_respawning,$05)" is defining "!retry_ram_is_respawning" as address "!retry_freeram+$05" (the "1" in the comment just means it's a 1 byte address).
40 | ; To use these in UberASM code, just use "retry_ram_is_respawning" (or whatever address you want), without the "!".
41 | ; To use these in other codes (patch, sprites, etc.), copy paste this file's contents at the start of the patch/sprite/etc., then use "!retry_ram_is_respawning" (with "!") or "retry_ram_is_respawning" (without "!").
42 |
43 | %retry_ram(timer,$00) ; 3
44 | %retry_ram(respawn,$03) ; 2
45 | %retry_ram(is_respawning,$05) ; 1
46 | %retry_ram(music_to_play,$06) ; 1
47 | %retry_ram(hurry_up,$07) ; 1
48 | %retry_ram(door_dest,$08) ; 2
49 | %retry_ram(music_backup,$0A) ; 1
50 | %retry_ram(update_request,$0B) ; 1
51 | %retry_ram(prompt_phase,$0C) ; 1
52 | %retry_ram(update_window,$0D) ; 1
53 | %retry_ram(is_dying,$0E) ; 1
54 | %retry_ram(9D_backup,$0F) ; 1
55 | %retry_ram(midway_powerup,$10) ; 1
56 | %retry_ram(prompt_override,$11) ; 1
57 | %retry_ram(disable_exit,$12) ; 1
58 | %retry_ram(set_checkpoint,$13) ; 2
59 | %retry_ram(prompt_x_pos,$15) ; 1
60 | %retry_ram(prompt_y_pos,$16) ; 1
61 | %retry_ram(disable_box,$17) ; 1
62 | %retry_ram(play_sfx,$18) ; 1
63 | %retry_ram(midways_override,$19) ; 1
64 | %retry_ram(coin_backup,$1A) ; 1
65 | %retry_ram(lives_backup,$1B) ; 1
66 | %retry_ram(bonus_stars_backup,$1C) ; 1
67 | %retry_ram(status_bar_item_box_tile,$1D) ; 2
68 | %retry_ram(status_bar_timer_tile,$1F) ; 2
69 | %retry_ram(status_bar_coins_tile,$21) ; 2
70 | %retry_ram(status_bar_lives_tile,$23) ; 2
71 | %retry_ram(status_bar_bonus_stars_tile,$25) ; 2
72 | %retry_ram(reserved,$27) ; 4 (reserved for future expansion)
73 | %retry_ram(death_counter,$2B) ; 5
74 | %retry_ram(checkpoint,$30) ; 192
75 | %retry_ram(cust_obj_data,$F0) ; 1+(!max_custom_midway_num*4)
76 |
--------------------------------------------------------------------------------
/src/retry_config/settings_local.asm:
--------------------------------------------------------------------------------
1 | ; This file is where you set Retry's level-specific settings.
2 | ; Supported settings:
3 | ; - %checkpoint(level, value)
4 | ; - %retry(level, value)
5 | ; - %checkpoint_retry(level, checkpoint, retry)
6 | ; - %sfx_echo(level)
7 | ; - %no_reset_rng(level)
8 | ; - %no_room_cp_sfx(level)
9 | ; - %no_lose_lives(level)
10 | ; - %settings(level, checkpoint, retry, sfx_echo, no_reset_rng, no_room_cp_sfx, no_lose_lives)
11 | ; For details, check out "docs/settings_local.html".
12 |
13 |
--------------------------------------------------------------------------------
/src/retry_config/sram_tables.asm:
--------------------------------------------------------------------------------
1 | ;=====================================;
2 | ; Save and SRAM default values tables ;
3 | ;=====================================;
4 | ; This table can be used to save custom values to SRAM, so they can persist when the console is turned off.
5 | ; By default it saves the custom checkpoint ram (so multiple midways will save properly) and the death counter.
6 | ; Each line is formatted as follows:
7 | ; dl $XXXXXX : dw $YYYY
8 | ; where:
9 | ; $XXXXXX = what RAM address to save. Make sure it's always 3 bytes long (i.e. use $7E0019 instead of $19 or $0019).
10 | ; $YYYY = how many bytes to save at that address (remove the $ to use a decimal value).
11 | ; For example, adding "dl $7E1F3C : dw 12" will make the 1-Up checkpoints for all levels save.
12 | ; Make sure to always put a colon between the two elements!
13 | ; The addresses you put under ".not_game_over" will be saved like usual, but they won't be reloaded from SRAM when getting a game over.
14 | ; This can be useful if you want some things to retain even if the player got a game over before being able to save them.
15 | ;
16 | ; Note: for each address you add here, you need to add the default values in the sram_defaults table below.
17 | ; Note: if using SA-1, for addresses in $7E0000-$7E1FFF you must change the bank to $40 ($400000-$401FFF).
18 | ; Additionally, a lot of other addresses might be remapped to different locations (see SA-1 docs for more info).
19 | ; Note: if using FastROM, using $000000-$001FFF instead of $7E0000-$7E1FFF will make the save/load process a bit faster.
20 |
21 | save:
22 | dl !ram_checkpoint : dw 192
23 | ; Feel free to add your own stuff here.
24 |
25 |
26 |
27 | .not_game_over:
28 | dl !ram_death_counter : dw 5
29 | ; Feel free to add your own stuff here.
30 |
31 |
32 |
33 | ; Here you specify the default values of the addresses you want to save, for when a new save file is started.
34 | ; You can do "db $XX,$XX,..." for 1 byte values, "dw $XXXX,$XXXX,..." for 2 bytes values and "dl $XXXXXX,$XXXXXX,..." for 3 bytes values.
35 | ; The amount of values of each entry should correspond to the dw $YYYY value in the save table
36 | ; (for example, the checkpoint values are 192, and the death counter values are 5).
37 | ; If you have some addresses after ".not_game_over" in the save table, put their default values after ".not_game_over" here too
38 | ; (in the same order as the other table, of course).
39 |
40 | sram_defaults:
41 | ; Default checkpoint values (don't edit this!).
42 | dw $0000,$0001,$0002,$0003,$0004,$0005,$0006,$0007
43 | dw $0008,$0009,$000A,$000B,$000C,$000D,$000E,$000F
44 | dw $0010,$0011,$0012,$0013,$0014,$0015,$0016,$0017
45 | dw $0018,$0019,$001A,$001B,$001C,$001D,$001E,$001F
46 | dw $0020,$0021,$0022,$0023,$0024,$0101,$0102,$0103
47 | dw $0104,$0105,$0106,$0107,$0108,$0109,$010A,$010B
48 | dw $010C,$010D,$010E,$010F,$0110,$0111,$0112,$0113
49 | dw $0114,$0115,$0116,$0117,$0118,$0119,$011A,$011B
50 | dw $011C,$011D,$011E,$011F,$0120,$0121,$0122,$0123
51 | dw $0124,$0125,$0126,$0127,$0128,$0129,$012A,$012B
52 | dw $012C,$012D,$012E,$012F,$0130,$0131,$0132,$0133
53 | dw $0134,$0135,$0136,$0137,$0138,$0139,$013A,$013B
54 | ; Feel free to add your own stuff here.
55 |
56 |
57 |
58 | .not_game_over:
59 | ; Initial death counter value (don't edit this!).
60 | db $00,$00,$00,$00,$00
61 | ; Feel free to add your own stuff here.
62 |
63 |
64 |
--------------------------------------------------------------------------------
/src/retry_unpatch.asm:
--------------------------------------------------------------------------------
1 | ; Patching this file with Asar will remove all of Retry's hijacks.
2 | ; Do not patch this if you don't want to remove the Retry from your ROM,
3 | ; and do not insert it with UberASM Tool either.
4 | ; Basically, you can ignore this file as long as you're using Retry in your ROM.
5 | ; For more information, see "docs/uninstall.html".
6 |
7 | if read1($00FFD5) == $23
8 | sa1rom
9 | !sa1 = 1
10 | !dp = $3000
11 | !addr = $6000
12 | !bank = $000000
13 | !sprite_slots = 22
14 | else
15 | lorom
16 | !sa1 = 0
17 | !dp = $0000
18 | !addr = $0000
19 | !bank = $800000
20 | !sprite_slots = 12
21 | endif
22 |
23 | if read1($00A2EA) == $5C && read4(read3($00A2EA+1)-4) == $4D6E6976
24 | org $00A2EA
25 | pla
26 | sta $1D
27 | pla
28 | endif
29 |
30 | org $05D842
31 | lda $0109|!addr
32 | db $D0
33 |
34 | org $05D9DA
35 | and #$40
36 | beq $0E
37 |
38 | org $05D9EC
39 | rep #$10
40 | lda $01
41 |
42 | org $05DAA3
43 | lda.l $05D78A|!bank,x
44 |
45 | org $00F2D8
46 | lda $13CD|!addr
47 | nop #2 ; LM edit.
48 |
49 | if read1($0DA415) == $5C && read1($0DA106) != $5C
50 | org $0DA415
51 | sep #$30
52 | lda $1931|!addr
53 | endif
54 |
55 | org $0DA691
56 | lda.l $001EA2|!addr,x
57 |
58 | if read1($009BCB) == $5C
59 | org $009BCB
60 | plb
61 | ldx $010A|!addr
62 |
63 | if !sa1 == 0
64 | org $00FFD8
65 | db $01
66 | endif
67 | endif
68 |
69 | if read1($009CF5) == $5C
70 | org $009CF5
71 | bne $2B
72 | phx
73 | stz $0109|!addr
74 | endif
75 |
76 | org $009E25
77 | db $04
78 |
79 | if read1($01AD33) == $94
80 | org $01AD33
81 | db $D1
82 | endif
83 |
84 | if read1($01AD3A) == $95
85 | org $01AD3A
86 | db $D2
87 | endif
88 |
89 | org $05DA1C
90 | cmp #$52
91 | bcc $04
92 |
93 | if read1($00C572) == $5C
94 | org $00C572
95 | lda $15
96 | and #$08
97 | endif
98 |
99 | org $00D0D8
100 | dec $0DBE|!addr
101 | bpl $09
102 |
103 | org $008E5B
104 | lda #$FF
105 | sta $1DF9|!addr
106 |
107 | if read1($008F49) == $5C
108 | org $008F49
109 | lda $0DBE|!addr
110 | inc
111 |
112 | ; Here I assume that people won't turn on the "DEATHS" display without also turning on the death counter display.
113 | org $008C89
114 | db $30,$28,$31,$28,$32,$28,$33,$28,$34,$28,$FC,$38
115 | endif
116 |
117 | if read1($0081F4+2) == $69
118 | org $0081F4
119 | jsr $8DAC
120 | endif
121 |
122 | if read1($008275+4) == $69
123 | org $008275
124 | lda $0D9B|!addr
125 | beq $18
126 | endif
127 |
128 | if read1($0082E8+2) == $69
129 | org $0082E8
130 | jsr $8DAC
131 | endif
132 |
133 | if read1($00985A+2) == $69
134 | org $00985A
135 | jsr $8CFF
136 | endif
137 |
138 | if read1($00A5A8+2) == $69
139 | org $00A5A8
140 | jsr $8CFF
141 | endif
142 |
143 | if read1($05B31B+1) == $69
144 | org $05B31B
145 | ldy #$1C
146 | endif
147 |
148 | org $009856
149 | lda #$20
150 | sta $44
151 |
152 | org $00D0D8
153 | dec $0DBE|!addr
154 | bpl $09
155 |
--------------------------------------------------------------------------------