November 2005, Broco (firstname.lastname@example.org)
Thanks for taking an interest in translating Gyakuten Saiban! There is a whopping 1.7 meg of uncompressed text in the script of Gyakuten Saiban 3, so any and all help is appreciated :). I'm Broco, ROM hacker and coordinator of the project.
As you can see from the preview release, the bulk of the ROM hacking has been done already. What's really needed now is translators, preferably some with lots of free time (although I'll take anything really :). Despite all the progress that's been done so far, this game will never be translated unless some dedicated translators join the team, so don't let my months of ROM hacking work go to waste: send me an email to join now!
I'm taking organization seriously for this project --- I used to be a translator in an earlier fan translation project that fell apart before release due to bad coordination, and I learned some lessons about how to avoid this happening again. Here the ROM is already thoroughly hacked before translation even begins, the tools are open-source, and we'll be making a lot of partial releases as we go. So I'm doing everything I can to make sure your translation efforts will not go to waste --- they'll make it into an actual release.
I am hoping that many translators will be interested in joining the team, so instead of explaining how everything works by email to each person individually, I thought I'd write a brief document explaining what's what once and for all. This text should hopefully cover everything you need to know to begin pumping out translated text and inserting it into the ROM.
The ROM hacking tools I wrote for Gyakuten Saiban are open-source and fairly user-friendly, so you won't need to send your translated blocks to me to have them inserted --- you'll be able to hack the ROM yourself and immediately look at your changes in-game as soon as you've got a few lines of the script translated. I'm hoping this will reduce post-translation editing work, as well as make the job more rewarding for the translators.
I'm assuming you're running Windows. (If you're running Linux or Mac OS, please e-mail me and I'll port the stuff.) First download and unzip the source package onto your hard disk: it will create a directory called "cc3_source". Then take your copy of the Gyakuten Saiban 3 ROM (I'll call it "GS3.gba") and copy it into this directory. That's all the installation you should need to do.
My utilities are all command-line, so open a Windows command prompt and
cd to the cc3_source directory. I've provided some Windows batch
files to perform the most important operations on the ROM.
hackall GS3.gba to create a ROM that's fully translated
up to the current stage of the distribution. It won't overwrite
GS3.gba: it will make a new file called "CC3_English.gba". Start up a
GBA emulator and try it out.
extractall GS3.gba to extract all the scripts (and a
few other things) into the "extracted" directory. The human-readable
text files are have the extension ".cc". Open one up with an
SJIS-capable text editor to see how it looks. The file format is
described in section 3.3 of this document.
Now take the script you want to translate (say case3-2.cc) and copy it
into the root directory "cc3_source". Open it with a text editor and add the
text "blah blah blah<p>" on the line right after the
@PTR0 tag. Now run
testhack case3-2.cc. This
modifies the "CC3_English.gba" ROM to insert this script at the point
where the beginning of Case 1 would normally be. So now if you start
the hacked ROM and start Case 1 it will say "blah blah blah" in the
bottom text box, and then go on to begin Case 3 Part 2. This should be
helpful for testing how your translation looks. Now all you need to do
is edit this .cc file to start translating.
It's important to keep in touch, and frequently send updates and partial translations to the team whenever any work gets done. My e-mail is email@example.com; contact me and I'll allocate you some blocks to translate, and put you in touch with the other team members. If you would prefer to translate one case in particular, request to translate that case and there'll certainly be some of it available. Please don't start translating a block without sending an e-mail though, because we want to work efficiently and avoid having several translators do redundant work.
From now on, I (Broco) am planning to work on stuff relating to ROM hacking and project coordination, and leave the bulk of the translation to others (although if you want to take on other responsibilities, tell me and I'll be happy to take some off my shoulders :). Although my Japanese is quite good, translating that enormous amount of text is just overwhelming for one person, and it'll be lots of work for me just coordinating and inserting the translation that's done by others. (And I have the feeling that I'll end up translating quite a bit of the text anyway.) If you think you can help with the ROM hacking (extending the work to Gyakuten Saiban 1 and 2 in particular) drop me a line too, although that's much less needed.
For now e-mail will be adequate for communication. If enough people join the team, I'll also set up a private bulletin board and CVS server.
There are several places in the Gyakuten Saiban 3 ROM that need to be modified in order to translate it.
By far the largest and most important is the script. The script contains all the text that appears in the box at the bottom of the screen. It also contains many control codes intermingled with the text: these codes basically regulate the entire flow of the game, adjusting backgrounds, sprites, sound effects, waits, etc. We'll need to replace all the Japanese text in the script with English text. Also, we'll need to make adjustments to many of the control codes to cope with the differing length and flow of English text. In the ROM, the script is stored in a compact binary form, but I've written a program to convert between this and an HTML-style human-readable hypertext (.cc files). You'll be modifying these .cc files to translate the game. (The .cc format is described in section 3.3 of this document.)
Text is stored in some other forms: there are the evidence boxes, which are 160x64 pixel 3-color bitmaps which appear during the game when you press the R button. I've written a program to convert grayscale .BMP files into Gyakuten Saiban's internal format, so currently these have to be made with an image editing program like Photoshop. It would be possible write a program to auto-generate them from .txt files --- I'll do this if making the pictures by hand proves too much of a pain. The fonts used here are: BatangChe 10pt, #636363 for title, Arial 10pt, #cecece for body.
There are the graphics. I've figured out how to modify the menu/nametag graphics and some have already been translated with a tile editor --- we'll have to do all of them. I haven't yet taken the time to figure out how to deal with the primary background/foreground graphics of the game, but although this is not so important it will have to eventually be done at some later stage of the translation. The title screen is a background graphic and the case selection boxes are foreground graphics. Also, some crucial in-game text is stored as background graphics --- when you press the L button for details, that stuff is always stored as background graphics (detailed police reports, the burnt parchment in Case 5, etc). The 証言開始, 無罪, 有罪, 異議あり and 待った animations are also foreground graphics, but I'm thinking that since they look cool as it is and their meaning is clear from context, we should probably just leave them in Japanese.
There were also many technical issues that needed to be dealt with inside the ROM, notably figuring out the script/graphics compression and rewriting the font display routine. Note that the new font display routine is designed to coexist with the old one: that means that a hacked ROM is able to display both English and Japanese text without any problems (however, please don't intermingle them in the same textbox). The ROM hacking is mostly done at this point and translators shouldn't have to worry about it much. For a detailed and technical overview of the ROM hacking front, see ROM_hacking_notes.txt.
Here are all the files provided in the source distribution:
The .cc file format is a human-readable representation of Gyakuten
Saiban scripts, which can be generated from and converted to raw script
dumps by my
ccscript program. I've designed this file
format to be as easy and fast to type for translators as possible (if
you have any suggestions as to how it could be improved further, please
tell me: this file format is not set in stone).
There are 4 basic types of objects in a .cc file, each of which map directly to some binary codes in the ROM. These are:
ccscriptaccording to a common-sense set of rules (described later), but they can also be forcibly inserted using the _ (underscore) character. English characters will be displayed by my rewritten variable-width font routine during the game. All English characters are to be inserted by translators --- there are none found in the original ROM.
Various numbers appear throughout .cc files, in such things as pointers, control code arguments and the names of unidentified control codes. Make sure to remember that all numbers are in hexadecimal (base 16). This is the number system that goes 0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F,10 instead of 0,1,2,3,4,5,6,7,8,9,10. This has the advantage of being more compact and faster to type, as well as more intuitive in many cases.
.cc files have a concept of whitespace. ASCII space characters, linebreaks, tabs, and comments (# This is a comment, terminated by a linebreak.) all count as whitespace. Whitespace will always be ignored completely except in one case: when it lies between two consecutive English characters (neither of which are space characters themselves). In that case, a single English space character will be inserted between those two English characters (always a single space character, regardless of the amount of whitespace). Note that since a raw script dumped from the original ROM will never contain a single English character, whitespace will always be ignored unless a file contains translated text.
.cc files begin with two directives: $NUMPOINTERS=xxxxxxxx, which gives the number of pointers found in total in this script, and (optionally) $MYSTERIOUSHEADER=xxxxxxxx, which is a mysterious number found in certain scripts whose purpose I haven't yet deciphered and which is best left untouched for now.
Finally, .cc files have certain translation aid features, namely [ ] autospacing boxes and the $TRANSLATED/$END_TRANSLATED directives, which are not strictly necessary but which you'll find extremely useful. See section 3.3.3 and 3.3.4 for how these work.
The complete list of control codes, along with a description of each, is found at gs3_controlcodes.txt. I will describe only some of the most important ones here: please use that file for reference.
There are 128 possible control codes in total. I've figured out the
function of only about a third of them, but in practice these are the
most important ones that you'll see 95% of the time. Most control codes
will be represented in .cc files in this form: <controlcodename arg1 arg2 arg3 arg4 ...>.
The "controlcodename" can be either the raw number of the control code (a
2-character hexadecimal number from 00 to 7F) or a meaningful name
I've given to it (such as
testimony_box). Each control code takes a fixed number of
arguments (parameters telling it what to do): these are all
hexadecimal numbers. The number of arguments depends on the control
code and can range from 0 to as much as 7. For example,
color requires exactly one argument, telling it which
color it should switch to.
Some of the most important and common control codes are represented in a shorthand form in ccscript. I came up with this shorthand because while translating text, I found that certain codes needed to be retyped over and over, and using the full HTML-style form was painful. Note that the full HTML-style form will still work for the following codes, though (if you really want to use it for some reason):
speed). This adjusts the speed that the text appears on the screen, as well as the speed of the "beep-beep-beep" sound representing the characters' voices. It takes one hexadecimal character from 0 (instantaneous) to f (very very slow). Note that because there are a lot more letters in an English word than characters in a Japanese word, in our translation we will almost always have to use higher speeds than in the original. I find that /2 is appropriate for normal text (in the Japanese, /3 /4 /5 is more common), /1 is appropriate for very fast speech, /3 for slow speech, and /5 or slower for ellipses ("...").
wait) This waits for a specified number of time units (always takes exactly 2 hexadecimal characters from 00 to ff). A time unit is something like 1/30th of a second. You'll need to readjust, remove and move these around a lot because the waits from the original text will often be inappropriate in your new English sentences.
shake) This shakes the entire screen. It takes one hexadecimal argument, either 0 (weakest), 1, or 2 (strongest). Note that this is only the visual shake effect, not the sound effect (which requires another control code).
bgcolor) This briefly flashes the screen white. Currently only the argument 0 is supported.
color) This changes the foreground color of the text. Takes one hexadecimal character argument, either 0 (white), 1 (red), 2 (blue), 3 (green). After changing the color make sure to remember to change it back to white when you're done with it, otherwise the game will continue with a weird color for a long time!
There are a few other important control codes which don't have a shorthand but which you should particularly know about.
<b>codes at the right place everywhere --- that's why you'll want to be using [ ] autospacing boxes instead (see the next section).
<nextpage_button>wait for the user to press a button before changing box, whereas
<nextpage_nobutton>does it instantly. Actually, I don't know the difference between
<nextpage_button>; there must be some subtle difference but as far as I can tell so far they do exactly the same thing.
jmpcontrol code is the number of the pointer, plus hexadecimal 80. So to jump to
@PTR2, the control code is
<jmp 82>; to jump to
@PTR4b, the control code is
<jmp cb>. Get it? You'll have to do a little hexadecimal arithmetic, but it's not hard (easier in fact than adding 128 decimal).
<p>codes between consecutive
<newevidence>codes that use the 4000 option, otherwise the game will crash.
As mentioned earlier, because the English font is variable-width it
would be a nightmare to manually place all the
linebreak control codes. How can you figure out when a line ends? The
primary goal of the [ ] autospacing boxes is to solve this for you. Each
[ ] box should correspond to one textbox in the game, and
ccscript will automatically take care of all the formatting
within that box.
ccscript understands the width of each English character in
Arial 13pt (which is what we use in the hacked ROM right now). When it
[ character, it starts calculating the width of the
line starting from that point. When it realizes that a character just
went past the right edge of the screen, it goes to find the last English
space character that was inserted and replaces it with a
<b> control code. If the next line after this
also goes off the screen, then it outputs an error message:
you've made this textbox too big and you'll have to remove some words or
split it up into several. The count stops when it sees the
ccscript also will detect
control codes that you've inserted manually and internally start
counting from the second line when this happens. So if you want to
force a linebreak inside a [ ] box for stylistic effect, you can still do
so. In this case the only effect of the [ ] box (aside from the
auto-spacing described below) will be to output an error if you go past
the length of the second line.
Auto-spacing. Inserting linebreaks is their primary purpose, but the [ ] boxes also have a subtle but important effect on spacing. As I mentioned earlier, whitespace is always ignored except when it is found between two consecutive English characters, in which case a space character is inserted. This behavior is reasonable but it turns out to be actually too conservative in practice. For example, consider this typical text:
/3 Hello,/2=08 Naruhodo.=1a How are you *0today?
Here we have some speed, wait and shake control codes interspersed through the English text. But remember that whitespace is only significant when it's between two consecutive English characters. That means the control codes mess everything up here. What you'll find outputted in the game is: "Hello,Naruhodo.How are youtoday?". Bad, bad, bad.
So one obvious solution is to use underscores to force spaces where you want them, like this:
/3 Hello,/2=08_Naruhodo.=1a_How are you_*0today?
This will output "Hello, Naruhodo. How are you today?", correctly spaced as we want, but it's painful to type and it would be all too easy to forget to put these underscores all the time. So [ ] boxes also intelligently deal with this problem.
[/3 Hello,/2=08 Naruhodo.=1a How are you *0today?]
will put all the spaces at the right
ccscript is intelligent enough to put spaces even
when there are control codes between two characters, and it also
understands that you should not put spaces before punctuation like
periods and commas. The only place where [ ] autospacing regularly
screws up is with quotation marks: you will need to put underscores
before and after a quotation block if there are control codes
There are only a few rare cases where [ ] boxes don't do what you want:
in those cases, feel free to enter English text outside of a [ ] box,
making sure to put the
<b> at the right point. But
in practice, 99% of your text should be in [ ] boxes.
If you look at a newly generated .cc file, you'll notice that
ccscript automatically puts empty  boxes after every line
of Japanese. This is just to save you a little typing: you can write
your English text inside the [ ] (and they have no effect on anything if
you don't write any English inside the brackets).
is smart enough to understand paragraph breaks and place the boxes
accordingly, but if you're not happy with the autogenerated results
you'll sometimes want to remove some brackets and merge lines to make
While translating the script, one way of going about it would be to
delete the original Japanese text and write the English text instead.
But it strikes me that it would be better to leave the Japanese in
alongside the English --- that way, it will be much easier to make
revisions to the translation later without needing to constantly
cross-reference an original dump of the script. We could simply
"comment out" the Japanese instead of deleting it completely. That's
why I came up with the $TRANSLATED
directive. This directive tells
ccscript to completely
ignore any line coming after it that contains one or more Japanese (i.e.
SJIS) characters. This behavior ends if the $END_TRANSLATED directive appears, after which
Japanese text is inserted normally again.
ccscript to ignore
the entire line whenever it sees Japanese; that means any
control codes on that line will be ignored too. Watch out that no
important control codes are on a line with Japanese on it. Fortunately,
ccscript is pretty smart and when it generates a new .cc
file it will ensure that only the shorthand control codes and
<b> are on the same line as Japanese text --- so in
fact this this dangerous-sounding behavior is a good thing, because it
will automatically kill all those control codes that you don't want in
your translation anyway.
Let's look at some real examples of script and how to translate them. These examples are taken from the beginning of case1-1.cc, and they were used in generating the preview release.
First, an example of some basic text. Near the beginning of case1-1.cc, we find this text:
‥‥千尋クン。=10<b>とにかく、まずは落ちつくんぢゃ。  <p> そんなキョロキョロしとったら、<b>挙動不審でタイホされちまうぞ。 
Nothing special here, other than the
=10 wait control code
and a few linebreaks. I translated this as:
$TRANSLATED ‥‥千尋クン。=10<b>とにかく、まずは落ちつくんぢゃ。 [... Chihiro.=10<b>First of all, calm down.] <p> そんなキョロキョロしとったら、<b>挙動不審でタイホされちまうぞ。 [If you keep fidgeting, you'll be arrested for hyperactivity in court.] $END_TRANSLATED
(In practice the $TRANSLATED and $END_TRANSLATED are far away from this point, not right beside, but just remember that they have to be there for the Japanese to be removed properly.) I inserted a linebreak in the translation of the first line for stylistic reasons, though it wasn't strictly necessary (in the second line, I let the brackets insert it). I had to take a few liberties with the translation in the second line to make it funny and fit within the box (it just barely fits), but that's all par for the course.
Here's a slightly more complex example, taken from the opening animation of case1-1 where Naruhodo appears to murder the victim:
<bgcolor 204 1 1f>=19<nextpage_nobutton><bganim 3 201><bg ff><bgcolor 100 0 1f> =01*0<bgcolor 301 8 1f> %0/1‥‥  <sound 48 1><bgcolor 301 8 1f> やめ  <bgcolor 301 8 1f> てくれッ！=64  <nextpage_nobutton> =0a/3彼女のコト/c‥‥=28<b>*1/2そんなふうに言うなッ！=50  <bgcolor 301 8 1f><bgcolor 400 0 1f>=01<hidetextbox 1><nextpage_nobutton><bg ff> <bgcolor 100 0 1f>=01<bganim 6 200><sound 16e 1>=24<bgcolor 400 0 1f>=01<bganim 6 201> <bganim c 3><bg 37><bganim b 201><bganim 1 202><music 14f 0><bgcolor 304 1 1f> =19=60=28<bganim 1 3>=50<6B 1 0 0><bganim c 200>=b4=b4<hidetextbox 0>
Now here we see there's lots of fancy control codes doing all sorts of gimmicks we don't understand with the music and animation. Don't worry about them: just leave them as they are and they should keep working in your translated version. All you need to do is fill in the brackets:
$TRANSLATED <bgcolor 204 1 1f>=19<nextpage_nobutton><bganim 3 201><bg ff><bgcolor 100 0 1f> =01*0<bgcolor 301 8 1f> %0/1‥‥ [%0/1 <sound 48 1><bgcolor 301 8 1f> やめ Stop <bgcolor 301 8 1f> てくれッ！=64 it!=64] <nextpage_nobutton> =0a/3彼女のコト/c‥‥=28<b>*1/2そんなふうに言うなッ！=50 [=0a/2Stop it/c...=28*1/1stop bloody badmouthing her!=50] <bgcolor 301 8 1f><bgcolor 400 0 1f>=01<hidetextbox 1><nextpage_nobutton><bg ff> <bgcolor 100 0 1f>=01<bganim 6 200><sound 16e 1>=24<bgcolor 400 0 1f>=01<bganim 6 201> <bganim c 3><bg 37><bganim b 201><bganim 1 202><music 14f 0><bgcolor 304 1 1f> =19=60=28<bganim 1 3>=50<6B 1 0 0><bganim c 200>=b4=b4<hidetextbox 0> $END_TRANSLATED
Now I decided to omit completely the opening ellipsis (....) completely,
because it isn't used as much in English. Here
wasn't so smart about where to split the lines and put the brackets, so
I had to remove some of the brackets to make sure the first block
represents an entire textbox. Note that even though "Stop it!"
obviously takes no more than one line, the brackets still perform a
useful function because they insert a space between the "Stop" and the
"it". As for the second line, it's a pretty straight translation:
you'll notice however that I increased the value of the speed control
codes from /3 and /2 to /2 and /1 respectively.
Now let's take an example from few lines in the witness mode:
@PTR21 <noop><testimony_box ac 0><person a 0 0><bg 3><name 300><54 0 1><hidetextbox 0> <person a 238 0> %3カゼゴロシ・Ｚは、この２・３日<b>ずっと飲んでいたんですけど‥‥%0  <special_jmp><endjmp> @PTR22 <noop><testimony_box ad 0><person a 0 0><bg 3><name 300><54 0 1><hidetextbox 0> <person a 238 0> %3事件のあった日のおヒルごはんの<b>ときから、なくなっちゃって。%0  <special_jmp><endjmp>
As you can see, each box has a pointer to it, which is used by the game to skip between them. Here it's crucial that your translation take up no more than one box; it would be a pain to have to add another one, with a new pointer and all. Other than that, though, it's a pretty straight translation:
$TRANSLATED @PTR21 <noop><testimony_box ac 0><person a 0 0><bg 3><name 300><54 0 1><hidetextbox 0> <person a 238 0> %3カゼゴロシ・Ｚは、この２・３日<b>ずっと飲んでいたんですけど‥‥%0 [%3/2I had been taking Cold-Killer Z for two or three days straight...%0] <special_jmp><endjmp> @PTR22 <noop><testimony_box ad 0><person a 0 0><bg 3><name 300><54 0 1><hidetextbox 0> <person a 238 0> %3事件のあった日のおヒルごはんの<b>ときから、なくなっちゃって。%0 [%3/2But on the day of his death, it disappeared around lunchtime.%0] <special_jmp><endjmp> $END_TRANSLATED
Finally, here's one of the rare examples where using the [ ] brackets is not appropriate:
/5なるほどさん。=10あなた‥‥  <wait_noanim 2d><b><26 1><person 25 148 0><bgtile 3><bg e><bgcolor 301 8 1f> <sound 48 1>*1<sound 48 1> /2この私に、=0cウソをついたのねっ！  <nextpage_button><person 0 0 0><hideperson><26 0><person a 3e8 3e8><bg 3> <name 300> /6‥‥‥‥/8‥‥/a‥‥/c‥‥=46<b>  <sound 4c 1>*2<bgcolor 301 8 1f><person a 1cb0 1cb0><bgcolor 301 8 1f>=05<sound 4c 1> *2=05<bgcolor 301 8 1f> /2ごめん  <bgcolor 301 8 1f> なさ  <bgcolor 301 8 1f> わわ  <sound 4c 1>*2<bgcolor 301 8 1f> ああああ  <bgcolor 301 8 1f> ああ  <bgcolor 301 8 1f> あん！*2=3c 
Here we're going to want to render Naruhodo's "waaaaaah" as a single word, so we don't want the brackets to automatically insert spaces, or else we'll end up with something like "waa aa aa aah". So I chose to remove all the brackets from Naruhodo's box in my translation:
$TRANSLATED /5なるほどさん。=10あなた‥‥ [/3Mr. Naruhodo.=30You... <wait_noanim 2d><b><26 1><person 25 148 0><bgtile 3><bg e><bgcolor 301 8 1f> <sound 48 1>*1<sound 48 1> /2この私に、=0cウソをついたのねっ！ /2you lied to me, didn't you?] <nextpage_button><person 0 0 0><hideperson><26 0><person a 3e8 3e8><bg 3> <name 300> /6‥‥‥‥/8‥‥/a‥‥/c‥‥=46<b> /6.../8.../a.../c...=46<b> <sound 4c 1>*2<bgcolor 301 8 1f><person a 1cb0 1cb0><bgcolor 301 8 1f>=05<sound 4c 1> *2=05<bgcolor 301 8 1f> /2ごめん /2So-sor <bgcolor 301 8 1f> なさ r <bgcolor 301 8 1f> わわ yyywaaaa <sound 4c 1>*2<bgcolor 301 8 1f> ああああ aaaa <bgcolor 301 8 1f> ああ aaaa <bgcolor 301 8 1f> あん！*2=3c aaah!*2=3c $END_TRANSLATED
Whenever you do something like this, make sure to test your translation in-game to make sure it renders the way you think.
Note that I don't feel that strongly about any of the following guidelines, it's just that we ought to just pick some policies and stick with them to be consistent across the entire translation. Feel free to add to this section if you feel the need to make new policies.
Here is a list of common names and phrases in the game. All translators should be translating these the same way to be consistent, thus this table.
|美柳ちなみ||Dolores Willow||My invention|
|呑田菊三||Jack Richford||My invention|
|ゴドー検事||Godot||From Samuel Beckett's play, "Waiting for Godot"|
|怪人☆仮面マスク||The Mysterious Mask|
|勇盟大学||Phamous University||Attempt at translating the pun|
This list is still very incomplete; it will be filled in gradually. This is not so crucial anyway because a search-and-replace can always be performed to make things consistent.