diff --git a/BizHawk.Emulation.Cores/Libretro/LibRetro.cs b/BizHawk.Emulation.Cores/Libretro/LibRetro.cs index 44e02479e4..30cb95fbd9 100644 --- a/BizHawk.Emulation.Cores/Libretro/LibRetro.cs +++ b/BizHawk.Emulation.Cores/Libretro/LibRetro.cs @@ -337,6 +337,47 @@ namespace BizHawk.Emulation.Cores EXPERIMENTAL = 0x10000 }; + public enum retro_hw_context_type + { + RETRO_HW_CONTEXT_NONE = 0, + RETRO_HW_CONTEXT_OPENGL = 1, + RETRO_HW_CONTEXT_OPENGLES2 = 2, + RETRO_HW_CONTEXT_OPENGL_CORE = 3, + RETRO_HW_CONTEXT_OPENGLES3 = 4, + RETRO_HW_CONTEXT_OPENGLES_VERSION = 5, + + RETRO_HW_CONTEXT_DUMMY = Int32.MaxValue + }; + + public struct retro_hw_render_callback + { + public uint context_type; //retro_hw_context_type + public IntPtr context_reset; //retro_hw_context_reset_t + public IntPtr get_current_framebuffer; //retro_hw_get_current_framebuffer_t + public IntPtr get_proc_address; //retro_hw_get_proc_address_t + [MarshalAs(UnmanagedType.U1)] public byte depth; + [MarshalAs(UnmanagedType.U1)] public bool stencil; + [MarshalAs(UnmanagedType.U1)] public bool bottom_left_origin; + public uint version_major; + public uint version_minor; + [MarshalAs(UnmanagedType.U1)] public bool cache_context; + public IntPtr context_destroy; //retro_hw_context_reset_t + [MarshalAs(UnmanagedType.U1)] public bool debug_context; + }; + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + public delegate long retro_hw_context_reset_t(); + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + public delegate IntPtr retro_hw_get_current_framebuffer_t(); + + //not used + //[UnmanagedFunctionPointer(CallingConvention.Cdecl)] + //public delegate void retro_proc_address_t(); + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + public delegate IntPtr retro_hw_get_proc_address_t(string sym); + struct retro_memory_map { public IntPtr descriptors; //retro_memory_descriptor * @@ -346,77 +387,12 @@ namespace BizHawk.Emulation.Cores struct retro_memory_descriptor { ulong 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. */ IntPtr ptr; IntPtr offset; //size_t - - /* This is the location in the emulated address space - * where the mapping starts. */ IntPtr start; //size_t - - /* 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. */ IntPtr select; //size_t - - /* If this is nonzero, the set bits are assumed not connected to the - * memory chip's address pins. */ IntPtr disconnect; //size_t - - /* 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'). */ IntPtr len; //size_t - - /* 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. */ string addrspace; }; diff --git a/BizHawk.Emulation.Cores/Libretro/LibRetroEmulator.cs b/BizHawk.Emulation.Cores/Libretro/LibRetroEmulator.cs index 8b663a924c..504eef9567 100644 --- a/BizHawk.Emulation.Cores/Libretro/LibRetroEmulator.cs +++ b/BizHawk.Emulation.Cores/Libretro/LibRetroEmulator.cs @@ -154,8 +154,12 @@ namespace BizHawk.Emulation.Cores case LibRetro.RETRO_ENVIRONMENT.SET_DISK_CONTROL_INTERFACE: return false; case LibRetro.RETRO_ENVIRONMENT.SET_HW_RENDER: - // this can be done in principle, but there's no reason to right now - return false; + { + //mupen64plus needs this, as well as 3dengine + LibRetro.retro_hw_render_callback* info = (LibRetro.retro_hw_render_callback*)data.ToPointer(); + Console.WriteLine("SET_HW_RENDER: {0}, version={1}.{2}, dbg/cache={3}/{4}, depth/stencil = {5}/{6}{7}", info->context_type, info->version_minor, info->version_major, info->debug_context, info->cache_context, info->depth, info->stencil, info->bottom_left_origin ? " (bottomleft)" : ""); + return true; + } case LibRetro.RETRO_ENVIRONMENT.GET_VARIABLE: { void** variables = (void**)data.ToPointer();