øAslickproductions.org/forum/index.php?PHPSESSID=5f0fck550j2m4m2fpbtkj2vkm1&action=printpage;topic=1831.0e:/My Web Sites/Slick Productions - FFIV Message Board/slickproductions.org/forum/index998a.htmlslickproductions.org/forum/index.php?PHPSESSID=5f0fck550j2m4m2fpbtkj2vkm1&topic=1831.0e:/My Web Sites/Slick Productions - FFIV Message Board/slickproductions.org/forum/index998a.html.zxœþg^ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÈ…¬·¡OKtext/htmlISO-8859-1gzip8:Ö·¡ÿÿÿÿÿÿÿÿTue, 10 Mar 2020 21:11:15 GMT0ó°° ®0®P®€§²ð®›þg^ÿÿÿÿÿÿÿÿ÷&·¡ Print Page - FF3us - 255 hours on timer

Board of Slick

Site Stuff => Slick News => Submissions => Topic started by: Leviathan Mist on May 29, 2013, 04:22:01 AM

Title: FF3us - 255 hours on timer
Post by: Leviathan Mist on May 29, 2013, 04:22:01 AM
(http://i.imgur.com/yyhgDYa.png)(http://i.imgur.com/7FaeVHU.png)

This is an improvement hack for Final Fantasy III US (SNES). It raises the maximum value for the in-game timer from 99:59 to 255:59.

I finally got around to doing this. Thanks for the help, Leno :P
Title: Re: FF3us - 255 hours on timer
Post by: Odbarc on June 02, 2013, 08:03:53 PM
Neat. May prove to be vital for hacks which have a longer than the default-game length intended.
Title: Re: FF3us - 255 hours on timer
Post by: JCE3000GT on June 02, 2013, 08:09:33 PM
Excellent, thank you.  I was looking for that data to change myself.  Saved me any further work on it. :)

Now, any idea if it's possible to change the byte data value over to an integer (2 byte)?  :D
Title: Re: FF3us - 255 hours on timer
Post by: Leviathan Mist on June 03, 2013, 06:58:02 PM
Excellent, thank you.  I was looking for that data to change myself.  Saved me any further work on it. :)

Now, any idea if it's possible to change the byte data value over to an integer (2 byte)?  :D

I looked into that a bit, but gave up when I realized that I'd basically have to write a whole new formula for both the in-game timer and the SRAM timer data. I'm not good enough to formulate assembly code from scratch yet :P

The problem is that the game stores data in RAM for seconds, minutes, and hours - each one being a single byte. I'm not sure if you could find a fourth byte to use for hours, and even if you did, I'm not sure how much of the game you'd have to edit to make it work. In theory, you could rework the formula to turn the seconds/minutes/hours bytes into a single 3-byte seconds counter instead, which would give you a total of 16777215 seconds, or 4660 hours before it rolls over. That would require a complete formula rewrite for the timer itself.

Also keep in mind that Step Mine's spell cost is affected by timer data, so the formula for Step Mine would have to be altered as well.
Title: Re: FF3us - 255 hours on timer
Post by: JCE3000GT on June 03, 2013, 10:40:25 PM
Is it possible to show the seconds?  :D
Title: Re: FF3us - 255 hours on timer
Post by: Leviathan Mist on June 04, 2013, 12:02:37 PM
Is it possible to show the seconds?  :D

That is indeed possible, and would be relatively easy provided you had enough space. The area for the menu timer that would need to be modified is here (courtesy of the co-opted C3 Bank Disassembly doc (http://slickproductions.org/docs/FF6/Bank%20C3%20disassembly.txt)):

Code: [Select]
C3/326C: AD8811  LDA $1188
C3/326F: 8910    BIT #$10
C3/3271: F016    BEQ $3289
C3/3273: AC8911  LDY $1189      (is $1189 the elapsed time in seconds?)
C3/3276: 20B232  JSR $32B2      (if so, this gives minutes)
C3/3279: 20B232  JSR $32B2      (and this would give hours)
C3/327C: A5E7    LDA $E7        (load A with hours)
C3/327E: 8D6318  STA $1863      (put hours in $1863)
C3/3281: AD1642  LDA $4216      (remainder is excess minutes)
C3/3284: 8D6418  STA $1864      (put that in $1864)
C3/3287: 800C    BRA $3295
C3/3289: AC1B02  LDY $021B      (Hours and minutes)
C3/328C: 8C6318  STY $1863      (store in SRAM)
C3/328F: AD1D02  LDA $021D      (Seconds amd frames)
C3/3292: 8D6518  STA $1865      (store in SRAM)
C3/3295: A920    LDA #$20
C3/3297: 8529    STA $29        (set text color to white)
C3/3299: AD6318  LDA $1863      (hours)
C3/329C: 20E004  JSR $04E0      (convert leading 0's to spaces)
C3/329F: A2FB7C  LDX #$7CFB     (The position, I believe)
C3/32A2: 20B604  JSR $04B6      (2 digits to display)
C3/32A5: AD6418  LDA $1864      (minutes)
C3/32A8: 20F904  JSR $04F9      (convert minutes to a displayable format)
C3/32AB: A2017D  LDX #$7D01
C3/32AE: 20B604  JSR $04B6      (JMP fool!, 2 digits to display)
C3/32B1: 60      RTS

You'd need to add the function for seconds display right before the RTS at C3/32B1. You'd also need to resize the timer window, and reposition hours and minutes. Here's how I would change it:

Code: [Select]
LDA $1863     
JSR $04E0     
LDX #$7CF5     (This will move the Hours counter 3 spaces to the left)
JSR $04C0      (This will change the counter from a 2-digit display to a 3-digit display)
LDA $1864     
JSR $04F9      (convert minutes to a displayable format)
LDX #$7CFB (This will move the minutes counter 3 spaces to the left)
JSR $04B6
LDA $1865 (seconds)
JSR $04F9 (convert to displayable format)
LDX #$7D01 (place where the minutes counter used to go)
JSR $04B6 (limit to 2 digits)
RTS

I'm not sure how this would affect the timer during timed events, such as catching Ultros in the opera house or the floating continent escape. There's a process which converts the timer from hours/minutes to minutes/seconds, but I can't remember where it's at.
Title: Re: FF3us - 255 hours on timer
Post by: Lenophis on June 04, 2013, 10:59:16 PM
That shouldn't be affected at all, since that timer is event-driven, which puts it in bank C0.
Title: Re: FF3us - 255 hours on timer
Post by: assassin on June 05, 2013, 04:41:30 AM
if you're in a battle, C2/B936 converts the timer into minutes and seconds for display.

looking at Variable $628F, it seems that this function is called every 61 frames rather than every 60?  meaning the display update will lag 1 frame behind each actual second update.  and if you're in a battle for over 60 seconds, you might see a 2-second decrement in this timer display..

maybe i'm misreading something here.  i'll test it in an emulator going frame-by-frame.
Title: Re: FF3us - 255 hours on timer
Post by: assassin on June 05, 2013, 05:14:57 AM
hah; confirmed.  the 2-second jump will occur 61 seconds into the battle, but maybe sooner..  i'm not sure on what frame alignments a battle can start, but suppose the real timer is at 20 seconds and 0 frames when a battle commences.  the initial display will indicate those 20 seconds.  then the display is updated 61 frames later, when the real timer is at 18 seconds and 59 frames -- meaning you'll see the seconds go from 20 to 18 without the 19.

those monkeys were apparently confused by C2/B925, even though it's right above C2/B936.  i think changing the "LDA #$3C" at the start of the latter function to "LDA #$3B" oughta solve it.  that said, i still need to do the frame-by-frame check, and verify that there are indeed 61 frames between display updates.
Title: Re: FF3us - 255 hours on timer
Post by: Leviathan Mist on June 05, 2013, 05:24:41 PM
 :wtf: were they thinking?
Title: Re: FF3us - 255 hours on timer
Post by: JCE3000GT on June 05, 2013, 06:53:41 PM
Oh cool, thanks!  I will play with it maybe this weekend.  But since I'm a novice with assembly I do have a question.  How do I relocate the subroutine in question to another place in the ROM so I can expand on it?   I didn't see a pointer. 
Title: Re: FF3us - 255 hours on timer
Post by: assassin on June 05, 2013, 08:58:22 PM
Quote from: assassin
that said, i still need to do the frame-by-frame check, and verify that there are indeed 61 frames between display updates.

confirmed this as well.

:wtf: were they thinking?

i did call them "monkeys" for it, but i can understand their mistake.  they want to update the display every 60 frames, so they set a "frame delay" variable to 60 in Function C2/B936.  if Function C2/B925 worked like:

- decrement frame delay variable
- branch to C2/B936 if the variable is zero

their delay would be as intended.  but the function does the variable check *before* decrementing it.  apparently, this is to make the timer display update the very first time C2/B925 is called in a battle.  i think that the frame delay variable is a default of zero to start a battle (as are many other variables), so my hypothetical order above wouldn't work right in that case.

anyway, Square's order means that C2/B936 won't be called on a frame where the variable goes from 1-->0, but on the frame _after_ that.  to compensate for that extra 1-frame wait, they should have made Variable $628F one smaller, at 59.

and that's what i shall do, in The Easiest Patch Ever (tm).
Title: Re: FF3us - 255 hours on timer
Post by: JCE3000GT on June 05, 2013, 10:20:57 PM
Assassin, any thoughts on my post?  :D
Title: Re: FF3us - 255 hours on timer
Post by: assassin on June 05, 2013, 11:54:58 PM
it was horrible! ;)  either:

1) change all references to $326C to have your new function's address, wherever that may be.  suppose it were located at C3/1234.  you'd change C3/311F to "20 34 12    JSR $1234", and C3/354B to "4C 34 12   JMP $1234".  C3/3143 and C3/3167, which enter Function C3/326C midway through at C3/3295, would also need to be adjusted.

so more generally, the format of the (non-relative) calls and branch instructions is: opcode (20h for the JSR, which is a call, or 4Ch for the jump JMP), low byte of offset, high byte of offset.  for a far call or jump, it's: opcode (22h for JSL, or 5Ch for JML), low byte of offset, high byte of offset, bank.

2) keep the original function in the same place, and just branch to free space to finish executing the added part.  so you'd include the first 7 instructions of Leviathan Mist's new code as written, then the first "JSR $04B6" would become "JMP $1234".  then at C3/1234, you'd have everything from the "JSR $04B6" through the end of his function.

this has the advantage of using less free space and not having to modify the functions that call or jump to C3/326C.  a disadvantage is that it's slightly slower due to the added "JMP $1234" instruction, but i doubt that matters.  hell, changing the "JSR $04B6" right before the "RTS" to a "JMP $04B6" like the disassembly recommends will make up for some of that.
Title: Re: FF3us - 255 hours on timer
Post by: JCE3000GT on June 07, 2013, 10:27:08 PM
Ok, I will dissect this and see if I can get it to work.  :)  Will let you know if I cannot get it to work...
Title: Re: FF3us - 255 hours on timer
Post by: Imzogelmo on August 02, 2013, 04:13:26 PM
Awesome work on the 255 hour timer. That's something I was hoping to do at some point, but never really got around to. I was even thinking of co-opting a byte somewhere to make a days counter, but for the reasons elaborated about finding another byte, I never did that either.

Also kudos to assassin on the bug fix!  :omghax:
Title: Re: FF3us - 255 hours on timer
Post by: Leviathan Mist on March 08, 2014, 05:04:56 PM
I had an interesting idea, to convert the hours/minutes timer into a days counter. However, it would require that I increase the maximum variable for the frames counter from 60 to 240. I know there are subroutines all over the place which pull the frames variable, and I'm curious if anyone knows of any potential issues that might arise if this variable is expanded.

The plan would be as follows:

Set maximum frame count to 240.
Set maximum "seconds" variable (which now increments every 4 seconds) to 216.
Set maximum "minutes" variable (which now increments every 864 seconds) to 100.
Set maximum "hours" variable (which now increments every 86400 seconds) to 255.

This would allow the timer to continue for 255 days before it caps out. The display timer would now show "Days" - which would show how many days, rounded to the nearest hundredth, you've been playing.

The only foreseeable issue with this is with the frame counter - I know there are at least a few formulas that use the frame counter, and assume it to be 1-60.
Title: Re: FF3us - 255 hours on timer
Post by: 13375K31C43R on February 29, 2016, 06:54:38 PM
I know this is an old thread, but I've been testing this and I've discovered that it interferes with the MP cost for Step Mine. MP costs for spells in general are 8-bit values, so without this patch, since the maximum time would be 99:59, the max MP cost for Step Mine would be 199. With this patch, the maximum time is 255:59, so in theory the max MP cost would be 511; however, this is no longer an 8-bit value. It's now a 9-bit value, but the top bit gets lost. As a result, for anyone who has played for 128 hours, Step Mine now has a cost of 0 when it should be 256.
Title: Re: FF3us - 255 hours on timer
Post by: Leviathan Mist on March 29, 2016, 11:52:40 PM
I know this is an old thread, but I've been testing this and I've discovered that it interferes with the MP cost for Step Mine. MP costs for spells in general are 8-bit values, so without this patch, since the maximum time would be 99:59, the max MP cost for Step Mine would be 199. With this patch, the maximum time is 255:59, so in theory the max MP cost would be 511; however, this is no longer an 8-bit value. It's now a 9-bit value, but the top bit gets lost. As a result, for anyone who has played for 128 hours, Step Mine now has a cost of 0 when it should be 256.

Thanks for bringing this to my attention. I have attached some patches to fix this. From the readme:

Quote
What is this?

In Final Fantasy III (US) there is a skill called Step Mine. This skill does damage based
on your total number of steps, and costs MP based on the total time played. I had created
a patch for the game that expands the timer to allow for up to 255 hours of gameplay to
be recorded. It was then brought to my attention, by 13375K31C43R, that this had an
adverse effect on Step Mine's MP cost. Since hours capped at 99, no rollover check was
put in place. At 128 hours, Step Mine's MP cost rolled over to 0. These patches will fix
this behavior when using my 255 hours patch.

The 199 patch will cap Step Mine MP cost at 199 (which was the natural maximum when hours
were capped at 99 - this is equivalent behavior to the original game and the choice for
purists who still want an expanded timer counter). It will cap at 199 when the timer
reaches 99:30, and will not go any higher when the hours go over 100.

The 255 patch will cap Step Mine's MP cost at 255. This will happen when the timer
reaches 127:30. It will not go any higher, nor will it roll over.

Edit: Apparently the patch isn't quite done yet. It fixes the MP cost in the menu, but not in battle. I'll work on the battle portion tomorrow.
Title: Re: FF3us - 255 hours on timer
Post by: assassin on March 30, 2016, 01:25:41 AM
as for adapting my revolutionary Step Mine MP cost fix to deal with this capping...

1) 255 cap:

- lengthen a branch:
Code: [Select]
C2/5665: D0 0E        BNE $5675      (branch and skip cost modification if not)
- put this code after the "TXA + ROL":

Code: [Select]
bcc okay
lda #$ff
okay:

- shift down the stuff under it accordingly.  there will still be 2 bytes to spare.

----------

2) 199 cap:

the smallest added code i can come up with is:
Code: [Select]
bcs over

cmp #$c8
bcc okay
over:
lda #$c7
okay:

that's 2 bytes too big, so it'll have to branch elsewhere.  i dunno what code is in Leviathan Mist's new function, so i can't say whether it's reusable here.
Title: Re: FF3us - 255 hours on timer
Post by: Leviathan Mist on March 30, 2016, 03:27:19 AM
I was under the assumption that your MP digit fix patch would simply work with the MP overflow fix.

Here's an overview of the code I used in these patches. The code modified is under the section listed to determine MP cost for a given spell.
(Credit: Co-opted C3 disassembly document by
Imzogelmo, Lenophis, assassin, Dragonsbrethren, Novalia Spirit )

Code right before that which is modified:
Code: [Select]
Determine the MP cost to a given spell
C3/510D: 48      PHA            (save current spell)
C3/510E: 20F550  JSR $50F5      (A = A * 14)
C3/5111: AE3421  LDX $2134      (X product of previous JSR)
C3/5114: BFC56AC4 LDA $C46AC5,X  (magic data, MP cost)
C3/5118: 85E0    STA $E0        (store MP cost)
C3/511A: 68      PLA            (get current spell)
C3/511B: C999    CMP #$99       (is the current spell Step Mine?)
C3/511D: D00F    BNE $512E      (branch if not)

The original code:
Code: [Select]
C3/511F: AD1B02  LDA $021B
C3/5122: 0A      ASL A          (* 2)
C3/5123: 85E0    STA $E0        (save as new MP cost)
C3/5125: AD1C02  LDA $021C
C3/5128: C91E    CMP #$1E
C3/512A: 9002    BCC $512E
C3/512C: E6E0    INC $E0        (add 1 to MP cost)

My modified code:
Code: [Select]
C3/511F: 20A1F0 JSR $F0A1 (Jump to new subroutine)
I simply moved this code down to an area where I would have more space for it. From C3/5122 to C3/512D, I emptied the code/replaced each byte with FF. (Could have done a bunch of NOP's here, but I was too lazy to do anything but just hold down the F key.)

Here's the actual important part of the new code (this one is for the 255 MP patch):
Code: [Select]
C3/F0A1: AD1B02 LDA $021B (Load hours)
C3/F0A4: C980 CMP #$80 (Are hours 128 or greater?)
C3/F0A6: 9005 BCC $F0AD (Branch to $F0AD if no)
C3/F0A8: A9FF LDA #$FF (Set MP cost to 255)
C3/F0AA: 85E0 STA $E0 (Store 255 as Step Mine MP cost)
C3/F0AC: 60 RTS (Return)
C3/F0AD: 0A      ASL A           (Multiply hours played by 2)
C3/F0AE: 85E0    STA $E0         (save this amount as new MP cost for Step Mine)
C3/F0B0: AD1C02  LDA $021C (load minutes)
C3/F0B3: C91E    CMP #$1E (Are minutes 30 or higher?)
C3/F0B5: 9002    BCC $F0B9 (Branch to $F0B9 if not)
C3/F0B7: E6E0    INC $E0         (add 1 to MP cost of Step Mine)
C3/F0B9: 60 RTS (Return)

The only changes between this and the 199 patch are the value at C3/F0A5 (64 instead of 80), and the value at C3/F0A9 (C7 instead of FF)
Title: Re: FF3us - 255 hours on timer
Post by: assassin on March 30, 2016, 03:51:34 AM
thanks for posting the code.

i actually meant my other Step Mine MP cost -related patch:
http://assassin17.brinkster.net/patches.htm#anchor32

:P

also, with no C2 modifications in your patch, you aren't capping the in-battle Step Mine cost.  see near the end of Function C2/5551.

----------

EDIT:

Quote
I simply moved this code down to an area where I would have more space for it. From C3/5122 to C3/512D, I emptied the code/replaced each byte with FF. (Could have done a bunch of NOP's here, but I was too lazy to do anything but just hold down the F key.)

won't the FFs break things after C3/F0A1 returns?  you might want those NOPs after all.
Title: Re: FF3us - 255 hours on timer
Post by: Leviathan Mist on March 30, 2016, 04:07:23 AM
also, with no C2 modifications in your patch, you aren't capping the in-battle Step Mine cost.  see near the end of Function C2/5551.
Wow, you're right. I completely forgot that battles use a different routine to determine MP cost, and that's important. It almost seems moot to cap it in the original game though, while leaving this bug intact. This patch looks like it should go hand-in-hand with yours. How about we co-author a patch for this that includes both the bugfix and the overflow fix?

won't the FFs break things after C3/F0A1 returns?  you might want those NOPs after all.

When I tested it, I didn't run into any problems. You're probably right though, nothing good ever comes out of being lazy/sloppy with code.
Title: Re: FF3us - 255 hours on timer
Post by: assassin on March 30, 2016, 04:16:58 AM
This patch looks like it should go hand-in-hand with yours. How about we co-author a patch for this that includes both the bugfix and the overflow fix?

sounds good.  but if it requires me to do anything, it'll probably wait until after April 15th.  i haven't started doing my taxes yet, so i'll be very busy the next 2 weeks.
Title: Re: FF3us - 255 hours on timer
Post by: Leviathan Mist on March 30, 2016, 04:21:09 AM
sounds good.  but if it requires me to do anything, it'll probably wait until after April 15th.  i haven't started doing my taxes yet, so i'll be very busy the next 2 weeks.

That's funny, I'm actually a certified tax preparer. But no, I can create the patch, but I would just be using your code instead of the original, and crediting you for your portion of it.
Title: Re: FF3us - 255 hours on timer
Post by: 13375K31C43R on March 30, 2016, 09:20:06 PM
I see that for purposes of spell menus, there are four bytes in RAM containing data for each spell at 7E:208E-7E:2091. $208E contains the spell ID, $2090 contains the aiming data and $2091 contains the MP cost...any idea what $208F is used for? I see it being used in a couple of places in bank C1, specifically bit 7, but I can't seem to debug it, nor can I find any place in the code where it's populated with any value.
Title: Re: FF3us - 255 hours on timer
Post by: assassin on March 30, 2016, 11:57:13 PM
availability; see C2/52DC.  only the top bit should matter, outside of the Sketch Glitch.
Title: Re: FF3us - 255 hours on timer
Post by: Rodimus Primal on April 11, 2016, 04:59:24 PM
Interesting. This affects the Woolsey Uncensored bug fix versions, so its certainly something to fix.
Title: Re: FF3us - 255 hours on timer
Post by: Leviathan Mist on April 27, 2016, 12:01:38 AM
Sorry for lack of updates guys, I completely forgot about this. I'll put it together this weekend.
Title: Re: FF3us - 255 hours on timer
Post by: C. V. Reynolds on May 02, 2016, 11:27:16 PM
Hoi, Leviathan. :3

Any updates on this? I'm interested. My apologies if you're busy. We all get busy sometimes, after all.
Title: Re: FF3us - 255 hours on timer
Post by: Imzogelmo on May 04, 2016, 05:05:21 PM
very very late and not related to the current course of discussion, but...

Changing the frame counter to max at 240 instead of 60 would also affect the Fixed Dice, which use the frame/10 to determine the 3rd die's value. So if you use 240, you'll need to change it to take frame/40.
Title: Re: FF3us - 255 hours on timer
Post by: Leviathan Mist on May 09, 2016, 01:35:24 AM
2 weeks later and I still haven't done it, I know. Been swamped and generally unmotivated. Not sure when I will pick this up, but assassin pretty much laid it out for you if you want to manually insert the fix along with his patch. If anyone else wants to take it on, you're welcome to - if not, I'll do it when my schedule opens up and I'm not feeling so drained by life. Sorry again.