mirror of
https://github.com/flyinghead/flycast.git
synced 2026-11-08 08:06:48 -10:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a51f310e96 | ||
|
|
89ccdf2814 | ||
|
|
52af352fcd | ||
|
|
7a33ae35e0 | ||
|
|
ce58ba3472 | ||
|
|
43ae2ea5f5 | ||
|
|
3006cd4f60 | ||
|
|
c27180fb32 | ||
|
|
6f233462c1 | ||
|
|
fcef404f50 | ||
|
|
5ac0e58886 | ||
|
|
a14fc35e47 | ||
|
|
e4d9be86b4 | ||
|
|
3c483c61e7 | ||
|
|
147bd8341d | ||
|
|
5c0dd67094 | ||
|
|
49688d6523 | ||
|
|
850f23be82 | ||
|
|
9aa3d8b987 | ||
|
|
eaf44bc18c | ||
|
|
31be731de0 | ||
|
|
82d2aa8a47 | ||
|
|
75af07331a | ||
|
|
eceb5ba982 | ||
|
|
042f2e0224 | ||
|
|
aeea301ee3 | ||
|
|
fd301186c7 | ||
|
|
b40328e621 | ||
|
|
7cd832e914 | ||
|
|
44feea4c01 | ||
|
|
c5ce475359 | ||
|
|
894a0540b9 | ||
|
|
967f4570ed | ||
|
|
14360beaf7 | ||
|
|
46e3258629 | ||
|
|
b3ad0a62c1 | ||
|
|
a5edd9c7ff | ||
|
|
7f49accc22 | ||
|
|
b8c2a695b8 | ||
|
|
c73bbc85bd | ||
|
|
d6545b253b | ||
|
|
293761bdf5 | ||
|
|
d862453956 | ||
|
|
58974c9305 | ||
|
|
cddb6609f1 | ||
|
|
4a9c51a6c8 | ||
|
|
329ae11d2f | ||
|
|
c3bc5cfc3b | ||
|
|
24f9003cd3 | ||
|
|
4c2bf59c46 | ||
|
|
642a89733b | ||
|
|
2b3d9427e1 | ||
|
|
6368241b77 | ||
|
|
57ae9022dd | ||
|
|
7ed68952ba | ||
|
|
4696733eb4 | ||
|
|
5f5d31730c | ||
|
|
e07977eea9 | ||
|
|
71fb024061 | ||
|
|
54cfc6e09b | ||
|
|
150cfa29e7 | ||
|
|
b90cdf9588 | ||
|
|
6316479930 | ||
|
|
f9603dc11a | ||
|
|
5359e9a09d | ||
|
|
28d2c6db73 | ||
|
|
abc8b18b78 | ||
|
|
c889bfa6d4 | ||
|
|
f2a0098fed | ||
|
|
b549c56b23 | ||
|
|
f107d380b9 |
No files matched your search
+8
-3
@@ -1,9 +1,14 @@
|
||||
freebsd_instance:
|
||||
image_family: freebsd-12-2
|
||||
image_family: freebsd-13-0
|
||||
|
||||
env:
|
||||
CCACHE_DIR: /tmp/ccache
|
||||
CIRRUS_CLONE_SUBMODULES: true
|
||||
|
||||
task:
|
||||
install_script: pkg install -y alsa-lib cmake evdev-proto flac git libao libevdev libudev-devd libzip mesa-libs miniupnpc ninja pkgconf png pulseaudio sdl2
|
||||
install_script: pkg install -y alsa-lib ccache cmake evdev-proto git libao libevdev libudev-devd libzip mesa-libs miniupnpc ninja pkgconf png pulseaudio sdl2
|
||||
ccache_cache:
|
||||
folder: /tmp/ccache
|
||||
script:
|
||||
- git submodule update --init --recursive
|
||||
- cmake -B build -DCMAKE_BUILD_TYPE=Release -G Ninja
|
||||
- cmake --build build --config Release
|
||||
@@ -8,7 +8,13 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Set up build environment
|
||||
run: echo "y" | sudo ${ANDROID_HOME}/tools/bin/sdkmanager --install "ndk;20.0.5594570"
|
||||
run: sudo apt-get update && sudo apt-get -y install ninja-build
|
||||
|
||||
# Workaround for https://github.com/actions/virtual-environments/issues/3078
|
||||
- name: Downgrade CMake
|
||||
uses: jwlawson/[email protected]
|
||||
with:
|
||||
cmake-version: '3.19.x'
|
||||
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
@@ -17,26 +23,28 @@ jobs:
|
||||
|
||||
- uses: actions/cache@v2
|
||||
with:
|
||||
path: ~/.gradle/caches
|
||||
key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*') }}
|
||||
path: |
|
||||
~/.gradle/caches
|
||||
~/.gradle/wrapper
|
||||
key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-gradle-
|
||||
|
||||
- name: Gradle
|
||||
working-directory: shell/android-studio
|
||||
run: ./gradlew assembleDebug --parallel
|
||||
run: ./gradlew assembleRelease --parallel
|
||||
|
||||
- uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: flycast-debug.apk
|
||||
path: shell/android-studio/flycast/build/outputs/apk/debug/flycast-debug.apk
|
||||
name: flycast-release.apk
|
||||
path: shell/android-studio/flycast/build/outputs/apk/release/flycast-release.apk
|
||||
|
||||
- name: Set up git vars
|
||||
run: |
|
||||
echo GIT_BUILD=`git describe --all --always | sed 's/remotes\/origin/heads/'`-$GITHUB_SHA >> $GITHUB_ENV
|
||||
|
||||
- name: Clean up
|
||||
run: rm -f shell/android-studio/flycast/build/outputs/apk/debug/*.json
|
||||
run: rm -f shell/android-studio/flycast/build/outputs/apk/release/*.json
|
||||
|
||||
- uses: jakejarvis/s3-sync-action@master
|
||||
with:
|
||||
@@ -46,6 +54,6 @@ jobs:
|
||||
AWS_ACCESS_KEY_ID: AKIAJOZQS4H2PHQWYFCA
|
||||
AWS_SECRET_ACCESS_KEY: ${{ secrets.S3_SECRET_KEY }}
|
||||
AWS_REGION: 'us-east-2'
|
||||
SOURCE_DIR: 'shell/android-studio/flycast/build/outputs/apk/debug/'
|
||||
SOURCE_DIR: 'shell/android-studio/flycast/build/outputs/apk/release/'
|
||||
DEST_DIR: android/${{ env.GIT_BUILD }}
|
||||
if: ${{ github.event_name == 'push' }}
|
||||
if: ${{ github.repository == 'flyinghead/flycast' && github.event_name == 'push' }}
|
||||
@@ -19,7 +19,7 @@ jobs:
|
||||
steps:
|
||||
- name: Set up build environment (macos-latest)
|
||||
run: |
|
||||
brew install ccache flac libao libomp pulseaudio zlib
|
||||
brew install ccache libao libomp pulseaudio zlib
|
||||
echo "/usr/local/opt/ccache/libexec" >> $GITHUB_PATH
|
||||
echo "CCACHE_DIR=/tmp/ccache" >> $GITHUB_ENV
|
||||
if: matrix.config.os == 'macos-latest'
|
||||
@@ -27,10 +27,14 @@ jobs:
|
||||
- name: Set up build environment (ubuntu-latest)
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get -y install ccache libao-dev libasound2-dev libevdev-dev libflac-dev libgl1-mesa-dev libpulse-dev libsdl2-dev libudev-dev libzip-dev libminiupnpc-dev
|
||||
sudo apt-get -y install ccache libao-dev libasound2-dev libevdev-dev libgl1-mesa-dev libpulse-dev libsdl2-dev libudev-dev libzip-dev libminiupnpc-dev
|
||||
echo "CCACHE_DIR=/tmp/ccache" >> $GITHUB_ENV
|
||||
if: matrix.config.os == 'ubuntu-latest'
|
||||
|
||||
- name: Set up build environment (windows-latest)
|
||||
run: echo "DXSDK_DIR=${Env:HOMEDRIVE}${Env:HOMEPATH}\ccache\" | Out-File -FilePath $Env:GITHUB_ENV -Encoding utf-8 -Append
|
||||
if: matrix.config.os == 'windows-latest' && matrix.config.name != 'x86_64-w64-mingw32'
|
||||
|
||||
- uses: actions/cache@v2
|
||||
with:
|
||||
path: /tmp/ccache
|
||||
@@ -38,6 +42,25 @@ jobs:
|
||||
restore-keys: ccache-${{ matrix.config.os }}-
|
||||
if: matrix.config.os != 'windows-latest'
|
||||
|
||||
- uses: actions/cache@v2
|
||||
id: cache
|
||||
with:
|
||||
path: $HOME/ccache
|
||||
key: ccache-${{ matrix.config.os }}-${{ github.sha }}
|
||||
restore-keys: ccache-${{ matrix.config.os }}-
|
||||
if: matrix.config.os == 'windows-latest'
|
||||
|
||||
- name: Download DX2010
|
||||
if: steps.cache.outputs.cache-hit != 'true' && matrix.config.os == 'windows-latest' && matrix.config.name != 'x86_64-w64-mingw32'
|
||||
run: |
|
||||
curl -L https://download.microsoft.com/download/a/e/7/ae743f1f-632b-4809-87a9-aa1bb3458e31/DXSDK_Jun10.exe -o _DX2010_.exe
|
||||
7z x _DX2010_.exe DXSDK/Include -o_DX2010_
|
||||
7z x _DX2010_.exe DXSDK/Lib/x86 -o_DX2010_
|
||||
7z x _DX2010_.exe DXSDK/Lib/x64 -o_DX2010_
|
||||
mv _DX2010_/DXSDK $HOME/ccache
|
||||
rm -fR _DX*_ _DX*_.exe
|
||||
shell: bash
|
||||
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
fetch-depth: 0
|
||||
@@ -91,13 +114,14 @@ jobs:
|
||||
shell: bash
|
||||
|
||||
- name: Configure AWS Credentials
|
||||
id: aws-credentials
|
||||
uses: aws-actions/configure-aws-credentials@v1
|
||||
with:
|
||||
aws-access-key-id: AKIAJOZQS4H2PHQWYFCA
|
||||
aws-secret-access-key: ${{ secrets.S3_SECRET_KEY }}
|
||||
aws-region: us-east-2
|
||||
if: github.event_name == 'push'
|
||||
if: github.repository == 'flyinghead/flycast' && github.event_name == 'push' && matrix.config.destDir != ''
|
||||
|
||||
- name: Upload to S3
|
||||
run: aws s3 sync build/artifact s3://flycast-builds/${{ matrix.config.destDir }}/${{ env.GIT_BUILD }} --acl public-read --follow-symlinks
|
||||
if: github.event_name == 'push' && matrix.config.destDir != ''
|
||||
if: ${{ steps.aws-credentials.outputs.aws-account-id != '' }}
|
||||
-15
@@ -10,7 +10,6 @@ Workdir/emu.cfg
|
||||
Workdir/lib*ant.properties
|
||||
|
||||
# iOS General
|
||||
.DS_Store
|
||||
*/build/*
|
||||
**/build/*
|
||||
*.pbxuser
|
||||
@@ -33,14 +32,7 @@ build/*
|
||||
*Karen_angelXwind*
|
||||
local.properties
|
||||
ant.properties
|
||||
*build_obj
|
||||
*.d
|
||||
Workdir/data
|
||||
Workdir/reicast*
|
||||
Workdir/vmu*
|
||||
Workdir/webui*
|
||||
Workdir/emu.cfg
|
||||
Workdir/lib*ant.properties
|
||||
reicast-ios.xccheckout
|
||||
|
||||
# Linux General
|
||||
@@ -54,13 +46,6 @@ shell/linux/dispframe.elf
|
||||
generated
|
||||
.vs
|
||||
|
||||
# Android Studio
|
||||
*.iml
|
||||
shell/android-studio/.gradle/
|
||||
shell/android-studio/flycast/.cxx/
|
||||
shell/android-studio/flycast/build/
|
||||
shell/android-studio/flycast/local.properties
|
||||
|
||||
# JetBrains IDES
|
||||
.idea/
|
||||
cmake-build-*/
|
||||
+49
-20
@@ -1,4 +1,4 @@
|
||||
cmake_minimum_required(VERSION 3.10.2 FATAL_ERROR)
|
||||
cmake_minimum_required(VERSION 3.10.2)
|
||||
|
||||
find_program(CCACHE_FOUND ccache)
|
||||
if(CCACHE_FOUND)
|
||||
@@ -21,6 +21,7 @@ set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/shell/cmake")
|
||||
|
||||
if(APPLE)
|
||||
set(CMAKE_OSX_DEPLOYMENT_TARGET "10.9" CACHE STRING "Minimum macOS deployment version")
|
||||
set(CMAKE_OSX_ARCHITECTURES "x86_64;arm64" CACHE STRING "")
|
||||
endif()
|
||||
|
||||
project(flycast)
|
||||
@@ -53,8 +54,6 @@ configure_file("${CMAKE_CURRENT_SOURCE_DIR}/core/version.h.in" "${CMAKE_CURRENT_
|
||||
|
||||
if(ANDROID)
|
||||
add_library(${PROJECT_NAME} SHARED core/nullDC.cpp)
|
||||
set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_RELEASE} -O3")
|
||||
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_RELEASE} -O3")
|
||||
target_compile_options(${PROJECT_NAME} PRIVATE -fno-stack-protector)
|
||||
set(CMAKE_ANDROID_STL_TYPE "c++_static")
|
||||
elseif(MSVC)
|
||||
@@ -91,11 +90,12 @@ if(OpenMP_CXX_FOUND AND NOT APPLE AND USE_OPENMP)
|
||||
if(MINGW)
|
||||
target_link_libraries(${PROJECT_NAME} PRIVATE "-static -lgomp -lpthread")
|
||||
target_compile_options(${PROJECT_NAME} PRIVATE -fopenmp)
|
||||
elseif(ANDROID)
|
||||
# Reference: https://android.googlesource.com/platform/ndk/+/refs/heads/master/tests/device/openmp/CMakeLists.txt
|
||||
set_target_properties(${PROJECT_NAME} PROPERTIES COMPILE_OPTIONS -fopenmp)
|
||||
target_link_libraries(${PROJECT_NAME} PRIVATE -fopenmp -static-openmp)
|
||||
else()
|
||||
target_link_libraries(${PROJECT_NAME} PRIVATE OpenMP::OpenMP_CXX)
|
||||
if(ANDROID_NDK_MAJOR VERSION_GREATER_EQUAL 21)
|
||||
target_link_libraries(${PROJECT_NAME} PRIVATE -static-openmp)
|
||||
endif()
|
||||
endif()
|
||||
else()
|
||||
target_compile_definitions(${PROJECT_NAME} PRIVATE TARGET_NO_OPENMP)
|
||||
@@ -111,6 +111,7 @@ add_subdirectory(core/deps/glm)
|
||||
target_link_libraries(${PROJECT_NAME} PRIVATE glm::glm)
|
||||
|
||||
if(NOT APPLE)
|
||||
option(BUILD_EXTERNAL "Build external dependencies in /External" OFF)
|
||||
add_subdirectory(core/deps/glslang)
|
||||
target_link_libraries(${PROJECT_NAME} PRIVATE SPIRV)
|
||||
endif()
|
||||
@@ -123,9 +124,7 @@ if(ALSA_FOUND AND NOT ANDROID)
|
||||
endif()
|
||||
|
||||
if(WIN32)
|
||||
# Patch and build SDL
|
||||
execute_process(COMMAND git apply -p1 ${CMAKE_CURRENT_SOURCE_DIR}/core/deps/patches/SDL.patch
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/core/deps/SDL)
|
||||
# Build SDL
|
||||
file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/core/deps/SDL")
|
||||
if(CMAKE_GENERATOR MATCHES "Visual Studio")
|
||||
set(SDL_CMAKE_ARCH_ARG -A ${CMAKE_GENERATOR_PLATFORM})
|
||||
@@ -217,7 +216,7 @@ if(PKG_CONFIG_FOUND AND NOT ANDROID AND NOT APPLE)
|
||||
if(USE_HOST_LIBZIP)
|
||||
pkg_check_modules(LIBZIP IMPORTED_TARGET libzip)
|
||||
if(LIBZIP_FOUND)
|
||||
target_link_libraries(${PROJECT_NAME} PRIVATE ${LIBZIP_LIBRARIES})
|
||||
target_link_libraries(${PROJECT_NAME} PRIVATE PkgConfig::LIBZIP)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
@@ -555,7 +554,6 @@ target_sources(${PROJECT_NAME} PRIVATE
|
||||
core/hw/sh4/sh4_mem.h
|
||||
core/hw/sh4/sh4_mmr.cpp
|
||||
core/hw/sh4/sh4_mmr.h
|
||||
core/hw/sh4/sh4_opcode.h
|
||||
core/hw/sh4/sh4_opcode_list.cpp
|
||||
core/hw/sh4/sh4_opcode_list.h
|
||||
core/hw/sh4/sh4_rom.cpp
|
||||
@@ -577,7 +575,6 @@ target_sources(${PROJECT_NAME} PRIVATE
|
||||
core/input/gamepad.h
|
||||
core/input/gamepad_device.cpp
|
||||
core/input/gamepad_device.h
|
||||
core/input/keyboard_device.cpp
|
||||
core/input/keyboard_device.h
|
||||
core/input/mapping.cpp
|
||||
core/input/mapping.h)
|
||||
@@ -791,7 +788,33 @@ if(USE_VULKAN AND NOT APPLE)
|
||||
core/rend/vulkan/vulkan_renderer.cpp)
|
||||
endif()
|
||||
|
||||
if(CMAKE_SYSTEM_PROCESSOR MATCHES "^(arm.*|ARM.*)")
|
||||
if(WIN32)
|
||||
target_sources(${PROJECT_NAME} PRIVATE
|
||||
core/rend/dx9/comptr.h
|
||||
core/rend/dx9/d3d_overlay.h
|
||||
core/rend/dx9/d3d_overlay.cpp
|
||||
core/rend/dx9/d3d_renderer.h
|
||||
core/rend/dx9/d3d_renderer.cpp
|
||||
core/rend/dx9/d3d_shaders.h
|
||||
core/rend/dx9/d3d_shaders.cpp
|
||||
core/rend/dx9/d3d_texture.h
|
||||
core/rend/dx9/d3d_texture.cpp
|
||||
core/rend/dx9/dxcontext.h
|
||||
core/rend/dx9/dxcontext.cpp
|
||||
core/rend/dx9/imgui_impl_dx9.h
|
||||
core/rend/dx9/imgui_impl_dx9.cpp)
|
||||
if(NOT MINGW)
|
||||
target_include_directories(${PROJECT_NAME} PRIVATE "$ENV{DXSDK_DIR}/Include")
|
||||
if (CMAKE_SIZEOF_VOID_P EQUAL 8)
|
||||
target_link_directories(${PROJECT_NAME} PRIVATE "$ENV{DXSDK_DIR}/Lib/x64")
|
||||
else()
|
||||
target_link_directories(${PROJECT_NAME} PRIVATE "$ENV{DXSDK_DIR}/Lib/x86")
|
||||
endif()
|
||||
endif()
|
||||
target_link_libraries(${PROJECT_NAME} PRIVATE d3d9 d3dx9)
|
||||
endif()
|
||||
|
||||
if(CMAKE_SYSTEM_PROCESSOR MATCHES "^(arm.*|ARM.*)" AND NOT APPLE)
|
||||
target_include_directories(${PROJECT_NAME} PRIVATE core/deps/vixl)
|
||||
target_sources(${PROJECT_NAME} PRIVATE
|
||||
core/rec-ARM/rec_arm.cpp
|
||||
@@ -825,7 +848,9 @@ if(CMAKE_SYSTEM_PROCESSOR MATCHES "^(arm.*|ARM.*)")
|
||||
core/deps/vixl/pool-manager-impl.h
|
||||
core/deps/vixl/utils-vixl.cc
|
||||
core/deps/vixl/utils-vixl.h)
|
||||
elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^(aarch64.*|AARCH64.*)")
|
||||
set(KNOWN_ARCHITECTURE_DETECTED ON)
|
||||
endif()
|
||||
if(CMAKE_SYSTEM_PROCESSOR MATCHES "^(aarch64.*|AARCH64.*|arm64.*)" OR CMAKE_OSX_ARCHITECTURES MATCHES "arm64")
|
||||
target_include_directories(${PROJECT_NAME} PRIVATE core/deps/vixl)
|
||||
target_sources(${PROJECT_NAME} PRIVATE
|
||||
core/deps/vixl/aarch64/abi-aarch64.h
|
||||
@@ -870,7 +895,9 @@ elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^(aarch64.*|AARCH64.*)")
|
||||
core/deps/vixl/utils-vixl.cc
|
||||
core/deps/vixl/utils-vixl.h)
|
||||
target_sources(${PROJECT_NAME} PRIVATE core/rec-ARM64/rec_arm64.cpp core/rec-ARM64/arm64_regalloc.h)
|
||||
elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "i686.*|i386.*|x86.*|amd64.*|x86_64.*|AMD64.*")
|
||||
set(KNOWN_ARCHITECTURE_DETECTED ON)
|
||||
endif()
|
||||
if(CMAKE_SYSTEM_PROCESSOR MATCHES "i686.*|i386.*|x86.*|amd64.*|x86_64.*|AMD64.*" OR CMAKE_OSX_ARCHITECTURES MATCHES "x86_64")
|
||||
add_subdirectory(core/deps/xbyak)
|
||||
target_link_libraries(${PROJECT_NAME} PRIVATE xbyak::xbyak)
|
||||
if(CMAKE_SIZEOF_VOID_P EQUAL 4)
|
||||
@@ -886,16 +913,16 @@ elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "i686.*|i386.*|x86.*|amd64.*|x86_64.*|AMD6
|
||||
core/rec-x64/rec_x64.cpp
|
||||
core/rec-x64/x64_regalloc.h)
|
||||
endif()
|
||||
else()
|
||||
set(KNOWN_ARCHITECTURE_DETECTED ON)
|
||||
endif()
|
||||
if(NOT KNOWN_ARCHITECTURE_DETECTED)
|
||||
message(FATAL_ERROR "Unknown target processor: ${CMAKE_SYSTEM_PROCESSOR}")
|
||||
endif()
|
||||
|
||||
if(ANDROID)
|
||||
target_compile_definitions(${PROJECT_NAME} PRIVATE GLES GLES3)
|
||||
|
||||
target_sources(${PROJECT_NAME} PRIVATE
|
||||
shell/android-studio/flycast/src/main/jni/src/Android.cpp
|
||||
shell/android-studio/flycast/src/main/jni/src/utils.cpp)
|
||||
target_sources(${PROJECT_NAME} PRIVATE shell/android-studio/flycast/src/main/jni/src/Android.cpp)
|
||||
|
||||
target_link_libraries(${PROJECT_NAME} PRIVATE android EGL GLESv2 log)
|
||||
elseif(APPLE)
|
||||
@@ -944,13 +971,15 @@ elseif(UNIX)
|
||||
elseif(WIN32)
|
||||
if(NOT BUILD_TESTING)
|
||||
target_sources(${PROJECT_NAME} PRIVATE
|
||||
core/windows/rawinput.cpp
|
||||
core/windows/rawinput.h
|
||||
core/windows/win_keyboard.h
|
||||
core/windows/winmain.cpp
|
||||
core/windows/xinput_gamepad.h)
|
||||
endif()
|
||||
target_sources(${PROJECT_NAME} PRIVATE
|
||||
core/windows/win_vmem.cpp
|
||||
shell/windows/reicast.rc)
|
||||
shell/windows/flycast.rc)
|
||||
|
||||
target_link_libraries(${PROJECT_NAME} PRIVATE dsound opengl32 winmm ws2_32 wsock32 xinput9_1_0)
|
||||
endif()
|
||||
|
||||
@@ -33,4 +33,4 @@ Get fresh builds for your system [on the builds page](https://flyinghead.github.
|
||||
|
||||
## Disclaimer
|
||||
|
||||
All code contritbuted to this fork is *not* bound by the Individual Contributor License Agreement of the upstream repository (https://github.com/reicast/reicast-emulator) and shall *not* be considered as a contribution to the upstream repository.
|
||||
All code contributed to this fork is *not* bound by the Individual Contributor License Agreement of the upstream repository (https://github.com/reicast/reicast-emulator) and shall *not* be considered as a contribution to the upstream repository.
|
||||
@@ -7,7 +7,6 @@ Here lies the core of our codebase. Everything that's OS inspecific rests here.
|
||||
### Some rudimentary categories are:
|
||||
- hw -- DC Hardware Components Implementation
|
||||
- nullDC.cpp -- Main entry points
|
||||
- emitter -- x86 code emitter
|
||||
- khronos -- OpenGL and Vulkan headers
|
||||
- oslib -- Audio drivers
|
||||
- cfg -- Configuration backend structure
|
||||
|
||||
@@ -39,6 +39,12 @@ bool RZipFile::Open(const std::string& path, bool write)
|
||||
Close();
|
||||
return false;
|
||||
}
|
||||
// savestates created on 32-bit platforms used to have a 32-bit size
|
||||
if (size >> 32 != 0)
|
||||
{
|
||||
size &= 0xffffffff;
|
||||
std::fseek(file, -4, SEEK_CUR);
|
||||
}
|
||||
chunk = new u8[maxChunkSize];
|
||||
chunkIndex = 0;
|
||||
chunkSize = 0;
|
||||
@@ -109,9 +115,10 @@ size_t RZipFile::Write(const void *data, size_t length)
|
||||
verify(std::ftell(file) == 0);
|
||||
|
||||
maxChunkSize = 1024 * 1024;
|
||||
size = length;
|
||||
if (std::fwrite(RZipHeader, sizeof(RZipHeader), 1, file) != 1
|
||||
|| std::fwrite(&maxChunkSize, sizeof(maxChunkSize), 1, file) != 1
|
||||
|| std::fwrite(&length, sizeof(length), 1, file) != 1)
|
||||
|| std::fwrite(&size, sizeof(size), 1, file) != 1)
|
||||
return 0;
|
||||
const u8 *p = (const u8 *)data;
|
||||
// compression output buffer must be 0.1% larger + 12 bytes
|
||||
|
||||
+1
-1
@@ -35,7 +35,7 @@ public:
|
||||
|
||||
private:
|
||||
FILE *file = nullptr;
|
||||
size_t size = 0;
|
||||
u64 size = 0;
|
||||
u32 maxChunkSize = 0;
|
||||
u8 *chunk = nullptr;
|
||||
u32 chunkSize = 0;
|
||||
|
||||
@@ -207,23 +207,8 @@
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if HOST_CPU == CPU_X64 || HOST_CPU == CPU_ARM64
|
||||
#define HOST_64BIT_CPU
|
||||
#endif
|
||||
|
||||
#define USE_MINIUPNPC
|
||||
|
||||
// Compiler Related
|
||||
|
||||
#ifndef _MSC_VER
|
||||
#define ATTR_USED __attribute__((used))
|
||||
#define ATTR_UNUSED __attribute__((used))
|
||||
#else
|
||||
#define ATTR_USED
|
||||
#define ATTR_UNUSED
|
||||
#endif
|
||||
|
||||
|
||||
// Some restrictions on FEAT_NO_RWX_PAGES
|
||||
#if defined(FEAT_NO_RWX_PAGES) && FEAT_SHREC == DYNAREC_JIT
|
||||
#if HOST_CPU != CPU_X64 && HOST_CPU != CPU_ARM64
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#include "ini.h"
|
||||
#include "types.h"
|
||||
#include <sstream>
|
||||
|
||||
char* trim_ws(char* str);
|
||||
|
||||
+3
-1
@@ -1,6 +1,8 @@
|
||||
#pragma once
|
||||
#include "types.h"
|
||||
|
||||
#include <cstdio>
|
||||
#include <map>
|
||||
#include <string>
|
||||
|
||||
namespace emucfg {
|
||||
|
||||
|
||||
+8
-2
@@ -34,7 +34,9 @@ Option<int> Broadcast("Dreamcast.Broadcast", 0); // NTSC
|
||||
Option<int> Language("Dreamcast.Language", 1); // English
|
||||
Option<bool> FullMMU("Dreamcast.FullMMU");
|
||||
Option<bool> ForceWindowsCE("Dreamcast.ForceWindowsCE");
|
||||
Option<bool> AutoSavestate("Dreamcast.AutoSavestate");
|
||||
Option<bool> AutoLoadState("Dreamcast.AutoLoadState");
|
||||
Option<bool> AutoSaveState("Dreamcast.AutoSaveState");
|
||||
Option<int> SavestateSlot("Dreamcast.SavestateSlot");
|
||||
|
||||
// Sound
|
||||
|
||||
@@ -54,6 +56,7 @@ Option<bool> AutoLatency("aica.AutoLatency",
|
||||
);
|
||||
|
||||
OptionString AudioBackend("backend", "auto", "audio");
|
||||
AudioVolumeOption AudioVolume;
|
||||
|
||||
// Rendering
|
||||
|
||||
@@ -75,7 +78,7 @@ Option<bool> Fog("rend.Fog", true);
|
||||
Option<bool> FloatVMUs("rend.FloatVMUs");
|
||||
Option<bool> Rotate90("rend.Rotate90");
|
||||
Option<bool> PerStripSorting("rend.PerStripSorting");
|
||||
Option<bool> DelayFrameSwapping("rend.DelayFrameSwapping");
|
||||
Option<bool> DelayFrameSwapping("rend.DelayFrameSwapping", true);
|
||||
Option<bool> WidescreenGameHacks("rend.WidescreenGameHacks");
|
||||
std::array<Option<int>, 4> CrosshairColor {
|
||||
Option<int>("rend.CrossHairColor1"),
|
||||
@@ -141,5 +144,8 @@ std::array<std::array<Option<MapleDeviceType>, 2>, 4> MapleExpansionDevices {
|
||||
Option<MapleDeviceType>("device4.1", MDT_None, "input"),
|
||||
Option<MapleDeviceType>("device4.2", MDT_None, "input"),
|
||||
};
|
||||
#ifdef _WIN32
|
||||
Option<bool> UseRawInput("RawInput", false, "input");
|
||||
#endif
|
||||
|
||||
} // namespace config
|
||||
+46
-9
@@ -20,6 +20,7 @@
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <array>
|
||||
#include <cmath>
|
||||
#include "cfg.h"
|
||||
#include "hw/maple/maple_cfg.h"
|
||||
|
||||
@@ -277,12 +278,6 @@ protected:
|
||||
|
||||
using OptionString = Option<std::string>;
|
||||
|
||||
template<typename T, T value = T()>
|
||||
class ConstOption {
|
||||
public:
|
||||
operator T() const { return value; }
|
||||
};
|
||||
|
||||
// Dynarec
|
||||
|
||||
extern Option<bool> DynarecEnabled;
|
||||
@@ -297,11 +292,13 @@ extern Option<int> Broadcast; // 0 -> NTSC, 1 -> PAL, 2 -> PAL/M, 3 -> PAL/N, 4
|
||||
extern Option<int> Language; // 0 -> JP, 1 -> EN, 2 -> DE, 3 -> FR, 4 -> SP, 5 -> IT, 6 -> default
|
||||
extern Option<bool> FullMMU;
|
||||
extern Option<bool> ForceWindowsCE;
|
||||
extern Option<bool> AutoSavestate;
|
||||
extern Option<bool> AutoLoadState;
|
||||
extern Option<bool> AutoSaveState;
|
||||
extern Option<int> SavestateSlot;
|
||||
|
||||
// Sound
|
||||
|
||||
constexpr ConstOption<bool, true> LimitFPS;
|
||||
constexpr bool LimitFPS = true;
|
||||
extern Option<bool> DSPEnabled;
|
||||
extern Option<bool> DisableSound;
|
||||
extern Option<int> AudioBufferSize; //In samples ,*4 for bytes
|
||||
@@ -309,16 +306,51 @@ extern Option<bool> AutoLatency;
|
||||
|
||||
extern OptionString AudioBackend;
|
||||
|
||||
class AudioVolumeOption : public Option<int> {
|
||||
public:
|
||||
AudioVolumeOption() : Option<int>("aica.Volume", 100) {};
|
||||
float logarithmic_volume_scale = 1.0;
|
||||
|
||||
void load() override {
|
||||
Option<int>::load();
|
||||
calcDbPower();
|
||||
}
|
||||
|
||||
float dbPower()
|
||||
{
|
||||
return logarithmic_volume_scale;
|
||||
}
|
||||
void calcDbPower()
|
||||
{
|
||||
// dB scaling calculation: https://www.dr-lex.be/info-stuff/volumecontrols.html
|
||||
logarithmic_volume_scale = fmin(exp(4.605 * float(value) / 100.0) / 100.0, 1.0);
|
||||
if (value < 10)
|
||||
logarithmic_volume_scale *= value / 10.0;
|
||||
}
|
||||
};
|
||||
extern AudioVolumeOption AudioVolume;
|
||||
|
||||
// Rendering
|
||||
|
||||
class RendererOption : public Option<RenderType> {
|
||||
public:
|
||||
RendererOption()
|
||||
#ifdef _WIN32
|
||||
: Option<RenderType>("pvr.rend", RenderType::DirectX9) {}
|
||||
#else
|
||||
: Option<RenderType>("pvr.rend", RenderType::OpenGL) {}
|
||||
#endif
|
||||
|
||||
bool isOpenGL() const {
|
||||
return value == RenderType::OpenGL || value == RenderType::OpenGL_OIT;
|
||||
}
|
||||
bool isVulkan() const {
|
||||
return value == RenderType::Vulkan || value == RenderType::Vulkan_OIT;
|
||||
}
|
||||
bool isDirectX() const {
|
||||
return value == RenderType::DirectX9;
|
||||
}
|
||||
|
||||
void set(RenderType v)
|
||||
{
|
||||
newValue = v;
|
||||
@@ -355,7 +387,7 @@ extern Option<bool> ShowFPS;
|
||||
extern Option<bool> RenderToTextureBuffer;
|
||||
extern Option<bool> TranslucentPolygonDepthMask;
|
||||
extern Option<bool> ModifierVolumes;
|
||||
constexpr ConstOption<bool, true> Clipping;
|
||||
constexpr bool Clipping = true;
|
||||
extern Option<int> TextureUpscale;
|
||||
extern Option<int> MaxFilteredTextureSize;
|
||||
extern Option<float> ExtraDepthScale;
|
||||
@@ -409,6 +441,11 @@ extern Option<int> MouseSensitivity;
|
||||
extern Option<int> VirtualGamepadVibration;
|
||||
extern std::array<Option<MapleDeviceType>, 4> MapleMainDevices;
|
||||
extern std::array<std::array<Option<MapleDeviceType>, 2>, 4> MapleExpansionDevices;
|
||||
#ifdef _WIN32
|
||||
extern Option<bool> UseRawInput;
|
||||
#else
|
||||
constexpr bool UseRawInput = false;
|
||||
#endif
|
||||
|
||||
} // namespace config
|
||||
|
||||
+3
-3
@@ -319,13 +319,13 @@ void CheatManager::loadCheatFile(const std::string& filename)
|
||||
while (fgets(buffer, sizeof(buffer), cheatfile) != nullptr)
|
||||
{
|
||||
std::string l = buffer;
|
||||
auto equalPos = l.find("=");
|
||||
auto equalPos = l.find('=');
|
||||
if (equalPos == std::string::npos)
|
||||
continue;
|
||||
auto quotePos = l.find("\"", equalPos);
|
||||
auto quotePos = l.find('"', equalPos);
|
||||
if (quotePos == std::string::npos)
|
||||
continue;
|
||||
auto quote2Pos = l.find("\"", quotePos + 1);
|
||||
auto quote2Pos = l.find('"', quotePos + 1);
|
||||
if (quote2Pos == std::string::npos)
|
||||
continue;
|
||||
if (l.substr(0, 5) != "cheat" || l[5] < '0' || l[5] > '9')
|
||||
|
||||
+3
-2
@@ -68,10 +68,11 @@ ifdef FOR_LINUX
|
||||
endif
|
||||
|
||||
ifdef FOR_WINDOWS
|
||||
RZDCY_MODULES += rend/dx9/
|
||||
ifndef UNIT_TESTS
|
||||
RZDCY_FILES += $(RZDCY_SRC_DIR)/windows/winmain.cpp
|
||||
endif
|
||||
RZDCY_FILES += $(RZDCY_SRC_DIR)/windows/win_vmem.cpp
|
||||
RZDCY_FILES += $(RZDCY_SRC_DIR)/windows/win_vmem.cpp $(RZDCY_SRC_DIR)/windows/rawinput.cpp
|
||||
RZDCY_CFLAGS += -I$(RZDCY_SRC_DIR)/deps/dirent
|
||||
endif
|
||||
|
||||
@@ -254,7 +255,7 @@ RZDCY_FILES += $(LIBZIP_DIR)/zip_add.c \
|
||||
endif
|
||||
|
||||
$(VERSION_HEADER):
|
||||
echo "#define REICAST_VERSION \"`git describe --tags --always`\"" > $(VERSION_HEADER)
|
||||
echo "#define GIT_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)
|
||||
|
||||
@@ -1,239 +0,0 @@
|
||||
/*
|
||||
* This code implements the MD5 message-digest algorithm.
|
||||
* The algorithm is due to Ron Rivest. This code was
|
||||
* written by Colin Plumb in 1993, no copyright is claimed.
|
||||
* This code is in the public domain; do with it what you wish.
|
||||
*
|
||||
* Equivalent code is available from RSA Data Security, Inc.
|
||||
* This code has been tested against that, and is equivalent,
|
||||
* except that you don't need to include two pages of legalese
|
||||
* with every copy.
|
||||
*
|
||||
* To compute the message digest of a chunk of bytes, declare an
|
||||
* MD5Context structure, pass it to MD5Init, call MD5Update as
|
||||
* needed on buffers full of bytes, and then call MD5Final, which
|
||||
* will fill a supplied 16-byte array with the digest.
|
||||
*
|
||||
* Changed so as no longer to depend on Colin Plumb's `usual.h' header
|
||||
* definitions; now uses stuff from dpkg's config.h.
|
||||
* - Ian Jackson <[email protected]>.
|
||||
* Still in the public domain.
|
||||
*/
|
||||
|
||||
#include <string.h> /* for memcpy() */
|
||||
|
||||
#include "md5.h"
|
||||
|
||||
#ifndef LSB_FIRST
|
||||
void
|
||||
byteSwap(UWORD32 *buf, unsigned words)
|
||||
{
|
||||
md5byte *p = (md5byte *)buf;
|
||||
|
||||
do {
|
||||
*buf++ = (UWORD32)((unsigned)p[3] << 8 | p[2]) << 16 |
|
||||
((unsigned)p[1] << 8 | p[0]);
|
||||
p += 4;
|
||||
} while (--words);
|
||||
}
|
||||
#else
|
||||
#define byteSwap(buf,words)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Start MD5 accumulation. Set bit count to 0 and buffer to mysterious
|
||||
* initialization constants.
|
||||
*/
|
||||
void
|
||||
MD5Init(struct MD5Context *ctx)
|
||||
{
|
||||
ctx->buf[0] = 0x67452301;
|
||||
ctx->buf[1] = 0xefcdab89;
|
||||
ctx->buf[2] = 0x98badcfe;
|
||||
ctx->buf[3] = 0x10325476;
|
||||
|
||||
ctx->bytes[0] = 0;
|
||||
ctx->bytes[1] = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Update context to reflect the concatenation of another buffer full
|
||||
* of bytes.
|
||||
*/
|
||||
void
|
||||
MD5Update(struct MD5Context *ctx, md5byte const *buf, unsigned len)
|
||||
{
|
||||
UWORD32 t;
|
||||
|
||||
/* Update byte count */
|
||||
|
||||
t = ctx->bytes[0];
|
||||
if ((ctx->bytes[0] = t + len) < t)
|
||||
ctx->bytes[1]++; /* Carry from low to high */
|
||||
|
||||
t = 64 - (t & 0x3f); /* Space available in ctx->in (at least 1) */
|
||||
if (t > len) {
|
||||
memcpy((md5byte *)ctx->in + 64 - t, buf, len);
|
||||
return;
|
||||
}
|
||||
/* First chunk is an odd size */
|
||||
memcpy((md5byte *)ctx->in + 64 - t, buf, t);
|
||||
byteSwap(ctx->in, 16);
|
||||
MD5Transform(ctx->buf, ctx->in);
|
||||
buf += t;
|
||||
len -= t;
|
||||
|
||||
/* Process data in 64-byte chunks */
|
||||
while (len >= 64) {
|
||||
memcpy(ctx->in, buf, 64);
|
||||
byteSwap(ctx->in, 16);
|
||||
MD5Transform(ctx->buf, ctx->in);
|
||||
buf += 64;
|
||||
len -= 64;
|
||||
}
|
||||
|
||||
/* Handle any remaining bytes of data. */
|
||||
memcpy(ctx->in, buf, len);
|
||||
}
|
||||
|
||||
/*
|
||||
* Final wrapup - pad to 64-byte boundary with the bit pattern
|
||||
* 1 0* (64-bit count of bits processed, MSB-first)
|
||||
*/
|
||||
void
|
||||
MD5Final(md5byte digest[16], struct MD5Context *ctx)
|
||||
{
|
||||
int count = ctx->bytes[0] & 0x3f; /* Number of bytes in ctx->in */
|
||||
md5byte *p = (md5byte *)ctx->in + count;
|
||||
|
||||
/* Set the first char of padding to 0x80. There is always room. */
|
||||
*p++ = 0x80;
|
||||
|
||||
/* Bytes of padding needed to make 56 bytes (-8..55) */
|
||||
count = 56 - 1 - count;
|
||||
|
||||
if (count < 0) { /* Padding forces an extra block */
|
||||
memset(p, 0, count + 8);
|
||||
byteSwap(ctx->in, 16);
|
||||
MD5Transform(ctx->buf, ctx->in);
|
||||
p = (md5byte *)ctx->in;
|
||||
count = 56;
|
||||
}
|
||||
memset(p, 0, count);
|
||||
byteSwap(ctx->in, 14);
|
||||
|
||||
/* Append length in bits and transform */
|
||||
ctx->in[14] = ctx->bytes[0] << 3;
|
||||
ctx->in[15] = ctx->bytes[1] << 3 | ctx->bytes[0] >> 29;
|
||||
MD5Transform(ctx->buf, ctx->in);
|
||||
|
||||
byteSwap(ctx->buf, 4);
|
||||
memcpy(digest, ctx->buf, 16);
|
||||
memset(ctx, 0, sizeof(*ctx)); /* In case it's sensitive */
|
||||
}
|
||||
|
||||
#ifndef ASM_MD5
|
||||
|
||||
/* The four core functions - F1 is optimized somewhat */
|
||||
|
||||
/* #define F1(x, y, z) (x & y | ~x & z) */
|
||||
#define F1(x, y, z) (z ^ (x & (y ^ z)))
|
||||
#define F2(x, y, z) F1(z, x, y)
|
||||
#define F3(x, y, z) (x ^ y ^ z)
|
||||
#define F4(x, y, z) (y ^ (x | ~z))
|
||||
|
||||
/* This is the central step in the MD5 algorithm. */
|
||||
#define MD5STEP(f,w,x,y,z,in,s) \
|
||||
(w += f(x,y,z) + in, w = (w<<s | w>>(32-s)) + x)
|
||||
|
||||
/*
|
||||
* The core of the MD5 algorithm, this alters an existing MD5 hash to
|
||||
* reflect the addition of 16 longwords of new data. MD5Update blocks
|
||||
* the data and converts bytes into longwords for this routine.
|
||||
*/
|
||||
void
|
||||
MD5Transform(UWORD32 buf[4], UWORD32 const in[16])
|
||||
{
|
||||
register UWORD32 a, b, c, d;
|
||||
|
||||
a = buf[0];
|
||||
b = buf[1];
|
||||
c = buf[2];
|
||||
d = buf[3];
|
||||
|
||||
MD5STEP(F1, a, b, c, d, in[0] + 0xd76aa478, 7);
|
||||
MD5STEP(F1, d, a, b, c, in[1] + 0xe8c7b756, 12);
|
||||
MD5STEP(F1, c, d, a, b, in[2] + 0x242070db, 17);
|
||||
MD5STEP(F1, b, c, d, a, in[3] + 0xc1bdceee, 22);
|
||||
MD5STEP(F1, a, b, c, d, in[4] + 0xf57c0faf, 7);
|
||||
MD5STEP(F1, d, a, b, c, in[5] + 0x4787c62a, 12);
|
||||
MD5STEP(F1, c, d, a, b, in[6] + 0xa8304613, 17);
|
||||
MD5STEP(F1, b, c, d, a, in[7] + 0xfd469501, 22);
|
||||
MD5STEP(F1, a, b, c, d, in[8] + 0x698098d8, 7);
|
||||
MD5STEP(F1, d, a, b, c, in[9] + 0x8b44f7af, 12);
|
||||
MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17);
|
||||
MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22);
|
||||
MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122, 7);
|
||||
MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12);
|
||||
MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17);
|
||||
MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22);
|
||||
|
||||
MD5STEP(F2, a, b, c, d, in[1] + 0xf61e2562, 5);
|
||||
MD5STEP(F2, d, a, b, c, in[6] + 0xc040b340, 9);
|
||||
MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14);
|
||||
MD5STEP(F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20);
|
||||
MD5STEP(F2, a, b, c, d, in[5] + 0xd62f105d, 5);
|
||||
MD5STEP(F2, d, a, b, c, in[10] + 0x02441453, 9);
|
||||
MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14);
|
||||
MD5STEP(F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20);
|
||||
MD5STEP(F2, a, b, c, d, in[9] + 0x21e1cde6, 5);
|
||||
MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9);
|
||||
MD5STEP(F2, c, d, a, b, in[3] + 0xf4d50d87, 14);
|
||||
MD5STEP(F2, b, c, d, a, in[8] + 0x455a14ed, 20);
|
||||
MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5);
|
||||
MD5STEP(F2, d, a, b, c, in[2] + 0xfcefa3f8, 9);
|
||||
MD5STEP(F2, c, d, a, b, in[7] + 0x676f02d9, 14);
|
||||
MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20);
|
||||
|
||||
MD5STEP(F3, a, b, c, d, in[5] + 0xfffa3942, 4);
|
||||
MD5STEP(F3, d, a, b, c, in[8] + 0x8771f681, 11);
|
||||
MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16);
|
||||
MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23);
|
||||
MD5STEP(F3, a, b, c, d, in[1] + 0xa4beea44, 4);
|
||||
MD5STEP(F3, d, a, b, c, in[4] + 0x4bdecfa9, 11);
|
||||
MD5STEP(F3, c, d, a, b, in[7] + 0xf6bb4b60, 16);
|
||||
MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23);
|
||||
MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6, 4);
|
||||
MD5STEP(F3, d, a, b, c, in[0] + 0xeaa127fa, 11);
|
||||
MD5STEP(F3, c, d, a, b, in[3] + 0xd4ef3085, 16);
|
||||
MD5STEP(F3, b, c, d, a, in[6] + 0x04881d05, 23);
|
||||
MD5STEP(F3, a, b, c, d, in[9] + 0xd9d4d039, 4);
|
||||
MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11);
|
||||
MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16);
|
||||
MD5STEP(F3, b, c, d, a, in[2] + 0xc4ac5665, 23);
|
||||
|
||||
MD5STEP(F4, a, b, c, d, in[0] + 0xf4292244, 6);
|
||||
MD5STEP(F4, d, a, b, c, in[7] + 0x432aff97, 10);
|
||||
MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15);
|
||||
MD5STEP(F4, b, c, d, a, in[5] + 0xfc93a039, 21);
|
||||
MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3, 6);
|
||||
MD5STEP(F4, d, a, b, c, in[3] + 0x8f0ccc92, 10);
|
||||
MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15);
|
||||
MD5STEP(F4, b, c, d, a, in[1] + 0x85845dd1, 21);
|
||||
MD5STEP(F4, a, b, c, d, in[8] + 0x6fa87e4f, 6);
|
||||
MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10);
|
||||
MD5STEP(F4, c, d, a, b, in[6] + 0xa3014314, 15);
|
||||
MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21);
|
||||
MD5STEP(F4, a, b, c, d, in[4] + 0xf7537e82, 6);
|
||||
MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10);
|
||||
MD5STEP(F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15);
|
||||
MD5STEP(F4, b, c, d, a, in[9] + 0xeb86d391, 21);
|
||||
|
||||
buf[0] += a;
|
||||
buf[1] += b;
|
||||
buf[2] += c;
|
||||
buf[3] += d;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,42 +0,0 @@
|
||||
/*
|
||||
* This is the header file for the MD5 message-digest algorithm.
|
||||
* The algorithm is due to Ron Rivest. This code was
|
||||
* written by Colin Plumb in 1993, no copyright is claimed.
|
||||
* This code is in the public domain; do with it what you wish.
|
||||
*
|
||||
* Equivalent code is available from RSA Data Security, Inc.
|
||||
* This code has been tested against that, and is equivalent,
|
||||
* except that you don't need to include two pages of legalese
|
||||
* with every copy.
|
||||
*
|
||||
* To compute the message digest of a chunk of bytes, declare an
|
||||
* MD5Context structure, pass it to MD5Init, call MD5Update as
|
||||
* needed on buffers full of bytes, and then call MD5Final, which
|
||||
* will fill a supplied 16-byte array with the digest.
|
||||
*
|
||||
* Changed so as no longer to depend on Colin Plumb's `usual.h'
|
||||
* header definitions; now uses stuff from dpkg's config.h
|
||||
* - Ian Jackson <[email protected]>.
|
||||
* Still in the public domain.
|
||||
*/
|
||||
|
||||
#ifndef MD5_H
|
||||
#define MD5_H
|
||||
|
||||
typedef unsigned int UWORD32;
|
||||
|
||||
#define md5byte unsigned char
|
||||
|
||||
struct MD5Context {
|
||||
UWORD32 buf[4];
|
||||
UWORD32 bytes[2];
|
||||
UWORD32 in[16];
|
||||
};
|
||||
|
||||
void MD5Init(struct MD5Context *context);
|
||||
void MD5Update(struct MD5Context *context, md5byte const *buf, unsigned len);
|
||||
void MD5Final(unsigned char digest[16], struct MD5Context *context);
|
||||
void MD5Transform(UWORD32 buf[4], UWORD32 const in[16]);
|
||||
|
||||
#endif /* !MD5_H */
|
||||
|
||||
@@ -1,387 +0,0 @@
|
||||
/* sha1.h
|
||||
*
|
||||
* The sha1 hash function.
|
||||
*/
|
||||
|
||||
/* nettle, low-level cryptographics library
|
||||
*
|
||||
* Copyright 2001 Peter Gutmann, Andrew Kuchling, Niels Moeller
|
||||
*
|
||||
* The nettle library is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation; either version 2.1 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
* The nettle library is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
|
||||
* License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with the nettle library; see the file COPYING.LIB. If not, write to
|
||||
* the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
|
||||
* MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include "sha1.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
static unsigned int READ_UINT32(const UINT8* data)
|
||||
{
|
||||
return ((UINT32)data[0] << 24) |
|
||||
((UINT32)data[1] << 16) |
|
||||
((UINT32)data[2] << 8) |
|
||||
((UINT32)data[3]);
|
||||
}
|
||||
|
||||
static void WRITE_UINT32(unsigned char* data, UINT32 val)
|
||||
{
|
||||
data[0] = (val >> 24) & 0xFF;
|
||||
data[1] = (val >> 16) & 0xFF;
|
||||
data[2] = (val >> 8) & 0xFF;
|
||||
data[3] = (val >> 0) & 0xFF;
|
||||
}
|
||||
|
||||
|
||||
/* A block, treated as a sequence of 32-bit words. */
|
||||
#define SHA1_DATA_LENGTH 16
|
||||
|
||||
/* The SHA f()-functions. The f1 and f3 functions can be optimized to
|
||||
save one boolean operation each - thanks to Rich Schroeppel,
|
||||
[email protected] for discovering this */
|
||||
|
||||
/* #define f1(x,y,z) ( ( x & y ) | ( ~x & z ) ) Rounds 0-19 */
|
||||
#define f1(x,y,z) ( z ^ ( x & ( y ^ z ) ) ) /* Rounds 0-19 */
|
||||
#define f2(x,y,z) ( x ^ y ^ z ) /* Rounds 20-39 */
|
||||
/* #define f3(x,y,z) ( ( x & y ) | ( x & z ) | ( y & z ) ) Rounds 40-59 */
|
||||
#define f3(x,y,z) ( ( x & y ) | ( z & ( x | y ) ) ) /* Rounds 40-59 */
|
||||
#define f4(x,y,z) ( x ^ y ^ z ) /* Rounds 60-79 */
|
||||
|
||||
/* The SHA Mysterious Constants */
|
||||
|
||||
#define K1 0x5A827999L /* Rounds 0-19 */
|
||||
#define K2 0x6ED9EBA1L /* Rounds 20-39 */
|
||||
#define K3 0x8F1BBCDCL /* Rounds 40-59 */
|
||||
#define K4 0xCA62C1D6L /* Rounds 60-79 */
|
||||
|
||||
/* SHA initial values */
|
||||
|
||||
#define h0init 0x67452301L
|
||||
#define h1init 0xEFCDAB89L
|
||||
#define h2init 0x98BADCFEL
|
||||
#define h3init 0x10325476L
|
||||
#define h4init 0xC3D2E1F0L
|
||||
|
||||
/* 32-bit rotate left - kludged with shifts */
|
||||
#ifdef _MSC_VER
|
||||
#define ROTL(n,X) _lrotl(X, n)
|
||||
#else
|
||||
#define ROTL(n,X) ( ( (X) << (n) ) | ( (X) >> ( 32 - (n) ) ) )
|
||||
#endif
|
||||
|
||||
/* The initial expanding function. The hash function is defined over an
|
||||
80-word expanded input array W, where the first 16 are copies of the input
|
||||
data, and the remaining 64 are defined by
|
||||
|
||||
W[ i ] = W[ i - 16 ] ^ W[ i - 14 ] ^ W[ i - 8 ] ^ W[ i - 3 ]
|
||||
|
||||
This implementation generates these values on the fly in a circular
|
||||
buffer - thanks to Colin Plumb, [email protected] for this
|
||||
optimization.
|
||||
|
||||
The updated SHA changes the expanding function by adding a rotate of 1
|
||||
bit. Thanks to Jim Gillogly, [email protected], and an anonymous contributor
|
||||
for this information */
|
||||
|
||||
#define expand(W,i) ( W[ i & 15 ] = \
|
||||
ROTL( 1, ( W[ i & 15 ] ^ W[ (i - 14) & 15 ] ^ \
|
||||
W[ (i - 8) & 15 ] ^ W[ (i - 3) & 15 ] ) ) )
|
||||
|
||||
|
||||
/* The prototype SHA sub-round. The fundamental sub-round is:
|
||||
|
||||
a' = e + ROTL( 5, a ) + f( b, c, d ) + k + data;
|
||||
b' = a;
|
||||
c' = ROTL( 30, b );
|
||||
d' = c;
|
||||
e' = d;
|
||||
|
||||
but this is implemented by unrolling the loop 5 times and renaming the
|
||||
variables ( e, a, b, c, d ) = ( a', b', c', d', e' ) each iteration.
|
||||
This code is then replicated 20 times for each of the 4 functions, using
|
||||
the next 20 values from the W[] array each time */
|
||||
|
||||
#define subRound(a, b, c, d, e, f, k, data) \
|
||||
( e += ROTL( 5, a ) + f( b, c, d ) + k + data, b = ROTL( 30, b ) )
|
||||
|
||||
/* Initialize the SHA values */
|
||||
|
||||
void
|
||||
sha1_init(struct sha1_ctx *ctx)
|
||||
{
|
||||
/* Set the h-vars to their initial values */
|
||||
ctx->digest[ 0 ] = h0init;
|
||||
ctx->digest[ 1 ] = h1init;
|
||||
ctx->digest[ 2 ] = h2init;
|
||||
ctx->digest[ 3 ] = h3init;
|
||||
ctx->digest[ 4 ] = h4init;
|
||||
|
||||
/* Initialize bit count */
|
||||
ctx->count_low = ctx->count_high = 0;
|
||||
|
||||
/* Initialize buffer */
|
||||
ctx->index = 0;
|
||||
}
|
||||
|
||||
/* Perform the SHA transformation. Note that this code, like MD5, seems to
|
||||
break some optimizing compilers due to the complexity of the expressions
|
||||
and the size of the basic block. It may be necessary to split it into
|
||||
sections, e.g. based on the four subrounds
|
||||
|
||||
Note that this function destroys the data area */
|
||||
|
||||
static void
|
||||
sha1_transform(UINT32 *state, UINT32 *data)
|
||||
{
|
||||
UINT32 A, B, C, D, E; /* Local vars */
|
||||
|
||||
/* Set up first buffer and local data buffer */
|
||||
A = state[0];
|
||||
B = state[1];
|
||||
C = state[2];
|
||||
D = state[3];
|
||||
E = state[4];
|
||||
|
||||
/* Heavy mangling, in 4 sub-rounds of 20 interations each. */
|
||||
subRound( A, B, C, D, E, f1, K1, data[ 0] );
|
||||
subRound( E, A, B, C, D, f1, K1, data[ 1] );
|
||||
subRound( D, E, A, B, C, f1, K1, data[ 2] );
|
||||
subRound( C, D, E, A, B, f1, K1, data[ 3] );
|
||||
subRound( B, C, D, E, A, f1, K1, data[ 4] );
|
||||
subRound( A, B, C, D, E, f1, K1, data[ 5] );
|
||||
subRound( E, A, B, C, D, f1, K1, data[ 6] );
|
||||
subRound( D, E, A, B, C, f1, K1, data[ 7] );
|
||||
subRound( C, D, E, A, B, f1, K1, data[ 8] );
|
||||
subRound( B, C, D, E, A, f1, K1, data[ 9] );
|
||||
subRound( A, B, C, D, E, f1, K1, data[10] );
|
||||
subRound( E, A, B, C, D, f1, K1, data[11] );
|
||||
subRound( D, E, A, B, C, f1, K1, data[12] );
|
||||
subRound( C, D, E, A, B, f1, K1, data[13] );
|
||||
subRound( B, C, D, E, A, f1, K1, data[14] );
|
||||
subRound( A, B, C, D, E, f1, K1, data[15] );
|
||||
subRound( E, A, B, C, D, f1, K1, expand( data, 16 ) );
|
||||
subRound( D, E, A, B, C, f1, K1, expand( data, 17 ) );
|
||||
subRound( C, D, E, A, B, f1, K1, expand( data, 18 ) );
|
||||
subRound( B, C, D, E, A, f1, K1, expand( data, 19 ) );
|
||||
|
||||
subRound( A, B, C, D, E, f2, K2, expand( data, 20 ) );
|
||||
subRound( E, A, B, C, D, f2, K2, expand( data, 21 ) );
|
||||
subRound( D, E, A, B, C, f2, K2, expand( data, 22 ) );
|
||||
subRound( C, D, E, A, B, f2, K2, expand( data, 23 ) );
|
||||
subRound( B, C, D, E, A, f2, K2, expand( data, 24 ) );
|
||||
subRound( A, B, C, D, E, f2, K2, expand( data, 25 ) );
|
||||
subRound( E, A, B, C, D, f2, K2, expand( data, 26 ) );
|
||||
subRound( D, E, A, B, C, f2, K2, expand( data, 27 ) );
|
||||
subRound( C, D, E, A, B, f2, K2, expand( data, 28 ) );
|
||||
subRound( B, C, D, E, A, f2, K2, expand( data, 29 ) );
|
||||
subRound( A, B, C, D, E, f2, K2, expand( data, 30 ) );
|
||||
subRound( E, A, B, C, D, f2, K2, expand( data, 31 ) );
|
||||
subRound( D, E, A, B, C, f2, K2, expand( data, 32 ) );
|
||||
subRound( C, D, E, A, B, f2, K2, expand( data, 33 ) );
|
||||
subRound( B, C, D, E, A, f2, K2, expand( data, 34 ) );
|
||||
subRound( A, B, C, D, E, f2, K2, expand( data, 35 ) );
|
||||
subRound( E, A, B, C, D, f2, K2, expand( data, 36 ) );
|
||||
subRound( D, E, A, B, C, f2, K2, expand( data, 37 ) );
|
||||
subRound( C, D, E, A, B, f2, K2, expand( data, 38 ) );
|
||||
subRound( B, C, D, E, A, f2, K2, expand( data, 39 ) );
|
||||
|
||||
subRound( A, B, C, D, E, f3, K3, expand( data, 40 ) );
|
||||
subRound( E, A, B, C, D, f3, K3, expand( data, 41 ) );
|
||||
subRound( D, E, A, B, C, f3, K3, expand( data, 42 ) );
|
||||
subRound( C, D, E, A, B, f3, K3, expand( data, 43 ) );
|
||||
subRound( B, C, D, E, A, f3, K3, expand( data, 44 ) );
|
||||
subRound( A, B, C, D, E, f3, K3, expand( data, 45 ) );
|
||||
subRound( E, A, B, C, D, f3, K3, expand( data, 46 ) );
|
||||
subRound( D, E, A, B, C, f3, K3, expand( data, 47 ) );
|
||||
subRound( C, D, E, A, B, f3, K3, expand( data, 48 ) );
|
||||
subRound( B, C, D, E, A, f3, K3, expand( data, 49 ) );
|
||||
subRound( A, B, C, D, E, f3, K3, expand( data, 50 ) );
|
||||
subRound( E, A, B, C, D, f3, K3, expand( data, 51 ) );
|
||||
subRound( D, E, A, B, C, f3, K3, expand( data, 52 ) );
|
||||
subRound( C, D, E, A, B, f3, K3, expand( data, 53 ) );
|
||||
subRound( B, C, D, E, A, f3, K3, expand( data, 54 ) );
|
||||
subRound( A, B, C, D, E, f3, K3, expand( data, 55 ) );
|
||||
subRound( E, A, B, C, D, f3, K3, expand( data, 56 ) );
|
||||
subRound( D, E, A, B, C, f3, K3, expand( data, 57 ) );
|
||||
subRound( C, D, E, A, B, f3, K3, expand( data, 58 ) );
|
||||
subRound( B, C, D, E, A, f3, K3, expand( data, 59 ) );
|
||||
|
||||
subRound( A, B, C, D, E, f4, K4, expand( data, 60 ) );
|
||||
subRound( E, A, B, C, D, f4, K4, expand( data, 61 ) );
|
||||
subRound( D, E, A, B, C, f4, K4, expand( data, 62 ) );
|
||||
subRound( C, D, E, A, B, f4, K4, expand( data, 63 ) );
|
||||
subRound( B, C, D, E, A, f4, K4, expand( data, 64 ) );
|
||||
subRound( A, B, C, D, E, f4, K4, expand( data, 65 ) );
|
||||
subRound( E, A, B, C, D, f4, K4, expand( data, 66 ) );
|
||||
subRound( D, E, A, B, C, f4, K4, expand( data, 67 ) );
|
||||
subRound( C, D, E, A, B, f4, K4, expand( data, 68 ) );
|
||||
subRound( B, C, D, E, A, f4, K4, expand( data, 69 ) );
|
||||
subRound( A, B, C, D, E, f4, K4, expand( data, 70 ) );
|
||||
subRound( E, A, B, C, D, f4, K4, expand( data, 71 ) );
|
||||
subRound( D, E, A, B, C, f4, K4, expand( data, 72 ) );
|
||||
subRound( C, D, E, A, B, f4, K4, expand( data, 73 ) );
|
||||
subRound( B, C, D, E, A, f4, K4, expand( data, 74 ) );
|
||||
subRound( A, B, C, D, E, f4, K4, expand( data, 75 ) );
|
||||
subRound( E, A, B, C, D, f4, K4, expand( data, 76 ) );
|
||||
subRound( D, E, A, B, C, f4, K4, expand( data, 77 ) );
|
||||
subRound( C, D, E, A, B, f4, K4, expand( data, 78 ) );
|
||||
subRound( B, C, D, E, A, f4, K4, expand( data, 79 ) );
|
||||
|
||||
/* Build message digest */
|
||||
state[0] += A;
|
||||
state[1] += B;
|
||||
state[2] += C;
|
||||
state[3] += D;
|
||||
state[4] += E;
|
||||
}
|
||||
|
||||
static void
|
||||
sha1_block(struct sha1_ctx *ctx, const UINT8 *block)
|
||||
{
|
||||
UINT32 data[SHA1_DATA_LENGTH];
|
||||
int i;
|
||||
|
||||
/* Update block count */
|
||||
if (!++ctx->count_low)
|
||||
++ctx->count_high;
|
||||
|
||||
/* Endian independent conversion */
|
||||
for (i = 0; i<SHA1_DATA_LENGTH; i++, block += 4)
|
||||
data[i] = READ_UINT32(block);
|
||||
|
||||
sha1_transform(ctx->digest, data);
|
||||
}
|
||||
|
||||
void
|
||||
sha1_update(struct sha1_ctx *ctx,
|
||||
unsigned length, const UINT8 *buffer)
|
||||
{
|
||||
if (ctx->index)
|
||||
{ /* Try to fill partial block */
|
||||
unsigned left = SHA1_DATA_SIZE - ctx->index;
|
||||
if (length < left)
|
||||
{
|
||||
memcpy(ctx->block + ctx->index, buffer, length);
|
||||
ctx->index += length;
|
||||
return; /* Finished */
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy(ctx->block + ctx->index, buffer, left);
|
||||
sha1_block(ctx, ctx->block);
|
||||
buffer += left;
|
||||
length -= left;
|
||||
}
|
||||
}
|
||||
while (length >= SHA1_DATA_SIZE)
|
||||
{
|
||||
sha1_block(ctx, buffer);
|
||||
buffer += SHA1_DATA_SIZE;
|
||||
length -= SHA1_DATA_SIZE;
|
||||
}
|
||||
ctx->index = length;
|
||||
if (length)
|
||||
/* Buffer leftovers */
|
||||
memcpy(ctx->block, buffer, length);
|
||||
}
|
||||
|
||||
/* Final wrapup - pad to SHA1_DATA_SIZE-byte boundary with the bit pattern
|
||||
1 0* (64-bit count of bits processed, MSB-first) */
|
||||
|
||||
void
|
||||
sha1_final(struct sha1_ctx *ctx)
|
||||
{
|
||||
UINT32 data[SHA1_DATA_LENGTH];
|
||||
int i;
|
||||
int words;
|
||||
|
||||
i = ctx->index;
|
||||
|
||||
/* Set the first char of padding to 0x80. This is safe since there is
|
||||
always at least one byte free */
|
||||
|
||||
assert(i < SHA1_DATA_SIZE);
|
||||
ctx->block[i++] = 0x80;
|
||||
|
||||
/* Fill rest of word */
|
||||
for( ; i & 3; i++)
|
||||
ctx->block[i] = 0;
|
||||
|
||||
/* i is now a multiple of the word size 4 */
|
||||
words = i >> 2;
|
||||
for (i = 0; i < words; i++)
|
||||
data[i] = READ_UINT32(ctx->block + 4*i);
|
||||
|
||||
if (words > (SHA1_DATA_LENGTH-2))
|
||||
{ /* No room for length in this block. Process it and
|
||||
* pad with another one */
|
||||
for (i = words ; i < SHA1_DATA_LENGTH; i++)
|
||||
data[i] = 0;
|
||||
sha1_transform(ctx->digest, data);
|
||||
for (i = 0; i < (SHA1_DATA_LENGTH-2); i++)
|
||||
data[i] = 0;
|
||||
}
|
||||
else
|
||||
for (i = words ; i < SHA1_DATA_LENGTH - 2; i++)
|
||||
data[i] = 0;
|
||||
|
||||
/* There are 512 = 2^9 bits in one block */
|
||||
data[SHA1_DATA_LENGTH-2] = (ctx->count_high << 9) | (ctx->count_low >> 23);
|
||||
data[SHA1_DATA_LENGTH-1] = (ctx->count_low << 9) | (ctx->index << 3);
|
||||
sha1_transform(ctx->digest, data);
|
||||
}
|
||||
|
||||
void
|
||||
sha1_digest(const struct sha1_ctx *ctx,
|
||||
unsigned length,
|
||||
UINT8 *digest)
|
||||
{
|
||||
unsigned i;
|
||||
unsigned words;
|
||||
unsigned leftover;
|
||||
|
||||
assert(length <= SHA1_DIGEST_SIZE);
|
||||
|
||||
words = length / 4;
|
||||
leftover = length % 4;
|
||||
|
||||
for (i = 0; i < words; i++, digest += 4)
|
||||
WRITE_UINT32(digest, ctx->digest[i]);
|
||||
|
||||
if (leftover)
|
||||
{
|
||||
UINT32 word;
|
||||
unsigned j = leftover;
|
||||
|
||||
assert(i < _SHA1_DIGEST_LENGTH);
|
||||
|
||||
word = ctx->digest[i];
|
||||
|
||||
switch (leftover)
|
||||
{
|
||||
default:
|
||||
/* this is just here to keep the compiler happy; it can never happen */
|
||||
case 3:
|
||||
digest[--j] = (word >> 8) & 0xff;
|
||||
/* Fall through */
|
||||
case 2:
|
||||
digest[--j] = (word >> 16) & 0xff;
|
||||
/* Fall through */
|
||||
case 1:
|
||||
digest[--j] = (word >> 24) & 0xff;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,63 +0,0 @@
|
||||
/* sha1.h
|
||||
*
|
||||
* The sha1 hash function.
|
||||
*/
|
||||
|
||||
/* nettle, low-level cryptographics library
|
||||
*
|
||||
* Copyright 2001 Niels Moeller
|
||||
*
|
||||
* The nettle library is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation; either version 2.1 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
* The nettle library is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
|
||||
* License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with the nettle library; see the file COPYING.LIB. If not, write to
|
||||
* the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
|
||||
* MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef NETTLE_SHA1_H_INCLUDED
|
||||
#define NETTLE_SHA1_H_INCLUDED
|
||||
|
||||
#include "../chdr/coretypes.h"
|
||||
|
||||
|
||||
|
||||
#define SHA1_DIGEST_SIZE 20
|
||||
#define SHA1_DATA_SIZE 64
|
||||
|
||||
/* Digest is kept internally as 4 32-bit words. */
|
||||
#define _SHA1_DIGEST_LENGTH 5
|
||||
|
||||
struct sha1_ctx
|
||||
{
|
||||
UINT32 digest[_SHA1_DIGEST_LENGTH]; /* Message digest */
|
||||
UINT32 count_low, count_high; /* 64-bit block count */
|
||||
UINT8 block[SHA1_DATA_SIZE]; /* SHA1 data buffer */
|
||||
unsigned int index; /* index into buffer */
|
||||
};
|
||||
|
||||
void
|
||||
sha1_init(struct sha1_ctx *ctx);
|
||||
|
||||
void
|
||||
sha1_update(struct sha1_ctx *ctx,
|
||||
unsigned length,
|
||||
const UINT8 *data);
|
||||
|
||||
void
|
||||
sha1_final(struct sha1_ctx *ctx);
|
||||
|
||||
void
|
||||
sha1_digest(const struct sha1_ctx *ctx,
|
||||
unsigned length,
|
||||
UINT8 *digest);
|
||||
|
||||
#endif /* NETTLE_SHA1_H_INCLUDED */
|
||||
@@ -1,161 +0,0 @@
|
||||
/*********************************************************************
|
||||
* Filename: sha256.c
|
||||
* Author: Brad Conte (brad AT bradconte.com)
|
||||
* Copyright:
|
||||
* Disclaimer: This code is presented "as is" without any guarantees.
|
||||
* Details: Implementation of the SHA-256 hashing algorithm.
|
||||
SHA-256 is one of the three algorithms in the SHA2
|
||||
specification. The others, SHA-384 and SHA-512, are not
|
||||
offered in this implementation.
|
||||
Algorithm specification can be found here:
|
||||
* http://csrc.nist.gov/publications/fips/fips180-2/fips180-2withchangenotice.pdf
|
||||
This implementation uses little endian byte order.
|
||||
*********************************************************************/
|
||||
|
||||
/*************************** HEADER FILES ***************************/
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "sha256.h"
|
||||
|
||||
#define WORD uint32_t
|
||||
#define BYTE uint8_t
|
||||
|
||||
/****************************** MACROS ******************************/
|
||||
#define ROTLEFT(a,b) (((a) << (b)) | ((a) >> (32-(b))))
|
||||
#define ROTRIGHT(a,b) (((a) >> (b)) | ((a) << (32-(b))))
|
||||
|
||||
#define CH(x,y,z) (((x) & (y)) ^ (~(x) & (z)))
|
||||
#define MAJ(x,y,z) (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z)))
|
||||
#define EP0(x) (ROTRIGHT(x,2) ^ ROTRIGHT(x,13) ^ ROTRIGHT(x,22))
|
||||
#define EP1(x) (ROTRIGHT(x,6) ^ ROTRIGHT(x,11) ^ ROTRIGHT(x,25))
|
||||
#define SIG0(x) (ROTRIGHT(x,7) ^ ROTRIGHT(x,18) ^ ((x) >> 3))
|
||||
#define SIG1(x) (ROTRIGHT(x,17) ^ ROTRIGHT(x,19) ^ ((x) >> 10))
|
||||
|
||||
/**************************** VARIABLES *****************************/
|
||||
static const WORD k[64] = {
|
||||
0x428a2f98,0x71374491,0xb5c0fbcf,0xe9b5dba5,0x3956c25b,0x59f111f1,0x923f82a4,0xab1c5ed5,
|
||||
0xd807aa98,0x12835b01,0x243185be,0x550c7dc3,0x72be5d74,0x80deb1fe,0x9bdc06a7,0xc19bf174,
|
||||
0xe49b69c1,0xefbe4786,0x0fc19dc6,0x240ca1cc,0x2de92c6f,0x4a7484aa,0x5cb0a9dc,0x76f988da,
|
||||
0x983e5152,0xa831c66d,0xb00327c8,0xbf597fc7,0xc6e00bf3,0xd5a79147,0x06ca6351,0x14292967,
|
||||
0x27b70a85,0x2e1b2138,0x4d2c6dfc,0x53380d13,0x650a7354,0x766a0abb,0x81c2c92e,0x92722c85,
|
||||
0xa2bfe8a1,0xa81a664b,0xc24b8b70,0xc76c51a3,0xd192e819,0xd6990624,0xf40e3585,0x106aa070,
|
||||
0x19a4c116,0x1e376c08,0x2748774c,0x34b0bcb5,0x391c0cb3,0x4ed8aa4a,0x5b9cca4f,0x682e6ff3,
|
||||
0x748f82ee,0x78a5636f,0x84c87814,0x8cc70208,0x90befffa,0xa4506ceb,0xbef9a3f7,0xc67178f2
|
||||
};
|
||||
|
||||
/*********************** FUNCTION DEFINITIONS ***********************/
|
||||
void sha256_transform(SHA256_CTX *ctx, const BYTE data[])
|
||||
{
|
||||
WORD a, b, c, d, e, f, g, h, i, j, t1, t2, m[64];
|
||||
|
||||
for (i = 0, j = 0; i < 16; ++i, j += 4)
|
||||
m[i] = (data[j] << 24) | (data[j + 1] << 16) | (data[j + 2] << 8) | (data[j + 3]);
|
||||
for ( ; i < 64; ++i)
|
||||
m[i] = SIG1(m[i - 2]) + m[i - 7] + SIG0(m[i - 15]) + m[i - 16];
|
||||
|
||||
a = ctx->state[0];
|
||||
b = ctx->state[1];
|
||||
c = ctx->state[2];
|
||||
d = ctx->state[3];
|
||||
e = ctx->state[4];
|
||||
f = ctx->state[5];
|
||||
g = ctx->state[6];
|
||||
h = ctx->state[7];
|
||||
|
||||
for (i = 0; i < 64; ++i) {
|
||||
t1 = h + EP1(e) + CH(e,f,g) + k[i] + m[i];
|
||||
t2 = EP0(a) + MAJ(a,b,c);
|
||||
h = g;
|
||||
g = f;
|
||||
f = e;
|
||||
e = d + t1;
|
||||
d = c;
|
||||
c = b;
|
||||
b = a;
|
||||
a = t1 + t2;
|
||||
}
|
||||
|
||||
ctx->state[0] += a;
|
||||
ctx->state[1] += b;
|
||||
ctx->state[2] += c;
|
||||
ctx->state[3] += d;
|
||||
ctx->state[4] += e;
|
||||
ctx->state[5] += f;
|
||||
ctx->state[6] += g;
|
||||
ctx->state[7] += h;
|
||||
}
|
||||
|
||||
void sha256_init(SHA256_CTX *ctx)
|
||||
{
|
||||
ctx->datalen = 0;
|
||||
ctx->bitlen = 0;
|
||||
ctx->state[0] = 0x6a09e667;
|
||||
ctx->state[1] = 0xbb67ae85;
|
||||
ctx->state[2] = 0x3c6ef372;
|
||||
ctx->state[3] = 0xa54ff53a;
|
||||
ctx->state[4] = 0x510e527f;
|
||||
ctx->state[5] = 0x9b05688c;
|
||||
ctx->state[6] = 0x1f83d9ab;
|
||||
ctx->state[7] = 0x5be0cd19;
|
||||
}
|
||||
|
||||
void sha256_update(SHA256_CTX *ctx, const BYTE data[], size_t len)
|
||||
{
|
||||
WORD i;
|
||||
|
||||
for (i = 0; i < len; ++i) {
|
||||
ctx->data[ctx->datalen] = data[i];
|
||||
ctx->datalen++;
|
||||
if (ctx->datalen == 64) {
|
||||
sha256_transform(ctx, ctx->data);
|
||||
ctx->bitlen += 512;
|
||||
ctx->datalen = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void sha256_final(SHA256_CTX *ctx, BYTE hash[])
|
||||
{
|
||||
WORD i;
|
||||
|
||||
i = ctx->datalen;
|
||||
|
||||
// Pad whatever data is left in the buffer.
|
||||
if (ctx->datalen < 56) {
|
||||
ctx->data[i++] = 0x80;
|
||||
while (i < 56)
|
||||
ctx->data[i++] = 0x00;
|
||||
}
|
||||
else {
|
||||
ctx->data[i++] = 0x80;
|
||||
while (i < 64)
|
||||
ctx->data[i++] = 0x00;
|
||||
sha256_transform(ctx, ctx->data);
|
||||
memset(ctx->data, 0, 56);
|
||||
}
|
||||
|
||||
// Append to the padding the total message's length in bits and transform.
|
||||
ctx->bitlen += ctx->datalen * 8;
|
||||
ctx->data[63] = (BYTE)(ctx->bitlen);
|
||||
ctx->data[62] = (BYTE)(ctx->bitlen >> 8);
|
||||
ctx->data[61] = (BYTE)(ctx->bitlen >> 16);
|
||||
ctx->data[60] = (BYTE)(ctx->bitlen >> 24);
|
||||
ctx->data[59] = (BYTE)(ctx->bitlen >> 32);
|
||||
ctx->data[58] = (BYTE)(ctx->bitlen >> 40);
|
||||
ctx->data[57] = (BYTE)(ctx->bitlen >> 48);
|
||||
ctx->data[56] = (BYTE)(ctx->bitlen >> 56);
|
||||
sha256_transform(ctx, ctx->data);
|
||||
|
||||
// Since this implementation uses little endian byte ordering and SHA uses big endian,
|
||||
// reverse all the bytes when copying the final state to the output hash.
|
||||
for (i = 0; i < 4; ++i) {
|
||||
hash[i] = (ctx->state[0] >> (24 - i * 8)) & 0x000000ff;
|
||||
hash[i + 4] = (ctx->state[1] >> (24 - i * 8)) & 0x000000ff;
|
||||
hash[i + 8] = (ctx->state[2] >> (24 - i * 8)) & 0x000000ff;
|
||||
hash[i + 12] = (ctx->state[3] >> (24 - i * 8)) & 0x000000ff;
|
||||
hash[i + 16] = (ctx->state[4] >> (24 - i * 8)) & 0x000000ff;
|
||||
hash[i + 20] = (ctx->state[5] >> (24 - i * 8)) & 0x000000ff;
|
||||
hash[i + 24] = (ctx->state[6] >> (24 - i * 8)) & 0x000000ff;
|
||||
hash[i + 28] = (ctx->state[7] >> (24 - i * 8)) & 0x000000ff;
|
||||
}
|
||||
}
|
||||
@@ -1,37 +0,0 @@
|
||||
/*********************************************************************
|
||||
* Filename: sha256.h
|
||||
* Author: Brad Conte (brad AT bradconte.com)
|
||||
* Copyright:
|
||||
* Disclaimer: This code is presented "as is" without any guarantees.
|
||||
* Details: Defines the API for the corresponding SHA1 implementation.
|
||||
*********************************************************************/
|
||||
|
||||
#ifndef SHA256_H
|
||||
#define SHA256_H
|
||||
|
||||
/*************************** HEADER FILES ***************************/
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
/****************************** MACROS ******************************/
|
||||
#define SHA256_BLOCK_SIZE 32 // SHA256 outputs a 32 byte digest
|
||||
|
||||
/**************************** DATA TYPES ****************************/
|
||||
/*
|
||||
typedef uint8_t BYTE; // 8-bit byte
|
||||
typedef uint32_t WORD; // 32-bit word, change to "long" for 16-bit machines
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
uint8_t data[64];
|
||||
uint32_t datalen;
|
||||
uint64_t bitlen;
|
||||
uint32_t state[8];
|
||||
} SHA256_CTX;
|
||||
|
||||
/*********************** FUNCTION DECLARATIONS **********************/
|
||||
void sha256_init(SHA256_CTX *ctx);
|
||||
void sha256_update(SHA256_CTX *ctx, const uint8_t data[], size_t len);
|
||||
void sha256_final(SHA256_CTX *ctx, uint8_t hash[]);
|
||||
|
||||
#endif // SHA256_H
|
||||
@@ -2795,6 +2795,7 @@ ImGuiWindow::ImGuiWindow(ImGuiContext* context, const char* name) : DrawListInst
|
||||
DrawList = &DrawListInst;
|
||||
DrawList->_Data = &context->DrawListSharedData;
|
||||
DrawList->_OwnerName = Name;
|
||||
DragScrolling = false;
|
||||
}
|
||||
|
||||
ImGuiWindow::~ImGuiWindow()
|
||||
|
||||
@@ -1619,6 +1619,8 @@ struct IMGUI_API ImGuiWindow
|
||||
ImVec2 ScrollTargetCenterRatio; // 0.0f = scroll so that target position is at top, 0.5f = scroll so that target position is centered
|
||||
ImVec2 ScrollTargetEdgeSnapDist; // 0.0f = no snapping, >0.0f snapping threshold
|
||||
ImVec2 ScrollbarSizes; // Size taken by each scrollbars on their smaller axis. Pay attention! ScrollbarSizes.x == width of the vertical scrollbar, ScrollbarSizes.y = height of the horizontal scrollbar.
|
||||
ImVec2 ScrollSpeed;
|
||||
bool DragScrolling;
|
||||
bool ScrollbarX, ScrollbarY; // Are scrollbars visible?
|
||||
bool Active; // Set to true on Begin(), unless Collapsed
|
||||
bool WasActive;
|
||||
|
||||
@@ -636,7 +636,24 @@ bool ImGui::ButtonBehavior(const ImRect& bb, ImGuiID id, bool* out_hovered, bool
|
||||
ClearActiveID();
|
||||
}
|
||||
if (!(flags & ImGuiButtonFlags_NoNavFocus))
|
||||
{
|
||||
g.NavDisableHighlight = true;
|
||||
// Check if dragging (except for scrollbars)
|
||||
if (held && !hovered && !pressed)
|
||||
{
|
||||
ImVec2 delta = GetMouseDragDelta(ImGuiMouseButton_Left);
|
||||
if (delta.x != 0.f || delta.y != 0.f)
|
||||
{
|
||||
ClearActiveID();
|
||||
ImGuiWindow *scrollableWindow = window;
|
||||
while ((scrollableWindow->Flags & ImGuiWindowFlags_ChildWindow) && scrollableWindow->ScrollMax.x == 0.0f && scrollableWindow->ScrollMax.y == 0.0f)
|
||||
scrollableWindow = scrollableWindow->ParentWindow;
|
||||
scrollableWindow->DragScrolling = true;
|
||||
held = false;
|
||||
pressed = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (g.ActiveIdSource == ImGuiInputSource_Nav)
|
||||
{
|
||||
@@ -6007,6 +6024,11 @@ bool ImGui::Selectable(const char* label, bool selected, ImGuiSelectableFlags fl
|
||||
|
||||
if (flags & ImGuiSelectableFlags_Disabled)
|
||||
selected = false;
|
||||
if (window->DragScrolling)
|
||||
{
|
||||
selected = false;
|
||||
button_flags |= ImGuiButtonFlags_Disabled;
|
||||
}
|
||||
|
||||
const bool was_selected = selected;
|
||||
bool hovered, held;
|
||||
|
||||
+1
-1
Submodule core/deps/libchdr updated: 00319cf31f...d3ffd20ca7.
@@ -1,100 +0,0 @@
|
||||
diff --git a/src/video/windows/SDL_windowsevents.c b/src/video/windows/SDL_windowsevents.c
|
||||
index 2557d8628..f3d214b1d 100644
|
||||
--- a/src/video/windows/SDL_windowsevents.c
|
||||
+++ b/src/video/windows/SDL_windowsevents.c
|
||||
@@ -294,31 +294,31 @@ WIN_CheckWParamMouseButtons(WPARAM wParam, SDL_WindowData *data, SDL_MouseID mou
|
||||
}
|
||||
|
||||
static void
|
||||
-WIN_CheckRawMouseButtons(ULONG rawButtons, SDL_WindowData *data)
|
||||
+WIN_CheckRawMouseButtons(ULONG rawButtons, SDL_WindowData *data, SDL_MouseID mouseID)
|
||||
{
|
||||
if (rawButtons != data->mouse_button_flags) {
|
||||
Uint32 mouseFlags = SDL_GetMouseState(NULL, NULL);
|
||||
SDL_bool swapButtons = GetSystemMetrics(SM_SWAPBUTTON) != 0;
|
||||
if ((rawButtons & RI_MOUSE_BUTTON_1_DOWN))
|
||||
- WIN_CheckWParamMouseButton((rawButtons & RI_MOUSE_BUTTON_1_DOWN), mouseFlags, swapButtons, data, SDL_BUTTON_LEFT, 0);
|
||||
+ WIN_CheckWParamMouseButton((rawButtons & RI_MOUSE_BUTTON_1_DOWN), mouseFlags, swapButtons, data, SDL_BUTTON_LEFT, mouseID);
|
||||
if ((rawButtons & RI_MOUSE_BUTTON_1_UP))
|
||||
- WIN_CheckWParamMouseButton(!(rawButtons & RI_MOUSE_BUTTON_1_UP), mouseFlags, swapButtons, data, SDL_BUTTON_LEFT, 0);
|
||||
+ WIN_CheckWParamMouseButton(!(rawButtons & RI_MOUSE_BUTTON_1_UP), mouseFlags, swapButtons, data, SDL_BUTTON_LEFT, mouseID);
|
||||
if ((rawButtons & RI_MOUSE_BUTTON_2_DOWN))
|
||||
- WIN_CheckWParamMouseButton((rawButtons & RI_MOUSE_BUTTON_2_DOWN), mouseFlags, swapButtons, data, SDL_BUTTON_RIGHT, 0);
|
||||
+ WIN_CheckWParamMouseButton((rawButtons & RI_MOUSE_BUTTON_2_DOWN), mouseFlags, swapButtons, data, SDL_BUTTON_RIGHT, mouseID);
|
||||
if ((rawButtons & RI_MOUSE_BUTTON_2_UP))
|
||||
- WIN_CheckWParamMouseButton(!(rawButtons & RI_MOUSE_BUTTON_2_UP), mouseFlags, swapButtons, data, SDL_BUTTON_RIGHT, 0);
|
||||
+ WIN_CheckWParamMouseButton(!(rawButtons & RI_MOUSE_BUTTON_2_UP), mouseFlags, swapButtons, data, SDL_BUTTON_RIGHT, mouseID);
|
||||
if ((rawButtons & RI_MOUSE_BUTTON_3_DOWN))
|
||||
- WIN_CheckWParamMouseButton((rawButtons & RI_MOUSE_BUTTON_3_DOWN), mouseFlags, swapButtons, data, SDL_BUTTON_MIDDLE, 0);
|
||||
+ WIN_CheckWParamMouseButton((rawButtons & RI_MOUSE_BUTTON_3_DOWN), mouseFlags, swapButtons, data, SDL_BUTTON_MIDDLE, mouseID);
|
||||
if ((rawButtons & RI_MOUSE_BUTTON_3_UP))
|
||||
- WIN_CheckWParamMouseButton(!(rawButtons & RI_MOUSE_BUTTON_3_UP), mouseFlags, swapButtons, data, SDL_BUTTON_MIDDLE, 0);
|
||||
+ WIN_CheckWParamMouseButton(!(rawButtons & RI_MOUSE_BUTTON_3_UP), mouseFlags, swapButtons, data, SDL_BUTTON_MIDDLE, mouseID);
|
||||
if ((rawButtons & RI_MOUSE_BUTTON_4_DOWN))
|
||||
- WIN_CheckWParamMouseButton((rawButtons & RI_MOUSE_BUTTON_4_DOWN), mouseFlags, swapButtons, data, SDL_BUTTON_X1, 0);
|
||||
+ WIN_CheckWParamMouseButton((rawButtons & RI_MOUSE_BUTTON_4_DOWN), mouseFlags, swapButtons, data, SDL_BUTTON_X1, mouseID);
|
||||
if ((rawButtons & RI_MOUSE_BUTTON_4_UP))
|
||||
- WIN_CheckWParamMouseButton(!(rawButtons & RI_MOUSE_BUTTON_4_UP), mouseFlags, swapButtons, data, SDL_BUTTON_X1, 0);
|
||||
+ WIN_CheckWParamMouseButton(!(rawButtons & RI_MOUSE_BUTTON_4_UP), mouseFlags, swapButtons, data, SDL_BUTTON_X1, mouseID);
|
||||
if ((rawButtons & RI_MOUSE_BUTTON_5_DOWN))
|
||||
- WIN_CheckWParamMouseButton((rawButtons & RI_MOUSE_BUTTON_5_DOWN), mouseFlags, swapButtons, data, SDL_BUTTON_X2, 0);
|
||||
+ WIN_CheckWParamMouseButton((rawButtons & RI_MOUSE_BUTTON_5_DOWN), mouseFlags, swapButtons, data, SDL_BUTTON_X2, mouseID);
|
||||
if ((rawButtons & RI_MOUSE_BUTTON_5_UP))
|
||||
- WIN_CheckWParamMouseButton(!(rawButtons & RI_MOUSE_BUTTON_5_UP), mouseFlags, swapButtons, data, SDL_BUTTON_X2, 0);
|
||||
+ WIN_CheckWParamMouseButton(!(rawButtons & RI_MOUSE_BUTTON_5_UP), mouseFlags, swapButtons, data, SDL_BUTTON_X2, mouseID);
|
||||
data->mouse_button_flags = rawButtons;
|
||||
}
|
||||
}
|
||||
@@ -631,15 +631,17 @@ WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
||||
|
||||
/* Mouse data (ignoring synthetic mouse events generated for touchscreens) */
|
||||
if (inp.header.dwType == RIM_TYPEMOUSE) {
|
||||
+ SDL_MouseID mouseID;
|
||||
if (GetMouseMessageSource() == SDL_MOUSE_EVENT_SOURCE_TOUCH ||
|
||||
(GetMessageExtraInfo() & 0x82) == 0x82) {
|
||||
break;
|
||||
}
|
||||
+ mouseID = (Uint32)(uintptr_t)inp.header.hDevice;
|
||||
if (isRelative) {
|
||||
RAWMOUSE* rawmouse = &inp.data.mouse;
|
||||
|
||||
if ((rawmouse->usFlags & 0x01) == MOUSE_MOVE_RELATIVE) {
|
||||
- SDL_SendMouseMotion(data->window, 0, 1, (int)rawmouse->lLastX, (int)rawmouse->lLastY);
|
||||
+ SDL_SendMouseMotion(data->window, mouseID, 1, (int)rawmouse->lLastX, (int)rawmouse->lLastY);
|
||||
} else if (rawmouse->lLastX || rawmouse->lLastY) {
|
||||
/* synthesize relative moves from the abs position */
|
||||
static SDL_Point lastMousePoint;
|
||||
@@ -654,12 +656,12 @@ WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
||||
lastMousePoint.y = y;
|
||||
}
|
||||
|
||||
- SDL_SendMouseMotion(data->window, 0, 1, (int)(x-lastMousePoint.x), (int)(y-lastMousePoint.y));
|
||||
+ SDL_SendMouseMotion(data->window, mouseID, 1, (int)(x-lastMousePoint.x), (int)(y-lastMousePoint.y));
|
||||
|
||||
lastMousePoint.x = x;
|
||||
lastMousePoint.y = y;
|
||||
}
|
||||
- WIN_CheckRawMouseButtons(rawmouse->usButtonFlags, data);
|
||||
+ WIN_CheckRawMouseButtons(rawmouse->usButtonFlags, data, mouseID);
|
||||
} else if (isCapture) {
|
||||
/* we check for where Windows thinks the system cursor lives in this case, so we don't really lose mouse accel, etc. */
|
||||
POINT pt;
|
||||
@@ -675,12 +677,12 @@ WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
||||
if(currentHnd != hwnd || pt.x < 0 || pt.y < 0 || pt.x > hwndRect.right || pt.y > hwndRect.right) {
|
||||
SDL_bool swapButtons = GetSystemMetrics(SM_SWAPBUTTON) != 0;
|
||||
|
||||
- SDL_SendMouseMotion(data->window, 0, 0, (int)pt.x, (int)pt.y);
|
||||
- SDL_SendMouseButton(data->window, 0, GetAsyncKeyState(VK_LBUTTON) & 0x8000 ? SDL_PRESSED : SDL_RELEASED, !swapButtons ? SDL_BUTTON_LEFT : SDL_BUTTON_RIGHT);
|
||||
- SDL_SendMouseButton(data->window, 0, GetAsyncKeyState(VK_RBUTTON) & 0x8000 ? SDL_PRESSED : SDL_RELEASED, !swapButtons ? SDL_BUTTON_RIGHT : SDL_BUTTON_LEFT);
|
||||
- SDL_SendMouseButton(data->window, 0, GetAsyncKeyState(VK_MBUTTON) & 0x8000 ? SDL_PRESSED : SDL_RELEASED, SDL_BUTTON_MIDDLE);
|
||||
- SDL_SendMouseButton(data->window, 0, GetAsyncKeyState(VK_XBUTTON1) & 0x8000 ? SDL_PRESSED : SDL_RELEASED, SDL_BUTTON_X1);
|
||||
- SDL_SendMouseButton(data->window, 0, GetAsyncKeyState(VK_XBUTTON2) & 0x8000 ? SDL_PRESSED : SDL_RELEASED, SDL_BUTTON_X2);
|
||||
+ SDL_SendMouseMotion(data->window, mouseID, 0, (int)pt.x, (int)pt.y);
|
||||
+ SDL_SendMouseButton(data->window, mouseID, GetAsyncKeyState(VK_LBUTTON) & 0x8000 ? SDL_PRESSED : SDL_RELEASED, !swapButtons ? SDL_BUTTON_LEFT : SDL_BUTTON_RIGHT);
|
||||
+ SDL_SendMouseButton(data->window, mouseID, GetAsyncKeyState(VK_RBUTTON) & 0x8000 ? SDL_PRESSED : SDL_RELEASED, !swapButtons ? SDL_BUTTON_RIGHT : SDL_BUTTON_LEFT);
|
||||
+ SDL_SendMouseButton(data->window, mouseID, GetAsyncKeyState(VK_MBUTTON) & 0x8000 ? SDL_PRESSED : SDL_RELEASED, SDL_BUTTON_MIDDLE);
|
||||
+ SDL_SendMouseButton(data->window, mouseID, GetAsyncKeyState(VK_XBUTTON1) & 0x8000 ? SDL_PRESSED : SDL_RELEASED, SDL_BUTTON_X1);
|
||||
+ SDL_SendMouseButton(data->window, mouseID, GetAsyncKeyState(VK_XBUTTON2) & 0x8000 ? SDL_PRESSED : SDL_RELEASED, SDL_BUTTON_X2);
|
||||
}
|
||||
} else {
|
||||
SDL_assert(0 && "Shouldn't happen");
|
||||
+2
-2
@@ -39,8 +39,8 @@ void dc_request_reset();
|
||||
void dc_exit();
|
||||
void dc_resume();
|
||||
void dc_step();
|
||||
void dc_savestate();
|
||||
void dc_loadstate();
|
||||
void dc_savestate(int index = 0);
|
||||
void dc_loadstate(int index = 0);
|
||||
void dc_load_game(const char *path);
|
||||
bool dc_is_load_done();
|
||||
void dc_cancel_load();
|
||||
|
||||
@@ -302,18 +302,9 @@ extern InterruptInfo* SCIRE;
|
||||
extern CommonData_struct* CommonData;
|
||||
extern DSPData_struct* DSPData;
|
||||
|
||||
void UpdateAICA(u32 Cycles);
|
||||
|
||||
void AICA_Init();
|
||||
void AICA_Term();
|
||||
|
||||
//u32 ReadAicaReg(u32 reg);
|
||||
void WriteAicaReg8(u32 reg,u32 data);
|
||||
|
||||
template<u32 sz>
|
||||
void WriteAicaReg(u32 reg,u32 data);
|
||||
|
||||
////
|
||||
//Timers :)
|
||||
struct AicaTimerData
|
||||
{
|
||||
|
||||
@@ -37,6 +37,7 @@ public:
|
||||
|
||||
void Compile(struct dsp_t *DSP)
|
||||
{
|
||||
JITWriteProtect(false);
|
||||
this->DSP = DSP;
|
||||
DEBUG_LOG(AICA_ARM, "DSPAssembler::DSPCompile recompiling for arm64 at %p", GetBuffer()->GetStartAddress<void*>());
|
||||
|
||||
@@ -329,6 +330,7 @@ public:
|
||||
vmem_platform_flush_cache(
|
||||
GetBuffer()->GetStartAddress<void*>(), GetBuffer()->GetEndAddress<void*>(),
|
||||
GetBuffer()->GetStartAddress<void*>(), GetBuffer()->GetEndAddress<void*>());
|
||||
JITWriteProtect(true);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
@@ -21,7 +21,6 @@
|
||||
|
||||
#if HOST_CPU == CPU_X64 && FEAT_DSPREC != DYNAREC_NONE
|
||||
|
||||
#define XBYAK_NO_OP_NAMES
|
||||
#include <xbyak/xbyak.h>
|
||||
#include "dsp.h"
|
||||
#include "aica.h"
|
||||
|
||||
@@ -21,8 +21,6 @@
|
||||
|
||||
#if HOST_CPU == CPU_X86 && FEAT_DSPREC != DYNAREC_NONE
|
||||
|
||||
#define XBYAK32
|
||||
#define XBYAK_NO_OP_NAMES
|
||||
#include <xbyak/xbyak.h>
|
||||
#include "dsp.h"
|
||||
#include "aica.h"
|
||||
|
||||
@@ -107,9 +107,17 @@ class Arm7Compiler : public MacroAssembler
|
||||
void call(void *loc)
|
||||
{
|
||||
ptrdiff_t offset = reinterpret_cast<uintptr_t>(loc) - GetBuffer()->GetStartAddress<uintptr_t>();
|
||||
Label function_label;
|
||||
BindToOffset(&function_label, offset);
|
||||
Bl(&function_label);
|
||||
if (offset < -128 * 1024 * 1024 || offset > 128 * 1024 * 1024)
|
||||
{
|
||||
Mov(x4, reinterpret_cast<uintptr_t>(loc));
|
||||
Blr(x4);
|
||||
}
|
||||
else
|
||||
{
|
||||
Label function_label;
|
||||
BindToOffset(&function_label, offset);
|
||||
Bl(&function_label);
|
||||
}
|
||||
}
|
||||
|
||||
Operand getOperand(const ArmOp::Operand& arg, const Register& scratch_reg)
|
||||
@@ -543,6 +551,7 @@ public:
|
||||
|
||||
void compile(const std::vector<ArmOp>& block_ops, u32 cycles)
|
||||
{
|
||||
JITWriteProtect(false);
|
||||
Ldr(w1, arm_reg_operand(CYCL_CNT));
|
||||
Sub(w1, w1, cycles);
|
||||
Str(w1, arm_reg_operand(CYCL_CNT));
|
||||
@@ -622,6 +631,7 @@ public:
|
||||
#endif
|
||||
delete regalloc;
|
||||
regalloc = nullptr;
|
||||
JITWriteProtect(true);
|
||||
}
|
||||
|
||||
void generateMainLoop()
|
||||
@@ -632,6 +642,7 @@ public:
|
||||
verify(arm_compilecode != nullptr);
|
||||
return;
|
||||
}
|
||||
JITWriteProtect(false);
|
||||
Label arm_dispatch_label;
|
||||
Label arm_dofiq;
|
||||
Label arm_exit;
|
||||
@@ -686,6 +697,7 @@ public:
|
||||
GetBuffer()->GetStartAddress<void*>(), GetBuffer()->GetEndAddress<void*>(),
|
||||
GetBuffer()->GetStartAddress<void*>(), GetBuffer()->GetEndAddress<void*>());
|
||||
recompiler::advance(GetBuffer()->GetSizeInBytes());
|
||||
JITWriteProtect(true);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -21,7 +21,6 @@
|
||||
|
||||
#if HOST_CPU == CPU_X64 && FEAT_AREC != DYNAREC_NONE
|
||||
|
||||
#define XBYAK_NO_OP_NAMES
|
||||
#include <xbyak/xbyak.h>
|
||||
#include <xbyak/xbyak_util.h>
|
||||
using namespace Xbyak::util;
|
||||
|
||||
@@ -1218,4 +1218,26 @@ void gdrom_reg_Reset(bool hard)
|
||||
memcpy(GD_HardwareInfo.system_version, "Rev 6.43", sizeof(GD_HardwareInfo.system_version));
|
||||
memcpy(GD_HardwareInfo.system_date, "990408", sizeof(GD_HardwareInfo.system_date));
|
||||
|
||||
gd_state = gds_waitcmd;
|
||||
sns_asc = 0;
|
||||
sns_ascq = 0;
|
||||
sns_key = 0;
|
||||
set_mode_offset = 0;
|
||||
read_params = {};
|
||||
packet_cmd = {};
|
||||
read_buff = {};
|
||||
pio_buff = {};
|
||||
ata_cmd = {};
|
||||
cdda = {};
|
||||
gd_disk_type = NoDisk;
|
||||
|
||||
data_write_mode = 0;
|
||||
DriveSel = 0;
|
||||
Error = {};
|
||||
IntReason = {};
|
||||
Features = {};
|
||||
SecCount = {};
|
||||
SecNumber = {};
|
||||
GDStatus = {};
|
||||
ByteCount = {};
|
||||
}
|
||||
@@ -129,7 +129,7 @@ struct read_params_t
|
||||
u32 start_sector;
|
||||
u32 remaining_sectors;
|
||||
u32 sector_type;
|
||||
} ;
|
||||
};
|
||||
|
||||
struct packet_cmd_t
|
||||
{
|
||||
@@ -162,7 +162,7 @@ struct packet_cmd_t
|
||||
};
|
||||
}GDReadBlock;
|
||||
};
|
||||
} ;
|
||||
};
|
||||
|
||||
//Buffer for sector reads [dma]
|
||||
struct read_buff_t
|
||||
@@ -170,7 +170,7 @@ struct read_buff_t
|
||||
u32 cache_index;
|
||||
u32 cache_size;
|
||||
u8 cache[2352 * 32];
|
||||
} ;
|
||||
};
|
||||
|
||||
//pio buffer
|
||||
struct pio_buff_t
|
||||
@@ -179,12 +179,12 @@ struct pio_buff_t
|
||||
u32 index;
|
||||
u32 size;
|
||||
u16 data[0x10000>>1]; //64 kb
|
||||
} ;
|
||||
};
|
||||
|
||||
struct ata_cmd_t
|
||||
{
|
||||
u8 command;
|
||||
} ;
|
||||
};
|
||||
|
||||
struct cdda_t
|
||||
{
|
||||
@@ -200,7 +200,7 @@ struct cdda_t
|
||||
u8 B2; // LSB
|
||||
};
|
||||
}CurrAddr,EndAddr,StartAddr;
|
||||
} ;
|
||||
};
|
||||
extern cdda_t cdda;
|
||||
|
||||
union ByteCount_t
|
||||
@@ -212,7 +212,7 @@ union ByteCount_t
|
||||
};
|
||||
|
||||
u16 full;
|
||||
} ;
|
||||
};
|
||||
|
||||
// REQ_MODE / SET_MODE
|
||||
struct GD_HardwareInfo_t
|
||||
|
||||
@@ -62,7 +62,7 @@ void MapleConfigMap::SetVibration(float power, float inclination, u32 duration_m
|
||||
|
||||
void MapleConfigMap::GetInput(PlainJoystickState* pjs)
|
||||
{
|
||||
int player_num = playerNum();
|
||||
u32 player_num = playerNum();
|
||||
|
||||
if (settings.platform.system == DC_PLATFORM_DREAMCAST)
|
||||
{
|
||||
@@ -154,7 +154,7 @@ void MapleConfigMap::GetAbsCoordinates(int& x, int& y)
|
||||
|
||||
void MapleConfigMap::GetMouseInput(u8& buttons, int& x, int& y, int& wheel)
|
||||
{
|
||||
int playerNum = this->playerNum();
|
||||
u32 playerNum = this->playerNum();
|
||||
buttons = mo_buttons[playerNum] & 0xff;
|
||||
x = (int)std::round(mo_x_delta[playerNum]);
|
||||
y = (int)std::round(mo_y_delta[playerNum]);
|
||||
@@ -174,7 +174,7 @@ bool maple_atomiswave_coin_chute(int slot)
|
||||
return false;
|
||||
}
|
||||
|
||||
void mcfg_Create(MapleDeviceType type, u32 bus, u32 port, s32 player_num = -1)
|
||||
static void mcfg_Create(MapleDeviceType type, u32 bus, u32 port, s32 player_num = -1)
|
||||
{
|
||||
delete MapleDevices[bus][port];
|
||||
maple_device* dev = maple_Create(type);
|
||||
@@ -189,7 +189,7 @@ void mcfg_CreateNAOMIJamma()
|
||||
mcfg_DestroyDevices();
|
||||
mcfg_Create(MDT_NaomiJamma, 0, 5);
|
||||
if (settings.input.JammaSetup == JVS::Keyboard)
|
||||
mcfg_Create(MDT_Keyboard, 1, 5);
|
||||
mcfg_Create(MDT_Keyboard, 1, 5, 0);
|
||||
else
|
||||
{
|
||||
// Connect VMU B1
|
||||
|
||||
@@ -1011,9 +1011,9 @@ struct maple_sega_purupuru : maple_base
|
||||
}
|
||||
};
|
||||
|
||||
u8 kb_shift; // shift keys pressed (bitmask)
|
||||
u8 kb_led; // leds currently lit
|
||||
u8 kb_key[6]={0}; // normal keys pressed
|
||||
u8 kb_shift[MAPLE_PORTS]; // shift keys pressed (bitmask)
|
||||
u8 kb_led[MAPLE_PORTS]; // leds currently lit
|
||||
u8 kb_key[MAPLE_PORTS][6]; // normal keys pressed
|
||||
|
||||
struct maple_keyboard : maple_base
|
||||
{
|
||||
@@ -1074,14 +1074,12 @@ struct maple_keyboard : maple_base
|
||||
w32(MFID_6_Keyboard);
|
||||
//struct data
|
||||
//int8 shift ; shift keys pressed (bitmask) //1
|
||||
w8(kb_shift);
|
||||
w8(kb_shift[player_num]);
|
||||
//int8 led ; leds currently lit //1
|
||||
w8(kb_led);
|
||||
w8(kb_led[player_num]);
|
||||
//int8 key[6] ; normal keys pressed //6
|
||||
for (int i = 0; i < 6; i++)
|
||||
{
|
||||
w8(kb_key[i]);
|
||||
}
|
||||
w8(kb_key[player_num][i]);
|
||||
|
||||
return MDRS_DataTransfer;
|
||||
|
||||
@@ -1103,7 +1101,7 @@ struct maple_keyboard : maple_base
|
||||
// bit 1: Right button (B)
|
||||
// bit 2: Left button (A)
|
||||
// bit 3: Wheel button
|
||||
u32 mo_buttons[4] = { 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF };
|
||||
u8 mo_buttons[4] = { 0xFF, 0xFF, 0xFF, 0xFF };
|
||||
// Relative mouse coordinates [-512:511]
|
||||
f32 mo_x_delta[4];
|
||||
f32 mo_y_delta[4];
|
||||
@@ -1116,9 +1114,6 @@ s32 mo_y_abs[4];
|
||||
// previous mouse coordinates for relative motion
|
||||
s32 mo_x_prev[4] = { -1, -1, -1, -1 };
|
||||
s32 mo_y_prev[4] = { -1, -1, -1, -1 };
|
||||
// physical mouse coordinates (relative to window/screen)
|
||||
s32 mo_x_phy;
|
||||
s32 mo_y_phy;
|
||||
// last known screen/window size
|
||||
static s32 mo_width;
|
||||
static s32 mo_height;
|
||||
@@ -1175,14 +1170,13 @@ struct maple_mouse : maple_base
|
||||
config->GetMouseInput(buttons, x, y, wheel);
|
||||
|
||||
w32(MFID_9_Mouse);
|
||||
//struct data
|
||||
//int8 buttons ; buttons (RLDUSABC, where A is left btn, B is right, and S is middle/scrollwheel)
|
||||
// buttons (RLDUSABC, where A is left btn, B is right, and S is middle/scrollwheel)
|
||||
w8(buttons);
|
||||
//int8 options
|
||||
// options
|
||||
w8(0);
|
||||
//int8 axes overflow
|
||||
// axes overflow
|
||||
w8(0);
|
||||
//int8 reserved
|
||||
// reserved
|
||||
w8(0);
|
||||
//int16 axis1 ; horizontal movement (0-$3FF) (little endian)
|
||||
w16(mo_cvt(x));
|
||||
@@ -1404,11 +1398,8 @@ static void screenToNative(int& x, int& y, int width, int height)
|
||||
|
||||
void SetMousePosition(int x, int y, int width, int height, u32 mouseId)
|
||||
{
|
||||
if (mouseId == 0)
|
||||
{
|
||||
mo_x_phy = x;
|
||||
mo_y_phy = y;
|
||||
}
|
||||
if (mouseId >= MAPLE_PORTS)
|
||||
return;
|
||||
mo_width = width;
|
||||
mo_height = height;
|
||||
|
||||
@@ -1434,6 +1425,8 @@ void SetMousePosition(int x, int y, int width, int height, u32 mouseId)
|
||||
|
||||
void SetRelativeMousePosition(int xrel, int yrel, u32 mouseId)
|
||||
{
|
||||
if (mouseId >= MAPLE_PORTS)
|
||||
return;
|
||||
int width = mo_width;
|
||||
int height = mo_height;
|
||||
if (config::Rotate90)
|
||||
|
||||
@@ -116,8 +116,6 @@ enum AWAVE_KEYS
|
||||
AWAVE_TRIGGER_KEY = 1 << 12,
|
||||
};
|
||||
|
||||
struct IMapleConfigMap;
|
||||
|
||||
struct maple_device
|
||||
{
|
||||
u8 maple_port; //raw maple port
|
||||
@@ -167,16 +165,13 @@ extern u8 EEPROM[0x100];
|
||||
void load_naomi_eeprom();
|
||||
|
||||
// Mouse position and buttons
|
||||
extern u32 mo_buttons[4];
|
||||
extern u8 mo_buttons[4];
|
||||
extern s32 mo_x_abs[4];
|
||||
extern s32 mo_y_abs[4];
|
||||
extern f32 mo_x_delta[4];
|
||||
extern f32 mo_y_delta[4];
|
||||
extern f32 mo_wheel_delta[4];
|
||||
|
||||
extern s32 mo_x_phy;
|
||||
extern s32 mo_y_phy;
|
||||
|
||||
extern s32 mo_x_prev[4];
|
||||
extern s32 mo_y_prev[4];
|
||||
|
||||
|
||||
@@ -30,4 +30,3 @@ enum
|
||||
AW_MPR_FILE_OFFSETH_addr = 0x18,
|
||||
AW_PIO_DATA_addr = 0x80,
|
||||
};
|
||||
|
||||
@@ -243,9 +243,9 @@ void AWCartridge::WriteMem(u32 address, u32 data, u32 size)
|
||||
|
||||
/*
|
||||
We are using 8 bits keys with the following subfields' structure:
|
||||
bits 0-3 is a index of 16-bits XOR (only 11 was used in known games)
|
||||
bits 4-5 is a index to the sboxes table
|
||||
bits 6-7 is a index to the permutation table
|
||||
bits 0-3 is an index of 16-bits XOR (only 11 was used in known games)
|
||||
bits 4-5 is an index to the sboxes table
|
||||
bits 6-7 is an index to the permutation table
|
||||
|
||||
These subfields could be differing from the "real" ones in the following ways:
|
||||
- Current keys equal to decrypted game code binary 8-bit sum (of each byte's swapped 4-bit nibbles)
|
||||
|
||||
@@ -35,7 +35,6 @@ public:
|
||||
void closeNetwork();
|
||||
|
||||
private:
|
||||
void initNetwork();
|
||||
void connectNetwork();
|
||||
void receiveNetwork();
|
||||
void sendNetwork();
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
#include "cheats.h"
|
||||
#include "hw/mem/_vmem.h"
|
||||
#include "hw/pvr/pvr_mem.h"
|
||||
#include "oslib/oslib.h"
|
||||
#include "rend/TexCache.h"
|
||||
#include "cfg/option.h"
|
||||
|
||||
@@ -248,6 +247,7 @@ Renderer* rend_GL4();
|
||||
Renderer* rend_norend();
|
||||
Renderer* rend_Vulkan();
|
||||
Renderer* rend_OITVulkan();
|
||||
Renderer* rend_DirectX9();
|
||||
|
||||
static void rend_create_renderer()
|
||||
{
|
||||
@@ -273,6 +273,11 @@ static void rend_create_renderer()
|
||||
case RenderType::Vulkan_OIT:
|
||||
renderer = rend_OITVulkan();
|
||||
break;
|
||||
#endif
|
||||
#ifdef _WIN32
|
||||
case RenderType::DirectX9:
|
||||
renderer = rend_DirectX9();
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
@@ -416,10 +421,10 @@ void rend_set_fb_write_addr(u32 fb_w_sof1)
|
||||
fb_w_cur = fb_w_sof1;
|
||||
}
|
||||
|
||||
void rend_swap_frame(u32 fb_r_sof1)
|
||||
void rend_swap_frame(u32 fb_r_sof)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(swap_mutex);
|
||||
if (fb_r_sof1 == fb_w_cur)
|
||||
if (fb_r_sof == fb_w_cur)
|
||||
{
|
||||
do_swap = true;
|
||||
rs.Set();
|
||||
|
||||
@@ -38,7 +38,7 @@ struct Renderer
|
||||
|
||||
virtual void DrawOSD(bool clear_screen) { }
|
||||
|
||||
virtual u64 GetTexture(TSP tsp, TCW tcw) { return 0; }
|
||||
virtual BaseTextureCacheData *GetTexture(TSP tsp, TCW tcw) { return nullptr; }
|
||||
};
|
||||
|
||||
extern Renderer* renderer;
|
||||
|
||||
@@ -87,12 +87,9 @@ void pvr_WriteReg(u32 paddr,u32 data)
|
||||
return;
|
||||
|
||||
case FB_R_SOF1_addr:
|
||||
data &= 0x00fffffc;
|
||||
rend_swap_frame(data);
|
||||
break;
|
||||
|
||||
case FB_R_SOF2_addr:
|
||||
data &= 0x00fffffc;
|
||||
rend_swap_frame(data);
|
||||
break;
|
||||
|
||||
case FB_W_SOF1_addr:
|
||||
|
||||
+1
-1
@@ -12,7 +12,7 @@ void ta_vtx_SoftReset();
|
||||
void DYNACALL ta_vtx_data32(const SQBuffer *data);
|
||||
void ta_vtx_data(const SQBuffer *data, u32 size);
|
||||
|
||||
bool ta_parse_vdrc(TA_context* ctx);
|
||||
bool ta_parse_vdrc(TA_context *ctx, bool bgraColors = false);
|
||||
|
||||
class TaTypeLut
|
||||
{
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
#include "ta_ctx.h"
|
||||
#include "spg.h"
|
||||
#include "oslib/oslib.h"
|
||||
#include "cfg/option.h"
|
||||
|
||||
extern u32 fskip;
|
||||
|
||||
+10
-2
@@ -13,6 +13,8 @@ void* OS_aligned_malloc(size_t align, size_t size);
|
||||
// helper for 32 byte aligned memory de-allocation
|
||||
void OS_aligned_free(void *ptr);
|
||||
|
||||
class BaseTextureCacheData;
|
||||
|
||||
//Vertex storage types
|
||||
struct Vertex
|
||||
{
|
||||
@@ -35,7 +37,10 @@ struct PolyParam
|
||||
u32 first; //entry index , holds vertex/pos data
|
||||
u32 count;
|
||||
|
||||
u64 texid;
|
||||
BaseTextureCacheData *texture;
|
||||
#if !defined(HOST_64BIT_CPU)
|
||||
u32 _pad0;
|
||||
#endif
|
||||
|
||||
TSP tsp;
|
||||
TCW tcw;
|
||||
@@ -46,7 +51,10 @@ struct PolyParam
|
||||
//float zMin,zMax;
|
||||
TSP tsp1;
|
||||
TCW tcw1;
|
||||
u64 texid1;
|
||||
BaseTextureCacheData *texture1;
|
||||
#if !defined(HOST_64BIT_CPU)
|
||||
u32 _pad1;
|
||||
#endif
|
||||
};
|
||||
|
||||
struct ModifierVolumeParam
|
||||
|
||||
@@ -110,7 +110,7 @@ union TSP
|
||||
u32 SrcInstr : 3;
|
||||
};
|
||||
u32 full;
|
||||
} ;
|
||||
};
|
||||
|
||||
|
||||
//// END TSP Instruction Word
|
||||
@@ -128,12 +128,12 @@ union TCW
|
||||
u32 PixelFmt : 3;
|
||||
u32 VQ_Comp : 1;
|
||||
u32 MipMapped : 1;
|
||||
} ;
|
||||
};
|
||||
struct
|
||||
{
|
||||
u32 pading_0 :21;
|
||||
u32 PalSelect : 6;
|
||||
} ;
|
||||
};
|
||||
u32 full;
|
||||
};
|
||||
|
||||
|
||||
+65
-59
@@ -86,8 +86,7 @@ static f32 f16(u16 v)
|
||||
|
||||
#define vdrc vd_rc
|
||||
|
||||
//Splitter function (normally ta_dma_main , modified for split dma's)
|
||||
|
||||
template<int Red = 0, int Green = 1, int Blue = 2, int Alpha = 3>
|
||||
class FifoSplitter
|
||||
{
|
||||
static const u32 *ta_type_lut;
|
||||
@@ -706,23 +705,23 @@ private:
|
||||
d_pp->pcw = pp->pcw;
|
||||
d_pp->tileclip = tileclip_val;
|
||||
|
||||
d_pp->texid = -1;
|
||||
|
||||
if (d_pp->pcw.Texture)
|
||||
d_pp->texid = renderer->GetTexture(d_pp->tsp,d_pp->tcw);
|
||||
d_pp->texture = renderer->GetTexture(d_pp->tsp, d_pp->tcw);
|
||||
else
|
||||
d_pp->texture = nullptr;
|
||||
|
||||
d_pp->tsp1.full = -1;
|
||||
d_pp->tcw1.full = -1;
|
||||
d_pp->texid1 = -1;
|
||||
d_pp->texture1 = nullptr;
|
||||
}
|
||||
|
||||
#define glob_param_bdc(pp) glob_param_bdc_( (TA_PolyParam0*)pp)
|
||||
|
||||
#define poly_float_color_(to,a,r,g,b) \
|
||||
to[0] = float_to_satu8(r); \
|
||||
to[1] = float_to_satu8(g); \
|
||||
to[2] = float_to_satu8(b); \
|
||||
to[3] = float_to_satu8(a);
|
||||
to[Red] = float_to_satu8(r); \
|
||||
to[Green] = float_to_satu8(g); \
|
||||
to[Blue] = float_to_satu8(b); \
|
||||
to[Alpha] = float_to_satu8(a);
|
||||
|
||||
|
||||
#define poly_float_color(to,src) \
|
||||
@@ -778,7 +777,7 @@ private:
|
||||
CurrentPP->tsp1.full = pp->tsp1.full;
|
||||
CurrentPP->tcw1.full = pp->tcw1.full;
|
||||
if (pp->pcw.Texture)
|
||||
CurrentPP->texid1 = renderer->GetTexture(pp->tsp1, pp->tcw1);
|
||||
CurrentPP->texture1 = renderer->GetTexture(pp->tsp1, pp->tcw1);
|
||||
}
|
||||
|
||||
// Intensity, with Two Volumes
|
||||
@@ -792,7 +791,7 @@ private:
|
||||
CurrentPP->tsp1.full = pp->tsp1.full;
|
||||
CurrentPP->tcw1.full = pp->tcw1.full;
|
||||
if (pp->pcw.Texture)
|
||||
CurrentPP->texid1 = renderer->GetTexture(pp->tsp1, pp->tcw1);
|
||||
CurrentPP->texture1 = renderer->GetTexture(pp->tsp1, pp->tcw1);
|
||||
}
|
||||
|
||||
__forceinline
|
||||
@@ -869,17 +868,17 @@ private:
|
||||
#define vert_packed_color_(to,src) \
|
||||
{ \
|
||||
u32 t=src; \
|
||||
to[2] = (u8)(t);t>>=8;\
|
||||
to[1] = (u8)(t);t>>=8;\
|
||||
to[0] = (u8)(t);t>>=8;\
|
||||
to[3] = (u8)(t); \
|
||||
to[Blue] = (u8)(t);t>>=8;\
|
||||
to[Green] = (u8)(t);t>>=8;\
|
||||
to[Red] = (u8)(t);t>>=8;\
|
||||
to[Alpha] = (u8)(t); \
|
||||
}
|
||||
|
||||
#define vert_float_color_(to,a,r,g,b) \
|
||||
to[0] = float_to_satu8(r); \
|
||||
to[1] = float_to_satu8(g); \
|
||||
to[2] = float_to_satu8(b); \
|
||||
to[3] = float_to_satu8(a);
|
||||
to[Red] = float_to_satu8(r); \
|
||||
to[Green] = float_to_satu8(g); \
|
||||
to[Blue] = float_to_satu8(b); \
|
||||
to[Alpha] = float_to_satu8(a);
|
||||
|
||||
//Macros to make thins easier ;)
|
||||
#define vert_packed_color(to,src) \
|
||||
@@ -895,34 +894,32 @@ private:
|
||||
//Intensity is clamped before the mul, as well as on face color to work the same as the hardware. [Fixes red dog]
|
||||
|
||||
#define vert_face_base_color(baseint) \
|
||||
{ u32 satint=float_to_satu8(vtx->baseint); \
|
||||
cv->col[0] = FaceBaseColor[0]*satint/256; \
|
||||
cv->col[1] = FaceBaseColor[1]*satint/256; \
|
||||
cv->col[2] = FaceBaseColor[2]*satint/256; \
|
||||
cv->col[3] = FaceBaseColor[3]; }
|
||||
{ u32 satint = float_to_satu8(vtx->baseint); \
|
||||
cv->col[Red] = FaceBaseColor[Red] * satint / 256; \
|
||||
cv->col[Green] = FaceBaseColor[Green] * satint / 256; \
|
||||
cv->col[Blue] = FaceBaseColor[Blue] * satint / 256; \
|
||||
cv->col[Alpha] = FaceBaseColor[Alpha]; }
|
||||
|
||||
#define vert_face_offs_color(offsint) \
|
||||
{ u32 satint=float_to_satu8(vtx->offsint); \
|
||||
cv->spc[0] = FaceOffsColor[0]*satint/256; \
|
||||
cv->spc[1] = FaceOffsColor[1]*satint/256; \
|
||||
cv->spc[2] = FaceOffsColor[2]*satint/256; \
|
||||
cv->spc[3] = FaceOffsColor[3]; }
|
||||
{ u32 satint = float_to_satu8(vtx->offsint); \
|
||||
cv->spc[Red] = FaceOffsColor[Red] * satint / 256; \
|
||||
cv->spc[Green] = FaceOffsColor[Green] * satint / 256; \
|
||||
cv->spc[Blue] = FaceOffsColor[Blue] * satint / 256; \
|
||||
cv->spc[Alpha] = FaceOffsColor[Alpha]; }
|
||||
|
||||
#define vert_face_base_color1(baseint) \
|
||||
{ u32 satint=float_to_satu8(vtx->baseint); \
|
||||
cv->col1[0] = FaceBaseColor1[0]*satint/256; \
|
||||
cv->col1[1] = FaceBaseColor1[1]*satint/256; \
|
||||
cv->col1[2] = FaceBaseColor1[2]*satint/256; \
|
||||
cv->col1[3] = FaceBaseColor1[3]; }
|
||||
{ u32 satint = float_to_satu8(vtx->baseint); \
|
||||
cv->col1[Red] = FaceBaseColor1[Red] * satint / 256; \
|
||||
cv->col1[Green] = FaceBaseColor1[Green] * satint / 256; \
|
||||
cv->col1[Blue] = FaceBaseColor1[Blue] * satint / 256; \
|
||||
cv->col1[Alpha] = FaceBaseColor1[Alpha]; }
|
||||
|
||||
#define vert_face_offs_color1(offsint) \
|
||||
{ u32 satint=float_to_satu8(vtx->offsint); \
|
||||
cv->spc1[0] = FaceOffsColor1[0]*satint/256; \
|
||||
cv->spc1[1] = FaceOffsColor1[1]*satint/256; \
|
||||
cv->spc1[2] = FaceOffsColor1[2]*satint/256; \
|
||||
cv->spc1[3] = FaceOffsColor1[3]; }
|
||||
|
||||
//vert_float_color_(cv->spc,FaceOffsColor[3],FaceOffsColor[0]*satint/256,FaceOffsColor[1]*satint/256,FaceOffsColor[2]*satint/256); }
|
||||
{ u32 satint = float_to_satu8(vtx->offsint); \
|
||||
cv->spc1[Red] = FaceOffsColor1[Red] * satint / 256; \
|
||||
cv->spc1[Green] = FaceOffsColor1[Green] * satint / 256; \
|
||||
cv->spc1[Blue] = FaceOffsColor1[Blue] * satint / 256; \
|
||||
cv->spc1[Alpha] = FaceOffsColor1[Alpha]; }
|
||||
|
||||
|
||||
//(Non-Textured, Packed Color)
|
||||
@@ -1170,14 +1167,14 @@ private:
|
||||
d_pp->pcw=spr->pcw;
|
||||
d_pp->tileclip=tileclip_val;
|
||||
|
||||
d_pp->texid = -1;
|
||||
|
||||
if (d_pp->pcw.Texture) {
|
||||
d_pp->texid = renderer->GetTexture(d_pp->tsp,d_pp->tcw);
|
||||
}
|
||||
if (d_pp->pcw.Texture)
|
||||
d_pp->texture = renderer->GetTexture(d_pp->tsp, d_pp->tcw);
|
||||
else
|
||||
d_pp->texture = nullptr;
|
||||
|
||||
d_pp->tcw1.full = -1;
|
||||
d_pp->tsp1.full = -1;
|
||||
d_pp->texid1 = -1;
|
||||
d_pp->texture1 = nullptr;
|
||||
|
||||
SFaceBaseColor=spr->BaseCol;
|
||||
SFaceOffsColor=spr->OffsCol;
|
||||
@@ -1374,7 +1371,8 @@ private:
|
||||
}
|
||||
};
|
||||
|
||||
const u32 *FifoSplitter::ta_type_lut;
|
||||
template<int Red, int Green, int Blue, int Alpha>
|
||||
const u32 *FifoSplitter<Red, Green, Blue, Alpha>::ta_type_lut;
|
||||
|
||||
TaTypeLut::TaTypeLut()
|
||||
{
|
||||
@@ -1382,8 +1380,8 @@ TaTypeLut::TaTypeLut()
|
||||
{
|
||||
PCW pcw;
|
||||
pcw.obj_ctrl = i;
|
||||
u32 rv = FifoSplitter::poly_data_type_id(pcw);
|
||||
u32 type = FifoSplitter::poly_header_type_size(pcw);
|
||||
u32 rv = FifoSplitter<>::poly_data_type_id(pcw);
|
||||
u32 type = FifoSplitter<>::poly_header_type_size(pcw);
|
||||
|
||||
if (type & 0x80)
|
||||
rv |= SZ64 << 30;
|
||||
@@ -1399,7 +1397,8 @@ TaTypeLut::TaTypeLut()
|
||||
static bool ClearZBeforePass(int pass_number);
|
||||
static void getRegionTileClipping(u32& xmin, u32& xmax, u32& ymin, u32& ymax);
|
||||
|
||||
FifoSplitter TAFifo0;
|
||||
FifoSplitter<> TAParser;
|
||||
FifoSplitter<2, 1, 0, 3> TAParserDX;
|
||||
|
||||
//
|
||||
// Check if a vertex has huge x,y,z values or negative z
|
||||
@@ -1540,7 +1539,7 @@ static void fix_texture_bleeding(const List<PolyParam> *list)
|
||||
}
|
||||
}
|
||||
|
||||
bool ta_parse_vdrc(TA_context* ctx)
|
||||
bool ta_parse_vdrc(TA_context* ctx, bool bgraColors)
|
||||
{
|
||||
ctx->rend_inuse.lock();
|
||||
bool rv=false;
|
||||
@@ -1548,7 +1547,10 @@ bool ta_parse_vdrc(TA_context* ctx)
|
||||
vd_ctx = ctx;
|
||||
vd_rc = vd_ctx->rend;
|
||||
|
||||
TAFifo0.vdec_init();
|
||||
if (bgraColors)
|
||||
TAParserDX.vdec_init();
|
||||
else
|
||||
TAParser.vdec_init();
|
||||
|
||||
bool empty_context = true;
|
||||
int op_poly_count = 0;
|
||||
@@ -1558,7 +1560,7 @@ bool ta_parse_vdrc(TA_context* ctx)
|
||||
PolyParam *bgpp = vd_rc.global_param_op.head();
|
||||
if (bgpp->pcw.Texture)
|
||||
{
|
||||
bgpp->texid = renderer->GetTexture(bgpp->tsp, bgpp->tcw);
|
||||
bgpp->texture = renderer->GetTexture(bgpp->tsp, bgpp->tcw);
|
||||
empty_context = false;
|
||||
}
|
||||
|
||||
@@ -1636,7 +1638,8 @@ bool ta_parse_vdrc(TA_context* ctx)
|
||||
|
||||
//decode a vertex in the native pvr format
|
||||
//used for bg poly
|
||||
static void decode_pvr_vertex(u32 base,u32 ptr,Vertex* cv)
|
||||
template<int Red, int Green, int Blue, int Alpha>
|
||||
void decode_pvr_vertex(u32 base, u32 ptr, Vertex* cv)
|
||||
{
|
||||
//ISP
|
||||
//TSP
|
||||
@@ -1749,14 +1752,14 @@ void FillBGP(TA_context* ctx)
|
||||
u32 vertex_ptr=strip_vert_num*strip_vs+strip_base +3*4;
|
||||
//now , all the info is ready :p
|
||||
|
||||
bgpp->texid = -1;
|
||||
bgpp->texture = nullptr;
|
||||
|
||||
bgpp->isp.full = pvr_read32p<u32>(strip_base);
|
||||
bgpp->tsp.full = pvr_read32p<u32>(strip_base + 4);
|
||||
bgpp->tcw.full = pvr_read32p<u32>(strip_base + 8);
|
||||
bgpp->tcw1.full = -1;
|
||||
bgpp->tsp1.full = -1;
|
||||
bgpp->texid1 = -1;
|
||||
bgpp->texture1 = nullptr;
|
||||
bgpp->count=4;
|
||||
bgpp->first=0;
|
||||
bgpp->tileclip=0;//disabled ! HA ~
|
||||
@@ -1773,7 +1776,10 @@ void FillBGP(TA_context* ctx)
|
||||
float scale_x= (SCALER_CTL.hscale) ? 2.f:1.f; //if AA hack the hacked pos value hacks
|
||||
for (int i=0;i<3;i++)
|
||||
{
|
||||
decode_pvr_vertex(strip_base,vertex_ptr,&cv[i]);
|
||||
if (config::RendererType.isDirectX())
|
||||
decode_pvr_vertex<2, 1, 0, 3>(strip_base,vertex_ptr,&cv[i]);
|
||||
else
|
||||
decode_pvr_vertex<0, 1, 2, 3>(strip_base,vertex_ptr,&cv[i]);
|
||||
vertex_ptr+=strip_vs;
|
||||
}
|
||||
|
||||
|
||||
@@ -423,7 +423,6 @@ static void recSh4_Init()
|
||||
// Ensure the pointer returned is non-null
|
||||
verify(CodeCache != NULL);
|
||||
|
||||
memset(CodeCache, 0xFF, CODE_SIZE + TEMP_CODE_SIZE);
|
||||
TempCodeCache = CodeCache + CODE_SIZE;
|
||||
ngen_init();
|
||||
bm_ResetCache();
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
#include "types.h"
|
||||
#include <cmath>
|
||||
#include <cfloat>
|
||||
|
||||
#include "sh4_opcodes.h"
|
||||
#include "../sh4_core.h"
|
||||
|
||||
@@ -13,8 +13,6 @@
|
||||
#include "hw/sh4/sh4_cache.h"
|
||||
#include "debug/gdb_server.h"
|
||||
|
||||
#include "hw/sh4/sh4_opcode.h"
|
||||
|
||||
#define GetN(str) ((str>>8) & 0xf)
|
||||
#define GetM(str) ((str>>4) & 0xf)
|
||||
#define GetImm4(str) ((str>>0) & 0xf)
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
#include "types.h"
|
||||
|
||||
void DMAC_Ch2St();
|
||||
|
||||
#define DMAOR_MASK 0xFFFF8201
|
||||
@@ -1,11 +1,9 @@
|
||||
#pragma once
|
||||
#include "types.h"
|
||||
|
||||
void bsc_init();
|
||||
void bsc_reset(bool hard);
|
||||
void bsc_term();
|
||||
|
||||
|
||||
void cpg_init();
|
||||
void cpg_reset();
|
||||
void cpg_term();
|
||||
|
||||
@@ -407,5 +407,3 @@ static bool wince_resolve_address(u32 va, TLB_Entry &entry)
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -16,10 +16,6 @@
|
||||
#include "oslib/oslib.h"
|
||||
#include "debug/gdb_server.h"
|
||||
|
||||
/*
|
||||
|
||||
*/
|
||||
|
||||
//these are fixed
|
||||
const u16 IRLPriority = 0x0246;
|
||||
#define IRLP9 &IRLPriority,0
|
||||
|
||||
@@ -1,50 +0,0 @@
|
||||
#pragma once
|
||||
#include "types.h"
|
||||
#include "sh4_if.h"
|
||||
|
||||
enum OpcodeAccessFlags
|
||||
{
|
||||
//Explicit registers
|
||||
OAF_RN,
|
||||
OAF_RM,
|
||||
OAF_FN,
|
||||
OAF_FM,
|
||||
|
||||
//Implicit registers
|
||||
OAF_SR_T,
|
||||
OAF_SR_S,
|
||||
OAF_FPSCR,
|
||||
OAF_PC,
|
||||
|
||||
//Other storage
|
||||
OAF_MEM,
|
||||
OAF_SQWB,
|
||||
};
|
||||
|
||||
struct sh4_opcode
|
||||
{
|
||||
u16 raw;
|
||||
|
||||
u32 n() { return (raw>>0)&0xF; }
|
||||
u32 m() { return (raw>>0)&0xF; }
|
||||
u32 u8() { return (raw>>0)&0xF; }
|
||||
u32 s8() { return (::s8)u8(); }
|
||||
u32 u12() { return (raw>>0)&0xF; }
|
||||
u32 s12() { return (s16)(u12()<<2)>>2; }
|
||||
|
||||
u32 dn() { return (raw>>0)&0xF; }
|
||||
u32 dm() { return (raw>>0)&0xF; }
|
||||
|
||||
bool is_valid();
|
||||
|
||||
bool is_branch();
|
||||
bool has_delayslot();
|
||||
|
||||
bool reads(Sh4RegType reg);
|
||||
bool writes(Sh4RegType reg);
|
||||
|
||||
bool defines(Sh4RegType reg) { return !reads(reg) && writes(reg); }
|
||||
|
||||
OpcodeAccessFlags read_flags();
|
||||
OpcodeAccessFlags write_flags();
|
||||
};
|
||||
@@ -1,10 +1,7 @@
|
||||
|
||||
#include "types.h"
|
||||
#include "sh4_interrupts.h"
|
||||
#include "sh4_core.h"
|
||||
#include "sh4_sched.h"
|
||||
#include "oslib/oslib.h"
|
||||
|
||||
|
||||
//sh4 scheduler
|
||||
|
||||
|
||||
@@ -204,8 +204,8 @@ struct Disc
|
||||
}
|
||||
virtual ~Disc()
|
||||
{
|
||||
for (size_t i=0;i<tracks.size();i++)
|
||||
tracks[i].Destroy();
|
||||
for (auto& track : tracks)
|
||||
track.Destroy();
|
||||
};
|
||||
|
||||
void FillGDSession()
|
||||
|
||||
@@ -22,9 +22,12 @@
|
||||
#include "oslib/oslib.h"
|
||||
#include "rend/gui.h"
|
||||
#include "emulator.h"
|
||||
#include "hw/maple/maple_devs.h"
|
||||
#include "stdclass.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <climits>
|
||||
#include <fstream>
|
||||
|
||||
#define MAPLE_PORT_CFG_PREFIX "maple_"
|
||||
|
||||
@@ -320,8 +323,82 @@ std::string GamepadDevice::make_mapping_filename(bool instance)
|
||||
return mapping_file;
|
||||
}
|
||||
|
||||
void GamepadDevice::verify_or_create_system_mappings()
|
||||
{
|
||||
std::string dc_name = make_mapping_filename(false, 0);
|
||||
std::string arcade_name = make_mapping_filename(false, 2);
|
||||
|
||||
std::string dc_path = get_readonly_config_path(std::string("mappings/") + dc_name);
|
||||
std::string arcade_path = get_readonly_config_path(std::string("mappings/") + arcade_name);
|
||||
|
||||
if (!file_exists(arcade_path))
|
||||
{
|
||||
save_mapping(2);
|
||||
input_mapper->ClearMappings();
|
||||
}
|
||||
if (!file_exists(dc_path))
|
||||
{
|
||||
save_mapping(0);
|
||||
input_mapper->ClearMappings();
|
||||
}
|
||||
|
||||
find_mapping(DC_PLATFORM_DREAMCAST);
|
||||
}
|
||||
|
||||
void GamepadDevice::load_system_mappings(int system)
|
||||
{
|
||||
for (int i = 0; i < GetGamepadCount(); i++)
|
||||
{
|
||||
std::shared_ptr<GamepadDevice> gamepad = GetGamepad(i);
|
||||
gamepad->find_mapping(system);
|
||||
}
|
||||
}
|
||||
|
||||
std::string GamepadDevice::make_mapping_filename(bool instance, int system)
|
||||
{
|
||||
std::string mapping_file = api_name() + "_" + name();
|
||||
if (instance)
|
||||
mapping_file += "-" + _unique_id;
|
||||
if (system != 0)
|
||||
mapping_file += "_arcade";
|
||||
std::replace(mapping_file.begin(), mapping_file.end(), '/', '-');
|
||||
std::replace(mapping_file.begin(), mapping_file.end(), '\\', '-');
|
||||
std::replace(mapping_file.begin(), mapping_file.end(), ':', '-');
|
||||
std::replace(mapping_file.begin(), mapping_file.end(), '?', '-');
|
||||
std::replace(mapping_file.begin(), mapping_file.end(), '*', '-');
|
||||
std::replace(mapping_file.begin(), mapping_file.end(), '|', '-');
|
||||
std::replace(mapping_file.begin(), mapping_file.end(), '"', '-');
|
||||
std::replace(mapping_file.begin(), mapping_file.end(), '<', '-');
|
||||
std::replace(mapping_file.begin(), mapping_file.end(), '>', '-');
|
||||
mapping_file += ".cfg";
|
||||
|
||||
return mapping_file;
|
||||
}
|
||||
|
||||
bool GamepadDevice::find_mapping(int system)
|
||||
{
|
||||
if (!_remappable)
|
||||
return true;
|
||||
std::string mapping_file;
|
||||
mapping_file = make_mapping_filename(false, system);
|
||||
|
||||
// fall back on default flycast mapping filename if system profile not found
|
||||
std::string system_mapping_path = get_readonly_config_path(std::string("mappings/") + mapping_file);
|
||||
if (!file_exists(system_mapping_path))
|
||||
mapping_file = make_mapping_filename(false);
|
||||
|
||||
std::shared_ptr<InputMapping> mapper = InputMapping::LoadMapping(mapping_file.c_str());
|
||||
|
||||
if (!mapper)
|
||||
return false;
|
||||
input_mapper = mapper;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GamepadDevice::find_mapping(const char *custom_mapping /* = nullptr */)
|
||||
{
|
||||
if (!_remappable)
|
||||
return true;
|
||||
std::string mapping_file;
|
||||
if (custom_mapping != nullptr)
|
||||
mapping_file = custom_mapping;
|
||||
@@ -365,6 +442,15 @@ void GamepadDevice::save_mapping()
|
||||
InputMapping::SaveMapping(filename.c_str(), input_mapper);
|
||||
}
|
||||
|
||||
void GamepadDevice::save_mapping(int system)
|
||||
{
|
||||
if (!input_mapper)
|
||||
return;
|
||||
std::string filename = make_mapping_filename(false, system);
|
||||
input_mapper->set_dirty();
|
||||
InputMapping::SaveMapping(filename.c_str(), input_mapper);
|
||||
}
|
||||
|
||||
void UpdateVibration(u32 port, float power, float inclination, u32 duration_ms)
|
||||
{
|
||||
int i = GamepadDevice::GetGamepadCount() - 1;
|
||||
@@ -446,6 +532,54 @@ void GamepadDevice::SaveMaplePorts()
|
||||
}
|
||||
}
|
||||
|
||||
void Mouse::setAbsPos(int x, int y, int width, int height) {
|
||||
SetMousePosition(x, y, width, height, maple_port());
|
||||
}
|
||||
|
||||
void Mouse::setRelPos(int deltax, int deltay) {
|
||||
SetRelativeMousePosition(deltax, deltay, maple_port());
|
||||
}
|
||||
|
||||
void Mouse::setWheel(int delta) {
|
||||
if (maple_port() >= 0 && maple_port() < ARRAY_SIZE(mo_wheel_delta))
|
||||
mo_wheel_delta[maple_port()] += delta;
|
||||
}
|
||||
|
||||
void Mouse::setButton(Button button, bool pressed)
|
||||
{
|
||||
if (maple_port() >= 0 && maple_port() < ARRAY_SIZE(mo_buttons))
|
||||
{
|
||||
if (pressed)
|
||||
mo_buttons[maple_port()] &= ~(1 << (int)button);
|
||||
else
|
||||
mo_buttons[maple_port()] |= 1 << (int)button;
|
||||
}
|
||||
if (gui_is_open() && !is_detecting_input())
|
||||
// Don't register mouse clicks as gamepad presses when gui is open
|
||||
// This makes the gamepad presses to be handled first and the mouse position to be ignored
|
||||
return;
|
||||
gamepad_btn_input(button, pressed);
|
||||
}
|
||||
|
||||
|
||||
void SystemMouse::setAbsPos(int x, int y, int width, int height) {
|
||||
gui_set_mouse_position(x, y);
|
||||
Mouse::setAbsPos(x, y, width, height);
|
||||
}
|
||||
|
||||
void SystemMouse::setButton(Button button, bool pressed) {
|
||||
int uiBtn = (int)button - 1;
|
||||
if (uiBtn < 2)
|
||||
uiBtn ^= 1;
|
||||
gui_set_mouse_button(uiBtn, pressed);
|
||||
Mouse::setButton(button, pressed);
|
||||
}
|
||||
|
||||
void SystemMouse::setWheel(int delta) {
|
||||
gui_set_mouse_wheel(delta * 35);
|
||||
Mouse::setWheel(delta);
|
||||
}
|
||||
|
||||
#ifdef TEST_AUTOMATION
|
||||
#include "cfg/option.h"
|
||||
static bool replay_inited;
|
||||
|
||||
@@ -33,7 +33,7 @@ public:
|
||||
|
||||
const std::string& api_name() { return _api_name; }
|
||||
const std::string& name() { return _name; }
|
||||
int maple_port() { return _maple_port; }
|
||||
int maple_port() const { return _maple_port; }
|
||||
void set_maple_port(int port) { _maple_port = port; }
|
||||
const std::string& unique_id() { return _unique_id; }
|
||||
virtual bool gamepad_btn_input(u32 code, bool pressed);
|
||||
@@ -48,6 +48,10 @@ public:
|
||||
}
|
||||
std::shared_ptr<InputMapping> get_input_mapping() { return input_mapper; }
|
||||
void save_mapping();
|
||||
void save_mapping(int system);
|
||||
|
||||
void verify_or_create_system_mappings();
|
||||
|
||||
virtual const char *get_button_name(u32 code) { return nullptr; }
|
||||
virtual const char *get_axis_name(u32 code) { return nullptr; }
|
||||
bool remappable() { return _remappable && input_mapper; }
|
||||
@@ -55,7 +59,7 @@ public:
|
||||
|
||||
virtual void rumble(float power, float inclination, u32 duration_ms) {}
|
||||
virtual void update_rumble() {}
|
||||
bool is_rumble_enabled() { return _rumble_enabled; }
|
||||
bool is_rumble_enabled() const { return _rumble_enabled; }
|
||||
|
||||
static void Register(const std::shared_ptr<GamepadDevice>& gamepad);
|
||||
|
||||
@@ -65,12 +69,22 @@ public:
|
||||
static std::shared_ptr<GamepadDevice> GetGamepad(int index);
|
||||
static void SaveMaplePorts();
|
||||
|
||||
static void load_system_mappings(int system = settings.platform.system);
|
||||
bool find_mapping(int system);
|
||||
protected:
|
||||
GamepadDevice(int maple_port, const char *api_name, bool remappable = true)
|
||||
: _api_name(api_name), _maple_port(maple_port), _input_detected(nullptr), _remappable(remappable)
|
||||
{
|
||||
}
|
||||
|
||||
bool find_mapping(const char *custom_mapping = nullptr);
|
||||
void loadMapping() {
|
||||
if (!find_mapping())
|
||||
input_mapper = getDefaultMapping();
|
||||
}
|
||||
virtual std::shared_ptr<InputMapping> getDefaultMapping() {
|
||||
return std::make_shared<IdentityInputMapping>();
|
||||
}
|
||||
|
||||
virtual void load_axis_min_max(u32 axis) {}
|
||||
bool is_detecting_input() { return _input_detected != nullptr; }
|
||||
@@ -86,6 +100,7 @@ private:
|
||||
int get_axis_min_value(u32 axis);
|
||||
unsigned int get_axis_range(u32 axis);
|
||||
std::string make_mapping_filename(bool instance = false);
|
||||
std::string make_mapping_filename(bool instance, int system);
|
||||
|
||||
std::string _api_name;
|
||||
int _maple_port;
|
||||
@@ -108,3 +123,73 @@ extern s8 joyx[4], joyy[4];
|
||||
extern s8 joyrx[4], joyry[4];
|
||||
|
||||
void UpdateVibration(u32 port, float power, float inclination, u32 duration_ms);
|
||||
|
||||
class MouseInputMapping : public InputMapping
|
||||
{
|
||||
public:
|
||||
MouseInputMapping()
|
||||
{
|
||||
name = "Mouse";
|
||||
set_button(DC_BTN_A, 2); // Left
|
||||
set_button(DC_BTN_B, 1); // Right
|
||||
set_button(DC_BTN_START, 3); // Middle
|
||||
|
||||
dirty = false;
|
||||
}
|
||||
};
|
||||
|
||||
class Mouse : public GamepadDevice
|
||||
{
|
||||
protected:
|
||||
Mouse(const char *apiName, int maplePort = 0) : GamepadDevice(maplePort, apiName) {
|
||||
this->_name = "Mouse";
|
||||
}
|
||||
|
||||
virtual std::shared_ptr<InputMapping> getDefaultMapping() override {
|
||||
return std::make_shared<MouseInputMapping>();
|
||||
}
|
||||
|
||||
public:
|
||||
enum Button {
|
||||
LEFT_BUTTON = 2,
|
||||
RIGHT_BUTTON = 1,
|
||||
MIDDLE_BUTTON = 3,
|
||||
BUTTON_4 = 4,
|
||||
BUTTON_5 = 5
|
||||
};
|
||||
|
||||
virtual const char *get_button_name(u32 code) override
|
||||
{
|
||||
switch((Button)code)
|
||||
{
|
||||
case LEFT_BUTTON:
|
||||
return "Left Button";
|
||||
case RIGHT_BUTTON:
|
||||
return "Right Button";
|
||||
case MIDDLE_BUTTON:
|
||||
return "Middle Button";
|
||||
case BUTTON_4:
|
||||
return "Button 4";
|
||||
case BUTTON_5:
|
||||
return "Button 5";
|
||||
default:
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void setAbsPos(int x, int y, int width, int height);
|
||||
void setRelPos(int deltax, int deltay);
|
||||
void setButton(Button button, bool pressed);
|
||||
void setWheel(int delta);
|
||||
};
|
||||
|
||||
class SystemMouse : public Mouse
|
||||
{
|
||||
protected:
|
||||
SystemMouse(const char *apiName, int maplePort = 0) : Mouse(apiName, maplePort) {}
|
||||
|
||||
public:
|
||||
void setAbsPos(int x, int y, int width, int height);
|
||||
void setButton(Button button, bool pressed);
|
||||
void setWheel(int delta);
|
||||
};
|
||||
@@ -1,3 +0,0 @@
|
||||
#include "keyboard_device.h"
|
||||
|
||||
KeyboardDevice *KeyboardDevice::_instance;
|
||||
+404
-82
@@ -1,45 +1,360 @@
|
||||
/*
|
||||
Copyright 2019 flyinghead
|
||||
Copyright 2021 flyinghead
|
||||
|
||||
This file is part of reicast.
|
||||
This file is part of Flycast.
|
||||
|
||||
reicast is free software: you can redistribute it and/or modify
|
||||
Flycast is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
reicast is distributed in the hope that it will be useful,
|
||||
Flycast is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with reicast. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
along with Flycast. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#pragma once
|
||||
#include "types.h"
|
||||
|
||||
#include "gamepad_device.h"
|
||||
#include "rend/gui.h"
|
||||
#include <memory>
|
||||
|
||||
class KeyboardDevice
|
||||
class KeyboardInputMapping : public InputMapping
|
||||
{
|
||||
public:
|
||||
virtual const char* name() = 0;
|
||||
int maple_port() { return _maple_port; }
|
||||
void keyboard_character(char c);
|
||||
std::string get_character_input();
|
||||
virtual ~KeyboardDevice() = default;
|
||||
KeyboardInputMapping()
|
||||
{
|
||||
name = "Keyboard";
|
||||
set_button(DC_BTN_A, 27); // X
|
||||
set_button(DC_BTN_B, 6); // C
|
||||
set_button(DC_BTN_X, 22); // S
|
||||
set_button(DC_BTN_Y, 7); // D
|
||||
set_button(DC_DPAD_UP, 82);
|
||||
set_button(DC_DPAD_DOWN, 81);
|
||||
set_button(DC_DPAD_LEFT, 80);
|
||||
set_button(DC_DPAD_RIGHT, 79);
|
||||
set_button(DC_BTN_START, 40); // Return
|
||||
set_button(EMU_BTN_TRIGGER_LEFT, 9); // F
|
||||
set_button(EMU_BTN_TRIGGER_RIGHT, 25); // V
|
||||
set_button(EMU_BTN_MENU, 43); // TAB
|
||||
set_button(EMU_BTN_FFORWARD, 44); // Space
|
||||
|
||||
static KeyboardDevice *GetInstance() { return _instance; }
|
||||
dirty = false;
|
||||
}
|
||||
};
|
||||
|
||||
class KeyboardDevice : public GamepadDevice
|
||||
{
|
||||
protected:
|
||||
KeyboardDevice(int maple_port) : _maple_port(maple_port) { _instance = this; }
|
||||
KeyboardDevice(int maple_port, const char* apiName, bool remappable = true)
|
||||
: GamepadDevice(maple_port, apiName, remappable) {
|
||||
_name = "Keyboard";
|
||||
}
|
||||
|
||||
private:
|
||||
int _maple_port;
|
||||
std::string char_input;
|
||||
static KeyboardDevice *_instance;
|
||||
std::shared_ptr<InputMapping> getDefaultMapping() override {
|
||||
return std::make_shared<KeyboardInputMapping>();
|
||||
}
|
||||
|
||||
public:
|
||||
const char *get_button_name(u32 code) override
|
||||
{
|
||||
switch (code)
|
||||
{
|
||||
case 0x04:
|
||||
return "A";
|
||||
case 0x05:
|
||||
return "B";
|
||||
case 0x06:
|
||||
return "C";
|
||||
case 0x07:
|
||||
return "D";
|
||||
case 0x08:
|
||||
return "E";
|
||||
case 0x09:
|
||||
return "F";
|
||||
case 0x0A:
|
||||
return "G";
|
||||
case 0x0B:
|
||||
return "H";
|
||||
case 0x0C:
|
||||
return "I";
|
||||
case 0x0D:
|
||||
return "J";
|
||||
case 0x0E:
|
||||
return "K";
|
||||
case 0x0F:
|
||||
return "L";
|
||||
case 0x10:
|
||||
return "M";
|
||||
case 0x11:
|
||||
return "N";
|
||||
case 0x12:
|
||||
return "O";
|
||||
case 0x13:
|
||||
return "P";
|
||||
case 0x14:
|
||||
return "Q";
|
||||
case 0x15:
|
||||
return "R";
|
||||
case 0x16:
|
||||
return "S";
|
||||
case 0x17:
|
||||
return "T";
|
||||
case 0x18:
|
||||
return "U";
|
||||
case 0x19:
|
||||
return "V";
|
||||
case 0x1A:
|
||||
return "W";
|
||||
case 0x1B:
|
||||
return "X";
|
||||
case 0x1C:
|
||||
return "Y";
|
||||
case 0x1D:
|
||||
return "Z";
|
||||
|
||||
case 0x1E:
|
||||
return "1";
|
||||
case 0x1F:
|
||||
return "2";
|
||||
case 0x20:
|
||||
return "3";
|
||||
case 0x21:
|
||||
return "4";
|
||||
case 0x22:
|
||||
return "5";
|
||||
case 0x23:
|
||||
return "6";
|
||||
case 0x24:
|
||||
return "7";
|
||||
case 0x25:
|
||||
return "8";
|
||||
case 0x26:
|
||||
return "9";
|
||||
case 0x27:
|
||||
return "0";
|
||||
|
||||
case 0x28:
|
||||
return "Return";
|
||||
case 0x29:
|
||||
return "Escape";
|
||||
case 0x2A:
|
||||
return "Backspace";
|
||||
case 0x2B:
|
||||
return "Tab";
|
||||
case 0x2C:
|
||||
return "Space";
|
||||
|
||||
case 0x2D:
|
||||
return "-";
|
||||
case 0x2E:
|
||||
return "=";
|
||||
case 0x2F:
|
||||
return "[";
|
||||
case 0x30:
|
||||
return "]";
|
||||
case 0x31:
|
||||
return "\\";
|
||||
case 0x32:
|
||||
return "#"; // non-US
|
||||
case 0x33:
|
||||
return ";";
|
||||
case 0x34:
|
||||
return "'";
|
||||
case 0x35:
|
||||
return "`";
|
||||
case 0x36:
|
||||
return ",";
|
||||
case 0x37:
|
||||
return ".";
|
||||
case 0x38:
|
||||
return "/";
|
||||
case 0x39:
|
||||
return "CapsLock";
|
||||
|
||||
case 0x3A:
|
||||
return "F1";
|
||||
case 0x3B:
|
||||
return "F2";
|
||||
case 0x3C:
|
||||
return "F3";
|
||||
case 0x3D:
|
||||
return "F4";
|
||||
case 0x3E:
|
||||
return "F5";
|
||||
case 0x3F:
|
||||
return "F6";
|
||||
case 0x40:
|
||||
return "F7";
|
||||
case 0x41:
|
||||
return "F8";
|
||||
case 0x42:
|
||||
return "F9";
|
||||
case 0x43:
|
||||
return "F10";
|
||||
case 0x44:
|
||||
return "F11";
|
||||
case 0x45:
|
||||
return "F12";
|
||||
|
||||
case 0x46:
|
||||
return "PrintScreen";
|
||||
case 0x47:
|
||||
return "ScrollLock";
|
||||
case 0x48:
|
||||
return "Pause";
|
||||
case 0x49:
|
||||
return "Insert";
|
||||
case 0x4A:
|
||||
return "Home";
|
||||
case 0x4B:
|
||||
return "Page Up";
|
||||
case 0x4C:
|
||||
return "Delete";
|
||||
case 0x4D:
|
||||
return "End";
|
||||
case 0x4E:
|
||||
return "Page Down";
|
||||
case 0x4F:
|
||||
return "Right";
|
||||
case 0x50:
|
||||
return "Left";
|
||||
case 0x51:
|
||||
return "Down";
|
||||
case 0x52:
|
||||
return "Up";
|
||||
|
||||
case 0x53:
|
||||
return "NumLock";
|
||||
case 0x54:
|
||||
return "Num /";
|
||||
case 0x55:
|
||||
return "Num *";
|
||||
case 0x56:
|
||||
return "Num -";
|
||||
case 0x57:
|
||||
return "Num +";
|
||||
case 0x58:
|
||||
return "Num Enter";
|
||||
case 0x59:
|
||||
return "Num 1";
|
||||
case 0x5A:
|
||||
return "Num 2";
|
||||
case 0x5B:
|
||||
return "Num 3";
|
||||
case 0x5C:
|
||||
return "Num 4";
|
||||
case 0x5D:
|
||||
return "Num 5";
|
||||
case 0x5E:
|
||||
return "Num 6";
|
||||
case 0x5F:
|
||||
return "Num 7";
|
||||
case 0x60:
|
||||
return "Num 8";
|
||||
case 0x61:
|
||||
return "Num 9";
|
||||
case 0x62:
|
||||
return "Num 0";
|
||||
case 0x63:
|
||||
return "Num .";
|
||||
|
||||
case 0x64:
|
||||
return "\\"; // non-US
|
||||
case 0x65:
|
||||
return "Application";
|
||||
case 0x66:
|
||||
return "Power";
|
||||
case 0x67:
|
||||
return "Num =";
|
||||
|
||||
case 0x68:
|
||||
return "F13";
|
||||
case 0x69:
|
||||
return "F14";
|
||||
case 0x6A:
|
||||
return "F15";
|
||||
case 0x6B:
|
||||
return "F16";
|
||||
case 0x6C:
|
||||
return "F17";
|
||||
case 0x6D:
|
||||
return "F18";
|
||||
case 0x6E:
|
||||
return "F19";
|
||||
case 0x6F:
|
||||
return "F20";
|
||||
case 0x70:
|
||||
return "F21";
|
||||
case 0x71:
|
||||
return "F22";
|
||||
case 0x72:
|
||||
return "F23";
|
||||
case 0x73:
|
||||
return "F24";
|
||||
|
||||
case 0x87:
|
||||
return "Int1";
|
||||
case 0x88:
|
||||
return "Int2";
|
||||
case 0x89:
|
||||
return "Yen";
|
||||
case 0x8A:
|
||||
return "Int4";
|
||||
case 0x8B:
|
||||
return "Int5";
|
||||
case 0x8C:
|
||||
return "Int6";
|
||||
case 0x8D:
|
||||
return "Int7";
|
||||
case 0x8E:
|
||||
return "Int8";
|
||||
case 0x8F:
|
||||
return "Int9";
|
||||
|
||||
case 0x90:
|
||||
return "Hangul";
|
||||
case 0x91:
|
||||
return "Hanja";
|
||||
case 0x92:
|
||||
return "Katakana";
|
||||
case 0x93:
|
||||
return "Hiragana";
|
||||
case 0x94:
|
||||
return "Zenkaku/Hankaku";
|
||||
case 0x95:
|
||||
return "Lang6";
|
||||
case 0x96:
|
||||
return "Lang7";
|
||||
case 0x97:
|
||||
return "Lang8";
|
||||
case 0x98:
|
||||
return "Lang9";
|
||||
|
||||
case 0xE0:
|
||||
return "Left Ctrl";
|
||||
case 0xE1:
|
||||
return "Left Shift";
|
||||
case 0xE2:
|
||||
return "Left Alt";
|
||||
case 0xE3:
|
||||
return "Left Meta";
|
||||
case 0xE4:
|
||||
return "Right Ctrl";
|
||||
case 0xE5:
|
||||
return "Right Shift";
|
||||
case 0xE6:
|
||||
return "Right Alt";
|
||||
case 0xE7:
|
||||
return "Right Meta";
|
||||
|
||||
default:
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Keycode>
|
||||
@@ -47,9 +362,11 @@ class KeyboardDeviceTemplate : public KeyboardDevice
|
||||
{
|
||||
public:
|
||||
virtual void keyboard_input(Keycode keycode, bool pressed, int modifier_keys = 0);
|
||||
virtual ~KeyboardDeviceTemplate() = default;
|
||||
|
||||
protected:
|
||||
KeyboardDeviceTemplate(int maple_port) : KeyboardDevice(maple_port), _modifier_keys(0), _kb_used(0) {}
|
||||
KeyboardDeviceTemplate(int maple_port, const char *apiName, bool remappable = true)
|
||||
: KeyboardDevice(maple_port, apiName, remappable), _modifier_keys(0), _kb_used(0) {}
|
||||
virtual u8 convert_keycode(Keycode keycode) = 0;
|
||||
|
||||
private:
|
||||
@@ -68,8 +385,8 @@ enum DCKeyboardModifiers {
|
||||
DC_KBMOD_S2 = 0x80,
|
||||
};
|
||||
|
||||
extern u8 kb_key[6]; // normal keys pressed
|
||||
extern u8 kb_shift; // modifier keys pressed (bitmask)
|
||||
extern u8 kb_key[4][6]; // normal keys pressed
|
||||
extern u8 kb_shift[4]; // modifier keys pressed (bitmask)
|
||||
|
||||
static inline void setFlag(int& v, u32 bitmask, bool set)
|
||||
{
|
||||
@@ -82,74 +399,79 @@ static inline void setFlag(int& v, u32 bitmask, bool set)
|
||||
template <typename Keycode>
|
||||
void KeyboardDeviceTemplate<Keycode>::keyboard_input(Keycode keycode, bool pressed, int modifier_keys)
|
||||
{
|
||||
const int port = maple_port();
|
||||
if (port < 0 || port > (int)ARRAY_SIZE(kb_key))
|
||||
return;
|
||||
|
||||
u8 dc_keycode = convert_keycode(keycode);
|
||||
// Some OSes (Mac OS) don't distinguish left and right modifier keys to we set them both.
|
||||
// But not for Alt since Right Alt is used as a special modifier keys on some international
|
||||
// keyboards.
|
||||
switch (dc_keycode)
|
||||
if (port < (int)ARRAY_SIZE(kb_key))
|
||||
{
|
||||
case 0xE1: // Left Shift
|
||||
case 0xE5: // Right Shift
|
||||
setFlag(_modifier_keys, DC_KBMOD_LEFTSHIFT | DC_KBMOD_RIGHTSHIFT, pressed);
|
||||
break;
|
||||
case 0xE0: // Left Ctrl
|
||||
case 0xE4: // Right Ctrl
|
||||
setFlag(_modifier_keys, DC_KBMOD_LEFTCTRL | DC_KBMOD_RIGHTCTRL, pressed);
|
||||
break;
|
||||
case 0xE2: // Left Alt
|
||||
setFlag(_modifier_keys, DC_KBMOD_LEFTALT, pressed);
|
||||
break;
|
||||
case 0xE6: // Right Alt
|
||||
setFlag(_modifier_keys, DC_KBMOD_RIGHTALT, pressed);
|
||||
break;
|
||||
case 0xE7: // S2 special key
|
||||
setFlag(_modifier_keys, DC_KBMOD_S2, pressed);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
kb_shift = _modifier_keys;
|
||||
|
||||
if (dc_keycode != 0 && dc_keycode < 0xE0)
|
||||
{
|
||||
if (pressed)
|
||||
// Some OSes (Mac OS) don't distinguish left and right modifier keys to we set them both.
|
||||
// But not for Alt since Right Alt is used as a special modifier keys on some international
|
||||
// keyboards.
|
||||
switch (dc_keycode)
|
||||
{
|
||||
if (_kb_used < ARRAY_SIZE(kb_key))
|
||||
{
|
||||
bool found = false;
|
||||
for (u32 i = 0; !found && i < _kb_used; i++)
|
||||
{
|
||||
if (kb_key[i] == dc_keycode)
|
||||
found = true;
|
||||
}
|
||||
if (!found)
|
||||
kb_key[_kb_used++] = dc_keycode;
|
||||
}
|
||||
case 0xE1: // Left Shift
|
||||
case 0xE5: // Right Shift
|
||||
setFlag(_modifier_keys, DC_KBMOD_LEFTSHIFT | DC_KBMOD_RIGHTSHIFT, pressed);
|
||||
break;
|
||||
case 0xE0: // Left Ctrl
|
||||
case 0xE4: // Right Ctrl
|
||||
setFlag(_modifier_keys, DC_KBMOD_LEFTCTRL | DC_KBMOD_RIGHTCTRL, pressed);
|
||||
break;
|
||||
case 0xE2: // Left Alt
|
||||
setFlag(_modifier_keys, DC_KBMOD_LEFTALT, pressed);
|
||||
break;
|
||||
case 0xE6: // Right Alt
|
||||
setFlag(_modifier_keys, DC_KBMOD_RIGHTALT, pressed);
|
||||
break;
|
||||
case 0xE7: // S2 special key
|
||||
setFlag(_modifier_keys, DC_KBMOD_S2, pressed);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
else
|
||||
kb_shift[port] = _modifier_keys;
|
||||
|
||||
if (dc_keycode != 0 && dc_keycode < 0xE0)
|
||||
{
|
||||
for (u32 i = 0; i < _kb_used; i++)
|
||||
if (pressed)
|
||||
{
|
||||
if (kb_key[i] == dc_keycode)
|
||||
if (_kb_used < ARRAY_SIZE(kb_key[port]))
|
||||
{
|
||||
_kb_used--;
|
||||
for (u32 j = i; j < ARRAY_SIZE(kb_key) - 1; j++)
|
||||
kb_key[j] = kb_key[j + 1];
|
||||
kb_key[ARRAY_SIZE(kb_key) - 1] = 0;
|
||||
break;
|
||||
bool found = false;
|
||||
for (u32 i = 0; !found && i < _kb_used; i++)
|
||||
{
|
||||
if (kb_key[port][i] == dc_keycode)
|
||||
found = true;
|
||||
}
|
||||
if (!found)
|
||||
kb_key[port][_kb_used++] = dc_keycode;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (u32 i = 0; i < _kb_used; i++)
|
||||
{
|
||||
if (kb_key[port][i] == dc_keycode)
|
||||
{
|
||||
_kb_used--;
|
||||
for (u32 j = i; j < ARRAY_SIZE(kb_key[port]) - 1; j++)
|
||||
kb_key[port][j] = kb_key[port][j + 1];
|
||||
kb_key[port][ARRAY_SIZE(kb_key[port]) - 1] = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
kb_shift[port] |= modifier_keys;
|
||||
}
|
||||
kb_shift |= modifier_keys;
|
||||
}
|
||||
}
|
||||
|
||||
inline void KeyboardDevice::keyboard_character(char c) {
|
||||
char_input.push_back(c);
|
||||
}
|
||||
|
||||
inline std::string KeyboardDevice::get_character_input() {
|
||||
std::string input = char_input;
|
||||
char_input.clear();
|
||||
return input;
|
||||
// Do not map keyboard keys to gamepad buttons unless the GUI is open
|
||||
// or the corresponding maple device (if any) isn't a keyboard
|
||||
if (gui_is_open()
|
||||
|| port == (int)ARRAY_SIZE(kb_key)
|
||||
|| (settings.platform.system == DC_PLATFORM_DREAMCAST && config::MapleMainDevices[port] != MDT_Keyboard)
|
||||
|| (settings.platform.system == DC_PLATFORM_NAOMI && settings.input.JammaSetup != JVS::Keyboard)
|
||||
|| settings.platform.system == DC_PLATFORM_ATOMISWAVE)
|
||||
gamepad_btn_input(dc_keycode, pressed);
|
||||
}
|
||||
@@ -97,6 +97,21 @@ axis_list[] =
|
||||
|
||||
std::map<std::string, std::shared_ptr<InputMapping>> InputMapping::loaded_mappings;
|
||||
|
||||
void InputMapping::clear_button(u32 port, DreamcastKey id, u32 code)
|
||||
{
|
||||
if (id != EMU_BTN_NONE)
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
u32 code = get_button_code(port, id);
|
||||
if (code == (u32)-1)
|
||||
break;
|
||||
buttons[port][code] = EMU_BTN_NONE;
|
||||
}
|
||||
dirty = true;
|
||||
}
|
||||
}
|
||||
|
||||
void InputMapping::set_button(u32 port, DreamcastKey id, u32 code)
|
||||
{
|
||||
if (id != EMU_BTN_NONE)
|
||||
@@ -113,6 +128,21 @@ void InputMapping::set_button(u32 port, DreamcastKey id, u32 code)
|
||||
}
|
||||
}
|
||||
|
||||
void InputMapping::clear_axis(u32 port, DreamcastKey id, u32 code)
|
||||
{
|
||||
if (id != EMU_AXIS_NONE)
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
u32 code = get_axis_code(port, id);
|
||||
if (code == (u32)-1)
|
||||
break;
|
||||
axes[port][code] = EMU_AXIS_NONE;
|
||||
}
|
||||
dirty = true;
|
||||
}
|
||||
}
|
||||
|
||||
void InputMapping::set_axis(u32 port, DreamcastKey id, u32 code, bool is_inverted)
|
||||
{
|
||||
if (id != EMU_AXIS_NONE)
|
||||
@@ -142,6 +172,7 @@ void InputMapping::load(FILE* fp)
|
||||
int dz = mf.get_int("emulator", "dead_zone", 10);
|
||||
dz = std::min(dz, 100);
|
||||
dz = std::max(dz, 0);
|
||||
version = mf.get_int("emulator", "version", 1);
|
||||
|
||||
this->dead_zone = (float)dz / 100.f;
|
||||
|
||||
@@ -200,6 +231,11 @@ u32 InputMapping::get_axis_code(u32 port, DreamcastKey key)
|
||||
return -1;
|
||||
}
|
||||
|
||||
void InputMapping::ClearMappings()
|
||||
{
|
||||
loaded_mappings.clear();
|
||||
}
|
||||
|
||||
std::shared_ptr<InputMapping> InputMapping::LoadMapping(const char *name)
|
||||
{
|
||||
auto it = loaded_mappings.find(name);
|
||||
@@ -218,6 +254,11 @@ std::shared_ptr<InputMapping> InputMapping::LoadMapping(const char *name)
|
||||
return mapping;
|
||||
}
|
||||
|
||||
void InputMapping::set_dirty()
|
||||
{
|
||||
dirty = true;
|
||||
}
|
||||
|
||||
bool InputMapping::save(const char *name)
|
||||
{
|
||||
if (!dirty)
|
||||
@@ -236,6 +277,7 @@ bool InputMapping::save(const char *name)
|
||||
|
||||
mf.set("emulator", "mapping_name", this->name);
|
||||
mf.set_int("emulator", "dead_zone", (int)std::round(this->dead_zone * 100.f));
|
||||
mf.set_int("emulator", "version", version);
|
||||
|
||||
for (int port = 0; port < 4; port++)
|
||||
{
|
||||
|
||||
@@ -41,6 +41,7 @@ public:
|
||||
|
||||
std::string name;
|
||||
float dead_zone = 0.1f;
|
||||
int version = 2;
|
||||
|
||||
DreamcastKey get_button_id(u32 port, u32 code)
|
||||
{
|
||||
@@ -50,6 +51,7 @@ public:
|
||||
else
|
||||
return EMU_BTN_NONE;
|
||||
}
|
||||
void clear_button(u32 port, DreamcastKey id, u32 code);
|
||||
void set_button(u32 port, DreamcastKey id, u32 code);
|
||||
void set_button(DreamcastKey id, u32 code) { set_button(0, id, code); }
|
||||
u32 get_button_code(u32 port, DreamcastKey key);
|
||||
@@ -71,17 +73,21 @@ public:
|
||||
return false;
|
||||
}
|
||||
u32 get_axis_code(u32 port, DreamcastKey key);
|
||||
void clear_axis(u32 port, DreamcastKey id, u32 code);
|
||||
void set_axis(u32 port, DreamcastKey id, u32 code, bool inverted);
|
||||
void set_axis(DreamcastKey id, u32 code, bool inverted) { set_axis(0, id, code, inverted); }
|
||||
|
||||
void load(FILE* fp);
|
||||
bool save(const char *name);
|
||||
|
||||
bool is_dirty() { return dirty; }
|
||||
void set_dirty();
|
||||
bool is_dirty() const { return dirty; }
|
||||
|
||||
static std::shared_ptr<InputMapping> LoadMapping(const char *name);
|
||||
static void SaveMapping(const char *name, const std::shared_ptr<InputMapping>& mapping);
|
||||
|
||||
void ClearMappings();
|
||||
|
||||
protected:
|
||||
bool dirty = false;
|
||||
|
||||
|
||||
@@ -212,4 +212,3 @@ bool input_evdev_handle()
|
||||
}
|
||||
|
||||
#endif // USE_EVDEV
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
#pragma once
|
||||
#include "types.h"
|
||||
|
||||
extern void input_evdev_init();
|
||||
extern void input_evdev_close();
|
||||
|
||||
@@ -83,27 +83,31 @@ public:
|
||||
input_mapper = std::make_shared<InputMapping>(*input_mapper);
|
||||
}
|
||||
else
|
||||
input_mapper = std::make_shared<DefaultEvdevInputMapping>();
|
||||
input_mapper = getDefaultMapping();
|
||||
input_mapper->name = _name + " mapping";
|
||||
save_mapping();
|
||||
}
|
||||
else
|
||||
INFO_LOG(INPUT, "using custom mapping '%s'", input_mapper->name.c_str());
|
||||
}
|
||||
virtual ~EvdevGamepadDevice() override
|
||||
~EvdevGamepadDevice() override
|
||||
{
|
||||
INFO_LOG(INPUT, "evdev: Device '%s' on port %d disconnected", _name.c_str(), maple_port());
|
||||
close(_fd);
|
||||
}
|
||||
|
||||
virtual void rumble(float power, float inclination, u32 duration_ms) override
|
||||
std::shared_ptr<InputMapping> getDefaultMapping() override {
|
||||
return std::make_shared<DefaultEvdevInputMapping>();
|
||||
}
|
||||
|
||||
void rumble(float power, float inclination, u32 duration_ms) override
|
||||
{
|
||||
vib_inclination = inclination * power;
|
||||
vib_stop_time = os_GetSeconds() + duration_ms / 1000.0;
|
||||
|
||||
do_rumble(power, duration_ms);
|
||||
}
|
||||
virtual void update_rumble() override
|
||||
void update_rumble() override
|
||||
{
|
||||
if (vib_inclination > 0)
|
||||
{
|
||||
@@ -115,7 +119,7 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
virtual const char *get_button_name(u32 code) override
|
||||
const char *get_button_name(u32 code) override
|
||||
{
|
||||
switch (code)
|
||||
{
|
||||
@@ -161,7 +165,7 @@ public:
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
virtual const char *get_axis_name(u32 code) override
|
||||
const char *get_axis_name(u32 code) override
|
||||
{
|
||||
switch (code)
|
||||
{
|
||||
@@ -222,7 +226,7 @@ public:
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual void load_axis_min_max(u32 axis) override
|
||||
void load_axis_min_max(u32 axis) override
|
||||
{
|
||||
struct input_absinfo abs;
|
||||
if (ioctl(_fd, EVIOCGABS(axis), &abs))
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
#pragma once
|
||||
|
||||
// We use long because X11 wants 32-bit pixels for 32-bit systems and 64 for 64...
|
||||
// ARGB
|
||||
static unsigned long reicast_icon[] =
|
||||
static unsigned long window_icon[] =
|
||||
{
|
||||
48, 48,
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "types.h"
|
||||
|
||||
#pragma once
|
||||
#define JOYSTICK_DEVICE_STRING "/dev/input/js%d"
|
||||
#define JOYSTICK_DEFAULT_DEVICE_ID -1
|
||||
#define JOYSTICK_MAP_SIZE 32
|
||||
|
||||
@@ -368,7 +368,7 @@ int main(int argc, char* argv[])
|
||||
common_linux_setup();
|
||||
|
||||
if (reicast_init(argc, argv))
|
||||
die("Reicast initialization failed\n");
|
||||
die("Flycast initialization failed\n");
|
||||
|
||||
mainui_loop();
|
||||
|
||||
@@ -394,6 +394,3 @@ void os_DebugBreak()
|
||||
{
|
||||
raise(SIGTRAP);
|
||||
}
|
||||
|
||||
|
||||
|
||||
+52
-126
@@ -27,74 +27,18 @@
|
||||
static Window x11_win;
|
||||
Display *x11_disp;
|
||||
|
||||
class MouseInputMapping : public InputMapping
|
||||
class X11Mouse : public SystemMouse
|
||||
{
|
||||
public:
|
||||
MouseInputMapping()
|
||||
X11Mouse() : SystemMouse("X11")
|
||||
{
|
||||
name = "X11 Mouse";
|
||||
set_button(DC_BTN_A, Button1);
|
||||
set_button(DC_BTN_B, Button3);
|
||||
set_button(DC_BTN_START, Button2);
|
||||
|
||||
dirty = false;
|
||||
}
|
||||
};
|
||||
|
||||
class X11MouseGamepadDevice : public GamepadDevice
|
||||
{
|
||||
public:
|
||||
X11MouseGamepadDevice(int maple_port) : GamepadDevice(maple_port, "X11")
|
||||
{
|
||||
_name = "Mouse";
|
||||
_unique_id = "x11_mouse";
|
||||
if (!find_mapping())
|
||||
input_mapper = std::make_shared<MouseInputMapping>();
|
||||
}
|
||||
|
||||
bool gamepad_btn_input(u32 code, bool pressed) override
|
||||
{
|
||||
if (gui_is_open() && !is_detecting_input())
|
||||
// Don't register mouse clicks as gamepad presses when gui is open
|
||||
// This makes the gamepad presses to be handled first and the mouse position to be ignored
|
||||
// TODO Make this generic
|
||||
return false;
|
||||
else
|
||||
return GamepadDevice::gamepad_btn_input(code, pressed);
|
||||
}
|
||||
|
||||
virtual const char *get_button_name(u32 code) override
|
||||
{
|
||||
switch (code)
|
||||
{
|
||||
case Button1:
|
||||
return "Left Button";
|
||||
case Button2:
|
||||
return "Middle Button";
|
||||
case Button3:
|
||||
return "Right Button";
|
||||
case Button4:
|
||||
return "Scroll Up";
|
||||
case Button5:
|
||||
return "Scroll Down";
|
||||
case 6:
|
||||
return "Scroll Left";
|
||||
case 7:
|
||||
return "Scroll Right";
|
||||
case 8:
|
||||
return "Button 4";
|
||||
case 9:
|
||||
return "Button 5";
|
||||
default:
|
||||
return nullptr;
|
||||
}
|
||||
loadMapping();
|
||||
}
|
||||
};
|
||||
|
||||
static int x11_keyboard_input = 0;
|
||||
static std::shared_ptr<X11KeyboardDevice> x11_keyboard;
|
||||
static std::shared_ptr<X11KbGamepadDevice> kb_gamepad;
|
||||
static std::shared_ptr<X11MouseGamepadDevice> mouse_gamepad;
|
||||
static std::shared_ptr<X11Keyboard> x11Keyboard;
|
||||
static std::shared_ptr<X11Mouse> x11Mouse;
|
||||
|
||||
int x11_width;
|
||||
int x11_height;
|
||||
@@ -217,7 +161,14 @@ void input_x11_handle()
|
||||
KeySym keysym_return;
|
||||
int len = XLookupString(&e.xkey, buf, 1, &keysym_return, NULL);
|
||||
if (len > 0)
|
||||
x11_keyboard->keyboard_character(buf[0]);
|
||||
{
|
||||
// Cheap ISO Latin-1 to UTF-8 conversion
|
||||
u16 b = (u8)buf[0];
|
||||
if (b < 0x80)
|
||||
gui_keyboard_input(b);
|
||||
else
|
||||
gui_keyboard_input((u16)((0xc2 + (b > 0xbf)) | ((b & 0x3f) + 0x80) << 8));
|
||||
}
|
||||
}
|
||||
/* no break */
|
||||
case KeyRelease:
|
||||
@@ -232,10 +183,7 @@ void input_x11_handle()
|
||||
// Key wasn’t actually released: auto repeat
|
||||
continue;
|
||||
}
|
||||
// Dreamcast keyboard emulation
|
||||
x11_keyboard->keyboard_input(e.xkey.keycode, e.type == KeyPress);
|
||||
// keyboard-based emulated gamepad
|
||||
kb_gamepad->gamepad_btn_input(e.xkey.keycode, e.type == KeyPress);
|
||||
x11Keyboard->keyboard_input(e.xkey.keycode, e.type == KeyPress);
|
||||
|
||||
// Start/stop mouse capture with Left Ctrl + Left Alt
|
||||
if (e.type == KeyPress
|
||||
@@ -249,72 +197,55 @@ void input_x11_handle()
|
||||
x11_uncapture_mouse();
|
||||
}
|
||||
// TODO Move this to bindable keys or in the gui menu
|
||||
if (x11_keyboard_input)
|
||||
#if 0
|
||||
if (e.xkey.keycode == KEY_F10)
|
||||
{
|
||||
if (e.xkey.keycode == KEY_F10)
|
||||
{
|
||||
// Dump the next frame into a file
|
||||
dump_frame_switch = e.type == KeyPress;
|
||||
}
|
||||
else if (e.type == KeyPress && e.xkey.keycode == KEY_F11)
|
||||
{
|
||||
x11_fullscreen = !x11_fullscreen;
|
||||
x11_window_set_fullscreen(x11_fullscreen);
|
||||
}
|
||||
// Dump the next frame into a file
|
||||
dump_frame_switch = e.type == KeyPress;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
if (e.type == KeyPress && e.xkey.keycode == KEY_F11)
|
||||
{
|
||||
x11_fullscreen = !x11_fullscreen;
|
||||
x11_window_set_fullscreen(x11_fullscreen);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case FocusOut:
|
||||
{
|
||||
if (capturing_mouse)
|
||||
x11_uncapture_mouse();
|
||||
capturing_mouse = false;
|
||||
}
|
||||
if (capturing_mouse)
|
||||
x11_uncapture_mouse();
|
||||
capturing_mouse = false;
|
||||
break;
|
||||
|
||||
case ButtonPress:
|
||||
case ButtonRelease:
|
||||
mouse_gamepad->gamepad_btn_input(e.xbutton.button, e.type == ButtonPress);
|
||||
switch (e.xbutton.button)
|
||||
{
|
||||
u32 button_mask = 0;
|
||||
switch (e.xbutton.button)
|
||||
{
|
||||
case Button1: // Left button
|
||||
button_mask = 1 << 2;
|
||||
break;
|
||||
case Button2: // Middle button
|
||||
button_mask = 1 << 3;
|
||||
break;
|
||||
case Button3: // Right button
|
||||
button_mask = 1 << 1;
|
||||
break;
|
||||
case Button4: // Mouse wheel up
|
||||
mo_wheel_delta[0] -= 16;
|
||||
break;
|
||||
case Button5: // Mouse wheel down
|
||||
mo_wheel_delta[0] += 16;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (button_mask)
|
||||
{
|
||||
if (e.type == ButtonPress)
|
||||
mo_buttons[0] &= ~button_mask;
|
||||
else
|
||||
mo_buttons[0] |= button_mask;
|
||||
}
|
||||
case Button1: // Left button
|
||||
x11Mouse->setButton(Mouse::LEFT_BUTTON, e.type == ButtonPress);
|
||||
break;
|
||||
case Button2: // Middle button
|
||||
x11Mouse->setButton(Mouse::MIDDLE_BUTTON, e.type == ButtonPress);
|
||||
break;
|
||||
case Button3: // Right button
|
||||
x11Mouse->setButton(Mouse::RIGHT_BUTTON, e.type == ButtonPress);
|
||||
break;
|
||||
case Button4: // Mouse wheel up
|
||||
x11Mouse->setWheel(-1);
|
||||
break;
|
||||
case Button5: // Mouse wheel down
|
||||
x11Mouse->setWheel(1);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
/* no break */
|
||||
|
||||
case MotionNotify:
|
||||
// For Light gun
|
||||
SetMousePosition(e.xmotion.x, e.xmotion.y, x11_width, x11_height);
|
||||
// For mouse
|
||||
x11Mouse->setAbsPos(e.xmotion.x, e.xmotion.y, x11_width, x11_height);
|
||||
mouse_moved = true;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -335,15 +266,10 @@ void input_x11_handle()
|
||||
|
||||
void input_x11_init()
|
||||
{
|
||||
x11_keyboard = std::make_shared<X11KeyboardDevice>(0);
|
||||
kb_gamepad = std::make_shared<X11KbGamepadDevice>(0);
|
||||
GamepadDevice::Register(kb_gamepad);
|
||||
mouse_gamepad = std::make_shared<X11MouseGamepadDevice>(0);
|
||||
GamepadDevice::Register(mouse_gamepad);
|
||||
|
||||
x11_keyboard_input = (cfgLoadInt("input", "enable_x11_keyboard", 1) >= 1);
|
||||
if (!x11_keyboard_input)
|
||||
INFO_LOG(INPUT, "X11 Keyboard input disabled by config.");
|
||||
x11Keyboard = std::make_shared<X11Keyboard>(0);
|
||||
GamepadDevice::Register(x11Keyboard);
|
||||
x11Mouse = std::make_shared<X11Mouse>();
|
||||
GamepadDevice::Register(x11Mouse);
|
||||
}
|
||||
|
||||
void x11_window_create()
|
||||
@@ -425,7 +351,7 @@ void x11_window_create()
|
||||
Atom net_wm_icon = XInternAtom(x11_disp, "_NET_WM_ICON", False);
|
||||
Atom cardinal = XInternAtom(x11_disp, "CARDINAL", False);
|
||||
XChangeProperty(x11_disp, x11_win, net_wm_icon, cardinal, 32, PropModeReplace,
|
||||
(const unsigned char*)reicast_icon, sizeof(reicast_icon) / sizeof(*reicast_icon));
|
||||
(const unsigned char*)window_icon, sizeof(window_icon) / sizeof(*window_icon));
|
||||
|
||||
// Capture the close window event
|
||||
wmDeleteMessage = XInternAtom(x11_disp, "WM_DELETE_WINDOW", False);
|
||||
|
||||
+14
-254
@@ -3,10 +3,10 @@
|
||||
#include "input/keyboard_device.h"
|
||||
#include "x11.h"
|
||||
|
||||
class X11KeyboardDevice : public KeyboardDeviceTemplate<int>
|
||||
class X11Keyboard : public KeyboardDeviceTemplate<int>
|
||||
{
|
||||
public:
|
||||
X11KeyboardDevice(int maple_port) : KeyboardDeviceTemplate(maple_port)
|
||||
X11Keyboard(int maple_port) : KeyboardDeviceTemplate(maple_port, "X11")
|
||||
{
|
||||
//04-1D Letter keys A-Z (in alphabetic order)
|
||||
kb_map[KEY_A] = 0x04;
|
||||
@@ -125,275 +125,35 @@ public:
|
||||
kb_map[90] = 0x62;
|
||||
//63 "." (Numeric keypad)
|
||||
kb_map[91] = 0x63;
|
||||
//64 #| (non-US)
|
||||
//kb_map[94] = 0x64;
|
||||
//65 S3 key
|
||||
//66-A4 Not used
|
||||
//A5-DF Reserved
|
||||
kb_map[KEY_LCTRL] = 0xE0; // Left Control
|
||||
kb_map[KEY_LSHIFT] = 0xE1; // Left Shift
|
||||
//E2 Left Alt
|
||||
kb_map[KEY_LALT] = 0xE2; // Left Alt
|
||||
//E3 Left S1
|
||||
kb_map[KEY_RCTRL] = 0xE4; // Right Control
|
||||
kb_map[KEY_RSHIFT] = 0xE5; // Right Shift
|
||||
//E6 Right Alt
|
||||
// AltGr
|
||||
kb_map[108] = 0xE6; // Right Alt
|
||||
kb_map[135] = 0x65; // Menu / S3
|
||||
//E7 Right S3
|
||||
//E8-FF Reserved
|
||||
|
||||
_unique_id = "x11_keyboard";
|
||||
loadMapping();
|
||||
}
|
||||
virtual const char* name() override { return "X11 Keyboard"; }
|
||||
|
||||
protected:
|
||||
virtual u8 convert_keycode(int keycode) override
|
||||
u8 convert_keycode(int keycode) override
|
||||
{
|
||||
if (kb_map.find(keycode) == kb_map.end()) {
|
||||
DEBUG_LOG(INPUT, "Unknown key %x", keycode);
|
||||
return 0;
|
||||
}
|
||||
return kb_map[keycode];
|
||||
}
|
||||
|
||||
private:
|
||||
std::map<int, u8> kb_map;
|
||||
};
|
||||
|
||||
class KbInputMapping : public InputMapping
|
||||
{
|
||||
public:
|
||||
KbInputMapping()
|
||||
{
|
||||
name = "X11 Keyboard";
|
||||
set_button(DC_BTN_A, KEY_X);
|
||||
set_button(DC_BTN_B, KEY_C);
|
||||
set_button(DC_BTN_X, KEY_S);
|
||||
set_button(DC_BTN_Y, KEY_D);
|
||||
set_button(DC_DPAD_UP, KEY_UP);
|
||||
set_button(DC_DPAD_DOWN, KEY_DOWN);
|
||||
set_button(DC_DPAD_LEFT, KEY_LEFT);
|
||||
set_button(DC_DPAD_RIGHT, KEY_RIGHT);
|
||||
set_button(DC_BTN_START, KEY_RETURN);
|
||||
set_button(EMU_BTN_TRIGGER_LEFT, KEY_F);
|
||||
set_button(EMU_BTN_TRIGGER_RIGHT, KEY_V);
|
||||
set_button(EMU_BTN_MENU, KEY_TAB);
|
||||
set_button(EMU_BTN_FFORWARD, KEY_SPACE);
|
||||
|
||||
dirty = false;
|
||||
}
|
||||
};
|
||||
|
||||
class X11KbGamepadDevice : public GamepadDevice
|
||||
{
|
||||
public:
|
||||
X11KbGamepadDevice(int maple_port) : GamepadDevice(maple_port, "X11")
|
||||
{
|
||||
_name = "Keyboard";
|
||||
_unique_id = "x11_keyboard";
|
||||
if (!find_mapping())
|
||||
input_mapper = std::make_shared<KbInputMapping>();
|
||||
}
|
||||
|
||||
virtual const char *get_button_name(u32 code) override
|
||||
{
|
||||
switch (code)
|
||||
{
|
||||
case KEY_A:
|
||||
return "A";
|
||||
case KEY_B:
|
||||
return "B";
|
||||
case KEY_C:
|
||||
return "C";
|
||||
case KEY_D:
|
||||
return "D";
|
||||
case KEY_E:
|
||||
return "E";
|
||||
case KEY_F:
|
||||
return "F";
|
||||
case KEY_G:
|
||||
return "G";
|
||||
case KEY_H:
|
||||
return "H";
|
||||
case KEY_I:
|
||||
return "I";
|
||||
case KEY_J:
|
||||
return "J";
|
||||
case KEY_K:
|
||||
return "K";
|
||||
case KEY_L:
|
||||
return "L";
|
||||
case KEY_M:
|
||||
return "M";
|
||||
case KEY_N:
|
||||
return "N";
|
||||
case KEY_O:
|
||||
return "O";
|
||||
case KEY_P:
|
||||
return "P";
|
||||
case KEY_Q:
|
||||
return "Q";
|
||||
case KEY_R:
|
||||
return "R";
|
||||
case KEY_S:
|
||||
return "S";
|
||||
case KEY_T:
|
||||
return "T";
|
||||
case KEY_U:
|
||||
return "U";
|
||||
case KEY_V:
|
||||
return "V";
|
||||
case KEY_W:
|
||||
return "W";
|
||||
case KEY_X:
|
||||
return "X";
|
||||
case KEY_Y:
|
||||
return "Y";
|
||||
case KEY_Z:
|
||||
return "Z";
|
||||
|
||||
case KEY_0:
|
||||
return "0";
|
||||
case KEY_1:
|
||||
return "1";
|
||||
case KEY_2:
|
||||
return "2";
|
||||
case KEY_3:
|
||||
return "3";
|
||||
case KEY_4:
|
||||
return "4";
|
||||
case KEY_5:
|
||||
return "5";
|
||||
case KEY_6:
|
||||
return "6";
|
||||
case KEY_7:
|
||||
return "7";
|
||||
case KEY_8:
|
||||
return "8";
|
||||
case KEY_9:
|
||||
return "9";
|
||||
|
||||
case KEY_BACKSPACE:
|
||||
return "Backspace";
|
||||
case KEY_DEL:
|
||||
return "Delete";
|
||||
case KEY_DOWN:
|
||||
return "Down";
|
||||
case KEY_UP:
|
||||
return "Up";
|
||||
case KEY_LEFT:
|
||||
return "Left";
|
||||
case KEY_RIGHT:
|
||||
return "Right";
|
||||
case KEY_END:
|
||||
return "End";
|
||||
case KEY_ESC:
|
||||
return "Escape";
|
||||
|
||||
case KEY_F1:
|
||||
return "F1";
|
||||
case KEY_F2:
|
||||
return "F2";
|
||||
case KEY_F3:
|
||||
return "F3";
|
||||
case KEY_F4:
|
||||
return "F4";
|
||||
case KEY_F5:
|
||||
return "F5";
|
||||
case KEY_F6:
|
||||
return "F6";
|
||||
case KEY_F7:
|
||||
return "F7";
|
||||
case KEY_F8:
|
||||
return "F8";
|
||||
case KEY_F9:
|
||||
return "F9";
|
||||
case KEY_F10:
|
||||
return "F10";
|
||||
case KEY_F11:
|
||||
return "F11";
|
||||
case KEY_F12:
|
||||
return "F12";
|
||||
|
||||
case KEY_HOME:
|
||||
return "Home";
|
||||
case KEY_INS:
|
||||
return "Insert";
|
||||
case KEY_RETURN:
|
||||
return "Return";
|
||||
case KEY_LALT:
|
||||
return "Left ALT";
|
||||
case KEY_LCTRL:
|
||||
return "Left CTRL";
|
||||
case KEY_LSHIFT:
|
||||
return "Left SHIFT";
|
||||
case KEY_RCTRL:
|
||||
return "Right CTRL";
|
||||
case KEY_RSHIFT:
|
||||
return "Right Shift";
|
||||
case 108:
|
||||
return "Right ALT";
|
||||
case KEY_PGDOWN:
|
||||
return "Page Down";
|
||||
case KEY_PGUP:
|
||||
return "Page Up";
|
||||
case KEY_SPACE:
|
||||
return "Space";
|
||||
case KEY_TAB:
|
||||
return "Tab";
|
||||
|
||||
case 87:
|
||||
return "Num 1";
|
||||
case 88:
|
||||
return "Num 2";
|
||||
case 89:
|
||||
return "Num 3";
|
||||
case 83:
|
||||
return "Num 4";
|
||||
case 84:
|
||||
return "Num 5";
|
||||
case 85:
|
||||
return "Num 6";
|
||||
case 79:
|
||||
return "Num 7";
|
||||
case 80:
|
||||
return "Num 8";
|
||||
case 81:
|
||||
return "Num 9";
|
||||
case 90:
|
||||
return "Num 0";
|
||||
case 91:
|
||||
return "Num .";
|
||||
case 106:
|
||||
return "Num /";
|
||||
case 63:
|
||||
return "Num *";
|
||||
case 82:
|
||||
return "Num -";
|
||||
case 86:
|
||||
return "Num +";
|
||||
case 104:
|
||||
return "Num Enter";
|
||||
|
||||
case 20:
|
||||
return "-";
|
||||
case 21:
|
||||
return "=";
|
||||
case 34:
|
||||
return "[";
|
||||
case 35:
|
||||
return "]";
|
||||
case 47:
|
||||
return ";";
|
||||
case 48:
|
||||
return "'";
|
||||
case 49:
|
||||
return "`";
|
||||
case 51:
|
||||
return "\\";
|
||||
case 59:
|
||||
return ",";
|
||||
case 60:
|
||||
return ".";
|
||||
case 61:
|
||||
return "/";
|
||||
case 94:
|
||||
return "102nd";
|
||||
|
||||
default:
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -73,7 +73,7 @@ void fault_handler (int sn, siginfo_t * si, void *segfault_ctx)
|
||||
}
|
||||
#undef HOST_CTX_READY
|
||||
|
||||
void install_fault_handler(void)
|
||||
void install_fault_handler()
|
||||
{
|
||||
struct sigaction act, segv_oact;
|
||||
memset(&act, 0, sizeof(act));
|
||||
@@ -91,7 +91,7 @@ void install_fault_handler(void)
|
||||
}
|
||||
#else // !defined(TARGET_NO_EXCEPTIONS)
|
||||
// No exceptions/nvmem dummy handlers.
|
||||
void install_fault_handler(void) {}
|
||||
void install_fault_handler() {}
|
||||
#endif // !defined(TARGET_NO_EXCEPTIONS)
|
||||
|
||||
double os_GetSeconds()
|
||||
|
||||
@@ -167,7 +167,7 @@ VMemType vmem_platform_init(void **vmem_base_addr, void **sh4rcb_addr) {
|
||||
|
||||
// Now try to allocate a contiguous piece of memory.
|
||||
VMemType rv;
|
||||
#ifdef HOST_64BIT_CPU
|
||||
#if HOST_CPU == CPU_X64 || HOST_CPU == CPU_ARM64
|
||||
reserved_size = 0x100000000L + sizeof(Sh4RCB) + 0x10000; // 4GB + context size + 64K padding
|
||||
reserved_base = mem_region_reserve(NULL, reserved_size);
|
||||
rv = MemType4GB;
|
||||
@@ -249,11 +249,21 @@ bool vmem_platform_prepare_jit_block(void *code_area, unsigned size, void **code
|
||||
{
|
||||
// Well it failed, use another approach, unmap the memory area and remap it back.
|
||||
// Seems it works well on Darwin according to reicast code :P
|
||||
#ifndef __ARM_MAC__
|
||||
munmap(code_area, size);
|
||||
void *ret_ptr = mmap(code_area, size, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_FIXED | MAP_PRIVATE | MAP_ANON, 0, 0);
|
||||
// Ensure it's the area we requested
|
||||
if (ret_ptr != code_area)
|
||||
return false; // Couldn't remap it? Perhaps RWX is disabled? This should never happen in any supported Unix platform.
|
||||
#else
|
||||
// MAP_JIT and toggleable write protection is required on Apple Silicon
|
||||
// Cannot use MAP_FIXED with MAP_JIT
|
||||
void *ret_ptr = mmap(NULL, size, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE | MAP_ANON | MAP_JIT, -1, 0);
|
||||
if ( ret_ptr == MAP_FAILED )
|
||||
return false;
|
||||
*code_area_rwx = ret_ptr;
|
||||
return true;
|
||||
#endif
|
||||
}
|
||||
|
||||
// Pointer location should be same:
|
||||
|
||||
+23
-14
@@ -27,7 +27,6 @@
|
||||
#include "hw/arm7/arm7_rec.h"
|
||||
#include "imgread/common.h"
|
||||
#include "rend/gui.h"
|
||||
#include "profiler/profiler.h"
|
||||
#include "input/gamepad_device.h"
|
||||
#include "hw/sh4/dyna/blockmanager.h"
|
||||
#include "log/LogManager.h"
|
||||
@@ -494,6 +493,8 @@ static void dc_start_game(const char *path)
|
||||
config::Settings::instance().reset();
|
||||
dc_reset(true);
|
||||
config::Settings::instance().load(false);
|
||||
|
||||
GamepadDevice::load_system_mappings();
|
||||
|
||||
if (settings.platform.system == DC_PLATFORM_DREAMCAST)
|
||||
{
|
||||
@@ -710,26 +711,29 @@ void SaveSettings()
|
||||
|
||||
void dc_resize_renderer()
|
||||
{
|
||||
int hres;
|
||||
float hres;
|
||||
int vres = config::RenderResolution;
|
||||
if (config::Widescreen && !config::Rotate90)
|
||||
{
|
||||
if (config::SuperWidescreen)
|
||||
hres = config::RenderResolution * screen_width / screen_height ;
|
||||
hres = (float)config::RenderResolution * screen_width / screen_height ;
|
||||
else
|
||||
hres = config::RenderResolution * 16 / 9;
|
||||
hres = config::RenderResolution * 16.f / 9.f;
|
||||
|
||||
}
|
||||
else if (config::Rotate90)
|
||||
{
|
||||
vres = vres * config::ScreenStretching / 100;
|
||||
hres = config::RenderResolution * 4 / 3;
|
||||
hres = config::RenderResolution * 4.f / 3.f;
|
||||
}
|
||||
else
|
||||
{
|
||||
hres = config::RenderResolution * 4 * config::ScreenStretching / 3 / 100;
|
||||
hres = config::RenderResolution * 4.f * config::ScreenStretching / 3.f / 100.f;
|
||||
}
|
||||
if (renderer != nullptr)
|
||||
renderer->Resize(hres, vres);
|
||||
if (!config::Rotate90)
|
||||
hres = std::roundf(hres / 2.f) * 2.f;
|
||||
DEBUG_LOG(RENDERER, "dc_resize_renderer: %d x %d", (int)hres, vres);
|
||||
renderer->Resize((int)hres, vres);
|
||||
}
|
||||
|
||||
void dc_resume()
|
||||
@@ -755,7 +759,7 @@ static void cleanup_serialize(void *data)
|
||||
free(data);
|
||||
}
|
||||
|
||||
static std::string get_savestate_file_path(bool writable)
|
||||
static std::string get_savestate_file_path(int index, bool writable)
|
||||
{
|
||||
std::string state_file = settings.imgread.ImagePath;
|
||||
size_t lastindex = state_file.find_last_of('/');
|
||||
@@ -771,14 +775,19 @@ static std::string get_savestate_file_path(bool writable)
|
||||
lastindex = state_file.find_last_of('.');
|
||||
if (lastindex != std::string::npos)
|
||||
state_file = state_file.substr(0, lastindex);
|
||||
state_file = state_file + ".state";
|
||||
|
||||
char index_str[4] = "";
|
||||
if (index != 0) // When index is 0, use same name before multiple states is added
|
||||
sprintf(index_str, "_%d", index);
|
||||
|
||||
state_file = state_file + index_str + ".state";
|
||||
if (writable)
|
||||
return get_writable_data_path(state_file);
|
||||
else
|
||||
return get_readonly_data_path(state_file);
|
||||
}
|
||||
|
||||
void dc_savestate()
|
||||
void dc_savestate(int index)
|
||||
{
|
||||
unsigned int total_size = 0 ;
|
||||
void *data = NULL ;
|
||||
@@ -810,7 +819,7 @@ void dc_savestate()
|
||||
return;
|
||||
}
|
||||
|
||||
std::string filename = get_savestate_file_path(true);
|
||||
std::string filename = get_savestate_file_path(index, true);
|
||||
#if 0
|
||||
FILE *f = nowide::fopen(filename.c_str(), "wb") ;
|
||||
|
||||
@@ -849,14 +858,14 @@ void dc_savestate()
|
||||
gui_display_notification("State saved", 1000);
|
||||
}
|
||||
|
||||
void dc_loadstate()
|
||||
void dc_loadstate(int index)
|
||||
{
|
||||
u32 total_size = 0;
|
||||
FILE *f = nullptr;
|
||||
|
||||
dc_stop();
|
||||
|
||||
std::string filename = get_savestate_file_path(false);
|
||||
std::string filename = get_savestate_file_path(index, false);
|
||||
RZipFile zipFile;
|
||||
if (zipFile.Open(filename, false))
|
||||
{
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#include "audiostream.h"
|
||||
#if USE_ALSA
|
||||
#include "audiostream.h"
|
||||
#include <alsa/asoundlib.h>
|
||||
#include "cfg/cfg.h"
|
||||
|
||||
|
||||
@@ -11,10 +11,8 @@
|
||||
|
||||
It does work on my macmini though
|
||||
*/
|
||||
|
||||
#include "audiostream.h"
|
||||
|
||||
#if defined(__APPLE__)
|
||||
#include "audiostream.h"
|
||||
#include "stdclass.h"
|
||||
|
||||
#include <atomic>
|
||||
|
||||
@@ -2,15 +2,12 @@
|
||||
#include "audiostream.h"
|
||||
#include <initguid.h>
|
||||
#include <dsound.h>
|
||||
#ifdef USE_SDL
|
||||
#include "sdl/sdl.h"
|
||||
#endif
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
#include <atomic>
|
||||
#include <thread>
|
||||
#include "stdclass.h"
|
||||
|
||||
HWND getNativeHwnd();
|
||||
#define verifyc(x) verify(!FAILED(x))
|
||||
|
||||
static IDirectSound8* dsound;
|
||||
@@ -66,12 +63,8 @@ static void audioThreadMain()
|
||||
static void directsound_init()
|
||||
{
|
||||
verifyc(DirectSoundCreate8(NULL, &dsound, NULL));
|
||||
verifyc(dsound->SetCooperativeLevel(getNativeHwnd(), DSSCL_PRIORITY));
|
||||
|
||||
#ifdef USE_SDL
|
||||
verifyc(dsound->SetCooperativeLevel(sdl_get_native_hwnd(), DSSCL_PRIORITY));
|
||||
#else
|
||||
verifyc(dsound->SetCooperativeLevel((HWND)libPvr_GetRenderTarget(), DSSCL_PRIORITY));
|
||||
#endif
|
||||
// Set up WAV format structure.
|
||||
WAVEFORMATEX wfx;
|
||||
memset(&wfx, 0, sizeof(WAVEFORMATEX));
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
#include "audiostream.h"
|
||||
#ifdef USE_LIBAO
|
||||
|
||||
#include "audiostream.h"
|
||||
#include <ao/ao.h>
|
||||
|
||||
static ao_device *aodevice;
|
||||
|
||||
@@ -16,8 +16,8 @@
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Flycast. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include "audiostream.h"
|
||||
#ifdef USE_OBOE
|
||||
#include "audiostream.h"
|
||||
#include <oboe/Oboe.h>
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
#include "audiostream.h"
|
||||
#if USE_OMX
|
||||
|
||||
#include "audiostream.h"
|
||||
#include <IL/OMX_Broadcom.h>
|
||||
#include <unistd.h>
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#include "audiostream.h"
|
||||
#ifdef USE_OSS
|
||||
#include "audiostream.h"
|
||||
#include <fcntl.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/soundcard.h>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#include "audiostream.h"
|
||||
#ifdef USE_PULSEAUDIO
|
||||
#include "audiostream.h"
|
||||
|
||||
#ifdef PULSEAUDIO_SIMPLE
|
||||
#include <pulse/simple.h>
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
|
||||
#if defined(USE_SDL_AUDIO)
|
||||
|
||||
#include <SDL.h>
|
||||
|
||||
@@ -79,8 +79,8 @@ audiobackend_t* GetAudioBackend(const std::string& slug)
|
||||
|
||||
void WriteSample(s16 r, s16 l)
|
||||
{
|
||||
Buffer[writePtr].r = r;
|
||||
Buffer[writePtr].l = l;
|
||||
Buffer[writePtr].r = r * config::AudioVolume.dbPower();
|
||||
Buffer[writePtr].l = l * config::AudioVolume.dbPower();
|
||||
|
||||
if (++writePtr == SAMPLE_COUNT)
|
||||
{
|
||||
|
||||
@@ -245,11 +245,11 @@ public:
|
||||
if (dir == nullptr)
|
||||
INFO_LOG(COMMON, "Cannot read directory '%s'", root.c_str());
|
||||
|
||||
return iterator(dir, root);
|
||||
return {dir, root};
|
||||
}
|
||||
iterator end()
|
||||
{
|
||||
return iterator(nullptr, root);
|
||||
return {nullptr, root};
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
@@ -22,5 +22,3 @@ u32 static INLINE bitscanrev(u32 v)
|
||||
return rv;
|
||||
#endif
|
||||
}
|
||||
|
||||
void os_DebugBreak();
|
||||
@@ -51,10 +51,10 @@ struct Arm64RegAlloc : RegAlloc<eReg, eFReg>
|
||||
RegAlloc::DoAlloc(block, alloc_regs, alloc_fregs);
|
||||
}
|
||||
|
||||
virtual void Preload(u32 reg, eReg nreg) override;
|
||||
virtual void Writeback(u32 reg, eReg nreg) override;
|
||||
virtual void Preload_FPU(u32 reg, eFReg nreg) override;
|
||||
virtual void Writeback_FPU(u32 reg, eFReg nreg) override;
|
||||
void Preload(u32 reg, eReg nreg) override;
|
||||
void Writeback(u32 reg, eReg nreg) override;
|
||||
void Preload_FPU(u32 reg, eFReg nreg) override;
|
||||
void Writeback_FPU(u32 reg, eFReg nreg) override;
|
||||
|
||||
const Register& MapRegister(const shil_param& param)
|
||||
{
|
||||
|
||||
@@ -46,9 +46,9 @@ static void generate_mainloop();
|
||||
|
||||
struct DynaRBI : RuntimeBlockInfo
|
||||
{
|
||||
virtual u32 Relink() override;
|
||||
u32 Relink() override;
|
||||
|
||||
virtual void Relocate(void* dst) override {
|
||||
void Relocate(void* dst) override {
|
||||
verify(false);
|
||||
}
|
||||
};
|
||||
@@ -278,6 +278,7 @@ public:
|
||||
void ngen_Compile(RuntimeBlockInfo* block, bool force_checks, bool reset, bool staging, bool optimise)
|
||||
{
|
||||
//printf("REC-ARM64 compiling %08x\n", block->addr);
|
||||
JITWriteProtect(false);
|
||||
this->block = block;
|
||||
CheckBlock(force_checks, block);
|
||||
|
||||
@@ -959,6 +960,7 @@ public:
|
||||
RelinkBlock(block);
|
||||
|
||||
Finalize();
|
||||
JITWriteProtect(true);
|
||||
}
|
||||
|
||||
void ngen_CC_Start(shil_opcode* op)
|
||||
@@ -1518,11 +1520,18 @@ private:
|
||||
void GenCallRuntime(R (*function)(P...))
|
||||
{
|
||||
ptrdiff_t offset = reinterpret_cast<uintptr_t>(function) - reinterpret_cast<uintptr_t>(CC_RW2RX(GetBuffer()->GetStartAddress<void*>()));
|
||||
verify(offset >= -128 * 1024 * 1024 && offset <= 128 * 1024 * 1024);
|
||||
verify((offset & 3) == 0);
|
||||
Label function_label;
|
||||
BindToOffset(&function_label, offset);
|
||||
Bl(&function_label);
|
||||
if (offset < -128 * 1024 * 1024 || offset > 128 * 1024 * 1024)
|
||||
{
|
||||
Mov(x4, reinterpret_cast<uintptr_t>(function));
|
||||
Blr(x4);
|
||||
}
|
||||
else
|
||||
{
|
||||
Label function_label;
|
||||
BindToOffset(&function_label, offset);
|
||||
Bl(&function_label);
|
||||
}
|
||||
}
|
||||
|
||||
void GenCall(DynaCode *function)
|
||||
@@ -1539,14 +1548,34 @@ private:
|
||||
void GenBranchRuntime(R (*target)(P...), Condition cond = al)
|
||||
{
|
||||
ptrdiff_t offset = reinterpret_cast<uintptr_t>(target) - reinterpret_cast<uintptr_t>(CC_RW2RX(GetBuffer()->GetStartAddress<void*>()));
|
||||
verify(offset >= -128 * 1024 * 1024 && offset <= 128 * 1024 * 1024);
|
||||
verify((offset & 3) == 0);
|
||||
Label target_label;
|
||||
BindToOffset(&target_label, offset);
|
||||
if (cond == al)
|
||||
B(&target_label);
|
||||
if (offset < -128 * 1024 * 1024 || offset > 128 * 1024 * 1024)
|
||||
{
|
||||
if (cond == al)
|
||||
{
|
||||
Mov(x4, reinterpret_cast<uintptr_t>(target));
|
||||
Br(x4);
|
||||
}
|
||||
else
|
||||
{
|
||||
Label skip_target;
|
||||
Condition inverse_cond = (Condition)((u32)cond ^ 1);
|
||||
|
||||
B(&skip_target, inverse_cond);
|
||||
Mov(x4, reinterpret_cast<uintptr_t>(target));
|
||||
Br(x4);
|
||||
Bind(&skip_target);
|
||||
}
|
||||
}
|
||||
else
|
||||
B(&target_label, cond);
|
||||
{
|
||||
Label target_label;
|
||||
BindToOffset(&target_label, offset);
|
||||
if (cond == al)
|
||||
B(&target_label);
|
||||
else
|
||||
B(&target_label, cond);
|
||||
}
|
||||
}
|
||||
|
||||
void GenBranch(DynaCode *code, Condition cond = al)
|
||||
@@ -2116,8 +2145,8 @@ private:
|
||||
std::vector<const VRegister*> call_fregs;
|
||||
Arm64RegAlloc regalloc;
|
||||
RuntimeBlockInfo* block = NULL;
|
||||
const int read_memory_rewrite_size = 3; // ubfx, add, ldr
|
||||
const int write_memory_rewrite_size = 3; // ubfx, add, str
|
||||
const int read_memory_rewrite_size = 5; // ubfx, add, ldr
|
||||
const int write_memory_rewrite_size = 5; // ubfx, add, str
|
||||
};
|
||||
|
||||
static Arm64Assembler* compiler;
|
||||
@@ -2188,6 +2217,7 @@ static const u32 op_sizes[] = {
|
||||
};
|
||||
bool ngen_Rewrite(host_context_t &context, void *faultAddress)
|
||||
{
|
||||
JITWriteProtect(false);
|
||||
//LOGI("ngen_Rewrite pc %zx\n", context.pc);
|
||||
u32 *code_ptr = (u32 *)CC_RX2RW(context.pc);
|
||||
u32 armv8_op = *code_ptr;
|
||||
@@ -2219,6 +2249,7 @@ bool ngen_Rewrite(host_context_t &context, void *faultAddress)
|
||||
assembler->Finalize(true);
|
||||
delete assembler;
|
||||
context.pc = (unat)CC_RW2RX(code_rewrite);
|
||||
JITWriteProtect(true);
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -2227,12 +2258,14 @@ static void generate_mainloop()
|
||||
{
|
||||
if (mainloop != nullptr)
|
||||
return;
|
||||
JITWriteProtect(false);
|
||||
compiler = new Arm64Assembler();
|
||||
|
||||
compiler->GenMainloop();
|
||||
|
||||
delete compiler;
|
||||
compiler = nullptr;
|
||||
JITWriteProtect(true);
|
||||
}
|
||||
|
||||
RuntimeBlockInfo* ngen_AllocateBlock()
|
||||
@@ -2250,11 +2283,13 @@ u32 DynaRBI::Relink()
|
||||
{
|
||||
#ifndef NO_BLOCK_LINKING
|
||||
//printf("DynaRBI::Relink %08x\n", this->addr);
|
||||
JITWriteProtect(false);
|
||||
Arm64Assembler *compiler = new Arm64Assembler((u8 *)this->code + this->relink_offset);
|
||||
|
||||
u32 code_size = compiler->RelinkBlock(this);
|
||||
compiler->Finalize(true);
|
||||
delete compiler;
|
||||
JITWriteProtect(true);
|
||||
|
||||
return code_size;
|
||||
#else
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
|
||||
#include "types.h"
|
||||
|
||||
#if FEAT_SHREC == DYNAREC_CPP
|
||||
@@ -10,8 +9,6 @@
|
||||
#include "hw/sh4/dyna/ngen.h"
|
||||
#include "hw/sh4/sh4_mem.h"
|
||||
#include "hw/sh4/dyna/regalloc.h"
|
||||
#include "profiler/profiler.h"
|
||||
#include "oslib/oslib.h"
|
||||
|
||||
#define SHIL_MODE 2
|
||||
#include "hw/sh4/dyna/shil_canonical.h"
|
||||
|
||||
@@ -17,7 +17,6 @@ using namespace Xbyak::util;
|
||||
|
||||
#include "hw/sh4/sh4_core.h"
|
||||
#include "hw/sh4/sh4_mem.h"
|
||||
#include "oslib/oslib.h"
|
||||
#include "x64_regalloc.h"
|
||||
#include "xbyak_base.h"
|
||||
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
//
|
||||
// Neep Bold by Jim Knoble
|
||||
//
|
||||
|
||||
@@ -25,7 +25,6 @@
|
||||
#include "hw/aica/aica.h"
|
||||
#include "hw/aica/aica_mem.h"
|
||||
#include "hw/pvr/pvr_regs.h"
|
||||
#include "oslib/oslib.h"
|
||||
#include "imgread/common.h"
|
||||
|
||||
#include <map>
|
||||
|
||||
+1
-4
@@ -1,5 +1,4 @@
|
||||
#ifndef REIOS_H
|
||||
#define REIOS_H
|
||||
#pragma once
|
||||
|
||||
#include "types.h"
|
||||
#include "hw/flashrom/flashrom.h"
|
||||
@@ -41,5 +40,3 @@ struct ip_meta_t
|
||||
extern ip_meta_t ip_meta;
|
||||
|
||||
#define REIOS_OPCODE 0x085B
|
||||
|
||||
#endif //REIOS_H
|
||||
@@ -1,8 +1,5 @@
|
||||
#ifndef REIOS_ELF_H
|
||||
#define REIOS_ELF_H
|
||||
#pragma once
|
||||
|
||||
#include "types.h"
|
||||
#include <string>
|
||||
|
||||
bool reios_loadElf(const std::string& elf);
|
||||
|
||||
#endif //REIOS_ELF_H
|
||||
+79
-39
@@ -182,50 +182,90 @@ void CustomTexture::DumpTexture(u32 hash, int w, int h, TextureType textype, voi
|
||||
|
||||
for (int y = 0; y < h; y++)
|
||||
{
|
||||
switch (textype)
|
||||
if (!config::RendererType.isDirectX())
|
||||
{
|
||||
case TextureType::_4444:
|
||||
for (int x = 0; x < w; x++)
|
||||
switch (textype)
|
||||
{
|
||||
*dst++ = ((*src >> 12) & 0xF) << 4;
|
||||
*dst++ = ((*src >> 8) & 0xF) << 4;
|
||||
*dst++ = ((*src >> 4) & 0xF) << 4;
|
||||
*dst++ = (*src & 0xF) << 4;
|
||||
src++;
|
||||
case TextureType::_4444:
|
||||
for (int x = 0; x < w; x++)
|
||||
{
|
||||
*dst++ = (((*src >> 12) & 0xF) << 4) | ((*src >> 12) & 0xF);
|
||||
*dst++ = (((*src >> 8) & 0xF) << 4) | ((*src >> 8) & 0xF);
|
||||
*dst++ = (((*src >> 4) & 0xF) << 4) | ((*src >> 4) & 0xF);
|
||||
*dst++ = ((*src & 0xF) << 4) | (*src & 0xF);
|
||||
src++;
|
||||
}
|
||||
break;
|
||||
case TextureType::_565:
|
||||
for (int x = 0; x < w; x++)
|
||||
{
|
||||
*(u32 *)dst = Unpacker565_32<RGBAPacker>::unpack(*src);
|
||||
dst += 4;
|
||||
src++;
|
||||
}
|
||||
break;
|
||||
case TextureType::_5551:
|
||||
for (int x = 0; x < w; x++)
|
||||
{
|
||||
*dst++ = (((*src >> 11) & 0x1F) << 3) | ((*src >> 13) & 7);
|
||||
*dst++ = (((*src >> 6) & 0x1F) << 3) | ((*src >> 8) & 7);
|
||||
*dst++ = (((*src >> 1) & 0x1F) << 3) | ((*src >> 3) & 7);
|
||||
*dst++ = (*src & 1) ? 255 : 0;
|
||||
src++;
|
||||
}
|
||||
break;
|
||||
case TextureType::_8888:
|
||||
memcpy(dst, src, w * 4);
|
||||
dst += w * 4;
|
||||
src += w * 2;
|
||||
break;
|
||||
default:
|
||||
WARN_LOG(RENDERER, "dumpTexture: unsupported picture format %x", (u32)textype);
|
||||
free(dst_buffer);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case TextureType::_565:
|
||||
for (int x = 0; x < w; x++)
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (textype)
|
||||
{
|
||||
*dst++ = ((*src >> 11) & 0x1F) << 3;
|
||||
*dst++ = ((*src >> 5) & 0x3F) << 2;
|
||||
*dst++ = (*src & 0x1F) << 3;
|
||||
*dst++ = 255;
|
||||
src++;
|
||||
case TextureType::_4444:
|
||||
for (int x = 0; x < w; x++)
|
||||
{
|
||||
*(u32 *)dst = Unpacker4444_32<RGBAPacker>::unpack(*src);
|
||||
dst += 4;
|
||||
src++;
|
||||
}
|
||||
break;
|
||||
case TextureType::_565:
|
||||
for (int x = 0; x < w; x++)
|
||||
{
|
||||
*(u32 *)dst = Unpacker565_32<RGBAPacker>::unpack(*src);
|
||||
dst += 4;
|
||||
src++;
|
||||
}
|
||||
break;
|
||||
case TextureType::_5551:
|
||||
for (int x = 0; x < w; x++)
|
||||
{
|
||||
*(u32 *)dst = Unpacker1555_32<RGBAPacker>::unpack(*src);
|
||||
dst += 4;
|
||||
src++;
|
||||
}
|
||||
break;
|
||||
case TextureType::_8888:
|
||||
for (int x = 0; x < w; x++)
|
||||
{
|
||||
*(u32 *)dst = Unpacker8888<RGBAPacker>::unpack(*(u32 *)src);
|
||||
dst += 4;
|
||||
src += 2;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
WARN_LOG(RENDERER, "dumpTexture: unsupported picture format %x", (u32)textype);
|
||||
free(dst_buffer);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case TextureType::_5551:
|
||||
for (int x = 0; x < w; x++)
|
||||
{
|
||||
*dst++ = ((*src >> 11) & 0x1F) << 3;
|
||||
*dst++ = ((*src >> 6) & 0x1F) << 3;
|
||||
*dst++ = ((*src >> 1) & 0x1F) << 3;
|
||||
*dst++ = (*src & 1) ? 255 : 0;
|
||||
src++;
|
||||
}
|
||||
break;
|
||||
case TextureType::_8888:
|
||||
for (int x = 0; x < w; x++)
|
||||
{
|
||||
*(u32 *)dst = *(u32 *)src;
|
||||
dst += 4;
|
||||
src += 2;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
WARN_LOG(RENDERER, "dumpTexture: unsupported picture format %x", (u32)textype);
|
||||
free(dst_buffer);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+184
-130
@@ -91,39 +91,74 @@ void palette_update()
|
||||
pal_needs_update = false;
|
||||
palette_updated = true;
|
||||
|
||||
switch(PAL_RAM_CTRL&3)
|
||||
if (!config::RendererType.isDirectX())
|
||||
{
|
||||
case 0:
|
||||
for (int i=0;i<1024;i++)
|
||||
switch(PAL_RAM_CTRL&3)
|
||||
{
|
||||
palette16_ram[i] = ARGB1555(PALETTE_RAM[i]);
|
||||
palette32_ram[i] = ARGB1555_32(PALETTE_RAM[i]);
|
||||
}
|
||||
break;
|
||||
case 0:
|
||||
for (int i=0;i<1024;i++)
|
||||
{
|
||||
palette16_ram[i] = Unpacker1555::unpack(PALETTE_RAM[i]);
|
||||
palette32_ram[i] = Unpacker1555_32<RGBAPacker>::unpack(PALETTE_RAM[i]);
|
||||
}
|
||||
break;
|
||||
|
||||
case 1:
|
||||
for (int i=0;i<1024;i++)
|
||||
{
|
||||
palette16_ram[i] = ARGB565(PALETTE_RAM[i]);
|
||||
palette32_ram[i] = ARGB565_32(PALETTE_RAM[i]);
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
for (int i=0;i<1024;i++)
|
||||
{
|
||||
palette16_ram[i] = UnpackerNop<u16>::unpack(PALETTE_RAM[i]);
|
||||
palette32_ram[i] = Unpacker565_32<RGBAPacker>::unpack(PALETTE_RAM[i]);
|
||||
}
|
||||
break;
|
||||
|
||||
case 2:
|
||||
for (int i=0;i<1024;i++)
|
||||
{
|
||||
palette16_ram[i] = ARGB4444(PALETTE_RAM[i]);
|
||||
palette32_ram[i] = ARGB4444_32(PALETTE_RAM[i]);
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
for (int i=0;i<1024;i++)
|
||||
{
|
||||
palette16_ram[i] = Unpacker4444::unpack(PALETTE_RAM[i]);
|
||||
palette32_ram[i] = Unpacker4444_32<RGBAPacker>::unpack(PALETTE_RAM[i]);
|
||||
}
|
||||
break;
|
||||
|
||||
case 3:
|
||||
for (int i=0;i<1024;i++)
|
||||
case 3:
|
||||
for (int i=0;i<1024;i++)
|
||||
palette32_ram[i] = Unpacker8888<RGBAPacker>::unpack(PALETTE_RAM[i]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
switch(PAL_RAM_CTRL&3)
|
||||
{
|
||||
palette16_ram[i] = ARGB8888(PALETTE_RAM[i]);
|
||||
palette32_ram[i] = ARGB8888_32(PALETTE_RAM[i]);
|
||||
|
||||
case 0:
|
||||
for (int i=0;i<1024;i++)
|
||||
{
|
||||
palette16_ram[i] = UnpackerNop<u16>::unpack(PALETTE_RAM[i]);
|
||||
palette32_ram[i] = Unpacker1555_32<BGRAPacker>::unpack(PALETTE_RAM[i]);
|
||||
}
|
||||
break;
|
||||
|
||||
case 1:
|
||||
for (int i=0;i<1024;i++)
|
||||
{
|
||||
palette16_ram[i] = UnpackerNop<u16>::unpack(PALETTE_RAM[i]);
|
||||
palette32_ram[i] = Unpacker565_32<BGRAPacker>::unpack(PALETTE_RAM[i]);
|
||||
}
|
||||
break;
|
||||
|
||||
case 2:
|
||||
for (int i=0;i<1024;i++)
|
||||
{
|
||||
palette16_ram[i] = UnpackerNop<u16>::unpack(PALETTE_RAM[i]);
|
||||
palette32_ram[i] = Unpacker4444_32<BGRAPacker>::unpack(PALETTE_RAM[i]);
|
||||
}
|
||||
break;
|
||||
|
||||
case 3:
|
||||
for (int i=0;i<1024;i++)
|
||||
palette32_ram[i] = UnpackerNop<u32>::unpack(PALETTE_RAM[i]);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
for (int i = 0; i < 64; i++)
|
||||
pal_hash_16[i] = XXH32(&PALETTE_RAM[i << 4], 16 * 4, 7);
|
||||
@@ -258,12 +293,6 @@ static void libCore_vramlock_Unlock_block_wb(vram_block* block)
|
||||
free(block);
|
||||
}
|
||||
|
||||
void libCore_vramlock_Unlock_block(vram_block* block)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(vramlist_lock);
|
||||
libCore_vramlock_Unlock_block_wb(block);
|
||||
}
|
||||
|
||||
#ifndef TARGET_NO_OPENMP
|
||||
static inline int getThreadCount()
|
||||
{
|
||||
@@ -309,28 +338,38 @@ struct PvrTexInfo
|
||||
int bpp; //4/8 for pal. 16 for yuv, rgb, argb
|
||||
TextureType type;
|
||||
// Conversion to 16 bpp
|
||||
TexConvFP *PL;
|
||||
TexConvFP *TW;
|
||||
TexConvFP *VQ;
|
||||
TexConvFP PL;
|
||||
TexConvFP TW;
|
||||
TexConvFP VQ;
|
||||
// Conversion to 32 bpp
|
||||
TexConvFP32 *PL32;
|
||||
TexConvFP32 *TW32;
|
||||
TexConvFP32 *VQ32;
|
||||
TexConvFP32 PL32;
|
||||
TexConvFP32 TW32;
|
||||
TexConvFP32 VQ32;
|
||||
// Conversion to 8 bpp (palette)
|
||||
TexConvFP8 *TW8;
|
||||
TexConvFP8 TW8;
|
||||
};
|
||||
|
||||
static const PvrTexInfo format[8] =
|
||||
{ // name bpp Final format Planar Twiddled VQ Planar(32b) Twiddled(32b) VQ (32b) Palette (8b)
|
||||
{"1555", 16, TextureType::_5551, tex1555_PL, tex1555_TW, tex1555_VQ, tex1555_PL32, tex1555_TW32, tex1555_VQ32, nullptr }, //1555
|
||||
{"565", 16, TextureType::_565, tex565_PL, tex565_TW, tex565_VQ, tex565_PL32, tex565_TW32, tex565_VQ32, nullptr }, //565
|
||||
{"4444", 16, TextureType::_4444, tex4444_PL, tex4444_TW, tex4444_VQ, tex4444_PL32, tex4444_TW32, tex4444_VQ32, nullptr }, //4444
|
||||
{"yuv", 16, TextureType::_8888, nullptr, nullptr, nullptr, texYUV422_PL, texYUV422_TW, texYUV422_VQ, nullptr }, //yuv
|
||||
{"bumpmap", 16, TextureType::_4444, texBMP_PL, texBMP_TW, texBMP_VQ, tex4444_PL32, tex4444_TW32, tex4444_VQ32, nullptr }, //bump map
|
||||
{"pal4", 4, TextureType::_5551, nullptr, texPAL4_TW, texPAL4_VQ, nullptr, texPAL4_TW32, texPAL4_VQ32, texPAL4PT_TW }, //pal4
|
||||
{"pal8", 8, TextureType::_5551, nullptr, texPAL8_TW, texPAL8_VQ, nullptr, texPAL8_TW32, texPAL8_VQ32, texPAL8PT_TW }, //pal8
|
||||
{"ns/1555", 0}, // Not supported (1555)
|
||||
};
|
||||
#define TEX_CONV_TABLE \
|
||||
const PvrTexInfo pvrTexInfo[8] = \
|
||||
{ /* name bpp Final format Planar Twiddled VQ Planar(32b) Twiddled(32b) VQ (32b) Palette (8b) */ \
|
||||
{"1555", 16, TextureType::_5551, tex1555_PL, tex1555_TW, tex1555_VQ, tex1555_PL32, tex1555_TW32, tex1555_VQ32, nullptr }, \
|
||||
{"565", 16, TextureType::_565, tex565_PL, tex565_TW, tex565_VQ, tex565_PL32, tex565_TW32, tex565_VQ32, nullptr }, \
|
||||
{"4444", 16, TextureType::_4444, tex4444_PL, tex4444_TW, tex4444_VQ, tex4444_PL32, tex4444_TW32, tex4444_VQ32, nullptr }, \
|
||||
{"yuv", 16, TextureType::_8888, nullptr, nullptr, nullptr, texYUV422_PL, texYUV422_TW, texYUV422_VQ, nullptr }, \
|
||||
{"bumpmap", 16, TextureType::_4444, texBMP_PL, texBMP_TW, texBMP_VQ, tex4444_PL32, tex4444_TW32, tex4444_VQ32, nullptr }, \
|
||||
{"pal4", 4, TextureType::_5551, nullptr, texPAL4_TW, texPAL4_VQ, nullptr, texPAL4_TW32, texPAL4_VQ32, texPAL4PT_TW }, \
|
||||
{"pal8", 8, TextureType::_5551, nullptr, texPAL8_TW, texPAL8_VQ, nullptr, texPAL8_TW32, texPAL8_VQ32, texPAL8PT_TW }, \
|
||||
{"ns/1555", 0}, \
|
||||
}
|
||||
|
||||
namespace opengl {
|
||||
TEX_CONV_TABLE;
|
||||
}
|
||||
namespace directx {
|
||||
TEX_CONV_TABLE;
|
||||
}
|
||||
#undef TEX_CONV_TABLE
|
||||
static const PvrTexInfo *pvrTexInfo = opengl::pvrTexInfo;
|
||||
|
||||
static const u32 VQMipPoint[11] =
|
||||
{
|
||||
@@ -427,20 +466,15 @@ void BaseTextureCacheData::Create()
|
||||
lock_block = nullptr;
|
||||
custom_image_data = nullptr;
|
||||
custom_load_in_progress = 0;
|
||||
gpuPalette = false;
|
||||
|
||||
//decode info from tsp/tcw into the texture struct
|
||||
tex = &format[tcw.PixelFmt == PixelReserved ? Pixel1555 : tcw.PixelFmt]; //texture format table entry
|
||||
tex = &pvrTexInfo[tcw.PixelFmt == PixelReserved ? Pixel1555 : tcw.PixelFmt]; //texture format table entry
|
||||
|
||||
sa_tex = (tcw.TexAddr << 3) & VRAM_MASK; //texture start address
|
||||
sa = sa_tex; //data texture start address (modified for MIPs, as needed)
|
||||
w = 8 << tsp.TexU; //tex width
|
||||
h = 8 << tsp.TexV; //tex height
|
||||
|
||||
//PAL texture
|
||||
if (tex->bpp == 4)
|
||||
palette_index = tcw.PalSelect << 4;
|
||||
else if (tex->bpp == 8)
|
||||
palette_index = (tcw.PalSelect >> 4) << 8;
|
||||
width = 8 << tsp.TexU; //tex width
|
||||
height = 8 << tsp.TexV; //tex height
|
||||
|
||||
texconv8 = nullptr;
|
||||
|
||||
@@ -460,7 +494,7 @@ void BaseTextureCacheData::Create()
|
||||
}
|
||||
|
||||
//Planar textures support stride selection, mostly used for non power of 2 textures (videos)
|
||||
int stride = w;
|
||||
int stride = width;
|
||||
if (tcw.StrideSel)
|
||||
stride = (TEXT_CONTROL & 31) * 32;
|
||||
|
||||
@@ -468,26 +502,28 @@ void BaseTextureCacheData::Create()
|
||||
texconv = tex->PL;
|
||||
texconv32 = tex->PL32;
|
||||
//calculate the size, in bytes, for the locking
|
||||
size = stride * h * tex->bpp / 8;
|
||||
size = stride * height * tex->bpp / 8;
|
||||
}
|
||||
else
|
||||
{
|
||||
tcw.ScanOrder = 0;
|
||||
tcw.StrideSel = 0;
|
||||
if (!IsPaletted())
|
||||
{
|
||||
tcw.ScanOrder = 0;
|
||||
tcw.StrideSel = 0;
|
||||
}
|
||||
// Quake 3 Arena uses one
|
||||
if (tcw.MipMapped)
|
||||
// Mipmapped texture must be square and TexV is ignored
|
||||
h = w;
|
||||
height = width;
|
||||
|
||||
if (tcw.VQ_Comp)
|
||||
{
|
||||
verify(tex->VQ != NULL || tex->VQ32 != NULL);
|
||||
vq_codebook = sa;
|
||||
if (tcw.MipMapped)
|
||||
sa += VQMipPoint[tsp.TexU + 3];
|
||||
texconv = tex->VQ;
|
||||
texconv32 = tex->VQ32;
|
||||
size = w * h / 8;
|
||||
size = width * height / 8 + 256 * 8;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -496,7 +532,7 @@ void BaseTextureCacheData::Create()
|
||||
sa += OtherMipPoint[tsp.TexU + 3] * tex->bpp / 8;
|
||||
texconv = tex->TW;
|
||||
texconv32 = tex->TW32;
|
||||
size = w * h * tex->bpp / 8;
|
||||
size = width * height * tex->bpp / 8;
|
||||
texconv8 = tex->TW8;
|
||||
}
|
||||
}
|
||||
@@ -504,26 +540,39 @@ void BaseTextureCacheData::Create()
|
||||
|
||||
void BaseTextureCacheData::ComputeHash()
|
||||
{
|
||||
texture_hash = XXH32(&vram[sa], size, 7);
|
||||
u32 hashSize = size;
|
||||
if (tcw.VQ_Comp)
|
||||
{
|
||||
// The size for VQ textures wasn't correctly calculated.
|
||||
// We use the old size to compute the hash for backward-compatibility
|
||||
// with existing custom texture packs.
|
||||
hashSize = size - 256 * 8;
|
||||
}
|
||||
texture_hash = XXH32(&vram[sa], hashSize, 7);
|
||||
if (IsPaletted())
|
||||
texture_hash ^= palette_hash;
|
||||
old_texture_hash = texture_hash;
|
||||
texture_hash ^= tcw.full & 0xFC000000; // everything but texaddr, reserved and stride
|
||||
// Include everything but texaddr, reserved and stride. Palette textures don't have ScanOrder
|
||||
const u32 tcwMask = IsPaletted() ? 0xF8000000 : 0xFC000000;
|
||||
texture_hash ^= tcw.full & tcwMask;
|
||||
}
|
||||
|
||||
void BaseTextureCacheData::Update()
|
||||
{
|
||||
//texture state tracking stuff
|
||||
Updates++;
|
||||
dirty=0;
|
||||
|
||||
dirty = 0;
|
||||
gpuPalette = false;
|
||||
tex_type = tex->type;
|
||||
|
||||
bool has_alpha = false;
|
||||
if (IsPaletted())
|
||||
{
|
||||
if (IsGpuHandledPaletted(tsp, tcw))
|
||||
{
|
||||
tex_type = TextureType::_8;
|
||||
gpuPalette = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
tex_type = PAL_TYPE[PAL_RAM_CTRL&3];
|
||||
@@ -532,30 +581,37 @@ void BaseTextureCacheData::Update()
|
||||
}
|
||||
|
||||
// Get the palette hash to check for future updates
|
||||
// TODO get rid of ::palette_index and ::vq_codebook
|
||||
if (tcw.PixelFmt == PixelPal4)
|
||||
{
|
||||
palette_hash = pal_hash_16[tcw.PalSelect];
|
||||
::palette_index = tcw.PalSelect << 4;
|
||||
}
|
||||
else
|
||||
{
|
||||
palette_hash = pal_hash_256[tcw.PalSelect >> 4];
|
||||
::palette_index = (tcw.PalSelect >> 4) << 8;
|
||||
}
|
||||
}
|
||||
|
||||
::palette_index = this->palette_index; // might be used if pal. tex
|
||||
::vq_codebook = &vram[vq_codebook]; // might be used if VQ tex
|
||||
if (tcw.VQ_Comp)
|
||||
::vq_codebook = &vram[sa_tex]; // might be used if VQ tex
|
||||
|
||||
//texture conversion work
|
||||
u32 stride = w;
|
||||
u32 stride = width;
|
||||
|
||||
if (tcw.StrideSel && tcw.ScanOrder && (tex->PL || tex->PL32))
|
||||
stride = (TEXT_CONTROL & 31) * 32;
|
||||
|
||||
u32 original_h = h;
|
||||
u32 original_h = height;
|
||||
if (sa_tex > VRAM_SIZE || size == 0 || sa + size > VRAM_SIZE)
|
||||
{
|
||||
if (sa < VRAM_SIZE && sa + size > VRAM_SIZE && tcw.ScanOrder && stride > 0)
|
||||
{
|
||||
// Shenmue Space Harrier mini-arcade loads a texture that goes beyond the end of VRAM
|
||||
// but only uses the top portion of it
|
||||
h = (VRAM_SIZE - sa) * 8 / stride / tex->bpp;
|
||||
size = stride * h * tex->bpp/8;
|
||||
height = (VRAM_SIZE - sa) * 8 / stride / tex->bpp;
|
||||
size = stride * height * tex->bpp/8;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -567,8 +623,8 @@ void BaseTextureCacheData::Update()
|
||||
custom_texture.LoadCustomTextureAsync(this);
|
||||
|
||||
void *temp_tex_buffer = NULL;
|
||||
u32 upscaled_w = w;
|
||||
u32 upscaled_h = h;
|
||||
u32 upscaled_w = width;
|
||||
u32 upscaled_h = height;
|
||||
|
||||
PixelBuffer<u16> pb16;
|
||||
PixelBuffer<u32> pb32;
|
||||
@@ -577,7 +633,7 @@ void BaseTextureCacheData::Update()
|
||||
// Figure out if we really need to use a 32-bit pixel buffer
|
||||
bool textureUpscaling = config::TextureUpscale > 1
|
||||
// Don't process textures that are too big
|
||||
&& (int)(w * h) <= config::MaxFilteredTextureSize * config::MaxFilteredTextureSize
|
||||
&& (int)(width * height) <= config::MaxFilteredTextureSize * config::MaxFilteredTextureSize
|
||||
// Don't process YUV textures
|
||||
&& tcw.PixelFmt != PixelYUV;
|
||||
bool need_32bit_buffer = true;
|
||||
@@ -600,7 +656,7 @@ void BaseTextureCacheData::Update()
|
||||
|
||||
if (mipmapped)
|
||||
{
|
||||
pb32.init(w, h, true);
|
||||
pb32.init(width, height, true);
|
||||
for (u32 i = 0; i <= tsp.TexU + 3u; i++)
|
||||
{
|
||||
pb32.set_mipmap(i);
|
||||
@@ -621,7 +677,7 @@ void BaseTextureCacheData::Update()
|
||||
vram_addr = sa_tex + OtherMipPoint[i] * tex->bpp / 8;
|
||||
if (tcw.PixelFmt == PixelYUV && i == 0)
|
||||
// Special case for YUV at 1x1 LoD
|
||||
format[Pixel565].TW32(&pb32, &vram[vram_addr], 1, 1);
|
||||
pvrTexInfo[Pixel565].TW32(&pb32, &vram[vram_addr], 1, 1);
|
||||
else
|
||||
texconv32(&pb32, &vram[vram_addr], 1 << i, 1 << i);
|
||||
}
|
||||
@@ -629,19 +685,19 @@ void BaseTextureCacheData::Update()
|
||||
}
|
||||
else
|
||||
{
|
||||
pb32.init(w, h);
|
||||
texconv32(&pb32, (u8*)&vram[sa], stride, h);
|
||||
pb32.init(width, height);
|
||||
texconv32(&pb32, (u8*)&vram[sa], stride, height);
|
||||
|
||||
// xBRZ scaling
|
||||
if (textureUpscaling)
|
||||
{
|
||||
PixelBuffer<u32> tmp_buf;
|
||||
tmp_buf.init(w * config::TextureUpscale, h * config::TextureUpscale);
|
||||
tmp_buf.init(width * config::TextureUpscale, height * config::TextureUpscale);
|
||||
|
||||
if (tcw.PixelFmt == Pixel1555 || tcw.PixelFmt == Pixel4444)
|
||||
// Alpha channel formats. Palettes with alpha are already handled
|
||||
has_alpha = true;
|
||||
UpscalexBRZ(config::TextureUpscale, pb32.data(), tmp_buf.data(), w, h, has_alpha);
|
||||
UpscalexBRZ(config::TextureUpscale, pb32.data(), tmp_buf.data(), width, height, has_alpha);
|
||||
pb32.steal_data(tmp_buf);
|
||||
upscaled_w *= config::TextureUpscale;
|
||||
upscaled_h *= config::TextureUpscale;
|
||||
@@ -653,7 +709,8 @@ void BaseTextureCacheData::Update()
|
||||
{
|
||||
if (mipmapped)
|
||||
{
|
||||
pb8.init(w, h, true);
|
||||
// This shouldn't happen since mipmapped palette textures are converted to rgba
|
||||
pb8.init(width, height, true);
|
||||
for (u32 i = 0; i <= tsp.TexU + 3u; i++)
|
||||
{
|
||||
pb8.set_mipmap(i);
|
||||
@@ -664,8 +721,8 @@ void BaseTextureCacheData::Update()
|
||||
}
|
||||
else
|
||||
{
|
||||
pb8.init(w, h);
|
||||
texconv8(&pb8, &vram[sa], stride, h);
|
||||
pb8.init(width, height);
|
||||
texconv8(&pb8, &vram[sa], stride, height);
|
||||
}
|
||||
temp_tex_buffer = pb8.data();
|
||||
}
|
||||
@@ -673,7 +730,7 @@ void BaseTextureCacheData::Update()
|
||||
{
|
||||
if (mipmapped)
|
||||
{
|
||||
pb16.init(w, h, true);
|
||||
pb16.init(width, height, true);
|
||||
for (u32 i = 0; i <= tsp.TexU + 3u; i++)
|
||||
{
|
||||
pb16.set_mipmap(i);
|
||||
@@ -698,8 +755,8 @@ void BaseTextureCacheData::Update()
|
||||
}
|
||||
else
|
||||
{
|
||||
pb16.init(w, h);
|
||||
texconv(&pb16,(u8*)&vram[sa],stride,h);
|
||||
pb16.init(width, height);
|
||||
texconv(&pb16,(u8*)&vram[sa],stride,height);
|
||||
}
|
||||
temp_tex_buffer = pb16.data();
|
||||
}
|
||||
@@ -707,13 +764,13 @@ void BaseTextureCacheData::Update()
|
||||
{
|
||||
//fill it in with a temp color
|
||||
WARN_LOG(RENDERER, "UNHANDLED TEXTURE");
|
||||
pb16.init(w, h);
|
||||
memset(pb16.data(), 0x80, w * h * 2);
|
||||
pb16.init(width, height);
|
||||
memset(pb16.data(), 0x80, width * height * 2);
|
||||
temp_tex_buffer = pb16.data();
|
||||
mipmapped = false;
|
||||
}
|
||||
// Restore the original texture height if it was constrained to VRAM limits above
|
||||
h = original_h;
|
||||
height = original_h;
|
||||
|
||||
//lock the texture to detect changes in it
|
||||
libCore_vramlock_Lock(sa_tex, sa + size - 1, this);
|
||||
@@ -733,12 +790,18 @@ void BaseTextureCacheData::CheckCustomTexture()
|
||||
if (IsCustomTextureAvailable())
|
||||
{
|
||||
tex_type = TextureType::_8888;
|
||||
gpuPalette = false;
|
||||
UploadToGPU(custom_width, custom_height, custom_image_data, IsMipmapped(), false);
|
||||
free(custom_image_data);
|
||||
custom_image_data = NULL;
|
||||
custom_image_data = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void BaseTextureCacheData::SetDirectXColorOrder(bool enabled) {
|
||||
pvrTexInfo = enabled ? directx::pvrTexInfo : opengl::pvrTexInfo;
|
||||
}
|
||||
|
||||
template<typename Packer>
|
||||
void ReadFramebuffer(PixelBuffer<u32>& pb, int& width, int& height)
|
||||
{
|
||||
width = (FB_R_SIZE.fb_x_size + 1) << 1; // in 16-bit words
|
||||
@@ -784,7 +847,7 @@ void ReadFramebuffer(PixelBuffer<u32>& pb, int& width, int& height)
|
||||
}
|
||||
|
||||
pb.init(width, height);
|
||||
u8 *dst = (u8*)pb.data();
|
||||
u32 *dst = (u32 *)pb.data();
|
||||
|
||||
switch (FB_R_CTRL.fb_depth)
|
||||
{
|
||||
@@ -794,10 +857,11 @@ void ReadFramebuffer(PixelBuffer<u32>& pb, int& width, int& height)
|
||||
for (int i = 0; i < width; i++)
|
||||
{
|
||||
u16 src = pvr_read32p<u16>(addr);
|
||||
*dst++ = (((src >> 10) & 0x1F) << 3) + FB_R_CTRL.fb_concat;
|
||||
*dst++ = (((src >> 5) & 0x1F) << 3) + FB_R_CTRL.fb_concat;
|
||||
*dst++ = (((src >> 0) & 0x1F) << 3) + FB_R_CTRL.fb_concat;
|
||||
*dst++ = 0xFF;
|
||||
*dst++ = Packer::pack(
|
||||
(((src >> 10) & 0x1F) << 3) + FB_R_CTRL.fb_concat,
|
||||
(((src >> 5) & 0x1F) << 3) + FB_R_CTRL.fb_concat,
|
||||
(((src >> 0) & 0x1F) << 3) + FB_R_CTRL.fb_concat,
|
||||
0xff);
|
||||
addr += bpp;
|
||||
}
|
||||
addr += modulus * bpp;
|
||||
@@ -810,10 +874,11 @@ void ReadFramebuffer(PixelBuffer<u32>& pb, int& width, int& height)
|
||||
for (int i = 0; i < width; i++)
|
||||
{
|
||||
u16 src = pvr_read32p<u16>(addr);
|
||||
*dst++ = (((src >> 11) & 0x1F) << 3) + FB_R_CTRL.fb_concat;
|
||||
*dst++ = (((src >> 5) & 0x3F) << 2) + (FB_R_CTRL.fb_concat & 3);
|
||||
*dst++ = (((src >> 0) & 0x1F) << 3) + FB_R_CTRL.fb_concat;
|
||||
*dst++ = 0xFF;
|
||||
*dst++ = Packer::pack(
|
||||
(((src >> 11) & 0x1F) << 3) + FB_R_CTRL.fb_concat,
|
||||
(((src >> 5) & 0x3F) << 2) + (FB_R_CTRL.fb_concat & 3),
|
||||
(((src >> 0) & 0x1F) << 3) + FB_R_CTRL.fb_concat,
|
||||
0xFF);
|
||||
addr += bpp;
|
||||
}
|
||||
addr += modulus * bpp;
|
||||
@@ -825,33 +890,21 @@ void ReadFramebuffer(PixelBuffer<u32>& pb, int& width, int& height)
|
||||
for (int i = 0; i < width; i += 4)
|
||||
{
|
||||
u32 src = pvr_read32p<u32>(addr);
|
||||
*dst++ = src >> 16;
|
||||
*dst++ = src >> 8;
|
||||
*dst++ = src;
|
||||
*dst++ = 0xFF;
|
||||
*dst++ = Packer::pack(src >> 16, src >> 8, src, 0xff);
|
||||
addr += 4;
|
||||
if (i + 1 >= width)
|
||||
break;
|
||||
u32 src2 = pvr_read32p<u32>(addr);
|
||||
*dst++ = src2 >> 8;
|
||||
*dst++ = src2;
|
||||
*dst++ = src >> 24;
|
||||
*dst++ = 0xFF;
|
||||
*dst++ = Packer::pack(src2 >> 8, src2, src >> 24, 0xff);
|
||||
addr += 4;
|
||||
if (i + 2 >= width)
|
||||
break;
|
||||
u32 src3 = pvr_read32p<u32>(addr);
|
||||
*dst++ = src3;
|
||||
*dst++ = src2 >> 24;
|
||||
*dst++ = src2 >> 16;
|
||||
*dst++ = 0xFF;
|
||||
*dst++ = Packer::pack(src3, src2 >> 24, src2 >> 16, 0xff);
|
||||
addr += 4;
|
||||
if (i + 3 >= width)
|
||||
break;
|
||||
*dst++ = src3 >> 24;
|
||||
*dst++ = src3 >> 16;
|
||||
*dst++ = src3 >> 8;
|
||||
*dst++ = 0xFF;
|
||||
*dst++ = Packer::pack(src3 >> 24, src3 >> 16, src3 >> 8, 0xff);
|
||||
}
|
||||
addr += modulus * bpp;
|
||||
}
|
||||
@@ -862,10 +915,7 @@ void ReadFramebuffer(PixelBuffer<u32>& pb, int& width, int& height)
|
||||
for (int i = 0; i < width; i++)
|
||||
{
|
||||
u32 src = pvr_read32p<u32>(addr);
|
||||
*dst++ = src >> 16;
|
||||
*dst++ = src >> 8;
|
||||
*dst++ = src;
|
||||
*dst++ = 0xFF;
|
||||
*dst++ = Packer::pack(src >> 16, src >> 8, src, 0xff);
|
||||
addr += bpp;
|
||||
}
|
||||
addr += modulus * bpp;
|
||||
@@ -873,7 +923,10 @@ void ReadFramebuffer(PixelBuffer<u32>& pb, int& width, int& height)
|
||||
break;
|
||||
}
|
||||
}
|
||||
template void ReadFramebuffer<RGBAPacker>(PixelBuffer<u32>& pb, int& width, int& height);
|
||||
template void ReadFramebuffer<BGRAPacker>(PixelBuffer<u32>& pb, int& width, int& height);
|
||||
|
||||
template<int Red, int Green, int Blue, int Alpha>
|
||||
void WriteTextureToVRam(u32 width, u32 height, u8 *data, u16 *dst, u32 fb_w_ctrl_in, u32 linestride)
|
||||
{
|
||||
FB_W_CTRL_type fb_w_ctrl;
|
||||
@@ -895,25 +948,25 @@ void WriteTextureToVRam(u32 width, u32 height, u8 *data, u16 *dst, u32 fb_w_ctrl
|
||||
{
|
||||
case 0: //0x0 0555 KRGB 16 bit (default) Bit 15 is the value of fb_kval[7].
|
||||
for (u32 c = 0; c < width; c++) {
|
||||
*dst++ = (((p[0] >> 3) & 0x1F) << 10) | (((p[1] >> 3) & 0x1F) << 5) | ((p[2] >> 3) & 0x1F) | kval_bit;
|
||||
*dst++ = (((p[Red] >> 3) & 0x1F) << 10) | (((p[Green] >> 3) & 0x1F) << 5) | ((p[Blue] >> 3) & 0x1F) | kval_bit;
|
||||
p += 4;
|
||||
}
|
||||
break;
|
||||
case 1: //0x1 565 RGB 16 bit
|
||||
for (u32 c = 0; c < width; c++) {
|
||||
*dst++ = (((p[0] >> 3) & 0x1F) << 11) | (((p[1] >> 2) & 0x3F) << 5) | ((p[2] >> 3) & 0x1F);
|
||||
*dst++ = (((p[Red] >> 3) & 0x1F) << 11) | (((p[Green] >> 2) & 0x3F) << 5) | ((p[Blue] >> 3) & 0x1F);
|
||||
p += 4;
|
||||
}
|
||||
break;
|
||||
case 2: //0x2 4444 ARGB 16 bit
|
||||
for (u32 c = 0; c < width; c++) {
|
||||
*dst++ = (((p[0] >> 4) & 0xF) << 8) | (((p[1] >> 4) & 0xF) << 4) | ((p[2] >> 4) & 0xF) | (((p[3] >> 4) & 0xF) << 12);
|
||||
*dst++ = (((p[Red] >> 4) & 0xF) << 8) | (((p[Green] >> 4) & 0xF) << 4) | ((p[Blue] >> 4) & 0xF) | (((p[Alpha] >> 4) & 0xF) << 12);
|
||||
p += 4;
|
||||
}
|
||||
break;
|
||||
case 3://0x3 1555 ARGB 16 bit The alpha value is determined by comparison with the value of fb_alpha_threshold.
|
||||
for (u32 c = 0; c < width; c++) {
|
||||
*dst++ = (((p[0] >> 3) & 0x1F) << 10) | (((p[1] >> 3) & 0x1F) << 5) | ((p[2] >> 3) & 0x1F) | (p[3] > fb_alpha_threshold ? 0x8000 : 0);
|
||||
*dst++ = (((p[Red] >> 3) & 0x1F) << 10) | (((p[Green] >> 3) & 0x1F) << 5) | ((p[Blue] >> 3) & 0x1F) | (p[Alpha] > fb_alpha_threshold ? 0x8000 : 0);
|
||||
p += 4;
|
||||
}
|
||||
break;
|
||||
@@ -921,6 +974,8 @@ void WriteTextureToVRam(u32 width, u32 height, u8 *data, u16 *dst, u32 fb_w_ctrl
|
||||
dst += padding;
|
||||
}
|
||||
}
|
||||
template void WriteTextureToVRam<0, 1, 2, 3>(u32 width, u32 height, u8 *data, u16 *dst, u32 fb_w_ctrl_in, u32 linestride);
|
||||
template void WriteTextureToVRam<2, 1, 0, 3>(u32 width, u32 height, u8 *data, u16 *dst, u32 fb_w_ctrl_in, u32 linestride);
|
||||
|
||||
static void rend_text_invl(vram_block* bl)
|
||||
{
|
||||
@@ -940,4 +995,3 @@ void dump_screenshot(u8 *buffer, u32 width, u32 height, bool alpha, u32 rowPitch
|
||||
stbi_write_png("screenshot.png", width, height, alpha ? 4 : 3, buffer, rowPitch);
|
||||
}
|
||||
#endif
|
||||
|
||||
+352
-437
@@ -21,6 +21,8 @@ extern bool palette_updated;
|
||||
|
||||
extern u32 detwiddle[2][11][1024];
|
||||
|
||||
void palette_update();
|
||||
|
||||
template<class pixel_type>
|
||||
class PixelBuffer
|
||||
{
|
||||
@@ -120,407 +122,276 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
void palette_update();
|
||||
|
||||
#define clamp(minv, maxv, x) ((x) < (minv) ? (minv) : (x) > (maxv) ? (maxv) : (x))
|
||||
|
||||
// Unpack to 16-bit word
|
||||
// Open GL
|
||||
struct RGBAPacker {
|
||||
static u32 pack(u8 r, u8 g, u8 b, u8 a) {
|
||||
return r | (g << 8) | (b << 16) | (a << 24);
|
||||
}
|
||||
};
|
||||
// DirectX
|
||||
struct BGRAPacker {
|
||||
static u32 pack(u8 r, u8 g, u8 b, u8 a) {
|
||||
return b | (g << 8) | (r << 16) | (a << 24);
|
||||
}
|
||||
};
|
||||
|
||||
#define ARGB1555( word ) ( ((word>>15)&1) | (((word>>10) & 0x1F)<<11) | (((word>>5) & 0x1F)<<6) | (((word>>0) & 0x1F)<<1) )
|
||||
|
||||
#define ARGB565( word ) ( (((word>>0)&0x1F)<<0) | (((word>>5)&0x3F)<<5) | (((word>>11)&0x1F)<<11) )
|
||||
|
||||
#define ARGB4444( word ) ( (((word>>0)&0xF)<<4) | (((word>>4)&0xF)<<8) | (((word>>8)&0xF)<<12) | (((word>>12)&0xF)<<0) )
|
||||
|
||||
#define ARGB8888( word ) ( (((word>>4)&0xF)<<4) | (((word>>12)&0xF)<<8) | (((word>>20)&0xF)<<12) | (((word>>28)&0xF)<<0) )
|
||||
|
||||
// Unpack to 32-bit word
|
||||
|
||||
#define ARGB1555_32( word ) ( ((word & 0x8000) ? 0xFF000000 : 0) | \
|
||||
(((word >> 10) & 0x1F) << 3) | (((word >> 12) & 0x7) << 0) | \
|
||||
(((word >> 5) & 0x1F) << 11) | (((word >> 7) & 0x7) << 8) | \
|
||||
(((word >> 0) & 0x1F) << 19) | (((word >> 2) & 0x7) << 16) )
|
||||
|
||||
#define ARGB565_32( word ) ( (((word >> 11) & 0x1F) << 3) | (((word >> 13) & 0x7) << 0) | \
|
||||
(((word >> 5) & 0x3F) << 10) | (((word >> 9) & 0x3) << 8) | \
|
||||
(((word >> 0) & 0x1F) << 19) | (((word >> 2) & 0x7) << 16) | \
|
||||
0xFF000000 )
|
||||
|
||||
#define ARGB4444_32( word ) ( (((word >> 12) & 0xF) << 28) | (((word >> 12) & 0xF) << 24) | \
|
||||
(((word >> 8) & 0xF) << 4) | (((word >> 8) & 0xF) << 0) | \
|
||||
(((word >> 4) & 0xF) << 12) | (((word >> 4) & 0xF) << 8) | \
|
||||
(((word >> 0) & 0xF) << 20) | (((word >> 0) & 0xF) << 16) )
|
||||
|
||||
#define ARGB8888_32( word ) ( ((word >> 0) & 0xFF000000) | (((word >> 16) & 0xFF) << 0) | (((word >> 8) & 0xFF) << 8) | ((word & 0xFF) << 16) )
|
||||
|
||||
inline static u32 YUV422(s32 Y,s32 Yu,s32 Yv)
|
||||
template<typename Packer>
|
||||
inline static u32 YUV422(s32 Y, s32 Yu, s32 Yv)
|
||||
{
|
||||
Yu-=128;
|
||||
Yv-=128;
|
||||
Yu -= 128;
|
||||
Yv -= 128;
|
||||
|
||||
s32 R = Y + Yv*11/8; // Y + (Yv-128) * (11/8) ?
|
||||
s32 G = Y - (Yu*11 + Yv*22)/32; // Y - (Yu-128) * (11/8) * 0.25 - (Yv-128) * (11/8) * 0.5 ?
|
||||
s32 B = Y + Yu*110/64; // Y + (Yu-128) * (11/8) * 1.25 ?
|
||||
s32 R = Y + Yv * 11 / 8; // Y + (Yv-128) * (11/8) ?
|
||||
s32 G = Y - (Yu * 11 + Yv * 22) / 32; // Y - (Yu-128) * (11/8) * 0.25 - (Yv-128) * (11/8) * 0.5 ?
|
||||
s32 B = Y + Yu * 110 / 64; // Y + (Yu-128) * (11/8) * 1.25 ?
|
||||
|
||||
return clamp(0, 255, R) | (clamp(0, 255, G) << 8) | (clamp(0, 255, B) << 16) | 0xFF000000;
|
||||
return Packer::pack(clamp(0, 255, R), clamp(0, 255, G), clamp(0, 255, B), 0xFF);
|
||||
}
|
||||
|
||||
#define twop(x,y,bcx,bcy) (detwiddle[0][bcy][x]+detwiddle[1][bcx][y])
|
||||
|
||||
//pixel convertors !
|
||||
#define pixelcvt_start_base(name,x,y,type) \
|
||||
struct name \
|
||||
{ \
|
||||
static const u32 xpp=x;\
|
||||
static const u32 ypp=y; \
|
||||
__forceinline static void Convert(PixelBuffer<type>* pb,u8* data) \
|
||||
{
|
||||
template<typename Pixel>
|
||||
struct UnpackerNop {
|
||||
using unpacked_type = Pixel;
|
||||
static Pixel unpack(Pixel word) {
|
||||
return word;
|
||||
}
|
||||
};
|
||||
// ARGB1555 to RGBA5551
|
||||
struct Unpacker1555 {
|
||||
using unpacked_type = u16;
|
||||
static u16 unpack(u16 word) {
|
||||
return ((word >> 15) & 1) | (((word >> 10) & 0x1F) << 11) | (((word >> 5) & 0x1F) << 6) | (((word >> 0) & 0x1F) << 1);
|
||||
}
|
||||
};
|
||||
// ARGB4444 to RGBA4444
|
||||
struct Unpacker4444 {
|
||||
using unpacked_type = u16;
|
||||
static u16 unpack(u16 word) {
|
||||
return (((word >> 0) & 0xF) << 4) | (((word >> 4) & 0xF) << 8) | (((word >> 8) & 0xF) << 12) | (((word >> 12) & 0xF) << 0);
|
||||
}
|
||||
};
|
||||
|
||||
#define pixelcvt_start(name,x,y) pixelcvt_start_base(name, x, y, u16)
|
||||
#define pixelcvt32_start(name,x,y) pixelcvt_start_base(name, x, y, u32)
|
||||
template <typename Packer>
|
||||
struct Unpacker1555_32 {
|
||||
using unpacked_type = u32;
|
||||
static u32 unpack(u16 word) {
|
||||
return Packer::pack(
|
||||
(((word >> 10) & 0x1F) << 3) | ((word >> 12) & 7),
|
||||
(((word >> 5) & 0x1F) << 3) | ((word >> 7) & 7),
|
||||
(((word >> 0) & 0x1F) << 3) | ((word >> 2) & 7),
|
||||
(word & 0x8000) ? 0xFF : 0);
|
||||
}
|
||||
};
|
||||
template <typename Packer>
|
||||
struct Unpacker565_32 {
|
||||
using unpacked_type = u32;
|
||||
static u32 unpack(u16 word) {
|
||||
return Packer::pack(
|
||||
(((word >> 11) & 0x1F) << 3) | ((word >> 13) & 7),
|
||||
(((word >> 5) & 0x3F) << 2) | ((word >> 9) & 3),
|
||||
(((word >> 0) & 0x1F) << 3) | ((word >> 2) & 7),
|
||||
0xFF);
|
||||
}
|
||||
};
|
||||
template <typename Packer>
|
||||
struct Unpacker4444_32 {
|
||||
using unpacked_type = u32;
|
||||
static u32 unpack(u16 word) {
|
||||
return Packer::pack(
|
||||
(((word >> 8) & 0xF) << 4) | ((word >> 8) & 0xF),
|
||||
(((word >> 4) & 0xF) << 4) | ((word >> 4) & 0xF),
|
||||
(((word >> 0) & 0xF) << 4) | ((word >> 0) & 0xF),
|
||||
(((word >> 12) & 0xF) << 4) | ((word >> 12) & 0xF));
|
||||
}
|
||||
};
|
||||
// ARGB8888 to whatever
|
||||
template <typename Packer>
|
||||
struct Unpacker8888 {
|
||||
using unpacked_type = u32;
|
||||
static u32 unpack(u32 word) {
|
||||
return Packer::pack(
|
||||
(word >> 16) & 0xFF,
|
||||
(word >> 8) & 0xFF,
|
||||
(word >> 0) & 0xFF,
|
||||
(word >> 24) & 0xFF);
|
||||
}
|
||||
};
|
||||
|
||||
#define pixelcvt_size_start(name, x, y) template<class pixel_size> \
|
||||
struct name \
|
||||
{ \
|
||||
static const u32 xpp=x;\
|
||||
static const u32 ypp=y; \
|
||||
__forceinline static void Convert(PixelBuffer<pixel_size>* pb,u8* data) \
|
||||
template<typename Unpacker>
|
||||
struct ConvertPlanar
|
||||
{
|
||||
using unpacked_type = typename Unpacker::unpacked_type;
|
||||
static constexpr u32 xpp = 4;
|
||||
static constexpr u32 ypp = 1;
|
||||
static void Convert(PixelBuffer<unpacked_type> *pb, u8 *data)
|
||||
{
|
||||
u16 *p_in = (u16 *)data;
|
||||
pb->prel(0, Unpacker::unpack(p_in[0]));
|
||||
pb->prel(1, Unpacker::unpack(p_in[1]));
|
||||
pb->prel(2, Unpacker::unpack(p_in[2]));
|
||||
pb->prel(3, Unpacker::unpack(p_in[3]));
|
||||
}
|
||||
};
|
||||
|
||||
#define pixelcvt_end } }
|
||||
#define pixelcvt_next(name,x,y) pixelcvt_end; pixelcvt_start(name,x,y)
|
||||
//
|
||||
//Non twiddled
|
||||
//
|
||||
// 16-bit pixel buffer
|
||||
pixelcvt_start(conv565_PL,4,1)
|
||||
template<typename Packer>
|
||||
struct ConvertPlanarYUV
|
||||
{
|
||||
//convert 4x1
|
||||
u16* p_in=(u16*)data;
|
||||
//0,0
|
||||
pb->prel(0,ARGB565(p_in[0]));
|
||||
//1,0
|
||||
pb->prel(1,ARGB565(p_in[1]));
|
||||
//2,0
|
||||
pb->prel(2,ARGB565(p_in[2]));
|
||||
//3,0
|
||||
pb->prel(3,ARGB565(p_in[3]));
|
||||
}
|
||||
pixelcvt_next(conv1555_PL,4,1)
|
||||
using unpacked_type = u32;
|
||||
static constexpr u32 xpp = 4;
|
||||
static constexpr u32 ypp = 1;
|
||||
static void Convert(PixelBuffer<u32> *pb, u8 *data)
|
||||
{
|
||||
//convert 4x1 4444 to 4x1 8888
|
||||
u32 *p_in = (u32 *)data;
|
||||
|
||||
|
||||
s32 Y0 = (p_in[0] >> 8) & 255; //
|
||||
s32 Yu = (p_in[0] >> 0) & 255; //p_in[0]
|
||||
s32 Y1 = (p_in[0] >> 24) & 255; //p_in[3]
|
||||
s32 Yv = (p_in[0] >> 16) & 255; //p_in[2]
|
||||
|
||||
//0,0
|
||||
pb->prel(0, YUV422<Packer>(Y0, Yu, Yv));
|
||||
//1,0
|
||||
pb->prel(1, YUV422<Packer>(Y1, Yu, Yv));
|
||||
|
||||
//next 4 bytes
|
||||
p_in += 1;
|
||||
|
||||
Y0 = (p_in[0] >> 8) & 255; //
|
||||
Yu = (p_in[0] >> 0) & 255; //p_in[0]
|
||||
Y1 = (p_in[0] >> 24) & 255; //p_in[3]
|
||||
Yv = (p_in[0] >> 16) & 255; //p_in[2]
|
||||
|
||||
//0,0
|
||||
pb->prel(2, YUV422<Packer>(Y0, Yu, Yv));
|
||||
//1,0
|
||||
pb->prel(3, YUV422<Packer>(Y1, Yu, Yv));
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Unpacker>
|
||||
struct ConvertTwiddle
|
||||
{
|
||||
//convert 4x1
|
||||
u16* p_in=(u16*)data;
|
||||
//0,0
|
||||
pb->prel(0,ARGB1555(p_in[0]));
|
||||
//1,0
|
||||
pb->prel(1,ARGB1555(p_in[1]));
|
||||
//2,0
|
||||
pb->prel(2,ARGB1555(p_in[2]));
|
||||
//3,0
|
||||
pb->prel(3,ARGB1555(p_in[3]));
|
||||
}
|
||||
pixelcvt_next(conv4444_PL,4,1)
|
||||
using unpacked_type = typename Unpacker::unpacked_type;
|
||||
static constexpr u32 xpp = 2;
|
||||
static constexpr u32 ypp = 2;
|
||||
static void Convert(PixelBuffer<unpacked_type> *pb, u8 *data)
|
||||
{
|
||||
u16 *p_in = (u16 *)data;
|
||||
pb->prel(0, 0, Unpacker::unpack(p_in[0]));
|
||||
pb->prel(0, 1, Unpacker::unpack(p_in[1]));
|
||||
pb->prel(1, 0, Unpacker::unpack(p_in[2]));
|
||||
pb->prel(1, 1, Unpacker::unpack(p_in[3]));
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Packer>
|
||||
struct ConvertTwiddleYUV
|
||||
{
|
||||
//convert 4x1
|
||||
u16* p_in=(u16*)data;
|
||||
//0,0
|
||||
pb->prel(0,ARGB4444(p_in[0]));
|
||||
//1,0
|
||||
pb->prel(1,ARGB4444(p_in[1]));
|
||||
//2,0
|
||||
pb->prel(2,ARGB4444(p_in[2]));
|
||||
//3,0
|
||||
pb->prel(3,ARGB4444(p_in[3]));
|
||||
}
|
||||
pixelcvt_end;
|
||||
using unpacked_type = u32;
|
||||
static constexpr u32 xpp = 2;
|
||||
static constexpr u32 ypp = 2;
|
||||
static void Convert(PixelBuffer<u32> *pb, u8 *data)
|
||||
{
|
||||
//convert 4x1 4444 to 4x1 8888
|
||||
u16* p_in = (u16 *)data;
|
||||
|
||||
// 32-bit pixel buffer
|
||||
pixelcvt32_start(conv565_PL32,4,1)
|
||||
s32 Y0 = (p_in[0] >> 8) & 255; //
|
||||
s32 Yu = (p_in[0] >> 0) & 255; //p_in[0]
|
||||
s32 Y1 = (p_in[2] >> 8) & 255; //p_in[3]
|
||||
s32 Yv = (p_in[2] >> 0) & 255; //p_in[2]
|
||||
|
||||
//0,0
|
||||
pb->prel(0, 0, YUV422<Packer>(Y0, Yu, Yv));
|
||||
//1,0
|
||||
pb->prel(1, 0, YUV422<Packer>(Y1, Yu, Yv));
|
||||
|
||||
//next 4 bytes
|
||||
//p_in+=2;
|
||||
|
||||
Y0 = (p_in[1] >> 8) & 255; //
|
||||
Yu = (p_in[1] >> 0) & 255; //p_in[0]
|
||||
Y1 = (p_in[3] >> 8) & 255; //p_in[3]
|
||||
Yv = (p_in[3] >> 0) & 255; //p_in[2]
|
||||
|
||||
//0,1
|
||||
pb->prel(0, 1, YUV422<Packer>(Y0, Yu, Yv));
|
||||
//1,1
|
||||
pb->prel(1, 1, YUV422<Packer>(Y1, Yu, Yv));
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Pixel>
|
||||
struct UnpackerPalToRgb {
|
||||
using unpacked_type = Pixel;
|
||||
static Pixel unpack(u8 col)
|
||||
{
|
||||
u32 *pal = sizeof(Pixel) == 2 ? &palette16_ram[palette_index] : &palette32_ram[palette_index];
|
||||
return pal[col];
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Unpacker>
|
||||
struct ConvertTwiddlePal4
|
||||
{
|
||||
//convert 4x1
|
||||
u16* p_in=(u16*)data;
|
||||
//0,0
|
||||
pb->prel(0,ARGB565_32(p_in[0]));
|
||||
//1,0
|
||||
pb->prel(1,ARGB565_32(p_in[1]));
|
||||
//2,0
|
||||
pb->prel(2,ARGB565_32(p_in[2]));
|
||||
//3,0
|
||||
pb->prel(3,ARGB565_32(p_in[3]));
|
||||
}
|
||||
pixelcvt_end;
|
||||
pixelcvt32_start(conv1555_PL32,4,1)
|
||||
using unpacked_type = typename Unpacker::unpacked_type;
|
||||
static constexpr u32 xpp = 4;
|
||||
static constexpr u32 ypp = 4;
|
||||
static void Convert(PixelBuffer<unpacked_type> *pb, u8 *data)
|
||||
{
|
||||
u8 *p_in = (u8 *)data;
|
||||
|
||||
pb->prel(0, 0, Unpacker::unpack(p_in[0] & 0xF));
|
||||
pb->prel(0, 1, Unpacker::unpack((p_in[0] >> 4) & 0xF)); p_in++;
|
||||
pb->prel(1, 0, Unpacker::unpack(p_in[0] & 0xF));
|
||||
pb->prel(1, 1, Unpacker::unpack((p_in[0] >> 4) & 0xF)); p_in++;
|
||||
|
||||
pb->prel(0, 2, Unpacker::unpack(p_in[0] & 0xF));
|
||||
pb->prel(0, 3, Unpacker::unpack((p_in[0] >> 4) & 0xF)); p_in++;
|
||||
pb->prel(1, 2, Unpacker::unpack(p_in[0] & 0xF));
|
||||
pb->prel(1, 3, Unpacker::unpack((p_in[0] >> 4) & 0xF)); p_in++;
|
||||
|
||||
pb->prel(2, 0, Unpacker::unpack(p_in[0] & 0xF));
|
||||
pb->prel(2, 1, Unpacker::unpack((p_in[0] >> 4) & 0xF)); p_in++;
|
||||
pb->prel(3, 0, Unpacker::unpack(p_in[0] & 0xF));
|
||||
pb->prel(3, 1, Unpacker::unpack((p_in[0] >> 4) & 0xF)); p_in++;
|
||||
|
||||
pb->prel(2, 2, Unpacker::unpack(p_in[0] & 0xF));
|
||||
pb->prel(2, 3, Unpacker::unpack((p_in[0] >> 4) & 0xF)); p_in++;
|
||||
pb->prel(3, 2, Unpacker::unpack(p_in[0] & 0xF));
|
||||
pb->prel(3, 3, Unpacker::unpack((p_in[0] >> 4) & 0xF)); p_in++;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Unpacker>
|
||||
struct ConvertTwiddlePal8
|
||||
{
|
||||
//convert 4x1
|
||||
u16* p_in=(u16*)data;
|
||||
//0,0
|
||||
pb->prel(0,ARGB1555_32(p_in[0]));
|
||||
//1,0
|
||||
pb->prel(1,ARGB1555_32(p_in[1]));
|
||||
//2,0
|
||||
pb->prel(2,ARGB1555_32(p_in[2]));
|
||||
//3,0
|
||||
pb->prel(3,ARGB1555_32(p_in[3]));
|
||||
}
|
||||
pixelcvt_end;
|
||||
pixelcvt32_start(conv4444_PL32,4,1)
|
||||
{
|
||||
//convert 4x1
|
||||
u16* p_in=(u16*)data;
|
||||
//0,0
|
||||
pb->prel(0,ARGB4444_32(p_in[0]));
|
||||
//1,0
|
||||
pb->prel(1,ARGB4444_32(p_in[1]));
|
||||
//2,0
|
||||
pb->prel(2,ARGB4444_32(p_in[2]));
|
||||
//3,0
|
||||
pb->prel(3,ARGB4444_32(p_in[3]));
|
||||
}
|
||||
pixelcvt_end;
|
||||
pixelcvt32_start(convYUV_PL,4,1)
|
||||
{
|
||||
//convert 4x1 4444 to 4x1 8888
|
||||
u32* p_in=(u32*)data;
|
||||
using unpacked_type = typename Unpacker::unpacked_type;
|
||||
static constexpr u32 xpp = 2;
|
||||
static constexpr u32 ypp = 4;
|
||||
static void Convert(PixelBuffer<unpacked_type> *pb, u8 *data)
|
||||
{
|
||||
u8* p_in = (u8 *)data;
|
||||
|
||||
pb->prel(0, 0, Unpacker::unpack(p_in[0])); p_in++;
|
||||
pb->prel(0, 1, Unpacker::unpack(p_in[0])); p_in++;
|
||||
pb->prel(1, 0, Unpacker::unpack(p_in[0])); p_in++;
|
||||
pb->prel(1, 1, Unpacker::unpack(p_in[0])); p_in++;
|
||||
|
||||
s32 Y0 = (p_in[0]>>8) &255; //
|
||||
s32 Yu = (p_in[0]>>0) &255; //p_in[0]
|
||||
s32 Y1 = (p_in[0]>>24) &255; //p_in[3]
|
||||
s32 Yv = (p_in[0]>>16) &255; //p_in[2]
|
||||
|
||||
//0,0
|
||||
pb->prel(0,YUV422(Y0,Yu,Yv));
|
||||
//1,0
|
||||
pb->prel(1,YUV422(Y1,Yu,Yv));
|
||||
|
||||
//next 4 bytes
|
||||
p_in+=1;
|
||||
|
||||
Y0 = (p_in[0]>>8) &255; //
|
||||
Yu = (p_in[0]>>0) &255; //p_in[0]
|
||||
Y1 = (p_in[0]>>24) &255; //p_in[3]
|
||||
Yv = (p_in[0]>>16) &255; //p_in[2]
|
||||
|
||||
//0,0
|
||||
pb->prel(2,YUV422(Y0,Yu,Yv));
|
||||
//1,0
|
||||
pb->prel(3,YUV422(Y1,Yu,Yv));
|
||||
}
|
||||
pixelcvt_end;
|
||||
|
||||
//
|
||||
//twiddled
|
||||
//
|
||||
// 16-bit pixel buffer
|
||||
pixelcvt_start(conv565_TW,2,2)
|
||||
{
|
||||
//convert 4x1 565 to 4x1 8888
|
||||
u16* p_in=(u16*)data;
|
||||
//0,0
|
||||
pb->prel(0,0,ARGB565(p_in[0]));
|
||||
//0,1
|
||||
pb->prel(0,1,ARGB565(p_in[1]));
|
||||
//1,0
|
||||
pb->prel(1,0,ARGB565(p_in[2]));
|
||||
//1,1
|
||||
pb->prel(1,1,ARGB565(p_in[3]));
|
||||
}
|
||||
pixelcvt_next(conv1555_TW,2,2)
|
||||
{
|
||||
//convert 4x1 565 to 4x1 8888
|
||||
u16* p_in=(u16*)data;
|
||||
//0,0
|
||||
pb->prel(0,0,ARGB1555(p_in[0]));
|
||||
//0,1
|
||||
pb->prel(0,1,ARGB1555(p_in[1]));
|
||||
//1,0
|
||||
pb->prel(1,0,ARGB1555(p_in[2]));
|
||||
//1,1
|
||||
pb->prel(1,1,ARGB1555(p_in[3]));
|
||||
}
|
||||
pixelcvt_next(conv4444_TW,2,2)
|
||||
{
|
||||
//convert 4x1 565 to 4x1 8888
|
||||
u16* p_in=(u16*)data;
|
||||
//0,0
|
||||
pb->prel(0,0,ARGB4444(p_in[0]));
|
||||
//0,1
|
||||
pb->prel(0,1,ARGB4444(p_in[1]));
|
||||
//1,0
|
||||
pb->prel(1,0,ARGB4444(p_in[2]));
|
||||
//1,1
|
||||
pb->prel(1,1,ARGB4444(p_in[3]));
|
||||
}
|
||||
pixelcvt_end;
|
||||
|
||||
// 32-bit pixel buffer
|
||||
pixelcvt32_start(conv565_TW32,2,2)
|
||||
{
|
||||
//convert 4x1 565 to 4x1 8888
|
||||
u16* p_in=(u16*)data;
|
||||
//0,0
|
||||
pb->prel(0,0,ARGB565_32(p_in[0]));
|
||||
//0,1
|
||||
pb->prel(0,1,ARGB565_32(p_in[1]));
|
||||
//1,0
|
||||
pb->prel(1,0,ARGB565_32(p_in[2]));
|
||||
//1,1
|
||||
pb->prel(1,1,ARGB565_32(p_in[3]));
|
||||
}
|
||||
pixelcvt_end;
|
||||
pixelcvt32_start(conv1555_TW32,2,2)
|
||||
{
|
||||
//convert 4x1 565 to 4x1 8888
|
||||
u16* p_in=(u16*)data;
|
||||
//0,0
|
||||
pb->prel(0,0,ARGB1555_32(p_in[0]));
|
||||
//0,1
|
||||
pb->prel(0,1,ARGB1555_32(p_in[1]));
|
||||
//1,0
|
||||
pb->prel(1,0,ARGB1555_32(p_in[2]));
|
||||
//1,1
|
||||
pb->prel(1,1,ARGB1555_32(p_in[3]));
|
||||
}
|
||||
pixelcvt_end;
|
||||
pixelcvt32_start(conv4444_TW32,2,2)
|
||||
{
|
||||
//convert 4x1 565 to 4x1 8888
|
||||
u16* p_in=(u16*)data;
|
||||
//0,0
|
||||
pb->prel(0,0,ARGB4444_32(p_in[0]));
|
||||
//0,1
|
||||
pb->prel(0,1,ARGB4444_32(p_in[1]));
|
||||
//1,0
|
||||
pb->prel(1,0,ARGB4444_32(p_in[2]));
|
||||
//1,1
|
||||
pb->prel(1,1,ARGB4444_32(p_in[3]));
|
||||
}
|
||||
pixelcvt_end;
|
||||
|
||||
pixelcvt32_start(convYUV_TW,2,2)
|
||||
{
|
||||
//convert 4x1 4444 to 4x1 8888
|
||||
u16* p_in=(u16*)data;
|
||||
|
||||
|
||||
s32 Y0 = (p_in[0]>>8) &255; //
|
||||
s32 Yu = (p_in[0]>>0) &255; //p_in[0]
|
||||
s32 Y1 = (p_in[2]>>8) &255; //p_in[3]
|
||||
s32 Yv = (p_in[2]>>0) &255; //p_in[2]
|
||||
|
||||
//0,0
|
||||
pb->prel(0,0,YUV422(Y0,Yu,Yv));
|
||||
//1,0
|
||||
pb->prel(1,0,YUV422(Y1,Yu,Yv));
|
||||
|
||||
//next 4 bytes
|
||||
//p_in+=2;
|
||||
|
||||
Y0 = (p_in[1]>>8) &255; //
|
||||
Yu = (p_in[1]>>0) &255; //p_in[0]
|
||||
Y1 = (p_in[3]>>8) &255; //p_in[3]
|
||||
Yv = (p_in[3]>>0) &255; //p_in[2]
|
||||
|
||||
//0,1
|
||||
pb->prel(0,1,YUV422(Y0,Yu,Yv));
|
||||
//1,1
|
||||
pb->prel(1,1,YUV422(Y1,Yu,Yv));
|
||||
}
|
||||
pixelcvt_end;
|
||||
|
||||
// 16-bit && 32-bit pixel buffers
|
||||
pixelcvt_size_start(convPAL4_TW,4,4)
|
||||
{
|
||||
u8* p_in=(u8*)data;
|
||||
u32* pal= sizeof(pixel_size) == 2 ? &palette16_ram[palette_index] : &palette32_ram[palette_index];
|
||||
|
||||
pb->prel(0,0,pal[p_in[0]&0xF]);
|
||||
pb->prel(0,1,pal[(p_in[0]>>4)&0xF]);p_in++;
|
||||
pb->prel(1,0,pal[p_in[0]&0xF]);
|
||||
pb->prel(1,1,pal[(p_in[0]>>4)&0xF]);p_in++;
|
||||
|
||||
pb->prel(0,2,pal[p_in[0]&0xF]);
|
||||
pb->prel(0,3,pal[(p_in[0]>>4)&0xF]);p_in++;
|
||||
pb->prel(1,2,pal[p_in[0]&0xF]);
|
||||
pb->prel(1,3,pal[(p_in[0]>>4)&0xF]);p_in++;
|
||||
|
||||
pb->prel(2,0,pal[p_in[0]&0xF]);
|
||||
pb->prel(2,1,pal[(p_in[0]>>4)&0xF]);p_in++;
|
||||
pb->prel(3,0,pal[p_in[0]&0xF]);
|
||||
pb->prel(3,1,pal[(p_in[0]>>4)&0xF]);p_in++;
|
||||
|
||||
pb->prel(2,2,pal[p_in[0]&0xF]);
|
||||
pb->prel(2,3,pal[(p_in[0]>>4)&0xF]);p_in++;
|
||||
pb->prel(3,2,pal[p_in[0]&0xF]);
|
||||
pb->prel(3,3,pal[(p_in[0]>>4)&0xF]);p_in++;
|
||||
}
|
||||
pixelcvt_end;
|
||||
|
||||
// Palette 4bpp -> 8bpp
|
||||
pixelcvt_size_start(convPAL4PT_TW, 4, 4)
|
||||
{
|
||||
u8* p_in = (u8 *)data;
|
||||
|
||||
pb->prel(0, 0, p_in[0] & 0xF);
|
||||
pb->prel(0, 1, (p_in[0] >> 4) & 0xF); p_in++;
|
||||
pb->prel(1, 0, p_in[0] & 0xF);
|
||||
pb->prel(1, 1, (p_in[0] >> 4) & 0xF); p_in++;
|
||||
|
||||
pb->prel(0, 2, p_in[0] & 0xF);
|
||||
pb->prel(0, 3, (p_in[0] >> 4) & 0xF); p_in++;
|
||||
pb->prel(1, 2, p_in[0] & 0xF);
|
||||
pb->prel(1, 3, (p_in[0] >> 4) & 0xF); p_in++;
|
||||
|
||||
pb->prel(2, 0, p_in[0] & 0xF);
|
||||
pb->prel(2, 1, (p_in[0] >> 4) & 0xF); p_in++;
|
||||
pb->prel(3, 0, p_in[0] & 0xF);
|
||||
pb->prel(3, 1, (p_in[0] >> 4) & 0xF); p_in++;
|
||||
|
||||
pb->prel(2, 2, p_in[0] & 0xF);
|
||||
pb->prel(2, 3, (p_in[0] >> 4) & 0xF); p_in++;
|
||||
pb->prel(3, 2, p_in[0] & 0xF);
|
||||
pb->prel(3, 3, (p_in[0] >> 4) & 0xF); p_in++;
|
||||
}
|
||||
pixelcvt_end;
|
||||
|
||||
pixelcvt_size_start(convPAL8_TW,2,4)
|
||||
{
|
||||
u8* p_in=(u8*)data;
|
||||
u32* pal= sizeof(pixel_size) == 2 ? &palette16_ram[palette_index] : &palette32_ram[palette_index];
|
||||
|
||||
pb->prel(0,0,pal[p_in[0]]);p_in++;
|
||||
pb->prel(0,1,pal[p_in[0]]);p_in++;
|
||||
pb->prel(1,0,pal[p_in[0]]);p_in++;
|
||||
pb->prel(1,1,pal[p_in[0]]);p_in++;
|
||||
|
||||
pb->prel(0,2,pal[p_in[0]]);p_in++;
|
||||
pb->prel(0,3,pal[p_in[0]]);p_in++;
|
||||
pb->prel(1,2,pal[p_in[0]]);p_in++;
|
||||
pb->prel(1,3,pal[p_in[0]]);p_in++;
|
||||
}
|
||||
pixelcvt_end;
|
||||
|
||||
// Palette 8bpp -> 8bpp (untwiddle only)
|
||||
pixelcvt_size_start(convPAL8PT_TW, 2, 4)
|
||||
{
|
||||
u8* p_in = (u8 *)data;
|
||||
|
||||
pb->prel(0, 0, p_in[0]); p_in++;
|
||||
pb->prel(0, 1, p_in[0]); p_in++;
|
||||
pb->prel(1, 0, p_in[0]); p_in++;
|
||||
pb->prel(1, 1, p_in[0]); p_in++;
|
||||
|
||||
pb->prel(0, 2, p_in[0]); p_in++;
|
||||
pb->prel(0, 3, p_in[0]); p_in++;
|
||||
pb->prel(1, 2, p_in[0]); p_in++;
|
||||
pb->prel(1, 3, p_in[0]); p_in++;
|
||||
}
|
||||
pixelcvt_end;
|
||||
|
||||
pb->prel(0, 2, Unpacker::unpack(p_in[0])); p_in++;
|
||||
pb->prel(0, 3, Unpacker::unpack(p_in[0])); p_in++;
|
||||
pb->prel(1, 2, Unpacker::unpack(p_in[0])); p_in++;
|
||||
pb->prel(1, 3, Unpacker::unpack(p_in[0])); p_in++;
|
||||
}
|
||||
};
|
||||
|
||||
//handler functions
|
||||
template<class PixelConvertor, class pixel_type>
|
||||
void texture_PL(PixelBuffer<pixel_type>* pb,u8* p_in,u32 Width,u32 Height)
|
||||
template<class PixelConvertor>
|
||||
void texture_PL(PixelBuffer<typename PixelConvertor::unpacked_type>* pb,u8* p_in,u32 Width,u32 Height)
|
||||
{
|
||||
pb->amove(0,0);
|
||||
|
||||
@@ -541,8 +412,8 @@ void texture_PL(PixelBuffer<pixel_type>* pb,u8* p_in,u32 Width,u32 Height)
|
||||
}
|
||||
}
|
||||
|
||||
template<class PixelConvertor, class pixel_type>
|
||||
void texture_TW(PixelBuffer<pixel_type>* pb,u8* p_in,u32 Width,u32 Height)
|
||||
template<class PixelConvertor>
|
||||
void texture_TW(PixelBuffer<typename PixelConvertor::unpacked_type>* pb,u8* p_in,u32 Width,u32 Height)
|
||||
{
|
||||
pb->amove(0, 0);
|
||||
|
||||
@@ -564,8 +435,8 @@ void texture_TW(PixelBuffer<pixel_type>* pb,u8* p_in,u32 Width,u32 Height)
|
||||
}
|
||||
}
|
||||
|
||||
template<class PixelConvertor, class pixel_type>
|
||||
void texture_VQ(PixelBuffer<pixel_type>* pb,u8* p_in,u32 Width,u32 Height)
|
||||
template<class PixelConvertor>
|
||||
void texture_VQ(PixelBuffer<typename PixelConvertor::unpacked_type>* pb,u8* p_in,u32 Width,u32 Height)
|
||||
{
|
||||
p_in += 256 * 4 * 2; // Skip VQ codebook
|
||||
pb->amove(0, 0);
|
||||
@@ -587,51 +458,98 @@ void texture_VQ(PixelBuffer<pixel_type>* pb,u8* p_in,u32 Width,u32 Height)
|
||||
}
|
||||
}
|
||||
|
||||
typedef void (*TexConvFP)(PixelBuffer<u16> *pb, u8 *p_in, u32 width, u32 height);
|
||||
typedef void (*TexConvFP8)(PixelBuffer<u8> *pb, u8 *p_in, u32 width, u32 height);
|
||||
typedef void (*TexConvFP32)(PixelBuffer<u32> *pb, u8 *p_in, u32 width, u32 height);
|
||||
|
||||
//Planar
|
||||
#define tex565_PL texture_PL<conv565_PL, u16>
|
||||
#define tex1555_PL texture_PL<conv1555_PL, u16>
|
||||
#define tex4444_PL texture_PL<conv4444_PL, u16>
|
||||
#define texYUV422_PL texture_PL<convYUV_PL, u32>
|
||||
#define texBMP_PL tex4444_PL
|
||||
|
||||
#define tex565_PL32 texture_PL<conv565_PL32, u32>
|
||||
#define tex1555_PL32 texture_PL<conv1555_PL32, u32>
|
||||
#define tex4444_PL32 texture_PL<conv4444_PL32, u32>
|
||||
|
||||
constexpr TexConvFP tex565_PL = texture_PL<ConvertPlanar<UnpackerNop<u16>>>;
|
||||
//Twiddle
|
||||
#define tex565_TW texture_TW<conv565_TW, u16>
|
||||
#define tex1555_TW texture_TW<conv1555_TW, u16>
|
||||
#define tex4444_TW texture_TW<conv4444_TW, u16>
|
||||
#define texYUV422_TW texture_TW<convYUV_TW, u32>
|
||||
#define texBMP_TW tex4444_TW
|
||||
#define texPAL4_TW texture_TW<convPAL4_TW<u16>, u16>
|
||||
#define texPAL8_TW texture_TW<convPAL8_TW<u16>, u16>
|
||||
#define texPAL4_TW32 texture_TW<convPAL4_TW<u32>, u32>
|
||||
#define texPAL8_TW32 texture_TW<convPAL8_TW<u32>, u32>
|
||||
#define texPAL4PT_TW texture_TW<convPAL4PT_TW<u8>, u8>
|
||||
#define texPAL8PT_TW texture_TW<convPAL8PT_TW<u8>, u8>
|
||||
|
||||
#define tex565_TW32 texture_TW<conv565_TW32, u32>
|
||||
#define tex1555_TW32 texture_TW<conv1555_TW32, u32>
|
||||
#define tex4444_TW32 texture_TW<conv4444_TW32, u32>
|
||||
|
||||
constexpr TexConvFP tex565_TW = texture_TW<ConvertTwiddle<UnpackerNop<u16>>>;
|
||||
// Palette
|
||||
constexpr TexConvFP texPAL4_TW = texture_TW<ConvertTwiddlePal4<UnpackerPalToRgb<u16>>>;
|
||||
constexpr TexConvFP texPAL8_TW = texture_TW<ConvertTwiddlePal8<UnpackerPalToRgb<u16>>>;
|
||||
constexpr TexConvFP32 texPAL4_TW32 = texture_TW<ConvertTwiddlePal4<UnpackerPalToRgb<u32>>>;
|
||||
constexpr TexConvFP32 texPAL8_TW32 = texture_TW<ConvertTwiddlePal8<UnpackerPalToRgb<u32>>>;
|
||||
constexpr TexConvFP8 texPAL4PT_TW = texture_TW<ConvertTwiddlePal4<UnpackerNop<u8>>>;
|
||||
constexpr TexConvFP8 texPAL8PT_TW = texture_TW<ConvertTwiddlePal8<UnpackerNop<u8>>>;
|
||||
//VQ
|
||||
#define tex565_VQ texture_VQ<conv565_TW, u16>
|
||||
#define tex1555_VQ texture_VQ<conv1555_TW, u16>
|
||||
#define tex4444_VQ texture_VQ<conv4444_TW, u16>
|
||||
#define texYUV422_VQ texture_VQ<convYUV_TW, u32>
|
||||
#define texBMP_VQ tex4444_VQ
|
||||
constexpr TexConvFP tex565_VQ = texture_VQ<ConvertTwiddle<UnpackerNop<u16>>>;
|
||||
// According to the documentation, a texture cannot be compressed and use
|
||||
// a palette at the same time. However the hardware displays them
|
||||
// just fine.
|
||||
#define texPAL4_VQ texture_VQ<convPAL4_TW<u16>, u16>
|
||||
#define texPAL8_VQ texture_VQ<convPAL8_TW<u16>, u16>
|
||||
constexpr TexConvFP texPAL4_VQ = texture_VQ<ConvertTwiddlePal4<UnpackerPalToRgb<u16>>>;
|
||||
constexpr TexConvFP texPAL8_VQ = texture_VQ<ConvertTwiddlePal8<UnpackerPalToRgb<u16>>>;
|
||||
constexpr TexConvFP32 texPAL4_VQ32 = texture_VQ<ConvertTwiddlePal4<UnpackerPalToRgb<u32>>>;
|
||||
constexpr TexConvFP32 texPAL8_VQ32 = texture_VQ<ConvertTwiddlePal8<UnpackerPalToRgb<u32>>>;
|
||||
|
||||
#define tex565_VQ32 texture_VQ<conv565_TW32, u32>
|
||||
#define tex1555_VQ32 texture_VQ<conv1555_TW32, u32>
|
||||
#define tex4444_VQ32 texture_VQ<conv4444_TW32, u32>
|
||||
#define texPAL4_VQ32 texture_VQ<convPAL4_TW<u32>, u32>
|
||||
#define texPAL8_VQ32 texture_VQ<convPAL8_TW<u32>, u32>
|
||||
namespace opengl {
|
||||
// Open GL
|
||||
|
||||
//Planar
|
||||
constexpr TexConvFP tex1555_PL = texture_PL<ConvertPlanar<Unpacker1555>>;
|
||||
constexpr TexConvFP tex4444_PL = texture_PL<ConvertPlanar<Unpacker4444>>;
|
||||
constexpr TexConvFP texBMP_PL = tex4444_PL;
|
||||
constexpr TexConvFP32 texYUV422_PL = texture_PL<ConvertPlanarYUV<RGBAPacker>>;
|
||||
|
||||
constexpr TexConvFP32 tex565_PL32 = texture_PL<ConvertPlanar<Unpacker565_32<RGBAPacker>>>;
|
||||
constexpr TexConvFP32 tex1555_PL32 = texture_PL<ConvertPlanar<Unpacker1555_32<RGBAPacker>>>;
|
||||
constexpr TexConvFP32 tex4444_PL32 = texture_PL<ConvertPlanar<Unpacker4444_32<RGBAPacker>>>;
|
||||
|
||||
//Twiddle
|
||||
constexpr TexConvFP tex1555_TW = texture_TW<ConvertTwiddle<Unpacker1555>>;
|
||||
constexpr TexConvFP tex4444_TW = texture_TW<ConvertTwiddle<Unpacker4444>>;
|
||||
constexpr TexConvFP texBMP_TW = tex4444_TW;
|
||||
constexpr TexConvFP32 texYUV422_TW = texture_TW<ConvertTwiddleYUV<RGBAPacker>>;
|
||||
|
||||
constexpr TexConvFP32 tex565_TW32 = texture_TW<ConvertTwiddle<Unpacker565_32<RGBAPacker>>>;
|
||||
constexpr TexConvFP32 tex1555_TW32 = texture_TW<ConvertTwiddle<Unpacker1555_32<RGBAPacker>>>;
|
||||
constexpr TexConvFP32 tex4444_TW32 = texture_TW<ConvertTwiddle<Unpacker4444_32<RGBAPacker>>>;
|
||||
|
||||
//VQ
|
||||
constexpr TexConvFP tex1555_VQ = texture_VQ<ConvertTwiddle<Unpacker1555>>;
|
||||
constexpr TexConvFP tex4444_VQ = texture_VQ<ConvertTwiddle<Unpacker4444>>;
|
||||
constexpr TexConvFP texBMP_VQ = tex4444_VQ;
|
||||
constexpr TexConvFP32 texYUV422_VQ = texture_VQ<ConvertTwiddleYUV<RGBAPacker>>;
|
||||
|
||||
constexpr TexConvFP32 tex565_VQ32 = texture_VQ<ConvertTwiddle<Unpacker565_32<RGBAPacker>>>;
|
||||
constexpr TexConvFP32 tex1555_VQ32 = texture_VQ<ConvertTwiddle<Unpacker1555_32<RGBAPacker>>>;
|
||||
constexpr TexConvFP32 tex4444_VQ32 = texture_VQ<ConvertTwiddle<Unpacker4444_32<RGBAPacker>>>;
|
||||
}
|
||||
|
||||
namespace directx {
|
||||
// DirectX
|
||||
|
||||
//Planar
|
||||
constexpr TexConvFP tex1555_PL = texture_PL<ConvertPlanar<UnpackerNop<u16>>>;
|
||||
constexpr TexConvFP tex4444_PL = texture_PL<ConvertPlanar<UnpackerNop<u16>>>;
|
||||
constexpr TexConvFP texBMP_PL = tex4444_PL;
|
||||
constexpr TexConvFP32 texYUV422_PL = texture_PL<ConvertPlanarYUV<BGRAPacker>>;
|
||||
|
||||
constexpr TexConvFP32 tex565_PL32 = texture_PL<ConvertPlanar<Unpacker565_32<BGRAPacker>>>;
|
||||
constexpr TexConvFP32 tex1555_PL32 = texture_PL<ConvertPlanar<Unpacker1555_32<BGRAPacker>>>;
|
||||
constexpr TexConvFP32 tex4444_PL32 = texture_PL<ConvertPlanar<Unpacker4444_32<BGRAPacker>>>;
|
||||
|
||||
//Twiddle
|
||||
constexpr TexConvFP tex1555_TW = texture_TW<ConvertTwiddle<UnpackerNop<u16>>>;
|
||||
constexpr TexConvFP tex4444_TW = texture_TW<ConvertTwiddle<UnpackerNop<u16>>>;
|
||||
constexpr TexConvFP texBMP_TW = tex4444_TW;
|
||||
constexpr TexConvFP32 texYUV422_TW = texture_TW<ConvertTwiddleYUV<BGRAPacker>>;
|
||||
|
||||
constexpr TexConvFP32 tex565_TW32 = texture_TW<ConvertTwiddle<Unpacker565_32<BGRAPacker>>>;
|
||||
constexpr TexConvFP32 tex1555_TW32 = texture_TW<ConvertTwiddle<Unpacker1555_32<BGRAPacker>>>;
|
||||
constexpr TexConvFP32 tex4444_TW32 = texture_TW<ConvertTwiddle<Unpacker4444_32<BGRAPacker>>>;
|
||||
|
||||
//VQ
|
||||
constexpr TexConvFP tex1555_VQ = texture_VQ<ConvertTwiddle<UnpackerNop<u16>>>;
|
||||
constexpr TexConvFP tex4444_VQ = texture_VQ<ConvertTwiddle<UnpackerNop<u16>>>;
|
||||
constexpr TexConvFP texBMP_VQ = tex4444_VQ;
|
||||
constexpr TexConvFP32 texYUV422_VQ = texture_VQ<ConvertTwiddleYUV<BGRAPacker>>;
|
||||
|
||||
constexpr TexConvFP32 tex565_VQ32 = texture_VQ<ConvertTwiddle<Unpacker565_32<BGRAPacker>>>;
|
||||
constexpr TexConvFP32 tex1555_VQ32 = texture_VQ<ConvertTwiddle<Unpacker1555_32<BGRAPacker>>>;
|
||||
constexpr TexConvFP32 tex4444_VQ32 = texture_VQ<ConvertTwiddle<Unpacker4444_32<BGRAPacker>>>;
|
||||
}
|
||||
|
||||
struct vram_block
|
||||
{
|
||||
@@ -646,52 +564,46 @@ struct vram_block
|
||||
class BaseTextureCacheData;
|
||||
|
||||
bool VramLockedWriteOffset(size_t offset);
|
||||
void libCore_vramlock_Unlock_block(vram_block *block);
|
||||
void libCore_vramlock_Lock(u32 start_offset, u32 end_offset, BaseTextureCacheData *texture);
|
||||
|
||||
void UpscalexBRZ(int factor, u32* source, u32* dest, int width, int height, bool has_alpha);
|
||||
|
||||
struct PvrTexInfo;
|
||||
template <class pixel_type> class PixelBuffer;
|
||||
typedef void TexConvFP(PixelBuffer<u16>* pb,u8* p_in,u32 Width,u32 Height);
|
||||
typedef void TexConvFP8(PixelBuffer<u8>* pb, u8* p_in, u32 Width, u32 Height);
|
||||
typedef void TexConvFP32(PixelBuffer<u32>* pb,u8* p_in,u32 Width,u32 Height);
|
||||
enum class TextureType { _565, _5551, _4444, _8888, _8 };
|
||||
|
||||
class BaseTextureCacheData
|
||||
{
|
||||
public:
|
||||
TSP tsp; //dreamcast texture parameters
|
||||
TSP tsp; //dreamcast texture parameters
|
||||
TCW tcw;
|
||||
|
||||
// Decoded/filtered texture format
|
||||
TextureType tex_type;
|
||||
u32 sa_tex; // texture data start address in vram
|
||||
|
||||
u32 sa; //pixel data start address in vram (might be offset for mipmaps/etc)
|
||||
u32 sa_tex; //texture data start address in vram
|
||||
u32 w,h; //width & height of the texture
|
||||
u32 size; //size, in bytes, in vram
|
||||
u32 dirty; // frame number at which texture was overwritten
|
||||
vram_block* lock_block;
|
||||
|
||||
u32 sa; // pixel data start address of max level mipmap
|
||||
u16 width, height; // width & height of the texture
|
||||
u32 size; // size in bytes of max level mipmap in vram
|
||||
|
||||
const PvrTexInfo* tex;
|
||||
TexConvFP *texconv;
|
||||
TexConvFP32 *texconv32;
|
||||
TexConvFP8 *texconv8;
|
||||
|
||||
u32 dirty;
|
||||
vram_block* lock_block;
|
||||
TexConvFP texconv;
|
||||
TexConvFP32 texconv32;
|
||||
TexConvFP8 texconv8;
|
||||
|
||||
u32 Updates;
|
||||
|
||||
u32 palette_index;
|
||||
//used for palette updates
|
||||
u32 palette_hash; // Palette hash at time of last update
|
||||
u32 vq_codebook; // VQ quantizers table for compressed textures
|
||||
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;
|
||||
std::atomic_int custom_load_in_progress;
|
||||
bool gpuPalette;
|
||||
|
||||
void PrintTextureName();
|
||||
virtual std::string GetId() = 0;
|
||||
@@ -748,6 +660,7 @@ public:
|
||||
&& !tcw.MipMapped
|
||||
&& !tcw.VQ_Comp;
|
||||
}
|
||||
static void SetDirectXColorOrder(bool enabled);
|
||||
};
|
||||
|
||||
template<typename Texture>
|
||||
@@ -829,7 +742,9 @@ protected:
|
||||
const TCW TCWTextureCacheMask = { { 0x1FFFFF, 0, 0, 1, 7, 1, 1 } };
|
||||
};
|
||||
|
||||
template<typename Packer = RGBAPacker>
|
||||
void ReadFramebuffer(PixelBuffer<u32>& pb, int& width, int& height);
|
||||
template<int Red = 0, int Green = 1, int Blue = 2, int Alpha = 3>
|
||||
void WriteTextureToVRam(u32 width, u32 height, u8 *data, u16 *dst, u32 fb_w_ctrl = -1, u32 linestride = -1);
|
||||
|
||||
static inline void MakeFogTexture(u8 *tex_data)
|
||||
|
||||
Loaded 100 of 202 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user