From 69af03a2c2fccc06cb836f42a10b490a48f29c15 Mon Sep 17 00:00:00 2001 From: notaz Date: Thu, 9 Dec 2010 19:15:01 +0200 Subject: [PATCH 1/1] add OMAP layer, also preliminary menu, hud and input support --- .gitignore | 2 + Makefile | 10 +- frontend/arm_utils.s | 5 +- frontend/main.c | 81 +++-- frontend/menu.c | 452 ++++++++++++++++++++++++++ frontend/omap.c | 203 ++++++++++++ frontend/omap.h | 6 + frontend/pcnt.h | 6 +- frontend/plugin.c | 15 +- frontend/plugin_lib.c | 88 +++-- frontend/plugin_lib.h | 22 ++ libpcsxcore/new_dynarec/new_dynarec.h | 1 + plugins/dfxvideo/draw_fb.c | 18 +- 13 files changed, 837 insertions(+), 72 deletions(-) create mode 100644 frontend/menu.c create mode 100644 frontend/omap.c create mode 100644 frontend/omap.h diff --git a/.gitignore b/.gitignore index 645bb348..694e02c3 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,6 @@ *.o frontend/linux +frontend/common +frontend/X11 tags cscope.out diff --git a/Makefile b/Makefile index d0b4bc76..3ca1616f 100644 --- a/Makefile +++ b/Makefile @@ -4,13 +4,13 @@ CC = $(CROSS_COMPILE)gcc LD = $(CROSS_COMPILE)ld CFLAGS += -ggdb -Ifrontend -LDFLAGS += -lz -lpthread -ldl +LDFLAGS += -lz -lpthread -ldl -lpng ifdef CROSS_COMPILE CFLAGS += -mcpu=cortex-a8 -mtune=cortex-a8 -mfloat-abi=softfp -ffast-math ASFLAGS += -mcpu=cortex-a8 -mfpu=neon endif ifndef DEBUG -CFLAGS += -O2 +CFLAGS += -O2 # -DNDEBUG endif #DRC_DBG = 1 #PCNT = 1 @@ -55,10 +55,14 @@ endif OBJS += gui/Config.o gui/Plugin.o OBJS += frontend/main.o frontend/plugin.o frontend/plugin_lib.o -OBJS += frontend/linux/fbdev.o +OBJS += frontend/omap.o frontend/menu.o +OBJS += frontend/linux/fbdev.o frontend/linux/in_evdev.o +OBJS += frontend/linux/plat.o frontend/linux/oshide.o +OBJS += frontend/common/fonts.o frontend/common/input.o frontend/common/readpng.o ifdef CROSS_COMPILE OBJS += frontend/arm_utils.o endif +frontend/%.o: CFLAGS += -Wall -DIN_EVDEV $(TARGET): $(OBJS) $(CC) -o $@ $^ $(LDFLAGS) -Wl,-Map=$@.map diff --git a/frontend/arm_utils.s b/frontend/arm_utils.s index d74c8b33..b0585b7b 100644 --- a/frontend/arm_utils.s +++ b/frontend/arm_utils.s @@ -1,7 +1,10 @@ /* * (C) Gražvydas "notaz" Ignotas, 2010 * - * This work is licensed under the terms of the GNU GPL, version 2 or later. + * This work is licensed under the terms of any of these licenses + * (at your option): + * - GNU GPL, version 2 or later. + * - GNU LGPL, version 2.1 or later. * See the COPYING file in the top-level directory. */ diff --git a/frontend/main.c b/frontend/main.c index 86aff348..bbcd7e41 100644 --- a/frontend/main.c +++ b/frontend/main.c @@ -17,7 +17,11 @@ #include "pcnt.h" #include "../gui/Linux.h" #include "../libpcsxcore/misc.h" +#include "common/menu.h" +#include "common/plat.h" +#include "common/input.h" +int ready_to_go; int UseGui; static char *(*real_getenv)(const char *name); @@ -185,46 +189,58 @@ int main(int argc, char *argv[]) chdir(plugin_default_dir); g_free(plugin_default_dir); */ - if (SysInit() == -1) return 1; + if (SysInit() == -1) + return 1; - // if !gui - { - // the following only occurs if the gui isn't started - if (LoadPlugins() == -1) { - SysMessage("Failed loading plugins!"); - return 1; - } - pcnt_hook_plugins(); + // frontend stuff + in_init(); + in_probe(); + plat_init(); + menu_init(); - if (OpenPlugins() == -1) { - return 1; - } + if (LoadPlugins() == -1) { + SysMessage("Failed loading plugins!"); + return 1; + } + pcnt_hook_plugins(); - SysReset(); - CheckCdrom(); + if (OpenPlugins() == -1) { + return 1; + } - if (file[0] != '\0') { - Load(file); - } else { - if (runcd) { - if (LoadCdrom() == -1) { - ClosePlugins(); - printf(_("Could not load CD-ROM!\n")); - return -1; - } + SysReset(); + CheckCdrom(); + + if (file[0] != '\0') { + if (Load(file) != -1) + ready_to_go = 1; + } else { + if (runcd) { + if (LoadCdrom() == -1) { + ClosePlugins(); + printf(_("Could not load CD-ROM!\n")); + return -1; } + ready_to_go = 1; } + } - // If a state has been specified, then load that - if (loadst) { - StatesC = loadst - 1; - char *state_filename = get_state_filename(StatesC); - int ret = LoadState(state_filename); - printf("%s state %s\n", ret ? "failed to load" : "loaded", state_filename); - free(state_filename); - } + // If a state has been specified, then load that + if (loadst) { + StatesC = loadst - 1; + char *state_filename = get_state_filename(StatesC); + int ret = LoadState(state_filename); + printf("%s state %s\n", ret ? "failed to load" : "loaded", state_filename); + free(state_filename); + } + if (!ready_to_go) + menu_loop(); + + while (1) + { psxCpu->Execute(); + menu_loop(); } return 0; @@ -378,7 +394,8 @@ char *getenv(const char *name) { static char ret[8] = "."; - if (name && strcmp(name, "HOME") == 0) + if (name && strcmp(name, "HOME") == 0 && + ((int)name >> 28) == 0) // HACK: let libs find home return ret; return real_getenv(name); diff --git a/frontend/menu.c b/frontend/menu.c new file mode 100644 index 00000000..3b38a956 --- /dev/null +++ b/frontend/menu.c @@ -0,0 +1,452 @@ +/* + * (C) Gražvydas "notaz" Ignotas, 2010 + * + * This work is licensed under the terms of any of these licenses + * (at your option): + * - GNU GPL, version 2 or later. + * - GNU LGPL, version 2.1 or later. + * See the COPYING file in the top-level directory. + */ + +#include +#include + +#include "config.h" +#include "plugin_lib.h" +#include "omap.h" +#include "common/plat.h" +#include "../libpcsxcore/misc.h" + +#define MENU_X2 1 +#define array_size(x) (sizeof(x) / sizeof(x[0])) + +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_CONTROLS, + MA_MAIN_CREDITS, + MA_MAIN_EXIT, + MA_CTRL_PLAYER1, + MA_CTRL_PLAYER2, + MA_CTRL_EMU, + MA_CTRL_DEV_FIRST, + MA_CTRL_DEV_NEXT, + MA_CTRL_DONE, + MA_OPT_SAVECFG, + MA_OPT_SAVECFG_GAME, + MA_OPT_CPU_CLOCKS, +} menu_id; + +extern int ready_to_go; + +static int dummy, state_slot; +static char rom_fname_reload[MAXPATHLEN]; +static char last_selected_fname[MAXPATHLEN]; + +void emu_make_path(char *buff, const char *end, int size) +{ + int pos, end_len; + + end_len = strlen(end); + pos = plat_get_root_dir(buff, size); + strncpy(buff + pos, end, size - pos); + buff[size - 1] = 0; + if (pos + end_len > size - 1) + printf("Warning: path truncated: %s\n", buff); +} + +static int emu_check_save_file(int slot) +{ + return 0; +} + +static int emu_save_load_game(int load, int sram) +{ + return 0; +} + +static int emu_write_config(int is_game) +{ + return 0; +} + +static void emu_set_defconfig(void) +{ +} + +#include "common/menu.c" + +static void draw_savestate_bg(int slot) +{ +} + +// -------------- key config -------------- + +me_bind_action me_ctrl_actions[] = +{ + { "UP ", 1 << DKEY_UP}, + { "DOWN ", 1 << DKEY_DOWN }, + { "LEFT ", 1 << DKEY_LEFT }, + { "RIGHT ", 1 << DKEY_RIGHT }, + { "TRIANGLE", 1 << DKEY_TRIANGLE }, + { "CIRCLE ", 1 << DKEY_SQUARE }, + { "CROSS ", 1 << DKEY_CROSS }, + { "SQUARE ", 1 << DKEY_SQUARE }, + { "L1 ", 1 << DKEY_L1 }, + { "R1 ", 1 << DKEY_R1 }, + { "L2 ", 1 << DKEY_L2 }, + { "R2 ", 1 << DKEY_R2 }, + { "START ", 1 << DKEY_START }, + { "SELECT ", 1 << DKEY_SELECT }, + { NULL, 0 } +}; + +me_bind_action emuctrl_actions[] = +{ + { "Load State ", PEV_STATE_LOAD }, + { "Save State ", PEV_STATE_SAVE }, + { "Prev Save Slot ", PEV_SSLOT_PREV }, + { "Next Save Slot ", PEV_SSLOT_NEXT }, + { "Enter Menu ", PEV_MENU }, + { NULL, 0 } +}; + +static int key_config_loop_wrap(int id, int keys) +{ + switch (id) { + case MA_CTRL_PLAYER1: + key_config_loop(me_ctrl_actions, array_size(me_ctrl_actions) - 1, 0); + break; + case MA_CTRL_PLAYER2: + key_config_loop(me_ctrl_actions, array_size(me_ctrl_actions) - 1, 1); + break; + case MA_CTRL_EMU: + key_config_loop(emuctrl_actions, array_size(emuctrl_actions) - 1, -1); + break; + default: + break; + } + return 0; +} + +static const char *mgn_dev_name(int id, int *offs) +{ + const char *name = NULL; + static int it = 0; + + if (id == MA_CTRL_DEV_FIRST) + it = 0; + + for (; it < IN_MAX_DEVS; it++) { + name = in_get_dev_name(it, 1, 1); + if (name != NULL) + break; + } + + it++; + return name; +} + +static const char *mgn_saveloadcfg(int id, int *offs) +{ + return ""; +} + +static int mh_saveloadcfg(int id, int keys) +{ + switch (id) { + case MA_OPT_SAVECFG: + case MA_OPT_SAVECFG_GAME: + if (emu_write_config(id == MA_OPT_SAVECFG_GAME ? 1 : 0)) + me_update_msg("config saved"); + else + me_update_msg("failed to write config"); + break; + default: + return 0; + } + + return 1; +} + +static menu_entry e_menu_keyconfig[] = +{ + mee_handler_id("Player 1", MA_CTRL_PLAYER1, key_config_loop_wrap), + mee_handler_id("Player 2", MA_CTRL_PLAYER2, key_config_loop_wrap), + mee_handler_id("Emulator controls", MA_CTRL_EMU, key_config_loop_wrap), + mee_cust_nosave("Save global config", MA_OPT_SAVECFG, mh_saveloadcfg, mgn_saveloadcfg), + mee_cust_nosave("Save cfg for loaded game", MA_OPT_SAVECFG_GAME, mh_saveloadcfg, mgn_saveloadcfg), + mee_label (""), + mee_label ("Input devices:"), + mee_label_mk (MA_CTRL_DEV_FIRST, mgn_dev_name), + mee_label_mk (MA_CTRL_DEV_NEXT, mgn_dev_name), + mee_label_mk (MA_CTRL_DEV_NEXT, mgn_dev_name), + mee_label_mk (MA_CTRL_DEV_NEXT, mgn_dev_name), + mee_label_mk (MA_CTRL_DEV_NEXT, mgn_dev_name), + mee_label_mk (MA_CTRL_DEV_NEXT, mgn_dev_name), + mee_label_mk (MA_CTRL_DEV_NEXT, mgn_dev_name), + mee_end, +}; + +static int menu_loop_keyconfig(int id, int keys) +{ + static int sel = 0; + + me_enable(e_menu_keyconfig, MA_OPT_SAVECFG_GAME, ready_to_go); + me_loop(e_menu_keyconfig, &sel, NULL); + return 0; +} + +// ------------ adv options menu ------------ + +static menu_entry e_menu_adv_options[] = +{ + mee_onoff ("captain placeholder", 0, dummy, 1), + mee_end, +}; + +static int menu_loop_adv_options(int id, int keys) +{ + static int sel = 0; + me_loop(e_menu_adv_options, &sel, NULL); + return 0; +} + +// ------------ gfx options menu ------------ + +static menu_entry e_menu_gfx_options[] = +{ + mee_end, +}; + +static int menu_loop_gfx_options(int id, int keys) +{ + static int sel = 0; + + me_loop(e_menu_gfx_options, &sel, NULL); + + return 0; +} + +// ------------ options menu ------------ + +static menu_entry e_menu_options[]; + +static int mh_restore_defaults(int id, int keys) +{ + emu_set_defconfig(); + me_update_msg("defaults restored"); + return 1; +} + +static const char *men_confirm_save[] = { "OFF", "writes", "loads", "both", NULL }; +static const char h_confirm_save[] = "Ask for confirmation when overwriting save,\n" + "loading state or both"; + +static menu_entry e_menu_options[] = +{ + mee_range ("Save slot", 0, state_slot, 0, 9), + mee_enum_h ("Confirm savestate", 0, dummy, men_confirm_save, h_confirm_save), + mee_range ("", MA_OPT_CPU_CLOCKS, dummy, 20, 5000), + mee_handler ("[Display]", menu_loop_gfx_options), + mee_handler ("[Advanced]", menu_loop_adv_options), + mee_cust_nosave("Save global config", MA_OPT_SAVECFG, mh_saveloadcfg, mgn_saveloadcfg), + mee_cust_nosave("Save cfg for loaded game",MA_OPT_SAVECFG_GAME, mh_saveloadcfg, mgn_saveloadcfg), + mee_handler ("Restore defaults", mh_restore_defaults), + mee_end, +}; + +static int menu_loop_options(int id, int keys) +{ + static int sel = 0; + int i; + + i = me_id2offset(e_menu_options, MA_OPT_CPU_CLOCKS); + e_menu_options[i].enabled = e_menu_options[i].name[0] ? 1 : 0; + me_enable(e_menu_options, MA_OPT_SAVECFG_GAME, ready_to_go); + + me_loop(e_menu_options, &sel, NULL); + + return 0; +} + +// ------------ debug menu ------------ + +#ifdef __GNUC__ +#define COMPILER "gcc " __VERSION__ +#else +#define COMPILER +#endif + +static void draw_frame_debug(void) +{ + smalltext_out16(4, 1, "build: "__DATE__ " " __TIME__ " " COMPILER, 0xffff); +} + +static void debug_menu_loop(void) +{ + int inp; + + while (1) + { + menu_draw_begin(1); + draw_frame_debug(); + menu_draw_end(); + + inp = in_menu_wait(PBTN_MOK|PBTN_MBACK|PBTN_MA2|PBTN_MA3|PBTN_L|PBTN_R | + PBTN_UP|PBTN_DOWN|PBTN_LEFT|PBTN_RIGHT, 70); + if (inp & PBTN_MBACK) + return; + } +} + +// ------------ main menu ------------ + +const char *plat_get_credits(void) +{ + return "(C) 1999-2003 PCSX Team\n" + "(C) 2005-2009 PCSX-df Team\n" + "(C) 2009-2010 PCSX-Reloaded Team\n\n" + "GPU and SPU code by Pete Bernert\n" + " and the P.E.Op.S. team\n" + "ARM recompiler by Ari64\n\n" + "integration, optimization and\n" + " frontend by (C) notaz, 2010\n"; +} + +static char *romsel_run(void) +{ + char *ret; + + ret = menu_loop_romsel(last_selected_fname, sizeof(last_selected_fname)); + if (ret == NULL) + return NULL; + + lprintf("selected file: %s\n", ret); + ready_to_go = 0; + + SetIsoFile(ret); + LoadPlugins(); + NetOpened = 0; + if (OpenPlugins() == -1) { + me_update_msg("failed to open plugins"); + return NULL; + } + + SysReset(); + + if (CheckCdrom() == -1) { + // Only check the CD if we are starting the console with a CD + ClosePlugins(); + me_update_msg("unsupported/invalid CD image"); + return NULL; + } + + // Read main executable directly from CDRom and start it + if (LoadCdrom() == -1) { + ClosePlugins(); + me_update_msg("failed to load CD image"); + return NULL; + } + + ready_to_go = 1; + return ret; +} + +static int main_menu_handler(int id, int keys) +{ + char *ret_name; + + switch (id) + { + case MA_MAIN_RESUME_GAME: + break; + case MA_MAIN_SAVE_STATE: + if (ready_to_go) + return menu_loop_savestate(0); + break; + case MA_MAIN_LOAD_STATE: + if (ready_to_go) + return menu_loop_savestate(1); + break; + case MA_MAIN_RESET_GAME: + break; + case MA_MAIN_LOAD_ROM: + ret_name = romsel_run(); + if (ret_name != NULL) + return 1; + break; + case MA_MAIN_CREDITS: + draw_menu_credits(); + in_menu_wait(PBTN_MOK|PBTN_MBACK, 70); + break; + case MA_MAIN_EXIT: + exit(1); // FIXME + default: + lprintf("%s: something unknown selected\n", __FUNCTION__); + break; + } + + return 0; +} + +static menu_entry e_menu_main[] = +{ + mee_label (""), + mee_label (""), + mee_handler_id("Resume game", MA_MAIN_RESUME_GAME, main_menu_handler), + mee_handler_id("Save State", MA_MAIN_SAVE_STATE, main_menu_handler), + mee_handler_id("Load State", MA_MAIN_LOAD_STATE, main_menu_handler), + mee_handler_id("Reset game", MA_MAIN_RESET_GAME, main_menu_handler), + mee_handler_id("Load CD image", MA_MAIN_LOAD_ROM, main_menu_handler), + mee_handler ("Options", menu_loop_options), + mee_handler ("Controls", menu_loop_keyconfig), + mee_handler_id("Credits", MA_MAIN_CREDITS, main_menu_handler), + mee_handler_id("Exit", MA_MAIN_EXIT, main_menu_handler), + mee_end, +}; + +void menu_loop(void) +{ + static int sel = 0; + + omap_enable_layer(0); + + me_enable(e_menu_main, MA_MAIN_RESUME_GAME, ready_to_go); + me_enable(e_menu_main, MA_MAIN_SAVE_STATE, ready_to_go); + me_enable(e_menu_main, MA_MAIN_LOAD_STATE, ready_to_go); + me_enable(e_menu_main, MA_MAIN_RESET_GAME, ready_to_go); + +strcpy(last_selected_fname, "/mnt/ntz/stuff/psx"); + menu_enter(ready_to_go); + in_set_config_int(0, IN_CFG_BLOCKING, 1); + + do { + me_loop(e_menu_main, &sel, NULL); + } while (!ready_to_go); + + /* wait until menu, ok, back is released */ + while (in_menu_wait_any(50) & (PBTN_MENU|PBTN_MOK|PBTN_MBACK)) + ; + + in_set_config_int(0, IN_CFG_BLOCKING, 0); + + memset(g_menuscreen_ptr, 0, g_menuscreen_w * g_menuscreen_h * 2); + menu_draw_end(); + omap_enable_layer(1); +} + +void me_update_msg(const char *msg) +{ + strncpy(menu_error_msg, msg, sizeof(menu_error_msg)); + menu_error_msg[sizeof(menu_error_msg) - 1] = 0; + + menu_error_time = plat_get_ticks_ms(); + lprintf("msg: %s\n", menu_error_msg); +} + diff --git a/frontend/omap.c b/frontend/omap.c new file mode 100644 index 00000000..e5f9ebda --- /dev/null +++ b/frontend/omap.c @@ -0,0 +1,203 @@ +/* + * (C) notaz, 2010 + * + * This work is licensed under the terms of the GNU GPLv2 or later. + * See the COPYING file in the top-level directory. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "common/input.h" +#include "common/menu.h" +#include "linux/fbdev.h" +#include "linux/oshide.h" +#include "plugin_lib.h" +#include "omap.h" + + +static struct vout_fbdev *main_fb; +int g_layer_x = 80, g_layer_y = 0; +int g_layer_w = 640, g_layer_h = 480; + +struct vout_fbdev *layer_fb; + +static const char * const pandora_gpio_keys[KEY_MAX + 1] = { + [0 ... KEY_MAX] = NULL, + [KEY_UP] = "Up", + [KEY_LEFT] = "Left", + [KEY_RIGHT] = "Right", + [KEY_DOWN] = "Down", + [KEY_HOME] = "A", + [KEY_PAGEDOWN] = "X", + [KEY_END] = "B", + [KEY_PAGEUP] = "Y", + [KEY_RIGHTSHIFT]= "L", + [KEY_RIGHTCTRL] = "R", + [KEY_LEFTALT] = "Start", + [KEY_LEFTCTRL] = "Select", + [KEY_MENU] = "Pandora", +}; + +struct in_default_bind in_evdev_defbinds[] = { + { KEY_UP, IN_BINDTYPE_PLAYER12, DKEY_UP }, + { KEY_DOWN, IN_BINDTYPE_PLAYER12, DKEY_DOWN }, + { KEY_LEFT, IN_BINDTYPE_PLAYER12, DKEY_LEFT }, + { KEY_RIGHT, IN_BINDTYPE_PLAYER12, DKEY_RIGHT }, + { KEY_SPACE, IN_BINDTYPE_EMU, PEVB_MENU }, + { KEY_PAGEUP, IN_BINDTYPE_PLAYER12, DKEY_TRIANGLE }, + { KEY_PAGEDOWN, IN_BINDTYPE_PLAYER12, DKEY_CROSS }, + { KEY_END, IN_BINDTYPE_PLAYER12, DKEY_CIRCLE }, + { KEY_HOME, IN_BINDTYPE_PLAYER12, DKEY_SQUARE }, + { KEY_LEFTALT, IN_BINDTYPE_PLAYER12, DKEY_START }, + { KEY_LEFTCTRL, IN_BINDTYPE_PLAYER12, DKEY_SELECT }, + { KEY_RIGHTSHIFT,IN_BINDTYPE_PLAYER12, DKEY_L1 }, + { KEY_RIGHTCTRL, IN_BINDTYPE_PLAYER12, DKEY_R1 }, + { KEY_Q, IN_BINDTYPE_PLAYER12, DKEY_L2 }, + { KEY_P, IN_BINDTYPE_PLAYER12, DKEY_R2 }, + { 0, 0, 0 } +}; + +static int omap_setup_layer_(int fd, int enabled, int x, int y, int w, int h) +{ + struct omapfb_plane_info pi; + struct omapfb_mem_info mi; + int ret; + + ret = ioctl(fd, OMAPFB_QUERY_PLANE, &pi); + if (ret != 0) { + perror("QUERY_PLANE"); + return -1; + } + + ret = ioctl(fd, OMAPFB_QUERY_MEM, &mi); + if (ret != 0) { + perror("QUERY_MEM"); + return -1; + } + + /* must disable when changing stuff */ + if (pi.enabled) { + pi.enabled = 0; + ret = ioctl(fd, OMAPFB_SETUP_PLANE, &pi); + if (ret != 0) + perror("SETUP_PLANE"); + } + + mi.size = 640*512*2*3; + ret = ioctl(fd, OMAPFB_SETUP_MEM, &mi); + if (ret != 0) { + perror("SETUP_MEM"); + return -1; + } + + pi.pos_x = x; + pi.pos_y = y; + pi.out_width = w; + pi.out_height = h; + pi.enabled = enabled; + + ret = ioctl(fd, OMAPFB_SETUP_PLANE, &pi); + if (ret != 0) { + perror("SETUP_PLANE"); + return -1; + } + + return 0; +} + +int omap_enable_layer(int enabled) +{ + return omap_setup_layer_(vout_fbdev_get_fd(layer_fb), enabled, + g_layer_x, g_layer_y, g_layer_w, g_layer_h); +} + +void plat_video_menu_enter(int is_rom_loaded) +{ +} + +void plat_video_menu_begin(void) +{ +} + +void plat_video_menu_end(void) +{ + g_menuscreen_ptr = vout_fbdev_flip(main_fb); +} + +void plat_init(void) +{ + const char *main_fb_name, *layer_fb_name; + void *temp_frame; + int fd, ret, w, h; + + main_fb_name = getenv("FBDEV_MAIN"); + if (main_fb_name == NULL) + main_fb_name = "/dev/fb0"; + + layer_fb_name = getenv("FBDEV_LAYER"); + if (layer_fb_name == NULL) + layer_fb_name = "/dev/fb1"; + + // must set the layer up first to be able to use it + fd = open(layer_fb_name, O_RDWR); + if (fd == -1) { + fprintf(stderr, "%s: ", layer_fb_name); + perror("open"); + exit(1); + } + + ret = omap_setup_layer_(fd, 1, g_layer_x, g_layer_y, g_layer_w, g_layer_h); + close(fd); + if (ret != 0) { + fprintf(stderr, "failed to set up layer, exiting.\n"); + exit(1); + } + + oshide_init(); + + w = h = 0; + main_fb = vout_fbdev_init(main_fb_name, &w, &h, 16, 2); + if (main_fb == NULL) { + fprintf(stderr, "couldn't init fb: %s\n", main_fb_name); + exit(1); + } + + g_menuscreen_w = w; + g_menuscreen_h = h; + g_menuscreen_ptr = vout_fbdev_flip(main_fb); + + w = 640; + h = 512; // ?? + layer_fb = vout_fbdev_init(layer_fb_name, &w, &h, 16, 3); + if (layer_fb == NULL) { + fprintf(stderr, "couldn't init fb: %s\n", layer_fb_name); + goto fail0; + } + + temp_frame = calloc(g_menuscreen_w * g_menuscreen_h * 2, 1); + if (temp_frame == NULL) { + fprintf(stderr, "OOM\n"); + goto fail1; + } + g_menubg_ptr = temp_frame; + g_menubg_src_ptr = temp_frame; + + in_set_config(in_name_to_id("evdev:gpio-keys"), IN_CFG_KEY_NAMES, + pandora_gpio_keys, sizeof(pandora_gpio_keys)); + return; + +fail1: + vout_fbdev_finish(layer_fb); +fail0: + vout_fbdev_finish(main_fb); + exit(1); + +} + diff --git a/frontend/omap.h b/frontend/omap.h new file mode 100644 index 00000000..5cd78eda --- /dev/null +++ b/frontend/omap.h @@ -0,0 +1,6 @@ + +extern struct vout_fbdev *layer_fb; +extern int g_layer_x, g_layer_y; +extern int g_layer_w, g_layer_h; + +int omap_enable_layer(int enabled); diff --git a/frontend/pcnt.h b/frontend/pcnt.h index d3eedfa5..3cf2925e 100644 --- a/frontend/pcnt.h +++ b/frontend/pcnt.h @@ -57,10 +57,6 @@ static inline unsigned int pcnt_get(void) #define pcnt_start(id) #define pcnt_end(id) #define pcnt_hook_plugins() - -static inline void pcnt_print(float fps) -{ - printf("%2.1f\n", fps); -} +#define pcnt_print(fps) #endif diff --git a/frontend/plugin.c b/frontend/plugin.c index bcf3885a..c83da729 100644 --- a/frontend/plugin.c +++ b/frontend/plugin.c @@ -9,6 +9,7 @@ #include #include +#include "plugin_lib.h" #include "plugin.h" static int dummy_func() { @@ -42,18 +43,22 @@ extern void SPUasync(unsigned int); extern void SPUplayCDDAchannel(short *, int); /* PAD */ -static uint8_t CurByte; +static uint8_t pad_buf[] = { 0x41, 0x5A, 0xFF, 0xFF }; +static uint8_t pad_byte; static unsigned char PADstartPoll(int pad) { - CurByte = 0; + pad_byte = 0; + pad_buf[2] = keystate; + pad_buf[3] = keystate >> 8; + return 0xFF; } static unsigned char PADpoll(unsigned char value) { - static uint8_t buf[] = {0x41, 0x5A, 0xFF, 0xFF, 0x80, 0x80, 0x80, 0x80}; - if (CurByte >= 4) + if (pad_byte >= 4) return 0; - return buf[CurByte++]; + + return pad_buf[pad_byte++]; } /* GPU */ diff --git a/frontend/plugin_lib.c b/frontend/plugin_lib.c index 92c2b538..7d5e15fd 100644 --- a/frontend/plugin_lib.c +++ b/frontend/plugin_lib.c @@ -7,48 +7,90 @@ #include #include +#include +#include #include "linux/fbdev.h" +#include "common/fonts.h" +#include "common/input.h" +#include "omap.h" +#include "../libpcsxcore/new_dynarec/new_dynarec.h" -static struct vout_fbdev *fbdev; void *pl_fbdev_buf; +int keystate; +static int pl_fbdev_w; int pl_fbdev_init(void) { - const char *fbdev_name; - int w, h; + pl_fbdev_buf = vout_fbdev_flip(layer_fb); + return 0; +} - fbdev_name = getenv("FBDEV"); - if (fbdev_name == NULL) - fbdev_name = "/dev/fb0"; +int pl_fbdev_set_mode(int w, int h, int bpp) +{ + int ret; - w = 640; - h = 512; // ?? - fbdev = vout_fbdev_init(fbdev_name, &w, &h, 16, 3); - if (fbdev == NULL) - return -1; + pl_fbdev_w = w; + printf("set mode %dx%d@%d\n", w, h, bpp); + ret = vout_fbdev_resize(layer_fb, w, h, bpp, 0, 0, 0, 0, 3); + if (ret) + fprintf(stderr, "failed to set mode\n"); + return ret; +} + +void *pl_fbdev_flip(void) +{ + /* doing input here because the pad is polled + * thousands of times for some reason */ + int actions[IN_BINDTYPE_COUNT] = { 0, }; - pl_fbdev_buf = vout_fbdev_flip(fbdev); + in_update(actions); + if (actions[IN_BINDTYPE_EMU] & PEV_MENU) + stop = 1; + keystate = ~actions[IN_BINDTYPE_PLAYER12]; - return 0; + // let's flip now + pl_fbdev_buf = vout_fbdev_flip(layer_fb); + return pl_fbdev_buf; } -int pl_fbdev_set_mode(int w, int h, int bpp) +void pl_fbdev_finish(void) { - printf("set mode %dx%d@%d\n", w, h, bpp); - return vout_fbdev_resize(fbdev, w, h, bpp, 0, 0, 0, 0, 3); } -void *pl_fbdev_flip(void) +static void pl_text_out16_(int x, int y, const char *text) { - pl_fbdev_buf = vout_fbdev_flip(fbdev); - return pl_fbdev_buf; + int i, l, len = strlen(text), w = pl_fbdev_w; + unsigned short *screen = (unsigned short *)pl_fbdev_buf + x + y * w; + unsigned short val = 0xffff; + + for (i = 0; i < len; i++, screen += 8) + { + for (l = 0; l < 8; l++) + { + unsigned char fd = fontdata8x8[text[i] * 8 + l]; + unsigned short *s = screen + l * w; + if (fd&0x80) s[0] = val; + if (fd&0x40) s[1] = val; + if (fd&0x20) s[2] = val; + if (fd&0x10) s[3] = val; + if (fd&0x08) s[4] = val; + if (fd&0x04) s[5] = val; + if (fd&0x02) s[6] = val; + if (fd&0x01) s[7] = val; + } + } } -void pl_fbdev_finish(void) +void pl_text_out16(int x, int y, const char *texto, ...) { - if (fbdev != NULL) - vout_fbdev_finish(fbdev); - fbdev = NULL; + va_list args; + char buffer[256]; + + va_start(args, texto); + vsnprintf(buffer, sizeof(buffer), texto, args); + va_end(args); + + pl_text_out16_(x, y, buffer); } diff --git a/frontend/plugin_lib.h b/frontend/plugin_lib.h index 03afc861..02a6240b 100644 --- a/frontend/plugin_lib.h +++ b/frontend/plugin_lib.h @@ -1,7 +1,29 @@ +extern int keystate; +enum { + DKEY_SELECT = 0, + DKEY_L3, + DKEY_R3, + DKEY_START, + DKEY_UP, + DKEY_RIGHT, + DKEY_DOWN, + DKEY_LEFT, + DKEY_L2, + DKEY_R2, + DKEY_L1, + DKEY_R1, + DKEY_TRIANGLE, + DKEY_CIRCLE, + DKEY_CROSS, + DKEY_SQUARE, +}; + extern void *pl_fbdev_buf; int pl_fbdev_init(void); int pl_fbdev_set_mode(int w, int h, int bpp); void *pl_fbdev_flip(void); void pl_fbdev_finish(void); + +void pl_text_out16(int x, int y, const char *texto, ...); diff --git a/libpcsxcore/new_dynarec/new_dynarec.h b/libpcsxcore/new_dynarec/new_dynarec.h index 515de8bb..6f0c74e9 100644 --- a/libpcsxcore/new_dynarec/new_dynarec.h +++ b/libpcsxcore/new_dynarec/new_dynarec.h @@ -2,6 +2,7 @@ extern int pcaddr; extern int pending_exception; +extern int stop; void new_dynarec_init(); void new_dynarec_cleanup(); diff --git a/plugins/dfxvideo/draw_fb.c b/plugins/dfxvideo/draw_fb.c index b48b4870..f3d0cf2e 100644 --- a/plugins/dfxvideo/draw_fb.c +++ b/plugins/dfxvideo/draw_fb.c @@ -36,6 +36,9 @@ PSXPoint_t ptCursorPoint[8]; unsigned short usCursorActive = 0; char * pCaptionText; +static int fbw, fbh, fb24bpp; +static int flip_cnt, flips_per_sec; + #ifndef __arm__ #define bgr555_to_rgb565 memcpy #define bgr888_to_rgb888 memcpy @@ -78,11 +81,10 @@ static void blit(void) { bgr555_to_rgb565(dest, srcs, w * 2); } + pl_text_out16(2, fbh - 10, "%2d %2.1f", flips_per_sec, fps_cur); } } -static int fbw, fbh, fb24bpp; - #include "pcnt.h" void DoBufferSwap(void) @@ -104,8 +106,18 @@ void DoBufferSwap(void) pcnt_end(PCNT_ALL); + { + static int oldsec; + struct timeval tv; + flip_cnt++; + gettimeofday(&tv, 0); + if (tv.tv_sec != oldsec) { + flips_per_sec = flip_cnt; + flip_cnt = 0; + oldsec = tv.tv_sec; + } + } if (++fps_counter == 60/6) { - //printf("%2.1f\n", fps_cur); pcnt_print(fps_cur); fps_counter = 0; } -- 2.39.2