| |||
Views: 88,489,670 |
Main | FAQ | Uploader | IRC chat | Radio | Memberlist | Active users | Latest posts | Calendar | Stats | Online users | Search | 04-26-24 09:03 PM |
|
Guest: Register | Login |
0 users currently in ROM Hacking | 2 guests |
Main - ROM Hacking - MM1: Spawn life energy capsule after beating rematch boss | New thread | New reply |
Insectduel |
| ||
Hammer Brother Level: 68 Posts: 121/1069 EXP: 2687864 Next: 40936 Since: 02-16-08 From: Insectduel's office Last post: 1257 days Last view: 1256 days |
ROM OFFSET 0x1CABA and edit the following in your favorite hex editor.
Example in screenshot Let me tell you something newbies just in case you don't know ASM. JSR jump to a new location while saving the current program counter. This is done by pushing the program counter onto the stack, then jumping to the location. In order for the user to return from the subroutine back to the originally saved program counter, a RTS or RTL instruction must be executed. Basically I added new codes into an empty space because I don't want to overwritten the existing code. My current ROM uses freespace mostly for enemy AI's and others for everything else. The freespace location I used is at ROM offset 0x17F86. Use this address only if you're NOT using any space. Otherwise change another JSR code in the other RAM address. BUT, there is a major problem. This takes away the spawn teleport in Wily 4 (Sprite 43). So if you're plan to use it in your hack, you have to change another scroll about 1 right or 1 down and don't forget to add special object 01 in your scroll path. See NetSplit's post. |
NetSplit |
| ||
Level: 32 Posts: 108/178 EXP: 188038 Next: 18404 Since: 02-26-07 Last post: 2217 days Last view: 2142 days |
This is one of the assembly hacks I've done for my MM1 hacks a few years back, albeit a more complex version. However, I'm confused by your implementation, and see some syntax problems that could cause major issues. For reference, here's the original routine, with some more comments thrown in by yours truly:
I don't know if Bisqwit has changed the address format to the better format your addresses are in since I last grabbed the disassembly, but the addresses here are in ROM format without a header. I'll use the addresses the code would use. So, if you're willing to sacrifice the teleporter, then I don't see why you can't just NOP out the first 6 bytes ($CAAA-CAAF) and modify $CAB5 to #$40, $CABC to #$80, $CAC5 to #$28, and $CACA to #$13. The way you did it is confusing; you shouldn't have to be using freespace. Furthermore, just a word of warning: be careful using space in other banks. You have to know for a fact that the bank you're using is always loaded. It may be in this case; I don't know. Just keep in mind that in many cases the game can have a different bank loaded if it wants to, which would cause the JSR you have there would probably cause a crash. Also, if you're posing modified assembly, please change all of the comments so that they're not mis-commenting (see line $CAD3). Your labels are a mess, too; for example, at $CAD5, you have a 9D opcode (STA Absolute,X) that's labeled as a STA Absolute, and the address is labeled as ObjectPosY+1, but it should be ObjectPosX,x. Your labels are all moved to the side after the address, so any assembler trying to reassemble this would choke everywhere because it would replace the labels with addresses and then have multiple addresses per instruction. You also have a JSR at the end that's way off; + is useful for branching forward or backward without declaring labels (I use an assembler that doesn't have it. Believe me, it's a great feature I wish I had). It's used for branches, while you used a JSR here. Additionally, ++ means to branch to ++, not to +\n+. Remove the ++ and just keep $BF76 and that JSR will assemble properly...oh, and make sure your comments start with a semicolon. You could also say JSR Freespace and then put a "Freespace:" label at $BF76, and that'd assemble fine, too. There's a definite flaw here, though. Your routine does a JSR to the code at Freespace, but does a JMP out of it. The JSR puts 2 bytes onto the stack (a return address), and if the game tries to get that data back with a PLA or something to that effect, it'll get the address instead of data and will possibly crash (and almost certainly do something unsavory when it gets to the next RTS). The JSR at $CADA should be a JMP so you don't put anything on the stack, and then you also won't need the RTS at $BF83, since there's an impassable JMP right before it. Frankly, unless there's an RTS at $CADD, I'm a bit surprised this routine seems to function properly. Anyway, sorry for the long post. I hope you learned a bit. I think it's worth being a hardass when it comes to programming code for multiple reasons. First is that it's important to practice good programming habits, which includes minding the stack. Stack abuse is something that almost always leads to problems and crashing. Another is that you have assembly code here, but it can't be assembled. There'd be errors all over the place. Typically, if an assembler can't read it, then it will be difficult for humans to read it, too, since there's some confusing element in there. I realize you were probably using this for reference and were inputting machine code directly into a hex editor, but that's not a good excuse when posting 'functional' code. A good start, though. You found the routine and modified it to seemingly function properly, which is great. Just mind your syntax and, more importantly, your stack, and you're good to go. Also, when modifying a routine, try to figure out more about it (like where the teleporter X and Y are coming from) so you don't have to make redundant, bloated code that requires precious freespace and uses excess precious cycles. Now that I'm done picking that apart... The item disappears after a set amount of time, right? If you want to have some more assembly fun, you could look into why and how to stop that. I implemented that that in my hack, as well, making this a special-case item (it differs from standard energy powerups in two ways, with no timer being one of them). You can disable the timer either with another assembly hack or by changing how you handle the spawning of the item; I chose the former because the latter didn't fit my implementation. For some beginning ASM modification, decent work. |
Insectduel |
| ||
Hammer Brother Level: 68 Posts: 122/1069 EXP: 2687864 Next: 40936 Since: 02-16-08 From: Insectduel's office Last post: 1257 days Last view: 1256 days |
Of course, I was so stupid. I haven't got the edge to see the code properly before I modify it but this is pure genius. Anyway, the code I used causes a bug after I beat wily in stage 4 causes him to fall from the top middle screen.
Sorry about the mixed, confusing writing. I was using the FCEUABS Debugger to copy a few notes down with Bisqwit's notes as well and haven't got time to find out. I'm not sure what MM1 ROM I'm using but I used Mega man (U) [!] to edit and I'm not sure if it has a header (or a change of an iNES header) or not. It's really fun to learn ASM on my own as I'm still learning some basics and stuff. |
NetSplit |
| ||
Level: 32 Posts: 110/178 EXP: 188038 Next: 18404 Since: 02-26-07 Last post: 2217 days Last view: 2142 days |
Your ROM will certainly have a header. The address format used in your code is superior because the game's code never cares about the addresses in the .nes, but rather in loaded ROM. It's not always possible to figure out what that address will be just by looking at the .nes addresses. Bisqwit has that style of address for part of the document because that section is based on AlphaBeta's old Mega Man document.
Interesting that it caused Wily to fall through the floor. Using my method fixes that? And yeah, learning assembly is great. It's all about diving right in and getting a lot of practice. |
Main - ROM Hacking - MM1: Spawn life energy capsule after beating rematch boss | New thread | New reply |
© 2005-2023 Acmlm, blackhole89, Xkeeper et al. |
MySQL - queries: 42, rows: 65/66, time: 0.015 seconds. |