#DRC_DBG = 1
#PCNT = 1
-all: config.mak $(TARGET) plugins_
+all: config.mak target_ plugins_
ifneq ($(wildcard config.mak),)
config.mak: ./configure
# gui
OBJS += frontend/main.o frontend/plugin.o
-OBJS += frontend/plugin_lib.o frontend/common/readpng.o
-OBJS += frontend/common/fonts.o frontend/linux/plat.o
-ifeq "$(PLATFORM)" "maemo"
-OBJS += maemo/hildon.o maemo/main.o
-maemo/%.o: maemo/%.c
-else
-OBJS += frontend/menu.o frontend/linux/in_evdev.o
-OBJS += frontend/common/input.o
+OBJS += frontend/common/readpng.o frontend/common/fonts.o
+OBJS += frontend/linux/plat.o
ifeq "$(PLATFORM)" "generic"
OBJS += frontend/plat_sdl.o frontend/common/in_sdl.o
+USE_FRONTEND = 1
endif
ifeq "$(PLATFORM)" "pandora"
OBJS += frontend/linux/fbdev.o
OBJS += frontend/plat_omap.o frontend/linux/xenv.o
OBJS += frontend/plat_pandora.o
+USE_FRONTEND = 1
endif
ifeq "$(PLATFORM)" "caanoo"
OBJS += frontend/plat_pollux.o frontend/in_tsbutton.o frontend/blit320.o
OBJS += frontend/gp2x/in_gp2x.o frontend/warm/warm.o
+USE_FRONTEND = 1
+endif
+ifeq "$(PLATFORM)" "maemo"
+OBJS += maemo/hildon.o maemo/main.o
+maemo/%.o: maemo/%.c
+OBJS += frontend/plugin_lib.o
+endif
+ifeq "$(PLATFORM)" "libretro"
+OBJS += frontend/libretro.o
+endif
+ifeq "$(USE_FRONTEND)" "1"
+OBJS += frontend/menu.o frontend/linux/in_evdev.o
+OBJS += frontend/common/input.o
+OBJS += frontend/plugin_lib.o
+ifeq "$(HAVE_TSLIB)" "1"
+frontend/%.o: CFLAGS += -DHAVE_TSLIB
+OBJS += frontend/pl_gun_ts.o
+endif
+else
+CFLAGS += -DNO_FRONTEND
endif
-endif # !maemo
ifdef X11
frontend/%.o: CFLAGS += -DX11
ifdef PCNT
CFLAGS += -DPCNT
endif
-ifeq "$(HAVE_TSLIB)" "1"
-frontend/%.o: CFLAGS += -DHAVE_TSLIB
-OBJS += frontend/pl_gun_ts.o
-endif
frontend/%.o: CFLAGS += -DIN_EVDEV
-frontend/menu.o frontend/plat_sdl.o: frontend/revision.h
+frontend/menu.o frontend/main.o frontend/plat_sdl.o: frontend/revision.h
libpcsxcore/gte_nf.o: libpcsxcore/gte.c
$(CC) -c -o $@ $^ $(CFLAGS) -DFLAGLESS
%.o: %.S
$(CC) $(CFLAGS) -c $^ -o $@
+target_: $(TARGET)
+
$(TARGET): $(OBJS)
$(CC) -o $@ $^ $(LDFLAGS) $(LDLIBS) -Wl,-Map=$@.map
# setting options to "yes" or "no" will make that choice default,
# "" means "autodetect".
-platform_list="generic pandora maemo caanoo"
+platform_list="generic pandora maemo caanoo libretro"
platform="generic"
-sound_driver_list="oss alsa none"
+sound_driver_list="oss alsa libretro none"
sound_driver="alsa"
plugins="plugins/spunull/spunull.so \
plugins/dfxvideo/gpu_peops.so plugins/gpu_unai/gpu_unai.so"
drc_cache_base="yes"
optimize_arm926ej="yes"
;;
+ libretro)
+ sound_driver="libretro"
+ ;;
*)
echo "unsupported platform: $platform"
exit 1
fi
case "$sound_driver" in
-oss|alsa|none)
+oss|alsa|libretro|none)
;;
*)
echo "unsupported sound driver: $sound_driver"
CFLAGS="$CFLAGS -DRAM_FIXED"
fi
-if [ "$platform" = "generic" ]; then
+case "$platform" in
+generic)
generic_cflags=`sdl-config --cflags`
generic_ldlibs=`sdl-config --libs`
CFLAGS="$CFLAGS $generic_cflags"
LDFLAGS="$LDFLAGS $generic_ldlibs"
-elif [ "$platform" = "maemo" ]; then
+ ;;
+maemo)
maemo_cflags=`pkg-config --cflags hildon-1`
maemo_ldlibs=`pkg-config --libs hildon-1`
CFLAGS="$CFLAGS -DMAEMO -DMAEMO_CHANGES $maemo_cflags"
LDFLAGS="$LDFLAGS $maemo_ldlibs"
-fi
+ ;;
+libretro)
+ CFLAGS="$CFLAGS -fPIC"
+ LDFLAGS="$LDFLAGS -shared"
+ ;;
+esac
# check for tslib (only headers needed)
if [ "x$have_tslib" = "x" ]; then
echo "PLUGIN_CFLAGS += $PLUGIN_CFLAGS" >> $config_mak
echo >> $config_mak
+if [ "$platform" = "libretro" ]; then
+ echo "TARGET = libretro.so" >> $config_mak
+fi
echo "ARCH = $ARCH" >> $config_mak
echo "PLATFORM = $platform" >> $config_mak
case "$sound_driver" in
--- /dev/null
+/*
+ * (C) notaz, 2012
+ *
+ * This work is licensed under the terms of the GNU GPLv2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "../libpcsxcore/misc.h"
+#include "../libpcsxcore/psxcounters.h"
+#include "../libpcsxcore/new_dynarec/new_dynarec.h"
+#include "main.h"
+#include "plugin.h"
+#include "plugin_lib.h"
+#include "revision.h"
+#include "libretro.h"
+
+static retro_video_refresh_t video_cb;
+static retro_input_poll_t input_poll_cb;
+static retro_input_state_t input_state_cb;
+static retro_environment_t environ_cb;
+static retro_audio_sample_batch_t audio_batch_cb;
+
+static void *vout_buf;
+static int vout_width, vout_height;
+static int samples_sent, samples_to_send;
+static int plugins_opened;
+
+/* PCSX ReARMed core calls and stuff */
+int in_type1, in_type2;
+int in_a1[2] = { 127, 127 }, in_a2[2] = { 127, 127 };
+int in_keystate;
+int in_enable_vibration;
+
+static int vout_open(void)
+{
+ return 0;
+}
+
+static void *vout_set_mode(int w, int h, int bpp)
+{
+ vout_width = w;
+ vout_height = h;
+ return vout_buf;
+}
+
+/* FIXME: either teach PCSX to blit to RGB1555 or RetroArch to support RGB565 */
+static void convert(void *buf, size_t size)
+{
+ unsigned int i, v, *p = buf;
+
+ for (i = 0; i < size / 2; i++) {
+ v = p[i];
+ p[i] = (v & 0x001f001f) | ((v >> 1) & 0x7fe07fe0);
+ }
+}
+
+static void *vout_flip(void)
+{
+ pl_rearmed_cbs.flip_cnt++;
+ convert(vout_buf, vout_width * vout_height * 2);
+ video_cb(vout_buf, vout_width, vout_height, vout_width * 2);
+
+ return vout_buf;
+}
+
+static void vout_close(void)
+{
+}
+
+struct rearmed_cbs pl_rearmed_cbs = {
+ .pl_vout_open = vout_open,
+ .pl_vout_set_mode = vout_set_mode,
+ .pl_vout_flip = vout_flip,
+ .pl_vout_close = vout_close,
+ /* from psxcounters */
+ .gpu_hcnt = &hSyncCount,
+ .gpu_frame_count = &frame_counter,
+};
+
+void pl_frame_limit(void)
+{
+ /* called once per frame, make psxCpu->Execute() above return */
+ stop = 1;
+}
+
+void pl_timing_prepare(int is_pal)
+{
+}
+
+void plat_trigger_vibrate(int is_strong)
+{
+}
+
+void pl_update_gun(int *xn, int *xres, int *y, int *in)
+{
+}
+
+/* sound calls */
+void SetupSound(void)
+{
+}
+
+void RemoveSound(void)
+{
+}
+
+unsigned long SoundGetBytesBuffered(void)
+{
+ if (samples_to_send > samples_sent)
+ return 0; /* give more samples */
+ else
+ return 1;
+}
+
+void SoundFeedStreamData(void *buf, long bytes)
+{
+ audio_batch_cb(buf, bytes / 4);
+ samples_sent += bytes / 4;
+}
+
+/* libretro */
+void retro_set_environment(retro_environment_t cb) { environ_cb = cb; }
+void retro_set_video_refresh(retro_video_refresh_t cb) { video_cb = cb; }
+void retro_set_audio_sample(retro_audio_sample_t cb) { (void)cb; }
+void retro_set_audio_sample_batch(retro_audio_sample_batch_t cb) { audio_batch_cb = cb; }
+void retro_set_input_poll(retro_input_poll_t cb) { input_poll_cb = cb; }
+void retro_set_input_state(retro_input_state_t cb) { input_state_cb = cb; }
+
+unsigned retro_api_version(void)
+{
+ return RETRO_API_VERSION;
+}
+
+void retro_set_controller_port_device(unsigned port, unsigned device)
+{
+}
+
+void retro_get_system_info(struct retro_system_info *info)
+{
+ memset(info, 0, sizeof(*info));
+ info->library_name = "PCSX-ReARMed";
+ info->library_version = REV;
+ info->valid_extensions = "bin|cue|img|mdf|pbp|cbn";
+ info->need_fullpath = true;
+}
+
+void retro_get_system_av_info(struct retro_system_av_info *info)
+{
+ memset(info, 0, sizeof(*info));
+ info->timing.fps = 60;
+ info->timing.sample_rate = 44100;
+ info->geometry.base_width = 320;
+ info->geometry.base_height = 240;
+ info->geometry.max_width = 640;
+ info->geometry.max_height = 512;
+ info->geometry.aspect_ratio = 4.0 / 3.0;
+}
+
+/* TODO */
+size_t retro_serialize_size(void)
+{
+ return 0;
+}
+
+bool retro_serialize(void *data, size_t size)
+{
+ return false;
+}
+
+bool retro_unserialize(const void *data, size_t size)
+{
+ return false;
+}
+
+void retro_cheat_reset(void)
+{
+}
+
+void retro_cheat_set(unsigned index, bool enabled, const char *code)
+{
+}
+
+bool retro_load_game(const struct retro_game_info *info)
+{
+ if (plugins_opened) {
+ ClosePlugins();
+ plugins_opened = 0;
+ }
+
+ set_cd_image(info->path);
+
+ /* have to reload after set_cd_image for correct cdr plugin */
+ if (LoadPlugins() == -1) {
+ printf("faled to load plugins\n");
+ return false;
+ }
+
+ plugins_opened = 1;
+ NetOpened = 0;
+
+ if (OpenPlugins() == -1) {
+ printf("faled to open plugins\n");
+ return false;
+ }
+
+ plugin_call_rearmed_cbs();
+
+ Config.PsxAuto = 1;
+ if (CheckCdrom() == -1) {
+ printf("unsupported/invalid CD image: %s\n", info->path);
+ return false;
+ }
+
+ SysReset();
+
+ if (LoadCdrom() == -1) {
+ printf("could not load CD-ROM!\n");
+ return false;
+ }
+ emu_on_new_cd();
+
+ return true;
+}
+
+bool retro_load_game_special(unsigned game_type, const struct retro_game_info *info, size_t num_info)
+{
+ return false;
+}
+
+void retro_unload_game(void)
+{
+}
+
+unsigned retro_get_region(void)
+{
+ return RETRO_REGION_NTSC;
+}
+
+void *retro_get_memory_data(unsigned id)
+{
+ return NULL;
+}
+
+size_t retro_get_memory_size(unsigned id)
+{
+ return 0;
+}
+
+void retro_reset(void)
+{
+ SysReset();
+}
+
+static const unsigned short retro_psx_map[] = {
+ [RETRO_DEVICE_ID_JOYPAD_B] = 1 << DKEY_CROSS,
+ [RETRO_DEVICE_ID_JOYPAD_Y] = 1 << DKEY_SQUARE,
+ [RETRO_DEVICE_ID_JOYPAD_SELECT] = 1 << DKEY_SELECT,
+ [RETRO_DEVICE_ID_JOYPAD_START] = 1 << DKEY_START,
+ [RETRO_DEVICE_ID_JOYPAD_UP] = 1 << DKEY_UP,
+ [RETRO_DEVICE_ID_JOYPAD_DOWN] = 1 << DKEY_DOWN,
+ [RETRO_DEVICE_ID_JOYPAD_LEFT] = 1 << DKEY_LEFT,
+ [RETRO_DEVICE_ID_JOYPAD_RIGHT] = 1 << DKEY_RIGHT,
+ [RETRO_DEVICE_ID_JOYPAD_A] = 1 << DKEY_CIRCLE,
+ [RETRO_DEVICE_ID_JOYPAD_X] = 1 << DKEY_TRIANGLE,
+ [RETRO_DEVICE_ID_JOYPAD_L] = 1 << DKEY_L1,
+ [RETRO_DEVICE_ID_JOYPAD_R] = 1 << DKEY_R1,
+ [RETRO_DEVICE_ID_JOYPAD_L2] = 1 << DKEY_L2,
+ [RETRO_DEVICE_ID_JOYPAD_R2] = 1 << DKEY_R2,
+ [RETRO_DEVICE_ID_JOYPAD_L3] = 1 << DKEY_L3,
+ [RETRO_DEVICE_ID_JOYPAD_R3] = 1 << DKEY_R3,
+};
+#define RETRO_PSX_MAP_LEN (sizeof(retro_psx_map) / sizeof(retro_psx_map[0]))
+
+void retro_run(void)
+{
+ int i;
+
+ input_poll_cb();
+ in_keystate = 0;
+ for (i = 0; i < RETRO_PSX_MAP_LEN; i++)
+ if (input_state_cb(1, RETRO_DEVICE_JOYPAD, 0, i))
+ in_keystate |= retro_psx_map[i];
+ in_keystate <<= 16;
+ for (i = 0; i < RETRO_PSX_MAP_LEN; i++)
+ if (input_state_cb(0, RETRO_DEVICE_JOYPAD, 0, i))
+ in_keystate |= retro_psx_map[i];
+
+ stop = 0;
+ psxCpu->Execute();
+
+ samples_to_send += 44100 / 60;
+}
+
+void retro_init(void)
+{
+ const char *bios[] = { "scph1001", "scph5501", "scph7001" };
+ const char *dir;
+ char path[256];
+ FILE *f = NULL;
+ int i, ret, level;
+
+ ret = emu_core_preinit();
+ ret |= emu_core_init();
+ if (ret != 0) {
+ printf("PCSX init failed, sorry\n");
+ exit(1);
+ }
+
+ vout_buf = malloc(640 * 512 * 2);
+
+ if (environ_cb(RETRO_ENVIRONMENT_GET_SYSTEM_DIRECTORY, &dir) && dir)
+ {
+ snprintf(Config.BiosDir, sizeof(Config.BiosDir), "%s/", dir);
+
+ for (i = 0; i < sizeof(bios) / sizeof(bios[0]); i++) {
+ snprintf(path, sizeof(path), "%s/%s.bin", dir, bios[i]);
+ f = fopen(path, "r");
+ if (f != NULL) {
+ snprintf(Config.Bios, sizeof(Config.Bios), "%s.bin", bios[i]);
+ break;
+ }
+ }
+ }
+ if (f != NULL) {
+ printf("found BIOS file: %s\n", Config.Bios);
+ fclose(f);
+ }
+ else
+ printf("no BIOS files found.\n");
+
+ level = 1;
+ environ_cb(RETRO_ENVIRONMENT_SET_PERFORMANCE_LEVEL, &level);
+}
+
+void retro_deinit(void)
+{
+ SysClose();
+ free(vout_buf);
+ vout_buf = NULL;
+}
+
--- /dev/null
+#ifndef LIBRETRO_H__
+#define LIBRETRO_H__
+
+#include <stdint.h>
+#include <stddef.h>
+
+#ifdef __cplusplus
+extern "C" {
+#else
+#if defined(_MSC_VER) && !defined(__cplusplus)
+#define bool unsigned char
+#define true 1
+#define false 0
+#else
+#include <stdbool.h>
+#endif
+#endif
+
+#define RETRO_API_VERSION 1
+
+#define RETRO_DEVICE_MASK 0xff
+#define RETRO_DEVICE_NONE 0
+#define RETRO_DEVICE_JOYPAD 1
+#define RETRO_DEVICE_MOUSE 2
+#define RETRO_DEVICE_KEYBOARD 3
+#define RETRO_DEVICE_LIGHTGUN 4
+#define RETRO_DEVICE_ANALOG 5
+
+#define RETRO_DEVICE_JOYPAD_MULTITAP ((1 << 8) | RETRO_DEVICE_JOYPAD)
+#define RETRO_DEVICE_LIGHTGUN_SUPER_SCOPE ((1 << 8) | RETRO_DEVICE_LIGHTGUN)
+#define RETRO_DEVICE_LIGHTGUN_JUSTIFIER ((2 << 8) | RETRO_DEVICE_LIGHTGUN)
+#define RETRO_DEVICE_LIGHTGUN_JUSTIFIERS ((3 << 8) | RETRO_DEVICE_LIGHTGUN)
+
+#define RETRO_DEVICE_ID_JOYPAD_B 0
+#define RETRO_DEVICE_ID_JOYPAD_Y 1
+#define RETRO_DEVICE_ID_JOYPAD_SELECT 2
+#define RETRO_DEVICE_ID_JOYPAD_START 3
+#define RETRO_DEVICE_ID_JOYPAD_UP 4
+#define RETRO_DEVICE_ID_JOYPAD_DOWN 5
+#define RETRO_DEVICE_ID_JOYPAD_LEFT 6
+#define RETRO_DEVICE_ID_JOYPAD_RIGHT 7
+#define RETRO_DEVICE_ID_JOYPAD_A 8
+#define RETRO_DEVICE_ID_JOYPAD_X 9
+#define RETRO_DEVICE_ID_JOYPAD_L 10
+#define RETRO_DEVICE_ID_JOYPAD_R 11
+#define RETRO_DEVICE_ID_JOYPAD_L2 12
+#define RETRO_DEVICE_ID_JOYPAD_R2 13
+#define RETRO_DEVICE_ID_JOYPAD_L3 14
+#define RETRO_DEVICE_ID_JOYPAD_R3 15
+
+#define RETRO_DEVICE_INDEX_ANALOG_LEFT 0
+#define RETRO_DEVICE_INDEX_ANALOG_RIGHT 1
+#define RETRO_DEVICE_ID_ANALOG_X 0
+#define RETRO_DEVICE_ID_ANALOG_Y 1
+
+#define RETRO_DEVICE_ID_MOUSE_X 0
+#define RETRO_DEVICE_ID_MOUSE_Y 1
+#define RETRO_DEVICE_ID_MOUSE_LEFT 2
+#define RETRO_DEVICE_ID_MOUSE_RIGHT 3
+
+#define RETRO_DEVICE_ID_LIGHTGUN_X 0
+#define RETRO_DEVICE_ID_LIGHTGUN_Y 1
+#define RETRO_DEVICE_ID_LIGHTGUN_TRIGGER 2
+#define RETRO_DEVICE_ID_LIGHTGUN_CURSOR 3
+#define RETRO_DEVICE_ID_LIGHTGUN_TURBO 4
+#define RETRO_DEVICE_ID_LIGHTGUN_PAUSE 5
+#define RETRO_DEVICE_ID_LIGHTGUN_START 6
+
+#define RETRO_REGION_NTSC 0
+#define RETRO_REGION_PAL 1
+
+#define RETRO_MEMORY_MASK 0xff
+#define RETRO_MEMORY_SAVE_RAM 0
+#define RETRO_MEMORY_RTC 1
+#define RETRO_MEMORY_SYSTEM_RAM 2
+#define RETRO_MEMORY_VIDEO_RAM 3
+
+#define RETRO_MEMORY_SNES_BSX_RAM ((1 << 8) | RETRO_MEMORY_SAVE_RAM)
+#define RETRO_MEMORY_SNES_BSX_PRAM ((2 << 8) | RETRO_MEMORY_SAVE_RAM)
+#define RETRO_MEMORY_SNES_SUFAMI_TURBO_A_RAM ((3 << 8) | RETRO_MEMORY_SAVE_RAM)
+#define RETRO_MEMORY_SNES_SUFAMI_TURBO_B_RAM ((4 << 8) | RETRO_MEMORY_SAVE_RAM)
+#define RETRO_MEMORY_SNES_GAME_BOY_RAM ((5 << 8) | RETRO_MEMORY_SAVE_RAM)
+#define RETRO_MEMORY_SNES_GAME_BOY_RTC ((6 << 8) | RETRO_MEMORY_RTC)
+
+#define RETRO_GAME_TYPE_BSX 0x101
+#define RETRO_GAME_TYPE_BSX_SLOTTED 0x102
+#define RETRO_GAME_TYPE_SUFAMI_TURBO 0x103
+#define RETRO_GAME_TYPE_SUPER_GAME_BOY 0x104
+
+
+// Environment commands.
+#define RETRO_ENVIRONMENT_SET_ROTATION 1 // const unsigned * --
+ // Sets screen rotation of graphics.
+ // Is only implemented if rotation can be accelerated by hardware.
+ // Valid values are 0, 1, 2, 3, which rotates screen by 0, 90, 180, 270 degrees
+ // counter-clockwise respectively.
+ //
+#define RETRO_ENVIRONMENT_GET_OVERSCAN 2 // bool * --
+ // Boolean value whether or not the implementation should use overscan, or crop away overscan.
+ //
+#define RETRO_ENVIRONMENT_GET_CAN_DUPE 3 // bool * --
+ // Boolean value whether or not RetroArch supports frame duping,
+ // passing NULL to video frame callback.
+ //
+#define RETRO_ENVIRONMENT_GET_VARIABLE 4 // struct retro_variable * --
+ // Interface to aquire user-defined information from environment
+ // that cannot feasibly be supported in a multi-system way.
+ // Mostly used for obscure,
+ // specific features that the user can tap into when neseccary.
+ //
+#define RETRO_ENVIRONMENT_SET_VARIABLES 5 // const struct retro_variable * --
+ // Allows an implementation to signal the environment
+ // which variables it might want to check for later using GET_VARIABLE.
+ // 'data' points to an array of retro_variable structs terminated by a { NULL, NULL } element.
+ // retro_variable::value should contain a human readable description of the key.
+ //
+#define RETRO_ENVIRONMENT_SET_MESSAGE 6 // const struct retro_message * --
+ // Sets a message to be displayed in implementation-specific manner for a certain amount of 'frames'.
+ // Should not be used for trivial messages, which should simply be logged to stderr.
+#define RETRO_ENVIRONMENT_SHUTDOWN 7 // N/A (NULL) --
+ // Requests the frontend to shutdown.
+ // Should only be used if game has a specific
+ // way to shutdown the game from a menu item or similar.
+ //
+#define RETRO_ENVIRONMENT_SET_PERFORMANCE_LEVEL 8
+ // const unsigned * --
+ // Gives a hint to the frontend how demanding this implementation
+ // is on a system. E.g. reporting a level of 2 means
+ // this implementation should run decently on all frontends
+ // of level 2 and up.
+ //
+ // It can be used by the frontend to potentially warn
+ // about too demanding implementations.
+ //
+ // The levels are "floating", but roughly defined as:
+ // 1: Low-powered devices such as Raspberry Pi, smart phones, tablets, etc.
+ // 2: Medium-spec consoles, such as PS3/360, with sub-par CPUs.
+ // 3: Modern desktop/laptops with reasonably powerful CPUs.
+ // 4: High-end desktops with very powerful CPUs.
+ //
+ // This function can be called on a per-game basis,
+ // as certain games an implementation can play might be
+ // particularily demanding.
+ // If called, it should be called in retro_load_game().
+ //
+#define RETRO_ENVIRONMENT_GET_SYSTEM_DIRECTORY 9
+ // const char ** --
+ // Returns the "system" directory of the frontend.
+ // This directory can be used to store system specific ROMs such as BIOSes, configuration data, etc.
+ // The returned value can be NULL.
+ // If so, no such directory is defined,
+ // and it's up to the implementation to find a suitable directory.
+ //
+#define RETRO_ENVIRONMENT_SET_PIXEL_FORMAT 10
+ // const enum retro_pixel_format * --
+ // Sets the internal pixel format used by the implementation.
+ // The default pixel format is RETRO_PIXEL_FORMAT_XRGB1555.
+ // If the call returns false, the frontend does not support this pixel format.
+ // This function should be called inside retro_load_game() or retro_get_system_av_info().
+
+enum retro_pixel_format
+{
+ RETRO_PIXEL_FORMAT_0RGB1555 = 0, // 0RGB1555, native endian. 0 bit must be set to 0.
+ RETRO_PIXEL_FORMAT_XRGB8888 // XRGB8888, native endian. X bits are ignored.
+};
+
+struct retro_message
+{
+ const char *msg; // Message to be displayed.
+ unsigned frames; // Duration in frames of message.
+};
+
+struct retro_system_info
+{
+ const char *library_name; // Descriptive name of library. Should not contain any version numbers, etc.
+ const char *library_version; // Descriptive version of core.
+
+ const char *valid_extensions; // A string listing probably rom extensions the core will be able to load, separated with pipe.
+ // I.e. "bin|rom|iso".
+ // Typically used for a GUI to filter out extensions.
+
+ bool need_fullpath; // If true, retro_load_game() is guaranteed to provide a valid pathname in retro_game_info::path.
+ // ::data and ::size are both invalid.
+ // If false, ::data and ::size are guaranteed to be valid, but ::path might not be valid.
+ // This is typically set to true for libretro implementations that must load from file.
+ // Implementations should strive for setting this to false, as it allows the frontend to perform patching, etc.
+
+ bool block_extract; // If true, the frontend is not allowed to extract any archives before loading the real ROM.
+ // Necessary for certain libretro implementations that load games from zipped archives.
+};
+
+struct retro_game_geometry
+{
+ unsigned base_width; // Nominal video width of game.
+ unsigned base_height; // Nominal video height of game.
+ unsigned max_width; // Maximum possible width of game.
+ unsigned max_height; // Maximum possible height of game.
+
+ float aspect_ratio; // Nominal aspect ratio of game. If aspect_ratio is <= 0.0,
+ // an aspect ratio of base_width / base_height is assumed.
+ // A frontend could override this setting if desired.
+};
+
+struct retro_system_timing
+{
+ double fps; // FPS of video content.
+ double sample_rate; // Sampling rate of audio.
+};
+
+struct retro_system_av_info
+{
+ struct retro_game_geometry geometry;
+ struct retro_system_timing timing;
+};
+
+struct retro_variable
+{
+ const char *key; // Variable to query in RETRO_ENVIRONMENT_GET_VARIABLE.
+ // If NULL, obtains the complete environment string if more complex parsing is necessary.
+ // The environment string is formatted as key-value pairs delimited by semicolons as so:
+ // "key1=value1;key2=value2;..."
+ const char *value; // Value to be obtained. If key does not exist, it is set to NULL.
+};
+
+struct retro_game_info
+{
+ const char *path; // Path to game, UTF-8 encoded. Usually used as a reference.
+ // May be NULL if rom was loaded from stdin or similar.
+ // retro_system_info::need_fullpath guaranteed that this path is valid.
+ const void *data; // Memory buffer of loaded game. Will be NULL if need_fullpath was set.
+ size_t size; // Size of memory buffer.
+ const char *meta; // String of implementation specific meta-data.
+};
+
+// Callbacks
+//
+// Environment callback. Gives implementations a way of performing uncommon tasks. Extensible.
+typedef bool (*retro_environment_t)(unsigned cmd, void *data);
+
+// Render a frame. Pixel format is 15-bit 0RGB1555 native endian unless changed (see RETRO_ENVIRONMENT_SET_PIXEL_FORMAT).
+// Width and height specify dimensions of buffer.
+// Pitch specifices length in bytes between two lines in buffer.
+typedef void (*retro_video_refresh_t)(const void *data, unsigned width, unsigned height, size_t pitch);
+
+// Renders a single audio frame. Should only be used if implementation generates a single sample at a time.
+// Format is signed 16-bit native endian.
+typedef void (*retro_audio_sample_t)(int16_t left, int16_t right);
+// Renders multiple audio frames in one go. One frame is defined as a sample of left and right channels, interleaved.
+// I.e. int16_t buf[4] = { l, r, l, r }; would be 2 frames.
+// Only one of the audio callbacks must ever be used.
+typedef size_t (*retro_audio_sample_batch_t)(const int16_t *data, size_t frames);
+
+// Polls input.
+typedef void (*retro_input_poll_t)(void);
+// Queries for input for player 'port'. device will be masked with RETRO_DEVICE_MASK.
+// Specialization of devices such as RETRO_DEVICE_JOYPAD_MULTITAP that have been set with retro_set_controller_port_device()
+// will still use the higher level RETRO_DEVICE_JOYPAD to request input.
+typedef int16_t (*retro_input_state_t)(unsigned port, unsigned device, unsigned index, unsigned id);
+
+// Sets callbacks. retro_set_environment() is guaranteed to be called before retro_init().
+// The rest of the set_* functions are guaranteed to have been called before the first call to retro_run() is made.
+void retro_set_environment(retro_environment_t);
+void retro_set_video_refresh(retro_video_refresh_t);
+void retro_set_audio_sample(retro_audio_sample_t);
+void retro_set_audio_sample_batch(retro_audio_sample_batch_t);
+void retro_set_input_poll(retro_input_poll_t);
+void retro_set_input_state(retro_input_state_t);
+
+// Library global initialization/deinitialization.
+void retro_init(void);
+void retro_deinit(void);
+
+// Must return RETRO_API_VERSION. Used to validate ABI compatibility when the API is revised.
+unsigned retro_api_version(void);
+
+// Gets statically known system info. Pointers provided in *info must be statically allocated.
+// Can be called at any time, even before retro_init().
+void retro_get_system_info(struct retro_system_info *info);
+
+// Gets information about system audio/video timings and geometry.
+// Can be called only after retro_load_game() has successfully completed.
+void retro_get_system_av_info(struct retro_system_av_info *info);
+
+// Sets device to be used for player 'port'.
+void retro_set_controller_port_device(unsigned port, unsigned device);
+
+// Resets the current game.
+void retro_reset(void);
+
+// Runs the game for one video frame.
+// During retro_run(), input_poll callback must be called at least once.
+//
+// If a frame is not rendered for reasons where a game "dropped" a frame,
+// this still counts as a frame, and retro_run() should explicitly dupe a frame if GET_CAN_DUPE returns true.
+// In this case, the video callback can take a NULL argument for data.
+void retro_run(void);
+
+// Returns the amount of data the implementation requires to serialize internal state (save states).
+// Beetween calls to retro_load_game() and retro_unload_game(), the returned size is never allowed to be larger than a previous returned value, to
+// ensure that the frontend can allocate a save state buffer once.
+size_t retro_serialize_size(void);
+
+// Serializes internal state. If failed, or size is lower than retro_serialize_size(), it should return false, true otherwise.
+bool retro_serialize(void *data, size_t size);
+bool retro_unserialize(const void *data, size_t size);
+
+void retro_cheat_reset(void);
+void retro_cheat_set(unsigned index, bool enabled, const char *code);
+
+// Loads a game.
+bool retro_load_game(const struct retro_game_info *game);
+
+// Loads a "special" kind of game. Should not be used except in extreme cases.
+bool retro_load_game_special(
+ unsigned game_type,
+ const struct retro_game_info *info, size_t num_info
+);
+
+// Unloads a currently loaded game.
+void retro_unload_game(void);
+
+// Gets region of game.
+unsigned retro_get_region(void);
+
+// Gets region of memory.
+void *retro_get_memory_data(unsigned id);
+size_t retro_get_memory_size(unsigned id);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
#include "common/readpng.h"
#include "common/input.h"
#include "linux/in_evdev.h"
+#include "revision.h"
// don't include debug.h - it breaks ARM build (R1 redefined)
void StartDebugger();
void do_emu_action(void)
{
- char buf[MAXPATHLEN];
int ret;
emu_action_old = emu_action;
switch (emu_action) {
- case SACTION_ENTER_MENU:
- menu_loop();
- return;
case SACTION_LOAD_STATE:
ret = emu_load_state(state_slot);
snprintf(hud_msg, sizeof(hud_msg), ret == 0 ? "LOADED" : "FAIL!");
ret = emu_save_state(state_slot);
snprintf(hud_msg, sizeof(hud_msg), ret == 0 ? "SAVED" : "FAIL!");
break;
+#ifndef NO_FRONTEND
+ case SACTION_ENTER_MENU:
+ menu_loop();
+ return;
case SACTION_NEXT_SSLOT:
state_slot++;
if (state_slot > 9)
state_slot--;
if (state_slot < 0)
state_slot = 9;
- goto do_state_slot;
+do_state_slot:
+ snprintf(hud_msg, sizeof(hud_msg), "STATE SLOT %d [%s]", state_slot,
+ emu_check_state(state_slot) == 0 ? "USED" : "FREE");
+ hud_new_msg = 3;
+ printf("* %s\n", hud_msg);
+ break;
case SACTION_TOGGLE_FSKIP:
pl_rearmed_cbs.fskip_advice = 0;
pl_rearmed_cbs.frameskip++;
break;
case SACTION_SCREENSHOT:
{
+ char buf[MAXPATHLEN];
void *scrbuf;
int w, h, bpp;
time_t t = time(NULL);
case SACTION_MINIMIZE:
plat_minimize();
return;
+#endif
default:
return;
}
- hud_new_msg = 3;
- return;
-do_state_slot:
- snprintf(hud_msg, sizeof(hud_msg), "STATE SLOT %d [%s]", state_slot,
- emu_check_state(state_slot) == 0 ? "USED" : "FREE");
hud_new_msg = 3;
- printf("* %s\n", hud_msg);
}
static int cdidcmp(const char *id1, const char *id2)
hud_new_msg = 2;
}
-int main(int argc, char *argv[])
+int emu_core_preinit(void)
{
// what is the name of the config file?
// it may be redefined by -cfg on the command line
memset(&Config, 0, sizeof(Config));
- CheckSubDir();
set_default_paths();
emu_set_default_config();
- check_memcards();
strcpy(Config.Bios, "HLE");
-#ifdef MAEMO
- extern int maemo_main(int argc, char **argv);
- return maemo_main(argc, argv);
-#else
+ return 0;
+}
+
+int emu_core_init(void)
+{
+ CheckSubDir();
+ check_memcards();
+
+ if (EmuInit() == -1) {
+ printf("PSX emulator couldn't be initialized.\n");
+ return -1;
+ }
+
+ LoadMcds(Config.Mcd1, Config.Mcd2);
+
+ if (Config.Debug) {
+ StartDebugger();
+ }
+
+ return 0;
+}
+
+#ifndef NO_FRONTEND
+int main(int argc, char *argv[])
+{
char file[MAXPATHLEN] = "";
char path[MAXPATHLEN];
const char *cdfile = NULL;
int loadst = 0;
int i;
+ emu_core_preinit();
+
// read command line options
for (i = 1; i < argc; i++) {
if (!strcmp(argv[i], "-psxout")) psxout = 1;
else if (!strcmp(argv[i], "-h") ||
!strcmp(argv[i], "-help") ||
!strcmp(argv[i], "--help")) {
- printf(PACKAGE_NAME " " PACKAGE_VERSION "\n");
+ printf("PCSX-ReARMed " REV "\n");
printf("%s\n", _(
" pcsx [options] [file]\n"
"\toptions:\n"
"\t-cdfile FILE\tRuns a CD image file\n"
- "\t-nogui\t\tDon't open the GTK GUI\n"
"\t-cfg FILE\tLoads desired configuration file (default: ~/.pcsx/pcsx.cfg)\n"
"\t-psxout\t\tEnable PSX output\n"
"\t-load STATENUM\tLoads savestate STATENUM (1-5)\n"
"\t-h -help\tDisplay this message\n"
- "\tfile\t\tLoads file\n"));
+ "\tfile\t\tLoads a PSX EXE file\n"));
return 0;
} else {
strncpy(file, argv[i], MAXPATHLEN);
if (cdfile)
set_cd_image(cdfile);
- if (SysInit() == -1)
- return 1;
-
// frontend stuff
// init input but leave probing to platform code,
// they add input drivers and may need to modify them after probe
plat_init();
menu_init(); // loads config
+ emu_core_init();
+
if (psxout)
Config.PsxOut = 1;
do_emu_action();
}
- return 0;
-#endif
-}
-
-int SysInit() {
- if (EmuInit() == -1) {
- printf("PSX emulator couldn't be initialized.\n");
- return -1;
- }
-
- LoadMcds(Config.Mcd1, Config.Mcd2);
-
- if (Config.Debug) {
- StartDebugger();
- }
-
return 0;
}
+#endif
void SysRunGui() {
printf("SysRunGui\n");
}
-void StartGui() {
- printf("StartGui\n");
-}
-
static void dummy_lace()
{
}
void OnFile_Exit() {
printf("OnFile_Exit\n");
-#ifndef MAEMO
- menu_finish();
-#endif
SysClose();
+#ifndef NO_FRONTEND
+ menu_finish();
plat_finish();
exit(0);
+#endif
}
int get_state_filename(char *buf, int size, int i) {
MAKE_PATH(dotdir, "/.pcsx/plugins/", NULL);
- strcpy(info.EmuName, "PCSX " PACKAGE_VERSION);
+ strcpy(info.EmuName, "PCSX");
strncpy(info.CdromID, CdromId, 9);
strncpy(info.CdromLabel, CdromLabel, 9);
info.psxMem = psxM;
extern char cfgfile_basename[MAXPATHLEN];
extern int state_slot;
+
+/* emu_core_preinit - must be the very first call
+ * emu_core_init - to be called after platform-specific setup */
+int emu_core_preinit(void);
+int emu_core_init(void);
+
void emu_set_default_config(void);
void emu_on_new_cd(void);
pl_rearmed_cbs.only_16bpp = 1;
}
-void menu_loop(void)
-{
-}
-
void *plat_gvideo_set_mode(int *w_, int *h_, int *bpp_)
{
int w = *w_, h = *h_;
}
}
-int maemo_main(int argc, char **argv)
+int main(int argc, char **argv)
{
- ChangeWorkingDirectory("c");
char file[MAXPATHLEN] = "";
char path[MAXPATHLEN];
const char *cdfile = NULL;
int loadst = 0;
int i;
+ emu_core_preinit();
+ ChangeWorkingDirectory("c");
+
strcpy(Config.BiosDir, "/home/user/MyDocs");
strcpy(Config.PluginsDir, "/opt/maemo/usr/games/plugins");
snprintf(Config.PatchesDir, sizeof(Config.PatchesDir), "/opt/maemo/usr/games" PATCHES_DIR);
Config.PsxAuto = 1;
+ pl_init();
+
+ emu_core_init();
+
// read command line options
for (i = 1; i < argc; i++) {
if (!strcmp(argv[i], "-psxout")) Config.PsxOut = 1;
strcpy(file_name, strrchr(cdfile,'/'));
}
- if (SysInit() == -1)
- return 1;
-
- pl_init();
-
if (LoadPlugins() == -1) {
SysMessage("Failed loading plugins!");
return 1;
void SetAspectRatio(void)
{
- cbs->pl_get_layer_pos(&rRatioRect.left, &rRatioRect.top, &rRatioRect.right, &rRatioRect.bottom);
+ if (cbs->pl_get_layer_pos)
+ cbs->pl_get_layer_pos(&rRatioRect.left, &rRatioRect.top, &rRatioRect.right, &rRatioRect.bottom);
glScissor(rRatioRect.left,
iResY-(rRatioRect.top+rRatioRect.bottom),