Compare commits
123 Commits
Author | SHA1 | Date |
---|---|---|
![]() |
211b4902d5 | |
![]() |
d2cb9d3011 | |
![]() |
c73637bc3d | |
![]() |
b1cfe7a486 | |
![]() |
c6ce6e80e8 | |
![]() |
c4afcbae32 | |
![]() |
f0eec9b53a | |
![]() |
6f8def5b3d | |
![]() |
878851ab61 | |
![]() |
6ce835b3e6 | |
![]() |
ac57149ebd | |
![]() |
6f4c2f7bf6 | |
![]() |
54c3c197ab | |
![]() |
a61325f195 | |
![]() |
6a251308e8 | |
![]() |
ee0b96cd87 | |
![]() |
69857756e3 | |
![]() |
f198be5d2f | |
![]() |
3efa52d2c4 | |
![]() |
4c7fdf59eb | |
![]() |
6868abec68 | |
![]() |
9eac43823d | |
![]() |
8581c7c54b | |
![]() |
df3c9838b8 | |
![]() |
644dc07604 | |
![]() |
eea8c368f9 | |
![]() |
2b1d57b48e | |
![]() |
b2b5db7034 | |
![]() |
59b236e493 | |
![]() |
857f133614 | |
![]() |
99880d50b6 | |
![]() |
bf3995a566 | |
![]() |
11c2776508 | |
![]() |
b209f56df2 | |
![]() |
351c1c9dd1 | |
![]() |
b9250e2c9c | |
![]() |
18ce2ebe42 | |
![]() |
4786e8e277 | |
![]() |
236b6abea1 | |
![]() |
96d986b7b4 | |
![]() |
4a6c799d1c | |
![]() |
6c851ca672 | |
![]() |
d466022bcd | |
![]() |
6c815186a6 | |
![]() |
d2436a2637 | |
![]() |
a4bd8a562b | |
![]() |
bd607a37dc | |
![]() |
75d4cff7f9 | |
![]() |
d18bde79a3 | |
![]() |
b35d71e10d | |
![]() |
96d2d44aae | |
![]() |
6bd7dedeef | |
![]() |
c9c077aa07 | |
![]() |
3d3f223a17 | |
![]() |
8421af8931 | |
![]() |
6a8714fb9b | |
![]() |
a1e7323abb | |
![]() |
916fb88dd8 | |
![]() |
0db0774147 | |
![]() |
c02aa1ea0a | |
![]() |
c217990d6d | |
![]() |
807b3c8ea1 | |
![]() |
b91f0d9299 | |
![]() |
0a2d94ec1d | |
![]() |
2ee4bbd3ab | |
![]() |
0d660c2be6 | |
![]() |
e13b683c52 | |
![]() |
c34127a536 | |
![]() |
7b5c19ff5e | |
![]() |
709237c79c | |
![]() |
b753f6eefa | |
![]() |
aaa6c15475 | |
![]() |
dccefede9b | |
![]() |
17652d9348 | |
![]() |
d9d4ea0ad4 | |
![]() |
d67ac42bbc | |
![]() |
60e07663d1 | |
![]() |
4c8740f309 | |
![]() |
acaeed8322 | |
![]() |
37e02b5a69 | |
![]() |
d4f3187ee0 | |
![]() |
122409e6f8 | |
![]() |
34e4439729 | |
![]() |
9b0c8c18de | |
![]() |
108478aaab | |
![]() |
175d578c07 | |
![]() |
0852d72dc9 | |
![]() |
e4b4b08c46 | |
![]() |
0197b406b8 | |
![]() |
727917773e | |
![]() |
d4b5cf6659 | |
![]() |
56a82682d5 | |
![]() |
0933f1ae66 | |
![]() |
6dfef64461 | |
![]() |
27b109b483 | |
![]() |
abb92327c0 | |
![]() |
682cdb0e28 | |
![]() |
146bec13ee | |
![]() |
13cf6aaacd | |
![]() |
f744e34687 | |
![]() |
ac64828880 | |
![]() |
f6b1d674db | |
![]() |
6fe0e61332 | |
![]() |
991a6b2447 | |
![]() |
ce37689720 | |
![]() |
18c1b44419 | |
![]() |
09679fb228 | |
![]() |
41fa2922f9 | |
![]() |
e787941351 | |
![]() |
f2164a9637 | |
![]() |
173a87f41b | |
![]() |
5e6ef2eaf7 | |
![]() |
51b8b06e91 | |
![]() |
f77ddc6fee | |
![]() |
6b982c8325 | |
![]() |
c9311529cb | |
![]() |
594380b2f9 | |
![]() |
c003a21362 | |
![]() |
ec8a8df269 | |
![]() |
3faee00fa7 | |
![]() |
02e0ff625b | |
![]() |
dded9debdb | |
![]() |
5d034cec3c |
|
@ -11,35 +11,46 @@ jobs:
|
||||||
linux:
|
linux:
|
||||||
name: Linux
|
name: Linux
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
env:
|
||||||
|
SDL3_VERSION: 3.2.14
|
||||||
steps:
|
steps:
|
||||||
- name: Check out the repository
|
- name: Check out the repository
|
||||||
uses: actions/checkout@93ea575cb5d8a053eaa0ac8fa3b40d7e05a33cc8
|
uses: actions/checkout@93ea575cb5d8a053eaa0ac8fa3b40d7e05a33cc8
|
||||||
- name: Install SDL2
|
- name: Install SDL3
|
||||||
run: |
|
run: |
|
||||||
sudo apt-get update
|
wget https://github.com/libsdl-org/SDL/releases/download/release-${SDL3_VERSION}/SDL3-${SDL3_VERSION}.tar.gz
|
||||||
sudo apt-get install libsdl2-dev
|
tar -xzf SDL3-${SDL3_VERSION}.tar.gz
|
||||||
|
mv SDL3-${SDL3_VERSION} SDL3
|
||||||
|
cd SDL3
|
||||||
|
cmake -DCMAKE_INSTALL_PREFIX="`pwd`/prefix" -DSDL_UNIX_CONSOLE_BUILD=ON .
|
||||||
|
make -j2 install
|
||||||
- name: Build Stella
|
- name: Build Stella
|
||||||
run: |
|
run: |
|
||||||
./configure && make -j2 all
|
CXXFLAGS="-I `pwd`/SDL3/prefix/include -O2 -g" PKG_CONFIG_PATH="`pwd`/SDL3/prefix/lib/pkgconfig/" ./configure
|
||||||
|
make -j2 all
|
||||||
|
|
||||||
macos:
|
macos:
|
||||||
name: macOS
|
name: macOS
|
||||||
runs-on: macos-latest
|
runs-on: macos-latest
|
||||||
|
env:
|
||||||
|
SDL3_VERSION: 3.2.14
|
||||||
steps:
|
steps:
|
||||||
- uses: maxim-lobanov/setup-xcode@v1
|
- uses: maxim-lobanov/setup-xcode@v1
|
||||||
with:
|
with:
|
||||||
xcode-version: '15.4'
|
xcode-version: '16.2'
|
||||||
- name: Check out the repository
|
- name: Check out the repository
|
||||||
uses: actions/checkout@93ea575cb5d8a053eaa0ac8fa3b40d7e05a33cc8
|
uses: actions/checkout@93ea575cb5d8a053eaa0ac8fa3b40d7e05a33cc8
|
||||||
- name: Install SDL2
|
- name: Install SDL3
|
||||||
run: |
|
run: |
|
||||||
curl https://www.libsdl.org/release/SDL2-2.26.0.tar.gz | tar xzf -
|
wget https://github.com/libsdl-org/SDL/releases/download/release-${SDL3_VERSION}/SDL3-${SDL3_VERSION}.dmg
|
||||||
mkdir SDL2-2.26.0/build
|
hdiutil attach SDL3-${SDL3_VERSION}.dmg
|
||||||
cd SDL2-2.26.0/build
|
mkdir -p src/os/macos/Frameworks
|
||||||
../configure && make -j3 && sudo make install
|
cp -Rv /Volumes/SDL3/SDL3.xcframework src/os/macos/Frameworks
|
||||||
|
hdiutil detach /Volumes/SDL3
|
||||||
- name: Build Stella
|
- name: Build Stella
|
||||||
run: |
|
run: |
|
||||||
./configure && make -j3 all
|
cd src/os/macos
|
||||||
|
xcodebuild
|
||||||
|
|
||||||
windows:
|
windows:
|
||||||
name: Windows
|
name: Windows
|
||||||
|
@ -49,19 +60,19 @@ jobs:
|
||||||
platform: [x64]
|
platform: [x64]
|
||||||
env:
|
env:
|
||||||
Platform: ${{ matrix.platform }}
|
Platform: ${{ matrix.platform }}
|
||||||
SDL2_version: 2.26.0
|
SDL3_version: 3.2.14
|
||||||
steps:
|
steps:
|
||||||
- name: Check out the repository
|
- name: Check out the repository
|
||||||
uses: actions/checkout@93ea575cb5d8a053eaa0ac8fa3b40d7e05a33cc8
|
uses: actions/checkout@93ea575cb5d8a053eaa0ac8fa3b40d7e05a33cc8
|
||||||
- name: Set up MSBUILD
|
- name: Set up MSBUILD
|
||||||
uses: microsoft/setup-msbuild@34cfbaee7f672c76950673338facd8a73f637506
|
uses: microsoft/setup-msbuild@34cfbaee7f672c76950673338facd8a73f637506
|
||||||
- name: Install SDL2
|
- name: Install SDL3
|
||||||
shell: cmd
|
shell: cmd
|
||||||
run: |
|
run: |
|
||||||
curl -o "C:\SDL2-devel.zip" "https://www.libsdl.org/release/SDL2-devel-%SDL2_version%-VC.zip"
|
curl -o "C:\SDL3-devel.zip" "https://www.libsdl.org/release/SDL3-devel-%SDL3_version%-VC.zip"
|
||||||
7z x "C:\SDL2-devel.zip" -o"C:\"
|
7z x "C:\SDL3-devel.zip" -o"C:\"
|
||||||
xcopy /S "C:\SDL2-%SDL2_version%\include" src\common
|
xcopy /S "C:\SDL3-%SDL3_version%\include" src\common
|
||||||
if %Platform%==x64 xcopy /S "C:\SDL2-%SDL2_version%\lib\x64" src\os\windows
|
if %Platform%==x64 xcopy /S "C:\SDL3-%SDL3_version%\lib\x64" src\os\windows
|
||||||
|
|
||||||
- name: Build Stella
|
- name: Build Stella
|
||||||
run: |
|
run: |
|
||||||
|
|
|
@ -5,6 +5,7 @@ src/**/*.so
|
||||||
src/**/*.dylib
|
src/**/*.dylib
|
||||||
src/**/*.dll
|
src/**/*.dll
|
||||||
src/**/*.o
|
src/**/*.o
|
||||||
|
src/**/*.d
|
||||||
src/**/*.obj
|
src/**/*.obj
|
||||||
src/**/*.tlog
|
src/**/*.tlog
|
||||||
out
|
out
|
||||||
|
@ -25,6 +26,7 @@ src/os/macos/M6502.ins
|
||||||
.vscode/c_cpp_properties.json
|
.vscode/c_cpp_properties.json
|
||||||
.vscode/settings.json
|
.vscode/settings.json
|
||||||
src/os/windows/sdl/*
|
src/os/windows/sdl/*
|
||||||
|
src/os/windows/sdl3/*
|
||||||
src/os/windows/x64/*
|
src/os/windows/x64/*
|
||||||
src/os/windows/Win32/*
|
src/os/windows/Win32/*
|
||||||
src/os/windows/Stella.vcxproj.user
|
src/os/windows/Stella.vcxproj.user
|
||||||
|
@ -43,3 +45,4 @@ a.out
|
||||||
*.json
|
*.json
|
||||||
*.sqlite3
|
*.sqlite3
|
||||||
*.bak
|
*.bak
|
||||||
|
debian/files
|
||||||
|
|
|
@ -28,7 +28,7 @@ distributions currently available are:
|
||||||
Stella-7.0-x64.exe (64-bit EXE installer)
|
Stella-7.0-x64.exe (64-bit EXE installer)
|
||||||
Stella-7.0-windows.zip (64 bit ZIP version)
|
Stella-7.0-windows.zip (64 bit ZIP version)
|
||||||
|
|
||||||
* Binary distribution for macOS 10.12 and above :
|
* Binary distribution for macOS 10.13 and above :
|
||||||
Stella-7.0-macos.dmg (ARM M1 and 64-bit Intel)
|
Stella-7.0-macos.dmg (ARM M1 and 64-bit Intel)
|
||||||
|
|
||||||
* Binary distribution for 64-bit Ubuntu :
|
* Binary distribution for 64-bit Ubuntu :
|
||||||
|
|
14
Changes.txt
|
@ -12,6 +12,20 @@
|
||||||
Release History
|
Release History
|
||||||
===========================================================================
|
===========================================================================
|
||||||
|
|
||||||
|
7.x to 8.0 (xxx x, 202x)
|
||||||
|
|
||||||
|
* Ported Stella to SDL3
|
||||||
|
|
||||||
|
* Added option for switching Stella's theme in sync with OS
|
||||||
|
|
||||||
|
7.0 to 7.1 (xxx x, 202x)
|
||||||
|
|
||||||
|
* Enhanced PAL-60 detection, searches for signature (e.g. PAL60) in ROM
|
||||||
|
|
||||||
|
* Enhanced VSYNC emulation, considers VBLANK now too
|
||||||
|
|
||||||
|
* Added developer option for disabling PlusROM support
|
||||||
|
|
||||||
6.7.1 to 7.0 (October 5, 2024)
|
6.7.1 to 7.0 (October 5, 2024)
|
||||||
|
|
||||||
* Enhanced ROM launcher to allow multiple images per ROM.
|
* Enhanced ROM launcher to allow multiple images per ROM.
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
License Information and Copyright Notice
|
License Information and Copyright Notice
|
||||||
===========================================================================
|
===========================================================================
|
||||||
|
|
||||||
Copyright (c) 1995-2024 by Bradford W. Mott, Stephen Anthony and the
|
Copyright (c) 1995-2025 by Bradford W. Mott, Stephen Anthony and the
|
||||||
Stella Team
|
Stella Team
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify it
|
This program is free software; you can redistribute it and/or modify it
|
||||||
|
|
2
Makefile
|
@ -8,7 +8,7 @@
|
||||||
## SS SS tt ee ll ll aa aa
|
## SS SS tt ee ll ll aa aa
|
||||||
## SSSS ttt eeeee llll llll aaaaa
|
## SSSS ttt eeeee llll llll aaaaa
|
||||||
##
|
##
|
||||||
## Copyright (c) 1995-2024 by Bradford W. Mott, Stephen Anthony
|
## Copyright (c) 1995-2025 by Bradford W. Mott, Stephen Anthony
|
||||||
## and the Stella Team
|
## and the Stella Team
|
||||||
##
|
##
|
||||||
## See the file "License.txt" for information on usage and redistribution of
|
## See the file "License.txt" for information on usage and redistribution of
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
# * command line options to...
|
# * command line options to...
|
||||||
# - override the host settings (for cross compiles
|
# - override the host settings (for cross compiles
|
||||||
# - whether to do a debug build (with -g) or an optimized build (-O3 etc.)
|
# - whether to do a debug build (with -g) or an optimized build (-O3 etc.)
|
||||||
# * detect whether the chosen backend is available (e.g. call sdl2-config)
|
# * detect whether the chosen backend is available
|
||||||
# * ....
|
# * ....
|
||||||
|
|
||||||
|
|
||||||
|
@ -45,6 +45,7 @@ _ranlib=ranlib
|
||||||
_install=install
|
_install=install
|
||||||
_ar="ar cru"
|
_ar="ar cru"
|
||||||
_strip=strip
|
_strip=strip
|
||||||
|
_pkg_config=pkg-config
|
||||||
_mkdir="mkdir -p"
|
_mkdir="mkdir -p"
|
||||||
_echo=printf
|
_echo=printf
|
||||||
_cat=cat
|
_cat=cat
|
||||||
|
@ -53,7 +54,6 @@ _rm_rec="$_rm -r"
|
||||||
_zip="zip -q"
|
_zip="zip -q"
|
||||||
_cp=cp
|
_cp=cp
|
||||||
_windowspath=""
|
_windowspath=""
|
||||||
_sdlconfig=sdl2-config
|
|
||||||
_sdlpath="$PATH"
|
_sdlpath="$PATH"
|
||||||
_prefix=/usr/local
|
_prefix=/usr/local
|
||||||
|
|
||||||
|
@ -335,20 +335,22 @@ case $_host in
|
||||||
# _host_os=amigaos
|
# _host_os=amigaos
|
||||||
# _host_cpu=ppc
|
# _host_cpu=ppc
|
||||||
# ;;
|
# ;;
|
||||||
retron77)
|
|
||||||
_host_os=retron77
|
|
||||||
;;
|
|
||||||
mingw32-cross)
|
mingw32-cross)
|
||||||
_host_os=mingw32msvc
|
_host_os=mingw32msvc
|
||||||
_host_cpu=i386
|
_host_cpu=i386
|
||||||
_host_prefix=i386-mingw32msvc
|
_host_prefix=i386-mingw32msvc
|
||||||
;;
|
;;
|
||||||
*)
|
"")
|
||||||
guessed_host=`$_srcdir/config.guess`
|
guessed_host=`$_srcdir/config.guess`
|
||||||
_host_cpu=`echo $guessed_host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
|
_host_cpu=`echo $guessed_host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
|
||||||
_host_os=`echo $guessed_host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
|
_host_os=`echo $guessed_host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
|
||||||
_host_vendor=`echo $guessed_host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
|
_host_vendor=`echo $guessed_host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
|
||||||
;;
|
;;
|
||||||
|
*)
|
||||||
|
_host_cpu=`echo "$_host" | sed 's/^\([^-]*\)-.*/\1/'`
|
||||||
|
_host_os=`echo "$_host" | sed 's/-\([^-]*\)-[^-]*$/\1/'`
|
||||||
|
_host_prefix="$_host"
|
||||||
|
;;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
#
|
#
|
||||||
|
@ -553,14 +555,6 @@ fi
|
||||||
if test -n "$_host"; then
|
if test -n "$_host"; then
|
||||||
# Cross-compiling mode - add your target here if needed
|
# Cross-compiling mode - add your target here if needed
|
||||||
case "$_host" in
|
case "$_host" in
|
||||||
retron77)
|
|
||||||
echo "Compiling for $_host, disabling windowed mode, debugger and cheats."
|
|
||||||
_build_gui=yes
|
|
||||||
_build_windowed=no
|
|
||||||
_build_debugger=no
|
|
||||||
_build_cheats=no
|
|
||||||
_build_httplib=no
|
|
||||||
;;
|
|
||||||
mingw32-cross)
|
mingw32-cross)
|
||||||
echo "Cross-compiling for Windows using MinGW."
|
echo "Cross-compiling for Windows using MinGW."
|
||||||
DEFINES="$DEFINES -DWIN32"
|
DEFINES="$DEFINES -DWIN32"
|
||||||
|
@ -626,6 +620,9 @@ fi
|
||||||
# Cross-compilers use their own commands for the following functions
|
# Cross-compilers use their own commands for the following functions
|
||||||
if test -n "$_host_prefix"; then
|
if test -n "$_host_prefix"; then
|
||||||
_strip="$_host_prefix-$_strip"
|
_strip="$_host_prefix-$_strip"
|
||||||
|
if command -v "$_host_prefix-$_pkg_config" >/dev/null 2>&1; then
|
||||||
|
_pkg_config="$_host_prefix-$_pkg_config"
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
#
|
#
|
||||||
|
@ -639,7 +636,7 @@ if test "$_build_zip" = yes ; then
|
||||||
#include <zlib.h>
|
#include <zlib.h>
|
||||||
int main(void) { return strcmp(ZLIB_VERSION, zlibVersion()); }
|
int main(void) { return strcmp(ZLIB_VERSION, zlibVersion()); }
|
||||||
EOF
|
EOF
|
||||||
cc_check $LDFLAGS $CXXFLAGS $ZLIB_CFLAGS $ZLIB_LIBS `pkg-config --libs zlib` && _zlib=yes
|
cc_check $LDFLAGS $CXXFLAGS $ZLIB_CFLAGS $ZLIB_LIBS `$_pkg_config --libs zlib` && _zlib=yes
|
||||||
|
|
||||||
if test "$_zlib" = yes ; then
|
if test "$_zlib" = yes ; then
|
||||||
echo "$_zlib"
|
echo "$_zlib"
|
||||||
|
@ -665,7 +662,7 @@ if test "$_build_png" = yes ; then
|
||||||
#include <png.h>
|
#include <png.h>
|
||||||
int main(void) { return printf("%s\n", PNG_HEADER_VERSION_STRING); }
|
int main(void) { return printf("%s\n", PNG_HEADER_VERSION_STRING); }
|
||||||
EOF
|
EOF
|
||||||
cc_check $LDFLAGS $CXXFLAGS $LIBPNG_CFLAGS $LIBPNG_LIBS `pkg-config --libs libpng` && _libpng=yes
|
cc_check $LDFLAGS $CXXFLAGS $LIBPNG_CFLAGS $LIBPNG_LIBS `$_pkg_config --libs libpng` && _libpng=yes
|
||||||
|
|
||||||
if test "$_libpng" = yes ; then
|
if test "$_libpng" = yes ; then
|
||||||
echo "$_libpng"
|
echo "$_libpng"
|
||||||
|
@ -689,7 +686,7 @@ if test "$_build_sqlite3" = yes ; then
|
||||||
#include <sqlite3.h>
|
#include <sqlite3.h>
|
||||||
int main(void) { return printf("%s\n", SQLITE_VERSION); }
|
int main(void) { return printf("%s\n", SQLITE_VERSION); }
|
||||||
EOF
|
EOF
|
||||||
cc_check $LDFLAGS $CXXFLAGS `pkg-config --libs sqlite3` && _libsqlite3=yes
|
cc_check $LDFLAGS $CXXFLAGS `$_pkg_config --libs sqlite3` && _libsqlite3=yes
|
||||||
|
|
||||||
if test "$_libsqlite3" = yes ; then
|
if test "$_libsqlite3" = yes ; then
|
||||||
echo "$_libsqlite3"
|
echo "$_libsqlite3"
|
||||||
|
@ -808,8 +805,8 @@ fi
|
||||||
#
|
#
|
||||||
# Now, add the appropriate defines/libraries/headers
|
# Now, add the appropriate defines/libraries/headers
|
||||||
#
|
#
|
||||||
echo
|
#echo
|
||||||
find_sdlconfig
|
#find_sdlconfig
|
||||||
|
|
||||||
SRC="src"
|
SRC="src"
|
||||||
SRC_OS="$SRC/os"
|
SRC_OS="$SRC/os"
|
||||||
|
@ -836,15 +833,18 @@ HTTP_LIB="$SRC_LIB/httplib"
|
||||||
|
|
||||||
INCLUDES="-I$CORE -I$COMMON -I$TV -I$TIA -I$TIA_FRAME_MANAGER -I$ELF -I$JSON -I$SQLITE_REPO"
|
INCLUDES="-I$CORE -I$COMMON -I$TV -I$TIA -I$TIA_FRAME_MANAGER -I$ELF -I$JSON -I$SQLITE_REPO"
|
||||||
|
|
||||||
INCLUDES="$INCLUDES `$_sdlconfig --cflags`"
|
#INCLUDES="$INCLUDES `$_sdlconfig --cflags`"
|
||||||
if test "$_build_static" = yes ; then
|
#if test "$_build_static" = yes ; then
|
||||||
_sdl_conf_libs="--static-libs"
|
# _sdl_conf_libs="--static-libs"
|
||||||
LDFLAGS="-static $LDFLAGS"
|
# LDFLAGS="-static $LDFLAGS"
|
||||||
else
|
#else
|
||||||
_sdl_conf_libs="--libs"
|
# _sdl_conf_libs="--libs"
|
||||||
fi
|
#fi
|
||||||
|
|
||||||
|
#if test "$_libpng" = yes ; then #FIXME:
|
||||||
|
LIBS="$LIBS `$_pkg_config --libs sdl3`"
|
||||||
|
#fi
|
||||||
|
|
||||||
LIBS="$LIBS `$_sdlconfig $_sdl_conf_libs`"
|
|
||||||
LD=$CXX
|
LD=$CXX
|
||||||
|
|
||||||
case $_host_os in
|
case $_host_os in
|
||||||
|
@ -865,11 +865,6 @@ case $_host_os in
|
||||||
fi
|
fi
|
||||||
_libsqlite3=no
|
_libsqlite3=no
|
||||||
;;
|
;;
|
||||||
retron77)
|
|
||||||
DEFINES="$DEFINES -DBSPF_UNIX -DRETRON77"
|
|
||||||
MODULES="$MODULES $SRC_OS/unix $SRC_OS/unix/r77"
|
|
||||||
INCLUDES="$INCLUDES -I$SRC_OS/unix -I$SRC_OS/unix/r77"
|
|
||||||
;;
|
|
||||||
win32)
|
win32)
|
||||||
DEFINES="$DEFINES -DBSPF_WINDOWS"
|
DEFINES="$DEFINES -DBSPF_WINDOWS"
|
||||||
MODULES="$MODULES $SRC_OS/windows"
|
MODULES="$MODULES $SRC_OS/windows"
|
||||||
|
@ -922,7 +917,7 @@ if test "$_build_png" = yes ; then
|
||||||
INCLUDES="$INCLUDES -I$LIBJPG -I$LIBJPGEXIF"
|
INCLUDES="$INCLUDES -I$LIBJPG -I$LIBJPGEXIF"
|
||||||
MODULES="$MODULES $LIBJPGEXIF"
|
MODULES="$MODULES $LIBJPGEXIF"
|
||||||
if test "$_libpng" = yes ; then
|
if test "$_libpng" = yes ; then
|
||||||
LIBS="$LIBS `pkg-config --libs libpng`"
|
LIBS="$LIBS `$_pkg_config --libs libpng`"
|
||||||
else
|
else
|
||||||
MODULES="$MODULES $LIBPNG"
|
MODULES="$MODULES $LIBPNG"
|
||||||
INCLUDES="$INCLUDES -I$LIBPNG"
|
INCLUDES="$INCLUDES -I$LIBPNG"
|
||||||
|
@ -930,7 +925,7 @@ if test "$_build_png" = yes ; then
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if test "$_libsqlite3" = yes ; then
|
if test "$_libsqlite3" = yes ; then
|
||||||
LIBS="$LIBS `pkg-config --libs sqlite3`"
|
LIBS="$LIBS `$_pkg_config --libs sqlite3`"
|
||||||
else
|
else
|
||||||
MODULES="$MODULES $SQLITE_LIB"
|
MODULES="$MODULES $SQLITE_LIB"
|
||||||
INCLUDES="$INCLUDES -I$SQLITE_LIB"
|
INCLUDES="$INCLUDES -I$SQLITE_LIB"
|
||||||
|
@ -939,7 +934,7 @@ fi
|
||||||
if test "$_build_zip" = yes ; then
|
if test "$_build_zip" = yes ; then
|
||||||
DEFINES="$DEFINES -DZIP_SUPPORT"
|
DEFINES="$DEFINES -DZIP_SUPPORT"
|
||||||
if test "$_zlib" = yes ; then
|
if test "$_zlib" = yes ; then
|
||||||
LIBS="$LIBS `pkg-config --libs zlib`"
|
LIBS="$LIBS `$_pkg_config --libs zlib`"
|
||||||
else
|
else
|
||||||
MODULES="$MODULES $ZLIB"
|
MODULES="$MODULES $ZLIB"
|
||||||
INCLUDES="$INCLUDES -I$ZLIB"
|
INCLUDES="$INCLUDES -I$ZLIB"
|
||||||
|
|
|
@ -3,8 +3,9 @@ Maintainer: Stephen Anthony <sa666666@gmail.com>
|
||||||
Section: otherosfs
|
Section: otherosfs
|
||||||
Priority: optional
|
Priority: optional
|
||||||
Build-Depends: debhelper (>= 10~),
|
Build-Depends: debhelper (>= 10~),
|
||||||
|
libgtest-dev,
|
||||||
libpng-dev,
|
libpng-dev,
|
||||||
libsdl2-dev,
|
libsdl3-dev,
|
||||||
zlib1g-dev
|
zlib1g-dev
|
||||||
Standards-Version: 4.5.0
|
Standards-Version: 4.5.0
|
||||||
Vcs-Browser: https://github.com/stella-emu/stella/
|
Vcs-Browser: https://github.com/stella-emu/stella/
|
||||||
|
@ -18,7 +19,7 @@ Depends: ${misc:Depends},
|
||||||
${shlibs:Depends}
|
${shlibs:Depends}
|
||||||
Recommends: joystick (>= 1:1.5.1)
|
Recommends: joystick (>= 1:1.5.1)
|
||||||
Pre-Depends: ${misc:Pre-Depends}
|
Pre-Depends: ${misc:Pre-Depends}
|
||||||
Description: Atari 2600 Emulator for SDL2
|
Description: Atari 2600 Emulator for SDL
|
||||||
Stella is a portable emulator of the old Atari 2600 video-game
|
Stella is a portable emulator of the old Atari 2600 video-game
|
||||||
console. You can play most Atari 2600 games with it.
|
console. You can play most Atari 2600 games with it.
|
||||||
.
|
.
|
||||||
|
|
|
@ -1,18 +1,18 @@
|
||||||
Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0
|
Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0
|
||||||
Upstream-Name: stella
|
Upstream-Name: stella
|
||||||
Source: https://stella-emu.github.io
|
Source: https://stella-emu.github.io
|
||||||
Copyright: 1995-2024 Bradford W. Mott, Stephen Anthony and the Stella Team
|
Copyright: 1995-2025 Bradford W. Mott, Stephen Anthony and the Stella Team
|
||||||
License: GPL-2+
|
License: GPL-2+
|
||||||
|
|
||||||
Files: *
|
Files: *
|
||||||
Copyright: 1995-2024 Bradford W. Mott, Stephen Anthony and the Stella
|
Copyright: 1995-2025 Bradford W. Mott, Stephen Anthony and the Stella
|
||||||
Team
|
Team
|
||||||
License: GPL-2+
|
License: GPL-2+
|
||||||
|
|
||||||
Files: debian/*
|
Files: debian/*
|
||||||
Copyright: 1998-2004 Tom Lear <tom@trap.mtview.ca.us>
|
Copyright: 1998-2004 Tom Lear <tom@trap.mtview.ca.us>
|
||||||
2006 Mario Iseli <admin@marioiseli.com>
|
2006 Mario Iseli <admin@marioiseli.com>
|
||||||
2010-2024 Stephen Kitt <skitt@debian.org>
|
2010-2025 Stephen Kitt <skitt@debian.org>
|
||||||
License: GPL-2+
|
License: GPL-2+
|
||||||
|
|
||||||
Files:
|
Files:
|
||||||
|
|
Before Width: | Height: | Size: 4.7 KiB After Width: | Height: | Size: 4.7 KiB |
Before Width: | Height: | Size: 5.2 KiB After Width: | Height: | Size: 5.2 KiB |
Before Width: | Height: | Size: 6.2 KiB After Width: | Height: | Size: 6.5 KiB |
Before Width: | Height: | Size: 6.1 KiB After Width: | Height: | Size: 6.4 KiB |
Before Width: | Height: | Size: 4.7 KiB After Width: | Height: | Size: 4.7 KiB |
|
@ -21,7 +21,7 @@
|
||||||
<img src="graphics/stella_icon.png">
|
<img src="graphics/stella_icon.png">
|
||||||
<h2><b>A multi-platform Atari 2600 VCS emulator</b></h2>
|
<h2><b>A multi-platform Atari 2600 VCS emulator</b></h2>
|
||||||
|
|
||||||
<h4><b>Release 7.0</b></h4>
|
<h4><b>Release 8.0</b></h4>
|
||||||
<br>
|
<br>
|
||||||
|
|
||||||
<h2><b>User's Guide</b></h2>
|
<h2><b>User's Guide</b></h2>
|
||||||
|
@ -342,7 +342,7 @@
|
||||||
<p>
|
<p>
|
||||||
<h3><b><u>General</u> (required for all versions of Stella)</b></h3>
|
<h3><b><u>General</u> (required for all versions of Stella)</b></h3>
|
||||||
<ul>
|
<ul>
|
||||||
<li>SDL version 2.0.14 or greater, latest version highly recommended</li>
|
<li>SDL version 3.2.14 or greater, latest version highly recommended</li>
|
||||||
<li>32 bit color graphics card</li>
|
<li>32 bit color graphics card</li>
|
||||||
<li>Enough RAM for the OS + 256MB RAM for the emulation; 512MB+ highly recommended</li>
|
<li>Enough RAM for the OS + 256MB RAM for the emulation; 512MB+ highly recommended</li>
|
||||||
<li>Joysticks or gamepads are highly recommended</li>
|
<li>Joysticks or gamepads are highly recommended</li>
|
||||||
|
@ -368,9 +368,9 @@
|
||||||
<p>The Mac version of Stella is designed to work on an Apple Macintosh with
|
<p>The Mac version of Stella is designed to work on an Apple Macintosh with
|
||||||
the following:</p>
|
the following:</p>
|
||||||
<ul>
|
<ul>
|
||||||
<li>macOS 10.11 or above</li>
|
<li>macOS 10.13 or above</li>
|
||||||
<li>64-bit ARM or Intel processor</li>
|
<li>64-bit ARM or Intel processor</li>
|
||||||
<li>Xcode 13.0 is required to compile the Stella source code</li>
|
<li>Xcode 16.0 is required to compile the Stella source code</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
|
@ -387,7 +387,7 @@
|
||||||
<h3><b><u>Other</u></b></h3>
|
<h3><b><u>Other</u></b></h3>
|
||||||
|
|
||||||
<p>Stella is extremely portable, and in its lifetime has been ported to almost every
|
<p>Stella is extremely portable, and in its lifetime has been ported to almost every
|
||||||
platform where the SDL library exists. It is 32/64-bit and endian clean in Linux/Unix, macOS
|
platform where the SDL library exists. It is 64-bit and endian clean in Linux/Unix, macOS
|
||||||
and Windows. The Stella Team is interested in hearing about any problems you may
|
and Windows. The Stella Team is interested in hearing about any problems you may
|
||||||
encounter with diverse operating systems and CPU types.</p>
|
encounter with diverse operating systems and CPU types.</p>
|
||||||
</blockquote></br>
|
</blockquote></br>
|
||||||
|
@ -2526,7 +2526,7 @@
|
||||||
|
|
||||||
<br>
|
<br>
|
||||||
<p><h2>
|
<p><h2>
|
||||||
<a name="Highscores">High Scores Saving</a></h2>
|
<a name="HighScores">High Scores Saving</a></h2>
|
||||||
<blockquote>
|
<blockquote>
|
||||||
|
|
||||||
<p>Stella allows the user to save high scores when the required definitions
|
<p>Stella allows the user to save high scores when the required definitions
|
||||||
|
@ -3249,12 +3249,17 @@
|
||||||
|
|
||||||
<tr>
|
<tr>
|
||||||
<td><pre>-uipalette2 <standard|classic|light|dark></pre></td>
|
<td><pre>-uipalette2 <standard|classic|light|dark></pre></td>
|
||||||
<td>Define alternative palette/theme for UI elements.</td>
|
<td>Define alternative/light palette/theme for UI elements.</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
||||||
<tr>
|
<tr>
|
||||||
<td><pre>-altpalette <1|0></pre></td>
|
<td><pre>-altpalette <1|0></pre></td>
|
||||||
<td>Use alternative palette/theme for UI elements.</td>
|
<td>Use alternative/dark palette/theme for UI elements.</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
<tr>
|
||||||
|
<td><pre>-autouipalette <1|0></pre></td>
|
||||||
|
<td>Automatic switching between light and dark theme in sync with OS.</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
||||||
<tr>
|
<tr>
|
||||||
|
@ -3635,6 +3640,9 @@
|
||||||
</tr><tr>
|
</tr><tr>
|
||||||
<td><pre>-<plr.|dev.>console <2600|7800></pre></td>
|
<td><pre>-<plr.|dev.>console <2600|7800></pre></td>
|
||||||
<td>Select console for B/W and Pause key handling and RAM initialization.</td>
|
<td>Select console for B/W and Pause key handling and RAM initialization.</td>
|
||||||
|
</tr><tr>
|
||||||
|
<td><pre>-dev.plusroms.on <1|0></pre></td>
|
||||||
|
<td>Enable/disable PlusROM support, e.g. for testing.</td>
|
||||||
</tr><tr>
|
</tr><tr>
|
||||||
<td><pre>-<plr.|dev.>bankrandom <1|0></pre></td>
|
<td><pre>-<plr.|dev.>bankrandom <1|0></pre></td>
|
||||||
<td>On reset, randomize the startup bank (only for selected bankswitch types).</td>
|
<td>On reset, randomize the startup bank (only for selected bankswitch types).</td>
|
||||||
|
@ -4007,8 +4015,9 @@
|
||||||
<td valign="top">
|
<td valign="top">
|
||||||
<table border="1" cellpadding="4">
|
<table border="1" cellpadding="4">
|
||||||
<tr><th>Item</th><th>Brief description</th><th>For more information,<br>see <a href="#CommandLine">Command Line</a></th></tr>
|
<tr><th>Item</th><th>Brief description</th><th>For more information,<br>see <a href="#CommandLine">Command Line</a></th></tr>
|
||||||
<tr><td>Theme #1</td><td>Default theme to use for UI elements (see examples)</td><td>-uipalette</td></tr>
|
<tr><td>Light theme</td><td>Default theme to use for UI elements (see examples)</td><td>-uipalette</td></tr>
|
||||||
<tr><td>Theme #2</td><td>Alternative theme to use for UI elements (see examples)</td><td>-uipalette2</td></tr>
|
<tr><td>Dark theme</td><td>Alternative theme to use for UI elements (see examples)</td><td>-uipalette2</td></tr>
|
||||||
|
<tr><td>Auto theme</td><td>Enable for automatic switching between light and dark themes in sync with OS.</td><td>-autouipalette</td></tr>
|
||||||
<tr><td>Dialogs font</td><td>The font used in the dialogs</td><td>-dialogfont</td></tr>
|
<tr><td>Dialogs font</td><td>The font used in the dialogs</td><td>-dialogfont</td></tr>
|
||||||
<tr><td>HiDPI mode</td><td>Scale the UI by a factor of two when enabled</td><td>-hidpi</td></tr>
|
<tr><td>HiDPI mode</td><td>Scale the UI by a factor of two when enabled</td><td>-hidpi</td></tr>
|
||||||
<tr><td>Dialogs position</td><td>Position of dialogs with Stella window</td><td>-dialogpos</td></tr>
|
<tr><td>Dialogs position</td><td>Position of dialogs with Stella window</td><td>-dialogpos</td></tr>
|
||||||
|
@ -4576,6 +4585,11 @@
|
||||||
emulation and zero-page RAM initialization</td>
|
emulation and zero-page RAM initialization</td>
|
||||||
<td>-plr.console <br/>-dev.console</td>
|
<td>-plr.console <br/>-dev.console</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>PlusROM support</td>
|
||||||
|
<td>Enable/disable PlusROM support, e.g. for testing.</td>
|
||||||
|
<td>-dev.plusroms.on</td>
|
||||||
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>Random startup bank</td>
|
<td>Random startup bank</td>
|
||||||
<td>Randomize the startup bank (only for selected bankswitch types)</td>
|
<td>Randomize the startup bank (only for selected bankswitch types)</td>
|
||||||
|
@ -5141,7 +5155,9 @@ Ms Pac-Man (Stella extended codes):
|
||||||
<tr><td>NTSC50 ¹</td><td>NTSC50, NTSC 50, NTSC-50, PAL-N</td></tr>
|
<tr><td>NTSC50 ¹</td><td>NTSC50, NTSC 50, NTSC-50, PAL-N</td></tr>
|
||||||
<tr><td>PAL60 ¹</td><td>PAL60, PAL 60, PAL-60</td></tr>
|
<tr><td>PAL60 ¹</td><td>PAL60, PAL 60, PAL-60</td></tr>
|
||||||
<tr><td>SECAM60 ¹</td><td>SECAM60, SECAM 60, SECAM-60</td></tr>
|
<tr><td>SECAM60 ¹</td><td>SECAM60, SECAM 60, SECAM-60</td></tr>
|
||||||
</table></td>
|
</table>
|
||||||
|
Additionally, to detect PAL-60 format games, the ROM is scanned for the following
|
||||||
|
signature strings: "PAL60", "PAL 60" and "PAL-60"</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
||||||
<tr>
|
<tr>
|
||||||
|
|
|
@ -264,7 +264,7 @@
|
||||||
<td width="41%">This dialog is similar to the PC version's
|
<td width="41%">This dialog is similar to the PC version's
|
||||||
<a href="index.html#CommandMenu"><b>Command Menu</b></a>, but with some
|
<a href="index.html#CommandMenu"><b>Command Menu</b></a>, but with some
|
||||||
commands especially selected for the RetroN 77.</td>
|
commands especially selected for the RetroN 77.</td>
|
||||||
<td><p><img src="commandsmenu_r77.png"></p></td>
|
<td><p><img src="graphics/commandsmenu_r77.png"></p></td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
</p>
|
</p>
|
||||||
|
@ -309,7 +309,7 @@
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
</td>
|
</td>
|
||||||
<td><p><img src="basic_settings.png"></p></td>
|
<td><p><img src="graphics/basic_settings.png"></p></td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
</p>
|
</p>
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
// SS SS tt ee ll ll aa aa
|
// SS SS tt ee ll ll aa aa
|
||||||
// SSSS ttt eeeee llll llll aaaaa
|
// SSSS ttt eeeee llll llll aaaaa
|
||||||
//
|
//
|
||||||
// Copyright (c) 1995-2024 by Bradford W. Mott, Stephen Anthony
|
// Copyright (c) 1995-2025 by Bradford W. Mott, Stephen Anthony
|
||||||
// and the Stella Team
|
// and the Stella Team
|
||||||
//
|
//
|
||||||
// See the file "License.txt" for information on usage and redistribution of
|
// See the file "License.txt" for information on usage and redistribution of
|
||||||
|
@ -33,7 +33,7 @@ BankRomCheat::BankRomCheat(OSystem& os, string_view name, string_view code)
|
||||||
count = static_cast<uInt8>(BSPF::stoi<16>(myCode.substr(7, 1)) + 1);
|
count = static_cast<uInt8>(BSPF::stoi<16>(myCode.substr(7, 1)) + 1);
|
||||||
|
|
||||||
// Back up original data; we need this if the cheat is ever disabled
|
// Back up original data; we need this if the cheat is ever disabled
|
||||||
for(int i = 0; i < count; ++i)
|
for(int i = 0; std::cmp_less(i, count); ++i)
|
||||||
savedRom[i] = myOSystem.console().cartridge().peek(address + i);
|
savedRom[i] = myOSystem.console().cartridge().peek(address + i);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -50,7 +50,7 @@ bool BankRomCheat::disable()
|
||||||
const int oldBank = myOSystem.console().cartridge().getBank(address);
|
const int oldBank = myOSystem.console().cartridge().getBank(address);
|
||||||
myOSystem.console().cartridge().bank(bank);
|
myOSystem.console().cartridge().bank(bank);
|
||||||
|
|
||||||
for(int i = 0; i < count; ++i)
|
for(int i = 0; std::cmp_less(i, count); ++i)
|
||||||
myOSystem.console().cartridge().patch(address + i, savedRom[i]);
|
myOSystem.console().cartridge().patch(address + i, savedRom[i]);
|
||||||
|
|
||||||
myOSystem.console().cartridge().bank(oldBank);
|
myOSystem.console().cartridge().bank(oldBank);
|
||||||
|
@ -66,7 +66,7 @@ void BankRomCheat::evaluate()
|
||||||
const int oldBank = myOSystem.console().cartridge().getBank(address);
|
const int oldBank = myOSystem.console().cartridge().getBank(address);
|
||||||
myOSystem.console().cartridge().bank(bank);
|
myOSystem.console().cartridge().bank(bank);
|
||||||
|
|
||||||
for(int i = 0; i < count; ++i)
|
for(int i = 0; std::cmp_less(i, count); ++i)
|
||||||
myOSystem.console().cartridge().patch(address + i, value);
|
myOSystem.console().cartridge().patch(address + i, value);
|
||||||
|
|
||||||
myOSystem.console().cartridge().bank(oldBank);
|
myOSystem.console().cartridge().bank(oldBank);
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
// SS SS tt ee ll ll aa aa
|
// SS SS tt ee ll ll aa aa
|
||||||
// SSSS ttt eeeee llll llll aaaaa
|
// SSSS ttt eeeee llll llll aaaaa
|
||||||
//
|
//
|
||||||
// Copyright (c) 1995-2024 by Bradford W. Mott, Stephen Anthony
|
// Copyright (c) 1995-2025 by Bradford W. Mott, Stephen Anthony
|
||||||
// and the Stella Team
|
// and the Stella Team
|
||||||
//
|
//
|
||||||
// See the file "License.txt" for information on usage and redistribution of
|
// See the file "License.txt" for information on usage and redistribution of
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
// SS SS tt ee ll ll aa aa
|
// SS SS tt ee ll ll aa aa
|
||||||
// SSSS ttt eeeee llll llll aaaaa
|
// SSSS ttt eeeee llll llll aaaaa
|
||||||
//
|
//
|
||||||
// Copyright (c) 1995-2024 by Bradford W. Mott, Stephen Anthony
|
// Copyright (c) 1995-2025 by Bradford W. Mott, Stephen Anthony
|
||||||
// and the Stella Team
|
// and the Stella Team
|
||||||
//
|
//
|
||||||
// See the file "License.txt" for information on usage and redistribution of
|
// See the file "License.txt" for information on usage and redistribution of
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
// SS SS tt ee ll ll aa aa
|
// SS SS tt ee ll ll aa aa
|
||||||
// SSSS ttt eeeee llll llll aaaaa
|
// SSSS ttt eeeee llll llll aaaaa
|
||||||
//
|
//
|
||||||
// Copyright (c) 1995-2024 by Bradford W. Mott, Stephen Anthony
|
// Copyright (c) 1995-2025 by Bradford W. Mott, Stephen Anthony
|
||||||
// and the Stella Team
|
// and the Stella Team
|
||||||
//
|
//
|
||||||
// See the file "License.txt" for information on usage and redistribution of
|
// See the file "License.txt" for information on usage and redistribution of
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
// SS SS tt ee ll ll aa aa
|
// SS SS tt ee ll ll aa aa
|
||||||
// SSSS ttt eeeee llll llll aaaaa
|
// SSSS ttt eeeee llll llll aaaaa
|
||||||
//
|
//
|
||||||
// Copyright (c) 1995-2024 by Bradford W. Mott, Stephen Anthony
|
// Copyright (c) 1995-2025 by Bradford W. Mott, Stephen Anthony
|
||||||
// and the Stella Team
|
// and the Stella Team
|
||||||
//
|
//
|
||||||
// See the file "License.txt" for information on usage and redistribution of
|
// See the file "License.txt" for information on usage and redistribution of
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
// SS SS tt ee ll ll aa aa
|
// SS SS tt ee ll ll aa aa
|
||||||
// SSSS ttt eeeee llll llll aaaaa
|
// SSSS ttt eeeee llll llll aaaaa
|
||||||
//
|
//
|
||||||
// Copyright (c) 1995-2024 by Bradford W. Mott, Stephen Anthony
|
// Copyright (c) 1995-2025 by Bradford W. Mott, Stephen Anthony
|
||||||
// and the Stella Team
|
// and the Stella Team
|
||||||
//
|
//
|
||||||
// See the file "License.txt" for information on usage and redistribution of
|
// See the file "License.txt" for information on usage and redistribution of
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
// SS SS tt ee ll ll aa aa
|
// SS SS tt ee ll ll aa aa
|
||||||
// SSSS ttt eeeee llll llll aaaaa
|
// SSSS ttt eeeee llll llll aaaaa
|
||||||
//
|
//
|
||||||
// Copyright (c) 1995-2024 by Bradford W. Mott, Stephen Anthony
|
// Copyright (c) 1995-2025 by Bradford W. Mott, Stephen Anthony
|
||||||
// and the Stella Team
|
// and the Stella Team
|
||||||
//
|
//
|
||||||
// See the file "License.txt" for information on usage and redistribution of
|
// See the file "License.txt" for information on usage and redistribution of
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
// SS SS tt ee ll ll aa aa
|
// SS SS tt ee ll ll aa aa
|
||||||
// SSSS ttt eeeee llll llll aaaaa
|
// SSSS ttt eeeee llll llll aaaaa
|
||||||
//
|
//
|
||||||
// Copyright (c) 1995-2024 by Bradford W. Mott, Stephen Anthony
|
// Copyright (c) 1995-2025 by Bradford W. Mott, Stephen Anthony
|
||||||
// and the Stella Team
|
// and the Stella Team
|
||||||
//
|
//
|
||||||
// See the file "License.txt" for information on usage and redistribution of
|
// See the file "License.txt" for information on usage and redistribution of
|
||||||
|
@ -28,7 +28,7 @@ CheetahCheat::CheetahCheat(OSystem& os, string_view name, string_view code)
|
||||||
count{static_cast<uInt8>(BSPF::stoi<16>(code.substr(5, 1)) + 1)}
|
count{static_cast<uInt8>(BSPF::stoi<16>(code.substr(5, 1)) + 1)}
|
||||||
{
|
{
|
||||||
// Back up original data; we need this if the cheat is ever disabled
|
// Back up original data; we need this if the cheat is ever disabled
|
||||||
for(int i = 0; i < count; ++i)
|
for(uInt8 i = 0; i < count; ++i)
|
||||||
savedRom[i] = myOSystem.console().cartridge().peek(address + i);
|
savedRom[i] = myOSystem.console().cartridge().peek(address + i);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -42,7 +42,7 @@ bool CheetahCheat::enable()
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
bool CheetahCheat::disable()
|
bool CheetahCheat::disable()
|
||||||
{
|
{
|
||||||
for(int i = 0; i < count; ++i)
|
for(uInt8 i = 0; i < count; ++i)
|
||||||
myOSystem.console().cartridge().patch(address + i, savedRom[i]);
|
myOSystem.console().cartridge().patch(address + i, savedRom[i]);
|
||||||
|
|
||||||
return myEnabled = false;
|
return myEnabled = false;
|
||||||
|
@ -53,7 +53,7 @@ void CheetahCheat::evaluate()
|
||||||
{
|
{
|
||||||
if(!myEnabled)
|
if(!myEnabled)
|
||||||
{
|
{
|
||||||
for(int i = 0; i < count; ++i)
|
for(uInt8 i = 0; i < count; ++i)
|
||||||
myOSystem.console().cartridge().patch(address + i, value);
|
myOSystem.console().cartridge().patch(address + i, value);
|
||||||
|
|
||||||
myEnabled = true;
|
myEnabled = true;
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
// SS SS tt ee ll ll aa aa
|
// SS SS tt ee ll ll aa aa
|
||||||
// SSSS ttt eeeee llll llll aaaaa
|
// SSSS ttt eeeee llll llll aaaaa
|
||||||
//
|
//
|
||||||
// Copyright (c) 1995-2024 by Bradford W. Mott, Stephen Anthony
|
// Copyright (c) 1995-2025 by Bradford W. Mott, Stephen Anthony
|
||||||
// and the Stella Team
|
// and the Stella Team
|
||||||
//
|
//
|
||||||
// See the file "License.txt" for information on usage and redistribution of
|
// See the file "License.txt" for information on usage and redistribution of
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
// SS SS tt ee ll ll aa aa
|
// SS SS tt ee ll ll aa aa
|
||||||
// SSSS ttt eeeee llll llll aaaaa
|
// SSSS ttt eeeee llll llll aaaaa
|
||||||
//
|
//
|
||||||
// Copyright (c) 1995-2024 by Bradford W. Mott, Stephen Anthony
|
// Copyright (c) 1995-2025 by Bradford W. Mott, Stephen Anthony
|
||||||
// and the Stella Team
|
// and the Stella Team
|
||||||
//
|
//
|
||||||
// See the file "License.txt" for information on usage and redistribution of
|
// See the file "License.txt" for information on usage and redistribution of
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
// SS SS tt ee ll ll aa aa
|
// SS SS tt ee ll ll aa aa
|
||||||
// SSSS ttt eeeee llll llll aaaaa
|
// SSSS ttt eeeee llll llll aaaaa
|
||||||
//
|
//
|
||||||
// Copyright (c) 1995-2024 by Bradford W. Mott, Stephen Anthony
|
// Copyright (c) 1995-2025 by Bradford W. Mott, Stephen Anthony
|
||||||
// and the Stella Team
|
// and the Stella Team
|
||||||
//
|
//
|
||||||
// See the file "License.txt" for information on usage and redistribution of
|
// See the file "License.txt" for information on usage and redistribution of
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
// SS SS tt ee ll ll aa aa
|
// SS SS tt ee ll ll aa aa
|
||||||
// SSSS ttt eeeee llll llll aaaaa
|
// SSSS ttt eeeee llll llll aaaaa
|
||||||
//
|
//
|
||||||
// Copyright (c) 1995-2024 by Bradford W. Mott, Stephen Anthony
|
// Copyright (c) 1995-2025 by Bradford W. Mott, Stephen Anthony
|
||||||
// and the Stella Team
|
// and the Stella Team
|
||||||
//
|
//
|
||||||
// See the file "License.txt" for information on usage and redistribution of
|
// See the file "License.txt" for information on usage and redistribution of
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
// SS SS tt ee ll ll aa aa
|
// SS SS tt ee ll ll aa aa
|
||||||
// SSSS ttt eeeee llll llll aaaaa
|
// SSSS ttt eeeee llll llll aaaaa
|
||||||
//
|
//
|
||||||
// Copyright (c) 1995-2024 by Bradford W. Mott, Stephen Anthony
|
// Copyright (c) 1995-2025 by Bradford W. Mott, Stephen Anthony
|
||||||
// and the Stella Team
|
// and the Stella Team
|
||||||
//
|
//
|
||||||
// See the file "License.txt" for information on usage and redistribution of
|
// See the file "License.txt" for information on usage and redistribution of
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
// SS SS tt ee ll ll aa aa
|
// SS SS tt ee ll ll aa aa
|
||||||
// SSSS ttt eeeee llll llll aaaaa
|
// SSSS ttt eeeee llll llll aaaaa
|
||||||
//
|
//
|
||||||
// Copyright (c) 1995-2024 by Bradford W. Mott, Stephen Anthony
|
// Copyright (c) 1995-2025 by Bradford W. Mott, Stephen Anthony
|
||||||
// and the Stella Team
|
// and the Stella Team
|
||||||
//
|
//
|
||||||
// See the file "License.txt" for information on usage and redistribution of
|
// See the file "License.txt" for information on usage and redistribution of
|
||||||
|
@ -67,20 +67,6 @@ void AudioSettings::normalize(Settings& settings)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (settings.getInt(SETTING_FRAGMENT_SIZE)) {
|
|
||||||
case 128:
|
|
||||||
case 256:
|
|
||||||
case 512:
|
|
||||||
case 1024:
|
|
||||||
case 2048:
|
|
||||||
case 4096:
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
settings.setValue(SETTING_FRAGMENT_SIZE, DEFAULT_FRAGMENT_SIZE);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
const int settingBufferSize = settings.getInt(SETTING_BUFFER_SIZE);
|
const int settingBufferSize = settings.getInt(SETTING_BUFFER_SIZE);
|
||||||
if (settingBufferSize < 0 || settingBufferSize > MAX_BUFFER_SIZE) settings.setValue(SETTING_BUFFER_SIZE, DEFAULT_BUFFER_SIZE);
|
if (settingBufferSize < 0 || settingBufferSize > MAX_BUFFER_SIZE) settings.setValue(SETTING_BUFFER_SIZE, DEFAULT_BUFFER_SIZE);
|
||||||
|
|
||||||
|
@ -115,7 +101,7 @@ uInt32 AudioSettings::sampleRate()
|
||||||
uInt32 AudioSettings::fragmentSize()
|
uInt32 AudioSettings::fragmentSize()
|
||||||
{
|
{
|
||||||
updatePresetFromSettings();
|
updatePresetFromSettings();
|
||||||
return customSettings() ? lboundInt(mySettings.getInt(SETTING_FRAGMENT_SIZE), DEFAULT_FRAGMENT_SIZE) : myPresetFragmentSize;
|
return myPresetFragmentSize; // No longer configurable in sound backend
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
@ -155,12 +141,6 @@ uInt32 AudioSettings::volume() const
|
||||||
return lboundInt(mySettings.getInt(SETTING_VOLUME), 0);
|
return lboundInt(mySettings.getInt(SETTING_VOLUME), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
uInt32 AudioSettings::device() const
|
|
||||||
{
|
|
||||||
return mySettings.getInt(SETTING_DEVICE);
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
bool AudioSettings::enabled() const
|
bool AudioSettings::enabled() const
|
||||||
{
|
{
|
||||||
|
@ -185,7 +165,6 @@ void AudioSettings::setPreset(AudioSettings::Preset preset)
|
||||||
|
|
||||||
case Preset::lowQualityMediumLag:
|
case Preset::lowQualityMediumLag:
|
||||||
myPresetSampleRate = 44100;
|
myPresetSampleRate = 44100;
|
||||||
myPresetFragmentSize = 1024;
|
|
||||||
myPresetBufferSize = 6;
|
myPresetBufferSize = 6;
|
||||||
myPresetHeadroom = 5;
|
myPresetHeadroom = 5;
|
||||||
myPresetResamplingQuality = ResamplingQuality::nearestNeighbour;
|
myPresetResamplingQuality = ResamplingQuality::nearestNeighbour;
|
||||||
|
@ -193,7 +172,6 @@ void AudioSettings::setPreset(AudioSettings::Preset preset)
|
||||||
|
|
||||||
case Preset::highQualityMediumLag:
|
case Preset::highQualityMediumLag:
|
||||||
myPresetSampleRate = 44100;
|
myPresetSampleRate = 44100;
|
||||||
myPresetFragmentSize = 1024;
|
|
||||||
myPresetBufferSize = 6;
|
myPresetBufferSize = 6;
|
||||||
myPresetHeadroom = 5;
|
myPresetHeadroom = 5;
|
||||||
myPresetResamplingQuality = ResamplingQuality::lanczos_2;
|
myPresetResamplingQuality = ResamplingQuality::lanczos_2;
|
||||||
|
@ -201,7 +179,6 @@ void AudioSettings::setPreset(AudioSettings::Preset preset)
|
||||||
|
|
||||||
case Preset::highQualityLowLag:
|
case Preset::highQualityLowLag:
|
||||||
myPresetSampleRate = 48000;
|
myPresetSampleRate = 48000;
|
||||||
myPresetFragmentSize = 512;
|
|
||||||
myPresetBufferSize = 3;
|
myPresetBufferSize = 3;
|
||||||
myPresetHeadroom = 2;
|
myPresetHeadroom = 2;
|
||||||
myPresetResamplingQuality = ResamplingQuality::lanczos_2;
|
myPresetResamplingQuality = ResamplingQuality::lanczos_2;
|
||||||
|
@ -209,7 +186,6 @@ void AudioSettings::setPreset(AudioSettings::Preset preset)
|
||||||
|
|
||||||
case Preset::ultraQualityMinimalLag:
|
case Preset::ultraQualityMinimalLag:
|
||||||
myPresetSampleRate = 96000;
|
myPresetSampleRate = 96000;
|
||||||
myPresetFragmentSize = 128;
|
|
||||||
myPresetBufferSize = 0;
|
myPresetBufferSize = 0;
|
||||||
myPresetHeadroom = 0;
|
myPresetHeadroom = 0;
|
||||||
myPresetResamplingQuality = ResamplingQuality::lanczos_3;
|
myPresetResamplingQuality = ResamplingQuality::lanczos_3;
|
||||||
|
@ -231,15 +207,6 @@ void AudioSettings::setSampleRate(uInt32 sampleRate)
|
||||||
normalize(mySettings);
|
normalize(mySettings);
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
void AudioSettings::setFragmentSize(uInt32 fragmentSize)
|
|
||||||
{
|
|
||||||
if (!myIsPersistent) return;
|
|
||||||
|
|
||||||
mySettings.setValue(SETTING_FRAGMENT_SIZE, fragmentSize);
|
|
||||||
normalize(mySettings);
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
void AudioSettings::setBufferSize(uInt32 bufferSize)
|
void AudioSettings::setBufferSize(uInt32 bufferSize)
|
||||||
{
|
{
|
||||||
|
@ -292,14 +259,6 @@ void AudioSettings::setVolume(uInt32 volume)
|
||||||
normalize(mySettings);
|
normalize(mySettings);
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
void AudioSettings::setDevice(uInt32 device)
|
|
||||||
{
|
|
||||||
if(!myIsPersistent) return;
|
|
||||||
|
|
||||||
mySettings.setValue(SETTING_DEVICE, device);
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
void AudioSettings::setEnabled(bool isEnabled)
|
void AudioSettings::setEnabled(bool isEnabled)
|
||||||
{
|
{
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
// SS SS tt ee ll ll aa aa
|
// SS SS tt ee ll ll aa aa
|
||||||
// SSSS ttt eeeee llll llll aaaaa
|
// SSSS ttt eeeee llll llll aaaaa
|
||||||
//
|
//
|
||||||
// Copyright (c) 1995-2024 by Bradford W. Mott, Stephen Anthony
|
// Copyright (c) 1995-2025 by Bradford W. Mott, Stephen Anthony
|
||||||
// and the Stella Team
|
// and the Stella Team
|
||||||
//
|
//
|
||||||
// See the file "License.txt" for information on usage and redistribution of
|
// See the file "License.txt" for information on usage and redistribution of
|
||||||
|
@ -42,13 +42,11 @@ class AudioSettings
|
||||||
|
|
||||||
static constexpr string_view SETTING_PRESET = "audio.preset";
|
static constexpr string_view SETTING_PRESET = "audio.preset";
|
||||||
static constexpr string_view SETTING_SAMPLE_RATE = "audio.sample_rate";
|
static constexpr string_view SETTING_SAMPLE_RATE = "audio.sample_rate";
|
||||||
static constexpr string_view SETTING_FRAGMENT_SIZE = "audio.fragment_size";
|
|
||||||
static constexpr string_view SETTING_BUFFER_SIZE = "audio.buffer_size";
|
static constexpr string_view SETTING_BUFFER_SIZE = "audio.buffer_size";
|
||||||
static constexpr string_view SETTING_HEADROOM = "audio.headroom";
|
static constexpr string_view SETTING_HEADROOM = "audio.headroom";
|
||||||
static constexpr string_view SETTING_RESAMPLING_QUALITY = "audio.resampling_quality";
|
static constexpr string_view SETTING_RESAMPLING_QUALITY = "audio.resampling_quality";
|
||||||
static constexpr string_view SETTING_STEREO = "audio.stereo";
|
static constexpr string_view SETTING_STEREO = "audio.stereo";
|
||||||
static constexpr string_view SETTING_VOLUME = "audio.volume";
|
static constexpr string_view SETTING_VOLUME = "audio.volume";
|
||||||
static constexpr string_view SETTING_DEVICE = "audio.device";
|
|
||||||
static constexpr string_view SETTING_ENABLED = "audio.enabled";
|
static constexpr string_view SETTING_ENABLED = "audio.enabled";
|
||||||
static constexpr string_view SETTING_DPC_PITCH = "audio.dpc_pitch";
|
static constexpr string_view SETTING_DPC_PITCH = "audio.dpc_pitch";
|
||||||
|
|
||||||
|
@ -132,7 +130,8 @@ class AudioSettings
|
||||||
Preset myPreset{Preset::custom};
|
Preset myPreset{Preset::custom};
|
||||||
|
|
||||||
uInt32 myPresetSampleRate{0};
|
uInt32 myPresetSampleRate{0};
|
||||||
uInt32 myPresetFragmentSize{0};
|
uInt32 myPresetFragmentSize{1024}; // no longer configurable in sound backend
|
||||||
|
|
||||||
uInt32 myPresetBufferSize{0};
|
uInt32 myPresetBufferSize{0};
|
||||||
uInt32 myPresetHeadroom{0};
|
uInt32 myPresetHeadroom{0};
|
||||||
ResamplingQuality myPresetResamplingQuality{ResamplingQuality::nearestNeighbour};
|
ResamplingQuality myPresetResamplingQuality{ResamplingQuality::nearestNeighbour};
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
// SS SS tt ee ll ll aa aa
|
// SS SS tt ee ll ll aa aa
|
||||||
// SSSS ttt eeeee llll llll aaaaa
|
// SSSS ttt eeeee llll llll aaaaa
|
||||||
//
|
//
|
||||||
// Copyright (c) 1995-2024 by Bradford W. Mott, Stephen Anthony
|
// Copyright (c) 1995-2025 by Bradford W. Mott, Stephen Anthony
|
||||||
// and the Stella Team
|
// and the Stella Team
|
||||||
//
|
//
|
||||||
// See the file "License.txt" for information on usage and redistribution of
|
// See the file "License.txt" for information on usage and redistribution of
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
// SS SS tt ee ll ll aa aa
|
// SS SS tt ee ll ll aa aa
|
||||||
// SSSS ttt eeeee llll llll aaaaa
|
// SSSS ttt eeeee llll llll aaaaa
|
||||||
//
|
//
|
||||||
// Copyright (c) 1995-2024 by Bradford W. Mott, Stephen Anthony
|
// Copyright (c) 1995-2025 by Bradford W. Mott, Stephen Anthony
|
||||||
// and the Stella Team
|
// and the Stella Team
|
||||||
//
|
//
|
||||||
// See the file "License.txt" for information on usage and redistribution of
|
// See the file "License.txt" for information on usage and redistribution of
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
// SS SS tt ee ll ll aa aa
|
// SS SS tt ee ll ll aa aa
|
||||||
// SSSS ttt eeeee llll llll aaaaa
|
// SSSS ttt eeeee llll llll aaaaa
|
||||||
//
|
//
|
||||||
// Copyright (c) 1995-2024 by Bradford W. Mott, Stephen Anthony
|
// Copyright (c) 1995-2025 by Bradford W. Mott, Stephen Anthony
|
||||||
// and the Stella Team
|
// and the Stella Team
|
||||||
//
|
//
|
||||||
// See the file "License.txt" for information on usage and redistribution of
|
// See the file "License.txt" for information on usage and redistribution of
|
||||||
|
@ -234,9 +234,8 @@ void Bezel::apply()
|
||||||
// Note: Variable bezel window positions are handled in VideoModeHandler::Mode
|
// Note: Variable bezel window positions are handled in VideoModeHandler::Mode
|
||||||
|
|
||||||
// Enable blending to allow overlaying the bezel over the TIA output
|
// Enable blending to allow overlaying the bezel over the TIA output
|
||||||
mySurface->attributes().blending = true;
|
mySurface->enableBlend(true);
|
||||||
mySurface->attributes().blendalpha = 100;
|
mySurface->setBlendLevel(100);
|
||||||
mySurface->applyAttributes();
|
|
||||||
mySurface->setVisible(true);
|
mySurface->setVisible(true);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
// SS SS tt ee ll ll aa aa
|
// SS SS tt ee ll ll aa aa
|
||||||
// SSSS ttt eeeee llll llll aaaaa
|
// SSSS ttt eeeee llll llll aaaaa
|
||||||
//
|
//
|
||||||
// Copyright (c) 1995-2024 by Bradford W. Mott, Stephen Anthony
|
// Copyright (c) 1995-2025 by Bradford W. Mott, Stephen Anthony
|
||||||
// and the Stella Team
|
// and the Stella Team
|
||||||
//
|
//
|
||||||
// See the file "License.txt" for information on usage and redistribution of
|
// See the file "License.txt" for information on usage and redistribution of
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
// SS SS tt ee ll ll aa aa
|
// SS SS tt ee ll ll aa aa
|
||||||
// SSSS ttt eeeee llll llll aaaaa
|
// SSSS ttt eeeee llll llll aaaaa
|
||||||
//
|
//
|
||||||
// Copyright (c) 1995-2024 by Bradford W. Mott, Stephen Anthony
|
// Copyright (c) 1995-2025 by Bradford W. Mott, Stephen Anthony
|
||||||
// and the Stella Team
|
// and the Stella Team
|
||||||
//
|
//
|
||||||
// See the file "License.txt" for information on usage and redistribution of
|
// See the file "License.txt" for information on usage and redistribution of
|
||||||
|
@ -46,6 +46,7 @@ void DevSettingsHandler::loadSettings(SettingsSet set)
|
||||||
// AtariVox/SaveKey/PlusROM access
|
// AtariVox/SaveKey/PlusROM access
|
||||||
myExternAccess[set] = settings.getBool(prefix + "extaccess");
|
myExternAccess[set] = settings.getBool(prefix + "extaccess");
|
||||||
myConsole[set] = settings.getString(prefix + "console") == "7800" ? 1 : 0;
|
myConsole[set] = settings.getString(prefix + "console") == "7800" ? 1 : 0;
|
||||||
|
myPlusROM[set] = devSettings ? settings.getBool("dev.plusroms.on") : true;
|
||||||
// Randomization
|
// Randomization
|
||||||
myRandomBank[set] = settings.getBool(prefix + "bankrandom");
|
myRandomBank[set] = settings.getBool(prefix + "bankrandom");
|
||||||
myRandomizeTIA[set] = settings.getBool(prefix + "tiarandom");
|
myRandomizeTIA[set] = settings.getBool(prefix + "tiarandom");
|
||||||
|
@ -118,6 +119,7 @@ void DevSettingsHandler::saveSettings(SettingsSet set)
|
||||||
|
|
||||||
if(devSettings)
|
if(devSettings)
|
||||||
{
|
{
|
||||||
|
settings.setValue("dev.plusroms.on", myPlusROM[set]);
|
||||||
settings.setValue("dev.hsrandom", myRandomHotspots[set]);
|
settings.setValue("dev.hsrandom", myRandomHotspots[set]);
|
||||||
// Undriven TIA pins
|
// Undriven TIA pins
|
||||||
settings.setValue("dev.tiadriven", myUndrivenPins[set]);
|
settings.setValue("dev.tiadriven", myUndrivenPins[set]);
|
||||||
|
@ -183,6 +185,7 @@ void DevSettingsHandler::applySettings(SettingsSet set)
|
||||||
{
|
{
|
||||||
myOSystem.console().cartridge().enableRandomHotspots(myRandomHotspots[set]);
|
myOSystem.console().cartridge().enableRandomHotspots(myRandomHotspots[set]);
|
||||||
myOSystem.console().tia().driveUnusedPinsRandom(myUndrivenPins[set]);
|
myOSystem.console().tia().driveUnusedPinsRandom(myUndrivenPins[set]);
|
||||||
|
myOSystem.console().cartridge().enablePlusROM(myPlusROM[set]);
|
||||||
// Notes:
|
// Notes:
|
||||||
// - thumb exceptions not updated, because set in cart constructor
|
// - thumb exceptions not updated, because set in cart constructor
|
||||||
// - other missing settings are used on-the-fly
|
// - other missing settings are used on-the-fly
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
// SS SS tt ee ll ll aa aa
|
// SS SS tt ee ll ll aa aa
|
||||||
// SSSS ttt eeeee llll llll aaaaa
|
// SSSS ttt eeeee llll llll aaaaa
|
||||||
//
|
//
|
||||||
// Copyright (c) 1995-2024 by Bradford W. Mott, Stephen Anthony
|
// Copyright (c) 1995-2025 by Bradford W. Mott, Stephen Anthony
|
||||||
// and the Stella Team
|
// and the Stella Team
|
||||||
//
|
//
|
||||||
// See the file "License.txt" for information on usage and redistribution of
|
// See the file "License.txt" for information on usage and redistribution of
|
||||||
|
@ -51,6 +51,7 @@ class DevSettingsHandler
|
||||||
std::array<bool, numSets> myDetectedInfo{};
|
std::array<bool, numSets> myDetectedInfo{};
|
||||||
std::array<bool, numSets> myExternAccess{};
|
std::array<bool, numSets> myExternAccess{};
|
||||||
std::array<int, numSets> myConsole{};
|
std::array<int, numSets> myConsole{};
|
||||||
|
std::array<int, numSets> myPlusROM{};
|
||||||
std::array<bool, numSets> myRandomBank{};
|
std::array<bool, numSets> myRandomBank{};
|
||||||
std::array<bool, numSets> myRandomizeTIA{};
|
std::array<bool, numSets> myRandomizeTIA{};
|
||||||
std::array<bool, numSets> myRandomizeRAM{};
|
std::array<bool, numSets> myRandomizeRAM{};
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
// SS SS tt ee ll ll aa aa
|
// SS SS tt ee ll ll aa aa
|
||||||
// SSSS ttt eeeee llll llll aaaaa
|
// SSSS ttt eeeee llll llll aaaaa
|
||||||
//
|
//
|
||||||
// Copyright (c) 1995-2024 by Bradford W. Mott, Stephen Anthony
|
// Copyright (c) 1995-2025 by Bradford W. Mott, Stephen Anthony
|
||||||
// and the Stella Team
|
// and the Stella Team
|
||||||
//
|
//
|
||||||
// See the file "License.txt" for information on usage and redistribution of
|
// See the file "License.txt" for information on usage and redistribution of
|
||||||
|
@ -17,12 +17,12 @@
|
||||||
|
|
||||||
#include "Logger.hxx"
|
#include "Logger.hxx"
|
||||||
#include "OSystem.hxx"
|
#include "OSystem.hxx"
|
||||||
#include "EventHandlerSDL2.hxx"
|
#include "EventHandlerSDL.hxx"
|
||||||
|
|
||||||
#include "ThreadDebugging.hxx"
|
#include "ThreadDebugging.hxx"
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
EventHandlerSDL2::EventHandlerSDL2(OSystem& osystem)
|
EventHandlerSDL::EventHandlerSDL(OSystem& osystem)
|
||||||
: EventHandler{osystem}
|
: EventHandler{osystem}
|
||||||
{
|
{
|
||||||
ASSERT_MAIN_THREAD;
|
ASSERT_MAIN_THREAD;
|
||||||
|
@ -31,28 +31,30 @@ EventHandlerSDL2::EventHandlerSDL2(OSystem& osystem)
|
||||||
{
|
{
|
||||||
ostringstream buf;
|
ostringstream buf;
|
||||||
myQwertz = int{'y'} == static_cast<int>
|
myQwertz = int{'y'} == static_cast<int>
|
||||||
(SDL_GetKeyFromScancode(static_cast<SDL_Scancode>(KBDK_Z)));
|
(SDL_GetKeyFromScancode(static_cast<SDL_Scancode>(KBDK_Z), static_cast<SDL_Keymod>(StellaMod::KBDM_NONE), false));
|
||||||
buf << "Keyboard: " << (myQwertz ? "QWERTZ" : "QWERTY");
|
buf << "Keyboard: " << (myQwertz ? "QWERTZ" : "QWERTY");
|
||||||
Logger::debug(buf.view());
|
Logger::debug(buf.view());
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef JOYSTICK_SUPPORT
|
#ifdef JOYSTICK_SUPPORT
|
||||||
if(SDL_InitSubSystem(SDL_INIT_JOYSTICK) < 0)
|
if(!SDL_InitSubSystem(SDL_INIT_JOYSTICK))
|
||||||
{
|
{
|
||||||
ostringstream buf;
|
ostringstream buf;
|
||||||
buf << "ERROR: Couldn't initialize SDL joystick support: "
|
buf << "ERROR: Couldn't initialize SDL joystick support: "
|
||||||
<< SDL_GetError() << '\n';
|
<< SDL_GetError() << '\n';
|
||||||
Logger::error(buf.view());
|
Logger::error(buf.view());
|
||||||
}
|
}
|
||||||
Logger::debug("EventHandlerSDL2::EventHandlerSDL2 SDL_INIT_JOYSTICK");
|
Logger::debug("EventHandlerSDL::EventHandlerSDL SDL_INIT_JOYSTICK");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
SDL_SetHint(SDL_HINT_MOUSE_FOCUS_CLICKTHROUGH, "1");
|
SDL_SetHint(SDL_HINT_MOUSE_FOCUS_CLICKTHROUGH, "1");
|
||||||
|
//SDL_SetHint(SDL_HINT_MOUSE_RELATIVE_SYSTEM_SCALE, "1");
|
||||||
|
//SDL_SetHint(SDL_HINT_MOUSE_RELATIVE_MODE_CENTER, "0");
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
EventHandlerSDL2::~EventHandlerSDL2()
|
EventHandlerSDL::~EventHandlerSDL()
|
||||||
{
|
{
|
||||||
ASSERT_MAIN_THREAD;
|
ASSERT_MAIN_THREAD;
|
||||||
|
|
||||||
|
@ -61,24 +63,13 @@ EventHandlerSDL2::~EventHandlerSDL2()
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
void EventHandlerSDL2::enableTextEvents(bool enable)
|
void EventHandlerSDL::copyText(const string& text) const
|
||||||
{
|
|
||||||
ASSERT_MAIN_THREAD;
|
|
||||||
|
|
||||||
if(enable)
|
|
||||||
SDL_StartTextInput();
|
|
||||||
else
|
|
||||||
SDL_StopTextInput();
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
void EventHandlerSDL2::copyText(const string& text) const
|
|
||||||
{
|
{
|
||||||
SDL_SetClipboardText(text.c_str());
|
SDL_SetClipboardText(text.c_str());
|
||||||
};
|
};
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
string EventHandlerSDL2::pasteText(string& text) const
|
string EventHandlerSDL::pasteText(string& text) const
|
||||||
{
|
{
|
||||||
if(SDL_HasClipboardText())
|
if(SDL_HasClipboardText())
|
||||||
text = SDL_GetClipboardText();
|
text = SDL_GetClipboardText();
|
||||||
|
@ -89,7 +80,7 @@ string EventHandlerSDL2::pasteText(string& text) const
|
||||||
};
|
};
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
void EventHandlerSDL2::pollEvent()
|
void EventHandlerSDL::pollEvent()
|
||||||
{
|
{
|
||||||
ASSERT_MAIN_THREAD;
|
ASSERT_MAIN_THREAD;
|
||||||
|
|
||||||
|
@ -98,31 +89,31 @@ void EventHandlerSDL2::pollEvent()
|
||||||
switch(myEvent.type)
|
switch(myEvent.type)
|
||||||
{
|
{
|
||||||
// keyboard events
|
// keyboard events
|
||||||
case SDL_KEYUP:
|
case SDL_EVENT_KEY_UP:
|
||||||
case SDL_KEYDOWN:
|
case SDL_EVENT_KEY_DOWN:
|
||||||
{
|
{
|
||||||
handleKeyEvent(static_cast<StellaKey>(myEvent.key.keysym.scancode),
|
handleKeyEvent(static_cast<StellaKey>(myEvent.key.scancode),
|
||||||
static_cast<StellaMod>(myEvent.key.keysym.mod),
|
static_cast<StellaMod>(myEvent.key.mod),
|
||||||
myEvent.key.type == SDL_KEYDOWN,
|
myEvent.type == SDL_EVENT_KEY_DOWN,
|
||||||
myEvent.key.repeat);
|
myEvent.key.repeat);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case SDL_TEXTINPUT:
|
case SDL_EVENT_TEXT_INPUT:
|
||||||
{
|
{
|
||||||
handleTextEvent(*(myEvent.text.text));
|
handleTextEvent(*(myEvent.text.text));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case SDL_MOUSEMOTION:
|
case SDL_EVENT_MOUSE_MOTION:
|
||||||
{
|
{
|
||||||
handleMouseMotionEvent(myEvent.motion.x, myEvent.motion.y,
|
handleMouseMotionEvent(myEvent.motion.x, myEvent.motion.y,
|
||||||
myEvent.motion.xrel, myEvent.motion.yrel);
|
myEvent.motion.xrel, myEvent.motion.yrel);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case SDL_MOUSEBUTTONDOWN:
|
case SDL_EVENT_MOUSE_BUTTON_DOWN:
|
||||||
case SDL_MOUSEBUTTONUP:
|
case SDL_EVENT_MOUSE_BUTTON_UP:
|
||||||
{
|
{
|
||||||
// ToDo: check support of more buttons and double-click
|
// ToDo: check support of more buttons and double-click
|
||||||
MouseButton b{MouseButton::NONE};
|
MouseButton b{MouseButton::NONE};
|
||||||
|
@ -140,39 +131,43 @@ void EventHandlerSDL2::pollEvent()
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
handleMouseButtonEvent(b, myEvent.button.type == SDL_MOUSEBUTTONDOWN,
|
handleMouseButtonEvent(b, myEvent.button.type == SDL_EVENT_MOUSE_BUTTON_DOWN,
|
||||||
myEvent.button.x, myEvent.button.y);
|
myEvent.button.x, myEvent.button.y);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case SDL_MOUSEWHEEL:
|
case SDL_EVENT_MOUSE_WHEEL:
|
||||||
{
|
{
|
||||||
int x{0}, y{0};
|
// TODO: SDL now uses float for mouse coords, but the core still
|
||||||
|
// uses int throughout; maybe this is sufficient?
|
||||||
|
float x{0.F}, y{0.F};
|
||||||
SDL_GetMouseState(&x, &y); // we need mouse position too
|
SDL_GetMouseState(&x, &y); // we need mouse position too
|
||||||
if(myEvent.wheel.y < 0)
|
if(myEvent.wheel.y < 0)
|
||||||
handleMouseButtonEvent(MouseButton::WHEELDOWN, true, x, y);
|
handleMouseButtonEvent(MouseButton::WHEELDOWN, true,
|
||||||
|
static_cast<int>(x), static_cast<int>(y));
|
||||||
else if(myEvent.wheel.y > 0)
|
else if(myEvent.wheel.y > 0)
|
||||||
handleMouseButtonEvent(MouseButton::WHEELUP, true, x, y);
|
handleMouseButtonEvent(MouseButton::WHEELUP, true,
|
||||||
|
static_cast<int>(x), static_cast<int>(y));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef JOYSTICK_SUPPORT
|
#ifdef JOYSTICK_SUPPORT
|
||||||
case SDL_JOYBUTTONUP:
|
case SDL_EVENT_JOYSTICK_BUTTON_UP:
|
||||||
case SDL_JOYBUTTONDOWN:
|
case SDL_EVENT_JOYSTICK_BUTTON_DOWN:
|
||||||
{
|
{
|
||||||
handleJoyBtnEvent(myEvent.jbutton.which, myEvent.jbutton.button,
|
handleJoyBtnEvent(myEvent.jbutton.which, myEvent.jbutton.button,
|
||||||
myEvent.jbutton.state == SDL_PRESSED);
|
myEvent.jbutton.down);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case SDL_JOYAXISMOTION:
|
case SDL_EVENT_JOYSTICK_AXIS_MOTION:
|
||||||
{
|
{
|
||||||
handleJoyAxisEvent(myEvent.jaxis.which, myEvent.jaxis.axis,
|
handleJoyAxisEvent(myEvent.jaxis.which, myEvent.jaxis.axis,
|
||||||
myEvent.jaxis.value);
|
myEvent.jaxis.value);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case SDL_JOYHATMOTION:
|
case SDL_EVENT_JOYSTICK_HAT_MOTION:
|
||||||
{
|
{
|
||||||
int value = 0;
|
int value = 0;
|
||||||
const int v = myEvent.jhat.value;
|
const int v = myEvent.jhat.value;
|
||||||
|
@ -187,86 +182,82 @@ void EventHandlerSDL2::pollEvent()
|
||||||
}
|
}
|
||||||
|
|
||||||
handleJoyHatEvent(myEvent.jhat.which, myEvent.jhat.hat, value);
|
handleJoyHatEvent(myEvent.jhat.which, myEvent.jhat.hat, value);
|
||||||
break; // SDL_JOYHATMOTION
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case SDL_JOYDEVICEADDED:
|
case SDL_EVENT_JOYSTICK_ADDED:
|
||||||
{
|
{
|
||||||
addPhysicalJoystick(make_shared<JoystickSDL2>(myEvent.jdevice.which));
|
addPhysicalJoystick(make_shared<JoystickSDL>(myEvent.jdevice.which));
|
||||||
break; // SDL_JOYDEVICEADDED
|
break;
|
||||||
}
|
}
|
||||||
case SDL_JOYDEVICEREMOVED:
|
case SDL_EVENT_JOYSTICK_REMOVED:
|
||||||
{
|
{
|
||||||
removePhysicalJoystick(myEvent.jdevice.which);
|
removePhysicalJoystick(myEvent.jdevice.which);
|
||||||
break; // SDL_JOYDEVICEREMOVED
|
break;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
case SDL_QUIT:
|
case SDL_EVENT_QUIT:
|
||||||
{
|
{
|
||||||
handleEvent(Event::Quit);
|
handleEvent(Event::Quit);
|
||||||
break; // SDL_QUIT
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case SDL_WINDOWEVENT:
|
case SDL_EVENT_WINDOW_SHOWN:
|
||||||
switch(myEvent.window.event)
|
handleSystemEvent(SystemEvent::WINDOW_SHOWN);
|
||||||
{
|
break;
|
||||||
case SDL_WINDOWEVENT_SHOWN:
|
case SDL_EVENT_WINDOW_HIDDEN:
|
||||||
handleSystemEvent(SystemEvent::WINDOW_SHOWN);
|
handleSystemEvent(SystemEvent::WINDOW_HIDDEN);
|
||||||
break;
|
break;
|
||||||
case SDL_WINDOWEVENT_HIDDEN:
|
case SDL_EVENT_WINDOW_EXPOSED:
|
||||||
handleSystemEvent(SystemEvent::WINDOW_HIDDEN);
|
handleSystemEvent(SystemEvent::WINDOW_EXPOSED);
|
||||||
break;
|
break;
|
||||||
case SDL_WINDOWEVENT_EXPOSED:
|
case SDL_EVENT_WINDOW_MOVED:
|
||||||
handleSystemEvent(SystemEvent::WINDOW_EXPOSED);
|
handleSystemEvent(SystemEvent::WINDOW_MOVED,
|
||||||
break;
|
myEvent.window.data1, myEvent.window.data1);
|
||||||
case SDL_WINDOWEVENT_MOVED:
|
break;
|
||||||
handleSystemEvent(SystemEvent::WINDOW_MOVED,
|
case SDL_EVENT_WINDOW_RESIZED:
|
||||||
myEvent.window.data1, myEvent.window.data1);
|
handleSystemEvent(SystemEvent::WINDOW_RESIZED,
|
||||||
break;
|
myEvent.window.data1, myEvent.window.data1);
|
||||||
case SDL_WINDOWEVENT_RESIZED:
|
break;
|
||||||
handleSystemEvent(SystemEvent::WINDOW_RESIZED,
|
case SDL_EVENT_WINDOW_MINIMIZED:
|
||||||
myEvent.window.data1, myEvent.window.data1);
|
handleSystemEvent(SystemEvent::WINDOW_MINIMIZED);
|
||||||
break;
|
break;
|
||||||
case SDL_WINDOWEVENT_MINIMIZED:
|
case SDL_EVENT_WINDOW_MAXIMIZED:
|
||||||
handleSystemEvent(SystemEvent::WINDOW_MINIMIZED);
|
handleSystemEvent(SystemEvent::WINDOW_MAXIMIZED);
|
||||||
break;
|
break;
|
||||||
case SDL_WINDOWEVENT_MAXIMIZED:
|
case SDL_EVENT_WINDOW_RESTORED:
|
||||||
handleSystemEvent(SystemEvent::WINDOW_MAXIMIZED);
|
handleSystemEvent(SystemEvent::WINDOW_RESTORED);
|
||||||
break;
|
break;
|
||||||
case SDL_WINDOWEVENT_RESTORED:
|
case SDL_EVENT_WINDOW_MOUSE_ENTER:
|
||||||
handleSystemEvent(SystemEvent::WINDOW_RESTORED);
|
handleSystemEvent(SystemEvent::WINDOW_ENTER);
|
||||||
break;
|
break;
|
||||||
case SDL_WINDOWEVENT_ENTER:
|
case SDL_EVENT_WINDOW_MOUSE_LEAVE:
|
||||||
handleSystemEvent(SystemEvent::WINDOW_ENTER);
|
handleSystemEvent(SystemEvent::WINDOW_LEAVE);
|
||||||
break;
|
break;
|
||||||
case SDL_WINDOWEVENT_LEAVE:
|
case SDL_EVENT_WINDOW_FOCUS_GAINED:
|
||||||
handleSystemEvent(SystemEvent::WINDOW_LEAVE);
|
handleSystemEvent(SystemEvent::WINDOW_FOCUS_GAINED);
|
||||||
break;
|
break;
|
||||||
case SDL_WINDOWEVENT_FOCUS_GAINED:
|
case SDL_EVENT_WINDOW_FOCUS_LOST:
|
||||||
handleSystemEvent(SystemEvent::WINDOW_FOCUS_GAINED);
|
handleSystemEvent(SystemEvent::WINDOW_FOCUS_LOST);
|
||||||
break;
|
break;
|
||||||
case SDL_WINDOWEVENT_FOCUS_LOST:
|
case SDL_EVENT_SYSTEM_THEME_CHANGED:
|
||||||
handleSystemEvent(SystemEvent::WINDOW_FOCUS_LOST);
|
handleSystemEvent(SystemEvent::THEME_CHANGED);
|
||||||
break;
|
break;
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
break; // SDL_WINDOWEVENT
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef JOYSTICK_SUPPORT
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
EventHandlerSDL2::JoystickSDL2::JoystickSDL2(int idx)
|
EventHandlerSDL::JoystickSDL::JoystickSDL(int idx)
|
||||||
{
|
{
|
||||||
ASSERT_MAIN_THREAD;
|
ASSERT_MAIN_THREAD;
|
||||||
|
|
||||||
// NOLINTNEXTLINE: we want to initialize here, not in the member list
|
// NOLINTNEXTLINE: we want to initialize here, not in the member list
|
||||||
myStick = SDL_JoystickOpen(idx);
|
myStick = SDL_OpenJoystick(idx);
|
||||||
if(myStick)
|
if(myStick)
|
||||||
{
|
{
|
||||||
// In Windows, all XBox controllers using the XInput API seem to name
|
// In Windows, all XBox controllers using the XInput API seem to name
|
||||||
|
@ -274,21 +265,24 @@ EventHandlerSDL2::JoystickSDL2::JoystickSDL2(int idx)
|
||||||
// it also appends " #x", where x seems to vary. Obviously this wreaks
|
// it also appends " #x", where x seems to vary. Obviously this wreaks
|
||||||
// havoc with the idea that a joystick will always have the same name.
|
// havoc with the idea that a joystick will always have the same name.
|
||||||
// So we truncate the number.
|
// So we truncate the number.
|
||||||
const char* const sdlname = SDL_JoystickName(myStick);
|
const char* const sdlname = SDL_GetJoystickName(myStick);
|
||||||
const string& desc = BSPF::startsWithIgnoreCase(sdlname, "XInput Controller")
|
const string& desc = BSPF::startsWithIgnoreCase(sdlname, "XInput Controller")
|
||||||
? "XInput Controller" : sdlname;
|
? "XInput Controller" : sdlname;
|
||||||
|
|
||||||
initialize(SDL_JoystickInstanceID(myStick), desc,
|
initialize(SDL_GetJoystickID(myStick), desc,
|
||||||
SDL_JoystickNumAxes(myStick), SDL_JoystickNumButtons(myStick),
|
SDL_GetNumJoystickAxes(myStick),
|
||||||
SDL_JoystickNumHats(myStick), SDL_JoystickNumBalls(myStick));
|
SDL_GetNumJoystickButtons(myStick),
|
||||||
|
SDL_GetNumJoystickHats(myStick),
|
||||||
|
SDL_GetNumJoystickBalls(myStick));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
EventHandlerSDL2::JoystickSDL2::~JoystickSDL2()
|
EventHandlerSDL::JoystickSDL::~JoystickSDL()
|
||||||
{
|
{
|
||||||
ASSERT_MAIN_THREAD;
|
ASSERT_MAIN_THREAD;
|
||||||
|
|
||||||
if(SDL_WasInit(SDL_INIT_JOYSTICK) && myStick)
|
if(SDL_WasInit(SDL_INIT_JOYSTICK) && myStick)
|
||||||
SDL_JoystickClose(myStick);
|
SDL_CloseJoystick(myStick);
|
||||||
}
|
}
|
||||||
|
#endif
|
|
@ -8,15 +8,15 @@
|
||||||
// SS SS tt ee ll ll aa aa
|
// SS SS tt ee ll ll aa aa
|
||||||
// SSSS ttt eeeee llll llll aaaaa
|
// SSSS ttt eeeee llll llll aaaaa
|
||||||
//
|
//
|
||||||
// Copyright (c) 1995-2024 by Bradford W. Mott, Stephen Anthony
|
// Copyright (c) 1995-2025 by Bradford W. Mott, Stephen Anthony
|
||||||
// and the Stella Team
|
// and the Stella Team
|
||||||
//
|
//
|
||||||
// See the file "License.txt" for information on usage and redistribution of
|
// See the file "License.txt" for information on usage and redistribution of
|
||||||
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
||||||
//============================================================================
|
//============================================================================
|
||||||
|
|
||||||
#ifndef EVENTHANDLER_SDL2_HXX
|
#ifndef EVENTHANDLER_SDL_HXX
|
||||||
#define EVENTHANDLER_SDL2_HXX
|
#define EVENTHANDLER_SDL_HXX
|
||||||
|
|
||||||
#include "SDL_lib.hxx"
|
#include "SDL_lib.hxx"
|
||||||
#include "EventHandler.hxx"
|
#include "EventHandler.hxx"
|
||||||
|
@ -24,26 +24,21 @@
|
||||||
|
|
||||||
/**
|
/**
|
||||||
This class handles event collection from the point of view of the specific
|
This class handles event collection from the point of view of the specific
|
||||||
backend toolkit (SDL2). It converts from SDL2-specific events into events
|
backend toolkit (SDL). It converts from SDL-specific events into events
|
||||||
that the Stella core can understand.
|
that the Stella core can understand.
|
||||||
|
|
||||||
@author Stephen Anthony
|
@author Stephen Anthony
|
||||||
*/
|
*/
|
||||||
class EventHandlerSDL2 : public EventHandler
|
class EventHandlerSDL : public EventHandler
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
Create a new SDL2 event handler object
|
Create a new SDL event handler object
|
||||||
*/
|
*/
|
||||||
explicit EventHandlerSDL2(OSystem& osystem);
|
explicit EventHandlerSDL(OSystem& osystem);
|
||||||
~EventHandlerSDL2() override;
|
~EventHandlerSDL() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/**
|
|
||||||
Enable/disable text events (distinct from single-key events).
|
|
||||||
*/
|
|
||||||
void enableTextEvents(bool enable) override;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Clipboard methods.
|
Clipboard methods.
|
||||||
*/
|
*/
|
||||||
|
@ -51,40 +46,42 @@ class EventHandlerSDL2 : public EventHandler
|
||||||
string pasteText(string& text) const override;
|
string pasteText(string& text) const override;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Collects and dispatches any pending SDL2 events.
|
Collects and dispatches any pending SDL events.
|
||||||
*/
|
*/
|
||||||
void pollEvent() override;
|
void pollEvent() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
SDL_Event myEvent{0};
|
SDL_Event myEvent{0};
|
||||||
|
|
||||||
|
#ifdef JOYSTICK_SUPPORT
|
||||||
// A thin wrapper around a basic PhysicalJoystick, holding the pointer to
|
// A thin wrapper around a basic PhysicalJoystick, holding the pointer to
|
||||||
// the underlying SDL joystick device.
|
// the underlying SDL joystick device.
|
||||||
class JoystickSDL2 : public PhysicalJoystick
|
class JoystickSDL : public PhysicalJoystick
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
explicit JoystickSDL2(int idx);
|
explicit JoystickSDL(int idx);
|
||||||
virtual ~JoystickSDL2();
|
virtual ~JoystickSDL();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
SDL_Joystick* myStick{nullptr};
|
SDL_Joystick* myStick{nullptr};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Following constructors and assignment operators not supported
|
// Following constructors and assignment operators not supported
|
||||||
JoystickSDL2() = delete;
|
JoystickSDL() = delete;
|
||||||
JoystickSDL2(const JoystickSDL2&) = delete;
|
JoystickSDL(const JoystickSDL&) = delete;
|
||||||
JoystickSDL2(JoystickSDL2&&) = delete;
|
JoystickSDL(JoystickSDL&&) = delete;
|
||||||
JoystickSDL2& operator=(const JoystickSDL2&) = delete;
|
JoystickSDL& operator=(const JoystickSDL&) = delete;
|
||||||
JoystickSDL2& operator=(JoystickSDL2&&) = delete;
|
JoystickSDL& operator=(JoystickSDL&&) = delete;
|
||||||
};
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Following constructors and assignment operators not supported
|
// Following constructors and assignment operators not supported
|
||||||
EventHandlerSDL2() = delete;
|
EventHandlerSDL() = delete;
|
||||||
EventHandlerSDL2(const EventHandlerSDL2&) = delete;
|
EventHandlerSDL(const EventHandlerSDL&) = delete;
|
||||||
EventHandlerSDL2(EventHandlerSDL2&&) = delete;
|
EventHandlerSDL(EventHandlerSDL&&) = delete;
|
||||||
EventHandlerSDL2& operator=(const EventHandlerSDL2&) = delete;
|
EventHandlerSDL& operator=(const EventHandlerSDL&) = delete;
|
||||||
EventHandlerSDL2& operator=(EventHandlerSDL2&&) = delete;
|
EventHandlerSDL& operator=(EventHandlerSDL&&) = delete;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
|
@ -8,7 +8,7 @@
|
||||||
// SS SS tt ee ll ll aa aa
|
// SS SS tt ee ll ll aa aa
|
||||||
// SSSS ttt eeeee llll llll aaaaa
|
// SSSS ttt eeeee llll llll aaaaa
|
||||||
//
|
//
|
||||||
// Copyright (c) 1995-2024 by Bradford W. Mott, Stephen Anthony
|
// Copyright (c) 1995-2025 by Bradford W. Mott, Stephen Anthony
|
||||||
// and the Stella Team
|
// and the Stella Team
|
||||||
//
|
//
|
||||||
// See the file "License.txt" for information on usage and redistribution of
|
// See the file "License.txt" for information on usage and redistribution of
|
||||||
|
@ -25,38 +25,36 @@
|
||||||
#include "Settings.hxx"
|
#include "Settings.hxx"
|
||||||
|
|
||||||
#include "ThreadDebugging.hxx"
|
#include "ThreadDebugging.hxx"
|
||||||
#include "FBSurfaceSDL2.hxx"
|
#include "FBSurfaceSDL.hxx"
|
||||||
#include "FBBackendSDL2.hxx"
|
#include "FBBackendSDL.hxx"
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
FBBackendSDL2::FBBackendSDL2(OSystem& osystem)
|
FBBackendSDL::FBBackendSDL(OSystem& osystem)
|
||||||
: myOSystem{osystem}
|
: myOSystem{osystem}
|
||||||
{
|
{
|
||||||
ASSERT_MAIN_THREAD;
|
ASSERT_MAIN_THREAD;
|
||||||
|
|
||||||
// Initialize SDL2 context
|
// Initialize SDL context
|
||||||
if(SDL_InitSubSystem(SDL_INIT_VIDEO | SDL_INIT_TIMER) < 0)
|
if(!SDL_InitSubSystem(SDL_INIT_VIDEO))
|
||||||
{
|
{
|
||||||
ostringstream buf;
|
ostringstream buf;
|
||||||
buf << "ERROR: Couldn't initialize SDL: " << SDL_GetError();
|
buf << "ERROR: Couldn't initialize SDL: " << SDL_GetError();
|
||||||
throw runtime_error(buf.str());
|
throw runtime_error(buf.str());
|
||||||
}
|
}
|
||||||
Logger::debug("FBBackendSDL2::FBBackendSDL2 SDL_Init()");
|
Logger::debug("FBBackendSDL::FBBackendSDL SDL_Init()");
|
||||||
|
|
||||||
// We need a pixel format for palette value calculations
|
// We need a pixel format for palette value calculations
|
||||||
// It's done this way (vs directly accessing a FBSurfaceSDL2 object)
|
// It's done this way (vs directly accessing a FBSurfaceSDL object)
|
||||||
// since the structure may be needed before any FBSurface's have
|
// since the structure may be needed before any FBSurface's have
|
||||||
// been created
|
// been created
|
||||||
myPixelFormat = SDL_AllocFormat(SDL_PIXELFORMAT_ARGB8888);
|
myPixelFormat = SDL_GetPixelFormatDetails(SDL_PIXELFORMAT_ARGB8888);
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
FBBackendSDL2::~FBBackendSDL2()
|
FBBackendSDL::~FBBackendSDL()
|
||||||
{
|
{
|
||||||
ASSERT_MAIN_THREAD;
|
ASSERT_MAIN_THREAD;
|
||||||
|
|
||||||
SDL_FreeFormat(myPixelFormat);
|
|
||||||
|
|
||||||
if(myRenderer)
|
if(myRenderer)
|
||||||
{
|
{
|
||||||
SDL_DestroyRenderer(myRenderer);
|
SDL_DestroyRenderer(myRenderer);
|
||||||
|
@ -64,46 +62,55 @@ FBBackendSDL2::~FBBackendSDL2()
|
||||||
}
|
}
|
||||||
if(myWindow)
|
if(myWindow)
|
||||||
{
|
{
|
||||||
SDL_SetWindowFullscreen(myWindow, 0); // on some systems, a crash occurs
|
SDL_SetWindowFullscreen(myWindow, false); // on some systems, a crash occurs
|
||||||
// when destroying fullscreen window
|
// when destroying fullscreen window
|
||||||
SDL_DestroyWindow(myWindow);
|
SDL_DestroyWindow(myWindow);
|
||||||
myWindow = nullptr;
|
myWindow = nullptr;
|
||||||
}
|
}
|
||||||
SDL_QuitSubSystem(SDL_INIT_VIDEO | SDL_INIT_TIMER);
|
SDL_QuitSubSystem(SDL_INIT_VIDEO);
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
void FBBackendSDL2::queryHardware(vector<Common::Size>& fullscreenRes,
|
void FBBackendSDL::queryHardware(vector<Common::Size>& fullscreenRes,
|
||||||
vector<Common::Size>& windowedRes,
|
vector<Common::Size>& windowedRes,
|
||||||
VariantList& renderers)
|
VariantList& renderers)
|
||||||
{
|
{
|
||||||
ASSERT_MAIN_THREAD;
|
ASSERT_MAIN_THREAD;
|
||||||
|
|
||||||
// Get number of displays (for most systems, this will be '1')
|
// Get number of displays (for most systems, this will be '1')
|
||||||
myNumDisplays = SDL_GetNumVideoDisplays();
|
int count = 0;
|
||||||
|
SDL_DisplayID* displays = SDL_GetDisplays(&count);
|
||||||
|
if(displays && count > 0)
|
||||||
|
myNumDisplays = static_cast<uInt32>(count);
|
||||||
|
else
|
||||||
|
return;
|
||||||
|
|
||||||
// First get the maximum fullscreen desktop resolution
|
// Get the maximum fullscreen and windowed desktop resolutions
|
||||||
SDL_DisplayMode display;
|
for(uInt32 i = 0; i < myNumDisplays; ++i)
|
||||||
for(int i = 0; i < myNumDisplays; ++i)
|
|
||||||
{
|
{
|
||||||
SDL_GetDesktopDisplayMode(i, &display);
|
// Fullscreen mode
|
||||||
fullscreenRes.emplace_back(display.w, display.h);
|
const SDL_DisplayMode* display = SDL_GetDesktopDisplayMode(displays[i]);
|
||||||
|
fullscreenRes.emplace_back(display->w, display->h);
|
||||||
|
|
||||||
// evaluate fullscreen display modes (debug only for now)
|
// Windowed mode
|
||||||
const int numModes = SDL_GetNumDisplayModes(i);
|
SDL_Rect r{};
|
||||||
|
if(SDL_GetDisplayUsableBounds(displays[i], &r))
|
||||||
|
windowedRes.emplace_back(r.w, r.h);
|
||||||
|
|
||||||
|
int numModes = 0;
|
||||||
ostringstream s;
|
ostringstream s;
|
||||||
|
string lastRes;
|
||||||
|
SDL_DisplayMode** modes = SDL_GetFullscreenDisplayModes(displays[i], &numModes);
|
||||||
|
|
||||||
s << "Supported video modes (" << numModes << ") for display " << i
|
s << "Supported video modes (" << numModes << ") for display " << i
|
||||||
<< " (" << SDL_GetDisplayName(i) << "):";
|
<< " (" << SDL_GetDisplayName(displays[i]) << "):";
|
||||||
|
|
||||||
string lastRes;
|
for(int m = 0; modes != nullptr && modes[m] != nullptr; m++)
|
||||||
for(int m = 0; m < numModes; ++m)
|
|
||||||
{
|
{
|
||||||
SDL_DisplayMode mode;
|
const SDL_DisplayMode* mode = modes[m];
|
||||||
ostringstream res;
|
ostringstream res, ref;
|
||||||
|
|
||||||
SDL_GetDisplayMode(i, m, &mode);
|
res << std::setw(4) << mode->w << "x" << std::setw(4) << mode->h;
|
||||||
res << std::setw(4) << mode.w << "x" << std::setw(4) << mode.h;
|
|
||||||
|
|
||||||
if(lastRes != res.view())
|
if(lastRes != res.view())
|
||||||
{
|
{
|
||||||
|
@ -112,47 +119,23 @@ void FBBackendSDL2::queryHardware(vector<Common::Size>& fullscreenRes,
|
||||||
lastRes = res.view();
|
lastRes = res.view();
|
||||||
s << " " << lastRes << ": ";
|
s << " " << lastRes << ": ";
|
||||||
}
|
}
|
||||||
s << mode.refresh_rate << "Hz";
|
|
||||||
if(mode.w == display.w && mode.h == display.h && mode.refresh_rate == display.refresh_rate)
|
ref << mode->refresh_rate << "Hz";
|
||||||
|
s << std::setw(7) << std::left << ref.str();
|
||||||
|
if(mode->w == display->w && mode->h == display->h &&
|
||||||
|
mode->refresh_rate == display->refresh_rate)
|
||||||
s << "* ";
|
s << "* ";
|
||||||
else
|
else
|
||||||
s << " ";
|
s << " ";
|
||||||
}
|
}
|
||||||
Logger::debug(s.view());
|
Logger::debug(s.view());
|
||||||
}
|
}
|
||||||
|
SDL_free(displays);
|
||||||
// Now get the maximum windowed desktop resolution
|
|
||||||
// Try to take into account taskbars, etc, if available
|
|
||||||
#if SDL_VERSION_ATLEAST(2,0,5)
|
|
||||||
// Take window title-bar into account; SDL_GetDisplayUsableBounds doesn't do that
|
|
||||||
int wTop = 0, wLeft = 0, wBottom = 0, wRight = 0;
|
|
||||||
SDL_Window* tmpWindow = SDL_CreateWindow("", 0, 0, 0, 0, SDL_WINDOW_HIDDEN);
|
|
||||||
if(tmpWindow != nullptr)
|
|
||||||
{
|
|
||||||
SDL_GetWindowBordersSize(tmpWindow, &wTop, &wLeft, &wBottom, &wRight);
|
|
||||||
SDL_DestroyWindow(tmpWindow);
|
|
||||||
}
|
|
||||||
|
|
||||||
SDL_Rect r;
|
|
||||||
for(int i = 0; i < myNumDisplays; ++i)
|
|
||||||
{
|
|
||||||
// Display bounds minus dock
|
|
||||||
SDL_GetDisplayUsableBounds(i, &r); // Requires SDL-2.0.5 or higher
|
|
||||||
r.h -= (wTop + wBottom);
|
|
||||||
windowedRes.emplace_back(r.w, r.h);
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
for(int i = 0; i < myNumDisplays; ++i)
|
|
||||||
{
|
|
||||||
SDL_GetDesktopDisplayMode(i, &display);
|
|
||||||
windowedRes.emplace_back(display.w, display.h);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
struct RenderName
|
struct RenderName
|
||||||
{
|
{
|
||||||
string sdlName;
|
string_view sdlName;
|
||||||
string stellaName;
|
string_view stellaName;
|
||||||
};
|
};
|
||||||
// Create name map for all currently known SDL renderers
|
// Create name map for all currently known SDL renderers
|
||||||
static const std::array<RenderName, 8> RENDERER_NAMES = {{
|
static const std::array<RenderName, 8> RENDERER_NAMES = {{
|
||||||
|
@ -169,68 +152,66 @@ void FBBackendSDL2::queryHardware(vector<Common::Size>& fullscreenRes,
|
||||||
const int numDrivers = SDL_GetNumRenderDrivers();
|
const int numDrivers = SDL_GetNumRenderDrivers();
|
||||||
for(int i = 0; i < numDrivers; ++i)
|
for(int i = 0; i < numDrivers; ++i)
|
||||||
{
|
{
|
||||||
SDL_RendererInfo info;
|
const char* const rendername = SDL_GetRenderDriver(i);
|
||||||
if(SDL_GetRenderDriverInfo(i, &info) == 0)
|
if(rendername)
|
||||||
{
|
{
|
||||||
// Map SDL names into nicer Stella names (if available)
|
// Map SDL names into nicer Stella names (if available)
|
||||||
bool found = false;
|
bool found = false;
|
||||||
for(const auto& render: RENDERER_NAMES)
|
for(const auto& render: RENDERER_NAMES)
|
||||||
{
|
{
|
||||||
if(render.sdlName == info.name)
|
if(render.sdlName == rendername)
|
||||||
{
|
{
|
||||||
VarList::push_back(renderers, render.stellaName, info.name);
|
VarList::push_back(renderers, render.stellaName, rendername);
|
||||||
found = true;
|
found = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(!found)
|
if(!found)
|
||||||
VarList::push_back(renderers, info.name, info.name);
|
VarList::push_back(renderers, rendername, rendername);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
bool FBBackendSDL2::isCurrentWindowPositioned() const
|
bool FBBackendSDL::isCurrentWindowPositioned() const
|
||||||
{
|
{
|
||||||
ASSERT_MAIN_THREAD;
|
ASSERT_MAIN_THREAD;
|
||||||
|
|
||||||
return !myCenter
|
return myWindow && !fullScreen() && !myCenter;
|
||||||
&& myWindow && !(SDL_GetWindowFlags(myWindow) & SDL_WINDOW_FULLSCREEN_DESKTOP);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
Common::Point FBBackendSDL2::getCurrentWindowPos() const
|
Common::Point FBBackendSDL::getCurrentWindowPos() const
|
||||||
{
|
{
|
||||||
ASSERT_MAIN_THREAD;
|
ASSERT_MAIN_THREAD;
|
||||||
|
|
||||||
Common::Point pos;
|
Common::Point pos;
|
||||||
|
|
||||||
SDL_GetWindowPosition(myWindow, &pos.x, &pos.y);
|
SDL_GetWindowPosition(myWindow, &pos.x, &pos.y);
|
||||||
|
|
||||||
return pos;
|
return pos;
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
Int32 FBBackendSDL2::getCurrentDisplayIndex() const
|
uInt32 FBBackendSDL::getCurrentDisplayID() const
|
||||||
{
|
{
|
||||||
ASSERT_MAIN_THREAD;
|
ASSERT_MAIN_THREAD;
|
||||||
|
|
||||||
return SDL_GetWindowDisplayIndex(myWindow);
|
return SDL_GetDisplayForWindow(myWindow);
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
bool FBBackendSDL2::setVideoMode(const VideoModeHandler::Mode& mode,
|
bool FBBackendSDL::setVideoMode(const VideoModeHandler::Mode& mode,
|
||||||
int winIdx, const Common::Point& winPos)
|
int winIdx, const Common::Point& winPos)
|
||||||
{
|
{
|
||||||
ASSERT_MAIN_THREAD;
|
ASSERT_MAIN_THREAD;
|
||||||
|
|
||||||
|
// cerr << mode << '\n';
|
||||||
|
|
||||||
// If not initialized by this point, then immediately fail
|
// If not initialized by this point, then immediately fail
|
||||||
if(SDL_WasInit(SDL_INIT_VIDEO) == 0)
|
if(SDL_WasInit(SDL_INIT_VIDEO) == 0)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
const bool fullScreen = mode.fsIndex != -1;
|
const uInt32 displayIndex = std::min<uInt32>(myNumDisplays, winIdx);
|
||||||
const Int32 displayIndex = std::min(myNumDisplays - 1, winIdx);
|
|
||||||
|
|
||||||
int posX = 0, posY = 0;
|
int posX = 0, posY = 0;
|
||||||
|
|
||||||
myCenter = myOSystem.settings().getBool("center");
|
myCenter = myOSystem.settings().getBool("center");
|
||||||
|
@ -261,10 +242,10 @@ bool FBBackendSDL2::setVideoMode(const VideoModeHandler::Mode& mode,
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef ADAPTABLE_REFRESH_SUPPORT
|
#ifdef ADAPTABLE_REFRESH_SUPPORT
|
||||||
SDL_DisplayMode adaptedSdlMode;
|
SDL_DisplayMode adaptedSdlMode{};
|
||||||
const int gameRefreshRate =
|
const int gameRefreshRate =
|
||||||
myOSystem.hasConsole() ? myOSystem.console().gameRefreshRate() : 0;
|
myOSystem.hasConsole() ? myOSystem.console().gameRefreshRate() : 0;
|
||||||
const bool shouldAdapt = fullScreen
|
const bool shouldAdapt = mode.fullscreen
|
||||||
&& myOSystem.settings().getBool("tia.fs_refresh")
|
&& myOSystem.settings().getBool("tia.fs_refresh")
|
||||||
&& gameRefreshRate
|
&& gameRefreshRate
|
||||||
// take care of 59.94 Hz
|
// take care of 59.94 Hz
|
||||||
|
@ -275,20 +256,18 @@ bool FBBackendSDL2::setVideoMode(const VideoModeHandler::Mode& mode,
|
||||||
#else
|
#else
|
||||||
const bool adaptRefresh = false;
|
const bool adaptRefresh = false;
|
||||||
#endif
|
#endif
|
||||||
const uInt32 flags = SDL_WINDOW_ALLOW_HIGHDPI
|
|
||||||
| (fullScreen ? adaptRefresh ? SDL_WINDOW_FULLSCREEN :
|
|
||||||
SDL_WINDOW_FULLSCREEN_DESKTOP : 0);
|
|
||||||
|
|
||||||
// Don't re-create the window if its display and size hasn't changed,
|
// Don't re-create the window if its display and size hasn't changed,
|
||||||
// as it's not necessary, and causes flashing in fullscreen mode
|
// as it's not necessary, and causes flashing in fullscreen mode
|
||||||
if(myWindow)
|
if(myWindow)
|
||||||
{
|
{
|
||||||
const int d = SDL_GetWindowDisplayIndex(myWindow);
|
const uInt32 d = getCurrentDisplayID();
|
||||||
int w{0}, h{0};
|
int w{0}, h{0};
|
||||||
|
|
||||||
SDL_GetWindowSize(myWindow, &w, &h);
|
SDL_GetWindowSize(myWindow, &w, &h);
|
||||||
if(d != displayIndex || static_cast<uInt32>(w) != mode.screenS.w ||
|
if(d != displayIndex ||
|
||||||
static_cast<uInt32>(h) != mode.screenS.h || adaptRefresh)
|
std::cmp_not_equal(w, mode.screenS.w) ||
|
||||||
|
std::cmp_not_equal(h, mode.screenS.h) || adaptRefresh)
|
||||||
{
|
{
|
||||||
// Renderer has to be destroyed *before* the window gets destroyed to avoid memory leaks
|
// Renderer has to be destroyed *before* the window gets destroyed to avoid memory leaks
|
||||||
SDL_DestroyRenderer(myRenderer);
|
SDL_DestroyRenderer(myRenderer);
|
||||||
|
@ -306,8 +285,25 @@ bool FBBackendSDL2::setVideoMode(const VideoModeHandler::Mode& mode,
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
myWindow = SDL_CreateWindow(myScreenTitle.c_str(), posX, posY,
|
// Re-create with new properties
|
||||||
mode.screenS.w, mode.screenS.h, flags);
|
const SDL_PropertiesID props = SDL_CreateProperties();
|
||||||
|
SDL_SetStringProperty(props, SDL_PROP_WINDOW_CREATE_TITLE_STRING,
|
||||||
|
myScreenTitle.c_str());
|
||||||
|
SDL_SetNumberProperty(props, SDL_PROP_WINDOW_CREATE_X_NUMBER, posX);
|
||||||
|
SDL_SetNumberProperty(props, SDL_PROP_WINDOW_CREATE_Y_NUMBER, posY);
|
||||||
|
SDL_SetNumberProperty(props, SDL_PROP_WINDOW_CREATE_WIDTH_NUMBER,
|
||||||
|
mode.screenS.w);
|
||||||
|
SDL_SetNumberProperty(props, SDL_PROP_WINDOW_CREATE_HEIGHT_NUMBER,
|
||||||
|
mode.screenS.h);
|
||||||
|
SDL_SetBooleanProperty(props, SDL_PROP_WINDOW_CREATE_HIDDEN_BOOLEAN,
|
||||||
|
true);
|
||||||
|
SDL_SetBooleanProperty(props, SDL_PROP_WINDOW_CREATE_FULLSCREEN_BOOLEAN,
|
||||||
|
mode.fullscreen);
|
||||||
|
SDL_SetBooleanProperty(props,
|
||||||
|
SDL_PROP_WINDOW_CREATE_HIGH_PIXEL_DENSITY_BOOLEAN,
|
||||||
|
true);
|
||||||
|
myWindow = SDL_CreateWindowWithProperties(props);
|
||||||
|
SDL_DestroyProperties(props);
|
||||||
if(myWindow == nullptr)
|
if(myWindow == nullptr)
|
||||||
{
|
{
|
||||||
const string msg = "ERROR: Unable to open SDL window: " + string(SDL_GetError());
|
const string msg = "ERROR: Unable to open SDL window: " + string(SDL_GetError());
|
||||||
|
@ -315,6 +311,7 @@ bool FBBackendSDL2::setVideoMode(const VideoModeHandler::Mode& mode,
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enableTextEvents(myTextEventsEnabled);
|
||||||
setWindowIcon();
|
setWindowIcon();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -322,7 +319,7 @@ bool FBBackendSDL2::setVideoMode(const VideoModeHandler::Mode& mode,
|
||||||
if(adaptRefresh)
|
if(adaptRefresh)
|
||||||
{
|
{
|
||||||
// Switch to mode for adapted refresh rate
|
// Switch to mode for adapted refresh rate
|
||||||
if(SDL_SetWindowDisplayMode(myWindow, &adaptedSdlMode) != 0)
|
if(!SDL_SetWindowFullscreenMode(myWindow, &adaptedSdlMode))
|
||||||
{
|
{
|
||||||
Logger::error("ERROR: Display refresh rate change failed");
|
Logger::error("ERROR: Display refresh rate change failed");
|
||||||
}
|
}
|
||||||
|
@ -334,31 +331,39 @@ bool FBBackendSDL2::setVideoMode(const VideoModeHandler::Mode& mode,
|
||||||
<< adaptedSdlMode.refresh_rate << " Hz " << "(" << adaptedSdlMode.w << "x" << adaptedSdlMode.h << ")";
|
<< adaptedSdlMode.refresh_rate << " Hz " << "(" << adaptedSdlMode.w << "x" << adaptedSdlMode.h << ")";
|
||||||
Logger::info(msg.view());
|
Logger::info(msg.view());
|
||||||
|
|
||||||
SDL_DisplayMode setSdlMode;
|
const SDL_DisplayMode* setSdlMode = SDL_GetWindowFullscreenMode(myWindow);
|
||||||
SDL_GetWindowDisplayMode(myWindow, &setSdlMode);
|
cerr << setSdlMode->refresh_rate << "Hz\n";
|
||||||
cerr << setSdlMode.refresh_rate << "Hz\n";
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return createRenderer();
|
const bool result = createRenderer();
|
||||||
|
if(result)
|
||||||
|
{
|
||||||
|
// TODO: Checking for fullscreen status later returns invalid results,
|
||||||
|
// so we check and cache it here
|
||||||
|
myIsFullscreen = SDL_GetWindowFlags(myWindow) & SDL_WINDOW_FULLSCREEN;
|
||||||
|
SDL_ShowWindow(myWindow);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
bool FBBackendSDL2::adaptRefreshRate(Int32 displayIndex,
|
bool FBBackendSDL::adaptRefreshRate(Int32 displayIndex,
|
||||||
SDL_DisplayMode& adaptedSdlMode)
|
SDL_DisplayMode& adaptedSdlMode)
|
||||||
{
|
{
|
||||||
ASSERT_MAIN_THREAD;
|
ASSERT_MAIN_THREAD;
|
||||||
|
|
||||||
SDL_DisplayMode sdlMode;
|
const SDL_DisplayMode* sdlMode = SDL_GetCurrentDisplayMode(displayIndex);
|
||||||
|
|
||||||
if(SDL_GetCurrentDisplayMode(displayIndex, &sdlMode) != 0)
|
if(sdlMode == nullptr)
|
||||||
{
|
{
|
||||||
Logger::error("ERROR: Display mode could not be retrieved");
|
Logger::error("ERROR: Display mode could not be retrieved");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
const int currentRefreshRate = sdlMode.refresh_rate;
|
const int currentRefreshRate = sdlMode->refresh_rate;
|
||||||
const int wantedRefreshRate =
|
const int wantedRefreshRate =
|
||||||
myOSystem.hasConsole() ? myOSystem.console().gameRefreshRate() : 0;
|
myOSystem.hasConsole() ? myOSystem.console().gameRefreshRate() : 0;
|
||||||
// Take care of rounded refresh rates (e.g. 59.94 Hz)
|
// Take care of rounded refresh rates (e.g. 59.94 Hz)
|
||||||
|
@ -374,18 +379,19 @@ bool FBBackendSDL2::adaptRefreshRate(Int32 displayIndex,
|
||||||
// Check for integer factors 1 (60/50 Hz) and 2 (120/100 Hz)
|
// Check for integer factors 1 (60/50 Hz) and 2 (120/100 Hz)
|
||||||
for(int m = 1; m <= 2; ++m)
|
for(int m = 1; m <= 2; ++m)
|
||||||
{
|
{
|
||||||
SDL_DisplayMode closestSdlMode;
|
SDL_DisplayMode closestSdlMode{};
|
||||||
|
const float refresh_rate = wantedRefreshRate * m;
|
||||||
|
|
||||||
sdlMode.refresh_rate = wantedRefreshRate * m;
|
if(!SDL_GetClosestFullscreenDisplayMode(displayIndex, sdlMode->w, sdlMode->h, refresh_rate, true, &closestSdlMode))
|
||||||
if(SDL_GetClosestDisplayMode(displayIndex, &sdlMode, &closestSdlMode) == nullptr)
|
|
||||||
{
|
{
|
||||||
Logger::error("ERROR: Closest display mode could not be retrieved");
|
Logger::error("ERROR: Closest display mode could not be retrieved");
|
||||||
return adapt;
|
return adapt;
|
||||||
}
|
}
|
||||||
factor = std::min(
|
factor = std::min(
|
||||||
static_cast<float>(sdlMode.refresh_rate) / sdlMode.refresh_rate,
|
static_cast<float>(refresh_rate) / refresh_rate,
|
||||||
static_cast<float>(sdlMode.refresh_rate) / (sdlMode.refresh_rate - 1));
|
static_cast<float>(refresh_rate) / (refresh_rate - 1));
|
||||||
const float diff = std::abs(factor - std::round(factor)) / factor;
|
const float diff = std::abs(factor - std::round(factor)) / factor;
|
||||||
|
|
||||||
if(diff < bestDiff)
|
if(diff < bestDiff)
|
||||||
{
|
{
|
||||||
bestDiff = diff;
|
bestDiff = diff;
|
||||||
|
@ -405,38 +411,46 @@ bool FBBackendSDL2::adaptRefreshRate(Int32 displayIndex,
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
bool FBBackendSDL2::createRenderer()
|
bool FBBackendSDL::createRenderer()
|
||||||
{
|
{
|
||||||
ASSERT_MAIN_THREAD;
|
ASSERT_MAIN_THREAD;
|
||||||
|
|
||||||
// A new renderer is only created when necessary:
|
// A new renderer is only created when necessary:
|
||||||
// - no renderer existing
|
// - no renderer existing
|
||||||
// - different renderer flags
|
|
||||||
// - different renderer name
|
// - different renderer name
|
||||||
|
// - different renderer vsync
|
||||||
|
const bool enableVSync = myOSystem.settings().getBool("vsync") &&
|
||||||
|
!myOSystem.settings().getBool("turbo");
|
||||||
|
const string& video = myOSystem.settings().getString("video");
|
||||||
|
|
||||||
bool recreate = myRenderer == nullptr;
|
bool recreate = myRenderer == nullptr;
|
||||||
uInt32 renderFlags = SDL_RENDERER_ACCELERATED;
|
if(myRenderer)
|
||||||
const string& video = myOSystem.settings().getString("video"); // Render hint
|
{
|
||||||
SDL_RendererInfo renderInfo;
|
recreate = recreate || video != SDL_GetRendererName(myRenderer);
|
||||||
|
|
||||||
if(myOSystem.settings().getBool("vsync")
|
const SDL_PropertiesID props = SDL_GetRendererProperties(myRenderer);
|
||||||
&& !myOSystem.settings().getBool("turbo")) // V'synced blits option
|
const bool currentVSync = SDL_GetNumberProperty(props,
|
||||||
renderFlags |= SDL_RENDERER_PRESENTVSYNC;
|
SDL_PROP_RENDERER_VSYNC_NUMBER, 0) != 0;
|
||||||
|
recreate = recreate || currentVSync != enableVSync;
|
||||||
// check renderer flags and name
|
}
|
||||||
recreate |= (SDL_GetRendererInfo(myRenderer, &renderInfo) != 0)
|
|
||||||
|| ((renderInfo.flags & (SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC)) != renderFlags
|
|
||||||
|| (video != renderInfo.name));
|
|
||||||
|
|
||||||
if(recreate)
|
if(recreate)
|
||||||
{
|
{
|
||||||
//cerr << "Create new renderer for buffer type #" << int(myBufferType) << '\n';
|
|
||||||
if(myRenderer)
|
if(myRenderer)
|
||||||
SDL_DestroyRenderer(myRenderer);
|
SDL_DestroyRenderer(myRenderer);
|
||||||
|
|
||||||
|
// Re-create with new properties
|
||||||
|
const SDL_PropertiesID props = SDL_CreateProperties();
|
||||||
if(!video.empty())
|
if(!video.empty())
|
||||||
SDL_SetHint(SDL_HINT_RENDER_DRIVER, video.c_str());
|
SDL_SetStringProperty(props, SDL_PROP_RENDERER_CREATE_NAME_STRING,
|
||||||
|
video.c_str());
|
||||||
|
SDL_SetNumberProperty(props, SDL_PROP_RENDERER_CREATE_PRESENT_VSYNC_NUMBER,
|
||||||
|
enableVSync ? 1 : 0);
|
||||||
|
SDL_SetPointerProperty(props, SDL_PROP_RENDERER_CREATE_WINDOW_POINTER,
|
||||||
|
myWindow);
|
||||||
|
|
||||||
myRenderer = SDL_CreateRenderer(myWindow, -1, renderFlags);
|
myRenderer = SDL_CreateRendererWithProperties(props);
|
||||||
|
SDL_DestroyProperties(props);
|
||||||
|
|
||||||
detectFeatures();
|
detectFeatures();
|
||||||
determineDimensions();
|
determineDimensions();
|
||||||
|
@ -450,85 +464,106 @@ bool FBBackendSDL2::createRenderer()
|
||||||
}
|
}
|
||||||
clear();
|
clear();
|
||||||
|
|
||||||
SDL_RendererInfo renderinfo;
|
const char* const detectedvideo = SDL_GetRendererName(myRenderer);
|
||||||
|
if(detectedvideo)
|
||||||
if(SDL_GetRendererInfo(myRenderer, &renderinfo) >= 0)
|
myOSystem.settings().setValue("video", detectedvideo);
|
||||||
myOSystem.settings().setValue("video", renderinfo.name);
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
void FBBackendSDL2::setTitle(string_view title)
|
void FBBackendSDL::setTitle(string_view title)
|
||||||
{
|
{
|
||||||
ASSERT_MAIN_THREAD;
|
ASSERT_MAIN_THREAD;
|
||||||
|
|
||||||
myScreenTitle = title;
|
myScreenTitle = title;
|
||||||
|
|
||||||
if(myWindow)
|
if(myWindow)
|
||||||
SDL_SetWindowTitle(myWindow, string{title}.c_str());
|
SDL_SetWindowTitle(myWindow, myScreenTitle.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
string FBBackendSDL2::about() const
|
string FBBackendSDL::about() const
|
||||||
{
|
{
|
||||||
ASSERT_MAIN_THREAD;
|
ASSERT_MAIN_THREAD;
|
||||||
|
|
||||||
ostringstream out;
|
ostringstream out;
|
||||||
out << "Video system: " << SDL_GetCurrentVideoDriver() << '\n';
|
out << "Video system: " << SDL_GetCurrentVideoDriver() << '\n';
|
||||||
SDL_RendererInfo info;
|
|
||||||
if(SDL_GetRendererInfo(myRenderer, &info) >= 0)
|
const SDL_PropertiesID props = SDL_GetRendererProperties(myRenderer);
|
||||||
|
if(props != 0)
|
||||||
{
|
{
|
||||||
out << " Renderer: " << info.name << '\n';
|
out << " Renderer: "
|
||||||
if(info.max_texture_width > 0 && info.max_texture_height > 0)
|
<< SDL_GetStringProperty(props, SDL_PROP_RENDERER_NAME_STRING, "")
|
||||||
out << " Max texture: " << info.max_texture_width << "x"
|
<< '\n';
|
||||||
<< info.max_texture_height << '\n';
|
const uInt64 maxTexSize =
|
||||||
|
SDL_GetNumberProperty(props, SDL_PROP_RENDERER_MAX_TEXTURE_SIZE_NUMBER, 0);
|
||||||
|
if(maxTexSize > 0)
|
||||||
|
out << " Max texture: " << maxTexSize << "x" << maxTexSize << '\n';
|
||||||
|
const bool usingVSync = SDL_GetNumberProperty(props,
|
||||||
|
SDL_PROP_RENDERER_VSYNC_NUMBER, 0) != 0;
|
||||||
out << " Flags: "
|
out << " Flags: "
|
||||||
<< ((info.flags & SDL_RENDERER_PRESENTVSYNC) ? "+" : "-") << "vsync, "
|
<< (usingVSync ? "+" : "-") << "vsync"
|
||||||
<< ((info.flags & SDL_RENDERER_ACCELERATED) ? "+" : "-") << "accel"
|
|
||||||
<< '\n';
|
<< '\n';
|
||||||
}
|
}
|
||||||
return out.str();
|
return out.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
void FBBackendSDL2::showCursor(bool show)
|
void FBBackendSDL::showCursor(bool show)
|
||||||
{
|
{
|
||||||
ASSERT_MAIN_THREAD;
|
ASSERT_MAIN_THREAD;
|
||||||
|
|
||||||
SDL_ShowCursor(show ? SDL_ENABLE : SDL_DISABLE);
|
if(show) SDL_ShowCursor();
|
||||||
|
else SDL_HideCursor();
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
void FBBackendSDL2::grabMouse(bool grab)
|
void FBBackendSDL::grabMouse(bool grab)
|
||||||
{
|
{
|
||||||
ASSERT_MAIN_THREAD;
|
ASSERT_MAIN_THREAD;
|
||||||
|
|
||||||
SDL_SetRelativeMouseMode(grab ? SDL_TRUE : SDL_FALSE);
|
SDL_SetWindowMouseGrab(myWindow, grab);
|
||||||
|
SDL_SetHint(SDL_HINT_MOUSE_RELATIVE_SYSTEM_SCALE, grab ? "1" : "0");
|
||||||
|
SDL_SetWindowRelativeMouseMode(myWindow, grab);
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
bool FBBackendSDL2::fullScreen() const
|
void FBBackendSDL::enableTextEvents(bool enable)
|
||||||
|
{
|
||||||
|
ASSERT_MAIN_THREAD;
|
||||||
|
|
||||||
|
if(enable)
|
||||||
|
SDL_StartTextInput(myWindow);
|
||||||
|
else
|
||||||
|
SDL_StopTextInput(myWindow);
|
||||||
|
// myWindows can still be null, so we remember the state and set again when
|
||||||
|
// the window is created
|
||||||
|
myTextEventsEnabled = enable;
|
||||||
|
}
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
bool FBBackendSDL::fullScreen() const
|
||||||
{
|
{
|
||||||
ASSERT_MAIN_THREAD;
|
ASSERT_MAIN_THREAD;
|
||||||
|
|
||||||
#ifdef WINDOWED_SUPPORT
|
#ifdef WINDOWED_SUPPORT
|
||||||
return SDL_GetWindowFlags(myWindow) & SDL_WINDOW_FULLSCREEN_DESKTOP;
|
return myIsFullscreen; // TODO: should query SDL directly
|
||||||
#else
|
#else
|
||||||
return true;
|
return true;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
int FBBackendSDL2::refreshRate() const
|
int FBBackendSDL::refreshRate() const
|
||||||
{
|
{
|
||||||
ASSERT_MAIN_THREAD;
|
ASSERT_MAIN_THREAD;
|
||||||
|
|
||||||
const uInt32 displayIndex = SDL_GetWindowDisplayIndex(myWindow);
|
const SDL_DisplayID displayID = getCurrentDisplayID();
|
||||||
SDL_DisplayMode sdlMode;
|
const SDL_DisplayMode* mode = SDL_GetCurrentDisplayMode(displayID);
|
||||||
|
|
||||||
if(SDL_GetCurrentDisplayMode(displayIndex, &sdlMode) == 0)
|
if(mode)
|
||||||
return sdlMode.refresh_rate;
|
return mode->refresh_rate;
|
||||||
|
|
||||||
if(myWindow != nullptr)
|
if(myWindow != nullptr)
|
||||||
Logger::error("Could not retrieve current display mode");
|
Logger::error("Could not retrieve current display mode");
|
||||||
|
@ -537,7 +572,7 @@ int FBBackendSDL2::refreshRate() const
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
void FBBackendSDL2::renderToScreen()
|
void FBBackendSDL::renderToScreen()
|
||||||
{
|
{
|
||||||
ASSERT_MAIN_THREAD;
|
ASSERT_MAIN_THREAD;
|
||||||
|
|
||||||
|
@ -546,35 +581,42 @@ void FBBackendSDL2::renderToScreen()
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
void FBBackendSDL2::setWindowIcon()
|
void FBBackendSDL::setWindowIcon()
|
||||||
{
|
{
|
||||||
#if !defined(BSPF_MACOS) && !defined(RETRON77)
|
#if !defined(BSPF_MACOS)
|
||||||
#include "stella_icon.hxx"
|
#include "stella_icon.hxx"
|
||||||
ASSERT_MAIN_THREAD;
|
ASSERT_MAIN_THREAD;
|
||||||
|
|
||||||
SDL_Surface* surface = SDL_CreateRGBSurfaceFrom(stella_icon, 32, 32, 32,
|
SDL_Surface* surface =
|
||||||
32 * 4, 0xFF0000, 0x00FF00, 0x0000FF, 0xFF000000);
|
SDL_CreateSurfaceFrom(32, 32, pixelFormat().format, stella_icon, 32 * 4);
|
||||||
SDL_SetWindowIcon(myWindow, surface);
|
SDL_SetWindowIcon(myWindow, surface);
|
||||||
SDL_FreeSurface(surface);
|
SDL_DestroySurface(surface);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
unique_ptr<FBSurface> FBBackendSDL2::createSurface(
|
unique_ptr<FBSurface> FBBackendSDL::createSurface(
|
||||||
uInt32 w,
|
uInt32 w,
|
||||||
uInt32 h,
|
uInt32 h,
|
||||||
ScalingInterpolation inter,
|
ScalingInterpolation inter,
|
||||||
const uInt32* data
|
const uInt32* data
|
||||||
) const
|
) const
|
||||||
{
|
{
|
||||||
return make_unique<FBSurfaceSDL2>
|
unique_ptr<FBSurface> s = make_unique<FBSurfaceSDL>
|
||||||
(const_cast<FBBackendSDL2&>(*this), w, h, inter, data);
|
(const_cast<FBBackendSDL&>(*this), w, h, inter, data);
|
||||||
|
s->setBlendLevel(100); // by default, disable shading (use full alpha)
|
||||||
|
|
||||||
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
void FBBackendSDL2::readPixels(uInt8* buffer, size_t pitch,
|
void FBBackendSDL::readPixels(uInt8* buffer, size_t pitch,
|
||||||
const Common::Rect& rect) const
|
const Common::Rect& rect) const
|
||||||
{
|
{
|
||||||
|
// FIXME: this method needs to be refactored to return an FBSurface,
|
||||||
|
// since SDL_RenderReadPixels now returns an SDL_Surface
|
||||||
|
// PNGLibrary is the only user of this; that will need to be refactored too
|
||||||
|
#if 0
|
||||||
ASSERT_MAIN_THREAD;
|
ASSERT_MAIN_THREAD;
|
||||||
|
|
||||||
SDL_Rect r;
|
SDL_Rect r;
|
||||||
|
@ -582,10 +624,11 @@ void FBBackendSDL2::readPixels(uInt8* buffer, size_t pitch,
|
||||||
r.w = rect.w(); r.h = rect.h();
|
r.w = rect.w(); r.h = rect.h();
|
||||||
|
|
||||||
SDL_RenderReadPixels(myRenderer, &r, 0, buffer, static_cast<int>(pitch));
|
SDL_RenderReadPixels(myRenderer, &r, 0, buffer, static_cast<int>(pitch));
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
void FBBackendSDL2::clear()
|
void FBBackendSDL::clear()
|
||||||
{
|
{
|
||||||
ASSERT_MAIN_THREAD;
|
ASSERT_MAIN_THREAD;
|
||||||
|
|
||||||
|
@ -593,7 +636,7 @@ void FBBackendSDL2::clear()
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
void FBBackendSDL2::detectFeatures()
|
void FBBackendSDL::detectFeatures()
|
||||||
{
|
{
|
||||||
myRenderTargetSupport = detectRenderTargetSupport();
|
myRenderTargetSupport = detectRenderTargetSupport();
|
||||||
|
|
||||||
|
@ -602,36 +645,20 @@ void FBBackendSDL2::detectFeatures()
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
bool FBBackendSDL2::detectRenderTargetSupport()
|
bool FBBackendSDL::detectRenderTargetSupport()
|
||||||
{
|
{
|
||||||
ASSERT_MAIN_THREAD;
|
ASSERT_MAIN_THREAD;
|
||||||
|
|
||||||
if(myRenderer == nullptr)
|
if(myRenderer == nullptr)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
SDL_RendererInfo info;
|
// All texture modes except software support render targets
|
||||||
SDL_GetRendererInfo(myRenderer, &info);
|
const char* const detectedvideo = SDL_GetRendererName(myRenderer);
|
||||||
|
return detectedvideo && !BSPF::equalsIgnoreCase(detectedvideo, "software");
|
||||||
if(!(info.flags & SDL_RENDERER_TARGETTEXTURE))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
SDL_Texture* tex =
|
|
||||||
SDL_CreateTexture(myRenderer, myPixelFormat->format,
|
|
||||||
SDL_TEXTUREACCESS_TARGET, 16, 16);
|
|
||||||
|
|
||||||
if(!tex)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
const int sdlError = SDL_SetRenderTarget(myRenderer, tex);
|
|
||||||
SDL_SetRenderTarget(myRenderer, nullptr);
|
|
||||||
|
|
||||||
SDL_DestroyTexture(tex);
|
|
||||||
|
|
||||||
return sdlError == 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
void FBBackendSDL2::determineDimensions()
|
void FBBackendSDL::determineDimensions()
|
||||||
{
|
{
|
||||||
ASSERT_MAIN_THREAD;
|
ASSERT_MAIN_THREAD;
|
||||||
|
|
||||||
|
@ -643,5 +670,5 @@ void FBBackendSDL2::determineDimensions()
|
||||||
myRenderH = myWindowH;
|
myRenderH = myWindowH;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
SDL_GetRendererOutputSize(myRenderer, &myRenderW, &myRenderH);
|
SDL_GetCurrentRenderOutputSize(myRenderer, &myRenderW, &myRenderH);
|
||||||
}
|
}
|
|
@ -8,38 +8,38 @@
|
||||||
// SS SS tt ee ll ll aa aa
|
// SS SS tt ee ll ll aa aa
|
||||||
// SSSS ttt eeeee llll llll aaaaa
|
// SSSS ttt eeeee llll llll aaaaa
|
||||||
//
|
//
|
||||||
// Copyright (c) 1995-2024 by Bradford W. Mott, Stephen Anthony
|
// Copyright (c) 1995-2025 by Bradford W. Mott, Stephen Anthony
|
||||||
// and the Stella Team
|
// and the Stella Team
|
||||||
//
|
//
|
||||||
// See the file "License.txt" for information on usage and redistribution of
|
// See the file "License.txt" for information on usage and redistribution of
|
||||||
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
||||||
//============================================================================
|
//============================================================================
|
||||||
|
|
||||||
#ifndef FB_BACKEND_SDL2_HXX
|
#ifndef FB_BACKEND_SDL_HXX
|
||||||
#define FB_BACKEND_SDL2_HXX
|
#define FB_BACKEND_SDL_HXX
|
||||||
|
|
||||||
#include "SDL_lib.hxx"
|
#include "SDL_lib.hxx"
|
||||||
|
|
||||||
class OSystem;
|
class OSystem;
|
||||||
class FBSurfaceSDL2;
|
class FBSurfaceSDL;
|
||||||
|
|
||||||
#include "bspf.hxx"
|
#include "bspf.hxx"
|
||||||
#include "FBBackend.hxx"
|
#include "FBBackend.hxx"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
This class implements a standard SDL2 2D, hardware accelerated framebuffer
|
This class implements a standard SDL 2D, hardware accelerated framebuffer
|
||||||
backend. Behind the scenes, it may be using Direct3D, OpenGL(ES), etc.
|
backend. Behind the scenes, it may be using Direct3D, OpenGL(ES), etc.
|
||||||
|
|
||||||
@author Stephen Anthony
|
@author Stephen Anthony
|
||||||
*/
|
*/
|
||||||
class FBBackendSDL2 : public FBBackend
|
class FBBackendSDL : public FBBackend
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
Creates a new SDL2 framebuffer
|
Creates a new SDL framebuffer
|
||||||
*/
|
*/
|
||||||
explicit FBBackendSDL2(OSystem& osystem);
|
explicit FBBackendSDL(OSystem& osystem);
|
||||||
~FBBackendSDL2() override;
|
~FBBackendSDL() override;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
|
@ -55,7 +55,7 @@ class FBBackendSDL2 : public FBBackend
|
||||||
/**
|
/**
|
||||||
Get the SDL pixel format.
|
Get the SDL pixel format.
|
||||||
*/
|
*/
|
||||||
const SDL_PixelFormat& pixelFormat() const { return *myPixelFormat; }
|
const SDL_PixelFormatDetails& pixelFormat() const { return *myPixelFormat; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Does the renderer support render targets?
|
Does the renderer support render targets?
|
||||||
|
@ -99,7 +99,7 @@ class FBBackendSDL2 : public FBBackend
|
||||||
@param b The blue component of the color
|
@param b The blue component of the color
|
||||||
*/
|
*/
|
||||||
FORCE_INLINE void getRGB(uInt32 pixel, uInt8* r, uInt8* g, uInt8* b) const override
|
FORCE_INLINE void getRGB(uInt32 pixel, uInt8* r, uInt8* g, uInt8* b) const override
|
||||||
{ SDL_GetRGB(pixel, myPixelFormat, r, g, b); }
|
{ SDL_GetRGB(pixel, myPixelFormat, nullptr, r, g, b); }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
This method is called to retrieve the R/G/B/A data from the given pixel.
|
This method is called to retrieve the R/G/B/A data from the given pixel.
|
||||||
|
@ -111,7 +111,7 @@ class FBBackendSDL2 : public FBBackend
|
||||||
@param a The alpha component of the color.
|
@param a The alpha component of the color.
|
||||||
*/
|
*/
|
||||||
FORCE_INLINE void getRGBA(uInt32 pixel, uInt8* r, uInt8* g, uInt8* b, uInt8* a) const override
|
FORCE_INLINE void getRGBA(uInt32 pixel, uInt8* r, uInt8* g, uInt8* b, uInt8* a) const override
|
||||||
{ SDL_GetRGBA(pixel, myPixelFormat, r, g, b, a); }
|
{ SDL_GetRGBA(pixel, myPixelFormat, nullptr, r, g, b, a); }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
This method is called to map a given R/G/B triple to the screen palette.
|
This method is called to map a given R/G/B triple to the screen palette.
|
||||||
|
@ -121,7 +121,7 @@ class FBBackendSDL2 : public FBBackend
|
||||||
@param b The blue component of the color.
|
@param b The blue component of the color.
|
||||||
*/
|
*/
|
||||||
uInt32 mapRGB(uInt8 r, uInt8 g, uInt8 b) const override
|
uInt32 mapRGB(uInt8 r, uInt8 g, uInt8 b) const override
|
||||||
{ return SDL_MapRGB(myPixelFormat, r, g, b); }
|
{ return SDL_MapRGB(myPixelFormat, nullptr, r, g, b); }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
This method is called to map a given R/G/B/A triple to the screen palette.
|
This method is called to map a given R/G/B/A triple to the screen palette.
|
||||||
|
@ -132,7 +132,7 @@ class FBBackendSDL2 : public FBBackend
|
||||||
@param a The alpha component of the color.
|
@param a The alpha component of the color.
|
||||||
*/
|
*/
|
||||||
uInt32 mapRGBA(uInt8 r, uInt8 g, uInt8 b, uInt8 a) const override
|
uInt32 mapRGBA(uInt8 r, uInt8 g, uInt8 b, uInt8 a) const override
|
||||||
{ return SDL_MapRGBA(myPixelFormat, r, g, b, a); }
|
{ return SDL_MapRGBA(myPixelFormat, nullptr, r, g, b, a); }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
This method is called to get a copy of the specified ARGB data from the
|
This method is called to get a copy of the specified ARGB data from the
|
||||||
|
@ -167,10 +167,9 @@ class FBBackendSDL2 : public FBBackend
|
||||||
This method is called to query the video hardware for the index
|
This method is called to query the video hardware for the index
|
||||||
of the display the current window is displayed on
|
of the display the current window is displayed on
|
||||||
|
|
||||||
@return the current display index or a negative value if no
|
@return the current display index or a 0 if no window is displayed
|
||||||
window is displayed
|
|
||||||
*/
|
*/
|
||||||
Int32 getCurrentDisplayIndex() const override;
|
uInt32 getCurrentDisplayID() const override;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Clear the frame buffer.
|
Clear the frame buffer.
|
||||||
|
@ -223,6 +222,11 @@ class FBBackendSDL2 : public FBBackend
|
||||||
*/
|
*/
|
||||||
void grabMouse(bool grab) override;
|
void grabMouse(bool grab) override;
|
||||||
|
|
||||||
|
/**
|
||||||
|
Enable/disable text events (distinct from single-key events).
|
||||||
|
*/
|
||||||
|
void enableTextEvents(bool enable) override;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
This method is called to provide information about the backend.
|
This method is called to provide information about the backend.
|
||||||
*/
|
*/
|
||||||
|
@ -246,6 +250,20 @@ class FBBackendSDL2 : public FBBackend
|
||||||
*/
|
*/
|
||||||
int refreshRate() const override;
|
int refreshRate() const override;
|
||||||
|
|
||||||
|
/**
|
||||||
|
Checks if the OS theme is set to light.
|
||||||
|
*/
|
||||||
|
bool isLightTheme() const override {
|
||||||
|
return SDL_GetSystemTheme() == SDL_SYSTEM_THEME_LIGHT;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Checks if the OS theme is set to dark.
|
||||||
|
*/
|
||||||
|
bool isDarkTheme() const override {
|
||||||
|
return SDL_GetSystemTheme() == SDL_SYSTEM_THEME_DARK;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Checks if the display refresh rate should be adapted to game refresh
|
Checks if the display refresh rate should be adapted to game refresh
|
||||||
rate in (real) fullscreen mode.
|
rate in (real) fullscreen mode.
|
||||||
|
@ -286,7 +304,18 @@ class FBBackendSDL2 : public FBBackend
|
||||||
SDL_Renderer* myRenderer{nullptr};
|
SDL_Renderer* myRenderer{nullptr};
|
||||||
|
|
||||||
// Used by mapRGB (when palettes are created)
|
// Used by mapRGB (when palettes are created)
|
||||||
SDL_PixelFormat* myPixelFormat{nullptr};
|
const SDL_PixelFormatDetails* myPixelFormat{nullptr};
|
||||||
|
|
||||||
|
// Are we in fullscreen mode?
|
||||||
|
// There seem to be issues with creating the window and renderer separately,
|
||||||
|
// and doing so means we can't query the window for fullscreen status
|
||||||
|
// So we do it at window creation and cache the result
|
||||||
|
// TODO: Is this a bug in SDL?
|
||||||
|
bool myIsFullscreen{false};
|
||||||
|
|
||||||
|
// Text events are sometimes enabled before a window exists
|
||||||
|
// So we cache the request here, and honour it after the window has been created
|
||||||
|
bool myTextEventsEnabled{false};
|
||||||
|
|
||||||
// Center setting of current window
|
// Center setting of current window
|
||||||
bool myCenter{false};
|
bool myCenter{false};
|
||||||
|
@ -298,18 +327,18 @@ class FBBackendSDL2 : public FBBackend
|
||||||
string myScreenTitle;
|
string myScreenTitle;
|
||||||
|
|
||||||
// Number of displays
|
// Number of displays
|
||||||
int myNumDisplays{1};
|
uInt32 myNumDisplays{0};
|
||||||
|
|
||||||
// Window and renderer dimensions
|
// Window and renderer dimensions
|
||||||
int myWindowW{0}, myWindowH{0}, myRenderW{0}, myRenderH{0};
|
int myWindowW{0}, myWindowH{0}, myRenderW{0}, myRenderH{0};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Following constructors and assignment operators not supported
|
// Following constructors and assignment operators not supported
|
||||||
FBBackendSDL2() = delete;
|
FBBackendSDL() = delete;
|
||||||
FBBackendSDL2(const FBBackendSDL2&) = delete;
|
FBBackendSDL(const FBBackendSDL&) = delete;
|
||||||
FBBackendSDL2(FBBackendSDL2&&) = delete;
|
FBBackendSDL(FBBackendSDL&&) = delete;
|
||||||
FBBackendSDL2& operator=(const FBBackendSDL2&) = delete;
|
FBBackendSDL& operator=(const FBBackendSDL&) = delete;
|
||||||
FBBackendSDL2& operator=(FBBackendSDL2&&) = delete;
|
FBBackendSDL& operator=(FBBackendSDL&&) = delete;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
|
@ -8,14 +8,14 @@
|
||||||
// SS SS tt ee ll ll aa aa
|
// SS SS tt ee ll ll aa aa
|
||||||
// SSSS ttt eeeee llll llll aaaaa
|
// SSSS ttt eeeee llll llll aaaaa
|
||||||
//
|
//
|
||||||
// Copyright (c) 1995-2024 by Bradford W. Mott, Stephen Anthony
|
// Copyright (c) 1995-2025 by Bradford W. Mott, Stephen Anthony
|
||||||
// and the Stella Team
|
// and the Stella Team
|
||||||
//
|
//
|
||||||
// See the file "License.txt" for information on usage and redistribution of
|
// See the file "License.txt" for information on usage and redistribution of
|
||||||
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
||||||
//============================================================================
|
//============================================================================
|
||||||
|
|
||||||
#include "FBSurfaceSDL2.hxx"
|
#include "FBSurfaceSDL.hxx"
|
||||||
|
|
||||||
#include "Logger.hxx"
|
#include "Logger.hxx"
|
||||||
#include "ThreadDebugging.hxx"
|
#include "ThreadDebugging.hxx"
|
||||||
|
@ -41,10 +41,10 @@ namespace {
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
FBSurfaceSDL2::FBSurfaceSDL2(FBBackendSDL2& backend,
|
FBSurfaceSDL::FBSurfaceSDL(FBBackendSDL& backend,
|
||||||
uInt32 width, uInt32 height,
|
uInt32 width, uInt32 height,
|
||||||
ScalingInterpolation inter,
|
ScalingInterpolation inter,
|
||||||
const uInt32* staticData)
|
const uInt32* staticData)
|
||||||
: myBackend{backend},
|
: myBackend{backend},
|
||||||
myInterpolationMode{inter}
|
myInterpolationMode{inter}
|
||||||
{
|
{
|
||||||
|
@ -53,19 +53,19 @@ FBSurfaceSDL2::FBSurfaceSDL2(FBBackendSDL2& backend,
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
FBSurfaceSDL2::~FBSurfaceSDL2()
|
FBSurfaceSDL::~FBSurfaceSDL()
|
||||||
{
|
{
|
||||||
ASSERT_MAIN_THREAD;
|
ASSERT_MAIN_THREAD;
|
||||||
|
|
||||||
if(mySurface)
|
if(mySurface)
|
||||||
{
|
{
|
||||||
SDL_FreeSurface(mySurface);
|
SDL_DestroySurface(mySurface);
|
||||||
mySurface = nullptr;
|
mySurface = nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
void FBSurfaceSDL2::fillRect(uInt32 x, uInt32 y, uInt32 w, uInt32 h, ColorId color)
|
void FBSurfaceSDL::fillRect(uInt32 x, uInt32 y, uInt32 w, uInt32 h, ColorId color)
|
||||||
{
|
{
|
||||||
ASSERT_MAIN_THREAD;
|
ASSERT_MAIN_THREAD;
|
||||||
|
|
||||||
|
@ -75,49 +75,49 @@ void FBSurfaceSDL2::fillRect(uInt32 x, uInt32 y, uInt32 w, uInt32 h, ColorId col
|
||||||
tmp.y = y;
|
tmp.y = y;
|
||||||
tmp.w = w;
|
tmp.w = w;
|
||||||
tmp.h = h;
|
tmp.h = h;
|
||||||
SDL_FillRect(mySurface, &tmp, myPalette[color]);
|
SDL_FillSurfaceRect(mySurface, &tmp, myPalette[color]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
uInt32 FBSurfaceSDL2::width() const
|
uInt32 FBSurfaceSDL::width() const
|
||||||
{
|
{
|
||||||
return mySurface->w;
|
return mySurface->w;
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
uInt32 FBSurfaceSDL2::height() const
|
uInt32 FBSurfaceSDL::height() const
|
||||||
{
|
{
|
||||||
return mySurface->h;
|
return mySurface->h;
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
const Common::Rect& FBSurfaceSDL2::srcRect() const
|
const Common::Rect& FBSurfaceSDL::srcRect() const
|
||||||
{
|
{
|
||||||
return mySrcGUIR;
|
return mySrcGUIR;
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
const Common::Rect& FBSurfaceSDL2::dstRect() const
|
const Common::Rect& FBSurfaceSDL::dstRect() const
|
||||||
{
|
{
|
||||||
return myDstGUIR;
|
return myDstGUIR;
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
void FBSurfaceSDL2::setSrcPos(uInt32 x, uInt32 y)
|
void FBSurfaceSDL::setSrcPos(uInt32 x, uInt32 y)
|
||||||
{
|
{
|
||||||
if(setSrcPosInternal(x, y))
|
if(setSrcPosInternal(x, y))
|
||||||
reinitializeBlitter();
|
reinitializeBlitter();
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
void FBSurfaceSDL2::setSrcSize(uInt32 w, uInt32 h)
|
void FBSurfaceSDL::setSrcSize(uInt32 w, uInt32 h)
|
||||||
{
|
{
|
||||||
if(setSrcSizeInternal(w, h))
|
if(setSrcSizeInternal(w, h))
|
||||||
reinitializeBlitter();
|
reinitializeBlitter();
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
void FBSurfaceSDL2::setSrcRect(const Common::Rect& r)
|
void FBSurfaceSDL::setSrcRect(const Common::Rect& r)
|
||||||
{
|
{
|
||||||
const bool posChanged = setSrcPosInternal(r.x(), r.y()),
|
const bool posChanged = setSrcPosInternal(r.x(), r.y()),
|
||||||
sizeChanged = setSrcSizeInternal(r.w(), r.h());
|
sizeChanged = setSrcSizeInternal(r.w(), r.h());
|
||||||
|
@ -127,21 +127,21 @@ void FBSurfaceSDL2::setSrcRect(const Common::Rect& r)
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
void FBSurfaceSDL2::setDstPos(uInt32 x, uInt32 y)
|
void FBSurfaceSDL::setDstPos(uInt32 x, uInt32 y)
|
||||||
{
|
{
|
||||||
if(setDstPosInternal(x, y))
|
if(setDstPosInternal(x, y))
|
||||||
reinitializeBlitter();
|
reinitializeBlitter();
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
void FBSurfaceSDL2::setDstSize(uInt32 w, uInt32 h)
|
void FBSurfaceSDL::setDstSize(uInt32 w, uInt32 h)
|
||||||
{
|
{
|
||||||
if(setDstSizeInternal(w, h))
|
if(setDstSizeInternal(w, h))
|
||||||
reinitializeBlitter();
|
reinitializeBlitter();
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
void FBSurfaceSDL2::setDstRect(const Common::Rect& r)
|
void FBSurfaceSDL::setDstRect(const Common::Rect& r)
|
||||||
{
|
{
|
||||||
const bool posChanged = setDstPosInternal(r.x(), r.y()),
|
const bool posChanged = setDstPosInternal(r.x(), r.y()),
|
||||||
sizeChanged = setDstSizeInternal(r.w(), r.h());
|
sizeChanged = setDstSizeInternal(r.w(), r.h());
|
||||||
|
@ -151,22 +151,23 @@ void FBSurfaceSDL2::setDstRect(const Common::Rect& r)
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
void FBSurfaceSDL2::setVisible(bool visible)
|
void FBSurfaceSDL::setVisible(bool visible)
|
||||||
{
|
{
|
||||||
myIsVisible = visible;
|
myIsVisible = visible;
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
void FBSurfaceSDL2::translateCoords(Int32& x, Int32& y) const
|
void FBSurfaceSDL::translateCoords(Int32& x, Int32& y) const
|
||||||
{
|
{
|
||||||
x -= myDstR.x; x /= myDstR.w / mySrcR.w;
|
x -= myDstR.x; x /= myDstR.w / mySrcR.w;
|
||||||
y -= myDstR.y; y /= myDstR.h / mySrcR.h;
|
y -= myDstR.y; y /= myDstR.h / mySrcR.h;
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
bool FBSurfaceSDL2::render()
|
bool FBSurfaceSDL::render()
|
||||||
{
|
{
|
||||||
if (!myBlitter) reinitializeBlitter();
|
if(!myBlitter)
|
||||||
|
reinitializeBlitter();
|
||||||
|
|
||||||
if(myIsVisible && myBlitter)
|
if(myIsVisible && myBlitter)
|
||||||
{
|
{
|
||||||
|
@ -178,15 +179,15 @@ bool FBSurfaceSDL2::render()
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
void FBSurfaceSDL2::invalidate()
|
void FBSurfaceSDL::invalidate()
|
||||||
{
|
{
|
||||||
ASSERT_MAIN_THREAD;
|
ASSERT_MAIN_THREAD;
|
||||||
|
|
||||||
SDL_FillRect(mySurface, nullptr, 0);
|
SDL_FillSurfaceRect(mySurface, nullptr, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
void FBSurfaceSDL2::invalidateRect(uInt32 x, uInt32 y, uInt32 w, uInt32 h)
|
void FBSurfaceSDL::invalidateRect(uInt32 x, uInt32 y, uInt32 w, uInt32 h)
|
||||||
{
|
{
|
||||||
ASSERT_MAIN_THREAD;
|
ASSERT_MAIN_THREAD;
|
||||||
|
|
||||||
|
@ -198,22 +199,22 @@ void FBSurfaceSDL2::invalidateRect(uInt32 x, uInt32 y, uInt32 w, uInt32 h)
|
||||||
tmp.h = h;
|
tmp.h = h;
|
||||||
// Note: Transparency has to be 0 to clear the rectangle foreground
|
// Note: Transparency has to be 0 to clear the rectangle foreground
|
||||||
// without affecting the background display.
|
// without affecting the background display.
|
||||||
SDL_FillRect(mySurface, &tmp, 0);
|
SDL_FillSurfaceRect(mySurface, &tmp, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
void FBSurfaceSDL2::reload()
|
void FBSurfaceSDL::reload()
|
||||||
{
|
{
|
||||||
reinitializeBlitter(true);
|
reinitializeBlitter(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
void FBSurfaceSDL2::resize(uInt32 width, uInt32 height)
|
void FBSurfaceSDL::resize(uInt32 width, uInt32 height)
|
||||||
{
|
{
|
||||||
ASSERT_MAIN_THREAD;
|
ASSERT_MAIN_THREAD;
|
||||||
|
|
||||||
if(mySurface)
|
if(mySurface)
|
||||||
SDL_FreeSurface(mySurface);
|
SDL_DestroySurface(mySurface);
|
||||||
|
|
||||||
// NOTE: Currently, a resize changes a 'static' surface to 'streaming'
|
// NOTE: Currently, a resize changes a 'static' surface to 'streaming'
|
||||||
// No code currently does this, but we should at least check for it
|
// No code currently does this, but we should at least check for it
|
||||||
|
@ -224,17 +225,13 @@ void FBSurfaceSDL2::resize(uInt32 width, uInt32 height)
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
void FBSurfaceSDL2::createSurface(uInt32 width, uInt32 height,
|
void FBSurfaceSDL::createSurface(uInt32 width, uInt32 height, const uInt32* data)
|
||||||
const uInt32* data)
|
|
||||||
{
|
{
|
||||||
ASSERT_MAIN_THREAD;
|
ASSERT_MAIN_THREAD;
|
||||||
|
|
||||||
// Create a surface in the same format as the parent GL class
|
// Create a surface in the same format as the parent GL class
|
||||||
const SDL_PixelFormat& pf = myBackend.pixelFormat();
|
const SDL_PixelFormatDetails& pf = myBackend.pixelFormat();
|
||||||
|
mySurface = SDL_CreateSurface(width, height, pf.format);
|
||||||
mySurface = SDL_CreateRGBSurface(0, width, height,
|
|
||||||
pf.BitsPerPixel, pf.Rmask, pf.Gmask, pf.Bmask, pf.Amask);
|
|
||||||
//SDL_SetSurfaceBlendMode(mySurface, SDL_BLENDMODE_ADD); // default: SDL_BLENDMODE_BLEND
|
|
||||||
|
|
||||||
// We start out with the src and dst rectangles containing the same
|
// We start out with the src and dst rectangles containing the same
|
||||||
// dimensions, indicating no scaling or re-positioning
|
// dimensions, indicating no scaling or re-positioning
|
||||||
|
@ -246,7 +243,7 @@ void FBSurfaceSDL2::createSurface(uInt32 width, uInt32 height,
|
||||||
////////////////////////////////////////////////////
|
////////////////////////////////////////////////////
|
||||||
// These *must* be set for the parent class
|
// These *must* be set for the parent class
|
||||||
myPixels = static_cast<uInt32*>(mySurface->pixels);
|
myPixels = static_cast<uInt32*>(mySurface->pixels);
|
||||||
myPitch = mySurface->pitch / pf.BytesPerPixel;
|
myPitch = mySurface->pitch / pf.bytes_per_pixel;
|
||||||
////////////////////////////////////////////////////
|
////////////////////////////////////////////////////
|
||||||
|
|
||||||
myIsStatic = data != nullptr;
|
myIsStatic = data != nullptr;
|
||||||
|
@ -258,30 +255,40 @@ void FBSurfaceSDL2::createSurface(uInt32 width, uInt32 height,
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
void FBSurfaceSDL2::reinitializeBlitter(bool force)
|
void FBSurfaceSDL::reinitializeBlitter(bool force)
|
||||||
{
|
{
|
||||||
if (force)
|
if(force)
|
||||||
myBlitter.reset();
|
myBlitter.reset();
|
||||||
|
|
||||||
if (!myBlitter && myBackend.isInitialized())
|
if(!myBlitter && myBackend.isInitialized())
|
||||||
myBlitter = BlitterFactory::createBlitter(
|
myBlitter = BlitterFactory::createBlitter(
|
||||||
myBackend, scalingAlgorithm(myInterpolationMode));
|
myBackend, scalingAlgorithm(myInterpolationMode));
|
||||||
|
|
||||||
if (myBlitter)
|
if(myBlitter)
|
||||||
myBlitter->reinitialize(mySrcR, myDstR, myAttributes,
|
myBlitter->reinitialize(mySrcR, myDstR, myEnableBlend, myBlendLevel,
|
||||||
myIsStatic ? mySurface : nullptr);
|
myIsStatic ? mySurface : nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
void FBSurfaceSDL2::applyAttributes()
|
void FBSurfaceSDL::setBlendLevel(uInt32 percent)
|
||||||
{
|
{
|
||||||
|
myBlendLevel = BSPF::clamp(percent, 0U, 100U);
|
||||||
|
|
||||||
reinitializeBlitter();
|
reinitializeBlitter();
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
void FBSurfaceSDL2::setScalingInterpolation(ScalingInterpolation interpolation)
|
void FBSurfaceSDL::enableBlend(bool enableBlend)
|
||||||
{
|
{
|
||||||
if (interpolation == ScalingInterpolation::sharp &&
|
myEnableBlend = enableBlend;
|
||||||
|
|
||||||
|
reinitializeBlitter();
|
||||||
|
}
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
void FBSurfaceSDL::setScalingInterpolation(ScalingInterpolation interpolation)
|
||||||
|
{
|
||||||
|
if(interpolation == ScalingInterpolation::sharp &&
|
||||||
(
|
(
|
||||||
static_cast<int>(mySrcGUIR.h()) >= myBackend.scaleY(myDstGUIR.h()) ||
|
static_cast<int>(mySrcGUIR.h()) >= myBackend.scaleY(myDstGUIR.h()) ||
|
||||||
static_cast<int>(mySrcGUIR.w()) >= myBackend.scaleX(myDstGUIR.w())
|
static_cast<int>(mySrcGUIR.w()) >= myBackend.scaleX(myDstGUIR.w())
|
||||||
|
@ -289,7 +296,8 @@ void FBSurfaceSDL2::setScalingInterpolation(ScalingInterpolation interpolation)
|
||||||
)
|
)
|
||||||
interpolation = ScalingInterpolation::blur;
|
interpolation = ScalingInterpolation::blur;
|
||||||
|
|
||||||
if (interpolation == myInterpolationMode) return;
|
if(interpolation == myInterpolationMode)
|
||||||
|
return;
|
||||||
|
|
||||||
myInterpolationMode = interpolation;
|
myInterpolationMode = interpolation;
|
||||||
reload();
|
reload();
|
|
@ -8,33 +8,33 @@
|
||||||
// SS SS tt ee ll ll aa aa
|
// SS SS tt ee ll ll aa aa
|
||||||
// SSSS ttt eeeee llll llll aaaaa
|
// SSSS ttt eeeee llll llll aaaaa
|
||||||
//
|
//
|
||||||
// Copyright (c) 1995-2024 by Bradford W. Mott, Stephen Anthony
|
// Copyright (c) 1995-2025 by Bradford W. Mott, Stephen Anthony
|
||||||
// and the Stella Team
|
// and the Stella Team
|
||||||
//
|
//
|
||||||
// See the file "License.txt" for information on usage and redistribution of
|
// See the file "License.txt" for information on usage and redistribution of
|
||||||
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
||||||
//============================================================================
|
//============================================================================
|
||||||
|
|
||||||
#ifndef FBSURFACE_SDL2_HXX
|
#ifndef FBSURFACE_SDL_HXX
|
||||||
#define FBSURFACE_SDL2_HXX
|
#define FBSURFACE_SDL_HXX
|
||||||
|
|
||||||
#include "bspf.hxx"
|
#include "bspf.hxx"
|
||||||
#include "FBSurface.hxx"
|
#include "FBSurface.hxx"
|
||||||
#include "FBBackendSDL2.hxx"
|
#include "FBBackendSDL.hxx"
|
||||||
#include "sdl_blitter/Blitter.hxx"
|
#include "sdl_blitter/Blitter.hxx"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
An FBSurface suitable for the SDL2 Render2D API, making use of hardware
|
An FBSurface suitable for the SDL Render2D API, making use of hardware
|
||||||
acceleration behind the scenes.
|
acceleration behind the scenes.
|
||||||
|
|
||||||
@author Stephen Anthony
|
@author Stephen Anthony
|
||||||
*/
|
*/
|
||||||
class FBSurfaceSDL2 : public FBSurface
|
class FBSurfaceSDL : public FBSurface
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
FBSurfaceSDL2(FBBackendSDL2& backend, uInt32 width, uInt32 height,
|
FBSurfaceSDL(FBBackendSDL& backend, uInt32 width, uInt32 height,
|
||||||
ScalingInterpolation inter, const uInt32* staticData);
|
ScalingInterpolation inter, const uInt32* staticData);
|
||||||
~FBSurfaceSDL2() override;
|
~FBSurfaceSDL() override;
|
||||||
|
|
||||||
// Most of the surface drawing primitives are implemented in FBSurface;
|
// Most of the surface drawing primitives are implemented in FBSurface;
|
||||||
// the ones implemented here use SDL-specific code for extra performance
|
// the ones implemented here use SDL-specific code for extra performance
|
||||||
|
@ -63,14 +63,13 @@ class FBSurfaceSDL2 : public FBSurface
|
||||||
void reload() override;
|
void reload() override;
|
||||||
void resize(uInt32 width, uInt32 height) override;
|
void resize(uInt32 width, uInt32 height) override;
|
||||||
|
|
||||||
|
void enableBlend(bool enable) override;
|
||||||
|
void setBlendLevel(uInt32 percent) override;
|
||||||
void setScalingInterpolation(ScalingInterpolation) override;
|
void setScalingInterpolation(ScalingInterpolation) override;
|
||||||
|
|
||||||
protected:
|
|
||||||
void applyAttributes() override;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool setSrcPosInternal(uInt32 x, uInt32 y) {
|
bool setSrcPosInternal(uInt32 x, uInt32 y) {
|
||||||
if(x != static_cast<uInt32>(mySrcR.x) || y != static_cast<uInt32>(mySrcR.y))
|
if(std::cmp_not_equal(x, mySrcR.x) || std::cmp_not_equal(y, mySrcR.y))
|
||||||
{
|
{
|
||||||
mySrcR.x = x; mySrcR.y = y;
|
mySrcR.x = x; mySrcR.y = y;
|
||||||
mySrcGUIR.moveTo(x, y);
|
mySrcGUIR.moveTo(x, y);
|
||||||
|
@ -79,7 +78,7 @@ class FBSurfaceSDL2 : public FBSurface
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
bool setSrcSizeInternal(uInt32 w, uInt32 h) {
|
bool setSrcSizeInternal(uInt32 w, uInt32 h) {
|
||||||
if(w != static_cast<uInt32>(mySrcR.w) || h != static_cast<uInt32>(mySrcR.h))
|
if(std::cmp_not_equal(w, mySrcR.w) || std::cmp_not_equal(h, mySrcR.h))
|
||||||
{
|
{
|
||||||
mySrcR.w = w; mySrcR.h = h;
|
mySrcR.w = w; mySrcR.h = h;
|
||||||
mySrcGUIR.setWidth(w); mySrcGUIR.setHeight(h);
|
mySrcGUIR.setWidth(w); mySrcGUIR.setHeight(h);
|
||||||
|
@ -88,7 +87,7 @@ class FBSurfaceSDL2 : public FBSurface
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
bool setDstPosInternal(uInt32 x, uInt32 y) {
|
bool setDstPosInternal(uInt32 x, uInt32 y) {
|
||||||
if(x != static_cast<uInt32>(myDstR.x) || y != static_cast<uInt32>(myDstR.y))
|
if(std::cmp_not_equal(x, myDstR.x) || std::cmp_not_equal(y, myDstR.y))
|
||||||
{
|
{
|
||||||
myDstR.x = x; myDstR.y = y;
|
myDstR.x = x; myDstR.y = y;
|
||||||
myDstGUIR.moveTo(x, y);
|
myDstGUIR.moveTo(x, y);
|
||||||
|
@ -97,7 +96,7 @@ class FBSurfaceSDL2 : public FBSurface
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
bool setDstSizeInternal(uInt32 w, uInt32 h) {
|
bool setDstSizeInternal(uInt32 w, uInt32 h) {
|
||||||
if(w != static_cast<uInt32>(myDstR.w) || h != static_cast<uInt32>(myDstR.h))
|
if(std::cmp_not_equal(w, myDstR.w) || std::cmp_not_equal(h, myDstR.h))
|
||||||
{
|
{
|
||||||
myDstR.w = w; myDstR.h = h;
|
myDstR.w = w; myDstR.h = h;
|
||||||
myDstGUIR.setWidth(w); myDstGUIR.setHeight(h);
|
myDstGUIR.setWidth(w); myDstGUIR.setHeight(h);
|
||||||
|
@ -111,18 +110,17 @@ class FBSurfaceSDL2 : public FBSurface
|
||||||
void reinitializeBlitter(bool force = false);
|
void reinitializeBlitter(bool force = false);
|
||||||
|
|
||||||
// Following constructors and assignment operators not supported
|
// Following constructors and assignment operators not supported
|
||||||
FBSurfaceSDL2() = delete;
|
FBSurfaceSDL() = delete;
|
||||||
FBSurfaceSDL2(const FBSurfaceSDL2&) = delete;
|
FBSurfaceSDL(const FBSurfaceSDL&) = delete;
|
||||||
FBSurfaceSDL2(FBSurfaceSDL2&&) = delete;
|
FBSurfaceSDL(FBSurfaceSDL&&) = delete;
|
||||||
FBSurfaceSDL2& operator=(const FBSurfaceSDL2&) = delete;
|
FBSurfaceSDL& operator=(const FBSurfaceSDL&) = delete;
|
||||||
FBSurfaceSDL2& operator=(FBSurfaceSDL2&&) = delete;
|
FBSurfaceSDL& operator=(FBSurfaceSDL&&) = delete;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
FBBackendSDL2& myBackend;
|
FBBackendSDL& myBackend;
|
||||||
|
|
||||||
unique_ptr<Blitter> myBlitter;
|
unique_ptr<Blitter> myBlitter;
|
||||||
ScalingInterpolation myInterpolationMode
|
ScalingInterpolation myInterpolationMode{ScalingInterpolation::none};
|
||||||
{ScalingInterpolation::none};
|
|
||||||
|
|
||||||
SDL_Surface* mySurface{nullptr};
|
SDL_Surface* mySurface{nullptr};
|
||||||
SDL_Rect mySrcR{-1, -1, -1, -1}, myDstR{-1, -1, -1, -1};
|
SDL_Rect mySrcR{-1, -1, -1, -1}, myDstR{-1, -1, -1, -1};
|
|
@ -8,7 +8,7 @@
|
||||||
// SS SS tt ee ll ll aa aa
|
// SS SS tt ee ll ll aa aa
|
||||||
// SSSS ttt eeeee llll llll aaaaa
|
// SSSS ttt eeeee llll llll aaaaa
|
||||||
//
|
//
|
||||||
// Copyright (c) 1995-2024 by Bradford W. Mott, Stephen Anthony
|
// Copyright (c) 1995-2025 by Bradford W. Mott, Stephen Anthony
|
||||||
// and the Stella Team
|
// and the Stella Team
|
||||||
//
|
//
|
||||||
// See the file "License.txt" for information on usage and redistribution of
|
// See the file "License.txt" for information on usage and redistribution of
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
// SS SS tt ee ll ll aa aa
|
// SS SS tt ee ll ll aa aa
|
||||||
// SSSS ttt eeeee llll llll aaaaa
|
// SSSS ttt eeeee llll llll aaaaa
|
||||||
//
|
//
|
||||||
// Copyright (c) 1995-2024 by Bradford W. Mott, Stephen Anthony
|
// Copyright (c) 1995-2025 by Bradford W. Mott, Stephen Anthony
|
||||||
// and the Stella Team
|
// and the Stella Team
|
||||||
//
|
//
|
||||||
// See the file "License.txt" for information on usage and redistribution of
|
// See the file "License.txt" for information on usage and redistribution of
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
// SS SS tt ee ll ll aa aa
|
// SS SS tt ee ll ll aa aa
|
||||||
// SSSS ttt eeeee llll llll aaaaa
|
// SSSS ttt eeeee llll llll aaaaa
|
||||||
//
|
//
|
||||||
// Copyright (c) 1995-2024 by Bradford W. Mott, Stephen Anthony
|
// Copyright (c) 1995-2025 by Bradford W. Mott, Stephen Anthony
|
||||||
// and the Stella Team
|
// and the Stella Team
|
||||||
//
|
//
|
||||||
// See the file "License.txt" for information on usage and redistribution of
|
// See the file "License.txt" for information on usage and redistribution of
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
// SS SS tt ee ll ll aa aa
|
// SS SS tt ee ll ll aa aa
|
||||||
// SSSS ttt eeeee llll llll aaaaa
|
// SSSS ttt eeeee llll llll aaaaa
|
||||||
//
|
//
|
||||||
// Copyright (c) 1995-2024 by Bradford W. Mott, Stephen Anthony
|
// Copyright (c) 1995-2025 by Bradford W. Mott, Stephen Anthony
|
||||||
// and the Stella Team
|
// and the Stella Team
|
||||||
//
|
//
|
||||||
// See the file "License.txt" for information on usage and redistribution of
|
// See the file "License.txt" for information on usage and redistribution of
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
// SS SS tt ee ll ll aa aa
|
// SS SS tt ee ll ll aa aa
|
||||||
// SSSS ttt eeeee llll llll aaaaa
|
// SSSS ttt eeeee llll llll aaaaa
|
||||||
//
|
//
|
||||||
// Copyright (c) 1995-2024 by Bradford W. Mott, Stephen Anthony
|
// Copyright (c) 1995-2025 by Bradford W. Mott, Stephen Anthony
|
||||||
// and the Stella Team
|
// and the Stella Team
|
||||||
//
|
//
|
||||||
// See the file "License.txt" for information on usage and redistribution of
|
// See the file "License.txt" for information on usage and redistribution of
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
// SS SS tt ee ll ll aa aa
|
// SS SS tt ee ll ll aa aa
|
||||||
// SSSS ttt eeeee llll llll aaaaa
|
// SSSS ttt eeeee llll llll aaaaa
|
||||||
//
|
//
|
||||||
// Copyright (c) 1995-2024 by Bradford W. Mott, Stephen Anthony
|
// Copyright (c) 1995-2025 by Bradford W. Mott, Stephen Anthony
|
||||||
// and the Stella Team
|
// and the Stella Team
|
||||||
//
|
//
|
||||||
// See the file "License.txt" for information on usage and redistribution of
|
// See the file "License.txt" for information on usage and redistribution of
|
||||||
|
@ -381,8 +381,7 @@ string HighScoresManager::formattedScore(Int32 score, Int32 width) const
|
||||||
|
|
||||||
if(scoreBCD(jprops))
|
if(scoreBCD(jprops))
|
||||||
{
|
{
|
||||||
if(width > digits)
|
digits = std::max(width, digits);
|
||||||
digits = width;
|
|
||||||
buf << std::setw(digits) << std::setfill(' ') << score;
|
buf << std::setw(digits) << std::setfill(' ') << score;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
// SS SS tt ee ll ll aa aa
|
// SS SS tt ee ll ll aa aa
|
||||||
// SSSS ttt eeeee llll llll aaaaa
|
// SSSS ttt eeeee llll llll aaaaa
|
||||||
//
|
//
|
||||||
// Copyright (c) 1995-2024 by Bradford W. Mott, Stephen Anthony
|
// Copyright (c) 1995-2025 by Bradford W. Mott, Stephen Anthony
|
||||||
// and the Stella Team
|
// and the Stella Team
|
||||||
//
|
//
|
||||||
// See the file "License.txt" for information on usage and redistribution of
|
// See the file "License.txt" for information on usage and redistribution of
|
||||||
|
@ -132,7 +132,7 @@ class HighScoresManager
|
||||||
|
|
||||||
@return The number of score address bytes
|
@return The number of score address bytes
|
||||||
*/
|
*/
|
||||||
static uInt32 numAddrBytes(Int32 digits, Int32 trailing) {
|
static constexpr uInt32 numAddrBytes(Int32 digits, Int32 trailing) {
|
||||||
return (digits - trailing + 1) / 2;
|
return (digits - trailing + 1) / 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
// SS SS tt ee ll ll aa aa
|
// SS SS tt ee ll ll aa aa
|
||||||
// SSSS ttt eeeee llll llll aaaaa
|
// SSSS ttt eeeee llll llll aaaaa
|
||||||
//
|
//
|
||||||
// Copyright (c) 1995-2024 by Bradford W. Mott, Stephen Anthony
|
// Copyright (c) 1995-2025 by Bradford W. Mott, Stephen Anthony
|
||||||
// and the Stella Team
|
// and the Stella Team
|
||||||
//
|
//
|
||||||
// See the file "License.txt" for information on usage and redistribution of
|
// See the file "License.txt" for information on usage and redistribution of
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
// SS SS tt ee ll ll aa aa
|
// SS SS tt ee ll ll aa aa
|
||||||
// SSSS ttt eeeee llll llll aaaaa
|
// SSSS ttt eeeee llll llll aaaaa
|
||||||
//
|
//
|
||||||
// Copyright (c) 1995-2024 by Bradford W. Mott, Stephen Anthony
|
// Copyright (c) 1995-2025 by Bradford W. Mott, Stephen Anthony
|
||||||
// and the Stella Team
|
// and the Stella Team
|
||||||
//
|
//
|
||||||
// See the file "License.txt" for information on usage and redistribution of
|
// See the file "License.txt" for information on usage and redistribution of
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
// SS SS tt ee ll ll aa aa
|
// SS SS tt ee ll ll aa aa
|
||||||
// SSSS ttt eeeee llll llll aaaaa
|
// SSSS ttt eeeee llll llll aaaaa
|
||||||
//
|
//
|
||||||
// Copyright (c) 1995-2024 by Bradford W. Mott, Stephen Anthony
|
// Copyright (c) 1995-2025 by Bradford W. Mott, Stephen Anthony
|
||||||
// and the Stella Team
|
// and the Stella Team
|
||||||
//
|
//
|
||||||
// See the file "License.txt" for information on usage and redistribution of
|
// See the file "License.txt" for information on usage and redistribution of
|
||||||
|
@ -188,27 +188,26 @@ json JoyMap::saveMapping(EventMode mode) const
|
||||||
using MapType = std::pair<JoyMapping, Event::Type>;
|
using MapType = std::pair<JoyMapping, Event::Type>;
|
||||||
std::vector<MapType> sortedMap(myMap.begin(), myMap.end());
|
std::vector<MapType> sortedMap(myMap.begin(), myMap.end());
|
||||||
|
|
||||||
std::sort(sortedMap.begin(), sortedMap.end(),
|
std::ranges::sort(sortedMap, [](const MapType& a, const MapType& b)
|
||||||
[](const MapType& a, const MapType& b)
|
{
|
||||||
{
|
// Event::Type first
|
||||||
// Event::Type first
|
if(a.first.button != b.first.button)
|
||||||
if(a.first.button != b.first.button)
|
return a.first.button < b.first.button;
|
||||||
return a.first.button < b.first.button;
|
|
||||||
|
|
||||||
if(a.first.axis != b.first.axis)
|
if(a.first.axis != b.first.axis)
|
||||||
return a.first.axis < b.first.axis;
|
return a.first.axis < b.first.axis;
|
||||||
|
|
||||||
if(a.first.adir != b.first.adir)
|
if(a.first.adir != b.first.adir)
|
||||||
return a.first.adir < b.first.adir;
|
return a.first.adir < b.first.adir;
|
||||||
|
|
||||||
if(a.first.hat != b.first.hat)
|
if(a.first.hat != b.first.hat)
|
||||||
return a.first.hat < b.first.hat;
|
return a.first.hat < b.first.hat;
|
||||||
|
|
||||||
if(a.first.hdir != b.first.hdir)
|
if(a.first.hdir != b.first.hdir)
|
||||||
return a.first.hdir < b.first.hdir;
|
return a.first.hdir < b.first.hdir;
|
||||||
|
|
||||||
return a.second < b.second;
|
return a.second < b.second;
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
json eventMappings = json::array();
|
json eventMappings = json::array();
|
||||||
|
@ -285,17 +284,17 @@ int JoyMap::loadMapping(const json& eventMappings, EventMode mode)
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
json JoyMap::convertLegacyMapping(string list)
|
json JoyMap::convertLegacyMapping(string lst)
|
||||||
{
|
{
|
||||||
json eventMappings = json::array();
|
json eventMappings = json::array();
|
||||||
|
|
||||||
// Since istringstream swallows whitespace, we have to make the
|
// Since istringstream swallows whitespace, we have to make the
|
||||||
// delimiters be spaces
|
// delimiters be spaces
|
||||||
std::replace(list.begin(), list.end(), '|', ' ');
|
std::ranges::replace(lst, '|', ' ');
|
||||||
std::replace(list.begin(), list.end(), ':', ' ');
|
std::ranges::replace(lst, ':', ' ');
|
||||||
std::replace(list.begin(), list.end(), ',', ' ');
|
std::ranges::replace(lst, ',', ' ');
|
||||||
|
|
||||||
istringstream buf(list);
|
istringstream buf(lst);
|
||||||
int event = 0, button = 0, axis = 0, adir = 0, hat = 0, hdir = 0;
|
int event = 0, button = 0, axis = 0, adir = 0, hat = 0, hdir = 0;
|
||||||
|
|
||||||
while(buf >> event && buf >> button
|
while(buf >> event && buf >> button
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
// SS SS tt ee ll ll aa aa
|
// SS SS tt ee ll ll aa aa
|
||||||
// SSSS ttt eeeee llll llll aaaaa
|
// SSSS ttt eeeee llll llll aaaaa
|
||||||
//
|
//
|
||||||
// Copyright (c) 1995-2024 by Bradford W. Mott, Stephen Anthony
|
// Copyright (c) 1995-2025 by Bradford W. Mott, Stephen Anthony
|
||||||
// and the Stella Team
|
// and the Stella Team
|
||||||
//
|
//
|
||||||
// See the file "License.txt" for information on usage and redistribution of
|
// See the file "License.txt" for information on usage and redistribution of
|
||||||
|
@ -112,7 +112,7 @@ class JoyMap
|
||||||
nlohmann::json saveMapping(EventMode mode) const;
|
nlohmann::json saveMapping(EventMode mode) const;
|
||||||
int loadMapping(const nlohmann::json& eventMappings, EventMode mode);
|
int loadMapping(const nlohmann::json& eventMappings, EventMode mode);
|
||||||
|
|
||||||
static nlohmann::json convertLegacyMapping(string list);
|
static nlohmann::json convertLegacyMapping(string lst);
|
||||||
|
|
||||||
/** Erase all mappings for given mode */
|
/** Erase all mappings for given mode */
|
||||||
void eraseMode(EventMode mode);
|
void eraseMode(EventMode mode);
|
||||||
|
@ -129,10 +129,10 @@ class JoyMap
|
||||||
size_t operator()(const JoyMapping& m)const {
|
size_t operator()(const JoyMapping& m)const {
|
||||||
return std::hash<uInt64>()((static_cast<uInt64>(m.mode)) // 3 bits
|
return std::hash<uInt64>()((static_cast<uInt64>(m.mode)) // 3 bits
|
||||||
+ ((static_cast<uInt64>(m.button)) * 7) // 3 bits
|
+ ((static_cast<uInt64>(m.button)) * 7) // 3 bits
|
||||||
+ (((static_cast<uInt64>(m.axis)) << 0) // 2 bits
|
+ (((static_cast<uInt64>(m.axis)) << 0) // 3 bits
|
||||||
| ((static_cast<uInt64>(m.adir)) << 2) // 2 bits
|
| ((static_cast<uInt64>(m.adir)) << 3) // 2 bits
|
||||||
| ((static_cast<uInt64>(m.hat )) << 4) // 1 bit
|
| ((static_cast<uInt64>(m.hat )) << 5) // 1 bit
|
||||||
| ((static_cast<uInt64>(m.hdir)) << 5) // 2 bits
|
| ((static_cast<uInt64>(m.hdir)) << 6) // 2 bits
|
||||||
) * 61
|
) * 61
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
// SS SS tt ee ll ll aa aa
|
// SS SS tt ee ll ll aa aa
|
||||||
// SSSS ttt eeeee llll llll aaaaa
|
// SSSS ttt eeeee llll llll aaaaa
|
||||||
//
|
//
|
||||||
// Copyright (c) 1995-2024 by Bradford W. Mott, Stephen Anthony
|
// Copyright (c) 1995-2025 by Bradford W. Mott, Stephen Anthony
|
||||||
// and the Stella Team
|
// and the Stella Team
|
||||||
//
|
//
|
||||||
// See the file "License.txt" for information on usage and redistribution of
|
// See the file "License.txt" for information on usage and redistribution of
|
||||||
|
@ -43,8 +43,7 @@ namespace {
|
||||||
StellaMod::KBDM_RGUI,
|
StellaMod::KBDM_RGUI,
|
||||||
StellaMod::KBDM_NUM,
|
StellaMod::KBDM_NUM,
|
||||||
StellaMod::KBDM_CAPS,
|
StellaMod::KBDM_CAPS,
|
||||||
StellaMod::KBDM_MODE,
|
StellaMod::KBDM_MODE
|
||||||
StellaMod::KBDM_RESERVED
|
|
||||||
}) {
|
}) {
|
||||||
if((mask & mod) != mod) continue;
|
if((mask & mod) != mod) continue;
|
||||||
|
|
||||||
|
@ -222,8 +221,7 @@ json KeyMap::saveMapping(EventMode mode) const
|
||||||
using MapType = std::pair<Mapping, Event::Type>;
|
using MapType = std::pair<Mapping, Event::Type>;
|
||||||
std::vector<MapType> sortedMap(myMap.begin(), myMap.end());
|
std::vector<MapType> sortedMap(myMap.begin(), myMap.end());
|
||||||
|
|
||||||
std::sort(sortedMap.begin(), sortedMap.end(),
|
std::ranges::sort(sortedMap, [](const MapType& a, const MapType& b)
|
||||||
[](const MapType& a, const MapType& b)
|
|
||||||
{
|
{
|
||||||
// Event::Type first
|
// Event::Type first
|
||||||
if(a.first.key != b.first.key)
|
if(a.first.key != b.first.key)
|
||||||
|
@ -290,11 +288,11 @@ json KeyMap::convertLegacyMapping(string_view lm)
|
||||||
|
|
||||||
// Since istringstream swallows whitespace, we have to make the
|
// Since istringstream swallows whitespace, we have to make the
|
||||||
// delimiters be spaces
|
// delimiters be spaces
|
||||||
string list{lm};
|
string lst{lm};
|
||||||
std::replace(list.begin(), list.end(), '|', ' ');
|
std::ranges::replace(lst, '|', ' ');
|
||||||
std::replace(list.begin(), list.end(), ':', ' ');
|
std::ranges::replace(lst, ':', ' ');
|
||||||
std::replace(list.begin(), list.end(), ',', ' ');
|
std::ranges::replace(lst, ',', ' ');
|
||||||
istringstream buf(list);
|
istringstream buf(lst);
|
||||||
int event = 0, key = 0, mod = 0;
|
int event = 0, key = 0, mod = 0;
|
||||||
|
|
||||||
while(buf >> event && buf >> key && buf >> mod)
|
while(buf >> event && buf >> key && buf >> mod)
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
// SS SS tt ee ll ll aa aa
|
// SS SS tt ee ll ll aa aa
|
||||||
// SSSS ttt eeeee llll llll aaaaa
|
// SSSS ttt eeeee llll llll aaaaa
|
||||||
//
|
//
|
||||||
// Copyright (c) 1995-2024 by Bradford W. Mott, Stephen Anthony
|
// Copyright (c) 1995-2025 by Bradford W. Mott, Stephen Anthony
|
||||||
// and the Stella Team
|
// and the Stella Team
|
||||||
//
|
//
|
||||||
// See the file "License.txt" for information on usage and redistribution of
|
// See the file "License.txt" for information on usage and redistribution of
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
// SS SS tt ee ll ll aa aa
|
// SS SS tt ee ll ll aa aa
|
||||||
// SSSS ttt eeeee llll llll aaaaa
|
// SSSS ttt eeeee llll llll aaaaa
|
||||||
//
|
//
|
||||||
// Copyright (c) 1995-2024 by Bradford W. Mott, Stephen Anthony
|
// Copyright (c) 1995-2025 by Bradford W. Mott, Stephen Anthony
|
||||||
// and the Stella Team
|
// and the Stella Team
|
||||||
//
|
//
|
||||||
// See the file "License.txt" for information on usage and redistribution of
|
// See the file "License.txt" for information on usage and redistribution of
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
// SS SS tt ee ll ll aa aa
|
// SS SS tt ee ll ll aa aa
|
||||||
// SSSS ttt eeeee llll llll aaaaa
|
// SSSS ttt eeeee llll llll aaaaa
|
||||||
//
|
//
|
||||||
// Copyright (c) 1995-2024 by Bradford W. Mott, Stephen Anthony
|
// Copyright (c) 1995-2025 by Bradford W. Mott, Stephen Anthony
|
||||||
// and the Stella Team
|
// and the Stella Team
|
||||||
//
|
//
|
||||||
// See the file "License.txt" for information on usage and redistribution of
|
// See the file "License.txt" for information on usage and redistribution of
|
||||||
|
@ -17,6 +17,10 @@
|
||||||
|
|
||||||
#include "Logger.hxx"
|
#include "Logger.hxx"
|
||||||
|
|
||||||
|
#ifdef __LIB_RETRO__
|
||||||
|
extern void libretro_logger(int log_level, const char *string);
|
||||||
|
#endif
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
Logger& Logger::instance()
|
Logger& Logger::instance()
|
||||||
{
|
{
|
||||||
|
@ -52,6 +56,10 @@ void Logger::debug(string_view message)
|
||||||
void Logger::logMessage(string_view message, Level level)
|
void Logger::logMessage(string_view message, Level level)
|
||||||
{
|
{
|
||||||
const std::lock_guard<std::mutex> lock(mutex);
|
const std::lock_guard<std::mutex> lock(mutex);
|
||||||
|
|
||||||
|
#ifdef __LIB_RETRO__
|
||||||
|
libretro_logger(static_cast<int>(level), string{message}.c_str());
|
||||||
|
#endif
|
||||||
|
|
||||||
if(level == Logger::Level::ERR)
|
if(level == Logger::Level::ERR)
|
||||||
{
|
{
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
// SS SS tt ee ll ll aa aa
|
// SS SS tt ee ll ll aa aa
|
||||||
// SSSS ttt eeeee llll llll aaaaa
|
// SSSS ttt eeeee llll llll aaaaa
|
||||||
//
|
//
|
||||||
// Copyright (c) 1995-2024 by Bradford W. Mott, Stephen Anthony
|
// Copyright (c) 1995-2025 by Bradford W. Mott, Stephen Anthony
|
||||||
// and the Stella Team
|
// and the Stella Team
|
||||||
//
|
//
|
||||||
// See the file "License.txt" for information on usage and redistribution of
|
// See the file "License.txt" for information on usage and redistribution of
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
// SS SS tt ee ll ll aa aa
|
// SS SS tt ee ll ll aa aa
|
||||||
// SSSS ttt eeeee llll llll aaaaa
|
// SSSS ttt eeeee llll llll aaaaa
|
||||||
//
|
//
|
||||||
// Copyright (c) 1995-2024 by Bradford W. Mott, Stephen Anthony
|
// Copyright (c) 1995-2025 by Bradford W. Mott, Stephen Anthony
|
||||||
// and the Stella Team
|
// and the Stella Team
|
||||||
//
|
//
|
||||||
// See the file "License.txt" for information on usage and redistribution of
|
// See the file "License.txt" for information on usage and redistribution of
|
||||||
|
@ -28,21 +28,13 @@
|
||||||
#include "SerialPort.hxx"
|
#include "SerialPort.hxx"
|
||||||
#if defined(BSPF_UNIX)
|
#if defined(BSPF_UNIX)
|
||||||
#include "SerialPortUNIX.hxx"
|
#include "SerialPortUNIX.hxx"
|
||||||
#if defined(RETRON77)
|
#include "OSystemUNIX.hxx"
|
||||||
#include "SettingsR77.hxx"
|
|
||||||
#include "OSystemR77.hxx"
|
|
||||||
#else
|
|
||||||
#include "OSystemUNIX.hxx"
|
|
||||||
#endif
|
|
||||||
#elif defined(BSPF_WINDOWS)
|
#elif defined(BSPF_WINDOWS)
|
||||||
#include "SerialPortWINDOWS.hxx"
|
#include "SerialPortWINDOWS.hxx"
|
||||||
#include "OSystemWINDOWS.hxx"
|
#include "OSystemWINDOWS.hxx"
|
||||||
#elif defined(BSPF_MACOS)
|
#elif defined(BSPF_MACOS)
|
||||||
#include "SerialPortMACOS.hxx"
|
#include "SerialPortMACOS.hxx"
|
||||||
#include "OSystemMACOS.hxx"
|
#include "OSystemMACOS.hxx"
|
||||||
extern "C" {
|
|
||||||
int stellaMain(int argc, char* argv[]);
|
|
||||||
}
|
|
||||||
#elif defined(__LIB_RETRO__)
|
#elif defined(__LIB_RETRO__)
|
||||||
#include "OSystemLIBRETRO.hxx"
|
#include "OSystemLIBRETRO.hxx"
|
||||||
#else
|
#else
|
||||||
|
@ -53,8 +45,8 @@
|
||||||
#include "EventHandlerLIBRETRO.hxx"
|
#include "EventHandlerLIBRETRO.hxx"
|
||||||
#include "FBBackendLIBRETRO.hxx"
|
#include "FBBackendLIBRETRO.hxx"
|
||||||
#elif defined(SDL_SUPPORT)
|
#elif defined(SDL_SUPPORT)
|
||||||
#include "EventHandlerSDL2.hxx"
|
#include "EventHandlerSDL.hxx"
|
||||||
#include "FBBackendSDL2.hxx"
|
#include "FBBackendSDL.hxx"
|
||||||
#else
|
#else
|
||||||
#error Unsupported backend!
|
#error Unsupported backend!
|
||||||
#endif
|
#endif
|
||||||
|
@ -63,7 +55,7 @@
|
||||||
#if defined(__LIB_RETRO__)
|
#if defined(__LIB_RETRO__)
|
||||||
#include "SoundLIBRETRO.hxx"
|
#include "SoundLIBRETRO.hxx"
|
||||||
#elif defined(SDL_SUPPORT)
|
#elif defined(SDL_SUPPORT)
|
||||||
#include "SoundSDL2.hxx"
|
#include "SoundSDL.hxx"
|
||||||
#else
|
#else
|
||||||
#include "SoundNull.hxx"
|
#include "SoundNull.hxx"
|
||||||
#endif
|
#endif
|
||||||
|
@ -78,10 +70,6 @@ class AudioSettings;
|
||||||
implementations for the various ports of Stella, and always returns a
|
implementations for the various ports of Stella, and always returns a
|
||||||
valid object based on the specific port and restrictions on that port.
|
valid object based on the specific port and restrictions on that port.
|
||||||
|
|
||||||
As of SDL2, this code is greatly simplified. However, it remains here
|
|
||||||
in case we ever have multiple backend implementations again (should
|
|
||||||
not be necessary since SDL2 covers this nicely).
|
|
||||||
|
|
||||||
@author Stephen Anthony
|
@author Stephen Anthony
|
||||||
*/
|
*/
|
||||||
class MediaFactory
|
class MediaFactory
|
||||||
|
@ -90,11 +78,7 @@ class MediaFactory
|
||||||
static unique_ptr<OSystem> createOSystem()
|
static unique_ptr<OSystem> createOSystem()
|
||||||
{
|
{
|
||||||
#if defined(BSPF_UNIX)
|
#if defined(BSPF_UNIX)
|
||||||
#if defined(RETRON77)
|
return make_unique<OSystemUNIX>();
|
||||||
return make_unique<OSystemR77>();
|
|
||||||
#else
|
|
||||||
return make_unique<OSystemUNIX>();
|
|
||||||
#endif
|
|
||||||
#elif defined(BSPF_WINDOWS)
|
#elif defined(BSPF_WINDOWS)
|
||||||
return make_unique<OSystemWINDOWS>();
|
return make_unique<OSystemWINDOWS>();
|
||||||
#elif defined(BSPF_MACOS)
|
#elif defined(BSPF_MACOS)
|
||||||
|
@ -108,11 +92,7 @@ class MediaFactory
|
||||||
|
|
||||||
static unique_ptr<Settings> createSettings()
|
static unique_ptr<Settings> createSettings()
|
||||||
{
|
{
|
||||||
#ifdef RETRON77
|
|
||||||
return make_unique<SettingsR77>();
|
|
||||||
#else
|
|
||||||
return make_unique<Settings>();
|
return make_unique<Settings>();
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static unique_ptr<SerialPort> createSerialPort()
|
static unique_ptr<SerialPort> createSerialPort()
|
||||||
|
@ -133,7 +113,7 @@ class MediaFactory
|
||||||
#if defined(__LIB_RETRO__)
|
#if defined(__LIB_RETRO__)
|
||||||
return make_unique<FBBackendLIBRETRO>(osystem);
|
return make_unique<FBBackendLIBRETRO>(osystem);
|
||||||
#elif defined(SDL_SUPPORT)
|
#elif defined(SDL_SUPPORT)
|
||||||
return make_unique<FBBackendSDL2>(osystem);
|
return make_unique<FBBackendSDL>(osystem);
|
||||||
#else
|
#else
|
||||||
#error Unsupported platform for FrameBuffer!
|
#error Unsupported platform for FrameBuffer!
|
||||||
#endif
|
#endif
|
||||||
|
@ -145,7 +125,7 @@ class MediaFactory
|
||||||
#if defined(__LIB_RETRO__)
|
#if defined(__LIB_RETRO__)
|
||||||
return make_unique<SoundLIBRETRO>(osystem, audioSettings);
|
return make_unique<SoundLIBRETRO>(osystem, audioSettings);
|
||||||
#elif defined(SOUND_SUPPORT) && defined(SDL_SUPPORT)
|
#elif defined(SOUND_SUPPORT) && defined(SDL_SUPPORT)
|
||||||
return make_unique<SoundSDL2>(osystem, audioSettings);
|
return make_unique<SoundSDL>(osystem, audioSettings);
|
||||||
#else
|
#else
|
||||||
return make_unique<SoundNull>(osystem);
|
return make_unique<SoundNull>(osystem);
|
||||||
#endif
|
#endif
|
||||||
|
@ -159,7 +139,7 @@ class MediaFactory
|
||||||
#if defined(__LIB_RETRO__)
|
#if defined(__LIB_RETRO__)
|
||||||
return make_unique<EventHandlerLIBRETRO>(osystem);
|
return make_unique<EventHandlerLIBRETRO>(osystem);
|
||||||
#elif defined(SDL_SUPPORT)
|
#elif defined(SDL_SUPPORT)
|
||||||
return make_unique<EventHandlerSDL2>(osystem);
|
return make_unique<EventHandlerSDL>(osystem);
|
||||||
#else
|
#else
|
||||||
#error Unsupported platform for EventHandler!
|
#error Unsupported platform for EventHandler!
|
||||||
#endif
|
#endif
|
||||||
|
@ -181,15 +161,6 @@ class MediaFactory
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool supportsURL()
|
|
||||||
{
|
|
||||||
#if defined(SDL_SUPPORT)
|
|
||||||
return SDLSupportsURL();
|
|
||||||
#else
|
|
||||||
return false;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool openURL(const string& url)
|
static bool openURL(const string& url)
|
||||||
{
|
{
|
||||||
#if defined(SDL_SUPPORT)
|
#if defined(SDL_SUPPORT)
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
// SS SS tt ee ll ll aa aa
|
// SS SS tt ee ll ll aa aa
|
||||||
// SSSS ttt eeeee llll llll aaaaa
|
// SSSS ttt eeeee llll llll aaaaa
|
||||||
//
|
//
|
||||||
// Copyright (c) 1995-2024 by Bradford W. Mott, Stephen Anthony
|
// Copyright (c) 1995-2025 by Bradford W. Mott, Stephen Anthony
|
||||||
// and the Stella Team
|
// and the Stella Team
|
||||||
//
|
//
|
||||||
// See the file "License.txt" for information on usage and redistribution of
|
// See the file "License.txt" for information on usage and redistribution of
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
// SS SS tt ee ll ll aa aa
|
// SS SS tt ee ll ll aa aa
|
||||||
// SSSS ttt eeeee llll llll aaaaa
|
// SSSS ttt eeeee llll llll aaaaa
|
||||||
//
|
//
|
||||||
// Copyright (c) 1995-2024 by Bradford W. Mott, Stephen Anthony
|
// Copyright (c) 1995-2025 by Bradford W. Mott, Stephen Anthony
|
||||||
// and the Stella Team
|
// and the Stella Team
|
||||||
//
|
//
|
||||||
// See the file "License.txt" for information on usage and redistribution of
|
// See the file "License.txt" for information on usage and redistribution of
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
// SS SS tt ee ll ll aa aa
|
// SS SS tt ee ll ll aa aa
|
||||||
// SSSS ttt eeeee llll llll aaaaa
|
// SSSS ttt eeeee llll llll aaaaa
|
||||||
//
|
//
|
||||||
// Copyright (c) 1995-2024 by Bradford W. Mott, Stephen Anthony
|
// Copyright (c) 1995-2025 by Bradford W. Mott, Stephen Anthony
|
||||||
// and the Stella Team
|
// and the Stella Team
|
||||||
//
|
//
|
||||||
// See the file "License.txt" for information on usage and redistribution of
|
// See the file "License.txt" for information on usage and redistribution of
|
||||||
|
@ -405,18 +405,11 @@ void PhysicalJoystickHandler::setStickDefaultMapping(
|
||||||
setDefaultAction(stick, item, event, EventMode::kDrivingMode, updateDefaults);
|
setDefaultAction(stick, item, event, EventMode::kDrivingMode, updateDefaults);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(RETRON77)
|
|
||||||
constexpr bool retron77 = true;
|
|
||||||
#else
|
|
||||||
constexpr bool retron77 = false;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Regular joysticks can only be used by one player at a time,
|
// Regular joysticks can only be used by one player at a time,
|
||||||
// so we need to separate the paddles onto different
|
// so we need to separate the paddles onto different
|
||||||
// devices. The R77 controllers support two players each when
|
// devices. The Stelladaptor and 2600-daptor controllers support
|
||||||
// used as paddles, so are different. Similarly, stelladaptors
|
// two players each when used as paddles, so are different.
|
||||||
// and 2600-daptors support two players natively.
|
const int paddlesPerJoystick = (j->type == PhysicalJoystick::Type::REGULAR) ? 1 : 2;
|
||||||
const int paddlesPerJoystick = (j->type == PhysicalJoystick::Type::REGULAR && !retron77) ? 1 : 2;
|
|
||||||
|
|
||||||
if(paddlesPerJoystick == 2)
|
if(paddlesPerJoystick == 2)
|
||||||
{
|
{
|
||||||
|
@ -1355,17 +1348,11 @@ PhysicalJoystickHandler::EventMappingArray PhysicalJoystickHandler::DefaultRight
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
PhysicalJoystickHandler::EventMappingArray PhysicalJoystickHandler::DefaultLeftPaddlesMapping = {
|
PhysicalJoystickHandler::EventMappingArray PhysicalJoystickHandler::DefaultLeftPaddlesMapping = {
|
||||||
{Event::LeftPaddleAAnalog, JOY_CTRL_NONE, JoyAxis::X, JoyDir::ANALOG},
|
{Event::LeftPaddleAAnalog, JOY_CTRL_NONE, JoyAxis::X, JoyDir::ANALOG},
|
||||||
#if defined(RETRON77)
|
|
||||||
{Event::LeftPaddleAAnalog, JOY_CTRL_NONE, JoyAxis::Z, JoyDir::ANALOG},
|
|
||||||
#endif
|
|
||||||
// Current code does NOT allow digital and anlog events on the same axis at the same time
|
// Current code does NOT allow digital and anlog events on the same axis at the same time
|
||||||
//{Event::LeftPaddleADecrease, JOY_CTRL_NONE, JoyAxis::X, JoyDir::POS},
|
//{Event::LeftPaddleADecrease, JOY_CTRL_NONE, JoyAxis::X, JoyDir::POS},
|
||||||
//{Event::LeftPaddleAIncrease, JOY_CTRL_NONE, JoyAxis::X, JoyDir::NEG},
|
//{Event::LeftPaddleAIncrease, JOY_CTRL_NONE, JoyAxis::X, JoyDir::NEG},
|
||||||
{Event::LeftPaddleAFire, 0},
|
{Event::LeftPaddleAFire, 0},
|
||||||
{Event::LeftPaddleBAnalog, JOY_CTRL_NONE, JoyAxis::Y, JoyDir::ANALOG},
|
{Event::LeftPaddleBAnalog, JOY_CTRL_NONE, JoyAxis::Y, JoyDir::ANALOG},
|
||||||
#if defined(RETRON77)
|
|
||||||
{Event::LeftPaddleBAnalog, JOY_CTRL_NONE, JoyAxis::A3, JoyDir::ANALOG},
|
|
||||||
#endif
|
|
||||||
// Current code does NOT allow digital and anlog events on the same axis at the same
|
// Current code does NOT allow digital and anlog events on the same axis at the same
|
||||||
//{Event::LeftPaddleBDecrease, JOY_CTRL_NONE, JoyAxis::Y, JoyDir::POS},
|
//{Event::LeftPaddleBDecrease, JOY_CTRL_NONE, JoyAxis::Y, JoyDir::POS},
|
||||||
//{Event::LeftPaddleBIncrease, JOY_CTRL_NONE, JoyAxis::Y, JoyDir::NEG},
|
//{Event::LeftPaddleBIncrease, JOY_CTRL_NONE, JoyAxis::Y, JoyDir::NEG},
|
||||||
|
@ -1375,17 +1362,11 @@ PhysicalJoystickHandler::EventMappingArray PhysicalJoystickHandler::DefaultLeftP
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
PhysicalJoystickHandler::EventMappingArray PhysicalJoystickHandler::DefaultRightPaddlesMapping = {
|
PhysicalJoystickHandler::EventMappingArray PhysicalJoystickHandler::DefaultRightPaddlesMapping = {
|
||||||
{Event::RightPaddleAAnalog, JOY_CTRL_NONE, JoyAxis::X, JoyDir::ANALOG},
|
{Event::RightPaddleAAnalog, JOY_CTRL_NONE, JoyAxis::X, JoyDir::ANALOG},
|
||||||
#if defined(RETRON77)
|
|
||||||
{Event::RightPaddleAAnalog, JOY_CTRL_NONE, JoyAxis::Z, JoyDir::ANALOG},
|
|
||||||
#endif
|
|
||||||
// Current code does NOT allow digital and anlog events on the same axis at the same
|
// Current code does NOT allow digital and anlog events on the same axis at the same
|
||||||
//{Event::RightPaddleADecrease, JOY_CTRL_NONE, JoyAxis::X, JoyDir::POS},
|
//{Event::RightPaddleADecrease, JOY_CTRL_NONE, JoyAxis::X, JoyDir::POS},
|
||||||
//{Event::RightPaddleAIncrease, JOY_CTRL_NONE, JoyAxis::X, JoyDir::NEG},
|
//{Event::RightPaddleAIncrease, JOY_CTRL_NONE, JoyAxis::X, JoyDir::NEG},
|
||||||
{Event::RightPaddleAFire, 0},
|
{Event::RightPaddleAFire, 0},
|
||||||
{Event::RightPaddleBAnalog, JOY_CTRL_NONE, JoyAxis::Y, JoyDir::ANALOG},
|
{Event::RightPaddleBAnalog, JOY_CTRL_NONE, JoyAxis::Y, JoyDir::ANALOG},
|
||||||
#if defined(RETRON77)
|
|
||||||
{Event::RightPaddleBAnalog, JOY_CTRL_NONE, JoyAxis::A3, JoyDir::ANALOG},
|
|
||||||
#endif
|
|
||||||
// Current code does NOT allow digital and anlog events on the same axis at the same
|
// Current code does NOT allow digital and anlog events on the same axis at the same
|
||||||
//{Event::RightPaddleBDecrease,JOY_CTRL_NONE, JoyAxis::Y, JoyDir::POS},
|
//{Event::RightPaddleBDecrease,JOY_CTRL_NONE, JoyAxis::Y, JoyDir::POS},
|
||||||
//{Event::RightPaddleBIncrease,JOY_CTRL_NONE, JoyAxis::Y, JoyDir::NEG},
|
//{Event::RightPaddleBIncrease,JOY_CTRL_NONE, JoyAxis::Y, JoyDir::NEG},
|
||||||
|
@ -1485,14 +1466,6 @@ PhysicalJoystickHandler::EventMappingArray
|
||||||
PhysicalJoystickHandler::DefaultCommonMapping = {
|
PhysicalJoystickHandler::DefaultCommonMapping = {
|
||||||
// valid for all joysticks
|
// valid for all joysticks
|
||||||
// Note: buttons 0..2 are used by controllers!
|
// Note: buttons 0..2 are used by controllers!
|
||||||
#if defined(RETRON77)
|
|
||||||
{Event::CmdMenuMode, 3}, // Button "Y" / "4"
|
|
||||||
{Event::ExitMode, 4}, // Left Shoulder Button
|
|
||||||
{Event::OptionsMenuMode, 5}, // Right Shoulder Button
|
|
||||||
{Event::RewindPause, 7}, // Right Trigger Button
|
|
||||||
{Event::ConsoleSelect, 8}, // Button "Select"
|
|
||||||
{Event::ConsoleReset, 9}, // Button "Start"
|
|
||||||
#else
|
|
||||||
{Event::ConsoleSelect, 8}, // Button "Select"
|
{Event::ConsoleSelect, 8}, // Button "Select"
|
||||||
{Event::ConsoleReset, 9}, // Button "Start"
|
{Event::ConsoleReset, 9}, // Button "Start"
|
||||||
{Event::ConsoleColorToggle, 3}, // Button "Y" / "4"
|
{Event::ConsoleColorToggle, 3}, // Button "Y" / "4"
|
||||||
|
@ -1500,7 +1473,6 @@ PhysicalJoystickHandler::DefaultCommonMapping = {
|
||||||
{Event::ConsoleRightDiffToggle, 5}, // Right Shoulder Button
|
{Event::ConsoleRightDiffToggle, 5}, // Right Shoulder Button
|
||||||
{Event::CmdMenuMode, 6}, // Left Trigger Button
|
{Event::CmdMenuMode, 6}, // Left Trigger Button
|
||||||
{Event::OptionsMenuMode, 7}, // Right Trigger Button
|
{Event::OptionsMenuMode, 7}, // Right Trigger Button
|
||||||
#endif
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
// SS SS tt ee ll ll aa aa
|
// SS SS tt ee ll ll aa aa
|
||||||
// SSSS ttt eeeee llll llll aaaaa
|
// SSSS ttt eeeee llll llll aaaaa
|
||||||
//
|
//
|
||||||
// Copyright (c) 1995-2024 by Bradford W. Mott, Stephen Anthony
|
// Copyright (c) 1995-2025 by Bradford W. Mott, Stephen Anthony
|
||||||
// and the Stella Team
|
// and the Stella Team
|
||||||
//
|
//
|
||||||
// See the file "License.txt" for information on usage and redistribution of
|
// See the file "License.txt" for information on usage and redistribution of
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
// SS SS tt ee ll ll aa aa
|
// SS SS tt ee ll ll aa aa
|
||||||
// SSSS ttt eeeee llll llll aaaaa
|
// SSSS ttt eeeee llll llll aaaaa
|
||||||
//
|
//
|
||||||
// Copyright (c) 1995-2024 by Bradford W. Mott, Stephen Anthony
|
// Copyright (c) 1995-2025 by Bradford W. Mott, Stephen Anthony
|
||||||
// and the Stella Team
|
// and the Stella Team
|
||||||
//
|
//
|
||||||
// See the file "License.txt" for information on usage and redistribution of
|
// See the file "License.txt" for information on usage and redistribution of
|
||||||
|
@ -806,18 +806,10 @@ PhysicalKeyboardHandler::DefaultCommonMapping = {
|
||||||
{ Event::HighScoresMenuMode, KBDK_INSERT },
|
{ Event::HighScoresMenuMode, KBDK_INSERT },
|
||||||
{ Event::TogglePlayBackMode, KBDK_SPACE, KBDM_SHIFT },
|
{ Event::TogglePlayBackMode, KBDK_SPACE, KBDM_SHIFT },
|
||||||
|
|
||||||
#if defined(RETRON77)
|
|
||||||
{ Event::ConsoleColorToggle, KBDK_F4 }, // back ("COLOR","B/W")
|
|
||||||
{ Event::ConsoleLeftDiffToggle, KBDK_F6 }, // front ("SKILL P1")
|
|
||||||
{ Event::ConsoleRightDiffToggle, KBDK_F8 }, // front ("SKILL P2")
|
|
||||||
{ Event::CmdMenuMode, KBDK_F13 }, // back ("4:3","16:9")
|
|
||||||
{ Event::ExitMode, KBDK_BACKSPACE }, // back ("FRY")
|
|
||||||
#else // defining duplicate keys must be avoided!
|
|
||||||
{ Event::ConsoleBlackWhite, KBDK_F4 },
|
{ Event::ConsoleBlackWhite, KBDK_F4 },
|
||||||
{ Event::ConsoleLeftDiffB, KBDK_F6 },
|
{ Event::ConsoleLeftDiffB, KBDK_F6 },
|
||||||
{ Event::ConsoleRightDiffB, KBDK_F8 },
|
{ Event::ConsoleRightDiffB, KBDK_F8 },
|
||||||
{ Event::Fry, KBDK_BACKSPACE, KBDM_SHIFT },
|
{ Event::Fry, KBDK_BACKSPACE, KBDM_SHIFT }
|
||||||
#endif
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
@ -862,24 +854,12 @@ PhysicalKeyboardHandler::DefaultMenuMapping = {
|
||||||
{Event::Quit, KBDK_Q, KBDM_CTRL},
|
{Event::Quit, KBDK_Q, KBDM_CTRL},
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(RETRON77)
|
|
||||||
{Event::UIUp, KBDK_F9}, // front ("SAVE")
|
|
||||||
{Event::UIDown, KBDK_F2}, // front ("RESET")
|
|
||||||
{Event::UINavPrev, KBDK_F11}, // front ("LOAD")
|
|
||||||
{Event::UINavNext, KBDK_F1}, // front ("MODE")
|
|
||||||
{Event::UISelect, KBDK_F6}, // front ("SKILL P1")
|
|
||||||
{Event::UICancel, KBDK_F8}, // front ("SKILL P2")
|
|
||||||
//{Event::NoType, KBDK_F4}, // back ("COLOR","B/W")
|
|
||||||
{Event::UITabPrev, KBDK_F13}, // back ("4:3","16:9")
|
|
||||||
{Event::UITabNext, KBDK_BACKSPACE}, // back (FRY)
|
|
||||||
#else // defining duplicate keys must be avoided!
|
|
||||||
{Event::UIPrevDir, KBDK_BACKSPACE},
|
{Event::UIPrevDir, KBDK_BACKSPACE},
|
||||||
#ifdef BSPF_MACOS
|
#ifdef BSPF_MACOS
|
||||||
{Event::UIHelp, KBDK_SLASH, KBDM_SHIFT | CMD},
|
{Event::UIHelp, KBDK_SLASH, KBDM_SHIFT | CMD},
|
||||||
#else
|
#else
|
||||||
{Event::UIHelp, KBDK_F1},
|
{Event::UIHelp, KBDK_F1},
|
||||||
#endif
|
#endif
|
||||||
#endif
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef GUI_SUPPORT
|
#ifdef GUI_SUPPORT
|
||||||
|
@ -1037,6 +1017,8 @@ PhysicalKeyboardHandler::DefaultPaddleMapping = {
|
||||||
{Event::LeftPaddleAFire, KBDK_SPACE},
|
{Event::LeftPaddleAFire, KBDK_SPACE},
|
||||||
{Event::LeftPaddleAFire, KBDK_LCTRL},
|
{Event::LeftPaddleAFire, KBDK_LCTRL},
|
||||||
{Event::LeftPaddleAFire, KBDK_KP_5},
|
{Event::LeftPaddleAFire, KBDK_KP_5},
|
||||||
|
{Event::LeftPaddleAButton1, KBDK_UP, KBDM_SHIFT},
|
||||||
|
{Event::LeftPaddleAButton2, KBDK_DOWN, KBDM_SHIFT},
|
||||||
|
|
||||||
{Event::LeftPaddleBDecrease, KBDK_DOWN},
|
{Event::LeftPaddleBDecrease, KBDK_DOWN},
|
||||||
{Event::LeftPaddleBIncrease, KBDK_UP},
|
{Event::LeftPaddleBIncrease, KBDK_UP},
|
||||||
|
@ -1046,6 +1028,8 @@ PhysicalKeyboardHandler::DefaultPaddleMapping = {
|
||||||
{Event::RightPaddleADecrease, KBDK_J},
|
{Event::RightPaddleADecrease, KBDK_J},
|
||||||
{Event::RightPaddleAIncrease, KBDK_G},
|
{Event::RightPaddleAIncrease, KBDK_G},
|
||||||
{Event::RightPaddleAFire, KBDK_F},
|
{Event::RightPaddleAFire, KBDK_F},
|
||||||
|
{Event::RightPaddleAButton1, KBDK_Y, KBDM_SHIFT},
|
||||||
|
{Event::RightPaddleAButton2, KBDK_H, KBDM_SHIFT},
|
||||||
|
|
||||||
{Event::RightPaddleBDecrease, KBDK_H},
|
{Event::RightPaddleBDecrease, KBDK_H},
|
||||||
{Event::RightPaddleBIncrease, KBDK_Y},
|
{Event::RightPaddleBIncrease, KBDK_Y},
|
||||||
|
@ -1097,10 +1081,16 @@ PhysicalKeyboardHandler::EventMappingArray PhysicalKeyboardHandler::DefaultDrivi
|
||||||
{Event::LeftDrivingFire, KBDK_SPACE},
|
{Event::LeftDrivingFire, KBDK_SPACE},
|
||||||
{Event::LeftDrivingFire, KBDK_LCTRL},
|
{Event::LeftDrivingFire, KBDK_LCTRL},
|
||||||
{Event::LeftDrivingFire, KBDK_KP_5},
|
{Event::LeftDrivingFire, KBDK_KP_5},
|
||||||
|
{Event::LeftDrivingButton1, KBDK_UP},
|
||||||
|
{Event::LeftDrivingButton2, KBDK_DOWN},
|
||||||
|
{Event::LeftDrivingButton1, KBDK_KP_8},
|
||||||
|
{Event::LeftDrivingButton2, KBDK_KP_2},
|
||||||
|
|
||||||
{Event::RightDrivingCCW, KBDK_G},
|
{Event::RightDrivingCCW, KBDK_G},
|
||||||
{Event::RightDrivingCW, KBDK_J},
|
{Event::RightDrivingCW, KBDK_J},
|
||||||
{Event::RightDrivingFire, KBDK_F},
|
{Event::RightDrivingFire, KBDK_F},
|
||||||
|
{Event::RightDrivingButton1, KBDK_Y},
|
||||||
|
{Event::RightDrivingButton2, KBDK_H},
|
||||||
};
|
};
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
@ -1157,9 +1147,7 @@ PhysicalKeyboardHandler::CompuMateMapping = {
|
||||||
{Event::CompuMateRightBracket, KBDK_RIGHTBRACKET},
|
{Event::CompuMateRightBracket, KBDK_RIGHTBRACKET},
|
||||||
{Event::CompuMateMinus, KBDK_MINUS},
|
{Event::CompuMateMinus, KBDK_MINUS},
|
||||||
{Event::CompuMateQuote, KBDK_APOSTROPHE, KBDM_SHIFT},
|
{Event::CompuMateQuote, KBDK_APOSTROPHE, KBDM_SHIFT},
|
||||||
#ifndef RETRON77
|
|
||||||
{Event::CompuMateBackspace, KBDK_BACKSPACE},
|
{Event::CompuMateBackspace, KBDK_BACKSPACE},
|
||||||
#endif
|
|
||||||
{Event::CompuMateEquals, KBDK_EQUALS},
|
{Event::CompuMateEquals, KBDK_EQUALS},
|
||||||
{Event::CompuMatePlus, KBDK_EQUALS, KBDM_SHIFT},
|
{Event::CompuMatePlus, KBDK_EQUALS, KBDM_SHIFT},
|
||||||
{Event::CompuMateSlash, KBDK_SLASH}
|
{Event::CompuMateSlash, KBDK_SLASH}
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
// SS SS tt ee ll ll aa aa
|
// SS SS tt ee ll ll aa aa
|
||||||
// SSSS ttt eeeee llll llll aaaaa
|
// SSSS ttt eeeee llll llll aaaaa
|
||||||
//
|
//
|
||||||
// Copyright (c) 1995-2024 by Bradford W. Mott, Stephen Anthony
|
// Copyright (c) 1995-2025 by Bradford W. Mott, Stephen Anthony
|
||||||
// and the Stella Team
|
// and the Stella Team
|
||||||
//
|
//
|
||||||
// See the file "License.txt" for information on usage and redistribution of
|
// See the file "License.txt" for information on usage and redistribution of
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
// SS SS tt ee ll ll aa aa
|
// SS SS tt ee ll ll aa aa
|
||||||
// SSSS ttt eeeee llll llll aaaaa
|
// SSSS ttt eeeee llll llll aaaaa
|
||||||
//
|
//
|
||||||
// Copyright (c) 1995-2024 by Bradford W. Mott, Stephen Anthony
|
// Copyright (c) 1995-2025 by Bradford W. Mott, Stephen Anthony
|
||||||
// and the Stella Team
|
// and the Stella Team
|
||||||
//
|
//
|
||||||
// See the file "License.txt" for information on usage and redistribution of
|
// See the file "License.txt" for information on usage and redistribution of
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
// SS SS tt ee ll ll aa aa
|
// SS SS tt ee ll ll aa aa
|
||||||
// SSSS ttt eeeee llll llll aaaaa
|
// SSSS ttt eeeee llll llll aaaaa
|
||||||
//
|
//
|
||||||
// Copyright (c) 1995-2024 by Bradford W. Mott, Stephen Anthony
|
// Copyright (c) 1995-2025 by Bradford W. Mott, Stephen Anthony
|
||||||
// and the Stella Team
|
// and the Stella Team
|
||||||
//
|
//
|
||||||
// See the file "License.txt" for information on usage and redistribution of
|
// See the file "License.txt" for information on usage and redistribution of
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
// SS SS tt ee ll ll aa aa
|
// SS SS tt ee ll ll aa aa
|
||||||
// SSSS ttt eeeee llll llll aaaaa
|
// SSSS ttt eeeee llll llll aaaaa
|
||||||
//
|
//
|
||||||
// Copyright (c) 1995-2024 by Bradford W. Mott, Stephen Anthony
|
// Copyright (c) 1995-2025 by Bradford W. Mott, Stephen Anthony
|
||||||
// and the Stella Team
|
// and the Stella Team
|
||||||
//
|
//
|
||||||
// See the file "License.txt" for information on usage and redistribution of
|
// See the file "License.txt" for information on usage and redistribution of
|
||||||
|
@ -449,13 +449,15 @@ void PaletteHandler::generateCustomPalette(ConsoleTiming timing) const
|
||||||
{
|
{
|
||||||
constexpr int NUM_CHROMA = 16;
|
constexpr int NUM_CHROMA = 16;
|
||||||
constexpr int NUM_LUMA = 8;
|
constexpr int NUM_LUMA = 8;
|
||||||
constexpr float SATURATION = 0.25F; // default saturation
|
|
||||||
|
|
||||||
if(timing == ConsoleTiming::ntsc)
|
if(timing == ConsoleTiming::ntsc)
|
||||||
{
|
{
|
||||||
|
constexpr float SATURATION = 0.30F; // default NTSC saturation
|
||||||
vector2d IQ[NUM_CHROMA];
|
vector2d IQ[NUM_CHROMA];
|
||||||
// YIQ is YUV shifted by 33 degrees
|
// YIQ is YUV shifted by 33°
|
||||||
constexpr float offset = 33 * BSPF::PI_f / 180;
|
// -90° + 33° = -57° would create a greenish yellow
|
||||||
|
// -90° + 53° = -37° creates gold (which is correct according to the documentation)
|
||||||
|
constexpr float offset = (33 + 20) * BSPF::PI_f / 180;
|
||||||
const float shift = myPhaseNTSC * BSPF::PI_f / 180;
|
const float shift = myPhaseNTSC * BSPF::PI_f / 180;
|
||||||
|
|
||||||
// color 0 is grayscale
|
// color 0 is grayscale
|
||||||
|
@ -478,9 +480,9 @@ void PaletteHandler::generateCustomPalette(ConsoleTiming timing) const
|
||||||
float G = Y + dotProduct(IQ[chroma], IQG);
|
float G = Y + dotProduct(IQ[chroma], IQG);
|
||||||
float B = Y + dotProduct(IQ[chroma], IQB);
|
float B = Y + dotProduct(IQ[chroma], IQB);
|
||||||
|
|
||||||
if(R < 0) R = 0;
|
R = std::max(R, 0.F);
|
||||||
if(G < 0) G = 0;
|
G = std::max(G, 0.F);
|
||||||
if(B < 0) B = 0;
|
B = std::max(B, 0.F);
|
||||||
|
|
||||||
R = powf(R, 0.9F);
|
R = powf(R, 0.9F);
|
||||||
G = powf(G, 0.9F);
|
G = powf(G, 0.9F);
|
||||||
|
@ -496,6 +498,7 @@ void PaletteHandler::generateCustomPalette(ConsoleTiming timing) const
|
||||||
}
|
}
|
||||||
else if(timing == ConsoleTiming::pal)
|
else if(timing == ConsoleTiming::pal)
|
||||||
{
|
{
|
||||||
|
constexpr float SATURATION = 0.25F; // default PAL saturation
|
||||||
constexpr float offset = BSPF::PI_f;
|
constexpr float offset = BSPF::PI_f;
|
||||||
const float shift = myPhasePAL * BSPF::PI_f / 180;
|
const float shift = myPhasePAL * BSPF::PI_f / 180;
|
||||||
constexpr float fixedShift = 22.5F * BSPF::PI_f / 180;
|
constexpr float fixedShift = 22.5F * BSPF::PI_f / 180;
|
||||||
|
@ -669,9 +672,9 @@ const PaletteArray PaletteHandler::ourPALPalette = {
|
||||||
0x6c6c6c, 0, 0x909090, 0, 0xb4b4b4, 0, 0xd8d8d8, 0,
|
0x6c6c6c, 0, 0x909090, 0, 0xb4b4b4, 0, 0xd8d8d8, 0,
|
||||||
#else
|
#else
|
||||||
0x0b0b0b, 0, 0x333333, 0, 0x595959, 0, 0x7b7b7b, 0, // 0
|
0x0b0b0b, 0, 0x333333, 0, 0x595959, 0, 0x7b7b7b, 0, // 0
|
||||||
0x8b8b8b, 0, 0xaaaaaa, 0, 0xc7c7c7, 0, 0xe3e3e3, 0,
|
0x999999, 0, 0xb6b6b6, 0, 0xcfcfcf, 0, 0xe6e6e6, 0,
|
||||||
0x000000, 0, 0x272727, 0, 0x404040, 0, 0x696969, 0, // 1
|
0x0b0b0b, 0, 0x333333, 0, 0x595959, 0, 0x7b7b7b, 0, // 1
|
||||||
0x8b8b8b, 0, 0xaaaaaa, 0, 0xc7c7c7, 0, 0xe3e3e3, 0,
|
0x999999, 0, 0xb6b6b6, 0, 0xcfcfcf, 0, 0xe6e6e6, 0,
|
||||||
0x3b2400, 0, 0x664700, 0, 0x8b7000, 0, 0xac9200, 0, // 2
|
0x3b2400, 0, 0x664700, 0, 0x8b7000, 0, 0xac9200, 0, // 2
|
||||||
0xc5ae36, 0, 0xdec85e, 0, 0xf7e27f, 0, 0xfff19e, 0,
|
0xc5ae36, 0, 0xdec85e, 0, 0xf7e27f, 0, 0xfff19e, 0,
|
||||||
0x004500, 0, 0x006f00, 0, 0x3b9200, 0, 0x65b009, 0, // 3
|
0x004500, 0, 0x006f00, 0, 0x3b9200, 0, 0x65b009, 0, // 3
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
// SS SS tt ee ll ll aa aa
|
// SS SS tt ee ll ll aa aa
|
||||||
// SSSS ttt eeeee llll llll aaaaa
|
// SSSS ttt eeeee llll llll aaaaa
|
||||||
//
|
//
|
||||||
// Copyright (c) 1995-2024 by Bradford W. Mott, Stephen Anthony
|
// Copyright (c) 1995-2025 by Bradford W. Mott, Stephen Anthony
|
||||||
// and the Stella Team
|
// and the Stella Team
|
||||||
//
|
//
|
||||||
// See the file "License.txt" for information on usage and redistribution of
|
// See the file "License.txt" for information on usage and redistribution of
|
||||||
|
@ -33,7 +33,7 @@ class PaletteHandler
|
||||||
static constexpr string_view SETTING_CUSTOM = "custom";
|
static constexpr string_view SETTING_CUSTOM = "custom";
|
||||||
|
|
||||||
// Phase shift default and limits
|
// Phase shift default and limits
|
||||||
static constexpr float DEF_NTSC_SHIFT = 26.2F;
|
static constexpr float DEF_NTSC_SHIFT = 26.7F; // makes color $fx fall between $1x and $2x
|
||||||
static constexpr float DEF_PAL_SHIFT = 31.3F; // ~= 360 / 11.5
|
static constexpr float DEF_PAL_SHIFT = 31.3F; // ~= 360 / 11.5
|
||||||
static constexpr float MAX_PHASE_SHIFT = 4.5F;
|
static constexpr float MAX_PHASE_SHIFT = 4.5F;
|
||||||
static constexpr float DEF_RGB_SHIFT = 0.0F;
|
static constexpr float DEF_RGB_SHIFT = 0.0F;
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
// SS SS tt ee ll ll aa aa
|
// SS SS tt ee ll ll aa aa
|
||||||
// SSSS ttt eeeee llll llll aaaaa
|
// SSSS ttt eeeee llll llll aaaaa
|
||||||
//
|
//
|
||||||
// Copyright (c) 1995-2024 by Bradford W. Mott, Stephen Anthony
|
// Copyright (c) 1995-2025 by Bradford W. Mott, Stephen Anthony
|
||||||
// and the Stella Team
|
// and the Stella Team
|
||||||
//
|
//
|
||||||
// See the file "License.txt" for information on usage and redistribution of
|
// See the file "License.txt" for information on usage and redistribution of
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
// SS SS tt ee ll ll aa aa
|
// SS SS tt ee ll ll aa aa
|
||||||
// SSSS ttt eeeee llll llll aaaaa
|
// SSSS ttt eeeee llll llll aaaaa
|
||||||
//
|
//
|
||||||
// Copyright (c) 1995-2024 by Bradford W. Mott, Stephen Anthony
|
// Copyright (c) 1995-2025 by Bradford W. Mott, Stephen Anthony
|
||||||
// and the Stella Team
|
// and the Stella Team
|
||||||
//
|
//
|
||||||
// See the file "License.txt" for information on usage and redistribution of
|
// See the file "License.txt" for information on usage and redistribution of
|
||||||
|
@ -64,15 +64,15 @@ class PhosphorHandler
|
||||||
static constexpr uInt32 getPixel(const uInt32 c, const uInt32 p)
|
static constexpr uInt32 getPixel(const uInt32 c, const uInt32 p)
|
||||||
{
|
{
|
||||||
// Mix current calculated frame with previous displayed frame
|
// Mix current calculated frame with previous displayed frame
|
||||||
const auto rc = static_cast<uInt8>(c >> 16),
|
const auto rc = static_cast<uInt8>(c),
|
||||||
gc = static_cast<uInt8>(c >> 8),
|
gc = static_cast<uInt8>(c >> 8),
|
||||||
bc = static_cast<uInt8>(c),
|
bc = static_cast<uInt8>(c >> 16),
|
||||||
rp = static_cast<uInt8>(p >> 16),
|
rp = static_cast<uInt8>(p),
|
||||||
gp = static_cast<uInt8>(p >> 8),
|
gp = static_cast<uInt8>(p >> 8),
|
||||||
bp = static_cast<uInt8>(p);
|
bp = static_cast<uInt8>(p >> 16);
|
||||||
|
|
||||||
return (ourPhosphorLUT[rc][rp] << 16) | (ourPhosphorLUT[gc][gp] << 8) |
|
return ourPhosphorLUT[rc][rp] | (ourPhosphorLUT[gc][gp] << 8) |
|
||||||
ourPhosphorLUT[bc][bp];
|
(ourPhosphorLUT[bc][bp] << 16);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
// SS SS tt ee ll ll aa aa
|
// SS SS tt ee ll ll aa aa
|
||||||
// SSSS ttt eeeee llll llll aaaaa
|
// SSSS ttt eeeee llll llll aaaaa
|
||||||
//
|
//
|
||||||
// Copyright (c) 1995-2024 by Bradford W. Mott, Stephen Anthony
|
// Copyright (c) 1995-2025 by Bradford W. Mott, Stephen Anthony
|
||||||
// and the Stella Team
|
// and the Stella Team
|
||||||
//
|
//
|
||||||
// See the file "License.txt" for information on usage and redistribution of
|
// See the file "License.txt" for information on usage and redistribution of
|
||||||
|
@ -112,26 +112,26 @@ json PhysicalJoystick::convertLegacyMapping(string_view mapping, string_view nam
|
||||||
{
|
{
|
||||||
istringstream buf(string{mapping}); // TODO: fixed in C++23
|
istringstream buf(string{mapping}); // TODO: fixed in C++23
|
||||||
json convertedMapping = json::object();
|
json convertedMapping = json::object();
|
||||||
string map;
|
string lmap;
|
||||||
|
|
||||||
// Skip joystick name
|
// Skip joystick name
|
||||||
getline(buf, map, MODE_DELIM);
|
getline(buf, lmap, MODE_DELIM);
|
||||||
|
|
||||||
while (getline(buf, map, MODE_DELIM))
|
while (getline(buf, lmap, MODE_DELIM))
|
||||||
{
|
{
|
||||||
int mode{0};
|
int mode{0};
|
||||||
|
|
||||||
// Get event mode
|
// Get event mode
|
||||||
std::replace(map.begin(), map.end(), '|', ' ');
|
std::ranges::replace(lmap, '|', ' ');
|
||||||
istringstream modeBuf(map);
|
istringstream modeBuf(lmap);
|
||||||
modeBuf >> mode;
|
modeBuf >> mode;
|
||||||
|
|
||||||
// Remove leading "<mode>|" string
|
// Remove leading "<mode>|" string
|
||||||
map.erase(0, 2);
|
lmap.erase(0, 2);
|
||||||
|
|
||||||
const json mappingForMode = JoyMap::convertLegacyMapping(map);
|
const json lmappingForMode = JoyMap::convertLegacyMapping(lmap);
|
||||||
|
|
||||||
convertedMapping[jsonName(static_cast<EventMode>(mode))] = mappingForMode;
|
convertedMapping[jsonName(static_cast<EventMode>(mode))] = lmappingForMode;
|
||||||
}
|
}
|
||||||
|
|
||||||
convertedMapping["name"] = name;
|
convertedMapping["name"] = name;
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
// SS SS tt ee ll ll aa aa
|
// SS SS tt ee ll ll aa aa
|
||||||
// SSSS ttt eeeee llll llll aaaaa
|
// SSSS ttt eeeee llll llll aaaaa
|
||||||
//
|
//
|
||||||
// Copyright (c) 1995-2024 by Bradford W. Mott, Stephen Anthony
|
// Copyright (c) 1995-2025 by Bradford W. Mott, Stephen Anthony
|
||||||
// and the Stella Team
|
// and the Stella Team
|
||||||
//
|
//
|
||||||
// See the file "License.txt" for information on usage and redistribution of
|
// See the file "License.txt" for information on usage and redistribution of
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
// SS SS tt ee ll ll aa aa
|
// SS SS tt ee ll ll aa aa
|
||||||
// SSSS ttt eeeee llll llll aaaaa
|
// SSSS ttt eeeee llll llll aaaaa
|
||||||
//
|
//
|
||||||
// Copyright (c) 1995-2024 by Bradford W. Mott, Stephen Anthony
|
// Copyright (c) 1995-2025 by Bradford W. Mott, Stephen Anthony
|
||||||
// and the Stella Team
|
// and the Stella Team
|
||||||
//
|
//
|
||||||
// See the file "License.txt" for information on usage and redistribution of
|
// See the file "License.txt" for information on usage and redistribution of
|
||||||
|
@ -114,10 +114,10 @@ private:
|
||||||
|
|
||||||
public:
|
public:
|
||||||
constexpr Rect() = default;
|
constexpr Rect() = default;
|
||||||
constexpr explicit Rect(const Size& s) : bottom{ s.h }, right{ s.w } { assert(valid()); }
|
constexpr explicit Rect(const Size& s) : bottom{s.h}, right{s.w} { assert(valid()); }
|
||||||
constexpr Rect(uInt32 w, uInt32 h) : bottom{ h }, right{ w } { assert(valid()); }
|
constexpr Rect(uInt32 w, uInt32 h) : bottom{h}, right{w} { assert(valid()); }
|
||||||
constexpr Rect(const Point& p, uInt32 w, uInt32 h)
|
constexpr Rect(const Point& p, uInt32 w, uInt32 h)
|
||||||
: top(p.y), left(p.x), bottom(p.y + h), right( p.x + w) { assert(valid()); }
|
: top(p.y), left(p.x), bottom(p.y + h), right(p.x + w) { assert(valid()); }
|
||||||
constexpr Rect(uInt32 x1, uInt32 y1, uInt32 x2, uInt32 y2) : top{y1}, left{x1}, bottom{y2}, right{x2} { assert(valid()); }
|
constexpr Rect(uInt32 x1, uInt32 y1, uInt32 x2, uInt32 y2) : top{y1}, left{x1}, bottom{y2}, right{x2} { assert(valid()); }
|
||||||
|
|
||||||
constexpr uInt32 x() const { return left; }
|
constexpr uInt32 x() const { return left; }
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
// SS SS tt ee ll ll aa aa
|
// SS SS tt ee ll ll aa aa
|
||||||
// SSSS ttt eeeee llll llll aaaaa
|
// SSSS ttt eeeee llll llll aaaaa
|
||||||
//
|
//
|
||||||
// Copyright (c) 1995-2024 by Bradford W. Mott, Stephen Anthony
|
// Copyright (c) 1995-2025 by Bradford W. Mott, Stephen Anthony
|
||||||
// and the Stella Team
|
// and the Stella Team
|
||||||
//
|
//
|
||||||
// See the file "License.txt" for information on usage and redistribution of
|
// See the file "License.txt" for information on usage and redistribution of
|
||||||
|
@ -114,7 +114,7 @@ bool RewindManager::addState(string_view message, bool timeMachine)
|
||||||
interval = interval * scanlines / 262;
|
interval = interval * scanlines / 262;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(myOSystem.console().tia().cycles() - lastState.cycles < interval)
|
if(myOSystem.console().system().cycles() - lastState.cycles < interval)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -135,7 +135,7 @@ bool RewindManager::addState(string_view message, bool timeMachine)
|
||||||
if(myStateManager.saveState(s) && myOSystem.console().tia().saveDisplay(s))
|
if(myStateManager.saveState(s) && myOSystem.console().tia().saveDisplay(s))
|
||||||
{
|
{
|
||||||
state.message = message;
|
state.message = message;
|
||||||
state.cycles = myOSystem.console().tia().cycles();
|
state.cycles = myOSystem.console().system().cycles();
|
||||||
myLastTimeMachineAdd = timeMachine;
|
myLastTimeMachineAdd = timeMachine;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -145,7 +145,7 @@ bool RewindManager::addState(string_view message, bool timeMachine)
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
uInt32 RewindManager::rewindStates(uInt32 numStates)
|
uInt32 RewindManager::rewindStates(uInt32 numStates)
|
||||||
{
|
{
|
||||||
const uInt64 startCycles = myOSystem.console().tia().cycles();
|
const uInt64 startCycles = myOSystem.console().system().cycles();
|
||||||
uInt32 i{0};
|
uInt32 i{0};
|
||||||
string message;
|
string message;
|
||||||
|
|
||||||
|
@ -185,7 +185,7 @@ uInt32 RewindManager::rewindStates(uInt32 numStates)
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
uInt32 RewindManager::unwindStates(uInt32 numStates)
|
uInt32 RewindManager::unwindStates(uInt32 numStates)
|
||||||
{
|
{
|
||||||
const uInt64 startCycles = myOSystem.console().tia().cycles();
|
const uInt64 startCycles = myOSystem.console().system().cycles();
|
||||||
uInt32 i{0};
|
uInt32 i{0};
|
||||||
string message;
|
string message;
|
||||||
|
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
// SS SS tt ee ll ll aa aa
|
// SS SS tt ee ll ll aa aa
|
||||||
// SSSS ttt eeeee llll llll aaaaa
|
// SSSS ttt eeeee llll llll aaaaa
|
||||||
//
|
//
|
||||||
// Copyright (c) 1995-2024 by Bradford W. Mott, Stephen Anthony
|
// Copyright (c) 1995-2025 by Bradford W. Mott, Stephen Anthony
|
||||||
// and the Stella Team
|
// and the Stella Team
|
||||||
//
|
//
|
||||||
// See the file "License.txt" for information on usage and redistribution of
|
// See the file "License.txt" for information on usage and redistribution of
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
// SS SS tt ee ll ll aa aa
|
// SS SS tt ee ll ll aa aa
|
||||||
// SSSS ttt eeeee llll llll aaaaa
|
// SSSS ttt eeeee llll llll aaaaa
|
||||||
//
|
//
|
||||||
// Copyright (c) 1995-2024 by Bradford W. Mott, Stephen Anthony
|
// Copyright (c) 1995-2025 by Bradford W. Mott, Stephen Anthony
|
||||||
// and the Stella Team
|
// and the Stella Team
|
||||||
//
|
//
|
||||||
// See the file "License.txt" for information on usage and redistribution of
|
// See the file "License.txt" for information on usage and redistribution of
|
||||||
|
@ -33,48 +33,30 @@
|
||||||
#pragma clang diagnostic ignored "-Wold-style-cast"
|
#pragma clang diagnostic ignored "-Wold-style-cast"
|
||||||
#pragma clang diagnostic ignored "-Wreserved-identifier"
|
#pragma clang diagnostic ignored "-Wreserved-identifier"
|
||||||
#pragma clang diagnostic ignored "-Wswitch-default"
|
#pragma clang diagnostic ignored "-Wswitch-default"
|
||||||
#include <SDL.h>
|
#include <SDL3/SDL.h>
|
||||||
#pragma clang diagnostic pop
|
#pragma clang diagnostic pop
|
||||||
#elif defined(BSPF_WINDOWS)
|
#elif defined(BSPF_WINDOWS)
|
||||||
#pragma warning(push, 0)
|
#pragma warning(push, 0)
|
||||||
#include <SDL.h>
|
#include <SDL3/SDL.h>
|
||||||
#pragma warning(pop)
|
#pragma warning(pop)
|
||||||
#else
|
#else
|
||||||
#include <SDL.h>
|
#include <SDL3/SDL.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
|
||||||
* Seems to be needed for ppc64le, doesn't hurt other archs
|
|
||||||
* Note that this is a problem in SDL2, which includes <altivec.h>
|
|
||||||
* https://bugzilla.redhat.com/show_bug.cgi?id=1419452
|
|
||||||
*/
|
|
||||||
#undef vector
|
|
||||||
#undef pixel
|
|
||||||
#undef bool
|
|
||||||
|
|
||||||
static inline string SDLVersion()
|
static inline string SDLVersion()
|
||||||
{
|
{
|
||||||
ostringstream buf;
|
ostringstream buf;
|
||||||
SDL_version ver;
|
const int ver = SDL_GetVersion();
|
||||||
SDL_GetVersion(&ver);
|
buf << "SDL "
|
||||||
buf << "SDL " << static_cast<int>(ver.major) << "." << static_cast<int>(ver.minor)
|
<< SDL_VERSIONNUM_MAJOR(ver) << "."
|
||||||
<< "." << static_cast<int>(ver.patch);
|
<< SDL_VERSIONNUM_MINOR(ver) << "."
|
||||||
|
<< SDL_VERSIONNUM_MICRO(ver);
|
||||||
return buf.str();
|
return buf.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline bool SDLSupportsURL()
|
|
||||||
{
|
|
||||||
return SDL_VERSION_ATLEAST(2,0,14);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline bool SDLOpenURL(const string& url)
|
static inline bool SDLOpenURL(const string& url)
|
||||||
{
|
{
|
||||||
#if SDL_VERSION_ATLEAST(2,0,14)
|
return SDL_OpenURL(url.c_str());
|
||||||
return SDL_OpenURL(url.c_str()) == 0;
|
|
||||||
#else
|
|
||||||
cerr << "OpenURL requires at least SDL 2.0.14\n";
|
|
||||||
return false;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // SDL_LIB_HXX
|
#endif // SDL_LIB_HXX
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
// SS SS tt ee ll ll aa aa
|
// SS SS tt ee ll ll aa aa
|
||||||
// SSSS ttt eeeee llll llll aaaaa
|
// SSSS ttt eeeee llll llll aaaaa
|
||||||
//
|
//
|
||||||
// Copyright (c) 1995-2024 by Bradford W. Mott, Stephen Anthony
|
// Copyright (c) 1995-2025 by Bradford W. Mott, Stephen Anthony
|
||||||
// and the Stella Team
|
// and the Stella Team
|
||||||
//
|
//
|
||||||
// See the file "License.txt" for information on usage and redistribution of
|
// See the file "License.txt" for information on usage and redistribution of
|
||||||
|
@ -90,9 +90,10 @@ class SoundNull : public Sound
|
||||||
volume is given as a range from 0 to 100 (0 indicates mute). Values
|
volume is given as a range from 0 to 100 (0 indicates mute). Values
|
||||||
outside this range indicate that the volume shouldn't be changed at all.
|
outside this range indicate that the volume shouldn't be changed at all.
|
||||||
|
|
||||||
@param volume The new volume level for the sound device
|
@param volume The new volume level for the sound device
|
||||||
|
@param persist Whether to save the volume change to settings
|
||||||
*/
|
*/
|
||||||
void setVolume(uInt32 volume) override { }
|
void setVolume(uInt32 volume, bool persist = true) override { }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Adjusts the volume of the sound device based on the given direction.
|
Adjusts the volume of the sound device based on the given direction.
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
// SS SS tt ee ll ll aa aa
|
// SS SS tt ee ll ll aa aa
|
||||||
// SSSS ttt eeeee llll llll aaaaa
|
// SSSS ttt eeeee llll llll aaaaa
|
||||||
//
|
//
|
||||||
// Copyright (c) 1995-2024 by Bradford W. Mott, Stephen Anthony
|
// Copyright (c) 1995-2025 by Bradford W. Mott, Stephen Anthony
|
||||||
// and the Stella Team
|
// and the Stella Team
|
||||||
//
|
//
|
||||||
// See the file "License.txt" for information on usage and redistribution of
|
// See the file "License.txt" for information on usage and redistribution of
|
||||||
|
@ -31,18 +31,18 @@
|
||||||
#include "audio/LanczosResampler.hxx"
|
#include "audio/LanczosResampler.hxx"
|
||||||
#include "ThreadDebugging.hxx"
|
#include "ThreadDebugging.hxx"
|
||||||
|
|
||||||
#include "SoundSDL2.hxx"
|
#include "SoundSDL.hxx"
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
SoundSDL2::SoundSDL2(OSystem& osystem, AudioSettings& audioSettings)
|
SoundSDL::SoundSDL(OSystem& osystem, AudioSettings& audioSettings)
|
||||||
: Sound{osystem},
|
: Sound{osystem},
|
||||||
myAudioSettings{audioSettings}
|
myAudioSettings{audioSettings}
|
||||||
{
|
{
|
||||||
ASSERT_MAIN_THREAD;
|
ASSERT_MAIN_THREAD;
|
||||||
|
|
||||||
Logger::debug("SoundSDL2::SoundSDL2 started ...");
|
Logger::debug("SoundSDL::SoundSDL started ...");
|
||||||
|
|
||||||
if(SDL_InitSubSystem(SDL_INIT_AUDIO) < 0)
|
if(!SDL_InitSubSystem(SDL_INIT_AUDIO))
|
||||||
{
|
{
|
||||||
ostringstream buf;
|
ostringstream buf;
|
||||||
|
|
||||||
|
@ -52,77 +52,35 @@ SoundSDL2::SoundSDL2(OSystem& osystem, AudioSettings& audioSettings)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
queryHardware(myDevices); // NOLINT
|
SDL_zero(mySpec);
|
||||||
|
if(!myAudioSettings.enabled())
|
||||||
|
Logger::info("Sound disabled\n");
|
||||||
|
|
||||||
SDL_zero(myHardwareSpec);
|
Logger::debug("SoundSDL::SoundSDL initialized");
|
||||||
if(!openDevice())
|
|
||||||
return;
|
|
||||||
|
|
||||||
Logger::debug("SoundSDL2::SoundSDL2 initialized");
|
// Reserve 8K for the audio buffer; seems to be enough on most systems
|
||||||
|
myBuffer.reserve(8_KB);
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
SoundSDL2::~SoundSDL2()
|
SoundSDL::~SoundSDL()
|
||||||
{
|
{
|
||||||
ASSERT_MAIN_THREAD;
|
ASSERT_MAIN_THREAD;
|
||||||
|
|
||||||
if(!myIsInitializedFlag)
|
if(!myIsInitializedFlag)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
SDL_DestroyAudioStream(myStream);
|
||||||
SDL_CloseAudioDevice(myDevice);
|
SDL_CloseAudioDevice(myDevice);
|
||||||
SDL_QuitSubSystem(SDL_INIT_AUDIO);
|
SDL_QuitSubSystem(SDL_INIT_AUDIO);
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
void SoundSDL2::queryHardware(VariantList& devices)
|
bool SoundSDL::openDevice()
|
||||||
{
|
{
|
||||||
ASSERT_MAIN_THREAD;
|
ASSERT_MAIN_THREAD;
|
||||||
|
|
||||||
const int numDevices = SDL_GetNumAudioDevices(0);
|
auto SOUND_ERROR = [this]() -> bool
|
||||||
|
|
||||||
// log the available audio devices
|
|
||||||
ostringstream s;
|
|
||||||
s << "Supported audio devices (" << numDevices << "):";
|
|
||||||
Logger::debug(s.view());
|
|
||||||
|
|
||||||
VarList::push_back(devices, "Default", 0);
|
|
||||||
for(int i = 0; i < numDevices; ++i)
|
|
||||||
{
|
|
||||||
ostringstream ss;
|
|
||||||
|
|
||||||
ss << " " << i + 1 << ": " << SDL_GetAudioDeviceName(i, 0);
|
|
||||||
Logger::debug(ss.view());
|
|
||||||
|
|
||||||
VarList::push_back(devices, SDL_GetAudioDeviceName(i, 0), i + 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
bool SoundSDL2::openDevice()
|
|
||||||
{
|
|
||||||
ASSERT_MAIN_THREAD;
|
|
||||||
|
|
||||||
SDL_AudioSpec desired;
|
|
||||||
desired.freq = myAudioSettings.sampleRate();
|
|
||||||
desired.format = AUDIO_F32SYS;
|
|
||||||
desired.channels = 2;
|
|
||||||
desired.samples = static_cast<Uint16>(myAudioSettings.fragmentSize());
|
|
||||||
desired.callback = callback;
|
|
||||||
desired.userdata = this;
|
|
||||||
|
|
||||||
if(myIsInitializedFlag)
|
|
||||||
SDL_CloseAudioDevice(myDevice);
|
|
||||||
|
|
||||||
myDeviceId = BSPF::clamp(myAudioSettings.device(), 0U,
|
|
||||||
static_cast<uInt32>(myDevices.size() - 1));
|
|
||||||
const char* const device = myDeviceId
|
|
||||||
? myDevices.at(myDeviceId).first.c_str()
|
|
||||||
: nullptr;
|
|
||||||
|
|
||||||
myDevice = SDL_OpenAudioDevice(device, 0, &desired, &myHardwareSpec,
|
|
||||||
SDL_AUDIO_ALLOW_FREQUENCY_CHANGE);
|
|
||||||
|
|
||||||
if(myDevice == 0)
|
|
||||||
{
|
{
|
||||||
ostringstream buf;
|
ostringstream buf;
|
||||||
|
|
||||||
|
@ -131,49 +89,72 @@ bool SoundSDL2::openDevice()
|
||||||
Logger::error(buf.view());
|
Logger::error(buf.view());
|
||||||
|
|
||||||
return myIsInitializedFlag = false;
|
return myIsInitializedFlag = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
if(myIsInitializedFlag)
|
||||||
|
{
|
||||||
|
SDL_DestroyAudioStream(myStream);
|
||||||
|
myStream = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mySpec = { SDL_AUDIO_F32, 2, static_cast<int>(myAudioSettings.sampleRate()) };
|
||||||
|
|
||||||
|
myDevice = SDL_OpenAudioDevice(SDL_AUDIO_DEVICE_DEFAULT_PLAYBACK, &mySpec);
|
||||||
|
if(myDevice == 0)
|
||||||
|
return SOUND_ERROR();
|
||||||
|
myStream = SDL_CreateAudioStream(&mySpec, nullptr);
|
||||||
|
if(!myStream)
|
||||||
|
return SOUND_ERROR();
|
||||||
|
if(!SDL_BindAudioStream(myDevice, myStream))
|
||||||
|
return SOUND_ERROR();
|
||||||
|
if(!SDL_SetAudioStreamGetCallback(myStream, audioCallback, this))
|
||||||
|
return SOUND_ERROR();
|
||||||
|
|
||||||
return myIsInitializedFlag = true;
|
return myIsInitializedFlag = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
void SoundSDL2::setEnabled(bool enable)
|
void SoundSDL::setEnabled(bool enable)
|
||||||
{
|
{
|
||||||
mute(!enable);
|
if(myIsInitializedFlag)
|
||||||
pause(!enable);
|
{
|
||||||
|
mute(!enable);
|
||||||
|
pause(!enable);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
void SoundSDL2::open(shared_ptr<AudioQueue> audioQueue,
|
void SoundSDL::open(shared_ptr<AudioQueue> audioQueue,
|
||||||
shared_ptr<const EmulationTiming> emulationTiming)
|
shared_ptr<const EmulationTiming> emulationTiming)
|
||||||
{
|
{
|
||||||
const string pre_about = myAboutString;
|
|
||||||
|
|
||||||
// Do we need to re-open the sound device?
|
|
||||||
// Only do this when absolutely necessary
|
|
||||||
if(myAudioSettings.sampleRate() != static_cast<uInt32>(myHardwareSpec.freq) ||
|
|
||||||
myAudioSettings.fragmentSize() != static_cast<uInt32>(myHardwareSpec.samples) ||
|
|
||||||
myAudioSettings.device() != myDeviceId)
|
|
||||||
openDevice();
|
|
||||||
|
|
||||||
myEmulationTiming = emulationTiming;
|
|
||||||
myWavHandler.setSpeed(262 * 60 * 2. / myEmulationTiming->audioSampleRate());
|
|
||||||
|
|
||||||
Logger::debug("SoundSDL2::open started ...");
|
|
||||||
|
|
||||||
audioQueue->ignoreOverflows(!myAudioSettings.enabled());
|
|
||||||
if(!myAudioSettings.enabled())
|
if(!myAudioSettings.enabled())
|
||||||
{
|
{
|
||||||
Logger::info("Sound disabled\n");
|
Logger::info("Sound disabled\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
pause(true);
|
||||||
|
|
||||||
|
const string pre_about = myAboutString;
|
||||||
|
|
||||||
myAudioQueue = audioQueue;
|
myAudioQueue = audioQueue;
|
||||||
|
myEmulationTiming = emulationTiming;
|
||||||
myUnderrun = true;
|
myUnderrun = true;
|
||||||
myCurrentFragment = nullptr;
|
myCurrentFragment = nullptr;
|
||||||
|
|
||||||
|
myAudioQueue->ignoreOverflows(!myAudioSettings.enabled());
|
||||||
|
myWavHandler.setSpeed(262 * 60 * 2. / myEmulationTiming->audioSampleRate());
|
||||||
|
|
||||||
|
// Do we need to re-open the sound device?
|
||||||
|
// Only do this when absolutely necessary
|
||||||
|
if(myAudioSettings.sampleRate() != static_cast<uInt32>(mySpec.freq))
|
||||||
|
openDevice();
|
||||||
|
|
||||||
|
Logger::debug("SoundSDL::open started ...");
|
||||||
|
|
||||||
// Adjust volume to that defined in settings
|
// Adjust volume to that defined in settings
|
||||||
setVolume(myAudioSettings.volume());
|
setVolume(myAudioSettings.volume());
|
||||||
|
|
||||||
|
// Initialize resampler; must be done after the sound device has opened
|
||||||
initResampler();
|
initResampler();
|
||||||
|
|
||||||
// Show some info
|
// Show some info
|
||||||
|
@ -184,20 +165,20 @@ void SoundSDL2::open(shared_ptr<AudioQueue> audioQueue,
|
||||||
// And start the SDL sound subsystem ...
|
// And start the SDL sound subsystem ...
|
||||||
pause(false);
|
pause(false);
|
||||||
|
|
||||||
Logger::debug("SoundSDL2::open finished");
|
Logger::debug("SoundSDL::open finished");
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
void SoundSDL2::mute(bool enable)
|
void SoundSDL::mute(bool enable)
|
||||||
{
|
{
|
||||||
if(enable)
|
if(enable)
|
||||||
myVolumeFactor = 0;
|
setVolume(0, false);
|
||||||
else
|
else
|
||||||
setVolume(myAudioSettings.volume());
|
setVolume(myAudioSettings.volume());
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
void SoundSDL2::toggleMute()
|
void SoundSDL::toggleMute()
|
||||||
{
|
{
|
||||||
const bool wasMuted = myVolumeFactor == 0;
|
const bool wasMuted = myVolumeFactor == 0;
|
||||||
mute(!wasMuted);
|
mute(!wasMuted);
|
||||||
|
@ -211,31 +192,40 @@ void SoundSDL2::toggleMute()
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
bool SoundSDL2::pause(bool enable)
|
bool SoundSDL::pause(bool enable)
|
||||||
{
|
{
|
||||||
ASSERT_MAIN_THREAD;
|
ASSERT_MAIN_THREAD;
|
||||||
|
|
||||||
const bool wasPaused = SDL_GetAudioDeviceStatus(myDevice) == SDL_AUDIO_PAUSED;
|
const bool wasPaused = SDL_AudioStreamDevicePaused(myStream);
|
||||||
if(myIsInitializedFlag)
|
if(myIsInitializedFlag)
|
||||||
{
|
{
|
||||||
SDL_PauseAudioDevice(myDevice, enable ? 1 : 0);
|
if(enable) SDL_PauseAudioStreamDevice(myStream);
|
||||||
|
else SDL_ResumeAudioStreamDevice(myStream);
|
||||||
|
|
||||||
myWavHandler.pause(enable);
|
myWavHandler.pause(enable);
|
||||||
}
|
}
|
||||||
return wasPaused;
|
return wasPaused;
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
void SoundSDL2::setVolume(uInt32 volume)
|
void SoundSDL::setVolume(uInt32 volume, bool persist)
|
||||||
{
|
{
|
||||||
if(myIsInitializedFlag && (volume <= 100))
|
if(myIsInitializedFlag && (volume <= 100))
|
||||||
{
|
{
|
||||||
myAudioSettings.setVolume(volume);
|
myVolumeFactor = myAudioSettings.enabled()
|
||||||
myVolumeFactor = myAudioSettings.enabled() ? static_cast<float>(volume) / 100.F : 0;
|
? static_cast<float>(volume) / 100.F
|
||||||
|
: 0.F;
|
||||||
|
|
||||||
|
SDL_SetAudioStreamGain(myStream, myVolumeFactor);
|
||||||
|
myWavHandler.setVolumeFactor(myVolumeFactor);
|
||||||
|
|
||||||
|
if(persist)
|
||||||
|
myAudioSettings.setVolume(volume);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
void SoundSDL2::adjustVolume(int direction)
|
void SoundSDL::adjustVolume(int direction)
|
||||||
{
|
{
|
||||||
Int32 percent = myAudioSettings.volume();
|
Int32 percent = myAudioSettings.volume();
|
||||||
percent = BSPF::clamp(percent + direction * 2, 0, 100);
|
percent = BSPF::clamp(percent + direction * 2, 0, 100);
|
||||||
|
@ -257,13 +247,12 @@ void SoundSDL2::adjustVolume(int direction)
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
string SoundSDL2::about() const
|
string SoundSDL::about() const
|
||||||
{
|
{
|
||||||
ostringstream buf;
|
ostringstream buf;
|
||||||
buf << "Sound enabled:\n"
|
buf << "Sound enabled:\n"
|
||||||
<< " Volume: " << myAudioSettings.volume() << "%\n"
|
<< " Volume: " << myAudioSettings.volume() << "%\n"
|
||||||
<< " Device: " << myDevices.at(myDeviceId).first << '\n'
|
<< " Channels: " << static_cast<uInt32>(mySpec.channels)
|
||||||
<< " Channels: " << static_cast<uInt32>(myHardwareSpec.channels)
|
|
||||||
<< (myAudioQueue->isStereo() ? " (Stereo)" : " (Mono)") << '\n'
|
<< (myAudioQueue->isStereo() ? " (Stereo)" : " (Mono)") << '\n'
|
||||||
<< " Preset: ";
|
<< " Preset: ";
|
||||||
switch(myAudioSettings.preset())
|
switch(myAudioSettings.preset())
|
||||||
|
@ -287,10 +276,7 @@ string SoundSDL2::about() const
|
||||||
default:
|
default:
|
||||||
break; // Not supposed to get here
|
break; // Not supposed to get here
|
||||||
}
|
}
|
||||||
buf << " Fragment size: " << static_cast<uInt32>(myHardwareSpec.samples)
|
buf << " Sample rate: " << static_cast<uInt32>(mySpec.freq) << " Hz\n";
|
||||||
<< " bytes\n"
|
|
||||||
<< " Sample rate: " << static_cast<uInt32>(myHardwareSpec.freq)
|
|
||||||
<< " Hz\n";
|
|
||||||
buf << " Resampling: ";
|
buf << " Resampling: ";
|
||||||
switch(myAudioSettings.resamplingQuality())
|
switch(myAudioSettings.resamplingQuality())
|
||||||
{
|
{
|
||||||
|
@ -315,7 +301,7 @@ string SoundSDL2::about() const
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
void SoundSDL2::initResampler()
|
void SoundSDL::initResampler()
|
||||||
{
|
{
|
||||||
const Resampler::NextFragmentCallback nextFragmentCallback = [this] () -> Int16* {
|
const Resampler::NextFragmentCallback nextFragmentCallback = [this] () -> Int16* {
|
||||||
Int16* nextFragment = nullptr;
|
Int16* nextFragment = nullptr;
|
||||||
|
@ -333,13 +319,11 @@ void SoundSDL2::initResampler()
|
||||||
|
|
||||||
return nextFragment;
|
return nextFragment;
|
||||||
};
|
};
|
||||||
|
|
||||||
const Resampler::Format formatFrom =
|
const Resampler::Format formatFrom =
|
||||||
Resampler::Format(myEmulationTiming->audioSampleRate(),
|
Resampler::Format(myEmulationTiming->audioSampleRate(),
|
||||||
myAudioQueue->fragmentSize(), myAudioQueue->isStereo());
|
myAudioQueue->fragmentSize(), myAudioQueue->isStereo());
|
||||||
const Resampler::Format formatTo =
|
const Resampler::Format formatTo =
|
||||||
Resampler::Format(myHardwareSpec.freq, myHardwareSpec.samples,
|
Resampler::Format(mySpec.freq, 1024, mySpec.channels > 1);
|
||||||
myHardwareSpec.channels > 1);
|
|
||||||
|
|
||||||
switch(myAudioSettings.resamplingQuality())
|
switch(myAudioSettings.resamplingQuality())
|
||||||
{
|
{
|
||||||
|
@ -365,183 +349,147 @@ void SoundSDL2::initResampler()
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
void SoundSDL2::callback(void* object, uInt8* stream, int len)
|
void SoundSDL::audioCallback(void* object, SDL_AudioStream* stream,
|
||||||
|
int additional_amt, int)
|
||||||
{
|
{
|
||||||
auto* self = static_cast<SoundSDL2*>(object);
|
auto* self = static_cast<SoundSDL*>(object);
|
||||||
|
std::vector<uInt8>& buf = self->myBuffer;
|
||||||
|
|
||||||
if(self->myAudioQueue && self->myResampler)
|
// Make sure we always have enough room in the buffer
|
||||||
{
|
if(std::cmp_greater_equal(additional_amt, buf.capacity()))
|
||||||
// The stream is 32-bit float (even though this callback is 8-bits), since
|
buf.resize(additional_amt);
|
||||||
// the resampler and TIA audio subsystem always generate float samples
|
|
||||||
auto* s = reinterpret_cast<float*>(stream);
|
|
||||||
const uInt32 length = len >> 2;
|
|
||||||
self->myResampler->fillFragment(s, length);
|
|
||||||
|
|
||||||
for(uInt32 i = 0; i < length; ++i)
|
// The stream is 32-bit float (even though this callback is 8-bits), since
|
||||||
s[i] *= SoundSDL2::myVolumeFactor;
|
// the resampler and TIA audio subsystem always generate float samples
|
||||||
}
|
auto* s = reinterpret_cast<float*>(buf.data());
|
||||||
|
self->myResampler->fillFragment(s, additional_amt >> 2);
|
||||||
|
|
||||||
|
SDL_PutAudioStreamData(stream, buf.data(), additional_amt);
|
||||||
|
}
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
bool SoundSDL::playWav(const string& fileName, uInt32 position, uInt32 length)
|
||||||
|
{
|
||||||
|
if(myStream)
|
||||||
|
return myWavHandler.play(SDL_GetAudioStreamDevice(myStream),
|
||||||
|
fileName, position, length);
|
||||||
else
|
else
|
||||||
SDL_memset(stream, 0, len);
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
bool SoundSDL2::playWav(const string& fileName, uInt32 position, uInt32 length)
|
void SoundSDL::stopWav()
|
||||||
{
|
|
||||||
const char* const device = myDeviceId
|
|
||||||
? myDevices.at(myDeviceId).first.c_str()
|
|
||||||
: nullptr;
|
|
||||||
|
|
||||||
return myWavHandler.play(fileName, device, position, length);
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
void SoundSDL2::stopWav()
|
|
||||||
{
|
{
|
||||||
myWavHandler.stop();
|
myWavHandler.stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
uInt32 SoundSDL2::wavSize() const
|
uInt32 SoundSDL::wavSize() const
|
||||||
{
|
{
|
||||||
return myWavHandler.size();
|
return myWavHandler.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
bool SoundSDL2::WavHandlerSDL2::play(
|
bool SoundSDL::WavHandler::play(SDL_AudioDeviceID device,
|
||||||
const string& fileName, const char* device, uInt32 position, uInt32 length)
|
const string& fileName, uInt32 position, uInt32 length)
|
||||||
{
|
{
|
||||||
// Load WAV file
|
// Load WAV file
|
||||||
if(fileName != myFilename || myBuffer == nullptr)
|
if(fileName != myFilename || myBuffer == nullptr)
|
||||||
{
|
{
|
||||||
if(myBuffer)
|
if(myBuffer)
|
||||||
{
|
{
|
||||||
SDL_FreeWAV(myBuffer);
|
SDL_free(myBuffer);
|
||||||
myBuffer = nullptr;
|
myBuffer = nullptr;
|
||||||
}
|
}
|
||||||
SDL_zero(mySpec);
|
SDL_zero(mySpec);
|
||||||
if(SDL_LoadWAV(fileName.c_str(), &mySpec, &myBuffer, &myLength) == nullptr)
|
if(!SDL_LoadWAV(fileName.c_str(), &mySpec, &myBuffer, &myLength))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// Set the callback function
|
|
||||||
mySpec.callback = callback;
|
|
||||||
mySpec.userdata = this;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(position > myLength)
|
if(position > myLength)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
myFilename = fileName;
|
if(myStream)
|
||||||
|
SDL_UnbindAudioStream(myStream);
|
||||||
|
|
||||||
|
myStream = SDL_CreateAudioStream(&mySpec, nullptr);
|
||||||
|
if(myStream == nullptr)
|
||||||
|
return false;
|
||||||
|
if(!SDL_BindAudioStream(device, myStream))
|
||||||
|
return false;
|
||||||
|
if(!SDL_SetAudioStreamGetCallback(myStream, WavHandler::wavCallback, this))
|
||||||
|
return false;
|
||||||
|
SDL_SetAudioStreamGain(myStream, myVolumeFactor);
|
||||||
|
|
||||||
|
myFilename = fileName;
|
||||||
myRemaining = length
|
myRemaining = length
|
||||||
? std::min(length, myLength - position)
|
? std::min(length, myLength - position)
|
||||||
: myLength;
|
: myLength;
|
||||||
myPos = myBuffer + position;
|
myPos = myBuffer + position;
|
||||||
|
|
||||||
// Open audio device
|
|
||||||
if(!myDevice)
|
|
||||||
{
|
|
||||||
myDevice = SDL_OpenAudioDevice(device, 0, &mySpec, nullptr, 0);
|
|
||||||
if(!myDevice)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
// Play audio
|
|
||||||
pause(false);
|
|
||||||
}
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
void SoundSDL2::WavHandlerSDL2::stop()
|
void SoundSDL::WavHandler::stop()
|
||||||
{
|
{
|
||||||
if(myBuffer)
|
if(myBuffer)
|
||||||
{
|
{
|
||||||
// Clean up
|
// Clean up
|
||||||
myRemaining = 0;
|
myRemaining = 0;
|
||||||
SDL_CloseAudioDevice(myDevice); myDevice = 0;
|
SDL_UnbindAudioStream(myStream); myStream = nullptr;
|
||||||
SDL_FreeWAV(myBuffer); myBuffer = nullptr;
|
SDL_free(myBuffer); myBuffer = nullptr;
|
||||||
}
|
}
|
||||||
if(myCvtBuffer)
|
}
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
void SoundSDL::WavHandler::setVolumeFactor(float volumeFactor)
|
||||||
|
{
|
||||||
|
myVolumeFactor = volumeFactor;
|
||||||
|
if(myStream)
|
||||||
|
SDL_SetAudioStreamGain(myStream, myVolumeFactor);
|
||||||
|
}
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
void SoundSDL::WavHandler::pause(bool state) const
|
||||||
|
{
|
||||||
|
if(myStream)
|
||||||
{
|
{
|
||||||
myCvtBuffer.reset();
|
if(state) SDL_PauseAudioStreamDevice(myStream);
|
||||||
myCvtBufferSize = 0;
|
else SDL_ResumeAudioStreamDevice(myStream);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
void SoundSDL2::WavHandlerSDL2::processWav(uInt8* stream, uInt32 len)
|
void SoundSDL::WavHandler::wavCallback(void* object, SDL_AudioStream* stream,
|
||||||
|
int additional_amt, int)
|
||||||
{
|
{
|
||||||
SDL_memset(stream, mySpec.silence, len);
|
auto* self = static_cast<WavHandler*>(object);
|
||||||
if(myRemaining)
|
auto len = static_cast<uInt32>(additional_amt);
|
||||||
|
auto& remaining = self->myRemaining;
|
||||||
|
|
||||||
|
if(remaining)
|
||||||
{
|
{
|
||||||
if(mySpeed != 1.0)
|
if(self->mySpeed != 1.0)
|
||||||
{
|
len = std::round(len / self->mySpeed);
|
||||||
const int origLen = len;
|
|
||||||
len = std::round(len / mySpeed);
|
|
||||||
const int newFreq =
|
|
||||||
std::round(static_cast<double>(mySpec.freq) * origLen / len);
|
|
||||||
|
|
||||||
if(len > myRemaining)
|
if(len > remaining) // NOLINT(readability-use-std-min-max)
|
||||||
len = myRemaining;
|
len = remaining;
|
||||||
|
|
||||||
SDL_AudioCVT cvt;
|
SDL_PutAudioStreamData(stream, self->myPos, len);
|
||||||
SDL_BuildAudioCVT(&cvt, mySpec.format, mySpec.channels, mySpec.freq,
|
|
||||||
mySpec.format, mySpec.channels, newFreq);
|
|
||||||
SDL_assert(cvt.needed); // Obviously, this one is always needed.
|
|
||||||
cvt.len = len * mySpec.channels; // Mono 8 bit sample frames
|
|
||||||
|
|
||||||
if(!myCvtBuffer ||
|
self->myPos += len;
|
||||||
myCvtBufferSize < static_cast<uInt32>(cvt.len * cvt.len_mult))
|
remaining -= len;
|
||||||
{
|
|
||||||
myCvtBufferSize = cvt.len * cvt.len_mult;
|
|
||||||
myCvtBuffer = make_unique<uInt8[]>(myCvtBufferSize);
|
|
||||||
}
|
|
||||||
cvt.buf = myCvtBuffer.get();
|
|
||||||
|
|
||||||
// Read original data into conversion buffer
|
|
||||||
SDL_memcpy(cvt.buf, myPos, cvt.len);
|
|
||||||
SDL_ConvertAudio(&cvt);
|
|
||||||
// Mix volume adjusted WAV data into silent buffer
|
|
||||||
SDL_MixAudioFormat(stream, cvt.buf, mySpec.format, cvt.len_cvt,
|
|
||||||
SDL_MIX_MAXVOLUME * SoundSDL2::myVolumeFactor);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if(len > myRemaining)
|
|
||||||
len = myRemaining;
|
|
||||||
|
|
||||||
// Mix volume adjusted WAV data into silent buffer
|
|
||||||
SDL_MixAudioFormat(stream, myPos, mySpec.format, len,
|
|
||||||
SDL_MIX_MAXVOLUME * myVolumeFactor);
|
|
||||||
}
|
|
||||||
myPos += len;
|
|
||||||
myRemaining -= len;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
void SoundSDL2::WavHandlerSDL2::callback(void* object, uInt8* stream, int len)
|
SoundSDL::WavHandler::~WavHandler()
|
||||||
{
|
{
|
||||||
static_cast<WavHandlerSDL2*>(object)->processWav(
|
ASSERT_MAIN_THREAD;
|
||||||
stream, static_cast<uInt32>(len));
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
if(myBuffer)
|
||||||
SoundSDL2::WavHandlerSDL2::~WavHandlerSDL2()
|
SDL_free(myBuffer);
|
||||||
{
|
|
||||||
if(myDevice)
|
|
||||||
{
|
|
||||||
SDL_CloseAudioDevice(myDevice);
|
|
||||||
SDL_FreeWAV(myBuffer);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
void SoundSDL2::WavHandlerSDL2::pause(bool state) const
|
|
||||||
{
|
|
||||||
if(myDevice)
|
|
||||||
SDL_PauseAudioDevice(myDevice, state ? 1 : 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
float SoundSDL2::myVolumeFactor = 0.F;
|
|
||||||
|
|
||||||
#endif // SOUND_SUPPORT
|
#endif // SOUND_SUPPORT
|
|
@ -8,7 +8,7 @@
|
||||||
// SS SS tt ee ll ll aa aa
|
// SS SS tt ee ll ll aa aa
|
||||||
// SSSS ttt eeeee llll llll aaaaa
|
// SSSS ttt eeeee llll llll aaaaa
|
||||||
//
|
//
|
||||||
// Copyright (c) 1995-2024 by Bradford W. Mott, Stephen Anthony
|
// Copyright (c) 1995-2025 by Bradford W. Mott, Stephen Anthony
|
||||||
// and the Stella Team
|
// and the Stella Team
|
||||||
//
|
//
|
||||||
// See the file "License.txt" for information on usage and redistribution of
|
// See the file "License.txt" for information on usage and redistribution of
|
||||||
|
@ -17,8 +17,8 @@
|
||||||
|
|
||||||
#ifdef SOUND_SUPPORT
|
#ifdef SOUND_SUPPORT
|
||||||
|
|
||||||
#ifndef SOUND_SDL2_HXX
|
#ifndef SOUND_SDL_HXX
|
||||||
#define SOUND_SDL2_HXX
|
#define SOUND_SDL_HXX
|
||||||
|
|
||||||
class OSystem;
|
class OSystem;
|
||||||
class AudioQueue;
|
class AudioQueue;
|
||||||
|
@ -36,15 +36,15 @@ class Resampler;
|
||||||
|
|
||||||
@author Stephen Anthony and Christian Speckner (DirtyHairy)
|
@author Stephen Anthony and Christian Speckner (DirtyHairy)
|
||||||
*/
|
*/
|
||||||
class SoundSDL2 : public Sound
|
class SoundSDL : public Sound
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
Create a new sound object. The init method must be invoked before
|
Create a new sound object. The init method must be invoked before
|
||||||
using the object.
|
using the object.
|
||||||
*/
|
*/
|
||||||
SoundSDL2(OSystem& osystem, AudioSettings& audioSettings);
|
SoundSDL(OSystem& osystem, AudioSettings& audioSettings);
|
||||||
~SoundSDL2() override;
|
~SoundSDL() override;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
|
@ -92,9 +92,10 @@ class SoundSDL2 : public Sound
|
||||||
volume is given as a range from 0 to 100 (0 indicates mute). Values
|
volume is given as a range from 0 to 100 (0 indicates mute). Values
|
||||||
outside this range indicate that the volume shouldn't be changed at all.
|
outside this range indicate that the volume shouldn't be changed at all.
|
||||||
|
|
||||||
@param volume The new volume level for the sound device
|
@param volume The new volume level for the sound device
|
||||||
|
@param persist Whether to save the volume change to settings
|
||||||
*/
|
*/
|
||||||
void setVolume(uInt32 volume) override;
|
void setVolume(uInt32 volume, bool persist = true) override;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Adjusts the volume of the sound device based on the given direction.
|
Adjusts the volume of the sound device based on the given direction.
|
||||||
|
@ -133,13 +134,6 @@ class SoundSDL2 : public Sound
|
||||||
uInt32 wavSize() const override;
|
uInt32 wavSize() const override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/**
|
|
||||||
This method is called to query the audio devices.
|
|
||||||
|
|
||||||
@param devices List of device names
|
|
||||||
*/
|
|
||||||
void queryHardware(VariantList& devices) override;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
The actual sound device is opened only when absolutely necessary.
|
The actual sound device is opened only when absolutely necessary.
|
||||||
Typically this will only happen once per program run, but it can also
|
Typically this will only happen once per program run, but it can also
|
||||||
|
@ -156,10 +150,14 @@ class SoundSDL2 : public Sound
|
||||||
bool myIsInitializedFlag{false};
|
bool myIsInitializedFlag{false};
|
||||||
|
|
||||||
// Audio specification structure
|
// Audio specification structure
|
||||||
SDL_AudioSpec myHardwareSpec{};
|
SDL_AudioSpec mySpec{};
|
||||||
|
|
||||||
SDL_AudioDeviceID myDevice{0};
|
// Audio device and stream, which handles all interaction with SDL sound backend
|
||||||
uInt32 myDeviceId{0};
|
SDL_AudioDeviceID myDevice{};
|
||||||
|
SDL_AudioStream* myStream{nullptr};
|
||||||
|
|
||||||
|
// Audio buffer, passed to the audio callback and filled from the resampler
|
||||||
|
std::vector<uInt8> myBuffer;
|
||||||
|
|
||||||
shared_ptr<AudioQueue> myAudioQueue;
|
shared_ptr<AudioQueue> myAudioQueue;
|
||||||
unique_ptr<Resampler> myResampler;
|
unique_ptr<Resampler> myResampler;
|
||||||
|
@ -169,65 +167,66 @@ class SoundSDL2 : public Sound
|
||||||
Int16* myCurrentFragment{nullptr};
|
Int16* myCurrentFragment{nullptr};
|
||||||
bool myUnderrun{false};
|
bool myUnderrun{false};
|
||||||
|
|
||||||
|
float myVolumeFactor{1.F}; // Current volume level (0.F - 1.F)
|
||||||
|
|
||||||
string myAboutString;
|
string myAboutString;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
This class implements WAV file playback using the SDL2 sound API.
|
This class implements WAV file playback using the SDL sound API.
|
||||||
*/
|
*/
|
||||||
class WavHandlerSDL2
|
class WavHandler
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
explicit WavHandlerSDL2() = default;
|
explicit WavHandler() = default;
|
||||||
~WavHandlerSDL2();
|
~WavHandler();
|
||||||
|
|
||||||
bool play(const string& fileName, const char* device,
|
bool play(SDL_AudioDeviceID device, const string& fileName,
|
||||||
uInt32 position, uInt32 length);
|
uInt32 position, uInt32 length);
|
||||||
void stop();
|
void stop();
|
||||||
uInt32 size() const { return myBuffer ? myRemaining : 0; }
|
uInt32 size() const { return myBuffer ? myRemaining : 0; }
|
||||||
|
void setSpeed(double speed) { mySpeed = speed; }
|
||||||
void setSpeed(const double speed) { mySpeed = speed; }
|
void setVolumeFactor(float volumeFactor);
|
||||||
void pause(bool state) const;
|
void pause(bool state) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
string myFilename;
|
string myFilename;
|
||||||
uInt32 myLength{0};
|
SDL_AudioStream* myStream{nullptr};
|
||||||
SDL_AudioDeviceID myDevice{0};
|
SDL_AudioSpec mySpec{};
|
||||||
uInt8* myBuffer{nullptr};
|
uInt8* myBuffer{nullptr};
|
||||||
|
uInt32 myLength{0};
|
||||||
double mySpeed{1.0};
|
double mySpeed{1.0};
|
||||||
unique_ptr<uInt8[]> myCvtBuffer;
|
float myVolumeFactor{1.F}; // Current volume level (0.F - 1.F)
|
||||||
uInt32 myCvtBufferSize{0};
|
|
||||||
SDL_AudioSpec mySpec{}; // audio output format
|
|
||||||
uInt8* myPos{nullptr}; // pointer to the audio buffer to be played
|
uInt8* myPos{nullptr}; // pointer to the audio buffer to be played
|
||||||
uInt32 myRemaining{0}; // remaining length of the sample we have to play
|
uInt32 myRemaining{0}; // remaining length of the sample we have to play
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Callback function invoked by the SDL Audio library when it needs data
|
// Callback function invoked by the SDL Audio library when it needs data
|
||||||
void processWav(uInt8* stream, uInt32 len);
|
static void wavCallback(void* object, SDL_AudioStream* stream,
|
||||||
static void callback(void* object, uInt8* stream, int len);
|
int additional_amt, int);
|
||||||
|
|
||||||
// Following constructors and assignment operators not supported
|
// Following constructors and assignment operators not supported
|
||||||
WavHandlerSDL2(const WavHandlerSDL2&) = delete;
|
WavHandler(const WavHandler&) = delete;
|
||||||
WavHandlerSDL2(WavHandlerSDL2&&) = delete;
|
WavHandler(WavHandler&&) = delete;
|
||||||
WavHandlerSDL2& operator=(const WavHandlerSDL2&) = delete;
|
WavHandler& operator=(const WavHandler&) = delete;
|
||||||
WavHandlerSDL2& operator=(WavHandlerSDL2&&) = delete;
|
WavHandler& operator=(WavHandler&&) = delete;
|
||||||
};
|
};
|
||||||
|
|
||||||
WavHandlerSDL2 myWavHandler;
|
WavHandler myWavHandler;
|
||||||
|
|
||||||
static float myVolumeFactor; // Current volume level (0 - 100)
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Callback functions invoked by the SDL Audio library when it needs data
|
// Callback functions invoked by the SDL Audio library when it needs data
|
||||||
static void callback(void* object, uInt8* stream, int len);
|
static void audioCallback(void* object, SDL_AudioStream* stream,
|
||||||
|
int additional_amt, int);
|
||||||
|
|
||||||
// Following constructors and assignment operators not supported
|
// Following constructors and assignment operators not supported
|
||||||
SoundSDL2() = delete;
|
SoundSDL() = delete;
|
||||||
SoundSDL2(const SoundSDL2&) = delete;
|
SoundSDL(const SoundSDL&) = delete;
|
||||||
SoundSDL2(SoundSDL2&&) = delete;
|
SoundSDL(SoundSDL&&) = delete;
|
||||||
SoundSDL2& operator=(const SoundSDL2&) = delete;
|
SoundSDL& operator=(const SoundSDL&) = delete;
|
||||||
SoundSDL2& operator=(SoundSDL2&&) = delete;
|
SoundSDL& operator=(SoundSDL&&) = delete;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif // SOUND_SDL_HXX
|
||||||
|
|
||||||
#endif // SOUND_SUPPORT
|
#endif // SOUND_SUPPORT
|
|
@ -8,7 +8,7 @@
|
||||||
// SS SS tt ee ll ll aa aa
|
// SS SS tt ee ll ll aa aa
|
||||||
// SSSS ttt eeeee llll llll aaaaa
|
// SSSS ttt eeeee llll llll aaaaa
|
||||||
//
|
//
|
||||||
// Copyright (c) 1995-2024 by Bradford W. Mott, Stephen Anthony
|
// Copyright (c) 1995-2025 by Bradford W. Mott, Stephen Anthony
|
||||||
// and the Stella Team
|
// and the Stella Team
|
||||||
//
|
//
|
||||||
// See the file "License.txt" for information on usage and redistribution of
|
// See the file "License.txt" for information on usage and redistribution of
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
// SS SS tt ee ll ll aa aa
|
// SS SS tt ee ll ll aa aa
|
||||||
// SSSS ttt eeeee llll llll aaaaa
|
// SSSS ttt eeeee llll llll aaaaa
|
||||||
//
|
//
|
||||||
// Copyright (c) 1995-2024 by Bradford W. Mott, Stephen Anthony
|
// Copyright (c) 1995-2025 by Bradford W. Mott, Stephen Anthony
|
||||||
// and the Stella Team
|
// and the Stella Team
|
||||||
//
|
//
|
||||||
// See the file "License.txt" for information on usage and redistribution of
|
// See the file "License.txt" for information on usage and redistribution of
|
||||||
|
@ -116,7 +116,9 @@ void StaggeredLogger::startInterval()
|
||||||
Int64 msecSinceLastIntervalEnd =
|
Int64 msecSinceLastIntervalEnd =
|
||||||
duration_cast<duration<Int64, std::milli>>(now - myLastIntervalEndTimestamp).count();
|
duration_cast<duration<Int64, std::milli>>(now - myLastIntervalEndTimestamp).count();
|
||||||
|
|
||||||
while (msecSinceLastIntervalEnd > myCooldownTime && myCurrentIntervalFactor > 1) {
|
while (std::cmp_greater(msecSinceLastIntervalEnd, myCooldownTime) &&
|
||||||
|
myCurrentIntervalFactor > 1)
|
||||||
|
{
|
||||||
msecSinceLastIntervalEnd -= myCooldownTime;
|
msecSinceLastIntervalEnd -= myCooldownTime;
|
||||||
decreaseInterval();
|
decreaseInterval();
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
// SS SS tt ee ll ll aa aa
|
// SS SS tt ee ll ll aa aa
|
||||||
// SSSS ttt eeeee llll llll aaaaa
|
// SSSS ttt eeeee llll llll aaaaa
|
||||||
//
|
//
|
||||||
// Copyright (c) 1995-2024 by Bradford W. Mott, Stephen Anthony
|
// Copyright (c) 1995-2025 by Bradford W. Mott, Stephen Anthony
|
||||||
// and the Stella Team
|
// and the Stella Team
|
||||||
//
|
//
|
||||||
// See the file "License.txt" for information on usage and redistribution of
|
// See the file "License.txt" for information on usage and redistribution of
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
// SS SS tt ee ll ll aa aa
|
// SS SS tt ee ll ll aa aa
|
||||||
// SSSS ttt eeeee llll llll aaaaa
|
// SSSS ttt eeeee llll llll aaaaa
|
||||||
//
|
//
|
||||||
// Copyright (c) 1995-2024 by Bradford W. Mott, Stephen Anthony
|
// Copyright (c) 1995-2025 by Bradford W. Mott, Stephen Anthony
|
||||||
// and the Stella Team
|
// and the Stella Team
|
||||||
//
|
//
|
||||||
// See the file "License.txt" for information on usage and redistribution of
|
// See the file "License.txt" for information on usage and redistribution of
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
// SS SS tt ee ll ll aa aa
|
// SS SS tt ee ll ll aa aa
|
||||||
// SSSS ttt eeeee llll llll aaaaa
|
// SSSS ttt eeeee llll llll aaaaa
|
||||||
//
|
//
|
||||||
// Copyright (c) 1995-2024 by Bradford W. Mott, Stephen Anthony
|
// Copyright (c) 1995-2025 by Bradford W. Mott, Stephen Anthony
|
||||||
// and the Stella Team
|
// and the Stella Team
|
||||||
//
|
//
|
||||||
// See the file "License.txt" for information on usage and redistribution of
|
// See the file "License.txt" for information on usage and redistribution of
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
// SS SS tt ee ll ll aa aa
|
// SS SS tt ee ll ll aa aa
|
||||||
// SSSS ttt eeeee llll llll aaaaa
|
// SSSS ttt eeeee llll llll aaaaa
|
||||||
//
|
//
|
||||||
// Copyright (c) 1995-2024 by Bradford W. Mott, Stephen Anthony
|
// Copyright (c) 1995-2025 by Bradford W. Mott, Stephen Anthony
|
||||||
// and the Stella Team
|
// and the Stella Team
|
||||||
//
|
//
|
||||||
// See the file "License.txt" for information on usage and redistribution of
|
// See the file "License.txt" for information on usage and redistribution of
|
||||||
|
@ -221,16 +221,16 @@ enum StellaKey // NOLINT: use 32-bit, even though 16-bit is sufficient
|
||||||
KBDK_F23 = 114,
|
KBDK_F23 = 114,
|
||||||
KBDK_F24 = 115,
|
KBDK_F24 = 115,
|
||||||
KBDK_EXECUTE = 116,
|
KBDK_EXECUTE = 116,
|
||||||
KBDK_HELP = 117,
|
KBDK_HELP = 117, /**< AL Integrated Help Center */
|
||||||
KBDK_MENU = 118,
|
KBDK_MENU = 118, /**< Menu (show menu) */
|
||||||
KBDK_SELECT = 119,
|
KBDK_SELECT = 119,
|
||||||
KBDK_STOP = 120,
|
KBDK_STOP = 120, /**< AC Stop */
|
||||||
KBDK_AGAIN = 121, /**< redo */
|
KBDK_AGAIN = 121, /**< AC Redo/Repeat */
|
||||||
KBDK_UNDO = 122,
|
KBDK_UNDO = 122, /**< AC Undo */
|
||||||
KBDK_CUT = 123,
|
KBDK_CUT = 123, /**< AC Cut */
|
||||||
KBDK_COPY = 124,
|
KBDK_COPY = 124, /**< AC Copy */
|
||||||
KBDK_PASTE = 125,
|
KBDK_PASTE = 125, /**< AC Paste */
|
||||||
KBDK_FIND = 126,
|
KBDK_FIND = 126, /**< AC Find */
|
||||||
KBDK_MUTE = 127,
|
KBDK_MUTE = 127,
|
||||||
KBDK_VOLUMEUP = 128,
|
KBDK_VOLUMEUP = 128,
|
||||||
KBDK_VOLUMEDOWN = 129,
|
KBDK_VOLUMEDOWN = 129,
|
||||||
|
@ -261,9 +261,9 @@ enum StellaKey // NOLINT: use 32-bit, even though 16-bit is sufficient
|
||||||
KBDK_LANG8 = 151, /**< reserved */
|
KBDK_LANG8 = 151, /**< reserved */
|
||||||
KBDK_LANG9 = 152, /**< reserved */
|
KBDK_LANG9 = 152, /**< reserved */
|
||||||
|
|
||||||
KBDK_ALTERASE = 153, /**< Erase-Eaze */
|
KBDK_ALTERASE = 153, /**< Erase-Eaze */
|
||||||
KBDK_SYSREQ = 154,
|
KBDK_SYSREQ = 154,
|
||||||
KBDK_CANCEL = 155,
|
KBDK_CANCEL = 155, /**< AC Cancel */
|
||||||
KBDK_CLEAR = 156,
|
KBDK_CLEAR = 156,
|
||||||
KBDK_PRIOR = 157,
|
KBDK_PRIOR = 157,
|
||||||
KBDK_RETURN2 = 158,
|
KBDK_RETURN2 = 158,
|
||||||
|
@ -330,10 +330,10 @@ enum StellaKey // NOLINT: use 32-bit, even though 16-bit is sufficient
|
||||||
KBDK_RALT = 230, /**< alt gr, option */
|
KBDK_RALT = 230, /**< alt gr, option */
|
||||||
KBDK_RGUI = 231, /**< windows, command (apple), meta */
|
KBDK_RGUI = 231, /**< windows, command (apple), meta */
|
||||||
|
|
||||||
KBDK_MODE = 257, /**< ALT-GR(aph) key on non-American keyboards
|
KBDK_MODE = 257, /**< I'm not sure if this is really not covered
|
||||||
* This is like pressing KBDK_RALT + KBDK_RCTRL
|
* by any of the above, but since there's a
|
||||||
* on some keyboards
|
* special SDL_KMOD_MODE for it I'm adding it here
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* @} *//* Usage page 0x07 */
|
/* @} *//* Usage page 0x07 */
|
||||||
|
|
||||||
|
@ -341,77 +341,98 @@ enum StellaKey // NOLINT: use 32-bit, even though 16-bit is sufficient
|
||||||
* \name Usage page 0x0C
|
* \name Usage page 0x0C
|
||||||
*
|
*
|
||||||
* These values are mapped from usage page 0x0C (USB consumer page).
|
* These values are mapped from usage page 0x0C (USB consumer page).
|
||||||
|
*
|
||||||
|
* There are way more keys in the spec than we can represent in the
|
||||||
|
* current scancode range, so pick the ones that commonly come up in
|
||||||
|
* real world usage.
|
||||||
*/
|
*/
|
||||||
/* @{ */
|
/* @{ */
|
||||||
|
|
||||||
KBDK_AUDIONEXT = 258,
|
KBDK_SLEEP = 258, /**< Sleep */
|
||||||
KBDK_AUDIOPREV = 259,
|
KBDK_WAKE = 259, /**< Wake */
|
||||||
KBDK_AUDIOSTOP = 260,
|
|
||||||
KBDK_AUDIOPLAY = 261,
|
KBDK_CHANNEL_INCREMENT = 260, /**< Channel Increment */
|
||||||
KBDK_AUDIOMUTE = 262,
|
KBDK_CHANNEL_DECREMENT = 261, /**< Channel Decrement */
|
||||||
KBDK_MEDIASELECT = 263,
|
|
||||||
KBDK_WWW = 264,
|
KBDK_MEDIA_PLAY = 262, /**< Play */
|
||||||
KBDK_MAIL = 265,
|
KBDK_MEDIA_PAUSE = 263, /**< Pause */
|
||||||
KBDK_CALCULATOR = 266,
|
KBDK_MEDIA_RECORD = 264, /**< Record */
|
||||||
KBDK_COMPUTER = 267,
|
KBDK_MEDIA_FAST_FORWARD = 265, /**< Fast Forward */
|
||||||
KBDK_AC_SEARCH = 268,
|
KBDK_MEDIA_REWIND = 266, /**< Rewind */
|
||||||
KBDK_AC_HOME = 269,
|
KBDK_MEDIA_NEXT_TRACK = 267, /**< Next Track */
|
||||||
KBDK_AC_BACK = 270,
|
KBDK_MEDIA_PREVIOUS_TRACK = 268, /**< Previous Track */
|
||||||
KBDK_AC_FORWARD = 271,
|
KBDK_MEDIA_STOP = 269, /**< Stop */
|
||||||
KBDK_AC_STOP = 272,
|
KBDK_MEDIA_EJECT = 270, /**< Eject */
|
||||||
KBDK_AC_REFRESH = 273,
|
KBDK_MEDIA_PLAY_PAUSE = 271, /**< Play / Pause */
|
||||||
KBDK_AC_BOOKMARKS = 274,
|
KBDK_MEDIA_SELECT = 272, /* Media Select */
|
||||||
|
|
||||||
|
KBDK_AC_NEW = 273, /**< AC New */
|
||||||
|
KBDK_AC_OPEN = 274, /**< AC Open */
|
||||||
|
KBDK_AC_CLOSE = 275, /**< AC Close */
|
||||||
|
KBDK_AC_EXIT = 276, /**< AC Exit */
|
||||||
|
KBDK_AC_SAVE = 277, /**< AC Save */
|
||||||
|
KBDK_AC_PRINT = 278, /**< AC Print */
|
||||||
|
KBDK_AC_PROPERTIES = 279, /**< AC Properties */
|
||||||
|
|
||||||
|
KBDK_AC_SEARCH = 280, /**< AC Search */
|
||||||
|
KBDK_AC_HOME = 281, /**< AC Home */
|
||||||
|
KBDK_AC_BACK = 282, /**< AC Back */
|
||||||
|
KBDK_AC_FORWARD = 283, /**< AC Forward */
|
||||||
|
KBDK_AC_STOP = 284, /**< AC Stop */
|
||||||
|
KBDK_AC_REFRESH = 285, /**< AC Refresh */
|
||||||
|
KBDK_AC_BOOKMARKS = 286, /**< AC Bookmarks */
|
||||||
|
|
||||||
/* @} *//* Usage page 0x0C */
|
/* @} *//* Usage page 0x0C */
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \name Walther keys
|
* \name Mobile keys
|
||||||
*
|
*
|
||||||
* These are values that Christian Walther added (for mac keyboard?).
|
* These are values that are often used on mobile phones.
|
||||||
*/
|
*/
|
||||||
/* @{ */
|
/* @{ */
|
||||||
|
|
||||||
KBDK_BRIGHTNESSDOWN = 275,
|
KBDK_SOFTLEFT = 287, /**< Usually situated below the display on phones and
|
||||||
KBDK_BRIGHTNESSUP = 276,
|
used as a multi-function feature key for selecting
|
||||||
KBDK_DISPLAYSWITCH = 277, /**< display mirroring/dual display
|
a software defined function shown on the bottom left
|
||||||
switch, video mode switch */
|
of the display. */
|
||||||
KBDK_KBDILLUMTOGGLE = 278,
|
KBDK_SOFTRIGHT = 288, /**< Usually situated below the display on phones and
|
||||||
KBDK_KBDILLUMDOWN = 279,
|
used as a multi-function feature key for selecting
|
||||||
KBDK_KBDILLUMUP = 280,
|
a software defined function shown on the bottom right
|
||||||
KBDK_EJECT = 281,
|
of the display. */
|
||||||
KBDK_SLEEP = 282,
|
KBDK_CALL = 289, /**< Used for accepting phone calls. */
|
||||||
|
KBDK_ENDCALL = 290, /**< Used for rejecting phone calls. */
|
||||||
|
|
||||||
KBDK_APP1 = 283,
|
/* @} *//* Mobile keys */
|
||||||
KBDK_APP2 = 284,
|
|
||||||
|
|
||||||
/* @} *//* Walther keys */
|
|
||||||
|
|
||||||
/* Add any other keys here. */
|
/* Add any other keys here. */
|
||||||
|
|
||||||
KBDK_LAST = 512 /**< not a key, just marks the number of scancodes
|
KBDK_RESERVED = 400, /**< 400-500 reserved for dynamic keycodes */
|
||||||
for array bounds */
|
|
||||||
|
KBDK_COUNT = 512 /**< not a key, just marks the number of scancodes for array bounds */
|
||||||
};
|
};
|
||||||
|
|
||||||
// This comes directly from SDL_keycode.h
|
// This comes directly from SDL_keycode.h
|
||||||
enum StellaMod: uInt16
|
enum StellaMod: uInt16
|
||||||
{
|
{
|
||||||
KBDM_NONE = 0x0000,
|
KBDM_NONE = 0x0000U, /**< no modifier is applicable. */
|
||||||
KBDM_LSHIFT = 0x0001,
|
KBDM_LSHIFT = 0x0001U, /**< the left Shift key is down. */
|
||||||
KBDM_RSHIFT = 0x0002,
|
KBDM_RSHIFT = 0x0002U, /**< the right Shift key is down. */
|
||||||
KBDM_LCTRL = 0x0040,
|
KBDM_LEVEL5 = 0x0004U, /**< the Level 5 Shift key is down. */
|
||||||
KBDM_RCTRL = 0x0080,
|
KBDM_LCTRL = 0x0040U, /**< the left Ctrl (Control) key is down. */
|
||||||
KBDM_LALT = 0x0100,
|
KBDM_RCTRL = 0x0080U, /**< the right Ctrl (Control) key is down. */
|
||||||
KBDM_RALT = 0x0200,
|
KBDM_LALT = 0x0100U, /**< the left Alt key is down. */
|
||||||
KBDM_LGUI = 0x0400,
|
KBDM_RALT = 0x0200U, /**< the right Alt key is down. */
|
||||||
KBDM_RGUI = 0x0800,
|
KBDM_LGUI = 0x0400U, /**< the left GUI key (often the Windows key) is down. */
|
||||||
KBDM_NUM = 0x1000,
|
KBDM_RGUI = 0x0800U, /**< the right GUI key (often the Windows key) is down. */
|
||||||
KBDM_CAPS = 0x2000,
|
KBDM_NUM = 0x1000U, /**< the Num Lock key (may be located on an extended keypad) is down. */
|
||||||
KBDM_MODE = 0x4000,
|
KBDM_CAPS = 0x2000U, /**< the Caps Lock key is down. */
|
||||||
KBDM_RESERVED = 0x8000,
|
KBDM_MODE = 0x4000U, /**< the !AltGr key is down. */
|
||||||
KBDM_CTRL = (KBDM_LCTRL|KBDM_RCTRL),
|
KBDM_SCROLL = 0x8000U, /**< the Scroll Lock key is down. */
|
||||||
KBDM_SHIFT = (KBDM_LSHIFT|KBDM_RSHIFT),
|
KBDM_CTRL = (KBDM_LCTRL | KBDM_RCTRL), /**< Any Ctrl key is down. */
|
||||||
KBDM_ALT = (KBDM_LALT|KBDM_RALT),
|
KBDM_SHIFT = (KBDM_LSHIFT | KBDM_RSHIFT), /**< Any Shift key is down. */
|
||||||
KBDM_GUI = (KBDM_LGUI|KBDM_RGUI)
|
KBDM_ALT = (KBDM_LALT | KBDM_RALT), /**< Any Alt key is down. */
|
||||||
|
KBDM_GUI = (KBDM_LGUI | KBDM_RGUI) /**< Any GUI key is down. */
|
||||||
};
|
};
|
||||||
|
|
||||||
// Test if specified modifier is pressed
|
// Test if specified modifier is pressed
|
||||||
|
@ -442,7 +463,7 @@ namespace StellaKeyName
|
||||||
inline string_view forKey(StellaKey key)
|
inline string_view forKey(StellaKey key)
|
||||||
{
|
{
|
||||||
#ifdef SDL_SUPPORT
|
#ifdef SDL_SUPPORT
|
||||||
return SDL_GetScancodeName(SDL_Scancode(key));
|
return SDL_GetScancodeName(static_cast<SDL_Scancode>(key));
|
||||||
#else
|
#else
|
||||||
return string_view{};
|
return string_view{};
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
// SS SS tt ee ll ll aa aa
|
// SS SS tt ee ll ll aa aa
|
||||||
// SSSS ttt eeeee llll llll aaaaa
|
// SSSS ttt eeeee llll llll aaaaa
|
||||||
//
|
//
|
||||||
// Copyright (c) 1995-2024 by Bradford W. Mott, Stephen Anthony
|
// Copyright (c) 1995-2025 by Bradford W. Mott, Stephen Anthony
|
||||||
// and the Stella Team
|
// and the Stella Team
|
||||||
//
|
//
|
||||||
// See the file "License.txt" for information on usage and redistribution of
|
// See the file "License.txt" for information on usage and redistribution of
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
// SS SS tt ee ll ll aa aa
|
// SS SS tt ee ll ll aa aa
|
||||||
// SSSS ttt eeeee llll llll aaaaa
|
// SSSS ttt eeeee llll llll aaaaa
|
||||||
//
|
//
|
||||||
// Copyright (c) 1995-2024 by Bradford W. Mott, Stephen Anthony
|
// Copyright (c) 1995-2025 by Bradford W. Mott, Stephen Anthony
|
||||||
// and the Stella Team
|
// and the Stella Team
|
||||||
//
|
//
|
||||||
// See the file "License.txt" for information on usage and redistribution of
|
// See the file "License.txt" for information on usage and redistribution of
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
// SS SS tt ee ll ll aa aa
|
// SS SS tt ee ll ll aa aa
|
||||||
// SSSS ttt eeeee llll llll aaaaa
|
// SSSS ttt eeeee llll llll aaaaa
|
||||||
//
|
//
|
||||||
// Copyright (c) 1995-2024 by Bradford W. Mott, Stephen Anthony
|
// Copyright (c) 1995-2025 by Bradford W. Mott, Stephen Anthony
|
||||||
// and the Stella Team
|
// and the Stella Team
|
||||||
//
|
//
|
||||||
// See the file "License.txt" for information on usage and redistribution of
|
// See the file "License.txt" for information on usage and redistribution of
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
// SS SS tt ee ll ll aa aa
|
// SS SS tt ee ll ll aa aa
|
||||||
// SSSS ttt eeeee llll llll aaaaa
|
// SSSS ttt eeeee llll llll aaaaa
|
||||||
//
|
//
|
||||||
// Copyright (c) 1995-2024 by Bradford W. Mott, Stephen Anthony
|
// Copyright (c) 1995-2025 by Bradford W. Mott, Stephen Anthony
|
||||||
// and the Stella Team
|
// and the Stella Team
|
||||||
//
|
//
|
||||||
// See the file "License.txt" for information on usage and redistribution of
|
// See the file "License.txt" for information on usage and redistribution of
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
// SS SS tt ee ll ll aa aa
|
// SS SS tt ee ll ll aa aa
|
||||||
// SSSS ttt eeeee llll llll aaaaa
|
// SSSS ttt eeeee llll llll aaaaa
|
||||||
//
|
//
|
||||||
// Copyright (c) 1995-2024 by Bradford W. Mott, Stephen Anthony
|
// Copyright (c) 1995-2025 by Bradford W. Mott, Stephen Anthony
|
||||||
// and the Stella Team
|
// and the Stella Team
|
||||||
//
|
//
|
||||||
// See the file "License.txt" for information on usage and redistribution of
|
// See the file "License.txt" for information on usage and redistribution of
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
// SS SS tt ee ll ll aa aa
|
// SS SS tt ee ll ll aa aa
|
||||||
// SSSS ttt eeeee llll llll aaaaa
|
// SSSS ttt eeeee llll llll aaaaa
|
||||||
//
|
//
|
||||||
// Copyright (c) 1995-2024 by Bradford W. Mott, Stephen Anthony
|
// Copyright (c) 1995-2025 by Bradford W. Mott, Stephen Anthony
|
||||||
// and the Stella Team
|
// and the Stella Team
|
||||||
//
|
//
|
||||||
// See the file "License.txt" for information on usage and redistribution of
|
// See the file "License.txt" for information on usage and redistribution of
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
// SS SS tt ee ll ll aa aa
|
// SS SS tt ee ll ll aa aa
|
||||||
// SSSS ttt eeeee llll llll aaaaa
|
// SSSS ttt eeeee llll llll aaaaa
|
||||||
//
|
//
|
||||||
// Copyright (c) 1995-2024 by Bradford W. Mott, Stephen Anthony
|
// Copyright (c) 1995-2025 by Bradford W. Mott, Stephen Anthony
|
||||||
// and the Stella Team
|
// and the Stella Team
|
||||||
//
|
//
|
||||||
// See the file "License.txt" for information on usage and redistribution of
|
// See the file "License.txt" for information on usage and redistribution of
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
// SS SS tt ee ll ll aa aa
|
// SS SS tt ee ll ll aa aa
|
||||||
// SSSS ttt eeeee llll llll aaaaa
|
// SSSS ttt eeeee llll llll aaaaa
|
||||||
//
|
//
|
||||||
// Copyright (c) 1995-2024 by Bradford W. Mott, Stephen Anthony
|
// Copyright (c) 1995-2025 by Bradford W. Mott, Stephen Anthony
|
||||||
// and the Stella Team
|
// and the Stella Team
|
||||||
//
|
//
|
||||||
// See the file "License.txt" for information on usage and redistribution of
|
// See the file "License.txt" for information on usage and redistribution of
|
||||||
|
@ -18,7 +18,7 @@
|
||||||
#ifndef VERSION_HXX
|
#ifndef VERSION_HXX
|
||||||
#define VERSION_HXX
|
#define VERSION_HXX
|
||||||
|
|
||||||
#define STELLA_VERSION "7.0"
|
#define STELLA_VERSION "8.0_pre"
|
||||||
#define STELLA_BUILD "8005"
|
#define STELLA_BUILD "8005"
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
// SS SS tt ee ll ll aa aa
|
// SS SS tt ee ll ll aa aa
|
||||||
// SSSS ttt eeeee llll llll aaaaa
|
// SSSS ttt eeeee llll llll aaaaa
|
||||||
//
|
//
|
||||||
// Copyright (c) 1995-2024 by Bradford W. Mott, Stephen Anthony
|
// Copyright (c) 1995-2025 by Bradford W. Mott, Stephen Anthony
|
||||||
// and the Stella Team
|
// and the Stella Team
|
||||||
//
|
//
|
||||||
// See the file "License.txt" for information on usage and redistribution of
|
// See the file "License.txt" for information on usage and redistribution of
|
||||||
|
@ -29,17 +29,17 @@ void VideoModeHandler::setImageSize(const Common::Size& image)
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
void VideoModeHandler::setDisplaySize(const Common::Size& display, Int32 fsIndex)
|
void VideoModeHandler::setDisplaySize(const Common::Size& display, bool fullscreen)
|
||||||
{
|
{
|
||||||
myDisplay = display;
|
myDisplay = display;
|
||||||
myFSIndex = fsIndex;
|
myFullscreen = fullscreen;
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
const VideoModeHandler::Mode&
|
const VideoModeHandler::Mode&
|
||||||
VideoModeHandler::buildMode(const Settings& settings, bool inTIAMode, Bezel::Info bezelInfo)
|
VideoModeHandler::buildMode(const Settings& settings, bool inTIAMode, Bezel::Info bezelInfo)
|
||||||
{
|
{
|
||||||
const bool windowedRequested = myFSIndex == -1;
|
const bool windowedRequested = !myFullscreen;
|
||||||
|
|
||||||
// TIA mode allows zooming at non-integral factors in most cases
|
// TIA mode allows zooming at non-integral factors in most cases
|
||||||
if(inTIAMode)
|
if(inTIAMode)
|
||||||
|
@ -53,7 +53,7 @@ const VideoModeHandler::Mode&
|
||||||
// Image and screen (aka window) dimensions are the same
|
// Image and screen (aka window) dimensions are the same
|
||||||
// Overscan is not applicable in this mode
|
// Overscan is not applicable in this mode
|
||||||
myMode = Mode(myImage.w, myImage.h,
|
myMode = Mode(myImage.w, myImage.h,
|
||||||
Mode::Stretch::Fill, myFSIndex,
|
Mode::Stretch::Fill, myFullscreen,
|
||||||
desc.view(), zoom, bezelInfo);
|
desc.view(), zoom, bezelInfo);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -74,7 +74,7 @@ const VideoModeHandler::Mode&
|
||||||
{
|
{
|
||||||
myMode = Mode(myImage.w, myImage.h,
|
myMode = Mode(myImage.w, myImage.h,
|
||||||
myDisplay.w, myDisplay.h,
|
myDisplay.w, myDisplay.h,
|
||||||
Mode::Stretch::Preserve, myFSIndex,
|
Mode::Stretch::Preserve, myFullscreen,
|
||||||
"Fullscreen: Preserve aspect, no stretch",
|
"Fullscreen: Preserve aspect, no stretch",
|
||||||
zoom, overscan, bezelInfo);
|
zoom, overscan, bezelInfo);
|
||||||
}
|
}
|
||||||
|
@ -82,7 +82,7 @@ const VideoModeHandler::Mode&
|
||||||
{
|
{
|
||||||
myMode = Mode(myImage.w, myImage.h,
|
myMode = Mode(myImage.w, myImage.h,
|
||||||
myDisplay.w, myDisplay.h,
|
myDisplay.w, myDisplay.h,
|
||||||
Mode::Stretch::Fill, myFSIndex,
|
Mode::Stretch::Fill, myFullscreen,
|
||||||
"Fullscreen: Ignore aspect, full stretch",
|
"Fullscreen: Ignore aspect, full stretch",
|
||||||
zoom, overscan, bezelInfo);
|
zoom, overscan, bezelInfo);
|
||||||
}
|
}
|
||||||
|
@ -94,31 +94,31 @@ const VideoModeHandler::Mode&
|
||||||
myMode = Mode(myImage.w, myImage.h, Mode::Stretch::None);
|
myMode = Mode(myImage.w, myImage.h, Mode::Stretch::None);
|
||||||
else
|
else
|
||||||
myMode = Mode(myImage.w, myImage.h, myDisplay.w, myDisplay.h,
|
myMode = Mode(myImage.w, myImage.h, myDisplay.w, myDisplay.h,
|
||||||
Mode::Stretch::None, myFSIndex);
|
Mode::Stretch::None, myFullscreen);
|
||||||
}
|
}
|
||||||
return myMode;
|
return myMode;
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
VideoModeHandler::Mode::Mode(uInt32 iw, uInt32 ih, Stretch smode,
|
VideoModeHandler::Mode::Mode(uInt32 iw, uInt32 ih, Stretch smode,
|
||||||
Int32 fsindex, string_view desc,
|
bool fullscreen, string_view desc,
|
||||||
double zoomLevel, Bezel::Info bezelInfo)
|
double zoomLevel, Bezel::Info bezelInfo)
|
||||||
: Mode(iw, ih, iw, ih, smode, fsindex, desc, zoomLevel, 1., bezelInfo)
|
: Mode(iw, ih, iw, ih, smode, fullscreen, desc, zoomLevel, 1., bezelInfo)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
VideoModeHandler::Mode::Mode(uInt32 iw, uInt32 ih, uInt32 sw, uInt32 sh,
|
VideoModeHandler::Mode::Mode(uInt32 iw, uInt32 ih, uInt32 sw, uInt32 sh,
|
||||||
Stretch smode, Int32 fsindex, string_view desc,
|
Stretch smode, bool fullscreen, string_view desc,
|
||||||
double zoomLevel, double overscan, Bezel::Info bezelInfo)
|
double zoomLevel, double overscan, Bezel::Info bezelInfo)
|
||||||
: screenS{sw, sh},
|
: screenS{sw, sh},
|
||||||
stretch{smode},
|
stretch{smode},
|
||||||
description{desc},
|
description{desc},
|
||||||
zoom{zoomLevel}, //hZoom{zoomLevel}, vZoom{zoomLevel},
|
zoom{zoomLevel}, //hZoom{zoomLevel}, vZoom{zoomLevel},
|
||||||
fsIndex{fsindex}
|
fullscreen{fullscreen}
|
||||||
{
|
{
|
||||||
// Now resize based on windowed/fullscreen mode and stretch factor
|
// Now resize based on windowed/fullscreen mode and stretch factor
|
||||||
if(fsIndex != -1) // fullscreen mode
|
if(fullscreen)
|
||||||
{
|
{
|
||||||
switch(stretch)
|
switch(stretch)
|
||||||
{
|
{
|
||||||
|
@ -174,9 +174,9 @@ VideoModeHandler::Mode::Mode(uInt32 iw, uInt32 ih, uInt32 sw, uInt32 sh,
|
||||||
const uInt32 wx = bezelInfo.window().x() * iw / bezelInfo.window().w();
|
const uInt32 wx = bezelInfo.window().x() * iw / bezelInfo.window().w();
|
||||||
const uInt32 wy = bezelInfo.window().y() * ih / bezelInfo.window().h();
|
const uInt32 wy = bezelInfo.window().y() * ih / bezelInfo.window().h();
|
||||||
const uInt32 bezelW = std::min(screenS.w,
|
const uInt32 bezelW = std::min(screenS.w,
|
||||||
static_cast<uInt32>(std::round(iw * bezelInfo.ratioW())));
|
static_cast<uInt32>(std::round(iw * bezelInfo.ratioW())));
|
||||||
const uInt32 bezelH = std::min(screenS.h,
|
const uInt32 bezelH = std::min(screenS.h,
|
||||||
static_cast<uInt32>(std::round(ih * bezelInfo.ratioH())));
|
static_cast<uInt32>(std::round(ih * bezelInfo.ratioH())));
|
||||||
// Center image (no bezel) or move image relative to centered bezel
|
// Center image (no bezel) or move image relative to centered bezel
|
||||||
imageR.moveTo(((screenS.w - bezelW) >> 1) + wx, ((screenS.h - bezelH) >> 1) + wy);
|
imageR.moveTo(((screenS.w - bezelW) >> 1) + wx, ((screenS.h - bezelH) >> 1) + wy);
|
||||||
|
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
// SS SS tt ee ll ll aa aa
|
// SS SS tt ee ll ll aa aa
|
||||||
// SSSS ttt eeeee llll llll aaaaa
|
// SSSS ttt eeeee llll llll aaaaa
|
||||||
//
|
//
|
||||||
// Copyright (c) 1995-2024 by Bradford W. Mott, Stephen Anthony
|
// Copyright (c) 1995-2025 by Bradford W. Mott, Stephen Anthony
|
||||||
// and the Stella Team
|
// and the Stella Team
|
||||||
//
|
//
|
||||||
// See the file "License.txt" for information on usage and redistribution of
|
// See the file "License.txt" for information on usage and redistribution of
|
||||||
|
@ -46,14 +46,14 @@ class VideoModeHandler
|
||||||
Stretch stretch{Mode::Stretch::None};
|
Stretch stretch{Mode::Stretch::None};
|
||||||
string description;
|
string description;
|
||||||
double zoom{1.};
|
double zoom{1.};
|
||||||
Int32 fsIndex{-1}; // -1 indicates windowed mode
|
bool fullscreen{false}; // false indicates windowed mode
|
||||||
|
|
||||||
Mode() = default;
|
Mode() = default;
|
||||||
Mode(uInt32 iw, uInt32 ih, uInt32 sw, uInt32 sh, Stretch smode,
|
Mode(uInt32 iw, uInt32 ih, uInt32 sw, uInt32 sh, Stretch smode,
|
||||||
Int32 fsindex = -1, string_view desc = "",
|
bool fullscreen = false, string_view desc = "",
|
||||||
double zoomLevel = 1., double overscan = 1.,
|
double zoomLevel = 1., double overscan = 1.,
|
||||||
Bezel::Info bezelInfo = Bezel::Info());
|
Bezel::Info bezelInfo = Bezel::Info());
|
||||||
Mode(uInt32 iw, uInt32 ih, Stretch smode, Int32 fsindex = -1,
|
Mode(uInt32 iw, uInt32 ih, Stretch smode, bool fullscreen = false,
|
||||||
string_view desc = "", double zoomLevel = 1.,
|
string_view desc = "", double zoomLevel = 1.,
|
||||||
Bezel::Info bezelInfo = Bezel::Info());
|
Bezel::Info bezelInfo = Bezel::Info());
|
||||||
|
|
||||||
|
@ -63,7 +63,7 @@ class VideoModeHandler
|
||||||
<< " stretch=" << (vm.stretch == Stretch::Preserve ? "preserve" :
|
<< " stretch=" << (vm.stretch == Stretch::Preserve ? "preserve" :
|
||||||
vm.stretch == Stretch::Fill ? "fill" : "none")
|
vm.stretch == Stretch::Fill ? "fill" : "none")
|
||||||
<< " desc=" << vm.description << " zoom=" << vm.zoom
|
<< " desc=" << vm.description << " zoom=" << vm.zoom
|
||||||
<< " fsIndex= " << vm.fsIndex;
|
<< " fullscreen= " << vm.fullscreen;
|
||||||
return os;
|
return os;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -84,10 +84,10 @@ class VideoModeHandler
|
||||||
Set the size of the display. This could be either the desktop size,
|
Set the size of the display. This could be either the desktop size,
|
||||||
or the size of the monitor currently active.
|
or the size of the monitor currently active.
|
||||||
|
|
||||||
@param display The dimensions of the enclosing display
|
@param display The dimensions of the enclosing display
|
||||||
@param fsIndex Fullscreen mode in use (-1 indicates windowed mode)
|
@param fullscreen Whether to use fullscreen or windowed mode
|
||||||
*/
|
*/
|
||||||
void setDisplaySize(const Common::Size& display, Int32 fsIndex = -1);
|
void setDisplaySize(const Common::Size& display, bool fullscreen);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Build a video mode based on the given parameters, assuming that
|
Build a video mode based on the given parameters, assuming that
|
||||||
|
@ -103,7 +103,7 @@ class VideoModeHandler
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Common::Size myImage, myDisplay;
|
Common::Size myImage, myDisplay;
|
||||||
Int32 myFSIndex{-1};
|
bool myFullscreen{false};
|
||||||
|
|
||||||
Mode myMode;
|
Mode myMode;
|
||||||
|
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
// SS SS tt ee ll ll aa aa
|
// SS SS tt ee ll ll aa aa
|
||||||
// SSSS ttt eeeee llll llll aaaaa
|
// SSSS ttt eeeee llll llll aaaaa
|
||||||
//
|
//
|
||||||
// Copyright (c) 1995-2024 by Bradford W. Mott, Stephen Anthony
|
// Copyright (c) 1995-2025 by Bradford W. Mott, Stephen Anthony
|
||||||
// and the Stella Team
|
// and the Stella Team
|
||||||
//
|
//
|
||||||
// See the file "License.txt" for information on usage and redistribution of
|
// See the file "License.txt" for information on usage and redistribution of
|
||||||
|
@ -266,8 +266,7 @@ void ZipHandler::ZipFile::readEcd()
|
||||||
uInt64 read_length = 0;
|
uInt64 read_length = 0;
|
||||||
|
|
||||||
// Max out the buf length at the size of the file
|
// Max out the buf length at the size of the file
|
||||||
if(buflen > myLength)
|
buflen = std::min(buflen, myLength);
|
||||||
buflen = myLength;
|
|
||||||
|
|
||||||
// Allocate buffer
|
// Allocate buffer
|
||||||
const ByteBuffer buffer = make_unique<uInt8[]>(buflen + 1);
|
const ByteBuffer buffer = make_unique<uInt8[]>(buflen + 1);
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
// SS SS tt ee ll ll aa aa
|
// SS SS tt ee ll ll aa aa
|
||||||
// SSSS ttt eeeee llll llll aaaaa
|
// SSSS ttt eeeee llll llll aaaaa
|
||||||
//
|
//
|
||||||
// Copyright (c) 1995-2024 by Bradford W. Mott, Stephen Anthony
|
// Copyright (c) 1995-2025 by Bradford W. Mott, Stephen Anthony
|
||||||
// and the Stella Team
|
// and the Stella Team
|
||||||
//
|
//
|
||||||
// See the file "License.txt" for information on usage and redistribution of
|
// See the file "License.txt" for information on usage and redistribution of
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
// SS SS tt ee ll ll aa aa
|
// SS SS tt ee ll ll aa aa
|
||||||
// SSSS ttt eeeee llll llll aaaaa
|
// SSSS ttt eeeee llll llll aaaaa
|
||||||
//
|
//
|
||||||
// Copyright (c) 1995-2024 by Bradford W. Mott, Stephen Anthony
|
// Copyright (c) 1995-2025 by Bradford W. Mott, Stephen Anthony
|
||||||
// and the Stella Team
|
// and the Stella Team
|
||||||
//
|
//
|
||||||
// See the file "License.txt" for information on usage and redistribution of
|
// See the file "License.txt" for information on usage and redistribution of
|
||||||
|
|