commit
e336ed27d1
|
@ -3,3 +3,5 @@ $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 }
|
||||
|
|
12
build.ps1
12
build.ps1
|
@ -6,6 +6,8 @@ $output_rom_file = "bin/m12.gba"
|
|||
$eb_rom_file = "bin/eb.smc"
|
||||
$working_dir = "working"
|
||||
$src_dir = "src"
|
||||
$data_dir = "src/data"
|
||||
$cast_roll_file = "working/cast_roll.json"
|
||||
$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
|
||||
|
@ -14,6 +16,7 @@ $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",
|
||||
|
@ -24,6 +27,7 @@ $input_c_files =
|
|||
|
||||
$base_c_address = 0x83755B8;
|
||||
$scripttool_cmd = "bin/ScriptTool/ScriptTool.dll"
|
||||
$rendercastroll_cmd= "bin/RenderCastRoll/RenderCastRoll.dll"
|
||||
$gcc_cmd = "arm-none-eabi-gcc"
|
||||
$ld_cmd = "arm-none-eabi-ld"
|
||||
$objdump_cmd = "arm-none-eabi-objdump"
|
||||
|
@ -49,6 +53,10 @@ $scripttool_args =
|
|||
$eb_rom_file,
|
||||
$input_rom_file
|
||||
|
||||
$rendercastroll_args =
|
||||
$cast_roll_file,
|
||||
$data_dir
|
||||
|
||||
$gcc_args =
|
||||
"-c",
|
||||
"-O1",
|
||||
|
@ -348,6 +356,10 @@ Copy-Item -Path $input_rom_file -Destination $output_rom_file
|
|||
& dotnet $scripttool_cmd $scripttool_args
|
||||
if ($LASTEXITCODE -ne 0) { exit -1 }
|
||||
|
||||
"Pre-rendering cast roll..."
|
||||
& dotnet $rendercastroll_cmd $rendercastroll_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
|
||||
|
|
|
@ -0,0 +1,316 @@
|
|||
#include "credits.h"
|
||||
|
||||
void printPlayerNameCredits(unsigned short *arrangements)
|
||||
{
|
||||
//Converts the player name to arrangements
|
||||
int length = 0;
|
||||
byte *player_name = m2_player1;
|
||||
//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 - 5) >> 1) + 1;
|
||||
unsigned short *player_name_arrangements = ((0x89 << 2) << 5) + arrangements + start_pos;
|
||||
unsigned short *default_player_name_arrangements = ((0x89 << 2) << 5) + arrangements + start_pos_default;
|
||||
player_name = m2_player1;
|
||||
|
||||
//Clears the default MARIO player name...
|
||||
for(int i = 0; i < 5; 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;
|
||||
setTilesToBlank(Tiles[0]);
|
||||
|
||||
//First things first, it calculates the total length of the text in pixels
|
||||
while((*castText_curr_ptr) != END)
|
||||
length += getCharWidth(*(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++)
|
||||
setTilesToBlank(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);
|
||||
}
|
||||
|
||||
copyTiles(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 copyTiles(int Tiles[SIDE_BUFFER_SIZE + 1][4], int indexMatrix)
|
||||
{
|
||||
for(int i = 0; i < 4; i++)
|
||||
Tiles[0][i] = Tiles[indexMatrix][i];
|
||||
}
|
||||
|
||||
void setTilesToBlank(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 getCharWidth(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 getPCWidth(pc_names+(chr-PC_START)*(PC_NAME_SIZE + 2), PC_NAME_SIZE);
|
||||
case PC_START+4:
|
||||
return getPCWidth(pc_names+(chr-PC_START)*(PC_NAME_SIZE + 2), DOG_NAME_SIZE);
|
||||
default:
|
||||
return m2_widths_table[CAST_FONT][chr] & 0xFF;
|
||||
}
|
||||
}
|
||||
|
||||
int getPCWidth(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;
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
#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 getCharWidth(byte chr);
|
||||
int getPCWidth(byte* pc_ptr, int max_size);
|
||||
void setTilesToBlank(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 copyTiles(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 int m2_bits_to_nybbles_fast_cast[];
|
||||
|
||||
#endif
|
|
@ -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
|
|
@ -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.
|
@ -0,0 +1 @@
|
|||
<EFBFBD>
|
Binary file not shown.
|
@ -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.
|
@ -0,0 +1 @@
|
|||
0
|
Binary file not shown.
|
@ -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.
|
@ -0,0 +1 @@
|
|||
0
|
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.
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.
|
@ -1727,6 +1727,41 @@ nop
|
|||
//==============================================================================
|
||||
.org 0x80DEE6C :: bl dee6c_fix_poison_gyigas :: nop :: nop :: nop
|
||||
|
||||
//==============================================================================
|
||||
// Credits hacks
|
||||
//==============================================================================
|
||||
|
||||
//Repoint credits font (Before it pointed to 0x82FF1B8)
|
||||
.org 0x82DB284 :: dw m2_credits_font
|
||||
.org 0x801352E :: bl printPlayerNameCredits
|
||||
|
||||
//Repoint cast graphical data
|
||||
.org m2_cast_roll_pointers :: dw m2_cast_graphics :: dw m2_cast_palette :: dw m2_cast_arrangements
|
||||
|
||||
//Remove flavour changing the palette
|
||||
.org 0x8010426 :: bl prevent_cast_changed_palettes
|
||||
|
||||
//Cast Roll VWF
|
||||
.org 0x800F640 :: bl writeCastText
|
||||
|
||||
//Master Belch and Star Master text appearing later
|
||||
.org 0x8018934 :: dw m2_cast_belch_arrangement
|
||||
.org 0x80188B2 :: .incbin "data/cast_roll_master_belch_size.bin"
|
||||
.org 0x82D92BC :: .incbin "data/cast_roll_master_belch_data.bin"
|
||||
.org 0x8018940 :: dw m2_cast_star_arrangement
|
||||
.org 0x8018904 :: .incbin "data/cast_roll_star_master_size.bin"
|
||||
.org 0x82D92C4 :: .incbin "data/cast_roll_star_master_data.bin"
|
||||
|
||||
//==============================================================================
|
||||
// "THE END...?" hacks
|
||||
//==============================================================================
|
||||
.org 0x88B5AA0 :: .incbin "data/the_end_graphics.bin"
|
||||
.org 0x88B62A0 :: .incbin "data/the_end_palette.bin"
|
||||
.org 0x88B62C0 :: .incbin "data/the_end_arrangements_frame0.bin"
|
||||
|
||||
//Add an extra event for the "?" in "THE END..."
|
||||
.org 0x80A5F5C :: bl extra_event_end_question_mark
|
||||
|
||||
//==============================================================================
|
||||
// Move stuff around in order to make space for the code
|
||||
//==============================================================================
|
||||
|
@ -1832,18 +1867,25 @@ m2_widths_battle:
|
|||
m2_widths_tiny:
|
||||
.incbin "data/m2-widths-tiny.bin"
|
||||
|
||||
.align 4
|
||||
m2_bits_to_nybbles:
|
||||
.incbin "data/m2-bits-to-nybbles.bin"
|
||||
|
||||
m2_bits_to_nybbles_fast:
|
||||
.incbin "data/m2-bits-to-nybbles-fast.bin"
|
||||
|
||||
m2_bits_to_nybbles_fast_cast:
|
||||
.incbin "data/m2-bits-to-nybbles-fast-cast.bin"
|
||||
|
||||
m2_nybbles_to_bits:
|
||||
.incbin "data/m2-nybbles-to-bits.bin"
|
||||
|
||||
m2_enemy_attributes:
|
||||
.incbin "data/m2-enemy-attributes.bin"
|
||||
|
||||
cast_vwf_names:
|
||||
.include "data/cast-vwf-names.asm"
|
||||
|
||||
.align 2
|
||||
luminesquaretable:
|
||||
.incbin "data/luminesquaretable.bin"
|
||||
|
@ -1888,6 +1930,42 @@ m2InsaneCultist:
|
|||
m2_coord_table_file:
|
||||
.incbin "data/m2-coord-table-file-select.bin"
|
||||
|
||||
.align 2
|
||||
m2_credits_conversion_table:
|
||||
.incbin "data/m2-credits-conversion-table.bin"
|
||||
|
||||
.align 4
|
||||
m2_cast_belch_arrangement:
|
||||
.incbin "data/cast_roll_master_belch_arrangement.bin"
|
||||
|
||||
.align 4
|
||||
m2_cast_star_arrangement:
|
||||
.incbin "data/cast_roll_star_master_arrangement.bin"
|
||||
|
||||
.align 2
|
||||
m2_cast_vwf_free:
|
||||
.incbin "data/cast_roll_first_free.bin"
|
||||
|
||||
.align 4
|
||||
m2_cast_graphics:
|
||||
.incbin "data/cast_roll_graphics_[c].bin"
|
||||
|
||||
.align 4
|
||||
m2_cast_palette:
|
||||
.incbin "data/cast_roll_palette_[c].bin"
|
||||
|
||||
.align 4
|
||||
m2_cast_arrangements:
|
||||
.incbin "data/cast_roll_arrangements_[c].bin"
|
||||
|
||||
.align 4
|
||||
m2_credits_font:
|
||||
.incbin "data/m2-credits-font_[c].bin"
|
||||
|
||||
.align 4
|
||||
m2_end_frame1:
|
||||
.incbin "data/the_end_arrangements_frame1.bin"
|
||||
|
||||
optimized_byte_4bpp_to_1bpp_table:
|
||||
.incbin "data/optimized-byte-4bpp-to-1bpp-table.bin"
|
||||
|
||||
|
@ -1978,6 +2056,7 @@ disclaimer_map:
|
|||
.definelabel m2_div ,0x80F49D8
|
||||
.definelabel m2_remainder ,0x80F4A70
|
||||
.definelabel cpuset ,0x80F47C0
|
||||
.definelabel m2_cast_roll_pointers ,0x82DB25C
|
||||
.definelabel m2_items ,0x8B1D62C
|
||||
.definelabel m2_default_names ,0x82B9330
|
||||
.definelabel m2_psi_print_table ,0x8B2A9C0
|
||||
|
|
|
@ -3375,6 +3375,49 @@ bl eb_cartridge_palette_change
|
|||
@@end:
|
||||
pop {pc}
|
||||
|
||||
//==============================================================================
|
||||
//Prevents changing the palette based on the flavour for the cast roll sequence
|
||||
prevent_cast_changed_palettes:
|
||||
push {lr}
|
||||
ldr r1,=#m2_cast_roll_pointers
|
||||
cmp r0,r1
|
||||
beq @@alternate_end
|
||||
bl 0x8010028
|
||||
pop {pc}
|
||||
|
||||
@@alternate_end:
|
||||
bl 0x8010028
|
||||
ldr r1,=#0x40000D4
|
||||
ldr r0,=#0x2010000
|
||||
str r0,[r1,#0]
|
||||
ldr r3,=#0x3001B30
|
||||
str r3,[r1,#4]
|
||||
ldr r0,=#0x84000080
|
||||
str r0,[r1,#8]
|
||||
ldr r0,[r1,#8]
|
||||
pop {r0}
|
||||
ldr r0,=#0x8010501 //Go to the end of the routine
|
||||
bx r0
|
||||
|
||||
//==============================================================================
|
||||
//Creates a new event that updates the "THE END..." screen to the second frame
|
||||
extra_event_end_question_mark:
|
||||
push {lr}
|
||||
add r0,r0,r1
|
||||
asr r0,r0,#0x10
|
||||
cmp r0,#0x48
|
||||
bne @@end
|
||||
push {r0}
|
||||
ldr r0,=#m2_end_frame1
|
||||
ldr r1,=#0x6001000
|
||||
mov r2,#0xA0
|
||||
lsl r2,r2,#1
|
||||
swi #0xC
|
||||
pop {r0}
|
||||
|
||||
@@end:
|
||||
pop {pc}
|
||||
|
||||
//==============================================================================
|
||||
//Prints the sick tiles and then the names
|
||||
sick_name:
|
||||
|
|
|
@ -1,12 +1,14 @@
|
|||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio Version 16
|
||||
VisualStudioVersion = 16.0.28407.52
|
||||
# Visual Studio 15
|
||||
VisualStudioVersion = 15.0.28307.168
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ScriptTool", "ScriptTool\ScriptTool.csproj", "{29AB41A8-6405-4C4B-A374-BF1BD7AF1A27}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ScriptToolGui", "ScriptToolGui\ScriptToolGui.csproj", "{BAE5CBBF-D0B3-4F82-A80A-957CEC379238}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RenderCastRoll", "RenderCastRoll\RenderCastRoll.csproj", "{DD1C607C-5A74-4921-81A4-6BF530A191D7}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
|
@ -21,6 +23,10 @@ Global
|
|||
{BAE5CBBF-D0B3-4F82-A80A-957CEC379238}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{BAE5CBBF-D0B3-4F82-A80A-957CEC379238}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{BAE5CBBF-D0B3-4F82-A80A-957CEC379238}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{DD1C607C-5A74-4921-81A4-6BF530A191D7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{DD1C607C-5A74-4921-81A4-6BF530A191D7}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{DD1C607C-5A74-4921-81A4-6BF530A191D7}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{DD1C607C-5A74-4921-81A4-6BF530A191D7}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
|
|
@ -0,0 +1,30 @@
|
|||
using System;
|
||||
using System.IO;
|
||||
|
||||
namespace RenderCastRoll
|
||||
{
|
||||
public static class Asset
|
||||
{
|
||||
public static readonly string AssetPath;
|
||||
|
||||
static Asset()
|
||||
{
|
||||
AssetPath = AppDomain.CurrentDomain.BaseDirectory;
|
||||
}
|
||||
|
||||
public static string GetFullPath(string path)
|
||||
=> Path.Combine(AssetPath, path);
|
||||
|
||||
public static string ReadAllText(string path)
|
||||
=> File.ReadAllText(GetFullPath(path));
|
||||
|
||||
public static byte[] ReadAllBytes(string path)
|
||||
=> File.ReadAllBytes(GetFullPath(path));
|
||||
|
||||
public static string[] ReadAllLines(string path)
|
||||
=> File.ReadAllLines(GetFullPath(path));
|
||||
|
||||
public static void WriteAllText(string path, string text)
|
||||
=> File.WriteAllText(GetFullPath(path), text);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,167 @@
|
|||
using System.Collections.Generic;
|
||||
|
||||
namespace GBA
|
||||
{
|
||||
class LZ77
|
||||
{
|
||||
public static int Decompress(byte[] data, int address, out byte[] output)
|
||||
{
|
||||
output = null;
|
||||
int start = address;
|
||||
|
||||
if (data[address++] != 0x10) return -1; // Check for LZ77 signature
|
||||
|
||||
// Read the block length
|
||||
int length = data[address++];
|
||||
length += (data[address++] << 8);
|
||||
length += (data[address++] << 16);
|
||||
output = new byte[length];
|
||||
|
||||
int bPos = 0;
|
||||
while (bPos < length)
|
||||
{
|
||||
byte ch = data[address++];
|
||||
for (int i = 0; i < 8; i++)
|
||||
{
|
||||
switch ((ch >> (7 - i)) & 1)
|
||||
{
|
||||
case 0:
|
||||
|
||||
// Direct copy
|
||||
if (bPos >= length) break;
|
||||
output[bPos++] = data[address++];
|
||||
break;
|
||||
|
||||
case 1:
|
||||
|
||||
// Compression magic
|
||||
int t = (data[address++] << 8);
|
||||
t += data[address++];
|
||||
int n = ((t >> 12) & 0xF) + 3; // Number of bytes to copy
|
||||
int o = (t & 0xFFF);
|
||||
|
||||
// Copy n bytes from bPos-o to the output
|
||||
for (int j = 0; j < n; j++)
|
||||
{
|
||||
if (bPos >= length) break;
|
||||
output[bPos] = output[bPos - o - 1];
|
||||
bPos++;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return address - start;
|
||||
}
|
||||
|
||||
public static byte[] Compress(byte[] data)
|
||||
{
|
||||
return Compress(data, 0, data.Length);
|
||||
}
|
||||
|
||||
public static byte[] Compress(byte[] data, int address, int length)
|
||||
{
|
||||
int start = address;
|
||||
|
||||
List<byte> obuf = new List<byte>();
|
||||
List<byte> tbuf = new List<byte>();
|
||||
int control = 0;
|
||||
|
||||
// Let's start by encoding the signature and the length
|
||||
obuf.Add(0x10);
|
||||
obuf.Add((byte)(length & 0xFF));
|
||||
obuf.Add((byte)((length >> 8) & 0xFF));
|
||||
obuf.Add((byte)((length >> 16) & 0xFF));
|
||||
|
||||
while ((address - start) < length)
|
||||
{
|
||||
tbuf.Clear();
|
||||
control = 0;
|
||||
for (int i = 0; i < 8; i++)
|
||||
{
|
||||
bool found = false;
|
||||
|
||||
// First byte should be raw
|
||||
if (address == start)
|
||||
{
|
||||
tbuf.Add(data[address++]);
|
||||
found = true;
|
||||
}
|
||||
else if ((address - start) >= length)
|
||||
{
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
// We're looking for the longest possible string
|
||||
// The farthest possible distance from the current address is 0x1000
|
||||
int max_length = -1;
|
||||
int max_distance = -1;
|
||||
|
||||
for (int k = 1; k <= 0x1000; k++)
|
||||
{
|
||||
if ((address - k) < start) break;
|
||||
|
||||
int l = 0;
|
||||
for (; l < 18; l++)
|
||||
{
|
||||
if (((address - start + l) >= length) ||
|
||||
(data[address - k + l] != data[address + l]))
|
||||
{
|
||||
if (l > max_length)
|
||||
{
|
||||
max_length = l;
|
||||
max_distance = k;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Corner case: we matched all 18 bytes. This is
|
||||
// the maximum length, so don't bother continuing
|
||||
if (l == 18)
|
||||
{
|
||||
max_length = 18;
|
||||
max_distance = k;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (max_length >= 3)
|
||||
{
|
||||
address += max_length;
|
||||
|
||||
// We hit a match, so add it to the output
|
||||
int t = (max_distance - 1) & 0xFFF;
|
||||
t |= (((max_length - 3) & 0xF) << 12);
|
||||
tbuf.Add((byte)((t >> 8) & 0xFF));
|
||||
tbuf.Add((byte)(t & 0xFF));
|
||||
|
||||
// Set the control bit
|
||||
control |= (1 << (7 - i));
|
||||
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!found)
|
||||
{
|
||||
// If we didn't find any strings, copy the byte to the output
|
||||
tbuf.Add(data[address++]);
|
||||
}
|
||||
}
|
||||
|
||||
// Flush the temp buffer
|
||||
obuf.Add((byte)(control & 0xFF));
|
||||
obuf.AddRange(tbuf.ToArray());
|
||||
}
|
||||
|
||||
return obuf.ToArray();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,355 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace RenderCastRoll
|
||||
{
|
||||
class Program
|
||||
{
|
||||
static IDictionary<string, byte> m12CharByteLookup;
|
||||
static byte[] BitsToNybbleLookup;
|
||||
static readonly ushort Palette = 0xF000;
|
||||
static RenderFont[] Fonts;
|
||||
static byte[] Graphics;
|
||||
static _1bppTile emptyTile = new _1bppTile();
|
||||
static _1bppTile[] _1bppGraphics;
|
||||
static _1bppTile[] _1bppGraphics_RotX;
|
||||
static _1bppTile[] _1bppGraphics_RotY;
|
||||
static _1bppTile[] _1bppGraphics_RotXY;
|
||||
static ushort[] Arrangements;
|
||||
static readonly ushort arrStart = 0x100;
|
||||
|
||||
static void Main(string[] args)
|
||||
{
|
||||
if (args.Length != 2)
|
||||
return;
|
||||
|
||||
//Initialization
|
||||
string rendersJson = File.ReadAllText(args[0]);
|
||||
string dataFolder = args[1] + Path.DirectorySeparatorChar;
|
||||
Fonts = new RenderFont[2];
|
||||
Fonts[0] = new RenderFont(dataFolder, "main");
|
||||
Fonts[1] = new RenderFont(dataFolder, "saturn");
|
||||
byte[] CastGraphics = File.ReadAllBytes(dataFolder + "cast_sign_graphics.bin");
|
||||
byte[] CastArrangements = File.ReadAllBytes(dataFolder + "cast_sign_arrangements.bin");
|
||||
List<Render> renders = JsonConvert.DeserializeObject<RenderRoot>(rendersJson).Renders;
|
||||
BitsToNybbleLookup = Asset.ReadAllBytes("bits_to_nybbles.bin");
|
||||
m12CharByteLookup = JsonConvert.DeserializeObject<Dictionary<string, byte>>(Asset.ReadAllText("m12-byte-lookup.json"));
|
||||
Graphics = new byte[0x8000];
|
||||
Arrangements = new ushort[0x48E0];
|
||||
|
||||
for (int i = 0; i < Arrangements.Length; i++)
|
||||
Arrangements[i] = 0x3FF; //Empty tile
|
||||
|
||||
for (int i = 0; i < CastGraphics.Length; i++)
|
||||
Graphics[0x8000 - CastGraphics.Length + i] = CastGraphics[i]; //Put the CAST graphics in
|
||||
|
||||
int castArrPos = readIntLE(CastArrangements, 0); //First 4 bytes are the position of the CAST arrangements
|
||||
for (int i = 0; i < ((CastArrangements.Length - 4) >> 1); i++) //Put the CAST arrangements in
|
||||
{
|
||||
Arrangements[(castArrPos / 2) + i] = readUShortLE(CastArrangements, (i * 2) + 4);
|
||||
}
|
||||
|
||||
int maxTiles = 0x300 - (CastGraphics.Length / 0x20);
|
||||
_1bppGraphics = new _1bppTile[maxTiles];
|
||||
_1bppGraphics_RotX = new _1bppTile[maxTiles];
|
||||
_1bppGraphics_RotY = new _1bppTile[maxTiles];
|
||||
_1bppGraphics_RotXY = new _1bppTile[maxTiles];
|
||||
int UsedTiles = 0;
|
||||
WritingBuffer[] buffers = new WritingBuffer[renders.Count];
|
||||
|
||||
//Render the text as 1bpp
|
||||
for (int i = 0; i < renders.Count; i++)
|
||||
buffers[i] = renderText(renders[i]);
|
||||
|
||||
for (int i = 0; i < buffers.Length; i++)
|
||||
UsedTiles = insertInGraphics(buffers[i], UsedTiles);
|
||||
|
||||
//Put the arrangements in
|
||||
for (int i = 0; i < renders.Count; i++)
|
||||
{
|
||||
int pos = buffers[i].startPos + 1 + (renders[i].Y * 0x20); //The + 1 is here because the scene's map starts from tile 1. Not tile 0
|
||||
if (renders[i].Separate_file_name == "")
|
||||
for (int j = 0; j < buffers[i].used; j++)
|
||||
for (int k = 0; k < WritingBuffer.yLength; k++)
|
||||
Arrangements[pos + j + (k * 0x20)] = buffers[i].arrangements[k, j];
|
||||
else
|
||||
{
|
||||
//This is an arrangement that changes when the game is running. Set the starting arrangements to empty
|
||||
for (int j = 0; j < buffers[i].used; j++)
|
||||
for (int k = 0; k < WritingBuffer.yLength; k++)
|
||||
Arrangements[pos + j + (k * 0x20)] = 0x3FF; //Empty tile
|
||||
|
||||
//Save this in an external file
|
||||
File.WriteAllBytes(dataFolder + "cast_roll_" + renders[i].Separate_file_name + "_arrangement.bin", prepareSeparateRender(buffers[i]));
|
||||
File.WriteAllBytes(dataFolder + "cast_roll_" + renders[i].Separate_file_name + "_data.bin", prepareSeparateRenderData(buffers[i], renders[i]));
|
||||
File.WriteAllBytes(dataFolder + "cast_roll_" + renders[i].Separate_file_name + "_size.bin", prepareSeparateRenderSize(buffers[i]));
|
||||
}
|
||||
}
|
||||
|
||||
//Convert the 1bpp tiles to 4bpp
|
||||
for (int tile = 0; tile < UsedTiles; tile++)
|
||||
{
|
||||
int basePos = (tile * 0x20) + 0x2000;
|
||||
_1bppTile pre_converted_tile = _1bppGraphics[tile];
|
||||
for (int i = 0; i < 8; i++)
|
||||
{
|
||||
int row = readIntLE(BitsToNybbleLookup, pre_converted_tile.getRow(i) * 4);
|
||||
for (int j = 0; j < 4; j++)
|
||||
Graphics[basePos + (i * 4) + j] = (byte)((row >> (j * 8)) & 0xFF);
|
||||
}
|
||||
}
|
||||
|
||||
//File.WriteAllBytes(dataFolder + "cast_roll_graphics.bin", Graphics);
|
||||
//File.WriteAllBytes(dataFolder + "cast_roll_arrangements.bin", convertUShortArrToByteArrLE(Arrangements));
|
||||
|
||||
File.WriteAllBytes(dataFolder + "cast_roll_first_free.bin", convertUShortToByteArrLE((ushort)(UsedTiles + 0x100)));
|
||||
File.WriteAllBytes(dataFolder + "cast_roll_graphics_[c].bin", GBA.LZ77.Compress(Graphics));
|
||||
File.WriteAllBytes(dataFolder + "cast_roll_arrangements_[c].bin", GBA.LZ77.Compress(convertUShortArrToByteArrLE(Arrangements)));
|
||||
}
|
||||
|
||||
static byte[] prepareSeparateRenderSize(WritingBuffer buf)
|
||||
{
|
||||
byte[] newArr = new byte[1]; //Used in order to have a properly sized buffer
|
||||
newArr[0] = (byte)((buf.used * 2 * WritingBuffer.yLength) & 0xFF);
|
||||
return newArr;
|
||||
}
|
||||
|
||||
static byte[] prepareSeparateRenderData(WritingBuffer buf, Render ren)
|
||||
{
|
||||
byte[] newArr = new byte[8]; //Data used to display the separate arrangements
|
||||
writeUShortToByteArrLE(newArr, 0, (ushort)(buf.startPos + 1)); //The + 1 is needed because the map starts from 1, not from 0
|
||||
writeUShortToByteArrLE(newArr, 2, (ushort)(ren.Y + 0x19)); //Apparently, the actual arrangements start at y = 0x19...
|
||||
writeUShortToByteArrLE(newArr, 4, (ushort)(buf.used));
|
||||
writeUShortToByteArrLE(newArr, 6, (ushort)(WritingBuffer.yLength));
|
||||
return newArr;
|
||||
}
|
||||
|
||||
static byte[] prepareSeparateRender(WritingBuffer buf)
|
||||
{
|
||||
//Converts the arrangements to an array that is to be included separately
|
||||
byte[] newArr = new byte[WritingBuffer.yLength * buf.used * 2];
|
||||
for (int j = 0; j < WritingBuffer.yLength; j++)
|
||||
for (int i = 0; i < buf.used; i++)
|
||||
writeUShortToByteArrLE(newArr, (i + (j * buf.used)) * 2, buf.arrangements[j, i]);
|
||||
|
||||
return newArr;
|
||||
}
|
||||
|
||||
static int readIntLE(byte[] arr, int pos)
|
||||
{
|
||||
return arr[pos] + (arr[pos + 1] << 8) + (arr[pos + 2] << 16) + (arr[pos + 3] << 24);
|
||||
}
|
||||
|
||||
static ushort readUShortLE(byte[] arr, int pos)
|
||||
{
|
||||
return (ushort)(arr[pos] + (arr[pos + 1] << 8));
|
||||
}
|
||||
|
||||
static void writeIntToByteArrLE(byte[] arr, int pos, int val)
|
||||
{
|
||||
for (int i = 0; i < 4; i++)
|
||||
arr[pos + i] = (byte)((val >> (i * 8)) & 0xFF);
|
||||
}
|
||||
|
||||
static void writeUShortToByteArrLE(byte[] arr, int pos, ushort val)
|
||||
{
|
||||
for (int i = 0; i < 2; i++)
|
||||
arr[pos + i] = (byte)((val >> (i * 8)) & 0xFF);
|
||||
}
|
||||
|
||||
static byte[] convertUShortToByteArrLE(ushort val)
|
||||
{
|
||||
byte[] newArr = new byte[2];
|
||||
newArr[0] = (byte)((val) & 0xFF);
|
||||
newArr[1] = (byte)((val >> 8) & 0xFF);
|
||||
return newArr;
|
||||
}
|
||||
|
||||
static byte[] convertUShortArrToByteArrLE(ushort[] arr)
|
||||
{
|
||||
byte[] newArr = new byte[arr.Length * 2];
|
||||
for (int i = 0; i < arr.Length; i++)
|
||||
{
|
||||
newArr[(i * 2)] = (byte)((arr[i]) & 0xFF);
|
||||
newArr[(i * 2) + 1] = (byte)((arr[i] >> 8) & 0xFF);
|
||||
}
|
||||
return newArr;
|
||||
}
|
||||
|
||||
static int insertInGraphics(WritingBuffer buf, int usedInGraphics)
|
||||
{
|
||||
//Optimally inserts the graphics inside the final product
|
||||
int total = usedInGraphics;
|
||||
|
||||
for (int i = 0; i < buf.used; i++)
|
||||
{
|
||||
for (int j = 0; j < WritingBuffer.yLength; j++)
|
||||
{
|
||||
_1bppTile tile = buf.tiles[j, i];
|
||||
|
||||
int rot = 0;
|
||||
int pos = -1;
|
||||
if (emptyTile.Equals(tile))
|
||||
pos = 0x2FF; //Empty tile
|
||||
else
|
||||
pos = getPosInFinal(tile, total, _1bppGraphics);
|
||||
|
||||
if (pos == -1)
|
||||
{
|
||||
rot = 1;
|
||||
pos = getPosInFinal(tile, total, _1bppGraphics_RotX);
|
||||
|
||||
if (pos == -1)
|
||||
{
|
||||
rot = 2;
|
||||
pos = getPosInFinal(tile, total, _1bppGraphics_RotY);
|
||||
|
||||
if (pos == -1)
|
||||
{
|
||||
rot = 3;
|
||||
pos = getPosInFinal(tile, total, _1bppGraphics_RotXY);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (pos == -1) //Hasn't been found in any of the ways the buffer can be looked at
|
||||
{
|
||||
rot = 0;
|
||||
pos = total++;
|
||||
_1bppGraphics[pos] = tile; //If we're here, we already calculated all four of them
|
||||
_1bppGraphics_RotX[pos] = tile.rotateX();
|
||||
_1bppGraphics_RotY[pos] = tile.rotateY();
|
||||
_1bppGraphics_RotXY[pos] = _1bppGraphics_RotX[pos].rotateY();
|
||||
}
|
||||
|
||||
buf.arrangements[j, i] = (ushort)(Palette | (pos + arrStart) | (rot << 0xA));
|
||||
}
|
||||
}
|
||||
|
||||
return total;
|
||||
}
|
||||
|
||||
static int getPosInFinal(_1bppTile tile, int total, _1bppTile[] finalProd)
|
||||
{
|
||||
int pos = -1;
|
||||
for (int k = 0; k < total; k++)
|
||||
if (finalProd[k].Equals(tile))
|
||||
{
|
||||
pos = k;
|
||||
break;
|
||||
}
|
||||
return pos;
|
||||
}
|
||||
|
||||
static WritingBuffer renderText(Render r)
|
||||
{
|
||||
WritingBuffer a = new WritingBuffer();
|
||||
byte[] text = getTextBytes(r.Text);
|
||||
int len = getTextLength(text, r.Font);
|
||||
int x = r.Center_X - (len / 2);
|
||||
|
||||
//Boundary checks
|
||||
if (x + len > 240)
|
||||
x = 240 - len;
|
||||
if (x < 0)
|
||||
x = 0;
|
||||
|
||||
a.startPos = (x >> 3);
|
||||
int bufferPos = x & 7;
|
||||
|
||||
for (int i = 0; i < text.Length; i++)
|
||||
bufferPos += _1bppRenderChar(text[i], bufferPos, r.Font, a);
|
||||
|
||||
a.used = (bufferPos + 7) >> 3;
|
||||
return a;
|
||||
}
|
||||
|
||||
static byte _1bppRenderChar(byte chr, int x, int font, WritingBuffer buf)
|
||||
{
|
||||
//Renders a character
|
||||
int tileHeight = 2;
|
||||
int tileWidth = 2;
|
||||
int tileX = x >> 3;
|
||||
int chrPos = chr * tileWidth * tileHeight * 8;
|
||||
int offsetX = x & 7;
|
||||
int startOffsetY = 3 & 7;
|
||||
if(font == 1) //Saturn font is higher, for some reason...
|
||||
startOffsetY = 0;
|
||||
byte vWidth = Fonts[font].fontWidth[chr * 2];
|
||||
byte rWidth = Fonts[font].fontWidth[(chr * 2) + 1];
|
||||
|
||||
if (font == 1 && vWidth != rWidth) //The Saturn font is compressed horizontally by removing 1 trailing pixel
|
||||
vWidth -= 1;
|
||||
|
||||
for(int dTileY = 0; dTileY < tileHeight; dTileY++)
|
||||
{
|
||||
int dTileX = 0;
|
||||
int renderedWidth = rWidth;
|
||||
while (renderedWidth > 0)
|
||||
{
|
||||
int offsetY = startOffsetY & 7;
|
||||
int tileIndexX = tileX + dTileX;
|
||||
int tileIndexY = dTileY;
|
||||
_1bppTile leftTile = buf.tiles[dTileY, tileIndexX];
|
||||
_1bppTile rightTile = buf.tiles[dTileY, tileIndexX + 1];
|
||||
|
||||
for (int row = 0; row < 8; row++)
|
||||
{
|
||||
ushort canvasRow = (ushort)(leftTile.getRow(row + offsetY) | (rightTile.getRow(row + offsetY) << 8));
|
||||
ushort glyphRow = (ushort)(Fonts[font].font[chrPos + row + (((dTileY * tileWidth) + dTileX) * 8)] << offsetX);
|
||||
|
||||
canvasRow |= glyphRow;
|
||||
leftTile.setRow(row + offsetY, (byte)(canvasRow & 0xFF));
|
||||
rightTile.setRow(row + offsetY, (byte)((canvasRow >> 8) & 0xFF));
|
||||
|
||||
if(row != 7 && row + offsetY == 7)
|
||||
{
|
||||
offsetY = -(row + 1);
|
||||
tileIndexY++;
|
||||
leftTile = buf.tiles[tileIndexY, tileIndexX];
|
||||
rightTile = buf.tiles[tileIndexY, tileIndexX + 1];
|
||||
}
|
||||
}
|
||||
|
||||
renderedWidth -= 8;
|
||||
dTileX++;
|
||||
}
|
||||
}
|
||||
return vWidth;
|
||||
}
|
||||
|
||||
static byte[] getTextBytes(String str)
|
||||
{
|
||||
//Reads a string and converts it to bytes
|
||||
List<byte> tokens = new List<byte>();
|
||||
for (int i = 0; str.Length > 0; i++)
|
||||
{
|
||||
string token = str[0].ToString();
|
||||
str = str.Substring(1);
|
||||
if (token == "[")
|
||||
while (str.Length > 0 && !token.EndsWith("]"))
|
||||
{
|
||||
token += str[0].ToString();
|
||||
str = str.Substring(1);
|
||||
}
|
||||
if (m12CharByteLookup.ContainsKey(token))
|
||||
tokens.Add(m12CharByteLookup[token]);
|
||||
}
|
||||
return tokens.ToArray();
|
||||
}
|
||||
|
||||
static int getTextLength(byte[] text, int Font)
|
||||
{
|
||||
int len = 0;
|
||||
for (int i = 0; i < text.Length; i++)
|
||||
{
|
||||
len += Fonts[Font].fontWidth[2 * text[i]];
|
||||
if (Font == 1 && Fonts[Font].fontWidth[2 * text[i]] != Fonts[Font].fontWidth[(2 * text[i]) + 1]) //Handle Saturn font compression
|
||||
len -= 1;
|
||||
}
|
||||
return len;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
{
|
||||
"profiles": {
|
||||
"ScriptTool": {
|
||||
"commandName": "Project",
|
||||
"commandLineArgs": "-compile -main -misc \"..\\working\" \"..\\eb.smc\" \"..\\m12fresh.gba\"",
|
||||
"workingDirectory": "C:\\Users\\jeffe\\M12\\bin\\ScriptTool"
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>netcoreapp2.1</TargetFramework>
|
||||
<SuppressNETCoreSdkPreviewMessage>true</SuppressNETCoreSdkPreviewMessage>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Newtonsoft.Json" Version="12.0.1" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Update="bits_to_nybbles.bin">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Update="m12-byte-lookup.json">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
|
@ -0,0 +1,132 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
|
||||
namespace RenderCastRoll
|
||||
{
|
||||
public class Render
|
||||
{
|
||||
public int Y { get; set; }
|
||||
public int Center_X { get; set; }
|
||||
public string Text { get; set; }
|
||||
public int Font { get; set; }
|
||||
public string Separate_file_name { get; set; }
|
||||
}
|
||||
|
||||
public class RenderRoot
|
||||
{
|
||||
public List<Render> Renders { get; set; }
|
||||
}
|
||||
|
||||
public class RenderFont
|
||||
{
|
||||
public byte[] font;
|
||||
public byte[] fontWidth;
|
||||
|
||||
public RenderFont(string folder, string fontName)
|
||||
{
|
||||
font = File.ReadAllBytes(folder + "m2-font-" + fontName + ".bin");
|
||||
fontWidth = File.ReadAllBytes(folder + "m2-widths-" + fontName + ".bin");
|
||||
}
|
||||
}
|
||||
|
||||
public class _1bppTile
|
||||
{
|
||||
UInt64 tile;
|
||||
|
||||
public _1bppTile() : this(0) { }
|
||||
|
||||
public _1bppTile(UInt64 val)
|
||||
{
|
||||
tile = val;
|
||||
}
|
||||
|
||||
public byte getRow(int i)
|
||||
{
|
||||
return (byte)((tile >> (i * 8)) & 0xFF);
|
||||
}
|
||||
|
||||
public void setRow(int i, byte val)
|
||||
{
|
||||
UInt64 mask = ~((UInt64)(0xFF) << (i * 8));
|
||||
tile = (tile & mask) | ((UInt64)val << (i * 8));
|
||||
}
|
||||
|
||||
public UInt64 getColumn(int i)
|
||||
{
|
||||
UInt64 mask = (UInt64)(0x0101010101010101 << i);
|
||||
return mask & tile;
|
||||
}
|
||||
|
||||
public void setColumn(int i, UInt64 val)
|
||||
{
|
||||
UInt64 mask = ~(UInt64)(0x0101010101010101 << i);
|
||||
tile = (tile & mask) | val;
|
||||
}
|
||||
|
||||
public bool Equals(_1bppTile t)
|
||||
{
|
||||
return this.tile == t.tile;
|
||||
}
|
||||
|
||||
public _1bppTile rotateX()
|
||||
{
|
||||
_1bppTile newTile = new _1bppTile(tile);
|
||||
for (int row = 0; row < 8; row++)
|
||||
{
|
||||
byte val = newTile.getRow(row);
|
||||
byte newVal = 0;
|
||||
for (int i = 0; i < 8; i++)
|
||||
newVal |= (byte)(((val >> i) & 1) << (7 - i));
|
||||
newTile.setRow(row, newVal);
|
||||
}
|
||||
return newTile;
|
||||
}
|
||||
|
||||
public _1bppTile rotateY()
|
||||
{
|
||||
_1bppTile newTile = new _1bppTile(tile);
|
||||
for (int column = 0; column < 8; column++)
|
||||
{
|
||||
UInt64 val = newTile.getColumn(column);
|
||||
UInt64 newVal = 0;
|
||||
for (int i = 0; i < 8; i++)
|
||||
newVal |= ((val >> (i * 8)) & 0xFF) << ((7 - i) * 8);
|
||||
newTile.setColumn(column, newVal);
|
||||
}
|
||||
return newTile;
|
||||
}
|
||||
|
||||
public override String ToString()
|
||||
{
|
||||
String str = "";
|
||||
for (int i = 0; i < 8; i++)
|
||||
str += getRow(i).ToString("X") + " ";
|
||||
return str;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public class WritingBuffer
|
||||
{
|
||||
public static readonly int yLength = 3;
|
||||
public _1bppTile[,] tiles;
|
||||
public ushort[,] arrangements;
|
||||
public int used;
|
||||
public int startPos;
|
||||
|
||||
public WritingBuffer()
|
||||
{
|
||||
used = 0;
|
||||
startPos = 0;
|
||||
tiles = new _1bppTile[yLength, 0x20];
|
||||
arrangements = new ushort[yLength, 0x20];
|
||||
for (int i = 0; i < yLength; i++)
|
||||
for (int j = 0; j < 0x20; j++)
|
||||
{
|
||||
tiles[i, j] = new _1bppTile();
|
||||
arrangements[i, j] = 0x3FF; //Empty tile
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Binary file not shown.
|
@ -0,0 +1,99 @@
|
|||
{
|
||||
" ": 0,
|
||||
"!": 1,
|
||||
"\"": 2,
|
||||
"#": 3,
|
||||
"$": 4,
|
||||
"%": 5,
|
||||
"&": 6,
|
||||
"'": 7,
|
||||
"(": 8,
|
||||
")": 9,
|
||||
"*": 10,
|
||||
"+": 11,
|
||||
",": 12,
|
||||
"-": 13,
|
||||
".": 129,
|
||||
"/": 15,
|
||||
"0": 16,
|
||||
"1": 17,
|
||||
"2": 18,
|
||||
"3": 19,
|
||||
"4": 20,
|
||||
"5": 21,
|
||||
"6": 22,
|
||||
"7": 23,
|
||||
"8": 24,
|
||||
"9": 25,
|
||||
":": 26,
|
||||
";": 27,
|
||||
"<": 28,
|
||||
"=": 29,
|
||||
">": 30,
|
||||
"?": 31,
|
||||
"@": 32,
|
||||
"A": 33,
|
||||
"B": 34,
|
||||
"C": 35,
|
||||
"D": 36,
|
||||
"E": 37,
|
||||
"F": 38,
|
||||
"G": 39,
|
||||
"H": 40,
|
||||
"I": 41,
|
||||
"J": 42,
|
||||
"K": 43,
|
||||
"L": 44,
|
||||
"M": 45,
|
||||
"N": 46,
|
||||
"O": 47,
|
||||
"P": 48,
|
||||
"Q": 49,
|
||||
"R": 50,
|
||||
"S": 51,
|
||||
"T": 52,
|
||||
"U": 53,
|
||||
"V": 54,
|
||||
"W": 55,
|
||||
"X": 56,
|
||||
"Y": 57,
|
||||
"Z": 58,
|
||||
"[8B]": 59,
|
||||
"[8C]": 60,
|
||||
"[8D]": 61,
|
||||
"[8E]": 62,
|
||||
"[8F]": 63,
|
||||
"`": 64,
|
||||
"a": 65,
|
||||
"b": 66,
|
||||
"c": 67,
|
||||
"d": 68,
|
||||
"e": 69,
|
||||
"f": 70,
|
||||
"g": 71,
|
||||
"h": 72,
|
||||
"i": 73,
|
||||
"j": 74,
|
||||
"k": 75,
|
||||
"l": 76,
|
||||
"m": 77,
|
||||
"n": 78,
|
||||
"o": 79,
|
||||
"p": 80,
|
||||
"q": 81,
|
||||
"r": 82,
|
||||
"s": 83,
|
||||
"t": 84,
|
||||
"u": 85,
|
||||
"v": 86,
|
||||
"w": 87,
|
||||
"x": 88,
|
||||
"y": 89,
|
||||
"z": 90,
|
||||
"{": 91,
|
||||
"|": 92,
|
||||
"}": 93,
|
||||
"~": 94,
|
||||
"[AF]": 95,
|
||||
"[DOT]": 128
|
||||
}
|
|
@ -0,0 +1,361 @@
|
|||
{
|
||||
"Renders":[
|
||||
{
|
||||
"Y":16,
|
||||
"Center_X":120,
|
||||
"Text":"Picky Minch",
|
||||
"Font": 0,
|
||||
"Separate_file_name": ""
|
||||
},
|
||||
{
|
||||
"Y":24,
|
||||
"Center_X":64,
|
||||
"Text":"Lardna Minch",
|
||||
"Font": 0,
|
||||
"Separate_file_name": ""
|
||||
},
|
||||
{
|
||||
"Y":24,
|
||||
"Center_X":176,
|
||||
"Text":"Aloysius Minch",
|
||||
"Font": 0,
|
||||
"Separate_file_name": ""
|
||||
},
|
||||
{
|
||||
"Y":32,
|
||||
"Center_X":120,
|
||||
"Text":"Pokey Minch",
|
||||
"Font": 0,
|
||||
"Separate_file_name": ""
|
||||
},
|
||||
{
|
||||
"Y":42,
|
||||
"Center_X":120,
|
||||
"Text":"Buzz Buzz",
|
||||
"Font": 0,
|
||||
"Separate_file_name": ""
|
||||
},
|
||||
{
|
||||
"Y":51,
|
||||
"Center_X":120,
|
||||
"Text":"Lier`X.`Agerate",
|
||||
"Font": 0,
|
||||
"Separate_file_name": ""
|
||||
},
|
||||
{
|
||||
"Y":62,
|
||||
"Center_X":120,
|
||||
"Text":"Frank Fly",
|
||||
"Font": 0,
|
||||
"Separate_file_name": ""
|
||||
},
|
||||
{
|
||||
"Y":71,
|
||||
"Center_X":120,
|
||||
"Text":"The Sharks",
|
||||
"Font": 0,
|
||||
"Separate_file_name": ""
|
||||
},
|
||||
{
|
||||
"Y":82,
|
||||
"Center_X":120,
|
||||
"Text":"B. H. Pirkle",
|
||||
"Font": 0,
|
||||
"Separate_file_name": ""
|
||||
},
|
||||
{
|
||||
"Y":93,
|
||||
"Center_X":120,
|
||||
"Text":"Captain Strong",
|
||||
"Font": 0,
|
||||
"Separate_file_name": ""
|
||||
},
|
||||
{
|
||||
"Y":102,
|
||||
"Center_X":120,
|
||||
"Text":"Onett police force",
|
||||
"Font": 0,
|
||||
"Separate_file_name": ""
|
||||
},
|
||||
{
|
||||
"Y":109,
|
||||
"Center_X":120,
|
||||
"Text":"[DOT]",
|
||||
"Font": 0,
|
||||
"Separate_file_name": ""
|
||||
},
|
||||
{
|
||||
"Y":139,
|
||||
"Center_X":120,
|
||||
"Text":"Orange kid",
|
||||
"Font": 0,
|
||||
"Separate_file_name": ""
|
||||
},
|
||||
{
|
||||
"Y":148,
|
||||
"Center_X":120,
|
||||
"Text":"Apple kid",
|
||||
"Font": 0,
|
||||
"Separate_file_name": ""
|
||||
},
|
||||
{
|
||||
"Y":159,
|
||||
"Center_X":120,
|
||||
"Text":"Mr. Everdred",
|
||||
"Font": 0,
|
||||
"Separate_file_name": ""
|
||||
},
|
||||
{
|
||||
"Y":175,
|
||||
"Center_X":120,
|
||||
"Text":"Runaway Five",
|
||||
"Font": 0,
|
||||
"Separate_file_name": ""
|
||||
},
|
||||
{
|
||||
"Y":182,
|
||||
"Center_X":120,
|
||||
"Text":"[DOT]",
|
||||
"Font": 0,
|
||||
"Separate_file_name": ""
|
||||
},
|
||||
{
|
||||
"Y":194,
|
||||
"Center_X":120,
|
||||
"Text":"Happy Happyists",
|
||||
"Font": 0,
|
||||
"Separate_file_name": ""
|
||||
},
|
||||
{
|
||||
"Y":204,
|
||||
"Center_X":120,
|
||||
"Text":"Carpainter",
|
||||
"Font": 0,
|
||||
"Separate_file_name": ""
|
||||
},
|
||||
{
|
||||
"Y":211,
|
||||
"Center_X":120,
|
||||
"Text":"[DOT]",
|
||||
"Font": 0,
|
||||
"Separate_file_name": ""
|
||||
},
|
||||
{
|
||||
"Y":223,
|
||||
"Center_X":120,
|
||||
"Text":"Bubble Monkey",
|
||||
"Font": 0,
|
||||
"Separate_file_name": ""
|
||||
},
|
||||
{
|
||||
"Y":230,
|
||||
"Center_X":64,
|
||||
"Text":"Tony",
|
||||
"Font": 0,
|
||||
"Separate_file_name": ""
|
||||
},
|
||||
{
|
||||
"Y":230,
|
||||
"Center_X":176,
|
||||
"Text":"Maxwell",
|
||||
"Font": 0,
|
||||
"Separate_file_name": ""
|
||||
},
|
||||
{
|
||||
"Y":237,
|
||||
"Center_X":120,
|
||||
"Text":"Tessie",
|
||||
"Font": 0,
|
||||
"Separate_file_name": ""
|
||||
},
|
||||
{
|
||||
"Y":245,
|
||||
"Center_X":120,
|
||||
"Text":"Tessie-Watching Club",
|
||||
"Font": 0,
|
||||
"Separate_file_name": ""
|
||||
},
|
||||
{
|
||||
"Y":257,
|
||||
"Center_X":120,
|
||||
"Text":"Brickroad",
|
||||
"Font": 0,
|
||||
"Separate_file_name": ""
|
||||
},
|
||||
{
|
||||
"Y":272,
|
||||
"Center_X":80,
|
||||
"Text":"Dr. Andonuts",
|
||||
"Font": 0,
|
||||
"Separate_file_name": ""
|
||||
},
|
||||
{
|
||||
"Y":290,
|
||||
"Center_X":120,
|
||||
"Text":"[DOT]",
|
||||
"Font": 0,
|
||||
"Separate_file_name": ""
|
||||
},
|
||||
{
|
||||
"Y":313,
|
||||
"Center_X":120,
|
||||
"Text":"mr.saturn",
|
||||
"Font": 1,
|
||||
"Separate_file_name": ""
|
||||
},
|
||||
{
|
||||
"Y":325,
|
||||
"Center_X":120,
|
||||
"Text":"Master Belch",
|
||||
"Font": 0,
|
||||
"Separate_file_name": "master_belch"
|
||||
},
|
||||
{
|
||||
"Y":332,
|
||||
"Center_X":120,
|
||||
"Text":"[DOT]",
|
||||
"Font": 0,
|
||||
"Separate_file_name": ""
|
||||
},
|
||||
{
|
||||
"Y":344,
|
||||
"Center_X":64,
|
||||
"Text":"George Montague",
|
||||
"Font": 0,
|
||||
"Separate_file_name": ""
|
||||
},
|
||||
{
|
||||
"Y":354,
|
||||
"Center_X":120,
|
||||
"Text":"Gerardo Montague",
|
||||
"Font": 0,
|
||||
"Separate_file_name": ""
|
||||
},
|
||||
{
|
||||
"Y":371,
|
||||
"Center_X":120,
|
||||
"Text":"Talah Rama",
|
||||
"Font": 0,
|
||||
"Separate_file_name": ""
|
||||
},
|
||||
{
|
||||
"Y":378,
|
||||
"Center_X":120,
|
||||
"Text":"[DOT]",
|
||||
"Font": 0,
|
||||
"Separate_file_name": ""
|
||||
},
|
||||
{
|
||||
"Y":389,
|
||||
"Center_X":120,
|
||||
"Text":"Geldegarde Monotoli",
|
||||
"Font": 0,
|
||||
"Separate_file_name": ""
|
||||
},
|
||||
{
|
||||
"Y":400,
|
||||
"Center_X":120,
|
||||
"Text":"Venus",
|
||||
"Font": 0,
|
||||
"Separate_file_name": ""
|
||||
},
|
||||
{
|
||||
"Y":407,
|
||||
"Center_X":120,
|
||||
"Text":"[DOT]",
|
||||
"Font": 0,
|
||||
"Separate_file_name": ""
|
||||
},
|
||||
{
|
||||
"Y":429,
|
||||
"Center_X":64,
|
||||
"Text":"Star Master",
|
||||
"Font": 0,
|
||||
"Separate_file_name": "star_master"
|
||||
},
|
||||
{
|
||||
"Y":438,
|
||||
"Center_X":120,
|
||||
"Text":"[DOT]",
|
||||
"Font": 0,
|
||||
"Separate_file_name": ""
|
||||
},
|
||||
{
|
||||
"Y":457,
|
||||
"Center_X":120,
|
||||
"Text":"Dungeon Man",
|
||||
"Font": 0,
|
||||
"Separate_file_name": ""
|
||||
},
|
||||
{
|
||||
"Y":457,
|
||||
"Center_X":192,
|
||||
"Text":"Noble warrior",
|
||||
"Font": 0,
|
||||
"Separate_file_name": ""
|
||||
},
|
||||
{
|
||||
"Y":464,
|
||||
"Center_X":120,
|
||||
"Text":"[DOT]",
|
||||
"Font": 0,
|
||||
"Separate_file_name": ""
|
||||
},
|
||||
{
|
||||
"Y":474,
|
||||
"Center_X":120,
|
||||
"Text":"Tenda tribesmen",
|
||||
"Font": 0,
|
||||
"Separate_file_name": ""
|
||||
},
|
||||
{
|
||||
"Y":481,
|
||||
"Center_X":120,
|
||||
"Text":"[DOT]",
|
||||
"Font": 0,
|
||||
"Separate_file_name": ""
|
||||
},
|
||||
{
|
||||
"Y":497,
|
||||
"Center_X":120,
|
||||
"Text":"Flying Men",
|
||||
"Font": 0,
|
||||
"Separate_file_name": ""
|
||||
},
|
||||
{
|
||||
"Y":504,
|
||||
"Center_X":120,
|
||||
"Text":"[DOT]",
|
||||
"Font": 0,
|
||||
"Separate_file_name": ""
|
||||
},
|
||||
{
|
||||
"Y":558,
|
||||
"Center_X":120,
|
||||
"Text":"[DOT]",
|
||||
"Font": 0,
|
||||
"Separate_file_name": ""
|
||||
},
|
||||
{
|
||||
"Y":570,
|
||||
"Center_X":96,
|
||||
"Text":"Dad",
|
||||
"Font": 0,
|
||||
"Separate_file_name": ""
|
||||
},
|
||||
{
|
||||
"Y":579,
|
||||
"Center_X":72,
|
||||
"Text":"Tracy",
|
||||
"Font": 0,
|
||||
"Separate_file_name": ""
|
||||
},
|
||||
{
|
||||
"Y":579,
|
||||
"Center_X":168,
|
||||
"Text":"Mom",
|
||||
"Font": 0,
|
||||
"Separate_file_name": ""
|
||||
}
|
||||
]
|
||||
}
|
|
@ -2202,7 +2202,7 @@
|
|||
^L2186^[1C FF 02 00 _L2188_]@Good morning everyone![1B FF 14 00] Are[01 FF] you ready for your adventure?[02 FF]@I think all of you are the bee's[01 FF] knees.[1B FF 14 00] Yes,[1B FF 0A 00] I do![02 FF]^L2188^@You are all so... cool![1B FF 14 00] Yes,[1B FF 0A 00][01 FF] you're hip![1D FF][00 FF]
|
||||
^L2192^[92 FF 03 01 02][81 FF _L3986_][92 FF 03 01 03][81 FF _L3986_][1C FF B8 02 _L3987_][FB FF 64 00]^L3988^[82 FF _L3986_]@Working through the night,[01 FF] [0F FF] fixed[01 FF] the [90 FF 00][1A FF 02 00].[02 FF]@After being fixed, the[01 FF] [90 FF 00][1A FF 02 00] became[01 FF] the [87 FF][90 FF 00][1A FF 02 00].[02 FF][08 FF B8 02][C6 FF]^L3986^[00 FF]
|
||||
^L2193^@[0D FF],[1B FF 0F 00] could you get the[01 FF] phone?[1D FF][00 FF]
|
||||
^L2194^@Did you finish doing everything[01 FF] that you wanted to?[22 FF][03 FF 00 00][04 FF _L2198_][05 FF _L2199_]^L2199^@You'd better do everything,[1B FF 0F 00][01 FF] because once you start looking[01 FF] at the album,[02 FF]@you can't stop![1D FF][00 FF]^L2198^@Okay![1B FF 14 00] Now you can finally[01 FF] share your incredible[01 FF] experiences with me...[02 FF]@You did so well![02 FF][C6 FF][86 FF _L2200_][86 FF _L2201_][C4 FF 00 5E][D9 FF 05 00][1C FF 7E 02 _L2202_][CB FF 02 00 06 00][A0 FF 01 00 12 03 01 00][1B FF 01 00][A6 FF 01 00 01 00]^L2202^[CB FF 01 00 06 00][A0 FF 00 00 21 03 01 00][1B FF 01 00][A6 FF 00 00 01 00][CE FF 0E 00 05 00][A1 FF 0E 00 01 00][CE FF 12 00 05 00][A1 FF 12 00 01 00][1B FF 78 00][1B FF 78 00][1B FF 78 00][1B FF 78 00][1B FF 78 00][1B FF 3C 00][A0 FF 29 00 C0 02 01 00][1B FF 3C 00][1B FF 64 00][A0 FF D0 07 C1 02 01 00][9E FF][86 FF _L2201_][FC FF 13 00][14 FF 6E 00][FC FF 2E 00][FC FF 14 00][C4 FF 00 5F][A0 FF 47 00 F5 02 01 00][9E FF][A0 FF B4 02 F6 02 01 00][9E FF][A0 FF 19 01 F7 02 01 00][9E FF][FC FF 13 00][14 FF 89 00][CB FF FF 00 06 00][FC FF 0C 00][9E FF][1B FF 3C 00][FC FF 15 00][86 FF _L2203_][00 FF]
|
||||
^L2194^@Did you finish doing everything[01 FF] that you wanted to?[22 FF][03 FF 00 00][04 FF _L2198_][05 FF _L2199_]^L2199^@You'd better do everything,[1B FF 0F 00][01 FF] because once you start looking[01 FF] at the album,[02 FF]@you can't stop![1D FF][00 FF]^L2198^@Okay![1B FF 14 00] Now you can finally[01 FF] share your incredible[01 FF] experiences with me...[02 FF]@You did so well![02 FF][C6 FF][86 FF _L2200_][86 FF _L2201_][C4 FF 00 5E][D9 FF 05 00][1C FF 7E 02 _L2202_][CB FF 02 00 06 00][A0 FF 01 00 12 03 01 00][1B FF 01 00][A6 FF 01 00 01 00]^L2202^[CB FF 01 00 06 00][A0 FF 00 00 21 03 01 00][1B FF 01 00][A6 FF 00 00 01 00][CE FF 0E 00 05 00][A1 FF 0E 00 01 00][CE FF 12 00 05 00][A1 FF 12 00 01 00][1B FF 78 00][1B FF 78 00][1B FF 78 00][1B FF 78 00][1B FF 78 00][1B FF 3C 00][A0 FF 29 00 C0 02 01 00][1B FF 3C 00][1B FF 64 00][A0 FF D0 07 C1 02 01 00][9E FF][FC FF 0B 00][14 FF 88 00][FC FF 2D 00][A0 FF D0 07 C2 02 01 00][CB FF FF 00 06 00][9E FF][86 FF _L2201_][FC FF 13 00][14 FF 6E 00][FC FF 2E 00][FC FF 14 00][C4 FF 00 5F][A0 FF 47 00 F5 02 01 00][9E FF][A0 FF B4 02 F6 02 01 00][9E FF][A0 FF 19 01 F7 02 01 00][9E FF][FC FF 13 00][14 FF 89 00][CB FF FF 00 06 00][FC FF 0C 00][9E FF][1B FF 3C 00][FC FF 15 00][86 FF _L2203_][00 FF]
|
||||
^L2195^^L2196^@After all your chats with people[01 FF] you met on your adventure are[01 FF] finally over,[02 FF]@please come back here.[02 FF]@The photo-man brought an[01 FF] album by.[02 FF]@I'd like to look at it with you...[1D FF][C6 FF][08 FF 83 02][83 FF 8E 02][82 FF _L2197_][1B FF 3C 00][A1 FF 15 00 7B 00][08 FF F1 02][00 FF]
|
||||
^L2197^[00 FF]
|
||||
^L2200^[09 FF B4 00][09 FF B5 00][09 FF 85 02][09 FF BE 01][09 FF 86 02][09 FF 87 02][09 FF 88 02][09 FF B6 02][09 FF B7 02][86 FF _L4002_][09 FF F2 02][FC FF 3A 00][00 FF]
|
||||
|
@ -3658,7 +3658,7 @@
|
|||
^L4038^[08 FF 3C 00][14 FF 86 00][FC FF 16 00][AF FF 02][EA FF FF 00][A0 FF D0 07 BE 02 01 00][1B FF 01 00][C9 FF D0 07][EB FF FF 00][00 FF]
|
||||
^L4039^[EA FF FF 00][14 FF 87 00][FC FF 16 00][AF FF 03][A0 FF D0 07 BF 02 01 00][1B FF 01 00][C9 FF D0 07][EB FF FF 00][9E FF][FC FF 17 00][9E FF][FC FF 19 00][00 FF]
|
||||
^L4040^[1B FF 01 00][C9 FF D0 07][EB FF FF 00][9E FF][CA FF][EA FF FF 00][00 FF]
|
||||
^L4041^[74 FF][D4 FF 08 00][A0 FF D0 07 14 00 01 00][86 FF _L4040_][A0 FF 2D 00 FA 02 01 00][85 FF 16 00 06 00][D4 FF 09 00][CA FF][DC FF 2D 00 01 00 01 00][DA FF 2D 00 00 00][C3 FF 01 03 2D 00][D8 FF 01 00 00 00][EA FF FF 00][1B FF 01 00][AA FF 2D 00][09 FF 27 01][08 FF D3 01][08 FF 61 00][1B FF 1E 00][C4 FF 00 B1][1B FF 78 00][1B FF 78 00][1B FF 14 00]@A letter arrived from my[01 FF] brother, Pokey...[1B FF 0F 00] it is[01 FF] addressed to [0D FF].[02 FF]@There's no stamp,[1B FF 0F 00] and it's not[01 FF] time for the mailman to come...[02 FF]@Anyway, I brought it over.[02 FF]@It says,[1B FF 0F 00] <come and get me,[01 FF] loser![02 FF]@Spankety, spankety, spankety.>[02 FF]@...I wonder where he is?[1D FF][1B FF 14 00][C6 FF][1B FF 01 00][08 FF D1 00][FC FF 1E 00][9E FF][CB FF FF 00 06 00][09 FF 83 02][09 FF D1 00][08 FF DA 01][14 FF 6E 00][FC FF 1F 00][1B FF 3C 00][1B FF 3C 00][1B FF 3C 00][1B FF 3C 00][1B FF 3C 00][1B FF 3C 00][1B FF 3C 00][1B FF 3C 00][FC FF 35 00][00 FF]
|
||||
^L4041^[74 FF][D4 FF 08 00][A0 FF D0 07 14 00 01 00][86 FF _L4040_][A0 FF 2D 00 FA 02 01 00][85 FF 16 00 06 00][D4 FF 09 00][CA FF][DC FF 2D 00 01 00 01 00][DA FF 2D 00 00 00][C3 FF 01 03 2D 00][D8 FF 01 00 00 00][EA FF FF 00][1B FF 01 00][AA FF 2D 00][09 FF 27 01][08 FF D3 01][08 FF 61 00][1B FF 1E 00][C4 FF 00 B1][1B FF 78 00][1B FF 78 00][1B FF 14 00]@A letter arrived from my[01 FF] brother, Pokey...[1B FF 0F 00] it is[01 FF] addressed to [0D FF].[02 FF]@There's no stamp,[1B FF 0F 00] and it's not[01 FF] time for the mailman to come...[02 FF]@Anyway, I brought it over.[02 FF]@It says,[1B FF 0F 00] <come and get me,[01 FF] loser![02 FF]@Spankety, spankety, spankety.>[02 FF]@...I wonder where he is?[1D FF][1B FF 14 00][C6 FF][1B FF 01 00][08 FF D1 00][FC FF 1E 00][9E FF][CB FF FF 00 06 00][09 FF 83 02][09 FF D1 00][08 FF DA 01][14 FF 6E 00][FC FF 1F 00][1B FF 3C 00][FC FF 49 00][1B FF 3C 00][1B FF 3C 00][1B FF 3C 00][1B FF 3C 00][1B FF 3C 00][1B FF 3C 00][1B FF 3C 00][1B FF 3C 00][FC FF 35 00][00 FF]
|
||||
^L4042^[C6 FF][AE FF 06][CB FF 06 00 06 00][A6 FF 2D 00 16 00][9E FF][A5 FF 2D 00 06 00][CC FF 06 00 01 00][C4 FF 00 7B][1B FF 78 00][1B FF 3C 00][C5 FF]@(Picky joins you.)[02 FF][C6 FF][00 FF]
|
||||
^L4043^[FC FF 33 00][6E FF 01 00][C3 FF 05 01 01 00][D8 FF 05 00 00 00][C3 FF 01 01 05 00][D8 FF 01 00 00 00]@[0D FF]![02 FF]@Do you hear a buzzing that[01 FF] sounds like a bee flying around?[22 FF][03 FF 00 00][04 FF _L4046_][05 FF _L4047_]^L4047^@Oh, c'mon...[1B FF 14 00] You must hear[01 FF] it...[02 FF][80 FF _L4048_]^L4046^@Yes! You can hear it![02 FF]^L4048^[C6 FF][C4 FF 00 76][1B FF 3C 00][C3 FF 01 02 C6 00][D8 FF 01 00 00 00][C3 FF 05 02 C6 00][D8 FF 05 00 00 00][C3 FF 06 02 C6 00][D8 FF 06 00 00 00][A9 FF 35 01][A0 FF D0 07 24 00 01 00][9E FF][A0 FF D5 00 25 00 01 00][9E FF]^L4051^@A bee I am[02 FF]@not...[02 FF]@I'm from 10 years in the[01 FF] future.[02 FF]@And,[02 FF]@in the future,[1B FF 0F 00] all is[01 FF] devastation...[02 FF]@Giygas, the universal cosmic[01 FF] destroyer,[02 FF]@sent all to the horror of eternal[01 FF] darkness...[02 FF]@.....[02 FF]@However,[1B FF 14 00] you must listen![02 FF]@Where I am from,[02 FF]@there is a well-known legend[01 FF] that has been handed down[01 FF] from ancient times.[02 FF]@It says <When the chosen boy[01 FF] reaches the point,[1B FF 0F 00] he will find[01 FF] the light.[02 FF]@The passing of time will shatter[01 FF] the nightmare rock[02 FF]@and will reveal the path of[01 FF] light.>[02 FF]@You see,[1B FF 0F 00] it is my opinion that[01 FF] you are that boy, [0D FF].[02 FF]@This I believe...[02 FF]@.....[02 FF]@Giygas' monstrous plan must[01 FF] have been set in motion[01 FF] somewhere on Earth...[02 FF]@If you start to confront the[01 FF] enemy immediately,[02 FF]@you may have time to counter[01 FF] the evil intentions of Giygas.[02 FF]@Three things are of the utmost[01 FF] importance:[1B FF 1E 00] wisdom,[1B FF 0F 00] courage,[1B FF 14 00][01 FF] and friendship.[02 FF]@...The legends from the ancient[01 FF] times tell of three boys and a[01 FF] girl[02 FF]@who defeat Giygas.[02 FF]@...I will tell you more later.[02 FF]@Go now![1B FF 14 00] And do not be anxious[01 FF] about the future.[02 FF]@You have much work to do,[01 FF] [0D FF].[02 FF]@Did you listen to what I told[01 FF] you?[03 FF 00 00][04 FF _L4049_][05 FF _L4050_]^L4050^@I hate to go over it again,[1B FF 0F 00] but I[01 FF] guess I'll start over...[02 FF]@We'll be here 'til sunrise![02 FF][C7 FF][80 FF _L4051_]^L4049^@Thank you for listening to my[01 FF] long story.[02 FF]@You are as exceptional as I[01 FF] expected you to be...[02 FF][C6 FF][C4 FF 00 0B][1B FF 78 00][1B FF 3C 00][1B FF 78 00][1B FF 78 00]@Buzz Buzz now joins you.[02 FF][C6 FF][A9 FF D5 00][08 FF 12 00][C5 FF][A9 FF D5 00][1B FF 3C 00][B2 FF 05 00 CC 00][1B FF 3C 00][B5 FF 05 00][AA FF D5 00]@[0D FF]![02 FF]@It looks like you're really in a lot[01 FF] of trouble this time...[02 FF]@Three boys,[1B FF 0F 00] he said? ...Uhhh...[02 FF]@I'm not one of those three, am[01 FF] I?...[02 FF]@...'Cause... I'm not into this kind[01 FF] of thing at all...[02 FF]@Geez.[1B FF 14 00] My heart is almost[01 FF] pounding right out of my[01 FF] chest!...[02 FF][C6 FF][9D FF 01 2B _L3912_][FC FF 34 00][00 FF]
|
||||
^L4044^[AF FF 07][00 FF]
|
||||
|
|
Loading…
Reference in New Issue