From dfd9ecf14a282c32dd227b3f60827102535b6d8e Mon Sep 17 00:00:00 2001 From: Ry Date: Sat, 15 Jun 2024 23:47:20 -0700 Subject: [PATCH] resource: Initial commit --- .gitignore | 1 + Makefile | 9 +++- demos/resource/resource.asm | 88 +++++++++++++++++++++++++++++++++ demos/resource/resource.rsf.asm | 50 +++++++++++++++++++ 4 files changed, 146 insertions(+), 2 deletions(-) create mode 100644 demos/resource/resource.asm create mode 100644 demos/resource/resource.rsf.asm diff --git a/.gitignore b/.gitignore index e46b930..0917335 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ *.fxf +*.rsf *.bin *.img demos/audio/audio.raw diff --git a/Makefile b/Makefile index a0e6d97..6bd2fb4 100644 --- a/Makefile +++ b/Makefile @@ -12,10 +12,11 @@ SRC = \ demos/robotfindskitten/rfk.asm \ demos/widget/widget.asm \ demos/window/window.asm \ + demos/resource/resource.asm \ demos/terminal/termio.asm \ cputest/cputest.asm -FXF = $(subst .asm,.fxf,$(SRC)) +FXF = $(subst .asm,.fxf,$(SRC)) demos/resource/resource.rsf BIN = cputest/cputest.bin @@ -29,11 +30,15 @@ demos/robotfindskitten/rfk.fxf: $(wildcard demos/robotfindskitten/*.asm) cputest/cputest.fxf: $(wildcard cputest/*.asm) demos/audio/audio.fxf: demos/audio/audio.raw - demos/audio/audio.raw: # create empty dummy file touch $@ +demos/resource/resource.fxf: demos/resource/resource.rsf.asm +demos/resource/resource.rsf: demos/resource/resource.rsf.asm + $(FOX32ASM) demos/resource/resource.rsf.asm demos/resource/resource.res.fxf + mv demos/resource/resource.res.fxf demos/resource/resource.rsf + cputest/cputest.bin: cputest/cputest-bin.asm $(wildcard cputest/*.asm) $(FOX32ASM) $< $@ diff --git a/demos/resource/resource.asm b/demos/resource/resource.asm new file mode 100644 index 0000000..c8c2f17 --- /dev/null +++ b/demos/resource/resource.asm @@ -0,0 +1,88 @@ +; widget demo, with a window created from an external .rsf resource file + + ; open and read resource.rsf into a buffer + ; exit if file not found + call get_current_disk_id + mov r1, r0 + mov r0, window_rsf_filename + mov r2, window_rsf_struct + call open + cmp r0, 0 + ifz call end_current_task + mov r0, window_rsf_struct + call get_size + push r0 + call allocate_memory ; TODO: error handling? + mov [window_rsf_buffer_ptr], r0 + pop r0 + mov r1, window_rsf_struct + mov r2, [window_rsf_buffer_ptr] + call read + + ; extract the resource data from the .rsf + mov r0, [window_rsf_buffer_ptr] + call get_res_in_fxf + mov r1, r0 + + ; create the window + mov r0, window_struct + ; r1 set above + call new_window_from_resource + + ; free the memory used by the .rsf as it is no longer needed + mov r0, [window_rsf_buffer_ptr] + call free_memory + + ; fill the window with white + mov r0, 0xFFFFFFFF + mov r1, window_struct + call fill_window + + ; redraw the widgets after filling the window + mov r0, window_struct + call draw_widgets_to_window + +event_loop: + mov r0, window_struct + call get_next_window_event + + ; did the user click somewhere in the window? + cmp r0, EVENT_TYPE_MOUSE_CLICK + ifz call mouse_click_event + + call yield_task + rjmp event_loop + +mouse_click_event: + push r0 + + ; check if we are attempting to drag or close the window + cmp r2, 16 + iflteq jmp drag_or_close_window + + ; check if we are clicking on a widget + mov r0, window_struct + call handle_widget_click + + pop r0 + ret + +drag_or_close_window: + cmp r1, 8 + iflteq jmp close_window + mov r0, window_struct + call start_dragging_window + pop r0 + ret +close_window: + mov r0, window_struct + call destroy_window + call end_current_task + +window_struct: data.fill 0, 40 +window_rsf_filename: data.strz "resource.rsf" +window_rsf_struct: data.fill 0, 32 +window_rsf_buffer_ptr: data.32 0 + + #include "../../../fox32rom/fox32rom.def" + #include "../../../fox32os/fox32os.def" diff --git a/demos/resource/resource.rsf.asm b/demos/resource/resource.rsf.asm new file mode 100644 index 0000000..b57adf7 --- /dev/null +++ b/demos/resource/resource.rsf.asm @@ -0,0 +1,50 @@ +; RES binaries can be "enclosed" in an FXF binary in order to handle relocations +; when a RES is enclosed in an FXF, it becomes a .rsf file instead of a standard .res file +; this .rsf.asm file should be assembled into a .res.fxf, then renamed to .rsf + +const WIDGET_TYPE_LABEL: 0x00000002 + + ; format: "RES"/"RSF" magic bytes, version, number of resource IDs + ; if "RES", no relocations; if "RSF", relocations applied + data.str "RSF" data.8 0 data.8 3 + + ; format: 3 character null-terminated ID, pointer to data, size + data.strz "WIN" data.32 win data.32 40 + data.strz "MNU" data.32 mnu data.32 32 ; REMEMBER TO CHANGE THIS SIZE!! + data.strz "WID" data.32 wid data.32 32 ; REMEMBER TO CHANGE THIS SIZE!! + +; WIN resource layout (40 bytes): +; data.fill 0, 32 - null-terminated window title +; data.16 width - width of this window +; data.16 height - height of this window, not including the title bar +; data.16 x_pos - X coordinate of this window (top left corner of title bar) +; data.16 y_pos - Y coordinate of this window (top left corner of title bar) +win: + data.str "RES demo" data.fill 0, 24 ; 32 byte window title + data.16 128 ; width + data.16 128 ; height + data.16 64 ; x_pos + data.16 64 ; y_pos + +mnu: + data.8 1 ; number of menus + data.32 menu_items_hello_list data.32 menu_items_hello_name ; pointer to menu list, pointer to menu name +menu_items_hello_name: + data.8 5 data.strz "Hello"; text length, text, null-terminator +menu_items_hello_list: + data.8 1 ; number of items + data.8 14 ; menu width (usually longest item + 2) + data.8 12 data.strz "Hello World!" ; text length, text, null-terminator + +wid: + data.32 0 ; next_ptr + data.32 0 ; id + data.32 WIDGET_TYPE_LABEL ; type + data.32 wid_text ; text_ptr + data.32 0xFF000000 ; foreground_color + data.32 0xFFFFFFFF ; background_color + data.16 0 ; reserved + data.16 0 ; reserved + data.16 16 ; x_pos + data.16 32 ; y_pos +wid_text: data.strz "Hello World!"