Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 40 additions & 0 deletions docs/PC.md
Original file line number Diff line number Diff line change
Expand Up @@ -774,6 +774,46 @@ retail's 0x136A7-byte image. `sce/sifdev.cpp` implements `sceOpen`,
device prefix stripped (the debug dump `edit.cpp` writes to `host0:`), and
`WriteFile` writes there too.

## Game text

`port/src/gametext.cpp` writes the port's own text in the game's message
font, so menus the port adds can match the game's. A message is an s16 code
per character ending in `MES_CODE_END` (-0xFF); a space is
`MES_CODE_SPACE` (-0xFE) and a line break `MES_CODE_NEWLINE` (-0x100). The
PAL font draws only the external characters from -0x300: -0x300 to -0x2E0
are the pad buttons and icons; -0x2DF to -0x288 are the 88 cells of
`gaiji.img`'s letter grid in order (`A`-`Z`, `a`-`z`,
`'="!?#&+-*/%()@|<>{}[]:,.$` and `0`-`9`); -0x287 to -0x254 are `œ ¡ ¿ ß Œ
Ç ç` and the letters `DrawGaijiFont` draws an accent over (`ÀÁÂÄÈÉÊËÌÍÎÏÑ
ÒÓÔÖÙÚÛÜàáâäèéêëìíîïñòóôöùúûü`). -0x263 to -0x261, -0x253 and -0x252
draw a bare `?`. There is no `;`, `_`, `~`, `^`, backquote or backslash.
The table was read off the `gaiji.img` of every `meswin/mes_tex_N.pak` (all
seven draw these characters in the same cells; only the pixels differ) and
checked by decoding every `.mes` on the disc: each language uses only
characters in it, and its own accents only.

`GameTextEncode` turns UTF-8 into codes. Curly quotes and dashes become the
font's own; any other character the font lacks, and any byte that is not
UTF-8, becomes `?` and is counted. `{N}` writes code N as it is, for control
codes and icons, and `{{` a `{`; `GameTextDecode` writes the same form, so
any message reads back and encodes to the same codes. `GameTextFile` lays
texts out as a message file for `ClsMes::SetBuff`. `GameText` is one piece of
text drawn as the menus draw their help line (`InitMenuMesSet`'s
`CommonMenuMes2`: the menu font, white with a black edge, shown whole): `Set`
the text, `SetColour` a `FontColor`, then `Draw(x, y, alpha)` from a menu's
draw function; `Width` gives its width for aligning a value.

Both have retail's fixed sizes. A window lays out at most `MES_WIN_LINE_MAX`
(720) characters, counting the end and what a `{N}` name, value or system
message code expands to; retail's `SetMesWinTbl` writes on past the table, so
the port's (`port/src/clsmes.cpp`) takes no more, and `GameText::Set` gives back
-1, draws nothing and has a width of 0 for a text that did not fit. A line past
the window's ten `line_pos` entries draws in the block layout, as a line
without one does. A message file is s16 throughout: an id is -0x8000 to
0x7FFF. Every message must start within 0x7FFF codes of `&buff[1 + count]`;
the last message by id may extend beyond that range. `GameTextFile::Set`
gives back -1 and leaves the file as it was where either would not hold.

## Arenas

`CDataAlloc2<1>::Alloc/Alloc64/Align64` and the carving in
Expand Down
55 changes: 54 additions & 1 deletion port/src/clsmes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

#include <array>
#include <cmath>
#include <iterator>
#include <vector>

#include "draw2d_port.hpp"
Expand Down Expand Up @@ -457,6 +458,56 @@ PC_OVERRIDE void ClsMes::MakeFukidashi(sceVif1Packet *packet) {
services.set_alpha(nullptr);
}

// Retail's, but a full table takes no more: past MES_WIN_LINE_MAX laid-out characters retail writes
// on over the fields that follow it. MakeMesWinTbl then lays out no MES_CODE_END, which tells a
// caller the text did not fit.
PC_OVERRIDE int ClsMes::SetMesWinTbl(int code, int mode, short x, short y) {
if (code >= -0x200 && code <= -0x101) {
if (this->win_line_num > 0) {
this->win_line[this->win_line_num - 1].space += code + 0x200;
}

return 0;
}

if (code >= -0x400 && code <= -0x301) {
if (code + 0x400 == 0) {
this->clut_now = this->clut_default;
} else if (code == -0x301) {
this->clut_now = 0xFF;
} else {
this->clut_now = code + 0x401;
}

return 0;
}

if (code >= -0xA00 && code <= -0x901) {
this->fukidashi_shape = code + 0xA00;
return 0;
}

if (this->win_line_num >= MES_WIN_LINE_MAX) {
return 0;
}

if (mode == 1) {
this->win_line[this->win_line_num].code = code + 0x1000;
this->win_line[this->win_line_num].x = x;
this->win_line[this->win_line_num].y = y;
this->win_line[this->win_line_num].clut = this->clut_now;
this->win_line_num++;
} else {
this->win_line[this->win_line_num].code = code;
this->win_line[this->win_line_num].x = x;
this->win_line[this->win_line_num].y = y;
this->win_line[this->win_line_num].clut = this->clut_now;
this->win_line_num++;
}

return 1;
}

PC_OVERRIDE void ClsMes::DrawMesWin() {
CTexture *texture;
int offset_x;
Expand Down Expand Up @@ -599,7 +650,9 @@ PC_OVERRIDE void ClsMes::DrawMesWin() {

int row = this->win_line[index].y / this->char_height;

if (this->line_pos[row].x < 0 || this->line_pos[row].y < 0) {
// A line past the last line_pos entry takes the block layout, as one with no entry does.
if (row >= static_cast<int>(std::size(this->line_pos)) || this->line_pos[row].x < 0 ||
this->line_pos[row].y < 0) {
int line_x = this->win_line[index].x + this->text_x;
int line_y = this->win_line[index].y + this->text_y;
int screen_x = offset_x + (line_x + dx);
Expand Down
Loading
Loading