From c7a4ff64287b12487c7e9cc13ce3b7d2aa6e1f06 Mon Sep 17 00:00:00 2001 From: notaz Date: Sat, 1 Sep 2007 11:07:03 +0000 Subject: [PATCH] giz menu works git-svn-id: file:///home/notaz/opt/svn/PicoDrive/platform@231 be3aeb3a-fb24-0410-a615-afba39da0efa --- gp2x/asmutils.h => common/arm_utils.h | 0 gp2x/asmutils.s => common/arm_utils.s | 0 {gp2x => common}/fonts.c | 0 {gp2x => common}/fonts.h | 0 common/lprintf.h | 6 + common/menu.c | 314 ++++++++++++++++++++ common/menu.h | 98 +++++++ {gp2x => common}/readpng.c | 21 +- {gp2x => common}/readpng.h | 0 gp2x/940ctl.c | 3 +- gp2x/Makefile | 7 +- gp2x/emu.c | 18 +- gp2x/gp2x.c | 2 +- gp2x/main.c | 1 + gp2x/menu.c | 402 ++------------------------ gp2x/menu.h | 2 - linux/Makefile | 8 +- 17 files changed, 471 insertions(+), 411 deletions(-) rename gp2x/asmutils.h => common/arm_utils.h (100%) rename gp2x/asmutils.s => common/arm_utils.s (100%) rename {gp2x => common}/fonts.c (100%) rename {gp2x => common}/fonts.h (100%) create mode 100644 common/lprintf.h create mode 100644 common/menu.c create mode 100644 common/menu.h rename {gp2x => common}/readpng.c (76%) rename {gp2x => common}/readpng.h (100%) diff --git a/gp2x/asmutils.h b/common/arm_utils.h similarity index 100% rename from gp2x/asmutils.h rename to common/arm_utils.h diff --git a/gp2x/asmutils.s b/common/arm_utils.s similarity index 100% rename from gp2x/asmutils.s rename to common/arm_utils.s diff --git a/gp2x/fonts.c b/common/fonts.c similarity index 100% rename from gp2x/fonts.c rename to common/fonts.c diff --git a/gp2x/fonts.h b/common/fonts.h similarity index 100% rename from gp2x/fonts.h rename to common/fonts.h diff --git a/common/lprintf.h b/common/lprintf.h new file mode 100644 index 0000000..5cd176f --- /dev/null +++ b/common/lprintf.h @@ -0,0 +1,6 @@ +#if defined(__GP2X__) +#define lprintf printf +#else +#include "giz.h" +#endif + diff --git a/common/menu.c b/common/menu.c new file mode 100644 index 0000000..53ef33d --- /dev/null +++ b/common/menu.c @@ -0,0 +1,314 @@ +// (c) Copyright 2006,2007 notaz, All rights reserved. +// Free for non-commercial use. + +// For commercial use, separate licencing terms must be obtained. + +#include +#include +#include +#include + +#include "menu.h" +#include "fonts.h" +#include "readpng.h" +#include "lprintf.h" + +#if defined(__GP2X__) +#include "../gp2x/gp2x.h" +#define SCREEN_WIDTH 320 +#define SCREEN_BUFFER gp2x_screen +#elif defined(__GIZ__) +#include "../gizmondo/giz.h" +#define SCREEN_WIDTH 321 +#define SCREEN_BUFFER giz_screen +#endif + +static unsigned char menu_font_data[10240]; +static int menu_text_color = 0xffff; // default to white +static int menu_sel_color = -1; // disabled + +// draws text to current bbp16 screen +static void text_out16_(int x, int y, const char *text, int color) +{ + int i, l, u, tr, tg, tb, len; + unsigned short *dest = (unsigned short *)SCREEN_BUFFER + x + y*SCREEN_WIDTH; + tr = (color & 0xf800) >> 8; + tg = (color & 0x07e0) >> 3; + tb = (color & 0x001f) << 3; + + if (text == (void *)1) + { + // selector symbol + text = ""; + len = 1; + } + else + len = strlen(text); + + for (i = 0; i < len; i++) + { + unsigned char *src = menu_font_data + (unsigned int)text[i]*4*10; + unsigned short *dst = dest; + for (l = 0; l < 10; l++, dst += SCREEN_WIDTH-8) + { + for (u = 8/2; u > 0; u--, src++) + { + int c, r, g, b; + c = *src >> 4; + r = (*dst & 0xf800) >> 8; + g = (*dst & 0x07e0) >> 3; + b = (*dst & 0x001f) << 3; + r = (c^0xf)*r/15 + c*tr/15; + g = (c^0xf)*g/15 + c*tg/15; + b = (c^0xf)*b/15 + c*tb/15; + *dst++ = ((r<<8)&0xf800) | ((g<<3)&0x07e0) | (b>>3); + c = *src & 0xf; + r = (*dst & 0xf800) >> 8; + g = (*dst & 0x07e0) >> 3; + b = (*dst & 0x001f) << 3; + r = (c^0xf)*r/15 + c*tr/15; + g = (c^0xf)*g/15 + c*tg/15; + b = (c^0xf)*b/15 + c*tb/15; + *dst++ = ((r<<8)&0xf800) | ((g<<3)&0x07e0) | (b>>3); + } + } + dest += 8; + } +} + +void text_out16(int x, int y, const char *texto, ...) +{ + va_list args; + char buffer[512]; + + va_start(args,texto); + vsprintf(buffer,texto,args); + va_end(args); + + text_out16_(x,y,buffer,menu_text_color); +} + + +void smalltext_out16(int x, int y, const char *texto, int color) +{ + int i; + unsigned char *src; + unsigned short *dst; + + for (i = 0;; i++, x += 6) + { + unsigned char c = (unsigned char) texto[i]; + int h = 8; + + if (!c) break; + + src = fontdata6x8[c]; + dst = (unsigned short *)SCREEN_BUFFER + x + y*SCREEN_WIDTH; + + while (h--) + { + int w = 0x20; + while (w) + { + if( *src & w ) *dst = color; + dst++; + w>>=1; + } + src++; + + dst += SCREEN_WIDTH-6; + } + } +} + +void smalltext_out16_lim(int x, int y, const char *texto, int color, int max) +{ + char buffer[SCREEN_WIDTH/6+1]; + + strncpy(buffer, texto, SCREEN_WIDTH/6); + if (max > SCREEN_WIDTH/6) max = SCREEN_WIDTH/6; + if (max < 0) max = 0; + buffer[max] = 0; + + smalltext_out16(x, y, buffer, color); +} + +void menu_draw_selection(int x, int y, int w) +{ + int i, h; + unsigned short *dst, *dest; + + text_out16_(x, y, (void *)1, (menu_sel_color < 0) ? menu_text_color : menu_sel_color); + + if (menu_sel_color < 0) return; // no selection hilight + + if (y > 0) y--; + dest = (unsigned short *)SCREEN_BUFFER + x + y*SCREEN_WIDTH + 14; + for (h = 11; h > 0; h--) + { + dst = dest; + for (i = w; i > 0; i--) + *dst++ = menu_sel_color; + dest += SCREEN_WIDTH; + } +} + +static int parse_hex_color(char *buff) +{ + char *endp = buff; + int t = (int) strtoul(buff, &endp, 16); + if (endp != buff) return ((t>>8)&0xf800) | ((t>>5)&0x07e0) | ((t>>3)&0x1f); + return -1; +} + +void menu_init(void) +{ + int c, l; + unsigned char *fd = menu_font_data; + char buff[256]; + FILE *f; + + // generate default font from fontdata8x8 + memset(menu_font_data, 0, sizeof(menu_font_data)); + for (c = 0; c < 256; c++) + { + for (l = 0; l < 8; l++) + { + unsigned char fd8x8 = fontdata8x8[c*8+l]; + if (fd8x8&0x80) *fd |= 0xf0; + if (fd8x8&0x40) *fd |= 0x0f; fd++; + if (fd8x8&0x20) *fd |= 0xf0; + if (fd8x8&0x10) *fd |= 0x0f; fd++; + if (fd8x8&0x08) *fd |= 0xf0; + if (fd8x8&0x04) *fd |= 0x0f; fd++; + if (fd8x8&0x02) *fd |= 0xf0; + if (fd8x8&0x01) *fd |= 0x0f; fd++; + } + fd += 8*2/2; // 2 empty lines + } + + // load custom font and selector (stored as 1st symbol in font table) + readpng(menu_font_data, "skin/font.png", READPNG_FONT); + memcpy(menu_font_data, menu_font_data + ((int)'>')*4*10, 4*10); // default selector symbol is '>' + readpng(menu_font_data, "skin/selector.png", READPNG_SELECTOR); + + // load custom colors + f = fopen("skin/skin.txt", "r"); + if (f != NULL) + { + lprintf("found skin.txt\n"); + while (!feof(f)) + { + fgets(buff, sizeof(buff), f); + if (buff[0] == '#' || buff[0] == '/') continue; // comment + if (buff[0] == '\r' || buff[0] == '\n') continue; // empty line + if (strncmp(buff, "text_color=", 11) == 0) + { + int tmp = parse_hex_color(buff+11); + if (tmp >= 0) menu_text_color = tmp; + else lprintf("skin.txt: parse error for text_color\n"); + } + else if (strncmp(buff, "selection_color=", 16) == 0) + { + int tmp = parse_hex_color(buff+16); + if (tmp >= 0) menu_sel_color = tmp; + else lprintf("skin.txt: parse error for selection_color\n"); + } + else + lprintf("skin.txt: parse error: %s\n", buff); + } + fclose(f); + } +} + + +int me_id2offset(const menu_entry *entries, int count, menu_id id) +{ + int i; + for (i = 0; i < count; i++) + { + if (entries[i].id == id) return i; + } + + lprintf("%s: id %i not found\n", __FUNCTION__, id); + return 0; +} + +void me_enable(menu_entry *entries, int count, menu_id id, int enable) +{ + int i = me_id2offset(entries, count, id); + entries[i].enabled = enable; +} + +int me_count_enabled(const menu_entry *entries, int count) +{ + int i, ret = 0; + + for (i = 0; i < count; i++) + { + if (entries[i].enabled) ret++; + } + + return ret; +} + +menu_id me_index2id(const menu_entry *entries, int count, int index) +{ + int i; + + for (i = 0; i < count; i++) + { + if (entries[i].enabled) + { + if (index == 0) break; + index--; + } + } + if (i >= count) i = count - 1; + return entries[i].id; +} + +void me_draw(const menu_entry *entries, int count, int x, int y, me_draw_custom_f *cust_draw, void *param) +{ + int i, y1 = y; + + for (i = 0; i < count; i++) + { + if (!entries[i].enabled) continue; + if (entries[i].name == NULL) + { + if (cust_draw != NULL) + cust_draw(&entries[i], x, y1, param); + y1 += 10; + continue; + } + text_out16(x, y1, entries[i].name); + if (entries[i].beh == MB_ONOFF) + text_out16(x + 27*8, y1, (*(int *)entries[i].var & entries[i].mask) ? "ON" : "OFF"); + else if (entries[i].beh == MB_RANGE) + text_out16(x + 27*8, y1, "%i", *(int *)entries[i].var); + y1 += 10; + } +} + +int me_process(menu_entry *entries, int count, menu_id id, int is_next) +{ + int i = me_id2offset(entries, count, id); + menu_entry *entry = &entries[i]; + switch (entry->beh) + { + case MB_ONOFF: + *(int *)entry->var ^= entry->mask; + return 1; + case MB_RANGE: + *(int *)entry->var += is_next ? 1 : -1; + if (*(int *)entry->var < (int)entry->min) *(int *)entry->var = (int)entry->min; + if (*(int *)entry->var > (int)entry->max) *(int *)entry->var = (int)entry->max; + return 1; + default: + return 0; + } +} + + + diff --git a/common/menu.h b/common/menu.h new file mode 100644 index 0000000..1e096ff --- /dev/null +++ b/common/menu.h @@ -0,0 +1,98 @@ +// (c) Copyright 2006,2007 notaz, All rights reserved. + + +void menu_init(void); +void text_out16(int x, int y, const char *texto, ...); +void smalltext_out16(int x, int y, const char *texto, int color); +void smalltext_out16_lim(int x, int y, const char *texto, int color, int max); +void menu_draw_selection(int x, int y, int w); + + + +typedef enum +{ + MB_NONE = 1, /* no auto processing */ + MB_ONOFF, /* ON/OFF setting */ + MB_RANGE, /* [min-max] setting */ +} menu_behavior; + +typedef enum +{ + MA_NONE = 1, + MA_MAIN_RESUME_GAME, + MA_MAIN_SAVE_STATE, + MA_MAIN_LOAD_STATE, + MA_MAIN_RESET_GAME, + MA_MAIN_LOAD_ROM, + MA_MAIN_OPTIONS, + MA_MAIN_CONTROLS, + MA_MAIN_CREDITS, + MA_MAIN_PATCHES, + MA_MAIN_EXIT, + MA_OPT_RENDERER, + MA_OPT_SCALING, + MA_OPT_ACC_TIMING, + MA_OPT_ACC_SPRITES, + MA_OPT_SHOW_FPS, + MA_OPT_FRAMESKIP, + MA_OPT_ENABLE_SOUND, + MA_OPT_SOUND_QUALITY, + MA_OPT_ARM940_SOUND, + MA_OPT_6BUTTON_PAD, + MA_OPT_REGION, + MA_OPT_SRAM_STATES, + MA_OPT_CONFIRM_STATES, + MA_OPT_SAVE_SLOT, + MA_OPT_CPU_CLOCKS, + MA_OPT_SCD_OPTS, + MA_OPT_ADV_OPTS, + MA_OPT_SAVECFG, + MA_OPT_SAVECFG_GAME, + MA_OPT_LOADCFG, + MA_OPT2_GAMMA, + MA_OPT2_A_SN_GAMMA, + MA_OPT2_VSYNC, + MA_OPT2_ENABLE_Z80, + MA_OPT2_ENABLE_YM2612, + MA_OPT2_ENABLE_SN76496, + MA_OPT2_GZIP_STATES, + MA_OPT2_NO_LAST_ROM, + MA_OPT2_RAMTIMINGS, + MA_OPT2_SQUIDGEHACK, + MA_OPT2_DONE, + MA_CDOPT_TESTBIOS_USA, + MA_CDOPT_TESTBIOS_EUR, + MA_CDOPT_TESTBIOS_JAP, + MA_CDOPT_LEDS, + MA_CDOPT_CDDA, + MA_CDOPT_PCM, + MA_CDOPT_READAHEAD, + MA_CDOPT_SAVERAM, + MA_CDOPT_SCALEROT_CHIP, + MA_CDOPT_BETTER_SYNC, + MA_CDOPT_DONE, +} menu_id; + +typedef struct +{ + char *name; + menu_behavior beh; + menu_id id; + void *var; /* for on-off settings */ + int mask; + signed char min; /* for ranged integer settings, to be sign-extended */ + signed char max; + char enabled; +} menu_entry; + + +typedef void (me_draw_custom_f)(const menu_entry *entry, int x, int y, void *param); + +int me_id2offset(const menu_entry *entries, int count, menu_id id); +void me_enable(menu_entry *entries, int count, menu_id id, int enable); +int me_count_enabled(const menu_entry *entries, int count); +menu_id me_index2id(const menu_entry *entries, int count, int index); +void me_draw(const menu_entry *entries, int count, int x, int y, me_draw_custom_f *cust_draw, void *param); +int me_process(menu_entry *entries, int count, menu_id id, int is_next); + + diff --git a/gp2x/readpng.c b/common/readpng.c similarity index 76% rename from gp2x/readpng.c rename to common/readpng.c index a890e4e..2a74668 100644 --- a/gp2x/readpng.c +++ b/common/readpng.c @@ -2,6 +2,7 @@ #include #include #include "readpng.h" +#include "lprintf.h" void readpng(void *dest, const char *fname, readpng_what what) { @@ -18,14 +19,14 @@ void readpng(void *dest, const char *fname, readpng_what what) fp = fopen(fname, "rb"); if (fp == NULL) { - printf(__FILE__ ": failed to open: %s\n", fname); + lprintf(__FILE__ ": failed to open: %s\n", fname); return; } png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); if (!png_ptr) { - printf(__FILE__ ": png_create_read_struct() failed\n"); + lprintf(__FILE__ ": png_create_read_struct() failed\n"); fclose(fp); return; } @@ -33,7 +34,7 @@ void readpng(void *dest, const char *fname, readpng_what what) info_ptr = png_create_info_struct(png_ptr); if (!info_ptr) { - printf(__FILE__ ": png_create_info_struct() failed\n"); + lprintf(__FILE__ ": png_create_info_struct() failed\n"); goto done; } @@ -43,11 +44,11 @@ void readpng(void *dest, const char *fname, readpng_what what) row_ptr = png_get_rows(png_ptr, info_ptr); if (row_ptr == NULL) { - printf(__FILE__ ": png_get_rows() failed\n"); + lprintf(__FILE__ ": png_get_rows() failed\n"); goto done; } - // printf("%s: %ix%i @ %ibpp\n", fname, (int)info_ptr->width, (int)info_ptr->height, info_ptr->pixel_depth); + // lprintf("%s: %ix%i @ %ibpp\n", fname, (int)info_ptr->width, (int)info_ptr->height, info_ptr->pixel_depth); switch (what) { @@ -57,7 +58,7 @@ void readpng(void *dest, const char *fname, readpng_what what) unsigned short *dst = dest; if (info_ptr->pixel_depth != 24) { - printf(__FILE__ ": bg image uses %ibpp, needed 24bpp\n", info_ptr->pixel_depth); + lprintf(__FILE__ ": bg image uses %ibpp, needed 24bpp\n", info_ptr->pixel_depth); break; } height = info_ptr->height; @@ -85,13 +86,13 @@ void readpng(void *dest, const char *fname, readpng_what what) unsigned char *dst = dest; if (info_ptr->width != 128 || info_ptr->height != 160) { - printf(__FILE__ ": unexpected font image size %ix%i, needed 128x160\n", + lprintf(__FILE__ ": unexpected font image size %ix%i, needed 128x160\n", (int)info_ptr->width, (int)info_ptr->height); break; } if (info_ptr->pixel_depth != 8) { - printf(__FILE__ ": font image uses %ibpp, needed 8bpp\n", info_ptr->pixel_depth); + lprintf(__FILE__ ": font image uses %ibpp, needed 8bpp\n", info_ptr->pixel_depth); break; } for (y = 0; y < 16; y++) @@ -115,13 +116,13 @@ void readpng(void *dest, const char *fname, readpng_what what) unsigned char *dst = dest; if (info_ptr->width != 8 || info_ptr->height != 10) { - printf(__FILE__ ": unexpected selector image size %ix%i, needed 8x10\n", + lprintf(__FILE__ ": unexpected selector image size %ix%i, needed 8x10\n", (int)info_ptr->width, (int)info_ptr->height); break; } if (info_ptr->pixel_depth != 8) { - printf(__FILE__ ": selector image uses %ibpp, needed 8bpp\n", info_ptr->pixel_depth); + lprintf(__FILE__ ": selector image uses %ibpp, needed 8bpp\n", info_ptr->pixel_depth); break; } for (y1 = 0; y1 < 10; y1++) diff --git a/gp2x/readpng.h b/common/readpng.h similarity index 100% rename from gp2x/readpng.h rename to common/readpng.h diff --git a/gp2x/940ctl.c b/gp2x/940ctl.c index 66a5d2b..075b827 100644 --- a/gp2x/940ctl.c +++ b/gp2x/940ctl.c @@ -14,8 +14,9 @@ #include "gp2x.h" #include "emu.h" #include "menu.h" -#include "asmutils.h" #include "mp3.h" +#include "../common/arm_utils.h" +#include "../common/menu.h" #include "../../Pico/PicoInt.h" #include "../../Pico/sound/mix.h" diff --git a/gp2x/Makefile b/gp2x/Makefile index 0eee0eb..5b8b039 100644 --- a/gp2x/Makefile +++ b/gp2x/Makefile @@ -48,10 +48,13 @@ LD = $(CROSS)ld OBJCOPY = $(CROSS)objcopy # frontend -OBJS += main.o menu.o fonts.o gp2x.o usbjoy.o emu.o squidgehack.o asmutils.o cpuctrl.o readpng.o +OBJS += main.o menu.o gp2x.o usbjoy.o emu.o squidgehack.o cpuctrl.o # 940 core control OBJS += 940ctl.o +# common +OBJS += ../common/menu.o ../common/fonts.o ../common/arm_utils.o ../common/readpng.o + # Pico ifeq "$(amalgamate)" "1" OBJS += ../../PicoAll.o @@ -148,7 +151,7 @@ up: PicoDrive.gpe # @cmd //C copy PicoDrive.gpe \\\\10.0.1.2\\gp2x\\mnt\\sd\\games\\PicoDrive\\ -testrefr.gpe : test.o gp2x.o asmutils.o +testrefr.gpe : test.o gp2x.o @echo $@ @$(GCC) $(COPT) $^ -o $@ @$(STRIP) $@ diff --git a/gp2x/emu.c b/gp2x/emu.c index a9a931a..adb10a3 100644 --- a/gp2x/emu.c +++ b/gp2x/emu.c @@ -18,9 +18,9 @@ #include "gp2x.h" #include "usbjoy.h" #include "menu.h" -#include "asmutils.h" +#include "../common/arm_utils.h" +#include "../common/fonts.h" #include "cpuctrl.h" -#include "fonts.h" #include #include @@ -52,7 +52,7 @@ static int combo_keys = 0, combo_acts = 0; // keys and actions which need button static int gp2x_old_gamma = 100; static unsigned char *movie_data = NULL; static int movie_size = 0; -unsigned char *framebuff = 0; // temporary buffer for alt renderer +unsigned char *PicoDraw2FB = NULL; // temporary buffer for alt renderer int state_slot = 0; int reset_timing = 0; int config_slot = 0, config_slot_current = 0; @@ -389,10 +389,10 @@ static void emu_msg_tray_open(void); void emu_Init(void) { // make temp buffer for alt renderer - framebuff = malloc((8+320)*(8+240+8)); - if (!framebuff) + PicoDraw2FB = malloc((8+320)*(8+240+8)); + if (!PicoDraw2FB) { - printf("framebuff == 0\n"); + printf("PicoDraw2FB == 0\n"); } // make dirs for saves, cfgs, etc. @@ -626,7 +626,7 @@ void emu_Deinit(void) } } - free(framebuff); + free(PicoDraw2FB); PicoExit(); @@ -768,7 +768,7 @@ static void blit(const char *fps, const char *notice) // feed new palette to our device gp2x_video_setpalette(localPal, 0x40); } - vidCpyM2((unsigned char *)gp2x_screen+320*8, framebuff+328*8); + vidCpyM2((unsigned char *)gp2x_screen+320*8, PicoDraw2FB+328*8); } else if (!(emu_opt&0x80)) { // 8bit accurate renderer if (Pico.m.dirtyPal) { @@ -1112,7 +1112,7 @@ void emu_forced_frame(void) clearArea(1); } else vidCpyM2 = vidCpyM2_40col; - vidCpyM2((unsigned char *)gp2x_screen+320*8, framebuff+328*8); + vidCpyM2((unsigned char *)gp2x_screen+320*8, PicoDraw2FB+328*8); vidConvCpyRGB32(localPal, Pico.cram, 0x40); gp2x_video_setpalette(localPal, 0x40); */ diff --git a/gp2x/gp2x.c b/gp2x/gp2x.c index 3b5d125..4995f08 100644 --- a/gp2x/gp2x.c +++ b/gp2x/gp2x.c @@ -34,7 +34,7 @@ #include "gp2x.h" #include "usbjoy.h" -#include "asmutils.h" +#include "../common/arm_utils.h" volatile unsigned short *gp2x_memregs; //static diff --git a/gp2x/main.c b/gp2x/main.c index e4e3bcf..13eb5a8 100644 --- a/gp2x/main.c +++ b/gp2x/main.c @@ -11,6 +11,7 @@ #include "gp2x.h" #include "menu.h" +#include "../common/menu.h" #include "emu.h" #include "940ctl.h" #include "version.h" diff --git a/gp2x/menu.c b/gp2x/menu.c index 71ddf68..a8d1f9e 100644 --- a/gp2x/menu.c +++ b/gp2x/menu.c @@ -13,10 +13,10 @@ #include "gp2x.h" #include "emu.h" #include "menu.h" -#include "fonts.h" #include "usbjoy.h" -#include "asmutils.h" -#include "readpng.h" +#include "../common/arm_utils.h" +#include "../common/menu.h" +#include "../common/readpng.h" #include "version.h" #include @@ -33,389 +33,18 @@ extern int mmuhack_status; extern int state_slot; extern int config_slot, config_slot_current; -static unsigned char menu_font_data[10240]; -static char *gp2xKeyNames[] = { +static const char *gp2xKeyNames[] = { "UP", "???", "LEFT", "???", "DOWN", "???", "RIGHT", "???", "START", "SELECT", "L", "R", "A", "B", "X", "Y", "???", "???", "???", "???", "???", "???", "VOL DOWN", "VOL UP", "???", "???", "???", "PUSH", "???", "???", "???", "???" }; -static int menu_text_color = 0xffff; // default to white -static int menu_sel_color = -1; // disabled char menuErrorMsg[40] = {0, }; static void menu_darken_bg(void *dst, int pixels, int darker); static void menu_prepare_bg(int use_game_bg); -// draws text to current bbp16 screen -static void text_out16_(int x, int y, const char *text, int color) -{ - int i, l, u, tr, tg, tb, len; - unsigned short *dest = (unsigned short *)gp2x_screen + x + y*320; - tr = (color & 0xf800) >> 8; - tg = (color & 0x07e0) >> 3; - tb = (color & 0x001f) << 3; - - if (text == (void *)1) - { - // selector symbol - text = ""; - len = 1; - } - else - len = strlen(text); - - for (i = 0; i < len; i++) - { - unsigned char *src = menu_font_data + (unsigned int)text[i]*4*10; - unsigned short *dst = dest; - for (l = 0; l < 10; l++, dst += 320-8) - { - for (u = 8/2; u > 0; u--, src++) - { - int c, r, g, b; - c = *src >> 4; - r = (*dst & 0xf800) >> 8; - g = (*dst & 0x07e0) >> 3; - b = (*dst & 0x001f) << 3; - r = (c^0xf)*r/15 + c*tr/15; - g = (c^0xf)*g/15 + c*tg/15; - b = (c^0xf)*b/15 + c*tb/15; - *dst++ = ((r<<8)&0xf800) | ((g<<3)&0x07e0) | (b>>3); - c = *src & 0xf; - r = (*dst & 0xf800) >> 8; - g = (*dst & 0x07e0) >> 3; - b = (*dst & 0x001f) << 3; - r = (c^0xf)*r/15 + c*tr/15; - g = (c^0xf)*g/15 + c*tg/15; - b = (c^0xf)*b/15 + c*tb/15; - *dst++ = ((r<<8)&0xf800) | ((g<<3)&0x07e0) | (b>>3); - } - } - dest += 8; - } -} - -void text_out16(int x, int y, const char *texto, ...) -{ - va_list args; - char buffer[512]; - - va_start(args,texto); - vsprintf(buffer,texto,args); - va_end(args); - - text_out16_(x,y,buffer,menu_text_color); -} - - -static void smalltext_out16(int x, int y, const char *texto, int color) -{ - int i; - unsigned char *src; - unsigned short *dst; - - for (i = 0;; i++, x += 6) - { - unsigned char c = (unsigned char) texto[i]; - int h = 8; - - if (!c) break; - - src = fontdata6x8[c]; - dst = (unsigned short *)gp2x_screen + x + y*320; - - while (h--) - { - int w = 0x20; - while (w) - { - if( *src & w ) *dst = color; - dst++; - w>>=1; - } - src++; - - dst += 320-6; - } - } -} - -static void smalltext_out16_lim(int x, int y, const char *texto, int color, int max) -{ - char buffer[320/6+1]; - - strncpy(buffer, texto, 320/6); - if (max > 320/6) max = 320/6; - if (max < 0) max = 0; - buffer[max] = 0; - - smalltext_out16(x, y, buffer, color); -} - -static void draw_selection(int x, int y, int w) -{ - int i, h; - unsigned short *dst, *dest; - - text_out16_(x, y, (void *)1, (menu_sel_color < 0) ? menu_text_color : menu_sel_color); - - if (menu_sel_color < 0) return; // no selection hilight - - if (y > 0) y--; - dest = (unsigned short *)gp2x_screen + x + y*320 + 14; - for (h = 11; h > 0; h--) - { - dst = dest; - for (i = w; i > 0; i--) - *dst++ = menu_sel_color; - dest += 320; - } -} - -static void menu_flip(void) -{ - gp2x_video_flush_cache(); - gp2x_video_flip2(); -} - - -typedef enum -{ - MB_NONE = 1, /* no auto processing */ - MB_ONOFF, /* ON/OFF setting */ - MB_RANGE, /* [min-max] setting */ -} menu_behavior; - -typedef enum -{ - MA_NONE = 1, - MA_MAIN_RESUME_GAME, - MA_MAIN_SAVE_STATE, - MA_MAIN_LOAD_STATE, - MA_MAIN_RESET_GAME, - MA_MAIN_LOAD_ROM, - MA_MAIN_OPTIONS, - MA_MAIN_CONTROLS, - MA_MAIN_CREDITS, - MA_MAIN_PATCHES, - MA_MAIN_EXIT, - MA_OPT_RENDERER, - MA_OPT_SCALING, - MA_OPT_ACC_TIMING, - MA_OPT_ACC_SPRITES, - MA_OPT_SHOW_FPS, - MA_OPT_FRAMESKIP, - MA_OPT_ENABLE_SOUND, - MA_OPT_SOUND_QUALITY, - MA_OPT_ARM940_SOUND, - MA_OPT_6BUTTON_PAD, - MA_OPT_REGION, - MA_OPT_SRAM_STATES, - MA_OPT_CONFIRM_STATES, - MA_OPT_SAVE_SLOT, - MA_OPT_CPU_CLOCKS, - MA_OPT_SCD_OPTS, - MA_OPT_ADV_OPTS, - MA_OPT_SAVECFG, - MA_OPT_SAVECFG_GAME, - MA_OPT_LOADCFG, - MA_OPT2_GAMMA, - MA_OPT2_A_SN_GAMMA, - MA_OPT2_VSYNC, - MA_OPT2_ENABLE_Z80, - MA_OPT2_ENABLE_YM2612, - MA_OPT2_ENABLE_SN76496, - MA_OPT2_GZIP_STATES, - MA_OPT2_NO_LAST_ROM, - MA_OPT2_RAMTIMINGS, - MA_OPT2_SQUIDGEHACK, - MA_OPT2_DONE, - MA_CDOPT_TESTBIOS_USA, - MA_CDOPT_TESTBIOS_EUR, - MA_CDOPT_TESTBIOS_JAP, - MA_CDOPT_LEDS, - MA_CDOPT_CDDA, - MA_CDOPT_PCM, - MA_CDOPT_READAHEAD, - MA_CDOPT_SAVERAM, - MA_CDOPT_SCALEROT_CHIP, - MA_CDOPT_BETTER_SYNC, - MA_CDOPT_DONE, -} menu_id; - -typedef struct -{ - char *name; - menu_behavior beh; - menu_id id; - void *var; /* for on-off settings */ - int mask; - signed char min; /* for ranged integer settings, to be sign-extended */ - signed char max; - char enabled; -} menu_entry; - -static int me_id2offset(const menu_entry *entries, int count, menu_id id) -{ - int i; - for (i = 0; i < count; i++) - { - if (entries[i].id == id) return i; - } - - printf("%s: id %i not found\n", __FUNCTION__, id); - return 0; -} - -static void me_enable(menu_entry *entries, int count, menu_id id, int enable) -{ - int i = me_id2offset(entries, count, id); - entries[i].enabled = enable; -} - -static int me_count_enabled(const menu_entry *entries, int count) -{ - int i, ret = 0; - - for (i = 0; i < count; i++) - { - if (entries[i].enabled) ret++; - } - - return ret; -} - -static menu_id me_index2id(const menu_entry *entries, int count, int index) -{ - int i; - - for (i = 0; i < count; i++) - { - if (entries[i].enabled) - { - if (index == 0) break; - index--; - } - } - if (i >= count) i = count - 1; - return entries[i].id; -} - -typedef void (me_draw_custom_f)(const menu_entry *entry, int x, int y, void *param); - -static void me_draw(const menu_entry *entries, int count, int x, int y, me_draw_custom_f *cust_draw, void *param) -{ - int i, y1 = y; - - for (i = 0; i < count; i++) - { - if (!entries[i].enabled) continue; - if (entries[i].name == NULL) - { - if (cust_draw != NULL) - cust_draw(&entries[i], x, y1, param); - y1 += 10; - continue; - } - text_out16(x, y1, entries[i].name); - if (entries[i].beh == MB_ONOFF) - text_out16(x + 27*8, y1, (*(int *)entries[i].var & entries[i].mask) ? "ON" : "OFF"); - else if (entries[i].beh == MB_RANGE) - text_out16(x + 27*8, y1, "%i", *(int *)entries[i].var); - y1 += 10; - } -} - -static int me_process(menu_entry *entries, int count, menu_id id, int is_next) -{ - int i = me_id2offset(entries, count, id); - menu_entry *entry = &entries[i]; - switch (entry->beh) - { - case MB_ONOFF: - *(int *)entry->var ^= entry->mask; - return 1; - case MB_RANGE: - *(int *)entry->var += is_next ? 1 : -1; - if (*(int *)entry->var < (int)entry->min) *(int *)entry->var = (int)entry->min; - if (*(int *)entry->var > (int)entry->max) *(int *)entry->var = (int)entry->max; - return 1; - default: - return 0; - } -} - - -static int parse_hex_color(char *buff) -{ - char *endp = buff; - int t = (int) strtoul(buff, &endp, 16); - if (endp != buff) return ((t>>8)&0xf800) | ((t>>5)&0x07e0) | ((t>>3)&0x1f); - return -1; -} - -void menu_init(void) -{ - int c, l; - unsigned char *fd = menu_font_data; - char buff[256]; - FILE *f; - - // generate default font from fontdata8x8 - memset(menu_font_data, 0, sizeof(menu_font_data)); - for (c = 0; c < 256; c++) - { - for (l = 0; l < 8; l++) - { - unsigned char fd8x8 = fontdata8x8[c*8+l]; - if (fd8x8&0x80) *fd |= 0xf0; - if (fd8x8&0x40) *fd |= 0x0f; fd++; - if (fd8x8&0x20) *fd |= 0xf0; - if (fd8x8&0x10) *fd |= 0x0f; fd++; - if (fd8x8&0x08) *fd |= 0xf0; - if (fd8x8&0x04) *fd |= 0x0f; fd++; - if (fd8x8&0x02) *fd |= 0xf0; - if (fd8x8&0x01) *fd |= 0x0f; fd++; - } - fd += 8*2/2; // 2 empty lines - } - - // load custom font and selector (stored as 1st symbol in font table) - readpng(menu_font_data, "skin/font.png", READPNG_FONT); - memcpy(menu_font_data, menu_font_data + ((int)'>')*4*10, 4*10); // default selector symbol is '>' - readpng(menu_font_data, "skin/selector.png", READPNG_SELECTOR); - - // load custom colors - f = fopen("skin/skin.txt", "r"); - if (f != NULL) - { - printf("found skin.txt\n"); - while (!feof(f)) - { - fgets(buff, sizeof(buff), f); - if (buff[0] == '#' || buff[0] == '/') continue; // comment - if (buff[0] == '\r' || buff[0] == '\n') continue; // empty line - if (strncmp(buff, "text_color=", 11) == 0) - { - int tmp = parse_hex_color(buff+11); - if (tmp >= 0) menu_text_color = tmp; - else printf("skin.txt: parse error for text_color\n"); - } - else if (strncmp(buff, "selection_color=", 16) == 0) - { - int tmp = parse_hex_color(buff+16); - if (tmp >= 0) menu_sel_color = tmp; - else printf("skin.txt: parse error for selection_color\n"); - } - else - printf("skin.txt: parse error: %s\n", buff); - } - fclose(f); - } -} - static unsigned long inp_prev = 0; static int inp_prevjoy = 0; @@ -500,6 +129,11 @@ static unsigned long wait_for_input_usbjoy(unsigned long interesting, int *joy) return ret; } +static void menu_flip(void) +{ + gp2x_video_flush_cache(); + gp2x_video_flip2(); +} // --------- loading ROM screen ---------- @@ -887,7 +521,7 @@ static void draw_savestate_menu(int menu_sel, int is_loading) text_out16(tl_x, 30, is_loading ? "Load state" : "Save state"); - draw_selection(tl_x - 16, tl_y + menu_sel*10, 108); + menu_draw_selection(tl_x - 16, tl_y + menu_sel*10, 108); /* draw all 10 slots */ y = tl_y; @@ -1029,7 +663,7 @@ static void draw_key_config(const bind_action_t *opts, int opt_cnt, int player_i x = 40; } - draw_selection(x - 16, tl_y + sel*10, (player_idx >= 0) ? 66 : 130); + menu_draw_selection(x - 16, tl_y + sel*10, (player_idx >= 0) ? 66 : 130); y = tl_y; for (i = 0; i < opt_cnt; i++, y+=10) @@ -1110,7 +744,7 @@ static void draw_kc_sel(int menu_sel) y = tl_y; gp2x_pd_clone_buffer2(); - draw_selection(tl_x - 16, tl_y + menu_sel*10, 138); + menu_draw_selection(tl_x - 16, tl_y + menu_sel*10, 138); text_out16(tl_x, y, "Player 1"); text_out16(tl_x, (y+=10), "Player 2"); @@ -1246,7 +880,7 @@ static void draw_cd_menu_options(int menu_sel, struct bios_names_t *bios_names) gp2x_pd_clone_buffer2(); - draw_selection(tl_x - 16, tl_y + menu_sel*10, 246); + menu_draw_selection(tl_x - 16, tl_y + menu_sel*10, 246); me_draw(cdopt_entries, CDOPT_ENTRY_COUNT, tl_x, tl_y, menu_cdopt_cust_draw, bios_names); @@ -1347,7 +981,7 @@ menu_entry opt2_entries[] = { { NULL, MB_NONE, MA_OPT2_GAMMA, NULL, 0, 0, 0, 1 }, { "A_SN's gamma curve", MB_ONOFF, MA_OPT2_A_SN_GAMMA, ¤tConfig.EmuOpt, 0x1000, 0, 0, 1 }, - { "Perfecf vsync", MB_ONOFF, MA_OPT2_VSYNC, ¤tConfig.EmuOpt, 0x2000, 0, 0, 1 }, + { "Perfect vsync", MB_ONOFF, MA_OPT2_VSYNC, ¤tConfig.EmuOpt, 0x2000, 0, 0, 1 }, { "Emulate Z80", MB_ONOFF, MA_OPT2_ENABLE_Z80, ¤tConfig.PicoOpt,0x0004, 0, 0, 1 }, { "Emulate YM2612 (FM)", MB_ONOFF, MA_OPT2_ENABLE_YM2612, ¤tConfig.PicoOpt,0x0001, 0, 0, 1 }, { "Emulate SN76496 (PSG)", MB_ONOFF, MA_OPT2_ENABLE_SN76496,¤tConfig.PicoOpt,0x0002, 0, 0, 1 }, @@ -1377,7 +1011,7 @@ static void draw_amenu_options(int menu_sel) gp2x_pd_clone_buffer2(); - draw_selection(tl_x - 16, tl_y + menu_sel*10, 252); + menu_draw_selection(tl_x - 16, tl_y + menu_sel*10, 252); me_draw(opt2_entries, OPT2_ENTRY_COUNT, tl_x, tl_y, menu_opt2_cust_draw, NULL); @@ -1546,7 +1180,7 @@ static void draw_menu_options(int menu_sel) gp2x_pd_clone_buffer2(); - draw_selection(tl_x - 16, tl_y + menu_sel*10, 284); + menu_draw_selection(tl_x - 16, tl_y + menu_sel*10, 284); me_draw(opt_entries, OPT_ENTRY_COUNT, tl_x, tl_y, menu_opt_cust_draw, NULL); @@ -1785,7 +1419,7 @@ static void draw_menu_root(int menu_sel) text_out16(tl_x, 20, "PicoDrive v" VERSION); - draw_selection(tl_x - 16, tl_y + menu_sel*10, 146); + menu_draw_selection(tl_x - 16, tl_y + menu_sel*10, 146); me_draw(main_entries, MAIN_ENTRY_COUNT, tl_x, tl_y, NULL, NULL); @@ -2008,7 +1642,7 @@ int menu_loop_tray(void) char curr_path[PATH_MAX], *selfname; FILE *tstf; - gp2x_memset_all_buffers(0, 0xe0, 320*240); + gp2x_memset_all_buffers(0, 0, 320*240*2); menu_gfx_prepare(); if ( (tstf = fopen(currentConfig.lastRomFile, "rb")) ) diff --git a/gp2x/menu.h b/gp2x/menu.h index 62ec051..bd216a4 100644 --- a/gp2x/menu.h +++ b/gp2x/menu.h @@ -5,8 +5,6 @@ extern char menuErrorMsg[40]; -void menu_init(void); -void text_out16(int x, int y, const char *texto, ...); void menu_loop(void); int menu_loop_tray(void); void menu_romload_prepare(const char *rom_name); diff --git a/linux/Makefile b/linux/Makefile index a85ef43..3380ae9 100644 --- a/linux/Makefile +++ b/linux/Makefile @@ -24,8 +24,12 @@ COPT += `pkg-config --cflags gthread-2.0` LDFLAGS += `pkg-config --libs gthread-2.0` # frontend -OBJS += ../gp2x/main.o ../gp2x/menu.o ../gp2x/fonts.o ../gp2x/emu.o ../gp2x/usbjoy.o blit.o \ - gp2x.o 940ctl_ym2612.o ../gp2x/readpng.o +OBJS += ../gp2x/main.o ../gp2x/menu.o ../gp2x/emu.o ../gp2x/usbjoy.o blit.o \ + gp2x.o 940ctl_ym2612.o + +# common +OBJS += ../common/menu.o ../common/fonts.o ../common/readpng.o + # Pico OBJS += ../../Pico/Area.o ../../Pico/Cart.o ../../Pico/Memory.o ../../Pico/Misc.o \ ../../Pico/Pico.o ../../Pico/Sek.o ../../Pico/VideoPort.o ../../Pico/Draw2.o ../../Pico/Draw.o \ -- 2.39.2