diff --git a/src/VsStats.asm b/src/VsStats.asm index c21ba2fa..73400d69 100644 --- a/src/VsStats.asm +++ b/src/VsStats.asm @@ -30,6 +30,14 @@ scope VsStats { stripe_on: db 0x00 + // @ Description + // Current stat page + current_page: + db 0x00 + + constant TOTAL_PAGES(2) + constant PAGE1_GROUP(0x1A) // randomly chosen group, supports up to 7 pages before running out of space + // @ Description // Strings used press_a:; db "Press for Match Stats", 0x00 @@ -46,8 +54,10 @@ scope VsStats { max_combo_hits_vs:; db "Longest Combo VS", 0x00 max_combo_hits_taken:; db "Max Hits Taken", 0x00 max_combo_damage_taken:; db "Max Damage Taken", 0x00 + other_stats:; db "Other Stats", 0x00 dash:; db "-", 0x00 press_b:; db ": Back", 0x00 + press_r:; db ": Next Page", 0x00 OS.align(4) // @ Description @@ -113,9 +123,11 @@ scope VsStats { // @ Description // This macro draws a line of the given width to act as an underline - macro draw_underline(width) { - jal draw_underline_ + macro draw_underline(width, page) { lli a0, {width} + lli a1, {page} + jal draw_underline_ + addiu a1, a1, PAGE1_GROUP } // @ Description @@ -130,7 +142,6 @@ scope VsStats { or s3, r0, a0 // s3 = width lli a0, 0x1F // a0 = room - lli a1, 0x0E // a1 = group lli s1, 24 // s3 = ulx or s2, r0, a2 // s2 = uly lli s4, 1 // s4 = height @@ -151,8 +162,8 @@ scope VsStats { // Draws a row with only a label // @ Arguments // label - address of the string to render - macro draw_header(label) { - draw_row({label}, 0, 0, 0, 0, -1, -1) + macro draw_header(label, page) { + draw_row({label}, 0, 0, 0, 0, -1, -1, {page}) } // @ Description @@ -165,13 +176,15 @@ scope VsStats { // struct_size - size of the struct // port_to_skip - port to skip (0 - 3) when drawing the stats // ignore_port - ignore port - don't draw anything when this port is not active - macro draw_row(label, indent, table, offset, struct_size, port_to_skip, ignore_port) { + macro draw_row(label, indent, table, offset, struct_size, port_to_skip, ignore_port, page) { li t4, {label} // t4 = address of label lli t5, {indent} // t5 = indent addiu t6, r0, {ignore_port} // t6 = ignore port li a0, {table} // a0 = address of table addiu a0, a0, {offset} // a0 = address of value lli a1, {struct_size} // a1 = size of struct + lli t7, {page} // t7 = page + addiu t7, t7, PAGE1_GROUP // t7 = group for page // a2 = y jal draw_line_ lli a3, {port_to_skip} // a3 = port to skip @@ -187,6 +200,7 @@ scope VsStats { // t4 - label address // t5 - indent amount for label // t6 - ignore port - don't do anything when this port is not active + // t7 - group scope draw_line_: { li t0, stats_struct_p1 // t0 = stats_struct_p1 address bltz t6, _begin // if no ignore port (-1) then don't test for active port @@ -209,6 +223,7 @@ scope VsStats { sw a1, 0x0018(sp) // ~ sw a2, 0x001C(sp) // ~ sw a3, 0x0020(sp) // ~ + sw t7, 0x0028(sp) // save group lli t1, 184 // t1 = start urx sw t1, 0x0010(sp) // save start urx @@ -227,7 +242,7 @@ scope VsStats { sb t3, 0x0000(t1) // save flipped value lli a0, 0x1F // a0 = room - lli a1, 0x0E // a1 = group + lw a1, 0x0028(sp) // a1 = group lli s1, 23 // s3 = ulx addiu s2, a2, 0 // s2 = uly lli s3, 266 // s3 = width @@ -238,7 +253,7 @@ scope VsStats { _draw_header: lli a0, 0x1F // a0 = room - lli a1, 0x0E // a1 = group + lw a1, 0x0028(sp) // a1 = group or a2, r0, t4 // a2 = label string address lli a3, 0x0000 // a3 = Render.NOOP lli t0, 24 // t0 = ulx @@ -265,7 +280,7 @@ scope VsStats { // draw stat lli a0, 0x1F // a0 = room - lli a1, 0x0E // a1 = group + lw a1, 0x0028(sp) // a1 = group lw a2, 0x0014(sp) // a2 = value address lli a3, 0x0000 // a3 = Render.NOOP lw t0, 0x0010(sp) // t0 = urx @@ -352,6 +367,16 @@ scope VsStats { _end_collect_{port}: } + // @ Description + // This macro flips the starting stripe value of the last page to keep a checkerboard pattern on the next + macro checkerboard_stripe() { + lb a1, 0x0018(sp) // a1 = starting value of stripe for last page + xori a1, a1, 0x0001 // 0 -> 1 or 1 -> 0 (flip bool) + sb a1, 0x0018(sp) // save flipped value to use again next page + li a0, stripe_on // a0 = stripe_on + sb a1, 0x0000(a0) // save flipped value + } + // @ Description // This draws the 1P, 2P, etc. headers scope draw_port_headers_: { @@ -556,7 +581,14 @@ scope VsStats { jal Render.toggle_group_display_ lli a1, 0x0001 // a1 = 1 -> turn off this display list - lli a0, 0x0E // a0 = group of stats menu + lli a0, 0x0E // a0 = group of stats instructions + port headers + jal Render.toggle_group_display_ + lli a1, 0x0000 // a1 = 0 -> turn on this display list + + lli a0, PAGE1_GROUP // a0 = group of stats (page 1) + li a1, current_page // ~ + lb a1, 0x0000(a1) // a1 = current page + addu a0, a0, a1 // a0 = PAGE1_GROUP + current page jal Render.toggle_group_display_ lli a1, 0x0000 // a1 = 0 -> turn on this display list @@ -576,7 +608,7 @@ scope VsStats { lli a2, Joypad.PRESSED // a2 - type jal Joypad.check_buttons_all_ // v0 - bool b_pressed nop - beqz v0, _end // if (!b_pressed), end + beqz v0, _check_r // if (!b_pressed), check for R button nop // if here, set button press buffer @@ -599,10 +631,72 @@ scope VsStats { jal Render.toggle_group_display_ lli a1, 0x0000 // a1 = 0 -> turn on this display list - lli a0, 0x0E // a0 = group of stats menu + lli a0, 0x0E // a0 = group of stats instructions + port headers + jal Render.toggle_group_display_ + lli a1, 0x0001 // a1 = 1 -> turn off this display list + + lli a0, PAGE1_GROUP // a0 = group of stats (page 1) + lli a2, TOTAL_PAGES // a2 = max amount of pages + addiu a2, a2, PAGE1_GROUP // ~ + addiu a2, a2, -0x0001 // a2 = max page + 1st page group - 1 + + // Loop to turn off all stat pages + _loop_page_off_b: + sltu at, a2, a0 // at = 0 if next group > TOTAL_PAGES group + bnez at, _end // if all pages turned off, don't loop + nop + jal Render.toggle_group_display_ + lli a1, 0x0001 // a1 = 1 -> turn off this display list + + b _loop_page_off_b + addiu a0, a0, 0x0001 // increment next group and loop + + // check for r press + _check_r: + lli a0, Joypad.R // a0 - button_mask + lli a1, 000420 // a1 - whatever you like! + lli a2, Joypad.PRESSED // a2 - type + jal Joypad.check_buttons_all_ // v0 - bool r_pressed + nop + beqz v0, _end // if (!r_pressed), end + nop + + // If we're here, R has been pressed, so update the current page + li a0, current_page // a0 = address of current page + lb a1, 0x0000(a0) // ~ + addiu a1, a1, 0x0001 // a1 = current page + 1 + sltiu a2, a1, TOTAL_PAGES // a2 = 0 only when next page < TOTAL_PAGES + beqzl a2, _loop_setup // skip rollover if within bounds + sb r0, 0x0000(a0) // rollover if next page > TOTAL_PAGES + sb a1, 0x0000(a0) // current page = next page + + _loop_setup: + lli a0, PAGE1_GROUP // a0 = group of stats (page 1) + lli a2, TOTAL_PAGES // a2 = max amount of pages + addiu a2, a2, PAGE1_GROUP // ~ + addiu a2, a2, -0x0001 // a2 = max page + 1st page group - 1 + + // Loop to turn off all stat pages + _loop_page_off_r: + sltu at, a2, a0 // at = 0 if next group > TOTAL_PAGES group + bnez at, _enable_next_page // if all pages turned off, don't loop + nop jal Render.toggle_group_display_ lli a1, 0x0001 // a1 = 1 -> turn off this display list + b _loop_page_off_r + addiu a0, a0, 0x0001 // increment next group and loop + + _enable_next_page: + lli a0, PAGE1_GROUP // a0 = group of stats (page 1) + li a1, current_page // ~ + lb a1, 0x0000(a1) // a1 = next page + addu a0, a0, a1 // a0 = PAGE1_GROUP + next page + jal Render.toggle_group_display_ + lli a1, 0x0000 // a1 = 0 -> turn on this display list + jal FGM.play_ // play menu toggle sound + lli a0, FGM.menu.SCROLL // a0 - fgm_id + _end: lw ra, 0x0004(sp) // restore registers addiu sp, sp, 0x0030 // deallocate stack space @@ -662,6 +756,13 @@ scope VsStats { addiu sp, sp,-0x0030 // allocate stack space sw ra, 0x0004(sp) // save registers + li t1, current_page // t1 = current_page address + sb r0, 0x0000(t1) // set current_page to 0 (always show first page) + + li t1, stripe_on // t1 = stripe_on address + lb t1, 0x0000(t1) // t1 = stripe_on + sb t1, 0x0018(sp) // store starting value of stripe_on for checkerboard between pages + li t1, stats_struct_p1 // t1 = stats_struct_p1 address li t2, stats_struct_p2 // t2 = stats_struct_p2 address li t3, stats_struct_p3 // t3 = stats_struct_p3 address @@ -699,29 +800,36 @@ scope VsStats { Render.draw_string(0x1F, 0x0E, press_b, Render.NOOP, 0x420B0000, 0x417F0000, 0xFFFFFFFF, 0x3F500000, Render.alignment.LEFT, OS.FALSE) Render.draw_texture_at_offset(0x1F, 0x0E, Render.file_pointer_1, Render.file_c5_offsets.B, Render.NOOP, 0x41B40000, 0x41600000, 0x00D040FF, 0x003000FF, 0x3F800000) + // R: Next Page upper left + Render.draw_string(0x1F, 0x0E, press_r, Render.NOOP, 0x42AE0000, 0x417F0000, 0xFFFFFFFF, 0x3F500000, Render.alignment.LEFT, OS.FALSE) + Render.draw_texture_at_offset(0x1F, 0x0E, Render.file_pointer_1, Render.file_c5_offsets.R, Render.NOOP, 0x428F0000, 0x41700000, 0x848484FF, 0x303030FF, 0x3F700000) + // Player port headers jal draw_port_headers_ nop + + // Page 1 + _page_1: // Draw lines lli a2, 30 // a2 = start y - draw_header(damage_stats) + draw_header(damage_stats, 0) addiu a2, a2, -1 // adjust y for better underline - draw_underline(75) - draw_header(damage_dealt_to) - draw_row(p1, 8, stats_struct_p1, 0x0004, 0x0020, 0, 0) - draw_row(p2, 8, stats_struct_p1, 0x0008, 0x0020, 1, 1) - draw_row(p3, 8, stats_struct_p1, 0x000C, 0x0020, 2, 2) - draw_row(p4, 8, stats_struct_p1, 0x0010, 0x0020, 3, 3) - draw_row(total_damage_given, 0, stats_struct_p1, 0x0018, 0x0020, -1, -1) - draw_row(total_damage_taken, 0, stats_struct_p1, 0x0014, 0x0020, -1, -1) - draw_row(highest_damage, 0, stats_struct_p1, 0x001C, 0x0020, -1, -1) + draw_underline(75, 0) + draw_header(damage_dealt_to, 0) + draw_row(p1, 8, stats_struct_p1, 0x0004, 0x0020, 0, 0, 0) + draw_row(p2, 8, stats_struct_p1, 0x0008, 0x0020, 1, 1, 0) + draw_row(p3, 8, stats_struct_p1, 0x000C, 0x0020, 2, 2, 0) + draw_row(p4, 8, stats_struct_p1, 0x0010, 0x0020, 3, 3, 0) + draw_row(total_damage_given, 0, stats_struct_p1, 0x0018, 0x0020, -1, -1, 0) + draw_row(total_damage_taken, 0, stats_struct_p1, 0x0014, 0x0020, -1, -1, 0) + draw_row(highest_damage, 0, stats_struct_p1, 0x001C, 0x0020, -1, -1, 0) b _combo_stats_on_check nop _combo_stats_off: - b _end // skip drawing combo stats if combo meter toggle is off + b _page_2 // skip drawing combo stats if combo meter toggle is off nop _combo_stats_on_check: @@ -729,22 +837,49 @@ scope VsStats { Toggles.guard(Toggles.entry_combo_meter, _combo_stats_off) addiu a2, a2, 5 // adjust y for cleaner spacing - draw_header(combo_stats) + draw_header(combo_stats, 0) + addiu a2, a2, -1 // adjust y for better underline + draw_underline(68, 0) + draw_header(max_combo_hits_vs, 0) + draw_row(p1, 8, ComboMeter.combo_struct_p1, 0x0024, 0x0038, 0, 0, 0) + draw_row(p2, 8, ComboMeter.combo_struct_p1, 0x0028, 0x0038, 1, 1, 0) + draw_row(p3, 8, ComboMeter.combo_struct_p1, 0x002C, 0x0038, 2, 2, 0) + draw_row(p4, 8, ComboMeter.combo_struct_p1, 0x0030, 0x0038, 3, 3, 0) + draw_row(max_combo_hits_taken, 0, ComboMeter.combo_struct_p1, 0x0004, 0x0038, -1, -1, 0) + draw_row(max_combo_damage_taken, 0, ComboMeter.combo_struct_p1, 0x0008, 0x0038, -1, -1, 0) + + // Page 2 example + _page_2: + // Draw lines + checkerboard_stripe() // continue checkerboard stripe pattern between pages + lli a2, 30 // a2 = start y + draw_header(other_stats, 1) addiu a2, a2, -1 // adjust y for better underline - draw_underline(68) - draw_header(max_combo_hits_vs) - draw_row(p1, 8, ComboMeter.combo_struct_p1, 0x0024, 0x0038, 0, 0) - draw_row(p2, 8, ComboMeter.combo_struct_p1, 0x0028, 0x0038, 1, 1) - draw_row(p3, 8, ComboMeter.combo_struct_p1, 0x002C, 0x0038, 2, 2) - draw_row(p4, 8, ComboMeter.combo_struct_p1, 0x0030, 0x0038, 3, 3) - draw_row(max_combo_hits_taken, 0, ComboMeter.combo_struct_p1, 0x0004, 0x0038, -1, -1) - draw_row(max_combo_damage_taken, 0, ComboMeter.combo_struct_p1, 0x0008, 0x0038, -1, -1) + draw_underline(64, 1) + // Hide stat groups so they aren't visible when first entering results screen _end: - lli a0, 0x0E // a0 = group of menu stats + lli a0, 0x0E // a0 = group of stats instructions + port headers jal Render.toggle_group_display_ lli a1, 0x0001 // a1 = 1 -> turn off this display list + lli a0, PAGE1_GROUP // a0 = group of stats (page 1) + lli a2, TOTAL_PAGES // a2 = max amount of pages + addiu a2, a2, PAGE1_GROUP // ~ + addiu a2, a2, -0x0001 // a2 = max page + 1st page group - 1 + + // Loop to turn off all stat pages + _loop_page_off: + sltu at, a2, a0 // at = 0 if next group > TOTAL_PAGES group + bnez at, _loop_page_end // if all pages turned off, don't loop + nop + jal Render.toggle_group_display_ + lli a1, 0x0001 // a1 = 1 -> turn off this display list + + b _loop_page_off + addiu a0, a0, 0x0001 // increment next group and loop + + _loop_page_end: lw ra, 0x0004(sp) // restore registers addiu sp, sp, 0x0030 // deallocate stack space