diff --git a/.gitignore b/.gitignore index cd531cf..168df4e 100644 --- a/.gitignore +++ b/.gitignore @@ -52,3 +52,4 @@ Module.symvers Mkfile.old dkms.conf +/hp48-sdl2 diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..8865b1e --- /dev/null +++ b/Makefile @@ -0,0 +1,85 @@ +# Makefile + +TARGETS = hp48-sdl2 + +PKG_CONFIG ?= pkg-config + +MAKEFLAGS +=-j$(NUM_CORES) -l$(NUM_CORES) + +DOTOS = src/ui.o \ + src/ui_sdl2.o \ + src/main.o + +cc-option = $(shell if $(CC) $(1) -c -x c /dev/null -o /dev/null > /dev/null 2>&1; \ + then echo $(1); fi) + +ifeq ($(FULL_WARNINGS), no) +EXTRA_WARNING_FLAGS := -Wno-unused-function \ + -Wno-redundant-decls \ + $(call cc-option,-Wno-maybe-uninitialized) \ + $(call cc-option,-Wno-discarded-qualifiers) \ + $(call cc-option,-Wno-uninitialized) \ + $(call cc-option,-Wno-ignored-qualifiers) +endif + +ifeq ($(FULL_WARNINGS), yes) +EXTRA_WARNING_FLAGS := -Wunused-function \ + -Wredundant-decls \ + -fsanitize-trap \ + $(call cc-option,-Wunused-variable) +endif + +override CFLAGS := -std=c11 \ + -Wall -Wextra -Wpedantic \ + -Wformat=2 -Wshadow \ + -Wwrite-strings -Wstrict-prototypes -Wold-style-definition \ + -Wnested-externs -Wmissing-include-dirs \ + -Wdouble-promotion \ + -Wno-sign-conversion \ + -Wno-unused-variable \ + -Wno-unused-parameter \ + -Wno-conversion \ + -Wno-format-nonliteral \ + $(call cc-option,-Wjump-misses-init) \ + $(call cc-option,-Wlogical-op) \ + $(call cc-option,-Wno-unknown-warning-option) \ + $(EXTRA_WARNING_FLAGS) \ + $(shell "$(PKG_CONFIG)" --cflags sdl2) \ + $(CFLAGS) + +override CPPFLAGS := -I./src/ -D_GNU_SOURCE=1 \ + -DVERSION_MAJOR=$(VERSION_MAJOR) \ + -DVERSION_MINOR=$(VERSION_MINOR) \ + -DPATCHLEVEL=$(PATCHLEVEL) \ + $(CPPFLAGS) + +LIBS = -lm $(shell "$(PKG_CONFIG)" --libs sdl2) + +# SDLCFLAGS = $(shell "$(PKG_CONFIG)" --cflags sdl2) +# SDLLIBS = $(shell "$(PKG_CONFIG)" --libs sdl2) + +# override CFLAGS += $(SDLCFLAGS) -DHAS_SDL2=1 +# LIBS += $(SDLLIBS) + +.PHONY: all clean clean-all pretty-code install mrproper + +all: $(TARGETS) + +hp48-sdl2: $(DOTOS) + +# Binaries +$(TARGETS): + $(CC) $^ -o $@ $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) $(LIBS) + +# Cleaning +clean: + rm -f src/*.o + +mrproper: clean + rm -f $(TARGETS) + +clean-all: mrproper + +# Formatting +pretty-code: + clang-format -i src/*.c src/*.h diff --git a/src/main.c b/src/main.c new file mode 100644 index 0000000..2ad3b16 --- /dev/null +++ b/src/main.c @@ -0,0 +1,18 @@ +#include + +#include "ui.h" + +int main( int argc, char** argv ) +{ + /* (G)UI */ + start_UI( argc, argv ); + + while (true) { + ui_update_LCD(); + ui_get_event(); + } + /* Never reached when not using please_exit */ + ui_stop(); + + return 0; +} diff --git a/src/ui.c b/src/ui.c new file mode 100644 index 0000000..eddfa28 --- /dev/null +++ b/src/ui.c @@ -0,0 +1,2340 @@ +#include +#include +#include + +//#include "config.h" +#include "ui.h" +#include "ui_inner.h" + +int last_annunc_state = -1; + +unsigned char lcd_nibbles_buffer[ DISP_ROWS ][ NIBS_PER_BUFFER_ROW ]; + +letter_t small_font[ 128 ] = { + {0, 0, 0 }, + {nl_gx_width, nl_gx_height, nl_gx_bits }, /* \x01 == \n gx */ + {comma_gx_width, comma_gx_height, comma_gx_bits }, /* \x02 == comma gx */ + {arrow_gx_width, arrow_gx_height, arrow_gx_bits }, /* \x03 == \-> gx */ + {equal_gx_width, equal_gx_height, equal_gx_bits }, /* \x04 == equal gx */ + {pi_gx_width, pi_gx_height, pi_gx_bits }, /* \x05 == pi gx */ + {arrow_width, arrow_height, arrow_bits }, /* \x06 == left arrow */ + {diff_width, diff_height, diff_bits }, /* \x07 == differential */ + {integral_width, integral_height, integral_bits }, /* \x08 == integral */ + {sigma_width, sigma_height, sigma_bits }, /* \x09 == sigma */ + {sqr_width, sqr_height, sqr_bits }, /* \x0a == sqr */ + {root_width, root_height, root_bits }, /* \x0b == root */ + {pow10_width, pow10_height, pow10_bits }, /* \x0c == pow10 */ + {exp_width, exp_height, exp_bits }, /* \x0d == exp */ + {prog_width, prog_height, prog_bits }, /* \x0e == << >> */ + {string_width, string_height, string_bits }, /* \x0f == " " */ + {nl_width, nl_height, nl_bits }, /* \x10 == New Line # 16 */ + {pi_width, pi_height, pi_bits }, /* \x11 == pi */ + {angle_width, angle_height, angle_bits }, /* \x12 == angle */ + {sqr_gx_width, sqr_gx_height, sqr_gx_bits }, /* \x13 == sqr gx */ + {root_gx_width, root_gx_height, root_gx_bits }, /* \x14 == root gx */ + {pow10_gx_width, pow10_gx_height, pow10_gx_bits }, /* \x15 == pow10 gx */ + {exp_gx_width, exp_gx_height, exp_gx_bits }, /* \x16 == exp gx */ + {parens_gx_width, parens_gx_height, parens_gx_bits }, /* \x17 == ( ) gx */ + {hash_gx_width, hash_gx_height, hash_gx_bits }, /* \x18 == # gx */ + {bracket_gx_width, bracket_gx_height, bracket_gx_bits }, /* \x19 == [] gx */ + {under_gx_width, under_gx_height, under_gx_bits }, /* \x1a == _ gx */ + {prog_gx_width, prog_gx_height, prog_gx_bits }, /* \x1b == << >> gx */ + {quote_gx_width, quote_gx_height, quote_gx_bits }, /* \x1c == " " gx */ + {curly_gx_width, curly_gx_height, curly_gx_bits }, /* \x1d == {} gx */ + {colon_gx_width, colon_gx_height, colon_gx_bits }, /* \x1e == :: gx */ + {angle_gx_width, angle_gx_height, angle_gx_bits }, /* \x1f == angle gx */ + {blank_width, blank_height, blank_bits }, /* # 32 */ + {0, 0, 0 }, + {0, 0, 0 }, + {hash_width, hash_height, hash_bits }, + {0, 0, 0 }, + {0, 0, 0 }, + {0, 0, 0 }, + {0, 0, 0 }, + {lbrace_width, lbrace_height, lbrace_bits }, + {rbrace_width, rbrace_height, rbrace_bits }, + {0, 0, 0 }, + {0, 0, 0 }, + {comma_width, comma_height, comma_bits }, + {0, 0, 0 }, + {0, 0, 0 }, + {slash_width, slash_height, slash_bits }, + {zero_width, zero_height, zero_bits }, /* # 48 */ + {one_width, one_height, one_bits }, + {two_width, two_height, two_bits }, + {three_width, three_height, three_bits }, + {four_width, four_height, four_bits }, + {five_width, five_height, five_bits }, + {six_width, six_height, six_bits }, + {seven_width, seven_height, seven_bits }, + {eight_width, eight_height, eight_bits }, + {nine_width, nine_height, nine_bits }, + {small_colon_width, small_colon_height, small_colon_bits}, + {0, 0, 0 }, + {0, 0, 0 }, + {equal_width, equal_height, equal_bits }, + {0, 0, 0 }, + {0, 0, 0 }, + {0, 0, 0 }, /* # 64 */ + {A_width, A_height, A_bits }, + {B_width, B_height, B_bits }, + {C_width, C_height, C_bits }, + {D_width, D_height, D_bits }, + {E_width, E_height, E_bits }, + {F_width, F_height, F_bits }, + {G_width, G_height, G_bits }, + {H_width, H_height, H_bits }, + {I_width, I_height, I_bits }, + {J_width, J_height, J_bits }, + {K_width, K_height, K_bits }, + {L_width, L_height, L_bits }, + {M_width, M_height, M_bits }, + {N_width, N_height, N_bits }, + {O_width, O_height, O_bits }, + {P_width, P_height, P_bits }, /* # 80 */ + {Q_width, Q_height, Q_bits }, + {R_width, R_height, R_bits }, + {S_width, S_height, S_bits }, + {T_width, T_height, T_bits }, + {U_width, U_height, U_bits }, + {V_width, V_height, V_bits }, + {W_width, W_height, W_bits }, + {X_width, X_height, X_bits }, + {Y_width, Y_height, Y_bits }, + {Z_width, Z_height, Z_bits }, + {lbracket_width, lbracket_height, lbracket_bits }, + {0, 0, 0 }, + {rbracket_width, rbracket_height, rbracket_bits }, + {0, 0, 0 }, + {under_width, under_height, under_bits }, + {0, 0, 0 }, /* # 96 */ + {0, 0, 0 }, /* a */ + {0, 0, 0 }, /* b */ + {0, 0, 0 }, /* c */ + {d_width, d_height, d_bits }, + {e_width, e_height, e_bits }, + {0, 0, 0 }, /* f */ + {0, 0, 0 }, /* g */ + {0, 0, 0 }, /* h */ + {i_width, i_height, i_bits }, + {0, 0, 0 }, /* j */ + {0, 0, 0 }, /* k */ + {0, 0, 0 }, /* l */ + {0, 0, 0 }, /* m */ + {0, 0, 0 }, /* n */ + {0, 0, 0 }, /* o */ + {p_width, p_height, p_bits }, + {0, 0, 0 }, /* q */ + {r_width, r_height, r_bits }, + {s_width, s_height, s_bits }, + {t_width, t_height, t_bits }, + {0, 0, 0 }, /* u */ + {v_width, v_height, v_bits }, + {w_width, w_height, w_bits }, + {0, 0, 0 }, /* x */ + {y_width, y_height, y_bits }, + {0, 0, 0 }, /* z */ + {lcurly_width, lcurly_height, lcurly_bits }, + {0, 0, 0 }, + {rcurly_width, rcurly_height, rcurly_bits }, + {0, 0, 0 }, + {0, 0, 0 }, /* 127 */ +}; + +letter_t big_font[ 128 ] = { + {0, 0, 0 }, + {0, 0, 0 }, + {0, 0, 0 }, + {0, 0, 0 }, + {0, 0, 0 }, + {0, 0, 0 }, + {0, 0, 0 }, + {0, 0, 0 }, + {0, 0, 0 }, + {0, 0, 0 }, + {0, 0, 0 }, + {0, 0, 0 }, + {0, 0, 0 }, + {0, 0, 0 }, + {0, 0, 0 }, + {0, 0, 0 }, + {0, 0, 0 }, /* # 16 */ + {0, 0, 0 }, + {0, 0, 0 }, + {0, 0, 0 }, + {0, 0, 0 }, + {0, 0, 0 }, + {0, 0, 0 }, + {0, 0, 0 }, + {0, 0, 0 }, + {0, 0, 0 }, + {0, 0, 0 }, + {0, 0, 0 }, + {0, 0, 0 }, + {0, 0, 0 }, + {0, 0, 0 }, + {0, 0, 0 }, + {0, 0, 0 }, /* # 32 */ + {0, 0, 0 }, + {0, 0, 0 }, + {0, 0, 0 }, + {0, 0, 0 }, + {0, 0, 0 }, + {0, 0, 0 }, + {0, 0, 0 }, + {0, 0, 0 }, + {0, 0, 0 }, + {0, 0, 0 }, + {0, 0, 0 }, + {0, 0, 0 }, + {0, 0, 0 }, + {big_font_dot_width, big_font_dot_height, big_font_dot_bits}, /* # 46 */ + {0, 0, 0 }, + {big_font_0_width, big_font_0_height, big_font_0_bits }, /* # 48 */ + {big_font_1_width, big_font_1_height, big_font_1_bits }, + {big_font_2_width, big_font_2_height, big_font_2_bits }, + {big_font_3_width, big_font_3_height, big_font_3_bits }, + {big_font_4_width, big_font_4_height, big_font_4_bits }, + {big_font_5_width, big_font_5_height, big_font_5_bits }, + {big_font_6_width, big_font_6_height, big_font_6_bits }, + {big_font_7_width, big_font_7_height, big_font_7_bits }, + {big_font_8_width, big_font_8_height, big_font_8_bits }, + {big_font_9_width, big_font_9_height, big_font_9_bits }, + {0, 0, 0 }, + {0, 0, 0 }, + {0, 0, 0 }, + {0, 0, 0 }, + {0, 0, 0 }, + {0, 0, 0 }, + {0, 0, 0 }, /* # 64 */ + {big_font_A_width, big_font_A_height, big_font_A_bits }, + {0, 0, 0 }, + {big_font_C_width, big_font_C_height, big_font_C_bits }, + {big_font_D_width, big_font_D_height, big_font_D_bits }, + {big_font_E_width, big_font_E_height, big_font_E_bits }, + {0, 0, 0 }, + {big_font_G_width, big_font_G_height, big_font_G_bits }, + {big_font_H_width, big_font_H_height, big_font_H_bits }, + {big_font_I_width, big_font_I_height, big_font_I_bits }, + {0, 0, 0 }, + {0, 0, 0 }, + {big_font_L_width, big_font_L_height, big_font_L_bits }, + {big_font_M_width, big_font_M_height, big_font_M_bits }, + {big_font_N_width, big_font_N_height, big_font_N_bits }, + {big_font_O_width, big_font_O_height, big_font_O_bits }, + {big_font_P_width, big_font_P_height, big_font_P_bits }, /* # 80 */ + {0, 0, 0 }, + {big_font_R_width, big_font_R_height, big_font_R_bits }, + {big_font_S_width, big_font_S_height, big_font_S_bits }, + {big_font_T_width, big_font_T_height, big_font_T_bits }, + {0, 0, 0 }, + {big_font_V_width, big_font_V_height, big_font_V_bits }, + {0, 0, 0 }, + {big_font_X_width, big_font_X_height, big_font_X_bits }, + {0, 0, 0 }, + {0, 0, 0 }, + {0, 0, 0 }, + {0, 0, 0 }, + {0, 0, 0 }, + {0, 0, 0 }, + {0, 0, 0 }, + {0, 0, 0 }, /* # 96 */ + {0, 0, 0 }, /* a */ + {0, 0, 0 }, /* b */ + {0, 0, 0 }, /* c */ + {0, 0, 0 }, /* d */ + {0, 0, 0 }, /* e */ + {0, 0, 0 }, /* f */ + {0, 0, 0 }, /* g */ + {0, 0, 0 }, /* h */ + {0, 0, 0 }, /* i */ + {0, 0, 0 }, /* j */ + {0, 0, 0 }, /* k */ + {0, 0, 0 }, /* l */ + {0, 0, 0 }, /* m */ + {0, 0, 0 }, /* n */ + {0, 0, 0 }, /* o */ + {0, 0, 0 }, /* p */ + {0, 0, 0 }, /* q */ + {0, 0, 0 }, /* r */ + {0, 0, 0 }, /* s */ + {0, 0, 0 }, /* t */ + {0, 0, 0 }, /* u */ + {0, 0, 0 }, /* v */ + {0, 0, 0 }, /* w */ + {0, 0, 0 }, /* x */ + {0, 0, 0 }, /* y */ + {0, 0, 0 }, /* z */ + {0, 0, 0 }, + {0, 0, 0 }, + {0, 0, 0 }, + {0, 0, 0 }, + {0, 0, 0 } +}; + +color_t colors_sx[ NB_COLORS ] = { + { + /* #ffffff */ + .name = "white", + .r = 255, + .g = 255, + .b = 255, + .a = 255, + .mono_rgb = 255, + .gray_rgb = 255, + }, + { + /* #ffa600 */ + .name = "left", + .r = 255, + .g = 166, + .b = 0, + .a = 255, + .mono_rgb = 255, + .gray_rgb = 230, + }, + { + /* #00d2ff */ + .name = "right", + .r = 0, + .g = 210, + .b = 255, + .a = 255, + .mono_rgb = 255, + .gray_rgb = 169, + }, + { + /* #6d5d5d */ + .name = "but_top", + .r = 109, + .g = 93, + .b = 93, + .a = 255, + .mono_rgb = 0, + .gray_rgb = 91, + }, + { + /* #5a4d4d */ + .name = "button", + .r = 90, + .g = 77, + .b = 77, + .a = 255, + .mono_rgb = 0, + .gray_rgb = 81, + }, + { + /* #4c4141 */ + .name = "but_bot", + .r = 76, + .g = 65, + .b = 65, + .a = 255, + .mono_rgb = 0, + .gray_rgb = 69, + }, + { + /* #cadd5c */ + .name = "lcd_col", + .r = 202, + .g = 221, + .b = 92, + .a = 255, + .mono_rgb = 255, + .gray_rgb = 205, + }, + { + /* #000080 */ + .name = "pix_col", + .r = 0, + .g = 0, + .b = 128, + .a = 255, + .mono_rgb = 0, + .gray_rgb = 20, + }, + { + /* #6d4e4e */ + .name = "pad_top", + .r = 109, + .g = 78, + .b = 78, + .a = 255, + .mono_rgb = 0, + .gray_rgb = 88, + }, + { + /* #5a4040 */ + .name = "pad", + .r = 90, + .g = 64, + .b = 64, + .a = 255, + .mono_rgb = 0, + .gray_rgb = 73, + }, + { + /* #4c3636 */ + .name = "pad_bot", + .r = 76, + .g = 54, + .b = 54, + .a = 255, + .mono_rgb = 0, + .gray_rgb = 60, + }, + { + /* #9b7654 */ + .name = "disp_pad_top", + .r = 155, + .g = 118, + .b = 84, + .a = 255, + .mono_rgb = 0, + .gray_rgb = 124, + }, + { + /* #7c5e43 */ + .name = "disp_pad", + .r = 124, + .g = 94, + .b = 67, + .a = 255, + .mono_rgb = 0, + .gray_rgb = 99, + }, + { + /* #644b35 */ + .name = "disp_pad_bot", + .r = 100, + .g = 75, + .b = 53, + .a = 255, + .mono_rgb = 0, + .gray_rgb = 79, + }, + { + /* #cca96b */ + .name = "logo", + .r = 204, + .g = 169, + .b = 107, + .a = 255, + .mono_rgb = 255, + .gray_rgb = 172, + }, + { + /* #404040 */ + .name = "logo_back", + .r = 64, + .g = 64, + .b = 64, + .a = 255, + .mono_rgb = 0, + .gray_rgb = 65, + }, + { + /* #cab890 */ + .name = "label", + .r = 202, + .g = 184, + .b = 144, + .a = 255, + .mono_rgb = 255, + .gray_rgb = 185, + }, + { + /* #000000 */ + .name = "frame", + .r = 0, + .g = 0, + .b = 0, + .a = 255, + .mono_rgb = 255, + .gray_rgb = 0, + }, + { + /* #3c2a2a */ + .name = "underlay", + .r = 60, + .g = 42, + .b = 42, + .a = 255, + .mono_rgb = 0, + .gray_rgb = 48, + }, + { + /* #000000 */ + .name = "black", + .r = 0, + .g = 0, + .b = 0, + .a = 255, + .mono_rgb = 0, + .gray_rgb = 0, + }, +}; + +color_t colors_gx[ NB_COLORS ] = { + { + /* #FFFFFF */ + .name = "white", + .r = 255, + .g = 255, + .b = 255, + .a = 255, + .mono_rgb = 255, + .gray_rgb = 255, + }, + { + /* #ffbaff */ + .name = "left", + .r = 255, + .g = 186, + .b = 255, + .a = 255, + .mono_rgb = 255, + .gray_rgb = 220, + }, + { + /* #00ffcc */ + .name = "right", + .r = 0, + .g = 255, + .b = 204, + .a = 255, + .mono_rgb = 255, + .gray_rgb = 169, + }, + { + /* #646464 */ + .name = "but_top", + .r = 104, + .g = 104, + .b = 104, + .a = 255, + .mono_rgb = 0, + .gray_rgb = 104, + }, + { + /* #585858 */ + .name = "button", + .r = 88, + .g = 88, + .b = 88, + .a = 255, + .mono_rgb = 0, + .gray_rgb = 88, + }, + { + /* #4a4a4a */ + .name = "but_bot", + .r = 74, + .g = 74, + .b = 74, + .a = 255, + .mono_rgb = 0, + .gray_rgb = 74, + }, + { + /* #cadd5c */ + .name = "lcd_col", + .r = 202, + .g = 221, + .b = 92, + .a = 255, + .mono_rgb = 255, + .gray_rgb = 205, + }, + { + /* #000080 */ + .name = "pix_col", + .r = 0, + .g = 0, + .b = 128, + .a = 255, + .mono_rgb = 0, + .gray_rgb = 20, + }, + { + /* #585858 */ + .name = "pad_top", + .r = 88, + .g = 88, + .b = 88, + .a = 255, + .mono_rgb = 0, + .gray_rgb = 88, + }, + { + /* #4a4a4a */ + .name = "pad", + .r = 74, + .g = 74, + .b = 74, + .a = 255, + .mono_rgb = 0, + .gray_rgb = 74, + }, + { + /* #404040 */ + .name = "pad_bot", + .r = 64, + .g = 64, + .b = 64, + .a = 255, + .mono_rgb = 0, + .gray_rgb = 64, + }, + { + /* #808080 */ + .name = "disp_pad_top", + .r = 128, + .g = 128, + .b = 138, + .a = 255, + .mono_rgb = 0, + .gray_rgb = 128, + }, + { + /* #68686E */ + .name = "disp_pad", + .r = 104, + .g = 104, + .b = 110, + .a = 255, + .mono_rgb = 0, + .gray_rgb = 104, + }, + { + /* #54545a */ + .name = "disp_pad_bot", + .r = 84, + .g = 84, + .b = 90, + .a = 255, + .mono_rgb = 0, + .gray_rgb = 84, + }, + { + /* #b0b0b8 */ + .name = "logo", + .r = 176, + .g = 176, + .b = 184, + .a = 255, + .mono_rgb = 255, + .gray_rgb = 176, + }, + { + /* #68686e */ + .name = "logo_back", + .r = 104, + .g = 104, + .b = 110, + .a = 255, + .mono_rgb = 0, + .gray_rgb = 104, + }, + { + /* #f0f0f0 */ + .name = "label", + .r = 240, + .g = 240, + .b = 240, + .a = 255, + .mono_rgb = 255, + .gray_rgb = 240, + }, + { + /* #000000 */ + .name = "frame", + .r = 0, + .g = 0, + .b = 0, + .a = 255, + .mono_rgb = 255, + .gray_rgb = 0, + }, + { + /* #68686e */ + .name = "underlay", + .r = 104, + .g = 104, + .b = 110, + .a = 255, + .mono_rgb = 0, + .gray_rgb = 104, + }, + { + /* #000000 */ + .name = "black", + .r = 0, + .g = 0, + .b = 0, + .a = 255, + .mono_rgb = 0, + .gray_rgb = 0, + }, +}; + +button_t buttons_sx[ NB_KEYS ] = { + {.name = "A", + .x = 0, + .y = 0, + .w = 36, + .h = 23, + .lc = WHITE, + .label = 0, + .font_size = 0, + .lw = menu_label_width, + .lh = menu_label_height, + .lb = menu_label_bitmap, + .letter = "A", + .left = 0, + .is_menu = 0, + .right = 0, + .sub = 0 }, + {.name = "B", + .x = 50, + .y = 0, + .w = 36, + .h = 23, + .lc = WHITE, + .label = 0, + .font_size = 0, + .lw = menu_label_width, + .lh = menu_label_height, + .lb = menu_label_bitmap, + .letter = "B", + .left = 0, + .is_menu = 0, + .right = 0, + .sub = 0 }, + {.name = "C", + .x = 100, + .y = 0, + .w = 36, + .h = 23, + .lc = WHITE, + .label = 0, + .font_size = 0, + .lw = menu_label_width, + .lh = menu_label_height, + .lb = menu_label_bitmap, + .letter = "C", + .left = 0, + .is_menu = 0, + .right = 0, + .sub = 0 }, + {.name = "D", + .x = 150, + .y = 0, + .w = 36, + .h = 23, + .lc = WHITE, + .label = 0, + .font_size = 0, + .lw = menu_label_width, + .lh = menu_label_height, + .lb = menu_label_bitmap, + .letter = "D", + .left = 0, + .is_menu = 0, + .right = 0, + .sub = 0 }, + {.name = "E", + .x = 200, + .y = 0, + .w = 36, + .h = 23, + .lc = WHITE, + .label = 0, + .font_size = 0, + .lw = menu_label_width, + .lh = menu_label_height, + .lb = menu_label_bitmap, + .letter = "E", + .left = 0, + .is_menu = 0, + .right = 0, + .sub = 0 }, + {.name = "F", + .x = 250, + .y = 0, + .w = 36, + .h = 23, + .lc = WHITE, + .label = 0, + .font_size = 0, + .lw = menu_label_width, + .lh = menu_label_height, + .lb = menu_label_bitmap, + .letter = "F", + .left = 0, + .is_menu = 0, + .right = 0, + .sub = 0 }, + + {.name = "MTH", + .x = 0, + .y = 50, + .w = 36, + .h = 26, + .lc = WHITE, + .label = "MTH", + .font_size = 0, + .lw = 0, + .lh = 0, + .lb = 0, + .letter = "G", + .left = "PRINT", + .is_menu = 1, + .right = 0, + .sub = 0 }, + {.name = "PRG", + .x = 50, + .y = 50, + .w = 36, + .h = 26, + .lc = WHITE, + .label = "PRG", + .font_size = 0, + .lw = 0, + .lh = 0, + .lb = 0, + .letter = "H", + .left = "I/O", + .is_menu = 1, + .right = 0, + .sub = 0 }, + {.name = "CST", + .x = 100, + .y = 50, + .w = 36, + .h = 26, + .lc = WHITE, + .label = "CST", + .font_size = 0, + .lw = 0, + .lh = 0, + .lb = 0, + .letter = "I", + .left = "MODES", + .is_menu = 1, + .right = 0, + .sub = 0 }, + {.name = "VAR", + .x = 150, + .y = 50, + .w = 36, + .h = 26, + .lc = WHITE, + .label = "VAR", + .font_size = 0, + .lw = 0, + .lh = 0, + .lb = 0, + .letter = "J", + .left = "MEMORY", + .is_menu = 1, + .right = 0, + .sub = 0 }, + {.name = "UP", + .x = 200, + .y = 50, + .w = 36, + .h = 26, + .lc = WHITE, + .label = 0, + .font_size = 0, + .lw = up_width, + .lh = up_height, + .lb = up_bitmap, + .letter = "K", + .left = "LIBRARY", + .is_menu = 1, + .right = 0, + .sub = 0 }, + {.name = "NXT", + .x = 250, + .y = 50, + .w = 36, + .h = 26, + .lc = WHITE, + .label = "NXT", + .font_size = 0, + .lw = 0, + .lh = 0, + .lb = 0, + .letter = "L", + .left = "PREV", + .is_menu = 0, + .right = 0, + .sub = 0 }, + + {.name = "QUOTE", + .x = 0, + .y = 100, + .w = 36, + .h = 26, + .lc = WHITE, + .label = 0, + .font_size = 0, + .lw = quote_width, + .lh = quote_height, + .lb = quote_bitmap, + .letter = "M", + .left = "UP", + .is_menu = 0, + .right = "HOME", + .sub = 0 }, + {.name = "STO", + .x = 50, + .y = 100, + .w = 36, + .h = 26, + .lc = WHITE, + .label = "STO", + .font_size = 0, + .lw = 0, + .lh = 0, + .lb = 0, + .letter = "N", + .left = "DEF", + .is_menu = 0, + .right = "RCL", + .sub = 0 }, + {.name = "EVAL", + .x = 100, + .y = 100, + .w = 36, + .h = 26, + .lc = WHITE, + .label = "EVAL", + .font_size = 0, + .lw = 0, + .lh = 0, + .lb = 0, + .letter = "O", + .left = "\x80Q", + .is_menu = 0, + .right = "\x80NUM", + .sub = 0 }, + {.name = "LEFT", + .x = 150, + .y = 100, + .w = 36, + .h = 26, + .lc = WHITE, + .label = 0, + .font_size = 0, + .lw = left_width, + .lh = left_height, + .lb = left_bitmap, + .letter = "P", + .left = "GRAPH", + .is_menu = 0, + .right = 0, + .sub = 0 }, + {.name = "DOWN", + .x = 200, + .y = 100, + .w = 36, + .h = 26, + .lc = WHITE, + .label = 0, + .font_size = 0, + .lw = down_width, + .lh = down_height, + .lb = down_bitmap, + .letter = "Q", + .left = "REVIEW", + .is_menu = 0, + .right = 0, + .sub = 0 }, + {.name = "RIGHT", + .x = 250, + .y = 100, + .w = 36, + .h = 26, + .lc = WHITE, + .label = 0, + .font_size = 0, + .lw = right_width, + .lh = right_height, + .lb = right_bitmap, + .letter = "R", + .left = "SWAP", + .is_menu = 0, + .right = 0, + .sub = 0 }, + + {.name = "SIN", + .x = 0, + .y = 150, + .w = 36, + .h = 26, + .lc = WHITE, + .label = "SIN", + .font_size = 0, + .lw = 0, + .lh = 0, + .lb = 0, + .letter = "S", + .left = "ASIN", + .is_menu = 0, + .right = "\x07", + .sub = 0 }, + {.name = "COS", + .x = 50, + .y = 150, + .w = 36, + .h = 26, + .lc = WHITE, + .label = "COS", + .font_size = 0, + .lw = 0, + .lh = 0, + .lb = 0, + .letter = "T", + .left = "ACOS", + .is_menu = 0, + .right = "\x08", + .sub = 0 }, + {.name = "TAN", + .x = 100, + .y = 150, + .w = 36, + .h = 26, + .lc = WHITE, + .label = "TAN", + .font_size = 0, + .lw = 0, + .lh = 0, + .lb = 0, + .letter = "U", + .left = "ATAN", + .is_menu = 0, + .right = "\x09", + .sub = 0 }, + {.name = "SQRT", + .x = 150, + .y = 150, + .w = 36, + .h = 26, + .lc = WHITE, + .label = 0, + .font_size = 0, + .lw = sqrt_width, + .lh = sqrt_height, + .lb = sqrt_bitmap, + .letter = "V", + .left = "\x0a", + .is_menu = 0, + .right = "\x0b", + .sub = 0 }, + {.name = "POWER", + .x = 200, + .y = 150, + .w = 36, + .h = 26, + .lc = WHITE, + .label = 0, + .font_size = 0, + .lw = power_width, + .lh = power_height, + .lb = power_bitmap, + .letter = "W", + .left = "\x0c", + .is_menu = 0, + .right = "LOG", + .sub = 0 }, + {.name = "INV", + .x = 250, + .y = 150, + .w = 36, + .h = 26, + .lc = WHITE, + .label = 0, + .font_size = 0, + .lw = inv_width, + .lh = inv_height, + .lb = inv_bitmap, + .letter = "X", + .left = "\x0d", + .is_menu = 0, + .right = "LN", + .sub = 0 }, + + {.name = "ENTER", + .x = 0, + .y = 200, + .w = 86, + .h = 26, + .lc = WHITE, + .label = "ENTER", + .font_size = 2, + .lw = 0, + .lh = 0, + .lb = 0, + .letter = 0, + .left = "EQUATION", + .is_menu = 0, + .right = "MATRIX", + .sub = 0 }, + {.name = "NEG", + .x = 100, + .y = 200, + .w = 36, + .h = 26, + .lc = WHITE, + .label = 0, + .font_size = 0, + .lw = neg_width, + .lh = neg_height, + .lb = neg_bitmap, + .letter = "Y", + .left = "EDIT", + .is_menu = 0, + .right = "VISIT", + .sub = 0 }, + {.name = "EEX", + .x = 150, + .y = 200, + .w = 36, + .h = 26, + .lc = WHITE, + .label = "EEX", + .font_size = 0, + .lw = 0, + .lh = 0, + .lb = 0, + .letter = "Z", + .left = "2D", + .is_menu = 0, + .right = "3D", + .sub = 0 }, + {.name = "DEL", + .x = 200, + .y = 200, + .w = 36, + .h = 26, + .lc = WHITE, + .label = "DEL", + .font_size = 0, + .lw = 0, + .lh = 0, + .lb = 0, + .letter = 0, + .left = "PURGE", + .is_menu = 0, + .right = 0, + .sub = 0 }, + {.name = "BS", + .x = 250, + .y = 200, + .w = 36, + .h = 26, + .lc = WHITE, + .label = 0, + .font_size = 0, + .lw = bs_width, + .lh = bs_height, + .lb = bs_bitmap, + .letter = 0, + .left = "DROP", + .is_menu = 0, + .right = "CLR", + .sub = 0 }, + + {.name = "ALPHA", + .x = 0, + .y = 250, + .w = 36, + .h = 26, + .lc = WHITE, + .label = 0, + .font_size = 0, + .lw = alpha_width, + .lh = alpha_height, + .lb = alpha_bitmap, + .letter = 0, + .left = "USR", + .is_menu = 0, + .right = "ENTRY", + .sub = 0 }, + {.name = "7", + .x = 60, + .y = 250, + .w = 46, + .h = 26, + .lc = WHITE, + .label = "7", + .font_size = 1, + .lw = 0, + .lh = 0, + .lb = 0, + .letter = 0, + .left = "SOLVE", + .is_menu = 1, + .right = 0, + .sub = 0 }, + {.name = "8", + .x = 120, + .y = 250, + .w = 46, + .h = 26, + .lc = WHITE, + .label = "8", + .font_size = 1, + .lw = 0, + .lh = 0, + .lb = 0, + .letter = 0, + .left = "PLOT", + .is_menu = 1, + .right = 0, + .sub = 0 }, + {.name = "9", + .x = 180, + .y = 250, + .w = 46, + .h = 26, + .lc = WHITE, + .label = "9", + .font_size = 1, + .lw = 0, + .lh = 0, + .lb = 0, + .letter = 0, + .left = "ALGEBRA", + .is_menu = 1, + .right = 0, + .sub = 0 }, + {.name = "DIV", + .x = 240, + .y = 250, + .w = 46, + .h = 26, + .lc = WHITE, + .label = 0, + .font_size = 0, + .lw = div_width, + .lh = div_height, + .lb = div_bitmap, + .letter = 0, + .left = "( )", + .is_menu = 0, + .right = "#", + .sub = 0 }, + + {.name = "SHL", + .x = 0, + .y = 300, + .w = 36, + .h = 26, + .lc = LEFT, + .label = 0, + .font_size = 0, + .lw = shl_width, + .lh = shl_height, + .lb = shl_bitmap, + .letter = 0, + .left = 0, + .is_menu = 0, + .right = 0, + .sub = 0 }, + {.name = "4", + .x = 60, + .y = 300, + .w = 46, + .h = 26, + .lc = WHITE, + .label = "4", + .font_size = 1, + .lw = 0, + .lh = 0, + .lb = 0, + .letter = 0, + .left = "TIME", + .is_menu = 1, + .right = 0, + .sub = 0 }, + {.name = "5", + .x = 120, + .y = 300, + .w = 46, + .h = 26, + .lc = WHITE, + .label = "5", + .font_size = 1, + .lw = 0, + .lh = 0, + .lb = 0, + .letter = 0, + .left = "STAT", + .is_menu = 1, + .right = 0, + .sub = 0 }, + {.name = "6", + .x = 180, + .y = 300, + .w = 46, + .h = 26, + .lc = WHITE, + .label = "6", + .font_size = 1, + .lw = 0, + .lh = 0, + .lb = 0, + .letter = 0, + .left = "UNITS", + .is_menu = 1, + .right = 0, + .sub = 0 }, + {.name = "MUL", + .x = 240, + .y = 300, + .w = 46, + .h = 26, + .lc = WHITE, + .label = 0, + .font_size = 0, + .lw = mul_width, + .lh = mul_height, + .lb = mul_bitmap, + .letter = 0, + .left = "[ ]", + .is_menu = 0, + .right = "_", + .sub = 0 }, + + {.name = "SHR", + .x = 0, + .y = 350, + .w = 36, + .h = 26, + .lc = RIGHT, + .label = 0, + .font_size = 0, + .lw = shr_width, + .lh = shr_height, + .lb = shr_bitmap, + .letter = 0, + .left = 0, + .is_menu = 0, + .right = 0, + .sub = 0 }, + {.name = "1", + .x = 60, + .y = 350, + .w = 46, + .h = 26, + .lc = WHITE, + .label = "1", + .font_size = 1, + .lw = 0, + .lh = 0, + .lb = 0, + .letter = 0, + .left = "RAD", + .is_menu = 0, + .right = "POLAR", + .sub = 0 }, + {.name = "2", + .x = 120, + .y = 350, + .w = 46, + .h = 26, + .lc = WHITE, + .label = "2", + .font_size = 1, + .lw = 0, + .lh = 0, + .lb = 0, + .letter = 0, + .left = "STACK", + .is_menu = 0, + .right = "ARG", + .sub = 0 }, + {.name = "3", + .x = 180, + .y = 350, + .w = 46, + .h = 26, + .lc = WHITE, + .label = "3", + .font_size = 1, + .lw = 0, + .lh = 0, + .lb = 0, + .letter = 0, + .left = "CMD", + .is_menu = 0, + .right = "MENU", + .sub = 0 }, + {.name = "MINUS", + .x = 240, + .y = 350, + .w = 46, + .h = 26, + .lc = WHITE, + .label = 0, + .font_size = 0, + .lw = minus_width, + .lh = minus_height, + .lb = minus_bitmap, + .letter = 0, + .left = "\x0e", + .is_menu = 0, + .right = "\x0f", + .sub = 0 }, + + {.name = "ON", + .x = 0, + .y = 400, + .w = 36, + .h = 26, + .lc = WHITE, + .label = "ON", + .font_size = 0, + .lw = 0, + .lh = 0, + .lb = 0, + .letter = 0, + .left = "CONT", + .is_menu = 0, + .right = "OFF", + .sub = "ATTN"}, + {.name = "0", + .x = 60, + .y = 400, + .w = 46, + .h = 26, + .lc = WHITE, + .label = "0", + .font_size = 1, + .lw = 0, + .lh = 0, + .lb = 0, + .letter = 0, + .left = "= ", + .is_menu = 0, + .right = " \x80", + .sub = 0 }, + {.name = "PERIOD", + .x = 120, + .y = 400, + .w = 46, + .h = 26, + .lc = WHITE, + .label = ".", + .font_size = 1, + .lw = 0, + .lh = 0, + .lb = 0, + .letter = 0, + .left = ",", + .is_menu = 0, + .right = " \x10", + .sub = 0 }, + {.name = "SPC", + .x = 180, + .y = 400, + .w = 46, + .h = 26, + .lc = WHITE, + .label = "SPC", + .font_size = 0, + .lw = 0, + .lh = 0, + .lb = 0, + .letter = 0, + .left = "\x11 ", + .is_menu = 0, + .right = " \x12", + .sub = 0 }, + {.name = "PLUS", + .x = 240, + .y = 400, + .w = 46, + .h = 26, + .lc = WHITE, + .label = 0, + .font_size = 0, + .lw = plus_width, + .lh = plus_height, + .lb = plus_bitmap, + .letter = 0, + .left = "{ }", + .is_menu = 0, + .right = ": :", + .sub = 0 }, +}; + +button_t buttons_gx[ NB_KEYS ] = { + {.name = "A", + .x = 0, + .y = 0, + .w = 36, + .h = 23, + .lc = WHITE, + .label = 0, + .font_size = 0, + .lw = menu_label_width, + .lh = menu_label_height, + .lb = menu_label_bitmap, + .letter = "A", + .left = 0, + .is_menu = 0, + .right = 0, + .sub = 0 }, + {.name = "B", + .x = 50, + .y = 0, + .w = 36, + .h = 23, + .lc = WHITE, + .label = 0, + .font_size = 0, + .lw = menu_label_width, + .lh = menu_label_height, + .lb = menu_label_bitmap, + .letter = "B", + .left = 0, + .is_menu = 0, + .right = 0, + .sub = 0 }, + {.name = "C", + .x = 100, + .y = 0, + .w = 36, + .h = 23, + .lc = WHITE, + .label = 0, + .font_size = 0, + .lw = menu_label_width, + .lh = menu_label_height, + .lb = menu_label_bitmap, + .letter = "C", + .left = 0, + .is_menu = 0, + .right = 0, + .sub = 0 }, + {.name = "D", + .x = 150, + .y = 0, + .w = 36, + .h = 23, + .lc = WHITE, + .label = 0, + .font_size = 0, + .lw = menu_label_width, + .lh = menu_label_height, + .lb = menu_label_bitmap, + .letter = "D", + .left = 0, + .is_menu = 0, + .right = 0, + .sub = 0 }, + {.name = "E", + .x = 200, + .y = 0, + .w = 36, + .h = 23, + .lc = WHITE, + .label = 0, + .font_size = 0, + .lw = menu_label_width, + .lh = menu_label_height, + .lb = menu_label_bitmap, + .letter = "E", + .left = 0, + .is_menu = 0, + .right = 0, + .sub = 0 }, + {.name = "F", + .x = 250, + .y = 0, + .w = 36, + .h = 23, + .lc = WHITE, + .label = 0, + .font_size = 0, + .lw = menu_label_width, + .lh = menu_label_height, + .lb = menu_label_bitmap, + .letter = "F", + .left = 0, + .is_menu = 0, + .right = 0, + .sub = 0 }, + + {.name = "MTH", + .x = 0, + .y = 50, + .w = 36, + .h = 26, + .lc = WHITE, + .label = "MTH", + .font_size = 0, + .lw = 0, + .lh = 0, + .lb = 0, + .letter = "G", + .left = "RAD", + .is_menu = 0, + .right = "POLAR", + .sub = 0 }, + {.name = "PRG", + .x = 50, + .y = 50, + .w = 36, + .h = 26, + .lc = WHITE, + .label = "PRG", + .font_size = 0, + .lw = 0, + .lh = 0, + .lb = 0, + .letter = "H", + .left = 0, + .is_menu = 0, + .right = "CHARS", + .sub = 0 }, + {.name = "CST", + .x = 100, + .y = 50, + .w = 36, + .h = 26, + .lc = WHITE, + .label = "CST", + .font_size = 0, + .lw = 0, + .lh = 0, + .lb = 0, + .letter = "I", + .left = 0, + .is_menu = 0, + .right = "MODES", + .sub = 0 }, + {.name = "VAR", + .x = 150, + .y = 50, + .w = 36, + .h = 26, + .lc = WHITE, + .label = "VAR", + .font_size = 0, + .lw = 0, + .lh = 0, + .lb = 0, + .letter = "J", + .left = 0, + .is_menu = 0, + .right = "MEMORY", + .sub = 0 }, + {.name = "UP", + .x = 200, + .y = 50, + .w = 36, + .h = 26, + .lc = WHITE, + .label = 0, + .font_size = 0, + .lw = up_width, + .lh = up_height, + .lb = up_bitmap, + .letter = "K", + .left = 0, + .is_menu = 0, + .right = "STACK", + .sub = 0 }, + {.name = "NXT", + .x = 250, + .y = 50, + .w = 36, + .h = 26, + .lc = WHITE, + .label = "NXT", + .font_size = 0, + .lw = 0, + .lh = 0, + .lb = 0, + .letter = "L", + .left = "PREV", + .is_menu = 0, + .right = "MENU", + .sub = 0 }, + + {.name = "QUOTE", + .x = 0, + .y = 100, + .w = 36, + .h = 26, + .lc = WHITE, + .label = 0, + .font_size = 0, + .lw = quote_width, + .lh = quote_height, + .lb = quote_bitmap, + .letter = "M", + .left = "UP", + .is_menu = 0, + .right = "HOME", + .sub = 0 }, + {.name = "STO", + .x = 50, + .y = 100, + .w = 36, + .h = 26, + .lc = WHITE, + .label = "STO", + .font_size = 0, + .lw = 0, + .lh = 0, + .lb = 0, + .letter = "N", + .left = "DEF", + .is_menu = 0, + .right = "RCL", + .sub = 0 }, + {.name = "EVAL", + .x = 100, + .y = 100, + .w = 36, + .h = 26, + .lc = WHITE, + .label = "EVAL", + .font_size = 0, + .lw = 0, + .lh = 0, + .lb = 0, + .letter = "O", + .left = "\x06NUM", + .is_menu = 0, + .right = "UNDO", + .sub = 0 }, + {.name = "LEFT", + .x = 150, + .y = 100, + .w = 36, + .h = 26, + .lc = WHITE, + .label = 0, + .font_size = 0, + .lw = left_width, + .lh = left_height, + .lb = left_bitmap, + .letter = "P", + .left = "PICTURE", + .is_menu = 0, + .right = 0, + .sub = 0 }, + {.name = "DOWN", + .x = 200, + .y = 100, + .w = 36, + .h = 26, + .lc = WHITE, + .label = 0, + .font_size = 0, + .lw = down_width, + .lh = down_height, + .lb = down_bitmap, + .letter = "Q", + .left = "VIEW", + .is_menu = 0, + .right = 0, + .sub = 0 }, + {.name = "RIGHT", + .x = 250, + .y = 100, + .w = 36, + .h = 26, + .lc = WHITE, + .label = 0, + .font_size = 0, + .lw = right_width, + .lh = right_height, + .lb = right_bitmap, + .letter = "R", + .left = "SWAP", + .is_menu = 0, + .right = 0, + .sub = 0 }, + + {.name = "SIN", + .x = 0, + .y = 150, + .w = 36, + .h = 26, + .lc = WHITE, + .label = "SIN", + .font_size = 0, + .lw = 0, + .lh = 0, + .lb = 0, + .letter = "S", + .left = "ASIN", + .is_menu = 0, + .right = "\x07", + .sub = 0 }, + {.name = "COS", + .x = 50, + .y = 150, + .w = 36, + .h = 26, + .lc = WHITE, + .label = "COS", + .font_size = 0, + .lw = 0, + .lh = 0, + .lb = 0, + .letter = "T", + .left = "ACOS", + .is_menu = 0, + .right = "\x08", + .sub = 0 }, + {.name = "TAN", + .x = 100, + .y = 150, + .w = 36, + .h = 26, + .lc = WHITE, + .label = "TAN", + .font_size = 0, + .lw = 0, + .lh = 0, + .lb = 0, + .letter = "U", + .left = "ATAN", + .is_menu = 0, + .right = "\x09", + .sub = 0 }, + {.name = "SQRT", + .x = 150, + .y = 150, + .w = 36, + .h = 26, + .lc = WHITE, + .label = 0, + .font_size = 0, + .lw = sqrt_width, + .lh = sqrt_height, + .lb = sqrt_bitmap, + .letter = "V", + .left = "\x13", + .is_menu = 0, + .right = "\x14", + .sub = 0 }, + {.name = "POWER", + .x = 200, + .y = 150, + .w = 36, + .h = 26, + .lc = WHITE, + .label = 0, + .font_size = 0, + .lw = power_width, + .lh = power_height, + .lb = power_bitmap, + .letter = "W", + .left = "\x15", + .is_menu = 0, + .right = "LOG", + .sub = 0 }, + {.name = "INV", + .x = 250, + .y = 150, + .w = 36, + .h = 26, + .lc = WHITE, + .label = 0, + .font_size = 0, + .lw = inv_width, + .lh = inv_height, + .lb = inv_bitmap, + .letter = "X", + .left = "\x16", + .is_menu = 0, + .right = "LN", + .sub = 0 }, + + {.name = "ENTER", + .x = 0, + .y = 200, + .w = 86, + .h = 26, + .lc = WHITE, + .label = "ENTER", + .font_size = 2, + .lw = 0, + .lh = 0, + .lb = 0, + .letter = 0, + .left = "EQUATION", + .is_menu = 0, + .right = "MATRIX", + .sub = 0 }, + {.name = "NEG", + .x = 100, + .y = 200, + .w = 36, + .h = 26, + .lc = WHITE, + .label = 0, + .font_size = 0, + .lw = neg_width, + .lh = neg_height, + .lb = neg_bitmap, + .letter = "Y", + .left = "EDIT", + .is_menu = 0, + .right = "CMD", + .sub = 0 }, + {.name = "EEX", + .x = 150, + .y = 200, + .w = 36, + .h = 26, + .lc = WHITE, + .label = "EEX", + .font_size = 0, + .lw = 0, + .lh = 0, + .lb = 0, + .letter = "Z", + .left = "PURG", + .is_menu = 0, + .right = "ARG", + .sub = 0 }, + {.name = "DEL", + .x = 200, + .y = 200, + .w = 36, + .h = 26, + .lc = WHITE, + .label = "DEL", + .font_size = 0, + .lw = 0, + .lh = 0, + .lb = 0, + .letter = 0, + .left = "CLEAR", + .is_menu = 0, + .right = 0, + .sub = 0 }, + {.name = "BS", + .x = 250, + .y = 200, + .w = 36, + .h = 26, + .lc = WHITE, + .label = 0, + .font_size = 0, + .lw = bs_width, + .lh = bs_height, + .lb = bs_bitmap, + .letter = 0, + .left = "DROP", + .is_menu = 0, + .right = 0, + .sub = 0 }, + + {.name = "ALPHA", + .x = 0, + .y = 250, + .w = 36, + .h = 26, + .lc = WHITE, + .label = 0, + .font_size = 0, + .lw = alpha_width, + .lh = alpha_height, + .lb = alpha_bitmap, + .letter = 0, + .left = "USER", + .is_menu = 0, + .right = "ENTRY", + .sub = 0 }, + {.name = "7", + .x = 60, + .y = 250, + .w = 46, + .h = 26, + .lc = WHITE, + .label = "7", + .font_size = 1, + .lw = 0, + .lh = 0, + .lb = 0, + .letter = 0, + .left = "SOLVE", + .is_menu = 1, + .right = 0, + .sub = 0 }, + {.name = "8", + .x = 120, + .y = 250, + .w = 46, + .h = 26, + .lc = WHITE, + .label = "8", + .font_size = 1, + .lw = 0, + .lh = 0, + .lb = 0, + .letter = 0, + .left = "PLOT", + .is_menu = 1, + .right = 0, + .sub = 0 }, + {.name = "9", + .x = 180, + .y = 250, + .w = 46, + .h = 26, + .lc = WHITE, + .label = "9", + .font_size = 1, + .lw = 0, + .lh = 0, + .lb = 0, + .letter = 0, + .left = "SYMBOLIC", + .is_menu = 1, + .right = 0, + .sub = 0 }, + {.name = "DIV", + .x = 240, + .y = 250, + .w = 46, + .h = 26, + .lc = WHITE, + .label = 0, + .font_size = 0, + .lw = div_width, + .lh = div_height, + .lb = div_bitmap, + .letter = 0, + .left = "\x17 ", + .is_menu = 0, + .right = "\x18", + .sub = 0 }, + + {.name = "SHL", + .x = 0, + .y = 300, + .w = 36, + .h = 26, + .lc = LEFT, + .label = 0, + .font_size = 0, + .lw = shl_width, + .lh = shl_height, + .lb = shl_bitmap, + .letter = 0, + .left = 0, + .is_menu = 0, + .right = 0, + .sub = 0 }, + {.name = "4", + .x = 60, + .y = 300, + .w = 46, + .h = 26, + .lc = WHITE, + .label = "4", + .font_size = 1, + .lw = 0, + .lh = 0, + .lb = 0, + .letter = 0, + .left = "TIME", + .is_menu = 1, + .right = 0, + .sub = 0 }, + {.name = "5", + .x = 120, + .y = 300, + .w = 46, + .h = 26, + .lc = WHITE, + .label = "5", + .font_size = 1, + .lw = 0, + .lh = 0, + .lb = 0, + .letter = 0, + .left = "STAT", + .is_menu = 1, + .right = 0, + .sub = 0 }, + {.name = "6", + .x = 180, + .y = 300, + .w = 46, + .h = 26, + .lc = WHITE, + .label = "6", + .font_size = 1, + .lw = 0, + .lh = 0, + .lb = 0, + .letter = 0, + .left = "UNITS", + .is_menu = 1, + .right = 0, + .sub = 0 }, + {.name = "MUL", + .x = 240, + .y = 300, + .w = 46, + .h = 26, + .lc = WHITE, + .label = 0, + .font_size = 0, + .lw = mul_width, + .lh = mul_height, + .lb = mul_bitmap, + .letter = 0, + .left = "\x19 ", + .is_menu = 0, + .right = "\x1a", + .sub = 0 }, + + {.name = "SHR", + .x = 0, + .y = 350, + .w = 36, + .h = 26, + .lc = RIGHT, + .label = 0, + .font_size = 0, + .lw = shr_width, + .lh = shr_height, + .lb = shr_bitmap, + .letter = 0, + .left = " ", + .is_menu = 1, + .right = 0, + .sub = 0 }, + {.name = "1", + .x = 60, + .y = 350, + .w = 46, + .h = 26, + .lc = WHITE, + .label = "1", + .font_size = 1, + .lw = 0, + .lh = 0, + .lb = 0, + .letter = 0, + .left = "I/O", + .is_menu = 1, + .right = 0, + .sub = 0 }, + {.name = "2", + .x = 120, + .y = 350, + .w = 46, + .h = 26, + .lc = WHITE, + .label = "2", + .font_size = 1, + .lw = 0, + .lh = 0, + .lb = 0, + .letter = 0, + .left = "LIBRARY", + .is_menu = 1, + .right = 0, + .sub = 0 }, + {.name = "3", + .x = 180, + .y = 350, + .w = 46, + .h = 26, + .lc = WHITE, + .label = "3", + .font_size = 1, + .lw = 0, + .lh = 0, + .lb = 0, + .letter = 0, + .left = "EQ LIB", + .is_menu = 1, + .right = 0, + .sub = 0 }, + {.name = "MINUS", + .x = 240, + .y = 350, + .w = 46, + .h = 26, + .lc = WHITE, + .label = 0, + .font_size = 0, + .lw = minus_width, + .lh = minus_height, + .lb = minus_bitmap, + .letter = 0, + .left = "\x1b ", + .is_menu = 0, + .right = "\x1c", + .sub = 0 }, + + {.name = "ON", + .x = 0, + .y = 400, + .w = 36, + .h = 26, + .lc = WHITE, + .label = "ON", + .font_size = 0, + .lw = 0, + .lh = 0, + .lb = 0, + .letter = 0, + .left = "CONT", + .is_menu = 0, + .right = "OFF", + .sub = "CANCEL"}, + {.name = "0", + .x = 60, + .y = 400, + .w = 46, + .h = 26, + .lc = WHITE, + .label = "0", + .font_size = 1, + .lw = 0, + .lh = 0, + .lb = 0, + .letter = 0, + .left = "\x04 ", + .is_menu = 0, + .right = "\x03", + .sub = 0 }, + {.name = "PERIOD", + .x = 120, + .y = 400, + .w = 46, + .h = 26, + .lc = WHITE, + .label = ".", + .font_size = 1, + .lw = 0, + .lh = 0, + .lb = 0, + .letter = 0, + .left = "\x02 ", + .is_menu = 0, + .right = "\x01", + .sub = 0 }, + {.name = "SPC", + .x = 180, + .y = 400, + .w = 46, + .h = 26, + .lc = WHITE, + .label = "SPC", + .font_size = 0, + .lw = 0, + .lh = 0, + .lb = 0, + .letter = 0, + .left = "\x05 ", + .is_menu = 0, + .right = "\x1f", + .sub = 0 }, + {.name = "PLUS", + .x = 240, + .y = 400, + .w = 46, + .h = 26, + .lc = WHITE, + .label = 0, + .font_size = 0, + .lw = plus_width, + .lh = plus_height, + .lb = plus_bitmap, + .letter = 0, + .left = "\x1d ", + .is_menu = 0, + .right = "\x1e", + .sub = 0 }, +}; + +ann_struct_t ann_tbl[ NB_ANNUNCIATORS ] = { + {.x = 16, .y = 4, .width = ann_left_width, .height = ann_left_height, .bits = ann_left_bitmap }, + {.x = 61, .y = 4, .width = ann_right_width, .height = ann_right_height, .bits = ann_right_bitmap }, + {.x = 106, .y = 4, .width = ann_alpha_width, .height = ann_alpha_height, .bits = ann_alpha_bitmap }, + {.x = 151, .y = 4, .width = ann_battery_width, .height = ann_battery_height, .bits = ann_battery_bitmap}, + {.x = 196, .y = 4, .width = ann_busy_width, .height = ann_busy_height, .bits = ann_busy_bitmap }, + {.x = 241, .y = 4, .width = ann_io_width, .height = ann_io_height, .bits = ann_io_bitmap }, +}; + +void ( *ui_disp_draw_nibble )( word_20 addr, word_4 val ); +void ( *ui_menu_draw_nibble )( word_20 addr, word_4 val ); +void ( *ui_get_event )( void ); +void ( *ui_update_LCD )( void ); +void ( *ui_refresh_LCD )( void ); +void ( *ui_adjust_contrast )( void ); +void ( *ui_draw_annunc )( void ); + +void ui_init_LCD( void ) { memset( lcd_nibbles_buffer, 0xf0, sizeof( lcd_nibbles_buffer ) ); } + +int SmallTextWidth( const char* string, unsigned int length ) +{ + int w = 0; + for ( unsigned int i = 0; i < length; i++ ) { + if ( small_font[ ( int )string[ i ] ].h != 0 ) + w += small_font[ ( int )string[ i ] ].w + 1; + else { + /* if ( config.verbose ) */ + /* fprintf( stderr, "Unknown small letter 0x00%x\n", ( int )string[ i ] ); */ + w += 5; + } + } + + return w; +} + +int BigTextWidth( const char* string, unsigned int length ) +{ + int w = 0; + for ( unsigned int i = 0; i < length; i++ ) { + if ( big_font[ ( int )string[ i ] ].h != 0 ) + w += big_font[ ( int )string[ i ] ].w; + else { + /* if ( config.verbose ) */ + /* fprintf( stderr, "Unknown small letter 0x00%x\n", ( int )string[ i ] ); */ + w += 7; + } + } + + return w; +} + +void start_UI( int argc, char** argv ) +{ + ui_init_LCD(); + + init_sdl2_ui( argc, argv ); +} + +void ui_stop( void ) +{ + sdl2_ui_stop(); +} + +void close_and_exit( void ) +{ + ui_stop(); + //exit_emulator(); + + exit( 0 ); +} diff --git a/src/ui.h b/src/ui.h new file mode 100644 index 0000000..d84bd4a --- /dev/null +++ b/src/ui.h @@ -0,0 +1,56 @@ +#ifndef _UI_H +#define _UI_H 1 + +#define NIBBLES_PER_ROW 0x22 + +#define DISP_ROWS 64 +#define NIBS_PER_BUFFER_ROW ( NIBBLES_PER_ROW + 2 ) + +typedef unsigned char word_4; +typedef unsigned char word_8; +typedef long word_20; + +/*************/ +/* variables */ +/*************/ +extern int last_annunc_state; + +extern unsigned char lcd_nibbles_buffer[ DISP_ROWS ][ NIBS_PER_BUFFER_ROW ]; + +/*************/ +/* functions */ +/*************/ +extern void init_sdl2_ui( int argc, char** argv ); +extern void sdl2_ui_stop( void ); + +/*************************************************/ +/* public API: if it's there it's used elsewhere */ +/*************************************************/ +/*************************/ +/* used in: emu_memory.c */ +/*************************/ +extern void ( *ui_disp_draw_nibble )( word_20 addr, word_4 val ); +extern void ( *ui_menu_draw_nibble )( word_20 addr, word_4 val ); + +/*****************************************/ +/* used in: emu_emulate.c */ +/*****************************************/ +extern void ( *ui_get_event )( void ); +extern void ( *ui_adjust_contrast )( void ); +extern void ( *ui_draw_annunc )( void ); + +/*****************************************************/ +/* used in: emu_emulate.c, debugger.c */ +/*****************************************************/ +extern void ( *ui_update_LCD )( void ); +extern void ( *ui_refresh_LCD )( void ); + +/*******************/ +/* used in: main.c */ +/*******************/ +extern void ui_stop( void ); +extern void start_UI( int argc, char** argv ); + +extern void close_and_exit( void ); + +#endif /* !_UI_H */ diff --git a/src/ui_bitmaps_big_font.h b/src/ui_bitmaps_big_font.h new file mode 100644 index 0000000..85b8c46 --- /dev/null +++ b/src/ui_bitmaps_big_font.h @@ -0,0 +1,172 @@ +#ifndef _UI_BIG_FONT_H +#define _UI_BIG_FONT_H 1 + +#define big_font_dot_width 8 +#define big_font_dot_height 13 +static unsigned char big_font_dot_bits[] = { + 0, 0, 0, 0, 0, 0, 0, 24, 24, 0, 0, 0, 0, +}; + +#define big_font_0_width 8 +#define big_font_0_height 13 +static unsigned char big_font_0_bits[] = { + 24, 60, 102, 102, 195, 195, 195, 195, 195, 102, 102, 60, 24, +}; + +#define big_font_1_width 8 +#define big_font_1_height 13 +static unsigned char big_font_1_bits[] = { + 24, 28, 30, 27, 24, 24, 24, 24, 24, 24, 24, 24, 255, +}; + +#define big_font_2_width 8 +#define big_font_2_height 13 +static unsigned char big_font_2_bits[] = { + 60, 102, 195, 195, 192, 192, 96, 56, 12, 6, 3, 3, 255, +}; + +#define big_font_3_width 8 +#define big_font_3_height 13 +static unsigned char big_font_3_bits[] = { + 60, 102, 195, 195, 192, 96, 56, 96, 192, 195, 195, 102, 60, +}; + +#define big_font_4_width 8 +#define big_font_4_height 13 +static unsigned char big_font_4_bits[] = { + 96, 112, 120, 108, 102, 99, 99, 255, 96, 96, 96, 96, 96, +}; + +#define big_font_5_width 8 +#define big_font_5_height 13 +static unsigned char big_font_5_bits[] = { + 255, 3, 3, 3, 3, 59, 103, 192, 192, 192, 195, 102, 60, +}; + +#define big_font_6_width 8 +#define big_font_6_height 13 +static unsigned char big_font_6_bits[] = { + 60, 102, 67, 3, 3, 59, 103, 195, 195, 195, 195, 102, 60, +}; + +#define big_font_7_width 8 +#define big_font_7_height 13 +static unsigned char big_font_7_bits[] = { + 255, 192, 192, 96, 96, 48, 48, 24, 24, 12, 12, 6, 6, +}; + +#define big_font_8_width 8 +#define big_font_8_height 13 +static unsigned char big_font_8_bits[] = { + 60, 102, 195, 195, 195, 102, 60, 102, 195, 195, 195, 102, 60, +}; + +#define big_font_9_width 8 +#define big_font_9_height 13 +static unsigned char big_font_9_bits[] = { + 62, 195, 195, 195, 195, 195, 230, 220, 192, 192, 194, 102, 60, +}; + +#define big_font_A_width 8 +#define big_font_A_height 10 +static unsigned char big_font_A_bits[] = { + 30, 51, 51, 51, 51, 51, 63, 51, 51, 51, +}; + +#define big_font_C_width 8 +#define big_font_C_height 10 +static unsigned char big_font_C_bits[] = { + 30, 51, 51, 3, 3, 3, 3, 51, 51, 30, +}; + +#define big_font_D_width 8 +#define big_font_D_height 10 +static unsigned char big_font_D_bits[] = { + 15, 27, 51, 51, 51, 51, 51, 51, 27, 15, +}; + +#define big_font_E_width 8 +#define big_font_E_height 10 +static unsigned char big_font_E_bits[] = { + 63, 3, 3, 3, 31, 3, 3, 3, 3, 63, +}; + +#define big_font_G_width 8 +#define big_font_G_height 10 +static unsigned char big_font_G_bits[] = { + 30, 51, 51, 3, 3, 59, 51, 51, 51, 30, +}; + +#define big_font_H_width 8 +#define big_font_H_height 10 +static unsigned char big_font_H_bits[] = { + 51, 51, 51, 51, 63, 51, 51, 51, 51, 51, +}; + +#define big_font_I_width 8 +#define big_font_I_height 10 +static unsigned char big_font_I_bits[] = { + 63, 12, 12, 12, 12, 12, 12, 12, 12, 63, +}; + +#define big_font_L_width 8 +#define big_font_L_height 10 +static unsigned char big_font_L_bits[] = { + 3, 3, 3, 3, 3, 3, 3, 3, 3, 63, +}; + +#define big_font_M_width 8 +#define big_font_M_height 10 +static unsigned char big_font_M_bits[] = { + 33, 51, 51, 63, 63, 51, 51, 51, 51, 51, +}; + +#define big_font_N_width 8 +#define big_font_N_height 10 +static unsigned char big_font_N_bits[] = { + 51, 51, 55, 55, 55, 59, 59, 59, 51, 51, +}; + +#define big_font_O_width 8 +#define big_font_O_height 10 +static unsigned char big_font_O_bits[] = { + 30, 51, 51, 51, 51, 51, 51, 51, 51, 30, +}; + +#define big_font_P_width 8 +#define big_font_P_height 10 +static unsigned char big_font_P_bits[] = { + 31, 51, 51, 51, 51, 31, 3, 3, 3, 3, +}; + +#define big_font_R_width 8 +#define big_font_R_height 10 +static unsigned char big_font_R_bits[] = { + 31, 51, 51, 51, 31, 27, 51, 51, 51, 51, +}; + +#define big_font_S_width 8 +#define big_font_S_height 10 +static unsigned char big_font_S_bits[] = { + 30, 51, 51, 6, 12, 12, 24, 51, 51, 30, +}; + +#define big_font_T_width 8 +#define big_font_T_height 10 +static unsigned char big_font_T_bits[] = { + 63, 12, 12, 12, 12, 12, 12, 12, 12, 12, +}; + +#define big_font_V_width 8 +#define big_font_V_height 10 +static unsigned char big_font_V_bits[] = { + 51, 51, 51, 51, 51, 51, 51, 30, 30, 12, +}; + +#define big_font_X_width 8 +#define big_font_X_height 10 +static unsigned char big_font_X_bits[] = { + 51, 51, 30, 30, 12, 12, 30, 30, 51, 51, +}; + +#endif /* _UI_BIG_FONT_H 1 */ diff --git a/src/ui_bitmaps_misc.h b/src/ui_bitmaps_misc.h new file mode 100644 index 0000000..4335d8f --- /dev/null +++ b/src/ui_bitmaps_misc.h @@ -0,0 +1,224 @@ +#ifndef _UI_BITMAPS_H +#define _UI_BITMAPS_H 1 + +#define hp_width 96 +#define hp_height 24 +static unsigned char hp_bitmap[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xf8, 0x9f, 0xfd, 0x3f, 0x60, 0xcc, 0x6f, 0x66, 0x83, 0xdf, 0xff, 0x3f, 0xfc, 0x9f, 0xf1, 0x7f, 0x60, 0xcc, + 0x60, 0x66, 0x83, 0x01, 0x06, 0x06, 0xfc, 0xc7, 0xc0, 0x7f, 0x60, 0xcc, 0x60, 0x66, 0x83, 0x01, 0x06, 0x06, 0xfc, 0xc3, 0x80, + 0x7f, 0x60, 0xcc, 0x40, 0x26, 0x83, 0x01, 0x06, 0x06, 0xfc, 0x61, 0x00, 0x7f, 0xe0, 0xcf, 0xcf, 0x36, 0x83, 0x1f, 0x06, 0x06, + 0xfc, 0x60, 0x00, 0x7e, 0x60, 0xcc, 0xc0, 0x36, 0x83, 0x01, 0x06, 0x06, 0xfc, 0x30, 0x00, 0x7e, 0x60, 0xcc, 0x80, 0x19, 0x83, + 0x01, 0x06, 0x06, 0x7c, 0xb0, 0x68, 0x7c, 0x60, 0xcc, 0x80, 0x19, 0x83, 0x01, 0x06, 0x06, 0x7c, 0xf8, 0xf9, 0x7c, 0x60, 0xcc, + 0x8f, 0x19, 0xbf, 0x1f, 0x06, 0x06, 0x7c, 0x98, 0xcd, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xcc, 0xcc, + 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xcc, 0x66, 0x7c, 0xe0, 0x87, 0x81, 0x67, 0x0c, 0xc3, 0xcf, 0x0f, + 0x7c, 0x66, 0x66, 0x7c, 0x60, 0xcc, 0xc3, 0x6c, 0x86, 0xc7, 0xd8, 0x18, 0x7c, 0x66, 0x3f, 0x7e, 0x60, 0x4c, 0x62, 0x60, 0x83, + 0xc4, 0xd8, 0x30, 0xfc, 0x00, 0x03, 0x7e, 0x60, 0x6c, 0x66, 0xe0, 0xc1, 0xcc, 0xd8, 0x30, 0xfc, 0x80, 0x01, 0x7f, 0xe0, 0x67, + 0x66, 0xe0, 0xc1, 0xcc, 0xcf, 0x30, 0xfc, 0x81, 0x81, 0x7f, 0x60, 0xe0, 0x67, 0x60, 0xc3, 0xcf, 0xcc, 0x30, 0xfc, 0xc3, 0xc0, + 0x7f, 0x60, 0x30, 0x6c, 0x60, 0x66, 0xd8, 0xd8, 0x30, 0xfc, 0xcf, 0xf0, 0x7f, 0x60, 0x30, 0xcc, 0x6c, 0x6c, 0xd8, 0xd8, 0x18, + 0xf8, 0x6f, 0xfe, 0x3f, 0x60, 0x30, 0x8c, 0x67, 0x78, 0xd8, 0xd8, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; + +#define hp48sx_width 42 +#define hp48sx_height 10 +static unsigned char hp48sx_bitmap[] = { 0xe0, 0xf1, 0xc3, 0x3f, 0x87, 0x03, 0xf0, 0xf9, 0xe7, 0x7f, 0xc7, 0x01, 0xf8, 0x39, 0xe7, + 0x70, 0xee, 0x00, 0xdc, 0x39, 0xe7, 0x00, 0x7e, 0x00, 0xee, 0xf0, 0xe3, 0x0f, 0x3c, 0x00, + 0xe7, 0xf8, 0xc1, 0x1f, 0x1c, 0x00, 0xff, 0x9d, 0x03, 0x1c, 0x3e, 0x00, 0xff, 0x9d, 0x3b, + 0x1c, 0x3f, 0x00, 0x70, 0xfc, 0xfb, 0x9f, 0x73, 0x00, 0x70, 0xf8, 0xf1, 0xcf, 0x71, 0x00 }; + +#define hp48gx_width 44 +#define hp48gx_height 14 +static unsigned char hp48gx_bitmap[] = { + 0x00, 0xc3, 0x03, 0x7c, 0x0c, 0x0c, 0x80, 0xe3, 0x07, 0xff, 0x0c, 0x0e, 0xc0, 0x33, 0x86, 0xc3, 0x1c, 0x06, 0xe0, 0x31, 0xc6, + 0xc0, 0x18, 0x03, 0xb0, 0x31, 0xe6, 0x00, 0xb0, 0x01, 0x98, 0x31, 0x63, 0x00, 0xf0, 0x01, 0x8c, 0xe1, 0x61, 0x00, 0xe0, 0x00, + 0xc6, 0xb8, 0x31, 0xfc, 0x70, 0x00, 0xc7, 0x18, 0x33, 0xfc, 0xf8, 0x00, 0xff, 0x0d, 0x33, 0x60, 0xd8, 0x00, 0xff, 0x0d, 0x73, + 0x60, 0x8c, 0x01, 0x60, 0x8c, 0x63, 0x30, 0x86, 0x03, 0x60, 0xfc, 0xe1, 0x3f, 0x07, 0x03, 0x60, 0xf8, 0x80, 0x37, 0x03, 0x03 }; + +#define science_width 131 +#define science_height 8 +static unsigned char science_bitmap[] = { + 0x38, 0x1c, 0xf2, 0x09, 0x7d, 0x79, 0xe2, 0x80, 0x2f, 0xe4, 0x41, 0x08, 0x79, 0x20, 0x3c, 0xc2, 0x07, 0x44, 0x22, 0x12, + 0x08, 0x11, 0x09, 0x12, 0x81, 0x20, 0x22, 0x62, 0x08, 0x89, 0x30, 0x44, 0x42, 0x00, 0x02, 0x01, 0x09, 0x94, 0x88, 0x04, + 0x09, 0x40, 0x40, 0x11, 0x52, 0x94, 0x88, 0x28, 0x42, 0x21, 0x00, 0x1c, 0x01, 0xf9, 0x94, 0x88, 0x3c, 0x09, 0xc0, 0xc7, + 0xf0, 0x51, 0x94, 0x84, 0x28, 0x3e, 0xe1, 0x03, 0xa0, 0x00, 0x09, 0x94, 0x88, 0x04, 0x05, 0x40, 0xc0, 0x10, 0x48, 0x94, + 0x44, 0x24, 0x22, 0x21, 0x00, 0xa1, 0xa0, 0x04, 0xa2, 0x44, 0x82, 0x04, 0x21, 0xa0, 0x08, 0xfc, 0xa2, 0x42, 0x7e, 0xa1, + 0x10, 0x00, 0x91, 0x90, 0x04, 0x42, 0x44, 0x82, 0x84, 0x20, 0x10, 0x09, 0x84, 0x42, 0x22, 0x42, 0xb1, 0x10, 0x00, 0x0e, + 0x8f, 0x7c, 0x42, 0x44, 0x82, 0x78, 0xe0, 0x0b, 0x09, 0x82, 0x42, 0x1e, 0x41, 0x9f, 0xf7, 0x01 }; + +#define gx_128K_ram_x_hot 1 +#define gx_128K_ram_y_hot 8 +#define gx_128K_ram_width 43 +#define gx_128K_ram_height 31 +static unsigned char gx_128K_ram_bitmap[] = { + 0xfe, 0xdf, 0xff, 0xff, 0x03, 0x00, 0xfe, 0xdf, 0xff, 0xff, 0x03, 0x00, 0xfe, 0xdf, 0xff, 0xff, 0x03, 0x00, 0xe2, 0xdf, 0xff, + 0xff, 0x03, 0x00, 0x9c, 0xdf, 0xff, 0xff, 0x03, 0x00, 0x7e, 0xdf, 0xff, 0xff, 0x01, 0x00, 0x7e, 0xdf, 0xff, 0xff, 0x01, 0x00, + 0xfe, 0xde, 0xff, 0xff, 0x02, 0x00, 0xfe, 0xde, 0xff, 0xff, 0x02, 0x00, 0xfe, 0xdd, 0xff, 0x7f, 0x03, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xfe, 0xdd, 0xff, 0xbf, 0x03, 0x00, 0xfe, 0xdb, 0xff, 0xdf, 0x03, 0x00, 0xfe, 0xdb, 0xff, 0xef, 0x03, 0x00, + 0xfe, 0xd7, 0xff, 0xf7, 0x03, 0x00, 0xfe, 0xcf, 0xff, 0xfb, 0x03, 0x00, 0xfe, 0xcf, 0xff, 0xfc, 0x03, 0x00, 0xfe, 0x1f, 0x3f, + 0xff, 0x03, 0x00, 0xfe, 0xdf, 0xc0, 0xff, 0x03, 0x00, 0xfe, 0xdf, 0xff, 0xff, 0x03, 0x00, 0xfe, 0xdf, 0xff, 0xff, 0x03, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xc4, 0x30, 0x12, 0x1c, 0x44, 0x04, 0x27, 0x49, 0x0a, 0x24, 0x46, 0x04, 0x84, 0x39, 0x06, 0x24, 0xc9, 0x06, + 0x62, 0x24, 0x07, 0x9e, 0xaf, 0x06, 0x12, 0x24, 0x09, 0x92, 0xa8, 0x05, 0xf2, 0x18, 0x11, 0x52, 0x28, 0x05 }; + +#define gx_silver_x_hot 0 +#define gx_silver_y_hot 8 +#define gx_silver_width 35 +#define gx_silver_height 21 +static unsigned char gx_silver_bitmap[] = { + 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x38, 0x40, 0x00, 0x00, 0x00, 0xc4, + 0x40, 0x00, 0x00, 0x00, 0x02, 0x41, 0x00, 0x00, 0x04, 0x02, 0x41, 0x00, 0x00, 0x04, 0x02, 0x42, 0x00, 0x00, 0x02, 0x01, 0x42, + 0x00, 0x00, 0x02, 0x01, 0x44, 0x00, 0x00, 0x01, 0xfd, 0xff, 0xff, 0xff, 0x07, 0x01, 0x44, 0x00, 0x80, 0x00, 0x01, 0x48, 0x00, + 0x40, 0x00, 0x01, 0x48, 0x00, 0x20, 0x00, 0x00, 0x50, 0x00, 0x10, 0x00, 0x00, 0x60, 0x00, 0x08, 0x00, 0x00, 0x60, 0x00, 0x06, + 0x00, 0x00, 0xc0, 0x81, 0x01, 0x00, 0x00, 0x40, 0x7e, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00 }; + +#define gx_green_x_hot 11 +#define gx_green_y_hot 0 +#define gx_green_width 34 +#define gx_green_height 22 +static unsigned char gx_green_bitmap[] = { + 0xff, 0xff, 0xff, 0xff, 0x03, 0xff, 0xff, 0xff, 0xff, 0x03, 0xff, 0xff, 0xff, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, + 0xff, 0xff, 0x03, 0xff, 0xff, 0xff, 0xff, 0x03, 0x00, 0x00, 0x00, 0xfc, 0x03, 0x00, 0x00, 0x00, 0xfc, 0x03, 0x00, 0x00, 0x00, 0xfc, + 0x03, 0x00, 0x00, 0x00, 0xf0, 0x03, 0x00, 0x00, 0x00, 0xf0, 0x03, 0x00, 0x00, 0x00, 0xf0, 0x03, 0x00, 0x00, 0x00, 0xf0, 0x03, 0x00, + 0x00, 0x00, 0xf0, 0x03, 0x00, 0x00, 0x00, 0xf0, 0x03, 0x00, 0x00, 0x00, 0xf0, 0x03, 0x00, 0x00, 0x00, 0xf0, 0x03, 0x00, 0x00, 0x00, + 0xf0, 0x03, 0x00, 0x00, 0x00, 0xf0, 0x03, 0x00, 0x00, 0x00, 0xf0, 0x03, 0x00, 0x00, 0x00, 0xf0, 0x03, 0x00, 0x00, 0x00, 0xf0, 0x03 }; + +#define ann_alpha_width 15 +#define ann_alpha_height 12 +static unsigned char ann_alpha_bitmap[] = { 0xe0, 0x03, 0x18, 0x44, 0x0c, 0x4c, 0x06, 0x2c, 0x07, 0x2c, 0x07, 0x1c, + 0x07, 0x0c, 0x07, 0x0c, 0x07, 0x0e, 0x0e, 0x4d, 0xf8, 0x38, 0x00, 0x00 }; + +#define ann_battery_width 15 +#define ann_battery_height 12 +static unsigned char ann_battery_bitmap[] = { 0x04, 0x10, 0x02, 0x20, 0x12, 0x24, 0x09, 0x48, 0xc9, 0x49, 0xc9, 0x49, + 0xc9, 0x49, 0x09, 0x48, 0x12, 0x24, 0x02, 0x20, 0x04, 0x10, 0x00, 0x00 }; + +#define ann_busy_width 15 +#define ann_busy_height 12 +static unsigned char ann_busy_bitmap[] = { 0xfc, 0x1f, 0x08, 0x08, 0x08, 0x08, 0xf0, 0x07, 0xe0, 0x03, 0xc0, 0x01, + 0x40, 0x01, 0x20, 0x02, 0x10, 0x04, 0xc8, 0x09, 0xe8, 0x0b, 0xfc, 0x1f }; + +#define ann_io_width 15 +#define ann_io_height 12 +static unsigned char ann_io_bitmap[] = { 0x0c, 0x00, 0x1e, 0x00, 0x33, 0x0c, 0x61, 0x18, 0xcc, 0x30, 0xfe, 0x7f, + 0xfe, 0x7f, 0xcc, 0x30, 0x61, 0x18, 0x33, 0x0c, 0x1e, 0x00, 0x0c, 0x00 }; + +#define ann_left_width 15 +#define ann_left_height 12 +static unsigned char ann_left_bitmap[] = { 0xfe, 0x3f, 0xff, 0x7f, 0x9f, 0x7f, 0xcf, 0x7f, 0xe7, 0x7f, 0x03, 0x78, + 0x03, 0x70, 0xe7, 0x73, 0xcf, 0x73, 0x9f, 0x73, 0xff, 0x73, 0xfe, 0x33 }; + +#define ann_right_width 15 +#define ann_right_height 12 +static unsigned char ann_right_bitmap[] = { 0xfe, 0x3f, 0xff, 0x7f, 0xff, 0x7c, 0xff, 0x79, 0xff, 0x73, 0x0f, 0x60, + 0x07, 0x60, 0xe7, 0x73, 0xe7, 0x79, 0xe7, 0x7c, 0xe7, 0x7f, 0xe6, 0x3f }; + +/* #endif /\* !_ANNUNC_H *\/ */ + +/* #ifndef _BUTTONS_H */ +/* #define _BUTTONS_H 1 */ + +#define menu_label_width 24 +#define menu_label_height 11 +static unsigned char menu_label_bitmap[] = { 0xfe, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0x7f }; + +#define up_width 11 +#define up_height 11 +static unsigned char up_bitmap[] = { 0x20, 0x00, 0x20, 0x00, 0x70, 0x00, 0x70, 0x00, 0xf8, 0x00, 0xf8, + 0x00, 0xfc, 0x01, 0xfc, 0x01, 0xfe, 0x03, 0xfe, 0x03, 0xff, 0x07 }; + +#define down_width 11 +#define down_height 11 +static unsigned char down_bitmap[] = { 0xff, 0x07, 0xfe, 0x03, 0xfe, 0x03, 0xfc, 0x01, 0xfc, 0x01, 0xf8, + 0x00, 0xf8, 0x00, 0x70, 0x00, 0x70, 0x00, 0x20, 0x00, 0x20, 0x00 }; + +#define left_width 11 +#define left_height 11 +static unsigned char left_bitmap[] = { 0x00, 0x04, 0x00, 0x07, 0xc0, 0x07, 0xf0, 0x07, 0xfc, 0x07, 0xff, + 0x07, 0xfc, 0x07, 0xf0, 0x07, 0xc0, 0x07, 0x00, 0x07, 0x00, 0x04 }; + +#define right_width 11 +#define right_height 11 +static unsigned char right_bitmap[] = { 0x01, 0x00, 0x07, 0x00, 0x1f, 0x00, 0x7f, 0x00, 0xff, 0x01, 0xff, + 0x07, 0xff, 0x01, 0x7f, 0x00, 0x1f, 0x00, 0x07, 0x00, 0x01, 0x00 }; + +#define sqrt_width 20 +#define sqrt_height 11 +static unsigned char sqrt_bitmap[] = { 0x00, 0xff, 0x0f, 0x00, 0x01, 0x08, 0x00, 0x01, 0x08, 0x80, 0x8c, 0x01, 0x80, 0x58, 0x01, 0x80, 0x38, + 0x00, 0x47, 0x30, 0x00, 0x4c, 0x30, 0x00, 0x58, 0x78, 0x00, 0x30, 0x6a, 0x01, 0x20, 0xc6, 0x00 }; + +#define power_width 17 +#define power_height 14 +static unsigned char power_bitmap[] = { 0x00, 0x8c, 0x01, 0x00, 0x58, 0x01, 0x00, 0x38, 0x00, 0xc8, 0x30, 0x00, 0x9c, 0x30, + 0x00, 0x98, 0x78, 0x00, 0x58, 0x6a, 0x01, 0x58, 0xc6, 0x00, 0x38, 0x00, 0x00, 0x30, + 0x00, 0x00, 0x10, 0x00, 0x00, 0x08, 0x00, 0x00, 0x05, 0x00, 0x00, 0x03, 0x00, 0x00 }; + +#define inv_width 18 +#define inv_height 13 +static unsigned char inv_bitmap[] = { 0x0c, 0x04, 0x00, 0x0f, 0x06, 0x00, 0x0c, 0x02, 0x00, 0x0c, 0x03, 0x00, 0x0c, + 0x01, 0x00, 0x8c, 0x19, 0x03, 0x8c, 0xb0, 0x02, 0xcc, 0x70, 0x00, 0x40, 0x60, + 0x00, 0x60, 0x60, 0x00, 0x20, 0xf0, 0x00, 0x30, 0xd4, 0x02, 0x10, 0x8c, 0x01 }; + +#define neg_width 21 +#define neg_height 11 +static unsigned char neg_bitmap[] = { 0x18, 0x00, 0x00, 0x18, 0x30, 0x00, 0x18, 0x30, 0x00, 0xff, 0x18, 0x00, 0xff, 0x18, 0x00, 0x18, 0x0c, + 0x00, 0x18, 0x0c, 0x00, 0x18, 0xc6, 0x1f, 0x00, 0xc6, 0x1f, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00 }; + +#define bs_width 11 +#define bs_height 11 +static unsigned char bs_bitmap[] = { 0x20, 0x00, 0x30, 0x00, 0x38, 0x00, 0xfc, 0x07, 0xfe, 0x07, 0xff, + 0x07, 0xfe, 0x07, 0xfc, 0x07, 0x38, 0x00, 0x30, 0x00, 0x20, 0x00 }; + +#define alpha_width 12 +#define alpha_height 10 +static unsigned char alpha_bitmap[] = { 0x78, 0x00, 0x84, 0x08, 0x82, 0x09, 0x83, 0x05, 0x83, 0x05, + 0x83, 0x03, 0x83, 0x01, 0x83, 0x01, 0x46, 0x09, 0x3c, 0x06 }; + +#define div_width 10 +#define div_height 10 +static unsigned char div_bitmap[] = { 0x30, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x03, + 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x30, 0x00 }; + +#define shl_width 24 +#define shl_height 14 +static unsigned char shl_bitmap[] = { 0xfe, 0xff, 0x7f, 0xff, 0xfc, 0xff, 0x7f, 0xfc, 0xff, 0x3f, 0xfe, 0xff, 0x1f, 0xff, + 0xff, 0x0f, 0x00, 0xfc, 0x07, 0x00, 0xf8, 0x0f, 0x00, 0xf0, 0x1f, 0xff, 0xf1, 0x3f, + 0xfe, 0xf1, 0x7f, 0xfc, 0xf1, 0xff, 0xfc, 0xf1, 0xff, 0xff, 0xf1, 0xfe, 0xff, 0x71 }; + +#define mul_width 10 +#define mul_height 10 +static unsigned char mul_bitmap[] = { 0x03, 0x03, 0x87, 0x03, 0xce, 0x01, 0xfc, 0x00, 0x78, 0x00, + 0x78, 0x00, 0xfc, 0x00, 0xce, 0x01, 0x87, 0x03, 0x03, 0x03 }; + +#define shr_width 24 +#define shr_height 14 +static unsigned char shr_bitmap[] = { 0xfe, 0xff, 0x7f, 0xff, 0x3f, 0xff, 0xff, 0x3f, 0xfe, 0xff, 0x7f, 0xfc, 0xff, 0xff, + 0xf8, 0x3f, 0x00, 0xf0, 0x1f, 0x00, 0xe0, 0x0f, 0x00, 0xf0, 0x8f, 0xff, 0xf8, 0x8f, + 0x7f, 0xfc, 0x8f, 0x3f, 0xfe, 0x8f, 0x3f, 0xff, 0x8f, 0xff, 0xff, 0x8e, 0xff, 0x7f }; + +#define minus_width 10 +#define minus_height 10 +static unsigned char minus_bitmap[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x03, + 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; + +#define plus_width 10 +#define plus_height 10 +static unsigned char plus_bitmap[] = { 0x30, 0x00, 0x30, 0x00, 0x30, 0x00, 0x30, 0x00, 0xff, 0x03, + 0xff, 0x03, 0x30, 0x00, 0x30, 0x00, 0x30, 0x00, 0x30, 0x00 }; + +#define quote_width 2 +#define quote_height 10 +static unsigned char quote_bitmap[] = { 0x03, 0x03, 0x03, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; + +/* Below used only for X11 */ +#define last_width 120 +#define last_height 6 +static unsigned char last_bitmap[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xc6, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x29, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x11, 0x49, 0x08, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x8f, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x29, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0xc9, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80 }; + +#endif /* _UI_BITMAPS_H 1 */ diff --git a/src/ui_bitmaps_small_font.h b/src/ui_bitmaps_small_font.h new file mode 100644 index 0000000..0a46923 --- /dev/null +++ b/src/ui_bitmaps_small_font.h @@ -0,0 +1,423 @@ +#ifndef _UI_SMALL_FONT_H +#define _UI_SMALL_FONT_H 1 + +#define blank_width 4 +#define blank_height 7 +static unsigned char blank_bits[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; + +#define hash_width 5 +#define hash_height 7 +static unsigned char hash_bits[] = { 0x00, 0x0a, 0x1f, 0x0a, 0x0a, 0x1f, 0x0a }; + +#define lbrace_width 3 +#define lbrace_height 7 +static unsigned char lbrace_bits[] = { 0x04, 0x02, 0x01, 0x01, 0x01, 0x02, 0x04 }; + +#define rbrace_width 3 +#define rbrace_height 7 +static unsigned char rbrace_bits[] = { 0x01, 0x02, 0x04, 0x04, 0x04, 0x02, 0x01 }; + +#define comma_width 3 +#define comma_height 7 +static unsigned char comma_bits[] = { 0x00, 0x00, 0x00, 0x00, 0x06, 0x06, 0x03 }; + +#define slash_width 3 +#define slash_height 7 +static unsigned char slash_bits[] = { 0x04, 0x04, 0x02, 0x02, 0x02, 0x01, 0x01 }; + +#define zero_width 5 +#define zero_height 7 +static unsigned char zero_bits[] = { + 14, 17, 25, 21, 19, 17, 14, +}; + +#define one_width 5 +#define one_height 7 +static unsigned char one_bits[] = { + 4, 6, 5, 4, 4, 4, 31, +}; + +#define two_width 5 +#define two_height 7 +static unsigned char two_bits[] = { 0x0e, 0x11, 0x10, 0x08, 0x04, 0x02, 0x1f }; + +#define three_width 5 +#define three_height 7 +static unsigned char three_bits[] = { 0x0e, 0x11, 0x10, 0x0c, 0x10, 0x11, 0x0e }; + +#define four_width 5 +#define four_height 7 +static unsigned char four_bits[] = { + 8, 12, 10, 9, 31, 8, 8, +}; + +#define five_width 5 +#define five_height 7 +static unsigned char five_bits[] = { + 31, 1, 1, 15, 16, 16, 15, +}; + +#define six_width 5 +#define six_height 7 +static unsigned char six_bits[] = { + 14, 17, 1, 15, 17, 17, 14, +}; + +#define seven_width 5 +#define seven_height 7 +static unsigned char seven_bits[] = { + 31, 16, 8, 4, 2, 1, 1, +}; + +#define eight_width 5 +#define eight_height 7 +static unsigned char eight_bits[] = { + 14, 17, 17, 14, 17, 17, 14, +}; + +#define nine_width 5 +#define nine_height 7 +static unsigned char nine_bits[] = { + 14, 17, 17, 30, 16, 17, 14, +}; + +#define small_colon_width 2 +#define small_colon_height 7 +static unsigned char small_colon_bits[] = { 0x00, 0x03, 0x03, 0x00, 0x03, 0x03, 0x00 }; + +#define d_width 5 +#define d_height 7 +static unsigned char d_bits[] = { + 16, 16, 30, 17, 17, 30, 0, +}; + +#define e_width 5 +#define e_height 7 +static unsigned char e_bits[] = { + 0, 14, 17, 15, 1, 14, 0, +}; + +#define i_width 5 +#define i_height 7 +static unsigned char i_bits[] = { + 4, 0, 6, 4, 4, 14, 0, +}; + +#define p_width 5 +#define p_height 7 +static unsigned char p_bits[] = { + 0, 15, 17, 17, 15, 1, 1, +}; + +#define r_width 5 +#define r_height 7 +static unsigned char r_bits[] = { + 0, 29, 3, 1, 1, 1, 0, +}; + +#define s_width 5 +#define s_height 7 +static unsigned char s_bits[] = { + 0, 30, 1, 14, 16, 15, 0, +}; + +#define t_width 5 +#define t_height 7 +static unsigned char t_bits[] = { + 2, 15, 2, 2, 2, 12, 0, +}; + +#define v_width 5 +#define v_height 7 +static unsigned char v_bits[] = { + 0, 17, 17, 10, 10, 4, 0, +}; + +#define w_width 5 +#define w_height 7 +static unsigned char w_bits[] = { + 0, 17, 17, 21, 21, 10, 0, +}; + +#define y_width 5 +#define y_height 7 +static unsigned char y_bits[] = { + 0, 0, 17, 17, 30, 16, 15, +}; + +#define A_width 5 +#define A_height 7 +static unsigned char A_bits[] = { 0x0e, 0x11, 0x11, 0x1f, 0x11, 0x11, 0x11 }; + +#define B_width 5 +#define B_height 7 +static unsigned char B_bits[] = { 0x0f, 0x11, 0x11, 0x0f, 0x11, 0x11, 0x0f }; + +#define C_width 5 +#define C_height 7 +static unsigned char C_bits[] = { 0x0e, 0x11, 0x01, 0x01, 0x01, 0x11, 0x0e }; + +#define D_width 5 +#define D_height 7 +static unsigned char D_bits[] = { 0x0f, 0x11, 0x11, 0x11, 0x11, 0x11, 0x0f }; + +#define E_width 5 +#define E_height 7 +static unsigned char E_bits[] = { 0x1f, 0x01, 0x01, 0x0f, 0x01, 0x01, 0x1f }; + +#define F_width 5 +#define F_height 7 +static unsigned char F_bits[] = { 0x1f, 0x01, 0x01, 0x0f, 0x01, 0x01, 0x01 }; + +#define G_width 5 +#define G_height 7 +static unsigned char G_bits[] = { 0x0e, 0x11, 0x01, 0x01, 0x19, 0x11, 0x0e }; + +#define H_width 5 +#define H_height 7 +static unsigned char H_bits[] = { 0x11, 0x11, 0x11, 0x1f, 0x11, 0x11, 0x11 }; + +#define I_width 1 +#define I_height 7 +static unsigned char I_bits[] = { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 }; + +#define J_width 4 +#define J_height 7 +static unsigned char J_bits[] = { 0x08, 0x08, 0x08, 0x08, 0x08, 0x09, 0x06 }; + +#define K_width 5 +#define K_height 7 +static unsigned char K_bits[] = { 0x11, 0x09, 0x05, 0x03, 0x05, 0x09, 0x11 }; + +#define L_width 4 +#define L_height 7 +static unsigned char L_bits[] = { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x0f }; + +#define M_width 5 +#define M_height 7 +static unsigned char M_bits[] = { 0x11, 0x1b, 0x15, 0x11, 0x11, 0x11, 0x11 }; + +#define N_width 5 +#define N_height 7 +static unsigned char N_bits[] = { 0x11, 0x11, 0x13, 0x15, 0x19, 0x11, 0x11 }; + +#define O_width 5 +#define O_height 7 +static unsigned char O_bits[] = { 0x0e, 0x11, 0x11, 0x11, 0x11, 0x11, 0x0e }; + +#define P_width 5 +#define P_height 7 +static unsigned char P_bits[] = { 0x0f, 0x11, 0x11, 0x0f, 0x01, 0x01, 0x01 }; + +#define Q_width 5 +#define Q_height 7 +static unsigned char Q_bits[] = { 0x0e, 0x11, 0x11, 0x11, 0x15, 0x09, 0x16 }; + +#define R_width 5 +#define R_height 7 +static unsigned char R_bits[] = { 0x0f, 0x11, 0x11, 0x0f, 0x05, 0x09, 0x11 }; + +#define S_width 5 +#define S_height 7 +static unsigned char S_bits[] = { 0x0e, 0x11, 0x01, 0x0e, 0x10, 0x11, 0x0e }; + +#define T_width 5 +#define T_height 7 +static unsigned char T_bits[] = { 0x1f, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04 }; + +#define U_width 5 +#define U_height 7 +static unsigned char U_bits[] = { 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x0e }; + +#define V_width 5 +#define V_height 7 +static unsigned char V_bits[] = { 0x11, 0x11, 0x11, 0x11, 0x0a, 0x0a, 0x04 }; + +#define W_width 5 +#define W_height 7 +static unsigned char W_bits[] = { 0x11, 0x11, 0x11, 0x11, 0x15, 0x1b, 0x11 }; + +#define X_width 5 +#define X_height 7 +static unsigned char X_bits[] = { 0x11, 0x11, 0x0a, 0x04, 0x0a, 0x11, 0x11 }; + +#define Y_width 5 +#define Y_height 7 +static unsigned char Y_bits[] = { 0x11, 0x11, 0x0a, 0x04, 0x04, 0x04, 0x04 }; + +#define Z_width 5 +#define Z_height 7 +static unsigned char Z_bits[] = { 0x1f, 0x10, 0x08, 0x04, 0x02, 0x01, 0x1f }; + +#define lbracket_width 3 +#define lbracket_height 7 +static unsigned char lbracket_bits[] = { 0x07, 0x01, 0x01, 0x01, 0x01, 0x01, 0x07 }; + +#define rbracket_width 3 +#define rbracket_height 7 +static unsigned char rbracket_bits[] = { 0x07, 0x04, 0x04, 0x04, 0x04, 0x04, 0x07 }; + +#define arrow_width 7 +#define arrow_height 7 +static unsigned char arrow_bits[] = { 0x00, 0x08, 0x18, 0x3f, 0x18, 0x08, 0x00 }; + +#define diff_width 5 +#define diff_height 7 +static unsigned char diff_bits[] = { 0x0e, 0x10, 0x10, 0x1e, 0x11, 0x11, 0x0e }; + +#define integral_width 5 +#define integral_height 8 +static unsigned char integral_bits[] = { 0x0c, 0x12, 0x02, 0x04, 0x04, 0x08, 0x09, 0x06 }; + +#define sigma_width 6 +#define sigma_height 9 +static unsigned char sigma_bits[] = { 0x3f, 0x21, 0x02, 0x04, 0x08, 0x04, 0x02, 0x21, 0x3f }; + +#define sqr_width 11 +#define sqr_height 10 +static unsigned char sqr_bits[] = { 0x00, 0x03, 0x80, 0x04, 0x00, 0x04, 0x00, 0x02, 0x26, 0x01, + 0x94, 0x07, 0x08, 0x00, 0x14, 0x00, 0x53, 0x00, 0x21, 0x00 }; + +#define root_width 18 +#define root_height 13 +static unsigned char root_bits[] = { 0x26, 0x00, 0x00, 0x14, 0x00, 0x00, 0x08, 0xfe, 0x03, 0x14, 0x02, 0x02, 0x53, + 0x02, 0x00, 0x21, 0x99, 0x00, 0x00, 0x91, 0x00, 0x10, 0x91, 0x00, 0xa0, 0x50, + 0x00, 0xc0, 0x60, 0x00, 0x80, 0x20, 0x00, 0x00, 0x14, 0x00, 0x00, 0x0c, 0x00 }; + +#define pow10_width 13 +#define pow10_height 9 +static unsigned char pow10_bits[] = { 0x00, 0x12, 0x00, 0x0c, 0x32, 0x04, 0x4b, 0x0a, 0x4a, + 0x09, 0x4a, 0x00, 0x4a, 0x00, 0x4a, 0x00, 0x32, 0x00 }; + +#define exp_width 11 +#define exp_height 9 +static unsigned char exp_bits[] = { 0x80, 0x04, 0x00, 0x03, 0x00, 0x01, 0x8c, 0x02, 0x52, + 0x02, 0x09, 0x00, 0x07, 0x00, 0x21, 0x00, 0x1e, 0x00 }; + +#define under_width 6 +#define under_height 7 +static unsigned char under_bits[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f }; + +#define prog_width 16 +#define prog_height 7 +static unsigned char prog_bits[] = { 0x48, 0x12, 0x24, 0x24, 0x12, 0x48, 0x09, 0x90, 0x12, 0x48, 0x24, 0x24, 0x48, 0x12 }; + +#define string_width 10 +#define string_height 7 +static unsigned char string_bits[] = { 0x85, 0x02, 0x85, 0x02, 0x85, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; + +#define equal_width 5 +#define equal_height 7 +static unsigned char equal_bits[] = { 0x00, 0x1f, 0x00, 0x00, 0x1f, 0x00, 0x00 }; + +#define nl_width 8 +#define nl_height 7 +static unsigned char nl_bits[] = { 0x00, 0x84, 0x86, 0xff, 0x06, 0x04, 0x00 }; + +#define pi_width 6 +#define pi_height 7 +static unsigned char pi_bits[] = { 0x20, 0x1f, 0x12, 0x12, 0x12, 0x12, 0x12 }; + +#define angle_width 8 +#define angle_height 7 +static unsigned char angle_bits[] = { 0x40, 0x20, 0x10, 0x28, 0x44, 0x42, 0xff }; + +#define lcurly_width 5 +#define lcurly_height 7 +static unsigned char lcurly_bits[] = { 0x18, 0x04, 0x04, 0x02, 0x04, 0x04, 0x18 }; + +#define rcurly_width 5 +#define rcurly_height 7 +static unsigned char rcurly_bits[] = { 0x03, 0x04, 0x04, 0x08, 0x04, 0x04, 0x03 }; + +#define sqr_gx_width 11 +#define sqr_gx_height 13 +static unsigned char sqr_gx_bits[] = { 0x00, 0x03, 0x80, 0x04, 0x00, 0x04, 0x00, 0x02, 0x00, 0x01, 0x80, 0x07, 0x00, + 0x00, 0x66, 0x00, 0x14, 0x00, 0x08, 0x00, 0x14, 0x00, 0x53, 0x00, 0x21, 0x00 }; + +#define root_gx_width 18 +#define root_gx_height 15 +static unsigned char root_gx_bits[] = { 0x66, 0x00, 0x00, 0x14, 0x00, 0x00, 0x08, 0x00, 0x00, 0x14, 0x00, 0x00, 0x53, 0xfe, 0x03, + 0x21, 0x02, 0x02, 0x00, 0x02, 0x00, 0x00, 0x99, 0x00, 0x00, 0x91, 0x00, 0x10, 0x91, 0x00, + 0xa0, 0x50, 0x00, 0xc0, 0x60, 0x00, 0x80, 0x20, 0x00, 0x00, 0x14, 0x00, 0x00, 0x0c, 0x00 }; + +#define pow10_gx_width 13 +#define pow10_gx_height 12 +static unsigned char pow10_gx_bits[] = { 0x00, 0x12, 0x00, 0x0c, 0x00, 0x04, 0x00, 0x0a, 0x00, 0x09, 0x32, 0x00, + 0x4b, 0x00, 0x4a, 0x00, 0x4a, 0x00, 0x4a, 0x00, 0x4a, 0x00, 0x32, 0x00 }; + +#define exp_gx_width 13 +#define exp_gx_height 12 +static unsigned char exp_gx_bits[] = { 0x00, 0xfb, 0x00, 0xf6, 0x00, 0xe6, 0x00, 0xf6, 0x80, 0xed, 0x18, 0xe0, + 0x36, 0xe0, 0x36, 0xe0, 0x1f, 0xe0, 0x03, 0xe0, 0x13, 0xe0, 0x0e, 0xe0 }; +#define parens_gx_width 20 +#define parens_gx_height 12 +static unsigned char parens_gx_bits[] = { 0x0c, 0x00, 0x03, 0x06, 0x00, 0x06, 0x06, 0x00, 0x06, 0x03, 0x00, 0x0c, + 0x03, 0x00, 0x0c, 0x03, 0x00, 0x0c, 0x03, 0x00, 0x0c, 0x03, 0x00, 0x0c, + 0x03, 0x00, 0x0c, 0x06, 0x00, 0x06, 0x06, 0x00, 0x06, 0x0c, 0x00, 0x03 }; + +#define hash_gx_width 8 +#define hash_gx_height 12 +static unsigned char hash_gx_bits[] = { 0x00, 0x00, 0x48, 0x48, 0xfe, 0x24, 0x24, 0x7f, 0x12, 0x12, 0x00, 0x00 }; + +#define bracket_gx_width 12 +#define bracket_gx_height 12 +static unsigned char bracket_gx_bits[] = { 0x0f, 0x0f, 0x03, 0x0c, 0x03, 0x0c, 0x03, 0x0c, 0x03, 0x0c, 0x03, 0x0c, + 0x03, 0x0c, 0x03, 0x0c, 0x03, 0x0c, 0x03, 0x0c, 0x03, 0x0c, 0x0f, 0x0f }; + +#define under_gx_width 10 +#define under_gx_height 12 +static unsigned char under_gx_bits[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x03, 0xff, 0x03 }; + +#define prog_gx_width 24 +#define prog_gx_height 12 +static unsigned char prog_gx_bits[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xc3, 0x18, + 0x8c, 0x81, 0x31, 0xc6, 0x00, 0x63, 0x63, 0x00, 0xc6, 0xc6, 0x00, 0x63, + 0x8c, 0x81, 0x31, 0x18, 0xc3, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; + +#define quote_gx_width 12 +#define quote_gx_height 12 +static unsigned char quote_gx_bits[] = { 0x05, 0x0a, 0x05, 0x0a, 0x05, 0x0a, 0x05, 0x0a, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; + +#define curly_gx_width 14 +#define curly_gx_height 12 +static unsigned char curly_gx_bits[] = { 0x0c, 0x0c, 0x06, 0x18, 0x06, 0x18, 0x06, 0x18, 0x06, 0x18, 0x03, 0x30, + 0x06, 0x18, 0x06, 0x18, 0x06, 0x18, 0x06, 0x18, 0x06, 0x18, 0x0c, 0x0c }; + +#define colon_gx_width 8 +#define colon_gx_height 12 +static unsigned char colon_gx_bits[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0xc3, 0x00, 0x00, 0xc3, 0xc3, 0x00 }; + +#define angle_gx_width 12 +#define angle_gx_height 12 +static unsigned char angle_gx_bits[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x80, 0x01, 0xc0, 0x00, 0xe0, 0x01, + 0xb0, 0x03, 0x18, 0x03, 0x0c, 0x03, 0x06, 0x03, 0xff, 0x0f, 0xff, 0x0f }; + +#define pi_gx_width 10 +#define pi_gx_height 12 +static unsigned char pi_gx_bits[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xfe, 0x03, 0xff, 0x01, + 0xcc, 0x00, 0xcc, 0x00, 0xcc, 0x00, 0xcc, 0x00, 0xcc, 0x00, 0xcc, 0x00 }; + +#define nl_gx_width 18 +#define nl_gx_height 12 +static unsigned char nl_gx_bits[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xc0, 0x00, 0x03, 0xf0, 0x00, 0x03, + 0xfc, 0x00, 0x03, 0xff, 0xff, 0x03, 0xff, 0xff, 0x03, 0xfc, 0x00, 0x00, + 0xf0, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; + +#define comma_gx_width 3 +#define comma_gx_height 12 +static unsigned char comma_gx_bits[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x07, 0x07, 0x04, 0x04, 0x02 }; + +#define arrow_gx_width 18 +#define arrow_gx_height 12 +static unsigned char arrow_gx_bits[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x3c, 0x00, + 0x00, 0xfc, 0x00, 0xff, 0xff, 0x03, 0xff, 0xff, 0x03, 0x00, 0xfc, 0x00, + 0x00, 0x3c, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; + +#define equal_gx_width 8 +#define equal_gx_height 12 +static unsigned char equal_gx_bits[] = { 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00 }; + +#endif /* _UI_SMALL_FONT_H 1 */ diff --git a/src/ui_inner.h b/src/ui_inner.h new file mode 100644 index 0000000..d4397d4 --- /dev/null +++ b/src/ui_inner.h @@ -0,0 +1,180 @@ +#ifndef _UI_INNER_H +#define _UI_INNER_H 1 + +//#include "emulator.h" +#include "ui_bitmaps_misc.h" +#include "ui_bitmaps_small_font.h" +#include "ui_bitmaps_big_font.h" + +// Colors +/* SX GX */ +#define WHITE 0 /* #ffffff #ffffff */ +#define LEFT 1 /* #ffa600 #ffbaff */ +#define RIGHT 2 /* #00d2ff #00ffcc */ +#define BUT_TOP 3 /* #6d5d5d #646464 */ +#define BUTTON 4 /* #5a4d4d #585858 */ +#define BUT_BOT 5 /* #4c4141 #4a4a4a */ +#define LCD 6 /* #cadd5c #cadd5c */ +#define PIXEL 7 /* #000080 #000080 */ +#define PAD_TOP 8 /* #6d4e4e #585858 */ +#define PAD 9 /* #5a4040 #4a4a4a */ +#define PAD_BOT 10 /* #4c3636 #404040 */ +#define DISP_PAD_TOP 11 /* #9b7654 #808080 */ +#define DISP_PAD 12 /* #7c5e43 #68686e */ +#define DISP_PAD_BOT 13 /* #644b35 #54545a */ +#define LOGO 14 /* #cca96b #b0b0b8 */ +#define LOGO_BACK 15 /* #404040 #68686e */ +#define LABEL 16 /* #cab890 #f0f0f0 */ +#define FRAME 17 /* #000000 #000000 */ +#define UNDERLAY 18 /* #3c2a2a #68686e */ +#define BLACK 19 /* #000000 #000000 */ + +#define FIRST_COLOR WHITE +#define LAST_COLOR BLACK +#define NB_COLORS ( LAST_COLOR + 1 ) + +// Keys +#define HPKEY_A 0 +#define HPKEY_B 1 +#define HPKEY_C 2 +#define HPKEY_D 3 +#define HPKEY_E 4 +#define HPKEY_F 5 + +#define HPKEY_MTH 6 +#define HPKEY_PRG 7 +#define HPKEY_CST 8 +#define HPKEY_VAR 9 +#define HPKEY_UP 10 +#define HPKEY_NXT 11 + +#define HPKEY_QUOTE 12 +#define HPKEY_STO 13 +#define HPKEY_EVAL 14 +#define HPKEY_LEFT 15 +#define HPKEY_DOWN 16 +#define HPKEY_RIGHT 17 + +#define HPKEY_SIN 18 +#define HPKEY_COS 19 +#define HPKEY_TAN 20 +#define HPKEY_SQRT 21 +#define HPKEY_POWER 22 +#define HPKEY_INV 23 + +#define HPKEY_ENTER 24 +#define HPKEY_NEG 25 +#define HPKEY_EEX 26 +#define HPKEY_DEL 27 +#define HPKEY_BS 28 + +#define HPKEY_ALPHA 29 +#define HPKEY_7 30 +#define HPKEY_8 31 +#define HPKEY_9 32 +#define HPKEY_DIV 33 + +#define HPKEY_SHL 34 +#define HPKEY_4 35 +#define HPKEY_5 36 +#define HPKEY_6 37 +#define HPKEY_MUL 38 + +#define HPKEY_SHR 39 +#define HPKEY_1 40 +#define HPKEY_2 41 +#define HPKEY_3 42 +#define HPKEY_MINUS 43 + +#define HPKEY_ON 44 +#define HPKEY_0 45 +#define HPKEY_PERIOD 46 +#define HPKEY_SPC 47 +#define HPKEY_PLUS 48 + +#define FIRST_HPKEY HPKEY_A +#define LAST_HPKEY HPKEY_PLUS +#define NB_KEYS ( LAST_HPKEY + 1 ) + +#define KEYS_BUFFER_SIZE 9 + +// Annunciators +#define NB_ANNUNCIATORS 6 + +#define ANN_LEFT 0x81 +#define ANN_RIGHT 0x82 +#define ANN_ALPHA 0x84 +#define ANN_BATTERY 0x88 +#define ANN_BUSY 0x90 +#define ANN_IO 0xa0 + +/***********/ +/* typedef */ +/***********/ +typedef struct letter_t { + unsigned int w, h; + unsigned char* bits; +} letter_t; + +typedef struct color_t { + const char* name; + int r, g, b, a; + int mono_rgb; + int gray_rgb; +} color_t; + +typedef struct button_t { + const char* name; + + int x, y; + int w, h; + + int lc; + const char* label; + short font_size; + unsigned int lw, lh; + unsigned char* lb; + + const char* letter; + + const char* left; + short is_menu; + const char* right; + const char* sub; +} button_t; + +typedef struct ann_struct_t { + int x; + int y; + unsigned int width; + unsigned int height; + unsigned char* bits; +} ann_struct_t; + +/*************/ +/* variables */ +/*************/ +extern letter_t small_font[ 128 ]; +extern letter_t big_font[ 128 ]; + +extern color_t colors_sx[ NB_COLORS ]; +extern color_t colors_gx[ NB_COLORS ]; +#define COLORS ( opt_gx ? colors_gx : colors_sx ) + +extern button_t buttons_sx[ NB_KEYS ]; +extern button_t buttons_gx[ NB_KEYS ]; +#define BUTTONS ( opt_gx ? buttons_gx : buttons_sx ) + +extern ann_struct_t ann_tbl[ NB_ANNUNCIATORS ]; + +#define small_ascent 8 +#define small_descent 4 + +/*************/ +/* functions */ +/*************/ +extern int SmallTextWidth( const char* string, unsigned int length ); +extern int BigTextWidth( const char* string, unsigned int length ); +extern void ui_init_LCD( void ); + +#endif /* _UI_INNER_H */ diff --git a/src/ui_sdl2.c b/src/ui_sdl2.c new file mode 100644 index 0000000..87925d0 --- /dev/null +++ b/src/ui_sdl2.c @@ -0,0 +1,1308 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +bool opt_gx = true; +char* wire_name = "/dummy/wire"; +char* ir_name = "/dummy/ir"; + +//#include "config.h" + +#include "ui.h" +#include "ui_inner.h" + +#define KEYBOARD_HEIGHT ( BUTTONS[ LAST_HPKEY ].y + BUTTONS[ LAST_HPKEY ].h ) +#define KEYBOARD_WIDTH ( BUTTONS[ LAST_HPKEY ].x + BUTTONS[ LAST_HPKEY ].w ) + +#define TOP_SKIP 65 +#define SIDE_SKIP 20 +#define BOTTOM_SKIP 25 +#define DISP_KBD_SKIP 65 +#define KBD_UPLINE 25 + +#define DISPLAY_WIDTH ( 264 + 8 ) +#define DISPLAY_HEIGHT ( 128 + 16 + 8 ) +#define DISPLAY_OFFSET_X ( SIDE_SKIP + ( 286 - DISPLAY_WIDTH ) / 2 ) +#define DISPLAY_OFFSET_Y TOP_SKIP + +#define DISP_FRAME 8 + +#define KEYBOARD_OFFSET_X SIDE_SKIP +#define KEYBOARD_OFFSET_Y ( TOP_SKIP + DISPLAY_HEIGHT + DISP_KBD_SKIP ) + +/***********/ +/* typedef */ +/***********/ +typedef struct on_off_sdl_textures_struct_t { + SDL_Texture* up; + SDL_Texture* down; +} on_off_sdl_textures_struct_t; + +typedef struct hpkey_t { + int code; + bool pressed; +} hpkey_t; + +typedef struct { + char* progname; + + bool verbose; + + bool leave_shift_keys; + bool inhibit_shutdown; + + bool mono; + bool gray; + + /* sdl */ + bool hide_chrome; + bool show_ui_fullscreen; + double scale; +} config_t; + +typedef struct display_t { + int on; + + long disp_start; + long disp_end; + + int offset; + int lines; + int nibs_per_line; + + int contrast; + + long menu_start; + long menu_end; +} display_t; + +typedef struct saturn_t { + word_8 annunc; +} saturn_t; + +/*************/ +/* variables */ +/*************/ +config_t config = { + .progname = ( char* )"hp48-sdl2", + + .verbose = false, + + .leave_shift_keys = false, + .inhibit_shutdown = false, + + .mono = false, + .gray = false, + + /* sdl */ + .hide_chrome = false, + .show_ui_fullscreen = false, + .scale = 1.0, +}; + +hpkey_t keyboard[ 49 ] = { + /* From top left to bottom right */ + {0x14, 0}, + {0x84, 0}, + {0x83, 0}, + {0x82, 0}, + {0x81, 0}, + {0x80, 0}, + + {0x24, 0}, + {0x74, 0}, + {0x73, 0}, + {0x72, 0}, + {0x71, 0}, + {0x70, 0}, + + {0x04, 0}, + {0x64, 0}, + {0x63, 0}, + {0x62, 0}, + {0x61, 0}, + {0x60, 0}, + + {0x34, 0}, + {0x54, 0}, + {0x53, 0}, + {0x52, 0}, + {0x51, 0}, + {0x50, 0}, + + {0x44, 0}, + {0x43, 0}, + {0x42, 0}, + {0x41, 0}, + {0x40, 0}, + + {0x35, 0}, + {0x33, 0}, + {0x32, 0}, + {0x31, 0}, + {0x30, 0}, + + {0x25, 0}, + {0x23, 0}, + {0x22, 0}, + {0x21, 0}, + {0x20, 0}, + + {0x15, 0}, + {0x13, 0}, + {0x12, 0}, + {0x11, 0}, + {0x10, 0}, + + {0x8000, 0}, + {0x03, 0}, + {0x02, 0}, + {0x01, 0}, + {0x00, 0}, +}; + +saturn_t saturn; +display_t display; + +int annunciators_bits[ NB_ANNUNCIATORS ] = { ANN_LEFT, ANN_RIGHT, ANN_ALPHA, ANN_BATTERY, ANN_BUSY, ANN_IO }; + +static int display_offset_x, display_offset_y; + +color_t colors[ NB_COLORS ]; +static on_off_sdl_textures_struct_t buttons_textures[ NB_KEYS ]; +static on_off_sdl_textures_struct_t annunciators_textures[ NB_ANNUNCIATORS ]; + +static SDL_Window* window; +static SDL_Renderer* renderer; +static SDL_Texture* main_texture; + +/****************************/ +/* functions implementation */ +/****************************/ +int read_nibble( long addr ) +{ + return 1; +} + +void press_key( int hpkey ) +{ + // Check not already pressed (may be important: avoids a useless do_kbd_int) + if ( keyboard[ hpkey ].pressed ) + return; + + keyboard[ hpkey ].pressed = true; +} + +void release_key( int hpkey ) +{ + // Check not already released (not critical) + if ( !keyboard[ hpkey ].pressed ) + return; + + keyboard[ hpkey ].pressed = false; +} + +static inline unsigned color2bgra( int color ) +{ + return 0xff000000 | ( colors[ color ].r << 16 ) | ( colors[ color ].g << 8 ) | colors[ color ].b; +} + +/* + Create a SDL_Texture from binary bitmap data +*/ +static SDL_Texture* bitmap_to_texture( unsigned int w, unsigned int h, unsigned char* data, int color_fg, int color_bg ) +{ + SDL_Surface* surf = SDL_CreateRGBSurface( SDL_SWSURFACE, w, h, 32, 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000 ); + + SDL_LockSurface( surf ); + + unsigned char* pixels = ( unsigned char* )surf->pixels; + unsigned int pitch = surf->pitch; + unsigned byteperline = w / 8; + if ( byteperline * 8 != w ) + byteperline++; + + for ( unsigned int y = 0; y < h; y++ ) { + unsigned int* lineptr = ( unsigned int* )( pixels + y * pitch ); + for ( unsigned int x = 0; x < w; x++ ) { + // Address the correct byte + char c = data[ y * byteperline + ( x >> 3 ) ]; + // Look for the bit in that byte + char b = c & ( 1 << ( x & 7 ) ); + + lineptr[ x ] = color2bgra( b ? color_fg : color_bg ); + } + } + + SDL_UnlockSurface( surf ); + + SDL_Texture* tex = SDL_CreateTextureFromSurface( renderer, surf ); + SDL_FreeSurface( surf ); + + return tex; +} + +static void __draw_pixel( int x, int y, int color ) +{ + SDL_SetRenderDrawColor( renderer, colors[ color ].r, colors[ color ].g, colors[ color ].b, colors[ color ].a ); + SDL_RenderDrawPoint( renderer, x, y ); +} + +static void __draw_line( int x1, int y1, int x2, int y2, int color ) +{ + SDL_SetRenderDrawColor( renderer, colors[ color ].r, colors[ color ].g, colors[ color ].b, colors[ color ].a ); + SDL_RenderDrawLine( renderer, x1, y1, x2, y2 ); +} + +static void __draw_rect( int x, int y, int w, int h, int color ) +{ + SDL_Rect rect; + rect.x = x; + rect.y = y; + rect.w = w; + rect.h = h; + + SDL_SetRenderDrawColor( renderer, colors[ color ].r, colors[ color ].g, colors[ color ].b, colors[ color ].a ); + SDL_RenderFillRect( renderer, &rect ); +} + +static void __draw_texture( int x, int y, unsigned int w, unsigned int h, SDL_Texture* texture ) +{ + SDL_Rect drect; + drect.x = x; + drect.y = y; + drect.w = w; + drect.h = h; + + SDL_RenderCopy( renderer, texture, NULL, &drect ); +} + +static void __draw_bitmap( int x, int y, unsigned int w, unsigned int h, unsigned char* data, int color_fg, int color_bg ) +{ + __draw_texture( x, y, w, h, bitmap_to_texture( w, h, data, color_fg, color_bg ) ); +} + +static void write_with_small_font( int x, int y, const char* string, int color_fg, int color_bg ) +{ + int c; + for ( unsigned int i = 0; i < strlen( string ); i++ ) { + c = ( int )string[ i ]; + if ( small_font[ c ].h != 0 ) + __draw_bitmap( x - 1, ( int )( y - small_font[ c ].h ), small_font[ c ].w, small_font[ c ].h, small_font[ c ].bits, color_fg, + color_bg ); + + x += SmallTextWidth( &string[ i ], 1 ); + } +} + +static void write_with_big_font( int x, int y, const char* string, int color_fg, int color_bg ) +{ + int c; + for ( unsigned int i = 0; i < strlen( string ); i++ ) { + c = ( int )string[ i ]; + if ( big_font[ c ].h != 0 ) + __draw_bitmap( x, y + ( big_font[ c ].h > 10 ? 0 : 2 ), big_font[ c ].w, big_font[ c ].h, big_font[ c ].bits, color_fg, + color_bg ); + + x += BigTextWidth( &string[ i ], 1 ) - 1; + } +} + +static void colors_setup( void ) +{ + // Adjust the LCD color according to the contrast + int contrast = 0x10;//display.contrast; + if ( contrast < 0x3 ) + contrast = 0x3; + if ( contrast > 0x13 ) + contrast = 0x13; + + for ( unsigned i = FIRST_COLOR; i < LAST_COLOR; i++ ) { + colors[ i ] = COLORS[ i ]; + if ( config.mono ) { + colors[ i ].r = colors[ i ].mono_rgb; + colors[ i ].g = colors[ i ].mono_rgb; + colors[ i ].b = colors[ i ].mono_rgb; + } else if ( config.gray ) { + colors[ i ].r = colors[ i ].gray_rgb; + colors[ i ].g = colors[ i ].gray_rgb; + colors[ i ].b = colors[ i ].gray_rgb; + } + + if ( !config.mono && i == PIXEL ) { + colors[ i ].r = ( 0x13 - contrast ) * ( colors[ LCD ].r / 0x10 ); + colors[ i ].g = ( 0x13 - contrast ) * ( colors[ LCD ].g / 0x10 ); + colors[ i ].b = 128 - ( ( 0x13 - contrast ) * ( ( 128 - colors[ LCD ].b ) / 0x10 ) ); + } + } +} + +// This should be called once to setup the surfaces. Calling it multiple +// times is fine, it won't do anything on subsequent calls. +static void create_annunciators_textures( void ) +{ + for ( int i = 0; i < NB_ANNUNCIATORS; i++ ) { + annunciators_textures[ i ].up = bitmap_to_texture( ann_tbl[ i ].width, ann_tbl[ i ].height, ann_tbl[ i ].bits, PIXEL, LCD ); + annunciators_textures[ i ].down = bitmap_to_texture( ann_tbl[ i ].width, ann_tbl[ i ].height, ann_tbl[ i ].bits, LCD, LCD ); + } +} + +// Find which key is pressed, if any. +// Returns -1 is no key is pressed +static int mouse_click_to_hpkey( unsigned int x, unsigned int y ) +{ + /* return immediatly if the click isn't even in the keyboard area */ + if ( y < KEYBOARD_OFFSET_Y ) + return -1; + + int row = ( y - KEYBOARD_OFFSET_Y ) / ( KEYBOARD_HEIGHT / 9 ); + int column; + switch ( row ) { + case 0: + case 1: + case 2: + case 3: + column = ( x - KEYBOARD_OFFSET_X ) / ( KEYBOARD_WIDTH / 6 ); + return ( row * 6 ) + column; + case 4: /* with [ENTER] key */ + column = ( ( x - KEYBOARD_OFFSET_X ) / ( KEYBOARD_WIDTH / 5 ) ) - 1; + if ( column < 0 ) + column = 0; + return ( 4 * 6 ) + column; + case 5: + case 6: + case 7: + case 8: + column = ( x - KEYBOARD_OFFSET_X ) / ( KEYBOARD_WIDTH / 5 ); + return ( 4 * 6 ) + 5 + ( ( row - 5 ) * 5 ) + column; + + default: + return -1; + } + + return -1; +} + +// Map the keyboard keys to the HP keys +// Returns -1 if there is no mapping +static int sdlkey_to_hpkey( SDL_Keycode k ) +{ + switch ( k ) { + case SDLK_0: + return HPKEY_0; + case SDLK_1: + return HPKEY_1; + case SDLK_2: + return HPKEY_2; + case SDLK_3: + return HPKEY_3; + case SDLK_4: + return HPKEY_4; + case SDLK_5: + return HPKEY_5; + case SDLK_6: + return HPKEY_6; + case SDLK_7: + return HPKEY_7; + case SDLK_8: + return HPKEY_8; + case SDLK_9: + return HPKEY_9; + case SDLK_KP_0: + return HPKEY_0; + case SDLK_KP_1: + return HPKEY_1; + case SDLK_KP_2: + return HPKEY_2; + case SDLK_KP_3: + return HPKEY_3; + case SDLK_KP_4: + return HPKEY_4; + case SDLK_KP_5: + return HPKEY_5; + case SDLK_KP_6: + return HPKEY_6; + case SDLK_KP_7: + return HPKEY_7; + case SDLK_KP_8: + return HPKEY_8; + case SDLK_KP_9: + return HPKEY_9; + case SDLK_a: + return HPKEY_A; + case SDLK_b: + return HPKEY_B; + case SDLK_c: + return HPKEY_C; + case SDLK_d: + return HPKEY_D; + case SDLK_e: + return HPKEY_E; + case SDLK_f: + return HPKEY_F; + case SDLK_g: + return HPKEY_MTH; + case SDLK_h: + return HPKEY_PRG; + case SDLK_i: + return HPKEY_CST; + case SDLK_j: + return HPKEY_VAR; + case SDLK_k: + return HPKEY_UP; + case SDLK_UP: + return HPKEY_UP; + case SDLK_l: + return HPKEY_NXT; + case SDLK_m: + return HPKEY_QUOTE; + case SDLK_n: + return HPKEY_STO; + case SDLK_o: + return HPKEY_EVAL; + case SDLK_p: + return HPKEY_LEFT; + case SDLK_LEFT: + return HPKEY_LEFT; + case SDLK_q: + return HPKEY_DOWN; + case SDLK_DOWN: + return HPKEY_DOWN; + case SDLK_r: + return HPKEY_RIGHT; + case SDLK_RIGHT: + return HPKEY_RIGHT; + case SDLK_s: + return HPKEY_SIN; + case SDLK_t: + return HPKEY_COS; + case SDLK_u: + return HPKEY_TAN; + case SDLK_v: + return HPKEY_SQRT; + case SDLK_w: + return HPKEY_POWER; + case SDLK_x: + return HPKEY_INV; + case SDLK_y: + return HPKEY_NEG; + case SDLK_z: + return HPKEY_EEX; + case SDLK_SPACE: + return HPKEY_SPC; + case SDLK_F1: + case SDLK_RETURN: + case SDLK_KP_ENTER: + return HPKEY_ENTER; + case SDLK_BACKSPACE: + return HPKEY_BS; + case SDLK_DELETE: + return HPKEY_DEL; + case SDLK_PERIOD: + return HPKEY_PERIOD; + case SDLK_KP_PERIOD: + return HPKEY_PERIOD; + case SDLK_PLUS: + return HPKEY_PLUS; + case SDLK_KP_PLUS: + return HPKEY_PLUS; + case SDLK_MINUS: + return HPKEY_MINUS; + case SDLK_KP_MINUS: + return HPKEY_MINUS; + case SDLK_ASTERISK: + return HPKEY_MUL; + case SDLK_KP_MULTIPLY: + return HPKEY_MUL; + case SDLK_SLASH: + return HPKEY_DIV; + case SDLK_KP_DIVIDE: + return HPKEY_DIV; + case SDLK_F5: + case SDLK_ESCAPE: + return HPKEY_ON; + case SDLK_LSHIFT: + if ( !config.leave_shift_keys ) + return HPKEY_SHL; + break; + case SDLK_RSHIFT: + if ( !config.leave_shift_keys ) + return HPKEY_SHR; + break; + case SDLK_F2: + case SDLK_RCTRL: + return HPKEY_SHL; + case SDLK_F3: + case SDLK_LCTRL: + return HPKEY_SHR; + case SDLK_F4: + case SDLK_LALT: + case SDLK_RALT: + return HPKEY_ALPHA; + case SDLK_F7: + case SDLK_F10: + // please_exit = true; + close_and_exit(); + return -1; + default: + return -1; + } + + return -1; +} + +static void _draw_bezel( unsigned int cut, unsigned int offset_y, int keypad_width, int keypad_height ) +{ + // bottom lines + __draw_line( 1, keypad_height - 1, keypad_width - 1, keypad_height - 1, PAD_TOP ); + __draw_line( 2, keypad_height - 2, keypad_width - 2, keypad_height - 2, PAD_TOP ); + + // right lines + __draw_line( keypad_width - 1, keypad_height - 1, keypad_width - 1, cut, PAD_TOP ); + __draw_line( keypad_width - 2, keypad_height - 2, keypad_width - 2, cut, PAD_TOP ); + + // right lines + __draw_line( keypad_width - 1, cut - 1, keypad_width - 1, 1, DISP_PAD_TOP ); + __draw_line( keypad_width - 2, cut - 1, keypad_width - 2, 2, DISP_PAD_TOP ); + + // top lines + __draw_line( 0, 0, keypad_width - 2, 0, DISP_PAD_BOT ); + __draw_line( 1, 1, keypad_width - 3, 1, DISP_PAD_BOT ); + + // left lines + __draw_line( 0, cut - 1, 0, 0, DISP_PAD_BOT ); + __draw_line( 1, cut - 1, 1, 1, DISP_PAD_BOT ); + + // left lines + __draw_line( 0, keypad_height - 2, 0, cut, PAD_BOT ); + __draw_line( 1, keypad_height - 3, 1, cut, PAD_BOT ); + + // lower the menu BUTTONS + + // bottom lines + __draw_line( 3, keypad_height - 3, keypad_width - 3, keypad_height - 3, PAD_TOP ); + __draw_line( 4, keypad_height - 4, keypad_width - 4, keypad_height - 4, PAD_TOP ); + + // right lines + __draw_line( keypad_width - 3, keypad_height - 3, keypad_width - 3, cut, PAD_TOP ); + __draw_line( keypad_width - 4, keypad_height - 4, keypad_width - 4, cut, PAD_TOP ); + + // right lines + __draw_line( keypad_width - 3, cut - 1, keypad_width - 3, offset_y - ( KBD_UPLINE - 1 ), DISP_PAD_TOP ); + __draw_line( keypad_width - 4, cut - 1, keypad_width - 4, offset_y - ( KBD_UPLINE - 2 ), DISP_PAD_TOP ); + + // top lines + __draw_line( 2, offset_y - ( KBD_UPLINE - 0 ), keypad_width - 4, offset_y - ( KBD_UPLINE - 0 ), DISP_PAD_BOT ); + __draw_line( 3, offset_y - ( KBD_UPLINE - 1 ), keypad_width - 5, offset_y - ( KBD_UPLINE - 1 ), DISP_PAD_BOT ); + + // left lines + __draw_line( 2, cut - 1, 2, offset_y - ( KBD_UPLINE - 1 ), DISP_PAD_BOT ); + __draw_line( 3, cut - 1, 3, offset_y - ( KBD_UPLINE - 2 ), DISP_PAD_BOT ); + + // left lines + __draw_line( 2, keypad_height - 4, 2, cut, PAD_BOT ); + __draw_line( 3, keypad_height - 5, 3, cut, PAD_BOT ); + + // lower the keyboard + + // bottom lines + __draw_line( 5, keypad_height - 5, keypad_width - 3, keypad_height - 5, PAD_TOP ); + __draw_line( 6, keypad_height - 6, keypad_width - 4, keypad_height - 6, PAD_TOP ); + + // right lines + __draw_line( keypad_width - 5, keypad_height - 5, keypad_width - 5, cut + 1, PAD_TOP ); + __draw_line( keypad_width - 6, keypad_height - 6, keypad_width - 6, cut + 2, PAD_TOP ); + + // top lines + __draw_line( 4, cut, keypad_width - 6, cut, DISP_PAD_BOT ); + __draw_line( 5, cut + 1, keypad_width - 7, cut + 1, DISP_PAD_BOT ); + + // left lines + __draw_line( 4, keypad_height - 6, 4, cut + 1, PAD_BOT ); + __draw_line( 5, keypad_height - 7, 5, cut + 2, PAD_BOT ); + + // round off the bottom edge + __draw_line( keypad_width - 7, keypad_height - 7, keypad_width - 7, keypad_height - 14, PAD_TOP ); + __draw_line( keypad_width - 8, keypad_height - 8, keypad_width - 8, keypad_height - 11, PAD_TOP ); + __draw_line( keypad_width - 7, keypad_height - 7, keypad_width - 14, keypad_height - 7, PAD_TOP ); + __draw_line( keypad_width - 7, keypad_height - 8, keypad_width - 11, keypad_height - 8, PAD_TOP ); + __draw_pixel( keypad_width - 9, keypad_height - 9, PAD_TOP ); + + __draw_line( 7, keypad_height - 7, 13, keypad_height - 7, PAD_TOP ); + __draw_line( 8, keypad_height - 8, 10, keypad_height - 8, PAD_TOP ); + + __draw_line( 6, keypad_height - 8, 6, keypad_height - 14, PAD_BOT ); + __draw_line( 7, keypad_height - 9, 7, keypad_height - 11, PAD_BOT ); +} + +static void _draw_header( void ) +{ + int x = display_offset_x; + int y; + + // insert the HP Logo + if ( opt_gx ) + x -= 6; + + __draw_bitmap( x, 10, hp_width, hp_height, hp_bitmap, LOGO, LOGO_BACK ); + + if ( !opt_gx ) { + __draw_line( display_offset_x, 9, display_offset_x + hp_width - 1, 9, FRAME ); + __draw_line( display_offset_x - 1, 10, display_offset_x - 1, 10 + hp_height - 1, FRAME ); + __draw_line( display_offset_x, 10 + hp_height, display_offset_x + hp_width - 1, 10 + hp_height, FRAME ); + __draw_line( display_offset_x + hp_width, 10, display_offset_x + hp_width, 10 + hp_height - 1, FRAME ); + } + + // write the name of it + if ( opt_gx ) { + x = display_offset_x + DISPLAY_WIDTH - gx_128K_ram_width + gx_128K_ram_x_hot + 2; + y = 10 + gx_128K_ram_y_hot; + __draw_bitmap( x, y, gx_128K_ram_width, gx_128K_ram_height, gx_128K_ram_bitmap, LABEL, DISP_PAD ); + + x = display_offset_x + hp_width; + y = hp_height + 8 - hp48gx_height; + __draw_bitmap( x, y, hp48gx_width, hp48gx_height, hp48gx_bitmap, LOGO, DISP_PAD ); + + x = display_offset_x + DISPLAY_WIDTH - gx_128K_ram_width + gx_green_x_hot + 2; + y = 10 + gx_green_y_hot; + __draw_bitmap( x, y, gx_green_width, gx_green_height, gx_green_bitmap, RIGHT, DISP_PAD ); + + x = display_offset_x + DISPLAY_WIDTH - gx_128K_ram_width + gx_silver_x_hot + 2; + y = 10 + gx_silver_y_hot; + __draw_bitmap( x, y, gx_silver_width, gx_silver_height, gx_silver_bitmap, LOGO, + 0 ); // Background transparent: draw only silver line + } else { + x = display_offset_x; + y = TOP_SKIP - DISP_FRAME - hp48sx_height - 3; + __draw_bitmap( x, y, hp48sx_width, hp48sx_height, hp48sx_bitmap, LOGO, DISP_PAD ); + + x = display_offset_x + DISPLAY_WIDTH - 1 - science_width; + y = TOP_SKIP - DISP_FRAME - science_height - 4; + __draw_bitmap( x, y, science_width, science_height, science_bitmap, LOGO, DISP_PAD ); + } +} + +static SDL_Texture* create_button_texture( int hpkey, bool is_up ) +{ + bool is_down = !is_up; + int x, y; + int on_key_offset_y = ( hpkey == HPKEY_ON ) ? 1 : 0; + SDL_Texture* texture = + SDL_CreateTexture( renderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, BUTTONS[ hpkey ].w, BUTTONS[ hpkey ].h ); + SDL_SetRenderTarget( renderer, texture ); + + // Fill the button and outline + // fix outer-corners color + int outer_color = PAD; + if ( BUTTONS[ hpkey ].is_menu ) + outer_color = UNDERLAY; + if ( hpkey < HPKEY_MTH ) + outer_color = DISP_PAD; + __draw_rect( 0, 0, BUTTONS[ hpkey ].w, BUTTONS[ hpkey ].h, outer_color ); + __draw_rect( 1, 1, BUTTONS[ hpkey ].w - 2, BUTTONS[ hpkey ].h - 2, BUTTON ); + + // draw label in button + if ( BUTTONS[ hpkey ].label != ( char* )0 ) { + /* Button has a text label */ + x = strlen( BUTTONS[ hpkey ].label ) - 1; + x += ( ( BUTTONS[ hpkey ].w - BigTextWidth( BUTTONS[ hpkey ].label, strlen( BUTTONS[ hpkey ].label ) ) ) / 2 ); + y = ( BUTTONS[ hpkey ].h + 1 ) / 2 - 6; + if ( is_down ) + y -= 1; + + write_with_big_font( x, y, BUTTONS[ hpkey ].label, WHITE, BUTTON ); + } else if ( BUTTONS[ hpkey ].lw != 0 ) { + /* Button has a texture */ + x = ( 1 + BUTTONS[ hpkey ].w - BUTTONS[ hpkey ].lw ) / 2; + y = ( 1 + BUTTONS[ hpkey ].h - BUTTONS[ hpkey ].lh ) / 2; + if ( is_up ) + y += 1; + + __draw_bitmap( x, y, BUTTONS[ hpkey ].lw, BUTTONS[ hpkey ].lh, BUTTONS[ hpkey ].lb, BUTTONS[ hpkey ].lc, BUTTON ); + } + + // draw edge of button + // top + __draw_line( 1, 1, BUTTONS[ hpkey ].w - 2, 1, BUT_TOP ); + __draw_line( 2, 2, BUTTONS[ hpkey ].w - 3, 2, BUT_TOP ); + if ( is_up ) { + __draw_line( 3, 3, BUTTONS[ hpkey ].w - 4, 3, BUT_TOP ); + __draw_line( 4, 4, BUTTONS[ hpkey ].w - 5, 4, BUT_TOP ); + } + // top-left + __draw_pixel( 4, 3 + ( is_up ? 2 : 0 ), BUT_TOP ); + // left + __draw_line( 1, 1, 1, BUTTONS[ hpkey ].h - 2, BUT_TOP ); + __draw_line( 2, 2, 2, BUTTONS[ hpkey ].h - 3, BUT_TOP ); + __draw_line( 3, 3, 3, BUTTONS[ hpkey ].h - 4, BUT_TOP ); + // right + __draw_line( BUTTONS[ hpkey ].w - 2, BUTTONS[ hpkey ].h - 2, BUTTONS[ hpkey ].w - 2, 3, BUT_BOT ); + __draw_line( BUTTONS[ hpkey ].w - 3, BUTTONS[ hpkey ].h - 3, BUTTONS[ hpkey ].w - 3, 4, BUT_BOT ); + __draw_line( BUTTONS[ hpkey ].w - 4, BUTTONS[ hpkey ].h - 4, BUTTONS[ hpkey ].w - 4, 5, BUT_BOT ); + __draw_pixel( BUTTONS[ hpkey ].w - 5, BUTTONS[ hpkey ].h - 4, BUT_BOT ); + // bottom + __draw_line( 3, BUTTONS[ hpkey ].h - 2, BUTTONS[ hpkey ].w - 2, BUTTONS[ hpkey ].h - 2, BUT_BOT ); + __draw_line( 4, BUTTONS[ hpkey ].h - 3, BUTTONS[ hpkey ].w - 3, BUTTONS[ hpkey ].h - 3, BUT_BOT ); + + // draw black frame around button + // top + __draw_line( 2, 0, BUTTONS[ hpkey ].w - 3, 0, FRAME ); + // left + __draw_line( 0, 2, 0, BUTTONS[ hpkey ].h - 3, FRAME ); + // right + __draw_line( BUTTONS[ hpkey ].w - 1, BUTTONS[ hpkey ].h - 3, BUTTONS[ hpkey ].w - 1, 2, FRAME ); + // bottom + __draw_line( 2, BUTTONS[ hpkey ].h - 1, BUTTONS[ hpkey ].w - 3, BUTTONS[ hpkey ].h - 1, FRAME ); + // top-left + __draw_pixel( 1, 1, FRAME ); + // top-right + __draw_pixel( BUTTONS[ hpkey ].w - 2, 1, FRAME ); + // bottom-left + __draw_pixel( 1, BUTTONS[ hpkey ].h - 2, FRAME ); + // bottom-right + __draw_pixel( BUTTONS[ hpkey ].w - 2, BUTTONS[ hpkey ].h - 2, FRAME ); + if ( hpkey == HPKEY_ON ) { + // top + __draw_line( 2, 1, BUTTONS[ hpkey ].w - 3, 1, FRAME ); + // top-left + __draw_pixel( 1, 1 + on_key_offset_y, FRAME ); + // top-right + __draw_pixel( BUTTONS[ hpkey ].w - 2, 1 + on_key_offset_y, FRAME ); + } + + if ( is_down ) { + // top + __draw_line( 2, 1 + on_key_offset_y, BUTTONS[ hpkey ].w - 3, 1 + on_key_offset_y, FRAME ); + // left + __draw_line( 1, 2, 1, BUTTONS[ hpkey ].h, FRAME ); + // right + __draw_line( BUTTONS[ hpkey ].w - 2, 2, BUTTONS[ hpkey ].w - 2, BUTTONS[ hpkey ].h, FRAME ); + // top-left + __draw_pixel( 2, 2 + on_key_offset_y, FRAME ); + // top-right + __draw_pixel( BUTTONS[ hpkey ].w - 3, 2 + on_key_offset_y, FRAME ); + } + + return texture; +} + +static void create_buttons_textures( void ) +{ + for ( int i = FIRST_HPKEY; i <= LAST_HPKEY; i++ ) { + buttons_textures[ i ].up = create_button_texture( i, true ); + buttons_textures[ i ].down = create_button_texture( i, false ); + } + + // Give back to renderer as it was + SDL_SetRenderTarget( renderer, main_texture ); +} + +static void _draw_key( int hpkey ) +{ + __draw_texture( KEYBOARD_OFFSET_X + BUTTONS[ hpkey ].x, KEYBOARD_OFFSET_Y + BUTTONS[ hpkey ].y, BUTTONS[ hpkey ].w, BUTTONS[ hpkey ].h, + keyboard[ hpkey ].pressed ? buttons_textures[ hpkey ].down : buttons_textures[ hpkey ].up ); +} + +static void _draw_keypad( void ) +{ + int x, y; + int pw = opt_gx ? 58 : 44; + int ph = opt_gx ? 48 : 9; + int left_label_width, right_label_width; + int space_char_width = SmallTextWidth( " ", 1 ); + int total_top_labels_width; + + for ( int i = FIRST_HPKEY; i <= LAST_HPKEY; i++ ) { + // Background + if ( BUTTONS[ i ].is_menu ) { + x = KEYBOARD_OFFSET_X + BUTTONS[ i ].x; + y = KEYBOARD_OFFSET_Y + BUTTONS[ i ].y - small_ascent - small_descent; + + if ( opt_gx ) { + x -= 6; + y -= 6; + } else + x += ( BUTTONS[ i ].w - pw ) / 2; + + __draw_rect( x, y, pw, ph, UNDERLAY ); + } + + // Letter (small character bottom right of key) + if ( BUTTONS[ i ].letter != ( char* )0 ) { + x = KEYBOARD_OFFSET_X + BUTTONS[ i ].x + BUTTONS[ i ].w; + y = KEYBOARD_OFFSET_Y + BUTTONS[ i ].y + BUTTONS[ i ].h; + + if ( opt_gx ) { + x += 3; + y += 1; + } else { + x -= SmallTextWidth( BUTTONS[ i ].letter, 1 ) / 2 + 5; + y -= 2; + } + + write_with_small_font( x, y, BUTTONS[ i ].letter, WHITE, ( i < HPKEY_MTH ) ? DISP_PAD : PAD ); + } + + // Bottom label: the only one is the cancel button + if ( BUTTONS[ i ].sub != ( char* )0 ) { + x = KEYBOARD_OFFSET_X + BUTTONS[ i ].x + + ( 1 + BUTTONS[ i ].w - SmallTextWidth( BUTTONS[ i ].sub, strlen( BUTTONS[ i ].sub ) ) ) / 2; + y = KEYBOARD_OFFSET_Y + BUTTONS[ i ].y + BUTTONS[ i ].h + small_ascent + 2; + write_with_small_font( x, y, BUTTONS[ i ].sub, WHITE, PAD ); + } + + total_top_labels_width = 0; + // Draw the left labels + if ( BUTTONS[ i ].left != ( char* )0 ) { + x = KEYBOARD_OFFSET_X + BUTTONS[ i ].x; + y = KEYBOARD_OFFSET_Y + BUTTONS[ i ].y - small_descent; + + left_label_width = SmallTextWidth( BUTTONS[ i ].left, strlen( BUTTONS[ i ].left ) ); + total_top_labels_width = left_label_width; + + if ( BUTTONS[ i ].right != ( char* )0 ) { + // label to the left + right_label_width = SmallTextWidth( BUTTONS[ i ].right, strlen( BUTTONS[ i ].right ) ); + total_top_labels_width += space_char_width + right_label_width; + } + + x += ( 1 + BUTTONS[ i ].w - total_top_labels_width ) / 2; + + write_with_small_font( x, y, BUTTONS[ i ].left, LEFT, BUTTONS[ i ].is_menu ? UNDERLAY : PAD ); + } + + // draw the right labels ( .is_menu never have one ) + if ( BUTTONS[ i ].right != ( char* )0 ) { + x = KEYBOARD_OFFSET_X + BUTTONS[ i ].x; + y = KEYBOARD_OFFSET_Y + BUTTONS[ i ].y - small_descent; + + if ( BUTTONS[ i ].left == ( char* )0 ) { + right_label_width = SmallTextWidth( BUTTONS[ i ].right, strlen( BUTTONS[ i ].right ) ); + total_top_labels_width = right_label_width; + } else + x += space_char_width + left_label_width; + + x += ( 1 + BUTTONS[ i ].w - total_top_labels_width ) / 2; + + write_with_small_font( x, y, BUTTONS[ i ].right, RIGHT, PAD ); + } + } + + for ( int i = FIRST_HPKEY; i <= LAST_HPKEY; i++ ) + _draw_key( i ); +} + +static void _draw_bezel_LCD( void ) +{ + for ( int i = 0; i < DISP_FRAME; i++ ) { + __draw_line( display_offset_x - i, display_offset_y + DISPLAY_HEIGHT + 2 * i, display_offset_x + DISPLAY_WIDTH + i, + display_offset_y + DISPLAY_HEIGHT + 2 * i, DISP_PAD_TOP ); + __draw_line( display_offset_x - i, display_offset_y + DISPLAY_HEIGHT + 2 * i + 1, display_offset_x + DISPLAY_WIDTH + i, + display_offset_y + DISPLAY_HEIGHT + 2 * i + 1, DISP_PAD_TOP ); + __draw_line( display_offset_x + DISPLAY_WIDTH + i, display_offset_y - i, display_offset_x + DISPLAY_WIDTH + i, + display_offset_y + DISPLAY_HEIGHT + 2 * i, DISP_PAD_TOP ); + + __draw_line( display_offset_x - i - 1, display_offset_y - i - 1, display_offset_x + DISPLAY_WIDTH + i - 1, display_offset_y - i - 1, + DISP_PAD_BOT ); + __draw_line( display_offset_x - i - 1, display_offset_y - i - 1, display_offset_x - i - 1, + display_offset_y + DISPLAY_HEIGHT + 2 * i - 1, DISP_PAD_BOT ); + } + + // round off corners + __draw_line( display_offset_x - DISP_FRAME, display_offset_y - DISP_FRAME, display_offset_x - DISP_FRAME + 3, + display_offset_y - DISP_FRAME, DISP_PAD ); + __draw_line( display_offset_x - DISP_FRAME, display_offset_y - DISP_FRAME, display_offset_x - DISP_FRAME, + display_offset_y - DISP_FRAME + 3, DISP_PAD ); + __draw_pixel( display_offset_x - DISP_FRAME + 1, display_offset_y - DISP_FRAME + 1, DISP_PAD ); + + __draw_line( display_offset_x + DISPLAY_WIDTH + DISP_FRAME - 4, display_offset_y - DISP_FRAME, + display_offset_x + DISPLAY_WIDTH + DISP_FRAME - 1, display_offset_y - DISP_FRAME, DISP_PAD ); + __draw_line( display_offset_x + DISPLAY_WIDTH + DISP_FRAME - 1, display_offset_y - DISP_FRAME, + display_offset_x + DISPLAY_WIDTH + DISP_FRAME - 1, display_offset_y - DISP_FRAME + 3, DISP_PAD ); + __draw_pixel( display_offset_x + DISPLAY_WIDTH + DISP_FRAME - 2, display_offset_y - DISP_FRAME + 1, DISP_PAD ); + + __draw_line( display_offset_x - DISP_FRAME, display_offset_y + DISPLAY_HEIGHT + 2 * DISP_FRAME - 4, display_offset_x - DISP_FRAME, + display_offset_y + DISPLAY_HEIGHT + 2 * DISP_FRAME - 1, DISP_PAD ); + __draw_line( display_offset_x - DISP_FRAME, display_offset_y + DISPLAY_HEIGHT + 2 * DISP_FRAME - 1, display_offset_x - DISP_FRAME + 3, + display_offset_y + DISPLAY_HEIGHT + 2 * DISP_FRAME - 1, DISP_PAD ); + __draw_pixel( display_offset_x - DISP_FRAME + 1, display_offset_y + DISPLAY_HEIGHT + 2 * DISP_FRAME - 2, DISP_PAD ); + + __draw_line( display_offset_x + DISPLAY_WIDTH + DISP_FRAME - 1, display_offset_y + DISPLAY_HEIGHT + 2 * DISP_FRAME - 4, + display_offset_x + DISPLAY_WIDTH + DISP_FRAME - 1, display_offset_y + DISPLAY_HEIGHT + 2 * DISP_FRAME - 1, DISP_PAD ); + __draw_line( display_offset_x + DISPLAY_WIDTH + DISP_FRAME - 4, display_offset_y + DISPLAY_HEIGHT + 2 * DISP_FRAME - 1, + display_offset_x + DISPLAY_WIDTH + DISP_FRAME - 1, display_offset_y + DISPLAY_HEIGHT + 2 * DISP_FRAME - 1, DISP_PAD ); + __draw_pixel( display_offset_x + DISPLAY_WIDTH + DISP_FRAME - 2, display_offset_y + DISPLAY_HEIGHT + 2 * DISP_FRAME - 2, DISP_PAD ); + + // simulate rounded lcd corners + __draw_line( display_offset_x - 1, display_offset_y + 1, display_offset_x - 1, display_offset_y + DISPLAY_HEIGHT - 2, LCD ); + __draw_line( display_offset_x + 1, display_offset_y - 1, display_offset_x + DISPLAY_WIDTH - 2, display_offset_y - 1, LCD ); + __draw_line( display_offset_x + 1, display_offset_y + DISPLAY_HEIGHT, display_offset_x + DISPLAY_WIDTH - 2, + display_offset_y + DISPLAY_HEIGHT, LCD ); + __draw_line( display_offset_x + DISPLAY_WIDTH, display_offset_y + 1, display_offset_x + DISPLAY_WIDTH, + display_offset_y + DISPLAY_HEIGHT - 2, LCD ); +} + +static void _draw_background( int width, int height, int w_top, int h_top ) +{ + __draw_rect( 0, 0, w_top, h_top, PAD ); + __draw_rect( 0, 0, width, height, DISP_PAD ); +} + +static void _draw_background_LCD( void ) { __draw_rect( display_offset_x, display_offset_y, DISPLAY_WIDTH, DISPLAY_HEIGHT, LCD ); } + +// Show the hp key which is being pressed +static void _show_key( int hpkey ) +{ + if ( config.hide_chrome || hpkey < 0 ) + return; + + SDL_SetRenderTarget( renderer, main_texture ); + + _draw_key( hpkey ); + + SDL_SetRenderTarget( renderer, NULL ); + SDL_RenderCopy( renderer, main_texture, NULL, NULL ); + SDL_RenderPresent( renderer ); + + return; +} + +static void _draw_serial_devices_path( void ) +{ + char text[ 1024 ] = ""; + + if ( config.verbose ) { + fprintf( stderr, "wire_name: %s\n", wire_name ); + fprintf( stderr, "ir_name: %s\n", ir_name ); + } + + if ( wire_name ) { + strcat( text, "wire: " ); + strcat( text, wire_name ); + } + if ( ir_name ) { + if ( strlen( text ) > 0 ) + strcat( text, " | " ); + + strcat( text, "IR: " ); + strcat( text, ir_name ); + } + + if ( strlen( text ) > 0 ) + write_with_small_font( SIDE_SKIP, KEYBOARD_OFFSET_Y - ( DISP_KBD_SKIP / 2 ), text, WHITE, DISP_PAD ); +} + +static void sdl_draw_nibble( int nx, int ny, int val ) +{ + SDL_SetRenderTarget( renderer, main_texture ); + + for ( int x = 0; x < 4; x++ ) { + if ( nx + x >= 131 ) // Clip at 131 pixels + break; + + char pixel = val & ( 1 << ( x & 3 ) ); + + __draw_rect( display_offset_x + 5 + ( 2 * ( nx + x ) ), display_offset_y + 20 + ( 2 * ny ), 2, 2, pixel ? PIXEL : LCD ); + } + + SDL_SetRenderTarget( renderer, NULL ); + SDL_RenderCopy( renderer, main_texture, NULL, NULL ); + SDL_RenderPresent( renderer ); +} + +static inline void draw_nibble( int col, int row, int val ) +{ + val &= 0x0f; + if ( val == lcd_nibbles_buffer[ row ][ col ] ) + return; + + lcd_nibbles_buffer[ row ][ col ] = val; + + int x = col * 4; + if ( row <= display.lines ) + x -= ( 2 * display.offset ); + + sdl_draw_nibble( x, row, val ); +} + +/* Identical in all ui_*.c */ +static inline void draw_row( long addr, int row ) +{ + int line_length = NIBBLES_PER_ROW; + + if ( ( display.offset > 3 ) && ( row <= display.lines ) ) + line_length += 2; + + for ( int i = 0; i < line_length; i++ ) + draw_nibble( i, row, read_nibble( addr + i ) ); +} + +static int sdl_press_key( int hpkey ) +{ + if ( hpkey == -1 || keyboard[ hpkey ].pressed ) + return -1; + + press_key( hpkey ); + _show_key( hpkey ); + + return hpkey; +} + +static int sdl_release_key( int hpkey ) +{ + if ( hpkey == -1 || !keyboard[ hpkey ].pressed ) + return -1; + + release_key( hpkey ); + _show_key( hpkey ); + + return hpkey; +} + +/**********/ +/* public */ +/**********/ +void sdl_get_event( void ) +{ + SDL_Event event; + int hpkey = -1; + static int lasthpkey = -1; // last key that was pressed or -1 for none + static int lastticks = -1; // time at which a key was pressed or -1 if timer expired + + // Iterate as long as there are events + while ( SDL_PollEvent( &event ) ) { + switch ( event.type ) { + case SDL_QUIT: + // please_exit = true; + close_and_exit(); + break; + + case SDL_MOUSEBUTTONDOWN: + hpkey = mouse_click_to_hpkey( event.button.x, event.button.y ); + if ( sdl_press_key( hpkey ) != -1 ) { + if ( lasthpkey == -1 ) { + lasthpkey = hpkey; + // Start timer + lastticks = SDL_GetTicks(); + } else + lasthpkey = lastticks = -1; + } + + break; + case SDL_MOUSEBUTTONUP: + hpkey = mouse_click_to_hpkey( event.button.x, event.button.y ); + if ( lasthpkey != hpkey || lastticks == -1 || ( SDL_GetTicks() - lastticks < 750 ) ) + sdl_release_key( hpkey ); + + lasthpkey = lastticks = -1; + break; + + case SDL_KEYDOWN: + sdl_press_key( sdlkey_to_hpkey( event.key.keysym.sym ) ); + break; + case SDL_KEYUP: + sdl_release_key( sdlkey_to_hpkey( event.key.keysym.sym ) ); + break; + } + } +} + +void sdl_update_LCD( void ) +{ + if ( display.on ) { + int i; + long addr = display.disp_start; + static int old_offset = -1; + static int old_lines = -1; + + if ( display.offset != old_offset ) { + memset( lcd_nibbles_buffer, 0xf0, ( size_t )( ( display.lines + 1 ) * NIBS_PER_BUFFER_ROW ) ); + old_offset = display.offset; + } + if ( display.lines != old_lines ) { + memset( &lcd_nibbles_buffer[ 56 ][ 0 ], 0xf0, ( size_t )( 8 * NIBS_PER_BUFFER_ROW ) ); + old_lines = display.lines; + } + for ( i = 0; i <= display.lines; i++ ) { + draw_row( addr, i ); + addr += display.nibs_per_line; + } + if ( i < DISP_ROWS ) { + addr = display.menu_start; + for ( ; i < DISP_ROWS; i++ ) { + draw_row( addr, i ); + addr += NIBBLES_PER_ROW; + } + } + } else + ui_init_LCD(); +} + +void sdl_refresh_LCD( void ) {} + +void sdl_disp_draw_nibble( word_20 addr, word_4 val ) +{ + long offset = ( addr - display.disp_start ); + int x = offset % display.nibs_per_line; + + if ( x < 0 || x > 35 ) + return; + + if ( display.nibs_per_line != 0 ) { + int y = offset / display.nibs_per_line; + if ( y < 0 || y > 63 ) + return; + + draw_nibble( x, y, val ); + } else + for ( int y = 0; y < display.lines; y++ ) + draw_nibble( x, y, val ); +} + +void sdl_menu_draw_nibble( word_20 addr, word_4 val ) +{ + long offset = ( addr - display.menu_start ); + int x = offset % NIBBLES_PER_ROW; + int y = display.lines + ( offset / NIBBLES_PER_ROW ) + 1; + + draw_nibble( x, y, val ); +} + +void sdl_draw_annunc( void ) +{ + if ( saturn.annunc == last_annunc_state ) + return; + + bool annunc_state; + last_annunc_state = saturn.annunc; + + SDL_SetRenderTarget( renderer, main_texture ); + + for ( int i = 0; i < NB_ANNUNCIATORS; i++ ) { + annunc_state = ( ( annunciators_bits[ i ] & saturn.annunc ) == annunciators_bits[ i ] ); + + __draw_texture( display_offset_x + ann_tbl[ i ].x, display_offset_y + ann_tbl[ i ].y, ann_tbl[ i ].width, ann_tbl[ i ].height, + ( annunc_state ) ? annunciators_textures[ i ].up : annunciators_textures[ i ].down ); + } + + // Always immediately update annunciators + SDL_SetRenderTarget( renderer, NULL ); + SDL_RenderCopy( renderer, main_texture, NULL, NULL ); + SDL_RenderPresent( renderer ); +} + +void sdl_adjust_contrast( void ) +{ + colors_setup(); + + // redraw LCD + ui_init_LCD(); + sdl_update_LCD(); + + // redraw annunc + last_annunc_state = -1; + + create_annunciators_textures(); + sdl_draw_annunc(); +} + +void sdl2_ui_stop( void ) +{ + SDL_DestroyTexture( main_texture ); + SDL_DestroyRenderer( renderer ); + SDL_DestroyWindow( window ); +} + +void init_sdl2_ui( int argc, char** argv ) +{ + if ( config.verbose ) + fprintf( stderr, "UI is sdl2\n" ); + + /* Set public API to this UI's functions */ + ui_disp_draw_nibble = sdl_disp_draw_nibble; + ui_menu_draw_nibble = sdl_menu_draw_nibble; + ui_get_event = sdl_get_event; + ui_update_LCD = sdl_update_LCD; + ui_refresh_LCD = sdl_refresh_LCD; + ui_adjust_contrast = sdl_adjust_contrast; + ui_draw_annunc = sdl_draw_annunc; + + // Initialize SDL + if ( SDL_Init( SDL_INIT_VIDEO ) < 0 ) { + printf( "Couldn't initialize SDL: %s\n", SDL_GetError() ); + exit( 1 ); + } + + // On exit: clean SDL + atexit( SDL_Quit ); + + unsigned int width, height; + display_offset_x = DISPLAY_OFFSET_X; + display_offset_y = DISPLAY_OFFSET_Y; + width = ( BUTTONS[ LAST_HPKEY ].x + BUTTONS[ LAST_HPKEY ].w ) + 2 * SIDE_SKIP; + height = display_offset_y + DISPLAY_HEIGHT + DISP_KBD_SKIP + BUTTONS[ LAST_HPKEY ].y + BUTTONS[ LAST_HPKEY ].h + BOTTOM_SKIP; + + if ( config.hide_chrome ) { + display_offset_x = 0; + display_offset_y = 0; + width = DISPLAY_WIDTH; + height = DISPLAY_HEIGHT; + } + + uint32_t window_flags = SDL_WINDOW_ALLOW_HIGHDPI; + if ( config.show_ui_fullscreen ) + window_flags |= SDL_WINDOW_FULLSCREEN_DESKTOP; + else + window_flags |= SDL_WINDOW_RESIZABLE; + + window = SDL_CreateWindow( config.progname, SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, width * config.scale, + height * config.scale, window_flags ); + if ( window == NULL ) { + printf( "Couldn't create window: %s\n", SDL_GetError() ); + exit( 1 ); + } + + renderer = SDL_CreateRenderer( window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_TARGETTEXTURE ); + if ( renderer == NULL ) + exit( 2 ); + + SDL_RenderSetLogicalSize( renderer, width, height ); + + main_texture = SDL_CreateTexture( renderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, width, height ); + + SDL_SetRenderTarget( renderer, main_texture ); + + colors_setup(); + + create_annunciators_textures(); + + if ( !config.hide_chrome ) { + int cut = BUTTONS[ HPKEY_MTH ].y + KEYBOARD_OFFSET_Y - 19; + + create_buttons_textures(); + + _draw_background( width, cut, width, height ); + _draw_bezel( cut, KEYBOARD_OFFSET_Y, width, height ); + _draw_header(); + _draw_bezel_LCD(); + _draw_keypad(); + + _draw_serial_devices_path(); + } + + _draw_background_LCD(); + + SDL_SetRenderTarget( renderer, NULL ); + SDL_RenderCopy( renderer, main_texture, NULL, NULL ); + SDL_RenderPresent( renderer ); +}