diff --git a/build.ps1 b/build.ps1 index 525d209..863bea9 100644 --- a/build.ps1 +++ b/build.ps1 @@ -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" diff --git a/notes/m2-notes.txt b/notes/m2-notes.txt index 18fc386..220b9b2 100644 --- a/notes/m2-notes.txt +++ b/notes/m2-notes.txt @@ -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? diff --git a/src/c/battle.c b/src/c/battle.c index 4bed408..e3c350f 100644 --- a/src/c/battle.c +++ b/src/c/battle.c @@ -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); diff --git a/src/c/ext.c b/src/c/ext.c index bfc5e83..708baac 100644 --- a/src/c/ext.c +++ b/src/c/ext.c @@ -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) {} diff --git a/src/c/fileselect.c b/src/c/fileselect.c index b95dd77..4c7bcc8 100644 --- a/src/c/fileselect.c +++ b/src/c/fileselect.c @@ -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)); diff --git a/src/c/fileselect.h b/src/c/fileselect.h index d0d86f4..a628cb5 100644 --- a/src/c/fileselect.h +++ b/src/c/fileselect.h @@ -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); diff --git a/src/c/luminehall.c b/src/c/luminehall.c new file mode 100644 index 0000000..8926a94 --- /dev/null +++ b/src/c/luminehall.c @@ -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; +} \ No newline at end of file diff --git a/src/c/luminehall.h b/src/c/luminehall.h new file mode 100644 index 0000000..d9be500 --- /dev/null +++ b/src/c/luminehall.h @@ -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 \ No newline at end of file diff --git a/src/c/pc.h b/src/c/pc.h index 6348b34..f77b0c8 100644 --- a/src/c/pc.h +++ b/src/c/pc.h @@ -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 diff --git a/src/data/lumine-char-tilemap.bin b/src/data/lumine-char-tilemap.bin deleted file mode 100644 index ac15881..0000000 Binary files a/src/data/lumine-char-tilemap.bin and /dev/null differ diff --git a/src/data/lumine-table.tbl b/src/data/lumine-table.tbl new file mode 100644 index 0000000..acc51ee --- /dev/null +++ b/src/data/lumine-table.tbl @@ -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 \ No newline at end of file diff --git a/src/data/lumine-text.asm b/src/data/lumine-text.asm new file mode 100644 index 0000000..64db7c1 --- /dev/null +++ b/src/data/lumine-text.asm @@ -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" diff --git a/src/data/luminesquaretable.bin b/src/data/luminesquaretable.bin new file mode 100644 index 0000000..e03a89b --- /dev/null +++ b/src/data/luminesquaretable.bin @@ -0,0 +1 @@ +æ¬ ¬ ª ¬ç«© ¬«ç© ª©©¨ \ No newline at end of file diff --git a/src/m2-bugfixes.asm b/src/m2-bugfixes.asm new file mode 100644 index 0000000..11e520b --- /dev/null +++ b/src/m2-bugfixes.asm @@ -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} + + +//============================================================================== \ No newline at end of file diff --git a/src/m2-hack.asm b/src/m2-hack.asm index 2e20a99..dfb3d55 100644 --- a/src/m2-hack.asm +++ b/src/m2-hack.asm @@ -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" diff --git a/src/m2-vwf-entries.asm b/src/m2-vwf-entries.asm index e9efcc9..02957f6 100644 --- a/src/m2-vwf-entries.asm +++ b/src/m2-vwf-entries.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: diff --git a/working/m12-strings-english.txt b/working/m12-strings-english.txt index 4541ed9..bea8f33 100644 --- a/working/m12-strings-english.txt +++ b/working/m12-strings-english.txt @@ -1106,7 +1106,7 @@ ^L1108^[00 FF] ^L1109^@[9F FF][C1 FF][87 FF] used[01 FF] the [90 FF 00][1A FF 02 00].[02 FF]@But nothing happened.[02 FF][00 FF] ^L1110^@[9F FF][C1 FF][87 FF] used[01 FF] the [90 FF 00][1A FF 02 00].[02 FF]@But nothing happened.[02 FF][00 FF] -^L1111^[C1 FF][87 FF]@[9F FF] tried[01 FF] to use the[90 FF 00][1A FF 02 00].[02 FF]@but [9F FF] could not use[01 FF] the [90 FF 00][1A FF 02 00] very well.[02 FF][00 FF] +^L1111^[C1 FF][87 FF]@[9F FF] tried[01 FF] to use the [90 FF 00][1A FF 02 00].[02 FF]@but [9F FF] could not use[01 FF] the [90 FF 00][1A FF 02 00] very well.[02 FF][00 FF] ^L1112^[FC FF 08 00][82 FF _L3462_][D4 FF 19 00]@[9F FF] is[01 FF] attacking![D4 FF 1A 00][02 FF][00 FF] ^L1113^[D4 FF 18 00]@[9F FF] attacks![D4 FF 1B 00][02 FF][00 FF] ^L1114^@[9F FF] spies on[01 FF] [AD FF]![02 FF][00 FF]