12-27-2022, 10:30 AM
PSX ripping can be tough at times but there's a quick trick not many people know about when it comes to finding palette data.
I was inspired to elaborate when I saw someone on Discord having trouble with Primal Rage (PSX). They could find the graphics but not the palettes. The case example was this dino graphic:
^ the graphics are in a file, but palette data nowhere to be found.
anyway, the gist of it is to first open NO$PSX and play the game to the part where you can _see_ the graphics. This one is from the character pre-battle intro scene, so AS SOON AS I saw the graphic, I paused emulation by clicking on the debug window.
Now the emulation is paused and the graphic is visible. I can't stress enough that you have to be quick, because if I had waited a bit longer, the game had entered a "Loading" state where graphics are visible but the VRAM doesn't actually store any data, it's all cached. It helps if you've got a keyboard with a numpad because hitting / is frame advance. But anyway, at this point, open the VRAM viewer by pushing F5. On the right, you see a list of primitives. Click on one and cycle through them with the up/down arrow keys until the graphic in question is highlighted.
In this case, the primitive type is QuadTexRaw, it's highlighted with the red box in the framebuffer and the small window on the bottom right shows exactly what I'm looking at. So, what now?
Look at the text in the bottom right window. It says:
We are interested in the third row after the ---. It says 7AC00000. The first half is what we're interested in, so 7AC0 is our key here.
Multiply 7AC0 (which, in decimal is 31424) by 32 and you should get F5800 (which is 1005568 in decimal)
There's your answer; the palette data for that highlighted dinosaur graphic is stored at address 0xF5800 in the VRAM.
Now, you want to visually verify this and get the VRAM in on itself as a file, so you should (while the emulation is still in its halted state) make a save state by hitting File -> Write Snapshot and saving it as whatever. I saved mine as "palette.sna".
NOTICE: NO$PSX compresses its savestates by default, so change the snapshot format to "Raw" from the Emulation settings' Files tab.
Now that all's said and done, you should have a save state file that's 4.4MB in size and contains the "scene" so to speak. Open the file in GGD and set your canvas to N x 512px (where N is 4096px if your graphics are 4bpp or 2048px if your graphics are 8bpp. Our dino is 8bpp so 2048x512 it is. (Hold Shift and hit the arrow keys to change your ScreenSize, hit the arrow keys without holding anything to change your ImageSize)
Okay, now you should navigate to the address 2658416 (or 0x289070 in hex) as that's where Raw NO$PSX snapshots store the VRAM. Once you're there, you should see the VRAM in its whole glory.
looks alright but the palette is wrong. Now, where was our palette again? It was at 0xF5800 (1005568) in VRAM, so it follows that the beginning of the VRAM plus the palette address must equal an address where the palette data is. So; 0x289070 + 0xF5800 = 0x37E870. Or if you like to count in decimal, 2658416 + 1005568 = 3663984.
Using the Palette View, navigating to 3663984 will get you the right palette.
just gotta scroll a bit right to see it lol
At this point, if you're just doing a one-off, you should be good to go, but if you really want to get to the bottom of this, you should actually look for the data itself, not just view/save it in GGD and call it a day. I usually open the snapshot file in a hex editor at this point and jump to the address where the palette data is. Here's a screenshot of my hex editor with the address 3663984 open and the 512 bytes (a full 256-color palette) highlighted:
This data appears like this in our snapshot, and it follows that (if it is uncompressed in the ISO) it must appear exactly like so somewhere in the ISO's files as well. How many files are there in the ISO?
ungh goddamn, there's a lot of files and folders inside. If there were just a few, I would've just opened them in a hex editor and searched the data from it one by one. But this is too much, so I'm gonna have to use a script.
NOTICE: I'm a macfriend and I don't know how to do this part in Windows or Linux, but maybe ask someone smarter in those things about it and let me know, I'll update the post. The thing I'm doing here is an operation of "Search for these bytes in every single file in every single subfolder in this particular folder"
and whaddya know, the output was
The bytes were found in seven files, all at the same address, and judging by the filenames, they're just more or less the same stuff, just in different languages. So hey, let's get back to our original problem file, CHALL01.bin:
and open LUMPS1/INIT.BIN as our palette:
and navigate to address 4692 (0x1254) in our palette view:
and there you have it
recap: NO$PSX's VRAM viewer's primitive info window's third row's first half multiplied by 32 gives you the explicit addressin VRAM where the palette of a given primitive is - get the VRAM somehow and extract the palette from there straight up or search for said bytes in the ISO's filesystem and get it straight from there.
FAQ:
question: i searched for the bytes in all of the files but got 0 hits
answer: the palette is compressed unfortunately. either use the sample you got in your VRAM or try to figure out the compression
I was inspired to elaborate when I saw someone on Discord having trouble with Primal Rage (PSX). They could find the graphics but not the palettes. The case example was this dino graphic:
^ the graphics are in a file, but palette data nowhere to be found.
anyway, the gist of it is to first open NO$PSX and play the game to the part where you can _see_ the graphics. This one is from the character pre-battle intro scene, so AS SOON AS I saw the graphic, I paused emulation by clicking on the debug window.
Now the emulation is paused and the graphic is visible. I can't stress enough that you have to be quick, because if I had waited a bit longer, the game had entered a "Loading" state where graphics are visible but the VRAM doesn't actually store any data, it's all cached. It helps if you've got a keyboard with a numpad because hitting / is frame advance. But anyway, at this point, open the VRAM viewer by pushing F5. On the right, you see a list of primitives. Click on one and cycle through them with the up/down arrow keys until the graphic in question is highlighted.
In this case, the primitive type is QuadTexRaw, it's highlighted with the red box in the framebuffer and the small window on the bottom right shows exactly what I'm looking at. So, what now?
Look at the text in the bottom right window. It says:
Code:
CPU.PC: 80063CF4
DMA.Start: 000A8CC4
DMA.Link: 000A8D68
---
2DFFFFFF
00380093
7AC00000
00380014
008D007F
00D80093
0000A000
00D80014
0000A07F
We are interested in the third row after the ---. It says 7AC00000. The first half is what we're interested in, so 7AC0 is our key here.
Multiply 7AC0 (which, in decimal is 31424) by 32 and you should get F5800 (which is 1005568 in decimal)
There's your answer; the palette data for that highlighted dinosaur graphic is stored at address 0xF5800 in the VRAM.
Now, you want to visually verify this and get the VRAM in on itself as a file, so you should (while the emulation is still in its halted state) make a save state by hitting File -> Write Snapshot and saving it as whatever. I saved mine as "palette.sna".
NOTICE: NO$PSX compresses its savestates by default, so change the snapshot format to "Raw" from the Emulation settings' Files tab.
Now that all's said and done, you should have a save state file that's 4.4MB in size and contains the "scene" so to speak. Open the file in GGD and set your canvas to N x 512px (where N is 4096px if your graphics are 4bpp or 2048px if your graphics are 8bpp. Our dino is 8bpp so 2048x512 it is. (Hold Shift and hit the arrow keys to change your ScreenSize, hit the arrow keys without holding anything to change your ImageSize)
Okay, now you should navigate to the address 2658416 (or 0x289070 in hex) as that's where Raw NO$PSX snapshots store the VRAM. Once you're there, you should see the VRAM in its whole glory.
looks alright but the palette is wrong. Now, where was our palette again? It was at 0xF5800 (1005568) in VRAM, so it follows that the beginning of the VRAM plus the palette address must equal an address where the palette data is. So; 0x289070 + 0xF5800 = 0x37E870. Or if you like to count in decimal, 2658416 + 1005568 = 3663984.
Using the Palette View, navigating to 3663984 will get you the right palette.
just gotta scroll a bit right to see it lol
At this point, if you're just doing a one-off, you should be good to go, but if you really want to get to the bottom of this, you should actually look for the data itself, not just view/save it in GGD and call it a day. I usually open the snapshot file in a hex editor at this point and jump to the address where the palette data is. Here's a screenshot of my hex editor with the address 3663984 open and the 512 bytes (a full 256-color palette) highlighted:
This data appears like this in our snapshot, and it follows that (if it is uncompressed in the ISO) it must appear exactly like so somewhere in the ISO's files as well. How many files are there in the ISO?
ungh goddamn, there's a lot of files and folders inside. If there were just a few, I would've just opened them in a hex editor and searched the data from it one by one. But this is too much, so I'm gonna have to use a script.
NOTICE: I'm a macfriend and I don't know how to do this part in Windows or Linux, but maybe ask someone smarter in those things about it and let me know, I'll update the post. The thing I'm doing here is an operation of "Search for these bytes in every single file in every single subfolder in this particular folder"
Code:
cd /Users/vervalkon/Primal\ Rage/Primal\ Rage\ \(Track\ 01\)
find . -name '*.*' | xargs binwalk -R "\x00\x00\x74\xCA\x32\x84\xF0\xB9\xAE\xB1\x6E\xA9\x2D\xCA\xCC"
and whaddya know, the output was
Code:
/LUMPS1/INIT.BIN
at address 4692 (0x1254)
/LUMPS1/INIT_JAP.BIN
at address 4692 (0x1254)
/LUMPS5/INIT_ITA.BIN
at address 4692 (0x1254)
/LUMPS5/INIT_GER.BIN
at address 4692 (0x1254)
/LUMPS5/INIT_FRE.BIN
at address 4692 (0x1254)
/LUMPS5/INIT_SPA.BIN
at address 4692 (0x1254)
/LUMPS5/INIT_POR.BIN
at address 4692 (0x1254)
The bytes were found in seven files, all at the same address, and judging by the filenames, they're just more or less the same stuff, just in different languages. So hey, let's get back to our original problem file, CHALL01.bin:
and open LUMPS1/INIT.BIN as our palette:
and navigate to address 4692 (0x1254) in our palette view:
and there you have it
recap: NO$PSX's VRAM viewer's primitive info window's third row's first half multiplied by 32 gives you the explicit addressin VRAM where the palette of a given primitive is - get the VRAM somehow and extract the palette from there straight up or search for said bytes in the ISO's filesystem and get it straight from there.
FAQ:
question: i searched for the bytes in all of the files but got 0 hits
answer: the palette is compressed unfortunately. either use the sample you got in your VRAM or try to figure out the compression