Merge branch 'master' into Cre
This commit is contained in:
commit
e3a1a54f9b
|
@ -22,7 +22,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"
|
||||
|
|
|
@ -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?
|
||||
|
|
|
@ -25,7 +25,7 @@ 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);
|
||||
|
|
|
@ -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) {}
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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];
|
||||
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 & 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++)
|
||||
setTilesToBlank(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)++;
|
||||
}
|
||||
|
||||
copyTiles(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);
|
||||
setTilesToBlank(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 copyTiles(int *Tiles, int AlternativeTiles[SIDE_BUFFER_SIZE][4], int indexMatrix)
|
||||
{
|
||||
for(int i = 0; i < 4; i++)
|
||||
Tiles[i] = AlternativeTiles[indexMatrix][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 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 + 2));
|
||||
default:
|
||||
return m2_widths_table[LUMINE_FONT][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[LUMINE_FONT][chr] & 0xFF;
|
||||
}
|
||||
return length;
|
||||
}
|
|
@ -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 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[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 copyTiles(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
|
|
@ -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
|
||||
|
|
Binary file not shown.
|
@ -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
|
|
@ -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"
|
|
@ -0,0 +1 @@
|
|||
ζ¬
¬ ͺ ¬η«© ¬«η©
ͺ©©¨
|
|
@ -0,0 +1,57 @@
|
|||
//==============================================================================
|
||||
//Fixes the issue where Gyigas and other enemies would not use their death attack
|
||||
//(or phase change) because of the poison
|
||||
dee6c_fix_poison_gyigas:
|
||||
push {lr}
|
||||
|
||||
bl 0x80E9CFC //Normal code
|
||||
|
||||
ldr r2,=#0x2024860 //Where the action's data is stored
|
||||
ldr r0,[r6,#0] //Load the entity's slot
|
||||
add r0,#0x44
|
||||
ldrh r1,[r0,#0]
|
||||
cmp r1,#0
|
||||
beq @@normal //Characters have this set as 0
|
||||
cmp r1,#0xDA //This particular Gyigas phase does not need this... (It will reflect the poison randomly if we let it continue)
|
||||
beq @@normal
|
||||
ldrh r1,[r0,#4] // Get the enemy's current HP
|
||||
cmp r1,#0 //Check if they're 0
|
||||
bne @@normal
|
||||
ldrh r1,[r0,#6] // Get the enemy's scrolling HP
|
||||
cmp r1,#0 //Check if they're 0 (probably not needed)
|
||||
bne @@normal
|
||||
mov r0,#0x9 //Fabricate a death check for the enemy
|
||||
add r2,#0x16
|
||||
strh r0,[r2,#0]
|
||||
mov r0,#0
|
||||
strh r0,[r2,#4]
|
||||
mov r0,#4 //This counts as a PSI, since setting it as a normal attack would make it so the Diamond Dog would reflect it
|
||||
strh r0,[r2,#6]
|
||||
add r2,#0xC
|
||||
strh r0,[r2,#0x6]
|
||||
mov r0,#1
|
||||
strh r0,[r2,#4]
|
||||
mov r0,#0
|
||||
strh r0,[r2,#0]
|
||||
add r2,#0x24
|
||||
strh r0,[r2,#0]
|
||||
strh r0,[r2,#0x12]
|
||||
ldr r2,=#0x2025034
|
||||
mov r0,#1
|
||||
strh r0,[r2,#0] //This is a PSI. Not a physical attack
|
||||
ldr r0,=#0x3005378
|
||||
mov r1,#0xC //This is PSI Cool Thing
|
||||
strh r1,[r0,#0]
|
||||
mov r1,#0
|
||||
strh r1,[r0,#0x10]
|
||||
b @@end
|
||||
|
||||
@@normal:
|
||||
mov r0,#0x64 //Normal game's behaviour
|
||||
strh r0,[r2,#0x16]
|
||||
|
||||
@@end:
|
||||
pop {pc}
|
||||
|
||||
|
||||
//==============================================================================
|
|
@ -994,6 +994,18 @@ pop {r4,pc}
|
|||
// Update musical note value (for Ness' Nightmare)
|
||||
.org 0x80DAF12 :: cmp r0,0xAC
|
||||
|
||||
//---------------------------------------------------------
|
||||
// Name setup hacks (improves the "The" fix and makes it portable)
|
||||
//---------------------------------------------------------
|
||||
.org 0x80020AE :: bl copy_name_perm_mem
|
||||
.org 0x80020BE :: bl copy_name_perm_mem
|
||||
.org 0x80020CE :: bl copy_name_perm_mem
|
||||
.org 0x80020DE :: bl copy_name_perm_mem
|
||||
.org 0x80020EE :: bl copy_name_perm_mem
|
||||
.org 0x80020FE :: bl copy_name_perm_mem
|
||||
.org 0x800210E :: bl copy_name_perm_mem
|
||||
.org 0x800215A :: bl _215a_load_names
|
||||
|
||||
//---------------------------------------------------------
|
||||
// BEB6C hacks (Goods inner menu)
|
||||
//---------------------------------------------------------
|
||||
|
@ -1701,6 +1713,20 @@ nop
|
|||
//Choose character table based on alphabet loaded in
|
||||
.org 0x80C7578 :: bl c7578_load_letters
|
||||
|
||||
|
||||
//==============================================================================
|
||||
// Bug fixes for the original game
|
||||
//==============================================================================
|
||||
|
||||
// Disallow warping with an Exit mouse in the Cave of the Past
|
||||
.org 0x8731046 :: dh 00h
|
||||
|
||||
|
||||
//==============================================================================
|
||||
// Fix Gyigas' poison bug
|
||||
//==============================================================================
|
||||
.org 0x80DEE6C :: bl dee6c_fix_poison_gyigas :: nop :: nop :: nop
|
||||
|
||||
//==============================================================================
|
||||
// Credits hacks
|
||||
//==============================================================================
|
||||
|
@ -1747,11 +1773,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
|
||||
|
@ -1864,6 +1886,13 @@ m2_enemy_attributes:
|
|||
cast_vwf_names:
|
||||
.include "data/cast-vwf-names.asm"
|
||||
|
||||
.align 2
|
||||
luminesquaretable:
|
||||
.incbin "data/luminesquaretable.bin"
|
||||
|
||||
luminetext:
|
||||
.include "data/lumine-text.asm"
|
||||
|
||||
flyovertextYear:
|
||||
.include "data/flyover-text-year.asm"
|
||||
|
||||
|
@ -1960,6 +1989,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
|
||||
|
@ -1989,6 +2019,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
|
||||
|
@ -2040,6 +2071,7 @@ disclaimer_map:
|
|||
.include "syscalls.asm"
|
||||
.include "m2-vwf.asm"
|
||||
.include "m2-vwf-entries.asm"
|
||||
.include "m2-bugfixes.asm"
|
||||
.include "m2-formatting.asm"
|
||||
.include "m2-customcodes.asm"
|
||||
.include "m2-compiled.asm"
|
||||
|
|
|
@ -971,6 +971,14 @@ add r0,r0,r7
|
|||
bx lr
|
||||
.pool
|
||||
|
||||
//==============================================================================
|
||||
//Sets the names' background to a default
|
||||
_215a_load_names:
|
||||
push {lr}
|
||||
bl 0x8012460
|
||||
bl set_background_loaded_names
|
||||
pop {pc}
|
||||
|
||||
//==============================================================================
|
||||
// Add a space between enemy name and letter in multi-enemy fights for the selection window. Called only by enemies.
|
||||
dcd00_enemy_letter:
|
||||
|
@ -1183,29 +1191,36 @@ add r2,#1
|
|||
ldrb r0,[r1,r2]
|
||||
cmp r0,#1 //Does this string have the the flag? If it does not, then proceed to the end
|
||||
bne @@end
|
||||
ldr r2,=0x50959884 //Does this string have "The "? If it does, check if it ends instantly.
|
||||
ldr r2,=0x50959884 //"The "
|
||||
ldr r0,[r1,#0]
|
||||
cmp r0,r2
|
||||
beq @@next_found_the
|
||||
sub r0,r0,r2 //Does this string have "the "? If it does not, then it's a character. Proceed to the end.
|
||||
cmp r0,#0x20
|
||||
bne @@end
|
||||
sub r2,r0,r2
|
||||
cmp r2,#0
|
||||
beq @@next_found_the //Does this string have "The "? If it does, proceed accordingly
|
||||
cmp r2,#0x20
|
||||
beq @@next_found_the //Does this string have "the "? If it does, proceed accordingly
|
||||
|
||||
//For the other languages: add the other things to compare to here...? Maybe you can do it in a smarter way though...
|
||||
|
||||
//No articles found. Go to the end
|
||||
b @@end
|
||||
|
||||
@@next_found_the: //A starting "The " or "the " has been found
|
||||
mov r2,#0xFF
|
||||
lsl r2,r2,#8 //r2 has 0xFF00
|
||||
ldrh r0,[r1,#4] //Load the next two bytes after "The " or "the "
|
||||
cmp r0,r2 //If they're the same as r2, then it's a character. End this here.
|
||||
beq @@end
|
||||
//Assumes the uppercase and lowercase characters are 0x20 apart
|
||||
ldr r0,=m2_cstm_last_printed
|
||||
ldrb r0,[r0,#0]
|
||||
cmp r0,#0x70 //Is the previous character an @?
|
||||
beq @@Maius
|
||||
mov r0,#0xA4 //Change The to the
|
||||
beq @@Upper
|
||||
|
||||
mov r0,#0x20
|
||||
sub r2,r0,r2 //Is this "t"? If it is, this will be 0. Otherwise, it will be 0x20
|
||||
ldr r0,[r1,#0]
|
||||
add r0,r0,r2 //Ensure it is the
|
||||
strb r0,[r1,#0]
|
||||
b @@end
|
||||
@@Maius:
|
||||
mov r0,#0x84 //Ensure it is The
|
||||
|
||||
@@Upper:
|
||||
ldr r0,[r1,#0]
|
||||
sub r0,r0,r2 //Ensure it is The
|
||||
strb r0,[r1,#0]
|
||||
|
||||
@@end:
|
||||
|
|
Loading…
Reference in New Issue