Lumine Hall's VWF
This commit is contained in:
parent
2ad223a8cb
commit
d3826d7662
|
@ -19,7 +19,8 @@ $input_c_files =
|
|||
"src/c/status.c",
|
||||
"src/c/battle.c",
|
||||
"src/c/equip.c",
|
||||
"src/c/psi.c"
|
||||
"src/c/psi.c",
|
||||
"src/c/luminehall.c"
|
||||
|
||||
$base_c_address = 0x83755B8;
|
||||
$scripttool_cmd = "bin/ScriptTool/ScriptTool.dll"
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
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) {}
|
||||
|
|
|
@ -0,0 +1,305 @@
|
|||
#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];
|
||||
setTilesToBlank(Tiles);
|
||||
//First things first, it calculates the total length of the text in pixels
|
||||
while((*lumineText_curr_ptr) != END)
|
||||
{
|
||||
length += getCharWidth(*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 & 8 == 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 tileWidth = 2;
|
||||
int tileHeight = 2;
|
||||
int chosenLen;
|
||||
int renderedLen;
|
||||
byte *glyphRows;
|
||||
int AlternativeTiles[4];
|
||||
switch(chr)
|
||||
{
|
||||
case END:
|
||||
return;
|
||||
case ENDL:
|
||||
printEmptyLumineTile(Tiles, hallAddress, length, *currPos, *currLen);
|
||||
(*currPos)++;
|
||||
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, Tiles, AlternativeTiles, hallAddress, length, currPos, currLen);
|
||||
return;
|
||||
default:
|
||||
chosenLen = m2_widths_table[0][chr] & 0xFF;
|
||||
renderedLen = m2_widths_table[0][chr] >> 8;
|
||||
glyphRows = &m2_font_table[0][chr * tileWidth * tileHeight * 8];
|
||||
}
|
||||
if(chosenLen <= 0)
|
||||
return;
|
||||
if(((*currLen) + chosenLen) >= 8)
|
||||
{
|
||||
setTilesToBlank(AlternativeTiles);
|
||||
if(renderedLen > 0)
|
||||
printLumineCharacterInMultiTiles(Tiles, AlternativeTiles, glyphRows, renderedLen, *currLen);
|
||||
printLumineTiles(Tiles, hallAddress, length, *currPos);
|
||||
(*currPos)++;
|
||||
copyTiles(Tiles, AlternativeTiles);
|
||||
(*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);
|
||||
setTilesToBlank(Tiles);
|
||||
}
|
||||
}
|
||||
|
||||
void readLumineCharacterName(byte* str, int *Tiles, int* AlternativeTiles, 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
|
||||
int tileWidth = 2;
|
||||
int tileHeight = 2;
|
||||
int chosenLen;
|
||||
int renderedLen;
|
||||
byte *glyphRows;
|
||||
for(int i = 0; i < PC_NAME_SIZE; i++)
|
||||
{
|
||||
if(*(str + 1) == 0xFF)
|
||||
return;
|
||||
byte chr = decode_character(*(str++));
|
||||
chosenLen = m2_widths_table[0][chr] & 0xFF;
|
||||
renderedLen = m2_widths_table[0][chr] >> 8;
|
||||
glyphRows = &m2_font_table[0][chr * tileWidth * tileHeight * 8];
|
||||
if(chosenLen <= 0)
|
||||
continue;
|
||||
if(((*currLen) + chosenLen) >= 8)
|
||||
{
|
||||
setTilesToBlank(AlternativeTiles);
|
||||
if(renderedLen > 0)
|
||||
printLumineCharacterInMultiTiles(Tiles, AlternativeTiles, glyphRows, renderedLen, *currLen);
|
||||
printLumineTiles(Tiles, hallAddress, length, *currPos);
|
||||
(*currPos)++;
|
||||
copyTiles(Tiles, AlternativeTiles);
|
||||
(*currLen) = ((*currLen) + chosenLen) & 7;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(renderedLen > 0)
|
||||
printLumineCharacterInSingleTiles(Tiles, glyphRows, renderedLen, *currLen);
|
||||
(*currLen) += chosenLen;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void printLumineCharacterInMultiTiles(int *Tiles, int *AlternativeTiles, 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 = 2;
|
||||
int tileHeight = 2;
|
||||
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 alternativeTile = AlternativeTiles[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)] << currLen;
|
||||
else if(dTileY == 1)
|
||||
glyphRow = glyphRows[row + (half * 4) - startY + 8] << currLen;
|
||||
canvasRow |= glyphRow;
|
||||
endingTile |= (canvasRow & 0xFF) << (8 * row);
|
||||
endingAlternativeTile |= ((canvasRow >> 8) & 0xFF) << (8 * row);
|
||||
}
|
||||
Tiles[tileIndex + half] = endingTile;
|
||||
AlternativeTiles[tileIndex + half] = endingAlternativeTile;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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 = 2;
|
||||
int tileHeight = 2;
|
||||
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 copyTiles(int *Tiles, int* AlternativeTiles)
|
||||
{
|
||||
for(int i = 0; i < 4; i++)
|
||||
Tiles[i] = AlternativeTiles[i];
|
||||
}
|
||||
|
||||
void setTilesToBlank(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 getCharWidth(byte chr)
|
||||
{
|
||||
//Gets the length for a character. Also handles special cases
|
||||
switch(chr)
|
||||
{
|
||||
case END:
|
||||
return 0;
|
||||
case ENDL:
|
||||
return ENDL_SIZE;
|
||||
case BLANK:
|
||||
return BLANK_SIZE;
|
||||
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);
|
||||
default:
|
||||
return m2_widths_table[0][chr] & 0xFF;
|
||||
}
|
||||
}
|
||||
|
||||
int getPCWidth(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[0][chr] & 0xFF;
|
||||
}
|
||||
return length;
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
#ifndef HEADER_LUMINE_INCLUDED
|
||||
#define HEADER_LUMINE_INCLUDED
|
||||
|
||||
#include "types.h"
|
||||
#include "locs.h"
|
||||
#include "vwf.h"
|
||||
|
||||
#define START_Y 2
|
||||
#define END 0xFF
|
||||
#define ENDL 0xFE
|
||||
#define ENDL_SIZE 0x8
|
||||
#define BLANK 0xFD
|
||||
#define BLANK_SIZE 0x40
|
||||
#define PC_START 0xF9
|
||||
#define PC_NAME_SIZE 5
|
||||
|
||||
void writeLumineHallText();
|
||||
int getCharWidth(byte chr);
|
||||
int getPCWidth(byte* pc_ptr);
|
||||
void setTilesToBlank(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, unsigned short *hallAddress, int length, int *currPos, int *currLen);
|
||||
void printLumineCharacterInMultiTiles(int *Tiles, int *AlternativeTiles, byte *glyphRows, int glyphLen, int currLen);
|
||||
void printLumineCharacterInSingleTiles(int *Tiles, byte *glyphRows, int glyphLen, int currLen);
|
||||
void copyTiles(int *Tiles, int* AlternativeTiles);
|
||||
|
||||
|
||||
extern unsigned short* m2_get_hall_address();
|
||||
|
||||
extern int m2_hall_line_size;
|
||||
extern byte luminetext[];
|
||||
extern unsigned short luminesquaretable[];
|
||||
#endif
|
Binary file not shown.
|
@ -0,0 +1,117 @@
|
|||
00=\x00
|
||||
01=\x01
|
||||
17=\x17
|
||||
1C=\x1C
|
||||
26=\x26
|
||||
30=\x30
|
||||
3E=\x3E
|
||||
44=\x44
|
||||
4A=\x4A
|
||||
4C=\x4C
|
||||
56=\x56
|
||||
|
||||
FF=\end
|
||||
FE=\n
|
||||
FD=\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]
|
||||
|
||||
F9=\cness
|
||||
FA=\cpaula
|
||||
FB=\cjeff
|
||||
FC=\cpoo
|
||||
/00
|
|
@ -0,0 +1,8 @@
|
|||
.loadtable "data/lumine-table.tbl"
|
||||
|
||||
.strn "\blank"
|
||||
.strn "I'm \cness....\nIt's been a long road getting here...\n"
|
||||
.strn "Soon, I'll be...\nSoon, I'll be...\nSoon, I'll be...\n"
|
||||
.strn "What will happen to us?\nW...what's happening?\n"
|
||||
.strn "My thoughts are being written out on the wall...\nor are they?"
|
||||
.str "\blank\end"
|
|
@ -0,0 +1 @@
|
|||
ζ¬
¬ ͺ ¬η«© ¬«η©
ͺ©©¨
|
|
@ -1712,11 +1712,7 @@ nop
|
|||
// Lumine Hall hacks
|
||||
//==============================================================================
|
||||
|
||||
.org 0x82DCF94
|
||||
lumine_char_tilemap:
|
||||
.area 4000h,00h
|
||||
.incbin "data/lumine-char-tilemap.bin"
|
||||
.endarea
|
||||
.org 0x800ECB2 :: bl writeLumineHallText
|
||||
|
||||
//==============================================================================
|
||||
// Cartridge choosing screen hacks
|
||||
|
@ -1822,6 +1818,12 @@ m2_nybbles_to_bits:
|
|||
m2_enemy_attributes:
|
||||
.incbin "data/m2-enemy-attributes.bin"
|
||||
|
||||
luminesquaretable:
|
||||
.incbin "data/luminesquaretable.bin"
|
||||
|
||||
luminetext:
|
||||
.include "data/lumine-text.asm"
|
||||
|
||||
flyovertextYear:
|
||||
.include "data/flyover-text-year.asm"
|
||||
|
||||
|
@ -1882,6 +1884,7 @@ disclaimer_map:
|
|||
|
||||
.definelabel buffer_subtractor ,0x0000800
|
||||
.definelabel overworld_buffer ,0x200F200
|
||||
.definelabel m2_hall_line_size ,0x3000374
|
||||
.definelabel m2_ness_data ,0x3001D54
|
||||
.definelabel m2_ness_name ,0x3001F10
|
||||
.definelabel m2_old_paula_name ,0x3001F16
|
||||
|
@ -1911,6 +1914,7 @@ disclaimer_map:
|
|||
.definelabel m2_change_naming_space ,0x8004E08
|
||||
.definelabel m2_copy_name_temp_mem ,0x8004E34
|
||||
.definelabel m2_insert_default_name ,0x8005708
|
||||
.definelabel m2_get_hall_address ,0x800D7BC
|
||||
.definelabel m12_dim_palette ,0x80137DC
|
||||
.definelabel m2_enable_script ,0x80A1F6C
|
||||
.definelabel m2_sub_a334c ,0x80A334C
|
||||
|
|
Loading…
Reference in New Issue