71 Commits
Author SHA1 Message Date
vkedwardli a51f310e96 Add volume slider in audio settings (#329)
Use logarithmic volume scale
2021-08-26 13:30:23 +02:00
Flyinghead 89ccdf2814 rend: better fix to force even width rendering 2021-08-26 13:28:13 +02:00
Flyinghead 52af352fcd input: never load mapping file for !remappable controllers
Fixes android on-screen gamepad not working when a (wrong) mapping file
exists for it.

Issue #325
Issue #330
2021-08-26 13:25:18 +02:00
vkedwardli 7a33ae35e0 [macOS] Fix DelayFrameSwapping and optimise Vsync logic (#307)
* Support macOS 10.15 and 11
* Enable VSync option on macOS. Use "swapOnVSync" logic from other wsi
* Limit `mainui_rend_frame()` to 5 iterations max: 4 renders and the final swap
2021-08-24 11:43:19 +02:00
Flyinghead ce58ba3472 pvr: detect swap on FB_R_SOF2 too. Force render res. to even width
Fixes Soul Calibur FPS /2 drop with Delay Frame Swapping on
2021-08-24 11:40:53 +02:00
Flyinghead 43ae2ea5f5 macOS: upgrade SDL to 2.0.16
fixes Xbox series X controller support
2021-08-23 17:56:40 +02:00
scribam 3006cd4f60 .cirrus.yml: update to freebsd-13-0 2021-08-22 11:44:34 +02:00
Flyinghead c27180fb32 android: fix navbar background. Add shortcuts for Coin/Service/Test
Fix black navigation bar background.
Shortcuts for virtual gamepad:
RT + A -> D (Coint)
RT + B -> C (Service)
RT + X -> Z (Test)
Issue #137

Don't deliver mouse clicks if analog triggers or stick are used
2021-08-11 12:58:57 +02:00
Edward Li 6f233462c1 Add missing JITWriteProtect to DSP 2021-08-09 09:02:59 +02:00
scribam fcef404f50 android: update gradle and dependencies 2021-07-30 19:35:07 +02:00
Flyinghead 5ac0e58886 android: mouse move events missing when btn down. Mouse wheel support
Issue #304
2021-07-27 10:32:22 +02:00
vkedwardli a14fc35e47 Support Fast Forward in macOS (#303) 2021-07-26 20:36:14 +02:00
vkedwardli e4d9be86b4 Fix cmake macOS ARM not building (#301)
set `CMAKE_OSX_ARCHITECTURES` as Cache Entry
2021-07-24 15:52:56 +02:00
vkedwardli 3c483c61e7 Support Apple Silicon (macOS ARM Universal Binary) (#253)
* Add audio arm64 cpp into Xcode project

* Build universal binary for SDL2 also

* Add vixl aarch64 dependency + build arm64 in cmake

* hardcode pagesize for M1 CPU

* Use `MAP_JIT` and toggle between RX and RW

* add pthread.h for cmake

* Disable audio dynarec temporary

* Enable aica arm dynarec

* Supports `br` with condition

* Dynamic linker flag for libSDL2.a since Homebrew path is different on arm (for xcodeproj)

* Fallback path for Intel

* de-dup for arm64, allow cross compilation on both Intel and Apple Silicon Mac

* Rename WriteProtect() to JITWriteProtect(), Move JITWriteProtect from arm7_rec to arm7_rec_arm64

* Remove CodeCache memset

* Remove keyboard_device.cpp from xcodeproj

* Use hard tab

* Update libchdr to support compiling on M1 (thanks @scribam)
2021-07-23 22:34:12 +02:00
scribam 147bd8341d android: update compileSdkVersion/targetSdkVersion to version 29 2021-07-17 19:35:14 +02:00
scribam 5c0dd67094 android: cleanup jni files 2021-07-17 19:35:14 +02:00
scribam 49688d6523 android: migrate to androidx 2021-07-17 19:35:14 +02:00
scribam 850f23be82 android: update project files 2021-07-17 19:35:14 +02:00
scribam 9aa3d8b987 android: do not filter abi, allow x86_64 build 2021-07-15 09:54:41 +02:00
scribam eaf44bc18c android: generate release apk with debug keystore, update ci and gradle 2021-07-15 09:54:41 +02:00
Flyinghead 31be731de0 input: fix atomiswave keyboard bindings 2021-07-14 09:42:13 +02:00
Flyinghead 82d2aa8a47 savestate: fix test 2021-07-10 19:30:13 +02:00
Flyinghead 75af07331a savestate: save gdrom read buffer. other fixes
Issue #294
2021-07-10 19:16:19 +02:00
Flyinghead eceb5ba982 naomi: keyboard needs player number 2021-07-09 14:34:11 +02:00
Flyinghead 042f2e0224 custom textures: saturate colors when dumping RGBA4444 and RGBA5551 2021-07-07 17:19:13 +02:00
scribam aeea301ee3 Minor include header changes 2021-07-07 10:37:11 +02:00
Flyinghead fd301186c7 android: avoid duplicates in controllers list 2021-07-05 19:26:57 +02:00
Flyinghead b40328e621 input: don't change mapper if file not found. sdl: fix default bindings 2021-07-05 09:59:46 +02:00
flyinghead 7cd832e914 input: use default mapping if no mapping file is found 2021-07-04 23:27:29 +02:00
flyinghead 44feea4c01 Merge pull request #288 from flyinghead/fh/directx
DirectX9 renderer
2021-07-04 18:35:19 +02:00
flyinghead c5ce475359 Merge remote-tracking branch 'origin/master' into fh/directx
# Conflicts:
#	core/input/gamepad_device.cpp
2021-07-04 17:53:49 +02:00
flyinghead 894a0540b9 sdl: convert keyboard mapping from keycodes to scancode on first load 2021-07-04 17:45:45 +02:00
flyinghead 967f4570ed rawinput: simplify USB device names 2021-07-04 15:51:33 +02:00
Flyinghead 14360beaf7 gdrom: reset registers and state on reset
Issue #281
2021-06-27 12:53:54 +02:00
Enrique Santos 46e3258629 Controller Mapping: System Profiles & Unmap Button (#269)
* add unmap button
* separate controller profiles for dc & arcade games
* loads current system mapping on menu exit
* simplify, use default filename for dc controls
* create blank mapping file for sdl controllers if not found
2021-06-27 12:49:47 +02:00
Flyinghead b3ad0a62c1 gl: fix multiple rendering with GLES 2
fixes split-screen multiplayer for SW1 Racer, Q3, Re-volt
2021-06-19 10:48:32 +02:00
scribam a5edd9c7ff deps: remove crypto folder (unused) 2021-06-19 10:46:22 +02:00
Flyinghead 7f49accc22 Merge remote-tracking branch 'origin/master' into fh/directx 2021-06-07 20:53:31 +02:00
Flyinghead b8c2a695b8 ui: allow drag scrolling anywhere. change some ui elements
allow scrolling by dragging (almost) anywhere
move physical devices before dreamcast ones
hide insets when displaying full screen window
reduce scroll bar size on android
fix controller mapping column sizes
2021-06-07 12:18:05 +02:00
Flyinghead c73bbc85bd savestate: rzip size must be 64-bit on all platforms 2021-06-06 11:18:42 +02:00
scribam d6545b253b Misc cleanup 2021-06-06 11:15:06 +02:00
Flyinghead 293761bdf5 gui: separate auto-load and auto-save options. Fix tool tips on android 2021-06-04 11:11:23 +02:00
scribam d862453956 github actions: authorize aws actions on main repository only 2021-06-04 11:08:30 +02:00
Flyinghead 58974c9305 savestate slots 2021-06-03 13:50:40 +02:00
keita yoshimoto cddb6609f1 Multiple save states (#248) 2021-06-03 13:22:40 +02:00
scribam 4a9c51a6c8 github actions: remove flac installation from macos 2021-05-31 23:24:43 +02:00
scribam 329ae11d2f Remove snap configuration file 2021-05-31 23:24:33 +02:00
Flyinghead c3bc5cfc3b vk oit: use a 2nd depth attachment for subpass 1
subpass 1 needs writable depth buffer (see
9f60c5e854)
2021-05-30 18:20:04 +02:00
scribam 24f9003cd3 cirrus ci: add ccache support 2021-05-29 14:32:06 +02:00
scribam 4c2bf59c46 github actions: extend cache for Android build 2021-05-29 14:32:06 +02:00
scribam 642a89733b ci: remove flac package 2021-05-29 14:13:05 +02:00
scribam 2b3d9427e1 .cirrus.yml: use CIRRUS_CLONE_SUBMODULES to checkout submodules 2021-05-29 14:12:51 +02:00
scribam 6368241b77 cmake: fix compilation on FreeBSD 2021-05-29 14:12:51 +02:00
scribam 57ae9022dd Update Windows resource and version.h.in files 2021-05-28 14:56:04 +02:00
flyinghead 7ed68952ba Merge remote-tracking branch 'origin/master' into fh/directx
# Conflicts:
#	core/deps/patches/SDL.patch
#	core/hw/maple/maple_devs.cpp
#	core/rend/gl4/gles.cpp
#	core/rend/gles/gles.cpp
#	core/rend/gui.cpp
#	core/rend/gui.h
#	shell/apple/emulator-osx/reicast-osx.xcodeproj/project.pbxproj
2021-05-26 22:38:48 +02:00
flyinghead 4696733eb4 dx9: linear filtering for fog texture. swap only when frame rendered 2021-05-26 21:40:43 +02:00
flyinghead 5f5d31730c sdl: hide mouse in fullscreen. fix & refactor mouse devices
support rawinput mouse wheel
simplify mapping load
2021-05-19 18:13:52 +02:00
Flyinghead e07977eea9 mac,x11: propagate win/sdl mouse/keyboard changes 2021-05-10 13:48:12 +02:00
flyinghead 71fb024061 rawinput: proper conversion of abs coordinates
Issue #138
get rid of libPvr_GetRenderTarget() -> getNativeHwnd()
2021-05-04 12:03:09 +02:00
flyinghead 54cfc6e09b build fix for non-windows 2021-04-29 19:15:34 +02:00
Flyinghead 150cfa29e7 Merge remote-tracking branch 'origin/master' into fh/directx 2021-04-29 19:06:38 +02:00
flyinghead b90cdf9588 RawInput driver. Multiple keyboards support
Merge Keyboard and KbGamepad
Always use system mouse for UI
Issue #138

Fix DX9 when not using SDL
2021-04-29 18:58:04 +02:00
flyinghead 6316479930 get rid of unneeded pixel unpacker and use better name 2021-04-29 18:38:58 +02:00
flyinghead f9603dc11a vk: use texture pointers instead of u64 2021-04-17 19:04:00 +02:00
flyinghead 5359e9a09d allow gpu-handled palette textures to be replaced by custom version
Issue #219
Fix incorrect texture size calculation for VQ textures.
Reorder BaseTextureCacheData fields to have hottest on top
2021-04-17 18:40:58 +02:00
flyinghead 28d2c6db73 dx9: rotate 90deg 2021-04-16 21:58:37 +02:00
flyinghead abc8b18b78 dx9: mipmaps. load/dump textures. vmu/crosshair display.
upload all texture mipmaps to gpu
dump textures. load custom textures
vmu and lightgun xhair display
fix dx9 half-pixel offset
fix 565_32 unpacker bug
2021-04-16 18:30:47 +02:00
flyinghead c889bfa6d4 dx9: copy to vram. clipping. fix depth/stencil size. better reset
Coordinate device reset with dxcontext. Keep compiled shaders.
Don't use automatic depth/stencil on backbuffer. Manually handle it.
Implement scissoring/clipping
multipass translucent depth
Render-to-texture copy to vram
2021-04-15 15:17:32 +02:00
flyinghead f2a0098fed build fix 2 2021-04-13 12:22:01 +02:00
flyinghead b549c56b23 build fix. default Delay Frame Swapping to true 2021-04-13 11:20:11 +02:00
flyinghead f107d380b9 WIP directx9 renderer 2021-04-12 22:49:04 +02:00
202 changed files with 7208 additions and 4671 deletions

No files matched your search

+8 -3
View File
@@ -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
+17 -9
View File
@@ -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' }}
+28 -4
View File
@@ -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
View File
@@ -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
View File
@@ -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()
+1 -1
View File
@@ -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.
-1
View File
@@ -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
+8 -1
View File
@@ -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
View File
@@ -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;
-15
View File
@@ -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
View File
@@ -1,4 +1,5 @@
#include "ini.h"
#include "types.h"
#include <sstream>
char* trim_ws(char* str);
+3 -1
View File
@@ -1,6 +1,8 @@
#pragma once
#include "types.h"
#include <cstdio>
#include <map>
#include <string>
namespace emucfg {
+8 -2
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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)
-239
View File
@@ -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
-42
View File
@@ -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 */
-387
View File
@@ -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;
}
}
}
-63
View File
@@ -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 */
-161
View File
@@ -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;
}
}
-37
View File
@@ -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
+1
View File
@@ -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()
+2
View File
@@ -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;
+22
View File
@@ -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;
-100
View File
@@ -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
View File
@@ -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();
-9
View File
@@ -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
{
+2
View File
@@ -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:
-1
View File
@@ -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"
-2
View File
@@ -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"
+15 -3
View File
@@ -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);
}
};
-1
View File
@@ -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;
+22
View File
@@ -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 = {};
}
+7 -7
View File
@@ -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
+4 -4
View File
@@ -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
+15 -22
View File
@@ -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)
+1 -6
View File
@@ -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];
-1
View File
@@ -30,4 +30,3 @@ enum
AW_MPR_FILE_OFFSETH_addr = 0x18,
AW_PIO_DATA_addr = 0x80,
};
+3 -3
View File
@@ -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)
-1
View File
@@ -35,7 +35,6 @@ public:
void closeNetwork();
private:
void initNetwork();
void connectNetwork();
void receiveNetwork();
void sendNetwork();
+8 -3
View File
@@ -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();
+1 -1
View File
@@ -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;
+1 -4
View File
@@ -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
View File
@@ -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
View File
@@ -1,6 +1,5 @@
#include "ta_ctx.h"
#include "spg.h"
#include "oslib/oslib.h"
#include "cfg/option.h"
extern u32 fskip;
+10 -2
View File
@@ -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
+3 -3
View File
@@ -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
View File
@@ -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;
}
-1
View File
@@ -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
View File
@@ -1,6 +1,5 @@
#include "types.h"
#include <cmath>
#include <cfloat>
#include "sh4_opcodes.h"
#include "../sh4_core.h"
-2
View File
@@ -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)
-2
View File
@@ -1,7 +1,5 @@
#pragma once
#include "types.h"
void DMAC_Ch2St();
#define DMAOR_MASK 0xFFFF8201
-2
View File
@@ -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();
-2
View File
@@ -407,5 +407,3 @@ static bool wince_resolve_address(u32 va, TLB_Entry &entry)
return false;
}
-4
View File
@@ -16,10 +16,6 @@
#include "oslib/oslib.h"
#include "debug/gdb_server.h"
/*
*/
//these are fixed
const u16 IRLPriority = 0x0246;
#define IRLP9 &IRLPriority,0
-50
View File
@@ -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();
};
-3
View File
@@ -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
+2 -2
View File
@@ -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()
+134
View File
@@ -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;
+87 -2
View File
@@ -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);
};
-3
View File
@@ -1,3 +0,0 @@
#include "keyboard_device.h"
KeyboardDevice *KeyboardDevice::_instance;
+404 -82
View File
@@ -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);
}
+42
View File
@@ -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++)
{
+7 -1
View File
@@ -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;
-1
View File
@@ -212,4 +212,3 @@ bool input_evdev_handle()
}
#endif // USE_EVDEV
-1
View File
@@ -1,5 +1,4 @@
#pragma once
#include "types.h"
extern void input_evdev_init();
extern void input_evdev_close();
+11 -7
View File
@@ -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))
+3 -1
View File
@@ -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,
+2 -1
View File
@@ -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
+1 -4
View File
@@ -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
View File
@@ -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
View File
@@ -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;
}
}
};
+2 -2
View File
@@ -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()
+11 -1
View File
@@ -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
View File
@@ -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 -1
View File
@@ -1,5 +1,5 @@
#include "audiostream.h"
#if USE_ALSA
#include "audiostream.h"
#include <alsa/asoundlib.h>
#include "cfg/cfg.h"
+1 -3
View File
@@ -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 -9
View File
@@ -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 -2
View File
@@ -1,6 +1,5 @@
#include "audiostream.h"
#ifdef USE_LIBAO
#include "audiostream.h"
#include <ao/ao.h>
static ao_device *aodevice;
+1 -1
View File
@@ -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 -2
View File
@@ -1,6 +1,5 @@
#include "audiostream.h"
#if USE_OMX
#include "audiostream.h"
#include <IL/OMX_Broadcom.h>
#include <unistd.h>
+1 -1
View File
@@ -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 -1
View File
@@ -1,5 +1,5 @@
#include "audiostream.h"
#ifdef USE_PULSEAUDIO
#include "audiostream.h"
#ifdef PULSEAUDIO_SIMPLE
#include <pulse/simple.h>
-1
View File
@@ -1,4 +1,3 @@
#if defined(USE_SDL_AUDIO)
#include <SDL.h>
+2 -2
View File
@@ -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)
{
+2 -2
View File
@@ -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:
-2
View File
@@ -22,5 +22,3 @@ u32 static INLINE bitscanrev(u32 v)
return rv;
#endif
}
void os_DebugBreak();
+4 -4
View File
@@ -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)
{
+49 -14
View File
@@ -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
-3
View File
@@ -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"
-1
View File
@@ -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"
+2
View File
@@ -1,3 +1,5 @@
#pragma once
//
// Neep Bold by Jim Knoble
//
-1
View File
@@ -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
View File
@@ -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
+2 -5
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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