Expansion of Treasure Chest subroutine - Printable Version +- FF6 Hacking (https://www.ff6hacking.com/forums) +-- Forum: Discussion Forums (https://www.ff6hacking.com/forums/forum-5.html) +--- Forum: Magitek Research Facility (https://www.ff6hacking.com/forums/forum-9.html) +--- Thread: Expansion of Treasure Chest subroutine (/thread-3706.html) Pages:
1
2
|
Expansion of Treasure Chest subroutine - NPCnextdoor - 07-01-2018 Hello, I started to learn ASM and I'm having lots of fun. I have an idea to expand the treasure chest subroutine. Currently, it offers the following possibilities:
I want to change it so it would also be possible to:
While the first two are technically already possible (as a small test, I changed the JSR branching of getting an item to the one that gives a summon and it worked. The message box was wrong, but I got the summon.), the other ones require an additional byte in the chest information. The Treasure Chest data is composed of 5 bytes starting at $ED/8634.
Here is the beginning of the subroutine: Code: C0/4C06: C220 REP #$20 (16 bit accum./memory) The thing is that the X register contains the relative value of the first byte of the current treasure chest. It is 5 times larger than the chest "ID". So, it gave me an idea. There is absolutely no need the keep the encoding byte/bit as hard-coded information if it can be found by a simple division (I know it costs many cycles, so it is not that simple! ). In that way, you ensure that every chest has its own encoding bit. Personally, I never liked the whole "not opening treasure chests so they offer more powerful items in the future" thing. I want to open ALL the chests. Additionally, it frees a whole byte. Code: C0/4C06 C2 20 -- -- REP #$20 Please note this is only a proof-of-concept. I know the code is really not optimized. I just wanted to move as less stuff as possible around. Now, this works. The chest is obtainable once and no longer available after that. But when the map is reloaded (after opening/closing the menu, finishing a battle or leaving the map and coming back), the chest is closed once more (its content can't be retaken though). My first question would be: Where in the map generation code the subroutine that decides if a chest is open or closed? Thanks in advance! RE: Expansion of Treasure Chest subroutine - madsiur - 07-01-2018 The treasure chest bits are at $7E1E40-$7E1E7F. The code is inevitably in bank $C0. Make a search for "$1E40", $C01614, $C04C24 (chest opening) and $C0BB14 (RAM / SRAM init) will come up. You answer should be $C01614, but I have not really looked closely at that code. BTW, this is a cool work. Nothing stops you once you found all relevant code to expand a data structure with any mean of programming, python or C family languages. A quick script can automate the data shuffling and the rest is regular ASM work and data relocation in some other ROM spot (expanding usually mean it won't fit in original ROM place unless you cut back on an amount of entries). RE: Expansion of Treasure Chest subroutine - NPCnextdoor - 07-01-2018 Found it! Thanks Madsiur! Code: Checking chest coordinates and event bit And yes, I already made a script to randomize the treasure chests. It will only be a matter of fooling around with the function to write information back to the ROM. RE: Expansion of Treasure Chest subroutine - madsiur - 07-02-2018 (07-01-2018, 11:20 PM)NPCnextdoor Wrote: And yes, I already made a script to randomize the treasure chests. It will only be a matter of fooling around with the function to write information back to the ROM. I was more referring to expand a structure in a general way, like from 5 bytes to 6 bytes in this case (though it is not needed in this hack). Biggest obstacles when this is wanted is that people don't have the tools to reorganize and edit the data. This is what is cool about being able to code in higher languages :) Is it a total chest randomization or are you keeping some structure for increase in loot types? As an example, preventing the paladin shield or top tier treasure to be found at beginning? RE: Expansion of Treasure Chest subroutine - NPCnextdoor - 07-02-2018 I thought about using 6 bytes if I was not going to be successful in eliminating the need for the event byte. But thanks to you, I found a way to do it! Regarding chest randomization, I have three options in mind:
I also want to randomize secret item locations, e.g. the clock, the armor, the fireplace and wherever Arvis checks when he takes the Slave Crown in his house could potentially hold an item. On top of that, since the game currently has a little more than 270 chests, there is still place for at least 200 other secret items. I want to see how many more of these could be added before it starts to feel ridiculous. RE: Expansion of Treasure Chest subroutine - NPCnextdoor - 07-14-2018 Update: I started the expansion with gold treasure chests. When I asked about how Final Fantasy VI handled 16 by 8-bit multiplication, Assassin wrote to look at C2/47B7. I must admit, I did not fully understand how it worked. Also, I noticed that the division process I used to get the chest ID did not work properly. By the time I arrive at the Returner's Hideout, most of the chests and pots are already empty. So, I decided to wrote my own subroutines instead of relying of the special registers that may or may not be used by something else. I have yet to write the long division, but here is my multiplication subroutine. (I love to say subroutine, I feel like I'm in Star Trek! ) I first experimented with hardcoding the multiplier, 10 in this case. Code: C2 21 REP #$21 16-bit mode + clear Carry bit So, of course, I wanted to automate the process for any 16-bit value so that I can reuse this subroutine. Here is what I got: Code: C0/D700 C2 31 -- REP #$31 16-bit accumulator mode, 16-bit X and Y registers and clear Carry bit I still don't understand why DEC $1C seems to be a 16-bit operation but INC $24 is only a 8-bit one. Does JSR has something to do with it? Feel free to propose code optimization. This is the result of moving pieces of code back and forth, hence the messy look. Also, is it possible to insert tables? I spend so much time trying to get the formatting right, but the tabulation in the editor doesn't act the same once it's published! RE: Expansion of Treasure Chest subroutine - assassin - 07-15-2018 C0/D722: for accuracy: switch the order of the $22 and $24 operations, so you can then rotate the Carry from the low bytes into the high. for speed and size: also, there's no need to load them into A. Code: ASL $22 ---- C0/D737: unless you plan to alter other CPU flags here, "CLC" is smaller. ---- for a similar but smaller way to do your non-special-register multiplication, look at C1/1867 and C1/18F4. here's the former since Slick is down for an eternity now: Code: (Multiply 16-bit $2E by 8-bit $2C, and put result in 32-bit $30-$33. RE: Expansion of Treasure Chest subroutine - NPCnextdoor - 07-15-2018 Thanks! I made the modifications. However, with ASL $22 ROL $24 (And also removing the BCS INC_HIGH_BYTE1 operation) It didn't work. The result was way too low. So I thought that perhaps ROL was 8-bit some how, even though the M flag is 0 (16-bit mode). So, I did ASL $22 ROL $25 ROL $24 And the result was way too high. However, ASL $22 ROL $25 Works perfectly! And I don't understand why. I did try first this approach (well, when I learnt eventually about the ROL opcode ) and because of this weird behavior, I took another route that I knew would work until I understood it better. I concluded that if some operations directly on the data were somehow always 8-bit, I would prefer to put the values in the A, X or Y registers first and put the results back. RE: Expansion of Treasure Chest subroutine - assassin - 07-15-2018 Quote:I still don't understand why DEC $1C seems to be a 16-bit operation but INC $24 is only a 8-bit one. Does JSR has something to do with it? what makes you think this? i never see your code change register size mid-function. so i think it's all 16-bits. ------ re C0/D744: 1) branching to this, and then returning by branching out to different places depending on the caller, is a mess. let's get rid of that. so instead of "BCS function", then a horrible mess inside "function", we'd do "BCC no_call_function / JSR function / no_call_function:". and inside of "function", we'd always return with an "RTS"; no spaghetti code branching. 2) you're in 16-bit mode, so there's no reason to increment both $24 and $25. just do $24. and chuck the "BCC", because the callers already limited when we'd reach here by usage of "BCS". 3) there's no point for a function anymore, anyway. just do the necessary incrementing inline. at C0/D737, have this: Code: CLC this change #3 supersedes the suggestions in #1 and #2. but i kept those anyway so you can see the motivation and process for refining or fixing code. RE: Expansion of Treasure Chest subroutine - NPCnextdoor - 07-18-2018 (07-15-2018, 05:44 PM)assassin Wrote:Quote:I still don't understand why DEC $1C seems to be a 16-bit operation but INC $24 is only a 8-bit one. Does JSR has something to do with it? Nevermind, I messed up the endianness in my head so I uselessly added operations to put $25 into $24 later in the code... and I just forgot about it a week later! I applied your suggestions. They work perfectly and the code is now 24 bytes smaller! |