10/31/2023: Localization News - Dead of the Brain 1!

No, NOT a trick, a Halloween treat! Presenting the Dead of the Brain 1 English patch by David Shadoff for the DEAD last official PC Engine CD game published by NEC before exiting the console biz in 1999! I helped edit/betatest and it's also a game I actually finished in 2023, yaaay! Shubibiman also did a French localization. github.com/dshadoff/DeadoftheBrain
twitter.com/NightWolve/PCENews
Main Menu

Cyber Knight translation

Started by megatron-uk, 02/05/2014, 01:03 PM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

johnnykonami

Quote from: guest on 10/27/2016, 12:39 PMDon't be like me and misread that as ASSBANK.ASSCHUNK

Unless you like to giggle like a child.

Totally understand the reason you'll be out of the game for 18 years or so. I just killed my free time for the same reason this month.
I'm learning some programming now, and I'm officially moving learning about using ASSBANK.ASSCHUNK to the top of my list.

megatron-uk

QuoteTotally understand the reason you'll be out of the game for 18 years or so. I just killed my free time for the same reason this month.
Commiserations  :wink:

megatron-uk

New commits to Github (https://github.com/megatron-uk/cyberknight-pce) - replaced the old script extractor with extractAssets.py and a translator/splitter named splitAssets.py. If you want to give it a go, run the former, then the latter, just make sure you have your "Cyber Knight (J).pce" rom in the same directory.

This should result in a directory of JSON files (under assets/raw and assets/split), split by asset bank and chunk (no, I refuse to stoop to calling them Assbank and Asschunk you bunch of lowlifes!) with translations using my old lookup tables. I've also been able to embed a few more special byte sequences; some missing NPC names and the like.

It's a much cleaner data set to work with now.

Next step is to run through the SNES translation and re-insert the strings again where they match.

Then write a patcher to expand the ROM, update the main bank asset map with the new ROM bank numbers to suit.

Perhaps a week until I can inject the output in to the ROM again and do a playtest? Hopefully, at that point we'll find those bits that were broken are no longer broken!

elmer

Quote from: megatron-uk on 10/28/2016, 12:27 PMPerhaps a week until I can inject the output in to the ROM again and do a playtest? Hopefully, at that point we'll find those bits that were broken are no longer broken!
Great news! I hope it all works properly now.  :D

You're doing excellent work getting everything refactored so quickly.

FYI ... It looks like it's possible to move the English font up by a pixel so that the lower-case descenders actually drop below the baseline (even if only by 1 pixel).  :-"

megatron-uk

So, as part of cleaning things up and trying to get to 100% on working out the remaining control bytes I've decided to try and work out the dialogue window control codes.

0x1a is the control code to open a dialogue window, it is then followed by a single byte that controls the size and placement of the window.

Recording the location of the dialogue windows and altering the second byte I get the following:

IMG

IMG

IMG

IMG

IMG

IMG

IMG

IMG

The control codes that start with 0x5 seem to be 2-line windows, and those that start with 0x7 are 1-line. I can't figure out how the length of the window is set, as the control code 0x74 is a tiny, 1-line box used for the jumpdrive countdown timer in the intro cinema, so it's not as if the lower 4 bits of this byte are width.

I can't work out how the second byte can encode the window position and size - I'm leaning more towards the fact that there may be a list of window position and sizes stored somewhere in the ROM and this byte is perhaps a lookup code.

If we want to control the size and location of the dialogue boxes for the expanded English translation, then I need to get a much more extensive lookup table of the boxes that these control codes produce. The intro and initial world get me some of them, but there will be lots more.

megatron-uk

Looks like the images are not coming through. Must be a problem with my router.

megatron-uk

Okay, no height/width link to the value of the second byte, that I can determine. I'm fairly sure that the value of this second byte is a lookup to a table of pre-set dialogue box dimensions.

I've been through about 50 or 60 variations of the second byte and although there is some similarity between some values and their nearest neighbours, ultimately it just seems to be a series of variations.

I'll upload a screen grab of all the working second byte values I've found so far a little later today. At least that will give me a manual look-up of whether I want to change the dialogue box for a given script segment or not.

megatron-uk

Here are all the 0x1a 0x?? dialogue box control codes that I've been able to find in the game.

IMG

I've tried variations on the second byte for codes that don't appear in the game, but I get weird results, so it would appear that this is the limit of what is used in the normal dialogue code. There are quite a few other instances that this doesn't cover:

- In-and-out of battle menus
- Planet names
- Discussions with crew

The above don't appear to use the same display code; the script for much of the above doesn't begin with the same control codes as elsewhere in the game. Much of this isn't a problem, but there are a few areas (ship locations, dialogue snippets with the crew) that would benefit from alternative text box location and/or sizes.

megatron-uk

Small commit to github. The splitAssets.py script now embeds dialogue box information into the extracted Japanese text.

Each of the text strings in a given asset chunk now looks something like this:

{
      "string_number" : 2,
      "string_size" : 59,
      "start_pos" : 0x28086,
      "bytes" : ["1a", "4f", "10", "30", "a2", "cb", "ae", "b3", "d2", "dd", "b5", "dd", "c4", "de", "20", "31", "30", "30", "30", "20", "df", "43", "20", "b2", "bc", "de", "ae", "b3", "a1", "03", "d6", "b3", "b6", "de", "dd", "c6", "20", "b5", "b5", "dc", "da", "c0", "20", "c1", "b2", "bb", "c5", "20", "dc", "b8", "be", "b2", "03", "c3", "de", "bd", "a1", "a3", "08"],
      "PCE_japanese" : "<newbox><24x3@bottom_centred><NPC_Mica>『ひょうめんおんど 1000゜C いじょう。\nようがんに おおわれた ちいさな わくせい\nです。』<wait>",
      "SNES_english" : "",
      "SNES_accuracy" : 0.0,
      "PCE_english" : "",
      "notes" : "",
},

elmer

Quote from: megatron-uk on 10/29/2016, 09:04 AMOkay, no height/width link to the value of the second byte, that I can determine. I'm fairly sure that the value of this second byte is a lookup to a table of pre-set dialogue box dimensions.

I've been through about 50 or 60 variations of the second byte and although there is some similarity between some values and their nearest neighbours, ultimately it just seems to be a series of variations.
Quote from: megatron-uk on 10/29/2016, 09:25 AMHere are all the 0x1a 0x?? dialogue box control codes that I've been able to find in the game.
Excellent work!  :D

It's great to see your posts and follow your investigations.

You and I approach the investigation process in different ways, and I find it fascinating to see how you're so successfully coming up with all this critically-important information.

My approach is more of "dive into the code and see what it's doing", which takes a lot longer to get any results, and can easily lead to lot of unnecessary disassembly.



Quote from: megatron-uk on 10/29/2016, 10:50 AMSmall commit to github. The splitAssets.py script now embeds dialogue box information into the extracted Japanese text.
I absolutely love your JSON-format extraction with all of its extra meta-data.

It presents the information in a way that's easy to read and modify (especially by automated tools).

megatron-uk

#210
Cheers!

I've modified the old mapScript.py code to work on the new JSON. I've run it through a few asset files and it's working the same as before, so it looks like I can get pretty much all of the automatic translations done again in no time.

The time sink will be the manual patches I did by hand in the old files.

I do prefer JSON to XML, it's much less noisy and XML always reminds me of LISP; matching opening and closing braces. I hated that at University.

JSON is a much lighter transfer format and it maps neatly to Python/Ruby/Javascript dictionaries and lists. Normally I wouldn't manually write JSON like I am doing now with file.write(), but because we've got a mix of ASCII and various Unicode fonts (shift-JIS, UTF-8, etc) all in the same file, it's a bit of pain to serialize it all just using a single json.dumps() call. Do as I say, not as I do, folks  :lol:

megatron-uk

Update from a couple of passes through the mapAssets.py script, using only the first couple of 'quality' levels of the fuzzy matching against the SNES script. Each 'quality level' represents a pass through the code where I use a different level at which I consider a script to be matched. I start of at level 1 with only strings that are >80% as possible matches, then each level after that drops by 5-10%. Once you get to level 6 or so you really need to start comparing by eyeball.

There's a lot more automatic matches still to get:

mapAssets.py - Map untranslated patches from the PC-Engine CyberKnight to the SNES script
----------------

Configuration
=============
Verbose: False
Over-write: False
Pass Type: 1
SNES Script File: CyberKnightSNES.csv <- OK
Input Directory: assets/split <- OK
Output Directory: assets/converted <- OK
Patches Found: 26 <- OK

Patch Summary
=============
|--------|------------|------------|----------|----------|---------|--------|---------------
| Strings|Translations|SNES matches|SNES best |SNES worst|SNES avg.| Tiny   | Patch Name
|--------|------------|------------|----------|----------|---------|--------|---------------
|  198   |   7 / 198  |   48 / 198 |      100 |        0 |      56 |   114  | 0x14.0x83.dat
|  136   |   0 / 136  |   39 / 136 |       93 |        0 |      52 |    80  | 0xa.0x1.dat
|  131   |   0 / 131  |   41 / 131 |      100 |        0 |      56 |    69  | 0xa.0x3.dat
|   21   |   0 /  21  |    7 /  21 |      100 |        0 |      68 |    13  | 0xa.0x5.dat
|   42   |   0 /  42  |   12 /  42 |       92 |        0 |      62 |    22  | 0xa.0x7.dat
|   82   |   0 /  82  |   31 /  82 |      100 |        0 |      74 |    45  | 0xa.0x9.dat
|   24   |   0 /  24  |    2 /  24 |        0 |        0 |       0 |    13  | 0xc.0x1.dat
|   25   |   0 /  25  |    9 /  25 |       92 |        0 |      59 |    13  | 0xc.0x11.dat
|    9   |   0 /   9  |    3 /   9 |       90 |        0 |      57 |     6  | 0xc.0x13.dat
|   29   |  22 /  29  |   12 /  29 |       89 |        0 |      70 |    16  | 0xc.0x15.dat
|  105   | 105 / 105  |    1 / 105 |        0 |        0 |       0 |    65  | 0xc.0x17.dat
|   74   |   0 /  74  |   33 /  74 |      100 |        0 |      73 |    38  | 0xc.0x3.dat
|   50   |   0 /  50  |   20 /  50 |      100 |        0 |      82 |    27  | 0xc.0x5.dat
|   53   |   0 /  53  |   22 /  53 |       90 |        0 |      61 |    27  | 0xc.0x7.dat
|   42   |   0 /  42  |   14 /  42 |      100 |        0 |      63 |    25  | 0xc.0x9.dat
|   29   |   0 /  29  |   10 /  29 |       90 |        0 |      17 |    16  | 0xc.0xb.dat
|   93   |   0 /  93  |   37 /  93 |       92 |        0 |      46 |    47  | 0xc.0xd.dat
|    5   |   3 /   5  |    2 /   5 |       92 |       72 |      82 |     3  | 0xc.0xf.dat
|  277   |   0 / 277  |   17 / 277 |      100 |        0 |      62 |   151  | 0xe.0x1.dat
|  287   |   0 / 287  |   66 / 287 |      100 |        0 |      49 |   185  | 0xe.0x3.dat
|  161   |   0 / 161  |   20 / 161 |      100 |        0 |      69 |    93  | 0xe.0x5.dat
|  149   | 148 / 149  |   56 / 149 |       92 |        0 |      48 |    89  | 0xe.0x7.dat
|  260   |   0 / 260  |   77 / 260 |      100 |        0 |      71 |   153  | 0xe.0x9.dat
|  385   |   0 / 385  |   77 / 385 |      100 |        0 |      68 |   227  | 0xe.0xb.dat
|  221   |   0 / 221  |    0 / 221 |        0 |      100 |       0 |   152  | 0xe.0xd.dat
|  228   |   0 / 228  |   75 / 228 |      100 |        0 |      81 |   134  | 0xe.0xf.dat
|--------|------------|------------|----------|----------|---------|--------|---------------
| Strings|Translations|SNES matches|SNES best |SNES worst|SNES avg.| Tiny   | Patch Name
|--------|------------|------------|----------|----------|---------|--------|---------------
| 3116   | 285 / 3116 | 731 / 3116 |      100 |        0 |      14 |   1823  |

Patch Summary Key
=================
Strings      : Total number of text strings in the patch file
Translations : How many strings already have we added a full english translation for?
SNES Matches : How many strings have matching SNES english text that canbe used as a basis for an english translation?
SNES Best    : The most accurate SNES match in this patch file.
SNES Worst   : The least accurate SNES match in this patch file.
SNES average : The average accuracy of SNES matches in this patch file.
Tiny         : How many strings are sub-2 characters (ie not text)?

The key figures are the SNES matches and Translations columns. The former is the number of automatic matches my code made against the SNES script, by comparing the decoded PCE byte sequences, and the latter is the number of by-hand entries I've made, or cut-and-paste from the SNES matches. I don't automatically use the SNES script matches, as there's a lot of improvements that can be made by eye (available length of text boxes, some grammar, as well as some words/phrases that I think can be improved).

On that note I'm thinking about having all of the items, monsters and names parameterised,  liked I'm using <newbox> or <wait> to represent different byte sequences. I'm using <NPC_name> at present, to ease name replacement if I desire, but I could extend it to items and other things. One thing that I want to replace for a more 'science fiction' feel is the use of the phrase 'monopole coil' (which is an in-game widget that you need to find to fix your ship FTL drive). I think a far more appropriate phrase would be a 'singularity' coil or cell. I think there is quite a bit of that kind of stuff in the game though  :wink:

megatron-uk

Found a couple more text control codes:

0x19 0x71 - Move cursor to the box that was active 2 windows ago
0x19 0x72 - Move cursor to the box that was active 3 windows ago
0x19 0x73 - Move cursor to the box that was active before this one

These take effect during the intro cinema and there are matching control codes used throughout in-game dialogue (both prefixed with 0x19, but the second byte differs). It doesn't appear the second byte can be swapped between the values used in-game and the cinema section (random text appears instead).

It explains how the active text window changes, especially when multiple characters have open dialogue on screen at any one point. Also gives me a bit more flexibility when 'enhancing' the more in-depth segments.

I've updated the translation table to include these and will run the script through it again.

megatron-uk

More story and in-game text done. Some bits I've expanded substantially; reworking simple one-line , one-way dialogue into more developed conversations between the player party and NPC's. Nothing earth shattering. For example, later in the game you run into the Garaians, and advanced but quite staid and pacifist race. They are also extremely boring and dislike violence.

One of the conversations originally went something like this:

NPC: "X warring race is awful."
NPC: "So are the killer machines."
NPC: "In fact, so is anyone with weapons."

I added in a dialogue box from one of the players party after the second line to say:

Player Party: "That sounds like they're talking about the <bleep> there..."

Just to give you an indication that these alien dudes are talking about the same nasties that you start to encounter yourself :)

What I would like to do, and haven't found a way to do it yet, is any control codes that adjust font colour. It would be nice to have 'inner thought' type messages like that in a different colour. Same goes for 'You acquired the widget!' in game messages. Just to differentiate against spoken dialogue.

Here's the stats so far:

mapAssets.py - Map untranslated patches from the PC-Engine CyberKnight to the SNES script
----------------

Configuration
=============
Verbose: False
Over-write: False
Pass Type: 1
SNES Script File: CyberKnightSNES.csv <- OK
Input Directory: assets/split <- OK
Output Directory: assets/converted <- OK
Patches Found: 26 <- OK

Patch Summary
=============
|--------|------------|------------|----------|----------|---------|--------|---------------
| Strings|Translations|SNES matches|SNES best |SNES worst|SNES avg.| Tiny   | Patch Name
|--------|------------|------------|----------|----------|---------|--------|---------------
|  198   |   7 / 198  |   48 / 198 |      100 |        0 |      56 |   114  | 0x14.0x83.dat
|  136   |   0 / 136  |   39 / 136 |       93 |        0 |      52 |    80  | 0xa.0x1.dat
|  131   |   0 / 131  |   41 / 131 |      100 |        0 |      56 |    69  | 0xa.0x3.dat
|   21   |  21 /  21  |    7 /  21 |      100 |        0 |      53 |    13  | 0xa.0x5.dat COMPLETE
|   42   |   0 /  42  |   12 /  42 |       92 |        0 |      62 |    22  | 0xa.0x7.dat
|   82   |   0 /  82  |   31 /  82 |      100 |        0 |      74 |    45  | 0xa.0x9.dat
|   24   |  15 /  24  |    2 /  24 |        0 |        0 |       0 |    13  | 0xc.0x1.dat
|   25   |  25 /  25  |    9 /  25 |       92 |        0 |      59 |    13  | 0xc.0x11.dat COMPLETE
|    9   |   9 /   9  |    3 /   9 |       90 |        0 |      57 |     6  | 0xc.0x13.dat COMPLETE
|   29   |  29 /  29  |   12 /  29 |       89 |        0 |      70 |    16  | 0xc.0x15.dat COMPLETE
|  105   | 105 / 105  |    1 / 105 |        0 |        0 |       0 |    65  | 0xc.0x17.dat COMPLETE
|   74   |   0 /  74  |   33 /  74 |      100 |        0 |      73 |    38  | 0xc.0x3.dat
|   50   |   0 /  50  |   20 /  50 |      100 |        0 |      82 |    27  | 0xc.0x5.dat
|   53   |   0 /  53  |   22 /  53 |       90 |        0 |      61 |    27  | 0xc.0x7.dat
|   42   |   0 /  42  |   14 /  42 |      100 |        0 |      63 |    25  | 0xc.0x9.dat
|   29   |  28 /  29  |   11 /  29 |       90 |        0 |      15 |    16  | 0xc.0xb.dat
|   93   |   0 /  93  |   37 /  93 |       92 |        0 |      46 |    47  | 0xc.0xd.dat
|    5   |   5 /   5  |    2 /   5 |       92 |       72 |      82 |     3  | 0xc.0xf.dat COMPLETE
|  274   | 149 / 274  |   13 / 274 |       93 |        0 |      51 |   149  | 0xe.0x1.dat
|  287   |   0 / 287  |   66 / 287 |      100 |        0 |      49 |   185  | 0xe.0x3.dat
|  161   |   0 / 161  |   20 / 161 |      100 |        0 |      69 |    93  | 0xe.0x5.dat
|  149   | 148 / 149  |   56 / 149 |       92 |        0 |      48 |    89  | 0xe.0x7.dat
|  260   |   0 / 260  |   77 / 260 |      100 |        0 |      71 |   153  | 0xe.0x9.dat
|  385   |   0 / 385  |   77 / 385 |      100 |        0 |      68 |   227  | 0xe.0xb.dat
|  221   |   0 / 221  |    0 / 221 |        0 |      100 |       0 |   152  | 0xe.0xd.dat
|  228   |   0 / 228  |   75 / 228 |      100 |        0 |      81 |   134  | 0xe.0xf.dat
|--------|------------|------------|----------|----------|---------|--------|---------------
| Strings|Translations|SNES matches|SNES best |SNES worst|SNES avg.| Tiny   | Patch Name
|--------|------------|------------|----------|----------|---------|--------|---------------
| 3113   | 541 / 3113 | 728 / 3113 |      100 |        0 |      14 |   1821  |


Also found another control code: 0x07 - sets the printing speed of the text string that follows. It's controlled by the immediately following byte. Experimentation shows that setting 0x07 0x01 is very slow, about 1 character every 2 seconds, whereas 0x07 0x2F is very fast, perhaps 10 characters a second.

The expanded text isn't getting inserted just yet. I'd like to try and track down as much of the control codes as possible before then.

elmer

#214
Quote from: megatron-uk on 11/03/2016, 06:10 PMFound a couple more text control codes:

0x19 0x71 - Move cursor to the box that was active 2 windows ago
0x19 0x72 - Move cursor to the box that was active 3 windows ago
0x19 0x73 - Move cursor to the box that was active before this one
Excellent detective work!  :D

You're finding and understanding things through alteration/experimentation that I'd have found by looking at the source-code itself.

The method isn't important ... for something like this, it's all about the result, and your persistence is paying off!

Congratulations!  :wink:


Quote from: megatron-uk on 11/04/2016, 09:16 PMI added in a dialogue box from one of the players party after the second line to say:

Player Party: "That sounds like they're talking about the <bleep> there..."
And this is why I'm taking some of my time to hopefully provide a little help.

You care enough about the game that you want it to sound good to an English-speaking audience, and you're not just satisfied with making it understandable.

Some passions deserve to be supported, even if they're not initially understood or shared.

That's how I felt when I saw SamIAm's work on Zeroigar, and you can see where his passion and enthusiasm lead in our continuing work on Xanadu 1 and Xanadu 2.

At the end of the day, it all (and IMHO always) relies upon someone who has a belief and passion in something informing/educating everyone else into seeing why they love that thing (game/sport/food/etc), and becoming "believers" themselves.

SamIAm has managed to get me to "believe" in a couple of games now that I didn't even know existed a few years ago.

And after the introduction, and spending months working on them, I understand why he loves those games, and I've come to share that love, and to trust his opinion.

What megatron-uk is doing here with Cyber Knight seems (to me) to show that same kind of passion.

He's doing (as esteban would say) "God's Work!".


Speaking of which ...

... here's the data table that Cyber Knight uses to load up the ASCII font into VRAM.

They're grouping a number of individual graphical "assets" into different VRAM "layout" arrangements that get set up at different times.

The ASCII font itself is compressed in bank $16, asset $01 ... but as you can see, the reference to it will need to be modified in a lot of places if that font is going to be changed.

ASSET BANK $10 ASSET CHUNK $0d

                .org  $4875

                .dw  group_4807 ; idx $00 - $4785 (1st font data loaded @ $1000-$1fff)
                .dw  group_4843 ; idx $01 - $4787
                .dw  group_487f ; idx $02 - $4789
                .dw  group_4893 ; idx $03 - $478b
                .dw  group_4893 ; idx $04 - $478d
                .dw  group_48d9 ; idx $05 - $478f
                .dw  group_48ed ; idx $06 - $4791
                .dw  group_4901 ; idx $07 - $4793
                .dw  group_4915 ; idx $08 - $4795
                .dw  group_4929 ; idx $09 - $4797
                .dw  group_493d ; idx $0a - $4799
                .dw  group_4951 ; idx $0b - $479b
                .dw  group_495b ; idx $0c - $479d
                .dw  group_496f ; idx $0d - $479f
                .dw  group_49c9 ; idx $0e - $47a1
                .dw  group_49d3 ; idx $0f - $47a3
                .dw  group_49dd ; idx $10 - $47a5
                .dw  group_49dd ; idx $11 - $47a7
                .dw  group_4a41 ; idx $12 - $47a9
                .dw  group_4aa5 ; idx $13 - $47ab
                .dw  group_4b13 ; idx $14 - $47ad
                .dw  group_4b77 ; idx $15 - $47af
                .dw  group_4bef ; idx $16 - $47b1
                .dw  group_4c67 ; idx $17 - $47b3
                .dw  group_4c67 ; idx $18 - $47b5
                .dw  group_4cdf ; idx $19 - $47b7
                .dw  group_4cfd ; idx $1a - $47b9
                .dw  group_4d1b ; idx $1b - $47bb
                .dw  group_4d43 ; idx $1c - $47bd
                .dw  group_4da7 ; idx $1d - $47bf
                .dw  group_4dc5 ; idx $1e - $47c1
                .dw  group_4ded ; idx $1f - $47c3
                .dw  group_4ded ; idx $20 - $47c5
                .dw  group_4ded ; idx $21 - $47c7
                .dw  group_4ded ; idx $22 - $47c9
                .dw  group_4ded ; idx $23 - $47cb
                .dw  group_4ded ; idx $24 - $47cd
                .dw  group_4ded ; idx $25 - $47cf
                .dw  group_4ded ; idx $26 - $47d1
                .dw  group_4ded ; idx $27 - $47d3
                .dw  group_4ded ; idx $28 - $47d5
                .dw  group_4ded ; idx $29 - $47d7
                .dw  group_4ded ; idx $2a - $47d9
                .dw  group_4ded ; idx $2b - $47db
                .dw  group_4ded ; idx $2c - $47dd
                .dw  group_4ded ; idx $2d - $47df
                .dw  group_4ded ; idx $2e - $47e1
                .dw  group_4ded ; idx $2f - $47e3
                .dw  group_4ded ; idx $30 - $47e5
                .dw  group_4df7 ; idx $31 - $47e7
                .dw  group_4e01 ; idx $32 - $47e9
                .dw  group_4e1f ; idx $33 - $47eb
                .dw  group_4e29 ; idx $34 - $47ed
                .dw  group_4e47 ; idx $35 - $47ef
                .dw  group_4e51 ; idx $36 - $47f1
                .dw  group_4e5b ; idx $37 - $47f3
                .dw  group_4e5b ; idx $38 - $47f5
                .dw  group_4e5b ; idx $39 - $47f7
                .dw  group_4e97 ; idx $3a - $47f9
                .dw  group_4edd ; idx $3b - $47fb
                .dw  group_4f0f ; idx $3c - $47fd
                .dw  group_4f41 ; idx $3d - $47ff
                .dw  group_4f73 ; idx $3e - $4801
                .dw  group_4faf ; idx $3f - $4803
                .dw  group_4faf ; idx $40 - $4805

        ; idx $00 : $32 $33   $34   $35   $36 $37 $38 $39   BNK IDX

group_4807:     .db $00,$11,  $6b,  $0c,  $80,$00,$80,$80,  $16,$01
group_4811:     .db $00,$18,  $80,  $0c,  $80,$00,$80,$80,  $16,$03
group_481b:     .db $b0,$17,  $04,  $24,  $00,$08,$10,$18,  $16,$05
group_4825:     .db $00,$11,  $01,  $08,  $c0,$80,$80,$80,  $16,$01
group_482f:     .db $00,$10,  $08,  $20,  $00,$08,$10,$18,  $16,$0d
group_4839:     .db $00,$20,  $00,  $0c,  $80,$00,$80,$80,  $16,$07

        ; idx $01 : $32 $33   $34   $35   $36 $37 $38 $39   BNK IDX

group_4843:     .db $00,$11,  $6b,  $0c,  $40,$00,$40,$40,  $16,$01
group_484d:     .db $00,$18,  $80,  $0c,  $40,$00,$40,$40,  $16,$03
group_4857:     .db $b0,$17,  $04,  $24,  $00,$08,$10,$18,  $16,$05
group_4861:     .db $00,$11,  $01,  $08,  $c0,$80,$80,$80,  $16,$01
group_486b:     .db $00,$10,  $08,  $20,  $00,$08,$10,$18,  $16,$0d
group_4875:     .db $00,$20,  $00,  $0c,  $40,$00,$40,$40,  $16,$07

        ; idx $02 : $32 $33   $34   $35   $36 $37 $38 $39   BNK IDX

group_487f:     .db $00,$30,  $0c,  $1c,  $00,$08,$10,$80,  $1c,$11
group_4889:     .db $c0,$30,  $a7,  $1c,  $00,$08,$10,$c0,  $1c,$13

        ; idx $03 : $32 $33   $34   $35   $36 $37 $38 $39   BNK IDX

group_4893:     .db $00,$11,  $6b,  $0c,  $40,$00,$40,$40,  $16,$01
group_489d:     .db $00,$18,  $80,  $0c,  $40,$00,$40,$40,  $16,$03
group_48a7:     .db $b0,$17,  $04,  $24,  $00,$08,$10,$18,  $16,$05
group_48b1:     .db $00,$11,  $01,  $08,  $c0,$80,$80,$80,  $16,$01
group_48bb:     .db $00,$10,  $07,  $20,  $00,$08,$10,$18,  $16,$0d
group_48c5:     .db $00,$21,  $20,  $0c,  $80,$00,$80,$80,  $16,$01
group_48cf:     .db $00,$21,  $01,  $08,  $c0,$80,$80,$80,  $16,$01

        ; idx $05 : $32 $33   $34   $35   $36 $37 $38 $39   BNK IDX

group_48d9:     .db $80,$24,  $08,  $0c,  $40,$00,$40,$40,  $16,$09
group_48e3:     .db $80,$26,  $08,  $0c,  $40,$00,$40,$40,  $16,$0b

        ; idx $06 : $32 $33   $34   $35   $36 $37 $38 $39   BNK IDX

group_48ed:     .db $00,$70,  $0d,  $24,  $00,$08,$10,$18,  $36,$05
group_48f7:     .db $d0,$70,  $30,  $1c,  $00,$08,$10,$80,  $36,$0f

        ; idx $07 : $32 $33   $34   $35   $36 $37 $38 $39   BNK IDX

group_4901:     .db $00,$70,  $0a,  $24,  $00,$08,$10,$18,  $36,$07
group_490b:     .db $a0,$70,  $2a,  $1c,  $00,$08,$10,$80,  $36,$11

        ; idx $08 : $32 $33   $34   $35   $36 $37 $38 $39   BNK IDX

group_4915:     .db $00,$70,  $0b,  $24,  $00,$08,$10,$18,  $36,$09
group_491f:     .db $b0,$70,  $3c,  $1c,  $00,$08,$10,$80,  $36,$13

        ; idx $09 : $32 $33   $34   $35   $36 $37 $38 $39   BNK IDX

group_4929:     .db $00,$70,  $03,  $24,  $00,$08,$10,$18,  $36,$0b
group_4933:     .db $30,$70,  $46,  $1c,  $00,$08,$10,$80,  $36,$15

        ; idx $0a : $32 $33   $34   $35   $36 $37 $38 $39   BNK IDX

group_493d:     .db $00,$70,  $0b,  $24,  $00,$08,$10,$18,  $36,$0d
group_4947:     .db $b0,$70,  $3f,  $1c,  $00,$08,$10,$80,  $36,$17

        ; idx $0b : $32 $33   $34   $35   $36 $37 $38 $39   BNK IDX

group_4951:     .db $00,$20,  $64,  $0c,  $80,$00,$80,$80,  $24,$13

        ; idx $0c : $32 $33   $34   $35   $36 $37 $38 $39   BNK IDX

group_495b:     .db $00,$20,  $98,  $0c,  $80,$80,$80,$80,  $24,$15
group_4965:     .db $00,$30,  $98,  $0c,  $80,$00,$80,$80,  $24,$15

        ; idx $0d : $32 $33   $34   $35   $36 $37 $38 $39   BNK IDX

group_496f:     .db $00,$10,  $01,  $20,  $00,$08,$10,$18,  $16,$0d
group_4979:     .db $00,$11,  $6b,  $0c,  $00,$80,$80,$80,  $16,$01
group_4983:     .db $00,$18,  $80,  $0c,  $00,$80,$80,$80,  $16,$03
group_498d:     .db $00,$21,  $6b,  $0c,  $80,$00,$80,$80,  $16,$01
group_4997:     .db $00,$28,  $80,  $0c,  $80,$00,$80,$80,  $16,$03
group_49a1:     .db $00,$31,  $6b,  $0c,  $00,$00,$80,$80,  $16,$01
group_49ab:     .db $00,$38,  $80,  $0c,  $00,$00,$80,$80,  $16,$03
group_49b5:     .db $00,$41,  $6b,  $0c,  $80,$80,$00,$80,  $16,$01
group_49bf:     .db $00,$48,  $80,  $0c,  $80,$80,$00,$80,  $16,$03

        ; idx $0e : $32 $33   $34   $35   $36 $37 $38 $39   BNK IDX

group_49c9:     .db $00,$30,  $40,  $1c,  $00,$08,$10,$80,  $24,$11

        ; idx $0f : $32 $33   $34   $35   $36 $37 $38 $39   BNK IDX

group_49d3:     .db $00,$30,  $f0,  $24,  $00,$08,$10,$18,  $24,$01

        ; idx $10 : $32 $33   $34   $35   $36 $37 $38 $39   BNK IDX

group_49dd:     .db $00,$40,  $36,  $1c,  $00,$08,$10,$80,  $2c,$03
group_49e7:     .db $60,$43,  $04,  $1c,  $00,$08,$10,$80,  $2c,$05
group_49f1:     .db $a0,$43,  $20,  $1c,  $00,$08,$10,$80,  $2c,$07
group_49fb:     .db $a0,$45,  $31,  $1c,  $00,$08,$10,$80,  $2e,$0d
group_4a05:     .db $b0,$48,  $0c,  $1c,  $00,$08,$10,$80,  $2c,$0b
group_4a0f:     .db $70,$49,  $01,  $1c,  $00,$08,$10,$80,  $2c,$0d
group_4a19:     .db $80,$49,  $43,  $1c,  $00,$08,$10,$80,  $2c,$0f
group_4a23:     .db $b0,$4d,  $05,  $1c,  $00,$08,$10,$80,  $2c,$11
group_4a2d:     .db $00,$4e,  $19,  $24,  $00,$08,$10,$18,  $2c,$13
group_4a37:     .db $90,$4f,  $04,  $1c,  $00,$08,$80,$10,  $2e,$19

        ; idx $12 : $32 $33   $34   $35   $36 $37 $38 $39   BNK IDX

group_4a41:     .db $00,$40,  $36,  $1c,  $00,$08,$10,$80,  $2c,$03
group_4a4b:     .db $60,$43,  $04,  $1c,  $00,$08,$10,$80,  $2c,$05
group_4a55:     .db $a0,$43,  $02,  $1c,  $00,$08,$10,$80,  $2c,$15
group_4a5f:     .db $c0,$43,  $2f,  $1c,  $00,$08,$10,$80,  $2c,$09
group_4a69:     .db $b0,$46,  $0c,  $1c,  $00,$08,$10,$80,  $2c,$1d
group_4a73:     .db $70,$47,  $01,  $1c,  $00,$08,$10,$80,  $2c,$33
group_4a7d:     .db $80,$47,  $10,  $1c,  $00,$08,$10,$80,  $2c,$35
group_4a87:     .db $80,$48,  $09,  $1c,  $00,$08,$10,$80,  $2c,$21
group_4a91:     .db $10,$49,  $22,  $1c,  $00,$08,$10,$10,  $2c,$25
group_4a9b:     .db $b0,$4b,  $44,  $1c,  $00,$08,$10,$c0,  $2e,$11

        ; idx $13 : $32 $33   $34   $35   $36 $37 $38 $39   BNK IDX

group_4aa5:     .db $00,$40,  $36,  $1c,  $00,$08,$10,$80,  $2c,$03
group_4aaf:     .db $60,$43,  $04,  $1c,  $00,$08,$10,$80,  $2c,$05
group_4ab9:     .db $a0,$43,  $31,  $1c,  $00,$08,$10,$80,  $2e,$0d
group_4ac3:     .db $b0,$46,  $0c,  $1c,  $00,$08,$10,$80,  $2c,$17
group_4acd:     .db $70,$47,  $01,  $1c,  $00,$08,$10,$80,  $2c,$19
group_4ad7:     .db $80,$47,  $22,  $1c,  $00,$08,$10,$80,  $2c,$1b
group_4ae1:     .db $a0,$49,  $02,  $1c,  $00,$08,$10,$80,  $2c,$15
group_4aeb:     .db $c0,$49,  $2f,  $1c,  $00,$08,$10,$80,  $2c,$09
group_4af5:     .db $b0,$4c,  $0c,  $1c,  $00,$08,$10,$80,  $2c,$1d
group_4aff:     .db $70,$4d,  $01,  $1c,  $00,$08,$10,$80,  $2c,$1f
group_4b09:     .db $00,$4e,  $20,  $1c,  $00,$08,$10,$80,  $2c,$03

        ; idx $14 : $32 $33   $34   $35   $36 $37 $38 $39   BNK IDX

group_4b13:     .db $00,$40,  $36,  $1c,  $00,$08,$10,$80,  $2c,$03
group_4b1d:     .db $60,$43,  $04,  $1c,  $00,$08,$10,$80,  $2c,$05
group_4b27:     .db $a0,$43,  $02,  $1c,  $00,$08,$10,$80,  $2c,$15
group_4b31:     .db $c0,$43,  $2f,  $1c,  $00,$08,$10,$80,  $2c,$09
group_4b3b:     .db $b0,$46,  $0c,  $1c,  $00,$08,$10,$80,  $2c,$1d
group_4b45:     .db $70,$47,  $01,  $1c,  $00,$08,$10,$80,  $2c,$2b
group_4b4f:     .db $80,$47,  $10,  $1c,  $00,$08,$10,$80,  $2c,$2d
group_4b59:     .db $80,$48,  $09,  $1c,  $00,$08,$10,$80,  $2c,$21
group_4b63:     .db $10,$49,  $22,  $1c,  $00,$08,$10,$10,  $2c,$25
group_4b6d:     .db $30,$4b,  $3b,  $1c,  $00,$08,$80,$10,  $2c,$23

        ; idx $15 : $32 $33   $34   $35   $36 $37 $38 $39   BNK IDX

group_4b77:     .db $00,$40,  $36,  $1c,  $00,$08,$10,$80,  $2c,$03
group_4b81:     .db $60,$43,  $04,  $1c,  $00,$08,$10,$80,  $2c,$05
group_4b8b:     .db $a0,$43,  $02,  $1c,  $00,$08,$10,$80,  $2e,$21
group_4b95:     .db $c0,$43,  $2f,  $1c,  $00,$08,$10,$80,  $2c,$09
group_4b9f:     .db $b0,$46,  $0c,  $1c,  $00,$08,$10,$80,  $2c,$1d
group_4ba9:     .db $70,$47,  $01,  $1c,  $00,$08,$10,$80,  $2c,$2b
group_4bb3:     .db $80,$47,  $10,  $1c,  $00,$08,$10,$80,  $2c,$2d
group_4bbd:     .db $80,$48,  $09,  $1c,  $00,$08,$10,$80,  $2c,$21
group_4bc7:     .db $10,$49,  $22,  $24,  $00,$08,$10,$18,  $2e,$0f
group_4bd1:     .db $30,$4b,  $0b,  $1c,  $00,$08,$80,$10,  $2c,$27
group_4bdb:     .db $e0,$4b,  $3c,  $1c,  $00,$08,$80,$10,  $2c,$29
group_4be5:     .db $00,$4f,  $10,  $1c,  $00,$08,$80,$10,  $2c,$01

        ; idx $16 : $32 $33   $34   $35   $36 $37 $38 $39   BNK IDX

group_4bef:     .db $00,$40,  $36,  $1c,  $00,$08,$10,$80,  $2c,$03
group_4bf9:     .db $60,$43,  $04,  $1c,  $00,$08,$10,$80,  $2c,$05
group_4c03:     .db $a0,$43,  $02,  $1c,  $00,$08,$10,$80,  $2c,$2f
group_4c0d:     .db $c0,$43,  $2f,  $1c,  $00,$08,$10,$80,  $2c,$09
group_4c17:     .db $b0,$46,  $0c,  $1c,  $00,$08,$10,$80,  $2c,$1d
group_4c21:     .db $70,$47,  $01,  $1c,  $00,$08,$10,$80,  $2c,$2b
group_4c2b:     .db $80,$47,  $10,  $1c,  $00,$08,$10,$80,  $2c,$2d
group_4c35:     .db $80,$48,  $09,  $1c,  $00,$08,$10,$80,  $2c,$21
group_4c3f:     .db $10,$49,  $22,  $24,  $00,$08,$10,$18,  $2c,$25
group_4c49:     .db $30,$4b,  $0b,  $1c,  $00,$08,$80,$10,  $2c,$27
group_4c53:     .db $e0,$4b,  $30,  $1c,  $00,$08,$80,$10,  $2c,$31
group_4c5d:     .db $00,$4f,  $10,  $1c,  $00,$08,$80,$10,  $2c,$01

        ; idx $17 : $32 $33   $34   $35   $36 $37 $38 $39   BNK IDX

group_4c67:     .db $00,$40,  $36,  $1c,  $00,$08,$10,$80,  $2c,$03
group_4c71:     .db $60,$43,  $04,  $1c,  $00,$08,$10,$80,  $2c,$05
group_4c7b:     .db $a0,$43,  $02,  $1c,  $00,$08,$10,$80,  $2c,$15
group_4c85:     .db $c0,$43,  $2f,  $1c,  $00,$08,$10,$80,  $2c,$09
group_4c8f:     .db $b0,$46,  $0c,  $1c,  $00,$08,$10,$80,  $2c,$1d
group_4c99:     .db $70,$47,  $01,  $1c,  $00,$08,$10,$80,  $2c,$33
group_4ca3:     .db $80,$47,  $10,  $1c,  $00,$08,$10,$80,  $2c,$35
group_4cad:     .db $80,$48,  $09,  $1c,  $00,$08,$10,$80,  $2c,$21
group_4cb7:     .db $10,$49,  $22,  $24,  $00,$08,$10,$18,  $2c,$25
group_4cc1:     .db $30,$4b,  $0b,  $1c,  $00,$08,$80,$10,  $2c,$27
group_4ccb:     .db $e0,$4b,  $30,  $1c,  $00,$08,$80,$10,  $2c,$29
group_4cd5:     .db $00,$4f,  $10,  $1c,  $00,$08,$80,$10,  $2c,$01

        ; idx $19 : $32 $33   $34   $35   $36 $37 $38 $39   BNK IDX

group_4cdf:     .db $00,$40,  $36,  $1c,  $00,$08,$10,$80,  $2c,$03
group_4ce9:     .db $60,$43,  $08,  $1c,  $00,$08,$10,$80,  $2e,$13
group_4cf3:     .db $e0,$43,  $92,  $1c,  $00,$08,$10,$c0,  $2e,$15

        ; idx $1a : $32 $33   $34   $35   $36 $37 $38 $39   BNK IDX

group_4cfd:     .db $00,$40,  $16,  $1c,  $00,$08,$10,$80,  $2e,$17
group_4d07:     .db $60,$41,  $1e,  $1c,  $00,$08,$80,$10,  $2e,$1f
group_4d11:     .db $40,$43,  $cc,  $1c,  $00,$08,$10,$c0,  $2e,$25

        ; idx $1b : $32 $33   $34   $35   $36 $37 $38 $39   BNK IDX

group_4d1b:     .db $00,$40,  $0b,  $1c,  $00,$08,$10,$80,  $2c,$37
group_4d25:     .db $b0,$40,  $0c,  $1c,  $00,$08,$10,$80,  $2c,$39
group_4d2f:     .db $70,$41,  $98,  $1c,  $00,$08,$10,$c0,  $2c,$3b
group_4d39:     .db $f0,$4a,  $17,  $1c,  $00,$08,$10,$c0,  $2e,$23

        ; idx $1c : $32 $33   $34   $35   $36 $37 $38 $39   BNK IDX

group_4d43:     .db $00,$40,  $36,  $1c,  $00,$08,$10,$80,  $2c,$03
group_4d4d:     .db $60,$43,  $04,  $1c,  $00,$08,$10,$80,  $2c,$05
group_4d57:     .db $a0,$43,  $02,  $1c,  $00,$08,$10,$80,  $2c,$15
group_4d61:     .db $c0,$43,  $2f,  $1c,  $00,$08,$10,$80,  $2c,$09
group_4d6b:     .db $b0,$46,  $0c,  $1c,  $00,$08,$10,$80,  $2c,$1d
group_4d75:     .db $70,$47,  $01,  $1c,  $00,$08,$10,$80,  $2c,$1f
group_4d7f:     .db $80,$47,  $10,  $1c,  $00,$08,$10,$80,  $2e,$01
group_4d89:     .db $80,$48,  $09,  $1c,  $00,$08,$10,$80,  $2c,$21
group_4d93:     .db $30,$4a,  $1a,  $1c,  $00,$08,$10,$c0,  $2e,$03
group_4d9d:     .db $b0,$4a,  $08,  $24,  $00,$08,$10,$18,  $2e,$1b

        ; idx $1d : $32 $33   $34   $35   $36 $37 $38 $39   BNK IDX

group_4da7:     .db $40,$40,  $13,  $1c,  $00,$08,$10,$c0,  $2e,$05
group_4db1:     .db $70,$41,  $98,  $1c,  $00,$08,$10,$c0,  $2c,$3b
group_4dbb:     .db $f0,$4a,  $49,  $1c,  $00,$08,$10,$80,  $2e,$07

        ; idx $1e : $32 $33   $34   $35   $36 $37 $38 $39   BNK IDX

group_4dc5:     .db $00,$40,  $36,  $1c,  $00,$08,$10,$80,  $2c,$03
group_4dcf:     .db $60,$43,  $11,  $1c,  $00,$08,$10,$80,  $2e,$1d
group_4dd9:     .db $70,$44,  $0c,  $1c,  $00,$08,$80,$10,  $2e,$09
group_4de3:     .db $30,$45,  $96,  $1c,  $00,$08,$10,$c0,  $2e,$0b

        ; idx $1f : $32 $33   $34   $35   $36 $37 $38 $39   BNK IDX

group_4ded:     .db $00,$60,  $fb,  $1c,  $00,$08,$10,$80,  $22,$01

        ; idx $31 : $32 $33   $34   $35   $36 $37 $38 $39   BNK IDX

group_4df7:     .db $00,$70,  $32,  $1c,  $00,$08,$10,$80,  $22,$03

        ; idx $32 : $32 $33   $34   $35   $36 $37 $38 $39   BNK IDX

group_4e01:     .db $00,$70,  $b3,  $0c,  $00,$00,$00,$80,  $22,$07
group_4e0b:     .db $30,$7b,  $25,  $1c,  $00,$08,$10,$80,  $22,$09
group_4e15:     .db $80,$7d,  $09,  $1d,  $00,$08,$10,$c0,  $22,$0b

        ; idx $33 : $32 $33   $34   $35   $36 $37 $38 $39   BNK IDX

group_4e1f:     .db $00,$70,  $a1,  $1c,  $00,$08,$10,$80,  $22,$05

        ; idx $34 : $32 $33   $34   $35   $36 $37 $38 $39   BNK IDX

group_4e29:     .db $00,$70,  $b3,  $8c,  $00,$00,$00,$80,  $22,$07
group_4e33:     .db $30,$7b,  $25,  $9c,  $00,$08,$10,$80,  $22,$09
group_4e3d:     .db $80,$7d,  $03,  $9d,  $00,$08,$10,$c0,  $22,$0b

        ; idx $35 : $32 $33   $34   $35   $36 $37 $38 $39   BNK IDX

group_4e47:     .db $00,$0e,  $10,  $0c,  $80,$00,$80,$80,  $16,$01

        ; idx $36 : $32 $33   $34   $35   $36 $37 $38 $39   BNK IDX

group_4e51:     .db $10,$70,  $7d,  $1c,  $00,$08,$10,$80,  $22,$0d

...

group_4faf:     .ds $42af - *

esteban

Elmer: there is a typo in line 3d2d: it should read "B$NK", not "BNK"

:)

I agree that megatron-UK's passion for Cyber Knight is going to awaken an appreciation for something that 99.6% of us were either completely ignorant of, or had barely any genuine experiences with.

:)
IMGIMG IMG  |  IMG  |  IMG IMG

megatron-uk

Many thanks, I do appreciate it.

In respect to the font, one thing I have been thinking about is if I can truly get every bit of Japanese text replaced then it would mean I would I would have over 100 free 8x8 tiles. It should be possible to get several variations on the ASCII font in those remaining tiles; italic, bold, etc. That would be one way of doing it and not have to mess with the font loader - it could all remain the same and simply load  italic ascii tiles, rather than the katakana/hiragana tiles.

Back to the dialogue, I do love this game. It's a fab SRPG, the graphics could be better - especially the overworld, but the music and sound fx are really great and there are some nice mecha designs and, judging from the amount of dialogue (I still haven't actually played the game beyond the first world) it seems to be fairly big and varied in terms of maps, characters and enemies.

Having the SNES english text has made translating our PCE version significantly easier (google translate is great, but it really doesn't beat someone fluent in Japanese) although there are a few small differences between the two that meant I had to write the mapper script to do fuzzy matching between the two. The big thing is, like you say, the script is understandable, but, it does leave a little to be desired. With a bit of tweaking (and judicious use of those extra control codes!) it can be made much more interactive. Hopefully people will enjoy it when it is eventually done!

megatron-uk

Just about finished writing the updated insert tool. It can currently expand the rom by the correct number of extra banks and also does a double conversion of the english text - once to hex bytecodes and then back again, just to be doubly sure that my conversion table is working properly. Tracking down dodgy bytes once inserted would be a pain!

Hopefully actually start to insert the text again before the end of the week and then test whether the expanded bank scheme works. I'll have to mess around with the bank loader table by hand first, but should be able to automate it once done.

megatron-uk

#218
Quickie - There are 27 text assets in the game, meaning 27 extra 8k banks. But that's an odd number so I've decided to up it to 32. That rounds the size up nicely to 768KB (64x8KB banks in the original ROM, plus 32 extra banks to hold the expanded English script).

There's only one asset that is larger than a single bank - it's already 10KB in Japanese (and thus in two consecutive banks already in the original game) and will probably expand to 14KB or more once fully converted. Everything else is well within the 8KB bank limit.

It's pretty wasteful though - the script is roughly 55-60KB in size so far, that's with about 20% English and 80% Japanese. That means we're wasting about 200KB of that extra ROM space... oh well, good job it's not a problem with SD card space!

elmer

Quote from: megatron-uk on 11/09/2016, 11:49 AMIt's pretty wasteful though - the script is roughly 55-60KB in size so far, that's with about 20% English and 80% Japanese. That means we're wasting about 200KB of that extra ROM space... oh well, good job it's not a problem with SD card space!
Space doesn't really matter in terms of ROM expansion these days, so you're doing the sensible and sane thing IMHO.  =D&gt;

Now ... programmer "bragging rights" ... well that's a different kettle-of-fish!  :wink:

megatron-uk

Well, I've got the text inserted into the expanded ROM banks, also altered the asset bank table and asset offset table and.... well... it still loads! Some of translated script displays, but it seems to be off by a few strings as the main menu and player creation screen is showing garbage for a few areas and a few sections are wrong ('Del' in place of the 'End' button for the name entry... that means just a couple of delimeters are out of place).

The original script is left as-is. It still occupies banks 0x0a to 0x15.

The intro cinematic plays nicely and most of that text is okay, which is another bank, so it, I must have that one pretty much spot on. I've got some work to do with the text box creation control codes - I must have counted the size wrong as I have a couple of characters spilling over what I thought was a 22 character box with 20 characters in it!  :roll:

So, it's looking promising; the relocation to the additional banks does seem to have worked, I now just need to track down the 'usual' problems of missing control bytes, delimiters, etc.  :)

megatron-uk

Starting to make real progress now. The intro cinema is back working again, the expanded scrolling story after the cinema works perfectly (unlike my original translation which bumped up against rom size limits!) and the 'power is out' dialogue that happens immediately after is 100%.

Shipboard menu entries are next - the move options are done, now working on the Kanji text. I did this by hand last time around, so unlike most dialogue in the game, they're not all seperated by 0x00 bytes (lots of Kanji which uses that byte as well!) so I'm having to do them by eyeball. But there's only a couple of dozen individual entries to do, so it's not like it's going to take forever.

Also added a automatic way to get the Git revision number into the game, so I now embed the revision into the main menu so that I know what version it is that I (or anyone else) is playing.

Latest script and patched assets up on Github. If you're savvy with Python on Linux, just clone the repo and drop a 'Cyber Knight (J).pce' rom in the folder then run 'expandRom.py'. You shouldn't need to do anything else.

If you want to play around with it, then the following sequence is how to get all the assets from the game:

extractAssets.py - Extract all text asset banks to ./assets/raw... e.g. ./assets/raw/0x0a.dat
splitAssets.py - Split asset banks by asset chunks e.g. ./assets/split/0x0a.0x01.dat
mapAssets.py - Programatically match SNES translations to the split assets, outputs to ./assets/converted
expandRom.py - Inserts assets from ./assets/converted back in to an expanded (768KB) ROM file.

At the moment I'm tweaking asset files and then re-running expandRom.py each time, then firing up Mednafen and either loading BRAM saves, or save states to test each time.

elmer

Quote from: megatron-uk on 11/13/2016, 04:32 AMStarting to make real progress now. The intro cinema is back working again, the expanded scrolling story after the cinema works perfectly (unlike my original translation which bumped up against rom size limits!) and the 'power is out' dialogue that happens immediately after is 100%.
Great progress!  :D


QuoteLatest script and patched assets up on Github. If you're savvy with Python on Linux, just clone the repo and drop a 'Cyber Knight (J).pce' rom in the folder then run 'expandRom.py'. You shouldn't need to do anything else.
I just gave it a try ... it's looking good!  8)

It was nice to see the intro in English.


QuoteAt the moment I'm tweaking asset files and then re-running expandRom.py each time, then firing up Mednafen and either loading BRAM saves, or save states to test each time.
That's what we're doing with the Xanadu games, too.

megatron-uk

Okay, here is your chance to contribute, folks.

We have 5 playable mecha in the game, they are:

レックス,Rex
ウイナー,Winner
シェリフ,Sheriff
タイタン,Titan
サウルス,Saurus

Catchy, eh?  ](*,)

We have a restriction in that their displayed name can be no more than 4 characters in length - this is decided by the width of the status window in combat, the fact that all 5 are displayed horizontally, in a list in the hangar bay to select from, etc. Not a lot I can do about it without some serious hacking, or a variable width font (not at the moment, thank you!).

So, let's have your ideas, ladies and gentlemen. My first thought was to use something like Gundam model numbers; RX78 and similar, as there's not a lot of 'cool' names to fit in just four characters!

elmer

Quote from: megatron-uk on 11/19/2016, 08:56 AMWe have a restriction in that their displayed name can be no more than 4 characters in length - this is decided by the width of the status window in combat, the fact that all 5 are displayed horizontally, in a list in the hangar bay to select from, etc. Not a lot I can do about it without some serious hacking, or a variable width font (not at the moment, thank you!).
You're never going to get a VWF in that game with any kind of reasonable-to-do hack ... the whole thing is too tile-based.

But ... when you get rid of the need for all of those Japanese characters, you can predraw certain strings in a VWF.

For instance, in this case you've got 5 mecha using 4 tiles each ... so if you have 20 tiles free in memory, then you just give them names like "abcd", "efgh", "ijkl", etc, and then draw each name into their unique set of 4 tiles.

It looks like you'll have 128 tiles free to do this trick in the main font in VRAM, and even more in the alternate font.

Perhaps that will be an option for you at some point?

TurboXray

elmer beat me to it. That's a common trick: hardcoded vwf stuff in tiles no longer needed.

megatron-uk

There's an interesting string hidden amongst those that are used for the main menu and player creation screen.

Hidden at 0x1c086 there is this sequence of bytes:
["20", "20", "be", "b2", "cd", "de", "c2", "3a", "02", "20", "b5", "dd", "c5", "20", "20", "b5", "c4", "ba"]

Translated, this is:
"  せいべつ:\n おんな  おとこ"

In English, this seems to be:
" Sex: Male Female"

It would appear that at some point, Cyber Knight perhaps was planned to allow the player to choose the sex of the character they played, but that string is never shown and there isn't any option to select a gender at character creation time. It's odd, as it's between strings that construct the player creation screen, so I would have expected it to be shown on that screen.

There are a few other bits and pieces like this that I've spotted, a sound menu is the other interesting one, which, if we could figure out how to access it, would be fantastic.

On translation news, I've got most of the battle menu text back in, and having figured out more of the control codes along the way, it's shaping up to be nicer looking that the previous version. In pure numbers I've got about 50% of the ~3000 strings translated so far (many are just control codes, so it's not all printable). The big job is jumping back and forth between savegames to make sure that inserted text doesn't break things... it often does!

esteban

#227
I don't care what gender I adopt when I play Cyber Knight—it's gonna be great!

:)

Also, I have suggestions for the names, should we limit them to only four characters (I know a solution was already found, humor me):

Leif
Pewk
Slam
Torn
Dr.B
Kawk
Tawk
Bono
Edge
Lynk
Lugi
Luge
IMGIMG IMG  |  IMG  |  IMG IMG

megatron-uk

There are actually only a few cases where NPC's having names longer than 4 characters makes a difference:

Team menu - selecting the two active members of your squad. Only 4 tiles of space is present between the 'selector' buttons, so anything longer gets cropped.

Battle menu - in the right hand stats column there is a space of 6 tiles between the border of the column and the current HP of the character. When you first start the game you only have a double-digit amount of HP, so 5 characters in your squadmates names will fit early on, with a space between the values, but later in the game they will overlap the displayed HP.

Mecha-equip menu - 4 characters width in the box to select the mecha to view. If longer, then the team mates name overflows the selection box.

At the moment I'm using 'Rx78', 'Wasp', 'Seta', 'Ogre' and 'Soru' as the mecha/combat suit names to simplify display issues.
There's nothing that 'breaks' the game as such, but it's a bit messy.

megatron-uk

One thing I've been thinking about is trying to work out how the portraits of the various characters are displayed. There is also some code somewhere that displays a graphic when you find an 'item', whatever that widget is - for instance in the first world, when the Professor gives you his Star Map, it pops up a little window with a start chart inside it; there are lots of items in the game to acquire, so I would think this will be consistent throughout the code.

It would be great to be able to do that throughout the game - pop up a window in the corner of the screen for whoever is speaking, for example. As well as reference any items when they are discussed on other worlds.

I thought there may have been some control codes embedded in the script that did this, but it doesn't appear to be the case.

elmer

Quote from: megatron-uk on 11/21/2016, 03:23 AMAt the moment I'm using 'Rx78', 'Wasp', 'Seta', 'Ogre' and 'Soru' as the mecha/combat suit names to simplify display issues.
Here are some others ... can you guess the theme?  :wink:

ErNy
KrMt
MsPg
KuKi
GrVr
BgBd

Too much? :roll:

megatron-uk

I should try to extract these graphic assets... I haven't seen any images of NPC's you talk to, and getting them in to the game, alongside the portraits of your team would be a fantastic achievement.

This is probably going to be a side-project alongside the translation. Need to track the existing graphic assets down first!

NecroPhile

Quote from: elmer on 11/21/2016, 04:18 AMHere are some others ... can you guess the theme?  :wink:

ErNy
KrMt
MsPg
KuKi
GrVr
BgBd

Too much? :roll:
No OsCr?
Ultimate Forum Bully/Thief/Saboteur/Clone Warrior! BURN IN HELL NECROPHUCK!!!

elmer


Psycho Punch

レックス,REX
ウイナー,ACE
シェリフ,STAR/CAPT
タイタン,HULK
サウルス,DINO

I tried.

This Toxic Turbo Turd/Troll & Clone Warrior calls himself "Burning Fight!!" on Neo-Geo.com
For a good time, reach out to: aleffrenan94@gmail.com or punchballmariobros@gmail.com
Like DildoKobold, dildos are provided free of charge, no need to bring your own! :lol:
He also ran scripts to steal/clone this forum which blew up the error logs! I had to delete THOUSANDS of errors cause of this nutcase!
how_to_spell_ys_sign_origin_ver.webp

megatron-uk

I keep coming across 'weird' behaviour in the new expanded ROM. There are certain bits of dialogue that I know are in one bank (the NPC text for the first world - Farworld, for example), that when triggered, display a partial string from a completely different bank.

Here's an example:

The first NPC triggers a string that was originally in bank 0x0a, asset ID 01 located at 0x1403e, and is now in bank 0x4c, asset ID 01 at ROM location 0x9805a:
IMG

But then this second NPC is supposed to trigger a string that was in the same bank (it was the next string in fact - seperated only by a single 0x00 delimeter [and still is] and started a dialogue about robots going around kidnapping people), but instead triggers one that is in fact located in another bank completely now. It triggers a string from bank 0x41, asset ID 01 (originally bank 0x14, asset ID 0x83) way, way off at 0x94004:
IMG

There's also the fact that whenever the save/load game screen is shown it gets corrupted with some of 'test screen' text that is normally never shown in the game:
IMG

I've even tried getting rid of every single byte of translated text and simply re-inserting the original japanese script (as raw hex bytes) as-is, in the new asset banks. I get the same result in this case, as well as a weird 'off by one string' error as shown here in the original, unaltered Japanese ROM:
IMG

... and here with the same data, but relocated to the new banks:
IMG

I'm starting to think that there may be some other logic to loading the script assets going on here. But I'm out of my depth when it comes to assembler.

I'm starting to tear my hair out with this now, actually.

elmer

#236
Quote from: megatron-uk on 11/26/2016, 05:14 AMI've even tried getting rid of every single byte of translated text and simply re-inserting the original japanese script (as raw hex bytes) as-is, in the new asset banks. I get the same result in this case, as well as a weird 'off by one string' error as shown here in the original, unaltered Japanese ROM:
IMG

... and here with the same data, but relocated to the new banks:
IMG

I'm starting to think that there may be some other logic to loading the script assets going on here. But I'm out of my depth when it comes to assembler.

I'm starting to tear my hair out with this now, actually.
This is the test to concentrate on for the moment ... insert all of the original Japanese text chunks (as binary blobs) into the new banks.

If you do that and get "off-by-one" errors like that, then I suspect that you could be constructing the new banks incorrectly.

Thinks to look at would be not putting in the beyond-the-last-chunk offset correctly (that's needed to calculate the length of a chunk), getting an off-by-one in the actual length of the text chunk (i.e. missing the last string, or the text-chunk-terminator).

The off-by-one of the text in those screens suggests that the game is looking for the strings correctly, but that it's missing one string in the count and so displaying stuff one string too soon.

That could easily be a missing terminator on the previous chunk, or the structure of the bank not pointing to the beginning of the chunk properly.


Quote from: megatron-uk on 11/26/2016, 05:14 AMBut then this second NPC is supposed to trigger a string that was in the same bank (it was the next string in fact - seperated only by a single 0x00 delimeter [and still is] and started a dialogue about robots going around kidnapping people), but instead triggers one that is in fact located in another bank completely now. It triggers a string from bank 0x41, asset ID 01 (originally bank 0x14, asset ID 0x83) way, way off at 0x94004:
IMG
Hold on ... ...  :-k

It could be as simple as a misunderstanding of the bank structure.

The game uses pairs of banks per 16KB block, starting at an even bank number ... so originally banks $0A+$0B, $0C+$0D, $0E+$0F, $14+$15.

So ... how come you've got a string in bank $41? Are you not putting things in 16KB blocks?

<EDIT>

Hmmm ... a quick look at my disassembly suggests that the code *should* handle data blocks on odd banks, but the game never does it, so I'd be worried about something in the code that I've not seen yet.

megatron-uk

#237
I'm remapping to 8kb banks for all assets apart from the one originally located in bank 0x14, asset ID 0x83, which is ~10KByte in size, so spans two banks (16KB).

So, for example, I'll have assets in bank 0x49, then one in 0x49, then my 16kb bank starting at 0x4a, then the next 8kb bank is 0x4c. The asset table at 0x2939 is modified to point to the correct one - i.e. anything originally referencing 0x14 is modified to reference 0x4a. All offset pointers in the pointer table are set to 0x1, as there is only one asset in each bank now (in fact, the header of each asset table in each bank is as simple as <bank_id> 0x03 0x40... as it always only has one asset entry that immediately follows at offset +3).

The asset bank table used to look like this:
0002930: aa7a 6020 46c7 4cb0 c50e 0e0e 0e0e 0e0c  .z` F.L....
0002940: 0e0e 0000 0000 0000 0014 0a0a 0a0a 0a0c  ...........
0002950: 0c0c 0c0c 0c0c 0c0c 0c0c 0103 0507 090b  ...........
0002960: 170d 0f00 0000 0000 0000 8301 0305 0709  ...........
0002970: 0103 0507 090b 0d0f 1113 1511 1111 1111  ...........

It now looks like this:
0002930: aa7a 6020 46c7 4cb0 c541 4243 4445 4647  .z` F.L..AB
0002940: 4849 0000 0000 0000 004a 4c4d 4e4f 5051  HI.......JL
0002950: 5253 5455 5657 5859 5a5b 0101 0101 0101  RSTUVWXYZ[.
0002960: 0101 0100 0000 0000 0000 0101 0101 0101  ...........
0002970: 0101 0101 0101 0101 0101 0111 1111 1111  ...........

megatron-uk

#238
I could go to a 16kb pair of banks per asset scheme, though that would take me straight to a 1MB ROM, as there are 27 individual assets that need to go in the new banks, using 16kb for each that's 54 x 8kb, rounding up to 64 to make it 512KBytes.

Potentially, that might be relatively easy to try.

EDIT: Nope, using 2 banks per asset and keeping it aligned on even bank numbers didn't make a difference.

megatron-uk

Okay, some good news, some bad news.

The good news is that I've figured out what is causing the 'jump to other asset string' behaviour that I've been seeing. Here's that second NPC that you talk to, he's the one who expressed shock at your 'robot costume'. Remember it was showing this dialogue, in error:
IMG

Here's what he should be saying (and now does!):
IMG

The bad news come from the realisation that the dialogue box display codes now appear to be game-area dependent. So I had changed the dialogue box from his Japanese text:

<1a><22>よくできた ぬいぐるみだなお。<pause><1E> え?<pause><1E> ほんもの?<wait>

Where the control codes "1a" "22" generated a 25x1 text box in the middle of the screen.

To my desired english translation:
<1a><70>Man: This robot really\nlooks real!<pause><1E>\nEh?<pause><1E> It IS real!!!<wait>

Where "1a" "70" displayed a 26x3 text box at the top of the screen. Only in this case, it didn't, it caused the game to jump to another bank and load an asset from the ship-based dialogue (i.e. the bit about a lava planet).

I just tried change the dialogue box codes to "1a" "1e" (24x2 box, top centred), thus:

<1a><1e>Man: This robot really\nlooks real!<pause><1E>\nEh?<pause><1E> It IS real!!!<wait>

...and that works, as seen in the image above.

So, the bad news is that I'll need to go through each dialogue box display, in turn, and work out which ones actually work in the overworld, in town, in the ship, during cinemas, etc and change the english translation to suit. What a goddamn pain.

It isn't the problem affecting the savescreen, that seems to be something else. At least this solves one problem, though generates quite a bit of work to go back through all the asset data and check if I'm using dialogue box codes that don't work in that particular section (and bearing in mind I've not played through the bulk of the game, a lot of that I'm simply not going to know, yet).

megatron-uk

Right, so through some judicious testing of the control codes it seems that of the 44 unique dialogue box control combinations, only 20 actually work correctly in the overworld and in NPC dialogue.

[0x1a, 0x1a] through to [0x1a, 0x2e] work correctly, but from [0x1a, 0x3a] to [0x1a, 0x74] cause the symptoms as described earlier - jumping into other banks. There must be some code specifically doing this, I can't imagine it's just a coincidence.

Now that I know what causes it, I'll have to go back through all of the text converted so far and see where I'm using any of those broken control codes, then try and pack the text into one of the dialogue boxes made available by the lower range of control codes instead. :roll:

elmer

Quote from: megatron-uk on 11/27/2016, 12:24 PMThe good news is that I've figured out what is causing the 'jump to other asset string' behaviour that I've been seeing.
...
The bad news come from the realisation that the dialogue box display codes now appear to be game-area dependent. So I had changed the dialogue box from his Japanese text:
Nice sleuthing!  =D&gt;

Yep, it's not horribly uncommon to change the meaning of script/command codes/parameters in assembly language.

It's not a problem when you're original developer with the source code, but it's a huge PITA when you're trying to do a post-mortem translation like this.

Sorry to hear that you've hit this problem.


Quote from: megatron-uk on 11/27/2016, 01:17 PMNow that I know what causes it, I'll have to go back through all of the text converted so far and see where I'm using any of those broken control codes, then try and pack the text into one of the dialogue boxes made available by the lower range of control codes instead. :roll:
That's what makes translations so much fun to work on!  ](*,)

megatron-uk

Okay, all NPC text for the first world now in place again. All displaying correctly now, too. That's all 80 or so strings for 'Farworld' in English and showing as intended. There's only one place that I'm not sure what to do with - I think I mentioned it early in the translation; the SNES text has the president giving you information about where to find the next people to help you. This is not in the PCE, so I need to make a decision about whether to put that in, or leave it up to the player to go exploring.

Perhaps the decision was made when coding the later SNES release to make it a little easier on the player?

I'll go back to the ship menu and battle messages now. Since it's the same asset used throughout the game, if I get the bugs worked out now, then it should be fine for the rest of the game.

esteban

I am so happy to see the NPC text progress... things went from crap to crystal in a relatively brief period of time (I'm not suggesting it wasn't frustrating as hell, mind you).

:)

I'm just happy things are moving forward.
IMGIMG IMG  |  IMG  |  IMG IMG

megatron-uk

Got pretty much all of the battle text done now. Two little fragments left to translate, and some overflow/corruption to track down, but nothing major.

One thing I am trying to do is to slow down the display of the 'player attacks badguy', 'player causes 5pts damage'  type messages that flash up after the battle animations. They fly past incredibly fast and the normal <pause> and <slow> control codes are not obeyed during battle. I'll try and figure something out.

The SNES and PCE script differ again, here in the battle screen - the SNES has a heap of extra strings that the onboard compute flashes up when an enemy has a particularly strong shield ('makes your laser weaker', 'cools your heat attacks', etc), these are not present in the PCE. Though instead we get not one, but two messages from the ships cook about the quality of tonights dinner onboard the SS-Swordfish when we return from battle! There's always a silver lining!  :lol:

elmer

Quote from: megatron-uk on 11/27/2016, 05:06 PMThere's only one place that I'm not sure what to do with - I think I mentioned it early in the translation; the SNES text has the president giving you information about where to find the next people to help you. This is not in the PCE, so I need to make a decision about whether to put that in, or leave it up to the player to go exploring.

Perhaps the decision was made when coding the later SNES release to make it a little easier on the player?
If the alternative is having the player walk randomly around the map with no idea of what to do, then I'd definitely favor giving them some kind of hint ... but it doesn't have to be hand-holdingly blatant.


Quote from: megatron-uk on 11/28/2016, 12:15 PMThe SNES and PCE script differ again, here in the battle screen - the SNES has a heap of extra strings that the onboard compute flashes up when an enemy has a particularly strong shield ('makes your laser weaker', 'cools your heat attacks', etc), these are not present in the PCE. Though instead we get not one, but two messages from the ships cook about the quality of tonights dinner onboard the SS-Swordfish when we return from battle! There's always a silver lining!  :lol:
:wink: