Merge branch 'title_work' into feature/title-screen

This commit is contained in:
Lorenzooone 2021-09-30 23:26:28 +02:00 committed by GitHub
commit c7e8c6e842
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
147 changed files with 6878 additions and 860 deletions

View File

@ -21,6 +21,17 @@ Text conversion:
Masaru
Sterophonick
Normmatt
KillThad
Graphics:
JeffMan
surrashubound
Masaru
Testing:
Eevs
John Enigma
CloverCharBoyBound
Graphics:
JeffMan

View File

@ -47,10 +47,11 @@ This project aims to both complete the VWF codebase and to provide a tool for tr
4. Copy EarthBound ROM to `bin/eb.smc`.
5. Run `build-tools.ps1`.
- Windows: `.\build-tools.ps1` in a PowerShell prompt
- Linux: `pwsh build-tools.ps1`
- Linux and MacOS: `pwsh build-tools.ps1`
6. Copy/build `armips` to `bin`.
- Windows: grab the latest release [here](https://github.com/Kingcom/armips/releases) and copy the executable to `bin/armips.exe`.
- Linux: follow the [README](https://github.com/Kingcom/armips/blob/master/Readme.md) to build `armips` and copy the executable to `bin/armips`.
- MacOS: grab the latest release [here](https://github.com/Emory-M/armips/releases) and copy the executable to `bin/armips`.
2. Building the ROM
1. Run `build.ps1`.
2. The default compiled ROM is copied to `bin/m12.gba`.
@ -58,3 +59,4 @@ This project aims to both complete the VWF codebase and to provide a tool for tr
1. `dotnet build tools/ScriptTool` (don't set the output directory)
2. `dotnet build tools/ScriptToolGui -o bin/ScriptToolGui`
3. Run with `dotnet bin/ScriptToolGui/ScriptToolGui.dll` (or just run the EXE file directly).

View File

@ -3,3 +3,7 @@ $pwd = $pwd.Path
& dotnet build tools/ScriptTool -o "$([IO.Path]::Combine($pwd, "bin/ScriptTool"))"
if ($LASTEXITCODE -ne 0) { exit -1 }
& dotnet build tools/RenderCastRoll -o "$([IO.Path]::Combine($pwd, "bin/RenderCastRoll"))"
if ($LASTEXITCODE -ne 0) { exit -1 }
& dotnet build tools/RenderStaffCredits -o "$([IO.Path]::Combine($pwd, "bin/RenderStaffCredits"))"
if ($LASTEXITCODE -ne 0) { exit -1 }

View File

@ -1,44 +1,50 @@
[Environment]::CurrentDirectory = (Get-Location -PSProvider FileSystem).ProviderPath
#Region Variables
$input_rom_file = "bin/m12fresh.gba"
$output_rom_file = "bin/m12.gba"
$eb_rom_file = "bin/eb.smc"
$working_dir = "working"
$src_dir = "src"
$compiled_asm_file = "src/m2-compiled.asm"
$includes_asm_file = "m12-includes.asm" # implicitly rooted in working_dir
$hack_asm_file = "m2-hack.asm" # implicitly rooted in src_dir
$input_rom_file = "bin/m12fresh.gba"
$output_rom_file = "bin/m12.gba"
$eb_rom_file = "bin/eb.smc"
$working_dir = "working"
$give_dir = "working/m12-give-strings"
$src_dir = "src"
$data_dir = "src/data"
$give_new_dir = "src/m12-give-strings"
$cast_roll_file = "working/cast_roll.json"
$staff_credits_file = "working/staff_text.md"
$compiled_asm_file = "src/m2-compiled.asm"
$includes_asm_file = "m12-includes.asm" # implicitly rooted in working_dir
$hack_asm_file = "m2-hack.asm" # implicitly rooted in src_dir
$input_c_files =
"src/c/ext.c",
"src/c/vwf.c",
"src/c/locs.c",
"src/c/credits.c",
"src/c/goods.c",
"src/c/fileselect.c",
"src/c/status.c",
"src/c/battle.c",
"src/c/equip.c",
"src/c/psi.c",
"src/c/title.c"
"src/c/title.c",
"src/c/luminehall.c"
$base_c_address = 0x83755B8;
$scripttool_cmd = "bin/ScriptTool/ScriptTool.dll"
$gcc_cmd = "arm-none-eabi-gcc"
$ld_cmd = "arm-none-eabi-ld"
$objdump_cmd = "arm-none-eabi-objdump"
$readelf_cmd = "arm-none-eabi-readelf"
$combined_obj_file = "src/c/combined.o"
$linked_obj_file = "src/c/linked.o"
$combine_script = "src/c/combine.ld"
$link_script = "src/c/link.ld"
$undefine_obj_file = "src/c/ext.o"
$base_c_address = 0x83755B8;
$scripttool_cmd = "bin/ScriptTool/ScriptTool.dll"
$rendercastroll_cmd = "bin/RenderCastRoll/RenderCastRoll.dll"
$renderstaffcredits_cmd = "bin/RenderStaffCredits/RenderStaffCredits.dll"
$gcc_cmd = "arm-none-eabi-gcc"
$ld_cmd = "arm-none-eabi-ld"
$objdump_cmd = "arm-none-eabi-objdump"
$readelf_cmd = "arm-none-eabi-readelf"
$combined_obj_file = "src/c/combined.o"
$linked_obj_file = "src/c/linked.o"
$combine_script = "src/c/combine.ld"
$link_script = "src/c/link.ld"
$undefine_obj_file = "src/c/ext.o"
If ($IsWindows) { $asm_cmd = "bin/armips.exe" }
ElseIf ($IsLinux) { $asm_cmd = "bin/armips" }
Else {
Write-Host "TODO: what's the Mac version of armips?"
Exit -1
}
If ($IsWindows) { $asm_cmd = "bin/armips.exe" }
ElseIf ($IsLinux -or $IsMacOS) { $asm_cmd = "bin/armips" }
$includes_sym_file = [IO.Path]::ChangeExtension($includes_asm_file, "sym")
$output_rom_sym_file = [IO.Path]::ChangeExtension($output_rom_file, "sym")
@ -51,6 +57,14 @@ $scripttool_args =
$working_dir,
$eb_rom_file,
$input_rom_file
$rendercastroll_args =
$cast_roll_file,
$data_dir
$renderstaffcredits_args =
$staff_credits_file,
$data_dir
$gcc_args =
"-c",
@ -351,6 +365,17 @@ Copy-Item -Path $input_rom_file -Destination $output_rom_file
& dotnet $scripttool_cmd $scripttool_args
if ($LASTEXITCODE -ne 0) { exit -1 }
"Copying give strings to src folder..."
Copy-Item -Path $give_dir -Destination $give_new_dir -Recurse
"Pre-rendering cast roll..."
& dotnet $rendercastroll_cmd $rendercastroll_args
if ($LASTEXITCODE -ne 0) { exit -1 }
"Pre-rendering staff credits..."
& dotnet $renderstaffcredits_cmd $renderstaffcredits_args
if ($LASTEXITCODE -ne 0) { exit -1 }
# ------------------------ ASSEMBLE GAME TEXT -----------------------
"Assembling game text..."
& $asm_cmd -root $working_dir -sym $includes_sym_file $includes_asm_file
@ -436,4 +461,6 @@ $rom_bytes = [IO.File]::ReadAllBytes($output_rom_file)
"Finished compiling $output_rom_file in $($timer.Elapsed.TotalSeconds.ToString("F3")) s"
Remove-Item -Path $give_new_dir -Recurse
exit 0

2
makefile Normal file
View File

@ -0,0 +1,2 @@
default:
pwsh.exe .\build.ps1

View File

@ -18,7 +18,8 @@ English names:
- Jeff: 7A 95 96 96
- Poo: 80 9F 9F
0x2020C70: enemy data slots in-battle? separated by 0x94 bytes
0x2020C70: party character slots in battle. 0x94 bytes long
0x2021110: enemy slots in battle. 0x94 bytes long
0x2025038: enemy count (initial, not current)
0x20251D8: item drop
0x3000A00: Current PSI list when displaying a PSI window?
@ -95,7 +96,7 @@ English names:
[00]: A menu
[01]: Money
[02]: ?
[03]: Action subject ("Who?", etc.)
[03]: Action subject ("Who?", etc.) / Money window (called by script)
[04]: New equipment selection
[05]: Offense/Defense
[06]: Equip

View File

@ -9,10 +9,10 @@ void printTargetOfAttack(short a, short target)
WINDOW *window = getWindow(3);
m2_setupwindow(window, 0x9, 0x3, 0x14, 0x2);
initWindow_buffer(window, NULL, 0);
printstr_buffer(window, &m12_battle_commands_str11, 0, 0, false); //To
printstr_buffer(window, m12_battle_commands_str11, 0, 0, false); //To
if(target != -1)
{
printstr_hlight_buffer(window, &m12_battle_commands_str14, 8, 0, false);// " "
printstr_hlight_buffer(window, m12_battle_commands_str14, 8, 0, false);// " "
short *pointer = (short*)(0x20248E0 + 0x83E);
byte *pointer2 = (byte*)(pointer);
short value = *pointer;
@ -25,23 +25,23 @@ void printTargetOfAttack(short a, short target)
pointer2 += 0x26;
byte val = *(pointer2 + target);
unsigned short ailmentTile = ailmentTileSetup((byte*)(0x2020CCF + (val * 0x94)), 0);
if(ailmentTile >= 1)
{
if(ailmentTile > 1)
{
map_tile(ailmentTile, window->window_x + 0x13, window->window_y);
map_tile(ailmentTile + 0x20, window->window_x + 0x13, window->window_y + 1);
}
else
{
map_tile(0x1FF, window->window_x + 0x13, window->window_y);
map_tile(0x1FF, window->window_x + 0x13, window->window_y + 1);
}
}
else
{
map_tile(0x1FF, window->window_x + 0x13, window->window_y);
map_tile(0x1FF, window->window_x + 0x13, window->window_y + 1);
}
}
else
{
if(a == 0) //a is the row here
printstr_buffer(window, &m12_battle_commands_str12, 2, 0, false); //the Front Row
printstr_buffer(window, m12_battle_commands_str12, 2, 0, false); //the Front Row
else
printstr_buffer(window, &m12_battle_commands_str13, 2, 0, false); //the Back Row
printstr_buffer(window, m12_battle_commands_str13, 2, 0, false); //the Back Row
}
}
@ -55,26 +55,26 @@ void printBattleMenu(byte validXs, byte validYs, byte highlighted)
{
if(validYs & 1)
{
print_blankstr_buffer(2,1,5,(int*)(OVERWORLD_BUFFER - 0x2000));
print_blankstr_buffer(2,1,5,(byte*)(OVERWORLD_BUFFER - ((*tile_offset) * TILESET_OFFSET_BUFFER_MULTIPLIER)));
if((*drawValue) == 2)
{
print_blankstr_buffer(7,1,5,(int*)(OVERWORLD_BUFFER - 0x2000));
str = &m12_battle_commands_str10; //Do Nothing
print_blankstr_buffer(7,1,5,(byte*)(OVERWORLD_BUFFER - ((*tile_offset) * TILESET_OFFSET_BUFFER_MULTIPLIER)));
str = m12_battle_commands_str10; //Do Nothing
}
else if((*drawValue) == 1)
str = &m12_battle_commands_str6; //Shoot
str = m12_battle_commands_str6; //Shoot
else
str = &m12_battle_commands_str0; //Bash
str = m12_battle_commands_str0; //Bash
printstr_hlight_buffer(window, str, 1, 0, highlighted & 1);
}
if(validYs & 2)
{
print_blankstr_buffer(2,3,5,(int*)(OVERWORLD_BUFFER - 0x2000));
print_blankstr_buffer(2,3,5,(byte*)(OVERWORLD_BUFFER - ((*tile_offset) * TILESET_OFFSET_BUFFER_MULTIPLIER)));
if((*active_window_party_member) != 2)
printstr_hlight_buffer(window, &m12_battle_commands_str3, 1, 1, highlighted & 2); //PSI
printstr_hlight_buffer(window, m12_battle_commands_str3, 1, 1, highlighted & 2); //PSI
else
printstr_hlight_buffer(window, &m12_battle_commands_str7, 1, 1, highlighted & 2); //Spy
printstr_hlight_buffer(window, m12_battle_commands_str7, 1, 1, highlighted & 2); //Spy
}
}
@ -84,17 +84,17 @@ void printBattleMenu(byte validXs, byte validYs, byte highlighted)
{
if((*drawValue) != 2)
{
print_blankstr_buffer(7,1,5,(int*)(OVERWORLD_BUFFER - 0x2000));
printstr_hlight_buffer(window, &m12_battle_commands_str1, 6, 0, highlighted & 4); //Goods
print_blankstr_buffer(7,1,5,(byte*)(OVERWORLD_BUFFER - ((*tile_offset) * TILESET_OFFSET_BUFFER_MULTIPLIER)));
printstr_hlight_buffer(window, m12_battle_commands_str1, 6, 0, highlighted & 4); //Goods
}
}
if(validYs & 2)
{
print_blankstr_buffer(7,3,5,(int*)(OVERWORLD_BUFFER - 0x2000));
print_blankstr_buffer(7,3,5,(byte*)(OVERWORLD_BUFFER - ((*tile_offset) * TILESET_OFFSET_BUFFER_MULTIPLIER)));
if((*drawValue) != 2)
{
printstr_hlight_buffer(window, &m12_battle_commands_str4, 6, 1, highlighted & 8); //Defend
printstr_hlight_buffer(window, m12_battle_commands_str4, 6, 1, highlighted & 8); //Defend
}
}
}

View File

@ -6,16 +6,16 @@
void printTargetOfAttack(short a, short target);
void printBattleMenu(byte validXs, byte validYs, byte highlighted);
extern byte m12_battle_commands_str0;
extern byte m12_battle_commands_str1;
extern byte m12_battle_commands_str3;
extern byte m12_battle_commands_str4;
extern byte m12_battle_commands_str6;
extern byte m12_battle_commands_str7;
extern byte m12_battle_commands_str10;
extern byte m12_battle_commands_str11;
extern byte m12_battle_commands_str12;
extern byte m12_battle_commands_str13;
extern byte m12_battle_commands_str14;
extern byte m12_battle_commands_str0[];
extern byte m12_battle_commands_str1[];
extern byte m12_battle_commands_str3[];
extern byte m12_battle_commands_str4[];
extern byte m12_battle_commands_str6[];
extern byte m12_battle_commands_str7[];
extern byte m12_battle_commands_str10[];
extern byte m12_battle_commands_str11[];
extern byte m12_battle_commands_str12[];
extern byte m12_battle_commands_str13[];
extern byte m12_battle_commands_str14[];
#endif

318
src/c/credits.c Normal file
View File

@ -0,0 +1,318 @@
#include "credits.h"
void printPlayerNameCredits(unsigned short *arrangements)
{
//Converts the player name to arrangements
int length = 0;
byte *player_name = m2_player1;
unsigned short yPosition = m2_credits_extras[0];
unsigned short defaultNameLength = m2_credits_extras[1];
//First things first, it calculates the length of the string
for(length = 0; length < PLAYER_NAME_SIZE && (*(++player_name)) != 0xFF; length++);
//Gets where to position the arrangements...
int start_pos = ((0x1F - length) >> 1) + 1;
int start_pos_default = ((0x1F - defaultNameLength) >> 1) + 1;
unsigned short *player_name_arrangements = (yPosition << 5) + arrangements + start_pos;
unsigned short *default_player_name_arrangements = (yPosition << 5) + arrangements + start_pos_default;
player_name = m2_player1;
//Clears the default MARIO player name...
for(int i = 0; i < defaultNameLength; i++)
{
default_player_name_arrangements[i] = 0xF19B;
default_player_name_arrangements[i + 0x20] = 0xF19B;
}
//Puts the new arrangements in
for(int i = 0; i < length; i++)
{
unsigned short arrangement = m2_credits_conversion_table[player_name[i]];
player_name_arrangements[i] = arrangement;
player_name_arrangements[i + 0x20] = arrangement + 0x20;
}
}
void writeCastText(unsigned short *bg0Arrangements, unsigned short *bg1Arrangements)
{
//Function that writes out the VWF Cast roll text and puts the arrangements in.
byte *castText_curr_ptr;
byte *castText_curr_start = cast_vwf_names;
int length;
int Tiles[SIDE_BUFFER_SIZE + 1][4];
unsigned short lastEdited = 0;
//Do all the entries
while((*castText_curr_start) != END_ALL)
{
//Read info
unsigned short tile_y = (*castText_curr_start) + ((*(castText_curr_start + 1)) << 8);
int center_x = *(castText_curr_start + 2);
castText_curr_start += 3;
//Setup
castText_curr_ptr = castText_curr_start;
length = 0;
setTilesToBlankCast(Tiles[0]);
//First things first, it calculates the total length of the text in pixels
while((*castText_curr_ptr) != END)
length += getCharWidthCast(*(castText_curr_ptr++));
//Calculate the starting position of the text
int x = center_x - (length >> 1);
if((x + length) > 240) //GBA Screen width
x = 240 - length;
if(x < 0)
x = 0;
//It then gets the length in arrangements
int effectiveLength = length;
length = (length + 7) >> 3;
castText_curr_ptr = castText_curr_start;
int currXStart = x;
//Prints out the characters
while((*castText_curr_ptr) != END)
x += readCastCharacter(*(castText_curr_ptr++), Tiles, bg0Arrangements, x, tile_y, &lastEdited);
if((x & 7) != 0)
{
//Do the last one
unsigned short baseTileValue = m2_cast_vwf_free;
int *baseGraphicsPointer = (int*)((baseTileValue << 5) + BASE_GRAPHICS_ADDRESS);
int currLen = x & 7;
int currPos = x >> 3;
unsigned short *baseArrangementsPointer = bg0Arrangements + (tile_y << 5) + currPos + 1;
int tileValue = (((lastEdited) >> 5) << 6) + ((lastEdited) & 0x1F);
lastEdited++;
printCastTiles(Tiles[0], baseArrangementsPointer, baseGraphicsPointer + (tileValue << 3), baseTileValue + tileValue);
}
//End of cycle stuff
castText_curr_start = (castText_curr_ptr + 1);
}
}
int readCastCharacter(byte chr, int Tiles[SIDE_BUFFER_SIZE + 1][4], unsigned short *arrangements, int x, int tile_y, unsigned short *lastEdited)
{
//Reads a character. Handles special cases.
//The valid characters are printed to the Tiles 1bpp buffer that stores the VWF form of the text.
//This is then stored (when it makes sense to do so) to arrangements and graphics by printCastTiles.
switch(chr)
{
case END:
return 0;
case PC_START:
case PC_START+1:
case PC_START+2:
case PC_START+3:
return readCastCharacterName(pc_names+(chr-PC_START)*(PC_NAME_SIZE + 2), Tiles, arrangements, x, tile_y, PC_NAME_SIZE, lastEdited);
case PC_START+4:
return readCastCharacterName(pc_names+(chr-PC_START)*(PC_NAME_SIZE + 2), Tiles, arrangements, x, tile_y, DOG_NAME_SIZE, lastEdited);
default:
return printCastCharacter(chr, Tiles, arrangements, x, tile_y, lastEdited);
}
}
int readCastCharacterName(byte* str, int Tiles[SIDE_BUFFER_SIZE + 1][4], unsigned short *arrangements, int x, int tile_y, int max_size, unsigned short *lastEdited)
{
//Reads a playable character's name.
//The characters are printed to the Tiles 1bpp buffer that stores the VWF form of the text.
//This is then converted (when it makes sense to do so) to arrangements by printLumineTiles.
//This is separate in order to avoid recursive issues caused by user's tinkering
int totalLen = 0;
for(int i = 0; i < max_size; i++)
{
if(*(str + 1) == 0xFF)
return totalLen;
byte chr = decode_character(*(str++));
totalLen += printCastCharacter(chr, Tiles, arrangements, x + totalLen, tile_y, lastEdited);
}
return totalLen;
}
int printCastCharacter(byte chr, int Tiles[SIDE_BUFFER_SIZE + 1][4], unsigned short *arrangements, int x, int tile_y, unsigned short *lastEdited)
{
//Function that gets a character and then prints it to the Tiles buffer.
//If the buffer is full, it uses the AlternativeTiles side-buffer and then prints Tiles to the arrangements.
//The same happens to any AlternativeTiles side-buffer that gets full
int tileWidth = CAST_FONT_WIDTH;
int tileHeight = CAST_FONT_HEIGHT;
unsigned short baseTileValue = m2_cast_vwf_free;
int *baseGraphicsPointer = (int*)((baseTileValue << 5) + BASE_GRAPHICS_ADDRESS);
int chosenLen = m2_widths_table[CAST_FONT][chr] & 0xFF;
int renderedLen = m2_widths_table[CAST_FONT][chr] >> 8;
byte *glyphRows = &m2_font_table[CAST_FONT][chr * tileWidth * tileHeight * 8];
int currLen = x & 7;
int currPos = x >> 3;
unsigned short *baseArrangementsPointer = arrangements + (tile_y << 5) + currPos + 1;
if(chosenLen <= 0)
return 0;
if((currLen + chosenLen) >= 8)
{
for(int i = 0; i < SIDE_BUFFER_SIZE; i++)
setTilesToBlankCast(Tiles[i + 1]);
if(renderedLen > 0)
printCastCharacterInMultiTiles(Tiles, glyphRows, renderedLen, currLen);
int fullAlternatives = ((currLen + chosenLen) >> 3);
for(int i = 0; i < fullAlternatives; i++)
{
int tileValue = (((*lastEdited) >> 5) << 6) + ((*lastEdited) & 0x1F);
(*lastEdited)++;
printCastTiles(Tiles[i], baseArrangementsPointer + i, baseGraphicsPointer + (tileValue << 3), baseTileValue + tileValue);
}
copyTilesCast(Tiles, fullAlternatives);
}
else if(renderedLen > 0)
printCastCharacterInSingleTiles(Tiles, glyphRows, renderedLen, currLen);
return chosenLen;
}
void printCastCharacterInMultiTiles(int Tiles[SIDE_BUFFER_SIZE + 1][4], byte *glyphRows, int glyphLen, int currLen)
{
//Prints a character to the tiles 1bpp buffer.
//The part that goes beyond the tiles buffer will be printed to the AlternativeTiles buffer
int tileWidth = CAST_FONT_WIDTH;
int tileHeight = CAST_FONT_HEIGHT;
int startY = START_Y;
for(int dTileY = 0; dTileY < tileHeight; dTileY++)
{
int tileIndex = dTileY * 2;
int renderedWidth = glyphLen;
int dTileX = 0;
while(renderedWidth > 0)
{
int *currTile = Tiles[dTileX];
int *currAlt = Tiles[dTileX + 1];
for(int half = 0; half < 2; half++)
{
int tile = currTile[tileIndex + half];
int alternativeTile = currAlt[tileIndex + half];
int endingTile = 0;
int endingAlternativeTile = 0;
for(int row = 0; row < 4; row++)
{
unsigned short canvasRow = ((tile >> (8 * row))&0xFF) | (((alternativeTile >> (8 * row))&0xFF) << 8);
unsigned short glyphRow = 0;
if(row + (half * 4) - startY >= 0)
glyphRow = glyphRows[row + (half * 4) - startY + (dTileY * 8 * tileWidth) + (dTileX * 8)] << currLen;
else if(dTileY == 1)
glyphRow = glyphRows[row + (half * 4) - startY + 8 + (dTileX * 8)] << currLen;
canvasRow |= glyphRow;
endingTile |= (canvasRow & 0xFF) << (8 * row);
endingAlternativeTile |= ((canvasRow >> 8) & 0xFF) << (8 * row);
}
currTile[tileIndex + half] = endingTile;
currAlt[tileIndex + half] = endingAlternativeTile;
}
renderedWidth -= 8;
dTileX++;
}
}
}
void printCastCharacterInSingleTiles(int Tiles[SIDE_BUFFER_SIZE + 1][4], byte *glyphRows, int glyphLen, int currLen)
{
//Prints a character to the tiles 1bpp buffer.
//We know this won't go outside of the buffer's range, so we avoid some checks
int tileWidth = CAST_FONT_WIDTH;
int tileHeight = CAST_FONT_HEIGHT;
int startY = START_Y;
for(int dTileY = 0; dTileY < tileHeight; dTileY++)
{
int tileIndex = dTileY * 2;
for(int half = 0; half < 2; half++)
{
int tile = Tiles[0][tileIndex + half];
int endingTile = 0;
for(int row = 0; row < 4; row++)
{
byte canvasRow = ((tile >> (8 * row))&0xFF);
byte glyphRow = 0;
if(row + (half * 4) - startY >= 0)
glyphRow = glyphRows[row + (half * 4) - startY + (dTileY * 8 * tileWidth)] << currLen;
else if(dTileY == 1)
glyphRow = glyphRows[row + (half * 4) - startY + 8] << currLen;
canvasRow |= glyphRow;
endingTile |= canvasRow << (8 * row);
}
Tiles[0][tileIndex + half] = endingTile;
}
}
}
void copyTilesCast(int Tiles[SIDE_BUFFER_SIZE + 1][4], int indexMatrix)
{
for(int i = 0; i < 4; i++)
Tiles[0][i] = Tiles[indexMatrix][i];
}
void setTilesToBlankCast(int *Tiles)
{
for(int i = 0; i < 4; i++)
Tiles[i] = 0;
}
void printCastTiles(int Tiles[4], unsigned short *arrangements, int *graphics, unsigned short tileValue)
{
//Converts what is written in 1bpp in the Tiles buffer to graphics and arrangements
int value;
int currTile;
for(int i = 0; i < 2; i++)
{
arrangements[(i << 5)] = PALETTE | (tileValue + (i << 5));
for(int k = 0; k < 2; k++)
{
currTile = Tiles[k + (i * 2)];
for(int j = 0; j < 4; j++)
graphics[(i << 8) + (k << 2) + j] = m2_bits_to_nybbles_fast_cast[((currTile >> (j * 8)) & 0xFF)];
}
}
}
int getCharWidthCast(byte chr)
{
//Gets the length for a character. Also handles special cases
switch(chr)
{
case END:
return 0;
case PC_START:
case PC_START+1:
case PC_START+2:
case PC_START+3:
return getPCWidthCast(pc_names+(chr-PC_START)*(PC_NAME_SIZE + 2), PC_NAME_SIZE);
case PC_START+4:
return getPCWidthCast(pc_names+(chr-PC_START)*(PC_NAME_SIZE + 2), DOG_NAME_SIZE);
default:
return m2_widths_table[CAST_FONT][chr] & 0xFF;
}
}
int getPCWidthCast(byte* pc_ptr, int max_size)
{
//Gets the length for a playable character's name.
//This is separate in order to avoid recursive issues caused by user's tinkering
int length = 0;
byte chr;
for(int i = 0; i < max_size; i++)
{
chr = *(pc_ptr+i+1);
if(chr == 0xFF)
return length;
chr = decode_character(*(pc_ptr+i));
length += m2_widths_table[CAST_FONT][chr] & 0xFF;
}
return length;
}

41
src/c/credits.h Normal file
View File

@ -0,0 +1,41 @@
#ifndef HEADER_CREDITS_INCLUDED
#define HEADER_CREDITS_INCLUDED
#include "types.h"
#include "locs.h"
#define PLAYER_NAME_SIZE 24
#define CAST_FONT 0
#define CAST_FONT_WIDTH 2
#define CAST_FONT_HEIGHT 2
#define SIDE_BUFFER_SIZE 2
#define START_Y 2
#define END_ALL 0xFF
#define END 0xFE
#define PC_START 0xF9
#define PC_NAME_SIZE 5
#define DOG_NAME_SIZE 6
#define BASE_GRAPHICS_ADDRESS 0x6000000
#define PALETTE 0xF000
void printPlayerNameCredits(unsigned short *arrangements);
void writeCastText(unsigned short *bg0Arrangements, unsigned short *bg1Arrangements);
int getCharWidthCast(byte chr);
int getPCWidthCast(byte* pc_ptr, int max_size);
void setTilesToBlankCast(int *Tiles);
void printCastTiles(int Tiles[4], unsigned short *arrangements, int *graphics, unsigned short tileValue);
int readCastCharacter(byte chr, int Tiles[SIDE_BUFFER_SIZE + 1][4], unsigned short *arrangements, int x, int tile_y, unsigned short *lastEdited);
int readCastCharacterName(byte* str, int Tiles[SIDE_BUFFER_SIZE + 1][4], unsigned short *arrangements, int x, int tile_y, int max_size, unsigned short *lastEdited);
void printCastCharacterInMultiTiles(int Tiles[SIDE_BUFFER_SIZE + 1][4], byte *glyphRows, int glyphLen, int currLen);
void printCastCharacterInSingleTiles(int Tiles[SIDE_BUFFER_SIZE + 1][4], byte *glyphRows, int glyphLen, int currLen);
void copyTilesCast(int Tiles[SIDE_BUFFER_SIZE + 1][4], int indexMatrix);
int printCastCharacter(byte chr, int Tiles[SIDE_BUFFER_SIZE + 1][4], unsigned short *arrangements, int x, int tile_y, unsigned short *lastEdited);
extern byte m2_player1[];
extern byte cast_vwf_names[];
extern unsigned short m2_cast_vwf_free;
extern unsigned short m2_credits_conversion_table[];
extern unsigned short m2_credits_extras[];
extern int m2_bits_to_nybbles_fast_cast[];
#endif

547
src/c/equip.c Normal file
View File

@ -0,0 +1,547 @@
#include "window.h"
#include "equip.h"
#include "number-selector.h"
#include "locs.h"
int equipReadInput(WINDOW* window) //Returns the character whose window we're going in, ACTION_NONE if nothing happens or ACTION_STEPOUT if going out of this window
{
unsigned short previousCharacter = *active_window_party_member;
int currentCharacter = previousCharacter;
PAD_STATE state = *pad_state;
PAD_STATE state_shadow = *pad_state_shadow;
bool printed = false; //Used to avoid sound issues. If we printed, we don't make sounds
if(state.right && !window->hold)
currentCharacter += 1;
if(state.left && !window->hold)
currentCharacter -= 1;
if((state.left || state.right) && !window->hold)
{
window->unknown7 = 0;
if(state.left)
{
if(currentCharacter < 0)
currentCharacter = 3;
int foundChar = currentCharacter;
for(int i = 0; i < 4; i++)
{
if (foundChar < 0)
foundChar = 3;
if ((*pc_flags)[foundChar])
break;
foundChar--;
}
currentCharacter = foundChar;
}
else
{
if(currentCharacter > 3)
currentCharacter = 0;
int foundChar = currentCharacter;
for(int i = 0; i < 4; i++)
{
if (foundChar > 3)
foundChar = 0;
if ((*pc_flags)[foundChar])
break;
foundChar++;
}
currentCharacter = foundChar;
}
(*active_window_party_member) = currentCharacter;
if(currentCharacter != previousCharacter) //Print only if needed
{
equipPrint(window);
printed = true;
}
}
if(state_shadow.right || state_shadow.left)
{
if(state.right || state.left)
{
if(currentCharacter != previousCharacter)
m2_soundeffect(0x131);
}
window->hold = true;
}
else
window->hold = false;
if(state.b || state.select)
{
if(!printed)
m2_soundeffect(0x12E);
window->counter = 0;
return ACTION_STEPOUT;
}
else if(state.a || state.l)
{
if(!printed)
m2_soundeffect(0x12D);
if((*pc_count) > 1)
{
unsigned short *arrangementBase = (*tilemap_pointer) + (((window->window_y - 1) << 5) + window->window_x + window->window_width - 4);
unsigned short topTile = ((*tile_offset) + 0x96) | (*palette_mask) | 0x800;
(*arrangementBase) = topTile;
(*(arrangementBase + 1)) = topTile;
(*(arrangementBase + 2)) = topTile;
(*(arrangementBase + 3)) = topTile;
}
window->counter = 0;
return 1;
}
window->counter++;
if (*pc_count > 1)
{
// We're doing a bit of simplification here.
// The Japanese version tries to highlight the arrow you pressed.
// It only shows for a couple frames and it looks weird, so we're
// just going to show the arrows and not bother with the direction indicator.
draw_window_arrows(window, window->counter < 8);
}
if (window->counter > 16)
window->counter = 0;
return ACTION_NONE;
}
void equippablePrint(WINDOW* window) //Prints equippable items (The innermost equip window)
{
unsigned short savedValue = 0;
byte* freeSpace = free_strings_pointers[3];
byte *none = m2_strlookup((int*)0x8B17EE4, (byte*)0x8B17424, 0x2C);
PC *character_data = &(m2_ness_data[*active_window_party_member]);
unsigned short* something = (unsigned short*)0x3005224;
unsigned short* something2 = (unsigned short*)0x300522C;
for(int i = 0; i < 7; i++)
freeSpace[i] = 0;
freeSpace[7] = 0xFF;
int* headerAddress = (int*)(((int)vram) + ((*something2) << 0xE) + ((*tile_offset) << 5));
map_tile(0xB3, window->window_x, window->window_y - 1);
unsigned short val = *something;
if(!window->vwf_skip)
clear_window_header(headerAddress, 8, 0x10, 0x11);
unsigned short* lastUsed = print_equip_header(*something, (unsigned short*)((*tilemap_pointer) + (((window->window_y - 1) << 5) + window->window_x + 1)), headerAddress, window);
window->vwf_skip = true;
if(window->cursor_x > 6) //Mode which prints only 5 items in M12. Used if one has more than 8 items of an equippable kind.
{
clearWindowTiles_buffer(window);
short counter = 0;
while(counter < 5)
{
int value = (window->cursor_x_base * 5) + counter;
byte equippables;
if(value <= 0xD)
equippables = *(window->number_text_area + 4 + value);
else
equippables = 0xFF;
if(equippables == 0xFF)
{
freeSpace[counter] = 0xFD;
printstr_buffer(window, none, 1, counter, false);
break;
}
else
{
byte *item = m2_strlookup((int*)0x8B1AF94, (byte*)0x8B1A694, character_data->goods[equippables - 1]);
byte x = 1;
if(m2_isequipped(equippables))
{
map_special_character(0x1DE,(window->window_x + 1), (counter << 1) + 1); //Print the E
x++;
}
printstr_buffer(window, item, x, counter, false);
freeSpace[counter] = equippables;
counter++;
}
}
byte* str = NULL;
switch(val)
{
case 3:
str = m12_other_str9; //->Weapons
break;
case 4:
str = m12_other_str10; //->Body
break;
case 5:
str = m12_other_str11; //->Arms
break;
case 6:
str = m12_other_str12; //->Other
break;
default:
break;
}
if(str != NULL)
savedValue = printstr_buffer(window, str, 1, 6, false); //Prints the string, savedValue is used to understand where to print "(X)"
int tmp = m2_div(window->cursor_x, 5);
str = NULL;
if(tmp <= window->cursor_x_base)
str = m2_strlookup((int*)0x8B17EE4, (byte*)0x8B17424, 0x8C);
else
str = m2_strlookup((int*)0x8B17EE4, (byte*)0x8B17424, 0x8D + window->cursor_x_base);
printstr_hlight_pixels_buffer(window, str, savedValue, 6 << 4, false); //Prints "(X)"
freeSpace[5] = 0;
freeSpace[6] = 0xFE;
freeSpace[7] = 0xFF;
}
else //Prints up to 7 equippable items. It's the same as the above cycle, without the cursor_x_base stuff.
{
short counter = 0;
while(counter < 7)
{
byte equippables = *(window->number_text_area + 4 + counter);
if(equippables == 0xFF)
{
freeSpace[counter] = 0xFD;
freeSpace[counter + 1] = 0xFF; //Different from the cycle above
printstr_buffer(window, none, 1, counter, false);
break;
}
else
{
byte *item = m2_strlookup((int*)0x8B1AF94, (byte*)0x8B1A694, character_data->goods[equippables - 1]);
byte x = 1;
if(m2_isequipped(equippables))
{
map_special_character(0x1DE,(window->window_x + 1), (counter << 1) + 1); //Print the E
x++;
}
printstr_buffer(window, item, x, counter, false);
freeSpace[counter] = equippables;
counter++;
}
}
}
window->loaded_code = 0;
}
int equippableReadInput(WINDOW* window) //Manages input in equipment-choice innermost window. Returns the equippable item the cursor is on or ACTION_STEPOUT
{
byte* freeSpace = free_strings_pointers[3];
PC *character_data = &(m2_ness_data[*active_window_party_member]);
bool printed = (window->loaded_code == 1);
// Get weird sign height value
unsigned short height = window->window_height;
unsigned int height_sign_bit = height >> 15;
unsigned int weird_value = (((height + height_sign_bit) << 15) >> 16);
// Clear cursor tiles
map_tile(0x1FF, window->window_x, window->window_y + window->cursor_y * 2);
map_tile(0x1FF, window->window_x, window->window_y + window->cursor_y * 2 + 1);
if(window->loaded_code == 1) //We're printing
equippablePrint(window);
PAD_STATE state = *pad_state;
PAD_STATE state_shadow = *pad_state_shadow;
unsigned short possibleEquippablesCount = window->cursor_x;
short previousY = window->cursor_y;
short currentY = window->cursor_y;
int counter = 0;
//Loads the total amount of items
if(possibleEquippablesCount > 6)
counter = 7;
else if(weird_value > 0)
while(counter < weird_value && freeSpace[counter] != 0xFF)
counter++;
if(state.up)
{
currentY--;
if(currentY < 0)
{
if(window->hold)
currentY = 0;
else
currentY = counter - 1;
}
else
while(freeSpace[currentY] == 0)
currentY--;
}
if(state.down)
{
currentY++;
if(currentY >= counter)
{
if(window->hold)
currentY = counter - 1;
else
currentY = 0;
}
else
while(freeSpace[currentY] == 0)
currentY++;
}
if(state_shadow.up || state_shadow.down)
{
window->counter = 0;
if(previousY != currentY)
m2_soundeffect(0x12F);
window->hold = true;
window->cursor_y = currentY;
}
else
window->hold = false;
if(state.b || state.select)
{
window->counter = 0;
m2_soundeffect(0x12E);
return ACTION_STEPOUT;
}
if((state.a || state.l) && !printed) //Avoid sound issues when going into the window
{
window->counter = 0xFFFF;
if(freeSpace[window->cursor_y] == 0xFE)
{
m2_soundeffect(0x12D); //Do the sound only if we're changing the page. Otherwise the original code will do the appropriate sound
window->counter = 0;
window->cursor_x_base++;
if(m2_div(window->cursor_x, 5) < window->cursor_x_base)
window->cursor_x_base = 0;
return 0xFE; //Change window counter
}
if(window->cursor_y + 1 < counter)
return freeSpace[window->cursor_y]; //Equipment
return 0xFD; //None
}
if (window->counter != 0xFFFF)
{
window->counter++;
// Draw cursor for current item
map_special_character((window->counter <= 7) ? 0x99 : 0x9A,
window->window_x,
window->window_y + window->cursor_y * 2);
if (window->counter > 0x10)
window->counter = 0;
}
if(window->cursor_y + 1 < counter)
return freeSpace[window->cursor_y];
return 0xFD; //None
}
//Simplified inner equip routine (The original routine had a pointer to a table of valid cursor positions as a parameter)
int innerEquipInput(WINDOW* window)
{
bool printing = !window->vwf_skip;
window->vwf_skip = true;
PAD_STATE state = *pad_state;
PAD_STATE state_shadow = *pad_state_shadow;
short previousY = window->cursor_y;
short currentY = window->cursor_y;
// Clear cursor tiles
map_tile(0x1FF, window->window_x, window->window_y + window->cursor_y * 2);
map_tile(0x1FF, window->window_x, window->window_y + window->cursor_y * 2 + 1);
if(state.up) //This has been simplified
{
currentY--;
if(currentY < 0)
{
if(window->hold)
currentY = 0;
else
currentY = 3;
}
}
if(state.down) //This has been simplified
{
currentY++;
if(currentY >= 4)
{
if(window->hold)
currentY = 3;
else
currentY = 0;
}
}
//The game does stuff when pressing left or right, however for the equipment window this is not needed
if(state.right) //This routine in particular did both the main overworld window and the inner equip window
{
}
if(state.left)
{
}
if(state_shadow.up || state_shadow.down)
{
window->counter = 0;
if(previousY != currentY)
m2_soundeffect(0x12F);
window->hold = true;
window->cursor_y = currentY;
}
else
window->hold = false;
if((state.b || state.select) && (!printing))
{
window->counter = 0;
m2_soundeffect(0x12E);
window->vwf_skip = false;
return ACTION_STEPOUT;
}
if((state.a || state.l) && (!printing))
{
window->counter = 0xFFFF;
m2_soundeffect(0x12D);
window->vwf_skip = false;
return (window->cursor_y << 1) + ACTION_STEPIN;
}
if (window->counter != 0xFFFF)
{
window->counter++;
// Draw cursor
map_special_character((window->counter <= 7) ? 0x99 : 0x9A,
window->window_x,
window->window_y + window->cursor_y * 2);
if (window->counter > 0x10)
window->counter = 0;
}
return ACTION_NONE;
}
void equipPrint(WINDOW* window) //Prints equipment
{
m2_hpwindow_up(*active_window_party_member);
// Draw window header
map_tile(0xB3, window->window_x, window->window_y - 1);
clear_name_header(window);
copy_name_header(window, *active_window_party_member);
PC *character_data = &(m2_ness_data[*active_window_party_member]);
byte *nothing = m2_strlookup((int*)0x8B17EE4, (byte*)0x8B17424, 0x2A);
byte *item;
//Clear the previous equipment
print_blankstr_buffer(window->window_x + 6, 1, 0xC, (byte*)(OVERWORLD_BUFFER - ((*tile_offset) * TILESET_OFFSET_BUFFER_MULTIPLIER)));
print_blankstr_buffer(window->window_x + 6, 3, 0xC, (byte*)(OVERWORLD_BUFFER - ((*tile_offset) * TILESET_OFFSET_BUFFER_MULTIPLIER)));
print_blankstr_buffer(window->window_x + 6, 5, 0xC, (byte*)(OVERWORLD_BUFFER - ((*tile_offset) * TILESET_OFFSET_BUFFER_MULTIPLIER)));
print_blankstr_buffer(window->window_x + 6, 7, 0xC, (byte*)(OVERWORLD_BUFFER - ((*tile_offset) * TILESET_OFFSET_BUFFER_MULTIPLIER)));
//Clear the previous numbers
print_blankstr_buffer(8, 0xB, 0x8, (byte*)(OVERWORLD_BUFFER - ((*tile_offset) * TILESET_OFFSET_BUFFER_MULTIPLIER)));
print_blankstr_buffer(8, 0xD, 0x8, (byte*)(OVERWORLD_BUFFER - ((*tile_offset) * TILESET_OFFSET_BUFFER_MULTIPLIER)));
//Reprint the ":"s
print_character_with_callback_1bpp_buffer(decode_character(0x6A), ((window->window_x + 6) << 3), (0x1 << 3), (byte*)(OVERWORLD_BUFFER - ((*tile_offset) * TILESET_OFFSET_BUFFER_MULTIPLIER)), &get_tile_number_with_offset, 0, *tilemap_pointer, 32, 0xC);
print_character_with_callback_1bpp_buffer(decode_character(0x6A), ((window->window_x + 6) << 3), (0x3 << 3), (byte*)(OVERWORLD_BUFFER - ((*tile_offset) * TILESET_OFFSET_BUFFER_MULTIPLIER)), &get_tile_number_with_offset, 0, *tilemap_pointer, 32, 0xC);
print_character_with_callback_1bpp_buffer(decode_character(0x6A), ((window->window_x + 6) << 3), (0x5 << 3), (byte*)(OVERWORLD_BUFFER - ((*tile_offset) * TILESET_OFFSET_BUFFER_MULTIPLIER)), &get_tile_number_with_offset, 0, *tilemap_pointer, 32, 0xC);
print_character_with_callback_1bpp_buffer(decode_character(0x6A), ((window->window_x + 6) << 3), (0x7 << 3), (byte*)(OVERWORLD_BUFFER - ((*tile_offset) * TILESET_OFFSET_BUFFER_MULTIPLIER)), &get_tile_number_with_offset, 0, *tilemap_pointer, 32, 0xC);
//Print the equipment
if(character_data->equipment[0] == 0) //Weapon
print_string_in_buffer(nothing, (((window->window_x + 7)) << 3) - 2, (0x1) << 3, (byte*)(OVERWORLD_BUFFER - ((*tile_offset) * TILESET_OFFSET_BUFFER_MULTIPLIER)));
else
{
item = m2_strlookup((int*)0x8B1AF94, (byte*)0x8B1A694, character_data->goods[character_data->equipment[0] - 1]);
map_special_character(0x1DE,(window->window_x + 7), 0x1); //Print the E
printstr_buffer(window, item, 8, 0, false);
}
if(character_data->equipment[1] == 0) //Body
print_string_in_buffer(nothing, (((window->window_x + 7)) << 3) - 2, (0x3) << 3, (byte*)(OVERWORLD_BUFFER - ((*tile_offset) * TILESET_OFFSET_BUFFER_MULTIPLIER)));
else
{
item = m2_strlookup((int*)0x8B1AF94, (byte*)0x8B1A694, character_data->goods[character_data->equipment[1] - 1]);
map_special_character(0x1DE,(window->window_x + 7), 0x3); //Print the E
printstr_buffer(window, item, 8, 1, false);
}
if(character_data->equipment[2] == 0) //Arms
print_string_in_buffer(nothing, (((window->window_x + 7)) << 3) - 2, (0x5) << 3, (byte*)(OVERWORLD_BUFFER - ((*tile_offset) * TILESET_OFFSET_BUFFER_MULTIPLIER)));
else
{
item = m2_strlookup((int*)0x8B1AF94, (byte*)0x8B1A694, character_data->goods[character_data->equipment[2] - 1]);
map_special_character(0x1DE,(window->window_x + 7), 0x5); //Print the E
printstr_buffer(window, item, 8, 2, false);
}
if(character_data->equipment[3] == 0) //Other
print_string_in_buffer(nothing, (((window->window_x + 7)) << 3) - 2, (0x7) << 3, (byte*)(OVERWORLD_BUFFER - ((*tile_offset) * TILESET_OFFSET_BUFFER_MULTIPLIER)));
else
{
item = m2_strlookup((int*)0x8B1AF94, (byte*)0x8B1A694, character_data->goods[character_data->equipment[3] - 1]);
map_special_character(0x1DE,(window->window_x + 7), 0x7); //Print the E
printstr_buffer(window, item, 8, 3, false);
}
}
//Prints the numbers in the window in a formatted way
void printNumberEquip(WINDOW* window, byte* str, unsigned short x, unsigned short y, bool highlight)
{
while((*str) == 0x50)
{
x += 6;
str++;
}
printstr_hlight_pixels_buffer(window, str, x, y, highlight);
}
//Prints Offense: and Defense:
void printEquipWindowNumberText(WINDOW* window)
{
handle_first_window_buffer(window, (byte*)(OVERWORLD_BUFFER - ((*tile_offset) * TILESET_OFFSET_BUFFER_MULTIPLIER)));
printstr_hlight_pixels_buffer(window, window->text_start, 0, 3, false);
}
//Prints the arrow for the numbers in the Offense/Defense menu
void printEquipNumbersArrow(WINDOW* window)
{
printTinyArrow((window->window_x + 9) << 3, (window->window_y + 0) << 3);
printTinyArrow((window->window_x + 9) << 3, (window->window_y + 2) << 3);
}

20
src/c/equip.h Normal file
View File

@ -0,0 +1,20 @@
#ifndef HEADER_EQUIP_INCLUDED
#define HEADER_EQUIP_INCLUDED
#include "vwf.h"
void equipPrint(WINDOW* window);
int equipReadInput(WINDOW* window);
void equippablePrint(WINDOW* window);
int equippableReadInput(WINDOW* window);
int innerEquipInput(WINDOW* window);
void printEquipWindowNumberText(WINDOW* window);
void printEquipNumbersArrow(WINDOW* window);
extern byte m12_other_str9[];
extern byte m12_other_str10[];
extern byte m12_other_str11[];
extern byte m12_other_str12[];
#endif

View File

@ -1,7 +1,9 @@
#include "window.h"
void __attribute__((naked)) cpufastset(void *source, void *dest, int mode) {}
void __attribute__((naked)) cpuset(void *source, void *dest, int mode) {}
byte* __attribute__((naked)) m2_strlookup(int *offset_table, byte *strings, int index) {}
unsigned short* __attribute__((naked)) m2_get_hall_address() {}
int __attribute__((naked)) bin_to_bcd(int value, int* digit_count) {}
int __attribute__((naked)) m2_drawwindow(WINDOW* window) {}
int __attribute__((naked)) m2_resetwindow(WINDOW* window, bool skip_redraw) {}
@ -20,5 +22,9 @@ int __attribute__((naked)) m2_clearwindowtiles(WINDOW* window) {}
int __attribute__((naked)) customcodes_parse_generic(int code, char* parserAddress, WINDOW* window, int* dest) {}
void __attribute__((naked)) m2_printstr(WINDOW* window, byte* str, unsigned short x, unsigned short y, bool highlight) {}
void __attribute__((naked)) m2_setupbattlename(short value) {}
void __attribute__((naked)) store_pixels_overworld() {}
void __attribute__((naked)) m12_dim_palette(short* palette, int total, int dimmingFactor) {}
int __attribute__((naked)) m2_jump_to_offset(byte* character) {}
byte* __attribute__((naked)) m2_malloc(int size) {}
void __attribute__((naked)) m2_title_teardown() {}
void __attribute__((naked)) vblank() {}

View File

@ -34,6 +34,44 @@ void clear_rect_file(int x, int y, int width, int height, int pixels, unsigned s
}
}
void set_background_loaded_names()
{
set_names_to_default_background(THING_NAME_LENGTH,
set_names_to_default_background(FOOD_NAME_LENGTH,
set_names_to_default_background(DOG_NAME_LENGTH,
set_names_to_default_background(POO_NAME_LENGTH,
set_names_to_default_background(JEFF_NAME_LENGTH,
set_names_to_default_background(PAULA_NAME_LENGTH,
set_names_to_default_background(NESS_NAME_LENGTH, pc_names)))))));
}
byte* set_names_to_default_background(int maxLetters, byte *source)
{
//Reads a name and sets the bytes after it to a fixed value
int i = 0;
while(i < maxLetters + 2 && (*source) != 0xFF)
{
source++;
i++;
}
source++;
i++;
for(; i < maxLetters + 2; i++)
*(source++) = 0;
return source;
}
void copy_name_perm_mem(int maxLetters, byte *source, byte *destination)
{
//Copies the names to perm memory, but also makes the background of them a fixed value
for(int i = 0; i < maxLetters + 2; i++)
destination[i] = 0;
byte *finalSource = source + maxLetters;
while(source < finalSource && (*source) != 0xFF)
(*destination++) = (*source++);
*(destination + 1) = 0xFF;
}
unsigned short* getTilesetDest(int window_selector, int *width)
{
int *tilesetBasePtr = (int *)(0x82B79B4 + (window_selector * 20));

View File

@ -4,6 +4,14 @@
#include "types.h"
#include "vwf.h"
#define NESS_NAME_LENGTH 5
#define PAULA_NAME_LENGTH 5
#define JEFF_NAME_LENGTH 5
#define POO_NAME_LENGTH 5
#define DOG_NAME_LENGTH 6
#define FOOD_NAME_LENGTH 6
#define THING_NAME_LENGTH 6
typedef struct FILE_SELECT {
short status; // 0 = used, -1 = empty
short slot; // 0-2
@ -31,6 +39,9 @@ typedef struct FILE_SELECT {
int get_tile_number_file_select(int x, int y);
void clear_tile_file(int x, int y, int pixels);
void clear_rect_file(int x, int y, int width, int height, int pixels, unsigned short *tilesetDestPtr);
void set_background_loaded_names();
byte* set_names_to_default_background(int maxLetters, byte *source);
void copy_name_perm_mem(int maxLetters, byte *source, byte *destination);
unsigned short* getTilesetDest(int window_selector, int *width);
unsigned short getPaletteFromFileWindow(int x, int y, int window_selector);
void setPaletteToFileWindow(int x, int y, int window_selector, unsigned short palette);

View File

@ -110,14 +110,15 @@ int goods_outer_process(WINDOW* window, int y_offset, bool give)
}
*active_window_party_member = current_pc;
m2_hpwindow_up(current_pc);
clear_name_header(window);
copy_name_header(window, current_pc);
// Print item names
if (!window->vwf_skip)
{
goods_print_items(window, current_items, y_offset);
m2_hpwindow_up(current_pc); //Why were these done repeatedly? I made it so they're done only when printing, however if there is a reason why they shouldn't, feel free to put them back
clear_name_header(window);
copy_name_header(window, current_pc);
store_pixels_overworld();
window->vwf_skip = true;
}
@ -417,10 +418,13 @@ int goods_inner_process(WINDOW *window, unsigned short *items)
clear_name_header(window);
copy_name_header(window, *active_window_party_member);
m2_clearwindowtiles(window);
clearWindowTiles_buffer(window);
if (weird_value > 0)
{
goods_print_items(window, items, 0);
store_pixels_overworld();
}
}
if (state_shadow.up || state_shadow.down || state_shadow.left || state_shadow.right)
@ -479,6 +483,7 @@ int goods_inner_process(WINDOW *window, unsigned short *items)
// Erases the slot before printing. Prints blanks for null items.
void goods_print_items(WINDOW *window, unsigned short *items, int y_offset)
{
byte* dest = (byte*)(OVERWORLD_BUFFER - ((*tile_offset) * TILESET_OFFSET_BUFFER_MULTIPLIER));
int item_x = (window->window_x << 3) + 8;
int item_y = (window->window_y + y_offset) << 3;
@ -488,7 +493,7 @@ void goods_print_items(WINDOW *window, unsigned short *items, int y_offset)
int x = item_x + ((i & 1) * 88);
int y = item_y + ((i >> 1) * 16);
print_blankstr(x >> 3, y >> 3, 11);
print_blankstr_buffer(x >> 3, y >> 3, 11, dest);
if (item > 0)
{
@ -501,7 +506,7 @@ void goods_print_items(WINDOW *window, unsigned short *items, int y_offset)
}
byte *item_str = m2_strlookup(m2_items_offsets, m2_items_strings, item);
print_string(item_str, x + x_offset, y);
print_string_in_buffer(item_str, x + x_offset, y, dest);
}
}
}
@ -534,27 +539,29 @@ void shop_print_items(WINDOW *window, unsigned char *items, int y_offset, int it
{
int x_offset = 0;
byte *item_str = m2_strlookup(m2_items_offsets, m2_items_strings, item);
print_string(item_str, x + x_offset, y);
print_string_in_buffer(item_str, x + x_offset, y, (byte*)(OVERWORLD_BUFFER - ((*tile_offset) * TILESET_OFFSET_BUFFER_MULTIPLIER)));
int digit_count;
int bcd = bin_to_bcd(getPrice(item), &digit_count); //Get the price in bcd, so it can be printed
int base = 120;
print_character(decode_character(0x56), x + base, y); //00, it will be at the end, always at the same position
print_character(decode_character(0x54), x + base - 6 - (digit_count * 6), y); //dollar, it must be before all digits
print_character_formatted_buffer(decode_character(0x56), x + base, y, 0, 0xF, (byte*)(OVERWORLD_BUFFER - ((*tile_offset) * TILESET_OFFSET_BUFFER_MULTIPLIER))); //00, it will be at the end, always at the same position
print_character_formatted_buffer(decode_character(0x54), x + base - 6 - (digit_count * 6), y, 0, 0xF, (byte*)(OVERWORLD_BUFFER - ((*tile_offset) * TILESET_OFFSET_BUFFER_MULTIPLIER))); //dollar, it must be before all digits
// Write the digits
for (int j = 0; j < digit_count; j++)
{
byte digit = ((bcd >> ((digit_count - 1 - j) * 4)) & 0xF) + ZERO;
print_character(decode_character(digit), x + base - 6 - ((digit_count - j - 1) * 6), y); //write a single digit
print_character_formatted_buffer(decode_character(digit), x + base - 6 - ((digit_count - j - 1) * 6), y, 0, 0xF, (byte*)(OVERWORLD_BUFFER - ((*tile_offset) * TILESET_OFFSET_BUFFER_MULTIPLIER))); //write a single digit
}
}
}
store_pixels_overworld();
}
//Load proper give text into str and then go to it
//It's based on the party's status, whether the target's inventory is full or not and whether the source is the target
void give_print(byte item, byte target, byte source, WINDOW *window, byte *str)
{
bool notFullInventory = false;
bool fullInventory = true;
int index;
struct PC *user_data = (&m2_ness_data[source]);
struct PC *target_data = (&m2_ness_data[target]);
@ -564,507 +571,121 @@ void give_print(byte item, byte target, byte source, WINDOW *window, byte *str)
for(index = 0; index < 0xE; index++)
if(target_data->goods[index] == 0)
{
notFullInventory = true;
fullInventory = false;
break;
}
if((user_data->ailment == UNCONSCIOUS) ||(user_data->ailment == DIAMONDIZED))
incapable_user = true;
if((target_data->ailment == UNCONSCIOUS) ||(target_data->ailment == DIAMONDIZED))
incapable_target = true;
index = 0;
if(source == target)
{
if(incapable_user)
setupSelf_Dead(str, &index, source, item);
readStringGive(str, give_strings_table[SELF_DEAD], source, target, item);
else
setupSelf_Alive(str, &index, source, item);
readStringGive(str, give_strings_table[SELF], source, target, item);
}
else if(!notFullInventory)
else if(fullInventory)
{
if(!incapable_target && !incapable_user)
setupFull_Both_Alive(str, &index, source, target, item);
readStringGive(str, give_strings_table[ALIVE_BOTH_FULL], source, target, item);
else if(incapable_target && incapable_user)
setupFull_Both_Dead(str, &index, source, target, item);
readStringGive(str, give_strings_table[DEAD_FULL], source, target, item);
else if(incapable_target && !incapable_user)
setupFull_Target_Dead(str, &index, source, target, item);
readStringGive(str, give_strings_table[TARGET_DEAD_FULL], source, target, item);
else
setupFull_User_Dead(str, &index, source, target, item);
readStringGive(str, give_strings_table[GIVER_DEAD_FULL], source, target, item);
}
else
{
if(!incapable_target && !incapable_user)
setup_Both_Alive(str, &index, source, target, item);
readStringGive(str, give_strings_table[ALIVE_BOTH], source, target, item);
else if(incapable_target && !incapable_user)
setup_Target_Dead(str, &index, source, target, item);
readStringGive(str, give_strings_table[TARGET_DEAD], source, target, item);
else if(!incapable_target && incapable_user)
setup_User_Dead(str, &index, source, target, item);
readStringGive(str, give_strings_table[GIVER_DEAD], source, target, item);
else
setup_Both_Dead(str, &index, source, target, item);
readStringGive(str, give_strings_table[DEAD], source, target, item);
}
str[index++] = 0x1D;
str[index++] = 0xFF; //END
str[index++] = 0;
str[index++] = 0xFF; //END
window->text_start = str;
window->text_start2 = str;
}
void setupSelf_Alive(byte *String, int *index, byte user, byte item)
void readStringGive(byte *outputString, byte *baseString, byte source, byte target, byte item)
{
char rearranged[] = " rearranged ";
char own[] = " own";
char items[] = " items and the ";
char moved[] = " moved.";
String[(*index)++] = 0x70; //Initial bullet
getCharName(user, String, index);
for (int i = 0; i < (sizeof(rearranged) - 1); i++)
String[(*index)++] = encode_ascii(rearranged[i]);
getPossessive(user, String, index);
for (int i = 0; i < (sizeof(own) - 1); i++)
String[(*index)++] = encode_ascii(own[i]);
String[(*index)++] = 1;
String[(*index)++] = 0xFF; //newline
for (int i = 0; i < (sizeof(items) - 1); i++)
String[(*index)++] = encode_ascii(items[i]);
String[(*index)++] = 1;
String[(*index)++] = 0xFF; //newline
String[(*index)++] = encode_ascii(' '); //Format
String[(*index)++] = encode_ascii(' ');
byte *item_str = m2_strlookup(m2_items_offsets, m2_items_strings, item);
copy_name(String, item_str, index, 0);
for (int i = 0; i < (sizeof(moved) - 1); i++)
String[(*index)++] = encode_ascii(moved[i]);
}
void setupSelf_Dead(byte *String, int *index, byte user, byte item)
{
struct PC *tmp; //Get alive character
byte alive = 0;
while((alive == user))
alive++;
for(int i = alive; i < 4; i++)
while(*baseString != END)
{
tmp = &(m2_ness_data[i]);
if((tmp->ailment != UNCONSCIOUS) && (tmp->ailment != DIAMONDIZED))
{
alive = i;
break;
}
}
char rearranged[] = " rearranged";
char items[] = "'s items and the";
char moved[] = " moved.";
String[(*index)++] = 0x70; //Initial bullet
getCharName(alive, String, index);
for (int i = 0; i < (sizeof(rearranged) - 1); i++)
String[(*index)++] = encode_ascii(rearranged[i]);
String[(*index)++] = 1;
String[(*index)++] = 0xFF; //newline
String[(*index)++] = encode_ascii(' ');
String[(*index)++] = encode_ascii(' '); //Format
getCharName(user, String, index);
for (int i = 0; i < (sizeof(items) - 1); i++)
String[(*index)++] = encode_ascii(items[i]);
String[(*index)++] = 1;
String[(*index)++] = 0xFF; //newline
String[(*index)++] = encode_ascii(' ');
String[(*index)++] = encode_ascii(' '); //Format
byte *item_str = m2_strlookup(m2_items_offsets, m2_items_strings, item);
copy_name(String, item_str, index, 0);
for (int i = 0; i < (sizeof(moved) - 1); i++)
String[(*index)++] = encode_ascii(moved[i]);
}
void setupFull_Both_Alive(byte *String, int *index, byte user, byte target, byte item)
{
char tried[] = " tried to give";
char the[] = " the ";
char to[] = " to ";
char but[] = "but ";
char was[] = " was already";
char carrying[] = " carrying too much stuff.";
String[(*index)++] = 0x70; //Initial bullet
getCharName(user, String, index);
for (int i = 0; i < (sizeof(tried) - 1); i++)
String[(*index)++] = encode_ascii(tried[i]);
String[(*index)++] = 1;
String[(*index)++] = 0xFF; //newline
for (int i = 0; i < (sizeof(the) - 1); i++)
String[(*index)++] = encode_ascii(the[i]);
byte *item_str = m2_strlookup(m2_items_offsets, m2_items_strings, item);
copy_name(String, item_str, index, 0);
String[(*index)++] = 1;
String[(*index)++] = 0xFF; //newline
for (int i = 0; i < (sizeof(to) - 1); i++)
String[(*index)++] = encode_ascii(to[i]);
getCharName(target, String, index);
String[(*index)++] = encode_ascii(',');
String[(*index)++] = 0x2;
String[(*index)++] = 0xFF; //prompt + newline
String[(*index)++] = 0x70; //Initial bullet
for (int i = 0; i < (sizeof(but) - 1); i++)
String[(*index)++] = encode_ascii(but[i]);
getPronoun(target, String, index);
for (int i = 0; i < (sizeof(was) - 1); i++)
String[(*index)++] = encode_ascii(was[i]);
String[(*index)++] = 1;
String[(*index)++] = 0xFF; //newline
for (int i = 0; i < (sizeof(carrying) - 1); i++)
String[(*index)++] = encode_ascii(carrying[i]);
}
void setupFull_Target_Dead(byte *String, int *index, byte user, byte target, byte item)
{
char tried[] = " tried to add";
char the[] = " the ";
char to[] = " to ";
char s_stuff[]= "'s stuff,";
char but[] = "but there was no room for it.";
String[(*index)++] = 0x70; //Initial bullet
getCharName(user, String, index);
for (int i = 0; i < (sizeof(tried) - 1); i++)
String[(*index)++] = encode_ascii(tried[i]);
String[(*index)++] = 1;
String[(*index)++] = 0xFF; //newline
for (int i = 0; i < (sizeof(the) - 1); i++)
String[(*index)++] = encode_ascii(the[i]);
byte *item_str = m2_strlookup(m2_items_offsets, m2_items_strings, item);
copy_name(String, item_str, index, 0);
String[(*index)++] = 1;
String[(*index)++] = 0xFF; //newline
for (int i = 0; i < (sizeof(to) - 1); i++)
String[(*index)++] = encode_ascii(to[i]);
getCharName(target, String, index);
for (int i = 0; i < (sizeof(s_stuff) - 1); i++)
String[(*index)++] = encode_ascii(s_stuff[i]);
String[(*index)++] = 0x2;
String[(*index)++] = 0xFF; //prompt + newline
String[(*index)++] = 0x70; //Initial bullet
for (int i = 0; i < (sizeof(but) - 1); i++)
String[(*index)++] = encode_ascii(but[i]);
}
void setupFull_User_Dead(byte *String, int *index, byte user, byte target, byte item)
{
char tried[] = " tried to take";
char the[] = " the ";
char from[] = " from ";
char s_stuff[]= "'s stuff,";
char but[] = "but ";
char was[] = " was already";
char carrying[] = " carrying too much stuff.";
String[(*index)++] = 0x70; //Initial bullet
getCharName(target, String, index);
for (int i = 0; i < (sizeof(tried) - 1); i++)
String[(*index)++] = encode_ascii(tried[i]);
String[(*index)++] = 1;
String[(*index)++] = 0xFF; //newline
for (int i = 0; i < (sizeof(the) - 1); i++)
String[(*index)++] = encode_ascii(the[i]);
byte *item_str = m2_strlookup(m2_items_offsets, m2_items_strings, item);
copy_name(String, item_str, index, 0);
String[(*index)++] = 1;
String[(*index)++] = 0xFF; //newline
for (int i = 0; i < (sizeof(from) - 1); i++)
String[(*index)++] = encode_ascii(from[i]);
getCharName(user, String, index);
for (int i = 0; i < (sizeof(s_stuff) - 1); i++)
String[(*index)++] = encode_ascii(s_stuff[i]);
String[(*index)++] = 0x2;
String[(*index)++] = 0xFF; //prompt + newline
String[(*index)++] = 0x70; //Initial bullet
for (int i = 0; i < (sizeof(but) - 1); i++)
String[(*index)++] = encode_ascii(but[i]);
getPronoun(target, String, index);
for (int i = 0; i < (sizeof(was) - 1); i++)
String[(*index)++] = encode_ascii(was[i]);
String[(*index)++] = 1;
String[(*index)++] = 0xFF; //newline
for (int i = 0; i < (sizeof(carrying) - 1); i++)
String[(*index)++] = encode_ascii(carrying[i]);
}
void setupFull_Both_Dead(byte *String, int *index, byte user, byte target, byte item)
{
struct PC *tmp; //Get alive character
byte alive = 0;
while((alive == user) || (alive == target))
alive++;
for(int i = alive; i < 4; i++)
{
tmp = &(m2_ness_data[i]);
if((tmp->ailment != UNCONSCIOUS) && (tmp->ailment != DIAMONDIZED))
{
alive = i;
break;
}
outputString = readCharacterGive(outputString, *baseString, source, target, item);
baseString++;
}
char tried[] = " tried to add";
char s_[] = "'s ";
char to[] = " to ";
char s_stuff[]= "'s stuff,";
char but[] = "but there was no room for it.";
String[(*index)++] = 0x70; //Initial bullet
getCharName(alive, String, index);
for (int i = 0; i < (sizeof(tried) - 1); i++)
String[(*index)++] = encode_ascii(tried[i]);
String[(*index)++] = 1;
String[(*index)++] = 0xFF; //newline
String[(*index)++] = encode_ascii(' ');
String[(*index)++] = encode_ascii(' '); //Format
getCharName(user, String, index);
for (int i = 0; i < (sizeof(s_) - 1); i++)
String[(*index)++] = encode_ascii(s_[i]);
byte *item_str = m2_strlookup(m2_items_offsets, m2_items_strings, item);
copy_name(String, item_str, index, 0);
String[(*index)++] = 1;
String[(*index)++] = 0xFF; //newline
for (int i = 0; i < (sizeof(to) - 1); i++)
String[(*index)++] = encode_ascii(to[i]);
getCharName(target, String, index);
for (int i = 0; i < (sizeof(s_stuff) - 1); i++)
String[(*index)++] = encode_ascii(s_stuff[i]);
String[(*index)++] = 0x2;
String[(*index)++] = 0xFF; //prompt + newline
String[(*index)++] = 0x70; //Initial bullet
for (int i = 0; i < (sizeof(but) - 1); i++)
String[(*index)++] = encode_ascii(but[i]);
outputString[0] = 0x1D;
outputString[1] = 0xFF; //END
outputString[2] = 0;
outputString[3] = 0xFF; //END
}
void setup_Both_Alive(byte *String, int *index, byte user, byte target, byte item)
byte *readCharacterGive(byte *outputString, byte chr, byte source, byte target, byte item)
{
char gave[] = " gave";
char the[] = " the ";
char to[] = " to ";
int index = 0; //Index used by multi-characters entries
struct PC *tmp; //Struct to get alive character
byte alive;
byte *item_str; //Item string
String[(*index)++] = 0x70; //Initial bullet
getCharName(user, String, index);
for (int i = 0; i < (sizeof(gave) - 1); i++)
String[(*index)++] = encode_ascii(gave[i]);
String[(*index)++] = 1;
String[(*index)++] = 0xFF; //newline
for (int i = 0; i < (sizeof(the) - 1); i++)
String[(*index)++] = encode_ascii(the[i]);
byte *item_str = m2_strlookup(m2_items_offsets, m2_items_strings, item);
copy_name(String, item_str, index, 0);
String[(*index)++] = 1;
String[(*index)++] = 0xFF; //newline
for (int i = 0; i < (sizeof(to) - 1); i++)
String[(*index)++] = encode_ascii(to[i]);
getCharName(target, String, index);
String[(*index)++] = encode_ascii('.');
}
void setup_Target_Dead(byte *String, int *index, byte user, byte target, byte item)
{
char added[] = " added";
char the[] = " the ";
char to[] = " to ";
char s_stuff[] = "'s stuff.";
String[(*index)++] = 0x70; //Initial bullet
getCharName(user, String, index);
for (int i = 0; i < (sizeof(added) - 1); i++)
String[(*index)++] = encode_ascii(added[i]);
String[(*index)++] = 1;
String[(*index)++] = 0xFF; //newline
for (int i = 0; i < (sizeof(the) - 1); i++)
String[(*index)++] = encode_ascii(the[i]);
byte *item_str = m2_strlookup(m2_items_offsets, m2_items_strings, item);
copy_name(String, item_str, index, 0);
String[(*index)++] = 1;
String[(*index)++] = 0xFF; //newline
for (int i = 0; i < (sizeof(to) - 1); i++)
String[(*index)++] = encode_ascii(to[i]);
getCharName(target, String, index);
for (int i = 0; i < (sizeof(s_stuff) - 1); i++)
String[(*index)++] = encode_ascii(s_stuff[i]);
}
void setup_User_Dead(byte *String, int *index, byte user, byte target, byte item)
{
char took[] = " took";
char the[] = " the ";
char from[] = " from ";
char s_stuff[] = "'s stuff.";
String[(*index)++] = 0x70; //Initial bullet
getCharName(target, String, index);
for (int i = 0; i < (sizeof(took) - 1); i++)
String[(*index)++] = encode_ascii(took[i]);
String[(*index)++] = 1;
String[(*index)++] = 0xFF; //newline
for (int i = 0; i < (sizeof(the) - 1); i++)
String[(*index)++] = encode_ascii(the[i]);
byte *item_str = m2_strlookup(m2_items_offsets, m2_items_strings, item);
copy_name(String, item_str, index, 0);
String[(*index)++] = 1;
String[(*index)++] = 0xFF; //newline
for (int i = 0; i < (sizeof(from) - 1); i++)
String[(*index)++] = encode_ascii(from[i]);
getCharName(user, String, index);
for (int i = 0; i < (sizeof(s_stuff) - 1); i++)
String[(*index)++] = encode_ascii(s_stuff[i]);
}
void setup_Both_Dead(byte *String, int *index, byte user, byte target, byte item)
{
struct PC *tmp; //Get alive character
byte alive = 0;
while((alive == user) || (alive == target))
alive++;
for(int i = alive; i < 4; i++)
switch(chr)
{
tmp = &(m2_ness_data[i]);
if((tmp->ailment != UNCONSCIOUS) && (tmp->ailment != DIAMONDIZED))
{
alive = i;
case PROMPT:
outputString[0] = 2;
outputString[1] = 0xFF;
index = 2;
break;
}
case NEWLINE:
outputString[0] = 1;
outputString[1] = 0xFF;
index = 2;
break;
case TARGET:
getCharName(target, outputString, &index);
break;
case SOURCE:
getCharName(source, outputString, &index);
break;
case ALIVE:
alive = 0;
while((alive == source))
alive++;
for(int i = alive; i < 4; i++)
{
tmp = &(m2_ness_data[i]);
if((tmp->ailment != UNCONSCIOUS) && (tmp->ailment != DIAMONDIZED))
{
alive = i;
break;
}
}
getCharName(alive, outputString, &index);
break;
case TARGET_POSS:
getPossessive(target, outputString, &index);
break;
case SOURCE_POSS:
getPossessive(source, outputString, &index);
break;
case TARGET_PRON:
getPronoun(target, outputString, &index);
break;
case SOURCE_PRON:
getPronoun(source, outputString, &index);
break;
case ITEM:
item_str = m2_strlookup(m2_items_offsets, m2_items_strings, item);
copy_name(outputString, item_str, &index, 0);
break;
default:
outputString[0] = chr + CHAR_OFFSET;
index = 1;
}
char added[] = " added ";
char _s[] = "'s";
char to[] = " to";
char s_stuff[] = "'s stuff.";
String[(*index)++] = 0x70; //Initial bullet
getCharName(alive, String, index);
for (int i = 0; i < (sizeof(added) - 1); i++)
String[(*index)++] = encode_ascii(added[i]);
getCharName(user, String, index);
for (int i = 0; i < (sizeof(_s) - 1); i++)
String[(*index)++] = encode_ascii(_s[i]);
String[(*index)++] = 1;
String[(*index)++] = 0xFF; //newline
String[(*index)++] = encode_ascii(' '); //Format
String[(*index)++] = encode_ascii(' ');
byte *item_str = m2_strlookup(m2_items_offsets, m2_items_strings, item);
copy_name(String, item_str, index, 0);
for (int i = 0; i < (sizeof(to) - 1); i++)
String[(*index)++] = encode_ascii(to[i]);
String[(*index)++] = 1;
String[(*index)++] = 0xFF; //newline
String[(*index)++] = encode_ascii(' '); //Format
String[(*index)++] = encode_ascii(' ');
getCharName(target, String, index);
for (int i = 0; i < (sizeof(s_stuff) - 1); i++)
String[(*index)++] = encode_ascii(s_stuff[i]);
return outputString + index;
}

View File

@ -5,6 +5,29 @@
#include "pc.h"
#include "input.h"
#define SELF 0
#define SELF_DEAD 1
#define ALIVE_BOTH 2
#define GIVER_DEAD 3
#define TARGET_DEAD 4
#define DEAD 5
#define ALIVE_BOTH_FULL 6
#define GIVER_DEAD_FULL 7
#define TARGET_DEAD_FULL 8
#define DEAD_FULL 9
#define END 0xFF
#define PROMPT 0xFE
#define NEWLINE 0xFD
#define TARGET 0xFC
#define SOURCE 0xFB
#define ALIVE 0xFA
#define TARGET_POSS 0xF9
#define SOURCE_POSS 0xF8
#define TARGET_PRON 0xF7
#define SOURCE_PRON 0xF6
#define ITEM 0xF5
typedef enum DIRECTION_MOVED
{
DIRECTION_NONE,
@ -16,19 +39,11 @@ int goods_outer_process(WINDOW* window, int y_offset, bool give);
int goods_inner_process(WINDOW *window, unsigned short *items);
void goods_print_items(WINDOW *window, unsigned short *items, int y_offset);
void shop_print_items(WINDOW *window, unsigned char *items, int y_offset, int itemsnum);
void setupSelf_Alive(byte *String, int *index, byte user, byte item);
void setupSelf_Dead(byte *String, int *index, byte user, byte item);
void setupFull_Both_Alive(byte *String, int *index, byte user, byte target, byte item);
void setupFull_Target_Dead(byte *String, int *index, byte user, byte target, byte item);
void setupFull_User_Dead(byte *String, int *index, byte user, byte target, byte item);
void setupFull_Both_Dead(byte *String, int *index, byte user, byte target, byte item);
void setup_Both_Alive(byte *String, int *index, byte user, byte target, byte item);
void setup_Target_Dead(byte *String, int *index, byte user, byte target, byte item);
void setup_User_Dead(byte *String, int *index, byte user, byte target, byte item);
void setup_Both_Dead(byte *String, int *index, byte user, byte target, byte item);
void give_print(byte item, byte target, byte source, WINDOW *window, byte *str);
void readStringGive(byte *outputString, byte *baseString, byte source, byte target, byte item);
byte *readCharacterGive(byte *outputString, byte chr, byte source, byte target, byte item);
extern bool m2_isequipped(int item_index);
extern void m2_soundeffect(int index);
extern int m2_div(int dividend, int divisor);
extern int m2_sub_a334c(int value);
@ -37,6 +52,7 @@ extern void m2_clearwindowtiles(WINDOW* window);
extern int bin_to_bcd(int value, int* digit_count);
extern int m2_items;
extern byte* give_strings_table[];
extern PC m2_ness_data[];
#endif

301
src/c/luminehall.c Normal file
View File

@ -0,0 +1,301 @@
#include "luminehall.h"
#include "locs.h"
void writeLumineHallText()
{
//Function that writes out the Lumine text in the form of arrangements.
//It adds a VWF to what the base game did
byte *lumineText_curr_ptr = luminetext;
int *hallLineSize = &m2_hall_line_size;
int length = 0;
int currLenInTile = 0;
int currPos = 0;
int Tiles[4];
setTilesToBlankLumine(Tiles);
//First things first, it calculates the total length of the text in pixels
while((*lumineText_curr_ptr) != END)
{
length += getCharWidthLumine(*lumineText_curr_ptr);
lumineText_curr_ptr++;
}
//It then gets the length in arrangements. It also makes sure it's a number divisible by 8.
//This avoids having empty tiles showing
length = (length & 7 == 0 ? length : (length + (8 - (length & 7)))) >> 1;
(*hallLineSize) = length;
lumineText_curr_ptr = luminetext;
unsigned short *hallAddress = m2_get_hall_address();
//Prints out the characters
while((*lumineText_curr_ptr) != END)
{
readLumineCharacter(*lumineText_curr_ptr, Tiles, hallAddress, length, &currPos, &currLenInTile);
lumineText_curr_ptr++;
}
//Avoid having tiles that were not entirely printed
while((currPos*4) < length)
{
printVoidLumineTiles(hallAddress, length, currPos);
currPos++;
}
}
void readLumineCharacter(byte chr, int *Tiles, unsigned short *hallAddress, int length, int *currPos, int *currLen)
{
//Reads a character. Handles special cases.
//The valid characters are printed to the Tiles 1bpp buffer that stores the VWF form of the text.
//This is then converted (when it makes sense to do so) to arrangements by printLumineTiles.
int AlternativeTiles[SIDE_BUFFER_SIZE][4];
switch(chr)
{
case END:
return;
case BLANK:
printEmptyLumineTile(Tiles, hallAddress, length, *currPos, *currLen);
for(int i = 1; i < 8; i++)
printVoidLumineTiles(hallAddress, length, (*currPos) + i);
(*currPos) += 8;
return;
case PC_START:
case PC_START+1:
case PC_START+2:
case PC_START+3:
readLumineCharacterName(pc_names+(chr-PC_START)*(PC_NAME_SIZE + 2), Tiles, AlternativeTiles, hallAddress, length, currPos, currLen);
return;
default:
printLumineCharacter(chr, Tiles, AlternativeTiles, hallAddress, length, currPos, currLen);
}
}
void printLumineCharacter(byte chr, int *Tiles, int AlternativeTiles[SIDE_BUFFER_SIZE][4], unsigned short *hallAddress, int length, int *currPos, int *currLen)
{
//Function that gets a character and then prints it to the Tiles buffer.
//If the buffer is full, it uses the AlternativeTiles side-buffer and then prints Tiles to the arrangements.
//The same happens to any AlternativeTiles side-buffer that gets full
int tileWidth = LUMINE_FONT_WIDTH;
int tileHeight = LUMINE_FONT_HEIGHT;
int chosenLen = m2_widths_table[LUMINE_FONT][chr] & 0xFF;
int renderedLen = m2_widths_table[LUMINE_FONT][chr] >> 8;
byte *glyphRows = &m2_font_table[LUMINE_FONT][chr * tileWidth * tileHeight * 8];
if(chosenLen <= 0)
return;
if(((*currLen) + chosenLen) >= 8)
{
for(int i = 0; i < SIDE_BUFFER_SIZE; i++)
setTilesToBlankLumine(AlternativeTiles[i]);
if(renderedLen > 0)
printLumineCharacterInMultiTiles(Tiles, AlternativeTiles, glyphRows, renderedLen, *currLen);
printLumineTiles(Tiles, hallAddress, length, *currPos);
(*currPos)++;
int fullAlternatives = (((*currLen) + chosenLen) >> 3) - 1;
for(int i = 0; i < fullAlternatives; i++)
{
printLumineTiles(AlternativeTiles[i], hallAddress, length, *currPos);
(*currPos)++;
}
copyTilesLumine(Tiles, AlternativeTiles, fullAlternatives);
(*currLen) = ((*currLen) + chosenLen) & 7;
}
else
{
if(renderedLen > 0)
printLumineCharacterInSingleTiles(Tiles, glyphRows, renderedLen, *currLen);
(*currLen) += chosenLen;
}
}
void printEmptyLumineTile(int *Tiles, unsigned short *hallAddress, int length, int currPos, int currLen)
{
//Prints either an entirely empty tile or what's been done in the current tile
if(currLen == 0)
printVoidLumineTiles(hallAddress, length, currPos);
else
{
printLumineTiles(Tiles, hallAddress, length, currPos);
setTilesToBlankLumine(Tiles);
}
}
void readLumineCharacterName(byte* str, int *Tiles, int AlternativeTiles[SIDE_BUFFER_SIZE][4], unsigned short *hallAddress, int length, int *currPos, int *currLen)
{
//Reads a playable character's name.
//The characters are printed to the Tiles 1bpp buffer that stores the VWF form of the text.
//This is then converted (when it makes sense to do so) to arrangements by printLumineTiles.
//This is separate in order to avoid recursive issues caused by user's tinkering
for(int i = 0; i < PC_NAME_SIZE; i++)
{
if(*(str + 1) == 0xFF)
return;
byte chr = decode_character(*(str++));
printLumineCharacter(chr, Tiles, AlternativeTiles, hallAddress, length, currPos, currLen);
}
}
void printLumineCharacterInMultiTiles(int *Tiles, int AlternativeTiles[SIDE_BUFFER_SIZE][4], byte *glyphRows, int glyphLen, int currLen)
{
//Prints a character to the tiles 1bpp buffer.
//The part that goes beyond the tiles buffer will be printed to the AlternativeTiles buffer
int tileWidth = LUMINE_FONT_WIDTH;
int tileHeight = LUMINE_FONT_HEIGHT;
int startY = START_Y;
for(int dTileY = 0; dTileY < tileHeight; dTileY++)
{
int tileIndex = dTileY * 2;
int renderedWidth = glyphLen;
int currSelected = 0;
int dTileX = 0;
int *currTile = Tiles;
int *currAlt = AlternativeTiles[currSelected];
while(renderedWidth > 0)
{
for(int half = 0; half < 2; half++)
{
int tile = currTile[tileIndex + half];
int alternativeTile = currAlt[tileIndex + half];
int endingTile = 0;
int endingAlternativeTile = 0;
for(int row = 0; row < 4; row++)
{
unsigned short canvasRow = ((tile >> (8 * row))&0xFF) | (((alternativeTile >> (8 * row))&0xFF) << 8);
unsigned short glyphRow = 0;
if(row + (half * 4) - startY >= 0)
glyphRow = glyphRows[row + (half * 4) - startY + (dTileY * 8 * tileWidth) + (dTileX * 8)] << currLen;
else if(dTileY == 1)
glyphRow = glyphRows[row + (half * 4) - startY + 8 + (dTileX * 8)] << currLen;
canvasRow |= glyphRow;
endingTile |= (canvasRow & 0xFF) << (8 * row);
endingAlternativeTile |= ((canvasRow >> 8) & 0xFF) << (8 * row);
}
currTile[tileIndex + half] = endingTile;
currAlt[tileIndex + half] = endingAlternativeTile;
}
renderedWidth -= 8;
currTile = AlternativeTiles[dTileX];
currAlt = AlternativeTiles[dTileX + 1];
dTileX++;
}
}
}
void printLumineCharacterInSingleTiles(int *Tiles, byte *glyphRows, int glyphLen, int currLen)
{
//Prints a character to the tiles 1bpp buffer.
//We know this won't go outside of the buffer's range, so we avoid some checks
int tileWidth = LUMINE_FONT_WIDTH;
int tileHeight = LUMINE_FONT_HEIGHT;
int startY = START_Y;
for(int dTileY = 0; dTileY < tileHeight; dTileY++)
{
int tileIndex = dTileY * 2;
for(int half = 0; half < 2; half++)
{
int tile = Tiles[tileIndex + half];
int endingTile = 0;
for(int row = 0; row < 4; row++)
{
byte canvasRow = ((tile >> (8 * row))&0xFF);
byte glyphRow = 0;
if(row + (half * 4) - startY >= 0)
glyphRow = glyphRows[row + (half * 4) - startY + (dTileY * 8 * tileWidth)] << currLen;
else if(dTileY == 1)
glyphRow = glyphRows[row + (half * 4) - startY + 8] << currLen;
canvasRow |= glyphRow;
endingTile |= canvasRow << (8 * row);
}
Tiles[tileIndex + half] = endingTile;
}
}
}
void copyTilesLumine(int *Tiles, int AlternativeTiles[SIDE_BUFFER_SIZE][4], int indexMatrix)
{
for(int i = 0; i < 4; i++)
Tiles[i] = AlternativeTiles[indexMatrix][i];
}
void setTilesToBlankLumine(int *Tiles)
{
for(int i = 0; i < 4; i++)
Tiles[i] = 0;
}
void printLumineTiles(int *Tiles, unsigned short *hallAddress, int length, int currPos)
{
//Converts what is written in 1bpp in the Tiles buffer to arrangements
unsigned short *start = hallAddress + (currPos * 4);
int currHalfTile;
int value;
for(int k = 0; k < 4; k++)
{
for(int i = 0; i < 2; i++)
{
currHalfTile = (Tiles[k] >> i*16)&0xFFFF;
for(int j = 0; j < 4; j++)
{
value = (currHalfTile&3)+((currHalfTile>>6)&0xC);
start[j] = luminesquaretable[value];
currHalfTile = currHalfTile >> 2;
}
start += length;
}
}
}
void printVoidLumineTiles(unsigned short *hallAddress, int length, int currPos)
{
//Prints empty arrangements fast
unsigned short *start = hallAddress + (currPos*4);
for(int k = 0; k < 4; k++)
{
for(int i = 0; i < 2; i++)
{
for(int j = 0; j < 4; j++)
{
start[j] = luminesquaretable[0];
}
start += length;
}
}
}
int getCharWidthLumine(byte chr)
{
//Gets the length for a character. Also handles special cases
switch(chr)
{
case END:
return 0;
case BLANK:
return BLANK_SIZE;
case PC_START:
case PC_START+1:
case PC_START+2:
case PC_START+3:
return getPCWidthLumine(pc_names+(chr-PC_START)*(PC_NAME_SIZE + 2));
default:
return m2_widths_table[LUMINE_FONT][chr] & 0xFF;
}
}
int getPCWidthLumine(byte* pc_ptr)
{
//Gets the length for a playable character's name.
//This is separate in order to avoid recursive issues caused by user's tinkering
int length = 0;
byte chr;
for(int i = 0; i < PC_NAME_SIZE; i++)
{
chr = *(pc_ptr+i+1);
if(chr == 0xFF)
return length;
chr = decode_character(*(pc_ptr+i));
length += m2_widths_table[LUMINE_FONT][chr] & 0xFF;
}
return length;
}

39
src/c/luminehall.h Normal file
View File

@ -0,0 +1,39 @@
#ifndef HEADER_LUMINE_INCLUDED
#define HEADER_LUMINE_INCLUDED
#include "types.h"
#include "locs.h"
#include "vwf.h"
#define LUMINE_FONT 0
#define LUMINE_FONT_WIDTH 2
#define LUMINE_FONT_HEIGHT 2
#define SIDE_BUFFER_SIZE 2
#define START_Y 2
#define END 0xFF
#define BLANK 0xFE
#define BLANK_SIZE 0x40
#define PC_START 0xFA
#define PC_NAME_SIZE 5
void writeLumineHallText();
int getCharWidthLumine(byte chr);
int getPCWidthLumine(byte* pc_ptr);
void setTilesToBlankLumine(int *Tiles);
void printLumineTiles(int *Tiles, unsigned short *hallAddress, int length, int currPos);
void printVoidLumineTiles(unsigned short *hallAddress, int length, int currPos);
void printEmptyLumineTile(int *Tiles, unsigned short *hallAddress, int length, int currPos, int currLen);
void readLumineCharacter(byte chr, int *Tiles, unsigned short *hallAddress, int length, int *currPos, int *currLen);
void readLumineCharacterName(byte* str, int *Tiles, int AlternativeTiles[SIDE_BUFFER_SIZE][4], unsigned short *hallAddress, int length, int *currPos, int *currLen);
void printLumineCharacterInMultiTiles(int *Tiles, int AlternativeTiles[SIDE_BUFFER_SIZE][4], byte *glyphRows, int glyphLen, int currLen);
void printLumineCharacterInSingleTiles(int *Tiles, byte *glyphRows, int glyphLen, int currLen);
void copyTilesLumine(int *Tiles, int AlternativeTiles[SIDE_BUFFER_SIZE][4], int indexMatrix);
void printLumineCharacter(byte chr, int *Tiles, int AlternativeTiles[SIDE_BUFFER_SIZE][4], unsigned short *hallAddress, int length, int *currPos, int *currLen);
extern unsigned short* m2_get_hall_address();
extern int m2_hall_line_size;
extern byte luminetext[];
extern unsigned short luminesquaretable[];
#endif

View File

@ -24,7 +24,9 @@ typedef enum AILMENT2
typedef enum AILMENT3
{
SLEEP = 1,
CRYING = 2
CRYING = 2,
CANNOT_MOVE = 3,
SOLIDIFIED = 4
} AILMENT3;
typedef enum CHARACTER

View File

@ -135,7 +135,7 @@ void psiPrint_buffer(byte value, WINDOW* window, bool printPSILine, PSIPrintInfo
if(PSIID == 1)
{
str = (byte*)(m2_ness_name + (7 * 4) + (8 * 2)); //Go to Rockin's name
print_string_in_buffer(str, 0x71, ((printInfo->YPrinting) + window->window_y) << 3, (int*)(OVERWORLD_BUFFER - 0x2000));
print_string_in_buffer(str, 0x71, ((printInfo->YPrinting) + window->window_y) << 3, (byte*)(OVERWORLD_BUFFER - ((*tile_offset) * TILESET_OFFSET_BUFFER_MULTIPLIER)));
}
}
@ -455,7 +455,7 @@ int PSITargetInput(WINDOW* window)
if(!window->vwf_skip)
{
clear_window_buffer(getWindow(9), (int*)(OVERWORLD_BUFFER - 0x2000));
clear_window_buffer(getWindow(9), (byte*)(OVERWORLD_BUFFER - ((*tile_offset) * TILESET_OFFSET_BUFFER_MULTIPLIER)));
psiTargetWindow_buffer(target);
window->vwf_skip = true;
}

View File

@ -9,17 +9,17 @@ void printNumberOfStatus(int maxLength, int value, int blankX, int y, int strX,
int end = setNumber_getLength(value, str, maxLength);
str[end] = 0;
str[end + 1] = 0xFF;
print_blankstr_buffer(blankX, y, width, (int*)(OVERWORLD_BUFFER - 0x2000));
print_blankstr_buffer(blankX, y, width, (byte*)(OVERWORLD_BUFFER - ((*tile_offset) * TILESET_OFFSET_BUFFER_MULTIPLIER)));
int x = (strX - (end * 6));
print_string_in_buffer(str, x, y << 3, (int*)(OVERWORLD_BUFFER - 0x2000));
print_string_in_buffer(str, x, y << 3, (byte*)(OVERWORLD_BUFFER - ((*tile_offset) * TILESET_OFFSET_BUFFER_MULTIPLIER)));
}
void printStatusSymbolArrangement(unsigned short symbolTile, WINDOW* window)
{
map_tile(symbolTile, window->window_x + 0xA, window->window_y + 2);
map_tile(symbolTile, window->window_x + 0xA, window->window_y + 2);
if(symbolTile == 0x1FF)
symbolTile -= 0x20;
map_tile(symbolTile + 0x20, window->window_x + 0xA, window->window_y + 3);
map_tile(symbolTile + 0x20, window->window_x + 0xA, window->window_y + 3);
}
void printStatusString(WINDOW* window, int value)
@ -57,7 +57,7 @@ int statusNumbersPrint(WINDOW* window, bool doNotPrint)
printNumberOfStatus(7, experienceLevelUp - character_data->experience, 2, 0xD, 0x3D, 6);
}
else
print_blankstr_buffer(2, 0xD, 6, (int*)(OVERWORLD_BUFFER - 0x2000));
print_blankstr_buffer(2, 0xD, 6, (byte*)(OVERWORLD_BUFFER - ((*tile_offset) * TILESET_OFFSET_BUFFER_MULTIPLIER)));
printNumberOfStatus(3, character_data->offense_effective, 0x19, 0x1, 0xE1, 4);
printNumberOfStatus(3, character_data->defense_effective, 0x19, 0x3, 0xE1, 4);
printNumberOfStatus(3, character_data->speed_effective, 0x19, 0x5, 0xE1, 4);
@ -65,13 +65,13 @@ int statusNumbersPrint(WINDOW* window, bool doNotPrint)
printNumberOfStatus(3, character_data->vitality_effective, 0x19, 0x9, 0xE1, 4);
printNumberOfStatus(3, character_data->iq_effective, 0x19, 0xB, 0xE1, 4);
printNumberOfStatus(3, character_data->luck_effective, 0x19, 0xD, 0xE1, 4);
print_blankstr_buffer(5, 0xF, 0x14, (int*)(OVERWORLD_BUFFER - 0x2000));
print_blankstr_buffer(5, 0xF, 0x14, (byte*)(OVERWORLD_BUFFER - ((*tile_offset) * TILESET_OFFSET_BUFFER_MULTIPLIER)));
if((*active_window_party_member) != JEFF)
{
byte *str = m2_strlookup((int*)0x8B17EE4, (byte*)0x8B17424, 0x13);
print_string_in_buffer(str, 0x2C, (0xF) << 3, (int*)(OVERWORLD_BUFFER - 0x2000));
print_string_in_buffer(str, 0x2C, (0xF) << 3, (byte*)(OVERWORLD_BUFFER - ((*tile_offset) * TILESET_OFFSET_BUFFER_MULTIPLIER)));
}
print_blankstr_buffer(1, 0x3, 0xA, (int*)(OVERWORLD_BUFFER - 0x2000));
print_blankstr_buffer(1, 0x3, 0xA, (byte*)(OVERWORLD_BUFFER - ((*tile_offset) * TILESET_OFFSET_BUFFER_MULTIPLIER)));
unsigned short symbolTile = ailmentTileSetup(&(character_data->ailment), 0);
if(symbolTile == 0)
{
@ -223,18 +223,18 @@ int statusWindowNumbers(WINDOW* window, bool doNotPrint)
int statusWindowText(WINDOW* window)
{
if(window->redraw)
buffer_drawwindow(window, (int*)(OVERWORLD_BUFFER - 0x2000));
buffer_drawwindow(window, (byte*)(OVERWORLD_BUFFER - ((*tile_offset) * TILESET_OFFSET_BUFFER_MULTIPLIER)));
if(window->loaded_code != 0 && ((*script_readability) == 0))
{
window->delay = 0;
while(true)
{
while(window->text_y >= window->window_height || window->window_y + window->text_y > 0x1F)
properScroll(window, (int*)(OVERWORLD_BUFFER - 0x2000));
properScroll(window, (byte*)(OVERWORLD_BUFFER - ((*tile_offset) * TILESET_OFFSET_BUFFER_MULTIPLIER)));
byte *str = window->text_start + window->text_offset;
if((*(str + 1)) == 0xFF)
{
int returnedLength = customcodes_parse_generic(*str, str, window, (int*)(OVERWORLD_BUFFER - 0x2000));
int returnedLength = customcodes_parse_generic(*str, str, window, (byte*)(OVERWORLD_BUFFER - ((*tile_offset) * TILESET_OFFSET_BUFFER_MULTIPLIER)));
if(returnedLength != 0)
{
if(returnedLength < 0)
@ -265,7 +265,7 @@ int statusWindowText(WINDOW* window)
window->text_y += 2;
window->text_x = 0;
}
weld_entry_custom_buffer(window, str, 0, 0xF, (int*)(OVERWORLD_BUFFER - 0x2000));
weld_entry_custom_buffer(window, str, 0, 0xF, (byte*)(OVERWORLD_BUFFER - ((*tile_offset) * TILESET_OFFSET_BUFFER_MULTIPLIER)));
window->text_offset++;
}
}

File diff suppressed because it is too large Load Diff

View File

@ -7,6 +7,8 @@
#define TRUE 1
#define FALSE 0
#define TILESET_OFFSET_BUFFER_MULTIPLIER 0x8
#define DEFAULT_DOUBLE_TILE_HEIGHT 0xC
#define CHAR_OFFSET 0x50
#define CHAR_END 0x60
#define YOUWON_START 0x64
@ -21,19 +23,28 @@
#define WINDOW_HEADER_Y 0x11
#define WINDOW_HEADER_TILE (WINDOW_HEADER_X + (WINDOW_HEADER_Y * 32))
#define OVERWORLD_BUFFER 0x200C000
#define OVERWORLD_BUFFER_POINTER 0x2028008
#define OVERWORLD_BUFFER_SIZE 0xA80
#define OVERWORLD_BUFFER check_overworld_buffer()
#define CUSTOMCC_SET_X 0x5F
#define CUSTOMCC_ADD_X 0x60
#define BUILD_PALETTE false
byte decode_character(byte chr);
byte encode_ascii(char chr);
int get_tile_number(int x, int y);
int get_tile_number_with_offset(int x, int y);
int get_tile_number_buffer(int x, int y);
int get_tile_number_with_offset_buffer(int x, int y);
int ascii_strlen(char *str);
int wrapper_count_pixels_to_tiles(byte *str, int length);
int count_pixels_to_tiles(byte *str, int length, int startingPos);
int expand_bit_depth(byte row, int foreground);
byte reduce_bit_depth(int row, int foreground);
int count_pixels_to_tiles_normal_string(byte *str, int startingPos);
int expand_bit_depth(byte row, byte foreground);
byte reduce_bit_depth(int row, int foregroundRow);
void reduce_bit_depth_sp(int* TileRows, int* bufferValues, int* bottomBufferValues);
byte print_character(byte chr, int x, int y);
byte print_character_formatted(byte chr, int x, int y, int font, int foreground);
byte print_character_to_window(byte chr, WINDOW* window);
@ -42,9 +53,12 @@ void map_special_character(unsigned short tile, int x, int y);
void map_tile(unsigned short tile, int x, int y);
byte print_character_with_callback(byte chr, int x, int y, int font, int foreground,
int *dest, int (*getTileCallback)(int, int), unsigned short *tilemapPtr, int tilemapWidth, byte doubleTileHeight);
byte print_character_with_callback_1bpp_buffer(byte chr, int x, int y, byte *dest, int (*getTileCallback)(int, int), int font,
unsigned short *tilemapPtr, int tilemapWidth, byte doubleTileHeight);
byte print_character_to_ram(byte chr, int *dest, int xOffset, int font, int foreground);
int print_window_header_string(int *dest, byte *str, int x, int y);
void clear_window_header(int *dest, int length, int x, int y);
int print_window_number_header_string(int *dest, byte *str, int x, int y);
unsigned short* print_equip_header(int type, unsigned short *tilemap, unsigned int *dest,
WINDOW *window);
unsigned short format_tile(unsigned short tile, bool flip_x, bool flip_y);
@ -65,6 +79,9 @@ void copy_tile(int xSource, int ySource, int xDest, int yDest);
void copy_tile_up(int x, int y);
void print_space(WINDOW *window);
int print_string(byte *str, int x, int y);
int print_string_edited(byte *str, int x, int y);
unsigned short printstr_hlight_edited(WINDOW* window, byte* str, unsigned short x, unsigned short y, bool highlight);
unsigned short printstr_hlight_pixels_edited(WINDOW* window, byte* str, unsigned short x, unsigned short y, bool highlight);
int print_menu_string(WINDOW* window);
void print_number_menu(WINDOW* window, int style);
void print_number_menu_current(byte digit, WINDOW* window);
@ -76,40 +93,55 @@ void copy_name(byte *str, byte *source, int *index, int pos);
byte getSex(byte character);
void getPossessive(byte character, byte *str, int *index);
void getPronoun(byte character, byte *str, int *index);
void setupShortMainMenu_Talk_to_Goods(char *String);
int get_pointer_jump_back(byte *character);
void print_letter_in_buffer(WINDOW* window, byte* character, int *dest);
void weld_entry_custom_buffer(WINDOW *window, byte *str, int font, int foreground, int* dest);
byte print_character_formatted_buffer(byte chr, int x, int y, int font, int foreground, int *dest);
void print_letter_in_buffer(WINDOW* window, byte* character, byte *dest);
void weld_entry_custom_buffer(WINDOW *window, byte *str, int font, int foreground, byte* dest);
byte print_character_formatted_buffer(byte chr, int x, int y, int font, int foreground, byte *dest);
int print_window_with_buffer(WINDOW* window);
byte print_character_with_codes(WINDOW* window, int* dest);
int buffer_reset_window(WINDOW* window, bool skip_redraw, int* dest);
void handle_first_window_buffer(WINDOW* window, int* dest);
void clear_window_buffer(WINDOW *window, int* dest);
void clear_rect_buffer(int x, int y, int width, int height, int pixels, int* dest);
void clear_tile_buffer(int x, int y, int pixels, int* dest);
int buffer_drawwindow(WINDOW* window, int* dest);
void scrolltext_buffer(WINDOW* window, int* dest);
void properScroll(WINDOW* window, int* dest);
int jumpToOffset(byte* character);
void copy_tile_buffer(int xSource, int ySource, int xDest, int yDest, int *dest);
void copy_tile_up_buffer(int x, int y, int *dest);
byte print_character_with_codes(WINDOW* window, byte* dest);
int buffer_reset_window(WINDOW* window, bool skip_redraw, byte* dest);
void handle_first_window_buffer(WINDOW* window, byte* dest);
void clear_window_buffer(WINDOW *window, byte* dest);
void clear_rect_buffer(int x, int y, int width, int height, byte* dest);
void clear_tile_buffer(int x, int y, byte* dest);
int buffer_drawwindow(WINDOW* window, byte* dest);
void scrolltext_buffer(WINDOW* window, byte* dest);
void properScroll(WINDOW* window, byte* dest);
void copy_tile_buffer(int xSource, int ySource, int xDest, int yDest, byte *dest);
void copy_tile_up_buffer(int x, int y, byte *dest);
void setStuffWindow_Graphics();
void clearWindowTiles_buffer(WINDOW* window);
int initWindow_buffer(WINDOW* window, byte* text_start, unsigned short delay_between_prints);
void print_blankstr_buffer(int x, int y, int width, int *dest);
int initWindow_cursor_buffer(WINDOW* window, byte* text_start, unsigned short cursor_x_delta, unsigned short unknown7a, unsigned short cursor_x_base);
void print_blankstr_buffer(int x, int y, int width, byte *dest);
void print_blankstr_window_buffer(int x, int y, int width, WINDOW* window);
int print_alphabet_buffer(WINDOW* window);
unsigned short ailmentTileSetup(byte *ailmentBase, unsigned short defaultVal);
int setNumber_getLength(int value, byte *str, int maxLength);
int print_string_in_buffer(byte *str, int x, int y, int *dest);
int print_string_in_buffer(byte *str, int x, int y, byte *dest);
void printCashWindow();
WINDOW* getWindow(int index);
void printstr_buffer(WINDOW* window, byte* str, unsigned short x, unsigned short y, bool highlight);
void printTinyArrow(int x, int y);
int printstr_buffer(WINDOW* window, byte* str, unsigned short x, unsigned short y, bool highlight);
int highlight_string(WINDOW* window, byte* str, unsigned short x, unsigned short y, bool highlight);
void highlight_talk_to();
unsigned short printstr_hlight_buffer(WINDOW* window, byte* str, unsigned short x, unsigned short y, bool highlight);
unsigned short printstr_hlight_pixels_buffer(WINDOW* window, byte* str, unsigned short x, unsigned short y, bool highlight);
int check_overworld_buffer();
void load_pixels_overworld_buffer();
void store_pixels_overworld_buffer(int totalYs);
void store_pixels_overworld_buffer_totalTiles(int totalTiles);
void eb_cartridge_palette_change(bool background);
extern unsigned short m2_coord_table_fast_progression[];
extern unsigned short m2_coord_table[];
extern byte m2_ness_name[];
extern int m2_buffer_counter;
extern int m2_bits_to_nybbles[];
extern int m2_bits_to_nybbles_fast[];
extern byte m2_nybbles_to_bits[];
extern byte optimized_byte_4bpp_to_1bpp_table[];
extern byte *m2_font_table[];
extern byte m2_font_widths[];
extern byte m2_font_heights[];
@ -120,10 +152,16 @@ extern byte m12_other_str7[];
extern byte m12_other_str8[];
extern byte m2_cstm_last_printed[];
extern byte *m2_script_readability;
extern unsigned short m12_cartridge_palettes[];
extern unsigned short m12_cartridge_palettes_dimmed[];
extern int overworld_buffer;
extern PC m2_ness_data[];
extern int m2_arrow_tile[];
extern bool m2_isequipped(int item_index);
extern void cpufastset(void *source, void *dest, int mode);
extern void cpuset(void *source, void *dest, int mode);
extern void m12_dim_palette(unsigned short* palette, int total, int dimmingFactor);
extern byte* m2_strlookup(int *offset_table, byte *strings, int index);
extern void m2_formatnumber(int value, byte* strDest, int length);
extern int bin_to_bcd(int value, int* digit_count);
@ -134,8 +172,11 @@ extern int m2_div(int dividend, int divisor);
extern int m2_remainder(int dividend, int divisor);
extern void m2_soundeffect(int index);
extern void m2_printstr(WINDOW* window, byte* str, unsigned short x, unsigned short y, bool highlight);
extern int customcodes_parse_generic(int code, char* parserAddress, WINDOW* window, int* dest);
extern int customcodes_parse_generic(int code, char* parserAddress, WINDOW* window, byte* dest);
extern int m2_jump_to_offset(byte* character);
extern void m2_sub_d3c50();
extern void m2_sub_d6844();
extern int m2_setupwindow(WINDOW* window, short window_x, short window_y, short window_width, short window_height);
extern void m2_setupbattlename(short value);
extern void store_pixels_overworld();
extern byte* m2_malloc();

Binary file not shown.

116
src/data/cast-table.tbl Normal file
View File

@ -0,0 +1,116 @@
00=\x00
01=\x01
17=\x17
1C=\x1C
26=\x26
30=\x30
3E=\x3E
44=\x44
4A=\x4A
4C=\x4C
56=\x56
FE=[END]
00=
01=!
02="
03=#
04=$
05=%
06=&
07='
08=(
09=)
0A=*
0B=+
0C=,
0D=-
0E=.
0F=/
10=0
11=1
12=2
13=3
14=4
15=5
16=6
17=7
18=8
19=9
1A=:
1B=;
1C=<
1D==
1E=>
1F=?
20=@
21=A
22=B
23=C
24=D
25=E
26=F
27=G
28=H
29=I
2A=J
2B=K
2C=L
2D=M
2E=N
2F=O
30=P
31=Q
32=R
33=S
34=T
35=U
36=V
37=W
38=X
39=Y
3A=Z
3B=[8B]
3C=[8C]
3D=[8D]
3E=[8E]
3F=[8F]
40=`
41=a
42=b
43=c
44=d
45=e
46=f
47=g
48=h
49=i
4A=j
4B=k
4C=l
4D=m
4E=n
4F=o
50=p
51=q
52=r
53=s
54=t
55=u
56=v
57=w
58=x
59=y
5A=z
5B={
5C=|
5D=}
5E=~
5F=[AF]
F9=\cness
FA=\cpaula
FB=\cjeff
FC=\cpoo
FD=\cking
/FF

View File

@ -0,0 +1,10 @@
.loadtable "data/cast-table.tbl"
.strn 078h, 000h, 050h, "\cpaula's mom[END]"
.strn 078h, 000h, 0A0h, "\cpaula's dad[END]"
.strn 080h, 000h, 078h, "\cpaula[END]"
.strn 01Ah, 001h, 078h, "\cjeff[END]"
.strn 0A2h, 001h, 078h, "\cpoo[END]"
.strn 0ADh, 001h, 0B0h, "\cpoo's Master[END]"
.strn 03Ah, 002h, 090h, "\cking[END]"
.str 043h, 002h, 078h, "\cness[END]"

Binary file not shown.

View File

@ -0,0 +1 @@
<EFBFBD>

Binary file not shown.

View File

@ -0,0 +1 @@
<16>3<EFBFBD>5<EFBFBD>7<EFBFBD>9<EFBFBD>;<3B>q<EFBFBD><1C><><EFBFBD>4<EFBFBD>6<EFBFBD>8<EFBFBD>:<3A><<3C><1B><1D><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>

Binary file not shown.

View File

@ -0,0 +1 @@
0

Binary file not shown.

View File

@ -0,0 +1 @@
q<EFBFBD>s<EFBFBD><EFBFBD><EFBFBD><16>3<EFBFBD>5<EFBFBD>7<EFBFBD>u<EFBFBD>r<EFBFBD>t<EFBFBD><74><EFBFBD><EFBFBD><EFBFBD>4<EFBFBD>6<EFBFBD>8<EFBFBD><38><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>

Binary file not shown.

View File

@ -0,0 +1 @@
0

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,92 @@
.loadtable "data/flyover-table.tbl"
.strn "\n"
.strn "\n"
.strn 01h, 1Ch, "You've traveled very far from\n"
.strn 01h, 1Ch, "home...\n"
.strn "\n"
.strn "\n"
.strn 01h, 1Ch, "Do you remember how your long\n"
.strn 01h, 1Ch, "and winding journey began with\n"
.strn 01h, 1Ch, "someone pounding at your door?\n"
.strn 01h, 1Ch, "It was Pokey, the worst person in\n"
.strn 01h, 1Ch, "your neighborhood, who knocked\n"
.strn 01h, 1Ch, "on the door that fateful night.\n"
.strn "\n"
.strn "\n"
.strn 01h, 1Ch, "On your way, you have walked,\n"
.strn 01h, 1Ch, "thought and fought. Yet through\n"
.strn 01h, 1Ch, "all this, you have never lost your\n"
.strn 01h, 1Ch, "courage. You have grown steadily\n"
.strn 01h, 1Ch, "stronger, though you have\n"
.strn 01h, 1Ch, "experienced the pain of battle\n"
.strn 01h, 1Ch, "many times.\n"
.strn "\n"
.strn "\n"
.strn "\n"
.strn "\n"
.strn 01h, 1Ch, "You are no longer alone in your\n"
.strn 01h, 1Ch, "adventure, \cpaula who is\n"
.strn 01h, 1Ch, "steadfast, kind and even pretty,\n"
.strn 01h, 1Ch, "is always at your side.\n"
.strn 01h, 1Ch, "\cjeff is with you as well.\n"
.strn 01h, 1Ch, "Though he is timid, he came from\n"
.strn 01h, 1Ch, "a distant land to help you.\n"
.strn 01h, 1Ch, "\cness, as you certainly\n"
.strn 01h, 1Ch, "know by now, you are not a\n"
.strn 01h, 1Ch, "regular young man... You have\n"
.strn 01h, 1Ch, "an awesome destiny to fulfill.\n"
.strn "\n"
.strn "\n"
.strn "\n"
.strn "\n"
.strn 01h, 1Ch, "The journey from this point will\n"
.strn 01h, 1Ch, "be long, and it will be more\n"
.strn 01h, 1Ch, "difficult than anything you have\n"
.strn 01h, 1Ch, "undergone to this point. Yet, I\n"
.strn 01h, 1Ch, "know you will be all right. When\n"
.strn 01h, 1Ch, "good battles evil, which side do\n"
.strn 01h, 1Ch, "you believe wins? Do you have\n"
.strn 01h, 1Ch, "faith that good is triumphant?\n"
.strn "\n"
.strn "\n"
.strn "\n"
.strn "\n"
.strn 01h, 1Ch, "One thing you must never lose is\n"
.strn 01h, 1Ch, "courage. If you believe in the\n"
.strn 01h, 1Ch, "goal you are striving for, you will\n"
.strn 01h, 1Ch, "be courageous. There are many\n"
.strn 01h, 1Ch, "difficult times ahead, but you\n"
.strn 01h, 1Ch, "must keep your sense of humor,\n"
.strn 01h, 1Ch, "work through the tough\n"
.strn 01h, 1Ch, "situations and enjoy yourself.\n"
.strn "\n"
.strn "\n"
.strn "\n"
.strn "\n"
.strn 01h, 1Ch, "When you have finished this cup\n"
.strn 01h, 1Ch, "of coffee, your adventure will\n"
.strn 01h, 1Ch, "begin again. Next, you must pass\n"
.strn 01h, 1Ch, "through a vast desert and\n"
.strn 01h, 1Ch, "proceed to the big city of\n"
.strn 01h, 1Ch, "Fourside.\n"
.strn "\n"
.strn "\n"
.strn "\n"
.strn "\n"
.strn 01h, 1Ch, "\cness...\n"
.strn 01h, 1Ch, " \cpaula...\n"
.strn 01h, 1Ch, " \cjeff...\n"
.strn "\n"
.strn "\n"
.strn 01h, 1Ch, "I wish you luck...\n"
.strn "\n"
.strn "\n"
.strn "\n"
.strn "\n"
.strn "\n"
.strn "\n"
.strn "\n"
.strn "\n"
.strn "\n"
.str "\n"

118
src/data/flyover-table.tbl Normal file
View File

@ -0,0 +1,118 @@
00=\x00
01=\x01
17=\x17
1C=\x1C
26=\x26
30=\x30
3E=\x3E
44=\x44
4A=\x4A
4C=\x4C
56=\x56
00=\end
01=\setx
02=\sety
09=\n
8000=
8001=!
8002="
8003=#
8004=$
8005=%
8006=&
8007='
8008=(
8009=)
800A=*
800B=+
800C=,
800D=-
800E=.
800F=/
8010=0
8011=1
8012=2
8013=3
8014=4
8015=5
8016=6
8017=7
8018=8
8019=9
801A=:
801B=;
801C=<
801D==
801E=>
801F=?
8020=@
8021=A
8022=B
8023=C
8024=D
8025=E
8026=F
8027=G
8028=H
8029=I
802A=J
802B=K
802C=L
802D=M
802E=N
802F=O
8030=P
8031=Q
8032=R
8033=S
8034=T
8035=U
8036=V
8037=W
8038=X
8039=Y
803A=Z
803B=[8B]
803C=[8C]
803D=[8D]
803E=[8E]
803F=[8F]
8040=`
8041=a
8042=b
8043=c
8044=d
8045=e
8046=f
8047=g
8048=h
8049=i
804A=j
804B=k
804C=l
804D=m
804E=n
804F=o
8050=p
8051=q
8052=r
8053=s
8054=t
8055=u
8056=v
8057=w
8058=x
8059=y
805A=z
805B={
805C=|
805D=}
805E=~
805F=[AF]
80FC=\cness
80FD=\cpaula
80FE=\cjeff
80FF=\cpoo
/00

71
src/data/flyover-tea.asm Normal file
View File

@ -0,0 +1,71 @@
.loadtable "data/flyover-table.tbl"
.strn "\n"
.strn "\n"
.strn 01h, 1Ch, "Like a great tapestry, vertical and\n"
.strn 01h, 1Ch, "horizontal threads have met and\n"
.strn 01h, 1Ch, "become intertwined, creating a\n"
.strn 01h, 1Ch, "huge, beautiful image.\n"
.strn "\n"
.strn "\n"
.strn "\n"
.strn "\n"
.strn 01h, 1Ch, "You may have cursed this never-\n"
.strn 01h, 1Ch, "ending journey. You have known\n"
.strn 01h, 1Ch, "injury and defeat, but you have\n"
.strn 01h, 1Ch, "struggled on to reach this place.\n"
.strn 01h, 1Ch, "Your in-born intelligence and\n"
.strn 01h, 1Ch, "courage have helped bring you\n"
.strn 01h, 1Ch, "here. You have believed in your\n"
.strn 01h, 1Ch, "friends, and as a group, you have\n"
.strn 01h, 1Ch, "supported each other. Have you\n"
.strn 01h, 1Ch, "ever stopped to consider how\n"
.strn 01h, 1Ch, "much your power has grown?\n"
.strn 01h, 1Ch, "Now, you could fell enemies in\n"
.strn 01h, 1Ch, "Onett and Twoson with one\n"
.strn 01h, 1Ch, "blow. As you certainly know,\n"
.strn 01h, 1Ch, "you cannot turn back. Giygas,\n"
.strn 01h, 1Ch, "the arch fiend of the universe, is\n"
.strn 01h, 1Ch, "growing frightened of you and\n"
.strn 01h, 1Ch, "your power. He is searching for\n"
.strn 01h, 1Ch, "ways to end your journey.\n"
.strn "\n"
.strn "\n"
.strn "\n"
.strn "\n"
.strn 01h, 1Ch, "From here, the challenge grows\n"
.strn 01h, 1Ch, "and your adventure will take you\n"
.strn 01h, 1Ch, "beyond anything you ever\n"
.strn 01h, 1Ch, "imagined. You are drawing near\n"
.strn 01h, 1Ch, "to Giygas. Remember, when you\n"
.strn 01h, 1Ch, "are suffering hardships, your\n"
.strn 01h, 1Ch, "enemy is also struggling.\n"
.strn "\n"
.strn "\n"
.strn "\n"
.strn "\n"
.strn 01h, 1Ch, "By the way, do you know where\n"
.strn 01h, 1Ch, "Pokey went? When this cup of\n"
.strn 01h, 1Ch, "tea is finished, your adventure will\n"
.strn 01h, 1Ch, "continue. Your destiny pulls you\n"
.strn 01h, 1Ch, "in the right direction. Believe in\n"
.strn 01h, 1Ch, "yourself and press forward.\n"
.strn "\n"
.strn "\n"
.strn "\n"
.strn "\n"
.strn 01h, 12h, "\cness!\n"
.strn 01h, 12h, " \cpaula!\n"
.strn 01h, 12h, " \cjeff!\n"
.strn 01h, 12h, " \cpoo!\n"
.strn "\n"
.strn "\n"
.strn 01h, 1Ch, "I wish you luck...\n"
.strn "\n"
.strn "\n"
.strn "\n"
.strn "\n"
.strn "\n"
.strn "\n"
.strn "\n"
.str "\n"

View File

@ -0,0 +1,5 @@
.loadtable "data/flyover-table.tbl"
db 02h, 01h
db 01h, 3Eh
.str "Dalaam, in the Far East\n"

View File

@ -0,0 +1,5 @@
.loadtable "data/flyover-table.tbl"
db 02h, 01h
db 01h, 4Ah
.str "Later that night...\n"

View File

@ -0,0 +1,5 @@
.loadtable "data/flyover-table.tbl"
db 02h, 01h
db 01h, 56h
.str "\cness's house\n"

View File

@ -0,0 +1,7 @@
.loadtable "data/flyover-table.tbl"
// Should this be 02 01?
db 02h, 02h
db 01h, 26h
.str "Onett, a small town in Eagleland\n"

View File

@ -0,0 +1,10 @@
.loadtable "data/flyover-table.tbl"
// Does 09 work for linebreaks? Existing bin used the system here
db 02h, 00h
db 01h, 44h
.strn "The palace of \cpoo"
db 02h, 04h
db 01h, 50h
.str "The Crown Prince\n"

View File

@ -0,0 +1,5 @@
.loadtable "data/flyover-table.tbl"
db 02h, 01h
db 01h, 30h
.str "Snow Wood Boarding House\n"

View File

@ -0,0 +1,5 @@
.loadtable "data/flyover-table.tbl"
db 02h, 01h
db 01h, 17h
.str "Winters, a small country to the north\n"

View File

@ -0,0 +1,5 @@
.loadtable "data/flyover-table.tbl"
db 02h, 01h
db 01h, 4Ch
.str "The year is 199X\n"

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

115
src/data/lumine-table.tbl Normal file
View File

@ -0,0 +1,115 @@
00=\x00
01=\x01
17=\x17
1C=\x1C
26=\x26
30=\x30
3E=\x3E
44=\x44
4A=\x4A
4C=\x4C
56=\x56
FE=\blank
00=
01=!
02="
03=#
04=$
05=%
06=&
07='
08=(
09=)
0A=*
0B=+
0C=,
0D=-
0E=.
0F=/
10=0
11=1
12=2
13=3
14=4
15=5
16=6
17=7
18=8
19=9
1A=:
1B=;
1C=<
1D==
1E=>
1F=?
20=@
21=A
22=B
23=C
24=D
25=E
26=F
27=G
28=H
29=I
2A=J
2B=K
2C=L
2D=M
2E=N
2F=O
30=P
31=Q
32=R
33=S
34=T
35=U
36=V
37=W
38=X
39=Y
3A=Z
3B=[8B]
3C=[8C]
3D=[8D]
3E=[8E]
3F=[8F]
40=`
41=a
42=b
43=c
44=d
45=e
46=f
47=g
48=h
49=i
4A=j
4B=k
4C=l
4D=m
4E=n
4F=o
50=p
51=q
52=r
53=s
54=t
55=u
56=v
57=w
58=x
59=y
5A=z
5B={
5C=|
5D=}
5E=~
5F=[AF]
FA=\cness
FB=\cpaula
FC=\cjeff
FD=\cpoo
/FF

8
src/data/lumine-text.asm Normal file
View File

@ -0,0 +1,8 @@
.loadtable "data/lumine-table.tbl"
.strn "\blank"
.strn "I'm \cness.... It's been a long road getting here... "
.strn "Soon, I'll be... Soon, I'll be... Soon, I'll be... "
.strn "What will happen to us? W...what's happening? "
.strn "My thoughts are being written out on the wall... or are they?"
.str "\blank"

View File

@ -0,0 +1 @@
ζ¬ ¬ ͺ ¬η«© ¬«η© ͺ©©¨

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1 @@
DDDDODDDôDDD˙DDDDODDOODDôODD˙ODDDôDDOôDDôôDD˙ôDDD˙DDO˙DDô˙DD˙˙DDDDODODODôDOD˙DODDOODOOODôOOD˙OODDôODOôODôôOD˙ôODD˙ODO˙ODô˙OD˙˙ODDDôDODôDôDôD˙DôDDOôDOOôDôOôD˙OôDDôôDOôôDôôôD˙ôôDD˙ôDO˙ôDô˙ôD˙˙ôDDD˙DOD˙DôD˙D˙D˙DDO˙DOO˙DôO˙D˙O˙DDô˙DOô˙Dôô˙D˙ô˙DD˙˙DO˙˙Dô˙˙D˙˙˙DDDDOODDOôDDO˙DDODODOOODOôODO˙ODODôDOOôDOôôDO˙ôDOD˙DOO˙DOô˙DO˙˙DODDOOODOOôDOO˙DOODOOOOOOOôOOO˙OOODôOOOôOOôôOO˙ôOOD˙OOO˙OOô˙OO˙˙OODDôOODôOôDôO˙DôODOôOOOôOôOôO˙OôODôôOOôôOôôôO˙ôôOD˙ôOO˙ôOô˙ôO˙˙ôODD˙OOD˙OôD˙O˙D˙ODO˙OOO˙OôO˙O˙O˙ODô˙OOô˙Oôô˙O˙ô˙OD˙˙OO˙˙Oô˙˙O˙˙˙ODDDôODDôôDDô˙DDôDODôOODôôODô˙ODôDôDôOôDôôôDô˙ôDôD˙DôO˙Dôô˙Dô˙˙DôDDOôODOôôDOô˙DOôDOOôOOOôôOOô˙OOôDôOôOôOôôôOô˙ôOôD˙OôO˙Oôô˙Oô˙˙OôDDôôODôôôDôô˙DôôDOôôOOôôôOôô˙OôôDôôôOôôôôôôô˙ôôôD˙ôôO˙ôôô˙ôô˙˙ôôDD˙ôOD˙ôôD˙ô˙D˙ôDO˙ôOO˙ôôO˙ô˙O˙ôDô˙ôOô˙ôôô˙ô˙ô˙ôD˙˙ôO˙˙ôô˙˙ô˙˙˙ôDDD˙ODD˙ôDD˙˙DD˙DOD˙OOD˙ôOD˙˙OD˙DôD˙OôD˙ôôD˙˙ôD˙D˙D˙O˙D˙ô˙D˙˙˙D˙DDO˙ODO˙ôDO˙˙DO˙DOO˙OOO˙ôOO˙˙OO˙DôO˙OôO˙ôôO˙˙ôO˙D˙O˙O˙O˙ô˙O˙˙˙O˙DDô˙ODô˙ôDô˙˙Dô˙DOô˙OOô˙ôOô˙˙Oô˙Dôô˙Oôô˙ôôô˙˙ôô˙D˙ô˙O˙ô˙ô˙ô˙˙˙ô˙DD˙˙OD˙˙ôD˙˙˙D˙˙DO˙˙OO˙˙ôO˙˙˙O˙˙Dô˙˙Oô˙˙ôô˙˙˙ô˙˙D˙˙˙O˙˙˙ô˙˙˙˙˙˙˙

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
src/data/m2-cola-truck.bin Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
src/data/m2-door-bubble.bin Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
src/data/m2-iron-eraser.bin Normal file

Binary file not shown.

Binary file not shown.

BIN
src/data/m2-iron-pencil.bin Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Some files were not shown because too many files have changed in this diff Show More