giz menu works

git-svn-id: file:///home/notaz/opt/svn/PicoDrive/platform@231 be3aeb3a-fb24-0410-a615-afba39da0efa
This commit is contained in:
notaz 2007-09-01 11:07:03 +00:00
parent 51b55351d2
commit c7a4ff6428
17 changed files with 471 additions and 411 deletions

6
common/lprintf.h Normal file
View file

@ -0,0 +1,6 @@
#if defined(__GP2X__)
#define lprintf printf
#else
#include "giz.h"
#endif

314
common/menu.c Normal file
View file

@ -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 <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdarg.h>
#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;
}
}

98
common/menu.h Normal file
View file

@ -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);

View file

@ -2,6 +2,7 @@
#include <string.h> #include <string.h>
#include <png.h> #include <png.h>
#include "readpng.h" #include "readpng.h"
#include "lprintf.h"
void readpng(void *dest, const char *fname, readpng_what what) 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"); fp = fopen(fname, "rb");
if (fp == NULL) if (fp == NULL)
{ {
printf(__FILE__ ": failed to open: %s\n", fname); lprintf(__FILE__ ": failed to open: %s\n", fname);
return; return;
} }
png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
if (!png_ptr) if (!png_ptr)
{ {
printf(__FILE__ ": png_create_read_struct() failed\n"); lprintf(__FILE__ ": png_create_read_struct() failed\n");
fclose(fp); fclose(fp);
return; return;
} }
@ -33,7 +34,7 @@ void readpng(void *dest, const char *fname, readpng_what what)
info_ptr = png_create_info_struct(png_ptr); info_ptr = png_create_info_struct(png_ptr);
if (!info_ptr) if (!info_ptr)
{ {
printf(__FILE__ ": png_create_info_struct() failed\n"); lprintf(__FILE__ ": png_create_info_struct() failed\n");
goto done; 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); row_ptr = png_get_rows(png_ptr, info_ptr);
if (row_ptr == NULL) if (row_ptr == NULL)
{ {
printf(__FILE__ ": png_get_rows() failed\n"); lprintf(__FILE__ ": png_get_rows() failed\n");
goto done; 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) switch (what)
{ {
@ -57,7 +58,7 @@ void readpng(void *dest, const char *fname, readpng_what what)
unsigned short *dst = dest; unsigned short *dst = dest;
if (info_ptr->pixel_depth != 24) 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; break;
} }
height = info_ptr->height; height = info_ptr->height;
@ -85,13 +86,13 @@ void readpng(void *dest, const char *fname, readpng_what what)
unsigned char *dst = dest; unsigned char *dst = dest;
if (info_ptr->width != 128 || info_ptr->height != 160) 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); (int)info_ptr->width, (int)info_ptr->height);
break; break;
} }
if (info_ptr->pixel_depth != 8) 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; break;
} }
for (y = 0; y < 16; y++) for (y = 0; y < 16; y++)
@ -115,13 +116,13 @@ void readpng(void *dest, const char *fname, readpng_what what)
unsigned char *dst = dest; unsigned char *dst = dest;
if (info_ptr->width != 8 || info_ptr->height != 10) 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); (int)info_ptr->width, (int)info_ptr->height);
break; break;
} }
if (info_ptr->pixel_depth != 8) 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; break;
} }
for (y1 = 0; y1 < 10; y1++) for (y1 = 0; y1 < 10; y1++)

View file

@ -14,8 +14,9 @@
#include "gp2x.h" #include "gp2x.h"
#include "emu.h" #include "emu.h"
#include "menu.h" #include "menu.h"
#include "asmutils.h"
#include "mp3.h" #include "mp3.h"
#include "../common/arm_utils.h"
#include "../common/menu.h"
#include "../../Pico/PicoInt.h" #include "../../Pico/PicoInt.h"
#include "../../Pico/sound/mix.h" #include "../../Pico/sound/mix.h"

View file

@ -48,10 +48,13 @@ LD = $(CROSS)ld
OBJCOPY = $(CROSS)objcopy OBJCOPY = $(CROSS)objcopy
# frontend # 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 # 940 core control
OBJS += 940ctl.o OBJS += 940ctl.o
# common
OBJS += ../common/menu.o ../common/fonts.o ../common/arm_utils.o ../common/readpng.o
# Pico # Pico
ifeq "$(amalgamate)" "1" ifeq "$(amalgamate)" "1"
OBJS += ../../PicoAll.o OBJS += ../../PicoAll.o
@ -148,7 +151,7 @@ up: PicoDrive.gpe
# @cmd //C copy PicoDrive.gpe \\\\10.0.1.2\\gp2x\\mnt\\sd\\games\\PicoDrive\\ # @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 $@ @echo $@
@$(GCC) $(COPT) $^ -o $@ @$(GCC) $(COPT) $^ -o $@
@$(STRIP) $@ @$(STRIP) $@

View file

@ -18,9 +18,9 @@
#include "gp2x.h" #include "gp2x.h"
#include "usbjoy.h" #include "usbjoy.h"
#include "menu.h" #include "menu.h"
#include "asmutils.h" #include "../common/arm_utils.h"
#include "../common/fonts.h"
#include "cpuctrl.h" #include "cpuctrl.h"
#include "fonts.h"
#include <Pico/PicoInt.h> #include <Pico/PicoInt.h>
#include <Pico/Patch.h> #include <Pico/Patch.h>
@ -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 int gp2x_old_gamma = 100;
static unsigned char *movie_data = NULL; static unsigned char *movie_data = NULL;
static int movie_size = 0; 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 state_slot = 0;
int reset_timing = 0; int reset_timing = 0;
int config_slot = 0, config_slot_current = 0; int config_slot = 0, config_slot_current = 0;
@ -389,10 +389,10 @@ static void emu_msg_tray_open(void);
void emu_Init(void) void emu_Init(void)
{ {
// make temp buffer for alt renderer // make temp buffer for alt renderer
framebuff = malloc((8+320)*(8+240+8)); PicoDraw2FB = malloc((8+320)*(8+240+8));
if (!framebuff) if (!PicoDraw2FB)
{ {
printf("framebuff == 0\n"); printf("PicoDraw2FB == 0\n");
} }
// make dirs for saves, cfgs, etc. // make dirs for saves, cfgs, etc.
@ -626,7 +626,7 @@ void emu_Deinit(void)
} }
} }
free(framebuff); free(PicoDraw2FB);
PicoExit(); PicoExit();
@ -768,7 +768,7 @@ static void blit(const char *fps, const char *notice)
// feed new palette to our device // feed new palette to our device
gp2x_video_setpalette(localPal, 0x40); 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)) { } else if (!(emu_opt&0x80)) {
// 8bit accurate renderer // 8bit accurate renderer
if (Pico.m.dirtyPal) { if (Pico.m.dirtyPal) {
@ -1112,7 +1112,7 @@ void emu_forced_frame(void)
clearArea(1); clearArea(1);
} else vidCpyM2 = vidCpyM2_40col; } 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); vidConvCpyRGB32(localPal, Pico.cram, 0x40);
gp2x_video_setpalette(localPal, 0x40); gp2x_video_setpalette(localPal, 0x40);
*/ */

View file

@ -34,7 +34,7 @@
#include "gp2x.h" #include "gp2x.h"
#include "usbjoy.h" #include "usbjoy.h"
#include "asmutils.h" #include "../common/arm_utils.h"
volatile unsigned short *gp2x_memregs; volatile unsigned short *gp2x_memregs;
//static //static

View file

@ -11,6 +11,7 @@
#include "gp2x.h" #include "gp2x.h"
#include "menu.h" #include "menu.h"
#include "../common/menu.h"
#include "emu.h" #include "emu.h"
#include "940ctl.h" #include "940ctl.h"
#include "version.h" #include "version.h"

View file

@ -13,10 +13,10 @@
#include "gp2x.h" #include "gp2x.h"
#include "emu.h" #include "emu.h"
#include "menu.h" #include "menu.h"
#include "fonts.h"
#include "usbjoy.h" #include "usbjoy.h"
#include "asmutils.h" #include "../common/arm_utils.h"
#include "readpng.h" #include "../common/menu.h"
#include "../common/readpng.h"
#include "version.h" #include "version.h"
#include <Pico/PicoInt.h> #include <Pico/PicoInt.h>
@ -33,389 +33,18 @@ extern int mmuhack_status;
extern int state_slot; extern int state_slot;
extern int config_slot, config_slot_current; extern int config_slot, config_slot_current;
static unsigned char menu_font_data[10240]; static const char *gp2xKeyNames[] = {
static char *gp2xKeyNames[] = {
"UP", "???", "LEFT", "???", "DOWN", "???", "RIGHT", "???", "UP", "???", "LEFT", "???", "DOWN", "???", "RIGHT", "???",
"START", "SELECT", "L", "R", "A", "B", "X", "Y", "START", "SELECT", "L", "R", "A", "B", "X", "Y",
"???", "???", "???", "???", "???", "???", "VOL DOWN", "VOL UP", "???", "???", "???", "???", "???", "???", "VOL DOWN", "VOL UP",
"???", "???", "???", "PUSH", "???", "???", "???", "???" "???", "???", "???", "PUSH", "???", "???", "???", "???"
}; };
static int menu_text_color = 0xffff; // default to white
static int menu_sel_color = -1; // disabled
char menuErrorMsg[40] = {0, }; char menuErrorMsg[40] = {0, };
static void menu_darken_bg(void *dst, int pixels, int darker); static void menu_darken_bg(void *dst, int pixels, int darker);
static void menu_prepare_bg(int use_game_bg); 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 unsigned long inp_prev = 0;
static int inp_prevjoy = 0; static int inp_prevjoy = 0;
@ -500,6 +129,11 @@ static unsigned long wait_for_input_usbjoy(unsigned long interesting, int *joy)
return ret; return ret;
} }
static void menu_flip(void)
{
gp2x_video_flush_cache();
gp2x_video_flip2();
}
// --------- loading ROM screen ---------- // --------- 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"); 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 */ /* draw all 10 slots */
y = tl_y; 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; 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; y = tl_y;
for (i = 0; i < opt_cnt; i++, y+=10) for (i = 0; i < opt_cnt; i++, y+=10)
@ -1110,7 +744,7 @@ static void draw_kc_sel(int menu_sel)
y = tl_y; y = tl_y;
gp2x_pd_clone_buffer2(); 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, "Player 1");
text_out16(tl_x, (y+=10), "Player 2"); 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(); 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); 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 }, { NULL, MB_NONE, MA_OPT2_GAMMA, NULL, 0, 0, 0, 1 },
{ "A_SN's gamma curve", MB_ONOFF, MA_OPT2_A_SN_GAMMA, &currentConfig.EmuOpt, 0x1000, 0, 0, 1 }, { "A_SN's gamma curve", MB_ONOFF, MA_OPT2_A_SN_GAMMA, &currentConfig.EmuOpt, 0x1000, 0, 0, 1 },
{ "Perfecf vsync", MB_ONOFF, MA_OPT2_VSYNC, &currentConfig.EmuOpt, 0x2000, 0, 0, 1 }, { "Perfect vsync", MB_ONOFF, MA_OPT2_VSYNC, &currentConfig.EmuOpt, 0x2000, 0, 0, 1 },
{ "Emulate Z80", MB_ONOFF, MA_OPT2_ENABLE_Z80, &currentConfig.PicoOpt,0x0004, 0, 0, 1 }, { "Emulate Z80", MB_ONOFF, MA_OPT2_ENABLE_Z80, &currentConfig.PicoOpt,0x0004, 0, 0, 1 },
{ "Emulate YM2612 (FM)", MB_ONOFF, MA_OPT2_ENABLE_YM2612, &currentConfig.PicoOpt,0x0001, 0, 0, 1 }, { "Emulate YM2612 (FM)", MB_ONOFF, MA_OPT2_ENABLE_YM2612, &currentConfig.PicoOpt,0x0001, 0, 0, 1 },
{ "Emulate SN76496 (PSG)", MB_ONOFF, MA_OPT2_ENABLE_SN76496,&currentConfig.PicoOpt,0x0002, 0, 0, 1 }, { "Emulate SN76496 (PSG)", MB_ONOFF, MA_OPT2_ENABLE_SN76496,&currentConfig.PicoOpt,0x0002, 0, 0, 1 },
@ -1377,7 +1011,7 @@ static void draw_amenu_options(int menu_sel)
gp2x_pd_clone_buffer2(); 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); 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(); 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); 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); 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); 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; char curr_path[PATH_MAX], *selfname;
FILE *tstf; FILE *tstf;
gp2x_memset_all_buffers(0, 0xe0, 320*240); gp2x_memset_all_buffers(0, 0, 320*240*2);
menu_gfx_prepare(); menu_gfx_prepare();
if ( (tstf = fopen(currentConfig.lastRomFile, "rb")) ) if ( (tstf = fopen(currentConfig.lastRomFile, "rb")) )

View file

@ -5,8 +5,6 @@
extern char menuErrorMsg[40]; extern char menuErrorMsg[40];
void menu_init(void);
void text_out16(int x, int y, const char *texto, ...);
void menu_loop(void); void menu_loop(void);
int menu_loop_tray(void); int menu_loop_tray(void);
void menu_romload_prepare(const char *rom_name); void menu_romload_prepare(const char *rom_name);

View file

@ -24,8 +24,12 @@ COPT += `pkg-config --cflags gthread-2.0`
LDFLAGS += `pkg-config --libs gthread-2.0` LDFLAGS += `pkg-config --libs gthread-2.0`
# frontend # frontend
OBJS += ../gp2x/main.o ../gp2x/menu.o ../gp2x/fonts.o ../gp2x/emu.o ../gp2x/usbjoy.o blit.o \ OBJS += ../gp2x/main.o ../gp2x/menu.o ../gp2x/emu.o ../gp2x/usbjoy.o blit.o \
gp2x.o 940ctl_ym2612.o ../gp2x/readpng.o gp2x.o 940ctl_ym2612.o
# common
OBJS += ../common/menu.o ../common/fonts.o ../common/readpng.o
# Pico # Pico
OBJS += ../../Pico/Area.o ../../Pico/Cart.o ../../Pico/Memory.o ../../Pico/Misc.o \ 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 \ ../../Pico/Pico.o ../../Pico/Sek.o ../../Pico/VideoPort.o ../../Pico/Draw2.o ../../Pico/Draw.o \