Compare commits
No commits in common. "master" and "6.5.2" have entirely different histories.
|
@ -1,79 +0,0 @@
|
||||||
---
|
|
||||||
name: Build
|
|
||||||
|
|
||||||
on:
|
|
||||||
pull_request:
|
|
||||||
push:
|
|
||||||
|
|
||||||
permissions: {}
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
linux:
|
|
||||||
name: Linux
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
env:
|
|
||||||
SDL3_VERSION: 3.2.14
|
|
||||||
steps:
|
|
||||||
- name: Check out the repository
|
|
||||||
uses: actions/checkout@93ea575cb5d8a053eaa0ac8fa3b40d7e05a33cc8
|
|
||||||
- name: Install SDL3
|
|
||||||
run: |
|
|
||||||
wget https://github.com/libsdl-org/SDL/releases/download/release-${SDL3_VERSION}/SDL3-${SDL3_VERSION}.tar.gz
|
|
||||||
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
|
|
||||||
run: |
|
|
||||||
CXXFLAGS="-I `pwd`/SDL3/prefix/include -O2 -g" PKG_CONFIG_PATH="`pwd`/SDL3/prefix/lib/pkgconfig/" ./configure
|
|
||||||
make -j2 all
|
|
||||||
|
|
||||||
macos:
|
|
||||||
name: macOS
|
|
||||||
runs-on: macos-latest
|
|
||||||
env:
|
|
||||||
SDL3_VERSION: 3.2.14
|
|
||||||
steps:
|
|
||||||
- uses: maxim-lobanov/setup-xcode@v1
|
|
||||||
with:
|
|
||||||
xcode-version: '16.2'
|
|
||||||
- name: Check out the repository
|
|
||||||
uses: actions/checkout@93ea575cb5d8a053eaa0ac8fa3b40d7e05a33cc8
|
|
||||||
- name: Install SDL3
|
|
||||||
run: |
|
|
||||||
wget https://github.com/libsdl-org/SDL/releases/download/release-${SDL3_VERSION}/SDL3-${SDL3_VERSION}.dmg
|
|
||||||
hdiutil attach SDL3-${SDL3_VERSION}.dmg
|
|
||||||
mkdir -p src/os/macos/Frameworks
|
|
||||||
cp -Rv /Volumes/SDL3/SDL3.xcframework src/os/macos/Frameworks
|
|
||||||
hdiutil detach /Volumes/SDL3
|
|
||||||
- name: Build Stella
|
|
||||||
run: |
|
|
||||||
cd src/os/macos
|
|
||||||
xcodebuild
|
|
||||||
|
|
||||||
windows:
|
|
||||||
name: Windows
|
|
||||||
runs-on: windows-latest
|
|
||||||
strategy:
|
|
||||||
matrix:
|
|
||||||
platform: [x64]
|
|
||||||
env:
|
|
||||||
Platform: ${{ matrix.platform }}
|
|
||||||
SDL3_version: 3.2.14
|
|
||||||
steps:
|
|
||||||
- name: Check out the repository
|
|
||||||
uses: actions/checkout@93ea575cb5d8a053eaa0ac8fa3b40d7e05a33cc8
|
|
||||||
- name: Set up MSBUILD
|
|
||||||
uses: microsoft/setup-msbuild@34cfbaee7f672c76950673338facd8a73f637506
|
|
||||||
- name: Install SDL3
|
|
||||||
shell: cmd
|
|
||||||
run: |
|
|
||||||
curl -o "C:\SDL3-devel.zip" "https://www.libsdl.org/release/SDL3-devel-%SDL3_version%-VC.zip"
|
|
||||||
7z x "C:\SDL3-devel.zip" -o"C:\"
|
|
||||||
xcopy /S "C:\SDL3-%SDL3_version%\include" src\common
|
|
||||||
if %Platform%==x64 xcopy /S "C:\SDL3-%SDL3_version%\lib\x64" src\os\windows
|
|
||||||
|
|
||||||
- name: Build Stella
|
|
||||||
run: |
|
|
||||||
msbuild src\os\windows\Stella.sln
|
|
|
@ -5,15 +5,12 @@ 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
|
||||||
out.pgo
|
out.pgo
|
||||||
out.pgen
|
out.pgen
|
||||||
out.test
|
|
||||||
stella
|
stella
|
||||||
stella-test
|
|
||||||
stella-pgo
|
stella-pgo
|
||||||
stella-pgo-generate
|
stella-pgo-generate
|
||||||
*.diff
|
*.diff
|
||||||
|
@ -21,18 +18,15 @@ project.xcworkspace/
|
||||||
xcuserdata/
|
xcuserdata/
|
||||||
.DS_Store
|
.DS_Store
|
||||||
build/
|
build/
|
||||||
src/os/macos/M6502.ins
|
src/macosx/M6502.ins
|
||||||
*.dSYM
|
*.dSYM
|
||||||
.vscode/c_cpp_properties.json
|
.vscode/c_cpp_properties.json
|
||||||
.vscode/settings.json
|
.vscode/settings.json
|
||||||
src/os/windows/sdl/*
|
src/windows/sdl/*
|
||||||
src/os/windows/sdl3/*
|
src/windows/x64/*
|
||||||
src/os/windows/x64/*
|
src/windows/Win32/*
|
||||||
src/os/windows/Win32/*
|
src/windows/Stella.vcxproj.user
|
||||||
src/os/windows/Stella.vcxproj.user
|
src/windows/*.bak
|
||||||
src/os/windows/*.bak
|
|
||||||
src/os/libretro/x64/*
|
|
||||||
src/os/libretro/Stella.vcxproj.user
|
|
||||||
.vs/*
|
.vs/*
|
||||||
.tgitconfig
|
.tgitconfig
|
||||||
src/**/*.psess
|
src/**/*.psess
|
||||||
|
@ -44,5 +38,3 @@ src/tools/fonts/*
|
||||||
a.out
|
a.out
|
||||||
*.json
|
*.json
|
||||||
*.sqlite3
|
*.sqlite3
|
||||||
*.bak
|
|
||||||
debian/files
|
|
||||||
|
|
140
.gitlab-ci.yml
|
@ -1,148 +1,60 @@
|
||||||
# DESCRIPTION: GitLab CI/CD for libRetro (NOT FOR GitLab-proper)
|
|
||||||
|
|
||||||
##############################################################################
|
|
||||||
################################# BOILERPLATE ################################
|
|
||||||
##############################################################################
|
|
||||||
|
|
||||||
# Core definitions
|
|
||||||
.core-defs:
|
.core-defs:
|
||||||
variables:
|
variables:
|
||||||
JNI_PATH: src/os/libretro
|
JNI_PATH: src/libretro
|
||||||
MAKEFILE_PATH: src/os/libretro
|
MAKEFILE_PATH: src/libretro
|
||||||
CORENAME: stella
|
CORENAME: stella
|
||||||
|
|
||||||
# Inclusion templates, required for the build to work
|
|
||||||
include:
|
include:
|
||||||
################################## DESKTOPS ################################
|
- template: Jobs/Code-Quality.gitlab-ci.yml
|
||||||
# Windows 64-bit
|
|
||||||
- project: 'libretro-infrastructure/ci-templates'
|
- project: 'libretro-infrastructure/ci-templates'
|
||||||
file: '/windows-x64-mingw.yml'
|
file: '/libnx-static.yml'
|
||||||
|
|
||||||
# Linux 64-bit
|
|
||||||
- project: 'libretro-infrastructure/ci-templates'
|
- project: 'libretro-infrastructure/ci-templates'
|
||||||
file: '/linux-x64.yml'
|
file: '/linux-x64.yml'
|
||||||
|
|
||||||
# MacOS 64-bit
|
|
||||||
- project: 'libretro-infrastructure/ci-templates'
|
- project: 'libretro-infrastructure/ci-templates'
|
||||||
file: '/osx-x64.yml'
|
file: '/windows-x64-mingw.yml'
|
||||||
|
|
||||||
# MacOS ARM 64-bit
|
|
||||||
- project: 'libretro-infrastructure/ci-templates'
|
|
||||||
file: '/osx-arm64.yml'
|
|
||||||
|
|
||||||
################################## CELLULAR ################################
|
|
||||||
# Android
|
|
||||||
- project: 'libretro-infrastructure/ci-templates'
|
- project: 'libretro-infrastructure/ci-templates'
|
||||||
file: '/android-jni.yml'
|
file: '/android-jni.yml'
|
||||||
|
|
||||||
# iOS
|
|
||||||
- project: 'libretro-infrastructure/ci-templates'
|
|
||||||
file: '/ios-arm64.yml'
|
|
||||||
|
|
||||||
# iOS (armv7)
|
|
||||||
- project: 'libretro-infrastructure/ci-templates'
|
|
||||||
file: '/ios9.yml'
|
|
||||||
|
|
||||||
################################## CONSOLES ################################
|
|
||||||
# Nintendo Switch
|
|
||||||
- project: 'libretro-infrastructure/ci-templates'
|
|
||||||
file: '/libnx-static.yml'
|
|
||||||
|
|
||||||
# tvOS (AppleTV)
|
|
||||||
- project: 'libretro-infrastructure/ci-templates'
|
|
||||||
file: '/tvos-arm64.yml'
|
|
||||||
|
|
||||||
#################################### MISC ##################################
|
|
||||||
|
|
||||||
# Stages for building
|
|
||||||
stages:
|
stages:
|
||||||
- build-prepare
|
- build-prepare
|
||||||
- build-shared
|
- build-shared
|
||||||
- build-static
|
- build-static
|
||||||
|
- test
|
||||||
|
|
||||||
|
#Desktop
|
||||||
|
libretro-build-linux-x64:
|
||||||
|
extends:
|
||||||
|
- .libretro-linux-x64-make-default
|
||||||
|
- .core-defs
|
||||||
|
|
||||||
##############################################################################
|
|
||||||
#################################### STAGES ##################################
|
|
||||||
##############################################################################
|
|
||||||
#
|
|
||||||
################################### DESKTOPS #################################
|
|
||||||
# Windows 64-bit
|
|
||||||
libretro-build-windows-x64:
|
libretro-build-windows-x64:
|
||||||
extends:
|
extends:
|
||||||
- .libretro-windows-x64-mingw-make-default
|
- .libretro-windows-x64-mingw-make-default
|
||||||
- .core-defs
|
- .core-defs
|
||||||
|
|
||||||
# Linux 64-bit
|
# Android
|
||||||
libretro-build-linux-x64:
|
android-armeabi-v7a:
|
||||||
extends:
|
extends:
|
||||||
- .libretro-linux-x64-make-default
|
- .libretro-android-jni-armeabi-v7a
|
||||||
- .core-defs
|
|
||||||
image: $CI_SERVER_HOST:5050/libretro-infrastructure/libretro-build-amd64-ubuntu:latest
|
|
||||||
before_script:
|
|
||||||
- export NUMPROC=$(($(nproc)/5))
|
|
||||||
- sudo apt-get update -qy
|
|
||||||
- sudo apt-get install -qy software-properties-common
|
|
||||||
- sudo add-apt-repository -y ppa:savoury1/build-tools
|
|
||||||
- sudo add-apt-repository -y ppa:savoury1/gcc-defaults-12
|
|
||||||
- sudo apt-get update -qy
|
|
||||||
- sudo apt-get install -qy gcc-12 g++-12
|
|
||||||
# This container's existing installations of gcc and CMake are way too old
|
|
||||||
variables:
|
|
||||||
CC: /usr/bin/gcc-12
|
|
||||||
CXX: /usr/bin/g++-12
|
|
||||||
CXXFLAGS: -Wno-deprecated-declarations # Deprecation warnings aren't helpful on the libretro Gitlab
|
|
||||||
|
|
||||||
# MacOS 64-bit
|
|
||||||
libretro-build-osx-x64:
|
|
||||||
tags:
|
|
||||||
- mac-apple-silicon
|
|
||||||
extends:
|
|
||||||
- .libretro-osx-x64-make-default
|
|
||||||
- .core-defs
|
- .core-defs
|
||||||
|
|
||||||
# MacOS ARM 64-bit
|
android-arm64-v8a:
|
||||||
libretro-build-osx-arm64:
|
|
||||||
tags:
|
|
||||||
- mac-apple-silicon
|
|
||||||
extends:
|
extends:
|
||||||
- .libretro-osx-arm64-make-default
|
- .libretro-android-jni-arm64-v8a
|
||||||
- .core-defs
|
- .core-defs
|
||||||
|
|
||||||
################################### CELLULAR #################################
|
android-x86_64:
|
||||||
# Android ARMv7a
|
|
||||||
# android-armeabi-v7a:
|
|
||||||
# extends:
|
|
||||||
# - .libretro-android-jni-armeabi-v7a
|
|
||||||
# - .core-defs
|
|
||||||
|
|
||||||
# Android ARMv8a
|
|
||||||
# android-arm64-v8a:
|
|
||||||
# extends:
|
|
||||||
# - .libretro-android-jni-arm64-v8a
|
|
||||||
# - .core-defs
|
|
||||||
|
|
||||||
# Android 64-bit x86
|
|
||||||
# android-x86_64:
|
|
||||||
# extends:
|
|
||||||
# - .libretro-android-jni-x86_64
|
|
||||||
# - .core-defs
|
|
||||||
|
|
||||||
# iOS
|
|
||||||
libretro-build-ios-arm64:
|
|
||||||
tags:
|
|
||||||
- mac-apple-silicon
|
|
||||||
extends:
|
extends:
|
||||||
- .libretro-ios-arm64-make-default
|
- .libretro-android-jni-x86_64
|
||||||
- .core-defs
|
- .core-defs
|
||||||
|
|
||||||
# tvOS
|
android-x86:
|
||||||
libretro-build-tvos-arm64:
|
|
||||||
extends:
|
extends:
|
||||||
- .libretro-tvos-arm64-make-default
|
- .libretro-android-jni-x86
|
||||||
- .core-defs
|
- .core-defs
|
||||||
|
|
||||||
################################### CONSOLES #################################
|
# Static
|
||||||
# Nintendo Switch
|
libretro-build-libnx-aarch64:
|
||||||
# libretro-build-libnx-aarch64:
|
extends:
|
||||||
# extends:
|
- .libretro-libnx-static-retroarch-master
|
||||||
# - .libretro-libnx-static-retroarch-master
|
- .core-defs
|
||||||
# - .core-defs
|
|
||||||
|
|
|
@ -0,0 +1,63 @@
|
||||||
|
# Build matrix / environment variables are explained on:
|
||||||
|
# http://about.travis-ci.org/docs/user/build-configuration/
|
||||||
|
# This file can be validated on: http://lint.travis-ci.org/
|
||||||
|
|
||||||
|
|
||||||
|
language: cpp
|
||||||
|
|
||||||
|
|
||||||
|
matrix:
|
||||||
|
include:
|
||||||
|
- os: linux
|
||||||
|
dist: xenial
|
||||||
|
compiler: gcc
|
||||||
|
env: GCC=9 CC=gcc-9 CXX=g++-9
|
||||||
|
addons:
|
||||||
|
apt:
|
||||||
|
sources:
|
||||||
|
- ubuntu-toolchain-r-test
|
||||||
|
packages:
|
||||||
|
- gcc-9
|
||||||
|
- g++-9
|
||||||
|
update: true
|
||||||
|
|
||||||
|
|
||||||
|
- os: osx
|
||||||
|
osx_image: xcode11.3
|
||||||
|
compiler: clang
|
||||||
|
addons:
|
||||||
|
homebrew:
|
||||||
|
update: true
|
||||||
|
|
||||||
|
|
||||||
|
install:
|
||||||
|
- |
|
||||||
|
old_cwd=$(pwd)
|
||||||
|
cd ~
|
||||||
|
|
||||||
|
if [[ "$HOST" == macosx-* ]]; then
|
||||||
|
curl -O https://www.libsdl.org/release/SDL2-2.0.10.tar.gz
|
||||||
|
tar xzf SDL2-2.0.10.tar.gz
|
||||||
|
cd SDL2-2.0.10/Xcode/SDL
|
||||||
|
sed -i -e 's/@rpath//g' SDL.xcodeproj/project.pbxproj
|
||||||
|
xcodebuild -configuration Release
|
||||||
|
mkdir -p ~/Library/Frameworks/
|
||||||
|
ln -s `pwd`/build/Release/SDL2.framework ~/Library/Frameworks/
|
||||||
|
else
|
||||||
|
curl -O https://www.libsdl.org/release/SDL2-2.0.10.tar.gz
|
||||||
|
tar xzf SDL2-2.0.10.tar.gz
|
||||||
|
cd SDL2-2.0.10
|
||||||
|
mkdir build
|
||||||
|
cd build
|
||||||
|
../configure
|
||||||
|
make
|
||||||
|
sudo make install
|
||||||
|
fi
|
||||||
|
|
||||||
|
cd $old_cwd
|
||||||
|
|
||||||
|
|
||||||
|
script:
|
||||||
|
- |
|
||||||
|
./configure
|
||||||
|
make all
|
|
@ -14,7 +14,6 @@
|
||||||
"C_Cpp.intelliSenseEngine": "Default",
|
"C_Cpp.intelliSenseEngine": "Default",
|
||||||
"files.insertFinalNewline": true,
|
"files.insertFinalNewline": true,
|
||||||
"files.associations": {
|
"files.associations": {
|
||||||
"*.h": "cpp",
|
|
||||||
"__functional_base": "cpp",
|
"__functional_base": "cpp",
|
||||||
"array": "cpp",
|
"array": "cpp",
|
||||||
"istream": "cpp",
|
"istream": "cpp",
|
||||||
|
@ -104,18 +103,6 @@
|
||||||
"version": "cpp",
|
"version": "cpp",
|
||||||
"shared_mutex": "cpp",
|
"shared_mutex": "cpp",
|
||||||
"compare": "cpp",
|
"compare": "cpp",
|
||||||
"concepts": "cpp",
|
"concepts": "cpp"
|
||||||
"__verbose_abort": "cpp",
|
|
||||||
"any": "cpp",
|
|
||||||
"charconv": "cpp",
|
|
||||||
"csignal": "cpp",
|
|
||||||
"execution": "cpp",
|
|
||||||
"numbers": "cpp",
|
|
||||||
"span": "cpp",
|
|
||||||
"unordered_set": "cpp",
|
|
||||||
"variant": "cpp",
|
|
||||||
"hash_map": "cpp",
|
|
||||||
"format": "cpp",
|
|
||||||
"*.inc": "cpp"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
22
Announce.txt
|
@ -9,7 +9,7 @@
|
||||||
SSSS ttt eeeee llll llll aaaaa
|
SSSS ttt eeeee llll llll aaaaa
|
||||||
|
|
||||||
===========================================================================
|
===========================================================================
|
||||||
Release 7.0 for Linux, macOS and Windows
|
Release 6.5.2 for Linux, macOS and Windows
|
||||||
===========================================================================
|
===========================================================================
|
||||||
|
|
||||||
The Atari 2600 Video Computer System (VCS), introduced in 1977, was the
|
The Atari 2600 Video Computer System (VCS), introduced in 1977, was the
|
||||||
|
@ -21,21 +21,25 @@ all of your favourite Atari 2600 games again! Stella was originally
|
||||||
developed for Linux by Bradford W. Mott, however, it has been ported to a
|
developed for Linux by Bradford W. Mott, however, it has been ported to a
|
||||||
number of other platforms and is currently maintained by Stephen Anthony.
|
number of other platforms and is currently maintained by Stephen Anthony.
|
||||||
|
|
||||||
This is the 7.0 release of Stella for Linux, macOS and Windows. The
|
This is the 6.5.2 release of Stella for Linux, macOS and Windows. The
|
||||||
distributions currently available are:
|
distributions currently available are:
|
||||||
|
|
||||||
* Binary for Windows 7/8/10/11 :
|
* Binaries for Windows 7/8/10 :
|
||||||
Stella-7.0-x64.exe (64-bit EXE installer)
|
Stella-6.5.2-win32.exe (32-bit EXE installer)
|
||||||
Stella-7.0-windows.zip (64 bit ZIP version)
|
Stella-6.5.2-x64.exe (64-bit EXE installer)
|
||||||
|
Stella-6.5.2-windows.zip (32/64 bit versions)
|
||||||
|
|
||||||
* Binary distribution for macOS 10.13 and above :
|
* Binary distribution for macOS 10.7 and above :
|
||||||
Stella-7.0-macos.dmg (ARM M1 and 64-bit Intel)
|
Stella-6.5.2-macos.dmg (64-bit Intel)
|
||||||
|
|
||||||
* Binary distribution for 64-bit Ubuntu :
|
* Binary distribution for 64-bit Ubuntu :
|
||||||
stella_7.0-1_amd64.deb
|
stella_6.5.2-1_amd64.deb
|
||||||
|
|
||||||
|
* Binary distribution for 64-bit Redhat :
|
||||||
|
stella-6.5.2-2.x86_64.rpm
|
||||||
|
|
||||||
* Source code distribution for all platforms :
|
* Source code distribution for all platforms :
|
||||||
stella-7.0-src.tar.xz
|
stella-6.5.2-src.tar.xz
|
||||||
|
|
||||||
|
|
||||||
Distribution Site
|
Distribution Site
|
||||||
|
|
200
Changes.txt
|
@ -12,204 +12,6 @@
|
||||||
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)
|
|
||||||
|
|
||||||
* Enhanced ROM launcher to allow multiple images per ROM.
|
|
||||||
|
|
||||||
* Made heaps of additional images available for the ROM launcher.
|
|
||||||
|
|
||||||
* Added searching by filename for ROM launcher images.
|
|
||||||
|
|
||||||
* Added option to start random ROM.
|
|
||||||
|
|
||||||
* Added automatically enabled phosphor modes.
|
|
||||||
|
|
||||||
* Enhanced Game Properties dialog for multigame ROMs.
|
|
||||||
|
|
||||||
* Added 2nd UI theme and hotkey for toggling UI theme.
|
|
||||||
|
|
||||||
* Added bezel support (incl. Sinden Lightgun).
|
|
||||||
|
|
||||||
* Added optional type format detection based on colors used.
|
|
||||||
|
|
||||||
* Added Joy2B+ controller support.
|
|
||||||
|
|
||||||
* Added auto detection for QuadTari attached controllers.
|
|
||||||
|
|
||||||
* Enhanced Kid Vid support to play tape audio.
|
|
||||||
|
|
||||||
* Added port selection, used for controller default mapping.
|
|
||||||
|
|
||||||
* Added missing PlusROM support for E7 bankswitching.
|
|
||||||
|
|
||||||
* Enhanced movie cart (MVC) support.
|
|
||||||
|
|
||||||
* Accelerated emulation up to ~15% (ARM).
|
|
||||||
|
|
||||||
* Added limited GameLine Master Module bankswitching support.
|
|
||||||
|
|
||||||
* Added 03E0 bankswitching for Brazilian Parker Bros ROMs.
|
|
||||||
|
|
||||||
* Added WF8 bankswitching used by some certain Coleco white carts.
|
|
||||||
|
|
||||||
* Added JANE bankswitching used by Coleco's Tarzan prototype.
|
|
||||||
|
|
||||||
* Added ELF mapper for Mattress Monkeys.
|
|
||||||
|
|
||||||
* Added BUS bankswitching support for some older demos.
|
|
||||||
|
|
||||||
* Fixed broken 7800 pause key support.
|
|
||||||
|
|
||||||
* Added developer option for random hotspot peek values.
|
|
||||||
|
|
||||||
* Added user defined CPU cycle timers to debugger.
|
|
||||||
|
|
||||||
* Removed 'launcherroms' option, since it was causing some issues.
|
|
||||||
|
|
||||||
* Codebase now uses C++20 features, which means a minimum of gcc-11
|
|
||||||
or clang-10 for Linux/Mac, and Visual Studio 2022 for Windows.
|
|
||||||
|
|
||||||
-Have fun!
|
|
||||||
|
|
||||||
|
|
||||||
6.7 to 6.7.1 (January 15, 2024)
|
|
||||||
|
|
||||||
* Fixed broken mouse and Stelladaptor input for Driving Controller.
|
|
||||||
|
|
||||||
* For UNIX systems: Now defaults to using system-installed libsqlite3
|
|
||||||
when available, and fixes delay on exiting app experienced on some
|
|
||||||
systems.
|
|
||||||
|
|
||||||
|
|
||||||
6.6 to 6.7 (June 13, 2022)
|
|
||||||
|
|
||||||
* IMPORTANT NOTES:
|
|
||||||
- Because of fixes to JSON handling, all remappings will be reset
|
|
||||||
to defaults; if you had custom mappings, they will need to be
|
|
||||||
re-entered again.
|
|
||||||
- Because of internal changes, all state files are now invalid.
|
|
||||||
|
|
||||||
* Completely reworked the file launcher:
|
|
||||||
- Redesigned user interface
|
|
||||||
- Added tracking of user favorites, recently played and most popular
|
|
||||||
games
|
|
||||||
- Added virtual directories for selecting tracked games
|
|
||||||
- Added quick path navigation
|
|
||||||
- Added navigation history
|
|
||||||
- Added icons for files and directories
|
|
||||||
- Added option to show/hide file extensions
|
|
||||||
- Extended context menu and shortcuts
|
|
||||||
- Fixed sluggish behaviour when reading large and/or invalid files
|
|
||||||
|
|
||||||
* Added hotkey display to tooltips.
|
|
||||||
|
|
||||||
* Added option to automatically pause emulation when focus is lost.
|
|
||||||
|
|
||||||
* Added option to toggle autofire mode.
|
|
||||||
|
|
||||||
* Improved controller mappings for Paddles.
|
|
||||||
|
|
||||||
* Improved controller mappings for Driving controllers.
|
|
||||||
|
|
||||||
* Improved Mindlink support.
|
|
||||||
|
|
||||||
* Added another oddball TIA glitch option for score mode color.
|
|
||||||
|
|
||||||
* Enhanced TV jitter emulation (TODO: doc).
|
|
||||||
|
|
||||||
* Enhanced support for CDFJ+ bankswitching type.
|
|
||||||
|
|
||||||
* Added 0FA0 bankswitching for Fotomania ROMs.
|
|
||||||
|
|
||||||
* Added ARM chip auto detection.
|
|
||||||
|
|
||||||
* Extended support for older BUS (experimental) ROMs that worked
|
|
||||||
with an older, obsolete version of the BUS scheme; special thanks
|
|
||||||
to SpiceWare for the code.
|
|
||||||
|
|
||||||
* Fixed Stella crash due to invalid ZIP files.
|
|
||||||
|
|
||||||
* Fixed TV mode auto detection in some ARM ROMs.
|
|
||||||
|
|
||||||
* Fixed color loss when switching TV mode from/to PAL.
|
|
||||||
|
|
||||||
* Fixed score mode glitch emulation corner case.
|
|
||||||
|
|
||||||
* Fixed state messages staying on screen forever.
|
|
||||||
|
|
||||||
* Added M1 support for the macOS build.
|
|
||||||
|
|
||||||
* Debugger improvements:
|
|
||||||
- added PlusROM information
|
|
||||||
- fixed patching code in ZP-RAM
|
|
||||||
- improved bank origin detection
|
|
||||||
|
|
||||||
* Updated internal ROM properties database to ROM-Hunter version 17
|
|
||||||
(thanks go to RomHunter for his tireless research in this area).
|
|
||||||
Related to this, updated the snapshot collection.
|
|
||||||
|
|
||||||
|
|
||||||
6.5.3 to 6.6 (November 16, 2021)
|
|
||||||
|
|
||||||
* Added preliminary PlusROM support for saving high scores.
|
|
||||||
|
|
||||||
* Added preliminary support for 'MVC' bankswitching scheme by
|
|
||||||
Rob Bairos.
|
|
||||||
|
|
||||||
* Added web links for many games.
|
|
||||||
|
|
||||||
* Added dead zone and linearity settings for analog controllers.
|
|
||||||
|
|
||||||
* Added 'Check for Update' button to Help dialog.
|
|
||||||
|
|
||||||
* Added different mask patterns for scanline emulation.
|
|
||||||
|
|
||||||
* Fixed MindLink controller.
|
|
||||||
|
|
||||||
* Fixed SaveKey not working with QuadTari.
|
|
||||||
|
|
||||||
* Added TIA randomization on startup option.
|
|
||||||
|
|
||||||
* Added different debug color luminances for player and missile copies.
|
|
||||||
|
|
||||||
* Added hotkeys for TV roll speed and toggling 'Developer settings' sets.
|
|
||||||
|
|
||||||
* Debugger: enhanced prompt's auto complete and history.
|
|
||||||
|
|
||||||
* Debugger: added optional logging of breaks and traps.
|
|
||||||
|
|
||||||
* Debugger: added Thumb cycle counting.
|
|
||||||
|
|
||||||
|
|
||||||
6.5.2 to 6.5.3 (April 20, 2021)
|
|
||||||
|
|
||||||
* Added context-sensitive help.
|
|
||||||
|
|
||||||
* Improved support of multiple monitors with different resolutions.
|
|
||||||
|
|
||||||
* Improved analog input reading (Paddles, Keyboards...).
|
|
||||||
|
|
||||||
* Fixed QuadTari support for controller types other than Joysticks.
|
|
||||||
|
|
||||||
* Fixed palette and TV effects saving for Retron77.
|
|
||||||
|
|
||||||
* Fixed immediate disassembling when switching options in debugger.
|
|
||||||
|
|
||||||
|
|
||||||
6.5.1 to 6.5.2 (February 25, 2021)
|
6.5.1 to 6.5.2 (February 25, 2021)
|
||||||
|
|
||||||
* Fixed broken Driving Controller support for Stelladaptor/2600-daptor
|
* Fixed broken Driving Controller support for Stelladaptor/2600-daptor
|
||||||
|
@ -221,6 +23,8 @@
|
||||||
|
|
||||||
* Added CPU usage stats to ARM cart classes debug widgets.
|
* Added CPU usage stats to ARM cart classes debug widgets.
|
||||||
|
|
||||||
|
-Have fun!
|
||||||
|
|
||||||
|
|
||||||
6.5 to 6.5.1 (January 24, 2021)
|
6.5 to 6.5.1 (January 24, 2021)
|
||||||
|
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
License Information and Copyright Notice
|
License Information and Copyright Notice
|
||||||
===========================================================================
|
===========================================================================
|
||||||
|
|
||||||
Copyright (c) 1995-2025 by Bradford W. Mott, Stephen Anthony and the
|
Copyright (c) 1995-2021 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
|
||||||
|
|
91
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-2025 by Bradford W. Mott, Stephen Anthony
|
## Copyright (c) 1995-2021 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
|
||||||
|
@ -26,7 +26,6 @@ LDFLAGS := -pthread
|
||||||
INCLUDES :=
|
INCLUDES :=
|
||||||
LIBS :=
|
LIBS :=
|
||||||
OBJS :=
|
OBJS :=
|
||||||
OBJS_TEST :=
|
|
||||||
PROF :=
|
PROF :=
|
||||||
|
|
||||||
MODULES :=
|
MODULES :=
|
||||||
|
@ -48,53 +47,28 @@ else
|
||||||
CFLAGS:= -O2
|
CFLAGS:= -O2
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifndef CXXFLAGS_TEST
|
|
||||||
CXXFLAGS_TEST := $(CXXFLAGS)
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifndef CFLAGS_TEST
|
|
||||||
CFLAGS_TEST := $(CFLAGS)
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifndef LDFLAGS_TEST
|
|
||||||
LDFLAGS_TEST := $(LDFLAGS)
|
|
||||||
endif
|
|
||||||
|
|
||||||
CXXFLAGS+= -Wall -Wextra -Wno-unused-parameter
|
CXXFLAGS+= -Wall -Wextra -Wno-unused-parameter
|
||||||
CFLAGS+= -Wall -Wextra -Wno-unused-parameter
|
CFLAGS+= -Wall -Wextra -Wno-unused-parameter
|
||||||
|
|
||||||
CXXFLAGS_TEST+= -Wall -Wextra -Wno-unused-parameter
|
|
||||||
CFLAGS_TEST+= -Wall -Wextra -Wno-unused-parameter
|
|
||||||
|
|
||||||
ifdef HAVE_GCC
|
ifdef HAVE_GCC
|
||||||
CXXFLAGS+= -Wno-multichar -Wunused -Woverloaded-virtual -std=c++20
|
CXXFLAGS+= -Wno-multichar -Wunused -Woverloaded-virtual -Wnon-virtual-dtor -std=c++17
|
||||||
CFLAGS+= -Wunused
|
CFLAGS+= -Wno-multichar -Wunused
|
||||||
|
|
||||||
CXXFLAGS_TEST+= -Wno-multichar -Wunused -Woverloaded-virtual -std=c++20
|
|
||||||
CFLAGS_TEST+= -Wno-multichar -Wunused
|
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifdef HAVE_CLANG
|
ifdef HAVE_CLANG
|
||||||
CXXFLAGS+= -Wunused -Woverloaded-virtual -std=c++20
|
CXXFLAGS+= -Wno-multichar -Wunused -Woverloaded-virtual -Wnon-virtual-dtor -std=c++17
|
||||||
CFLAGS+= -Wunused
|
CFLAGS+= -Wno-multichar -Wunused
|
||||||
|
|
||||||
CXXFLAGS_TEST+= -Wno-multichar -Wunused -Woverloaded-virtual -std=c++20
|
|
||||||
CFLAGS_TEST+= -Wno-multichar -Wunused
|
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifdef CLANG_WARNINGS
|
ifdef CLANG_WARNINGS
|
||||||
EXTRA_WARN=-Wno-c++98-compat-pedantic -Wno-undefined-func-template \
|
EXTRA_WARN=-Weverything -Wno-c++17-extensions -Wno-c++98-compat-pedantic \
|
||||||
-Wno-switch-enum -Wno-conversion -Wno-covered-switch-default \
|
-Wno-switch-enum -Wno-conversion -Wno-covered-switch-default \
|
||||||
-Wno-documentation -Wno-float-equal \
|
-Wno-inconsistent-missing-destructor-override -Wno-float-equal \
|
||||||
-Wno-exit-time-destructors -Wno-global-constructors -Wno-weak-vtables \
|
-Wno-exit-time-destructors -Wno-global-constructors -Wno-weak-vtables \
|
||||||
-Wno-four-char-constants -Wno-padded -Wno-reserved-identifier \
|
-Wno-four-char-constants -Wno-padded
|
||||||
-Wno-duplicate-enum -Wno-unsafe-buffer-usage
|
|
||||||
|
|
||||||
CXXFLAGS+= $(EXTRA_WARN)
|
CXXFLAGS+= $(EXTRA_WARN)
|
||||||
CFLAGS+= $(EXTRA_WARN)
|
CFLAGS+= $(EXTRA_WARN)
|
||||||
|
|
||||||
CXXFLAGS_TEST+= $(EXTRA_WARN)
|
|
||||||
CFLAGS_TEST+= $(EXTRA_WARN)
|
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifdef PROFILE
|
ifdef PROFILE
|
||||||
|
@ -104,8 +78,8 @@ ifdef PROFILE
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifdef DEBUG
|
ifdef DEBUG
|
||||||
CXXFLAGS += -g -Wp,-D_GLIBCXX_DEBUG
|
CXXFLAGS += -g
|
||||||
CFLAGS += -g -Wp,-D_GLIBCXX_DEBUG
|
CFLAGS += -g
|
||||||
else
|
else
|
||||||
ifdef HAVE_GCC
|
ifdef HAVE_GCC
|
||||||
CXXFLAGS+= -fomit-frame-pointer
|
CXXFLAGS+= -fomit-frame-pointer
|
||||||
|
@ -133,14 +107,12 @@ ifdef STELLA_BUILD_ROOT
|
||||||
else
|
else
|
||||||
OBJECT_ROOT := out
|
OBJECT_ROOT := out
|
||||||
endif
|
endif
|
||||||
OBJECT_ROOT_TEST := out.test
|
|
||||||
OBJECT_ROOT_PROFILE_GENERERATE := out.pgen
|
OBJECT_ROOT_PROFILE_GENERERATE := out.pgen
|
||||||
OBJECT_ROOT_PROFILE_USE := out.pgo
|
OBJECT_ROOT_PROFILE_USE := out.pgo
|
||||||
|
|
||||||
EXECUTABLE := stella$(EXEEXT)
|
EXECUTABLE := stella$(EXEEXT)
|
||||||
EXECUTABLE_PROFILE_GENERATE := stella-pgo-generate$(EXEEXT)
|
EXECUTABLE_PROFILE_GENERATE := stella-pgo-generate$(EXEEXT)
|
||||||
EXECUTABLE_PROFILE_USE := stella-pgo$(EXEEXT)
|
EXECUTABLE_PROFILE_USE := stella-pgo$(EXEEXT)
|
||||||
EXECUTABLE_TEST := stella-test$(EXEEXT)
|
|
||||||
|
|
||||||
PROFILE_DIR = $(CURDIR)/test/roms/profile
|
PROFILE_DIR = $(CURDIR)/test/roms/profile
|
||||||
PROFILE_OUT = $(PROFILE_DIR)/out
|
PROFILE_OUT = $(PROFILE_DIR)/out
|
||||||
|
@ -173,17 +145,14 @@ ifdef HAVE_GCC
|
||||||
CFLAGS_PROFILE_USE += -fprofile-use -fprofile-dir=$(PROFILE_OUT)
|
CFLAGS_PROFILE_USE += -fprofile-use -fprofile-dir=$(PROFILE_OUT)
|
||||||
LDFLAGS_PROFILE_GENERATE += -fprofile-generate
|
LDFLAGS_PROFILE_GENERATE += -fprofile-generate
|
||||||
STELLA_PROFILE_GENERATE := $(STELLA_PROFILE_GENERATE) && \
|
STELLA_PROFILE_GENERATE := $(STELLA_PROFILE_GENERATE) && \
|
||||||
(rm -fr $(PROFILE_OUT)/$(OBJECT_ROOT_PROFILE_USE) || true) && \
|
rm -fr $(PROFILE_OUT)/$(OBJECT_ROOT_PROFILE_USE) && \
|
||||||
(mv $(PROFILE_OUT)/$(OBJECT_ROOT_PROFILE_GENERERATE) $(PROFILE_OUT)/$(OBJECT_ROOT_PROFILE_USE) || true)
|
mv $(PROFILE_OUT)/$(OBJECT_ROOT_PROFILE_GENERERATE) $(PROFILE_OUT)/$(OBJECT_ROOT_PROFILE_USE)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
all: $(EXECUTABLE)
|
all: $(EXECUTABLE)
|
||||||
|
|
||||||
pgo: $(EXECUTABLE_PROFILE_USE)
|
pgo: $(EXECUTABLE_PROFILE_USE)
|
||||||
|
|
||||||
test: $(EXECUTABLE_TEST)
|
|
||||||
./$(EXECUTABLE_TEST)
|
|
||||||
|
|
||||||
######################################################################
|
######################################################################
|
||||||
# Various minor settings
|
# Various minor settings
|
||||||
######################################################################
|
######################################################################
|
||||||
|
@ -206,8 +175,8 @@ MODULES += \
|
||||||
src/emucore \
|
src/emucore \
|
||||||
src/emucore/tia \
|
src/emucore/tia \
|
||||||
src/emucore/tia/frame-manager \
|
src/emucore/tia/frame-manager \
|
||||||
src/emucore/elf \
|
src/common/repository/sqlite \
|
||||||
src/common/repository/sqlite
|
src/sqlite
|
||||||
|
|
||||||
######################################################################
|
######################################################################
|
||||||
# The build rules follow - normally you should have no need to
|
# The build rules follow - normally you should have no need to
|
||||||
|
@ -225,7 +194,6 @@ DEPDIRS = $(addsuffix /$(DEPDIR),$(MODULE_DIRS))
|
||||||
DEPFILES =
|
DEPFILES =
|
||||||
|
|
||||||
OBJ=$(addprefix $(OBJECT_ROOT)/,$(OBJS))
|
OBJ=$(addprefix $(OBJECT_ROOT)/,$(OBJS))
|
||||||
OBJ_TEST=$(addprefix $(OBJECT_ROOT_TEST)/,$(OBJS_TEST))
|
|
||||||
OBJ_PROFILE_GENERATE=$(addprefix $(OBJECT_ROOT_PROFILE_GENERERATE)/,$(OBJS))
|
OBJ_PROFILE_GENERATE=$(addprefix $(OBJECT_ROOT_PROFILE_GENERERATE)/,$(OBJS))
|
||||||
OBJ_PROFILE_USE=$(addprefix $(OBJECT_ROOT_PROFILE_USE)/,$(OBJS))
|
OBJ_PROFILE_USE=$(addprefix $(OBJECT_ROOT_PROFILE_USE)/,$(OBJS))
|
||||||
|
|
||||||
|
@ -233,9 +201,6 @@ OBJ_PROFILE_USE=$(addprefix $(OBJECT_ROOT_PROFILE_USE)/,$(OBJS))
|
||||||
$(EXECUTABLE): $(OBJ)
|
$(EXECUTABLE): $(OBJ)
|
||||||
$(LD) $(LDFLAGS) $(PRE_OBJS_FLAGS) $+ $(POST_OBJS_FLAGS) $(LIBS) $(PROF) -o $@
|
$(LD) $(LDFLAGS) $(PRE_OBJS_FLAGS) $+ $(POST_OBJS_FLAGS) $(LIBS) $(PROF) -o $@
|
||||||
|
|
||||||
$(EXECUTABLE_TEST): $(OBJ_TEST)
|
|
||||||
$(LD) $(LDFLAGS_TEST) $(PRE_OBJS_FLAGS) $+ $(POST_OBJS_FLAGS) $(LIBS) -lgtest -lgtest_main -o $@
|
|
||||||
|
|
||||||
$(EXECUTABLE_PROFILE_GENERATE): $(OBJ_PROFILE_GENERATE)
|
$(EXECUTABLE_PROFILE_GENERATE): $(OBJ_PROFILE_GENERATE)
|
||||||
$(LD) $(LDFLAGS_PROFILE_GENERATE) $(PRE_OBJS_FLAGS) $+ $(POST_OBJS_FLAGS) $(LIBS) $(PROF) -o $@
|
$(LD) $(LDFLAGS_PROFILE_GENERATE) $(PRE_OBJS_FLAGS) $+ $(POST_OBJS_FLAGS) $(LIBS) $(PROF) -o $@
|
||||||
|
|
||||||
|
@ -250,7 +215,7 @@ clean:
|
||||||
-$(RM) -fr \
|
-$(RM) -fr \
|
||||||
$(OBJECT_ROOT) $(OBJECT_ROOT_PROFILE_GENERERATE) $(OBJECT_ROOT_PROFILE_USE) \
|
$(OBJECT_ROOT) $(OBJECT_ROOT_PROFILE_GENERERATE) $(OBJECT_ROOT_PROFILE_USE) \
|
||||||
$(EXECUTABLE) $(EXECUTABLE_PROFILE_GENERATE) $(EXECUTABLE_PROFILE_USE) \
|
$(EXECUTABLE) $(EXECUTABLE_PROFILE_GENERATE) $(EXECUTABLE_PROFILE_USE) \
|
||||||
$(OBJECT_ROOT_TEST) $(PROFILE_OUT) $(PROFILE_STAMP)
|
$(PROFILE_OUT) $(PROFILE_STAMP)
|
||||||
|
|
||||||
.PHONY: all clean dist distclean
|
.PHONY: all clean dist distclean
|
||||||
|
|
||||||
|
@ -278,16 +243,6 @@ $(OBJECT_ROOT)/%.o: %.cxx
|
||||||
$(merge_dep)
|
$(merge_dep)
|
||||||
|
|
||||||
$(OBJECT_ROOT)/%.o: %.c
|
$(OBJECT_ROOT)/%.o: %.c
|
||||||
$(create_dir)
|
|
||||||
$(CC) $(CXX_UPDATE_DEP_FLAG) $(CFLAGS_TEST) $(CPPFLAGS) -c $(<) -o $@
|
|
||||||
$(merge_dep)
|
|
||||||
|
|
||||||
$(OBJECT_ROOT_TEST)/%.o: %.cxx
|
|
||||||
$(create_dir)
|
|
||||||
$(CXX) $(CXX_UPDATE_DEP_FLAG) $(CXXFLAGS_TEST) $(CPPFLAGS) -c $(<) -o $@
|
|
||||||
$(merge_dep)
|
|
||||||
|
|
||||||
$(OBJECT_ROOT_TEST)/%.o: %.c
|
|
||||||
$(create_dir)
|
$(create_dir)
|
||||||
$(CC) $(CXX_UPDATE_DEP_FLAG) $(CFLAGS) $(CPPFLAGS) -c $(<) -o $@
|
$(CC) $(CXX_UPDATE_DEP_FLAG) $(CFLAGS) $(CPPFLAGS) -c $(<) -o $@
|
||||||
$(merge_dep)
|
$(merge_dep)
|
||||||
|
@ -325,14 +280,6 @@ $(OBJECT_ROOT)/%.o: %.c
|
||||||
$(create_dir)
|
$(create_dir)
|
||||||
$(CC) $(CXX_UPDATE_DEP_FLAG) $(CFLAGS) $(CPPFLAGS) -c $(<) -o $@
|
$(CC) $(CXX_UPDATE_DEP_FLAG) $(CFLAGS) $(CPPFLAGS) -c $(<) -o $@
|
||||||
|
|
||||||
$(OBJECT_ROOT_TEST)/%.o: %.cxx
|
|
||||||
$(create_dir)
|
|
||||||
$(CXX) $(CXX_UPDATE_DEP_FLAG) $(CXXFLAGS_TEST) $(CPPFLAGS) -c $(<) -o $@
|
|
||||||
|
|
||||||
$(OBJECT_ROOT_TEST)/%.o: %.c
|
|
||||||
$(create_dir)
|
|
||||||
$(CC) $(CXX_UPDATE_DEP_FLAG) $(CFLAGS_TEST) $(CPPFLAGS) -c $(<) -o $@
|
|
||||||
|
|
||||||
$(OBJECT_ROOT_PROFILE_GENERERATE)/%.o: %.cxx
|
$(OBJECT_ROOT_PROFILE_GENERERATE)/%.o: %.cxx
|
||||||
$(create_dir)
|
$(create_dir)
|
||||||
$(CXX) $(CXX_UPDATE_DEP_FLAG) $(CXXFLAGS_PROFILE_GENERATE) $(CPPFLAGS) -c $(<) -o $@
|
$(CXX) $(CXX_UPDATE_DEP_FLAG) $(CXXFLAGS_PROFILE_GENERATE) $(CPPFLAGS) -c $(<) -o $@
|
||||||
|
@ -370,11 +317,11 @@ install: all
|
||||||
$(INSTALL) -d "$(DESTDIR)$(BINDIR)"
|
$(INSTALL) -d "$(DESTDIR)$(BINDIR)"
|
||||||
$(INSTALL) -c -m 755 "$(srcdir)/stella$(EXEEXT)" "$(DESTDIR)$(BINDIR)/stella$(EXEEXT)"
|
$(INSTALL) -c -m 755 "$(srcdir)/stella$(EXEEXT)" "$(DESTDIR)$(BINDIR)/stella$(EXEEXT)"
|
||||||
$(INSTALL) -d "$(DESTDIR)$(DOCDIR)"
|
$(INSTALL) -d "$(DESTDIR)$(DOCDIR)"
|
||||||
$(INSTALL) -c -m 644 "$(srcdir)/Announce.txt" "$(srcdir)/Changes.txt" "$(srcdir)/Copyright.txt" "$(srcdir)/License.txt" "$(srcdir)/README-SDL.txt" "$(srcdir)/README.md" "$(srcdir)/Todo.txt" "$(srcdir)/docs/index.html" "$(srcdir)/docs/debugger.html" "$(DESTDIR)$(DOCDIR)/"
|
$(INSTALL) -c -m 644 "$(srcdir)/Announce.txt" "$(srcdir)/Changes.txt" "$(srcdir)/Copyright.txt" "$(srcdir)/License.txt" "$(srcdir)/README-SDL.txt" "$(srcdir)/Readme.txt" "$(srcdir)/Todo.txt" "$(srcdir)/docs/index.html" "$(srcdir)/docs/debugger.html" "$(DESTDIR)$(DOCDIR)/"
|
||||||
$(INSTALL) -d "$(DESTDIR)$(DOCDIR)/graphics"
|
$(INSTALL) -d "$(DESTDIR)$(DOCDIR)/graphics"
|
||||||
$(INSTALL) -c -m 644 $(wildcard $(srcdir)/docs/graphics/*.png) "$(DESTDIR)$(DOCDIR)/graphics"
|
$(INSTALL) -c -m 644 $(wildcard $(srcdir)/docs/graphics/*.png) "$(DESTDIR)$(DOCDIR)/graphics"
|
||||||
$(INSTALL) -d "$(DESTDIR)$(DATADIR)/applications"
|
$(INSTALL) -d "$(DESTDIR)$(DATADIR)/applications"
|
||||||
$(INSTALL) -c -m 644 "$(srcdir)/src/os/unix/stella.desktop" "$(DESTDIR)$(DATADIR)/applications"
|
$(INSTALL) -c -m 644 "$(srcdir)/src/unix/stella.desktop" "$(DESTDIR)$(DATADIR)/applications"
|
||||||
$(INSTALL) -d "$(DESTDIR)$(DATADIR)/icons/hicolor/16x16/apps"
|
$(INSTALL) -d "$(DESTDIR)$(DATADIR)/icons/hicolor/16x16/apps"
|
||||||
$(INSTALL) -d "$(DESTDIR)$(DATADIR)/icons/hicolor/22x22/apps"
|
$(INSTALL) -d "$(DESTDIR)$(DATADIR)/icons/hicolor/22x22/apps"
|
||||||
$(INSTALL) -d "$(DESTDIR)$(DATADIR)/icons/hicolor/24x24/apps"
|
$(INSTALL) -d "$(DESTDIR)$(DATADIR)/icons/hicolor/24x24/apps"
|
||||||
|
@ -410,7 +357,7 @@ src/emucore/M6502.ins: src/emucore/M6502.m4
|
||||||
m4 src/emucore/M6502.m4 > src/emucore/M6502.ins
|
m4 src/emucore/M6502.m4 > src/emucore/M6502.ins
|
||||||
|
|
||||||
# Special rule for windows icon stuff (there's probably a better way to do this ...)
|
# Special rule for windows icon stuff (there's probably a better way to do this ...)
|
||||||
src/os/windows/stella_icon.o: src/os/windows/stella.ico src/os/windows/stella.rc
|
src/windows/stella_icon.o: src/windows/stella.ico src/windows/stella.rc
|
||||||
windres --include-dir src/os/windows src/os/windows/stella.rc src/os/windows/stella_icon.o
|
windres --include-dir src/windows src/windows/stella.rc src/windows/stella_icon.o
|
||||||
|
|
||||||
.PHONY: deb bundle test install uninstall
|
.PHONY: deb bundle test install uninstall
|
||||||
|
|
|
@ -15,10 +15,6 @@ Please check the list of known issues first (see below) before reporting new one
|
||||||
If you encounter any issues, please open a new issue on the project
|
If you encounter any issues, please open a new issue on the project
|
||||||
[issue tracker](https://github.com/stella-emu/stella/issues).
|
[issue tracker](https://github.com/stella-emu/stella/issues).
|
||||||
|
|
||||||
Note: Please do **not** report issues regarding platforms other than PC and RetroN 77
|
|
||||||
(e.g. Libretro) here. The Stella Team is not responsible for these forks and cannot
|
|
||||||
help with them.
|
|
||||||
|
|
||||||
# Known issues
|
# Known issues
|
||||||
|
|
||||||
Please check out the [issue tracker](https://github.com/stella-emu/stella/issues) for
|
Please check out the [issue tracker](https://github.com/stella-emu/stella/issues) for
|
||||||
|
|
|
@ -0,0 +1,10 @@
|
||||||
|
Stella is a multi-platform Atari 2600 VCS emulator which allows you to
|
||||||
|
play all of your favourite Atari 2600 games on your PC. You'll find the
|
||||||
|
Stella Users Manual in the docs subdirectory. If you'd like to verify
|
||||||
|
that you have the latest release of Stella, visit the Stella Website at:
|
||||||
|
|
||||||
|
https://stella-emu.github.io
|
||||||
|
|
||||||
|
Enjoy,
|
||||||
|
|
||||||
|
The Stella Team
|
|
@ -0,0 +1,32 @@
|
||||||
|
image: Visual Studio 2019
|
||||||
|
|
||||||
|
shallow_clone: true
|
||||||
|
|
||||||
|
|
||||||
|
environment:
|
||||||
|
matrix:
|
||||||
|
- Platform: x64
|
||||||
|
- Platform: Win32
|
||||||
|
|
||||||
|
Configuration: Release
|
||||||
|
|
||||||
|
SDL2_version: 2.0.12
|
||||||
|
|
||||||
|
|
||||||
|
install:
|
||||||
|
- cmd: |
|
||||||
|
curl -o "C:\SDL2-devel.zip" "https://www.libsdl.org/release/SDL2-devel-%SDL2_version%-VC.zip"
|
||||||
|
7z x "C:\SDL2-devel.zip" -o"C:\"
|
||||||
|
xcopy /S "C:\SDL2-%SDL2_version%\include" src\common
|
||||||
|
|
||||||
|
if %Platform%==x64 xcopy /S "C:\SDL2-%SDL2_version%\lib\x64" src\windows
|
||||||
|
if %Platform%==Win32 xcopy /S "C:\SDL2-%SDL2_version%\lib\x86" src\windows
|
||||||
|
|
||||||
|
|
||||||
|
build_script:
|
||||||
|
- cmd: |
|
||||||
|
msbuild src\windows\Stella.sln
|
||||||
|
|
||||||
|
|
||||||
|
artifacts:
|
||||||
|
- path: '**\stella.exe'
|
|
@ -4,9 +4,7 @@
|
||||||
# contains the module name, a trick we use so we can keep multiple different
|
# contains the module name, a trick we use so we can keep multiple different
|
||||||
# module object lists, one for each module.
|
# module object lists, one for each module.
|
||||||
MODULE_OBJS-$(MODULE) := $(MODULE_OBJS)
|
MODULE_OBJS-$(MODULE) := $(MODULE_OBJS)
|
||||||
MODULE_TEST_OBJS-$(MODULE) := $(MODULE_TEST_OBJS)
|
|
||||||
|
|
||||||
# If not building as a plugin, add the object files to the main OBJS list
|
# If not building as a plugin, add the object files to the main OBJS list
|
||||||
#OBJS += $(MODULE_LIB-$(MODULE))
|
#OBJS += $(MODULE_LIB-$(MODULE))
|
||||||
OBJS += $(MODULE_OBJS)
|
OBJS += $(MODULE_OBJS)
|
||||||
OBJS_TEST += $(MODULE_TEST_OBJS)
|
|
||||||
|
|
|
@ -6,23 +6,13 @@
|
||||||
# * 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
|
# * detect whether the chosen backend is available (e.g. call sdl2-config)
|
||||||
# * ....
|
# * ....
|
||||||
|
|
||||||
|
|
||||||
# use environment vars if set
|
# use environment vars if set
|
||||||
CXXFLAGS="$CXXFLAGS $CPPFLAGS"
|
CXXFLAGS="$CXXFLAGS $CPPFLAGS"
|
||||||
|
|
||||||
if test -n "$CXXFLAGS_TEST"; then
|
|
||||||
CXXFLAGS_TEST="$CXXFLAGS_TEST $CPPFLAGS"
|
|
||||||
else
|
|
||||||
CXXFLAGS_TEST="$CXXFLAGS"
|
|
||||||
fi
|
|
||||||
|
|
||||||
if test -z "$LDFLAGS_TEST"; then
|
|
||||||
LDFLAGS_TEST="$LDFLAGS"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# default option behaviour yes/no
|
# default option behaviour yes/no
|
||||||
_build_gui=yes
|
_build_gui=yes
|
||||||
_build_windowed=yes
|
_build_windowed=yes
|
||||||
|
@ -30,22 +20,18 @@ _build_sound=yes
|
||||||
_build_debugger=yes
|
_build_debugger=yes
|
||||||
_build_joystick=yes
|
_build_joystick=yes
|
||||||
_build_cheats=yes
|
_build_cheats=yes
|
||||||
_build_httplib=yes
|
|
||||||
_build_png=yes
|
_build_png=yes
|
||||||
_build_sqlite3=yes
|
|
||||||
_build_zip=yes
|
_build_zip=yes
|
||||||
_build_static=no
|
_build_static=no
|
||||||
_build_profile=no
|
_build_profile=no
|
||||||
_build_debug=no
|
_build_debug=no
|
||||||
_build_release=no
|
_build_release=no
|
||||||
_build_mold=no
|
|
||||||
|
|
||||||
# more defaults
|
# more defaults
|
||||||
_ranlib=ranlib
|
_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
|
||||||
|
@ -54,6 +40,7 @@ _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
|
||||||
|
|
||||||
|
@ -227,15 +214,11 @@ Optional Features:
|
||||||
--disable-profile
|
--disable-profile
|
||||||
--enable-debug build with debugging symbols [disabled]
|
--enable-debug build with debugging symbols [disabled]
|
||||||
--disable-debug
|
--disable-debug
|
||||||
--enable-release build with all optimizations, for final release [disabled]
|
|
||||||
--disable-release
|
|
||||||
--use-mold-linker use mold linker (experimental) [disabled]
|
|
||||||
|
|
||||||
Optional Libraries:
|
Optional Libraries:
|
||||||
--with-sdl-prefix=DIR Prefix where the sdl2-config script is installed (optional)
|
--with-sdl-prefix=DIR Prefix where the sdl2-config script is installed (optional)
|
||||||
--with-libpng-prefix=DIR Prefix where libpng is installed (optional)
|
--with-libpng-prefix=DIR Prefix where libpng is installed (optional)
|
||||||
--with-zlib-prefix=DIR Prefix where zlib is installed (optional)
|
--with-zlib-prefix=DIR Prefix where zlib is installed (optional)
|
||||||
--with-gtest-prefix=DIR Prefix where googletest is installed (optional)
|
|
||||||
|
|
||||||
Some influential environment variables:
|
Some influential environment variables:
|
||||||
LDFLAGS linker flags, e.g. -L<lib dir> if you have libraries in a
|
LDFLAGS linker flags, e.g. -L<lib dir> if you have libraries in a
|
||||||
|
@ -244,8 +227,6 @@ Some influential environment variables:
|
||||||
CXXFLAGS C++ compiler flags
|
CXXFLAGS C++ compiler flags
|
||||||
CPPFLAGS C++ preprocessor flags, e.g. -I<include dir> if you have
|
CPPFLAGS C++ preprocessor flags, e.g. -I<include dir> if you have
|
||||||
headers in a nonstandard directory <include dir>
|
headers in a nonstandard directory <include dir>
|
||||||
LDFLAGS_TEST linker flags for unit tests
|
|
||||||
CXXFLAGS_TEST C++ compiler flags for unit tests
|
|
||||||
|
|
||||||
EOF
|
EOF
|
||||||
exit 0
|
exit 0
|
||||||
|
@ -279,7 +260,6 @@ for ac_option in $@; do
|
||||||
--disable-debug) _build_debug=no ;;
|
--disable-debug) _build_debug=no ;;
|
||||||
--enable-release) _build_release=yes ;;
|
--enable-release) _build_release=yes ;;
|
||||||
--disable-release) _build_release=no ;;
|
--disable-release) _build_release=no ;;
|
||||||
--use-mold-linker) _build_mold=yes ;;
|
|
||||||
--with-sdl-prefix=*)
|
--with-sdl-prefix=*)
|
||||||
arg=`echo $ac_option | cut -d '=' -f 2`
|
arg=`echo $ac_option | cut -d '=' -f 2`
|
||||||
_sdlpath="$arg:$arg/bin"
|
_sdlpath="$arg:$arg/bin"
|
||||||
|
@ -293,11 +273,6 @@ for ac_option in $@; do
|
||||||
_prefix=`echo $ac_option | cut -d '=' -f 2`
|
_prefix=`echo $ac_option | cut -d '=' -f 2`
|
||||||
ZLIB_CFLAGS="-I$_prefix/include"
|
ZLIB_CFLAGS="-I$_prefix/include"
|
||||||
ZLIB_LIBS="-L$_prefix/lib"
|
ZLIB_LIBS="-L$_prefix/lib"
|
||||||
;;
|
|
||||||
--with-gtest-prefix=*)
|
|
||||||
_prefix=`echo $ac_option | cut -d '=' -f 2`
|
|
||||||
CXXFLAGS_TEST="$CXXFLAGS_TEST -I$_prefix/include"
|
|
||||||
LDFLAGS_TEST="$LDFLAGS_TEST -L$_prefix/lib"
|
|
||||||
;;
|
;;
|
||||||
--host=*)
|
--host=*)
|
||||||
_host=`echo $ac_option | cut -d '=' -f 2`
|
_host=`echo $ac_option | cut -d '=' -f 2`
|
||||||
|
@ -335,22 +310,20 @@ 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
|
||||||
|
|
||||||
#
|
#
|
||||||
|
@ -366,6 +339,9 @@ arm-riscos-aof)
|
||||||
psp)
|
psp)
|
||||||
EXEEXT=".elf"
|
EXEEXT=".elf"
|
||||||
;;
|
;;
|
||||||
|
gp2x)
|
||||||
|
EXEEXT=""
|
||||||
|
;;
|
||||||
*)
|
*)
|
||||||
EXEEXT=""
|
EXEEXT=""
|
||||||
;;
|
;;
|
||||||
|
@ -398,7 +374,7 @@ else
|
||||||
fi
|
fi
|
||||||
|
|
||||||
for compiler in $compilers; do
|
for compiler in $compilers; do
|
||||||
if test_compiler "$compiler -std=c++20"; then
|
if test_compiler "$compiler -std=c++17"; then
|
||||||
CXX=$compiler
|
CXX=$compiler
|
||||||
echo $CXX
|
echo $CXX
|
||||||
break
|
break
|
||||||
|
@ -555,6 +531,13 @@ 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
|
||||||
|
;;
|
||||||
mingw32-cross)
|
mingw32-cross)
|
||||||
echo "Cross-compiling for Windows using MinGW."
|
echo "Cross-compiling for Windows using MinGW."
|
||||||
DEFINES="$DEFINES -DWIN32"
|
DEFINES="$DEFINES -DWIN32"
|
||||||
|
@ -620,9 +603,6 @@ 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
|
||||||
|
|
||||||
#
|
#
|
||||||
|
@ -636,7 +616,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 -lz && _zlib=yes
|
||||||
|
|
||||||
if test "$_zlib" = yes ; then
|
if test "$_zlib" = yes ; then
|
||||||
echo "$_zlib"
|
echo "$_zlib"
|
||||||
|
@ -662,7 +642,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"
|
||||||
|
@ -675,30 +655,6 @@ else
|
||||||
_build_png=no
|
_build_png=no
|
||||||
fi
|
fi
|
||||||
|
|
||||||
#
|
|
||||||
# Check for sqlite3
|
|
||||||
#
|
|
||||||
echocheck "libsqlite3"
|
|
||||||
if test "$_build_sqlite3" = yes ; then
|
|
||||||
_libsqlite3=no
|
|
||||||
cat > $TMPC << EOF
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <sqlite3.h>
|
|
||||||
int main(void) { return printf("%s\n", SQLITE_VERSION); }
|
|
||||||
EOF
|
|
||||||
cc_check $LDFLAGS $CXXFLAGS `$_pkg_config --libs sqlite3` && _libsqlite3=yes
|
|
||||||
|
|
||||||
if test "$_libsqlite3" = yes ; then
|
|
||||||
echo "$_libsqlite3"
|
|
||||||
else
|
|
||||||
echo "built-in"
|
|
||||||
_build_sqlite3=yes
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
echo "built-in"
|
|
||||||
_build_sqlite3=yes
|
|
||||||
fi
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# figure out installation directories
|
# figure out installation directories
|
||||||
#
|
#
|
||||||
|
@ -805,70 +761,62 @@ 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_LIB="$SRC/lib"
|
|
||||||
CORE="$SRC/emucore"
|
CORE="$SRC/emucore"
|
||||||
COMMON="$SRC/common"
|
COMMON="$SRC/common"
|
||||||
TIA="$SRC/emucore/tia"
|
TIA="$SRC/emucore/tia"
|
||||||
ELF="$SRC/emucore/elf"
|
|
||||||
TIA_FRAME_MANAGER="$SRC/emucore/tia/frame-manager"
|
TIA_FRAME_MANAGER="$SRC/emucore/tia/frame-manager"
|
||||||
TV="$SRC/common/tv_filters"
|
TV="$SRC/common/tv_filters"
|
||||||
GUI="$SRC/gui"
|
GUI="$SRC/gui"
|
||||||
DBG="$SRC/debugger"
|
DBG="$SRC/debugger"
|
||||||
DBGGUI="$SRC/debugger/gui"
|
DBGGUI="$SRC/debugger/gui"
|
||||||
YACC="$SRC/debugger/yacc"
|
YACC="$SRC/yacc"
|
||||||
CHEAT="$SRC/cheat"
|
CHEAT="$SRC/cheat"
|
||||||
LIBPNG="$SRC_LIB/libpng"
|
LIBPNG="$SRC/libpng"
|
||||||
LIBJPG="$SRC_LIB/nanojpeg"
|
ZLIB="$SRC/zlib"
|
||||||
LIBJPGEXIF="$SRC_LIB/tinyexif"
|
|
||||||
ZLIB="$SRC_LIB/zlib"
|
|
||||||
SQLITE_REPO="$SRC/common/repository/sqlite"
|
SQLITE_REPO="$SRC/common/repository/sqlite"
|
||||||
SQLITE_LIB="$SRC_LIB/sqlite"
|
SQLITE_LIB="$SRC/sqlite"
|
||||||
JSON="$SRC_LIB/json"
|
JSON="$SRC/json"
|
||||||
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$JSON -I$SQLITE_REPO -I$SQLITE_LIB"
|
||||||
|
|
||||||
#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
|
||||||
unix)
|
unix)
|
||||||
DEFINES="$DEFINES -DBSPF_UNIX"
|
DEFINES="$DEFINES -DBSPF_UNIX"
|
||||||
MODULES="$MODULES $SRC_OS/unix"
|
MODULES="$MODULES $SRC/unix"
|
||||||
INCLUDES="$INCLUDES -I$SRC_OS/unix"
|
INCLUDES="$INCLUDES -I$SRC/unix"
|
||||||
;;
|
;;
|
||||||
darwin)
|
darwin)
|
||||||
DEFINES="$DEFINES -DBSPF_UNIX -DMACOS_KEYS"
|
DEFINES="$DEFINES -DBSPF_UNIX -DMACOS_KEYS"
|
||||||
MODULES="$MODULES $SRC_OS/unix"
|
MODULES="$MODULES $SRC/unix"
|
||||||
INCLUDES="$INCLUDES -I$SRC_OS/unix"
|
INCLUDES="$INCLUDES -I$SRC/unix"
|
||||||
if test "$have_clang" == yes; then
|
if test "$have_clang" == yes; then
|
||||||
CXXFLAGS="$CXXFLAGS -Wno-poison-system-directories"
|
CXXFLAGS="$CXXFLAGS -Wno-poison-system-directories"
|
||||||
if test -n "$CXXFLAGS_TEST"; then
|
|
||||||
CXXFLAGS_TEST="$CXXFLAGS_TEST -Wno-poison-system-directories"
|
|
||||||
fi
|
|
||||||
fi
|
fi
|
||||||
_libsqlite3=no
|
|
||||||
;;
|
;;
|
||||||
|
retron77)
|
||||||
|
DEFINES="$DEFINES -DBSPF_UNIX -DRETRON77"
|
||||||
|
MODULES="$MODULES $SRC/unix $SRC/unix/r77"
|
||||||
|
INCLUDES="$INCLUDES -I$SRC/unix -I$SRC/unix/r77"
|
||||||
|
;;
|
||||||
win32)
|
win32)
|
||||||
DEFINES="$DEFINES -DBSPF_WINDOWS"
|
DEFINES="$DEFINES -DBSPF_WINDOWS"
|
||||||
MODULES="$MODULES $SRC_OS/windows"
|
MODULES="$MODULES $SRC/windows"
|
||||||
INCLUDES="$INCLUDES -I$SRC_OS/windows"
|
INCLUDES="$INCLUDES -I$SRC/windows"
|
||||||
LIBS="$LIBS -lmingw32 -lwinmm"
|
LIBS="$LIBS -lmingw32 -lwinmm"
|
||||||
;;
|
;;
|
||||||
*)
|
*)
|
||||||
|
@ -907,34 +855,20 @@ if test "$_build_cheats" = yes ; then
|
||||||
INCLUDES="$INCLUDES -I$CHEAT"
|
INCLUDES="$INCLUDES -I$CHEAT"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if test "$_build_httplib" = yes ; then
|
|
||||||
DEFINES="$DEFINES -DHTTP_LIB_SUPPORT"
|
|
||||||
INCLUDES="$INCLUDES -I$HTTP_LIB"
|
|
||||||
fi
|
|
||||||
|
|
||||||
if test "$_build_png" = yes ; then
|
if test "$_build_png" = yes ; then
|
||||||
DEFINES="$DEFINES -DIMAGE_SUPPORT"
|
DEFINES="$DEFINES -DPNG_SUPPORT"
|
||||||
INCLUDES="$INCLUDES -I$LIBJPG -I$LIBJPGEXIF"
|
|
||||||
MODULES="$MODULES $LIBJPGEXIF"
|
|
||||||
if test "$_libpng" = yes ; then
|
if test "$_libpng" = yes ; then
|
||||||
LIBS="$LIBS `$_pkg_config --libs libpng`"
|
LIBS="$LIBS -lpng"
|
||||||
else
|
else
|
||||||
MODULES="$MODULES $LIBPNG"
|
MODULES="$MODULES $LIBPNG"
|
||||||
INCLUDES="$INCLUDES -I$LIBPNG"
|
INCLUDES="$INCLUDES -I$LIBPNG"
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if test "$_libsqlite3" = yes ; then
|
|
||||||
LIBS="$LIBS `$_pkg_config --libs sqlite3`"
|
|
||||||
else
|
|
||||||
MODULES="$MODULES $SQLITE_LIB"
|
|
||||||
INCLUDES="$INCLUDES -I$SQLITE_LIB"
|
|
||||||
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 -lz"
|
||||||
else
|
else
|
||||||
MODULES="$MODULES $ZLIB"
|
MODULES="$MODULES $ZLIB"
|
||||||
INCLUDES="$INCLUDES -I$ZLIB"
|
INCLUDES="$INCLUDES -I$ZLIB"
|
||||||
|
@ -953,24 +887,12 @@ if test "$_build_release" = no ; then
|
||||||
_build_release=
|
_build_release=
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if test "$_build_mold" = yes ; then
|
|
||||||
LDFLAGS="-fuse-ld=mold"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Workaround until we deal with autodetection of C compiler properly
|
|
||||||
# Or we remove C files from Stella entirely, by making them C++
|
|
||||||
if test -z "$CC"; then
|
|
||||||
CC=cc
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo "Creating config.mak"
|
echo "Creating config.mak"
|
||||||
cat > config.mak << EOF
|
cat > config.mak << EOF
|
||||||
# -------- Generated by configure -----------
|
# -------- Generated by configure -----------
|
||||||
|
|
||||||
CC := $CC
|
|
||||||
CXX := $CXX
|
CXX := $CXX
|
||||||
CXXFLAGS := $CXXFLAGS
|
CXXFLAGS := $CXXFLAGS
|
||||||
CXXFLAGS_TEST := $CXXFLAGS_TEST
|
|
||||||
LD := $LD
|
LD := $LD
|
||||||
LIBS += $LIBS
|
LIBS += $LIBS
|
||||||
RANLIB := $_ranlib
|
RANLIB := $_ranlib
|
||||||
|
@ -1008,7 +930,6 @@ INCLUDES += $INCLUDES
|
||||||
OBJS += $OBJS
|
OBJS += $OBJS
|
||||||
DEFINES += $DEFINES
|
DEFINES += $DEFINES
|
||||||
LDFLAGS += $LDFLAGS
|
LDFLAGS += $LDFLAGS
|
||||||
LDFLAGS_TEST += $LDFLAGS_TEST
|
|
||||||
$_config_mk_data
|
$_config_mk_data
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
|
|
|
@ -1,31 +1,3 @@
|
||||||
stella (7.0) stable; urgency=high
|
|
||||||
|
|
||||||
* Version 7.0 release
|
|
||||||
|
|
||||||
-- Stephen Anthony <sa666666@gmail.com> Sat, 5 Oct 2024 17:09:59 -0230
|
|
||||||
|
|
||||||
|
|
||||||
stella (6.7) stable; urgency=high
|
|
||||||
|
|
||||||
* Version 6.7 release
|
|
||||||
|
|
||||||
-- Stephen Anthony <sa666666@gmail.com> Mon, 13 Jun 2022 17:09:59 -0230
|
|
||||||
|
|
||||||
|
|
||||||
stella (6.6) stable; urgency=high
|
|
||||||
|
|
||||||
* Version 6.6 release
|
|
||||||
|
|
||||||
-- Stephen Anthony <sa666666@gmail.com> Tue, 16 Nov 2021 17:09:59 -0230
|
|
||||||
|
|
||||||
|
|
||||||
stella (6.5.3) stable; urgency=high
|
|
||||||
|
|
||||||
* Version 6.5.3 release
|
|
||||||
|
|
||||||
-- Stephen Anthony <sa666666@gmail.com> Tue, 20 Apr 2021 17:09:59 -0230
|
|
||||||
|
|
||||||
|
|
||||||
stella (6.5.2) stable; urgency=high
|
stella (6.5.2) stable; urgency=high
|
||||||
|
|
||||||
* Version 6.5.2 release
|
* Version 6.5.2 release
|
||||||
|
|
|
@ -3,9 +3,8 @@ 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,
|
||||||
libsdl3-dev,
|
libsdl2-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/
|
||||||
|
@ -19,7 +18,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 SDL
|
Description: Atari 2600 Emulator for SDL2
|
||||||
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-2025 Bradford W. Mott, Stephen Anthony and the Stella Team
|
Copyright: 1995-2021 Bradford W. Mott, Stephen Anthony and the Stella Team
|
||||||
License: GPL-2+
|
License: GPL-2+
|
||||||
|
|
||||||
Files: *
|
Files: *
|
||||||
Copyright: 1995-2025 Bradford W. Mott, Stephen Anthony and the Stella
|
Copyright: 1995-2021 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-2025 Stephen Kitt <skitt@debian.org>
|
2010-2021 Stephen Kitt <skitt@debian.org>
|
||||||
License: GPL-2+
|
License: GPL-2+
|
||||||
|
|
||||||
Files:
|
Files:
|
||||||
|
@ -73,7 +73,7 @@ License: RSA
|
||||||
These notices must be retained in any copies of any part of this
|
These notices must be retained in any copies of any part of this
|
||||||
documentation and/or software.
|
documentation and/or software.
|
||||||
|
|
||||||
Files: src/lib/libpng/*
|
Files: src/libpng/*
|
||||||
Copyright: 1995-1996 Guy Eric Schalnat, Group 42, Inc.
|
Copyright: 1995-1996 Guy Eric Schalnat, Group 42, Inc.
|
||||||
1996-1997 Andreas Dilger
|
1996-1997 Andreas Dilger
|
||||||
1998-2013 Glenn Randers-Pehrson
|
1998-2013 Glenn Randers-Pehrson
|
||||||
|
@ -112,7 +112,7 @@ License: libpng
|
||||||
risk of satisfactory quality, performance, accuracy, and effort is
|
risk of satisfactory quality, performance, accuracy, and effort is
|
||||||
with the user.
|
with the user.
|
||||||
|
|
||||||
Files: src/os/libretro/libretro.h
|
Files: src/libretro/libretro.h
|
||||||
Copyright: 2010-2017 The RetroArch team
|
Copyright: 2010-2017 The RetroArch team
|
||||||
License: MIT
|
License: MIT
|
||||||
Permission is hereby granted, free of charge, to any person obtaining
|
Permission is hereby granted, free of charge, to any person obtaining
|
||||||
|
@ -135,7 +135,7 @@ License: MIT
|
||||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
SOFTWARE.
|
SOFTWARE.
|
||||||
|
|
||||||
Files: src/os/macos/*
|
Files: src/macos/*
|
||||||
Copyright: 2005-2006 Mark Grebe
|
Copyright: 2005-2006 Mark Grebe
|
||||||
License: GPL-2+
|
License: GPL-2+
|
||||||
|
|
||||||
|
@ -164,7 +164,7 @@ License: GPL-2
|
||||||
License version 2 can be found in
|
License version 2 can be found in
|
||||||
`/usr/share/common-licenses/GPL-2'.
|
`/usr/share/common-licenses/GPL-2'.
|
||||||
|
|
||||||
Files: src/lib/zlib/*
|
Files: src/zlib/*
|
||||||
Copyright: 1995-2012, 2016 Jean-loup Gailly and Mark Adler
|
Copyright: 1995-2012, 2016 Jean-loup Gailly and Mark Adler
|
||||||
License: zlib
|
License: zlib
|
||||||
This software is provided 'as-is', without any express or implied
|
This software is provided 'as-is', without any express or implied
|
||||||
|
|
|
@ -2,7 +2,7 @@ Announce.txt
|
||||||
Changes.txt
|
Changes.txt
|
||||||
Copyright.txt
|
Copyright.txt
|
||||||
README-SDL.txt
|
README-SDL.txt
|
||||||
README.md
|
Readme.txt
|
||||||
docs/*.html
|
docs/*.html
|
||||||
docs/graphics/*.png
|
doc/graphics/*.png
|
||||||
Todo.txt
|
Todo.txt
|
||||||
|
|
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 |
|
@ -15,7 +15,7 @@
|
||||||
<body>
|
<body>
|
||||||
|
|
||||||
<center><b><font size="7">Stella</font></b></center>
|
<center><b><font size="7">Stella</font></b></center>
|
||||||
<center><h4><b>Release 7.0</b></h4></center>
|
<center><h4><b>Release 6.5.2</b></h4></center>
|
||||||
<center><h1><b>Integrated Debugger</b></h1></center>
|
<center><h1><b>Integrated Debugger</b></h1></center>
|
||||||
<center><h4><b>(a work in progress)</b></h4></center>
|
<center><h4><b>(a work in progress)</b></h4></center>
|
||||||
<br>
|
<br>
|
||||||
|
@ -45,7 +45,6 @@
|
||||||
<li><a href="#PseudoRegisters">Pseudo-Registers</a></li>
|
<li><a href="#PseudoRegisters">Pseudo-Registers</a></li>
|
||||||
<li><a href="#Watches">Watches</a></li>
|
<li><a href="#Watches">Watches</a></li>
|
||||||
<li><a href="#Traps">Traps</a></li>
|
<li><a href="#Traps">Traps</a></li>
|
||||||
<li><a href="#Timers">Timers</a></li>
|
|
||||||
</ul>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
<li><a href="#SaveWork">Save your work!</a></li>
|
<li><a href="#SaveWork">Save your work!</a></li>
|
||||||
|
@ -103,10 +102,10 @@ feature that no other 2600 debugger has; it's <b>completely</b> cross-platform.<
|
||||||
breakpoints as you want.</li>
|
breakpoints as you want.</li>
|
||||||
|
|
||||||
<li>Conditional breakpoints - Break running program when some arbitrary
|
<li>Conditional breakpoints - Break running program when some arbitrary
|
||||||
condition is true (e.g. "breakIf {a == $7f && c}" will break when the Accumulator value is $7f and the Carry flag is true, no matter where
|
condition is true (e.g. "breakif {a == $7f && c}" will break when the Accumulator value is $7f and the Carry flag is true, no matter where
|
||||||
in the program this happens). Unlike the cond breaks in PCAE, Stella's
|
in the program this happens). Unlike the cond breaks in PCAE, Stella's
|
||||||
are *fast*: the emulation will run at full speed unless you use lots
|
are *fast*: the emulation will run at full speed unless you use lots
|
||||||
of breakIf's at the same time, or have a slow CPU.</li>
|
of breakif's at the same time, or have a slow CPU.</li>
|
||||||
|
|
||||||
<li>Watches - View contents of a location/register before every
|
<li>Watches - View contents of a location/register before every
|
||||||
debugger prompt.</li>
|
debugger prompt.</li>
|
||||||
|
@ -173,7 +172,7 @@ feature that no other 2600 debugger has; it's <b>completely</b> cross-platform.<
|
||||||
<li>Data sources for the CPU SP/A/X/Y registers, showing the resolved/source
|
<li>Data sources for the CPU SP/A/X/Y registers, showing the resolved/source
|
||||||
address of of load operands.</li>
|
address of of load operands.</li>
|
||||||
<li>Scanline advance (like frame advance, break at beginning
|
<li>Scanline advance (like frame advance, break at beginning
|
||||||
of next scanLine).</li>
|
of next scanline).</li>
|
||||||
<li>TIA display is updated during step/trace, so we can see our
|
<li>TIA display is updated during step/trace, so we can see our
|
||||||
scanlines being drawn as it happens. This isn't 100% perfect: unlike
|
scanlines being drawn as it happens. This isn't 100% perfect: unlike
|
||||||
a real TIA, the one in Stella only updates when it's written to.</li>
|
a real TIA, the one in Stella only updates when it's written to.</li>
|
||||||
|
@ -184,7 +183,7 @@ feature that no other 2600 debugger has; it's <b>completely</b> cross-platform.<
|
||||||
named after the ROM image.</li>
|
named after the ROM image.</li>
|
||||||
<li>Saving the current debugger state to a script file (including
|
<li>Saving the current debugger state to a script file (including
|
||||||
breakpoints, traps, etc).</li>
|
breakpoints, traps, etc).</li>
|
||||||
<li>Built-in functions for use with "breakIf", to support common conditions
|
<li>Built-in functions for use with "breakif", to support common conditions
|
||||||
(such as breaking when the user presses Game Select...)</li>
|
(such as breaking when the user presses Game Select...)</li>
|
||||||
<li>Patching ROM in-place.</li>
|
<li>Patching ROM in-place.</li>
|
||||||
<li>Save patched ROM</li>
|
<li>Save patched ROM</li>
|
||||||
|
@ -252,9 +251,9 @@ command on the command line, or alternatively within the ROM launcher in
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p>Using the ` key will always enter the debugger at the end of
|
<p>Using the ` key will always enter the debugger at the end of
|
||||||
the frame (for NTSC games usually scanLine 262). This is because Stella only checks
|
the frame (for NTSC games usually scanline 262). This is because Stella only checks
|
||||||
for keystrokes once per frame. Once in the debugger, you can control
|
for keystrokes once per frame. Once in the debugger, you can control
|
||||||
execution by stepping one instruction, scanLine, or frame at a time
|
execution by stepping one instruction, scanline, or frame at a time
|
||||||
(or more than one at a time, using commands in the prompt). You can
|
(or more than one at a time, using commands in the prompt). You can
|
||||||
also set breakpoints or traps, which will cause the emulator to enter
|
also set breakpoints or traps, which will cause the emulator to enter
|
||||||
the debugger when they are triggered, even if it happens in mid-frame.</p>
|
the debugger when they are triggered, even if it happens in mid-frame.</p>
|
||||||
|
@ -311,7 +310,7 @@ more convenient.
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
"<rom_filename>.sym" (located in the same directory as the ROM)</br>
|
"<rom_filename>.sym" (located in the same directory as the ROM)</br>
|
||||||
If you provide the -l and -s parameters DASM will create these two files during
|
If you provied the -l and -s parameters DASM will create these two files during
|
||||||
assembly. Stella uses the file content to display the correct labels.
|
assembly. Stella uses the file content to display the correct labels.
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
@ -346,57 +345,56 @@ size can be configured e.g. in the
|
||||||
<p>
|
<p>
|
||||||
<table BORDER=1 cellpadding=4>
|
<table BORDER=1 cellpadding=4>
|
||||||
<tr>
|
<tr>
|
||||||
<th>Function</th>
|
|
||||||
<th>Key</th>
|
<th>Key</th>
|
||||||
|
<th>Function</th>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>Step ¹</td>
|
|
||||||
<td>Control + S</td>
|
<td>Control + S</td>
|
||||||
|
<td>Step</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>Trace ¹</td>
|
|
||||||
<td>Control + T</td>
|
<td>Control + T</td>
|
||||||
|
<td>Trace</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>Scan +1 ¹</td>
|
|
||||||
<td>Control + L</td>
|
<td>Control + L</td>
|
||||||
|
<td>Scan +1</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>Frame +1 ¹</td>
|
|
||||||
<td>Control + F</td>
|
<td>Control + F</td>
|
||||||
|
<td>Frame +1</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>Rewind 1</td>
|
|
||||||
<td>Alt + Left arrow</td>
|
<td>Alt + Left arrow</td>
|
||||||
|
<td>Rewind 1</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>Rewind 10</td>
|
|
||||||
<td>Shift-Alt + Left arrow</td>
|
<td>Shift-Alt + Left arrow</td>
|
||||||
|
<td>Rewind 10</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>Rewind all</td>
|
|
||||||
<td>Alt + Down arrow</td>
|
<td>Alt + Down arrow</td>
|
||||||
|
<td>Rewind all</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>Unwind 1</td>
|
|
||||||
<td>Alt + Right arrow</td>
|
<td>Alt + Right arrow</td>
|
||||||
|
<td>Unwind 1</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>Unwind 10</td>
|
|
||||||
<td>Shift-Alt + Right arrow</td>
|
<td>Shift-Alt + Right arrow</td>
|
||||||
|
<td>Unwind 10</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>Unwind all</td>
|
|
||||||
<td>Alt + Up arrow</td>
|
<td>Alt + Up arrow</td>
|
||||||
|
<td>Unwind all</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
|
<td>Backquote (`)</td>
|
||||||
<td>Run, exits debugger</td>
|
<td>Run, exits debugger</td>
|
||||||
<td>Backquote (`), Escape</td>
|
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
</p>
|
</p>
|
||||||
For MacOS use 'Cmd' instead of 'Alt' key.
|
For MacOS use 'Cmd' instead of 'Alt' key.
|
||||||
<p>¹: External I/O input is ignored, the state of the <a href="#IOTab">I/O Tab</a> remains unchanged.</p>
|
|
||||||
<p>To the left of the global buttons, you find the 'Options...' button.</p>
|
<p>To the left of the global buttons, you find the 'Options...' button.</p>
|
||||||
<ul>
|
<ul>
|
||||||
<p><img src="graphics/debugger_options.png"></p>
|
<p><img src="graphics/debugger_options.png"></p>
|
||||||
|
@ -410,7 +408,7 @@ in detail in the <a href="index.html">User's Guide</a>.</p>
|
||||||
|
|
||||||
<p>The debugger tracks changes to the CPU, TIA and RIOT registers and RAM by
|
<p>The debugger tracks changes to the CPU, TIA and RIOT registers and RAM by
|
||||||
displaying changed locations or registers with a red background after each step,
|
displaying changed locations or registers with a red background after each step,
|
||||||
trace, scanLine, or frame advance. This sounds simple, and it is, but
|
trace, scanline, or frame advance. This sounds simple, and it is, but
|
||||||
it's also amazingly useful.</p>
|
it's also amazingly useful.</p>
|
||||||
|
|
||||||
<p>One clarification about the change tracking: it only tracks when values
|
<p>One clarification about the change tracking: it only tracks when values
|
||||||
|
@ -430,28 +428,25 @@ or Supermon for the C=64.</p>
|
||||||
Bash-style commands are also supported:</p>
|
Bash-style commands are also supported:</p>
|
||||||
|
|
||||||
<table border="1" cellpadding=4>
|
<table border="1" cellpadding=4>
|
||||||
<tr><th>Function</th><th>Key</th></tr>
|
<tr><th>Key</th><th>Function</th></tr>
|
||||||
<tr><td>Move cursor to beginning of line</td><td>Home</td></tr>
|
<tr><td>Home</td><td>Move cursor to beginning of line</td></tr>
|
||||||
<tr><td>Move cursor to end of line</td><td>End</td></tr>
|
<tr><td>End</td><td>Move cursor to end of line</td></tr>
|
||||||
<tr><td>Remove character to right of cursor</td><td>Delete</td></tr>
|
<tr><td>Delete</td><td>Remove character to right of cursor</td></tr>
|
||||||
<tr><td>Remove character to left of cursor</td><td>Backspace</td></tr>
|
<tr><td>Backspace</td><td>Remove character to left of cursor</td></tr>
|
||||||
<tr><td>Same function as 'Home'</td><td>Control + A</td></tr>
|
<tr><td>Control + A</td><td>Same function as 'Home'</td></tr>
|
||||||
<tr><td>Same function as 'End'</td><td>Control + E</td></tr>
|
<tr><td>Control + E</td><td>Same function as 'End'</td></tr>
|
||||||
<tr><td>Same function as 'Delete'</td><td>Control + D</td></tr>
|
<tr><td>Control + D</td><td>Same function as 'Delete'</td></tr>
|
||||||
<tr><td>Remove all characters from cursor to end of line</td><td>Control + K</td></tr>
|
<tr><td>Control + K</td><td>Remove all characters from cursor to end of line</td></tr>
|
||||||
<tr><td>Remove all characters from cursor to beginning of line</td><td>Control + U</td></tr>
|
<tr><td>Control + U</td><td>Remove all characters from cursor to beginning of line</td></tr>
|
||||||
<tr><td>Remove entire word to left of cursor</td><td>Control + W</td></tr>
|
<tr><td>Control + W</td><td>Remove entire word to left of cursor</td></tr>
|
||||||
<tr><td>Copy current line</td><td>Control + C</td></tr>
|
<tr><td>Shift + PgUp</td><td>Scroll up through previous commands one screen/page</td></tr>
|
||||||
<tr><td>Cut current line</td><td>Control + X</td></tr>
|
<tr><td>Shift + PgDown</td><td>Scroll down through previous commands one screen/page</td></tr>
|
||||||
<tr><td>Paste over current line</td><td>Control + V</td></tr>
|
<tr><td>Shift + Up</td><td>Scroll up through previous commands one line</td></tr>
|
||||||
<tr><td>Scroll up through previous commands one screen/page</td><td>Shift + PgUp</td></tr>
|
<tr><td>Shift + Down</td><td>Scroll down through previous commands one line</td></tr>
|
||||||
<tr><td>Scroll down through previous commands one screen/page</td><td>Shift + PgDown</td></tr>
|
<tr><td>Shift + Home</td><td>Scroll to beginning of commands</td></tr>
|
||||||
<tr><td>Scroll up through previous commands one line</td><td>Shift + Up</td></tr>
|
<tr><td>Shift + End</td><td>Scroll to end of commands</td></tr>
|
||||||
<tr><td>Scroll down through previous commands one line</td><td>Shift + Down</td></tr>
|
|
||||||
<tr><td>Scroll to beginning of commands</td><td>Shift + Home</td></tr>
|
|
||||||
<tr><td>Scroll to end of commands</td><td>Shift + End</td></tr>
|
|
||||||
</table>
|
</table>
|
||||||
<p>You can also scroll with the mouse. Copy and paste is currently only supported for a complete line.</p>
|
<p>You can also scroll with the mouse. Copy and paste is not yet supported.</p>
|
||||||
|
|
||||||
<p>To see the available commands, enter "help". For extended help, type "help cmd",
|
<p>To see the available commands, enter "help". For extended help, type "help cmd",
|
||||||
where 'cmd' is the command you wish to know about. The available commands are listed
|
where 'cmd' is the command you wish to know about. The available commands are listed
|
||||||
|
@ -472,16 +467,16 @@ just by re-running the relevant commands in the prompt.</p>
|
||||||
<h3><a name="TabCompletion">Tab Key Auto-Complete</a></h3>
|
<h3><a name="TabCompletion">Tab Key Auto-Complete</a></h3>
|
||||||
|
|
||||||
<p>While entering a command, label or function, you can type a partial name and
|
<p>While entering a command, label or function, you can type a partial name and
|
||||||
press the (Shift +) Tab key to attempt to auto-complete it. If you've ever used
|
press the Tab key to attempt to auto-complete it. If you've ever used
|
||||||
"bash", this will be immediately familiar. If not, try it: load up
|
"bash", this will be immediately familiar. If not, try it: load up
|
||||||
a ROM, go to the debugger, type "g" (but don't press Enter),
|
a ROM, go to the debugger, type "g" (but don't press Enter),
|
||||||
then hit Tab. The "g" will change to "gfx" (since this is the only
|
then hit Tab. The "g" will change to "gfx" (since this is the only
|
||||||
built-in command starting with a "g"). If there are multiple possible
|
built-in command starting with a "g"). If there are multiple possible
|
||||||
completions (try with "tr" instead of "g"), you can tab through them.
|
completions (try with "tr" instead of "g"), you'll see a list of them,
|
||||||
|
and your partial name will be completed as far as possible.
|
||||||
After the first character, the autocompletion considers all
|
After the first character, the autocompletion considers all
|
||||||
characters in the right order as a match (e.g. "twf" will be completed to
|
characters in the right order as a match (e.g. "twf" will be completed to
|
||||||
"trapWriteIf"). Alternatively you can make use of the camel case names and type
|
"trapwriteif").</p>
|
||||||
e.g. "tWI" ("trapWriteIf") or "lAS" ("LoadAllStates").</p>
|
|
||||||
|
|
||||||
<p>Tab completion works on all labels: built-in, loaded from a symbol file,
|
<p>Tab completion works on all labels: built-in, loaded from a symbol file,
|
||||||
or set during debugging with the "define" command. It also works with
|
or set during debugging with the "define" command. It also works with
|
||||||
|
@ -614,7 +609,7 @@ command that takes arguments.</p>
|
||||||
<h4><a name="Breakpoints">Breakpoints</a></h4>
|
<h4><a name="Breakpoints">Breakpoints</a></h4>
|
||||||
|
|
||||||
<p>A breakpoint is a "hotspot" in your program that causes the emulator
|
<p>A breakpoint is a "hotspot" in your program that causes the emulator
|
||||||
to stop emulating and jump into the debugger ¹. You can set as many
|
to stop emulating and jump into the debugger. You can set as many
|
||||||
breakpoints as you like. The command is "break xx yy" where xx is any
|
breakpoints as you like. The command is "break xx yy" where xx is any
|
||||||
expression and yy a bank number. Both arguments are optional. If you have
|
expression and yy a bank number. Both arguments are optional. If you have
|
||||||
created a symbol file, you can use labels for the expression.</p>
|
created a symbol file, you can use labels for the expression.</p>
|
||||||
|
@ -635,11 +630,8 @@ set it. In the example, "break kernel" will remove the breakpoint.
|
||||||
The "break" command can be thought of as a *toggle*: it turns the
|
The "break" command can be thought of as a *toggle*: it turns the
|
||||||
breakpoint on & off, like a light switch.</p>
|
breakpoint on & off, like a light switch.</p>
|
||||||
|
|
||||||
<p>You could also use "clearBreaks" to remove all the breakpoints. Also,
|
<p>You could also use "clearbreaks" to remove all the breakpoints. Also,
|
||||||
there is a "listBreaks" command that will list them all.</p>
|
there is a "listbreaks" command that will list them all.</p>
|
||||||
|
|
||||||
<p>¹ By enabling "logBreaks" you can log the current state into
|
|
||||||
the System Log and continue emulation instead.</p>
|
|
||||||
|
|
||||||
<h4><a name="ConditionalBreaks">Conditional Breaks</a></h4>
|
<h4><a name="ConditionalBreaks">Conditional Breaks</a></h4>
|
||||||
|
|
||||||
|
@ -669,10 +661,10 @@ is the "!" operator): !(*SWCHB&1). The parentheses are necessary as
|
||||||
we want to apply the ! to the result of the &, not just the first term
|
we want to apply the ! to the result of the &, not just the first term
|
||||||
(the "*SWCHB").</p>
|
(the "*SWCHB").</p>
|
||||||
|
|
||||||
<p>"breakIf !(*SWCHB&1)" will do the job for us. However, it's an ugly mess
|
<p>"breakif !(*SWCHB&1)" will do the job for us. However, it's an ugly mess
|
||||||
of letters, numbers, and punctuation. We can do a little better:</p>
|
of letters, numbers, and punctuation. We can do a little better:</p>
|
||||||
|
|
||||||
<p>"breakIf { !(*SWCHB & 1 ) }" is a lot more readable, isn't it? If
|
<p>"breakif { !(*SWCHB & 1 ) }" is a lot more readable, isn't it? If
|
||||||
you're going to use readable expressions with spaces in them,
|
you're going to use readable expressions with spaces in them,
|
||||||
enclose the entire expression in curly braces.</p>
|
enclose the entire expression in curly braces.</p>
|
||||||
|
|
||||||
|
@ -681,9 +673,9 @@ condition that depends on input (like SWCHB) will always happen at the
|
||||||
end of a frame. This is different from how a real 2600 works, but most
|
end of a frame. This is different from how a real 2600 works, but most
|
||||||
ROMs only check for input once per frame anyway.</p>
|
ROMs only check for input once per frame anyway.</p>
|
||||||
|
|
||||||
<p>Conditional breaks appear in "listBreaks", numbered starting from
|
<p>Conditional breaks appear in "listbreaks", numbered starting from
|
||||||
zero. You can remove a cond-break with "delBreakIf number", where
|
zero. You can remove a cond-break with "delbreakif number", where
|
||||||
the number comes from "listBreaks" or by entering the same conditional break again.</p>
|
the number comes from "listbreaks" or by entering the same conditional break again.</p>
|
||||||
|
|
||||||
<p>Any time the debugger is entered due to a trap, breakpoint, or
|
<p>Any time the debugger is entered due to a trap, breakpoint, or
|
||||||
conditional break, the reason will be displayed in the
|
conditional break, the reason will be displayed in the
|
||||||
|
@ -692,16 +684,16 @@ conditional break, the reason will be displayed in the
|
||||||
<h4><a name="Functions">Functions</a></h4>
|
<h4><a name="Functions">Functions</a></h4>
|
||||||
|
|
||||||
<p>There is one annoyance about complex expressions: once we
|
<p>There is one annoyance about complex expressions: once we
|
||||||
remove the conditional break with "delBreakIf" or "clearBreaks",
|
remove the conditional break with "delbreakif" or "clearbreaks",
|
||||||
we'd have to retype it (or search backwards with the up-arrow key)
|
we'd have to retype it (or search backwards with the up-arrow key)
|
||||||
if we wanted to use it again.</p>
|
if we wanted to use it again.</p>
|
||||||
|
|
||||||
<p>We can avoid this by defining the expression as a function, then using
|
<p>We can avoid this by defining the expression as a function, then using
|
||||||
"breakIf function_name":</p>
|
"breakif function_name":</p>
|
||||||
|
|
||||||
<pre>
|
<pre>
|
||||||
function gameReset { !(*SWCHB & 1 ) }
|
function gameReset { !(*SWCHB & 1 ) }
|
||||||
breakIf gameReset
|
breakif gameReset
|
||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
<p>Now we have a meaningful name for the condition, so we can use it again.
|
<p>Now we have a meaningful name for the condition, so we can use it again.
|
||||||
|
@ -711,16 +703,16 @@ if the Game Select switch is pressed. We want to break when the user
|
||||||
presses both Select and Reset:</p>
|
presses both Select and Reset:</p>
|
||||||
|
|
||||||
<pre>
|
<pre>
|
||||||
breakIf { gameReset && gameSelect }
|
breakif { gameReset && gameSelect }
|
||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
<p>User-defined functions appear in "listFunctions", which shows the label
|
<p>User-defined functions appear in "listfunctions", which shows the label
|
||||||
and expression for each function. Functions can be removed with
|
and expression for each function. Functions can be removed with
|
||||||
"delFunction label", where the labels come from "listFunctions".</p>
|
"delfunction label", where the labels come from "listfunctions".</p>
|
||||||
|
|
||||||
<h4><a name="BuiltInFunctions">Built-in Functions</a></h4>
|
<h4><a name="BuiltInFunctions">Built-in Functions</a></h4>
|
||||||
|
|
||||||
<p>Stella has some pre-defined functions for use with the "breakIf"
|
<p>Stella has some pre-defined functions for use with the "breakif"
|
||||||
command. These allow you to break and enter the debugger on various
|
command. These allow you to break and enter the debugger on various
|
||||||
conditions without having to define the conditions yourself.</p>
|
conditions without having to define the conditions yourself.</p>
|
||||||
|
|
||||||
|
@ -731,24 +723,24 @@ Stella debugger.</p>
|
||||||
|
|
||||||
<table border="1" cellpadding=4>
|
<table border="1" cellpadding=4>
|
||||||
<tr><th>Function</th><th>Definition</th><th>Description</th></tr>
|
<tr><th>Function</th><th>Definition</th><th>Description</th></tr>
|
||||||
<tr><td> _joy0Left</td><td> !(*SWCHA & $40)</td><td> Left joystick moved left</td></tr>
|
<tr><td> _joy0left</td><td> !(*SWCHA & $40)</td><td> Left joystick moved left</td></tr>
|
||||||
<tr><td> _joy0Right</td><td> !(*SWCHA & $80)</td><td> Left joystick moved right</td></tr>
|
<tr><td> _joy0right</td><td> !(*SWCHA & $80)</td><td> Left joystick moved right</td></tr>
|
||||||
<tr><td> _joy0Up</td><td> !(*SWCHA & $10)</td><td> Left joystick moved up</td></tr>
|
<tr><td> _joy0up</td><td> !(*SWCHA & $10)</td><td> Left joystick moved up</td></tr>
|
||||||
<tr><td> _joy0Down</td><td> !(*SWCHA & $20)</td><td> Left joystick moved down</td></tr>
|
<tr><td> _joy0down</td><td> !(*SWCHA & $20)</td><td> Left joystick moved down</td></tr>
|
||||||
<tr><td> _joy0Fire</td><td> !(*INPT4 & $80)</td><td> Left joystick fire button pressed</td></tr>
|
<tr><td> _joy0button</td><td> !(*INPT4 & $80)</td><td> Left joystick button pressed</td></tr>
|
||||||
<tr><td> _joy1Left</td><td> !(*SWCHA & $04)</td><td> Right joystick moved left</td></tr>
|
<tr><td> _joy1left</td><td> !(*SWCHA & $04)</td><td> Right joystick moved left</td></tr>
|
||||||
<tr><td> _joy1Right</td><td> !(*SWCHA & $08)</td><td> Right joystick moved right</td></tr>
|
<tr><td> _joy1right</td><td> !(*SWCHA & $08)</td><td> Right joystick moved right</td></tr>
|
||||||
<tr><td> _joy1Up</td><td> !(*SWCHA & $01)</td><td> Right joystick moved up</td></tr>
|
<tr><td> _joy1up</td><td> !(*SWCHA & $01)</td><td> Right joystick moved up</td></tr>
|
||||||
<tr><td> _joy1Down</td><td> !(*SWCHA & $02)</td><td> Right joystick moved down</td></tr>
|
<tr><td> _joy1down</td><td> !(*SWCHA & $02)</td><td> Right joystick moved down</td></tr>
|
||||||
<tr><td> _joy1Fire</td><td> !(*INPT5 & $80)</td><td> Right joystick fire button pressed</td></tr>
|
<tr><td> _joy1button</td><td> !(*INPT5 & $80)</td><td> Right joystick button pressed</td></tr>
|
||||||
<tr><td> _select</td><td> !(*SWCHB & $02)</td><td> Game Select pressed</td></tr>
|
<tr><td> _select</td><td> !(*SWCHB & $02)</td><td> Game Select pressed</td></tr>
|
||||||
<tr><td> _reset</td><td> !(*SWCHB & $01)</td><td> Game Reset pressed</td></tr>
|
<tr><td> _reset</td><td> !(*SWCHB & $01)</td><td> Game Reset pressed</td></tr>
|
||||||
<tr><td> _color</td><td> *SWCHB & $08</td><td> Color/BW set to Color</td></tr>
|
<tr><td> _color</td><td> *SWCHB & $08</td><td> Color/BW set to Color</td></tr>
|
||||||
<tr><td> _bw</td><td> !(*SWCHB & $08)</td><td> Color/BW set to BW</td></tr>
|
<tr><td> _bw</td><td> !(*SWCHB & $08)</td><td> Color/BW set to BW</td></tr>
|
||||||
<tr><td> _diff0B</td><td> !(*SWCHB & $40)</td><td> Left difficulty set to B (easy)</td></tr>
|
<tr><td> _diff0b</td><td> !(*SWCHB & $40)</td><td> Left difficulty set to B (easy)</td></tr>
|
||||||
<tr><td> _diff0A</td><td> *SWCHB & $40</td><td> Left difficulty set to A (hard)</td></tr>
|
<tr><td> _diff0a</td><td> *SWCHB & $40</td><td> Left difficulty set to A (hard)</td></tr>
|
||||||
<tr><td> _diff1B</td><td> !(*SWCHB & $80)</td><td> Right difficulty set to B (easy)</td></tr>
|
<tr><td> _diff1b</td><td> !(*SWCHB & $80)</td><td> Right difficulty set to B (easy)</td></tr>
|
||||||
<tr><td> _diff1A</td><td> *SWCHB & $80</td><td> Right difficulty set to A (hard)</td></tr>
|
<tr><td> _diff1a</td><td> *SWCHB & $80</td><td> Right difficulty set to A (hard)</td></tr>
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
<p>Don't worry about memorizing them all: the Prompt "help" command
|
<p>Don't worry about memorizing them all: the Prompt "help" command
|
||||||
|
@ -764,38 +756,36 @@ that holds 'number of scanlines' on an actual console).</p>
|
||||||
<table border="1" cellpadding=4>
|
<table border="1" cellpadding=4>
|
||||||
<tr><th>Function</th><th>Description</th></tr>
|
<tr><th>Function</th><th>Description</th></tr>
|
||||||
<tr><td> _bank</td><td> Currently selected bank</td></tr>
|
<tr><td> _bank</td><td> Currently selected bank</td></tr>
|
||||||
<tr><td> _cClocks</td><td> Color clocks on a scanLine</td></tr>
|
<tr><td> _cclocks</td><td> Color clocks on a scanline</td></tr>
|
||||||
<tr><td> _cyclesHi</td><td> Higher 32 bits of number of cycles since emulation started</td></tr>
|
<tr><td> _cycleshi</td><td> Higher 32 bits of number of cycles since emulation started</td></tr>
|
||||||
<tr><td> _cyclesLo</td><td> Lower 32 bits of number of cycles since emulation started</td></tr>
|
<tr><td> _cycleslo</td><td> Lower 32 bits of number of cycles since emulation started</td></tr>
|
||||||
<tr><td> _fCount</td><td> Number of frames since emulation started</td></tr>
|
<tr><td> _fcount</td><td> Number of frames since emulation started</td></tr>
|
||||||
<tr><td> _fCycles</td><td> Number of cycles since frame started</td></tr>
|
<tr><td> _fcycles</td><td> Number of cycles since frame started</td></tr>
|
||||||
<tr><td> _fTimReadCycles</td><td>Number of cycles used by timer reads since frame started</td></tr>
|
<tr><td> _ftimreadcycles</td><td>Number of cycles used by timer reads since frame started</td></tr>
|
||||||
<tr><td> _fWsyncCycles</td><td>Number of cycles skipped by WSYNC since frame started</td></tr>
|
<tr><td> _fwsynccycles</td><td>Number of cycles skipped by WSYNC since frame started</td></tr>
|
||||||
<tr><td> _iCycles</td><td> Number of cycles of last instruction</td></tr>
|
<tr><td> _icycles</td><td> Number of cycles of last instruction</td></tr>
|
||||||
<tr><td> _inTim</td><td> Current INTIM value</td></tr>
|
<tr><td> _scan</td><td> Current scanline count</td></tr>
|
||||||
<tr><td> _scan</td><td> Current scanLine count</td></tr>
|
<tr><td> _scanend</td><td> Scanline count at end of last frame</td></tr>
|
||||||
<tr><td> _scanEnd</td><td> Scanline count at end of last frame</td></tr>
|
<tr><td> _scycles</td><td> Number of cycles in current scanline</td></tr>
|
||||||
<tr><td> _sCycles</td><td> Number of cycles in current scanLine</td></tr>
|
<tr><td> _timwrapread</td><td> Timer read wrapped on this cycle</td></tr>
|
||||||
<tr><td> _timInt</td><td> Current TIMINT value</td></tr>
|
<tr><td> _timwrapwrite</td><td> Timer write wrapped on this cycle</td></tr>
|
||||||
<tr><td> _timWrapRead</td><td> Timer read wrapped on this cycle</td></tr>
|
<tr><td> _vblank</td><td> Whether vertical blank is enabled (1 or 0)</td></tr>
|
||||||
<tr><td> _timWrapWrite</td><td> Timer write wrapped on this cycle</td></tr>
|
<tr><td> _vsync</td><td> Whether vertical sync is enabled (1 or 0)</td></tr>
|
||||||
<tr><td> _vBlank</td><td> Whether vertical blank is enabled (1 or 0)</td></tr>
|
|
||||||
<tr><td> _vSync</td><td> Whether vertical sync is enabled (1 or 0)</td></tr>
|
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
<p><b>_scan</b> always contains the current scanLine count. You can use
|
<p><b>_scan</b> always contains the current scanline count. You can use
|
||||||
this to break your program in the middle of your kernel. Example:</p>
|
this to break your program in the middle of your kernel. Example:</p>
|
||||||
<pre>
|
<pre>
|
||||||
breakIf _scan==#64
|
breakif _scan==#64
|
||||||
</pre>
|
</pre>
|
||||||
<p>This will cause Stella to enter the debugger when the TIA reaches the
|
<p>This will cause Stella to enter the debugger when the TIA reaches the
|
||||||
beginning of the 64th scanLine.</p>
|
beginning of the 64th scanline.</p>
|
||||||
|
|
||||||
<p><b>_bank</b> always contains the currently selected bank. For 2K or 4K
|
<p><b>_bank</b> always contains the currently selected bank. For 2K or 4K
|
||||||
(non-bankswitched) ROMs, it will always contain 0. One useful use is:</p>
|
(non-bankswitched) ROMs, it will always contain 0. One useful use is:</p>
|
||||||
|
|
||||||
<pre>
|
<pre>
|
||||||
breakIf { pc==myLabel && _bank==1 }
|
breakif { pc==myLabel && _bank==1 }
|
||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
<p>This is similar to setting a regular breakpoint, but it will only trigger
|
<p>This is similar to setting a regular breakpoint, but it will only trigger
|
||||||
|
@ -814,8 +804,8 @@ pointed to by the Y register, even if the Y register changes.</p>
|
||||||
|
|
||||||
<p>The watches are numbered. The numbers are printed along with the
|
<p>The watches are numbered. The numbers are printed along with the
|
||||||
watches, so you can tell which is which. To delete a watch use the
|
watches, so you can tell which is which. To delete a watch use the
|
||||||
"delWatch" command with the watch number (1 to whatever). You can
|
"delwatch" command with the watch number (1 to whatever). You can
|
||||||
also delete them all with the "clearWatches" command.</p>
|
also delete them all with the "clearwatches" command.</p>
|
||||||
|
|
||||||
<p>Note that there's no real point in watching a label or CPU register
|
<p>Note that there's no real point in watching a label or CPU register
|
||||||
without dereferencing it: Labels are constants, and CPU registers
|
without dereferencing it: Labels are constants, and CPU registers
|
||||||
|
@ -828,7 +818,7 @@ accesses to a memory address, rather than specific location in the
|
||||||
program. They're useful for finding code that modifies TIA registers
|
program. They're useful for finding code that modifies TIA registers
|
||||||
or memory.</p>
|
or memory.</p>
|
||||||
|
|
||||||
<p>Traps can also combined with a condition ("trapIf"). If an access
|
<p>Traps can also combined with a condition ("trapif"). If an access
|
||||||
to a memory address is caught, the condition is evaluated additionally.
|
to a memory address is caught, the condition is evaluated additionally.
|
||||||
Only if the condition is true too, the emulations stops. For details
|
Only if the condition is true too, the emulations stops. For details
|
||||||
about conditions see <a href="#ConditionalBreaks"><b>Conditional Breaks</b></a> described above.</p>
|
about conditions see <a href="#ConditionalBreaks"><b>Conditional Breaks</b></a> described above.</p>
|
||||||
|
@ -852,28 +842,12 @@ so the best we can do is stop before the next instruction runs.</p>
|
||||||
<p>Traps come in two varieties: read access traps and write access traps.
|
<p>Traps come in two varieties: read access traps and write access traps.
|
||||||
It is possible to set both types of trap on the same address (that's
|
It is possible to set both types of trap on the same address (that's
|
||||||
what the plain "trap" command does). To set a read or write only trap,
|
what the plain "trap" command does). To set a read or write only trap,
|
||||||
use "trapRead(if)" or "trapWrite(if)".
|
use "trapread(if)" or "trapwrite(if)".
|
||||||
|
|
||||||
<p>All traps appear in "listTraps", numbered starting from zero. You
|
<p>All traps appear in "listtraps", numbered starting from zero. You
|
||||||
can remove a trap with "delTrap number", where the number comes from
|
can remove a trap with "deltrap number", where the number comes from
|
||||||
"listTraps" or by entering the identical trap again. You can get rid of
|
"listtraps" or by entering the identical trap again. You can get rid of
|
||||||
all traps at once with the "clearTraps" command.</p></p>
|
all traps at once with the "cleartraps" command.</p></p>
|
||||||
|
|
||||||
<h4><a name="Timers">Timers</a></h4>
|
|
||||||
|
|
||||||
<p>Timers are used to measure cycles used between two timer points. They
|
|
||||||
measure the minimum, maximum and average cycles executed between their two
|
|
||||||
timer points. Start and end points can be set via prompt command or ROM
|
|
||||||
Disassembly settings dialog.</p>
|
|
||||||
|
|
||||||
<p>If the timer point is defined without an address or bank, the current PC
|
|
||||||
address or bank are used. If a '+' is added, both timer points use address
|
|
||||||
mirrors too, a '*' triggers both timer points in any bank.</p>
|
|
||||||
|
|
||||||
<p>All timers can be shown in detail with "listTimers", a single timer
|
|
||||||
with "printTimer number". "resetTimers" allows resetting all timer statistics,
|
|
||||||
"delTimer number" removes a single timer. All timers can be deleted with the
|
|
||||||
"clearTimers" command.</p>
|
|
||||||
|
|
||||||
</br>
|
</br>
|
||||||
<h3><a name="SaveWork">Save your work!</a></h3>
|
<h3><a name="SaveWork">Save your work!</a></h3>
|
||||||
|
@ -882,61 +856,58 @@ later re-use.</p>
|
||||||
|
|
||||||
<ul>
|
<ul>
|
||||||
<li>
|
<li>
|
||||||
<b><a name="savecmd">save</a></b>: If you've defined a lot of complex
|
<b><a name="savecmd">save</a></b>: If you've defined a lot of complex functions, you probably will
|
||||||
functions, you probably will want to re-use them in future runs of the
|
want to re-use them in future runs of the debugger. You can save all
|
||||||
debugger. You can save all your functions, breakpoints, conditional breaks,
|
your functions, breakpoints, conditional breaks, traps and watches with the
|
||||||
traps and watches with the "save" command. By default it is saved in the
|
"save" command. If you name your saved file the same as the ROM filename
|
||||||
user directory with the same as the ROM filename. In this case it will be
|
and place it in the ROM directory, it will be auto-loaded next time you
|
||||||
auto-loaded next time you load the same ROM in Stella. The saved file is
|
load the same ROM in Stella. The saved file is just a plain text file
|
||||||
just a plain text file called "<rom_filename>.script", so you can
|
called "<rom_filename>.script", so you can edit it and add new functions, etc.
|
||||||
edit it and add more functions, etc.
|
|
||||||
<p>Use "autoSave" to automatically execute the "save" command when
|
|
||||||
exiting the debugger.</p>
|
|
||||||
<p>Note: While "save" is ROM specific, you can also create a file called
|
<p>Note: While "save" is ROM specific, you can also create a file called
|
||||||
"autoexec.script" which will be loaded when the debugger starts, no matter
|
"autoexec.script" which will be loaded when the debugger starts, no matter
|
||||||
what ROM you have loaded.<p>
|
what ROM you have loaded.<p>
|
||||||
See <a href="#Startup"><b>Startup</b></a> for details.
|
See <a href="#Startup"><b>Startup</b></a> for details.
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<b>saveConfig</b>: The "saveConfig" command creates a
|
<b>saveconfig</b>: The "saveconfig" command creates a
|
||||||
<a href="#DistellaConfiguration"><b>DiStella Configuration File</b></a> which is
|
<a href="#DistellaConfiguration"><b>DiStella Configuration File</b></a> which is
|
||||||
based on Stella's dynamic and static analysis of the current ROM.
|
based on Stella's dynamic and static analysis of the current ROM.
|
||||||
<p>This will be automatically loaded the next time your start the debugger.
|
<p>This will be automatically loaded the next time your start the debugger.
|
||||||
From there on, you can continue analyzing the ROM and then use "saveConfig"
|
From there on, you can continue analyzing the ROM and then use "saveconfig"
|
||||||
again to update the configuration. You can also use "loadConfig" to load it
|
again to update the configuration. You can also use "loadconfig" to load it
|
||||||
manually.
|
manually.
|
||||||
<p>Note that this is not tested for multi-banked ROMs.</p>
|
<p>Note that this is not tested for multi-banked ROMs.</p>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<b>saveDis</b>:
|
<b>savedis</b>:
|
||||||
While your are playing or debugging a game, Stella will gather dynamic
|
While your are playing or debugging a game, Stella will gather dynamic
|
||||||
information about the ROM. It can then use that information together with
|
information about the ROM. It can then use that information together with
|
||||||
a static analysis of the ROM and therefore create a better disassembly
|
a static analysis of the ROM and therefore create a better disassembly
|
||||||
than DiStella alone. "saveDis" allows you to save that disassembly as the
|
than DiStella alone. "savedis" allows you to save that disassembly as the
|
||||||
result of this combined analysis.
|
result of this combined analysis.
|
||||||
<p>Note that this currently only works for single banked ROMs. For larger
|
<p>Note that this currently only works for single banked ROMs. For larger
|
||||||
ROMs, the created disassembly is incomplete.</p>
|
ROMs, the created disassembly is incomplete.</p>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<p><b>saveRom</b>:
|
<p><b>saverom</b>:
|
||||||
If you have manipulated a ROM, you can save it with "saveRom". The file is
|
If you have manipulated a ROM, you can save it with "saverom". The file is
|
||||||
named "<rom_filename>.a26".</p>
|
named "<rom_filename>.a26".</p>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<p><b>saveSes</b>:
|
<p><b>saveses</b>:
|
||||||
The "saveSes" command dumps the whole prompt session into a file named
|
The "saveses" command dumps the whole prompt session into a file named
|
||||||
"<YYYY-MM-DD_HH-mm-ss>.txt". So you can later lookup what you did exactly
|
"<YYYY-MM-DD_HH-mm-ss>.txt". So you can later lookup what you did exactly
|
||||||
when you were debugging at that time.</p>
|
when you were debugging at that time.</p>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<p><b>saveAllStates</b>:
|
<p><b>saveallstates</b>:
|
||||||
This command works identical to the save all states hotkey (Alt + F9) during emulation.
|
This command works identical to the save all states hotkey (Alt + F9) during emulation.
|
||||||
The saved states can be loaded with "loadAllStates".</p>
|
The saved states can be loaded with "loadallstates".</p>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<p><b>saveState</b>:
|
<p><b>savestate</b>:
|
||||||
This command works identical to the save state hotkey (F9) during emulation.
|
This command works identical to the save state hotkey (F9) during emulation.
|
||||||
Any previously saved state can be loaded with "loadState" plus the slot
|
Any previously saved state can be loaded with "loadstate" plus the slot
|
||||||
number (0-9).</p>
|
number (0-9).</p>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
@ -950,107 +921,97 @@ Type "help 'cmd'" to see extended information about the given command.</p>
|
||||||
<pre>
|
<pre>
|
||||||
a - Set Accumulator to <value>
|
a - Set Accumulator to <value>
|
||||||
aud - Mark 'AUD' range in disassembly
|
aud - Mark 'AUD' range in disassembly
|
||||||
autoSave - Automatically execute "save" when exiting the debugger
|
|
||||||
base - Set default number base to <base> (bin, dec, hex)
|
base - Set default number base to <base> (bin, dec, hex)
|
||||||
bCol - Mark 'BCOL' range in disassembly
|
bcol - Mark 'BCOL' range in disassembly
|
||||||
break - Set/clear breakpoint at <address> and <bank>
|
break - Set/clear breakpoint at <address> and <bank>
|
||||||
breakIf - Set/clear breakpoint on <condition>
|
breakif - Set/clear breakpoint on <condition>
|
||||||
breakLabel - Set/clear breakpoint on <address> (no mirrors, all banks)
|
breaklabel - Set/clear breakpoint on <address> (no mirrors, all banks)
|
||||||
c - Carry Flag: set (0 or 1), or toggle (no arg)
|
c - Carry Flag: set (0 or 1), or toggle (no arg)
|
||||||
cheat - Use a cheat code (see manual for cheat types)
|
cheat - Use a cheat code (see manual for cheat types)
|
||||||
clearBreaks - Clear all breakpoints
|
clearbreaks - Clear all breakpoints
|
||||||
clearConfig - Clear DiStella config directives [bank xx]
|
clearconfig - Clear DiStella config directives [bank xx]
|
||||||
clearHistory - Clear the prompt history
|
clearsavestateifs - Clear all savestate points
|
||||||
clearSaveStateIfs - Clear all saveState points
|
cleartraps - Clear all traps
|
||||||
clearTimers - Clear all timers
|
clearwatches - Clear all watches
|
||||||
clearTraps - Clear all traps
|
|
||||||
clearWatches - Clear all watches
|
|
||||||
cls - Clear prompt area of text
|
cls - Clear prompt area of text
|
||||||
code - Mark 'CODE' range in disassembly
|
code - Mark 'CODE' range in disassembly
|
||||||
col - Mark 'COL' range in disassembly
|
col - Mark 'COL' range in disassembly
|
||||||
colorTest - Show value xx as TIA color
|
colortest - Show value xx as TIA color
|
||||||
d - Decimal Mode Flag: set (0 or 1), or toggle (no arg)
|
d - Decimal Mode Flag: set (0 or 1), or toggle (no arg)
|
||||||
data - Mark 'DATA' range in disassembly
|
data - Mark 'DATA' range in disassembly
|
||||||
debugColors - Show Fixed Debug Colors information
|
debugcolors - Show Fixed Debug Colors information
|
||||||
define - Define label xx for address yy
|
define - Define label xx for address yy
|
||||||
delBreakIf - Delete conditional breakIf <xx>
|
delbreakif - Delete conditional breakif <xx>
|
||||||
delFunction - Delete function with label xx
|
delfunction - Delete function with label xx
|
||||||
delSaveStateIf - Delete conditional saveState point <xx>
|
delsavestateif - Delete conditional savestate point <xx>
|
||||||
delTrap - Delete trap <xx>
|
deltrap - Delete trap <xx>
|
||||||
delTimer - Delete timer <xx>
|
delwatch - Delete watch <xx>
|
||||||
delWatch - Delete watch <xx>
|
disasm - Disassemble address xx [yy lines] (default=PC)
|
||||||
disAsm - Disassemble address xx [yy lines] (default=PC)
|
|
||||||
dump - Dump data at address <xx> [to yy] [1: memory; 2: CPU state; 4: input regs] [?]
|
dump - Dump data at address <xx> [to yy] [1: memory; 2: CPU state; 4: input regs] [?]
|
||||||
exec - Execute script file <xx> [prefix]
|
exec - Execute script file <xx> [prefix]
|
||||||
exitRom - Exit emulator, return to ROM launcher
|
exitrom - Exit emulator, return to ROM launcher
|
||||||
frame - Advance emulation by <xx> frames (default=1)
|
frame - Advance emulation by <xx> frames (default=1)
|
||||||
function - Define function name xx for expression yy
|
function - Define function name xx for expression yy
|
||||||
gfx - Mark 'GFX' range in disassembly
|
gfx - Mark 'GFX' range in disassembly
|
||||||
help - help <command>
|
help - help <command>
|
||||||
joy0Up - Set joystick 0 up direction to value <x> (0 or 1), or toggle (no arg)
|
joy0up - Set joystick 0 up direction to value <x> (0 or 1), or toggle (no arg)
|
||||||
joy0Down - Set joystick 0 down direction to value <x> (0 or 1), or toggle (no arg)
|
joy0down - Set joystick 0 down direction to value <x> (0 or 1), or toggle (no arg)
|
||||||
joy0Left - Set joystick 0 left direction to value <x> (0 or 1), or toggle (no arg)
|
joy0left - Set joystick 0 left direction to value <x> (0 or 1), or toggle (no arg)
|
||||||
joy0Right - Set joystick 0 right direction to value <x> (0 or 1), or toggle (no arg)
|
joy0right - Set joystick 0 right direction to value <x> (0 or 1), or toggle (no arg)
|
||||||
joy0Fire - Set joystick 0 fire button to value <x> (0 or 1), or toggle (no arg)
|
joy0fire - Set joystick 0 fire button to value <x> (0 or 1), or toggle (no arg)
|
||||||
joy1Up - Set joystick 1 up direction to value <x> (0 or 1), or toggle (no arg)
|
joy1up - Set joystick 1 up direction to value <x> (0 or 1), or toggle (no arg)
|
||||||
joy1Down - Set joystick 1 down direction to value <x> (0 or 1), or toggle (no arg)
|
joy1down - Set joystick 1 down direction to value <x> (0 or 1), or toggle (no arg)
|
||||||
joy1Left - Set joystick 1 left direction to value <x> (0 or 1), or toggle (no arg)
|
joy1left - Set joystick 1 left direction to value <x> (0 or 1), or toggle (no arg)
|
||||||
joy1Right - Set joystick 1 right direction to value <x> (0 or 1), or toggle (no arg)
|
joy1right - Set joystick 1 right direction to value <x> (0 or 1), or toggle (no arg)
|
||||||
joy1Fire - Set joystick 1 fire button to value <x> (0 or 1), or toggle (no arg)
|
joy1fire - Set joystick 1 fire button to value <x> (0 or 1), or toggle (no arg)
|
||||||
jump - Scroll disassembly to address xx
|
jump - Scroll disassembly to address xx
|
||||||
listBreaks - List breakpoints
|
listbreaks - List breakpoints
|
||||||
listConfig - List DiStella config directives [bank xx]
|
listconfig - List DiStella config directives [bank xx]
|
||||||
listFunctions - List user-defined functions
|
listfunctions - List user-defined functions
|
||||||
listSaveStateIfs - List saveState points
|
listsavestateifs - List savestate points
|
||||||
listTraps - List traps
|
listtraps - List traps
|
||||||
loadConfig - Load DiStella config file
|
loadconfig - Load DiStella config file
|
||||||
loadAllStates - Load all emulator states
|
loadallstates - Load all emulator states
|
||||||
loadState - Load emulator state xx (0-9)
|
loadstate - Load emulator state xx (0-9)
|
||||||
logBreaks - Logs breaks and traps and continues emulation
|
|
||||||
logTrace - Logs emulation (note: emulation may slow down and the log becomes huge soon)
|
|
||||||
n - Negative Flag: set (0 or 1), or toggle (no arg)
|
n - Negative Flag: set (0 or 1), or toggle (no arg)
|
||||||
palette - Show current TIA palette
|
palette - Show current TIA palette
|
||||||
pc - Set Program Counter to address xx
|
pc - Set Program Counter to address xx
|
||||||
pCol - Mark 'PCOL' range in disassembly
|
pcol - Mark 'PCOL' range in disassembly
|
||||||
pGfx - Mark 'PGFX' range in disassembly
|
pgfx - Mark 'PGFX' range in disassembly
|
||||||
print - Evaluate/print expression xx in hex/dec/binary
|
print - Evaluate/print expression xx in hex/dec/binary
|
||||||
printTimer - Print details of timer xx
|
|
||||||
ram - Show ZP RAM, or set address xx to yy1 [yy2 ...]
|
ram - Show ZP RAM, or set address xx to yy1 [yy2 ...]
|
||||||
reset - Reset system to power-on state
|
reset - Reset system to power-on state
|
||||||
resetTimers - Reset all timers' statistics
|
|
||||||
rewind - Rewind state by one or [xx] steps/traces/scanlines/frames...
|
rewind - Rewind state by one or [xx] steps/traces/scanlines/frames...
|
||||||
riot - Show RIOT timer/input status
|
riot - Show RIOT timer/input status
|
||||||
rom - Set ROM address xx to yy1 [yy2 ...]
|
rom - Set ROM address xx to yy1 [yy2 ...]
|
||||||
row - Mark 'ROW' range in disassembly
|
row - Mark 'ROW' range in disassembly
|
||||||
run - Exit debugger, return to emulator
|
run - Exit debugger, return to emulator
|
||||||
runTo - Run until string xx in disassembly
|
runto - Run until string xx in disassembly
|
||||||
runToPc - Run until PC is set to value xx
|
runtopc - Run until PC is set to value xx
|
||||||
s - Set Stack Pointer to value xx
|
s - Set Stack Pointer to value xx
|
||||||
save - Save breaks, watches, traps and functions to file [xx or ?]
|
save - Save breaks, watches, traps and functions to file <xx or ?>
|
||||||
saveAccess - Save access counters to CSV file [?]
|
saveaccess - Save access counters to CSV file [?]
|
||||||
saveConfig - Save DiStella config file (with default name)
|
saveconfig - Save DiStella config file (with default name)
|
||||||
saveDis - Save DiStella disassembly to file [?]
|
savedis - Save DiStella disassembly to file [?]
|
||||||
saveRom - Save (possibly patched) ROM to file [?]
|
saverom - Save (possibly patched) ROM to file [?]
|
||||||
saveSes - Save console session to file [?]
|
saveses - Save console session to file [?]
|
||||||
saveSnap - Save current TIA image to PNG file
|
savesnap - Save current TIA image to PNG file
|
||||||
saveAllStates - Save all emulator states
|
saveallstates - Save all emulator states
|
||||||
saveState - Save emulator state xx (valid args 0-9)
|
savestate - Save emulator state xx (valid args 0-9)
|
||||||
saveStateIf - Create saveState on <condition>
|
savestateif - Create savestate on <condition>
|
||||||
scanLine - Advance emulation by <xx> scanlines (default=1)
|
scanline - Advance emulation by <xx> scanlines (default=1)
|
||||||
step - Single step CPU [with count xx]
|
step - Single step CPU [with count xx]
|
||||||
stepWhile - Single step CPU while <condition> is true
|
stepwhile - Single step CPU while <condition> is true
|
||||||
swchb - Set SWCHB to value xx
|
|
||||||
tia - Show TIA state
|
tia - Show TIA state
|
||||||
timer - Set a timer point
|
|
||||||
trace - Single step CPU over subroutines [with count xx]
|
trace - Single step CPU over subroutines [with count xx]
|
||||||
trap - Trap read/write access to address(es) xx [yy]
|
trap - Trap read/write access to address(es) xx [yy]
|
||||||
trapIf - On <condition> trap R/W access to address(es) xx [yy]
|
trapif - On <condition> trap R/W access to address(es) xx [yy]
|
||||||
trapRead - Trap read access to address(es) xx [yy]
|
trapread - Trap read access to address(es) xx [yy]
|
||||||
trapReadIf - On <condition> trap read access to address(es) xx [yy]
|
trapreadif - On <condition> trap read access to address(es) xx [yy]
|
||||||
trapWrite - Trap write access to address(es) xx [yy]
|
trapwrite - Trap write access to address(es) xx [yy]
|
||||||
trapWriteIf - On <condition> trap write access to address(es) xx [yy]
|
trapwriteif - On <condition> trap write access to address(es) xx [yy]
|
||||||
type - Show disassembly type for address xx [yy]
|
type - Show disassembly type for address xx [yy]
|
||||||
uHex - Toggle upper/lowercase HEX display
|
uhex - Toggle upper/lowercase HEX display
|
||||||
undef - Undefine label xx (if defined)
|
undef - Undefine label xx (if defined)
|
||||||
unwind - Unwind state state by one or [xx] steps/traces/scanlines/frames...
|
unwind - Unwind state state by one or [xx] steps/traces/scanlines/frames...
|
||||||
v - Overflow Flag: set (0 or 1), or toggle (no arg)
|
v - Overflow Flag: set (0 or 1), or toggle (no arg)
|
||||||
|
@ -1108,7 +1069,7 @@ VDELBL selects the register that is used to control the ball. This is
|
||||||
visualized in the debugger in the same way as the two copies of GRP0 and
|
visualized in the debugger in the same way as the two copies of GRP0 and
|
||||||
GRP1</p>
|
GRP1</p>
|
||||||
|
|
||||||
<p>For many registers, writes don't take effect immediately as the
|
<p>For many registers, writes don't take effect immediatelly as the
|
||||||
TIA takes some color clocks to change state. In Stella's TIA core, this
|
TIA takes some color clocks to change state. In Stella's TIA core, this
|
||||||
is implemented by queueing the writes, and the contents of this queue
|
is implemented by queueing the writes, and the contents of this queue
|
||||||
are visualized in the debugger in the "Queued Writes" area of the TIA tab.</p>
|
are visualized in the debugger in the "Queued Writes" area of the TIA tab.</p>
|
||||||
|
@ -1123,11 +1084,11 @@ in another part of the debugger).</p>
|
||||||
<p><img src="graphics/debugger_iotab.png"></p>
|
<p><img src="graphics/debugger_iotab.png"></p>
|
||||||
|
|
||||||
<p>As with the TIA tab, most of the values here will be self-explanatory to a 2600
|
<p>As with the TIA tab, most of the values here will be self-explanatory to a 2600
|
||||||
developer, and many can be modified. However, the SWCHx registers need
|
developer, and almost all can be modified. However, the SWCHx registers need
|
||||||
further explanation:<p>
|
further explanation:<p>
|
||||||
<p>SWCHx(W/R) can be modified; here (W) stands for write, (R) for read.
|
<p>SWCHx(W) can be modified; here, the (W) stands for write. Similarly,
|
||||||
Similarly, SWxCNT can be directly modified. However, the results of reading
|
SWACNT/SWBCNT can be directly modified. However, the results of reading back from
|
||||||
back from the SWCHx register are influenced by SWxCNT, and SWCHx(R) is
|
the SWCHx register are influenced by SWACNT/SWBCNT, and SWCHx(R) is a read-only display
|
||||||
reflecting this result.</p>
|
reflecting this result.</p>
|
||||||
|
|
||||||
|
|
||||||
|
@ -1150,12 +1111,12 @@ volume resulting from the two channel volumes.</p>
|
||||||
<p>In the upper left of the debugger, you'll see the current frame of
|
<p>In the upper left of the debugger, you'll see the current frame of
|
||||||
video as generated by the TIA. If a complete frame hasn't been drawn,
|
video as generated by the TIA. If a complete frame hasn't been drawn,
|
||||||
the partial contents of the current frame will be displayed up to the
|
the partial contents of the current frame will be displayed up to the
|
||||||
current scanLine, with the contents of the old frame (in black &
|
current scanline, with the contents of the old frame (in black &
|
||||||
white) filling the rest of the display. Note that if 'phosphor mode'
|
white) filling the rest of the display. Note that if 'phosphor mode'
|
||||||
or TV effects are enabled, you won't see the effects here; this shows the
|
or TV effects are enabled, you won't see the effects here; this shows the
|
||||||
<b>raw</b> TIA image only.</p>
|
<b>raw</b> TIA image only.</p>
|
||||||
|
|
||||||
<p>To e.g. watch the TIA draw the frame one scanLine at a time, you can
|
<p>To e.g. watch the TIA draw the frame one scanline at a time, you can
|
||||||
use the 'Scan+1' button, the prompt "scan" command or the Control-L key.</p>
|
use the 'Scan+1' button, the prompt "scan" command or the Control-L key.</p>
|
||||||
|
|
||||||
<p>You can also right-click anywhere in this window to show a context menu,
|
<p>You can also right-click anywhere in this window to show a context menu,
|
||||||
|
@ -1163,10 +1124,10 @@ as illustrated:</p>
|
||||||
<p><img src="graphics/debugger_tiaoutcmenu.png"></p>
|
<p><img src="graphics/debugger_tiaoutcmenu.png"></p>
|
||||||
<p>The options are as follows:</p>
|
<p>The options are as follows:</p>
|
||||||
<ul>
|
<ul>
|
||||||
<li><b>Fill to scanLine</b>: This option will draw all scanlines up to the
|
<li><b>Fill to scanline</b>: This option will draw all scanlines up to the
|
||||||
vertical position where the mouse was clicked (see also <a href="#TIAZoom"><b>TIA Zoom</b></a>).</li>
|
vertical position where the mouse was clicked (see also <a href="#TIAZoom"><b>TIA Zoom</b></a>).</li>
|
||||||
<li><b>Toggle breakpoint</b>: Will toggle a conditional breakpoint at the
|
<li><b>Toggle breakpoint</b>: Will toggle a conditional breakpoint at the
|
||||||
scanLine where the mouse was clicked. You can also use a left-click or
|
scanline where the mouse was clicked. You can also use a left-click or
|
||||||
the Prompt Tab commands to list and turn off the breakpoint
|
the Prompt Tab commands to list and turn off the breakpoint
|
||||||
(see also <a href="#TIAZoom"><b>TIA Zoom</b></a>).</li>
|
(see also <a href="#TIAZoom"><b>TIA Zoom</b></a>).</li>
|
||||||
<li><b>Set zoom position</b>: Influences what is shown in the TIA
|
<li><b>Set zoom position</b>: Influences what is shown in the TIA
|
||||||
|
@ -1187,27 +1148,27 @@ as illustrated:</p>
|
||||||
<p>The indicators are as follows (note that all these are read-only):</p>
|
<p>The indicators are as follows (note that all these are read-only):</p>
|
||||||
<ul>
|
<ul>
|
||||||
<li><b>Frame Cycls</b>: The number of CPU cycles that have been executed this frame since
|
<li><b>Frame Cycls</b>: The number of CPU cycles that have been executed this frame since
|
||||||
VSYNC was cleared at scanLine 0.</li>
|
VSYNC was cleared at scanline 0.</li>
|
||||||
<li><b>WSync Cycls</b>: The number of CPU cycles that have been skipped by WSYNC this frame since
|
<li><b>WSync Cycls</b>: The number of CPU cycles that have been skipped by WSYNC this frame since
|
||||||
VSYNC was cleared at scanLine 0.</li>
|
VSYNC was cleared at scanline 0.</li>
|
||||||
<li><b>Timer Cycls</b>: The number of CPU cycles (approximately) that have been used by timer read loops since
|
<li><b>Timer Cycls</b>: The number of CPU cycles (approximately) that have been used by timer read loops since
|
||||||
VSYNC was cleared at scanLine 0.</li>
|
VSYNC was cleared at scanline 0.</li>
|
||||||
<li><b>Total</b>: The total number of CPU cycles since this ROM was loaded or reset.</li>
|
<li><b>Total</b>: The total number of CPU cycles since this ROM was loaded or reset.</li>
|
||||||
<li><b>Delta</b>: The number of CPU cycles that have been executed since the last debugger
|
<li><b>Delta</b>: The number of CPU cycles that have been executed since the last debugger
|
||||||
interrupt.</li>
|
interrupt.</li>
|
||||||
<li><b>Frame Cnt.</b>: The number of frames since this ROM was loaded or reset.</li>
|
<li><b>Frame Cnt.</b>: The number of frames since this ROM was loaded or reset.</li>
|
||||||
<li><b>Scanline</b>: The scanLine that's currently being drawn, and the count from the
|
<li><b>Scanline</b>: The scanline that's currently being drawn, and the count from the
|
||||||
previous frame. Scanline 0 is the one on which VSYNC is cleared (after being set for
|
previous frame. Scanline 0 is the one on which VSYNC is cleared (after being set for
|
||||||
3 scanlines, as per the Stella Programmer's Guide).</li>
|
3 scanlines, as per the Stella Programmer's Guide).</li>
|
||||||
<li><b>Scan Cycle</b>: The number of CPU cycles that have been executed since the beginning
|
<li><b>Scan Cycle</b>: The number of CPU cycles that have been executed since the beginning
|
||||||
of the current scanLine.</li>
|
of the current scanline.</li>
|
||||||
<li><b>Pixel Pos</b>: The current number of visible color clocks that have been displayed on
|
<li><b>Pixel Pos</b>: The current number of visible color clocks that have been displayed on
|
||||||
the current scanLine, starting from the beginning of the Horizontal Blank period.
|
the current scanline, starting from the beginning of the Horizontal Blank period.
|
||||||
During HBLANK, this value will be negative (representing the number of clocks
|
During HBLANK, this value will be negative (representing the number of clocks
|
||||||
until the first visible one). Since there are 68 color clocks per HBLANK and
|
until the first visible one). Since there are 68 color clocks per HBLANK and
|
||||||
160 visible clocks per scanLine, the Pixel Position will range from -68 to 159.</li>
|
160 visible clocks per scanline, the Pixel Position will range from -68 to 159.</li>
|
||||||
<li><b>Color Clock</b>: The current number of total color clocks since the beginning of this
|
<li><b>Color Clock</b>: The current number of total color clocks since the beginning of this
|
||||||
scanLine's HBLANK. This counter starts at zero, but otherwise displays the same
|
scanline's HBLANK. This counter starts at zero, but otherwise displays the same
|
||||||
information as the Pixel Position (so Color Clock will always be 68 more than Pixel
|
information as the Pixel Position (so Color Clock will always be 68 more than Pixel
|
||||||
Position, and will range from 0 to 228).</li>
|
Position, and will range from 0 to 228).</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
@ -1225,10 +1186,10 @@ as illustrated:</p>
|
||||||
<p><img src="graphics/debugger_tiazoomcmenu.png"></p>
|
<p><img src="graphics/debugger_tiazoomcmenu.png"></p>
|
||||||
<p>These options allow you to:</p>
|
<p>These options allow you to:</p>
|
||||||
<ul>
|
<ul>
|
||||||
<li><b>Fill to scanLine</b>: This option will draw all scanlines up to the
|
<li><b>Fill to scanline</b>: This option will draw all scanlines up to the
|
||||||
vertical position where the mouse was clicked.</li>
|
vertical position where the mouse was clicked.</li>
|
||||||
<li><b>Toggle breakpoint</b>: Will toggle a conditional breakpoint at the
|
<li><b>Toggle breakpoint</b>: Will toggle a conditional breakpoint at the
|
||||||
scanLine where the mouse was clicked. You can also
|
scanline where the mouse was clicked. You can also
|
||||||
the Prompt Tab commands to list and turn off the breakpoint.</li>
|
the Prompt Tab commands to list and turn off the breakpoint.</li>
|
||||||
<li><b>2x|4x|8x zoom</b>: Zoom in on the image for even greater detail.</li>
|
<li><b>2x|4x|8x zoom</b>: Zoom in on the image for even greater detail.</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
@ -1327,40 +1288,13 @@ are lost (they will NOT end up in the Carry flag).</p>
|
||||||
<h2><a name="M6532"><u>(K)</u> M6532/RIOT RAM</a></h2>
|
<h2><a name="M6532"><u>(K)</u> M6532/RIOT RAM</a></h2>
|
||||||
<p>This is a spreadsheet-like GUI for inspecting and changing the contents
|
<p>This is a spreadsheet-like GUI for inspecting and changing the contents
|
||||||
of the 2600's zero-page RAM.</p>
|
of the 2600's zero-page RAM.</p>
|
||||||
<p>You can navigate with either the mouse or the keyboard (see below).
|
<p>You can navigate with either the mouse or the keyboard arrow keys.
|
||||||
To change a RAM location, either double-click on it or press 'Enter' while
|
To change a RAM location, either double-click on it or press 'Enter' while
|
||||||
it's highlighted. Enter the new value (hex, other formats using the bottom textboxes), then
|
it's highlighted. Enter the new value (hex, other formats using the bottom textboxes), then
|
||||||
press 'Enter' to make the change. The currently selected RAM cell
|
press 'Enter' to make the change. The currently selected RAM cell
|
||||||
can also be changed by using the
|
can also be changed by using the
|
||||||
<a href="#DataOpButtons"><b>Data Operations Buttons</b></a> or the associated
|
<a href="#DataOpButtons"><b>Data Operations Buttons</b></a> or the associated
|
||||||
shortcut keys.</p>
|
shortcut keys.</p>
|
||||||
|
|
||||||
<p>You can navigate all RAM grids (and other data grids too) using the following keyboard shortcuts.</p>
|
|
||||||
<table border="1" cellpadding=4>
|
|
||||||
<tr>
|
|
||||||
<th>Shortut</th><th>Description</th>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>Left arrow</td><td>Move to left cell.</td>
|
|
||||||
</tr><tr>
|
|
||||||
<td>Right arrow</td><td>Move to right cell.</td>
|
|
||||||
</tr><tr>
|
|
||||||
<td>Home</td><td>Move to leftmost cell.</td>
|
|
||||||
</tr><tr>
|
|
||||||
<td>End</td><td>Move to rightmost cell.</td>
|
|
||||||
</tr><tr>
|
|
||||||
<td>Up arrow</td><td>Move to cell above.</td>
|
|
||||||
</tr><tr>
|
|
||||||
<td>Down arrow</td><td>Move to cell below.</td>
|
|
||||||
</tr><tr>
|
|
||||||
<td>Page Up</td><td>Move to top visible row.</td>
|
|
||||||
</tr><tr>
|
|
||||||
<td>Page Down</td><td>Move to bottom visible row.</td>
|
|
||||||
</tr><tr>
|
|
||||||
<td>Shift + Page Up</td><td>Scroll one page up.</td>
|
|
||||||
</tr><tr>
|
|
||||||
<td>Shift + Page Down</td><td>Scroll one page down.</td>
|
|
||||||
</table>
|
|
||||||
<p><img src="graphics/debugger_ram.png"></p>
|
<p><img src="graphics/debugger_ram.png"></p>
|
||||||
<p>The 'Undo' button in the upper right should be self-explanatory; it will
|
<p>The 'Undo' button in the upper right should be self-explanatory; it will
|
||||||
undo the most previous operation to one cell only. The 'Revert' button is
|
undo the most previous operation to one cell only. The 'Revert' button is
|
||||||
|
@ -1441,7 +1375,7 @@ labels. Normally there will be nothing there: this indicates that there's
|
||||||
no breakpoint set at that address. You can set and clear breakpoints by
|
no breakpoint set at that address. You can set and clear breakpoints by
|
||||||
clicking in this area. When a breakpoint is set, there will be a
|
clicking in this area. When a breakpoint is set, there will be a
|
||||||
red circle in this area. These are the same breakpoints as used
|
red circle in this area. These are the same breakpoints as used
|
||||||
by the <a href="#Breakpoints">break</a> command, <b>not</b> the conditional "breakIf" breakpoints
|
by the <a href="#Breakpoints">break</a> command, <b>not</b> the conditional "breakif" breakpoints
|
||||||
(which makes sense: conditional breaks can break on any condition, the Program
|
(which makes sense: conditional breaks can break on any condition, the Program
|
||||||
Counter isn't necessarily involved).</li>
|
Counter isn't necessarily involved).</li>
|
||||||
<li><b>Labels</b>: Any labels assigned to the given address, either generated
|
<li><b>Labels</b>: Any labels assigned to the given address, either generated
|
||||||
|
@ -1539,7 +1473,7 @@ or lowercase for "illegal" 6502 instructions (like "dcp"). If automatic resolvin
|
||||||
of code sections has been disabled for any reason, you'll likely see a lot
|
of code sections has been disabled for any reason, you'll likely see a lot
|
||||||
of illegal opcodes if you scroll to a data table in ROM. This can also
|
of illegal opcodes if you scroll to a data table in ROM. This can also
|
||||||
occur if the disassembler hasn't yet encountered addresses in the PC.
|
occur if the disassembler hasn't yet encountered addresses in the PC.
|
||||||
If you step/trace/scanLine/frame advance into such an area, the disassembler
|
If you step/trace/scanline/frame advance into such an area, the disassembler
|
||||||
will make note of it, and disassemble it correctly from that point on.</p>
|
will make note of it, and disassemble it correctly from that point on.</p>
|
||||||
|
|
||||||
<!-- TODO - is this true any longer?
|
<!-- TODO - is this true any longer?
|
||||||
|
@ -1586,16 +1520,13 @@ matches the address of the disassembly line where the mouse was clicked.</li>
|
||||||
<li><b>Disassemble @ current line</b>: Disassemble from the disassembly line where the mouse was clicked.
|
<li><b>Disassemble @ current line</b>: Disassemble from the disassembly line where the mouse was clicked.
|
||||||
This allows to fill gaps in the disassembly and is most useful for bankswitched ROMs.</li>
|
This allows to fill gaps in the disassembly and is most useful for bankswitched ROMs.</li>
|
||||||
|
|
||||||
<li><b>Set timer @ current line</b>: Set a timer point using the current
|
|
||||||
disassembly line's address and bank</li>
|
|
||||||
|
|
||||||
<li><b>Show tentative code</b>: Allow DiStella to do a static analysis/disassembly.</li>
|
<li><b>Show tentative code</b>: Allow DiStella to do a static analysis/disassembly.</li>
|
||||||
|
|
||||||
<li><b>Show PC addresses</b>: Show Program Counter addresses as labels (where there
|
<li><b>Show PC addresses</b>: Show Program Counter addresses as labels (where there
|
||||||
isn't already a defined label).</li>
|
isn't already a defined label).</li>
|
||||||
|
|
||||||
<li><b>Show GFX as binary</b>: Switch between displaying/editing GFX and PGFX sections
|
<li><b>Show GFX as binary</b>: Switch between displaying/editing GFX and PGFX sections
|
||||||
in either binary or hexadecimal.</li>
|
in either binary or hexidecimal.</li>
|
||||||
|
|
||||||
<li><b>Use address relocation</b>: Corresponds to the DiStella '-r' option
|
<li><b>Use address relocation</b>: Corresponds to the DiStella '-r' option
|
||||||
(Relocate calls out of address range).</br>
|
(Relocate calls out of address range).</br>
|
||||||
|
@ -1610,7 +1541,7 @@ Note: The code will continue to run fine, but the ROM image will be altered.</li
|
||||||
<li>The ROM Widget only works on ROM or zero-page RAM separately. If your game runs
|
<li>The ROM Widget only works on ROM or zero-page RAM separately. If your game runs
|
||||||
code from zero-page RAM, the disassembly will show addresses $80 to $FF (zero-page
|
code from zero-page RAM, the disassembly will show addresses $80 to $FF (zero-page
|
||||||
RAM address space) only. Once your RAM routine returns, the ROM Widget will switch
|
RAM address space) only. Once your RAM routine returns, the ROM Widget will switch
|
||||||
back to ROM space ($1000 - $1FFF and mirrors). The same is true of the "disAsm"
|
back to ROM space ($1000 - $1FFF and mirrors). The same is true of the "disasm"
|
||||||
command; it will show either ROM or RAM space, not both at the same time.</li>
|
command; it will show either ROM or RAM space, not both at the same time.</li>
|
||||||
|
|
||||||
<li>The standard VCS memory map has the cartridge port at locations
|
<li>The standard VCS memory map has the cartridge port at locations
|
||||||
|
@ -1679,13 +1610,13 @@ space with the appropriate directive, there are times when it will fail. There a
|
||||||
several options in this case:</p>
|
several options in this case:</p>
|
||||||
<ol>
|
<ol>
|
||||||
<li><b>Manually set the directives</b>: Directives can be set in the debugger
|
<li><b>Manually set the directives</b>: Directives can be set in the debugger
|
||||||
prompt with the aud/code/col/bcol/gfx/pCol/pGfx/data/row commands. These accept an address range
|
prompt with the aud/code/col/bcol/gfx/pcol/pgfx/data/row commands. These accept an address range
|
||||||
for the given directive type. Setting a range with the same type a second time
|
for the given directive type. Setting a range with the same type a second time
|
||||||
will remove that directive from the range.</li>
|
will remove that directive from the range.</li>
|
||||||
<li><b>Use configuration files</b>: Configuration files can be used to automatically
|
<li><b>Use configuration files</b>: Configuration files can be used to automatically
|
||||||
load a list of directives when a ROM is loaded. These files can be generated with the
|
load a list of directives when a ROM is loaded. These files can be generated with the
|
||||||
'saveConfig' command, and loaded with the 'loadConfig' command. There are also
|
'saveconfig' command, and loaded with the 'loadconfig' command. There are also
|
||||||
'listConfig' and 'clearConfig' commands to show and erase (respectively) the current
|
'listconfig' and 'clearconfig' commands to show and erase (respectively) the current
|
||||||
directive listing. Upon opening the debugger for the first time, Stella attempts
|
directive listing. Upon opening the debugger for the first time, Stella attempts
|
||||||
to load a configuration file from the folder containing the ROM. Assuming a ROM named "rr.a26" exists, the config file must be named <i>rr.cfg</i>.
|
to load a configuration file from the folder containing the ROM. Assuming a ROM named "rr.a26" exists, the config file must be named <i>rr.cfg</i>.
|
||||||
</ul>
|
</ul>
|
||||||
|
@ -1758,7 +1689,7 @@ but it helps to know at least a little about 6502 programming.</p>
|
||||||
(for that, we have to disable the collision checking code, which means
|
(for that, we have to disable the collision checking code, which means
|
||||||
we have to find and understand it first!)</li>
|
we have to find and understand it first!)</li>
|
||||||
|
|
||||||
<li>Set a Write Trap on the lives counter address: "trapWrite $ba"
|
<li>Set a Write Trap on the lives counter address: "trapwrite $ba"
|
||||||
in the Prompt. Exit the debugger and play until you get killed. When
|
in the Prompt. Exit the debugger and play until you get killed. When
|
||||||
you die, the trap will cause the emulator to enter the debugger with the
|
you die, the trap will cause the emulator to enter the debugger with the
|
||||||
Program Counter pointing to the instruction *after* the one that wrote
|
Program Counter pointing to the instruction *after* the one that wrote
|
||||||
|
@ -1806,7 +1737,7 @@ but it helps to know at least a little about 6502 programming.</p>
|
||||||
will *still* see 3 lives: Success! We've hacked Battlezone to give us
|
will *still* see 3 lives: Success! We've hacked Battlezone to give us
|
||||||
infinite lives.</li>
|
infinite lives.</li>
|
||||||
|
|
||||||
<li>Save your work. In the prompt: "saveRom". You now
|
<li>Save your work. In the prompt: "saverom". You now
|
||||||
have your very own infinite-lives version of Battlezone. The file will
|
have your very own infinite-lives version of Battlezone. The file will
|
||||||
be saved in your HOME directory (NOT your ROM directory), so you might
|
be saved in your HOME directory (NOT your ROM directory), so you might
|
||||||
want to move it to your ROM directory if it isn't the current directory.
|
want to move it to your ROM directory if it isn't the current directory.
|
||||||
|
|
Before Width: | Height: | Size: 18 KiB After Width: | Height: | Size: 18 KiB |
Before Width: | Height: | Size: 2.1 KiB After Width: | Height: | Size: 2.8 KiB |
Before Width: | Height: | Size: 2.3 KiB After Width: | Height: | Size: 2.3 KiB |
Before Width: | Height: | Size: 5.2 KiB After Width: | Height: | Size: 5.0 KiB |
Before Width: | Height: | Size: 64 KiB After Width: | Height: | Size: 63 KiB |
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 8.5 KiB |
Before Width: | Height: | Size: 4.5 KiB After Width: | Height: | Size: 4.4 KiB |
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 1.7 KiB |
Before Width: | Height: | Size: 4.9 KiB After Width: | Height: | Size: 4.5 KiB |
Before Width: | Height: | Size: 3.2 KiB After Width: | Height: | Size: 3.1 KiB |
Before Width: | Height: | Size: 4.4 KiB After Width: | Height: | Size: 4.3 KiB |
Before Width: | Height: | Size: 4.1 KiB After Width: | Height: | Size: 4.0 KiB |
Before Width: | Height: | Size: 28 KiB After Width: | Height: | Size: 14 KiB |
Before Width: | Height: | Size: 3.0 KiB After Width: | Height: | Size: 3.0 KiB |
Before Width: | Height: | Size: 4.5 KiB After Width: | Height: | Size: 4.1 KiB |
Before Width: | Height: | Size: 8.9 KiB After Width: | Height: | Size: 8.9 KiB |
Before Width: | Height: | Size: 380 B |
Before Width: | Height: | Size: 187 B |
Before Width: | Height: | Size: 2.0 KiB After Width: | Height: | Size: 2.0 KiB |
Before Width: | Height: | Size: 4.0 KiB After Width: | Height: | Size: 3.9 KiB |
Before Width: | Height: | Size: 2.9 KiB |
Before Width: | Height: | Size: 6.5 KiB After Width: | Height: | Size: 5.1 KiB |
Before Width: | Height: | Size: 3.2 KiB After Width: | Height: | Size: 3.1 KiB |
Before Width: | Height: | Size: 6.4 KiB After Width: | Height: | Size: 5.0 KiB |
Before Width: | Height: | Size: 4.3 KiB After Width: | Height: | Size: 3.6 KiB |
Before Width: | Height: | Size: 3.4 KiB After Width: | Height: | Size: 3.4 KiB |
Before Width: | Height: | Size: 4.3 KiB After Width: | Height: | Size: 4.1 KiB |
Before Width: | Height: | Size: 3.5 KiB After Width: | Height: | Size: 3.4 KiB |
Before Width: | Height: | Size: 3.8 KiB After Width: | Height: | Size: 3.4 KiB |
Before Width: | Height: | Size: 2.8 KiB After Width: | Height: | Size: 2.7 KiB |
Before Width: | Height: | Size: 4.4 KiB After Width: | Height: | Size: 4.4 KiB |
Before Width: | Height: | Size: 3.6 KiB After Width: | Height: | Size: 3.5 KiB |
Before Width: | Height: | Size: 3.5 KiB After Width: | Height: | Size: 3.5 KiB |
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 1.4 KiB |
Before Width: | Height: | Size: 4.7 KiB After Width: | Height: | Size: 4.2 KiB |
Before Width: | Height: | Size: 3.7 KiB After Width: | Height: | Size: 3.7 KiB |
Before Width: | Height: | Size: 4.2 KiB After Width: | Height: | Size: 4.2 KiB |
Before Width: | Height: | Size: 5.7 KiB After Width: | Height: | Size: 5.7 KiB |
Before Width: | Height: | Size: 3.8 KiB After Width: | Height: | Size: 3.5 KiB |
Before Width: | Height: | Size: 3.5 KiB After Width: | Height: | Size: 3.5 KiB |
After Width: | Height: | Size: 4.7 KiB |
Before Width: | Height: | Size: 9.6 KiB After Width: | Height: | Size: 9.6 KiB |
Before Width: | Height: | Size: 4.0 KiB After Width: | Height: | Size: 3.7 KiB |
Before Width: | Height: | Size: 194 B |
Before Width: | Height: | Size: 2.2 KiB After Width: | Height: | Size: 3.0 KiB |
Before Width: | Height: | Size: 30 KiB After Width: | Height: | Size: 44 KiB |
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 36 KiB |
Before Width: | Height: | Size: 42 KiB After Width: | Height: | Size: 74 KiB |
Before Width: | Height: | Size: 218 B |
Before Width: | Height: | Size: 171 B |
Before Width: | Height: | Size: 196 B |
1898
docs/index.html
|
@ -58,7 +58,7 @@
|
||||||
|
|
||||||
<center><h1>Stella for RetroN 77</h1></center>
|
<center><h1>Stella for RetroN 77</h1></center>
|
||||||
<center><h2>Atari 2600 VCS emulator</h2></center>
|
<center><h2>Atari 2600 VCS emulator</h2></center>
|
||||||
<center>Release 7.0</center>
|
<center>Release 6.5.2</center>
|
||||||
<center><h2>Quick Navigation Guide</h2></center>
|
<center><h2>Quick Navigation Guide</h2></center>
|
||||||
<br/>
|
<br/>
|
||||||
|
|
||||||
|
@ -77,7 +77,7 @@
|
||||||
<tr>
|
<tr>
|
||||||
<th width=110px>Joystick</th>
|
<th width=110px>Joystick</th>
|
||||||
<th width=100px>Button</th>
|
<th width=100px>Button</th>
|
||||||
<th width=200px>Action</th>
|
<th width=170px>Action</th>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>Button 4</td>
|
<td>Button 4</td>
|
||||||
|
@ -95,17 +95,17 @@
|
||||||
<td>Open settings</td>
|
<td>Open settings</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>Button 8</td>
|
<td>Button 7</td>
|
||||||
<td>-</td>
|
<td>-</td>
|
||||||
<td>Rewind game</td>
|
<td>Rewind game</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>Button 9</td>
|
<td>Button 8</td>
|
||||||
<td>MODE</td>
|
<td>MODE</td>
|
||||||
<td>Select</td>
|
<td>Select</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>Button 10</td>
|
<td>Button 9</td>
|
||||||
<td>RESET</td>
|
<td>RESET</td>
|
||||||
<td>Reset</td>
|
<td>Reset</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
@ -119,7 +119,7 @@
|
||||||
<tr>
|
<tr>
|
||||||
<th width=110px>Joystick</th>
|
<th width=110px>Joystick</th>
|
||||||
<th width=100px>Button</th>
|
<th width=100px>Button</th>
|
||||||
<th width=200px>Action</th>
|
<th width=170px>Action</th>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>Up</td>
|
<td>Up</td>
|
||||||
|
@ -147,40 +147,10 @@
|
||||||
<td>Start selected game</td>
|
<td>Start selected game</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>Hold Button 1</td>
|
<td>Button 2 or</br>hold Button 1</td>
|
||||||
<td>-</td>
|
|
||||||
<td>Open a context menu with the following choices:
|
|
||||||
<ul>
|
|
||||||
<li>Add to favorites</li>
|
|
||||||
<li>Power-On options...</li>
|
|
||||||
<li>Go to initial directory</li>
|
|
||||||
<li>Go to parent directory</li>
|
|
||||||
<li><a href="#Settings">Settings...</a></li>
|
|
||||||
</ul>
|
|
||||||
Button 2 or 6 close the menu without any action.
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>Button 1 + Left</td>
|
|
||||||
<td>-</td>
|
|
||||||
<td>Display previous image</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>Button 1 + Right</td>
|
|
||||||
<td>-</td>
|
|
||||||
<td>Display next image</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>Button 1 + Up</td>
|
|
||||||
<td>-</td>
|
|
||||||
<td>Toggle image zoom</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>Button 2</td>
|
|
||||||
<td>SKILL P2</td>
|
<td>SKILL P2</td>
|
||||||
<td>Open Power-On options</td>
|
<td>Open Power-On options</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
||||||
<tr>
|
<tr>
|
||||||
<td>Button 4</td>
|
<td>Button 4</td>
|
||||||
<td>COLOR, B/W</td>
|
<td>COLOR, B/W</td>
|
||||||
|
@ -196,7 +166,7 @@
|
||||||
<tr>
|
<tr>
|
||||||
<th width=110px>Joystick</th>
|
<th width=110px>Joystick</th>
|
||||||
<th width=100px>Button</th>
|
<th width=100px>Button</th>
|
||||||
<th width=200px>Action</th>
|
<th width=170px>Action</th>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>Up</td>
|
<td>Up</td>
|
||||||
|
@ -264,7 +234,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="graphics/commandsmenu_r77.png"></p></td>
|
<td><p><img src="commandsmenu_r77.png"></p></td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
</p>
|
</p>
|
||||||
|
@ -309,7 +279,7 @@
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
</td>
|
</td>
|
||||||
<td><p><img src="graphics/basic_settings.png"></p></td>
|
<td><p><img src="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-2025 by Bradford W. Mott, Stephen Anthony
|
// Copyright (c) 1995-2021 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
|
||||||
|
@ -21,19 +21,19 @@
|
||||||
#include "BankRomCheat.hxx"
|
#include "BankRomCheat.hxx"
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
BankRomCheat::BankRomCheat(OSystem& os, string_view name, string_view code)
|
BankRomCheat::BankRomCheat(OSystem& os, const string& name, const string& code)
|
||||||
: Cheat(os, name, code)
|
: Cheat(os, name, code)
|
||||||
{
|
{
|
||||||
if(myCode.length() == 7)
|
if(myCode.length() == 7)
|
||||||
myCode = "0" + string{code};
|
myCode = "0" + code;
|
||||||
|
|
||||||
bank = BSPF::stoi<16>(myCode.substr(0, 2));
|
bank = unhex(myCode.substr(0, 2));
|
||||||
address = 0xf000 + BSPF::stoi<16>(myCode.substr(2, 3));
|
address = 0xf000 + unhex(myCode.substr(2, 3));
|
||||||
value = static_cast<uInt8>(BSPF::stoi<16>(myCode.substr(5, 2)));
|
value = uInt8(unhex(myCode.substr(5, 2)));
|
||||||
count = static_cast<uInt8>(BSPF::stoi<16>(myCode.substr(7, 1)) + 1);
|
count = uInt8(unhex(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; std::cmp_less(i, count); ++i)
|
for(int i = 0; i < count; ++i)
|
||||||
savedRom[i] = myOSystem.console().cartridge().peek(address + i);
|
savedRom[i] = myOSystem.console().cartridge().peek(address + i);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -47,11 +47,11 @@ bool BankRomCheat::enable()
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
bool BankRomCheat::disable()
|
bool BankRomCheat::disable()
|
||||||
{
|
{
|
||||||
const int oldBank = myOSystem.console().cartridge().getBank(address);
|
int oldBank = myOSystem.console().cartridge().getBank(address);
|
||||||
myOSystem.console().cartridge().bank(bank);
|
myOSystem.console().cartridge().bank(bank);
|
||||||
|
|
||||||
for(int i = 0; std::cmp_less(i, count); ++i)
|
for(int i = 0; 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);
|
||||||
|
|
||||||
|
@ -63,10 +63,10 @@ void BankRomCheat::evaluate()
|
||||||
{
|
{
|
||||||
if(!myEnabled)
|
if(!myEnabled)
|
||||||
{
|
{
|
||||||
const int oldBank = myOSystem.console().cartridge().getBank(address);
|
int oldBank = myOSystem.console().cartridge().getBank(address);
|
||||||
myOSystem.console().cartridge().bank(bank);
|
myOSystem.console().cartridge().bank(bank);
|
||||||
|
|
||||||
for(int i = 0; std::cmp_less(i, count); ++i)
|
for(int i = 0; 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-2025 by Bradford W. Mott, Stephen Anthony
|
// Copyright (c) 1995-2021 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
|
||||||
|
@ -23,7 +23,7 @@
|
||||||
class BankRomCheat : public Cheat
|
class BankRomCheat : public Cheat
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
BankRomCheat(OSystem& os, string_view name, string_view code);
|
BankRomCheat(OSystem& os, const string& name, const string& code);
|
||||||
~BankRomCheat() override = default;
|
~BankRomCheat() override = default;
|
||||||
|
|
||||||
bool enable() override;
|
bool enable() override;
|
||||||
|
@ -31,7 +31,7 @@ class BankRomCheat : public Cheat
|
||||||
void evaluate() override;
|
void evaluate() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::array<uInt8, 16> savedRom{};
|
std::array<uInt8, 16> savedRom;
|
||||||
uInt16 address{0};
|
uInt16 address{0};
|
||||||
uInt8 value{0};
|
uInt8 value{0};
|
||||||
uInt8 count{0};
|
uInt8 count{0};
|
||||||
|
|
|
@ -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-2025 by Bradford W. Mott, Stephen Anthony
|
// Copyright (c) 1995-2021 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,9 +25,9 @@ class OSystem;
|
||||||
class Cheat
|
class Cheat
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Cheat(OSystem& osystem, string_view name, string_view code)
|
Cheat(OSystem& osystem, const string& name, const string& code)
|
||||||
: myOSystem{osystem},
|
: myOSystem{osystem},
|
||||||
myName{name.empty() ? code : name},
|
myName{name == "" ? code : name},
|
||||||
myCode{code} { }
|
myCode{code} { }
|
||||||
virtual ~Cheat() = default;
|
virtual ~Cheat() = default;
|
||||||
|
|
||||||
|
@ -40,6 +40,23 @@ class Cheat
|
||||||
|
|
||||||
virtual void evaluate() = 0;
|
virtual void evaluate() = 0;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
static uInt16 unhex(const string& hex)
|
||||||
|
{
|
||||||
|
int ret = 0;
|
||||||
|
for(char c: hex)
|
||||||
|
{
|
||||||
|
ret *= 16;
|
||||||
|
if(c >= '0' && c <= '9')
|
||||||
|
ret += c - '0';
|
||||||
|
else if(c >= 'A' && c <= 'F')
|
||||||
|
ret += c - 'A' + 10;
|
||||||
|
else
|
||||||
|
ret += c - 'a' + 10;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
OSystem& myOSystem;
|
OSystem& myOSystem;
|
||||||
|
|
||||||
|
|
|
@ -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-2025 by Bradford W. Mott, Stephen Anthony
|
// Copyright (c) 1995-2021 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,6 +25,7 @@
|
||||||
#include "Font.hxx"
|
#include "Font.hxx"
|
||||||
#include "InputTextDialog.hxx"
|
#include "InputTextDialog.hxx"
|
||||||
#include "OSystem.hxx"
|
#include "OSystem.hxx"
|
||||||
|
#include "Props.hxx"
|
||||||
#include "Widget.hxx"
|
#include "Widget.hxx"
|
||||||
|
|
||||||
#include "CheatCodeDialog.hxx"
|
#include "CheatCodeDialog.hxx"
|
||||||
|
@ -42,15 +43,16 @@ CheatCodeDialog::CheatCodeDialog(OSystem& osystem, DialogContainer& parent,
|
||||||
VGAP = Dialog::vGap(),
|
VGAP = Dialog::vGap(),
|
||||||
VBORDER = Dialog::vBorder(),
|
VBORDER = Dialog::vBorder(),
|
||||||
HBORDER = Dialog::hBorder();
|
HBORDER = Dialog::hBorder();
|
||||||
|
int xpos, ypos;
|
||||||
WidgetArray wid;
|
WidgetArray wid;
|
||||||
ButtonWidget* b = nullptr;
|
ButtonWidget* b;
|
||||||
|
|
||||||
// Set real dimensions
|
// Set real dimensions
|
||||||
_w = 45 * fontWidth + HBORDER * 2;
|
_w = 45 * fontWidth + HBORDER * 2;
|
||||||
_h = _th + 11 * (lineHeight + 4) + VBORDER * 2;
|
_h = _th + 11 * (lineHeight + 4) + VBORDER * 2;
|
||||||
|
|
||||||
// List of cheats, with checkboxes to enable/disable
|
// List of cheats, with checkboxes to enable/disable
|
||||||
int xpos = HBORDER, ypos = _th + VBORDER;
|
xpos = HBORDER; ypos = _th + VBORDER;
|
||||||
myCheatList =
|
myCheatList =
|
||||||
new CheckListWidget(this, font, xpos, ypos, _w - buttonWidth - HBORDER * 2 - fontWidth,
|
new CheckListWidget(this, font, xpos, ypos, _w - buttonWidth - HBORDER * 2 - fontWidth,
|
||||||
_h - _th - buttonHeight - VBORDER * 3);
|
_h - _th - buttonHeight - VBORDER * 3);
|
||||||
|
@ -82,18 +84,18 @@ CheatCodeDialog::CheatCodeDialog(OSystem& osystem, DialogContainer& parent,
|
||||||
|
|
||||||
// Inputbox which will pop up when adding/editing a cheat
|
// Inputbox which will pop up when adding/editing a cheat
|
||||||
StringList labels;
|
StringList labels;
|
||||||
labels.emplace_back("Name ");
|
labels.push_back("Name ");
|
||||||
labels.emplace_back("Code (hex) ");
|
labels.push_back("Code (hex) ");
|
||||||
myCheatInput = make_unique<InputTextDialog>(this, font, labels, "Cheat code");
|
myCheatInput = make_unique<InputTextDialog>(this, font, labels, "Cheat code");
|
||||||
myCheatInput->setTarget(this);
|
myCheatInput->setTarget(this);
|
||||||
|
|
||||||
// Add filtering for each textfield
|
// Add filtering for each textfield
|
||||||
const EditableWidget::TextFilter f0 = [](char c) {
|
EditableWidget::TextFilter f0 = [](char c) {
|
||||||
return isprint(c) && c != '\"' && c != ':';
|
return isprint(c) && c != '\"' && c != ':';
|
||||||
};
|
};
|
||||||
myCheatInput->setTextFilter(f0, 0);
|
myCheatInput->setTextFilter(f0, 0);
|
||||||
|
|
||||||
const EditableWidget::TextFilter f1 = [](char c) {
|
EditableWidget::TextFilter f1 = [](char c) {
|
||||||
return (c >= 'a' && c <= 'f') || (c >= '0' && c <= '9');
|
return (c >= 'a' && c <= 'f') || (c >= '0' && c <= '9');
|
||||||
};
|
};
|
||||||
myCheatInput->setTextFilter(f1, 1);
|
myCheatInput->setTextFilter(f1, 1);
|
||||||
|
@ -105,12 +107,10 @@ CheatCodeDialog::CheatCodeDialog(OSystem& osystem, DialogContainer& parent,
|
||||||
wid.clear();
|
wid.clear();
|
||||||
addOKCancelBGroup(wid, font);
|
addOKCancelBGroup(wid, font);
|
||||||
addBGroupToFocusList(wid);
|
addBGroupToFocusList(wid);
|
||||||
|
|
||||||
setHelpAnchor("Cheats");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
CheatCodeDialog::~CheatCodeDialog() // NOLINT (we need an empty d'tor)
|
CheatCodeDialog::~CheatCodeDialog()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -127,14 +127,14 @@ void CheatCodeDialog::loadConfig()
|
||||||
for(const auto& c: list)
|
for(const auto& c: list)
|
||||||
{
|
{
|
||||||
l.push_back(c->name());
|
l.push_back(c->name());
|
||||||
b.push_back(c->enabled());
|
b.push_back(bool(c->enabled()));
|
||||||
}
|
}
|
||||||
myCheatList->setList(l, b);
|
myCheatList->setList(l, b);
|
||||||
|
|
||||||
// Redraw the list, auto-selecting the first item if possible
|
// Redraw the list, auto-selecting the first item if possible
|
||||||
myCheatList->setSelected(!l.empty() ? 0 : -1);
|
myCheatList->setSelected(l.size() > 0 ? 0 : -1);
|
||||||
|
|
||||||
const bool enabled = !list.empty();
|
bool enabled = (list.size() > 0);
|
||||||
myEditButton->setEnabled(enabled);
|
myEditButton->setEnabled(enabled);
|
||||||
myRemoveButton->setEnabled(enabled);
|
myRemoveButton->setEnabled(enabled);
|
||||||
}
|
}
|
||||||
|
@ -167,7 +167,7 @@ void CheatCodeDialog::addCheat()
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
void CheatCodeDialog::editCheat()
|
void CheatCodeDialog::editCheat()
|
||||||
{
|
{
|
||||||
const int idx = myCheatList->getSelected();
|
int idx = myCheatList->getSelected();
|
||||||
if(idx < 0)
|
if(idx < 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -232,7 +232,7 @@ void CheatCodeDialog::handleCommand(CommandSender* sender, int cmd,
|
||||||
{
|
{
|
||||||
const string& name = myCheatInput->getResult(0);
|
const string& name = myCheatInput->getResult(0);
|
||||||
const string& code = myCheatInput->getResult(1);
|
const string& code = myCheatInput->getResult(1);
|
||||||
if(CheatManager::isValidCode(code))
|
if(instance().cheat().isValidCode(code))
|
||||||
{
|
{
|
||||||
myCheatInput->close();
|
myCheatInput->close();
|
||||||
instance().cheat().add(name, code);
|
instance().cheat().add(name, code);
|
||||||
|
@ -247,9 +247,9 @@ void CheatCodeDialog::handleCommand(CommandSender* sender, int cmd,
|
||||||
{
|
{
|
||||||
const string& name = myCheatInput->getResult(0);
|
const string& name = myCheatInput->getResult(0);
|
||||||
const string& code = myCheatInput->getResult(1);
|
const string& code = myCheatInput->getResult(1);
|
||||||
const bool enable = myCheatList->getSelectedState();
|
bool enable = myCheatList->getSelectedState();
|
||||||
const int idx = myCheatList->getSelected();
|
int idx = myCheatList->getSelected();
|
||||||
if(CheatManager::isValidCode(code))
|
if(instance().cheat().isValidCode(code))
|
||||||
{
|
{
|
||||||
myCheatInput->close();
|
myCheatInput->close();
|
||||||
instance().cheat().add(name, code, enable, idx);
|
instance().cheat().add(name, code, enable, idx);
|
||||||
|
@ -272,7 +272,7 @@ void CheatCodeDialog::handleCommand(CommandSender* sender, int cmd,
|
||||||
{
|
{
|
||||||
const string& name = myCheatInput->getResult(0);
|
const string& name = myCheatInput->getResult(0);
|
||||||
const string& code = myCheatInput->getResult(1);
|
const string& code = myCheatInput->getResult(1);
|
||||||
if(CheatManager::isValidCode(code))
|
if(instance().cheat().isValidCode(code))
|
||||||
{
|
{
|
||||||
myCheatInput->close();
|
myCheatInput->close();
|
||||||
instance().cheat().addOneShot(name, code);
|
instance().cheat().addOneShot(name, code);
|
||||||
|
|
|
@ -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-2025 by Bradford W. Mott, Stephen Anthony
|
// Copyright (c) 1995-2021 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-2025 by Bradford W. Mott, Stephen Anthony
|
// Copyright (c) 1995-2021 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
|
||||||
|
@ -16,6 +16,7 @@
|
||||||
//============================================================================
|
//============================================================================
|
||||||
|
|
||||||
#include "OSystem.hxx"
|
#include "OSystem.hxx"
|
||||||
|
#include "Console.hxx"
|
||||||
#include "Cheat.hxx"
|
#include "Cheat.hxx"
|
||||||
#include "Settings.hxx"
|
#include "Settings.hxx"
|
||||||
#include "CheetahCheat.hxx"
|
#include "CheetahCheat.hxx"
|
||||||
|
@ -32,10 +33,10 @@ CheatManager::CheatManager(OSystem& osystem)
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
bool CheatManager::add(string_view name, string_view code,
|
bool CheatManager::add(const string& name, const string& code,
|
||||||
bool enable, int idx)
|
bool enable, int idx)
|
||||||
{
|
{
|
||||||
const shared_ptr<Cheat> cheat = createCheat(name, code);
|
shared_ptr<Cheat> cheat = createCheat(name, code);
|
||||||
if(!cheat)
|
if(!cheat)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
@ -67,7 +68,7 @@ bool CheatManager::add(string_view name, string_view code,
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
void CheatManager::remove(int idx)
|
void CheatManager::remove(int idx)
|
||||||
{
|
{
|
||||||
if(static_cast<size_t>(idx) < myCheatList.size())
|
if(uInt32(idx) < myCheatList.size())
|
||||||
{
|
{
|
||||||
// This will also remove it from the per-frame list (if applicable)
|
// This will also remove it from the per-frame list (if applicable)
|
||||||
myCheatList[idx]->disable();
|
myCheatList[idx]->disable();
|
||||||
|
@ -78,7 +79,7 @@ void CheatManager::remove(int idx)
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
void CheatManager::addPerFrame(string_view name, string_view code, bool enable)
|
void CheatManager::addPerFrame(const string& name, const string& code, bool enable)
|
||||||
{
|
{
|
||||||
// The actual cheat will always be in the main list; we look there first
|
// The actual cheat will always be in the main list; we look there first
|
||||||
shared_ptr<Cheat> cheat;
|
shared_ptr<Cheat> cheat;
|
||||||
|
@ -92,8 +93,8 @@ void CheatManager::addPerFrame(string_view name, string_view code, bool enable)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Make sure there are no duplicates
|
// Make sure there are no duplicates
|
||||||
bool found{false};
|
bool found = false;
|
||||||
uInt32 i{0};
|
uInt32 i;
|
||||||
for(i = 0; i < myPerFrameList.size(); ++i)
|
for(i = 0; i < myPerFrameList.size(); ++i)
|
||||||
{
|
{
|
||||||
if(myPerFrameList[i]->code() == cheat->code())
|
if(myPerFrameList[i]->code() == cheat->code())
|
||||||
|
@ -116,16 +117,16 @@ void CheatManager::addPerFrame(string_view name, string_view code, bool enable)
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
void CheatManager::addOneShot(string_view name, string_view code)
|
void CheatManager::addOneShot(const string& name, const string& code)
|
||||||
{
|
{
|
||||||
// Evaluate this cheat once, and then immediately discard it
|
// Evaluate this cheat once, and then immediately discard it
|
||||||
const shared_ptr<Cheat> cheat = createCheat(name, code);
|
shared_ptr<Cheat> cheat = createCheat(name, code);
|
||||||
if(cheat)
|
if(cheat)
|
||||||
cheat->evaluate();
|
cheat->evaluate();
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
shared_ptr<Cheat> CheatManager::createCheat(string_view name, string_view code) const
|
shared_ptr<Cheat> CheatManager::createCheat(const string& name, const string& code) const
|
||||||
{
|
{
|
||||||
if(!isValidCode(code))
|
if(!isValidCode(code))
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
@ -135,14 +136,14 @@ shared_ptr<Cheat> CheatManager::createCheat(string_view name, string_view code)
|
||||||
{
|
{
|
||||||
case 4: return make_shared<RamCheat>(myOSystem, name, code);
|
case 4: return make_shared<RamCheat>(myOSystem, name, code);
|
||||||
case 6: return make_shared<CheetahCheat>(myOSystem, name, code);
|
case 6: return make_shared<CheetahCheat>(myOSystem, name, code);
|
||||||
case 7: [[fallthrough]];
|
case 7: return make_shared<BankRomCheat>(myOSystem, name, code);
|
||||||
case 8: return make_shared<BankRomCheat>(myOSystem, name, code);
|
case 8: return make_shared<BankRomCheat>(myOSystem, name, code);
|
||||||
default: return nullptr;
|
default: return nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
void CheatManager::parse(string_view cheats)
|
void CheatManager::parse(const string& cheats)
|
||||||
{
|
{
|
||||||
StringList s;
|
StringList s;
|
||||||
string::size_type lastPos = cheats.find_first_not_of(',', 0);
|
string::size_type lastPos = cheats.find_first_not_of(',', 0);
|
||||||
|
@ -185,9 +186,6 @@ void CheatManager::parse(string_view cheats)
|
||||||
code = s[1];
|
code = s[1];
|
||||||
add(name, code, s[2] == "1");
|
add(name, code, s[2] == "1");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
s.clear();
|
s.clear();
|
||||||
|
|
||||||
|
@ -197,7 +195,7 @@ void CheatManager::parse(string_view cheats)
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
void CheatManager::enable(string_view code, bool enable)
|
void CheatManager::enable(const string& code, bool enable)
|
||||||
{
|
{
|
||||||
for(const auto& cheat: myCheatList)
|
for(const auto& cheat: myCheatList)
|
||||||
{
|
{
|
||||||
|
@ -220,17 +218,18 @@ void CheatManager::loadCheatDatabase()
|
||||||
catch(...) { return; }
|
catch(...) { return; }
|
||||||
|
|
||||||
string line, md5, cheat;
|
string line, md5, cheat;
|
||||||
|
string::size_type one, two, three, four;
|
||||||
|
|
||||||
// Loop reading cheats
|
// Loop reading cheats
|
||||||
while(getline(in, line))
|
while(getline(in, line))
|
||||||
{
|
{
|
||||||
if(line.empty())
|
if(line.length() == 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
const string::size_type one = line.find('\"', 0);
|
one = line.find('\"', 0);
|
||||||
const string::size_type two = line.find('\"', one + 1);
|
two = line.find('\"', one + 1);
|
||||||
const string::size_type three = line.find('\"', two + 1);
|
three = line.find('\"', two + 1);
|
||||||
const string::size_type four = line.find('\"', three + 1);
|
four = line.find('\"', three + 1);
|
||||||
|
|
||||||
// Invalid line if it doesn't contain 4 quotes
|
// Invalid line if it doesn't contain 4 quotes
|
||||||
if((one == string::npos) || (two == string::npos) ||
|
if((one == string::npos) || (two == string::npos) ||
|
||||||
|
@ -255,14 +254,14 @@ void CheatManager::saveCheatDatabase()
|
||||||
|
|
||||||
stringstream out;
|
stringstream out;
|
||||||
for(const auto& [md5, cheat]: myCheatMap)
|
for(const auto& [md5, cheat]: myCheatMap)
|
||||||
out << "\"" << md5 << "\" " << "\"" << cheat << "\"\n";
|
out << "\"" << md5 << "\" " << "\"" << cheat << "\"" << endl;
|
||||||
|
|
||||||
try { myOSystem.cheatFile().write(out); }
|
try { myOSystem.cheatFile().write(out); }
|
||||||
catch(...) { return; }
|
catch(...) { return; }
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
void CheatManager::loadCheats(string_view md5sum)
|
void CheatManager::loadCheats(const string& md5sum)
|
||||||
{
|
{
|
||||||
myPerFrameList.clear();
|
myPerFrameList.clear();
|
||||||
myCheatList.clear();
|
myCheatList.clear();
|
||||||
|
@ -271,11 +270,11 @@ void CheatManager::loadCheats(string_view md5sum)
|
||||||
// Set up any cheatcodes that was on the command line
|
// Set up any cheatcodes that was on the command line
|
||||||
// (and remove the key from the settings, so they won't get set again)
|
// (and remove the key from the settings, so they won't get set again)
|
||||||
const string& cheats = myOSystem.settings().getString("cheat");
|
const string& cheats = myOSystem.settings().getString("cheat");
|
||||||
if(!cheats.empty())
|
if(cheats != "")
|
||||||
myOSystem.settings().setValue("cheat", "");
|
myOSystem.settings().setValue("cheat", "");
|
||||||
|
|
||||||
const auto& iter = myCheatMap.find(md5sum);
|
const auto& iter = myCheatMap.find(md5sum);
|
||||||
if(iter == myCheatMap.end() && cheats.empty())
|
if(iter == myCheatMap.end() && cheats == "")
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Remember the cheats for this ROM
|
// Remember the cheats for this ROM
|
||||||
|
@ -286,7 +285,7 @@ void CheatManager::loadCheats(string_view md5sum)
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
void CheatManager::saveCheats(string_view md5sum)
|
void CheatManager::saveCheats(const string& md5sum)
|
||||||
{
|
{
|
||||||
ostringstream cheats;
|
ostringstream cheats;
|
||||||
for(uInt32 i = 0; i < myCheatList.size(); ++i)
|
for(uInt32 i = 0; i < myCheatList.size(); ++i)
|
||||||
|
@ -298,20 +297,20 @@ void CheatManager::saveCheats(string_view md5sum)
|
||||||
cheats << ",";
|
cheats << ",";
|
||||||
}
|
}
|
||||||
|
|
||||||
const bool changed = cheats.view() != myCurrentCheat;
|
bool changed = cheats.str() != myCurrentCheat;
|
||||||
|
|
||||||
// Only update the list if absolutely necessary
|
// Only update the list if absolutely necessary
|
||||||
if(changed)
|
if(changed)
|
||||||
{
|
{
|
||||||
const auto iter = myCheatMap.find(md5sum);
|
auto iter = myCheatMap.find(md5sum);
|
||||||
|
|
||||||
// Erase old entry and add a new one only if it's changed
|
// Erase old entry and add a new one only if it's changed
|
||||||
if(iter != myCheatMap.end())
|
if(iter != myCheatMap.end())
|
||||||
myCheatMap.erase(iter);
|
myCheatMap.erase(iter);
|
||||||
|
|
||||||
// Add new entry only if there are any cheats defined
|
// Add new entry only if there are any cheats defined
|
||||||
if(!cheats.view().empty())
|
if(cheats.str() != "")
|
||||||
myCheatMap.emplace(md5sum, cheats.view());
|
myCheatMap.emplace(md5sum, cheats.str());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update the dirty flag
|
// Update the dirty flag
|
||||||
|
@ -321,12 +320,12 @@ void CheatManager::saveCheats(string_view md5sum)
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
bool CheatManager::isValidCode(string_view code)
|
bool CheatManager::isValidCode(const string& code) const
|
||||||
{
|
{
|
||||||
for(const auto c: code)
|
for(char c: code)
|
||||||
if(!isxdigit(c))
|
if(!isxdigit(c))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
const size_t length = code.length();
|
uInt32 length = uInt32(code.length());
|
||||||
return (length == 4 || length == 6 || length == 7 || length == 8);
|
return (length == 4 || length == 6 || length == 7 || length == 8);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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-2025 by Bradford W. Mott, Stephen Anthony
|
// Copyright (c) 1995-2021 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
|
||||||
|
@ -38,7 +38,6 @@ class CheatManager
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
explicit CheatManager(OSystem& osystem);
|
explicit CheatManager(OSystem& osystem);
|
||||||
~CheatManager() = default;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Adds the specified cheat to an internal list.
|
Adds the specified cheat to an internal list.
|
||||||
|
@ -50,7 +49,7 @@ class CheatManager
|
||||||
|
|
||||||
@return Whether the cheat was created and enabled.
|
@return Whether the cheat was created and enabled.
|
||||||
*/
|
*/
|
||||||
bool add(string_view name, string_view code,
|
bool add(const string& name, const string& code,
|
||||||
bool enable = true, int idx = -1);
|
bool enable = true, int idx = -1);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -69,7 +68,7 @@ class CheatManager
|
||||||
@param code The actual cheatcode
|
@param code The actual cheatcode
|
||||||
@param enable Add or remove the cheat to the per-frame list
|
@param enable Add or remove the cheat to the per-frame list
|
||||||
*/
|
*/
|
||||||
void addPerFrame(string_view name, string_view code, bool enable);
|
void addPerFrame(const string& name, const string& code, bool enable);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Creates and enables a one-shot cheat. One-shot cheats are the
|
Creates and enables a one-shot cheat. One-shot cheats are the
|
||||||
|
@ -79,7 +78,7 @@ class CheatManager
|
||||||
@param name Name of the cheat (not absolutely required)
|
@param name Name of the cheat (not absolutely required)
|
||||||
@param code The actual cheatcode (in hex)
|
@param code The actual cheatcode (in hex)
|
||||||
*/
|
*/
|
||||||
void addOneShot(string_view name, string_view code);
|
void addOneShot(const string& name, const string& code);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Enable/disabled the cheat specified by the given code.
|
Enable/disabled the cheat specified by the given code.
|
||||||
|
@ -87,7 +86,7 @@ class CheatManager
|
||||||
@param code The actual cheatcode to search for
|
@param code The actual cheatcode to search for
|
||||||
@param enable Enable/disable the cheat
|
@param enable Enable/disable the cheat
|
||||||
*/
|
*/
|
||||||
void enable(string_view code, bool enable);
|
void enable(const string& code, bool enable);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Returns the game cheatlist.
|
Returns the game cheatlist.
|
||||||
|
@ -112,17 +111,17 @@ class CheatManager
|
||||||
/**
|
/**
|
||||||
Load cheats for ROM with given MD5sum to cheatlist(s).
|
Load cheats for ROM with given MD5sum to cheatlist(s).
|
||||||
*/
|
*/
|
||||||
void loadCheats(string_view md5sum);
|
void loadCheats(const string& md5sum);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Saves cheats for ROM with given MD5sum to cheat map.
|
Saves cheats for ROM with given MD5sum to cheat map.
|
||||||
*/
|
*/
|
||||||
void saveCheats(string_view md5sum);
|
void saveCheats(const string& md5sum);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Checks if a code is valid.
|
Checks if a code is valid.
|
||||||
*/
|
*/
|
||||||
static bool isValidCode(string_view code);
|
bool isValidCode(const string& code) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/**
|
/**
|
||||||
|
@ -133,14 +132,14 @@ class CheatManager
|
||||||
|
|
||||||
@return The cheat (if was created), else nullptr.
|
@return The cheat (if was created), else nullptr.
|
||||||
*/
|
*/
|
||||||
shared_ptr<Cheat> createCheat(string_view name, string_view code) const;
|
shared_ptr<Cheat> createCheat(const string& name, const string& code) const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Parses a list of cheats and adds/enables each one.
|
Parses a list of cheats and adds/enables each one.
|
||||||
|
|
||||||
@param cheats Comma-separated list of cheats (without any names)
|
@param cheats Comma-separated list of cheats (without any names)
|
||||||
*/
|
*/
|
||||||
void parse(string_view cheats);
|
void parse(const string& cheats);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
OSystem& myOSystem;
|
OSystem& myOSystem;
|
||||||
|
@ -148,7 +147,7 @@ class CheatManager
|
||||||
CheatList myCheatList;
|
CheatList myCheatList;
|
||||||
CheatList myPerFrameList;
|
CheatList myPerFrameList;
|
||||||
|
|
||||||
std::map<string,string, std::less<>> myCheatMap;
|
std::map<string,string> myCheatMap;
|
||||||
string myCheatFile;
|
string myCheatFile;
|
||||||
|
|
||||||
// This is set each time a new cheat/ROM is loaded, for later
|
// This is set each time a new cheat/ROM is loaded, for later
|
||||||
|
|
|
@ -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-2025 by Bradford W. Mott, Stephen Anthony
|
// Copyright (c) 1995-2021 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
|
||||||
|
@ -21,14 +21,14 @@
|
||||||
#include "CheetahCheat.hxx"
|
#include "CheetahCheat.hxx"
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
CheetahCheat::CheetahCheat(OSystem& os, string_view name, string_view code)
|
CheetahCheat::CheetahCheat(OSystem& os, const string& name, const string& code)
|
||||||
: Cheat(os, name, code),
|
: Cheat(os, name, code),
|
||||||
address{static_cast<uInt16>(0xf000 + BSPF::stoi<16>(code.substr(0, 3)))},
|
address{uInt16(0xf000 + unhex(code.substr(0, 3)))},
|
||||||
value{static_cast<uInt8>(BSPF::stoi<16>(code.substr(3, 2)))},
|
value{uInt8(unhex(code.substr(3, 2)))},
|
||||||
count{static_cast<uInt8>(BSPF::stoi<16>(code.substr(5, 1)) + 1)}
|
count{uInt8(unhex(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(uInt8 i = 0; i < count; ++i)
|
for(int 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(uInt8 i = 0; i < count; ++i)
|
for(int 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(uInt8 i = 0; i < count; ++i)
|
for(int 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-2025 by Bradford W. Mott, Stephen Anthony
|
// Copyright (c) 1995-2021 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
|
||||||
|
@ -23,7 +23,7 @@
|
||||||
class CheetahCheat : public Cheat
|
class CheetahCheat : public Cheat
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CheetahCheat(OSystem& os, string_view name, string_view code);
|
CheetahCheat(OSystem& os, const string& name, const string& code);
|
||||||
~CheetahCheat() override = default;
|
~CheetahCheat() override = default;
|
||||||
|
|
||||||
bool enable() override;
|
bool enable() override;
|
||||||
|
@ -31,7 +31,7 @@ class CheetahCheat : public Cheat
|
||||||
void evaluate() override;
|
void evaluate() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::array<uInt8, 16> savedRom{};
|
std::array<uInt8, 16> savedRom;
|
||||||
uInt16 address{0};
|
uInt16 address{0};
|
||||||
uInt8 value{0};
|
uInt8 value{0};
|
||||||
uInt8 count{0};
|
uInt8 count{0};
|
||||||
|
|
|
@ -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-2025 by Bradford W. Mott, Stephen Anthony
|
// Copyright (c) 1995-2021 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
|
||||||
|
@ -23,10 +23,10 @@
|
||||||
#include "RamCheat.hxx"
|
#include "RamCheat.hxx"
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
RamCheat::RamCheat(OSystem& os, string_view name, string_view code)
|
RamCheat::RamCheat(OSystem& os, const string& name, const string& code)
|
||||||
: Cheat(os, name, code),
|
: Cheat(os, name, code),
|
||||||
address{static_cast<uInt16>(BSPF::stoi<16>(myCode.substr(0, 2)))},
|
address{uInt16(unhex(myCode.substr(0, 2)))},
|
||||||
value{static_cast<uInt8>(BSPF::stoi<16>(myCode.substr(2, 2)))}
|
value{uInt8(unhex(myCode.substr(2, 2)))}
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -55,5 +55,5 @@ bool RamCheat::disable()
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
void RamCheat::evaluate()
|
void RamCheat::evaluate()
|
||||||
{
|
{
|
||||||
myOSystem.console().system().pokeOob(address, value);
|
myOSystem.console().system().poke(address, value);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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-2025 by Bradford W. Mott, Stephen Anthony
|
// Copyright (c) 1995-2021 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
|
||||||
|
@ -23,7 +23,7 @@
|
||||||
class RamCheat : public Cheat
|
class RamCheat : public Cheat
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
RamCheat(OSystem& os, string_view name, string_view code);
|
RamCheat(OSystem& os, const string& name, const string& code);
|
||||||
~RamCheat() override = default;
|
~RamCheat() override = default;
|
||||||
|
|
||||||
bool enable() override;
|
bool enable() override;
|
||||||
|
|
|
@ -7,8 +7,6 @@ MODULE_OBJS := \
|
||||||
src/cheat/BankRomCheat.o \
|
src/cheat/BankRomCheat.o \
|
||||||
src/cheat/RamCheat.o
|
src/cheat/RamCheat.o
|
||||||
|
|
||||||
MODULE_TEST_OBJS =
|
|
||||||
|
|
||||||
MODULE_DIRS += \
|
MODULE_DIRS += \
|
||||||
src/cheat
|
src/cheat
|
||||||
|
|
||||||
|
|
|
@ -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-2025 by Bradford W. Mott, Stephen Anthony
|
// Copyright (c) 1995-2021 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,32 +29,28 @@ AudioQueue::AudioQueue(uInt32 fragmentSize, uInt32 capacity, bool isStereo)
|
||||||
{
|
{
|
||||||
const uInt8 sampleSize = myIsStereo ? 2 : 1;
|
const uInt8 sampleSize = myIsStereo ? 2 : 1;
|
||||||
|
|
||||||
myFragmentBuffer = make_unique<Int16[]>(
|
myFragmentBuffer = make_unique<Int16[]>(myFragmentSize * sampleSize * (capacity + 2));
|
||||||
static_cast<size_t>(myFragmentSize) * sampleSize * (capacity + 2));
|
|
||||||
|
|
||||||
for (uInt32 i = 0; i < capacity; ++i)
|
for (uInt32 i = 0; i < capacity; ++i)
|
||||||
myFragmentQueue[i] = myAllFragments[i] = myFragmentBuffer.get() +
|
myFragmentQueue[i] = myAllFragments[i] = myFragmentBuffer.get() + i * sampleSize * myFragmentSize;
|
||||||
static_cast<size_t>(myFragmentSize) * sampleSize * i;
|
|
||||||
|
|
||||||
myAllFragments[capacity] = myFirstFragmentForEnqueue =
|
myAllFragments[capacity] = myFirstFragmentForEnqueue =
|
||||||
myFragmentBuffer.get() + static_cast<size_t>(myFragmentSize) * sampleSize *
|
myFragmentBuffer.get() + capacity * sampleSize * myFragmentSize;
|
||||||
capacity;
|
|
||||||
|
|
||||||
myAllFragments[capacity + 1] = myFirstFragmentForDequeue =
|
myAllFragments[capacity + 1] = myFirstFragmentForDequeue =
|
||||||
myFragmentBuffer.get() + static_cast<size_t>(myFragmentSize) * sampleSize *
|
myFragmentBuffer.get() + (capacity + 1) * sampleSize * myFragmentSize;
|
||||||
(capacity + 1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
uInt32 AudioQueue::capacity() const
|
uInt32 AudioQueue::capacity() const
|
||||||
{
|
{
|
||||||
return static_cast<uInt32>(myFragmentQueue.size());
|
return uInt32(myFragmentQueue.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
uInt32 AudioQueue::size() const
|
uInt32 AudioQueue::size() const
|
||||||
{
|
{
|
||||||
const lock_guard<mutex> guard(myMutex);
|
lock_guard<mutex> guard(myMutex);
|
||||||
|
|
||||||
return mySize;
|
return mySize;
|
||||||
}
|
}
|
||||||
|
@ -74,9 +70,9 @@ uInt32 AudioQueue::fragmentSize() const
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
Int16* AudioQueue::enqueue(Int16* fragment)
|
Int16* AudioQueue::enqueue(Int16* fragment)
|
||||||
{
|
{
|
||||||
const lock_guard<mutex> guard(myMutex);
|
lock_guard<mutex> guard(myMutex);
|
||||||
|
|
||||||
Int16* newFragment = nullptr;
|
Int16* newFragment;
|
||||||
|
|
||||||
if (!fragment) {
|
if (!fragment) {
|
||||||
if (!myFirstFragmentForEnqueue) throw runtime_error("enqueue called empty");
|
if (!myFirstFragmentForEnqueue) throw runtime_error("enqueue called empty");
|
||||||
|
@ -87,7 +83,7 @@ Int16* AudioQueue::enqueue(Int16* fragment)
|
||||||
return newFragment;
|
return newFragment;
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto capacity = static_cast<uInt8>(myFragmentQueue.size());
|
const uInt8 capacity = uInt8(myFragmentQueue.size());
|
||||||
const uInt8 fragmentIndex = (myNextFragment + mySize) % capacity;
|
const uInt8 fragmentIndex = (myNextFragment + mySize) % capacity;
|
||||||
|
|
||||||
newFragment = myFragmentQueue.at(fragmentIndex);
|
newFragment = myFragmentQueue.at(fragmentIndex);
|
||||||
|
@ -105,7 +101,7 @@ Int16* AudioQueue::enqueue(Int16* fragment)
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
Int16* AudioQueue::dequeue(Int16* fragment)
|
Int16* AudioQueue::dequeue(Int16* fragment)
|
||||||
{
|
{
|
||||||
const lock_guard<mutex> guard(myMutex);
|
lock_guard<mutex> guard(myMutex);
|
||||||
|
|
||||||
if (mySize == 0) return nullptr;
|
if (mySize == 0) return nullptr;
|
||||||
|
|
||||||
|
@ -128,7 +124,7 @@ Int16* AudioQueue::dequeue(Int16* fragment)
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
void AudioQueue::closeSink(Int16* fragment)
|
void AudioQueue::closeSink(Int16* fragment)
|
||||||
{
|
{
|
||||||
const lock_guard<mutex> guard(myMutex);
|
lock_guard<mutex> guard(myMutex);
|
||||||
|
|
||||||
if (myFirstFragmentForDequeue && fragment)
|
if (myFirstFragmentForDequeue && fragment)
|
||||||
throw runtime_error("attempt to return unknown buffer on closeSink");
|
throw runtime_error("attempt to return unknown buffer on closeSink");
|
||||||
|
|
|
@ -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-2025 by Bradford W. Mott, Stephen Anthony
|
// Copyright (c) 1995-2021 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
|
||||||
|
@ -24,7 +24,7 @@
|
||||||
#include "StaggeredLogger.hxx"
|
#include "StaggeredLogger.hxx"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
This class implements an audio queue that acts both like a ring buffer
|
This class implements a an audio queue that acts both like a ring buffer
|
||||||
and a pool of audio fragments. The TIA emulation core fills a fragment
|
and a pool of audio fragments. The TIA emulation core fills a fragment
|
||||||
with samples and then returns it to the queue, receiving a new fragment
|
with samples and then returns it to the queue, receiving a new fragment
|
||||||
in return. The sound driver removes fragments for playback from the
|
in return. The sound driver removes fragments for playback from the
|
||||||
|
@ -46,7 +46,6 @@ class AudioQueue
|
||||||
@param isStereo Whether samples are stereo or mono.
|
@param isStereo Whether samples are stereo or mono.
|
||||||
*/
|
*/
|
||||||
AudioQueue(uInt32 fragmentSize, uInt32 capacity, bool isStereo);
|
AudioQueue(uInt32 fragmentSize, uInt32 capacity, bool isStereo);
|
||||||
~AudioQueue() = default;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Capacity getter.
|
Capacity getter.
|
||||||
|
@ -134,6 +133,7 @@ class AudioQueue
|
||||||
StaggeredLogger myOverflowLogger{"audio buffer overflow", Logger::Level::INFO};
|
StaggeredLogger myOverflowLogger{"audio buffer overflow", Logger::Level::INFO};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
AudioQueue() = delete;
|
AudioQueue() = delete;
|
||||||
AudioQueue(const AudioQueue&) = delete;
|
AudioQueue(const AudioQueue&) = delete;
|
||||||
AudioQueue(AudioQueue&&) = delete;
|
AudioQueue(AudioQueue&&) = delete;
|
||||||
|
|
|
@ -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-2025 by Bradford W. Mott, Stephen Anthony
|
// Copyright (c) 1995-2021 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
|
||||||
|
@ -19,12 +19,12 @@
|
||||||
#include "Settings.hxx"
|
#include "Settings.hxx"
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
constexpr uInt32 lboundInt(int x, int defaultValue)
|
uInt32 lboundInt(int x, int defaultValue)
|
||||||
{
|
{
|
||||||
return x <= 0 ? defaultValue : x;
|
return x <= 0 ? defaultValue : x;
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr AudioSettings::Preset normalizedPreset(int numericPreset)
|
AudioSettings::Preset normalizedPreset(int numericPreset)
|
||||||
{
|
{
|
||||||
return (
|
return (
|
||||||
numericPreset >= static_cast<int>(AudioSettings::Preset::custom) &&
|
numericPreset >= static_cast<int>(AudioSettings::Preset::custom) &&
|
||||||
|
@ -32,14 +32,14 @@ namespace {
|
||||||
) ? static_cast<AudioSettings::Preset>(numericPreset) : AudioSettings::DEFAULT_PRESET;
|
) ? static_cast<AudioSettings::Preset>(numericPreset) : AudioSettings::DEFAULT_PRESET;
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr AudioSettings::ResamplingQuality normalizeResamplingQuality(int numericResamplingQuality)
|
AudioSettings::ResamplingQuality normalizeResamplingQuality(int numericResamplingQuality)
|
||||||
{
|
{
|
||||||
return (
|
return (
|
||||||
numericResamplingQuality >= static_cast<int>(AudioSettings::ResamplingQuality::nearestNeighbour) &&
|
numericResamplingQuality >= static_cast<int>(AudioSettings::ResamplingQuality::nearestNeightbour) &&
|
||||||
numericResamplingQuality <= static_cast<int>(AudioSettings::ResamplingQuality::lanczos_3)
|
numericResamplingQuality <= static_cast<int>(AudioSettings::ResamplingQuality::lanczos_3)
|
||||||
) ? static_cast<AudioSettings::ResamplingQuality>(numericResamplingQuality) : AudioSettings::DEFAULT_RESAMPLING_QUALITY;
|
) ? static_cast<AudioSettings::ResamplingQuality>(numericResamplingQuality) : AudioSettings::DEFAULT_RESAMPLING_QUALITY;
|
||||||
}
|
}
|
||||||
} // namespace
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
AudioSettings::AudioSettings(Settings& settings)
|
AudioSettings::AudioSettings(Settings& settings)
|
||||||
|
@ -51,10 +51,9 @@ AudioSettings::AudioSettings(Settings& settings)
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
void AudioSettings::normalize(Settings& settings)
|
void AudioSettings::normalize(Settings& settings)
|
||||||
{
|
{
|
||||||
const int settingPreset = settings.getInt(SETTING_PRESET);
|
int settingPreset = settings.getInt(SETTING_PRESET);
|
||||||
const Preset preset = normalizedPreset(settingPreset);
|
Preset preset = normalizedPreset(settingPreset);
|
||||||
if (static_cast<int>(preset) != settingPreset)
|
if (static_cast<int>(preset) != settingPreset) settings.setValue(SETTING_PRESET, static_cast<int>(DEFAULT_PRESET));
|
||||||
settings.setValue(SETTING_PRESET, static_cast<int>(DEFAULT_PRESET));
|
|
||||||
|
|
||||||
switch (settings.getInt(SETTING_SAMPLE_RATE)) {
|
switch (settings.getInt(SETTING_SAMPLE_RATE)) {
|
||||||
case 44100:
|
case 44100:
|
||||||
|
@ -67,19 +66,32 @@ void AudioSettings::normalize(Settings& settings)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
const int settingBufferSize = settings.getInt(SETTING_BUFFER_SIZE);
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
const int settingHeadroom = settings.getInt(SETTING_HEADROOM);
|
int settingHeadroom = settings.getInt(SETTING_HEADROOM);
|
||||||
if (settingHeadroom < 0 || settingHeadroom > MAX_HEADROOM) settings.setValue(SETTING_HEADROOM, DEFAULT_HEADROOM);
|
if (settingHeadroom < 0 || settingHeadroom > MAX_HEADROOM) settings.setValue(SETTING_HEADROOM, DEFAULT_HEADROOM);
|
||||||
|
|
||||||
const int settingResamplingQuality = settings.getInt(SETTING_RESAMPLING_QUALITY);
|
int settingResamplingQuality = settings.getInt(SETTING_RESAMPLING_QUALITY);
|
||||||
const ResamplingQuality resamplingQuality =
|
ResamplingQuality resamplingQuality = normalizeResamplingQuality(settingResamplingQuality);
|
||||||
normalizeResamplingQuality(settingResamplingQuality);
|
|
||||||
if (static_cast<int>(resamplingQuality) != settingResamplingQuality)
|
if (static_cast<int>(resamplingQuality) != settingResamplingQuality)
|
||||||
settings.setValue(SETTING_RESAMPLING_QUALITY, static_cast<int>(DEFAULT_RESAMPLING_QUALITY));
|
settings.setValue(SETTING_RESAMPLING_QUALITY, static_cast<int>(DEFAULT_RESAMPLING_QUALITY));
|
||||||
|
|
||||||
const int settingVolume = settings.getInt(SETTING_VOLUME);
|
int settingVolume = settings.getInt(SETTING_VOLUME);
|
||||||
if (settingVolume < 0 || settingVolume > 100) settings.setValue(SETTING_VOLUME, DEFAULT_VOLUME);
|
if (settingVolume < 0 || settingVolume > 100) settings.setValue(SETTING_VOLUME, DEFAULT_VOLUME);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -101,7 +113,7 @@ uInt32 AudioSettings::sampleRate()
|
||||||
uInt32 AudioSettings::fragmentSize()
|
uInt32 AudioSettings::fragmentSize()
|
||||||
{
|
{
|
||||||
updatePresetFromSettings();
|
updatePresetFromSettings();
|
||||||
return myPresetFragmentSize; // No longer configurable in sound backend
|
return customSettings() ? lboundInt(mySettings.getInt(SETTING_FRAGMENT_SIZE), DEFAULT_FRAGMENT_SIZE) : myPresetFragmentSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
@ -141,6 +153,12 @@ 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
|
||||||
{
|
{
|
||||||
|
@ -165,13 +183,15 @@ 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::nearestNeightbour;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
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;
|
||||||
|
@ -179,6 +199,7 @@ 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;
|
||||||
|
@ -186,6 +207,7 @@ 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;
|
||||||
|
@ -207,6 +229,15 @@ 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)
|
||||||
{
|
{
|
||||||
|
@ -259,6 +290,14 @@ 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-2025 by Bradford W. Mott, Stephen Anthony
|
// Copyright (c) 1995-2021 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
|
||||||
|
@ -26,7 +26,7 @@ class AudioSettings
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
enum class Preset: uInt8 {
|
enum class Preset {
|
||||||
custom = 1,
|
custom = 1,
|
||||||
lowQualityMediumLag = 2,
|
lowQualityMediumLag = 2,
|
||||||
highQualityMediumLag = 3,
|
highQualityMediumLag = 3,
|
||||||
|
@ -34,21 +34,23 @@ class AudioSettings
|
||||||
ultraQualityMinimalLag = 5
|
ultraQualityMinimalLag = 5
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class ResamplingQuality: uInt8 {
|
enum class ResamplingQuality {
|
||||||
nearestNeighbour = 1,
|
nearestNeightbour = 1,
|
||||||
lanczos_2 = 2,
|
lanczos_2 = 2,
|
||||||
lanczos_3 = 3
|
lanczos_3 = 3
|
||||||
};
|
};
|
||||||
|
|
||||||
static constexpr string_view SETTING_PRESET = "audio.preset";
|
static constexpr const char* SETTING_PRESET = "audio.preset";
|
||||||
static constexpr string_view SETTING_SAMPLE_RATE = "audio.sample_rate";
|
static constexpr const char* SETTING_SAMPLE_RATE = "audio.sample_rate";
|
||||||
static constexpr string_view SETTING_BUFFER_SIZE = "audio.buffer_size";
|
static constexpr const char* SETTING_FRAGMENT_SIZE = "audio.fragment_size";
|
||||||
static constexpr string_view SETTING_HEADROOM = "audio.headroom";
|
static constexpr const char* SETTING_BUFFER_SIZE = "audio.buffer_size";
|
||||||
static constexpr string_view SETTING_RESAMPLING_QUALITY = "audio.resampling_quality";
|
static constexpr const char* SETTING_HEADROOM = "audio.headroom";
|
||||||
static constexpr string_view SETTING_STEREO = "audio.stereo";
|
static constexpr const char* SETTING_RESAMPLING_QUALITY = "audio.resampling_quality";
|
||||||
static constexpr string_view SETTING_VOLUME = "audio.volume";
|
static constexpr const char* SETTING_STEREO = "audio.stereo";
|
||||||
static constexpr string_view SETTING_ENABLED = "audio.enabled";
|
static constexpr const char* SETTING_VOLUME = "audio.volume";
|
||||||
static constexpr string_view SETTING_DPC_PITCH = "audio.dpc_pitch";
|
static constexpr const char* SETTING_DEVICE = "audio.device";
|
||||||
|
static constexpr const char* SETTING_ENABLED = "audio.enabled";
|
||||||
|
static constexpr const char* SETTING_DPC_PITCH = "audio.dpc_pitch";
|
||||||
|
|
||||||
static constexpr Preset DEFAULT_PRESET = Preset::highQualityMediumLag;
|
static constexpr Preset DEFAULT_PRESET = Preset::highQualityMediumLag;
|
||||||
static constexpr uInt32 DEFAULT_SAMPLE_RATE = 44100;
|
static constexpr uInt32 DEFAULT_SAMPLE_RATE = 44100;
|
||||||
|
@ -125,16 +127,15 @@ class AudioSettings
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
Settings& mySettings; // NOLINT: we want a reference here
|
Settings& mySettings;
|
||||||
|
|
||||||
Preset myPreset{Preset::custom};
|
Preset myPreset{Preset::custom};
|
||||||
|
|
||||||
uInt32 myPresetSampleRate{0};
|
uInt32 myPresetSampleRate{0};
|
||||||
uInt32 myPresetFragmentSize{1024}; // no longer configurable in sound backend
|
uInt32 myPresetFragmentSize{0};
|
||||||
|
|
||||||
uInt32 myPresetBufferSize{0};
|
uInt32 myPresetBufferSize{0};
|
||||||
uInt32 myPresetHeadroom{0};
|
uInt32 myPresetHeadroom{0};
|
||||||
ResamplingQuality myPresetResamplingQuality{ResamplingQuality::nearestNeighbour};
|
ResamplingQuality myPresetResamplingQuality{ResamplingQuality::nearestNeightbour};
|
||||||
|
|
||||||
bool myIsPersistent{true};
|
bool myIsPersistent{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-2025 by Bradford W. Mott, Stephen Anthony
|
// Copyright (c) 1995-2021 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
|
||||||
|
@ -24,7 +24,7 @@ string Base::toString(int value, Common::Base::Fmt outputBase)
|
||||||
{
|
{
|
||||||
static char vToS_buf[32]; // NOLINT : One place where C-style is acceptable
|
static char vToS_buf[32]; // NOLINT : One place where C-style is acceptable
|
||||||
|
|
||||||
if(outputBase == Base::Fmt::DEFAULT)
|
if(outputBase == Base::Fmt::_DEFAULT)
|
||||||
outputBase = myDefaultBase;
|
outputBase = myDefaultBase;
|
||||||
|
|
||||||
switch(outputBase)
|
switch(outputBase)
|
||||||
|
@ -47,83 +47,74 @@ string Base::toString(int value, Common::Base::Fmt outputBase)
|
||||||
|
|
||||||
case Base::Fmt::_10: // base 10: 3 or 5 bytes (depending on value)
|
case Base::Fmt::_10: // base 10: 3 or 5 bytes (depending on value)
|
||||||
if(value > -0x100 && value < 0x100)
|
if(value > -0x100 && value < 0x100)
|
||||||
std::ignore = std::snprintf(vToS_buf, 5, "%3d", static_cast<Int16>(value));
|
std::snprintf(vToS_buf, 5, "%3d", Int16(value));
|
||||||
else
|
else
|
||||||
std::ignore = std::snprintf(vToS_buf, 6, "%5d", value);
|
std::snprintf(vToS_buf, 6, "%5d", value);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Base::Fmt::_10_02: // base 10: 2 digits (with leading zero)
|
case Base::Fmt::_10_02: // base 10: 2 digits (with leading zero)
|
||||||
std::ignore = std::snprintf(vToS_buf, 3, "%02d", value);
|
std::snprintf(vToS_buf, 3, "%02d", value);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Base::Fmt::_10_3: // base 10: 3 digits
|
case Base::Fmt::_10_3: // base 10: 3 digits
|
||||||
std::ignore = std::snprintf(vToS_buf, 4, "%3d", value);
|
std::snprintf(vToS_buf, 4, "%3d", value);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Base::Fmt::_10_4: // base 10: 4 digits
|
case Base::Fmt::_10_4: // base 10: 4 digits
|
||||||
std::ignore = std::snprintf(vToS_buf, 5, "%4d", value);
|
std::snprintf(vToS_buf, 5, "%4d", value);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Base::Fmt::_10_5: // base 10: 5 digits
|
case Base::Fmt::_10_5: // base 10: 5 digits
|
||||||
std::ignore = std::snprintf(vToS_buf, 6, "%5d", value);
|
std::snprintf(vToS_buf, 6, "%5d", value);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Base::Fmt::_10_6: // base 10: 6 digits
|
case Base::Fmt::_10_6: // base 10: 6 digits
|
||||||
std::ignore = std::snprintf(vToS_buf, 7, "%6d", value);
|
std::snprintf(vToS_buf, 7, "%6d", value);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Base::Fmt::_10_8: // base 10: 8 digits
|
case Base::Fmt::_10_8: // base 10: 8 digits
|
||||||
std::ignore = std::snprintf(vToS_buf, 9, "%8d", value);
|
std::snprintf(vToS_buf, 9, "%8d", value);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Base::Fmt::_16_1: // base 16: 1 byte wide
|
case Base::Fmt::_16_1: // base 16: 1 byte wide
|
||||||
std::ignore = std::snprintf(
|
std::snprintf(vToS_buf, 2, hexUppercase() ? "%1X" : "%1x", value);
|
||||||
vToS_buf, 2, hexUppercase() ? "%1X" : "%1x", value);
|
|
||||||
break;
|
break;
|
||||||
case Base::Fmt::_16_2: // base 16: 2 bytes wide
|
case Base::Fmt::_16_2: // base 16: 2 bytes wide
|
||||||
std::ignore = std::snprintf(
|
std::snprintf(vToS_buf, 3, hexUppercase() ? "%02X" : "%02x", value);
|
||||||
vToS_buf, 3, hexUppercase() ? "%02X" : "%02x", value);
|
|
||||||
break;
|
break;
|
||||||
case Base::Fmt::_16_2_2:
|
case Base::Fmt::_16_2_2:
|
||||||
std::ignore = std::snprintf(
|
std::snprintf(vToS_buf, 6, hexUppercase() ? "%02X.%02X" : "%02x.%02x",
|
||||||
vToS_buf, 6, hexUppercase() ? "%02X.%02X" : "%02x.%02x",
|
value >> 8, value & 0xff );
|
||||||
value >> 8, value & 0xff );
|
|
||||||
break;
|
break;
|
||||||
case Base::Fmt::_16_3_2:
|
case Base::Fmt::_16_3_2:
|
||||||
std::ignore = std::snprintf(
|
std::snprintf(vToS_buf, 7, hexUppercase() ? "%03X.%02X" : "%03x.%02x",
|
||||||
vToS_buf, 7, hexUppercase() ? "%03X.%02X" : "%03x.%02x",
|
value >> 8, value & 0xff );
|
||||||
value >> 8, value & 0xff );
|
|
||||||
break;
|
break;
|
||||||
case Base::Fmt::_16_4: // base 16: 4 bytes wide
|
case Base::Fmt::_16_4: // base 16: 4 bytes wide
|
||||||
std::ignore = std::snprintf(
|
std::snprintf(vToS_buf, 5, hexUppercase() ? "%04X" : "%04x", value);
|
||||||
vToS_buf, 5, hexUppercase() ? "%04X" : "%04x", value);
|
|
||||||
break;
|
break;
|
||||||
case Base::Fmt::_16_8: // base 16: 8 bytes wide
|
case Base::Fmt::_16_8: // base 16: 8 bytes wide
|
||||||
std::ignore = std::snprintf(
|
std::snprintf(vToS_buf, 9, hexUppercase() ? "%08X" : "%08x", value);
|
||||||
vToS_buf, 9, hexUppercase() ? "%08X" : "%08x", value);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Base::Fmt::_16: // base 16: 2, 4, 8 bytes (depending on value)
|
case Base::Fmt::_16: // base 16: 2, 4, 8 bytes (depending on value)
|
||||||
default:
|
default:
|
||||||
if(value < 0x100)
|
if(value < 0x100)
|
||||||
std::ignore = std::snprintf(
|
std::snprintf(vToS_buf, 3, hexUppercase() ? "%02X" : "%02x", value);
|
||||||
vToS_buf, 3, hexUppercase() ? "%02X" : "%02x", value);
|
|
||||||
else if(value < 0x10000)
|
else if(value < 0x10000)
|
||||||
std::ignore = std::snprintf(
|
std::snprintf(vToS_buf, 5, hexUppercase() ? "%04X" : "%04x", value);
|
||||||
vToS_buf, 5, hexUppercase() ? "%04X" : "%04x", value);
|
|
||||||
else
|
else
|
||||||
std::ignore = std::snprintf(
|
std::snprintf(vToS_buf, 9, hexUppercase() ? "%08X" : "%08x", value);
|
||||||
vToS_buf, 9, hexUppercase() ? "%08X" : "%08x", value);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return {vToS_buf};
|
return string(vToS_buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
Base::Fmt Base::myDefaultBase = Base::Fmt::_16;
|
Base::Fmt Base::myDefaultBase = Base::Fmt::_16;
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
std::ios_base::fmtflags Base::myHexflags = std::ios_base::hex; // NOLINT
|
std::ios_base::fmtflags Base::myHexflags = std::ios_base::hex;
|
||||||
|
|
||||||
} // namespace Common
|
} // Namespace Common
|
||||||
|
|
|
@ -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-2025 by Bradford W. Mott, Stephen Anthony
|
// Copyright (c) 1995-2021 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
|
||||||
|
@ -38,7 +38,7 @@ class Base
|
||||||
// The base to use for conversion from integers to strings
|
// The base to use for conversion from integers to strings
|
||||||
// Note that the actual number of places will be determined by
|
// Note that the actual number of places will be determined by
|
||||||
// the magnitude of the value itself in the general case
|
// the magnitude of the value itself in the general case
|
||||||
enum class Fmt: uInt8 {
|
enum class Fmt {
|
||||||
_16, // base 16: 2, 4, 8 bytes (depending on value)
|
_16, // base 16: 2, 4, 8 bytes (depending on value)
|
||||||
_16_1, // base 16: 1 byte wide
|
_16_1, // base 16: 1 byte wide
|
||||||
_16_2, // base 16: 2 bytes wide
|
_16_2, // base 16: 2 bytes wide
|
||||||
|
@ -56,7 +56,7 @@ class Base
|
||||||
_2, // base 2: 8 or 16 bits (depending on value)
|
_2, // base 2: 8 or 16 bits (depending on value)
|
||||||
_2_8, // base 2: 1 byte (8 bits) wide
|
_2_8, // base 2: 1 byte (8 bits) wide
|
||||||
_2_16, // base 2: 2 bytes (16 bits) wide
|
_2_16, // base 2: 2 bytes (16 bits) wide
|
||||||
DEFAULT
|
_DEFAULT
|
||||||
};
|
};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
@ -72,31 +72,31 @@ class Base
|
||||||
static bool hexUppercase() { return myHexflags & std::ios_base::uppercase; }
|
static bool hexUppercase() { return myHexflags & std::ios_base::uppercase; }
|
||||||
|
|
||||||
/** Output HEX digits in 0.5/1/2/4 byte format */
|
/** Output HEX digits in 0.5/1/2/4 byte format */
|
||||||
static std::ostream& HEX1(std::ostream& os) {
|
static inline std::ostream& HEX1(std::ostream& os) {
|
||||||
os.flags(myHexflags);
|
os.flags(myHexflags);
|
||||||
return os << std::setw(1);
|
return os << std::setw(1);
|
||||||
}
|
}
|
||||||
static std::ostream& HEX2(std::ostream& os) {
|
static inline std::ostream& HEX2(std::ostream& os) {
|
||||||
os.flags(myHexflags);
|
os.flags(myHexflags);
|
||||||
return os << std::setw(2) << std::setfill('0');
|
return os << std::setw(2) << std::setfill('0');
|
||||||
}
|
}
|
||||||
static std::ostream& HEX3(std::ostream& os)
|
static inline std::ostream& HEX3(std::ostream& os)
|
||||||
{
|
{
|
||||||
os.flags(myHexflags);
|
os.flags(myHexflags);
|
||||||
return os << std::setw(3) << std::setfill('0');
|
return os << std::setw(3) << std::setfill('0');
|
||||||
}
|
}
|
||||||
static std::ostream& HEX4(std::ostream& os) {
|
static inline std::ostream& HEX4(std::ostream& os) {
|
||||||
os.flags(myHexflags);
|
os.flags(myHexflags);
|
||||||
return os << std::setw(4) << std::setfill('0');
|
return os << std::setw(4) << std::setfill('0');
|
||||||
}
|
}
|
||||||
static std::ostream& HEX8(std::ostream& os) {
|
static inline std::ostream& HEX8(std::ostream& os) {
|
||||||
os.flags(myHexflags);
|
os.flags(myHexflags);
|
||||||
return os << std::setw(8) << std::setfill('0');
|
return os << std::setw(8) << std::setfill('0');
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Convert integer to a string in the given base format */
|
/** Convert integer to a string in the given base format */
|
||||||
static string toString(int value,
|
static string toString(int value,
|
||||||
Common::Base::Fmt outputBase = Common::Base::Fmt::DEFAULT);
|
Common::Base::Fmt outputBase = Common::Base::Fmt::_DEFAULT);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Default format to use when none is specified
|
// Default format to use when none is specified
|
||||||
|
@ -108,7 +108,6 @@ class Base
|
||||||
private:
|
private:
|
||||||
// Following constructors and assignment operators not supported
|
// Following constructors and assignment operators not supported
|
||||||
Base() = delete;
|
Base() = delete;
|
||||||
~Base() = delete;
|
|
||||||
Base(const Base&) = delete;
|
Base(const Base&) = delete;
|
||||||
Base(Base&&) = delete;
|
Base(Base&&) = delete;
|
||||||
Base& operator=(const Base&) = delete;
|
Base& operator=(const Base&) = delete;
|
||||||
|
|
|
@ -1,251 +0,0 @@
|
||||||
//============================================================================
|
|
||||||
//
|
|
||||||
// SSSS tt lll lll
|
|
||||||
// SS SS tt ll ll
|
|
||||||
// SS tttttt eeee ll ll aaaa
|
|
||||||
// SSSS tt ee ee ll ll aa
|
|
||||||
// SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator"
|
|
||||||
// SS SS tt ee ll ll aa aa
|
|
||||||
// SSSS ttt eeeee llll llll aaaaa
|
|
||||||
//
|
|
||||||
// Copyright (c) 1995-2025 by Bradford W. Mott, Stephen Anthony
|
|
||||||
// and the Stella Team
|
|
||||||
//
|
|
||||||
// See the file "License.txt" for information on usage and redistribution of
|
|
||||||
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
|
||||||
//============================================================================
|
|
||||||
|
|
||||||
#include <cmath>
|
|
||||||
|
|
||||||
#include "OSystem.hxx"
|
|
||||||
#include "Console.hxx"
|
|
||||||
#include "EventHandler.hxx"
|
|
||||||
#include "FBSurface.hxx"
|
|
||||||
#include "PNGLibrary.hxx"
|
|
||||||
#include "PropsSet.hxx"
|
|
||||||
|
|
||||||
#include "Bezel.hxx"
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
Bezel::Bezel(OSystem& osystem)
|
|
||||||
: myOSystem{osystem},
|
|
||||||
myFB{osystem.frameBuffer()}
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
string Bezel::getName(const string& path, const Properties& props)
|
|
||||||
{
|
|
||||||
string imageName;
|
|
||||||
int index = 1; // skip property name
|
|
||||||
|
|
||||||
do
|
|
||||||
{
|
|
||||||
imageName = getName(props, index);
|
|
||||||
if(imageName != EmptyString)
|
|
||||||
{
|
|
||||||
// Note: JPG does not support transparency
|
|
||||||
const string imagePath = path + imageName + ".png";
|
|
||||||
const FSNode node(imagePath);
|
|
||||||
if(node.exists())
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} while(index != -1);
|
|
||||||
|
|
||||||
return imageName;
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
string Bezel::getName(const Properties& props, int& index)
|
|
||||||
{
|
|
||||||
if(++index == 1)
|
|
||||||
return props.get(PropType::Bezel_Name);
|
|
||||||
|
|
||||||
// Try to generate bezel name from cart name
|
|
||||||
const string& cartName = props.get(PropType::Cart_Name);
|
|
||||||
size_t pos = cartName.find_first_of('(');
|
|
||||||
if(pos == std::string::npos)
|
|
||||||
pos = cartName.length() + 1;
|
|
||||||
if(index < 10 && pos != std::string::npos && pos > 0)
|
|
||||||
{
|
|
||||||
// The following suffixes are from "The Official No-Intro Convention",
|
|
||||||
// covering all used combinations by "The Bezel Project" (except single ones)
|
|
||||||
// (Unl) = unlicensed (Homebrews)
|
|
||||||
const std::array<string, 8> suffixes = {
|
|
||||||
" (USA)", " (USA) (Proto)", " (USA) (Unl)", " (USA) (Hack)",
|
|
||||||
" (Europe)", " (Germany)", " (France) (Unl)", " (Australia)"
|
|
||||||
};
|
|
||||||
return cartName.substr(0, pos - 1) + suffixes[index - 2];
|
|
||||||
}
|
|
||||||
|
|
||||||
if(index == 10)
|
|
||||||
{
|
|
||||||
return "Atari-2600";
|
|
||||||
}
|
|
||||||
|
|
||||||
if(index == 11)
|
|
||||||
{
|
|
||||||
index = -1;
|
|
||||||
return "default";
|
|
||||||
}
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
string Bezel::getName(int& index) const
|
|
||||||
{
|
|
||||||
return getName(myOSystem.console().properties(), index);
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
uInt32 Bezel::borderSize(uInt32 x, uInt32 y, uInt32 size, Int32 step) const
|
|
||||||
{
|
|
||||||
uInt32 *pixels{nullptr}, pitch{0};
|
|
||||||
|
|
||||||
mySurface->basePtr(pixels, pitch);
|
|
||||||
pixels += x + y * pitch;
|
|
||||||
|
|
||||||
for(uInt32 i = 0; i < size; ++i, pixels += step)
|
|
||||||
{
|
|
||||||
uInt8 r{0}, g{0}, b{0}, a{0};
|
|
||||||
|
|
||||||
myFB.getRGBA(*pixels, &r, &g, &b, &a);
|
|
||||||
if(a < 255) // transparent pixel?
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
return size - 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
bool Bezel::load()
|
|
||||||
{
|
|
||||||
const Settings& settings = myOSystem.settings();
|
|
||||||
bool isValid = false;
|
|
||||||
string imageName;
|
|
||||||
|
|
||||||
#ifdef IMAGE_SUPPORT
|
|
||||||
const bool show = myOSystem.eventHandler().inTIAMode() &&
|
|
||||||
settings.getBool("bezel.show") &&
|
|
||||||
(settings.getBool("fullscreen") ||
|
|
||||||
settings.getBool("bezel.windowed"));
|
|
||||||
|
|
||||||
if(show)
|
|
||||||
{
|
|
||||||
if(!mySurface)
|
|
||||||
mySurface = myFB.allocateSurface(1, 1); // dummy size
|
|
||||||
try
|
|
||||||
{
|
|
||||||
const string& path = myOSystem.bezelDir().getPath();
|
|
||||||
VariantList metaData;
|
|
||||||
int index = 0;
|
|
||||||
|
|
||||||
do
|
|
||||||
{
|
|
||||||
imageName = getName(index);
|
|
||||||
if(imageName != EmptyString)
|
|
||||||
{
|
|
||||||
// Note: JPG does not support transparency
|
|
||||||
const string imagePath = path + imageName + ".png";
|
|
||||||
const FSNode node(imagePath);
|
|
||||||
if(node.exists())
|
|
||||||
{
|
|
||||||
isValid = true;
|
|
||||||
myOSystem.png().loadImage(imagePath, *mySurface, metaData);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} while(index != -1);
|
|
||||||
}
|
|
||||||
catch(const runtime_error&) { cerr << "ERROR: Bezel load\n"; }
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
const bool show = false;
|
|
||||||
#endif
|
|
||||||
if(isValid)
|
|
||||||
{
|
|
||||||
const Int32 w = mySurface->width();
|
|
||||||
const Int32 h = mySurface->height();
|
|
||||||
uInt32 top{0}, bottom{0}, left{0}, right{0};
|
|
||||||
|
|
||||||
if(settings.getBool("bezel.win.auto"))
|
|
||||||
{
|
|
||||||
// Determine transparent window inside bezel image
|
|
||||||
const uInt32 xCenter = w >> 1;
|
|
||||||
top = borderSize(xCenter, 0, h, w);
|
|
||||||
bottom = h - 1 - borderSize(xCenter, h - 1, h, -w);
|
|
||||||
const uInt32 yCenter = (bottom + top) >> 1;
|
|
||||||
left = borderSize(0, yCenter, w, 1);
|
|
||||||
right = w - 1 - borderSize(w - 1, yCenter, w, -1);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// BP: 13, 13, 0, 0%
|
|
||||||
// HY: 12, 12, 0, 0%
|
|
||||||
// P1: 25, 25, 11, 22%
|
|
||||||
// P2: 23, 23, 7, 20%
|
|
||||||
left = std::min(w - 1, static_cast<Int32>(w * settings.getInt("bezel.win.left") / 100. + .5)); // NOLINT
|
|
||||||
right = w - 1 - std::min(w - 1, static_cast<Int32>(w * settings.getInt("bezel.win.right") / 100. + .5)); // NOLINT
|
|
||||||
top = std::min(h - 1, static_cast<Int32>(h * settings.getInt("bezel.win.top") / 100. + .5)); // NOLINT
|
|
||||||
bottom = h - 1 - std::min(h - 1, static_cast<Int32>(h * settings.getInt("bezel.win.bottom") / 100. + .5)); // NOLINT
|
|
||||||
}
|
|
||||||
|
|
||||||
//cerr << (int)(right - left + 1) << " x " << (int)(bottom - top + 1) << " = "
|
|
||||||
// << double((int)(right - left + 1)) / double((int)(bottom - top + 1));
|
|
||||||
|
|
||||||
// Disable bezel is no transparent window was found
|
|
||||||
if(left < right && top < bottom)
|
|
||||||
myInfo = Info(Common::Size(w, h), Common::Rect(left, top, right, bottom));
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if(mySurface)
|
|
||||||
myFB.deallocateSurface(mySurface);
|
|
||||||
mySurface = nullptr;
|
|
||||||
myInfo = Info();
|
|
||||||
myFB.showTextMessage("Invalid bezel image ('" + imageName + "')!");
|
|
||||||
isValid = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
myInfo = Info();
|
|
||||||
if(show)
|
|
||||||
myFB.showTextMessage("No bezel image found");
|
|
||||||
}
|
|
||||||
return isValid;
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
void Bezel::apply()
|
|
||||||
{
|
|
||||||
if(isShown())
|
|
||||||
{
|
|
||||||
const uInt32 bezelW =
|
|
||||||
std::min(myFB.screenSize().w,
|
|
||||||
static_cast<uInt32>(std::round(myFB.imageRect().w() * myInfo.ratioW())));
|
|
||||||
const uInt32 bezelH =
|
|
||||||
std::min(myFB.screenSize().h,
|
|
||||||
static_cast<uInt32>(std::round(myFB.imageRect().h() * myInfo.ratioH())));
|
|
||||||
|
|
||||||
// Position and scale bezel
|
|
||||||
mySurface->setDstSize(bezelW, bezelH);
|
|
||||||
mySurface->setDstPos((myFB.screenSize().w - bezelW) / 2, // center
|
|
||||||
(myFB.screenSize().h - bezelH) / 2);
|
|
||||||
mySurface->setScalingInterpolation(ScalingInterpolation::sharp);
|
|
||||||
// Note: Variable bezel window positions are handled in VideoModeHandler::Mode
|
|
||||||
|
|
||||||
// Enable blending to allow overlaying the bezel over the TIA output
|
|
||||||
mySurface->enableBlend(true);
|
|
||||||
mySurface->setBlendLevel(100);
|
|
||||||
mySurface->setVisible(true);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
if(mySurface)
|
|
||||||
mySurface->setVisible(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
void Bezel::render()
|
|
||||||
{
|
|
||||||
if(mySurface)
|
|
||||||
mySurface->render();
|
|
||||||
}
|
|
|
@ -1,151 +0,0 @@
|
||||||
//============================================================================
|
|
||||||
//
|
|
||||||
// SSSS tt lll lll
|
|
||||||
// SS SS tt ll ll
|
|
||||||
// SS tttttt eeee ll ll aaaa
|
|
||||||
// SSSS tt ee ee ll ll aa
|
|
||||||
// SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator"
|
|
||||||
// SS SS tt ee ll ll aa aa
|
|
||||||
// SSSS ttt eeeee llll llll aaaaa
|
|
||||||
//
|
|
||||||
// Copyright (c) 1995-2025 by Bradford W. Mott, Stephen Anthony
|
|
||||||
// and the Stella Team
|
|
||||||
//
|
|
||||||
// See the file "License.txt" for information on usage and redistribution of
|
|
||||||
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
|
||||||
//============================================================================
|
|
||||||
|
|
||||||
#ifndef BEZEL_HXX
|
|
||||||
#define BEZEL_HXX
|
|
||||||
|
|
||||||
class OSystem;
|
|
||||||
class FBSurface;
|
|
||||||
class FrameBuffer;
|
|
||||||
class Properties;
|
|
||||||
|
|
||||||
#include "Rect.hxx"
|
|
||||||
|
|
||||||
/**
|
|
||||||
This class handles the bezels.
|
|
||||||
|
|
||||||
Bezels are loaded using a file name which is either a bezel name property or
|
|
||||||
is autogenerated from the cart name property. The bezels can be any size and
|
|
||||||
their transparent emulation window can be at any position. The position of
|
|
||||||
the window can be determined automatically.
|
|
||||||
|
|
||||||
+--------------------------------------+
|
|
||||||
| | display.h
|
|
||||||
+--------------------------------------+
|
|
||||||
| |
|
|
||||||
| +---------------+ |
|
|
||||||
| | window | |
|
|
||||||
| | | |
|
|
||||||
| | tia.h * zoom | |
|
|
||||||
| | | | bezel.h * zoom
|
|
||||||
| | | |
|
|
||||||
| +---------------+ |
|
|
||||||
| |
|
|
||||||
+--------------------------------------+ size
|
|
||||||
| |
|
|
||||||
+--------------------------------------+
|
|
||||||
|
|
||||||
The bezel and window sizes and their ratios are used for correct scaling.
|
|
||||||
|
|
||||||
@author Thomas Jentzsch
|
|
||||||
*/
|
|
||||||
|
|
||||||
class Bezel
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
explicit Bezel(OSystem& osystem);
|
|
||||||
~Bezel() = default;
|
|
||||||
|
|
||||||
struct Info
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
bool _isShown{false}; // Is bezel shown?
|
|
||||||
Common::Size _size{1, 1}; // Bezel size
|
|
||||||
Common::Rect _window{1, 1}; // Area of transparent TIA window inside bezel
|
|
||||||
|
|
||||||
public:
|
|
||||||
explicit Info() = default;
|
|
||||||
explicit Info(Common::Size size, Common::Rect window)
|
|
||||||
: _isShown{true}, _size{size}, _window{window} { }
|
|
||||||
|
|
||||||
bool isShown() const { return _isShown; }
|
|
||||||
Common::Size size() const { return _size; }
|
|
||||||
Common::Rect window() const { return _window; }
|
|
||||||
|
|
||||||
// Ratios between bezel sizes and TIA window sizes
|
|
||||||
double ratioW() const { return static_cast<double>(size().w) / window().w(); }
|
|
||||||
double ratioH() const { return static_cast<double>(size().h) / window().h(); }
|
|
||||||
};
|
|
||||||
|
|
||||||
// Structure access methods
|
|
||||||
const Info& info() const { return myInfo; }
|
|
||||||
bool isShown() const { return myInfo.isShown(); }
|
|
||||||
Common::Size size() const { return myInfo.size(); }
|
|
||||||
Common::Rect window() const { return myInfo.window(); }
|
|
||||||
// Ratio between bezel size and TIA window size
|
|
||||||
double ratioW() const { return myInfo.ratioW(); }
|
|
||||||
double ratioH() const { return myInfo.ratioH(); }
|
|
||||||
|
|
||||||
/*
|
|
||||||
Calculate size of a bezel border.
|
|
||||||
*/
|
|
||||||
uInt32 borderSize(uInt32 x, uInt32 y, uInt32 size, Int32 step) const;
|
|
||||||
|
|
||||||
/*
|
|
||||||
Load the bezel.
|
|
||||||
*/
|
|
||||||
bool load();
|
|
||||||
|
|
||||||
/*
|
|
||||||
Display scaled bezel.
|
|
||||||
*/
|
|
||||||
void apply();
|
|
||||||
|
|
||||||
/*
|
|
||||||
Render bezel surface
|
|
||||||
*/
|
|
||||||
void render();
|
|
||||||
|
|
||||||
/*
|
|
||||||
Generate bezel file name.
|
|
||||||
*/
|
|
||||||
static string getName(const string& path, const Properties& props);
|
|
||||||
|
|
||||||
private:
|
|
||||||
/*
|
|
||||||
Generate bezel file name.
|
|
||||||
*/
|
|
||||||
static string getName(const Properties& props, int& index);
|
|
||||||
|
|
||||||
/*
|
|
||||||
Generate bezel file name.
|
|
||||||
*/
|
|
||||||
string getName(int& index) const;
|
|
||||||
|
|
||||||
private:
|
|
||||||
// The parent system for the bezel
|
|
||||||
OSystem& myOSystem;
|
|
||||||
|
|
||||||
// Pointer to the FrameBuffer object
|
|
||||||
FrameBuffer& myFB;
|
|
||||||
|
|
||||||
// The bezel surface which blends over the TIA surface
|
|
||||||
shared_ptr<FBSurface> mySurface;
|
|
||||||
|
|
||||||
// Bezel info structure
|
|
||||||
Info myInfo;
|
|
||||||
|
|
||||||
private:
|
|
||||||
// Following constructors and assignment operators not supported
|
|
||||||
Bezel() = delete;
|
|
||||||
Bezel(const Bezel&) = delete;
|
|
||||||
Bezel(Bezel&&) = delete;
|
|
||||||
Bezel& operator=(const Bezel&) = delete;
|
|
||||||
Bezel& operator=(Bezel&&) = delete;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,250 +0,0 @@
|
||||||
//============================================================================
|
|
||||||
//
|
|
||||||
// SSSS tt lll lll
|
|
||||||
// SS SS tt ll ll
|
|
||||||
// SS tttttt eeee ll ll aaaa
|
|
||||||
// SSSS tt ee ee ll ll aa
|
|
||||||
// SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator"
|
|
||||||
// SS SS tt ee ll ll aa aa
|
|
||||||
// SSSS ttt eeeee llll llll aaaaa
|
|
||||||
//
|
|
||||||
// Copyright (c) 1995-2025 by Bradford W. Mott, Stephen Anthony
|
|
||||||
// and the Stella Team
|
|
||||||
//
|
|
||||||
// See the file "License.txt" for information on usage and redistribution of
|
|
||||||
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
|
||||||
//============================================================================
|
|
||||||
|
|
||||||
#include "Console.hxx"
|
|
||||||
#include "EventHandler.hxx"
|
|
||||||
#include "M6502.hxx"
|
|
||||||
#include "OSystem.hxx"
|
|
||||||
#include "RewindManager.hxx"
|
|
||||||
#include "Settings.hxx"
|
|
||||||
#include "StateManager.hxx"
|
|
||||||
#include "TIA.hxx"
|
|
||||||
#include "Cart.hxx"
|
|
||||||
#include "CartELF.hxx"
|
|
||||||
|
|
||||||
#include "DevSettingsHandler.hxx"
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
DevSettingsHandler::DevSettingsHandler(OSystem& osystem)
|
|
||||||
: myOSystem{osystem}
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
void DevSettingsHandler::loadSettings(SettingsSet set)
|
|
||||||
{
|
|
||||||
const bool devSettings = set == SettingsSet::developer;
|
|
||||||
const string& prefix = devSettings ? "dev." : "plr.";
|
|
||||||
const Settings& settings = myOSystem.settings();
|
|
||||||
|
|
||||||
myFrameStats[set] = settings.getBool(prefix + "stats");
|
|
||||||
myDetectedInfo[set] = settings.getBool(prefix + "detectedinfo");
|
|
||||||
// AtariVox/SaveKey/PlusROM access
|
|
||||||
myExternAccess[set] = settings.getBool(prefix + "extaccess");
|
|
||||||
myConsole[set] = settings.getString(prefix + "console") == "7800" ? 1 : 0;
|
|
||||||
myPlusROM[set] = devSettings ? settings.getBool("dev.plusroms.on") : true;
|
|
||||||
// Randomization
|
|
||||||
myRandomBank[set] = settings.getBool(prefix + "bankrandom");
|
|
||||||
myRandomizeTIA[set] = settings.getBool(prefix + "tiarandom");
|
|
||||||
myRandomizeRAM[set] = settings.getBool(prefix + "ramrandom");
|
|
||||||
myRandomizeCPU[set] = settings.getString(prefix + "cpurandom");
|
|
||||||
// Random hotspot peeks
|
|
||||||
myRandomHotspots[set] = devSettings ? settings.getBool("dev.hsrandom") : false;
|
|
||||||
// Undriven TIA pins
|
|
||||||
myUndrivenPins[set] = devSettings ? settings.getBool("dev.tiadriven") : false;
|
|
||||||
#ifdef DEBUGGER_SUPPORT
|
|
||||||
// Read from write ports break
|
|
||||||
myRWPortBreak[set] = devSettings ? settings.getBool("dev.rwportbreak") : false;
|
|
||||||
// Write to read ports break
|
|
||||||
myWRPortBreak[set] = devSettings ? settings.getBool("dev.wrportbreak") : false;
|
|
||||||
#endif
|
|
||||||
// Thumb ARM emulation exception
|
|
||||||
myThumbException[set] = devSettings ? settings.getBool("dev.thumb.trapfatal") : false;
|
|
||||||
myArmSpeed[set] = devSettings ? settings.getInt("dev.arm.mips") : CartridgeELF::MIPS_MAX;
|
|
||||||
|
|
||||||
// TIA tab
|
|
||||||
myTIAType[set] = devSettings ? settings.getString("dev.tia.type") : "standard";
|
|
||||||
myPlInvPhase[set] = devSettings ? settings.getBool("dev.tia.plinvphase") : false;
|
|
||||||
myMsInvPhase[set] = devSettings ? settings.getBool("dev.tia.msinvphase") : false;
|
|
||||||
myBlInvPhase[set] = devSettings ? settings.getBool("dev.tia.blinvphase") : false;
|
|
||||||
myPlLateHMove[set] = devSettings ? settings.getBool("dev.tia.pllatehmove") : false;
|
|
||||||
myMsLateHMove[set] = devSettings ? settings.getBool("dev.tia.mslatehmove") : false;
|
|
||||||
myBlLateHMove[set] = devSettings ? settings.getBool("dev.tia.bllatehmove") : false;
|
|
||||||
myPFBits[set] = devSettings ? settings.getBool("dev.tia.delaypfbits") : false;
|
|
||||||
myPFColor[set] = devSettings ? settings.getBool("dev.tia.delaypfcolor") : false;
|
|
||||||
myPFScore[set] = devSettings ? settings.getBool("dev.tia.pfscoreglitch") : false;
|
|
||||||
myBKColor[set] = devSettings ? settings.getBool("dev.tia.delaybkcolor") : false;
|
|
||||||
myPlSwap[set] = devSettings ? settings.getBool("dev.tia.delayplswap") : false;
|
|
||||||
myBlSwap[set] = devSettings ? settings.getBool("dev.tia.delayblswap") : false;
|
|
||||||
|
|
||||||
// Debug colors
|
|
||||||
myDebugColors[set] = settings.getBool(prefix + "debugcolors");
|
|
||||||
// PAL color-loss effect
|
|
||||||
myColorLoss[set] = settings.getBool(prefix + "colorloss");
|
|
||||||
// Jitter
|
|
||||||
myTVJitter[set] = settings.getBool(prefix + "tv.jitter");
|
|
||||||
myTVJitterSense[set] = settings.getInt(prefix + "tv.jitter_sense");
|
|
||||||
myTVJitterRec[set] = settings.getInt(prefix + "tv.jitter_recovery");
|
|
||||||
|
|
||||||
// States
|
|
||||||
myTimeMachine[set] = settings.getBool(prefix + "timemachine");
|
|
||||||
myStateSize[set] = settings.getInt(prefix + "tm.size");
|
|
||||||
myUncompressed[set] = settings.getInt(prefix + "tm.uncompressed");
|
|
||||||
myStateInterval[set] = settings.getString(prefix + "tm.interval");
|
|
||||||
myStateHorizon[set] = settings.getString(prefix + "tm.horizon");
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
void DevSettingsHandler::saveSettings(SettingsSet set)
|
|
||||||
{
|
|
||||||
const bool devSettings = set == SettingsSet::developer;
|
|
||||||
const string& prefix = devSettings ? "dev." : "plr.";
|
|
||||||
Settings& settings = myOSystem.settings();
|
|
||||||
|
|
||||||
settings.setValue(prefix + "stats", myFrameStats[set]);
|
|
||||||
settings.setValue(prefix + "detectedinfo", myDetectedInfo[set]);
|
|
||||||
settings.setValue(prefix + "console", myConsole[set] == 1 ? "7800" : "2600");
|
|
||||||
if(myOSystem.hasConsole())
|
|
||||||
myOSystem.eventHandler().set7800Mode();
|
|
||||||
|
|
||||||
// Randomization
|
|
||||||
settings.setValue(prefix + "bankrandom", myRandomBank[set]);
|
|
||||||
settings.setValue(prefix + "tiarandom", myRandomizeTIA[set]);
|
|
||||||
settings.setValue(prefix + "ramrandom", myRandomizeRAM[set]);
|
|
||||||
settings.setValue(prefix + "cpurandom", myRandomizeCPU[set]);
|
|
||||||
|
|
||||||
if(devSettings)
|
|
||||||
{
|
|
||||||
settings.setValue("dev.plusroms.on", myPlusROM[set]);
|
|
||||||
settings.setValue("dev.hsrandom", myRandomHotspots[set]);
|
|
||||||
// Undriven TIA pins
|
|
||||||
settings.setValue("dev.tiadriven", myUndrivenPins[set]);
|
|
||||||
#ifdef DEBUGGER_SUPPORT
|
|
||||||
// Read from write ports break
|
|
||||||
settings.setValue("dev.rwportbreak", myRWPortBreak[set]);
|
|
||||||
// Write to read ports break
|
|
||||||
settings.setValue("dev.wrportbreak", myWRPortBreak[set]);
|
|
||||||
#endif
|
|
||||||
// Thumb ARM emulation exception
|
|
||||||
settings.setValue("dev.thumb.trapfatal", myThumbException[set]);
|
|
||||||
settings.setValue("dev.arm.mips", myArmSpeed[set]);
|
|
||||||
}
|
|
||||||
|
|
||||||
// AtariVox/SaveKey/PlusROM access
|
|
||||||
settings.setValue(prefix + "extaccess", myExternAccess[set]);
|
|
||||||
|
|
||||||
// TIA tab
|
|
||||||
if(devSettings)
|
|
||||||
{
|
|
||||||
settings.setValue("dev.tia.type", myTIAType[set]);
|
|
||||||
if(BSPF::equalsIgnoreCase("custom", myTIAType[set]))
|
|
||||||
{
|
|
||||||
settings.setValue("dev.tia.plinvphase", myPlInvPhase[set]);
|
|
||||||
settings.setValue("dev.tia.msinvphase", myMsInvPhase[set]);
|
|
||||||
settings.setValue("dev.tia.blinvphase", myBlInvPhase[set]);
|
|
||||||
settings.setValue("dev.tia.pllatehmove", myPlLateHMove[set]);
|
|
||||||
settings.setValue("dev.tia.mslatehmove", myMsLateHMove[set]);
|
|
||||||
settings.setValue("dev.tia.bllatehmove", myBlLateHMove[set]);
|
|
||||||
settings.setValue("dev.tia.delaypfbits", myPFBits[set]);
|
|
||||||
settings.setValue("dev.tia.delaypfcolor", myPFColor[set]);
|
|
||||||
settings.setValue("dev.tia.pfscoreglitch", myPFScore[set]);
|
|
||||||
settings.setValue("dev.tia.delaybkcolor", myBKColor[set]);
|
|
||||||
settings.setValue("dev.tia.delayplswap", myPlSwap[set]);
|
|
||||||
settings.setValue("dev.tia.delayblswap", myBlSwap[set]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Debug colors
|
|
||||||
settings.setValue(prefix + "debugcolors", myDebugColors[set]);
|
|
||||||
// PAL color loss
|
|
||||||
settings.setValue(prefix + "colorloss", myColorLoss[set]);
|
|
||||||
// Jitter
|
|
||||||
settings.setValue(prefix + "tv.jitter", myTVJitter[set]);
|
|
||||||
settings.setValue(prefix + "tv.jitter_sense", myTVJitterSense[set]);
|
|
||||||
settings.setValue(prefix + "tv.jitter_recovery", myTVJitterRec[set]);
|
|
||||||
|
|
||||||
// States
|
|
||||||
settings.setValue(prefix + "timemachine", myTimeMachine[set]);
|
|
||||||
settings.setValue(prefix + "tm.size", myStateSize[set]);
|
|
||||||
settings.setValue(prefix + "tm.uncompressed", myUncompressed[set]);
|
|
||||||
settings.setValue(prefix + "tm.interval", myStateInterval[set]);
|
|
||||||
settings.setValue(prefix + "tm.horizon", myStateHorizon[set]);
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
void DevSettingsHandler::applySettings(SettingsSet set)
|
|
||||||
{
|
|
||||||
// *** Emulation tab ***
|
|
||||||
myOSystem.frameBuffer().showFrameStats(myFrameStats[set]);
|
|
||||||
|
|
||||||
if(myOSystem.hasConsole())
|
|
||||||
{
|
|
||||||
myOSystem.console().cartridge().enableRandomHotspots(myRandomHotspots[set]);
|
|
||||||
myOSystem.console().tia().driveUnusedPinsRandom(myUndrivenPins[set]);
|
|
||||||
myOSystem.console().cartridge().enablePlusROM(myPlusROM[set]);
|
|
||||||
// Notes:
|
|
||||||
// - thumb exceptions not updated, because set in cart constructor
|
|
||||||
// - other missing settings are used on-the-fly
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef DEBUGGER_SUPPORT
|
|
||||||
// Read from write ports and write to read ports breaks
|
|
||||||
if(myOSystem.hasConsole())
|
|
||||||
{
|
|
||||||
myOSystem.console().system().m6502().setReadFromWritePortBreak(myRWPortBreak[set]);
|
|
||||||
myOSystem.console().system().m6502().setWriteToReadPortBreak(myWRPortBreak[set]);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// *** TIA tab ***
|
|
||||||
if(myOSystem.hasConsole())
|
|
||||||
{
|
|
||||||
myOSystem.console().tia().setPlInvertedPhaseClock(myPlInvPhase[set]);
|
|
||||||
myOSystem.console().tia().setMsInvertedPhaseClock(myMsInvPhase[set]);
|
|
||||||
myOSystem.console().tia().setBlInvertedPhaseClock(myBlInvPhase[set]);
|
|
||||||
myOSystem.console().tia().setPlShortLateHMove(myPlLateHMove[set]);
|
|
||||||
myOSystem.console().tia().setMsShortLateHMove(myMsLateHMove[set]);
|
|
||||||
myOSystem.console().tia().setBlShortLateHMove(myBlLateHMove[set]);
|
|
||||||
myOSystem.console().tia().setPFBitsDelay(myPFBits[set]);
|
|
||||||
myOSystem.console().tia().setPFColorDelay(myPFColor[set]);
|
|
||||||
myOSystem.console().tia().setPFScoreGlitch(myPFScore[set]);
|
|
||||||
myOSystem.console().tia().setBKColorDelay(myBKColor[set]);
|
|
||||||
myOSystem.console().tia().setPlSwapDelay(myPlSwap[set]);
|
|
||||||
myOSystem.console().tia().setBlSwapDelay(myBlSwap[set]);
|
|
||||||
}
|
|
||||||
|
|
||||||
// *** Video tab ***
|
|
||||||
if(myOSystem.hasConsole())
|
|
||||||
{
|
|
||||||
// TV Jitter
|
|
||||||
myOSystem.console().tia().toggleJitter(myTVJitter[set] ? 1 : 0);
|
|
||||||
myOSystem.console().tia().setJitterSensitivity(myTVJitterSense[set]);
|
|
||||||
myOSystem.console().tia().setJitterRecoveryFactor(myTVJitterRec[set]);
|
|
||||||
// PAL color loss
|
|
||||||
myOSystem.console().enableColorLoss(myColorLoss[set]);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Debug colours
|
|
||||||
handleEnableDebugColors(myDebugColors[set]);
|
|
||||||
|
|
||||||
// *** Time Machine tab ***
|
|
||||||
// update RewindManager
|
|
||||||
myOSystem.state().rewindManager().setup();
|
|
||||||
myOSystem.state().setRewindMode(myTimeMachine[set] ?
|
|
||||||
StateManager::Mode::TimeMachine : StateManager::Mode::Off);
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
void DevSettingsHandler::handleEnableDebugColors(bool enable)
|
|
||||||
{
|
|
||||||
if(myOSystem.hasConsole())
|
|
||||||
{
|
|
||||||
const bool fixed = myOSystem.console().tia().usingFixedColors();
|
|
||||||
if(fixed != enable)
|
|
||||||
myOSystem.console().tia().toggleFixedColors();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,104 +0,0 @@
|
||||||
//============================================================================
|
|
||||||
//
|
|
||||||
// SSSS tt lll lll
|
|
||||||
// SS SS tt ll ll
|
|
||||||
// SS tttttt eeee ll ll aaaa
|
|
||||||
// SSSS tt ee ee ll ll aa
|
|
||||||
// SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator"
|
|
||||||
// SS SS tt ee ll ll aa aa
|
|
||||||
// SSSS ttt eeeee llll llll aaaaa
|
|
||||||
//
|
|
||||||
// Copyright (c) 1995-2025 by Bradford W. Mott, Stephen Anthony
|
|
||||||
// and the Stella Team
|
|
||||||
//
|
|
||||||
// See the file "License.txt" for information on usage and redistribution of
|
|
||||||
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
|
||||||
//============================================================================
|
|
||||||
|
|
||||||
#ifndef DEV_SETTINGS_HANDLER_HXX
|
|
||||||
#define DEV_SETTINGS_HANDLER_HXX
|
|
||||||
|
|
||||||
class OSystem;
|
|
||||||
|
|
||||||
#include <array>
|
|
||||||
#include "bspf.hxx"
|
|
||||||
|
|
||||||
/**
|
|
||||||
This class takes care of developer settings sets.
|
|
||||||
|
|
||||||
@author Thomas Jentzsch
|
|
||||||
*/
|
|
||||||
class DevSettingsHandler
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
enum SettingsSet: uInt8 {
|
|
||||||
player,
|
|
||||||
developer,
|
|
||||||
numSets
|
|
||||||
};
|
|
||||||
|
|
||||||
explicit DevSettingsHandler(OSystem& osystem);
|
|
||||||
~DevSettingsHandler() = default;
|
|
||||||
|
|
||||||
void loadSettings(SettingsSet set);
|
|
||||||
void saveSettings(SettingsSet set);
|
|
||||||
void applySettings(SettingsSet set);
|
|
||||||
|
|
||||||
protected:
|
|
||||||
OSystem& myOSystem;
|
|
||||||
// Emulator sets
|
|
||||||
std::array<bool, numSets> myFrameStats{};
|
|
||||||
std::array<bool, numSets> myDetectedInfo{};
|
|
||||||
std::array<bool, numSets> myExternAccess{};
|
|
||||||
std::array<int, numSets> myConsole{};
|
|
||||||
std::array<int, numSets> myPlusROM{};
|
|
||||||
std::array<bool, numSets> myRandomBank{};
|
|
||||||
std::array<bool, numSets> myRandomizeTIA{};
|
|
||||||
std::array<bool, numSets> myRandomizeRAM{};
|
|
||||||
std::array<string, numSets> myRandomizeCPU{};
|
|
||||||
std::array<bool, numSets> myColorLoss{};
|
|
||||||
std::array<bool, numSets> myTVJitter{};
|
|
||||||
std::array<int, numSets> myTVJitterSense{};
|
|
||||||
std::array<int, numSets> myTVJitterRec{};
|
|
||||||
std::array<bool, numSets> myDebugColors{};
|
|
||||||
std::array<bool, numSets> myRandomHotspots{};
|
|
||||||
std::array<bool, numSets> myUndrivenPins{};
|
|
||||||
#ifdef DEBUGGER_SUPPORT
|
|
||||||
std::array<bool, numSets> myRWPortBreak{};
|
|
||||||
std::array<bool, numSets> myWRPortBreak{};
|
|
||||||
#endif
|
|
||||||
std::array<bool, numSets> myThumbException{};
|
|
||||||
std::array<int, numSets> myArmSpeed{};
|
|
||||||
// TIA sets
|
|
||||||
std::array<string, numSets> myTIAType{};
|
|
||||||
std::array<bool, numSets> myPlInvPhase{};
|
|
||||||
std::array<bool, numSets> myMsInvPhase{};
|
|
||||||
std::array<bool, numSets> myBlInvPhase{};
|
|
||||||
std::array<bool, numSets> myPlLateHMove{};
|
|
||||||
std::array<bool, numSets> myMsLateHMove{};
|
|
||||||
std::array<bool, numSets> myBlLateHMove{};
|
|
||||||
std::array<bool, numSets> myPFBits{};
|
|
||||||
std::array<bool, numSets> myPFColor{};
|
|
||||||
std::array<bool, numSets> myPFScore{};
|
|
||||||
std::array<bool, numSets> myBKColor{};
|
|
||||||
std::array<bool, numSets> myPlSwap{};
|
|
||||||
std::array<bool, numSets> myBlSwap{};
|
|
||||||
// States sets
|
|
||||||
std::array<bool, numSets> myTimeMachine{};
|
|
||||||
std::array<int, numSets> myStateSize{};
|
|
||||||
std::array<int, numSets> myUncompressed{};
|
|
||||||
std::array<string, numSets> myStateInterval{};
|
|
||||||
std::array<string, numSets> myStateHorizon{};
|
|
||||||
|
|
||||||
private:
|
|
||||||
void handleEnableDebugColors(bool enable);
|
|
||||||
|
|
||||||
// Following constructors and assignment operators not supported
|
|
||||||
DevSettingsHandler() = delete;
|
|
||||||
DevSettingsHandler(const DevSettingsHandler&) = delete;
|
|
||||||
DevSettingsHandler(DevSettingsHandler&&) = delete;
|
|
||||||
DevSettingsHandler& operator=(const DevSettingsHandler&) = delete;
|
|
||||||
DevSettingsHandler& operator=(DevSettingsHandler&&) = delete;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,288 +0,0 @@
|
||||||
//============================================================================
|
|
||||||
//
|
|
||||||
// SSSS tt lll lll
|
|
||||||
// SS SS tt ll ll
|
|
||||||
// SS tttttt eeee ll ll aaaa
|
|
||||||
// SSSS tt ee ee ll ll aa
|
|
||||||
// SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator"
|
|
||||||
// SS SS tt ee ll ll aa aa
|
|
||||||
// SSSS ttt eeeee llll llll aaaaa
|
|
||||||
//
|
|
||||||
// Copyright (c) 1995-2025 by Bradford W. Mott, Stephen Anthony
|
|
||||||
// and the Stella Team
|
|
||||||
//
|
|
||||||
// See the file "License.txt" for information on usage and redistribution of
|
|
||||||
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
|
||||||
//============================================================================
|
|
||||||
|
|
||||||
#include "Logger.hxx"
|
|
||||||
#include "OSystem.hxx"
|
|
||||||
#include "EventHandlerSDL.hxx"
|
|
||||||
|
|
||||||
#include "ThreadDebugging.hxx"
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
EventHandlerSDL::EventHandlerSDL(OSystem& osystem)
|
|
||||||
: EventHandler{osystem}
|
|
||||||
{
|
|
||||||
ASSERT_MAIN_THREAD;
|
|
||||||
|
|
||||||
#ifdef GUI_SUPPORT
|
|
||||||
{
|
|
||||||
ostringstream buf;
|
|
||||||
myQwertz = int{'y'} == static_cast<int>
|
|
||||||
(SDL_GetKeyFromScancode(static_cast<SDL_Scancode>(KBDK_Z), static_cast<SDL_Keymod>(StellaMod::KBDM_NONE), false));
|
|
||||||
buf << "Keyboard: " << (myQwertz ? "QWERTZ" : "QWERTY");
|
|
||||||
Logger::debug(buf.view());
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef JOYSTICK_SUPPORT
|
|
||||||
if(!SDL_InitSubSystem(SDL_INIT_JOYSTICK))
|
|
||||||
{
|
|
||||||
ostringstream buf;
|
|
||||||
buf << "ERROR: Couldn't initialize SDL joystick support: "
|
|
||||||
<< SDL_GetError() << '\n';
|
|
||||||
Logger::error(buf.view());
|
|
||||||
}
|
|
||||||
Logger::debug("EventHandlerSDL::EventHandlerSDL SDL_INIT_JOYSTICK");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
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");
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
EventHandlerSDL::~EventHandlerSDL()
|
|
||||||
{
|
|
||||||
ASSERT_MAIN_THREAD;
|
|
||||||
|
|
||||||
if(SDL_WasInit(SDL_INIT_JOYSTICK))
|
|
||||||
SDL_QuitSubSystem(SDL_INIT_JOYSTICK);
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
void EventHandlerSDL::copyText(const string& text) const
|
|
||||||
{
|
|
||||||
SDL_SetClipboardText(text.c_str());
|
|
||||||
};
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
string EventHandlerSDL::pasteText(string& text) const
|
|
||||||
{
|
|
||||||
if(SDL_HasClipboardText())
|
|
||||||
text = SDL_GetClipboardText();
|
|
||||||
else
|
|
||||||
text = "";
|
|
||||||
|
|
||||||
return text;
|
|
||||||
};
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
void EventHandlerSDL::pollEvent()
|
|
||||||
{
|
|
||||||
ASSERT_MAIN_THREAD;
|
|
||||||
|
|
||||||
while(SDL_PollEvent(&myEvent))
|
|
||||||
{
|
|
||||||
switch(myEvent.type)
|
|
||||||
{
|
|
||||||
// keyboard events
|
|
||||||
case SDL_EVENT_KEY_UP:
|
|
||||||
case SDL_EVENT_KEY_DOWN:
|
|
||||||
{
|
|
||||||
handleKeyEvent(static_cast<StellaKey>(myEvent.key.scancode),
|
|
||||||
static_cast<StellaMod>(myEvent.key.mod),
|
|
||||||
myEvent.type == SDL_EVENT_KEY_DOWN,
|
|
||||||
myEvent.key.repeat);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case SDL_EVENT_TEXT_INPUT:
|
|
||||||
{
|
|
||||||
handleTextEvent(*(myEvent.text.text));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case SDL_EVENT_MOUSE_MOTION:
|
|
||||||
{
|
|
||||||
handleMouseMotionEvent(myEvent.motion.x, myEvent.motion.y,
|
|
||||||
myEvent.motion.xrel, myEvent.motion.yrel);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case SDL_EVENT_MOUSE_BUTTON_DOWN:
|
|
||||||
case SDL_EVENT_MOUSE_BUTTON_UP:
|
|
||||||
{
|
|
||||||
// ToDo: check support of more buttons and double-click
|
|
||||||
MouseButton b{MouseButton::NONE};
|
|
||||||
switch(myEvent.button.button)
|
|
||||||
{
|
|
||||||
case SDL_BUTTON_LEFT:
|
|
||||||
b = MouseButton::LEFT;
|
|
||||||
break;
|
|
||||||
case SDL_BUTTON_RIGHT:
|
|
||||||
b = MouseButton::RIGHT;
|
|
||||||
break;
|
|
||||||
case SDL_BUTTON_MIDDLE:
|
|
||||||
b = MouseButton::MIDDLE;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
handleMouseButtonEvent(b, myEvent.button.type == SDL_EVENT_MOUSE_BUTTON_DOWN,
|
|
||||||
myEvent.button.x, myEvent.button.y);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case SDL_EVENT_MOUSE_WHEEL:
|
|
||||||
{
|
|
||||||
// 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
|
|
||||||
if(myEvent.wheel.y < 0)
|
|
||||||
handleMouseButtonEvent(MouseButton::WHEELDOWN, true,
|
|
||||||
static_cast<int>(x), static_cast<int>(y));
|
|
||||||
else if(myEvent.wheel.y > 0)
|
|
||||||
handleMouseButtonEvent(MouseButton::WHEELUP, true,
|
|
||||||
static_cast<int>(x), static_cast<int>(y));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef JOYSTICK_SUPPORT
|
|
||||||
case SDL_EVENT_JOYSTICK_BUTTON_UP:
|
|
||||||
case SDL_EVENT_JOYSTICK_BUTTON_DOWN:
|
|
||||||
{
|
|
||||||
handleJoyBtnEvent(myEvent.jbutton.which, myEvent.jbutton.button,
|
|
||||||
myEvent.jbutton.down);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case SDL_EVENT_JOYSTICK_AXIS_MOTION:
|
|
||||||
{
|
|
||||||
handleJoyAxisEvent(myEvent.jaxis.which, myEvent.jaxis.axis,
|
|
||||||
myEvent.jaxis.value);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case SDL_EVENT_JOYSTICK_HAT_MOTION:
|
|
||||||
{
|
|
||||||
int value = 0;
|
|
||||||
const int v = myEvent.jhat.value;
|
|
||||||
if(v == SDL_HAT_CENTERED)
|
|
||||||
value = EVENT_HATCENTER_M;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if(v & SDL_HAT_UP) value |= EVENT_HATUP_M;
|
|
||||||
if(v & SDL_HAT_DOWN) value |= EVENT_HATDOWN_M;
|
|
||||||
if(v & SDL_HAT_LEFT) value |= EVENT_HATLEFT_M;
|
|
||||||
if(v & SDL_HAT_RIGHT) value |= EVENT_HATRIGHT_M;
|
|
||||||
}
|
|
||||||
|
|
||||||
handleJoyHatEvent(myEvent.jhat.which, myEvent.jhat.hat, value);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case SDL_EVENT_JOYSTICK_ADDED:
|
|
||||||
{
|
|
||||||
addPhysicalJoystick(make_shared<JoystickSDL>(myEvent.jdevice.which));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case SDL_EVENT_JOYSTICK_REMOVED:
|
|
||||||
{
|
|
||||||
removePhysicalJoystick(myEvent.jdevice.which);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
case SDL_EVENT_QUIT:
|
|
||||||
{
|
|
||||||
handleEvent(Event::Quit);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case SDL_EVENT_WINDOW_SHOWN:
|
|
||||||
handleSystemEvent(SystemEvent::WINDOW_SHOWN);
|
|
||||||
break;
|
|
||||||
case SDL_EVENT_WINDOW_HIDDEN:
|
|
||||||
handleSystemEvent(SystemEvent::WINDOW_HIDDEN);
|
|
||||||
break;
|
|
||||||
case SDL_EVENT_WINDOW_EXPOSED:
|
|
||||||
handleSystemEvent(SystemEvent::WINDOW_EXPOSED);
|
|
||||||
break;
|
|
||||||
case SDL_EVENT_WINDOW_MOVED:
|
|
||||||
handleSystemEvent(SystemEvent::WINDOW_MOVED,
|
|
||||||
myEvent.window.data1, myEvent.window.data1);
|
|
||||||
break;
|
|
||||||
case SDL_EVENT_WINDOW_RESIZED:
|
|
||||||
handleSystemEvent(SystemEvent::WINDOW_RESIZED,
|
|
||||||
myEvent.window.data1, myEvent.window.data1);
|
|
||||||
break;
|
|
||||||
case SDL_EVENT_WINDOW_MINIMIZED:
|
|
||||||
handleSystemEvent(SystemEvent::WINDOW_MINIMIZED);
|
|
||||||
break;
|
|
||||||
case SDL_EVENT_WINDOW_MAXIMIZED:
|
|
||||||
handleSystemEvent(SystemEvent::WINDOW_MAXIMIZED);
|
|
||||||
break;
|
|
||||||
case SDL_EVENT_WINDOW_RESTORED:
|
|
||||||
handleSystemEvent(SystemEvent::WINDOW_RESTORED);
|
|
||||||
break;
|
|
||||||
case SDL_EVENT_WINDOW_MOUSE_ENTER:
|
|
||||||
handleSystemEvent(SystemEvent::WINDOW_ENTER);
|
|
||||||
break;
|
|
||||||
case SDL_EVENT_WINDOW_MOUSE_LEAVE:
|
|
||||||
handleSystemEvent(SystemEvent::WINDOW_LEAVE);
|
|
||||||
break;
|
|
||||||
case SDL_EVENT_WINDOW_FOCUS_GAINED:
|
|
||||||
handleSystemEvent(SystemEvent::WINDOW_FOCUS_GAINED);
|
|
||||||
break;
|
|
||||||
case SDL_EVENT_WINDOW_FOCUS_LOST:
|
|
||||||
handleSystemEvent(SystemEvent::WINDOW_FOCUS_LOST);
|
|
||||||
break;
|
|
||||||
case SDL_EVENT_SYSTEM_THEME_CHANGED:
|
|
||||||
handleSystemEvent(SystemEvent::THEME_CHANGED);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef JOYSTICK_SUPPORT
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
EventHandlerSDL::JoystickSDL::JoystickSDL(int idx)
|
|
||||||
{
|
|
||||||
ASSERT_MAIN_THREAD;
|
|
||||||
|
|
||||||
// NOLINTNEXTLINE: we want to initialize here, not in the member list
|
|
||||||
myStick = SDL_OpenJoystick(idx);
|
|
||||||
if(myStick)
|
|
||||||
{
|
|
||||||
// In Windows, all XBox controllers using the XInput API seem to name
|
|
||||||
// the controller as "XInput Controller". This would be fine, except
|
|
||||||
// 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.
|
|
||||||
// So we truncate the number.
|
|
||||||
const char* const sdlname = SDL_GetJoystickName(myStick);
|
|
||||||
const string& desc = BSPF::startsWithIgnoreCase(sdlname, "XInput Controller")
|
|
||||||
? "XInput Controller" : sdlname;
|
|
||||||
|
|
||||||
initialize(SDL_GetJoystickID(myStick), desc,
|
|
||||||
SDL_GetNumJoystickAxes(myStick),
|
|
||||||
SDL_GetNumJoystickButtons(myStick),
|
|
||||||
SDL_GetNumJoystickHats(myStick),
|
|
||||||
SDL_GetNumJoystickBalls(myStick));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
EventHandlerSDL::JoystickSDL::~JoystickSDL()
|
|
||||||
{
|
|
||||||
ASSERT_MAIN_THREAD;
|
|
||||||
|
|
||||||
if(SDL_WasInit(SDL_INIT_JOYSTICK) && myStick)
|
|
||||||
SDL_CloseJoystick(myStick);
|
|
||||||
}
|
|
||||||
#endif
|
|