From c45b93754cd259452277e2ec47f914e08d726cb0 Mon Sep 17 00:00:00 2001 From: RPG Hacker Date: Wed, 10 Apr 2024 09:08:44 +0200 Subject: [PATCH] VWF Test Suite works --- .../data/testing/data/vwfmessages.asm | 24 + patches/vwf_dialogues/package.bat | 1 + patches/vwf_dialogues/patch_config.py | 2 + .../testing/uberasm/code/gamemode_code.asm | 160 +--- patches/vwf_dialogues/vwf_dialogues.asm | 51 +- patches/vwf_dialogues/vwftestsuite.asm | 737 ++++++++++++++++++ 6 files changed, 813 insertions(+), 162 deletions(-) create mode 100644 patches/vwf_dialogues/vwftestsuite.asm diff --git a/patches/vwf_dialogues/data/testing/data/vwfmessages.asm b/patches/vwf_dialogues/data/testing/data/vwfmessages.asm index 3c1a0ec..4f9e579 100644 --- a/patches/vwf_dialogues/data/testing/data/vwfmessages.asm +++ b/patches/vwf_dialogues/data/testing/data/vwfmessages.asm @@ -55,6 +55,30 @@ %vwf_claim_varram(box_anim_test_show_close, 1) +%vwf_register_test_suite_category("BasicCommands", "Basic Commands") +%vwf_register_test("BasicCommands", "Hub", $0050) +%vwf_register_test("BasicCommands", "Test 1", $0050) +%vwf_register_test("BasicCommands", "Test 2", $0050) +%vwf_register_test("BasicCommands", "Test 3", $0050) +%vwf_register_test("BasicCommands", "Test 4", $0050) +%vwf_register_test("BasicCommands", "Test 5", $0050) +%vwf_register_test("BasicCommands", "Test 6", $0050) +%vwf_register_test("BasicCommands", "Test 7", $0050) +%vwf_register_test("BasicCommands", "Test 8", $0050) +%vwf_register_test("BasicCommands", "Test 9", $0050) +%vwf_register_test("BasicCommands", "Test 10", $0050) +%vwf_register_test("BasicCommands", "Test 11", $0050) +%vwf_register_test("BasicCommands", "Test 12", $0050) +%vwf_register_test("BasicCommands", "Test 13", $0050) +%vwf_register_test("BasicCommands", "Test 14", $0050) +%vwf_register_test("BasicCommands", "Test 15", $0050) +%vwf_register_test("BasicCommands", "Test 16", $0050) +%vwf_register_test("BasicCommands", "Test 17", $0050) +%vwf_register_test("BasicCommands", "Test 18", $0050) +%vwf_register_test("BasicCommands", "Test 19", $0050) +%vwf_register_test("BasicCommands", "Test 20", $0050) + + ; Messages: ; RPG Hacker: Really, message $0050 (Yoshi's House) is the most important one for us, since it's the quickest one to get to. diff --git a/patches/vwf_dialogues/package.bat b/patches/vwf_dialogues/package.bat index ba22b93..4434bc3 100644 --- a/patches/vwf_dialogues/package.bat +++ b/patches/vwf_dialogues/package.bat @@ -26,6 +26,7 @@ IF EXIST "./%patchname%.zip" ( "C:\Program Files\7-Zip\7z.exe" rn ./%patchname%.zip code/external/vwfsharedroutines.asm code/blocks/display_once_on_touch/vwfsharedroutines.asm "C:\Program Files\7-Zip\7z.exe" a ./%patchname%.zip code/external/vwfsharedroutines.asm +"C:\Program Files\7-Zip\7z.exe" d ./%patchname%.zip vwftestsuite.asm cd ..\.. diff --git a/patches/vwf_dialogues/patch_config.py b/patches/vwf_dialogues/patch_config.py index 9ae4f15..1caf771 100644 --- a/patches/vwf_dialogues/patch_config.py +++ b/patches/vwf_dialogues/patch_config.py @@ -57,6 +57,8 @@ def main() -> None: if options.messages_file == 'smw': vwf_dialogues_asm.include_paths[0] = os.path.join(os.path.dirname(__file__), 'data/smw') + else: + vwf_dialogues_asm.defines.append('vwf_enable_test_suite=true') if options.bit_mode == '16-bit': vwf_dialogues_asm.defines.append('vwf_bit_mode=VWF_BitMode.16Bit') diff --git a/patches/vwf_dialogues/testing/uberasm/code/gamemode_code.asm b/patches/vwf_dialogues/testing/uberasm/code/gamemode_code.asm index f2f1371..a2a08b9 100644 --- a/patches/vwf_dialogues/testing/uberasm/code/gamemode_code.asm +++ b/patches/vwf_dialogues/testing/uberasm/code/gamemode_code.asm @@ -1,151 +1,7 @@ +; This is here twice intentionally, to test the include guard. incsrc "vwfsharedroutines.asm" incsrc "vwfsharedroutines.asm" -macro write_stripe_image_header(x_pos, y_pos, data_size) - !temp_length = (()-1) - - db %01010000|((&%100000)>>2)|((&%100000)>>3)|((&%011000)>>3) - db ((&%000111)<<5)|(&%011111) - db %00000000|((!temp_length&%11111100000000)>>8) - db !temp_length&%00000011111111 - - undef "temp_length" -endmacro - -macro define_stripe_image_raw_line(x_pos, y_pos, ...) - !magic_token ?= .X - !magic_token += X - -!magic_token: - %write_stripe_image_header(, , ..End-..Start) - -..Start: - for i = 0..sizeof(...) - db <...[!i]> - db $39 - endfor -..End: -endmacro - -macro define_stripe_image_text_line(x_pos, y_pos, text) - pushtable - - ;!temp_property_byte #= %00111001 - !temp_property_byte = 39 - - 'A' = $!{temp_property_byte}00 - 'B' = $!{temp_property_byte}01 - 'C' = $!{temp_property_byte}02 - 'D' = $!{temp_property_byte}03 - 'E' = $!{temp_property_byte}04 - 'F' = $!{temp_property_byte}05 - 'G' = $!{temp_property_byte}06 - 'H' = $!{temp_property_byte}07 - 'I' = $!{temp_property_byte}08 - 'J' = $!{temp_property_byte}09 - 'K' = $!{temp_property_byte}0A - 'L' = $!{temp_property_byte}0B - 'M' = $!{temp_property_byte}0C - 'N' = $!{temp_property_byte}0D - 'O' = $!{temp_property_byte}0E - 'P' = $!{temp_property_byte}0F - - 'Q' = $!{temp_property_byte}10 - 'R' = $!{temp_property_byte}11 - 'S' = $!{temp_property_byte}12 - 'T' = $!{temp_property_byte}13 - 'U' = $!{temp_property_byte}14 - 'V' = $!{temp_property_byte}15 - 'W' = $!{temp_property_byte}16 - 'X' = $!{temp_property_byte}17 - 'Y' = $!{temp_property_byte}18 - 'Z' = $!{temp_property_byte}19 - '!' = $!{temp_property_byte}1A - '.' = $!{temp_property_byte}1B - '-' = $!{temp_property_byte}1C - ',' = $!{temp_property_byte}1D - '?' = $!{temp_property_byte}1E - ' ' = $!{temp_property_byte}1F - - 'a' = $!{temp_property_byte}40 - 'b' = $!{temp_property_byte}41 - 'c' = $!{temp_property_byte}42 - 'd' = $!{temp_property_byte}43 - 'e' = $!{temp_property_byte}44 - 'f' = $!{temp_property_byte}45 - 'g' = $!{temp_property_byte}46 - 'h' = $!{temp_property_byte}47 - 'i' = $!{temp_property_byte}48 - 'j' = $!{temp_property_byte}49 - 'k' = $!{temp_property_byte}4A - 'l' = $!{temp_property_byte}4B - 'm' = $!{temp_property_byte}4C - 'n' = $!{temp_property_byte}4D - 'o' = $!{temp_property_byte}4E - 'p' = $!{temp_property_byte}4F - - 'q' = $!{temp_property_byte}50 - 'r' = $!{temp_property_byte}51 - 's' = $!{temp_property_byte}52 - 't' = $!{temp_property_byte}53 - 'u' = $!{temp_property_byte}54 - 'v' = $!{temp_property_byte}55 - 'w' = $!{temp_property_byte}56 - 'x' = $!{temp_property_byte}57 - 'y' = $!{temp_property_byte}58 - 'z' = $!{temp_property_byte}59 - '#' = $!{temp_property_byte}5A - '(' = $!{temp_property_byte}5B - ')' = $!{temp_property_byte}5C - ''' = $!{temp_property_byte}5D : ''' = $!{temp_property_byte}5D - - ; Used as cursor character - '>' = $!{temp_property_byte}5E - - undef "temp_property_byte" - - !magic_token ?= .X - !magic_token += X - -!magic_token: - %write_stripe_image_header(, , ..End-..Start) - -..Start: - dw "" -..End: - - pulltable -endmacro - -macro stripe_image_end() - db $FF -endmacro - -macro transfer_stripe_image(address, size) - rep #$30 - - ldx.w #(
) - - lda $7F837B - clc - adc.w #$7F837D - tay - - lda.w #() - pha - dec - clc - adc $7F837B - sta $7F837B - pla - - phb - mvn bank($7F837D), bank(
) - plb - - sep #$30 -endmacro - gamemode_0: RTS gamemode_1: @@ -224,22 +80,8 @@ gamemode_14: error "Whoops, VWF_DisplayAMessage routine not found. Did you patch UberASM before VWF Dialogues Patch?" endif - - lda.b #%00001000 - tsb $3E - lda.b #%00000100 - trb $40 - - %transfer_stripe_image(.TestImage, .TestImageEnd-.TestImage) - RTS -.TestImage -%define_stripe_image_raw_line(1, 32, $1F, $1F, $1F, $1F, $1F, $1F, $1F) -%define_stripe_image_text_line(2, 32, "Test") -%stripe_image_end() -.TestImageEnd - gamemode_15: RTS gamemode_16: diff --git a/patches/vwf_dialogues/vwf_dialogues.asm b/patches/vwf_dialogues/vwf_dialogues.asm index 3e90ff4..6beb0c5 100644 --- a/patches/vwf_dialogues/vwf_dialogues.asm +++ b/patches/vwf_dialogues/vwf_dialogues.asm @@ -61,6 +61,7 @@ if !use_sa1_mapping endif !vwf_debug_vblank_time ?= false +!vwf_enable_test_suite ?= false !vwf_var_rampos #= 0 @@ -198,6 +199,11 @@ endmacro %vwf_claim_varram(current_box_color, 6) %vwf_claim_varram(current_box_frame, 1) +if !vwf_enable_test_suite != false + %vwf_claim_varram(current_test_suite_page, 1) + %vwf_claim_varram(current_test_suite_row, 1) +endif + !vwf_buffer_empty_tile = !vwf_gfx_ram !vwf_buffer_bg_tile = !vwf_gfx_ram+$10 !vwf_buffer_frame = !vwf_gfx_ram+$20 @@ -749,8 +755,13 @@ endif .NoOriginalMessageBoxRequested ; New code: If our own message box is open, also don't simulate frame. lda !vwf_freeze_sprites - beq .RunGameFrame +if !vwf_enable_test_suite != false + bne .FreezeGame + lda !vwf_current_test_suite_page +endif + beq .RunGameFrame +.FreezeGame jml remap_rom($00A1E3) ; Skip frame simulation .RunGameFrame @@ -793,6 +804,16 @@ NMIHijack: jml remap_rom($00827A) .NoSpecialIrqMode +if !vwf_enable_test_suite != false + lda !vwf_current_test_suite_page + beq .NoTestSuiteNMI + + jsr TestSuiteNMI + + bra .NMIEndWithoutHDMA +.NoTestSuiteNMI +endif + lda !vwf_mode tax lda.l .NMITable,x @@ -864,14 +885,17 @@ endif lda.b #$01 sta $2112 - lda remap_ram($0DAE) - sta $2100 +.NMIEnd lda remap_ram($0D9F) if !vwf_enable_smb3_status_bar_layer_3_hdma_fix_hack != false and.b #%11111110 endif sta $420C +.NMIEndWithoutHDMA + lda remap_ram($0DAE) + sta $2100 + ldx.b #$81 ; Disable IRQ if !use_sa1_mapping == false stx $4200 @@ -986,6 +1010,15 @@ endif jmp (.Routinetable,x) .End +if !vwf_enable_test_suite != false + lda !vwf_mode + bne .RealEnd + + jsr ProcessTestSuiteInput + +.RealEnd +endif + if !use_sa1_mapping else plp ; Return @@ -6069,6 +6102,12 @@ BackupTilemap: Emptytile: db $00,$20 + + + +if !vwf_enable_test_suite != false + incsrc vwftestsuite.asm +endif @@ -6135,6 +6174,12 @@ MainDataStart: %vwf_next_bank() %vwf_generate_pointers() + +if !vwf_enable_test_suite != false + %vwf_next_bank() + %vwf_generate_test_suite_tables() + %vwf_generate_test_suite_stripe_images() +endif ; Shared routine tables go here. diff --git a/patches/vwf_dialogues/vwftestsuite.asm b/patches/vwf_dialogues/vwftestsuite.asm new file mode 100644 index 0000000..ea1e8d6 --- /dev/null +++ b/patches/vwf_dialogues/vwftestsuite.asm @@ -0,0 +1,737 @@ + +macro vwf_write_stripe_image_header(x_pos, y_pos, data_size, is_rle) + if != false + !temp_rle = %01000000 + !temp_length = (-()) + else + !temp_rle = %00000000 + !temp_length = (()-1) + endif + + db %01010000|((()&%100000)>>2)|((()&%100000)>>3)|((()&%011000)>>3) + db ((()&%000111)<<5)|(()&%011111) + db !temp_rle|((!temp_length&%11111100000000)>>8) + db !temp_length&%00000011111111 + + undef "temp_rle" + undef "temp_length" +endmacro + +macro vwf_define_stripe_image_raw_line(x_pos, y_pos, ...) + !magic_token ?= .X + !magic_token += X + +!magic_token: + %vwf_write_stripe_image_header(, , ..End-..Start, false) + +..Start: + for i = 0..sizeof(...) + db <...[!i]> + db $39 + endfor +..End: +endmacro + +macro vwf_define_stripe_image_raw_line_rle(x_pos, y_pos, tile_id, count) + !magic_token ?= .X + !magic_token += X + +!magic_token: + %vwf_write_stripe_image_header(, , -()*2, true) + + db + db $39 +endmacro + +macro vwf_define_stripe_image_text_line(x_pos, y_pos, text) + pushtable + + !temp_property_byte #= %00111001<<8 + !temp_property_byte_page_1 #= %00111000<<8 + + 'A' = !temp_property_byte|$00 + 'B' = !temp_property_byte|$01 + 'C' = !temp_property_byte|$02 + 'D' = !temp_property_byte|$03 + 'E' = !temp_property_byte|$04 + 'F' = !temp_property_byte|$05 + 'G' = !temp_property_byte|$06 + 'H' = !temp_property_byte|$07 + 'I' = !temp_property_byte|$08 + 'J' = !temp_property_byte|$09 + 'K' = !temp_property_byte|$0A + 'L' = !temp_property_byte|$0B + 'M' = !temp_property_byte|$0C + 'N' = !temp_property_byte|$0D + 'O' = !temp_property_byte|$0E + 'P' = !temp_property_byte|$0F + + 'Q' = !temp_property_byte|$10 + 'R' = !temp_property_byte|$11 + 'S' = !temp_property_byte|$12 + 'T' = !temp_property_byte|$13 + 'U' = !temp_property_byte|$14 + 'V' = !temp_property_byte|$15 + 'W' = !temp_property_byte|$16 + 'X' = !temp_property_byte|$17 + 'Y' = !temp_property_byte|$18 + 'Z' = !temp_property_byte|$19 + '!' = !temp_property_byte|$1A + '.' = !temp_property_byte|$1B + '-' = !temp_property_byte|$1C + ',' = !temp_property_byte|$1D + '?' = !temp_property_byte|$1E + ' ' = !temp_property_byte|$1F + + 'a' = !temp_property_byte|$40 + 'b' = !temp_property_byte|$41 + 'c' = !temp_property_byte|$42 + 'd' = !temp_property_byte|$43 + 'e' = !temp_property_byte|$44 + 'f' = !temp_property_byte|$45 + 'g' = !temp_property_byte|$46 + 'h' = !temp_property_byte|$47 + 'i' = !temp_property_byte|$48 + 'j' = !temp_property_byte|$49 + 'k' = !temp_property_byte|$4A + 'l' = !temp_property_byte|$4B + 'm' = !temp_property_byte|$4C + 'n' = !temp_property_byte|$4D + 'o' = !temp_property_byte|$4E + 'p' = !temp_property_byte|$4F + + 'q' = !temp_property_byte|$50 + 'r' = !temp_property_byte|$51 + 's' = !temp_property_byte|$52 + 't' = !temp_property_byte|$53 + 'u' = !temp_property_byte|$54 + 'v' = !temp_property_byte|$55 + 'w' = !temp_property_byte|$56 + 'x' = !temp_property_byte|$57 + 'y' = !temp_property_byte|$58 + 'z' = !temp_property_byte|$59 + '#' = !temp_property_byte|$5A + '(' = !temp_property_byte|$5B + ')' = !temp_property_byte|$5C + ''' = !temp_property_byte|$5D : ''' = !temp_property_byte|$5D + '/' = !temp_property_byte|$3F + + '0' = !temp_property_byte_page_1|$00 + '1' = !temp_property_byte_page_1|$01 + '2' = !temp_property_byte_page_1|$02 + '3' = !temp_property_byte_page_1|$03 + '4' = !temp_property_byte_page_1|$04 + '5' = !temp_property_byte_page_1|$05 + '6' = !temp_property_byte_page_1|$06 + '7' = !temp_property_byte_page_1|$07 + '8' = !temp_property_byte_page_1|$08 + '9' = !temp_property_byte_page_1|$09 + + ; Used as cursor character + '>' = !temp_property_byte|$5E + + undef "temp_property_byte" + undef "temp_property_byte_page_1" + + !magic_token ?= .X + !magic_token += X + +!magic_token: + %vwf_write_stripe_image_header(, , ..End-..Start, false) + +..Start: + dw "" +..End: + + pulltable +endmacro + +macro vwf_stripe_image_end() + db $FF +endmacro + +macro vwf_append_stripe_image(address, size) + rep #$30 + + ldx.w #(
) + + lda $7F837B + clc + adc.w #$7F837D + tay + + lda.w #() + pha + dec + clc + adc $7F837B + sta $7F837B + pla + + phb + mvn bank($7F837D), bank(
) + plb + + sep #$30 +endmacro + + +TestSuiteNMI: + lda remap_ram($0D9D) + ora.b #%00000100 + sta $212C + lda remap_ram($0D9E) + and.b #%11111011 + sta $212D + + lda $3E + ora.b #%00001000 + sta $2105 + lda $40 + and.b #%11111011 + sta $2131 + + stz $11 + stz $2111 ; Set layer 3 X scroll to $0000 + stz $2111 + lda.b #$1F ; Set layer 3 Y scroll to $011F + sta $2112 + lda.b #$01 + sta $2112 + + lda.b #$22 + sta $2123 + lda.b #$00 + sta $2124 + lda.b #$22 + sta $2125 + lda.b #$22 + sta $2130 + + lda remap_ram($0D9F) + ora.b #$80 + sta $420C + + rts + + +ProcessTestSuiteInput: + lda !vwf_current_test_suite_page + beq .NotOpenYet + +.AlreadyOpen + lda.b #%10000000 + trb $18 + beq .DontConfirm + + lda.b #$29 + sta $1DFC + + jsr StartMessage + + jsr CloseTestSuite + rts + +.DontConfirm + lda.b #%00010000 + trb $16 + beq .DontClose + + lda.b #$12 + sta $1DF9 + + jsr CloseTestSuite + rts + +.DontClose + lda.b #%00001000 + trb $16 + beq .UpNotPressed + + jsr CursorUp + +.UpNotPressed + lda.b #%00000100 + trb $16 + beq .DownNotPressed + + jsr CursorDown + +.DownNotPressed + lda.b #%00000010 + trb $16 + beq .LeftNotPressed + + jsr PageLeft + +.LeftNotPressed + lda.b #%00000001 + trb $16 + beq .RightNotPressed + + jsr PageRight + +.RightNotPressed + rts + +.NotOpenYet + lda.b #%00010000 + trb $16 + beq .Return + + lda.b #$12 + sta $1DF9 + + jsr OpenTestSuite + +.Return + rts + + +CursorUp: + lda.b #$23 + sta $1DFC + + jsr ClearCursor + jsr GetNumTestsOnPage + + lda !vwf_current_test_suite_row + dec + bpl .NoWrapAround + lda $00 + dec + +.NoWrapAround + sta !vwf_current_test_suite_row + + jsr DrawCursor + + rts + +CursorDown: + lda.b #$23 + sta $1DFC + + jsr ClearCursor + jsr GetNumTestsOnPage + + lda !vwf_current_test_suite_row + inc + cmp $00 + bcc .NoWrapAround + lda.b #$00 + +.NoWrapAround + sta !vwf_current_test_suite_row + + jsr DrawCursor + + rts + +PageLeft: + lda.b #$23 + sta $1DFC + + lda !vwf_current_test_suite_page + dec + bne .NoWrapAround + lda TestSuiteNumPages + +.NoWrapAround + sta !vwf_current_test_suite_page + + jsr ClampCursor + jsr DrawCurrentTestSuitePage + jsr DrawCursor + + rts + +PageRight: + lda.b #$23 + sta $1DFC + + lda !vwf_current_test_suite_page + cmp TestSuiteNumPages + bcc .NoWrapAround + lda.b #$00 + +.NoWrapAround + inc + sta !vwf_current_test_suite_page + + jsr ClampCursor + jsr DrawCurrentTestSuitePage + jsr DrawCursor + rts + + +GetNumTestsOnPage: + rep #$30 + jsr GetPageTableOffset + sep #$20 + lda TestSuitePageInfos+8,x + sep #$10 + sta $00 + + rts + +ClampCursor: + jsr GetNumTestsOnPage + + lda !vwf_current_test_suite_row + cmp $00 + bcc .NoClamp + lda $00 + dec + sta !vwf_current_test_suite_row + +.NoClamp + rts + + +StartMessage: + rep #$30 + jsr GetPageTableOffset + + lda TestSuitePageInfos+5,x + sta $00 + lda TestSuitePageInfos+6,x + sta $01 + + lda !vwf_current_test_suite_row + and.w #$00FF + asl + tay + + lda [$00],y + xba + tax + xba + sep #$30 + + jsl VWF_DisplayAMessage + + rts + + +!vwf_test_suite_scanline_start #= 8 +!vwf_test_suite_scanline_stop #= 224-8 + +assert !vwf_test_suite_scanline_stop > !vwf_test_suite_scanline_start + +OpenTestSuite: + lda.b #$01 + sta !vwf_current_test_suite_page + lda.b #$00 + sta !vwf_current_test_suite_row + + ; Set up background window + rep #$30 + ldx.w #(!vwf_test_suite_scanline_start*2) + lda.w #$F808 +.SetUpWindow + sta remap_ram($04A0),x + inx #2 + cpx.w #(!vwf_test_suite_scanline_stop*2) + bne .SetUpWindow + sep #$30 + + jsr DrawCurrentTestSuitePage + + jsr DrawCursor + + rts + +CloseTestSuite: + lda.b #$00 + sta !vwf_current_test_suite_page + + jsr ClearTestSuiteScreen + + rts + +DrawCurrentTestSuitePage: + jsr DrawTestSuiteBackground + + rep #$30 + + jsr GetPageTableOffset + + ; Build MVN as RAM routine + lda.w #$7F54 ; $54 = MVN opcode, 7F = bank byte of $7F837B + sta $00 + lda TestSuitePageInfos+2,x ; Get source bank byte from TestSuitePageInfos + and.w #$00FF + ora.w #$6B00 ; $6B = RTL opcode + sta $02 + + + lda $7F837B + clc + adc.w #$7F837D + tay + + lda TestSuitePageInfos+3,x + pha + pha + + lda TestSuitePageInfos,x + tax + + pla + dec ; $7F837B does not count the terminating $FF. + clc + adc $7F837B + sta $7F837B + pla + + jsl $7E0000 + + sep #$30 + rts + +GetPageTableOffset: + lda !vwf_current_test_suite_page + and.w #$00FF + dec + asl #4 ; Multiply by 16 + tax + + rts + +DrawTestSuiteBackground: + %vwf_append_stripe_image(.BackgroundImage_Start, .BackgroundImage_End-.BackgroundImage_Start) + rts + +!vwf_test_suite_left = 1 +!vwf_test_suite_top = 37 +!vwf_test_suite_width = 29 +!vwf_test_suite_height = 26 +!vwf_test_suite_right #= !vwf_test_suite_left+!vwf_test_suite_width +!vwf_test_suite_bottom #= !vwf_test_suite_top+!vwf_test_suite_height + +.BackgroundImage_Start + for temp_current_y = !vwf_test_suite_top..!vwf_test_suite_bottom + %vwf_define_stripe_image_raw_line_rle(!vwf_test_suite_left, !temp_current_y, $1F, !vwf_test_suite_width) + endfor + %vwf_define_stripe_image_text_line(!vwf_test_suite_left+10, !vwf_test_suite_top+1, "Test Suite") + %vwf_define_stripe_image_raw_line_rle(!vwf_test_suite_left, !vwf_test_suite_top+2, $1C, !vwf_test_suite_width) + %vwf_stripe_image_end() +.BackgroundImage_End + +ClearTestSuiteScreen: + %vwf_append_stripe_image(.ClearScreen_Start, .ClearScreen_End-.ClearScreen_Start) + rts + +.ClearScreen_Start + for temp_current_y = !vwf_test_suite_top..!vwf_test_suite_bottom + %vwf_define_stripe_image_raw_line_rle(!vwf_test_suite_left, !temp_current_y, $79, !vwf_test_suite_width) + endfor + %vwf_stripe_image_end() +.ClearScreen_End + +!vwf_test_suite_cursor_x_pos #= !vwf_test_suite_left+1 +!vwf_test_suite_cursor_y_pos_start #= !vwf_test_suite_top+6 +!vwf_test_suite_cursor_tile_value #= (%00101101<<8)|$2E +!vwf_test_suite_empty_tile_value #= (%00111001<<8)|$1F + +DrawCursor: + rep #$30 + lda.w #!vwf_test_suite_cursor_tile_value + sta $02 + jsr DrawTileAtCursorPos + rts + +ClearCursor: + rep #$30 + lda.w #!vwf_test_suite_empty_tile_value + sta $02 + jsr DrawTileAtCursorPos + rts + +DrawTileAtCursorPos: + ;rep #$30 + lda $7F837B + tax + + lda !vwf_current_test_suite_row + and.w #$00FF + clc + adc.w #!vwf_test_suite_cursor_y_pos_start + and.w #%011111 + asl #5 + sta $00 + + lda !vwf_current_test_suite_row + and.w #$00FF + clc + adc.w #!vwf_test_suite_cursor_y_pos_start + and.w #%100000 + asl #6 + ora $00 + xba + sta $00 + + ora.w #%01010000|((!vwf_test_suite_cursor_x_pos&%100000)>>3)|((!vwf_test_suite_cursor_x_pos&%011111)<<8) + + sta $7F837D,x + inx #2 + + lda.w #$0100 + sta $7F837D,x + inx #2 + + lda $02 + sta $7F837D,x + inx #2 + + lda $7F837B + clc + adc.w #6 + sta $7F837B + + sep #$20 + lda.b #$FF + sta $7F837D,x + + sep #$10 + + rts + + +!vwf_test_suite_max_num_tests_per_page #= (!vwf_test_suite_height-7) +!vwf_test_suite_num_categories #= 0 +!vwf_test_suite_page_start_offset_x #= !vwf_test_suite_left+1 +!vwf_test_suite_page_start_offset_y #= !vwf_test_suite_top+4 + +macro vwf_register_test_suite_category(internal_name, display_name) + if defined("vwf_test_suite_category__id") + error "Test suite category """" was already defined." + endif + + !{vwf_test_suite_category_!{vwf_test_suite_num_categories}_internal_name} := + !{vwf_test_suite_category__id} #= !vwf_test_suite_num_categories + !{vwf_test_suite_category_!{vwf_test_suite_num_categories}_display_name} := "" + !{vwf_test_suite_category_!{vwf_test_suite_num_categories}_num_tests} #= 0 + + !vwf_test_suite_num_categories #= !vwf_test_suite_num_categories+1 +endmacro + +macro vwf_register_test(category_internal_name, test_name, message_number) + if not(defined("vwf_test_suite_category__id")) + error "Test suite category """" wasn't defined yet." + else + !temp_category_id #= !vwf_test_suite_category__id + !temp_test_id #= !{vwf_test_suite_category_!{temp_category_id}_num_tests} + + !{vwf_test_suite_test_!{temp_category_id}_!{temp_test_id}_display_name} := "" + !{vwf_test_suite_test_!{temp_category_id}_!{temp_test_id}_message_number} #= + + !{vwf_test_suite_category_!{temp_category_id}_num_tests} #= !{vwf_test_suite_category_!{temp_category_id}_num_tests}+1 + undef "temp_category_id" + undef "temp_test_id" + endif +endmacro + +macro vwf_generate_test_suite_tables() + TestSuitePageInfos: + + !temp_num_pages = 0 + + for temp_category_idx = 0..!vwf_test_suite_num_categories + !temp_num_tests_in_category #= !{vwf_test_suite_category_!{temp_category_idx}_num_tests} + !temp_num_pages_for_category #= ceil(!temp_num_tests_in_category/!vwf_test_suite_max_num_tests_per_page) + + for temp_page_idx = 0..!temp_num_pages_for_category + dl TestSuitePageImages!{temp_num_pages} + dw TestSuitePageImages!{temp_num_pages}End-TestSuitePageImages!{temp_num_pages} + dl TestSuiteTestPropertiesStart!{temp_num_pages} + db min(!temp_num_tests_in_category-(!temp_page_idx*!vwf_test_suite_max_num_tests_per_page),!vwf_test_suite_max_num_tests_per_page) + ; Padding + db $FF + db $FF + db $FF + db $FF + db $FF + db $FF + db $FF + + !temp_num_pages #= !temp_num_pages+1 + endfor + + undef "temp_num_tests_in_category" + undef "temp_num_pages_for_category" + endfor + + TestSuiteNumPages: + dw !temp_num_pages + + !temp_num_pages = 0 + + for temp_category_idx = 0..!vwf_test_suite_num_categories + !temp_num_tests_in_category #= !{vwf_test_suite_category_!{temp_category_idx}_num_tests} + !temp_num_pages_for_category #= ceil(!temp_num_tests_in_category/!vwf_test_suite_max_num_tests_per_page) + + for temp_page_idx = 0..!temp_num_pages_for_category + !temp_test_start_idx #= !temp_page_idx*!vwf_test_suite_max_num_tests_per_page + + TestSuiteTestPropertiesStart!{temp_num_pages}: + for temp_test_idx = 0..!vwf_test_suite_max_num_tests_per_page + !temp_test_id #= !temp_test_start_idx+!temp_test_idx + if !temp_test_idx >= !temp_num_tests_in_category-(!temp_page_idx*!vwf_test_suite_max_num_tests_per_page) + dw $FFFF + else + dw !{vwf_test_suite_test_!{temp_category_idx}_!{temp_test_id}_message_number} + endif + undef "temp_test_id" + endfor + + !temp_num_pages #= !temp_num_pages+1 + undef "temp_test_start_idx" + endfor + + undef "temp_num_tests_in_category" + undef "temp_num_pages_for_category" + endfor + + undef "temp_num_pages" +endmacro + +macro vwf_generate_test_suite_stripe_images() + !temp_num_pages = 0 + + for temp_category_idx = 0..!vwf_test_suite_num_categories + !temp_category_name := !{vwf_test_suite_category_!{temp_category_idx}_display_name} + !temp_num_tests_in_category #= !{vwf_test_suite_category_!{temp_category_idx}_num_tests} + !temp_num_pages_for_category #= ceil(!temp_num_tests_in_category/!vwf_test_suite_max_num_tests_per_page) + + for temp_page_idx = 0..!temp_num_pages_for_category + TestSuitePageImages!{temp_num_pages}: + !temp_test_start_idx #= !temp_page_idx*!vwf_test_suite_max_num_tests_per_page + !temp_page_idx_display #= !temp_page_idx+1 + + %vwf_define_stripe_image_text_line(!vwf_test_suite_page_start_offset_x, !vwf_test_suite_page_start_offset_y, "!temp_category_name (!temp_page_idx_display of !temp_num_pages_for_category)") + + for temp_test_idx = 0..min(!temp_num_tests_in_category-(!temp_page_idx*!vwf_test_suite_max_num_tests_per_page),!vwf_test_suite_max_num_tests_per_page) + !temp_test_id #= !temp_test_start_idx+!temp_test_idx + !temp_test_name := !{vwf_test_suite_test_!{temp_category_idx}_!{temp_test_id}_display_name} + %vwf_define_stripe_image_text_line(!vwf_test_suite_page_start_offset_x+2, !vwf_test_suite_page_start_offset_y+2+!temp_test_idx, "!temp_test_name") + undef "temp_test_id" + undef "temp_test_name" + endfor + + %vwf_stripe_image_end() + TestSuitePageImages!{temp_num_pages}End: + + !temp_num_pages #= !temp_num_pages+1 + undef "temp_test_start_idx" + undef "temp_page_idx_display" + endfor + + undef "temp_category_name" + undef "temp_num_tests_in_category" + undef "temp_num_pages_for_category" + endfor + + undef "temp_num_pages" +endmacro