The Analogue Turbo Duo clone shipped in time for Christmas 2023. Are you happy with yours ?? Find firmware updates here.
IMG
Main Menu
Menu

Show posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.

Show posts Menu

Messages - megatron-uk

#1
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:
#2
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.
#3
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:
#4
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).
#5
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.
#6
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  ...........
#7
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.
#8
I didn't realise the new TED had 4MB of RAM onboard! Wow! That makes the original look positively rubbish in comparison.

That absolutely tons of room for translations, extra code, graphics.... brilliant. I reckon I can make use of some of that in the future (have an idea for a couple of SCD translations next) ....

I think I have to get myself one. I'll justify it by passing on my TED 1 to the PCE, while the Duo gets the TED 2  :lol:
#9
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!
#10
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.
#11
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.
#12
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!
#13
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!
#14
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.
#15
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.  :)
#16
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!
#17
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.
#18
Just read over on Romhacking.net that the SRPG X-Serd has been translated to English:

https://www.romhacking.net/translations/2780/

That's another one to try out on your flash cards now!

X-SERD1.png X-SERD4.png
X-SERD3.png X-SERD2.png

IMG
#19
I propose a new name: Kitty Bobble  :D

Looks totally nuts  :lol: - great work!  =D&gt;
#20
Remember that all your code and data needs to fit in 8KB banks that the PCE maps in and out as needed.

Perhaps you have a function that is so large it is over the size of an 8KB bank?

One thing I tried previously was re-arranging the order of my functions, so that when assembled they fit in different banks. That might help? I don't know if the compiler and assembler is smart enough to do that by default?
#21
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!
#22
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.
#23
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.
#24
Yep, then running screaming away from it.  :lol:

It is easy to get something up and running, but if you do want to port anything or do something slightly approaching ANSI standard it's a big pain in the bum. One of the reasons I never got around to finishing the FAT filesystem driver for the Everdrive is the lack of struct support, so doing anything with the FAT table was a pain, calculating offset after offset for table entries... argh!

That and the lack of 'long' support. Yes, I know it is slow on a 8bit cpu, but my word, when you don't have 32bit integer support these days you do feel it!
#25
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:
#26
Looks like it could have been an interesting one.

Along the same lines, has anyone had much luck playing either of the Super Swarzschild games or translating the menu structures? They look like really well done space strategy games.
#27
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:
#28
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" : "",
},
#29
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.
#30
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.
#31
Looks like the images are not coming through. Must be a problem with my router.
#32
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.
#33
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!
#34
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:
#35
Just made a new commit to github with a Python based extractor tool (extractAssets.py) that outputs one data file per asset chunk. It saves to ./assets/raw by default.

Files are named as ASSETBANK.ASSETCHUNK.dat.

e.g.

0x14.0x83.dat

Now need to write something to load each data file, split the script into strings and then pass back through my translation table that I used earlier. Hopefully have something working for that tomorrow.

There are 26 script asset chunks, allocating a new 16KB bank for each would increase the size of the ROM by 420KB, which, although wasteful, would mean each block of text would have more than enough space to be fully expanded, without worrying whether each of the assets would fit back in to a single bank.

The main story script asset chunk will probably need the most space for expansion, but I had to make savings here and there in a lot of other places, so this would help with those sections, too.
#36
Since the asset pointed at by 0x83 is the story main script for the game, it should be possible to relocate that one asset to a new bank, to give me another 60% of space to expand it (from ~10KB of Japanese dialogue to 16KB of English to fill the new bank).

That's going to be a massive help.
#37
Argh, ignore my 0x79 asset chunk comments. It's transcription error - I wrote 0x288E4 instead of 0x2B8E4 as the physical ROM address.

That makes things simpler; just one script location (pointed to by 0x83) in that bank now. Albeit with 10 KBytes of text data....
#38
So to clarify, every single asset chunk in bank 0x0A, 0x0C and 0x0E is directly accessed by the offset pointers in the bank 0x01 table:

Asset bank load table
Quote0e 0e 0e 0e 0e 0e 0c 0e
0e 00 00 00 00 00 00 00
14 0a 0a 0a 0a 0a 0c 0c
0c 0c 0c 0c 0c 0c 0c 0c
0c
Asset index chunk offset table
Quote01 03 05 07 09 0b 17 0d
0f 00 00 00 00 00 00 00
83 01 03 05 07 09 01 03
05 07 09 0b 0d 0f 11 13
15
Each asset bank has a corresponding index offset in the second table. No asset index is without an entry, apart from asset bank 0x14, which only has one index offset: 0x83.

It looks like from index 0x83 (0x28085) until the end of the chunk 0x79 (0x2aa15) is one contiguous script chunk. This looks to be remarkably similar to my existing extractions, which have grabbed text in that region from 0x28086 up to 0x2a930.
#39
Right, so it looks like all of the assets in banks 0x0A, 0x0C and 0x0E are script. They also coincide with my extracted text regions, so that's great. I can use these new accurate locations to extract the sections in more detail.

Here are the sections so far:

Bank 0x0C
Bank: 0xc
---> Contains 12 asset pointers
---> Region 0x18000 - 0x1bfff
---> Starting asset chunk (0x1) located at: 0x18019
---> Finding next asset sequence
-----> 0x1: 0x18019 - 0x18462 [1097 bytes]
-----> 0x3: 0x18462 - 0x18c61 [2047 bytes]
-----> 0x5: 0x18c61 - 0x19147 [1254 bytes]
-----> 0x7: 0x19147 - 0x19927 [2016 bytes]
-----> 0x9: 0x19927 - 0x19c16 [751 bytes]
-----> 0xb: 0x19c16 - 0x1a34b [1845 bytes]
-----> 0xd: 0x1a34b - 0x1ae17 [2764 bytes]
-----> 0xf: 0x1ae17 - 0x1aea2 [139 bytes]
-----> 0x11: 0x1aea2 - 0x1b1d5 [819 bytes]
-----> 0x13: 0x1b1d5 - 0x1b5d8 [1027 bytes]
-----> 0x15: 0x1b5d8 - 0x1b8ce [758 bytes]
-----> 0x17: 0x1b8ce - 0x1bfff [1841 bytes]

Bank 0x0A
Bank: 0xa
---> Contains 5 asset pointers
---> Region 0x14000 - 0x17fff
---> Starting asset chunk (0x1) located at: 0x1400b
---> Finding next asset sequence
-----> 0x1: 0x1400b - 0x154fd [5362 bytes]
-----> 0x3: 0x154fd - 0x16a6f [5490 bytes]
-----> 0x9: 0x175c1 - 0x17fff [2622 bytes]
-----> 0x5: 0x16a6f - 0x16c29 [442 bytes]
-----> 0x7: 0x16c29 - 0x175c1 [2456 bytes]

Bank 0x0E
Bank: 0xe
---> Contains 8 asset pointers
---> Region 0x1c000 - 0x1ffff
---> Starting asset chunk (0x1) located at: 0x1c011
---> Finding next asset sequence
-----> 0x1: 0x1c011 - 0x1cb4c [2875 bytes]
-----> 0x3: 0x1cb4c - 0x1ceed [929 bytes]
-----> 0x5: 0x1ceed - 0x1d373 [1158 bytes]
-----> 0x7: 0x1d373 - 0x1d5b2 [575 bytes]
-----> 0x9: 0x1d5b2 - 0x1dc86 [1748 bytes]
-----> 0xb: 0x1dc86 - 0x1ebff [3961 bytes]
-----> 0xd: 0x1ebff - 0x1f0ec [1261 bytes]
-----> 0xf: 0x1f0ec - 0x1ffff [3859 bytes]


With bank 0x14 there only appear to be two script assets. Identified by asset index 0x79 and 0x83. Though only 0x83 is referenced by the main asset table in bank 0x01.

0x83: 0x28085 - 0x288e4 [2143 bytes]
0x79: 0x288e4 - 0x2aa15 [8497 bytes]

I've taken the end address of each chunk to be the start address of the next chunk in ram, so these are the maximum sizes of those asset chunks. You can see that 0x79 runs on from 0x83, so one thing I need to find out is how the script in that section is addressed, when asset 0x79 is not directly referenced in the main bank 0x01 offset pointer table, only 0x83 is for bank 0x14.
#40
IMG

I know why I'm confused.

The pointer index table is little endian. I was reading it as big endian.

I couldn't work out where you were getting the pointer $4085 from, since my last pointer was $4000. But of course it's not, and the second byte isn't a counter at all.

SO where I thought the 0x0A table (which is 0A 0B 40 FD 54 6F 6A 29 6C C1 75 00)...

0x0A (asset bank id)
0x0B (table pointer size)
40 FD (pointer)
54 6F (pointer)
... and so on.

it's actually (yes, you can slap me now):
0x0A (asset bank id)
40 0B (pointer)
54 FD (pointer)
... etc.

I'll go sit in the corner now.  :oops:
#41
I think I've got it, but I want to run through the pointer system a few times so that I'm clear. I think I've got where asset index $83 is coming from, and what it relates to, but want to be sure before asking more inane questions  #-o

I'll play around with a few examples this evening first.
#42
Okay, I've written up a summary of the asset banks so far.

==============================================

Master Bank $01, always loaded at 0xC000-0xDFFF

Table A, ROM offset 0x02939, type = Script Text Bank pointers
This is a table of which Text Bank to load at any point.

Start byte position = 10553

Data:
0e 0e 0e 0e 0e 0e 0c 0e
0e 00 00 00 00 00 00 00
14 0a 0a 0a 0a 0a 0c 0c
0c 0c 0c 0c 0c 0c 0c 0c
0c

There are 33 bank load addresses, many of which, as shown, are duplicates.

---

Table B, ROM offset 0x0295a, type = Script Offset pointers.
This is a table of offsets into the pointer tables at the start of each text bank.

Start byte position = 10586

Data:
01 03 05 07 09 0b 17 0d
0f 00 00 00 00 00 00 00
83 01 03 05 07 09 01 03
05 07 09 0b 0d 0f 11 13
15

There are 33 asset chunk pointer offset addresses, one for each of the bank load entries in Table A.

=============================================

The below text banks are always loaded at 0x4000-0x7FFF

=============================================

Text Bank $0A/$0B, ROM offset $14000-$17FFF
First byte = Bank number = 0x0A
Second byte = 0x0B = 11 = 10/2 = 5x 2-byte pointers

Pointer Data
-------------
0A 0B 40 FD 54 6F 6A 29
6C C1 75 00

Pointer Table
----------------
Position / Value
0x00 = 0A = Bank ID
0x01 = 0B = Table size
0x02 = 40 FD - 0x4000 + 0x14000 = 0x140FD
0x03 = 54 6F - 0x4000 + 0x14000 = 0x1546F
0x04 = 6A 29 - 0x4000 + 0x14000 = 0x16A29
0x05 = 6C C1 - 0x4000 + 0x14000 = 0x16CC1
0x06 = 75 00 - 0x4000 + 0x14000 = 0x17500

=============================================

Text Bank $0C/$0D, ROM offset $18000-$1BFFF
First byte = Bank number = 0x0C
Second byte = 0x19 = 25 = 24/2 = 12x 2-byte pointers

Pointer Data
-------------
0C 19 40 62 44 61 4C 47
51 27 59 16 5C 4B 63 17
6E A2 6E D5 71 DB 75 CE
78 00

Pointer Table
----------------
Position / Value
0x00 = 0C = Bank ID
0x01 = 19 = Table size
0x02 = 40 62 - 0x4000 + 0x18000 = 0x18062
0x03 = 44 61 - 0x4000 + 0x18000 = 0x18461
0x04 = 4C 47 - 0x4000 + 0x18000 = 0x18C47
0x05 = 51 27 - 0x4000 + 0x18000 = 0x19127
0x06 = 59 16 - 0x4000 + 0x18000 = 0x19916
0x07 = 5C 4B - 0x4000 + 0x18000 = 0x19C4B
0x08 = 63 17 - 0x4000 + 0x18000 = 0x1A317
0x09 = 6E A2 - 0x4000 + 0x18000 = 0x1AEA2
0x0A = 6E D5 - 0x4000 + 0x18000 = 0x1AED5
0x0B = 71 DB - 0x4000 + 0x18000 = 0x1B1DB
0x0C = 75 CE - 0x4000 + 0x18000 = 0x1B5CE
0x0D = 78 00 - 0x4000 + 0x18000 = 0x1B800

=============================================

Text Bank $0E/$0F, ROM offset $1C000-$1FFFF
First byte = Bank number = 0x0E
Second byte = 0x11 = 17 bytes = 16/2 = 8x 2-byte pointers

Pointer Data
-------------
0E 11 40 4C 4B ED 4E 73
53 B2 55 86 5C FF 6B EC
70 00

Pointer Table
----------------
Position / Value
0x01 = 0E = Bank ID
0x02 = 11 = Table size
0x03 = 40 4C - 0x4000 + 0x1C000 = 0x1C04C
0x04 = 4B ED - 0x4000 + 0x1C000 = 0x1CBED
0x05 = 4E 73 - 0x4000 + 0x1C000 = 0x1CE73
0x06 = 53 B2 - 0x4000 + 0x1C000 = 0x1D3B2
0x07 = 55 86 - 0x4000 + 0x1C000 = 0x1D586
0x08 = 5C FF - 0x4000 + 0x1C000 = 0x1DCFF
0x09 = 6B EC - 0x4000 + 0x1C000 = 0x1EBEC
0x0A = 70 00 - 0x4000 + 0x1C000 = 0x1F000

=============================================

Text Bank $14/$15, ROM offset $28000-$2BFFF
First byte = Bank number = 0x14
Second byte = 0x93 = 147 bytes = 146/2 = 73x 2-byte pointers <- INCORRECT, only 66 pointers in this table.

Pointer Data
-------------
14 93 6D 95 6D A4 6D 36
6E 65 6E B7 6E 95 6D 0E
6F 95 6D 3D 6F 5E 70 95
6D 84 70 95 6D 93 6D 45
71 71 71 02 72 37 72 B2
72 95 6D 0E 73 DF 73 95
6D 20 74 81 74 AA 74 BD
74 D4 74 93 6D 93 6D 42
75 95 6D 74 75 B4 75 95
6D F7 75 49 76 95 6D 6F
76 F4 76 B4 77 CF 77 CF
77 95 6D 93 6D 93 6D 93
6D 93 6D 93 6D 93 6D 93
6D 93 6D 93 6D 93 6D DA
77 95 6D FA 77 6C 78 C1
78 E4 78 0C 79 93 6D 3D
79 15 6A 85 40 00

Pointer Table
----------------
Position / Value
0x01 = 14 = Bank ID
0x02 = 93 = Table size <- INCORRECT

TODO: The table size byte (0x93 == 147) doesn't appear to correlate to the actual number of entries (133 - 1 / 2 = 66) in the table for bank 0x0E, as there are not 73 entries in the table.

One problem I've found is that the second byte == pointer table size assumption doesn't hold true for bank 0x14/0x15 - it should have a 147 byte pointer table == 76 pointers, but it only appears to have 66 pointers if we assume they all have to be within 0x4000-0x7FFF. Something odd happening with that one.
#43
To clarify the number of pointers at the start of an asset bank:

Second byte = 0x19 = 25 = 24/2 = 12x 2-byte pointers

I think that's correct.
#44
Okay, I think I can answer the first question myself now, having looked at one of the asset banks in more detail.

Here's the start of 0x0C bank:

ROM position 0x18000-0x1BFFF

0C 19 40 62 44 61 4C 47 51 27 59 16 5C 4B 63 17 6E A2 6E D5 71 DB 75 CE 78 00 .....

So, if I follow your advice, the first byte, 0x0C is the text bank number. Then there is a single byte 0x19 which is 25 in decimal. Count 25 bytes, take off 1 for the 'size' and then that's the number of pointers in the table. That gives the following:

Bank: 0x0C
Size: 0x19
Pointers: 0x4062, 0x4461, 0x4C47, 0x5127, 0x5916, 0x5C4B, 0x6317, 0x6EA2, 0x6ED5, 0x71DB, 0x75CE, 0x7800

That seems to work for the other asset banks, too, with asset bank 0x14 the biggest, with a 147 byte table.

So, (now the gears are turning in my mind...) does that mean that when bank 0x0E is loaded from the first entry in the main bank 0x01, it jumps to pointer 1 (offset 0x01 from the offset table) in the table? Likewise, the last load entry for table 0x0C jumps to position 0x15 in the header table?

Have I got that right?

I guess that once it jumps to pointer position 0x15 (which will point to a block of text at 0x5FFF, say), it will then follow the logic from before, of looping over the script fragments in that block at 0x5FFF, skipping end-of-string bytes until it finds the 93rd one (for example), then displays it?
#45
That does indeed explain why some of the expanded text seems to have broken other, unrelated parts of the game.

I think I've got my head around most of what you've explained (and thank you very much for taking the time to do so!). Those 4 text banks you've identified overlap with the text sections I have extracted and am injecting back in, so that makes sense why the bulk of what I'm doing works, but also why it starts to go awry later one.

I have a couple of clarifications though:

- In the 16kb text block 'banks' (0x0a/0x0b, 0x14/0x15 etc), In the table of 2-byte asset pointers immediately following the text bank number, how do I know how many of those such pointers there are before the assets begin?

- In the main bank 0x01, in the second table, what are those asset pointer offsets doing? I can see that when bank 0x14 is loaded for example, the corresponding offset is 0x83. But what does that actually result in?

Many thanks for the information so far, I think this will be an incredible step forward. I was at the point of contemplating going back to fixed-length string insertions, which, while it would have worked, would have resulted in some awful dialogue compared to the original Japanese.
#46
The work on cleaning up the menu and UI elements is fantastic. They look so much better than the original images posted several pages back. Top work!  =D&gt;
#47
Hello, me again :)

So, I've decided to have a look at Cyber Knight again, after a break of over 2 years. Now's the time to do it, as things are probably going to change quite dramatically in my life in the next 6 months or so and I imagine I'll not have any spare time for the next ... ooh, 18 years or more!

So, where I got to with the translation was a point where the English text simply won't fit in to the space available. I had to start overflowing in to areas of the ROM that appear to be blank, although this gave me some extra space for NPC text for the first world, it broke the scrolling intro and I got random rubbish after finishing the first world, meaning I couldn't progress.

I really need the assistance of someone with more PCE programming knowledge who can help by either changing the text routines to point to blocks outside the main code section, or expand the ROM size, and, again move the text their. There just isn't the space available to replace the bulk of the text without overflowing in to the code sections.

Just as a reminder, Cyber Knight uses a fairly crude text block system, which makes it relatively easy to insert: the text is stored in several positions throughout the ROM, interspersed by code and graphics data. The text strings simply run on from each other and are seperated by a given byte sequence, the text display routine just counts over these text blocks until the right number of skipped sequences have been counted, then displays the next sequence. It makes it easy to modify the text (and its uncompressed, which is a big bonus for me). But expanding beyond the availabvle space, or moving it altogether is out of my league.

So, here's a request for help - would anyone be willing to assist in this particular part of the translation, i.e. changing the text routine, and/or expanding the ROM to include enough space to store the english text?

It's a shame for more of us not to get to play it, it really is a great little hucard rpg/strategy game.
#48
Sorry folks, real life has gotten in the way. I haven't had the time to touch this for probably a year now - a promotion at work to managing a team (and all the paperwork that comes with!) and more responsibilities at home mean I just don't have the time to devote to it.
#49
Hey all,

I've just spent a few hours working on the Everdrive-fat libraries over the past couple of days (where has the time gone???).

I've refactored a few things as well as added some missing 32bit math functions I needed (subtraction, for one). It should be easier to follow now.

I too had a problem using the later versions of huc and pceas, so I've gone back to the 3.21 release. A shame, as the new version with struct support would have made things a lot more compact (all the free fat drivers out there are ansi-c and use structs extensively).

Anyway, I'm now working on the get-next-cluster and get-next-sector code, so reading the entirety of a file from the SD card should not be far off.

Everything is on github, as usual: https://github.com/megatron-uk/everdrive-fat
#50
I've done a little more - I have some changes that take the translation up to the end of the first world, but these are not committed to GIt yet. I haven't made as much progress as I would have liked as I'm constantly hitting free-space issues in the script.... there is some free space in most text segments, but it seems random whether they can be used or not (there's no lookup table as such - each string is simply delimited from the next one and the print routines loop over the delimiters until they get to the correct string).

In terms of the error you're getting, I think you must be using Python3 - the 'print' call changed from Python1/Python2, which used the directive:
print "STRING"

to be a proper function called like this in Python3:
print("STRING")

Fortunately the latter format is backwards compatible with Python2 - so I could go back through the code and change it and it would be compatible with all Python versions.