Files
persona-script-editor/README.md
2026-07-17 01:04:47 +03:00

182 lines
5.0 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Persona Script Editor
A GUI tool for translating the PS1 game **Megami Ibunroku Persona** (真・女神転生ペルソナ / Revelations: Persona).
Parses dialogue scripts directly from a BIN/CUE disc image, provides JSON export/import for translators, and writes translations back into the image.
Built with Rust + Tauri. Runs on Windows. Minimal RAM usage (~6MB for script data, not the full 667MB image).
---
## Quick Start
1. Place `Persona_jap.tbl` (or any `.tbl` file) next to the exe
2. Run `persona-script-editor.exe`
3. **Open ISO** → select the `.bin` disc image (Redump Rev 1, ~699MB)
4. Four files appear: E0, E1, E2, E3 — all game dialogue (~12000 strings total)
5. Click a file → scene list → click a scene → strings
---
## Translation Workflow
### For the project lead
```
Open ISO → Export JSON → distribute to translators → Import JSON → Save ISO
```
### For translators
You receive a JSON file. Open it in any text editor (VS Code, Notepad++, etc).
Fill in the `translation` field for each string:
```json
{
"index": 0,
"original": "南条:やあ、[firstname]。[nl]今日もいい天気だな。[end]",
"translation": "Nanjo: Hey, [firstname].[nl]Nice weather today.[end]"
}
```
Rules:
- **Do not remove or modify** control codes: `[nl]`, `[clear]`, `[end]`, `[firstname]`, `[lastname]`, `[choice=N]`
- `[nl]` = line break (max ~20 characters per line)
- `[clear]` = clear text box (next "page")
- `[end]` = end of dialogue
- `[choice=N]` = choice menu
- Maximum **3 lines** between `[clear]` tags (PSX text box limitation)
---
## Control Codes
| Code | Meaning |
|------|---------|
| `[nl]` | New line |
| `[clear]` | Clear text box |
| `[end]` | End dialogue |
| `[wait=N]` | Pause for N frames |
| `[color=N]` | Set text color |
| `[firstname]` | Player's first name |
| `[lastname]` | Player's last name |
| `[nickname]` | Player's nickname |
| `[choice=N]` | Choice menu (ID=N) |
---
## Game File Structure
| File | Contents | Strings |
|------|----------|---------|
| ADV/E0.BIN | Dialogue (main story) | 3878 |
| ADV/E1.BIN | Dialogue (side scenes) | 2242 |
| ADV/E2.BIN | Dialogue (side scenes) | 4632 |
| ADV/E3.BIN | Dialogue (ending) | 1380 |
| **Total** | | **~12000** |
All other files (MES, BGM, BVB, EBG, SE, B/*) contain graphics, audio, or map data. No translatable text.
---
## Technical Details
### Disc Image Format
- MODE2/2352 (raw CD-ROM XA)
- Sector: 2352 bytes total, user data at offset 24, size 2048
- Game uses internal FSECT table (LBA 634) to locate files, not ISO9660 directory
### Container Format (E0E3)
```
[Pointer Table] uint16_le[] × (N+1), terminated by 0x0000
[Sub-files] aligned to 0x800 (2048) bytes
```
Each pointer value × 0x800 = byte offset of the sub-file within the container.
### Event Script Sub-file Format
```
[Header] 8 bytes: hdr_size(u16) + marker 0x8010(u16) + data(4 bytes)
[Data] Script bytecode + string pointer table + text blob
```
Key fields in the data section (offsets relative to data start):
- `data[52]` (uint16_le) = `ett` — start of text blob area
- `data[96]` (uint16_le) = `table_ptr` — start of string pointer table (0xFFFF = no strings)
String pointer entries follow the pattern: `FF 55 00 00 [ptr_lo] [ptr_hi] 10 80`
### Text Encoding
- `0x010x7F` — single-byte characters (kana in JP, can be remapped to Cyrillic/Latin via font)
- `0x80xx` — two-byte characters (kanji, punctuation). Mapped via `.tbl` file
- `0xFF xx` — control codes (see table above)
- `0xFF 0x01` — string terminator
### TBL File
Plain text mapping of byte codes to Unicode characters. Format: `XXYY=char` per line.
Example:
```
80A5=。
80CB=
80D0=
80D1=
80D5=、
```
The editor auto-loads any `.tbl` file found in the same directory as the executable.
---
## Memory Usage
The editor does **not** load the entire disc image into RAM. It reads sectors on demand via file seek. Only the parsed script containers (~6MB total) are kept in memory.
---
## Saving
When saving a translated ISO:
- If the rebuilt container fits in its original location → written in-place
- If the container grew (longer translations) → appended to end of image, FSECT table updated automatically
---
## Logs
Log file: `%LOCALAPPDATA%\com.persona.script-editor\logs\Persona Script Editor.log`
Logs are also output to:
- stdout (when launched from terminal)
- DevTools console (F12 inside the app window)
---
## Building from Source
```bash
cd persona-script-editor
npm install
npx tauri build
```
Requirements: Rust 1.70+, Node 18+, npm, Windows (MSVC toolchain).
Output:
- `src-tauri/target/release/persona-script-editor.exe` — portable exe
- `src-tauri/target/release/bundle/nsis/Persona Script Editor_0.1.0_x64-setup.exe` — installer
**Important:** Place any `.tbl` file (e.g. `Persona_jap.tbl`) in the same folder as the exe before running.
> **Note:** Do not use `cargo build --release` directly — it builds only the Rust backend without the frontend.
> Always use `npx tauri build` to get a working executable with the UI embedded.
---
## License
MIT