Show Posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.


Messages - antd

Pages: [1] 2
1
Hi,
All of the links in the wiki are dead, concerning the Final Fantasy VII 1.02 Patch.

Could someone upload it?

Preferably to Google docs, Mega.co.nz, or some other good filehost.

Thanks.

2
I just suffered from this issue. However, I did not install Chrome.
Instead the issue was caused by Visual Studio Ultimate.

3
In the PC version, the 'random' offsets to the Random Number Lookup Table (RNLUT) increment even while the game is paused.

A random byte is accessed in this way at sub_5C8BA1 (decompiler output):
Code: [Select]
{
  return b_RNLUT[byte_C06740[dword_C06738]++];
}

The c06740 and c06738 offsets increment in a simple way which attempts to point to a random number each time.

However, in the PSX version the offsets are frozen when the game is paused.

It turns out that both implementations can be abused (only useful in a TAS).

So, the mechanics were changed to have the randomness always running in-battle, even when paused, was this change intentional?

I don't know why they would make this change. I haven't seen any problem with the in-battle randomness in the PSX version.

4
Ok, so I'm looking into the timers a little too much. Well, that's what happens when you are working on an FF7 TAS.

Again, looking at the Countdown Timer in the first reactor, it appears there is a flag that can cause the Countdown to reverse. If this flag is set, the Countdown will become a regular timer, counting up:

Code: (Assembly) [Select]
; CDFraction = Countdown Timer Fraction
; TimerDirection = Countdown Timer Direction Flag?
; CDSeconds = Countdown Timer Seconds


.text:0040AC0F mov     edx, dw_CDFraction       
.text:0040AC15 add     edx, 444h
.text:0040AC1B mov     dw_CDFraction, edx        ; increase Fraction by 1092
.text:0040AC21 mov     eax, dw_CDFraction
.text:0040AC26 shr     eax, 10h
.text:0040AC29 test    eax, eax                 ; check if Fraction is > 65535 (need to increment seconds)
.text:0040AC2B jz      short loc_40AC75         ; exit if < 65536 (no need to increment seconds)

.text:0040AC2D xor     ecx, ecx
.text:0040AC2F mov     cl, b_TimerDirection     ; Check timer direction (up or down)
.text:0040AC35 and     ecx, 2
.text:0040AC38 test    ecx, ecx                 ; TimerDirection AND 2
.text:0040AC3A jnz     short loc_40AC56

.text:0040AC3C cmp     dw_CDSeconds, 0
.text:0040AC43 jz      short loc
.text:0040AC45 mov     edx, dw_CDSeconds
.text:0040AC4B sub     edx, 1
.text:0040AC4E mov     dw_CDSecond              ; Count down seconds value

...
.text:0040AC56 loc_40AC56:
.text:0040AC56 mov     eax, dw_CDSeconds
.text:0040AC5B add     eax, 1
.text:0040AC5E mov     dw_CDSecond              ; Count up seconds value

Code: (pseudocode) [Select]
        dw_CDFraction += 1092;             
        if ( dw_CDFraction >> 16 )
        {                                   
          if ( b_TimerDirection & 2 )               
          {
            ++dw_CDSeconds;                 
          }
          else
          {
            if ( dw_CDSeconds )           
              --dw_CDSeconds;
          }
          dw_CDFraction & 0xFFFF;           

The problem is, the timer direction flag thing is never set to >1. At least I couldn't find any code that writes to it...
I found 2 instructions that write to it and all they do is change it to 1.

A value of 1 should have no effect here though?
1 AND 2 = 0
0 AND 2 = 0
2 AND 2 = 1
Code: [Select]
if ( b_TimerDirection & 2 )               
          {
            ++dw_CDSeconds;                 
          }
Seems to always be false.

So it would need to be set to 2 (at least) to make the timer increment instead of decrement.

Off the top of my head, I can only think of the snowboard game using a separate incrementing timer. But then I don't see the flag being set to anything >1 in the code.

The Flag address is only read/written in 3 places. It is read only once (here). It is written to in 2 other places; written to 1 and 0.

Does anyone have any insight on this? Or is this just useless code that they left in?

5
Perfect answers, thanks.

Have I understood correctly:
The 60 is just to convert the unit to seconds. The programmer specified the timer in minutes.
The 60 is hardcoded because the timer is always going to be based on seconds.

6
In the first reactor, after defeating Guard Scorpion, the countdown timer is set to 10 minutes (600 seconds).

I debugged this area of code and it seems a little strange to me.

The timer is set to 600 seconds (0x258) in this way:

Code: (Assembly) [Select]
; Set Countdown Timer to 0x258

; dw_CDSeconds = Countdown Timer RAM address

mov     cl, [edx+eax] ECX=0000040A
mov     [ebp+var_4], cl
mov     al, [ebp+var_4] EAX=0000000A    ; 10!

...
imul    eax, 3Ch                EAX=00000258    ; 10 * 60 = 600
mov     ecx, [ebp+var_4] ECX=00000000
add     ecx, eax         ECX=00000258
mov     [ebp+var_4], ecx ECX=00000258

...
mov     edx, [ebp+var_4] EDX=00000258

...
mov     eax, [ebp+var_4] EAX=00000258   
mov     dw_CDSeconds, eax                       ; 600 seconds for the countdown timer

It does many things in between and I understand the need to push to the stack, etc.

However, why does it go to the trouble of using the expensive imul instruction?
And why calculate 0x258 instead of using it directly as an immediate?

Would it not be more efficient to do something like:
Code: (Assembly) [Select]
mov     eax, 258h
mov     dw_CDSeconds, eax

I'm thinking they didn't do this because the countdown routine will be used in places other than the first reactor, and thus use a different seconds value (not 10 minutes)? >.<

I'm not a programmer. Please explain!

7
I just needed to know all of the memory addresses for PSX and there exact interaction for the TAS, hence the post!

8
Well.... better late than never, I suppose!

Code: [Select]
Random = [Rnd(0..65535) * 99 / 65535] + 1This post investigates the rnd part of the critical hit formula.

Code: [Select]
crit% = chance of critical       # (luck + level - enemy level) / 4
Here is how the randomness in critical hits is determined (Bad comments show PSX addresses ;p):

Code: [Select]
##Random Function##

lw r3,0x00d4(r28) # load word from 80062e18 = offset1
lui r2, 0x8006
addiu r2,r2,0x2e10 # 80062e10
addu r3,r3,r2 # 80062e10 + (word from 80062e18 as offset)
lbu r2,0x0(r3) # load byte from 80062e10(offset1) = offset2
nop

addiu r4,r2,0x01
andi r2,r2,0xff
sb r4,0x0(r3) # increment by 1 and store

lui r1,0x8008
addu r1,r1,r2 # 80083084
lbu r2,0x3084(r1) # load byte from 80083084(offset2) = rnd1
jr r31
nop

lw r3,0x0008(r28) # load word from 80062d4c
nop

addiu r4,r3,0x01 # increment by 1

andi r3,r3,0x07 # AND 7 (check that value < 8)
sw r4,0x08(r28) # store incremented value back to 8062d4c


beq r3,r0,0x14c18 # if crit% = 0 then no critical
addu r16,r2,r0 # move rnd1
jal 0x14b54
nop

lw r2,0xd4(r28) # load word from 80062e18
nop
addiu r2,r2,0x01 # increment by 1
andi r2,r2,0x07 # AND with 7 (check that value < 8) = offset2
sw r2,0xd4(r28) # store in 80026e18
jr r31
nop

jal 0x14b70
nop

lw r3,0xd4(r28) # load word from 80062e18 = offset3
lui r2,0x8006
addiu r2,r2,0x2e10
addu r3,r3,r2
lbu r2,0x0(r3) # load byte from 80062e10(offset3) = offset4
nop

addiu r4,r2,0x01
andi r2,r2,0xff
sb r4,0x0(r3) # increment byte by 1 and store in 80062e11

lui r1,0x8008
addu r1,r1,r2
lbu r2,0x3084(r1) # load byte from 80083084(offset4) = rnd2
jr r31
nop

andi r2,r2,0xff
sll r2,r2,0x08 # rnd2 * 256
andi r3,r16,0xff
or r2,r3,r2 # rnd1 OR rnd2 (combine rnd1 and rnd2) = rnd0
lw r31,0x14(r29)
lw r16,0x10(r29)
addiu r29,r29,0x18
jr r31
nop

lw r31,0x10(r29)
andi r2,r2,0xffff # take 2 bytes of rnd0
jr r31
addiu r29,r29,0x18


## calculate crit_rnd for which to compare against crit% ##

lui r4,0x8000
ori r4,r4,0x8001
andi r2,r2,0xffff
sll r3,r2,0x01 ## This section is actually simple, but compiler
addu r3,r3,r2 ## optimised for MIPS
sll r2,r3,0x05 ## Just: crit_rnd = ((rnd0 * 99) / 65535) + 1
addu r3,r3,r2
mult r3,r4
addu r2,r5,r3
sra r2,r2,0x0f
sra r3,r3,0x1f
subu r2,r2,r3
lw r31,0x10(r29)
addiu r2,r2,0x01
jr r31
addiu r29,r29,0x0018

slt r2,r16,r2
bne r2,r0,0xb0888 # if crit% >= crit_rnd then critical hit success
nop

9
Thanks for that.

10
Quote from: Terrence's Enemy Mechanics Guide
You will encounter a random battle if, during a battle check, Rnd(0..255) is
less than [Danger Counter * Enemy Lure Value / 256]


Note that the Enemy Lure Value is a fraction between 2/16ths to 32/16ths, but is only altered
through the presence of Enemy Lure and Enemy Away Materia on your party.
The default value when no such Materia is equipped is 16/16ths or 100%.

Yet, here is the disasm of the battle check (PSX NTSC U):

Code: [Select]
lui r4,0x8007
lhu r4,0x173c(r4) # load DangerValue
lui r3,0x8006
lbu r3,0x2f19(r3) # load EnemyLureValue (16)
nop
mult r4,r3 # DangerValue * EnemyLureValue (24128)
andi r2,r2,0xff
mflo r3
srl r3,r3,0x0c # (DangerValue * EnemyLureValue) / 4096
sltu r2,r2,r3
beq r2,r0,0xabef0 # if Rnd < [DangerValue * EnemyLureValue / 4096] then battle time
nop

It appears to divide by 2^12 (4096) and not 256.

Does someone care to tell me where I have gone wrong here?

EDIT: I think I see. EnemyLureValue is considered a fraction in Terrence's guide. Therefore the 4096 is divided by 16 to become 256?

11
Wouldn't the playback have to happen on the same type of modified emulator? I thought the recorded commands were stored by frame. I'm not much of an authority on emulators either way.

No one believes that I had a hand in the existence of TASes anyway.  :cry:
Yup. Playback requires that specific emulator build.

12
Long version showing graphical glitches:
http://www.youtube.com/watch?v=RxwF9paxKbE

13
Script much?

Did you use some sort of turbo function? Because there's no way a human could do that :P
Yup, turbo.
My personal result doing it manually:
Human Pause Glitch = 52.420 seconds (and I'm slow!)

http://antdgar.com/final-fantasy-vii/ff7-pause-glitch-slow-down-timer/

14
It's probably impossible in a frame-advancing emulator. It would require millisecond timing to do such a thing even in real-time. Even so, each 'frame' isn't considered fully processed until all the background processing is finished too.
A snes emulator was modified to allow "mid-frame resets". Essentially it allowed the author of the glitched chrono trigger run to do what I'm trying to do in ffvii.

But it seems there is almost no chance of this being implemented in the current psx tas emulator.

Oh well!  :-X

15
I see!

Another question:
Currently the save mechanism saves the FieldID (2bytes) in 1 frame.

Are there any thoughts on how to get this to save in 2 frames? (1 byte in one frame, the other byte in the next frame)

If it can be done in 2 frames, instead of 1, I will be able to skip most of the game by manipulating the FieldID via a corrupt save.

16
I want to corrupt a save file and then be able to load it (PSX version).

I have successfully corrupted a save file. However, I cannot load it because it says 'file ruined'.

I have read that it is possible, by changing the 'window colour' values, to fix the checksum and load a corrupted save file.
I've also found that the window colour can change when attempting to load a corrupted save file....

Does anyone here know how to do this? Or how I can find out which 'window colour' settings to use to fix the file?

Thanks! :D

17
Pause glitch: 28.726 seconds
Normal: 1 minute 11.265 seconds

http://www.youtube.com/watch?v=PJn0RPhRjLM

(in-game time is accurate, I'm simply reading it from RAM and displaying it on screen)

18


https://www.youtube.com/watch?v=axoAiLMvTlE

Detailed information:
http://antdgar.com/final-fantasy-vii/the-emerald-glitch-final-fantasy-vii/


Quick information:

1. Change battle config to 'wait'. (Optional; however this makes it much easier to perform)
2. Find Emerald Weapon on Disc 2 and enter the battle. (Disc 3 almost always crashes, in my experience)

3. Inflict enough damage so that Emerald Weapon is left with a very low amount of HP.
4. Force an in-battle 'wait' by placing the cursor on a character, or by entering a menu.
5. Wait until the countdown timer reaches 10 seconds.
6. Deliver the killing blow to Emerald Weapon before the timer reaches 0. Ideally Emerald Weapon should turn red on the 8 second mark.
7. Start a new game or load a game from a memory card.

Killing Emerald too soon or too late will not reproduce the glitch properly.

Effects: High Stats / Weird limit breaks / Instant win all battles/bosses

19
Brutalal released his glitch publicly:
http://www.youtube.com/watch?feature=player_detailpage&v=_9gKdr37gsI

Read the video for more information.

Basically:
The Menu Glitch can be used to manipulate which field you want to go to next.

How-to:
Exit a field and get a battle on the same frame. Menu glitch the battle (you don't enter the battle).
The battle ID is read as the field ID and you go to that field.

I'm about half-way through the TAS.
At the current rate, when this is used with the 'data error' glitch, I should be able to complete the game in around 3 hours 30 minutes.

20
It's not so much that the error 'makes materia limit breaks', as that it alters the attack IDs for the character's limits. Does this effect all characters? It sounds like data in the kernel is being corrupted somehow.

I'm not sure if this could be to do with the tools you're using for your TAS. If you're using an emulator, there might be oddities to the way it handles savestates. Be wary - they could invalidate your speedrun.

No not all characters are affected. Just Cloud, Tifa and Red so far. I don't think the emulator is causing the glitch, as I get the same results using different emulators. I would guess the same glitch is possible on console.

It's really funny that the Square coding team forgot to test this possibility... the glitch is so easy to do that one wonders if they bothered to test anything...

Quote
It sounds like data in the kernel is being corrupted somehow.
Also, if Barret has 53 magic stat before the glitch, he will have 53 magic stat after selecting 'new game'.
I just need to find a way to 'fix' the limit breaks so I can actually fight battles...

21
Ok great. Nice to know it is in the code then :D
Thanks

22
Is there anything in the code that shows it loops after 65536 frames? Because that is what it does in practice.

In my results I keep seeing the same loop of item drops after 65536 frames. And none of those results have a 3*item drop. This means, in this particular instance, it is not possible to get 3*item drop.

Here is the savestate: http://www.multiupload.com/UDRDKFIBAC
Here is the emulator which can load it: http://code.google.com/p/pcsxrr/
Load it by moving to sstates directory and pressing F1 in the emulaor.

If 3*drop from 3*enemy is possible, then there must be another factor in order to account for my results?

23
Error 38 is a little mysterious. I've seen a couple of other people report it, but as part of mods that change character AI. What's the 'game breaking glitch' you found? Can you tell us how to replicate it, and the full effects?

Did you edit your limits or initial data in some way?

I don't think this is caused by your limit breaks, rather that both your bugs with limits and in battles have another, separate root cause.

As for what the codes mean, I don't know. I did document some of these errors here, but haven't discovered much more since.

Hmm. I didn't edit anything. The glitch causes this. I will reveal the glitch once I've finished my TAS speed run that uses it!

Glitch effects:
Improved stats
Materia as Limit breaks (can't be used in battle)
Flea battles by using L1+R1+Select
Quick learning of level 1.2 and level 3 limit breaks after one battle
Random weirdness: Jessie getting stuck on the door that she opens

The glitch is simple to replicate, but sometimes crashes the emulator at a certain point. Once beyond this point it will not crash (at least so far).

24
I found a game breaking glitch earlier; changes initial stats and other stuff. It leads to code 38 in battles. I would like to know what code 38 is. The good thing about code 38 is it allows me to press L1+R1+Select to 'win'/escape any battle, including bosses.

I have a feeling it is to do with limit breaks, but uncertain if code 38 can give you any clue.

Does anyone have an idea what it means?



The code only appears when a glitched-limit-break-character has a battle. So I'm guessing it is due to that.

Also, does anyone have an idea why the glitch only seems to produce 'comet' or 'demi3' as cloud's limit break. It also changes stats.
Are those addresses near each other? What else are they near to? etc.

25
I have tried out the 3 Sneaky Steps battle and easily won 3 M-Tentacles after having adjusted the drop rate to 63.
Is this the same in the PSX version?

Changing the drop rate manually may not show if it is possible in a real game.
Anyone have the memory address for 'drop rate' or a way that i can easily find it?

Also, can someone explain why I have not seen 3*item drops after 400,000 (and counting) consecutive attempts? Possibly too low level to win all items?

Pages: [1] 2