From 5f5771e82345c62ed1852bbae2167b41396a0bed Mon Sep 17 00:00:00 2001 From: ry755 Date: Sat, 12 Feb 2022 20:42:37 -0800 Subject: [PATCH] fox32rom: Move text drawing to a generic routine Instead of having lots of duplicate code for drawing text to overlays and the background, move all of the actual drawing logic to a generic routine that can be used to draw text to *any* type of framebuffer. --- background.asm | 66 ++++++----------------------- draw_text.asm | 111 +++++++++++++++++++++++++++++++++++++++++++++++++ fox32rom.def | 32 +++++++------- main.asm | 22 +++++++--- overlay.asm | 75 +++++++-------------------------- 5 files changed, 173 insertions(+), 133 deletions(-) create mode 100644 draw_text.asm diff --git a/background.asm b/background.asm index 434816b..fb68cf2 100644 --- a/background.asm +++ b/background.asm @@ -81,67 +81,27 @@ draw_filled_rectangle_to_background_x_loop: ; outputs: ; none draw_font_tile_to_background: - push r0 - push r1 - push r2 push r5 push r6 + push r7 + push r8 + push r9 - ;movz.8 r0, r0 ; ensure the tile number is a single byte - - ; calculate pointer to the tile data - push r1 - push r2 - mov r1, 8 ; tile width - mov r2, 16 ; tile height - mul r1, r2 - mul r0, r1 - mul r0, 4 ; 4 bytes per pixel - add r0, font ; r0: pointer to tile data - pop r2 - pop r1 - - ; calculate pointer to the framebuffer - mul r2, 2560 ; y * 2560 (640 * 4 = 2560) - mul r1, 4 ; x * 4 - add r1, r2 ; y * 2560 + (x * 4) - add r1, BACKGROUND_FRAMEBUFFER ; r1: pointer to framebuffer - - mov r6, 16 ; y counter -draw_font_tile_to_background_y_loop: - mov r5, 8 ; x counter -draw_font_tile_to_background_x_loop: - mov r2, [r0] - cmp r2, 0xFF000000 - ifz jmp draw_font_tile_to_background_x_loop_background - ; drawing foreground pixel - cmp r3, 0x00000000 ; is the foreground color supposed to be transparent? - ifz jmp draw_font_tile_to_background_x_loop_end - mov [r1], r3 ; draw foreground color - jmp draw_font_tile_to_background_x_loop_end -draw_font_tile_to_background_x_loop_background: - ; drawing background pixel - cmp r4, 0x00000000 ; is the background color supposed to be transparent? - ifz jmp draw_font_tile_to_background_x_loop_end - mov [r1], r4 ; draw background color -draw_font_tile_to_background_x_loop_end: - add r0, 4 ; increment tile pointer - add r1, 4 ; increment framebuffer pointer - dec r5 - ifnz jmp draw_font_tile_to_background_x_loop ; loop if there are still more X pixels to draw - sub r1, 32 ; 8*4, return to the beginning of this line - add r1, 2560 ; 640*4, increment to the next line - dec r6 - ifnz jmp draw_font_tile_to_background_y_loop ; loop if there are still more Y pixels to draw + mov r5, standard_font_data + movz.16 r6, [standard_font_width] + movz.16 r7, [standard_font_height] + mov r8, BACKGROUND_FRAMEBUFFER + mov r9, 640 + call draw_font_tile_generic + pop r9 + pop r8 + pop r7 pop r6 pop r5 - pop r2 - pop r1 - pop r0 ret -; draw text on the background +; draw text to the background ; inputs: ; r0: pointer to null-terminated string ; r1: X coordinate diff --git a/draw_text.asm b/draw_text.asm new file mode 100644 index 0000000..d367774 --- /dev/null +++ b/draw_text.asm @@ -0,0 +1,111 @@ +; generic text drawing routines + +; draw a single font tile to a framebuffer +; inputs: +; r0: tile number +; r1: X coordinate +; r2: Y coordinate +; r3: foreground color +; r4: background color +; r5: pointer to font graphics +; r6: font width +; r7: font height +; r8: pointer to framebuffer +; r9: framebuffer width (pixels) +; outputs: +; none +draw_font_tile_generic: + push r0 + push r1 + push r2 + push r5 + push r6 + push r7 + push r8 + push r9 + + ;movz.8 r0, r0 ; ensure the tile number is a single byte + + ; calculate pointer to the tile data + push r6 + mul r6, r7 + mul r0, r6 + mul r0, 4 ; 4 bytes per pixel + add r0, r5 ; r0: pointer to tile data + pop r6 + + ; calculate pointer to the framebuffer + mul r9, 4 ; 4 bytes per pixel + mul r2, r9 ; y * width * 4 + mul r1, 4 ; x * 4 + add r1, r2 ; y * width * 4 + (x * 4) + add r1, r8 ; r1: pointer to framebuffer + + ; r8: font width in bytes + mov r8, r6 + mul r8, 4 + +draw_font_tile_generic_y_loop: + mov r5, r6 ; x counter +draw_font_tile_generic_x_loop: + mov r2, [r0] + cmp r2, 0xFF000000 + ifz jmp draw_font_tile_generic_x_loop_background + ; drawing foreground pixel + cmp r3, 0x00000000 ; is the foreground color supposed to be transparent? + ifz jmp draw_font_tile_generic_x_loop_end + mov [r1], r3 ; draw foreground color + jmp draw_font_tile_generic_x_loop_end +draw_font_tile_generic_x_loop_background: + ; drawing background pixel + cmp r4, 0x00000000 ; is the background color supposed to be transparent? + ifz jmp draw_font_tile_generic_x_loop_end + mov [r1], r4 ; draw background color +draw_font_tile_generic_x_loop_end: + add r0, 4 ; increment tile pointer + add r1, 4 ; increment framebuffer pointer + dec r5 + ifnz jmp draw_font_tile_generic_x_loop ; loop if there are still more X pixels to draw + sub r1, r8 ; return to the beginning of this line + add r1, r9 ; increment to the next line by adding the framebuffer width in bytes + dec r7 ; decrement height counter + ifnz jmp draw_font_tile_generic_y_loop ; loop if there are still more Y pixels to draw + + pop r9 + pop r8 + pop r7 + pop r6 + pop r5 + pop r2 + pop r1 + pop r0 + ret + +; draw text to a framebuffer +; inputs: +; r0: pointer to null-terminated string +; r1: X coordinate +; r2: Y coordinate +; r3: foreground color +; r4: background color +; r5: pointer to font graphics +; r6: font width +; r7: font height +; r8: pointer to framebuffer +; r9: framebuffer width +; outputs: +; r1: X coordinate of end of text +draw_str_generic: + push r0 + push r10 + mov r10, r0 +draw_str_generic_loop: + movz.8 r0, [r10] + call draw_font_tile_generic + inc r10 + add r1, r6 + cmp.8 [r10], 0x00 + ifnz jmp draw_str_generic_loop + pop r10 + pop r0 + ret diff --git a/fox32rom.def b/fox32rom.def index da0f186..1bb0d31 100644 --- a/fox32rom.def +++ b/fox32rom.def @@ -8,25 +8,29 @@ new_event: jmp [0xF004000C] wait_for_event: jmp [0xF0040010] get_next_event: jmp [0xF0040014] +; generic text drawing jump table +draw_str_generic: jmp [0xF0041000] +draw_font_tile_generic: jmp [0xF0041004] + ; background jump table entries -draw_str_to_background: jmp [0xF0041000] -draw_font_tile_to_background: jmp [0xF0041004] -fill_background: jmp [0xF0041008] +fill_background: jmp [0xF0042000] +draw_str_to_background: jmp [0xF0042004] +draw_font_tile_to_background: jmp [0xF0042008] ; overlay jump table entries -draw_str_to_overlay: jmp [0xF0042000] -draw_font_tile_to_overlay: jmp [0xF0042004] -fill_overlay: jmp [0xF0042008] -find_overlay_covering_position: jmp [0xF004200C] -check_if_overlay_covers_position: jmp [0xF0042010] -check_if_enabled_overlay_covers_position: jmp [0xF0042014] +fill_overlay: jmp [0xF0043000] +draw_str_to_overlay: jmp [0xF0043004] +draw_font_tile_to_overlay: jmp [0xF0043008] +find_overlay_covering_position: jmp [0xF004300C] +check_if_overlay_covers_position: jmp [0xF0043010] +check_if_enabled_overlay_covers_position: jmp [0xF0043014] ; menu bar jump table entries -menu_bar_click_event: jmp [0xF0043000] -clear_menu_bar: jmp [0xF0043004] -draw_menu_bar_root_items: jmp [0xF0043008] -draw_submenu_items: jmp [0xF004300C] -close_submenu: jmp [0xF0043010] +menu_bar_click_event: jmp [0xF0044000] +clear_menu_bar: jmp [0xF0044004] +draw_menu_bar_root_items: jmp [0xF0044008] +draw_submenu_items: jmp [0xF004400C] +close_submenu: jmp [0xF0044010] ; event types const MOUSE_CLICK_EVENT_TYPE: 0x00000000 diff --git a/main.asm b/main.asm index aca173a..87b71ff 100644 --- a/main.asm +++ b/main.asm @@ -173,6 +173,7 @@ get_rom_version: #include "background.asm" #include "boot.asm" #include "debug.asm" + #include "draw_text.asm" #include "event.asm" #include "memory.asm" #include "menu.asm" @@ -196,23 +197,28 @@ get_rom_version: data.32 wait_for_event data.32 get_next_event - ; background jump table + ; generic text drawing jump table org.pad 0xF0041000 + data.32 draw_str_generic + data.32 draw_font_tile_generic + + ; background jump table + org.pad 0xF0042000 + data.32 fill_background data.32 draw_str_to_background data.32 draw_font_tile_to_background - data.32 fill_background ; overlay jump table - org.pad 0xF0042000 + org.pad 0xF0043000 + data.32 fill_overlay data.32 draw_str_to_overlay data.32 draw_font_tile_to_overlay - data.32 fill_overlay data.32 find_overlay_covering_position data.32 check_if_overlay_covers_position data.32 check_if_enabled_overlay_covers_position ; menu bar jump table - org.pad 0xF0043000 + org.pad 0xF0044000 data.32 menu_bar_click_event data.32 clear_menu_bar data.32 draw_menu_bar_root_items @@ -220,7 +226,11 @@ get_rom_version: data.32 close_submenu org.pad 0xF004F000 -font: +standard_font_width: + data.16 8 +standard_font_height: + data.16 16 +standard_font_data: #include_bin "font/unifont-thin.raw" mouse_cursor: diff --git a/overlay.asm b/overlay.asm index c11e758..808ce04 100644 --- a/overlay.asm +++ b/overlay.asm @@ -103,77 +103,32 @@ draw_filled_rectangle_to_overlay_x_loop: ; outputs: ; none draw_font_tile_to_overlay: - push r0 - push r1 - push r2 push r5 push r6 push r7 + push r8 + push r9 - ;movz.8 r0, r0 ; ensure the tile number is a single byte - - ; calculate pointer to the tile data - push r1 - push r2 - mov r1, 8 ; tile width - mov r2, 16 ; tile height - mul r1, r2 - mul r0, r1 - mul r0, 4 ; 4 bytes per pixel - add r0, font ; r0: pointer to tile data - pop r2 - pop r1 - - ; calculate pointer to the framebuffer - mov r7, r5 ; r7: overlay number - or r7, 0x80000100 ; bitwise or the overlay number with the command to get the overlay size - in r6, r7 - and r6, 0x0000FFFF ; mask off the height, we only need the width - mul r6, 4 ; 4 bytes per pixel - mov r7, r6 ; r7: overlay width in bytes (width * 4) - mul r2, r7 ; y * width * 4 - mul r1, 4 ; x * 4 - add r1, r2 ; y * width * 4 + (x * 4) + mov r6, r5 + or r6, 0x80000100 ; bitwise or the overlay number with the command to get the overlay size or r5, 0x80000200 ; bitwise or the overlay number with the command to get the framebuffer pointer - in r6, r5 - add r1, r6 ; r1: pointer to framebuffer + in r8, r5 ; r8: overlay framebuffer poiner + in r9, r6 + and r9, 0x0000FFFF ; r9: overlay width - mov r6, 16 ; y counter -draw_font_tile_to_overlay_y_loop: - mov r5, 8 ; x counter -draw_font_tile_to_overlay_x_loop: - mov r2, [r0] - cmp r2, 0xFF000000 - ifz jmp draw_font_tile_to_overlay_x_loop_background - ; drawing foreground pixel - cmp r3, 0x00000000 ; is the foreground color supposed to be transparent? - ifz jmp draw_font_tile_to_overlay_x_loop_end - mov [r1], r3 ; draw foreground color - jmp draw_font_tile_to_overlay_x_loop_end -draw_font_tile_to_overlay_x_loop_background: - ; drawing background pixel - cmp r4, 0x00000000 ; is the background color supposed to be transparent? - ifz jmp draw_font_tile_to_overlay_x_loop_end - mov [r1], r4 ; draw background color -draw_font_tile_to_overlay_x_loop_end: - add r0, 4 ; increment tile pointer - add r1, 4 ; increment framebuffer pointer - dec r5 - ifnz jmp draw_font_tile_to_overlay_x_loop ; loop if there are still more X pixels to draw - sub r1, 32 ; 8*4, return to the beginning of this line - add r1, r7 ; increment to the next line by adding the overlay width in bytes - dec r6 - ifnz jmp draw_font_tile_to_overlay_y_loop ; loop if there are still more Y pixels to draw + mov r5, standard_font_data + movz.16 r6, [standard_font_width] + movz.16 r7, [standard_font_height] + call draw_font_tile_generic + pop r9 + pop r8 pop r7 pop r6 pop r5 - pop r2 - pop r1 - pop r0 ret -; draw text on an overlay +; draw text to an overlay ; inputs: ; r0: pointer to null-terminated string ; r1: X coordinate @@ -354,4 +309,4 @@ make_coordinates_relative_to_overlay: pop r3 pop r2 - ret \ No newline at end of file + ret