TheOpponent / st3-translation-notes

Notes for the translation of the Dreamcast game Sakura Taisen 3
The Unlicense
11 stars 1 forks source link

VMU tasks #11

Open TheOpponent opened 1 year ago

TheOpponent commented 1 year ago
TheOpponent commented 1 year ago

The game checks memory card types after the title screen. If the memory card in slot A-1 is not a VMU with a screen, the game displays a warning message but otherwise proceeds normally. During gameplay, at moments where the portable Cinematron would display a message, the VMU will beep and relay the message as scrolling text on the VMU screen, with the game showing a hint for the player to look at the screen. If a screen is not available, the message is reproduced as normal text in place of this hint.

Screenshots: https://user-images.githubusercontent.com/8432212/216801601-6bdbe7af-7363-418b-a3b5-ff096200a6ea.jpg https://user-images.githubusercontent.com/8432212/216801568-2eac69b8-573c-4546-b0c3-33992601bf36.jpg

TheOpponent commented 1 year ago

The game updates the VMU display very frequently, up to 30 Hz in some places to produce a shimmer effect in a logo graphic. Examining a RAM dump at the title screen where the game's logo is shown on the VMU screen reveals that the image data is stored as a 1bpp bitmap. According to the Shinobi library manual, bit 0 is off (white) and bit 1 is on (black). Because the data was stored in 1bpp format, it is using the low-level pdVmsLcdWrite1() function, which means each image rendered this way is 192 bytes in length.

CrystalTile preview of an animation of the Sakura Taisen 3 logo:

0010978

TheOpponent commented 1 year ago

VMU graphics loaded at the title screen can be found in several .BIN files in SYSLIST.AFS:

These files contain 1 or more screens of data, 48 x 32 in 1bpp format, 192 bytes each. They contain no headers or footers.

These files appear to be VMU executables and contain graphics that should be editable:

These graphics can be observed in CrystalTile 2 in solid 1bpp mode by setting an appropriate palette such as TLP, then setting the width and height to 48 x 32.

TheOpponent commented 1 year ago

A script has been written to convert PNG images into the 1bpp bitmap format used by low-level LCD screen update functions: https://github.com/TheOpponent/st3-translation-notes/blob/main/Scripts/write_lcd_data.py

TheOpponent commented 1 year ago

The scrolling Kinematron messages are stored as normal strings in the script files. They are delineated with the character ▼, and a fallback copy of the message is stored in the following string with formatting for the main text box. A string in 1ST_READ.BIN at 8c22106b is displayed on the TV screen while the Kinematron message is displayed on the VMU screen. A function at 8c12575c references this string, but the string itself appears to be hardcoded.

Additionally, the message scrolled on the VMU screen appears to use its own text rendering function, which uses the font sheet in SKFONT.CG, but with its own text width value.

TheOpponent commented 1 year ago

Changing the function for producing the Kinematron message is not viable with current hacking techniques. While it is possible to change various bytes set to 0x1a to change character width, searching for a byte that determines the total message length as the message is written to memory cannot be done since the message is formed instantaneously. Instead, we are using the same workaround for map labels: redefine now unused kanji tiles. The characters have no gaps between them, so tiles can be changed without hacking the LCD code for Kinematron messages.

The screen data for the Kinematron messages is formed in memory using the normal in-game font, which is converted to 1-bit pixel data and stored in a buffer that is scrolled across the screen until the player dismisses it. This function is separate from the other text functions for the main script and ignores all control codes, so using codes to manually set character width was not an option either.

To conserve font tiles, we are currently using a proportional English font that scales well without antialiasing. Our current in-game font, Kosugi Maru, is fixed-width and difficult to read at low font sizes without antialiasing.

TheOpponent commented 1 year ago

Three programs have been published to assist with LCD graphic editing tasks:

https://github.com/TheOpponent/st3-translation-notes/blob/main/Scripts/read_lc1.py https://github.com/TheOpponent/st3-translation-notes/blob/main/Scripts/write_lc1.py https://github.com/TheOpponent/st3-translation-notes/blob/main/Scripts/write_lcd_data.py

TheOpponent commented 1 year ago

The S3vm_ files in SYSLIST.AFS are the same executables that are uploaded to the VMU as minigames. They contain a font sheet at 0x4010 and include a complete English character set. The tiles are rotated 90 degrees counterclockwise and are 6x7 when rotated correctly. This allows for 2 rows of 30 pixels of text.

Strings begin at approximately 0x6354, preceded with eight 00 bytes and are terminated with FF. There is likely a table containing offsets for each string, as terminating strings prematurely causes the game to jump to the next line where a change in the on-screen character's appearance takes place.