diff --git a/libretro/libretro.c b/libretro/libretro.c index 0b34067..facfd46 100644 --- a/libretro/libretro.c +++ b/libretro/libretro.c @@ -13,15 +13,14 @@ #include #endif -#define RETRO_DEVICE_MDPAD_3B RETRO_DEVICE_SUBCLASS(RETRO_DEVICE_JOYPAD, 0) -#define RETRO_DEVICE_MDPAD_6B RETRO_DEVICE_SUBCLASS(RETRO_DEVICE_JOYPAD, 1) -#define RETRO_DEVICE_SMSPAD_2B RETRO_DEVICE_SUBCLASS(RETRO_DEVICE_JOYPAD, 2) -#define RETRO_DEVICE_PORT_NONE RETRO_DEVICE_SUBCLASS(RETRO_DEVICE_JOYPAD, 3) -#define RETRO_DEVICE_MDPAD_3B_WAYPLAY RETRO_DEVICE_SUBCLASS(RETRO_DEVICE_JOYPAD, 4) -#define RETRO_DEVICE_MDPAD_6B_WAYPLAY RETRO_DEVICE_SUBCLASS(RETRO_DEVICE_JOYPAD, 5) -#define RETRO_DEVICE_MDPAD_3B_TEAMPLAYER RETRO_DEVICE_SUBCLASS(RETRO_DEVICE_JOYPAD, 6) -#define RETRO_DEVICE_MDPAD_6B_TEAMPLAYER RETRO_DEVICE_SUBCLASS(RETRO_DEVICE_JOYPAD, 7) -#define RETRO_DEVICE_SMSPAD_4P RETRO_DEVICE_SUBCLASS(RETRO_DEVICE_JOYPAD, 8) +#define RETRO_DEVICE_MDPAD_3B RETRO_DEVICE_SUBCLASS(RETRO_DEVICE_JOYPAD, 0) +#define RETRO_DEVICE_MDPAD_6B RETRO_DEVICE_SUBCLASS(RETRO_DEVICE_JOYPAD, 1) +#define RETRO_DEVICE_MSPAD_2B RETRO_DEVICE_SUBCLASS(RETRO_DEVICE_JOYPAD, 2) +#define RETRO_DEVICE_MDPAD_3B_WAYPLAY RETRO_DEVICE_SUBCLASS(RETRO_DEVICE_JOYPAD, 3) +#define RETRO_DEVICE_MDPAD_6B_WAYPLAY RETRO_DEVICE_SUBCLASS(RETRO_DEVICE_JOYPAD, 4) +#define RETRO_DEVICE_MDPAD_3B_TEAMPLAYER RETRO_DEVICE_SUBCLASS(RETRO_DEVICE_JOYPAD, 5) +#define RETRO_DEVICE_MDPAD_6B_TEAMPLAYER RETRO_DEVICE_SUBCLASS(RETRO_DEVICE_JOYPAD, 6) +#define RETRO_DEVICE_MSPAD_2B_MASTERTAP RETRO_DEVICE_SUBCLASS(RETRO_DEVICE_JOYPAD, 7) #include "shared.h" #include "libretro.h" @@ -113,8 +112,8 @@ int load_archive(char *filename, unsigned char *buffer, int maxsize, char *exten { if (log_cb) log_cb(RETRO_LOG_ERROR, "Unable to open CD BIOS: %s.\n", filename); - return 0; - } + return 0; + } if (log_cb) log_cb(RETRO_LOG_ERROR, "Unable to open file.\n"); @@ -171,7 +170,7 @@ void osd_input_update(void) input_poll_cb(); - for(i = 0; i < MAX_INPUTS; i++) + for (i = 0; i < MAX_INPUTS; i++) { temp = 0; switch (input.dev[i]) @@ -267,6 +266,14 @@ static void config_default(void) config.gg_extra = 0; config.ntsc = 0; config.render = 0; + + /* input options */ + input.system[0] = SYSTEM_GAMEPAD; + input.system[1] = SYSTEM_GAMEPAD; + for (i=0; ipath)) return false; - for (i = 0; i < 2; i++) - retro_set_controller_port_device(i, input.dev[i]); - audio_init(44100, vdp_pal ? pal_fps : ntsc_fps); system_init(); system_reset(); @@ -1072,7 +1099,7 @@ void retro_run(void) { struct retro_system_av_info info; retro_get_system_av_info(&info); - environ_cb(RETRO_ENVIRONMENT_SET_SYSTEM_AV_INFO, &info); + environ_cb(RETRO_ENVIRONMENT_SET_GEOMETRY, &info.geometry); } } diff --git a/libretro/libretro.h b/libretro/libretro.h index a0a7483..d132fb1 100755 --- a/libretro/libretro.h +++ b/libretro/libretro.h @@ -388,16 +388,11 @@ enum retro_mod // It can be used by the frontend to potentially warn // about too demanding implementations. // - // The levels are "floating", but roughly defined as: - // 0: Low-powered embedded devices such as Raspberry Pi - // 1: 6th generation consoles, such as Wii/Xbox 1, and phones, tablets, etc. - // 2: 7th generation 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. + // The levels are "floating". // // This function can be called on a per-game basis, // as certain games an implementation can play might be - // particularily demanding. + // particularly demanding. // If called, it should be called in retro_load_game(). // #define RETRO_ENVIRONMENT_GET_SYSTEM_DIRECTORY 9 @@ -589,15 +584,15 @@ enum retro_mod // This should *only* be used if the core is completely altering the internal resolutions, aspect ratios, timings, sampling rate, etc. // Calling this can require a full reinitialization of video/audio drivers in the frontend, // so it is important to call it very sparingly, and usually only with the users explicit consent. - // An eventual driver reinit will happen so that video and audio callbacks + // An eventual driver reinitialize will happen so that video and audio callbacks // happening after this call within the same retro_run() call will target the newly initialized driver. // // This callback makes it possible to support configurable resolutions in games, which can be useful to // avoid setting the "worst case" in max_width/max_height. // // ***HIGHLY RECOMMENDED*** Do not call this callback every time resolution changes in an emulator core if it's - // expected to be a temporary change, for the reasons of possible driver reinit. - // This call is not a free pass for not trying to provide correct values in retro_get_system_av_info(). + // expected to be a temporary change, for the reasons of possible driver reinitialization. + // This call is not a free pass for not trying to provide correct values in retro_get_system_av_info(). If you need to change things like aspect ratio or nominal width/height, use RETRO_ENVIRONMENT_SET_GEOMETRY, which is a softer variant of SET_SYSTEM_AV_INFO. // // If this returns false, the frontend does not acknowledge a changed av_info struct. #define RETRO_ENVIRONMENT_SET_PROC_ADDRESS_CALLBACK 33 @@ -640,6 +635,129 @@ enum retro_mod // The core must pass an array of const struct retro_controller_info which is terminated with // a blanked out struct. Each element of the struct corresponds to an ascending port index to retro_set_controller_port_device(). // Even if special device types are set in the libretro core, libretro should only poll input based on the base input device types. +#define RETRO_ENVIRONMENT_SET_MEMORY_MAPS (36 | RETRO_ENVIRONMENT_EXPERIMENTAL) + // const struct retro_memory_map * -- + // This environment call lets a libretro core tell the frontend about the memory maps this + // core emulates. This can be used to implement, for example, cheats in a core-agnostic way. + // + // Should only be used by emulators; it doesn't make much sense for anything else. + // It is recommended to expose all relevant pointers through retro_get_memory_* as well. + // + // Can be called from retro_init and retro_load_game. + // +#define RETRO_ENVIRONMENT_SET_GEOMETRY 37 + // const struct retro_game_geometry * -- + // This environment call is similar to SET_SYSTEM_AV_INFO for changing video parameters, + // but provides a guarantee that drivers will not be reinitialized. + // This can only be called from within retro_run(). + // + // The purpose of this call is to allow a core to alter nominal width/heights as well as aspect ratios on-the-fly, + // which can be useful for some emulators to change in run-time. + // + // max_width/max_height arguments are ignored and cannot be changed + // with this call as this could potentially require a reinitialization or a non-constant time operation. + // If max_width/max_height are to be changed, SET_SYSTEM_AV_INFO is required. + // + // A frontend must guarantee that this environment call completes in constant time. + + + + +#define RETRO_MEMDESC_CONST (1 << 0) // The frontend will never change this memory area once retro_load_game has returned. +#define RETRO_MEMDESC_BIGENDIAN (1 << 1) // The memory area contains big endian data. Default is little endian. +#define RETRO_MEMDESC_ALIGN_2 (1 << 16) // All memory access in this area is aligned to their own size, or 2, whichever is smaller. +#define RETRO_MEMDESC_ALIGN_4 (2 << 16) +#define RETRO_MEMDESC_ALIGN_8 (3 << 16) +#define RETRO_MEMDESC_MINSIZE_2 (1 << 24) // All memory in this region is accessed at least 2 bytes at the time. +#define RETRO_MEMDESC_MINSIZE_4 (2 << 24) +#define RETRO_MEMDESC_MINSIZE_8 (3 << 24) +struct retro_memory_descriptor +{ + uint64_t flags; + + // Pointer to the start of the relevant ROM or RAM chip. + // It's strongly recommended to use 'offset' if possible, rather than doing math on the pointer. + // If the same byte is mapped my multiple descriptors, their descriptors must have the same pointer. + // If 'start' does not point to the first byte in the pointer, put the difference in 'offset' instead. + // May be NULL if there's nothing usable here (e.g. hardware registers and open bus). No flags should be set if the pointer is NULL. + // It's recommended to minimize the number of descriptors if possible, but not mandatory. + void *ptr; + size_t offset; + + // This is the location in the emulated address space where the mapping starts. + size_t start; + + // Which bits must be same as in 'start' for this mapping to apply. + // The first memory descriptor to claim a certain byte is the one that applies. + // A bit which is set in 'start' must also be set in this. + // Can be zero, in which case each byte is assumed mapped exactly once. In this case, 'len' must be a power of two. + size_t select; + + // If this is nonzero, the set bits are assumed not connected to the memory chip's address pins. + size_t disconnect; + + // This one tells the size of the current memory area. + // If, after start+disconnect are applied, the address is higher than this, the highest bit of the address is cleared. + // If the address is still too high, the next highest bit is cleared. + // Can be zero, in which case it's assumed to be infinite (as limited by 'select' and 'disconnect'). + size_t len; + + // To go from emulated address to physical address, the following order applies: + // Subtract 'start', pick off 'disconnect', apply 'len', add 'offset'. + + // The address space name must consist of only a-zA-Z0-9_-, should be as short as feasible (maximum length is 8 plus the NUL), + // and may not be any other address space plus one or more 0-9A-F at the end. + // However, multiple memory descriptors for the same address space is allowed, and the address + // space name can be empty. NULL is treated as empty. + // Address space names are case sensitive, but avoid lowercase if possible. + // The same pointer may exist in multiple address spaces. + // Examples: + // blank+blank - valid (multiple things may be mapped in the same namespace) + // 'Sp'+'Sp' - valid (multiple things may be mapped in the same namespace) + // 'A'+'B' - valid (neither is a prefix of each other) + // 'S'+blank - valid ('S' is not in 0-9A-F) + // 'a'+blank - valid ('a' is not in 0-9A-F) + // 'a'+'A' - valid (neither is a prefix of each other) + // 'AR'+blank - valid ('R' is not in 0-9A-F) + // 'ARB'+blank - valid (the B can't be part of the address either, because there is no namespace 'AR') + // blank+'B' - not valid, because it's ambigous which address space B1234 would refer to. + // The length can't be used for that purpose; the frontend may want to append arbitrary data to an address, without a separator. + const char *addrspace; +}; +// The frontend may use the largest value of 'start'+'select' in a certain namespace to infer the size of the address space. +// If the address space is larger than that, a mapping with .ptr=NULL should be at the end of the array, with .select set to all ones for as long as the address space is big. +// Sample descriptors (minus .ptr, and RETRO_MEMFLAG_ on the flags): +// SNES WRAM: +// .start=0x7E0000, .len=0x20000 +// (Note that this must be mapped before the ROM in most cases; some of the ROM mappers try to claim $7E0000, or at least $7E8000.) +// SNES SPC700 RAM: +// .addrspace="S", .len=0x10000 +// SNES WRAM mirrors: +// .flags=MIRROR, .start=0x000000, .select=0xC0E000, .len=0x2000 +// .flags=MIRROR, .start=0x800000, .select=0xC0E000, .len=0x2000 +// SNES WRAM mirrors, alternate equivalent descriptor: +// .flags=MIRROR, .select=0x40E000, .disconnect=~0x1FFF +// (Various similar constructions can be created by combining parts of the above two.) +// SNES LoROM (512KB, mirrored a couple of times): +// .flags=CONST, .start=0x008000, .select=0x408000, .disconnect=0x8000, .len=512*1024 +// .flags=CONST, .start=0x400000, .select=0x400000, .disconnect=0x8000, .len=512*1024 +// SNES HiROM (4MB): +// .flags=CONST, .start=0x400000, .select=0x400000, .len=4*1024*1024 +// .flags=CONST, .offset=0x8000, .start=0x008000, .select=0x408000, .len=4*1024*1024 +// SNES ExHiROM (8MB): +// .flags=CONST, .offset=0, .start=0xC00000, .select=0xC00000, .len=4*1024*1024 +// .flags=CONST, .offset=4*1024*1024, .start=0x400000, .select=0xC00000, .len=4*1024*1024 +// .flags=CONST, .offset=0x8000, .start=0x808000, .select=0xC08000, .len=4*1024*1024 +// .flags=CONST, .offset=4*1024*1024+0x8000, .start=0x008000, .select=0xC08000, .len=4*1024*1024 +// Clarify the size of the address space: +// .ptr=NULL, .select=0xFFFFFF +// .len can be implied by .select in many of them, but was included for clarity. + +struct retro_memory_map +{ + const struct retro_memory_descriptor *descriptors; + unsigned num_descriptors; +}; struct retro_controller_description { @@ -987,7 +1105,7 @@ struct retro_frame_time_callback // it should implement context_destroy callback. // If called, all GPU resources must be reinitialized. // Usually called when frontend reinits video driver. -// Also called first time video driver is initialized, allowing libretro core to init resources. +// Also called first time video driver is initialized, allowing libretro core to initialize resources. typedef void (*retro_hw_context_reset_t)(void); // Gets current framebuffer which is to be rendered to. Could change every frame potentially. typedef uintptr_t (*retro_hw_get_current_framebuffer_t)(void); @@ -997,11 +1115,12 @@ typedef retro_proc_address_t (*retro_hw_get_proc_address_t)(const char *sym); enum retro_hw_context_type { - RETRO_HW_CONTEXT_NONE = 0, - RETRO_HW_CONTEXT_OPENGL, // OpenGL 2.x. Latest version available before 3.x+. Driver can choose to use latest compatibility context. - RETRO_HW_CONTEXT_OPENGLES2, // GLES 2.0 - RETRO_HW_CONTEXT_OPENGL_CORE, // Modern desktop core GL context. Use major/minor fields to set GL version. - RETRO_HW_CONTEXT_OPENGLES3, // GLES 3.0 + RETRO_HW_CONTEXT_NONE = 0, + RETRO_HW_CONTEXT_OPENGL = 1, // OpenGL 2.x. Driver can choose to use latest compatibility context. + RETRO_HW_CONTEXT_OPENGLES2 = 2, // GLES 2.0 + RETRO_HW_CONTEXT_OPENGL_CORE = 3, // Modern desktop core GL context. Use version_major/version_minor fields to set GL version. + RETRO_HW_CONTEXT_OPENGLES3 = 4, // GLES 3.0 + RETRO_HW_CONTEXT_OPENGLES_VERSION = 5, // GLES 3.1+. Set version_major/version_minor. For GLES2 and GLES3, use the corresponding enums directly. RETRO_HW_CONTEXT_DUMMY = INT_MAX }; @@ -1026,8 +1145,8 @@ struct retro_hw_render_callback bool stencil; // Set if stencil buffers should be attached. // If depth and stencil are true, a packed 24/8 buffer will be added. Only attaching stencil is invalid and will be ignored. bool bottom_left_origin; // Use conventional bottom-left origin convention. Is false, standard libretro top-left origin semantics are used. - unsigned version_major; // Major version number for core GL context. - unsigned version_minor; // Minor version number for core GL context. + unsigned version_major; // Major version number for core GL context or GLES 3.1+. + unsigned version_minor; // Minor version number for core GL context or GLES 3.1+. bool cache_context; // If this is true, the frontend will go very far to avoid resetting context in scenarios like toggling fullscreen, etc. // The reset callback might still be called in extreme situations such as if the context is lost beyond recovery.