diff --git a/.github/workflows/c-cpp.yml b/.github/workflows/c-cpp.yml
index 739b8aa62..8c4a7fbf5 100644
--- a/.github/workflows/c-cpp.yml
+++ b/.github/workflows/c-cpp.yml
@@ -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
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 725282e62..a1f5c8cef 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -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()
diff --git a/core/hw/pvr/Renderer_if.cpp b/core/hw/pvr/Renderer_if.cpp
index b08367c03..d8715a081 100644
--- a/core/hw/pvr/Renderer_if.cpp
+++ b/core/hw/pvr/Renderer_if.cpp
@@ -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;
diff --git a/core/rend/dx9/d3d_overlay.cpp b/core/rend/dx9/d3d_overlay.cpp
index 71a912b54..d68001539 100644
--- a/core/rend/dx9/d3d_overlay.cpp
+++ b/core/rend/dx9/d3d_overlay.cpp
@@ -17,6 +17,7 @@
along with Flycast. If not, see .
*/
#include "d3d_overlay.h"
+#include "rend/osd.h"
#include "rend/gui.h"
#include
#include
diff --git a/core/rend/gles/gles.cpp b/core/rend/gles/gles.cpp
index 19a32be7e..790c1ff75 100644
--- a/core/rend/gles/gles.cpp
+++ b/core/rend/gles/gles.cpp
@@ -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);
diff --git a/core/windows/fault_handler.cpp b/core/windows/fault_handler.cpp
new file mode 100644
index 000000000..7991d0af8
--- /dev/null
+++ b/core/windows/fault_handler.cpp
@@ -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 .
+*/
+#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;
+}
diff --git a/core/windows/fault_handler.h b/core/windows/fault_handler.h
new file mode 100644
index 000000000..f3be4ae17
--- /dev/null
+++ b/core/windows/fault_handler.h
@@ -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 .
+*/
+#include
+
+LONG exceptionHandler(EXCEPTION_POINTERS *ep);
+void setup_seh();
diff --git a/core/windows/winmain.cpp b/core/windows/winmain.cpp
index 9d0bad075..de76e40da 100644
--- a/core/windows/winmain.cpp
+++ b/core/windows/winmain.cpp
@@ -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 .
+*/
#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
#include
@@ -117,9 +131,6 @@ static PCHAR*
return argv;
}
-bool VramLockedWrite(u8* address);
-bool BM_LockedWrite(u8* address);
-
#ifndef USE_SDL
static std::shared_ptr 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();
diff --git a/core/wsi/switcher.cpp b/core/wsi/switcher.cpp
index 8f72ce68e..985b651b4 100644
--- a/core/wsi/switcher.cpp
+++ b/core/wsi/switcher.cpp
@@ -18,6 +18,7 @@
You should have received a copy of the GNU General Public License
along with Flycast. If not, see .
*/
+#ifndef LIBRETRO
#include "context.h"
#include "rend/gui.h"
#include "cfg/option.h"
@@ -64,3 +65,4 @@ void TermRenderApi()
#endif
theGLContext.Term();
}
+#endif
diff --git a/shell/libretro/libretro.cpp b/shell/libretro/libretro.cpp
index 0daf12074..557cd5cd1 100644
--- a/shell/libretro/libretro.cpp
+++ b/shell/libretro/libretro.cpp
@@ -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, ¶ms))
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, ¶ms);
#else
return false;
diff --git a/shell/libretro/libretro_core_options.h b/shell/libretro/libretro_core_options.h
index 82e3fa5fb..a552e1788 100644
--- a/shell/libretro/libretro_core_options.h
+++ b/shell/libretro/libretro_core_options.h
@@ -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",
diff --git a/shell/libretro/libretro_core_options_intl.h b/shell/libretro/libretro_core_options_intl.h
index cb9813a77..01809107c 100644
--- a/shell/libretro/libretro_core_options_intl.h
+++ b/shell/libretro/libretro_core_options_intl.h
@@ -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 },
},