Mother2GbaTranslation/m2-vwf.asm

1445 lines
31 KiB
NASM

m2_vwf:
//==============================================================================
// int get_tile_number(int x, int y)
// In:
// r0: x
// r1: y
// Out:
// r0: tile number
//==============================================================================
.get_tile_number:
print "m2vwf.get_tile_number: $",pc
push {r1-r5,lr}
ldr r4,=#m2_coord_table
sub r0,r0,#1
sub r1,r1,#1
lsl r2,r1,#0x1F
lsr r2,r2,#0x1F
lsr r1,r1,#1
lsl r5,r1,#4
sub r5,r5,r1
sub r5,r5,r1
lsl r5,r5,#2
lsl r0,r0,#1
add r4,r4,r0
add r4,r4,r5
ldrh r0,[r4,#0]
lsl r2,r2,#5
add r0,r0,r2
pop {r1-r5,pc}
//==============================================================================
// int get_window_number(WINDOW* window)
// In:
// r0: window
// Out:
// r0: window number
//==============================================================================
.get_window_number:
push {r1-r3,lr}
ldr r1,=#0x3005230
mov r2,#0
-
ldr r3,[r1,#0]
cmp r3,r0
beq +
add r1,r1,#4
add r2,r2,#1
cmp r2,#0xB
beq +
b -
+
mov r0,r2
pop {r1-r3,pc}
//==============================================================================
// void weld_entry(WINDOW* window, byte* chr, ushort* mapEntry)
// In:
// r0: address of window data
// [r5 + 0x04]: start address of text being displayed
// [r5 + 0x08]: same as above?
// [r5 + 0x20]: window area (just width * height)
// [r5 + 0x22]: window text area X
// [r5 + 0x24]: window text area Y
// [r5 + 0x26]: window width
// [r5 + 0x28]: window height
// [r5 + 0x2A]: relative text X
// [r5 + 0x2C]: relative text Y
// r1: address of char to print
// r2: address of map entry
//==============================================================================
// Notes:
// [0x30009F4] == current major window mode
// 00: none
// 01: main A menu
// 02: ?
// 03: talk
// 04: goods
// 05: psi
// 06: equip
// 07: check
// 08: status
// [0x30051EC] == current tile offset
// [0x3005228] == current text palette, << 0xC
// [0x3005230] == addresses of all 11 windows
// [0x3005270] == address of tilemap start in WRAM, can use this to figure out X and Y
// 80C9860
// 80CA440
//--------------------------------
.weld_entry:
print "m2vwf.weld_entry: $",pc
push {r0-r7,lr}
add sp,#-28
//--------------------------------
// Check which window we're on
mov r5,r0
bl .get_window_number
mov r6,r0
cmp r6,#0xB
bne +
dw $E801 // Break by means of invalid opcode
+
//--------------------------------
// Get the char
ldrb r0,[r1,#0]
sub r0,#0x50
bpl +
mov r0,#0x1F // Replace char with ? if it's invalid
b .char_custom
+
cmp r0,#0x60
bcc .char_custom
mov r0,#0x1F
.char_custom:
str r0,[sp,#0x0]
// [sp+0] = char
//--------------------------------
// Get the current X
ldr r7,=#m2_custom_wram
add r7,r7,#4
mov r0,#0x22
ldrb r1,[r5,r0]
mov r0,#0x2A
ldrb r2,[r5,r0]
add r1,r1,r2
str r1,[sp,#4]
lsl r0,r1,#3
ldrb r1,[r7,r6]
str r1,[sp,#24]
add r0,r0,r1 // Current pixel X
str r0,[sp,#20]
// Get the current Y
mov r2,#0x24
ldrb r1,[r5,r2]
mov r2,#0x2C
ldrb r3,[r5,r2]
add r1,r1,r3
str r1,[sp,#8]
lsl r1,r1,#3
//--------------------------------
// Print
ldr r2,[sp,#0x0]
mov r3,#0
bl .print_character
str r0,[sp,#12]
//--------------------------------
// Figure out new window coords
ldr r0,[sp,#20]
ldr r1,[sp,#12]
add r0,r0,r1
// Store new window coords
lsr r1,r0,#3
mov r2,#0x22
ldrb r2,[r5,r2]
sub r1,r1,r2
mov r2,#0x2A
strb r1,[r5,r2]
// Store new pixel X
lsl r0,r0,#29
lsr r0,r0,#29
strb r0,[r7,r6]
//--------------------------------
add sp,#28
pop {r0-r7,pc}
//=============================================================================
// void print_string(int x, int y, char* str)
// In:
// r0: x (pixel)
// r1: y (pixel)
// r2: numerical string to print (ends with 0xFF)
//=============================================================================
.print_string:
print "m2vwf.print_string: $",pc
push {r0-r7,lr}
//--------------------------------
mov r3,#0
mov r4,r2
mov r5,r0
-
ldrb r2,[r4,#1]
cmp r2,#0xFF
bne +
ldrb r6,[r4,#0]
cmp r6,#0
beq .print_numerical_endcode
.print_numerical_invalid:
dw $E801 // Break by means of invalid opcode
// Print the character
+
ldrb r2,[r4,#0]
mov r7,r0
sub r2,#0x50
bl .print_character
add r0,r0,r7
add r4,r4,#1
b -
.print_numerical_endcode:
pop {r0-r7,pc}
//==============================================================================
// void print_string_relative(int x, int y, char* str, WINDOW* window)
// In:
// r2: relative x (tile)
// r3: relative y (tile)
// r1: str
// r0: window
//==============================================================================
.print_string_relative:
push {r0-r6,lr}
//--------------------------------
mov r5,#0x22
ldrb r4,[r0,r5] // Window X
mov r5,#0x24
ldrb r5,[r0,r5] // Window Y
lsl r3,r3,#1
add r2,r2,r4
add r3,r3,r5
lsl r2,r2,#3
lsl r3,r3,#3
//--------------------------------
mov r0,r2
mov r2,r1
mov r1,r3
bl m2_vwf.print_string
//--------------------------------
pop {r0-r6,pc}
//=============================================================================
// void print_character(int x, int y, int chr, int font)
// In:
// r0: x (pixel)
// r1: y (pixel)
// r2: character
// r3: font
// 0: main
// 1: saturn
// 2: tiny
// Out:
// r0: virtual width
//=============================================================================
.print_character:
print "m2vwf.print_character: $",pc
push {r1-r7,lr}
mov r4,r8
mov r5,r9
mov r6,r10
mov r7,r11
push {r4-r7}
mov r4,r12
push {r4}
add sp,#-24
mov r10,r0
mov r11,r1
mov r12,r2
mov r5,r3
//----------------------------------------
ldr r3,=#0x30051EC
ldrh r4,[r3,#0] // Tile offset
add r3,#0x3C
ldrh r6,[r3,#0] // Palette mask
add r3,#0x48
ldr r7,[r3,#0] // Tilemap address
lsr r0,r0,#3
lsr r1,r1,#3
lsl r1,r1,#5
add r0,r0,r1
lsl r0,r0,#1
add r7,r7,r0 // Local tilemap address
mov r8,r4
//----------------------------------------
ldr r0,=#m2_widths_table
lsl r1,r5,#2 // Font number * 4
ldr r0,[r0,r1]
mov r3,r12 // Character
lsl r2,r3,#1
ldrb r1,[r0,r2] // Virtual width
mov r9,r1
add r2,r2,#1
ldrb r0,[r0,r2] // Render width
cmp r0,#0
beq + // Don't bother rendering a zero-width character
ldr r2,=#m2_height_table
ldrb r2,[r2,r5]
str r2,[sp,#16] // No more registers, gotta store this on the stack
mov r3,sp
strb r0,[r3,#9]
strb r2,[r3,#12]
mov r1,r10
lsl r1,r1,#29
lsr r1,r1,#29
strb r1,[r3,#8]
mov r1,#4
strb r1,[r3,#10]
mov r1,#0xF
strb r1,[r3,#11]
//----------------------------------------
mov r0,r10
mov r1,r11
lsr r0,r0,#3
lsr r1,r1,#3
bl .get_tile_number
add r4,r0,r4
lsl r0,r4,#5
mov r1,#6
lsl r1,r1,#0x18
add r0,r0,r1 // VRAM address
str r0,[sp,#0]
//----------------------------------------
ldr r0,=#m2_font_table
lsl r1,r5,#2
ldr r0,[r0,r1]
mov r1,r12
lsl r1,r1,#5
add r0,r0,r1 // Glyph address
str r0,[sp,#4]
//----------------------------------------
// Render left portion
mov r0,sp
bl .print_left
//----------------------------------------
// Update the map
orr r4,r6
mov r1,r7
-
strh r4,[r1,#0]
add r4,#0x20
add r1,#0x40
sub r2,r2,#1
bne -
add r7,r7,#2
//----------------------------------------
// Now we've rendered the left portion;
// we need to determine whether or not to render the right portion
ldrb r1,[r0,#8] // VRAM x offset
str r1,[sp,#20] // No more registers, gotta store this on the stack
ldrb r2,[r0,#9] // Render width
add r2,r1,r2
cmp r2,#8
bls +
// We still have more to render; figure out how much we already rendered
mov r3,#8
sub r3,r3,r1
strb r3,[r0,#8]
// Allocate a new tile
mov r0,r10
mov r1,r11
lsr r0,r0,#3
add r0,r0,#1
lsr r1,r1,#3
bl .get_tile_number
add r0,r8
mov r4,r0
lsl r0,r0,#5
mov r1,#6
lsl r1,r1,#0x18
add r0,r0,r1
str r0,[sp,#0]
mov r0,sp
bl .print_right
//----------------------------------------
// Update the map
orr r4,r6
mov r1,r7
ldr r2,[sp,#16]
-
strh r4,[r1,#0]
add r4,#0x20
add r1,#0x40
sub r2,r2,#1
bne -
add r7,r7,#2
//----------------------------------------
// Now we've rendered the left and right portions;
// we need to determin whether or not to do a final
// right portion for super wide characters
ldr r1,[sp,#20] // Original pixel X offset
ldrb r2,[r0,#9] // Render width
add r2,r1,r2 // Right side of glyph
cmp r2,#16
bls +
// We have one more chunk to render; figure out how much we already rendered
mov r3,#16
sub r3,r3,r1
strb r3,[r0,#8]
// Allocate a new tile
mov r0,r10
mov r1,r11
lsr r0,r0,#3
add r0,r0,#2
lsr r1,r1,#3
bl .get_tile_number
add r0,r8
mov r4,r0
lsl r0,r0,#5
mov r1,#6
lsl r1,r1,#0x18
add r0,r0,r1
str r0,[sp,#0]
mov r0,sp
bl .print_right
//----------------------------------------
// Update the map
orr r4,r6
mov r1,r7
ldr r2,[sp,#16]
-
strh r4,[r1,#0]
add r4,#0x20
add r1,#0x40
sub r2,r2,#1
bne -
add r7,r7,#2
//----------------------------------------
+
mov r0,r9
add sp,#24
pop {r4}
mov r12,r4
pop {r4-r7}
mov r8,r4
mov r9,r5
mov r10,r6
mov r11,r7
pop {r1-r7,pc}
//=============================================================================
// void print_left(void* structPointer)
//=============================================================================
// In:
// r0: struct pointer
// [r0+0]: VRAM address
// [r0+4]: glyph address
// [r0+8]: VRAM x offset (byte)
// [r0+9]: render width (byte)
// [r0+10]: background index (byte)
// [r0+11]: foreground index (byte)
// [r0+12]: height in tiles (byte)
// [r0+13]: <unused> (3 bytes)
.print_left:
print "m2vwf.print_left: $",pc
push {r0-r7,lr}
mov r7,r0
//----------------------------------------
ldr r6,[r7,#0] // VRAM address
ldr r3,[r7,#4] // Glyph address
ldrb r4,[r7,#12] // Height in tiles
.print_left_loop:
mov r5,#8
-
ldr r0,[r6,#0] // 4BPP VRAM row
ldrb r1,[r7,#11] // Foreground index
bl .reduce_bit_depth // Returns r0 = 1BPP VRAM row
ldrb r1,[r7,#9] // Glyph render width
mov r2,#32
sub r2,r2,r1
ldrb r1,[r3,#0] // Glyph row
lsl r1,r2 // Cut off the pixels we don't want to render
lsr r1,r2
ldrb r2,[r7,#8] // X offset
lsl r1,r2
lsl r1,r1,#0x18
lsr r1,r1,#0x18
orr r0,r1
ldrb r1,[r7,#10]
ldrb r2,[r7,#11]
bl .expand_bit_depth
str r0,[r6,#0]
add r6,r6,#4
add r3,r3,#1
sub r5,r5,#1
bne -
mov r0,#0x1F
lsl r0,r0,#5
add r6,r0,r6
add r3,#8
sub r4,r4,#1
bne .print_left_loop
//----------------------------------------
pop {r0-r7,pc}
//=============================================================================
// void print_right(void* structPointer)
//=============================================================================
// In:
// r0: struct pointer
// [r0+0]: VRAM address
// [r0+4]: glyph address
// [r0+8]: glyph x offset (byte)
// [r0+9]: render width (byte)
// [r0+10]: background index (byte)
// [r0+11]: foreground index (byte)
// [r0+12]: height in tiles (byte)
// [r0+13]: <unused> (3 bytes)
.print_right:
print "m2vwf.print_right: $",pc
push {r0-r7,lr}
mov r7,r0
//----------------------------------------
ldr r6,[r7,#0] // VRAM address
ldr r3,[r7,#4] // Glyph address
ldrb r4,[r7,#12] // Height in tiles
.print_right_loop:
mov r5,#8
-
ldr r0,[r6,#0] // 4BPP VRAM row
ldrb r1,[r7,#11] // Foreground index
bl .reduce_bit_depth // Returns r0 = 1BPP VRAM row
ldrb r1,[r7,#9] // Glyph render width
mov r2,#32
sub r2,r2,r1
ldrb r1,[r3,#0] // Glyph row
lsl r1,r2 // Cut off the pixels we don't want to render
lsr r1,r2
ldrb r2,[r7,#8] // X offset
lsr r1,r2
lsl r1,r1,#0x18
lsr r1,r1,#0x18
orr r0,r1
ldrb r1,[r7,#10]
ldrb r2,[r7,#11]
bl .expand_bit_depth
str r0,[r6,#0]
add r6,r6,#4
add r3,r3,#1
sub r5,r5,#1
bne -
mov r0,#0x1F
lsl r0,r0,#5
add r6,r0,r6
add r3,#8
sub r4,r4,#1
bne .print_right_loop
//----------------------------------------
pop {r0-r7,pc}
//==============================================================================
// void erase_tile(int x, int y)
// In:
// r0: x
// r1: y
//==============================================================================
.erase_tile:
push {r0-r2,lr}
//--------------------------------
bl .get_tile_number
ldr r1,=#0x30051EC
ldrh r1,[r1,#0] // Tile offset
add r0,r0,r1
mov r2,#6
lsl r2,r2,#0x18
lsl r0,r0,#5
add r0,r0,r2
ldr r1,=#0x44444444 // Empty row of pixels
str r1,[r0,#0]
str r1,[r0,#4]
str r1,[r0,#8]
str r1,[r0,#12]
str r1,[r0,#16]
str r1,[r0,#20]
str r1,[r0,#24]
str r1,[r0,#28]
//--------------------------------
pop {r0-r2,pc}
//==============================================================================
// void erase_tile_short(int x, int y, WINDOW* window)
// In:
// r4: (x << 16), relative
// r8: y, relative
// r6: window
//==============================================================================
.erase_tile_short:
push {r0-r2,r4,lr}
//--------------------------------
// Get the window X and Y
mov r0,#0x22
ldrb r1,[r6,r0] // Window X
mov r0,#0x24
ldrb r2,[r6,r0] // Window Y
lsr r4,r4,#16
add r0,r1,r4 // Absolute X
mov r1,r8
add r1,r1,r2 // Absolute Y
bl .erase_tile
//--------------------------------
// Clobbered code
pop {r0-r2,r4}
strh r0,[r5,#0]
mov r0,r12
//--------------------------------
pop {pc}
//==============================================================================
// void erase_tile_short2(int x, int y, WINDOW* window)
// In:
// r2: (x << 16), relative
// r7: y, relative
// r4: window
//==============================================================================
.erase_tile_short2:
push {r0-r3,lr}
//--------------------------------
// Get the window X and Y
mov r0,#0x22
ldrb r1,[r4,r0] // Window X
mov r0,#0x24
ldrb r3,[r4,r0] // Window Y
lsr r2,r2,#16
add r0,r1,r2 // Absolute X
add r1,r3,r7 // Absolute Y
bl .erase_tile
//--------------------------------
// Clobbered code
pop {r0-r3}
strh r0,[r5,#0]
lsl r1,r6,#0x10
//--------------------------------
pop {pc}
//==============================================================================
// void erase_tile_main(TILEDATA* tileData)
// In:
// r12: tile data address
//==============================================================================
.erase_tile_main:
print "m2vwf.erase_tile_main: $",pc
push {r2,lr}
//--------------------------------
// Figure out X and Y based on the tile data address
ldr r1,=#0x3005270
ldr r0,[r1,#0] // Tilemap base
mov r1,r12
sub r0,r1,r0
lsr r1,r0,#1
lsl r0,r1,#27
lsr r0,r0,#27 // X
lsr r1,r1,#5 // Y
bl .erase_tile
// This only gets called once per character, ie, once for every two tiles vertically
// So we need to erase the next tile down as well
add r1,r1,#1
bl .erase_tile
//--------------------------------
// Clobbered code
ldrh r1,[r7,#0]
add r0,r6,r1
pop {r2,pc}
//==============================================================================
// void copy_tile(TILEDATA* source, TILEDATA* dest)
// In:
// r7: source
// r5: dest
// r10: 3005270
//==============================================================================
.copy_tile:
push {r0-r6,lr}
mov r0,r8
mov r1,r9
mov r2,r10
push {r0-r2}
//--------------------------------
mov r0,r10
mov r3,#0x1F
ldr r2,[r0,#0] // Tilemap base
sub r1,r7,r2
lsr r0,r1,#1
mov r4,r0
and r0,r3 // Source X
lsr r1,r4,#5 // Source Y
bl .get_tile_number
ldr r4,=#0x30051EC
mov r10,r4
ldr r4,[r4,#0]
mov r8,r4
add r6,r0,r4 // Source tile number
lsl r6,r6,#5
sub r1,r5,r2
lsr r0,r1,#1
mov r2,r0
and r0,r3 // Dest X
lsr r1,r2,#5 // Dest Y
bl .get_tile_number
add r2,r0,r4 // Dest tile number
mov r9,r2
lsl r2,r2,#5
// Add the VRAM base
mov r1,#6
lsl r3,r1,#0x18
add r1,r6,r3
add r2,r2,r3
// Copy the tile
ldr r0,[r1,#0]
str r0,[r2,#0]
ldr r0,[r1,#4]
str r0,[r2,#4]
ldr r0,[r1,#8]
str r0,[r2,#8]
ldr r0,[r1,#12]
str r0,[r2,#12]
ldr r0,[r1,#16]
str r0,[r2,#16]
ldr r0,[r1,#20]
str r0,[r2,#20]
ldr r0,[r1,#24]
str r0,[r2,#24]
ldr r0,[r1,#28]
str r0,[r2,#28]
// Erase the old tile
ldr r0,=#0x44444444 // Empty row of pixels
str r0,[r1,#0]
str r0,[r1,#4]
str r0,[r1,#8]
str r0,[r1,#12]
str r0,[r1,#16]
str r0,[r1,#20]
str r0,[r1,#24]
str r0,[r1,#28]
//--------------------------------
// Clobbered code: original game copies
// tile data always; we only want it under certain conditions
ldr r0,=#0x1FF
mov r1,r8 // Tile offset
add r0,r0,r1 // Blank tile number
ldrh r2,[r7,#0]
lsl r1,r2,#20
lsr r1,r1,#20 // Source tile number
ldrh r3,[r5,#0]
lsl r2,r3,#20
lsr r2,r2,#20 // Dest tile number
// If we're copying from non-blank to blank, we need to
// update the dest tile data
cmp r1,r0
beq +
cmp r2,r0
bne +
// Update tile data
mov r1,r9 // Dest tile number
mov r3,r10
add r3,#0x3C
ldrh r2,[r3,#0] // Palette mask
orr r1,r2
strh r1,[r5,#0]
+
//--------------------------------
pop {r0-r2}
mov r8,r0
mov r9,r1
mov r10,r2
pop {r0-r6,pc}
//==============================================================================
// byte reduce_bit_depth(int pixels)
// In:
// r0: row of 4BPP pixels
// r1: foreground index
// Out:
// r0: row of 1BPP pixels
//==============================================================================
.reduce_bit_depth:
push {r1-r6,lr}
mov r3,r0
mov r0,#0
mov r4,#0xF
mov r5,#1
mov r6,#28
//--------------------------------
-
mov r2,r3
lsr r2,r6
and r2,r4
cmp r1,r2
bne +
orr r0,r5
+
sub r6,r6,#4
bmi +
lsl r0,r0,#1
b -
//--------------------------------
+
pop {r1-r6,pc}
//==============================================================================
// int expand_bit_depth(byte pixels)
// In:
// r0: row of 1BPP pixels
// r1: background index
// r2: foreground index
// Out:
// r0: row of 4BPP pixels
//==============================================================================
.expand_bit_depth:
push {r1-r6,lr}
mov r3,r0
mov r0,#0
mov r5,#1
mov r6,#7
//--------------------------------
-
mov r4,r3
lsr r4,r6
and r4,r5
bne +
orr r0,r1
b .next
+
orr r0,r2
.next:
sub r6,r6,#1
bmi +
lsl r0,r0,#4
b -
//--------------------------------
+
pop {r1-r6,pc}
//==============================================================================
// void save_tilebase(int tilebase)
// In:
// r0: tilebase
//==============================================================================
.save_tilebase:
print "m2vwf.save_tilebase: $", pc
push {r5,lr}
ldr r5,[sp,#8]
mov lr,r5
ldr r5,[sp,#4]
str r5,[sp,#8]
pop {r5}
add sp,#4
push {r1}
//--------------------------------
ldr r1,=#m2_custom_wram
str r0,[r1,#0]
//--------------------------------
// Clobbered code
str r0,[r4,#4]
ldr r5,=#0x84001600
str r5,[r4,#8]
//--------------------------------
pop {r1}
pop {pc}
//==============================================================================
// void x_reset0()
// In:
// r1: window address
//==============================================================================
.x_reset0:
push {r1-r3,lr}
//--------------------------------
// Get the window number
mov r0,r1
bl .get_window_number
//--------------------------------
// Reset the pixel X
ldr r3,=#m2_custom_wram
add r2,r0,r3
mov r3,#0
strb r3,[r2,#4]
//--------------------------------
// Clear the window
mov r0,r1
bl .clear_window
//--------------------------------
// Clobbered code
mov r0,#0
str r0,[r1,#0x18]
strh r0,[r1,#0x2C]
//--------------------------------
pop {r1-r3,pc}
//==============================================================================
// void x_reset1()
// In:
// r5: window address
//==============================================================================
.x_reset1:
push {r1-r2,lr}
//--------------------------------
// Get the window number
mov r0,r5
bl .get_window_number
//--------------------------------
// Reset the pixel X
ldr r1,=#m2_custom_wram
add r2,r0,r1
mov r1,#0
strb r1,[r2,#4]
//--------------------------------
// Clobbered code
ldrh r0,[r5,#0x2C]
sub r0,#2
//--------------------------------
pop {r1-r2,pc}
//==============================================================================
// void x_reset2()
// In:
// r5: window address
//==============================================================================
.x_reset2:
push {r1-r2,lr}
//--------------------------------
// Get the window number
mov r0,r5
bl .get_window_number
//--------------------------------
// Reset the pixel X
ldr r1,=#m2_custom_wram
add r2,r0,r1
mov r1,#0
strb r1,[r2,#4]
//--------------------------------
// Clobbered code
ldrh r0,[r5,#0x2C]
add r0,#2
//--------------------------------
pop {r1-r2,pc}
//==============================================================================
// void x_reset3()
// In:
// r3: window address
//==============================================================================
.x_reset3:
push {r1-r2,lr}
//--------------------------------
// Get the window number
mov r0,r3
bl .get_window_number
//--------------------------------
// Reset the pixel X
ldr r1,=#m2_custom_wram
add r2,r0,r1
mov r1,#0
strb r1,[r2,#4]
//--------------------------------
// Clear the window
mov r0,r3
bl .clear_window
//--------------------------------
// Clobbered code
mov r0,#0
str r0,[r3,#0x18]
strh r0,[r3,#0x2C]
//--------------------------------
pop {r1-r2,pc}
//==============================================================================
// void x_reset4()
// In:
// r5: window address
//==============================================================================
.x_reset4:
push {r1-r3,lr}
mov r3,r0
//--------------------------------
// Get the window number
mov r0,r5
bl .get_window_number
//--------------------------------
// Reset the pixel X
ldr r1,=#m2_custom_wram
add r2,r0,r1
mov r1,#0
strb r1,[r2,#4]
//--------------------------------
// Clobbered code
mov r0,r3
mov r6,r0
ldr r4,=#0x3005228
pop {r1-r3,pc}
//==============================================================================
// void clear_window(*WINDOW window)
// In:
// r0: window address
//==============================================================================
.clear_window:
print "m2vwf.clear_window: $",pc
push {r0-r7,lr}
mov r1,r8
push {r1}
ldr r1,=#0x44444444
mov r8,r1
//--------------------------------
mov r7,#0x22
ldrb r6,[r0,r7] // Window X
mov r7,#0x24
ldrb r2,[r0,r7] // Window Y
mov r7,#0x26
ldrb r3,[r0,r7] // Window width
add r3,r3,r6 // Window right
mov r7,#0x28
ldrb r4,[r0,r7] // Window height
add r4,r4,r2 // Window bottom
ldr r7,=#0x30051EC
ldrh r7,[r7,#0] // Tile offset
//--------------------------------
.clear_loop:
mov r5,r6
-
mov r0,r5
mov r1,r2
bl .get_tile_number
add r0,r0,r7
lsl r0,r0,#5
mov r1,#6
lsl r1,r1,#0x18
add r0,r0,r1
mov r1,r8
str r1,[r0,#0]
str r1,[r0,#4]
str r1,[r0,#8]
str r1,[r0,#12]
str r1,[r0,#16]
str r1,[r0,#20]
str r1,[r0,#24]
str r1,[r0,#28]
add r5,r5,#1
cmp r5,r3
bcc -
add r2,r2,#1
cmp r2,r4
bcc .clear_loop
//--------------------------------
pop {r1}
mov r8,r1
pop {r0-r7,pc}
//==============================================================================
// void clear_tilemap(*WINDOW window)
// In:
// r0: window address
//==============================================================================
.clear_tilemap:
push {r0-r7,lr}
//--------------------------------
ldr r1,=#0x30051EC
ldrh r6,[r1,#0] // Palette mask
add r1,#0x3C
ldrh r5,[r1,#0] // Tile offset
orr r6,r5
ldr r5,=#0x1FF
add r6,r6,r5 // Blank value to copy to tilemap
add r1,#0x48
ldr r1,[r1,#0] // Tilemap address
mov r7,#0x22
ldrb r2,[r0,r7] // Window X
mov r7,#0x24
ldrb r3,[r0,r7] // Window Y
mov r7,#0x26
ldrb r4,[r0,r7] // Width
mov r7,#0x28
ldrb r5,[r0,r7] // Height
//--------------------------------
// Advance to the appropriate position in the tilemap
lsl r0,r3,#5
add r0,r0,r2
lsl r0,r0,#1
add r1,r0,r1
//--------------------------------
mov r7,#0
.clear_tilemap_loop:
cmp r7,r5
bcs .clear_tilemap_finished
mov r3,#0
mov r2,r1
-
cmp r3,r4
bcs +
strh r6,[r2,#0]
add r2,r2,#2
add r3,r3,#1
b -
+
add r1,r1,#0x40
add r7,r7,#1
b .clear_tilemap_loop
//--------------------------------
.clear_tilemap_finished:
pop {r0-r7,pc}
//==============================================================================
// void main(WINDOW* window, char* chr, TILEDATA* tileData)
// In:
// r5: window
// r7: chr
// r8: tileData
//==============================================================================
.main:
print "m2vwf.main: $",pc
push {r5,lr}
ldr r5,[sp,#8]
mov lr,r5
ldr r5,[sp,#4]
str r5,[sp,#8]
pop {r5}
add sp,#4
push {r0-r2}
//--------------------------------
mov r0,r5
mov r1,r7
mov r2,r8
bl .weld_entry
//--------------------------------
pop {r0-r2}
pop {pc}
//==============================================================================
// void status(WINDOW* window, char* chr, TILEDATA* tileData)
// In:
// r4: window
// r2: chr
// r5: tileData
//==============================================================================
.status:
print "m2vwf.status: $",pc
push {r5,lr}
ldr r5,[sp,#8]
mov lr,r5
ldr r5,[sp,#4]
str r5,[sp,#8]
pop {r5}
add sp,#4
push {r0-r2}
//--------------------------------
mov r0,r4
mov r1,r2
mov r2,r5
bl .weld_entry
//--------------------------------
pop {r0-r2}
pop {pc}
//==============================================================================
// void menu_select(WINDOW* window, char* chr, TILEDATA* tileData)
// In:
// r4: window
// r6: chr
// r3: tileData
//==============================================================================
.menu_select:
print "m2vwf.menu_select: $",pc
push {r5,lr}
ldr r5,[sp,#8]
mov lr,r5
ldr r5,[sp,#4]
str r5,[sp,#8]
pop {r5}
add sp,#4
push {r0-r2}
//--------------------------------
mov r0,r4
mov r1,r2
mov r2,r5
bl .weld_entry
//--------------------------------
pop {r0-r2}
pop {pc}
//==============================================================================
// void selection_menu(WINDOW* window, char* chr, TILEDATA* tileData)
// In:
// r4: window
// r3: chr
// r12: tileData
//==============================================================================
.selection_menu:
print "m2vwf.selection_menu: $",pc
push {r0-r2,lr}
//--------------------------------
mov r0,r4
mov r1,r3
mov r2,r12
bl .weld_entry
//--------------------------------
pop {r0-r2,pc}
//==============================================================================
// void ppcost_once(WINDOW* window)
// In:
// r0: window
//==============================================================================
.ppcost_once:
print "m2vwf.ppcost_once: $",pc
// Need to copy LR to somewhere other than the stack
push {r1,r3}
ldr r3,=#m2_custom_wram
mov r1,lr
str r1,[r3,#0x10]
pop {r1,r3}
// Check [r0 + 0x30]: if it's 0xFFFF, then we've already drawn the window
push {r1,r2}
mov r1,#0x30
ldsh r2,[r0,r1]
mov r1,#1
neg r1,r1
cmp r1,r2
pop {r1,r2}
beq +
bl $80C9634
+
// Get back LR
push {r1,r3}
ldr r3,=#m2_custom_wram
ldr r1,[r3,#0x10]
mov lr,r1
pop {r1,r3}
mov pc,lr
//==============================================================================
// void ppcost_once2(WINDOW* window)
// In:
// r0: window
//==============================================================================
// This one might be more unreliable -- maybe find a better way to do it
// if it causes problems
.ppcost_once2:
print "m2vwf.ppcost_once2: $",pc
// Need to copy LR to somewhere other than the stack
push {r1,r3}
ldr r3,=#m2_custom_wram
mov r1,lr
str r1,[r3,#0x10]
pop {r1,r3}
// Check [r0 + 0x80]: if it's 0xFFFF, then we've already drawn the window
push {r1,r2}
mov r1,#0x80
ldsh r2,[r0,r1]
mov r1,#1
neg r1,r1
cmp r1,r2
pop {r1,r2}
beq +
bl $80C9634
+
// Get back LR
push {r1,r3}
ldr r3,=#m2_custom_wram
ldr r1,[r3,#0x10]
mov lr,r1
pop {r1,r3}
mov pc,lr