diff --git a/.gitignore b/.gitignore index 1fda17e..723a319 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,6 @@ # Build directories -build.fx/ -build.cg/ +build-fx/ +build-cg/ # Targets gintctl.g1a diff --git a/Makefile b/Makefile old mode 100755 new mode 100644 index 57ed664..991c2ba --- a/Makefile +++ b/Makefile @@ -1,53 +1,69 @@ #! /usr/bin/make -f -# Makefile for the gint control add-in +# Default Makefile for fxSDK add-ins. This file was probably copied there by +# the [fxsdk] program. #--- # # Configuration # +include project.cfg + # Compiler flags -cf := -mb -ffreestanding -nostdlib -Wall -Wextra -std=c11 -Os \ - -fstrict-volatile-bitfields -I include +cf := -mb -ffreestanding -nostdlib -Wall -Wextra \ + -fstrict-volatile-bitfields $(CFLAGS) cf-fx := $(cf) -m3 -DFX9860G cf-cg := $(cf) -m4-nofpu -DFXCG50 # Linker flags -lf-fx := -Tfx9860g.ld -lprof -lgint-fx -lgcc -Wl,-Map=build.fx/map -lf-cg := -Tfxcg50.ld -lprof -lgint-cg -lgcc -Wl,-Map=build.cg/map +lf-fx := $(LDFLAGS) -Tfx9860g.ld -lgint-fx -lgcc -Wl,-Map=build-fx/map +lf-cg := $(LDFLAGS) -Tfxcg50.ld -lgint-cg -lgcc -Wl,-Map=build-cg/map dflags = -MMD -MT $@ -MF $(@:.o=.d) -MP cpflags := -R .bss -R .gint_bss -g1af := -i assets-fx/icon.png -n gintctl --internal=@GINTCTL -g3af := -n basic:" " -i uns:assets-cg/icon-uns.png \ - -i sel:assets-cg/icon-sel.png +g1af := -i "$(ICON_FX)" -n "$(NAME)" --internal="$(INTERNAL)" +g3af := -n basic:"$(NAME)" -i uns:"$(ICON_CG_UNS)" -i sel:"$(ICON_CG_SEL)" # # File listings # -elf = $(dir $<)gintctl.elf -bin = $(dir $<)gintctl.bin -target-fx := gintctl.g1a -target-cg := gintctl.g3a +null := +filename := $(subst $(null) $(null),-,$(NAME)) -# Source and object files -src := $(shell find src -name '*.c') -assets-fx := $(wildcard assets-fx/*.png) -assets-cg := $(wildcard assets-cg/*.png) -obj-fx := $(src:%.c=build.fx/%.o) $(assets-fx:assets-fx/%=build.fx/%.o) -obj-cg := $(src:%.c=build.cg/%.o) $(assets-ch:assets-cg/%=build.cg/%.o) +elf = $(dir $<)$(filename).elf +bin = $(dir $<)$(filename).bin +target-fx := $(filename).g1a +target-cg := $(filename).g3a + +# Source files +src := $(wildcard src/*.c src/*/*.c src/*/*/*.c src/*/*/*/*.c) +assets-fx := $(wildcard assets-fx/*/*) +assets-cg := $(wildcard assets-cg/*/*) + +# Object files +obj-fx := $(src:%.c=build-fx/%.o) $(assets-fx:assets-fx/%=build-fx/assets/%.o) +obj-cg := $(src:%.c=build-cg/%.o) $(assets-cg:assets-cg/%=build-cg/assets/%.o) # Additional dependencies -deps-fx := assets-fx/icon.png -deps-cg := assets-cg/icon-uns.png assets-cg/icon-sel.png +deps-fx := $(ICON_FX) +deps-cg := $(ICON_CG_UNS) $(ICON_CG_SEL) + +# All targets +all := +ifneq "$(wildcard build-fx)" "" +all += all-fx +endif +ifneq "$(wildcard build-cg)" "" +all += all-cg +endif # # Build rules # -all: all-fx all-cg +all: $(all) all-fx: $(target-fx) all-cg: $(target-cg) @@ -65,21 +81,32 @@ $(target-cg): $(obj-cg) $(deps-cg) mkg3a $(g3af) $(bin) $@ # C sources -build.fx/%.o: %.c +build-fx/%.o: %.c @ mkdir -p $(dir $@) sh3eb-elf-gcc -c $< -o $@ $(cf-fx) $(dflags) -build.cg/%.o: %.c +build-cg/%.o: %.c @ mkdir -p $(dir $@) sh4eb-elf-gcc -c $< -o $@ $(cf-cg) $(dflags) # Images -build.fx/%.png.o: assets-fx/%.png +build-fx/assets/img/%.o: assets-fx/img/% @ mkdir -p $(dir $@) - fxconv -i $< -o $@ name:$* -build.cg/%.png.o: assets-cg/%.png - @ echo -e "\e[31;1mWARNING: conversion for fxcg50 not supported yet\e[0m" + fxconv -i $< -o $@ name:img_$(basename $*) + +build-cg/assets/img/%.o: assets-cg/img/% + @ echo -ne "\e[31;1mWARNING: image conversion for fxcg50 is not " + @ echo -ne "supported yet\e[0m" @ mkdir -p $(dir $@) - fxconv -i $< -o $@ name:$* + fxconv -i $< -o $@ name:img_$(basename $*) + +# Fonts +build-fx/assets/fonts/%.o: assets-fx/fonts/% + @ mkdir -p $(dir $@) + fxconv -f $< -o $@ name:font_$(basename $*) $(FONT.$*) + +build-cg/assets/fonts/%.o: assets-cg/fonts/% + @ mkdir -p $(dir $@) + fxconv -f $< -o $@ name:font_$(basename $*) $(FONT.$*) # # Cleaning and utilities @@ -87,9 +114,9 @@ build.cg/%.png.o: assets-cg/%.png # Dependency information -include $(shell find build* -name *.d 2> /dev/null) -build.fx/%.d: ; -build.cg/%.d: ; -.PRECIOUS: build.fx build.cg build.fx/%.d build.cg/%.d %/ +build-fx/%.d: ; +build-cg/%.d: ; +.PRECIOUS: build-fx build-cg build-fx/%.d build-cg/%.d %/ clean: @ rm -rf build* diff --git a/assets-fx/fonts/hexa.png b/assets-fx/fonts/hexa.png new file mode 100644 index 0000000..1841de1 Binary files /dev/null and b/assets-fx/fonts/hexa.png differ diff --git a/assets-fx/img/opt_gint_gray.png b/assets-fx/img/opt_gint_gray.png new file mode 100644 index 0000000..725d4aa Binary files /dev/null and b/assets-fx/img/opt_gint_gray.png differ diff --git a/assets-fx/opt_gint_timers.png b/assets-fx/img/opt_gint_timers.png similarity index 100% rename from assets-fx/opt_gint_timers.png rename to assets-fx/img/opt_gint_timers.png diff --git a/assets-fx/opt_main.png b/assets-fx/img/opt_main.png similarity index 100% rename from assets-fx/opt_main.png rename to assets-fx/img/opt_main.png diff --git a/assets-fx/img/opt_mem.png b/assets-fx/img/opt_mem.png new file mode 100644 index 0000000..af226bb Binary files /dev/null and b/assets-fx/img/opt_mem.png differ diff --git a/assets-fx/opt_perf_libprof.png b/assets-fx/img/opt_perf_libprof.png similarity index 100% rename from assets-fx/opt_perf_libprof.png rename to assets-fx/img/opt_perf_libprof.png diff --git a/assets-fx/opt_perf_render.png b/assets-fx/img/opt_perf_render.png similarity index 100% rename from assets-fx/opt_perf_render.png rename to assets-fx/img/opt_perf_render.png diff --git a/assets-fx/img/profile_gray.png b/assets-fx/img/profile_gray.png new file mode 100644 index 0000000..4b2e448 Binary files /dev/null and b/assets-fx/img/profile_gray.png differ diff --git a/assets-fx/img/profile_gray_alpha.png b/assets-fx/img/profile_gray_alpha.png new file mode 100644 index 0000000..45ec67f Binary files /dev/null and b/assets-fx/img/profile_gray_alpha.png differ diff --git a/assets-fx/img/profile_mono.png b/assets-fx/img/profile_mono.png new file mode 100644 index 0000000..d1b2e99 Binary files /dev/null and b/assets-fx/img/profile_mono.png differ diff --git a/assets-fx/img/profile_mono_alpha.png b/assets-fx/img/profile_mono_alpha.png new file mode 100644 index 0000000..c54097e Binary files /dev/null and b/assets-fx/img/profile_mono_alpha.png differ diff --git a/include/gintctl/gint.h b/include/gintctl/gint.h index b9c7480..3821bed 100644 --- a/include/gintctl/gint.h +++ b/include/gintctl/gint.h @@ -11,4 +11,14 @@ void gintctl_gint_hardware(void); /* gintctl_gint_timer(): Show the timer status in real-time */ void gintctl_gint_timer(void); +#ifdef FX9860G + +/* gintctl_gint_gray(): Gray engine tuning */ +void gintctl_gint_gray(void); + +/* gintctl_gint_grayrender(): Gray rendering functions */ +void gintctl_gint_grayrender(void); + +#endif /* FX9860G */ + #endif /* GINTCTL_GINT */ diff --git a/include/gintctl/mem.h b/include/gintctl/mem.h new file mode 100644 index 0000000..1e6d2d8 --- /dev/null +++ b/include/gintctl/mem.h @@ -0,0 +1,11 @@ +//--- +// gintctl:mem - Memory browser +//--- + +#ifndef GINTCTL_MEM +#define GINTCTL_MEM + +/* gintctl_mem(): Memory browser */ +void gintctl_mem(void); + +#endif /* GINTCTL_MEM */ diff --git a/project.cfg b/project.cfg new file mode 100644 index 0000000..e14bd80 --- /dev/null +++ b/project.cfg @@ -0,0 +1,22 @@ +#--- +# fxSDK project configuration file for gintctl +#--- + +# Project name, should be at most 8 bytes long. +NAME = gintctl +# Internal name, should be '@' followed by at most 7 uppercase letters. +INTERNAL = @GINTCTL + +# fx-9860G icon location +ICON_FX = assets-fx/icon.png +# fx-CG 50 icon locations +ICON_CG_UNS = assets-cg/icon-uns.png +ICON_CG_SEL = assets-cg/icon-sel.png + +# Additional compiler flags +CFLAGS = -std=c11 -Os -I include +# Additional linker flags +LDFLAGS = -lprof + +# Parameters for the hexadecimal font on fx9860g +FONT.hexa.png = charset:print grid.size:3x5 grid.padding:1 diff --git a/src/gint/gray.c b/src/gint/gray.c new file mode 100644 index 0000000..d2dac3e --- /dev/null +++ b/src/gint/gray.c @@ -0,0 +1,130 @@ +#ifdef FX9860G + +#include +#include +#include +#include +#include + +/* gintctl_gint_gray(): Gray engine tuning */ +void gintctl_gint_gray(void) +{ + uint32_t delays[2]; + gray_config(&delays[0], &delays[1]); + + int key = 0, sel = 0; + char str[20]; + + gray_start(); + + while(key != KEY_EXIT) + { + gclear(C_WHITE); + + gtext(1, 0, "Gray engine tuning", C_BLACK, C_NONE); + + sprintf(str, "Light%5u", delays[0]); + gtext(13, 24, str, C_BLACK, C_NONE); + sprintf(str, "Dark %5u", delays[1]); + gtext(13, 32, str, C_BLACK, C_NONE); + + int y = 24 + (sel << 3); + gtext(7, y, "<", C_BLACK, C_NONE); + gtext(73, y, ">", C_BLACK, C_NONE); + + grect(96, 16, 127, 31, C_LIGHT); + grect(96, 32, 127, 47, C_DARK); + + extern image_t img_opt_gint_gray; + gimage(0, 56, &img_opt_gint_gray); + + gupdate(); + key = getkey().key; + + if(key == KEY_UP && sel) sel = 0; + if(key == KEY_DOWN && !sel) sel = 1; + + if(key == KEY_LEFT) + delays[sel]--; + else if(key == KEY_RIGHT) + delays[sel]++; + else if(key == KEY_F1) + /* TODO: Default settings */ ; + else if(key == KEY_F2) + /* TODO: Default settings */ ; + else if(key == KEY_F3) + /* TODO: Default settings */ ; + else continue; + + if(delays[sel] < 100) delays[sel] = 100; + if(delays[sel] > 3000) delays[sel] = 3000; + gray_delays(delays[0], delays[1]); + } + gray_stop(); +} + +/* gintctl_gint_grayrender(): Gray rendering functions */ +void gintctl_gint_grayrender(void) +{ + int x, y; + + gray_start(); + gclear(C_WHITE); + + gtext(1, 1, "Gray rendering", C_BLACK, C_NONE); + + x = 6, y = 12; + grect(x, y, x + 15, y + 15, C_WHITE); + grect(x + 16, y, x + 31, y + 15, C_LIGHT); + grect(x + 32, y, x + 47, y + 15, C_DARK); + grect(x + 48, y, x + 63, y + 15, C_BLACK); + grect(x, y, x + 63, y + 3, C_LIGHTEN); + grect(x, y + 12, x + 63, y + 15, C_DARKEN); + + x = 104, y = 0; + grect(x, y, x + 23, y + 32, C_BLACK); + gtext(x - 13, y + 1, "White", C_WHITE, C_NONE); + gtext(x - 13, y + 9, "Light", C_LIGHT, C_NONE); + gtext(x - 13, y + 17, "Dark", C_DARK, C_NONE); + gtext(x - 13, y + 25, "Black", C_BLACK, C_NONE); + + x = 76, y = 33; + grect(x, y, x + 12, y + 24, C_WHITE); + grect(x + 13, y, x + 25, y + 24, C_LIGHT); + grect(x + 26, y, x + 38, y + 24, C_DARK); + grect(x + 39, y, x + 51, y + 24, C_BLACK); + gtext(x + 8, y + 1, "Lighten", C_LIGHTEN, C_NONE); + gtext(x + 8, y + 9, "Darken", C_DARKEN, C_NONE); + gtext(x + 8, y + 17, "Invert", C_INVERT, C_NONE); + + extern image_t img_profile_mono; + extern image_t img_profile_mono_alpha; + extern image_t img_profile_gray; + extern image_t img_profile_gray_alpha; + + x = 8, y = 32; + for(int c = 0; c < 8; c++) + { + int z = x + 8 * c + 3; + gline(z, y, z + 3, y + 3, c); + gline(z - 1, y + 1, z - 3, y + 3, c); + gline(z + 2, y + 4, z, y + 6, c); + gline(z - 2, y + 4, z - 1, y + 5, c); + } + + x = 2, y = 42; + for(int j = 0; j < 20; j++) + for(int i = 0; i < 74; i++) + gpixel(x + i, y + j, (i ^ j) & 1 ? C_BLACK : C_WHITE); + gimage(x + 2, y + 2, &img_profile_mono); + gimage(x + 20, y + 2, &img_profile_mono_alpha); + gimage(x + 38, y + 2, &img_profile_gray); + gimage(x + 56, y + 2, &img_profile_gray_alpha); + + gupdate(); + getkey(); + + gray_stop(); +} + +#endif /* FX9860G */ diff --git a/src/gint/timer.c b/src/gint/timer.c index 9d9d1f8..0dd3458 100644 --- a/src/gint/timer.c +++ b/src/gint/timer.c @@ -102,8 +102,8 @@ void gintctl_gint_timer(void) if(tab == 2) show_etmu_1(); if(tab == 3) show_etmu_2(); - extern image_t opt_gint_timers; - dimage(0, 56, &opt_gint_timers); + extern image_t img_opt_gint_timers; + dimage(0, 56, &img_opt_gint_timers); #endif #ifdef FXCG50 diff --git a/src/gintctl.c b/src/gintctl.c index 06e08f9..93ee6b7 100644 --- a/src/gintctl.c +++ b/src/gintctl.c @@ -12,6 +12,7 @@ #include #include +#include #include @@ -41,7 +42,8 @@ struct menu menu_gint = { { "Image rendering", NULL }, { "Text rendering", NULL }, #ifdef FX9860G - { "Gray engine", NULL }, + { "Gray engine", gintctl_gint_gray }, + { "Gray rendering", gintctl_gint_grayrender }, #endif { NULL, NULL }, }}; @@ -139,7 +141,6 @@ void gintctl_main(void) #endif /* FXCG50 */ } - int main(GUNUSED int isappli, GUNUSED int optnum) { /* Initialize menu metadata */ @@ -161,8 +162,8 @@ int main(GUNUSED int isappli, GUNUSED int optnum) else gintctl_main(); #ifdef FX9860G - extern image_t opt_main; - dimage(0, 56, &opt_main); + extern image_t img_opt_main; + dimage(0, 56, &img_opt_main); #else fkey_action(1, "INFO"); fkey_menu(2, "GINT"); @@ -183,7 +184,7 @@ int main(GUNUSED int isappli, GUNUSED int optnum) if(key == KEY_F5) gintctl_regs(); if(key == KEY_F6) - /* TODO: Launch memory explorer */ { } + gintctl_mem(); if(!menu) continue; diff --git a/src/mem/mem.c b/src/mem/mem.c new file mode 100644 index 0000000..c4624a9 --- /dev/null +++ b/src/mem/mem.c @@ -0,0 +1,77 @@ +#include +#include +#include + +#include +#include + +int c(int c) +{ + return (c >= 0x20 && c < 0x7f) ? c : '.'; +} + +/* gintctl_mem(): Memory browser */ +void gintctl_mem(void) +{ + uint32_t base = 0x88010758; + int key = 0, ascii = 0; + + #ifdef FX9860G + extern font_t font_hexa; + font_t const *old_font = dfont(&font_hexa); + + char header[12]; + char bytes[24]; + + while(key != KEY_EXIT) + { + dclear(C_WHITE); + + uint32_t addr = base; + uint8_t *mem = (void *)addr; + + for(int i = 0; i <= 8; i++) + { + if(!ascii) + { + sprintf(header, "%08X:", addr); + } + else + { + for(int k = 0; k < 8; k++) + header[k] = c(mem[k]); + header[8] = 0; + } + + sprintf(bytes, "%02X%02X %02X%02X %02X%02X %02X%02X", + mem[0], mem[1], mem[2], mem[3], + mem[4], mem[5], mem[6], mem[7] + ); + + dtext( 5, 6 * i + 1, header, C_BLACK, C_NONE); + dtext(45, 6 * i + 1, bytes, C_BLACK, C_NONE); + + mem += 8; + addr += 8; + } + + extern image_t img_opt_mem; + dsubimage(0, 56, &img_opt_mem, 0, 0, 128, 8, DIMAGE_NONE); + + if(ascii) + { + dsubimage(107, 56, &img_opt_mem, 107, 9, 21, 8, DIMAGE_NONE); + } + + dupdate(); + key = getkey().key; + + if(key == KEY_UP) base -= 72; + if(key == KEY_DOWN) base += 72; + + if(key == KEY_F6) ascii = !ascii; + } + + dfont(old_font); + #endif +} diff --git a/src/perf/libprof.c b/src/perf/libprof.c index 6576b62..3ac7833 100644 --- a/src/perf/libprof.c +++ b/src/perf/libprof.c @@ -55,8 +55,8 @@ void gintctl_perf_libprof(void) row_print(6, 1, "Empty: %d us", empty); } - extern image_t opt_perf_libprof; - dimage(0, 56, &opt_perf_libprof); + extern image_t img_opt_perf_libprof; + dimage(0, 56, &img_opt_perf_libprof); #endif /* FX9860G */ #ifdef FXCG50 diff --git a/src/perf/render.c b/src/perf/render.c index d9f60a7..4183314 100644 --- a/src/perf/render.c +++ b/src/perf/render.c @@ -75,8 +75,8 @@ void gintctl_perf_render(void) row_print(6, 1, "rect3: %s", printtime(time.rect3)); } - extern image_t opt_perf_render; - dimage(0, 56, &opt_perf_render); + extern image_t img_opt_perf_render; + dimage(0, 56, &img_opt_perf_render); #endif #ifdef FXCG50