libretro: win32 support. build fix.

This commit is contained in:
flyinghead 2021-07-06 13:22:54 +02:00
parent 68f4c50bd3
commit a3b66aec1f
12 changed files with 348 additions and 284 deletions

View File

@ -79,7 +79,7 @@ jobs:
- name: CMake
run: |
cmake -B build -DCMAKE_BUILD_TYPE=Release -DCMAKE_RUNTIME_OUTPUT_DIRECTORY_RELEASE=artifact ${{ matrix.config.cmakeArgs }}
cmake -B build -DCMAKE_BUILD_TYPE=Release -DCMAKE_RUNTIME_OUTPUT_DIRECTORY_RELEASE=artifact -DCMAKE_LIBRARY_OUTPUT_DIRECTORY=artifact ${{ matrix.config.cmakeArgs }}
cmake --build build --config Release --parallel 2
- name: Unit Tests

View File

@ -55,16 +55,23 @@ configure_file("${CMAKE_CURRENT_SOURCE_DIR}/core/version.h.in" "${CMAKE_CURRENT_
if(LIBRETRO)
add_library(${PROJECT_NAME} SHARED core/emulator.cpp)
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,--no-undefined")
set_target_properties(${PROJECT_NAME} PROPERTIES OUTPUT_NAME "flycast_libretro")
set(CMAKE_SHARED_LIBRARY_PREFIX "")
target_compile_definitions(${PROJECT_NAME} PRIVATE LIBRETRO)
if(ANDROID OR USE_GLES)
target_compile_definitions(${PROJECT_NAME} PRIVATE GLES GLES3 HAVE_OPENGLES HAVE_OPENGLES3)
target_link_libraries(${PROJECT_NAME} PRIVATE "-lGLESv3")
elseif(USE_GLES2)
target_compile_definitions(${PROJECT_NAME} PRIVATE GLES GLES2 HAVE_OPENGLES HAVE_OPENGLES2)
target_link_libraries(${PROJECT_NAME} PRIVATE "-lGLESv2")
else()
target_compile_definitions(${PROJECT_NAME} PRIVATE HAVE_OPENGL)
if(NOT APPLE)
target_compile_definitions(${PROJECT_NAME} PRIVATE HAVE_OIT)
endif()
if(WIN32)
target_link_libraries(${PROJECT_NAME} PRIVATE "-lopengl32")
endif()
endif()
elseif(ANDROID)
add_library(${PROJECT_NAME} SHARED core/emulator.cpp)
@ -641,11 +648,14 @@ if(NOT LIBRETRO)
core/input/mapping.h)
endif()
target_sources(${PROJECT_NAME} PRIVATE
core/linux/common.cpp)
if(NOT WIN32)
if(WIN32)
target_sources(${PROJECT_NAME} PRIVATE
core/windows/fault_handler.cpp
core/windows/fault_handler.h
core/windows/win_vmem.cpp)
else()
target_sources(${PROJECT_NAME} PRIVATE
core/linux/common.cpp
core/linux/context.cpp
core/linux/posix_vmem.cpp)
endif()
@ -869,11 +879,10 @@ if(USE_VULKAN AND NOT APPLE)
endif()
endif()
if(WIN32)
# TODO
if(WIN32 AND NOT LIBRETRO)
target_sources(${PROJECT_NAME} PRIVATE
core/rend/dx9/comptr.h
core/rend/dx9/d3d_overlay.h
core/rend/dx9/d3d_overlay.cpp
core/rend/dx9/d3d_renderer.h
core/rend/dx9/d3d_renderer.cpp
core/rend/dx9/d3d_shaders.h
@ -881,15 +890,20 @@ if(WIN32)
core/rend/dx9/d3d_texture.h
core/rend/dx9/d3d_texture.cpp
core/rend/dx9/dxcontext.h
core/rend/dx9/dxcontext.cpp
core/rend/dx9/imgui_impl_dx9.h
core/rend/dx9/imgui_impl_dx9.cpp)
if(NOT MINGW)
target_include_directories(${PROJECT_NAME} PRIVATE "$ENV{DXSDK_DIR}/Include")
if (CMAKE_SIZEOF_VOID_P EQUAL 8)
target_link_directories(${PROJECT_NAME} PRIVATE "$ENV{DXSDK_DIR}/Lib/x64")
else()
target_link_directories(${PROJECT_NAME} PRIVATE "$ENV{DXSDK_DIR}/Lib/x86")
core/rend/dx9/dxcontext.cpp)
if(NOT LIBRETRO)
target_sources(${PROJECT_NAME} PRIVATE
core/rend/dx9/d3d_overlay.h
core/rend/dx9/d3d_overlay.cpp
core/rend/dx9/imgui_impl_dx9.h
core/rend/dx9/imgui_impl_dx9.cpp)
if(NOT MINGW)
target_include_directories(${PROJECT_NAME} PRIVATE "$ENV{DXSDK_DIR}/Include")
if (CMAKE_SIZEOF_VOID_P EQUAL 8)
target_link_directories(${PROJECT_NAME} PRIVATE "$ENV{DXSDK_DIR}/Lib/x64")
else()
target_link_directories(${PROJECT_NAME} PRIVATE "$ENV{DXSDK_DIR}/Lib/x86")
endif()
endif()
endif()
target_link_libraries(${PROJECT_NAME} PRIVATE d3d9 d3dx9)
@ -1055,10 +1069,8 @@ if(NOT LIBRETRO)
core/windows/winmain.cpp
core/windows/xinput_gamepad.h)
endif()
target_sources(${PROJECT_NAME} PRIVATE
core/windows/win_vmem.cpp
shell/windows/flycast.rc)
target_sources(${PROJECT_NAME} PRIVATE shell/windows/flycast.rc)
target_link_libraries(${PROJECT_NAME} PRIVATE dsound opengl32 winmm ws2_32 wsock32 xinput9_1_0)
endif()
endif()

View File

@ -274,7 +274,7 @@ static void rend_create_renderer()
renderer = rend_OITVulkan();
break;
#endif
#ifdef _WIN32
#if defined(_WIN32) && !defined(LIBRETRO)
case RenderType::DirectX9:
renderer = rend_DirectX9();
break;

View File

@ -17,6 +17,7 @@
along with Flycast. If not, see <https://www.gnu.org/licenses/>.
*/
#include "d3d_overlay.h"
#include "rend/osd.h"
#include "rend/gui.h"
#include <glm/glm.hpp>
#include <glm/gtx/transform.hpp>

View File

@ -482,7 +482,7 @@ void findGLVersion()
}
}
#endif
NOTICE_LOG(RENDERER, "GL %s version %d.%d", gl.is_gles ? "ES" : "", gl.gl_major, gl.gl_minor);
NOTICE_LOG(RENDERER, "Open GL%s version %d.%d", gl.is_gles ? "ES" : "", gl.gl_major, gl.gl_minor);
}
struct ShaderUniforms_t ShaderUniforms;
@ -1150,6 +1150,7 @@ bool RenderFrame(int width, int height)
else
{
#ifdef LIBRETRO
glBindFramebuffer(GL_FRAMEBUFFER, glsm_get_current_framebuffer());
gl.ofbo.width = width;
gl.ofbo.height = height;
glViewport(0, 0, width, height);

View File

@ -0,0 +1,194 @@
/*
This file is part of Flycast.
Flycast is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
Flycast is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Flycast. If not, see <https://www.gnu.org/licenses/>.
*/
#include "fault_handler.h"
#include "hw/sh4/dyna/blockmanager.h"
#include "hw/sh4/dyna/ngen.h"
bool VramLockedWrite(u8* address);
bool BM_LockedWrite(u8* address);
static void readContext(const EXCEPTION_POINTERS *ep, host_context_t &context)
{
#if HOST_CPU == CPU_X86
context.pc = ep->ContextRecord->Eip;
context.esp = ep->ContextRecord->Esp;
context.eax = ep->ContextRecord->Eax;
context.ecx = ep->ContextRecord->Ecx;
#elif HOST_CPU == CPU_X64
context.pc = ep->ContextRecord->Rip;
context.rsp = ep->ContextRecord->Rsp;
context.r9 = ep->ContextRecord->R9;
context.rcx = ep->ContextRecord->Rcx;
#endif
}
static void writeContext(EXCEPTION_POINTERS *ep, const host_context_t &context)
{
#if HOST_CPU == CPU_X86
ep->ContextRecord->Eip = context.pc;
ep->ContextRecord->Esp = context.esp;
ep->ContextRecord->Eax = context.eax;
ep->ContextRecord->Ecx = context.ecx;
#elif HOST_CPU == CPU_X64
ep->ContextRecord->Rip = context.pc;
ep->ContextRecord->Rsp = context.rsp;
ep->ContextRecord->R9 = context.r9;
ep->ContextRecord->Rcx = context.rcx;
#endif
}
LONG exceptionHandler(EXCEPTION_POINTERS *ep)
{
u32 dwCode = ep->ExceptionRecord->ExceptionCode;
if (dwCode != EXCEPTION_ACCESS_VIOLATION)
return EXCEPTION_CONTINUE_SEARCH;
EXCEPTION_RECORD* pExceptionRecord = ep->ExceptionRecord;
u8* address = (u8 *)pExceptionRecord->ExceptionInformation[1];
//printf("[EXC] During access to : 0x%X\n", address);
// code protection in RAM
if (bm_RamWriteAccess(address))
return EXCEPTION_CONTINUE_EXECUTION;
// texture protection in VRAM
if (VramLockedWrite(address))
return EXCEPTION_CONTINUE_EXECUTION;
// FPCB jump table protection
if (BM_LockedWrite(address))
return EXCEPTION_CONTINUE_EXECUTION;
host_context_t context;
readContext(ep, context);
#if FEAT_SHREC == DYNAREC_JIT
// fast mem access rewriting
if (ngen_Rewrite(context, address))
{
writeContext(ep, context);
return EXCEPTION_CONTINUE_EXECUTION;
}
#endif
ERROR_LOG(COMMON, "[GPF] PC %p unhandled access to %p", (void *)context.pc, address);
os_DebugBreak();
return EXCEPTION_CONTINUE_SEARCH;
}
#ifdef _WIN64
typedef union _UNWIND_CODE {
struct {
u8 CodeOffset;
u8 UnwindOp : 4;
u8 OpInfo : 4;
};
USHORT FrameOffset;
} UNWIND_CODE, *PUNWIND_CODE;
typedef struct _UNWIND_INFO {
u8 Version : 3;
u8 Flags : 5;
u8 SizeOfProlog;
u8 CountOfCodes;
u8 FrameRegister : 4;
u8 FrameOffset : 4;
//ULONG ExceptionHandler;
UNWIND_CODE UnwindCode[1];
/* UNWIND_CODE MoreUnwindCode[((CountOfCodes + 1) & ~1) - 1];
* union {
* OPTIONAL ULONG ExceptionHandler;
* OPTIONAL ULONG FunctionEntry;
* };
* OPTIONAL ULONG ExceptionData[]; */
} UNWIND_INFO, *PUNWIND_INFO;
static RUNTIME_FUNCTION Table[1];
static _UNWIND_INFO unwind_info[1];
PRUNTIME_FUNCTION
seh_callback(
_In_ DWORD64 ControlPc,
_In_opt_ PVOID Context
) {
unwind_info[0].Version = 1;
unwind_info[0].Flags = UNW_FLAG_UHANDLER;
/* We don't use the unwinding info so fill the structure with 0 values. */
unwind_info[0].SizeOfProlog = 0;
unwind_info[0].CountOfCodes = 0;
unwind_info[0].FrameOffset = 0;
unwind_info[0].FrameRegister = 0;
/* Add the exception handler. */
// unwind_info[0].ExceptionHandler =
// (DWORD)((u8 *)__gnat_SEH_error_handler - CodeCache);
/* Set its scope to the entire program. */
Table[0].BeginAddress = 0;// (CodeCache - (u8*)__ImageBase);
Table[0].EndAddress = /*(CodeCache - (u8*)__ImageBase) +*/ CODE_SIZE + TEMP_CODE_SIZE;
Table[0].UnwindData = (DWORD)((u8 *)unwind_info - CodeCache);
INFO_LOG(COMMON, "TABLE CALLBACK");
//for (;;);
return Table;
}
void setup_seh()
{
/* Get the base of the module. */
//u8* __ImageBase = (u8*)GetModuleHandle(NULL);
/* Current version is always 1 and we are registering an
exception handler. */
unwind_info[0].Version = 1;
unwind_info[0].Flags = UNW_FLAG_NHANDLER;
/* We don't use the unwinding info so fill the structure with 0 values. */
unwind_info[0].SizeOfProlog = 0;
unwind_info[0].CountOfCodes = 1;
unwind_info[0].FrameOffset = 0;
unwind_info[0].FrameRegister = 0;
/* Add the exception handler. */
unwind_info[0].UnwindCode[0].CodeOffset = 0;
unwind_info[0].UnwindCode[0].UnwindOp = 2;// UWOP_ALLOC_SMALL;
unwind_info[0].UnwindCode[0].OpInfo = 0x20 / 8;
//unwind_info[0].ExceptionHandler =
//(DWORD)((u8 *)__gnat_SEH_error_handler - CodeCache);
/* Set its scope to the entire program. */
Table[0].BeginAddress = 0;// (CodeCache - (u8*)__ImageBase);
Table[0].EndAddress = /*(CodeCache - (u8*)__ImageBase) +*/ CODE_SIZE + TEMP_CODE_SIZE;
Table[0].UnwindData = (DWORD)((u8 *)unwind_info - CodeCache);
/* Register the unwind information. */
RtlAddFunctionTable(Table, 1, (DWORD64)CodeCache);
//verify(RtlInstallFunctionTableCallback((unat)CodeCache | 0x3, (DWORD64)CodeCache, CODE_SIZE + TEMP_CODE_SIZE, seh_callback, 0, 0));
}
#endif
double os_GetSeconds()
{
static double qpfd = []() {
LARGE_INTEGER qpf;
QueryPerformanceFrequency(&qpf);
return 1.0 / qpf.QuadPart; }();
LARGE_INTEGER time_now;
QueryPerformanceCounter(&time_now);
static LARGE_INTEGER time_now_base = time_now;
return (time_now.QuadPart - time_now_base.QuadPart) * qpfd;
}

View File

@ -0,0 +1,20 @@
/*
This file is part of Flycast.
Flycast is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
Flycast is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Flycast. If not, see <https://www.gnu.org/licenses/>.
*/
#include <windows.h>
LONG exceptionHandler(EXCEPTION_POINTERS *ep);
void setup_seh();

View File

@ -1,10 +1,25 @@
/*
This file is part of Flycast.
Flycast is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
Flycast is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Flycast. If not, see <https://www.gnu.org/licenses/>.
*/
#include "oslib/oslib.h"
#include "oslib/audiostream.h"
#include "imgread/common.h"
#include "stdclass.h"
#include "cfg/cfg.h"
#include "win_keyboard.h"
#include "hw/sh4/dyna/blockmanager.h"
#include "log/LogManager.h"
#include "wsi/context.h"
#if defined(USE_SDL)
@ -15,10 +30,9 @@
#include "hw/maple/maple_devs.h"
#include "emulator.h"
#include "rend/mainui.h"
#include "hw/sh4/dyna/ngen.h"
#include "oslib/host_context.h"
#include "../shell/windows/resource.h"
#include "rawinput.h"
#include "fault_handler.h"
#include <windows.h>
#include <windowsx.h>
@ -117,9 +131,6 @@ static PCHAR*
return argv;
}
bool VramLockedWrite(u8* address);
bool BM_LockedWrite(u8* address);
#ifndef USE_SDL
static std::shared_ptr<WinMouse> mouse;
@ -186,74 +197,6 @@ void os_SetupInput()
rawinput::init();
}
static void readContext(const EXCEPTION_POINTERS *ep, host_context_t &context)
{
#if HOST_CPU == CPU_X86
context.pc = ep->ContextRecord->Eip;
context.esp = ep->ContextRecord->Esp;
context.eax = ep->ContextRecord->Eax;
context.ecx = ep->ContextRecord->Ecx;
#elif HOST_CPU == CPU_X64
context.pc = ep->ContextRecord->Rip;
context.rsp = ep->ContextRecord->Rsp;
context.r9 = ep->ContextRecord->R9;
context.rcx = ep->ContextRecord->Rcx;
#endif
}
static void writeContext(EXCEPTION_POINTERS *ep, const host_context_t &context)
{
#if HOST_CPU == CPU_X86
ep->ContextRecord->Eip = context.pc;
ep->ContextRecord->Esp = context.esp;
ep->ContextRecord->Eax = context.eax;
ep->ContextRecord->Ecx = context.ecx;
#elif HOST_CPU == CPU_X64
ep->ContextRecord->Rip = context.pc;
ep->ContextRecord->Rsp = context.rsp;
ep->ContextRecord->R9 = context.r9;
ep->ContextRecord->Rcx = context.rcx;
#endif
}
static LONG exceptionHandler(EXCEPTION_POINTERS *ep)
{
u32 dwCode = ep->ExceptionRecord->ExceptionCode;
if (dwCode != EXCEPTION_ACCESS_VIOLATION)
return EXCEPTION_CONTINUE_SEARCH;
EXCEPTION_RECORD* pExceptionRecord = ep->ExceptionRecord;
u8* address = (u8 *)pExceptionRecord->ExceptionInformation[1];
//printf("[EXC] During access to : 0x%X\n", address);
// code protection in RAM
if (bm_RamWriteAccess(address))
return EXCEPTION_CONTINUE_EXECUTION;
// texture protection in VRAM
if (VramLockedWrite(address))
return EXCEPTION_CONTINUE_EXECUTION;
// FPCB jump table protection
if (BM_LockedWrite(address))
return EXCEPTION_CONTINUE_EXECUTION;
host_context_t context;
readContext(ep, context);
#if FEAT_SHREC == DYNAREC_JIT
// fast mem access rewriting
if (ngen_Rewrite(context, address))
{
writeContext(ep, context);
return EXCEPTION_CONTINUE_EXECUTION;
}
#endif
ERROR_LOG(COMMON, "[GPF] PC %p unhandled access to %p", (void *)context.pc, address);
os_DebugBreak();
return EXCEPTION_CONTINUE_SEARCH;
}
static void setupPath()
{
@ -705,94 +648,6 @@ static void reserveBottomMemory()
OutputDebugStringA(buffer);
#endif
}
#ifdef _WIN64
typedef union _UNWIND_CODE {
struct {
u8 CodeOffset;
u8 UnwindOp : 4;
u8 OpInfo : 4;
};
USHORT FrameOffset;
} UNWIND_CODE, *PUNWIND_CODE;
typedef struct _UNWIND_INFO {
u8 Version : 3;
u8 Flags : 5;
u8 SizeOfProlog;
u8 CountOfCodes;
u8 FrameRegister : 4;
u8 FrameOffset : 4;
//ULONG ExceptionHandler;
UNWIND_CODE UnwindCode[1];
/* UNWIND_CODE MoreUnwindCode[((CountOfCodes + 1) & ~1) - 1];
* union {
* OPTIONAL ULONG ExceptionHandler;
* OPTIONAL ULONG FunctionEntry;
* };
* OPTIONAL ULONG ExceptionData[]; */
} UNWIND_INFO, *PUNWIND_INFO;
static RUNTIME_FUNCTION Table[1];
static _UNWIND_INFO unwind_info[1];
PRUNTIME_FUNCTION
seh_callback(
_In_ DWORD64 ControlPc,
_In_opt_ PVOID Context
) {
unwind_info[0].Version = 1;
unwind_info[0].Flags = UNW_FLAG_UHANDLER;
/* We don't use the unwinding info so fill the structure with 0 values. */
unwind_info[0].SizeOfProlog = 0;
unwind_info[0].CountOfCodes = 0;
unwind_info[0].FrameOffset = 0;
unwind_info[0].FrameRegister = 0;
/* Add the exception handler. */
// unwind_info[0].ExceptionHandler =
// (DWORD)((u8 *)__gnat_SEH_error_handler - CodeCache);
/* Set its scope to the entire program. */
Table[0].BeginAddress = 0;// (CodeCache - (u8*)__ImageBase);
Table[0].EndAddress = /*(CodeCache - (u8*)__ImageBase) +*/ CODE_SIZE + TEMP_CODE_SIZE;
Table[0].UnwindData = (DWORD)((u8 *)unwind_info - CodeCache);
INFO_LOG(COMMON, "TABLE CALLBACK");
//for (;;);
return Table;
}
static void setup_seh()
{
/* Get the base of the module. */
//u8* __ImageBase = (u8*)GetModuleHandle(NULL);
/* Current version is always 1 and we are registering an
exception handler. */
unwind_info[0].Version = 1;
unwind_info[0].Flags = UNW_FLAG_NHANDLER;
/* We don't use the unwinding info so fill the structure with 0 values. */
unwind_info[0].SizeOfProlog = 0;
unwind_info[0].CountOfCodes = 1;
unwind_info[0].FrameOffset = 0;
unwind_info[0].FrameRegister = 0;
/* Add the exception handler. */
unwind_info[0].UnwindCode[0].CodeOffset = 0;
unwind_info[0].UnwindCode[0].UnwindOp = 2;// UWOP_ALLOC_SMALL;
unwind_info[0].UnwindCode[0].OpInfo = 0x20 / 8;
//unwind_info[0].ExceptionHandler =
//(DWORD)((u8 *)__gnat_SEH_error_handler - CodeCache);
/* Set its scope to the entire program. */
Table[0].BeginAddress = 0;// (CodeCache - (u8*)__ImageBase);
Table[0].EndAddress = /*(CodeCache - (u8*)__ImageBase) +*/ CODE_SIZE + TEMP_CODE_SIZE;
Table[0].UnwindData = (DWORD)((u8 *)unwind_info - CodeCache);
/* Register the unwind information. */
RtlAddFunctionTable(Table, 1, (DWORD64)CodeCache);
//verify(RtlInstallFunctionTableCallback((unat)CodeCache | 0x3, (DWORD64)CodeCache, CODE_SIZE + TEMP_CODE_SIZE, seh_callback, 0, 0));
}
#endif
static void findKeyboardLayout()
{
HKL keyboardLayout = GetKeyboardLayout(0);
@ -885,21 +740,6 @@ int CALLBACK WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLi
return 0;
}
double os_GetSeconds()
{
static double qpfd = []() {
LARGE_INTEGER qpf;
QueryPerformanceFrequency(&qpf);
return 1.0 / qpf.QuadPart; }();
LARGE_INTEGER time_now;
QueryPerformanceCounter(&time_now);
static LARGE_INTEGER time_now_base = time_now;
return (time_now.QuadPart - time_now_base.QuadPart) * qpfd;
}
void os_DebugBreak()
{
__debugbreak();

View File

@ -18,6 +18,7 @@
You should have received a copy of the GNU General Public License
along with Flycast. If not, see <https://www.gnu.org/licenses/>.
*/
#ifndef LIBRETRO
#include "context.h"
#include "rend/gui.h"
#include "cfg/option.h"
@ -64,3 +65,4 @@ void TermRenderApi()
#endif
theGLContext.Term();
}
#endif

View File

@ -72,6 +72,9 @@ char* strdup(const char *str)
#include "rend/osd.h"
#include "cfg/option.h"
#include "wsi/gl_context.h"
#ifdef _WIN32
#include "windows/fault_handler.h"
#endif
constexpr char slash = path_default_slash_c();
@ -281,8 +284,13 @@ void retro_init()
if (!_vmem_reserve())
ERROR_LOG(VMEM, "Cannot reserve memory space");
#ifdef WIN32
#error TODO
#ifdef _WIN32
#ifdef _WIN64
AddVectoredExceptionHandler(1, exceptionHandler);
setup_seh();
#else
SetUnhandledExceptionFilter((LPTOP_LEVEL_EXCEPTION_FILTER)&exceptionHandler);
#endif
#else
void install_fault_handler();
install_fault_handler();
@ -776,9 +784,11 @@ void retro_run()
{
dc_run(nullptr);
}
// TODO Widescreen
int width = config::RenderResolution * 4 / 3;
if (config::Widescreen && !config::Rotate90)
width = width * 4 / 3;
#if defined(HAVE_OPENGL) || defined(HAVE_OPENGLES) || defined(HAVE_VULKAN)
video_cb(is_dupe ? 0 : RETRO_HW_FRAME_BUFFER_VALID, config::RenderResolution * 4 / 3, config::RenderResolution, 0);
video_cb(is_dupe ? 0 : RETRO_HW_FRAME_BUFFER_VALID, width, config::RenderResolution, 0);
#endif
if (!config::ThreadedRendering)
is_dupe = true;
@ -1255,8 +1265,10 @@ static void retro_vk_context_reset()
ERROR_LOG(RENDERER, "Get Vulkan HW interface failed");
return;
}
// TODO Widescreen
theVulkanContext.SetWindowSize(config::RenderResolution * 4 / 3, config::RenderResolution);
int width = config::RenderResolution * 4 / 3;
if (config::Widescreen && !config::Rotate90)
width = width * 4 / 3;
theVulkanContext.SetWindowSize(width, config::RenderResolution);
theVulkanContext.Init((retro_hw_render_interface_vulkan *)vulkan);
}
@ -1343,12 +1355,15 @@ static bool set_opengl_hw_render(u32 preferred)
params.context_type = (retro_hw_context_type)preferred;
params.major = 3;
params.minor = 0;
config::RendererType = RenderType::OpenGL;
}
#elif defined(HAVE_GL3)
params.context_type = (retro_hw_context_type)preferred;
params.major = 3;
params.minor = 0;
config::RendererType = RenderType::OpenGL;
#endif
config::RendererType.commit();
if (glsm_ctl(GLSM_CTL_STATE_CONTEXT_INIT, &params))
return true;
@ -1362,6 +1377,8 @@ static bool set_opengl_hw_render(u32 preferred)
params.major = 0;
params.minor = 0;
#endif
config::RendererType = RenderType::OpenGL;
config::RendererType.commit();
return glsm_ctl(GLSM_CTL_STATE_CONTEXT_INIT, &params);
#else
return false;

View File

@ -194,27 +194,6 @@ extern "C" {
},
struct retro_core_option_definition option_defs_us[] = {
#if ((FEAT_SHREC == DYNAREC_JIT && HOST_CPU == CPU_X86) || (HOST_CPU == CPU_ARM) || (HOST_CPU == CPU_ARM64) || (HOST_CPU == CPU_X64)) && defined(TARGET_NO_JIT)
{
CORE_OPTION_NAME "_cpu_mode",
"CPU Mode (Restart)",
"",
{
#if (FEAT_SHREC == DYNAREC_JIT && HOST_CPU == CPU_X86) || (HOST_CPU == CPU_ARM) || (HOST_CPU == CPU_ARM64) || (HOST_CPU == CPU_X64)
{ "dynamic_recompiler", "Dynamic Recompiler" },
#endif
#ifdef TARGET_NO_JIT
{ "generic_recompiler", "Generic Recompiler" },
#endif
{ NULL, NULL },
},
#if (FEAT_SHREC == DYNAREC_JIT && HOST_CPU == CPU_X86) || (HOST_CPU == CPU_ARM) || (HOST_CPU == CPU_ARM64) || (HOST_CPU == CPU_X64)
"dynamic_recompiler",
#elif defined(TARGET_NO_JIT)
"generic_recompiler",
#endif
},
#endif
{
CORE_OPTION_NAME "_boot_to_bios",
"Boot to BIOS (Restart)",
@ -226,19 +205,6 @@ struct retro_core_option_definition option_defs_us[] = {
},
"disabled",
},
{
CORE_OPTION_NAME "_system",
"System Type (Restart)",
"",
{
{ "auto", "Auto" },
{ "dreamcast", "Dreamcast" },
{ "naomi", "NAOMI" },
{ "atomiswave", "Atomiswave" },
{ NULL, NULL },
},
"auto",
},
{
CORE_OPTION_NAME "_hle_bios",
"HLE BIOS",

View File

@ -202,23 +202,6 @@ extern "C" {
},
struct retro_core_option_definition option_defs_tr[] = {
#if ((FEAT_SHREC == DYNAREC_JIT && HOST_CPU == CPU_X86) || (HOST_CPU == CPU_ARM) || (HOST_CPU == CPU_ARM64) || (HOST_CPU == CPU_X64)) && defined(TARGET_NO_JIT)
{
CORE_OPTION_NAME "_cpu_mode",
"CPU Modu (Yeniden Başlatma Gerektirir)",
"",
{
#if (FEAT_SHREC == DYNAREC_JIT && HOST_CPU == CPU_X86) || (HOST_CPU == CPU_ARM) || (HOST_CPU == CPU_ARM64) || (HOST_CPU == CPU_X64)
{ "dynamic_recompiler", "Dinamik Yeniden Derleyici" },
#endif
#ifdef TARGET_NO_JIT
{ "generic_recompiler", "Jenerik Yeniden Derleyici" },
#endif
{ NULL, NULL },
},
NULL,
},
#endif
{
CORE_OPTION_NAME "_boot_to_bios",
"BIOS'a önyükleme (Yeniden Başlatma Gerektirir)",
@ -228,19 +211,6 @@ struct retro_core_option_definition option_defs_tr[] = {
},
NULL,
},
{
CORE_OPTION_NAME "_system",
"Sistem Tipi (Yeniden Başlatma Gerektirir)",
"",
{
{ "auto", "Otomatik" },
{ "dreamcast", "Dreamcast" },
{ "naomi", "NAOMI" },
{ "atomiswave", "Atomiswave" },
{ NULL, NULL },
},
NULL,
},
{
CORE_OPTION_NAME "_hle_bios",
"HLE BIOS",
@ -313,6 +283,15 @@ struct retro_core_option_definition option_defs_tr[] = {
},
NULL,
},
{
CORE_OPTION_NAME "_fog",
"Fog Effects",
"",
{
{ NULL, NULL },
},
NULL,
},
{
CORE_OPTION_NAME "_volume_modifier_enable",
"Hacim Değiştirici",
@ -331,14 +310,20 @@ struct retro_core_option_definition option_defs_tr[] = {
},
NULL,
},
{
CORE_OPTION_NAME "_widescreen_cheats",
"Widescreen Cheats (Restart)",
"Activates cheats that allow certain games to display in widescreen format.",
{
{ NULL, NULL },
},
NULL,
},
{
CORE_OPTION_NAME "_cable_type",
"Kablo Tipi",
"",
{
{ "TV (RGB)", NULL },
{ "TV (Composite)", NULL },
{ "VGA (RGB)", NULL },
{ NULL, NULL },
},
NULL,
@ -348,11 +333,11 @@ struct retro_core_option_definition option_defs_tr[] = {
"Yayın",
"",
{
{ "Default", "Varsayılan" },
{ "PAL_M", "PAL-M (Brazil)" },
{ "PAL_N", "PAL-N (Argentina, Paraguay, Uruguay)" },
{ "NTSC", NULL },
{ "PAL", "PAL (World)" },
{ "PAL_N", "PAL-N (Argentina, Paraguay, Uruguay)" },
{ "PAL_M", "PAL-M (Brazil)" },
{ "Default", "Varsayılan" },
{ NULL, NULL },
},
NULL,
@ -362,8 +347,8 @@ struct retro_core_option_definition option_defs_tr[] = {
"Kare Hızı",
"Emülatörün ön uçla nasıl etkileşimde bulunduğunu etkiler. 'Tam Hız' - emülatör, bir kare oluşturulduğunda, kontrolü RetroArch'a geri döndürür. 'Normal' - emülatör, V-blank kesmesi her üretildiğinde kontrolü RetroArch'a döndürür. Çoğu durumda 'Tam Hız' kullanılmalıdır. 'Normal' bazı sistemlerde kare ilerleme hızını iyileştirebilir, ancak ekran statik olduğunda (örneğin, yükleme/duraklatma ekranları) yanıt vermeyen girişe neden olabilir.",
{
{ "fullspeed", "Tam Hız" },
{ "normal", "Normal" },
{ "fullspeed", "Tam Hız" },
{ NULL, NULL },
},
NULL,
@ -373,10 +358,10 @@ struct retro_core_option_definition option_defs_tr[] = {
"Bölge",
"",
{
{ "Default", "Varsayılan" },
{ "Japan", NULL },
{ "USA", NULL },
{ "Europe", NULL },
{ "Default", "Varsayılan" },
{ NULL, NULL },
},
NULL,
@ -386,13 +371,13 @@ struct retro_core_option_definition option_defs_tr[] = {
"Dil",
"",
{
{ "Default", "Varsayılan" },
{ "Japanese", NULL },
{ "English", NULL },
{ "German", NULL },
{ "French", NULL },
{ "Spanish", NULL },
{ "Italian", NULL },
{ "Default", "Varsayılan" },
{ NULL, NULL },
},
NULL,
@ -402,9 +387,8 @@ struct retro_core_option_definition option_defs_tr[] = {
"DIV Eşleştirme (performans, daha az doğru)",
"",
{
{ "disabled", NULL },
{ "enabled", NULL },
{ "auto", "Otomatik" },
{ "disabled", NULL },
{ NULL, NULL },
},
NULL,
@ -456,6 +440,24 @@ struct retro_core_option_definition option_defs_tr[] = {
},
NULL,
},
{
CORE_OPTION_NAME "_anisotropic_filtering",
"Anisotropic Filtering",
"Enhance the quality of textures on surfaces that are at oblique viewing angles with respect to the camera.",
{
{ NULL, NULL },
},
NULL,
},
{
CORE_OPTION_NAME "_pvr2_filtering",
"PowerVR2 Post-processing Filter",
"Post-process the rendered image to simulate effects specific to the PowerVR2 GPU and analog video signals.",
{
{ NULL, NULL },
},
NULL,
},
#ifdef HAVE_TEXUPSCALE
{
CORE_OPTION_NAME "_texupscale",
@ -508,9 +510,18 @@ struct retro_core_option_definition option_defs_tr[] = {
NULL,
},
{
CORE_OPTION_NAME "_synchronous_rendering",
"Senkronize İşleme",
"",
CORE_OPTION_NAME "_auto_skip_frame",
"Auto Skip Frame",
"Automatically skip frames when the emulator is running slow. Note: This setting only applies when 'Threaded Rendering' is enabled.",
{
{ NULL, NULL },
},
NULL
},
{
CORE_OPTION_NAME "_delay_frame_swapping",
"Delay Frame Swapping",
"Useful to avoid flashing screens or glitchy videos. Not recommended on slow platforms. Note: This setting only applies when 'Threaded Rendering' is enabled.",
{
{ NULL, NULL },
},