libretro: win32 support. build fix.
This commit is contained in:
parent
68f4c50bd3
commit
a3b66aec1f
|
@ -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
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -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();
|
|
@ -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();
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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 },
|
||||
},
|
||||
|
|
Loading…
Reference in New Issue