Feature/fileselect (#57)
* Start file select notes * Blank out file select tileset template * Preliminary string printing Had to change the signature of the base print_chr function because the file select screen uses a lot of non-standard memory layouts. For example, the tilemap has a variable width instead of the standard 32 tiles. * Include string data in linker script * Update notes * Print the full array * Add external calls * Add FILE_SELECT struct * Add format_file_string * Widen main file select window * Format full text speed string * Add build badges to readme
This commit is contained in:
parent
87a1e261df
commit
4d73302a0e
|
@ -1,3 +1,8 @@
|
|||
| Branch | Status |
|
||||
| --- | --- |
|
||||
| Project | [![Build status](https://ci.appveyor.com/api/projects/status/9ml81r7fn0k7i8g1?svg=true)](https://ci.appveyor.com/project/jeffman/mother2gbatranslation) |
|
||||
| `master` | [![Build status](https://ci.appveyor.com/api/projects/status/9ml81r7fn0k7i8g1?svg=true)](https://ci.appveyor.com/project/jeffman/mother2gbatranslation) |
|
||||
|
||||
# MOTHER 2 Translation for the GBA
|
||||
This is a work-in-progress translation patch for MOTHER 2 on the GBA.
|
||||
|
||||
|
|
|
@ -62,7 +62,7 @@ $combine_script_contents =
|
|||
"SECTIONS { .text 0x$($base_c_address.ToString('X')) : { *(.text .rodata) } }"
|
||||
|
||||
$link_script_contents =
|
||||
"SECTIONS { .text 0x$($base_c_address.ToString('X')) : { *(.text .data .rodata) } }"
|
||||
"SECTIONS { .text 0x$($base_c_address.ToString('X')) : { *(.text .data .rodata*) } }"
|
||||
#EndRegion Variables
|
||||
|
||||
#Region Functions
|
||||
|
|
|
@ -0,0 +1,38 @@
|
|||
80035AC: print file select/naming string
|
||||
r0: tile x
|
||||
r1: tile y
|
||||
r2: characters to print
|
||||
r3: string buffer (0xFF terminated)
|
||||
sp: arg4
|
||||
|
||||
g = arg4 * 20
|
||||
row = 0 or 1 (note that it scans each string twice, once for the first row of tiles and once for the second row)
|
||||
tileset destination = [82B79B4 + g] + (x * 2) + ((y + row) * [82B79BC + g] * 2)
|
||||
|
||||
----
|
||||
|
||||
A template tileset is decompressed from 86DB070 to 200A400 (note: "1: Ness" starts printing to 200A434)
|
||||
It seems to get fully overwritten, so we can replace it with all blank tiles
|
||||
|
||||
----
|
||||
|
||||
We also need to blank out the font that gets decompressed from 86D9808 to VRAM at 6008000
|
||||
|
||||
----
|
||||
|
||||
Note that the palette on these screens uses 0x1 for background, 0x9 for foreground
|
||||
|
||||
----
|
||||
|
||||
We need to allocate more space for the strings... The same only allocates 32 bytes per file slot,
|
||||
but we need at least 41:
|
||||
|
||||
"X: " 3
|
||||
"NAME " 5
|
||||
[FE 5F xx] 3
|
||||
"Level: XX" 9
|
||||
[FE 5F xx] 3
|
||||
"Text speed: Medium" 18
|
||||
= 41
|
||||
|
||||
However, the game allocates 32 bytes per row per file slot, which is actually 64 total, so we should be ok.
|
|
@ -0,0 +1,291 @@
|
|||
// Format file select strings
|
||||
// r0: file select struct
|
||||
|
||||
08001E30 (T) push r4-r7,r14
|
||||
08001E32 (T) mov r7,r10
|
||||
08001E34 (T) mov r6,r9
|
||||
08001E36 (T) mov r5,r8
|
||||
08001E38 (T) push r5-r7
|
||||
08001E3A (T) add sp,-1Ch
|
||||
08001E3C (T) mov r7,r0
|
||||
08001E3E (T) mov r0,r13
|
||||
08001E40 (T) ldr r1,=80FC454h
|
||||
08001E42 (T) ldmia [r1]!,r2-r4
|
||||
08001E44 (T) stmia [r0]!,r2-r4
|
||||
08001E46 (T) mov r1,0h
|
||||
08001E48 (T) ldsh r0,[r7,r1] // 0 if file exists, -1 otherwise
|
||||
08001E4A (T) cmp r0,0h
|
||||
08001E4C (T) bge 8001E5Ch
|
||||
08001E4E (T) mov r0,r7
|
||||
08001E50 (T) bl 8001DC8h // presumably this formats the Start New Game string
|
||||
08001E54 (T) b 8002062h
|
||||
08001E56 (T) lsl r0,r0,0h
|
||||
08001E58 (T) stmia [r4]!,r2,r4,r6
|
||||
08001E5A (T) lsr r7,r1,20h
|
||||
|
||||
08001E5C (T) mov r4,0h
|
||||
08001E5E (T) ldr r2,=205h
|
||||
08001E60 (T) add r2,r2,r7
|
||||
08001E62 (T) mov r9,r2 // address of file number colon (1st row)
|
||||
08001E64 (T) ldr r3,=225h
|
||||
08001E66 (T) add r3,r3,r7
|
||||
08001E68 (T) mov r10,r3 // address of file number colon (2nd row)
|
||||
08001E6A (T) ldr r0,=206h
|
||||
08001E6C (T) add r0,r7,r0
|
||||
08001E6E (T) str r0,[sp,0Ch] // address of space after colon (1st)
|
||||
08001E70 (T) ldr r1,=226h
|
||||
08001E72 (T) add r1,r7,r1
|
||||
08001E74 (T) str r1,[sp,14h] // address of space after colon (2nd)
|
||||
08001E76 (T) ldr r2,=207h
|
||||
08001E78 (T) add r2,r7,r2
|
||||
08001E7A (T) str r2,[sp,10h] // address of ness' name (1st)
|
||||
08001E7C (T) ldr r3,=227h
|
||||
08001E7E (T) add r3,r7,r3
|
||||
08001E80 (T) str r3,[sp,18h] // address of ness' name (2nd)
|
||||
08001E82 (T) mov r0,0Ch
|
||||
08001E84 (T) add r0,r0,r7
|
||||
08001E86 (T) mov r8,r0 // address of ness' name (source string)
|
||||
08001E88 (T) mov r1,89h
|
||||
08001E8A (T) lsl r1,r1,2h
|
||||
08001E8C (T) add r5,r7,r1 // address of 2nd row
|
||||
|
||||
// Fill second row (32 bytes) with spaces
|
||||
08001E8E (T) bl 80057B0h // literally just returns a space (0x4D)
|
||||
08001E92 (T) add r1,r5,r4
|
||||
08001E94 (T) strb r0,[r1]
|
||||
08001E96 (T) add r4,1h
|
||||
08001E98 (T) cmp r4,1Fh
|
||||
08001E9A (T) ble 8001E8Eh
|
||||
|
||||
// Format file slot number
|
||||
08001E9C (T) mov r2,81h
|
||||
08001E9E (T) lsl r2,r2,2h
|
||||
08001EA0 (T) add r5,r7,r2 // address of 1st row
|
||||
08001EA2 (T) mov r3,89h
|
||||
08001EA4 (T) lsl r3,r3,2h
|
||||
08001EA6 (T) add r6,r7,r3 // address of 2nd row
|
||||
08001EA8 (T) mov r4,2h
|
||||
08001EAA (T) ldsh r0,[r7,r4] // file slot index (0-2)
|
||||
08001EAC (T) add r0,1h
|
||||
08001EAE (T) bl 80057A8h // format number (1 -> E1)
|
||||
08001EB2 (T) strb r0,[r5]
|
||||
08001EB4 (T) mov r5,r9
|
||||
08001EB6 (T) mov r1,2h
|
||||
08001EB8 (T) ldsh r0,[r7,r1]
|
||||
08001EBA (T) add r0,1h
|
||||
08001EBC (T) bl 80057A8h // literally doing exactly what it just did...
|
||||
08001EC0 (T) strb r0,[r6]
|
||||
|
||||
// Format colon
|
||||
08001EC2 (T) mov r6,r10
|
||||
08001EC4 (T) ldr r4,=80FC438h
|
||||
08001EC6 (T) mov r0,r4
|
||||
08001EC8 (T) bl 80057B4h // some weird jump table that ultimately returns a colon tile (EE)
|
||||
08001ECC (T) strb r0,[r5]
|
||||
08001ECE (T) ldr r5,[sp,0Ch]
|
||||
08001ED0 (T) mov r0,r4
|
||||
08001ED2 (T) bl 80057B4h
|
||||
08001ED6 (T) strb r0,[r6]
|
||||
|
||||
// Format space after colon
|
||||
08001ED8 (T) ldr r6,[sp,14h]
|
||||
08001EDA (T) bl 80057B0h
|
||||
08001EDE (T) strb r0,[r5]
|
||||
08001EE0 (T) ldr r5,[sp,10h]
|
||||
08001EE2 (T) bl 80057B0h
|
||||
08001EE6 (T) strb r0,[r6]
|
||||
|
||||
// Format Ness' name (1st row)
|
||||
08001EE8 (T) ldr r6,[sp,18h] // address of ness' name (dest)
|
||||
08001EEA (T) mov r4,0h
|
||||
08001EEC (T) mov r2,r8
|
||||
08001EEE (T) add r0,r2,r4 // address of ness' name (source); struct+0xC
|
||||
08001EF0 (T) ldrb r1,[r0]
|
||||
08001EF2 (T) mov r0,r1
|
||||
08001EF4 (T) cmp r0,0FFh
|
||||
08001EF6 (T) bne 8001F1Ch
|
||||
|
||||
// If 0xFF: write a space
|
||||
08001EF8 (T) bl 80057B0h
|
||||
08001EFC (T) strb r0,[r5]
|
||||
08001EFE (T) b 8001F1Eh
|
||||
08001F00 (T) lsl r5,r0,8h
|
||||
08001F02 (T) lsl r0,r0,0h
|
||||
08001F04 (T) lsl r5,r4,8h
|
||||
08001F06 (T) lsl r0,r0,0h
|
||||
08001F08 (T) lsl r6,r0,8h
|
||||
08001F0A (T) lsl r0,r0,0h
|
||||
08001F0C (T) lsl r6,r4,8h
|
||||
08001F0E (T) lsl r0,r0,0h
|
||||
08001F10 (T) lsl r7,r0,8h
|
||||
08001F12 (T) lsl r0,r0,0h
|
||||
08001F14 (T) lsl r7,r4,8h
|
||||
08001F16 (T) lsl r0,r0,0h
|
||||
08001F18 (T) stmia [r4]!,r3-r5
|
||||
08001F1A (T) lsr r7,r1,20h
|
||||
|
||||
// Else: format the letter
|
||||
08001F1C (T) strb r1,[r5]
|
||||
08001F1E (T) add r5,1h
|
||||
08001F20 (T) add r4,1h
|
||||
08001F22 (T) cmp r4,4h
|
||||
08001F24 (T) ble 8001EECh
|
||||
|
||||
// Format Ness' name (2nd row) + put spaces after both rows
|
||||
08001F26 (T) mov r4,0h
|
||||
08001F28 (T) ldrb r0,[r7,0Ch]
|
||||
08001F2A (T) cmp r0,0FFh
|
||||
08001F2C (T) beq 8001F44h
|
||||
08001F2E (T) mov r1,r8
|
||||
08001F30 (T) ldrb r0,[r1]
|
||||
08001F32 (T) strb r0,[r6]
|
||||
08001F34 (T) add r6,1h
|
||||
08001F36 (T) add r1,1h
|
||||
08001F38 (T) add r4,1h
|
||||
08001F3A (T) cmp r4,4h
|
||||
08001F3C (T) bgt 8001F44h
|
||||
08001F3E (T) ldrb r0,[r1]
|
||||
08001F40 (T) cmp r0,0FFh
|
||||
08001F42 (T) bne 8001F30h
|
||||
08001F44 (T) bl 80057B0h
|
||||
08001F48 (T) strb r0,[r5]
|
||||
08001F4A (T) add r5,1h
|
||||
08001F4C (T) bl 80057B0h
|
||||
08001F50 (T) strb r0,[r6]
|
||||
08001F52 (T) add r6,1h
|
||||
|
||||
// Format "Level:" string (weirdly, it puts it at different spots in the two rows... bug?)
|
||||
08001F54 (T) ldr r4,=80FC460h
|
||||
08001F56 (T) mov r0,r4
|
||||
08001F58 (T) bl 80057B4h
|
||||
08001F5C (T) strb r0,[r5]
|
||||
08001F5E (T) add r5,1h
|
||||
08001F60 (T) mov r0,r4
|
||||
08001F62 (T) bl 80057B4h
|
||||
08001F66 (T) strb r0,[r6]
|
||||
08001F68 (T) add r6,1h
|
||||
08001F6A (T) ldr r4,=80FC464h
|
||||
08001F6C (T) mov r0,r4
|
||||
08001F6E (T) bl 80057B4h
|
||||
08001F72 (T) strb r0,[r5]
|
||||
08001F74 (T) add r5,1h
|
||||
08001F76 (T) mov r0,r4
|
||||
08001F78 (T) bl 80057B4h
|
||||
08001F7C (T) strb r0,[r6]
|
||||
08001F7E (T) add r6,1h
|
||||
08001F80 (T) ldr r4,=80FC468h
|
||||
08001F82 (T) mov r0,r4
|
||||
08001F84 (T) bl 80057B4h
|
||||
08001F88 (T) strb r0,[r5]
|
||||
08001F8A (T) add r5,1h
|
||||
08001F8C (T) mov r0,r4
|
||||
08001F8E (T) bl 80057B4h
|
||||
08001F92 (T) strb r0,[r6]
|
||||
08001F94 (T) add r6,1h
|
||||
08001F96 (T) ldr r4,=80FC438h
|
||||
08001F98 (T) mov r0,r4
|
||||
08001F9A (T) bl 80057B4h
|
||||
08001F9E (T) strb r0,[r5]
|
||||
08001FA0 (T) add r5,1h
|
||||
08001FA2 (T) mov r0,r4
|
||||
08001FA4 (T) bl 80057B4h
|
||||
08001FA8 (T) strb r0,[r6]
|
||||
08001FAA (T) add r6,1h
|
||||
|
||||
// Format level
|
||||
08001FAC (T) ldrb r3,[r7,0Ah] // level
|
||||
08001FAE (T) mov r8,r3
|
||||
08001FB0 (T) mov r0,r8
|
||||
08001FB2 (T) mov r1,0Ah
|
||||
08001FB4 (T) bl 80F4A70h
|
||||
08001FB8 (T) mov r8,r0 // ones digit
|
||||
08001FBA (T) ldrb r0,[r7,0Ah]
|
||||
08001FBC (T) mov r1,0Ah
|
||||
08001FBE (T) bl m2_div
|
||||
08001FC2 (T) mov r4,r0 // tens digit
|
||||
08001FC4 (T) cmp r4,0h
|
||||
08001FC6 (T) beq 8001FE8h
|
||||
|
||||
// If level is greater than nine: print tens digit
|
||||
08001FC8 (T) bl 80057A8h
|
||||
08001FCC (T) strb r0,[r5]
|
||||
08001FCE (T) add r5,1h
|
||||
08001FD0 (T) mov r0,r4
|
||||
08001FD2 (T) bl 80057A8h
|
||||
08001FD6 (T) b 8001FF4h
|
||||
08001FD8 (T) stmia [r4]!,r5,r6
|
||||
08001FDA (T) lsr r7,r1,20h
|
||||
08001FDC (T) stmia [r4]!,r2,r5,r6
|
||||
08001FDE (T) lsr r7,r1,20h
|
||||
08001FE0 (T) stmia [r4]!,r3,r5,r6
|
||||
08001FE2 (T) lsr r7,r1,20h
|
||||
08001FE4 (T) stmia [r4]!,r3-r5
|
||||
08001FE6 (T) lsr r7,r1,20h
|
||||
|
||||
// Else: print space
|
||||
08001FE8 (T) bl 80057B0h
|
||||
08001FEC (T) strb r0,[r5]
|
||||
08001FEE (T) add r5,1h
|
||||
08001FF0 (T) bl 80057B0h
|
||||
|
||||
// Print tens digit (2nd row)
|
||||
08001FF4 (T) strb r0,[r6]
|
||||
|
||||
// Print tens digit
|
||||
08001FF6 (T) add r6,1h
|
||||
08001FF8 (T) mov r0,r8
|
||||
08001FFA (T) bl 80057A8h
|
||||
08001FFE (T) strb r0,[r5]
|
||||
08002000 (T) add r5,1h
|
||||
08002002 (T) mov r0,r8
|
||||
08002004 (T) bl 80057A8h
|
||||
08002008 (T) strb r0,[r6]
|
||||
|
||||
// Print "Text speed:"
|
||||
0800200A (T) bl 80057B0h
|
||||
0800200E (T) strb r0,[r5]
|
||||
08002010 (T) add r5,1h
|
||||
08002012 (T) ldr r0,=80FC46Ch
|
||||
08002014 (T) bl 80057B4h
|
||||
08002018 (T) strb r0,[r5]
|
||||
0800201A (T) add r5,1h
|
||||
0800201C (T) ldr r0,=80FC470h
|
||||
0800201E (T) bl 80057B4h
|
||||
08002022 (T) strb r0,[r5]
|
||||
08002024 (T) add r5,1h
|
||||
08002026 (T) ldr r0,=80FC474h
|
||||
08002028 (T) bl 80057B4h
|
||||
0800202C (T) strb r0,[r5]
|
||||
0800202E (T) add r5,1h
|
||||
08002030 (T) ldr r0,=80FC478h
|
||||
08002032 (T) bl 80057B4h
|
||||
08002036 (T) strb r0,[r5]
|
||||
08002038 (T) add r5,1h
|
||||
0800203A (T) ldr r0,=80FC438h
|
||||
0800203C (T) bl 80057B4h
|
||||
08002040 (T) strb r0,[r5]
|
||||
08002042 (T) add r5,1h
|
||||
|
||||
// Print speed
|
||||
08002044 (T) mov r4,0h
|
||||
08002046 (T) mov r1,4h
|
||||
08002048 (T) ldsh r0,[r7,r1]
|
||||
0800204A (T) lsl r0,r0,2h
|
||||
0800204C (T) add r0,r13
|
||||
0800204E (T) lsl r1,r4,1h
|
||||
08002050 (T) ldr r0,[r0]
|
||||
08002052 (T) add r0,r0,r1
|
||||
08002054 (T) bl 80057B4h
|
||||
08002058 (T) strb r0,[r5]
|
||||
0800205A (T) add r5,1h
|
||||
0800205C (T) add r4,1h
|
||||
0800205E (T) cmp r4,2h
|
||||
08002060 (T) ble 8002046h
|
||||
08002062 (T) add sp,1Ch
|
||||
08002064 (T) pop r3-r5
|
||||
08002066 (T) mov r8,r3
|
||||
08002068 (T) mov r9,r4
|
||||
0800206A (T) mov r10,r5
|
||||
0800206C (T) pop r4-r7
|
||||
0800206E (T) pop r0
|
||||
08002070 (T) bx r0
|
|
@ -9,6 +9,7 @@ void __attribute__((naked)) m2_hpwindow_up(int character) {}
|
|||
bool __attribute__((naked)) m2_isequipped(int item_index) {}
|
||||
void __attribute__((naked)) m2_soundeffect(int index) {}
|
||||
int __attribute__((naked)) m2_div(int dividend, int divisor) {}
|
||||
int __attribute__((naked)) m2_remainder(int dividend, int divisor) {}
|
||||
int __attribute__((naked)) m2_sub_a334c(int value) {}
|
||||
int __attribute__((naked)) m2_sub_a3384(int value) {}
|
||||
int __attribute__((naked)) m2_clearwindowtiles(WINDOW* window) {}
|
||||
|
|
|
@ -0,0 +1,30 @@
|
|||
#ifndef HEADER_FILE_SELECT_INCLUDED
|
||||
#define HEADER_FILE_SELECT_INCLUDED
|
||||
|
||||
#include "types.h"
|
||||
|
||||
typedef struct FILE_SELECT {
|
||||
short status; // 0 = used, -1 = empty
|
||||
short slot; // 0-2
|
||||
short text_speed; // 0-2
|
||||
short unknown_a;
|
||||
short unknown_b; // used when going to file setup
|
||||
short ness_level;
|
||||
byte ness_name[8];
|
||||
byte unknown_c[64];
|
||||
byte paula_name[8];
|
||||
byte unknown_d[64];
|
||||
byte jeff_name[8];
|
||||
byte unknown_e[64];
|
||||
byte poo_name[8];
|
||||
byte unknown_f[68];
|
||||
byte king_name[4];
|
||||
byte unknown_g[64];
|
||||
byte food_name[8];
|
||||
byte unknown_h[64];
|
||||
byte thing_name[8];
|
||||
byte unknown_i[64];
|
||||
byte formatted_str[64];
|
||||
} FILE_SELECT;
|
||||
|
||||
#endif
|
155
src/c/vwf.c
155
src/c/vwf.c
|
@ -2,6 +2,7 @@
|
|||
#include "vwf.h"
|
||||
#include "number-selector.h"
|
||||
#include "locs.h"
|
||||
#include "fileselect.h"
|
||||
|
||||
byte decode_character(byte chr)
|
||||
{
|
||||
|
@ -12,6 +13,11 @@ byte decode_character(byte chr)
|
|||
return c;
|
||||
}
|
||||
|
||||
byte encode_ascii(char chr)
|
||||
{
|
||||
return (byte)(chr + 48);
|
||||
}
|
||||
|
||||
int get_tile_number(int x, int y)
|
||||
{
|
||||
x--;
|
||||
|
@ -46,6 +52,141 @@ byte reduce_bit_depth(int row, int foreground)
|
|||
return lower | (upper << 4);
|
||||
}
|
||||
|
||||
void print_file_string(int x, int y, int length, byte *str, int unknown)
|
||||
{
|
||||
int *tilesetBasePtr = (int *)(0x82B79B4 + (unknown * 20));
|
||||
int width = tilesetBasePtr[2];
|
||||
unsigned short *tilesetDestPtr = (unsigned short *)(tilesetBasePtr[0]);
|
||||
|
||||
int pixelX = x * 8;
|
||||
int pixelY = y * 8;
|
||||
|
||||
for (int i = 0; i < length; i++)
|
||||
{
|
||||
byte chr = str[i];
|
||||
|
||||
if (chr == 0xFF)
|
||||
{
|
||||
break; // the game does something else here, haven't looked into what exactly
|
||||
}
|
||||
else if (chr == 0xFE)
|
||||
{
|
||||
// Define 0xFE as a control code
|
||||
byte cmd = str[++i];
|
||||
switch (cmd)
|
||||
{
|
||||
case CUSTOMCC_ADD_X:
|
||||
pixelX += str[++i];
|
||||
break;
|
||||
|
||||
case CUSTOMCC_SET_X:
|
||||
pixelX = str[++i];
|
||||
break;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
chr = decode_character(chr);
|
||||
int pixels = print_character_with_callback(
|
||||
chr,
|
||||
pixelX,
|
||||
pixelY,
|
||||
0,
|
||||
9,
|
||||
vram + 0x2000,
|
||||
&get_tile_number,
|
||||
tilesetDestPtr,
|
||||
width);
|
||||
|
||||
pixelX += pixels;
|
||||
}
|
||||
}
|
||||
|
||||
void format_file_cc(FILE_SELECT *file, int *index, byte cmd)
|
||||
{
|
||||
file->formatted_str[(*index)++] = 0xFE;
|
||||
file->formatted_str[(*index)++] = cmd;
|
||||
}
|
||||
|
||||
int ascii_strlen(char *str)
|
||||
{
|
||||
int len = 0;
|
||||
while (str[len] != 0)
|
||||
len++;
|
||||
return len;
|
||||
}
|
||||
|
||||
void format_file_string(FILE_SELECT *file)
|
||||
{
|
||||
int index = 0;
|
||||
|
||||
// Slot
|
||||
int slot = file->slot + 1;
|
||||
file->formatted_str[index++] = (byte)(slot + ZERO);
|
||||
file->formatted_str[index++] = encode_ascii(':');
|
||||
file->formatted_str[index++] = encode_ascii(' ');
|
||||
|
||||
if (file->status != 0)
|
||||
{
|
||||
char startNewStr[] = "Start New Game";
|
||||
for (int i = 0; i < (sizeof(startNewStr) - 1); i++)
|
||||
file->formatted_str[index++] = encode_ascii(startNewStr[i]);
|
||||
|
||||
file->formatted_str[index++] = 0xFF;
|
||||
return;
|
||||
}
|
||||
|
||||
// Name
|
||||
for (int i = 0; i < 5; i++)
|
||||
{
|
||||
byte name_chr = file->ness_name[i];
|
||||
|
||||
if (name_chr != 0xFF)
|
||||
file->formatted_str[index++] = name_chr;
|
||||
else
|
||||
file->formatted_str[index++] = encode_ascii(' ');
|
||||
}
|
||||
|
||||
// Re-position
|
||||
format_file_cc(file, &index, CUSTOMCC_SET_X);
|
||||
file->formatted_str[index++] = 76;
|
||||
|
||||
// Level
|
||||
char levelStr[] = "Level: ";
|
||||
for (int i = 0; i < (sizeof(levelStr) - 1); i++)
|
||||
file->formatted_str[index++] = encode_ascii(levelStr[i]);
|
||||
|
||||
int level = file->ness_level;
|
||||
int ones = m2_remainder(level, 10);
|
||||
int tens = m2_div(level, 10);
|
||||
|
||||
if (tens > 0)
|
||||
file->formatted_str[index++] = tens + ZERO;
|
||||
|
||||
file->formatted_str[index++] = ones + ZERO;
|
||||
|
||||
// Re-position
|
||||
format_file_cc(file, &index, CUSTOMCC_SET_X);
|
||||
file->formatted_str[index++] = 128;
|
||||
|
||||
// Text speed
|
||||
char textSpeedStr[] = "Text Speed: ";
|
||||
for (int i = 0; i < (sizeof(textSpeedStr) - 1); i++)
|
||||
file->formatted_str[index++] = encode_ascii(textSpeedStr[i]);
|
||||
|
||||
char speedStrs[][7] = {
|
||||
"Fast",
|
||||
"Medium",
|
||||
"Slow"
|
||||
};
|
||||
|
||||
char *speedStr = speedStrs[file->text_speed];
|
||||
for (int i = 0; i < ascii_strlen(speedStr); i++)
|
||||
file->formatted_str[index++] = encode_ascii(speedStr[i]);
|
||||
|
||||
file->formatted_str[index++] = 0xFF;
|
||||
}
|
||||
|
||||
byte print_character(byte chr, int x, int y)
|
||||
{
|
||||
return print_character_formatted(chr, x, y, 0, 0xF);
|
||||
|
@ -67,12 +208,12 @@ byte print_character_formatted(byte chr, int x, int y, int font, int foreground)
|
|||
return 8;
|
||||
}
|
||||
|
||||
return print_character_with_callback(chr, x, y, font, foreground, vram, &get_tile_number_with_offset, TRUE);
|
||||
return print_character_with_callback(chr, x, y, font, foreground, vram, &get_tile_number_with_offset, *tilemap_pointer, 32);
|
||||
}
|
||||
|
||||
byte print_character_to_ram(byte chr, int *dest, int xOffset, int font, int foreground)
|
||||
{
|
||||
return print_character_with_callback(chr, xOffset, 0, font, foreground, dest, &get_tile_number_grid, FALSE);
|
||||
return print_character_with_callback(chr, xOffset, 0, font, foreground, dest, &get_tile_number_grid, NULL, 32);
|
||||
}
|
||||
|
||||
// Prints a special tile. Pixels are copied to the VWF buffer.
|
||||
|
@ -110,7 +251,7 @@ void map_tile(unsigned short tile, int x, int y)
|
|||
}
|
||||
|
||||
byte print_character_with_callback(byte chr, int x, int y, int font, int foreground,
|
||||
int *dest, int (*getTileCallback)(int, int), int useTilemap)
|
||||
int *dest, int (*getTileCallback)(int, int), unsigned short *tilemapPtr, int tilemapWidth)
|
||||
{
|
||||
int tileWidth = m2_font_widths[font];
|
||||
int tileHeight = m2_font_heights[font];
|
||||
|
@ -149,8 +290,8 @@ byte print_character_with_callback(byte chr, int x, int y, int font, int foregro
|
|||
dest[(tileIndex * 8) + row] = canvasRow;
|
||||
}
|
||||
|
||||
if (useTilemap)
|
||||
(*tilemap_pointer)[tileX + dTileX + ((tileY + dTileY) * 32)] = paletteMask | tileIndex;
|
||||
if (tilemapPtr != NULL)
|
||||
tilemapPtr[tileX + dTileX + ((tileY + dTileY) * tilemapWidth)] = paletteMask | tileIndex;
|
||||
|
||||
if (renderedWidth - leftPortionWidth > 0 && leftPortionWidth < 8)
|
||||
{
|
||||
|
@ -171,8 +312,8 @@ byte print_character_with_callback(byte chr, int x, int y, int font, int foregro
|
|||
dest[(tileIndex * 8) + row] = canvasRow;
|
||||
}
|
||||
|
||||
if (useTilemap)
|
||||
(*tilemap_pointer)[tileX + dTileX + 1 + ((tileY + dTileY) * 32)] = paletteMask | tileIndex;
|
||||
if (tilemapPtr != NULL)
|
||||
tilemapPtr[tileX + dTileX + 1 + ((tileY + dTileY) * tilemapWidth)] = paletteMask | tileIndex;
|
||||
}
|
||||
|
||||
renderedWidth -= 8;
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
#include "types.h"
|
||||
#include "pc.h"
|
||||
#include "fileselect.h"
|
||||
|
||||
#define NULL (0)
|
||||
#define QUESTION_MARK 0x1F
|
||||
|
@ -25,6 +26,7 @@
|
|||
#define CUSTOMCC_ADD_X 0x60
|
||||
|
||||
byte decode_character(byte chr);
|
||||
byte encode_ascii(char chr);
|
||||
int get_tile_number(int x, int y);
|
||||
int expand_bit_depth(byte row, int foreground);
|
||||
byte reduce_bit_depth(int row, int foreground);
|
||||
|
@ -35,7 +37,7 @@ void print_special_character(int tile, int x, int y);
|
|||
void map_special_character(unsigned short tile, int x, int y);
|
||||
void map_tile(unsigned short tile, int x, int y);
|
||||
byte print_character_with_callback(byte chr, int x, int y, int font, int foreground,
|
||||
int *dest, int (*getTileCallback)(int, int), int useTilemap);
|
||||
int *dest, int (*getTileCallback)(int, int), unsigned short *tilemapPtr, int tilemapWidth);
|
||||
byte print_character_to_ram(byte chr, int *dest, int xOffset, int font, int foreground);
|
||||
int print_window_header_string(int *dest, byte *str, int x, int y);
|
||||
void clear_window_header(int *dest, int length, int x, int y);
|
||||
|
@ -65,6 +67,8 @@ void print_number_menu_current(byte digit, WINDOW* window);
|
|||
void clear_number_menu(WINDOW* window);
|
||||
void format_cash_window(int value, int padding, byte* str);
|
||||
void handle_first_window(WINDOW* window);
|
||||
void print_file_string(int x, int y, int length, byte *str, int unknown);
|
||||
void format_file_string(FILE_SELECT *file);
|
||||
|
||||
extern unsigned short m2_coord_table[];
|
||||
extern int m2_bits_to_nybbles[];
|
||||
|
@ -84,3 +88,5 @@ extern int bin_to_bcd(int value, int* digit_count);
|
|||
extern int m2_drawwindow(WINDOW* window);
|
||||
extern int m2_resetwindow(WINDOW* window, bool skip_redraw);
|
||||
extern void m2_hpwindow_up(int character);
|
||||
extern int m2_div(int dividend, int divisor);
|
||||
extern int m2_remainder(int dividend, int divisor);
|
||||
|
|
Binary file not shown.
Binary file not shown.
|
@ -1047,6 +1047,32 @@ nop
|
|||
//.org 0x80BDA02 :: mov r2,#0x1B //Poo
|
||||
|
||||
|
||||
//==============================================================================
|
||||
// File select hacks
|
||||
//==============================================================================
|
||||
|
||||
// Main file select window resize
|
||||
.org 0x82B79BC :: dw 0x1C // new window width
|
||||
.org 0x8003998 :: mov r0,1 // new window x
|
||||
.org 0x8003A04 :: mov r1,1
|
||||
.org 0x8003B40 :: mov r0,0x10 // new cursor x
|
||||
.org 0x86DB070 :: .incbin "data/m2-fileselect-template.bin"
|
||||
|
||||
.org 0x86D9808
|
||||
.incbin "data/m2-fileselect-tileset.bin"
|
||||
|
||||
// Formatting
|
||||
.org 0x80021E8 :: bl format_file_string
|
||||
.org 0x8002284 :: bl format_file_string
|
||||
|
||||
// Printing
|
||||
.org 0x80038CC :: mov r2,0x40 :: bl print_file_string
|
||||
.org 0x80038DE :: mov r2,0x40 :: bl print_file_string
|
||||
.org 0x80038F2 :: mov r2,0x40 :: bl print_file_string
|
||||
|
||||
// Bump file select cursor up by 3 pixels
|
||||
.org 0x8003844 :: add r0,r5,1
|
||||
|
||||
//==============================================================================
|
||||
// Data files
|
||||
//==============================================================================
|
||||
|
@ -1183,6 +1209,7 @@ m2_enemy_attributes:
|
|||
.definelabel m2_hpwindow_up ,0x80D3F0C
|
||||
.definelabel m2_curhpwindow_down ,0x80D41D8
|
||||
.definelabel m2_div ,0x80F49D8
|
||||
.definelabel m2_remainder ,0x80F4A70
|
||||
.definelabel m2_items ,0x8B1D62C
|
||||
.definelabel m2_default_names ,0x82B9330
|
||||
|
||||
|
|
Loading…
Reference in New Issue