Hey people, I'm currently working on a translation hack for the PSX version of the horror game Clock Tower: The First Fear. For those that don't know, its a 2D point and click horror game that was first released for the SFC. I absolutely love the concept, and I wish more games were made in its style!

This is my first hack, thankfully it was relatively simple to pull off and the project is almost complete, with just a few minor things left to fix up.For those that don't know, the PSX version contains a few extra scenes that are not in the original.

The hack should be relatively complete in a couple of months, and I'm hoping it will generate at least a small renewal in interest for the series.

Interesting project. AFAIK, the only real barrier for the hacking is making the game print text without using the horrifying BIOS font (it's just a matter of loading a static font and patching the sprite rendering association).

Logged

I am the lord, you all know my name, now. I got it all: cash, money, and fame.

That's true, I haven't been able to get it to use a font other than one in the BIOS yet, but in the meantime I've rewritten the font rendering code to use the half-width font from the BIOS. So its able to get at least a few words on a line now.

I don't know much about memory management on the PS1, so how would I go about adding a call to load an extra file in memory when the game loads, without messing up pointers and things?

You'd probably want to check how the game gets access to data on disk (most games don't make straight references to file names, but would rather rely on indexing tables), as it more than likely has a generic routine to do so for all its data. Once you're set with that, you need to inject an extra call somewhere, load a font file from disk, upload it to VRAM and make so that the game doesn't ever need to overwrite it with glyphs coming from the BIOS font with the aid of psy-q function Krom2Addr. That done, you can alter text rendering so that the encoding doesn't require more gfx requests, then you should map sprites directly to what you have in VRAM (should simply require reworked logic for UV cordinates). If the engine isn't too strict, you can also add a VWF with very little effort.

The whole operation shouldn't be too difficult if you know how to identify PSY-Q libraries inside the exe (IDA and its flirt signatures can help). I did a similar hack with the japanese version of Symphony of the Night, which totally relies on the same trick, although it renders text in a way that requires a lot of extra work for a VWF. Still, you should be able to make it work even if the original engine doesn't allow so.

« Last Edit: August 23, 2013, 12:05:15 pm by Gemini »

Logged

I am the lord, you all know my name, now. I got it all: cash, money, and fame.

Ok, thanks. I've been a little reluctant all along to get into the whole PSY-Q thing with IDA (lazy haha), but it seems now that it would have been a huge advantage.

Would you say just using a regular monospaced font would be fine as long is looks ok? Like something based off Courier perhaps, because it seems like it would save me a load of work if I just make a new font that renders using the current system. Basically, I'd like to get something presentable out there as soon as possible, because its getting increasingly difficult to find time to work on the hack :\

Hey and really appreciate the help. Seems I've learned more from this project alone about general system architecture than I have at university haha.

The Chinese translation is bogus. It comes with a hacked BIOS containing the Chinese Hanzi and changes the dialog data to account for the new font. In other words, it's extremely illegal (because of the BIOS) and works only on some emulators. Definitively not useful as it doesn't contain any changes to the engine required for a real translation.

If the game renders text like I'm supposing, making it work with a VWF should be just a matter of replacing a static "x+=16" with a more dynamic "x+=width_table[char]", which only really takes a few bytes to hack and a few more to store the width table.

Logged

I am the lord, you all know my name, now. I got it all: cash, money, and fame.

If the game renders text like I'm supposing, making it work with a VWF should be just a matter of replacing a static "x+=16" with a more dynamic "x+=width_table[char]", which only really takes a few bytes to hack and a few more to store the width table.

Yeah, that's how it works. I changed that to +=8 for rendering the half-width font. Using the half-width one meant that I could free up some space in the function that fetches the font data and reformats it for rendering. So that's where I'm chucking all my extra calls and things at the moment, which is super convenient. Hope I don't run out of room haha.

Looks cool. The method used to change the font probably won't be too useful in this case but it'll be interesting to see how a couple of other things were done. I wonder how you would make a chinese hack without hacking the BIOS anyway, because there are so many characters.

There are really many strategies to make a huge font set fit. For example, some games upload to vram only what is required on screen, keeping the whole font in ram in the meanwhile. Let's say you need a set of 4000 glyphs for your Chinese game. You could make it use 12x12 1bpp glyphs, which take 18 bytes per character. With 72,000 bytes you can store in memory a set of 4,000 characters. Other games make the set always cached in vram. You could use some palette tricks to store 4 layers of graphics for each vram page. Again, with a 12x12 set in mind, you could have 21x21x4=1,764 glyphs per vram page that way. With the first page you could store the global set used everywhere, while with another page you could load at runtime a subset required for special characters, say for a specific map or section of the game.

Logged

I am the lord, you all know my name, now. I got it all: cash, money, and fame.

I found a way to load a custom font to ram without messing with the cd. The whole of the SLPS file gets written to ram at the start, and it has a gigantic chunk of free space in the middle. So what I'll do is chuck a font in there, in a place which corresponds to space in ram that is never overwritten by anything else, then I can just redirect the font fetching function to read from there. For the variable width-ness, I'll see if I can make a width table to go with the font, and change the spacing based on that.

I found a way to load a custom font to ram without messing with the cd. The whole of the SLPS file gets written to ram at the start, and it has a gigantic chunk of free space in the middle.

Be careful with that: what looks like free room could be just the BSS section of the exe, which is cleared as soon as the BIOS jumps to the stub function. Even if you write there a temp font to be sent to vram, it could be cleared way before you have a chance to upload it.

Quote

Gemini, do you know of any good beginner tuts for IDA and PsyQ?

As for IDA, I'd simply suggest you to use the internal guide. For PSY-Q, try downloading from somewhere (wink wink) the reference documentation. It's a huge PDF with most functions documented, what they do, what parameters you need to find, and quite a lot of helpful structures used at low level by all PlayStation games.

Logged

I am the lord, you all know my name, now. I got it all: cash, money, and fame.

Be careful with that: what looks like free room could be just the BSS section of the exe, which is cleared as soon as the BIOS jumps to the stub function.

Ok, well I did test it quite far into the game, and after doing a memory dump the data I'd written was still there. It looks like a lot of that space is left untouched for the whole game. I have yet to test a bunch of other conditions that might affect it, as well as different BIOS versions, but I think it should still work fine?

Question: how do you usually go about injecting extra calls, or adding functionality to a game? Because it seems to me that after a while you'd need to start finding free space in ram to upload the new functions to, or write at least the code required to upload the functions to ram in the free space of the SPLS file.

Also, is there a PsyQ function or whatever that loads a sector from the cdrom? The game doesn't seem to just have one function that uploads stuff from the cd. I've been doing all my hacks in assembly up till now, and I can't get stuff to load from the cd.What I tried is:write 0 to 1f801800write the MSF to 1f801802 as a sequence of byteswrite 2 to 1f801801write address to write to in ram to 1f8010b0write 00010200 to 1f8010b4 (number of blocks and block size)write 11000000 to 1f8010b8

but it apparently just re-uploads the previously loaded sector to the specified address in ram.

Ok, well I did test it quite far into the game, and after doing a memory dump the data I'd written was still there. It looks like a lot of that space is left untouched for the whole game. I have yet to test a bunch of other conditions that might affect it, as well as different BIOS versions, but I think it should still work fine?

Tests with different BIOS roms shouldn't be required. The stub alone takes care of the BSS segment, so if the data is still there after boot it's definitively not affected by the clearing loop.

Quote

Question: how do you usually go about injecting extra calls, or adding functionality to a game? Because it seems to me that after a while you'd need to start finding free space in ram to upload the new functions to, or write at least the code required to upload the functions to ram in the free space of the SPLS file.

I usually derive room from other routines I either need to rewrite (which drastically reduces them in size) or remove entirely because they are never used by the code, even if they were linked with the rest of the EXE.

Quote

Also, is there a PsyQ function or whatever that loads a sector from the cdrom? The game doesn't seem to just have one function that uploads stuff from the cd.

Games use either CdRead or DsRead to start buffering data, depending on which libraries they were developed with. IIRC the extended cd libraries were introduced only in 1998, which means you're likely to find only LIBCD in the code.

Quote

but it apparently just re-uploads the previously loaded sector to the specified address in ram.

Sounds like it's CdGetSector(), a function that flushes the last read from the cd buffer to main memory. It's used to retrieve byte precise reads for the last sector of a file.

Logged

I am the lord, you all know my name, now. I got it all: cash, money, and fame.

So it turns out the PSX version uses a 1bpp font whereas the SFC version appears to use a nice smoothed 2bpp one.Haha so either I just go ahead and make a custom 1bpp VWF that looks a little better than the BIOS version, or am I now going to be advised to change the system to render a 2bpp font?

But assuming I don't change it, does anyone know of any ok-looking 1bpp fonts I could use?