diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 000000000..80342e0d2 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,311 @@ +cmake_minimum_required(VERSION 3.5.0 FATAL_ERROR) + +set(TNAME reicast) + +project(${TNAME}) + +enable_language(ASM) + +set(DEBUG_CMAKE ON) + +set(CMAKE_VERBOSE_MAKEFILE ON) +set(CMAKE_INCLUDE_CURRENT_DIR ON) + + +set(reicast_root_path "${CMAKE_CURRENT_SOURCE_DIR}") +set(reicast_core_path "${reicast_root_path}/core") +set(reicast_shell_path "${reicast_root_path}/shell") + +list(APPEND CMAKE_MODULE_PATH "${reicast_shell_path}/cmake") + + +include(GetGitRevisionDescription) +git_describe(GIT_VERSION --tags) +configure_file(${reicast_core_path}/version.h.in ${reicast_core_path}/version.h @ONLY) + + + + +## reicast build modules # +# + +set(reicast_SRCS "") + +include(config) # configure build settings, must be first + + + +### libdreamcast.cmake ######################################################################### + +set(d_core ${reicast_core_path}) + +file(GLOB_RECURSE hw_SRCS ${d_core}/hw/*.cpp ${d_core}/hw/*.h) + +file(GLOB cfg_SRCS ${d_core}/cfg/*.cpp ${d_core}/cfg/*.h) +file(GLOB rend_SRCS ${d_core}/rend/*.cpp ${d_core}/rend/*.h) +file(GLOB input_SRCS ${d_core}/input/*.cpp ${d_core}/input/*.h) +file(GLOB reios_SRCS ${d_core}/reios/*.cpp ${d_core}/reios/*.h) +file(GLOB imgread_SRCS ${d_core}/imgread/*.cpp ${d_core}/imgread/*.h) +file(GLOB profiler_SRCS ${d_core}/profiler/*.cpp ${d_core}/profiler/*.h) +file(GLOB archive_SRCS ${d_core}/archive/*.cpp ${d_core}/archive/*.h) + +#### option(rend) +file(GLOB gl4_SRCS ${d_core}/rend/gl4/*.cpp ${d_core}/rend/gl4/*.h) +file(GLOB gles_SRCS ${d_core}/rend/gles/*.cpp ${d_core}/rend/gles/*.h) + +set(core_SRCS + ${hw_SRCS} + ${cfg_SRCS} + ${rend_SRCS} + ${gl4_SRCS} + ${gles_SRCS} + ${input_SRCS} + ${reios_SRCS} + ${imgread_SRCS} + ${profiler_SRCS} + ${d_core}/archive/archive.cpp ${d_core}/archive/archive.h + ${d_core}/nullDC.cpp + ${d_core}/stdclass.cpp + ${d_core}/dispframe.cpp + ${d_core}/serialize.cpp +) + + +if(${BUILD_COMPILER} EQUAL ${COMPILER_GCC}) # Add Clang if NOT WIN32 *FIXME* + list(APPEND core_SRCS ${archive_SRCS}) +endif() + +if(${FEAT_SHREC} EQUAL ${DYNAREC_JIT}) +# + if(${HOST_CPU} EQUAL ${CPU_X86}) + list(APPEND core_SRCS + ${d_core}/rec-x86/rec_x86_driver.cpp + ${d_core}/rec-x86/rec_x86_il.cpp + ${d_core}/rec-x86/rec_x86_asm.cpp # change for linux , rec_lin86_asm.S + ${d_core}/rec-x86/rec_x86_ngen.h + ) + elseif(${HOST_CPU} EQUAL ${CPU_ARM}) + list(APPEND core_SRCS + ${d_core}/rec-ARM/ngen_arm.S + ${d_core}/rec-ARM/rec_arm.cpp + ) + elseif(${HOST_CPU} EQUAL ${CPU_X64}) + + ### FIXME: asm with cmake ninja+VC + if(${BUILD_COMPILER} EQUAL ${COMPILER_VC}) + list(APPEND core_SRCS ${d_core}/rec-x64/msvc.asm) + endif() + + list(APPEND core_SRCS ${d_core}/rec-x64/rec_x64.cpp ${d_core}/rec-x64/x64_regalloc.h) + + elseif(${HOST_CPU} EQUAL ${CPU_A64}) + list(APPEND core_SRCS ${d_core}/rec-ARM64/rec_arm64.cpp ${d_core}/rec-ARM64/arm64_regalloc.h) + + else() + message(" FEAT_SHREC==DYNAREC_JIT && HOST_CPU Unknown Default add arch or disable rec if not avail.") + error() + endif() +# +elseif(${FEAT_SHREC} EQUAL ${DYNAREC_CPP}) + list(APPEND core_SRCS ${d_core}/rec-cpp/rec_cpp.cpp) +endif() + +add_definitions(/DFEAT_HAS_SOFTREND=0) + + +### deps.cmake ################################################################################# + +set(d_deps ${reicast_core_path}/deps) +include_directories ("${d_deps}") +include_directories ("${d_deps}/picotcp/include") +include_directories ("${d_deps}/picotcp/modules") + +file(GLOB xbyak_H ${d_deps}/xbyak/*.h) # include headers into cmake target/project view + +file(GLOB chdr_SRCS ${d_deps}/chdr/*.c) +file(GLOB lzma_SRCS ${d_deps}/lzma/*.c) +file(GLOB lz_SRCS ${d_deps}/zlib/*.c) +file(GLOB lzip_SRCS ${d_deps}/libzip/*.c) +file(GLOB lpng_SRCS ${d_deps}/libpng/*.c) +file(GLOB lelf_SRCS ${d_deps}/libelf/el*.cpp) +file(GLOB crypt_SRCS ${d_deps}/crypto/*.cpp) +file(GLOB imgui_SRCS ${d_deps}/imgui/*.cpp) +file(GLOB lws_SRCS ${d_deps}/libwebsocket/*.c) + +file(GLOB picoModS ${d_deps}/picotcp/modules/*.c) +file(GLOB picoStkS ${d_deps}/picotcp/stack/*.c) +set(pico_SRCS ${picoModS} ${picoStkS}) + +set(deps_SRCS + ${lz_SRCS} + ${lpng_SRCS} + ${lelf_SRCS} + ${chdr_SRCS} + ${crypt_SRCS} + ${imgui_SRCS} + ${d_deps}/xbrz/xbrz.cpp + ${d_deps}/dirent/dirent.c + ${d_deps}/xxhash/xxhash.c + ${d_deps}/chdpsr/cdipsr.cpp # sigh, this dir is named chdpsr for some reason ... + ${d_deps}/coreio/coreio.cpp +# ${d_deps}/ifaddrs/ifaddrs.c + ${xbyak_H} +) + +if(${BUILD_COMPILER} EQUAL ${COMPILER_GCC}) # Add Clang if NOT WIN32 *FIXME* + list(APPEND deps_SRCS + ${lzip_SRCS} + ${lzma_SRCS} + ${pico_SRCS} + ) + add_definitions(-D_7ZIP_ST -DCHD5_LZMA) +endif() + +### libosd.cmake ################################################################################ + + +set(d_aout ${reicast_core_path}/oslib) + +include_directories ("${d_core}/khronos") + +## I really should just glob all of the dirs and ;shrug; if guards don't do it all ## + +set(osd_SRCS "") + +list(APPEND osd_SRCS ${d_aout}/audiostream.cpp) + +if (${HOST_OS} EQUAL ${OS_WINDOWS}) + + list(APPEND osd_SRCS ${d_core}/windows/winmain.cpp) + list(APPEND osd_SRCS ${d_aout}/audiobackend_directsound.cpp) + + + link_libraries(dsound.lib winmm.lib xinput.lib wsock32.lib opengl32.lib) + + +elseif (${HOST_OS} EQUAL ${OS_LINUX} OR ${HOST_OS} EQUAL ${OS_ANDROID}) + + list(APPEND osd_SRCS + ${d_core}/linux/common.cpp + ${d_core}/linux/context.cpp + ${d_core}/linux/nixprof/nixprof.cpp + + ${d_aout}/audiobackend_oss.cpp # add option + ) # todo: configure linux audio lib options + + if(NOT ANDROID) + list(APPEND osd_SRCS + ${d_core}/linux-dist/x11.cpp + ${d_core}/linux-dist/main.cpp + ${d_core}/linux-dist/evdev.cpp) + + add_definitions(-DSUPPORT_X11) ## don't use GLES ? + link_libraries(X11) + else() + list(APPEND osd_SRCS + .//android-studio/reicast/src/main/jni/src/Android.cpp + .//android-studio/reicast/src/main/jni/src/utils.cpp + # .//android-studio/reicast/src/main/jni/src/XperiaPlay.c + ) + endif() # ANDROID + + add_definitions(-DGLES -DUSE_EVDEV) + + link_libraries(pthread dl rt asound Xext GLESv2 EGL) + +elseif(${HOST_OS} EQUAL ${OS_DARWIN}) +# + list(APPEND objc_SRCS + ./shell/apple/emulator-osx/emulator-osx/osx-main.mm + ./shell/apple/emulator-osx/emulator-osx/AppDelegate.swift + ./shell/apple/emulator-osx/emulator-osx/EmuGLView.swift + ) + + set_source_files_properties(${objc_SRCS} PROPERTIES COMPILE_FLAGS "-x objective-c++") + + list(APPEND osd_SRCS ${objc_SRCS} + ${d_osd}/linux/common.cpp + ${d_osd}/linux/context.cpp + ${d_osd}/audiobackend/audiobackend_coreaudio.cpp + # if NOT USE_SWIFT / ObjC + #${d_osd}/apple/osx_osd.cpp + ) + +else() +# + message("OS Unhandled") + error() +# +endif() + + + +## + +include_directories ("${reicast_core_path}") + + + + +set(reicast_SRCS ${core_SRCS} ${deps_SRCS} ${osd_SRCS}) + +add_executable(${TNAME}${binSuffix} ${reicast_SRCS} ${deps_SRCS}) + + + + + +if(APPLE) + enable_language(Swift) + set_property(TARGET ${TNAME} PROPERTY XCODE_ATTRIBUTE_SWIFT_OBJC_BRIDGING_HEADER "./shell/apple/emulator-osx/emulator-osx/emulator-osx-Bridging-Header.h") + + target_link_libraries(${TNAME} +# "-framework Cocoa" +# "-framework AppKit" + "-framework CoreData" + "-framework CoreAudio" + "-framework AudioUnit" + "-framework AudioToolbox" + "-framework Foundation" +) + +#### OSX Notes, when not using xcode you have to make app bundle, edit plist and copy, convert MainMenu.xib to nib and copy, +#null@devpc:~$ /Users/null/Documents/projects/reicast-emulator/bin/RelWithDebInfo/Reicast.app/Contents/MacOS/reicast ; exit; +#2019-03-18 14:28:44.842 reicast[11468:131797] Unknown class _TtC12emulator_osx9EmuGLView in Interface Builder file at path /Users/null/Documents/projects/reicast-emulator/bin/RelWithDebInfo/Reicast.app/Contents/Resources/MainMenu.nib. +#2019-03-18 14:28:44.842 reicast[11468:131797] Unknown class _TtC12emulator_osx11AppDelegate in Interface Builder file at path /Users/null/Documents/projects/reicast-emulator/bin/RelWithDebInfo/Reicast.app/Contents/Resources/MainMenu.nib. +#2019-03-18 14:28:44.860 reicast[11468:131797] Failed to connect (window) outlet from (NSObject) to (NSWindow): missing setter or instance variable +# + +endif() #APPLE + + +if(DEBUG_CMAKE) + message(" ------------------------------------------------") + message(" - HOST_OS: ${HOST_OS} - HOST_CPU: ${HOST_CPU} ") + message(" - host_os: ${host_os} - host_arch: ${host_arch} ") + message(" ------------------------------------------------") + message(" C Flags: ${CMAKE_C_FLAGS} ") + message(" CXX Flags: ${CMAKE_CXX_FLAGS} ") + message(" LINK_DIRS: ${LINK_DIRECTORIES}") + message("LINK_FLAGS: ${CMAKE_EXE_LINKER_FLAGS}") + message(" ------------------------------------------------\n") +endif() + + + + + + + + + + + + + + + + + + + diff --git a/CMakeSettings.json b/CMakeSettings.json new file mode 100644 index 000000000..7fbe9b101 --- /dev/null +++ b/CMakeSettings.json @@ -0,0 +1,220 @@ +{ + "environments": [ + { + "environment": "toolchain.generic", + "TOOLCHAIN_FILE": "ps4sdk.cmake" + } + ], + "configurations": [ + { + "name": "win-x86-Debug", + "generator": "Ninja", + "description": "TemplateDescription_Localize_x86Debug", + "configurationType": "Debug", + "inheritEnvironments": [ + "msvc_x86" + ], + "buildRoot": "${projectDir}\\build\\${name}", + "installRoot": "${projectDir}\\build\\${name}\\install", + "cmakeCommandArgs": "", + "buildCommandArgs": "-v", + "ctestCommandArgs": "" + }, + { + "name": "win-x86-Release", + "generator": "Ninja", + "description": "TemplateDescription_Localize_x86Release", + "configurationType": "RelWithDebInfo", + "inheritEnvironments": [ + "msvc_x86" + ], + "buildRoot": "${projectDir}\\build\\${name}", + "installRoot": "${projectDir}\\build\\${name}\\install", + "cmakeCommandArgs": "", + "buildCommandArgs": "-v", + "ctestCommandArgs": "" + }, + { + "name": "win-x64-Debug", + "generator": "Ninja", + "description": "TemplateDescription_Localize_x64Debug", + "configurationType": "Debug", + "inheritEnvironments": [ + "msvc_x64_x64" + ], + "buildRoot": "${projectDir}\\build\\${name}", + "installRoot": "${projectDir}\\build\\${name}\\install", + "cmakeCommandArgs": "-DNINJA=1", + "buildCommandArgs": "-v", + "ctestCommandArgs": "" + }, + { + "name": "win-x64-Release", + "generator": "Ninja", + "description": "TemplateDescription_Localize_x64Release", + "configurationType": "RelWithDebInfo", + "inheritEnvironments": [ + "msvc_x64_x64" + ], + "buildRoot": "${projectDir}\\build\\${name}", + "installRoot": "${projectDir}\\build\\${name}\\install", + "cmakeCommandArgs": "-DNINJA=1", + "buildCommandArgs": "-v", + "ctestCommandArgs": "" + }, + { + "name": "win-x64-Clang-RelWithDebInfo", + "generator": "Ninja", + "description": "TemplateDescription_Localize_x64Release", + "configurationType": "RelWithDebInfo", + "inheritEnvironments": [ + "msvc_x64_x64" + ], + "buildRoot": "${projectDir}\\build\\${name}", + "installRoot": "${projectDir}\\build\\${name}\\install", + "cmakeCommandArgs": "", + "buildCommandArgs": "-v", + "ctestCommandArgs": "", + "variables": [ + { + "name": "CMAKE_C_COMPILER", + "value": "clang-cl.exe" + }, + { + "name": "CMAKE_CXX_COMPILER", + "value": "clang-cl.exe" + } + ] + }, + + // Console SDK's + { + "name": "PS4 SDK", + "generator": "Ninja", + "description": "TemplateDescription_Localize_PS4SDK", + "configurationType": "RelWithDebInfo", + "inheritEnvironments": [ + "toolchain.generic" + ], + "buildRoot": "${projectDir}\\build\\${name}", + "installRoot": "${projectDir}\\build\\${name}\\install", + "cmakeCommandArgs": "-DCMAKE_TOOLCHAIN_FILE=${projectDir}\\cmake\\ps4sdk.cmake", + "buildCommandArgs": "-v", + "ctestCommandArgs": "" + }, + { + "name": "NSW SDK", + "generator": "Ninja", + "description": "TemplateDescription_Localize_PS4SDK", + "configurationType": "RelWithDebInfo", + "inheritEnvironments": [ + "toolchain.generic" + ], + "buildRoot": "${projectDir}\\build\\${name}", + "installRoot": "${projectDir}\\build\\${name}\\install", + "cmakeCommandArgs": "-DCMAKE_TOOLCHAIN_FILE=${projectDir}\\cmake\\devkitA64.cmake", + "buildCommandArgs": "-v", + "ctestCommandArgs": "" + }, + + // UWP and VS Gen (temp?) + { + "name": "uwp-x64-Release", + "generator": "Visual Studio 15 2017 Win64", + "description": "TemplateDescription_Localize_x64Release", + "configurationType": "RelWithDebInfo", + "inheritEnvironments": [ + "msvc_x64_x64" + ], + "buildRoot": "${projectDir}\\build\\${name}", + "installRoot": "${projectDir}\\build\\${name}\\install", + "cmakeCommandArgs": "-DCMAKE_SYSTEM_NAME=WindowsStore -DCMAKE_SYSTEM_VERSION=10", + "buildCommandArgs": "", + "ctestCommandArgs": "" + }, + { + "name": "win-x64-MSBuild-Release", + "generator": "Visual Studio 15 2017 Win64", + "description": "TemplateDescription_Localize_x64Release", + "configurationType": "RelWithDebInfo", + "inheritEnvironments": [ + "msvc_x64_x64" + ], + "buildRoot": "${projectDir}\\build\\${name}", + "installRoot": "${projectDir}\\build\\${name}\\install", + "cmakeCommandArgs": "", + "buildCommandArgs": "", + "ctestCommandArgs": "" + }, + { + "environments": [ + { + //"MINGW64_ROOT": "C:\\msys64\\mingw64", + "BIN_ROOT": "${env.MINGW64_ROOT}\\bin", + "FLAVOR": "x86_64-w64-mingw32", + "TOOLSET_VERSION": "7.3.0", + "PATH": "${env.MINGW64_ROOT}\\bin;${env.MINGW64_ROOT}\\..\\usr\\local\\bin;${env.MINGW64_ROOT}\\..\\usr\\bin;${env.MINGW64_ROOT}\\..\\bin;${env.PATH}", + "INCLUDE": "${env.INCLUDE};${env.MINGW64_ROOT}\\include\\c++\\${env.TOOLSET_VERSION};${env.MINGW64_ROOT}\\include\\c++\\${env.TOOLSET_VERSION}\\tr1;${env.MINGW64_ROOT}\\include\\c++\\${env.TOOLSET_VERSION}\\${env.FLAVOR}", + "environment": "mingw_64" + } + ], + "name": "Mingw64-Release", + "generator": "Ninja", + "configurationType": "RelWithDebInfo", + "inheritEnvironments": [ + "mingw_64" + ], + "buildRoot": "${projectDir}\\build\\${name}", + "installRoot": "${projectDir}\\build\\${name}\\install", + "cmakeCommandArgs": "", + "buildCommandArgs": "-v", + "ctestCommandArgs": "", + "intelliSenseMode": "linux-gcc-x64", + "variables": [ + { + "name": "CMAKE_C_COMPILER", + "value": "${env.BIN_ROOT}\\gcc.exe" + }, + { + "name": "CMAKE_CXX_COMPILER", + "value": "${env.BIN_ROOT}\\g++.exe" + } + ] + }, + { + "environments": [ + { + //"MINGW64_ROOT": "C:\\msys64\\mingw64", + "BIN_ROOT": "${env.MINGW64_ROOT}\\bin", + "FLAVOR": "x86_64-w64-mingw32", + "TOOLSET_VERSION": "7.3.0", + "PATH": "${env.MINGW64_ROOT}\\bin;${env.MINGW64_ROOT}\\..\\usr\\local\\bin;${env.MINGW64_ROOT}\\..\\usr\\bin;${env.MINGW64_ROOT}\\..\\bin;${env.PATH}", + "INCLUDE": "${env.INCLUDE};${env.MINGW64_ROOT}\\include\\c++\\${env.TOOLSET_VERSION};${env.MINGW64_ROOT}\\include\\c++\\${env.TOOLSET_VERSION}\\tr1;${env.MINGW64_ROOT}\\include\\c++\\${env.TOOLSET_VERSION}\\${env.FLAVOR}", + "environment": "mingw_64" + } + ], + "name": "Mingw64-Debug", + "generator": "Ninja", + "configurationType": "Debug", + "inheritEnvironments": [ + "mingw_64" + ], + "buildRoot": "${projectDir}\\build\\${name}", + "installRoot": "${projectDir}\\build\\${name}\\install", + "cmakeCommandArgs": "", + "buildCommandArgs": "-v", + "ctestCommandArgs": "", + "intelliSenseMode": "linux-gcc-x64", + "variables": [ + { + "name": "CMAKE_C_COMPILER", + "value": "${env.BIN_ROOT}\\gcc.exe" + }, + { + "name": "CMAKE_CXX_COMPILER", + "value": "${env.BIN_ROOT}\\g++.exe" + } + ] + } + ] +} \ No newline at end of file diff --git a/core/.gitignore b/core/.gitignore new file mode 100644 index 000000000..a948ed453 --- /dev/null +++ b/core/.gitignore @@ -0,0 +1 @@ +/version.h diff --git a/core/archive/archive.cpp b/core/archive/archive.cpp index 904839a5f..1bef0f2a4 100644 --- a/core/archive/archive.cpp +++ b/core/archive/archive.cpp @@ -21,12 +21,15 @@ #include "archive.h" #include "7zArchive.h" +#ifndef _MSC_VER #include "ZipArchive.h" +#endif Archive *OpenArchive(const char *path) { std::string base_path(path); +#ifndef _MSC_VER Archive *sz_archive = new SzArchive(); if (sz_archive->Open(base_path.c_str()) || sz_archive->Open((base_path + ".7z").c_str()) || sz_archive->Open((base_path + ".7Z").c_str())) return sz_archive; @@ -36,6 +39,7 @@ Archive *OpenArchive(const char *path) if (zip_archive->Open(base_path.c_str()) || zip_archive->Open((base_path + ".zip").c_str()) || zip_archive->Open((base_path + ".ZIP").c_str())) return zip_archive; delete zip_archive; +#endif return NULL; } diff --git a/core/build.h b/core/build.h index a9a9777dd..57a00a46c 100755 --- a/core/build.h +++ b/core/build.h @@ -127,10 +127,18 @@ #define DC_PLATFORM_AURORA 6 /* Needs to be done, Uses newer 300 mhz sh4 + 150 mhz pvr mbx SoC */ + //HOST_OS #define OS_WINDOWS 0x10000001 #define OS_LINUX 0x10000002 #define OS_DARWIN 0x10000003 +#define OS_IOS 0x10000004 +#define OS_ANDROID 0x10000005 + +#define OS_UWP 0x10000011 +#define OS_NSW_HOS 0x80000001 +#define OS_PS4_BSD 0x80000002 + //HOST_CPU #define CPU_X86 0x20000001 @@ -138,11 +146,16 @@ #define CPU_MIPS 0x20000003 #define CPU_X64 0x20000004 #define CPU_GENERIC 0x20000005 //used for pnacl, emscripten, etc -#define CPU_ARM64 0x20000006 +#define CPU_PPC 0x20000006 +#define CPU_PPC64 0x20000007 +#define CPU_A64 0x20000008 +#define CPU_MIPS64 0x20000009 //BUILD_COMPILER -#define COMPILER_VC 0x30000001 -#define COMPILER_GCC 0x30000002 +#define COMPILER_VC 0x30000001 +#define COMPILER_GCC 0x30000002 +#define COMPILER_CLANG 0x30000003 +#define COMPILER_INTEL 0x30000004 //FEAT_SHREC, FEAT_AREC, FEAT_DSPREC #define DYNAREC_NONE 0x40000001 @@ -152,6 +165,8 @@ //automatic +#ifndef CMAKE_BUILD + #if defined(_WIN32) && !defined(TARGET_WIN86) && !defined(TARGET_WIN64) #if !defined(_M_AMD64) && !defined(__x86_64__) #define TARGET_WIN86 @@ -233,6 +248,8 @@ #define FEAT_DSPREC DYNAREC_NONE #endif +#endif // !CMAKE_BUILD + #if defined(TARGET_NO_NIXPROF) #define FEAT_HAS_NIXPROF 0 @@ -295,6 +312,21 @@ #error Dont use HOST_NO_AREC #endif + +// Compiler Related + +#define COMPILER_VC_OR_CLANG_WIN32 ((BUILD_COMPILER == COMPILER_VC) || (BUILD_COMPILER == COMPILER_CLANG) && defined(WIN32)) + +#if BUILD_COMPILER!=COMPILER_VC +#define ATTR_USED __attribute__((used)) +#define ATTR_UNUSED __attribute__((used)) +#else +#define ATTR_USED +#define ATTR_UNUSED +#endif + + + // TARGET PLATFORM #define RAM_SIZE_MAX (32*1024*1024) diff --git a/core/core.mk b/core/core.mk index cad01b997..4573ba5e7 100755 --- a/core/core.mk +++ b/core/core.mk @@ -5,22 +5,13 @@ #LDFLAGS := -Wl,-Map,$(notdir $@).map,--gc-sections -Wl,-O3 -Wl,--sort-common RZDCY_SRC_DIR ?= $(call my-dir) -VERSION_SRC := $(RZDCY_SRC_DIR)/version/version.cpp +VERSION_HEADER := $(RZDCY_SRC_DIR)/version.h -RZDCY_MODULES := cfg/ hw/arm7/ hw/aica/ hw/holly/ hw/ hw/gdrom/ hw/maple/ hw/modem/ \ +RZDCY_MODULES := cfg/ hw/arm7/ hw/aica/ hw/holly/ hw/ hw/gdrom/ hw/maple/ \ hw/mem/ hw/pvr/ hw/sh4/ hw/sh4/interpr/ hw/sh4/modules/ plugins/ profiler/ oslib/ \ hw/extdev/ hw/arm/ hw/naomi/ imgread/ ./ deps/coreio/ deps/zlib/ deps/chdr/ deps/crypto/ \ deps/libelf/ deps/chdpsr/ arm_emitter/ rend/ reios/ deps/libpng/ deps/xbrz/ \ - deps/picotcp/modules/ deps/picotcp/stack/ deps/xxhash/ deps/libzip/ deps/imgui/ \ - archive/ input/ - -ifdef CHD5_LZMA - RZDCY_MODULES += deps/lzma/ -endif - -ifdef CHD5_FLAC - RZDCY_MODULES += deps/flac/src/libFLAC/ -endif + deps/xxhash/ deps/libzip/ deps/imgui/ archive/ input/ ifdef WEBUI RZDCY_MODULES += webui/ @@ -31,10 +22,6 @@ ifdef WEBUI endif endif -ifndef NO_REC - RZDCY_MODULES += hw/sh4/dyna/ -endif - ifndef NOT_ARM RZDCY_MODULES += rec-ARM/ endif @@ -66,10 +53,6 @@ else RZDCY_MODULES += rend/norend/ endif -ifdef HAS_SOFTREND - RZDCY_MODULES += rend/soft/ -endif - ifndef NO_NIXPROF RZDCY_MODULES += linux/nixprof/ endif @@ -90,12 +73,6 @@ ifdef FOR_WINDOWS RZDCY_MODULES += windows/ endif -RZDCY_FILES := $(foreach dir,$(addprefix $(RZDCY_SRC_DIR)/,$(RZDCY_MODULES)),$(wildcard $(dir)*.cpp)) -RZDCY_FILES += $(foreach dir,$(addprefix $(RZDCY_SRC_DIR)/,$(RZDCY_MODULES)),$(wildcard $(dir)*.cc)) -RZDCY_FILES += $(foreach dir,$(addprefix $(RZDCY_SRC_DIR)/,$(RZDCY_MODULES)),$(wildcard $(dir)*.c)) -RZDCY_FILES += $(foreach dir,$(addprefix $(RZDCY_SRC_DIR)/,$(RZDCY_MODULES)),$(wildcard $(dir)*.S)) -RZDCY_FILES += $(VERSION_SRC) - ifdef FOR_PANDORA RZDCY_CFLAGS := \ $(CFLAGS) -c -O3 \ @@ -134,11 +111,17 @@ RZDCY_CFLAGS := endif RZDCY_CFLAGS += -I$(RZDCY_SRC_DIR) -I$(RZDCY_SRC_DIR)/rend/gles -I$(RZDCY_SRC_DIR)/deps \ - -I$(RZDCY_SRC_DIR)/deps/picotcp/include -I$(RZDCY_SRC_DIR)/deps/picotcp/modules \ -I$(RZDCY_SRC_DIR)/deps/vixl -I$(RZDCY_SRC_DIR)/khronos +ifdef USE_MODEM + RZDCY_CFLAGS += -DENABLE_MODEM -I$(RZDCY_SRC_DIR)/deps/picotcp/include -I$(RZDCY_SRC_DIR)/deps/picotcp/modules + RZDCY_MODULES += hw/modem/ deps/picotcp/modules/ deps/picotcp/stack/ +endif + ifdef NO_REC - RZDCY_CFLAGS += -DTARGET_NO_REC + RZDCY_CFLAGS += -DTARGET_NO_REC +else + RZDCY_MODULES += hw/sh4/dyna/ endif ifdef USE_GLES @@ -147,17 +130,30 @@ endif ifdef HAS_SOFTREND RZDCY_CFLAGS += -DTARGET_SOFTREND + RZDCY_MODULES += rend/soft/ endif ifdef CHD5_FLAC - RZDCY_CFLAGS += -I$(RZDCY_SRC_DIR)/deps/flac/src/libFLAC/include/ -I$(RZDCY_SRC_DIR)/deps/flac/include + RZDCY_CFLAGS += -DCHD5_FLAC -I$(RZDCY_SRC_DIR)/deps/flac/src/libFLAC/include/ -I$(RZDCY_SRC_DIR)/deps/flac/include RZDCY_CFLAGS += -DPACKAGE_VERSION=\"1.3.2\" -DFLAC__HAS_OGG=0 -DFLAC__NO_DLL -DHAVE_LROUND -DHAVE_STDINT_H -DHAVE_STDLIB_H -DHAVE_SYS_PARAM_H + RZDCY_MODULES += deps/flac/src/libFLAC/ +endif + +# 7-Zip/LZMA settings (CHDv5) +ifdef CHD5_LZMA + RZDCY_MODULES += deps/lzma/ + RZDCY_CFLAGS += -D_7ZIP_ST -DCHD5_LZMA endif RZDCY_CXXFLAGS := $(RZDCY_CFLAGS) -fno-exceptions -fno-rtti -std=gnu++11 -$(VERSION_SRC): - echo "const char *version = \"`git describe --tags --always`\";" > $(VERSION_SRC) - echo "const char *git_hash = \"`git rev-parse --short HEAD`\";" >> $(VERSION_SRC) - echo "const char *build_date = \"`date '+%Y-%m-%d %H:%M:%S %Z'`\";" >> $(VERSION_SRC) +RZDCY_FILES := $(foreach dir,$(addprefix $(RZDCY_SRC_DIR)/,$(RZDCY_MODULES)),$(wildcard $(dir)*.cpp)) +RZDCY_FILES += $(foreach dir,$(addprefix $(RZDCY_SRC_DIR)/,$(RZDCY_MODULES)),$(wildcard $(dir)*.cc)) +RZDCY_FILES += $(foreach dir,$(addprefix $(RZDCY_SRC_DIR)/,$(RZDCY_MODULES)),$(wildcard $(dir)*.c)) +RZDCY_FILES += $(foreach dir,$(addprefix $(RZDCY_SRC_DIR)/,$(RZDCY_MODULES)),$(wildcard $(dir)*.S)) + +$(VERSION_HEADER): + echo "#define REICAST_VERSION \"`git describe --tags --always`\"" > $(VERSION_HEADER) + echo "#define GIT_HASH \"`git rev-parse --short HEAD`\"" >> $(VERSION_HEADER) + echo "#define BUILD_DATE \"`date '+%Y-%m-%d %H:%M:%S %Z'`\"" >> $(VERSION_HEADER) diff --git a/core/deps/dirent/dirent.c b/core/deps/dirent/dirent.c new file mode 100644 index 000000000..8d496474c --- /dev/null +++ b/core/deps/dirent/dirent.c @@ -0,0 +1,148 @@ +/* + + Implementation of POSIX directory browsing functions and types for Win32. + + Author: Kevlin Henney (kevlin@acm.org, kevlin@curbralan.com) + History: Created March 1997. Updated June 2003 and July 2012. + Rights: See end of file. + +*/ + +#include "dirent.h" +#include +#include /* _findfirst and _findnext set errno iff they return -1 */ +#include +#include + +#ifdef __cplusplus +extern "C" +{ +#endif + + typedef ptrdiff_t handle_type; /* C99's intptr_t not sufficiently portable */ + + struct DIR + { + handle_type handle; /* -1 for failed rewind */ + struct _finddata_t info; + struct dirent result; /* d_name null iff first time */ + char *name; /* null-terminated char string */ + }; + + DIR *opendir(const char *name) + { + DIR *dir = 0; + + if (name && name[0]) + { + size_t base_length = strlen(name); + const char *all = /* search pattern must end with suitable wildcard */ + strchr("/\\", name[base_length - 1]) ? "*" : "/*"; + + if ((dir = (DIR *)malloc(sizeof *dir)) != 0 && + (dir->name = (char *)malloc(base_length + strlen(all) + 1)) != 0) + { + strcat(strcpy(dir->name, name), all); + + if ((dir->handle = + (handle_type)_findfirst(dir->name, &dir->info)) != -1) + { + dir->result.d_name = 0; + } + else /* rollback */ + { + free(dir->name); + free(dir); + dir = 0; + } + } + else /* rollback */ + { + free(dir); + dir = 0; + errno = ENOMEM; + } + } + else + { + errno = EINVAL; + } + + return dir; + } + + int closedir(DIR *dir) + { + int result = -1; + + if (dir) + { + if (dir->handle != -1) + { + result = _findclose(dir->handle); + } + + free(dir->name); + free(dir); + } + + if (result == -1) /* map all errors to EBADF */ + { + errno = EBADF; + } + + return result; + } + + struct dirent *readdir(DIR *dir) + { + struct dirent *result = 0; + + if (dir && dir->handle != -1) + { + if (!dir->result.d_name || _findnext(dir->handle, &dir->info) != -1) + { + result = &dir->result; + result->d_name = dir->info.name; + } + } + else + { + errno = EBADF; + } + + return result; + } + + void rewinddir(DIR *dir) + { + if (dir && dir->handle != -1) + { + _findclose(dir->handle); + dir->handle = (handle_type)_findfirst(dir->name, &dir->info); + dir->result.d_name = 0; + } + else + { + errno = EBADF; + } + } + +#ifdef __cplusplus +} +#endif + +/* + + Copyright Kevlin Henney, 1997, 2003, 2012. All rights reserved. + + Permission to use, copy, modify, and distribute this software and its + documentation for any purpose is hereby granted without fee, provided + that this copyright and permissions notice appear in all copies and + derivatives. + + This software is supplied "as is" without express or implied warranty. + + But that said, if there are any problems please get in touch. + +*/ diff --git a/core/deps/dirent/dirent.h b/core/deps/dirent/dirent.h new file mode 100644 index 000000000..192be112f --- /dev/null +++ b/core/deps/dirent/dirent.h @@ -0,0 +1,50 @@ +#ifndef DIRENT_INCLUDED +#define DIRENT_INCLUDED + +/* + + Declaration of POSIX directory browsing functions and types for Win32. + + Author: Kevlin Henney (kevlin@acm.org, kevlin@curbralan.com) + History: Created March 1997. Updated June 2003. + Rights: See end of file. + +*/ + +#ifdef __cplusplus +extern "C" +{ +#endif + + typedef struct DIR DIR; + + struct dirent + { + char *d_name; + }; + + DIR *opendir(const char *); + int closedir(DIR *); + struct dirent *readdir(DIR *); + void rewinddir(DIR *); + + /* + + Copyright Kevlin Henney, 1997, 2003. All rights reserved. + + Permission to use, copy, modify, and distribute this software and its + documentation for any purpose is hereby granted without fee, provided + that this copyright and permissions notice appear in all copies and + derivatives. + + This software is supplied "as is" without express or implied warranty. + + But that said, if there are any problems please get in touch. + + */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/core/hw/aica/aica.cpp b/core/hw/aica/aica.cpp index 1eea5a03d..3cbf02bd9 100644 --- a/core/hw/aica/aica.cpp +++ b/core/hw/aica/aica.cpp @@ -1,4 +1,5 @@ #include "aica.h" +#include "aica_if.h" #include "sgc_if.h" #include "aica_mem.h" #include @@ -180,6 +181,7 @@ template void WriteAicaReg<2>(u32 reg,u32 data); s32 libAICA_Init() { init_mem(); + aica_Init(); verify(sizeof(*CommonData)==0x508); verify(sizeof(*DSPData)==0x15C8); @@ -203,9 +205,12 @@ s32 libAICA_Init() return rv_ok; } -void libAICA_Reset(bool m) +void libAICA_Reset(bool manual) { + if (!manual) + init_mem(); sgc_Init(); + aica_Reset(manual); } void libAICA_Term() diff --git a/core/hw/aica/aica_if.cpp b/core/hw/aica/aica_if.cpp index c717f8507..d562a0de1 100644 --- a/core/hw/aica/aica_if.cpp +++ b/core/hw/aica/aica_if.cpp @@ -13,11 +13,12 @@ #include -VArray2 aica_ram; +VLockedMemory aica_ram; u32 VREG;//video reg =P u32 ARMRST;//arm reset reg u32 rtc_EN=0; int dma_sched_id; +u32 RealTimeClock; u32 GetRTC_now() { @@ -39,9 +40,9 @@ u32 ReadMem_aica_rtc(u32 addr,u32 sz) switch( addr & 0xFF ) { case 0: - return settings.dreamcast.RTC>>16; + return RealTimeClock>>16; case 4: - return settings.dreamcast.RTC &0xFFFF; + return RealTimeClock &0xFFFF; case 8: return 0; } @@ -57,16 +58,16 @@ void WriteMem_aica_rtc(u32 addr,u32 data,u32 sz) case 0: if (rtc_EN) { - settings.dreamcast.RTC&=0xFFFF; - settings.dreamcast.RTC|=(data&0xFFFF)<<16; + RealTimeClock&=0xFFFF; + RealTimeClock|=(data&0xFFFF)<<16; rtc_EN=0; } return; case 4: if (rtc_EN) { - settings.dreamcast.RTC&=0xFFFF0000; - settings.dreamcast.RTC|= data&0xFFFF; + RealTimeClock&=0xFFFF0000; + RealTimeClock|= data&0xFFFF; //TODO: Clean the internal timer ? } return; @@ -153,15 +154,12 @@ void WriteMem_aica_reg(u32 addr,u32 data,u32 sz) //Init/res/term void aica_Init() { - //mmnnn ? gotta fill it w/ something + RealTimeClock = GetRTC_now(); } void aica_Reset(bool Manual) { - if (!Manual) - { - aica_ram.Zero(); - } + aica_Init(); } void aica_Term() diff --git a/core/hw/aica/aica_if.h b/core/hw/aica/aica_if.h index 8c6009a66..13ee6fd97 100644 --- a/core/hw/aica/aica_if.h +++ b/core/hw/aica/aica_if.h @@ -2,7 +2,8 @@ #include "types.h" extern u32 VREG; -extern VArray2 aica_ram; +extern VLockedMemory aica_ram; +extern u32 RealTimeClock; u32 ReadMem_aica_rtc(u32 addr,u32 sz); void WriteMem_aica_rtc(u32 addr,u32 data,u32 sz); u32 ReadMem_aica_reg(u32 addr,u32 sz); @@ -17,4 +18,4 @@ void aica_Term(); void aica_sb_Init(); void aica_sb_Reset(bool Manual); -void aica_sb_Term(); \ No newline at end of file +void aica_sb_Term(); diff --git a/core/hw/holly/sb.cpp b/core/hw/holly/sb.cpp index 69c809a82..4c962b6f6 100644 --- a/core/hw/holly/sb.cpp +++ b/core/hw/holly/sb.cpp @@ -783,7 +783,7 @@ void sb_Init() maple_Init(); aica_sb_Init(); -#if DC_PLATFORM == DC_PLATFORM_DREAMCAST +#if DC_PLATFORM == DC_PLATFORM_DREAMCAST && defined(ENABLE_MODEM) ModemInit(); #endif } diff --git a/core/hw/holly/sb_mem.cpp b/core/hw/holly/sb_mem.cpp index d201550c3..c60e4a7ba 100644 --- a/core/hw/holly/sb_mem.cpp +++ b/core/hw/holly/sb_mem.cpp @@ -217,8 +217,10 @@ T DYNACALL ReadMem_area0(u32 addr) { #if DC_PLATFORM == DC_PLATFORM_NAOMI || DC_PLATFORM == DC_PLATFORM_ATOMISWAVE return (T)libExtDevice_ReadMem_A0_006(addr, sz); -#else +#elif defined(ENABLE_MODEM) return (T)ModemReadMem_A0_006(addr, sz); +#else + return (T)0; #endif } //map 0x0060 to 0x006F @@ -302,7 +304,7 @@ void DYNACALL WriteMem_area0(u32 addr,T data) { #if DC_PLATFORM == DC_PLATFORM_NAOMI || DC_PLATFORM == DC_PLATFORM_ATOMISWAVE libExtDevice_WriteMem_A0_006(addr, data, sz); -#else +#elif defined(ENABLE_MODEM) ModemWriteMem_A0_006(addr, data, sz); #endif } diff --git a/core/hw/maple/maple_cfg.cpp b/core/hw/maple/maple_cfg.cpp index 5a02ef11b..4f8c9d2d6 100644 --- a/core/hw/maple/maple_cfg.cpp +++ b/core/hw/maple/maple_cfg.cpp @@ -4,6 +4,7 @@ #include "maple_devs.h" #include "maple_cfg.h" #include "cfg/cfg.h" +#include "hw/naomi/naomi_cart.h" #define HAS_VMU /* @@ -28,13 +29,31 @@ extern u16 kcode[4]; extern u32 vks[4]; extern s8 joyx[4],joyy[4]; extern u8 rt[4],lt[4]; -extern bool naomi_test_button; u8 GetBtFromSgn(s8 val) { return val+128; } +u32 awave_button_mapping[] = { + AWAVE_SERVICE_KEY, // DC_BTN_C + AWAVE_BTN1_KEY, // DC_BTN_B + AWAVE_BTN0_KEY, // DC_BTN_A + AWAVE_START_KEY, // DC_BTN_START + AWAVE_UP_KEY, // DC_DPAD_UP + AWAVE_DOWN_KEY, // DC_DPAD_DOWN + AWAVE_LEFT_KEY, // DC_DPAD_LEFT + AWAVE_RIGHT_KEY, // DC_DPAD_RIGHT + AWAVE_TEST_KEY, // DC_BTN_Z + AWAVE_BTN3_KEY, // DC_BTN_Y + AWAVE_BTN2_KEY, // DC_BTN_X + AWAVE_COIN_KEY, // DC_BTN_D + // DC_DPAD2_UP + // DC_DPAD2_DOWN + // DC_DPAD2_LEFT + // DC_DPAD2_RIGHT +}; + struct MapleConfigMap : IMapleConfigMap { maple_device* dev; @@ -59,17 +78,32 @@ struct MapleConfigMap : IMapleConfigMap pjs->kcode=kcode[player_num]; #if DC_PLATFORM == DC_PLATFORM_DREAMCAST - pjs->kcode |= 0xF901; -#elif DC_PLATFORM == DC_PLATFORM_ATOMISWAVE - if (naomi_test_button) - pjs->kcode &= ~(1 << 14); -// if (!(pjs->kcode & (1 << 9))) // Hack (Y -> service btn) -// pjs->kcode &= ~(1 << 13); -#endif + pjs->kcode |= 0xF901; // mask off DPad2, C, D and Z pjs->joy[PJAI_X1]=GetBtFromSgn(joyx[player_num]); pjs->joy[PJAI_Y1]=GetBtFromSgn(joyy[player_num]); pjs->trigger[PJTI_R]=rt[player_num]; pjs->trigger[PJTI_L]=lt[player_num]; +#elif DC_PLATFORM == DC_PLATFORM_ATOMISWAVE + pjs->kcode = 0xFFFF; + for (int i = 0; i < 16; i++) + { + if ((kcode[player_num] & (1 << i)) == 0) + pjs->kcode &= ~awave_button_mapping[i]; + } + pjs->joy[PJAI_X1] = GetBtFromSgn(joyx[player_num]); + if (NaomiGameInputs != NULL && NaomiGameInputs->axes[1].name != NULL && NaomiGameInputs->axes[1].type == Half) + { + // Driving games: put axis 2 on RT (accel) and axis 3 on LT (brake) + pjs->joy[PJAI_Y1] = rt[player_num]; + pjs->joy[PJAI_X2] = lt[player_num]; + } + else + { + pjs->joy[PJAI_Y1] = GetBtFromSgn(joyy[player_num]); + pjs->joy[PJAI_X2] = rt[player_num]; + pjs->joy[PJAI_Y2] = lt[player_num]; + } +#endif } void SetImage(void* img) { @@ -77,6 +111,16 @@ struct MapleConfigMap : IMapleConfigMap } }; +bool maple_atomiswave_coin_chute(int slot) +{ + for (int i = 0; i < 16; i++) + { + if ((kcode[slot] & (1 << i)) == 0 && awave_button_mapping[i] == AWAVE_COIN_KEY) + return true; + } + return false; +} + void mcfg_Create(MapleDeviceType type, u32 bus, u32 port, s32 player_num = -1) { if (MapleDevices[bus][port] != NULL) @@ -100,17 +144,32 @@ void mcfg_CreateAtomisWaveControllers() // Then other devices on port 2 and 3 for analog axes, light guns, ... mcfg_Create(MDT_SegaController, 0, 5); mcfg_Create(MDT_SegaController, 1, 5); -// mcfg_Create(MDT_SegaController, 2, 5, 0); -// mcfg_Create(MDT_SegaController, 3, 5, 1); -// mcfg_Create(MDT_LightGun, 2, 5, 0); -// mcfg_Create(MDT_LightGun, 3, 5, 1); -// mcfg_Create(MDT_Mouse, 2, 5, 0); - // Guilty Gear Isuka (4P) needs 4 std controllers - // Faster Than Speed needs 1 std controller on port 0 (digital inputs) and one on port 2 (analog axes) - // Maximum Speed same - // Clay Challenge needs 2 std controllers on port 0 & 1 (digital in) and light guns on port 2 & 3 - // Sports Shooting same - // Sega Bass Fishing Challenge needs a mouse (track-ball) on port 3 + if (NaomiGameInputs != NULL && NaomiGameInputs->axes[0].name != NULL) + { + // Game needs analog axes + mcfg_Create(MDT_SegaController, 2, 5, 0); + mcfg_Create(MDT_SegaController, 3, 5, 1); + // Faster Than Speed needs 1 std controller on port 0 (digital inputs) and one on port 2 (analog axes) + // Maximum Speed same + } + else if (settings.input.JammaSetup == 1) + { + // 4 players + mcfg_Create(MDT_SegaController, 2, 5); + mcfg_Create(MDT_SegaController, 3, 5); + } + else if (settings.input.JammaSetup == 5) + { + // Clay Challenge needs 2 std controllers on port 0 & 1 (digital in) and light guns on port 2 & 3 + // Sports Shooting same + mcfg_Create(MDT_LightGun, 2, 5, 0); + mcfg_Create(MDT_LightGun, 3, 5, 1); + } + else if (settings.input.JammaSetup == 3) + { + // Sega Bass Fishing Challenge needs a mouse (track-ball) on port 2 + mcfg_Create(MDT_Mouse, 2, 5, 0); + } } void mcfg_CreateDevices() diff --git a/core/hw/maple/maple_cfg.h b/core/hw/maple/maple_cfg.h index 4afcc99ce..75d4d116e 100644 --- a/core/hw/maple/maple_cfg.h +++ b/core/hw/maple/maple_cfg.h @@ -68,3 +68,5 @@ void mcfg_CreateAtomisWaveControllers(); void mcfg_DestroyDevices(); void mcfg_SerializeDevices(void **data, unsigned int *total_size); void mcfg_UnserializeDevices(void **data, unsigned int *total_size); + +bool maple_atomiswave_coin_chute(int slot); diff --git a/core/hw/maple/maple_devs.cpp b/core/hw/maple/maple_devs.cpp index ef9d5ac35..90b4c972a 100755 --- a/core/hw/maple/maple_devs.cpp +++ b/core/hw/maple/maple_devs.cpp @@ -7,6 +7,7 @@ #include "hw/naomi/naomi.h" #include "hw/naomi/naomi_cart.h" #include "hw/pvr/spg.h" +#include "input/gamepad.h" #include #include "deps/zlib/zlib.h" @@ -198,6 +199,35 @@ struct maple_base: maple_device */ struct maple_sega_controller: maple_base { + virtual u32 get_capabilities() { + // byte 0: 0 0 0 0 0 0 0 0 + // byte 1: 0 0 a5 a4 a3 a2 a1 a0 + // byte 2: R2 L2 D2 U2 D X Y Z + // byte 3: R L D U St A B C + + return 0xfe060f00; // 4 analog axes (0-3) X Y A B Start U D L R + } + + virtual u32 transform_kcode(u32 kcode) { + return kcode; + } + + virtual u32 get_analog_axis(int index, const PlainJoystickState &pjs) { + switch (index) + { + case 0: + return pjs.trigger[PJTI_R]; // Right trigger + case 1: + return pjs.trigger[PJTI_L]; // Left trigger + case 2: + return pjs.joy[PJAI_X1]; // Stick X + case 3: + return pjs.joy[PJAI_Y1]; // Stick Y + default: + return 0x80; // unused + } + } + virtual MapleDeviceType get_device_type() { return MDT_SegaController; @@ -215,9 +245,9 @@ struct maple_sega_controller: maple_base //struct data //3*4 - w32( 0xfe060f00); - w32( 0); - w32( 0); + w32(get_capabilities()); + w32(0); + w32(0); //1 area code w8(0xFF); @@ -250,26 +280,26 @@ struct maple_sega_controller: maple_base //state data //2 key code - w16(pjs.kcode); + w16(transform_kcode(pjs.kcode)); //triggers //1 R - w8(pjs.trigger[PJTI_R]); + w8(get_analog_axis(0, pjs)); //1 L - w8(pjs.trigger[PJTI_L]); + w8(get_analog_axis(1, pjs)); //joyx //1 - w8(pjs.joy[PJAI_X1]); + w8(get_analog_axis(2, pjs)); //joyy //1 - w8(pjs.joy[PJAI_Y1]); + w8(get_analog_axis(3, pjs)); //not used //1 - w8(0x80); + w8(get_analog_axis(4, pjs)); //1 - w8(0x80); + w8(get_analog_axis(5, pjs)); } return MDRS_DataTransfer; @@ -281,6 +311,38 @@ struct maple_sega_controller: maple_base } }; +struct maple_atomiswave_controller: maple_sega_controller +{ + virtual u32 get_capabilities() override { + // byte 0: 0 0 0 0 0 0 0 0 + // byte 1: 0 0 a5 a4 a3 a2 a1 a0 + // byte 2: R2 L2 D2 U2 D X Y Z + // byte 3: R L D U St A B C + + return 0xff663f00; // 6 analog axes, X Y L2/D2(?) A B C Start U D L R + } + + virtual u32 transform_kcode(u32 kcode) override { + return kcode | AWAVE_TRIGGER_KEY; + } + + virtual u32 get_analog_axis(int index, const PlainJoystickState &pjs) override { + switch (index) + { + case 2: + return pjs.joy[PJAI_X1]; + case 3: + return pjs.joy[PJAI_Y1]; + case 4: + return pjs.joy[PJAI_X2]; + case 5: + return pjs.joy[PJAI_Y2]; + default: + return 0x80; + } + } +}; + /* Sega Dreamcast Visual Memory Unit This is pretty much done (?) @@ -1267,6 +1329,10 @@ struct maple_mouse : maple_base struct maple_lightgun : maple_base { + virtual u32 transform_kcode(u32 kcode) { + return kcode | 0xFF01; + } + virtual MapleDeviceType get_device_type() { return MDT_LightGun; @@ -1315,21 +1381,13 @@ struct maple_lightgun : maple_base PlainJoystickState pjs; config->GetInput(&pjs); - // Also use the mouse buttons - if (!(mo_buttons & 4)) // Left button - pjs.kcode &= ~4; // A - if (!(mo_buttons & 2)) // Right button - pjs.kcode &= ~2; // B - if (!(mo_buttons & 8)) // Wheel button - pjs.kcode &= ~8; // Start - //caps //4 w32(MFID_0_Input); //state data //2 key code - w16(pjs.kcode | 0xFF01); + w16(transform_kcode(pjs.kcode)); //not used //2 @@ -1355,6 +1413,13 @@ struct maple_lightgun : maple_base } }; +struct atomiswave_lightgun : maple_lightgun +{ + virtual u32 transform_kcode(u32 kcode) override { + return (kcode & AWAVE_TRIGGER_KEY) == 0 ? ~AWAVE_BTN0_KEY : ~0; + } +}; + extern u16 kcode[4]; extern s8 joyx[4],joyy[4]; extern u8 rt[4], lt[4]; @@ -1381,20 +1446,29 @@ static u16 getRightTriggerAxis() return rt[0] << 8; } -NaomiInputMapping Naomi_Mapping = { - { getJoystickXAxis, getJoystickYAxis, getRightTriggerAxis, getLeftTriggerAxis }, - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0 }, - { 0x40, 0x01, 0x02, 0x80, 0x20, 0x10, 0x08, 0x04, 0, 0x80, 0x40, 0, 0 }, -// SERVICE BTN1 BTN0 START UP DOWN LEFT RIGHT BTN2 BTN3 +u32 naomi_button_mapping[] = { + NAOMI_SERVICE_KEY, // DC_BTN_C + NAOMI_BTN1_KEY, // DC_BTN_B + NAOMI_BTN0_KEY, // DC_BTN_A + NAOMI_START_KEY, // DC_BTN_START + NAOMI_UP_KEY, // DC_DPAD_UP + NAOMI_DOWN_KEY, // DC_DPAD_DOWN + NAOMI_LEFT_KEY, // DC_DPAD_LEFT + NAOMI_RIGHT_KEY, // DC_DPAD_RIGHT + NAOMI_TEST_KEY, // DC_BTN_Z + NAOMI_BTN3_KEY, // DC_BTN_Y + NAOMI_BTN2_KEY, // DC_BTN_X + NAOMI_COIN_KEY, // DC_BTN_D + // DC_DPAD2_UP + // DC_DPAD2_DOWN + // DC_DPAD2_LEFT + // DC_DPAD2_RIGHT }; - /* * Sega JVS I/O board */ -bool coin_chute; -static bool old_coin_chute; -static int coin_count; -bool naomi_test_button = false; +static bool old_coin_chute[4]; +static int coin_count[4]; struct maple_naomi_jamma; @@ -2313,63 +2387,56 @@ u32 jvs_io_board::handle_jvs_message(u8 *buffer_in, u32 length_in, u8 *buffer_ou { JVS_STATUS1(); // report byte - LOGJVS("btns "); - JVS_OUT(naomi_test_button ? 0x80 : 0x00); // test, tilt1, tilt2, tilt3, unused, unused, unused, unused - // FIXME in-lst mapping - u8 buttons[8] = { 0 }; - u32 keycode = ~kcode[0]; - for (int i = 0; i < 16; i++) - if ((keycode & (1 << i)) != 0) - { - buttons[Naomi_Mapping.button_mapping_byte[i]] |= Naomi_Mapping.button_mapping_mask[i]; - } - for (int player = 0; player < buffer_in[cmdi + 1]; player++) + u16 buttons[4] = { 0 }; + for (int player = 0; player < buffer_in[cmdi + 1] && first_player + player < ARRAY_SIZE(kcode); player++) { - u8 *cur_btns = &buttons[(first_player + player) * 2]; - LOGJVS("P%d %02x ", player + 1 + first_player, cur_btns[0]); - JVS_OUT(cur_btns[0]); - if (buffer_in[cmdi + 2] == 2) + u32 keycode = ~kcode[first_player + player]; + for (int i = 0; i < 16; i++) { - LOGJVS("%02x ", cur_btns[1]); - JVS_OUT(cur_btns[1]); + if ((keycode & (1 << i)) != 0) + buttons[player] |= naomi_button_mapping[i]; + } + } + + LOGJVS("btns "); + JVS_OUT((buttons[0] & NAOMI_TEST_KEY) ? 0x80 : 0x00); // test, tilt1, tilt2, tilt3, unused, unused, unused, unused + for (int player = 0; player < buffer_in[cmdi + 1]; player++) + { + u16 cur_btns = first_player + player < ARRAY_SIZE(buttons) ? buttons[first_player + player] : 0; + LOGJVS("P%d %02x ", player + 1 + first_player, cur_btns >> 8); + JVS_OUT(cur_btns >> 8); + if (buffer_in[cmdi + 2] == 2) + { + LOGJVS("%02x ", cur_btns & 0xFF); + JVS_OUT(cur_btns); } } -// for (int player = 0; player < jvs_request[channel][cmdi + 1]; player++) -// { -// u32 keycode = ~kcode[player]; -// if (keycode & DC_BTN_C) -// keycode |= 0xFFff; -// -// if (jvs_request[channel][cmdi + 2] == 1) -// JVS_OUT(keycode); -// else -// w16(keycode); -// } cmdi += 3; } break; case 0x21: // Read coins { - if (coin_chute && !old_coin_chute) - coin_count++; - old_coin_chute = coin_chute; JVS_STATUS1(); // report byte LOGJVS("coins "); for (int slot = 0; slot < buffer_in[cmdi + 1]; slot++) { - if (slot == 0) + bool coin_chute = false; + u32 keycode = ~kcode[first_player + slot]; + for (int i = 0; i < 16 && !coin_chute; i++) { - LOGJVS("0:%d ", coin_count); - JVS_OUT((coin_count >> 8) & 0x3F); // status (2 highest bits, 0: normal), coin count MSB - JVS_OUT(coin_count); // coin count LSB - } - else - { - LOGJVS("%d:0 ", slot); - JVS_OUT(0); - JVS_OUT(0); + if (naomi_button_mapping[i] == NAOMI_COIN_KEY && (keycode & (1 << i)) != 0) + coin_chute = true; } + if (coin_chute && !old_coin_chute[first_player + slot]) + coin_count[first_player + slot] += 1; + old_coin_chute[first_player + slot] = coin_chute; + + LOGJVS("%d:%d ", slot + 1 + first_player, coin_count[first_player + slot]); + // status (2 highest bits, 0: normal), coin count MSB + JVS_OUT((coin_count[first_player + slot] >> 8) & 0x3F); + // coin count LSB + JVS_OUT(coin_count[first_player + slot]); } cmdi += 2; } @@ -2393,34 +2460,50 @@ u32 jvs_io_board::handle_jvs_message(u8 *buffer_in, u32 length_in, u8 *buffer_ou } LOGJVS("x,y:%4x,%4x ", x, y); JVS_OUT(x >> 8); // X, MSB - JVS_OUT(x); // X, LSB + JVS_OUT(x); // X, LSB JVS_OUT(y >> 8); // Y, MSB - JVS_OUT(y); // Y, LSB + JVS_OUT(y); // Y, LSB axis = 2; } + int full_axis_count = 0; + int half_axis_count = 0; for (; axis < buffer_in[cmdi + 1]; axis++) { - // FIXME Need to know how many axes per player for proper mapping u16 axis_value; - if (axis + first_player * 4 < 8 && Naomi_Mapping.axis[axis + first_player * 4] != NULL) - axis_value = Naomi_Mapping.axis[axis + first_player * 4](); + if (NaomiGameInputs != NULL + && axis < ARRAY_SIZE(NaomiGameInputs->axes) + && NaomiGameInputs->axes[axis].name != NULL + && NaomiGameInputs->axes[axis].type == Half) + { + if (half_axis_count == 0) + axis_value = rt[first_player] << 8; + else if (half_axis_count == 1) + axis_value = lt[first_player] << 8; + else + axis_value = 0; + half_axis_count++; + } else { - switch (axis) { + switch (full_axis_count) { case 0: - axis_value = (joyx[first_player + axis / 4] + 128) << 8; + axis_value = (joyx[first_player] + 128) << 8; break; case 1: - axis_value = (joyy[first_player + axis / 4] + 128) << 8; - break; - case 2: - axis_value = rt[first_player + axis / 4] << 8; - break; - case 3: - axis_value = lt[first_player + axis / 4] << 8; + axis_value = (joyy[first_player] + 128) << 8; break; + // TODO right analog stick +// case 2: +// axis_value = (joyrx[first_player] + 128) << 8; +// break; +// case 3: +// axis_value = (joyry[first_player] + 128) << 8; +// break; + default: + axis_value = 128; } + full_axis_count++; } LOGJVS("%d:%4x ", axis, axis_value); JVS_OUT(axis_value >> 8); @@ -2493,8 +2576,8 @@ u32 jvs_io_board::handle_jvs_message(u8 *buffer_in, u32 length_in, u8 *buffer_ou break; case 0x30: // substract coin - if (buffer_in[cmdi + 1] == 1) - coin_count -= (buffer_in[cmdi + 2] << 8) + buffer_in[cmdi + 3]; + if (buffer_in[cmdi + 1] > 0 && first_player + buffer_in[cmdi + 1] - 1 < ARRAY_SIZE(coin_count)) + coin_count[first_player + buffer_in[cmdi + 1] - 1] -= (buffer_in[cmdi + 2] << 8) + buffer_in[cmdi + 3]; JVS_STATUS1(); // report byte cmdi += 4; break; @@ -2542,7 +2625,11 @@ maple_device* maple_Create(MapleDeviceType type) switch(type) { case MDT_SegaController: - rv=new maple_sega_controller(); +#if DC_PLATFORM != DC_PLATFORM_ATOMISWAVE + rv = new maple_sega_controller(); +#else + rv = new maple_atomiswave_controller(); +#endif break; case MDT_Microphone: @@ -2566,7 +2653,11 @@ maple_device* maple_Create(MapleDeviceType type) break; case MDT_LightGun: +#if DC_PLATFORM != DC_PLATFORM_ATOMISWAVE rv = new maple_lightgun(); +#else + rv = new atomiswave_lightgun(); +#endif break; case MDT_NaomiJamma: diff --git a/core/hw/mem/_vmem.cpp b/core/hw/mem/_vmem.cpp index 2c02197c5..3fbfdf6b5 100644 --- a/core/hw/mem/_vmem.cpp +++ b/core/hw/mem/_vmem.cpp @@ -21,7 +21,6 @@ _vmem_WriteMem32FP* _vmem_WF32[HANDLER_COUNT]; //upper 8b of the address void* _vmem_MemInfo_ptr[0x100]; - void _vmem_get_ptrs(u32 sz,bool write,void*** vmap,void*** func) { *vmap=_vmem_MemInfo_ptr; @@ -385,10 +384,7 @@ void _vmem_reset() verify(_vmem_register_handler(0,0,0,0,0,0)==0); } -void _vmem_term() -{ - -} +void _vmem_term() {} #include "hw/pvr/pvr_mem.h" #include "hw/sh4/sh4_mem.h" @@ -409,414 +405,119 @@ void* malloc_pages(size_t size) { #endif } -bool _vmem_reserve_nonvmem() -{ - virt_ram_base = 0; - - p_sh4rcb=(Sh4RCB*)malloc_pages(sizeof(Sh4RCB)); - - mem_b.size=RAM_SIZE; - mem_b.data=(u8*)malloc_pages(RAM_SIZE); - - vram.size=VRAM_SIZE; - vram.data=(u8*)malloc_pages(VRAM_SIZE); - - aica_ram.size=ARAM_SIZE; - aica_ram.data=(u8*)malloc_pages(ARAM_SIZE); - - return true; -} - -void _vmem_bm_reset_nvmem(); - +// Resets the FPCB table (by either clearing it to the default val +// or by flushing it and making it fault on access again. void _vmem_bm_reset() { - if (virt_ram_base) { - #if !defined(TARGET_NO_NVMEM) - _vmem_bm_reset_nvmem(); - #endif - } - -#ifndef TARGET_IPHONE - if (!virt_ram_base) -#endif - { - bm_vmem_pagefill((void**)p_sh4rcb->fpcb, FPCB_SIZE); - } + // If we allocated it via vmem: + if (virt_ram_base) + vmem_platform_reset_mem(p_sh4rcb->fpcb, sizeof(p_sh4rcb->fpcb)); + else + // We allocated it via a regular malloc/new/whatever on the heap + bm_vmem_pagefill((void**)p_sh4rcb->fpcb, sizeof(p_sh4rcb->fpcb)); } -static void _vmem_release_nonvmem() -{ - free(p_sh4rcb); - free(vram.data); - free(aica_ram.data); - free(mem_b.data); -} +// This gets called whenever there is a pagefault, it is possible that it lands +// on the fpcb memory range, which is allocated on miss. Returning true tells the +// fault handler this was us, and that the page is resolved and can continue the execution. +bool BM_LockedWrite(u8* address) { + if (!virt_ram_base) + return false; // No vmem, therefore not us who caused this. -#if !defined(TARGET_NO_NVMEM) + uintptr_t ptrint = (uintptr_t)address; + uintptr_t start = (uintptr_t)p_sh4rcb->fpcb; + uintptr_t end = start + sizeof(p_sh4rcb->fpcb); -#define MAP_RAM_START_OFFSET 0 -#define MAP_VRAM_START_OFFSET (MAP_RAM_START_OFFSET+RAM_SIZE) -#define MAP_ARAM_START_OFFSET (MAP_VRAM_START_OFFSET+VRAM_SIZE) - -#if HOST_OS==OS_WINDOWS -#include -HANDLE mem_handle; - -void* _nvmem_map_buffer(u32 dst,u32 addrsz,u32 offset,u32 size, bool w) -{ - void* ptr; - void* rv; - - u32 map_times=addrsz/size; - verify((addrsz%size)==0); - verify(map_times>=1); - - rv= MapViewOfFileEx(mem_handle,FILE_MAP_READ | (w?FILE_MAP_WRITE:0),0,offset,size,&virt_ram_base[dst]); - if (!rv) - return 0; - - for (u32 i=1;i - #include - #include - #include - #include - #include - -#ifndef MAP_NOSYNC -#define MAP_NOSYNC 0 //missing from linux :/ -- could be the cause of android slowness ? -#endif - -#ifdef _ANDROID -#include - -#ifndef ASHMEM_DEVICE -#define ASHMEM_DEVICE "/dev/ashmem" -#endif -int ashmem_create_region(const char *name, size_t size) -{ - int fd, ret; - - fd = open(ASHMEM_DEVICE, O_RDWR); - if (fd < 0) - return fd; - - if (name) { - char buf[ASHMEM_NAME_LEN]; - - strlcpy(buf, name, sizeof(buf)); - ret = ioctl(fd, ASHMEM_SET_NAME, buf); - if (ret < 0) - goto error; - } - - ret = ioctl(fd, ASHMEM_SET_SIZE, size); - if (ret < 0) - goto error; - - return fd; - -error: - close(fd); - return ret; -} -#endif - - int fd; - void* _nvmem_unused_buffer(u32 start,u32 end) - { - void* ptr=mmap(&virt_ram_base[start], end-start, PROT_NONE, MAP_FIXED | MAP_PRIVATE | MAP_ANON, -1, 0); - if (MAP_FAILED==ptr) - return 0; - return ptr; - } - - - void* _nvmem_map_buffer(u32 dst,u32 addrsz,u32 offset,u32 size, bool w) - { - void* ptr; - void* rv; - - printf("MAP %08X w/ %d\n",dst,offset); - u32 map_times=addrsz/size; - verify((addrsz%size)==0); - verify(map_times>=1); - u32 prot=PROT_READ|(w?PROT_WRITE:0); - rv= mmap(&virt_ram_base[dst], size, prot, MAP_SHARED | MAP_NOSYNC | MAP_FIXED, fd, offset); - if (MAP_FAILED==rv || rv!=(void*)&virt_ram_base[dst] || (mprotect(rv,size,prot)!=0)) - { - printf("MAP1 failed %d\n",errno); - return 0; - } - - for (u32 i=1;i slow and stuttery - { - fd = open("/data/data/com.reicast.emulator/files/dcnzorz_mem",O_CREAT|O_RDWR|O_TRUNC,S_IRWXU|S_IRWXG|S_IRWXO); - unlink("/data/data/com.reicast.emulator/files/dcnzorz_mem"); - } -#endif - - - - u32 sz = 512*1024*1024 + sizeof(Sh4RCB) + ARAM_SIZE_MAX + 0x10000; - void* rv=mmap(0, sz, PROT_NONE, MAP_PRIVATE | MAP_ANON, -1, 0); - verify(rv != NULL); - munmap(rv,sz); - return (u8*)rv + 0x10000 - unat(rv)%0x10000;//align to 64 KB (Needed for linaro mmap not to extend to next region) - } -#endif - -#define map_buffer(dsts,dste,offset,sz,w) {ptr=_nvmem_map_buffer(dsts,dste-dsts,offset,sz,w);if (!ptr) return false;} -#define unused_buffer(start,end) {ptr=_nvmem_unused_buffer(start,end);if (!ptr) return false;} - -u32 pagecnt; -void _vmem_bm_reset_nvmem() -{ - #if defined(TARGET_NO_NVMEM) - return; - #endif - - #ifdef TARGET_IPHONE - //On iOS & nacl we allways allocate all of the mapping table - mprotect(p_sh4rcb, sizeof(p_sh4rcb->fpcb), PROT_READ | PROT_WRITE); - return; - #endif - pagecnt=0; - -#if HOST_OS==OS_WINDOWS - VirtualFree(p_sh4rcb,sizeof(p_sh4rcb->fpcb),MEM_DECOMMIT); -#else - mprotect(p_sh4rcb, sizeof(p_sh4rcb->fpcb), PROT_NONE); - madvise(p_sh4rcb,sizeof(p_sh4rcb->fpcb),MADV_DONTNEED); - #ifdef MADV_REMOVE - madvise(p_sh4rcb,sizeof(p_sh4rcb->fpcb),MADV_REMOVE); - #else - //OSX, IOS - madvise(p_sh4rcb,sizeof(p_sh4rcb->fpcb),MADV_FREE); - #endif -#endif - - printf("Freeing fpcb\n"); -} - -bool BM_LockedWrite(u8* address) -{ - if (!_nvmem_enabled()) - return false; - -#if FEAT_SHREC != DYNAREC_NONE - u32 addr=address-(u8*)p_sh4rcb->fpcb; - - address=(u8*)p_sh4rcb->fpcb+ (addr&~PAGE_MASK); - - if (addrfpcb)) - { - //printf("Allocated %d PAGES [%08X]\n",++pagecnt,addr); - -#if HOST_OS==OS_WINDOWS - verify(VirtualAlloc(address,PAGE_SIZE,MEM_COMMIT,PAGE_READWRITE)); -#else - mprotect (address, PAGE_SIZE, PROT_READ | PROT_WRITE); -#endif - - bm_vmem_pagefill((void**)address,PAGE_SIZE); - + if (ptrint >= start && ptrint < end) { + // Alloc the page then and initialize it to default values + void *aligned_addr = (void*)(ptrint & (~PAGE_MASK)); + vmem_platform_ondemand_page(aligned_addr, PAGE_SIZE); + bm_vmem_pagefill((void**)aligned_addr, PAGE_SIZE); return true; } -#else -die("BM_LockedWrite and NO REC"); -#endif return false; } -bool _vmem_reserve() -{ - void* ptr=0; - +bool _vmem_reserve() { + // TODO: Static assert? verify((sizeof(Sh4RCB)%PAGE_SIZE)==0); - if (settings.dynarec.disable_nvmem) - return _vmem_reserve_nonvmem(); + VMemType vmemstatus = MemTypeError; - virt_ram_base=(u8*)_nvmem_alloc_mem(); + // Use vmem only if settings mandate so, and if we have proper exception handlers. + #ifndef TARGET_NO_EXCEPTIONS + if (!settings.dynarec.disable_nvmem) + vmemstatus = vmem_platform_init((void**)&virt_ram_base, (void**)&p_sh4rcb); + #endif - if (virt_ram_base==0) - return _vmem_reserve_nonvmem(); - - p_sh4rcb=(Sh4RCB*)virt_ram_base; + // Fallback to statically allocated buffers, this results in slow-ops being generated. + if (vmemstatus == MemTypeError) { + printf("Warning! nvmem is DISABLED (due to failure or not being built-in\n"); + virt_ram_base = 0; - // Map the sh4 context but protect access to Sh4RCB.fpcb[] -#if HOST_OS==OS_WINDOWS - //verify(p_sh4rcb==VirtualAlloc(p_sh4rcb,sizeof(Sh4RCB),MEM_RESERVE|MEM_COMMIT,PAGE_READWRITE)); - verify(p_sh4rcb==VirtualAlloc(p_sh4rcb,sizeof(Sh4RCB),MEM_RESERVE,PAGE_NOACCESS)); + // Allocate it all and initialize it. + p_sh4rcb = (Sh4RCB*)malloc_pages(sizeof(Sh4RCB)); + bm_vmem_pagefill((void**)p_sh4rcb->fpcb, sizeof(p_sh4rcb->fpcb)); - verify(VirtualAlloc((u8*)p_sh4rcb + sizeof(p_sh4rcb->fpcb),sizeof(Sh4RCB)-sizeof(p_sh4rcb->fpcb),MEM_COMMIT,PAGE_READWRITE)); -#else - verify(p_sh4rcb==mmap(p_sh4rcb,sizeof(Sh4RCB),PROT_NONE,MAP_PRIVATE | MAP_ANON, -1, 0)); - mprotect((u8*)p_sh4rcb + sizeof(p_sh4rcb->fpcb),sizeof(Sh4RCB)-sizeof(p_sh4rcb->fpcb),PROT_READ|PROT_WRITE); -#endif - virt_ram_base+=sizeof(Sh4RCB); + mem_b.size = RAM_SIZE; + mem_b.data = (u8*)malloc_pages(RAM_SIZE); - //Area 0 - //[0x00000000 ,0x00800000) -> unused - unused_buffer(0x00000000,0x00800000); + vram.size = VRAM_SIZE; + vram.data = (u8*)malloc_pages(VRAM_SIZE); - //I wonder, aica ram warps here ?.? - //I really should check teh docs before codin ;p - //[0x00800000,0x00A00000); - map_buffer(0x00800000,0x01000000,MAP_ARAM_START_OFFSET,ARAM_SIZE,false); - map_buffer(0x20000000,0x20000000+ARAM_SIZE,MAP_ARAM_START_OFFSET,ARAM_SIZE,true); + aica_ram.size = ARAM_SIZE; + aica_ram.data = (u8*)malloc_pages(ARAM_SIZE); + } + else { + printf("Info: nvmem is enabled, with addr space of size %s\n", vmemstatus == MemType4GB ? "4GB" : "512MB"); + // Map the different parts of the memory file into the new memory range we got. + #define MAP_RAM_START_OFFSET 0 + #define MAP_VRAM_START_OFFSET (MAP_RAM_START_OFFSET+RAM_SIZE) + #define MAP_ARAM_START_OFFSET (MAP_VRAM_START_OFFSET+VRAM_SIZE) + const vmem_mapping mem_mappings[] = { + {0x00000000, 0x00800000, 0, 0, false}, // Area 0 -> unused + {0x00800000, 0x01000000, MAP_ARAM_START_OFFSET, ARAM_SIZE, false}, // Aica, wraps too + {0x20000000, 0x20000000+ARAM_SIZE, MAP_ARAM_START_OFFSET, ARAM_SIZE, true}, + {0x01000000, 0x04000000, 0, 0, false}, // More unused + {0x04000000, 0x05000000, MAP_VRAM_START_OFFSET, VRAM_SIZE, true}, // Area 1 (vram, 16MB, wrapped on DC as 2x8MB) + {0x05000000, 0x06000000, 0, 0, false}, // 32 bit path (unused) + {0x06000000, 0x07000000, MAP_VRAM_START_OFFSET, VRAM_SIZE, true}, // VRAM mirror + {0x07000000, 0x08000000, 0, 0, false}, // 32 bit path (unused) mirror + {0x08000000, 0x0C000000, 0, 0, false}, // Area 2 + {0x0C000000, 0x10000000, MAP_RAM_START_OFFSET, RAM_SIZE, true}, // Area 3 (main RAM + 3 mirrors) + {0x10000000, 0x20000000, 0, 0, false}, // Area 4-7 (unused) + }; + vmem_platform_create_mappings(&mem_mappings[0], sizeof(mem_mappings) / sizeof(mem_mappings[0])); - aica_ram.size=ARAM_SIZE; - aica_ram.data=(u8*)ptr; - //[0x01000000 ,0x04000000) -> unused - unused_buffer(0x01000000,0x04000000); - + // Point buffers to actual data pointers + aica_ram.size = ARAM_SIZE; + aica_ram.data = &virt_ram_base[0x20000000]; // Points to the writtable AICA addrspace - //Area 1 - //[0x04000000,0x05000000) -> vram (16mb, warped on dc) - map_buffer(0x04000000,0x05000000,MAP_VRAM_START_OFFSET,VRAM_SIZE,true); - - vram.size=VRAM_SIZE; - vram.data=(u8*)ptr; + vram.size = VRAM_SIZE; + vram.data = &virt_ram_base[0x04000000]; // Points to first vram mirror (writtable and lockable) - //[0x05000000,0x06000000) -> unused (32b path) - unused_buffer(0x05000000,0x06000000); - - //[0x06000000,0x07000000) -> vram mirror - map_buffer(0x06000000,0x07000000,MAP_VRAM_START_OFFSET,VRAM_SIZE,true); - - - //[0x07000000,0x08000000) -> unused (32b path) mirror - unused_buffer(0x07000000,0x08000000); - - //Area 2 - //[0x08000000,0x0C000000) -> unused - unused_buffer(0x08000000,0x0C000000); - - //Area 3 - //[0x0C000000,0x0D000000) -> main ram - //[0x0D000000,0x0E000000) -> main ram mirror - //[0x0E000000,0x0F000000) -> main ram mirror - //[0x0F000000,0x10000000) -> main ram mirror - map_buffer(0x0C000000,0x10000000,MAP_RAM_START_OFFSET,RAM_SIZE,true); - - mem_b.size=RAM_SIZE; - mem_b.data=(u8*)ptr; - - //Area 4 - //Area 5 - //Area 6 - //Area 7 - //all -> Unused - //[0x10000000,0x20000000) -> unused - unused_buffer(0x10000000,0x20000000); - - printf("vmem reserve: base: %08X, aram: %08x, vram: %08X, ram: %08X\n",virt_ram_base,aica_ram.data,vram.data,mem_b.data); + mem_b.size = RAM_SIZE; + mem_b.data = &virt_ram_base[0x0C000000]; // Main memory, first mirror + } + // Clear out memory aica_ram.Zero(); vram.Zero(); mem_b.Zero(); - printf("Mem alloc successful!\n"); - - return virt_ram_base!=0; + return true; } -void _vmem_release() -{ - if (!_nvmem_enabled()) - _vmem_release_nonvmem(); - else - { - if (virt_ram_base != NULL) - { -#if HOST_OS == OS_WINDOWS - VirtualFree(virt_ram_base, 0, MEM_RELEASE); -#else - munmap(virt_ram_base, 0x20000000); -#endif - virt_ram_base = NULL; - } -#if HOST_OS != OS_WINDOWS - close(fd); -#endif +#define freedefptr(x) \ + if (x) { free(x); x = NULL; } + +void _vmem_release() { + if (virt_ram_base) + vmem_platform_destroy(); + else { + freedefptr(p_sh4rcb); + freedefptr(vram.data); + freedefptr(aica_ram.data); + freedefptr(mem_b.data); } } -#else - -bool _vmem_reserve() -{ - return _vmem_reserve_nonvmem(); -} -void _vmem_release() -{ - _vmem_release_nonvmem(); -} -#endif diff --git a/core/hw/mem/_vmem.h b/core/hw/mem/_vmem.h index 8509fe3ac..f739b0454 100644 --- a/core/hw/mem/_vmem.h +++ b/core/hw/mem/_vmem.h @@ -1,6 +1,33 @@ #pragma once #include "types.h" +enum VMemType { + MemType4GB, + MemType512MB, + MemTypeError +}; + +struct vmem_mapping { + u32 start_address, end_address; + unsigned memoffset, memsize; + bool allow_writes; +}; + +// Platform specific vmemory API +// To initialize (maybe) the vmem subsystem +VMemType vmem_platform_init(void **vmem_base_addr, void **sh4rcb_addr); +// To reset the on-demand allocated pages. +void vmem_platform_reset_mem(void *ptr, unsigned size_bytes); +// To handle a fault&allocate an ondemand page. +void vmem_platform_ondemand_page(void *address, unsigned size_bytes); +// To create the mappings in the address space. +void vmem_platform_create_mappings(const vmem_mapping *vmem_maps, unsigned nummaps); +// Just tries to wipe as much as possible in the relevant area. +void vmem_platform_destroy(); + +// Note: if you want to disable vmem magic in any given platform, implement the +// above functions as empty functions and make vmem_platform_init return MemTypeError. + //Typedef's //ReadMem typedef u8 DYNACALL _vmem_ReadMem8FP(u32 Address); @@ -70,4 +97,4 @@ static inline bool _nvmem_enabled() { return virt_ram_base != 0; } -void _vmem_bm_reset(); \ No newline at end of file +void _vmem_bm_reset(); diff --git a/core/hw/modem/dns.cpp b/core/hw/modem/dns.cpp index 1dc7f46c8..95c8657c4 100644 --- a/core/hw/modem/dns.cpp +++ b/core/hw/modem/dns.cpp @@ -18,6 +18,9 @@ You should have received a copy of the GNU General Public License along with reicast. If not, see . */ +#include "types.h" + +#if BUILD_COMPILER!=COMPILER_VC && (BUILD_COMPILER!=COMPILER_CLANG || !defined(WIN32)) #include #include @@ -145,3 +148,5 @@ char *read_name(char *reader, char *buffer, int *count) return name; } + +#endif // !COMPILER_VC_OR_CLANG_WIN32 \ No newline at end of file diff --git a/core/hw/naomi/awcartridge.cpp b/core/hw/naomi/awcartridge.cpp index 02b773b1a..f013ce8f7 100644 --- a/core/hw/naomi/awcartridge.cpp +++ b/core/hw/naomi/awcartridge.cpp @@ -162,6 +162,11 @@ ROM board internal layouts: */ #include "awcartridge.h" #include "awave_regs.h" +#ifdef _MSC_VER +#undef min +#undef max +#include +#endif u32 AWCartridge::ReadMem(u32 address, u32 size) { verify(size != 1); diff --git a/core/hw/naomi/naomi.cpp b/core/hw/naomi/naomi.cpp index 3f2a40af8..1b75b1a03 100644 --- a/core/hw/naomi/naomi.cpp +++ b/core/hw/naomi/naomi.cpp @@ -6,6 +6,7 @@ #include "hw/holly/sb.h" #include "hw/sh4/sh4_mem.h" #include "hw/holly/holly_intc.h" +#include "hw/maple/maple_cfg.h" #include "naomi.h" #include "naomi_cart.h" @@ -634,7 +635,6 @@ void Update_naomi() } static u8 aw_maple_devs; -extern bool coin_chute; u32 libExtDevice_ReadMem_A0_006(u32 addr,u32 size) { addr &= 0x7ff; @@ -653,12 +653,13 @@ u32 libExtDevice_ReadMem_A0_006(u32 addr,u32 size) { aw_ram_test_skipped = true; return 0; } - if (coin_chute) { - // FIXME Coin Error if coin_chute is set for too long - return 0xE; + u8 coin_input = 0xF; + for (int slot = 0; slot < 4; slot++) + if (maple_atomiswave_coin_chute(slot)) + coin_input &= ~(1 << slot); + return coin_input; } - return 0xF; case 0x284: // Atomiswave maple devices // ddcc0000 where cc/dd are the types of devices on maple bus 2 and 3: diff --git a/core/hw/naomi/naomi_cart.cpp b/core/hw/naomi/naomi_cart.cpp index 1dee0c64f..e9b18e2c0 100644 --- a/core/hw/naomi/naomi_cart.cpp +++ b/core/hw/naomi/naomi_cart.cpp @@ -32,7 +32,7 @@ fd_t* RomCacheMap = NULL; u32 RomCacheMapCount; char naomi_game_id[33]; -InputDescriptors *naomi_game_inputs; +InputDescriptors *NaomiGameInputs; u8 *naomi_default_eeprom; extern RomChip sys_rom; @@ -246,7 +246,7 @@ static bool naomi_cart_LoadZip(char *filename) break; } CurrentCartridge->SetKey(game->key); - naomi_game_inputs = game->inputs; + NaomiGameInputs = game->inputs; for (int romid = 0; game->blobs[romid].filename != NULL; romid++) { diff --git a/core/hw/naomi/naomi_cart.h b/core/hw/naomi/naomi_cart.h index b5c9745dc..918de1b72 100644 --- a/core/hw/naomi/naomi_cart.h +++ b/core/hw/naomi/naomi_cart.h @@ -110,6 +110,6 @@ struct InputDescriptors AxisDescriptor axes[8]; }; -extern InputDescriptors *naomi_game_inputs; +extern InputDescriptors *NaomiGameInputs; #endif //NAOMI_CART_H diff --git a/core/hw/pvr/Renderer_if.cpp b/core/hw/pvr/Renderer_if.cpp index fc4db314d..71c954e34 100644 --- a/core/hw/pvr/Renderer_if.cpp +++ b/core/hw/pvr/Renderer_if.cpp @@ -82,8 +82,7 @@ bool renderer_enabled = true; // Signals the renderer thread to exit bool renderer_changed = false; // Signals the renderer thread to switch renderer #if !defined(TARGET_NO_THREADS) -cResetEvent rs(false,true); -cResetEvent re(false,true); +cResetEvent rs, re; #endif int max_idx,max_mvo,max_op,max_pt,max_tr,max_vtx,max_modt, ovrn; @@ -99,6 +98,7 @@ TA_context* _pvrrc; void SetREP(TA_context* cntx); void killtex(); bool render_output_framebuffer(); +static void rend_create_renderer(); void dump_frame(const char* file, TA_context* ctx, u8* vram, u8* vram_ref = NULL) { FILE* fw = fopen(file, "wb"); @@ -267,6 +267,13 @@ bool rend_frame(TA_context* ctx, bool draw_osd) { bool rend_single_frame() { + if (renderer_changed) + { + renderer_changed = false; + rend_term_renderer(); + rend_create_renderer(); + rend_init_renderer(); + } //wait render start only if no frame pending do { @@ -363,6 +370,7 @@ void rend_init_renderer() } printf("Selected renderer initialization failed. Falling back to default renderer.\n"); renderer = fallback_renderer; + fallback_renderer = NULL; // avoid double-free } } @@ -378,7 +386,6 @@ void rend_term_renderer() delete fallback_renderer; fallback_renderer = NULL; } - tactx_Term(); } void* rend_thread(void* p) @@ -392,13 +399,6 @@ void* rend_thread(void* p) { if (rend_single_frame()) renderer->Present(); - if (renderer_changed) - { - renderer_changed = false; - rend_term_renderer(); - rend_create_renderer(); - rend_init_renderer(); - } } rend_term_renderer(); @@ -539,6 +539,7 @@ void rend_end_render() void rend_stop_renderer() { renderer_enabled = false; + tactx_Term(); } void rend_vblank() diff --git a/core/hw/pvr/pvr_mem.h b/core/hw/pvr/pvr_mem.h index 722d37bf6..f2584937d 100644 --- a/core/hw/pvr/pvr_mem.h +++ b/core/hw/pvr/pvr_mem.h @@ -9,7 +9,7 @@ f32 vrf(u32 addr); u32 vri(u32 addr); //vram 32-64b -extern VArray2 vram; +extern VLockedMemory vram; //read u8 DYNACALL pvr_read_area1_8(u32 addr); u16 DYNACALL pvr_read_area1_16(u32 addr); @@ -36,4 +36,4 @@ extern "C" void DYNACALL TAWriteSQ(u32 address,u8* sqb); void YUV_init(); //registers -#define PVR_BASE 0x005F8000 \ No newline at end of file +#define PVR_BASE 0x005F8000 diff --git a/core/hw/pvr/spg.cpp b/core/hw/pvr/spg.cpp index 0cf4c4d0b..b0970c3f1 100755 --- a/core/hw/pvr/spg.cpp +++ b/core/hw/pvr/spg.cpp @@ -88,6 +88,8 @@ double full_rps; static u32 lightgun_line = 0xffff; static u32 lightgun_hpos; +double mspdf; + u32 fskip=0; //called from sh4 context , should update pvr/ta state and everything else int spg_line_sched(int tag, int cycl, int jit) @@ -174,7 +176,7 @@ int spg_line_sched(int tag, int cycl, int jit) } double frames_done=spd_cpu/2; - double mspdf=1/frames_done*1000; + mspdf=1/frames_done*1000; full_rps=(spd_fps+fskip/ts); diff --git a/core/hw/pvr/ta_ctx.cpp b/core/hw/pvr/ta_ctx.cpp index 781d82aa4..31e80b07e 100644 --- a/core/hw/pvr/ta_ctx.cpp +++ b/core/hw/pvr/ta_ctx.cpp @@ -124,7 +124,7 @@ void VDecEnd() cMutex mtx_rqueue; TA_context* rqueue; -cResetEvent frame_finished(false, true); +cResetEvent frame_finished; double last_frame = 0; u64 last_cyces = 0; diff --git a/core/hw/sh4/dyna/blockmanager.cpp b/core/hw/sh4/dyna/blockmanager.cpp index e64cd0d60..0994c3469 100644 --- a/core/hw/sh4/dyna/blockmanager.cpp +++ b/core/hw/sh4/dyna/blockmanager.cpp @@ -339,9 +339,9 @@ void bm_Rebuild() rebuild_counter=30; } -void bm_vmem_pagefill(void** ptr,u32 PAGE_SZ) +void bm_vmem_pagefill(void** ptr, u32 size_bytes) { - for (size_t i=0; i list; +vector sch_list; // using list as external inside a macro confuses clang and msc int sh4_sched_next_id=-1; u32 sh4_sched_remaining(int id, u32 reference) { - if (list[id].end != -1) + if (sch_list[id].end != -1) { - return list[id].end - reference; + return sch_list[id].end - reference; } else { @@ -51,7 +51,7 @@ void sh4_sched_ffts() u32 diff=-1; int slot=-1; - for (size_t i=0;i= 0 && cycles <= SH4_MAIN_CLOCK)); - list[id].start=sh4_sched_now(); + sch_list[id].start=sh4_sched_now(); if (cycles == -1) { - list[id].end = -1; + sch_list[id].end = -1; } else { - list[id].end = list[id].start + cycles; - if (list[id].end == -1) - list[id].end++; + sch_list[id].end = sch_list[id].start + cycles; + if (sch_list[id].end == -1) + sch_list[id].end++; } sh4_sched_ffts(); @@ -120,10 +120,10 @@ void sh4_sched_request(int id, int cycles) int sh4_sched_elapsed(int id) { - if (list[id].end!=-1) + if (sch_list[id].end!=-1) { - int rv=sh4_sched_now()-list[id].start; - list[id].start=sh4_sched_now(); + int rv=sh4_sched_now()-sch_list[id].start; + sch_list[id].start=sh4_sched_now(); return rv; } else @@ -132,12 +132,12 @@ int sh4_sched_elapsed(int id) void handle_cb(int id) { - int remain=list[id].end-list[id].start; + int remain=sch_list[id].end-sch_list[id].start; int elapsd=sh4_sched_elapsed(id); int jitter=elapsd-remain; - list[id].end=-1; - int re_sch=list[id].cb(list[id].tag,remain,jitter); + sch_list[id].end=-1; + int re_sch=sch_list[id].cb(sch_list[id].tag,remain,jitter); if (re_sch > 0) sh4_sched_request(id, max(0, re_sch - jitter)); @@ -156,7 +156,7 @@ void sh4_sched_tick(int cycles) sh4_sched_intr++; if (sh4_sched_next_id!=-1) { - for (int i=0;i= 0 || remaining == -1); diff --git a/core/imgread/ioctl.cpp b/core/imgread/ioctl.cpp index 4486dc99a..9dfd66b43 100644 --- a/core/imgread/ioctl.cpp +++ b/core/imgread/ioctl.cpp @@ -4,7 +4,7 @@ #include "common.h" #include -#include +#include #include #include "SCSIDEFS.H" @@ -388,4 +388,4 @@ Disc* ioctl_parse(const wchar* file) } } -#endif \ No newline at end of file +#endif diff --git a/core/input/gamepad_device.cpp b/core/input/gamepad_device.cpp index 843f18d62..82ccefdf8 100644 --- a/core/input/gamepad_device.cpp +++ b/core/input/gamepad_device.cpp @@ -51,7 +51,39 @@ bool GamepadDevice::gamepad_btn_input(u32 code, bool pressed) if (key < 0x10000) { if (pressed) + { kcode[_maple_port] &= ~(u16)key; + // Avoid two opposite dpad keys being pressed simultaneously + switch (key) + { + case DC_DPAD_UP: + kcode[_maple_port] |= (u16)DC_DPAD_DOWN; + break; + case DC_DPAD_DOWN: + kcode[_maple_port] |= (u16)DC_DPAD_UP; + break; + case DC_DPAD_LEFT: + kcode[_maple_port] |= (u16)DC_DPAD_RIGHT; + break; + case DC_DPAD_RIGHT: + kcode[_maple_port] |= (u16)DC_DPAD_LEFT; + break; + case DC_DPAD2_UP: + kcode[_maple_port] |= (u16)DC_DPAD2_DOWN; + break; + case DC_DPAD2_DOWN: + kcode[_maple_port] |= (u16)DC_DPAD2_UP; + break; + case DC_DPAD2_LEFT: + kcode[_maple_port] |= (u16)DC_DPAD2_RIGHT; + break; + case DC_DPAD2_RIGHT: + kcode[_maple_port] |= (u16)DC_DPAD2_LEFT; + break; + default: + break; + } + } else kcode[_maple_port] |= (u16)key; } diff --git a/core/linux-dist/x11.cpp b/core/linux-dist/x11.cpp index 85c6fd5f1..e053097be 100644 --- a/core/linux-dist/x11.cpp +++ b/core/linux-dist/x11.cpp @@ -84,8 +84,6 @@ Atom wmDeleteMessage; void* x11_vis; extern bool dump_frame_switch; -extern bool naomi_test_button; -extern bool coin_chute; void dc_exit(void); @@ -275,16 +273,6 @@ void input_x11_handle() x11_fullscreen = !x11_fullscreen; x11_window_set_fullscreen(x11_fullscreen); } -#if DC_PLATFORM == DC_PLATFORM_NAOMI || DC_PLATFORM == DC_PLATFORM_ATOMISWAVE - else if (e.xkey.keycode == KEY_F8) - { - coin_chute = e.type == KeyPress; - } - else if (e.xkey.keycode == KEY_F7) - { - naomi_test_button = e.type == KeyPress; - } -#endif } } break; @@ -373,6 +361,11 @@ void input_x11_init() printf("X11 Keyboard input disabled by config.\n"); } +static int x11_error_handler(Display *, XErrorEvent *) +{ + return 0; +} + void x11_window_create() { if (cfgLoadInt("pvr", "nox11", 0) == 0) @@ -531,20 +524,22 @@ void x11_window_create() GLX_CONTEXT_PROFILE_MASK_ARB, GLX_CONTEXT_CORE_PROFILE_BIT_ARB, None }; + int (*old_handler)(Display *, XErrorEvent *) = XSetErrorHandler(&x11_error_handler); x11_glc = glXCreateContextAttribsARB(x11Display, bestFbc, 0, True, context_attribs); if (!x11_glc) { printf("Open GL 4.3 not supported\n"); - // Try GL 3.1 + // Try GL 3.0 context_attribs[1] = 3; - context_attribs[3] = 1; + context_attribs[3] = 0; x11_glc = glXCreateContextAttribsARB(x11Display, bestFbc, 0, True, context_attribs); if (!x11_glc) { - die("Open GL 3.1 not supported\n"); + die("Open GL 3.0 not supported\n"); } } + XSetErrorHandler(old_handler); XSync(x11Display, False); #endif diff --git a/core/linux/common.cpp b/core/linux/common.cpp index 7b6db0f7f..ce9194436 100644 --- a/core/linux/common.cpp +++ b/core/linux/common.cpp @@ -23,10 +23,6 @@ #include #include #endif -#if HOST_OS == OS_DARWIN -#include -#include -#endif #include #include "hw/sh4/dyna/blockmanager.h" @@ -57,7 +53,6 @@ void sigill_handler(int sn, siginfo_t * si, void *segfault_ctx) { } #endif -#if !defined(TARGET_NO_EXCEPTIONS) void fault_handler (int sn, siginfo_t * si, void *segfault_ctx) { rei_host_context_t ctx; @@ -108,12 +103,9 @@ void fault_handler (int sn, siginfo_t * si, void *segfault_ctx) signal(SIGSEGV, SIG_DFL); } } -#endif -#endif -void install_fault_handler (void) +void install_fault_handler(void) { -#if !defined(TARGET_NO_EXCEPTIONS) struct sigaction act, segv_oact; memset(&act, 0, sizeof(act)); act.sa_sigaction = fault_handler; @@ -127,180 +119,14 @@ void install_fault_handler (void) act.sa_sigaction = sigill_handler; sigaction(SIGILL, &act, &segv_oact); #endif -#endif } - -#if !defined(TARGET_NO_THREADS) - -//Thread class -cThread::cThread(ThreadEntryFP* function,void* prm) -{ - Entry=function; - param=prm; -} - -void cThread::Start() -{ - verify(hThread == NULL); - if (pthread_create( (pthread_t*)&hThread, NULL, Entry, param)) - { - die("Thread creation failed"); - } -} - -void cThread::WaitToEnd() -{ - if (hThread != NULL) - { - pthread_join((pthread_t)hThread,0); - hThread = NULL; - } -} - -//End thread class -#endif - -//cResetEvent Calss -cResetEvent::cResetEvent(bool State,bool Auto) -{ - //sem_init((sem_t*)hEvent, 0, State?1:0); - verify(State==false&&Auto==true); - pthread_mutex_init(&mutx, NULL); - pthread_cond_init(&cond, NULL); -} -cResetEvent::~cResetEvent() -{ - //Destroy the event object ? - -} -void cResetEvent::Set()//Signal -{ - pthread_mutex_lock( &mutx ); - state=true; - pthread_cond_signal( &cond); - pthread_mutex_unlock( &mutx ); -} -void cResetEvent::Reset()//reset -{ - pthread_mutex_lock( &mutx ); - state=false; - pthread_mutex_unlock( &mutx ); -} -bool cResetEvent::Wait(u32 msec)//Wait for signal , then reset -{ - pthread_mutex_lock( &mutx ); - if (!state) - { - struct timespec ts; -#if HOST_OS == OS_DARWIN - // OSX doesn't have clock_gettime. - clock_serv_t cclock; - mach_timespec_t mts; - - host_get_clock_service(mach_host_self(), CALENDAR_CLOCK, &cclock); - clock_get_time(cclock, &mts); - mach_port_deallocate(mach_task_self(), cclock); - ts.tv_sec = mts.tv_sec; - ts.tv_nsec = mts.tv_nsec; -#else - clock_gettime(CLOCK_REALTIME, &ts); -#endif - ts.tv_sec += msec / 1000; - ts.tv_nsec += (msec % 1000) * 1000000; - while (ts.tv_nsec > 1000000000) - { - ts.tv_nsec -= 1000000000; - ts.tv_sec++; - } - pthread_cond_timedwait( &cond, &mutx, &ts ); - } - bool rc = state; - state=false; - pthread_mutex_unlock( &mutx ); - - return rc; -} -void cResetEvent::Wait()//Wait for signal , then reset -{ - pthread_mutex_lock( &mutx ); - if (!state) - { - pthread_cond_wait( &cond, &mutx ); - } - state=false; - pthread_mutex_unlock( &mutx ); -} - -//End AutoResetEvent +#else // !defined(TARGET_NO_EXCEPTIONS) +// No exceptions/nvmem dummy handlers. +void install_fault_handler(void) {} +#endif // !defined(TARGET_NO_EXCEPTIONS) #include -void VArray2::LockRegion(u32 offset,u32 size) -{ - #if !defined(TARGET_NO_EXCEPTIONS) - u32 inpage=offset & PAGE_MASK; - u32 rv=mprotect (data+offset-inpage, size+inpage, PROT_READ ); - if (rv!=0) - { - printf("mprotect(%8s,%08X,R) failed: %d | %d\n",data+offset-inpage,size+inpage,rv,errno); - die("mprotect failed ..\n"); - } - - #else - //printf("VA2: LockRegion\n"); - #endif -} - -void print_mem_addr() -{ - FILE *ifp, *ofp; - - char outputFilename[] = "/data/data/com.reicast.emulator/files/mem_alloc.txt"; - - ifp = fopen("/proc/self/maps", "r"); - - if (ifp == NULL) { - fprintf(stderr, "Can't open input file /proc/self/maps!\n"); - exit(1); - } - - ofp = fopen(outputFilename, "w"); - - if (ofp == NULL) { - fprintf(stderr, "Can't open output file %s!\n", - outputFilename); -#if HOST_OS == OS_LINUX - ofp = stderr; -#else - exit(1); -#endif - } - - char line [ 512 ]; - while (fgets(line, sizeof line, ifp) != NULL) { - fprintf(ofp, "%s", line); - } - - fclose(ifp); - if (ofp != stderr) - fclose(ofp); -} - -void VArray2::UnLockRegion(u32 offset,u32 size) -{ - #if !defined(TARGET_NO_EXCEPTIONS) - u32 inpage=offset & PAGE_MASK; - u32 rv=mprotect (data+offset-inpage, size+inpage, PROT_READ | PROT_WRITE); - if (rv!=0) - { - print_mem_addr(); - printf("mprotect(%8p,%08X,RW) failed: %d | %d\n",data+offset-inpage,size+inpage,rv,errno); - die("mprotect failed ..\n"); - } - #else - //printf("VA2: UnLockRegion\n"); - #endif -} double os_GetSeconds() { timeval a; diff --git a/core/linux/posix_vmem.cpp b/core/linux/posix_vmem.cpp new file mode 100644 index 000000000..3601eef1b --- /dev/null +++ b/core/linux/posix_vmem.cpp @@ -0,0 +1,178 @@ + +// Implementation of the vmem related function for POSIX-like platforms. +// There's some minimal amount of platform specific hacks to support +// Android and OSX since they are slightly different in some areas. + +// This implements the VLockedMemory interface, as defined in _vmem.h +// The implementation allows it to be empty (that is, to not lock memory). + +#include +#include +#include +#include +#include +#include + +#include "hw/mem/_vmem.h" +#include "stdclass.h" + +#ifndef MAP_NOSYNC +#define MAP_NOSYNC 0 //missing from linux :/ -- could be the cause of android slowness ? +#endif + +#ifdef _ANDROID + #include + #ifndef ASHMEM_DEVICE + #define ASHMEM_DEVICE "/dev/ashmem" + #undef PAGE_MASK + #define PAGE_MASK (PAGE_SIZE-1) +#else + #define PAGE_SIZE 4096 + #define PAGE_MASK (PAGE_SIZE-1) +#endif + +// Android specific ashmem-device stuff for creating shared memory regions +int ashmem_create_region(const char *name, size_t size) { + int fd = open(ASHMEM_DEVICE, O_RDWR); + if (fd < 0) + return -1; + + if (ioctl(fd, ASHMEM_SET_SIZE, size) < 0) { + close(fd); + return -1; + } + + return fd; +} +#endif // #ifdef _ANDROID + +void VLockedMemory::LockRegion(unsigned offset, unsigned size_bytes) { + size_t inpage = offset & PAGE_MASK; + if (mprotect(&data[offset - inpage], size_bytes + inpage, PROT_READ)) { + die("mprotect failed ..\n"); + } +} + +void VLockedMemory::UnLockRegion(unsigned offset, unsigned size_bytes) { + size_t inpage = offset & PAGE_MASK; + if (mprotect(&data[offset - inpage], size_bytes + inpage, PROT_READ|PROT_WRITE)) { + // Add some way to see why it failed? gdb> info proc mappings + die("mprotect failed ..\n"); + } +} + +// Allocates memory via a fd on shmem/ahmem or even a file on disk +static int allocate_shared_filemem() { + int fd = -1; + #if defined(_ANDROID) + // Use Android's specific shmem stuff. + fd = ashmem_create_region(0, RAM_SIZE_MAX + VRAM_SIZE_MAX + ARAM_SIZE_MAX); + #else + #if HOST_OS != OS_DARWIN + fd = shm_open("/dcnzorz_mem", O_CREAT | O_EXCL | O_RDWR,S_IREAD | S_IWRITE); + shm_unlink("/dcnzorz_mem"); + #endif + + // if shmem does not work (or using OSX) fallback to a regular file on disk + if (fd < 0) { + string path = get_writable_data_path("/dcnzorz_mem"); + fd = open(path.c_str(), O_CREAT|O_RDWR|O_TRUNC, S_IRWXU|S_IRWXG|S_IRWXO); + unlink(path.c_str()); + } + // If we can't open the file, fallback to slow mem. + if (fd < 0) + return -1; + + // Finally make the file as big as we need! + if (ftruncate(fd, RAM_SIZE_MAX + VRAM_SIZE_MAX + ARAM_SIZE_MAX)) { + // Can't get as much memory as needed, fallback. + close(fd); + return -1; + } + #endif + + return fd; +} + +// Implement vmem initialization for RAM, ARAM, VRAM and SH4 context, fpcb etc. +// The function supports allocating 512MB or 4GB addr spaces. + +static int shmem_fd = -1; + +// vmem_base_addr points to an address space of 512MB (or 4GB) that can be used for fast memory ops. +// In negative offsets of the pointer (up to FPCB size, usually 65/129MB) the context and jump table +// can be found. If the platform init returns error, the user is responsible for initializing the +// memory using a fallback (that is, regular mallocs and falling back to slow memory JIT). +VMemType vmem_platform_init(void **vmem_base_addr, void **sh4rcb_addr) { + // Firt let's try to allocate the shm-backed memory + shmem_fd = allocate_shared_filemem(); + if (shmem_fd < 0) + return MemTypeError; + + // Now try to allocate a contiguous piece of memory. + unsigned memsize = 512*1024*1024 + sizeof(Sh4RCB) + ARAM_SIZE_MAX + 0x10000; + void *first_ptr = mmap(0, memsize, PROT_NONE, MAP_PRIVATE | MAP_ANON, -1, 0); + if (!first_ptr) { + close(shmem_fd); + return MemTypeError; + } + + // Align pointer to 64KB too, some Linaro bug (no idea but let's just be safe I guess). + uintptr_t ptrint = (uintptr_t)first_ptr; + ptrint = (ptrint + 0x10000 - 1) & (~0xffff); + *sh4rcb_addr = (void*)ptrint; + *vmem_base_addr = (void*)(ptrint + sizeof(Sh4RCB)); + void *sh4rcb_base_ptr = (void*)(ptrint + FPCB_SIZE); + + // Now map the memory for the SH4 context, do not include FPCB on purpose (paged on demand). + mprotect(sh4rcb_base_ptr, sizeof(Sh4RCB) - FPCB_SIZE, PROT_READ | PROT_WRITE); + + return MemType512MB; +} + +// Just tries to wipe as much as possible in the relevant area. +void vmem_platform_destroy() { + munmap(virt_ram_base, 0x20000000); +} + +// Resets a chunk of memory by deleting its data and setting its protection back. +void vmem_platform_reset_mem(void *ptr, unsigned size_bytes) { + // Mark them as non accessible. + mprotect(ptr, size_bytes, PROT_NONE); + // Tell the kernel to flush'em all (FIXME: perhaps unmap+mmap 'd be better?) + madvise(ptr, size_bytes, MADV_DONTNEED); + #if defined(MADV_REMOVE) + madvise(ptr, size_bytes, MADV_REMOVE); + #elif defined(MADV_FREE) + madvise(ptr, size_bytes, MADV_FREE); + #endif +} + +// Allocates a bunch of memory (page aligned and page-sized) +void vmem_platform_ondemand_page(void *address, unsigned size_bytes) { + verify(!mprotect(address, size_bytes, PROT_READ | PROT_WRITE)); +} + +// Creates mappings to the underlying file including mirroring sections +void vmem_platform_create_mappings(const vmem_mapping *vmem_maps, unsigned nummaps) { + for (unsigned i = 0; i < nummaps; i++) { + // Ignore unmapped stuff, it is already reserved as PROT_NONE + if (!vmem_maps[i].memsize) + continue; + + // Calculate the number of mirrors + unsigned address_range_size = vmem_maps[i].end_address - vmem_maps[i].start_address; + unsigned num_mirrors = (address_range_size) / vmem_maps[i].memsize; + int protection = vmem_maps[i].allow_writes ? (PROT_READ | PROT_WRITE) : PROT_READ; + verify((address_range_size % vmem_maps[i].memsize) == 0 && num_mirrors >= 1); + + for (unsigned j = 0; j < num_mirrors; j++) { + unsigned offset = vmem_maps[i].start_address + j * vmem_maps[i].memsize; + verify(!munmap(&virt_ram_base[offset], vmem_maps[i].memsize)); + verify(MAP_FAILED != mmap(&virt_ram_base[offset], vmem_maps[i].memsize, protection, + MAP_SHARED | MAP_NOSYNC | MAP_FIXED, shmem_fd, vmem_maps[i].memoffset)); + // ??? (mprotect(rv,size,prot)!=0) + } + } +} + diff --git a/core/nullDC.cpp b/core/nullDC.cpp index e770b3c08..1deeebad7 100755 --- a/core/nullDC.cpp +++ b/core/nullDC.cpp @@ -134,7 +134,7 @@ void LoadSpecialSettings() safemode_game = false; tr_poly_depth_mask_game = false; extra_depth_game = false; - + if (reios_windows_ce) { printf("Enabling Extra depth scaling for Windows CE games\n"); @@ -190,7 +190,7 @@ void LoadSpecialSettings() } #elif DC_PLATFORM == DC_PLATFORM_NAOMI || DC_PLATFORM == DC_PLATFORM_ATOMISWAVE printf("Game ID is [%s]\n", naomi_game_id); - + if (!strcmp("METAL SLUG 6", naomi_game_id) || !strcmp("WAVE RUNNER GP", naomi_game_id)) { printf("Enabling Dynarec safe mode for game %s\n", naomi_game_id); @@ -213,12 +213,14 @@ void LoadSpecialSettings() printf("Enabling JVS rotary encoders for game %s\n", naomi_game_id); settings.input.JammaSetup = 2; } - else if (!strcmp("POWER STONE 2 JAPAN", naomi_game_id)) + else if (!strcmp("POWER STONE 2 JAPAN", naomi_game_id) // Naomi + || !strcmp("GUILTY GEAR isuka", naomi_game_id)) // AW { printf("Enabling 4-player setup for game %s\n", naomi_game_id); settings.input.JammaSetup = 1; } - else if (!strcmp("SEGA MARINE FISHING JAPAN", naomi_game_id)) + else if (!strcmp("SEGA MARINE FISHING JAPAN", naomi_game_id) + || !strcmp(naomi_game_id, "BASS FISHING SIMULATOR VER.A")) // AW { printf("Enabling specific JVS setup for game %s\n", naomi_game_id); settings.input.JammaSetup = 3; @@ -228,9 +230,11 @@ void LoadSpecialSettings() printf("Enabling specific JVS setup for game %s\n", naomi_game_id); settings.input.JammaSetup = 4; } - else if (!strcmp("NINJA ASSAULT", naomi_game_id)) + else if (!strcmp("NINJA ASSAULT", naomi_game_id) + || !strcmp(naomi_game_id, "Sports Shooting USA") // AW + || !strcmp(naomi_game_id, "SEGA CLAY CHALLENGE")) // AW { - printf("Enabling specific JVS setup for game %s\n", naomi_game_id); + printf("Enabling lightgun setup for game %s\n", naomi_game_id); settings.input.JammaSetup = 5; } else if (!strcmp(" BIOHAZARD GUN SURVIVOR2", naomi_game_id)) @@ -309,11 +313,12 @@ int dc_start_game(const char *path) { InitSettings(); LoadSettings(false); - settings.dreamcast.RTC = GetRTC_now(); // FIXME This shouldn't be in settings anymore #if DC_PLATFORM == DC_PLATFORM_DREAMCAST if (!settings.bios.UseReios) #endif - LoadRomFiles(get_readonly_data_path(DATA_PATH)); + if (!LoadRomFiles(get_readonly_data_path(DATA_PATH))) + return -5; + #if DC_PLATFORM == DC_PLATFORM_DREAMCAST if (path == NULL) { @@ -345,7 +350,6 @@ int dc_start_game(const char *path) return 0; } - settings.dreamcast.RTC = GetRTC_now(); // FIXME This shouldn't be in settings anymore if (settings.bios.UseReios || !LoadRomFiles(get_readonly_data_path(DATA_PATH))) { #ifdef USE_REIOS @@ -485,7 +489,6 @@ void dc_exit() void InitSettings() { - settings.dreamcast.RTC = GetRTC_now(); settings.dynarec.Enable = true; settings.dynarec.idleskip = true; settings.dynarec.unstable_opt = false; @@ -499,6 +502,7 @@ void InitSettings() settings.aica.LimitFPS = true; settings.aica.NoBatch = false; // This also controls the DSP. Disabled by default settings.aica.NoSound = false; + settings.audio.backend = "auto"; settings.rend.UseMipmaps = true; settings.rend.WideScreen = false; settings.rend.ShowFPS = false; @@ -513,6 +517,10 @@ void InitSettings() settings.rend.CustomTextures = false; settings.rend.DumpTextures = false; settings.rend.ScreenScaling = 100; + settings.rend.ScreenStretching = 100; + settings.rend.Fog = true; + settings.rend.FloatVMUs = false; + settings.rend.Rotate90 = false; settings.pvr.ta_skip = 0; settings.pvr.rend = 0; @@ -559,6 +567,7 @@ void LoadSettings(bool game_specific) { const char *config_section = game_specific ? cfgGetGameId() : "config"; const char *input_section = game_specific ? cfgGetGameId() : "input"; + const char *audio_section = game_specific ? cfgGetGameId() : "audio"; settings.dynarec.Enable = cfgLoadBool(config_section, "Dynarec.Enabled", settings.dynarec.Enable); settings.dynarec.idleskip = cfgLoadBool(config_section, "Dynarec.idleskip", settings.dynarec.idleskip); @@ -574,6 +583,7 @@ void LoadSettings(bool game_specific) settings.aica.LimitFPS = cfgLoadBool(config_section, "aica.LimitFPS", settings.aica.LimitFPS); settings.aica.NoBatch = cfgLoadBool(config_section, "aica.NoBatch", settings.aica.NoBatch); settings.aica.NoSound = cfgLoadBool(config_section, "aica.NoSound", settings.aica.NoSound); + settings.audio.backend = cfgLoadStr(audio_section, "backend", settings.audio.backend.c_str()); settings.rend.UseMipmaps = cfgLoadBool(config_section, "rend.UseMipmaps", settings.rend.UseMipmaps); settings.rend.WideScreen = cfgLoadBool(config_section, "rend.WideScreen", settings.rend.WideScreen); settings.rend.ShowFPS = cfgLoadBool(config_section, "rend.ShowFPS", settings.rend.ShowFPS); @@ -595,6 +605,10 @@ void LoadSettings(bool game_specific) settings.rend.DumpTextures = cfgLoadBool(config_section, "rend.DumpTextures", settings.rend.DumpTextures); settings.rend.ScreenScaling = cfgLoadInt(config_section, "rend.ScreenScaling", settings.rend.ScreenScaling); settings.rend.ScreenScaling = min(max(1, settings.rend.ScreenScaling), 100); + settings.rend.ScreenStretching = cfgLoadInt(config_section, "rend.ScreenStretching", settings.rend.ScreenStretching); + settings.rend.Fog = cfgLoadBool(config_section, "rend.Fog", settings.rend.Fog); + settings.rend.FloatVMUs = cfgLoadBool(config_section, "rend.FloatVMUs", settings.rend.FloatVMUs); + settings.rend.Rotate90 = cfgLoadBool(config_section, "rend.Rotate90", settings.rend.Rotate90); settings.pvr.ta_skip = cfgLoadInt(config_section, "ta.skip", settings.pvr.ta_skip); settings.pvr.rend = cfgLoadInt(config_section, "pvr.rend", settings.pvr.rend); @@ -706,6 +720,27 @@ void SaveSettings() cfgSaveBool("config", "aica.LimitFPS", settings.aica.LimitFPS); cfgSaveBool("config", "aica.NoBatch", settings.aica.NoBatch); cfgSaveBool("config", "aica.NoSound", settings.aica.NoSound); + cfgSaveStr("audio", "backend", settings.audio.backend.c_str()); + + // Write backend specific settings + // std::map> + for (std::map>::iterator it = settings.audio.options.begin(); it != settings.audio.options.end(); ++it) + { + + std::pair> p = (std::pair>)*it; + std::string section = p.first; + std::map options = p.second; + + for (std::map::iterator it2 = options.begin(); it2 != options.end(); ++it2) + { + std::pair p2 = (std::pair)*it2; + std::string key = p2.first; + std::string val = p2.second; + + cfgSaveStr(section.c_str(), key.c_str(), val.c_str()); + } + } + cfgSaveBool("config", "rend.WideScreen", settings.rend.WideScreen); cfgSaveBool("config", "rend.ShowFPS", settings.rend.ShowFPS); if (!rtt_to_buffer_game || !settings.rend.RenderToTextureBuffer) @@ -718,6 +753,10 @@ void SaveSettings() cfgSaveBool("config", "rend.CustomTextures", settings.rend.CustomTextures); cfgSaveBool("config", "rend.DumpTextures", settings.rend.DumpTextures); cfgSaveInt("config", "rend.ScreenScaling", settings.rend.ScreenScaling); + cfgSaveInt("config", "rend.ScreenStretching", settings.rend.ScreenStretching); + cfgSaveBool("config", "rend.Fog", settings.rend.Fog); + cfgSaveBool("config", "rend.FloatVMUs", settings.rend.FloatVMUs); + cfgSaveBool("config", "rend.Rotate90", settings.rend.Rotate90); cfgSaveInt("config", "ta.skip", settings.pvr.ta_skip); cfgSaveInt("config", "pvr.rend", settings.pvr.rend); diff --git a/core/oslib/audiobackend_alsa.cpp b/core/oslib/audiobackend_alsa.cpp index 949af077e..47c4f348c 100644 --- a/core/oslib/audiobackend_alsa.cpp +++ b/core/oslib/audiobackend_alsa.cpp @@ -1,4 +1,4 @@ -#include "oslib/audiobackend_alsa.h" +#include "oslib/audiostream.h" #if USE_ALSA #include #include "cfg/cfg.h" @@ -18,30 +18,43 @@ static void alsa_init() string device = cfgLoadStr("alsa", "device", ""); int rc = -1; - if (device == "") + if (device == "" || device == "auto") { printf("ALSA: trying to determine audio device\n"); - /* Open PCM device for playback. */ + + // trying default device device = "default"; rc = snd_pcm_open(&handle, device.c_str(), SND_PCM_STREAM_PLAYBACK, 0); + // "default" didn't work, try first device if (rc < 0) { device = "plughw:0,0,0"; rc = snd_pcm_open(&handle, device.c_str(), SND_PCM_STREAM_PLAYBACK, 0); + + if (rc < 0) + { + device = "plughw:0,0"; + rc = snd_pcm_open(&handle, device.c_str(), SND_PCM_STREAM_PLAYBACK, 0); + } } + // first didn't work, try second if (rc < 0) { - device = "plughw:0,0"; + device = "plughw:1,0"; rc = snd_pcm_open(&handle, device.c_str(), SND_PCM_STREAM_PLAYBACK, 0); } - if (rc >= 0) + // try pulse audio backend + if (rc < 0) { - // init successfull, write value back to config - cfgSaveStr("alsa", "device", device.c_str()); + device = "pulse"; + rc = snd_pcm_open(&handle, device.c_str(), SND_PCM_STREAM_PLAYBACK, 0); } + + if (rc < 0) + printf("ALSA: unable to automatically determine audio device.\n"); } else { rc = snd_pcm_open(&handle, device.c_str(), SND_PCM_STREAM_PLAYBACK, 0); @@ -49,7 +62,7 @@ static void alsa_init() if (rc < 0) { - fprintf(stderr, "unable to open PCM device %s: %s\n", device.c_str(), snd_strerror(rc)); + fprintf(stderr, "ALSA: unable to open PCM device %s: %s\n", device.c_str(), snd_strerror(rc)); return; } @@ -62,7 +75,7 @@ static void alsa_init() rc=snd_pcm_hw_params_any(handle, params); if (rc < 0) { - fprintf(stderr, "Error:snd_pcm_hw_params_any %s\n", snd_strerror(rc)); + fprintf(stderr, "ALSA: Error:snd_pcm_hw_params_any %s\n", snd_strerror(rc)); return; } @@ -72,7 +85,7 @@ static void alsa_init() rc=snd_pcm_hw_params_set_access(handle, params, SND_PCM_ACCESS_RW_INTERLEAVED); if (rc < 0) { - fprintf(stderr, "Error:snd_pcm_hw_params_set_access %s\n", snd_strerror(rc)); + fprintf(stderr, "ALSA: Error:snd_pcm_hw_params_set_access %s\n", snd_strerror(rc)); return; } @@ -80,7 +93,7 @@ static void alsa_init() rc=snd_pcm_hw_params_set_format(handle, params, SND_PCM_FORMAT_S16_LE); if (rc < 0) { - fprintf(stderr, "Error:snd_pcm_hw_params_set_format %s\n", snd_strerror(rc)); + fprintf(stderr, "ALSA: Error:snd_pcm_hw_params_set_format %s\n", snd_strerror(rc)); return; } @@ -88,7 +101,7 @@ static void alsa_init() rc=snd_pcm_hw_params_set_channels(handle, params, 2); if (rc < 0) { - fprintf(stderr, "Error:snd_pcm_hw_params_set_channels %s\n", snd_strerror(rc)); + fprintf(stderr, "ALSA: Error:snd_pcm_hw_params_set_channels %s\n", snd_strerror(rc)); return; } @@ -97,7 +110,7 @@ static void alsa_init() rc=snd_pcm_hw_params_set_rate_near(handle, params, &val, &dir); if (rc < 0) { - fprintf(stderr, "Error:snd_pcm_hw_params_set_rate_near %s\n", snd_strerror(rc)); + fprintf(stderr, "ALSA: Error:snd_pcm_hw_params_set_rate_near %s\n", snd_strerror(rc)); return; } @@ -106,26 +119,31 @@ static void alsa_init() rc=snd_pcm_hw_params_set_period_size_near(handle, params, &period_size, &dir); if (rc < 0) { - fprintf(stderr, "Error:snd_pcm_hw_params_set_buffer_size_near %s\n", snd_strerror(rc)); + fprintf(stderr, "ALSA: Error:snd_pcm_hw_params_set_buffer_size_near %s\n", snd_strerror(rc)); return; } else + { printf("ALSA: period size set to %ld\n", period_size); + } + buffer_size = (44100 * 100 /* settings.omx.Audio_Latency */ / 1000 / period_size + 1) * period_size; rc=snd_pcm_hw_params_set_buffer_size_near(handle, params, &buffer_size); if (rc < 0) { - fprintf(stderr, "Error:snd_pcm_hw_params_set_buffer_size_near %s\n", snd_strerror(rc)); + fprintf(stderr, "ALSA: Error:snd_pcm_hw_params_set_buffer_size_near %s\n", snd_strerror(rc)); return; } else + { printf("ALSA: buffer size set to %ld\n", buffer_size); + } /* Write the parameters to the driver */ rc = snd_pcm_hw_params(handle, params); if (rc < 0) { - fprintf(stderr, "Unable to set hw parameters: %s\n", snd_strerror(rc)); + fprintf(stderr, "ALSA: Unable to set hw parameters: %s\n", snd_strerror(rc)); return; } } @@ -175,11 +193,84 @@ static void alsa_term() snd_pcm_close(handle); } -audiobackend_t audiobackend_alsa = { +std::vector alsa_get_devicelist() +{ + std::vector result; + + char **hints; + int err = snd_device_name_hint(-1, "pcm", (void***)&hints); + + // Error initializing ALSA + if (err != 0) + return result; + + // special value to automatically detect on initialization + result.push_back("auto"); + + char** n = hints; + while (*n != NULL) + { + // Get the type (NULL/Input/Output) + char *type = snd_device_name_get_hint(*n, "IOID"); + char *name = snd_device_name_get_hint(*n, "NAME"); + + if (name != NULL) + { + // We only want output or special devices (like "default" or "pulse") + // TODO Only those with type == NULL? + if (type == NULL || strcmp(type, "Output") == 0) + { + // TODO Check if device works (however we need to hash the resulting list then) + /*snd_pcm_t *handle; + int rc = snd_pcm_open(&handle, name, SND_PCM_STREAM_PLAYBACK, 0); + + if (rc == 0) + { + result.push_back(name); + snd_pcm_close(handle); + } + */ + + result.push_back(name); + } + + } + + if (type != NULL) + free(type); + + if (name != NULL) + free(name); + + n++; + } + + snd_device_name_free_hint((void**)hints); + + return result; +} + +static audio_option_t* alsa_audio_options(int* option_count) +{ + *option_count = 1; + static audio_option_t result[1]; + + result[0].cfg_name = "device"; + result[0].caption = "Device"; + result[0].type = list; + result[0].list_callback = alsa_get_devicelist; + + return result; +} + +static audiobackend_t audiobackend_alsa = { "alsa", // Slug "Advanced Linux Sound Architecture", // Name &alsa_init, &alsa_push, - &alsa_term + &alsa_term, + &alsa_audio_options }; + +static bool alsa = RegisterAudioBackend(&audiobackend_alsa); #endif diff --git a/core/oslib/audiobackend_alsa.h b/core/oslib/audiobackend_alsa.h deleted file mode 100644 index 3995cb1ac..000000000 --- a/core/oslib/audiobackend_alsa.h +++ /dev/null @@ -1,4 +0,0 @@ -#pragma once -#include "oslib/audiostream.h" - -extern audiobackend_t audiobackend_alsa; diff --git a/core/oslib/audiobackend_android.h b/core/oslib/audiobackend_android.h deleted file mode 100644 index c2765c14b..000000000 --- a/core/oslib/audiobackend_android.h +++ /dev/null @@ -1,4 +0,0 @@ -#pragma once -#include "oslib/audiostream.h" - -extern audiobackend_t audiobackend_android; \ No newline at end of file diff --git a/core/oslib/audiobackend_coreaudio.cpp b/core/oslib/audiobackend_coreaudio.cpp index 9ce685cd9..4f7cb44a8 100644 --- a/core/oslib/audiobackend_coreaudio.cpp +++ b/core/oslib/audiobackend_coreaudio.cpp @@ -1,18 +1,18 @@ /* Simple Core Audio backend for osx (and maybe ios?) Based off various audio core samples and dolphin's code - + This is part of the Reicast project, please consult the LICENSE file for licensing & related information - + This could do with some locking logic to avoid race conditions, and some variable length buffer logic to support chunk sizes other than 512 bytes - + It does work on my macmini though */ -#include "oslib/audiobackend_coreaudio.h" +#include "oslib/audiostream.h" #if HOST_OS == OS_DARWIN #include @@ -28,7 +28,7 @@ static u8 samples_temp[BUFSIZE]; static std::atomic samples_wptr; static std::atomic samples_rptr; -static cResetEvent bufferEmpty(false, true); +static cResetEvent bufferEmpty; static OSStatus coreaudio_callback(void* ctx, AudioUnitRenderActionFlags* flags, const AudioTimeStamp* ts, UInt32 bus, UInt32 frames, AudioBufferList* abl) @@ -49,9 +49,9 @@ static OSStatus coreaudio_callback(void* ctx, AudioUnitRenderActionFlags* flags, samples_rptr = (samples_rptr + buf_size) % BUFSIZE; } } - + bufferEmpty.Set(); - + return noErr; } @@ -63,7 +63,7 @@ static void coreaudio_init() AudioStreamBasicDescription format; AudioComponentDescription desc; AudioComponent component; - + desc.componentType = kAudioUnitType_Output; #if !defined(TARGET_IPHONE) desc.componentSubType = kAudioUnitSubType_DefaultOutput; @@ -75,12 +75,12 @@ static void coreaudio_init() desc.componentFlagsMask = 0; desc.componentManufacturer = kAudioUnitManufacturer_Apple; component = AudioComponentFindNext(nullptr, &desc); - + verify(component != nullptr); - + err = AudioComponentInstanceNew(component, &audioUnit); verify(err == noErr); - + FillOutASBDForLPCM(format, 44100, 2, 16, 16, false, false, false); err = AudioUnitSetProperty(audioUnit, @@ -88,7 +88,7 @@ static void coreaudio_init() kAudioUnitScope_Input, 0, &format, sizeof(AudioStreamBasicDescription)); verify(err == noErr); - + callback_struct.inputProc = coreaudio_callback; callback_struct.inputProcRefCon = 0; err = AudioUnitSetProperty(audioUnit, @@ -96,24 +96,24 @@ static void coreaudio_init() kAudioUnitScope_Input, 0, &callback_struct, sizeof callback_struct); verify(err == noErr); - + /* err = AudioUnitSetParameter(audioUnit, kHALOutputParam_Volume, kAudioUnitParameterFlag_Output, 0, 1, 0); verify(err == noErr); - + */ - + err = AudioUnitInitialize(audioUnit); - + verify(err == noErr); - + err = AudioOutputUnitStart(audioUnit); verify(err == noErr); - + bufferEmpty.Set(); } @@ -134,23 +134,23 @@ static u32 coreaudio_push(void* frame, u32 samples, bool wait) samples_wptr = (samples_wptr + byte_size) % BUFSIZE; break; } - + return 1; } static void coreaudio_term() { OSStatus err; - + err = AudioOutputUnitStop(audioUnit); verify(err == noErr); - + err = AudioUnitUninitialize(audioUnit); verify(err == noErr); - + err = AudioComponentInstanceDispose(audioUnit); verify(err == noErr); - + bufferEmpty.Set(); } @@ -159,6 +159,10 @@ audiobackend_t audiobackend_coreaudio = { "Core Audio", // Name &coreaudio_init, &coreaudio_push, - &coreaudio_term + &coreaudio_term, + NULL }; + +static bool core = RegisterAudioBackend(&audiobackend_coreaudio); + #endif diff --git a/core/oslib/audiobackend_coreaudio.h b/core/oslib/audiobackend_coreaudio.h deleted file mode 100644 index 8f3172317..000000000 --- a/core/oslib/audiobackend_coreaudio.h +++ /dev/null @@ -1,5 +0,0 @@ -#pragma once -#include "oslib/audiostream.h" - -extern audiobackend_t audiobackend_coreaudio; - diff --git a/core/oslib/audiobackend_directsound.cpp b/core/oslib/audiobackend_directsound.cpp index 36a4d692c..f004bdfd2 100644 --- a/core/oslib/audiobackend_directsound.cpp +++ b/core/oslib/audiobackend_directsound.cpp @@ -1,4 +1,4 @@ -#include "oslib/audiobackend_directsound.h" +#include "oslib/audiostream.h" #if HOST_OS==OS_WINDOWS #include "oslib.h" #include @@ -19,31 +19,31 @@ static void directsound_init() verifyc(dsound->SetCooperativeLevel((HWND)libPvr_GetRenderTarget(),DSSCL_PRIORITY)); IDirectSoundBuffer* buffer_; - WAVEFORMATEX wfx; - DSBUFFERDESC desc; + WAVEFORMATEX wfx; + DSBUFFERDESC desc; - // Set up WAV format structure. + // Set up WAV format structure. - memset(&wfx, 0, sizeof(WAVEFORMATEX)); - wfx.wFormatTag = WAVE_FORMAT_PCM; - wfx.nChannels = 2; - wfx.nSamplesPerSec = 44100; - wfx.nBlockAlign = 4; - wfx.nAvgBytesPerSec = wfx.nSamplesPerSec * wfx.nBlockAlign; - wfx.wBitsPerSample = 16; + memset(&wfx, 0, sizeof(WAVEFORMATEX)); + wfx.wFormatTag = WAVE_FORMAT_PCM; + wfx.nChannels = 2; + wfx.nSamplesPerSec = 44100; + wfx.nBlockAlign = 4; + wfx.nAvgBytesPerSec = wfx.nSamplesPerSec * wfx.nBlockAlign; + wfx.wBitsPerSample = 16; - // Set up DSBUFFERDESC structure. + // Set up DSBUFFERDESC structure. ds_ring_size=8192*wfx.nBlockAlign; - memset(&desc, 0, sizeof(DSBUFFERDESC)); - desc.dwSize = sizeof(DSBUFFERDESC); - desc.dwFlags = DSBCAPS_GETCURRENTPOSITION2 | DSBCAPS_CTRLPOSITIONNOTIFY;// _CTRLPAN | DSBCAPS_CTRLVOLUME | DSBCAPS_CTRLFREQUENCY; - - desc.dwBufferBytes = ds_ring_size; - desc.lpwfxFormat = &wfx; + memset(&desc, 0, sizeof(DSBUFFERDESC)); + desc.dwSize = sizeof(DSBUFFERDESC); + desc.dwFlags = DSBCAPS_GETCURRENTPOSITION2 | DSBCAPS_CTRLPOSITIONNOTIFY;// _CTRLPAN | DSBCAPS_CTRLVOLUME | DSBCAPS_CTRLFREQUENCY; + + desc.dwBufferBytes = ds_ring_size; + desc.lpwfxFormat = &wfx; + - if (settings.aica.HW_mixing==0) { @@ -71,7 +71,7 @@ static void directsound_init() //Play the buffer ! verifyc(buffer->Play(0,0,DSBPLAY_LOOPING)); - + } @@ -159,7 +159,7 @@ static u32 directsound_push(void* frame, u32 samples, bool wait) wait &= w; */ int ffs=1; - + /* while (directsound_IsAudioBufferedLots() && wait) if (ffs == 0) @@ -175,7 +175,7 @@ static u32 directsound_push(void* frame, u32 samples, bool wait) static void directsound_term() { buffer->Stop(); - + buffer->Release(); dsound->Release(); } @@ -185,6 +185,9 @@ audiobackend_t audiobackend_directsound = { "Microsoft DirectSound", // Name &directsound_init, &directsound_push, - &directsound_term + &directsound_term, + NULL }; + +static bool ds = RegisterAudioBackend(&audiobackend_directsound); #endif diff --git a/core/oslib/audiobackend_directsound.h b/core/oslib/audiobackend_directsound.h deleted file mode 100644 index 544ba629d..000000000 --- a/core/oslib/audiobackend_directsound.h +++ /dev/null @@ -1,4 +0,0 @@ -#pragma once -#include "oslib/audiostream.h" - -extern audiobackend_t audiobackend_directsound; diff --git a/core/oslib/audiobackend_libao.cpp b/core/oslib/audiobackend_libao.cpp index 1445c1492..0a6a72e7d 100644 --- a/core/oslib/audiobackend_libao.cpp +++ b/core/oslib/audiobackend_libao.cpp @@ -1,4 +1,4 @@ -#include "oslib/audiobackend_libao.h" +#include "oslib/audiostream.h" #ifdef USE_LIBAO #include @@ -10,12 +10,12 @@ static void libao_init() { ao_initialize(); memset(&aoformat, 0, sizeof(aoformat)); - + aoformat.bits = 16; aoformat.channels = 2; aoformat.rate = 44100; aoformat.byte_format = AO_FMT_LITTLE; - + aodevice = ao_open_live(ao_default_driver_id(), &aoformat, NULL); // Live output if (!aodevice) aodevice = ao_open_live(ao_driver_id("null"), &aoformat, NULL); @@ -23,13 +23,13 @@ static void libao_init() static u32 libao_push(void* frame, u32 samples, bool wait) { - if (aodevice) + if (aodevice) ao_play(aodevice, (char*)frame, samples * 4); - + return 1; } -static void libao_term() +static void libao_term() { if (aodevice) { @@ -43,7 +43,9 @@ audiobackend_t audiobackend_libao = { "libao", // Name &libao_init, &libao_push, - &libao_term + &libao_term, + NULL }; +static bool ao = RegisterAudioBackend(&audiobackend_libao); #endif diff --git a/core/oslib/audiobackend_libao.h b/core/oslib/audiobackend_libao.h deleted file mode 100644 index 5bf957286..000000000 --- a/core/oslib/audiobackend_libao.h +++ /dev/null @@ -1,4 +0,0 @@ -#pragma once -#include "oslib/audiostream.h" - -extern audiobackend_t audiobackend_libao; diff --git a/core/oslib/audiobackend_omx.cpp b/core/oslib/audiobackend_omx.cpp index ffb0779a9..c8c8a6536 100644 --- a/core/oslib/audiobackend_omx.cpp +++ b/core/oslib/audiobackend_omx.cpp @@ -1,4 +1,4 @@ -#include "oslib/audiobackend_omx.h" +#include "oslib/audiostream.h" #if USE_OMX #include @@ -313,7 +313,9 @@ audiobackend_t audiobackend_omx = { "OpenMAX IL", // Name &omx_init, &omx_push, - &omx_term + &omx_term, + NULL }; +static bool omx = RegisterAudioBackend(&audiobackend_omx); #endif diff --git a/core/oslib/audiobackend_omx.h b/core/oslib/audiobackend_omx.h deleted file mode 100644 index 63fdcb5fd..000000000 --- a/core/oslib/audiobackend_omx.h +++ /dev/null @@ -1,4 +0,0 @@ -#pragma once -#include "oslib/audiostream.h" - -extern audiobackend_t audiobackend_omx; diff --git a/core/oslib/audiobackend_oss.cpp b/core/oslib/audiobackend_oss.cpp index 67015db6c..b3a48cbd6 100644 --- a/core/oslib/audiobackend_oss.cpp +++ b/core/oslib/audiobackend_oss.cpp @@ -1,4 +1,4 @@ -#include "oslib/audiobackend_oss.h" +#include "oslib/audiostream.h" #ifdef USE_OSS #include #include @@ -48,7 +48,9 @@ audiobackend_t audiobackend_oss = { "Open Sound System", // Name &oss_init, &oss_push, - &oss_term + &oss_term, + NULL }; +static bool oss = RegisterAudioBackend(&audiobackend_oss); #endif diff --git a/core/oslib/audiobackend_oss.h b/core/oslib/audiobackend_oss.h deleted file mode 100644 index cfeb53955..000000000 --- a/core/oslib/audiobackend_oss.h +++ /dev/null @@ -1,4 +0,0 @@ -#pragma once -#include "oslib/audiostream.h" - -extern audiobackend_t audiobackend_oss; diff --git a/core/oslib/audiobackend_pulseaudio.cpp b/core/oslib/audiobackend_pulseaudio.cpp index dea4256cc..b651b4003 100644 --- a/core/oslib/audiobackend_pulseaudio.cpp +++ b/core/oslib/audiobackend_pulseaudio.cpp @@ -1,4 +1,4 @@ -#include "oslib/audiobackend_pulseaudio.h" +#include "oslib/audiostream.h" #ifdef USE_PULSEAUDIO #include #include @@ -43,6 +43,9 @@ audiobackend_t audiobackend_pulseaudio = { "PulseAudio", // Name &pulseaudio_init, &pulseaudio_push, - &pulseaudio_term + &pulseaudio_term, + NULL }; + +static bool pulse = RegisterAudioBackend(&audiobackend_pulseaudio); #endif diff --git a/core/oslib/audiobackend_pulseaudio.h b/core/oslib/audiobackend_pulseaudio.h deleted file mode 100644 index 7948d5b16..000000000 --- a/core/oslib/audiobackend_pulseaudio.h +++ /dev/null @@ -1,4 +0,0 @@ -#pragma once -#include "oslib/audiostream.h" - -extern audiobackend_t audiobackend_pulseaudio; diff --git a/core/oslib/audiobackend_sdl2.cpp b/core/oslib/audiobackend_sdl2.cpp new file mode 100644 index 000000000..39d2e8464 --- /dev/null +++ b/core/oslib/audiobackend_sdl2.cpp @@ -0,0 +1,136 @@ + +#if defined(USE_SDL_AUDIO) + +#include +#include "oslib/audiostream.h" +#include "stdclass.h" + +static SDL_AudioDeviceID audiodev; +static bool needs_resampling; +static cResetEvent read_wait; +static cMutex stream_mutex; +static struct { + uint32_t prevs; + uint32_t sample_buffer[2048]; +} audiobuf; +static unsigned sample_count = 0; + +// To easily access samples. +union Sample { int16_t s[2]; uint32_t l; }; + +static float InterpolateCatmull4pt3oX(float x0, float x1, float x2, float x3, float t) { + return 0.45 * ((2 * x1) + t * ((-x0 + x2) + t * ((2 * x0 - 5 * x1 + 4 * x2 - x3) + t * (-x0 + 3 * x1 - 3 * x2 + x3)))); +} + +static void sdl2_audiocb(void* userdata, Uint8* stream, int len) { + stream_mutex.Lock(); + // Wait until there's enough samples to feed the kraken + unsigned oslen = len / sizeof(uint32_t); + unsigned islen = needs_resampling ? oslen * 16 / 17 : oslen; + unsigned minlen = needs_resampling ? islen + 2 : islen; // Resampler looks ahead by 2 samples. + + if (sample_count < minlen) { + // No data, just output a bit of silence for the underrun + memset(stream, 0, len); + stream_mutex.Unlock(); + read_wait.Set(); + return; + } + + if (!needs_resampling) { + // Just copy bytes for this case. + memcpy(stream, &audiobuf.sample_buffer[0], len); + } + else { + // 44.1KHz to 48KHz (actually 46.86KHz) resampling + uint32_t *outbuf = (uint32_t*)stream; + const float ra = 1.0f / 17; + Sample *sbuf = (Sample*)&audiobuf.sample_buffer[0]; // [-1] stores the previous iteration last sample output + for (int i = 0; i < islen/16; i++) { + *outbuf++ = sbuf[i*16+ 0].l; // First sample stays at the same location. + for (int k = 1; k < 17; k++) { + Sample r; + // Note we access offset -1 on first iteration, as to access prevs + r.s[0] = InterpolateCatmull4pt3oX(sbuf[i*16+k-2].s[0], sbuf[i*16+k-1].s[0], sbuf[i*16+k].s[0], sbuf[i*16+k+1].s[0], 1 - ra*k); + r.s[1] = InterpolateCatmull4pt3oX(sbuf[i*16+k-2].s[1], sbuf[i*16+k-1].s[1], sbuf[i*16+k].s[1], sbuf[i*16+k+1].s[1], 1 - ra*k); + *outbuf++ = r.l; + } + } + audiobuf.prevs = audiobuf.sample_buffer[islen-1]; + } + + // Move samples in the buffer and consume them + memmove(&audiobuf.sample_buffer[0], &audiobuf.sample_buffer[islen], (sample_count-islen)*sizeof(uint32_t)); + sample_count -= islen; + + stream_mutex.Unlock(); + read_wait.Set(); +} + +static void sdl2_audio_init() { + if (!SDL_WasInit(SDL_INIT_AUDIO)) + SDL_InitSubSystem(SDL_INIT_AUDIO); + + // Support 44.1KHz (native) but also upsampling to 48KHz + SDL_AudioSpec wav_spec, out_spec; + memset(&wav_spec, 0, sizeof(wav_spec)); + wav_spec.freq = 44100; + wav_spec.format = AUDIO_S16; + wav_spec.channels = 2; + wav_spec.samples = 1024; // Must be power of two + wav_spec.callback = sdl2_audiocb; + + // Try 44.1KHz which should be faster since it's native. + audiodev = SDL_OpenAudioDevice(NULL, 0, &wav_spec, &out_spec, 0); + if (!audiodev) { + needs_resampling = true; + wav_spec.freq = 48000; + audiodev = SDL_OpenAudioDevice(NULL, 0, &wav_spec, &out_spec, 0); + verify(audiodev); + } +} + +static u32 sdl2_audio_push(void* frame, u32 samples, bool wait) { + // Unpause the device shall it be paused. + if (SDL_GetAudioDeviceStatus(audiodev) != SDL_AUDIO_PLAYING) + SDL_PauseAudioDevice(audiodev, 0); + + // If wait, then wait for the buffer to be smaller than a certain size. + stream_mutex.Lock(); + if (wait) { + while (sample_count + samples > sizeof(audiobuf.sample_buffer)/sizeof(audiobuf.sample_buffer[0])) { + stream_mutex.Unlock(); + read_wait.Wait(); + read_wait.Reset(); + stream_mutex.Lock(); + } + } + + // Copy as many samples as possible, drop any remaining (this should not happen usually) + unsigned free_samples = sizeof(audiobuf.sample_buffer) / sizeof(audiobuf.sample_buffer[0]) - sample_count; + unsigned tocopy = samples < free_samples ? samples : free_samples; + memcpy(&audiobuf.sample_buffer[sample_count], frame, tocopy * sizeof(uint32_t)); + sample_count += tocopy; + stream_mutex.Unlock(); + + return 1; +} + +static void sdl2_audio_term() { + // Stop audio playback. + SDL_PauseAudioDevice(audiodev, 1); + read_wait.Set(); +} + +audiobackend_t audiobackend_sdl2audio = { + "sdl2", // Slug + "Simple DirectMedia Layer 2 Audio", // Name + &sdl2_audio_init, + &sdl2_audio_push, + &sdl2_audio_term +}; + +static bool sdl2audiobe = RegisterAudioBackend(&audiobackend_sdl2audio); + +#endif + diff --git a/core/oslib/audiostream.cpp b/core/oslib/audiostream.cpp index f89e783fb..1d6f4f079 100644 --- a/core/oslib/audiostream.cpp +++ b/core/oslib/audiostream.cpp @@ -2,14 +2,6 @@ #include "cfg/cfg.h" #include "oslib/oslib.h" #include "audiostream.h" -#include "oslib/audiobackend_directsound.h" -#include "oslib/audiobackend_android.h" -#include "oslib/audiobackend_alsa.h" -#include "oslib/audiobackend_oss.h" -#include "oslib/audiobackend_pulseaudio.h" -#include "oslib/audiobackend_coreaudio.h" -#include "oslib/audiobackend_omx.h" -#include "oslib/audiobackend_libao.h" struct SoundFrame { s16 l;s16 r; }; #define SAMPLE_COUNT 512 @@ -25,16 +17,27 @@ u32 gen_samples=0; double time_diff = 128/44100.0; double time_last; + #ifdef LOG_SOUND +// TODO Only works on Windows! WaveWriter rawout("d:\\aica_out.wav"); #endif -static bool audiobackends_registered = false; static unsigned int audiobackends_num_max = 1; static unsigned int audiobackends_num_registered = 0; -static audiobackend_t **audiobackends = static_cast(calloc(audiobackends_num_max, sizeof(audiobackend_t*))); +static audiobackend_t **audiobackends = NULL; static audiobackend_t *audiobackend_current = NULL; +u32 GetAudioBackendCount() +{ + return audiobackends_num_registered; +} + +audiobackend_t* GetAudioBackend(int num) +{ + return audiobackends[num]; +} + bool RegisterAudioBackend(audiobackend_t *backend) { /* This function announces the availability of an audio backend to reicast. */ @@ -44,10 +47,16 @@ bool RegisterAudioBackend(audiobackend_t *backend) printf("ERROR: Tried to register invalid audio backend (NULL pointer).\n"); return false; } + if (backend->slug == "auto" || backend->slug == "none") { printf("ERROR: Tried to register invalid audio backend (slug \"%s\" is a reserved keyword).\n", backend->slug.c_str()); return false; } + + // First call to RegisterAudioBackend(), create the backend structure; + if (audiobackends == NULL) + audiobackends = static_cast(calloc(audiobackends_num_max, sizeof(audiobackend_t*))); + // Check if we need to allocate addition memory for storing the pointers and allocate if neccessary if (audiobackends_num_registered == audiobackends_num_max) { @@ -67,46 +76,19 @@ bool RegisterAudioBackend(audiobackend_t *backend) } audiobackends = new_ptr; } + audiobackends[audiobackends_num_registered] = backend; audiobackends_num_registered++; return true; } -void RegisterAllAudioBackends() { - #if HOST_OS==OS_WINDOWS - RegisterAudioBackend(&audiobackend_directsound); - #endif - #if ANDROID - RegisterAudioBackend(&audiobackend_android); - #endif - #if USE_OMX - RegisterAudioBackend(&audiobackend_omx); - #endif - #if USE_ALSA - RegisterAudioBackend(&audiobackend_alsa); - #endif - #if USE_OSS - RegisterAudioBackend(&audiobackend_oss); - #endif - #if USE_PULSEAUDIO - RegisterAudioBackend(&audiobackend_pulseaudio); - #endif - #if USE_LIBAO - RegisterAudioBackend(&audiobackend_libao); - #endif - #if HOST_OS == OS_DARWIN - RegisterAudioBackend(&audiobackend_coreaudio); - #endif - audiobackends_registered = true; -} - -static audiobackend_t* GetAudioBackend(std::string slug) +audiobackend_t* GetAudioBackend(std::string slug) { if (slug == "none") { printf("WARNING: Audio backend set to \"none\"!\n"); } - else if(audiobackends_num_registered > 0) + else if (audiobackends_num_registered > 0) { if (slug == "auto") { @@ -135,7 +117,8 @@ static audiobackend_t* GetAudioBackend(std::string slug) return NULL; } -u32 PushAudio(void* frame, u32 amt, bool wait) { +u32 PushAudio(void* frame, u32 amt, bool wait) +{ if (audiobackend_current != NULL) { return audiobackend_current->push(frame, amt, wait); } @@ -151,11 +134,13 @@ u32 asRingUsedCount() //s32 sz=(WritePtr+1)%RingBufferSampleCount-ReadPtr; //return sz<0?sz+RingBufferSampleCount:sz; } + u32 asRingFreeCount() { return RingBufferSampleCount-asRingUsedCount(); } +extern double mspdf; void WriteSample(s16 r, s16 l) { const u32 ptr=(WritePtr+1)%RingBufferSampleCount; @@ -165,7 +150,30 @@ void WriteSample(s16 r, s16 l) if (WritePtr==(SAMPLE_COUNT-1)) { - PushAudio(RingBuffer,SAMPLE_COUNT,settings.aica.LimitFPS); + bool do_wait = settings.aica.LimitFPS && (mspdf <= 11); + + PushAudio(RingBuffer,SAMPLE_COUNT, do_wait); + } +} + +static bool backends_sorted = false; +void SortAudioBackends() +{ + if (backends_sorted) + return; + + // Sort backends by slug + for (int n = audiobackends_num_registered; n > 0; n--) + { + for (int i = 0; i < n-1; i++) + { + if (audiobackends[i]->slug > audiobackends[i+1]->slug) + { + audiobackend_t* swap = audiobackends[i]; + audiobackends[i] = audiobackends[i+1]; + audiobackends[i+1] = swap; + } + } } } @@ -176,26 +184,24 @@ void InitAudio() return; } - cfgSaveInt("audio","disable",0); - - if (!audiobackends_registered) { - //FIXME: There might some nicer way to do this. - RegisterAllAudioBackends(); - } + cfgSaveInt("audio", "disable", 0); if (audiobackend_current != NULL) { printf("ERROR: The audio backend \"%s\" (%s) has already been initialized, you need to terminate it before you can call audio_init() again!\n", audiobackend_current->slug.c_str(), audiobackend_current->name.c_str()); return; } - string audiobackend_slug = cfgLoadStr("audio", "backend", "auto"); // FIXME: This could be made a parameter + SortAudioBackends(); + + string audiobackend_slug = settings.audio.backend; audiobackend_current = GetAudioBackend(audiobackend_slug); if (audiobackend_current == NULL) { printf("WARNING: Running without audio!\n"); return; } + printf("Initializing audio backend \"%s\" (%s)...\n", audiobackend_current->slug.c_str(), audiobackend_current->name.c_str()); - audiobackend_current->init(); + audiobackend_current->init(); } void TermAudio() @@ -204,5 +210,5 @@ void TermAudio() audiobackend_current->term(); printf("Terminating audio backend \"%s\" (%s)...\n", audiobackend_current->slug.c_str(), audiobackend_current->name.c_str()); audiobackend_current = NULL; - } + } } diff --git a/core/oslib/audiostream.h b/core/oslib/audiostream.h index b700eb066..408592b55 100644 --- a/core/oslib/audiostream.h +++ b/core/oslib/audiostream.h @@ -1,5 +1,6 @@ #pragma once #include "types.h" +#include //Get used size in the ring buffer u32 asRingUsedCount(); @@ -10,6 +11,29 @@ u32 asRingFreeCount(); bool asRingRead(u8* dst,u32 count=0); void UpdateBuff(u8* pos); +typedef std::vector (*audio_option_callback_t)(); +enum audio_option_type +{ + integer = 0 +, checkbox = 1 +, list = 2 +}; + +typedef struct { + std::string cfg_name; + std::string caption; + audio_option_type type; + + // type int_value (spin edit) + int min_value; + int max_value; + + // type list edit (string/char*) + audio_option_callback_t list_callback; +} audio_option_t; + +typedef audio_option_t* (*audio_options_func_t)(int* option_count); + typedef void (*audio_backend_init_func_t)(); typedef u32 (*audio_backend_push_func_t)(void*, u32, bool); typedef void (*audio_backend_term_func_t)(); @@ -19,8 +43,14 @@ typedef struct { audio_backend_init_func_t init; audio_backend_push_func_t push; audio_backend_term_func_t term; + audio_options_func_t get_options; } audiobackend_t; extern bool RegisterAudioBackend(audiobackend_t* backend); extern void InitAudio(); extern u32 PushAudio(void* frame, u32 amt, bool wait); extern void TermAudio(); + +u32 GetAudioBackendCount(); +void SortAudioBackends(); +audiobackend_t* GetAudioBackend(int num); +audiobackend_t* GetAudioBackend(std::string slug); diff --git a/core/rec-ARM64/rec_arm64.cpp b/core/rec-ARM64/rec_arm64.cpp index b30720796..2a9108349 100644 --- a/core/rec-ARM64/rec_arm64.cpp +++ b/core/rec-ARM64/rec_arm64.cpp @@ -1420,9 +1420,12 @@ private: std::vector call_fregs; Arm64RegAlloc regalloc; RuntimeBlockInfo* block; + const int write_memory_rewrite_size = 3; // same size (fast write) for any size: add, bfc, str + #ifdef EXPLODE_SPANS const int read_memory_rewrite_size = 6; // worst case for u64: add, bfc, ldr, fmov, lsr, fmov - // FIXME rewrite size per read/write size? - const int write_memory_rewrite_size = 3; + #else + const int read_memory_rewrite_size = 4; // worst case for u64: add, bfc, ldr, str + #endif }; static Arm64Assembler* compiler; diff --git a/core/rec-x64/msvc.asm b/core/rec-x64/msvc.asm new file mode 100644 index 000000000..4562cbdd2 --- /dev/null +++ b/core/rec-x64/msvc.asm @@ -0,0 +1,61 @@ +_TEXT SEGMENT + +SH4_TIMESLICE = 448 +CPU_RUNNING = 135266148 +PC = 135266120 + +EXTERN bm_GetCode2: PROC +EXTERN UpdateSystem_INTC: PROC +EXTERN cycle_counter: dword +EXTERN p_sh4rcb: qword + +PUBLIC ngen_mainloop +ngen_mainloop PROC + + push rbx + push rbp + push rdi + push rsi + push r12 + push r13 + push r14 + push r15 + sub rsp, 40 ; 32-byte shadow space + 8 for stack 16-byte alignment + + mov dword ptr [cycle_counter], SH4_TIMESLICE + +run_loop: + mov rax, qword ptr [p_sh4rcb] + mov edx, dword ptr[CPU_RUNNING + rax] + test edx, edx + je end_run_loop + +slice_loop: + mov rax, qword ptr [p_sh4rcb] + mov ecx, dword ptr[PC + rax] + call bm_GetCode2 + call rax + mov ecx, dword ptr [cycle_counter] + test ecx, ecx + jg slice_loop + + add ecx, SH4_TIMESLICE + mov dword ptr [cycle_counter], ecx + call UpdateSystem_INTC + jmp run_loop + +end_run_loop: + + add rsp, 40 + pop r15 + pop r14 + pop r13 + pop r12 + pop rsi + pop rdi + pop rbp + pop rbx + ret +ngen_mainloop ENDP +_TEXT ENDS +END diff --git a/core/rec-x64/rec_x64.cpp b/core/rec-x64/rec_x64.cpp index b80df57ee..5717f73b1 100644 --- a/core/rec-x64/rec_x64.cpp +++ b/core/rec-x64/rec_x64.cpp @@ -32,7 +32,9 @@ struct DynaRBI : RuntimeBlockInfo } }; -int cycle_counter; +extern "C" { + int cycle_counter; +} double host_cpu_time; u64 guest_cpu_cycles; @@ -76,6 +78,8 @@ static __attribute((used)) void end_slice() #error RAM_SIZE_MAX unknown #endif +#ifndef _MSC_VER + #ifdef _WIN32 // Fully naked function in win32 for proper SEH prologue __asm__ ( @@ -177,6 +181,7 @@ WIN32_ONLY( ".seh_pushreg %r14 \n\t") } #endif +#endif // !_MSC_VER #undef _U #undef _S diff --git a/core/rec-x86/rec_x86_driver.cpp b/core/rec-x86/rec_x86_driver.cpp index 1d19a46fa..727cf4eee 100644 --- a/core/rec-x86/rec_x86_driver.cpp +++ b/core/rec-x86/rec_x86_driver.cpp @@ -326,8 +326,8 @@ void ngen_Compile(RuntimeBlockInfo* block, SmcCheckEnum smc_checks, bool reset, if (prof.enable) { - if (force_checks) - x86e->Emit(op_add32,&prof.counters.blkrun.force_check,1); + //if (force_checks) + // x86e->Emit(op_add32,&prof.counters.blkrun.force_check,1); x86e->Emit(op_add32,&prof.counters.blkrun.cycles[block->guest_cycles],1); } diff --git a/core/rend/TexCache.cpp b/core/rend/TexCache.cpp index b0480c273..df904ed22 100644 --- a/core/rend/TexCache.cpp +++ b/core/rend/TexCache.cpp @@ -124,8 +124,7 @@ void palette_update() using namespace std; vector VramLocks[VRAM_SIZE/PAGE_SIZE]; -//vram 32-64b -VArray2 vram; +VLockedMemory vram; // vram 32-64b //List functions // @@ -207,7 +206,7 @@ vram_block* libCore_vramlock_Lock(u32 start_offset64,u32 end_offset64,void* user { vramlist_lock.Lock(); - vram.LockRegion(block->start,block->len); + vram.LockRegion(block->start, block->len); //TODO: Fix this for 32M wrap as well if (_nvmem_enabled() && VRAM_SIZE == 0x800000) { diff --git a/core/rend/d3d11/d3d11.cpp b/core/rend/d3d11/d3d11.cpp index bf059af21..974ac94e8 100644 --- a/core/rend/d3d11/d3d11.cpp +++ b/core/rend/d3d11/d3d11.cpp @@ -1,6 +1,6 @@ #include -#include "hw\pvr\Renderer_if.h" -#include "oslib\oslib.h" +#include "hw/pvr/Renderer_if.h" +#include "oslib/oslib.h" #pragma comment(lib,"d3d11.lib") @@ -102,4 +102,4 @@ struct d3d11 : Renderer Renderer* rend_D3D11() { return new d3d11(); -} \ No newline at end of file +} diff --git a/core/rend/gl4/abuffer.cpp b/core/rend/gl4/abuffer.cpp index b09cc962d..7e9b67c64 100644 --- a/core/rend/gl4/abuffer.cpp +++ b/core/rend/gl4/abuffer.cpp @@ -331,23 +331,23 @@ void initABuffer() { char source[16384]; sprintf(source, final_shader_source, 1); - gl4CompilePipelineShader(&g_abuffer_final_shader, source); + gl4CompilePipelineShader(&g_abuffer_final_shader, false, source); } if (g_abuffer_final_nosort_shader.program == 0) { char source[16384]; sprintf(source, final_shader_source, 0); - gl4CompilePipelineShader(&g_abuffer_final_nosort_shader, source); + gl4CompilePipelineShader(&g_abuffer_final_nosort_shader, false, source); } if (g_abuffer_clear_shader.program == 0) - gl4CompilePipelineShader(&g_abuffer_clear_shader, clear_shader_source); + gl4CompilePipelineShader(&g_abuffer_clear_shader, false, clear_shader_source); if (g_abuffer_tr_modvol_shaders[0].program == 0) { char source[16384]; for (int mode = 0; mode < ModeCount; mode++) { sprintf(source, tr_modvol_shader_source, mode); - gl4CompilePipelineShader(&g_abuffer_tr_modvol_shaders[mode], source); + gl4CompilePipelineShader(&g_abuffer_tr_modvol_shaders[mode], false, source); } } @@ -417,6 +417,17 @@ void termABuffer() glDeleteBuffers(1, &g_quadBuffer); g_quadBuffer = 0; } + glcache.DeleteProgram(g_abuffer_final_shader.program); + g_abuffer_final_shader.program = 0; + glcache.DeleteProgram(g_abuffer_final_nosort_shader.program); + g_abuffer_final_nosort_shader.program = 0; + glcache.DeleteProgram(g_abuffer_clear_shader.program); + g_abuffer_clear_shader.program = 0; + for (int mode = 0; mode < ModeCount; mode++) + { + glcache.DeleteProgram(g_abuffer_tr_modvol_shaders[mode].program); + g_abuffer_tr_modvol_shaders[mode].program = 0; + } } void reshapeABuffer(int w, int h) diff --git a/core/rend/gl4/gl4.h b/core/rend/gl4/gl4.h index 7abc1db20..4c3ca82ac 100755 --- a/core/rend/gl4/gl4.h +++ b/core/rend/gl4/gl4.h @@ -1,6 +1,6 @@ #pragma once #include "rend/gles/gles.h" -#include +#include void gl4DrawStrips(GLuint output_fbo); @@ -44,7 +44,8 @@ struct gl4_ctx GLuint extra_depth_scale; } modvol_shader; - std::map shaders; + std::unordered_map shaders; + bool rotate90; struct { @@ -53,16 +54,6 @@ struct gl4_ctx GLuint modvol_vao; GLuint tr_poly_params; } vbo; - - gl4PipelineShader *getShader(int programId) { - gl4PipelineShader *shader = shaders[programId]; - if (shader == NULL) { - shader = new gl4PipelineShader(); - shaders[programId] = shader; - shader->program = -1; - } - return shader; - } }; extern gl4_ctx gl4; @@ -76,7 +67,8 @@ bool gl4_render_output_framebuffer(); void abufferDrawQuad(bool upsideDown = false, float x = 0.f, float y = 0.f, float w = 0.f, float h = 0.f); extern const char *gl4PixelPipelineShader; -bool gl4CompilePipelineShader(gl4PipelineShader* s, const char *source = gl4PixelPipelineShader); +bool gl4CompilePipelineShader(gl4PipelineShader* s, bool rotate_90, const char *source = gl4PixelPipelineShader); +void gl4_delete_shaders(); extern GLuint stencilTexId; extern GLuint depthTexId; diff --git a/core/rend/gl4/gldraw.cpp b/core/rend/gl4/gldraw.cpp index 3342325d7..dfa403a19 100644 --- a/core/rend/gl4/gldraw.cpp +++ b/core/rend/gl4/gldraw.cpp @@ -45,10 +45,15 @@ static GLuint texSamplers[2]; static GLuint depth_fbo; GLuint depthSaveTexId; -static int gl4GetProgramID(u32 cp_AlphaTest, u32 pp_ClipTestMode, +static gl4PipelineShader *gl4GetProgram(u32 cp_AlphaTest, u32 pp_ClipTestMode, u32 pp_Texture, u32 pp_UseAlpha, u32 pp_IgnoreTexA, u32 pp_ShadInstr, u32 pp_Offset, u32 pp_FogCtrl, bool pp_TwoVolumes, u32 pp_DepthFunc, bool pp_Gouraud, bool pp_BumpMap, bool fog_clamping, int pass) { + if (settings.rend.Rotate90 != gl4.rotate90) + { + gl4_delete_shaders(); + gl4.rotate90 = settings.rend.Rotate90; + } u32 rv=0; rv|=pp_ClipTestMode; @@ -66,45 +71,27 @@ static int gl4GetProgramID(u32 cp_AlphaTest, u32 pp_ClipTestMode, rv <<= 1; rv |= fog_clamping; rv <<= 2; rv |= pass; - return rv; -} - -static void setCurrentShader(u32 cp_AlphaTest, u32 pp_ClipTestMode, - u32 pp_Texture, u32 pp_UseAlpha, u32 pp_IgnoreTexA, u32 pp_ShadInstr, u32 pp_Offset, - u32 pp_FogCtrl, bool pp_TwoVolumes, u32 pp_DepthFunc, bool pp_Gouraud, bool pp_BumpMap, bool fog_clamping, int pass) -{ - int shaderId = gl4GetProgramID(cp_AlphaTest, - pp_ClipTestMode + 1, - pp_Texture, - pp_UseAlpha, - pp_IgnoreTexA, - pp_ShadInstr, - pp_Offset, - pp_FogCtrl, - pp_TwoVolumes, - pp_DepthFunc, - pp_Gouraud, - pp_BumpMap, - fog_clamping, - pass); - CurrentShader = gl4.getShader(shaderId); - if (CurrentShader->program == -1) { - CurrentShader->cp_AlphaTest = cp_AlphaTest; - CurrentShader->pp_ClipTestMode = pp_ClipTestMode; - CurrentShader->pp_Texture = pp_Texture; - CurrentShader->pp_UseAlpha = pp_UseAlpha; - CurrentShader->pp_IgnoreTexA = pp_IgnoreTexA; - CurrentShader->pp_ShadInstr = pp_ShadInstr; - CurrentShader->pp_Offset = pp_Offset; - CurrentShader->pp_FogCtrl = pp_FogCtrl; - CurrentShader->pp_TwoVolumes = pp_TwoVolumes; - CurrentShader->pp_DepthFunc = pp_DepthFunc; - CurrentShader->pp_Gouraud = pp_Gouraud; - CurrentShader->pp_BumpMap = pp_BumpMap; - CurrentShader->fog_clamping = fog_clamping; - CurrentShader->pass = pass; - gl4CompilePipelineShader(CurrentShader); + gl4PipelineShader *shader = &gl4.shaders[rv]; + if (shader->program == 0) + { + shader->cp_AlphaTest = cp_AlphaTest; + shader->pp_ClipTestMode = pp_ClipTestMode; + shader->pp_Texture = pp_Texture; + shader->pp_UseAlpha = pp_UseAlpha; + shader->pp_IgnoreTexA = pp_IgnoreTexA; + shader->pp_ShadInstr = pp_ShadInstr; + shader->pp_Offset = pp_Offset; + shader->pp_FogCtrl = pp_FogCtrl; + shader->pp_TwoVolumes = pp_TwoVolumes; + shader->pp_DepthFunc = pp_DepthFunc; + shader->pp_Gouraud = pp_Gouraud; + shader->pp_BumpMap = pp_BumpMap; + shader->fog_clamping = fog_clamping; + shader->pass = pass; + gl4CompilePipelineShader(shader, settings.rend.Rotate90); } + + return shader; } static void SetTextureRepeatMode(int index, GLuint dir, u32 clamp, u32 mirror) @@ -132,7 +119,7 @@ template if (pass == 0) { - setCurrentShader(Type == ListType_Punch_Through ? 1 : 0, + CurrentShader = gl4GetProgram(Type == ListType_Punch_Through ? 1 : 0, clipping, Type == ListType_Punch_Through ? gp->pcw.Texture : 0, 1, @@ -153,6 +140,8 @@ template bool two_volumes_mode = (gp->tsp1.full != -1) && Type != ListType_Translucent; bool color_clamp = gp->tsp.ColorClamp && (pvrrc.fog_clamp_min != 0 || pvrrc.fog_clamp_max != 0xffffffff); + int fog_ctrl = settings.rend.Fog ? gp->tsp.FogCtrl : 2; + int depth_func = 0; if (Type == ListType_Translucent) { @@ -162,14 +151,14 @@ template depth_func = gp->isp.DepthMode; } - setCurrentShader(Type == ListType_Punch_Through ? 1 : 0, + CurrentShader = gl4GetProgram(Type == ListType_Punch_Through ? 1 : 0, clipping, gp->pcw.Texture, gp->tsp.UseAlpha, gp->tsp.IgnoreTexA, gp->tsp.ShadInstr, gp->pcw.Offset, - gp->tsp.FogCtrl, + fog_ctrl, two_volumes_mode, depth_func, gp->pcw.Gouraud, @@ -681,7 +670,7 @@ static void gl4_draw_quad_texture(GLuint texture, bool upsideDown, float x = 0.f ShaderUniforms.trilinear_alpha = 1.0; - setCurrentShader(0, + CurrentShader = gl4GetProgram(0, 0, 1, 0, @@ -713,11 +702,15 @@ void gl4DrawFramebuffer(float w, float h) bool gl4_render_output_framebuffer() { - glBindFramebuffer(GL_FRAMEBUFFER, 0); glViewport(0, 0, screen_width, screen_height); - if (gl.ofbo.tex == 0) + glcache.Disable(GL_SCISSOR_TEST); + if (gl.ofbo.fbo == 0) return false; - - gl4_draw_quad_texture(gl.ofbo.tex, true); + glBindFramebuffer(GL_READ_FRAMEBUFFER, gl.ofbo.fbo); + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); + glBlitFramebuffer(0, 0, gl.ofbo.width, gl.ofbo.height, + 0, 0, screen_width, screen_height, + GL_COLOR_BUFFER_BIT, GL_LINEAR); + glBindFramebuffer(GL_FRAMEBUFFER, 0); return true; } diff --git a/core/rend/gl4/gles.cpp b/core/rend/gl4/gles.cpp index 505b1d23f..4d3003569 100644 --- a/core/rend/gl4/gles.cpp +++ b/core/rend/gl4/gles.cpp @@ -14,6 +14,7 @@ static const char* VertexShaderSource = "\ #version 140 \n\ #define pp_Gouraud %d \n\ +#define ROTATE_90 %d \n\ \n\ #if pp_Gouraud == 0 \n\ #define INTERPOLATION flat \n\ @@ -56,6 +57,9 @@ void main() \n\ \n\ vpos.w = extra_depth_scale / vpos.z; \n\ vpos.z = vpos.w; \n\ +#if ROTATE_90 == 1 \n\ + vpos.xy = vec2(vpos.y, -vpos.x); \n\ +#endif \n\ vpos.xy=vpos.xy*scale.xy-scale.zw; \n\ vpos.xy*=vpos.w; \n\ gl_Position = vpos; \n\ @@ -393,11 +397,11 @@ gl4_ctx gl4; struct gl4ShaderUniforms_t gl4ShaderUniforms; -bool gl4CompilePipelineShader( gl4PipelineShader* s, const char *source /* = PixelPipelineShader */) +bool gl4CompilePipelineShader( gl4PipelineShader* s, bool rotate_90, const char *source /* = PixelPipelineShader */) { char vshader[16384]; - sprintf(vshader, VertexShaderSource, s->pp_Gouraud); + sprintf(vshader, VertexShaderSource, s->pp_Gouraud, rotate_90); char pshader[16384]; @@ -478,28 +482,45 @@ bool gl4CompilePipelineShader( gl4PipelineShader* s, const char *source /* = Pix void gl_term(); +void gl4_delete_shaders() +{ + for (auto it : gl4.shaders) + { + if (it.second.program != 0) + glcache.DeleteProgram(it.second.program); + } + gl4.shaders.clear(); + glcache.DeleteProgram(gl4.modvol_shader.program); + gl4.modvol_shader.program = 0; +} + static void gles_term(void) { - glDeleteProgram(gl4.modvol_shader.program); glDeleteBuffers(1, &gl4.vbo.geometry); gl4.vbo.geometry = 0; glDeleteBuffers(1, &gl4.vbo.modvols); glDeleteBuffers(1, &gl4.vbo.idxs); glDeleteBuffers(1, &gl4.vbo.idxs2); glDeleteBuffers(1, &gl4.vbo.tr_poly_params); - for (auto it = gl4.shaders.begin(); it != gl4.shaders.end(); it++) - { - if (it->second->program != -1) - glDeleteProgram(it->second->program); - delete it->second; - } - gl4.shaders.clear(); + gl4_delete_shaders(); glDeleteVertexArrays(1, &gl4.vbo.main_vao); glDeleteVertexArrays(1, &gl4.vbo.modvol_vao); gl_term(); } +static void create_modvol_shader() +{ + if (gl4.modvol_shader.program != 0) + return; + char vshader[16384]; + sprintf(vshader, VertexShaderSource, 1, settings.rend.Rotate90); + + gl4.modvol_shader.program=gl_CompileAndLink(vshader, ModifierVolumeShader); + gl4.modvol_shader.scale = glGetUniformLocation(gl4.modvol_shader.program, "scale"); + gl4.modvol_shader.extra_depth_scale = glGetUniformLocation(gl4.modvol_shader.program, "extra_depth_scale"); +} + static bool gl_create_resources() { if (gl4.vbo.geometry != 0) @@ -521,12 +542,7 @@ static bool gl_create_resources() gl4SetupMainVBO(); gl4SetupModvolVBO(); - char vshader[16384]; - sprintf(vshader, VertexShaderSource, 1); - - gl4.modvol_shader.program=gl_CompileAndLink(vshader, ModifierVolumeShader); - gl4.modvol_shader.scale = glGetUniformLocation(gl4.modvol_shader.program, "scale"); - gl4.modvol_shader.extra_depth_scale = glGetUniformLocation(gl4.modvol_shader.program, "extra_depth_scale"); + create_modvol_shader(); gl_load_osd_resources(); @@ -604,6 +620,7 @@ static bool RenderFrame() old_screen_scaling = settings.rend.ScreenScaling; } DoCleanup(); + create_modvol_shader(); bool is_rtt=pvrrc.isRTT; @@ -639,6 +656,8 @@ static bool RenderFrame() { scale_x=fb_scale_x; scale_y=fb_scale_y; + if (SCALER_CTL.interlace == 0 && SCALER_CTL.vscalefactor >= 0x400) + scale_y *= SCALER_CTL.vscalefactor / 0x400; //work out scaling parameters ! //Pixel doubling is on VO, so it does not affect any pixel operations @@ -662,16 +681,41 @@ static bool RenderFrame() /* Handle Dc to screen scaling */ - float screen_scaling = is_rtt ? 1.f : settings.rend.ScreenScaling / 100.f; - float dc2s_scale_h = is_rtt ? (screen_width / dc_width) : (screen_height / 480.0); - dc2s_scale_h *= screen_scaling; - float ds2s_offs_x = is_rtt ? 0 : (((screen_width * screen_scaling) - dc2s_scale_h * 640.0) / 2); + float screen_scaling = settings.rend.ScreenScaling / 100.f; + float screen_stretching = settings.rend.ScreenStretching / 100.f; - //-1 -> too much to left - gl4ShaderUniforms.scale_coefs[0] = 2.0f / (screen_width * screen_scaling / dc2s_scale_h * scale_x); - gl4ShaderUniforms.scale_coefs[1] = (is_rtt ? 2 : -2) / dc_height; // FIXME CT2 needs 480 here instead of dc_height=512 - gl4ShaderUniforms.scale_coefs[2] = 1 - 2 * ds2s_offs_x / (screen_width * screen_scaling); - gl4ShaderUniforms.scale_coefs[3] = (is_rtt ? 1 : -1); + float dc2s_scale_h; + float ds2s_offs_x; + + if (is_rtt) + { + gl4ShaderUniforms.scale_coefs[0] = 2.0f / dc_width; + gl4ShaderUniforms.scale_coefs[1] = 2.0f / dc_height; // FIXME CT2 needs 480 here instead of dc_height=512 + gl4ShaderUniforms.scale_coefs[2] = 1; + gl4ShaderUniforms.scale_coefs[3] = 1; + } + else + { + if (settings.rend.Rotate90) + { + dc2s_scale_h = screen_height / 640.0; + ds2s_offs_x = (screen_width - dc2s_scale_h * 480.0 * screen_stretching) / 2; + gl4ShaderUniforms.scale_coefs[0] = 2.0f / (screen_width / dc2s_scale_h * scale_x) * screen_stretching; + gl4ShaderUniforms.scale_coefs[1] = -2.0f / dc_width; + gl4ShaderUniforms.scale_coefs[2] = 1 - 2 * ds2s_offs_x / screen_width; + gl4ShaderUniforms.scale_coefs[3] = 1; + } + else + { + dc2s_scale_h = screen_height / 480.0; + ds2s_offs_x = (screen_width - dc2s_scale_h * 640.0 * screen_stretching) / 2; + //-1 -> too much to left + gl4ShaderUniforms.scale_coefs[0] = 2.0f / (screen_width / dc2s_scale_h * scale_x) * screen_stretching; + gl4ShaderUniforms.scale_coefs[1] = -2.0f / dc_height; + gl4ShaderUniforms.scale_coefs[2] = 1 - 2 * ds2s_offs_x / screen_width; + gl4ShaderUniforms.scale_coefs[3] = -1; + } + } gl4ShaderUniforms.extra_depth_scale = settings.rend.ExtraDepthScale; @@ -704,7 +748,7 @@ static bool RenderFrame() gl4ShaderUniforms.fog_clamp_max[2] = ((pvrrc.fog_clamp_max >> 0) & 0xFF) / 255.0f; gl4ShaderUniforms.fog_clamp_max[3] = ((pvrrc.fog_clamp_max >> 24) & 0xFF) / 255.0f; - if (fog_needs_update) + if (fog_needs_update && settings.rend.Fog) { fog_needs_update = false; UpdateFogTexture((u8 *)FOG_TABLE, GL_TEXTURE5, GL_RED); @@ -764,7 +808,7 @@ static bool RenderFrame() { if (settings.rend.ScreenScaling != 100 || gl.swap_buffer_not_preserved) { - output_fbo = init_output_framebuffer(screen_width * screen_scaling, screen_height * screen_scaling); + output_fbo = init_output_framebuffer(screen_width * screen_scaling + 0.5f, screen_height * screen_scaling + 0.5f); } else { @@ -826,22 +870,37 @@ static bool RenderFrame() float min_y = pvrrc.fb_Y_CLIP.min / scale_y; if (!is_rtt) { + if (SCALER_CTL.interlace && SCALER_CTL.vscalefactor >= 0x400) + { + // Clipping is done after scaling/filtering so account for that if enabled + height *= SCALER_CTL.vscalefactor / 0x400; + min_y *= SCALER_CTL.vscalefactor / 0x400; + } + if (settings.rend.Rotate90) + { + float t = width; + width = height; + height = t; + t = min_x; + min_x = min_y; + min_y = 640 - t - height; + } // Add x offset for aspect ratio > 4/3 - min_x = min_x * dc2s_scale_h + ds2s_offs_x; + min_x = (min_x * dc2s_scale_h * screen_stretching + ds2s_offs_x) * screen_scaling; // Invert y coordinates when rendering to screen - min_y = screen_height * screen_scaling - (min_y + height) * dc2s_scale_h; - width *= dc2s_scale_h; - height *= dc2s_scale_h; + min_y = (screen_height - (min_y + height) * dc2s_scale_h) * screen_scaling; + width *= dc2s_scale_h * screen_stretching * screen_scaling; + height *= dc2s_scale_h * screen_scaling; if (ds2s_offs_x > 0) { - float rounded_offs_x = ds2s_offs_x + 0.5f; + float scaled_offs_x = ds2s_offs_x * screen_scaling; glcache.ClearColor(0.f, 0.f, 0.f, 0.f); glcache.Enable(GL_SCISSOR_TEST); - glScissor(0, 0, rounded_offs_x, screen_height); + glScissor(0, 0, scaled_offs_x + 0.5f, screen_height * screen_scaling + 0.5f); glClear(GL_COLOR_BUFFER_BIT); - glScissor(screen_width - rounded_offs_x, 0, rounded_offs_x, screen_height); + glScissor(screen_width * screen_scaling - scaled_offs_x + 0.5f, 0, scaled_offs_x + 1.f, screen_height * screen_scaling + 0.5f); glClear(GL_COLOR_BUFFER_BIT); } } diff --git a/core/rend/gl4/gltex.cpp b/core/rend/gl4/gltex.cpp index 85a0b9430..52aba888e 100644 --- a/core/rend/gl4/gltex.cpp +++ b/core/rend/gl4/gltex.cpp @@ -1,5 +1,5 @@ #include "gl4.h" -#include "glcache.h" +#include "../gles/glcache.h" GLuint gl4BindRTT(u32 addy, u32 fbw, u32 fbh, u32 channels, u32 fmt) { diff --git a/core/rend/gles/CustomTexture.cpp b/core/rend/gles/CustomTexture.cpp index 3d8db4561..8f062d1b2 100644 --- a/core/rend/gles/CustomTexture.cpp +++ b/core/rend/gles/CustomTexture.cpp @@ -22,7 +22,11 @@ #include #include #include +#ifdef _MSC_VER +#include "dirent/dirent.h" +#else #include +#endif #include "deps/libpng/png.h" #include "reios/reios.h" @@ -46,23 +50,28 @@ void CustomTexture::LoaderThread() if (texture != NULL) { - // FIXME texture may have been deleted. Need to detect this. texture->ComputeHash(); - int width, height; - u8 *image_data = LoadCustomTexture(texture->texture_hash, width, height); - if (image_data == NULL) + if (texture->custom_image_data != NULL) { - image_data = LoadCustomTexture(texture->old_texture_hash, width, height); + delete [] texture->custom_image_data; + texture->custom_image_data = NULL; } - if (image_data != NULL) + if (!texture->dirty) { - if (texture->custom_image_data != NULL) - delete [] texture->custom_image_data; - texture->custom_width = width; - texture->custom_height = height; - texture->custom_image_data = image_data; + int width, height; + u8 *image_data = LoadCustomTexture(texture->texture_hash, width, height); + if (image_data == NULL) + { + image_data = LoadCustomTexture(texture->old_texture_hash, width, height); + } + if (image_data != NULL) + { + texture->custom_width = width; + texture->custom_height = height; + texture->custom_image_data = image_data; + } } - texture->custom_load_in_progress = false; + texture->custom_load_in_progress--; } } while (texture != NULL); @@ -140,10 +149,9 @@ u8* CustomTexture::LoadCustomTexture(u32 hash, int& width, int& height) void CustomTexture::LoadCustomTextureAsync(TextureCacheData *texture_data) { if (!Init()) - { - texture_data->custom_load_in_progress = false; return; - } + + texture_data->custom_load_in_progress++; work_queue_mutex.Lock(); work_queue.insert(work_queue.begin(), texture_data); work_queue_mutex.Unlock(); diff --git a/core/rend/gles/CustomTexture.h b/core/rend/gles/CustomTexture.h index d0847717b..fd8a00db1 100644 --- a/core/rend/gles/CustomTexture.h +++ b/core/rend/gles/CustomTexture.h @@ -29,9 +29,9 @@ public: CustomTexture() : #ifndef TARGET_NO_THREADS - loader_thread(loader_thread_func, this), + loader_thread(loader_thread_func, this) #endif - wakeup_thread(false, true) {} + {} ~CustomTexture() { Terminate(); } u8* LoadCustomTexture(u32 hash, int& width, int& height); void LoadCustomTextureAsync(TextureCacheData *texture_data); @@ -53,7 +53,7 @@ private: cThread loader_thread; #endif cResetEvent wakeup_thread; - std::vector work_queue; + std::vector work_queue; cMutex work_queue_mutex; }; diff --git a/core/rend/gles/glcache.h b/core/rend/gles/glcache.h index d7f292af9..32c73c644 100644 --- a/core/rend/gles/glcache.h +++ b/core/rend/gles/glcache.h @@ -149,6 +149,19 @@ public: return _texture_ids[--_texture_cache_size]; } + void DeleteProgram(GLuint program) + { + GLsizei shader_count; + GLuint shaders[2]; + glGetAttachedShaders(program, ARRAY_SIZE(shaders), &shader_count, shaders); + for (int i = 0; i < shader_count; i++) + glDeleteShader(shaders[i]); + + glDeleteProgram(program); + if (_program == program) + _program = 0; + } + void Reset() { _texture = 0xFFFFFFFFu; _src_blend_factor = 0xFFFFFFFFu; @@ -179,7 +192,7 @@ public: void DisableCache() { _disable_cache = true; } void EnableCache() { - _disable_cache = true; + _disable_cache = false; Reset(); } diff --git a/core/rend/gles/gldraw.cpp b/core/rend/gles/gldraw.cpp index 4d58204b8..a8d3288c3 100644 --- a/core/rend/gles/gldraw.cpp +++ b/core/rend/gles/gldraw.cpp @@ -114,13 +114,30 @@ s32 SetTileClip(u32 val, GLint uniform) csy /= scale_y; cex /= scale_x; cey /= scale_y; - float t = cey; - cey = 480 - csy; - csy = 480 - t; - float dc2s_scale_h = screen_height / 480.0f; - float ds2s_offs_x = (screen_width - dc2s_scale_h * 640) / 2; - csx = csx * dc2s_scale_h + ds2s_offs_x; - cex = cex * dc2s_scale_h + ds2s_offs_x; + float dc2s_scale_h; + float ds2s_offs_x; + float screen_stretching = settings.rend.ScreenStretching / 100.f; + + if (settings.rend.Rotate90) + { + float t = cex; + cex = cey; + cey = 640 - csx; + csx = csy; + csy = 640 - t; + dc2s_scale_h = screen_height / 640.0f; + ds2s_offs_x = (screen_width - dc2s_scale_h * 480.0 * screen_stretching) / 2; + } + else + { + float t = cey; + cey = 480 - csy; + csy = 480 - t; + dc2s_scale_h = screen_height / 480.0f; + ds2s_offs_x = (screen_width - dc2s_scale_h * 640.0 * screen_stretching) / 2; + } + csx = csx * dc2s_scale_h * screen_stretching + ds2s_offs_x; + cex = cex * dc2s_scale_h * screen_stretching + ds2s_offs_x; csy = csy * dc2s_scale_h; cey = cey * dc2s_scale_h; } @@ -173,28 +190,25 @@ __forceinline ShaderUniforms.trilinear_alpha = 1.f; bool color_clamp = gp->tsp.ColorClamp && (pvrrc.fog_clamp_min != 0 || pvrrc.fog_clamp_max != 0xffffffff); + int fog_ctrl = settings.rend.Fog ? gp->tsp.FogCtrl : 2; - CurrentShader = &gl.pogram_table[ - GetProgramID(Type == ListType_Punch_Through ? 1 : 0, - SetTileClip(gp->tileclip, -1) + 1, - gp->pcw.Texture, - gp->tsp.UseAlpha, - gp->tsp.IgnoreTexA, - gp->tsp.ShadInstr, - gp->pcw.Offset, - gp->tsp.FogCtrl, - gp->pcw.Gouraud, - gp->tcw.PixelFmt == PixelBumpMap, - color_clamp, - ShaderUniforms.trilinear_alpha != 1.f)]; + CurrentShader = GetProgram(Type == ListType_Punch_Through ? 1 : 0, + SetTileClip(gp->tileclip, -1) + 1, + gp->pcw.Texture, + gp->tsp.UseAlpha, + gp->tsp.IgnoreTexA, + gp->tsp.ShadInstr, + gp->pcw.Offset, + fog_ctrl, + gp->pcw.Gouraud, + gp->tcw.PixelFmt == PixelBumpMap, + color_clamp, + ShaderUniforms.trilinear_alpha != 1.f); - if (CurrentShader->program == -1) - CompilePipelineShader(CurrentShader); - else - { - glcache.UseProgram(CurrentShader->program); - ShaderUniforms.Set(CurrentShader); - } + glcache.UseProgram(CurrentShader->program); + if (CurrentShader->trilinear_alpha != -1) + glUniform1f(CurrentShader->trilinear_alpha, ShaderUniforms.trilinear_alpha); + SetTileClip(gp->tileclip, CurrentShader->pp_ClipTest); //This bit control which pixels are affected @@ -1124,14 +1138,8 @@ static void DrawQuad(GLuint texId, float x, float y, float w, float h, float u0, ShaderUniforms.trilinear_alpha = 1.0; - PipelineShader *shader = &gl.pogram_table[GetProgramID(0, 1, 1, 0, 1, 0, 0, 2, false, false, false, false)]; - if (shader->program == -1) - CompilePipelineShader(shader); - else - { - glcache.UseProgram(shader->program); - ShaderUniforms.Set(shader); - } + PipelineShader *shader = GetProgram(0, 1, 1, 0, 1, 0, 0, 2, false, false, false, false); + glcache.UseProgram(shader->program); glActiveTexture(GL_TEXTURE0); glcache.BindTexture(GL_TEXTURE_2D, texId); @@ -1152,17 +1160,27 @@ void DrawFramebuffer(float w, float h) bool render_output_framebuffer() { -#if HOST_OS != OS_DARWIN - //Fix this in a proper way - glBindFramebuffer(GL_FRAMEBUFFER, 0); -#endif - glViewport(0, 0, screen_width, screen_height); - if (gl.ofbo.tex == 0) - return false; - - float scl = 480.f / screen_height; - float tx = (screen_width * scl - 640.f) / 2; - DrawQuad(gl.ofbo.tex, -tx, 0, 640.f + tx * 2, 480.f, 0, 1, 1, 0); - + glcache.Disable(GL_SCISSOR_TEST); + if (gl.gl_major < 3) + { + glViewport(0, 0, screen_width, screen_height); + if (gl.ofbo.tex == 0) + return false; + glBindFramebuffer(GL_FRAMEBUFFER, 0); + float scl = 480.f / screen_height; + float tx = (screen_width * scl - 640.f) / 2; + DrawQuad(gl.ofbo.tex, -tx, 0, 640.f + tx * 2, 480.f, 0, 1, 1, 0); + } + else + { + if (gl.ofbo.fbo == 0) + return false; + glBindFramebuffer(GL_READ_FRAMEBUFFER, gl.ofbo.fbo); + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); + glBlitFramebuffer(0, 0, gl.ofbo.width, gl.ofbo.height, + 0, 0, screen_width, screen_height, + GL_COLOR_BUFFER_BIT, GL_LINEAR); + glBindFramebuffer(GL_FRAMEBUFFER, 0); + } return true; } diff --git a/core/rend/gles/gles.cpp b/core/rend/gles/gles.cpp index 3bf1ecfb7..487981db3 100644 --- a/core/rend/gles/gles.cpp +++ b/core/rend/gles/gles.cpp @@ -79,6 +79,7 @@ const char* VertexShaderSource = %s \n\ #define TARGET_GL %s \n\ #define pp_Gouraud %d \n\ +#define ROTATE_90 %d \n\ \n\ #define GLES2 0 \n\ #define GLES3 1 \n\ @@ -136,6 +137,9 @@ void main() \n\ vpos.z = vpos.w; \n\ #else \n\ vpos.z=depth_scale.x+depth_scale.y*vpos.w; \n\ +#endif \n\ +#if ROTATE_90 == 1 \n\ + vpos.xy = vec2(vpos.y, -vpos.x); \n\ #endif \n\ vpos.xy=vpos.xy*scale.xy-scale.zw; \n\ vpos.xy*=vpos.w; \n\ @@ -782,7 +786,7 @@ GLuint fogTextureId; return rv; } - #include + #include void gl_swap() { wglSwapLayerBuffers(ourWindowHandleToDeviceContext,WGL_SWAP_MAIN_PLANE); @@ -853,9 +857,20 @@ GLuint fogTextureId; extern void gl_term(); #endif +static void gl_delete_shaders() +{ + for (auto it : gl.shaders) + { + if (it.second.program != 0) + glcache.DeleteProgram(it.second.program); + } + gl.shaders.clear(); + glcache.DeleteProgram(gl.modvol_shader.program); + gl.modvol_shader.program = 0; +} + static void gles_term() { - glDeleteProgram(gl.modvol_shader.program); glDeleteBuffers(1, &gl.vbo.geometry); gl.vbo.geometry = 0; glDeleteBuffers(1, &gl.vbo.modvols); @@ -868,7 +883,7 @@ static void gles_term() gl_free_osd_resources(); free_output_framebuffer(); - memset(gl.pogram_table, 0, sizeof(gl.pogram_table)); + gl_delete_shaders(); gl_term(); } @@ -1017,10 +1032,15 @@ GLuint gl_CompileAndLink(const char* VertexShader, const char* FragmentShader) return program; } -int GetProgramID(u32 cp_AlphaTest, u32 pp_ClipTestMode, +PipelineShader *GetProgram(u32 cp_AlphaTest, u32 pp_ClipTestMode, u32 pp_Texture, u32 pp_UseAlpha, u32 pp_IgnoreTexA, u32 pp_ShadInstr, u32 pp_Offset, u32 pp_FogCtrl, bool pp_Gouraud, bool pp_BumpMap, bool fog_clamping, bool trilinear) { + if (settings.rend.Rotate90 != gl.rotate90) + { + gl_delete_shaders(); + gl.rotate90 = settings.rend.Rotate90; + } u32 rv=0; rv|=pp_ClipTestMode; @@ -1036,14 +1056,32 @@ int GetProgramID(u32 cp_AlphaTest, u32 pp_ClipTestMode, rv<<=1; rv|=fog_clamping; rv<<=1; rv|=trilinear; - return rv; + PipelineShader *shader = &gl.shaders[rv]; + if (shader->program == 0) + { + shader->cp_AlphaTest = cp_AlphaTest; + shader->pp_ClipTestMode = pp_ClipTestMode-1; + shader->pp_Texture = pp_Texture; + shader->pp_UseAlpha = pp_UseAlpha; + shader->pp_IgnoreTexA = pp_IgnoreTexA; + shader->pp_ShadInstr = pp_ShadInstr; + shader->pp_Offset = pp_Offset; + shader->pp_FogCtrl = pp_FogCtrl; + shader->pp_Gouraud = pp_Gouraud; + shader->pp_BumpMap = pp_BumpMap; + shader->fog_clamping = fog_clamping; + shader->trilinear = trilinear; + CompilePipelineShader(shader); + } + + return shader; } bool CompilePipelineShader( PipelineShader* s) { char vshader[8192]; - sprintf(vshader, VertexShaderSource, gl.glsl_version_header, gl.gl_version, s->pp_Gouraud); + sprintf(vshader, VertexShaderSource, gl.glsl_version_header, gl.gl_version, s->pp_Gouraud, settings.rend.Rotate90); char pshader[8192]; @@ -1129,13 +1167,30 @@ void gl_load_osd_resources() void gl_free_osd_resources() { - glDeleteProgram(gl.OSD_SHADER.program); + glcache.DeleteProgram(gl.OSD_SHADER.program); if (osd_tex != 0) { glcache.DeleteTextures(1, &osd_tex); osd_tex = 0; } } + +static void create_modvol_shader() +{ + if (gl.modvol_shader.program != 0) + return; + char vshader[8192]; + sprintf(vshader, VertexShaderSource, gl.glsl_version_header, gl.gl_version, 1, settings.rend.Rotate90); + char fshader[8192]; + sprintf(fshader, ModifierVolumeShader, gl.glsl_version_header, gl.gl_version); + + gl.modvol_shader.program=gl_CompileAndLink(vshader, fshader); + gl.modvol_shader.scale = glGetUniformLocation(gl.modvol_shader.program, "scale"); + gl.modvol_shader.sp_ShaderColor = glGetUniformLocation(gl.modvol_shader.program, "sp_ShaderColor"); + gl.modvol_shader.depth_scale = glGetUniformLocation(gl.modvol_shader.program, "depth_scale"); + gl.modvol_shader.extra_depth_scale = glGetUniformLocation(gl.modvol_shader.program, "extra_depth_scale"); +} + bool gl_create_resources() { if (gl.vbo.geometry != 0) @@ -1161,84 +1216,7 @@ bool gl_create_resources() glGenBuffers(1, &gl.vbo.idxs); glGenBuffers(1, &gl.vbo.idxs2); - memset(gl.pogram_table,0,sizeof(gl.pogram_table)); - - PipelineShader* dshader=0; - u32 compile=0; -#define forl(name,max) for(u32 name=0;name<=max;name++) - forl(cp_AlphaTest,1) - { - forl(pp_ClipTestMode,2) - { - forl(pp_UseAlpha,1) - { - forl(pp_Texture,1) - { - forl(pp_FogCtrl,3) - { - forl(pp_IgnoreTexA,1) - { - forl(pp_ShadInstr,3) - { - forl(pp_Offset,1) - { - forl(pp_Gouraud,1) - { - forl(pp_BumpMap,1) - { - forl(fog_clamping,1) - { - forl(trilinear,1) - { - dshader=&gl.pogram_table[GetProgramID(cp_AlphaTest,pp_ClipTestMode,pp_Texture,pp_UseAlpha,pp_IgnoreTexA, - pp_ShadInstr,pp_Offset,pp_FogCtrl, (bool)pp_Gouraud, (bool)pp_BumpMap, (bool)fog_clamping, - (bool)trilinear)]; - - dshader->cp_AlphaTest = cp_AlphaTest; - dshader->pp_ClipTestMode = pp_ClipTestMode-1; - dshader->pp_Texture = pp_Texture; - dshader->pp_UseAlpha = pp_UseAlpha; - dshader->pp_IgnoreTexA = pp_IgnoreTexA; - dshader->pp_ShadInstr = pp_ShadInstr; - dshader->pp_Offset = pp_Offset; - dshader->pp_FogCtrl = pp_FogCtrl; - dshader->pp_Gouraud = pp_Gouraud; - dshader->pp_BumpMap = pp_BumpMap; - dshader->fog_clamping = fog_clamping; - dshader->trilinear = trilinear; - dshader->program = -1; - } - } - } - } - } - } - } - } - } - } - } - } - - char vshader[8192]; - sprintf(vshader, VertexShaderSource, gl.glsl_version_header, gl.gl_version, 1); - char fshader[8192]; - sprintf(fshader, ModifierVolumeShader, gl.glsl_version_header, gl.gl_version); - - gl.modvol_shader.program=gl_CompileAndLink(vshader, fshader); - gl.modvol_shader.scale = glGetUniformLocation(gl.modvol_shader.program, "scale"); - gl.modvol_shader.sp_ShaderColor = glGetUniformLocation(gl.modvol_shader.program, "sp_ShaderColor"); - gl.modvol_shader.depth_scale = glGetUniformLocation(gl.modvol_shader.program, "depth_scale"); - gl.modvol_shader.extra_depth_scale = glGetUniformLocation(gl.modvol_shader.program, "extra_depth_scale"); - - //#define PRECOMPILE_SHADERS - #ifdef PRECOMPILE_SHADERS - for (u32 i=0;i= 0x400) + scale_y *= SCALER_CTL.vscalefactor / 0x400; //work out scaling parameters ! //Pixel doubling is on VO, so it does not affect any pixel operations @@ -1724,17 +1705,41 @@ bool RenderFrame() /* Handle Dc to screen scaling */ - float screen_scaling = is_rtt ? 1.f : settings.rend.ScreenScaling / 100.f; - float dc2s_scale_h = is_rtt ? (screen_width / dc_width) : (screen_height / 480.0); - dc2s_scale_h *= screen_scaling; - float ds2s_offs_x = is_rtt ? 0 : (((screen_width * screen_scaling) - dc2s_scale_h * 640.0) / 2); + float screen_stretching = settings.rend.ScreenStretching / 100.f; + float screen_scaling = settings.rend.ScreenScaling / 100.f; - //-1 -> too much to left - ShaderUniforms.scale_coefs[0] = 2.0f / (screen_width * screen_scaling / dc2s_scale_h * scale_x); - ShaderUniforms.scale_coefs[1]= (is_rtt ? 2 : -2) / dc_height; // FIXME CT2 needs 480 here instead of dc_height=512 - ShaderUniforms.scale_coefs[2]= 1 - 2 * ds2s_offs_x / (screen_width * screen_scaling); - ShaderUniforms.scale_coefs[3]= (is_rtt ? 1 : -1); + float dc2s_scale_h; + float ds2s_offs_x; + if (is_rtt) + { + ShaderUniforms.scale_coefs[0] = 2.0f / dc_width; + ShaderUniforms.scale_coefs[1] = 2.0f / dc_height; // FIXME CT2 needs 480 here instead of dc_height=512 + ShaderUniforms.scale_coefs[2] = 1; + ShaderUniforms.scale_coefs[3] = 1; + } + else + { + if (settings.rend.Rotate90) + { + dc2s_scale_h = screen_height / 640.0f; + ds2s_offs_x = (screen_width - dc2s_scale_h * 480.0f * screen_stretching) / 2; + ShaderUniforms.scale_coefs[0] = 2.0f / (screen_width / dc2s_scale_h * scale_x) * screen_stretching; + ShaderUniforms.scale_coefs[1] = -2.0f / dc_width; + ShaderUniforms.scale_coefs[2] = 1 - 2 * ds2s_offs_x / screen_width; + ShaderUniforms.scale_coefs[3] = 1; + } + else + { + dc2s_scale_h = screen_height / 480.0f; + ds2s_offs_x = (screen_width - dc2s_scale_h * 640.0f * screen_stretching) / 2; + ShaderUniforms.scale_coefs[0] = 2.0f / (screen_width / dc2s_scale_h * scale_x) * screen_stretching; + ShaderUniforms.scale_coefs[1] = -2.0f / dc_height; + ShaderUniforms.scale_coefs[2] = 1 - 2 * ds2s_offs_x / screen_width; + ShaderUniforms.scale_coefs[3] = -1; + } + //-1 -> too much to left + } ShaderUniforms.depth_coefs[0]=2/(vtx_max_fZ-vtx_min_fZ); ShaderUniforms.depth_coefs[1]=-vtx_min_fZ-1; @@ -1773,7 +1778,7 @@ bool RenderFrame() ShaderUniforms.fog_clamp_max[2] = ((pvrrc.fog_clamp_max >> 0) & 0xFF) / 255.0f; ShaderUniforms.fog_clamp_max[3] = ((pvrrc.fog_clamp_max >> 24) & 0xFF) / 255.0f; - if (fog_needs_update) + if (fog_needs_update && settings.rend.Fog) { fog_needs_update = false; UpdateFogTexture((u8 *)FOG_TABLE, GL_TEXTURE1, gl.fog_image_format); @@ -1787,16 +1792,12 @@ bool RenderFrame() ShaderUniforms.PT_ALPHA=(PT_ALPHA_REF&0xFF)/255.0f; -// for (u32 i=0;iprogram == -1) -// continue; -// -// glcache.UseProgram(s->program); -// -// ShaderUniforms.Set(s); -// } + for (auto it : gl.shaders) + { + glcache.UseProgram(it.second.program); + ShaderUniforms.Set(&it.second); + } + //setup render target first if (is_rtt) { @@ -1841,7 +1842,7 @@ bool RenderFrame() { if (settings.rend.ScreenScaling != 100 || gl.swap_buffer_not_preserved) { - init_output_framebuffer(screen_width * screen_scaling, screen_height * screen_scaling); + init_output_framebuffer(screen_width * screen_scaling + 0.5f, screen_height * screen_scaling + 0.5f); } else { @@ -1888,9 +1889,6 @@ bool RenderFrame() glBufferData(GL_ARRAY_BUFFER,pvrrc.modtrig.bytes(),pvrrc.modtrig.head(),GL_STREAM_DRAW); glCheck(); } - int offs_x=ds2s_offs_x+0.5f; - //this needs to be scaled - //not all scaling affects pixel operations, scale to adjust for that scale_x *= scissoring_scale_x; @@ -1909,22 +1907,37 @@ bool RenderFrame() float min_y = pvrrc.fb_Y_CLIP.min / scale_y; if (!is_rtt) { + if (SCALER_CTL.interlace && SCALER_CTL.vscalefactor >= 0x400) + { + // Clipping is done after scaling/filtering so account for that if enabled + height *= SCALER_CTL.vscalefactor / 0x400; + min_y *= SCALER_CTL.vscalefactor / 0x400; + } + if (settings.rend.Rotate90) + { + float t = width; + width = height; + height = t; + t = min_x; + min_x = min_y; + min_y = 640 - t - height; + } // Add x offset for aspect ratio > 4/3 - min_x = min_x * dc2s_scale_h + ds2s_offs_x; + min_x = (min_x * dc2s_scale_h * screen_stretching + ds2s_offs_x) * screen_scaling; // Invert y coordinates when rendering to screen - min_y = screen_height * screen_scaling - (min_y + height) * dc2s_scale_h; - width *= dc2s_scale_h; - height *= dc2s_scale_h; + min_y = (screen_height - (min_y + height) * dc2s_scale_h) * screen_scaling; + width *= dc2s_scale_h * screen_stretching * screen_scaling; + height *= dc2s_scale_h * screen_scaling; if (ds2s_offs_x > 0) { - float rounded_offs_x = ds2s_offs_x + 0.5f; + float scaled_offs_x = ds2s_offs_x * screen_scaling; glcache.ClearColor(0.f, 0.f, 0.f, 0.f); glcache.Enable(GL_SCISSOR_TEST); - glScissor(0, 0, rounded_offs_x, screen_height); + glScissor(0, 0, scaled_offs_x + 0.5f, screen_height * screen_scaling + 0.5f); glClear(GL_COLOR_BUFFER_BIT); - glScissor(screen_width - rounded_offs_x, 0, rounded_offs_x, screen_height); + glScissor(screen_width * screen_scaling - scaled_offs_x + 0.5f, 0, scaled_offs_x + 1.f, screen_height * screen_scaling + 0.5f); glClear(GL_COLOR_BUFFER_BIT); } } diff --git a/core/rend/gles/gles.h b/core/rend/gles/gles.h index 4fb98e656..6c2b892b2 100755 --- a/core/rend/gles/gles.h +++ b/core/rend/gles/gles.h @@ -1,4 +1,6 @@ #pragma once +#include +#include #include "rend/rend.h" #if (defined(GLES) && !defined(TARGET_NACL32) && HOST_OS != OS_DARWIN && !defined(USE_SDL)) || defined(_ANDROID) @@ -95,7 +97,9 @@ struct gl_ctx } modvol_shader; - PipelineShader pogram_table[24576]; + std::unordered_map shaders; + bool rotate90; + struct { GLuint program; @@ -119,6 +123,7 @@ struct gl_ctx struct { GLuint depthb; + GLuint colorb; GLuint tex; GLuint fbo; int width; @@ -178,7 +183,7 @@ void free_output_framebuffer(); void HideOSD(); void OSD_DRAW(bool clear_screen); -int GetProgramID(u32 cp_AlphaTest, u32 pp_ClipTestMode, +PipelineShader *GetProgram(u32 cp_AlphaTest, u32 pp_ClipTestMode, u32 pp_Texture, u32 pp_UseAlpha, u32 pp_IgnoreTexA, u32 pp_ShadInstr, u32 pp_Offset, u32 pp_FogCtrl, bool pp_Gouraud, bool pp_BumpMap, bool fog_clamping, bool trilinear); @@ -225,9 +230,6 @@ extern struct ShaderUniforms_t if (s->sp_FOG_COL_VERT!=-1) glUniform3fv( s->sp_FOG_COL_VERT, 1, ps_FOG_COL_VERT); - if (s->trilinear_alpha != -1) - glUniform1f(s->trilinear_alpha, trilinear_alpha); - if (s->fog_clamp_min != -1) glUniform4fv(s->fog_clamp_min, 1, fog_clamp_min); if (s->fog_clamp_max != -1) @@ -274,10 +276,10 @@ struct TextureCacheData //a texture can't be both VQ and PAL at the same time u32 texture_hash; // xxhash of texture data, used for custom textures u32 old_texture_hash; // legacy hash - u8* custom_image_data; // loaded custom image data - u32 custom_width; - u32 custom_height; - bool custom_load_in_progress; + u8* volatile custom_image_data; // loaded custom image data + volatile u32 custom_width; + volatile u32 custom_height; + std::atomic_int custom_load_in_progress; void PrintTextureName(); diff --git a/core/rend/gles/gltex.cpp b/core/rend/gles/gltex.cpp index ef6263ddc..1a3802fb7 100644 --- a/core/rend/gles/gltex.cpp +++ b/core/rend/gles/gltex.cpp @@ -296,10 +296,7 @@ void TextureCacheData::Update() } } if (settings.rend.CustomTextures) - { - custom_load_in_progress = true; custom_texture.LoadCustomTextureAsync(this); - } void *temp_tex_buffer = NULL; u32 upscaled_w = w; @@ -428,7 +425,7 @@ void TextureCacheData::UploadToGPU(GLuint textype, int width, int height, u8 *te void TextureCacheData::CheckCustomTexture() { - if (custom_image_data != NULL) + if (custom_load_in_progress == 0 && custom_image_data != NULL) { UploadToGPU(GL_UNSIGNED_BYTE, custom_width, custom_height, custom_image_data); delete [] custom_image_data; @@ -446,7 +443,7 @@ bool TextureCacheData::NeedsUpdate() { bool TextureCacheData::Delete() { - if (custom_load_in_progress) + if (custom_load_in_progress > 0) return false; if (pData) { @@ -736,11 +733,7 @@ TextureCacheData *getTextureCacheData(TSP tsp, TCW tcw) { } else //create if not existing { - TextureCacheData tfc={0}; - TexCache[key] = tfc; - - tx=TexCache.find(key); - tf=&tx->second; + tf=&TexCache[key]; tf->tsp = tsp; tf->tcw = tcw; @@ -800,11 +793,7 @@ text_info raw_GetTexture(TSP tsp, TCW tcw) } else //create if not existing { - TextureCacheData tfc = { 0 }; - TexCache[key] = tfc; - - tx = TexCache.find(key); - tf = &tx->second; + tf = &TexCache[key]; tf->tsp = tsp; tf->tcw = tcw; @@ -1007,13 +996,7 @@ GLuint init_output_framebuffer(int width, int height) { if (width != gl.ofbo.width || height != gl.ofbo.height) { - if (gl.ofbo.fbo != 0) - { - glDeleteFramebuffers(1, &gl.ofbo.fbo); - gl.ofbo.fbo = 0; - glDeleteRenderbuffers(1, &gl.ofbo.depthb); - glcache.DeleteTextures(1, &gl.ofbo.tex); - } + free_output_framebuffer(); gl.ofbo.width = width; gl.ofbo.height = height; } @@ -1037,15 +1020,25 @@ GLuint init_output_framebuffer(int width, int height) else glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, width, height); - // Create a texture for rendering to - gl.ofbo.tex = glcache.GenTexture(); - glcache.BindTexture(GL_TEXTURE_2D, gl.ofbo.tex); + if (gl.gl_major < 3) + { + // Create a texture for rendering to + gl.ofbo.tex = glcache.GenTexture(); + glcache.BindTexture(GL_TEXTURE_2D, gl.ofbo.tex); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); - glcache.TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glcache.TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glcache.TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glcache.TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); + glcache.TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glcache.TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glcache.TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glcache.TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + } + else + { + // Use a renderbuffer and glBlitFramebuffer + glGenRenderbuffers(1, &gl.ofbo.colorb); + glBindRenderbuffer(GL_RENDERBUFFER, gl.ofbo.colorb); + glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, width, height); + } // Create the framebuffer glGenFramebuffers(1, &gl.ofbo.fbo); @@ -1057,13 +1050,20 @@ GLuint init_output_framebuffer(int width, int height) if (!gl.is_gles || gl.GL_OES_packed_depth_stencil_supported) glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, gl.ofbo.depthb); - // Attach the texture to the FBO - glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, gl.ofbo.tex, 0); + // Attach the texture/renderbuffer to the FBO + if (gl.gl_major < 3) + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, gl.ofbo.tex, 0); + else + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, gl.ofbo.colorb); // Check that our FBO creation was successful GLuint uStatus = glCheckFramebufferStatus(GL_FRAMEBUFFER); verify(uStatus == GL_FRAMEBUFFER_COMPLETE); + + glcache.Disable(GL_SCISSOR_TEST); + glcache.ClearColor(0.f, 0.f, 0.f, 0.f); + glClear(GL_COLOR_BUFFER_BIT); } else glBindFramebuffer(GL_FRAMEBUFFER, gl.ofbo.fbo); @@ -1082,7 +1082,15 @@ void free_output_framebuffer() gl.ofbo.fbo = 0; glDeleteRenderbuffers(1, &gl.ofbo.depthb); gl.ofbo.depthb = 0; - glcache.DeleteTextures(1, &gl.ofbo.tex); - gl.ofbo.tex = 0; + if (gl.ofbo.tex != 0) + { + glcache.DeleteTextures(1, &gl.ofbo.tex); + gl.ofbo.tex = 0; + } + if (gl.ofbo.colorb != 0) + { + glDeleteRenderbuffers(1, &gl.ofbo.colorb); + gl.ofbo.colorb = 0; + } } } diff --git a/core/rend/gles/imgui_impl_opengl3.cpp b/core/rend/gles/imgui_impl_opengl3.cpp index 3107feaf2..4026341f1 100644 --- a/core/rend/gles/imgui_impl_opengl3.cpp +++ b/core/rend/gles/imgui_impl_opengl3.cpp @@ -67,6 +67,7 @@ #endif #include "gles.h" +#include "glcache.h" // OpenGL Data static char g_GlslVersionString[32] = ""; @@ -127,28 +128,7 @@ void ImGui_ImplOpenGL3_RenderDrawData(ImDrawData* draw_data, bool save_backgr draw_data->ScaleClipRects(io.DisplayFramebufferScale); // Backup GL state - GLenum last_active_texture; glGetIntegerv(GL_ACTIVE_TEXTURE, (GLint*)&last_active_texture); glActiveTexture(GL_TEXTURE0); - GLint last_program; glGetIntegerv(GL_CURRENT_PROGRAM, &last_program); - GLint last_texture; glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); - GLint last_sampler; glGetIntegerv(GL_SAMPLER_BINDING, &last_sampler); - GLint last_array_buffer; glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &last_array_buffer); - GLint last_vertex_array; glGetIntegerv(GL_VERTEX_ARRAY_BINDING, &last_vertex_array); -#ifdef GL_POLYGON_MODE - GLint last_polygon_mode[2]; glGetIntegerv(GL_POLYGON_MODE, last_polygon_mode); -#endif - GLint last_viewport[4]; glGetIntegerv(GL_VIEWPORT, last_viewport); - GLint last_scissor_box[4]; glGetIntegerv(GL_SCISSOR_BOX, last_scissor_box); - GLenum last_blend_src_rgb; glGetIntegerv(GL_BLEND_SRC_RGB, (GLint*)&last_blend_src_rgb); - GLenum last_blend_dst_rgb; glGetIntegerv(GL_BLEND_DST_RGB, (GLint*)&last_blend_dst_rgb); - GLenum last_blend_src_alpha; glGetIntegerv(GL_BLEND_SRC_ALPHA, (GLint*)&last_blend_src_alpha); - GLenum last_blend_dst_alpha; glGetIntegerv(GL_BLEND_DST_ALPHA, (GLint*)&last_blend_dst_alpha); - GLenum last_blend_equation_rgb; glGetIntegerv(GL_BLEND_EQUATION_RGB, (GLint*)&last_blend_equation_rgb); - GLenum last_blend_equation_alpha; glGetIntegerv(GL_BLEND_EQUATION_ALPHA, (GLint*)&last_blend_equation_alpha); - GLboolean last_enable_blend = glIsEnabled(GL_BLEND); - GLboolean last_enable_cull_face = glIsEnabled(GL_CULL_FACE); - GLboolean last_enable_depth_test = glIsEnabled(GL_DEPTH_TEST); - GLboolean last_enable_scissor_test = glIsEnabled(GL_SCISSOR_TEST); bool clip_origin_lower_left = true; #ifdef GL_CLIP_ORIGIN if (gl.gl_major >= 4 && glClipControl != NULL) @@ -167,13 +147,13 @@ void ImGui_ImplOpenGL3_RenderDrawData(ImDrawData* draw_data, bool save_backgr // (Re-)create the background texture and reserve space for it if (g_BackgroundTexture != 0) - glDeleteTextures(1, &g_BackgroundTexture); - glGenTextures(1, &g_BackgroundTexture); - glBindTexture(GL_TEXTURE_2D, g_BackgroundTexture); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glcache.DeleteTextures(1, &g_BackgroundTexture); + g_BackgroundTexture = glcache.GenTexture(); + glcache.BindTexture(GL_TEXTURE_2D, g_BackgroundTexture); + glcache.TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glcache.TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glcache.TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glcache.TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, fb_width, fb_height, 0, GL_RGB, GL_UNSIGNED_BYTE, (GLvoid*)NULL); // Copy the current framebuffer into it @@ -182,12 +162,12 @@ void ImGui_ImplOpenGL3_RenderDrawData(ImDrawData* draw_data, bool save_backgr } // Setup render state: alpha-blending enabled, no face culling, no depth testing, scissor enabled, polygon fill - glEnable(GL_BLEND); + glcache.Enable(GL_BLEND); glBlendEquation(GL_FUNC_ADD); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glDisable(GL_CULL_FACE); - glDisable(GL_DEPTH_TEST); - glEnable(GL_SCISSOR_TEST); + glcache.BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glcache.Disable(GL_CULL_FACE); + glcache.Disable(GL_DEPTH_TEST); + glcache.Enable(GL_SCISSOR_TEST); #ifdef GL_POLYGON_MODE if (glPolygonMode != NULL) glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); @@ -207,7 +187,7 @@ void ImGui_ImplOpenGL3_RenderDrawData(ImDrawData* draw_data, bool save_backgr { 0.0f, 0.0f, -1.0f, 0.0f }, { (R+L)/(L-R), (T+B)/(B-T), 0.0f, 1.0f }, }; - glUseProgram(g_ShaderHandle); + glcache.UseProgram(g_ShaderHandle); glUniform1i(g_AttribLocationTex, 0); glUniformMatrix4fv(g_AttribLocationProjMtx, 1, GL_FALSE, &ortho_projection[0][0]); #if !defined(GLES) || defined(_ANDROID) @@ -265,7 +245,7 @@ void ImGui_ImplOpenGL3_RenderDrawData(ImDrawData* draw_data, bool save_backgr glScissor((int)clip_rect.x, (int)clip_rect.y, (int)clip_rect.z, (int)clip_rect.w); // Support for GL 4.5's glClipControl(GL_UPPER_LEFT) // Bind texture, Draw - glBindTexture(GL_TEXTURE_2D, (GLuint)(intptr_t)pcmd->TextureId); + glcache.BindTexture(GL_TEXTURE_2D, (GLuint)(intptr_t)pcmd->TextureId); glDrawElements(GL_TRIANGLES, (GLsizei)pcmd->ElemCount, sizeof(ImDrawIdx) == 2 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT, idx_buffer_offset); } } @@ -276,31 +256,6 @@ void ImGui_ImplOpenGL3_RenderDrawData(ImDrawData* draw_data, bool save_backgr if (vao_handle != 0) glDeleteVertexArrays(1, &vao_handle); #endif - // Restore modified GL state - glUseProgram(last_program); - glBindTexture(GL_TEXTURE_2D, last_texture); -#if !defined(GLES) || defined(_ANDROID) - if (gl.gl_major >= 3 && glBindSampler != NULL) - glBindSampler(0, last_sampler); -#endif - glActiveTexture(last_active_texture); - glBindBuffer(GL_ARRAY_BUFFER, last_array_buffer); -#if !defined(GLES) || defined(_ANDROID) - if (gl.gl_major >= 3) - glBindVertexArray(last_vertex_array); -#endif - glBlendEquationSeparate(last_blend_equation_rgb, last_blend_equation_alpha); - glBlendFuncSeparate(last_blend_src_rgb, last_blend_dst_rgb, last_blend_src_alpha, last_blend_dst_alpha); - if (last_enable_blend) glEnable(GL_BLEND); else glDisable(GL_BLEND); - if (last_enable_cull_face) glEnable(GL_CULL_FACE); else glDisable(GL_CULL_FACE); - if (last_enable_depth_test) glEnable(GL_DEPTH_TEST); else glDisable(GL_DEPTH_TEST); - if (last_enable_scissor_test) glEnable(GL_SCISSOR_TEST); else glDisable(GL_SCISSOR_TEST); -#ifdef GL_POLYGON_MODE - if (glPolygonMode != NULL) - glPolygonMode(GL_FRONT_AND_BACK, (GLenum)last_polygon_mode[0]); -#endif - glViewport(last_viewport[0], last_viewport[1], (GLsizei)last_viewport[2], (GLsizei)last_viewport[3]); - glScissor(last_scissor_box[0], last_scissor_box[1], (GLsizei)last_scissor_box[2], (GLsizei)last_scissor_box[3]); } bool ImGui_ImplOpenGL3_CreateFontsTexture() @@ -312,21 +267,16 @@ bool ImGui_ImplOpenGL3_CreateFontsTexture() io.Fonts->GetTexDataAsRGBA32(&pixels, &width, &height); // Load as RGBA 32-bits (75% of the memory is wasted, but default font is so small) because it is more likely to be compatible with user's existing shaders. If your ImTextureId represent a higher-level concept than just a GL texture id, consider calling GetTexDataAsAlpha8() instead to save on GPU memory. // Upload texture to graphics system - GLint last_texture; - glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); - glGenTextures(1, &g_FontTexture); - glBindTexture(GL_TEXTURE_2D, g_FontTexture); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + g_FontTexture = glcache.GenTexture(); + glcache.BindTexture(GL_TEXTURE_2D, g_FontTexture); + glcache.TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glcache.TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels); // Store our identifier io.Fonts->TexID = (ImTextureID)(intptr_t)g_FontTexture; - // Restore state - glBindTexture(GL_TEXTURE_2D, last_texture); - return true; } @@ -335,7 +285,7 @@ void ImGui_ImplOpenGL3_DestroyFontsTexture() if (g_FontTexture) { ImGuiIO& io = ImGui::GetIO(); - glDeleteTextures(1, &g_FontTexture); + glcache.DeleteTextures(1, &g_FontTexture); io.Fonts->TexID = 0; g_FontTexture = 0; } @@ -377,14 +327,8 @@ static bool CheckProgram(GLuint handle, const char* desc) return (GLboolean)status == GL_TRUE; } -bool ImGui_ImplOpenGL3_CreateDeviceObjects() +bool ImGui_ImplOpenGL3_CreateDeviceObjects() { - // Backup GL state - GLint last_texture, last_array_buffer, last_vertex_array; - glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); - glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &last_array_buffer); - glGetIntegerv(GL_VERTEX_ARRAY_BINDING, &last_vertex_array); - // Parse GLSL version string int glsl_version = 130; sscanf(g_GlslVersionString, "#version %d", &glsl_version); @@ -544,14 +488,6 @@ bool ImGui_ImplOpenGL3_CreateDeviceObjects() ImGui_ImplOpenGL3_CreateFontsTexture(); - // Restore modified GL state - glBindTexture(GL_TEXTURE_2D, last_texture); - glBindBuffer(GL_ARRAY_BUFFER, last_array_buffer); -#if !defined(GLES) || defined(_ANDROID) - if (gl.gl_major >= 3) - glBindVertexArray(last_vertex_array); -#endif - return true; } @@ -561,26 +497,23 @@ void ImGui_ImplOpenGL3_DestroyDeviceObjects() if (g_ElementsHandle) glDeleteBuffers(1, &g_ElementsHandle); g_VboHandle = g_ElementsHandle = 0; - if (g_ShaderHandle && g_VertHandle) glDetachShader(g_ShaderHandle, g_VertHandle); - if (g_VertHandle) glDeleteShader(g_VertHandle); + glcache.DeleteProgram(g_ShaderHandle); g_VertHandle = 0; - - if (g_ShaderHandle && g_FragHandle) glDetachShader(g_ShaderHandle, g_FragHandle); - if (g_FragHandle) glDeleteShader(g_FragHandle); g_FragHandle = 0; - - if (g_ShaderHandle) glDeleteProgram(g_ShaderHandle); g_ShaderHandle = 0; ImGui_ImplOpenGL3_DestroyFontsTexture(); if (g_BackgroundTexture != 0) - glDeleteTextures(1, &g_BackgroundTexture); + glcache.DeleteTextures(1, &g_BackgroundTexture); g_BackgroundTexture = 0; } void ImGui_ImplOpenGL3_DrawBackground() { + glcache.Disable(GL_SCISSOR_TEST); + glcache.ClearColor(0, 0, 0, 0); + glClear(GL_COLOR_BUFFER_BIT); if (g_BackgroundTexture != 0) { ImGuiIO& io = ImGui::GetIO(); @@ -591,20 +524,14 @@ void ImGui_ImplOpenGL3_DrawBackground() ImGui::GetWindowDrawList()->AddImage((ImTextureID)(uintptr_t)g_BackgroundTexture, ImVec2(0, 0), io.DisplaySize, ImVec2(0, 1), ImVec2(1, 0), 0xffffffff); ImGui::End(); } - else - { - glClearColor(0, 0, 0, 0); - glClear(GL_COLOR_BUFFER_BIT); - } } ImTextureID ImGui_ImplOpenGL3_CreateVmuTexture(const unsigned int *data) { - GLuint tex_id; - glGenTextures(1, &tex_id); - glBindTexture(GL_TEXTURE_2D, tex_id); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + GLuint tex_id = glcache.GenTexture(); + glcache.BindTexture(GL_TEXTURE_2D, tex_id); + glcache.TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glcache.TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 48, 32, 0, GL_RGBA, GL_UNSIGNED_BYTE, data); return reinterpret_cast(tex_id); @@ -612,5 +539,5 @@ ImTextureID ImGui_ImplOpenGL3_CreateVmuTexture(const unsigned int *data) void ImGui_ImplOpenGL3_DeleteVmuTexture(ImTextureID tex_id) { - glDeleteTextures(1, &(GLuint &)tex_id); + glcache.DeleteTextures(1, &(GLuint &)tex_id); } diff --git a/core/rend/gui.cpp b/core/rend/gui.cpp index 03e976d85..b6f0b30aa 100644 --- a/core/rend/gui.cpp +++ b/core/rend/gui.cpp @@ -18,7 +18,12 @@ */ #include #include +#ifdef _MSC_VER +#include "dirent/dirent.h" +#define S_ISDIR(mode) (((mode) & _S_IFMT) == _S_IFDIR) +#else #include +#endif #include #include "gui.h" @@ -34,7 +39,10 @@ #include "linux-dist/main.h" // FIXME for kcode[] #include "gui_util.h" #include "gui_android.h" -#include "version/version.h" + +#include "version.h" +#include "oslib/audiostream.h" + extern void dc_loadstate(); extern void dc_savestate(); @@ -294,7 +302,9 @@ static void gui_display_commands() if (!settings_opening) ImGui_ImplOpenGL3_DrawBackground(); - display_vmus(); + if (!settings.rend.FloatVMUs) + // If floating VMUs, they are already visible on the background + display_vmus(); ImGui::SetNextWindowPos(ImVec2(screen_width / 2.f, screen_height / 2.f), ImGuiCond_Always, ImVec2(0.5f, 0.5f)); ImGui::SetNextWindowSize(ImVec2(330 * scaling, 0)); @@ -617,6 +627,8 @@ void directory_selected_callback(bool cancelled, std::string selection) static void gui_display_settings() { + static bool maple_devices_changed; + ImGui_Impl_NewFrame(); ImGui::NewFrame(); @@ -639,10 +651,14 @@ static void gui_display_settings() gui_state = Commands; else gui_state = Main; + if (maple_devices_changed) + { + maple_devices_changed = false; #if DC_PLATFORM == DC_PLATFORM_DREAMCAST - maple_ReconnectDevices(); - reset_vmus(); + maple_ReconnectDevices(); + reset_vmus(); #endif + } SaveSettings(); } if (game_started) @@ -796,13 +812,14 @@ static void gui_display_settings() if (ImGui::BeginTabItem("Controls")) { ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, normal_padding); -#if DC_PLATFORM == DC_PLATFORM_DREAMCAST +#if DC_PLATFORM == DC_PLATFORM_DREAMCAST || DC_PLATFORM == DC_PLATFORM_ATOMISWAVE if (ImGui::CollapsingHeader("Dreamcast Devices", ImGuiTreeNodeFlags_DefaultOpen)) { for (int bus = 0; bus < MAPLE_PORTS; bus++) { ImGui::Text("Device %c", bus + 'A'); ImGui::SameLine(); +#if DC_PLATFORM == DC_PLATFORM_DREAMCAST char device_name[32]; sprintf(device_name, "##device%d", bus); float w = ImGui::CalcItemWidth() / 3; @@ -813,7 +830,10 @@ static void gui_display_settings() { bool is_selected = settings.input.maple_devices[bus] == maple_device_type_from_index(i); if (ImGui::Selectable(maple_device_types[i], &is_selected)) + { settings.input.maple_devices[bus] = maple_device_type_from_index(i); + maple_devices_changed = true; + } if (is_selected) ImGui::SetItemDefaultFocus(); } @@ -831,7 +851,10 @@ static void gui_display_settings() { bool is_selected = settings.input.maple_expansion_devices[bus][port] == maple_expansion_device_type_from_index(i); if (ImGui::Selectable(maple_expansion_device_types[i], &is_selected)) + { settings.input.maple_expansion_devices[bus][port] = maple_expansion_device_type_from_index(i); + maple_devices_changed = true; + } if (is_selected) ImGui::SetItemDefaultFocus(); } @@ -840,6 +863,10 @@ static void gui_display_settings() ImGui::PopID(); } ImGui::PopItemWidth(); +#elif DC_PLATFORM == DC_PLATFORM_ATOMISWAVE + if (MapleDevices[bus][5] != NULL) + ImGui::Text("%s", maple_device_name(MapleDevices[bus][5]->get_device_type())); +#endif } ImGui::Spacing(); } @@ -940,15 +967,27 @@ static void gui_display_settings() ImGui::Checkbox("Shadows", &settings.rend.ModifierVolumes); ImGui::SameLine(); ShowHelpMarker("Enable modifier volumes, usually used for shadows"); + ImGui::Checkbox("Fog", &settings.rend.Fog); + ImGui::SameLine(); + ShowHelpMarker("Enable fog effects"); ImGui::Checkbox("Widescreen", &settings.rend.WideScreen); ImGui::SameLine(); ShowHelpMarker("Draw geometry outside of the normal 4:3 aspect ratio. May produce graphical glitches in the revealed areas"); ImGui::Checkbox("Show FPS Counter", &settings.rend.ShowFPS); ImGui::SameLine(); ShowHelpMarker("Show on-screen frame/sec counter"); + ImGui::Checkbox("Show VMU in game", &settings.rend.FloatVMUs); + ImGui::SameLine(); + ShowHelpMarker("Show the VMU LCD screens while in game"); + ImGui::Checkbox("Rotate screen 90°", &settings.rend.Rotate90); + ImGui::SameLine(); + ShowHelpMarker("Rotate the screen 90° counterclockwise"); ImGui::SliderInt("Scaling", (int *)&settings.rend.ScreenScaling, 1, 100); ImGui::SameLine(); ShowHelpMarker("Downscaling factor relative to native screen resolution. Higher is better"); + ImGui::SliderInt("Horizontal Stretching", (int *)&settings.rend.ScreenStretching, 100, 150); + ImGui::SameLine(); + ShowHelpMarker("Stretch the screen horizontally"); ImGui::SliderInt("Frame Skipping", (int *)&settings.pvr.ta_skip, 0, 6); ImGui::SameLine(); ShowHelpMarker("Number of frames to skip between two actually rendered frames"); @@ -986,12 +1025,122 @@ static void gui_display_settings() ImGui::Checkbox("Disable Sound", &settings.aica.NoSound); ImGui::SameLine(); ShowHelpMarker("Disable the emulator sound output"); + ImGui::Checkbox("Enable DSP", &settings.aica.NoBatch); ImGui::SameLine(); ShowHelpMarker("Enable the Dreamcast Digital Sound Processor. Only recommended on fast and arm64 platforms"); ImGui::Checkbox("Limit FPS", &settings.aica.LimitFPS); ImGui::SameLine(); ShowHelpMarker("Use the sound output to limit the speed of the emulator. Recommended in most cases"); + + audiobackend_t* backend = NULL;; + std::string backend_name = settings.audio.backend; + if (backend_name != "auto" && backend_name != "none") + { + backend = GetAudioBackend(settings.audio.backend); + if (backend != NULL) + backend_name = backend->slug; + } + + SortAudioBackends(); + + audiobackend_t* current_backend = backend; + if (ImGui::BeginCombo("Audio Backend", backend_name.c_str(), ImGuiComboFlags_None)) + { + bool is_selected = (settings.audio.backend == "auto"); + if (ImGui::Selectable("auto", &is_selected)) + settings.audio.backend = "auto"; + ImGui::SameLine(); ImGui::Text("-"); + ImGui::SameLine(); ImGui::Text("Autoselect audio backend"); + + is_selected = (settings.audio.backend == "none"); + if (ImGui::Selectable("none", &is_selected)) + settings.audio.backend = "none"; + ImGui::SameLine(); ImGui::Text("-"); + ImGui::SameLine(); ImGui::Text("No audio backend"); + + for (int i = 0; i < GetAudioBackendCount(); i++) + { + backend = GetAudioBackend(i); + is_selected = (settings.audio.backend == backend->slug); + + if (is_selected) + current_backend = backend; + + if (ImGui::Selectable(backend->slug.c_str(), &is_selected)) + settings.audio.backend = backend->slug; + ImGui::SameLine(); ImGui::Text("-"); + ImGui::SameLine(); ImGui::Text(backend->name.c_str()); + if (is_selected) + ImGui::SetItemDefaultFocus(); + } + ImGui::EndCombo(); + } + ImGui::SameLine(); + ShowHelpMarker("The audio backend to use"); + + if (current_backend != NULL && current_backend->get_options != NULL) + { + // get backend specific options + int option_count; + audio_option_t* options = current_backend->get_options(&option_count); + + // initialize options if not already done + std::map* cfg_entries = &settings.audio.options[current_backend->slug]; + bool populate_entries = (cfg_entries->size() == 0); + + for (int o = 0; o < option_count; o++) + { + std::string value; + if (populate_entries) + { + value = cfgLoadStr(current_backend->slug.c_str(), options->cfg_name.c_str(), ""); + (*cfg_entries)[options->cfg_name] = value; + } + value = (*cfg_entries)[options->cfg_name]; + + if (options->type == integer) + { + int val = stoi(value); + ImGui::SliderInt(options->caption.c_str(), &val, options->min_value, options->max_value); + (*cfg_entries)[options->cfg_name] = to_string(val); + } + else if (options->type == checkbox) + { + bool check = (value == "1"); + ImGui::Checkbox(options->caption.c_str(), &check); + std::string cur = check ? "1" : "0"; + (*cfg_entries)[options->cfg_name] = cur; + } + else if (options->type == list) + { + if (ImGui::BeginCombo(options->caption.c_str(), value.c_str(), ImGuiComboFlags_None)) + { + bool is_selected = false; + std::vector list_items = options->list_callback(); + for (std::vector::iterator it = list_items.begin() ; it != list_items.end(); ++it) + { + std::string cur = (std::string)*it; + is_selected = (value == cur); + if (ImGui::Selectable(cur.c_str(), &is_selected)) + { + (*cfg_entries)[options->cfg_name] = cur; + } + + if (is_selected) + ImGui::SetItemDefaultFocus(); + } + ImGui::EndCombo(); + } + } + else { + printf("Unknown option\n"); + } + + options++; + } + } + ImGui::PopStyleVar(); ImGui::EndTabItem(); } @@ -1064,9 +1213,9 @@ static void gui_display_settings() ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, normal_padding); if (ImGui::CollapsingHeader("Reicast", ImGuiTreeNodeFlags_DefaultOpen)) { - ImGui::Text("Version: %s", version); - ImGui::Text("Git Hash: %s", git_hash); - ImGui::Text("Build Date: %s", build_date); + ImGui::Text("Version: %s", REICAST_VERSION); + ImGui::Text("Git Hash: %s", GIT_HASH); + ImGui::Text("Build Date: %s", BUILD_DATE); ImGui::Text("Target: %s", #if DC_PLATFORM == DC_PLATFORM_DREAMCAST "Dreamcast" @@ -1248,6 +1397,7 @@ static void gui_start_game(const std::string& path) { gui_state = Main; game_started = false; + cfgSetVirtual("config", "image", ""); switch (rc) { case -3: error_msg = "Audio/video initialization failed"; @@ -1405,24 +1555,6 @@ void gui_display_ui() gui_state = Closed; } -void gui_display_fps(const char *string) -{ - ImGui_Impl_NewFrame(); - ImGui::NewFrame(); - - ImGui::SetNextWindowBgAlpha(0); - ImGui::SetNextWindowPos(ImVec2(0, screen_height), ImGuiCond_Always, ImVec2(0.f, 1.f)); // Lower left corner - - ImGui::Begin("##fps", NULL, ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_NoNav - | ImGuiWindowFlags_NoInputs | ImGuiWindowFlags_NoBackground); - ImGui::SetWindowFontScale(2); - ImGui::TextColored(ImVec4(1, 1, 0, 0.7), "%s", string); - ImGui::End(); - - ImGui::Render(); - ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData()); -} - static float LastFPSTime; static int lastFrameCount = 0; static float fps = -1; @@ -1470,26 +1602,32 @@ void gui_display_osd() if (osd_message.empty()) { message = getFPSNotification(); - if (message.empty()) - return; } else message = osd_message; - ImGui_Impl_NewFrame(); - ImGui::NewFrame(); + if (!message.empty() || settings.rend.FloatVMUs) + { + ImGui_Impl_NewFrame(); + ImGui::NewFrame(); - ImGui::SetNextWindowBgAlpha(0); - ImGui::SetNextWindowPos(ImVec2(0, screen_height), ImGuiCond_Always, ImVec2(0.f, 1.f)); // Lower left corner + if (!message.empty()) + { + ImGui::SetNextWindowBgAlpha(0); + ImGui::SetNextWindowPos(ImVec2(0, screen_height), ImGuiCond_Always, ImVec2(0.f, 1.f)); // Lower left corner - ImGui::Begin("##osd", NULL, ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_NoNav - | ImGuiWindowFlags_NoInputs | ImGuiWindowFlags_NoBackground); - ImGui::SetWindowFontScale(1.5); - ImGui::TextColored(ImVec4(1, 1, 0, 0.7), "%s", message.c_str()); - ImGui::End(); + ImGui::Begin("##osd", NULL, ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_NoNav + | ImGuiWindowFlags_NoInputs | ImGuiWindowFlags_NoBackground); + ImGui::SetWindowFontScale(1.5); + ImGui::TextColored(ImVec4(1, 1, 0, 0.7), "%s", message.c_str()); + ImGui::End(); + } + if (settings.rend.FloatVMUs) + display_vmus(); - ImGui::Render(); - ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData()); + ImGui::Render(); + ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData()); + } } void gui_open_onboarding() diff --git a/core/rend/gui_util.cpp b/core/rend/gui_util.cpp index f9e9ce91b..5fb9e9d02 100644 --- a/core/rend/gui_util.cpp +++ b/core/rend/gui_util.cpp @@ -21,8 +21,16 @@ #include #include #include +#ifdef _MSC_VER +#include +#include "dirent/dirent.h" +#define S_ISDIR(mode) (((mode) & _S_IFMT) == _S_IFDIR) +#define access _access +#define R_OK 4 +#else #include #include +#endif #include #include "types.h" diff --git a/core/serialize.cpp b/core/serialize.cpp index f040744a4..8b7e29900 100644 --- a/core/serialize.cpp +++ b/core/serialize.cpp @@ -101,7 +101,7 @@ extern AicaTimer timers[3]; //./core/hw/aica/aica_if.o -extern VArray2 aica_ram; +extern VLockedMemory aica_ram; extern u32 VREG;//video reg =P extern u32 ARMRST;//arm reset reg extern u32 rtc_EN; @@ -381,7 +381,7 @@ extern DECL_ALIGN(4) u32 SFaceOffsColor; //extern vector VramLocks[/*VRAM_SIZE*/(16*1024*1024)/PAGE_SIZE]; //maybe - probably not - just a locking mechanism //extern cMutex vramlist_lock; -extern VArray2 vram; +extern VLockedMemory vram; @@ -403,7 +403,7 @@ extern Array SCIF; //SCIF : 10 registers //./core/hw/sh4/sh4_mem.o -extern VArray2 mem_b; +extern VLockedMemory mem_b; //one-time init //extern _vmem_handler area1_32b; //one-time init @@ -441,7 +441,7 @@ extern u32 old_dn; //./core/hw/sh4/sh4_sched.o extern u64 sh4_sched_ffb; extern u32 sh4_sched_intr; -extern vector list; +extern vector sch_list; //extern int sh4_sched_next_id; @@ -975,8 +975,6 @@ bool dc_serialize(void **data, unsigned int *total_size) REICAST_S(decoded_srimask); - - //default to nommu_full i = 3 ; if ( do_sqw_nommu == &do_sqw_nommu_area_3) @@ -1008,61 +1006,63 @@ bool dc_serialize(void **data, unsigned int *total_size) //extern vector list; - REICAST_S(list[aica_schid].tag) ; - REICAST_S(list[aica_schid].start) ; - REICAST_S(list[aica_schid].end) ; - REICAST_S(list[rtc_schid].tag) ; - REICAST_S(list[rtc_schid].start) ; - REICAST_S(list[rtc_schid].end) ; + REICAST_S(sch_list[aica_schid].tag) ; + REICAST_S(sch_list[aica_schid].start) ; + REICAST_S(sch_list[aica_schid].end) ; - REICAST_S(list[gdrom_schid].tag) ; - REICAST_S(list[gdrom_schid].start) ; - REICAST_S(list[gdrom_schid].end) ; + REICAST_S(sch_list[rtc_schid].tag) ; + REICAST_S(sch_list[rtc_schid].start) ; + REICAST_S(sch_list[rtc_schid].end) ; - REICAST_S(list[maple_schid].tag) ; - REICAST_S(list[maple_schid].start) ; - REICAST_S(list[maple_schid].end) ; + REICAST_S(sch_list[gdrom_schid].tag) ; + REICAST_S(sch_list[gdrom_schid].start) ; + REICAST_S(sch_list[gdrom_schid].end) ; - REICAST_S(list[dma_sched_id].tag) ; - REICAST_S(list[dma_sched_id].start) ; - REICAST_S(list[dma_sched_id].end) ; + REICAST_S(sch_list[maple_schid].tag) ; + REICAST_S(sch_list[maple_schid].start) ; + REICAST_S(sch_list[maple_schid].end) ; + + REICAST_S(sch_list[dma_sched_id].tag) ; + REICAST_S(sch_list[dma_sched_id].start) ; + REICAST_S(sch_list[dma_sched_id].end) ; for (int i = 0; i < 3; i++) { - REICAST_S(list[tmu_sched[i]].tag) ; - REICAST_S(list[tmu_sched[i]].start) ; - REICAST_S(list[tmu_sched[i]].end) ; + REICAST_S(sch_list[tmu_sched[i]].tag) ; + REICAST_S(sch_list[tmu_sched[i]].start) ; + REICAST_S(sch_list[tmu_sched[i]].end) ; } - REICAST_S(list[render_end_schid].tag) ; - REICAST_S(list[render_end_schid].start) ; - REICAST_S(list[render_end_schid].end) ; + REICAST_S(sch_list[render_end_schid].tag) ; + REICAST_S(sch_list[render_end_schid].start) ; + REICAST_S(sch_list[render_end_schid].end) ; - REICAST_S(list[vblank_schid].tag) ; - REICAST_S(list[vblank_schid].start) ; - REICAST_S(list[vblank_schid].end) ; - - REICAST_S(list[time_sync].tag) ; - REICAST_S(list[time_sync].start) ; - REICAST_S(list[time_sync].end) ; - - REICAST_S(list[modem_sched].tag) ; - REICAST_S(list[modem_sched].start) ; - REICAST_S(list[modem_sched].end) ; + REICAST_S(sch_list[vblank_schid].tag) ; + REICAST_S(sch_list[vblank_schid].start) ; + REICAST_S(sch_list[vblank_schid].end) ; + REICAST_S(sch_list[time_sync].tag) ; + REICAST_S(sch_list[time_sync].start) ; + REICAST_S(sch_list[time_sync].end) ; + #ifdef ENABLE_MODEM + REICAST_S(sch_list[modem_sched].tag) ; + REICAST_S(sch_list[modem_sched].start) ; + REICAST_S(sch_list[modem_sched].end) ; + #else + int modem_dummy = 0; + REICAST_S(modem_dummy); + REICAST_S(modem_dummy); + REICAST_S(modem_dummy); + #endif REICAST_S(SCIF_SCFSR2); REICAST_S(SCIF_SCFRDR2); REICAST_S(SCIF_SCFDR2); - REICAST_S(BSC_PDTRA); - - - REICAST_SA(tmu_shift,3); REICAST_SA(tmu_mask,3); REICAST_SA(tmu_mask64,3); @@ -1070,14 +1070,8 @@ bool dc_serialize(void **data, unsigned int *total_size) REICAST_SA(tmu_ch_base,3); REICAST_SA(tmu_ch_base64,3); - - - REICAST_SA(CCN_QACR_TR,2); - - - REICAST_SA(UTLB,64); REICAST_SA(ITLB,4); #if defined(NO_MMU) @@ -1087,8 +1081,6 @@ bool dc_serialize(void **data, unsigned int *total_size) REICAST_S(mmu_error_TT); #endif - - REICAST_S(NullDriveDiscType); REICAST_SA(q_subchannel,96); @@ -1130,22 +1122,16 @@ bool dc_serialize(void **data, unsigned int *total_size) REICAST_S(div_som_reg2); REICAST_S(div_som_reg3); - - REICAST_S(LastAddr); REICAST_S(LastAddr_min); REICAST_SA(block_hash,1024); - REICAST_SA(RegisterWrite,sh4_reg_count); REICAST_SA(RegisterRead,sh4_reg_count); REICAST_S(fallback_blocks); REICAST_S(total_blocks); REICAST_S(REMOVED_OPS); - - - REICAST_SA(kcode,4); REICAST_SA(rt,4); REICAST_SA(lt,4); @@ -1246,12 +1232,7 @@ static bool dc_unserialize_libretro(void **data, unsigned int *total_size) //this is one-time init, no updates - don't need to serialize //extern _vmem_handler area0_handler; - - - - REICAST_USA(reply_11,16) ; - - + REICAST_USA(reply_11,16); REICAST_US(sns_asc); REICAST_US(sns_ascq); @@ -1365,8 +1346,6 @@ static bool dc_unserialize_libretro(void **data, unsigned int *total_size) REICAST_USA(mem_b.data, mem_b.size); - - REICAST_US(IRLPriority); REICAST_USA(InterruptEnvId,32); REICAST_USA(InterruptBit,32); @@ -1375,9 +1354,6 @@ static bool dc_unserialize_libretro(void **data, unsigned int *total_size) REICAST_US(interrupt_vmask); REICAST_US(decoded_srimask); - - - REICAST_US(i) ; if ( i == 0 ) do_sqw_nommu = &do_sqw_nommu_area_3 ; @@ -1402,69 +1378,67 @@ static bool dc_unserialize_libretro(void **data, unsigned int *total_size) REICAST_US(old_rm); REICAST_US(old_dn); - - - REICAST_US(sh4_sched_ffb); REICAST_US(sh4_sched_intr); - //extern vector list; + //extern vector sch_list; - REICAST_US(list[aica_schid].tag) ; - REICAST_US(list[aica_schid].start) ; - REICAST_US(list[aica_schid].end) ; + REICAST_US(sch_list[aica_schid].tag) ; + REICAST_US(sch_list[aica_schid].start) ; + REICAST_US(sch_list[aica_schid].end) ; - REICAST_US(list[rtc_schid].tag) ; - REICAST_US(list[rtc_schid].start) ; - REICAST_US(list[rtc_schid].end) ; + REICAST_US(sch_list[rtc_schid].tag) ; + REICAST_US(sch_list[rtc_schid].start) ; + REICAST_US(sch_list[rtc_schid].end) ; - REICAST_US(list[gdrom_schid].tag) ; - REICAST_US(list[gdrom_schid].start) ; - REICAST_US(list[gdrom_schid].end) ; + REICAST_US(sch_list[gdrom_schid].tag) ; + REICAST_US(sch_list[gdrom_schid].start) ; + REICAST_US(sch_list[gdrom_schid].end) ; - REICAST_US(list[maple_schid].tag) ; - REICAST_US(list[maple_schid].start) ; - REICAST_US(list[maple_schid].end) ; + REICAST_US(sch_list[maple_schid].tag) ; + REICAST_US(sch_list[maple_schid].start) ; + REICAST_US(sch_list[maple_schid].end) ; - REICAST_US(list[dma_sched_id].tag) ; - REICAST_US(list[dma_sched_id].start) ; - REICAST_US(list[dma_sched_id].end) ; + REICAST_US(sch_list[dma_sched_id].tag) ; + REICAST_US(sch_list[dma_sched_id].start) ; + REICAST_US(sch_list[dma_sched_id].end) ; for (int i = 0; i < 3; i++) { - REICAST_US(list[tmu_sched[i]].tag) ; - REICAST_US(list[tmu_sched[i]].start) ; - REICAST_US(list[tmu_sched[i]].end) ; + REICAST_US(sch_list[tmu_sched[i]].tag) ; + REICAST_US(sch_list[tmu_sched[i]].start) ; + REICAST_US(sch_list[tmu_sched[i]].end) ; } - REICAST_US(list[render_end_schid].tag) ; - REICAST_US(list[render_end_schid].start) ; - REICAST_US(list[render_end_schid].end) ; + REICAST_US(sch_list[render_end_schid].tag) ; + REICAST_US(sch_list[render_end_schid].start) ; + REICAST_US(sch_list[render_end_schid].end) ; - REICAST_US(list[vblank_schid].tag) ; - REICAST_US(list[vblank_schid].start) ; - REICAST_US(list[vblank_schid].end) ; - - REICAST_US(list[time_sync].tag) ; - REICAST_US(list[time_sync].start) ; - REICAST_US(list[time_sync].end) ; - - REICAST_US(list[modem_sched].tag) ; - REICAST_US(list[modem_sched].start) ; - REICAST_US(list[modem_sched].end) ; + REICAST_US(sch_list[vblank_schid].tag) ; + REICAST_US(sch_list[vblank_schid].start) ; + REICAST_US(sch_list[vblank_schid].end) ; + REICAST_US(sch_list[time_sync].tag) ; + REICAST_US(sch_list[time_sync].start) ; + REICAST_US(sch_list[time_sync].end) ; + #ifdef ENABLE_MODEM + REICAST_US(sch_list[modem_sched].tag) ; + REICAST_US(sch_list[modem_sched].start) ; + REICAST_US(sch_list[modem_sched].end) ; + #else + int modem_dummy; + REICAST_US(modem_dummy); + REICAST_US(modem_dummy); + REICAST_US(modem_dummy); + #endif REICAST_US(SCIF_SCFSR2); REICAST_US(SCIF_SCFRDR2); REICAST_US(SCIF_SCFDR2); - REICAST_US(BSC_PDTRA); - - - REICAST_USA(tmu_shift,3); REICAST_USA(tmu_mask,3); REICAST_USA(tmu_mask64,3); @@ -1472,14 +1446,8 @@ static bool dc_unserialize_libretro(void **data, unsigned int *total_size) REICAST_USA(tmu_ch_base,3); REICAST_USA(tmu_ch_base64,3); - - - REICAST_USA(CCN_QACR_TR,2); - - - REICAST_USA(UTLB,64); REICAST_USA(ITLB,4); #if defined(NO_MMU) @@ -1489,9 +1457,6 @@ static bool dc_unserialize_libretro(void **data, unsigned int *total_size) REICAST_US(mmu_error_TT); #endif - - - REICAST_US(NullDriveDiscType); REICAST_USA(q_subchannel,96); @@ -1546,9 +1511,6 @@ static bool dc_unserialize_libretro(void **data, unsigned int *total_size) REICAST_US(div_som_reg2); REICAST_US(div_som_reg3); - - - //REICAST_USA(CodeCache,CODE_SIZE) ; //REICAST_USA(SH4_TCB,CODE_SIZE+4096); REICAST_US(LastAddr); @@ -1612,7 +1574,6 @@ bool dc_unserialize(void **data, unsigned int *total_size) REICAST_US(timers[i].m_step); } - REICAST_USA(aica_ram.data,aica_ram.size) ; REICAST_US(VREG); REICAST_US(ARMRST); @@ -1620,8 +1581,6 @@ bool dc_unserialize(void **data, unsigned int *total_size) REICAST_USA(aica_reg,0x8000); - - REICAST_USA(volume_lut,16); REICAST_USA(tl_lut,256 + 768); REICAST_USA(AEG_ATT_SPS,64); @@ -1636,14 +1595,11 @@ bool dc_unserialize(void **data, unsigned int *total_size) REICAST_USA(mxlr,64); REICAST_US(samples_gen); - register_unserialize(sb_regs, data, total_size) ; REICAST_US(SB_ISTNRM); REICAST_US(SB_FFST_rc); REICAST_US(SB_FFST); - - //this is one-time init, no updates - don't need to serialize //extern RomChip sys_rom; REICAST_US(sys_nvmem.size); @@ -1755,8 +1711,6 @@ bool dc_unserialize(void **data, unsigned int *total_size) REICAST_USA(mem_b.data, mem_b.size); - - REICAST_US(IRLPriority); REICAST_USA(InterruptEnvId,32); REICAST_USA(InterruptBit,32); @@ -1765,9 +1719,6 @@ bool dc_unserialize(void **data, unsigned int *total_size) REICAST_US(interrupt_vmask); REICAST_US(decoded_srimask); - - - REICAST_US(i) ; if ( i == 0 ) do_sqw_nommu = &do_sqw_nommu_area_3 ; @@ -1800,50 +1751,55 @@ bool dc_unserialize(void **data, unsigned int *total_size) //extern vector list; - REICAST_US(list[aica_schid].tag) ; - REICAST_US(list[aica_schid].start) ; - REICAST_US(list[aica_schid].end) ; + REICAST_US(sch_list[aica_schid].tag) ; + REICAST_US(sch_list[aica_schid].start) ; + REICAST_US(sch_list[aica_schid].end) ; - REICAST_US(list[rtc_schid].tag) ; - REICAST_US(list[rtc_schid].start) ; - REICAST_US(list[rtc_schid].end) ; + REICAST_US(sch_list[rtc_schid].tag) ; + REICAST_US(sch_list[rtc_schid].start) ; + REICAST_US(sch_list[rtc_schid].end) ; - REICAST_US(list[gdrom_schid].tag) ; - REICAST_US(list[gdrom_schid].start) ; - REICAST_US(list[gdrom_schid].end) ; + REICAST_US(sch_list[gdrom_schid].tag) ; + REICAST_US(sch_list[gdrom_schid].start) ; + REICAST_US(sch_list[gdrom_schid].end) ; - REICAST_US(list[maple_schid].tag) ; - REICAST_US(list[maple_schid].start) ; - REICAST_US(list[maple_schid].end) ; + REICAST_US(sch_list[maple_schid].tag) ; + REICAST_US(sch_list[maple_schid].start) ; + REICAST_US(sch_list[maple_schid].end) ; - REICAST_US(list[dma_sched_id].tag) ; - REICAST_US(list[dma_sched_id].start) ; - REICAST_US(list[dma_sched_id].end) ; + REICAST_US(sch_list[dma_sched_id].tag) ; + REICAST_US(sch_list[dma_sched_id].start) ; + REICAST_US(sch_list[dma_sched_id].end) ; for (int i = 0; i < 3; i++) { - REICAST_US(list[tmu_sched[i]].tag) ; - REICAST_US(list[tmu_sched[i]].start) ; - REICAST_US(list[tmu_sched[i]].end) ; + REICAST_US(sch_list[tmu_sched[i]].tag) ; + REICAST_US(sch_list[tmu_sched[i]].start) ; + REICAST_US(sch_list[tmu_sched[i]].end) ; } - REICAST_US(list[render_end_schid].tag) ; - REICAST_US(list[render_end_schid].start) ; - REICAST_US(list[render_end_schid].end) ; + REICAST_US(sch_list[render_end_schid].tag) ; + REICAST_US(sch_list[render_end_schid].start) ; + REICAST_US(sch_list[render_end_schid].end) ; - REICAST_US(list[vblank_schid].tag) ; - REICAST_US(list[vblank_schid].start) ; - REICAST_US(list[vblank_schid].end) ; - - REICAST_US(list[time_sync].tag) ; - REICAST_US(list[time_sync].start) ; - REICAST_US(list[time_sync].end) ; - - REICAST_US(list[modem_sched].tag) ; - REICAST_US(list[modem_sched].start) ; - REICAST_US(list[modem_sched].end) ; + REICAST_US(sch_list[vblank_schid].tag) ; + REICAST_US(sch_list[vblank_schid].start) ; + REICAST_US(sch_list[vblank_schid].end) ; + REICAST_US(sch_list[time_sync].tag) ; + REICAST_US(sch_list[time_sync].start) ; + REICAST_US(sch_list[time_sync].end) ; + #ifdef ENABLE_MODEM + REICAST_US(sch_list[modem_sched].tag) ; + REICAST_US(sch_list[modem_sched].start) ; + REICAST_US(sch_list[modem_sched].end) ; + #else + int modem_dummy; + REICAST_US(modem_dummy); + REICAST_US(modem_dummy); + REICAST_US(modem_dummy); + #endif REICAST_US(SCIF_SCFSR2); REICAST_US(SCIF_SCFRDR2); @@ -1880,8 +1836,6 @@ bool dc_unserialize(void **data, unsigned int *total_size) #endif - - REICAST_US(NullDriveDiscType); REICAST_USA(q_subchannel,96); @@ -1897,7 +1851,6 @@ bool dc_unserialize(void **data, unsigned int *total_size) // REICAST_US(i); // VRAM_MASK - REICAST_US(naomi_updates); REICAST_US(i); // BoardID REICAST_US(GSerialBuffer); @@ -1936,25 +1889,18 @@ bool dc_unserialize(void **data, unsigned int *total_size) REICAST_US(div_som_reg2); REICAST_US(div_som_reg3); - - - //REICAST_USA(CodeCache,CODE_SIZE) ; //REICAST_USA(SH4_TCB,CODE_SIZE+4096); REICAST_US(LastAddr); REICAST_US(LastAddr_min); REICAST_USA(block_hash,1024); - REICAST_USA(RegisterWrite,sh4_reg_count); REICAST_USA(RegisterRead,sh4_reg_count); REICAST_US(fallback_blocks); REICAST_US(total_blocks); REICAST_US(REMOVED_OPS); - - - REICAST_USA(kcode,4); REICAST_USA(rt,4); REICAST_USA(lt,4); diff --git a/core/stdclass.cpp b/core/stdclass.cpp index 5f689b72e..76921d170 100644 --- a/core/stdclass.cpp +++ b/core/stdclass.cpp @@ -4,9 +4,16 @@ #include #include "types.h" #include "cfg/cfg.h" +#include "stdclass.h" +#if HOST_OS == OS_DARWIN +#include +#include +#endif -#if BUILD_COMPILER==COMPILER_VC + +#if COMPILER_VC_OR_CLANG_WIN32 #include + #include #define access _access #define R_OK 4 #else @@ -140,62 +147,156 @@ string get_game_dir() bool make_directory(const string& path) { - return mkdir(path.c_str() -#ifndef _WIN32 - , 0755 +#if COMPILER_VC_OR_CLANG_WIN32 +#define mkdir _mkdir +#endif + +#ifdef _WIN32 + return mkdir(path.c_str()) == 0; +#else + return mkdir(path.c_str(), 0755) == 0; #endif - ) == 0; } -#if 0 -//File Enumeration -void FindAllFiles(FileFoundCB* callback,wchar* dir,void* param) -{ - WIN32_FIND_DATA FindFileData; - HANDLE hFind = INVALID_HANDLE_VALUE; - wchar DirSpec[MAX_PATH + 1]; // directory specification - DWORD dwError; +// Thread & related platform dependant code +#if !defined(HOST_NO_THREADS) - strncpy (DirSpec, dir, strlen(dir)+1); - //strncat (DirSpec, "\\*", 3); - - hFind = FindFirstFile( DirSpec, &FindFileData); - - if (hFind == INVALID_HANDLE_VALUE) - { - return; - } - else - { - - if ((FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)==0) - { - callback(FindFileData.cFileName,param); - } -u32 rv; - while ( (rv=FindNextFile(hFind, &FindFileData)) != 0) - { - if ((FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)==0) - { - callback(FindFileData.cFileName,param); - } - } - dwError = GetLastError(); - FindClose(hFind); - if (dwError != ERROR_NO_MORE_FILES) - { - return ; - } +#if HOST_OS==OS_WINDOWS +void cThread::Start() { + verify(hThread == NULL); + hThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)entry, param, 0, NULL); + ResumeThread(hThread); +} +void cThread::WaitToEnd() { + WaitForSingleObject(hThread,INFINITE); + CloseHandle(hThread); + hThread = NULL; +} +#else +void cThread::Start() { + verify(hThread == NULL); + hThread = new pthread_t; + if (pthread_create( hThread, NULL, entry, param)) + die("Thread creation failed"); +} +void cThread::WaitToEnd() { + if (hThread) { + pthread_join(*hThread,0); + delete hThread; + hThread = NULL; } - return ; } #endif -/* -#include "dc\sh4\rec_v1\compiledblock.h" -#include "dc\sh4\rec_v1\blockmanager.h" +#endif + + +#if HOST_OS==OS_WINDOWS +cResetEvent::cResetEvent() { + hEvent = CreateEvent( + NULL, // default security attributes + FALSE, // auto-reset event? + FALSE, // initial state is State + NULL // unnamed object + ); +} +cResetEvent::~cResetEvent() +{ + //Destroy the event object ? + CloseHandle(hEvent); +} +void cResetEvent::Set()//Signal +{ + #if defined(DEBUG_THREADS) + Sleep(rand() % 10); + #endif + SetEvent(hEvent); +} +void cResetEvent::Reset()//reset +{ + #if defined(DEBUG_THREADS) + Sleep(rand() % 10); + #endif + ResetEvent(hEvent); +} +bool cResetEvent::Wait(u32 msec)//Wait for signal , then reset +{ + #if defined(DEBUG_THREADS) + Sleep(rand() % 10); + #endif + return WaitForSingleObject(hEvent,msec) == WAIT_OBJECT_0; +} +void cResetEvent::Wait()//Wait for signal , then reset +{ + #if defined(DEBUG_THREADS) + Sleep(rand() % 10); + #endif + WaitForSingleObject(hEvent,(u32)-1); +} +#else +cResetEvent::cResetEvent() { + pthread_mutex_init(&mutx, NULL); + pthread_cond_init(&cond, NULL); +} +cResetEvent::~cResetEvent() { +} +void cResetEvent::Set()//Signal +{ + pthread_mutex_lock( &mutx ); + state=true; + pthread_cond_signal( &cond); + pthread_mutex_unlock( &mutx ); +} +void cResetEvent::Reset()//reset +{ + pthread_mutex_lock( &mutx ); + state=false; + pthread_mutex_unlock( &mutx ); +} +bool cResetEvent::Wait(u32 msec)//Wait for signal , then reset +{ + pthread_mutex_lock( &mutx ); + if (!state) + { + struct timespec ts; +#if HOST_OS == OS_DARWIN + // OSX doesn't have clock_gettime. + clock_serv_t cclock; + mach_timespec_t mts; + + host_get_clock_service(mach_host_self(), CALENDAR_CLOCK, &cclock); + clock_get_time(cclock, &mts); + mach_port_deallocate(mach_task_self(), cclock); + ts.tv_sec = mts.tv_sec; + ts.tv_nsec = mts.tv_nsec; +#else + clock_gettime(CLOCK_REALTIME, &ts); +#endif + ts.tv_sec += msec / 1000; + ts.tv_nsec += (msec % 1000) * 1000000; + while (ts.tv_nsec > 1000000000) + { + ts.tv_nsec -= 1000000000; + ts.tv_sec++; + } + pthread_cond_timedwait( &cond, &mutx, &ts ); + } + bool rc = state; + state=false; + pthread_mutex_unlock( &mutx ); + + return rc; +} +void cResetEvent::Wait()//Wait for signal , then reset +{ + pthread_mutex_lock( &mutx ); + if (!state) + { + pthread_cond_wait( &cond, &mutx ); + } + state=false; + pthread_mutex_unlock( &mutx ); +} +#endif -bool VramLockedWrite(u8* address); -bool RamLockedWrite(u8* address,u32* sp); -*/ diff --git a/core/stdclass.h b/core/stdclass.h index 0c30dd534..e7f8d2685 100644 --- a/core/stdclass.h +++ b/core/stdclass.h @@ -7,7 +7,7 @@ #if HOST_OS!=OS_WINDOWS #include #else -#include +#include #endif @@ -166,38 +166,41 @@ public: #if !defined(HOST_NO_THREADS) typedef void* ThreadEntryFP(void* param); -typedef void* THREADHANDLE; - -class cThread -{ +class cThread { private: - ThreadEntryFP* Entry; + ThreadEntryFP* entry; void* param; public : - THREADHANDLE hThread; - cThread(ThreadEntryFP* function,void* param); - + #if HOST_OS==OS_WINDOWS + HANDLE hThread; + #else + pthread_t *hThread; + #endif + + cThread(ThreadEntryFP* function, void* param) + :entry(function), param(param), hThread(NULL) {} + ~cThread() { WaitToEnd(); } void Start(); void WaitToEnd(); }; #endif + + //Wait Events typedef void* EVENTHANDLE; class cResetEvent { - private: #if HOST_OS==OS_WINDOWS EVENTHANDLE hEvent; #else pthread_mutex_t mutx; pthread_cond_t cond; - + bool state; #endif public : - bool state; - cResetEvent(bool State,bool Auto); + cResetEvent(); ~cResetEvent(); void Set(); //Set state to signaled void Reset(); //Set state to non signaled @@ -276,29 +279,38 @@ string get_game_save_prefix(); string get_game_basename(); string get_game_dir(); -class VArray2 -{ + +// Locked memory class, used for texture invalidation purposes. +class VLockedMemory { public: - u8* data; - u32 size; - //void Init(void* data,u32 sz); - //void Term(); - void LockRegion(u32 offset,u32 size); - void UnLockRegion(u32 offset,u32 size); + unsigned size; - void Zero() - { - UnLockRegion(0,size); - memset(data,0,size); + void SetRegion(void* ptr, unsigned size) { + this->data = (u8*)ptr; + this->size = size; + } + void *getPtr() const { return data; } + unsigned getSize() const { return size; } + + #ifdef TARGET_NO_EXCEPTIONS + void LockRegion(unsigned offset, unsigned size_bytes) {} + void UnLockRegion(unsigned offset, unsigned size_bytes) {} + #else + void LockRegion(unsigned offset, unsigned size_bytes); + void UnLockRegion(unsigned offset, unsigned size_bytes); + #endif + + void Zero() { + UnLockRegion(0, size); + memset(data, 0, size); } - INLINE u8& operator [](const u32 i) - { + INLINE u8& operator [](unsigned i) { #ifdef MEM_BOUND_CHECK - if (i>=size) + if (i >= size) { - printf("Error: VArray2 , index out of range (%d>%d)\n",i,size-1); + printf("Error: VLockedMemory , index out of range (%d > %d)\n", i, size-1); MEM_DO_BREAK; } #endif @@ -306,6 +318,7 @@ public: } }; + int msgboxf(const wchar* text,unsigned int type,...); diff --git a/core/types.h b/core/types.h index 9d2e54d4d..8b1a039a8 100644 --- a/core/types.h +++ b/core/types.h @@ -39,7 +39,7 @@ #undef _CRT_SECURE_NO_DEPRECATE #endif -#define _CRT_SECURE_NO_DEPRECATE +#define _CRT_SECURE_NO_DEPRECATE //unnamed struncts/unions #pragma warning( disable : 4201) @@ -123,7 +123,7 @@ enum HollyInterruptType }; enum HollyInterruptID -{ +{ // asic9a /sh4 external holly normal [internal] holly_RENDER_DONE_vd = holly_nrm | 0, //bit 0 = End of Render interrupt : Video holly_RENDER_DONE_isp = holly_nrm | 1, //bit 1 = End of Render interrupt : ISP @@ -132,11 +132,11 @@ enum HollyInterruptID holly_SCANINT1 = holly_nrm | 3, //bit 3 = V Blank-in interrupt holly_SCANINT2 = holly_nrm | 4, //bit 4 = V Blank-out interrupt holly_HBLank = holly_nrm | 5, //bit 5 = H Blank-in interrupt - + holly_YUV_DMA = holly_nrm | 6, //bit 6 = End of Transferring interrupt : YUV holly_OPAQUE = holly_nrm | 7, //bit 7 = End of Transferring interrupt : Opaque List holly_OPAQUEMOD = holly_nrm | 8, //bit 8 = End of Transferring interrupt : Opaque Modifier Volume List - + holly_TRANS = holly_nrm | 9, //bit 9 = End of Transferring interrupt : Translucent List holly_TRANSMOD = holly_nrm | 10, //bit 10 = End of Transferring interrupt : Translucent Modifier Volume List holly_PVR_DMA = holly_nrm | 11, //bit 11 = End of DMA interrupt : PVR-DMA @@ -145,12 +145,12 @@ enum HollyInterruptID holly_MAPLE_VBOI = holly_nrm | 13, //bit 13 = Maple V blank over interrupt holly_GDROM_DMA = holly_nrm | 14, //bit 14 = End of DMA interrupt : GD-DMA holly_SPU_DMA = holly_nrm | 15, //bit 15 = End of DMA interrupt : AICA-DMA - + holly_EXT_DMA1 = holly_nrm | 16, //bit 16 = End of DMA interrupt : Ext-DMA1(External 1) holly_EXT_DMA2 = holly_nrm | 17, //bit 17 = End of DMA interrupt : Ext-DMA2(External 2) holly_DEV_DMA = holly_nrm | 18, //bit 18 = End of DMA interrupt : Dev-DMA(Development tool DMA) - - holly_CH2_DMA = holly_nrm | 19, //bit 19 = End of DMA interrupt : ch2-DMA + + holly_CH2_DMA = holly_nrm | 19, //bit 19 = End of DMA interrupt : ch2-DMA holly_PVR_SortDMA = holly_nrm | 20, //bit 20 = End of DMA interrupt : Sort-DMA (Transferring for alpha sorting) holly_PUNCHTHRU = holly_nrm | 21, //bit 21 = End of Transferring interrupt : Punch Through List @@ -188,8 +188,8 @@ enum HollyInterruptID //bit 23 = G2 : AICA-DMA Time out //bit 24 = G2 : Ext-DMA1 Time out //bit 25 = G2 : Ext-DMA2 Time out - //bit 26 = G2 : Dev-DMA Time out - //bit 27 = G2 : Time out in CPU accessing + //bit 26 = G2 : Dev-DMA Time out + //bit 27 = G2 : Time out in CPU accessing }; @@ -200,7 +200,7 @@ struct vram_block u32 end; u32 len; u32 type; - + void* userdata; }; @@ -229,7 +229,7 @@ struct NDC_WINDOW_RECT //****************************************************** //*********************** PowerVR ********************** //****************************************************** - + void libCore_vramlock_Unlock_block (vram_block* block); void libCore_vramlock_Unlock_block_wb (vram_block* block); vram_block* libCore_vramlock_Lock(u32 start_offset,u32 end_offset,void* userdata); @@ -246,7 +246,7 @@ enum DiscType CdRom_XA=0x20, CdRom_Extra=0x30, CdRom_CDI=0x40, - GdRom=0x80, + GdRom=0x80, NoDisk=0x1, //These are a bit hacky .. but work for now ... Open=0x2, //tray is open :) @@ -344,6 +344,7 @@ int darw_printf(const wchar* Text,...); //includes from c++rt #include #include +#include using namespace std; //used for asm-olny functions @@ -385,9 +386,9 @@ using namespace std; #include "stdclass.h" #ifndef RELEASE -#define EMUERROR(format, ...) printf("Error in %s:%s:%d: " format "\n", \ - strlen(__FILE__) <= 20 ? __FILE__ : __FILE__ + strlen(__FILE__) - 20, \ - __FUNCTION__, __LINE__, ##__VA_ARGS__) +#define EMUERROR(format, ...) printf("Error in %20s:%s:%d: " format "\n", \ + __FILE__, __FUNCTION__, __LINE__, ##__VA_ARGS__) +//strlen(__FILE__) <= 20 ? __FILE__ : __FILE__ + strlen(__FILE__) - 20, #else #define EMUERROR(format, ...) #endif @@ -518,7 +519,7 @@ typedef union -#if COMPILER_VC==BUILD_COMPILER +#if COMPILER_VC_OR_CLANG_WIN32 #pragma warning( disable : 4127 4996 /*4244*/) #else #define stricmp strcasecmp @@ -576,7 +577,7 @@ enum RegIO RIO_RO = REG_RO | REG_WF, RIO_RO_FUNC = REG_RO | REG_RF | REG_WF, RIO_CONST = REG_RO | REG_WF, - RIO_WO_FUNC = REG_WF | REG_RF | REG_WO, + RIO_WO_FUNC = REG_WF | REG_RF | REG_WO, RIO_NO_ACCESS = REG_WF | REG_RF | REG_NO_ACCESS }; @@ -632,7 +633,11 @@ struct settings_t f32 ExtraDepthScale; bool CustomTextures; bool DumpTextures; - int ScreenScaling; // in percent. 50 means half the native resolution + int ScreenScaling; // in percent. 50 means half the native resolution + int ScreenStretching; // in percent. 150 means stretch from 4/3 to 6/3 + bool Fog; + bool FloatVMUs; + bool Rotate90; // Rotate the screen 90 deg CC } rend; struct @@ -644,7 +649,7 @@ struct settings_t bool disable_nvmem; SmcCheckEnum SmcCheckLevel; } dynarec; - + struct { u32 run_counts; @@ -653,7 +658,6 @@ struct settings_t struct { u32 cable; // 0 -> VGA, 1 -> VGA, 2 -> RGB, 3 -> TV - u32 RTC; u32 region; // 0 -> JP, 1 -> USA, 2 -> EU, 3 -> default u32 broadcast; // 0 -> NTSC, 1 -> PAL, 2 -> PAL/M, 3 -> PAL/N, 4 -> default u32 language; // 0 -> JP, 1 -> EN, 2 -> DE, 3 -> FR, 4 -> SP, 5 -> IT, 6 -> default @@ -676,6 +680,14 @@ struct settings_t bool NoSound; } aica; + struct{ + std::string backend; + + // slug<> + std::map> options; + } audio; + + #if USE_OMX struct { @@ -705,7 +717,7 @@ struct settings_t { u32 ta_skip; u32 rend; - + u32 MaxThreads; bool SynchronousRender; } pvr; @@ -748,7 +760,7 @@ static inline void do_nada(...) { } #ifdef _ANDROID #include -#ifdef printf +#ifdef printf #undef printf #endif @@ -855,7 +867,7 @@ void libARM_Update(u32 cycles); else if (sz==2) \ return *(u16*)&arr[addr]; \ else if (sz==4) \ - return *(u32*)&arr[addr];} + return *(u32*)&arr[addr];} #define WriteMemArr(arr,addr,data,sz) \ {if(sz==1) \ @@ -863,7 +875,7 @@ void libARM_Update(u32 cycles); else if (sz==2) \ {*(u16*)&arr[addr]=(u16)data;} \ else if (sz==4) \ - {*(u32*)&arr[addr]=data;}} + {*(u32*)&arr[addr]=data;}} #define WriteMemArrRet(arr,addr,data,sz) \ {if(sz==1) \ @@ -871,7 +883,7 @@ void libARM_Update(u32 cycles); else if (sz==2) \ {*(u16*)&arr[addr]=(u16)data;return;} \ else if (sz==4) \ - {*(u32*)&arr[addr]=data;return;}} + {*(u32*)&arr[addr]=data;return;}} struct OnLoad { diff --git a/core/version.h.in b/core/version.h.in new file mode 100644 index 000000000..81a831a05 --- /dev/null +++ b/core/version.h.in @@ -0,0 +1,8 @@ +/* + * reicast: version.h + */ +#pragma once + +#define REICAST_VERSION "@GIT_VERSION@" +#define GIT_HASH "@GIT_HASH@" +#define BUILD_DATE __DATE__ \ No newline at end of file diff --git a/core/version/.gitignore b/core/version/.gitignore deleted file mode 100644 index 1946cee8c..000000000 --- a/core/version/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/version.cpp diff --git a/core/version/version.h b/core/version/version.h deleted file mode 100644 index 3c9912aa7..000000000 --- a/core/version/version.h +++ /dev/null @@ -1,3 +0,0 @@ -extern const char *version; -extern const char *git_hash; -extern const char *build_date; diff --git a/core/windows/win_vmem.cpp b/core/windows/win_vmem.cpp new file mode 100644 index 000000000..2e456198c --- /dev/null +++ b/core/windows/win_vmem.cpp @@ -0,0 +1,104 @@ + +#define _WIN32_WINNT 0x0500 +#include +#include + +#include "hw/mem/_vmem.h" + +// Implementation of the vmem related function for Windows platforms. +// For now this probably does some assumptions on the CPU/platform. + +// This implements the VLockedMemory interface, as defined in _vmem.h +// The implementation allows it to be empty (that is, to not lock memory). + +void VLockedMemory::LockRegion(unsigned offset, unsigned size) { + //verify(offset + size < this->size && size != 0); + DWORD old; + VirtualProtect(&data[offset], size, PAGE_READONLY, &old); +} + +void VLockedMemory::UnLockRegion(unsigned offset, unsigned size) { + //verify(offset + size <= this->size && size != 0); + DWORD old; + VirtualProtect(&data[offset], size, PAGE_READWRITE, &old); +} + +static HANDLE mem_handle = INVALID_HANDLE_VALUE; +static char * base_alloc = NULL; + +// Implement vmem initialization for RAM, ARAM, VRAM and SH4 context, fpcb etc. +// The function supports allocating 512MB or 4GB addr spaces. + +// Plase read the POSIX implementation for more information. On Windows this is +// rather straightforward. +VMemType vmem_platform_init(void **vmem_base_addr, void **sh4rcb_addr) { + // Firt let's try to allocate the in-memory file + mem_handle = CreateFileMapping(INVALID_HANDLE_VALUE, 0, PAGE_READWRITE, 0, RAM_SIZE_MAX + VRAM_SIZE_MAX + ARAM_SIZE_MAX, 0); + + // Now allocate the actual address space (it will be 64KB aligned on windows). + unsigned memsize = 512*1024*1024 + sizeof(Sh4RCB) + ARAM_SIZE_MAX; + base_alloc = (char*)VirtualAlloc(0, memsize, MEM_RESERVE, PAGE_NOACCESS); + + // Calculate pointers now + *sh4rcb_addr = &base_alloc[0]; + *vmem_base_addr = &base_alloc[sizeof(Sh4RCB)]; + + return MemType512MB; +} + +// Just tries to wipe as much as possible in the relevant area. +void vmem_platform_destroy() { + VirtualFree(base_alloc, 0, MEM_RELEASE); + CloseHandle(mem_handle); +} + +// Resets a chunk of memory by deleting its data and setting its protection back. +void vmem_platform_reset_mem(void *ptr, unsigned size_bytes) { + VirtualFree(ptr, size_bytes, MEM_DECOMMIT); +} + +// Allocates a bunch of memory (page aligned and page-sized) +void vmem_platform_ondemand_page(void *address, unsigned size_bytes) { + verify(VirtualAlloc(address, size_bytes, MEM_COMMIT, PAGE_READWRITE)); +} + +/// Creates mappings to the underlying file including mirroring sections +void vmem_platform_create_mappings(const vmem_mapping *vmem_maps, unsigned nummaps) { + // Since this is tricky to get right in Windows (in posix one can just unmap sections and remap later) + // we unmap the whole thing only to remap it later. + + // Unmap the whole section + VirtualFree(base_alloc, 0, MEM_RELEASE); + + // Map the SH4CB block too + void *base_ptr = VirtualAlloc(base_alloc, sizeof(Sh4RCB), MEM_RESERVE, PAGE_NOACCESS); + verify(base_ptr == base_alloc); + void *cntx_ptr = VirtualAlloc((u8*)p_sh4rcb + sizeof(p_sh4rcb->fpcb), sizeof(Sh4RCB) - sizeof(p_sh4rcb->fpcb), MEM_COMMIT, PAGE_READWRITE); + verify(cntx_ptr == (u8*)p_sh4rcb + sizeof(p_sh4rcb->fpcb)); + + for (unsigned i = 0; i < nummaps; i++) { + unsigned address_range_size = vmem_maps[i].end_address - vmem_maps[i].start_address; + DWORD protection = vmem_maps[i].allow_writes ? (FILE_MAP_READ | FILE_MAP_WRITE) : FILE_MAP_READ; + + if (!vmem_maps[i].memsize) { + // Unmapped stuff goes with a protected area or memory. Prevent anything from allocating here + void *ptr = VirtualAlloc(&virt_ram_base[vmem_maps[i].start_address], address_range_size, MEM_RESERVE, PAGE_NOACCESS); + verify(ptr == &virt_ram_base[vmem_maps[i].start_address]); + } + else { + // Calculate the number of mirrors + unsigned num_mirrors = (address_range_size) / vmem_maps[i].memsize; + verify((address_range_size % vmem_maps[i].memsize) == 0 && num_mirrors >= 1); + + // Remap the views one by one + for (unsigned j = 0; j < num_mirrors; j++) { + unsigned offset = vmem_maps[i].start_address + j * vmem_maps[i].memsize; + + void *ptr = MapViewOfFileEx(mem_handle, protection, 0, vmem_maps[i].memoffset, + vmem_maps[i].memsize, &virt_ram_base[offset]); + verify(ptr == &virt_ram_base[offset]); + } + } + } +} + diff --git a/core/windows/winmain.cpp b/core/windows/winmain.cpp index 1731193e9..adec1ffa9 100644 --- a/core/windows/winmain.cpp +++ b/core/windows/winmain.cpp @@ -1,6 +1,6 @@ -#include "oslib\oslib.h" -#include "oslib\audiostream.h" -#include "imgread\common.h" +#include "oslib/oslib.h" +#include "oslib/audiostream.h" +#include "imgread/common.h" #include "stdclass.h" #include "cfg/cfg.h" #include "xinput_gamepad.h" @@ -10,8 +10,8 @@ #include #include -#include -#include "hw\maple\maple_cfg.h" +#include +#include "hw/maple/maple_cfg.h" #pragma comment(lib, "XInput9_1_0.lib") PCHAR* @@ -148,12 +148,10 @@ LONG ExeptionHandler(EXCEPTION_POINTERS *ExceptionInfo) { return EXCEPTION_CONTINUE_EXECUTION; } -#ifndef TARGET_NO_NVMEM else if (BM_LockedWrite(address)) { return EXCEPTION_CONTINUE_EXECUTION; } -#endif #if FEAT_SHREC == DYNAREC_JIT && HOST_CPU == CPU_X86 else if ( ngen_Rewrite((unat&)ep->ContextRecord->Eip,*(unat*)ep->ContextRecord->Esp,ep->ContextRecord->Eax) ) { @@ -188,8 +186,6 @@ u16 kcode[4] = { 0xffff, 0xffff, 0xffff, 0xffff }; u32 vks[4]; s8 joyx[4],joyy[4]; u8 rt[4],lt[4]; -extern bool coin_chute; -extern bool naomi_test_button; // Mouse extern s32 mo_x_abs; extern s32 mo_y_abs; @@ -200,6 +196,10 @@ extern f32 mo_wheel_delta; // Keyboard static Win32KeyboardDevice keyboard(0); + +void ToggleFullscreen(); + + void UpdateInputState(u32 port) { /* @@ -220,12 +220,6 @@ void UpdateInputState(u32 port) std::shared_ptr gamepad = XInputGamepadDevice::GetXInputDevice(port); if (gamepad != NULL) gamepad->ReadInput(); - -#if DC_PLATFORM == DC_PLATFORM_NAOMI || DC_PLATFORM == DC_PLATFORM_ATOMISWAVE - // FIXME - coin_chute = GetAsyncKeyState(VK_F8); - naomi_test_button = GetAsyncKeyState(VK_F7); -#endif } // Windows class name to register @@ -339,6 +333,14 @@ LRESULT CALLBACK WndProc2(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) keyboard.keyboard_input(keycode, message == WM_KEYDOWN); } break; + + case WM_SYSKEYDOWN: + if (wParam == VK_RETURN) + if ((HIWORD(lParam) & KF_ALTDOWN)) + ToggleFullscreen(); + + break; + case WM_CHAR: keyboard.keyboard_character((char)wParam); return 0; @@ -396,6 +398,45 @@ void* libPvr_GetRenderSurface() return GetDC((HWND)window_win); } + +void ToggleFullscreen() +{ + static RECT rSaved; + static bool fullscreen=false; + HWND hWnd = (HWND)window_win; + + fullscreen = !fullscreen; + + + if (fullscreen) + { + GetWindowRect(hWnd, &rSaved); + + MONITORINFO mi = { sizeof(mi) }; + HMONITOR hmon = MonitorFromWindow(hWnd, MONITOR_DEFAULTTONEAREST); + if (GetMonitorInfo(hmon, &mi)) { + + SetWindowLongPtr(hWnd, GWL_EXSTYLE, WS_EX_APPWINDOW | WS_EX_TOPMOST); + SetWindowLongPtr(hWnd, GWL_STYLE, WS_POPUP | WS_VISIBLE); + + SetWindowPos(hWnd, HWND_TOPMOST, mi.rcMonitor.left, mi.rcMonitor.top, + mi.rcMonitor.right - mi.rcMonitor.left, mi.rcMonitor.bottom - mi.rcMonitor.top, + SWP_SHOWWINDOW|SWP_FRAMECHANGED|SWP_ASYNCWINDOWPOS); + } + } + else { + + SetWindowLongPtr(hWnd, GWL_EXSTYLE, WS_EX_APPWINDOW | WS_EX_TOPMOST); + SetWindowLongPtr(hWnd, GWL_STYLE, WS_VISIBLE | WS_OVERLAPPEDWINDOW | (window_maximized ? WS_MAXIMIZE : 0)); + + SetWindowPos(hWnd, NULL, rSaved.left, rSaved.top, + rSaved.right - rSaved.left, rSaved.bottom - rSaved.top, + SWP_SHOWWINDOW|SWP_FRAMECHANGED|SWP_ASYNCWINDOWPOS|SWP_NOZORDER); + } + +} + + BOOL CtrlHandler( DWORD fdwCtrlType ) { switch( fdwCtrlType ) @@ -646,15 +687,31 @@ int CALLBACK WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine int argc=0; wchar* cmd_line=GetCommandLineA(); wchar** argv=CommandLineToArgvA(cmd_line,&argc); - if(strstr(cmd_line,"NoConsole")==0) + for (int i = 0; i < argc; i++) { - if (AllocConsole()) + if (!stricmp(argv[i], "-console")) { - freopen("CON","w",stdout); - freopen("CON","w",stderr); - freopen("CON","r",stdin); + if (AllocConsole()) + { + freopen("CON", "w", stdout); + freopen("CON", "w", stderr); + freopen("CON", "r", stdin); + } + SetConsoleCtrlHandler((PHANDLER_ROUTINE)CtrlHandler, TRUE); + } + else if (!stricmp(argv[i], "-log")) + { + const char *logfile; + if (i < argc - 1) + { + logfile = argv[i + 1]; + i++; + } + else + logfile = "reicast-log.txt"; + freopen(logfile, "w", stdout); + freopen(logfile, "w", stderr); } - SetConsoleCtrlHandler( (PHANDLER_ROUTINE) CtrlHandler, TRUE ); } #endif @@ -662,14 +719,13 @@ int CALLBACK WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine ReserveBottomMemory(); SetupPath(); -#ifndef __GNUC__ - __try -#else #ifdef _WIN64 AddVectoredExceptionHandler(1, ExeptionHandler); #else - SetUnhandledExceptionFilter(&ExeptionHandler); + SetUnhandledExceptionFilter((LPTOP_LEVEL_EXCEPTION_FILTER)&ExeptionHandler); #endif +#ifndef __GNUC__ + __try #endif { int reicast_init(int argc, char* argv[]); @@ -742,90 +798,5 @@ void os_DoEvents() } } - - - -//Windoze Code implementation of commong classes from here and after .. - -//Thread class -cThread::cThread(ThreadEntryFP* function,void* prm) -{ - Entry=function; - param=prm; -} - - -void cThread::Start() -{ - hThread=CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)Entry,param,0,NULL); - ResumeThread(hThread); -} - -void cThread::WaitToEnd() -{ - WaitForSingleObject(hThread,INFINITE); -} -//End thread class - -//cResetEvent Calss -cResetEvent::cResetEvent(bool State,bool Auto) -{ - hEvent = CreateEvent( - NULL, // default security attributes - Auto?FALSE:TRUE, // auto-reset event? - State?TRUE:FALSE, // initial state is State - NULL // unnamed object - ); -} -cResetEvent::~cResetEvent() -{ - //Destroy the event object ? - CloseHandle(hEvent); -} -void cResetEvent::Set()//Signal -{ - #if defined(DEBUG_THREADS) - Sleep(rand() % 10); - #endif - SetEvent(hEvent); -} -void cResetEvent::Reset()//reset -{ - #if defined(DEBUG_THREADS) - Sleep(rand() % 10); - #endif - ResetEvent(hEvent); -} -bool cResetEvent::Wait(u32 msec)//Wait for signal , then reset -{ - #if defined(DEBUG_THREADS) - Sleep(rand() % 10); - #endif - return WaitForSingleObject(hEvent,msec) == WAIT_OBJECT_0; -} -void cResetEvent::Wait()//Wait for signal , then reset -{ - #if defined(DEBUG_THREADS) - Sleep(rand() % 10); - #endif - WaitForSingleObject(hEvent,(u32)-1); -} -//End AutoResetEvent - -void VArray2::LockRegion(u32 offset,u32 size) -{ - //verify(offset+sizesize); - verify(size!=0); - DWORD old; - VirtualProtect(((u8*)data)+offset , size, PAGE_READONLY,&old); -} -void VArray2::UnLockRegion(u32 offset,u32 size) -{ - //verify(offset+size<=this->size); - verify(size!=0); - DWORD old; - VirtualProtect(((u8*)data)+offset , size, PAGE_READWRITE,&old); -} - int get_mic_data(u8* buffer) { return 0; } int push_vmu_screen(u8* buffer) { return 0; } diff --git a/core/windows/xinput_gamepad.h b/core/windows/xinput_gamepad.h index 894d0aa79..beb311413 100644 --- a/core/windows/xinput_gamepad.h +++ b/core/windows/xinput_gamepad.h @@ -1,4 +1,4 @@ -#include +#include #include "input/gamepad_device.h" #include "rend/gui.h" @@ -181,7 +181,6 @@ protected: private: void do_rumble(float power) { - printf("do_rumble %f\n", power); XINPUT_VIBRATION vib; vib.wLeftMotorSpeed = (u16)(65535 * power); diff --git a/shell/android-studio/reicast/src/dreamcast/AndroidManifest.xml b/shell/android-studio/reicast/src/dreamcast/AndroidManifest.xml index 165b7b014..d0a0cfb3b 100644 --- a/shell/android-studio/reicast/src/dreamcast/AndroidManifest.xml +++ b/shell/android-studio/reicast/src/dreamcast/AndroidManifest.xml @@ -3,54 +3,57 @@ xmlns:tools="http://schemas.android.com/tools"> - - - - - - - - - - - - - - - - + android:name="com.reicast.emulator.NativeGLActivity"/> + + + + + + + + + + + + + + + + + - \ No newline at end of file + diff --git a/shell/android-studio/reicast/src/main/AndroidManifest.xml b/shell/android-studio/reicast/src/main/AndroidManifest.xml index de600f7bc..bc93a562f 100644 --- a/shell/android-studio/reicast/src/main/AndroidManifest.xml +++ b/shell/android-studio/reicast/src/main/AndroidManifest.xml @@ -53,14 +53,18 @@ + android:screenOrientation="sensorLandscape" + android:exported="true"/> + - + vjoy[j][1] && y <= (vjoy[j][1] + vjoy[j][3])) { if (vjoy[j][4] >= -2) { if (vjoy[j][5] == 0) - if (!editVjoyMode && Emulator.vibrationDuration > 0) - vib.vibrate(Emulator.vibrationDuration); + if (!editVjoyMode) { + vibratorThread.vibrate(); + } vjoy[j][5] = 2; } @@ -397,4 +401,51 @@ public class VirtualJoystickDelegate { selectedVjoyElement = -1; } } + + private class VibratorThread extends Thread + { + private Vibrator vibrator; + private boolean vibrate = false; + private boolean stopping = false; + + VibratorThread(Context context) { + vibrator = (Vibrator)context.getSystemService(Context.VIBRATOR_SERVICE); + } + + @Override + public void run() { + while (!stopping) { + boolean doVibrate; + synchronized (this) { + doVibrate = false; + try { + this.wait(); + } catch (InterruptedException e) { + } + if (vibrate) { + doVibrate = true; + vibrate = false; + } + } + if (doVibrate) + vibrator.vibrate(Emulator.vibrationDuration); + } + } + + public void stopVibrator() { + synchronized (this) { + stopping = true; + notify(); + } + } + + public void vibrate() { + if (Emulator.vibrationDuration > 0) { + synchronized (this) { + vibrate = true; + notify(); + } + } + } + } } diff --git a/shell/android-studio/reicast/src/main/jni/Android.mk b/shell/android-studio/reicast/src/main/jni/Android.mk index 357131a41..0eb55d90a 100644 --- a/shell/android-studio/reicast/src/main/jni/Android.mk +++ b/shell/android-studio/reicast/src/main/jni/Android.mk @@ -22,6 +22,7 @@ WEBUI := 1 USE_GLES := 1 CHD5_LZMA := 1 CHD5_FLAC := 1 +USE_MODEM := 1 ifneq ($(TARGET_ARCH_ABI),armeabi-v7a) NOT_ARM := 1 @@ -112,6 +113,8 @@ else endif endif +$(LOCAL_SRC_FILES): $(VERSION_HEADER) + # # android has poor support for hardfp calling. # r9b+ is required, and it only works for internal calls diff --git a/shell/android-studio/reicast/src/main/jni/src/Android.cpp b/shell/android-studio/reicast/src/main/jni/src/Android.cpp index 3ab96e5dd..07521e6ee 100644 --- a/shell/android-studio/reicast/src/main/jni/src/Android.cpp +++ b/shell/android-studio/reicast/src/main/jni/src/Android.cpp @@ -20,7 +20,7 @@ #include "hw/maple/maple_devs.h" #include "hw/maple/maple_if.h" #include "hw/naomi/naomi_cart.h" -#include "oslib/audiobackend_android.h" +#include "oslib/audiostream.h" #include "imgread/common.h" #include "rend/gui.h" #include "cfg/cfg.h" @@ -91,8 +91,7 @@ JNIEXPORT void JNICALL Java_com_reicast_emulator_emu_JNIdc_destroy(JNIEnv *env,j JNIEXPORT jint JNICALL Java_com_reicast_emulator_emu_JNIdc_send(JNIEnv *env,jobject obj,jint id, jint v) __attribute__((visibility("default"))); JNIEXPORT jint JNICALL Java_com_reicast_emulator_emu_JNIdc_data(JNIEnv *env,jobject obj,jint id, jbyteArray d) __attribute__((visibility("default"))); -JNIEXPORT void JNICALL Java_com_reicast_emulator_emu_JNIdc_rendinitNative(JNIEnv *env, jobject obj, jobject surface, jint w, jint h) __attribute__((visibility("default"))); -JNIEXPORT jboolean JNICALL Java_com_reicast_emulator_emu_JNIdc_rendframeNative(JNIEnv *env,jobject obj) __attribute__((visibility("default"))); +JNIEXPORT void JNICALL Java_com_reicast_emulator_emu_JNIdc_rendinitNative(JNIEnv *env, jobject obj, jobject surface) __attribute__((visibility("default"))); JNIEXPORT void JNICALL Java_com_reicast_emulator_emu_JNIdc_rendinitJava(JNIEnv *env, jobject obj, jint w, jint h) __attribute__((visibility("default"))); JNIEXPORT jboolean JNICALL Java_com_reicast_emulator_emu_JNIdc_rendframeJava(JNIEnv *env, jobject obj) __attribute__((visibility("default"))); JNIEXPORT void JNICALL Java_com_reicast_emulator_emu_JNIdc_rendtermJava(JNIEnv *env, jobject obj) __attribute__((visibility("default"))); @@ -404,35 +403,57 @@ JNIEXPORT jint JNICALL Java_com_reicast_emulator_emu_JNIdc_data(JNIEnv *env, job extern void gl_swap(); extern void egl_stealcntx(); +volatile static bool render_running; +volatile static bool render_reinit; -JNIEXPORT jboolean JNICALL Java_com_reicast_emulator_emu_JNIdc_rendframeNative(JNIEnv *env,jobject obj) +void *render_thread_func(void *) { - if (g_window == NULL) - return false; - if (!egl_makecurrent()) - return false; - jboolean ret = (jboolean)rend_single_frame(); - if (ret) - gl_swap(); - return ret; + render_running = true; + + rend_init_renderer(); + + while (render_running) { + if (render_reinit) + { + render_reinit = false; + rend_init_renderer(); + } + else + if (!egl_makecurrent()) + break;; + + bool ret = rend_single_frame(); + if (ret) + gl_swap(); + } + egl_makecurrent(); + rend_term_renderer(); + ANativeWindow_release(g_window); + g_window = NULL; + render_running = false; + + return NULL; } -JNIEXPORT void JNICALL Java_com_reicast_emulator_emu_JNIdc_rendinitNative(JNIEnv * env, jobject obj, jobject surface, jint width, jint height) +static cThread render_thread(render_thread_func, NULL); + +JNIEXPORT void JNICALL Java_com_reicast_emulator_emu_JNIdc_rendinitNative(JNIEnv * env, jobject obj, jobject surface) { - if (g_window != NULL) - { - egl_makecurrent(); - rend_term_renderer(); - ANativeWindow_release(g_window); - g_window = NULL; - } - if (surface != NULL) - { + if (render_thread.hThread != NULL) + { + if (surface == NULL) + { + render_running = false; + render_thread.WaitToEnd(); + } + else + render_reinit = true; + } + else if (surface != NULL) + { g_window = ANativeWindow_fromSurface(env, surface); - rend_init_renderer(); - screen_width = width; - screen_height = height; - } + render_thread.Start(); + } } JNIEXPORT void JNICALL Java_com_reicast_emulator_emu_JNIdc_rendinitJava(JNIEnv * env, jobject obj, jint width, jint height) @@ -526,9 +547,13 @@ audiobackend_t audiobackend_android = { "Android Audio", // Name &androidaudio_init, &androidaudio_push, - &androidaudio_term + &androidaudio_term, + NULL }; +static bool android = RegisterAudioBackend(&audiobackend_android); + + JNIEXPORT void JNICALL Java_com_reicast_emulator_emu_AudioBackend_setInstance(JNIEnv *env, jobject obj, jobject instance) { if (g_audioBackend != NULL) @@ -568,7 +593,7 @@ void os_DebugBreak() raise(SIGABRT); //pthread_exit(NULL); - + // Attach debugger here to figure out what went wrong for(;;) ; } diff --git a/shell/android-studio/reicast/src/naomi/AndroidManifest.xml b/shell/android-studio/reicast/src/naomi/AndroidManifest.xml index ce8b25026..a1a4c24b2 100644 --- a/shell/android-studio/reicast/src/naomi/AndroidManifest.xml +++ b/shell/android-studio/reicast/src/naomi/AndroidManifest.xml @@ -3,7 +3,10 @@ android:name="com.reicast.emulator.Emulator"> + android:name="com.reicast.emulator.NativeGLActivity"/> + @@ -61,6 +64,6 @@ android:pathPattern=".*\\.7z" android:scheme="file" /> - + diff --git a/shell/apple/emulator-osx/reicast-osx.xcodeproj/project.pbxproj b/shell/apple/emulator-osx/reicast-osx.xcodeproj/project.pbxproj index b50789eb9..835041b08 100644 --- a/shell/apple/emulator-osx/reicast-osx.xcodeproj/project.pbxproj +++ b/shell/apple/emulator-osx/reicast-osx.xcodeproj/project.pbxproj @@ -266,6 +266,7 @@ AEE6278E2224762000EC7E89 /* imgui_impl_opengl3.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AEE6278B2224762000EC7E89 /* imgui_impl_opengl3.cpp */; }; AEE6279422247C0A00EC7E89 /* gui_util.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AEE6279222247C0A00EC7E89 /* gui_util.cpp */; }; AEE6279622247C2B00EC7E89 /* keyboard_device.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AEE6279522247C2B00EC7E89 /* keyboard_device.cpp */; }; + AEF2564822886A2E00348550 /* posix_vmem.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AEF2564722886A2E00348550 /* posix_vmem.cpp */; }; AEFF7ECC214AEC810068CE11 /* modem.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AEFF7EC7214AEC800068CE11 /* modem.cpp */; }; AEFF7F4D214D9D590068CE11 /* pico_arp.c in Sources */ = {isa = PBXBuildFile; fileRef = AEFF7EFA214D9D590068CE11 /* pico_arp.c */; }; AEFF7F4E214D9D590068CE11 /* pico_dev_ppp.c in Sources */ = {isa = PBXBuildFile; fileRef = AEFF7EFE214D9D590068CE11 /* pico_dev_ppp.c */; }; @@ -803,6 +804,7 @@ AEE6279222247C0A00EC7E89 /* gui_util.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = gui_util.cpp; sourceTree = ""; }; AEE6279322247C0A00EC7E89 /* gui_util.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = gui_util.h; sourceTree = ""; }; AEE6279522247C2B00EC7E89 /* keyboard_device.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = keyboard_device.cpp; sourceTree = ""; }; + AEF2564722886A2E00348550 /* posix_vmem.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = posix_vmem.cpp; sourceTree = ""; }; AEFF7EC7214AEC800068CE11 /* modem.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = modem.cpp; sourceTree = ""; }; AEFF7EC8214AEC800068CE11 /* modem.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = modem.h; sourceTree = ""; }; AEFF7EC9214AEC800068CE11 /* modem_regs.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = modem_regs.h; sourceTree = ""; }; @@ -1556,6 +1558,7 @@ 84B7BE661B72720100F9733F /* context.cpp */, 84B7BE671B72720100F9733F /* context.h */, 84B7BE681B72720100F9733F /* nixprof */, + AEF2564722886A2E00348550 /* posix_vmem.cpp */, 84B7BE6A1B72720100F9733F /* typedefs.h */, ); name = linux; @@ -2199,7 +2202,7 @@ ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "echo \"const char *version = \\\"`git describe --tags --always`\\\";\" > $SRCROOT/../../../core/version/version.cpp\necho \"const char *git_hash = \\\"`git rev-parse --short HEAD`\\\";\" >> $SRCROOT/../../../core/version/version.cpp\necho \"const char *build_date = \\\"`date '+%Y-%m-%d %H:%M:%S %Z'`\\\";\" >> $SRCROOT/../../../core/version/version.cpp\n"; + shellScript = "echo \"#define REICAST_VERSION \\\"`git describe --tags --always`\\\"\" > $SRCROOT/../../../core/version.h\necho \"#define GIT_HASH \\\"`git rev-parse --short HEAD`\\\"\" >> $SRCROOT/../../../core/version.h\necho \"#define BUILD_DATE \\\"`date '+%Y-%m-%d %H:%M:%S %Z'`\\\"\" >> $SRCROOT/../../../core/version.h\n"; }; /* End PBXShellScriptBuildPhase section */ @@ -2310,6 +2313,7 @@ 84B7BF131B72720200F9733F /* zip_unchange_all.c in Sources */, 84B7BF541B72720200F9733F /* sh4_interrupts.cpp in Sources */, AE2A2D7F21D6851E004B308D /* 7zFile.c in Sources */, + AEF2564822886A2E00348550 /* posix_vmem.cpp in Sources */, 84B7BF6B1B72720200F9733F /* audiostream.cpp in Sources */, 84B7BEFB1B72720200F9733F /* zip_get_file_comment.c in Sources */, 84B7BF301B72720200F9733F /* holly_intc.cpp in Sources */, @@ -2546,6 +2550,7 @@ TARGET_NO_AREC, XBYAK_NO_OP_NAMES, TARGET_NO_OPENMP, + ENABLE_MODEM, CHD5_LZMA, _7ZIP_ST, CHD5_FLAC, @@ -2602,6 +2607,7 @@ TARGET_NO_AREC, XBYAK_NO_OP_NAMES, TARGET_NO_OPENMP, + ENABLE_MODEM, CHD5_LZMA, _7ZIP_ST, CHD5_FLAC, diff --git a/shell/cmake/GetGitRevisionDescription.cmake b/shell/cmake/GetGitRevisionDescription.cmake new file mode 100644 index 000000000..8ab03bc5f --- /dev/null +++ b/shell/cmake/GetGitRevisionDescription.cmake @@ -0,0 +1,168 @@ +# - Returns a version string from Git +# +# These functions force a re-configure on each git commit so that you can +# trust the values of the variables in your build system. +# +# get_git_head_revision( [ ...]) +# +# Returns the refspec and sha hash of the current head revision +# +# git_describe( [ ...]) +# +# Returns the results of git describe on the source tree, and adjusting +# the output so that it tests false if an error occurs. +# +# git_get_exact_tag( [ ...]) +# +# Returns the results of git describe --exact-match on the source tree, +# and adjusting the output so that it tests false if there was no exact +# matching tag. +# +# git_local_changes() +# +# Returns either "CLEAN" or "DIRTY" with respect to uncommitted changes. +# Uses the return code of "git diff-index --quiet HEAD --". +# Does not regard untracked files. +# +# Requires CMake 2.6 or newer (uses the 'function' command) +# +# Original Author: +# 2009-2010 Ryan Pavlik +# http://academic.cleardefinition.com +# Iowa State University HCI Graduate Program/VRAC +# +# Copyright Iowa State University 2009-2010. +# Distributed under the Boost Software License, Version 1.0. +# (See accompanying file LICENSE_1_0.txt or copy at +# http://www.boost.org/LICENSE_1_0.txt) + +if(__get_git_revision_description) + return() +endif() +set(__get_git_revision_description YES) + +# We must run the following at "include" time, not at function call time, +# to find the path to this module rather than the path to a calling list file +get_filename_component(_gitdescmoddir ${CMAKE_CURRENT_LIST_FILE} PATH) + +function(get_git_head_revision _refspecvar _hashvar) + set(GIT_PARENT_DIR "${CMAKE_CURRENT_SOURCE_DIR}") + set(GIT_DIR "${GIT_PARENT_DIR}/.git") + while(NOT EXISTS "${GIT_DIR}") # .git dir not found, search parent directories + set(GIT_PREVIOUS_PARENT "${GIT_PARENT_DIR}") + get_filename_component(GIT_PARENT_DIR ${GIT_PARENT_DIR} PATH) + if(GIT_PARENT_DIR STREQUAL GIT_PREVIOUS_PARENT) + # We have reached the root directory, we are not in git + set(${_refspecvar} "GITDIR-NOTFOUND" PARENT_SCOPE) + set(${_hashvar} "GITDIR-NOTFOUND" PARENT_SCOPE) + return() + endif() + set(GIT_DIR "${GIT_PARENT_DIR}/.git") + endwhile() + # check if this is a submodule + if(NOT IS_DIRECTORY ${GIT_DIR}) + file(READ ${GIT_DIR} submodule) + string(REGEX REPLACE "gitdir: (.*)\n$" "\\1" GIT_DIR_RELATIVE ${submodule}) + get_filename_component(SUBMODULE_DIR ${GIT_DIR} PATH) + get_filename_component(GIT_DIR ${SUBMODULE_DIR}/${GIT_DIR_RELATIVE} ABSOLUTE) + endif() + set(GIT_DATA "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/git-data") + if(NOT EXISTS "${GIT_DATA}") + file(MAKE_DIRECTORY "${GIT_DATA}") + endif() + + if(NOT EXISTS "${GIT_DIR}/HEAD") + return() + endif() + set(HEAD_FILE "${GIT_DATA}/HEAD") + configure_file("${GIT_DIR}/HEAD" "${HEAD_FILE}" COPYONLY) + + configure_file("${_gitdescmoddir}/GetGitRevisionDescription.cmake.in" + "${GIT_DATA}/grabRef.cmake" + @ONLY) + include("${GIT_DATA}/grabRef.cmake") + + set(${_refspecvar} "${HEAD_REF}" PARENT_SCOPE) + set(${_hashvar} "${HEAD_HASH}" PARENT_SCOPE) +endfunction() + +function(git_describe _var) + if(NOT GIT_FOUND) + find_package(Git QUIET) + endif() + get_git_head_revision(refspec hash) + if(NOT GIT_FOUND) + set(${_var} "GIT-NOTFOUND" PARENT_SCOPE) + return() + endif() + if(NOT hash) + set(${_var} "HEAD-HASH-NOTFOUND" PARENT_SCOPE) + return() + endif() + + # TODO sanitize + #if((${ARGN}" MATCHES "&&") OR + # (ARGN MATCHES "||") OR + # (ARGN MATCHES "\\;")) + # message("Please report the following error to the project!") + # message(FATAL_ERROR "Looks like someone's doing something nefarious with git_describe! Passed arguments ${ARGN}") + #endif() + + #message(STATUS "Arguments to execute_process: ${ARGN}") + + execute_process(COMMAND + "${GIT_EXECUTABLE}" + describe + ${hash} + ${ARGN} + WORKING_DIRECTORY + "${CMAKE_CURRENT_SOURCE_DIR}" + RESULT_VARIABLE + res + OUTPUT_VARIABLE + out + ERROR_QUIET + OUTPUT_STRIP_TRAILING_WHITESPACE) + if(NOT res EQUAL 0) + set(out "${out}-${res}-NOTFOUND") + endif() + + set(${_var} "${out}" PARENT_SCOPE) +endfunction() + +function(git_get_exact_tag _var) + git_describe(out --exact-match ${ARGN}) + set(${_var} "${out}" PARENT_SCOPE) +endfunction() + +function(git_local_changes _var) + if(NOT GIT_FOUND) + find_package(Git QUIET) + endif() + get_git_head_revision(refspec hash) + if(NOT GIT_FOUND) + set(${_var} "GIT-NOTFOUND" PARENT_SCOPE) + return() + endif() + if(NOT hash) + set(${_var} "HEAD-HASH-NOTFOUND" PARENT_SCOPE) + return() + endif() + + execute_process(COMMAND + "${GIT_EXECUTABLE}" + diff-index --quiet HEAD -- + WORKING_DIRECTORY + "${CMAKE_CURRENT_SOURCE_DIR}" + RESULT_VARIABLE + res + OUTPUT_VARIABLE + out + ERROR_QUIET + OUTPUT_STRIP_TRAILING_WHITESPACE) + if(res EQUAL 0) + set(${_var} "CLEAN" PARENT_SCOPE) + else() + set(${_var} "DIRTY" PARENT_SCOPE) + endif() +endfunction() diff --git a/shell/cmake/GetGitRevisionDescription.cmake.in b/shell/cmake/GetGitRevisionDescription.cmake.in new file mode 100644 index 000000000..6d8b708ef --- /dev/null +++ b/shell/cmake/GetGitRevisionDescription.cmake.in @@ -0,0 +1,41 @@ +# +# Internal file for GetGitRevisionDescription.cmake +# +# Requires CMake 2.6 or newer (uses the 'function' command) +# +# Original Author: +# 2009-2010 Ryan Pavlik +# http://academic.cleardefinition.com +# Iowa State University HCI Graduate Program/VRAC +# +# Copyright Iowa State University 2009-2010. +# Distributed under the Boost Software License, Version 1.0. +# (See accompanying file LICENSE_1_0.txt or copy at +# http://www.boost.org/LICENSE_1_0.txt) + +set(HEAD_HASH) + +file(READ "@HEAD_FILE@" HEAD_CONTENTS LIMIT 1024) + +string(STRIP "${HEAD_CONTENTS}" HEAD_CONTENTS) +if(HEAD_CONTENTS MATCHES "ref") + # named branch + string(REPLACE "ref: " "" HEAD_REF "${HEAD_CONTENTS}") + if(EXISTS "@GIT_DIR@/${HEAD_REF}") + configure_file("@GIT_DIR@/${HEAD_REF}" "@GIT_DATA@/head-ref" COPYONLY) + else() + configure_file("@GIT_DIR@/packed-refs" "@GIT_DATA@/packed-refs" COPYONLY) + file(READ "@GIT_DATA@/packed-refs" PACKED_REFS) + if(${PACKED_REFS} MATCHES "([0-9a-z]*) ${HEAD_REF}") + set(HEAD_HASH "${CMAKE_MATCH_1}") + endif() + endif() +else() + # detached HEAD + configure_file("@GIT_DIR@/HEAD" "@GIT_DATA@/head-ref" COPYONLY) +endif() + +if(NOT HEAD_HASH) + file(READ "@GIT_DATA@/head-ref" HEAD_HASH LIMIT 1024) + string(STRIP "${HEAD_HASH}" HEAD_HASH) +endif() diff --git a/shell/cmake/android.cmake b/shell/cmake/android.cmake new file mode 100644 index 000000000..366fcb043 --- /dev/null +++ b/shell/cmake/android.cmake @@ -0,0 +1,101 @@ +## android.cmake +# + + + +function(TestPathNDK ndkPath) +# + file(TO_CMAKE_PATH "${ndkPath}" testPath) + + if(NOT NDK AND EXISTS "${testPath}") + if(EXISTS "${testPath}/ndk-bundle") + set(NDK ${testPath}/ndk-bundle PARENT_SCOPE) + elseif(EXISTS "${testPath}/sysroot") + set(NDK ${testPath} PARENT_SCOPE) + endif() + endif() +# +endfunction(TestPathNDK) + + +TestPathNDK("$ENV{ANDROID_HOME}") +TestPathNDK("$ENV{NDK}") +TestPathNDK("$ENV{NDK_ROOT}") + +if(NOT NDK) + message("Failed to find NDK !") +endif() + + + + + + +### option for ARM || ARM64 ? HOST isn't useful it's a cross ... + +#set(CMAKE_SYSTEM_PROCESSOR aarch64) + + + +set(CMAKE_SYSTEM_NAME Android) +set(CMAKE_SYSTEM_VERSION 22) # API level + +set(CMAKE_ANDROID_NDK ${NDK}) +set(CMAKE_ANDROID_ARCH_ABI armeabi-v7a) #arm64-v8a , armeabi-v7a , armeabi +set(CMAKE_ANDROID_STL_TYPE c++_static) #gnustl_static libc++ will allow C++17, if you use _shared you must include in apk ! +set(CMAKE_ANDROID_NDK_TOOLCHAIN_VERSION clang) + + +#arm $TOOLCHAIN/ arm-linux-androideabi /lib/ +#arm64 $TOOLCHAIN/ aarch64-linux-android /lib/ +#x86 $TOOLCHAIN/ i686-linux-android /lib/ +#x86_64 $TOOLCHAIN/ x86_64-linux-android /lib/ + + + +#include(${NDK}/build/cmake/android.toolchain.cmake) + + +set(ANDROID ON) + +add_definitions(-D_ANDROID -DANDROID) +add_definitions(-DANDROID_STL=c++_static) + + +add_definitions(-DTARGET_ANDROID) + +add_definitions(-DGLES) + + + + + +## FML + +#[[ +CMAKE_ANDROID_ANT_ADDITIONAL_OPTIONS +CMAKE_ANDROID_API +CMAKE_ANDROID_API_MIN +CMAKE_ANDROID_ARCH +CMAKE_ANDROID_ARCH_ABI +CMAKE_ANDROID_ARM_MODE +CMAKE_ANDROID_ARM_NEON +CMAKE_ANDROID_ASSETS_DIRECTORIES +CMAKE_ANDROID_GUI +CMAKE_ANDROID_JAR_DEPENDENCIES +CMAKE_ANDROID_JAR_DIRECTORIES +CMAKE_ANDROID_JAVA_SOURCE_DIR +CMAKE_ANDROID_NATIVE_LIB_DEPENDENCIES +CMAKE_ANDROID_NATIVE_LIB_DIRECTORIES +CMAKE_ANDROID_NDK +CMAKE_ANDROID_NDK_DEPRECATED_HEADERS +CMAKE_ANDROID_NDK_TOOLCHAIN_HOST_TAG +CMAKE_ANDROID_NDK_TOOLCHAIN_VERSION +CMAKE_ANDROID_PROCESS_MAX +CMAKE_ANDROID_PROGUARD +CMAKE_ANDROID_PROGUARD_CONFIG_PATH +CMAKE_ANDROID_SECURE_PROPS_PATH +CMAKE_ANDROID_SKIP_ANT_STEP +CMAKE_ANDROID_STANDALONE_TOOLCHAIN +CMAKE_ANDROID_STL_TYPE +#]] diff --git a/shell/cmake/config.cmake b/shell/cmake/config.cmake new file mode 100644 index 000000000..d1dfd59e4 --- /dev/null +++ b/shell/cmake/config.cmake @@ -0,0 +1,422 @@ +## config module +# +# get luserx0 to doc this shit or something, vars in all caps are to be exported as defs if they aren't in build.h already +# handle options for FEAT per platform, so rec isn't built for targets w.o one... +# *TODO* fix Android for build system in emu too, OS_LINUX is hardly fitting: prob works better as PLATFORM_ANDROID_{S,N}DK or something +# *TODO* setup git version like it's done in VS/make and configure header so --version works still +# *TODO* lots of other shit to improve build, add enabling/disabling libs/features, setting 3rd party libs as either built in static, dynamic or shared/system +# +# + + +set(ZBUILD Off) + + + +set(BUILD_LIBS OFF) ## Scope:Local If set will build libs { dreamcast, osd, ... } +set(BUILD_LIB_TYPE STATIC) ## Scope:Local If BUILD_LIBS is set, will use this as type of lib to use { STATIC, SHARED, MODULE (plugin) } *TODO* +set(BUILD_SHARED_LIBS OFF) ## Scope:CMAKE If type is not specified in add_library, use SHARED + + + + +## Build flags ## +# + +set(DC_PLATFORM_MASK 7) # Z: Uh, not a bitset +set(DC_PLATFORM_DREAMCAST 0) # /* Works, for the most part */ +set(DC_PLATFORM_DEV_UNIT 1) # /* This is missing hardware */ +set(DC_PLATFORM_NAOMI 2) # /* Works, for the most part */ +set(DC_PLATFORM_NAOMI2 3) # /* Needs to be done, 2xsh4 + 2xpvr + custom TNL */ +set(DC_PLATFORM_ATOMISWAVE 4) # /* Needs to be done, DC-like hardware with possibly more ram */ +set(DC_PLATFORM_HIKARU 5) # /* Needs to be done, 2xsh4, 2x aica , custom vpu */ +set(DC_PLATFORM_AURORA 6) # /* Needs to be done, Uses newer 300 mhz sh4 + 150 mhz pvr mbx SoC */ + + + +set(OS_WINDOWS 0x10000001) # HOST_OS +set(OS_LINUX 0x10000002) +set(OS_DARWIN 0x10000003) +set(OS_IOS 0x10000004) # todo: iOS != OS_DARWIN +set(OS_ANDROID 0x10000005) # todo: should be SYSTEM_ANDROID but ! OS_LINUX + +set(OS_UWP 0x10000011) +set(OS_NSW_HOS 0x80000001) +set(OS_PS4_BSD 0x80000002) + + + +set(CPU_X86 0x20000001) # HOST_CPU +set(CPU_X64 0x20000004) +set(CPU_ARM 0x20000002) +set(CPU_A64 0x20000008) +set(CPU_MIPS 0x20000003) +set(CPU_MIPS64 0x20000009) +set(CPU_PPC 0x20000006) +set(CPU_PPC64 0x20000007) +set(CPU_GENERIC 0x20000005) # used for pnacl, emscripten, etc + +set(DYNAREC_NONE 0x40000001) # FEAT_SHREC, FEAT_AREC, FEAT_DSPREC +set(DYNAREC_JIT 0x40000002) +set(DYNAREC_CPP 0x40000003) + +set(COMPILER_VC 0x30000001) # BUILD_COMPILER +set(COMPILER_GCC 0x30000002) +set(COMPILER_CLANG 0x30000003) +set(COMPILER_INTEL 0x30000004) + + + + + + + +## These default to host, but are used for cross so make sure not to contaminate +# +# CMAKE_SYSTEM ${CMAKE_SYSTEM_NAME}-${CMAKE_SYSTEM_VERSION}. +# CMAKE_SYSTEM_NAME CMAKE_HOST_SYSTEM_NAME uname -s Linux, Windows, and Darwin +# CMAKE_SYSTEM_VERSION CMAKE_HOST_SYSTEM_VERSION uname -r +# CMAKE_SYSTEM_PROCESSOR CMAKE_HOST_SYSTEM_PROCESSOR uname -p +# +# +# +# BOOL: CMAKE_HOST_UNIX CMAKE_HOST_WIN32 CMAKE_HOST_APPLE +# +# +# CMAKE_LIBRARY_ARCHITECTURE CMAKE__LIBRARY_ARCHITECTURE /lib/ +# +# + + + + +## strings are used to append to path/file names, and to filter multiple possibilities down to one +# AMD64/x86_64:x64, i*86:x86, ppc/powerpc[64][b|l]e:ppc[64] etc +# +if("${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "i686") # todo: check MATCHES "i.86" ? + set(host_arch "x86") + set(HOST_CPU ${CPU_X86}) +# +elseif(("${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "AMD64") OR + ("${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "x86_64")) + set(host_arch "x64") + set(HOST_CPU ${CPU_X64}) +# +elseif("${CMAKE_SYSTEM_PROCESSOR}" MATCHES "aarch64") + set(host_arch "arm64") + set(HOST_CPU ${CPU_A64}) +# +elseif("${CMAKE_SYSTEM_PROCESSOR}" MATCHES "arm") + set(host_arch "arm") + set(HOST_CPU ${CPU_ARM}) +# +elseif("${CMAKE_SYSTEM_PROCESSOR}" MATCHES "ppc64") + set(host_arch "ppc64") + set(HOST_CPU ${CPU_PPC64}) +# +elseif("${CMAKE_SYSTEM_PROCESSOR}" MATCHES "ppc") # has to be done after ppc64 obv + set(host_arch "ppc") + set(HOST_CPU ${CPU_PPC}) +# +elseif("${CMAKE_SYSTEM_PROCESSOR}" MATCHES "mips64") # todo: check , r* names? + set(host_arch "mips64") + set(HOST_CPU ${CPU_MIPS64}) +# +elseif("${CMAKE_SYSTEM_PROCESSOR}" MATCHES "mips") # todo: check , r* names? + set(host_arch "mips") + set(HOST_CPU ${CPU_MIPS}) +# +else() + message("Warning: Unknown Host System Processor: \"${CMAKE_SYSTEM_PROCESSOR}\"") + set(host_arch "${CMAKE_SYSTEM_PROCESSOR}") + set(HOST_CPU ${CPU_GENERIC}) +endif() + + + + +string(TOLOWER ${CMAKE_SYSTEM_NAME} host_os) + +#message(" - testing cmake host_os: \"${host_os}\"") + +## HOST_* is not TARGET_* ;; change ndc-e internal naming it's wrong , then change this ;; + +if("android" STREQUAL "${host_os}" OR ANDROID) + set(HOST_OS ${OS_LINUX}) # *FIXME* we might have to keep as OS_LINUX or add to full cleanup list :| + +elseif("windowsstore" STREQUAL "${host_os}") + set(HOST_OS ${OS_UWP}) + set(HOST_CPU ${CPU_X64}) + +elseif(CMAKE_HOST_WIN32) + set(HOST_OS ${OS_WINDOWS}) + +elseif(CMAKE_HOST_APPLE) + + if("${host_arch}" MATCHES "arm") + set(HOST_OS ${OS_IOS}) + set(TARGET_IOS On) + add_definitions(-DTARGET_IPHONE -DTARGET_IOS) + else() + set(HOST_OS ${OS_DARWIN}) # todo ios check, check compiler/arch? + set(TARGET_OSX On) + add_definitions(-DTARGET_OSX) + endif() + +elseif(CMAKE_HOST_UNIX) # GP UNIX MUST BE AFTER OTHER UNIX'ish options such as APPLE , it matches both + + set(HOST_OS ${OS_LINUX}) # todo android check, just check android vars? +endif() + + + +#option(TARGET_NO_REC BOOL "") +#option(TARGET_NO_AREC BOOL "") +#option(TARGET_NO_JIT BOOL "") + + + +## Dynarec avail on x86,x64,arm and aarch64 in arm.32 compat +# +if((${HOST_CPU} EQUAL ${CPU_X86}) OR (${HOST_CPU} EQUAL ${CPU_X64}) OR + (${HOST_CPU} EQUAL ${CPU_ARM}) OR (${HOST_CPU} EQUAL ${CPU_A64})) +# + message("Dynarec Features Available") + + set(FEAT_SHREC ${DYNAREC_JIT}) + set(FEAT_AREC ${DYNAREC_NONE}) + set(FEAT_DSPREC ${DYNAREC_NONE}) +# +else() + set(FEAT_SHREC ${DYNAREC_CPP}) + set(FEAT_AREC ${DYNAREC_NONE}) + set(FEAT_DSPREC ${DYNAREC_NONE}) +endif() + +## Handle TARGET_* to FEAT_ *FIXME* stupid use one or the other and propogate : part of build cleanup , TARGET_ will only be for platform specifics and FEAT_ as OPTIONS +# +if(TARGET_NO_REC) + set(FEAT_SHREC ${DYNAREC_NONE}) + set(FEAT_AREC ${DYNAREC_NONE}) + set(FEAT_DSPREC ${DYNAREC_NONE}) +endif() + +if(TARGET_NO_AREC) + set(FEAT_SHREC ${DYNAREC_JIT}) + set(FEAT_AREC ${DYNAREC_NONE}) + set(FEAT_DSPREC ${DYNAREC_NONE}) +endif() + +if(TARGET_NO_JIT) + set(FEAT_SHREC ${DYNAREC_CPP}) + set(FEAT_AREC ${DYNAREC_NONE}) + set(FEAT_DSPREC ${DYNAREC_NONE}) +endif() + + + + + +######## Looks like something to delete, but if we're going to handle options here and NOT in libosd/lib* ######### + +# FindNativeCompilers() +## options BUILD_COMPILER { GCC, Clang, Intel, RealView? } + + +#set(CMAKE_C_COMPILER clang) +#set(CMAKE_C_COMPILER_TARGET ${triple}) +#set(CMAKE_CXX_COMPILER clang++) +#set(CMAKE_CXX_COMPILER_TARGET ${triple}) + + + +if(${HOST_OS} EQUAL ${OS_LINUX}) +# option SUPPORT_X11 +# option FEAT_HAS_NIXPROF +# option EMSCripten +endif() + +if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC") +# + set(BUILD_COMPILER ${COMPILER_VC}) + message("MSVC Platform: ${CMAKE_VS_PLATFORM_NAME}") + message("MSVC Toolset: ${CMAKE_VS_PLATFORM_TOOLSET}") + + + add_definitions(/D_CRT_SECURE_NO_WARNINGS /D_CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES=1) + + if("${HOST_OS}" STREQUAL "${OS_UWP}") + set(_CXX_FLAGS "/ZW ") + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /AppContainer") + endif() +# +elseif("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU") + set(BUILD_COMPILER ${COMPILER_GCC}) +# +elseif("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang") # AppleClang ffs + set(BUILD_COMPILER ${COMPILER_CLANG}) +# +elseif("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Intel") + set(BUILD_COMPILER ${COMPILER_INTEL}) +# +else() + message("Unknown Compiler: ${CMAKE_CXX_COMPILER_ID}") +endif() + + + +## Setup some common flags +# +if ((${BUILD_COMPILER} EQUAL ${COMPILER_VC}) OR + (${BUILD_COMPILER} EQUAL ${COMPILER_CLANG}) AND (${HOST_OS} STREQUAL ${OS_WINDOWS})) + + if((${HOST_CPU} EQUAL ${CPU_X64}) AND (${FEAT_SHREC} EQUAL ${DYNAREC_JIT})) # AND NOT "${NINJA}" STREQUAL "") + set(FEAT_SHREC ${DYNAREC_CPP}) + message("---x64 rec disabled for VC x64 via NINJA") + endif() + + add_definitions(/D_CRT_SECURE_NO_WARNINGS /D_CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES=1) + + if(${BUILD_COMPILER} EQUAL ${COMPILER_CLANG}) + add_definitions(/DXBYAK_NO_OP_NAMES /DTARGET_NO_OPENMP) #*FIXME* check openmp on clang-cl + remove_definitions(/U_HAS_STD_BYTE) + set(_CXX_FLAGS "/std:c++14") # /U_HAS_STD_BYTE not working, have to use c++14 not 17 :| + set(_C_FLAGS "-Wno-unused-function -Wno-unused-variable") + endif() + + +elseif ((${BUILD_COMPILER} EQUAL ${COMPILER_GCC}) OR + (${BUILD_COMPILER} EQUAL ${COMPILER_CLANG})) # AND NOT ${HOST_OS} EQUAL ${OS_WINDOWS})) + + if(USE_32B OR TARGET_LINUX_X86) + set(_C_FLAGS "${_C_FLAGS} -m32") + endif() + + if((${HOST_CPU} EQUAL ${CPU_X86}) OR (${HOST_CPU} EQUAL ${CPU_X64})) + set(_C_FLAGS "${_C_FLAGS} -msse4") + + if(NOT CMAKE_HOST_APPLE) + set(_C_FLAGS "${_C_FLAGS} -fopenmp") + endif() + endif() # X86 family + + + set(_CXX_FLAGS "${_CXX_FLAGS} -fno-operator-names -fpermissive -std=c++11") # -fcxx-exceptions") ## xbyak needs exceptions + + +endif() + + +set(_CXX_FLAGS "${_CXX_FLAGS} ${_C_FLAGS}") + + + +set(CMAKE_C_FLAGS " ${_C_FLAGS}") # ${CMAKE_C_FLAGS} -- these hold default VC flags for non VC Build ? +set(CMAKE_CXX_FLAGS " ${_CXX_FLAGS}") # ${CMAKE_CXX_FLAGS} + + + +#if defined(TARGET_NAOMI) + #define DC_PLATFORM DC_PLATFORM_NAOMI + #undef TARGET_NAOMI +#endif + + + +#if defined(TARGET_NO_NIXPROF) +#define FEAT_HAS_NIXPROF 0 +#endif + +#if defined(TARGET_NO_COREIO_HTTP) +#define FEAT_HAS_COREIO_HTTP 0 +#endif + +#if defined(TARGET_SOFTREND) # need -fopenmp + #define FEAT_HAS_SOFTREND 1 +#endif + + +if (TARGET_NSW) # -DCMAKE_TOOLCHAIN_FILE=./cmake/devkitA64.cmake -DTARGET_NSW=ON + set(HOST_OS ${OS_NSW_HOS}) + + message(" DEVKITA64: ${DEVKITA64} ") + message("HOST_OS ${HOST_OS}") + + add_definitions(-D__SWITCH__ -DGLES -DMESA_EGL_NO_X11_HEADERS) + add_definitions(-DTARGET_NO_THREADS -DTARGET_NO_EXCEPTIONS -DTARGET_NO_NIXPROF) + add_definitions(-DTARGET_NO_COREIO_HTTP -DTARGET_NO_WEBUI -UTARGET_SOFTREND) + add_definitions(-D_GLIBCXX_USE_C99_MATH_TR1 -D_LDBL_EQ_DBL) + +endif() + +if (TARGET_PS4) # -DCMAKE_TOOLCHAIN_FILE=./cmake/{ps4sdk,clang_scei}.cmake -DTARGET_PS4=ON + set(HOST_OS ${OS_PS4_BSD}) + message("HOST_OS ${HOST_OS}") + + + add_definitions(-DPS4 -DTARGET_PS4 -DTARGET_BSD -D__ORBIS__ -DGLES -DMESA_EGL_NO_X11_HEADERS) ## last needed for __unix__ on eglplatform.h + add_definitions(-DTARGET_NO_THREADS -DTARGET_NO_EXCEPTIONS -DTARGET_NO_NIXPROF) + add_definitions(-DTARGET_NO_COREIO_HTTP -DTARGET_NO_WEBUI -UTARGET_SOFTREND) + + + message("*******FIXME******** LARGE PAGES !!") +endif() + + + +if(ZBUILD) + set(DEBUG_CMAKE ON) + add_definitions(-D_Z_) # Get rid of some warnings and internal dev testing + + if(NOT TARGET_PS4 AND NOT TARGET_NSW AND + NOT TARGET_OSX AND NOT TARGET_IOS ) + set(USE_QT ON) + endif() +endif() + + + +# configure options for osd/ui +# osd_default, osd_qt +# ui_default, ui_sdl, ui_qt +# USE_NATIVE , USE_SDL , USE_QT -- these (can) define multiple + +option(USE_QT False "Use Qt5 for UI and support OS Deps.") + + + + +#option TARGET_NO_WEBUI + + + + + +#option(BUILD_TESTS "Build tests" OFF) # todo: luserx0 this is your arena, you want tests add em + + +add_definitions(-DCMAKE_BUILD) + + + + +add_definitions(-DHOST_OS=${HOST_OS}) +add_definitions(-DHOST_CPU=${HOST_CPU}) + +add_definitions(-DFEAT_AREC=${FEAT_AREC}) +add_definitions(-DFEAT_SHREC=${FEAT_SHREC}) +add_definitions(-DFEAT_DSPREC=${FEAT_DSPREC}) + +add_definitions(-DBUILD_COMPILER=${BUILD_COMPILER}) + +add_definitions(-DTARGET_NO_WEBUI) +add_definitions(-DDEF_CONSOLE) + + +set(RE_CMAKE_CONFIGURED 1) +#add_definitions(-D=${}) + + + + + diff --git a/shell/cmake/devkitA64.cmake b/shell/cmake/devkitA64.cmake new file mode 100644 index 000000000..3eb80ff24 --- /dev/null +++ b/shell/cmake/devkitA64.cmake @@ -0,0 +1,41 @@ +## devkitA64.cmake - devkitpro A64 cross-compile +# +set(CMAKE_SYSTEM_NAME Linux) # this one is important // Add Platform/switch to use this name ... +set(CMAKE_SYSTEM_PROCESSOR aarch64) + +set(CMAKE_SYSTEM_VERSION 1) # this one not so much + + +set(DEVKITPRO $ENV{DEVKITPRO}) +set(DEVKITA64 $ENV{DEVKITA64}) + + +if ("" STREQUAL "${DEVKITPRO}") + set(DEVKITA64 "/opt/devkitpro") +endif() + +if ("" STREQUAL "${DEVKITA64}") + set(DEVKITA64 ${DEVKITPRO}/devkitA64) +endif() + + +## specify the cross compiler +# +set(CMAKE_C_COMPILER ${DEVKITA64}/bin/aarch64-none-elf-gcc) +set(CMAKE_CXX_COMPILER ${DEVKITA64}/bin/aarch64-none-elf-g++) + + +set(CMAKE_FIND_ROOT_PATH ${DEVKITA64}) # where is the target environment + +set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) # search for programs in the build host directories +set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) # for libraries and headers in the target directories +set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) + + + + +include_directories(${DEVKITPRO}/libnx/include) + + + +set(TARGET_NSW ON) diff --git a/shell/cmake/ps4sdk.cmake b/shell/cmake/ps4sdk.cmake new file mode 100644 index 000000000..d8cac168f --- /dev/null +++ b/shell/cmake/ps4sdk.cmake @@ -0,0 +1,130 @@ +## ps4sdk.cmake - devkitpro A64 cross-compile +# +set(CMAKE_SYSTEM_NAME FreeBSD) # this one is important +set(CMAKE_SYSTEM_PROCESSOR x86_64) +set(CMAKE_SYSTEM_VERSION 9) # this one not so much + + + + +set(TARGET_PS4 ON) +set(TARGET_BSD ON) + + + +### This shit is very WIP ### +# +## TODO: Check for + + +set(PS4SDK $ENV{PS4SDK}) +set(SCESDK $ENV{SCESDK}) + +set(USE_SCE ON) +set(PS4_PKG ON) + +if(PS4_PKG) + add_definitions(-DPS4_PKG) +endif() + + + +if ("" STREQUAL "${PS4SDK}") + if ("Windows" STREQUAL "${CMAKE_HOST_SYSTEM_NAME}") + set(PS4SDK "C:/Dev/SDK/PS4") + else() + set(PS4SDK "/opt/ps4") + endif() +endif() + + + +set(TAUON_SDK ${PS4SDK}/tauon) + + + +if(USE_SCE) +# + set(PS4SDK ${PS4SDK}/SCE/PS4SDK) + + set(PS4HOST ${PS4SDK}/host_tools) + set(PS4TARGET ${PS4SDK}/target) + + set(toolPrefix "orbis-") + set(toolSuffix ".exe") + + set(CMAKE_C_COMPILER ${PS4HOST}/bin/${toolPrefix}clang${toolSuffix}) + set(CMAKE_CXX_COMPILER ${PS4HOST}/bin/${toolPrefix}clang++${toolSuffix}) + + set(CMAKE_FIND_ROOT_PATH ${PS4TARGET}) # where is the target environment + + + + set (PS4_inc_dirs + ${TAUON_SDK}/include + ${PS4TARGET}/include + ${PS4TARGET}/include_common + ) + +# set (PS4_link_dirs +# "${PS4TARGET}/lib" +# "${PS4TARGET}/tauon/lib" +# ) + + +#LDFLAGS += -L $(TAUON_SDK_DIR)/lib -L $(SCE_ORBIS_SDK_DIR)/target/lib + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -s -Wl,--addressing=non-aslr,--strip-unused-data ") + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -L ${TAUON_SDK}/lib -L ${PS4TARGET}/lib") + + message("CMAKE_EXE_LINKER_FLAGS ${CMAKE_EXE_LINKER_FLAGS}") +# +else() +# + set(triple "x86_64-scei-ps4") + + set(CMAKE_C_COMPILER_TARGET ${triple}) + set(CMAKE_CXX_COMPILER_TARGET ${triple}) + + set(CMAKE_C_COMPILER clang) + set(CMAKE_CXX_COMPILER clang++) + + + set (PS4_inc_dirs + ${TAUON_SDK}/include + + ${PS4SDK}/include + ${PS4SDK}/tauon/include + ) + +# set (PS4_link_dirs +# "${PS4SDK}/lib" +# "${PS4SDK}/tauon/lib" +# ) + + + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -s -Wl,--addressing=non-aslr,--strip-unused-data -L${TAUON_SDK}/lib") +# +endif() + + + + +set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) # search for programs in the build host directories +set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY BOTH) # for libraries and headers in the target directories +set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE BOTH) + + +include_directories(${PS4_inc_dirs}) + + + + + ### Add a helper to add libSce PREFIX and [_tau]*_stub[_weak]*.a SUFFIX + # +link_libraries( + kernel_tau_stub_weak SceSysmodule_tau_stub_weak SceSystemService_stub_weak SceSystemService_tau_stub_weak SceShellCoreUtil_tau_stub_weak ScePigletv2VSH_tau_stub_weak kernel_util + ScePad_stub_weak SceNet_stub_weak SceCommonDialog_stub_weak ScePosix_stub_weak +) + + + diff --git a/shell/emscripten/Makefile b/shell/emscripten/Makefile index 6f1054198..1b8ef4c22 100644 --- a/shell/emscripten/Makefile +++ b/shell/emscripten/Makefile @@ -26,7 +26,7 @@ LDFLAGS := -Wl,-Map,$(notdir $@).map,--gc-sections -Wl,-O3 -Wl,--sort-common CXXONLYFLAGS := -std=c++11 -CXXFLAGS := -O3 -D GLES -D RELEASE -c -D TARGET_EMSCRIPTEN -D TARGET_NO_REC -D TARGET_NO_NVMEM -D TARGET_NO_WEBUI -D TARGET_NO_THREADS -D TARGET_BOUNDED_EXECUTION -D TARGET_NO_EXCEPTIONS -D TARGET_NO_COREIO_HTTP +CXXFLAGS := -O3 -D GLES -D RELEASE -c -D TARGET_EMSCRIPTEN -D TARGET_NO_REC -D TARGET_NO_EXCEPTIONS -D TARGET_NO_WEBUI -D TARGET_NO_THREADS -D TARGET_BOUNDED_EXECUTION -D TARGET_NO_COREIO_HTTP CXXFLAGS += -fno-strict-aliasing CXXFLAGS += -ffast-math diff --git a/shell/linux/Makefile b/shell/linux/Makefile index eea87ef76..c3a32668a 100644 --- a/shell/linux/Makefile +++ b/shell/linux/Makefile @@ -6,9 +6,11 @@ FOR_LINUX :=1 WEBUI :=1 USE_OSS := 1 #USE_PULSEAUDIO := 1 +#USE_SDLAUDIO := 1 #USE_LIBAO := 1 USE_EVDEV := 1 USE_UDEV := 1 +USE_MODEM := 1 PLATFORM_EXT := elf CXX=${CC_PREFIX}g++ @@ -16,6 +18,7 @@ CC=${CC_PREFIX}gcc AS=${CC_PREFIX}as STRIP=${CC_PREFIX}strip LD=${CC} +WINDRES=${CC_PREFIX}windres CHD5_LZMA := 1 CHD5_FLAC := 1 @@ -45,6 +48,7 @@ ifeq (,$(platform)) else ifeq ($(ARCH), $(filter $(ARCH), x86_64 AMD64 amd64)) platform = x64 else ifneq (,$(findstring aarch64,$(ARCH))) + platform = arm64 HARDWARE = $(shell grep Hardware /proc/cpuinfo) ifneq (,$(findstring Vero4K,$(HARDWARE))) platform = vero4k @@ -122,6 +126,15 @@ else ifneq (,$(findstring x64,$(platform))) HAS_SOFTREND := 1 endif +# Generic 64 bit ARM (armv8) Linux +else ifneq (,$(findstring arm64,$(platform))) + NOT_ARM := 1 + USE_X11 := 1 + ARM64_REC := 1 + ISARM64 := 1 + CFLAGS += -D TARGET_LINUX_ARMv8 -D TARGET_NO_AREC -fno-builtin-sqrtf + CXXFLAGS += -fexceptions + # Generic 32 bit ARMhf (a.k.a. ARMv7h) else ifneq (,$(findstring armv7h,$(platform))) MFLAGS += -marm -mfloat-abi=hard -march=armv7-a -funroll-loops @@ -240,7 +253,7 @@ else ifneq (,$(findstring vero4k,$(platform))) else ifneq (,$(findstring win32,$(platform))) NOT_ARM := 1 CFLAGS += -DTARGET_NO_WEBUI -fno-builtin-sqrtf -funroll-loops -DHAVE_FSEEKO -D TARGET_NO_AREC - LDFLAGS += -static-libgcc -static-libstdc++ + LDFLAGS += -static-libgcc -static-libstdc++ -Wl,-subsystem,windows LIBS := -lopengl32 -lwinmm -lgdi32 -lwsock32 -ldsound -lcomctl32 -lcomdlg32 -lxinput -liphlpapi PLATFORM_EXT := exe CC = gcc @@ -265,15 +278,6 @@ else $(error Unknown platform) endif -# 7-Zip/LZMA settings (CHDv5) -ifdef CHD5_LZMA - CFLAGS += -D_7ZIP_ST -DCHD5_LZMA -endif - -ifdef CHD5_FLAC - CFLAGS += -DCHD5_FLAC -endif - RZDCY_SRC_DIR = $(LOCAL_PATH)/../../core include $(RZDCY_SRC_DIR)/core.mk @@ -289,7 +293,7 @@ INCS += -I$(RZDCY_SRC_DIR) -I$(RZDCY_SRC_DIR)/deps -I$(RZDCY_SRC_DIR)/khronos LIBS += -lm -lpthread ifdef FOR_LINUX -LIBS += -lrt -ldl +LIBS += -lrt endif PREFIX ?= /usr/local @@ -360,6 +364,11 @@ ifdef USE_PULSEAUDIO LIBS += `pkg-config --libs libpulse-simple` endif +ifdef USE_SDLAUDIO + CXXFLAGS += `sdl2-config --cflags` -D USE_SDL_AUDIO + LIBS += `sdl2-config --libs` +endif + ifdef USE_LIBAO CXXFLAGS += `pkg-config --cflags ao` -D USE_LIBAO LIBS += `pkg-config --libs ao` @@ -421,6 +430,12 @@ OBJECTS:=$(OBJECTS:.c=.build_obj) OBJECTS:=$(OBJECTS:.S=.build_obj) OBJECTS:=$(patsubst $(RZDCY_SRC_DIR)/%,$(BUILDDIR)/%,$(OBJECTS)) +ifdef FOR_WINDOWS +OBJECTS+=$(BUILDDIR)/reicastres.build_obj +$(BUILDDIR)/reicastres.build_obj: $(LOCAL_PATH)/../windows/reicast.rc $(LOCAL_PATH)/../windows/reicast.ico $(RZDCY_SRC_DIR)/version.h + $(WINDRES) $< $@ +endif + DEPDIR := .dep-$(BUILDDIR) DEPFLAGS = -MT $@ -MD -MP -MF $(DEPDIR)/$*.Td DEPS=$(RZDCY_FILES:.cpp=.d) @@ -442,27 +457,27 @@ $(EXECUTABLE_STRIPPED): $(EXECUTABLE) cp $< $@ && $(STRIP) $@ $(BUILDDIR)/%.build_obj : $(RZDCY_SRC_DIR)/%.cpp -$(BUILDDIR)/%.build_obj: $(RZDCY_SRC_DIR)/%.cpp $(DEPDIR)/%.d +$(BUILDDIR)/%.build_obj: $(RZDCY_SRC_DIR)/%.cpp $(DEPDIR)/%.d $(VERSION_HEADER) mkdir -p $(dir $@) mkdir -p .dep-$(dir $@) $(CXX) $(EXTRAFLAGS) $(INCS) $(DEPFLAGS) $(CFLAGS) $(MFLAGS) $(CXXFLAGS) $< -o $@ $(POSTCOMPILE) $(BUILDDIR)/%.build_obj : $(RZDCY_SRC_DIR)/%.cc -$(BUILDDIR)/%.build_obj: $(RZDCY_SRC_DIR)/%.cc $(DEPDIR)/%.d +$(BUILDDIR)/%.build_obj: $(RZDCY_SRC_DIR)/%.cc $(DEPDIR)/%.d $(VERSION_HEADER) mkdir -p $(dir $@) mkdir -p .dep-$(dir $@) $(CXX) $(EXTRAFLAGS) $(INCS) $(DEPFLAGS) $(CFLAGS) $(MFLAGS) $(CXXFLAGS) $< -o $@ $(POSTCOMPILE) $(BUILDDIR)/%.build_obj : $(RZDCY_SRC_DIR)/%.c -$(BUILDDIR)/%.build_obj: $(RZDCY_SRC_DIR)/%.c $(DEPDIR)/%.d +$(BUILDDIR)/%.build_obj: $(RZDCY_SRC_DIR)/%.c $(DEPDIR)/%.d $(VERSION_HEADER) mkdir -p $(dir $@) mkdir -p .dep-$(dir $@) $(CC) $(EXTRAFLAGS) $(INCS) $(DEPFLAGS) $(CFLAGS) $< -o $@ $(POSTCOMPILE) -$(BUILDDIR)/%.build_obj : $(RZDCY_SRC_DIR)/%.S +$(BUILDDIR)/%.build_obj : $(RZDCY_SRC_DIR)/%.S $(VERSION_HEADER) mkdir -p $(dir $@) $(AS) $(ASFLAGS) $(INCS) $< -o $@ @@ -500,7 +515,7 @@ uninstall: rm -f $(DESTDIR)$(ICON_DIR)/reicast.png clean: - rm -f $(OBJECTS) $(EXECUTABLE) $(EXECUTABLE_STRIPPED) .map + rm -f $(OBJECTS) $(EXECUTABLE) $(EXECUTABLE_STRIPPED) .map $(VERSION_HEADER) .PRECIOUS = $(DEPDIR)/%.d $(DEPDIR)/%.d: ; diff --git a/shell/nacl/Makefile b/shell/nacl/Makefile index 733a7d538..fec9cf250 100644 --- a/shell/nacl/Makefile +++ b/shell/nacl/Makefile @@ -23,7 +23,7 @@ CFLAGS = -Wno-error -Wno-ignored-attributes CFLAGS += -O3 -fno-strict-aliasing -ffast-math CFLAGS += -I$(RZDCY_SRC_DIR) -I$(RZDCY_SRC_DIR)/deps CFLAGS += -D RELEASE -D TARGET_NO_JIT -D TARGET_NACL32 -DGLES -CFLAGS += -D TARGET_NO_EXCEPTIONS -D TARGET_NO_NVMEM -D TARGET_NO_WEBUI -D TARGET_NO_COREIO_HTTP +CFLAGS += -D TARGET_NO_EXCEPTIONS -D TARGET_NO_WEBUI -D TARGET_NO_COREIO_HTTP SOURCES = $(RZDCY_FILES) ../../core/nacl/nacl.cpp @@ -49,4 +49,4 @@ endif SHELL = sh -$(eval $(call NMF_RULE,$(TARGET),)) \ No newline at end of file +$(eval $(call NMF_RULE,$(TARGET),)) diff --git a/shell/reicast.vcxproj b/shell/reicast.vcxproj index 6a8ec8b4c..93904ce9a 100644 --- a/shell/reicast.vcxproj +++ b/shell/reicast.vcxproj @@ -35,6 +35,27 @@ + + true + true + true + true + true + true + true + true + + + + true + true + true + true + true + true + true + true + @@ -47,6 +68,7 @@ + @@ -68,6 +90,10 @@ + + + + @@ -154,6 +180,11 @@ + + + + + @@ -192,9 +223,13 @@ + + + + true true @@ -269,6 +304,8 @@ + + @@ -276,14 +313,21 @@ + + + + + + + @@ -297,6 +341,7 @@ + @@ -313,6 +358,13 @@ + + + + + + + @@ -384,9 +436,17 @@ + + + + + + + + @@ -430,6 +490,10 @@ + + + + true true @@ -454,6 +518,11 @@ + + + + Document + true true @@ -464,9 +533,14 @@ + + + + + @@ -501,7 +575,7 @@ Win32Proj reicast reicast - 10.0.17134.0 + 10.0.17763.0 @@ -640,7 +714,7 @@ Level3 Full WIN32;CHD5_FLAC;PACKAGE_VERSION="1.3.2";FLAC__HAS_OGG=0;FLAC__NO_DLL;HAVE_LROUND;HAVE_STDINT_H;HAVE_STDLIB_H;CHD5_LZMA;_7ZIP_ST;NDEBUG;_CONSOLE;X86;RELEASE;%(PreprocessorDefinitions) - $(ProjectDir)..\core\;$(ProjectDir)..\core\khronos;$(ProjectDir)..\core\rend\gles;$(ProjectDir)..\core\deps\flac\src\libflac\include;$(ProjectDir)..\core\deps\flac\include + $(ProjectDir)..\core\;$(ProjectDir)..\core\khronos;$(ProjectDir)..\core\rend\gles;$(ProjectDir)..\core\deps;$(ProjectDir)..\core\deps\flac\src\libflac\include;$(ProjectDir)..\core\deps\flac\include /MP %(AdditionalOptions) AnySuitable true @@ -664,6 +738,13 @@ $(SolutionDir)..\pvrframe Dsound.lib;winmm.lib;wsock32.lib;comctl32.lib;%(AdditionalDependencies) + + for /f "delims=" %%i in ('git describe') do echo #define REICAST_VERSION "%%i" >$(ProjectDir)\..\core\version.h +for /f "delims=" %%i in ('git rev-parse --short HEAD') do echo #define GIT_HASH "%%i" >>$(ProjectDir)\..\core\version.h +for /f "delims=" %%i in ('date /T') do echo #define BUILD_DATE "%%i" >>$(ProjectDir)\..\core\version.h + + Create version.h + @@ -672,7 +753,7 @@ Level3 Full WIN32;CHD5_FLAC;PACKAGE_VERSION="1.3.2";FLAC__HAS_OGG=0;FLAC__NO_DLL;HAVE_LROUND;HAVE_STDINT_H;HAVE_STDLIB_H;CHD5_LZMA;_7ZIP_ST;NDEBUG;_CONSOLE;X86;RELEASE;TARGET_NAOMI;%(PreprocessorDefinitions) - $(ProjectDir)..\core\;$(ProjectDir)..\core\khronos;$(ProjectDir)..\core\rend\gles;$(ProjectDir)..\core\deps\flac\src\libflac\include;$(ProjectDir)..\core\deps\flac\include + $(ProjectDir)..\core\;$(ProjectDir)..\core\khronos;$(ProjectDir)..\core\rend\gles;$(ProjectDir)..\core\deps;$(ProjectDir)..\core\deps\flac\src\libflac\include;$(ProjectDir)..\core\deps\flac\include /MP %(AdditionalOptions) AnySuitable true @@ -696,6 +777,13 @@ $(SolutionDir)..\pvrframe Dsound.lib;winmm.lib;wsock32.lib;comctl32.lib;%(AdditionalDependencies) + + for /f "delims=" %%i in ('git describe') do echo #define REICAST_VERSION "%%i" >$(ProjectDir)\..\core\version.h +for /f "delims=" %%i in ('git rev-parse --short HEAD') do echo #define GIT_HASH "%%i" >>$(ProjectDir)\..\core\version.h +for /f "delims=" %%i in ('date /T') do echo #define BUILD_DATE "%%i" >>$(ProjectDir)\..\core\version.h + + Create version.h + @@ -704,7 +792,7 @@ Level3 Full WIN32;CHD5_FLAC;PACKAGE_VERSION="1.3.2";FLAC__HAS_OGG=0;FLAC__NO_DLL;HAVE_LROUND;HAVE_STDINT_H;HAVE_STDLIB_H;CHD5_LZMA;_7ZIP_ST;NDEBUG;_CONSOLE;X86;RELEASE;%(PreprocessorDefinitions) - $(ProjectDir)..\core\;$(ProjectDir)..\core\khronos;$(ProjectDir)..\core\rend\gles;$(ProjectDir)..\core\deps\flac\src\libflac\include;$(ProjectDir)..\core\deps\flac\include + $(ProjectDir)..\core\;$(ProjectDir)..\core\khronos;$(ProjectDir)..\core\rend\gles;$(ProjectDir)..\core\deps;$(ProjectDir)..\core\deps\flac\src\libflac\include;$(ProjectDir)..\core\deps\flac\include /MP %(AdditionalOptions) AnySuitable true @@ -730,6 +818,13 @@ $(SolutionDir)..\pvrframe Dsound.lib;winmm.lib;wsock32.lib;comctl32.lib;%(AdditionalDependencies) + + for /f "delims=" %%i in ('git describe') do echo #define REICAST_VERSION "%%i" >$(ProjectDir)\..\core\version.h +for /f "delims=" %%i in ('git rev-parse --short HEAD') do echo #define GIT_HASH "%%i" >>$(ProjectDir)\..\core\version.h +for /f "delims=" %%i in ('date /T') do echo #define BUILD_DATE "%%i" >>$(ProjectDir)\..\core\version.h + + Create version.h + @@ -738,7 +833,7 @@ Level3 Full WIN32;CHD5_FLAC;PACKAGE_VERSION="1.3.2";FLAC__HAS_OGG=0;FLAC__NO_DLL;HAVE_LROUND;HAVE_STDINT_H;HAVE_STDLIB_H;CHD5_LZMA;_7ZIP_ST;NDEBUG;_CONSOLE;X86;RELEASE;TARGET_NAOMI;%(PreprocessorDefinitions) - $(ProjectDir)..\core\;$(ProjectDir)..\core\khronos;$(ProjectDir)..\core\rend\gles;$(ProjectDir)..\core\deps\flac\src\libflac\include;$(ProjectDir)..\core\deps\flac\include + $(ProjectDir)..\core\;$(ProjectDir)..\core\khronos;$(ProjectDir)..\core\rend\gles;$(ProjectDir)..\core\deps;$(ProjectDir)..\core\deps\flac\src\libflac\include;$(ProjectDir)..\core\deps\flac\include /MP %(AdditionalOptions) AnySuitable true @@ -764,6 +859,13 @@ $(SolutionDir)..\pvrframe Dsound.lib;winmm.lib;wsock32.lib;comctl32.lib;%(AdditionalDependencies) + + for /f "delims=" %%i in ('git describe') do echo #define REICAST_VERSION "%%i" >$(ProjectDir)\..\core\version.h +for /f "delims=" %%i in ('git rev-parse --short HEAD') do echo #define GIT_HASH "%%i" >>$(ProjectDir)\..\core\version.h +for /f "delims=" %%i in ('date /T') do echo #define BUILD_DATE "%%i" >>$(ProjectDir)\..\core\version.h + + Create version.h + @@ -772,7 +874,7 @@ Level3 Disabled WIN32;CHD5_FLAC;PACKAGE_VERSION="1.3.2";FLAC__HAS_OGG=0;FLAC__NO_DLL;HAVE_LROUND;HAVE_STDINT_H;HAVE_STDLIB_H;CHD5_LZMA;_7ZIP_ST;_DEBUG;_CONSOLE;X86;%(PreprocessorDefinitions) - $(ProjectDir)..\core\;$(ProjectDir)..\core\khronos;$(ProjectDir)..\core\rend\gles;$(ProjectDir)..\core\deps\flac\src\libflac\include;$(ProjectDir)..\core\deps\flac\include + $(ProjectDir)..\core\;$(ProjectDir)..\core\khronos;$(ProjectDir)..\core\rend\gles;$(ProjectDir)..\core\deps;$(ProjectDir)..\core\deps\flac\src\libflac\include;$(ProjectDir)..\core\deps\flac\include true false Default @@ -785,6 +887,13 @@ $(SolutionDir)..\pvrframe Dsound.lib;winmm.lib;wsock32.lib;comctl32.lib;%(AdditionalDependencies) + + for /f "delims=" %%i in ('git describe') do echo #define REICAST_VERSION "%%i" >$(ProjectDir)\..\core\version.h +for /f "delims=" %%i in ('git rev-parse --short HEAD') do echo #define GIT_HASH "%%i" >>$(ProjectDir)\..\core\version.h +for /f "delims=" %%i in ('date /T') do echo #define BUILD_DATE "%%i" >>$(ProjectDir)\..\core\version.h + + Create version.h + @@ -793,7 +902,7 @@ Level3 Disabled WIN32;CHD5_FLAC;PACKAGE_VERSION="1.3.2";FLAC__HAS_OGG=0;FLAC__NO_DLL;HAVE_LROUND;HAVE_STDINT_H;HAVE_STDLIB_H;CHD5_LZMA;_7ZIP_ST;_DEBUG;_CONSOLE;X86;TARGET_NAOMI;%(PreprocessorDefinitions) - $(ProjectDir)..\core\;$(ProjectDir)..\core\khronos;$(ProjectDir)..\core\rend\gles;$(ProjectDir)..\core\deps\flac\src\libflac\include;$(ProjectDir)..\core\deps\flac\include + $(ProjectDir)..\core\;$(ProjectDir)..\core\khronos;$(ProjectDir)..\core\rend\gles;$(ProjectDir)..\core\deps;$(ProjectDir)..\core\deps\flac\src\libflac\include;$(ProjectDir)..\core\deps\flac\include true false Default @@ -806,6 +915,13 @@ $(SolutionDir)..\pvrframe Dsound.lib;winmm.lib;wsock32.lib;comctl32.lib;%(AdditionalDependencies) + + for /f "delims=" %%i in ('git describe') do echo #define REICAST_VERSION "%%i" >$(ProjectDir)\..\core\version.h +for /f "delims=" %%i in ('git rev-parse --short HEAD') do echo #define GIT_HASH "%%i" >>$(ProjectDir)\..\core\version.h +for /f "delims=" %%i in ('date /T') do echo #define BUILD_DATE "%%i" >>$(ProjectDir)\..\core\version.h + + Create version.h + @@ -814,7 +930,7 @@ Level3 Disabled WIN32;CHD5_FLAC;PACKAGE_VERSION="1.3.2";FLAC__HAS_OGG=0;FLAC__NO_DLL;HAVE_LROUND;HAVE_STDINT_H;HAVE_STDLIB_H;CHD5_LZMA;_7ZIP_ST;_DEBUG;_CONSOLE;X86;%(PreprocessorDefinitions) - $(ProjectDir)..\core\;$(ProjectDir)..\core\khronos;$(ProjectDir)..\core\rend\gles;$(ProjectDir)..\core\deps\flac\src\libflac\include;$(ProjectDir)..\core\deps\flac\include + $(ProjectDir)..\core\;$(ProjectDir)..\core\khronos;$(ProjectDir)..\core\rend\gles;$(ProjectDir)..\core\deps;$(ProjectDir)..\core\deps\flac\src\libflac\include;$(ProjectDir)..\core\deps\flac\include true false Default @@ -830,6 +946,13 @@ $(SolutionDir)..\pvrframe Dsound.lib;winmm.lib;wsock32.lib;comctl32.lib;%(AdditionalDependencies) + + for /f "delims=" %%i in ('git describe') do echo #define REICAST_VERSION "%%i" >$(ProjectDir)\..\core\version.h +for /f "delims=" %%i in ('git rev-parse --short HEAD') do echo #define GIT_HASH "%%i" >>$(ProjectDir)\..\core\version.h +for /f "delims=" %%i in ('date /T') do echo #define BUILD_DATE "%%i" >>$(ProjectDir)\..\core\version.h + + Create version.h + @@ -838,7 +961,7 @@ Level3 Disabled WIN32;CHD5_FLAC;PACKAGE_VERSION="1.3.2";FLAC__HAS_OGG=0;FLAC__NO_DLL;HAVE_LROUND;HAVE_STDINT_H;HAVE_STDLIB_H;CHD5_LZMA;_7ZIP_ST;_DEBUG;_CONSOLE;X86;TARGET_NAOMI;%(PreprocessorDefinitions) - $(ProjectDir)..\core\;$(ProjectDir)..\core\khronos;$(ProjectDir)..\core\rend\gles;$(ProjectDir)..\core\deps\flac\src\libflac\include;$(ProjectDir)..\core\deps\flac\include + $(ProjectDir)..\core\;$(ProjectDir)..\core\khronos;$(ProjectDir)..\core\rend\gles;$(ProjectDir)..\core\deps;$(ProjectDir)..\core\deps\flac\src\libflac\include;$(ProjectDir)..\core\deps\flac\include true false Default @@ -854,6 +977,13 @@ $(SolutionDir)..\pvrframe Dsound.lib;winmm.lib;wsock32.lib;comctl32.lib;%(AdditionalDependencies) + + for /f "delims=" %%i in ('git describe') do echo #define REICAST_VERSION "%%i" >$(ProjectDir)\..\core\version.h +for /f "delims=" %%i in ('git rev-parse --short HEAD') do echo #define GIT_HASH "%%i" >>$(ProjectDir)\..\core\version.h +for /f "delims=" %%i in ('date /T') do echo #define BUILD_DATE "%%i" >>$(ProjectDir)\..\core\version.h + + Create version.h + @@ -869,4 +999,4 @@ - \ No newline at end of file + diff --git a/shell/reicast.vcxproj.filters b/shell/reicast.vcxproj.filters index 6c854badf..59289b0b3 100644 --- a/shell/reicast.vcxproj.filters +++ b/shell/reicast.vcxproj.filters @@ -1,1229 +1,1403 @@ - - - - - hw\aica - - - hw\aica - - - hw\aica - - - hw\aica - - - hw\aica - - - hw\arm7 - - - hw\arm7 - - - hw\arm7 - - - hw\arm7 - - - hw\gdrom - - - hw\gdrom - - - hw\maple - - - hw\maple - - - hw\maple - - - hw\maple - - - hw\mem - - - hw\sh4 - - - hw\pvr - - - hw\pvr - - - deps\zlib - - - deps\zlib - - - deps\zlib - - - deps\zlib - - - deps\zlib - - - deps\zlib - - - deps\zlib - - - deps\zlib - - - deps\zlib - - - deps\zlib - - - deps\zlib - - - deps\crypto - - - deps\crypto - - - imgread - - - imgread - - - imgread - - - imgread - - - imgread - - - imgread - - - - - cfg - - - cfg - - - emitter - - - windows - - - profiler - - - hw\holly - - - hw\holly - - - hw\holly - - - hw\sh4 - - - oslib - - - hw\sh4\modules - - - hw\sh4\modules - - - hw\sh4\modules - - - hw\sh4\modules - - - hw\sh4\modules - - - hw\sh4\modules - - - hw\sh4\modules - - - hw\sh4\modules - - - hw\sh4\dyna - - - hw\sh4\dyna - - - hw\sh4\dyna - - - hw\sh4\dyna - - - hw\sh4\interpr - - - hw\sh4\interpr - - - hw\sh4\interpr - - - hw\sh4 - - - hw\sh4\modules - - - hw\sh4\modules - - - hw\sh4 - - - hw\sh4 - - - hw\sh4 - - - hw\sh4 - - - deps\libelf - - - deps\libelf - - - deps\libelf - - - linux - - - linux - - - deps\chdpsr - - - deps\libpng - - - deps\libpng - - - deps\libpng - - - deps\libpng - - - deps\libpng - - - deps\libpng - - - deps\libpng - - - deps\libpng - - - deps\libpng - - - deps\libpng - - - deps\libpng - - - deps\libpng - - - deps\libpng - - - deps\libpng - - - deps\libpng - - - rend\gles - - - rend\gles - - - rend\gles - - - rend - - - rend\d3d11 - - - deps\libwebsocket - - - deps\libwebsocket - - - deps\libwebsocket - - - deps\libwebsocket - - - deps\libwebsocket - - - deps\libwebsocket - - - deps\libwebsocket - - - deps\libwebsocket - - - deps\libwebsocket - - - deps\libwebsocket - - - deps\libwebsocket - - - deps\libwebsocket - - - deps\libwebsocket - - - deps\libwebsocket - - - deps\libwebsocket - - - deps\libwebsocket - - - deps\libwebsocket - - - deps\libwebsocket - - - deps\libwebsocket - - - webui - - - deps\coreio - - - reios - - - reios - - - reios - - - reios - - - linux - - - oslib - - - rec-ARM - - - rec-x86 - - - rec-x86 - - - rec-x86 - - - rec-x64 - - - rec-cpp - - - rend\soft - - - hw\naomi - - - hw\naomi - - - cfg - - - - deps\xxhash - - - rend\gl4 - - - rend\gl4 - - - rend\gl4 - - - rend\gl4 - - - hw\aica - - - hw\modem - - - hw\modem - - - deps\xbrz - - - hw\pvr - - - hw\pvr - - - hw\pvr - - - hw\pvr - - - hw\pvr - - - hw\pvr - - - hw\pvr - - - deps\lzma - - - deps\lzma - - - deps\lzma - - - deps\lzma - - - deps\lzma - - - deps\lzma - - - deps\lzma - - - deps\lzma - - - deps\lzma - - - deps\lzma - - - deps\lzma - - - deps\lzma - - - deps\lzma - - - deps\flac\src\libFLAC - - - deps\flac\src\libFLAC - - - deps\flac\src\libFLAC - - - deps\flac\src\libFLAC - - - deps\flac\src\libFLAC - - - deps\flac\src\libFLAC - - - deps\flac\src\libFLAC - - - deps\flac\src\libFLAC - - - deps\flac\src\libFLAC - - - deps\flac\src\libFLAC - - - deps\flac\src\libFLAC - - - deps\flac\src\libFLAC - - - deps\flac\src\libFLAC - - - deps\flac\src\libFLAC - - - deps\flac\src\libFLAC - - - deps\flac\src\libFLAC - - - deps\flac\src\libFLAC - - - deps\flac\src\libFLAC - - - deps\flac\src\libFLAC - - - deps\flac\src\libFLAC - - - deps\flac\src\libFLAC - - - deps\chdr - - - deps\chdr - - - deps\chdr - - - deps\chdr - - - deps\chdr - - - - - {2099cae6-67fb-489f-b082-7555e8330705} - - - {70620682-2709-4701-b0a7-7d8f8e1571de} - - - {9659b21d-ccee-4d2b-973d-09e447be743e} - - - {a07a09a2-a585-4144-a0d0-c54d4bb442ec} - - - {9da5f3a4-2e41-4f94-a499-e2524c4dd0c2} - - - {c3e9aa73-a90e-4f37-b357-b0378fb1feff} - - - {65dd7d80-739d-4b5c-a01c-3262cb8ec97a} - - - {da5bfaf9-fca7-4397-9034-e201c1f38e49} - - - {ee2a1c0f-d38c-4d2b-bb07-ba6841fc5832} - - - {09e0d071-e3c1-4549-b2a8-52f24f4691a8} - - - {d0252230-b46c-424f-8aa8-037774915f81} - - - {5cdde132-a201-4bbc-9dd4-2ba3b3637a19} - - - {bd80604a-c634-44b3-a729-811bbefd3f71} - - - {8783a652-88e4-49bf-be90-bc36abe6753b} - - - {2e4fe5a7-a86c-45cf-b456-39b107a91bc7} - - - {369d7f53-be71-4055-a303-675f1132b118} - - - {e14356dc-6635-49f9-94d5-dc14ff1dec70} - - - {f96b3c39-1255-4ee8-999e-5c6e8fef21e5} - - - {b81a858a-7327-4eb4-bc6b-6ae24e2c08fd} - - - {755fe7c9-b6b5-42e5-b0e6-d1d02d5a6e03} - - - {2bbf43fd-2127-412f-bd76-6260b04522f8} - - - {be756ece-25e8-4a69-b90e-2601fdbb42fe} - - - {66246039-9de4-4bc0-88a9-94582e2713e0} - - - {3ef102e4-a05f-4774-b2d7-7e1529bfd9b1} - - - {82948f1f-819b-4a2d-9e07-72dfbf3e96ca} - - - {fe073008-ffba-43c1-9192-daec4b48148e} - - - {fa363b78-585a-476a-9afc-628b0f6650cf} - - - {3f5c03ee-36db-4818-b0d2-4eec9c084f75} - - - {cd2c89fd-7a5b-43c8-a940-6ea0d29e9b5d} - - - {cc05f61b-c484-40e6-9859-6ca0cd64735c} - - - {3d3de3ff-9e79-4920-a95a-61d190e73004} - - - {81193efc-656a-4154-9adf-146856d4c7d3} - - - {23cfa286-fe88-439d-89de-a6a5a23cacc9} - - - {f614dd66-5d30-4548-a209-f857f95fb505} - - - {df854851-d3b5-4549-8248-acdfa954be44} - - - {5a7b63eb-8c03-46ac-b6e0-dfd3ade02f11} - - - {f73263e9-dbe8-4a6f-8b73-335af8307551} - - - {63d1fcf2-64b4-4973-995f-cd471f51117c} - - - {6c4b2d69-54c0-4660-9969-a98fd0339a15} - - - {1752487d-0739-47bf-8c6b-1d38e6f389f7} - - - {83d7e5cc-cbd2-40e3-b2c0-79cc53b1dd9a} - - - {e9e574e5-cce8-467b-8457-acf3999240c1} - - - {c1ffb17b-f29e-466a-a6a6-e93aa1bb2ca7} - - - {a67aece4-e47f-48a2-8944-6afbe679a5fb} - - - {4c0328b2-a9b3-4b0a-ab54-558ba960b03a} - - - {8bb0b4a0-7661-4533-9245-fc43582f6182} - - - {98226656-1e2d-4d69-bcd4-c1c1b6d4cb0a} - - - {f06382df-ae0e-459c-92a2-dc0eaab25b05} - - - {39e82b10-530a-4978-b8cc-8a11b67981d7} - - - {51e03f58-a90d-4ebc-95f7-6af6cdc39165} - - - {4c52c0a3-9e35-4285-a062-290d3667e1d1} - - - - - hw\aica - - - hw\aica - - - hw\aica - - - hw\aica - - - hw\aica - - - hw\arm7 - - - hw\arm7 - - - hw\arm7 - - - hw\arm7 - - - hw\gdrom - - - hw\gdrom - - - hw\maple - - - hw\maple - - - hw\maple - - - hw\maple - - - hw\mem - - - hw\sh4 - - - hw\sh4 - - - hw\sh4 - - - hw\pvr - - - hw\pvr - - - hw\pvr - - - hw\pvr - - - deps\zlib - - - deps\zlib - - - deps\zlib - - - deps\zlib - - - deps\zlib - - - deps\zlib - - - deps\zlib - - - deps\zlib - - - deps\zlib - - - deps\zlib - - - deps\zlib - - - deps\crypto - - - deps\crypto - - - deps\chdr - - - deps\chdr - - - imgread - - - imgread - - - imgread - - - imgread - - - imgread - - - imgread - - - oslib - - - - - cfg - - - - emitter - - - emitter - - - emitter - - - emitter - - - emitter - - - emitter - - - emitter - - - emitter - - - emitter - - - emitter - - - profiler - - - hw\holly - - - hw\holly - - - hw\flashrom - - - hw\holly - - - hw\sh4 - - - oslib - - - hw\sh4\modules - - - hw\sh4\modules - - - hw\sh4\modules - - - hw\sh4\modules - - - hw\sh4\dyna - - - hw\sh4\dyna - - - hw\sh4\dyna - - - hw\sh4\dyna - - - hw\sh4\dyna - - - hw\sh4\dyna - - - hw\sh4\dyna - - - hw\sh4\dyna - - - hw\sh4\interpr - - - hw\sh4\modules - - - hw\sh4 - - - hw\sh4 - - - hw\sh4 - - - hw\sh4 - - - hw\sh4 - - - hw\sh4 - - - deps\libelf - - - deps\libelf - - - deps\libelf - - - deps\libelf - - - linux - - - deps\chdpsr - - - deps\libpng - - - deps\libpng - - - deps\libpng - - - deps\libpng - - - rend\gles - - - rend - - - rend - - - deps\libwebsocket - - - deps\libwebsocket - - - deps\libwebsocket - - - deps\libwebsocket - - - deps\libwebsocket - - - webui - - - deps\coreio - - - reios - - - reios - - - reios - - - reios - - - linux - - - oslib - - - rec-x86 - - - hw\naomi - - - hw\naomi - - - hw\naomi - - - cfg - - - hw\sh4\modules - - - rend\gl4 - - - rend\gl4 - - - hw\modem - - - hw\modem - - - hw\modem - - - hw\pvr - - - hw\pvr - - - hw\pvr - - - hw\pvr - - - hw\pvr - - - hw\pvr - - - hw\pvr - - - hw\pvr - - - deps\lzma - - - deps\lzma - - - deps\lzma - - - deps\lzma - - - deps\lzma - - - deps\lzma - - - deps\lzma - - - deps\lzma - - - deps\lzma - - - deps\lzma - - - deps\lzma - - - deps\lzma - - - deps\lzma - - - deps\lzma - - - deps\flac\include\FLAC - - - deps\flac\include\FLAC - - - deps\flac\include\FLAC - - - deps\flac\include\FLAC - - - deps\flac\include\FLAC - - - deps\flac\include\FLAC - - - deps\flac\include\FLAC - - - deps\flac\include\FLAC - - - deps\flac\include\FLAC - - - deps\flac\include\share - - - deps\flac\include\share - - - deps\flac\include\share - - - deps\flac\include\share - - - deps\flac\include\share - - - deps\flac\include\share - - - deps\flac\include\share - - - deps\chdr - - - deps\chdr - - - deps\chdr - - - deps\chdr - - - - - deps\zlib - - - rec-ARM - - - rec-x86 - - - \ No newline at end of file + + + + + hw\aica + + + hw\aica + + + hw\aica + + + hw\aica + + + hw\aica + + + hw\arm7 + + + hw\arm7 + + + hw\arm7 + + + hw\arm7 + + + hw\gdrom + + + hw\gdrom + + + hw\maple + + + hw\maple + + + hw\maple + + + hw\maple + + + hw\mem + + + hw\sh4 + + + hw\pvr + + + hw\pvr + + + deps\zlib + + + deps\zlib + + + deps\zlib + + + deps\zlib + + + deps\zlib + + + deps\zlib + + + deps\zlib + + + deps\zlib + + + deps\zlib + + + deps\zlib + + + deps\zlib + + + deps\crypto + + + deps\crypto + + + imgread + + + imgread + + + imgread + + + imgread + + + imgread + + + imgread + + + + + cfg + + + cfg + + + emitter + + + windows + + + windows + + + profiler + + + hw\holly + + + hw\holly + + + hw\holly + + + hw\sh4 + + + oslib + + + hw\sh4\modules + + + hw\sh4\modules + + + hw\sh4\modules + + + hw\sh4\modules + + + hw\sh4\modules + + + hw\sh4\modules + + + hw\sh4\modules + + + hw\sh4\modules + + + hw\sh4\dyna + + + hw\sh4\dyna + + + hw\sh4\dyna + + + hw\sh4\dyna + + + hw\sh4\interpr + + + hw\sh4\interpr + + + hw\sh4\interpr + + + hw\sh4 + + + hw\sh4\modules + + + hw\sh4\modules + + + hw\sh4 + + + hw\sh4 + + + hw\sh4 + + + hw\sh4 + + + deps\libelf + + + deps\libelf + + + deps\libelf + + + linux + + + linux + + + deps\chdpsr + + + deps\libpng + + + deps\libpng + + + deps\libpng + + + deps\libpng + + + deps\libpng + + + deps\libpng + + + deps\libpng + + + deps\libpng + + + deps\libpng + + + deps\libpng + + + deps\libpng + + + deps\libpng + + + deps\libpng + + + deps\libpng + + + deps\libpng + + + rend\gles + + + rend\gles + + + rend\gles + + + rend + + + rend\d3d11 + + + deps\libwebsocket + + + deps\libwebsocket + + + deps\libwebsocket + + + deps\libwebsocket + + + deps\libwebsocket + + + deps\libwebsocket + + + deps\libwebsocket + + + deps\libwebsocket + + + deps\libwebsocket + + + deps\libwebsocket + + + deps\libwebsocket + + + deps\libwebsocket + + + deps\libwebsocket + + + deps\libwebsocket + + + deps\libwebsocket + + + deps\libwebsocket + + + deps\libwebsocket + + + deps\libwebsocket + + + deps\libwebsocket + + + webui + + + deps\coreio + + + reios + + + reios + + + reios + + + reios + + + linux + + + oslib + + + rec-ARM + + + rec-x86 + + + rec-x86 + + + rec-x86 + + + rec-x64 + + + rec-cpp + + + rend\soft + + + hw\naomi + + + hw\naomi + + + cfg + + + + deps\xxhash + + + rend\gl4 + + + rend\gl4 + + + rend\gl4 + + + rend\gl4 + + + hw\aica + + + hw\modem + + + hw\modem + + + deps\xbrz + + + hw\pvr + + + hw\pvr + + + hw\pvr + + + hw\pvr + + + hw\pvr + + + hw\pvr + + + hw\pvr + + + deps\lzma + + + deps\lzma + + + deps\lzma + + + deps\lzma + + + deps\lzma + + + deps\lzma + + + deps\lzma + + + deps\lzma + + + deps\lzma + + + deps\lzma + + + deps\lzma + + + deps\lzma + + + deps\lzma + + + deps\flac\src\libFLAC + + + deps\flac\src\libFLAC + + + deps\flac\src\libFLAC + + + deps\flac\src\libFLAC + + + deps\flac\src\libFLAC + + + deps\flac\src\libFLAC + + + deps\flac\src\libFLAC + + + deps\flac\src\libFLAC + + + deps\flac\src\libFLAC + + + deps\flac\src\libFLAC + + + deps\flac\src\libFLAC + + + deps\flac\src\libFLAC + + + deps\flac\src\libFLAC + + + deps\flac\src\libFLAC + + + deps\flac\src\libFLAC + + + deps\flac\src\libFLAC + + + deps\flac\src\libFLAC + + + deps\flac\src\libFLAC + + + deps\flac\src\libFLAC + + + deps\flac\src\libFLAC + + + deps\flac\src\libFLAC + + + deps\chdr + + + deps\chdr + + + deps\chdr + + + deps\chdr + + + deps\chdr + + + rend + + + rend + + + deps\imgui + + + deps\imgui + + + deps\imgui + + + deps\imgui + + + deps\dirent + + + input + + + input + + + input + + + rend\gles + + + rend\gles + + + rend\gles + + + hw\naomi + + + hw\naomi + + + hw\naomi + + + hw\naomi + + + hw\naomi + + + archive + + + archive + + + archive + + + imgread + + + + + {2099cae6-67fb-489f-b082-7555e8330705} + + + {70620682-2709-4701-b0a7-7d8f8e1571de} + + + {9659b21d-ccee-4d2b-973d-09e447be743e} + + + {a07a09a2-a585-4144-a0d0-c54d4bb442ec} + + + {9da5f3a4-2e41-4f94-a499-e2524c4dd0c2} + + + {c3e9aa73-a90e-4f37-b357-b0378fb1feff} + + + {65dd7d80-739d-4b5c-a01c-3262cb8ec97a} + + + {da5bfaf9-fca7-4397-9034-e201c1f38e49} + + + {ee2a1c0f-d38c-4d2b-bb07-ba6841fc5832} + + + {09e0d071-e3c1-4549-b2a8-52f24f4691a8} + + + {d0252230-b46c-424f-8aa8-037774915f81} + + + {5cdde132-a201-4bbc-9dd4-2ba3b3637a19} + + + {bd80604a-c634-44b3-a729-811bbefd3f71} + + + {8783a652-88e4-49bf-be90-bc36abe6753b} + + + {2e4fe5a7-a86c-45cf-b456-39b107a91bc7} + + + {369d7f53-be71-4055-a303-675f1132b118} + + + {e14356dc-6635-49f9-94d5-dc14ff1dec70} + + + {f96b3c39-1255-4ee8-999e-5c6e8fef21e5} + + + {b81a858a-7327-4eb4-bc6b-6ae24e2c08fd} + + + {755fe7c9-b6b5-42e5-b0e6-d1d02d5a6e03} + + + {2bbf43fd-2127-412f-bd76-6260b04522f8} + + + {be756ece-25e8-4a69-b90e-2601fdbb42fe} + + + {66246039-9de4-4bc0-88a9-94582e2713e0} + + + {3ef102e4-a05f-4774-b2d7-7e1529bfd9b1} + + + {82948f1f-819b-4a2d-9e07-72dfbf3e96ca} + + + {fe073008-ffba-43c1-9192-daec4b48148e} + + + {fa363b78-585a-476a-9afc-628b0f6650cf} + + + {3f5c03ee-36db-4818-b0d2-4eec9c084f75} + + + {cd2c89fd-7a5b-43c8-a940-6ea0d29e9b5d} + + + {cc05f61b-c484-40e6-9859-6ca0cd64735c} + + + {3d3de3ff-9e79-4920-a95a-61d190e73004} + + + {81193efc-656a-4154-9adf-146856d4c7d3} + + + {23cfa286-fe88-439d-89de-a6a5a23cacc9} + + + {f614dd66-5d30-4548-a209-f857f95fb505} + + + {df854851-d3b5-4549-8248-acdfa954be44} + + + {5a7b63eb-8c03-46ac-b6e0-dfd3ade02f11} + + + {f73263e9-dbe8-4a6f-8b73-335af8307551} + + + {63d1fcf2-64b4-4973-995f-cd471f51117c} + + + {6c4b2d69-54c0-4660-9969-a98fd0339a15} + + + {1752487d-0739-47bf-8c6b-1d38e6f389f7} + + + {83d7e5cc-cbd2-40e3-b2c0-79cc53b1dd9a} + + + {e9e574e5-cce8-467b-8457-acf3999240c1} + + + {c1ffb17b-f29e-466a-a6a6-e93aa1bb2ca7} + + + {a67aece4-e47f-48a2-8944-6afbe679a5fb} + + + {4c0328b2-a9b3-4b0a-ab54-558ba960b03a} + + + {8bb0b4a0-7661-4533-9245-fc43582f6182} + + + {98226656-1e2d-4d69-bcd4-c1c1b6d4cb0a} + + + {f06382df-ae0e-459c-92a2-dc0eaab25b05} + + + {39e82b10-530a-4978-b8cc-8a11b67981d7} + + + {51e03f58-a90d-4ebc-95f7-6af6cdc39165} + + + {4c52c0a3-9e35-4285-a062-290d3667e1d1} + + + {0746d3c7-838f-43ed-817b-8215a24b87d4} + + + {29043329-ba53-45d5-8513-a5ee92c73853} + + + {ff6259dd-375b-46bb-a2ad-bf2825eb81ee} + + + {8fea504f-a313-4ab2-b25b-74e80fe449c8} + + + + + hw\aica + + + hw\aica + + + hw\aica + + + hw\aica + + + hw\aica + + + hw\arm7 + + + hw\arm7 + + + hw\arm7 + + + hw\arm7 + + + hw\gdrom + + + hw\gdrom + + + hw\maple + + + hw\maple + + + hw\maple + + + hw\maple + + + hw\mem + + + hw\sh4 + + + hw\sh4 + + + hw\sh4 + + + hw\pvr + + + hw\pvr + + + hw\pvr + + + hw\pvr + + + deps\zlib + + + deps\zlib + + + deps\zlib + + + deps\zlib + + + deps\zlib + + + deps\zlib + + + deps\zlib + + + deps\zlib + + + deps\zlib + + + deps\zlib + + + deps\zlib + + + deps\crypto + + + deps\crypto + + + deps\chdr + + + deps\chdr + + + imgread + + + imgread + + + imgread + + + imgread + + + imgread + + + imgread + + + oslib + + + + + cfg + + + + emitter + + + emitter + + + emitter + + + emitter + + + emitter + + + emitter + + + emitter + + + emitter + + + emitter + + + emitter + + + profiler + + + hw\holly + + + hw\holly + + + hw\flashrom + + + hw\holly + + + hw\sh4 + + + oslib + + + hw\sh4\modules + + + hw\sh4\modules + + + hw\sh4\modules + + + hw\sh4\modules + + + hw\sh4\dyna + + + hw\sh4\dyna + + + hw\sh4\dyna + + + hw\sh4\dyna + + + hw\sh4\dyna + + + hw\sh4\dyna + + + hw\sh4\dyna + + + hw\sh4\dyna + + + hw\sh4\interpr + + + hw\sh4\modules + + + hw\sh4 + + + hw\sh4 + + + hw\sh4 + + + hw\sh4 + + + hw\sh4 + + + hw\sh4 + + + deps\libelf + + + deps\libelf + + + deps\libelf + + + deps\libelf + + + linux + + + deps\chdpsr + + + deps\libpng + + + deps\libpng + + + deps\libpng + + + deps\libpng + + + rend\gles + + + rend + + + rend + + + deps\libwebsocket + + + deps\libwebsocket + + + deps\libwebsocket + + + deps\libwebsocket + + + deps\libwebsocket + + + webui + + + deps\coreio + + + reios + + + reios + + + reios + + + reios + + + linux + + + oslib + + + rec-x86 + + + hw\naomi + + + hw\naomi + + + hw\naomi + + + cfg + + + hw\sh4\modules + + + rend\gl4 + + + rend\gl4 + + + hw\modem + + + hw\modem + + + hw\modem + + + hw\pvr + + + hw\pvr + + + hw\pvr + + + hw\pvr + + + hw\pvr + + + hw\pvr + + + hw\pvr + + + hw\pvr + + + deps\lzma + + + deps\lzma + + + deps\lzma + + + deps\lzma + + + deps\lzma + + + deps\lzma + + + deps\lzma + + + deps\lzma + + + deps\lzma + + + deps\lzma + + + deps\lzma + + + deps\lzma + + + deps\lzma + + + deps\lzma + + + deps\flac\include\FLAC + + + deps\flac\include\FLAC + + + deps\flac\include\FLAC + + + deps\flac\include\FLAC + + + deps\flac\include\FLAC + + + deps\flac\include\FLAC + + + deps\flac\include\FLAC + + + deps\flac\include\FLAC + + + deps\flac\include\FLAC + + + deps\flac\include\share + + + deps\flac\include\share + + + deps\flac\include\share + + + deps\flac\include\share + + + deps\flac\include\share + + + deps\flac\include\share + + + deps\flac\include\share + + + deps\chdr + + + deps\chdr + + + deps\chdr + + + deps\chdr + + + rend + + + rend + + + deps\imgui + + + deps\imgui + + + deps\imgui + + + deps\imgui + + + deps\imgui + + + deps\imgui + + + deps\imgui + + + deps\dirent + + + input + + + input + + + input + + + input + + + rend\gles + + + rend\gles + + + rend\gles + + + hw\naomi + + + hw\naomi + + + hw\naomi + + + hw\naomi + + + hw\naomi + + + hw\naomi + + + hw\naomi + + + hw\naomi + + + archive + + + archive + + + archive + + + windows + + + windows + + + + + deps\zlib + + + rec-ARM + + + rec-x86 + + + + + + diff --git a/shell/windows/reicast.ico b/shell/windows/reicast.ico new file mode 100644 index 000000000..99528ed33 Binary files /dev/null and b/shell/windows/reicast.ico differ diff --git a/shell/windows/reicast.rc b/shell/windows/reicast.rc new file mode 100644 index 000000000..13bedb6cf --- /dev/null +++ b/shell/windows/reicast.rc @@ -0,0 +1,39 @@ +// Microsoft Visual C++ generated resource script. +// +#include "resource.h" +#include "../../core/version.h" + +///////////////////////////////////////////////////////////////////////////// +// +// Icon +// + +// Icon with lowest ID value placed first to ensure application icon +// remains consistent on all systems. +IDI_ICON1 ICON "reicast.ico" + +///////////////////////////////////////////////////////////////////////////// + +1 VERSIONINFO +FILEVERSION 1,0,0,0 +PRODUCTVERSION 1,0,0,0 +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904E4" + BEGIN + VALUE "CompanyName", "Reicast Team" + VALUE "FileDescription", "Reicast" + VALUE "FileVersion", REICAST_VERSION + VALUE "InternalName", "reicast" + VALUE "LegalCopyright", "Copyright (c) Reicast Team. All rights reserved." + VALUE "OriginalFilename", "reicast.exe" + VALUE "ProductName", "Reicast" + VALUE "ProductVersion", REICAST_VERSION + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x409, 1252 + END +END \ No newline at end of file diff --git a/shell/windows/resource.h b/shell/windows/resource.h new file mode 100644 index 000000000..ad4c5aebf --- /dev/null +++ b/shell/windows/resource.h @@ -0,0 +1,16 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Visual C++ generated include file. +// Used by reicast.rc +// +#define IDI_ICON1 105 + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 106 +#define _APS_NEXT_COMMAND_VALUE 40001 +#define _APS_NEXT_CONTROL_VALUE 1000 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif