Compare commits

..

1 Commits

Author SHA1 Message Date
yabause 08435def85 tagging again :) 2009-04-24 19:35:21 +00:00
2244 changed files with 118698 additions and 878525 deletions

View File

@ -1,19 +0,0 @@
---
name: New Issue, Bug report, Question
about: New Issue, Bug report, Question
title: ''
labels: ''
assignees: ''
---
## State your operating system:
Windows/Mac/Linux. in case of linux, whether you use CLI, gtk2, or gtk3 version.
## DesMuME version
e.g. 0.9.13 or git master
## Isse
type here what's bothering you, in a detailed manner.

View File

@ -1,80 +0,0 @@
name: DeSmuME
on:
- push
- pull_request
jobs:
build:
name: Build DeSmuME (Linux)
runs-on: ubuntu-24.04
steps:
- name: checkout
uses: actions/checkout@v4
- name: install dependencies
run: sudo apt update && sudo apt install meson libsdl2-dev libpcap-dev libgtk-3-dev
- name: meson
run: |
cd desmume/src/frontend/posix/
meson build
- name: ninja
run: ninja -C desmume/src/frontend/posix/build
build_gtk2:
name: Build DeSmuME (Linux/GTK+2)
runs-on: ubuntu-24.04
steps:
- name: checkout
uses: actions/checkout@v4
- name: install dependencies
run: sudo apt update && sudo apt install autoconf libglu1-mesa-dev libsdl2-dev libpcap-dev libgtk2.0-dev
- name: buildit
run: |
cd desmume/src/frontend/posix/
autoreconf -i
./configure --prefix=/usr --enable-gdb-stub --enable-wifi
make -j8
make DESTDIR=/tmp/DeSmuME install
- name: Pack artifact
run: |
cd /tmp
tar cJf DeSmuME.tar.xz DeSmuME/
- name: Upload artifact
uses: actions/upload-artifact@v4
with:
name: desmume-linux-gtk2-cli-x86_64
path: /tmp/DeSmuME.tar.xz
build_macos:
name: Build DeSmuME (macOS)
runs-on: macos-14
steps:
- name: checkout
uses: actions/checkout@v4
- name: xcodebuild
run: |
cd desmume/src/frontend/cocoa/
xcodebuild archive -project "DeSmuME (Latest).xcodeproj" -scheme "DeSmuME (macOS App; Intel64 -- Latest Xcode)" -arch x86_64 -archivePath "$(pwd)/desmume.xcarchive" | xcpretty -c
- name: make zip
run: |
cd desmume/src/frontend/cocoa/desmume.xcarchive/Products/Applications/
7z a DeSmuME.app.zip DeSmuME.app
- name: Upload artifict
uses: actions/upload-artifact@v4
with:
name: macos
path: desmume/src/frontend/cocoa/desmume.xcarchive/Products/Applications/DeSmuME.app.zip
if-no-files-found: error

View File

@ -1,87 +0,0 @@
name: DeSmuME Interface (DLL/SO)
on:
- push
- pull_request
jobs:
build_linux:
runs-on: ubuntu-24.04
name: Build Linux
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Install dependencies
run: sudo apt update && sudo apt install meson libsdl2-dev libpcap-dev
- name: Build - Meson
run: |
cd desmume/src/frontend/interface/
meson build
- name: Build - ninja
run: ninja -C desmume/src/frontend/interface/build
- name: Upload artifact
uses: actions/upload-artifact@v4
with:
name: linux
path: desmume/src/frontend/interface/build/libdesmume.so
build_macos:
runs-on: macos-14
name: Build MacOS
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Install MacOS build deps
run: brew install coreutils sdl2 meson
- name: Build - Meson
run: |
cd desmume/src/frontend/interface/
meson build
env:
CC: clang
CXX: clang++
- name: Build - ninja
run: ninja -C desmume/src/frontend/interface/build
env:
CC: clang
CXX: clang++
- name: Upload artifact
uses: actions/upload-artifact@v4
with:
name: macos
path: desmume/src/frontend/interface/build/libdesmume.dylib
build_windows:
runs-on: windows-2022
name: Build Windows
strategy:
fail-fast: false
matrix:
arch: [ 'x64', 'x86' ]
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Add msbuild to PATH
uses: microsoft/setup-msbuild@v2
with:
msbuild-architecture: ${{ matrix.arch }}
- name: Build
run: |
cd desmume\src\frontend\interface\windows
MSBuild.exe DeSmuME_Interface.vcxproj /p:configuration="Release Fastbuild" /p:Platform=${{ matrix.arch }}
- name: Upload artifact
uses: actions/upload-artifact@v4
with:
name: win-${{ matrix.arch }}
path: desmume/src/frontend/interface/windows/__bins/*.dll

View File

@ -1,30 +0,0 @@
name: DeSmuME Windows build
on:
- push
- pull_request
jobs:
build-sln:
runs-on: windows-2022
steps:
- uses: actions/checkout@v4
- name: Setup MSBuild.exe
uses: microsoft/setup-msbuild@v2
with:
msbuild-architecture: x64
- name: Build solution
run: |
SET CL=-Wno-c++11-narrowing
msbuild 'desmume/src/frontend/windows/DeSmuME.sln' /p:configuration="Release" /p:platform=x64 /p:CL_cgthreads=1 /p:CLToolExe=clang-cl.exe
cmd /c desmume\src\frontend\windows\ci_postbuild.bat
- name: Upload artifact
uses: actions/upload-artifact@v4
with:
name: desmume-win-x64
path: desmume/src/frontend/windows/__bins/*.exe

View File

@ -1,43 +0,0 @@
name: Generate Source Tarball
# Trigger whenever a release is created
on:
release:
types:
- created
jobs:
build:
name: build
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
with:
submodules: recursive
- name: archive
id: archive
run: |
THISDIR="$PWD"
cd desmume/src/frontend/posix
autoreconf -i
cd "$THISDIR"
VERSION=$(printf "%s\n" ${{ github.event.release.tag_name }} | sed -e 's/^release_//' -e 's/_/./g')
PKGNAME="desmume-$VERSION"
mkdir -p /tmp/$PKGNAME
mv * /tmp/$PKGNAME
mv /tmp/$PKGNAME .
TARBALL=$PKGNAME.tar.xz
tar cJf $TARBALL $PKGNAME
echo "::set-output name=tarball::$TARBALL"
- name: upload tarball
uses: actions/upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ github.event.release.upload_url }}
asset_path: ./${{ steps.archive.outputs.tarball }}
asset_name: ${{ steps.archive.outputs.tarball }}
asset_content_type: application/x-xz

77
.gitignore vendored
View File

@ -1,77 +0,0 @@
/desmume/src/scmrev.h
/desmume/src/frontend/windows/defaultconfig/scmrev.h
/desmume/src/frontend/windows/.libs
/desmume/src/frontend/windows/.obj
/desmume/src/frontend/windows/__bins
/desmume/src/frontend/windows/*.tlog
/desmume/src/frontend/windows/*.aps
.vs/
*.user
*.suo
*.VC.db
*.VC.opendb
*.o
*.ipch
.deps
*.dirstamp
Makefile.in
/desmume/src/frontend/posix/missing
/desmume/src/frontend/posix/*.a
/desmume/src/frontend/posix/autom4te.cache
/desmume/src/frontend/posix/Makefile
/desmume/src/frontend/posix/aclocal.m4
/desmume/src/frontend/posix/configure
/desmume/src/frontend/posix/cli/Makefile
/desmume/src/frontend/posix/cli/desmume-cli
/desmume/src/frontend/posix/cli/doc/Makefile
/desmume/src/frontend/posix/compile
/desmume/src/frontend/posix/config.guess
/desmume/src/frontend/posix/config.log
/desmume/src/frontend/posix/config.status
/desmume/src/frontend/posix/config.sub
/desmume/src/frontend/posix/depcomp
/desmume/src/frontend/posix/gtk/Makefile
/desmume/src/frontend/posix/gtk/desmume
/desmume/src/frontend/posix/gtk/doc/Makefile
/desmume/src/frontend/posix/gtk-glade/Makefile
/desmume/src/frontend/posix/gtk-glade/desmume-glade
/desmume/src/frontend/posix/gtk-glade/doc/Makefile
/desmume/src/frontend/posix/install-sh
/desmume/src/frontend/cocoa/openemu/OpenEmuBase.framework/
/desmume/src/frontend/cocoa/OptimizationProfiles/
# Xcode
## Build generated
build/
DerivedData/
## Various settings
*.pbxuser
!default.pbxuser
*.mode1v3
!default.mode1v3
*.mode2v3
!default.mode2v3
*.perspectivev3
!default.perspectivev3
xcuserdata/
.vs/ProjectSettings.json
## Other
*.moved-aside
*.xcuserstate
*.xcscmblueprint
## Obj-C/Swift specific
*.hmap
*.ipa
*.dSYM.zip
*.dSYM
## Eclipse CDT generated files
/.autotools
/.cproject
/config.log
/.project
.DS_Store

View File

@ -6,12 +6,22 @@ Current team
------------
Guillaume Duhamel
Normmatt
Bernat Muñoz (shash)
thoduv
Tim Seidel (Mighty Max)
Pascal Giard (evilynux)
Ben Jaques (masscat)
Jeff Bland
Riccardo Magliocchetti
Max Tabachenko (CrazyMax)
zeromus
rogerman
Luigi__
adelikat
matusz
pa__
Contributors
------------
Bernat Muñoz (shash)
Allustar
amponzi
Anthony Molinaro
@ -21,30 +31,3 @@ delfare
Romain Vallet
snkmad
Theo Berkau
thoduv
Tim Seidel (Mighty Max)
Pascal Giard (evilynux)
Ben Jaques (masscat)
Jeff Bland
Bernat Muñoz (shash)
matusz
nitsuja
gocha
pa__
adelikat
hi-coder
WinterMute
pengvado
dormito
ldesnogue
mtheall
thelemonman
nash679
pokefan999
dottorleo
yki
Luigi__
CrazyMax
Riccardo Magliocchetti
CyberWarriorX
mic

View File

@ -1,12 +1,12 @@
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
@ -15,7 +15,7 @@ software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Lesser General Public License instead.) You can apply it to
the GNU Library General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
@ -55,8 +55,8 @@ patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
@ -110,7 +110,7 @@ above, provided that you also meet all of these conditions:
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
@ -168,7 +168,7 @@ access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
@ -225,7 +225,7 @@ impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
@ -255,7 +255,7 @@ make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
NO WARRANTY
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
@ -277,9 +277,9 @@ YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
@ -303,16 +303,17 @@ the "copyright" line and a pointer to where the full notice is found.
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:
Gnomovision version 69, Copyright (C) year name of author
Gnomovision version 69, Copyright (C) year name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
@ -335,5 +336,5 @@ necessary. Here is a sample; alter the names:
This General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library. If this is what you want to do, use the GNU Lesser General
library. If this is what you want to do, use the GNU Library General
Public License instead of this License.

360
ChangeLog Normal file
View File

@ -0,0 +1,360 @@
0.9.2 -> 0.9.2-1
General/Core:
bug: fixed compilation for 64 bits linux systems
bug: fixed compilation when using --enable-osmesa with recent osmesa versions
0.9.1 -> 0.9.2
General/Core:
bug: fix error in SBCS/RSCS flags; fixes many odd behaviors and crashes [zeromus]
bug: add support for sleep mode and power registers [luigi__]
bug: important fixes to RTC so correct time is actually told [luigi__]
bug: fix card reads below 0x8000; fixes some game freezes [normatt]
bug: fix 4 mbit save type; fix non-autodetect savefile dumping [zeromus, matusz]
enh: add sram to GBA game addon emulation for importing savefiles [zeromus]
enh: many improvements and feature hookups in linux ports [matusz, luigi__]
Graphics:
bug: fix specular texture mapping mode [luigi__]
bug: repairs to some capture modes and vram mapping [zeromus, CrazyMax]
bug: viewports finally correctly handled [zeromus]
enh: add software rasterizer. quirky, but on par with opengl [zeromus]
Windows:
bug: mitigate bad frameskipper; default to old frameskipping mode [zeromus]
bug: fixes with recent roms and zipfile loading [zeromus]
bug: fix window position memory [zeromus]
enh: bios and firmware may now be used and booted [luigi__]
enh: many display, OSD, and input enhancements [luigi__]
enh: brand new hotkey and controls binding system [zeromus]
enh: configurable screen separation [luigi__]
enh: fast forward key [pa__]
enh: improvements to mic [luigi__]
enh: faster updates in debug tools, up to once per frame [pa__]
Mac OS X Port:
enh: added Italian translation thanks to Paolo Bernini [jeff]
enh: resurrection of GDB stub [sigmaris]
0.9 -> 0.9.1
General/Core:
enh: GBA slot emulation [CrazyMax]
- Rumble support (windows only)
- GBA game
enh: Mic support (windows only?) [luigi__]
enh: Preliminary cheats system [CrazyMax]
enh: Savestates invalidated, as more variables have been added.
bug: Added PSG white noise [luigi__]
bug: fix arm/thumb ROR [zeromus]
bug: [ 2550645 ] Super Princess Peach: crash when starting a puzzle [zeromus]
bug: win32: fix spu wav file writer (regression from 0.8) [zeromus,luigi__]
bug: Much work on FIFOs, still not finished [CrazyMax]
bug: Many fixes to dma [zeromus, CrazyMax]
bug: bios WaitForVblank and WaitForInterrupt fixed [luigi__]
Graphics:
bug: Added sprite blending [luigi__]
bug: more correct mosaic effects, still imperfect [zeromus]
bug: Many fixes to tile rendering; all graphics tests now pass [luigi__]
bug: fix crashes in some affine BG [zeromus]
bug: Implement some pos test function [luigi__]
bug: fix texture mapping across texture and palette banks and to unmapped banks [zeromus]
bug: fix texture handling for texels with MSB set (fixes some texture corruption) [zeromus]
bug: fix texture coordinate generation, including environment mapping [zeromus]
bug: texture cache invalidates when palettes change, prevents some texture corruption [zeromus]
bug: fix display capturing from 2d+3d source when display mode is display-vram [zeromus]
bug: [ 2488334 ].1 fixes to layer compositing [luigi__]
bug: [ 2488334 ].3 fix bug in support for hdma affine bg parameters [zeromus]
bug: Improvements to 3d h-scrolling [luigi__]
bug: Fix some errors in rendering 512 tall BG [zeromus,CrazyMax] (still not fully resolved)
bug: Add optional fragment shading pipeline (more precision) [luigi__]
bug: Fix bug where some sprites got cut of on x=255 [zeromus]
bug: Implement GXSTAT register [CrazyMax]
Windows:
bug: resizing and rotating work in vista [luigi__]
enh: 0 frameskip now lets emulator run at excess speed [zeromus]
Mac OS X Port:
bug: left key setting no longer gets confused with the right key [jeff]
enh: more keys can be mapped
0.8 -> 0.9
There have been so many changes that this list can hardly be considered complete.
For this release, we have formatted the list into a high level overview of big changes and bad bugs relative to the previous release. Hopefully what you're interested in.
This list does not include items which are solely performance boosts, for let us just say that virtually every system has been speeded up.
* The savestate system is totally changed and incompatible with old savestates.
* The 3d system should be considered rewritten.
General/Core:
enh: Convert to c++
enh: Add functions for a lid open/close. Holding key (default "Backspace" in Windows port) while game is freeze/non freeze. [CrazyMax]
enh: Add secure area decryption from ndstool [zeromus]
enh: Change savestate code to support loosely bound chunks and more easily other parts of the emu (GE, GPU).
The savestate format is changed, but from now on it is in principle more resilient
(though it will continue to break as we tinker with the internals) [zeromus]
enh: Added SSE2 optimizations for matrices. Since we now make an SSE2 build, more optimizations can be made. [CrazyMax]
enh: Add a preliminary GUI hud system [CrazyMax,zeromus]
CPU/MMU:
bug: Many fixes in IPC and GE FIFOs. Fixes freezes in NSMB, dsracing, and others. [CrazyMax,luigi__,shash]
bug: Fix ARM instructions SBC and RSC (likewise SBC in thumb) [normatt]
bug: Fixed Thumb LDMIA (fixes ingame Dead'n'Furious) [shash]
bug: Fix repeating DMA (fixes NSMB parallax BG) [zeromus]
bug: Proper handling for unaligned CPU accesses [luigi__]
bug: Proper handling for undefined instruction exceptions [Salva Peiró]
bug: correctly return vram control register values (fixes homebrew 3d games) [zeromus]
enh: Remove 16MB of WRAM at 0x01****** from arm9. Mapped to unused instead. Nobody knows what this was. [zeromus]
enh: Changed instruction execution to 16 at a time blocks (tested and stable) [shash]
Hardware:
bug: Newer and better sqrt and div emulation; makes SM64DS playable [luigi__,shash,zeromus]
bug: Add preliminary RTC implementations [CrazyMax]
enh: Add cosine interpolation in the SPU (conditionally compiled) [zeromus,luigi__]
enh: Experimental: always one silent non-mixing SPU core at 44.1khz synched with emu, for more precision.
The audible core runs with the host, causing music to slow down but not tear or pitch bend. [zeromus]
Graphics:
- Overhaul 3d:
. Move entire GE to core emu.
. Move OpenGL renderer to emu core for optional use by platforms, removing ogl_collector. Now every platform shares the same 3d code.
. Reorganize 3d code to defer rendering to after 3d vblank. Eliminates tearing, and texturing artifacts. [zeromus]
. Add optional fragment shading pipeline (more precision) [luigi__]
. Move lighting model to software instead of using opengl's fixed function model [zeromus]
. Render shadow volumes; toon shading and highlight table [zeromus, luigi__]
. Added texture caching! big speed up. [CrazyMax]
bug: Many assorted tweaks and improvements to 3d and 2d precision [zeromus,CrazyMax,luigi__]
bug: Fixes to GE: command unpacking, projection and pos-vector mode matrix handling, mult and load commands [zeromus]
bug: Fix a bug in texture transformation mode 1 [zeromus]
bug: Fixed GPU rendering bugs in sprites and BG [CrazyMax]
bug: Fixes to texture conversion [CrazyMax,zeromus]
bug: Fixes in capture display (no blinking in many games with dual 3D) [CrazyMax]
bug: Fixes in master brightness (this fixes some games with black screens) [CrazyMax]
bug: Fixes in screen, backdrop, and sprite blending [luigi__]
bug: Changed clear depths and how depth initial values are calculated (fixes SM64DS skybox, Castlevania) [shash,lugi__]
bug: Add 3d layer h-scrolling [zeromus]
bug: Added transparency and fixed material alpha support and alpha testing on the 3D core [shash]
bug: Rewrite VRAM mapping control and rendering (more accurate) [CrazyMax,luigi__]
bug: convert colors to opengl better to prevent alpha=31 polys from being ever so slightly transparent [zeromus]
enh: Add MMU->GPU signal for when vram mappings change to function as a texture cache invalidate signal [zeromus]
enh: Make matrix 4x4 multiply routines use W-coordinate; carry w coord through pipeline [zeromus]
Mac OS X port:
bug: Fixed: Filenames and paths with unicode characters now work. [Jeff]
bug: Fixed: Load state from file button works again. [Jeff]
enh: Save State panel now pauses emulation while the file selection box is open. [Jeff]
bug: Fixed: Frozen video output (and/or messed 3d emulation) after loading a state. [Jeff]
bug: Added option to load the most recent file upon launching the program. [Jeff]
enh: Added French translation (thanks to Pierre Rudloff). [Jeff]
enh: Added basic key mapping configuration to application preferences (thanks to Julio GorgŽ). [Jeff]
enh: Added keyboard shortcuts for Execute, Pause and Reset command (thanks to Julio GorgŽ). [Jeff]
enh: Default key mappings are no longer case sensitive. [Jeff]
enh: Added ability to limit speed. [Jeff]
enh: Fixed: Video output should work on software-only 3D renderers. [Jeff]
Windows port:
bug: Fix a race condition in NDS_3D_Reset and NDS_glInit [zeromus]
bug: Fix the buggy auto frameskip logic which made the emu slow to a crawl. Now it runs fast! [zeromus]
bug: Fix resizing, rotate & aspect ration of main window. [CrazyMax,_zeromus]
bug: Remove multithreading from user interface after finding several synchronization issues [zeromus]
enh: recent roms menu [luigi_]
enh: Changed graphics render core to DirectDraw (work faster) [CrazyMax]
enh: Add an arm9 cpu load average calculator similar to no$. but I dont think it works right. [zeromus]
enh: Rewrite all debug tools (autoupdate works now) [CrazyMax]
enh: Rewrite input core & replace config input dialog [CrazyMax]
enh: Add AVI output [zeromus]
enh: Add pause toggle and frame advance hotkeys [adelikat]
enh: Add frame counter display and hud messages framework [adelikat]
enh: Main window remembers position, size, and a few other emu preferences [adelikat]
enh: Removed directx sdk dependency for easier building. [zeromus]
enh: Savestate doesnt unpause emu if it is already paused [adelikat]
0.7.3 -> 0.8
Cocoa:
- Save State As function now works. [Jeff B]
- Recent Items menu now works. [Jeff B]
- Opening NDS files from Finder now works. [Jeff B]
- Added screenshot feature. [Jeff B]
- Added preferences. [Jeff B]
- Many more strings are translatable now. [Jeff B]
- Default screen color is black (better represents being "off" and easier on eyes at night). [Jeff B]
- Added sound. [Jeff B]
- Now is a universal binary. [Jeff B]
- Leopard resolution icon added. [Jeff B]
- Added a Japanese translation. [Jeff B]
- Added an optional status bar (resize handle no longer overlaps screen). [Jeff B]
- New ROM Info and About DeSmuME windows have been added. [Jeff B]
- Fixed several bugs in window resizing. [Jeff B]
- Added FAT image support for homebrew games (thanks to TypeError). [Jeff B]
- Key config can be changed on the command line. Save/load hotkeys changed (so expose doesn't override). [Jeff B]
- Key bindings may work better on non-US keyboards now (needs testing). [Jeff B]
general:
- Encapsulate GDB debug stub to avoid certain problems [shash]
- Fixed CPU LD*/ST* bugs [shash]
- Fixed New SMB mini-games freeze [shash]
- Fixed possible segfault in ROMReader on ia64 and amd64. [evilynux]
- Fixed a crash bug with 2D background corrupting memory [shash]
- Flag check optimization [carlo_bramini]
- Applied some endian fixes in GPU (thanks to Phazz) [Jeff B]
gtk-glade:
- Added DeSmuME version in about dialog. [evilynux]
- Updated website url in about dialog. [evilynux]
- Added Brazilian Portuguese translation by Dreampeppers99. [evilynux]
- Better desktop menu entry following FreeDesktop specifications. [evilynux]
gtk:
- Updated website url in about dialog. [evilynux]
- Better desktop menu entry following FreeDesktop specifications. [evilynux]
windows port:
- Added an "about" box [shash]
- DirectInput control interface with joystick support [CrazyMax]
- Matrix and Light viewer [Acid Burn]
0.7.2 -> 0.7.3
gtk-glade:
- Full localization using intltool/gettext. [evilynux]
general:
- Added a README.TRANSLATION documenting the localization process. [evilynux]
MacOS X:
- Initial version of the Mac interface added. [Jeff B]
0.7.1 -> 0.7.2
spu:
- big endian fixes. [cyberwarriorx]
gpu:
- big endian fixes. [marcus_c]
gtk-glade:
- opengl improvements. [masscat]
general:
- Added support for setting NDS firmware language value. [masscat]
- Function added for setting firmware language. [masscat]
- Mac/msys compilation fixes. [cyberwarriorx]
- Fix compilation when pkg-config macros are not available [evilynux]
0.7.0 -> 0.7.1
general:
- Added GDB debugger stub [masscat]
- Added new/different GBAMP CFlash image reader/writer [masscat]
gpu:
- Major speedup to the 2D core [shash]
gtk-glade:
- Added command line options. [masscat]
- Added FPS limiter [masscat]
cli:
- Added command line options. [masscat]
- Added FPS limiter [masscat]
- Added option to use OpenGl to render window (allows resizing). [masscat]
windows port:
- Added command line options. [masscat]
- Added multiple language support [cyberwarriorx]
- Added Danish language translation [thomas-2007]
0.6.0 -> 0.7.0
general:
- Added support for *.duc files [cyberwarriorx]
gpu:
- Added support for sprite rotation/scaling [shash]
- Added support for the 3D core (openGL and null plugins) [shash]
windows port:
- A bunch of fixes [Dmitry Krutskih]
- Fixed a bug in sound that was causing it to still not work for some
people [cyberwarriorx]
gtk:
- Added 3D emulation
- Added command line options.
- Added option to use OpenGL to render window (allows resizing).
gtk-glade:
- Added 3D emulation
0.5.0 -> 0.6.0
general:
- Added zipped (based on zziplib) and gzipped (based on zlib) rom support.
arm:
- Added relocation interrupt vector.
- Added region access right checks.
- Enabled LDC/STC instructions.
- Fixed powersave (cp15) IRQ wait.
- Fixed MOV instructions
gpu:
- Added special color effects.
- Added windowing feature.
- Fixed transparent direct color backgrounds.
- Fixed disabled sprites showing.
- Fixed 8/32 bit access to gpu registers.
- Fixed missing backgrounds
- Support for master brightness
wifi:
- Added RF chip interface.
- Added BB chip interface.
windows port:
- Fixed address calculation in disassembler.
- Added Force Maintain Ratio option for window stretching
linux port (cli, gtk and gtk-glade):
all:
- Added joystick support.
- Fixed X and Y buttons.
gtk-glade:
- Added joystick configuration.
- Improved I/O registers viewer tool.
- Added save and load states support.
0.3.3 -> 0.5.0
arm:
- Fixed MSR with immediate value opcode.
- Fixed LSR_0 thumb opcode (C flag is correctly set now).
- Fixed LDR*/STR* opcodes.
- Fixed unaligned memory access on THUMB Core.
- Added relocating SWI routines.
bios:
- Added decompression functions.
- Added GetPitchTable function.
- Added GetVolumeTable function.
- Added GetCRC16 function.
- Added experimental SoundBias function.
- Added GetSineTable function.
cart:
- Added CompactFlash/FAT emulation.
- Added Get ROM chip ID Cartridge command.
gpu:
- Added framebuffer emulation.
- Fixed a bug in GPU (xfin could be greater than LG causing a segfault).
- Added support for Display Mode 0(Display Off).
- Added the basic framework for Display Mode 3(Display from Main RAM).
spu:
- Added sound emulation.
- Added sound core system.
- Added WAV write core.
- Added dummy core.
- Added Direct Sound core.
linux port:
- Added GTK+ GUI.
- Added command line interface.
- Added stylus and arm9 keypad support in CLI version.
- Added FPS display.
- Added basic frameskip.
windows port:
- Fixed a bug when displaying a ROM's information.
- Added key configuration.
- Removed the debug key.
- Added new experimental auto frameskip/frame limit code.
- Added sound settings dialog.
- Added a few menu options for accessing the website, forums, and for
submitting bugs.
general:
- Rewrote code in C.
- Fixed warnings.
- Used defines and typedef's to make things more portable and easier to
read.
- Added autotools stuff.
- Changes to logging system.
- Added screenshot function.
- Translated most french to english.
- Added savestate support.
- Added firmware reading support(needs work).
- Added Backup Memory support with autodetection.
- Fixed some endianess issues.
- Fixed things so Visual C++ can compile code.
- Added bsd support.
- Reworked ROM loading so you can load a different rom without any problems.
- Finished NDS_Reset. Now the emulation can be reset even while running.

237
INSTALL Normal file
View File

@ -0,0 +1,237 @@
Installation Instructions
*************************
Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002, 2004, 2005,
2006, 2007 Free Software Foundation, Inc.
This file is free documentation; the Free Software Foundation gives
unlimited permission to copy, distribute and modify it.
Basic Installation
==================
Briefly, the shell commands `./configure; make; make install' should
configure, build, and install this package. The following
more-detailed instructions are generic; see the `README' file for
instructions specific to this package.
The `configure' shell script attempts to guess correct values for
various system-dependent variables used during compilation. It uses
those values to create a `Makefile' in each directory of the package.
It may also create one or more `.h' files containing system-dependent
definitions. Finally, it creates a shell script `config.status' that
you can run in the future to recreate the current configuration, and a
file `config.log' containing compiler output (useful mainly for
debugging `configure').
It can also use an optional file (typically called `config.cache'
and enabled with `--cache-file=config.cache' or simply `-C') that saves
the results of its tests to speed up reconfiguring. Caching is
disabled by default to prevent problems with accidental use of stale
cache files.
If you need to do unusual things to compile the package, please try
to figure out how `configure' could check whether to do them, and mail
diffs or instructions to the address given in the `README' so they can
be considered for the next release. If you are using the cache, and at
some point `config.cache' contains results you don't want to keep, you
may remove or edit it.
The file `configure.ac' (or `configure.in') is used to create
`configure' by a program called `autoconf'. You need `configure.ac' if
you want to change it or regenerate `configure' using a newer version
of `autoconf'.
The simplest way to compile this package is:
1. `cd' to the directory containing the package's source code and type
`./configure' to configure the package for your system.
Running `configure' might take a while. While running, it prints
some messages telling which features it is checking for.
2. Type `make' to compile the package.
3. Optionally, type `make check' to run any self-tests that come with
the package.
4. Type `make install' to install the programs and any data files and
documentation.
5. You can remove the program binaries and object files from the
source code directory by typing `make clean'. To also remove the
files that `configure' created (so you can compile the package for
a different kind of computer), type `make distclean'. There is
also a `make maintainer-clean' target, but that is intended mainly
for the package's developers. If you use it, you may have to get
all sorts of other programs in order to regenerate files that came
with the distribution.
6. Often, you can also type `make uninstall' to remove the installed
files again.
Compilers and Options
=====================
Some systems require unusual options for compilation or linking that the
`configure' script does not know about. Run `./configure --help' for
details on some of the pertinent environment variables.
You can give `configure' initial values for configuration parameters
by setting variables in the command line or in the environment. Here
is an example:
./configure CC=c99 CFLAGS=-g LIBS=-lposix
*Note Defining Variables::, for more details.
Compiling For Multiple Architectures
====================================
You can compile the package for more than one kind of computer at the
same time, by placing the object files for each architecture in their
own directory. To do this, you can use GNU `make'. `cd' to the
directory where you want the object files and executables to go and run
the `configure' script. `configure' automatically checks for the
source code in the directory that `configure' is in and in `..'.
With a non-GNU `make', it is safer to compile the package for one
architecture at a time in the source code directory. After you have
installed the package for one architecture, use `make distclean' before
reconfiguring for another architecture.
Installation Names
==================
By default, `make install' installs the package's commands under
`/usr/local/bin', include files under `/usr/local/include', etc. You
can specify an installation prefix other than `/usr/local' by giving
`configure' the option `--prefix=PREFIX'.
You can specify separate installation prefixes for
architecture-specific files and architecture-independent files. If you
pass the option `--exec-prefix=PREFIX' to `configure', the package uses
PREFIX as the prefix for installing programs and libraries.
Documentation and other data files still use the regular prefix.
In addition, if you use an unusual directory layout you can give
options like `--bindir=DIR' to specify different values for particular
kinds of files. Run `configure --help' for a list of the directories
you can set and what kinds of files go in them.
If the package supports it, you can cause programs to be installed
with an extra prefix or suffix on their names by giving `configure' the
option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'.
Optional Features
=================
Some packages pay attention to `--enable-FEATURE' options to
`configure', where FEATURE indicates an optional part of the package.
They may also pay attention to `--with-PACKAGE' options, where PACKAGE
is something like `gnu-as' or `x' (for the X Window System). The
`README' should mention any `--enable-' and `--with-' options that the
package recognizes.
For packages that use the X Window System, `configure' can usually
find the X include and library files automatically, but if it doesn't,
you can use the `configure' options `--x-includes=DIR' and
`--x-libraries=DIR' to specify their locations.
Specifying the System Type
==========================
There may be some features `configure' cannot figure out automatically,
but needs to determine by the type of machine the package will run on.
Usually, assuming the package is built to be run on the _same_
architectures, `configure' can figure that out, but if it prints a
message saying it cannot guess the machine type, give it the
`--build=TYPE' option. TYPE can either be a short name for the system
type, such as `sun4', or a canonical name which has the form:
CPU-COMPANY-SYSTEM
where SYSTEM can have one of these forms:
OS KERNEL-OS
See the file `config.sub' for the possible values of each field. If
`config.sub' isn't included in this package, then this package doesn't
need to know the machine type.
If you are _building_ compiler tools for cross-compiling, you should
use the option `--target=TYPE' to select the type of system they will
produce code for.
If you want to _use_ a cross compiler, that generates code for a
platform different from the build platform, you should specify the
"host" platform (i.e., that on which the generated programs will
eventually be run) with `--host=TYPE'.
Sharing Defaults
================
If you want to set default values for `configure' scripts to share, you
can create a site shell script called `config.site' that gives default
values for variables like `CC', `cache_file', and `prefix'.
`configure' looks for `PREFIX/share/config.site' if it exists, then
`PREFIX/etc/config.site' if it exists. Or, you can set the
`CONFIG_SITE' environment variable to the location of the site script.
A warning: not all `configure' scripts look for a site script.
Defining Variables
==================
Variables not defined in a site shell script can be set in the
environment passed to `configure'. However, some packages may run
configure again during the build, and the customized values of these
variables may be lost. In order to avoid this problem, you should set
them in the `configure' command line, using `VAR=value'. For example:
./configure CC=/usr/local2/bin/gcc
causes the specified `gcc' to be used as the C compiler (unless it is
overridden in the site shell script).
Unfortunately, this technique does not work for `CONFIG_SHELL' due to
an Autoconf bug. Until the bug is fixed you can use this workaround:
CONFIG_SHELL=/bin/bash /bin/bash ./configure CONFIG_SHELL=/bin/bash
`configure' Invocation
======================
`configure' recognizes the following options to control how it operates.
`--help'
`-h'
Print a summary of the options to `configure', and exit.
`--version'
`-V'
Print the version of Autoconf used to generate the `configure'
script, and exit.
`--cache-file=FILE'
Enable the cache: use and save the results of the tests in FILE,
traditionally `config.cache'. FILE defaults to `/dev/null' to
disable caching.
`--config-cache'
`-C'
Alias for `--cache-file=config.cache'.
`--quiet'
`--silent'
`-q'
Do not print messages saying which checks are being made. To
suppress all normal output, redirect it to `/dev/null' (any error
messages will still be shown).
`--srcdir=DIR'
Look for the package's source code in directory DIR. Usually
`configure' can determine that directory automatically.
`configure' also accepts some other, not widely useful, options. Run
`configure --help' for more details.

5
Makefile.am Normal file
View File

@ -0,0 +1,5 @@
EXTRA_DIST = README.LIN README.MAC README.WIN README.TRANSLATION autogen.sh \
$(PO_FILES_IN)
DISTCLEANFILES = $(PO_FILES)
SUBDIRS = $(PO_DIR) src

69
README Normal file
View File

@ -0,0 +1,69 @@
DeSmuME
_________________________________________
Copyright (C) 2006 yopyop
Copyright (C) 2006-2007-2008-2009 DeSmuME team
1) Introduction.............................................13
2) Staff/Thanks.............................................36
3) Contact information......................................72
4) Disclaimer...............................................82
1 Introduction________________________________________________
DeSmuME is a Nintendo DS emulator under GNU GPL.
DeSmuME can boot homebrew and games, some of which are
playable.
For installation/how to use informations, check the ports
specific README files:
* README.LIN for the linux port
* README.WIN for the windows port
* README.MAC for the mac port
2 Staff/Thanks________________________________________________
See the AUTHORS file for team members list.
Thanks to:
* yopyop (original author of DeSMUME),
for releasing the source code of this great emulator.
* Martin Korth (author of GBATEK),
for his well-written Gameboy Advance and Nintendo DS
documentation.
3 Contact information_________________________________________
E-mail: guillaume.duhamel@gmail.com
Web: http://desmume.org
IRC: irc://irc.freenode.net/desmume
Please don't ask for roms, bios files or any other
copyrighted stuff.
4 Disclaimer__________________________________________________
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of
the License, or (at your option) any later version.
This program is distributed in the hope that it will be
useful,but WITHOUT ANY WARRANTY; without even the implied
warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public
License along with this program; if not, write to the Free
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
MA 02111-1307 USA
See the GNU General Public License details in COPYING.

177
README.LIN Normal file
View File

@ -0,0 +1,177 @@
DeSmuME
_________________________________________
Copyright (C) 2006 yopyop
Copyright (C) 2006-2007 DeSmuME team
1) Compiling instructions...................................13
2) How to use DeSmuME.......................................53
3) Contact information......................................142
4) Disclaimer...............................................160
1 Compiling instructions______________________________________
DeSmuME is written in C using the gtk+ and SDL libraries.
So you need a working C compiler, such as gcc and
the above libraries runtime and development packages:
* http://www.gtk.org
* http://www.libsdl.org/
Once these libraries are installed, you should be ready to
install DeSmuME.
DeSmuME provides another interface based on libglade, to use
it, you'll need glade:
* http://glade.gnome.org/
1.1 From a release archive____________________________________
Uncompress the DeSmuME archive, move to the newly created
directory, type "./configure", then "make".
It will generate three programs:
1) "desmume" in the "src/gtk" directory;
2) "desmume-cli" in the "src/cli" directory.
If glade is installed on your system, you'll get a third
binary:
3) "desmume-glade" in the "src/gtk-glade" directory.
You can even type "make install" to install those programs on
your system (in /usr/local/ by default), then uninstalling is
done by typing "make uninstall".
1.2 From a CVS copy___________________________________________
Move to the toplevel directory (the one that contains the
configure.ac file). Type "./autogen.sh" to generate the
configure/install scripts and needed Makefiles. Then you can follow the
same procedure as in 1.1 .
2 How to use DeSmuME__________________________________________
There are three versions of DeSmuME under Linux. These are a
Gtk+ build, a Glade build and a CLI SDL build. All these builds
have some common command line options:
--disable-limiter Disables the 60 fps limiter
--soft-convert Use software colour conversion during OpenGL
screen rendering. May produce better or worse
frame rates depending on hardware.
--arm9gdb=PORT_NUM Enable the ARM9 GDB stub on the given port
--arm7gdb=PORT_NUM Enable the ARM7 GDB stub on the given port
--cflash=PATH_TO_DISK_IMAGE
Enable disk image GBAMP compact flash emulation
--help Display this message
NOTE:
The Gtk+ and Glade builds use gtkGLext to handle the OpenGL
rendering and contexts. You may get improved performance by
also passing the argument --gdk-gl-force-indirect. This has
been seen to improve things for Nvidia based graphics cards
under Linux.
GDB Debugger Stubs:
Source level debugging of ARM9 and/or ARM7 code is supported
using a GDB/Insight debugger.
The GDB stubs are enabled from the command line using the
following options:
--arm9gdb=<PORT_NUM> (for the ARM9)
--arm7gdb=<PORT_NUM> (for the ARM7)
The PORT_NUM is the TCP port upon which the stub will listen for
connections. Once enabled you can connect to the stub using the
following command at the GDB debugger prompt (assuming GDB and
DeSmuME are running on the same machine):
target remote :<PORT_NUM>
NOTE: there are problems with the ARM support when stepping code
with GDB versions prior to version 6.6. It is recommended that
you use at least version 6.6 if possible.
GBAMP compact flash emulation:
The default behaviour of DeSmumME is to attempt to emulate the
FAT image for the contents of the directory where the running
.nds file was located.
This behaviour can be altered using the
--cflash=<DISK_IMAGE_FILE> command line option. Using this
option DeSmuME will emulation a GBAMP and read and write sectors
from/to the disk image file.
The disk image file must be created and populated with files
using some external tool.
NOTE: currently if desmume fails to open the disk image file it
will silently continue minus a working GBAMP emulation.
2.1 Gtk+ version______________________________________________
Type "desmume" in a shell, a window should appear, then open
a rom file using the "open" button, next use the "run" button
to start emulation.
The following command line options are specific to the Gtk+
build:
--opengl-2d Enables using OpenGL for screen rendering
--disable-sound Disables the sound emulation
--disable-3d Disables the 3D emulation
2.2 CLI SDL version_______________________________________________
Just type "desmume-cli path-to-a-rom" in a shell.
The following command line options are specific to the CLI
build:
--opengl-2d Enables using OpenGL for screen rendering
--disable-sound Disables the sound emulation
3 Contact information_________________________________________
General inquiries should go to:
E-mail: guillaume@desmume.org
Linux Port-related inquiries should go to:
E-mail: guillaume@desmume.org
Web: http://desmume.org
Please don't ask for roms, bios files or any other copyrighted
stuff.
If you want to submit a bug report, please run desmume, go into
the "Help" menu, and click on "Submit a bug report". If you're
having trouble with it, please feel free to email.
4 Disclaimer__________________________________________________
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of
the License, or (at your option) any later version.
This program is distributed in the hope that it will be
useful,but WITHOUT ANY WARRANTY; without even the implied
warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public
License along with this program; if not, write to the Free
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
MA 02111-1307 USA
See the GNU General Public License details in COPYING.

107
README.MAC Normal file
View File

@ -0,0 +1,107 @@
DeSmuME
_________________________________________
Copyright (C) 2006 yopyop
Copyright (C) 2006-2007 DeSmuME team
1) Compiling instructions...................................13
2) How to use DeSmuME.......................................31
3) Contact information......................................73
4) Disclaimer...............................................90
1 Compiling instructions______________________________________
DeSmuME is written in C, and the Cocoa interface was written
in Objective-C. It uses the Cocoa, OpenGL, and [optionally]
the zlib library.
So you need a working C and Objective-C compiler, such as
GCC for Mac OS X.
* Cocoa and OpenGL come standard with Mac OS X
* zlib can be found at http://www.zlib.net, and may
also come with Mac OS X.
DeSmuME for Mac OS X can be compiled using the XCode IDE
or the CodeBlocks IDE. Project files are available in the
Cocoa source folder.
2 How to use DeSmuME__________________________________________
To install DeSmuME, copy DeSmuME.app into the folder of your
choice (Applications folder is recommended). You can also drag
it to your dock for quicker launching.
Double click the application to launch DeSmuME.
Most options can be found in the menu bar a the top of the
screen. On Leopard, you can use the search box under the help
menu to find things.
DeSmuME for Mac OS X does not support all the features of the
Linux and Windows versions.
Click the lower screen for DS touch-screen input.
Key mappings can be changed or viewed from the preferences
panel. Here are the defaults (may be subject to change):
up arrow - Up
left arrow - Left
down arrow - Down
right arrow - Right
v - A button
b - B button
g - X button
h - Y button
c - Left Trigger
n - Right Trigger
enter - Start button
space - Select button
States can be saved with shift + number keys.
States can be loaded with the number keys.
To set up a FAT disk image (for homebrew apps) you can use the
"Emulation > Set FAT Image File" option in the menu. You can
also set this from the command line by launching DeSmuME
inside its app bundle:
DeSmuME.app/Contents/MacOS/DeSmuME -FlashFile /path/to/file.img
3 Contact information_________________________________________
General inquiries should go to:
E-mail: guillaume.duhamel@gmail.com
Mac OS X Port-related inquiries should go to:
E-mail: osx@desmume.org
Web: http://desmume.org
Please don't ask for roms, bios files or any other copyrighted
stuff.
If you want to submit a bug report, please run desmume, go
into the "Help" menu, and click on "Submit a bug report". If
you're having trouble with it, please feel free to email.
4 Disclaimer__________________________________________________
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of
the License, or (at your option) any later version.
This program is distributed in the hope that it will be
useful,but WITHOUT ANY WARRANTY; without even the implied
warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public
License along with this program; if not, write to the Free
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
MA 02111-1307 USA
See the GNU General Public License details in COPYING.

169
README.TRANSLATION Normal file
View File

@ -0,0 +1,169 @@
__________________________ Localization of DeSmuME _____________________________
Users and translators:
1) Supported UIs
2) Starting a new translation
3) Editors
4) Contact Us
Developpers:
5) Creating translation friendly strings (gtk-glade)
6) Updating the template (gtk-glade)
7) Integrating new translations
1 Supported UIs ________________________________________________________________
Although there are 4 UIs, only 3 currently support localization:
windows, gtk-glade, and Cocoa (Mac OS X).
To translate DeSmuME, see "Starting a new translation" below.
If you have created a new translation, or improved an existing one, please
send us your translation by getting in touch with us: see "Contact Us" below.
1.1 gtk-glade UI _____________________________________________________________
Localization is done with gettext. gettext uses po files.
The po files are located in the po/ folder.
Note that there is one po file per language.
To use the available translations, set up your environment properly.
e.g. under GNU/Linux you can verify that the value of your LANG variable.
1.2 Windows UI ______________________________________________________________
Localization is located in one single file: src/windows/resources.rc .
1.3 Mac OS X (Cocoa) UI _____________________________________________________
Localization files are located within the application bundle (in Finder right
click on DeSmuME and select "Show Package Contents"). Within the
Contents/Resources folder there is a folder for each localization.
2 Starting a new translation ___________________________________________________
2.1 gtk-glade UI _____________________________________________________________
Grab a copy of po/desmume.pot and rename it.
You can use the two letter iso code of the language as the filename
e.g. fr.po
or you can specify the country code as well
e.g. fr_CA.po
Open the newly created file with an editor: see "Editors" below.
Translate the strings.
2.2 Windows UI _______________________________________________________________
Grab a copy of src/windows/resources.rc .
Create a section for your language by looking at another language e.g. french.
Translate the strings.
2.3 Max OS X (Cocoa) UI ______________________________________________________
Copy and paste one of the localization folders mentioned in 1.3.
Rename the part before ".lproj" to the language of the translation.
Within your newly created folder edit "Localizable.strings".
The MainMenu.nib opaque folder also contains localization of the Application
menu, however since this is a standard menu in Mac OS X, for most languages
standard strings can be generated by Apple's Interface Builder.
The strings file should stay in UTF-16 encoding (UTF-8 or others may work,
but UTF-16 is preferred).
If your strings file has an error, no translated strings will show in DeSmuME.
Debugging the string file:
If you have Mac OS X developer tools installed, from the console you can type
"plutil FILE", replacing FILE with the name and path of the string file, and
it will tell you if there are any errors (and on what line).
3 Editors ______________________________________________________________________
You can use plain text editors but there are many po file editors.
Here are some recommanded po editors, in no particular order.
3.1 GNU/Linux ________________________________________________________________
- gtranslator: http://gtranslator.sourceforge.net/
- KBabel: http://kbabel.kde.org/
3.2 OSX ______________________________________________________________________
- LocFactory Editor:
http://www.triplespin.com/en/products/locfactoryeditor.html
3.3 All platforms ____________________________________________________________
- poEdit: http://www.poedit.net/
- OmegaT: http://www.omegat.org/omegat/omegat.html
- GNUEmacs/XEmacs/AquaEmacs with po-mode
- Vim with PO ftplugin
- Eclipse with gted
4 Contact Us ___________________________________________________________________
As there isn't many translations so far, we're still asking you to get in touch
via the forum located at http://forums.desmume.org/ .
You can upload your translation files to your favorite sharing site and paste
the link in a post under General.
5 Creating translation friendly strings (gtk-glade) ____________________________
5.1 In the code ______________________________________________________________
Make sure libintl.h is included and that _() is defined.
e.g. see src/gtk-glade/globals.h
Add the filename to po/POTFILES.in if it's not already there.
Where you would use "my text", use _("my text").
For long strings, for translators' sanity, please do something like:
printf( _(" This is a\n\
very long text\n") );
5.2 Glade interface __________________________________________________________
You have nothing special to do aside from adding the filename to
po/POTFILES.in.
6 Updating the template (gtk-glade) ____________________________________________
To update po/desmume.pot, move to the po/ folder and execute "make update-po".
7 Integrating new translations
7.1 gtk-glade UI _____________________________________________________________
Add the new po file to po/ .
Add the new language to ALL_LINGUAS in configure.ac .
Regenerated the build files (./autogen.sh) and rebuild (./configure && make).
You can also add the language to po/LINGUAS (it's a convention? it has no effect).
7.2 Windows UI _______________________________________________________________
Update the src/windows/resource.rc .
Add the new language to to the list in src/windows/resource.h .
Rebuild.
7.3 Max OS X (Cocoa) UI ______________________________________________________________
After following the steps in 2.3, your translation is ready to go.
You can set the DeSmuME language one of three ways:
1) Set the system language (System Preferences -> International).
2) Right click on DeSmuME in Finder, select Get Info and disable the other translations.
3) From a command line, run the following line after replacing LANG with the language:
DeSmuME.app/Contents/MacOS/DeSmuME -AppleLanguages '<array><string>LANG</string></array>'
All of these methods require a restart of DeSmuME.

215
README.WIN Normal file
View File

@ -0,0 +1,215 @@
DeSmuME
_________________________________________
Copyright (C) 2006 yopyop
Copyright (C) 2006-2007-2008-2009 DeSmuME team
1) Compiling instructions...................................13
2) How to use DeSmuME.......................................51
3) Contact information.....................................166
4) Disclaimer..............................................184
1 Compiling instructions______________________________________
DeSmuME is written in C++, using the DirectX 8.0, OpenGL, zlib,
zziplib libraries, so you need a working C++ compiler, such as
Visual C++ 2005, Visual C++ 2008 or Intel compiler. It should
also be possible to compile it on dev-cpp, but it's currently
untested.
* OpenGL should be included with your compiler, if it isn't,
check on your compiler's website for links.
* zlib can be found at http://www.zlib.net
* zziplib can be found at http://zziplib.sourceforge.net
Visual C++:
Load either the project file DeSmuME_2005.vcproj
or DeSmuME_2008.vcproj (depending on the VisualC++ version
you're using) in the src/windows directory, compile, and
you're set.
2 How to use DeSmuME__________________________________________
Execute "desmume". A new window (and a information console)
should pop up. The default settings should be fine for most
people, but in case you need to adjust them, here's a brief
explanation:
Under the "Config", there are a number of items:
Save Type:
Here you can select which type of Backup Memory DeSmuME should
emulate. By default, Autodetect works fine, but in some cases
DeSmuME doesn't correctly detect the Backup Memory. In that
case, you will want to select the correct one.
3D Config:
Here you can change what will be used to emulate the 3D core
of the DS. By default it's on openGL, but you can also select
a Null device, that won't show any 3D.
Control Config:
Here you can change the default key mappings. For now only the
keyboard is supported, but in the near future gamepads and
joysticks will be supported.
Here are the default key mappings (they may be subject to
change):
Up arrow - Up
Left arrow - Left
Down arrow - Down
Right arrow - Right
x - A button
z - B button
s - X button
a - Y button
q - Left Trigger
w - Right Trigger
Enter - Start button
Right Shift - Select button
Backspace - Lid fold/unfold
n - Frame advance
Space - Pause/Unpause
p - Load current state
1,2,3,4,5,6,7,8,9,0 - Select current state
F1-F10 - Load relevant state
Shift+F1-F10 - Save relevant state
Sound Settings:
Here you can change the default sound settings. By default
DeSmuME uses Direct Sound, a buffer size of 2940, and volume
set to max. But if you want to mute the sound, you can set the
sound core to none. Or if you want to save the sound to a
file, you can set the sound core to WAV write. If you find the
sound is crackling a lot, try increasing the buffer size. On
the other hand, if you find the sound somewhat delayed or
jumpy, try decreasing the buffer size.
Firmware Settings:
Here you can change settings that are used as a customization
on the real DS: your name, birthday, favourite colour, etc...
Frame Skip:
Here you can adjust the amount of frame draws to skip during
emulation. Normally the emulator detects whether the emulator
is running too fast or slow and skips a frame or more if it
needs to speed things up. However some people don't like the
results of it, so here you can adjust that.
Language:
Here you can change the emulator menus language. Currently we
only support English, French and Danish.
After all the settings are set to your satisfaction, you can
then load a ROM image by going into the "File" menu, and
choosing "Open". Select which file you'd like to open, and the
emulator will automatically load and start running the
selected ROM.
------------------------
Under the View menu there's also a few additional options you
may wish to change.
Rotation:
Here you can adjust which angle of the display. Some programs
require that you normally turn the DS on its side. You can set
it up in that manner using this.
Window size:
With these options you can increase or decrease the window
size.
Note: You can also adjust the window size by clicking on the
edge of the window, and dragging the mouse.
Force Maintain Ratio:
Sometimes when the window size is changed it's doesn't look
correct on the screen. This option forces the window to
maintain a correct ratio so it looks correct.
Default size:
This option makes the emulator window go back to the default
size.
------------------------
GDB Debugger Stubs:
Source level debugging of ARM9 and/or ARM7 code is supported
using a GDB/Insight debugger. The GDB stubs are enabled from
the command line using the following options:
--arm9gdb=<PORT_NUM> (for the ARM9)
--arm7gdb=<PORT_NUM> (for the ARM7)
The PORT_NUM is the TCP port upon which the stub will listen
for connections. Once enabled you can connect to the stub
using the following command at the GDB debugger prompt
(assuming GDB and DeSmuME are running on the same machine):
target remote :<PORT_NUM>
NOTE: There are problems with the ARM support when stepping
code with GDB versions prior to version 6.6. It is recommended
that you use at least version 6.6 if possible.
------------------------
GBAMP compact flash emulation:
The default behaviour of DeSmumME is to attempt to emulate the
FAT image for the contents of the directory where the running
.nds file was located.
This behaviour can be altered using the --cflash=<DISK_IMAGE_FILE>
command line option. Using this option DeSmuME will emulation
a GBAMP and read and write sectors from/to the disk image
file. The disk image file must be created and populated with
files using some external tool.
NOTE: Currently if desmume fails to open the disk image file
it will silently continue minus a working GBAMP emulation.
3 Contact information_________________________________________
General inquiries should go to:
E-mail: guillaume@desmume.org
Web: http://www.desmume.org
Forums: http://forums.desmume.org
Please don't ask for roms, bios files or any other copyrighted
stuff.
If you want to submit a bug report, please run desmume, go
into the "Help" menu, and click on "Submit a bug report". If
you're having trouble with it, please feel free to email.
4 Disclaimer__________________________________________________
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of
the License, or (at your option) any later version.
This program is distributed in the hope that it will be
useful,but WITHOUT ANY WARRANTY; without even the implied
warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public
License along with this program; if not, write to the Free
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
MA 02111-1307 USA
See the GNU General Public License details in COPYING.

View File

@ -1,6 +0,0 @@
# DeSmuME
[![AppVeyor CI Build Status](https://ci.appveyor.com/api/projects/status/abfd7jm09wnmxyvu?svg=true)](https://ci.appveyor.com/project/zeromus/desmume)
DeSmuME is a Nintendo DS emulator.
http://desmume.org/download

14
autogen.sh Executable file
View File

@ -0,0 +1,14 @@
#!/bin/sh
# intltoolize is optionnal as it's only required for the gtk-glade UI.
if test ! "x$(which intltoolize)" = "x"; then
echo "Running intltoolize"
intltoolize --copy --force --automake
else
if test ! "x$(which gintltoolize)" = "x"; then
echo "Running gintltoolize"
gintltoolize --copy --force --automake
fi
fi
autoreconf --install --force --verbose

View File

@ -0,0 +1,39 @@
# -*-shell-script-*-
[Meta]
RootName: @desmume.sf.net/desmume:$SOFTWAREVERSION
DisplayName: DeSmuME Nintendo DS Emulator
ShortName: desmume
Maintainer: Guillaume Duhamel <guillaume.duhamel@gmail.com>
Packager: Guillaume Duhamel <guillaume.duhamel@gmail.com>
Summary: DeSmuME is a Nintendo DS emulator.
URL: http://desmume.sf.net/
License: GNU General Public License, Version 2
SoftwareVersion: @VERSION@
AutopackageTarget: 1.0
[Description]
This is a Nintendo DS emulator.
[BuildPrepare]
prepareBuild
[BuildUnprepare]
unprepareBuild
[Imports]
echo '*' | import
[Prepare]
# Dependency checking
require @gtk.org/gtk 2.4
[Install]
# Put your installation script here
installExe bin/desmume
installExe bin/desmume-cli
installExe bin/desmume-glade
[Uninstall]
# Usually just the following line is enough to uninstall everything
uninstallFromLog

142
compile Executable file
View File

@ -0,0 +1,142 @@
#! /bin/sh
# Wrapper for compilers which do not understand `-c -o'.
scriptversion=2005-05-14.22
# Copyright (C) 1999, 2000, 2003, 2004, 2005 Free Software Foundation, Inc.
# Written by Tom Tromey <tromey@cygnus.com>.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2, or (at your option)
# any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
# As a special exception to the GNU General Public License, if you
# distribute this file as part of a program that contains a
# configuration script generated by Autoconf, you may include it under
# the same distribution terms that you use for the rest of that program.
# This file is maintained in Automake, please report
# bugs to <bug-automake@gnu.org> or send patches to
# <automake-patches@gnu.org>.
case $1 in
'')
echo "$0: No command. Try \`$0 --help' for more information." 1>&2
exit 1;
;;
-h | --h*)
cat <<\EOF
Usage: compile [--help] [--version] PROGRAM [ARGS]
Wrapper for compilers which do not understand `-c -o'.
Remove `-o dest.o' from ARGS, run PROGRAM with the remaining
arguments, and rename the output as expected.
If you are trying to build a whole package this is not the
right script to run: please start by reading the file `INSTALL'.
Report bugs to <bug-automake@gnu.org>.
EOF
exit $?
;;
-v | --v*)
echo "compile $scriptversion"
exit $?
;;
esac
ofile=
cfile=
eat=
for arg
do
if test -n "$eat"; then
eat=
else
case $1 in
-o)
# configure might choose to run compile as `compile cc -o foo foo.c'.
# So we strip `-o arg' only if arg is an object.
eat=1
case $2 in
*.o | *.obj)
ofile=$2
;;
*)
set x "$@" -o "$2"
shift
;;
esac
;;
*.c)
cfile=$1
set x "$@" "$1"
shift
;;
*)
set x "$@" "$1"
shift
;;
esac
fi
shift
done
if test -z "$ofile" || test -z "$cfile"; then
# If no `-o' option was seen then we might have been invoked from a
# pattern rule where we don't need one. That is ok -- this is a
# normal compilation that the losing compiler can handle. If no
# `.c' file was seen then we are probably linking. That is also
# ok.
exec "$@"
fi
# Name of file we expect compiler to create.
cofile=`echo "$cfile" | sed -e 's|^.*/||' -e 's/\.c$/.o/'`
# Create the lock directory.
# Note: use `[/.-]' here to ensure that we don't use the same name
# that we are using for the .o file. Also, base the name on the expected
# object file name, since that is what matters with a parallel build.
lockdir=`echo "$cofile" | sed -e 's|[/.-]|_|g'`.d
while true; do
if mkdir "$lockdir" >/dev/null 2>&1; then
break
fi
sleep 1
done
# FIXME: race condition here if user kills between mkdir and trap.
trap "rmdir '$lockdir'; exit 1" 1 2 15
# Run the compile.
"$@"
ret=$?
if test -f "$cofile"; then
mv "$cofile" "$ofile"
elif test -f "${cofile}bj"; then
mv "${cofile}bj" "$ofile"
fi
rmdir "$lockdir"
exit $ret
# Local Variables:
# mode: shell-script
# sh-indentation: 2
# eval: (add-hook 'write-file-hooks 'time-stamp)
# time-stamp-start: "scriptversion="
# time-stamp-format: "%:y-%02m-%02d.%02H"
# time-stamp-end: "$"
# End:

257
configure.ac Normal file
View File

@ -0,0 +1,257 @@
dnl --- Package name is first argument to AC_INIT
dnl --- Release version is second argument to AC_INIT
AC_INIT(desmume, [0.9.2-1])
dnl -- find target architecture for some os specific libraries
AC_CANONICAL_TARGET
case $target in
*linux*) desmume_arch=linux;;
*mingw*) desmume_arch=windows;;
*darwin*) desmume_arch=linux;;
*bsd*) desmume_arch=linux;;
esac
AC_SUBST(desmume_arch)
AM_INIT_AUTOMAKE([1.10])
dnl -- make sure we have a c++ compiler
AC_PROG_CXX
dnl -- use ranlib for libraries
AC_PROG_RANLIB
dnl -- check for endianess
AC_C_BIGENDIAN
dnl --- Other prerequisites ---
dnl - Check for pkg-config macros
m4_ifdef([PKG_PROG_PKG_CONFIG], [PKG_PROG_PKG_CONFIG])
dnl - Check for intltool/gettext macros
m4_ifdef([IT_PROG_INTLTOOL],[IT_PROG_INTLTOOL])
dnl - Check for zlib
AC_CHECK_LIB(z, gzopen)
dnl - Check for zziplib
AC_CHECK_LIB(zzip, zzip_open)
dnl - Check for SDL
AC_PATH_PROGS(SDLCONFIG, [sdl-config sdl11-config])
if test ! "x$SDLCONFIG" = "x" ; then
SDL_CFLAGS=`$SDLCONFIG --cflags`
SDL_LIBS=`$SDLCONFIG --libs`
AC_SUBST(SDL_CFLAGS)
AC_SUBST(SDL_LIBS)
HAVE_SDL="yes"
else
HAVE_SDL="no"
fi
dnl - Check for the OpenGL includes
AC_CHECK_HEADERS([GL/gl.h])
AC_CHECK_HEADERS([GL/glu.h])
dnl - if --enable-osmesa is used, check for it
AC_ARG_ENABLE([osmesa],
[AC_HELP_STRING([--enable-osmesa], [use off-screen mesa])],
[osmesa=$enableval],
[osmesa=no])
if test "x$osmesa" = "xyes" ; then
AC_CHECK_LIB(dl, main)
AC_CHECK_LIB(OSMesa, main,[
useosmesa=yes
AC_DEFINE(HAVE_LIBOSMESA)
LIBS="-lOSMesa $LIBS"
])
fi
dnl - Check for GTK and/or libglade
GLIB_VER=2.8
GTK_VER=2.6
AC_CHECK_TOOL(HAVE_PKG, pkg-config)
AC_PROVIDE_IFELSE([PKG_PROG_PKG_CONFIG], [
if test ! "x$HAVE_PKG" = "x" ; then
PKG_CHECK_MODULES(GLIB,
glib-2.0 >= $GLIB_VER,
HAVE_GLIB=yes,
HAVE_GLIB=no)
if test "$HAVE_GLIB" = "no"; then
AC_MSG_ERROR([glib-2.0 >= $GLIB_VER is required to build desmume gtk frontend])
fi
PKG_CHECK_MODULES(GTK,
gtk+-2.0 >= $GTK_VER,
HAVE_GTK=yes,
HAVE_GTK=no)
if test "$HAVE_GTK" = "no"; then
AC_MSG_ERROR([gtk-2.0 >= $GTK_VER is required to build desmume gtk frontend])
fi
AC_SUBST(GTK_CFLAGS)
AC_SUBST(GTK_LIBS)
if test ! "x$useosmesa" = "xyes" ; then
PKG_CHECK_MODULES(GTKGLEXT,
"gtkglext-1.0",
HAVE_GTKGLEXT=yes,
HAVE_GTKGLEXT=no)
AC_SUBST(GTKGLEXT_CFLAGS)
AC_SUBST(GTKGLEXT_LIBS)
fi
PKG_CHECK_MODULES(GTHREAD,
"gthread-2.0",
HAVE_GTHREAD=yes,
HAVE_GTHREAD=no)
AC_SUBST(GTHREAD_CFLAGS)
AC_SUBST(GTHREAD_LIBS)
PKG_CHECK_MODULES(LIBGLADE,
"libglade-2.0",
HAVE_LIBGLADE=yes,
HAVE_LIBGLADE=no)
AC_SUBST(LIBGLADE_CFLAGS)
AC_SUBST(LIBGLADE_LIBS)
dnl uninstalled glade ui dir
AC_DEFINE_UNQUOTED(GLADEUI_UNINSTALLED_DIR,"`pwd`/src/gtk-glade/glade/",[path to glade ui dir])
AC_SUBST(GLADEUI_UNINSTALLED_DIR)
fi
],[
echo "WARNING: pkg-config is not available therefore gtk and gtk-glade UIs are not available either."
])
dnl - If the gtkGLext package is available define the corresponding C macro
if test "x$HAVE_GTKGLEXT" = "xyes"; then
AC_DEFINE([GTKGLEXT_AVAILABLE], [1])
fi
dnl - Determine which UIs to build and if po/ should be included
PO_DIR=""
PO_FILES=""
PO_FILES_IN=""
if test "x$HAVE_SDL" = "xyes"; then
# SDL adds just a cli
UI_DIR="cli $UI_DIR"
if test "x$HAVE_GTK" = "xyes"; then
# GTK requires SDL
UI_DIR="gtk $UI_DIR"
fi
if test "x$HAVE_LIBGLADE" = "xyes"; then
AC_PROVIDE_IFELSE([IT_PROG_INTLTOOL],[
# libglade requires SDL too
UI_DIR="gtk-glade $UI_DIR"
dnl -- localization for gtk-glade UI
GETTEXT_PACKAGE=desmume
AC_DEFINE_UNQUOTED(GETTEXT_PACKAGE, "$GETTEXT_PACKAGE", [Define to the gettext package name])
AC_SUBST(GETTEXT_PACKAGE)
ALL_LINGUAS="fr pt_BR"
AM_GLIB_GNU_GETTEXT
PO_DIR="po"
PO_FILES="intltool-extract intltool-merge intltool-update"
PO_FILES_IN="intltool-extract.in intltool-merge.in intltool-update.in"
PO_MAKEFILE="po/Makefile.in"
],[
echo "WARNING: intltool and/or gettext are not available therefore the gtk-glade interface won't be installed. The gtk-glade UI requires intltool and gettext."
])
fi
fi
dnl Set compiler library flags per target.
case $target in
*linux* | *bsd*)
LIBS="$LIBS -lGLU"
;;
*mingw*)
LIBS="$LIBS -ldxguid -ldxerr8 -ldsound -lopengl32 -lws2_32 -mwindows"
UI_DIR="windows"
;;
*darwin*)
LIBS="$LIBS -framework OpenGL"
;;
esac
AC_SUBST(UI_DIR)
AC_SUBST(PO_DIR)
AC_SUBST(PO_FILES)
AC_SUBST(PO_FILES_IN)
dnl - Gdb stub
AC_ARG_ENABLE(gdb-stub,
[AC_HELP_STRING(--enable-gdb-stub, enable gdb stub)],
[
AC_DEFINE(GDB_STUB)
wantgdbstub=yes
])
AM_CONDITIONAL([HAVE_GDB_STUB], [test "${wantgdbstub}" = "yes"])
dnl - Compiler warnings
# for developer use, enable lots of compile warnings,
# but don't require this generally, because some system's
# header files (BSD) can't handle it
#
# NB: must add -Werror after AC_PROG_CC, etc., so do this last
AC_ARG_ENABLE(hardcore,
[AC_HELP_STRING(--enable-hardcore, turn on -W -Wall -Werror)],
[case "${enableval}" in
yes) ENABLE_HARDCORE=1 ;;
no) ENABLE_HARDCORE=0 ;;
*) AC_MSG_ERROR(bad value ${enableval} for --enable-hardcore) ;; esac],
[ENABLE_HARDCORE=0])
if test "x[$]ENABLE_HARDCORE" = "x1"; then
AC_MSG_WARN(enable hardcore compile warnings)
if test "x$CXX" = "x"; then
dnl - only valid for C with newer gcc's
CPPFLAGS="[$]CPPFLAGS -Wmissing-prototypes"
fi
CPPFLAGS="[$]CPPFLAGS -Wall -Wextra -D_FORTIFY_SOURCE=2 -Wno-missing-field-initializers -Wpointer-arith -Wcast-align -Wwrite-strings -Wno-unused-parameter -Wmissing-declarations -Wundef -Wmissing-noreturn -Wshadow -Wredundant-decls -Wformat-nonliteral -Wformat-security -Wswitch-enum -Winit-self"
fi
dnl - Enable debug mode
AC_ARG_ENABLE(debug,
AC_HELP_STRING(--enable-debug, enable debug information),
AC_DEFINE(DEBUG))
AC_ARG_ENABLE(gpu-debug,
AC_HELP_STRING(--enable-gpu-debug, enable gpu debug information),
AC_DEFINE(GPUDEBUG))
AC_ARG_ENABLE(div-debug,
AC_HELP_STRING(--enable-div-debug, enable div debug information),
AC_DEFINE(DIVDEBUG))
AC_ARG_ENABLE(sqrt-debug,
AC_HELP_STRING(--enable-sqrt-debug, enable sqrt debug information),
AC_DEFINE(SQRTDEBUG))
AC_ARG_ENABLE(dma-debug,
AC_HELP_STRING(--enable-dma-debug, enable dma debug information),
AC_DEFINE(DMADEBUG))
dnl - Enable memory profiling
AC_ARG_ENABLE(memory-profiling,
AC_HELP_STRING(--enable-memory-profiling, enable memory profiling information),
AC_DEFINE(PROFILE_MEMORY_ACCESS))
dnl -- set maintainer mode
AM_MAINTAINER_MODE
AC_SUBST(USE_MAINTAINER_MODE)
dnl --- Finally, output all the makefiles
AC_CONFIG_FILES([Makefile
${PO_MAKEFILE}
src/Makefile
src/cli/Makefile
src/cli/doc/Makefile
src/cocoa/Makefile
src/gtk/Makefile
src/gtk/doc/Makefile
src/gtk-glade/Makefile
src/gtk-glade/doc/Makefile
src/windows/Makefile
src/gdbstub/Makefile
autopackage/default.apspec
])
AC_OUTPUT

View File

@ -1,972 +0,0 @@
0.9.12 -> 0.9.13
In this version we have added support for high-resolution 3D rendering. Try the new "GPU Scaling Factor" feature to
increase the 3D resolution beyond the native resolution of 256x192 pixels. Also, the Cocoa frontend sees continued
radical enhancements and while the Windows frontend sees some new incremental enhancements.
General/Core:
bug: numerous host compatibility and accuracy improvements to OpenGL renderer, tho off-by-1 sampling bugs will remain.
bug: fixes to 'edge marking', shadows, box tests, maths & depths precision, and some other rarer 3d rendering usecases
bug: fixes to AR cheat processing
bug: fixes to cheat database game identification
bug: fix interpolation at SPU loop points, emulation of SPU half/byte size registers & others
bug: backlight emulation added (for fade effects)
bug: other small ongoing fixes to 2d rendering and GPU memory maps
bug: emulate slot-1 read timings, probably for AP-related purposes
bug: general improvement to hardware component power-off state handling, especially 3d engine
bug: fix virtual fat (homebrew) building in environment with symlinks
bug: fix some rarely-bugged CPU instructions
bug: fix bugs in homebrew filesystems
bug: fix bugs in big-endian hosts
bug: fix loading gzipped files and some newer rars
bug: fix inconsistencies and omissions in command-line processing
bug: extensive improvement to wifi emulation, though wifi is still not supported.
bug: firmware file settings/management now behaves more or less sensibly as advertised
bug: fix movie (dsm) being bitrotted and failing to sync settings or manage sram properly
enh: movie (dsm) add record from state feature
enh: high-resolution 3d rendering, from 1x-16x the native resolution of 256x192 pixels
enh: texture upscaling for 3d rendering, from 1x-4x the native texture size
enh: texture smoothing option for OpenGL renderer
enh: user-selectable internal GPU bpp 15/18/24 to change from accuracy to attractiveness
enh: game-specific hacks library finally implemented internally, user-selectable.
enh: game-specific hack for popular games that randomly corrupt their sprites when going in and out of doors
enh: officially supported arm and arm64 jits and overall improvements on arm hosts
enh: emulator now makes "(backups)" states on every loadstate, for in case you hit loadstate on accident
enh: User-selectable MSAA level for OpenGL renderer.
enh: "interface" for dll/so control of a desmume core
enh: optimizations, cpu arch-specific, and otherwise, to all 3d and 2d rendering, ranging from SSE to AVX2
enh: lua - Add raw joystick API and setlayermask API (windows only)
enh: lua - Add gamecode APU for game-specific hacks in scripts and 'freelook' script functionality
enh: add options to emulate game cards more badly, to trip AP on purpose
enh: fix some save type / slot type autodetections and save memory import codepaths
enh: add fake impossible debug AR code to select CPU: DFFFFFFF 77777777/99999999
enh: add --rtc-day and --rtc-hour to specify an offset from host RTC
enh: support newer duc files
enh: upgrade and add some upscalers, hq3x, 6xBRZ, etc.
enh: add "interface" frontend for use via dll/so
Windows:
note: windows xp and x86 support is dropped for official builds. windows 7 support will be dropped over my dead body.
bug: fix numerous bugs involving filenames and path with non-latin characters
bug: fix bugs in various display layout, rotate, vsync, gaps, and display method configurations
bug: fix bugs in user configured paths
bug: aviout/wavout is now more robust
bug: fix bugs in window clearing and various display method configurations which leave garbage on screen
enh: add fullscreen display options
enh: major revisions to mic sample feature, loaded as a bunch and rotated with hotkeys
enh: add user-facing option to control console window visibility
enh: add some crude capability for breakpoints to cpu debugger and memory viewer, and other bugfixes
enh: add "screen size ratio" for smaller sub-screens, etc.
enh: add some hotkeys
enh: add option to kill stylus input when outside the NDS screen
enh: improve cheat list UX
enh: optimizations to reduce cpu usage overall and during idle especially for high resolutions, scalers, etc.
enh: improve pen&touch support
Cocoa:
bug: fix issues with v-sync causing frame rate issues under various circumstances
bug: fix issues when running a display window in fullscreen
enh: add native binary support for Apple Silicon CPUs
enh: Macs with an Intel Haswell or later CPU now benefit from the new AVX2 optimizations
enh: add support for Apple's Dark Mode user interface introduced in macOS Mojave
enh: add some new toolbar items for the following: Frame Advance, Enable/Disable HUD, Toggle Displays
enh: turbo inputs can now be configured with a frame-by-frame press/release pattern
enh: display windows now run their video output using Metal, if available
enh: display windows now support HiDPI monitors like Apple's Retina monitors
enh: display windows have new "Hybrid" layouts for better fit on modern widescreen monitors (View > Display Layout)
enh: display windows can now change the video source going to each individual DS screen (View > Display Video Source)
enh: display windows can now run a Heads-Up Display for reporting useful info (View > Show HUD Settings)
enh: add support for changing the NDS stylus pressure (Emulation > Show Stylus Settings)
enh: screenshots can now be captured using a dedicated tool for it (Tools > Show Screenshot Capture Tool)
enh: lots of miscellaneous stability and performance improvements
Linux:
note: SDL2 now employed
note: GTK3 port added, built with meson
note: CLI and GTK ports improved, according to their respective niche (gaming vs functionality)
note: CLI: added horizontal screen layout
note: CLI: added floating-point scale factor support with HW stretching
note: CLI/GTK2: improved gdb stub for game debugging
note: CLI/GTK2/GTK3: various other improvements
0.9.11 -> 0.9.12
We decided to start skipping even versions to disambiguate official releases from several years of interim builds,
and to insulate ourselves from consideration for world record of "longest time between consecutive releases" by
creating confusion as to what constitutes a consecutive release.
0.9.10 -> 0.9.11 (r4908-r5146)
In this version, we have focused on the Cocoa frontend, but there have been some good core fixes over so long.
Notably, the save-related issues resulting in the advice "dont use 0.9.10" have been resolved.
General/Core:
bug: fix large numbers of games not being able to save anymore
bug: fix some missing sound effects due to wrong volumes in some boot scenarios and other things
bug: fix freezes due to tiny looping sounds
bug: fix many big endian issues
bug: fix some apparently rarely-used CPU instructions, no known consequences
bug: fix (block) reading of some GPU registers
bug: fix action replay code type 0xE
bug: fix reading of last 4 bytes of rom
bug: large improvements to stability of GDB stub
bug: support w-buffer support in OpenGL renderers
bug: fix unpredictable crashes in some 3d scenes from w=0
enh: better loading of roms (bad patches) with wrong size info in header
enh: warn user sometimes when 'stream rom from disk' will create malfunctions
enh: add xBRZ filters
enh: add "TXT Hack" for software rasterizer to improve text rendering in some games
Windows:
bug: fix 5x filters
enh: support import of action replay save files (.dss)
enh: add antialiasing option for OpenGL renderers
enh: don't malfunction if saveram is unavailable or read-only
Cocoa:
bug: 16-bit to 32-bit color space conversions no longer darken video or images
bug: fix intermittent issues with loading user defaults on app startup
bug: fix rendering inaccuracies of the video preview in the app display preferences
bug: fix various UI font rendering and text alignment issues on OS X Yosemite
bug: fix crackly sound from N-sync and Z-sync methods
enh: make N-sync method the default sound sync method since it has much lower latency than P-sync method
enh: add support for gdbstub (Tools > Show GDB Stub Control) (only available on custom builds using the dev+ build target)
enh: optimize input handling to use less CPU
enh: add support for App Nap when the app is in an idle state (only supported on OS X Mavericks and later)
enh: add Execution Control panel (Emulation > Show Execution Control), now with frame advance and frame jump controls
enh: auto frame skip is now smoother
enh: further improve execution timing accuracy
enh: improve overall video performance
enh: render video through a 3-stage filtering pipeline, (Video Source)-->(Pixel Scaler)-->(Video Output)
enh: add the following video source filters - Deposterize
enh: add the following video output filters - Bicubic B-Spline, Bicubic Mitchell-Netravali, Lanczos2, Lanczos3
enh: add ability to run all existing pixel scalers on either the CPU or the GPU
enh: add ability to toggle the main and touch display positions (View > Toggle All Displays)
enh: add preliminary support for replay playback and recording
enh: add support for turbo and autohold
enh: add support for the entire suite of slot-2 devices (Emulation > Show SLOT-2 Manager)
enh: add support for using the host machine's audio input device for emulating the NDS microphone (Emulation > Show Microphone Settings)
enh: change the sine wave tone generator's range from 100Hz-5000Hz to 40Hz-4000Hz
enh: reorganize the menu options to more logical locations
enh: greatly improve the File Migration Assistant (now renamed Game Data Migration Assistant) and ROM Info panel with a more modern and space efficient look and feel
enh: miscellaneous user interface improvements
Linux:
bug: fix screen gap bug
bug: workaround for std::bad_alloc exceptions compiler bugs
enh: add experimental AV recording
enh: generally improve main loop throttling and skipping
enh: massive improvements to HUD and menu layout
enh: add window sizing options and sound interpolation options
enh: add Lid button; disallow U+D, L+R; manual option saving
0.9.9 -> 0.9.10 (r4623-r4908)
In this version, we have focused on trying to clean up some complexities in the user experience and emulator internals. Pretty unglamorous stuff, but some games are newly compatible.
General/Core:
enh: break savestate back-compatibility
bug: improve save size autodetection for some games
bug: cpu: fix many basic jit cpu bugs
bug: 3d: tweak softrasterizer edge marking
bug: 3d: fix stale 4x4 texture palettes
bug: fix some GPU sprite blending scenarios
bug: fix bios HLE BitUnPack, UnCompHuffman
enh: modular slot-1 device system, emulate GC bus more faithfully
enh: support NAND slot-1 device
enh: auto-detect appropriate slot-1 and slot-2 device
enh: many revisions to firmware boot process for more authenticity. iQue and FlashME versions function, .dfc rewritten.
enh: support streaming NDS file from disk (like an ISO, to avoid long initial load time)
enh: run .dsv directly on disk, to save long flushing times. should speed backup operations.
enh: spu synch mode and method on commandline
Windows:
bug: fixes to advanscene DB import
bug: save opengl display method filter option
bug: general bugfixes to various screen layout modes
enh: add option to stop non-integer scaling during fullscreen or maximize
enh: improvements to save import dialog
enh: improved memory viewer tool
enh: operate better when run, against our advice, from a zipfile
enh: add slot-1 Nitro Filesystem viewer tool
Cocoa:
bug: fix slot1-R4 path saving
bug: fix bug with mic samples < 16khz
bug: fix bugs and enhancements in multi display windows
bug: fix handling of some joystick analog inputs
enh: save display windows configuration and emulation speed on app exit
0.9.8 -> 0.9.9 (r4228-r4623)
Yes, it's been a while since the last release, but we haven't been completely idle. There's a brand new jit cpu core which yields some impressive speedups!
General/Core:
!!!: add optional arm cpu jit (functioning on x86 and x64 hosts only)
bug: we're not going to list 70% of the emulation fixes, as is traditional.
bug: savestate reliability fixes related to halt states, gxstat, firmware
bug: lua: fix readbyterange, gdscreenshot functions
bug: commandline slot-1 handling straightened out
enh: fixes and additions to resize filter options
Graphics:
enh: opengl 3d driver compatibility improvements
bug: fix giant regression from 0.9.7 that left garbage from previous frames on the screen in some games
bug: 3d: fix some single poly pixels
bug: 3d: fix some polygon and texture coloring bugs on big-endian systems
Windows:
bug: fix some full screen stretching bugs
enh: add xaudio2 output driver
enh: add opengl display method (as opposed to directdraw), with controllable bilinear filter
enh: upgrade archive handling system, lzma2 supported
enh: reorganize main menu quite a bit
enh: add rotation hotkeys, and hotkey to control mouse cursor visibility
enh: memory viewer improvements and fixes
enh: improve interface for rom eject to prevent accidents and improve usefulness (hide in slot-1 config screen)
Cocoa:
bug: fix missing display when running on OS X v10.8 Mountain Lion
bug: fix possible sound crash when using Dual SPU Synch/Asynch
bug: fix File menu items being disabled after the file migration sheet is used
bug: fix window resizing issues
bug: fix text rendering in About box
enh: show the icon and name of the loaded ROM
enh: add Support Request and Bug Report forms to the Help menu
enh: add more detailed info to the About box
enh: add OpenGL as a 3D rendering option
enh: add support for MSAA when using OpenGL as the 3D rendering engine
enh: add V-Sync option
enh: add Display Orientation, Display Order, and Display Separation options for Combo Display mode
enh: add HQ4xS filter
enh: completely revamp the user interface for Input Preferences
enh: many emulator commands may now be mapped
enh: add ability to map an input to user-defined touch screen coordinates
enh: add support for saving and applying input profiles
enh: add support for using an audio file for the microphone input
enh: add sine wave tone generator for microphone input
enh: add support for multiple display windows (File > New Display Window)
enh: add support for SLOT-1 devices (Emulation > Show SLOT-1 Manager)
enh: overall performance and stability improvements
enh: miscellaneous user interface improvements
0.9.7 -> 0.9.8 (r3812-r4228)
Yes, it's been a while since the last release, but we haven't been completely idle. There's a brand new top shelf Cocoa frontend to make life far more pleasant for OSX users, and a host of compatibility fixes.
General/Core:
bug: fix more IPC FIFO errors
bug: import more save files correctly
bug: don't autopatch already-patched roms
bug: fix bugs in piano and guitar grip
bug: fix ARM7's VRAMSTAT register
bug: fix memory leaks on compact flash emulation
bug: fix reading of rom from low header area
bug: spu: fix some poppy interpolation audio quality issues
bug: improve timing of dma operations by running through normal mem cycle accounting; fixes an annoying number of games and graphical glitches
bug: fix opcode MRC and fake bios CRC16
enh: jitter some related register and irq events to simulate pipeline effects and stimulate some race conditions to other outcomes
enh: fake (deterministic) some tiny jitter from human's hand holding stylus; some games were accidentally depending on this
enh: support nocash-style prints from arm
enh: add lua apis for accessing vram
enh: platforms other than windows receive threading optimizations
enh: provide diagnostics when system powers off (useful for homebrewers returning from main())
enh: clarify handling of different console types within the family (ds,dslite,debug)
enh: vfat support for slot-1 devices
enh: emulate temperature register
enh: add paddle emulation
Graphics:
bug: fix occasional crash from uninitialized blending table
bug: fix some 2d alpha blending cases resulting in white screens
bug: fix VRAM_I B_OBJ mirroring and fix sprites rendering across the end of vram
bug: fix rotoscaled sprites wrapping around screen
bug: dont fix rotscaled bitmap sprites with alpha==0
bug: opengl: fix degradation of toon rendering during loadstate
bug: opengl: alpha blending fixes
bug: many refinements to opengl renderer
bug: opengl: support rear-plane/ClearImage emulation (fixes many graphics)
bug: rasterizer: fix some rare alpha blending cases
bug: fix bug in environment mapping introduced after 0.9.6
bug: fix totally glitched out 3d graphics with several improvements involving matrix stack
bug: fix memory overflows in epx filter
bug: prevent backdrop from blending with ???
enh: opengl: better depth buffering emulation
enh: better support for line segment "polys" by detection and special rendering logic
enh: opengl: support quad primitives directly
enh: add hq4x filter
Windows:
bug: fix a long-standing loadstate crash
bug: fix lag frame accounting
bug: fix glitches in cheat entry menu
bug: stop compact flash emulation from accidentally scanning c:\ sometimes
enh: add support for game database for improved save type detection
enh: hotkey for limit framerate toggle
enh: remove stop and reset toolbar buttons which were accidentally getting used
enh: additional complexification to desmume's behaviour run from a console prompt. whether it's better is uncertain.
enh: add support for cheats databases
enh: improvements to ram search tool
enh: preliminary support for varying stylus pressure
enh: add [Display] Show Console=1 to ini file
enh: more graceful cheat parsing and add some hotkeys
enh: add 5x window size
enh: add big endian and 20.12 toggle to memview and ramwatch
enh: improve FPS throttle feedback and granularity
enh: add lua menu API
enh: hud font switching
enh: add optional file association for .nds to path config dialog
Cocoa:
enh: Big update to cocoa frontend. Pretty much entirely new. (rogerman)
Linux:
bug: gtk: glitches in rom and recent rom loading
bug: glade: normalize savestate slot to hotkey mapping
enh: support soundtouch for use by metaspu
enh: gtk: add SPU mode selection (Tobias Jakobi)
enh: cli: better fps limiting (Thomas Jones)
Wx:
bug: some small fixes here and there (Jan Bücken)
enh: lot of code cleanup (Jan Bücken)
0.9.6 -> 0.9.7 (r3493-r3812)
General/Core:
bug: fix a ton of old, broken cpu opcodes and CP15 logic
bug: return Z1 and Z2 from TSC (fixes some touch logic)
bug: gba slot save type detection improved
bug: handle unusual rom headers more correctly
bug: dont confuse motion pack commands with save memory commands
bug: make cheat system a little less flaky and add AR 1.54 support
bug: fix nondeterministic backup memory behaviour while rerecording
bug: correct emulation of register accesses of wrong size and during powerdown
bug: rewrite --cflash-path emulation
bug: rewrite IPC/GX FIFO, IRQ flag generation, and wait-for-IRQ logics
bug: rewrite RTC calendar handling; now supports years > 2038
enh: auto-DLDI patching for homebrew
enh: --gbaslot-rom=self mounts self.nds in slot2
enh: more realistic exception handling
enh: piano controller emulation
enh: modular slot-1 system for exact emulation of homebrew cards
Graphics:
bug: edge marking colors were wrong
bug: handle some "invalid" vram configurations correctly
bug: convert half of geometry engine to fixed point
bug: fix sprite blend+fadein/fadeout
bug: improve rasterizer shadows
bug: fix main memory display DMA
bug: fix some raster fx timing bugs
enh: add a hack for improving some non-stencil shadows
Windows:
bug: misc fixes and improvements to gpu viewer tools
bug: sub screen layer display toggling fixed
bug: fixes and improvements to ram watch, ram search, cheats list
bug: fix start-paused commandline
bug: fix memory leaks when sound disabled
bug: improve load average calculators and add arm7 load average
enh: background input support
enh: add vsync option
enh: support more knobs on joysticks
enh: import cheats from R4 database
enh: add xinput rumble for 360 pads
Linux/OSX:
bug: crash less in recent roms list
enh: Add horizontal screen layout and swap screen ability to gtk frontend (noodlebox)
enh: Big improvement to joystick support, support complex configurations and multiple devices (noodlebox)
0.9.5 -> 0.9.6 (r3075-r3493)
Users of gtk, cli and gtk-glade frontends please note that now we
have a common directory in ~/.config/desmume for config file,
saves and savestates. The old .desmume.ini will be moved
automatically with the name config but you have to move your saves
manually.
Some save files may be invalidated due to use of broken crc logic.
Back up your DSV files before using this version of the emulator or else
the game might wipe it.
General/Core:
bug: emulate keypad interrupt
bug: spu overhaul, add capture support
bug: fix dma address reloading
bug: fix rom close memory corruption
bug: fix div and sqrt busy flag bug
bug: fix vectest
bug: fix lid savestate desync
bug: fix texcache memory GB explosion when games use tons of tiny 3d sprites
bug: fix huge rerecording movie file handle leak
bug: fix EXXXXXXX cheat codes and some add/edit/save/load bugs
bug: add 8MBit - 512MBit flash emulation
bug: fix firmware booted-from-card flag
bug: fix some failures to wake
bug: fix some rtc calendar logic
bug: op_bkpt emulation
bug: correctly emulate POWCNT1 and POWCNT2 and SPI power device
bug: corrections to bootup stack configuration
bug: protect bios from being overwritten
bug: initialize save data to 0xFF instead of 0x00
bug: handle relocated irq vectors
bug: support patched firmwares
bug: handle 8bit auxspidata, 32bit BLDY, 32bit div regs
bug: fix some divide by zero cases
bug: don't print \n in ideas debug message
bug: don't let games read off end of cart and crash emulator
bug: fix SWI 0x0E crc16 ; some save files using wrong crc may be invalidated
bug: fix many big endian bugs
bug: fix CPSR.I idle wakeup
bug: fix loadstate crashes, mostly when sound is enabled
enh: support devkitpro argv
enh: add gbaslot-rom commandline
enh: add no$gba debug message
enh: add rtc start to dsm header
Graphics:
bug: fix a mistakenly rendered OBJ window and 3d blend effects
bug: fixes to matrix stacks, fixing lots of garbled geometry
bug: fix fog density registers
bug: fix hblank dma to run also on scanline 262
bug: fix w/z depth flags for broken GUIs in dual screen 3d games
bug: fixes to poly sorting
bug: block 8bit vram writes
enh: improve accuracy of opengl shaders
Windows:
bug: fix 16bpp display
bug: more fixes to multi-gamepads
bug: cheat windows robustification
bug: fix that sticky pause state when resetting and loading roms
bug: dont crash when no sound device is available
bug: change F10 to be save slot 0
bug: fix --start-paused
enh: try not to screensave while using gamepad
enh: add EPX and EPX1.5X resize filters
enh: add a japanese translation which will soon be stale like the others
enh: add fancy ctrl+printscreen with emulator info on it
enh: add "lockdown" window mode to keep window safe from fast stylus action
enh: add alt+enter fullscreen command
enh: add card eject command
enh: add ddraw software mode forcer
enh: improve oam viewer
enh: default 3d to rasterizer so we dont have to suggest it 1000 times a day
enh: add dump-all-memory tool
enh: add reload rom menu/hotkey
Linux/OSX:
bug: fix building for nosse2 systems
bug: fix --num-cores
bug: fix occasional touchscreen failures
bug: fix crash starting dsm record
enh: add --nojoy=1 to fix laptops with accelerometers
enh: add simple auto frameskip mode in the gtk frontend
enh: add gui for configuring joystick in the gtk frontend
enh: make the cli frontend read the ini config file too
enh: additional OpenAL microphone backend (ncalexan)
enh: common place for config and saves (Jan Steffens)
enh: libagg is now optional if you don't need the hud
0.9.4 -> 0.9.5 (r2437-r3075)
0.9.5 introduces an entirely rewritten main emulation loop
This totally changes the timing, and totally breaks old savestates.
The OSX build is now based on the GTK port which is more up-to-date.
Assorted Highlights:
* synchronous SPU mode to fix streaming sounds
* win32: lua engine, path configuration, 7z dearchiving support
General/Core:
bug: rewrite main emulation loop and cycle accounting, fixes a lot of timings
bug: add more detailed timing emulation, removes much bogus lag
bug: rewrite DMA,gxfifo,gxstat; fix many games and no more alternate flush mode
bug: fix cflash directory support for non-windows and sector-writing
bug: fix freeze in cart irq
bug: correctly emulate dma to/from tcm
bug: fix in thumb LSR carryflag
bug: fix thumb BX PC switch to arm state
bug: fix adpcm looping, remove adpcm caching (no longer necessary)
bug: fixes to swi 3,4,5,8,0x10
bug: fixes to exmemstat and ipc sync registers
bug: support new backup commands
bug: improve bootup bios/firmware emulation steps
enh: gbaslot: add guitar grip, gbagame flash support, expansion memory pak
enh: add more powerful antigrain-based drawing library and rewrite OSD system
enh: ideas-style debugging prints
enh: most optimizations now SSE instead of SSE2
enh: more improvements to frameskipping and frame advance/speed controls
Graphics:
bug: fix backdrop blending with garbage
bug: fix 256B granularity sprite addressing for sub gpu
bug: fix obj blending, bmp obj rendering, and some obj window cases
bug: fix 128-wide captures
bug: fix 16color BG line buffer overflow
bug: fix color overflow in capture blending
bug: fix disp fifo capture
bug: fix simultaneous vram display and capture via same bank
bug: fix 3d overflow acknowledge registers
bug: fix 32bit toon table writes
bug: change 3d cores to use 18bit color
bug: fix boxtest (addition overflow!), move clipper to main graphics engine
bug: fix failure in some cases of polygon clipping
bug: fix disp3dcnt emulations
bug: fixes to poly sorting
bug: fix ogl renderer wireframe support
bug: swrast: fix backface culling of nonconvex polys
bug: swrast: add clear image and scroll emulation
bug: swrast: add fog emulation
bug: swrast: fixes to shadow rendering
bug: swrast: preliminary edge marking, works decent
enh: swrast: multicore optimization for a few fps speedup
Windows:
bug: fix support for multiple gamepads and gamepad hotkeys
bug: fix mic noise code and load wav instead of raw; effective in more cases
bug: fix for several sticky and broken hotkeys, and f10 hotkeys
bug: fixes in ram search, add DTCM and ITCM searching, ...
bug: fix sound settings vol slider
bug: recover from missing window -32000 problem
bug: don't turn on mic unless mic input is enabled
enh: x64 build type now supported
enh: side-by-side and single screen view modes, many fixes to window resizing
enh: choose any gap size by dragging bottom window edge (must be enabled)
enh: choose a gap color
enh: import/export no$GBA savefiles directly
enh: multicore optimization for filters, rotation, OSD
enh: soundview can now mute channels
enh: new ioregview
enh: common commandline system, many arguments shared with linux
enh: improve map view tool to support more modes
enh: add "FORCE AS CURRENT" recovery tool for mis-sized savefiles
enh: add some kind of very small savestate rewinding buffer
enh: autoframeskip works better
enh: add Italian translation
enh: added 2x resizing filters (hq2x, hq2xs, lq2x, lq2xs, 2xsai, supereagle)
(scanlines, nearest2x, bilinear)
Linux:
enh: alsa microphone support
enh: hud and osd notification for gtk and cli frontends
enh: add support for the SSE optimizations
0.9.2 -> 0.9.4 (r1844->r2352->r2437)
0.9.3 was skipped due to emu news sites sneaking it out of our staging area and
releasing it prematurely while it still had bugs. I was going to curse them
individually, but then I decided that they would just like the publicity.
Highlights:
* New save autodetection and save file format
* Full rerecording support
General/Core:
bug: fix many 64 bit and endian issues
bug: fix mic input, which was nearly useless before
bug: fix failures of large dmas
bug: fix in ipc sync which broke devkitpro touch
bug: screenshots now exclude hud and rotation
bug: rewritten vram mapping (fixes corrupted or missing BG)
enh: add universal commandline system (same commandline options on every port)
enh: cheats: added Action Replay code parser
enh: more reliable and useful frameskipping
enh: SPU: speedup: add adpcm caching
enh: SPU: speedup: interpolation is now optional
enh: print svn build number so we can identify people's svn builds from screenshots
Graphics:
bug: add polygon y-sorting (fixes 3d guis)
bug: fix texcoordgen mode 3; fixes some ortho sprites and some entirely broken games
bug: display capture fixes
bug: fix a number of OBJ modes
bug: fixes to affine BG modes
bug: better emulate some translucent OBJ
bug: more correct handling of color effect windows and backdrop colors
bug: fix matrix stack overrun which crashed emulator
bug: swrast: add clear depth image emulation and other fixes to depth buffering
bug: swrast: fix some toon and highlight cases
bug: fix bug in matrix stack, fixes some broken models
enh: add alternate flush mode HACK 3d config toggle, fixes some entirely broken 3d games
Windows:
bug: more robust cheats engine and dialog
enh: more solid avi and wav recording
enh: improved tools: memory viewer
enh: added tools: spu viewer, ram watch, ram search
enh: change build configuration system
enh: speedup: add gpu core disabling to hide useless screens
enh: add background pause feature (for when emulator loses focus)
enh: add missing autohold for L and R
enh: add chinese translation
Gtk frontend:
enh: switch all of menu/toolbar system to GtkAction + GtkUIManager
enh: remove the gtglext 3d code
enh: improve/speedup screen resize and final presentation logic in gtk frontend
enh: minimal rerecording hookups
Cli frontend:
enh: hooked the frameskip (szigor)
enh: misc usability improvements: auto pause switch for pausing when focus is lost and exit on escape pressing (szigor)
enh: hook the fake noise mic; use m to toggle
0.9.1 -> 0.9.2
General/Core:
bug: fix error in SBCS/RSCS flags; fixes many odd behaviors and crashes [zeromus]
bug: add support for sleep mode and power registers [luigi__]
bug: important fixes to RTC so correct time is actually told [luigi__]
bug: fix card reads below 0x8000; fixes some game freezes [normatt]
bug: fix 4 mbit save type; fix non-autodetect savefile dumping [zeromus, matusz]
enh: add sram to GBA game addon emulation for importing savefiles [zeromus]
enh: many improvements and feature hookups in linux ports [matusz, luigi__]
Graphics:
bug: fix specular texture mapping mode [luigi__]
bug: repairs to some capture modes and vram mapping [zeromus, CrazyMax]
bug: viewports finally correctly handled [zeromus]
enh: add software rasterizer. quirky, but on par with opengl [zeromus]
Windows:
bug: mitigate bad frameskipper; default to old frameskipping mode [zeromus]
bug: fixes with recent roms and zipfile loading [zeromus]
bug: fix window position memory [zeromus]
enh: bios and firmware may now be used and booted [luigi__]
enh: many display, OSD, and input enhancements [luigi__]
enh: brand new hotkey and controls binding system [zeromus]
enh: configurable screen separation [luigi__]
enh: fast forward key [pa__]
enh: improvements to mic [luigi__]
enh: faster updates in debug tools, up to once per frame [pa__]
Mac OS X Port:
enh: added Italian translation thanks to Paolo Bernini [jeff]
enh: resurrection of GDB stub [sigmaris]
0.9 -> 0.9.1
General/Core:
enh: GBA slot emulation [CrazyMax]
- Rumble support (windows only)
- GBA game
enh: Mic support (windows only?) [luigi__]
enh: Preliminary cheats system [CrazyMax]
enh: Savestates invalidated, as more variables have been added.
bug: Added PSG white noise [luigi__]
bug: fix arm/thumb ROR [zeromus]
bug: [ 2550645 ] Super Princess Peach: crash when starting a puzzle [zeromus]
bug: win32: fix spu wav file writer (regression from 0.8) [zeromus,luigi__]
bug: Much work on FIFOs, still not finished [CrazyMax]
bug: Many fixes to dma [zeromus, CrazyMax]
bug: bios WaitForVblank and WaitForInterrupt fixed [luigi__]
Graphics:
bug: Added sprite blending [luigi__]
bug: more correct mosaic effects, still imperfect [zeromus]
bug: Many fixes to tile rendering; all graphics tests now pass [luigi__]
bug: fix crashes in some affine BG [zeromus]
bug: Implement some pos test function [luigi__]
bug: fix texture mapping across texture and palette banks and to unmapped banks [zeromus]
bug: fix texture handling for texels with MSB set (fixes some texture corruption) [zeromus]
bug: fix texture coordinate generation, including environment mapping [zeromus]
bug: texture cache invalidates when palettes change, prevents some texture corruption [zeromus]
bug: fix display capturing from 2d+3d source when display mode is display-vram [zeromus]
bug: [ 2488334 ].1 fixes to layer compositing [luigi__]
bug: [ 2488334 ].3 fix bug in support for hdma affine bg parameters [zeromus]
bug: Improvements to 3d h-scrolling [luigi__]
bug: Fix some errors in rendering 512 tall BG [zeromus,CrazyMax] (still not fully resolved)
bug: Add optional fragment shading pipeline (more precision) [luigi__]
bug: Fix bug where some sprites got cut of on x=255 [zeromus]
bug: Implement GXSTAT register [CrazyMax]
Windows:
bug: resizing and rotating work in vista [luigi__]
enh: 0 frameskip now lets emulator run at excess speed [zeromus]
Mac OS X Port:
bug: left key setting no longer gets confused with the right key [jeff]
enh: more keys can be mapped
0.8 -> 0.9
There have been so many changes that this list can hardly be considered complete.
For this release, we have formatted the list into a high level overview of big changes and bad bugs relative to the previous release. Hopefully what you're interested in.
This list does not include items which are solely performance boosts, for let us just say that virtually every system has been speeded up.
* The savestate system is totally changed and incompatible with old savestates.
* The 3d system should be considered rewritten.
General/Core:
enh: Convert to c++
enh: Add functions for a lid open/close. Holding key (default "Backspace" in Windows port) while game is freeze/non freeze. [CrazyMax]
enh: Add secure area decryption from ndstool [zeromus]
enh: Change savestate code to support loosely bound chunks and more easily other parts of the emu (GE, GPU).
The savestate format is changed, but from now on it is in principle more resilient
(though it will continue to break as we tinker with the internals) [zeromus]
enh: Added SSE2 optimizations for matrices. Since we now make an SSE2 build, more optimizations can be made. [CrazyMax]
enh: Add a preliminary GUI hud system [CrazyMax,zeromus]
CPU/MMU:
bug: Many fixes in IPC and GE FIFOs. Fixes freezes in NSMB, dsracing, and others. [CrazyMax,luigi__,shash]
bug: Fix ARM instructions SBC and RSC (likewise SBC in thumb) [normatt]
bug: Fixed Thumb LDMIA (fixes ingame Dead'n'Furious) [shash]
bug: Fix repeating DMA (fixes NSMB parallax BG) [zeromus]
bug: Proper handling for unaligned CPU accesses [luigi__]
bug: Proper handling for undefined instruction exceptions [Salva Peiró]
bug: correctly return vram control register values (fixes homebrew 3d games) [zeromus]
enh: Remove 16MB of WRAM at 0x01****** from arm9. Mapped to unused instead. Nobody knows what this was. [zeromus]
enh: Changed instruction execution to 16 at a time blocks (tested and stable) [shash]
Hardware:
bug: Newer and better sqrt and div emulation; makes SM64DS playable [luigi__,shash,zeromus]
bug: Add preliminary RTC implementations [CrazyMax]
enh: Add cosine interpolation in the SPU (conditionally compiled) [zeromus,luigi__]
enh: Experimental: always one silent non-mixing SPU core at 44.1khz synched with emu, for more precision.
The audible core runs with the host, causing music to slow down but not tear or pitch bend. [zeromus]
Graphics:
- Overhaul 3d:
. Move entire GE to core emu.
. Move OpenGL renderer to emu core for optional use by platforms, removing ogl_collector. Now every platform shares the same 3d code.
. Reorganize 3d code to defer rendering to after 3d vblank. Eliminates tearing, and texturing artifacts. [zeromus]
. Add optional fragment shading pipeline (more precision) [luigi__]
. Move lighting model to software instead of using opengl's fixed function model [zeromus]
. Render shadow volumes; toon shading and highlight table [zeromus, luigi__]
. Added texture caching! big speed up. [CrazyMax]
bug: Many assorted tweaks and improvements to 3d and 2d precision [zeromus,CrazyMax,luigi__]
bug: Fixes to GE: command unpacking, projection and pos-vector mode matrix handling, mult and load commands [zeromus]
bug: Fix a bug in texture transformation mode 1 [zeromus]
bug: Fixed GPU rendering bugs in sprites and BG [CrazyMax]
bug: Fixes to texture conversion [CrazyMax,zeromus]
bug: Fixes in capture display (no blinking in many games with dual 3D) [CrazyMax]
bug: Fixes in master brightness (this fixes some games with black screens) [CrazyMax]
bug: Fixes in screen, backdrop, and sprite blending [luigi__]
bug: Changed clear depths and how depth initial values are calculated (fixes SM64DS skybox, Castlevania) [shash,lugi__]
bug: Add 3d layer h-scrolling [zeromus]
bug: Added transparency and fixed material alpha support and alpha testing on the 3D core [shash]
bug: Rewrite VRAM mapping control and rendering (more accurate) [CrazyMax,luigi__]
bug: convert colors to opengl better to prevent alpha=31 polys from being ever so slightly transparent [zeromus]
enh: Add MMU->GPU signal for when vram mappings change to function as a texture cache invalidate signal [zeromus]
enh: Make matrix 4x4 multiply routines use W-coordinate; carry w coord through pipeline [zeromus]
Mac OS X port:
bug: Fixed: Filenames and paths with unicode characters now work. [Jeff]
bug: Fixed: Load state from file button works again. [Jeff]
enh: Save State panel now pauses emulation while the file selection box is open. [Jeff]
bug: Fixed: Frozen video output (and/or messed 3d emulation) after loading a state. [Jeff]
bug: Added option to load the most recent file upon launching the program. [Jeff]
enh: Added French translation (thanks to Pierre Rudloff). [Jeff]
enh: Added basic key mapping configuration to application preferences (thanks to Julio GorgŽ). [Jeff]
enh: Added keyboard shortcuts for Execute, Pause and Reset command (thanks to Julio GorgŽ). [Jeff]
enh: Default key mappings are no longer case sensitive. [Jeff]
enh: Added ability to limit speed. [Jeff]
enh: Fixed: Video output should work on software-only 3D renderers. [Jeff]
Windows port:
bug: Fix a race condition in NDS_3D_Reset and NDS_glInit [zeromus]
bug: Fix the buggy auto frameskip logic which made the emu slow to a crawl. Now it runs fast! [zeromus]
bug: Fix resizing, rotate & aspect ration of main window. [CrazyMax,_zeromus]
bug: Remove multithreading from user interface after finding several synchronization issues [zeromus]
enh: recent roms menu [luigi_]
enh: Changed graphics render core to DirectDraw (work faster) [CrazyMax]
enh: Add an arm9 cpu load average calculator similar to no$. but I dont think it works right. [zeromus]
enh: Rewrite all debug tools (autoupdate works now) [CrazyMax]
enh: Rewrite input core & replace config input dialog [CrazyMax]
enh: Add AVI output [zeromus]
enh: Add pause toggle and frame advance hotkeys [adelikat]
enh: Add frame counter display and hud messages framework [adelikat]
enh: Main window remembers position, size, and a few other emu preferences [adelikat]
enh: Removed directx sdk dependency for easier building. [zeromus]
enh: Savestate doesnt unpause emu if it is already paused [adelikat]
0.7.3 -> 0.8
Cocoa:
- Save State As function now works. [Jeff B]
- Recent Items menu now works. [Jeff B]
- Opening NDS files from Finder now works. [Jeff B]
- Added screenshot feature. [Jeff B]
- Added preferences. [Jeff B]
- Many more strings are translatable now. [Jeff B]
- Default screen color is black (better represents being "off" and easier on eyes at night). [Jeff B]
- Added sound. [Jeff B]
- Now is a universal binary. [Jeff B]
- Leopard resolution icon added. [Jeff B]
- Added a Japanese translation. [Jeff B]
- Added an optional status bar (resize handle no longer overlaps screen). [Jeff B]
- New ROM Info and About DeSmuME windows have been added. [Jeff B]
- Fixed several bugs in window resizing. [Jeff B]
- Added FAT image support for homebrew games (thanks to TypeError). [Jeff B]
- Key config can be changed on the command line. Save/load hotkeys changed (so expose doesn't override). [Jeff B]
- Key bindings may work better on non-US keyboards now (needs testing). [Jeff B]
general:
- Encapsulate GDB debug stub to avoid certain problems [shash]
- Fixed CPU LD*/ST* bugs [shash]
- Fixed New SMB mini-games freeze [shash]
- Fixed possible segfault in ROMReader on ia64 and amd64. [evilynux]
- Fixed a crash bug with 2D background corrupting memory [shash]
- Flag check optimization [carlo_bramini]
- Applied some endian fixes in GPU (thanks to Phazz) [Jeff B]
gtk-glade:
- Added DeSmuME version in about dialog. [evilynux]
- Updated website url in about dialog. [evilynux]
- Added Brazilian Portuguese translation by Dreampeppers99. [evilynux]
- Better desktop menu entry following FreeDesktop specifications. [evilynux]
gtk:
- Updated website url in about dialog. [evilynux]
- Better desktop menu entry following FreeDesktop specifications. [evilynux]
windows port:
- Added an "about" box [shash]
- DirectInput control interface with joystick support [CrazyMax]
- Matrix and Light viewer [Acid Burn]
0.7.2 -> 0.7.3
gtk-glade:
- Full localization using intltool/gettext. [evilynux]
general:
- Added a README.TRANSLATION documenting the localization process. [evilynux]
MacOS X:
- Initial version of the Mac interface added. [Jeff B]
0.7.1 -> 0.7.2
spu:
- big endian fixes. [cyberwarriorx]
gpu:
- big endian fixes. [marcus_c]
gtk-glade:
- opengl improvements. [masscat]
general:
- Added support for setting NDS firmware language value. [masscat]
- Function added for setting firmware language. [masscat]
- Mac/msys compilation fixes. [cyberwarriorx]
- Fix compilation when pkg-config macros are not available [evilynux]
0.7.0 -> 0.7.1
general:
- Added GDB debugger stub [masscat]
- Added new/different GBAMP CFlash image reader/writer [masscat]
gpu:
- Major speedup to the 2D core [shash]
gtk-glade:
- Added command line options. [masscat]
- Added FPS limiter [masscat]
cli:
- Added command line options. [masscat]
- Added FPS limiter [masscat]
- Added option to use OpenGl to render window (allows resizing). [masscat]
windows port:
- Added command line options. [masscat]
- Added multiple language support [cyberwarriorx]
- Added Danish language translation [thomas-2007]
0.6.0 -> 0.7.0
general:
- Added support for *.duc files [cyberwarriorx]
gpu:
- Added support for sprite rotation/scaling [shash]
- Added support for the 3D core (openGL and null plugins) [shash]
windows port:
- A bunch of fixes [Dmitry Krutskih]
- Fixed a bug in sound that was causing it to still not work for some
people [cyberwarriorx]
gtk:
- Added 3D emulation
- Added command line options.
- Added option to use OpenGL to render window (allows resizing).
gtk-glade:
- Added 3D emulation
0.5.0 -> 0.6.0
general:
- Added zipped (based on zziplib) and gzipped (based on zlib) rom support.
arm:
- Added relocation interrupt vector.
- Added region access right checks.
- Enabled LDC/STC instructions.
- Fixed powersave (cp15) IRQ wait.
- Fixed MOV instructions
gpu:
- Added special color effects.
- Added windowing feature.
- Fixed transparent direct color backgrounds.
- Fixed disabled sprites showing.
- Fixed 8/32 bit access to gpu registers.
- Fixed missing backgrounds
- Support for master brightness
wifi:
- Added RF chip interface.
- Added BB chip interface.
windows port:
- Fixed address calculation in disassembler.
- Added Force Maintain Ratio option for window stretching
linux port (cli, gtk and gtk-glade):
all:
- Added joystick support.
- Fixed X and Y buttons.
gtk-glade:
- Added joystick configuration.
- Improved I/O registers viewer tool.
- Added save and load states support.
0.3.3 -> 0.5.0
arm:
- Fixed MSR with immediate value opcode.
- Fixed LSR_0 thumb opcode (C flag is correctly set now).
- Fixed LDR*/STR* opcodes.
- Fixed unaligned memory access on THUMB Core.
- Added relocating SWI routines.
bios:
- Added decompression functions.
- Added GetPitchTable function.
- Added GetVolumeTable function.
- Added GetCRC16 function.
- Added experimental SoundBias function.
- Added GetSineTable function.
cart:
- Added CompactFlash/FAT emulation.
- Added Get ROM chip ID Cartridge command.
gpu:
- Added framebuffer emulation.
- Fixed a bug in GPU (xfin could be greater than LG causing a segfault).
- Added support for Display Mode 0(Display Off).
- Added the basic framework for Display Mode 3(Display from Main RAM).
spu:
- Added sound emulation.
- Added sound core system.
- Added WAV write core.
- Added dummy core.
- Added Direct Sound core.
linux port:
- Added GTK+ GUI.
- Added command line interface.
- Added stylus and arm9 keypad support in CLI version.
- Added FPS display.
- Added basic frameskip.
windows port:
- Fixed a bug when displaying a ROM's information.
- Added key configuration.
- Removed the debug key.
- Added new experimental auto frameskip/frame limit code.
- Added sound settings dialog.
- Added a few menu options for accessing the website, forums, and for
submitting bugs.
general:
- Rewrote code in C.
- Fixed warnings.
- Used defines and typedef's to make things more portable and easier to
read.
- Added autotools stuff.
- Changes to logging system.
- Added screenshot function.
- Translated most french to english.
- Added savestate support.
- Added firmware reading support(needs work).
- Added Backup Memory support with autodetection.
- Fixed some endianess issues.
- Fixed things so Visual C++ can compile code.
- Added bsd support.
- Reworked ROM loading so you can load a different rom without any problems.
- Finished NDS_Reset. Now the emulation can be reset even while running.

View File

@ -1,97 +0,0 @@
DeSmuME
_________________________________________
Copyright (C) 2006 yopyop
Copyright (C) 2006-2022 DeSmuME team
Last Updated: May 23, 2022
Contents:
1) About ................................................................... 14
2) Credits ................................................................. 59
3) Contact Information ..................................................... 72
4) License ................................................................. 82
1) About ______________________________________________________________________
DeSmuME is software that allows you to emulate a Nintendo DS system. Think of
it as a Swiss-Army knife for Nintendo DS emulation, giving you access to many
powerful tools for testing DS features, from viewing ROM properties to managing
Action Replay cheats. And best of all, this software is completely free and
open-source.
For information on how to install or operate DeSmuME for your operating system,
please see the README file that should be present with your installation.
Port-specific README files:
* README.LIN for the Linux ports
* README.WIN for the Windows port
* README.MAC for the Macintosh port
Note that each DeSmuME port may have a different feature set from another port.
You may see more feature parity between ports over time as we continue
developing DeSmuME.
You can find our documentation on our online Wiki page. The major pages of
interest are:
* Official Documentation: https://wiki.desmume.org/index.php?title=Main_Page
This is the main Wiki page that contains all of our official documentation.
* Manuals: https://wiki.desmume.org/index.php?title=Manual
The manuals contain detailed information about how to operate DeSmuME for each
port.
* FAQ: https://wiki.desmume.org/index.php?title=Faq
The Frequently Asked Questions (FAQ) page has a lot of useful general
information about DeSmuME. Do note that some of the information may be platform
specific, and may not directly apply to your version of DeSmuME.
* Build Instructions:
https://wiki.desmume.org/index.php?title=Installing_DeSmuME_from_source
This page contains detailed port-specific instructions about how to make your
own build of DeSmuME directly from the source code.
2) Credits ____________________________________________________________________
See the AUTHORS file for list of DeSmuME team members.
Special thanks go to:
* yopyop (original author of DeSmuME),
for releasing the source code of this great emulator.
* Martin Korth (author of GBATEK),
for his well-written Gameboy Advance and Nintendo DS documentation.
3) Contact Information ________________________________________________________
Official Website: https://desmume.org
Public Forum: https://forums.desmume.org
Developer Chat: irc://irc.libera.chat:6697/desmume
Source & Bug Reports: https://github.com/TASEmulators/desmume
Please don't ask for ROMs, BIOS files, or any other copyrighted stuff.
4) License ____________________________________________________________________
This file is free software: you can redistribute it and/or modify it under the
terms of the GNU General Public License as published by the Free Software
Foundation, either version 2 of the License, or (at your option) any later
version.
This file is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with
this software. If not, see <https://www.gnu.org/licenses/>.
* See the GNU General Public License details in COPYING.

View File

@ -1,441 +0,0 @@
DeSmuME DLL/SO
DeSmuME is written in C++ using the SDL libraries.
* http://www.libsdl.org/
Reference Usage
===============
A Python library using the DLL/SO interface can be found at
`https://github.com/SkyTemple/py-desmume/blob/master/desmume/emulator.py`.
Build Linux & Mac
=================
DeSmuME uses the Meson build system to the shared object under Linux and MacOS:
* https://mesonbuild.com/
To build, first cd to src/frontend/interface and then run `meson build`
Then build the library by running `ninja -C build`
It will generate a shared object under `build/libdesmume.so`.
Build Windows
=============
To build open and build the Visual Studio solution at
`src/frontend/interface/windows/DeSmuME_Interface.sln`.
Interface
=========
The interface has the following API functions exposed in the DLL/SO.
Emulator key indices
--------------------
Internal ID numbers for emulator keys (used for some functions):
#define KEY_NONE 0
#define KEY_A 1
#define KEY_B 2
#define KEY_SELECT 3
#define KEY_START 4
#define KEY_RIGHT 5
#define KEY_LEFT 6
#define KEY_UP 7
#define KEY_DOWN 8
#define KEY_R 9
#define KEY_L 10
#define KEY_X 11
#define KEY_Y 12
#define KEY_DEBUG 13
#define KEY_BOOST 14
#define KEY_LID 15
int desmume_init(void);
-----------------------
Initializes the emulator. Needs to be called before any other API functions.
void desmume_free(void);
------------------------
Destroys the emulator, needs to be called to free memory. After this no API
functions must be called.
void desmume_set_language(unsigned char language);
--------------------------------------------------
Sets the firmware language. Valid values:
0 = Japanese, 1 = English, 2 = French, 3 = German, 4 = Italian, 5 = Spanish
int desmume_open(const char *filename);
---------------------------------------
Loads a ROM into the emulator. Returns 0 on success and another number on error.
void desmume_set_savetype(int type);
------------------------------------
Sets the type of SRAM save. 0 for auto.
void desmume_pause(void);
-------------------------
Pauses the emulator.
void desmume_resume(void);
--------------------------
Resumes the emulator.
void desmume_reset(void);
-------------------------
Resets the emulator and resumes.
BOOL desmume_running(void);
---------------------------
Returns 0 if the emulator is not running and 1 if it is.
void desmume_skip_next_frame(void);
-----------------------------------
Instructs the emulator to not draw the next frame.
void desmume_cycle(BOOL with_joystick);
---------------------------------------
Runs one loop iteration (tick) of the emulation.
The parameter must be 1 if `desmume_input_joy_init` was called before and
joystick input should be processed
and 0 otherwise.
int desmume_sdl_get_ticks();
----------------------------
Get the current tick number as reported by SDL.
void desmume_draw_opengl(GLuint *texture);
------------------------------------------
Only available if INCLUDE_OPENGL_2D was defined.
Draws the current tick onto the provided OpenGL texture.
BOOL desmume_has_opengl();
--------------------------
Returns whether or not OpenGL support is available.
int desmume_draw_window_init(BOOL auto_pause, BOOL use_opengl_if_possible);
---------------------------------------------------------------------------
Opens an SDL-powered window for drawing the emulator on and processing input.
If `auto_pause` is >0, the emulator is paused when the window is not in focus.
If `use_opengl_if_possible` is >0, OpenGL-based drawing is used
if OpenGL is available.
void desmume_draw_window_input();
---------------------------------
Process user input on the SDL window for this tick.
Requires `desmume_draw_window_init` to be called first.
void desmume_draw_window_frame();
---------------------------------
Draw the SDL window for this tick. Requires `desmume_draw_window_init` to be called first.
BOOL desmume_draw_window_has_quit();
------------------------------------
Returns 1 if the SDL window was closed by the user and 0 if not.
Requires `desmume_draw_window_init` to be called first.
void desmume_draw_window_free();
--------------------------------
Destroys the SDL window and frees memory. Requires `desmume_draw_window_init` to be called first.
No other SDL window functions must be called after this.
unsigned short *desmume_draw_raw();
-----------------------------------
Returns the content of the raw framebuffer of the emulator.
void desmume_draw_raw_as_rgbx(unsigned char *buffer);
-----------------------------------------------------
Fills the provided buffer as an RGBx formatted version of the emulator's framebuffer.
void desmume_savestate_clear();
-------------------------------
Deletes all savestates stored on slots.
BOOL desmume_savestate_load(const char *file_name);
---------------------------------------------------
Loads a savestate from a file. Returns 1 on success, 0 on failure.
BOOL desmume_savestate_save(const char *file_name);
---------------------------------------------------
Saves a savestate to a file. Returns 1 on success, 0 on failure.
void desmume_savestate_scan();
------------------------------
Scans the savestate slots for data. Required for `desmume_savestate_slot_exists` and
`desmume_savestate_save_slot` to return the correct data.
void desmume_savestate_slot_load(int index);
--------------------------------------------
Loads the savestate from slot `index`.
void desmume_savestate_slot_save(int index);
--------------------------------------------
Saves the current state to the savestate in slot `index`.
BOOL desmume_savestate_slot_exists(int index);
----------------------------------------------
Returns whether or not the savetstate at slot `index` exists.
char* desmume_savestate_slot_date(int index);
---------------------------------------------
Returns the date (as string) that the savestate at slot `index` was saved.
BOOL desmume_gpu_get_layer_main_enable_state(int layer_index);
--------------------------------------------------------------
Returns whether or not the layer with the given index for the main GPU is enabled.
BOOL desmume_gpu_get_layer_sub_enable_state(int layer_index);
-------------------------------------------------------------
Returns whether or not the layer with the given index for the sub GPU is enabled.
void desmume_gpu_set_layer_main_enable_state(int layer_index, BOOL the_state);
------------------------------------------------------------------------------
Disables or enables the layer with the given index for the main GPU.
Disabled layers are not drawn.
void desmume_gpu_set_layer_sub_enable_state(int layer_index, BOOL the_state);
-----------------------------------------------------------------------------
Disables or enables the layer with the given index for the sub GPU.
Disabled layers are not drawn.
int desmume_volume_get();
-------------------------
Returns the current emulator volume in a range from 0-100.
void desmume_volume_set(int volume);
------------------------------------
Sets the current emulator volume in a range from 0-100.
unsigned char desmume_memory_read_byte(int address);
signed char desmume_memory_read_byte_signed(int address);
unsigned short desmume_memory_read_short(int address);
signed short desmume_memory_read_short_signed(int address);
unsigned long desmume_memory_read_long(int address);
signed long desmume_memory_read_long_signed(int address);
-----------------------------------------------------------
Read the emulated memory at `address` with different sizes and sign settings.
void desmume_memory_write_byte(int address, unsigned char value);
void desmume_memory_write_short(int address, unsigned short value);
void desmume_memory_write_long(int address, unsigned long value);
-------------------------------------------------------------------
Write the value `value` as bytes/shorts/longs to `address` in the emulated memory.
int desmume_memory_read_register(char* register_name);
void desmume_memory_write_register(char* register_name, long value);
--------------------------------------------------------------------
Read or write the value of the specified register.
Valid register names:
- arm9.r0 - arm9.r15 : Registers r0 - r15 on the ARM9 processor.
- arm9.cpsr
- arm9.spsr
- arm7.r0 - arm7.r15 : Registers r0 - r15 on the ARM7 processor.
- arm7.cpsr
- arm7.spsr
`main` may be used as an alias for `arm9` and `sub` for `arm7`.
If the prefix is omitted, `arm9` is used.
typedef BOOL (*memory_cb_fnc)(unsigned int, int);
void desmume_memory_register_write(int address, int size, memory_cb_fnc cb);
void desmume_memory_register_read(int address, int size, memory_cb_fnc cb);
void desmume_memory_register_exec(int address, int size, memory_cb_fnc cb);
----------------------------------------------------------------------------
Register a callback function to execute when the emulator writes/reads or executes
an instruction at `address`. `size` is the size in bytes to monitor for that location
(should always be 2 to exec).
The passed callback function gets to arguments when called. The first argument
is the address the callback was triggered for, the second the size.
Only one callback can be specified per address and type (write/read/exec).
Pass 0 instead for `cb` to unregister previously registered callbacks.
void desmume_screenshot(char *screenshot_buffer);
-------------------------------------------------
Fills the 98304*3 bytes long `screenshot_buffer` with an RGB snapshot of
the framebuffer.
BOOL desmume_input_joy_init(void);
----------------------------------
Initialize SDL joypad handling. Returns 1 on success, 0 otherwise.
Must be called before any other joypad operation.
void desmume_input_joy_uninit(void);
------------------------------------
Destroys the joypad functionality. After calling this, no other joypad
operations must be called.
unsigned short desmume_input_joy_number_connected(void);
--------------------------------------------------------
Returns the number of connected joypads.
unsigned short desmume_input_joy_get_key(int index);
----------------------------------------------------
Returns the joypad key assigned to the specified emulator key.
unsigned short desmume_input_joy_get_set_key(int index);
--------------------------------------------------------
Pause and wait for the user to press a button on a joypad.
This button will be assigned to the specified emulator key.
void desmume_input_joy_set_key(int index, int joystick_key_index);
------------------------------------------------------------------
Sets the emulator key `index` to the specified joypad key `joystick_key_index`.
void desmume_input_keypad_update(unsigned short keys);
------------------------------------------------------
Update the currently pressed emulator keys. This is a bitmask where each bit
is one of the emulator's keys. See:
#define ADD_KEY(keypad,key) ( (keypad) |= (key) )
#define RM_KEY(keypad,key) ( (keypad) &= ~(key) )
#define KEYMASK_(k) (1 << (k))
unsigned short desmume_input_keypad_get(void);
----------------------------------------------
Get the currently pressed emulator keys. This is a bitmask where each bit is
one of the emulator's keys.
void desmume_input_set_touch_pos(unsigned short x, unsigned short y);
---------------------------------------------------------------------
Register a touch input at the specified location on the bottom screen.
Use `desmume_input_release_touch` to release.
void desmume_input_release_touch();
-----------------------------------
Release the current touch.
BOOL desmume_movie_is_active();
BOOL desmume_movie_is_recording();
BOOL desmume_movie_is_playing();
BOOL desmume_movie_is_finished();
----------------------------------
Returns whether the movie system is active/recording/playing/finished.
int desmume_movie_get_length();
-------------------------------
Returns the size of the movie records.
char *desmume_movie_get_name();
-------------------------------
Returns the name of the movie.
int desmume_movie_get_rerecord_count();
---------------------------------------
Returns the current rerecount counter value of the movie.
void desmume_movie_set_rerecord_count(int count);
-------------------------------------------------
Sets the current rerecount counter value of the movie.
BOOL desmume_movie_get_readonly();
----------------------------------
Returns 1 if the movie can only be read, 0 if it can also be modified.
void desmume_movie_set_readonly(BOOL state);
--------------------------------------------
Change whether or not the movie is only read-only (can not be modified).
// Returns NULL on success, error message otherwise.
const char *desmume_movie_play(const char *file_name);
------------------------------------------------------
Play the movie from the file `file_name`. Returns NULL on success, otherwise
an error message.
enum START_FROM {START_BLANK = 0, START_SRAM, START_SAVESTATE};
struct SimpleDate {int year; int month; int day; int hour; int minute; int second; int millisecond;};
void desmume_movie_record_simple(const char *save_file_name, const char *author_name);
void desmume_movie_record(const char *save_file_name, const char *author_name,
START_FROM start_from, const char* sram_file_name);
void desmume_movie_record_from_date(const char *save_file_name, const char *author_name,
START_FROM start_from, const char* sram_file_name,
SimpleDate date);
----------------------------------------------------------------------------------------
Record a movie.
- `save_file_name`: The name of the file to save the movie to.
- `author_name`: The name of the author of the movie.
- `start_from`: Where to start from:
- START_BLANK (0): Reset the emulator, start without SRAM (no savefile).
- START_SRAM (1): Reset the emulator, start using the SRAM loaded from `sram_file_name`.
- START_SAVESTATE (2): Not supported.
- `sram_file_name`: Name of the SRAM to load, if `start_from` == 1. NULL otherwise.
- `date`: Date to set the emulated device's clock to.
void desmume_movie_replay();
----------------------------
Restart playback of the current movie.
void desmume_movie_stop();
----------------------------
Stop playback/recording of the current movie.
Visit us on the web at http://www.desmume.org

View File

@ -1,72 +0,0 @@
DeSmuME
DeSmuME is written in C++ using the GTK+ and SDL2 libraries.
* https://gtk.org/
* https://libsdl.org/
It uses the Meson build system to build the GTK+3 and SDL2 port:
* https://mesonbuild.com/
... and the autotools build system for the GTK+2 and SDL2 port.
to build GTK+2 or SDL2 frontend with autotools, cd to src/frontend/posix, then
autoreconf -i (or alternatively: ./autogen.sh)
./configure
make -jN (where N is the number of CPU cores to use).
DeSmuME provides another interface based on libglade, to use
, you'll need glade:
* http://glade.gnome.org/
To build, first cd to src/frontend/posix and run
`meson build --buildtype=release`
Then build the program by running `ninja -C build`
It will generate three programs:
1) "desmume" in the "build/gtk" directory;
2) "desmume-cli" in the "build/cli" directory.
If glade is installed on your system, you'll get a third
binary:
3) "desmume-glade" in the "build/gtk-glade" directory.
You can even type "ninja -C build install" to install those programs on
your system (in /usr/local/ by default); then uninstalling is
done by typing "ninja -C build uninstall".
For more information on the available commandline options,
check the other README files which will be more up to date.
The following options specially are available on these posix ports:
--disable-limiter Disables the 60 fps limiter
--soft-convert Use software colour conversion during OpenGL
screen rendering. May produce better or worse
frame rates depending on hardware.
The following options specially are available on the Gtk+ port:
--opengl-2d Enables using OpenGL for screen rendering
--disable-sound Disables the sound emulation
--disable-3d Disables the 3D emulation
The following options specially are available on the CLI port:
--opengl-2d Enables using OpenGL for screen rendering
--disable-sound Disables the sound emulation
NOTE:
The Gtk+ and Glade builds use gtkGLext to handle the OpenGL
rendering and contexts. You may get improved performance by
also passing the argument --gdk-gl-force-indirect. This has
been seen to improve things for Nvidia based graphics cards
under Linux.
Visit us on the web at http://www.desmume.org

View File

@ -1,392 +0,0 @@
DeSmuME
_________________________________________
Copyright (C) 2006 yopyop
Copyright (C) 2006-2022 DeSmuME team
Last Updated: May 23, 2022
Contents:
1) System Requirements ..................................................... 17
2) Quick Start Guide for Using DeSmuME for macOS ........................... 58
3) Improving Emulation Performance ........................................ 204
4) Troubleshooting ........................................................ 230
5) Additional Documentation ............................................... 245
6) Contact Information .................................................... 275
7) License ................................................................ 377
1) System Requirements ________________________________________________________
Operating System: macOS v10.5 (Leopard) or later
CPU: Can run on any PowerPC G4, G5, or Intel processor
Minimum Recommended: 2.4 GHz Intel Core 2 Duo
Best Experience Recommended: 2.4 GHz Intel i5 (Haswell)
RAM: 512 MB (minimum)
2 GB (recommended)
Before you begin, make sure that your Mac meets the listed system requirements.
In general, any Mac with an Intel Core 2 Duo processor (from Mid-2007) should
be sufficient for basic gaming. However, it is possible to run DeSmuME with
even older hardware than that. In this case, you will need to use the settings
listed in the section "Improving Emulation Performance" to make things usable.
With this level of hardware, running any additional graphics enhancing features
will result in a poor experience. Some frameskip will also be necessary in
order maintain your execution speed.
If your Mac meets the minimum recommended requirements, then you should be able
to run all games at full speed without any frameskip. You may need to use some
of the settings listed in the section "Improving Emulation Performance" for
certain games, but they should not be required for most games. You will also be
able to use some basic graphical enhancements, such as using some of the
display filters. However, increased 3D rendering resolution may not be possible
for all games for this level of hardware.
However, if your Mac has an Intel Haswell (from late 2013) or an Apple Silicon
processor (from 2020), you will be able to run all games with all of DeSmuME's
features without any performance problems. Graphics enhancements, such as
increased 3D rendering resolution, can be adjusted as needed to fit the
performance level of your hardware.
Please note that running DeSmuME on a PowerPC, while possible, is not fully
supported. The PowerPC binary exists mostly for testing and development
purposes, and also just because we can. Most games don't work well on PowerPC,
and so you will be limited to running only the most basic of games, such as
"Phoenix Wright: Ace Attorney" or "Picross DS."
2) Quick Start Guide for Using DeSmuME for macOS ______________________________
Installing DeSmuME is as easy as copying DeSmuME.app to your Applications
folder (or other folder of your choice). Double-click the app to start DeSmuME.
Note that DeSmuME for macOS may have a different feature set than DeSmuME for
Windows and DeSmuME for Linux. As of this writing, some features that are
present in DeSmuME for Windows are not present in DeSmuME for macOS.
The rest of this section will be a guide to help you quickly get started using
DeSmuME for macOS.
Loading a ROM and Starting the Emulator:
Simply double-click the desired ROM from the Finder to play the game. By
default, DeSmuME will load the ROM and start emulation. Also, there are
additional ROM loading options that you can change in DeSmuME > Preferences if
you need them.
Using the NDS Controller:
Each NDS controller button can be mapped to a button of your choice on your
keyboard, gamepad, or joystick. You can view the mappings by clicking on Input
in DeSmuME > Preferences. To change a mapping, click on the NDS control that
you want to change, then press the button on your input device to map it.
By default, the NDS controller is mapped to the following keys on your keyboard:
Up - Up Arrow
Down - Down Arrow
Left - Left Arrow
Right - Right Arrow
A Button - X
B Button - Z
X Button - S
Y Button - A
L Trigger - Q
R Trigger - W
Start - Return
Select - Tab
Lid - Delete (Backspace)
Microphone (Internal Noise Samples) - ` (Accent)
The NDS can support a variety of SLOT-2 devices. Some devices, such as the
Guitar Grip, EasyPiano, and Taito Paddle have inputs, which are mapped to your
keyboard using these defaults:
Guitar Grip:
Green - E
Red - R
Yellow - T
Blue - Y
EasyPiano:
C - C
C# - F
D - V
D# - G
E - B
F - N
F# - J
G - M
G# - K
A - , (Comma)
A# - L
B - . (Period)
High C - / (Forward Slash)
Paddle:
Paddle Adjust -5 - O
Paddle Adjust +5 - P
In addition, the following emulator functions are mapped to your keyboard by
default:
Execute/Pause - Forward Delete
Reset - Page Down
Rotate Display Left - [ (Left Bracket)
Rotate Display Right - ] (Right Bracket)
Set Speed to Half - - (Dash)
Set Speed to Double - = (Equal)
Using the NDS Touch Pad:
Touch pad input is emulated using the left mouse button by default. Simply
click in the touch pad area of the NDS display window to use the NDS touch pad.
Using the NDS Microphone:
Some games make use of the NDS microphone. DeSmuME emulates the NDS microphone
by using the default audio input device selected in your System Preferences.
You can choose Emulation > Show Microphone Settings to view the audio input
device that DeSmuME is currently using, as well as setting its gain.
DeSmuME will track the audio input level on the meter as the NDS reads the
microphone. The meter reflects the audio input level as seen by the NDS, not
the host. Note that some games ignore the microphone, and therefore will not
register on the meter. If you need to view the audio input level from the host
machine's perspective, you can view the host's audio input level in your System
Preferences.
Finally, you can generate audio samples in software by using one of DeSmuME's
audio generators, and send those audio samples to the NDS. This is what the
Microphone command in your Input Preferences does. As long as the Microphone
command is engaged, the host input device will be ignored. When you disengage
the Microphone command, DeSmuME will automatically return to reading the host
input device.
The microphone icon serves to indicate the current status of the NDS
microphone, and will change color for each status:
Black - The microphone is inactive due to the emulation being paused.
Dark Gray - The host audio input is inactive because the user has muted it
or because the user never authorized its usage. The emulation
is currently only accepting software-generated sources.
Bright Gray - A software-generated source is being used for the microphone
input. This overrides any host audio input.
Dark Green - The host audio input is active. However, the input level is
too low to be meaningful, or the game is ignoring the
microphone.
Bright Green - The microphone is active and the game is reading a
meaningful input level from the host audio input.
Bright Red - The microphone is active and the game is reading a clipped
input level. Depending on the situation, this may or may not
be desirable. Use the gain slider to influence the host audio
input level if needed.
Rotating the NDS Display:
Some games require that the NDS display be at a certain rotation in order to
look correct. Rotation options can be found by choosing
View > Display Rotation. You can also use the toolbar buttons Rotate Left and
Rotate Right to rotate the display by 90 degrees counterclockwise or clockwise,
respectively. Finally, you can assign inputs to Rotate Left and Rotate Right in
your Input Preferences.
Freezing and Restoring the Emulation State:
Save states are a powerful feature that allows you to freeze the emulation
state and restore it later. However, note that save states are only a
temporary means of saving -- more permanent saves must be done using the
in-game save (or ROM save).
- To freeze the emulation state, choose File > Save State File.
- To restore the emulation state, choose File > Open State File.
You can also freeze/restore emulation states without having to manage the
Open/Save dialogs. There are ten available save state "slots" that you can
use to quickly freeze/restore the emulation state.
- To quick freeze the emulation state, choose File > Save State Slot > Slot #.
The default hotkey for this is (Shift-#).
- To quick restore the emulation state, choose File > Load State Slot > Slot #.
The default hotkey for this is (#).
3) Improving Emulation Performance ____________________________________________
There are many settings you can change in order to improve DeSmuME's emulation
performance. All of the settings listed below affect performance the most. Use
the settings as shown for the best possible performance. All of these settings
may be found in DeSmuME > Preferences.
- WARNING: Changing any Emulation setting may cause emulation glitches in
certain ROMs. Do not change these settings unless you are willing to
accept reduced emulation accuracy or ROM compatibility.
Emulation:
Advanced Bus Level Timing - Off (May cause glitches)
Rigorous 3D Rendering Timing - On (May cause graphical glitches)
CPU Emulation Engine - Dynamic Recompiler (Reduces ROM compatibility)
Dynamic Recompiler Block Size - 100 (May cause glitches)
Use External BIOS Images - Off (May reduce ROM compatibility)
3D Rendering:
3D Rendering Engine - SoftRasterizer (or OpenGL if GPU Scaling Factor
is greater than 4)
GPU Scaling Factor - 1
GPU Color Depth - 15-bit (Reduces color accuracy of 3D rendering)
Texture Scaling Factor - 1
4) Troubleshooting ____________________________________________________________
The vast majority of problems can be resolved by simply resetting DeSmuME's
settings back to their defaults. The easiest way to do this is to delete the
org.desmume.DeSmuME.plist file in your ~/Library/Preferences folder. There is
also a DeleteUserDefaults.applescript script that is included with your DeSmuME
installation that will do this for you.
If you are still experiencing problems after restoring your DeSmuME settings to
their defaults, then you may want to post your issue on our DeSmuME forum. Your
post may gain the attention of another user, or even a DeSmuME developer, to
help assist you with your issue. See the section "Contact Information" for how
to contact us on the forum.
5) Additional Documentation ___________________________________________________
The quick start guide in this Read Me is by no means a complete reference to
everything that DeSmuME can do! If you need any additional information about
DeSmuME, then you can reference our online Wiki pages for up-to-date
information.
* Official Documentation: https://wiki.desmume.org/index.php?title=Main_Page
This is the main Wiki page that contains all of our official documentation.
* FAQ: https://wiki.desmume.org/index.php?title=Faq
The Frequently Asked Questions (FAQ) page has a lot of useful general
information about DeSmuME. Do note that some of the information may be platform
specific, and may not directly apply to the macOS version of DeSmuME.
* DeSmuME Manual for macOS:
https://wiki.desmume.org/index.php?title=DeSmuME_Manual_for_the_Macintosh_port
This page contains complete and detailed information about how to operate
DeSmuME for macOS.
* DeSmuME Build Instructions for macOS:
https://wiki.desmume.org/index.php?title=Installing_DeSmuME_from_source_on_OS_X
This page contains complete and detailed instructions about how to make your
own build of DeSmuME for macOS directly from the source code.
6) Contact Information ________________________________________________________
Thank you for you interest in DeSmuME! If you want to tell us how useful
DeSmuME is in your life, your love (or hate) of certain NDS games, your passion
for NDS homebrew development, or anything else related to DeSmuME or NDS
emulation, then there are various ways for you to contact us!
However, keep in mind that there are a few of rules that you need to follow:
- Do not ask us to provide ROMs, BIOS files, or any other copyrighted stuff.
We don't want to have to deal with any legal issues that could get us in
trouble, or worse, completely shut down.
- When contacting us, please use the appropriate means to do it. For example,
if you simply want to tell us how much you love or hate us, then use the
comments on the official webpage. Another example: If you want to post on the
forum, be sure to keep the topic focused on DeSmuME; questions that ask for
things like us providing you the latest Pokemon cheats are not DeSmuME
related, and we will instead refer you to a Pokemon cheaters forum. Finally,
our developer chat channel is intended for furthering the development work of
DeSmuME; questions about how to use DeSmuME should not come here, but instead
go to the Support forum. In short, use the appropriate contact method. That's
why the different methods exist!
* Official Website: https://desmume.org
Our official website has the latest news on DeSmuME releases, and also has a
lot of other useful information about DeSmuME. You can comment on different
posts telling us how you feel about DeSmuME. Is DeSmuME the best thing in your
life? Is it making you cry? Or is it a bunch of blah? Let us know here!
* Public Forum: https://forums.desmume.org
If you have a question about DeSmuME, then this is the place to ask it. But
before you ask it, be aware that your question may have already been answered
before, so try the following things first:
- Read the manual and the FAQ. A lot of questions people have are usually
already answered in our documentation.
- Do a forum search about your question.
If you still need to ask a question, choose Help > Submit a Support Request in
the DeSmuME application. Follow the onscreen instructions on the Support
Request Form.
* Live Developer Chat Channel: irc://irc.libera.chat:6697/desmume
We have a live developer chatline on Libera IRC at #desmume. This channel
is meant for discussing the development of DeSmuME, and shows the real work
that goes on behind the scenes. If you are interested in doing any sort of
software programming, software testing, documentation, or graphics work, then
please join our chat channel! We would love for you to join us!
* Bug Reports:
If you believe that you have found a bug, you may submit a bug report by
choosing Help > Submit a Bug Report in the DeSmuME application. Follow the
onscreen instructions on the Bug Report Form.
When you click Go To Bug Report Webpage, you will be taken to our bug tracker
on SourceForge. Do note that you will need a SourceForge account in order to
submit a bug report.
Bug submissions are very welcome and encouraged. However, when you submit a bug
to us, you MUST provide the following information, or else your bug submission
may be rejected:
- DeSmuME app version
- Your operating system and OS version
- Your Mac model identifier
- The name of the running ROM when the bug was observed (or "None", if no ROM
was running)
- The serial code of the running ROM when the bug was observed (or "None", if
no ROM was running)
- A description of the exact behavior you observed
- A description of the behavior you expected
All of this information will be prepared for you if you use the Bug Report Form
from Help > Submit a Bug Report.
When you write your description, make sure that they are as detailed as
possible. The better your descriptions are, the faster we can test and fix
bugs. For example, if you observed a bug in the game "Golden Sun: Dark Dawn,"
then the bug report could look something like this:
App Version: 0.9.13
Operating System: macOS v12.4 (21F79)
Mac Model Identifier: MacBookPro15,1
ROM Name: GOLDENSUN_DD
ROM Serial: NTR-BO5E-USA
Observed Behavior: I tried to load a save state using the
File > Load State > Slot 3 menu option, but the game froze. If I reset, I
can get the game working again.
Expected Behavior: The game should continue running from the point where I
made the save state.
We will try to get your bug tested as soon as possible, but any fixes may take
longer, depending on the complexity of the bug. Also, some bugs may require us
to ask you for certain files, such as your ROM saves, save states, or console
logs. For the above example, we would probably ask you for your save states to
help us track down the bug.
7) License ____________________________________________________________________
This file is free software: you can redistribute it and/or modify it under the
terms of the GNU General Public License as published by the Free Software
Foundation, either version 2 of the License, or (at your option) any later
version.
This file is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with
this software. If not, see <https://www.gnu.org/licenses/>.
* See the GNU General Public License details in COPYING.

File diff suppressed because it is too large Load Diff

View File

@ -1,74 +0,0 @@
DSM is ascii plain text. It is derived from the FCEUX FM2 format.
It consists of several key-value pairs followed by an inputlog section.
The inputlog section can be identified by its starting with a | (pipe).
The inputlog section terminates at eof.
Newlines may be \r\n or \n
Key-value pairs consist of a key identifier, followed by a space separator, followed by the value text.
Value text is always terminated by a newline, which the value text will not include.
The value text is parsed differently depending on the type of the key.
The key-value pairs may be in any order, except that the first key must be version.
Integer keys (also used for booleans, with a 1 or 0) will have a value that is a simple integer not to exceed 32bits
- version (required) - the version of the movie file format; for now it is always 3
- emuVersion (required) - the version of the emulator used to produce the movie
- rerecordCount (optional) - the rerecord count
- romChecksum (optional) - the CRC32 of the rom used to make the movie. should match values specified on advanscene.com
- romSerial (optional) - a concatenation of other uniquely identifying information about the rom (name,gamecode,makercode)
- useExtBios (optional) - were bios files was used? defaults to false.
- swiFromBios (optional) - were swi emulated by ExtBios? (alternative is internal HLE bios). defaults to false.
The rom identification information may be used at a later point to warn about mismatches between movies and roms, but is not right now.
String keys have values that consist of the remainder of the key-value pair line. As a consequence, string values cannot contain newlines.
- romFilename (required) - the name of the file used to record the movie
- comment (optional) - simply a memo.
by convention, the first token in the comment value is the subject of the comment.
by convention, subsequent comments with the same subject will have their ordering preserved and may be used to approximate multiline comments.
by convention, the author of the movie should be stored in comment(s) with a subject of: author
Hex string keys (used for binary blobs) will have a value that is like 0x0123456789ABCDEF...
- romChecksum (required) - this is currently unused.
GUID keys have a value which is in the standard guid format: 452DE2C3-EF43-2FA9-77AC-0677FC51543B
- guid (required) a unique identifier for a movie, generated when the movie is created, which is used when loading a savestate to make sure it belongs to the current movie.
The inputlog section consists of lines beginning and ending with a | (pipe).
The fields are as follows, except as noted in note C.
|c|.............XXX YYY Z|
'R','L','D','U','T','S','B','A','Y','X','W','E','G'
field c is a variable length decimal integer which is a bitfield corresponding to miscellaneous input states which are valid at the start of the frame.
Therefore, no miscellaneous commands is represented by a value of 0.
Here are the currently defined bit values:
0x01 - Microphone Noise (hardcoded noise sample; to be held through duration of frame)
0x02 - Reset
0x04 - Lid
the format of the main section is as follows:
the field begins with 13 characters which constitute a bitfield.
any character other than ' ' or '.' means that the button was pressed.
by convention, the following mnemonics will be used in a column to remind us of which button corresponds to which column:
RLDUTSBAYXWEG (Right,Left,Down,Up,sTart,Select,B,A,Y,X,lshoulder,rshoulder,debuG)
This ordering is based on FCEUX to a certain extent, and arbitrary after that.
W and E were chosen for shoulders to suggest West and East for Left and Right.
While the emulator supports a 'lid' button, and to some extent a 'blow' button, these are not supported in the movies.
XXX: %03d, the x position of the stylus (0,0 topleft, 255,191 bottomright)
YYY: %03d, the y position of the stylus
Z: %1d, 1 if the stylus is pressed pressed; 0 if not
Additional fields after this main section may be added later without breaking the file format.
* Notes *
A. There is no key-value pair that indicates the length of the movie. This must be read by scanning the inputlog and counting the number of lines.
B. All movies start from power-on.
C. The emulator uses these framerate constants
arm7_cycles_per_frame = 560190
frames_per_second = 59.8261

View File

@ -1,39 +0,0 @@
The desmume save file format is merely a raw save file with a FOOTER.
This was chosen in order to maximize compatibility with other emulators,
which tend load the savefile as-is and let the game read out of whatever range
it is expecting. To assist with this, before writing the save file, desmume
will pad the raw save file out to the next highest known length. Note that this
may sometimes be incorrect if the savefile hasnt been written through to the end
during initialization. This could cause other emulators to fail to recognize the
save file.
Additionally, the footer makes it easier to analyze save files, because the
game's data will be at the correct addresses starting at offset 0x0000.
The footer format can be identified by locating the 16Byte ascii string
"|-DESMUME SAVE-|"
at the end of the file. This corresponds with the following save structure:
struct Footer {
u32 actually_written_size;
u32 padded_size;
u32 save_type; //(not currently used)
u32 address_size; //address bus size
u32 save_size; //size parameter of the save type (not currently used)
u32 version_number; //should be 0
char cookie[16];
};
note that padded_size should be where you see the end of the raw save data
and the beginning of desmume-specific information, including some junk before
the actual footer.
actually_written_size is the highest address (plus one) written to by the game.
The new desmume savefile system tries to make as few decisions as possible,
which is the reason for the behavior of actually_written_size and the disuse
of save_type and save_size. If few decisions are made, then few mistakes can
be made. That is the idea, anyway. We'll make decisions later if we need to.
save_type and save_size are reserved in case we do.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -1,8 +0,0 @@
Tips:
* Set hotkeys for "Mic Prev Sample" and "Mic Next Sample" in the "Main" section of hotkey configuration (suggest [ and ])
* This will rotate through all the provided desmume_N.wav. You can add your own in the series, just pick the next number.
* Keep the microphone hotkey held down for as long as you want the noise to play! Just tapping it will make a very short sound indeed.
desmume_0.wav was formerly "PERFECT BLOW FOR DS EMULATORS.wav"
desmume_1.wav was formerly "noise_loud.wav"
desmume_4.wav came to us as "pcm0822m.wav"; these are alleged to work well for Giant Bowser fights in Bowser's Inside Story.

Binary file not shown.

View File

@ -1,4 +0,0 @@
root = true
[*]
indent_style = tab

View File

@ -1,392 +0,0 @@
/*
Copyright (C) 2008-2021 DeSmuME team
This file is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
This file is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with the this software. If not, see <http://www.gnu.org/licenses/>.
*/
#include <string.h>
#include "types.h"
#include "Database.h"
#include "retro_miscellaneous.h"
//------------------------------------------------------------
//large databases are first. scroll down to ENDLARGE to find the code
struct MAKER
{
u16 code;
const char* name;
};
static const char regions_index[] = "JPFSEODIRKHXVWUC";
static const char *regions[] = {
"JPN", // J
"EUR", // P
"FRA", // F
"ESP", // S
"USA", // E
"INT", // O
"NOE", // D
"ITA", // I
"RUS", // R
"KOR", // K
"HOL", // H
"EUU", // X
"EUU", // V
"EUU", // W
"AUS", // U
"CHN", // C
};
static MAKER makerCodes[] = {
{ 0x3130, "Nintendo" },
{ 0x3230, "Rocket Games, Ajinomoto" },
{ 0x3330, "Imagineer-Zoom" },
{ 0x3430, "Gray Matter?" },
{ 0x3530, "Zamuse" },
{ 0x3630, "Falcom" },
{ 0x3730, "Enix?" },
{ 0x3830, "Capcom" },
{ 0x3930, "Hot B Co." },
{ 0x4130, "Jaleco" },
{ 0x4230, "Coconuts Japan" },
{ 0x4330, "Coconuts Japan/G.X.Media" },
{ 0x4430, "Micronet?" },
{ 0x4530, "Technos" },
{ 0x4630, "Mebio Software" },
{ 0x4730, "Shouei System" },
{ 0x4830, "Starfish" },
{ 0x4A30, "Mitsui Fudosan/Dentsu" },
{ 0x4C30, "Warashi Inc." },
{ 0x4E30, "Nowpro" },
{ 0x5030, "Game Village" },
{ 0x3031, "?????????????" },
{ 0x3231, "Infocom" },
{ 0x3331, "Electronic Arts Japan" },
{ 0x3531, "Cobra Team" },
{ 0x3631, "Human/Field" },
{ 0x3731, "KOEI" },
{ 0x3831, "Hudson Soft" },
{ 0x3931, "S.C.P." },
{ 0x4131, "Yanoman" },
{ 0x4331, "Tecmo Products" },
{ 0x4431, "Japan Glary Business" },
{ 0x4531, "Forum/OpenSystem" },
{ 0x4631, "Virgin Games" },
{ 0x4731, "SMDE" },
{ 0x4A31, "Daikokudenki" },
{ 0x5031, "Creatures Inc." },
{ 0x5131, "TDK Deep Impresion" },
{ 0x3032, "Destination Software, KSS" },
{ 0x3132, "Sunsoft/Tokai Engineering??" },
{ 0x3232, "POW, VR 1 Japan??" },
{ 0x3332, "Micro World" },
{ 0x3532, "San-X" },
{ 0x3632, "Enix" },
{ 0x3732, "Loriciel/Electro Brain" },
{ 0x3832, "Kemco Japan" },
{ 0x3932, "Seta" },
{ 0x4132, "Culture Brain" },
{ 0x4332, "Palsoft" },
{ 0x4432, "Visit Co.,Ltd." },
{ 0x4532, "Intec" },
{ 0x4632, "System Sacom" },
{ 0x4732, "Poppo" },
{ 0x4832, "Ubisoft Japan" },
{ 0x4A32, "Media Works" },
{ 0x4B32, "NEC InterChannel" },
{ 0x4C32, "Tam" },
{ 0x4D32, "Jordan" },
{ 0x4E32, "Smilesoft ???, Rocket ???" },
{ 0x5132, "Mediakite" },
{ 0x3033, "Viacom" },
{ 0x3133, "Carrozzeria" },
{ 0x3233, "Dynamic" },
{ 0x3433, "Magifact" },
{ 0x3533, "Hect" },
{ 0x3633, "Codemasters" },
{ 0x3733, "Taito/GAGA Communications" },
{ 0x3833, "Laguna" },
{ 0x3933, "Telstar Fun & Games, Event/Taito" },
{ 0x4233, "Arcade Zone Ltd" },
{ 0x4333, "Entertainment International/Empire Software?" },
{ 0x4433, "Loriciel" },
{ 0x4533, "Gremlin Graphics" },
{ 0x4633, "K.Amusement Leasing Co." },
{ 0x3034, "Seika Corp." },
{ 0x3134, "Ubi Soft Entertainment" },
{ 0x3234, "Sunsoft US?" },
{ 0x3434, "Life Fitness" },
{ 0x3634, "System 3" },
{ 0x3734, "Spectrum Holobyte" },
{ 0x3934, "IREM" },
{ 0x4234, "Raya Systems" },
{ 0x4334, "Renovation Products" },
{ 0x4434, "Malibu Games" },
{ 0x4634, "Eidos (was U.S. Gold <=1995)" },
{ 0x4734, "Playmates Interactive?" },
{ 0x4A34, "Fox Interactive" },
{ 0x4B34, "Time Warner Interactive" },
{ 0x5134, "Disney Interactive" },
{ 0x5334, "Black Pearl" },
{ 0x5534, "Advanced Productions" },
{ 0x5834, "GT Interactive" },
{ 0x5934, "RARE?" },
{ 0x5A34, "Crave Entertainment" },
{ 0x3035, "Absolute Entertainment" },
{ 0x3135, "Acclaim" },
{ 0x3235, "Activision" },
{ 0x3335, "American Sammy" },
{ 0x3435, "Take 2 Interactive (before it was GameTek)" },
{ 0x3535, "Hi Tech" },
{ 0x3635, "LJN LTD." },
{ 0x3835, "Mattel" },
{ 0x4135, "Mindscape, Red Orb Entertainment?" },
{ 0x4235, "Romstar" },
{ 0x4335, "Taxan" },
{ 0x4435, "Midway (before it was Tradewest)" },
{ 0x4635, "American Softworks" },
{ 0x4735, "Majesco Sales Inc" },
{ 0x4835, "3DO" },
{ 0x4B35, "Hasbro" },
{ 0x4C35, "NewKidCo" },
{ 0x4D35, "Telegames" },
{ 0x4E35, "Metro3D" },
{ 0x5035, "Vatical Entertainment" },
{ 0x5135, "LEGO Media" },
{ 0x5335, "Xicat Interactive" },
{ 0x5435, "Cryo Interactive" },
{ 0x5735, "Red Storm Entertainment" },
{ 0x5835, "Microids" },
{ 0x5A35, "Conspiracy/Swing" },
{ 0x3036, "Titus" },
{ 0x3136, "Virgin Interactive" },
{ 0x3236, "Maxis" },
{ 0x3436, "LucasArts Entertainment" },
{ 0x3736, "Ocean" },
{ 0x3936, "Electronic Arts" },
{ 0x4236, "Laser Beam" },
{ 0x4536, "Elite Systems" },
{ 0x4636, "Electro Brain" },
{ 0x4736, "The Learning Company" },
{ 0x4836, "BBC" },
{ 0x4A36, "Software 2000" },
{ 0x4C36, "BAM! Entertainment" },
{ 0x4D36, "Studio 3" },
{ 0x5136, "Classified Games" },
{ 0x5336, "TDK Mediactive" },
{ 0x5536, "DreamCatcher" },
{ 0x5636, "JoWood Produtions" },
{ 0x5736, "SEGA" },
{ 0x5836, "Wannado Edition" },
{ 0x5936, "LSP" },
{ 0x5A36, "ITE Media" },
{ 0x3037, "Infogrames" },
{ 0x3137, "Interplay" },
{ 0x3237, "JVC" },
{ 0x3337, "Parker Brothers" },
{ 0x3537, "Sales Curve" },
{ 0x3837, "THQ" },
{ 0x3937, "Accolade" },
{ 0x4137, "Triffix Entertainment" },
{ 0x4337, "Microprose Software" },
{ 0x4437, "Universal Interactive, Sierra, Simon & Schuster?" },
{ 0x4637, "Kemco" },
{ 0x4737, "Rage Software" },
{ 0x4837, "Encore" },
{ 0x4A37, "Zoo" },
{ 0x4B37, "BVM" },
{ 0x4C37, "Simon & Schuster Interactive" },
{ 0x4D37, "Asmik Ace Entertainment Inc./AIA" },
{ 0x4E37, "Empire Interactive?" },
{ 0x5137, "Jester Interactive" },
{ 0x5437, "Scholastic" },
{ 0x5537, "Ignition Entertainment" },
{ 0x5737, "Stadlbauer" },
{ 0x3038, "Misawa" },
{ 0x3138, "Teichiku" },
{ 0x3238, "Namco Ltd." },
{ 0x3338, "LOZC" },
{ 0x3438, "KOEI" },
{ 0x3638, "Tokuma Shoten Intermedia" },
{ 0x3738, "Tsukuda Original" },
{ 0x3838, "DATAM-Polystar" },
{ 0x4238, "Bulletproof Software" },
{ 0x4338, "Vic Tokai Inc." },
{ 0x4538, "Character Soft" },
{ 0x4638, "I'Max" },
{ 0x4738, "Saurus" },
{ 0x4A38, "General Entertainment" },
{ 0x4E38, "Success" },
{ 0x5038, "SEGA Japan" },
{ 0x3039, "Takara Amusement" },
{ 0x3139, "Chun Soft" },
{ 0x3239, "Video System, McO'River???" },
{ 0x3339, "BEC" },
{ 0x3539, "Varie" },
{ 0x3639, "Yonezawa/S'pal" },
{ 0x3739, "Kaneko" },
{ 0x3939, "Victor Interactive Software, Pack in Video" },
{ 0x4139, "Nichibutsu/Nihon Bussan" },
{ 0x4239, "Tecmo" },
{ 0x4339, "Imagineer" },
{ 0x4639, "Nova" },
{ 0x4739, "Den'Z" },
{ 0x4839, "Bottom Up" },
{ 0x4A39, "TGL" },
{ 0x4C39, "Hasbro Japan?" },
{ 0x4E39, "Marvelous Entertainment" },
{ 0x5039, "Keynet Inc." },
{ 0x5139, "Hands-On Entertainment" },
{ 0x3041, "Telenet" },
{ 0x3141, "Hori" },
{ 0x3441, "Konami" },
{ 0x3541, "K.Amusement Leasing Co." },
{ 0x3641, "Kawada" },
{ 0x3741, "Takara" },
{ 0x3941, "Technos Japan Corp." },
{ 0x4141, "JVC, Victor Musical Indutries" },
{ 0x4341, "Toei Animation" },
{ 0x4441, "Toho" },
{ 0x4641, "Namco" },
{ 0x4741, "Media Rings Corporation" },
{ 0x4841, "J-Wing" },
{ 0x4A41, "Pioneer LDC" },
{ 0x4B41, "KID" },
{ 0x4C41, "Mediafactory" },
{ 0x5041, "Infogrames Hudson" },
{ 0x5141, "Kiratto. Ludic Inc" },
{ 0x3042, "Acclaim Japan" },
{ 0x3142, "ASCII (was Nexoft?)" },
{ 0x3242, "Bandai" },
{ 0x3442, "Enix" },
{ 0x3642, "HAL Laboratory" },
{ 0x3742, "SNK" },
{ 0x3942, "Pony Canyon" },
{ 0x4142, "Culture Brain" },
{ 0x4242, "Sunsoft" },
{ 0x4342, "Toshiba EMI" },
{ 0x4442, "Sony Imagesoft" },
{ 0x4642, "Sammy" },
{ 0x4742, "Magical" },
{ 0x4842, "Visco" },
{ 0x4A42, "Compile " },
{ 0x4C42, "MTO Inc." },
{ 0x4E42, "Sunrise Interactive" },
{ 0x5042, "Global A Entertainment" },
{ 0x5142, "Fuuki" },
{ 0x3043, "Taito" },
{ 0x3243, "Kemco" },
{ 0x3343, "Square" },
{ 0x3443, "Tokuma Shoten" },
{ 0x3543, "Data East" },
{ 0x3643, "Tonkin House (was Tokyo Shoseki)" },
{ 0x3843, "Koei" },
{ 0x4143, "Konami/Ultra/Palcom" },
{ 0x4243, "NTVIC/VAP" },
{ 0x4343, "Use Co.,Ltd." },
{ 0x4443, "Meldac" },
{ 0x4543, "Pony Canyon" },
{ 0x4643, "Angel, Sotsu Agency/Sunrise" },
{ 0x4A43, "Boss" },
{ 0x4743, "Yumedia/Aroma Co., Ltd" },
{ 0x4B43, "Axela/Crea-Tech?" },
{ 0x4C43, "Sekaibunka-Sha, Sumire kobo?, Marigul Management Inc.?" },
{ 0x4D43, "Konami Computer Entertainment Osaka" },
{ 0x5043, "Enterbrain" },
{ 0x3044, "Taito/Disco" },
{ 0x3144, "Sofel" },
{ 0x3244, "Quest, Bothtec" },
{ 0x3344, "Sigma, ?????" },
{ 0x3444, "Ask Kodansha" },
{ 0x3644, "Naxat" },
{ 0x3744, "Copya System" },
{ 0x3844, "Capcom Co., Ltd." },
{ 0x3944, "Banpresto" },
{ 0x4144, "TOMY" },
{ 0x4244, "LJN Japan" },
{ 0x4444, "NCS" },
{ 0x4544, "Human Entertainment" },
{ 0x4644, "Altron" },
{ 0x4744, "Jaleco???" },
{ 0x4844, "Gaps Inc." },
{ 0x4C44, "????" },
{ 0x4E44, "Elf" },
{ 0x3045, "Jaleco" },
{ 0x3145, "????" },
{ 0x3245, "Yutaka" },
{ 0x3345, "Varie" },
{ 0x3445, "T&ESoft" },
{ 0x3545, "Epoch" },
{ 0x3745, "Athena" },
{ 0x3845, "Asmik" },
{ 0x3945, "Natsume" },
{ 0x4145, "King Records" },
{ 0x4245, "Atlus" },
{ 0x4345, "Epic/Sony Records" },
{ 0x4545, "IGS" },
{ 0x4745, "Chatnoir" },
{ 0x4845, "Right Stuff" },
{ 0x4C45, "Spike" },
{ 0x4D45, "Konami Computer Entertainment Tokyo" },
{ 0x4E45, "Alphadream Corporation" },
{ 0x3046, "A Wave" },
{ 0x3146, "Motown Software" },
{ 0x3246, "Left Field Entertainment" },
{ 0x3346, "Extreme Ent. Grp." },
{ 0x3446, "TecMagik" },
{ 0x3946, "Cybersoft" },
{ 0x4246, "Psygnosis" },
{ 0x4546, "Davidson/Western Tech." },
{ 0x3147, "PCCW Japan" },
{ 0x3447, "KiKi Co Ltd" },
{ 0x3547, "Open Sesame Inc???" },
{ 0x3647, "Sims" },
{ 0x3747, "Broccoli" },
{ 0x3847, "Avex" },
{ 0x3947, "D3 Publisher" },
{ 0x4247, "Konami Computer Entertainment Japan" },
{ 0x4447, "Square-Enix" },
{ 0x4849, "Yojigen" },
};
//------------------------------------------------------------
//ENDLARGE
//------------------------------------------------------------
namespace Database
{
const char* RegionXXXForCode(char code, bool unknownAsString)
{
size_t regions_num = ARRAY_SIZE(regions);
const char* found = strchr(regions_index,code);
if(found && found-regions_index < strlen(regions_index)) return regions[found-regions_index];
else return unknownAsString ? "???" : NULL;
}
const char *MakerNameForMakerCode(u16 id, bool unknownAsString)
{
//too bad these aren't sorted
for (size_t i = 0; i < ARRAY_SIZE(makerCodes); i++)
{
if (makerCodes[i].code == id)
return makerCodes[i].name;
}
return unknownAsString ? "Unknown" : NULL;
}
}

View File

@ -1,10 +0,0 @@
#ifndef DESMUME_DATABASE_H_
#define DESMUME_DATABASE_H_
namespace Database
{
const char* RegionXXXForCode(char code, bool unknownAsString);
const char* MakerNameForMakerCode(u16 id, bool unknownAsString);
};
#endif

View File

@ -1,549 +0,0 @@
/*
Copyright 2006 yopyop
Copyright 2007 shash
Copyright 2007-2024 DeSmuME team
This file is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
This file is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with the this software. If not, see <http://www.gnu.org/licenses/>.
*/
#include "FIFO.h"
#include <string.h>
#include "armcpu.h"
#include "debug.h"
#include "mem.h"
#include "MMU.h"
#include "registers.h"
#include "NDSSystem.h"
#include "gfx3d.h"
#if defined(ENABLE_AVX512_1)
#define USEVECTORSIZE_512
#define VECTORSIZE 64
#elif defined(ENABLE_AVX2)
#define USEVECTORSIZE_256
#define VECTORSIZE 32
#elif defined(ENABLE_SSE2)
#define USEVECTORSIZE_128
#define VECTORSIZE 16
#elif defined(ENABLE_NEON_A64)
#define USEVECTORSIZE_128
#define VECTORSIZE 16
#elif defined(ENABLE_ALTIVEC)
#define USEVECTORSIZE_128
#define VECTORSIZE 16
#endif
#if defined(USEVECTORSIZE_512) || defined(USEVECTORSIZE_256) || defined(USEVECTORSIZE_128)
#define USEMANUALVECTORIZATION
#endif
// ========================================================= IPC FIFO
IPC_FIFO ipc_fifo[2];
void IPC_FIFOinit(u8 proc)
{
memset(&ipc_fifo[proc], 0, sizeof(IPC_FIFO));
T1WriteWord(MMU.MMU_MEM[proc][0x40], 0x184, 0x00000101);
}
void IPC_FIFOsend(u8 proc, u32 val)
{
u16 cnt_l = T1ReadWord(MMU.MMU_MEM[proc][0x40], 0x184);
if (!(cnt_l & IPCFIFOCNT_FIFOENABLE)) return; // FIFO disabled
u8 proc_remote = proc ^ 1;
if (ipc_fifo[proc].size > 15)
{
cnt_l |= IPCFIFOCNT_FIFOERROR;
T1WriteWord(MMU.MMU_MEM[proc][0x40], 0x184, cnt_l);
return;
}
u16 cnt_r = T1ReadWord(MMU.MMU_MEM[proc_remote][0x40], 0x184);
//LOG("IPC%s send FIFO 0x%08X size %03i (l 0x%X, tail %02i) (r 0x%X, tail %02i)\n",
// proc?"7":"9", val, ipc_fifo[proc].size, cnt_l, ipc_fifo[proc].tail, cnt_r, ipc_fifo[proc^1].tail);
cnt_l &= 0xBFFC; // clear send empty bit & full
cnt_r &= 0xBCFF; // set recv empty bit & full
ipc_fifo[proc].buf[ipc_fifo[proc].tail] = val;
ipc_fifo[proc].tail++;
ipc_fifo[proc].size++;
if (ipc_fifo[proc].tail > 15) ipc_fifo[proc].tail = 0;
if (ipc_fifo[proc].size > 15)
{
cnt_l |= IPCFIFOCNT_SENDFULL; // set send full bit
cnt_r |= IPCFIFOCNT_RECVFULL; // set recv full bit
}
T1WriteWord(MMU.MMU_MEM[proc][0x40], 0x184, cnt_l);
T1WriteWord(MMU.MMU_MEM[proc_remote][0x40], 0x184, cnt_r);
if(cnt_r&IPCFIFOCNT_RECVIRQEN)
NDS_makeIrq(proc_remote, IRQ_BIT_IPCFIFO_RECVNONEMPTY);
NDS_Reschedule();
}
u32 IPC_FIFOrecv(u8 proc)
{
u16 cnt_l = T1ReadWord(MMU.MMU_MEM[proc][0x40], 0x184);
if (!(cnt_l & IPCFIFOCNT_FIFOENABLE)) return (0); // FIFO disabled
u8 proc_remote = proc ^ 1;
u32 val = 0;
if ( ipc_fifo[proc_remote].size == 0 ) // remote FIFO error
{
cnt_l |= IPCFIFOCNT_FIFOERROR;
T1WriteWord(MMU.MMU_MEM[proc][0x40], 0x184, cnt_l);
return (0);
}
u16 cnt_r = T1ReadWord(MMU.MMU_MEM[proc_remote][0x40], 0x184);
cnt_l &= 0xBCFF; // clear send full bit & empty
cnt_r &= 0xBFFC; // set recv full bit & empty
val = ipc_fifo[proc_remote].buf[ipc_fifo[proc_remote].head];
ipc_fifo[proc_remote].head++;
ipc_fifo[proc_remote].size--;
if (ipc_fifo[proc_remote].head > 15) ipc_fifo[proc_remote].head = 0;
//LOG("IPC%s recv FIFO 0x%08X size %03i (l 0x%X, tail %02i) (r 0x%X, tail %02i)\n",
// proc?"7":"9", val, ipc_fifo[proc].size, cnt_l, ipc_fifo[proc].tail, cnt_r, ipc_fifo[proc^1].tail);
if ( ipc_fifo[proc_remote].size == 0 ) // FIFO empty
{
cnt_l |= IPCFIFOCNT_RECVEMPTY;
cnt_r |= IPCFIFOCNT_SENDEMPTY;
if(cnt_r&IPCFIFOCNT_SENDIRQEN)
NDS_makeIrq(proc_remote, IRQ_BIT_IPCFIFO_SENDEMPTY);
}
T1WriteWord(MMU.MMU_MEM[proc][0x40], 0x184, cnt_l);
T1WriteWord(MMU.MMU_MEM[proc_remote][0x40], 0x184, cnt_r);
NDS_Reschedule();
return (val);
}
void IPC_FIFOcnt(u8 proc, u16 val)
{
u16 cnt_l = T1ReadWord(MMU.MMU_MEM[proc][0x40], 0x184);
u16 cnt_r = T1ReadWord(MMU.MMU_MEM[proc^1][0x40], 0x184);
if (val & IPCFIFOCNT_FIFOERROR)
{
//at least SPP uses this, maybe every retail game
cnt_l &= ~IPCFIFOCNT_FIFOERROR;
}
if (val & IPCFIFOCNT_SENDCLEAR)
{
ipc_fifo[proc].head = 0; ipc_fifo[proc].tail = 0; ipc_fifo[proc].size = 0;
cnt_l |= IPCFIFOCNT_SENDEMPTY;
cnt_r |= IPCFIFOCNT_RECVEMPTY;
cnt_l &= ~IPCFIFOCNT_SENDFULL;
cnt_r &= ~IPCFIFOCNT_RECVFULL;
}
cnt_l &= ~IPCFIFOCNT_WRITEABLE;
cnt_l |= val & IPCFIFOCNT_WRITEABLE;
//IPCFIFOCNT_SENDIRQEN may have been set (and/or the fifo may have been cleared) so we may need to trigger this irq
//(this approach is used by libnds fifo system on occasion in fifoInternalSend, and began happening frequently for value32 with r4326)
if(cnt_l&IPCFIFOCNT_SENDIRQEN) if(cnt_l & IPCFIFOCNT_SENDEMPTY)
NDS_makeIrq(proc, IRQ_BIT_IPCFIFO_SENDEMPTY);
//IPCFIFOCNT_RECVIRQEN may have been set so we may need to trigger this irq
if(cnt_l&IPCFIFOCNT_RECVIRQEN) if(!(cnt_l & IPCFIFOCNT_RECVEMPTY))
NDS_makeIrq(proc, IRQ_BIT_IPCFIFO_RECVNONEMPTY);
T1WriteWord(MMU.MMU_MEM[proc][0x40], 0x184, cnt_l);
T1WriteWord(MMU.MMU_MEM[proc^1][0x40], 0x184, cnt_r);
NDS_Reschedule();
}
// ========================================================= GFX FIFO
GFX_PIPE gxPIPE;
GFX_FIFO gxFIFO;
void GFX_PIPEclear()
{
gxPIPE.head = 0;
gxPIPE.tail = 0;
gxPIPE.size = 0;
gxFIFO.matrix_stack_op_size = 0;
}
void GFX_FIFOclear()
{
gxFIFO.head = 0;
gxFIFO.tail = 0;
gxFIFO.size = 0;
gxFIFO.matrix_stack_op_size = 0;
}
static void GXF_FIFO_handleEvents()
{
bool low = gxFIFO.size <= 127;
bool lowchange = MMU_new.gxstat.fifo_low ^ low;
MMU_new.gxstat.fifo_low = low;
if(low) triggerDma(EDMAMode_GXFifo);
bool empty = gxFIFO.size == 0;
bool emptychange = MMU_new.gxstat.fifo_empty ^ empty;
MMU_new.gxstat.fifo_empty = empty;
MMU_new.gxstat.sb = gxFIFO.matrix_stack_op_size != 0;
if(emptychange||lowchange) NDS_Reschedule();
}
static bool IsMatrixStackCommand(u8 cmd)
{
return cmd == 0x11 || cmd == 0x12;
}
void GFX_FIFOsend(u8 cmd, u32 param)
{
//INFO("gxFIFO: send 0x%02X = 0x%08X (size %03i/0x%02X) gxstat 0x%08X\n", cmd, param, gxFIFO.size, gxFIFO.size, gxstat);
//printf("fifo recv: %02X: %08X upto:%d\n",cmd,param,gxFIFO.size+1);
//TODO - WOAH ! NOT HANDLING A TOO-BIG FIFO RIGHT NOW!
//if (gxFIFO.size > 255)
//{
// GXF_FIFO_handleEvents();
// //NEED TO HANDLE THIS!!!!!!!!!!!!!!!!!!!!!!!!!!
// //gxstat |= 0x08000000; // busy
// NDS_RescheduleGXFIFO(1);
// //INFO("ERROR: gxFIFO is full (cmd 0x%02X = 0x%08X) (prev cmd 0x%02X = 0x%08X)\n", cmd, param, gxFIFO.cmd[255], gxFIFO.param[255]);
// return;
//}
gxFIFO.cmd[gxFIFO.tail] = cmd;
gxFIFO.param[gxFIFO.tail] = param;
gxFIFO.tail++;
gxFIFO.size++;
if (gxFIFO.tail > HACK_GXIFO_SIZE-1) gxFIFO.tail = 0;
//if a matrix op is entering the pipeline, do accounting for it
//(this is tested by wild west, which will jam a few ops in the fifo and then wait for the matrix stack to be
//un-busy so it can read back the current matrix stack position).
//it is definitely only pushes and pops which set this flag.
//seems like it would be less work in the HW to make a counter than do cmps on all the command bytes, so maybe we're even doing it right.
if(IsMatrixStackCommand(cmd))
gxFIFO.matrix_stack_op_size++;
//along the same lines:
//american girls julie finds a way will put a bunch of stuff and then a box test into the fifo and then immediately test the busy flag
//so we need to set the busy flag here.
//does it expect the fifo to be running then? well, it's definitely jammed -- making it unjammed at one point did fix this bug.
//it's still not clear whether we're handling the immediate vs fifo commands properly at all :(
//anyway, here we go, similar treatment. consider this a hack.
if(cmd == 0x70) MMU_new.gxstat.tb = 1; //just set the flag--youre insane if you queue more than one of these anyway
if(cmd == 0x71) MMU_new.gxstat.tb = 1;
if(gxFIFO.size>=HACK_GXIFO_SIZE) {
printf("--FIFO FULL-- : %d\n",gxFIFO.size);
}
//gxstat |= 0x08000000; // set busy flag
GXF_FIFO_handleEvents();
NDS_RescheduleGXFIFO(1);
}
// this function used ONLY in gxFIFO
BOOL GFX_PIPErecv(u8 *cmd, u32 *param)
{
//gxstat &= 0xF7FFFFFF; // clear busy flag
if (gxFIFO.size == 0)
{
GXF_FIFO_handleEvents();
return FALSE;
}
*cmd = gxFIFO.cmd[gxFIFO.head];
*param = gxFIFO.param[gxFIFO.head];
//see the associated increment in another function
if(IsMatrixStackCommand(*cmd))
{
gxFIFO.matrix_stack_op_size--;
if(gxFIFO.matrix_stack_op_size>0x10000000)
printf("bad news disaster in matrix_stack_op_size\n");
}
gxFIFO.head++;
gxFIFO.size--;
if (gxFIFO.head > HACK_GXIFO_SIZE-1) gxFIFO.head = 0;
GXF_FIFO_handleEvents();
return (TRUE);
}
void GFX_FIFOcnt(u32 val)
{
////INFO("gxFIFO: write cnt 0x%08X (prev 0x%08X) FIFO size %03i PIPE size %03i\n", val, gxstat, gxFIFO.size, gxPIPE.size);
if (val & (1<<29)) // clear? (only in homebrew?)
{
GFX_PIPEclear();
GFX_FIFOclear();
return;
}
//zeromus says: what happened to clear stack?
//if (val & (1<<15)) // projection stack pointer reset
//{
// gfx3d_ClearStack();
// val &= 0xFFFF5FFF; // clear reset (bit15) & stack level (bit13)
//}
T1WriteLong(MMU.ARM9_REG, 0x600, val);
}
// ========================================================= DISP FIFO
DISP_FIFO disp_fifo;
void DISP_FIFOinit()
{
memset(&disp_fifo, 0, sizeof(DISP_FIFO));
}
template <typename T, size_t ADDROFFSET>
void DISP_FIFOsend(const T val)
{
//INFO("DISP_FIFO send value 0x%08X (head 0x%06X, tail 0x%06X)\n", val, disp_fifo.head, disp_fifo.tail);
const size_t numBytes = sizeof(T);
const size_t baseWriteAddress = disp_fifo.tail * sizeof(u32);
const size_t finalWriteAddress = baseWriteAddress + ADDROFFSET;
switch (numBytes)
{
case 1:
{
#ifndef MSB_FIRST
HostWriteByte((u8 *)disp_fifo.buf, (u32)finalWriteAddress, val);
#else
switch (ADDROFFSET)
{
case 0:
HostWriteByte((u8 *)disp_fifo.buf, (u32)baseWriteAddress + 2, val);
break;
case 1:
HostWriteByte((u8 *)disp_fifo.buf, (u32)baseWriteAddress + 3, val);
break;
case 2:
HostWriteByte((u8 *)disp_fifo.buf, (u32)baseWriteAddress + 0, val);
break;
case 3:
HostWriteByte((u8 *)disp_fifo.buf, (u32)baseWriteAddress + 1, val);
break;
default:
break;
}
#endif
#ifndef MSB_FIRST
if (ADDROFFSET == 3)
#else
if (ADDROFFSET == 1)
#endif
{
disp_fifo.tail++;
}
break;
}
case 2:
{
#ifndef MSB_FIRST
HostWriteWord((u8 *)disp_fifo.buf, (u32)finalWriteAddress, val);
#else
switch (ADDROFFSET)
{
case 0:
HostWriteWord((u8 *)disp_fifo.buf, (u32)baseWriteAddress + 2, val);
break;
case 2:
HostWriteWord((u8 *)disp_fifo.buf, (u32)baseWriteAddress + 0, val);
break;
default:
break;
}
#endif
#ifndef MSB_FIRST
if (ADDROFFSET == 2)
#else
if (ADDROFFSET == 0)
#endif
{
disp_fifo.tail++;
}
break;
}
case 4:
HostWriteTwoWords((u8 *)disp_fifo.buf, (u32)finalWriteAddress, val);
disp_fifo.tail++;
break;
default:
break;
}
if (disp_fifo.tail >= 0x6000)
{
disp_fifo.tail = 0;
}
}
u32 DISP_FIFOrecv_u32()
{
//if (disp_fifo.tail == disp_fifo.head) return (0); // FIFO is empty
u32 val = disp_fifo.buf[disp_fifo.head];
disp_fifo.head++;
if (disp_fifo.head >= 0x6000)
{
disp_fifo.head = 0;
}
return val;
}
static void _DISP_FIFOrecv_LineAdvance()
{
disp_fifo.head += (GPU_FRAMEBUFFER_NATIVE_WIDTH * sizeof(u16)) / sizeof(u32);
if (disp_fifo.head >= 0x6000)
{
disp_fifo.head -= 0x6000;
}
}
void DISP_FIFOrecv_Line16(u16 *__restrict dst)
{
#ifdef USEMANUALVECTORIZATION
if ( (disp_fifo.head + (GPU_FRAMEBUFFER_NATIVE_WIDTH * sizeof(u16)) / sizeof(u32) <= 0x6000) && (disp_fifo.head == (disp_fifo.head & ~(VECTORSIZE - 1))) )
{
buffer_copy_fast<GPU_FRAMEBUFFER_NATIVE_WIDTH * sizeof(u16)>(dst, disp_fifo.buf + disp_fifo.head);
_DISP_FIFOrecv_LineAdvance();
}
else
#endif // USEMANUALVECTORIZATION
{
for (size_t i = 0; i < GPU_FRAMEBUFFER_NATIVE_WIDTH * sizeof(u16) / sizeof(u32); i++)
{
const u32 src = DISP_FIFOrecv_u32();
((u32 *)dst)[i] = src;
}
}
}
template <NDSColorFormat OUTPUTFORMAT>
void DISP_FIFOrecv_LineOpaque(u32 *__restrict dst)
{
#ifdef USEMANUALVECTORIZATION
if ( (disp_fifo.head + (GPU_FRAMEBUFFER_NATIVE_WIDTH * sizeof(u16)) / sizeof(u32) <= 0x6000) && (disp_fifo.head == (disp_fifo.head & ~(VECTORSIZE - 1))) )
{
if (OUTPUTFORMAT == NDSColorFormat_BGR555_Rev)
{
buffer_copy_or_constant_s16_fast<GPU_FRAMEBUFFER_NATIVE_WIDTH * sizeof(u16), false>(dst, disp_fifo.buf + disp_fifo.head, 0x8000);
}
else if (OUTPUTFORMAT == NDSColorFormat_BGR666_Rev)
{
ColorspaceConvertBuffer555xTo6665Opaque<false, false, BESwapDst>((u16 *)(disp_fifo.buf + disp_fifo.head), dst, GPU_FRAMEBUFFER_NATIVE_WIDTH);
}
else if (OUTPUTFORMAT == NDSColorFormat_BGR888_Rev)
{
ColorspaceConvertBuffer555xTo8888Opaque<false, false, BESwapDst>((u16 *)(disp_fifo.buf + disp_fifo.head), dst, GPU_FRAMEBUFFER_NATIVE_WIDTH);
}
_DISP_FIFOrecv_LineAdvance();
}
else
#endif // USEMANUALVECTORIZATION
{
if (OUTPUTFORMAT == NDSColorFormat_BGR555_Rev)
{
for (size_t i = 0; i < GPU_FRAMEBUFFER_NATIVE_WIDTH * sizeof(u16) / sizeof(u32); i++)
{
const u32 src = DISP_FIFOrecv_u32();
dst[i] = src | 0x80008000;
}
}
else
{
for (size_t i = 0; i < GPU_FRAMEBUFFER_NATIVE_WIDTH; i+=2)
{
const u32 src = DISP_FIFOrecv_u32();
if (OUTPUTFORMAT == NDSColorFormat_BGR666_Rev)
{
dst[i+0] = LE_TO_LOCAL_32( ColorspaceConvert555To6665Opaque<false>((src >> 0) & 0x7FFF) );
dst[i+1] = LE_TO_LOCAL_32( ColorspaceConvert555To6665Opaque<false>((src >> 16) & 0x7FFF) );
}
else if (OUTPUTFORMAT == NDSColorFormat_BGR888_Rev)
{
dst[i+0] = LE_TO_LOCAL_32( ColorspaceConvert555To8888Opaque<false>((src >> 0) & 0x7FFF) );
dst[i+1] = LE_TO_LOCAL_32( ColorspaceConvert555To8888Opaque<false>((src >> 16) & 0x7FFF) );
}
}
}
}
}
void DISP_FIFOreset()
{
disp_fifo.head = 0;
disp_fifo.tail = 0;
}
template void DISP_FIFOsend< u8, 0>(const u8 val);
template void DISP_FIFOsend< u8, 1>(const u8 val);
template void DISP_FIFOsend< u8, 2>(const u8 val);
template void DISP_FIFOsend< u8, 3>(const u8 val);
template void DISP_FIFOsend<u16, 0>(const u16 val);
template void DISP_FIFOsend<u16, 2>(const u16 val);
template void DISP_FIFOsend<u32, 0>(const u32 val);
template void DISP_FIFOrecv_LineOpaque<NDSColorFormat_BGR555_Rev>(u32 *__restrict dst);
template void DISP_FIFOrecv_LineOpaque<NDSColorFormat_BGR666_Rev>(u32 *__restrict dst);
template void DISP_FIFOrecv_LineOpaque<NDSColorFormat_BGR888_Rev>(u32 *__restrict dst);

View File

@ -1,98 +0,0 @@
/*
Copyright 2006 yopyop
Copyright 2007 shash
Copyright 2007-2022 DeSmuME team
This file is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
This file is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with the this software. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef FIFO_H
#define FIFO_H
#include "types.h"
#include "./utils/colorspacehandler/colorspacehandler.h"
//=================================================== IPC FIFO
typedef struct
{
u32 buf[16];
u8 head;
u8 tail;
u8 size;
} IPC_FIFO;
extern IPC_FIFO ipc_fifo[2];
extern void IPC_FIFOinit(u8 proc);
extern void IPC_FIFOsend(u8 proc, u32 val);
extern u32 IPC_FIFOrecv(u8 proc);
extern void IPC_FIFOcnt(u8 proc, u16 val);
//=================================================== GFX FIFO
//yeah, its oversize for now. thats a simpler solution
//moon seems to overdrive the fifo with immediate dmas
//i think this might be nintendo code too
#define HACK_GXIFO_SIZE 200000
typedef struct
{
u8 cmd[HACK_GXIFO_SIZE];
u32 param[HACK_GXIFO_SIZE];
u32 head; // start position
u32 tail; // tail
u32 size; // size FIFO buffer
u32 matrix_stack_op_size; //number of matrix stack items in the fifo (stack is busy when this is nonzero)
} GFX_FIFO;
typedef struct
{
u8 cmd[4];
u32 param[4];
u8 head;
u8 tail;
u8 size;
} GFX_PIPE;
extern GFX_PIPE gxPIPE;
extern GFX_FIFO gxFIFO;
void GFX_PIPEclear();
void GFX_FIFOclear();
void GFX_FIFOsend(u8 cmd, u32 param);
BOOL GFX_PIPErecv(u8 *cmd, u32 *param);
void GFX_FIFOcnt(u32 val);
//=================================================== Display memory FIFO
typedef struct
{
CACHE_ALIGN u32 buf[0x6000]; // 256x192 32K color
u32 head; // head
u32 tail; // tail
} DISP_FIFO;
extern DISP_FIFO disp_fifo;
void DISP_FIFOinit();
template<typename T, size_t ADDROFFSET> void DISP_FIFOsend(const T val);
u32 DISP_FIFOrecv_u32();
void DISP_FIFOrecv_Line16(u16 *__restrict dst);
template<NDSColorFormat OUTPUTFORMAT> void DISP_FIFOrecv_LineOpaque(u32 *__restrict dst);
void DISP_FIFOreset();
#endif

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,96 +0,0 @@
/*
Copyright (C) 2021-2023 DeSmuME team
This file is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
This file is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with the this software. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef GPU_OPERATIONS_H
#define GPU_OPERATIONS_H
#include <stdio.h>
#include "types.h"
#include "./utils/colorspacehandler/colorspacehandler.h"
#include "GPU.h"
template <s32 INTEGERSCALEHINT, bool SCALEVERTICAL, bool USELINEINDEX, bool NEEDENDIANSWAP, size_t ELEMENTSIZE>
void CopyLineExpandHinted(const void *__restrict srcBuffer, const size_t srcLineIndex,
void *__restrict dstBuffer, const size_t dstLineIndex, const size_t dstLineWidth, const size_t dstLineCount);
template <s32 INTEGERSCALEHINT, bool SCALEVERTICAL, bool USELINEINDEX, bool NEEDENDIANSWAP, size_t ELEMENTSIZE>
void CopyLineExpandHinted(const GPUEngineLineInfo &lineInfo, const void *__restrict srcBuffer, void *__restrict dstBuffer);
template <s32 INTEGERSCALEHINT, bool USELINEINDEX, bool NEEDENDIANSWAP, size_t ELEMENTSIZE>
void CopyLineReduceHinted(const void *__restrict srcBuffer, const size_t srcLineIndex, const size_t srcLineWidth,
void *__restrict dstBuffer, const size_t dstLineIndex);
template <s32 INTEGERSCALEHINT, bool USELINEINDEX, bool NEEDENDIANSWAP, size_t ELEMENTSIZE>
void CopyLineReduceHinted(const GPUEngineLineInfo &lineInfo, const void *__restrict srcBuffer, void *__restrict dstBuffer);
class ColorOperation
{
public:
ColorOperation() {};
FORCEINLINE u16 blend(const u16 colA, const u16 colB, const u16 blendEVA, const u16 blendEVB) const;
FORCEINLINE u16 blend(const u16 colA, const u16 colB, const TBlendTable *blendTable) const;
template<NDSColorFormat COLORFORMAT> FORCEINLINE Color4u8 blend(const Color4u8 colA, const Color4u8 colB, const u16 blendEVA, const u16 blendEVB) const;
FORCEINLINE u16 blend3D(const Color4u8 colA, const u16 colB) const;
template<NDSColorFormat COLORFORMAT> FORCEINLINE Color4u8 blend3D(const Color4u8 colA, const Color4u8 colB) const;
FORCEINLINE u16 increase(const u16 col, const u16 blendEVY) const;
template<NDSColorFormat COLORFORMAT> FORCEINLINE Color4u8 increase(const Color4u8 col, const u16 blendEVY) const;
FORCEINLINE u16 decrease(const u16 col, const u16 blendEVY) const;
template<NDSColorFormat COLORFORMAT> FORCEINLINE Color4u8 decrease(const Color4u8 col, const u16 blendEVY) const;
};
class PixelOperation
{
private:
template<GPULayerType LAYERTYPE> FORCEINLINE void __selectedEffect(const GPUEngineCompositorInfo &compInfo, const u8 &dstLayerID, const bool enableColorEffect, const u8 spriteAlpha, const OBJMode spriteMode, ColorEffect &selectedEffect, TBlendTable **selectedBlendTable, u8 &blendEVA, u8 &blendEVB) const;
protected:
template<NDSColorFormat OUTPUTFORMAT, bool ISDEBUGRENDER> FORCEINLINE void _copy16(GPUEngineCompositorInfo &compInfo, const u16 srcColor16) const;
template<NDSColorFormat OUTPUTFORMAT, bool ISDEBUGRENDER> FORCEINLINE void _copy32(GPUEngineCompositorInfo &compInfo, const Color4u8 srcColor32) const;
template<NDSColorFormat OUTPUTFORMAT> FORCEINLINE void _brightnessUp16(GPUEngineCompositorInfo &compInfo, const u16 srcColor16) const;
template<NDSColorFormat OUTPUTFORMAT> FORCEINLINE void _brightnessUp32(GPUEngineCompositorInfo &compInfo, const Color4u8 srcColor32) const;
template<NDSColorFormat OUTPUTFORMAT> FORCEINLINE void _brightnessDown16(GPUEngineCompositorInfo &compInfo, const u16 srcColor16) const;
template<NDSColorFormat OUTPUTFORMAT> FORCEINLINE void _brightnessDown32(GPUEngineCompositorInfo &compInfo, const Color4u8 srcColor32) const;
template<NDSColorFormat OUTPUTFORMAT, GPULayerType LAYERTYPE> FORCEINLINE void _unknownEffect16(GPUEngineCompositorInfo &compInfo, const u16 srcColor16, const bool enableColorEffect, const u8 spriteAlpha, const OBJMode spriteMode) const;
template<NDSColorFormat OUTPUTFORMAT, GPULayerType LAYERTYPE> FORCEINLINE void _unknownEffect32(GPUEngineCompositorInfo &compInfo, const Color4u8 srcColor32, const bool enableColorEffect, const u8 spriteAlpha, const OBJMode spriteMode) const;
public:
static CACHE_ALIGN u8 BlendTable555[17][17][32][32];
static CACHE_ALIGN u16 BrightnessUpTable555[17][0x8000];
static CACHE_ALIGN Color4u8 BrightnessUpTable666[17][0x8000];
static CACHE_ALIGN Color4u8 BrightnessUpTable888[17][0x8000];
static CACHE_ALIGN u16 BrightnessDownTable555[17][0x8000];
static CACHE_ALIGN Color4u8 BrightnessDownTable666[17][0x8000];
static CACHE_ALIGN Color4u8 BrightnessDownTable888[17][0x8000];
static void InitLUTs();
PixelOperation() {};
template <GPUCompositorMode COMPOSITORMODE, NDSColorFormat OUTPUTFORMAT, GPULayerType LAYERTYPE> FORCEINLINE void Composite16(GPUEngineCompositorInfo &compInfo, const u16 srcColor16, const bool enableColorEffect, const u8 spriteAlpha, const u8 spriteMode) const;
template <GPUCompositorMode COMPOSITORMODE, NDSColorFormat OUTPUTFORMAT, GPULayerType LAYERTYPE> FORCEINLINE void Composite32(GPUEngineCompositorInfo &compInfo, Color4u8 srcColor32, const bool enableColorEffect, const u8 spriteAlpha, const u8 spriteMode) const;
};
#endif // GPU_OPERATIONS_H

File diff suppressed because it is too large Load Diff

View File

@ -1,122 +0,0 @@
/*
Copyright (C) 2021 DeSmuME team
This file is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
This file is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with the this software. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef GPU_OPERATIONS_AVX2_H
#define GPU_OPERATIONS_AVX2_H
#include "GPU_Operations.h"
#ifndef ENABLE_AVX2
#warning This header requires AVX2 support.
#else
class ColorOperation_AVX2
{
public:
ColorOperation_AVX2() {};
FORCEINLINE v256u16 blend(const v256u16 &colA, const v256u16 &colB, const v256u16 &blendEVA, const v256u16 &blendEVB) const;
template<NDSColorFormat COLORFORMAT, bool USECONSTANTBLENDVALUESHINT> FORCEINLINE v256u32 blend(const v256u32 &colA, const v256u32 &colB, const v256u16 &blendEVA, const v256u16 &blendEVB) const;
FORCEINLINE v256u16 blend3D(const v256u32 &colA_Lo, const v256u32 &colA_Hi, const v256u16 &colB) const;
template<NDSColorFormat COLORFORMAT> FORCEINLINE v256u32 blend3D(const v256u32 &colA, const v256u32 &colB) const;
FORCEINLINE v256u16 increase(const v256u16 &col, const v256u16 &blendEVY) const;
template<NDSColorFormat COLORFORMAT> FORCEINLINE v256u32 increase(const v256u32 &col, const v256u16 &blendEVY) const;
FORCEINLINE v256u16 decrease(const v256u16 &col, const v256u16 &blendEVY) const;
template<NDSColorFormat COLORFORMAT> FORCEINLINE v256u32 decrease(const v256u32 &col, const v256u16 &blendEVY) const;
};
class PixelOperation_AVX2
{
protected:
template<NDSColorFormat OUTPUTFORMAT, bool ISDEBUGRENDER> FORCEINLINE void _copy16(GPUEngineCompositorInfo &compInfo, const v256u8 &srcLayerID, const v256u16 &src1, const v256u16 &src0) const;
template<NDSColorFormat OUTPUTFORMAT, bool ISDEBUGRENDER> FORCEINLINE void _copy32(GPUEngineCompositorInfo &compInfo, const v256u8 &srcLayerID, const v256u32 &src3, const v256u32 &src2, const v256u32 &src1, const v256u32 &src0) const;
template<NDSColorFormat OUTPUTFORMAT, bool ISDEBUGRENDER> FORCEINLINE void _copyMask16(GPUEngineCompositorInfo &compInfo, const v256u8 &passMask8, const v256u8 &srcLayerID, const v256u16 &src1, const v256u16 &src0) const;
template<NDSColorFormat OUTPUTFORMAT, bool ISDEBUGRENDER> FORCEINLINE void _copyMask32(GPUEngineCompositorInfo &compInfo, const v256u8 &passMask8, const v256u8 &srcLayerID, const v256u32 &src3, const v256u32 &src2, const v256u32 &src1, const v256u32 &src0) const;
template<NDSColorFormat OUTPUTFORMAT> FORCEINLINE void _brightnessUp16(GPUEngineCompositorInfo &compInfo, const v256u16 &evy16, const v256u8 &srcLayerID, const v256u16 &src1, const v256u16 &src0) const;
template<NDSColorFormat OUTPUTFORMAT> FORCEINLINE void _brightnessUp32(GPUEngineCompositorInfo &compInfo, const v256u16 &evy16, const v256u8 &srcLayerID, const v256u32 &src3, const v256u32 &src2, const v256u32 &src1, const v256u32 &src0) const;
template<NDSColorFormat OUTPUTFORMAT> FORCEINLINE void _brightnessUpMask16(GPUEngineCompositorInfo &compInfo, const v256u8 &passMask8, const v256u16 &evy16, const v256u8 &srcLayerID, const v256u16 &src1, const v256u16 &src0) const;
template<NDSColorFormat OUTPUTFORMAT> FORCEINLINE void _brightnessUpMask32(GPUEngineCompositorInfo &compInfo, const v256u8 &passMask8, const v256u16 &evy16, const v256u8 &srcLayerID, const v256u32 &src3, const v256u32 &src2, const v256u32 &src1, const v256u32 &src0) const;
template<NDSColorFormat OUTPUTFORMAT> FORCEINLINE void _brightnessDown16(GPUEngineCompositorInfo &compInfo, const v256u16 &evy16, const v256u8 &srcLayerID, const v256u16 &src1, const v256u16 &src0) const;
template<NDSColorFormat OUTPUTFORMAT> FORCEINLINE void _brightnessDown32(GPUEngineCompositorInfo &compInfo, const v256u16 &evy16, const v256u8 &srcLayerID, const v256u32 &src3, const v256u32 &src2, const v256u32 &src1, const v256u32 &src0) const;
template<NDSColorFormat OUTPUTFORMAT> FORCEINLINE void _brightnessDownMask16(GPUEngineCompositorInfo &compInfo, const v256u8 &passMask8, const v256u16 &evy16, const v256u8 &srcLayerID, const v256u16 &src1, const v256u16 &src0) const;
template<NDSColorFormat OUTPUTFORMAT> FORCEINLINE void _brightnessDownMask32(GPUEngineCompositorInfo &compInfo, const v256u8 &passMask8, const v256u16 &evy16, const v256u8 &srcLayerID, const v256u32 &src3, const v256u32 &src2, const v256u32 &src1, const v256u32 &src0) const;
template<NDSColorFormat OUTPUTFORMAT, GPULayerType LAYERTYPE>
FORCEINLINE void _unknownEffectMask16(GPUEngineCompositorInfo &compInfo,
const v256u8 &passMask8,
const v256u16 &evy16,
const v256u8 &srcLayerID,
const v256u16 &src1, const v256u16 &src0,
const v256u8 &srcEffectEnableMask,
const v256u8 &dstBlendEnableMaskLUT,
const v256u8 &enableColorEffectMask,
const v256u8 &spriteAlpha,
const v256u8 &spriteMode) const;
template<NDSColorFormat OUTPUTFORMAT, GPULayerType LAYERTYPE>
FORCEINLINE void _unknownEffectMask32(GPUEngineCompositorInfo &compInfo,
const v256u8 &passMask8,
const v256u16 &evy16,
const v256u8 &srcLayerID,
const v256u32 &src3, const v256u32 &src2, const v256u32 &src1, const v256u32 &src0,
const v256u8 &srcEffectEnableMask,
const v256u8 &dstBlendEnableMaskLUT,
const v256u8 &enableColorEffectMask,
const v256u8 &spriteAlpha,
const v256u8 &spriteMode) const;
public:
PixelOperation_AVX2() {};
template <GPUCompositorMode COMPOSITORMODE, NDSColorFormat OUTPUTFORMAT, GPULayerType LAYERTYPE, bool WILLPERFORMWINDOWTEST>
FORCEINLINE void Composite16(GPUEngineCompositorInfo &compInfo,
const bool didAllPixelsPass,
const v256u8 &passMask8,
const v256u16 &evy16,
const v256u8 &srcLayerID,
const v256u16 &src1, const v256u16 &src0,
const v256u8 &srcEffectEnableMask,
const v256u8 &dstBlendEnableMaskLUT,
const u8 *__restrict enableColorEffectPtr,
const u8 *__restrict sprAlphaPtr,
const u8 *__restrict sprModePtr) const;
template <GPUCompositorMode COMPOSITORMODE, NDSColorFormat OUTPUTFORMAT, GPULayerType LAYERTYPE, bool WILLPERFORMWINDOWTEST>
FORCEINLINE void Composite32(GPUEngineCompositorInfo &compInfo,
const bool didAllPixelsPass,
const v256u8 &passMask8,
const v256u16 &evy16,
const v256u8 &srcLayerID,
const v256u32 &src3, const v256u32 &src2, const v256u32 &src1, const v256u32 &src0,
const v256u8 &srcEffectEnableMask,
const v256u8 &dstBlendEnableMaskLUT,
const u8 *__restrict enableColorEffectPtr,
const u8 *__restrict sprAlphaPtr,
const u8 *__restrict sprModePtr) const;
};
#endif // ENABLE_AVX2
#endif // GPU_OPERATIONS_AVX2_H

File diff suppressed because it is too large Load Diff

View File

@ -1,122 +0,0 @@
/*
Copyright (C) 2025 DeSmuME team
This file is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
This file is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with the this software. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef GPU_OPERATIONS_NEON_H
#define GPU_OPERATIONS_NEON_H
#include "GPU_Operations.h"
#ifndef ENABLE_NEON_A64
#warning This header requires ARM64 NEON support.
#else
class ColorOperation_NEON
{
public:
ColorOperation_NEON() {};
FORCEINLINE v128u16 blend(const v128u16 &colA, const v128u16 &colB, const v128u16 &blendEVA, const v128u16 &blendEVB) const;
template<NDSColorFormat COLORFORMAT, bool USECONSTANTBLENDVALUESHINT> FORCEINLINE v128u32 blend(const v128u32 &colA, const v128u32 &colB, const v128u16 &blendEVA, const v128u16 &blendEVB) const;
FORCEINLINE v128u16 blend3D(const v128u32 &colA_Lo, const v128u32 &colA_Hi, const v128u16 &colB) const;
template<NDSColorFormat COLORFORMAT> FORCEINLINE v128u32 blend3D(const v128u32 &colA, const v128u32 &colB) const;
FORCEINLINE v128u16 increase(const v128u16 &col, const v128u16 &blendEVY) const;
template<NDSColorFormat COLORFORMAT> FORCEINLINE v128u32 increase(const v128u32 &col, const v128u16 &blendEVY) const;
FORCEINLINE v128u16 decrease(const v128u16 &col, const v128u16 &blendEVY) const;
template<NDSColorFormat COLORFORMAT> FORCEINLINE v128u32 decrease(const v128u32 &col, const v128u16 &blendEVY) const;
};
class PixelOperation_NEON
{
protected:
template<NDSColorFormat OUTPUTFORMAT, bool ISDEBUGRENDER> FORCEINLINE void _copy16(GPUEngineCompositorInfo &compInfo, const v128u8 &srcLayerID, const v128u16 &src1, const v128u16 &src0) const;
template<NDSColorFormat OUTPUTFORMAT, bool ISDEBUGRENDER> FORCEINLINE void _copy32(GPUEngineCompositorInfo &compInfo, const v128u8 &srcLayerID, const v128u32 &src3, const v128u32 &src2, const v128u32 &src1, const v128u32 &src0) const;
template<NDSColorFormat OUTPUTFORMAT, bool ISDEBUGRENDER> FORCEINLINE void _copyMask16(GPUEngineCompositorInfo &compInfo, const v128u8 &passMask8, const v128u8 &srcLayerID, const v128u16 &src1, const v128u16 &src0) const;
template<NDSColorFormat OUTPUTFORMAT, bool ISDEBUGRENDER> FORCEINLINE void _copyMask32(GPUEngineCompositorInfo &compInfo, const v128u8 &passMask8, const v128u8 &srcLayerID, const v128u32 &src3, const v128u32 &src2, const v128u32 &src1, const v128u32 &src0) const;
template<NDSColorFormat OUTPUTFORMAT> FORCEINLINE void _brightnessUp16(GPUEngineCompositorInfo &compInfo, const v128u16 &evy16, const v128u8 &srcLayerID, const v128u16 &src1, const v128u16 &src0) const;
template<NDSColorFormat OUTPUTFORMAT> FORCEINLINE void _brightnessUp32(GPUEngineCompositorInfo &compInfo, const v128u16 &evy16, const v128u8 &srcLayerID, const v128u32 &src3, const v128u32 &src2, const v128u32 &src1, const v128u32 &src0) const;
template<NDSColorFormat OUTPUTFORMAT> FORCEINLINE void _brightnessUpMask16(GPUEngineCompositorInfo &compInfo, const v128u8 &passMask8, const v128u16 &evy16, const v128u8 &srcLayerID, const v128u16 &src1, const v128u16 &src0) const;
template<NDSColorFormat OUTPUTFORMAT> FORCEINLINE void _brightnessUpMask32(GPUEngineCompositorInfo &compInfo, const v128u8 &passMask8, const v128u16 &evy16, const v128u8 &srcLayerID, const v128u32 &src3, const v128u32 &src2, const v128u32 &src1, const v128u32 &src0) const;
template<NDSColorFormat OUTPUTFORMAT> FORCEINLINE void _brightnessDown16(GPUEngineCompositorInfo &compInfo, const v128u16 &evy16, const v128u8 &srcLayerID, const v128u16 &src1, const v128u16 &src0) const;
template<NDSColorFormat OUTPUTFORMAT> FORCEINLINE void _brightnessDown32(GPUEngineCompositorInfo &compInfo, const v128u16 &evy16, const v128u8 &srcLayerID, const v128u32 &src3, const v128u32 &src2, const v128u32 &src1, const v128u32 &src0) const;
template<NDSColorFormat OUTPUTFORMAT> FORCEINLINE void _brightnessDownMask16(GPUEngineCompositorInfo &compInfo, const v128u8 &passMask8, const v128u16 &evy16, const v128u8 &srcLayerID, const v128u16 &src1, const v128u16 &src0) const;
template<NDSColorFormat OUTPUTFORMAT> FORCEINLINE void _brightnessDownMask32(GPUEngineCompositorInfo &compInfo, const v128u8 &passMask8, const v128u16 &evy16, const v128u8 &srcLayerID, const v128u32 &src3, const v128u32 &src2, const v128u32 &src1, const v128u32 &src0) const;
template<NDSColorFormat OUTPUTFORMAT, GPULayerType LAYERTYPE>
FORCEINLINE void _unknownEffectMask16(GPUEngineCompositorInfo &compInfo,
const v128u8 &passMask8,
const v128u16 &evy16,
const v128u8 &srcLayerID,
const v128u16 &src1, const v128u16 &src0,
const v128u8 &srcEffectEnableMask,
const v128u8 &dstBlendEnableMaskLUT,
const v128u8 &enableColorEffectMask,
const v128u8 &spriteAlpha,
const v128u8 &spriteMode) const;
template<NDSColorFormat OUTPUTFORMAT, GPULayerType LAYERTYPE>
FORCEINLINE void _unknownEffectMask32(GPUEngineCompositorInfo &compInfo,
const v128u8 &passMask8,
const v128u16 &evy16,
const v128u8 &srcLayerID,
const v128u32 &src3, const v128u32 &src2, const v128u32 &src1, const v128u32 &src0,
const v128u8 &srcEffectEnableMask,
const v128u8 &dstBlendEnableMaskLUT,
const v128u8 &enableColorEffectMask,
const v128u8 &spriteAlpha,
const v128u8 &spriteMode) const;
public:
PixelOperation_NEON() {};
template <GPUCompositorMode COMPOSITORMODE, NDSColorFormat OUTPUTFORMAT, GPULayerType LAYERTYPE, bool WILLPERFORMWINDOWTEST>
FORCEINLINE void Composite16(GPUEngineCompositorInfo &compInfo,
const bool didAllPixelsPass,
const v128u8 &passMask8,
const v128u16 &evy16,
const v128u8 &srcLayerID,
const v128u16 &src1, const v128u16 &src0,
const v128u8 &srcEffectEnableMask,
const v128u8 &dstBlendEnableMaskLUT,
const u8 *__restrict enableColorEffectPtr,
const u8 *__restrict sprAlphaPtr,
const u8 *__restrict sprModePtr) const;
template <GPUCompositorMode COMPOSITORMODE, NDSColorFormat OUTPUTFORMAT, GPULayerType LAYERTYPE, bool WILLPERFORMWINDOWTEST>
FORCEINLINE void Composite32(GPUEngineCompositorInfo &compInfo,
const bool didAllPixelsPass,
const v128u8 &passMask8,
const v128u16 &evy16,
const v128u8 &srcLayerID,
const v128u32 &src3, const v128u32 &src2, const v128u32 &src1, const v128u32 &src0,
const v128u8 &srcEffectEnableMask,
const v128u8 &dstBlendEnableMaskLUT,
const u8 *__restrict enableColorEffectPtr,
const u8 *__restrict sprAlphaPtr,
const u8 *__restrict sprModePtr) const;
};
#endif // ENABLE_NEON_A64
#endif // GPU_OPERATIONS_NEON_H

File diff suppressed because it is too large Load Diff

View File

@ -1,122 +0,0 @@
/*
Copyright (C) 2021 DeSmuME team
This file is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
This file is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with the this software. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef GPU_OPERATIONS_SSE2_H
#define GPU_OPERATIONS_SSE2_H
#include "GPU_Operations.h"
#ifndef ENABLE_SSE2
#warning This header requires SSE2 support.
#else
class ColorOperation_SSE2
{
public:
ColorOperation_SSE2() {};
FORCEINLINE v128u16 blend(const v128u16 &colA, const v128u16 &colB, const v128u16 &blendEVA, const v128u16 &blendEVB) const;
template<NDSColorFormat COLORFORMAT, bool USECONSTANTBLENDVALUESHINT> FORCEINLINE v128u32 blend(const v128u32 &colA, const v128u32 &colB, const v128u16 &blendEVA, const v128u16 &blendEVB) const;
FORCEINLINE v128u16 blend3D(const v128u32 &colA_Lo, const v128u32 &colA_Hi, const v128u16 &colB) const;
template<NDSColorFormat COLORFORMAT> FORCEINLINE v128u32 blend3D(const v128u32 &colA, const v128u32 &colB) const;
FORCEINLINE v128u16 increase(const v128u16 &col, const v128u16 &blendEVY) const;
template<NDSColorFormat COLORFORMAT> FORCEINLINE v128u32 increase(const v128u32 &col, const v128u16 &blendEVY) const;
FORCEINLINE v128u16 decrease(const v128u16 &col, const v128u16 &blendEVY) const;
template<NDSColorFormat COLORFORMAT> FORCEINLINE v128u32 decrease(const v128u32 &col, const v128u16 &blendEVY) const;
};
class PixelOperation_SSE2
{
protected:
template<NDSColorFormat OUTPUTFORMAT, bool ISDEBUGRENDER> FORCEINLINE void _copy16(GPUEngineCompositorInfo &compInfo, const v128u8 &srcLayerID, const v128u16 &src1, const v128u16 &src0) const;
template<NDSColorFormat OUTPUTFORMAT, bool ISDEBUGRENDER> FORCEINLINE void _copy32(GPUEngineCompositorInfo &compInfo, const v128u8 &srcLayerID, const v128u32 &src3, const v128u32 &src2, const v128u32 &src1, const v128u32 &src0) const;
template<NDSColorFormat OUTPUTFORMAT, bool ISDEBUGRENDER> FORCEINLINE void _copyMask16(GPUEngineCompositorInfo &compInfo, const v128u8 &passMask8, const v128u8 &srcLayerID, const v128u16 &src1, const v128u16 &src0) const;
template<NDSColorFormat OUTPUTFORMAT, bool ISDEBUGRENDER> FORCEINLINE void _copyMask32(GPUEngineCompositorInfo &compInfo, const v128u8 &passMask8, const v128u8 &srcLayerID, const v128u32 &src3, const v128u32 &src2, const v128u32 &src1, const v128u32 &src0) const;
template<NDSColorFormat OUTPUTFORMAT> FORCEINLINE void _brightnessUp16(GPUEngineCompositorInfo &compInfo, const v128u16 &evy16, const v128u8 &srcLayerID, const v128u16 &src1, const v128u16 &src0) const;
template<NDSColorFormat OUTPUTFORMAT> FORCEINLINE void _brightnessUp32(GPUEngineCompositorInfo &compInfo, const v128u16 &evy16, const v128u8 &srcLayerID, const v128u32 &src3, const v128u32 &src2, const v128u32 &src1, const v128u32 &src0) const;
template<NDSColorFormat OUTPUTFORMAT> FORCEINLINE void _brightnessUpMask16(GPUEngineCompositorInfo &compInfo, const v128u8 &passMask8, const v128u16 &evy16, const v128u8 &srcLayerID, const v128u16 &src1, const v128u16 &src0) const;
template<NDSColorFormat OUTPUTFORMAT> FORCEINLINE void _brightnessUpMask32(GPUEngineCompositorInfo &compInfo, const v128u8 &passMask8, const v128u16 &evy16, const v128u8 &srcLayerID, const v128u32 &src3, const v128u32 &src2, const v128u32 &src1, const v128u32 &src0) const;
template<NDSColorFormat OUTPUTFORMAT> FORCEINLINE void _brightnessDown16(GPUEngineCompositorInfo &compInfo, const v128u16 &evy16, const v128u8 &srcLayerID, const v128u16 &src1, const v128u16 &src0) const;
template<NDSColorFormat OUTPUTFORMAT> FORCEINLINE void _brightnessDown32(GPUEngineCompositorInfo &compInfo, const v128u16 &evy16, const v128u8 &srcLayerID, const v128u32 &src3, const v128u32 &src2, const v128u32 &src1, const v128u32 &src0) const;
template<NDSColorFormat OUTPUTFORMAT> FORCEINLINE void _brightnessDownMask16(GPUEngineCompositorInfo &compInfo, const v128u8 &passMask8, const v128u16 &evy16, const v128u8 &srcLayerID, const v128u16 &src1, const v128u16 &src0) const;
template<NDSColorFormat OUTPUTFORMAT> FORCEINLINE void _brightnessDownMask32(GPUEngineCompositorInfo &compInfo, const v128u8 &passMask8, const v128u16 &evy16, const v128u8 &srcLayerID, const v128u32 &src3, const v128u32 &src2, const v128u32 &src1, const v128u32 &src0) const;
template<NDSColorFormat OUTPUTFORMAT, GPULayerType LAYERTYPE>
FORCEINLINE void _unknownEffectMask16(GPUEngineCompositorInfo &compInfo,
const v128u8 &passMask8,
const v128u16 &evy16,
const v128u8 &srcLayerID,
const v128u16 &src1, const v128u16 &src0,
const v128u8 &srcEffectEnableMask,
const v128u8 &dstBlendEnableMaskLUT,
const v128u8 &enableColorEffectMask,
const v128u8 &spriteAlpha,
const v128u8 &spriteMode) const;
template<NDSColorFormat OUTPUTFORMAT, GPULayerType LAYERTYPE>
FORCEINLINE void _unknownEffectMask32(GPUEngineCompositorInfo &compInfo,
const v128u8 &passMask8,
const v128u16 &evy16,
const v128u8 &srcLayerID,
const v128u32 &src3, const v128u32 &src2, const v128u32 &src1, const v128u32 &src0,
const v128u8 &srcEffectEnableMask,
const v128u8 &dstBlendEnableMaskLUT,
const v128u8 &enableColorEffectMask,
const v128u8 &spriteAlpha,
const v128u8 &spriteMode) const;
public:
PixelOperation_SSE2() {};
template <GPUCompositorMode COMPOSITORMODE, NDSColorFormat OUTPUTFORMAT, GPULayerType LAYERTYPE, bool WILLPERFORMWINDOWTEST>
FORCEINLINE void Composite16(GPUEngineCompositorInfo &compInfo,
const bool didAllPixelsPass,
const v128u8 &passMask8,
const v128u16 &evy16,
const v128u8 &srcLayerID,
const v128u16 &src1, const v128u16 &src0,
const v128u8 &srcEffectEnableMask,
const v128u8 &dstBlendEnableMaskLUT,
const u8 *__restrict enableColorEffectPtr,
const u8 *__restrict sprAlphaPtr,
const u8 *__restrict sprModePtr) const;
template <GPUCompositorMode COMPOSITORMODE, NDSColorFormat OUTPUTFORMAT, GPULayerType LAYERTYPE, bool WILLPERFORMWINDOWTEST>
FORCEINLINE void Composite32(GPUEngineCompositorInfo &compInfo,
const bool didAllPixelsPass,
const v128u8 &passMask8,
const v128u16 &evy16,
const v128u8 &srcLayerID,
const v128u32 &src3, const v128u32 &src2, const v128u32 &src1, const v128u32 &src0,
const v128u8 &srcEffectEnableMask,
const v128u8 &dstBlendEnableMaskLUT,
const u8 *__restrict enableColorEffectPtr,
const u8 *__restrict sprAlphaPtr,
const u8 *__restrict sprModePtr) const;
};
#endif // ENABLE_SSE2
#endif // GPU_OPERATIONS_SSE2_H

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,460 +0,0 @@
/*
Copyright (C) 2006 yopyop
Copyright (C) 2007 shash
Copyright (C) 2007-2017 DeSmuME team
This file is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
This file is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with the this software. If not, see <http://www.gnu.org/licenses/>.
*/
// this file is split from MMU.h for the purpose of avoiding ridiculous recompile times
// when changing it, because practically everything includes MMU.h.
#ifndef MMUTIMING_H
#define MMUTIMING_H
#include <algorithm>
#include "MMU.h"
#include "cp15.h"
#include "readwrite.h"
#include "debug.h"
#include "NDSSystem.h"
#include "emufile.h"
////////////////////////////////////////////////////////////////
// MEMORY TIMING ACCURACY CONFIGURATION
//
// the more of these are enabled,
// the more accurate memory access timing _should_ become.
// they should be listed roughly in order of most to least important.
// it's reasonable to disable some of these as a speed hack.
// obviously, these defines don't cover all the variables or features needed,
// and in particular, DMA or code+data access bus contention is still missing.
//disable this to prevent the advanced timing logic from ever running at all
#define ENABLE_ADVANCED_TIMING
#ifdef ENABLE_ADVANCED_TIMING
// makes non-sequential accesses slower than sequential ones.
#define ACCOUNT_FOR_NON_SEQUENTIAL_ACCESS
//(SOMETIMES THIS IS A BIG SPEED HIT!)
// enables emulation of code fetch waits.
#define ACCOUNT_FOR_CODE_FETCH_CYCLES
// makes access to DTCM (arm9 only) fast.
#define ACCOUNT_FOR_DATA_TCM_SPEED
// enables simulation of cache hits and cache misses.
#define ENABLE_CACHE_CONTROLLER_EMULATION
#endif //ENABLE_ADVANCED_TIMING
//
////////////////////////////////////////////////////////////////
FORCEINLINE bool USE_TIMING() {
#ifdef ENABLE_ADVANCED_TIMING
return CommonSettings.advanced_timing;
#else
return false;
#endif
}
enum MMU_ACCESS_DIRECTION
{
MMU_AD_READ, MMU_AD_WRITE
};
// note that we don't actually emulate the cache contents here,
// only enough to guess what would be a cache hit or a cache miss.
// this doesn't really get used unless ENABLE_CACHE_CONTROLLER_EMULATION is defined.
template<int SIZESHIFT, int ASSOCIATIVESHIFT, int BLOCKSIZESHIFT>
class CacheController
{
public:
template<MMU_ACCESS_DIRECTION DIR>
FORCEINLINE bool Cached(u32 addr)
{
u32 blockMasked = addr & BLOCKMASK;
if(blockMasked == m_cacheCache)
return true;
else
return this->CachedInternal<DIR>(addr, blockMasked);
}
void Reset()
{
for(int blockIndex = 0; blockIndex < NUMBLOCKS; blockIndex++)
m_blocks[blockIndex].Reset();
m_cacheCache = ~0;
}
CacheController()
{
Reset();
}
void savestate(EMUFILE &os, int version)
{
os.write_32LE(m_cacheCache);
for (int i = 0; i < NUMBLOCKS; i++)
{
for (int j = 0; j < ASSOCIATIVITY; j++)
os.write_32LE(m_blocks[i].tag[j]);
os.write_32LE(m_blocks[i].nextWay);
}
}
bool loadstate(EMUFILE &is, int version)
{
is.read_32LE(m_cacheCache);
for (int i = 0; i < NUMBLOCKS; i++)
{
for (int j = 0; j < ASSOCIATIVITY; j++)
is.read_32LE(m_blocks[i].tag[j]);
is.read_32LE(m_blocks[i].nextWay);
}
return true;
}
private:
template<MMU_ACCESS_DIRECTION DIR>
bool CachedInternal(u32 addr, u32 blockMasked)
{
u32 blockIndex = blockMasked >> BLOCKSIZESHIFT;
CacheBlock& block = m_blocks[blockIndex];
addr &= TAGMASK;
for(int way = 0; way < ASSOCIATIVITY; way++)
if(addr == block.tag[way])
{
// found it, already allocated
m_cacheCache = blockMasked;
return true;
}
if(DIR == MMU_AD_READ)
{
// TODO: support other allocation orders?
block.tag[block.nextWay++] = addr;
block.nextWay %= ASSOCIATIVITY;
m_cacheCache = blockMasked;
}
return false;
}
enum { SIZE = 1 << SIZESHIFT };
enum { ASSOCIATIVITY = 1 << ASSOCIATIVESHIFT };
enum { BLOCKSIZE = 1 << BLOCKSIZESHIFT };
enum { TAGSHIFT = SIZESHIFT - ASSOCIATIVESHIFT };
enum { TAGMASK = (u32)(~0U << TAGSHIFT) };
enum { BLOCKMASK = ((u32)~0U >> (32 - TAGSHIFT)) & (u32)(~0U << BLOCKSIZESHIFT) };
enum { WORDSIZE = sizeof(u32) };
enum { WORDSPERBLOCK = (1 << BLOCKSIZESHIFT) / WORDSIZE };
enum { DATAPERWORD = WORDSIZE * ASSOCIATIVITY };
enum { DATAPERBLOCK = DATAPERWORD * WORDSPERBLOCK };
enum { NUMBLOCKS = SIZE / DATAPERBLOCK };
struct CacheBlock
{
u32 tag [ASSOCIATIVITY];
u32 nextWay;
void Reset()
{
nextWay = 0;
for(int way = 0; way < ASSOCIATIVITY; way++)
tag[way] = 0;
}
};
u32 m_cacheCache; // optimization
CacheBlock m_blocks [NUMBLOCKS];
};
template<int PROCNUM, MMU_ACCESS_TYPE AT, int READSIZE, MMU_ACCESS_DIRECTION DIRECTION, bool TIMING>
FORCEINLINE u32 _MMU_accesstime(u32 addr, bool sequential);
template<int PROCNUM, MMU_ACCESS_TYPE AT>
class FetchAccessUnit
{
public:
template<int READSIZE, MMU_ACCESS_DIRECTION DIRECTION, bool TIMING>
FORCEINLINE u32 Fetch(u32 address)
{
#ifdef ACCOUNT_FOR_CODE_FETCH_CYCLES
const bool prohibit = TIMING;
#else
const bool prohibit = false;
#endif
if(AT == MMU_AT_CODE && !prohibit)
{
return 1;
}
u32 time = _MMU_accesstime<PROCNUM, AT, READSIZE, DIRECTION,TIMING>(address,
#ifdef ACCOUNT_FOR_NON_SEQUENTIAL_ACCESS
(TIMING?
(address == (m_lastAddress + (READSIZE>>3)))
:true
)
#else
true
#endif
);
#ifdef ACCOUNT_FOR_NON_SEQUENTIAL_ACCESS
m_lastAddress = address;
#endif
return time;
}
void Reset()
{
m_lastAddress = ~0;
}
FetchAccessUnit() { this->Reset(); }
void savestate(EMUFILE &os, int version)
{
os.write_32LE(m_lastAddress);
}
bool loadstate(EMUFILE &is, int version)
{
is.read_32LE(m_lastAddress);
return true;
}
private:
u32 m_lastAddress;
};
struct MMU_struct_timing
{
// technically part of the cp15, but I didn't want the dereferencing penalty.
// these template values correspond with the value of armcp15->cacheType.
CacheController<13,2,5> arm9codeCache; // 8192 bytes, 4-way associative, 32-byte blocks
CacheController<12,2,5> arm9dataCache; // 4096 bytes, 4-way associative, 32-byte blocks
// technically part of armcpu_t, but that struct isn't templated on PROCNUM
FetchAccessUnit<0,MMU_AT_CODE> arm9codeFetch;
FetchAccessUnit<0,MMU_AT_DATA> arm9dataFetch;
FetchAccessUnit<1,MMU_AT_CODE> arm7codeFetch;
FetchAccessUnit<1,MMU_AT_DATA> arm7dataFetch;
template<int PROCNUM> FORCEINLINE FetchAccessUnit<PROCNUM,MMU_AT_CODE>& armCodeFetch();
template<int PROCNUM> FORCEINLINE FetchAccessUnit<PROCNUM,MMU_AT_DATA>& armDataFetch();
};
template<> FORCEINLINE FetchAccessUnit<0,MMU_AT_CODE>& MMU_struct_timing::armCodeFetch<0>() { return this->arm9codeFetch; }
template<> FORCEINLINE FetchAccessUnit<1,MMU_AT_CODE>& MMU_struct_timing::armCodeFetch<1>() { return this->arm7codeFetch; }
template<> FORCEINLINE FetchAccessUnit<0,MMU_AT_DATA>& MMU_struct_timing::armDataFetch<0>() { return this->arm9dataFetch; }
template<> FORCEINLINE FetchAccessUnit<1,MMU_AT_DATA>& MMU_struct_timing::armDataFetch<1>() { return this->arm7dataFetch; }
extern MMU_struct_timing MMU_timing;
// calculates the time a single memory access takes,
// in units of cycles of the current processor.
// this function replaces what used to be MMU_WAIT16 and MMU_WAIT32.
// this may have side effects, so don't call it more than necessary.
template<int PROCNUM, MMU_ACCESS_TYPE AT, int READSIZE, MMU_ACCESS_DIRECTION DIRECTION, bool TIMING>
FORCEINLINE u32 _MMU_accesstime(u32 addr, bool sequential)
{
static const int MC = 1; // cached or tcm memory speed
static const int M32 = (PROCNUM==ARMCPU_ARM9) ? 2 : 1; // access through 32-bit bus
static const int M16 = M32 * ((READSIZE>16) ? 2 : 1); // access through 16-bit bus
static const int MSLW = M16 * 8; // this needs tuning
if(PROCNUM==ARMCPU_ARM9 && AT == MMU_AT_CODE && addr < 0x02000000)
return MC; // ITCM
#ifdef ACCOUNT_FOR_DATA_TCM_SPEED
if(TIMING && PROCNUM==ARMCPU_ARM9 && AT==MMU_AT_DATA && (addr&(~0x3FFF)) == MMU.DTCMRegion)
return MC; // DTCM
#endif
// for now, assume the cache is always enabled for all of main memory
if(AT != MMU_AT_DMA && TIMING && PROCNUM==ARMCPU_ARM9 && (addr & 0x0F000000) == 0x02000000)
{
#ifdef ENABLE_CACHE_CONTROLLER_EMULATION
bool cached = false;
if(AT==MMU_AT_CODE)
cached = MMU_timing.arm9codeCache.Cached<DIRECTION>(addr);
if(AT==MMU_AT_DATA)
cached = MMU_timing.arm9dataCache.Cached<DIRECTION>(addr);
if(cached)
return MC;
u32 c;
if(sequential && AT==MMU_AT_DATA)
c = M16; // bonus for sequential data access
else if(DIRECTION == MMU_AD_READ)
c = M16 * 5;
else
c = M16 * 2; // should be 4, but write buffer isn't emulated yet.
if(DIRECTION == MMU_AD_READ)
{
// cache miss while reading means it has to fill a whole cache line
// by reading 32 bytes...
c += 8 * M32*2;
}
if(CheckDebugEvent(DEBUG_EVENT_CACHE_MISS))
{
DebugEventData.addr = addr;
DebugEventData.size = READSIZE;
HandleDebugEvent(DEBUG_EVENT_CACHE_MISS);
}
return c;
#elif defined(ACCOUNT_FOR_NON_SEQUENTIAL_ACCESS)
// this is the closest approximation I could find
// to the with-cache-controller timing
// that doesn't do any actual caching logic.
return sequential ? MC : M16;
#endif
}
static const TWaitState MMU_WAIT[16*16] = {
// ITCM, ITCM, MAIN, SWI, REG, VMEM, LCD, OAM, ROM, ROM, RAM, U, U, U, U, BIOS
#define X MC, MC, M16, M32, M32, M16, M16, M32, MSLW, MSLW, MSLW, M32,M32,M32,M32, M32,
// duplicate it 16 times (this was somehow faster than using a mask of 0xF)
X X X X X X X X X X X X X X X X
#undef X
};
u32 c = MMU_WAIT[(addr >> 24)];
#ifdef ACCOUNT_FOR_NON_SEQUENTIAL_ACCESS
if(TIMING && !sequential)
{
//if(c != MC || PROCNUM==ARMCPU_ARM7) // check not needed anymore because ITCM/DTCM return earlier
{
c += (PROCNUM==ARMCPU_ARM9) ? 3*2 : 1;
}
}
#endif
return c;
}
// calculates the cycle time of a single memory access in the MEM stage.
// to be used to calculate the memCycles argument for MMU_aluMemCycles.
// this may have side effects, so don't call it more than necessary.
template<int PROCNUM, int READSIZE, MMU_ACCESS_DIRECTION DIRECTION, bool TIMING>
FORCEINLINE u32 MMU_memAccessCycles(u32 addr)
{
if(TIMING)
return MMU_timing.armDataFetch<PROCNUM>().template Fetch<READSIZE,DIRECTION,true>((addr)&(~((READSIZE>>3)-1)));
else
return MMU_timing.armDataFetch<PROCNUM>().template Fetch<READSIZE,DIRECTION,false>((addr)&(~((READSIZE>>3)-1)));
}
template<int PROCNUM, int READSIZE, MMU_ACCESS_DIRECTION DIRECTION>
FORCEINLINE u32 MMU_memAccessCycles(u32 addr)
{
if(USE_TIMING())
return MMU_memAccessCycles<PROCNUM,READSIZE,DIRECTION,true>(addr);
else
return MMU_memAccessCycles<PROCNUM,READSIZE,DIRECTION,false>(addr);
}
// calculates the cycle time of a single code fetch in the FETCH stage
// to be used to calculate the fetchCycles argument for MMU_fetchExecuteCycles.
// this may have side effects, so don't call it more than necessary.
template<int PROCNUM, int READSIZE>
FORCEINLINE u32 MMU_codeFetchCycles(u32 addr)
{
if(USE_TIMING())
return MMU_timing.armCodeFetch<PROCNUM>().template Fetch<READSIZE,MMU_AD_READ,true>((addr)&(~((READSIZE>>3)-1)));
else
return MMU_timing.armCodeFetch<PROCNUM>().template Fetch<READSIZE,MMU_AD_READ,false>((addr)&(~((READSIZE>>3)-1)));
}
// calculates the cycle contribution of ALU + MEM stages (= EXECUTE)
// given ALU cycle time and the summation of multiple memory access cycle times.
// this function might belong more in armcpu, but I don't think it matters.
template<int PROCNUM>
FORCEINLINE u32 MMU_aluMemCycles(u32 aluCycles, u32 memCycles)
{
if(PROCNUM==ARMCPU_ARM9)
{
// ALU and MEM are different stages of the 5-stage pipeline.
// we approximate the pipeline throughput using max,
// since simply adding the cycles of each instruction together
// fails to take into account the parallelism of the arm pipeline
// and would make the emulated system unnaturally slow.
return std::max(aluCycles, memCycles);
}
else
{
// ALU and MEM are part of the same stage of the 3-stage pipeline,
// thus they occur in sequence and we can simply add the counts together.
return aluCycles + memCycles;
}
}
// calculates the cycle contribution of ALU + MEM stages (= EXECUTE)
// given ALU cycle time and the description of a single memory access.
// this may have side effects, so don't call it more than necessary.
template<int PROCNUM, int READSIZE, MMU_ACCESS_DIRECTION DIRECTION>
FORCEINLINE u32 MMU_aluMemAccessCycles(u32 aluCycles, u32 addr)
{
u32 memCycles;
if(USE_TIMING())
memCycles = MMU_memAccessCycles<PROCNUM,READSIZE,DIRECTION,true>(addr);
else memCycles = MMU_memAccessCycles<PROCNUM,READSIZE,DIRECTION,false>(addr);
return MMU_aluMemCycles<PROCNUM>(aluCycles, memCycles);
}
// calculates the cycle contribution of FETCH + EXECUTE stages
// given executeCycles = the combined ALU+MEM cycles
// and fetchCycles = the cycle time of the FETCH stage
// this function might belong more in armcpu, but I don't think it matters.
template<int PROCNUM>
FORCEINLINE u32 MMU_fetchExecuteCycles(u32 executeCycles, u32 fetchCycles)
{
#ifdef ACCOUNT_FOR_CODE_FETCH_CYCLES
const bool allow = true;
#else
const bool allow = false;
#endif
if(USE_TIMING() && allow)
{
// execute and fetch are different stages of the pipeline for both arm7 and arm9.
// again, we approximate the pipeline throughput using max.
return std::max(executeCycles, fetchCycles);
// TODO: add an option to support conflict between MEM and FETCH cycles
// if they're both using the same data bus.
// in the case of a conflict this should be:
// return std::max(aluCycles, memCycles + fetchCycles);
}
return executeCycles;
}
#endif //MMUTIMING_H

File diff suppressed because it is too large Load Diff

View File

@ -1,702 +0,0 @@
/*
Copyright (C) 2006 yopyop
Copyright (C) 2008-2022 DeSmuME team
This file is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
This file is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with the this software. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef NDSSYSTEM_H
#define NDSSYSTEM_H
#include <string.h>
#include <string>
#include <vector>
#include "types.h"
#include "ROMReader.h"
#include "firmware.h"
class CFIRMWARE;
class EMUFILE;
template<typename Type>
struct buttonstruct {
union {
struct {
// changing the order of these fields would break stuff
//fRLDUTSBAYXWEg
Type G; // debug
Type E; // right shoulder
Type W; // left shoulder
Type X;
Type Y;
Type A;
Type B;
Type S; // start
Type T; // select
Type U; // up
Type D; // down
Type L; // left
Type R; // right
Type F; // lid
};
Type array[14];
};
};
extern buttonstruct<bool> Turbo;
extern buttonstruct<u32> TurboTime;
extern buttonstruct<bool> AutoHold;
extern volatile bool execute;
extern BOOL click;
/*
* The firmware language values
*/
#define NDS_FW_LANG_JAP 0
#define NDS_FW_LANG_ENG 1
#define NDS_FW_LANG_FRE 2
#define NDS_FW_LANG_GER 3
#define NDS_FW_LANG_ITA 4
#define NDS_FW_LANG_SPA 5
#define NDS_FW_LANG_CHI 6
#define NDS_FW_LANG_RES 7
extern CFIRMWARE *extFirmwareObj;
#define DSGBA_LOADER_SIZE 512
enum
{
ROM_NDS = 0,
ROM_DSGBA
};
enum EmuHaltReasonCode
{
EMUHALT_REASON_USER_REQUESTED_HALT = 0,
EMUHALT_REASON_SYSTEM_POWERED_OFF = 1000,
EMUHALT_REASON_JIT_UNMAPPED_ADDRESS_EXCEPTION = 2000,
EMUHALT_REASON_ARM_RESERVED_0X14_EXCEPTION,
EMUHALT_REASON_ARM_UNDEFINED_INSTRUCTION_EXCEPTION,
EMUHALT_REASON_UNKNOWN = 10000
};
enum NDSErrorCode
{
NDSError_NoError = 0,
NDSError_SystemPoweredOff = 1000,
NDSError_JITUnmappedAddressException = 2000,
NDSError_ARMUndefinedInstructionException,
NDSError_UnknownError = 10000
};
enum NDSErrorTag
{
NDSErrorTag_None = 0,
NDSErrorTag_ARM9 = 1,
NDSErrorTag_ARM7 = 2,
NDSErrorTag_BothCPUs = 3,
};
struct NDSError
{
NDSErrorCode code;
NDSErrorTag tag;
u32 programCounterARM9;
u32 instructionARM9;
u32 instructionAddrARM9;
u32 programCounterARM7;
u32 instructionARM7;
u32 instructionAddrARM7;
};
typedef struct NDSError NDSError;
//#define LOG_ARM9
//#define LOG_ARM7
#include "PACKED.h"
struct NDS_header
{
char gameTile[12]; // 000 - Game Title (uppercase ASCII, padded with 00h)
char gameCode[4]; // 00C - Gamecode (uppercase ASCII, NTR-<code>, 0=homebrew)
u16 makerCode; // 010 - Makercode (uppercase ASCII, 0=homebrew)
u8 unitCode; // 012 - Unitcode (00h=Nintendo DS)
u8 deviceCode; // 013 - Encryption Seed Select (00..07h, usually 00h)
u8 cardSize; // 014 - Devicecapacity (Chipsize = 128KB SHL nn) (eg. 7 = 16MB)
u8 reserved1[8]; // 015 - Must be set to 0x00
u8 region; // 01D - Specific region: 0x80 - China, 0x40 - Korea, 0x00 - Other
u8 romversion; // 01E - ROM Version (usually 00h)
u8 autostart; // 01F - Autostart (Bit2: Skip "Press Button" after Health and Safety)
// (Also skips bootmenu, even in Manual mode & even Start pressed)
u32 ARM9src; // 020 - ARM9 rom_offset (4000h and up, align 1000h)
u32 ARM9exe; // 024 - ARM9 entry_address (2000000h..23BFE00h)
u32 ARM9cpy; // 028 - ARM9 ram_address (2000000h..23BFE00h)
u32 ARM9binSize; // 02C - ARM9 size (max 3BFE00h) (3839.5KB)
u32 ARM7src; // 030 - ARM7 rom_offset (8000h and up)
u32 ARM7exe; // 034 - ARM7 entry_address (2000000h..23BFE00h, or 37F8000h..3807E00h)
u32 ARM7cpy; // 038 - ARM7 ram_address (2000000h..23BFE00h, or 37F8000h..3807E00h)
u32 ARM7binSize; // 03C - ARM7 size (max 3BFE00h, or FE00h) (3839.5KB, 63.5KB)
u32 FNameTblOff; // 040 - File Name Table (FNT) offset
u32 FNameTblSize; // 044 - File Name Table (FNT) size
u32 FATOff; // 048 - File Allocation Table (FAT) offset
u32 FATSize; // 04C - File Allocation Table (FAT) size
u32 ARM9OverlayOff; // 050 - File ARM9 overlay_offset
u32 ARM9OverlaySize; // 054 - File ARM9 overlay_size
u32 ARM7OverlayOff; // 058 - File ARM7 overlay_offset
u32 ARM7OverlaySize; // 05C - File ARM7 overlay_size
u32 normalCmd; // 060 - Port 40001A4h setting for normal commands (usually 00586000h)
u32 Key1Cmd; // 064 - Port 40001A4h setting for KEY1 commands (usually 001808F8h)
u32 IconOff; // 068 - Icon_title_offset (0=None) (8000h and up)
u16 CRC16; // 06C - Secure Area Checksum, CRC-16 of [ [20h]..7FFFh] - Calculations with this algorithm use 0xffff as the initial value
u16 ROMtimeout; // 06E - Secure Area Loading Timeout (usually 051Eh)
u32 ARM9autoload; // 070 - ARM9 Auto Load List RAM Address
u32 ARM7autoload; // 074 - ARM7 Auto Load List RAM Address
u8 infoResevedRegion[8]; // 078 - ROM Information Reserved Region (must be set to 0x00)
u32 endROMoffset; // 080 - Total Used ROM size (remaining/unused bytes usually FFh-padded)
u32 HeaderSize; // 084 - ROM Header Size (4000h)
u32 ARM9module; // 088 - ARM9 Module Parameter Address (auto-load parameters)
u32 ARM7module; // 08C - ARM7 Module Parameter Address (auto-load parameters)
u8 reserved2[48]; // 090 - Must be set to 0x00 - "PASS" is contained within here?
u8 logo[156]; // 0C0 - Nintendo Logo (compressed bitmap, same as in GBA Headers)
u16 logoCRC16; // 15C - Nintendo Logo Checksum, CRC-16 of [0C0h-15Bh], fixed CF56h
u16 headerCRC16; // 15E - Header Checksum, CRC-16 of [000h-15Dh]
u8 reserved[160]; // Must be set to 0x00
};
#include "PACKED_END.h"
extern void debug();
NDSError NDS_GetLastError();
void emu_halt(EmuHaltReasonCode reasonCode, NDSErrorTag errorTag);
extern u64 nds_timer;
void NDS_Reschedule();
void NDS_RescheduleGXFIFO(u32 cost);
void NDS_RescheduleDMA();
void NDS_RescheduleReadSlot1(int procnum, int size);
void NDS_RescheduleTimers();
enum ENSATA_HANDSHAKE
{
ENSATA_HANDSHAKE_none = 0,
ENSATA_HANDSHAKE_query = 1,
ENSATA_HANDSHAKE_ack = 2,
ENSATA_HANDSHAKE_confirm = 3,
ENSATA_HANDSHAKE_complete = 4
};
enum NDS_CONSOLE_TYPE
{
NDS_CONSOLE_TYPE_FAT = 0xFF,
NDS_CONSOLE_TYPE_LITE = 0x20,
NDS_CONSOLE_TYPE_IQUE = 0x43,
NDS_CONSOLE_TYPE_IQUE_LITE = 0x63,
NDS_CONSOLE_TYPE_DSI = 0xFE
};
struct NDSSystem
{
s32 wifiCycle;
s32 cycles;
u64 timerCycle[2][4];
u32 VCount;
u32 old;
u8 overclock;
//raw adc touch coords for old NDS
u16 adc_touchX;
u16 adc_touchY;
s32 adc_jitterctr;
//the DSI returns calibrated touch coords from its TSC (?), so we need to save these separately
u16 scr_touchX;
u16 scr_touchY;
//whether the console is using our faked-bootup process
BOOL isFakeBooted;
BOOL isTouch;
u16 paddle;
u8 *FW_ARM9BootCode;
u8 *FW_ARM7BootCode;
u32 FW_ARM9BootCodeAddr;
u32 FW_ARM7BootCodeAddr;
u32 FW_ARM9BootCodeSize;
u32 FW_ARM7BootCodeSize;
BOOL sleeping;
BOOL cardEjected;
u32 freezeBus;
//this is not essential NDS runtime state.
//it was perhaps a mistake to put it here.
//it is far less important than the above.
//maybe I should move it.
s32 idleCycles[2];
s32 runCycleCollector[2][16];
s32 idleFrameCounter;
s32 cpuloopIterationCount; //counts the number of times during a frame that a reschedule happened
//console type must be copied in when the system boots. it can't be changed on the fly.
int ConsoleType;
bool Is_DSI() { return ConsoleType == NDS_CONSOLE_TYPE_DSI; }
bool Is_DebugConsole() { return _DebugConsole!=0; }
BOOL _DebugConsole;
//set if the user requests ensata emulation
BOOL ensataEmulation;
//there is a hack in the ipc sync for ensata. this tracks its state
u32 ensataIpcSyncCounter;
//maintains the state of the ensata handshaking protocol
u32 ensataHandshake;
struct {
u8 lcd, gpuMain, gfx3d_render, gfx3d_geometry, gpuSub, dispswap;
} power1; //POWCNT1
struct {
u8 speakers, wifi /*(initial value=0)*/;
} power2; //POWCNT2
BOOL power_render, power_geometry;
bool isInVblank() const { return VCount >= 192; }
bool isIn3dVblank() const { return VCount >= 192 && VCount<215; }
};
extern NDSSystem nds;
int NDS_Init();
void Desmume_InitOnce();
void NDS_DeInit(void);
BOOL NDS_SetROM(u8 * rom, u32 mask);
NDS_header * NDS_getROMHeader(void);
struct RomBanner
{
RomBanner(bool defaultInit = true);
u16 version; //Version (0001h)
u16 crc16; //CRC16 across entries 020h..83Fh
u8 reserved[0x1C]; //Reserved (zero-filled)
u8 bitmap[0x200]; //Icon Bitmap (32x32 pix) (4x4 tiles, each 4x8 bytes, 4bit depth)
u16 palette[0x10]; //Icon Palette (16 colors, 16bit, range 0000h-7FFFh) (Color 0 is transparent, so the 1st palette entry is ignored)
enum { NUM_TITLES = 6 };
union {
struct {
u16 title_jp[0x80]; //Title 0 Japanese (128 characters, 16bit Unicode)
u16 title_en[0x80]; //Title 1 English ("")
u16 title_fr[0x80]; //Title 2 French ("")
u16 title_de[0x80]; //Title 3 German ("")
u16 title_it[0x80]; //Title 4 Italian ("")
u16 title_es[0x80]; //Title 5 Spanish ("")
};
u16 titles[NUM_TITLES][0x80];
};
u8 end0xFF[0x1C0];
//840h ? (Maybe newer/chinese firmware do also support chinese title?)
//840h - End of Icon/Title structure (next 1C0h bytes usually FFh-filled)
};
struct GameInfo
{
void *fROM;
ROMReader_struct *reader;
u8 *romdataForReader;
u32 romsize;
u32 cardSize;
u32 mask;
u32 crc;
u32 crcForCheatsDb;
u32 chipID;
u32 romType;
u32 headerOffset;
char ROMserial[20];
char ROMname[13];
bool _isDSiEnhanced;
NDS_header header;
//a copy of the pristine secure area from the rom
u8 secureArea[0x4000];
RomBanner banner;
const RomBanner& getRomBanner();
GameInfo() : fROM(NULL),
romdataForReader(NULL),
crc(0),
chipID(0x00000FC2),
romsize(0),
cardSize(0),
mask(0),
romType(ROM_NDS),
headerOffset(0),
_isDSiEnhanced(false)
{
memset(&header, 0, sizeof(header));
memset(&ROMserial[0], 0, sizeof(ROMserial));
memset(&ROMname[0], 0, sizeof(ROMname));
}
~GameInfo() { closeROM(); }
bool IsCode(const char* code) const;
bool loadROM(std::string fname, u32 type = ROM_NDS);
void closeROM();
u32 readROM(u32 pos);
bool ValidateHeader();
void populate();
bool isDSiEnhanced();
bool isHomebrew();
bool hasRomBanner();
};
typedef struct TSCalInfo
{
struct
{
u16 x1, x2;
u16 y1, y2;
u16 width;
u16 height;
} adc;
struct
{
u8 x1, x2;
u8 y1, y2;
u16 width;
u16 height;
} scr;
} TSCalInfo;
extern GameInfo gameInfo;
extern std::vector<u32> memReadBreakPoints;
extern std::vector<u32> memWriteBreakPoints;
struct UserButtons : buttonstruct<bool>
{
};
struct UserTouch
{
u16 touchX;
u16 touchY;
bool isTouch;
};
struct UserMicrophone
{
u32 micButtonPressed;
u8 micSample;
};
struct UserInput
{
UserButtons buttons;
UserTouch touch;
UserMicrophone mic;
};
// set physical user input
// these functions merely request the input to be changed.
// the actual change happens later at a specific time during the frame.
// this is to minimize the risk of desyncs.
void NDS_setTouchPos(u16 x, u16 y);
void NDS_releaseTouch(void);
void NDS_setPad(bool right,bool left,bool down,bool up,bool select,bool start,bool B,bool A,bool Y,bool X,bool leftShoulder,bool rightShoulder,bool debug, bool lid);
void NDS_setMic(bool pressed);
// get physical user input
// not including the results of autofire/etc.
// the effects of calls to "set physical user input" functions will be immediately reflected here though.
const UserInput& NDS_getRawUserInput();
const UserInput& NDS_getPrevRawUserInput();
// get final (fully processed) user input
// this should match whatever was or would be sent to the game
const UserInput& NDS_getFinalUserInput();
// set/get to-be-processed or in-the-middle-of-being-processed user input
// to process input, simply call this function and edit the return value.
// (applying autofire is one example of processing the input.)
// (movie playback is another example.)
// this must be done after the raw user input is set
// and before that input is sent to the game's memory.
UserInput& NDS_getProcessingUserInput();
bool NDS_isProcessingUserInput();
// call once per frame to prepare input for processing
void NDS_beginProcessingInput();
// call once per frame to copy the processed input to the final input
void NDS_endProcessingInput();
// this is in case something needs reentrancy while processing input
void NDS_suspendProcessingInput(bool suspend);
int NDS_LoadROM(const char *filename, const char* physicalFilename=0, const char* logicalFilename=0);
void NDS_FreeROM(void);
void NDS_Reset();
bool NDS_LegitBoot();
bool NDS_FakeBoot();
void nds_savestate(EMUFILE &os);
bool nds_loadstate(EMUFILE &is, int size);
void NDS_Sleep();
void NDS_TriggerCardEjectIRQ();
void NDS_SkipNextFrame();
#define NDS_SkipFrame(s) if(s) NDS_SkipNext2DFrame();
void NDS_OmitFrameSkip(int force=0);
void NDS_debug_break();
void NDS_debug_continue();
void NDS_debug_step();
int NDS_GetCPUCoreCount();
void NDS_GetCPULoadAverage(u32 &outLoadAvgARM9, u32 &outLoadAvgARM7);
void NDS_SetupDefaultFirmware();
//void execHardware_doAllDma(EDMAMode modeNum);
template<bool FORCE> void NDS_exec(s32 nb = 560190<<1);
extern int lagframecounter;
extern struct TCommonSettings
{
TCommonSettings()
: GFX3D_HighResolutionInterpolateColor(true)
, GFX3D_EdgeMark(true)
, GFX3D_Fog(true)
, GFX3D_Texture(true)
, GFX3D_LineHack(true)
, GFX3D_Renderer_MultisampleSize(0)
, GFX3D_Renderer_TextureScalingFactor(1) // Possible values: 1, 2, 4
, GFX3D_Renderer_TextureDeposterize(false)
, GFX3D_Renderer_TextureSmoothing(false)
, GFX3D_TXTHack(false)
, OpenGL_Emulation_ShadowPolygon(true)
, OpenGL_Emulation_SpecialZeroAlphaBlending(true)
, OpenGL_Emulation_NDSDepthCalculation(true)
, OpenGL_Emulation_DepthLEqualPolygonFacing(false)
, jit_max_block_size(12)
, loadToMemory(false)
, UseExtBIOS(false)
, SWIFromBIOS(false)
, PatchSWI3(false)
, UseExtFirmware(false)
, UseExtFirmwareSettings(false)
, RetailCardProtection8000(true)
, BootFromFirmware(false)
, DebugConsole(false)
, EnsataEmulation(false)
, cheatsDisable(false)
, rigorous_timing(false)
, advanced_timing(true)
, micMode(InternalNoise)
, spuInterpolationMode(2)
, manualBackupType(0)
, autodetectBackupMethod(0)
, spu_captureMuted(false)
, spu_advanced(true)
, StylusPressure(50)
, ConsoleType(NDS_CONSOLE_TYPE_FAT)
, backupSave(false)
, SPU_sync_mode(1)
, SPU_sync_method(0)
, WifiBridgeDeviceID(0)
{
strcpy(ARM9BIOS, "biosnds9.bin");
strcpy(ARM7BIOS, "biosnds7.bin");
strcpy(ExtFirmwarePath, "firmware.bin");
for(int i=0;i<16;i++)
spu_muteChannels[i] = false;
for(int g=0;g<2;g++)
for(int x=0;x<5;x++)
dispLayers[g][x]=true;
#ifdef HAVE_JIT
//zero 06-sep-2012 - shouldnt be defaulting this to true for now, since the jit is buggy.
//id rather have people discover a bonus speedhack than discover new bugs in a new version
use_jit = false;
#else
use_jit = false;
#endif
num_cores = NDS_GetCPUCoreCount();
NDS_SetupDefaultFirmware();
}
bool GFX3D_HighResolutionInterpolateColor;
bool GFX3D_EdgeMark;
bool GFX3D_Fog;
bool GFX3D_Texture;
bool GFX3D_LineHack;
int GFX3D_Renderer_MultisampleSize;
int GFX3D_Renderer_TextureScalingFactor; //must be one of {1,2,4}
bool GFX3D_Renderer_TextureDeposterize;
bool GFX3D_Renderer_TextureSmoothing;
bool GFX3D_TXTHack;
bool OpenGL_Emulation_ShadowPolygon;
bool OpenGL_Emulation_SpecialZeroAlphaBlending;
bool OpenGL_Emulation_NDSDepthCalculation;
bool OpenGL_Emulation_DepthLEqualPolygonFacing;
bool loadToMemory;
bool UseExtBIOS;
char ARM9BIOS[MAX_PATH];
char ARM7BIOS[MAX_PATH];
bool SWIFromBIOS;
bool PatchSWI3;
bool RetailCardProtection8000;
bool UseExtFirmware;
bool UseExtFirmwareSettings;
char ExtFirmwarePath[MAX_PATH];
char ExtFirmwareUserSettingsPath[MAX_PATH];
bool BootFromFirmware;
FirmwareConfig fwConfig;
NDS_CONSOLE_TYPE ConsoleType;
bool DebugConsole;
bool EnsataEmulation;
bool cheatsDisable;
int num_cores;
bool single_core() { return num_cores==1; }
bool rigorous_timing;
struct GameHacks {
GameHacks()
: en(true)
{
clear();
}
bool en;
struct {
bool overclock;
bool stylusjitter;
} flags;
void apply();
void clear();
} gamehacks;
int StylusPressure;
bool dispLayers[2][5];
FAST_ALIGN bool advanced_timing;
bool use_jit;
u32 jit_max_block_size;
int WifiBridgeDeviceID;
enum MicMode
{
InternalNoise = 0,
Sample = 1,
Random = 2,
Physical = 3
} micMode;
int spuInterpolationMode;
//this is a temporary hack until we straighten out the flushing logic and/or gxfifo
//int gfx3d_flushMode;
int autodetectBackupMethod;
//this is the user's choice of manual backup type, for cases when the autodetection can't be trusted
int manualBackupType;
bool backupSave;
int SPU_sync_mode;
int SPU_sync_method;
bool spu_muteChannels[16];
bool spu_captureMuted;
bool spu_advanced;
struct _ShowGpu {
_ShowGpu() : main(true), sub(true) {}
union {
struct { bool main,sub; };
bool screens[2];
};
} showGpu;
struct _Hud {
_Hud()
: ShowInputDisplay(false)
, ShowGraphicalInputDisplay(false)
, FpsDisplay(false)
, FrameCounterDisplay(false)
, ShowLagFrameCounter(false)
, ShowMicrophone(false)
, ShowRTC(false)
{}
bool ShowInputDisplay, ShowGraphicalInputDisplay, FpsDisplay, FrameCounterDisplay, ShowLagFrameCounter, ShowMicrophone, ShowRTC;
} hud;
std::string run_advanscene_import;
} CommonSettings;
void NDS_RunAdvansceneAutoImport();
extern std::string InputDisplayString;
extern int LagFrameFlag;
extern int lastLag, TotalLagFrames;
extern u8 MicSampleSelection;
extern std::vector< std::vector<u8> > micSamples;
void MovieSRAM();
void ClearAutoHold(void);
bool ValidateSlot2Access(u32 procnum, u32 demandSRAMSpeed, u32 demand1stROMSpeed, u32 demand2ndROMSpeed, int clockbits);
//MUSTANG
//extern ADVANsCEne advsc;
#endif

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,176 +0,0 @@
/*
Copyright (C) 2006 yopyop
Copyright (C) 2006-2007 shash
Copyright (C) 2008-2024 DeSmuME team
This file is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
This file is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with the this software. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef OGLRENDER_3_2_H
#define OGLRENDER_3_2_H
#include "OGLRender.h"
#define MAX_CLIPPED_POLY_COUNT_FOR_UBO 16384
extern const char *GeometryVtxShader_150;
extern const char *GeometryFragShader_150;
extern const char *GeometryZeroDstAlphaPixelMaskVtxShader_150;
extern const char *GeometryZeroDstAlphaPixelMaskFragShader_150;
extern const char *MSGeometryZeroDstAlphaPixelMaskFragShader_150;
extern const char *ClearImageVtxShader_150;
extern const char *ClearImageFragShader_150;
extern const char *EdgeMarkVtxShader_150;
extern const char *EdgeMarkFragShader_150;
extern const char *FogVtxShader_150;
extern const char *FogFragShader_150;
extern const char *FramebufferOutputVtxShader_150;
extern const char *FramebufferOutput6665FragShader_150;
// A port that wants to use the OpenGL 3.2 renderer must assign the two following functions
// to OGLLoadEntryPoints_3_2_Func and OGLCreateRenderer_3_2_Func, respectively.
//
// In addition, the port must add the following GPU3DInterface objects to core3DList:
// - gpu3Dgl: Automatically selects the most fully featured version of standard OpenGL that
// is available on the host system, prefering OpenGL 3.2 Core Profile.
// - gpu3Dgl_3_2: Selects the OpenGL 3.2 Core Profile renderer, and returns an error if it
// is not available on the host system.
//
// Finally, the port must call GPU->Set3DRendererByID() and pass in the index where
// gpu3Dgl_3_2 exists in core3DList so that the emulator can create the appropriate
// OpenGLRenderer object.
//
// Example code:
// OGLLoadEntryPoints_3_2_Func = &OGLLoadEntryPoints_3_2;
// OGLCreateRenderer_3_2_Func = &OGLCreateRenderer_3_2;
// GPU3DInterface *core3DList[] = { &gpu3DNull, &gpu3DRasterize, &gpu3Dgl_3_2, NULL };
// GPU->Set3DRendererByID(2);
void OGLLoadEntryPoints_3_2();
void OGLCreateRenderer_3_2(OpenGLRenderer **rendererPtr);
class OpenGLGeometryResource : public Render3DResourceGeometry
{
protected:
GLuint _vboID[3];
GLuint _eboID[3];
GLuint _vaoID[3];
GLuint _uboPolyStatesID[3];
GLuint _tboPolyStatesID[3];
GLuint _texPolyStatesID[3];
GLsync _syncGeometryRender[3];
u16 *_indexBuffer[3];
OGLPolyStates *_polyStatesBuffer[3];
public:
OpenGLGeometryResource(const OpenGLVariantID variantID);
~OpenGLGeometryResource();
size_t BindWrite(const size_t rawVtxCount, const size_t clippedPolyCount);
size_t BindUsage();
size_t UnbindUsage();
size_t RebindUsage();
u16* GetIndexBuffer(const size_t index);
OGLPolyStates* GetPolyStatesBuffer(const size_t index);
bool IsPolyStatesBufferUBO();
bool IsPolyStatesBufferTBO();
};
class OpenGLRenderStatesResource : public Render3DResource
{
protected:
GLsync _sync[3];
GLuint _uboRenderStatesID[3];
OGLRenderStates *_buffer[3];
public:
OpenGLRenderStatesResource();
~OpenGLRenderStatesResource();
size_t BindWrite();
size_t BindUsage();
size_t UnbindUsage();
OGLRenderStates* GetRenderStatesBuffer(const size_t index);
};
class OpenGLRenderer_3_2 : public OpenGLRenderer_2_1
{
protected:
bool _isShaderFixedLocationSupported;
bool _isConservativeDepthSupported;
bool _isConservativeDepthAMDSupported;
OpenGLGeometryResource *_gResource;
OpenGLRenderStatesResource *_rsResource;
virtual Render3DError CreateVBOs();
virtual Render3DError CreatePBOs();
virtual Render3DError CreateFBOs();
virtual void DestroyFBOs();
virtual Render3DError CreateMultisampledFBO(GLsizei numSamples);
virtual void DestroyMultisampledFBO();
virtual void ResizeMultisampledFBOs(GLsizei numSamples);
virtual Render3DError CreateVAOs();
virtual void DestroyVAOs();
virtual Render3DError CreateGeometryPrograms();
virtual Render3DError CreateClearImageProgram(const char *vsCString, const char *fsCString);
virtual void DestroyClearImageProgram();
virtual Render3DError CreateGeometryZeroDstAlphaProgram(const char *vtxShaderCString, const char *fragShaderCString);
virtual Render3DError CreateMSGeometryZeroDstAlphaProgram(const char *vtxShaderCString, const char *fragShaderCString);
virtual void DestroyMSGeometryZeroDstAlphaProgram();
virtual Render3DError CreateEdgeMarkProgram(const bool isMultisample, const char *vtxShaderCString, const char *fragShaderCString);
virtual Render3DError CreateFogProgram(const OGLFogProgramKey fogProgramKey, const bool isMultisample, const char *vtxShaderCString, const char *fragShaderCString);
virtual Render3DError CreateFramebufferOutput6665Program(const char *vtxShaderCString, const char *fragShaderCString);
virtual Render3DError CreateFramebufferOutput8888Program(const char *vtxShaderCString, const char *fragShaderCString);
virtual void GetExtensionSet(std::set<std::string> *oglExtensionSet);
virtual void _SetupGeometryShaders(const OGLGeometryFlags flags);
virtual void _RenderGeometryVertexAttribEnable();
virtual void _RenderGeometryVertexAttribDisable();
virtual Render3DError ZeroDstAlphaPass(const POLY *rawPolyList, const CPoly *clippedPolyList, const size_t clippedPolyCount, const size_t clippedPolyOpaqueCount, bool enableAlphaBlending, size_t indexOffset, POLYGON_ATTR lastPolyAttr);
virtual void _RenderGeometryLoopBegin();
virtual void _RenderGeometryLoopEnd();
virtual void _ResolveWorkingBackFacing();
virtual void _ResolveGeometry();
virtual void _ResolveFinalFramebuffer();
virtual void _FramebufferProcessVertexAttribEnable();
virtual void _FramebufferProcessVertexAttribDisable();
virtual Render3DError _FramebufferConvertColorFormat();
virtual Render3DError BeginRender(const GFX3D_State &renderState, const GFX3D_GeometryList &renderGList);
virtual Render3DError PostprocessFramebuffer();
virtual Render3DError ClearUsingImage(const u16 *__restrict colorBuffer, const u32 *__restrict depthBuffer, const u8 *__restrict fogBuffer, const u8 opaquePolyID);
virtual Render3DError ClearUsingValues(const Color4u8 &clearColor6665, const FragmentAttributes &clearAttributes);
virtual void SetPolygonIndex(const size_t index);
virtual Render3DError SetupPolygon(const POLY &thePoly, bool treatAsTranslucent, bool willChangeStencilBuffer, bool isBackFacing);
virtual Render3DError SetupTexture(const POLY &thePoly, size_t polyRenderIndex);
public:
OpenGLRenderer_3_2();
~OpenGLRenderer_3_2();
virtual Render3DError InitExtensions();
virtual Render3DError RenderFinish();
virtual Render3DError RenderPowerOff();
virtual Render3DError SetFramebufferSize(size_t w, size_t h);
};
#endif

View File

@ -1,963 +0,0 @@
/*
Copyright (C) 2024 DeSmuME team
This file is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
This file is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with the this software. If not, see <http://www.gnu.org/licenses/>.
*/
#include "OGLRender_ES3.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <algorithm>
#include <string>
#include <sstream>
#include "utils/bits.h"
#include "common.h"
#include "debug.h"
#include "NDSSystem.h"
static const GLenum GeometryDrawBuffersEnumES[8][4] = {
{ OGL_COLOROUT_ATTACHMENT_ID, GL_NONE, GL_NONE, GL_NONE },
{ OGL_COLOROUT_ATTACHMENT_ID, GL_NONE, GL_NONE, OGL_FOGATTRIBUTES_ATTACHMENT_ID },
{ OGL_COLOROUT_ATTACHMENT_ID, GL_NONE, OGL_POLYID_ATTACHMENT_ID, GL_NONE },
{ OGL_COLOROUT_ATTACHMENT_ID, GL_NONE, OGL_POLYID_ATTACHMENT_ID, OGL_FOGATTRIBUTES_ATTACHMENT_ID },
{ OGL_COLOROUT_ATTACHMENT_ID, OGL_WORKING_ATTACHMENT_ID, GL_NONE, GL_NONE },
{ OGL_COLOROUT_ATTACHMENT_ID, OGL_WORKING_ATTACHMENT_ID, GL_NONE, OGL_FOGATTRIBUTES_ATTACHMENT_ID },
{ OGL_COLOROUT_ATTACHMENT_ID, OGL_WORKING_ATTACHMENT_ID, OGL_POLYID_ATTACHMENT_ID, GL_NONE },
{ OGL_COLOROUT_ATTACHMENT_ID, OGL_WORKING_ATTACHMENT_ID, OGL_POLYID_ATTACHMENT_ID, OGL_FOGATTRIBUTES_ATTACHMENT_ID }
};
static const GLint GeometryAttachmentWorkingBufferES[8] = { 1,1,1,1,1,1,1,1 };
static const GLint GeometryAttachmentPolyIDES[8] = { 2,2,2,2,2,2,2,2 };
static const GLint GeometryAttachmentFogAttributesES[8] = { 3,3,3,3,3,3,3,3 };
// Vertex shader for geometry, GLSL ES 3.00
static const char *GeometryVtxShader_ES300 = {"\
IN_VTX_POSITION vec4 inPosition;\n\
IN_VTX_TEXCOORD0 vec2 inTexCoord0;\n\
IN_VTX_COLOR vec3 inColor; \n\
\n\
#if IS_USING_UBO_POLY_STATES\n\
layout (std140) uniform PolyStates\n\
{\n\
ivec4 value[4096];\n\
} polyState;\n\
#elif IS_USING_TBO_POLY_STATES\n\
uniform highp isamplerBuffer PolyStates;\n\
#else\n\
uniform highp isampler2D PolyStates;\n\
#endif\n\
uniform mediump int polyIndex;\n\
uniform bool polyDrawShadow;\n\
\n\
out vec2 vtxTexCoord;\n\
out vec4 vtxColor;\n\
flat out lowp int polyID;\n\
flat out lowp int polyMode;\n\
flat out lowp int polyIsWireframe;\n\
flat out lowp int polyEnableFog;\n\
flat out lowp int polySetNewDepthForTranslucent;\n\
flat out lowp int polyEnableTexture;\n\
flat out lowp int texSingleBitAlpha;\n\
flat out lowp int polyIsBackFacing;\n\
flat out lowp int isPolyDrawable;\n\
\n\
void main()\n\
{\n\
#if IS_USING_UBO_POLY_STATES\n\
ivec4 polyStateVec = polyState.value[polyIndex >> 2];\n\
int polyStateBits = polyStateVec[polyIndex & 0x03];\n\
#elif IS_USING_TBO_POLY_STATES\n\
int polyStateBits = texelFetch(PolyStates, polyIndex).r;\n\
#else\n\
int polyStateBits = texelFetch(PolyStates, ivec2(polyIndex & 0x00FF, (polyIndex >> 8) & 0x007F), 0).r;\n\
#endif\n\
int texSizeShiftS = (polyStateBits >> 18) & 0x07;\n\
int texSizeShiftT = (polyStateBits >> 21) & 0x07;\n\
\n\
float polyAlpha = float((polyStateBits >> 8) & 0x1F) / 31.0;\n\
vec2 polyTexScale = vec2(1.0 / float(8 << texSizeShiftS), 1.0 / float(8 << texSizeShiftT));\n\
\n\
polyID = (polyStateBits >> 0) & 0x3F;\n\
polyMode = (polyStateBits >> 6) & 0x03;\n\
polyIsWireframe = (polyStateBits >> 13) & 0x01;\n\
polyEnableFog = (polyStateBits >> 14) & 0x01;\n\
polySetNewDepthForTranslucent = (polyStateBits >> 15) & 0x01;\n\
polyEnableTexture = (polyStateBits >> 16) & 0x01;\n\
texSingleBitAlpha = (polyStateBits >> 17) & 0x01;\n\
polyIsBackFacing = (polyStateBits >> 24) & 0x01;\n\
\n\
isPolyDrawable = int((polyMode != 3) || polyDrawShadow);\n\
\n\
mat2 texScaleMtx = mat2( vec2(polyTexScale.x, 0.0), \n\
vec2( 0.0, polyTexScale.y)); \n\
\n\
vtxTexCoord = (texScaleMtx * inTexCoord0) / 16.0;\n\
vtxColor = vec4(inColor / 63.0, polyAlpha);\n\
gl_Position = vec4(inPosition.x, -inPosition.y, inPosition.z, inPosition.w) / 4096.0;\n\
}\n\
"};
// Fragment shader for geometry, GLSL ES 3.00
static const char *GeometryFragShader_ES300 = {"\
in vec2 vtxTexCoord;\n\
in vec4 vtxColor;\n\
flat in lowp int polyID;\n\
flat in lowp int polyMode;\n\
flat in lowp int polyIsWireframe;\n\
flat in lowp int polyEnableFog;\n\
flat in lowp int polySetNewDepthForTranslucent;\n\
flat in lowp int polyEnableTexture;\n\
flat in lowp int texSingleBitAlpha;\n\
flat in lowp int polyIsBackFacing;\n\
flat in lowp int isPolyDrawable;\n\
\n\
layout (std140) uniform RenderStates\n\
{\n\
bool enableAntialiasing;\n\
bool enableFogAlphaOnly;\n\
int clearPolyID;\n\
float clearDepth;\n\
float alphaTestRef;\n\
float fogOffset;\n\
float fogStep;\n\
float pad_0;\n\
vec4 fogColor;\n\
vec4 edgeColor[8];\n\
vec4 toonColor[32];\n\
} state;\n\
\n\
uniform sampler2D texRenderObject;\n\
uniform bool texDrawOpaque;\n\
uniform bool drawModeDepthEqualsTest;\n\
uniform bool polyDrawShadow;\n\
uniform float polyDepthOffset;\n\
\n\
OUT_COLOR vec4 outFragColor;\n\
\n\
#if DRAW_MODE_OPAQUE\n\
OUT_WORKING_BUFFER vec4 outDstBackFacing;\n\
#elif USE_DEPTH_LEQUAL_POLYGON_FACING\n\
uniform sampler2D inDstBackFacing;\n\
#endif\n\
\n\
#if ENABLE_EDGE_MARK\n\
OUT_POLY_ID vec4 outPolyID;\n\
#endif\n\
#if ENABLE_FOG\n\
OUT_FOG_ATTRIBUTES vec4 outFogAttributes;\n\
#endif\n\
\n\
void main()\n\
{\n\
#if USE_DEPTH_LEQUAL_POLYGON_FACING && !DRAW_MODE_OPAQUE\n\
bool isOpaqueDstBackFacing = bool( texelFetch(inDstBackFacing, ivec2(gl_FragCoord.xy), 0).r );\n\
if ( drawModeDepthEqualsTest && (bool(polyIsBackFacing) || !isOpaqueDstBackFacing) )\n\
{\n\
discard;\n\
}\n\
#endif\n\
\n\
vec4 mainTexColor = (ENABLE_TEXTURE_SAMPLING && bool(polyEnableTexture)) ? texture(texRenderObject, vtxTexCoord) : vec4(1.0, 1.0, 1.0, 1.0);\n\
\n\
if (!bool(texSingleBitAlpha))\n\
{\n\
if (texDrawOpaque)\n\
{\n\
if ( (polyMode != 1) && (mainTexColor.a <= 0.999) )\n\
{\n\
discard;\n\
}\n\
}\n\
else\n\
{\n\
if ( ((polyMode != 1) && (mainTexColor.a * vtxColor.a > 0.999)) || ((polyMode == 1) && (vtxColor.a > 0.999)) )\n\
{\n\
discard;\n\
}\n\
}\n\
}\n\
#if USE_TEXTURE_SMOOTHING\n\
else\n\
{\n\
if (mainTexColor.a < 0.500)\n\
{\n\
mainTexColor.a = 0.0;\n\
}\n\
else\n\
{\n\
mainTexColor.rgb = mainTexColor.rgb / mainTexColor.a;\n\
mainTexColor.a = 1.0;\n\
}\n\
}\n\
#endif\n\
\n\
outFragColor = mainTexColor * vtxColor;\n\
\n\
if (polyMode == 1)\n\
{\n\
outFragColor.rgb = (ENABLE_TEXTURE_SAMPLING && bool(polyEnableTexture)) ? mix(vtxColor.rgb, mainTexColor.rgb, mainTexColor.a) : vtxColor.rgb;\n\
outFragColor.a = vtxColor.a;\n\
}\n\
else if (polyMode == 2)\n\
{\n\
vec3 newToonColor = state.toonColor[int((vtxColor.r * 31.0) + 0.5)].rgb;\n\
#if TOON_SHADING_MODE\n\
outFragColor.rgb = min((mainTexColor.rgb * vtxColor.r) + newToonColor.rgb, 1.0);\n\
#else\n\
outFragColor.rgb = mainTexColor.rgb * newToonColor.rgb;\n\
#endif\n\
}\n\
else if ((polyMode == 3) && polyDrawShadow)\n\
{\n\
outFragColor = vtxColor;\n\
}\n\
\n\
if ( (isPolyDrawable != 0) && ((outFragColor.a < 0.001) || (ENABLE_ALPHA_TEST && outFragColor.a < state.alphaTestRef)) )\n\
{\n\
discard;\n\
}\n\
#if ENABLE_EDGE_MARK\n\
outPolyID = (isPolyDrawable != 0) ? vec4( float(polyID)/63.0, float(polyIsWireframe == 1), 0.0, float(outFragColor.a > 0.999) ) : vec4(0.0, 0.0, 0.0, 0.0);\n\
#endif\n\
#if ENABLE_FOG\n\
outFogAttributes = (isPolyDrawable != 0) ? vec4( float(polyEnableFog), 0.0, 0.0, float((outFragColor.a > 0.999) ? 1.0 : 0.5) ) : vec4(0.0, 0.0, 0.0, 0.0);\n\
#endif\n\
#if DRAW_MODE_OPAQUE\n\
outDstBackFacing = vec4(float(polyIsBackFacing), 0.0, 0.0, 1.0);\n\
#endif\n\
\n\
#if USE_NDS_DEPTH_CALCULATION || ENABLE_FOG\n\
// It is tempting to perform the NDS depth calculation in the vertex shader rather than in the fragment shader.\n\
// Resist this temptation! It is much more reliable to do the depth calculation in the fragment shader due to\n\
// subtle interpolation differences between various GPUs and/or drivers. If the depth calculation is not done\n\
// here, then it is very possible for the user to experience Z-fighting in certain rendering situations.\n\
\n\
#if ENABLE_W_DEPTH\n\
gl_FragDepth = clamp( ((1.0/gl_FragCoord.w) * (4096.0/16777215.0)) + polyDepthOffset, 0.0, 1.0 );\n\
#else\n\
// hack: when using z-depth, drop some LSBs so that the overworld map in Dragon Quest IV shows up correctly\n\
gl_FragDepth = clamp( (floor(gl_FragCoord.z * 4194303.0) * (4.0/16777215.0)) + polyDepthOffset, 0.0, 1.0 );\n\
#endif\n\
#endif\n\
}\n\
"};
void OGLLoadEntryPoints_ES_3_0()
{
OGLLoadEntryPoints_3_2();
}
void OGLCreateRenderer_ES_3_0(OpenGLRenderer **rendererPtr)
{
if (IsOpenGLDriverVersionSupported(3, 0, 0))
{
*rendererPtr = new OpenGLESRenderer_3_0;
(*rendererPtr)->SetVersion(3, 0, 0);
}
}
OpenGLESRenderer_3_0::OpenGLESRenderer_3_0()
{
_variantID = OpenGLVariantID_ES3_3_0;
_geometryDrawBuffersEnum = GeometryDrawBuffersEnumES;
_geometryAttachmentWorkingBuffer = GeometryAttachmentWorkingBufferES;
_geometryAttachmentPolyID = GeometryAttachmentPolyIDES;
_geometryAttachmentFogAttributes = GeometryAttachmentFogAttributesES;
ref->textureSrcTypeCIColor = GL_UNSIGNED_BYTE;
ref->textureSrcTypeCIFog = GL_UNSIGNED_BYTE;
ref->textureSrcTypeEdgeColor = GL_UNSIGNED_BYTE;
ref->textureSrcTypeToonTable = GL_UNSIGNED_BYTE;
}
Render3DError OpenGLESRenderer_3_0::InitExtensions()
{
OGLRenderRef &OGLRef = *this->ref;
Render3DError error = OGLERROR_NOERR;
// Get OpenGL extensions
std::set<std::string> oglExtensionSet;
this->GetExtensionSet(&oglExtensionSet);
// OpenGL ES 3.0 should fully support FBOs, so we don't need the default framebuffer.
// However, OpenGL ES has traditionally required some kind of surface buffer attached
// to the context before using it. We don't want it, nor would we ever use it here.
// Therefore, check if our context supports being surfaceless before doing anything else,
// as this works as a kind of compatibility check.
if (!this->IsExtensionPresent(&oglExtensionSet, "GL_OES_surfaceless_context"))
{
INFO("OpenGL ES: Client contexts are not expected to have any surfaces attached\n");
INFO(" to the default framebuffer. The fact that the context does not\n");
INFO(" work surfaceless may indicate an error in the context creation,\n");
INFO(" or that your platform's context creation is too old.\n");
error = OGLERROR_FEATURE_UNSUPPORTED;
return error;
}
// Mirrored Repeat Mode Support
OGLRef.stateTexMirroredRepeat = GL_MIRRORED_REPEAT;
// Blending Support
this->_isBlendFuncSeparateSupported = true;
this->_isBlendEquationSeparateSupported = true;
// Fixed locations in shaders are supported in ES 3.0 by default.
this->_isShaderFixedLocationSupported = true;
GLfloat maxAnisotropyOGL = 1.0f;
glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &maxAnisotropyOGL);
this->_deviceInfo.maxAnisotropy = (float)maxAnisotropyOGL;
// OpenGL ES 3.0 should be able to handle the GL_RGBA format in glReadPixels without any performance penalty.
OGLRef.readPixelsBestFormat = GL_RGBA;
OGLRef.readPixelsBestDataType = GL_UNSIGNED_BYTE;
this->_deviceInfo.isEdgeMarkSupported = true;
this->_deviceInfo.isFogSupported = true;
// Need to generate this texture first because FBO creation needs it.
// This texture is only required by shaders, and so if shader creation
// fails, then we can immediately delete this texture if an error occurs.
glGenTextures(1, &OGLRef.texFinalColorID);
glActiveTexture(GL_TEXTURE0 + OGLTextureUnitID_FinalColor);
glBindTexture(GL_TEXTURE_2D, OGLRef.texFinalColorID);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, (GLsizei)this->_framebufferWidth, (GLsizei)this->_framebufferHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
glActiveTexture(GL_TEXTURE0);
// OpenGL ES 3.0 should have all the necessary features to be able to flip and convert the framebuffer.
this->_willConvertFramebufferOnGPU = true;
this->_enableTextureSmoothing = CommonSettings.GFX3D_Renderer_TextureSmoothing;
this->_emulateShadowPolygon = CommonSettings.OpenGL_Emulation_ShadowPolygon;
this->_emulateSpecialZeroAlphaBlending = CommonSettings.OpenGL_Emulation_SpecialZeroAlphaBlending;
this->_emulateNDSDepthCalculation = CommonSettings.OpenGL_Emulation_NDSDepthCalculation;
this->_emulateDepthLEqualPolygonFacing = CommonSettings.OpenGL_Emulation_DepthLEqualPolygonFacing;
// Load and create shaders. Return on any error, since ES 3.0 makes shaders mandatory.
this->isShaderSupported = true;
this->_rsResource = new OpenGLRenderStatesResource();
if (IsOpenGLDriverVersionSupported(3, 2, 0))
{
this->_gResource = new OpenGLGeometryResource(OpenGLVariantID_ES3_3_2);
}
else if (IsOpenGLDriverVersionSupported(3, 1, 0))
{
this->_gResource = new OpenGLGeometryResource(OpenGLVariantID_ES3_3_1);
}
else
{
this->_gResource = new OpenGLGeometryResource(OpenGLVariantID_ES3_3_0);
}
error = this->CreateGeometryPrograms();
if (error != OGLERROR_NOERR)
{
glUseProgram(0);
this->DestroyGeometryPrograms();
this->isShaderSupported = false;
return error;
}
error = this->CreateClearImageProgram(ClearImageVtxShader_150, ClearImageFragShader_150);
if (error != OGLERROR_NOERR)
{
glUseProgram(0);
this->DestroyGeometryPrograms();
this->isShaderSupported = false;
return error;
}
error = this->CreateGeometryZeroDstAlphaProgram(GeometryZeroDstAlphaPixelMaskVtxShader_150, GeometryZeroDstAlphaPixelMaskFragShader_150);
if (error != OGLERROR_NOERR)
{
glUseProgram(0);
this->DestroyGeometryPrograms();
this->DestroyClearImageProgram();
this->isShaderSupported = false;
return error;
}
INFO("OpenGL ES: Successfully created geometry shaders.\n");
error = this->InitPostprocessingPrograms(EdgeMarkVtxShader_150,
EdgeMarkFragShader_150,
FramebufferOutputVtxShader_150,
FramebufferOutput6665FragShader_150,
NULL);
if (error != OGLERROR_NOERR)
{
glUseProgram(0);
this->DestroyGeometryPrograms();
this->DestroyClearImageProgram();
this->DestroyGeometryZeroDstAlphaProgram();
this->isShaderSupported = false;
return error;
}
this->isVBOSupported = true;
this->CreateVBOs();
// PBOs are only used when reading back the rendered framebuffer for the emulated
// BG0 layer. For desktop-class GPUs, doing an asynchronous glReadPixels() call
// is always advantageous since such devices are expected to have their GPUs
// connected to a data bus.
//
// However, many ARM-based mobile devices use integrated GPUs of varying degrees
// of memory latency and implementation quality. This means that the performance
// of an asynchronous glReadPixels() call is NOT guaranteed on such devices.
//
// In fact, many ARM-based devices suffer devastating performance drops when trying
// to do asynchronous framebuffer reads. Therefore, since most OpenGL ES users will
// be running an ARM-based iGPU, we will disable PBOs for OpenGL ES and stick with
// a traditional synchronous glReadPixels() call instead.
this->isPBOSupported = false;
this->isVAOSupported = true;
this->CreateVAOs();
// Load and create FBOs. Return on any error, since OpenGL ES 3.0 includes FBOs as core functionality.
this->isFBOSupported = true;
error = this->CreateFBOs();
if (error != OGLERROR_NOERR)
{
this->isFBOSupported = false;
return error;
}
this->_isFBOBlitSupported = true;
this->isMultisampledFBOSupported = true;
this->_selectedMultisampleSize = CommonSettings.GFX3D_Renderer_MultisampleSize;
GLint maxSamplesOGL = 0;
glGetIntegerv(GL_MAX_SAMPLES, &maxSamplesOGL);
this->_deviceInfo.maxSamples = (u8)maxSamplesOGL;
if (this->_deviceInfo.maxSamples >= 2)
{
// Try and initialize the multisampled FBOs with the GFX3D_Renderer_MultisampleSize.
// However, if the client has this set to 0, then set sampleSize to 2 in order to
// force the generation and the attachments of the buffers at a meaningful sample
// size. If GFX3D_Renderer_MultisampleSize is 0, then we can deallocate the buffer
// memory afterwards.
GLsizei sampleSize = this->GetLimitedMultisampleSize();
if (sampleSize == 0)
{
sampleSize = 2;
}
error = this->CreateMultisampledFBO(sampleSize);
if (error != OGLERROR_NOERR)
{
this->isMultisampledFBOSupported = false;
}
// If GFX3D_Renderer_MultisampleSize is 0, then we can deallocate the buffers now
// in order to save some memory.
if (this->_selectedMultisampleSize == 0)
{
this->ResizeMultisampledFBOs(0);
}
}
else
{
this->isMultisampledFBOSupported = false;
INFO("OpenGL ES: Driver does not support at least 2x multisampled FBOs.\n");
}
this->_isDepthLEqualPolygonFacingSupported = true;
this->_enableMultisampledRendering = ((this->_selectedMultisampleSize >= 2) && this->isMultisampledFBOSupported);
return OGLERROR_NOERR;
}
Render3DError OpenGLESRenderer_3_0::CreateGeometryPrograms()
{
Render3DError error = OGLERROR_NOERR;
OGLRenderRef &OGLRef = *this->ref;
// Create shader resources.
glGenTextures(1, &OGLRef.texFogDensityTableID);
glActiveTexture(GL_TEXTURE0 + OGLTextureUnitID_LookupTable);
glBindTexture(GL_TEXTURE_2D, OGLRef.texFogDensityTableID);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexImage2D(GL_TEXTURE_2D, 0, GL_R8, 32, 1, 0, GL_RED, GL_UNSIGNED_BYTE, NULL);
glActiveTexture(GL_TEXTURE0);
OGLGeometryFlags programFlags;
programFlags.value = 0;
std::stringstream shaderHeader;
shaderHeader << "#version 300 es\n";
shaderHeader << "precision highp float;\n";
shaderHeader << "precision highp int;\n";
shaderHeader << "\n";
std::stringstream vsHeader;
vsHeader << "#define IN_VTX_POSITION layout (location = " << OGLVertexAttributeID_Position << ") in\n";
vsHeader << "#define IN_VTX_TEXCOORD0 layout (location = " << OGLVertexAttributeID_TexCoord0 << ") in\n";
vsHeader << "#define IN_VTX_COLOR layout (location = " << OGLVertexAttributeID_Color << ") in\n";
vsHeader << "\n";
vsHeader << "#define IS_USING_UBO_POLY_STATES " << ((this->_gResource->IsPolyStatesBufferUBO()) ? 1 : 0) << "\n";
vsHeader << "#define IS_USING_TBO_POLY_STATES " << ((this->_gResource->IsPolyStatesBufferTBO()) ? 1 : 0) << "\n";
vsHeader << "#define DEPTH_EQUALS_TEST_TOLERANCE " << DEPTH_EQUALS_TEST_TOLERANCE << ".0\n";
vsHeader << "\n";
std::string vtxShaderCode = shaderHeader.str() + vsHeader.str() + std::string(GeometryVtxShader_ES300);
for (size_t flagsValue = 0; flagsValue < 128; flagsValue++, programFlags.value++)
{
std::stringstream shaderFlags;
shaderFlags << "#define OUT_COLOR layout (location = 0) out\n";
shaderFlags << "#define OUT_WORKING_BUFFER layout (location = " << (OGL_WORKING_ATTACHMENT_ID - GL_COLOR_ATTACHMENT0) << ") out\n";
shaderFlags << "#define OUT_POLY_ID layout (location = " << (OGL_POLYID_ATTACHMENT_ID - GL_COLOR_ATTACHMENT0) << ") out\n";
shaderFlags << "#define OUT_FOG_ATTRIBUTES layout (location = " << (OGL_FOGATTRIBUTES_ATTACHMENT_ID - GL_COLOR_ATTACHMENT0) << ") out\n";
shaderFlags << "\n";
shaderFlags << "#define USE_TEXTURE_SMOOTHING " << ((this->_enableTextureSmoothing) ? 1 : 0) << "\n";
shaderFlags << "#define USE_NDS_DEPTH_CALCULATION " << ((this->_emulateNDSDepthCalculation) ? 1 : 0) << "\n";
shaderFlags << "#define USE_DEPTH_LEQUAL_POLYGON_FACING " << ((this->_emulateDepthLEqualPolygonFacing) ? 1 : 0) << "\n";
shaderFlags << "\n";
shaderFlags << "#define ENABLE_W_DEPTH " << ((programFlags.EnableWDepth) ? 1 : 0) << "\n";
shaderFlags << "#define ENABLE_ALPHA_TEST " << ((programFlags.EnableAlphaTest) ? "true\n" : "false\n");
shaderFlags << "#define ENABLE_TEXTURE_SAMPLING " << ((programFlags.EnableTextureSampling) ? "true\n" : "false\n");
shaderFlags << "#define TOON_SHADING_MODE " << ((programFlags.ToonShadingMode) ? 1 : 0) << "\n";
shaderFlags << "#define ENABLE_FOG " << ((programFlags.EnableFog) ? 1 : 0) << "\n";
shaderFlags << "#define ENABLE_EDGE_MARK " << ((programFlags.EnableEdgeMark) ? 1 : 0) << "\n";
shaderFlags << "#define DRAW_MODE_OPAQUE " << ((programFlags.OpaqueDrawMode) ? 1 : 0) << "\n";
shaderFlags << "\n";
std::string fragShaderCode = shaderHeader.str() + shaderFlags.str() + std::string(GeometryFragShader_ES300);
error = this->ShaderProgramCreate(OGLRef.vertexGeometryShaderID,
OGLRef.fragmentGeometryShaderID[flagsValue],
OGLRef.programGeometryID[flagsValue],
vtxShaderCode.c_str(),
fragShaderCode.c_str());
if (error != OGLERROR_NOERR)
{
INFO("OpenGL ES: Failed to create the GEOMETRY shader program.\n");
glUseProgram(0);
this->DestroyGeometryPrograms();
return error;
}
glLinkProgram(OGLRef.programGeometryID[flagsValue]);
if (!this->ValidateShaderProgramLink(OGLRef.programGeometryID[flagsValue]))
{
INFO("OpenGL ES: Failed to link the GEOMETRY shader program.\n");
glUseProgram(0);
this->DestroyGeometryPrograms();
return OGLERROR_SHADER_CREATE_ERROR;
}
glValidateProgram(OGLRef.programGeometryID[flagsValue]);
glUseProgram(OGLRef.programGeometryID[flagsValue]);
// Set up render states UBO
const GLuint uniformBlockRenderStates = glGetUniformBlockIndex(OGLRef.programGeometryID[flagsValue], "RenderStates");
glUniformBlockBinding(OGLRef.programGeometryID[flagsValue], uniformBlockRenderStates, OGLBindingPointID_RenderStates);
GLint uboSize = 0;
glGetActiveUniformBlockiv(OGLRef.programGeometryID[flagsValue], uniformBlockRenderStates, GL_UNIFORM_BLOCK_DATA_SIZE, &uboSize);
assert(uboSize == sizeof(OGLRenderStates));
const GLint uniformTexRenderObject = glGetUniformLocation(OGLRef.programGeometryID[flagsValue], "texRenderObject");
glUniform1i(uniformTexRenderObject, 0);
if (this->_gResource->IsPolyStatesBufferUBO())
{
const GLuint uniformBlockPolyStates = glGetUniformBlockIndex(OGLRef.programGeometryID[flagsValue], "PolyStates");
glUniformBlockBinding(OGLRef.programGeometryID[flagsValue], uniformBlockPolyStates, OGLBindingPointID_PolyStates);
}
else
{
const GLint uniformTexBufferPolyStates = glGetUniformLocation(OGLRef.programGeometryID[flagsValue], "PolyStates");
glUniform1i(uniformTexBufferPolyStates, OGLTextureUnitID_PolyStates);
}
if (this->_emulateDepthLEqualPolygonFacing && !programFlags.OpaqueDrawMode)
{
const GLint uniformTexBackfacing = glGetUniformLocation(OGLRef.programGeometryID[flagsValue], "inDstBackFacing");
glUniform1i(uniformTexBackfacing, OGLTextureUnitID_FinalColor);
}
OGLRef.uniformTexDrawOpaque[flagsValue] = glGetUniformLocation(OGLRef.programGeometryID[flagsValue], "texDrawOpaque");
OGLRef.uniformDrawModeDepthEqualsTest[flagsValue] = glGetUniformLocation(OGLRef.programGeometryID[flagsValue], "drawModeDepthEqualsTest");
OGLRef.uniformPolyDrawShadow[flagsValue] = glGetUniformLocation(OGLRef.programGeometryID[flagsValue], "polyDrawShadow");
OGLRef.uniformPolyStateIndex[flagsValue] = glGetUniformLocation(OGLRef.programGeometryID[flagsValue], "polyIndex");
OGLRef.uniformPolyDepthOffset[flagsValue] = glGetUniformLocation(OGLRef.programGeometryID[flagsValue], "polyDepthOffset");
}
return error;
}
Render3DError OpenGLESRenderer_3_0::CreateClearImageProgram(const char *vsCString, const char *fsCString)
{
Render3DError error = OGLERROR_NOERR;
OGLRenderRef &OGLRef = *this->ref;
std::stringstream shaderHeader;
shaderHeader << "#version 300 es\n";
shaderHeader << "precision highp float;\n";
shaderHeader << "precision highp int;\n";
shaderHeader << "\n";
std::stringstream vsHeader;
if (this->_isShaderFixedLocationSupported)
{
vsHeader << "#define IN_VTX_POSITION layout (location = " << OGLVertexAttributeID_Position << ") in\n";
vsHeader << "#define IN_VTX_TEXCOORD0 layout (location = " << OGLVertexAttributeID_TexCoord0 << ") in\n";
}
else
{
vsHeader << "#define IN_VTX_POSITION in\n";
vsHeader << "#define IN_VTX_TEXCOORD0 in\n";
}
vsHeader << "\n";
std::string vtxShaderCode = shaderHeader.str() + vsHeader.str() + std::string(vsCString);
std::stringstream fsHeader;
if (this->_isShaderFixedLocationSupported)
{
fsHeader << "#define OUT_COLOR layout (location = 0) out\n";
fsHeader << "#define OUT_FOGATTR layout (location = 1) out\n";
}
else
{
fsHeader << "#define OUT_COLOR out\n";
fsHeader << "#define OUT_FOGATTR out\n";
}
fsHeader << "\n";
std::string fragShaderCodeFogColor = shaderHeader.str() + fsHeader.str() + std::string(fsCString);
error = this->ShaderProgramCreate(OGLRef.vsClearImageID,
OGLRef.fsClearImageID,
OGLRef.pgClearImageID,
vtxShaderCode.c_str(),
fragShaderCodeFogColor.c_str());
if (error != OGLERROR_NOERR)
{
INFO("OpenGL ES: Failed to create the CLEAR_IMAGE shader program.\n");
glUseProgram(0);
this->DestroyClearImageProgram();
return error;
}
glLinkProgram(OGLRef.pgClearImageID);
if (!this->ValidateShaderProgramLink(OGLRef.pgClearImageID))
{
INFO("OpenGL ES: Failed to link the CLEAR_IMAGE shader color/fog program.\n");
glUseProgram(0);
this->DestroyClearImageProgram();
return OGLERROR_SHADER_CREATE_ERROR;
}
glValidateProgram(OGLRef.pgClearImageID);
glUseProgram(OGLRef.pgClearImageID);
const GLint uniformTexCIColor = glGetUniformLocation(OGLRef.pgClearImageID, "texCIColor");
const GLint uniformTexCIFogAttr = glGetUniformLocation(OGLRef.pgClearImageID, "texCIFogAttr");
const GLint uniformTexCIDepthCF = glGetUniformLocation(OGLRef.pgClearImageID, "texCIDepth");
glUniform1i(uniformTexCIColor, OGLTextureUnitID_CIColor);
glUniform1i(uniformTexCIFogAttr, OGLTextureUnitID_CIFogAttr);
glUniform1i(uniformTexCIDepthCF, OGLTextureUnitID_CIDepth);
return error;
}
Render3DError OpenGLESRenderer_3_0::CreateGeometryZeroDstAlphaProgram(const char *vtxShaderCString, const char *fragShaderCString)
{
Render3DError error = OGLERROR_NOERR;
OGLRenderRef &OGLRef = *this->ref;
if ( (vtxShaderCString == NULL) || (fragShaderCString == NULL) )
{
return error;
}
std::stringstream shaderHeader;
shaderHeader << "#version 300 es\n";
shaderHeader << "precision highp float;\n";
shaderHeader << "precision highp int;\n";
shaderHeader << "\n";
std::stringstream vsHeader;
vsHeader << "#define IN_VTX_POSITION layout (location = " << OGLVertexAttributeID_Position << ") in\n";
vsHeader << "#define IN_VTX_TEXCOORD0 layout (location = " << OGLVertexAttributeID_TexCoord0 << ") in\n";
vsHeader << "#define IN_VTX_COLOR layout (location = " << OGLVertexAttributeID_Color << ") in\n";
std::string vtxShaderCode = shaderHeader.str() + vsHeader.str() + std::string(vtxShaderCString);
std::string fragShaderCode = shaderHeader.str() + std::string(fragShaderCString);
error = this->ShaderProgramCreate(OGLRef.vtxShaderGeometryZeroDstAlphaID,
OGLRef.fragShaderGeometryZeroDstAlphaID,
OGLRef.programGeometryZeroDstAlphaID,
vtxShaderCode.c_str(),
fragShaderCode.c_str());
if (error != OGLERROR_NOERR)
{
INFO("OpenGL ES: Failed to create the GEOMETRY ZERO DST ALPHA shader program.\n");
glUseProgram(0);
this->DestroyGeometryZeroDstAlphaProgram();
return error;
}
glLinkProgram(OGLRef.programGeometryZeroDstAlphaID);
if (!this->ValidateShaderProgramLink(OGLRef.programGeometryZeroDstAlphaID))
{
INFO("OpenGL ES: Failed to link the GEOMETRY ZERO DST ALPHA shader program.\n");
glUseProgram(0);
this->DestroyGeometryZeroDstAlphaProgram();
return OGLERROR_SHADER_CREATE_ERROR;
}
glValidateProgram(OGLRef.programGeometryZeroDstAlphaID);
glUseProgram(OGLRef.programGeometryZeroDstAlphaID);
const GLint uniformTexGColor = glGetUniformLocation(OGLRef.programGeometryZeroDstAlphaID, "texInFragColor");
glUniform1i(uniformTexGColor, OGLTextureUnitID_GColor);
return OGLERROR_NOERR;
}
Render3DError OpenGLESRenderer_3_0::CreateEdgeMarkProgram(const bool isMultisample, const char *vtxShaderCString, const char *fragShaderCString)
{
Render3DError error = OGLERROR_NOERR;
OGLRenderRef &OGLRef = *this->ref;
if ( (vtxShaderCString == NULL) || (fragShaderCString == NULL) )
{
return error;
}
std::stringstream shaderHeader;
shaderHeader << "#version 300 es\n";
shaderHeader << "precision highp float;\n";
shaderHeader << "precision highp int;\n";
shaderHeader << "\n";
shaderHeader << "#define FRAMEBUFFER_SIZE_X " << this->_framebufferWidth << ".0 \n";
shaderHeader << "#define FRAMEBUFFER_SIZE_Y " << this->_framebufferHeight << ".0 \n";
shaderHeader << "\n";
std::stringstream vsHeader;
vsHeader << "#define IN_VTX_POSITION layout (location = " << OGLVertexAttributeID_Position << ") in\n";
vsHeader << "#define IN_VTX_TEXCOORD0 layout (location = " << OGLVertexAttributeID_TexCoord0 << ") in\n";
vsHeader << "#define IN_VTX_COLOR layout (location = " << OGLVertexAttributeID_Color << ") in\n";
std::stringstream fsHeader;
fsHeader << "#define OUT_COLOR layout (location = 0) out\n";
std::string vtxShaderCode = shaderHeader.str() + vsHeader.str() + std::string(vtxShaderCString);
std::string fragShaderCode = shaderHeader.str() + fsHeader.str() + std::string(fragShaderCString);
error = this->ShaderProgramCreate(OGLRef.vertexEdgeMarkShaderID,
OGLRef.fragmentEdgeMarkShaderID,
OGLRef.programEdgeMarkID,
vtxShaderCode.c_str(),
fragShaderCode.c_str());
if (error != OGLERROR_NOERR)
{
INFO("OpenGL ES: Failed to create the EDGE MARK shader program.\n");
glUseProgram(0);
this->DestroyEdgeMarkProgram();
return error;
}
glLinkProgram(OGLRef.programEdgeMarkID);
if (!this->ValidateShaderProgramLink(OGLRef.programEdgeMarkID))
{
INFO("OpenGL ES: Failed to link the EDGE MARK shader program.\n");
glUseProgram(0);
this->DestroyEdgeMarkProgram();
return OGLERROR_SHADER_CREATE_ERROR;
}
glValidateProgram(OGLRef.programEdgeMarkID);
glUseProgram(OGLRef.programEdgeMarkID);
const GLuint uniformBlockRenderStates = glGetUniformBlockIndex(OGLRef.programEdgeMarkID, "RenderStates");
glUniformBlockBinding(OGLRef.programEdgeMarkID, uniformBlockRenderStates, OGLBindingPointID_RenderStates);
const GLint uniformTexGDepth = glGetUniformLocation(OGLRef.programEdgeMarkID, "texInFragDepth");
const GLint uniformTexGPolyID = glGetUniformLocation(OGLRef.programEdgeMarkID, "texInPolyID");
glUniform1i(uniformTexGDepth, OGLTextureUnitID_DepthStencil);
glUniform1i(uniformTexGPolyID, OGLTextureUnitID_GPolyID);
return OGLERROR_NOERR;
}
Render3DError OpenGLESRenderer_3_0::CreateFogProgram(const OGLFogProgramKey fogProgramKey, const bool isMultisample, const char *vtxShaderCString, const char *fragShaderCString)
{
Render3DError error = OGLERROR_NOERR;
OGLRenderRef &OGLRef = *this->ref;
if (vtxShaderCString == NULL)
{
INFO("OpenGL ES: The FOG vertex shader is unavailable.\n");
error = OGLERROR_VERTEX_SHADER_PROGRAM_LOAD_ERROR;
return error;
}
else if (fragShaderCString == NULL)
{
INFO("OpenGL ES: The FOG fragment shader is unavailable.\n");
error = OGLERROR_FRAGMENT_SHADER_PROGRAM_LOAD_ERROR;
return error;
}
const s32 fogOffset = fogProgramKey.offset;
const GLfloat fogOffsetf = (GLfloat)fogOffset / 32767.0f;
const s32 fogStep = 0x0400 >> fogProgramKey.shift;
std::stringstream shaderHeader;
shaderHeader << "#version 300 es\n";
shaderHeader << "precision highp float;\n";
shaderHeader << "precision highp int;\n";
shaderHeader << "\n";
std::stringstream vsHeader;
vsHeader << "#define IN_VTX_POSITION layout (location = " << OGLVertexAttributeID_Position << ") in\n";
vsHeader << "#define IN_VTX_TEXCOORD0 layout (location = " << OGLVertexAttributeID_TexCoord0 << ") in\n";
vsHeader << "#define IN_VTX_COLOR layout (location = " << OGLVertexAttributeID_Color << ") in\n";
std::stringstream fsHeader;
fsHeader << "#define FOG_OFFSET " << fogOffset << "\n";
fsHeader << "#define FOG_OFFSETF " << fogOffsetf << (((fogOffsetf == 0.0f) || (fogOffsetf == 1.0f)) ? ".0" : "") << "\n";
fsHeader << "#define FOG_STEP " << fogStep << "\n";
fsHeader << "\n";
fsHeader << "#define OUT_COLOR layout (location = 0) out\n";
std::string vtxShaderCode = shaderHeader.str() + vsHeader.str() + std::string(vtxShaderCString);
std::string fragShaderCode = shaderHeader.str() + fsHeader.str() + std::string(fragShaderCString);
OGLFogShaderID shaderID;
shaderID.program = 0;
shaderID.fragShader = 0;
error = this->ShaderProgramCreate(OGLRef.vertexFogShaderID,
shaderID.fragShader,
shaderID.program,
vtxShaderCode.c_str(),
fragShaderCode.c_str());
this->_fogProgramMap[fogProgramKey.key] = shaderID;
if (error != OGLERROR_NOERR)
{
INFO("OpenGL ES: Failed to create the FOG shader program.\n");
glUseProgram(0);
this->DestroyFogProgram(fogProgramKey);
return error;
}
glLinkProgram(shaderID.program);
if (!this->ValidateShaderProgramLink(shaderID.program))
{
INFO("OpenGL ES: Failed to link the FOG shader program.\n");
glUseProgram(0);
this->DestroyFogProgram(fogProgramKey);
return OGLERROR_SHADER_CREATE_ERROR;
}
glValidateProgram(shaderID.program);
glUseProgram(shaderID.program);
const GLuint uniformBlockRenderStates = glGetUniformBlockIndex(shaderID.program, "RenderStates");
glUniformBlockBinding(shaderID.program, uniformBlockRenderStates, OGLBindingPointID_RenderStates);
const GLint uniformTexGDepth = glGetUniformLocation(shaderID.program, "texInFragDepth");
const GLint uniformTexGFog = glGetUniformLocation(shaderID.program, "texInFogAttributes");
const GLint uniformTexFogDensityTable = glGetUniformLocation(shaderID.program, "texFogDensityTable");
glUniform1i(uniformTexGDepth, OGLTextureUnitID_DepthStencil);
glUniform1i(uniformTexGFog, OGLTextureUnitID_FogAttr);
glUniform1i(uniformTexFogDensityTable, OGLTextureUnitID_LookupTable);
return OGLERROR_NOERR;
}
Render3DError OpenGLESRenderer_3_0::CreateFramebufferOutput6665Program(const char *vtxShaderCString, const char *fragShaderCString)
{
Render3DError error = OGLERROR_NOERR;
OGLRenderRef &OGLRef = *this->ref;
if ( (vtxShaderCString == NULL) || (fragShaderCString == NULL) )
{
return error;
}
std::stringstream shaderHeader;
shaderHeader << "#version 300 es\n";
shaderHeader << "precision highp float;\n";
shaderHeader << "precision highp int;\n";
shaderHeader << "\n";
shaderHeader << "#define FRAMEBUFFER_SIZE_X " << this->_framebufferWidth << ".0 \n";
shaderHeader << "#define FRAMEBUFFER_SIZE_Y " << this->_framebufferHeight << ".0 \n";
shaderHeader << "\n";
std::stringstream vsHeader;
vsHeader << "#define IN_VTX_POSITION layout (location = " << OGLVertexAttributeID_Position << ") in\n";
vsHeader << "#define IN_VTX_TEXCOORD0 layout (location = " << OGLVertexAttributeID_TexCoord0 << ") in\n";
vsHeader << "#define IN_VTX_COLOR layout (location = " << OGLVertexAttributeID_Color << ") in\n";
std::stringstream fsHeader;
fsHeader << "#define OUT_COLOR layout (location = " << (OGL_WORKING_ATTACHMENT_ID - GL_COLOR_ATTACHMENT0) << ") out\n";
std::string vtxShaderCode = shaderHeader.str() + vsHeader.str() + std::string(vtxShaderCString);
std::string fragShaderCode = shaderHeader.str() + fsHeader.str() + std::string(fragShaderCString);
error = this->ShaderProgramCreate(OGLRef.vertexFramebufferOutput6665ShaderID,
OGLRef.fragmentFramebufferRGBA6665OutputShaderID,
OGLRef.programFramebufferRGBA6665OutputID,
vtxShaderCode.c_str(),
fragShaderCode.c_str());
if (error != OGLERROR_NOERR)
{
INFO("OpenGL ES: Failed to create the FRAMEBUFFER OUTPUT RGBA6665 shader program.\n");
glUseProgram(0);
this->DestroyFramebufferOutput6665Programs();
return error;
}
glLinkProgram(OGLRef.programFramebufferRGBA6665OutputID);
if (!this->ValidateShaderProgramLink(OGLRef.programFramebufferRGBA6665OutputID))
{
INFO("OpenGL ES: Failed to link the FRAMEBUFFER OUTPUT RGBA6665 shader program.\n");
glUseProgram(0);
this->DestroyFramebufferOutput6665Programs();
return OGLERROR_SHADER_CREATE_ERROR;
}
glValidateProgram(OGLRef.programFramebufferRGBA6665OutputID);
glUseProgram(OGLRef.programFramebufferRGBA6665OutputID);
const GLint uniformTexGColor = glGetUniformLocation(OGLRef.programFramebufferRGBA6665OutputID, "texInFragColor");
glUniform1i(uniformTexGColor, OGLTextureUnitID_GColor);
return OGLERROR_NOERR;
}

View File

@ -1,59 +0,0 @@
/*
Copyright (C) 2024 DeSmuME team
This file is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
This file is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with the this software. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef OGLRENDER_ES3_H
#define OGLRENDER_ES3_H
#include "OGLRender_3_2.h"
// A port that wants to use the OpenGL ES renderer must assign the two following functions
// to OGLLoadEntryPoints_ES_3_0_Func and OGLCreateRenderer_ES_3_0_Func, respectively.
//
// In addition, the port must add the following GPU3DInterface objects to core3DList:
// - gpu3Dgl_ES_3_0: Selects the OpenGL ES 3.0 renderer, and returns an error if it is
// not available on the host system.
//
// Finally, the port must call GPU->Set3DRendererByID() and pass in the index where
// gpu3Dgl_ES_3_0 exists in core3DList so that the emulator can create the appropriate
// OpenGLRenderer object.
//
// Example code:
// OGLLoadEntryPoints_ES_3_0_Func = &OGLLoadEntryPoints_ES_3_0;
// OGLCreateRenderer_ES_3_0_Func = &OGLCreateRenderer_ES_3_0;
// GPU3DInterface *core3DList[] = { &gpu3DNull, &gpu3DRasterize, &gpu3Dgl_ES_3_0, NULL };
// GPU->Set3DRendererByID(2);
void OGLLoadEntryPoints_ES_3_0();
void OGLCreateRenderer_ES_3_0(OpenGLRenderer **rendererPtr);
class OpenGLESRenderer_3_0 : public OpenGLRenderer_3_2
{
protected:
virtual Render3DError CreateGeometryPrograms();
virtual Render3DError CreateClearImageProgram(const char *vsCString, const char *fsCString);
virtual Render3DError CreateGeometryZeroDstAlphaProgram(const char *vtxShaderCString, const char *fragShaderCString);
virtual Render3DError CreateEdgeMarkProgram(const bool isMultisample, const char *vtxShaderCString, const char *fragShaderCString);
virtual Render3DError CreateFogProgram(const OGLFogProgramKey fogProgramKey, const bool isMultisample, const char *vtxShaderCString, const char *fragShaderCString);
virtual Render3DError CreateFramebufferOutput6665Program(const char *vtxShaderCString, const char *fragShaderCString);
public:
OpenGLESRenderer_3_0();
virtual Render3DError InitExtensions();
};
#endif // OGLRENDER_ES3_H

View File

@ -1,3 +0,0 @@
#ifndef __GNUC__
#pragma pack(pop)
#endif

View File

@ -1,375 +0,0 @@
/*
Copyright 2007 Guillaume Duhamel
Copyright 2007-2017 DeSmuME team
This file is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
This file is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with the this software. If not, see <http://www.gnu.org/licenses/>.
*/
#include "ROMReader.h"
#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>
#ifdef HAVE_LIBZZIP
#include <zzip/zzip.h>
#endif
#include "utils/xstring.h"
#ifdef WIN32
#define stat(...) _stat(__VA_ARGS__)
#define S_IFMT _S_IFMT
#define S_IFREG _S_IFREG
#endif
ROMReader_struct * ROMReaderInit(char ** filename)
{
#ifdef HAVE_LIBZ
if(!strcasecmp(".gz", *filename + (strlen(*filename) - 3)))
{
(*filename)[strlen(*filename) - 3] = '\0';
return &GZIPROMReader;
}
#endif
#ifdef HAVE_LIBZZIP
if (!strcasecmp(".zip", *filename + (strlen(*filename) - 4)))
{
(*filename)[strlen(*filename) - 4] = '\0';
return &ZIPROMReader;
}
#endif
return &STDROMReader;
}
void * STDROMReaderInit(const char * filename);
void STDROMReaderDeInit(void *);
u32 STDROMReaderSize(void *);
int STDROMReaderSeek(void *, int, int);
int STDROMReaderRead(void *, void *, u32);
int STDROMReaderWrite(void *, void *, u32);
ROMReader_struct STDROMReader =
{
ROMREADER_STD,
"Standard ROM Reader",
STDROMReaderInit,
STDROMReaderDeInit,
STDROMReaderSize,
STDROMReaderSeek,
STDROMReaderRead,
STDROMReaderWrite
};
struct STDROMReaderData
{
FILE* file;
long pos;
};
void* STDROMReaderInit(const char* filename)
{
#ifndef _MSC_VER
struct stat sb;
if (stat(filename, &sb) == -1)
return 0;
if ((sb.st_mode & S_IFMT) != S_IFREG)
return 0;
#endif
#ifdef WIN32
FILE* inf = _wfopen(mbstowcs((std::string)filename).c_str(),L"rb");
#else
FILE* inf = fopen(filename, "rb");
#endif
if(!inf) return NULL;
STDROMReaderData* ret = new STDROMReaderData();
ret->file = inf;
ret->pos = 0;
return (void*)ret;
}
void STDROMReaderDeInit(void * file)
{
if (!file) return ;
fclose(((STDROMReaderData*)file)->file);
delete ((STDROMReaderData*)file);
}
u32 STDROMReaderSize(void * file)
{
u32 size;
if (!file) return 0;
FILE* inf = ((STDROMReaderData*)file)->file;
fseek(inf, 0, SEEK_END);
size = ftell(inf);
fseek(inf, ((STDROMReaderData*)file)->pos, SEEK_SET);
return size;
}
int STDROMReaderSeek(void * file, int offset, int whence)
{
//not normal fseek return value meanings. awesome.
if (!file) return 0;
if(whence == SEEK_SET && offset == ((STDROMReaderData*)file)->pos)
return 1;
fseek(((STDROMReaderData*)file)->file, offset, whence);
((STDROMReaderData*)file)->pos = ftell(((STDROMReaderData*)file)->file);
return 1;
}
int STDROMReaderRead(void * file, void * buffer, u32 size)
{
if (!file) return 0;
int read = fread(buffer, 1, size, ((STDROMReaderData*)file)->file);
((STDROMReaderData*)file)->pos += read;
return read;
}
int STDROMReaderWrite(void *, void *, u32)
{
//not supported, for now
return 0;
}
#ifdef HAVE_LIBZ
void * GZIPROMReaderInit(const char * filename);
void GZIPROMReaderDeInit(void *);
u32 GZIPROMReaderSize(void *);
int GZIPROMReaderSeek(void *, int, int);
int GZIPROMReaderRead(void *, void *, u32);
int GZIPROMReaderWrite(void *, void *, u32);
ROMReader_struct GZIPROMReader =
{
ROMREADER_GZIP,
"Gzip ROM Reader",
GZIPROMReaderInit,
GZIPROMReaderDeInit,
GZIPROMReaderSize,
GZIPROMReaderSeek,
GZIPROMReaderRead,
GZIPROMReaderWrite
};
void * GZIPROMReaderInit(const char * filename)
{
return (void*)gzopen(filename, "rb");
}
void GZIPROMReaderDeInit(void * file)
{
gzclose((gzFile)file);
}
u32 GZIPROMReaderSize(void * file)
{
char useless[1024];
u32 size = 0;
/* FIXME this function should first save the current
* position and restore it after size calculation */
gzrewind((gzFile)file);
while (gzeof ((gzFile)file) == 0)
size += gzread((gzFile)file, useless, 1024);
gzrewind((gzFile)file);
return size;
}
int GZIPROMReaderSeek(void * file, int offset, int whence)
{
return gzseek((gzFile)file, offset, whence);
}
int GZIPROMReaderRead(void * file, void * buffer, u32 size)
{
return gzread((gzFile)file, buffer, size);
}
int GZIPROMReaderWrite(void *, void *, u32)
{
//not supported, ever
return 0;
}
#endif
#ifdef HAVE_LIBZZIP
void * ZIPROMReaderInit(const char * filename);
void ZIPROMReaderDeInit(void *);
u32 ZIPROMReaderSize(void *);
int ZIPROMReaderSeek(void *, int, int);
int ZIPROMReaderRead(void *, void *, u32);
int ZIPROMReaderWrite(void *, void *, u32);
ROMReader_struct ZIPROMReader =
{
ROMREADER_ZIP,
"Zip ROM Reader",
ZIPROMReaderInit,
ZIPROMReaderDeInit,
ZIPROMReaderSize,
ZIPROMReaderSeek,
ZIPROMReaderRead,
ZIPROMReaderWrite
};
void * ZIPROMReaderInit(const char * filename)
{
ZZIP_DIR * dir = zzip_opendir(filename);
ZZIP_DIRENT * dirent = zzip_readdir(dir);
if (dir != NULL)
{
char *tmp1;
char tmp2[1024];
memset(tmp2,0,sizeof(tmp2));
tmp1 = strndup(filename, strlen(filename) - 4);
sprintf(tmp2, "%s/%s", tmp1, dirent->d_name);
free(tmp1);
return zzip_fopen(tmp2, "rb");
}
return NULL;
}
void ZIPROMReaderDeInit(void * file)
{
zzip_close((ZZIP_FILE*)file);
}
u32 ZIPROMReaderSize(void * file)
{
u32 size;
zzip_seek((ZZIP_FILE*)file, 0, SEEK_END);
size = zzip_tell((ZZIP_FILE*)file);
zzip_seek((ZZIP_FILE*)file, 0, SEEK_SET);
return size;
}
int ZIPROMReaderSeek(void * file, int offset, int whence)
{
return zzip_seek((ZZIP_FILE*)file, offset, whence);
}
int ZIPROMReaderRead(void * file, void * buffer, u32 size)
{
#ifdef ZZIP_OLD_READ
return zzip_read((ZZIP_FILE*)file, (char *) buffer, size);
#else
return zzip_read((ZZIP_FILE*)file, buffer, size);
#endif
}
int ZIPROMReaderWrite(void *, void *, u32)
{
//not supported ever
return 0;
}
#endif
struct {
void* buf;
int len;
int pos;
} mem;
void * MemROMReaderInit(const char * filename)
{
return NULL; //dummy
}
void MemROMReaderDeInit(void *)
{
//nothing to do
}
u32 MemROMReaderSize(void *)
{
return (u32)mem.len;
}
int MemROMReaderSeek(void * file, int offset, int whence)
{
switch(whence) {
case SEEK_SET:
mem.pos = offset;
break;
case SEEK_CUR:
mem.pos += offset;
break;
case SEEK_END:
mem.pos = mem.len + offset;
break;
}
return mem.pos;
}
int MemROMReaderRead(void * file, void * buffer, u32 size)
{
if(mem.pos<0) return 0;
int todo = (int)size;
int remain = mem.len - mem.pos;
if(remain<todo)
todo = remain;
if(todo<=0)
return 0;
else if(todo==1) *(u8*)buffer = ((u8*)mem.buf)[mem.pos];
else memcpy(buffer,(u8*)mem.buf + mem.pos, todo);
mem.pos += todo;
return todo;
}
int MemROMReaderWrite(void * file, void * buffer, u32 size)
{
if(mem.pos<0) return 0;
int todo = (int)size;
int remain = mem.len - mem.pos;
if(remain<todo)
todo = remain;
if (todo == 1) ((u8*)mem.buf)[mem.pos] = *(u8*)buffer;
else memcpy((u8*)mem.buf + mem.pos,buffer, todo);
mem.pos += todo;
return todo;
}
static ROMReader_struct MemROMReader =
{
ROMREADER_MEM,
"Memory ROM Reader",
MemROMReaderInit,
MemROMReaderDeInit,
MemROMReaderSize,
MemROMReaderSeek,
MemROMReaderRead,
MemROMReaderWrite,
};
ROMReader_struct * MemROMReaderRead_TrueInit(void* buf, int length)
{
mem.buf = buf;
mem.len = length;
mem.pos = 0;
return &MemROMReader;
}

View File

@ -1,58 +0,0 @@
/*
Copyright (C) 2007 Guillaume Duhamel
Copyright (C) 2007-2022 DeSmuME team
This file is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
This file is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with the this software. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _ROMREADER_H_
#define _ROMREADER_H_
#ifdef HAVE_LIBZ
#include <zlib.h>
#endif
#include <string.h>
#include "types.h"
#define ROMREADER_DEFAULT -1
#define ROMREADER_STD 0
#define ROMREADER_GZIP 1
#define ROMREADER_ZIP 2
#define ROMREADER_MEM 3
typedef struct
{
int id;
const char * Name;
void * (*Init)(const char * filename);
void (*DeInit)(void * file);
u32 (*Size)(void * file);
int (*Seek)(void * file, int offset, int whence);
int (*Read)(void * file, void * buffer, u32 size);
int (*Write)(void * file, void * buffer, u32 size);
} ROMReader_struct;
extern ROMReader_struct STDROMReader;
#ifdef HAVE_LIBZ
extern ROMReader_struct GZIPROMReader;
#endif
#ifdef HAVE_LIBZZIP
extern ROMReader_struct ZIPROMReader;
#endif
ROMReader_struct * ROMReaderInit(char ** filename);
ROMReader_struct * MemROMReaderRead_TrueInit(void* buf, int length);
#endif // _ROMREADER_H_

File diff suppressed because it is too large Load Diff

View File

@ -1,305 +0,0 @@
/*
Copyright 2006 Theo Berkau
Copyright (C) 2006-2015 DeSmuME team
This file is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
This file is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with the this software. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef SPU_H
#define SPU_H
#include <iosfwd>
#include <string>
#include <assert.h>
#include <stdio.h>
#include "types.h"
#include "matrix.h"
#include "metaspu/metaspu.h"
class EMUFILE;
#define SNDCORE_DEFAULT -1
#define SNDCORE_DUMMY 0
#define CHANSTAT_STOPPED 0
#define CHANSTAT_PLAY 1
#define SPUINTERPOLATION_TAPS 4 // Must be at least 4 for Catmull-Rom interpolation
//who made these static? theyre used in multiple places.
FORCEINLINE s32 spumuldiv7(s32 val, u8 multiplier) {
assert(multiplier <= 127);
return (multiplier == 127) ? val : ((val * multiplier) >> 7);
}
enum SPUInterpolationMode
{
SPUInterpolation_None = 0,
SPUInterpolation_Linear = 1,
SPUInterpolation_Cosine = 2,
SPUInterpolation_CatmullRom = 3
};
struct SoundInterface_struct
{
int id;
const char *Name;
int (*Init)(int buffersize);
void (*DeInit)();
void (*UpdateAudio)(s16 *buffer, u32 num_samples);
u32 (*GetAudioSpace)();
void (*MuteAudio)();
void (*UnMuteAudio)();
void (*SetVolume)(int volume);
void (*ClearBuffer)();
void (*FetchSamples)(s16 *sampleBuffer, size_t sampleCount, ESynchMode synchMode, ISynchronizingAudioBuffer *theSynchronizer);
size_t (*PostProcessSamples)(s16 *postProcessBuffer, size_t requestedSampleCount, ESynchMode synchMode, ISynchronizingAudioBuffer *theSynchronizer);
};
extern SoundInterface_struct SNDDummy;
extern SoundInterface_struct SNDFile;
extern int SPU_currentCoreNum;
struct channel_struct
{
channel_struct() : num(0),
vol(0),
volumeDiv(0),
hold(0),
pan(0),
waveduty(0),
repeat(0),
format(0),
keyon(0),
status(0),
pcm16bOffs(0),
addr(0),
timer(0),
loopstart(0),
length(0),
totlength(0),
totlength_shifted(0),
sampcntFrac(0),
sampcntInt(0),
sampincFrac(0),
sampincInt(0),
loop_pcm16b(0),
index(0),
loop_index(0),
x(0)
{}
u32 num;
u8 vol;
u8 volumeDiv;
u8 hold;
u8 pan;
u8 waveduty;
u8 repeat;
u8 format;
u8 keyon;
u8 status;
u8 pcm16bOffs;
u32 addr;
u16 timer;
u16 loopstart;
u32 length;
u32 totlength;
s32 totlength_shifted;
u32 sampcntFrac;
s32 sampcntInt;
u32 sampincFrac;
u32 sampincInt;
s16 pcm16b[SPUINTERPOLATION_TAPS];
// ADPCM specific
s16 loop_pcm16b;
s32 index;
int loop_index;
// PSG noise
u16 x;
};
class SPUFifo
{
public:
SPUFifo();
void enqueue(s16 val);
s16 dequeue();
s16 buffer[16];
s32 head,tail,size;
void save(EMUFILE &fp);
bool load(EMUFILE &fp);
void reset();
};
class SPU_struct
{
public:
SPU_struct(int buffersize);
u32 bufpos;
u32 buflength;
s32 *sndbuf;
s32 lastdata; //the last sample that a channel generated
s16 *outbuf;
u32 bufsize;
channel_struct channels[16];
//registers
struct REGS {
REGS()
: mastervol(0)
, ctl_left(0)
, ctl_right(0)
, ctl_ch1bypass(0)
, ctl_ch3bypass(0)
, masteren(0)
, soundbias(0)
{}
u8 mastervol;
u8 ctl_left, ctl_right;
u8 ctl_ch1bypass, ctl_ch3bypass;
u8 masteren;
u16 soundbias;
enum LeftOutputMode
{
LOM_LEFT_MIXER=0, LOM_CH1=1, LOM_CH3=2, LOM_CH1_PLUS_CH3=3
};
enum RightOutputMode
{
ROM_RIGHT_MIXER=0, ROM_CH1=1, ROM_CH3=2, ROM_CH1_PLUS_CH3=3
};
struct CAP {
CAP()
: add(0), source(0), oneshot(0), bits8(0), active(0), dad(0), len(0)
{}
u8 add, source, oneshot, bits8, active;
u32 dad;
u16 len;
struct Runtime {
Runtime()
: running(0), curdad(0), maxdad(0)
{}
u8 running;
u32 curdad;
u32 maxdad;
u32 sampcntFrac;
u32 sampcntInt;
SPUFifo fifo;
} runtime;
} cap[2];
} regs;
void reset();
~SPU_struct();
void KeyOff(int channel);
void KeyOn(int channel);
void KeyProbe(int channel);
void ProbeCapture(int which);
void WriteByte(u32 addr, u8 val);
void WriteWord(u32 addr, u16 val);
void WriteLong(u32 addr, u32 val);
u8 ReadByte(u32 addr);
u16 ReadWord(u32 addr);
u32 ReadLong(u32 addr);
bool isSPU(u32 addr) { return ((addr >= 0x04000400) && (addr < 0x04000520)); }
//kills all channels but leaves SPU otherwise running normally
void ShutUp();
};
extern SPU_struct *SPU_core, *SPU_user;
extern int spu_core_samples;
int SPU_ChangeSoundCore(int coreid, int newBufferSizeBytes);
SoundInterface_struct *SPU_SoundCore();
void SPU_ReInit(bool fakeBoot = false);
int SPU_Init(int coreid, int newBufferSizeBytes);
void SPU_Pause(int pause);
void SPU_SetVolume(int newVolume);
void SPU_SetSynchMode(int mode, int method);
void SPU_ClearOutputBuffer(void);
void SPU_Reset(void);
void SPU_DeInit(void);
void SPU_KeyOn(int channel);
static FORCEINLINE void SPU_WriteByte(u32 addr, u8 val)
{
addr &= 0xFFF;
SPU_core->WriteByte(addr,val);
if(SPU_user)
SPU_user->WriteByte(addr,val);
}
static FORCEINLINE void SPU_WriteWord(u32 addr, u16 val)
{
addr &= 0xFFF;
SPU_core->WriteWord(addr,val);
if(SPU_user)
SPU_user->WriteWord(addr,val);
}
static FORCEINLINE void SPU_WriteLong(u32 addr, u32 val)
{
addr &= 0xFFF;
SPU_core->WriteLong(addr,val);
if(SPU_user)
SPU_user->WriteLong(addr,val);
}
static FORCEINLINE u8 SPU_ReadByte(u32 addr) { return SPU_core->ReadByte(addr & 0x0FFF); }
static FORCEINLINE u16 SPU_ReadWord(u32 addr) { return SPU_core->ReadWord(addr & 0x0FFF); }
static FORCEINLINE u32 SPU_ReadLong(u32 addr) { return SPU_core->ReadLong(addr & 0x0FFF); }
void SPU_Emulate_core(void);
void SPU_Emulate_user(bool mix = true);
void SPU_DefaultFetchSamples(s16 *sampleBuffer, size_t sampleCount, ESynchMode synchMode, ISynchronizingAudioBuffer *theSynchronizer);
size_t SPU_DefaultPostProcessSamples(s16 *postProcessBuffer, size_t requestedSampleCount, ESynchMode synchMode, ISynchronizingAudioBuffer *theSynchronizer);
void spu_savestate(EMUFILE &os);
bool spu_loadstate(EMUFILE &is, int size);
enum WAVMode
{
WAVMODE_ANY = -1,
WAVMODE_CORE = 0,
WAVMODE_USER = 1
};
class WavWriter
{
public:
WavWriter();
bool open(const std::string & fname);
void close();
void update(void* soundData, int numSamples);
bool isRecording() const;
WAVMode mode;
private:
FILE *spufp;
};
void WAV_End();
bool WAV_Begin(const char* fname, WAVMode mode=WAVMODE_CORE);
bool WAV_IsRecording(WAVMode mode=WAVMODE_ANY);
void WAV_WavSoundUpdate(void* soundData, int numSamples, WAVMode mode=WAVMODE_CORE);
// we should make this configurable eventually
// but at least defining it somewhere is probably a step in the right direction
#define DESMUME_SAMPLE_RATE 44100
//#define DESMUME_SAMPLE_RATE 48000
#endif

View File

@ -1,35 +0,0 @@
/*
Copyright (C) 2010-2015 DeSmuME team
This file is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
This file is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with the this software. If not, see <http://www.gnu.org/licenses/>.
*/
#include "../slot1.h"
class Slot1_None : public ISlot1Interface
{
public:
virtual Slot1Info const* info()
{
static Slot1InfoSimple info("None","Slot1 no-card emulation", 0xFF);
return &info;
}
//pretty much every access to the card should just be ignored and reading HIGH-Z off the GC bus.
//so, nothing really to do here
//(notably, it results in a 0xFFFFFFFF card ID)
};
ISlot1Interface* construct_Slot1_None() { return new Slot1_None(); }

View File

@ -1,236 +0,0 @@
/*
Copyright (C) 2010-2021 DeSmuME team
This file is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
This file is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with the this software. If not, see <http://www.gnu.org/licenses/>.
*/
#include "slot1comp_protocol.h"
#include <time.h>
#include "../slot1.h"
#include "../NDSSystem.h"
#include "../emufile.h"
class Slot1_R4 : public ISlot1Interface, public ISlot1Comp_Protocol_Client
{
private:
EMUFILE *img;
Slot1Comp_Protocol protocol;
u32 write_count;
u32 write_enabled;
public:
Slot1_R4()
: img(NULL)
, write_count(0)
, write_enabled(0)
{
}
virtual Slot1Info const* info()
{
static Slot1InfoSimple info("R4", "Slot1 R4 emulation", 0x03);
return &info;
}
virtual void connect()
{
img = slot1_GetFatImage();
if(!img)
INFO("slot1 fat not successfully mounted\n");
protocol.reset(this);
protocol.chipId = 0xFC2;
protocol.gameCode = T1ReadLong((u8*)gameInfo.header.gameCode,0);
}
//called when the emulator disconnects the device
virtual void disconnect()
{
img = NULL;
}
//called when the emulator shuts down, or when the device disappears from existence
virtual void shutdown()
{
}
virtual void write_command(u8 PROCNUM, GC_Command command)
{
protocol.write_command(command);
}
virtual void write_GCDATAIN(u8 PROCNUM, u32 val)
{
protocol.write_GCDATAIN(PROCNUM, val);
}
virtual u32 read_GCDATAIN(u8 PROCNUM)
{
return protocol.read_GCDATAIN(PROCNUM);
}
virtual void slot1client_startOperation(eSlot1Operation theOperation)
{
if (theOperation != eSlot1Operation_Unknown)
return;
u32 address;
int cmd = protocol.command.bytes[0];
switch(cmd)
{
case 0xB0:
break;
case 0xB9:
case 0xBA:
address = (protocol.command.bytes[1] << 24) | (protocol.command.bytes[2] << 16) | (protocol.command.bytes[3] << 8) | protocol.command.bytes[4];
img->fseek(address,SEEK_SET);
break;
case 0xBB:
write_enabled = 1;
write_count = 0x80;
//passthrough on purpose?
case 0xBC:
address = (protocol.command.bytes[1] << 24) | (protocol.command.bytes[2] << 16) | (protocol.command.bytes[3] << 8) | protocol.command.bytes[4];
img->fseek(address,SEEK_SET);
break;
}
}
virtual u32 slot1client_read_GCDATAIN(eSlot1Operation theOperation)
{
if (theOperation != eSlot1Operation_Unknown)
return 0;
u32 val = 0;
int cmd = protocol.command.bytes[0];
switch (cmd)
{
case 0xB0:
val = (img != NULL) ? 0x1F4 : 0x1F2;
break;
case 0xB9:
val = (rand() % 100) ? (img) ? 0x1F4 : 0x1F2 : 0;
break;
case 0xBB:
case 0xBC:
val = 0;
break;
case 0xBA:
//INFO("Read from sd at sector %08X at adr %08X ",card.address/512,ftell(img));
img->read_32LE(val);
//INFO("val %08X\n",val);
break;
default:
val = 0;
break;
}
return val;
}
void slot1client_write_GCDATAIN(eSlot1Operation theOperation, u32 val)
{
if (theOperation != eSlot1Operation_Unknown)
return;
int cmd = protocol.command.bytes[0];
switch (cmd)
{
case 0xBB:
{
if (write_count && write_enabled)
{
img->write_32LE(val);
img->fflush();
write_count--;
}
break;
}
default:
break;
}
}
virtual void post_fakeboot(int PROCNUM)
{
// The BIOS leaves the card in NORMAL mode
protocol.mode = eCardMode_NORMAL;
}
void write32_GCDATAIN(u32 val)
{
//bool log = false;
//last_write_count = write_count;
//can someone tell me ... what the hell is this doing, anyway?
//seems odd to use card.command[4] for this... isnt it part of the address?
if (protocol.command.bytes[4])
{
// transfer is done
//are you SURE this is logical? there doesnt seem to be any way for the card to signal that
T1WriteLong(MMU.MMU_MEM[0][0x40], 0x1A4,val & 0x7F7FFFFF);
MMU_GC_endTransfer(0);
return;
}
int cmd = protocol.command.bytes[0];
switch (cmd)
{
case 0xBB:
{
if (write_count && write_enabled)
{
img->write_32LE(val);
img->fflush();
write_count--;
}
break;
}
default:
break;
}
if (write_count == 0)
{
write_enabled = 0;
//transfer is done
//are you SURE this is logical? there doesnt seem to be any way for the card to signal that
T1WriteLong(MMU.MMU_MEM[0][0x40], 0x1A4,val & 0x7F7FFFFF);
//but isnt this a different IRQ? IREQ_MC perhaps
MMU_GC_endTransfer(0);
}
/*if(log)
{
INFO("WRITE CARD command: %02X%02X%02X%02X%02X%02X%02X%02X\t",
card.command[0], card.command[1], card.command[2], card.command[3],
card.command[4], card.command[5], card.command[6], card.command[7]);
INFO("FROM: %08X\t", NDS_ARM9.instruct_adr);
INFO("VAL: %08X\n", val);
}*/
}
};
ISlot1Interface* construct_Slot1_R4() { return new Slot1_R4(); }

View File

@ -1,104 +0,0 @@
/*
Copyright (C) 2013-2015 DeSmuME team
This file is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
This file is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with the this software. If not, see <http://www.gnu.org/licenses/>.
*/
#include "../slot1.h"
#include "../NDSSystem.h"
class Slot1_Retail_Auto : public ISlot1Interface
{
private:
ISlot1Interface *mSelectedImplementation;
public:
Slot1_Retail_Auto()
: mSelectedImplementation(NULL)
{
}
virtual Slot1Info const* info()
{
static Slot1InfoSimple info("Retail (Auto)","Slot1 Retail (auto-selection) card emulation", 0xFE);
return &info;
}
virtual void connect()
{
NDS_SLOT1_TYPE selection = NDS_SLOT1_RETAIL_MCROM;
//check game ID in core emulator and select right implementation
//gamehack: definitely not a game hack, just a lazy way of selecting the right equipment for the game
if(gameInfo.IsCode("UOR") || // WarioWare - D.I.Y. (U)(E)(EUR) / Made in Ore (J)
gameInfo.IsCode("UXBP") || // Jam with the Band (EUR)
gameInfo.IsCode("AXBJ") // Daigassou! Band-Brothers DX (J)
)
selection = NDS_SLOT1_RETAIL_NAND;
slot1_selected_type = selection;
mSelectedImplementation = slot1_List[selection];
mSelectedImplementation->connect();
printf("Slot1 auto-selected device type: %s\n",mSelectedImplementation->info()->name());
}
virtual void disconnect()
{
if(mSelectedImplementation) mSelectedImplementation->disconnect();
mSelectedImplementation = NULL;
}
virtual void write_command(u8 PROCNUM, GC_Command command)
{
mSelectedImplementation->write_command(PROCNUM, command);
}
virtual void write_GCDATAIN(u8 PROCNUM, u32 val)
{
mSelectedImplementation->write_GCDATAIN(PROCNUM, val);
}
virtual u32 read_GCDATAIN(u8 PROCNUM)
{
return mSelectedImplementation->read_GCDATAIN(PROCNUM);
}
virtual u8 auxspi_transaction(int PROCNUM, u8 value)
{
return mSelectedImplementation->auxspi_transaction(PROCNUM, value);
}
virtual void auxspi_reset(int PROCNUM)
{
mSelectedImplementation->auxspi_reset(PROCNUM);
}
virtual void post_fakeboot(int PROCNUM)
{
mSelectedImplementation->post_fakeboot(PROCNUM);
}
virtual void savestate(EMUFILE &os)
{
mSelectedImplementation->savestate(os);
}
virtual void loadstate(EMUFILE &is)
{
mSelectedImplementation->loadstate(is);
}
};
ISlot1Interface* construct_Slot1_Retail_Auto() { return new Slot1_Retail_Auto(); }

View File

@ -1,107 +0,0 @@
/*
Copyright (C) 2010-2021 DeSmuME team
This file is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
This file is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with the this software. If not, see <http://www.gnu.org/licenses/>.
*/
#include "slot1comp_mc.h"
#include "slot1comp_rom.h"
#include "slot1comp_protocol.h"
#include "../slot1.h"
#include "../NDSSystem.h"
//quick architecture overview:
//MCROM receives GC bus commands from MMU.cpp
//those are passed on to the protocol component for parsing
//protocol calls back into MCROM via ISlot1Comp_Protocol_Client interface for things the protocol doesnt know about (the contents of the rom, chiefly)
//MCROM utilizes the rom component for address logic and delivering data
class Slot1_Retail_MCROM : public ISlot1Interface, public ISlot1Comp_Protocol_Client
{
private:
Slot1Comp_Protocol protocol;
Slot1Comp_Rom rom;
public:
virtual Slot1Info const* info()
{
static Slot1InfoSimple info("Retail MC+ROM", "Slot1 Retail MC+ROM (standard) card emulation", 0x01);
return &info;
}
virtual void connect()
{
protocol.reset(this);
protocol.chipId = gameInfo.chipID;
protocol.gameCode = T1ReadLong((u8*)gameInfo.header.gameCode,0);
g_Slot1Comp_MC.connect();
}
virtual u8 auxspi_transaction(int PROCNUM, u8 value)
{
return g_Slot1Comp_MC.auxspi_transaction(PROCNUM,value);
}
virtual void auxspi_reset(int PROCNUM)
{
g_Slot1Comp_MC.auxspi_reset(PROCNUM);
}
virtual void write_command(u8 PROCNUM, GC_Command command)
{
protocol.write_command(command);
}
virtual void write_GCDATAIN(u8 PROCNUM, u32 val)
{
protocol.write_GCDATAIN(PROCNUM, val);
}
virtual u32 read_GCDATAIN(u8 PROCNUM)
{
return protocol.read_GCDATAIN(PROCNUM);
}
virtual void slot1client_startOperation(eSlot1Operation theOperation)
{
rom.start(theOperation,protocol.address);
}
virtual void post_fakeboot(int PROCNUM)
{
// The BIOS leaves the card in NORMAL mode
protocol.mode = eCardMode_NORMAL;
}
virtual void savestate(EMUFILE &os)
{
protocol.savestate(os);
rom.savestate(os);
}
virtual void loadstate(EMUFILE &is)
{
protocol.loadstate(is);
rom.loadstate(is);
}
private:
u32 slot1client_read_GCDATAIN(eSlot1Operation operation)
{
return rom.read();
}
};
ISlot1Interface* construct_Slot1_Retail_MCROM() { return new Slot1_Retail_MCROM(); }

View File

@ -1,214 +0,0 @@
/*
Copyright (C) 2013-2021 DeSmuME team
This file is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
This file is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with the this software. If not, see <http://www.gnu.org/licenses/>.
*/
//This module implements a device which is capable of building a nitro FS on the fly
//(and REBUILDING it! -- Q: under what conditions?)
//so that you can test your homebrew games and patches without having to rebuild the ROM and restart it.
//Q. can it handle resized files?
#include "slot1comp_mc.h"
#include "slot1comp_rom.h"
#include "slot1comp_protocol.h"
#include <stdio.h>
#include <string>
#include "../slot1.h"
#include "../path.h"
#include "../NDSSystem.h"
#include "../utils/fsnitro.h"
class Slot1_Retail_DEBUG : public ISlot1Interface, public ISlot1Comp_Protocol_Client
{
private:
Slot1Comp_Protocol protocol;
Slot1Comp_Rom rom;
FILE *fpROM;
FS_NITRO *fs;
u16 curr_file_id;
std::string pathData;
public:
virtual Slot1Info const* info()
{
static Slot1InfoSimple info("Retail DEBUG","Slot1 Retail (standard) card emulation + FS Nitro DEBUG", 0x04);
return &info;
}
virtual void connect()
{
protocol.reset(this);
protocol.chipId = gameInfo.chipID;
protocol.gameCode = T1ReadLong((u8*)gameInfo.header.gameCode,0);
curr_file_id = 0xFFFF;
fpROM = NULL;
fs = NULL;
pathData = path.getpath(path.SLOT1D) + path.GetRomNameWithoutExtension();
printf("Path to Slot1 data: %s\n", pathData.c_str());
fs = new FS_NITRO();
fs->rebuildFAT(pathData);
}
virtual u8 auxspi_transaction(int PROCNUM, u8 value)
{
return g_Slot1Comp_MC.auxspi_transaction(PROCNUM,value);
}
virtual void auxspi_reset(int PROCNUM)
{
g_Slot1Comp_MC.auxspi_reset(PROCNUM);
}
virtual void write_command(u8 PROCNUM, GC_Command command)
{
protocol.write_command(command);
}
virtual void write_GCDATAIN(u8 PROCNUM, u32 val)
{
protocol.write_GCDATAIN(PROCNUM, val);
}
virtual u32 read_GCDATAIN(u8 PROCNUM)
{
return protocol.read_GCDATAIN(PROCNUM);
}
virtual void post_fakeboot(int PROCNUM)
{
// The BIOS leaves the card in NORMAL mode
protocol.mode = eCardMode_NORMAL;
}
virtual void savestate(EMUFILE &os)
{
protocol.savestate(os);
rom.savestate(os);
}
virtual void loadstate(EMUFILE &is)
{
protocol.loadstate(is);
rom.loadstate(is);
}
virtual void slot1client_startOperation(eSlot1Operation theOperation)
{
if (protocol.operation == eSlot1Operation_B7_Read)
{
u16 file_id = 0xFFFF; u32 offset = 0;
bool bFromFile = false;
if (fs && fs->isFAT(protocol.address))
{
fs->rebuildFAT(protocol.address, protocol.length, pathData);
}
else
{
if (fs && fs->getFileIdByAddr(protocol.address, file_id, offset))
{
if (file_id != curr_file_id)
{
std::string tmp = fs->getFullPathByFileID(file_id);
printf("%04X:[%08X, ofs %08X] %s\n", file_id, protocol.address, offset, tmp.c_str());
if (fpROM)
{
fclose(fpROM);
fpROM = NULL;
}
tmp = pathData + tmp;
fpROM = fopen(tmp.c_str(), "rb");
if (fpROM)
{
bFromFile = true;
printf("\t * found at disk, offset %08X\n", offset);
if (fseek(fpROM, offset, SEEK_SET) != 0)
{
printf("\t\t - ERROR seek file position\n");
}
}
}
else
{
if (fpROM)
{
bFromFile = true;
if (ftell(fpROM) != offset)
{
printf("\t * new file seek %08Xh\n", offset);
fseek(fpROM, offset, SEEK_SET);
}
}
}
}
}
if (!bFromFile && fpROM)
{
fclose(fpROM);
fpROM = NULL;
}
curr_file_id = file_id;
}
rom.start(theOperation, protocol.address);
}
private:
u32 slot1client_read_GCDATAIN(eSlot1Operation operation)
{
if (protocol.operation == eSlot1Operation_B7_Read)
{
u32 address = rom.getAddress();
if (fs && fs->isFAT(address))
{
u32 res = fs->getFATRecord(address);
if (res != 0xFFFFFFFF)
{
rom.incAddress();
return res;
}
}
else
if (fpROM)
{
u32 data = 0;
u32 readed = fread(&data, 1, 4, fpROM);
if (readed)
{
rom.incAddress();
if (readed < 4)
data |= ((u32)0xFFFFFFFF << (readed * 8));
return data;
}
fclose(fpROM);
fpROM = NULL;
}
}
return rom.read();
}
};
ISlot1Interface* construct_Slot1_Retail_DEBUG() { return new Slot1_Retail_DEBUG(); }

View File

@ -1,327 +0,0 @@
/*
Copyright (C) 2010-2021 DeSmuME team
This file is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
This file is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with the this software. If not, see <http://www.gnu.org/licenses/>.
*/
// Games with NAND Flash:
// Ore/WarioWare D.I.Y. - chip: SAMSUNG 004
// KLC2811ANB-P204
// NTR-UORE-0
// - 128Mbit
#include "slot1comp_rom.h"
#include "slot1comp_protocol.h"
#include "../slot1.h"
#include "../NDSSystem.h"
#include "../emufile.h"
//quick architecture overview:
//NAND receives GC bus commands from MMU.cpp
//those are passed on to the protocol component for parsing
//protocol calls back into NAND via ISlot1Comp_Protocol_Client interface for things the protocol doesn't know about (the contents of the rom, chiefly)
//NAND utilizes the rom component for address logic and delivering data.
//it also processes some commands itself which aren't rom-related (the NANDy stuff)
class Slot1_Retail_NAND : public ISlot1Interface, public ISlot1Comp_Protocol_Client
{
private:
u32 subAdr;
Slot1Comp_Protocol protocol;
Slot1Comp_Rom rom;
u32 mode;
u32 handle_save;
//current NAND read/write start position
//when this is changed, the read/write cursor will be reset to it
//when it is set to the same value, the read/write cursor will NOT be reset
//(this is since some value must necessarily come in on the protocol address, so the 'current save_start' is used as a special 'dont change' value
u32 save_start;
//current NAND read/write cursor
u32 save_adr;
public:
virtual Slot1Info const* info()
{
static Slot1InfoSimple info("Retail NAND","Slot1 retail NAND card emulation", 0x02);
return &info;
}
virtual void connect()
{
protocol.reset(this);
protocol.chipId = gameInfo.chipID;
protocol.gameCode = T1ReadLong((u8*)gameInfo.header.gameCode,0);
save_adr = 0;
handle_save = 0;
mode = 0;
subAdr = T1ReadWord(gameInfo.header.reserved2, 0x6) << 17;
}
virtual void write_command(u8 PROCNUM, GC_Command command)
{
protocol.write_command(command);
}
virtual void write_GCDATAIN(u8 PROCNUM, u32 val)
{
protocol.write_GCDATAIN(PROCNUM, val);
}
virtual u32 read_GCDATAIN(u8 PROCNUM)
{
return protocol.read_GCDATAIN(PROCNUM);
}
virtual void slot1client_startOperation(eSlot1Operation theOperation)
{
//INFO("Start command: %02X%02X%02X%02X%02X%02X%02X%02X\t",
// protocol.command.bytes[0], protocol.command.bytes[1], protocol.command.bytes[2], protocol.command.bytes[3],
// protocol.command.bytes[4], protocol.command.bytes[5], protocol.command.bytes[6], protocol.command.bytes[7]);
//INFO("FROM: %08X\n", NDS_ARM9.instruct_adr);
u32 addressFromProtocol = (protocol.command.bytes[1] << 24) | (protocol.command.bytes[2] << 16) | (protocol.command.bytes[3] << 8) | protocol.command.bytes[4];
//pass the normal rom operations along to the rom component
switch (theOperation)
{
case eSlot1Operation_00_ReadHeader_Unencrypted:
rom.start(theOperation, addressFromProtocol);
return;
case eSlot1Operation_2x_SecureAreaLoad:
rom.start(theOperation, protocol.address);
return;
default:
break;
}
//handle special commands ourselves
int cmd = protocol.command.bytes[0];
switch(cmd)
{
// Nand Init
case 0x94:
mode = cmd;
break;
// Nand Error?
case 0xD6:
break;
//Nand Write Page
case 0x81:
mode = cmd;
if(addressFromProtocol != save_start)
{
save_start = addressFromProtocol;
save_adr = (addressFromProtocol & gameInfo.mask) - subAdr;
}
handle_save = 1;
break;
case 0x84: //Write disable
case 0x85: //Write enable
mode = cmd;
break;
case 0x8B:
mode = cmd;
handle_save = 0;
MMU_new.backupDevice.flushBackup();
break;
//Start read mode
case 0xB7:
if (handle_save)
{
mode = cmd;
if(addressFromProtocol != save_start)
{
save_start = addressFromProtocol;
save_adr = (addressFromProtocol & gameInfo.mask) - subAdr;
}
}
else
{
rom.start(theOperation, addressFromProtocol);
}
break;
case 0xB2: //Set save position
mode = cmd;
save_start = addressFromProtocol;
//cursor resets regardless of whether save_start changed, that's what makes this special.
//the cursor could be reset to the beginning of the previous save_start region
save_adr = (addressFromProtocol & gameInfo.mask) - subAdr;
handle_save = 1;
break;
}
}
virtual u32 slot1client_read_GCDATAIN(eSlot1Operation operation)
{
//pass the normal rom operations along to the rom component
switch(operation)
{
case eSlot1Operation_00_ReadHeader_Unencrypted:
case eSlot1Operation_2x_SecureAreaLoad:
//case eSlot1Operation_B7_Read:
return rom.read();
default:
break;
}
//handle special commands ourselves
int cmd = protocol.command.bytes[0];
int val = 0;
switch(cmd)
{
// Nand Init?
case 0x94:
val = 0;
mode = 0;
break;
//Rom/Save Read
case 0xB7:
{
if(handle_save)
{
MMU_new.backupDevice.ensure(save_adr+4, (u8)0);
val = MMU_new.backupDevice.readLong(save_adr, 0);
save_adr += 4;
}
else
{
val = rom.read();
}
}
break;
// Nand Status?
case 0xD6:
//0x80 == busy
//0x40 == ??
//0x20 == ready?
//0x10 == write enabled?
switch (mode)
{
case 0x84: //Write disable
val = 0x20202020;
break;
case 0x85: //Write enable
val = 0x20202020 | 0x10101010;
break;
case 0x8B:
val = 0x60606060 | 0x10101010;
break;
case 0xB2: //Set save position
val = 0x20202020;
break;
default:
val = 0x60606060; //0x20 == ready
break;
}
break;
}
return val;
}
virtual void slot1client_write_GCDATAIN(eSlot1Operation operation, u32 val)
{
//pass the normal rom operations along to the rom component
switch(operation)
{
case eSlot1Operation_00_ReadHeader_Unencrypted:
case eSlot1Operation_B7_Read:
case eSlot1Operation_2x_SecureAreaLoad:
return;
default:
break;
}
//handle special commands ourselves
int cmd = protocol.command.bytes[0];
u32 value = val;
u32 adr = save_adr;
switch(cmd)
{
case 0x81: //Nand Write
MMU_new.backupDevice.ensure(adr+4, (u8)0);
MMU_new.backupDevice.writeLong(adr, val);
save_adr += 4;
break;
}
}
virtual void post_fakeboot(int PROCNUM)
{
// The BIOS leaves the card in NORMAL mode
protocol.mode = eCardMode_NORMAL;
}
virtual void savestate(EMUFILE &os)
{
s32 version = 0;
protocol.savestate(os);
rom.savestate(os);
os.write_32LE(version);
os.write_32LE(mode);
os.write_32LE(handle_save);
os.write_32LE(save_adr);
os.write_32LE(save_start);
os.write_32LE(subAdr);
}
virtual void loadstate(EMUFILE &is)
{
s32 version = 0;
protocol.loadstate(is);
rom.loadstate(is);
is.read_32LE(version);
// version 0
if (version >= 0)
{
is.read_32LE(mode);
is.read_32LE(handle_save);
is.read_32LE(save_adr);
is.read_32LE(save_start);
is.read_32LE(subAdr);
}
}
};
ISlot1Interface* construct_Slot1_Retail_NAND() { return new Slot1_Retail_NAND(); }

View File

@ -1,43 +0,0 @@
/*
Copyright (C) 2013-2017 DeSmuME team
This file is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
This file is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with the this software. If not, see <http://www.gnu.org/licenses/>.
*/
//this file contains the components used for emulating standard gamecard "MC" devices (eeprom, fram, flash)
//this is largely done by accessing the BackupDevice resources in the core emulator
#include "slot1comp_mc.h"
#include "../MMU.h"
#include "../NDSSystem.h"
Slot1Comp_MC g_Slot1Comp_MC;
u8 Slot1Comp_MC::auxspi_transaction(int PROCNUM, u8 value)
{
return MMU_new.backupDevice.data_command(value, PROCNUM);
}
void Slot1Comp_MC::auxspi_reset(int PROCNUM)
{
MMU_new.backupDevice.reset_command();
}
void Slot1Comp_MC::connect()
{
//gamehack: not really a game hack
if(gameInfo.IsCode("AXBJ"))
MMU_new.backupDevice.uninitializedValue = 0x00; // Daigassou! Band Brothers DX (JP)
}

View File

@ -1,35 +0,0 @@
/*
Copyright (C) 2013-2015 DeSmuME team
This file is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
This file is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with the this software. If not, see <http://www.gnu.org/licenses/>.
*/
//this file contains the components used for emulating standard gamecard "MC" devices (eeprom, fram, flash)
#ifndef _SLOT1COMP_MC_H
#define _SLOT1COMP_MC_H
#include "../types.h"
class Slot1Comp_MC
{
public:
u8 auxspi_transaction(int PROCNUM, u8 value);
void auxspi_reset(int PROCNUM);
void connect();
};
extern Slot1Comp_MC g_Slot1Comp_MC;
#endif

View File

@ -1,262 +0,0 @@
/*
Copyright (C) 2012-2021 DeSmuME team
This file is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
This file is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with the this software. If not, see <http://www.gnu.org/licenses/>.
*/
#include "slot1comp_protocol.h"
#include <string.h>
#include "../armcpu.h"
#include "../encrypt.h"
#include "../emufile.h"
#include "../utils/decrypt/decrypt.h"
static _KEY1 key1((const u8*)arm7_key);
void Slot1Comp_Protocol::reset(ISlot1Comp_Protocol_Client* theClient)
{
this->client = theClient;
//we have to initialize this to something.. lets use dummy.
//(need to clean this up...)
memcpy(&command,"\x9F\0\0\0\0\0\0\0",8);
operation = eSlot1Operation_9F_Dummy;
length = 0;
delay = 0;
mode = eCardMode_RAW;
}
void Slot1Comp_Protocol::write_command_RAW(GC_Command theCommand)
{
int cmd = theCommand.bytes[0];
if(cmd == 0x9F)
{
operation = eSlot1Operation_9F_Dummy;
length = 0x2000;
}
if(cmd == 0x90)
{
operation = eSlot1Operation_90_ChipID;
length = 4;
//we handle this operation ourselves
}
if(cmd == 0x3C)
{
//switch to KEY1
length = 0;
mode = eCardMode_KEY1;
//defer initialization of KEY1 until we know we need it, just to save some CPU time.
//TODO - some information about these parameters
//level == 2
//modulo == 8
key1.init(gameCode, 2, 0x08);
GCLOG("[GC] KEY1 ACTIVATED\n");
}
if(cmd == 0x00)
{
operation = eSlot1Operation_00_ReadHeader_Unencrypted;
client->slot1client_startOperation(operation);
}
}
void Slot1Comp_Protocol::write_command_KEY1(GC_Command theCommand)
{
//decrypt the KEY1-format command
u32 temp[2];
theCommand.toCryptoBuffer(temp);
key1.decrypt(temp);
theCommand.fromCryptoBuffer(temp);
GCLOG("[GC] (key1-decrypted):"); theCommand.print();
//and process it:
int cmd = theCommand.bytes[0];
switch(cmd&0xF0)
{
case 0x10:
operation = eSlot1Operation_1x_ChipID;
delay = 0x910, length = 4;
//we handle this operation ourselves
break;
case 0x20:
operation = eSlot1Operation_2x_SecureAreaLoad;
delay = 0x910, length = 0x11A8;
//TODO - more endian-safe way of doing this (theres examples in R4)
{
#ifdef MSB_FIRST
u64 cmd64 = *(u64*)theCommand.bytes;
#else
u64 cmd64 = bswap64(*(u64*)theCommand.bytes);
#endif
//todo - parse into blocknumber
u32 blocknumber = (cmd64>>44)&0xFFFF;
if(blocknumber<4||blocknumber>7)
printf("SLOT1 WARNING: INVALID BLOCKNUMBER FOR \"Get Secure Area Block\": 0x%04X\n",blocknumber);
address = blocknumber*0x1000;
}
client->slot1client_startOperation(operation);
break;
case 0x40:
//switch to KEY2
delay = 0x910, length = 0;
//well.. not really... yet.
GCLOG("[GC] KEY2 ACTIVATED\n");
break;
case 0x60:
//KEY2 disable? any info?
break;
case 0xA0:
delay = 0x910, length = 0;
mode = eCardMode_NORMAL;
GCLOG("[GC] NORMAL MODE ACTIVATED\n");
break;
}
}
void Slot1Comp_Protocol::write_command_NORMAL(GC_Command theCommand)
{
switch(command.bytes[0])
{
case 0xB7:
{
operation = eSlot1Operation_B7_Read;
//TODO - more endian-safe way of doing this (theres examples in R4)
#ifdef MSB_FIRST
u64 cmd64 = *(u64*)theCommand.bytes;
#else
u64 cmd64 = bswap64(*(u64*)theCommand.bytes);
#endif
address = (u32)((cmd64 >> 24));
length = 0x200;
client->slot1client_startOperation(operation);
}
break;
case 0xB8:
operation = eSlot1Operation_B8_ChipID;
delay = 0, length = 4;
//we handle this operation ourselves
break;
default:
operation = eSlot1Operation_Unknown;
client->slot1client_startOperation(operation);
break;
}
}
void Slot1Comp_Protocol::write_command(GC_Command theCommand)
{
this->command = theCommand;
//unrecognized commands will do something depending on the current state of the card
delay = 0;
length = 0;
address = 0;
switch(mode)
{
case eCardMode_RAW:
write_command_RAW(theCommand);
break;
case eCardMode_KEY1:
write_command_KEY1(theCommand);
break;
case eCardMode_NORMAL:
write_command_NORMAL(theCommand);
break;
default:
break;
}
}
void Slot1Comp_Protocol::write_GCDATAIN(u8 PROCNUM, u32 val)
{
switch(operation)
{
case eSlot1Operation_Unknown:
client->slot1client_write_GCDATAIN(operation,val);
break;
default:
break;
}
}
u32 Slot1Comp_Protocol::read_GCDATAIN(u8 PROCNUM)
{
switch(operation)
{
default:
return client->slot1client_read_GCDATAIN(operation);
case eSlot1Operation_9F_Dummy:
return 0xFFFFFFFF;
case eSlot1Operation_1x_ChipID:
return chipId;
case eSlot1Operation_90_ChipID:
case eSlot1Operation_B8_ChipID:
//Most games continuously compare the current chipId with the value in
//stored in memory at boot-up, probably to know if the card was removed.
//staff of kings verifies this (it also uses the arm7 IRQ 20 to detect card ejects)
return chipId;
}
return 0xFFFFFFFF;
}
void Slot1Comp_Protocol::savestate(EMUFILE &os)
{
s32 version = 0;
os.write_32LE(version);
os.write_32LE((s32)mode);
os.write_32LE((s32)operation);
os.fwrite(command.bytes,8);
os.write_32LE(address);
os.write_32LE(length);
os.write_32LE(delay);
os.write_32LE(chipId);
os.write_32LE(gameCode);
}
void Slot1Comp_Protocol::loadstate(EMUFILE &is)
{
s32 version = is.read_s32LE();
mode = (eCardMode)is.read_s32LE();
operation = (eSlot1Operation)is.read_s32LE();
is.fread(command.bytes,8);
is.read_32LE(address);
is.read_32LE(length);
is.read_32LE(delay);
is.read_32LE(chipId);
is.read_32LE(gameCode);
}

View File

@ -1,114 +0,0 @@
/*
Copyright (C) 2013-2021 DeSmuME team
This file is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
This file is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with the this software. If not, see <http://www.gnu.org/licenses/>.
*/
//this file contains the components used for emulating standard gamecard protocol.
//this largely means the complex boot-up process.
//i think there's no reason why proprietary cards couldn't speak any protocol they wish, as long as they didn't mind being unbootable.
//TODO - could this be refactored into a base class? that's probably more reasonable. but we've gone with this modular mix-in architecture so... not yet.
#ifndef _SLOT1COMP_PROTOCOL_H
#define _SLOT1COMP_PROTOCOL_H
#include "../types.h"
#include "../MMU.h"
class EMUFILE;
enum eSlot1Operation
{
//----------
//RAW mode operations
//before encrypted communications can be established, some values from the rom header must be read.
//this is the only way to read the header, actually, since the only reading commands available to games (after KEY2 mode is set) are
eSlot1Operation_00_ReadHeader_Unencrypted,
//it's not clear why this exists
eSlot1Operation_9F_Dummy,
eSlot1Operation_90_ChipID,
//----------
//----------
//KEY1 mode operations
eSlot1Operation_1x_ChipID,
eSlot1Operation_2x_SecureAreaLoad,
//----------
//----------
//NORMAL mode operations
//the main rom data reading command
eSlot1Operation_B7_Read,
eSlot1Operation_B8_ChipID,
//----------
eSlot1Operation_Unknown
};
class ISlot1Comp_Protocol_Client
{
public:
virtual void slot1client_startOperation(eSlot1Operation theOperation) {}
virtual u32 slot1client_read_GCDATAIN(eSlot1Operation theOperation) = 0;
virtual void slot1client_write_GCDATAIN(eSlot1Operation theOperation, u32 val) {}
};
class Slot1Comp_Protocol
{
public:
void savestate(EMUFILE &os);
void loadstate(EMUFILE &is);
//set some kind of protocol/hardware reset state
void reset(ISlot1Comp_Protocol_Client* theClient);
//signals from the GC bus
void write_command(GC_Command theCommand);
void write_GCDATAIN(u8 PROCNUM, u32 val);
u32 read_GCDATAIN(u8 PROCNUM);
//helpers for write_command()
void write_command_RAW(GC_Command theCommand);
void write_command_KEY1(GC_Command theCommand);
void write_command_NORMAL(GC_Command theCommand);
//operations not related to obscurities of the protocol or otherwise unknown are passed through to the client here
ISlot1Comp_Protocol_Client* client;
//--state--
//the major operational mode. the protocol shifts modes and interprets commands into operations differently depending on the mode
eCardMode mode;
//the current operational state
eSlot1Operation operation;
//the command we're currently crunching on
GC_Command command;
//most operations are defined in terms of returning a series of bytes
//the meaning of these varies by operation. they are provided publicly as a service to clients
u32 address;
s32 length, delay; //the expected length and delay of this state
//chipId which should be returned by the various chipId commands
u32 chipId;
//gameCode used by the protocol KEY1 crypto
u32 gameCode;
};
#endif //_SLOT1COMP_PROTOCOL_H

View File

@ -1,123 +0,0 @@
/*
Copyright (C) 2010-2021 DeSmuME team
This file is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
This file is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with the this software. If not, see <http://www.gnu.org/licenses/>.
*/
#include "slot1comp_rom.h"
#include "../NDSSystem.h"
#include "../emufile.h"
void Slot1Comp_Rom::start(eSlot1Operation operation, u32 addr)
{
this->_operation = operation;
this->_address = addr;
}
u32 Slot1Comp_Rom::read()
{
switch(this->_operation)
{
case eSlot1Operation_00_ReadHeader_Unencrypted:
{
u32 ret = gameInfo.readROM(this->_address);
this->_address = (this->_address + 4) & 0xFFF;
return ret;
}
break;
case eSlot1Operation_2x_SecureAreaLoad:
{
//see B7 for details
//zero 15-sep-2014 - this is meaningless. newer mask is actually reasonable
//address &= gameInfo.mask; //sanity check
u32 secureAreaAddress = (this->_address - 0x4000);
secureAreaAddress &= 0x3FFF; //memory safe sanity test
u32 ret = LE_TO_LOCAL_32(*(u32*)(gameInfo.secureArea + secureAreaAddress));
this->_address = (this->_address&~0xFFF) + ((this->_address+4)&0xFFF);
return ret;
}
case eSlot1Operation_B7_Read:
{
//TODO - check about non-4-byte aligned addresses
//it seems that etrian odyssey 3 doesnt work unless we mask this to cart size.
//but, a thought: does the internal rom address counter register wrap around? we may be making a mistake by keeping the extra precision
//but there is no test case yet
this->_address &= gameInfo.mask;
//feature of retail carts:
//B7 "Can be used only for addresses 8000h and up, smaller addresses will be silently redirected to address `8000h+(addr AND 1FFh)`"
if(CommonSettings.RetailCardProtection8000)
if(this->_address < 0x8000)
this->_address = (0x8000 + (this->_address & 0x1FF));
//1. as a sanity measure for funny-sized roms (homebrew and perhaps truncated retail roms) we need to protect ourselves by returning 0xFF for things still out of range.
//2. this isnt right, unless someone documents otherwise:
//if (address > gameInfo.header.endROMoffset)
// ... the cart hardware doesnt know anything about the rom header. if it has a totally bogus endROMoffset, the cart will probably work just fine. and, the +4 is missing anyway:
//3. this is better: it just allows us to read 0xFF anywhere we dont have rom data. forget what the header says
//note: we allow the reading to proceed anyway, because the readROM method is built to allow jaggedy reads off the end of the rom to support trimmed roms
if(this->_address+4 > gameInfo.romsize)
{
DEBUG_Notify.ReadBeyondEndOfCart(this->_address,gameInfo.romsize);
}
//actually read from the ROM provider
u32 ret = gameInfo.readROM(this->_address);
//"However, the datastream wraps to the begin of the current 4K block when address+length crosses a 4K boundary (1000h bytes)"
this->_address = (this->_address&~0xFFF) + ((this->_address+4)&0xFFF);
return ret;
}
break;
default:
return 0;
} //switch(operation)
} //Slot1Comp_Rom::read()
u32 Slot1Comp_Rom::getAddress()
{
return this->_address & gameInfo.mask;
} //Slot1Comp_Rom::getAddress()
u32 Slot1Comp_Rom::incAddress()
{
this->_address &= gameInfo.mask;
this->_address = (this->_address&~0xFFF) + ((this->_address+4)&0xFFF);
return this->_address;
}
void Slot1Comp_Rom::savestate(EMUFILE &os)
{
s32 version = 0;
os.write_32LE(version);
os.write_32LE((s32)this->_operation);
os.write_32LE(this->_address);
}
void Slot1Comp_Rom::loadstate(EMUFILE &is)
{
s32 version = is.read_s32LE();
this->_operation = (eSlot1Operation)is.read_s32LE();
this->_address = is.read_u32LE();
}

View File

@ -1,45 +0,0 @@
/*
Copyright (C) 2010-2021 DeSmuME team
This file is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
This file is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with the this software. If not, see <http://www.gnu.org/licenses/>.
*/
//this file contains the components used for emulating standard gamecard ROMs
//this is largely done by accessing the rom provided in the core emulator
#ifndef _SLOT1COMP_ROM_H
#define _SLOT1COMP_ROM_H
#include "slot1comp_protocol.h"
#include "../types.h"
class EMUFILE;
class Slot1Comp_Rom
{
public:
void start(eSlot1Operation operation, u32 addr);
u32 read();
u32 getAddress();
u32 incAddress();
void savestate(EMUFILE &os);
void loadstate(EMUFILE &is);
private:
u32 _address;
eSlot1Operation _operation;
};
#endif

View File

@ -1,72 +0,0 @@
/*
Copyright (C) 2013-2015 DeSmuME team
This file is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
This file is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with the this software. If not, see <http://www.gnu.org/licenses/>.
*/
#include <stdio.h>
#include "../slot2.h"
class Slot2_Auto : public ISlot2Interface
{
private:
ISlot2Interface *mSelectedImplementation;
public:
Slot2_Auto()
: mSelectedImplementation(NULL)
{
}
virtual Slot2Info const* info()
{
static Slot2InfoSimple info("Auto","Slot2 (auto-selection) device emulation", 0xFE);
return &info;
}
virtual void connect()
{
slot2_selected_type = slot2_DetermineType();
mSelectedImplementation = slot2_List[slot2_selected_type];
mSelectedImplementation->connect();
printf("Slot2 auto-selected device type: %s (0x%02X)\n", mSelectedImplementation->info()->name(), mSelectedImplementation->info()->id());
}
virtual void disconnect()
{
if(mSelectedImplementation) mSelectedImplementation->disconnect();
mSelectedImplementation = NULL;
}
virtual void writeByte(u8 PROCNUM, u32 addr, u8 val) { mSelectedImplementation->writeByte(PROCNUM, addr, val); }
virtual void writeWord(u8 PROCNUM, u32 addr, u16 val) { mSelectedImplementation->writeWord(PROCNUM, addr, val); }
virtual void writeLong(u8 PROCNUM, u32 addr, u32 val) { mSelectedImplementation->writeLong(PROCNUM, addr, val); }
virtual u8 readByte(u8 PROCNUM, u32 addr) { return mSelectedImplementation->readByte(PROCNUM, addr); }
virtual u16 readWord(u8 PROCNUM, u32 addr) { return mSelectedImplementation->readWord(PROCNUM, addr); }
virtual u32 readLong(u8 PROCNUM, u32 addr) { return mSelectedImplementation->readLong(PROCNUM, addr); }
virtual void savestate(EMUFILE &os)
{
mSelectedImplementation->savestate(os);
}
virtual void loadstate(EMUFILE &is)
{
mSelectedImplementation->loadstate(is);
}
};
ISlot2Interface* construct_Slot2_Auto() { return new Slot2_Auto(); }

View File

@ -1,196 +0,0 @@
/*
Copyright (C) 2009 CrazyMax
Copyright (C) 2009-2017 DeSmuME team
This file is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
This file is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with the this software. If not, see <http://www.gnu.org/licenses/>.
*/
#include "../slot2.h"
#include "../emufile.h"
#include "../mem.h"
#if 0
#define EXPINFO(...) INFO(__VA_ARGS__)
#else
#define EXPINFO(...)
#endif
#define EXPANSION_MEMORY_SIZE (8 * 1024 * 1024)
static u8 header_0x00B0[] =
{ 0xFF, 0xFF, 0x96, 0x00, //this 0x96 is strange. it can't be read from the pak when it boots, it must appear later
0x00, 0x24, 0x24, 0x24,
0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0x7F
};
class Slot2_ExpansionPak : public ISlot2Interface
{
private:
u8 *expMemory;
bool ext_ram_lock;
public:
Slot2_ExpansionPak()
{
expMemory = NULL;
ext_ram_lock = true;
}
virtual Slot2Info const* info()
{
static Slot2InfoSimple info("Memory Expansion Pak", "Official RAM expansion for Opera browser", 0x05);
return &info;
}
virtual void connect()
{
if (expMemory == NULL)
{
expMemory = new u8[EXPANSION_MEMORY_SIZE];
}
memset(expMemory, 0xFF, EXPANSION_MEMORY_SIZE);
ext_ram_lock = true;
}
virtual void disconnect()
{
delete[] expMemory;
expMemory = NULL;
}
virtual void writeByte(u8 PROCNUM, u32 addr, u8 val)
{
if (ext_ram_lock) return;
if (addr >= 0x09000000)
{
u32 offs = (addr - 0x09000000);
if (offs >= EXPANSION_MEMORY_SIZE) return;
T1WriteByte(expMemory, offs, val);
}
EXPINFO("ExpMemory: write 08 at 0x%08X = 0x%02X\n", addr, val);
}
virtual void writeWord(u8 PROCNUM, u32 addr, u16 val)
{
if (addr == 0x08240000)
{
if (val == 0)
ext_ram_lock = true;
else
if (val == 1)
ext_ram_lock = false;
return;
}
if (ext_ram_lock) return;
if (addr >= 0x09000000)
{
u32 offs = (addr - 0x09000000);
if (offs >= EXPANSION_MEMORY_SIZE) return;
T1WriteWord(expMemory, offs, val);
}
EXPINFO("ExpMemory: write 16 at 0x%08X = 0x%04X\n", addr, val);
}
virtual void writeLong(u8 PROCNUM, u32 addr, u32 val)
{
if (ext_ram_lock) return;
if (addr >= 0x09000000)
{
u32 offs = (addr - 0x09000000);
if (offs >= EXPANSION_MEMORY_SIZE) return;
T1WriteLong(expMemory, offs, val);
}
EXPINFO("ExpMemory: write 32 at 0x%08X = 0x%08X\n", addr, val);
}
virtual u8 readByte(u8 PROCNUM, u32 addr)
{
EXPINFO("ExpMemory: read 08 at 0x%08X\n", addr);
if ((addr >= 0x080000B0) && (addr < 0x080000C0))
return T1ReadByte(header_0x00B0, (addr - 0x080000B0));
if (addr >= 0x09000000)
{
u32 offs = (addr - 0x09000000);
if (offs >= EXPANSION_MEMORY_SIZE) return (0xFF);
return T1ReadByte(expMemory, offs);
}
return 0xFF;
}
virtual u16 readWord(u8 PROCNUM, u32 addr)
{
EXPINFO("ExpMemory: read 16 at 0x%08X\n", addr);
if ((addr >= 0x080000B0) && (addr < 0x080000C0))
return T1ReadWord(header_0x00B0, (addr - 0x080000B0));
if (addr == 0x0801FFFC) return 0x7FFF;
if (addr == 0x08240002) return 0; //this can't be 0xFFFF. dunno why, we just guessed 0
if (addr >= 0x09000000)
{
u32 offs = (addr - 0x09000000);
if (offs >= EXPANSION_MEMORY_SIZE) return (0xFFFF);
return T1ReadWord(expMemory, offs);
}
return 0xFFFF;
}
virtual u32 readLong(u8 PROCNUM, u32 addr)
{
EXPINFO("ExpMemory: read 32 at 0x%08X\n", addr);
if((addr >= 0x080000B0) && (addr < 0x080000C0))
return T1ReadLong(header_0x00B0, (addr - 0x080000B0));
if (addr >= 0x09000000)
{
u32 offs = (addr - 0x09000000);
if (offs >= EXPANSION_MEMORY_SIZE) return 0xFFFFFFFF;
return T1ReadLong(expMemory, offs);
}
return 0xFFFFFFFF;
}
virtual void savestate(EMUFILE &os)
{
s32 version = 0;
EMUFILE_MEMORY ram = EMUFILE_MEMORY(expMemory, EXPANSION_MEMORY_SIZE);
os.write_32LE(version);
os.write_bool32(ext_ram_lock);
os.write_MemoryStream(ram);
}
virtual void loadstate(EMUFILE &is)
{
EMUFILE_MEMORY ram = EMUFILE_MEMORY();
s32 version = is.read_s32LE();
if (version >= 0)
{
is.read_bool32(ext_ram_lock);
is.read_MemoryStream(ram);
memcpy(expMemory, ram.buf(), std::min(EXPANSION_MEMORY_SIZE, ram.size()));
}
}
};
ISlot2Interface* construct_Slot2_ExpansionPak() { return new Slot2_ExpansionPak(); }

View File

@ -1,466 +0,0 @@
/*
Copyright (C) 2009 CrazyMax
Copyright (C) 2009-2021 DeSmuME team
This file is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
This file is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with the this software. If not, see <http://www.gnu.org/licenses/>.
*/
#include "../slot2.h"
#include <string.h>
#include "../debug.h"
#include "../NDSSystem.h"
#include "../path.h"
#include "../emufile.h"
#define EEPROM 0x52504545
#define SRAM_ 0x4D415253
#define FLASH 0x53414C46
#define FLASH1M_ 0x5F4D3148
#define SIIRTC_V 0x52494953
static const char *saveTypes[] = {
"EEPROM",
"SRAM",
"FLASH",
"FLASH1M",
"SIIRTC_V",
};
class Slot2_GbaCart : public ISlot2Interface
{
private:
EMUFILE* fROM;
EMUFILE* fSRAM;
u32 romSize;
u32 sramSize;
u32 saveType;
struct
{
u32 size;
u8 state;
u8 cmd;
u8 idDevice;
u8 idManufacturer;
u8 bank;
} gbaFlash;
u32 readRom(const u32 pos, const u8 size)
{
if (!fROM) return 0xFFFFFFFF;
fROM->fseek(pos, SEEK_SET);
u32 data = 0xFFFFFFFF;
u32 readed = fROM->fread(&data, size);
return data;
}
u32 readSRAM(const u32 pos, const u8 size)
{
if (!fSRAM)
return 0xFFFFFFFF;
fSRAM->fseek(pos, SEEK_SET);
u32 data = 0xFFFFFFFF;
u32 readed = fSRAM->fread(&data, size);
return data;
}
void writeSRAM(const u32 pos, const u8 *data, u32 size)
{
if (!fSRAM)
return;
fSRAM->fseek(pos, SEEK_SET);
u32 writed = size;
fSRAM->fwrite(data, size);
fSRAM->fflush();
}
u32 scanSaveTypeGBA()
{
if (!fROM) return 0xFF;
fROM->fseek(0, SEEK_SET);
int size = fROM->size();
int lastpct=1;
int len = fROM->size();
for(;;)
{
u32 romType = 0;
u32 readed = fROM->fread(&romType, 4);
int pos = fROM->ftell();
int currPct = pos*100/(size-1);
for(int i=lastpct;i<currPct;i++)
{
if(i%10==0)
printf(" %d%%\n",i/10*10);
else printf(".");
lastpct = currPct;
}
if (readed < 4)
break;
if(pos >= len)
break;
switch (romType)
{
case EEPROM:
return 1;
case SRAM_:
return 2;
case FLASH:
{
u32 tmp = fROM->read_u32LE();
return ((tmp == FLASH1M_)?3:5);
}
case SIIRTC_V:
return 4;
default:
break;
}
}
return 0xFF;
}
void gbaWriteFlash(u32 adr, u8 val)
{
if (!fSRAM) return;
switch (gbaFlash.state)
{
case 0:
if (adr == 0x0A005555)
{
if (val == 0xF0)
{
//INFO("GBAgame: Flash: reset\n");
gbaFlash.state = 0;
gbaFlash.cmd = 0;
return;
}
if (val == 0xAA)
{
gbaFlash.state = 1;
return;
}
}
if (adr == 0x0A000000)
{
if (gbaFlash.cmd == 0xB0)
{
gbaFlash.bank = val;
gbaFlash.cmd = 0;
//INFO("GBAgame: Flash: change bank %i\n", val);
return;
}
}
break;
case 1:
if ( (adr == 0x0A002AAA) && (val == 0x55) )
{
gbaFlash.state = 2;
return;
}
gbaFlash.state = 0;
break;
case 2:
if (adr == 0x0A005555)
{
//INFO("GBAgame: Flash: send command flash 0x%02X\n", val);
switch (val)
{
case 0x80: // Erase
gbaFlash.state = 0x80;
break;
case 0x90: // Chip Identification
gbaFlash.state = 0x90;
break;
case 0xA0: // Write
gbaFlash.state = 0;
break;
default:
gbaFlash.state = 0;
break;
}
gbaFlash.cmd = val;
return;
}
gbaFlash.state = 0;
break;
// erase
case 0x80:
if ( (adr == 0x0A005555) && (val == 0xAA) )
{
gbaFlash.state = 0x81;
return;
}
gbaFlash.state = 0;
break;
case 0x81:
if ( (adr == 0x0A002AAA) && (val == 0x55) )
{
gbaFlash.state = 0x82;
return;
}
gbaFlash.state = 0;
break;
case 0x82:
if (val == 0x30)
{
u32 ofs = (adr & 0x0000F000) + (0x10000 * gbaFlash.bank);
//INFO("GBAgame: Flash: erase from 0x%08X to 0x%08X\n", ofs + 0x0A000000, ofs + 0x0A001000);
u8 *tmp = new u8[0x1000];
memset(tmp, 0xFF, 0x1000);
writeSRAM(ofs, tmp, 0x1000);
delete [] tmp;
}
gbaFlash.state = 0;
gbaFlash.cmd = 0;
return;
// Chip Identification
case 0x90:
if ( (adr == 0x0A005555) && (val == 0xAA) )
{
gbaFlash.state = 0x91;
return;
}
gbaFlash.state = 0;
break;
case 0x91:
if ( (adr == 0x0A002AAA) && (val == 0x55) )
{
gbaFlash.state = 0x92;
return;
}
gbaFlash.state = 0;
break;
case 0x92:
gbaFlash.state = 0;
gbaFlash.cmd = 0;
return;
}
if (gbaFlash.cmd == 0xA0) // write
{
writeSRAM((adr & 0x1FFFF) + (0x10000 * gbaFlash.bank), &val, 1);
gbaFlash.state = 0;
gbaFlash.cmd = 0;
return;
}
INFO("GBAgame: Flash: write unknown atn 0x%08X = 0x%02X\n", adr, val);
}
u8 gbaReadFlash(u32 adr)
{
if (!fSRAM) return 0xFF;
if (gbaFlash.cmd == 0)
return readSRAM((adr & 0x1FFFF) + (0x10000 * gbaFlash.bank), 1);
//INFO("GBAgame: flash read at 0x%08X\n", adr);
switch (gbaFlash.cmd)
{
case 0x90: // Chip Identification
if (adr == 0x0A000000) return gbaFlash.idManufacturer;
if (adr == 0x0A000001) return gbaFlash.idDevice;
break;
case 0xF0: //
gbaFlash.state = 0;
gbaFlash.cmd = 0;
break;
case 0xB0: // Bank switching
break;
default:
INFO("GBAgame: Flash: read - unknown command at 0x%08X = 0x%02X\n", adr, gbaFlash.cmd);
break;
}
return 0xFF;
}
void Close()
{
delete fROM; fROM = NULL;
delete fSRAM; fSRAM = NULL;
romSize = 0;
sramSize = 0;
}
public:
Slot2_GbaCart()
: fROM(NULL)
, fSRAM(NULL)
{
Close();
}
virtual Slot2Info const* info()
{
static Slot2InfoSimple info("GBA Cartridge", "GBA cartridge in slot", 0x03);
return &info;
}
virtual void connect()
{
Close();
romSize = 0;
sramSize = 0;
if (gameInfo.romsize == 0)
{
return;
}
if (GBACartridge_RomPath.empty())
{
return;
}
if (!strcasecmp(GBACartridge_RomPath.c_str(), "self"))
{
GBACartridge_RomPath = path.path;
GBACartridge_SRAMPath = Path::GetFileNameWithoutExt(GBACartridge_RomPath) + "." + GBA_SRAM_FILE_EXT;
}
printf("GBASlot opening ROM: %s\n", GBACartridge_RomPath.c_str());
EMUFILE_FILE *inf = new EMUFILE_FILE(GBACartridge_RomPath, "rb");
fROM = inf;
if (fROM->fail())
{
printf(" - Failed\n");
Close();
return;
}
inf->EnablePositionCache();
romSize = fROM->size();
printf(" - Success (%u bytes)\n", romSize);
// Load the GBA cartridge SRAM.
inf = new EMUFILE_FILE(GBACartridge_SRAMPath, "rb+");
fSRAM = inf;
if(fSRAM->fail())
{
delete fSRAM;
fSRAM = NULL;
printf("GBASlot did not load associated SRAM.\n");
}
else
{
inf->EnablePositionCache();
sramSize = fSRAM->size();
printf("Scanning GBA rom to ID save type\n");
saveType = scanSaveTypeGBA();
printf("\nGBASlot found SRAM (%s - %u bytes) at:\n%s\n", (saveType == 0xFF)?"Unknown":saveTypes[saveType], sramSize, GBACartridge_SRAMPath.c_str());
gbaFlash.size = sramSize;
if (gbaFlash.size <= (64 * 1024))
{
gbaFlash.idDevice = 0x1B;
gbaFlash.idManufacturer = 0x32;
}
else
{
gbaFlash.idDevice = 0x09;
gbaFlash.idManufacturer = 0xC2;
}
gbaFlash.state = 0;
}
}
virtual void disconnect()
{
Close();
}
virtual void writeByte(u8 PROCNUM, u32 addr, u8 val)
{
if ((addr >= 0x0A000000) && (addr < 0x0A010000))
{
switch (saveType)
{
case 3: // Flash
case 5:
gbaWriteFlash(addr, val);
break;
default: break;
}
}
}
virtual u8 readByte(u8 PROCNUM, u32 addr)
{
if (addr < 0x0A000000)
return (u8)readRom(addr - 0x08000000, 1);
if (addr < 0x0A010000)
{
if ((saveType == 3) || (saveType == 5))
return gbaReadFlash(addr);
return (u8)readSRAM(addr - 0x0A000000, 1);
}
return 0xFF;
}
virtual u16 readWord(u8 PROCNUM, u32 addr)
{
if (addr < 0x0A000000)
return (u16)readRom(addr - 0x08000000, 2);
if (addr < 0x0A010000)
return (u16)readSRAM(addr - 0x0A000000, 2);
return 0xFFFF;
}
virtual u32 readLong(u8 PROCNUM, u32 addr)
{
if (addr < 0x0A000000)
return (u32)readRom(addr - 0x08000000, 4);
if (addr < 0x0A010000)
return (u32)readSRAM(addr - 0x0A000000, 4);
return 0xFFFFFFFF;
}
};
ISlot2Interface* construct_Slot2_GbaCart() { return new Slot2_GbaCart(); }

View File

@ -1,65 +0,0 @@
/*
Copyright (C) 2009 CrazyMax
Copyright (C) 2009-2013 DeSmuME team
This file is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
This file is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with the this software. If not, see <http://www.gnu.org/licenses/>.
*/
#include "../slot2.h"
static u8 guitarKeyStatus;
class Slot2_GuitarGrip : public ISlot2Interface
{
private:
public:
virtual Slot2Info const* info()
{
static Slot2InfoSimple info("Guitar Grip", "Guitar Grip for Guitar Hero games", 0x04);
return &info;
}
virtual void connect()
{
guitarKeyStatus = 0xFF;
}
virtual u8 readByte(u8 PROCNUM, u32 addr)
{
if (addr == 0x0A000000)
return guitarKeyStatus;
return (addr & 1) ? 0xF9 : 0xFF;
}
virtual u16 readWord(u8 PROCNUM, u32 addr) { return 0xF9FF; }
virtual u32 readLong(u8 PROCNUM, u32 addr) { return 0xF9FFF9FF; }
};
ISlot2Interface* construct_Slot2_GuitarGrip() { return new Slot2_GuitarGrip(); }
void guitarGrip_setKey(bool green, bool red, bool yellow, bool blue)
{
const u8 g = (green) ? (1 << 6) : 0;
const u8 r = (red) ? (1 << 5) : 0;
const u8 y = (yellow) ? (1 << 4) : 0;
const u8 b = (blue) ? (1 << 3) : 0;
guitarKeyStatus = ~(g | r | y | b);
}
void guitarGrip_setKey(u8 theKeys)
{
guitarKeyStatus = theKeys;
}

View File

@ -1,87 +0,0 @@
//HCV-1000 emulation code adapted from GBE+: https://github.com/shonumi/gbe-plus
/*
Modifications Copyright (C) 2023 DeSmuME team
This file is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
This file is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with the this software. If not, see <http://www.gnu.org/licenses/>.
*/
#include <string.h>
#include "../slot2.h"
u8 hcv1000_cnt;
char hcv1000_data[16];
class Slot2_HCV1000 : public ISlot2Interface
{
public:
virtual Slot2Info const* info()
{
static Slot2InfoSimple info("Sega Card Reader", "Sega Card Reader(HCV-1000) add-on", 0x09);
return &info;
}
virtual bool init()
{
hcv1000_cnt = 0;
memset(hcv1000_data, 0x5F, 16);
return TRUE;
}
virtual void writeByte(u8 PROCNUM, u32 addr, u8 val)
{
if (addr == 0xA000000) { hcv1000_cnt = (val & 0x83); }
}
virtual u8 readByte(u8 PROCNUM, u32 addr)
{
u8 slot_byte = 0xFF;
//Reading these cart addresses is for detection
if (addr < 0x8020000)
{
u8 data = 0xF0 | ((addr & 0x1F) >> 1);
slot_byte = (addr & 0x1) ? 0xFD : data;
}
//HCV_CNT
else if (addr == 0xA000000) { slot_byte = hcv1000_cnt; }
//HCV_DATA
else if ((addr >= 0xA000010) && (addr <= 0xA00001F))
{
slot_byte = (u8)hcv1000_data[addr & 0xF];
}
return slot_byte;
}
virtual u16 readWord(u8 PROCNUM, u32 addr) { return 0xFDFD; };
virtual u32 readLong(u8 PROCNUM, u32 addr) { return 0xFDFDFDFD; };
};
ISlot2Interface* construct_Slot2_HCV1000() { return new Slot2_HCV1000(); }
void HCV1000_setReady()
{
hcv1000_cnt &= ~0x80;
}
void HCV1000_setBarcode(std::string barcode)
{
barcode.resize(16, '_');
memcpy(hcv1000_data, barcode.c_str(), barcode.length());
}

View File

@ -1,301 +0,0 @@
/*
Copyright (C) 2006 yopyop
Copyright (C) 2006 Mic
Copyright (C) 2009-2017 DeSmuME team
This file is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
This file is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with the this software. If not, see <http://www.gnu.org/licenses/>.
*/
#include <string>
#include <string.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include "../slot2.h"
#include "../debug.h"
#include "../emufile.h"
#include "../path.h"
#include "../utils/vfat.h"
// Set up addresses for GBAMP
#define CF_REG_DATA 0x9000000
#define CF_REG_ERR 0x9020000
#define CF_REG_SEC 0x9040000
#define CF_REG_LBA1 0x9060000
#define CF_REG_LBA2 0x9080000
#define CF_REG_LBA3 0x90A0000
#define CF_REG_LBA4 0x90C0000
#define CF_REG_CMD 0x90E0000
#define CF_REG_STS 0x98C0000
// CF Card commands
#define CF_CMD_LBA 0xE0
#define CF_CMD_READ 0x20
#define CF_CMD_WRITE 0x30
static u16 cf_reg_sts,
cf_reg_lba1,
cf_reg_lba2,
cf_reg_lba3,
cf_reg_lba4,
cf_reg_cmd;
static off_t currLBA;
static const int lfnPos[13] = {1,3,5,7,9,14,16,18,20,22,24,28,30};
static u32 fileStartLBA,fileEndLBA;
static std::string sFlashPath;
static BOOL cflashDeviceEnabled = FALSE;
static EMUFILE* file = NULL;
// ===========================
BOOL inited;
enum EListCallbackArg {
EListCallbackArg_Item, EListCallbackArg_Pop
};
static BOOL cflash_init()
{
if (inited) return FALSE;
BOOL init_good = FALSE;
CFLASHLOG("CFlash_Mode: %d\n",CFlash_Mode);
if (CFlash_Mode == ADDON_CFLASH_MODE_RomPath)
{
sFlashPath = path.RomDirectory;
INFO("Using CFlash directory of rom: %s\n", sFlashPath.c_str());
}
else if(CFlash_Mode == ADDON_CFLASH_MODE_Path)
{
sFlashPath = CFlash_Path;
INFO("Using CFlash directory: %s\n", sFlashPath.c_str());
}
else if(CFlash_Mode == ADDON_CFLASH_MODE_File)
{
sFlashPath = CFlash_Path;
INFO("Using CFlash disk image file %s\n", sFlashPath.c_str());
}
else
{
return FALSE;
}
if (sFlashPath == "") return FALSE;
if(CFlash_IsUsingPath())
{
cflashDeviceEnabled = FALSE;
currLBA = 0;
fileStartLBA = fileEndLBA = 0xFFFFFFFF;
VFAT vfat;
bool ret = vfat.build(sFlashPath.c_str(),16); //allocate 16MB extra for writing. this is probably enough for anyone, but maybe it should be configurable.
//we could always suggest to users to add a big file to their directory to overwrite (that would cause the image to get padded)
if(!ret)
{
CFLASHLOG("FAILED cflash_build_fat\n");
return FALSE;
}
file = vfat.detach();
cf_reg_sts = 0x58; // READY
cflashDeviceEnabled = TRUE;
init_good = TRUE;
}
else
{
file = new EMUFILE_FILE(sFlashPath.c_str(),"rb+");
if(file->fail())
{
INFO("Failed to open file %s\n", sFlashPath.c_str());
delete file;
file = NULL;
}
}
// READY
cf_reg_sts = 0x58;
currLBA = 0;
cf_reg_lba1 = cf_reg_lba2 =
cf_reg_lba3 = cf_reg_lba4 = 0;
inited = TRUE;
return init_good;
}
static unsigned int cflash_read(unsigned int address)
{
unsigned int ret_value = 0;
size_t elems_read = 0;
switch (address)
{
case CF_REG_STS:
ret_value = cf_reg_sts;
break;
case CF_REG_DATA:
if (cf_reg_cmd == CF_CMD_READ)
{
if(file)
{
u8 data[2] = {0,0};
file->fseek(currLBA, SEEK_SET);
elems_read += file->fread(data,2);
ret_value = data[1] << 8 | data[0];
}
currLBA += 2;
}
break;
case CF_REG_CMD:
break;
case CF_REG_LBA1:
ret_value = cf_reg_lba1;
break;
}
return ret_value;
}
static void cflash_write(unsigned int address,unsigned int data)
{
static u8 sector_data[512];
static u32 sector_write_index = 0;
switch (address)
{
case CF_REG_STS:
cf_reg_sts = data&0xFFFF;
break;
case CF_REG_DATA:
if (cf_reg_cmd == CF_CMD_WRITE)
{
{
sector_data[sector_write_index] = (data >> 0) & 0xff;
sector_data[sector_write_index + 1] = (data >> 8) & 0xff;
sector_write_index += 2;
if (sector_write_index == 512)
{
CFLASHLOG( "Write sector to %ld\n", currLBA);
size_t written = 0;
if(file)
if(currLBA + 512 < file->size())
{
file->fseek(currLBA,SEEK_SET);
while(written < 512)
{
size_t todo = 512-written;
file->fwrite(&sector_data[written], todo);
size_t cur_write = todo;
written += cur_write;
if ( cur_write == (size_t)-1) break;
}
}
CFLASHLOG("Wrote %u bytes\n", written);
currLBA += 512;
sector_write_index = 0;
}
}
}
break;
case CF_REG_CMD:
cf_reg_cmd = data&0xFF;
cf_reg_sts = 0x58; // READY
break;
case CF_REG_LBA1:
cf_reg_lba1 = data&0xFF;
currLBA = (currLBA&0xFFFFFF00)| cf_reg_lba1;
break;
case CF_REG_LBA2:
cf_reg_lba2 = data&0xFF;
currLBA = (currLBA&0xFFFF00FF)|(cf_reg_lba2<<8);
break;
case CF_REG_LBA3:
cf_reg_lba3 = data&0xFF;
currLBA = (currLBA&0xFF00FFFF)|(cf_reg_lba3<<16);
break;
case CF_REG_LBA4:
cf_reg_lba4 = data&0xFF;
if ((cf_reg_lba4 & 0xf0) == CF_CMD_LBA)
{
currLBA = (currLBA&0x00FFFFFF)|((cf_reg_lba4&0x0F)<<24);
currLBA *= 512;
sector_write_index = 0;
}
break;
}
}
static void cflash_close( void)
{
if (!inited) return;
if(file) delete file;
cflashDeviceEnabled = FALSE;
file = NULL;
inited = FALSE;
}
class Slot2_CFlash : public ISlot2Interface
{
public:
virtual Slot2Info const* info()
{
static Slot2InfoSimple info("MPCF Flash Card Device", "MPCF Flash Card Device", 0x01);
return &info;
}
virtual void connect()
{
cflash_close();
cflash_init();
}
virtual void disconnect()
{
cflash_close();
}
virtual void writeByte(u8 PROCNUM, u32 addr, u8 val) { cflash_write(addr, val); }
virtual void writeWord(u8 PROCNUM, u32 addr, u16 val) { cflash_write(addr, val); }
virtual void writeLong(u8 PROCNUM, u32 addr, u32 val) { cflash_write(addr, val); }
virtual u8 readByte(u8 PROCNUM, u32 addr) { return (cflash_read(addr)); }
virtual u16 readWord(u8 PROCNUM, u32 addr) { return (cflash_read(addr)); }
virtual u32 readLong(u8 PROCNUM, u32 addr) { return (cflash_read(addr)); }
};
ISlot2Interface* construct_Slot2_CFlash() { return new Slot2_CFlash(); }

View File

@ -1,31 +0,0 @@
/*
Copyright (C) 2009 CrazyMax
Copyright (C) 2009-2013 DeSmuME team
This file is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
This file is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with the this software. If not, see <http://www.gnu.org/licenses/>.
*/
#include "../slot2.h"
class Slot2_None : public ISlot2Interface
{
public:
virtual Slot2Info const* info()
{
static Slot2InfoSimple info("None", "Slot2 no-device emulation", 0xFF);
return &info;
}
};
ISlot2Interface* construct_Slot2_None() { return new Slot2_None(); }

View File

@ -1,143 +0,0 @@
/*
Copyright (C) 2011-2015 DeSmuME team
This file is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
This file is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with the this software. If not, see <http://www.gnu.org/licenses/>.
*/
/*
this device seems to have a 12bit value (like 20.12 fixed point.. get it?) located at 0x0A000000
clockwise = right = increases.
it returns the correct little endian bytes through byte reads.
through halfword reads, it returns the LSB twice
through full word reads, it returns the LSB four times.
after that everything is 0x00.
if the slot2 timings are wrong, then this device will return glitchy or 0xFF output.
so this emulation code will attempt to validate that.
arkanoid was setting REG_EXMEMCNT = 0x082F
the rom returns 0xEFFF for all addresses and should be used to detect this device
writing any byte to SRAM or writing any halfword/word to rom results in a reset or some kind of recalibrate
the resulting value may be 0x000,0x001, or 0xFFF. seems mostly random, though once it is reset, resetting again won't change it.
you must wait until the paddle has been moved.
conclusion:
The emulation in all the handling of erroneous cases is not perfect, and some other users of the paddle (do any other games use it?)
maybe legally configure the paddle differently, which could be rejected here; in which case this code will need finetuning
*/
#include <string.h>
#include "../slot2.h"
#include "../NDSSystem.h"
class Slot2_Paddle : public ISlot2Interface
{
private:
void calibrate() { nds.paddle = 0; }
bool Validate(u32 procnum, bool rom)
{
if(rom)
return ValidateSlot2Access(procnum, 0, 0, 0, -1);
else
return ValidateSlot2Access(procnum, 18, 0, 0, 1);
}
public:
virtual Slot2Info const* info()
{
static Slot2InfoSimple info("Paddle Controller", "Taito Paddle Controller", 0x07);
return &info;
}
virtual void writeByte(u8 PROCNUM, u32 addr, u8 val)
{
if (addr < 0x0A000000)
calibrate();
}
virtual void writeWord(u8 PROCNUM, u32 addr, u16 val)
{
if (addr < 0x0A000000)
calibrate();
}
virtual void writeLong(u8 PROCNUM, u32 addr, u32 val)
{
if (addr < 0x0A000000)
calibrate();
}
virtual u8 readByte(u8 PROCNUM, u32 addr)
{
//printf("paddle: read 08 at 0x%08X\n", addr);
if (!Validate(PROCNUM, (addr < 0x0A000000)))
return 0xFF;
if (addr < 0x0A000000)
return (addr & 1)?0xFF:0xEF;
if (addr == 0x0A000000)
return (nds.paddle & 0xFF);
if (addr == 0x0A000001)
return ((nds.paddle >> 8) & 0x0F);
return 0x00;
}
virtual u16 readWord(u8 PROCNUM, u32 addr)
{
//printf("paddle: read 16 at 0x%08X\n", addr);
if (!Validate(PROCNUM, (addr < 0x0A000000)))
return 0xFFFF;
if (addr < 0x0A000000)
return 0xEFFF;
if (addr == 0x0A000000)
{
u8 val = (nds.paddle & 0xFF);
return (val | (val << 8));
}
return 0x0000;
}
virtual u32 readLong(u8 PROCNUM, u32 addr)
{
//printf("paddle: read 32 at 0x%08X\n", addr);
if (!Validate(PROCNUM, (addr < 0x0A000000)))
return 0xFFFFFFFF;
if (addr < 0x0A000000)
return 0xEFFFEFFF;
if (addr == 0x0A000000)
{
u8 val = (nds.paddle & 0xFF);
return (val | (val << 8) | (val << 16) | (val << 24));
}
return 0x00000000;
}
};
u16 Paddle_GetValue()
{
return nds.paddle;
}
void Paddle_SetValue(u16 theValue)
{
nds.paddle = theValue;
}
ISlot2Interface* construct_Slot2_Paddle() { return new Slot2_Paddle(); }

View File

@ -1,56 +0,0 @@
/*
Copyright (C) 2013-2015 DeSmuME team
This file is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
This file is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with the this software. If not, see <http://www.gnu.org/licenses/>.
*/
#include "../slot2.h"
#include "../NDSSystem.h"
class Slot2_PassME : public ISlot2Interface
{
public:
virtual Slot2Info const* info()
{
static Slot2InfoSimple info("PassME", "PassME in GBA slot", 0x08);
return &info;
}
virtual u8 readByte(u8 PROCNUM, u32 addr)
{
u32 tmp_addr = (addr & 0x07FFFFFF);
if (tmp_addr < gameInfo.romsize)
return (u8)gameInfo.readROM(tmp_addr);
return (0xFF);
}
virtual u16 readWord(u8 PROCNUM, u32 addr)
{
u32 tmp_addr = (addr & 0x07FFFFFF);
if (tmp_addr < gameInfo.romsize)
return (u16)gameInfo.readROM(tmp_addr);
return (0xFFFF);
}
virtual u32 readLong(u8 PROCNUM, u32 addr)
{
u32 tmp_addr = (addr & 0x07FFFFFF);
if (tmp_addr < gameInfo.romsize)
return (u32)gameInfo.readROM(tmp_addr);
return (0xFFFFFFFF);
}
};
ISlot2Interface* construct_Slot2_PassME() { return new Slot2_PassME(); }

View File

@ -1,122 +0,0 @@
/*
Copyright (C) 2010-2013 DeSmuME team
This file is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
This file is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with the this software. If not, see <http://www.gnu.org/licenses/>.
*/
#include "../slot2.h"
static u16 pianoKeyStatus = 0;
class Slot2_EasyPiano : public ISlot2Interface
{
public:
virtual Slot2Info const* info()
{
static Slot2InfoSimple info("Piano", "Piano for EasyPiano", 0x06);
return &info;
}
virtual void connect()
{
pianoKeyStatus = 0xE7FF;
}
virtual u8 readByte(u8 PROCNUM, u32 addr)
{
//printf("piano: read 08 at 0x%08X\n", adr);
//the actual keyboard output
//byte:bit
//0x09FFFFFE:0 = C
//0x09FFFFFE:1 = C#
//0x09FFFFFE:2 = D
//0x09FFFFFE:3 = D#
//0x09FFFFFE:4 = E
//0x09FFFFFE:5 = F
//0x09FFFFFE:6 = F#
//0x09FFFFFE:7 = G
//0x09FFFFFF:0 = G#
//0x09FFFFFF:1 = A
//0x09FFFFFF:2 = A#
//0x09FFFFFF:3 = ?
//0x09FFFFFF:4 = ?
//0x09FFFFFF:5 = B
//0x09FFFFFF:6 = hiC
//0x09FFFFFF:7 = ?
//deassert bit if key is pressed
//LOG("PIANO: %04X\n",pianoKeyStatus);
if (addr == 0x09FFFFFE) return ((pianoKeyStatus >> 0) & 0xFF);
if (addr == 0x09FFFFFF) return ((pianoKeyStatus >> 8) & 0xFF) & ~(0x18);
return (addr & 1) ? 0xE7 : 0xFF;
}
virtual u16 readWord(u8 PROCNUM, u32 addr)
{
if (addr != 0x09FFFFFE)
return 0xE7FF;
return readByte(PROCNUM, 0x09FFFFFE) | (readByte(PROCNUM,0x09FFFFFF) << 8);
}
virtual u32 readLong(u8 PROCNUM, u32 addr) { return 0xE7FFE7FF; }
};
ISlot2Interface* construct_Slot2_EasyPiano() { return new Slot2_EasyPiano(); }
void piano_setKey(bool c, bool cs, bool d, bool ds, bool e, bool f, bool fs, bool g, bool gs, bool a, bool as, bool b, bool hic)
{
//0x09FFFFFE:0 = C
//0x09FFFFFE:1 = C#
//0x09FFFFFE:2 = D
//0x09FFFFFE:3 = D#
//0x09FFFFFE:4 = E
//0x09FFFFFE:5 = F
//0x09FFFFFE:6 = F#
//0x09FFFFFE:7 = G
//0x09FFFFFE:0 = G#
//0x09FFFFFE:1 = A
//0x09FFFFFF:2 = A#
//0x09FFFFFF:3 = ?
//0x09FFFFFF:4 = ?
//0x09FFFFFF:5 = B
//0x09FFFFFF:6 = hiC
//0x09FFFFFF:7 = ?
#define BIT_P(N,v) ((v)?(1<<(N)):0)
pianoKeyStatus = ~(
BIT_P(0,c) |
BIT_P(1,cs) |
BIT_P(2,d) |
BIT_P(3,ds) |
BIT_P(4,e) |
BIT_P(5,f) |
BIT_P(6,fs) |
BIT_P(7,g) |
BIT_P(8,gs) |
BIT_P(9,a) |
BIT_P(10,as) |
BIT_P(13,b) |
BIT_P(14,hic)
);
}
void piano_setKey(u16 theKeys)
{
pianoKeyStatus = theKeys;
}

View File

@ -1,62 +0,0 @@
/*
Copyright (C) 2009 CrazyMax
Copyright (C) 2009-2013 DeSmuME team
This file is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
This file is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with the this software. If not, see <http://www.gnu.org/licenses/>.
*/
#include "../slot2.h"
void (*FeedbackON)(bool enable) = NULL;
class Slot2_RumblePak : public ISlot2Interface
{
private:
u16 old_val_rumble;
public:
virtual Slot2Info const* info()
{
static Slot2InfoSimple info("Rumble Pak", "NDS Rumble Pak (need joystick with Feedback)", 0x02);
return &info;
}
virtual void connect()
{
old_val_rumble = 0;
if (!FeedbackON) return;
FeedbackON(false);
}
virtual void disconnect()
{
FeedbackON(false);
}
virtual void writeWord(u8 PROCNUM, u32 addr, u16 val)
{
if (!FeedbackON) return;
if (old_val_rumble == val) return;
old_val_rumble = val;
if ((addr == 0x08000000) || (addr == 0x08001000))
FeedbackON(val);
}
virtual u8 readByte(u8 PROCNUM, u32 addr) { return (addr & 1)?0xFF:0xFD; };
virtual u16 readWord(u8 PROCNUM, u32 addr) { return 0xFFFD; };
virtual u32 readLong(u8 PROCNUM, u32 addr) { return 0xFFFDFFFD; };
};
ISlot2Interface* construct_Slot2_RumblePak() { return new Slot2_RumblePak(); }

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,82 +0,0 @@
/* Copyright (C) 2006 yopyop
Copyright (C) 2011 Loren Merritt
Copyright (C) 2012-2013 DeSmuME team
This file is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This file is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with the this software. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef ARM_JIT
#define ARM_JIT
#include "types.h"
#ifndef _MSC_VER
#include <stdint.h>
#endif
typedef u32 (FASTCALL* ArmOpCompiled)();
void arm_jit_reset(bool enable, bool suppress_msg = false);
void arm_jit_close();
void arm_jit_sync();
template<int PROCNUM> u32 arm_jit_compile();
//#define MAPPED_JIT_FUNCS: to define or not to define?
//* x86 windows seems faster with NON-DEFINED
//* x64 windows seems faster with DEFINED
//* x86 windows seems to have problems without DEFINED when desmume is built as a dll due to the
// ~300 MB .bss section created by the 256MB non-mapped compiled_funcs table
// (when loaded as a dll into a busy process, that much contiguous address space is hard to find. No big deal when starting up a process)
//In principle, mapped compiled_funcs should be faster because it avoids some bit shifting logic to look it up from the memory map, right,
//but I guess it doesn't always work out that way.
//
//So here's my proposed policy. NON-DEFINED is dangerous due to the huge .bss section, so it should be the default
//The build system should #define JIT_FUNCS_FLAT to make the flat array
#ifndef JIT_FUNCS_FLAT
#define MAPPED_JIT_FUNCS
#endif
#ifdef MAPPED_JIT_FUNCS
struct JIT_struct
{
// only include the memory types that code can execute from
uintptr_t MAIN_MEM[16*1024*1024/2];
uintptr_t SWIRAM[0x8000/2];
uintptr_t ARM9_ITCM[0x8000/2];
uintptr_t ARM9_LCDC[0xA4000/2];
uintptr_t ARM9_BIOS[0x8000/2];
uintptr_t ARM7_BIOS[0x4000/2];
uintptr_t ARM7_ERAM[0x10000/2];
uintptr_t ARM7_WIRAM[0x10000/2];
uintptr_t ARM7_WRAM[0x40000/2];
static uintptr_t *JIT_MEM[2][0x4000];
};
extern CACHE_ALIGN JIT_struct JIT;
#define JIT_COMPILED_FUNC(adr, PROCNUM) JIT.JIT_MEM[PROCNUM][((adr)&0x0FFFC000)>>14][((adr)&0x00003FFE)>>1]
#define JIT_COMPILED_FUNC_PREMASKED(adr, PROCNUM, ofs) JIT.JIT_MEM[PROCNUM][(adr)>>14][(((adr)&0x00003FFE)>>1)+ofs]
#define JIT_COMPILED_FUNC_KNOWNBANK(adr, bank, mask, ofs) JIT.bank[(((adr)&(mask))>>1)+ofs]
#define JIT_MAPPED(adr, PROCNUM) JIT.JIT_MEM[PROCNUM][(adr)>>14]
#else
// actually an array of function pointers, but they fit in 32bit address space, so might as well save memory
extern uintptr_t compiled_funcs[];
// there isn't anything mapped between 07000000 and 0EFFFFFF, so we can mask off bit 27 and get away with a smaller array
#define JIT_COMPILED_FUNC(adr, PROCNUM) compiled_funcs[((adr) & 0x07FFFFFE) >> 1]
#define JIT_COMPILED_FUNC_PREMASKED(adr, PROCNUM, ofs) JIT_COMPILED_FUNC(adr+(ofs<<1), PROCNUM)
#define JIT_COMPILED_FUNC_KNOWNBANK(adr, bank, mask, ofs) JIT_COMPILED_FUNC(adr+(ofs<<1), PROCNUM)
#define JIT_MAPPED(adr, PROCNUM) true
#endif
extern u32 saveBlockSizeJIT;
#endif

View File

@ -1,776 +0,0 @@
/*
Copyright (C) 2006 yopyop
Copyright (C) 2009-2021 DeSmuME team
This file is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
This file is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with the this software. If not, see <http://www.gnu.org/licenses/>.
*/
#include <stdlib.h>
#include <stdio.h>
#include <assert.h>
#include <algorithm>
#include "armcpu.h"
#include "instructions.h"
#include "cp15.h"
#include "bios.h"
#include "debug.h"
#include "NDSSystem.h"
#include "MMU_timing.h"
#include "utils/bits.h"
#ifdef HAVE_LUA
#include "lua-engine.h"
#endif
#ifdef TARGET_INTERFACE
#include "frontend/interface/interface.h"
#endif
#ifdef HAVE_JIT
#include "arm_jit.h"
#endif
template<u32> static u32 armcpu_prefetch();
FORCEINLINE u32 armcpu_prefetch(armcpu_t *armcpu) {
if(armcpu->proc_ID==0) return armcpu_prefetch<0>();
else return armcpu_prefetch<1>();
}
armcpu_t NDS_ARM7;
armcpu_t NDS_ARM9;
#define SWAP(a, b, c) do \
{ \
c=a; \
a=b; \
b=c; \
} \
while(0)
#define STALLED_CYCLE_COUNT 10
static void
stall_cpu( void *instance) {
armcpu_t *armcpu = (armcpu_t *)instance;
printf("STALL\n");
armcpu->stalled = 1;
}
static void
unstall_cpu( void *instance) {
armcpu_t *armcpu = (armcpu_t *)instance;
printf("UNSTALL\n");
armcpu->stalled = 0;
}
static void
install_post_exec_fn( void *instance,
void (*ex_fn)( void *, u32 adr, int thumb),
void *fn_data) {
armcpu_t *armcpu = (armcpu_t *)instance;
armcpu->post_ex_fn = ex_fn;
armcpu->post_ex_fn_data = fn_data;
}
static void
remove_post_exec_fn( void *instance) {
armcpu_t *armcpu = (armcpu_t *)instance;
armcpu->post_ex_fn = NULL;
}
static u32 read_cpu_reg( void *instance, u32 reg_num)
{
armcpu_t *armcpu = (armcpu_t *)instance;
if ( reg_num <= 14) {
return armcpu->R[reg_num];
}
else if ( reg_num == 15) {
return armcpu->instruct_adr;
}
else if ( reg_num == 16) {
//CPSR
return armcpu->CPSR.val;
}
return 0;
}
static void
set_cpu_reg( void *instance, u32 reg_num, u32 value) {
armcpu_t *armcpu = (armcpu_t *)instance;
if ( reg_num <= 14) {
armcpu->R[reg_num] = value;
}
else if ( reg_num == 15) {
armcpu->next_instruction = value;
}
else if ( reg_num == 16) {
/* FIXME: setting the CPSR */
}
}
int armcpu_new( armcpu_t *armcpu, u32 id)
{
armcpu->proc_ID = id;
armcpu->stalled = 0;
armcpu->base_mem_if.prefetch32 = NULL;
armcpu->base_mem_if.prefetch16 = NULL;
armcpu->base_mem_if.read8 = NULL;
armcpu->base_mem_if.read16 = NULL;
armcpu->base_mem_if.read32 = NULL;
armcpu->base_mem_if.write8 = NULL;
armcpu->base_mem_if.write16 = NULL;
armcpu->base_mem_if.write32 = NULL;
armcpu->base_mem_if.data = NULL;
armcpu_SetControlInterface(armcpu, &arm_default_ctrl_iface);
armcpu_SetControlInterfaceData(armcpu, armcpu);
armcpu_SetCurrentMemoryInterface(armcpu, NULL);
armcpu_SetCurrentMemoryInterfaceData(armcpu, NULL);
armcpu->post_ex_fn = NULL;
armcpu->post_ex_fn_data = NULL;
armcpu->breakPoints = new std::vector<u32>;
armcpu_init(armcpu, 0);
return 0;
}
void armcpu_SetControlInterface(armcpu_t *armcpu, const armcpu_ctrl_iface *theControlInterface)
{
armcpu->ctrl_iface = *theControlInterface;
}
armcpu_ctrl_iface* armcpu_GetControlInterface(armcpu_t *armcpu)
{
return &armcpu->ctrl_iface;
}
void armcpu_SetControlInterfaceData(armcpu_t *armcpu, void *theData)
{
armcpu->ctrl_iface.data = theData;
}
void* armcpu_GetControlInterfaceData(const armcpu_t *armcpu)
{
return armcpu->ctrl_iface.data;
}
void armcpu_SetCurrentMemoryInterface(armcpu_t *armcpu, armcpu_memory_iface *theMemoryInterface)
{
armcpu->mem_if = theMemoryInterface;
}
armcpu_memory_iface* armcpu_GetCurrentMemoryInterface(const armcpu_t *armcpu)
{
return armcpu->mem_if;
}
void armcpu_SetCurrentMemoryInterfaceData(armcpu_t *armcpu, void *theData)
{
if (armcpu->mem_if != NULL)
{
armcpu->mem_if->data = theData;
}
}
void* armcpu_GetCurrentMemoryInterfaceData(const armcpu_t *armcpu)
{
return (armcpu->mem_if != NULL) ? armcpu->mem_if->data : NULL;
}
void armcpu_SetBaseMemoryInterface(armcpu_t *armcpu, const armcpu_memory_iface *theMemInterface)
{
armcpu->base_mem_if = *theMemInterface;
}
armcpu_memory_iface* armcpu_GetBaseMemoryInterface(armcpu_t *armcpu)
{
return &armcpu->base_mem_if;
}
void armcpu_SetBaseMemoryInterfaceData(armcpu_t *armcpu, void *theData)
{
armcpu->base_mem_if.data = theData;
}
void* armcpu_GetBaseMemoryInterfaceData(const armcpu_t *armcpu)
{
return armcpu->base_mem_if.data;
}
void armcpu_ResetMemoryInterfaceToBase(armcpu_t *armcpu)
{
armcpu_SetCurrentMemoryInterface(armcpu, armcpu_GetBaseMemoryInterface(armcpu));
armcpu_SetCurrentMemoryInterfaceData(armcpu, armcpu_GetBaseMemoryInterfaceData(armcpu));
}
//call this whenever CPSR is changed (other than CNVZQ or T flags); interrupts may need to be unleashed
void armcpu_changeCPSR()
{
//but all it does is give them a chance to unleash by forcing an immediate reschedule
//TODO - we could actually set CPSR through here and look for a change in the I bit
//that would be a little optimization as well as a safety measure if we prevented setting CPSR directly
NDS_Reschedule();
}
void armcpu_init(armcpu_t *armcpu, u32 adr)
{
#if defined(_M_X64) || defined(__x86_64__)
memcpy(&armcpu->cond_table[0], &arm_cond_table[0], sizeof(arm_cond_table));
#endif
armcpu->LDTBit = (armcpu->proc_ID==0); //set ARMv5 style bit--different for each processor
armcpu->intVector = 0xFFFF0000 * (armcpu->proc_ID==0);
armcpu->freeze = CPU_FREEZE_NONE;
armcpu->intrWaitARM_state = 0;
//#ifdef GDB_STUB
// armcpu->irq_flag = 0;
//#endif
for(int i = 0; i < 16; ++i)
armcpu->R[i] = 0;
armcpu->CPSR.val = armcpu->SPSR.val = SYS;
armcpu->R13_usr = armcpu->R14_usr = 0;
armcpu->R13_svc = armcpu->R14_svc = 0;
armcpu->R13_abt = armcpu->R14_abt = 0;
armcpu->R13_und = armcpu->R14_und = 0;
armcpu->R13_irq = armcpu->R14_irq = 0;
armcpu->R8_fiq = armcpu->R9_fiq = armcpu->R10_fiq = armcpu->R11_fiq = armcpu->R12_fiq = armcpu->R13_fiq = armcpu->R14_fiq = 0;
armcpu->SPSR_svc.val = armcpu->SPSR_abt.val = armcpu->SPSR_und.val = armcpu->SPSR_irq.val = armcpu->SPSR_fiq.val = 0;
//#ifdef GDB_STUB
// armcpu->instruct_adr = adr;
// armcpu->R[15] = adr + 8;
//#else
//armcpu->R[15] = adr;
//#endif
//do something sensible when booting up to a thumb address
armcpu->next_instruction = adr & ~1;
armcpu->CPSR.bits.T = BIT0(adr);
//#ifndef GDB_STUB
armcpu_prefetch(armcpu);
//#endif
}
u32 armcpu_switchMode(armcpu_t *armcpu, u8 mode)
{
u32 oldmode = armcpu->CPSR.bits.mode;
switch(oldmode)
{
case USR :
case SYS :
armcpu->R13_usr = armcpu->R[13];
armcpu->R14_usr = armcpu->R[14];
break;
case FIQ :
{
u32 tmp;
SWAP(armcpu->R[8], armcpu->R8_fiq, tmp);
SWAP(armcpu->R[9], armcpu->R9_fiq, tmp);
SWAP(armcpu->R[10], armcpu->R10_fiq, tmp);
SWAP(armcpu->R[11], armcpu->R11_fiq, tmp);
SWAP(armcpu->R[12], armcpu->R12_fiq, tmp);
armcpu->R13_fiq = armcpu->R[13];
armcpu->R14_fiq = armcpu->R[14];
armcpu->SPSR_fiq = armcpu->SPSR;
break;
}
case IRQ :
armcpu->R13_irq = armcpu->R[13];
armcpu->R14_irq = armcpu->R[14];
armcpu->SPSR_irq = armcpu->SPSR;
break;
case SVC :
armcpu->R13_svc = armcpu->R[13];
armcpu->R14_svc = armcpu->R[14];
armcpu->SPSR_svc = armcpu->SPSR;
break;
case ABT :
armcpu->R13_abt = armcpu->R[13];
armcpu->R14_abt = armcpu->R[14];
armcpu->SPSR_abt = armcpu->SPSR;
break;
case UND :
armcpu->R13_und = armcpu->R[13];
armcpu->R14_und = armcpu->R[14];
armcpu->SPSR_und = armcpu->SPSR;
break;
default :
break;
}
switch(mode)
{
case USR :
case SYS :
armcpu->R[13] = armcpu->R13_usr;
armcpu->R[14] = armcpu->R14_usr;
//SPSR = CPSR;
break;
case FIQ :
{
u32 tmp;
SWAP(armcpu->R[8], armcpu->R8_fiq, tmp);
SWAP(armcpu->R[9], armcpu->R9_fiq, tmp);
SWAP(armcpu->R[10], armcpu->R10_fiq, tmp);
SWAP(armcpu->R[11], armcpu->R11_fiq, tmp);
SWAP(armcpu->R[12], armcpu->R12_fiq, tmp);
armcpu->R[13] = armcpu->R13_fiq;
armcpu->R[14] = armcpu->R14_fiq;
armcpu->SPSR = armcpu->SPSR_fiq;
break;
}
case IRQ :
armcpu->R[13] = armcpu->R13_irq;
armcpu->R[14] = armcpu->R14_irq;
armcpu->SPSR = armcpu->SPSR_irq;
break;
case SVC :
armcpu->R[13] = armcpu->R13_svc;
armcpu->R[14] = armcpu->R14_svc;
armcpu->SPSR = armcpu->SPSR_svc;
break;
case ABT :
armcpu->R[13] = armcpu->R13_abt;
armcpu->R[14] = armcpu->R14_abt;
armcpu->SPSR = armcpu->SPSR_abt;
break;
case UND :
armcpu->R[13] = armcpu->R13_und;
armcpu->R[14] = armcpu->R14_und;
armcpu->SPSR = armcpu->SPSR_und;
break;
default :
printf("switchMode: WRONG mode %02X\n",mode);
break;
}
armcpu->CPSR.bits.mode = mode & 0x1F;
armcpu_changeCPSR();
return oldmode;
}
u32 armcpu_Wait4IRQ(armcpu_t *cpu)
{
cpu->freeze = (CPU_FREEZE_WAIT_IRQ | CPU_FREEZE_IE_IF);
return 1;
}
template<u32 PROCNUM>
FORCEINLINE static u32 armcpu_prefetch()
{
armcpu_t* const armcpu = &ARMPROC;
//#ifdef GDB_STUB
// u32 temp_instruction;
//#endif
u32 curInstruction = armcpu->next_instruction;
if(armcpu->CPSR.bits.T == 0)
{
//#ifdef GDB_STUB
// temp_instruction =
// armcpu->mem_if->prefetch32( armcpu->mem_if->data,
// armcpu->next_instruction);
//
// if ( !armcpu->stalled) {
// armcpu->instruction = temp_instruction;
// armcpu->instruct_adr = armcpu->next_instruction;
// armcpu->next_instruction += 4;
// armcpu->R[15] = armcpu->next_instruction + 4;
// }
//#else
curInstruction &= 0xFFFFFFFC; //please don't change this to 0x0FFFFFFC -- the NDS will happily run on 0xF******* addresses all day long
//please note that we must setup R[15] before reading the instruction since there is a protection
//which prevents PC > 0x3FFF from reading the bios region
armcpu->instruct_adr = curInstruction;
armcpu->next_instruction = curInstruction + 4;
armcpu->R[15] = curInstruction + 8;
armcpu->instruction = _MMU_read32<PROCNUM, MMU_AT_CODE>(curInstruction);
//#endif
return MMU_codeFetchCycles<PROCNUM,32>(curInstruction);
}
//#ifdef GDB_STUB
// temp_instruction =
// armcpu->mem_if->prefetch16( armcpu->mem_if->data,
// armcpu->next_instruction);
//
// if ( !armcpu->stalled) {
// armcpu->instruction = temp_instruction;
// armcpu->instruct_adr = armcpu->next_instruction;
// armcpu->next_instruction = armcpu->next_instruction + 2;
// armcpu->R[15] = armcpu->next_instruction + 2;
// }
//#else
curInstruction &= 0xFFFFFFFE; //please don't change this to 0x0FFFFFFE -- the NDS will happily run on 0xF******* addresses all day long
//please note that we must setup R[15] before reading the instruction since there is a protection
//which prevents PC > 0x3FFF from reading the bios region
armcpu->instruct_adr = curInstruction;
armcpu->next_instruction = curInstruction + 2;
armcpu->R[15] = curInstruction + 4;
armcpu->instruction = _MMU_read16<PROCNUM, MMU_AT_CODE>(curInstruction);
//#endif
if(PROCNUM==0)
{
// arm9 fetches 2 instructions at a time in thumb mode
if(!(curInstruction == armcpu->instruct_adr + 2 && (curInstruction & 2)))
return MMU_codeFetchCycles<PROCNUM,32>(curInstruction);
else
return 0;
}
return MMU_codeFetchCycles<PROCNUM,16>(curInstruction);
}
#if 0 /* not used */
static BOOL FASTCALL test_EQ(Status_Reg CPSR) { return ( CPSR.bits.Z); }
static BOOL FASTCALL test_NE(Status_Reg CPSR) { return (!CPSR.bits.Z); }
static BOOL FASTCALL test_CS(Status_Reg CPSR) { return ( CPSR.bits.C); }
static BOOL FASTCALL test_CC(Status_Reg CPSR) { return (!CPSR.bits.C); }
static BOOL FASTCALL test_MI(Status_Reg CPSR) { return ( CPSR.bits.N); }
static BOOL FASTCALL test_PL(Status_Reg CPSR) { return (!CPSR.bits.N); }
static BOOL FASTCALL test_VS(Status_Reg CPSR) { return ( CPSR.bits.V); }
static BOOL FASTCALL test_VC(Status_Reg CPSR) { return (!CPSR.bits.V); }
static BOOL FASTCALL test_HI(Status_Reg CPSR) { return (CPSR.bits.C) && (!CPSR.bits.Z); }
static BOOL FASTCALL test_LS(Status_Reg CPSR) { return (CPSR.bits.Z) || (!CPSR.bits.C); }
static BOOL FASTCALL test_GE(Status_Reg CPSR) { return (CPSR.bits.N==CPSR.bits.V); }
static BOOL FASTCALL test_LT(Status_Reg CPSR) { return (CPSR.bits.N!=CPSR.bits.V); }
static BOOL FASTCALL test_GT(Status_Reg CPSR) { return (!CPSR.bits.Z) && (CPSR.bits.N==CPSR.bits.V); }
static BOOL FASTCALL test_LE(Status_Reg CPSR) { return ( CPSR.bits.Z) || (CPSR.bits.N!=CPSR.bits.V); }
static BOOL FASTCALL test_AL(Status_Reg CPSR) { return 1; }
static BOOL (FASTCALL* test_conditions[])(Status_Reg CPSR)= {
test_EQ , test_NE ,
test_CS , test_CC ,
test_MI , test_PL ,
test_VS , test_VC ,
test_HI , test_LS ,
test_GE , test_LT ,
test_GT , test_LE ,
test_AL
};
#define TEST_COND2(cond, CPSR) \
(cond<15&&test_conditions[cond](CPSR))
#endif
//TODO - merge with armcpu_irqException?
//http://www.ethernut.de/en/documents/arm-exceptions.html
//http://docs.google.com/viewer?a=v&q=cache:V4ht1YkxprMJ:www.cs.nctu.edu.tw/~wjtsai/EmbeddedSystemDesign/Ch3-1.pdf+arm+exception+handling&hl=en&gl=us&pid=bl&srcid=ADGEEShx9VTHbUhWdDOrTVRzLkcCsVfJiijncNDkkgkrlJkLa7D0LCpO8fQ_hhU3DTcgZh9rcZWWQq4TYhhCovJ625h41M0ZUX3WGasyzWQFxYzDCB-VS6bsUmpoJnRxAc-bdkD0qmsu&sig=AHIEtbR9VHvDOCRmZFQDUVwy53iJDjoSPQ
void armcpu_exception(armcpu_t *cpu, u32 number)
{
Mode cpumode = USR;
switch(number)
{
case EXCEPTION_RESET: cpumode = SVC; break;
case EXCEPTION_UNDEFINED_INSTRUCTION: cpumode = UND; break;
case EXCEPTION_SWI: cpumode = SVC; break;
case EXCEPTION_PREFETCH_ABORT: cpumode = ABT; break;
case EXCEPTION_DATA_ABORT: cpumode = ABT; break;
case EXCEPTION_RESERVED_0x14: emu_halt(EMUHALT_REASON_ARM_RESERVED_0X14_EXCEPTION, (cpu->proc_ID == ARMCPU_ARM9) ? NDSErrorTag_ARM9 : NDSErrorTag_ARM7); break;
case EXCEPTION_IRQ: cpumode = IRQ; break;
case EXCEPTION_FAST_IRQ: cpumode = FIQ; break;
}
Status_Reg tmp = cpu->CPSR;
armcpu_switchMode(cpu, cpumode); //enter new mode
cpu->R[14] = cpu->next_instruction;
cpu->SPSR = tmp; //save old CPSR as new SPSR
cpu->CPSR.bits.T = 0; //handle as ARM32 code
cpu->CPSR.bits.I = 1;
armcpu_changeCPSR();
cpu->R[15] = cpu->intVector + number;
cpu->next_instruction = cpu->R[15];
printf("armcpu_exception!\n");
//extern bool dolog;
//dolog=true;
//HOW DOES THIS WORTK WITHOUT A PREFETCH, LIKE IRQ BELOW?
//I REALLY WISH WE DIDNT PREFETCH BEFORE EXECUTING
}
BOOL armcpu_irqException(armcpu_t *armcpu)
{
Status_Reg tmp;
//TODO - remove GDB specific code
//#ifdef GDB_STUB
// armcpu->irq_flag = 0;
//#endif
tmp = armcpu->CPSR;
armcpu_switchMode(armcpu, IRQ);
//TODO - remove GDB specific code
//#ifdef GDB_STUB
// armcpu->R[14] = armcpu->next_instruction + 4;
//#else
armcpu->R[14] = armcpu->instruct_adr + 4;
//#endif
armcpu->SPSR = tmp;
armcpu->CPSR.bits.T = 0;
armcpu->CPSR.bits.I = 1;
armcpu->next_instruction = armcpu->intVector + 0x18;
armcpu->freeze &= ~CPU_FREEZE_IRQ_IE_IF;
//must retain invariant of having next instruction to be executed prefetched
//(yucky)
armcpu_prefetch(armcpu);
return TRUE;
}
//TODO - remove GDB specific code
//BOOL
//armcpu_flagIrq( armcpu_t *armcpu) {
// if(armcpu->CPSR.bits.I) return FALSE;
//
// armcpu->waitIRQ = 0;
//
//#ifdef GDB_STUB
// armcpu->irq_flag = 1;
//#endif
//
// return TRUE;
//}
u32 TRAPUNDEF(armcpu_t* cpu)
{
INFO("ARM%c: Undefined instruction: 0x%08X PC=0x%08X\n", cpu->proc_ID?'7':'9', cpu->instruction, cpu->instruct_adr);
if (((cpu->intVector != 0) ^ (cpu->proc_ID == ARMCPU_ARM9)))
{
armcpu_exception(&NDS_ARM9,EXCEPTION_UNDEFINED_INSTRUCTION);
return 4;
}
else
{
emu_halt(EMUHALT_REASON_ARM_UNDEFINED_INSTRUCTION_EXCEPTION, (cpu->proc_ID == ARMCPU_ARM9) ? NDSErrorTag_ARM9 : NDSErrorTag_ARM7);
return 4;
}
}
//BOOL
//armcpu_flagIrq( armcpu_t *armcpu) {
// if(armcpu->CPSR.bits.I) return FALSE;
//
// armcpu->waitIRQ = 0;
//
//#ifdef GDB_STUB
// armcpu->irq_flag = 1;
//#endif
//
// return TRUE;
//}
template<int PROCNUM>
u32 armcpu_exec()
{
// Usually, fetching and executing are processed parallelly.
// So this function stores the cycles of each process to
// the variables below, and returns appropriate cycle count.
u32 cFetch = 0;
u32 cExecute = 0;
//this assert is annoying. but sometimes it is handy.
//assert(ARMPROC.instruct_adr!=0x00000000);
//#ifdef DEVELOPER
#if 0
if ((((ARMPROC.instruct_adr & 0x0F000000) == 0x0F000000) && (PROCNUM == 0)) ||
(((ARMPROC.instruct_adr & 0x0F000000) == 0x00000000) && (PROCNUM == 1)))
{
switch (ARMPROC.instruct_adr & 0xFFFF)
{
case 0x00000000:
printf("BIOS%c: Reset!!!\n", PROCNUM?'7':'9');
emu_halt();
break;
case 0x00000004:
printf("BIOS%c: Undefined instruction\n", PROCNUM?'7':'9');
//emu_halt();
break;
case 0x00000008:
//printf("BIOS%c: SWI\n", PROCNUM?'7':'9');
break;
case 0x0000000C:
printf("BIOS%c: Prefetch Abort!!!\n", PROCNUM?'7':'9');
//emu_halt();
break;
case 0x00000010:
//printf("BIOS%c: Data Abort!!!\n", PROCNUM?'7':'9');
//emu_halt();
break;
case 0x00000014:
printf("BIOS%c: Reserved!!!\n", PROCNUM?'7':'9');
break;
case 0x00000018:
//printf("BIOS%c: IRQ\n", PROCNUM?'7':'9');
break;
case 0x0000001C:
printf("BIOS%c: Fast IRQ\n", PROCNUM?'7':'9');
break;
}
}
#endif
#if 0 //#ifdef GDB_STUB
if (ARMPROC.stalled) {
return STALLED_CYCLE_COUNT;
}
/* check for interrupts */
if (ARMPROC.irq_flag) {
armcpu_irqException(&ARMPROC);
}
cFetch = armcpu_prefetch(&ARMPROC);
if (ARMPROC.stalled) {
return MMU_fetchExecuteCycles<PROCNUM>(cExecute, cFetch);
}
#endif
//cFetch = armcpu_prefetch(&ARMPROC);
//printf("%d: %08X\n",PROCNUM,ARMPROC.instruct_adr);
if(ARMPROC.CPSR.bits.T == 0)
{
if(
CONDITION(ARMPROC.instruction) == 0x0E //fast path for unconditional instructions
|| (TEST_COND(CONDITION(ARMPROC.instruction), CODE(ARMPROC.instruction), ARMPROC.CPSR)) //handles any condition
)
{
#ifdef HAVE_LUA
CallRegisteredLuaMemHook(ARMPROC.instruct_adr, 4, ARMPROC.instruction, LUAMEMHOOK_EXEC); // should report even if condition=false?
#endif
#ifdef TARGET_INTERFACE
call_registered_interface_mem_hook(ARMPROC.instruct_adr, 4, HOOK_EXEC);
#endif
#ifdef DEVELOPER
DEBUG_statistics.instructionHits[PROCNUM].arm[INSTRUCTION_INDEX(ARMPROC.instruction)]++;
#endif
cExecute = arm_instructions_set[PROCNUM][INSTRUCTION_INDEX(ARMPROC.instruction)](ARMPROC.instruction);
}
else
cExecute = 1; // If condition=false: 1S cycle
#ifdef GDB_STUB
if ( ARMPROC.post_ex_fn != NULL) {
/* call the external post execute function */
ARMPROC.post_ex_fn(ARMPROC.post_ex_fn_data, ARMPROC.instruct_adr, 0);
}
ARMPROC.mem_if->prefetch32( ARMPROC.mem_if->data, ARMPROC.next_instruction);
#endif
cFetch = armcpu_prefetch<PROCNUM>();
return MMU_fetchExecuteCycles<PROCNUM>(cExecute, cFetch);
}
#ifdef HAVE_LUA
CallRegisteredLuaMemHook(ARMPROC.instruct_adr, 2, ARMPROC.instruction, LUAMEMHOOK_EXEC);
#endif
#ifdef TARGET_INTERFACE
call_registered_interface_mem_hook(ARMPROC.instruct_adr, 2, HOOK_EXEC);
#endif
#ifdef DEVELOPER
DEBUG_statistics.instructionHits[PROCNUM].thumb[ARMPROC.instruction>>6]++;
#endif
cExecute = thumb_instructions_set[PROCNUM][ARMPROC.instruction>>6](ARMPROC.instruction);
#ifdef GDB_STUB
if ( ARMPROC.post_ex_fn != NULL) {
/* call the external post execute function */
ARMPROC.post_ex_fn( ARMPROC.post_ex_fn_data, ARMPROC.instruct_adr, 1);
}
ARMPROC.mem_if->prefetch32( ARMPROC.mem_if->data, ARMPROC.next_instruction);
#endif
cFetch = armcpu_prefetch<PROCNUM>();
return MMU_fetchExecuteCycles<PROCNUM>(cExecute, cFetch);
}
//these templates needed to be instantiated manually
template u32 armcpu_exec<0>();
template u32 armcpu_exec<1>();
#ifdef HAVE_JIT
void arm_jit_sync()
{
NDS_ARM7.next_instruction = NDS_ARM7.instruct_adr;
NDS_ARM9.next_instruction = NDS_ARM9.instruct_adr;
armcpu_prefetch<0>();
armcpu_prefetch<1>();
}
template<int PROCNUM, bool jit>
u32 armcpu_exec()
{
if (jit)
{
ARMPROC.instruct_adr &= ARMPROC.CPSR.bits.T?0xFFFFFFFE:0xFFFFFFFC;
ArmOpCompiled f = (ArmOpCompiled)JIT_COMPILED_FUNC(ARMPROC.instruct_adr, PROCNUM);
return f ? f() : arm_jit_compile<PROCNUM>();
}
return armcpu_exec<PROCNUM>();
}
template u32 armcpu_exec<0,false>();
template u32 armcpu_exec<0,true>();
template u32 armcpu_exec<1,false>();
template u32 armcpu_exec<1,true>();
#endif
void setIF(int PROCNUM, u32 flag)
{
//don't set generated bits!!!
assert(!(flag&0x00200000));
MMU.reg_IF_bits[PROCNUM] |= flag;
NDS_Reschedule();
}
const armcpu_ctrl_iface arm_default_ctrl_iface = {
stall_cpu,
unstall_cpu,
read_cpu_reg,
set_cpu_reg,
install_post_exec_fn,
remove_post_exec_fn,
NULL
};

View File

@ -1,366 +0,0 @@
/*
Copyright (C) 2006 yopyop
Copyright (C) 2006-2021 DeSmuME team
This file is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
This file is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with the this software. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef DESMUME_ARMCPU_H
#define DESMUME_ARMCPU_H
//half of this stuff is arm cpu internals
//half is public API
//really a mess
#include "types.h"
#include "MMU.h"
#define CONDITION(i) ((i)>>28)
#define REG_POS(i,n) (((i)>>n)&0xF)
#define CODE(i) (((i)>>25)&0x7)
#define OPCODE(i) (((i)>>21)&0xF)
#define SIGNEBIT(i) (((i)>>20)&1)
#define EXCEPTION_RESET 0x00
#define EXCEPTION_UNDEFINED_INSTRUCTION 0x04
#define EXCEPTION_SWI 0x08
#define EXCEPTION_PREFETCH_ABORT 0x0C
#define EXCEPTION_DATA_ABORT 0x10
#define EXCEPTION_RESERVED_0x14 0x14
#define EXCEPTION_IRQ 0x18
#define EXCEPTION_FAST_IRQ 0x1C
#define CPU_FREEZE_NONE 0x00
#define CPU_FREEZE_WAIT_IRQ 0x01 //waiting for some IRQ to happen, any IRQ
#define CPU_FREEZE_IE_IF 0x02 //waiting for IE&IF to signal something (probably edge triggered on IRQ too)
#define CPU_FREEZE_IRQ_IE_IF (CPU_FREEZE_WAIT_IRQ|CPU_FREEZE_IE_IF)
#define CPU_FREEZE_OVERCLOCK_HACK 0x04
#define INSTRUCTION_INDEX(i) ((((i)>>16)&0xFF0)|(((i)>>4)&0xF))
inline u32 ROR(u32 i, u32 j) { return ((((u32)(i))>>(j)) | (((u32)(i))<<(32-(j)))); }
template<typename T>
inline T UNSIGNED_OVERFLOW(T a,T b,T c) { return BIT31(((a)&(b)) | (((a)|(b))&(~c))); }
template<typename T>
inline T UNSIGNED_UNDERFLOW(T a,T b,T c) { return BIT31(((~a)&(b)) | (((~a)|(b))&(c))); }
template<typename T>
inline T SIGNED_OVERFLOW(T a,T b,T c) { return BIT31(((a)&(b)&(~c)) | ((~a)&(~(b))&(c))); }
template<typename T>
inline T SIGNED_UNDERFLOW(T a,T b,T c) { return BIT31(((a)&(~(b))&(~c)) | ((~a)&(b)&(c))); }
#if !defined(bswap32)
#define bswap32(val) \
( (val << 24) & 0xFF000000) | \
( (val << 8) & 0x00FF0000) | \
( (val >> 8) & 0x0000FF00) | \
( (val >> 24) & 0x000000FF)
#endif
#if !defined(bswap64)
#define bswap64(x) \
( (x << 56) & 0xff00000000000000ULL ) | \
( (x << 40) & 0x00ff000000000000ULL ) | \
( (x << 24) & 0x0000ff0000000000ULL ) | \
( (x << 8) & 0x000000ff00000000ULL ) | \
( (x >> 8) & 0x00000000ff000000ULL ) | \
( (x >> 24) & 0x0000000000ff0000ULL ) | \
( (x >> 40) & 0x000000000000ff00ULL ) | \
( (x >> 56) & 0x00000000000000ffULL )
#endif
// ============================= CPRS flags funcs
inline bool CarryFrom(s32 left, s32 right)
{
u32 res = (0xFFFFFFFFU - (u32)left);
return ((u32)right > res);
}
inline bool BorrowFrom(s32 left, s32 right)
{
return ((u32)right > (u32)left);
}
inline bool OverflowFromADD(s32 alu_out, s32 left, s32 right)
{
return ((left >= 0 && right >= 0) || (left < 0 && right < 0))
&& ((left < 0 && alu_out >= 0) || (left >= 0 && alu_out < 0));
}
inline bool OverflowFromSUB(s32 alu_out, s32 left, s32 right)
{
return ((left < 0 && right >= 0) || (left >= 0 && right < 0))
&& ((left < 0 && alu_out >= 0) || (left >= 0 && alu_out < 0));
}
//zero 15-feb-2009 - these werent getting used and they were getting in my way
//#define EQ 0x0
//#define NE 0x1
//#define CS 0x2
//#define CC 0x3
//#define MI 0x4
//#define PL 0x5
//#define VS 0x6
//#define VC 0x7
//#define HI 0x8
//#define LS 0x9
//#define GE 0xA
//#define LT 0xB
//#define GT 0xC
//#define LE 0xD
//#define AL 0xE
static const u8 arm_cond_table[16*16] = {
// N=0, Z=0, C=0, V=0
0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF, // 0x00
0x00,0xFF,0xFF,0x00,0xFF,0x00,0xFF,0x20, // 0x00
// N=0, Z=0, C=0, V=1
0x00,0xFF,0x00,0xFF,0x00,0xFF,0xFF,0x00, // 0x10
0x00,0xFF,0x00,0xFF,0x00,0xFF,0xFF,0x20,
// N=0, Z=0, C=1, V=0
0x00,0xFF,0xFF,0x00,0x00,0xFF,0x00,0xFF, // 0x20
0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF,0x20,
// N=0, Z=0, C=1, V=1
0x00,0xFF,0xFF,0x00,0x00,0xFF,0xFF,0x00, // 0x30
0xFF,0x00,0x00,0xFF,0x00,0xFF,0xFF,0x20,
// N=0, Z=1, C=0, V=0
0xFF,0x00,0x00,0xFF,0x00,0xFF,0x00,0xFF, // 0x40
0x00,0xFF,0xFF,0x00,0x00,0xFF,0xFF,0x20,
// N=0, Z=1, C=0, V=1
0xFF,0x00,0x00,0xFF,0x00,0xFF,0xFF,0x00, // 0x50
0x00,0xFF,0x00,0xFF,0x00,0xFF,0xFF,0x20,
// N=0, Z=1, C=1, V=0
0xFF,0x00,0xFF,0x00,0x00,0xFF,0x00,0xFF, // 0x60
0x00,0xFF,0xFF,0x00,0x00,0xFF,0xFF,0x20,
// N=0, Z=1, C=1, V=1
0xFF,0x00,0xFF,0x00,0x00,0xFF,0xFF,0x00, // 0x70
0x00,0xFF,0x00,0xFF,0x00,0xFF,0xFF,0x20,
// N=1, Z=0, C=0, V=0
0x00,0xFF,0x00,0xFF,0xFF,0x00,0x00,0xFF, // 0x80
0x00,0xFF,0x00,0xFF,0x00,0xFF,0xFF,0x20,
// N=1, Z=0, C=0, V=1
0x00,0xFF,0x00,0xFF,0xFF,0x00,0xFF,0x00, // 0x90
0x00,0xFF,0xFF,0x00,0xFF,0x00,0xFF,0x20,
// N=1, Z=0, C=1, V=0
0x00,0xFF,0xFF,0x00,0xFF,0x00,0x00,0xFF, // 0xA0
0xFF,0x00,0x00,0xFF,0x00,0xFF,0xFF,0x20,
// N=1, Z=0, C=1, V=1
0x00,0xFF,0xFF,0x00,0xFF,0x00,0xFF,0x00, // 0xB0
0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF,0x20,
// N=1, Z=1, C=0, V=0
0xFF,0x00,0x00,0xFF,0xFF,0x00,0x00,0xFF, // 0xC0
0x00,0xFF,0x00,0xFF,0x00,0xFF,0xFF,0x20,
// N=1, Z=1, C=0, V=1
0xFF,0x00,0x00,0xFF,0xFF,0x00,0xFF,0x00, // 0xD0
0x00,0xFF,0xFF,0x00,0x00,0xFF,0xFF,0x20,
// N=1, Z=1, C=1, V=0
0xFF,0x00,0xFF,0x00,0xFF,0x00,0x00,0xFF, // 0xE0
0x00,0xFF,0x00,0xFF,0x00,0xFF,0xFF,0x20,
// N=1, Z=1, C=1, V=1
0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00, // 0xF0
0x00,0xFF,0xFF,0x00,0x00,0xFF,0xFF,0x20
};
#define TEST_COND(cond, inst, CPSR) ((arm_cond_table[((CPSR.val >> 24) & 0xf0)|(cond)]) & (1 << (inst)))
enum Mode
{
USR = 0x10,
FIQ = 0x11,
IRQ = 0x12,
SVC = 0x13,
ABT = 0x17,
UND = 0x1B,
SYS = 0x1F
};
typedef union
{
struct
{
#ifdef MSB_FIRST
u32 N : 1,
Z : 1,
C : 1,
V : 1,
Q : 1,
RAZ : 19,
I : 1,
F : 1,
T : 1,
mode : 5;
#else
u32 mode : 5,
T : 1,
F : 1,
I : 1,
RAZ : 19,
Q : 1,
V : 1,
C : 1,
Z : 1,
N : 1;
#endif
} bits;
u32 val;
} Status_Reg;
/**
* The control interface to a CPU
*/
struct armcpu_ctrl_iface
{
/** stall the processor */
void (*stall)( void *instance);
/** unstall the processor */
void (*unstall)( void *instance);
/** read a register value */
u32 (*read_reg)( void *instance, u32 reg_num);
/** set a register value */
void (*set_reg)( void *instance, u32 reg_num, u32 value);
/** install the post execute function */
void (*install_post_ex_fn)( void *instance,
void (*fn)( void *, u32 adr, int thumb),
void *fn_data);
/** remove the post execute function */
void (*remove_post_ex_fn)( void *instance);
/** the private data passed to all interface functions */
void *data;
};
typedef void* armcp_t;
struct armcpu_t
{
u32 proc_ID;
u32 instruction; //4
u32 instruct_adr; //8
u32 next_instruction; //12
u32 R[16]; //16
Status_Reg CPSR; //80
Status_Reg SPSR;
u32 R13_usr, R14_usr;
u32 R13_svc, R14_svc;
u32 R13_abt, R14_abt;
u32 R13_und, R14_und;
u32 R13_irq, R14_irq;
u32 R8_fiq, R9_fiq, R10_fiq, R11_fiq, R12_fiq, R13_fiq, R14_fiq;
Status_Reg SPSR_svc, SPSR_abt, SPSR_und, SPSR_irq, SPSR_fiq;
u32 intVector;
u8 LDTBit; //1 : ARMv5 style 0 : non ARMv5 (earlier)
u32 freeze;
//BOOL waitIRQ;
//BOOL halt_IE_and_IF;
u8 intrWaitARM_state;
BOOL BIOS_loaded;
u32 (* *swi_tab)();
// flag indicating if the processor is stalled (for debugging)
int stalled;
#if defined(_M_X64) || defined(__x86_64__)
u8 cond_table[16*16];
#endif
/** there is a pending irq for the cpu */
int irq_flag;
/** the post executed function (if installed) */
void (*post_ex_fn)( void *, u32 adr, int thumb);
/** data for the post executed function */
void *post_ex_fn_data;
/** the memory interface */
armcpu_memory_iface *mem_if; // This is the memory interface currently in use.
armcpu_memory_iface base_mem_if; // This is the CPU's base memory interface.
/** the ctrl interface */
armcpu_ctrl_iface ctrl_iface;
// debugging stuff
u32 runToRetTmp;
bool runToRet;
u32 stepOverBreak;
std::vector<u32> *breakPoints;
bool debugStep;
};
void armcpu_SetControlInterface(armcpu_t *armcpu, const armcpu_ctrl_iface *theCtrlInterface);
armcpu_ctrl_iface* armcpu_GetControlInterface(armcpu_t *armcpu);
void armcpu_SetControlInterfaceData(armcpu_t *armcpu, void *theData);
void* armcpu_GetControlInterfaceData(const armcpu_t *armcpu);
void armcpu_SetCurrentMemoryInterface(armcpu_t *armcpu, armcpu_memory_iface *theMemInterface);
armcpu_memory_iface* armcpu_GetCurrentMemoryInterface(const armcpu_t *armcpu);
void armcpu_SetCurrentMemoryInterfaceData(armcpu_t *armcpu, void *theData);
void* armcpu_GetCurrentMemoryInterfaceData(const armcpu_t *armcpu);
void armcpu_SetBaseMemoryInterface(armcpu_t *armcpu, const armcpu_memory_iface *theMemInterface);
armcpu_memory_iface* armcpu_GetBaseMemoryInterface(armcpu_t *armcpu);
void armcpu_SetBaseMemoryInterfaceData(armcpu_t *armcpu, void *theData);
void* armcpu_GetBaseMemoryInterfaceData(const armcpu_t *armcpu);
void armcpu_ResetMemoryInterfaceToBase(armcpu_t *armcpu);
void armcpu_changeCPSR();
int armcpu_new( armcpu_t *armcpu, u32 id);
void armcpu_init(armcpu_t *armcpu, u32 adr);
u32 armcpu_switchMode(armcpu_t *armcpu, u8 mode);
BOOL armcpu_irqException(armcpu_t *armcpu);
BOOL armcpu_flagIrq( armcpu_t *armcpu);
void armcpu_exception(armcpu_t *cpu, u32 number);
u32 TRAPUNDEF(armcpu_t* cpu);
u32 armcpu_Wait4IRQ(armcpu_t *cpu);
extern armcpu_t NDS_ARM7;
extern armcpu_t NDS_ARM9;
extern const armcpu_ctrl_iface arm_default_ctrl_iface;
template<int PROCNUM> u32 armcpu_exec();
#ifdef HAVE_JIT
template<int PROCNUM, bool jit> u32 armcpu_exec();
#endif
void setIF(int PROCNUM, u32 flag);
static INLINE void NDS_makeIrq(int PROCNUM, u32 num)
{
setIF(PROCNUM,1<<num);
}
#endif

View File

@ -1,28 +0,0 @@
/*
Copyright (C) 2006 yopyop
Copyright (C) 2006-2015 DeSmuME team
This file is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
This file is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with the this software. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef BIOS_H
#define BIOS_H
#include "types.h"
extern u32 (* ARM_swi_tab[2][32])();
extern const char* ARM_swi_names[2][32];
#endif

File diff suppressed because it is too large Load Diff

View File

@ -1,329 +0,0 @@
/*
Copyright (C) 2009-2024 DeSmuME team
This file is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
This file is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with the this software. If not, see <http://www.gnu.org/licenses/>.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <string>
#include <vector>
#include "types.h"
#define CHEAT_VERSION_MAJOR 2
#define CHEAT_VERSION_MINOR 0
#define MAX_XX_CODE 1024
#define CHEAT_FILE_MIN_FGETS_BUFFER 32768
#define CHEAT_TYPE_EMPTY 0xFF
#define CHEAT_TYPE_INTERNAL 0
#define CHEAT_TYPE_AR 1
#define CHEAT_TYPE_CODEBREAKER 2
enum CheatSystemError
{
CheatSystemError_NoError = 0,
CheatSystemError_FileOpenFailed = 1,
CheatSystemError_FileFormatInvalid = 2,
CheatSystemError_GameNotFound = 3,
CheatSystemError_LoadEntryError = 4,
CheatSystemError_FileSaveFailed = 5,
CheatSystemError_FileDoesNotExist = 6
};
struct CHEATS_LIST
{
CHEATS_LIST()
{
memset(this,0,sizeof(*this));
type = CHEAT_TYPE_EMPTY;
}
u8 type;
u8 enabled;
// TODO
u8 freezeType; // 0 - normal freeze
// 1 - can decrease
// 2 - can increase
u32 code[MAX_XX_CODE][2];
union
{
char description[1024];
struct
{
char descriptionMajor[512];
char descriptionMinor[512];
};
};
u32 num;
u8 size;
};
class CHEATS
{
private:
std::vector<CHEATS_LIST> _list;
u8 _filename[MAX_PATH];
size_t _currentGet;
char *clearCode(char *s);
public:
CHEATS()
: _currentGet(0)
{
memset(_filename, 0, sizeof(_filename));
}
~CHEATS() {}
void clear();
void init(const char *thePath);
const char* getFilePath() const;
void setFilePath(const char *thePath);
size_t addItem(const CHEATS_LIST &srcCheat);
bool add(u8 size, u32 address, u32 val, char *description, bool enabled);
bool add(u8 size, u32 address, u32 val, char *description, u8 enabled);
bool updateItemAtIndex(const CHEATS_LIST &srcCheat, const size_t pos);
bool update(u8 size, u32 address, u32 val, char *description, bool enabled, const size_t pos);
bool update(u8 size, u32 address, u32 val, char *description, u8 enabled, const size_t pos);
bool move(size_t srcPos, size_t dstPos);
size_t add_AR_Direct(const CHEATS_LIST &srcCheat);
bool add_AR(char *code, char *description, bool enabled);
bool add_AR(char *code, char *description, u8 enabled);
bool update_AR(char *code, char *description, bool enabled, const size_t pos);
bool update_AR(char *code, char *description, u8 enabled, const size_t pos);
bool add_CB(char *code, char *description, bool enabled);
bool add_CB(char *code, char *description, u8 enabled);
bool update_CB(char *code, char *description, bool enabled, const size_t pos);
bool update_CB(char *code, char *description, u8 enabled, const size_t pos);
bool remove(const size_t pos);
void toggle(bool enabled, const size_t pos);
void toggle(u8 enablbed, const size_t pos);
void getListReset();
bool getList(CHEATS_LIST *cheat);
CHEATS_LIST* getListPtr();
bool copyItemFromIndex(const size_t pos, CHEATS_LIST &outCheatItem);
CHEATS_LIST* getItemPtrAtIndex(const size_t pos) const;
size_t getListSize() const;
size_t getActiveCount() const;
void setDescription(const char *description, const size_t pos);
bool save();
bool load();
bool process(int targetType) const;
static void JitNeedsReset();
static bool ResetJitIfNeeded();
template<size_t LENGTH> static bool DirectWrite(const int targetProc, const u32 targetAddress, u32 newValue);
static bool DirectWrite(const size_t newValueLength, const int targetProc, const u32 targetAddress, u32 newValue);
static bool ARparser(const CHEATS_LIST &cheat);
static void StringFromXXCode(const CHEATS_LIST &srcCheatItem, char *outCStringBuffer);
static bool XXCodeFromString(const std::string codeString, CHEATS_LIST &outCheatItem);
static bool XXCodeFromString(const char *codeString, CHEATS_LIST &outCheatItem);
};
class CHEATSEARCH
{
private:
u8 *_statMem;
u8 *_mem;
u32 _amount;
u32 _lastRecord;
u32 _type;
u32 _size;
u32 _sign;
public:
CHEATSEARCH()
: _statMem(0), _mem(0), _amount(0), _lastRecord(0), _type(0), _size(0), _sign(0)
{}
~CHEATSEARCH() { this->close(); }
bool start(u8 type, u8 size, u8 sign);
void close();
u32 search(u32 val);
u32 search(u8 comp);
u32 getAmount();
bool getList(u32 *address, u32 *curVal);
void getListReset();
};
#define CHEATDB_OFFSET_FILE_DESCRIPTION 0x00000010
#define CHEATDB_FILEOFFSET_FIRST_FAT_ENTRY 0x00000100
enum CheatDBFileFormat
{
CheatDBFileFormat_Undefined = 0,
CheatDBFileFormat_R4 = 1,
CheatDBFileFormat_Unknown = 65535
};
// This struct maps to the FAT entries in the R4 cheat database file.
#pragma pack(push)
#pragma pack(1)
typedef struct FAT_R4
{
u8 serial[4];
u32 CRC;
u64 addr;
} FAT_R4;
#pragma pack(pop)
// Wrapper for a single entry in a memory block that contains data read from a cheat database file.
// This struct also maintains the hierarchical relationships between entries.
struct CheatDBEntry
{
u8 *base; // Pointer to the entry's base location in memory.
char *name; // Pointer to the entry's name string.
char *note; // Pointer to the entry's note string.
u32 *codeLength; // Pointer to the entry's 32-bit code length in bytes. This value is NULL if the entry is a directory.
u32 *codeData; // Pointer to the entry's code data, provided in pairs of 32-bit values. This value is NULL if the entry is a directory.
CheatDBEntry *parent;
std::vector<CheatDBEntry> child;
};
typedef struct CheatDBEntry CheatDBEntry;
class CheatDBGame
{
protected:
u32 _baseOffset; // This offset is relative to the file head.
u32 _firstEntryOffset; // This offset is relative to the file head.
u32 _encryptOffset; // This offset is relative to the memory address of this->_entryDataRawPtr.
u32 _rawDataSize;
u32 _workingDataSize;
u32 _crc;
u32 _entryCount;
std::string _title;
char _serial[4 + 1];
u8 *_entryDataRawPtr;
u8 *_entryData;
CheatDBEntry _entryRoot;
u32 _cheatItemCount;
void _UpdateDirectoryParents(CheatDBEntry &directory);
bool _CreateCheatItemFromCheatEntry(const CheatDBEntry &inEntry, const bool isHierarchical, CHEATS_LIST &outCheatItem);
size_t _DirectoryAddCheatsFlat(const CheatDBEntry &directory, const bool isHierarchical, size_t cheatIndex, CHEATS_LIST *outCheatsList);
public:
CheatDBGame();
CheatDBGame(const u32 encryptOffset, const FAT_R4 &fat, const u32 rawDataSize);
CheatDBGame(FILE *fp, const bool isEncrypted, const u32 encryptOffset, const FAT_R4 &fat, const u32 rawDataSize, u8 (&workingBuffer)[1024]);
~CheatDBGame();
void SetInitialProperties(const u32 rawDataSize, const u32 encryptOffset, const FAT_R4 &fat);
void LoadPropertiesFromFile(FILE *fp, const bool isEncrypted, u8 (&workingBuffer)[1024]);
u32 GetBaseOffset() const;
u32 GetFirstEntryOffset() const;
u32 GetEncryptOffset() const;
u32 GetRawDataSize() const;
u32 GetWorkingDataSize() const;
u32 GetCRC() const;
u32 GetEntryCount() const;
u32 GetCheatItemCount() const;
const char* GetTitle() const;
const char* GetSerial() const;
const CheatDBEntry& GetEntryRoot() const;
const u8* GetEntryRawData() const;
bool IsEntryDataLoaded() const;
u8* LoadEntryData(FILE *fp, const bool isEncrypted);
size_t ParseEntriesToCheatsListFlat(CHEATS_LIST *outCheatsList);
};
typedef std::vector<CheatDBGame> CheatDBGameList;
class CheatDBFile
{
protected:
std::string _path;
std::string _description;
std::string _formatString;
CheatDBFileFormat _format;
bool _isEncrypted;
size_t _size;
FILE *_fp;
CheatDBGame _ReadGame(const u32 encryptOffset, const FAT_R4 &fat, const u32 gameDataSize, u8 (&workingBuffer)[1024]);
public:
CheatDBFile();
~CheatDBFile();
static void R4Decrypt(u8 *buf, const size_t len, u64 n);
static bool ReadToBuffer(FILE *fp, const size_t fileOffset, const bool isEncrypted, const size_t encryptOffset, const size_t requestedSize, u8 *outBuffer);
FILE* GetFilePtr() const;
bool IsEncrypted() const;
const char* GetDescription() const;
CheatDBFileFormat GetFormat() const;
const char* GetFormatString() const;
CheatSystemError OpenFile(const char *filePath);
void CloseFile();
u32 LoadGameList(const char *gameCode, const u32 gameDatabaseCRC, CheatDBGameList &outList);
};
class CHEATSEXPORT
{
private:
CheatDBFile _dbFile;
CheatDBGameList _tempGameList;
CheatDBGame *_selectedDbGame;
CHEATS_LIST *_cheats;
CheatSystemError _lastError;
public:
CHEATSEXPORT();
~CHEATSEXPORT();
bool load(const char *path);
void close();
CHEATS_LIST *getCheats() const;
size_t getCheatsNum() const;
const char* getGameTitle() const;
const char* getDescription() const;
CheatSystemError getErrorCode() const;
};
CheatDBGame* GetCheatDBGameEntryFromList(const CheatDBGameList &gameList, const char *gameCode, const u32 gameDatabaseCRC);
void CheatItemGenerateDescriptionHierarchical(const char *itemName, const char *itemNote, CHEATS_LIST &outCheatItem);
void CheatItemGenerateDescriptionFlat(const char *folderName, const char *folderNote, const char *itemName, const char *itemNote, CHEATS_LIST &outCheatItem);
extern CHEATS *cheats;
extern CHEATSEARCH *cheatSearch;

View File

@ -1,634 +0,0 @@
/*
Copyright (C) 2009-2017 DeSmuME team
This file is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
This file is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with the this software. If not, see <http://www.gnu.org/licenses/>.
*/
//windows note: make sure this file gets compiled with _cdecl
#include <algorithm>
#include <stdio.h>
#include "commandline.h"
#include "types.h"
#include "movie.h"
#include "rtc.h"
#include "slot1.h"
#include "slot2.h"
#include "NDSSystem.h"
#include "utils/datetime.h"
#include "utils/xstring.h"
#include <compat/getopt.h>
//#include "frontend/modules/mGetOpt.h" //to test with this, make sure global `optind` is initialized to 1
#define printerror(...) fprintf(stderr, __VA_ARGS__)
int _scanline_filter_a = 0, _scanline_filter_b = 2, _scanline_filter_c = 2, _scanline_filter_d = 4;
int _commandline_linux_nojoy = 0;
CommandLine::CommandLine()
: is_cflash_configured(false)
, _load_to_memory(-1)
, _play_movie_file(0)
, _record_movie_file(0)
, _cflash_image(0)
, _cflash_path(0)
, _gbaslot_rom(0)
, _bios_arm9(NULL)
, _bios_arm7(NULL)
, _bios_swi(0)
, _fw_path(NULL)
, _fw_boot(0)
, _spu_sync_mode(-1)
, _spu_sync_method(-1)
, _spu_advanced(0)
, _num_cores(-1)
, _rigorous_timing(0)
, _advanced_timing(-1)
, _gamehacks(-1)
, _texture_deposterize(-1)
, _texture_smooth(-1)
, _slot1(NULL)
, _slot1_fat_dir(NULL)
, _slot1_fat_dir_type(false)
, _slot1_no8000prot(0)
#ifdef HAVE_JIT
, _cpu_mode(-1)
, _jit_size(-1)
#endif
, _console_type(NULL)
, _advanscene_import(NULL)
, load_slot(-1)
, arm9_gdb_port(0)
, arm7_gdb_port(0)
, start_paused(FALSE)
, autodetect_method(-1)
, render3d(COMMANDLINE_RENDER3D_DEFAULT)
, texture_upscale(-1)
, gpu_resolution_multiplier(-1)
, language(1) //english by default
, disable_sound(0)
, disable_limiter(0)
, windowed_fullscreen(0)
, frameskip(0)
, horizontal(0)
, scale(1.0)
, _rtc_day(-1)
, _rtc_hour(-1)
{
}
CommandLine::~CommandLine()
{
}
static char mytoupper(char c) { return ::toupper(c); }
static std::string strtoupper(const std::string& str)
{
std::string ret = str;
std::transform(ret.begin(), ret.end(), ret.begin(), ::mytoupper);
return ret;
}
#define ENDL "\n"
static const char* help_string = \
"Arguments affecting overall emulator behaviour: (`user settings`):" ENDL
" --num-cores N Override numcores detection and use this many" ENDL
" --spu-synch Use SPU synch (crackles; helps streams; default ON)" ENDL
" --spu-method N Select SPU synch method: 0:N, 1:Z, 2:P; default 0" ENDL
" --3d-render [SW|AUTOGL|GL|OLDGL]" ENDL
" Select 3d renderer; default SW" ENDL
" --3d-texture-deposterize-enable" ENDL
" Enables texture deposterization." ENDL
" --3d-texture-upscale [1|2|4]" ENDL
" Automatically upscales textures by the specified" ENDL
" amount; 1:No scaling (default), 2:2x upscaling," ENDL
" 4:4x upscaling" ENDL
" --3d-texture-smoothing-enable" ENDL
" Enables smooth texture sampling while rendering." ENDL
#ifdef HOST_WINDOWS
" --gpu-resolution-multiplier N" ENDL
" Increases the resolution of GPU rendering by this" ENDL
" multipler; 1:256x192 (default), 2:512x384," ENDL
" 3:768x576, 4:1024x768, 5:1280x960" ENDL
" --windowed-fullscreen" ENDL
" Launches in windowed fullscreen (same as alt+enter)" ENDL
#else
" --scale N scale factor for window; default 1.0" ENDL
" --horizontal display touch screen to the right; default OFF" ENDL
" --nojoy Disables joystick support" ENDL
#endif
" --disable-sound Disables the sound output" ENDL
" --disable-limiter Disables the 60fps limiter" ENDL
" --rtc-day D Override RTC day, 0=Sunday, 6=Saturday" ENDL
" --rtc-hour H Override RTC hour, 0=midnight, 23=an hour before" ENDL
" --frameskip N Set frameskip to N; default 0" ENDL
ENDL
"Arguments affecting overall emulation parameters (`sync settings`): " ENDL
#ifdef HAVE_JIT
" --jit-enable Formerly --cpu-mode; default OFF" ENDL
" --jit-size N JIT block size 1-100; 1:accurate 100:fast (default)" ENDL
#endif
" --advanced-timing Use advanced bus-level timing; default ON" ENDL
" --rigorous-timing Use more realistic component timings; default OFF" ENDL
" --gamehacks Use game-specific hacks; default ON" ENDL
" --spu-advanced Enable advanced SPU capture functions (reverb)" ENDL
" --backupmem-db Use DB for autodetecting backup memory type" ENDL
ENDL
"Arguments affecting the emulated requipment:" ENDL
" --console-type [FAT|LITE|IQUE|DEBUG|DSI]" ENDL
" Select basic console type; default FAT" ENDL
" --bios-arm9 BIN_FILE Uses the ARM9 BIOS provided at the specified path" ENDL
" --bios-arm7 BIN_FILE Uses the ARM7 BIOS provided at the specified path" ENDL
" --firmware-path BIN_FILE Uses the firmware provided at the specified path" ENDL
" --firmware-boot 0|1 Boot from firmware" ENDL
" --bios-swi Uses SWI from the provided bios files (else HLE)" ENDL
" --lang N Firmware language (can affect game translations)" ENDL
" 0 = Japanese, 1 = English (default), 2 = French" ENDL
" 3 = German, 4 = Italian, 5 = Spanish" ENDL
ENDL
"Arguments affecting contents of SLOT-1:" ENDL
" --slot1 [RETAIL|RETAILAUTO|R4|RETAILNAND|RETAILMCDROM|RETAILDEBUG]" ENDL
" Device type to be used SLOT-1; default RETAILAUTO" ENDL
" --preload-rom precache ROM to RAM instead of streaming from disk" ENDL
" --slot1-fat-dir DIR Directory to mount for SLOT-1 flash cards" ENDL
" --slot1_no8000prot Disables retail card copy protection <8000 feature" ENDL
ENDL
"Arguments affecting contents of SLOT-2:" ENDL
" --cflash-image IMG_FILE Mounts cflash in SLOT-2 with specified image file" ENDL
" --cflash-path DIR Mounts cflash in SLOT-2 with FS rooted at DIR" ENDL
" --gbaslot-rom GBA_FILE Mounts GBA specified rom in SLOT-2" ENDL
ENDL
"Commands taking place after ROM is loaded: (be sure to specify a ROM!)" ENDL
" --start-paused emulation should start paused" ENDL
" --load-slot N loads savestate from slot N (0-9)" ENDL
" --play-movie DSM_FILE automatically plays movie" ENDL
" --record-movie DSM_FILE begin recording a movie" ENDL
ENDL
"Arguments affecting video filters:" ENDL
" --scanline-filter-a N Fadeout intensity (N/16) (topleft) (default 0)" ENDL
" --scanline-filter-b N Fadeout intensity (N/16) (topright) (default 2)" ENDL
" --scanline-filter-c N Fadeout intensity (N/16) (bottomleft) (default 2)" ENDL
" --scanline-filter-d N Fadeout intensity (N/16) (bottomright) (default 4)" ENDL
ENDL
#ifdef GDB_STUB
"Arguments affecting debugging features:" ENDL
" --arm9gdb PORTNUM Enable the ARM9 GDB stub on the given port" ENDL
" --arm7gdb PORTNUM Enable the ARM7 GDB stub on the given port" ENDL
ENDL
#endif
"Utility commands which occur in place of emulation:" ENDL
" --advanscene-import PATH Import advanscene, dump .ddb, and exit" ENDL
ENDL
"These arguments may be reorganized/renamed in the future." ENDL ENDL
;
//https://github.com/mono/mono/blob/b7a308f660de8174b64697a422abfc7315d07b8c/eglib/test/driver.c
#define OPT_NUMCORES 1
#define OPT_SPU_METHOD 2
#define OPT_3D_RENDER 3
#define OPT_3D_TEXTURE_UPSCALE 81
#define OPT_GPU_RESOLUTION_MULTIPLIER 82
#define OPT_FRAMESKIP 83
#define OPT_SCALE 84
#define OPT_JIT_SIZE 100
#define OPT_CONSOLE_TYPE 200
#define OPT_ARM9 201
#define OPT_ARM7 202
#define OPT_LANGUAGE 203
#define OPT_FIRMPATH 204
#define OPT_FIRMBOOT 205
#define OPT_SLOT1 300
#define OPT_SLOT1_FAT_DIR 301
#define OPT_LOAD_SLOT 400
#define OPT_PLAY_MOVIE 410
#define OPT_RECORD_MOVIE 411
#define OPT_SLOT2_CFLASH_IMAGE 500
#define OPT_SLOT2_CFLASH_DIR 501
#define OPT_SLOT2_GBAGAME 502
#define OPT_SCANLINES_A 600
#define OPT_SCANLINES_B 601
#define OPT_SCANLINES_C 602
#define OPT_SCANLINES_D 603
#define OPT_ARM9GDB 700
#define OPT_ARM7GDB 701
#define OPT_RTC_DAY 800
#define OPT_RTC_HOUR 801
#define OPT_ADVANSCENE 900
bool CommandLine::parse(int argc,char **argv)
{
//closest thing to a portable main() we have, I guess.
srand((unsigned)time(nullptr));
std::string _render3d;
int opt_help = 0;
int option_index = 0;
for(;;)
{
//libretro-common's optional argument is not supported presently
static struct option long_options[] =
{
//stuff
{ "help", no_argument, &opt_help, 1 },
//user settings
{ "num-cores", required_argument, NULL, OPT_NUMCORES },
{ "spu-synch", no_argument, &_spu_sync_mode, 1 },
{ "spu-method", required_argument, NULL, OPT_SPU_METHOD },
{ "3d-render", required_argument, NULL, OPT_3D_RENDER },
{ "3d-texture-deposterize-enable", no_argument, &_texture_deposterize, 1 },
{ "3d-texture-upscale", required_argument, NULL, OPT_3D_TEXTURE_UPSCALE },
{ "3d-texture-smoothing-enable", no_argument, &_texture_smooth, 1 },
#ifdef HOST_WINDOWS
{ "gpu-resolution-multiplier", required_argument, NULL, OPT_GPU_RESOLUTION_MULTIPLIER },
{ "windowed-fullscreen", no_argument, &windowed_fullscreen, 1 },
#else
{ "nojoy", no_argument, &_commandline_linux_nojoy, 1},
{ "horizontal", no_argument, &horizontal, 1},
{ "scale", required_argument, NULL, OPT_SCALE},
#endif
{ "frameskip", required_argument, NULL, OPT_FRAMESKIP},
{ "disable-sound", no_argument, &disable_sound, 1},
{ "disable-limiter", no_argument, &disable_limiter, 1},
{ "rtc-day", required_argument, NULL, OPT_RTC_DAY},
{ "rtc-hour", required_argument, NULL, OPT_RTC_HOUR},
//sync settings
#ifdef HAVE_JIT
{ "jit-enable", no_argument, &_cpu_mode, 1},
{ "jit-size", required_argument, NULL, OPT_JIT_SIZE },
#endif
{ "rigorous-timing", no_argument, &_rigorous_timing, 1},
{ "advanced-timing", no_argument, &_advanced_timing, 1},
{ "gamehacks", no_argument, &_gamehacks, 1},
{ "spu-advanced", no_argument, &_spu_advanced, 1},
{ "backupmem-db", no_argument, &autodetect_method, 1},
//system equipment
{ "console-type", required_argument, NULL, OPT_CONSOLE_TYPE },
{ "bios-arm9", required_argument, NULL, OPT_ARM9},
{ "bios-arm7", required_argument, NULL, OPT_ARM7},
{ "bios-swi", no_argument, &_bios_swi, 1},
{ "firmware-path", required_argument, NULL, OPT_FIRMPATH},
{ "firmware-boot", required_argument, NULL, OPT_FIRMBOOT},
{ "lang", required_argument, NULL, OPT_LANGUAGE},
//slot-1 contents
{ "slot1", required_argument, NULL, OPT_SLOT1},
{ "preload-rom", no_argument, &_load_to_memory, 1},
{ "slot1-fat-dir", required_argument, NULL, OPT_SLOT1_FAT_DIR},
//and other slot-1 option
{ "slot1-no8000prot", no_argument, &_slot1_no8000prot, 1},
//slot-2 contents
{ "cflash-image", required_argument, NULL, OPT_SLOT2_CFLASH_IMAGE},
{ "cflash-path", required_argument, NULL, OPT_SLOT2_CFLASH_DIR},
{ "gbaslot-rom", required_argument, NULL, OPT_SLOT2_GBAGAME},
//commands
{ "start-paused", no_argument, &start_paused, 1},
{ "load-slot", required_argument, NULL, OPT_LOAD_SLOT},
{ "play-movie", required_argument, NULL, OPT_PLAY_MOVIE},
{ "record-movie", required_argument, NULL, OPT_RECORD_MOVIE},
//video filters
{ "scanline-filter-a", required_argument, NULL, OPT_SCANLINES_A},
{ "scanline-filter-b", required_argument, NULL, OPT_SCANLINES_B},
{ "scanline-filter-c", required_argument, NULL, OPT_SCANLINES_C},
{ "scanline-filter-d", required_argument, NULL, OPT_SCANLINES_D},
//debugging
#ifdef GDB_STUB
{ "arm9gdb", required_argument, NULL, OPT_ARM9GDB},
{ "arm7gdb", required_argument, NULL, OPT_ARM7GDB},
#endif
//utilities
{ "advanscene-import", required_argument, NULL, OPT_ADVANSCENE},
{0,0,0,0}
};
int c = getopt_long(argc,argv,"",long_options,&option_index);
if(c == -1) break;
if(c == '?')
break;
switch(c)
{
case 0: break;
//user settings
case OPT_NUMCORES: _num_cores = atoi(optarg); break;
case OPT_SPU_METHOD: _spu_sync_method = atoi(optarg); break;
case OPT_3D_RENDER: _render3d = optarg; break;
case OPT_3D_TEXTURE_UPSCALE: texture_upscale = atoi(optarg); break;
case OPT_GPU_RESOLUTION_MULTIPLIER: gpu_resolution_multiplier = atoi(optarg); break;
case OPT_SCALE: scale = atof(optarg); break;
case OPT_FRAMESKIP: frameskip = atoi(optarg); break;
//RTC settings
case OPT_RTC_DAY: _rtc_day = atoi(optarg); break;
case OPT_RTC_HOUR: _rtc_hour = atoi(optarg); break;
//sync settings
#ifdef HAVE_JIT
case OPT_JIT_SIZE: _jit_size = atoi(optarg); break;
#endif
//system equipment
case OPT_CONSOLE_TYPE: console_type = optarg; break;
case OPT_ARM9: _bios_arm9 = strdup(optarg); break;
case OPT_ARM7: _bios_arm7 = strdup(optarg); break;
case OPT_FIRMPATH: _fw_path = strdup(optarg); break;
case OPT_FIRMBOOT: _fw_boot = atoi(optarg); break;
//slot-1 contents
case OPT_SLOT1: slot1 = strtoupper(optarg); break;
case OPT_SLOT1_FAT_DIR: slot1_fat_dir = optarg; break;
//slot-2 contents
case OPT_SLOT2_CFLASH_IMAGE: cflash_image = optarg; break;
case OPT_SLOT2_CFLASH_DIR: _cflash_path = optarg; break;
case OPT_SLOT2_GBAGAME: _gbaslot_rom = optarg; break;
//commands
case OPT_LOAD_SLOT: load_slot = atoi(optarg); break;
case OPT_PLAY_MOVIE: play_movie_file = optarg; break;
case OPT_RECORD_MOVIE: record_movie_file = optarg; break;
//video filters
case OPT_SCANLINES_A: _scanline_filter_a = atoi(optarg); break;
case OPT_SCANLINES_B: _scanline_filter_b = atoi(optarg); break;
case OPT_SCANLINES_C: _scanline_filter_c = atoi(optarg); break;
case OPT_SCANLINES_D: _scanline_filter_d = atoi(optarg); break;
//debugging
case OPT_ARM9GDB: arm9_gdb_port = atoi(optarg); break;
case OPT_ARM7GDB: arm7_gdb_port = atoi(optarg); break;
//utilities
case OPT_ADVANSCENE: CommonSettings.run_advanscene_import = optarg; break;
case OPT_LANGUAGE: language = atoi(optarg); break;
}
} //arg parsing loop
if(opt_help)
{
printf("%s",help_string);
exit(1);
}
if(_load_to_memory != -1) CommonSettings.loadToMemory = (_load_to_memory == 1)?true:false;
if(_num_cores != -1) CommonSettings.num_cores = _num_cores;
if(_rigorous_timing) CommonSettings.rigorous_timing = true;
if(_advanced_timing != -1) CommonSettings.advanced_timing = _advanced_timing==1;
if(_gamehacks != -1) CommonSettings.gamehacks.en = _gamehacks==1;
#ifdef HAVE_JIT
if(_cpu_mode != -1) CommonSettings.use_jit = (_cpu_mode==1);
if(_jit_size != -1)
{
if ((_jit_size < 1) || (_jit_size > 100))
CommonSettings.jit_max_block_size = 100;
else
CommonSettings.jit_max_block_size = _jit_size;
}
#endif
//process console type
CommonSettings.DebugConsole = false;
CommonSettings.ConsoleType = NDS_CONSOLE_TYPE_FAT;
console_type = strtoupper(console_type);
if(console_type == "") {}
else if(console_type == "FAT") CommonSettings.ConsoleType = NDS_CONSOLE_TYPE_FAT;
else if(console_type == "LITE") CommonSettings.ConsoleType = NDS_CONSOLE_TYPE_LITE;
else if(console_type == "IQUE") CommonSettings.ConsoleType = NDS_CONSOLE_TYPE_IQUE;
else if(console_type == "DSI") CommonSettings.ConsoleType = NDS_CONSOLE_TYPE_DSI;
else if(console_type == "DEBUG")
{
CommonSettings.ConsoleType = NDS_CONSOLE_TYPE_FAT;
CommonSettings.DebugConsole = true;
}
//process 3d renderer
_render3d = strtoupper(_render3d);
if(_render3d == "NONE") render3d = COMMANDLINE_RENDER3D_NONE;
else if(_render3d == "SW") render3d = COMMANDLINE_RENDER3D_SW;
else if(_render3d == "OLDGL") render3d = COMMANDLINE_RENDER3D_OLDGL;
else if(_render3d == "AUTOGL") render3d = COMMANDLINE_RENDER3D_AUTOGL;
else if(_render3d == "GL") render3d = COMMANDLINE_RENDER3D_GL;
if (_texture_deposterize != -1) CommonSettings.GFX3D_Renderer_TextureDeposterize = (_texture_deposterize == 1);
if (_texture_smooth != -1) CommonSettings.GFX3D_Renderer_TextureSmoothing = (_texture_smooth == 1);
if (autodetect_method != -1)
CommonSettings.autodetectBackupMethod = autodetect_method;
//TODO NOT MAX PRIORITY! change ARM9BIOS etc to be a std::string
if(_bios_arm9) { CommonSettings.UseExtBIOS = true; strcpy(CommonSettings.ARM9BIOS,_bios_arm9); }
if(_bios_arm7) { CommonSettings.UseExtBIOS = true; strcpy(CommonSettings.ARM7BIOS,_bios_arm7); }
#ifndef HOST_WINDOWS
if(_fw_path) { CommonSettings.UseExtFirmware = true; CommonSettings.UseExtFirmwareSettings = true; strcpy(CommonSettings.ExtFirmwarePath,_fw_path); }
#endif
if(_fw_boot) CommonSettings.BootFromFirmware = true;
if(_bios_swi) CommonSettings.SWIFromBIOS = true;
if(_slot1_no8000prot) CommonSettings.RetailCardProtection8000 = false;
if(_spu_sync_mode != -1) CommonSettings.SPU_sync_mode = _spu_sync_mode;
if(_spu_sync_method != -1) CommonSettings.SPU_sync_method = _spu_sync_method;
if(_spu_advanced) CommonSettings.spu_advanced = true;
free(_bios_arm9);
free(_bios_arm7);
_bios_arm9 = _bios_arm7 = NULL;
//remaining argument should be an NDS file, and nothing more
int remain = argc-optind;
if(remain==1)
nds_file = argv[optind];
else if(remain>1) return false;
return true;
}
bool CommandLine::validate()
{
if(slot1 != "")
{
if(slot1 != "R4" && slot1 != "RETAIL" && slot1 != "NONE" && slot1 != "RETAILNAND") {
printerror("Invalid slot1 device specified.\n");
return false;
}
}
if (_load_to_memory < -1 || _load_to_memory > 1) {
printerror("Invalid parameter (0 - stream from disk, 1 - from RAM)\n");
return false;
}
if (_spu_sync_mode < -1 || _spu_sync_mode > 1) {
printerror("Invalid parameter\n");
return false;
}
if (_spu_sync_method < -1 || _spu_sync_method > 2) {
printerror("Invalid parameter\n");
return false;
}
if (load_slot < -1 || load_slot > 10) {
printerror("I only know how to load from slots 0-10; -1 means 'do not load savegame' and is default\n");
return false;
}
if(play_movie_file != "" && record_movie_file != "") {
printerror("Cannot both play and record a movie.\n");
return false;
}
if(record_movie_file != "" && load_slot != -1) {
printerror("Cannot both record a movie and load a savestate.\n");
return false;
}
if(cflash_path != "" && cflash_image != "") {
printerror("Cannot specify both cflash-image and cflash-path.\n");
return false;
}
if((_bios_arm9 && !_bios_arm7) || (_bios_arm7 && !_bios_arm9)) {
printerror("If either bios-arm7 or bios-arm9 are specified, both must be.\n");
return false;
}
if(_bios_swi && (!_bios_arm7 || !_bios_arm9)) {
printerror("If either bios-swi is used, bios-arm9 and bios-arm7 must be specified.\n");
}
if(_fw_boot && (!_fw_path)) {
printerror("If either firmware boot is used, firmware path must be specified.\n");
}
if((_cflash_image && _gbaslot_rom) || (_cflash_path && _gbaslot_rom)) {
printerror("Cannot specify both cflash and gbaslot rom (both occupy SLOT-2)\n");
}
if (autodetect_method < -1 || autodetect_method > 1) {
printerror("Invalid autodetect save method (0 - internal, 1 - from database)\n");
}
if ( (texture_upscale != -1) && (texture_upscale != 1) && (texture_upscale != 2) && (texture_upscale != 4) ) {
printerror("Invalid texture upscaling value [1|2|4]. Ignoring command line setting.\n");
texture_upscale = -1;
}
if ( (gpu_resolution_multiplier != -1) && ((gpu_resolution_multiplier < 1) || (gpu_resolution_multiplier > 5)) ) {
printerror("Invalid GPU resolution multiplier [1..5]. Ignoring command line setting.\n");
gpu_resolution_multiplier = -1;
}
#ifdef HAVE_JIT
if (_cpu_mode < -1 || _cpu_mode > 1) {
printerror("Invalid cpu mode emulation (0 - interpreter, 1 - dynarec)\n");
}
if (_jit_size < -1 && (_jit_size == 0 || _jit_size > 100)) {
printerror("Invalid jit block size [1..100]. set to 100\n");
}
#endif
if (_rtc_day < -1 || _rtc_day > 6) {
printerror("Invalid rtc day override, valid values are from 0 to 6");
return false;
}
if (_rtc_hour < -1 || _rtc_hour > 23) {
printerror("Invalid rtc day override, valid values are from 0 to 23");
return false;
}
return true;
}
void CommandLine::errorHelp(const char* binName)
{
printerror("%s",help_string);
}
void CommandLine::process_movieCommands()
{
if(play_movie_file != "")
{
FCEUI_LoadMovie(play_movie_file.c_str(),true,false,-1);
}
else if(record_movie_file != "")
{
FCEUI_SaveMovie(record_movie_file.c_str(), L"", START_BLANK, NULL, FCEUI_MovieGetRTCDefault());
}
}
void CommandLine::process_addonCommands()
{
if (cflash_image != "")
{
CFlash_Mode = ADDON_CFLASH_MODE_File;
CFlash_Path = cflash_image;
is_cflash_configured = true;
}
if (cflash_path != "")
{
CFlash_Mode = ADDON_CFLASH_MODE_Path;
CFlash_Path = cflash_path;
is_cflash_configured = true;
}
if(slot1_fat_dir != "")
slot1_SetFatDir(slot1_fat_dir);
if(slot1 == "RETAIL")
slot1_Change(NDS_SLOT1_RETAIL_AUTO);
else if(slot1 == "RETAILAUTO")
slot1_Change(NDS_SLOT1_RETAIL_AUTO);
else if(slot1 == "R4")
slot1_Change(NDS_SLOT1_R4);
else if(slot1 == "RETAILNAND")
slot1_Change(NDS_SLOT1_RETAIL_NAND);
else if(slot1 == "RETAILMCROM")
slot1_Change(NDS_SLOT1_RETAIL_MCROM);
else if(slot1 == "RETAILDEBUG")
slot1_Change(NDS_SLOT1_RETAIL_DEBUG);
if (_rtc_day != -1 || _rtc_hour != -1) {
DateTime now = DateTime::get_Now();
int cur_day = now.get_DayOfWeek();
int cur_hour = now.get_Hour();
int cur_total = cur_day * 24 + cur_hour;
int day = (_rtc_day != -1 ? _rtc_day : cur_day);
int hour = (_rtc_hour != -1 ? _rtc_hour : cur_hour);
int total = day * 24 + hour;
int diff = total - cur_total;
if (diff < 0)
diff += 24 * 7;
rtcHourOverride = diff;
}
}

Some files were not shown because too many files have changed in this diff Show More