| |||
Views: 88,434,105 |
Main | FAQ | Uploader | IRC chat | Radio | Memberlist | Active users | Latest posts | Calendar | Stats | Online users | Search | 04-19-24 03:16 AM |
|
Guest: Register | Login |
0 users currently in ROM Hacking | 1 guest |
Main - ROM Hacking - Zelda 2 restart from current palace after game over | New thread | New reply |
njosro |
| |||
Goomba Level: 13 Posts: 1/27 EXP: 8448 Next: 1819 Since: 05-15-14 Last post: 2532 days Last view: 2270 days |
This is my first post(!), my first time doing real ASM hacking, and the first time I really come to appreciate the tools FCEUX provides.
I heard about someone making it so that you start where you died if you were in a palace in zelda 2, instead of being sent allll the way back to zelda's castle. I never saw anything come of it though, so I decided to try for myself. I figured I could exploit the fact that the game has a real continue option for the great palace. This is when I discovered how magical fceux is. I used the code/data logger in conjunction with the trace logger to narrow my search for the relevant code. It took a few tries, but eventually I found it! The debugger was incredibly helpful in making the code understandable with the symbolic names and all that. ...sorry if I'm rambling about stuff you already know about! So this is what I found: Let's start with relevant RAM addresses. Naming these and finding their functions were the preliminary steps. $0700 - lives left $0701 - how Link enters the screen $0706 - overworld index (0=west hyrule, 1=death mtn/maze island, 2=east hyrule) $0707 - "world" (0=caves, enemy encounters...; 1=west hyrule towns; 2=east hyrule towns; 3=palace 1,2,5 ; 4=palace 3,4,6 ; 5=great palace) $0736 - screen intro type $0748 - area location index (the index of the spot on the overworld that pulled you into the sideview) $075C - start this many 'pages' into the scene $075F - something to do with music $0760 - I don't know... freezing it doesn't affect anything anywhere but it's in the code so... yeah $0561 - scene layout index (doesn't affect location) $076C - begin a special routine. Changing this value has the most 'automation' (00=restart from zelda's castle with 3 lives, 01=no routine, 02=die, 03=wake up zelda, 04=roll credits, 06=show the lives then restart the scene) Okay now for the the ASM code. It starts at CF30, but of course in the file it's really at 1CF40.
So it calculates with a formula whether to send you back to the beginning or keep you in the same "world". Here's my little pseudocode describing the situation. if (overworld_index*4+overworld_index+world = $F) { lives=3 ???++ special_routine++ scene_index=0 //return to the palace entrance Link_entrance_type=0 //walk in from the left pages_into_scene=0 special_routine=1 //don't do any special routine change_music=2 } else { special_routine=0 //go back to zelda's castle. This sets a bunch of ram addresses automatically. change_music=1 } My first step was to make it so that you stay in the current world no matter which palace you're in. So I changed the condition for branching.
(if you're in any world >= 3, you're in a palace so don't start over) And it worked!! ... except it always sets scene_index (ram $561) to 0, so if you're in the ocean palace, for example, you'll be sent to scene 0 of that world which is the entrance to parapa palace! But the palette stays green, and your location on the overworld is fine. At this point I thought I was in over my head, beyond my capabilities. I was really nervous about injecting my own routine instead of just manipulating what's already there! First I had to figure out how to get a unique number identifier for each palace, since I couldn't find one already in the game. I took the area location index ($748), world ($707), and overworld index ($706) of each palace and tried to see what I could do with that. After playing around a bit, I got a unique number for each one. It could probably be better, but this one works: overworld_index*4 + world + area_location_index = the palace id (sure why not) 4 is the smallest multiplier that prevents non-unique numbers for each palace. Now I needed a place to store the corresponding scene indices in RAM. I found a spot with a bunch of zeros and I'm hoping that it isn't used for anything important It's around $6500. I think that's near the SRAM? I also needed a place in ROM to put my code that would load the scene index from the correct RAM address. I found a bunch of FF's (undefined opcodes) in the debugger and stupid me thought it would be plenty of room for everything! (thinking 1 byte = room for a whole opcode and operand(s)) The FF's start at $D39A in rom. I just barely made it, in terms of available bytes. (2 bytes to spare!) At $CADE in rom I changed the JSR location from $C358 (the subroutine in bold from above) to $D39A (the FF's). At $D39A:
(the code then returns to that LDA #$00 statement, but I don't want A to be overwritten so I just changed it to LDY) I don't have an assembler and I don't know how to access fceux's inline assembler if it has one, so doing this by hand in the hex editor took a little while. (Good old pen and paper planning!) I gulped, started the game, went into the 'purple' palace and continued from a gameover. Annnnd.... (play 'item found' sound) it works!!!! For every single palace without a glitch! And then I realized I didn't code any scene_index lookup location for the great palace But lucky me, the spot in RAM that gets looked up for the great palace is unused (I hope) and always = 00 which is correct! So... wow, I actually did it. Hopefully without inadvertently causing problems somewhere else. video! https://www.youtube.com/watch?v=4PWFpUTDwK4 patch! http://acmlm.kafuka.org/uploader/get.php?id=4629 EDIT: a glitch was fixed. The link now takes you to the new patch. EDIT2: the glitch was fixed properly this time and works without causing problems elsewhere in the game (finally!) |
Chaobomr |
| ||
Buster Beetle Banned: Spammer takeover? Level: 45 Posts: 319/467 EXP: 638211 Next: 21953 Since: 05-07-13 From: The dirty south Last post: 3473 days Last view: 3471 days |
That's easy! You take an IPS Patcher (I'm gonna say Lunar IPS), and click on the option that essentially says "Create Patch." Then you go through the steps that the patcher tells you and voila! You have created an IPS! You can then upload that sucker here using that "Uploader" up there or right here, and post it using the <a href=""></a> or [url] tags. ____________________ Sorry for the stupidity. That jerk will be dealt with in the most insane way possible. |
njosro |
| ||
Goomba Level: 13 Posts: 2/27 EXP: 8448 Next: 1819 Since: 05-15-14 Last post: 2532 days Last view: 2270 days |
Oh cool I didn't think it would be that simple.
Ok, I'll edit my post above to include the patch. If anyone can think of a way to improve my code or to expand on it, let me know! |
Vanya |
| ||
Red Koopa Level: 27 Posts: 51/139 EXP: 104994 Next: 11165 Since: 01-22-13 Last post: 3286 days Last view: 3285 days |
Sweet! This is a great patch for people like me that have always been turned off by this one incredibly annoying 'feature' of Zelda II. ____________________ Krakenskin Leather Works, my Etsy store. LordVanya, my art page. FundamentalEssence, my game development page. |
njosro |
| ||
Goomba Level: 13 Posts: 3/27 EXP: 8448 Next: 1819 Since: 05-15-14 Last post: 2532 days Last view: 2270 days |
Ok so I did a whole playthrough of the game with my patch applied and everything worked completely fine until the very end... the game froze just as Thunderbird was about to die! > Also the continue feature might mess up in the great palace. Luckily I was able to find the opcodes causing the problems. I messed around with a few values because I was getting desperate and luckily got it to work. Thunderbird dies and if you die in the great palace you can continue glitch-free. That is, unless this new patch causes something else to go wrong. If anyone finds a new glitch, let me know.
Updated my first post with the new patch. |
njosro |
| ||
Goomba Level: 13 Posts: 4/27 EXP: 8448 Next: 1819 Since: 05-15-14 Last post: 2532 days Last view: 2270 days |
New update. version 3 patch caused glitches with some other bosses in the game. I got the will power to look through why this was happening and it turns out that the code at $CF30 is shared! If you're in the great palace then I guess it does a different defeat explosion? But that's how it is. It was checking for the great palace with CMP #$0F but with my modified code it should actually be #$05. This seems to work properly for everything, and I'm fairly confident that it won't cause any unwanted effects elsewhere (nothing noticeable anyway)
If you downloaded one of the older patches, just repatch the rom with this new one and it should work. |
Moo |
| ||
Micro-Goomba Level: 8 Posts: 10/10 EXP: 2015 Next: 172 Since: 03-05-13 Last post: 3621 days Last view: 3615 days |
When you get to a final version, you should submit this hack to romhacking.net. I'm sure a hack like this would be definately useful. |
Trax |
| ||
Yellow Stalfos Level: 71 Posts: 1143/1145 EXP: 3033986 Next: 133128 Since: 07-06-07 From: Québec Last post: 3619 days Last view: 2871 days |
The Palaces in the game have several codes that define them, but most of the time, it's not straightforward, like 00 for Palace 1 and 06 for Palace 7. There are two major RAM addresses that are used to refer to Side-Scrolling Areas. One is $607, which I call Region Code, and $707, which I call World Code...
Another very important RAM address is $748 : Overworld Area out of Side View. This address contains the Area Index that tells where Link will re-emerge when getting out of a Side-Scrolling Area. This value is used at $1CB82 to determine where Link will be located when he exits the Palace. With this information, you can find out the last Palace visited (where Link died last) and set the $706 and $707 variables accordingly... But maybe I'm overcomplicating things here. A long time ago, I tried to do the same as Njosro here is trying to accomplish. I almost succeeded, except that you would restart in any Area, including the non-Palace ones. So maybe by doing this, and adding a simple condition (one that is true only if you're in a Palace), we could have what we want... |
infidelity |
| ||
Fuzz Ball Level: 66 Posts: 523/968 EXP: 2366651 Next: 95200 Since: 05-24-07 Last post: 951 days Last view: 807 days |
Wow, great info/insight Trax! |
njosro |
| ||
Goomba Level: 13 Posts: 5/27 EXP: 8448 Next: 1819 Since: 05-15-14 Last post: 2532 days Last view: 2270 days |
Hey Trax thanks a lot for getting back to me!
If you download the patch you'll see it already does work as I want it to! At this point I just need to make sure I'm not interfering with something else by accident. In case you didn't see in my first post (which I wouldnt blame you because it's a mess of paragraphs ), I do use $706 and $707 to compute where the game should make you restart. The trick is that there is no single variable that can be used to identify which palace your're at, so I use a combination of the two. Just like in your chart, except I do *4 instead of *5. (two ASL instructions) The code is in my first post. Since we only want the game to care about where you are if you're in a palace, I took advantage of the fact that whenever $707 ('world') >= 3, you're in a palace. The original code does region*4 + region + world. If it equals $F, (which it only does if you're in the great palace), then it hard codes in the proper values of where to begin. I modified it so that if world >= 3, JSR to my own subroutine, which computes where to start off based on lookup values I manually store in RAM. The problem was that when the bosses die, they share the code that tests if region*4+region+world=$F so that Thunderbird can have a distinguished explosion from the other bosses. I don't remember the specifics but in my newest patch I fixed where the branching and jumping goes so it goes to the correct routines. Download the patch! Try it out |
Trax |
| ||
Yellow Stalfos Level: 71 Posts: 1144/1145 EXP: 3033986 Next: 133128 Since: 07-06-07 From: Québec Last post: 3619 days Last view: 2871 days |
Njosro, I've read your first post more attentively, and it covers most of the issue. About your hack, if it works without glitch, that's a good thing. While I give you brownie points for ASM, I've seen worrisome things about your code...
First, I would not temper with the R*5+W routine, because it's used in many places and it's not worth having glitches somewhere else in the game (like with the Thunderbird). Free space is not that limited, and this calculation can be used to find out about the Palaces Starting Screens... Your new routine stores arbitrary values one after the other in Cartridge RAM, but you could simply store a table somewhere in ROM, since this data is not meant to change... Also, there could be additional problems if you decide to move the Palaces around in the Overworld. The game engine presumes that all Palaces in a given region start at index 34 (1CB87) in the Overworld. Maximum 4 Palaces per region. There are at least two data tables that rely on this to confer the right values for Graphics Banks (1CD2A) and Palace Palettes (1CD35)... So, what do we want exactly? The right map number to start from. This value can be found in the Overworld Area Data Table, stored between 6A00 and 6AFB in Cartridge RAM (VRAM): 6A00-6A3E Area Byte 0 (Y Position) 6A3F-6A7D Area Byte 1 (X Position) 6A7E-6ABC Area Byte 2 (Map Number) 6ABD-6AFB Area Byte 3 (Region/World Code) Take byte 2, keep bits 0-5, and you've got your Map Number. That's where $748 comes handy. It's the index to use in these tables... |
njosro |
| ||
Goomba Level: 13 Posts: 6/27 EXP: 8448 Next: 1819 Since: 05-15-14 Last post: 2532 days Last view: 2270 days |
Yes this is exactly the kind of feedback I was looking for. I knew the way I did it is not a very good way.
For the R*5+W routine, I thought about the problems it might cause if changed, but I did three play throughs of the entire game and noticed no change, except for the original Thunderbird glitch. But the latest patch fixes that. The problem was that for Thunderbird's explosion, it would use my new thing of just taking 'world', then exit that subroutine and compare it to $F. I changed it to compare it to $5, which is of course the great palace. So now every boss works. Even Dark Link (because he doesn't explode of course). Nothing else has been affected by this change as far as I could tell when I played through it again. For me writing to RAM, I really didn't want to do that. It was just my on-the-spot thinking to get the job done. I was thinking about what you mentioned: moving the Palaces in the overworld, and how flexible my modification would be. Because what if, for example, ice penguin got a soft spot in his heart and decided to use the patch to make one of his future hacks easier ? There's no guarantee that the palace entrances would be the same. I actually do know about the area data table thanks to people like you and dwedit updating data crystal, although I thought it was only in ROM. I used that data to make an overworld editor that can modify areas (because hex editing for that is soooo archaic! And I don't have a mac to use yours). I haven't released it. Anyway, I'm no expert, but are you saying that I should use $748 to lookup the correct index, then extract the corresponding map number from byte 2, and use THAT as the scene to return the player to after a gameover? Something like this maybe: LDY $0748 LDA $6A7E , Y AND #%00111111 RTS ... STA $0561 is that kind of what you're saying? I'll try it out. Thanks EDIT: Ok maybe that's not what you meant... I tested it out. The problem is that the area tables completely change as soon as you enter a palace (or change to any other world I'm guessing), so the lookup index doesn't work for me inside a palace which is when I need it. Aw man EDIT 2: It doesn't fix anything, but I thought you were going from left to right talking about bits 0-5. Now I know you meant to go right-to-left. Fixed the code anyway. |
Trax |
| ||
Yellow Stalfos Level: 71 Posts: 1145/1145 EXP: 3033986 Next: 133128 Since: 07-06-07 From: Québec Last post: 3619 days Last view: 2871 days |
Yeah, I realized my mistake after posting. The code you wrote in your last message is exactly what I used myself, verbatim. But yes, the Area Data Bytes change when the world change, and the VRAM is updated, so it's a no-go that way...
To correct this, we would have to determine the correct bank to load, switch to it, load $561 accordingly, and switch back. It looks complicated when said like that, but games do that kind of manipulation all the time, and Zelda II is no exception... Your code could be simplified by taking the result of R*5+W, transfer it to Y, and use that index in your own custom table. If someone wants to change Palaces around, they could simply change these values by hand to match the starting areas of the palaces. Seems like a reasonable tradeoff... I just realized that the R*5+W routine is also used to determine the RAM range used for Item Presence. This is vital because this is what makes an item taken and doesn't reappear when you go back to the area. This data is saved to VRAM... |
njosro |
| ||
Goomba Level: 13 Posts: 7/27 EXP: 8448 Next: 1819 Since: 05-15-14 Last post: 2532 days Last view: 2270 days |
The R*5+W routine seems like it is very important in theory, but honestly I've played the patched rom, going back to areas after saving and restarting, and it remembers correctly that, for example, the candle was taken or a P-bag was taken. But if you're telling me I should change it back, I'll change it back.
Using Y as an index for my own custom table is what I had in the first place, except I make the game write it to RAM, which I know is not good. I don't know how to load data from a table of values in ROM. But like you said, doing it this way makes palace entrance manipulation an extra chore. I guess it isn't too much work for the user, but ideally I think we'd like this patch to work automatically even if the palace entrances get moved. If switching banks is what it takes to accomplish this, I'm willing to try. But I don't know how to switch banks... |
Main - ROM Hacking - Zelda 2 restart from current palace after game over | New thread | New reply |
© 2005-2023 Acmlm, blackhole89, Xkeeper et al. |
MySQL - queries: 102, rows: 135/136, time: 0.017 seconds. |