Repository navigation
Initialization file
Initialize the game system, allowing the developer to modify generic parameters that are not specific to each game release. An example would be the game's resolution, and the position of the message window.
| Version number | Name of file | Comments |
|---|---|---|
| 1 | system.ini | Introduced in Princess Knight☆Catue -Ochita Ryuuki Hime- |
| 2 | system.dat | system.ini is also present, but is unused |
The file is structured in 4 main parts, according to the following IDA decompilation:
ReadSystemIniFile
LengthFirstEncryptedString = 0;
PendingPreviousBytesToRead_LengthFirstString = 4;// indicate that the game wants to read the first 4 bytes of the file
do
{
--PendingPreviousBytesToRead_LengthFirstString;
LengthFirstEncryptedString = fgetc(Stream) + 10 * LengthFirstEncryptedString - 48;
}
while ( PendingPreviousBytesToRead_LengthFirstString );
if ( LengthFirstEncryptedString > 0 )
{
do
CatalogNumber[PendingPreviousBytesToRead_LengthFirstString++] = fgetc(Stream) ^ 0xD1;
while ( PendingPreviousBytesToRead_LengthFirstString < LengthFirstEncryptedString );
}
LengthSecondEncryptedString = 0;
CatalogNumber[PendingPreviousBytesToRead_LengthFirstString] = 0;
PendingPreviousBytesToRead_LengthSecondString = 4;
do
{
--PendingPreviousBytesToRead_LengthSecondString;
LengthSecondEncryptedString = fgetc(Stream) + 10 * LengthSecondEncryptedString - 48;
}
while ( PendingPreviousBytesToRead_LengthSecondString );
if ( LengthSecondEncryptedString > 0 )
{
do
Game_Title[PendingPreviousBytesToRead_LengthSecondString++] = fgetc(Stream) ^ 0xD1;
while ( PendingPreviousBytesToRead_LengthSecondString < LengthSecondEncryptedString );
}
v10 = Stream;
Game_Title[PendingPreviousBytesToRead_LengthSecondString] = 0;
GameResolution = fgetc(v10);
if ( GameResolution )
{
if ( GameResolution == 1 )
{
Game_Width_1 = 800;
Game_Height_1 = 600;
}
else if ( GameResolution == 2 )
{
Game_Width_1 = 1024;
Game_Height_1 = 768;
}
}
else
{
Game_Width_1 = 640;
Game_Height_1 = 480;
}
Game_Width = Game_Width_1;
Game_Height = Game_Height_1;
NumberOfVoiceChannels = fgetc(Stream) - 48;
for ( i = 0; i < 48; ++i )
{
FirstVoiceCharacterName[i] = fgetc(Stream);
v8 = fgetc(Stream);
v9 = Stream;
SecondVoiceCharacterName[i] = v8;
ThirdVoiceCharacterName[i] = fgetc(v9);
}
strcpy_s(WindowName, 0x64u, Game_Title);- Length: 4 bytes
- Type of value: unsigned integer
- Purpose: indicates the length of the catalog number string. To obtain the actual value, one can take two approaches.
Let's use the value 30 30 31 32 as an example:
Convert the value to an ASCII string.
30 30 31 32 becomes 0012. If we trim the initial zeros, we get 12.
Do the following operation 4 times, and making sure that LengthFirstEncryptedString and IterationNumber are 0 during the first iteration:
LengthFirstEncryptedString = CatalogNumberLength[IterationNumber] + 10 * LengthFirstEncryptedString - 48
Also, after each iteration, remember to increase by 1 the value of IterationNumber.
After doing the 4 loops, 30 30 31 32 becomes the number 12.
- Length: Catalog number length bytes
- Type of value: string
-
Purpose: it does not seem to be used, but its value is the official's catalog number for that product (if it's the digital version that also gets included, like they do in the game's executable name). To decode each of the bytes successfully, one must XOR each byte by
0xD1. From what it seems, it's not exactly the catalog number but rather, the executable's name. That can be inferred based on what the earlier games did with this variable.
- Length: 4 bytes
- Type of value: unsigned integer
- Purpose: indicates the length of the window title string. To calculate its exact value, one must follow the steps specified in the catalog number length section.
- Length: Window title length bytes
- Type of value: string
-
Purpose: the title for the game's window. To decode each of the bytes successfully, one must XOR each byte by
0xD1.
- Length: Window title length bytes
- Type of value: unsigned byte
- Purpose: the size of the game's window. Sadly due to how the engine assigns memory to each process, modifying said value causes adverse situations.
| Value | Resolution |
|---|---|
| 1 | 800x600 |
| 2 | 1024x768 |
| Anything else | 640x480 |
- Length: 1 byte
- Type of value: unsigned byte
- Purpose: probably a value used for an unavailable debug mode. The idea is to allow the developer from a toolbar to activate and deactivate specific sound channels. From the get-go, the BGM and SE channels are already typed out, but for the channels specific to each characters need the names of said characters to create the labels for those buttons. To calculate its exact value, one must follow the steps specified in the catalog number length section.
- Length: 144 bytes
- Type of value: string
- Purpose: each of the character name for each voice channel. Even though the previous variable does state how many bytes one should read, that never happens, and the game assumes that the 3 slots are occupied. The names are interleaved between themselves.
For example, if we have this array (the remaining bytes that follow are all 0x00):
83 83 00 4A 4A 00 83 83 00 60 60 00 83 83 00 85 85 00 83 83 00 41 41 00
So, in this case, each of the character names would be:
- 1st character: 83 4A 83 60 83 85 83 41 which equals to カチュア.
- 2nd character: 83 4A 83 60 83 85 83 41 which equals to カチュア.
- 3rd character: 00 00 00 00 00 00 00 00 which equals to an empty string.
The file is divided into three parts, according to to the following IDA decompilation:
WinMain
wsprintfA(FileName, "%s\\system.dat", "");
SystemDatFileHandler = CreateFileA(FileName, 0x80000000, 1u, 0, 3u, 0x80u, 0);
if ( SystemDatFileHandler == (HANDLE)-1 )
{
MessageBoxA(0, &FailureReadInitializationFile, Default, 0);
return 0;
}
ReadFile(SystemDatFileHandler, &GameIdentifier, 0x2194u, &NumberOfBytesRead, 0);
ReadFile(SystemDatFileHandler, DialogBox_Message_BackgroundFill_Enabled, 0x37F0u, &NumberOfBytesRead, 0);
ReadFile(SystemDatFileHandler, ChoiceBox_Text_Alignment, 0x6A90u, &NumberOfBytesRead, 0);
CloseHandle(SystemDatFileHandler);So, we can see that file size of system.dat is hardcoded, and its always 0x2194 + 0x37F0 + 0x6A90 = 0xC414 bytes, or in decimal, 50196 bytes.
- Length: 4 bytes
- Type of value: time_t
- Purpose: the general save file and save states can be interchanged between games, because they only store flags values, so in order to avoid the game from loading saves generated from other games, they include this value in the header in order to let the game know that they are in theory valid save files.
- Length: 4 bytes
- Type of value: unsigned int
- Purpose: unused. Maybe it could be used at a later date for setting up demo versions of the game, but at this point in time, they have never created any.
- Length: 1 byte
- Type of value: unsigned byte
- Purpose: it is meant to be used for really old systems, in case that they need the game to be executed in exclusive fullscreen mode.
| Value | Outcome |
|---|---|
| 0 | Disabled |
| 1 | Enabled |
- Length: 1 byte
- Type of value: unsigned byte
- Purpose: when clicking the game icon in the top bar, a lot of options will show up, like disabling DirectX, and the speed text. If enabled, the game will load the English version of those options, and some MessageBox calls will also have their message translated to English. It is important to note that all debug menus won't be translated to English.
| Value | Locale language |
|---|---|
| 0 | Japanese |
| 1 | English |
- Length: 260 bytes
- Type of value: string
- Purpose: on all MessageBox windows and in the main window title, this is what it will appear as the game's name. The game will consider the first null byte to be the end of the string.
- Length: 260 bytes
- Type of value: unsigned byte
- Purpose: used for decryption purposes, primarily for decrypting the .dat files, but also is used for getting the actual SDT key during runtime.
- Length: 2 bytes
- Type of value: unsigned short
- Purpose: indicates the width of the game's window.
- Length: 2 bytes
- Type of value: unsigned short
- Purpose: indicates the height of the game's window.
- Length: 2 bytes
- Length: 4 bytes
- Type of value: signed int
-
Purpose: indicates the amount of
DIflag slots will be created on boot.
- Length: 4 bytes
- Type of value: signed int
-
Purpose: indicates the amount of
DGflag slots will be created on boot.
- Length: 4 bytes
- Type of value: signed int
-
Purpose: indicates the amount of
DTflag slots will be created on boot.
- Length: 4 bytes
- Type of value: signed int
-
Purpose: indicates the amount of
SIflag slots will be created on boot.
- Length: 4 bytes
- Type of value: signed int
-
Purpose: indicates the amount of
SGflag slot will be created on boot.
- Length: 4 bytes
- Type of value: signed int
-
Purpose: indicates the amount of
STflag slots will be created on boot.
- Length: 4 bytes
- Type of value: signed int
-
Purpose: indicates the amount of
objslots will be created on boot.
- Length: 4 bytes
- Type of value: signed int
-
Purpose: indicates the amount of
MSKslots will be created on boot.
- Length: 4 bytes
- Type of value: signed int
-
Purpose: indicates the amount of
CGBslots will be created on boot.
- Length: 4 bytes
- Type of value: signed int
-
Purpose: indicates the amount of
Buttonslots will be created on boot.
- Length: 4 bytes
- Type of value: signed int
-
Purpose: indicates the amount of
Boxslots will be created on boot.
- Length: 4 bytes
- Type of value: signed int
- Purpose: indicates the amount of messages the game will store at the same time. A message in this case indicates any piece of dialog said during the story, and if the limit is exceeded, the oldest message in the log will disappear to make space for the latest one, which will be the one displayed outside the message log window.
- Length: 4 bytes
- Type of value: signed int
- Purpose: indicates the ID that will be used for the messages window, which is necessary for the in-game configuration of configuring the its opacity and color.
In this image, the RECT that has the image of the message window is the one that will be colored and its opacity changed.
- Length: 4 bytes
- Type of value: signed int
- Purpose: indicates the biggest ID for any obj that will be accepted on boot. This seems to be used because some images, like the one used to change the game from windowed to fullscreen mode can have a value higher than the one accepted here, but at no point this image gets loaded on boot.
- Length: 260 bytes
- Type of value: string
- Purpose: the game uses this value to know what's the folder name (or file if compressed) to store the .sdt files. The game will consider the first null byte to be the end of the string.
- Length: 260 bytes
- Type of value: string
- Purpose: the game uses this value to know what's the folder name (or file if compressed) to store the .mg2 files. The game will consider the first null byte to be the end of the string.
- Length: 260 bytes
- Type of value: string
- Purpose: the game uses this value to know what's the folder name (or file if compressed) to store the .mal files. The game will consider the first null byte to be the end of the string.
- Length: 260 bytes
- Type of value: string
- Purpose: the game uses this value to know what's the folder name (or file if compressed) to store the BGM files. The game will consider the first null byte to be the end of the string.
- Length: 260 bytes
- Type of value: string
- Purpose: the game uses this value to know what's the folder name (or file if compressed) to store the voice files. The game will consider the first null byte to be the end of the string.
- Length: 260 bytes
- Type of value: string
- Purpose: the game uses this value to know what's the folder name (or file if compressed) to store the sound effect files. The game will consider the first null byte to be the end of the string.
- Length: 260 bytes
- Type of value: string
- Purpose: the game uses this value to know what's the folder name (or file if compressed) to store the .am2 files. The game will consider the first null byte to be the end of the string.
- Length: 260 bytes
- Type of value: string
- Purpose: it is unused, but it would fulfill the same role as the other folder names. The game will consider the first null byte to be the end of the string.
- Length: 260 bytes
- Type of value: string
- Purpose: the game uses this value to know what's the folder name to store the save files. The game will consider the first null byte to be the end of the string.
- Length: 260 bytes
- Type of value: string
- Purpose: the game uses this value to know what's the file name to store the configuration and general progress of the game. The game will consider the first null byte to be the end of the string.
- Length: 1 byte
- Type of value: unsigned byte
- Purpose: when closing the game, the game can either offer to show a standard MessageBox window to ask the user for confirmation to close the game, or show the custom image the game uses to ask the user for confirmation.
| Value | Outcome |
|---|---|
| 1 | MessageBox |
| Anything else | Official window |
- Length: 1 byte
- Length: 2 bytes
- Type of value: unsigned short
-
Purpose: when closing the game, if Close game with MessageBox is not set to 1, when closing the game it needs to know to what scene it should go into. For example, if the file that contains the exit screen is
seen0010.sdt, the value that should be set in system.dat is10.
- Length: 260 bytes
- Type of value: string
-
Purpose: following the explanation in Close game
Seennumber, the game also needs to know the name of the label to jump to from the .sdt file in order to know exactly what to show to the user. The game will consider the first null byte to be the end of the string.
- Length: 4 bytes
- Type of value: unsigned int
-
Purpose: the explanation from Close game
Seennumber applies here too, but here it's for the game knowing what to do when the user decides to make the game be full screen (when pressing the SCREEN button).
- Length: 260 bytes
- Type of value: string
-
Purpose: the explanation from Close game
Jumplabel applies here too, but here it's for the game knowing what to do when the user decides to make the game be full screen (when pressing the SCREEN button). The game will consider the first null byte to be the end of the string.
- Length: 4 bytes
- Type of value: unsigned int
-
Purpose: the explanation from Activate full screen mode
Seennumber applies here too, but here it's for the game knowing what to do when the user decides to make the game be in a window (when pressing the SCREEN button).
- Length: 260 bytes
- Type of value: string
-
Purpose: the explanation from Activate full screen mode
Jumplabel applies here too, but here it's for the game knowing what to do when the user decides to make the game be in a window (when pressing the SCREEN button). The game will consider the first null byte to be the end of the string.
- Length: 260 bytes
- Type of value: string
- Purpose: for all text drawn in-game, the game needs to know the name of the font to be used. The game will consider the first null byte to be the end of the string.
- Length: 28 bytes * 50 fonts = 1400 bytes
- Type of value: signed int
- Purpose: for all text drawn in-game, the game creates 50 slots, so that different types of fonts are allowed.
- Length: 4 bytes
- Type of value: signed int
- Purpose: for the current font slot, indicate the height of said font.
- Length: 4 bytes
- Type of value: signed int
- Purpose: for the current font slot, indicate the width of said font.
- Length: 4 bytes
- Type of value: signed int
- Purpose: for the current font slot, indicate the weight of said font.
- Length: 4 bytes
- Type of value: signed int
- Purpose: for the current font slot, indicate the distance in the X-axis from the drop shadow to the actual text.
- Length: 4 bytes
- Type of value: signed int
- Purpose: for the current font slot, indicate the distance in the Y-axis from the drop shadow to the actual text.
- Length: 4 bytes
- Type of value: signed bytes
- Purpose: for the current font slot, indicate the color that the drop shadow will have. It assigns 1 byte per color.
- Length: 4 bytes
- Length: 50 names * 50 bytes = 2500 bytes
- Type of value: string
- Purpose: when a character is speaking, one can assign a custom color to the text that holds its name. This part contains the name of the character that will be assigned to its corresponding RGB values assigned later on. The game will consider the first null byte to be the end of the string.
- Length: 50 colors * 3 bytes = 150 bytes
- Type of value: signed bytes
- Purpose: following the explanation given in Message window (Character name part) custom color - Character name, this holds the RGB values assigned for each slot.
- Length: 3 bytes
- Type of value: signed bytes
- Purpose: following the explanation given in Message window (Character name part) custom color - Character name, this holds the RGB values for the characters that do not have any custom color assigned to them.
- Length: 1 byte
- Type of value: signed byte
- Purpose: following the explanation given in Message window (Character name part) custom color - Character name, this basically controls the status of that function.
| Value | Status |
|---|---|
| 0 | Disabled |
| 1 | Enabled |
- Length: 3 bytes
- Type of value: signed bytes
- Purpose: like with Character name part: default color, but in this case this applies for the text that holds the current message.
The game does allow to create a RECT that is linked to specific objects within the game, like the Message window and Choice boxes. Why they were decided to be put in there is not known, since they go completely unused. My guess would be that instead of loading actual images for those two objects, one could make them be 1 solid color, reducing the RAM consumption, although it seems kinda pointless nowadays.
- Length: 3 bytes
- Type of value: signed bytes
- Purpose: indicates the color in RGB that will have all of the background fill objects.
- Length: 1 byte
- Type of value: signed byte
- Purpose: indicates the level of opacity that will have all of the background fill objects.
- Length: 1 byte
- Type of value: signed byte
- Purpose: none, it only gets copied onto the main save file when closing the game.
- Length: 1 byte
- Type of value: signed byte
- Purpose: none, it only gets copied onto the main save file when closing the game.
- Length: 1 byte
- Length: 2 bytes
- Type of value: signed bytes
- Purpose: none, it only gets copied onto the main save file when closing the game.
- Length: 2 bytes
- Type of value: signed short
- Purpose: following the explanation given in Fonts, this indicates what font type to use for the dialogue text.
- Length: 2 bytes
- Type of value: unsigned short
- Purpose: while not fully understood, it seems that the engine expects to be given the order of layers for each element in screen, the smaller the number being even further behind the other objects on screen. In this case, we have the Surface created to accommodate the entire Message window.
- Length: 2 bytes
- Type of value: unsigned short
- Purpose: following the explanation from RECT order: surface for the image, but in this case applied to the image for the Message window itself.
- Length: 2 bytes
- Type of value: unsigned short
- Purpose: following the explanation from RECT order: surface for the image, but in this case applied to the surface that holds the text for the current message.
- Length: 2 bytes
- Type of value: unsigned short
- Purpose: following the explanation from RECT order: surface for the image, but in this case applied to the surface that holds the text for the current character's name.
- Length: 2 bytes
- Type of value: unsigned short
- Purpose: following the explanation from RECT order: surface for the image, but in this case applied to the current message text.
- Length: 2 bytes
- Type of value: unsigned short
- Purpose: following the explanation from RECT order: surface for the image, but in this case applied to the current character's name text.
These boxes are the ones included inside the game for selecting a choice, or a different story branch to put in other words (each choice box has 4 obj assigned to them).
- Length: 2 bytes
- Type of value: unsigned short
-
Purpose: the game needs to know what is going to be the
objID assigned for all of the choice boxes, so it needs to know the first slot number.
- Length: 2 bytes
- Type of value: unsigned short
-
Purpose: like with Choice box - First
objID, but in this case for the lastobjID. This lets the game know how many slots in total needs to assign for the choice boxes, since this determines the last ID reserved for choice boxes.
The game delegates all sound functions to a custom DLL called Ayame (apparently is also used on some games by other companies too), which is dropped on the %TEMP% folder at runtime.
- Length: 2 bytes
- Type of value: unsigned short
- Purpose: the total amount of instances that Ayame must create at runtime. Any petition to create a sound slot with an ID bigger than the number stated here will throw an error.
- Length: 2 bytes
- Type of value: unsigned short
- Purpose: the instance ID given to the currently played BGM track.
- Length: 2 bytes
- Type of value: unsigned short
- Purpose: the instance ID given to the currently played voice file.
- Length: 1 byte
- Type of value: unsigned byte
- Purpose: this variable comes out unused. It only ends up writing at the end of the main save file the amount specified here of null bytes. Sadly due to bug in their code, if the value is set to 0, we get a violation access error:
OpcodeResolver
case 0x813u:
WriteToLogFile(v3107, "KoeVolume");
v291 = (unsigned __int16)GetNumberFlag((unsigned __int16 *)v3107);
v292 = GetNumberFlag((unsigned __int16 *)v3107);
*(_BYTE *)(v291 + *(_DWORD *)(v3107 + 820)) = v292; --> The crash happens here
v293 = *(_BYTE *)(*(unsigned __int16 *)(v3107 + 1088) + *(_DWORD *)(v3107 + 820));
if ( v293 )
sub_6484E0((int)AyameDLL, (unsigned __int16)AudioSlots_Voice, (float)v293);
goto LABEL_616;.text:00682CC7 mov ecx, [esp+23DE0h+var_1EC70] ; jumptable 00681A1A case 2067
.text:00682CCE push offset aKoevolume ; "KoeVolume"
.text:00682CD3 call WriteToLogFile
.text:00682CD8 mov ecx, [esp+23DE0h+var_1EC70]
.text:00682CDF call GetNumberFlag
.text:00682CE4 mov ecx, [esp+23DE0h+var_1EC70]
.text:00682CEB movzx esi, ax
.text:00682CEE call GetNumberFlag
.text:00682CF3 mov dl, al
.text:00682CF5 mov ecx, esi
.text:00682CF7 mov eax, [esp+23DE0h+var_1EC70]
.text:00682CFE mov eax, [eax+334h] --> eax+334h is where this unused variable gets stored during runtime
.text:00682D04 mov [ecx+eax], dl --> The crash happens here
.text:00682D07 mov eax, [esp+23DE0h+var_1EC70]
.text:00682D0E movzx ecx, word ptr [eax+440h]
.text:00682D15 mov eax, [eax+334h]
.text:00682D1B mov al, [ecx+eax]
.text:00682D1E test al, al
- Length: 1 byte
- Type of value: unsigned byte
- Purpose: for obfuscation purposes, the game uses this byte to shuffle the first and last byte of the actual SDT key, by using the length of the Dat key.
- Length: 1 byte
- Type of value: unsigned byte
- Purpose: the actual key the game to decrypt all .sdt files and to keep debug mode secured.
- Length: 1 byte
- Type of value: signed byte
-
Purpose: the game for some reason allows for a RECT to be created alongside certain
objin the screen, and each of them are completely independent from the others, and they simply pop up when theobjthey are linked to are present on screen. This functionality goes completely unused in the game, but regardless, the engine allows to be customize this RECT with some basic parameters.
| Value | Outcome |
|---|---|
| 0 | Disabled |
| 1 | Enabled |
- Length: 1 byte
- Length: 2 bytes
- Type of value: signed short
- Purpose: indicates the coordinate in the x axis of the game screen where the top-left corner of the RECT that contains the image for the message part of the dialogue window should be placed at.
- Length: 2 bytes
- Type of value: signed short
- Purpose: the same as with Message part: RECT for image (x axis origin), but for the y axis.
- Length: 2 bytes
- Type of value: signed short
- Purpose: the same as with Message part: RECT for image (x axis origin), but applying it for the RECT that contains the text itself.
- Length: 2 bytes
- Type of value: signed short
- Purpose: the same as with Message part: RECT for text (x axis origin), but for the y axis.
- Length: 2 bytes
- Type of value: unsigned short
- Purpose: another property of the same background managed in Message part: RECT for text (x axis origin), but in this case this parameter indicates its width. This should not to be confused with the actual text width, which can be managed through Message part: font ID.
- Length: 2 bytes
- Type of value: unsigned short
- Purpose: the same as with Message part: RECT for text (width), but in this case this parameter indicates its height. This should not to be confused with the actual text height, which can be managed through Message part: font ID.
- Length: 2 bytes
- Type of value: signed short
- Purpose: the same as with Message part: RECT for image (x axis origin), but applying it for the RECT that contains the background fill.
- Length: 2 bytes
- Type of value: signed short
- Purpose: the same as with Message part: RECT for the background fill (x axis origin), but for the y axis.
- Length: 2 bytes
- Type of value: unsigned short
- Purpose: another property of the same background managed in Message part: RECT for the background fill (x axis origin), but in this case this parameter indicates its width.
- Length: 2 bytes
- Type of value: unsigned short
- Purpose: the same as with Message part: RECT for the background fill (width), but in this case this parameter indicates its height.
- Length: 260 bytes
- Type of value: string
- Purpose: indicates the name of the .mg2 file that corresponds to the background of the message window for the text. The game will consider the first null byte to be the end of the string.
- Length: 2 bytes
- Type of value: signed short
- Purpose: the same as with Message part: font ID, but for the name of the current character.
- Length: 1 byte
- Type of value: signed byte
- Purpose: exactly the same as for Message part: enable the background fill, but applied to the character name. When the current message has no character associated to it, the background fill gets removed from the screen too.
- Length: 1 byte
- Length: 2 bytes
- Type of value: signed short
- Purpose: indicates the coordinate in the x axis of the game screen where the top-left corner of the RECT that contains the image for the character name part of the dialogue window should be placed at.
- Length: 2 bytes
- Type of value: signed short
- Purpose: the same as with Character name part: RECT for image (x axis origin), but for the y axis.
- Length: 2 bytes
- Type of value: signed short
- Purpose: the same as with Character name part: RECT for image (x axis origin), but applying it for the RECT that contains the text itself.
- Length: 2 bytes
- Type of value: signed short
- Purpose: the same as with Character name part: RECT for text (x axis origin), but for the y axis.
- Length: 2 bytes
- Type of value: unsigned short
- Purpose: another property of the same background managed in Character name part: RECT for text (x axis origin), but in this case this parameter indicates its width. This should not to be confused with the actual text width, which can be managed through Character name part: font ID.
- Length: 2 bytes
- Type of value: unsigned short
- Purpose: the same as with Character name part: RECT for text (width), but in this case this parameter indicates its height. This should not to be confused with the actual text height, which can be managed through Character name part: font ID.
- Length: 2 bytes
- Type of value: signed short
- Purpose: the same as with Character name part: RECT for image (x axis origin), but applying it for the RECT that contains the background fill.
- Length: 2 bytes
- Type of value: signed short
- Purpose: the same as with Character name part: RECT for the background fill (x axis origin), but for the y axis.
- Length: 2 bytes
- Type of value: unsigned short
- Purpose: another property of the same background managed in Character name part: RECT for the background fill (x axis origin), but in this case this parameter indicates its width.
- Length: 2 bytes
- Type of value: unsigned short
- Purpose: the same as with Character name part: RECT for the background fill (width), but in this case this parameter indicates its height.
- Length: 2 bytes
- Type of value: unsigned short
- Purpose: not known, it does not seem to do anything at all.
- Length: 2 bytes
- Type of value: unsigned short
- Purpose: not known, it does not seem to do anything at all.
- Length: 1 byte
- Type of value: unsigned byte
- Purpose: not known, it does not seem to do anything at all.
- Length: 260 bytes
- Type of value: string
- Purpose: indicates the name of the .mg2 file that corresponds to the background of the character name window for the text. The game will consider the first null byte to be the end of the string.
- Length: 4 bytes
- Type of value: signed bytes
- Length: 4 bytes
- Type of value: signed bytes
- Length: 8 bytes
- Length: 4 bytes
- Type of value: signed bytes
- Length: 4 bytes
- Type of value: signed bytes
- Length: 4 bytes
- Type of value: signed bytes
- Length: 4 bytes
- Type of value: signed bytes
- Length: 40 bytes
- Length: 4 bytes
- Type of value: signed bytes
- Length: 4 bytes
- Type of value: signed bytes
- Length: 4 bytes
- Type of value: signed bytes
- Length: 4 bytes
- Type of value: signed bytes
- Length: 4 bytes
- Type of value: signed bytes
- Length: 4 bytes
- Type of value: signed bytes
- Length: 13644 bytes (or the remaining bytes needed to fill the size of the 2nd section, as indicated in File structure
As any visual novel should do, there are branching paths in the plot. So each option given to the user constitutes a choice box that has to be created.
- Length: 1 byte
- Type of value: signed byte
- Purpose: indicates the alignment the text inside the choice box should have. This value should be taken into consideration with what's the value put in Choice boxes: RECT for text (x axis origin).
| Value | Alignment |
|---|---|
| 0, 3 | Center |
| 1, 4 | Left |
| 2, 5 | Right |
(While these values will vary depending on the opcode called in-game, it seems that the only times that this value gets used for, is it for the SelExLoop opcode.
- Length: 1 byte
- Length: 2 bytes
- Type of value: unsigned short
- Purpose: following the explanation given in Fonts, this indicates what font type to use for the choice boxes.
- Length: 3 bytes
- Type of value: signed bytes
- Purpose: this holds the RGB values that the text inside each choice box will have.
- Length: 1 byte
- Type of value: signed byte
- Purpose: exactly the same as for Message part: enable the background fill, but applied to the choice boxes.
- Length: 2 bytes
- Type of value: signed short
- Purpose: the same as with Message part: RECT for image (x axis origin), but for the RECT that contains the text inside the first Choice box.
- Length: 2 bytes
- Type of value: signed short
- Purpose: the same as with Choice boxes: RECT for text (x axis origin), but for the y axis.
- Length: 2 bytes
- Type of value: unsigned short
- Purpose: another property of the same background managed in Choice boxes: RECT for text (x axis origin), but in this case this parameter indicates its width. This should not to be confused with the actual text width, which can be managed through Choice boxes: font ID.
- Length: 2 bytes
- Type of value: unsigned short
- Purpose: the same as with Choice boxes: RECT for text (width), but in this case this parameter indicates its height. This should not to be confused with the actual text height, which can be managed through Choice boxes: font ID.
- Length: 2 bytes
- Type of value: unsigned short
- Purpose: not known, it does not seem to do anything at all.
- Length: 2 bytes
- Type of value: unsigned short
- Purpose: not known, it does not seem to do anything at all.
- Length: 2 bytes
- Type of value: unsigned short
- Purpose: not known, it does not seem to do anything at all.
- Length: 2 bytes
- Type of value: unsigned short
- Purpose: the background fill created for each Choice box, this parameter indicates their height.
- Length: 2 bytes
- Type of value: unsigned short
- Purpose: the same as with Choice boxes: RECT for the background fill (height), but in this case this parameter indicates their width.
- Length: 2 bytes
- Type of value: signed short
- Purpose: not known, it does not seem to do anything at all.
- Length: 2 bytes
- Type of value: signed short
- Purpose: between each choice box there must be some space, this parameter indicates how much vertical space there should between each of them. In reality this value what does do is indicate how much distance there should be between the top edge of the game's screen and the center of the image for the latest choice box.
- Length: 2 bytes
- Type of value: signed short
- Purpose: between the left edge of the game's screen and each choice box there should be some space, this parameter determines that.
- Length: 2 bytes
- Type of value: signed short
- Purpose: not known, it does not seem to do anything at all.
- Length: 260 bytes
- Type of value: string
- Purpose: the name of the .mg2 file that contains the choice box, but it has not been selected by the user previously. The game will consider the first null byte to be the end of the string.
- Length: 260 bytes
- Type of value: string
- Purpose: the same as with Choice boxes: image with option not chosen, but when the mouse is hovering the choice box.
- Length: 260 bytes
- Type of value: string
- Purpose: the same as with Choice boxes: image with option not chosen, but when the user has already chosen that option in a previous walkthrough.
- Length: 260 bytes
- Type of value: string
- Purpose: the same as with Choice boxes: image with option already chosen, but when the mouse is hovering the choice box.
- Length: 2 bytes
- Length: 4 bytes
- Type of value: signed int
- Purpose: not used at any point in time, probably created for future games that might use it.
- Length: 4 bytes
- Type of value: signed int
- Purpose: not used at any point in time, probably created for future games that might use it.
- Length: 4 bytes
- Type of value: signed int
- Purpose: not used at any point in time, probably created for future games that might use it.
- Length: 4 bytes
- Length: 4 bytes
- Type of value: signed int
- Purpose: not used at any point in time, probably created for future games that might use it.
- Length: 4 bytes
- Type of value: signed int
- Purpose: not used at any point in time, probably created for future games that might use it.
- Length: 4 bytes
- Type of value: signed int
- Purpose: not used at any point in time, probably created for future games that might use it.
- Length: 4 bytes
- Type of value: signed int
- Purpose: not used at any point in time, probably created for future games that might use it.
- Length: 40 bytes
- Length: 4 bytes
- Type of value: signed int
- Purpose: not used at any point in time, probably created for future games that might use it.
- Length: 4 bytes
- Type of value: signed int
- Purpose: not used at any point in time, probably created for future games that might use it.
- Length: 4 bytes
- Type of value: signed int
- Purpose: not used at any point in time, probably created for future games that might use it.
- Length: 4 bytes
- Length: 4 bytes
- Type of value: signed int
- Purpose: not used at any point in time, probably created for future games that might use it.
- Length: 4 bytes
- Type of value: signed int
- Purpose: not used at any point in time, probably created for future games that might use it.
- Length: 4 bytes
- Type of value: signed int
- Purpose: not used at any point in time, probably created for future games that might use it.
- Length: 4 bytes
- Type of value: signed int
- Purpose: not used at any point in time, probably created for future games that might use it.
- Length: 40 bytes
- Length: 4 bytes
- Type of value: signed int
- Purpose: not used at any point in time, probably created for future games that might use it.
- Length: 4 bytes
- Type of value: signed int
- Purpose: not used at any point in time, probably created for future games that might use it.
- Length: 16 bytes
- Length: 4 bytes
- Type of value: signed int
- Purpose: not used at any point in time, probably created for future games that might use it.
- Length: 4 bytes
- Type of value: signed int
- Purpose: not used at any point in time, probably created for future games that might use it.
- Length: 4 bytes
- Type of value: signed int
- Purpose: not used at any point in time, probably created for future games that might use it.
- Length: 40 bytes
- Length: 4 bytes
- Type of value: signed int
- Purpose: not used at any point in time, probably created for future games that might use it.
- Length: 4 bytes
- Type of value: signed int
- Purpose: not used at any point in time, probably created for future games that might use it.
- Length: 12 bytes
- Length: 4 bytes
- Type of value: signed int
- Purpose: not used at any point in time, probably created for future games that might use it.
- Length: 4 bytes
- Type of value: signed int
- Purpose: not used at any point in time, probably created for future games that might use it.
- Length: 4 bytes
- Type of value: signed int
- Purpose: not used at any point in time, probably created for future games that might use it.
- Length: 25952 bytes (or the remaining bytes needed to fill the size of the 3rd section, as indicated in File structure.