FF7 In-Town Graphic Mod Project

Lazy Bastard, LiquidManZero
Lazy Bastard Section...

This project is something I couldn't help but mess with a bit once I'd thought of a few things while pondering world map sprites in comparison with what I already knew about in-town sprites. Anyway, just bear with me...these are notes, and weren't really intended for anyone but myself...I've just become so lazy these days that it's easier to post my original notes, with some comments before and after, heh. Here:

Universal difference between sprites - 84
(the difference in memory between parallel data of sprites)

Number of sprites in room - 8009AC1C 00??

Sprite 1

(never mapped due to laziness...just use the universal difference if you want these addresses)

Sprite 2



80074FB8 ????
80074FBA ????


80074FBC ????
80074FBE ????
80074FC0 ????
80074FC2 ????

Time before next blink (?) - 80074FB4 ??00

Rotation - 80074FE4 00??

More Coordinates (?)


80074FEC ????


80074FF2 ????

Another (Y)

80074FF8 ????

Visibility Mod - 80075008 - 000?

0 = Yes
1 = No

Sprite 3



8007503C ????
8007503E ????


80075040 ????
80075042 ????
80075044 ????
80075046 ????

Time before next blink (?) - 80075038 ??00

Rotation - 80075068 00??

More Coordinates (?)


80075070 ????


80075076 ????

Another (Y)

8007507C ????

Sprite 4

(same as 1)

And so forth...

In-Town Sprite Numbers (seem to be consistent; solved with sprite control mod)

0 - Cloud
1 - Tifa
2 - Barret
3 - Red XIII
4 - Blah
5 - Cait Sith
6 - Blah
7 - Cid

"Blah" digits (both of them, and any others discovered) are always either invisible sprites, the character right after them, or some miscellaneous character like an average townsperson. This list, therefore, will not always have the correct digits, but will usually have the correct order of characters within your party. Use it as a possible reference, not as a guide.

What I'm attempting to modify is what graphic is called into memory, per sprite slot, per room. After a little thought, I'm not even sure if this is possible, as a GSPro only accesses the RAM, and unused data may not be called in all places. Assuming it isn't possible, I'll try a different approach to an in-town graphic mod, as I have a few other theories I came to before this most recent idea came to mind.

My original doubt in the possibility of modifying what was called from the memory upon entering a room was quelled when I pondered the room mod hacked by Czar a million and a half years ago (surely you've used the debug room code; this is the room mod with digits - found by RPGod - for the debug room). Before you actually enter a room, but after you've done whatever it takes to initiate the room change (walking through a door, walking into a town from the world map, etc), the memory calls up whatever room it needs to. If you walk into the barn at the Chocobo Farm, it obviously calls up the data for the barn. This can be overridden by simply using the room mod and giving it digits for, say, the first room of Tifa's 7th Heaven (the bar); walking into the barn with this code on would bring you to Tifa's bar. If what room the game is told to call - upon the next room change (or when a save is loaded or a new game is started) - can be modified, it's logical to assume that characters - graphics, more specifically - to be called up could also be modified.

Either each individual slot can be modified upon a call up, or they work in sets. In other words, perhaps I'll eventually be able to put Cloud in a wheelchair in the same room as Cloud with the Buster Sword and the regular Cloud; and perhaps the memory uses graphic sets instead of individual graphics, so that I'll only be able to modify which set of graphics is called up, which would allow for me to use Cloud in the wheelchair, Cloud with the Buster Sword, and the regular Cloud, but only individually, as there is never a point in the game where, in any room, all three of these Clouds is present at the same time. It should be noted that I would also get all of the other graphics from whatever town/event the graphic set value represents.

For example, let's say there was a room in the game, somewhere, that at some point had a Cloud with the Buster Sword, a Sephiroth, a Tifa, a Red XIII, and a female shopkeeper (for variety, heh), and no other graphics. If indeed the memory uses graphic sets, and I chose the value for the graphic set of this room/event (the graphic set for the event that caused the presence of all of those characters, in this room), I would get all of those characters. Any room I went into would have those characters, and no others. So if ol' Seph was graphic 2, then graphic 2 in any room would always be Sephiroth. This could cause problems. If there was a room in the game where there were quite a few sprites (with visible graphics; not empty sprite slots), and each of them needed to be talked to, you'd have to walk around until you found the invisible ones (the ones with no graphics), assuming the memory still acknowledges sprites with no graphics as still having actions and responses, and doesn't instead somehow bundle sprite responses with sprite graphics (as it does on the world map). The memory won't allow for more than one sprite to have the same graphic, so even if I also found individual graphic mods within the available graphics in a room (they would only be able to change to graphics from the graphic set I caused to be called up), I still wouldn't be able to fill the other, empty sprite slots with, say, Sephiroths, because the memory would contradict itself in noting that graphic "blah1" was in sprite slot 1, and graphic "blah1" was in sprite slot 2. At least, that was my original assumption. After all, that's the way the world map works.

I began to think that maybe the memory would allow more than one of the same graphic when I thought of those rooms of the debug room where there are more than one of the same graphic. I can't completely conclude that the same graphic value could be used twice, however, because perhaps in one of those rooms graphic "blah1" is Yuffie's graphic, and so is graphic "blah2", and therefore it's not breaking any of its own laws while still prohibiting the use of the same graphic value twice in the same room. I'm too lazy to ponder all that, so I'll deal with that after I've finished actually hacking a graphic set mod.

But, then again, perhaps the simple answer is the correct one, and each individual graphic to be called up can be modified. This would explain the way you can go into (as far as I can see, using the USO code at inappropriate times) almost any event with any combination of characters, and they still jump out at their designated times, and do what they're supposed to do (or, in the case of characters that aren't supposed to be used in an event, take over the actions of a character that is). Are we to assume that the memory has allocated values for every possible combination of graphics you could ever use? It's possible, but I don't think it's very likely. Therefore, I'll first assume that each individual graphic to be called up can be modified, and if I'm wrong, I'll start over, and assume that the memory uses graphic sets. Anyway, on with it...

It is most likely that, even if they do correspond to the numbers above (way above, thanks to my obese compendium of notes, heh), the values of graphics will not simply be things like "0002" or "0003". Graphic values on the world map were things like "CE02" or "8203"; in-town graphic values are probably similar.

Since I'm trying to modify what's "called up" upon entering a room, I must implement whatever I need to implement before I actually enter the room.

The simplest way of going about all this is to change what character is in a particular slot in my party, before entering a room with an event, or at least a room in which both of my other characters come out. This is important because I'm fairly sure the memory won't naturally call up graphics in rooms/events for characters that aren't going to appear. Simply switching my slot 2 and slot 3 would not work, as the memory doesn't care what order my party is in; it's only concerned with who's in it. So I must either use PHS or the USO code (or anything else that would achieve the same effect) and change the character in one particular slot (and then run searches accordingly).

Another thing to note is the way sprites and graphics work on the world map (and may work in towns). I'm too lazy to go and get actual numbers from somewhere in my notes, so I'll give you an example instead. If sprite "blah1" contains the graphic of Ultimate Weapon, I'll simply call it Ultimate Weapon's sprite, during this example, to simplify things. So, let's say, for example, that the sprite values were arranged as so (now remember I'm inventing all of this, so mathematically it probably won't be sound):

80091234 A634 - Ultimate Weapon
80091234 A754 - Airship
80091234 A874 - Cloud

This, is, basically, how these three are actually arranged. From Cloud, the sprite values go down to the airship, and then to Ultimate, and so on. Now let's say the graphic values (which are at a different address for each sprite slot) were arranged as so:

80092000 4502 - Cloud
80092048 7403 - Airship
80092090 5404 - Ultimate Weapon

Remember that the first two digits of each value here are graphic behavior. The actual graphic mod is just the last two digits. Looking at the above (fictional) sprite control mod and graphic mods, you'll notice something interesting (and if you don't, I'll tell you anyway, heh). While, as I've said, the values of the sprite control mod go down progressively from Cloud, to the airship, to Ultimate Weapon, the graphic values go up from Cloud progressively, in exactly the opposite manner (graphic mod addresses, by the way, are in the same order as values of the sprite control mod) . This may be the way sprites/graphics work in towns; instead of using the list of digits way above, perhaps the inverse should be used as a reference point. I won't know this for sure until I've hacked the code, heh. I'll first assume that things work in regular order, and if that seems to fail, I'll of course try things assuming inverse order. Either way it's something to keep in mind.

Everything I've done so far has just been to build a sort of rough base from which to start. I'll actually do some hacking using these theories probably tomorrow. I am finally out of school for a while. If anyone wants to jump in, be my guest; it'd be great to have another hacker to compare notes with, or even someone doing testing. Ahh, well...

I managed to find the addresses that modify what graphic each of your characters (Slot 1, 2, and 3 in the menu) is represented by in town environments. This, unfortunately, only uses the list of characters that the normal character mod uses. As a result, you can have Cloud, Tifa, and Cid in your party, and run around as Red XIII, with Yuffie and Cait Sith popping out during events, but that's about the extent of its abilities. Here:

In-Town Character Graphic Mods

3009D391 000? - 1st
3009D392 000? - 2nd
3009D393 000? - 3rd

0 - Cloud
1 - Barret
2 - Tifa
3 - Aeris
4 - Red XIII
5 - Yuffie
6 - Cait Sith
7 - Vincent
8 - Cid
9 - Young Cloud
A - Sephiroth
B - Invisible
20 - Invisible

I'm fairly sure everything after B is nothing, but if anyone wants to check 21 and above, they're welcome to it, heh.

A problem to note is the fact that only Cloud, Tifa, Cid, and Red XIII were ever meant to lead the party, so other character graphics, when used as the graphics of character 1, will not allow room transitions (in other words, you can't change rooms unless you have Cloud, Tifa, Cid, or Red XIII as your main character). At the moment I can't see how this would be fixed if someone went about to try, but I'm open to suggestions.

Another issue is the fact that graphics for most characters haven't been introduced at the beginning of the game, so generally until you've met a character, you can't use it as a graphic, which really sucks. Ahh, well...

Any input?

Someone else brought this address to my attention, although I don't remember who exactly. It was probably Liquid:

3009ABF5 000?

1 - The game is loading a map
2 - The game is not loading a map

I'm not quite sure how that'll help me, but it may be useful to know at some point. Anyway, I began using this simple joker system to do some testing:

D009AC5C 0001
3009D391 0002
D009AC5C 0002
3009D391 0000
D009AC5C 0004
3009D391 0008

Press L2 (Tifa), L1 (Cid), or R2 (Cloud), and your character graphic changes. Change rooms for it to take effect. What I noticed when running searches was that the value of 8009AC1E, my old in-town sprite control mod, changed as my character's graphic changed. What I assume this means is that my graphic isn't changing at all...instead my sprite is changing, and the graphic for whatever sprite I change to is...turned on, so to speak.

OK, I've noticed that the visibility mod is being triggered. If I control a sprite, the visibility mod for that sprite is set to a value of 1; if not, a value of 0.

I thought for a moment that since graphic values are probably set at 0 as default, and to a higher number when they're a visible graphic, the best approach would be to keep in mind, when I'm searching for the graphic mod of one character, that even though I'm effectively changing my graphic with the "testing code" above, I'm really changing the value of a different graphic mod each time I change graphics. So when I come in to a room as Tifa, and I take control of her sprite automatically, I change the value of her graphic mod to that of the graphic of Tifa, but I'm not at all affecting the values of the other graphic mods (except perhaps the value of the graphic mod of whoever I was the last time I was in the room, as it's now not a visible graphic, heh).

But now that I think about it, I don't think that's correct. For one thing, the graphic value 0 is usually assigned to Cloud, heh. But besides that, assuming then that the value would be FFFF, it still seems more likely that they work the same way as the character graphic mods do...they probably share an address (in other words, they're half-word values and not full word). This makes hacking for them a bit more difficult, as I don't know what address contains what two graphic mods, hence I can't go about things the way I mentioned in the above paragraph.

Hmm....I've noticed that the same graphic value (in the case of those character graphic mods) can't be used twice at the same time, in the same room. So in rooms like some of the debug room...sub-rooms...there must be more than one value that'll yield the same graphic, so as to allow three of the same Yuffie in the same room. This clears up a minor question I had before. Just a note.

While trying to think of ways to prove a few things, I noticed that when my character graphic mod value is that of Tifa, the value of the sprite control mod becomes 0001 (it's 0000 when my character graphic is set to Cloud); in other words, she's the 2nd sprite, but more important than mapping out what sprite slot she's in is the fact that this happens at all, heh.

With that knowledge (I could now connect Tifa's visibility to that of the 2nd sprite), I went back to my notes and grabbed the 2nd sprite visibility mod, input it, and set its value to 0001. As I expected, when I entered the room (the Forgotten City room in which you take a nap before...that big event happens...don't want to spoil it, in case someone still hasn't played to that point, heh) Tifa was standing at the point in which she (or whatever character is in the 2nd slot), along with the 3rd character, usually comes out of your main character and talks, and she was visible (otherwise I wouldn't have noticed, heheh).

I then tried another system:

80075008 0001 - Visibility On, 2nd sprite

D009AC5C 0001

3009D392 0005 - Press L2 to change 2nd character graphic to that of Yuffie

D009AC5C 0002

3009D392 0007 - Press R2 to change 2nd character graphic to that of Vincent

D009AC5C 0004

3009D392 0006 - Press L1 to change 2nd character graphic to that of Cait Sith

I then went into the room, noted that Tifa was there, and left the room. Before I re-entered, I used the L2 joker and changed the 2nd character graphic to Yuffie. I then entered. As I expected, no one was there.

What I'm assuming here is that when the 2nd character graphic (3009D392 000?) was changed, the value of Tifa's graphic (the undiscovered address of the graphic of sprite 2) was changed to no graphic (or an invisible one). Even though I had visibility locked On, there was nothing to see. Then visibility for sprite slot 5 was turned on, and the graphic for that sprite was changed to Yuffie's. I know part of this for sure: visibility was turned on for sprite 5 only when I entered a room as Yuffie; before that the value was 0.

Just to be sure, to test whether or not the graphic for sprite 5 was changed to that of Yuffie, I mapped out some coordinates in the same Forgotten City room. I then reset, and input a few codes. One was the 5th sprite visibility mod, set to On, and the others were 5th sprite coordinate mods, set to the values I'd mapped out and tested. If sprite 5 was always preset with Yuffie's graphic, with this code on Yuffie would be standing in front of me as I entered the room, perfectly visible. If this was the case, it would mean that no sprite graphic mods are being affected at all, making these character graphic mods useless in this project. As I hoped, she wasn't. Therefore, the 5th sprite's graphic became Yuffie only when I entered the room as Yuffie. This means the 5th sprite graphic mod's value is changing. When I'm Yuffie, it's probably something like 000X; when I'm not, something like 00FF (as 0000 would probably yield Cloud's graphic, although I can't be sure).

Something else, which is really just a reiteration of what's already been said, should be noted.

From the above testing, it can be assumed that sprite graphics for all three characters in your party are loaded upon entering the room. Graphics for characters that aren't in your party are not loaded. Something else to note would be the fact that I can't be sure at the moment whether or not those graphics (those that are loaded) are loaded only because the room I'm using for testing is the site of an event (that I have left untriggered, to ensure that graphics would definitely be loaded). Perhaps if I was in a room where the party never "comes out" of Cloud, those graphics wouldn't be loaded. I suppose I'll solve this later.

I was forced to discover something I'm surprised I never noticed. If Tifa uses sprite slot 2, and Barret is before Tifa in terms of sprites...where the hell is Cloud? Well, Cloud is right before Barret. Since I've already been calling all these slots by the names I've given them, I'll stick to that, and call this newly-discovered slot "Sprite 0" (which is, I suppose, an appropriate name, as Cloud is usually represented by a 0 anyway). So here:

Sprite 0



80074EB0 ????
80074EB2 ????


80074EB4 ????
80074EB6 ????
80074EB8 ????
80074EBA ????

Visibility Mod - 80074F00 ????

0 - No
1 - Yes

I obviously didn't go for the extensive collection of addresses here, as I didn't for a few other sprites, but the framework is all that matters, as I can solve for anything I need with the universal difference between sprites (near the top of this topic).

Also, I noted an interesting set of addresses, one per sprite data area. The values at these addresses seem to correspond to their sprites, and hence, their supposed graphics.

Sprite 0
80074F0A 0000

Sprite 1
80074F8E 0001

Sprite 2
80075012 0002

Sprite 3
80075096 0003

Sprite 4
8007511A 0004

Sprite 5
8007519E 0005

Sprite 6
80075222 0006

Sprite 7
800752A6 0007

Sprite 8
8007532A 0008

Sprite 9
800753AE 0009

The sequence ends at Sprite 9 in the room I'm working in, as at one more offset of 84 (address 80075432), the value is 0000. I checked 8009AC1C (the address that controls the number of sprites in the current room), and the value was 000A. Since there's now a Sprite 0 to take into account, the fact that there are ten addresses with correctly corresponding sprite values and the fact that there are ten sprites in the room match up.

Now there is the slight matter of figuring out what exactly these addresses affect. If they have anything to do with graphics, then my assumption that graphics aren't normally loaded (and sprites aren't assigned a graphic value) unless they're needed is wrong. But I don't think they're involved with graphics at all. They're certainly not graphic mods, as I've tested them quite conclusively. I can even lock two of them at the same value, and there's no conflict at all; I can't even cause a glitch with these, heh. If they have nothing to do with graphics, it would then be assumed they directly correspond to their sprite numbers. But the question then arises, "For what purpose?". And I do not have the answer.

Is there any chance anyone can offer any...mental assistance? I am, after all, a lazy bastard. It would definitely help to have another person even toying with this a bit. In any case, I'll continue the project as I've been doing. 'Night.

Looking at the RAM again, I think now that sprite graphics are loaded upon entering a room, and bound to a respective sprite. Some have visibility turned on, while the others have visibility turned off.


LiquidManZero Section

Some of this is a repeat of what Lazy already found, but some isn't:

Universal Difference Between Sprites: 84

Start of Sprite 0

Offsets in sprites:

00 - Start, nothing?

04 - ? (Turn to 01, changes to 02)

08 - Pointer to motion data/graphics alteration(!?) Default is 0. Varies by room. [32 bits]

0D - Time to next blink (in # of frames?)

10 - X Coordinates [32 bits]
14 - Y Coordinates [32 bits]
18 - Z Coordinates [32 bits]

3A - Echo of rotation angle (actual rotaion angle can be changed without this one changing at all, until you move)
3C - Actual rotation angle (0000 - 'south', 0040 - 'east', 0080 - 'north', 00C0 - 'west')

54 - Sprite gfx centering, ofset from actual center location (X)

5A - ... Y

60 - ... Z

60 - Visibility (0001 - Visible, Else - Invisible, > 00FF - Crash)
62 - Current Motion (0 - Standing still, 1 - Walking, 2 - Running)

70 - ?
72 - ?

75 - ?
76 - ?

Debug Room -> Sprite 0's default data
~~ = Constantly changing
Address+: 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F
80074EA0: 00 00 00 00 00 00 00 00 00 00 00 00 00 ~~ 00 00
80074EB0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
80074EC0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
80074ED0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
80074EE0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
80074EF0: 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 00
80074F00: 01 00 00 00 10 00 00 00 00 00 00 00 00 00 00 00
80074F10: 22 00 50 00 00 04 01 00 00 00 00 00 00 00 00 00
80074F20: 00 00 00 00 -- -- -- -- -- -- -- -- -- -- -- --

Sprite 4's default data
80075020: -- -- -- -- -- -- -- -- -- -- -- -- 00 00 00 00
80075030: 00 00 00 00 00 00 00 00 00 ~~ 00 00 00 60 FB FF
80075040: 00 E0 F7 FF 00 00 00 00 00 00 00 00 00 00 00 00
80075050: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
80075060: 00 00 00 00 00 00 00 00 60 00 00 00 00 00 00 00
80075070: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
80075080: 00 00 00 00 00 00 00 04 00 00 00 00 01 00 00 00
80075090: 10 00 10 00 01 00 03 00 00 00 00 00 01 00 50 00
800750A0: 00 04 64 00 00 00 00 00 00 00 00 00 00 00 00 00

If you copy Sprite 4's data onto where Sprite 1 is, you get a Tifa that is otherwise identical to Yuffie... Menu and everything.
And, if you move Yuffie, you have two NPCs in the same room with the exact same menu that you can use. I'd say, this proves that sprite responses are not sprite specific, and are not unique like the sprites themselves.

Room # 02D5 (Cloud's Head) -> Sprite 0 - Giant Semi-Transparent Cloud
80074EA0: 00 00 00 00 02 00 00 00 E6 53 11 80 00 ~~ 00 00
80074EB0: 00 90 E3 FF 00 B0 C4 FD 00 E0 04 00 00 00 00 00
80074EC0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
80074ED0: 00 00 00 00 00 00 00 00 00 00 00 00 18 00 00 00
80074EE0: 40 00 18 00 94 00 00 00 94 00 AB F3 00 00 AB F3
80074EF0: 80 08 00 00 80 08 00 00 00 00 00 01 00 01 00 00
80074F00: 01 00 04 00 02 00 02 00 03 00 00 00 00 00 00 00
80074F10: 04 00 40 01 00 10 56 00 00 00 00 00 00 00 00 00
80074F20: 00 00 00 00 -- -- -- -- -- -- -- -- -- -- -- --

I'd include the data from 801153E6, except I don't know where it ends. But, I know from modifying it, that this is at very least where the info about how a sprite moves is stored, if this is used.

This text was brought to you by GSHI.org, unless someone else gave it to you, in which case it was only written by someone at GSHI.org. Heheh.