From f6eaae4f09c6abab99692900a31c1df2a06b99af Mon Sep 17 00:00:00 2001 From: notaz Date: Mon, 31 May 2010 22:12:46 +0000 Subject: [PATCH] tweaking pandora frontend git-svn-id: file:///home/notaz/opt/svn/PicoDrive/platform@874 be3aeb3a-fb24-0410-a615-afba39da0efa --- common/menu.c | 29 ++++---- common/readpng.c | 55 +++++++------- common/readpng.h | 5 +- linux/fbdev.c | 2 +- linux/in_evdev.c | 24 +++---- linux/{x11h.c => oshide.c} | 108 +++++++++++++++++++++++++--- linux/oshide.h | 3 + linux/x11h.h | 2 - pandora/Makefile | 4 +- pandora/asm_utils.h | 3 +- pandora/asm_utils.s | 60 ++++++++++++++-- pandora/emu.c | 143 +++++++++++++++++++++---------------- pandora/menu.c | 8 ++- pandora/pandora.c | 7 +- pandora/picorestore.c | 67 +++++++++++++++++ win32/main.c | 2 +- 16 files changed, 378 insertions(+), 144 deletions(-) rename linux/{x11h.c => oshide.c} (64%) create mode 100644 linux/oshide.h delete mode 100644 linux/x11h.h create mode 100644 pandora/picorestore.c diff --git a/common/menu.c b/common/menu.c index 9402796..fdc8e89 100644 --- a/common/menu.c +++ b/common/menu.c @@ -187,11 +187,11 @@ static void menu_draw_selection(int x, int y, int w) if (menu_sel_color < 0) return; // no selection hilight if (y > 0) y--; - dest = (unsigned short *)g_screen_ptr + x + y * g_screen_width + 14; + dest = (unsigned short *)g_screen_ptr + x + y * g_screen_width + me_mfont_w * 2 - 2; for (h = me_mfont_h + 1; h > 0; h--) { dst = dest; - for (i = w - 14; i > 0; i--) + for (i = w - (me_mfont_w * 2 - 2); i > 0; i--) *dst++ = menu_sel_color; dest += g_screen_width; } @@ -268,12 +268,13 @@ void menu_init(void) // load custom font and selector (stored as 1st symbol in font table) emu_make_path(buff, "skin/font.png", sizeof(buff)); - readpng(menu_font_data, buff, READPNG_FONT); + readpng(menu_font_data, buff, READPNG_FONT, + MENU_X2 ? 256 : 128, MENU_X2 ? 320 : 160); // default selector symbol is '>' memcpy(menu_font_data, menu_font_data + ((int)'>') * me_mfont_w * me_mfont_h / 2, me_mfont_w * me_mfont_h / 2); emu_make_path(buff, "skin/selector.png", sizeof(buff)); - readpng(menu_font_data, buff, READPNG_SELECTOR); + readpng(menu_font_data, buff, READPNG_SELECTOR, MENU_X2 ? 16 : 8, MENU_X2 ? 20 : 10); // load custom colors emu_make_path(buff, "skin/skin.txt", sizeof(buff)); @@ -343,7 +344,7 @@ static void menu_enter(int is_rom_loaded) // should really only happen once, on startup.. emu_make_path(buff, "skin/background.png", sizeof(buff)); - if (readpng(g_menubg_ptr, buff, READPNG_BG) < 0) + if (readpng(g_menubg_ptr, buff, READPNG_BG, g_screen_width, g_screen_height) < 0) memset(g_menubg_ptr, 0, g_screen_width * g_screen_height * 2); } @@ -378,11 +379,11 @@ static int me_count(const menu_entry *ent) static void me_draw(const menu_entry *entries, int sel, void (*draw_more)(void)) { - const menu_entry *ent; + const menu_entry *ent, *ent_sel = entries; int x, y, w = 0, h = 0; int offs, col2_offs = 27 * me_mfont_w; + int vi_sel_ln = 0; const char *name; - int asel = 0; int i, n; /* calculate size of menu rect */ @@ -393,8 +394,10 @@ static void me_draw(const menu_entry *entries, int sel, void (*draw_more)(void)) if (!ent->enabled) continue; - if (i == sel) - asel = n; + if (i == sel) { + ent_sel = ent; + vi_sel_ln = n; + } name = NULL; wt = strlen(ent->name) * me_mfont_w; @@ -450,7 +453,7 @@ static void me_draw(const menu_entry *entries, int sel, void (*draw_more)(void)) /* draw */ plat_video_menu_begin(); - menu_draw_selection(x, y + asel * me_mfont_h, w); + menu_draw_selection(x, y + vi_sel_ln * me_mfont_h, w); x += me_mfont_w * 2; for (ent = entries; ent->name; ent++) @@ -517,13 +520,13 @@ static void me_draw(const menu_entry *entries, int sel, void (*draw_more)(void)) if (plat_get_ticks_ms() - menu_error_time > 2048) menu_error_msg[0] = 0; } - else if (entries[asel].help != NULL) { - const char *tmp = entries[asel].help; + else if (ent_sel->help != NULL) { + const char *tmp = ent_sel->help; int l; for (l = 0; tmp != NULL && *tmp != 0; l++) tmp = strchr(tmp + 1, '\n'); if (h >= l * me_sfont_h + 4) - for (tmp = entries[asel].help; l > 0; l--, tmp = strchr(tmp, '\n') + 1) + for (tmp = ent_sel->help; l > 0; l--, tmp = strchr(tmp, '\n') + 1) smalltext_out16(5, g_screen_height - (l * me_sfont_h + 4), tmp, 0xffff); } diff --git a/common/readpng.c b/common/readpng.c index a437a52..50e8834 100644 --- a/common/readpng.c +++ b/common/readpng.c @@ -4,15 +4,7 @@ #include "readpng.h" #include "lprintf.h" -#ifdef PSP -#define BG_WIDTH 480 -#define BG_HEIGHT 272 -#else -#define BG_WIDTH 320 -#define BG_HEIGHT 240 -#endif - -int readpng(void *dest, const char *fname, readpng_what what) +int readpng(void *dest, const char *fname, readpng_what what, int req_w, int req_h) { FILE *fp; png_structp png_ptr = NULL; @@ -71,9 +63,11 @@ int readpng(void *dest, const char *fname, readpng_what what) break; } height = info_ptr->height; - if (height > BG_HEIGHT) height = BG_HEIGHT; + if (height > req_h) + height = req_h; width = info_ptr->width; - if (width > BG_WIDTH) width = BG_WIDTH; + if (width > req_w) + width = req_w; for (h = 0; h < height; h++) { @@ -88,7 +82,7 @@ int readpng(void *dest, const char *fname, readpng_what what) #endif src += 3; } - dst += BG_WIDTH - width; + dst += req_w - width; } break; } @@ -97,10 +91,10 @@ int readpng(void *dest, const char *fname, readpng_what what) { int x, y, x1, y1; unsigned char *dst = dest; - if (info_ptr->width != 128 || info_ptr->height != 160) + if (info_ptr->width != req_w || info_ptr->height != req_h) { - lprintf(__FILE__ ": unexpected font image size %ix%i, needed 128x160\n", - (int)info_ptr->width, (int)info_ptr->height); + lprintf(__FILE__ ": unexpected font image size %dx%d, needed %dx%d\n", + (int)info_ptr->width, (int)info_ptr->height, req_w, req_h); break; } if (info_ptr->pixel_depth != 8) @@ -112,10 +106,13 @@ int readpng(void *dest, const char *fname, readpng_what what) { for (x = 0; x < 16; x++) { - for (y1 = 0; y1 < 10; y1++) + /* 16x16 grid of syms */ + int sym_w = req_w / 16; + int sym_h = req_h / 16; + for (y1 = 0; y1 < sym_h; y1++) { - unsigned char *src = row_ptr[y*10 + y1] + x*8; - for (x1 = 8/2; x1 > 0; x1--, src+=2) + unsigned char *src = row_ptr[y*sym_h + y1] + x*sym_w; + for (x1 = sym_w/2; x1 > 0; x1--, src+=2) *dst++ = ((src[0]^0xff) & 0xf0) | ((src[1]^0xff) >> 4); } } @@ -127,10 +124,10 @@ int readpng(void *dest, const char *fname, readpng_what what) { int x1, y1; unsigned char *dst = dest; - if (info_ptr->width != 8 || info_ptr->height != 10) + if (info_ptr->width != req_w || info_ptr->height != req_h) { - lprintf(__FILE__ ": unexpected selector image size %ix%i, needed 8x10\n", - (int)info_ptr->width, (int)info_ptr->height); + lprintf(__FILE__ ": unexpected selector image size %ix%i, needed %dx%d\n", + (int)info_ptr->width, (int)info_ptr->height, req_w, req_h); break; } if (info_ptr->pixel_depth != 8) @@ -138,20 +135,18 @@ int readpng(void *dest, const char *fname, readpng_what what) lprintf(__FILE__ ": selector image uses %ibpp, needed 8bpp\n", info_ptr->pixel_depth); break; } - for (y1 = 0; y1 < 10; y1++) + for (y1 = 0; y1 < req_h; y1++) { unsigned char *src = row_ptr[y1]; - for (x1 = 8/2; x1 > 0; x1--, src+=2) + for (x1 = req_w/2; x1 > 0; x1--, src+=2) *dst++ = ((src[0]^0xff) & 0xf0) | ((src[1]^0xff) >> 4); } break; } - case READPNG_320_24: - case READPNG_480_24: + case READPNG_24: { int height, width, h; - int needw = (what == READPNG_480_24) ? 480 : 320; unsigned char *dst = dest; if (info_ptr->pixel_depth != 24) { @@ -159,15 +154,17 @@ int readpng(void *dest, const char *fname, readpng_what what) break; } height = info_ptr->height; - if (height > 240) height = 240; + if (height > req_h) + height = req_h; width = info_ptr->width; - if (width > needw) width = needw; + if (width > req_w) + width = req_w; for (h = 0; h < height; h++) { int len = width; unsigned char *src = row_ptr[h]; - dst += (needw - width) * 3; + dst += (req_w - width) * 3; for (len = width; len > 0; len--, dst+=3, src+=3) dst[0] = src[2], dst[1] = src[1], dst[2] = src[0]; } diff --git a/common/readpng.h b/common/readpng.h index 7d74fee..ce5d635 100644 --- a/common/readpng.h +++ b/common/readpng.h @@ -3,8 +3,7 @@ typedef enum READPNG_BG = 1, READPNG_FONT, READPNG_SELECTOR, - READPNG_320_24, - READPNG_480_24 + READPNG_24, } readpng_what; @@ -12,7 +11,7 @@ readpng_what; extern "C" { #endif -int readpng(void *dest, const char *fname, readpng_what what); +int readpng(void *dest, const char *fname, readpng_what what, int w, int h); #ifdef __cplusplus } diff --git a/linux/fbdev.c b/linux/fbdev.c index 474f708..adf7a3d 100644 --- a/linux/fbdev.c +++ b/linux/fbdev.c @@ -95,9 +95,9 @@ int vout_fbdev_init(int *w, int *h) fbdev_mem_size = *w * *h * 2 * fbdev_buffer_count; fbdev_mem = mmap(0, fbdev_mem_size, PROT_WRITE|PROT_READ, MAP_SHARED, fbdev, 0); if (fbdev_mem == MAP_FAILED && fbdev_buffer_count > 1) { + fprintf(stderr, "Warning: can't map %d bytes, doublebuffering disabled\n", fbdev_mem_size); fbdev_mem_size = *w * *h * 2; fbdev_buffer_count = 1; - fprintf(stderr, "Warning: can't map %d bytes, doublebuffering disabled\n", fbdev_mem_size); fbdev_mem = mmap(0, fbdev_mem_size, PROT_WRITE|PROT_READ, MAP_SHARED, fbdev, 0); } if (fbdev_mem == MAP_FAILED) { diff --git a/linux/in_evdev.c b/linux/in_evdev.c index 631bb3d..8a00296 100644 --- a/linux/in_evdev.c +++ b/linux/in_evdev.c @@ -411,20 +411,20 @@ static const struct { { KEY_LEFT, PBTN_LEFT }, { KEY_RIGHT, PBTN_RIGHT }, { KEY_ENTER, PBTN_MOK }, - { KEY_KP2, PBTN_MOK }, + { KEY_END, PBTN_MOK }, { BTN_TRIGGER, PBTN_MOK }, { KEY_ESC, PBTN_MBACK }, - { KEY_KP3, PBTN_MBACK }, + { KEY_PAGEDOWN, PBTN_MBACK }, { BTN_THUMB, PBTN_MBACK }, { KEY_A, PBTN_MA2 }, - { KEY_KP4, PBTN_MA2 }, + { KEY_HOME, PBTN_MA2 }, { KEY_S, PBTN_MA3 }, - { KEY_KP1, PBTN_MA3 }, + { KEY_PAGEUP, PBTN_MA3 }, { KEY_BACKSLASH, PBTN_MENU }, { KEY_LEFTCTRL, PBTN_MENU }, - { BTN_TL, PBTN_L }, + { KEY_RIGHTSHIFT, PBTN_L }, { KEY_LEFTBRACE, PBTN_L }, - { BTN_TR, PBTN_R }, + { KEY_RIGHTCTRL, PBTN_R }, { KEY_RIGHTBRACE, PBTN_R }, }; @@ -487,16 +487,16 @@ static const struct { { KEY_LEFT, IN_BINDTYPE_PLAYER12, 2 }, { KEY_RIGHT, IN_BINDTYPE_PLAYER12, 3 }, { KEY_S, IN_BINDTYPE_PLAYER12, 4 }, /* B */ - { KEY_KP3, IN_BINDTYPE_PLAYER12, 4 }, + { KEY_PAGEDOWN, IN_BINDTYPE_PLAYER12, 4 }, { KEY_D, IN_BINDTYPE_PLAYER12, 5 }, /* C */ - { KEY_KP2, IN_BINDTYPE_PLAYER12, 5 }, + { KEY_END, IN_BINDTYPE_PLAYER12, 5 }, { KEY_A, IN_BINDTYPE_PLAYER12, 6 }, /* A */ - { KEY_KP4, IN_BINDTYPE_PLAYER12, 6 }, + { KEY_HOME, IN_BINDTYPE_PLAYER12, 6 }, { KEY_ENTER, IN_BINDTYPE_PLAYER12, 7 }, { KEY_LEFTALT, IN_BINDTYPE_PLAYER12, 7 }, - { BTN_TL, IN_BINDTYPE_EMU, PEVB_STATE_LOAD }, - { BTN_TR, IN_BINDTYPE_EMU, PEVB_STATE_SAVE }, - { KEY_LEFTCTRL, IN_BINDTYPE_EMU, PEVB_MENU }, + { KEY_RIGHTSHIFT,IN_BINDTYPE_EMU, PEVB_STATE_SAVE }, + { KEY_RIGHTCTRL, IN_BINDTYPE_EMU, PEVB_STATE_LOAD }, + { KEY_LEFTCTRL, IN_BINDTYPE_EMU, PEVB_MENU }, }; #define DEF_BIND_COUNT (sizeof(in_evdev_def_binds) / sizeof(in_evdev_def_binds[0])) diff --git a/linux/x11h.c b/linux/oshide.c similarity index 64% rename from linux/x11h.c rename to linux/oshide.c index 4ca5d30..e66aaae 100644 --- a/linux/x11h.c +++ b/linux/oshide.c @@ -1,10 +1,22 @@ #include #include #include + #include #include #include +#include +#include +#include +#include +#include +#include +#include + +#define PFX "oshide: " +#define TERMIOS_DUMP_FILE "/tmp/pico_tios" + #define FPTR(f) typeof(f) * p##f #define FPTR_LINK(xf, dl, f) { \ xf.p##f = dlsym(dl, #f); \ @@ -92,13 +104,9 @@ static void *x11h_handler(void *arg) visual = DefaultVisual(display, 0); if (visual->class != TrueColor) - { - fprintf(stderr, "cannot handle non true color visual\n"); - xf.pXCloseDisplay(display); - goto fail2; - } + fprintf(stderr, PFX "warning: non true color visual\n"); - printf("x11h: X vendor: %s, rel: %d, display: %s, protocol ver: %d.%d\n", ServerVendor(display), + printf(PFX "X vendor: %s, rel: %d, display: %s, protocol ver: %d.%d\n", ServerVendor(display), VendorRelease(display), DisplayString(display), ProtocolVersion(display), ProtocolRevision(display)); @@ -106,7 +114,7 @@ static void *x11h_handler(void *arg) display_width = DisplayWidth(display, screen); display_height = DisplayHeight(display, screen); - printf("x11h: display is %dx%d\n", display_width, display_height); + printf(PFX "display is %dx%d\n", display_width, display_height); win = xf.pXCreateSimpleWindow(display, RootWindow(display, screen), @@ -155,21 +163,103 @@ fail: return NULL; } -int x11h_init(void) +static struct termios g_kbd_termios_saved; +static int g_kbdfd; + +static void hidecon_start(void) +{ + struct termios kbd_termios; + FILE *tios_f; + int mode; + + g_kbdfd = open("/dev/tty", O_RDWR); + if (g_kbdfd == -1) { + perror(PFX "open /dev/tty"); + return; + } + + if (ioctl(g_kbdfd, KDGETMODE, &mode) == -1) { + perror(PFX "(not hiding FB): KDGETMODE"); + goto fail; + } + + if (tcgetattr(g_kbdfd, &kbd_termios) == -1) { + perror(PFX "tcgetattr"); + goto fail; + } + + /* dump for picorestore */ + g_kbd_termios_saved = kbd_termios; + tios_f = fopen(TERMIOS_DUMP_FILE, "wb"); + if (tios_f) { + fwrite(&kbd_termios, sizeof(kbd_termios), 1, tios_f); + fclose(tios_f); + } + + kbd_termios.c_lflag &= ~(ICANON | ECHO); // | ISIG); + kbd_termios.c_iflag &= ~(ISTRIP | IGNCR | ICRNL | INLCR | IXOFF | IXON); + kbd_termios.c_cc[VMIN] = 0; + kbd_termios.c_cc[VTIME] = 0; + + if (tcsetattr(g_kbdfd, TCSAFLUSH, &kbd_termios) == -1) { + perror(PFX "tcsetattr"); + goto fail; + } + + if (ioctl(g_kbdfd, KDSETMODE, KD_GRAPHICS) == -1) { + perror(PFX "KDSETMODE KD_GRAPHICS"); + tcsetattr(g_kbdfd, TCSAFLUSH, &g_kbd_termios_saved); + goto fail; + } + + return; + +fail: + close(g_kbdfd); + g_kbdfd = -1; +} + +static void hidecon_end(void) +{ + if (g_kbdfd < 0) + return; + + if (ioctl(g_kbdfd, KDSETMODE, KD_TEXT) == -1) + perror(PFX "KDSETMODE KD_TEXT"); + + if (tcsetattr(g_kbdfd, TCSAFLUSH, &g_kbd_termios_saved) == -1) + perror(PFX "tcsetattr"); + + remove(TERMIOS_DUMP_FILE); + + close(g_kbdfd); + g_kbdfd = -1; +} + +int oshide_init(void) { pthread_t tid; int ret; ret = pthread_create(&tid, NULL, x11h_handler, NULL); if (ret != 0) { - fprintf(stderr, "x11h: failed to create thread: %d\n", ret); + fprintf(stderr, PFX "failed to create thread: %d\n", ret); return ret; } pthread_detach(tid); + hidecon_start(); + return 0; } +void oshide_finish(void) +{ + /* XXX: the X thread.. */ + + hidecon_end(); +} + #if 0 int main() { diff --git a/linux/oshide.h b/linux/oshide.h new file mode 100644 index 0000000..f661305 --- /dev/null +++ b/linux/oshide.h @@ -0,0 +1,3 @@ +int oshide_init(void); +void oshide_finish(void); + diff --git a/linux/x11h.h b/linux/x11h.h deleted file mode 100644 index b491b48..0000000 --- a/linux/x11h.h +++ /dev/null @@ -1,2 +0,0 @@ -int x11h_init(void); - diff --git a/pandora/Makefile b/pandora/Makefile index 875c253..72cc9f2 100644 --- a/pandora/Makefile +++ b/pandora/Makefile @@ -49,7 +49,7 @@ OBJS += platform/common/emu.o platform/common/menu.o platform/common/fonts.o pla platform/common/arm_utils.o platform/common/mp3_helix.o platform/common/arm_linux.o \ platform/common/readpng.o platform/common/input.o platform/common/main.o \ platform/linux/fbdev.o platform/linux/in_evdev.o platform/linux/sndout_oss.o \ - platform/linux/plat.o platform/linux/x11h.o + platform/linux/plat.o platform/linux/oshide.o # ARM stuff OBJS += pico/carthw/svp/compiler.o pico/carthw/svp/stub_arm.o @@ -66,7 +66,7 @@ vpath %.s = ../.. vpath %.S = ../.. DIRS += platform/linux zlib unzip -all: mkdirs PicoDrive +all: mkdirs PicoDrive picorestore include ../common/common.mak include ../common/common_arm.mak diff --git a/pandora/asm_utils.h b/pandora/asm_utils.h index 881b0cd..5b273d5 100644 --- a/pandora/asm_utils.h +++ b/pandora/asm_utils.h @@ -1,2 +1,3 @@ -void clut_line(void *dest, const void *src, const unsigned short *pal, int pixels_mask); +void clut_line2x2(void *dest, const void *src, const unsigned short *pal, int pixels_mask); +void clut_line3x2(void *dest, const void *src, const unsigned short *pal, int pixels_mask); diff --git a/pandora/asm_utils.s b/pandora/asm_utils.s index a117d2d..74dd3fd 100644 --- a/pandora/asm_utils.s +++ b/pandora/asm_utils.s @@ -1,9 +1,10 @@ @ vim:filetype=armasm -.global clut_line @ void *dest, void *src, unsigned short *pal, int pixels_mask +@ FIXME: handle dual issue +.global clut_line2x2 @ void *dest, void *src, unsigned short *pal, int pixels_mask -clut_line: +clut_line2x2: stmfd sp!, {r4-r11,lr} and lr, r3, #0xff0000 @@ -12,7 +13,7 @@ clut_line: and r3, r3, #0xff @ counter add r11,r0, #800*2 -clut_line_loop: +clut_line_2x2_loop: ldmia r1!, {r10,r12} and r4, lr, r10, lsl #1 @@ -50,7 +51,58 @@ clut_line_loop: stmia r0!, {r4-r10,r12} stmia r11!,{r4-r10,r12} - bne clut_line_loop + bne clut_line_2x2_loop + + ldmfd sp!, {r4-r11,pc} + + +@ 00 01 11 22 23 33 +@ r4 r5 r6 r7 r8 r9 + +.macro do_4_to_12 rs + and r4, lr, \rs, lsl #1 + and r6, lr, \rs, lsr #7 + and r7, lr, \rs, lsr #15 + and r9, lr, \rs, lsr #23 + ldrh r4, [r2, r4] + ldrh r6, [r2, r6] + ldrh r7, [r2, r7] + ldrh r9, [r2, r9] + + orr r5, r4, r6, lsl #16 + orr r4, r4, r4, lsl #16 + orr r6, r6, r6, lsl #16 + + orr r8, r7, r9, lsl #16 + orr r7, r7, r7, lsl #16 + orr r9, r9, r9, lsl #16 +.endm + + +.global clut_line3x2 @ void *dest, void *src, unsigned short *pal, int pixels_mask + +clut_line3x2: + stmfd sp!, {r4-r11,lr} + + and lr, r3, #0xff0000 + mov lr, lr, lsr #15 @ mask + mov r3, r3, lsr #3 + and r3, r3, #0xff @ counter + add r11,r0, #800*2 + +clut_line3x2_loop: + ldmia r1!, {r10,r12} + + do_4_to_12 r10 + stmia r0!, {r4-r9} + stmia r11!,{r4-r9} + + do_4_to_12 r12 + subs r3, r3, #1 + stmia r0!, {r4-r9} + stmia r11!,{r4-r9} + + bne clut_line3x2_loop ldmfd sp!, {r4-r11,pc} diff --git a/pandora/emu.c b/pandora/emu.c index 951d85e..a9556b1 100644 --- a/pandora/emu.c +++ b/pandora/emu.c @@ -17,16 +17,31 @@ #include -//#define USE_320_SCREEN 1 - static short __attribute__((aligned(4))) sndBuffer[2*44100/50]; static unsigned char temp_frame[g_screen_width * g_screen_height * 2]; unsigned char *PicoDraw2FB = temp_frame; const char *renderer_names[] = { NULL }; const char *renderer_names32x[] = { NULL }; -char cpu_clk_name[] = "unused"; +char cpu_clk_name[] = "Max CPU clock"; + +enum { + SCALE_1x1, + SCALE_2x2_3x2, + SCALE_2x2_2x2, +}; +static int get_cpu_clock(void) +{ + FILE *f; + int ret = 0; + f = fopen("/proc/pandora/cpu_mhz_max", "r"); + if (f) { + fscanf(f, "%d", &ret); + fclose(f); + } + return ret; +} void pemu_prep_defconfig(void) { @@ -34,10 +49,12 @@ void pemu_prep_defconfig(void) g_menubg_ptr = temp_frame; defaultConfig.EmuOpt |= EOPT_VSYNC; + defaultConfig.scaling = SCALE_2x2_3x2; } void pemu_validate_config(void) { + currentConfig.CPUclock = get_cpu_clock(); } // FIXME: cleanup @@ -94,9 +111,7 @@ static void draw_cd_leds(void) } } -#ifdef USE_320_SCREEN - -static int EmuScanBegin16(unsigned int num) +static int emuscan_1x1(unsigned int num) { DrawLineDest = (unsigned short *)g_screen_ptr + num*800 + 800/2 - 320/2; //int w = (Pico.video.reg[12]&1) ? 320 : 256; @@ -105,47 +120,32 @@ static int EmuScanBegin16(unsigned int num) return 0; } -#else // USE_320_SCREEN - -static int EmuScanEnd16(unsigned int num) -{ - unsigned char *ps=HighCol+8; - unsigned short *pd; - unsigned short *pal=HighPal; - int sh = Pico.video.reg[0xC]&8; - int len, mask = 0xff; - - pd=(unsigned short *)g_screen_ptr + num*800*2 + 800/2 - 320*2/2; - - if (Pico.m.dirtyPal) - PicoDoHighPal555(sh); - - if (Pico.video.reg[12]&1) { - len = 320; - } else { - pd += 32*2; - len = 256; - } - - if (!sh && (rendstatus & PDRAW_SPR_LO_ON_HI)) - mask=0x3f; // messed sprites, upper bits are priority stuff - -#if 1 - clut_line(pd, ps, pal, (mask<<16) | len); -#else - for (; len > 0; len--) - { - unsigned int p = pal[*ps++ & mask]; - p |= p << 16; - *(unsigned int *)pd = p; - *(unsigned int *)(&pd[800]) = p; - pd += 2; - } -#endif - - return 0; +#define MAKE_EMUSCAN(name_, clut_name_, offs_, len_) \ +static int name_(unsigned int num) \ +{ \ + unsigned char *ps = HighCol+8; \ + unsigned short *pd, *pal = HighPal; \ + int sh = Pico.video.reg[0xC] & 8; \ + int mask = 0xff; \ + \ + pd = (unsigned short *)g_screen_ptr + num*800*2 + offs_;\ + \ + if (Pico.m.dirtyPal) \ + PicoDoHighPal555(sh); \ + \ + if (!sh && (rendstatus & PDRAW_SPR_LO_ON_HI)) \ + mask = 0x3f; /* upper bits are priority stuff */\ + \ + clut_line##clut_name_(pd, ps, pal, (mask<<16) | len_); \ + \ + return 0; \ } +MAKE_EMUSCAN(emuscan_2x2_40, 2x2, 800/2 - 320*2/2, 320) +MAKE_EMUSCAN(emuscan_2x2_32, 2x2, 800/2 - 256*2/2, 256) +MAKE_EMUSCAN(emuscan_3x2_32, 3x2, 800/2 - 256*3/2, 256) + +#if 0 /* FIXME */ static int EmuScanEnd16_32x(unsigned int num) { unsigned int *ps; @@ -171,7 +171,7 @@ static int EmuScanEnd16_32x(unsigned int num) return 0; } -#endif // USE_320_SCREEN +#endif void pemu_finalize_frame(const char *fps, const char *notice) { @@ -337,26 +337,47 @@ void emu_video_mode_change(int start_line, int line_count, int is_32cols) for (i = 0; i < fbdev_buffer_count; i++) memset32(fbdev_buffers[i], 0, g_screen_width * g_screen_height * 2 / 4); -#ifdef USE_320_SCREEN - PicoDrawSetOutFormat(PDF_RGB555, 1); - PicoScanBegin = EmuScanBegin16; -#else + PicoScanBegin = NULL; + PicoScanEnd = NULL; + +#if 0 if (PicoAHW & PAHW_32X) { + /* FIXME */ DrawLineDest = (unsigned short *)temp_frame; PicoDrawSetOutFormat(PDF_RGB555, 1); - PicoScanBegin = NULL; PicoScanEnd = EmuScanEnd16_32x; - } else { - PicoDrawSetOutFormat(PDF_NONE, 0); - PicoScanBegin = NULL; - PicoScanEnd = EmuScanEnd16; - } + } else #endif + { + switch (currentConfig.scaling) { + case SCALE_1x1: + PicoDrawSetOutFormat(PDF_RGB555, 1); + PicoScanBegin = emuscan_1x1; + break; + case SCALE_2x2_3x2: + PicoDrawSetOutFormat(PDF_NONE, 0); + PicoScanEnd = is_32cols ? emuscan_3x2_32 : emuscan_2x2_40; + break; + case SCALE_2x2_2x2: + PicoDrawSetOutFormat(PDF_NONE, 0); + PicoScanEnd = is_32cols ? emuscan_2x2_32 : emuscan_2x2_40; + break; + } + } } void pemu_loop_prep(void) { emu_video_mode_change(0, 0, 0); + + if (currentConfig.CPUclock != get_cpu_clock()) { + FILE *f = fopen("/proc/pandora/cpu_mhz_max", "w"); + if (f != NULL) { + fprintf(f, "%d\n", currentConfig.CPUclock); + fclose(f); + } + } + pemu_sound_start(); } @@ -388,7 +409,7 @@ void plat_wait_till_us(unsigned int us_to) now = plat_get_ticks_us(); - // XXX: need to check NOHZ and djw kernel + // XXX: need to check NOHZ diff = (signed int)(us_to - now); if (diff > 10000) { //printf("sleep %d\n", us_to - now); @@ -412,12 +433,8 @@ const char *plat_get_credits(void) " base code of PicoDrive\n" "Reesy & FluBBa: DrZ80 core\n" "MAME devs: YM2612 and SN76496 cores\n" - "rlyeh and others: minimal SDK\n" - "Squidge: mmuhack\n" - "Dzz: ARM940 sample\n" - "GnoStiC / Puck2099: USB joy code\n" - "craigix: GP2X hardware\n" - "ketchupgun: skin design\n" + "Pandora team: Pandora\n" + "Inder: menu bg\n" "\n" "special thanks (for docs, ideas):\n" " Charles MacDonald, Haze,\n" diff --git a/pandora/menu.c b/pandora/menu.c index 5b7b9f7..a9a54ab 100644 --- a/pandora/menu.c +++ b/pandora/menu.c @@ -1,5 +1,11 @@ +static const char *men_scaler[] = { "1x1, 1x1", "2x2, 3x2", "2x2, 2x2", NULL }; +static const char h_scaler[] = "Scalers for 40 and 32 column modes\n" + "(320 and 256 pixel wide horizontal)"; + #define MENU_OPTIONS_GFX \ - mee_onoff ("Vsync", MA_OPT2_VSYNC, currentConfig.EmuOpt, EOPT_VSYNC), + mee_onoff ("Vsync", MA_OPT2_VSYNC, currentConfig.EmuOpt, EOPT_VSYNC), \ + mee_enum_h ("Scaler", MA_OPT_SCALING, currentConfig.scaling, \ + men_scaler, h_scaler), #define MENU_OPTIONS_ADV \ mee_onoff ("SVP dynarec", MA_OPT2_SVP_DYNAREC, PicoOpt, POPT_EN_SVP_DRC), \ diff --git a/pandora/pandora.c b/pandora/pandora.c index 736052f..5541c2d 100644 --- a/pandora/pandora.c +++ b/pandora/pandora.c @@ -4,7 +4,7 @@ #include "../linux/sndout_oss.h" #include "../linux/fbdev.h" -#include "../linux/x11h.h" +#include "../linux/oshide.h" #include "../common/emu.h" void plat_early_init(void) @@ -15,7 +15,7 @@ void plat_init(void) { int ret, w, h; - x11h_init(); + oshide_init(); ret = vout_fbdev_init(&w, &h); if (ret != 0) { @@ -37,8 +37,9 @@ void plat_finish(void) { sndout_oss_exit(); vout_fbdev_finish(); + oshide_finish(); - printf("all done"); + printf("all done\n"); } /* lprintf */ diff --git a/pandora/picorestore.c b/pandora/picorestore.c new file mode 100644 index 0000000..6a32755 --- /dev/null +++ b/pandora/picorestore.c @@ -0,0 +1,67 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +int main() +{ + struct fb_var_screeninfo fbvar; + struct termios kbd_termios; + int ret, fbdev, kbdfd; + FILE *tios_f; + + fbdev = open("/dev/fb0", O_RDWR); + if (fbdev == -1) { + perror("open"); + return 1; + } + + ret = ioctl(fbdev, FBIOGET_VSCREENINFO, &fbvar); + if (ret == -1) { + perror("FBIOGET_VSCREENINFO ioctl"); + goto end_fb; + } + + if (fbvar.yoffset != 0) { + printf("fixing yoffset.. "); + fbvar.yoffset = 0; + ret = ioctl(fbdev, FBIOPAN_DISPLAY, &fbvar); + if (ret < 0) + perror("ioctl FBIOPAN_DISPLAY"); + else + printf("ok\n"); + } + +end_fb: + close(fbdev); + + tios_f = fopen("/tmp/pico_tios", "rb"); + if (tios_f != NULL) { + kbdfd = open("/dev/tty", O_RDWR); + if (kbdfd == -1) { + perror("open /dev/tty"); + return 1; + } + + if (fread(&kbd_termios, sizeof(kbd_termios), 1, tios_f) == 1) { + if (ioctl(kbdfd, KDSETMODE, KD_TEXT) == -1) + perror("KDSETMODE KD_TEXT"); + + printf("restoring termios.. "); + if (tcsetattr(kbdfd, TCSAFLUSH, &kbd_termios) == -1) + perror("tcsetattr"); + else + printf("ok\n"); + } + + close(kbdfd); + fclose(tios_f); + } + + return 0; +} diff --git a/win32/main.c b/win32/main.c index 85d153b..cf2523a 100644 --- a/win32/main.c +++ b/win32/main.c @@ -107,7 +107,7 @@ static HBITMAP png2hb(const char *fname, int is_480) bmem = calloc(1, is_480 ? 480*240*3 : 320*240*3); if (bmem == NULL) return NULL; - ret = readpng(bmem, fname, is_480 ? READPNG_480_24 : READPNG_320_24); + ret = readpng(bmem, fname, READPNG_24, is_480 ? 480 : 320, 240); if (ret != 0) { free(bmem); return NULL; -- 2.39.5