Whitespace trim, and eol-style native propery set again.
git-svn-id: https://svn.code.sf.net/p/vbam/code/trunk@448 a31d4220-a93d-0410-bf67-fe4944624d44
This commit is contained in:
parent
8b59cf952b
commit
acacbd5c2d
150
VBA2008.sln
150
VBA2008.sln
|
@ -1,75 +1,75 @@
|
|||
Microsoft Visual Studio Solution File, Format Version 10.00
|
||||
# Visual Studio 2008
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "VisualBoyAdvance", "VBA2008.vcproj", "{6D4C5EC8-933F-4C05-A1BF-498E658576DF}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{DB5C12E9-BCD3-4517-8708-475C0D1D88CE} = {DB5C12E9-BCD3-4517-8708-475C0D1D88CE}
|
||||
{96E945F7-0377-48DA-A5F8-1C192DE9F25F} = {96E945F7-0377-48DA-A5F8-1C192DE9F25F}
|
||||
{B938FBD9-C7F9-4BF7-8C27-68865D1FA092} = {B938FBD9-C7F9-4BF7-8C27-68865D1FA092}
|
||||
{7AEC599C-7C82-4F00-AA60-411E0A359CB0} = {7AEC599C-7C82-4F00-AA60-411E0A359CB0}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "zlib", "..\dependencies\zlib\zlib2008.vcproj", "{B938FBD9-C7F9-4BF7-8C27-68865D1FA092}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libpng", "..\dependencies\libpng\libpng2008.vcproj", "{96E945F7-0377-48DA-A5F8-1C192DE9F25F}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{B938FBD9-C7F9-4BF7-8C27-68865D1FA092} = {B938FBD9-C7F9-4BF7-8C27-68865D1FA092}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "File_Extractor", "..\dependencies\File_Extractor-0.4.2\File_Extractor2008.vcproj", "{7AEC599C-7C82-4F00-AA60-411E0A359CB0}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{B938FBD9-C7F9-4BF7-8C27-68865D1FA092} = {B938FBD9-C7F9-4BF7-8C27-68865D1FA092}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "cximage", "..\dependencies\cximage\cximage2008.vcproj", "{DB5C12E9-BCD3-4517-8708-475C0D1D88CE}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Win32 = Debug|Win32
|
||||
Debug|x64 = Debug|x64
|
||||
Release|Win32 = Release|Win32
|
||||
Release|x64 = Release|x64
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{6D4C5EC8-933F-4C05-A1BF-498E658576DF}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{6D4C5EC8-933F-4C05-A1BF-498E658576DF}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{6D4C5EC8-933F-4C05-A1BF-498E658576DF}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{6D4C5EC8-933F-4C05-A1BF-498E658576DF}.Debug|x64.Build.0 = Debug|x64
|
||||
{6D4C5EC8-933F-4C05-A1BF-498E658576DF}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{6D4C5EC8-933F-4C05-A1BF-498E658576DF}.Release|Win32.Build.0 = Release|Win32
|
||||
{6D4C5EC8-933F-4C05-A1BF-498E658576DF}.Release|x64.ActiveCfg = Release|x64
|
||||
{6D4C5EC8-933F-4C05-A1BF-498E658576DF}.Release|x64.Build.0 = Release|x64
|
||||
{B938FBD9-C7F9-4BF7-8C27-68865D1FA092}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{B938FBD9-C7F9-4BF7-8C27-68865D1FA092}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{B938FBD9-C7F9-4BF7-8C27-68865D1FA092}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{B938FBD9-C7F9-4BF7-8C27-68865D1FA092}.Debug|x64.Build.0 = Debug|x64
|
||||
{B938FBD9-C7F9-4BF7-8C27-68865D1FA092}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{B938FBD9-C7F9-4BF7-8C27-68865D1FA092}.Release|Win32.Build.0 = Release|Win32
|
||||
{B938FBD9-C7F9-4BF7-8C27-68865D1FA092}.Release|x64.ActiveCfg = Release|x64
|
||||
{B938FBD9-C7F9-4BF7-8C27-68865D1FA092}.Release|x64.Build.0 = Release|x64
|
||||
{96E945F7-0377-48DA-A5F8-1C192DE9F25F}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{96E945F7-0377-48DA-A5F8-1C192DE9F25F}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{96E945F7-0377-48DA-A5F8-1C192DE9F25F}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{96E945F7-0377-48DA-A5F8-1C192DE9F25F}.Debug|x64.Build.0 = Debug|x64
|
||||
{96E945F7-0377-48DA-A5F8-1C192DE9F25F}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{96E945F7-0377-48DA-A5F8-1C192DE9F25F}.Release|Win32.Build.0 = Release|Win32
|
||||
{96E945F7-0377-48DA-A5F8-1C192DE9F25F}.Release|x64.ActiveCfg = Release|x64
|
||||
{96E945F7-0377-48DA-A5F8-1C192DE9F25F}.Release|x64.Build.0 = Release|x64
|
||||
{7AEC599C-7C82-4F00-AA60-411E0A359CB0}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{7AEC599C-7C82-4F00-AA60-411E0A359CB0}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{7AEC599C-7C82-4F00-AA60-411E0A359CB0}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{7AEC599C-7C82-4F00-AA60-411E0A359CB0}.Debug|x64.Build.0 = Debug|x64
|
||||
{7AEC599C-7C82-4F00-AA60-411E0A359CB0}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{7AEC599C-7C82-4F00-AA60-411E0A359CB0}.Release|Win32.Build.0 = Release|Win32
|
||||
{7AEC599C-7C82-4F00-AA60-411E0A359CB0}.Release|x64.ActiveCfg = Release|x64
|
||||
{7AEC599C-7C82-4F00-AA60-411E0A359CB0}.Release|x64.Build.0 = Release|x64
|
||||
{DB5C12E9-BCD3-4517-8708-475C0D1D88CE}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{DB5C12E9-BCD3-4517-8708-475C0D1D88CE}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{DB5C12E9-BCD3-4517-8708-475C0D1D88CE}.Debug|x64.ActiveCfg = Debug|Win32
|
||||
{DB5C12E9-BCD3-4517-8708-475C0D1D88CE}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{DB5C12E9-BCD3-4517-8708-475C0D1D88CE}.Release|Win32.Build.0 = Release|Win32
|
||||
{DB5C12E9-BCD3-4517-8708-475C0D1D88CE}.Release|x64.ActiveCfg = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
Microsoft Visual Studio Solution File, Format Version 10.00
|
||||
# Visual Studio 2008
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "VisualBoyAdvance", "VBA2008.vcproj", "{6D4C5EC8-933F-4C05-A1BF-498E658576DF}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{DB5C12E9-BCD3-4517-8708-475C0D1D88CE} = {DB5C12E9-BCD3-4517-8708-475C0D1D88CE}
|
||||
{96E945F7-0377-48DA-A5F8-1C192DE9F25F} = {96E945F7-0377-48DA-A5F8-1C192DE9F25F}
|
||||
{B938FBD9-C7F9-4BF7-8C27-68865D1FA092} = {B938FBD9-C7F9-4BF7-8C27-68865D1FA092}
|
||||
{7AEC599C-7C82-4F00-AA60-411E0A359CB0} = {7AEC599C-7C82-4F00-AA60-411E0A359CB0}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "zlib", "..\dependencies\zlib\zlib2008.vcproj", "{B938FBD9-C7F9-4BF7-8C27-68865D1FA092}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libpng", "..\dependencies\libpng\libpng2008.vcproj", "{96E945F7-0377-48DA-A5F8-1C192DE9F25F}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{B938FBD9-C7F9-4BF7-8C27-68865D1FA092} = {B938FBD9-C7F9-4BF7-8C27-68865D1FA092}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "File_Extractor", "..\dependencies\File_Extractor-0.4.2\File_Extractor2008.vcproj", "{7AEC599C-7C82-4F00-AA60-411E0A359CB0}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{B938FBD9-C7F9-4BF7-8C27-68865D1FA092} = {B938FBD9-C7F9-4BF7-8C27-68865D1FA092}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "cximage", "..\dependencies\cximage\cximage2008.vcproj", "{DB5C12E9-BCD3-4517-8708-475C0D1D88CE}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Win32 = Debug|Win32
|
||||
Debug|x64 = Debug|x64
|
||||
Release|Win32 = Release|Win32
|
||||
Release|x64 = Release|x64
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{6D4C5EC8-933F-4C05-A1BF-498E658576DF}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{6D4C5EC8-933F-4C05-A1BF-498E658576DF}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{6D4C5EC8-933F-4C05-A1BF-498E658576DF}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{6D4C5EC8-933F-4C05-A1BF-498E658576DF}.Debug|x64.Build.0 = Debug|x64
|
||||
{6D4C5EC8-933F-4C05-A1BF-498E658576DF}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{6D4C5EC8-933F-4C05-A1BF-498E658576DF}.Release|Win32.Build.0 = Release|Win32
|
||||
{6D4C5EC8-933F-4C05-A1BF-498E658576DF}.Release|x64.ActiveCfg = Release|x64
|
||||
{6D4C5EC8-933F-4C05-A1BF-498E658576DF}.Release|x64.Build.0 = Release|x64
|
||||
{B938FBD9-C7F9-4BF7-8C27-68865D1FA092}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{B938FBD9-C7F9-4BF7-8C27-68865D1FA092}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{B938FBD9-C7F9-4BF7-8C27-68865D1FA092}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{B938FBD9-C7F9-4BF7-8C27-68865D1FA092}.Debug|x64.Build.0 = Debug|x64
|
||||
{B938FBD9-C7F9-4BF7-8C27-68865D1FA092}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{B938FBD9-C7F9-4BF7-8C27-68865D1FA092}.Release|Win32.Build.0 = Release|Win32
|
||||
{B938FBD9-C7F9-4BF7-8C27-68865D1FA092}.Release|x64.ActiveCfg = Release|x64
|
||||
{B938FBD9-C7F9-4BF7-8C27-68865D1FA092}.Release|x64.Build.0 = Release|x64
|
||||
{96E945F7-0377-48DA-A5F8-1C192DE9F25F}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{96E945F7-0377-48DA-A5F8-1C192DE9F25F}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{96E945F7-0377-48DA-A5F8-1C192DE9F25F}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{96E945F7-0377-48DA-A5F8-1C192DE9F25F}.Debug|x64.Build.0 = Debug|x64
|
||||
{96E945F7-0377-48DA-A5F8-1C192DE9F25F}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{96E945F7-0377-48DA-A5F8-1C192DE9F25F}.Release|Win32.Build.0 = Release|Win32
|
||||
{96E945F7-0377-48DA-A5F8-1C192DE9F25F}.Release|x64.ActiveCfg = Release|x64
|
||||
{96E945F7-0377-48DA-A5F8-1C192DE9F25F}.Release|x64.Build.0 = Release|x64
|
||||
{7AEC599C-7C82-4F00-AA60-411E0A359CB0}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{7AEC599C-7C82-4F00-AA60-411E0A359CB0}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{7AEC599C-7C82-4F00-AA60-411E0A359CB0}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{7AEC599C-7C82-4F00-AA60-411E0A359CB0}.Debug|x64.Build.0 = Debug|x64
|
||||
{7AEC599C-7C82-4F00-AA60-411E0A359CB0}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{7AEC599C-7C82-4F00-AA60-411E0A359CB0}.Release|Win32.Build.0 = Release|Win32
|
||||
{7AEC599C-7C82-4F00-AA60-411E0A359CB0}.Release|x64.ActiveCfg = Release|x64
|
||||
{7AEC599C-7C82-4F00-AA60-411E0A359CB0}.Release|x64.Build.0 = Release|x64
|
||||
{DB5C12E9-BCD3-4517-8708-475C0D1D88CE}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{DB5C12E9-BCD3-4517-8708-475C0D1D88CE}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{DB5C12E9-BCD3-4517-8708-475C0D1D88CE}.Debug|x64.ActiveCfg = Debug|Win32
|
||||
{DB5C12E9-BCD3-4517-8708-475C0D1D88CE}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{DB5C12E9-BCD3-4517-8708-475C0D1D88CE}.Release|Win32.Build.0 = Release|Win32
|
||||
{DB5C12E9-BCD3-4517-8708-475C0D1D88CE}.Release|x64.ActiveCfg = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
|
|
3738
VBA2008.vcproj
3738
VBA2008.vcproj
File diff suppressed because it is too large
Load Diff
|
@ -1,14 +1,14 @@
|
|||
vbam (0.svn333-1) unstable; urgency=low
|
||||
|
||||
* Added a man page
|
||||
* Added a default configuration file
|
||||
* Updated VBA-M to r333
|
||||
|
||||
-- Bastien Bouclet <bgkweb@gmail.com> Tue, 22 Jan 2008 22:06:31 +0100
|
||||
|
||||
vbam (0.svn307-1) unstable; urgency=low
|
||||
|
||||
* Initial release
|
||||
|
||||
-- Bastien Bouclet <bgkweb@gmail.com> Tue, 15 Jan 2008 13:31:45 +0100
|
||||
|
||||
vbam (0.svn333-1) unstable; urgency=low
|
||||
|
||||
* Added a man page
|
||||
* Added a default configuration file
|
||||
* Updated VBA-M to r333
|
||||
|
||||
-- Bastien Bouclet <bgkweb@gmail.com> Tue, 22 Jan 2008 22:06:31 +0100
|
||||
|
||||
vbam (0.svn307-1) unstable; urgency=low
|
||||
|
||||
* Initial release
|
||||
|
||||
-- Bastien Bouclet <bgkweb@gmail.com> Tue, 15 Jan 2008 13:31:45 +0100
|
||||
|
||||
|
|
|
@ -1 +1 @@
|
|||
5
|
||||
5
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
Source: vbam
|
||||
Section: games
|
||||
Priority: extra
|
||||
Maintainer: Bastien Bouclet <bgkweb@gmail.com>
|
||||
Build-Depends: debhelper (>= 5), zlib1g-dev, libpng12-dev, libsdl1.2-dev, libgl1-mesa-dev
|
||||
Standards-Version: 3.7.2
|
||||
|
||||
Package: vbam
|
||||
Architecture: any
|
||||
Depends: ${shlibs:Depends}, ${misc:Depends}
|
||||
Description: Nintendo GameBoy Advance emulator
|
||||
VBA-M is a Nintendo GameBoy Advance emulator. It runs homebrew and commercial games.
|
||||
This version is based on the SDL library.
|
||||
Source: vbam
|
||||
Section: games
|
||||
Priority: extra
|
||||
Maintainer: Bastien Bouclet <bgkweb@gmail.com>
|
||||
Build-Depends: debhelper (>= 5), zlib1g-dev, libpng12-dev, libsdl1.2-dev, libgl1-mesa-dev
|
||||
Standards-Version: 3.7.2
|
||||
|
||||
Package: vbam
|
||||
Architecture: any
|
||||
Depends: ${shlibs:Depends}, ${misc:Depends}
|
||||
Description: Nintendo GameBoy Advance emulator
|
||||
VBA-M is a Nintendo GameBoy Advance emulator. It runs homebrew and commercial games.
|
||||
This version is based on the SDL library.
|
||||
|
|
|
@ -1,23 +1,23 @@
|
|||
This package was debianized by Bastien Bouclet <bgkweb@gmail.com> on
|
||||
Tue, 15 Jan 2008 13:31:45 +0100.
|
||||
|
||||
It was downloaded from https://vbam.bountysource.com/
|
||||
|
||||
Copyright:
|
||||
|
||||
Copyright (C) 1999-2003 Forgotten
|
||||
Copyright (C) 2004-2006 VBA development team
|
||||
Copyright (C) 2007-2008 VBA-M development team
|
||||
|
||||
License:
|
||||
|
||||
VBA-M 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.
|
||||
|
||||
On Debian systems, the complete text of the GNU General Public License
|
||||
can be found in the '/usr/share/common-licenses/GPL' file.
|
||||
|
||||
The Debian packaging is (C) 2008, Bastien Bouclet <bgkweb@gmail.com> and
|
||||
is licensed under the GPL, see `/usr/share/common-licenses/GPL'.
|
||||
This package was debianized by Bastien Bouclet <bgkweb@gmail.com> on
|
||||
Tue, 15 Jan 2008 13:31:45 +0100.
|
||||
|
||||
It was downloaded from https://vbam.bountysource.com/
|
||||
|
||||
Copyright:
|
||||
|
||||
Copyright (C) 1999-2003 Forgotten
|
||||
Copyright (C) 2004-2006 VBA development team
|
||||
Copyright (C) 2007-2008 VBA-M development team
|
||||
|
||||
License:
|
||||
|
||||
VBA-M 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.
|
||||
|
||||
On Debian systems, the complete text of the GNU General Public License
|
||||
can be found in the '/usr/share/common-licenses/GPL' file.
|
||||
|
||||
The Debian packaging is (C) 2008, Bastien Bouclet <bgkweb@gmail.com> and
|
||||
is licensed under the GPL, see `/usr/share/common-licenses/GPL'.
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
usr/bin
|
||||
usr/sbin
|
||||
usr/bin
|
||||
usr/sbin
|
||||
|
|
|
@ -1 +1 @@
|
|||
doc/*
|
||||
doc/*
|
||||
|
|
|
@ -1,164 +1,164 @@
|
|||
.TH "VBAM" "1" "January 2008" "VBA-M development team" "User Commands"
|
||||
.SH "NAME"
|
||||
vbam \- manual page for VisualBoy Advance\-M
|
||||
.SH "DESCRIPTION"
|
||||
vbam [option ...] file
|
||||
.SH "OPTIONS"
|
||||
.TP
|
||||
\fB\-O\fR, \fB\-\-opengl\fR=\fIMODE\fR
|
||||
Set OpenGL texture filter
|
||||
.TP
|
||||
\fB\-\-no\-opengl\fR
|
||||
0 \- Disable OpenGL
|
||||
.TP
|
||||
\fB\-\-opengl\-nearest\fR
|
||||
1 \- No filtering
|
||||
.TP
|
||||
\fB\-\-opengl\-bilinear\fR
|
||||
2 \- Bilinear filtering
|
||||
.TP
|
||||
\fB\-F\fR, \fB\-\-fullscreen\fR
|
||||
Full screen
|
||||
.TP
|
||||
\fB\-G\fR, \fB\-\-gdb\fR=\fIPROTOCOL\fR
|
||||
GNU Remote Stub mode:
|
||||
\fBtcp\fR \- use TCP at port 55555,
|
||||
\fBtcp:PORT\fR \- use TCP at port PORT,
|
||||
\fBpipe\fR \- use pipe transport
|
||||
.TP
|
||||
\fB\-I\fR, \fB\-\-ifb\-filter\fR=\fIFILTER\fR
|
||||
Select interframe blending filter:
|
||||
\fB0\fR \- No interframe blending,
|
||||
\fB1\fR \- Interframe motion blur,
|
||||
\fB2\fR \- Smart interframe blending
|
||||
.TP
|
||||
\fB\-N\fR, \fB\-\-no\-debug\fR
|
||||
Don't parse debug information
|
||||
.TP
|
||||
\fB\-S\fR, \fB\-\-flash\-size\fR=\fISIZE\fR
|
||||
Set the Flash size
|
||||
.TP
|
||||
\fB\-\-flash\-64k\fR
|
||||
0 \- 64K Flash
|
||||
.TP
|
||||
\fB\-\-flash\-128k\fR
|
||||
1 \- 128K Flash
|
||||
.TP
|
||||
\fB\-T\fR, \fB\-\-throttle\fR=\fITHROTTLE\fR
|
||||
Set the desired throttle (5...1000)
|
||||
.TP
|
||||
\fB\-b\fR, \fB\-\-bios\fR=\fIBIOS\fR
|
||||
Use given bios file
|
||||
.TP
|
||||
\fB\-c\fR, \fB\-\-config\fR=\fIFILE\fR
|
||||
Read the given configuration file
|
||||
.TP
|
||||
\fB\-d\fR, \fB\-\-debug\fR
|
||||
Enter debugger
|
||||
.TP
|
||||
\fB\-f\fR, \fB\-\-filter\fR=\fIFILTER\fR
|
||||
Select filter:
|
||||
\fB0\fR \- Stretch 1x,
|
||||
\fB1\fR \- Stretch 2x,
|
||||
\fB2\fR \- 2xSaI,
|
||||
\fB3\fR \- Super 2xSaI,
|
||||
\fB4\fR \- Super Eagle,
|
||||
\fB5\fR \- Pixelate,
|
||||
\fB6\fR \- Motion Blur,
|
||||
\fB7\fR \- AdvanceMAME Scale2x,
|
||||
\fB8\fR \- Bilinear,
|
||||
\fB9\fR \- Bilinear Plus,
|
||||
\fB10\fR \- Scanlines,
|
||||
\fB11\fR \- TV Mode,
|
||||
\fB12\fR \- lq2x,
|
||||
\fB13\fR \- hq2x,
|
||||
\fB14\fR \- Stretch 3x,
|
||||
\fB15\fR \- hq3x,
|
||||
\fB16\fR \- Stretch 4x,
|
||||
\fB17\fR \- hq4x
|
||||
.TP
|
||||
\fB\-h\fR, \fB\-\-help\fR
|
||||
Print an help screen
|
||||
.TP
|
||||
\fB\-i\fR, \fB\-\-ips\fR=\fIPATCH\fR
|
||||
Apply given IPS patch
|
||||
.TP
|
||||
\fB\-p\fR, \fB\-\-profile\fR=\fI[HERTZ]\fR
|
||||
Enable profiling
|
||||
.TP
|
||||
\fB\-s\fR, \fB\-\-frameskip\fR=\fIFRAMESKIP\fR
|
||||
Set frame skip (0...9)
|
||||
.TP
|
||||
\fB\-t\fR, \fB\-\-save\-type\fR=\fITYPE\fR
|
||||
Set the available save type
|
||||
.TP
|
||||
\fB\-\-save\-auto\fR
|
||||
0 \- Automatic (EEPROM, SRAM, FLASH)
|
||||
.TP
|
||||
\fB\-\-save\-eeprom\fR
|
||||
1 \- EEPROM
|
||||
.TP
|
||||
\fB\-\-save\-sram\fR
|
||||
2 \- SRAM
|
||||
.TP
|
||||
\fB\-\-save\-flash\fR
|
||||
3 \- FLASH
|
||||
.TP
|
||||
\fB\-\-save\-sensor\fR
|
||||
4 \- EEPROM+Sensor
|
||||
.TP
|
||||
\fB\-\-save\-none\fR
|
||||
5 \- NONE
|
||||
.TP
|
||||
\fB\-v\fR, \fB\-\-verbose\fR=\fIVERBOSE\fR
|
||||
Set verbose logging (trace.log):
|
||||
\fB1\fR \- SWI,
|
||||
\fB2\fR \- Unaligned memory access,
|
||||
\fB4\fR \- Illegal memory write,
|
||||
\fB8\fR \- Illegal memory read,
|
||||
\fB16\fR \- DMA 0,
|
||||
\fB32\fR \- DMA 1,
|
||||
\fB64\fR \- DMA 2,
|
||||
\fB128\fR \- DMA 3,
|
||||
\fB256\fR \- Undefined instruction,
|
||||
\fB512\fR \- AGBPrint messages
|
||||
.SS "Long options only:"
|
||||
.TP
|
||||
\fB\-\-agb\-print\fR
|
||||
Enable AGBPrint support
|
||||
.TP
|
||||
\fB\-\-auto\-frameskip\fR
|
||||
Enable auto frameskipping
|
||||
.TP
|
||||
\fB\-\-no\-agb\-print\fR
|
||||
Disable AGBPrint support
|
||||
.TP
|
||||
\fB\-\-no\-auto\-frameskip\fR
|
||||
Disable auto frameskipping
|
||||
.TP
|
||||
\fB\-\-no\-ips\fR
|
||||
Do not apply IPS patch
|
||||
.TP
|
||||
\fB\-\-no\-pause\-when\-inactive\fR
|
||||
Don't pause when inactive
|
||||
.TP
|
||||
\fB\-\-no\-rtc\fR
|
||||
Disable RTC support
|
||||
.TP
|
||||
\fB\-\-no\-show\-speed\fR
|
||||
Don't show emulation speed
|
||||
.TP
|
||||
\fB\-\-no\-throttle\fR
|
||||
Disable throttle
|
||||
.TP
|
||||
\fB\-\-pause\-when\-inactive\fR
|
||||
Pause when inactive
|
||||
.TP
|
||||
\fB\-\-rtc\fR
|
||||
Enable RTC support
|
||||
.TP
|
||||
\fB\-\-show\-speed\-normal\fR
|
||||
Show emulation speed
|
||||
.TP
|
||||
\fB\-\-show\-speed\-detailed\fR
|
||||
Show detailed speed data
|
||||
.TH "VBAM" "1" "January 2008" "VBA-M development team" "User Commands"
|
||||
.SH "NAME"
|
||||
vbam \- manual page for VisualBoy Advance\-M
|
||||
.SH "DESCRIPTION"
|
||||
vbam [option ...] file
|
||||
.SH "OPTIONS"
|
||||
.TP
|
||||
\fB\-O\fR, \fB\-\-opengl\fR=\fIMODE\fR
|
||||
Set OpenGL texture filter
|
||||
.TP
|
||||
\fB\-\-no\-opengl\fR
|
||||
0 \- Disable OpenGL
|
||||
.TP
|
||||
\fB\-\-opengl\-nearest\fR
|
||||
1 \- No filtering
|
||||
.TP
|
||||
\fB\-\-opengl\-bilinear\fR
|
||||
2 \- Bilinear filtering
|
||||
.TP
|
||||
\fB\-F\fR, \fB\-\-fullscreen\fR
|
||||
Full screen
|
||||
.TP
|
||||
\fB\-G\fR, \fB\-\-gdb\fR=\fIPROTOCOL\fR
|
||||
GNU Remote Stub mode:
|
||||
\fBtcp\fR \- use TCP at port 55555,
|
||||
\fBtcp:PORT\fR \- use TCP at port PORT,
|
||||
\fBpipe\fR \- use pipe transport
|
||||
.TP
|
||||
\fB\-I\fR, \fB\-\-ifb\-filter\fR=\fIFILTER\fR
|
||||
Select interframe blending filter:
|
||||
\fB0\fR \- No interframe blending,
|
||||
\fB1\fR \- Interframe motion blur,
|
||||
\fB2\fR \- Smart interframe blending
|
||||
.TP
|
||||
\fB\-N\fR, \fB\-\-no\-debug\fR
|
||||
Don't parse debug information
|
||||
.TP
|
||||
\fB\-S\fR, \fB\-\-flash\-size\fR=\fISIZE\fR
|
||||
Set the Flash size
|
||||
.TP
|
||||
\fB\-\-flash\-64k\fR
|
||||
0 \- 64K Flash
|
||||
.TP
|
||||
\fB\-\-flash\-128k\fR
|
||||
1 \- 128K Flash
|
||||
.TP
|
||||
\fB\-T\fR, \fB\-\-throttle\fR=\fITHROTTLE\fR
|
||||
Set the desired throttle (5...1000)
|
||||
.TP
|
||||
\fB\-b\fR, \fB\-\-bios\fR=\fIBIOS\fR
|
||||
Use given bios file
|
||||
.TP
|
||||
\fB\-c\fR, \fB\-\-config\fR=\fIFILE\fR
|
||||
Read the given configuration file
|
||||
.TP
|
||||
\fB\-d\fR, \fB\-\-debug\fR
|
||||
Enter debugger
|
||||
.TP
|
||||
\fB\-f\fR, \fB\-\-filter\fR=\fIFILTER\fR
|
||||
Select filter:
|
||||
\fB0\fR \- Stretch 1x,
|
||||
\fB1\fR \- Stretch 2x,
|
||||
\fB2\fR \- 2xSaI,
|
||||
\fB3\fR \- Super 2xSaI,
|
||||
\fB4\fR \- Super Eagle,
|
||||
\fB5\fR \- Pixelate,
|
||||
\fB6\fR \- Motion Blur,
|
||||
\fB7\fR \- AdvanceMAME Scale2x,
|
||||
\fB8\fR \- Bilinear,
|
||||
\fB9\fR \- Bilinear Plus,
|
||||
\fB10\fR \- Scanlines,
|
||||
\fB11\fR \- TV Mode,
|
||||
\fB12\fR \- lq2x,
|
||||
\fB13\fR \- hq2x,
|
||||
\fB14\fR \- Stretch 3x,
|
||||
\fB15\fR \- hq3x,
|
||||
\fB16\fR \- Stretch 4x,
|
||||
\fB17\fR \- hq4x
|
||||
.TP
|
||||
\fB\-h\fR, \fB\-\-help\fR
|
||||
Print an help screen
|
||||
.TP
|
||||
\fB\-i\fR, \fB\-\-ips\fR=\fIPATCH\fR
|
||||
Apply given IPS patch
|
||||
.TP
|
||||
\fB\-p\fR, \fB\-\-profile\fR=\fI[HERTZ]\fR
|
||||
Enable profiling
|
||||
.TP
|
||||
\fB\-s\fR, \fB\-\-frameskip\fR=\fIFRAMESKIP\fR
|
||||
Set frame skip (0...9)
|
||||
.TP
|
||||
\fB\-t\fR, \fB\-\-save\-type\fR=\fITYPE\fR
|
||||
Set the available save type
|
||||
.TP
|
||||
\fB\-\-save\-auto\fR
|
||||
0 \- Automatic (EEPROM, SRAM, FLASH)
|
||||
.TP
|
||||
\fB\-\-save\-eeprom\fR
|
||||
1 \- EEPROM
|
||||
.TP
|
||||
\fB\-\-save\-sram\fR
|
||||
2 \- SRAM
|
||||
.TP
|
||||
\fB\-\-save\-flash\fR
|
||||
3 \- FLASH
|
||||
.TP
|
||||
\fB\-\-save\-sensor\fR
|
||||
4 \- EEPROM+Sensor
|
||||
.TP
|
||||
\fB\-\-save\-none\fR
|
||||
5 \- NONE
|
||||
.TP
|
||||
\fB\-v\fR, \fB\-\-verbose\fR=\fIVERBOSE\fR
|
||||
Set verbose logging (trace.log):
|
||||
\fB1\fR \- SWI,
|
||||
\fB2\fR \- Unaligned memory access,
|
||||
\fB4\fR \- Illegal memory write,
|
||||
\fB8\fR \- Illegal memory read,
|
||||
\fB16\fR \- DMA 0,
|
||||
\fB32\fR \- DMA 1,
|
||||
\fB64\fR \- DMA 2,
|
||||
\fB128\fR \- DMA 3,
|
||||
\fB256\fR \- Undefined instruction,
|
||||
\fB512\fR \- AGBPrint messages
|
||||
.SS "Long options only:"
|
||||
.TP
|
||||
\fB\-\-agb\-print\fR
|
||||
Enable AGBPrint support
|
||||
.TP
|
||||
\fB\-\-auto\-frameskip\fR
|
||||
Enable auto frameskipping
|
||||
.TP
|
||||
\fB\-\-no\-agb\-print\fR
|
||||
Disable AGBPrint support
|
||||
.TP
|
||||
\fB\-\-no\-auto\-frameskip\fR
|
||||
Disable auto frameskipping
|
||||
.TP
|
||||
\fB\-\-no\-ips\fR
|
||||
Do not apply IPS patch
|
||||
.TP
|
||||
\fB\-\-no\-pause\-when\-inactive\fR
|
||||
Don't pause when inactive
|
||||
.TP
|
||||
\fB\-\-no\-rtc\fR
|
||||
Disable RTC support
|
||||
.TP
|
||||
\fB\-\-no\-show\-speed\fR
|
||||
Don't show emulation speed
|
||||
.TP
|
||||
\fB\-\-no\-throttle\fR
|
||||
Disable throttle
|
||||
.TP
|
||||
\fB\-\-pause\-when\-inactive\fR
|
||||
Pause when inactive
|
||||
.TP
|
||||
\fB\-\-rtc\fR
|
||||
Enable RTC support
|
||||
.TP
|
||||
\fB\-\-show\-speed\-normal\fR
|
||||
Show emulation speed
|
||||
.TP
|
||||
\fB\-\-show\-speed\-detailed\fR
|
||||
Show detailed speed data
|
||||
|
|
|
@ -1 +1 @@
|
|||
debian/vbam.1
|
||||
debian/vbam.1
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
Original Developers:
|
||||
Forgotten
|
||||
|
||||
New Developers:
|
||||
Mudlord
|
||||
DJRobX
|
||||
Nach
|
||||
Jonas Quinn
|
||||
Spacy
|
||||
|
||||
|
||||
The Qt build uses Icons from the KDE project:
|
||||
http://kde.org/
|
||||
svn://anonsvn.kde.org/home/kde/trunk/KDE/kdebase/runtime/pics/oxygen
|
||||
Original Developers:
|
||||
Forgotten
|
||||
|
||||
New Developers:
|
||||
Mudlord
|
||||
DJRobX
|
||||
Nach
|
||||
Jonas Quinn
|
||||
Spacy
|
||||
|
||||
|
||||
The Qt build uses Icons from the KDE project:
|
||||
http://kde.org/
|
||||
svn://anonsvn.kde.org/home/kde/trunk/KDE/kdebase/runtime/pics/oxygen
|
||||
|
|
104
doc/todo.txt
104
doc/todo.txt
|
@ -1,53 +1,53 @@
|
|||
Important:
|
||||
- Many games show emulation warnings in the log window (unaligned read, bad read/write address)
|
||||
- Test: Metroid Fusion, Advance Wars 2
|
||||
|
||||
- Gfx.cpp/h optimization
|
||||
- Test: Final Fantasy 4 airship intro
|
||||
|
||||
- Improve automatic 64k/128k flash save detection
|
||||
|
||||
- HQ3x/4x ASM implementation produces wrong interpolation on the image's border
|
||||
- This has already been fixed in the C version; look at hq_base.h / line 343 - 372. The ASM version most likely only has something like skipLine instead of skipLinePlus and skipLineMinus, which is however necessary in order to work correctly.
|
||||
|
||||
- Fix OpenGL issues
|
||||
|
||||
- Remove 16 bit hack for filters
|
||||
- Not compatible to software motion blur (display corruption)
|
||||
|
||||
- Add selection for compressed archives with more than one ROM in them
|
||||
|
||||
|
||||
|
||||
Less important:
|
||||
- Add GBA cheat editing support (GB already has)
|
||||
- Look at Cheats.cpp (Core) and GBACheats.cpp (GUI)
|
||||
|
||||
- Support D3DFMT_A2R10G10B10 (10 bit per color component) color format
|
||||
|
||||
- Add documentation for VBA-M (configuration guide)
|
||||
|
||||
- Improve AVI recording (produces asynchronous files)
|
||||
|
||||
- Enable audio stream compression for AVI files
|
||||
|
||||
- Add stereo upmixing support to OpenAL
|
||||
|
||||
- Verify BIOS files by checksum instead by file extension
|
||||
|
||||
- Merge HQ2x/LQ2x C code into code for HQ3x/4x
|
||||
|
||||
- Apply pixel filter to sprites and BG seperately for better image quality
|
||||
|
||||
- Create Visual Studio project using SDL makefile
|
||||
|
||||
|
||||
|
||||
Performance:
|
||||
- Apply HQ3x/4x optimizations from C version to ASM version
|
||||
|
||||
- Apply pixel filter only to changed parts of the image
|
||||
|
||||
- Make use of multi-core CPUs
|
||||
|
||||
Important:
|
||||
- Many games show emulation warnings in the log window (unaligned read, bad read/write address)
|
||||
- Test: Metroid Fusion, Advance Wars 2
|
||||
|
||||
- Gfx.cpp/h optimization
|
||||
- Test: Final Fantasy 4 airship intro
|
||||
|
||||
- Improve automatic 64k/128k flash save detection
|
||||
|
||||
- HQ3x/4x ASM implementation produces wrong interpolation on the image's border
|
||||
- This has already been fixed in the C version; look at hq_base.h / line 343 - 372. The ASM version most likely only has something like skipLine instead of skipLinePlus and skipLineMinus, which is however necessary in order to work correctly.
|
||||
|
||||
- Fix OpenGL issues
|
||||
|
||||
- Remove 16 bit hack for filters
|
||||
- Not compatible to software motion blur (display corruption)
|
||||
|
||||
- Add selection for compressed archives with more than one ROM in them
|
||||
|
||||
|
||||
|
||||
Less important:
|
||||
- Add GBA cheat editing support (GB already has)
|
||||
- Look at Cheats.cpp (Core) and GBACheats.cpp (GUI)
|
||||
|
||||
- Support D3DFMT_A2R10G10B10 (10 bit per color component) color format
|
||||
|
||||
- Add documentation for VBA-M (configuration guide)
|
||||
|
||||
- Improve AVI recording (produces asynchronous files)
|
||||
|
||||
- Enable audio stream compression for AVI files
|
||||
|
||||
- Add stereo upmixing support to OpenAL
|
||||
|
||||
- Verify BIOS files by checksum instead by file extension
|
||||
|
||||
- Merge HQ2x/LQ2x C code into code for HQ3x/4x
|
||||
|
||||
- Apply pixel filter to sprites and BG seperately for better image quality
|
||||
|
||||
- Create Visual Studio project using SDL makefile
|
||||
|
||||
|
||||
|
||||
Performance:
|
||||
- Apply HQ3x/4x optimizations from C version to ASM version
|
||||
|
||||
- Apply pixel filter only to changed parts of the image
|
||||
|
||||
- Make use of multi-core CPUs
|
||||
|
||||
- Make use of 64 bit CPUs
|
|
@ -1,27 +1,27 @@
|
|||
How to create a new translation:
|
||||
|
||||
For Windows:
|
||||
|
||||
- Add "TRANSLATIONS += path/to/language.ts" to vba-m.pro
|
||||
|
||||
- Execute the "update.cmd" script to create .ts files
|
||||
|
||||
- Edit & translate the .ts file with the "Qt Linguist" tool
|
||||
|
||||
- Execute the "release.cmd" script to compile it to a .qm file
|
||||
|
||||
- The .qm file can now be loaded & used by the application
|
||||
|
||||
|
||||
|
||||
For Linux:
|
||||
|
||||
- Add "TRANSLATIONS += path/to/language.ts" to vba-m.pro
|
||||
|
||||
- Type lrelease vba-m.pro
|
||||
|
||||
- Edit & translate the .ts file with the "Qt Linguist" tool
|
||||
|
||||
- In Qt Linguist, go to File -> release as. This will compile it into a .qm file
|
||||
|
||||
- The .qm file can now be loaded & used by the application
|
||||
How to create a new translation:
|
||||
|
||||
For Windows:
|
||||
|
||||
- Add "TRANSLATIONS += path/to/language.ts" to vba-m.pro
|
||||
|
||||
- Execute the "update.cmd" script to create .ts files
|
||||
|
||||
- Edit & translate the .ts file with the "Qt Linguist" tool
|
||||
|
||||
- Execute the "release.cmd" script to compile it to a .qm file
|
||||
|
||||
- The .qm file can now be loaded & used by the application
|
||||
|
||||
|
||||
|
||||
For Linux:
|
||||
|
||||
- Add "TRANSLATIONS += path/to/language.ts" to vba-m.pro
|
||||
|
||||
- Type lrelease vba-m.pro
|
||||
|
||||
- Edit & translate the .ts file with the "Qt Linguist" tool
|
||||
|
||||
- In Qt Linguist, go to File -> release as. This will compile it into a .qm file
|
||||
|
||||
- The .qm file can now be loaded & used by the application
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
cd ..\project\qmake
|
||||
cd ..\project\qmake
|
||||
lrelease vba-m.pro
|
|
@ -1,2 +1,2 @@
|
|||
cd ..\project\qmake
|
||||
cd ..\project\qmake
|
||||
lupdate vba-m.pro
|
|
@ -1,169 +1,169 @@
|
|||
TEMPLATE = app
|
||||
CONFIG += qt release
|
||||
QT += opengl
|
||||
TARGET = VisualBoyAdvance
|
||||
DEFINES += BKPT_SUPPORT
|
||||
|
||||
|
||||
# Directory Locations
|
||||
M_DIR_QT = ../../src/qt/
|
||||
M_DIR_LANG = ../../lang/
|
||||
M_DIR_SHARED = ../../src/
|
||||
M_DIR_GBAPU = ../../src/dmg/gb_apu/
|
||||
M_DIR_AGB = ../../src/agb/
|
||||
M_DIR_DMG = ../../src/dmg/
|
||||
|
||||
|
||||
# Tweaks
|
||||
win32-msvc2005 {
|
||||
DEFINES += _CRT_SECURE_NO_WARNINGS
|
||||
DEFINES += NO_PNG
|
||||
}
|
||||
|
||||
|
||||
# Resource Files
|
||||
RESOURCES += $${M_DIR_QT}vba-m.qrc
|
||||
|
||||
win32 {
|
||||
RC_FILE = $${M_DIR_QT}vba-m.rc
|
||||
}
|
||||
|
||||
|
||||
# Language Files
|
||||
TRANSLATIONS += $${M_DIR_LANG}german.ts
|
||||
TRANSLATIONS += $${M_DIR_LANG}spanish.ts
|
||||
|
||||
|
||||
# Qt GUI Files
|
||||
PRECOMPILED_HEADER = $${M_DIR_QT}precompile.h
|
||||
|
||||
HEADERS += $${M_DIR_QT}version.h
|
||||
|
||||
HEADERS += $${M_DIR_QT}main.h
|
||||
SOURCES += $${M_DIR_QT}main.cpp
|
||||
|
||||
HEADERS += $${M_DIR_QT}MainWnd.h
|
||||
SOURCES += $${M_DIR_QT}MainWnd.cpp
|
||||
|
||||
FORMS += $${M_DIR_QT}sidewidget_cheats.ui
|
||||
HEADERS += $${M_DIR_QT}sidewidget_cheats.h
|
||||
SOURCES += $${M_DIR_QT}sidewidget_cheats.cpp
|
||||
|
||||
HEADERS += $${M_DIR_QT}MainOptions.h
|
||||
SOURCES += $${M_DIR_QT}MainOptions.cpp
|
||||
|
||||
HEADERS += $${M_DIR_QT}configdialog.h
|
||||
SOURCES += $${M_DIR_QT}configdialog.cpp
|
||||
|
||||
HEADERS += $${M_DIR_QT}emu.h
|
||||
SOURCES += $${M_DIR_QT}emu.cpp
|
||||
|
||||
HEADERS += $${M_DIR_QT}EmuManager.h
|
||||
SOURCES += $${M_DIR_QT}EmuManager.cpp
|
||||
|
||||
HEADERS += $${M_DIR_QT}GraphicsOutput.h
|
||||
SOURCES += $${M_DIR_QT}GraphicsOutput.cpp
|
||||
|
||||
|
||||
# Shared Core Files
|
||||
HEADERS += $${M_DIR_SHARED}System.h
|
||||
|
||||
HEADERS += $${M_DIR_SHARED}Globals.h
|
||||
SOURCES += $${M_DIR_SHARED}Globals.cpp
|
||||
|
||||
#HEADERS += $${M_DIR_SHARED}armdis.h
|
||||
#SOURCES += $${M_DIR_SHARED}armdis.cpp
|
||||
|
||||
HEADERS += $${M_DIR_SHARED}bios.h
|
||||
SOURCES += $${M_DIR_SHARED}bios.cpp
|
||||
|
||||
HEADERS += $${M_DIR_SHARED}Cheats.h
|
||||
SOURCES += $${M_DIR_SHARED}Cheats.cpp
|
||||
|
||||
#HEADERS += $${M_DIR_SHARED}CheatSearch.h
|
||||
#SOURCES += $${M_DIR_SHARED}CheatSearch.cpp
|
||||
|
||||
HEADERS += $${M_DIR_SHARED}EEprom.h
|
||||
SOURCES += $${M_DIR_SHARED}EEprom.cpp
|
||||
|
||||
HEADERS += $${M_DIR_SHARED}Flash.h
|
||||
SOURCES += $${M_DIR_SHARED}Flash.cpp
|
||||
|
||||
HEADERS += $${M_DIR_SHARED}Sram.h
|
||||
SOURCES += $${M_DIR_SHARED}Sram.cpp
|
||||
|
||||
HEADERS += $${M_DIR_SHARED}elf.h
|
||||
SOURCES += $${M_DIR_SHARED}elf.cpp
|
||||
|
||||
HEADERS += $${M_DIR_SHARED}RTC.h
|
||||
SOURCES += $${M_DIR_SHARED}RTC.cpp
|
||||
|
||||
HEADERS += $${M_DIR_SHARED}Sound.h
|
||||
SOURCES += $${M_DIR_SHARED}Sound.cpp
|
||||
|
||||
HEADERS += $${M_DIR_SHARED}memgzio.h
|
||||
SOURCES += $${M_DIR_SHARED}memgzio.c
|
||||
|
||||
HEADERS += $${M_DIR_SHARED}fex.h
|
||||
SOURCES += $${M_DIR_SHARED}fex_mini.cpp
|
||||
|
||||
HEADERS += $${M_DIR_SHARED}Util.h
|
||||
SOURCES += $${M_DIR_SHARED}Util.cpp
|
||||
|
||||
SOURCES += $${M_DIR_SHARED}Mode0.cpp
|
||||
SOURCES += $${M_DIR_SHARED}Mode1.cpp
|
||||
SOURCES += $${M_DIR_SHARED}Mode2.cpp
|
||||
SOURCES += $${M_DIR_SHARED}Mode3.cpp
|
||||
SOURCES += $${M_DIR_SHARED}Mode4.cpp
|
||||
SOURCES += $${M_DIR_SHARED}Mode5.cpp
|
||||
|
||||
#HEADERS += $${M_DIR_SHARED}NLS.h
|
||||
|
||||
#HEADERS += $${M_DIR_SHARED}Port.h
|
||||
|
||||
#SOURCES += $${M_DIR_SHARED}remote.cpp
|
||||
|
||||
|
||||
# GB APU
|
||||
HEADERS += $${M_DIR_GBAPU}blargg_common.h
|
||||
HEADERS += $${M_DIR_GBAPU}blargg_config.h
|
||||
HEADERS += $${M_DIR_GBAPU}blargg_source.h
|
||||
|
||||
HEADERS += $${M_DIR_GBAPU}Blip_Buffer.h
|
||||
SOURCES += $${M_DIR_GBAPU}Blip_Buffer.cpp
|
||||
|
||||
HEADERS += $${M_DIR_GBAPU}Effects_Buffer.h
|
||||
SOURCES += $${M_DIR_GBAPU}Effects_Buffer.cpp
|
||||
|
||||
HEADERS += $${M_DIR_GBAPU}Gb_Apu.h
|
||||
SOURCES += $${M_DIR_GBAPU}Gb_Apu.cpp
|
||||
SOURCES += $${M_DIR_GBAPU}Gb_Apu_State.cpp
|
||||
|
||||
HEADERS += $${M_DIR_GBAPU}Gb_Oscs.h
|
||||
SOURCES += $${M_DIR_GBAPU}Gb_Oscs.cpp
|
||||
|
||||
HEADERS += $${M_DIR_GBAPU}Multi_Buffer.h
|
||||
SOURCES += $${M_DIR_GBAPU}Multi_Buffer.cpp
|
||||
|
||||
|
||||
# GBA Core Files
|
||||
HEADERS += $${M_DIR_AGB}agbprint.h
|
||||
SOURCES += $${M_DIR_AGB}agbprint.cpp
|
||||
|
||||
HEADERS += $${M_DIR_AGB}GBA.h
|
||||
SOURCES += $${M_DIR_AGB}GBA.cpp
|
||||
|
||||
#HEADERS += $${M_DIR_AGB}gbafilter.h
|
||||
#SOURCES += $${M_DIR_AGB}gbafilter.cpp
|
||||
|
||||
HEADERS += $${M_DIR_AGB}GBAGfx.h
|
||||
SOURCES += $${M_DIR_AGB}GBAGfx.cpp
|
||||
|
||||
#HEADERS += $${M_DIR_AGB}GBALink.h
|
||||
#SOURCES += $${M_DIR_AGB}GBALink.cpp
|
||||
|
||||
SOURCES += $${M_DIR_AGB}GBA-arm.cpp
|
||||
SOURCES += $${M_DIR_AGB}GBA-thumb.cpp
|
||||
|
||||
HEADERS += $${M_DIR_AGB}GBAcpu.h
|
||||
HEADERS += $${M_DIR_AGB}GBAinline.h
|
||||
TEMPLATE = app
|
||||
CONFIG += qt release
|
||||
QT += opengl
|
||||
TARGET = VisualBoyAdvance
|
||||
DEFINES += BKPT_SUPPORT
|
||||
|
||||
|
||||
# Directory Locations
|
||||
M_DIR_QT = ../../src/qt/
|
||||
M_DIR_LANG = ../../lang/
|
||||
M_DIR_SHARED = ../../src/
|
||||
M_DIR_GBAPU = ../../src/dmg/gb_apu/
|
||||
M_DIR_AGB = ../../src/agb/
|
||||
M_DIR_DMG = ../../src/dmg/
|
||||
|
||||
|
||||
# Tweaks
|
||||
win32-msvc2005 {
|
||||
DEFINES += _CRT_SECURE_NO_WARNINGS
|
||||
DEFINES += NO_PNG
|
||||
}
|
||||
|
||||
|
||||
# Resource Files
|
||||
RESOURCES += $${M_DIR_QT}vba-m.qrc
|
||||
|
||||
win32 {
|
||||
RC_FILE = $${M_DIR_QT}vba-m.rc
|
||||
}
|
||||
|
||||
|
||||
# Language Files
|
||||
TRANSLATIONS += $${M_DIR_LANG}german.ts
|
||||
TRANSLATIONS += $${M_DIR_LANG}spanish.ts
|
||||
|
||||
|
||||
# Qt GUI Files
|
||||
PRECOMPILED_HEADER = $${M_DIR_QT}precompile.h
|
||||
|
||||
HEADERS += $${M_DIR_QT}version.h
|
||||
|
||||
HEADERS += $${M_DIR_QT}main.h
|
||||
SOURCES += $${M_DIR_QT}main.cpp
|
||||
|
||||
HEADERS += $${M_DIR_QT}MainWnd.h
|
||||
SOURCES += $${M_DIR_QT}MainWnd.cpp
|
||||
|
||||
FORMS += $${M_DIR_QT}sidewidget_cheats.ui
|
||||
HEADERS += $${M_DIR_QT}sidewidget_cheats.h
|
||||
SOURCES += $${M_DIR_QT}sidewidget_cheats.cpp
|
||||
|
||||
HEADERS += $${M_DIR_QT}MainOptions.h
|
||||
SOURCES += $${M_DIR_QT}MainOptions.cpp
|
||||
|
||||
HEADERS += $${M_DIR_QT}configdialog.h
|
||||
SOURCES += $${M_DIR_QT}configdialog.cpp
|
||||
|
||||
HEADERS += $${M_DIR_QT}emu.h
|
||||
SOURCES += $${M_DIR_QT}emu.cpp
|
||||
|
||||
HEADERS += $${M_DIR_QT}EmuManager.h
|
||||
SOURCES += $${M_DIR_QT}EmuManager.cpp
|
||||
|
||||
HEADERS += $${M_DIR_QT}GraphicsOutput.h
|
||||
SOURCES += $${M_DIR_QT}GraphicsOutput.cpp
|
||||
|
||||
|
||||
# Shared Core Files
|
||||
HEADERS += $${M_DIR_SHARED}System.h
|
||||
|
||||
HEADERS += $${M_DIR_SHARED}Globals.h
|
||||
SOURCES += $${M_DIR_SHARED}Globals.cpp
|
||||
|
||||
#HEADERS += $${M_DIR_SHARED}armdis.h
|
||||
#SOURCES += $${M_DIR_SHARED}armdis.cpp
|
||||
|
||||
HEADERS += $${M_DIR_SHARED}bios.h
|
||||
SOURCES += $${M_DIR_SHARED}bios.cpp
|
||||
|
||||
HEADERS += $${M_DIR_SHARED}Cheats.h
|
||||
SOURCES += $${M_DIR_SHARED}Cheats.cpp
|
||||
|
||||
#HEADERS += $${M_DIR_SHARED}CheatSearch.h
|
||||
#SOURCES += $${M_DIR_SHARED}CheatSearch.cpp
|
||||
|
||||
HEADERS += $${M_DIR_SHARED}EEprom.h
|
||||
SOURCES += $${M_DIR_SHARED}EEprom.cpp
|
||||
|
||||
HEADERS += $${M_DIR_SHARED}Flash.h
|
||||
SOURCES += $${M_DIR_SHARED}Flash.cpp
|
||||
|
||||
HEADERS += $${M_DIR_SHARED}Sram.h
|
||||
SOURCES += $${M_DIR_SHARED}Sram.cpp
|
||||
|
||||
HEADERS += $${M_DIR_SHARED}elf.h
|
||||
SOURCES += $${M_DIR_SHARED}elf.cpp
|
||||
|
||||
HEADERS += $${M_DIR_SHARED}RTC.h
|
||||
SOURCES += $${M_DIR_SHARED}RTC.cpp
|
||||
|
||||
HEADERS += $${M_DIR_SHARED}Sound.h
|
||||
SOURCES += $${M_DIR_SHARED}Sound.cpp
|
||||
|
||||
HEADERS += $${M_DIR_SHARED}memgzio.h
|
||||
SOURCES += $${M_DIR_SHARED}memgzio.c
|
||||
|
||||
HEADERS += $${M_DIR_SHARED}fex.h
|
||||
SOURCES += $${M_DIR_SHARED}fex_mini.cpp
|
||||
|
||||
HEADERS += $${M_DIR_SHARED}Util.h
|
||||
SOURCES += $${M_DIR_SHARED}Util.cpp
|
||||
|
||||
SOURCES += $${M_DIR_SHARED}Mode0.cpp
|
||||
SOURCES += $${M_DIR_SHARED}Mode1.cpp
|
||||
SOURCES += $${M_DIR_SHARED}Mode2.cpp
|
||||
SOURCES += $${M_DIR_SHARED}Mode3.cpp
|
||||
SOURCES += $${M_DIR_SHARED}Mode4.cpp
|
||||
SOURCES += $${M_DIR_SHARED}Mode5.cpp
|
||||
|
||||
#HEADERS += $${M_DIR_SHARED}NLS.h
|
||||
|
||||
#HEADERS += $${M_DIR_SHARED}Port.h
|
||||
|
||||
#SOURCES += $${M_DIR_SHARED}remote.cpp
|
||||
|
||||
|
||||
# GB APU
|
||||
HEADERS += $${M_DIR_GBAPU}blargg_common.h
|
||||
HEADERS += $${M_DIR_GBAPU}blargg_config.h
|
||||
HEADERS += $${M_DIR_GBAPU}blargg_source.h
|
||||
|
||||
HEADERS += $${M_DIR_GBAPU}Blip_Buffer.h
|
||||
SOURCES += $${M_DIR_GBAPU}Blip_Buffer.cpp
|
||||
|
||||
HEADERS += $${M_DIR_GBAPU}Effects_Buffer.h
|
||||
SOURCES += $${M_DIR_GBAPU}Effects_Buffer.cpp
|
||||
|
||||
HEADERS += $${M_DIR_GBAPU}Gb_Apu.h
|
||||
SOURCES += $${M_DIR_GBAPU}Gb_Apu.cpp
|
||||
SOURCES += $${M_DIR_GBAPU}Gb_Apu_State.cpp
|
||||
|
||||
HEADERS += $${M_DIR_GBAPU}Gb_Oscs.h
|
||||
SOURCES += $${M_DIR_GBAPU}Gb_Oscs.cpp
|
||||
|
||||
HEADERS += $${M_DIR_GBAPU}Multi_Buffer.h
|
||||
SOURCES += $${M_DIR_GBAPU}Multi_Buffer.cpp
|
||||
|
||||
|
||||
# GBA Core Files
|
||||
HEADERS += $${M_DIR_AGB}agbprint.h
|
||||
SOURCES += $${M_DIR_AGB}agbprint.cpp
|
||||
|
||||
HEADERS += $${M_DIR_AGB}GBA.h
|
||||
SOURCES += $${M_DIR_AGB}GBA.cpp
|
||||
|
||||
#HEADERS += $${M_DIR_AGB}gbafilter.h
|
||||
#SOURCES += $${M_DIR_AGB}gbafilter.cpp
|
||||
|
||||
HEADERS += $${M_DIR_AGB}GBAGfx.h
|
||||
SOURCES += $${M_DIR_AGB}GBAGfx.cpp
|
||||
|
||||
#HEADERS += $${M_DIR_AGB}GBALink.h
|
||||
#SOURCES += $${M_DIR_AGB}GBALink.cpp
|
||||
|
||||
SOURCES += $${M_DIR_AGB}GBA-arm.cpp
|
||||
SOURCES += $${M_DIR_AGB}GBA-thumb.cpp
|
||||
|
||||
HEADERS += $${M_DIR_AGB}GBAcpu.h
|
||||
HEADERS += $${M_DIR_AGB}GBAinline.h
|
||||
|
|
|
@ -1,20 +1,20 @@
|
|||
|
||||
Microsoft Visual Studio Solution File, Format Version 10.00
|
||||
# Visual C++ Express 2008
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "vba-m", "vba-m.vcproj", "{714B3EF3-5D43-421F-A97E-447540E7C137}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
debug|Win32 = debug|Win32
|
||||
release|Win32 = release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{714B3EF3-5D43-421F-A97E-447540E7C137}.debug|Win32.ActiveCfg = debug|Win32
|
||||
{714B3EF3-5D43-421F-A97E-447540E7C137}.debug|Win32.Build.0 = debug|Win32
|
||||
{714B3EF3-5D43-421F-A97E-447540E7C137}.release|Win32.ActiveCfg = release|Win32
|
||||
{714B3EF3-5D43-421F-A97E-447540E7C137}.release|Win32.Build.0 = release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 10.00
|
||||
# Visual C++ Express 2008
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "vba-m", "vba-m.vcproj", "{714B3EF3-5D43-421F-A97E-447540E7C137}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
debug|Win32 = debug|Win32
|
||||
release|Win32 = release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{714B3EF3-5D43-421F-A97E-447540E7C137}.debug|Win32.ActiveCfg = debug|Win32
|
||||
{714B3EF3-5D43-421F-A97E-447540E7C137}.debug|Win32.Build.0 = debug|Win32
|
||||
{714B3EF3-5D43-421F-A97E-447540E7C137}.release|Win32.ActiveCfg = release|Win32
|
||||
{714B3EF3-5D43-421F-A97E-447540E7C137}.release|Win32.Build.0 = release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
|
|
|
@ -1,437 +1,437 @@
|
|||
<?xml version="1.0" encoding="Windows-1252"?>
|
||||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="9,00"
|
||||
Name="vba-m"
|
||||
ProjectGUID="{714B3EF3-5D43-421F-A97E-447540E7C137}"
|
||||
RootNamespace="vba-m"
|
||||
Keyword="MakeFileProj"
|
||||
TargetFrameworkVersion="196613"
|
||||
>
|
||||
<Platforms>
|
||||
<Platform
|
||||
Name="Win32"
|
||||
/>
|
||||
</Platforms>
|
||||
<ToolFiles>
|
||||
</ToolFiles>
|
||||
<Configurations>
|
||||
<Configuration
|
||||
Name="debug|Win32"
|
||||
OutputDirectory="$(ConfigurationName)"
|
||||
IntermediateDirectory="$(ConfigurationName)"
|
||||
ConfigurationType="0"
|
||||
>
|
||||
<Tool
|
||||
Name="VCNMakeTool"
|
||||
BuildCommandLine="qmake -makefile -win32 "CONFIG+=debug" ..\qmake\vba-m.pro
nmake debug"
|
||||
ReBuildCommandLine=""
|
||||
CleanCommandLine="nmake distclean
rmdir /S /Q debug
rmdir /S /Q release"
|
||||
Output="$(OutDir)\VisualBoyAdvance.exe"
|
||||
PreprocessorDefinitions="WIN32;_DEBUG"
|
||||
IncludeSearchPath=""$(ProjectDir)""
|
||||
ForcedIncludes=""
|
||||
AssemblySearchPath=""
|
||||
ForcedUsingAssemblies=""
|
||||
CompileAsManaged=""
|
||||
/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="release|Win32"
|
||||
OutputDirectory="$(ConfigurationName)"
|
||||
IntermediateDirectory="$(ConfigurationName)"
|
||||
ConfigurationType="0"
|
||||
>
|
||||
<Tool
|
||||
Name="VCNMakeTool"
|
||||
BuildCommandLine="qmake -makefile -win32 ..\qmake\vba-m.pro
nmake release
upx --best "$(TargetPath)""
|
||||
ReBuildCommandLine=""
|
||||
CleanCommandLine="nmake distclean
rmdir /S /Q debug
rmdir /S /Q release"
|
||||
Output="$(OutDir)\VisualBoyAdvance.exe"
|
||||
PreprocessorDefinitions="WIN32;NDEBUG"
|
||||
IncludeSearchPath=""$(ProjectDir)""
|
||||
ForcedIncludes=""
|
||||
AssemblySearchPath=""
|
||||
ForcedUsingAssemblies=""
|
||||
CompileAsManaged=""
|
||||
/>
|
||||
</Configuration>
|
||||
</Configurations>
|
||||
<References>
|
||||
</References>
|
||||
<Files>
|
||||
<Filter
|
||||
Name="GUI"
|
||||
Filter="cpp;h"
|
||||
>
|
||||
<Filter
|
||||
Name="main"
|
||||
>
|
||||
<File
|
||||
RelativePath="..\..\src\qt\main.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\qt\main.h"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="MainWnd"
|
||||
>
|
||||
<File
|
||||
RelativePath="..\..\src\qt\MainWnd.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\qt\MainWnd.h"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="side widgets"
|
||||
>
|
||||
<Filter
|
||||
Name="cheats"
|
||||
>
|
||||
<File
|
||||
RelativePath="..\..\src\qt\sidewidget_cheats.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\qt\sidewidget_cheats.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\qt\sidewidget_cheats.ui"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Config Dialog"
|
||||
>
|
||||
<File
|
||||
RelativePath="..\..\src\qt\configdialog.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\qt\configdialog.h"
|
||||
>
|
||||
</File>
|
||||
<Filter
|
||||
Name="Pages"
|
||||
>
|
||||
<File
|
||||
RelativePath="..\..\src\qt\MainOptions.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\qt\MainOptions.h"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="IO"
|
||||
>
|
||||
<File
|
||||
RelativePath="..\..\src\qt\GraphicsOutput.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\qt\GraphicsOutput.h"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Build"
|
||||
Filter="pro"
|
||||
>
|
||||
<File
|
||||
RelativePath="..\qmake\vba-m.pro"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\qt\vba-m.qrc"
|
||||
FileType="13"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\qt\vba-m.rc"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Other"
|
||||
>
|
||||
<File
|
||||
RelativePath="..\..\src\qt\precompile.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\qt\version.h"
|
||||
>
|
||||
</File>
|
||||
<Filter
|
||||
Name="EmuManager"
|
||||
>
|
||||
<File
|
||||
RelativePath="..\..\src\qt\emu.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\qt\emu.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\qt\EmuManager.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\qt\EmuManager.h"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Core"
|
||||
>
|
||||
<Filter
|
||||
Name="Shared"
|
||||
>
|
||||
<File
|
||||
RelativePath="..\..\src\bios.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\bios.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\Cheats.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\Cheats.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\EEprom.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\EEprom.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\elf.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\elf.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\fex.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\fex_mini.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\Flash.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\Flash.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\Globals.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\Globals.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\memgzio.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\memgzio.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\Mode0.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\Mode1.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\Mode2.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\Mode3.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\Mode4.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\Mode5.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\RTC.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\RTC.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\Sound.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\Sound.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\Sram.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\Sram.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\System.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\Util.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\Util.h"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="GBA"
|
||||
>
|
||||
<File
|
||||
RelativePath="..\..\src\agb\agbprint.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\agb\agbprint.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\agb\GBA-arm.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\agb\GBA-thumb.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\agb\GBA.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\agb\GBA.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\agb\GBAcpu.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\agb\GBAGfx.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\agb\GBAGfx.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\agb\GBAinline.h"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="APU"
|
||||
>
|
||||
<File
|
||||
RelativePath="..\..\src\dmg\gb_apu\blargg_common.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\dmg\gb_apu\blargg_config.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\dmg\gb_apu\blargg_source.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\dmg\gb_apu\Blip_Buffer.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\dmg\gb_apu\Blip_Buffer.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\dmg\gb_apu\Effects_Buffer.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\dmg\gb_apu\Effects_Buffer.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\dmg\gb_apu\Gb_Apu.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\dmg\gb_apu\Gb_Apu.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\dmg\gb_apu\Gb_Apu_State.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\dmg\gb_apu\Gb_Oscs.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\dmg\gb_apu\Gb_Oscs.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\dmg\gb_apu\Multi_Buffer.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\dmg\gb_apu\Multi_Buffer.h"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
</Filter>
|
||||
</Files>
|
||||
<Globals>
|
||||
</Globals>
|
||||
</VisualStudioProject>
|
||||
<?xml version="1.0" encoding="Windows-1252"?>
|
||||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="9,00"
|
||||
Name="vba-m"
|
||||
ProjectGUID="{714B3EF3-5D43-421F-A97E-447540E7C137}"
|
||||
RootNamespace="vba-m"
|
||||
Keyword="MakeFileProj"
|
||||
TargetFrameworkVersion="196613"
|
||||
>
|
||||
<Platforms>
|
||||
<Platform
|
||||
Name="Win32"
|
||||
/>
|
||||
</Platforms>
|
||||
<ToolFiles>
|
||||
</ToolFiles>
|
||||
<Configurations>
|
||||
<Configuration
|
||||
Name="debug|Win32"
|
||||
OutputDirectory="$(ConfigurationName)"
|
||||
IntermediateDirectory="$(ConfigurationName)"
|
||||
ConfigurationType="0"
|
||||
>
|
||||
<Tool
|
||||
Name="VCNMakeTool"
|
||||
BuildCommandLine="qmake -makefile -win32 "CONFIG+=debug" ..\qmake\vba-m.pro
nmake debug"
|
||||
ReBuildCommandLine=""
|
||||
CleanCommandLine="nmake distclean
rmdir /S /Q debug
rmdir /S /Q release"
|
||||
Output="$(OutDir)\VisualBoyAdvance.exe"
|
||||
PreprocessorDefinitions="WIN32;_DEBUG"
|
||||
IncludeSearchPath=""$(ProjectDir)""
|
||||
ForcedIncludes=""
|
||||
AssemblySearchPath=""
|
||||
ForcedUsingAssemblies=""
|
||||
CompileAsManaged=""
|
||||
/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="release|Win32"
|
||||
OutputDirectory="$(ConfigurationName)"
|
||||
IntermediateDirectory="$(ConfigurationName)"
|
||||
ConfigurationType="0"
|
||||
>
|
||||
<Tool
|
||||
Name="VCNMakeTool"
|
||||
BuildCommandLine="qmake -makefile -win32 ..\qmake\vba-m.pro
nmake release
upx --best "$(TargetPath)""
|
||||
ReBuildCommandLine=""
|
||||
CleanCommandLine="nmake distclean
rmdir /S /Q debug
rmdir /S /Q release"
|
||||
Output="$(OutDir)\VisualBoyAdvance.exe"
|
||||
PreprocessorDefinitions="WIN32;NDEBUG"
|
||||
IncludeSearchPath=""$(ProjectDir)""
|
||||
ForcedIncludes=""
|
||||
AssemblySearchPath=""
|
||||
ForcedUsingAssemblies=""
|
||||
CompileAsManaged=""
|
||||
/>
|
||||
</Configuration>
|
||||
</Configurations>
|
||||
<References>
|
||||
</References>
|
||||
<Files>
|
||||
<Filter
|
||||
Name="GUI"
|
||||
Filter="cpp;h"
|
||||
>
|
||||
<Filter
|
||||
Name="main"
|
||||
>
|
||||
<File
|
||||
RelativePath="..\..\src\qt\main.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\qt\main.h"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="MainWnd"
|
||||
>
|
||||
<File
|
||||
RelativePath="..\..\src\qt\MainWnd.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\qt\MainWnd.h"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="side widgets"
|
||||
>
|
||||
<Filter
|
||||
Name="cheats"
|
||||
>
|
||||
<File
|
||||
RelativePath="..\..\src\qt\sidewidget_cheats.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\qt\sidewidget_cheats.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\qt\sidewidget_cheats.ui"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Config Dialog"
|
||||
>
|
||||
<File
|
||||
RelativePath="..\..\src\qt\configdialog.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\qt\configdialog.h"
|
||||
>
|
||||
</File>
|
||||
<Filter
|
||||
Name="Pages"
|
||||
>
|
||||
<File
|
||||
RelativePath="..\..\src\qt\MainOptions.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\qt\MainOptions.h"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="IO"
|
||||
>
|
||||
<File
|
||||
RelativePath="..\..\src\qt\GraphicsOutput.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\qt\GraphicsOutput.h"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Build"
|
||||
Filter="pro"
|
||||
>
|
||||
<File
|
||||
RelativePath="..\qmake\vba-m.pro"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\qt\vba-m.qrc"
|
||||
FileType="13"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\qt\vba-m.rc"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Other"
|
||||
>
|
||||
<File
|
||||
RelativePath="..\..\src\qt\precompile.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\qt\version.h"
|
||||
>
|
||||
</File>
|
||||
<Filter
|
||||
Name="EmuManager"
|
||||
>
|
||||
<File
|
||||
RelativePath="..\..\src\qt\emu.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\qt\emu.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\qt\EmuManager.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\qt\EmuManager.h"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Core"
|
||||
>
|
||||
<Filter
|
||||
Name="Shared"
|
||||
>
|
||||
<File
|
||||
RelativePath="..\..\src\bios.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\bios.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\Cheats.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\Cheats.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\EEprom.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\EEprom.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\elf.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\elf.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\fex.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\fex_mini.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\Flash.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\Flash.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\Globals.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\Globals.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\memgzio.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\memgzio.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\Mode0.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\Mode1.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\Mode2.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\Mode3.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\Mode4.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\Mode5.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\RTC.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\RTC.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\Sound.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\Sound.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\Sram.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\Sram.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\System.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\Util.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\Util.h"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="GBA"
|
||||
>
|
||||
<File
|
||||
RelativePath="..\..\src\agb\agbprint.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\agb\agbprint.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\agb\GBA-arm.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\agb\GBA-thumb.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\agb\GBA.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\agb\GBA.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\agb\GBAcpu.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\agb\GBAGfx.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\agb\GBAGfx.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\agb\GBAinline.h"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="APU"
|
||||
>
|
||||
<File
|
||||
RelativePath="..\..\src\dmg\gb_apu\blargg_common.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\dmg\gb_apu\blargg_config.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\dmg\gb_apu\blargg_source.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\dmg\gb_apu\Blip_Buffer.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\dmg\gb_apu\Blip_Buffer.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\dmg\gb_apu\Effects_Buffer.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\dmg\gb_apu\Effects_Buffer.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\dmg\gb_apu\Gb_Apu.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\dmg\gb_apu\Gb_Apu.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\dmg\gb_apu\Gb_Apu_State.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\dmg\gb_apu\Gb_Oscs.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\dmg\gb_apu\Gb_Oscs.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\dmg\gb_apu\Multi_Buffer.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\dmg\gb_apu\Multi_Buffer.h"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
</Filter>
|
||||
</Files>
|
||||
<Globals>
|
||||
</Globals>
|
||||
</VisualStudioProject>
|
||||
|
|
1502
src/Util.cpp
1502
src/Util.cpp
File diff suppressed because it is too large
Load Diff
5930
src/agb/GBA-arm.cpp
5930
src/agb/GBA-arm.cpp
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
7966
src/agb/GBA.cpp
7966
src/agb/GBA.cpp
File diff suppressed because it is too large
Load Diff
320
src/agb/GBA.h
320
src/agb/GBA.h
|
@ -1,160 +1,160 @@
|
|||
// -*- C++ -*-
|
||||
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
|
||||
// Copyright (C) 1999-2003 Forgotten
|
||||
// Copyright (C) 2005 Forgotten and the VBA development team
|
||||
|
||||
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
#ifndef VBA_GBA_H
|
||||
#define VBA_GBA_H
|
||||
|
||||
#include "../System.h"
|
||||
|
||||
#define SAVE_GAME_VERSION_1 1
|
||||
#define SAVE_GAME_VERSION_2 2
|
||||
#define SAVE_GAME_VERSION_3 3
|
||||
#define SAVE_GAME_VERSION_4 4
|
||||
#define SAVE_GAME_VERSION_5 5
|
||||
#define SAVE_GAME_VERSION_6 6
|
||||
#define SAVE_GAME_VERSION_7 7
|
||||
#define SAVE_GAME_VERSION_8 8
|
||||
#define SAVE_GAME_VERSION_9 9
|
||||
#define SAVE_GAME_VERSION_10 10
|
||||
#define SAVE_GAME_VERSION SAVE_GAME_VERSION_10
|
||||
|
||||
typedef struct {
|
||||
u8 *address;
|
||||
u32 mask;
|
||||
} memoryMap;
|
||||
|
||||
typedef union {
|
||||
struct {
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
u8 B3;
|
||||
u8 B2;
|
||||
u8 B1;
|
||||
u8 B0;
|
||||
#else
|
||||
u8 B0;
|
||||
u8 B1;
|
||||
u8 B2;
|
||||
u8 B3;
|
||||
#endif
|
||||
} B;
|
||||
struct {
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
u16 W1;
|
||||
u16 W0;
|
||||
#else
|
||||
u16 W0;
|
||||
u16 W1;
|
||||
#endif
|
||||
} W;
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
volatile u32 I;
|
||||
#else
|
||||
u32 I;
|
||||
#endif
|
||||
} reg_pair;
|
||||
|
||||
#ifndef NO_GBA_MAP
|
||||
extern memoryMap map[256];
|
||||
#endif
|
||||
|
||||
extern reg_pair reg[45];
|
||||
extern u8 biosProtected[4];
|
||||
|
||||
extern bool N_FLAG;
|
||||
extern bool Z_FLAG;
|
||||
extern bool C_FLAG;
|
||||
extern bool V_FLAG;
|
||||
extern bool armIrqEnable;
|
||||
extern bool armState;
|
||||
extern int armMode;
|
||||
extern void (*cpuSaveGameFunc)(u32,u8);
|
||||
|
||||
#ifdef BKPT_SUPPORT
|
||||
extern u8 freezeWorkRAM[0x40000];
|
||||
extern u8 freezeInternalRAM[0x8000];
|
||||
extern u8 freezeVRAM[0x18000];
|
||||
extern u8 freezeOAM[0x400];
|
||||
extern u8 freezePRAM[0x400];
|
||||
extern bool debugger_last;
|
||||
extern int oldreg[17];
|
||||
extern char oldbuffer[10];
|
||||
#endif
|
||||
|
||||
extern bool CPUReadGSASnapshot(const char *);
|
||||
extern bool CPUWriteGSASnapshot(const char *, const char *, const char *, const char *);
|
||||
extern bool CPUWriteBatteryFile(const char *);
|
||||
extern bool CPUReadBatteryFile(const char *);
|
||||
extern bool CPUExportEepromFile(const char *);
|
||||
extern bool CPUImportEepromFile(const char *);
|
||||
extern bool CPUWritePNGFile(const char *);
|
||||
extern bool CPUWriteBMPFile(const char *);
|
||||
extern void CPUCleanUp();
|
||||
extern void CPUUpdateRender();
|
||||
extern void CPUUpdateRenderBuffers(bool);
|
||||
extern bool CPUReadMemState(char *, int);
|
||||
extern bool CPUReadState(const char *);
|
||||
extern bool CPUWriteMemState(char *, int);
|
||||
extern bool CPUWriteState(const char *);
|
||||
extern int CPULoadRom(const char *);
|
||||
extern void doMirroring(bool);
|
||||
extern void CPUUpdateRegister(u32, u16);
|
||||
extern void applyTimer ();
|
||||
extern void CPUInit(const char *,bool);
|
||||
extern void CPUReset();
|
||||
extern void CPULoop(int);
|
||||
extern void CPUCheckDMA(int,int);
|
||||
extern bool CPUIsGBAImage(const char *);
|
||||
extern bool CPUIsZipFile(const char *);
|
||||
#ifdef PROFILING
|
||||
#include "prof/prof.h"
|
||||
extern void cpuProfil(profile_segment *seg);
|
||||
extern void cpuEnableProfiling(int hz);
|
||||
#endif
|
||||
|
||||
extern struct EmulatedSystem GBASystem;
|
||||
|
||||
#define R13_IRQ 18
|
||||
#define R14_IRQ 19
|
||||
#define SPSR_IRQ 20
|
||||
#define R13_USR 26
|
||||
#define R14_USR 27
|
||||
#define R13_SVC 28
|
||||
#define R14_SVC 29
|
||||
#define SPSR_SVC 30
|
||||
#define R13_ABT 31
|
||||
#define R14_ABT 32
|
||||
#define SPSR_ABT 33
|
||||
#define R13_UND 34
|
||||
#define R14_UND 35
|
||||
#define SPSR_UND 36
|
||||
#define R8_FIQ 37
|
||||
#define R9_FIQ 38
|
||||
#define R10_FIQ 39
|
||||
#define R11_FIQ 40
|
||||
#define R12_FIQ 41
|
||||
#define R13_FIQ 42
|
||||
#define R14_FIQ 43
|
||||
#define SPSR_FIQ 44
|
||||
|
||||
#include "../Cheats.h"
|
||||
#include "../Globals.h"
|
||||
#include "../EEprom.h"
|
||||
#include "../Flash.h"
|
||||
|
||||
#endif //VBA_GBA_H
|
||||
// -*- C++ -*-
|
||||
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
|
||||
// Copyright (C) 1999-2003 Forgotten
|
||||
// Copyright (C) 2005 Forgotten and the VBA development team
|
||||
|
||||
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
#ifndef VBA_GBA_H
|
||||
#define VBA_GBA_H
|
||||
|
||||
#include "../System.h"
|
||||
|
||||
#define SAVE_GAME_VERSION_1 1
|
||||
#define SAVE_GAME_VERSION_2 2
|
||||
#define SAVE_GAME_VERSION_3 3
|
||||
#define SAVE_GAME_VERSION_4 4
|
||||
#define SAVE_GAME_VERSION_5 5
|
||||
#define SAVE_GAME_VERSION_6 6
|
||||
#define SAVE_GAME_VERSION_7 7
|
||||
#define SAVE_GAME_VERSION_8 8
|
||||
#define SAVE_GAME_VERSION_9 9
|
||||
#define SAVE_GAME_VERSION_10 10
|
||||
#define SAVE_GAME_VERSION SAVE_GAME_VERSION_10
|
||||
|
||||
typedef struct {
|
||||
u8 *address;
|
||||
u32 mask;
|
||||
} memoryMap;
|
||||
|
||||
typedef union {
|
||||
struct {
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
u8 B3;
|
||||
u8 B2;
|
||||
u8 B1;
|
||||
u8 B0;
|
||||
#else
|
||||
u8 B0;
|
||||
u8 B1;
|
||||
u8 B2;
|
||||
u8 B3;
|
||||
#endif
|
||||
} B;
|
||||
struct {
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
u16 W1;
|
||||
u16 W0;
|
||||
#else
|
||||
u16 W0;
|
||||
u16 W1;
|
||||
#endif
|
||||
} W;
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
volatile u32 I;
|
||||
#else
|
||||
u32 I;
|
||||
#endif
|
||||
} reg_pair;
|
||||
|
||||
#ifndef NO_GBA_MAP
|
||||
extern memoryMap map[256];
|
||||
#endif
|
||||
|
||||
extern reg_pair reg[45];
|
||||
extern u8 biosProtected[4];
|
||||
|
||||
extern bool N_FLAG;
|
||||
extern bool Z_FLAG;
|
||||
extern bool C_FLAG;
|
||||
extern bool V_FLAG;
|
||||
extern bool armIrqEnable;
|
||||
extern bool armState;
|
||||
extern int armMode;
|
||||
extern void (*cpuSaveGameFunc)(u32,u8);
|
||||
|
||||
#ifdef BKPT_SUPPORT
|
||||
extern u8 freezeWorkRAM[0x40000];
|
||||
extern u8 freezeInternalRAM[0x8000];
|
||||
extern u8 freezeVRAM[0x18000];
|
||||
extern u8 freezeOAM[0x400];
|
||||
extern u8 freezePRAM[0x400];
|
||||
extern bool debugger_last;
|
||||
extern int oldreg[17];
|
||||
extern char oldbuffer[10];
|
||||
#endif
|
||||
|
||||
extern bool CPUReadGSASnapshot(const char *);
|
||||
extern bool CPUWriteGSASnapshot(const char *, const char *, const char *, const char *);
|
||||
extern bool CPUWriteBatteryFile(const char *);
|
||||
extern bool CPUReadBatteryFile(const char *);
|
||||
extern bool CPUExportEepromFile(const char *);
|
||||
extern bool CPUImportEepromFile(const char *);
|
||||
extern bool CPUWritePNGFile(const char *);
|
||||
extern bool CPUWriteBMPFile(const char *);
|
||||
extern void CPUCleanUp();
|
||||
extern void CPUUpdateRender();
|
||||
extern void CPUUpdateRenderBuffers(bool);
|
||||
extern bool CPUReadMemState(char *, int);
|
||||
extern bool CPUReadState(const char *);
|
||||
extern bool CPUWriteMemState(char *, int);
|
||||
extern bool CPUWriteState(const char *);
|
||||
extern int CPULoadRom(const char *);
|
||||
extern void doMirroring(bool);
|
||||
extern void CPUUpdateRegister(u32, u16);
|
||||
extern void applyTimer ();
|
||||
extern void CPUInit(const char *,bool);
|
||||
extern void CPUReset();
|
||||
extern void CPULoop(int);
|
||||
extern void CPUCheckDMA(int,int);
|
||||
extern bool CPUIsGBAImage(const char *);
|
||||
extern bool CPUIsZipFile(const char *);
|
||||
#ifdef PROFILING
|
||||
#include "prof/prof.h"
|
||||
extern void cpuProfil(profile_segment *seg);
|
||||
extern void cpuEnableProfiling(int hz);
|
||||
#endif
|
||||
|
||||
extern struct EmulatedSystem GBASystem;
|
||||
|
||||
#define R13_IRQ 18
|
||||
#define R14_IRQ 19
|
||||
#define SPSR_IRQ 20
|
||||
#define R13_USR 26
|
||||
#define R14_USR 27
|
||||
#define R13_SVC 28
|
||||
#define R14_SVC 29
|
||||
#define SPSR_SVC 30
|
||||
#define R13_ABT 31
|
||||
#define R14_ABT 32
|
||||
#define SPSR_ABT 33
|
||||
#define R13_UND 34
|
||||
#define R14_UND 35
|
||||
#define SPSR_UND 36
|
||||
#define R8_FIQ 37
|
||||
#define R9_FIQ 38
|
||||
#define R10_FIQ 39
|
||||
#define R11_FIQ 40
|
||||
#define R12_FIQ 41
|
||||
#define R13_FIQ 42
|
||||
#define R14_FIQ 43
|
||||
#define SPSR_FIQ 44
|
||||
|
||||
#include "../Cheats.h"
|
||||
#include "../Globals.h"
|
||||
#include "../EEprom.h"
|
||||
#include "../Flash.h"
|
||||
|
||||
#endif //VBA_GBA_H
|
||||
|
|
|
@ -1,47 +1,47 @@
|
|||
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
|
||||
// Copyright (C) 1999-2003 Forgotten
|
||||
// Copyright (C) 2004 Forgotten and the VBA development team
|
||||
|
||||
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
#include "../System.h"
|
||||
|
||||
int coeff[32] = {
|
||||
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
|
||||
16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16};
|
||||
|
||||
u32 line0[240];
|
||||
u32 line1[240];
|
||||
u32 line2[240];
|
||||
u32 line3[240];
|
||||
u32 lineOBJ[240];
|
||||
u32 lineOBJWin[240];
|
||||
u32 lineMix[240];
|
||||
bool gfxInWin0[240];
|
||||
bool gfxInWin1[240];
|
||||
int lineOBJpixleft[128];
|
||||
|
||||
int gfxBG2Changed = 0;
|
||||
int gfxBG3Changed = 0;
|
||||
|
||||
int gfxBG2X = 0;
|
||||
int gfxBG2Y = 0;
|
||||
int gfxBG2LastX = 0;
|
||||
int gfxBG2LastY = 0;
|
||||
int gfxBG3X = 0;
|
||||
int gfxBG3Y = 0;
|
||||
int gfxBG3LastX = 0;
|
||||
int gfxBG3LastY = 0;
|
||||
int gfxLastVCOUNT = 0;
|
||||
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
|
||||
// Copyright (C) 1999-2003 Forgotten
|
||||
// Copyright (C) 2004 Forgotten and the VBA development team
|
||||
|
||||
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
#include "../System.h"
|
||||
|
||||
int coeff[32] = {
|
||||
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
|
||||
16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16};
|
||||
|
||||
u32 line0[240];
|
||||
u32 line1[240];
|
||||
u32 line2[240];
|
||||
u32 line3[240];
|
||||
u32 lineOBJ[240];
|
||||
u32 lineOBJWin[240];
|
||||
u32 lineMix[240];
|
||||
bool gfxInWin0[240];
|
||||
bool gfxInWin1[240];
|
||||
int lineOBJpixleft[128];
|
||||
|
||||
int gfxBG2Changed = 0;
|
||||
int gfxBG3Changed = 0;
|
||||
|
||||
int gfxBG2X = 0;
|
||||
int gfxBG2Y = 0;
|
||||
int gfxBG2LastX = 0;
|
||||
int gfxBG2LastY = 0;
|
||||
int gfxBG3X = 0;
|
||||
int gfxBG3Y = 0;
|
||||
int gfxBG3LastX = 0;
|
||||
int gfxBG3LastY = 0;
|
||||
int gfxLastVCOUNT = 0;
|
||||
|
|
3202
src/agb/GBAGfx.h
3202
src/agb/GBAGfx.h
File diff suppressed because it is too large
Load Diff
2166
src/agb/GBALink.cpp
2166
src/agb/GBALink.cpp
File diff suppressed because it is too large
Load Diff
|
@ -1,124 +1,124 @@
|
|||
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
|
||||
// Copyright (C) 1999-2003 Forgotten
|
||||
// Copyright (C) 2004 Forgotten and the VBA development team
|
||||
|
||||
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
#include<winsock.h>
|
||||
|
||||
#ifndef LINKH
|
||||
#define LINKH
|
||||
#define LINK_PARENTLOST 0x80
|
||||
#define UNSUPPORTED -1
|
||||
#define MULTIPLAYER 0
|
||||
#define NORMAL8 1
|
||||
#define NORMAL32 2
|
||||
#define UART 3
|
||||
#define JOYBUS 4
|
||||
#define GP 5
|
||||
#define RFU_INIT 0
|
||||
#define RFU_COMM 1
|
||||
#define RFU_SEND 2
|
||||
#define RFU_RECV 3
|
||||
|
||||
typedef struct {
|
||||
WORD linkdata[4];
|
||||
WORD linkcmd[4];
|
||||
WORD numtransfers;
|
||||
int lastlinktime;
|
||||
unsigned char numgbas;
|
||||
unsigned char linkflags;
|
||||
int rfu_q[4];
|
||||
u8 rfu_request[4];
|
||||
int rfu_linktime[4];
|
||||
u32 rfu_bdata[4][7];
|
||||
u32 rfu_data[4][32];
|
||||
} LINKDATA;
|
||||
|
||||
class lserver{
|
||||
int numbytes;
|
||||
fd_set fdset;
|
||||
timeval wsocktimeout;
|
||||
//timeval udptimeout;
|
||||
char inbuffer[256], outbuffer[256];
|
||||
int *intinbuffer;
|
||||
u16 *u16inbuffer;
|
||||
int *intoutbuffer;
|
||||
u16 *u16outbuffer;
|
||||
int counter;
|
||||
int done;
|
||||
public:
|
||||
int howmanytimes;
|
||||
SOCKET tcpsocket[4];
|
||||
SOCKADDR_IN udpaddr[4];
|
||||
lserver(void);
|
||||
int Init(void*);
|
||||
void Send(void);
|
||||
void Recv(void);
|
||||
};
|
||||
|
||||
class lclient{
|
||||
fd_set fdset;
|
||||
timeval wsocktimeout;
|
||||
char inbuffer[256], outbuffer[256];
|
||||
int *intinbuffer;
|
||||
u16 *u16inbuffer;
|
||||
int *intoutbuffer;
|
||||
u16 *u16outbuffer;
|
||||
int numbytes;
|
||||
public:
|
||||
bool oncesend;
|
||||
SOCKADDR_IN serverinfo;
|
||||
SOCKET noblock;
|
||||
int numtransfers;
|
||||
lclient(void);
|
||||
int Init(LPHOSTENT, void*);
|
||||
void Send(void);
|
||||
void Recv(void);
|
||||
void CheckConn(void);
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
SOCKET tcpsocket;
|
||||
//SOCKET udpsocket;
|
||||
int numgbas;
|
||||
HANDLE thread;
|
||||
u8 type;
|
||||
u8 server;
|
||||
bool terminate;
|
||||
bool connected;
|
||||
bool speed;
|
||||
bool active;
|
||||
} LANLINKDATA;
|
||||
|
||||
extern void LinkUpdate(void);
|
||||
extern void LinkChildStop(void);
|
||||
extern void LinkChildSend(u16);
|
||||
extern int openLinkLog(void);
|
||||
extern void closeLinkLog();
|
||||
extern void CloseLanLink(void);
|
||||
extern char *MakeInstanceFilename(const char *Input);
|
||||
|
||||
extern LANLINKDATA lanlink;
|
||||
extern FILE *linklogfile;
|
||||
extern int vbaid;
|
||||
extern int linklog;
|
||||
extern bool adapter;
|
||||
extern bool linkenable;
|
||||
extern int linktimeout;
|
||||
extern lclient lc;
|
||||
extern int linkid;
|
||||
|
||||
#endif
|
||||
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
|
||||
// Copyright (C) 1999-2003 Forgotten
|
||||
// Copyright (C) 2004 Forgotten and the VBA development team
|
||||
|
||||
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
#include<winsock.h>
|
||||
|
||||
#ifndef LINKH
|
||||
#define LINKH
|
||||
#define LINK_PARENTLOST 0x80
|
||||
#define UNSUPPORTED -1
|
||||
#define MULTIPLAYER 0
|
||||
#define NORMAL8 1
|
||||
#define NORMAL32 2
|
||||
#define UART 3
|
||||
#define JOYBUS 4
|
||||
#define GP 5
|
||||
#define RFU_INIT 0
|
||||
#define RFU_COMM 1
|
||||
#define RFU_SEND 2
|
||||
#define RFU_RECV 3
|
||||
|
||||
typedef struct {
|
||||
WORD linkdata[4];
|
||||
WORD linkcmd[4];
|
||||
WORD numtransfers;
|
||||
int lastlinktime;
|
||||
unsigned char numgbas;
|
||||
unsigned char linkflags;
|
||||
int rfu_q[4];
|
||||
u8 rfu_request[4];
|
||||
int rfu_linktime[4];
|
||||
u32 rfu_bdata[4][7];
|
||||
u32 rfu_data[4][32];
|
||||
} LINKDATA;
|
||||
|
||||
class lserver{
|
||||
int numbytes;
|
||||
fd_set fdset;
|
||||
timeval wsocktimeout;
|
||||
//timeval udptimeout;
|
||||
char inbuffer[256], outbuffer[256];
|
||||
int *intinbuffer;
|
||||
u16 *u16inbuffer;
|
||||
int *intoutbuffer;
|
||||
u16 *u16outbuffer;
|
||||
int counter;
|
||||
int done;
|
||||
public:
|
||||
int howmanytimes;
|
||||
SOCKET tcpsocket[4];
|
||||
SOCKADDR_IN udpaddr[4];
|
||||
lserver(void);
|
||||
int Init(void*);
|
||||
void Send(void);
|
||||
void Recv(void);
|
||||
};
|
||||
|
||||
class lclient{
|
||||
fd_set fdset;
|
||||
timeval wsocktimeout;
|
||||
char inbuffer[256], outbuffer[256];
|
||||
int *intinbuffer;
|
||||
u16 *u16inbuffer;
|
||||
int *intoutbuffer;
|
||||
u16 *u16outbuffer;
|
||||
int numbytes;
|
||||
public:
|
||||
bool oncesend;
|
||||
SOCKADDR_IN serverinfo;
|
||||
SOCKET noblock;
|
||||
int numtransfers;
|
||||
lclient(void);
|
||||
int Init(LPHOSTENT, void*);
|
||||
void Send(void);
|
||||
void Recv(void);
|
||||
void CheckConn(void);
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
SOCKET tcpsocket;
|
||||
//SOCKET udpsocket;
|
||||
int numgbas;
|
||||
HANDLE thread;
|
||||
u8 type;
|
||||
u8 server;
|
||||
bool terminate;
|
||||
bool connected;
|
||||
bool speed;
|
||||
bool active;
|
||||
} LANLINKDATA;
|
||||
|
||||
extern void LinkUpdate(void);
|
||||
extern void LinkChildStop(void);
|
||||
extern void LinkChildSend(u16);
|
||||
extern int openLinkLog(void);
|
||||
extern void closeLinkLog();
|
||||
extern void CloseLanLink(void);
|
||||
extern char *MakeInstanceFilename(const char *Input);
|
||||
|
||||
extern LANLINKDATA lanlink;
|
||||
extern FILE *linklogfile;
|
||||
extern int vbaid;
|
||||
extern int linklog;
|
||||
extern bool adapter;
|
||||
extern bool linkenable;
|
||||
extern int linktimeout;
|
||||
extern lclient lc;
|
||||
extern int linkid;
|
||||
|
||||
#endif
|
||||
|
|
604
src/agb/GBAcpu.h
604
src/agb/GBAcpu.h
|
@ -1,302 +1,302 @@
|
|||
// -*- C++ -*-
|
||||
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
|
||||
// Copyright (C) 1999-2003 Forgotten
|
||||
// Copyright (C) 2005 Forgotten and the VBA development team
|
||||
|
||||
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
#ifndef VBA_GBAcpu_H
|
||||
#define VBA_GBAcpu_H
|
||||
|
||||
extern int armExecute();
|
||||
extern int thumbExecute();
|
||||
|
||||
#ifdef __GNUC__
|
||||
# define INSN_REGPARM __attribute__((regparm(1)))
|
||||
# define LIKELY(x) __builtin_expect(!!(x),1)
|
||||
# define UNLIKELY(x) __builtin_expect(!!(x),0)
|
||||
#else
|
||||
# define INSN_REGPARM /*nothing*/
|
||||
# define LIKELY(x) (x)
|
||||
# define UNLIKELY(x) (x)
|
||||
#endif
|
||||
|
||||
#define UPDATE_REG(address, value)\
|
||||
{\
|
||||
WRITE16LE(((u16 *)&ioMem[address]),value);\
|
||||
}\
|
||||
|
||||
#define ARM_PREFETCH \
|
||||
{\
|
||||
cpuPrefetch[0] = CPUReadMemoryQuick(armNextPC);\
|
||||
cpuPrefetch[1] = CPUReadMemoryQuick(armNextPC+4);\
|
||||
}
|
||||
|
||||
#define THUMB_PREFETCH \
|
||||
{\
|
||||
cpuPrefetch[0] = CPUReadHalfWordQuick(armNextPC);\
|
||||
cpuPrefetch[1] = CPUReadHalfWordQuick(armNextPC+2);\
|
||||
}
|
||||
|
||||
#define ARM_PREFETCH_NEXT \
|
||||
cpuPrefetch[1] = CPUReadMemoryQuick(armNextPC+4);
|
||||
|
||||
#define THUMB_PREFETCH_NEXT\
|
||||
cpuPrefetch[1] = CPUReadHalfWordQuick(armNextPC+2);
|
||||
|
||||
|
||||
extern int SWITicks;
|
||||
extern u32 mastercode;
|
||||
extern bool busPrefetch;
|
||||
extern bool busPrefetchEnable;
|
||||
extern u32 busPrefetchCount;
|
||||
extern int cpuNextEvent;
|
||||
extern bool holdState;
|
||||
extern u32 cpuPrefetch[2];
|
||||
extern int cpuTotalTicks;
|
||||
extern u8 memoryWait[16];
|
||||
extern u8 memoryWait32[16];
|
||||
extern u8 memoryWaitSeq[16];
|
||||
extern u8 memoryWaitSeq32[16];
|
||||
extern u8 cpuBitsSet[256];
|
||||
extern u8 cpuLowestBitSet[256];
|
||||
extern void CPUSwitchMode(int mode, bool saveState, bool breakLoop);
|
||||
extern void CPUSwitchMode(int mode, bool saveState);
|
||||
extern void CPUUpdateCPSR();
|
||||
extern void CPUUpdateFlags(bool breakLoop);
|
||||
extern void CPUUpdateFlags();
|
||||
extern void CPUUndefinedException();
|
||||
extern void CPUSoftwareInterrupt();
|
||||
extern void CPUSoftwareInterrupt(int comment);
|
||||
|
||||
|
||||
// Waitstates when accessing data
|
||||
inline int dataTicksAccess16(u32 address) // DATA 8/16bits NON SEQ
|
||||
{
|
||||
int addr = (address>>24)&15;
|
||||
int value = memoryWait[addr];
|
||||
|
||||
if ((addr>=0x08) || (addr < 0x02))
|
||||
{
|
||||
busPrefetchCount=0;
|
||||
busPrefetch=false;
|
||||
}
|
||||
else if (busPrefetch)
|
||||
{
|
||||
int waitState = value;
|
||||
if (!waitState)
|
||||
waitState = 1;
|
||||
busPrefetchCount = ((busPrefetchCount+1)<<waitState) - 1;
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
inline int dataTicksAccess32(u32 address) // DATA 32bits NON SEQ
|
||||
{
|
||||
int addr = (address>>24)&15;
|
||||
int value = memoryWait32[addr];
|
||||
|
||||
if ((addr>=0x08) || (addr < 0x02))
|
||||
{
|
||||
busPrefetchCount=0;
|
||||
busPrefetch=false;
|
||||
}
|
||||
else if (busPrefetch)
|
||||
{
|
||||
int waitState = value;
|
||||
if (!waitState)
|
||||
waitState = 1;
|
||||
busPrefetchCount = ((busPrefetchCount+1)<<waitState) - 1;
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
inline int dataTicksAccessSeq16(u32 address)// DATA 8/16bits SEQ
|
||||
{
|
||||
int addr = (address>>24)&15;
|
||||
int value = memoryWaitSeq[addr];
|
||||
|
||||
if ((addr>=0x08) || (addr < 0x02))
|
||||
{
|
||||
busPrefetchCount=0;
|
||||
busPrefetch=false;
|
||||
}
|
||||
else if (busPrefetch)
|
||||
{
|
||||
int waitState = value;
|
||||
if (!waitState)
|
||||
waitState = 1;
|
||||
busPrefetchCount = ((busPrefetchCount+1)<<waitState) - 1;
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
inline int dataTicksAccessSeq32(u32 address)// DATA 32bits SEQ
|
||||
{
|
||||
int addr = (address>>24)&15;
|
||||
int value = memoryWaitSeq32[addr];
|
||||
|
||||
if ((addr>=0x08) || (addr < 0x02))
|
||||
{
|
||||
busPrefetchCount=0;
|
||||
busPrefetch=false;
|
||||
}
|
||||
else if (busPrefetch)
|
||||
{
|
||||
int waitState = value;
|
||||
if (!waitState)
|
||||
waitState = 1;
|
||||
busPrefetchCount = ((busPrefetchCount+1)<<waitState) - 1;
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
|
||||
// Waitstates when executing opcode
|
||||
inline int codeTicksAccess16(u32 address) // THUMB NON SEQ
|
||||
{
|
||||
int addr = (address>>24)&15;
|
||||
|
||||
if ((addr>=0x08) && (addr<=0x0D))
|
||||
{
|
||||
if (busPrefetchCount&0x1)
|
||||
{
|
||||
if (busPrefetchCount&0x2)
|
||||
{
|
||||
busPrefetchCount = ((busPrefetchCount&0xFF)>>2) | (busPrefetchCount&0xFFFFFF00);
|
||||
return 0;
|
||||
}
|
||||
busPrefetchCount = ((busPrefetchCount&0xFF)>>1) | (busPrefetchCount&0xFFFFFF00);
|
||||
return memoryWaitSeq[addr]-1;
|
||||
}
|
||||
else
|
||||
{
|
||||
busPrefetchCount=0;
|
||||
return memoryWait[addr];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
busPrefetchCount = 0;
|
||||
return memoryWait[addr];
|
||||
}
|
||||
}
|
||||
|
||||
inline int codeTicksAccess32(u32 address) // ARM NON SEQ
|
||||
{
|
||||
int addr = (address>>24)&15;
|
||||
|
||||
if ((addr>=0x08) && (addr<=0x0D))
|
||||
{
|
||||
if (busPrefetchCount&0x1)
|
||||
{
|
||||
if (busPrefetchCount&0x2)
|
||||
{
|
||||
busPrefetchCount = ((busPrefetchCount&0xFF)>>2) | (busPrefetchCount&0xFFFFFF00);
|
||||
return 0;
|
||||
}
|
||||
busPrefetchCount = ((busPrefetchCount&0xFF)>>1) | (busPrefetchCount&0xFFFFFF00);
|
||||
return memoryWaitSeq[addr] - 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
busPrefetchCount = 0;
|
||||
return memoryWait32[addr];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
busPrefetchCount = 0;
|
||||
return memoryWait32[addr];
|
||||
}
|
||||
}
|
||||
|
||||
inline int codeTicksAccessSeq16(u32 address) // THUMB SEQ
|
||||
{
|
||||
int addr = (address>>24)&15;
|
||||
|
||||
if ((addr>=0x08) && (addr<=0x0D))
|
||||
{
|
||||
if (busPrefetchCount&0x1)
|
||||
{
|
||||
busPrefetchCount = ((busPrefetchCount&0xFF)>>1) | (busPrefetchCount&0xFFFFFF00);
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
if (busPrefetchCount>0xFF)
|
||||
{
|
||||
busPrefetchCount=0;
|
||||
return memoryWait[addr];
|
||||
}
|
||||
else
|
||||
return memoryWaitSeq[addr];
|
||||
}
|
||||
else
|
||||
{
|
||||
busPrefetchCount = 0;
|
||||
return memoryWaitSeq[addr];
|
||||
}
|
||||
}
|
||||
|
||||
inline int codeTicksAccessSeq32(u32 address) // ARM SEQ
|
||||
{
|
||||
int addr = (address>>24)&15;
|
||||
|
||||
if ((addr>=0x08) && (addr<=0x0D))
|
||||
{
|
||||
if (busPrefetchCount&0x1)
|
||||
{
|
||||
if (busPrefetchCount&0x2)
|
||||
{
|
||||
busPrefetchCount = ((busPrefetchCount&0xFF)>>2) | (busPrefetchCount&0xFFFFFF00);
|
||||
return 0;
|
||||
}
|
||||
busPrefetchCount = ((busPrefetchCount&0xFF)>>1) | (busPrefetchCount&0xFFFFFF00);
|
||||
return memoryWaitSeq[addr];
|
||||
}
|
||||
else
|
||||
if (busPrefetchCount>0xFF)
|
||||
{
|
||||
busPrefetchCount=0;
|
||||
return memoryWait32[addr];
|
||||
}
|
||||
else
|
||||
return memoryWaitSeq32[addr];
|
||||
}
|
||||
else
|
||||
{
|
||||
return memoryWaitSeq32[addr];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Emulates the Cheat System (m) code
|
||||
inline void cpuMasterCodeCheck()
|
||||
{
|
||||
if((mastercode) && (mastercode == armNextPC))
|
||||
{
|
||||
u32 joy = 0;
|
||||
if(systemReadJoypads())
|
||||
joy = systemReadJoypad(-1);
|
||||
u32 ext = (joy >> 10);
|
||||
cpuTotalTicks += cheatsCheckKeys(P1^0x3FF, ext);
|
||||
}
|
||||
}
|
||||
|
||||
#endif //VBA_GBAcpu_H
|
||||
// -*- C++ -*-
|
||||
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
|
||||
// Copyright (C) 1999-2003 Forgotten
|
||||
// Copyright (C) 2005 Forgotten and the VBA development team
|
||||
|
||||
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
#ifndef VBA_GBAcpu_H
|
||||
#define VBA_GBAcpu_H
|
||||
|
||||
extern int armExecute();
|
||||
extern int thumbExecute();
|
||||
|
||||
#ifdef __GNUC__
|
||||
# define INSN_REGPARM __attribute__((regparm(1)))
|
||||
# define LIKELY(x) __builtin_expect(!!(x),1)
|
||||
# define UNLIKELY(x) __builtin_expect(!!(x),0)
|
||||
#else
|
||||
# define INSN_REGPARM /*nothing*/
|
||||
# define LIKELY(x) (x)
|
||||
# define UNLIKELY(x) (x)
|
||||
#endif
|
||||
|
||||
#define UPDATE_REG(address, value)\
|
||||
{\
|
||||
WRITE16LE(((u16 *)&ioMem[address]),value);\
|
||||
}\
|
||||
|
||||
#define ARM_PREFETCH \
|
||||
{\
|
||||
cpuPrefetch[0] = CPUReadMemoryQuick(armNextPC);\
|
||||
cpuPrefetch[1] = CPUReadMemoryQuick(armNextPC+4);\
|
||||
}
|
||||
|
||||
#define THUMB_PREFETCH \
|
||||
{\
|
||||
cpuPrefetch[0] = CPUReadHalfWordQuick(armNextPC);\
|
||||
cpuPrefetch[1] = CPUReadHalfWordQuick(armNextPC+2);\
|
||||
}
|
||||
|
||||
#define ARM_PREFETCH_NEXT \
|
||||
cpuPrefetch[1] = CPUReadMemoryQuick(armNextPC+4);
|
||||
|
||||
#define THUMB_PREFETCH_NEXT\
|
||||
cpuPrefetch[1] = CPUReadHalfWordQuick(armNextPC+2);
|
||||
|
||||
|
||||
extern int SWITicks;
|
||||
extern u32 mastercode;
|
||||
extern bool busPrefetch;
|
||||
extern bool busPrefetchEnable;
|
||||
extern u32 busPrefetchCount;
|
||||
extern int cpuNextEvent;
|
||||
extern bool holdState;
|
||||
extern u32 cpuPrefetch[2];
|
||||
extern int cpuTotalTicks;
|
||||
extern u8 memoryWait[16];
|
||||
extern u8 memoryWait32[16];
|
||||
extern u8 memoryWaitSeq[16];
|
||||
extern u8 memoryWaitSeq32[16];
|
||||
extern u8 cpuBitsSet[256];
|
||||
extern u8 cpuLowestBitSet[256];
|
||||
extern void CPUSwitchMode(int mode, bool saveState, bool breakLoop);
|
||||
extern void CPUSwitchMode(int mode, bool saveState);
|
||||
extern void CPUUpdateCPSR();
|
||||
extern void CPUUpdateFlags(bool breakLoop);
|
||||
extern void CPUUpdateFlags();
|
||||
extern void CPUUndefinedException();
|
||||
extern void CPUSoftwareInterrupt();
|
||||
extern void CPUSoftwareInterrupt(int comment);
|
||||
|
||||
|
||||
// Waitstates when accessing data
|
||||
inline int dataTicksAccess16(u32 address) // DATA 8/16bits NON SEQ
|
||||
{
|
||||
int addr = (address>>24)&15;
|
||||
int value = memoryWait[addr];
|
||||
|
||||
if ((addr>=0x08) || (addr < 0x02))
|
||||
{
|
||||
busPrefetchCount=0;
|
||||
busPrefetch=false;
|
||||
}
|
||||
else if (busPrefetch)
|
||||
{
|
||||
int waitState = value;
|
||||
if (!waitState)
|
||||
waitState = 1;
|
||||
busPrefetchCount = ((busPrefetchCount+1)<<waitState) - 1;
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
inline int dataTicksAccess32(u32 address) // DATA 32bits NON SEQ
|
||||
{
|
||||
int addr = (address>>24)&15;
|
||||
int value = memoryWait32[addr];
|
||||
|
||||
if ((addr>=0x08) || (addr < 0x02))
|
||||
{
|
||||
busPrefetchCount=0;
|
||||
busPrefetch=false;
|
||||
}
|
||||
else if (busPrefetch)
|
||||
{
|
||||
int waitState = value;
|
||||
if (!waitState)
|
||||
waitState = 1;
|
||||
busPrefetchCount = ((busPrefetchCount+1)<<waitState) - 1;
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
inline int dataTicksAccessSeq16(u32 address)// DATA 8/16bits SEQ
|
||||
{
|
||||
int addr = (address>>24)&15;
|
||||
int value = memoryWaitSeq[addr];
|
||||
|
||||
if ((addr>=0x08) || (addr < 0x02))
|
||||
{
|
||||
busPrefetchCount=0;
|
||||
busPrefetch=false;
|
||||
}
|
||||
else if (busPrefetch)
|
||||
{
|
||||
int waitState = value;
|
||||
if (!waitState)
|
||||
waitState = 1;
|
||||
busPrefetchCount = ((busPrefetchCount+1)<<waitState) - 1;
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
inline int dataTicksAccessSeq32(u32 address)// DATA 32bits SEQ
|
||||
{
|
||||
int addr = (address>>24)&15;
|
||||
int value = memoryWaitSeq32[addr];
|
||||
|
||||
if ((addr>=0x08) || (addr < 0x02))
|
||||
{
|
||||
busPrefetchCount=0;
|
||||
busPrefetch=false;
|
||||
}
|
||||
else if (busPrefetch)
|
||||
{
|
||||
int waitState = value;
|
||||
if (!waitState)
|
||||
waitState = 1;
|
||||
busPrefetchCount = ((busPrefetchCount+1)<<waitState) - 1;
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
|
||||
// Waitstates when executing opcode
|
||||
inline int codeTicksAccess16(u32 address) // THUMB NON SEQ
|
||||
{
|
||||
int addr = (address>>24)&15;
|
||||
|
||||
if ((addr>=0x08) && (addr<=0x0D))
|
||||
{
|
||||
if (busPrefetchCount&0x1)
|
||||
{
|
||||
if (busPrefetchCount&0x2)
|
||||
{
|
||||
busPrefetchCount = ((busPrefetchCount&0xFF)>>2) | (busPrefetchCount&0xFFFFFF00);
|
||||
return 0;
|
||||
}
|
||||
busPrefetchCount = ((busPrefetchCount&0xFF)>>1) | (busPrefetchCount&0xFFFFFF00);
|
||||
return memoryWaitSeq[addr]-1;
|
||||
}
|
||||
else
|
||||
{
|
||||
busPrefetchCount=0;
|
||||
return memoryWait[addr];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
busPrefetchCount = 0;
|
||||
return memoryWait[addr];
|
||||
}
|
||||
}
|
||||
|
||||
inline int codeTicksAccess32(u32 address) // ARM NON SEQ
|
||||
{
|
||||
int addr = (address>>24)&15;
|
||||
|
||||
if ((addr>=0x08) && (addr<=0x0D))
|
||||
{
|
||||
if (busPrefetchCount&0x1)
|
||||
{
|
||||
if (busPrefetchCount&0x2)
|
||||
{
|
||||
busPrefetchCount = ((busPrefetchCount&0xFF)>>2) | (busPrefetchCount&0xFFFFFF00);
|
||||
return 0;
|
||||
}
|
||||
busPrefetchCount = ((busPrefetchCount&0xFF)>>1) | (busPrefetchCount&0xFFFFFF00);
|
||||
return memoryWaitSeq[addr] - 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
busPrefetchCount = 0;
|
||||
return memoryWait32[addr];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
busPrefetchCount = 0;
|
||||
return memoryWait32[addr];
|
||||
}
|
||||
}
|
||||
|
||||
inline int codeTicksAccessSeq16(u32 address) // THUMB SEQ
|
||||
{
|
||||
int addr = (address>>24)&15;
|
||||
|
||||
if ((addr>=0x08) && (addr<=0x0D))
|
||||
{
|
||||
if (busPrefetchCount&0x1)
|
||||
{
|
||||
busPrefetchCount = ((busPrefetchCount&0xFF)>>1) | (busPrefetchCount&0xFFFFFF00);
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
if (busPrefetchCount>0xFF)
|
||||
{
|
||||
busPrefetchCount=0;
|
||||
return memoryWait[addr];
|
||||
}
|
||||
else
|
||||
return memoryWaitSeq[addr];
|
||||
}
|
||||
else
|
||||
{
|
||||
busPrefetchCount = 0;
|
||||
return memoryWaitSeq[addr];
|
||||
}
|
||||
}
|
||||
|
||||
inline int codeTicksAccessSeq32(u32 address) // ARM SEQ
|
||||
{
|
||||
int addr = (address>>24)&15;
|
||||
|
||||
if ((addr>=0x08) && (addr<=0x0D))
|
||||
{
|
||||
if (busPrefetchCount&0x1)
|
||||
{
|
||||
if (busPrefetchCount&0x2)
|
||||
{
|
||||
busPrefetchCount = ((busPrefetchCount&0xFF)>>2) | (busPrefetchCount&0xFFFFFF00);
|
||||
return 0;
|
||||
}
|
||||
busPrefetchCount = ((busPrefetchCount&0xFF)>>1) | (busPrefetchCount&0xFFFFFF00);
|
||||
return memoryWaitSeq[addr];
|
||||
}
|
||||
else
|
||||
if (busPrefetchCount>0xFF)
|
||||
{
|
||||
busPrefetchCount=0;
|
||||
return memoryWait32[addr];
|
||||
}
|
||||
else
|
||||
return memoryWaitSeq32[addr];
|
||||
}
|
||||
else
|
||||
{
|
||||
return memoryWaitSeq32[addr];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Emulates the Cheat System (m) code
|
||||
inline void cpuMasterCodeCheck()
|
||||
{
|
||||
if((mastercode) && (mastercode == armNextPC))
|
||||
{
|
||||
u32 joy = 0;
|
||||
if(systemReadJoypads())
|
||||
joy = systemReadJoypad(-1);
|
||||
u32 ext = (joy >> 10);
|
||||
cpuTotalTicks += cheatsCheckKeys(P1^0x3FF, ext);
|
||||
}
|
||||
}
|
||||
|
||||
#endif //VBA_GBAcpu_H
|
||||
|
|
1478
src/agb/GBAinline.h
1478
src/agb/GBAinline.h
File diff suppressed because it is too large
Load Diff
|
@ -1,98 +1,98 @@
|
|||
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
|
||||
// Copyright (C) 1999-2003 Forgotten
|
||||
// Copyright (C) 2004 Forgotten and the VBA development team
|
||||
|
||||
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "GBA.h"
|
||||
#include "../Globals.h"
|
||||
#include "../Port.h"
|
||||
#include "../System.h"
|
||||
|
||||
#define debuggerWriteHalfWord(addr, value) \
|
||||
WRITE16LE((u16*)&map[(addr)>>24].address[(addr) & map[(addr)>>24].mask], (value))
|
||||
|
||||
#define debuggerReadHalfWord(addr) \
|
||||
READ16LE(((u16*)&map[(addr)>>24].address[(addr) & map[(addr)>>24].mask]))
|
||||
|
||||
static bool agbPrintEnabled = false;
|
||||
static bool agbPrintProtect = false;
|
||||
|
||||
bool agbPrintWrite(u32 address, u16 value)
|
||||
{
|
||||
if(agbPrintEnabled) {
|
||||
if(address == 0x9fe2ffe) { // protect
|
||||
agbPrintProtect = (value != 0);
|
||||
debuggerWriteHalfWord(address, value);
|
||||
return true;
|
||||
} else {
|
||||
if(agbPrintProtect &&
|
||||
((address >= 0x9fe20f8 && address <= 0x9fe20ff) // control structure
|
||||
|| (address >= 0x8fd0000 && address <= 0x8fdffff)
|
||||
|| (address >= 0x9fd0000 && address <= 0x9fdffff))) {
|
||||
debuggerWriteHalfWord(address, value);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void agbPrintReset()
|
||||
{
|
||||
agbPrintProtect = false;
|
||||
}
|
||||
|
||||
void agbPrintEnable(bool enable)
|
||||
{
|
||||
agbPrintEnabled = enable;
|
||||
}
|
||||
|
||||
bool agbPrintIsEnabled()
|
||||
{
|
||||
return agbPrintEnabled;
|
||||
}
|
||||
|
||||
void agbPrintFlush()
|
||||
{
|
||||
u16 get = debuggerReadHalfWord(0x9fe20fc);
|
||||
u16 put = debuggerReadHalfWord(0x9fe20fe);
|
||||
|
||||
u32 address = (debuggerReadHalfWord(0x9fe20fa) << 16);
|
||||
if(address != 0xfd0000 && address != 0x1fd0000) {
|
||||
dbgOutput("Did you forget to call AGBPrintInit?\n", 0);
|
||||
// get rid of the text otherwise we will continue to be called
|
||||
debuggerWriteHalfWord(0x9fe20fc, put);
|
||||
return;
|
||||
}
|
||||
|
||||
u8 *data = &rom[address];
|
||||
|
||||
while(get != put) {
|
||||
char c = data[get++];
|
||||
char s[2];
|
||||
s[0] = c;
|
||||
s[1] = 0;
|
||||
|
||||
if(systemVerbose & VERBOSE_AGBPRINT)
|
||||
dbgOutput(s, 0);
|
||||
if(c == '\n')
|
||||
break;
|
||||
}
|
||||
debuggerWriteHalfWord(0x9fe20fc, get);
|
||||
}
|
||||
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
|
||||
// Copyright (C) 1999-2003 Forgotten
|
||||
// Copyright (C) 2004 Forgotten and the VBA development team
|
||||
|
||||
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "GBA.h"
|
||||
#include "../Globals.h"
|
||||
#include "../Port.h"
|
||||
#include "../System.h"
|
||||
|
||||
#define debuggerWriteHalfWord(addr, value) \
|
||||
WRITE16LE((u16*)&map[(addr)>>24].address[(addr) & map[(addr)>>24].mask], (value))
|
||||
|
||||
#define debuggerReadHalfWord(addr) \
|
||||
READ16LE(((u16*)&map[(addr)>>24].address[(addr) & map[(addr)>>24].mask]))
|
||||
|
||||
static bool agbPrintEnabled = false;
|
||||
static bool agbPrintProtect = false;
|
||||
|
||||
bool agbPrintWrite(u32 address, u16 value)
|
||||
{
|
||||
if(agbPrintEnabled) {
|
||||
if(address == 0x9fe2ffe) { // protect
|
||||
agbPrintProtect = (value != 0);
|
||||
debuggerWriteHalfWord(address, value);
|
||||
return true;
|
||||
} else {
|
||||
if(agbPrintProtect &&
|
||||
((address >= 0x9fe20f8 && address <= 0x9fe20ff) // control structure
|
||||
|| (address >= 0x8fd0000 && address <= 0x8fdffff)
|
||||
|| (address >= 0x9fd0000 && address <= 0x9fdffff))) {
|
||||
debuggerWriteHalfWord(address, value);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void agbPrintReset()
|
||||
{
|
||||
agbPrintProtect = false;
|
||||
}
|
||||
|
||||
void agbPrintEnable(bool enable)
|
||||
{
|
||||
agbPrintEnabled = enable;
|
||||
}
|
||||
|
||||
bool agbPrintIsEnabled()
|
||||
{
|
||||
return agbPrintEnabled;
|
||||
}
|
||||
|
||||
void agbPrintFlush()
|
||||
{
|
||||
u16 get = debuggerReadHalfWord(0x9fe20fc);
|
||||
u16 put = debuggerReadHalfWord(0x9fe20fe);
|
||||
|
||||
u32 address = (debuggerReadHalfWord(0x9fe20fa) << 16);
|
||||
if(address != 0xfd0000 && address != 0x1fd0000) {
|
||||
dbgOutput("Did you forget to call AGBPrintInit?\n", 0);
|
||||
// get rid of the text otherwise we will continue to be called
|
||||
debuggerWriteHalfWord(0x9fe20fc, put);
|
||||
return;
|
||||
}
|
||||
|
||||
u8 *data = &rom[address];
|
||||
|
||||
while(get != put) {
|
||||
char c = data[get++];
|
||||
char s[2];
|
||||
s[0] = c;
|
||||
s[1] = 0;
|
||||
|
||||
if(systemVerbose & VERBOSE_AGBPRINT)
|
||||
dbgOutput(s, 0);
|
||||
if(c == '\n')
|
||||
break;
|
||||
}
|
||||
debuggerWriteHalfWord(0x9fe20fc, get);
|
||||
}
|
||||
|
|
|
@ -1,27 +1,27 @@
|
|||
// -*- C++ -*-
|
||||
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
|
||||
// Copyright (C) 1999-2003 Forgotten
|
||||
// Copyright (C) 2004 Forgotten and the VBA development team
|
||||
|
||||
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
#ifndef VBA_AGBPRINT_H
|
||||
#define VBA_AGBPRINT_H
|
||||
extern void agbPrintEnable(bool);
|
||||
extern bool agbPrintIsEnabled();
|
||||
extern void agbPrintReset();
|
||||
extern bool agbPrintWrite(u32, u16);
|
||||
extern void agbPrintFlush();
|
||||
#endif
|
||||
// -*- C++ -*-
|
||||
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
|
||||
// Copyright (C) 1999-2003 Forgotten
|
||||
// Copyright (C) 2004 Forgotten and the VBA development team
|
||||
|
||||
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
#ifndef VBA_AGBPRINT_H
|
||||
#define VBA_AGBPRINT_H
|
||||
extern void agbPrintEnable(bool);
|
||||
extern bool agbPrintIsEnabled();
|
||||
extern void agbPrintReset();
|
||||
extern bool agbPrintWrite(u32, u16);
|
||||
extern void agbPrintFlush();
|
||||
#endif
|
||||
|
|
|
@ -1,227 +1,227 @@
|
|||
#include "gbafilter.h"
|
||||
|
||||
#include <math.h>
|
||||
|
||||
extern int systemColorDepth;
|
||||
extern int systemRedShift;
|
||||
extern int systemGreenShift;
|
||||
extern int systemBlueShift;
|
||||
|
||||
extern u16 systemColorMap16[0x10000];
|
||||
extern u32 systemColorMap32[0x10000];
|
||||
|
||||
static const unsigned char curve[32] = { 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0e, 0x10, 0x12,
|
||||
0x14, 0x16, 0x18, 0x1c, 0x20, 0x28, 0x30, 0x38,
|
||||
0x40, 0x48, 0x50, 0x58, 0x60, 0x68, 0x70, 0x80,
|
||||
0x88, 0x90, 0xa0, 0xb0, 0xc0, 0xd0, 0xe0, 0xf0};
|
||||
|
||||
// output R G B
|
||||
static const unsigned char influence[3 * 3] = { 16, 4, 4, // red
|
||||
8, 16, 8, // green
|
||||
0, 8, 16};// blue
|
||||
|
||||
inline void swap(short & a, short & b)
|
||||
{
|
||||
short temp = a;
|
||||
a = b;
|
||||
b = temp;
|
||||
}
|
||||
|
||||
void gbafilter_pal(u16 * buf, int count)
|
||||
{
|
||||
short temp[3 * 3], s;
|
||||
unsigned pix;
|
||||
u8 red, green, blue;
|
||||
|
||||
while (count--)
|
||||
{
|
||||
pix = *buf;
|
||||
|
||||
s = curve[(pix >> systemGreenShift) & 0x1f];
|
||||
temp[3] = s * influence[3];
|
||||
temp[4] = s * influence[4];
|
||||
temp[5] = s * influence[5];
|
||||
|
||||
s = curve[(pix >> systemRedShift) & 0x1f];
|
||||
temp[0] = s * influence[0];
|
||||
temp[1] = s * influence[1];
|
||||
temp[2] = s * influence[2];
|
||||
|
||||
s = curve[(pix >> systemBlueShift) & 0x1f];
|
||||
temp[6] = s * influence[6];
|
||||
temp[7] = s * influence[7];
|
||||
temp[8] = s * influence[8];
|
||||
|
||||
if (temp[0] < temp[3]) swap(temp[0], temp[3]);
|
||||
if (temp[0] < temp[6]) swap(temp[0], temp[6]);
|
||||
if (temp[3] < temp[6]) swap(temp[3], temp[6]);
|
||||
temp[3] <<= 1;
|
||||
temp[0] <<= 2;
|
||||
temp[0] += temp[3] + temp[6];
|
||||
|
||||
red = ((int(temp[0]) * 160) >> 17) + 4;
|
||||
if (red > 31) red = 31;
|
||||
|
||||
if (temp[2] < temp[5]) swap(temp[2], temp[5]);
|
||||
if (temp[2] < temp[8]) swap(temp[2], temp[8]);
|
||||
if (temp[5] < temp[8]) swap(temp[5], temp[8]);
|
||||
temp[5] <<= 1;
|
||||
temp[2] <<= 2;
|
||||
temp[2] += temp[5] + temp[8];
|
||||
|
||||
blue = ((int(temp[2]) * 160) >> 17) + 4;
|
||||
if (blue > 31) blue = 31;
|
||||
|
||||
if (temp[1] < temp[4]) swap(temp[1], temp[4]);
|
||||
if (temp[1] < temp[7]) swap(temp[1], temp[7]);
|
||||
if (temp[4] < temp[7]) swap(temp[4], temp[7]);
|
||||
temp[4] <<= 1;
|
||||
temp[1] <<= 2;
|
||||
temp[1] += temp[4] + temp[7];
|
||||
|
||||
green = ((int(temp[1]) * 160) >> 17) + 4;
|
||||
if (green > 31) green = 31;
|
||||
|
||||
pix = red << systemRedShift;
|
||||
pix += green << systemGreenShift;
|
||||
pix += blue << systemBlueShift;
|
||||
|
||||
*buf++ = pix;
|
||||
}
|
||||
}
|
||||
|
||||
void gbafilter_pal32(u32 * buf, int count)
|
||||
{
|
||||
short temp[3 * 3], s;
|
||||
unsigned pix;
|
||||
u8 red, green, blue;
|
||||
|
||||
while (count--)
|
||||
{
|
||||
pix = *buf;
|
||||
|
||||
s = curve[(pix >> systemGreenShift) & 0x1f];
|
||||
temp[3] = s * influence[3];
|
||||
temp[4] = s * influence[4];
|
||||
temp[5] = s * influence[5];
|
||||
|
||||
s = curve[(pix >> systemRedShift) & 0x1f];
|
||||
temp[0] = s * influence[0];
|
||||
temp[1] = s * influence[1];
|
||||
temp[2] = s * influence[2];
|
||||
|
||||
s = curve[(pix >> systemBlueShift) & 0x1f];
|
||||
temp[6] = s * influence[6];
|
||||
temp[7] = s * influence[7];
|
||||
temp[8] = s * influence[8];
|
||||
|
||||
if (temp[0] < temp[3]) swap(temp[0], temp[3]);
|
||||
if (temp[0] < temp[6]) swap(temp[0], temp[6]);
|
||||
if (temp[3] < temp[6]) swap(temp[3], temp[6]);
|
||||
temp[3] <<= 1;
|
||||
temp[0] <<= 2;
|
||||
temp[0] += temp[3] + temp[6];
|
||||
|
||||
//red = ((int(temp[0]) * 160) >> 17) + 4;
|
||||
red = ((int(temp[0]) * 160) >> 14) + 32;
|
||||
|
||||
if (temp[2] < temp[5]) swap(temp[2], temp[5]);
|
||||
if (temp[2] < temp[8]) swap(temp[2], temp[8]);
|
||||
if (temp[5] < temp[8]) swap(temp[5], temp[8]);
|
||||
temp[5] <<= 1;
|
||||
temp[2] <<= 2;
|
||||
temp[2] += temp[5] + temp[8];
|
||||
|
||||
//blue = ((int(temp[2]) * 160) >> 17) + 4;
|
||||
blue = ((int(temp[2]) * 160) >> 14) + 32;
|
||||
|
||||
if (temp[1] < temp[4]) swap(temp[1], temp[4]);
|
||||
if (temp[1] < temp[7]) swap(temp[1], temp[7]);
|
||||
if (temp[4] < temp[7]) swap(temp[4], temp[7]);
|
||||
temp[4] <<= 1;
|
||||
temp[1] <<= 2;
|
||||
temp[1] += temp[4] + temp[7];
|
||||
|
||||
//green = ((int(temp[1]) * 160) >> 17) + 4;
|
||||
green = ((int(temp[1]) * 160) >> 14) + 32;
|
||||
|
||||
//pix = red << redshift;
|
||||
//pix += green << greenshift;
|
||||
//pix += blue << blueshift;
|
||||
|
||||
pix = red << (systemRedShift - 3);
|
||||
pix += green << (systemGreenShift - 3);
|
||||
pix += blue << (systemBlueShift - 3);
|
||||
|
||||
*buf++ = pix;
|
||||
}
|
||||
}
|
||||
|
||||
// for palette mode to work with the three spoony filters in 32bpp depth
|
||||
|
||||
void gbafilter_pad(u8 * buf, int count)
|
||||
{
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
u8 r;
|
||||
u8 g;
|
||||
u8 b;
|
||||
u8 a;
|
||||
} part;
|
||||
unsigned whole;
|
||||
}
|
||||
mask;
|
||||
|
||||
mask.whole = 0x1f << systemRedShift;
|
||||
mask.whole += 0x1f << systemGreenShift;
|
||||
mask.whole += 0x1f << systemBlueShift;
|
||||
|
||||
switch (systemColorDepth)
|
||||
{
|
||||
case 24:
|
||||
while (count--)
|
||||
{
|
||||
*buf++ &= mask.part.r;
|
||||
*buf++ &= mask.part.g;
|
||||
*buf++ &= mask.part.b;
|
||||
}
|
||||
break;
|
||||
case 32:
|
||||
while (count--)
|
||||
{
|
||||
*((u32*)buf) &= mask.whole;
|
||||
buf += 4;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
void UpdateSystemColorMaps(int lcd)
|
||||
{
|
||||
switch(systemColorDepth) {
|
||||
case 16:
|
||||
{
|
||||
for(int i = 0; i < 0x10000; i++) {
|
||||
systemColorMap16[i] = ((i & 0x1f) << systemRedShift) |
|
||||
(((i & 0x3e0) >> 5) << systemGreenShift) |
|
||||
(((i & 0x7c00) >> 10) << systemBlueShift);
|
||||
}
|
||||
if (lcd == 1) gbafilter_pal(systemColorMap16, 0x10000);
|
||||
}
|
||||
break;
|
||||
case 24:
|
||||
case 32:
|
||||
{
|
||||
for(int i = 0; i < 0x10000; i++) {
|
||||
systemColorMap32[i] = ((i & 0x1f) << systemRedShift) |
|
||||
(((i & 0x3e0) >> 5) << systemGreenShift) |
|
||||
(((i & 0x7c00) >> 10) << systemBlueShift);
|
||||
}
|
||||
if (lcd == 1) gbafilter_pal32(systemColorMap32, 0x10000);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
*/
|
||||
#include "gbafilter.h"
|
||||
|
||||
#include <math.h>
|
||||
|
||||
extern int systemColorDepth;
|
||||
extern int systemRedShift;
|
||||
extern int systemGreenShift;
|
||||
extern int systemBlueShift;
|
||||
|
||||
extern u16 systemColorMap16[0x10000];
|
||||
extern u32 systemColorMap32[0x10000];
|
||||
|
||||
static const unsigned char curve[32] = { 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0e, 0x10, 0x12,
|
||||
0x14, 0x16, 0x18, 0x1c, 0x20, 0x28, 0x30, 0x38,
|
||||
0x40, 0x48, 0x50, 0x58, 0x60, 0x68, 0x70, 0x80,
|
||||
0x88, 0x90, 0xa0, 0xb0, 0xc0, 0xd0, 0xe0, 0xf0};
|
||||
|
||||
// output R G B
|
||||
static const unsigned char influence[3 * 3] = { 16, 4, 4, // red
|
||||
8, 16, 8, // green
|
||||
0, 8, 16};// blue
|
||||
|
||||
inline void swap(short & a, short & b)
|
||||
{
|
||||
short temp = a;
|
||||
a = b;
|
||||
b = temp;
|
||||
}
|
||||
|
||||
void gbafilter_pal(u16 * buf, int count)
|
||||
{
|
||||
short temp[3 * 3], s;
|
||||
unsigned pix;
|
||||
u8 red, green, blue;
|
||||
|
||||
while (count--)
|
||||
{
|
||||
pix = *buf;
|
||||
|
||||
s = curve[(pix >> systemGreenShift) & 0x1f];
|
||||
temp[3] = s * influence[3];
|
||||
temp[4] = s * influence[4];
|
||||
temp[5] = s * influence[5];
|
||||
|
||||
s = curve[(pix >> systemRedShift) & 0x1f];
|
||||
temp[0] = s * influence[0];
|
||||
temp[1] = s * influence[1];
|
||||
temp[2] = s * influence[2];
|
||||
|
||||
s = curve[(pix >> systemBlueShift) & 0x1f];
|
||||
temp[6] = s * influence[6];
|
||||
temp[7] = s * influence[7];
|
||||
temp[8] = s * influence[8];
|
||||
|
||||
if (temp[0] < temp[3]) swap(temp[0], temp[3]);
|
||||
if (temp[0] < temp[6]) swap(temp[0], temp[6]);
|
||||
if (temp[3] < temp[6]) swap(temp[3], temp[6]);
|
||||
temp[3] <<= 1;
|
||||
temp[0] <<= 2;
|
||||
temp[0] += temp[3] + temp[6];
|
||||
|
||||
red = ((int(temp[0]) * 160) >> 17) + 4;
|
||||
if (red > 31) red = 31;
|
||||
|
||||
if (temp[2] < temp[5]) swap(temp[2], temp[5]);
|
||||
if (temp[2] < temp[8]) swap(temp[2], temp[8]);
|
||||
if (temp[5] < temp[8]) swap(temp[5], temp[8]);
|
||||
temp[5] <<= 1;
|
||||
temp[2] <<= 2;
|
||||
temp[2] += temp[5] + temp[8];
|
||||
|
||||
blue = ((int(temp[2]) * 160) >> 17) + 4;
|
||||
if (blue > 31) blue = 31;
|
||||
|
||||
if (temp[1] < temp[4]) swap(temp[1], temp[4]);
|
||||
if (temp[1] < temp[7]) swap(temp[1], temp[7]);
|
||||
if (temp[4] < temp[7]) swap(temp[4], temp[7]);
|
||||
temp[4] <<= 1;
|
||||
temp[1] <<= 2;
|
||||
temp[1] += temp[4] + temp[7];
|
||||
|
||||
green = ((int(temp[1]) * 160) >> 17) + 4;
|
||||
if (green > 31) green = 31;
|
||||
|
||||
pix = red << systemRedShift;
|
||||
pix += green << systemGreenShift;
|
||||
pix += blue << systemBlueShift;
|
||||
|
||||
*buf++ = pix;
|
||||
}
|
||||
}
|
||||
|
||||
void gbafilter_pal32(u32 * buf, int count)
|
||||
{
|
||||
short temp[3 * 3], s;
|
||||
unsigned pix;
|
||||
u8 red, green, blue;
|
||||
|
||||
while (count--)
|
||||
{
|
||||
pix = *buf;
|
||||
|
||||
s = curve[(pix >> systemGreenShift) & 0x1f];
|
||||
temp[3] = s * influence[3];
|
||||
temp[4] = s * influence[4];
|
||||
temp[5] = s * influence[5];
|
||||
|
||||
s = curve[(pix >> systemRedShift) & 0x1f];
|
||||
temp[0] = s * influence[0];
|
||||
temp[1] = s * influence[1];
|
||||
temp[2] = s * influence[2];
|
||||
|
||||
s = curve[(pix >> systemBlueShift) & 0x1f];
|
||||
temp[6] = s * influence[6];
|
||||
temp[7] = s * influence[7];
|
||||
temp[8] = s * influence[8];
|
||||
|
||||
if (temp[0] < temp[3]) swap(temp[0], temp[3]);
|
||||
if (temp[0] < temp[6]) swap(temp[0], temp[6]);
|
||||
if (temp[3] < temp[6]) swap(temp[3], temp[6]);
|
||||
temp[3] <<= 1;
|
||||
temp[0] <<= 2;
|
||||
temp[0] += temp[3] + temp[6];
|
||||
|
||||
//red = ((int(temp[0]) * 160) >> 17) + 4;
|
||||
red = ((int(temp[0]) * 160) >> 14) + 32;
|
||||
|
||||
if (temp[2] < temp[5]) swap(temp[2], temp[5]);
|
||||
if (temp[2] < temp[8]) swap(temp[2], temp[8]);
|
||||
if (temp[5] < temp[8]) swap(temp[5], temp[8]);
|
||||
temp[5] <<= 1;
|
||||
temp[2] <<= 2;
|
||||
temp[2] += temp[5] + temp[8];
|
||||
|
||||
//blue = ((int(temp[2]) * 160) >> 17) + 4;
|
||||
blue = ((int(temp[2]) * 160) >> 14) + 32;
|
||||
|
||||
if (temp[1] < temp[4]) swap(temp[1], temp[4]);
|
||||
if (temp[1] < temp[7]) swap(temp[1], temp[7]);
|
||||
if (temp[4] < temp[7]) swap(temp[4], temp[7]);
|
||||
temp[4] <<= 1;
|
||||
temp[1] <<= 2;
|
||||
temp[1] += temp[4] + temp[7];
|
||||
|
||||
//green = ((int(temp[1]) * 160) >> 17) + 4;
|
||||
green = ((int(temp[1]) * 160) >> 14) + 32;
|
||||
|
||||
//pix = red << redshift;
|
||||
//pix += green << greenshift;
|
||||
//pix += blue << blueshift;
|
||||
|
||||
pix = red << (systemRedShift - 3);
|
||||
pix += green << (systemGreenShift - 3);
|
||||
pix += blue << (systemBlueShift - 3);
|
||||
|
||||
*buf++ = pix;
|
||||
}
|
||||
}
|
||||
|
||||
// for palette mode to work with the three spoony filters in 32bpp depth
|
||||
|
||||
void gbafilter_pad(u8 * buf, int count)
|
||||
{
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
u8 r;
|
||||
u8 g;
|
||||
u8 b;
|
||||
u8 a;
|
||||
} part;
|
||||
unsigned whole;
|
||||
}
|
||||
mask;
|
||||
|
||||
mask.whole = 0x1f << systemRedShift;
|
||||
mask.whole += 0x1f << systemGreenShift;
|
||||
mask.whole += 0x1f << systemBlueShift;
|
||||
|
||||
switch (systemColorDepth)
|
||||
{
|
||||
case 24:
|
||||
while (count--)
|
||||
{
|
||||
*buf++ &= mask.part.r;
|
||||
*buf++ &= mask.part.g;
|
||||
*buf++ &= mask.part.b;
|
||||
}
|
||||
break;
|
||||
case 32:
|
||||
while (count--)
|
||||
{
|
||||
*((u32*)buf) &= mask.whole;
|
||||
buf += 4;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
void UpdateSystemColorMaps(int lcd)
|
||||
{
|
||||
switch(systemColorDepth) {
|
||||
case 16:
|
||||
{
|
||||
for(int i = 0; i < 0x10000; i++) {
|
||||
systemColorMap16[i] = ((i & 0x1f) << systemRedShift) |
|
||||
(((i & 0x3e0) >> 5) << systemGreenShift) |
|
||||
(((i & 0x7c00) >> 10) << systemBlueShift);
|
||||
}
|
||||
if (lcd == 1) gbafilter_pal(systemColorMap16, 0x10000);
|
||||
}
|
||||
break;
|
||||
case 24:
|
||||
case 32:
|
||||
{
|
||||
for(int i = 0; i < 0x10000; i++) {
|
||||
systemColorMap32[i] = ((i & 0x1f) << systemRedShift) |
|
||||
(((i & 0x3e0) >> 5) << systemGreenShift) |
|
||||
(((i & 0x7c00) >> 10) << systemBlueShift);
|
||||
}
|
||||
if (lcd == 1) gbafilter_pal32(systemColorMap32, 0x10000);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#include "../System.h"
|
||||
|
||||
void gbafilter_pal(u16 * buf, int count);
|
||||
void gbafilter_pal32(u32 * buf, int count);
|
||||
void gbafilter_pad(u8 * buf, int count);
|
||||
#include "../System.h"
|
||||
|
||||
void gbafilter_pal(u16 * buf, int count);
|
||||
void gbafilter_pal32(u32 * buf, int count);
|
||||
void gbafilter_pad(u8 * buf, int count);
|
||||
|
|
10898
src/dmg/GB.cpp
10898
src/dmg/GB.cpp
File diff suppressed because it is too large
Load Diff
128
src/dmg/gb.h
128
src/dmg/gb.h
|
@ -1,64 +1,64 @@
|
|||
// -*- C++ -*-
|
||||
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
|
||||
// Copyright (C) 1999-2003 Forgotten
|
||||
// Copyright (C) 2005-2006 Forgotten and the VBA development team
|
||||
|
||||
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
#ifndef VBA_GB_GB_H
|
||||
#define VBA_GB_GB_H
|
||||
|
||||
#define C_FLAG 0x10
|
||||
#define H_FLAG 0x20
|
||||
#define N_FLAG 0x40
|
||||
#define Z_FLAG 0x80
|
||||
|
||||
typedef union {
|
||||
struct {
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
u8 B1, B0;
|
||||
#else
|
||||
u8 B0,B1;
|
||||
#endif
|
||||
} B;
|
||||
u16 W;
|
||||
} gbRegister;
|
||||
|
||||
extern bool gbLoadRom(const char *);
|
||||
extern void gbEmulate(int);
|
||||
extern void gbWriteMemory(register u16, register u8);
|
||||
extern void gbDrawLine();
|
||||
extern bool gbIsGameboyRom(const char *);
|
||||
extern void gbSoundReset();
|
||||
extern void gbSoundSetQuality(int);
|
||||
extern void gbGetHardwareType();
|
||||
extern void gbReset();
|
||||
extern void gbCleanUp();
|
||||
extern void gbCPUInit(const char *,bool);
|
||||
extern bool gbWriteBatteryFile(const char *);
|
||||
extern bool gbWriteBatteryFile(const char *, bool);
|
||||
extern bool gbReadBatteryFile(const char *);
|
||||
extern bool gbWriteSaveState(const char *);
|
||||
extern bool gbWriteMemSaveState(char *, int);
|
||||
extern bool gbReadSaveState(const char *);
|
||||
extern bool gbReadMemSaveState(char *, int);
|
||||
extern void gbSgbRenderBorder();
|
||||
extern bool gbWritePNGFile(const char *);
|
||||
extern bool gbWriteBMPFile(const char *);
|
||||
extern bool gbReadGSASnapshot(const char *);
|
||||
|
||||
extern struct EmulatedSystem GBSystem;
|
||||
|
||||
#endif
|
||||
// -*- C++ -*-
|
||||
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
|
||||
// Copyright (C) 1999-2003 Forgotten
|
||||
// Copyright (C) 2005-2006 Forgotten and the VBA development team
|
||||
|
||||
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
#ifndef VBA_GB_GB_H
|
||||
#define VBA_GB_GB_H
|
||||
|
||||
#define C_FLAG 0x10
|
||||
#define H_FLAG 0x20
|
||||
#define N_FLAG 0x40
|
||||
#define Z_FLAG 0x80
|
||||
|
||||
typedef union {
|
||||
struct {
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
u8 B1, B0;
|
||||
#else
|
||||
u8 B0,B1;
|
||||
#endif
|
||||
} B;
|
||||
u16 W;
|
||||
} gbRegister;
|
||||
|
||||
extern bool gbLoadRom(const char *);
|
||||
extern void gbEmulate(int);
|
||||
extern void gbWriteMemory(register u16, register u8);
|
||||
extern void gbDrawLine();
|
||||
extern bool gbIsGameboyRom(const char *);
|
||||
extern void gbSoundReset();
|
||||
extern void gbSoundSetQuality(int);
|
||||
extern void gbGetHardwareType();
|
||||
extern void gbReset();
|
||||
extern void gbCleanUp();
|
||||
extern void gbCPUInit(const char *,bool);
|
||||
extern bool gbWriteBatteryFile(const char *);
|
||||
extern bool gbWriteBatteryFile(const char *, bool);
|
||||
extern bool gbReadBatteryFile(const char *);
|
||||
extern bool gbWriteSaveState(const char *);
|
||||
extern bool gbWriteMemSaveState(char *, int);
|
||||
extern bool gbReadSaveState(const char *);
|
||||
extern bool gbReadMemSaveState(char *, int);
|
||||
extern void gbSgbRenderBorder();
|
||||
extern bool gbWritePNGFile(const char *);
|
||||
extern bool gbWriteBMPFile(const char *);
|
||||
extern bool gbReadGSASnapshot(const char *);
|
||||
|
||||
extern struct EmulatedSystem GBSystem;
|
||||
|
||||
#endif
|
||||
|
|
1044
src/dmg/gbCheats.cpp
1044
src/dmg/gbCheats.cpp
File diff suppressed because it is too large
Load Diff
|
@ -1,62 +1,62 @@
|
|||
// -*- C++ -*-
|
||||
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
|
||||
// Copyright (C) 1999-2003 Forgotten
|
||||
// Copyright (C) 2004 Forgotten and the VBA development team
|
||||
|
||||
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
#ifndef __VBA_GB_GBCHEATS_H
|
||||
#define __VBA_GB_GBCHEATS_H
|
||||
|
||||
#include "../System.h"
|
||||
|
||||
struct gbXxCheat {
|
||||
char cheatDesc[100];
|
||||
char cheatCode[20];
|
||||
};
|
||||
|
||||
struct gbCheat {
|
||||
char cheatCode[20];
|
||||
char cheatDesc[32];
|
||||
u16 address;
|
||||
int code;
|
||||
u8 compare;
|
||||
u8 value;
|
||||
bool enabled;
|
||||
};
|
||||
|
||||
void gbCheatsSaveGame(gzFile);
|
||||
void gbCheatsReadGame(gzFile, int);
|
||||
void gbCheatsSaveCheatList(const char *);
|
||||
bool gbCheatsLoadCheatList(const char *);
|
||||
bool gbCheatReadGSCodeFile(const char *);
|
||||
|
||||
bool gbAddGsCheat(const char *, const char*);
|
||||
bool gbAddGgCheat(const char *, const char*);
|
||||
void gbCheatRemove(int);
|
||||
void gbCheatRemoveAll();
|
||||
void gbCheatEnable(int);
|
||||
void gbCheatDisable(int);
|
||||
u8 gbCheatRead(u16);
|
||||
void gbCheatWrite(bool);
|
||||
bool gbVerifyGsCode(const char *code);
|
||||
bool gbVerifyGgCode(const char *code);
|
||||
|
||||
|
||||
extern int gbCheatNumber;
|
||||
extern gbCheat gbCheatList[100];
|
||||
extern bool gbCheatMap[0x10000];
|
||||
#endif
|
||||
|
||||
// -*- C++ -*-
|
||||
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
|
||||
// Copyright (C) 1999-2003 Forgotten
|
||||
// Copyright (C) 2004 Forgotten and the VBA development team
|
||||
|
||||
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
#ifndef __VBA_GB_GBCHEATS_H
|
||||
#define __VBA_GB_GBCHEATS_H
|
||||
|
||||
#include "../System.h"
|
||||
|
||||
struct gbXxCheat {
|
||||
char cheatDesc[100];
|
||||
char cheatCode[20];
|
||||
};
|
||||
|
||||
struct gbCheat {
|
||||
char cheatCode[20];
|
||||
char cheatDesc[32];
|
||||
u16 address;
|
||||
int code;
|
||||
u8 compare;
|
||||
u8 value;
|
||||
bool enabled;
|
||||
};
|
||||
|
||||
void gbCheatsSaveGame(gzFile);
|
||||
void gbCheatsReadGame(gzFile, int);
|
||||
void gbCheatsSaveCheatList(const char *);
|
||||
bool gbCheatsLoadCheatList(const char *);
|
||||
bool gbCheatReadGSCodeFile(const char *);
|
||||
|
||||
bool gbAddGsCheat(const char *, const char*);
|
||||
bool gbAddGgCheat(const char *, const char*);
|
||||
void gbCheatRemove(int);
|
||||
void gbCheatRemoveAll();
|
||||
void gbCheatEnable(int);
|
||||
void gbCheatDisable(int);
|
||||
u8 gbCheatRead(u16);
|
||||
void gbCheatWrite(bool);
|
||||
bool gbVerifyGsCode(const char *code);
|
||||
bool gbVerifyGgCode(const char *code);
|
||||
|
||||
|
||||
extern int gbCheatNumber;
|
||||
extern gbCheat gbCheatList[100];
|
||||
extern bool gbCheatMap[0x10000];
|
||||
#endif
|
||||
|
||||
|
|
2920
src/dmg/gbCodes.h
2920
src/dmg/gbCodes.h
File diff suppressed because it is too large
Load Diff
2582
src/dmg/gbCodesCB.h
2582
src/dmg/gbCodesCB.h
File diff suppressed because it is too large
Load Diff
|
@ -1,249 +1,249 @@
|
|||
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
|
||||
// Copyright (C) 1999-2003 Forgotten
|
||||
// Copyright (C) 2004 Forgotten and the VBA development team
|
||||
|
||||
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "../System.h"
|
||||
#include "gbGlobals.h"
|
||||
|
||||
typedef struct {
|
||||
u8 mask;
|
||||
u8 value;
|
||||
const char *mnen;
|
||||
} GBOPCODE;
|
||||
|
||||
#define GB_READ(x) gbMemoryMap[(x)>>12][(x)&0xfff]
|
||||
|
||||
static const char *registers[] =
|
||||
{ "B", "C", "D", "E", "H", "L", "(HL)", "A" };
|
||||
|
||||
static const char *registers16[] =
|
||||
{ "BC", "DE", "HL", "SP", // for some operations
|
||||
"BC", "DE", "HL", "AF" }; // for push/pop
|
||||
|
||||
static const char *cond[] =
|
||||
{ "NZ", "Z", "NC", "C" };
|
||||
|
||||
static char hexDigits[16] = {
|
||||
'0', '1', '2', '3', '4', '5', '6', '7',
|
||||
'8', '9', 'A', 'B', 'C', 'D', 'E', 'F'
|
||||
};
|
||||
|
||||
static GBOPCODE opcodes[] = {
|
||||
{ 0xff, 0x00, "NOP" },
|
||||
{ 0xcf, 0x01, "LD %R4,%W" },
|
||||
{ 0xff, 0x02, "LD (BC),A" },
|
||||
{ 0xcf, 0x03, "INC %R4" },
|
||||
{ 0xc7, 0x04, "INC %r3" },
|
||||
{ 0xc7, 0x05, "DEC %r3" },
|
||||
{ 0xc7, 0x06, "LD %r3,%B" },
|
||||
{ 0xff, 0x07, "RLCA" },
|
||||
{ 0xff, 0x08, "LD (%W),SP" },
|
||||
{ 0xcf, 0x09, "ADD HL,%R4" },
|
||||
{ 0xff, 0x0a, "LD A,(BC)" },
|
||||
{ 0xcf, 0x0b, "DEC %R4" },
|
||||
{ 0xff, 0x0f, "RRCA" },
|
||||
{ 0xff, 0x10, "STOP" },
|
||||
{ 0xff, 0x12, "LD (DE),A" },
|
||||
{ 0xff, 0x17, "RLA" },
|
||||
{ 0xff, 0x18, "JR %d" },
|
||||
{ 0xff, 0x1a, "LD A,(DE)" },
|
||||
{ 0xff, 0x1f, "RRA" },
|
||||
{ 0xe7, 0x20, "JR %c3,%d" },
|
||||
{ 0xff, 0x22, "LDI (HL),A" },
|
||||
{ 0xff, 0x27, "DAA" },
|
||||
{ 0xff, 0x2a, "LDI A,(HL)" },
|
||||
{ 0xff, 0x2f, "CPL" },
|
||||
{ 0xff, 0x32, "LDD (HL),A" },
|
||||
{ 0xff, 0x37, "SCF" },
|
||||
{ 0xff, 0x3a, "LDD A,(HL)" },
|
||||
{ 0xff, 0x3f, "CCF" },
|
||||
{ 0xff, 0x76, "HALT" },
|
||||
{ 0xc0, 0x40, "LD %r3,%r0" },
|
||||
{ 0xf8, 0x80, "ADD A,%r0" },
|
||||
{ 0xf8, 0x88, "ADC A,%r0" },
|
||||
{ 0xf8, 0x90, "SUB %r0" },
|
||||
{ 0xf8, 0x98, "SBC A,%r0" },
|
||||
{ 0xf8, 0xa0, "AND %r0" },
|
||||
{ 0xf8, 0xa8, "XOR %r0" },
|
||||
{ 0xf8, 0xb0, "OR %r0" },
|
||||
{ 0xf8, 0xb8, "CP %r0" },
|
||||
{ 0xe7, 0xc0, "RET %c3" },
|
||||
{ 0xcf, 0xc1, "POP %t4" },
|
||||
{ 0xe7, 0xc2, "JP %c3,%W" },
|
||||
{ 0xff, 0xc3, "JP %W" },
|
||||
{ 0xe7, 0xc4, "CALL %c3,%W" },
|
||||
{ 0xcf, 0xc5, "PUSH %t4" },
|
||||
{ 0xff, 0xc6, "ADD A,%B" },
|
||||
{ 0xc7, 0xc7, "RST %P" },
|
||||
{ 0xff, 0xc9, "RET" },
|
||||
{ 0xff, 0xcd, "CALL %W" },
|
||||
{ 0xff, 0xce, "ADC %B" },
|
||||
{ 0xff, 0xd6, "SUB %B" },
|
||||
{ 0xff, 0xd9, "RETI" },
|
||||
{ 0xff, 0xde, "SBC %B" },
|
||||
{ 0xff, 0xe0, "LD (FF%B),A" },
|
||||
{ 0xff, 0xe2, "LD (FF00h+C),A" },
|
||||
{ 0xff, 0xe6, "AND %B" },
|
||||
{ 0xff, 0xe8, "ADD SP,%D" },
|
||||
{ 0xff, 0xe9, "LD PC,HL" },
|
||||
{ 0xff, 0xea, "LD (%W),A" },
|
||||
{ 0xff, 0xee, "XOR %B" },
|
||||
{ 0xff, 0xf0, "LD A,(FF%B)" },
|
||||
{ 0xff, 0xf2, "LD A,(FF00h+C)" },
|
||||
{ 0xff, 0xf3, "DI" },
|
||||
{ 0xff, 0xf6, "OR %B" },
|
||||
{ 0xff, 0xf8, "LD HL,SP%D" },
|
||||
{ 0xff, 0xf9, "LD SP,HL" },
|
||||
{ 0xff, 0xfa, "LD A,(%W)" },
|
||||
{ 0xff, 0xfb, "EI" },
|
||||
{ 0xff, 0xfe, "CP %B" },
|
||||
{ 0x00, 0x00, "DB %B" }
|
||||
};
|
||||
|
||||
static GBOPCODE cbOpcodes[] = {
|
||||
{ 0xf8, 0x00, "RLC %r0" },
|
||||
{ 0xf8, 0x08, "RRC %r0" },
|
||||
{ 0xf8, 0x10, "RL %r0" },
|
||||
{ 0xf8, 0x18, "RR %r0" },
|
||||
{ 0xf8, 0x20, "SLA %r0" },
|
||||
{ 0xf8, 0x28, "SRA %r0" },
|
||||
{ 0xf8, 0x30, "SWAP %r0" },
|
||||
{ 0xf8, 0x38, "SRL %r0" },
|
||||
{ 0xc0, 0x40, "BIT %b,%r0" },
|
||||
{ 0xc0, 0x80, "RES %b,%r0" },
|
||||
{ 0xc0, 0xc0, "SET %b,%r0" },
|
||||
{ 0x00, 0x00, "DB CBh,%B" }
|
||||
};
|
||||
|
||||
static char *addHex(char *p, u8 value)
|
||||
{
|
||||
*p++ = hexDigits[value >> 4];
|
||||
*p++ = hexDigits[value & 15];
|
||||
return p;
|
||||
}
|
||||
|
||||
static char *addHex16(char *p, u16 value)
|
||||
{
|
||||
p = addHex(p, value>>8);
|
||||
return addHex(p, value & 255);
|
||||
}
|
||||
|
||||
static char *addStr(char *p, const char *s)
|
||||
{
|
||||
while(*s) {
|
||||
*p++ = *s++;
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
int gbDis(char *buffer, u16 address)
|
||||
{
|
||||
char *p = buffer;
|
||||
int instr = 1;
|
||||
u16 addr = address;
|
||||
sprintf(p, "%04x ", address);
|
||||
p += 12;
|
||||
|
||||
u8 opcode = GB_READ(address);
|
||||
address++;
|
||||
const char *mnen;
|
||||
GBOPCODE *op;
|
||||
if(opcode == 0xcb) {
|
||||
opcode = GB_READ(address);
|
||||
address++;
|
||||
instr++;
|
||||
op = cbOpcodes;
|
||||
} else {
|
||||
op = opcodes;
|
||||
}
|
||||
while(op->value != (opcode & op->mask)) op++;
|
||||
mnen = op->mnen;
|
||||
|
||||
u8 b0, b1;
|
||||
s8 disp;
|
||||
int shift;
|
||||
|
||||
while(*mnen) {
|
||||
if(*mnen == '%') {
|
||||
mnen++;
|
||||
switch(*mnen++) {
|
||||
case 'W':
|
||||
b0 = GB_READ(address);
|
||||
address++;
|
||||
b1 = GB_READ(address);
|
||||
address++;
|
||||
p = addHex16(p, b0|b1<<8);
|
||||
instr += 2;
|
||||
*p++ = 'h';
|
||||
break;
|
||||
case 'B':
|
||||
p = addHex(p, GB_READ(address));
|
||||
*p++ = 'h';
|
||||
address++;
|
||||
instr++;
|
||||
break;
|
||||
case 'D':
|
||||
disp = GB_READ(address);
|
||||
if(disp >= 0)
|
||||
*p++ = '+';
|
||||
p += sprintf(p, "%d", disp);
|
||||
instr++;
|
||||
break;
|
||||
case 'd':
|
||||
disp = GB_READ(address);
|
||||
address++;
|
||||
p = addHex16(p, address+disp);
|
||||
*p++ = 'h';
|
||||
instr++;
|
||||
break;
|
||||
case 'b':
|
||||
// kind of a hack, but it works :-)
|
||||
*p++ = hexDigits[(opcode >> 3) & 7];
|
||||
break;
|
||||
case 'r':
|
||||
shift = *mnen++ - '0';
|
||||
p = addStr(p, registers[(opcode >> shift) & 7]);
|
||||
break;
|
||||
case 'R':
|
||||
shift = *mnen++ - '0';
|
||||
p = addStr(p, registers16[(opcode >> shift) & 3]);
|
||||
break;
|
||||
case 't':
|
||||
shift = *mnen++ - '0';
|
||||
p = addStr(p, registers16[4+((opcode >> shift) & 3)]);
|
||||
break;
|
||||
case 'P':
|
||||
p = addHex(p, ((opcode >> 3) & 7) * 8);
|
||||
break;
|
||||
case 'c':
|
||||
shift = *mnen++ - '0';
|
||||
p = addStr(p, cond[(opcode >> shift) & 3]);
|
||||
break;
|
||||
}
|
||||
} else
|
||||
*p++ = *mnen++;
|
||||
}
|
||||
for(int i = 0; i < instr; i++) {
|
||||
u16 a = addr + i;
|
||||
addHex(buffer+5+i*2, GB_READ(a));
|
||||
}
|
||||
*p = 0;
|
||||
return instr;
|
||||
}
|
||||
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
|
||||
// Copyright (C) 1999-2003 Forgotten
|
||||
// Copyright (C) 2004 Forgotten and the VBA development team
|
||||
|
||||
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "../System.h"
|
||||
#include "gbGlobals.h"
|
||||
|
||||
typedef struct {
|
||||
u8 mask;
|
||||
u8 value;
|
||||
const char *mnen;
|
||||
} GBOPCODE;
|
||||
|
||||
#define GB_READ(x) gbMemoryMap[(x)>>12][(x)&0xfff]
|
||||
|
||||
static const char *registers[] =
|
||||
{ "B", "C", "D", "E", "H", "L", "(HL)", "A" };
|
||||
|
||||
static const char *registers16[] =
|
||||
{ "BC", "DE", "HL", "SP", // for some operations
|
||||
"BC", "DE", "HL", "AF" }; // for push/pop
|
||||
|
||||
static const char *cond[] =
|
||||
{ "NZ", "Z", "NC", "C" };
|
||||
|
||||
static char hexDigits[16] = {
|
||||
'0', '1', '2', '3', '4', '5', '6', '7',
|
||||
'8', '9', 'A', 'B', 'C', 'D', 'E', 'F'
|
||||
};
|
||||
|
||||
static GBOPCODE opcodes[] = {
|
||||
{ 0xff, 0x00, "NOP" },
|
||||
{ 0xcf, 0x01, "LD %R4,%W" },
|
||||
{ 0xff, 0x02, "LD (BC),A" },
|
||||
{ 0xcf, 0x03, "INC %R4" },
|
||||
{ 0xc7, 0x04, "INC %r3" },
|
||||
{ 0xc7, 0x05, "DEC %r3" },
|
||||
{ 0xc7, 0x06, "LD %r3,%B" },
|
||||
{ 0xff, 0x07, "RLCA" },
|
||||
{ 0xff, 0x08, "LD (%W),SP" },
|
||||
{ 0xcf, 0x09, "ADD HL,%R4" },
|
||||
{ 0xff, 0x0a, "LD A,(BC)" },
|
||||
{ 0xcf, 0x0b, "DEC %R4" },
|
||||
{ 0xff, 0x0f, "RRCA" },
|
||||
{ 0xff, 0x10, "STOP" },
|
||||
{ 0xff, 0x12, "LD (DE),A" },
|
||||
{ 0xff, 0x17, "RLA" },
|
||||
{ 0xff, 0x18, "JR %d" },
|
||||
{ 0xff, 0x1a, "LD A,(DE)" },
|
||||
{ 0xff, 0x1f, "RRA" },
|
||||
{ 0xe7, 0x20, "JR %c3,%d" },
|
||||
{ 0xff, 0x22, "LDI (HL),A" },
|
||||
{ 0xff, 0x27, "DAA" },
|
||||
{ 0xff, 0x2a, "LDI A,(HL)" },
|
||||
{ 0xff, 0x2f, "CPL" },
|
||||
{ 0xff, 0x32, "LDD (HL),A" },
|
||||
{ 0xff, 0x37, "SCF" },
|
||||
{ 0xff, 0x3a, "LDD A,(HL)" },
|
||||
{ 0xff, 0x3f, "CCF" },
|
||||
{ 0xff, 0x76, "HALT" },
|
||||
{ 0xc0, 0x40, "LD %r3,%r0" },
|
||||
{ 0xf8, 0x80, "ADD A,%r0" },
|
||||
{ 0xf8, 0x88, "ADC A,%r0" },
|
||||
{ 0xf8, 0x90, "SUB %r0" },
|
||||
{ 0xf8, 0x98, "SBC A,%r0" },
|
||||
{ 0xf8, 0xa0, "AND %r0" },
|
||||
{ 0xf8, 0xa8, "XOR %r0" },
|
||||
{ 0xf8, 0xb0, "OR %r0" },
|
||||
{ 0xf8, 0xb8, "CP %r0" },
|
||||
{ 0xe7, 0xc0, "RET %c3" },
|
||||
{ 0xcf, 0xc1, "POP %t4" },
|
||||
{ 0xe7, 0xc2, "JP %c3,%W" },
|
||||
{ 0xff, 0xc3, "JP %W" },
|
||||
{ 0xe7, 0xc4, "CALL %c3,%W" },
|
||||
{ 0xcf, 0xc5, "PUSH %t4" },
|
||||
{ 0xff, 0xc6, "ADD A,%B" },
|
||||
{ 0xc7, 0xc7, "RST %P" },
|
||||
{ 0xff, 0xc9, "RET" },
|
||||
{ 0xff, 0xcd, "CALL %W" },
|
||||
{ 0xff, 0xce, "ADC %B" },
|
||||
{ 0xff, 0xd6, "SUB %B" },
|
||||
{ 0xff, 0xd9, "RETI" },
|
||||
{ 0xff, 0xde, "SBC %B" },
|
||||
{ 0xff, 0xe0, "LD (FF%B),A" },
|
||||
{ 0xff, 0xe2, "LD (FF00h+C),A" },
|
||||
{ 0xff, 0xe6, "AND %B" },
|
||||
{ 0xff, 0xe8, "ADD SP,%D" },
|
||||
{ 0xff, 0xe9, "LD PC,HL" },
|
||||
{ 0xff, 0xea, "LD (%W),A" },
|
||||
{ 0xff, 0xee, "XOR %B" },
|
||||
{ 0xff, 0xf0, "LD A,(FF%B)" },
|
||||
{ 0xff, 0xf2, "LD A,(FF00h+C)" },
|
||||
{ 0xff, 0xf3, "DI" },
|
||||
{ 0xff, 0xf6, "OR %B" },
|
||||
{ 0xff, 0xf8, "LD HL,SP%D" },
|
||||
{ 0xff, 0xf9, "LD SP,HL" },
|
||||
{ 0xff, 0xfa, "LD A,(%W)" },
|
||||
{ 0xff, 0xfb, "EI" },
|
||||
{ 0xff, 0xfe, "CP %B" },
|
||||
{ 0x00, 0x00, "DB %B" }
|
||||
};
|
||||
|
||||
static GBOPCODE cbOpcodes[] = {
|
||||
{ 0xf8, 0x00, "RLC %r0" },
|
||||
{ 0xf8, 0x08, "RRC %r0" },
|
||||
{ 0xf8, 0x10, "RL %r0" },
|
||||
{ 0xf8, 0x18, "RR %r0" },
|
||||
{ 0xf8, 0x20, "SLA %r0" },
|
||||
{ 0xf8, 0x28, "SRA %r0" },
|
||||
{ 0xf8, 0x30, "SWAP %r0" },
|
||||
{ 0xf8, 0x38, "SRL %r0" },
|
||||
{ 0xc0, 0x40, "BIT %b,%r0" },
|
||||
{ 0xc0, 0x80, "RES %b,%r0" },
|
||||
{ 0xc0, 0xc0, "SET %b,%r0" },
|
||||
{ 0x00, 0x00, "DB CBh,%B" }
|
||||
};
|
||||
|
||||
static char *addHex(char *p, u8 value)
|
||||
{
|
||||
*p++ = hexDigits[value >> 4];
|
||||
*p++ = hexDigits[value & 15];
|
||||
return p;
|
||||
}
|
||||
|
||||
static char *addHex16(char *p, u16 value)
|
||||
{
|
||||
p = addHex(p, value>>8);
|
||||
return addHex(p, value & 255);
|
||||
}
|
||||
|
||||
static char *addStr(char *p, const char *s)
|
||||
{
|
||||
while(*s) {
|
||||
*p++ = *s++;
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
int gbDis(char *buffer, u16 address)
|
||||
{
|
||||
char *p = buffer;
|
||||
int instr = 1;
|
||||
u16 addr = address;
|
||||
sprintf(p, "%04x ", address);
|
||||
p += 12;
|
||||
|
||||
u8 opcode = GB_READ(address);
|
||||
address++;
|
||||
const char *mnen;
|
||||
GBOPCODE *op;
|
||||
if(opcode == 0xcb) {
|
||||
opcode = GB_READ(address);
|
||||
address++;
|
||||
instr++;
|
||||
op = cbOpcodes;
|
||||
} else {
|
||||
op = opcodes;
|
||||
}
|
||||
while(op->value != (opcode & op->mask)) op++;
|
||||
mnen = op->mnen;
|
||||
|
||||
u8 b0, b1;
|
||||
s8 disp;
|
||||
int shift;
|
||||
|
||||
while(*mnen) {
|
||||
if(*mnen == '%') {
|
||||
mnen++;
|
||||
switch(*mnen++) {
|
||||
case 'W':
|
||||
b0 = GB_READ(address);
|
||||
address++;
|
||||
b1 = GB_READ(address);
|
||||
address++;
|
||||
p = addHex16(p, b0|b1<<8);
|
||||
instr += 2;
|
||||
*p++ = 'h';
|
||||
break;
|
||||
case 'B':
|
||||
p = addHex(p, GB_READ(address));
|
||||
*p++ = 'h';
|
||||
address++;
|
||||
instr++;
|
||||
break;
|
||||
case 'D':
|
||||
disp = GB_READ(address);
|
||||
if(disp >= 0)
|
||||
*p++ = '+';
|
||||
p += sprintf(p, "%d", disp);
|
||||
instr++;
|
||||
break;
|
||||
case 'd':
|
||||
disp = GB_READ(address);
|
||||
address++;
|
||||
p = addHex16(p, address+disp);
|
||||
*p++ = 'h';
|
||||
instr++;
|
||||
break;
|
||||
case 'b':
|
||||
// kind of a hack, but it works :-)
|
||||
*p++ = hexDigits[(opcode >> 3) & 7];
|
||||
break;
|
||||
case 'r':
|
||||
shift = *mnen++ - '0';
|
||||
p = addStr(p, registers[(opcode >> shift) & 7]);
|
||||
break;
|
||||
case 'R':
|
||||
shift = *mnen++ - '0';
|
||||
p = addStr(p, registers16[(opcode >> shift) & 3]);
|
||||
break;
|
||||
case 't':
|
||||
shift = *mnen++ - '0';
|
||||
p = addStr(p, registers16[4+((opcode >> shift) & 3)]);
|
||||
break;
|
||||
case 'P':
|
||||
p = addHex(p, ((opcode >> 3) & 7) * 8);
|
||||
break;
|
||||
case 'c':
|
||||
shift = *mnen++ - '0';
|
||||
p = addStr(p, cond[(opcode >> shift) & 3]);
|
||||
break;
|
||||
}
|
||||
} else
|
||||
*p++ = *mnen++;
|
||||
}
|
||||
for(int i = 0; i < instr; i++) {
|
||||
u16 a = addr + i;
|
||||
addHex(buffer+5+i*2, GB_READ(a));
|
||||
}
|
||||
*p = 0;
|
||||
return instr;
|
||||
}
|
||||
|
|
1202
src/dmg/gbGfx.cpp
1202
src/dmg/gbGfx.cpp
File diff suppressed because it is too large
Load Diff
|
@ -1,57 +1,57 @@
|
|||
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
|
||||
// Copyright (C) 1999-2003 Forgotten
|
||||
// Copyright (C) 2005-2006 Forgotten and the VBA development team
|
||||
|
||||
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
#include "../agb/GBA.h"
|
||||
|
||||
u8 *gbMemoryMap[16];
|
||||
|
||||
int gbRomSizeMask = 0;
|
||||
int gbRomSize = 0;
|
||||
int gbRamSizeMask = 0;
|
||||
int gbRamSize = 0;
|
||||
int gbTAMA5ramSize = 0;
|
||||
|
||||
u8 *gbMemory = NULL;
|
||||
u8 *gbVram = NULL;
|
||||
u8 *gbRom = NULL;
|
||||
u8 *gbRam = NULL;
|
||||
u8 *gbWram = NULL;
|
||||
u16 *gbLineBuffer = NULL;
|
||||
u8 *gbTAMA5ram = NULL;
|
||||
|
||||
u16 gbPalette[128];
|
||||
u8 gbBgp[4] = { 0, 1, 2, 3};
|
||||
u8 gbObp0[4] = { 0, 1, 2, 3};
|
||||
u8 gbObp1[4] = { 0, 1, 2, 3};
|
||||
int gbWindowLine = -1;
|
||||
|
||||
bool genericflashcardEnable = false;
|
||||
int gbCgbMode = 0;
|
||||
|
||||
u16 gbColorFilter[32768];
|
||||
int gbColorOption = 0;
|
||||
int gbPaletteOption = 0;
|
||||
int gbEmulatorType = 0;
|
||||
int gbBorderOn = 1;
|
||||
int gbBorderAutomatic = 0;
|
||||
int gbBorderLineSkip = 160;
|
||||
int gbBorderRowSkip = 0;
|
||||
int gbBorderColumnSkip = 0;
|
||||
int gbDmaTicks = 0;
|
||||
|
||||
u8 (*gbSerialFunction)(u8) = NULL;
|
||||
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
|
||||
// Copyright (C) 1999-2003 Forgotten
|
||||
// Copyright (C) 2005-2006 Forgotten and the VBA development team
|
||||
|
||||
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
#include "../agb/GBA.h"
|
||||
|
||||
u8 *gbMemoryMap[16];
|
||||
|
||||
int gbRomSizeMask = 0;
|
||||
int gbRomSize = 0;
|
||||
int gbRamSizeMask = 0;
|
||||
int gbRamSize = 0;
|
||||
int gbTAMA5ramSize = 0;
|
||||
|
||||
u8 *gbMemory = NULL;
|
||||
u8 *gbVram = NULL;
|
||||
u8 *gbRom = NULL;
|
||||
u8 *gbRam = NULL;
|
||||
u8 *gbWram = NULL;
|
||||
u16 *gbLineBuffer = NULL;
|
||||
u8 *gbTAMA5ram = NULL;
|
||||
|
||||
u16 gbPalette[128];
|
||||
u8 gbBgp[4] = { 0, 1, 2, 3};
|
||||
u8 gbObp0[4] = { 0, 1, 2, 3};
|
||||
u8 gbObp1[4] = { 0, 1, 2, 3};
|
||||
int gbWindowLine = -1;
|
||||
|
||||
bool genericflashcardEnable = false;
|
||||
int gbCgbMode = 0;
|
||||
|
||||
u16 gbColorFilter[32768];
|
||||
int gbColorOption = 0;
|
||||
int gbPaletteOption = 0;
|
||||
int gbEmulatorType = 0;
|
||||
int gbBorderOn = 1;
|
||||
int gbBorderAutomatic = 0;
|
||||
int gbBorderLineSkip = 160;
|
||||
int gbBorderRowSkip = 0;
|
||||
int gbBorderColumnSkip = 0;
|
||||
int gbDmaTicks = 0;
|
||||
|
||||
u8 (*gbSerialFunction)(u8) = NULL;
|
||||
|
|
|
@ -1,89 +1,89 @@
|
|||
// -*- C++ -*-
|
||||
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
|
||||
// Copyright (C) 1999-2003 Forgotten
|
||||
// Copyright (C) 2005-2006 Forgotten and the VBA development team
|
||||
|
||||
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
extern int gbRomSizeMask;
|
||||
extern int gbRomSize;
|
||||
extern int gbRamSize;
|
||||
extern int gbRamSizeMask;
|
||||
extern int gbTAMA5ramSize;
|
||||
|
||||
extern bool useBios;
|
||||
extern bool skipBios;
|
||||
extern u8 *bios;
|
||||
|
||||
extern u8 *gbRom;
|
||||
extern u8 *gbRam;
|
||||
extern u8 *gbVram;
|
||||
extern u8 *gbWram;
|
||||
extern u8 *gbMemory;
|
||||
extern u16 *gbLineBuffer;
|
||||
extern u8 *gbTAMA5ram;
|
||||
|
||||
extern u8 *gbMemoryMap[16];
|
||||
|
||||
extern int gbFrameSkip;
|
||||
extern u16 gbColorFilter[32768];
|
||||
extern int gbColorOption;
|
||||
extern int gbPaletteOption;
|
||||
extern int gbEmulatorType;
|
||||
extern int gbBorderOn;
|
||||
extern int gbBorderAutomatic;
|
||||
extern int gbCgbMode;
|
||||
extern int gbSgbMode;
|
||||
extern int gbWindowLine;
|
||||
extern int gbSpeed;
|
||||
extern u8 gbBgp[4];
|
||||
extern u8 gbObp0[4];
|
||||
extern u8 gbObp1[4];
|
||||
extern u16 gbPalette[128];
|
||||
extern bool gbScreenOn;
|
||||
extern bool gbDrawWindow;
|
||||
extern u8 gbSCYLine[300];
|
||||
// gbSCXLine is used for the emulation (bug) of the SX change
|
||||
// found in the Artic Zone game.
|
||||
extern u8 gbSCXLine[300];
|
||||
// gbBgpLine is used for the emulation of the
|
||||
// Prehistorik Man's title screen scroller.
|
||||
extern u8 gbBgpLine[300];
|
||||
extern u8 gbObp0Line [300];
|
||||
extern u8 gbObp1Line [300];
|
||||
// gbSpritesTicks is used for the emulation of Parodius' Laser Beam.
|
||||
extern u8 gbSpritesTicks[300];
|
||||
|
||||
extern u8 register_LCDC;
|
||||
extern u8 register_LY;
|
||||
extern u8 register_SCY;
|
||||
extern u8 register_SCX;
|
||||
extern u8 register_WY;
|
||||
extern u8 register_WX;
|
||||
extern u8 register_VBK;
|
||||
extern u8 oldRegister_WY;
|
||||
|
||||
extern int emulating;
|
||||
extern bool genericflashcardEnable;
|
||||
|
||||
extern int gbBorderLineSkip;
|
||||
extern int gbBorderRowSkip;
|
||||
extern int gbBorderColumnSkip;
|
||||
extern int gbDmaTicks;
|
||||
|
||||
extern void gbRenderLine();
|
||||
extern void gbDrawSprites(bool);
|
||||
|
||||
extern u8 (*gbSerialFunction)(u8);
|
||||
// -*- C++ -*-
|
||||
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
|
||||
// Copyright (C) 1999-2003 Forgotten
|
||||
// Copyright (C) 2005-2006 Forgotten and the VBA development team
|
||||
|
||||
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
extern int gbRomSizeMask;
|
||||
extern int gbRomSize;
|
||||
extern int gbRamSize;
|
||||
extern int gbRamSizeMask;
|
||||
extern int gbTAMA5ramSize;
|
||||
|
||||
extern bool useBios;
|
||||
extern bool skipBios;
|
||||
extern u8 *bios;
|
||||
|
||||
extern u8 *gbRom;
|
||||
extern u8 *gbRam;
|
||||
extern u8 *gbVram;
|
||||
extern u8 *gbWram;
|
||||
extern u8 *gbMemory;
|
||||
extern u16 *gbLineBuffer;
|
||||
extern u8 *gbTAMA5ram;
|
||||
|
||||
extern u8 *gbMemoryMap[16];
|
||||
|
||||
extern int gbFrameSkip;
|
||||
extern u16 gbColorFilter[32768];
|
||||
extern int gbColorOption;
|
||||
extern int gbPaletteOption;
|
||||
extern int gbEmulatorType;
|
||||
extern int gbBorderOn;
|
||||
extern int gbBorderAutomatic;
|
||||
extern int gbCgbMode;
|
||||
extern int gbSgbMode;
|
||||
extern int gbWindowLine;
|
||||
extern int gbSpeed;
|
||||
extern u8 gbBgp[4];
|
||||
extern u8 gbObp0[4];
|
||||
extern u8 gbObp1[4];
|
||||
extern u16 gbPalette[128];
|
||||
extern bool gbScreenOn;
|
||||
extern bool gbDrawWindow;
|
||||
extern u8 gbSCYLine[300];
|
||||
// gbSCXLine is used for the emulation (bug) of the SX change
|
||||
// found in the Artic Zone game.
|
||||
extern u8 gbSCXLine[300];
|
||||
// gbBgpLine is used for the emulation of the
|
||||
// Prehistorik Man's title screen scroller.
|
||||
extern u8 gbBgpLine[300];
|
||||
extern u8 gbObp0Line [300];
|
||||
extern u8 gbObp1Line [300];
|
||||
// gbSpritesTicks is used for the emulation of Parodius' Laser Beam.
|
||||
extern u8 gbSpritesTicks[300];
|
||||
|
||||
extern u8 register_LCDC;
|
||||
extern u8 register_LY;
|
||||
extern u8 register_SCY;
|
||||
extern u8 register_SCX;
|
||||
extern u8 register_WY;
|
||||
extern u8 register_WX;
|
||||
extern u8 register_VBK;
|
||||
extern u8 oldRegister_WY;
|
||||
|
||||
extern int emulating;
|
||||
extern bool genericflashcardEnable;
|
||||
|
||||
extern int gbBorderLineSkip;
|
||||
extern int gbBorderRowSkip;
|
||||
extern int gbBorderColumnSkip;
|
||||
extern int gbDmaTicks;
|
||||
|
||||
extern void gbRenderLine();
|
||||
extern void gbDrawSprites(bool);
|
||||
|
||||
extern u8 (*gbSerialFunction)(u8);
|
||||
|
|
3434
src/dmg/gbMemory.cpp
3434
src/dmg/gbMemory.cpp
File diff suppressed because it is too large
Load Diff
|
@ -1,206 +1,206 @@
|
|||
// -*- C++ -*-
|
||||
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
|
||||
// Copyright (C) 1999-2003 Forgotten
|
||||
// Copyright (C) 2004-2006 Forgotten and the VBA development team
|
||||
|
||||
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
#include <time.h>
|
||||
|
||||
struct mapperMBC1 {
|
||||
int mapperRAMEnable;
|
||||
int mapperROMBank;
|
||||
int mapperRAMBank;
|
||||
int mapperMemoryModel;
|
||||
int mapperROMHighAddress;
|
||||
int mapperRAMAddress;
|
||||
int mapperRomBank0Remapping;
|
||||
};
|
||||
|
||||
struct mapperMBC2 {
|
||||
int mapperRAMEnable;
|
||||
int mapperROMBank;
|
||||
};
|
||||
|
||||
struct mapperMBC3 {
|
||||
int mapperRAMEnable;
|
||||
int mapperROMBank;
|
||||
int mapperRAMBank;
|
||||
int mapperRAMAddress;
|
||||
int mapperClockLatch;
|
||||
int mapperClockRegister;
|
||||
int mapperSeconds;
|
||||
int mapperMinutes;
|
||||
int mapperHours;
|
||||
int mapperDays;
|
||||
int mapperControl;
|
||||
int mapperLSeconds;
|
||||
int mapperLMinutes;
|
||||
int mapperLHours;
|
||||
int mapperLDays;
|
||||
int mapperLControl;
|
||||
time_t mapperLastTime;
|
||||
};
|
||||
|
||||
struct mapperMBC5 {
|
||||
int mapperRAMEnable;
|
||||
int mapperROMBank;
|
||||
int mapperRAMBank;
|
||||
int mapperROMHighAddress;
|
||||
int mapperRAMAddress;
|
||||
int isRumbleCartridge;
|
||||
};
|
||||
|
||||
struct mapperMBC7 {
|
||||
int mapperRAMEnable;
|
||||
int mapperROMBank;
|
||||
int mapperRAMBank;
|
||||
int mapperRAMAddress;
|
||||
int cs;
|
||||
int sk;
|
||||
int state;
|
||||
int buffer;
|
||||
int idle;
|
||||
int count;
|
||||
int code;
|
||||
int address;
|
||||
int writeEnable;
|
||||
int value;
|
||||
};
|
||||
|
||||
struct mapperHuC1 {
|
||||
int mapperRAMEnable;
|
||||
int mapperROMBank;
|
||||
int mapperRAMBank;
|
||||
int mapperMemoryModel;
|
||||
int mapperROMHighAddress;
|
||||
int mapperRAMAddress;
|
||||
};
|
||||
|
||||
struct mapperHuC3 {
|
||||
int mapperRAMEnable;
|
||||
int mapperROMBank;
|
||||
int mapperRAMBank;
|
||||
int mapperRAMAddress;
|
||||
int mapperAddress;
|
||||
int mapperRAMFlag;
|
||||
int mapperRAMValue;
|
||||
int mapperRegister1;
|
||||
int mapperRegister2;
|
||||
int mapperRegister3;
|
||||
int mapperRegister4;
|
||||
int mapperRegister5;
|
||||
int mapperRegister6;
|
||||
int mapperRegister7;
|
||||
int mapperRegister8;
|
||||
};
|
||||
|
||||
struct mapperTAMA5 {
|
||||
int mapperRAMEnable;
|
||||
int mapperROMBank;
|
||||
int mapperRAMBank;
|
||||
int mapperRAMAddress;
|
||||
int mapperRamByteSelect;
|
||||
int mapperCommandNumber;
|
||||
int mapperLastCommandNumber;
|
||||
int mapperCommands[0x10];
|
||||
int mapperRegister;
|
||||
int mapperClockLatch;
|
||||
int mapperClockRegister;
|
||||
int mapperSeconds;
|
||||
int mapperMinutes;
|
||||
int mapperHours;
|
||||
int mapperDays;
|
||||
int mapperMonths;
|
||||
int mapperYears;
|
||||
int mapperControl;
|
||||
int mapperLSeconds;
|
||||
int mapperLMinutes;
|
||||
int mapperLHours;
|
||||
int mapperLDays;
|
||||
int mapperLMonths;
|
||||
int mapperLYears;
|
||||
int mapperLControl;
|
||||
time_t mapperLastTime;
|
||||
};
|
||||
|
||||
struct mapperMMM01 {
|
||||
int mapperRAMEnable;
|
||||
int mapperROMBank;
|
||||
int mapperRAMBank;
|
||||
int mapperMemoryModel;
|
||||
int mapperROMHighAddress;
|
||||
int mapperRAMAddress;
|
||||
int mapperRomBank0Remapping;
|
||||
};
|
||||
|
||||
struct mapperGS3 {
|
||||
int mapperROMBank;
|
||||
};
|
||||
|
||||
extern mapperMBC1 gbDataMBC1;
|
||||
extern mapperMBC2 gbDataMBC2;
|
||||
extern mapperMBC3 gbDataMBC3;
|
||||
extern mapperMBC5 gbDataMBC5;
|
||||
extern mapperHuC1 gbDataHuC1;
|
||||
extern mapperHuC3 gbDataHuC3;
|
||||
extern mapperTAMA5 gbDataTAMA5;
|
||||
extern mapperMMM01 gbDataMMM01;
|
||||
extern mapperGS3 gbDataGS3;
|
||||
|
||||
void mapperMBC1ROM(u16,u8);
|
||||
void mapperMBC1RAM(u16,u8);
|
||||
u8 mapperMBC1ReadRAM(u16);
|
||||
void mapperMBC2ROM(u16,u8);
|
||||
void mapperMBC2RAM(u16,u8);
|
||||
void mapperMBC3ROM(u16,u8);
|
||||
void mapperMBC3RAM(u16,u8);
|
||||
u8 mapperMBC3ReadRAM(u16);
|
||||
void mapperMBC5ROM(u16,u8);
|
||||
void mapperMBC5RAM(u16,u8);
|
||||
u8 mapperMBC5ReadRAM(u16);
|
||||
void mapperMBC7ROM(u16,u8);
|
||||
void mapperMBC7RAM(u16,u8);
|
||||
u8 mapperMBC7ReadRAM(u16);
|
||||
void mapperHuC1ROM(u16,u8);
|
||||
void mapperHuC1RAM(u16,u8);
|
||||
void mapperHuC3ROM(u16,u8);
|
||||
void mapperHuC3RAM(u16,u8);
|
||||
u8 mapperHuC3ReadRAM(u16);
|
||||
void mapperTAMA5RAM(u16,u8);
|
||||
u8 mapperTAMA5ReadRAM(u16);
|
||||
void memoryUpdateTAMA5Clock();
|
||||
void mapperMMM01ROM(u16,u8);
|
||||
void mapperMMM01RAM(u16,u8);
|
||||
void mapperGGROM(u16,u8);
|
||||
void mapperGS3ROM(u16,u8);
|
||||
//extern void (*mapper)(u16,u8);
|
||||
//extern void (*mapperRAM)(u16,u8);
|
||||
//extern u8 (*mapperReadRAM)(u16);
|
||||
|
||||
extern void memoryUpdateMapMBC1();
|
||||
extern void memoryUpdateMapMBC2();
|
||||
extern void memoryUpdateMapMBC3();
|
||||
extern void memoryUpdateMapMBC5();
|
||||
extern void memoryUpdateMapMBC7();
|
||||
extern void memoryUpdateMapHuC1();
|
||||
extern void memoryUpdateMapHuC3();
|
||||
extern void memoryUpdateMapTAMA5();
|
||||
extern void memoryUpdateMapMMM01();
|
||||
extern void memoryUpdateMapGS3();
|
||||
|
||||
|
||||
|
||||
|
||||
// -*- C++ -*-
|
||||
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
|
||||
// Copyright (C) 1999-2003 Forgotten
|
||||
// Copyright (C) 2004-2006 Forgotten and the VBA development team
|
||||
|
||||
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
#include <time.h>
|
||||
|
||||
struct mapperMBC1 {
|
||||
int mapperRAMEnable;
|
||||
int mapperROMBank;
|
||||
int mapperRAMBank;
|
||||
int mapperMemoryModel;
|
||||
int mapperROMHighAddress;
|
||||
int mapperRAMAddress;
|
||||
int mapperRomBank0Remapping;
|
||||
};
|
||||
|
||||
struct mapperMBC2 {
|
||||
int mapperRAMEnable;
|
||||
int mapperROMBank;
|
||||
};
|
||||
|
||||
struct mapperMBC3 {
|
||||
int mapperRAMEnable;
|
||||
int mapperROMBank;
|
||||
int mapperRAMBank;
|
||||
int mapperRAMAddress;
|
||||
int mapperClockLatch;
|
||||
int mapperClockRegister;
|
||||
int mapperSeconds;
|
||||
int mapperMinutes;
|
||||
int mapperHours;
|
||||
int mapperDays;
|
||||
int mapperControl;
|
||||
int mapperLSeconds;
|
||||
int mapperLMinutes;
|
||||
int mapperLHours;
|
||||
int mapperLDays;
|
||||
int mapperLControl;
|
||||
time_t mapperLastTime;
|
||||
};
|
||||
|
||||
struct mapperMBC5 {
|
||||
int mapperRAMEnable;
|
||||
int mapperROMBank;
|
||||
int mapperRAMBank;
|
||||
int mapperROMHighAddress;
|
||||
int mapperRAMAddress;
|
||||
int isRumbleCartridge;
|
||||
};
|
||||
|
||||
struct mapperMBC7 {
|
||||
int mapperRAMEnable;
|
||||
int mapperROMBank;
|
||||
int mapperRAMBank;
|
||||
int mapperRAMAddress;
|
||||
int cs;
|
||||
int sk;
|
||||
int state;
|
||||
int buffer;
|
||||
int idle;
|
||||
int count;
|
||||
int code;
|
||||
int address;
|
||||
int writeEnable;
|
||||
int value;
|
||||
};
|
||||
|
||||
struct mapperHuC1 {
|
||||
int mapperRAMEnable;
|
||||
int mapperROMBank;
|
||||
int mapperRAMBank;
|
||||
int mapperMemoryModel;
|
||||
int mapperROMHighAddress;
|
||||
int mapperRAMAddress;
|
||||
};
|
||||
|
||||
struct mapperHuC3 {
|
||||
int mapperRAMEnable;
|
||||
int mapperROMBank;
|
||||
int mapperRAMBank;
|
||||
int mapperRAMAddress;
|
||||
int mapperAddress;
|
||||
int mapperRAMFlag;
|
||||
int mapperRAMValue;
|
||||
int mapperRegister1;
|
||||
int mapperRegister2;
|
||||
int mapperRegister3;
|
||||
int mapperRegister4;
|
||||
int mapperRegister5;
|
||||
int mapperRegister6;
|
||||
int mapperRegister7;
|
||||
int mapperRegister8;
|
||||
};
|
||||
|
||||
struct mapperTAMA5 {
|
||||
int mapperRAMEnable;
|
||||
int mapperROMBank;
|
||||
int mapperRAMBank;
|
||||
int mapperRAMAddress;
|
||||
int mapperRamByteSelect;
|
||||
int mapperCommandNumber;
|
||||
int mapperLastCommandNumber;
|
||||
int mapperCommands[0x10];
|
||||
int mapperRegister;
|
||||
int mapperClockLatch;
|
||||
int mapperClockRegister;
|
||||
int mapperSeconds;
|
||||
int mapperMinutes;
|
||||
int mapperHours;
|
||||
int mapperDays;
|
||||
int mapperMonths;
|
||||
int mapperYears;
|
||||
int mapperControl;
|
||||
int mapperLSeconds;
|
||||
int mapperLMinutes;
|
||||
int mapperLHours;
|
||||
int mapperLDays;
|
||||
int mapperLMonths;
|
||||
int mapperLYears;
|
||||
int mapperLControl;
|
||||
time_t mapperLastTime;
|
||||
};
|
||||
|
||||
struct mapperMMM01 {
|
||||
int mapperRAMEnable;
|
||||
int mapperROMBank;
|
||||
int mapperRAMBank;
|
||||
int mapperMemoryModel;
|
||||
int mapperROMHighAddress;
|
||||
int mapperRAMAddress;
|
||||
int mapperRomBank0Remapping;
|
||||
};
|
||||
|
||||
struct mapperGS3 {
|
||||
int mapperROMBank;
|
||||
};
|
||||
|
||||
extern mapperMBC1 gbDataMBC1;
|
||||
extern mapperMBC2 gbDataMBC2;
|
||||
extern mapperMBC3 gbDataMBC3;
|
||||
extern mapperMBC5 gbDataMBC5;
|
||||
extern mapperHuC1 gbDataHuC1;
|
||||
extern mapperHuC3 gbDataHuC3;
|
||||
extern mapperTAMA5 gbDataTAMA5;
|
||||
extern mapperMMM01 gbDataMMM01;
|
||||
extern mapperGS3 gbDataGS3;
|
||||
|
||||
void mapperMBC1ROM(u16,u8);
|
||||
void mapperMBC1RAM(u16,u8);
|
||||
u8 mapperMBC1ReadRAM(u16);
|
||||
void mapperMBC2ROM(u16,u8);
|
||||
void mapperMBC2RAM(u16,u8);
|
||||
void mapperMBC3ROM(u16,u8);
|
||||
void mapperMBC3RAM(u16,u8);
|
||||
u8 mapperMBC3ReadRAM(u16);
|
||||
void mapperMBC5ROM(u16,u8);
|
||||
void mapperMBC5RAM(u16,u8);
|
||||
u8 mapperMBC5ReadRAM(u16);
|
||||
void mapperMBC7ROM(u16,u8);
|
||||
void mapperMBC7RAM(u16,u8);
|
||||
u8 mapperMBC7ReadRAM(u16);
|
||||
void mapperHuC1ROM(u16,u8);
|
||||
void mapperHuC1RAM(u16,u8);
|
||||
void mapperHuC3ROM(u16,u8);
|
||||
void mapperHuC3RAM(u16,u8);
|
||||
u8 mapperHuC3ReadRAM(u16);
|
||||
void mapperTAMA5RAM(u16,u8);
|
||||
u8 mapperTAMA5ReadRAM(u16);
|
||||
void memoryUpdateTAMA5Clock();
|
||||
void mapperMMM01ROM(u16,u8);
|
||||
void mapperMMM01RAM(u16,u8);
|
||||
void mapperGGROM(u16,u8);
|
||||
void mapperGS3ROM(u16,u8);
|
||||
//extern void (*mapper)(u16,u8);
|
||||
//extern void (*mapperRAM)(u16,u8);
|
||||
//extern u8 (*mapperReadRAM)(u16);
|
||||
|
||||
extern void memoryUpdateMapMBC1();
|
||||
extern void memoryUpdateMapMBC2();
|
||||
extern void memoryUpdateMapMBC3();
|
||||
extern void memoryUpdateMapMBC5();
|
||||
extern void memoryUpdateMapMBC7();
|
||||
extern void memoryUpdateMapHuC1();
|
||||
extern void memoryUpdateMapHuC3();
|
||||
extern void memoryUpdateMapTAMA5();
|
||||
extern void memoryUpdateMapMMM01();
|
||||
extern void memoryUpdateMapGS3();
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -1,229 +1,229 @@
|
|||
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
|
||||
// Copyright (C) 1999-2003 Forgotten
|
||||
// Copyright (C) 2004 Forgotten and the VBA development team
|
||||
|
||||
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
#include <stdio.h>
|
||||
#include <memory.h>
|
||||
#include "../agb/GBA.h"
|
||||
|
||||
u8 gbPrinterStatus = 0;
|
||||
int gbPrinterState = 0;
|
||||
u8 gbPrinterData[0x280*9];
|
||||
u8 gbPrinterPacket[0x400];
|
||||
int gbPrinterCount = 0;
|
||||
int gbPrinterDataCount = 0;
|
||||
int gbPrinterDataSize = 0;
|
||||
int gbPrinterResult = 0;
|
||||
|
||||
bool gbPrinterCheckCRC()
|
||||
{
|
||||
u16 crc = 0;
|
||||
|
||||
for(int i = 2; i < (6+gbPrinterDataSize); i++) {
|
||||
crc += gbPrinterPacket[i];
|
||||
}
|
||||
|
||||
int msgCrc = gbPrinterPacket[6+gbPrinterDataSize] +
|
||||
(gbPrinterPacket[7+gbPrinterDataSize]<<8);
|
||||
|
||||
return msgCrc == crc;
|
||||
}
|
||||
|
||||
void gbPrinterReset()
|
||||
{
|
||||
gbPrinterState = 0;
|
||||
gbPrinterDataSize = 0;
|
||||
gbPrinterDataCount = 0;
|
||||
gbPrinterCount = 0;
|
||||
gbPrinterStatus = 0;
|
||||
gbPrinterResult = 0;
|
||||
}
|
||||
|
||||
void gbPrinterShowData()
|
||||
{
|
||||
systemGbPrint(gbPrinterData,
|
||||
gbPrinterPacket[6],
|
||||
gbPrinterPacket[7],
|
||||
gbPrinterPacket[8],
|
||||
gbPrinterPacket[9]);
|
||||
/*
|
||||
allegro_init();
|
||||
install_keyboard();
|
||||
set_gfx_mode(GFX_AUTODETECT, 160, 144, 0, 0);
|
||||
PALETTE pal;
|
||||
pal[0].r = 255;
|
||||
pal[0].g = 255;
|
||||
pal[0].b = 255;
|
||||
pal[1].r = 168;
|
||||
pal[1].g = 168;
|
||||
pal[1].b = 168;
|
||||
pal[2].r = 96;
|
||||
pal[2].g = 96;
|
||||
pal[2].b = 96;
|
||||
pal[3].r = 0;
|
||||
pal[3].g = 0;
|
||||
pal[3].b = 0;
|
||||
set_palette(pal);
|
||||
acquire_screen();
|
||||
u8 *data = gbPrinterData;
|
||||
for(int y = 0; y < 0x12; y++) {
|
||||
for(int x = 0; x < 0x14; x++) {
|
||||
for(int k = 0; k < 8; k++) {
|
||||
int a = *data++;
|
||||
int b = *data++;
|
||||
for(int j = 0; j < 8; j++) {
|
||||
int mask = 1 << (7-j);
|
||||
int c = 0;
|
||||
if(a & mask)
|
||||
c++;
|
||||
if(b & mask)
|
||||
c+=2;
|
||||
putpixel(screen, x*8+j, y*8+k, c);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
release_screen();
|
||||
while(!keypressed()) {
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
void gbPrinterReceiveData()
|
||||
{
|
||||
if(gbPrinterPacket[3]) { // compressed
|
||||
u8 *data = &gbPrinterPacket[6];
|
||||
u8 *dest = &gbPrinterData[gbPrinterDataCount];
|
||||
int len = 0;
|
||||
while(len < gbPrinterDataSize) {
|
||||
u8 control = *data++;
|
||||
if(control & 0x80) { // repeated data
|
||||
control &= 0x7f;
|
||||
control += 2;
|
||||
memset(dest, *data++, control);
|
||||
len += control;
|
||||
dest += control;
|
||||
} else { // raw data
|
||||
control++;
|
||||
memcpy(dest, data, control);
|
||||
dest += control;
|
||||
data += control;
|
||||
len += control;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
memcpy(&gbPrinterData[gbPrinterDataCount],
|
||||
&gbPrinterPacket[6],
|
||||
gbPrinterDataSize);
|
||||
gbPrinterDataCount += gbPrinterDataSize;
|
||||
}
|
||||
}
|
||||
|
||||
void gbPrinterCommand()
|
||||
{
|
||||
switch(gbPrinterPacket[2]) {
|
||||
case 0x01:
|
||||
// reset/initialize packet
|
||||
gbPrinterDataCount = 0;
|
||||
gbPrinterStatus = 0;
|
||||
break;
|
||||
case 0x02:
|
||||
// print packet
|
||||
gbPrinterShowData();
|
||||
break;
|
||||
case 0x04:
|
||||
// data packet
|
||||
gbPrinterReceiveData();
|
||||
break;
|
||||
case 0x0f:
|
||||
// NUL packet
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
u8 gbPrinterSend(u8 b)
|
||||
{
|
||||
switch(gbPrinterState) {
|
||||
case 0:
|
||||
gbPrinterCount = 0;
|
||||
// receiving preamble
|
||||
if(b == 0x88) {
|
||||
gbPrinterPacket[gbPrinterCount++] = b;
|
||||
gbPrinterState++;
|
||||
} else {
|
||||
// todo: handle failure
|
||||
gbPrinterReset();
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
// receiving preamble
|
||||
if(b == 0x33) {
|
||||
gbPrinterPacket[gbPrinterCount++] = b;
|
||||
gbPrinterState++;
|
||||
} else {
|
||||
// todo: handle failure
|
||||
gbPrinterReset();
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
// receiving header
|
||||
gbPrinterPacket[gbPrinterCount++] = b;
|
||||
if(gbPrinterCount == 6) {
|
||||
gbPrinterState++;
|
||||
gbPrinterDataSize = gbPrinterPacket[4] + (gbPrinterPacket[5]<<8);
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
// receiving data
|
||||
if(gbPrinterDataSize) {
|
||||
gbPrinterPacket[gbPrinterCount++] = b;
|
||||
if(gbPrinterCount == (6+gbPrinterDataSize)) {
|
||||
gbPrinterState++;
|
||||
}
|
||||
break;
|
||||
}
|
||||
gbPrinterState++;
|
||||
// intentionally move to next if no data to receive
|
||||
case 4:
|
||||
// receiving CRC
|
||||
gbPrinterPacket[gbPrinterCount++] = b;
|
||||
gbPrinterState++;
|
||||
break;
|
||||
case 5:
|
||||
// receiving CRC-2
|
||||
gbPrinterPacket[gbPrinterCount++] = b;
|
||||
if(gbPrinterCheckCRC()) {
|
||||
gbPrinterCommand();
|
||||
}
|
||||
gbPrinterState++;
|
||||
break;
|
||||
case 6:
|
||||
// receiving dummy 1
|
||||
gbPrinterPacket[gbPrinterCount++] = b;
|
||||
gbPrinterResult = 0x81;
|
||||
gbPrinterState++;
|
||||
break;
|
||||
case 7:
|
||||
// receiving dummy 2
|
||||
gbPrinterPacket[gbPrinterCount++] = b;
|
||||
gbPrinterResult = gbPrinterStatus;
|
||||
gbPrinterState = 0;
|
||||
gbPrinterCount = 0;
|
||||
break;
|
||||
}
|
||||
return gbPrinterResult;
|
||||
}
|
||||
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
|
||||
// Copyright (C) 1999-2003 Forgotten
|
||||
// Copyright (C) 2004 Forgotten and the VBA development team
|
||||
|
||||
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
#include <stdio.h>
|
||||
#include <memory.h>
|
||||
#include "../agb/GBA.h"
|
||||
|
||||
u8 gbPrinterStatus = 0;
|
||||
int gbPrinterState = 0;
|
||||
u8 gbPrinterData[0x280*9];
|
||||
u8 gbPrinterPacket[0x400];
|
||||
int gbPrinterCount = 0;
|
||||
int gbPrinterDataCount = 0;
|
||||
int gbPrinterDataSize = 0;
|
||||
int gbPrinterResult = 0;
|
||||
|
||||
bool gbPrinterCheckCRC()
|
||||
{
|
||||
u16 crc = 0;
|
||||
|
||||
for(int i = 2; i < (6+gbPrinterDataSize); i++) {
|
||||
crc += gbPrinterPacket[i];
|
||||
}
|
||||
|
||||
int msgCrc = gbPrinterPacket[6+gbPrinterDataSize] +
|
||||
(gbPrinterPacket[7+gbPrinterDataSize]<<8);
|
||||
|
||||
return msgCrc == crc;
|
||||
}
|
||||
|
||||
void gbPrinterReset()
|
||||
{
|
||||
gbPrinterState = 0;
|
||||
gbPrinterDataSize = 0;
|
||||
gbPrinterDataCount = 0;
|
||||
gbPrinterCount = 0;
|
||||
gbPrinterStatus = 0;
|
||||
gbPrinterResult = 0;
|
||||
}
|
||||
|
||||
void gbPrinterShowData()
|
||||
{
|
||||
systemGbPrint(gbPrinterData,
|
||||
gbPrinterPacket[6],
|
||||
gbPrinterPacket[7],
|
||||
gbPrinterPacket[8],
|
||||
gbPrinterPacket[9]);
|
||||
/*
|
||||
allegro_init();
|
||||
install_keyboard();
|
||||
set_gfx_mode(GFX_AUTODETECT, 160, 144, 0, 0);
|
||||
PALETTE pal;
|
||||
pal[0].r = 255;
|
||||
pal[0].g = 255;
|
||||
pal[0].b = 255;
|
||||
pal[1].r = 168;
|
||||
pal[1].g = 168;
|
||||
pal[1].b = 168;
|
||||
pal[2].r = 96;
|
||||
pal[2].g = 96;
|
||||
pal[2].b = 96;
|
||||
pal[3].r = 0;
|
||||
pal[3].g = 0;
|
||||
pal[3].b = 0;
|
||||
set_palette(pal);
|
||||
acquire_screen();
|
||||
u8 *data = gbPrinterData;
|
||||
for(int y = 0; y < 0x12; y++) {
|
||||
for(int x = 0; x < 0x14; x++) {
|
||||
for(int k = 0; k < 8; k++) {
|
||||
int a = *data++;
|
||||
int b = *data++;
|
||||
for(int j = 0; j < 8; j++) {
|
||||
int mask = 1 << (7-j);
|
||||
int c = 0;
|
||||
if(a & mask)
|
||||
c++;
|
||||
if(b & mask)
|
||||
c+=2;
|
||||
putpixel(screen, x*8+j, y*8+k, c);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
release_screen();
|
||||
while(!keypressed()) {
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
void gbPrinterReceiveData()
|
||||
{
|
||||
if(gbPrinterPacket[3]) { // compressed
|
||||
u8 *data = &gbPrinterPacket[6];
|
||||
u8 *dest = &gbPrinterData[gbPrinterDataCount];
|
||||
int len = 0;
|
||||
while(len < gbPrinterDataSize) {
|
||||
u8 control = *data++;
|
||||
if(control & 0x80) { // repeated data
|
||||
control &= 0x7f;
|
||||
control += 2;
|
||||
memset(dest, *data++, control);
|
||||
len += control;
|
||||
dest += control;
|
||||
} else { // raw data
|
||||
control++;
|
||||
memcpy(dest, data, control);
|
||||
dest += control;
|
||||
data += control;
|
||||
len += control;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
memcpy(&gbPrinterData[gbPrinterDataCount],
|
||||
&gbPrinterPacket[6],
|
||||
gbPrinterDataSize);
|
||||
gbPrinterDataCount += gbPrinterDataSize;
|
||||
}
|
||||
}
|
||||
|
||||
void gbPrinterCommand()
|
||||
{
|
||||
switch(gbPrinterPacket[2]) {
|
||||
case 0x01:
|
||||
// reset/initialize packet
|
||||
gbPrinterDataCount = 0;
|
||||
gbPrinterStatus = 0;
|
||||
break;
|
||||
case 0x02:
|
||||
// print packet
|
||||
gbPrinterShowData();
|
||||
break;
|
||||
case 0x04:
|
||||
// data packet
|
||||
gbPrinterReceiveData();
|
||||
break;
|
||||
case 0x0f:
|
||||
// NUL packet
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
u8 gbPrinterSend(u8 b)
|
||||
{
|
||||
switch(gbPrinterState) {
|
||||
case 0:
|
||||
gbPrinterCount = 0;
|
||||
// receiving preamble
|
||||
if(b == 0x88) {
|
||||
gbPrinterPacket[gbPrinterCount++] = b;
|
||||
gbPrinterState++;
|
||||
} else {
|
||||
// todo: handle failure
|
||||
gbPrinterReset();
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
// receiving preamble
|
||||
if(b == 0x33) {
|
||||
gbPrinterPacket[gbPrinterCount++] = b;
|
||||
gbPrinterState++;
|
||||
} else {
|
||||
// todo: handle failure
|
||||
gbPrinterReset();
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
// receiving header
|
||||
gbPrinterPacket[gbPrinterCount++] = b;
|
||||
if(gbPrinterCount == 6) {
|
||||
gbPrinterState++;
|
||||
gbPrinterDataSize = gbPrinterPacket[4] + (gbPrinterPacket[5]<<8);
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
// receiving data
|
||||
if(gbPrinterDataSize) {
|
||||
gbPrinterPacket[gbPrinterCount++] = b;
|
||||
if(gbPrinterCount == (6+gbPrinterDataSize)) {
|
||||
gbPrinterState++;
|
||||
}
|
||||
break;
|
||||
}
|
||||
gbPrinterState++;
|
||||
// intentionally move to next if no data to receive
|
||||
case 4:
|
||||
// receiving CRC
|
||||
gbPrinterPacket[gbPrinterCount++] = b;
|
||||
gbPrinterState++;
|
||||
break;
|
||||
case 5:
|
||||
// receiving CRC-2
|
||||
gbPrinterPacket[gbPrinterCount++] = b;
|
||||
if(gbPrinterCheckCRC()) {
|
||||
gbPrinterCommand();
|
||||
}
|
||||
gbPrinterState++;
|
||||
break;
|
||||
case 6:
|
||||
// receiving dummy 1
|
||||
gbPrinterPacket[gbPrinterCount++] = b;
|
||||
gbPrinterResult = 0x81;
|
||||
gbPrinterState++;
|
||||
break;
|
||||
case 7:
|
||||
// receiving dummy 2
|
||||
gbPrinterPacket[gbPrinterCount++] = b;
|
||||
gbPrinterResult = gbPrinterStatus;
|
||||
gbPrinterState = 0;
|
||||
gbPrinterCount = 0;
|
||||
break;
|
||||
}
|
||||
return gbPrinterResult;
|
||||
}
|
||||
|
|
|
@ -1,20 +1,20 @@
|
|||
// -*- C++ -*-
|
||||
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
|
||||
// Copyright (C) 1999-2003 Forgotten
|
||||
// Copyright (C) 2004 Forgotten and the VBA development team
|
||||
|
||||
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
extern u8 gbPrinterSend(u8 b);
|
||||
// -*- C++ -*-
|
||||
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
|
||||
// Copyright (C) 1999-2003 Forgotten
|
||||
// Copyright (C) 2004 Forgotten and the VBA development team
|
||||
|
||||
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
extern u8 gbPrinterSend(u8 b);
|
||||
|
|
1834
src/dmg/gbSGB.cpp
1834
src/dmg/gbSGB.cpp
File diff suppressed because it is too large
Load Diff
|
@ -1,39 +1,39 @@
|
|||
// -*- C++ -*-
|
||||
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
|
||||
// Copyright (C) 1999-2003 Forgotten
|
||||
// Copyright (C) 2004 Forgotten and the VBA development team
|
||||
|
||||
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
void gbSgbInit();
|
||||
void gbSgbShutdown();
|
||||
void gbSgbCommand();
|
||||
void gbSgbResetPacketState();
|
||||
void gbSgbReset();
|
||||
void gbSgbDoBitTransfer(u8);
|
||||
void gbSgbSaveGame(gzFile);
|
||||
void gbSgbReadGame(gzFile, int version);
|
||||
void gbSgbRenderBorder();
|
||||
|
||||
extern u8 gbSgbATF[20*18];
|
||||
extern int gbSgbMode;
|
||||
extern int gbSgbMask;
|
||||
extern int gbSgbMultiplayer;
|
||||
extern u8 gbSgbNextController;
|
||||
extern int gbSgbPacketTimeout;
|
||||
extern u8 gbSgbReadingController;
|
||||
extern int gbSgbFourPlayers;
|
||||
|
||||
|
||||
// -*- C++ -*-
|
||||
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
|
||||
// Copyright (C) 1999-2003 Forgotten
|
||||
// Copyright (C) 2004 Forgotten and the VBA development team
|
||||
|
||||
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
void gbSgbInit();
|
||||
void gbSgbShutdown();
|
||||
void gbSgbCommand();
|
||||
void gbSgbResetPacketState();
|
||||
void gbSgbReset();
|
||||
void gbSgbDoBitTransfer(u8);
|
||||
void gbSgbSaveGame(gzFile);
|
||||
void gbSgbReadGame(gzFile, int version);
|
||||
void gbSgbRenderBorder();
|
||||
|
||||
extern u8 gbSgbATF[20*18];
|
||||
extern int gbSgbMode;
|
||||
extern int gbSgbMask;
|
||||
extern int gbSgbMultiplayer;
|
||||
extern u8 gbSgbNextController;
|
||||
extern int gbSgbPacketTimeout;
|
||||
extern u8 gbSgbReadingController;
|
||||
extern int gbSgbFourPlayers;
|
||||
|
||||
|
||||
|
|
|
@ -1,412 +1,412 @@
|
|||
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
|
||||
// Copyright (C) 1999-2003 Forgotten
|
||||
// Copyright (C) 2005-2006 Forgotten and the VBA development team
|
||||
// Copyright (C) 2007-2008 VBA-M development team
|
||||
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
#include <memory.h>
|
||||
|
||||
#include "../System.h"
|
||||
#include "../Util.h"
|
||||
#include "gbGlobals.h"
|
||||
#include "gbSound.h"
|
||||
|
||||
#include "gb_apu/Gb_Apu.h"
|
||||
#include "gb_apu/Effects_Buffer.h"
|
||||
|
||||
static Gb_Apu* gb_apu;
|
||||
static Simple_Effects_Buffer* stereo_buffer;
|
||||
|
||||
extern u16 soundFinalWave[1470];
|
||||
extern int soundVolume;
|
||||
|
||||
extern int gbHardware;
|
||||
|
||||
extern void soundResume();
|
||||
|
||||
extern int soundBufferLen;
|
||||
extern int soundQuality;
|
||||
extern bool soundPaused;
|
||||
extern int soundTicks;
|
||||
extern int SOUND_CLOCK_TICKS;
|
||||
extern u32 soundNextPosition;
|
||||
|
||||
extern int soundDebug;
|
||||
|
||||
extern bool soundEcho;
|
||||
extern bool soundLowPass;
|
||||
extern bool soundReverse;
|
||||
extern bool soundOffFlag;
|
||||
|
||||
int const ticks_to_time = 2 * GB_APU_OVERCLOCK;
|
||||
|
||||
static inline blip_time_t blip_time()
|
||||
{
|
||||
return (SOUND_CLOCK_TICKS - soundTicks) * ticks_to_time;
|
||||
}
|
||||
|
||||
u8 gbSoundRead( u16 address )
|
||||
{
|
||||
if ( gb_apu && address >= NR10 && address <= 0xFF3F )
|
||||
return gb_apu->read_register( blip_time(), address );
|
||||
|
||||
return gbMemory[address];
|
||||
}
|
||||
|
||||
void gbSoundEvent(register u16 address, register int data)
|
||||
{
|
||||
int freq = 0;
|
||||
|
||||
gbMemory[address] = data;
|
||||
|
||||
#ifndef FINAL_VERSION
|
||||
if(soundDebug) {
|
||||
// don't translate. debug only
|
||||
log("Sound event: %08lx %02x\n", address, data);
|
||||
}
|
||||
#endif
|
||||
|
||||
if ( gb_apu && address >= NR10 && address <= 0xFF3F )
|
||||
gb_apu->write_register( blip_time(), address, data );
|
||||
}
|
||||
|
||||
static void end_frame( blip_time_t time )
|
||||
{
|
||||
gb_apu ->end_frame( time );
|
||||
stereo_buffer->end_frame( time );
|
||||
}
|
||||
|
||||
static void flush_samples()
|
||||
{
|
||||
// number of samples in output buffer
|
||||
int const out_buf_size = soundBufferLen / sizeof *soundFinalWave;
|
||||
|
||||
// Keep filling and writing soundFinalWave until it can't be fully filled
|
||||
while ( stereo_buffer->samples_avail() >= out_buf_size )
|
||||
{
|
||||
stereo_buffer->read_samples( (blip_sample_t*) soundFinalWave, out_buf_size );
|
||||
if(systemSoundOn)
|
||||
{
|
||||
if(soundPaused)
|
||||
soundResume();
|
||||
|
||||
systemWriteDataToSoundBuffer();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int const chan_count = 4;
|
||||
|
||||
gb_effects_config_t gb_effects_config;
|
||||
static gb_effects_config_t gb_effects_config_current;
|
||||
|
||||
static void apply_effects()
|
||||
{
|
||||
gb_effects_config_current = gb_effects_config;
|
||||
|
||||
stereo_buffer->config().enabled = gb_effects_config_current.enabled;
|
||||
stereo_buffer->config().echo = gb_effects_config_current.echo;
|
||||
stereo_buffer->config().stereo = gb_effects_config_current.stereo;
|
||||
stereo_buffer->config().surround = gb_effects_config_current.surround;
|
||||
stereo_buffer->apply_config();
|
||||
|
||||
for ( int i = 0; i < chan_count; i++ )
|
||||
{
|
||||
Multi_Buffer::channel_t ch = stereo_buffer->channel( i );
|
||||
gb_apu->set_output( ch.center, ch.left, ch.right, i );
|
||||
}
|
||||
}
|
||||
|
||||
void gbSoundTick()
|
||||
{
|
||||
if ( systemSoundOn && gb_apu && stereo_buffer )
|
||||
{
|
||||
// Run sound hardware to present
|
||||
end_frame( SOUND_CLOCK_TICKS * ticks_to_time );
|
||||
|
||||
flush_samples();
|
||||
|
||||
gb_effects_config.enabled = soundEcho;
|
||||
|
||||
// Update effects config if it was changed
|
||||
if ( memcmp( &gb_effects_config_current, &gb_effects_config,
|
||||
sizeof gb_effects_config ) )
|
||||
apply_effects();
|
||||
}
|
||||
}
|
||||
|
||||
static void reset_apu()
|
||||
{
|
||||
// Use DMG or CGB sound differences based on type of game
|
||||
gb_apu->reset( gbHardware & 1 ? gb_apu->mode_dmg : gb_apu->mode_cgb );
|
||||
|
||||
if ( stereo_buffer )
|
||||
stereo_buffer->clear();
|
||||
|
||||
soundTicks = SOUND_CLOCK_TICKS;
|
||||
}
|
||||
|
||||
static void remake_stereo_buffer()
|
||||
{
|
||||
// Stereo_Buffer
|
||||
delete stereo_buffer;
|
||||
stereo_buffer = 0;
|
||||
|
||||
stereo_buffer = new Simple_Effects_Buffer; // TODO: handle out of memory
|
||||
stereo_buffer->set_sample_rate( 44100 / soundQuality ); // TODO: handle out of memory
|
||||
stereo_buffer->clock_rate( gb_apu->clock_rate );
|
||||
|
||||
// APU
|
||||
static int const chan_types [chan_count] = {
|
||||
Multi_Buffer::wave_type+1, Multi_Buffer::wave_type+2,
|
||||
Multi_Buffer::wave_type+3, Multi_Buffer::mixed_type+1
|
||||
};
|
||||
stereo_buffer->set_channel_count( chan_count, chan_types );
|
||||
|
||||
if ( !gb_apu )
|
||||
{
|
||||
gb_apu = new Gb_Apu;
|
||||
reset_apu();
|
||||
}
|
||||
|
||||
apply_effects();
|
||||
}
|
||||
|
||||
void gbSoundReset()
|
||||
{
|
||||
gb_effects_config.echo = 0.20f;
|
||||
gb_effects_config.stereo = 0.15f;
|
||||
gb_effects_config.surround = false;
|
||||
|
||||
SOUND_CLOCK_TICKS = 20000;
|
||||
|
||||
remake_stereo_buffer();
|
||||
reset_apu();
|
||||
|
||||
soundPaused = 1;
|
||||
soundNextPosition = 0;
|
||||
|
||||
// don't translate
|
||||
#ifndef FINAL_VERSION
|
||||
if(soundDebug) {
|
||||
log("*** Sound Init ***\n");
|
||||
}
|
||||
#endif
|
||||
gbSoundEvent(0xff10, 0x80);
|
||||
gbSoundEvent(0xff11, 0xbf);
|
||||
gbSoundEvent(0xff12, 0xf3);
|
||||
gbSoundEvent(0xff14, 0xbf);
|
||||
gbSoundEvent(0xff16, 0x3f);
|
||||
gbSoundEvent(0xff17, 0x00);
|
||||
gbSoundEvent(0xff19, 0xbf);
|
||||
|
||||
gbSoundEvent(0xff1a, 0x7f);
|
||||
gbSoundEvent(0xff1b, 0xff);
|
||||
gbSoundEvent(0xff1c, 0xbf);
|
||||
gbSoundEvent(0xff1e, 0xbf);
|
||||
|
||||
gbSoundEvent(0xff20, 0xff);
|
||||
gbSoundEvent(0xff21, 0x00);
|
||||
gbSoundEvent(0xff22, 0x00);
|
||||
gbSoundEvent(0xff23, 0xbf);
|
||||
gbSoundEvent(0xff24, 0x77);
|
||||
gbSoundEvent(0xff25, 0xf3);
|
||||
|
||||
if (gbHardware & 0x4)
|
||||
gbSoundEvent(0xff26, 0xf0);
|
||||
else
|
||||
gbSoundEvent(0xff26, 0xf1);
|
||||
|
||||
// don't translate
|
||||
#ifndef FINAL_VERSION
|
||||
if(soundDebug) {
|
||||
log("*** Sound Init Complete ***\n");
|
||||
}
|
||||
#endif
|
||||
int addr = 0xff30;
|
||||
|
||||
while(addr < 0xff40) {
|
||||
gbMemory[addr++] = 0x00;
|
||||
gbMemory[addr++] = 0xff;
|
||||
}
|
||||
}
|
||||
|
||||
extern bool soundInit();
|
||||
extern void soundShutdown();
|
||||
|
||||
void gbSoundSetQuality(int quality)
|
||||
{
|
||||
if ( soundQuality != quality )
|
||||
{
|
||||
if ( systemCanChangeSoundQuality() )
|
||||
{
|
||||
if ( !soundOffFlag )
|
||||
soundShutdown();
|
||||
|
||||
soundQuality = quality;
|
||||
soundNextPosition = 0;
|
||||
|
||||
if ( !soundOffFlag )
|
||||
soundInit();
|
||||
}
|
||||
else
|
||||
{
|
||||
soundQuality = quality;
|
||||
soundNextPosition = 0;
|
||||
}
|
||||
|
||||
remake_stereo_buffer();
|
||||
}
|
||||
}
|
||||
|
||||
static char dummy_buf [735 * 2];
|
||||
|
||||
#define SKIP( type, name ) { dummy_buf, sizeof (type) }
|
||||
|
||||
// funny expr at end ensures that type matches type of variable
|
||||
#define LOAD( type, name ) { &name, sizeof (name) + (&name - (type*) &name) }
|
||||
|
||||
static variable_desc gbsound_format [] =
|
||||
{
|
||||
SKIP( int, soundPaused ),
|
||||
SKIP( int, soundPlay ),
|
||||
SKIP( int, soundTicks ),
|
||||
SKIP( int, SOUND_CLOCK_TICKS ),
|
||||
SKIP( int, soundLevel1 ),
|
||||
SKIP( int, soundLevel2 ),
|
||||
SKIP( int, soundBalance ),
|
||||
SKIP( int, soundMasterOn ),
|
||||
SKIP( int, soundIndex ),
|
||||
SKIP( int, soundVIN ),
|
||||
SKIP( int, soundOn [0] ),
|
||||
SKIP( int, soundATL [0] ),
|
||||
SKIP( int, sound1Skip ),
|
||||
SKIP( int, soundIndex [0] ),
|
||||
SKIP( int, sound1Continue ),
|
||||
SKIP( int, soundEnvelopeVolume [0] ),
|
||||
SKIP( int, soundEnvelopeATL [0] ),
|
||||
SKIP( int, sound1EnvelopeATLReload ),
|
||||
SKIP( int, sound1EnvelopeUpDown ),
|
||||
SKIP( int, sound1SweepATL ),
|
||||
SKIP( int, sound1SweepATLReload ),
|
||||
SKIP( int, sound1SweepSteps ),
|
||||
SKIP( int, sound1SweepUpDown ),
|
||||
SKIP( int, sound1SweepStep ),
|
||||
SKIP( int, soundOn [1] ),
|
||||
SKIP( int, soundATL [1] ),
|
||||
SKIP( int, sound2Skip ),
|
||||
SKIP( int, soundIndex [1] ),
|
||||
SKIP( int, sound2Continue ),
|
||||
SKIP( int, soundEnvelopeVolume [1] ),
|
||||
SKIP( int, soundEnvelopeATL [1] ),
|
||||
SKIP( int, sound2EnvelopeATLReload ),
|
||||
SKIP( int, sound2EnvelopeUpDown ),
|
||||
SKIP( int, soundOn [2] ),
|
||||
SKIP( int, soundATL [2] ),
|
||||
SKIP( int, sound3Skip ),
|
||||
SKIP( int, soundIndex [2] ),
|
||||
SKIP( int, sound3Continue ),
|
||||
SKIP( int, sound3OutputLevel ),
|
||||
SKIP( int, soundOn [3] ),
|
||||
SKIP( int, soundATL [3] ),
|
||||
SKIP( int, sound4Skip ),
|
||||
SKIP( int, soundIndex [3] ),
|
||||
SKIP( int, sound4Clock ),
|
||||
SKIP( int, sound4ShiftRight ),
|
||||
SKIP( int, sound4ShiftSkip ),
|
||||
SKIP( int, sound4ShiftIndex ),
|
||||
SKIP( int, sound4NSteps ),
|
||||
SKIP( int, sound4CountDown ),
|
||||
SKIP( int, sound4Continue ),
|
||||
SKIP( int, soundEnvelopeVolume [2] ),
|
||||
SKIP( int, soundEnvelopeATL [2] ),
|
||||
SKIP( int, sound4EnvelopeATLReload ),
|
||||
SKIP( int, sound4EnvelopeUpDown ),
|
||||
SKIP( int, soundEnableFlag ),
|
||||
{ NULL, 0 }
|
||||
};
|
||||
|
||||
static variable_desc gbsound_format2 [] =
|
||||
{
|
||||
SKIP( int, sound1ATLreload ),
|
||||
SKIP( int, freq1low ),
|
||||
SKIP( int, freq1high ),
|
||||
SKIP( int, sound2ATLreload ),
|
||||
SKIP( int, freq2low ),
|
||||
SKIP( int, freq2high ),
|
||||
SKIP( int, sound3ATLreload ),
|
||||
SKIP( int, freq3low ),
|
||||
SKIP( int, freq3high ),
|
||||
SKIP( int, sound4ATLreload ),
|
||||
SKIP( int, freq4 ),
|
||||
{ NULL, 0 }
|
||||
};
|
||||
|
||||
static variable_desc gbsound_format3 [] =
|
||||
{
|
||||
SKIP( u8[2*735], soundBuffer ),
|
||||
SKIP( u8[2*735], soundBuffer ),
|
||||
SKIP( u16[735], soundFinalWave ),
|
||||
{ NULL, 0 }
|
||||
};
|
||||
|
||||
void gbSoundSaveGame(gzFile gzFile)
|
||||
{
|
||||
// TODO: implement
|
||||
}
|
||||
|
||||
enum {
|
||||
nr10 = 0,
|
||||
nr11, nr12, nr13, nr14,
|
||||
nr20, nr21, nr22, nr23, nr24,
|
||||
nr30, nr31, nr32, nr33, nr34,
|
||||
nr40, nr41, nr42, nr43, nr44,
|
||||
nr50, nr51, nr52
|
||||
};
|
||||
|
||||
void gbSoundReadGame(int version,gzFile gzFile)
|
||||
{
|
||||
return; // TODO: apparently GB save states don't work in the main emulator
|
||||
|
||||
// Load state
|
||||
utilReadData( gzFile, gbsound_format );
|
||||
|
||||
if ( version >= 11 )
|
||||
utilReadData( gzFile, gbsound_format2 );
|
||||
|
||||
utilReadData( gzFile, gbsound_format3 );
|
||||
|
||||
int quality = 1;
|
||||
if ( version >= 7 )
|
||||
quality = utilReadInt( gzFile );
|
||||
|
||||
gbSoundSetQuality( quality );
|
||||
|
||||
// Convert to format Gb_Apu uses
|
||||
reset_apu();
|
||||
gb_apu_state_t s;
|
||||
gb_apu->save_state( &s ); // use fresh values for anything not restored
|
||||
|
||||
// Only some registers are properly preserved
|
||||
static int const regs_to_copy [] = {
|
||||
nr10, nr11, nr12, nr21, nr22, nr30, nr32, nr42, nr43, nr50, nr51, nr52, -1
|
||||
};
|
||||
for ( int i = 0; regs_to_copy [i] >= 0; i++ )
|
||||
s.regs [regs_to_copy [i]] = gbMemory [0xFF10 + regs_to_copy [i]];
|
||||
|
||||
memcpy( &s.regs [0x20], &gbMemory [0xFF30], 0x10 ); // wave
|
||||
|
||||
gb_apu->load_state( s );
|
||||
}
|
||||
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
|
||||
// Copyright (C) 1999-2003 Forgotten
|
||||
// Copyright (C) 2005-2006 Forgotten and the VBA development team
|
||||
// Copyright (C) 2007-2008 VBA-M development team
|
||||
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
#include <memory.h>
|
||||
|
||||
#include "../System.h"
|
||||
#include "../Util.h"
|
||||
#include "gbGlobals.h"
|
||||
#include "gbSound.h"
|
||||
|
||||
#include "gb_apu/Gb_Apu.h"
|
||||
#include "gb_apu/Effects_Buffer.h"
|
||||
|
||||
static Gb_Apu* gb_apu;
|
||||
static Simple_Effects_Buffer* stereo_buffer;
|
||||
|
||||
extern u16 soundFinalWave[1470];
|
||||
extern int soundVolume;
|
||||
|
||||
extern int gbHardware;
|
||||
|
||||
extern void soundResume();
|
||||
|
||||
extern int soundBufferLen;
|
||||
extern int soundQuality;
|
||||
extern bool soundPaused;
|
||||
extern int soundTicks;
|
||||
extern int SOUND_CLOCK_TICKS;
|
||||
extern u32 soundNextPosition;
|
||||
|
||||
extern int soundDebug;
|
||||
|
||||
extern bool soundEcho;
|
||||
extern bool soundLowPass;
|
||||
extern bool soundReverse;
|
||||
extern bool soundOffFlag;
|
||||
|
||||
int const ticks_to_time = 2 * GB_APU_OVERCLOCK;
|
||||
|
||||
static inline blip_time_t blip_time()
|
||||
{
|
||||
return (SOUND_CLOCK_TICKS - soundTicks) * ticks_to_time;
|
||||
}
|
||||
|
||||
u8 gbSoundRead( u16 address )
|
||||
{
|
||||
if ( gb_apu && address >= NR10 && address <= 0xFF3F )
|
||||
return gb_apu->read_register( blip_time(), address );
|
||||
|
||||
return gbMemory[address];
|
||||
}
|
||||
|
||||
void gbSoundEvent(register u16 address, register int data)
|
||||
{
|
||||
int freq = 0;
|
||||
|
||||
gbMemory[address] = data;
|
||||
|
||||
#ifndef FINAL_VERSION
|
||||
if(soundDebug) {
|
||||
// don't translate. debug only
|
||||
log("Sound event: %08lx %02x\n", address, data);
|
||||
}
|
||||
#endif
|
||||
|
||||
if ( gb_apu && address >= NR10 && address <= 0xFF3F )
|
||||
gb_apu->write_register( blip_time(), address, data );
|
||||
}
|
||||
|
||||
static void end_frame( blip_time_t time )
|
||||
{
|
||||
gb_apu ->end_frame( time );
|
||||
stereo_buffer->end_frame( time );
|
||||
}
|
||||
|
||||
static void flush_samples()
|
||||
{
|
||||
// number of samples in output buffer
|
||||
int const out_buf_size = soundBufferLen / sizeof *soundFinalWave;
|
||||
|
||||
// Keep filling and writing soundFinalWave until it can't be fully filled
|
||||
while ( stereo_buffer->samples_avail() >= out_buf_size )
|
||||
{
|
||||
stereo_buffer->read_samples( (blip_sample_t*) soundFinalWave, out_buf_size );
|
||||
if(systemSoundOn)
|
||||
{
|
||||
if(soundPaused)
|
||||
soundResume();
|
||||
|
||||
systemWriteDataToSoundBuffer();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int const chan_count = 4;
|
||||
|
||||
gb_effects_config_t gb_effects_config;
|
||||
static gb_effects_config_t gb_effects_config_current;
|
||||
|
||||
static void apply_effects()
|
||||
{
|
||||
gb_effects_config_current = gb_effects_config;
|
||||
|
||||
stereo_buffer->config().enabled = gb_effects_config_current.enabled;
|
||||
stereo_buffer->config().echo = gb_effects_config_current.echo;
|
||||
stereo_buffer->config().stereo = gb_effects_config_current.stereo;
|
||||
stereo_buffer->config().surround = gb_effects_config_current.surround;
|
||||
stereo_buffer->apply_config();
|
||||
|
||||
for ( int i = 0; i < chan_count; i++ )
|
||||
{
|
||||
Multi_Buffer::channel_t ch = stereo_buffer->channel( i );
|
||||
gb_apu->set_output( ch.center, ch.left, ch.right, i );
|
||||
}
|
||||
}
|
||||
|
||||
void gbSoundTick()
|
||||
{
|
||||
if ( systemSoundOn && gb_apu && stereo_buffer )
|
||||
{
|
||||
// Run sound hardware to present
|
||||
end_frame( SOUND_CLOCK_TICKS * ticks_to_time );
|
||||
|
||||
flush_samples();
|
||||
|
||||
gb_effects_config.enabled = soundEcho;
|
||||
|
||||
// Update effects config if it was changed
|
||||
if ( memcmp( &gb_effects_config_current, &gb_effects_config,
|
||||
sizeof gb_effects_config ) )
|
||||
apply_effects();
|
||||
}
|
||||
}
|
||||
|
||||
static void reset_apu()
|
||||
{
|
||||
// Use DMG or CGB sound differences based on type of game
|
||||
gb_apu->reset( gbHardware & 1 ? gb_apu->mode_dmg : gb_apu->mode_cgb );
|
||||
|
||||
if ( stereo_buffer )
|
||||
stereo_buffer->clear();
|
||||
|
||||
soundTicks = SOUND_CLOCK_TICKS;
|
||||
}
|
||||
|
||||
static void remake_stereo_buffer()
|
||||
{
|
||||
// Stereo_Buffer
|
||||
delete stereo_buffer;
|
||||
stereo_buffer = 0;
|
||||
|
||||
stereo_buffer = new Simple_Effects_Buffer; // TODO: handle out of memory
|
||||
stereo_buffer->set_sample_rate( 44100 / soundQuality ); // TODO: handle out of memory
|
||||
stereo_buffer->clock_rate( gb_apu->clock_rate );
|
||||
|
||||
// APU
|
||||
static int const chan_types [chan_count] = {
|
||||
Multi_Buffer::wave_type+1, Multi_Buffer::wave_type+2,
|
||||
Multi_Buffer::wave_type+3, Multi_Buffer::mixed_type+1
|
||||
};
|
||||
stereo_buffer->set_channel_count( chan_count, chan_types );
|
||||
|
||||
if ( !gb_apu )
|
||||
{
|
||||
gb_apu = new Gb_Apu;
|
||||
reset_apu();
|
||||
}
|
||||
|
||||
apply_effects();
|
||||
}
|
||||
|
||||
void gbSoundReset()
|
||||
{
|
||||
gb_effects_config.echo = 0.20f;
|
||||
gb_effects_config.stereo = 0.15f;
|
||||
gb_effects_config.surround = false;
|
||||
|
||||
SOUND_CLOCK_TICKS = 20000;
|
||||
|
||||
remake_stereo_buffer();
|
||||
reset_apu();
|
||||
|
||||
soundPaused = 1;
|
||||
soundNextPosition = 0;
|
||||
|
||||
// don't translate
|
||||
#ifndef FINAL_VERSION
|
||||
if(soundDebug) {
|
||||
log("*** Sound Init ***\n");
|
||||
}
|
||||
#endif
|
||||
gbSoundEvent(0xff10, 0x80);
|
||||
gbSoundEvent(0xff11, 0xbf);
|
||||
gbSoundEvent(0xff12, 0xf3);
|
||||
gbSoundEvent(0xff14, 0xbf);
|
||||
gbSoundEvent(0xff16, 0x3f);
|
||||
gbSoundEvent(0xff17, 0x00);
|
||||
gbSoundEvent(0xff19, 0xbf);
|
||||
|
||||
gbSoundEvent(0xff1a, 0x7f);
|
||||
gbSoundEvent(0xff1b, 0xff);
|
||||
gbSoundEvent(0xff1c, 0xbf);
|
||||
gbSoundEvent(0xff1e, 0xbf);
|
||||
|
||||
gbSoundEvent(0xff20, 0xff);
|
||||
gbSoundEvent(0xff21, 0x00);
|
||||
gbSoundEvent(0xff22, 0x00);
|
||||
gbSoundEvent(0xff23, 0xbf);
|
||||
gbSoundEvent(0xff24, 0x77);
|
||||
gbSoundEvent(0xff25, 0xf3);
|
||||
|
||||
if (gbHardware & 0x4)
|
||||
gbSoundEvent(0xff26, 0xf0);
|
||||
else
|
||||
gbSoundEvent(0xff26, 0xf1);
|
||||
|
||||
// don't translate
|
||||
#ifndef FINAL_VERSION
|
||||
if(soundDebug) {
|
||||
log("*** Sound Init Complete ***\n");
|
||||
}
|
||||
#endif
|
||||
int addr = 0xff30;
|
||||
|
||||
while(addr < 0xff40) {
|
||||
gbMemory[addr++] = 0x00;
|
||||
gbMemory[addr++] = 0xff;
|
||||
}
|
||||
}
|
||||
|
||||
extern bool soundInit();
|
||||
extern void soundShutdown();
|
||||
|
||||
void gbSoundSetQuality(int quality)
|
||||
{
|
||||
if ( soundQuality != quality )
|
||||
{
|
||||
if ( systemCanChangeSoundQuality() )
|
||||
{
|
||||
if ( !soundOffFlag )
|
||||
soundShutdown();
|
||||
|
||||
soundQuality = quality;
|
||||
soundNextPosition = 0;
|
||||
|
||||
if ( !soundOffFlag )
|
||||
soundInit();
|
||||
}
|
||||
else
|
||||
{
|
||||
soundQuality = quality;
|
||||
soundNextPosition = 0;
|
||||
}
|
||||
|
||||
remake_stereo_buffer();
|
||||
}
|
||||
}
|
||||
|
||||
static char dummy_buf [735 * 2];
|
||||
|
||||
#define SKIP( type, name ) { dummy_buf, sizeof (type) }
|
||||
|
||||
// funny expr at end ensures that type matches type of variable
|
||||
#define LOAD( type, name ) { &name, sizeof (name) + (&name - (type*) &name) }
|
||||
|
||||
static variable_desc gbsound_format [] =
|
||||
{
|
||||
SKIP( int, soundPaused ),
|
||||
SKIP( int, soundPlay ),
|
||||
SKIP( int, soundTicks ),
|
||||
SKIP( int, SOUND_CLOCK_TICKS ),
|
||||
SKIP( int, soundLevel1 ),
|
||||
SKIP( int, soundLevel2 ),
|
||||
SKIP( int, soundBalance ),
|
||||
SKIP( int, soundMasterOn ),
|
||||
SKIP( int, soundIndex ),
|
||||
SKIP( int, soundVIN ),
|
||||
SKIP( int, soundOn [0] ),
|
||||
SKIP( int, soundATL [0] ),
|
||||
SKIP( int, sound1Skip ),
|
||||
SKIP( int, soundIndex [0] ),
|
||||
SKIP( int, sound1Continue ),
|
||||
SKIP( int, soundEnvelopeVolume [0] ),
|
||||
SKIP( int, soundEnvelopeATL [0] ),
|
||||
SKIP( int, sound1EnvelopeATLReload ),
|
||||
SKIP( int, sound1EnvelopeUpDown ),
|
||||
SKIP( int, sound1SweepATL ),
|
||||
SKIP( int, sound1SweepATLReload ),
|
||||
SKIP( int, sound1SweepSteps ),
|
||||
SKIP( int, sound1SweepUpDown ),
|
||||
SKIP( int, sound1SweepStep ),
|
||||
SKIP( int, soundOn [1] ),
|
||||
SKIP( int, soundATL [1] ),
|
||||
SKIP( int, sound2Skip ),
|
||||
SKIP( int, soundIndex [1] ),
|
||||
SKIP( int, sound2Continue ),
|
||||
SKIP( int, soundEnvelopeVolume [1] ),
|
||||
SKIP( int, soundEnvelopeATL [1] ),
|
||||
SKIP( int, sound2EnvelopeATLReload ),
|
||||
SKIP( int, sound2EnvelopeUpDown ),
|
||||
SKIP( int, soundOn [2] ),
|
||||
SKIP( int, soundATL [2] ),
|
||||
SKIP( int, sound3Skip ),
|
||||
SKIP( int, soundIndex [2] ),
|
||||
SKIP( int, sound3Continue ),
|
||||
SKIP( int, sound3OutputLevel ),
|
||||
SKIP( int, soundOn [3] ),
|
||||
SKIP( int, soundATL [3] ),
|
||||
SKIP( int, sound4Skip ),
|
||||
SKIP( int, soundIndex [3] ),
|
||||
SKIP( int, sound4Clock ),
|
||||
SKIP( int, sound4ShiftRight ),
|
||||
SKIP( int, sound4ShiftSkip ),
|
||||
SKIP( int, sound4ShiftIndex ),
|
||||
SKIP( int, sound4NSteps ),
|
||||
SKIP( int, sound4CountDown ),
|
||||
SKIP( int, sound4Continue ),
|
||||
SKIP( int, soundEnvelopeVolume [2] ),
|
||||
SKIP( int, soundEnvelopeATL [2] ),
|
||||
SKIP( int, sound4EnvelopeATLReload ),
|
||||
SKIP( int, sound4EnvelopeUpDown ),
|
||||
SKIP( int, soundEnableFlag ),
|
||||
{ NULL, 0 }
|
||||
};
|
||||
|
||||
static variable_desc gbsound_format2 [] =
|
||||
{
|
||||
SKIP( int, sound1ATLreload ),
|
||||
SKIP( int, freq1low ),
|
||||
SKIP( int, freq1high ),
|
||||
SKIP( int, sound2ATLreload ),
|
||||
SKIP( int, freq2low ),
|
||||
SKIP( int, freq2high ),
|
||||
SKIP( int, sound3ATLreload ),
|
||||
SKIP( int, freq3low ),
|
||||
SKIP( int, freq3high ),
|
||||
SKIP( int, sound4ATLreload ),
|
||||
SKIP( int, freq4 ),
|
||||
{ NULL, 0 }
|
||||
};
|
||||
|
||||
static variable_desc gbsound_format3 [] =
|
||||
{
|
||||
SKIP( u8[2*735], soundBuffer ),
|
||||
SKIP( u8[2*735], soundBuffer ),
|
||||
SKIP( u16[735], soundFinalWave ),
|
||||
{ NULL, 0 }
|
||||
};
|
||||
|
||||
void gbSoundSaveGame(gzFile gzFile)
|
||||
{
|
||||
// TODO: implement
|
||||
}
|
||||
|
||||
enum {
|
||||
nr10 = 0,
|
||||
nr11, nr12, nr13, nr14,
|
||||
nr20, nr21, nr22, nr23, nr24,
|
||||
nr30, nr31, nr32, nr33, nr34,
|
||||
nr40, nr41, nr42, nr43, nr44,
|
||||
nr50, nr51, nr52
|
||||
};
|
||||
|
||||
void gbSoundReadGame(int version,gzFile gzFile)
|
||||
{
|
||||
return; // TODO: apparently GB save states don't work in the main emulator
|
||||
|
||||
// Load state
|
||||
utilReadData( gzFile, gbsound_format );
|
||||
|
||||
if ( version >= 11 )
|
||||
utilReadData( gzFile, gbsound_format2 );
|
||||
|
||||
utilReadData( gzFile, gbsound_format3 );
|
||||
|
||||
int quality = 1;
|
||||
if ( version >= 7 )
|
||||
quality = utilReadInt( gzFile );
|
||||
|
||||
gbSoundSetQuality( quality );
|
||||
|
||||
// Convert to format Gb_Apu uses
|
||||
reset_apu();
|
||||
gb_apu_state_t s;
|
||||
gb_apu->save_state( &s ); // use fresh values for anything not restored
|
||||
|
||||
// Only some registers are properly preserved
|
||||
static int const regs_to_copy [] = {
|
||||
nr10, nr11, nr12, nr21, nr22, nr30, nr32, nr42, nr43, nr50, nr51, nr52, -1
|
||||
};
|
||||
for ( int i = 0; regs_to_copy [i] >= 0; i++ )
|
||||
s.regs [regs_to_copy [i]] = gbMemory [0xFF10 + regs_to_copy [i]];
|
||||
|
||||
memcpy( &s.regs [0x20], &gbMemory [0xFF30], 0x10 ); // wave
|
||||
|
||||
gb_apu->load_state( s );
|
||||
}
|
||||
|
|
|
@ -1,74 +1,74 @@
|
|||
// -*- C++ -*-
|
||||
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
|
||||
// Copyright (C) 1999-2003 Forgotten
|
||||
// Copyright (C) 2004 Forgotten and the VBA development team
|
||||
|
||||
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
#define NR10 0xff10
|
||||
#define NR11 0xff11
|
||||
#define NR12 0xff12
|
||||
#define NR13 0xff13
|
||||
#define NR14 0xff14
|
||||
#define NR21 0xff16
|
||||
#define NR22 0xff17
|
||||
#define NR23 0xff18
|
||||
#define NR24 0xff19
|
||||
#define NR30 0xff1a
|
||||
#define NR31 0xff1b
|
||||
#define NR32 0xff1c
|
||||
#define NR33 0xff1d
|
||||
#define NR34 0xff1e
|
||||
#define NR41 0xff20
|
||||
#define NR42 0xff21
|
||||
#define NR43 0xff22
|
||||
#define NR44 0xff23
|
||||
#define NR50 0xff24
|
||||
#define NR51 0xff25
|
||||
#define NR52 0xff26
|
||||
|
||||
#define SOUND_EVENT(address,value) \
|
||||
gbSoundEvent(address,value)
|
||||
|
||||
extern void gbSoundTick();
|
||||
extern void gbSoundPause();
|
||||
extern void gbSoundResume();
|
||||
extern void gbSoundEnable(int);
|
||||
extern void gbSoundDisable(int);
|
||||
extern int gbSoundGetEnable();
|
||||
extern void gbSoundReset();
|
||||
extern void gbSoundSaveGame(gzFile);
|
||||
extern void gbSoundReadGame(int,gzFile);
|
||||
extern void gbSoundEvent(register u16, register int);
|
||||
extern void gbSoundSetQuality(int);
|
||||
|
||||
extern u8 gbSoundRead(u16 address);
|
||||
|
||||
extern int soundTicks;
|
||||
extern int soundQuality;
|
||||
extern int SOUND_CLOCK_TICKS;
|
||||
|
||||
struct gb_effects_config_t
|
||||
{
|
||||
bool enabled; // false = disable all effects
|
||||
|
||||
float echo; // 0.0 = none, 1.0 = lots
|
||||
float stereo; // 0.0 = channels in center, 1.0 = channels on left/right
|
||||
bool surround; // true = put some channels in back
|
||||
};
|
||||
|
||||
// Can be changed at any time, probably from another thread too.
|
||||
// Sound will notice changes during next 1/100 second.
|
||||
extern gb_effects_config_t gb_effects_config;
|
||||
// -*- C++ -*-
|
||||
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
|
||||
// Copyright (C) 1999-2003 Forgotten
|
||||
// Copyright (C) 2004 Forgotten and the VBA development team
|
||||
|
||||
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
#define NR10 0xff10
|
||||
#define NR11 0xff11
|
||||
#define NR12 0xff12
|
||||
#define NR13 0xff13
|
||||
#define NR14 0xff14
|
||||
#define NR21 0xff16
|
||||
#define NR22 0xff17
|
||||
#define NR23 0xff18
|
||||
#define NR24 0xff19
|
||||
#define NR30 0xff1a
|
||||
#define NR31 0xff1b
|
||||
#define NR32 0xff1c
|
||||
#define NR33 0xff1d
|
||||
#define NR34 0xff1e
|
||||
#define NR41 0xff20
|
||||
#define NR42 0xff21
|
||||
#define NR43 0xff22
|
||||
#define NR44 0xff23
|
||||
#define NR50 0xff24
|
||||
#define NR51 0xff25
|
||||
#define NR52 0xff26
|
||||
|
||||
#define SOUND_EVENT(address,value) \
|
||||
gbSoundEvent(address,value)
|
||||
|
||||
extern void gbSoundTick();
|
||||
extern void gbSoundPause();
|
||||
extern void gbSoundResume();
|
||||
extern void gbSoundEnable(int);
|
||||
extern void gbSoundDisable(int);
|
||||
extern int gbSoundGetEnable();
|
||||
extern void gbSoundReset();
|
||||
extern void gbSoundSaveGame(gzFile);
|
||||
extern void gbSoundReadGame(int,gzFile);
|
||||
extern void gbSoundEvent(register u16, register int);
|
||||
extern void gbSoundSetQuality(int);
|
||||
|
||||
extern u8 gbSoundRead(u16 address);
|
||||
|
||||
extern int soundTicks;
|
||||
extern int soundQuality;
|
||||
extern int SOUND_CLOCK_TICKS;
|
||||
|
||||
struct gb_effects_config_t
|
||||
{
|
||||
bool enabled; // false = disable all effects
|
||||
|
||||
float echo; // 0.0 = none, 1.0 = lots
|
||||
float stereo; // 0.0 = channels in center, 1.0 = channels on left/right
|
||||
bool surround; // true = put some channels in back
|
||||
};
|
||||
|
||||
// Can be changed at any time, probably from another thread too.
|
||||
// Sound will notice changes during next 1/100 second.
|
||||
extern gb_effects_config_t gb_effects_config;
|
||||
|
|
|
@ -1,465 +1,465 @@
|
|||
// Blip_Buffer 0.4.1. http://www.slack.net/~ant/
|
||||
|
||||
#include "Blip_Buffer.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <limits.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
|
||||
/* Copyright (C) 2003-2007 Shay Green. This module is free software; you
|
||||
can redistribute it and/or modify it under the terms of the GNU Lesser
|
||||
General Public License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version. This
|
||||
module is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
|
||||
details. You should have received a copy of the GNU Lesser General Public
|
||||
License along with this module; if not, write to the Free Software Foundation,
|
||||
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
|
||||
|
||||
// TODO: use scoped for variables in treble_eq()
|
||||
|
||||
#ifdef BLARGG_ENABLE_OPTIMIZER
|
||||
#include BLARGG_ENABLE_OPTIMIZER
|
||||
#endif
|
||||
|
||||
int const silent_buf_size = 1; // size used for Silent_Blip_Buffer
|
||||
|
||||
Blip_Buffer::Blip_Buffer()
|
||||
{
|
||||
factor_ = LONG_MAX;
|
||||
buffer_ = 0;
|
||||
buffer_size_ = 0;
|
||||
sample_rate_ = 0;
|
||||
bass_shift_ = 0;
|
||||
clock_rate_ = 0;
|
||||
bass_freq_ = 16;
|
||||
length_ = 0;
|
||||
|
||||
// assumptions code makes about implementation-defined features
|
||||
#ifndef NDEBUG
|
||||
// right shift of negative value preserves sign
|
||||
buf_t_ i = -0x7FFFFFFE;
|
||||
assert( (i >> 1) == -0x3FFFFFFF );
|
||||
|
||||
// casting to short truncates to 16 bits and sign-extends
|
||||
i = 0x18000;
|
||||
assert( (short) i == -0x8000 );
|
||||
#endif
|
||||
|
||||
clear();
|
||||
}
|
||||
|
||||
Blip_Buffer::~Blip_Buffer()
|
||||
{
|
||||
if ( buffer_size_ != silent_buf_size )
|
||||
free( buffer_ );
|
||||
}
|
||||
|
||||
Silent_Blip_Buffer::Silent_Blip_Buffer()
|
||||
{
|
||||
factor_ = 0;
|
||||
buffer_ = buf;
|
||||
buffer_size_ = silent_buf_size;
|
||||
clear();
|
||||
}
|
||||
|
||||
void Blip_Buffer::clear( int entire_buffer )
|
||||
{
|
||||
offset_ = 0;
|
||||
reader_accum_ = 0;
|
||||
modified_ = 0;
|
||||
if ( buffer_ )
|
||||
{
|
||||
long count = (entire_buffer ? buffer_size_ : samples_avail());
|
||||
memset( buffer_, 0, (count + blip_buffer_extra_) * sizeof (buf_t_) );
|
||||
}
|
||||
}
|
||||
|
||||
Blip_Buffer::blargg_err_t Blip_Buffer::set_sample_rate( long new_rate, int msec )
|
||||
{
|
||||
if ( buffer_size_ == silent_buf_size )
|
||||
{
|
||||
assert( 0 );
|
||||
return "Internal (tried to resize Silent_Blip_Buffer)";
|
||||
}
|
||||
|
||||
// start with maximum length that resampled time can represent
|
||||
long new_size = (ULONG_MAX >> BLIP_BUFFER_ACCURACY) - blip_buffer_extra_ - 64;
|
||||
if ( msec != blip_max_length )
|
||||
{
|
||||
long s = (new_rate * (msec + 1) + 999) / 1000;
|
||||
if ( s < new_size )
|
||||
new_size = s;
|
||||
else
|
||||
assert( 0 ); // fails if requested buffer length exceeds limit
|
||||
}
|
||||
|
||||
if ( buffer_size_ != new_size )
|
||||
{
|
||||
void* p = realloc( buffer_, (new_size + blip_buffer_extra_) * sizeof *buffer_ );
|
||||
if ( !p )
|
||||
return "Out of memory";
|
||||
buffer_ = (buf_t_*) p;
|
||||
}
|
||||
|
||||
buffer_size_ = new_size;
|
||||
assert( buffer_size_ != silent_buf_size ); // size should never happen to match this
|
||||
|
||||
// update things based on the sample rate
|
||||
sample_rate_ = new_rate;
|
||||
length_ = new_size * 1000 / new_rate - 1;
|
||||
if ( msec )
|
||||
assert( length_ == msec ); // ensure length is same as that passed in
|
||||
|
||||
// update these since they depend on sample rate
|
||||
if ( clock_rate_ )
|
||||
clock_rate( clock_rate_ );
|
||||
bass_freq( bass_freq_ );
|
||||
|
||||
clear();
|
||||
|
||||
return 0; // success
|
||||
}
|
||||
|
||||
blip_resampled_time_t Blip_Buffer::clock_rate_factor( long rate ) const
|
||||
{
|
||||
double ratio = (double) sample_rate_ / rate;
|
||||
blip_long factor = (blip_long) floor( ratio * (1L << BLIP_BUFFER_ACCURACY) + 0.5 );
|
||||
assert( factor > 0 || !sample_rate_ ); // fails if clock/output ratio is too large
|
||||
return (blip_resampled_time_t) factor;
|
||||
}
|
||||
|
||||
void Blip_Buffer::bass_freq( int freq )
|
||||
{
|
||||
bass_freq_ = freq;
|
||||
int shift = 31;
|
||||
if ( freq > 0 )
|
||||
{
|
||||
shift = 13;
|
||||
long f = (freq << 16) / sample_rate_;
|
||||
while ( (f >>= 1) && --shift ) { }
|
||||
}
|
||||
bass_shift_ = shift;
|
||||
}
|
||||
|
||||
void Blip_Buffer::end_frame( blip_time_t t )
|
||||
{
|
||||
offset_ += t * factor_;
|
||||
assert( samples_avail() <= (long) buffer_size_ ); // fails if time is past end of buffer
|
||||
}
|
||||
|
||||
long Blip_Buffer::count_samples( blip_time_t t ) const
|
||||
{
|
||||
blip_resampled_time_t last_sample = resampled_time( t ) >> BLIP_BUFFER_ACCURACY;
|
||||
blip_resampled_time_t first_sample = offset_ >> BLIP_BUFFER_ACCURACY;
|
||||
return long (last_sample - first_sample);
|
||||
}
|
||||
|
||||
blip_time_t Blip_Buffer::count_clocks( long count ) const
|
||||
{
|
||||
if ( !factor_ )
|
||||
{
|
||||
assert( 0 ); // sample rate and clock rates must be set first
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ( count > buffer_size_ )
|
||||
count = buffer_size_;
|
||||
blip_resampled_time_t time = (blip_resampled_time_t) count << BLIP_BUFFER_ACCURACY;
|
||||
return (blip_time_t) ((time - offset_ + factor_ - 1) / factor_);
|
||||
}
|
||||
|
||||
void Blip_Buffer::remove_samples( long count )
|
||||
{
|
||||
if ( count )
|
||||
{
|
||||
remove_silence( count );
|
||||
|
||||
// copy remaining samples to beginning and clear old samples
|
||||
long remain = samples_avail() + blip_buffer_extra_;
|
||||
memmove( buffer_, buffer_ + count, remain * sizeof *buffer_ );
|
||||
memset( buffer_ + remain, 0, count * sizeof *buffer_ );
|
||||
}
|
||||
}
|
||||
|
||||
// Blip_Synth_
|
||||
|
||||
Blip_Synth_Fast_::Blip_Synth_Fast_()
|
||||
{
|
||||
buf = 0;
|
||||
last_amp = 0;
|
||||
delta_factor = 0;
|
||||
}
|
||||
|
||||
void Blip_Synth_Fast_::volume_unit( double new_unit )
|
||||
{
|
||||
delta_factor = int (new_unit * (1L << blip_sample_bits) + 0.5);
|
||||
}
|
||||
|
||||
#if !BLIP_BUFFER_FAST
|
||||
|
||||
Blip_Synth_::Blip_Synth_( short* p, int w ) :
|
||||
impulses( p ),
|
||||
width( w )
|
||||
{
|
||||
volume_unit_ = 0.0;
|
||||
kernel_unit = 0;
|
||||
buf = 0;
|
||||
last_amp = 0;
|
||||
delta_factor = 0;
|
||||
}
|
||||
|
||||
#undef PI
|
||||
#define PI 3.1415926535897932384626433832795029
|
||||
|
||||
static void gen_sinc( float* out, int count, double oversample, double treble, double cutoff )
|
||||
{
|
||||
if ( cutoff >= 0.999 )
|
||||
cutoff = 0.999;
|
||||
|
||||
if ( treble < -300.0 )
|
||||
treble = -300.0;
|
||||
if ( treble > 5.0 )
|
||||
treble = 5.0;
|
||||
|
||||
double const maxh = 4096.0;
|
||||
double const rolloff = pow( 10.0, 1.0 / (maxh * 20.0) * treble / (1.0 - cutoff) );
|
||||
double const pow_a_n = pow( rolloff, maxh - maxh * cutoff );
|
||||
double const to_angle = PI / 2 / maxh / oversample;
|
||||
for ( int i = 0; i < count; i++ )
|
||||
{
|
||||
double angle = ((i - count) * 2 + 1) * to_angle;
|
||||
double c = rolloff * cos( (maxh - 1.0) * angle ) - cos( maxh * angle );
|
||||
double cos_nc_angle = cos( maxh * cutoff * angle );
|
||||
double cos_nc1_angle = cos( (maxh * cutoff - 1.0) * angle );
|
||||
double cos_angle = cos( angle );
|
||||
|
||||
c = c * pow_a_n - rolloff * cos_nc1_angle + cos_nc_angle;
|
||||
double d = 1.0 + rolloff * (rolloff - cos_angle - cos_angle);
|
||||
double b = 2.0 - cos_angle - cos_angle;
|
||||
double a = 1.0 - cos_angle - cos_nc_angle + cos_nc1_angle;
|
||||
|
||||
out [i] = (float) ((a * d + c * b) / (b * d)); // a / b + c / d
|
||||
}
|
||||
}
|
||||
|
||||
void blip_eq_t::generate( float* out, int count ) const
|
||||
{
|
||||
// lower cutoff freq for narrow kernels with their wider transition band
|
||||
// (8 points->1.49, 16 points->1.15)
|
||||
double oversample = blip_res * 2.25 / count + 0.85;
|
||||
double half_rate = sample_rate * 0.5;
|
||||
if ( cutoff_freq )
|
||||
oversample = half_rate / cutoff_freq;
|
||||
double cutoff = rolloff_freq * oversample / half_rate;
|
||||
|
||||
gen_sinc( out, count, blip_res * oversample, treble, cutoff );
|
||||
|
||||
// apply (half of) hamming window
|
||||
double to_fraction = PI / (count - 1);
|
||||
for ( int i = count; i--; )
|
||||
out [i] *= 0.54f - 0.46f * (float) cos( i * to_fraction );
|
||||
}
|
||||
|
||||
void Blip_Synth_::adjust_impulse()
|
||||
{
|
||||
// sum pairs for each phase and add error correction to end of first half
|
||||
int const size = impulses_size();
|
||||
for ( int p = blip_res; p-- >= blip_res / 2; )
|
||||
{
|
||||
int p2 = blip_res - 2 - p;
|
||||
long error = kernel_unit;
|
||||
for ( int i = 1; i < size; i += blip_res )
|
||||
{
|
||||
error -= impulses [i + p ];
|
||||
error -= impulses [i + p2];
|
||||
}
|
||||
if ( p == p2 )
|
||||
error /= 2; // phase = 0.5 impulse uses same half for both sides
|
||||
impulses [size - blip_res + p] += (short) error;
|
||||
//printf( "error: %ld\n", error );
|
||||
}
|
||||
|
||||
//for ( int i = blip_res; i--; printf( "\n" ) )
|
||||
// for ( int j = 0; j < width / 2; j++ )
|
||||
// printf( "%5ld,", impulses [j * blip_res + i + 1] );
|
||||
}
|
||||
|
||||
void Blip_Synth_::treble_eq( blip_eq_t const& eq )
|
||||
{
|
||||
float fimpulse [blip_res / 2 * (blip_widest_impulse_ - 1) + blip_res * 2];
|
||||
|
||||
int const half_size = blip_res / 2 * (width - 1);
|
||||
eq.generate( &fimpulse [blip_res], half_size );
|
||||
|
||||
int i;
|
||||
|
||||
// need mirror slightly past center for calculation
|
||||
for ( i = blip_res; i--; )
|
||||
fimpulse [blip_res + half_size + i] = fimpulse [blip_res + half_size - 1 - i];
|
||||
|
||||
// starts at 0
|
||||
for ( i = 0; i < blip_res; i++ )
|
||||
fimpulse [i] = 0.0f;
|
||||
|
||||
// find rescale factor
|
||||
double total = 0.0;
|
||||
for ( i = 0; i < half_size; i++ )
|
||||
total += fimpulse [blip_res + i];
|
||||
|
||||
//double const base_unit = 44800.0 - 128 * 18; // allows treble up to +0 dB
|
||||
//double const base_unit = 37888.0; // allows treble to +5 dB
|
||||
double const base_unit = 32768.0; // necessary for blip_unscaled to work
|
||||
double rescale = base_unit / 2 / total;
|
||||
kernel_unit = (long) base_unit;
|
||||
|
||||
// integrate, first difference, rescale, convert to int
|
||||
double sum = 0.0;
|
||||
double next = 0.0;
|
||||
int const size = this->impulses_size();
|
||||
for ( i = 0; i < size; i++ )
|
||||
{
|
||||
impulses [i] = (short) (int) floor( (next - sum) * rescale + 0.5 );
|
||||
sum += fimpulse [i];
|
||||
next += fimpulse [i + blip_res];
|
||||
}
|
||||
adjust_impulse();
|
||||
|
||||
// volume might require rescaling
|
||||
double vol = volume_unit_;
|
||||
if ( vol )
|
||||
{
|
||||
volume_unit_ = 0.0;
|
||||
volume_unit( vol );
|
||||
}
|
||||
}
|
||||
|
||||
void Blip_Synth_::volume_unit( double new_unit )
|
||||
{
|
||||
if ( new_unit != volume_unit_ )
|
||||
{
|
||||
// use default eq if it hasn't been set yet
|
||||
if ( !kernel_unit )
|
||||
treble_eq( -8.0 );
|
||||
|
||||
volume_unit_ = new_unit;
|
||||
double factor = new_unit * (1L << blip_sample_bits) / kernel_unit;
|
||||
|
||||
if ( factor > 0.0 )
|
||||
{
|
||||
int shift = 0;
|
||||
|
||||
// if unit is really small, might need to attenuate kernel
|
||||
while ( factor < 2.0 )
|
||||
{
|
||||
shift++;
|
||||
factor *= 2.0;
|
||||
}
|
||||
|
||||
if ( shift )
|
||||
{
|
||||
kernel_unit >>= shift;
|
||||
assert( kernel_unit > 0 ); // fails if volume unit is too low
|
||||
|
||||
// keep values positive to avoid round-towards-zero of sign-preserving
|
||||
// right shift for negative values
|
||||
long offset = 0x8000 + (1 << (shift - 1));
|
||||
long offset2 = 0x8000 >> shift;
|
||||
for ( int i = impulses_size(); i--; )
|
||||
impulses [i] = (short) (int) (((impulses [i] + offset) >> shift) - offset2);
|
||||
adjust_impulse();
|
||||
}
|
||||
}
|
||||
delta_factor = (int) floor( factor + 0.5 );
|
||||
//printf( "delta_factor: %d, kernel_unit: %d\n", delta_factor, kernel_unit );
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
long Blip_Buffer::read_samples( blip_sample_t* out_, long max_samples, int stereo )
|
||||
{
|
||||
long count = samples_avail();
|
||||
if ( count > max_samples )
|
||||
count = max_samples;
|
||||
|
||||
if ( count )
|
||||
{
|
||||
int const bass = BLIP_READER_BASS( *this );
|
||||
BLIP_READER_BEGIN( reader, *this );
|
||||
BLIP_READER_ADJ_( reader, count );
|
||||
blip_sample_t* BLIP_RESTRICT out = out_ + count;
|
||||
blip_long offset = (blip_long) -count;
|
||||
|
||||
if ( !stereo )
|
||||
{
|
||||
do
|
||||
{
|
||||
blip_long s = BLIP_READER_READ( reader );
|
||||
BLIP_READER_NEXT_IDX_( reader, bass, offset );
|
||||
BLIP_CLAMP( s, s );
|
||||
out [offset] = (blip_sample_t) s;
|
||||
}
|
||||
while ( ++offset );
|
||||
}
|
||||
else
|
||||
{
|
||||
do
|
||||
{
|
||||
blip_long s = BLIP_READER_READ( reader );
|
||||
BLIP_READER_NEXT_IDX_( reader, bass, offset );
|
||||
BLIP_CLAMP( s, s );
|
||||
out [offset * 2] = (blip_sample_t) s;
|
||||
}
|
||||
while ( ++offset );
|
||||
}
|
||||
|
||||
BLIP_READER_END( reader, *this );
|
||||
|
||||
remove_samples( count );
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
void Blip_Buffer::mix_samples( blip_sample_t const* in, long count )
|
||||
{
|
||||
if ( buffer_size_ == silent_buf_size )
|
||||
{
|
||||
assert( 0 );
|
||||
return;
|
||||
}
|
||||
|
||||
buf_t_* out = buffer_ + (offset_ >> BLIP_BUFFER_ACCURACY) + blip_widest_impulse_ / 2;
|
||||
|
||||
int const sample_shift = blip_sample_bits - 16;
|
||||
int prev = 0;
|
||||
while ( count-- )
|
||||
{
|
||||
blip_long s = (blip_long) *in++ << sample_shift;
|
||||
*out += s - prev;
|
||||
prev = s;
|
||||
++out;
|
||||
}
|
||||
*out -= prev;
|
||||
}
|
||||
|
||||
blip_ulong const subsample_mask = (1L << BLIP_BUFFER_ACCURACY) - 1;
|
||||
|
||||
void Blip_Buffer::save_state( blip_buffer_state_t* out )
|
||||
{
|
||||
assert( samples_avail() == 0 );
|
||||
out->offset_ = offset_;
|
||||
out->reader_accum_ = reader_accum_;
|
||||
memcpy( out->buf, &buffer_ [offset_ >> BLIP_BUFFER_ACCURACY], sizeof out->buf );
|
||||
}
|
||||
|
||||
void Blip_Buffer::load_state( blip_buffer_state_t const& in )
|
||||
{
|
||||
clear( false );
|
||||
|
||||
offset_ = in.offset_;
|
||||
reader_accum_ = in.reader_accum_;
|
||||
memcpy( buffer_, in.buf, sizeof in.buf );
|
||||
}
|
||||
// Blip_Buffer 0.4.1. http://www.slack.net/~ant/
|
||||
|
||||
#include "Blip_Buffer.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <limits.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
|
||||
/* Copyright (C) 2003-2007 Shay Green. This module is free software; you
|
||||
can redistribute it and/or modify it under the terms of the GNU Lesser
|
||||
General Public License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version. This
|
||||
module is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
|
||||
details. You should have received a copy of the GNU Lesser General Public
|
||||
License along with this module; if not, write to the Free Software Foundation,
|
||||
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
|
||||
|
||||
// TODO: use scoped for variables in treble_eq()
|
||||
|
||||
#ifdef BLARGG_ENABLE_OPTIMIZER
|
||||
#include BLARGG_ENABLE_OPTIMIZER
|
||||
#endif
|
||||
|
||||
int const silent_buf_size = 1; // size used for Silent_Blip_Buffer
|
||||
|
||||
Blip_Buffer::Blip_Buffer()
|
||||
{
|
||||
factor_ = LONG_MAX;
|
||||
buffer_ = 0;
|
||||
buffer_size_ = 0;
|
||||
sample_rate_ = 0;
|
||||
bass_shift_ = 0;
|
||||
clock_rate_ = 0;
|
||||
bass_freq_ = 16;
|
||||
length_ = 0;
|
||||
|
||||
// assumptions code makes about implementation-defined features
|
||||
#ifndef NDEBUG
|
||||
// right shift of negative value preserves sign
|
||||
buf_t_ i = -0x7FFFFFFE;
|
||||
assert( (i >> 1) == -0x3FFFFFFF );
|
||||
|
||||
// casting to short truncates to 16 bits and sign-extends
|
||||
i = 0x18000;
|
||||
assert( (short) i == -0x8000 );
|
||||
#endif
|
||||
|
||||
clear();
|
||||
}
|
||||
|
||||
Blip_Buffer::~Blip_Buffer()
|
||||
{
|
||||
if ( buffer_size_ != silent_buf_size )
|
||||
free( buffer_ );
|
||||
}
|
||||
|
||||
Silent_Blip_Buffer::Silent_Blip_Buffer()
|
||||
{
|
||||
factor_ = 0;
|
||||
buffer_ = buf;
|
||||
buffer_size_ = silent_buf_size;
|
||||
clear();
|
||||
}
|
||||
|
||||
void Blip_Buffer::clear( int entire_buffer )
|
||||
{
|
||||
offset_ = 0;
|
||||
reader_accum_ = 0;
|
||||
modified_ = 0;
|
||||
if ( buffer_ )
|
||||
{
|
||||
long count = (entire_buffer ? buffer_size_ : samples_avail());
|
||||
memset( buffer_, 0, (count + blip_buffer_extra_) * sizeof (buf_t_) );
|
||||
}
|
||||
}
|
||||
|
||||
Blip_Buffer::blargg_err_t Blip_Buffer::set_sample_rate( long new_rate, int msec )
|
||||
{
|
||||
if ( buffer_size_ == silent_buf_size )
|
||||
{
|
||||
assert( 0 );
|
||||
return "Internal (tried to resize Silent_Blip_Buffer)";
|
||||
}
|
||||
|
||||
// start with maximum length that resampled time can represent
|
||||
long new_size = (ULONG_MAX >> BLIP_BUFFER_ACCURACY) - blip_buffer_extra_ - 64;
|
||||
if ( msec != blip_max_length )
|
||||
{
|
||||
long s = (new_rate * (msec + 1) + 999) / 1000;
|
||||
if ( s < new_size )
|
||||
new_size = s;
|
||||
else
|
||||
assert( 0 ); // fails if requested buffer length exceeds limit
|
||||
}
|
||||
|
||||
if ( buffer_size_ != new_size )
|
||||
{
|
||||
void* p = realloc( buffer_, (new_size + blip_buffer_extra_) * sizeof *buffer_ );
|
||||
if ( !p )
|
||||
return "Out of memory";
|
||||
buffer_ = (buf_t_*) p;
|
||||
}
|
||||
|
||||
buffer_size_ = new_size;
|
||||
assert( buffer_size_ != silent_buf_size ); // size should never happen to match this
|
||||
|
||||
// update things based on the sample rate
|
||||
sample_rate_ = new_rate;
|
||||
length_ = new_size * 1000 / new_rate - 1;
|
||||
if ( msec )
|
||||
assert( length_ == msec ); // ensure length is same as that passed in
|
||||
|
||||
// update these since they depend on sample rate
|
||||
if ( clock_rate_ )
|
||||
clock_rate( clock_rate_ );
|
||||
bass_freq( bass_freq_ );
|
||||
|
||||
clear();
|
||||
|
||||
return 0; // success
|
||||
}
|
||||
|
||||
blip_resampled_time_t Blip_Buffer::clock_rate_factor( long rate ) const
|
||||
{
|
||||
double ratio = (double) sample_rate_ / rate;
|
||||
blip_long factor = (blip_long) floor( ratio * (1L << BLIP_BUFFER_ACCURACY) + 0.5 );
|
||||
assert( factor > 0 || !sample_rate_ ); // fails if clock/output ratio is too large
|
||||
return (blip_resampled_time_t) factor;
|
||||
}
|
||||
|
||||
void Blip_Buffer::bass_freq( int freq )
|
||||
{
|
||||
bass_freq_ = freq;
|
||||
int shift = 31;
|
||||
if ( freq > 0 )
|
||||
{
|
||||
shift = 13;
|
||||
long f = (freq << 16) / sample_rate_;
|
||||
while ( (f >>= 1) && --shift ) { }
|
||||
}
|
||||
bass_shift_ = shift;
|
||||
}
|
||||
|
||||
void Blip_Buffer::end_frame( blip_time_t t )
|
||||
{
|
||||
offset_ += t * factor_;
|
||||
assert( samples_avail() <= (long) buffer_size_ ); // fails if time is past end of buffer
|
||||
}
|
||||
|
||||
long Blip_Buffer::count_samples( blip_time_t t ) const
|
||||
{
|
||||
blip_resampled_time_t last_sample = resampled_time( t ) >> BLIP_BUFFER_ACCURACY;
|
||||
blip_resampled_time_t first_sample = offset_ >> BLIP_BUFFER_ACCURACY;
|
||||
return long (last_sample - first_sample);
|
||||
}
|
||||
|
||||
blip_time_t Blip_Buffer::count_clocks( long count ) const
|
||||
{
|
||||
if ( !factor_ )
|
||||
{
|
||||
assert( 0 ); // sample rate and clock rates must be set first
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ( count > buffer_size_ )
|
||||
count = buffer_size_;
|
||||
blip_resampled_time_t time = (blip_resampled_time_t) count << BLIP_BUFFER_ACCURACY;
|
||||
return (blip_time_t) ((time - offset_ + factor_ - 1) / factor_);
|
||||
}
|
||||
|
||||
void Blip_Buffer::remove_samples( long count )
|
||||
{
|
||||
if ( count )
|
||||
{
|
||||
remove_silence( count );
|
||||
|
||||
// copy remaining samples to beginning and clear old samples
|
||||
long remain = samples_avail() + blip_buffer_extra_;
|
||||
memmove( buffer_, buffer_ + count, remain * sizeof *buffer_ );
|
||||
memset( buffer_ + remain, 0, count * sizeof *buffer_ );
|
||||
}
|
||||
}
|
||||
|
||||
// Blip_Synth_
|
||||
|
||||
Blip_Synth_Fast_::Blip_Synth_Fast_()
|
||||
{
|
||||
buf = 0;
|
||||
last_amp = 0;
|
||||
delta_factor = 0;
|
||||
}
|
||||
|
||||
void Blip_Synth_Fast_::volume_unit( double new_unit )
|
||||
{
|
||||
delta_factor = int (new_unit * (1L << blip_sample_bits) + 0.5);
|
||||
}
|
||||
|
||||
#if !BLIP_BUFFER_FAST
|
||||
|
||||
Blip_Synth_::Blip_Synth_( short* p, int w ) :
|
||||
impulses( p ),
|
||||
width( w )
|
||||
{
|
||||
volume_unit_ = 0.0;
|
||||
kernel_unit = 0;
|
||||
buf = 0;
|
||||
last_amp = 0;
|
||||
delta_factor = 0;
|
||||
}
|
||||
|
||||
#undef PI
|
||||
#define PI 3.1415926535897932384626433832795029
|
||||
|
||||
static void gen_sinc( float* out, int count, double oversample, double treble, double cutoff )
|
||||
{
|
||||
if ( cutoff >= 0.999 )
|
||||
cutoff = 0.999;
|
||||
|
||||
if ( treble < -300.0 )
|
||||
treble = -300.0;
|
||||
if ( treble > 5.0 )
|
||||
treble = 5.0;
|
||||
|
||||
double const maxh = 4096.0;
|
||||
double const rolloff = pow( 10.0, 1.0 / (maxh * 20.0) * treble / (1.0 - cutoff) );
|
||||
double const pow_a_n = pow( rolloff, maxh - maxh * cutoff );
|
||||
double const to_angle = PI / 2 / maxh / oversample;
|
||||
for ( int i = 0; i < count; i++ )
|
||||
{
|
||||
double angle = ((i - count) * 2 + 1) * to_angle;
|
||||
double c = rolloff * cos( (maxh - 1.0) * angle ) - cos( maxh * angle );
|
||||
double cos_nc_angle = cos( maxh * cutoff * angle );
|
||||
double cos_nc1_angle = cos( (maxh * cutoff - 1.0) * angle );
|
||||
double cos_angle = cos( angle );
|
||||
|
||||
c = c * pow_a_n - rolloff * cos_nc1_angle + cos_nc_angle;
|
||||
double d = 1.0 + rolloff * (rolloff - cos_angle - cos_angle);
|
||||
double b = 2.0 - cos_angle - cos_angle;
|
||||
double a = 1.0 - cos_angle - cos_nc_angle + cos_nc1_angle;
|
||||
|
||||
out [i] = (float) ((a * d + c * b) / (b * d)); // a / b + c / d
|
||||
}
|
||||
}
|
||||
|
||||
void blip_eq_t::generate( float* out, int count ) const
|
||||
{
|
||||
// lower cutoff freq for narrow kernels with their wider transition band
|
||||
// (8 points->1.49, 16 points->1.15)
|
||||
double oversample = blip_res * 2.25 / count + 0.85;
|
||||
double half_rate = sample_rate * 0.5;
|
||||
if ( cutoff_freq )
|
||||
oversample = half_rate / cutoff_freq;
|
||||
double cutoff = rolloff_freq * oversample / half_rate;
|
||||
|
||||
gen_sinc( out, count, blip_res * oversample, treble, cutoff );
|
||||
|
||||
// apply (half of) hamming window
|
||||
double to_fraction = PI / (count - 1);
|
||||
for ( int i = count; i--; )
|
||||
out [i] *= 0.54f - 0.46f * (float) cos( i * to_fraction );
|
||||
}
|
||||
|
||||
void Blip_Synth_::adjust_impulse()
|
||||
{
|
||||
// sum pairs for each phase and add error correction to end of first half
|
||||
int const size = impulses_size();
|
||||
for ( int p = blip_res; p-- >= blip_res / 2; )
|
||||
{
|
||||
int p2 = blip_res - 2 - p;
|
||||
long error = kernel_unit;
|
||||
for ( int i = 1; i < size; i += blip_res )
|
||||
{
|
||||
error -= impulses [i + p ];
|
||||
error -= impulses [i + p2];
|
||||
}
|
||||
if ( p == p2 )
|
||||
error /= 2; // phase = 0.5 impulse uses same half for both sides
|
||||
impulses [size - blip_res + p] += (short) error;
|
||||
//printf( "error: %ld\n", error );
|
||||
}
|
||||
|
||||
//for ( int i = blip_res; i--; printf( "\n" ) )
|
||||
// for ( int j = 0; j < width / 2; j++ )
|
||||
// printf( "%5ld,", impulses [j * blip_res + i + 1] );
|
||||
}
|
||||
|
||||
void Blip_Synth_::treble_eq( blip_eq_t const& eq )
|
||||
{
|
||||
float fimpulse [blip_res / 2 * (blip_widest_impulse_ - 1) + blip_res * 2];
|
||||
|
||||
int const half_size = blip_res / 2 * (width - 1);
|
||||
eq.generate( &fimpulse [blip_res], half_size );
|
||||
|
||||
int i;
|
||||
|
||||
// need mirror slightly past center for calculation
|
||||
for ( i = blip_res; i--; )
|
||||
fimpulse [blip_res + half_size + i] = fimpulse [blip_res + half_size - 1 - i];
|
||||
|
||||
// starts at 0
|
||||
for ( i = 0; i < blip_res; i++ )
|
||||
fimpulse [i] = 0.0f;
|
||||
|
||||
// find rescale factor
|
||||
double total = 0.0;
|
||||
for ( i = 0; i < half_size; i++ )
|
||||
total += fimpulse [blip_res + i];
|
||||
|
||||
//double const base_unit = 44800.0 - 128 * 18; // allows treble up to +0 dB
|
||||
//double const base_unit = 37888.0; // allows treble to +5 dB
|
||||
double const base_unit = 32768.0; // necessary for blip_unscaled to work
|
||||
double rescale = base_unit / 2 / total;
|
||||
kernel_unit = (long) base_unit;
|
||||
|
||||
// integrate, first difference, rescale, convert to int
|
||||
double sum = 0.0;
|
||||
double next = 0.0;
|
||||
int const size = this->impulses_size();
|
||||
for ( i = 0; i < size; i++ )
|
||||
{
|
||||
impulses [i] = (short) (int) floor( (next - sum) * rescale + 0.5 );
|
||||
sum += fimpulse [i];
|
||||
next += fimpulse [i + blip_res];
|
||||
}
|
||||
adjust_impulse();
|
||||
|
||||
// volume might require rescaling
|
||||
double vol = volume_unit_;
|
||||
if ( vol )
|
||||
{
|
||||
volume_unit_ = 0.0;
|
||||
volume_unit( vol );
|
||||
}
|
||||
}
|
||||
|
||||
void Blip_Synth_::volume_unit( double new_unit )
|
||||
{
|
||||
if ( new_unit != volume_unit_ )
|
||||
{
|
||||
// use default eq if it hasn't been set yet
|
||||
if ( !kernel_unit )
|
||||
treble_eq( -8.0 );
|
||||
|
||||
volume_unit_ = new_unit;
|
||||
double factor = new_unit * (1L << blip_sample_bits) / kernel_unit;
|
||||
|
||||
if ( factor > 0.0 )
|
||||
{
|
||||
int shift = 0;
|
||||
|
||||
// if unit is really small, might need to attenuate kernel
|
||||
while ( factor < 2.0 )
|
||||
{
|
||||
shift++;
|
||||
factor *= 2.0;
|
||||
}
|
||||
|
||||
if ( shift )
|
||||
{
|
||||
kernel_unit >>= shift;
|
||||
assert( kernel_unit > 0 ); // fails if volume unit is too low
|
||||
|
||||
// keep values positive to avoid round-towards-zero of sign-preserving
|
||||
// right shift for negative values
|
||||
long offset = 0x8000 + (1 << (shift - 1));
|
||||
long offset2 = 0x8000 >> shift;
|
||||
for ( int i = impulses_size(); i--; )
|
||||
impulses [i] = (short) (int) (((impulses [i] + offset) >> shift) - offset2);
|
||||
adjust_impulse();
|
||||
}
|
||||
}
|
||||
delta_factor = (int) floor( factor + 0.5 );
|
||||
//printf( "delta_factor: %d, kernel_unit: %d\n", delta_factor, kernel_unit );
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
long Blip_Buffer::read_samples( blip_sample_t* out_, long max_samples, int stereo )
|
||||
{
|
||||
long count = samples_avail();
|
||||
if ( count > max_samples )
|
||||
count = max_samples;
|
||||
|
||||
if ( count )
|
||||
{
|
||||
int const bass = BLIP_READER_BASS( *this );
|
||||
BLIP_READER_BEGIN( reader, *this );
|
||||
BLIP_READER_ADJ_( reader, count );
|
||||
blip_sample_t* BLIP_RESTRICT out = out_ + count;
|
||||
blip_long offset = (blip_long) -count;
|
||||
|
||||
if ( !stereo )
|
||||
{
|
||||
do
|
||||
{
|
||||
blip_long s = BLIP_READER_READ( reader );
|
||||
BLIP_READER_NEXT_IDX_( reader, bass, offset );
|
||||
BLIP_CLAMP( s, s );
|
||||
out [offset] = (blip_sample_t) s;
|
||||
}
|
||||
while ( ++offset );
|
||||
}
|
||||
else
|
||||
{
|
||||
do
|
||||
{
|
||||
blip_long s = BLIP_READER_READ( reader );
|
||||
BLIP_READER_NEXT_IDX_( reader, bass, offset );
|
||||
BLIP_CLAMP( s, s );
|
||||
out [offset * 2] = (blip_sample_t) s;
|
||||
}
|
||||
while ( ++offset );
|
||||
}
|
||||
|
||||
BLIP_READER_END( reader, *this );
|
||||
|
||||
remove_samples( count );
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
void Blip_Buffer::mix_samples( blip_sample_t const* in, long count )
|
||||
{
|
||||
if ( buffer_size_ == silent_buf_size )
|
||||
{
|
||||
assert( 0 );
|
||||
return;
|
||||
}
|
||||
|
||||
buf_t_* out = buffer_ + (offset_ >> BLIP_BUFFER_ACCURACY) + blip_widest_impulse_ / 2;
|
||||
|
||||
int const sample_shift = blip_sample_bits - 16;
|
||||
int prev = 0;
|
||||
while ( count-- )
|
||||
{
|
||||
blip_long s = (blip_long) *in++ << sample_shift;
|
||||
*out += s - prev;
|
||||
prev = s;
|
||||
++out;
|
||||
}
|
||||
*out -= prev;
|
||||
}
|
||||
|
||||
blip_ulong const subsample_mask = (1L << BLIP_BUFFER_ACCURACY) - 1;
|
||||
|
||||
void Blip_Buffer::save_state( blip_buffer_state_t* out )
|
||||
{
|
||||
assert( samples_avail() == 0 );
|
||||
out->offset_ = offset_;
|
||||
out->reader_accum_ = reader_accum_;
|
||||
memcpy( out->buf, &buffer_ [offset_ >> BLIP_BUFFER_ACCURACY], sizeof out->buf );
|
||||
}
|
||||
|
||||
void Blip_Buffer::load_state( blip_buffer_state_t const& in )
|
||||
{
|
||||
clear( false );
|
||||
|
||||
offset_ = in.offset_;
|
||||
reader_accum_ = in.reader_accum_;
|
||||
memcpy( buffer_, in.buf, sizeof in.buf );
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -1,143 +1,143 @@
|
|||
// Multi-channel effects buffer with echo and individual panning for each channel
|
||||
|
||||
// Game_Music_Emu $vers
|
||||
#ifndef EFFECTS_BUFFER_H
|
||||
#define EFFECTS_BUFFER_H
|
||||
|
||||
#include "Multi_Buffer.h"
|
||||
|
||||
// See Simple_Effects_Buffer (below) for a simpler interface
|
||||
|
||||
class Effects_Buffer : public Multi_Buffer {
|
||||
public:
|
||||
// To reduce memory usage, fewer buffers can be used (with a best-fit
|
||||
// approach if there are too few), and maximum echo delay can be reduced
|
||||
Effects_Buffer( int max_bufs = 32, long echo_size = 24 * 1024L );
|
||||
|
||||
struct pan_vol_t
|
||||
{
|
||||
float vol; // 0.0 = silent, 0.5 = half volume, 1.0 = normal
|
||||
float pan; // -1.0 = left, 0.0 = center, +1.0 = right
|
||||
};
|
||||
|
||||
// Global configuration
|
||||
struct config_t
|
||||
{
|
||||
bool enabled; // false = disable all effects
|
||||
|
||||
// Current sound is echoed at adjustable left/right delay,
|
||||
// with reduced treble and volume (feedback).
|
||||
float treble; // 1.0 = full treble, 0.1 = very little, 0.0 = silent
|
||||
int delay [2]; // left, right delays (msec)
|
||||
float feedback; // 0.0 = no echo, 0.5 = each echo half previous, 1.0 = cacophony
|
||||
pan_vol_t side_chans [2]; // left and right side channel volume and pan
|
||||
};
|
||||
config_t& config() { return config_; }
|
||||
|
||||
// Limits of delay (msec)
|
||||
int min_delay() const;
|
||||
int max_delay() const;
|
||||
|
||||
// Per-channel configuration. Two or more channels with matching parameters are
|
||||
// optimized to internally use the same buffer.
|
||||
struct chan_config_t : pan_vol_t
|
||||
{
|
||||
// (inherited from pan_vol_t)
|
||||
//float vol; // these only affect center channel
|
||||
//float pan;
|
||||
bool surround; // if true, negates left volume to put sound in back
|
||||
bool echo; // false = channel doesn't have any echo
|
||||
};
|
||||
chan_config_t& chan_config( int i ) { return chans [i + extra_chans].cfg; }
|
||||
|
||||
// Apply any changes made to config() and chan_config()
|
||||
virtual void apply_config();
|
||||
|
||||
public:
|
||||
~Effects_Buffer();
|
||||
blargg_err_t set_sample_rate( long samples_per_sec, int msec = blip_default_length );
|
||||
blargg_err_t set_channel_count( int, int const* = 0 );
|
||||
void clock_rate( long );
|
||||
void bass_freq( int );
|
||||
void clear();
|
||||
channel_t channel( int );
|
||||
void end_frame( blip_time_t );
|
||||
long read_samples( blip_sample_t*, long );
|
||||
long samples_avail() const { return (bufs [0].samples_avail() - mixer.samples_read) * 2; }
|
||||
enum { stereo = 2 };
|
||||
typedef blargg_long fixed_t;
|
||||
protected:
|
||||
enum { extra_chans = stereo * stereo };
|
||||
private:
|
||||
config_t config_;
|
||||
long clock_rate_;
|
||||
int bass_freq_;
|
||||
|
||||
blargg_long echo_size;
|
||||
|
||||
struct chan_t
|
||||
{
|
||||
fixed_t vol [stereo];
|
||||
chan_config_t cfg;
|
||||
channel_t channel;
|
||||
};
|
||||
blargg_vector<chan_t> chans;
|
||||
|
||||
struct buf_t : Tracked_Blip_Buffer
|
||||
{
|
||||
fixed_t vol [stereo];
|
||||
bool echo;
|
||||
|
||||
void* operator new ( size_t, void* p ) { return p; }
|
||||
void operator delete ( void* ) { }
|
||||
|
||||
~buf_t() { }
|
||||
};
|
||||
buf_t* bufs;
|
||||
int bufs_size;
|
||||
int bufs_max; // bufs_size <= bufs_max, to limit memory usage
|
||||
Stereo_Mixer mixer;
|
||||
|
||||
struct {
|
||||
long delay [stereo];
|
||||
fixed_t treble;
|
||||
fixed_t feedback;
|
||||
fixed_t low_pass [stereo];
|
||||
} s;
|
||||
|
||||
blargg_vector<fixed_t> echo;
|
||||
blargg_long echo_pos;
|
||||
|
||||
bool no_effects;
|
||||
bool no_echo;
|
||||
|
||||
void assign_buffers();
|
||||
void clear_echo();
|
||||
void mix_effects( blip_sample_t* out, int pair_count );
|
||||
blargg_err_t new_bufs( int size );
|
||||
void delete_bufs();
|
||||
};
|
||||
|
||||
// Simpler interface and lower memory usage
|
||||
class Simple_Effects_Buffer : public Effects_Buffer {
|
||||
public:
|
||||
struct config_t
|
||||
{
|
||||
bool enabled; // false = disable all effects
|
||||
float echo; // 0.0 = none, 1.0 = lots
|
||||
float stereo; // 0.0 = channels in center, 1.0 = channels on left/right
|
||||
bool surround; // true = put some channels in back
|
||||
};
|
||||
config_t& config() { return config_; }
|
||||
|
||||
// Apply any changes made to config()
|
||||
void apply_config();
|
||||
|
||||
public:
|
||||
Simple_Effects_Buffer();
|
||||
private:
|
||||
config_t config_;
|
||||
void chan_config(); // hide
|
||||
};
|
||||
|
||||
#endif
|
||||
// Multi-channel effects buffer with echo and individual panning for each channel
|
||||
|
||||
// Game_Music_Emu $vers
|
||||
#ifndef EFFECTS_BUFFER_H
|
||||
#define EFFECTS_BUFFER_H
|
||||
|
||||
#include "Multi_Buffer.h"
|
||||
|
||||
// See Simple_Effects_Buffer (below) for a simpler interface
|
||||
|
||||
class Effects_Buffer : public Multi_Buffer {
|
||||
public:
|
||||
// To reduce memory usage, fewer buffers can be used (with a best-fit
|
||||
// approach if there are too few), and maximum echo delay can be reduced
|
||||
Effects_Buffer( int max_bufs = 32, long echo_size = 24 * 1024L );
|
||||
|
||||
struct pan_vol_t
|
||||
{
|
||||
float vol; // 0.0 = silent, 0.5 = half volume, 1.0 = normal
|
||||
float pan; // -1.0 = left, 0.0 = center, +1.0 = right
|
||||
};
|
||||
|
||||
// Global configuration
|
||||
struct config_t
|
||||
{
|
||||
bool enabled; // false = disable all effects
|
||||
|
||||
// Current sound is echoed at adjustable left/right delay,
|
||||
// with reduced treble and volume (feedback).
|
||||
float treble; // 1.0 = full treble, 0.1 = very little, 0.0 = silent
|
||||
int delay [2]; // left, right delays (msec)
|
||||
float feedback; // 0.0 = no echo, 0.5 = each echo half previous, 1.0 = cacophony
|
||||
pan_vol_t side_chans [2]; // left and right side channel volume and pan
|
||||
};
|
||||
config_t& config() { return config_; }
|
||||
|
||||
// Limits of delay (msec)
|
||||
int min_delay() const;
|
||||
int max_delay() const;
|
||||
|
||||
// Per-channel configuration. Two or more channels with matching parameters are
|
||||
// optimized to internally use the same buffer.
|
||||
struct chan_config_t : pan_vol_t
|
||||
{
|
||||
// (inherited from pan_vol_t)
|
||||
//float vol; // these only affect center channel
|
||||
//float pan;
|
||||
bool surround; // if true, negates left volume to put sound in back
|
||||
bool echo; // false = channel doesn't have any echo
|
||||
};
|
||||
chan_config_t& chan_config( int i ) { return chans [i + extra_chans].cfg; }
|
||||
|
||||
// Apply any changes made to config() and chan_config()
|
||||
virtual void apply_config();
|
||||
|
||||
public:
|
||||
~Effects_Buffer();
|
||||
blargg_err_t set_sample_rate( long samples_per_sec, int msec = blip_default_length );
|
||||
blargg_err_t set_channel_count( int, int const* = 0 );
|
||||
void clock_rate( long );
|
||||
void bass_freq( int );
|
||||
void clear();
|
||||
channel_t channel( int );
|
||||
void end_frame( blip_time_t );
|
||||
long read_samples( blip_sample_t*, long );
|
||||
long samples_avail() const { return (bufs [0].samples_avail() - mixer.samples_read) * 2; }
|
||||
enum { stereo = 2 };
|
||||
typedef blargg_long fixed_t;
|
||||
protected:
|
||||
enum { extra_chans = stereo * stereo };
|
||||
private:
|
||||
config_t config_;
|
||||
long clock_rate_;
|
||||
int bass_freq_;
|
||||
|
||||
blargg_long echo_size;
|
||||
|
||||
struct chan_t
|
||||
{
|
||||
fixed_t vol [stereo];
|
||||
chan_config_t cfg;
|
||||
channel_t channel;
|
||||
};
|
||||
blargg_vector<chan_t> chans;
|
||||
|
||||
struct buf_t : Tracked_Blip_Buffer
|
||||
{
|
||||
fixed_t vol [stereo];
|
||||
bool echo;
|
||||
|
||||
void* operator new ( size_t, void* p ) { return p; }
|
||||
void operator delete ( void* ) { }
|
||||
|
||||
~buf_t() { }
|
||||
};
|
||||
buf_t* bufs;
|
||||
int bufs_size;
|
||||
int bufs_max; // bufs_size <= bufs_max, to limit memory usage
|
||||
Stereo_Mixer mixer;
|
||||
|
||||
struct {
|
||||
long delay [stereo];
|
||||
fixed_t treble;
|
||||
fixed_t feedback;
|
||||
fixed_t low_pass [stereo];
|
||||
} s;
|
||||
|
||||
blargg_vector<fixed_t> echo;
|
||||
blargg_long echo_pos;
|
||||
|
||||
bool no_effects;
|
||||
bool no_echo;
|
||||
|
||||
void assign_buffers();
|
||||
void clear_echo();
|
||||
void mix_effects( blip_sample_t* out, int pair_count );
|
||||
blargg_err_t new_bufs( int size );
|
||||
void delete_bufs();
|
||||
};
|
||||
|
||||
// Simpler interface and lower memory usage
|
||||
class Simple_Effects_Buffer : public Effects_Buffer {
|
||||
public:
|
||||
struct config_t
|
||||
{
|
||||
bool enabled; // false = disable all effects
|
||||
float echo; // 0.0 = none, 1.0 = lots
|
||||
float stereo; // 0.0 = channels in center, 1.0 = channels on left/right
|
||||
bool surround; // true = put some channels in back
|
||||
};
|
||||
config_t& config() { return config_; }
|
||||
|
||||
// Apply any changes made to config()
|
||||
void apply_config();
|
||||
|
||||
public:
|
||||
Simple_Effects_Buffer();
|
||||
private:
|
||||
config_t config_;
|
||||
void chan_config(); // hide
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,394 +1,394 @@
|
|||
// Gb_Snd_Emu 0.2.0. http://www.slack.net/~ant/
|
||||
|
||||
#include "Gb_Apu.h"
|
||||
|
||||
/* Copyright (C) 2003-2007 Shay Green. This module is free software; you
|
||||
can redistribute it and/or modify it under the terms of the GNU Lesser
|
||||
General Public License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version. This
|
||||
module is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
|
||||
details. You should have received a copy of the GNU Lesser General Public
|
||||
License along with this module; if not, write to the Free Software Foundation,
|
||||
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
|
||||
|
||||
#include "blargg_source.h"
|
||||
|
||||
unsigned const vol_reg = 0xFF24;
|
||||
unsigned const stereo_reg = 0xFF25;
|
||||
unsigned const status_reg = 0xFF26;
|
||||
unsigned const wave_ram = 0xFF30;
|
||||
|
||||
int const power_mask = 0x80;
|
||||
|
||||
void Gb_Apu::treble_eq( blip_eq_t const& eq )
|
||||
{
|
||||
good_synth.treble_eq( eq );
|
||||
med_synth .treble_eq( eq );
|
||||
}
|
||||
|
||||
inline int Gb_Apu::calc_output( int osc ) const
|
||||
{
|
||||
int bits = regs [stereo_reg - start_addr] >> osc;
|
||||
return (bits >> 3 & 2) | (bits & 1);
|
||||
}
|
||||
|
||||
void Gb_Apu::set_output( Blip_Buffer* center, Blip_Buffer* left, Blip_Buffer* right, int osc )
|
||||
{
|
||||
// Must be silent (all NULL), mono (left and right NULL), or stereo (none NULL)
|
||||
require( !center || (center && !left && !right) || (center && left && right) );
|
||||
require( (unsigned) osc <= osc_count ); // fails if you pass invalid osc index
|
||||
|
||||
if ( !center || !left || !right )
|
||||
{
|
||||
left = center;
|
||||
right = center;
|
||||
}
|
||||
|
||||
int i = (unsigned) osc % osc_count;
|
||||
do
|
||||
{
|
||||
Gb_Osc& o = *oscs [i];
|
||||
o.outputs [1] = right;
|
||||
o.outputs [2] = left;
|
||||
o.outputs [3] = center;
|
||||
o.output = o.outputs [calc_output( i )];
|
||||
}
|
||||
while ( ++i < osc );
|
||||
}
|
||||
|
||||
void Gb_Apu::synth_volume( int iv )
|
||||
{
|
||||
double v = volume_ * 0.60 / osc_count / 15 /*steps*/ / 8 /*master vol range*/ * iv;
|
||||
good_synth.volume( v );
|
||||
med_synth .volume( v );
|
||||
}
|
||||
|
||||
void Gb_Apu::apply_volume()
|
||||
{
|
||||
// TODO: Doesn't handle differing left and right volumes (panning).
|
||||
// Not worth the complexity.
|
||||
int data = regs [vol_reg - start_addr];
|
||||
int left = data >> 4 & 7;
|
||||
int right = data & 7;
|
||||
//if ( data & 0x88 ) dprintf( "Vin: %02X\n", data & 0x88 );
|
||||
//if ( left != right ) dprintf( "l: %d r: %d\n", left, right );
|
||||
synth_volume( max( left, right ) + 1 );
|
||||
}
|
||||
|
||||
void Gb_Apu::volume( double v )
|
||||
{
|
||||
if ( volume_ != v )
|
||||
{
|
||||
volume_ = v;
|
||||
apply_volume();
|
||||
}
|
||||
}
|
||||
|
||||
void Gb_Apu::reset_regs()
|
||||
{
|
||||
for ( int i = 0; i < 0x20; i++ )
|
||||
regs [i] = 0;
|
||||
|
||||
square1.reset();
|
||||
square2.reset();
|
||||
wave .reset();
|
||||
noise .reset();
|
||||
|
||||
apply_volume();
|
||||
}
|
||||
|
||||
void Gb_Apu::reset_lengths()
|
||||
{
|
||||
square1.length_ctr = 64;
|
||||
square2.length_ctr = 64;
|
||||
wave .length_ctr = 256;
|
||||
noise .length_ctr = 64;
|
||||
}
|
||||
|
||||
void Gb_Apu::reduce_clicks( bool reduce )
|
||||
{
|
||||
reduce_clicks_ = reduce;
|
||||
|
||||
// Click reduction makes DAC off generate same output as volume 0
|
||||
int dac_off_amp = 0;
|
||||
if ( reduce && wave.mode != mode_agb ) // AGB already eliminates clicks
|
||||
dac_off_amp = -Gb_Osc::dac_bias;
|
||||
|
||||
for ( int i = 0; i < osc_count; i++ )
|
||||
oscs [i]->dac_off_amp = dac_off_amp;
|
||||
|
||||
// AGB always eliminates clicks on wave channel using same method
|
||||
if ( wave.mode == mode_agb )
|
||||
wave.dac_off_amp = -Gb_Osc::dac_bias;
|
||||
}
|
||||
|
||||
void Gb_Apu::reset( mode_t mode, bool agb_wave )
|
||||
{
|
||||
// Hardware mode
|
||||
if ( agb_wave )
|
||||
mode = mode_agb; // using AGB wave features implies AGB hardware
|
||||
wave.agb_mask = agb_wave ? 0xFF : 0;
|
||||
for ( int i = 0; i < osc_count; i++ )
|
||||
oscs [i]->mode = mode;
|
||||
reduce_clicks( reduce_clicks_ );
|
||||
|
||||
// Reset state
|
||||
frame_time = 0;
|
||||
last_time = 0;
|
||||
frame_phase = 0;
|
||||
|
||||
reset_regs();
|
||||
reset_lengths();
|
||||
|
||||
// Load initial wave RAM
|
||||
static byte const initial_wave [2] [16] = {
|
||||
{0x84,0x40,0x43,0xAA,0x2D,0x78,0x92,0x3C,0x60,0x59,0x59,0xB0,0x34,0xB8,0x2E,0xDA},
|
||||
{0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF},
|
||||
};
|
||||
for ( int b = 2; --b >= 0; )
|
||||
{
|
||||
// Init both banks (does nothing if not in AGB mode)
|
||||
// TODO: verify that this works
|
||||
write_register( 0, 0xFF1A, b * 0x40 );
|
||||
for ( unsigned i = 0; i < sizeof initial_wave [0]; i++ )
|
||||
write_register( 0, i + wave_ram, initial_wave [(mode != mode_dmg)] [i] );
|
||||
}
|
||||
}
|
||||
|
||||
void Gb_Apu::set_tempo( double t )
|
||||
{
|
||||
frame_period = 4194304 / 512; // 512 Hz
|
||||
if ( t != 1.0 )
|
||||
frame_period = blip_time_t (frame_period / t);
|
||||
}
|
||||
|
||||
Gb_Apu::Gb_Apu()
|
||||
{
|
||||
wave.wave_ram = ®s [wave_ram - start_addr];
|
||||
|
||||
oscs [0] = &square1;
|
||||
oscs [1] = &square2;
|
||||
oscs [2] = &wave;
|
||||
oscs [3] = &noise;
|
||||
|
||||
for ( int i = osc_count; --i >= 0; )
|
||||
{
|
||||
Gb_Osc& o = *oscs [i];
|
||||
o.regs = ®s [i * 5];
|
||||
o.output = 0;
|
||||
o.outputs [0] = 0;
|
||||
o.outputs [1] = 0;
|
||||
o.outputs [2] = 0;
|
||||
o.outputs [3] = 0;
|
||||
o.good_synth = &good_synth;
|
||||
o.med_synth = &med_synth;
|
||||
}
|
||||
|
||||
reduce_clicks_ = false;
|
||||
set_tempo( 1.0 );
|
||||
volume_ = 1.0;
|
||||
reset();
|
||||
}
|
||||
|
||||
void Gb_Apu::run_until_( blip_time_t end_time )
|
||||
{
|
||||
while ( true )
|
||||
{
|
||||
// run oscillators
|
||||
blip_time_t time = end_time;
|
||||
if ( time > frame_time )
|
||||
time = frame_time;
|
||||
|
||||
square1.run( last_time, time );
|
||||
square2.run( last_time, time );
|
||||
wave .run( last_time, time );
|
||||
noise .run( last_time, time );
|
||||
last_time = time;
|
||||
|
||||
if ( time == end_time )
|
||||
break;
|
||||
|
||||
// run frame sequencer
|
||||
frame_time += frame_period * Gb_Osc::clk_mul;
|
||||
switch ( frame_phase++ )
|
||||
{
|
||||
case 2:
|
||||
case 6:
|
||||
// 128 Hz
|
||||
square1.clock_sweep();
|
||||
case 0:
|
||||
case 4:
|
||||
// 256 Hz
|
||||
square1.clock_length();
|
||||
square2.clock_length();
|
||||
wave .clock_length();
|
||||
noise .clock_length();
|
||||
break;
|
||||
|
||||
case 7:
|
||||
// 64 Hz
|
||||
frame_phase = 0;
|
||||
square1.clock_envelope();
|
||||
square2.clock_envelope();
|
||||
noise .clock_envelope();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
inline void Gb_Apu::run_until( blip_time_t time )
|
||||
{
|
||||
require( time >= last_time ); // end_time must not be before previous time
|
||||
if ( time > last_time )
|
||||
run_until_( time );
|
||||
}
|
||||
|
||||
void Gb_Apu::end_frame( blip_time_t end_time )
|
||||
{
|
||||
if ( end_time > last_time )
|
||||
run_until( end_time );
|
||||
|
||||
frame_time -= end_time;
|
||||
assert( frame_time >= 0 );
|
||||
|
||||
last_time -= end_time;
|
||||
assert( last_time >= 0 );
|
||||
}
|
||||
|
||||
void Gb_Apu::silence_osc( Gb_Osc& o )
|
||||
{
|
||||
int delta = -o.last_amp;
|
||||
if ( delta )
|
||||
{
|
||||
o.last_amp = 0;
|
||||
if ( o.output )
|
||||
{
|
||||
o.output->set_modified();
|
||||
med_synth.offset( last_time, delta, o.output );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Gb_Apu::apply_stereo()
|
||||
{
|
||||
for ( int i = osc_count; --i >= 0; )
|
||||
{
|
||||
Gb_Osc& o = *oscs [i];
|
||||
Blip_Buffer* out = o.outputs [calc_output( i )];
|
||||
if ( o.output != out )
|
||||
{
|
||||
silence_osc( o );
|
||||
o.output = out;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Gb_Apu::write_register( blip_time_t time, unsigned addr, int data )
|
||||
{
|
||||
require( (unsigned) data < 0x100 );
|
||||
|
||||
int reg = addr - start_addr;
|
||||
if ( (unsigned) reg >= register_count )
|
||||
{
|
||||
require( false );
|
||||
return;
|
||||
}
|
||||
|
||||
if ( addr < status_reg && !(regs [status_reg - start_addr] & power_mask) )
|
||||
{
|
||||
// Power is off
|
||||
|
||||
// length counters can only be written in DMG mode
|
||||
if ( wave.mode != mode_dmg || (reg != 1 && reg != 5+1 && reg != 10+1 && reg != 15+1) )
|
||||
return;
|
||||
|
||||
if ( reg < 10 )
|
||||
data &= 0x3F; // clear square duty
|
||||
}
|
||||
|
||||
run_until( time );
|
||||
|
||||
if ( addr >= wave_ram )
|
||||
{
|
||||
wave.write( addr, data );
|
||||
}
|
||||
else
|
||||
{
|
||||
int old_data = regs [reg];
|
||||
regs [reg] = data;
|
||||
|
||||
if ( addr < vol_reg )
|
||||
{
|
||||
// Oscillator
|
||||
write_osc( reg / 5, reg, old_data, data );
|
||||
}
|
||||
else if ( addr == vol_reg && data != old_data )
|
||||
{
|
||||
// Master volume
|
||||
for ( int i = osc_count; --i >= 0; )
|
||||
silence_osc( *oscs [i] );
|
||||
|
||||
apply_volume();
|
||||
}
|
||||
else if ( addr == stereo_reg )
|
||||
{
|
||||
// Stereo panning
|
||||
apply_stereo();
|
||||
}
|
||||
else if ( addr == status_reg && (data ^ old_data) & power_mask )
|
||||
{
|
||||
// Power control
|
||||
frame_phase = 0;
|
||||
for ( int i = osc_count; --i >= 0; )
|
||||
silence_osc( *oscs [i] );
|
||||
|
||||
reset_regs();
|
||||
if ( wave.mode != mode_dmg )
|
||||
reset_lengths();
|
||||
|
||||
regs [status_reg - start_addr] = data;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int Gb_Apu::read_register( blip_time_t time, unsigned addr )
|
||||
{
|
||||
run_until( time );
|
||||
|
||||
int reg = addr - start_addr;
|
||||
if ( (unsigned) reg >= register_count )
|
||||
{
|
||||
require( false );
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ( addr >= wave_ram )
|
||||
return wave.read( addr );
|
||||
|
||||
// Value read back has some bits always set
|
||||
static byte const masks [] = {
|
||||
0x80,0x3F,0x00,0xFF,0xBF,
|
||||
0xFF,0x3F,0x00,0xFF,0xBF,
|
||||
0x7F,0xFF,0x9F,0xFF,0xBF,
|
||||
0xFF,0xFF,0x00,0x00,0xBF,
|
||||
0x00,0x00,0x70,
|
||||
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF
|
||||
};
|
||||
int mask = masks [reg];
|
||||
if ( wave.agb_mask && (reg == 10 || reg == 12) )
|
||||
mask = 0x1F; // extra implemented bits in wave regs on AGB
|
||||
int data = regs [reg] | mask;
|
||||
|
||||
// Status register
|
||||
if ( addr == status_reg )
|
||||
{
|
||||
data &= 0xF0;
|
||||
data |= (int) square1.enabled << 0;
|
||||
data |= (int) square2.enabled << 1;
|
||||
data |= (int) wave .enabled << 2;
|
||||
data |= (int) noise .enabled << 3;
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
// Gb_Snd_Emu 0.2.0. http://www.slack.net/~ant/
|
||||
|
||||
#include "Gb_Apu.h"
|
||||
|
||||
/* Copyright (C) 2003-2007 Shay Green. This module is free software; you
|
||||
can redistribute it and/or modify it under the terms of the GNU Lesser
|
||||
General Public License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version. This
|
||||
module is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
|
||||
details. You should have received a copy of the GNU Lesser General Public
|
||||
License along with this module; if not, write to the Free Software Foundation,
|
||||
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
|
||||
|
||||
#include "blargg_source.h"
|
||||
|
||||
unsigned const vol_reg = 0xFF24;
|
||||
unsigned const stereo_reg = 0xFF25;
|
||||
unsigned const status_reg = 0xFF26;
|
||||
unsigned const wave_ram = 0xFF30;
|
||||
|
||||
int const power_mask = 0x80;
|
||||
|
||||
void Gb_Apu::treble_eq( blip_eq_t const& eq )
|
||||
{
|
||||
good_synth.treble_eq( eq );
|
||||
med_synth .treble_eq( eq );
|
||||
}
|
||||
|
||||
inline int Gb_Apu::calc_output( int osc ) const
|
||||
{
|
||||
int bits = regs [stereo_reg - start_addr] >> osc;
|
||||
return (bits >> 3 & 2) | (bits & 1);
|
||||
}
|
||||
|
||||
void Gb_Apu::set_output( Blip_Buffer* center, Blip_Buffer* left, Blip_Buffer* right, int osc )
|
||||
{
|
||||
// Must be silent (all NULL), mono (left and right NULL), or stereo (none NULL)
|
||||
require( !center || (center && !left && !right) || (center && left && right) );
|
||||
require( (unsigned) osc <= osc_count ); // fails if you pass invalid osc index
|
||||
|
||||
if ( !center || !left || !right )
|
||||
{
|
||||
left = center;
|
||||
right = center;
|
||||
}
|
||||
|
||||
int i = (unsigned) osc % osc_count;
|
||||
do
|
||||
{
|
||||
Gb_Osc& o = *oscs [i];
|
||||
o.outputs [1] = right;
|
||||
o.outputs [2] = left;
|
||||
o.outputs [3] = center;
|
||||
o.output = o.outputs [calc_output( i )];
|
||||
}
|
||||
while ( ++i < osc );
|
||||
}
|
||||
|
||||
void Gb_Apu::synth_volume( int iv )
|
||||
{
|
||||
double v = volume_ * 0.60 / osc_count / 15 /*steps*/ / 8 /*master vol range*/ * iv;
|
||||
good_synth.volume( v );
|
||||
med_synth .volume( v );
|
||||
}
|
||||
|
||||
void Gb_Apu::apply_volume()
|
||||
{
|
||||
// TODO: Doesn't handle differing left and right volumes (panning).
|
||||
// Not worth the complexity.
|
||||
int data = regs [vol_reg - start_addr];
|
||||
int left = data >> 4 & 7;
|
||||
int right = data & 7;
|
||||
//if ( data & 0x88 ) dprintf( "Vin: %02X\n", data & 0x88 );
|
||||
//if ( left != right ) dprintf( "l: %d r: %d\n", left, right );
|
||||
synth_volume( max( left, right ) + 1 );
|
||||
}
|
||||
|
||||
void Gb_Apu::volume( double v )
|
||||
{
|
||||
if ( volume_ != v )
|
||||
{
|
||||
volume_ = v;
|
||||
apply_volume();
|
||||
}
|
||||
}
|
||||
|
||||
void Gb_Apu::reset_regs()
|
||||
{
|
||||
for ( int i = 0; i < 0x20; i++ )
|
||||
regs [i] = 0;
|
||||
|
||||
square1.reset();
|
||||
square2.reset();
|
||||
wave .reset();
|
||||
noise .reset();
|
||||
|
||||
apply_volume();
|
||||
}
|
||||
|
||||
void Gb_Apu::reset_lengths()
|
||||
{
|
||||
square1.length_ctr = 64;
|
||||
square2.length_ctr = 64;
|
||||
wave .length_ctr = 256;
|
||||
noise .length_ctr = 64;
|
||||
}
|
||||
|
||||
void Gb_Apu::reduce_clicks( bool reduce )
|
||||
{
|
||||
reduce_clicks_ = reduce;
|
||||
|
||||
// Click reduction makes DAC off generate same output as volume 0
|
||||
int dac_off_amp = 0;
|
||||
if ( reduce && wave.mode != mode_agb ) // AGB already eliminates clicks
|
||||
dac_off_amp = -Gb_Osc::dac_bias;
|
||||
|
||||
for ( int i = 0; i < osc_count; i++ )
|
||||
oscs [i]->dac_off_amp = dac_off_amp;
|
||||
|
||||
// AGB always eliminates clicks on wave channel using same method
|
||||
if ( wave.mode == mode_agb )
|
||||
wave.dac_off_amp = -Gb_Osc::dac_bias;
|
||||
}
|
||||
|
||||
void Gb_Apu::reset( mode_t mode, bool agb_wave )
|
||||
{
|
||||
// Hardware mode
|
||||
if ( agb_wave )
|
||||
mode = mode_agb; // using AGB wave features implies AGB hardware
|
||||
wave.agb_mask = agb_wave ? 0xFF : 0;
|
||||
for ( int i = 0; i < osc_count; i++ )
|
||||
oscs [i]->mode = mode;
|
||||
reduce_clicks( reduce_clicks_ );
|
||||
|
||||
// Reset state
|
||||
frame_time = 0;
|
||||
last_time = 0;
|
||||
frame_phase = 0;
|
||||
|
||||
reset_regs();
|
||||
reset_lengths();
|
||||
|
||||
// Load initial wave RAM
|
||||
static byte const initial_wave [2] [16] = {
|
||||
{0x84,0x40,0x43,0xAA,0x2D,0x78,0x92,0x3C,0x60,0x59,0x59,0xB0,0x34,0xB8,0x2E,0xDA},
|
||||
{0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF},
|
||||
};
|
||||
for ( int b = 2; --b >= 0; )
|
||||
{
|
||||
// Init both banks (does nothing if not in AGB mode)
|
||||
// TODO: verify that this works
|
||||
write_register( 0, 0xFF1A, b * 0x40 );
|
||||
for ( unsigned i = 0; i < sizeof initial_wave [0]; i++ )
|
||||
write_register( 0, i + wave_ram, initial_wave [(mode != mode_dmg)] [i] );
|
||||
}
|
||||
}
|
||||
|
||||
void Gb_Apu::set_tempo( double t )
|
||||
{
|
||||
frame_period = 4194304 / 512; // 512 Hz
|
||||
if ( t != 1.0 )
|
||||
frame_period = blip_time_t (frame_period / t);
|
||||
}
|
||||
|
||||
Gb_Apu::Gb_Apu()
|
||||
{
|
||||
wave.wave_ram = ®s [wave_ram - start_addr];
|
||||
|
||||
oscs [0] = &square1;
|
||||
oscs [1] = &square2;
|
||||
oscs [2] = &wave;
|
||||
oscs [3] = &noise;
|
||||
|
||||
for ( int i = osc_count; --i >= 0; )
|
||||
{
|
||||
Gb_Osc& o = *oscs [i];
|
||||
o.regs = ®s [i * 5];
|
||||
o.output = 0;
|
||||
o.outputs [0] = 0;
|
||||
o.outputs [1] = 0;
|
||||
o.outputs [2] = 0;
|
||||
o.outputs [3] = 0;
|
||||
o.good_synth = &good_synth;
|
||||
o.med_synth = &med_synth;
|
||||
}
|
||||
|
||||
reduce_clicks_ = false;
|
||||
set_tempo( 1.0 );
|
||||
volume_ = 1.0;
|
||||
reset();
|
||||
}
|
||||
|
||||
void Gb_Apu::run_until_( blip_time_t end_time )
|
||||
{
|
||||
while ( true )
|
||||
{
|
||||
// run oscillators
|
||||
blip_time_t time = end_time;
|
||||
if ( time > frame_time )
|
||||
time = frame_time;
|
||||
|
||||
square1.run( last_time, time );
|
||||
square2.run( last_time, time );
|
||||
wave .run( last_time, time );
|
||||
noise .run( last_time, time );
|
||||
last_time = time;
|
||||
|
||||
if ( time == end_time )
|
||||
break;
|
||||
|
||||
// run frame sequencer
|
||||
frame_time += frame_period * Gb_Osc::clk_mul;
|
||||
switch ( frame_phase++ )
|
||||
{
|
||||
case 2:
|
||||
case 6:
|
||||
// 128 Hz
|
||||
square1.clock_sweep();
|
||||
case 0:
|
||||
case 4:
|
||||
// 256 Hz
|
||||
square1.clock_length();
|
||||
square2.clock_length();
|
||||
wave .clock_length();
|
||||
noise .clock_length();
|
||||
break;
|
||||
|
||||
case 7:
|
||||
// 64 Hz
|
||||
frame_phase = 0;
|
||||
square1.clock_envelope();
|
||||
square2.clock_envelope();
|
||||
noise .clock_envelope();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
inline void Gb_Apu::run_until( blip_time_t time )
|
||||
{
|
||||
require( time >= last_time ); // end_time must not be before previous time
|
||||
if ( time > last_time )
|
||||
run_until_( time );
|
||||
}
|
||||
|
||||
void Gb_Apu::end_frame( blip_time_t end_time )
|
||||
{
|
||||
if ( end_time > last_time )
|
||||
run_until( end_time );
|
||||
|
||||
frame_time -= end_time;
|
||||
assert( frame_time >= 0 );
|
||||
|
||||
last_time -= end_time;
|
||||
assert( last_time >= 0 );
|
||||
}
|
||||
|
||||
void Gb_Apu::silence_osc( Gb_Osc& o )
|
||||
{
|
||||
int delta = -o.last_amp;
|
||||
if ( delta )
|
||||
{
|
||||
o.last_amp = 0;
|
||||
if ( o.output )
|
||||
{
|
||||
o.output->set_modified();
|
||||
med_synth.offset( last_time, delta, o.output );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Gb_Apu::apply_stereo()
|
||||
{
|
||||
for ( int i = osc_count; --i >= 0; )
|
||||
{
|
||||
Gb_Osc& o = *oscs [i];
|
||||
Blip_Buffer* out = o.outputs [calc_output( i )];
|
||||
if ( o.output != out )
|
||||
{
|
||||
silence_osc( o );
|
||||
o.output = out;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Gb_Apu::write_register( blip_time_t time, unsigned addr, int data )
|
||||
{
|
||||
require( (unsigned) data < 0x100 );
|
||||
|
||||
int reg = addr - start_addr;
|
||||
if ( (unsigned) reg >= register_count )
|
||||
{
|
||||
require( false );
|
||||
return;
|
||||
}
|
||||
|
||||
if ( addr < status_reg && !(regs [status_reg - start_addr] & power_mask) )
|
||||
{
|
||||
// Power is off
|
||||
|
||||
// length counters can only be written in DMG mode
|
||||
if ( wave.mode != mode_dmg || (reg != 1 && reg != 5+1 && reg != 10+1 && reg != 15+1) )
|
||||
return;
|
||||
|
||||
if ( reg < 10 )
|
||||
data &= 0x3F; // clear square duty
|
||||
}
|
||||
|
||||
run_until( time );
|
||||
|
||||
if ( addr >= wave_ram )
|
||||
{
|
||||
wave.write( addr, data );
|
||||
}
|
||||
else
|
||||
{
|
||||
int old_data = regs [reg];
|
||||
regs [reg] = data;
|
||||
|
||||
if ( addr < vol_reg )
|
||||
{
|
||||
// Oscillator
|
||||
write_osc( reg / 5, reg, old_data, data );
|
||||
}
|
||||
else if ( addr == vol_reg && data != old_data )
|
||||
{
|
||||
// Master volume
|
||||
for ( int i = osc_count; --i >= 0; )
|
||||
silence_osc( *oscs [i] );
|
||||
|
||||
apply_volume();
|
||||
}
|
||||
else if ( addr == stereo_reg )
|
||||
{
|
||||
// Stereo panning
|
||||
apply_stereo();
|
||||
}
|
||||
else if ( addr == status_reg && (data ^ old_data) & power_mask )
|
||||
{
|
||||
// Power control
|
||||
frame_phase = 0;
|
||||
for ( int i = osc_count; --i >= 0; )
|
||||
silence_osc( *oscs [i] );
|
||||
|
||||
reset_regs();
|
||||
if ( wave.mode != mode_dmg )
|
||||
reset_lengths();
|
||||
|
||||
regs [status_reg - start_addr] = data;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int Gb_Apu::read_register( blip_time_t time, unsigned addr )
|
||||
{
|
||||
run_until( time );
|
||||
|
||||
int reg = addr - start_addr;
|
||||
if ( (unsigned) reg >= register_count )
|
||||
{
|
||||
require( false );
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ( addr >= wave_ram )
|
||||
return wave.read( addr );
|
||||
|
||||
// Value read back has some bits always set
|
||||
static byte const masks [] = {
|
||||
0x80,0x3F,0x00,0xFF,0xBF,
|
||||
0xFF,0x3F,0x00,0xFF,0xBF,
|
||||
0x7F,0xFF,0x9F,0xFF,0xBF,
|
||||
0xFF,0xFF,0x00,0x00,0xBF,
|
||||
0x00,0x00,0x70,
|
||||
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF
|
||||
};
|
||||
int mask = masks [reg];
|
||||
if ( wave.agb_mask && (reg == 10 || reg == 12) )
|
||||
mask = 0x1F; // extra implemented bits in wave regs on AGB
|
||||
int data = regs [reg] | mask;
|
||||
|
||||
// Status register
|
||||
if ( addr == status_reg )
|
||||
{
|
||||
data &= 0xF0;
|
||||
data |= (int) square1.enabled << 0;
|
||||
data |= (int) square2.enabled << 1;
|
||||
data |= (int) wave .enabled << 2;
|
||||
data |= (int) noise .enabled << 3;
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
|
|
@ -1,182 +1,182 @@
|
|||
// Nintendo Game Boy sound hardware emulator with save state support
|
||||
|
||||
// Gb_Snd_Emu 0.2.0
|
||||
#ifndef GB_APU_H
|
||||
#define GB_APU_H
|
||||
|
||||
#include "Gb_Oscs.h"
|
||||
|
||||
struct gb_apu_state_t;
|
||||
|
||||
class Gb_Apu {
|
||||
public:
|
||||
// Basics
|
||||
|
||||
// Clock rate that sound hardware runs at.
|
||||
enum { clock_rate = 4194304 * GB_APU_OVERCLOCK };
|
||||
|
||||
// Sets buffer(s) to generate sound into. If left and right are NULL, output is mono.
|
||||
// If all are NULL, no output is generated but other emulation still runs.
|
||||
// If chan is specified, only that channel's output is changed, otherwise all are.
|
||||
enum { osc_count = 4 }; // 0: Square 1, 1: Square 2, 2: Wave, 3: Noise
|
||||
void set_output( Blip_Buffer* center, Blip_Buffer* left = NULL, Blip_Buffer* right = NULL,
|
||||
int chan = osc_count );
|
||||
|
||||
// Resets hardware to initial power on state BEFORE boot ROM runs. Mode selects
|
||||
// sound hardware. Additional AGB wave features are enabled separately.
|
||||
enum mode_t {
|
||||
mode_dmg, // Game Boy monochrome
|
||||
mode_cgb, // Game Boy Color
|
||||
mode_agb // Game Boy Advance
|
||||
};
|
||||
void reset( mode_t mode = mode_cgb, bool agb_wave = false );
|
||||
|
||||
// Reads and writes must be within the start_addr to end_addr range, inclusive.
|
||||
// Addresses outside this range are not mapped to the sound hardware.
|
||||
enum { start_addr = 0xFF10 };
|
||||
enum { end_addr = 0xFF3F };
|
||||
enum { register_count = end_addr - start_addr + 1 };
|
||||
|
||||
// Times are specified as the number of clocks since the beginning of the
|
||||
// current time frame.
|
||||
|
||||
// Emulates CPU write of data to addr at specified time.
|
||||
void write_register( blip_time_t time, unsigned addr, int data );
|
||||
|
||||
// Emulates CPU read from addr at specified time.
|
||||
int read_register( blip_time_t time, unsigned addr );
|
||||
|
||||
// Emulates sound hardware up to specified time, ends current time frame, then
|
||||
// starts a new frame at time 0.
|
||||
void end_frame( blip_time_t frame_length );
|
||||
|
||||
// Sound adjustments
|
||||
|
||||
// Sets overall volume, where 1.0 is normal.
|
||||
void volume( double );
|
||||
|
||||
// If true, reduces clicking by disabling DAC biasing. Note that this reduces
|
||||
// emulation accuracy, since the clicks are authentic.
|
||||
void reduce_clicks( bool reduce = true );
|
||||
|
||||
// Sets treble equalization.
|
||||
void treble_eq( blip_eq_t const& );
|
||||
|
||||
// Treble and bass values for various hardware.
|
||||
enum {
|
||||
speaker_treble = -47, // speaker on system
|
||||
speaker_bass = 2000,
|
||||
dmg_treble = 0, // headphones on each system
|
||||
dmg_bass = 30,
|
||||
cgb_treble = 0,
|
||||
cgb_bass = 300, // CGB has much less bass
|
||||
agb_treble = 0,
|
||||
agb_bass = 30
|
||||
};
|
||||
|
||||
// Sets frame sequencer rate, where 1.0 is normal. Meant for adjusting the
|
||||
// tempo in a game music player.
|
||||
void set_tempo( double );
|
||||
|
||||
// Save states
|
||||
|
||||
// Saves full emulation state to state_out. Data format is portable and
|
||||
// includes some extra space to avoid expansion in case more state needs
|
||||
// to be stored in the future.
|
||||
void save_state( gb_apu_state_t* state_out );
|
||||
|
||||
// Loads state. You should call reset() BEFORE this.
|
||||
blargg_err_t load_state( gb_apu_state_t const& in );
|
||||
|
||||
public:
|
||||
Gb_Apu();
|
||||
|
||||
// Use set_output() in place of these
|
||||
BLARGG_DEPRECATED void output ( Blip_Buffer* c ) { set_output( c, c, c ); }
|
||||
BLARGG_DEPRECATED void output ( Blip_Buffer* c, Blip_Buffer* l, Blip_Buffer* r ) { set_output( c, l, r ); }
|
||||
BLARGG_DEPRECATED void osc_output( int i, Blip_Buffer* c ) { set_output( c, c, c, i ); }
|
||||
BLARGG_DEPRECATED void osc_output( int i, Blip_Buffer* c, Blip_Buffer* l, Blip_Buffer* r ) { set_output( c, l, r, i ); }
|
||||
|
||||
private:
|
||||
// noncopyable
|
||||
Gb_Apu( const Gb_Apu& );
|
||||
Gb_Apu& operator = ( const Gb_Apu& );
|
||||
|
||||
Gb_Osc* oscs [osc_count];
|
||||
blip_time_t last_time; // time sound emulator has been run to
|
||||
blip_time_t frame_period; // clocks between each frame sequencer step
|
||||
double volume_;
|
||||
bool reduce_clicks_;
|
||||
|
||||
Gb_Sweep_Square square1;
|
||||
Gb_Square square2;
|
||||
Gb_Wave wave;
|
||||
Gb_Noise noise;
|
||||
blip_time_t frame_time; // time of next frame sequencer action
|
||||
int frame_phase; // phase of next frame sequencer step
|
||||
enum { regs_size = register_count + 0x10 };
|
||||
BOOST::uint8_t regs [regs_size];// last values written to registers
|
||||
|
||||
// large objects after everything else
|
||||
Gb_Osc::Good_Synth good_synth;
|
||||
Gb_Osc::Med_Synth med_synth;
|
||||
|
||||
void reset_lengths();
|
||||
void reset_regs();
|
||||
int calc_output( int osc ) const;
|
||||
void apply_stereo();
|
||||
void apply_volume();
|
||||
void synth_volume( int );
|
||||
void run_until_( blip_time_t );
|
||||
void run_until( blip_time_t );
|
||||
void silence_osc( Gb_Osc& );
|
||||
void write_osc( int index, int reg, int old_data, int data );
|
||||
const char* save_load( gb_apu_state_t*, bool save );
|
||||
void save_load2( gb_apu_state_t*, bool save );
|
||||
friend class Gb_Apu_Tester;
|
||||
};
|
||||
|
||||
// Format of save state. Should be stable across versions of the library,
|
||||
// with earlier versions properly opening later save states. Includes some
|
||||
// room for expansion so the state size shouldn't increase.
|
||||
struct gb_apu_state_t
|
||||
{
|
||||
#if GB_APU_CUSTOM_STATE
|
||||
// Values stored as plain int so your code can read/write them easily.
|
||||
// Structure can NOT be written to disk, since format is not portable.
|
||||
typedef int val_t;
|
||||
#else
|
||||
// Values written in portable little-endian format, allowing structure
|
||||
// to be written directly to disk.
|
||||
typedef unsigned char val_t [4];
|
||||
#endif
|
||||
|
||||
enum { format0 = 0x50414247 };
|
||||
|
||||
val_t format; // format of all following data
|
||||
val_t version; // later versions just add fields to end
|
||||
|
||||
unsigned char regs [0x40];
|
||||
val_t frame_time;
|
||||
val_t frame_phase;
|
||||
|
||||
val_t sweep_freq;
|
||||
val_t sweep_delay;
|
||||
val_t sweep_enabled;
|
||||
val_t sweep_neg;
|
||||
val_t noise_divider;
|
||||
val_t wave_buf;
|
||||
|
||||
val_t delay [4];
|
||||
val_t length_ctr [4];
|
||||
val_t phase [4];
|
||||
val_t enabled [4];
|
||||
|
||||
val_t env_delay [3];
|
||||
val_t env_volume [3];
|
||||
val_t env_enabled [3];
|
||||
|
||||
val_t unused [13]; // for future expansion
|
||||
};
|
||||
|
||||
#endif
|
||||
// Nintendo Game Boy sound hardware emulator with save state support
|
||||
|
||||
// Gb_Snd_Emu 0.2.0
|
||||
#ifndef GB_APU_H
|
||||
#define GB_APU_H
|
||||
|
||||
#include "Gb_Oscs.h"
|
||||
|
||||
struct gb_apu_state_t;
|
||||
|
||||
class Gb_Apu {
|
||||
public:
|
||||
// Basics
|
||||
|
||||
// Clock rate that sound hardware runs at.
|
||||
enum { clock_rate = 4194304 * GB_APU_OVERCLOCK };
|
||||
|
||||
// Sets buffer(s) to generate sound into. If left and right are NULL, output is mono.
|
||||
// If all are NULL, no output is generated but other emulation still runs.
|
||||
// If chan is specified, only that channel's output is changed, otherwise all are.
|
||||
enum { osc_count = 4 }; // 0: Square 1, 1: Square 2, 2: Wave, 3: Noise
|
||||
void set_output( Blip_Buffer* center, Blip_Buffer* left = NULL, Blip_Buffer* right = NULL,
|
||||
int chan = osc_count );
|
||||
|
||||
// Resets hardware to initial power on state BEFORE boot ROM runs. Mode selects
|
||||
// sound hardware. Additional AGB wave features are enabled separately.
|
||||
enum mode_t {
|
||||
mode_dmg, // Game Boy monochrome
|
||||
mode_cgb, // Game Boy Color
|
||||
mode_agb // Game Boy Advance
|
||||
};
|
||||
void reset( mode_t mode = mode_cgb, bool agb_wave = false );
|
||||
|
||||
// Reads and writes must be within the start_addr to end_addr range, inclusive.
|
||||
// Addresses outside this range are not mapped to the sound hardware.
|
||||
enum { start_addr = 0xFF10 };
|
||||
enum { end_addr = 0xFF3F };
|
||||
enum { register_count = end_addr - start_addr + 1 };
|
||||
|
||||
// Times are specified as the number of clocks since the beginning of the
|
||||
// current time frame.
|
||||
|
||||
// Emulates CPU write of data to addr at specified time.
|
||||
void write_register( blip_time_t time, unsigned addr, int data );
|
||||
|
||||
// Emulates CPU read from addr at specified time.
|
||||
int read_register( blip_time_t time, unsigned addr );
|
||||
|
||||
// Emulates sound hardware up to specified time, ends current time frame, then
|
||||
// starts a new frame at time 0.
|
||||
void end_frame( blip_time_t frame_length );
|
||||
|
||||
// Sound adjustments
|
||||
|
||||
// Sets overall volume, where 1.0 is normal.
|
||||
void volume( double );
|
||||
|
||||
// If true, reduces clicking by disabling DAC biasing. Note that this reduces
|
||||
// emulation accuracy, since the clicks are authentic.
|
||||
void reduce_clicks( bool reduce = true );
|
||||
|
||||
// Sets treble equalization.
|
||||
void treble_eq( blip_eq_t const& );
|
||||
|
||||
// Treble and bass values for various hardware.
|
||||
enum {
|
||||
speaker_treble = -47, // speaker on system
|
||||
speaker_bass = 2000,
|
||||
dmg_treble = 0, // headphones on each system
|
||||
dmg_bass = 30,
|
||||
cgb_treble = 0,
|
||||
cgb_bass = 300, // CGB has much less bass
|
||||
agb_treble = 0,
|
||||
agb_bass = 30
|
||||
};
|
||||
|
||||
// Sets frame sequencer rate, where 1.0 is normal. Meant for adjusting the
|
||||
// tempo in a game music player.
|
||||
void set_tempo( double );
|
||||
|
||||
// Save states
|
||||
|
||||
// Saves full emulation state to state_out. Data format is portable and
|
||||
// includes some extra space to avoid expansion in case more state needs
|
||||
// to be stored in the future.
|
||||
void save_state( gb_apu_state_t* state_out );
|
||||
|
||||
// Loads state. You should call reset() BEFORE this.
|
||||
blargg_err_t load_state( gb_apu_state_t const& in );
|
||||
|
||||
public:
|
||||
Gb_Apu();
|
||||
|
||||
// Use set_output() in place of these
|
||||
BLARGG_DEPRECATED void output ( Blip_Buffer* c ) { set_output( c, c, c ); }
|
||||
BLARGG_DEPRECATED void output ( Blip_Buffer* c, Blip_Buffer* l, Blip_Buffer* r ) { set_output( c, l, r ); }
|
||||
BLARGG_DEPRECATED void osc_output( int i, Blip_Buffer* c ) { set_output( c, c, c, i ); }
|
||||
BLARGG_DEPRECATED void osc_output( int i, Blip_Buffer* c, Blip_Buffer* l, Blip_Buffer* r ) { set_output( c, l, r, i ); }
|
||||
|
||||
private:
|
||||
// noncopyable
|
||||
Gb_Apu( const Gb_Apu& );
|
||||
Gb_Apu& operator = ( const Gb_Apu& );
|
||||
|
||||
Gb_Osc* oscs [osc_count];
|
||||
blip_time_t last_time; // time sound emulator has been run to
|
||||
blip_time_t frame_period; // clocks between each frame sequencer step
|
||||
double volume_;
|
||||
bool reduce_clicks_;
|
||||
|
||||
Gb_Sweep_Square square1;
|
||||
Gb_Square square2;
|
||||
Gb_Wave wave;
|
||||
Gb_Noise noise;
|
||||
blip_time_t frame_time; // time of next frame sequencer action
|
||||
int frame_phase; // phase of next frame sequencer step
|
||||
enum { regs_size = register_count + 0x10 };
|
||||
BOOST::uint8_t regs [regs_size];// last values written to registers
|
||||
|
||||
// large objects after everything else
|
||||
Gb_Osc::Good_Synth good_synth;
|
||||
Gb_Osc::Med_Synth med_synth;
|
||||
|
||||
void reset_lengths();
|
||||
void reset_regs();
|
||||
int calc_output( int osc ) const;
|
||||
void apply_stereo();
|
||||
void apply_volume();
|
||||
void synth_volume( int );
|
||||
void run_until_( blip_time_t );
|
||||
void run_until( blip_time_t );
|
||||
void silence_osc( Gb_Osc& );
|
||||
void write_osc( int index, int reg, int old_data, int data );
|
||||
const char* save_load( gb_apu_state_t*, bool save );
|
||||
void save_load2( gb_apu_state_t*, bool save );
|
||||
friend class Gb_Apu_Tester;
|
||||
};
|
||||
|
||||
// Format of save state. Should be stable across versions of the library,
|
||||
// with earlier versions properly opening later save states. Includes some
|
||||
// room for expansion so the state size shouldn't increase.
|
||||
struct gb_apu_state_t
|
||||
{
|
||||
#if GB_APU_CUSTOM_STATE
|
||||
// Values stored as plain int so your code can read/write them easily.
|
||||
// Structure can NOT be written to disk, since format is not portable.
|
||||
typedef int val_t;
|
||||
#else
|
||||
// Values written in portable little-endian format, allowing structure
|
||||
// to be written directly to disk.
|
||||
typedef unsigned char val_t [4];
|
||||
#endif
|
||||
|
||||
enum { format0 = 0x50414247 };
|
||||
|
||||
val_t format; // format of all following data
|
||||
val_t version; // later versions just add fields to end
|
||||
|
||||
unsigned char regs [0x40];
|
||||
val_t frame_time;
|
||||
val_t frame_phase;
|
||||
|
||||
val_t sweep_freq;
|
||||
val_t sweep_delay;
|
||||
val_t sweep_enabled;
|
||||
val_t sweep_neg;
|
||||
val_t noise_divider;
|
||||
val_t wave_buf;
|
||||
|
||||
val_t delay [4];
|
||||
val_t length_ctr [4];
|
||||
val_t phase [4];
|
||||
val_t enabled [4];
|
||||
|
||||
val_t env_delay [3];
|
||||
val_t env_volume [3];
|
||||
val_t env_enabled [3];
|
||||
|
||||
val_t unused [13]; // for future expansion
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,118 +1,118 @@
|
|||
// Gb_Snd_Emu $vers. http://www.slack.net/~ant/
|
||||
|
||||
#include "Gb_Apu.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
/* Copyright (C) 2007 Shay Green. This module is free software; you
|
||||
can redistribute it and/or modify it under the terms of the GNU Lesser
|
||||
General Public License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version. This
|
||||
module is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
|
||||
details. You should have received a copy of the GNU Lesser General Public
|
||||
License along with this module; if not, write to the Free Software Foundation,
|
||||
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
|
||||
|
||||
#include "blargg_source.h"
|
||||
|
||||
#if GB_APU_CUSTOM_STATE
|
||||
#define REFLECT( x, y ) (save ? (io->y) = (x) : (x) = (io->y) )
|
||||
#else
|
||||
#define REFLECT( x, y ) (save ? set_val( io->y, x ) : (void) ((x) = get_val( io->y )))
|
||||
|
||||
static blargg_ulong get_val( byte const* p )
|
||||
{
|
||||
return p [3] * 0x1000000 + p [2] * 0x10000 + p [1] * 0x100 + p [0];
|
||||
}
|
||||
|
||||
static void set_val( byte* p, blargg_ulong n )
|
||||
{
|
||||
p [0] = (byte) (n );
|
||||
p [1] = (byte) (n >> 8);
|
||||
p [2] = (byte) (n >> 16);
|
||||
p [3] = (byte) (n >> 24);
|
||||
}
|
||||
#endif
|
||||
|
||||
inline const char* Gb_Apu::save_load( gb_apu_state_t* io, bool save )
|
||||
{
|
||||
#if !GB_APU_CUSTOM_STATE
|
||||
assert( sizeof (gb_apu_state_t) == 256 );
|
||||
#endif
|
||||
|
||||
int format = io->format0;
|
||||
REFLECT( format, format );
|
||||
if ( format != io->format0 )
|
||||
return "Unsupported sound save state format";
|
||||
|
||||
int version = 0;
|
||||
REFLECT( version, version );
|
||||
|
||||
// Registers and wave RAM
|
||||
assert( regs_size == sizeof io->regs );
|
||||
if ( save )
|
||||
memcpy( io->regs, regs, sizeof io->regs );
|
||||
else
|
||||
memcpy( regs, io->regs, sizeof regs );
|
||||
|
||||
// Frame sequencer
|
||||
REFLECT( frame_time, frame_time );
|
||||
REFLECT( frame_phase, frame_phase );
|
||||
|
||||
REFLECT( square1.sweep_freq, sweep_freq );
|
||||
REFLECT( square1.sweep_delay, sweep_delay );
|
||||
REFLECT( square1.sweep_enabled, sweep_enabled );
|
||||
REFLECT( square1.sweep_neg, sweep_neg );
|
||||
|
||||
REFLECT( noise.divider, noise_divider );
|
||||
REFLECT( wave.sample_buf, wave_buf );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// second function to avoid inline limits of some compilers
|
||||
inline void Gb_Apu::save_load2( gb_apu_state_t* io, bool save )
|
||||
{
|
||||
for ( int i = osc_count; --i >= 0; )
|
||||
{
|
||||
Gb_Osc& osc = *oscs [i];
|
||||
REFLECT( osc.delay, delay [i] );
|
||||
REFLECT( osc.length_ctr, length_ctr [i] );
|
||||
REFLECT( osc.phase, phase [i] );
|
||||
REFLECT( osc.enabled, enabled [i] );
|
||||
|
||||
if ( i != 2 )
|
||||
{
|
||||
int j = min( i, 2 );
|
||||
Gb_Env& env = STATIC_CAST(Gb_Env&,osc);
|
||||
REFLECT( env.env_delay, env_delay [j] );
|
||||
REFLECT( env.volume, env_volume [j] );
|
||||
REFLECT( env.env_enabled, env_enabled [j] );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Gb_Apu::save_state( gb_apu_state_t* out )
|
||||
{
|
||||
(void) save_load( out, true );
|
||||
save_load2( out, true );
|
||||
|
||||
#if !GB_APU_CUSTOM_STATE
|
||||
memset( out->unused, 0, sizeof out->unused );
|
||||
#endif
|
||||
}
|
||||
|
||||
blargg_err_t Gb_Apu::load_state( gb_apu_state_t const& in )
|
||||
{
|
||||
RETURN_ERR( save_load( CONST_CAST(gb_apu_state_t*,&in), false ) );
|
||||
save_load2( CONST_CAST(gb_apu_state_t*,&in), false );
|
||||
|
||||
apply_stereo();
|
||||
synth_volume( 0 ); // suppress output for the moment
|
||||
run_until_( last_time ); // get last_amp updated
|
||||
apply_volume(); // now use correct volume
|
||||
|
||||
return 0;
|
||||
}
|
||||
// Gb_Snd_Emu $vers. http://www.slack.net/~ant/
|
||||
|
||||
#include "Gb_Apu.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
/* Copyright (C) 2007 Shay Green. This module is free software; you
|
||||
can redistribute it and/or modify it under the terms of the GNU Lesser
|
||||
General Public License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version. This
|
||||
module is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
|
||||
details. You should have received a copy of the GNU Lesser General Public
|
||||
License along with this module; if not, write to the Free Software Foundation,
|
||||
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
|
||||
|
||||
#include "blargg_source.h"
|
||||
|
||||
#if GB_APU_CUSTOM_STATE
|
||||
#define REFLECT( x, y ) (save ? (io->y) = (x) : (x) = (io->y) )
|
||||
#else
|
||||
#define REFLECT( x, y ) (save ? set_val( io->y, x ) : (void) ((x) = get_val( io->y )))
|
||||
|
||||
static blargg_ulong get_val( byte const* p )
|
||||
{
|
||||
return p [3] * 0x1000000 + p [2] * 0x10000 + p [1] * 0x100 + p [0];
|
||||
}
|
||||
|
||||
static void set_val( byte* p, blargg_ulong n )
|
||||
{
|
||||
p [0] = (byte) (n );
|
||||
p [1] = (byte) (n >> 8);
|
||||
p [2] = (byte) (n >> 16);
|
||||
p [3] = (byte) (n >> 24);
|
||||
}
|
||||
#endif
|
||||
|
||||
inline const char* Gb_Apu::save_load( gb_apu_state_t* io, bool save )
|
||||
{
|
||||
#if !GB_APU_CUSTOM_STATE
|
||||
assert( sizeof (gb_apu_state_t) == 256 );
|
||||
#endif
|
||||
|
||||
int format = io->format0;
|
||||
REFLECT( format, format );
|
||||
if ( format != io->format0 )
|
||||
return "Unsupported sound save state format";
|
||||
|
||||
int version = 0;
|
||||
REFLECT( version, version );
|
||||
|
||||
// Registers and wave RAM
|
||||
assert( regs_size == sizeof io->regs );
|
||||
if ( save )
|
||||
memcpy( io->regs, regs, sizeof io->regs );
|
||||
else
|
||||
memcpy( regs, io->regs, sizeof regs );
|
||||
|
||||
// Frame sequencer
|
||||
REFLECT( frame_time, frame_time );
|
||||
REFLECT( frame_phase, frame_phase );
|
||||
|
||||
REFLECT( square1.sweep_freq, sweep_freq );
|
||||
REFLECT( square1.sweep_delay, sweep_delay );
|
||||
REFLECT( square1.sweep_enabled, sweep_enabled );
|
||||
REFLECT( square1.sweep_neg, sweep_neg );
|
||||
|
||||
REFLECT( noise.divider, noise_divider );
|
||||
REFLECT( wave.sample_buf, wave_buf );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// second function to avoid inline limits of some compilers
|
||||
inline void Gb_Apu::save_load2( gb_apu_state_t* io, bool save )
|
||||
{
|
||||
for ( int i = osc_count; --i >= 0; )
|
||||
{
|
||||
Gb_Osc& osc = *oscs [i];
|
||||
REFLECT( osc.delay, delay [i] );
|
||||
REFLECT( osc.length_ctr, length_ctr [i] );
|
||||
REFLECT( osc.phase, phase [i] );
|
||||
REFLECT( osc.enabled, enabled [i] );
|
||||
|
||||
if ( i != 2 )
|
||||
{
|
||||
int j = min( i, 2 );
|
||||
Gb_Env& env = STATIC_CAST(Gb_Env&,osc);
|
||||
REFLECT( env.env_delay, env_delay [j] );
|
||||
REFLECT( env.volume, env_volume [j] );
|
||||
REFLECT( env.env_enabled, env_enabled [j] );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Gb_Apu::save_state( gb_apu_state_t* out )
|
||||
{
|
||||
(void) save_load( out, true );
|
||||
save_load2( out, true );
|
||||
|
||||
#if !GB_APU_CUSTOM_STATE
|
||||
memset( out->unused, 0, sizeof out->unused );
|
||||
#endif
|
||||
}
|
||||
|
||||
blargg_err_t Gb_Apu::load_state( gb_apu_state_t const& in )
|
||||
{
|
||||
RETURN_ERR( save_load( CONST_CAST(gb_apu_state_t*,&in), false ) );
|
||||
save_load2( CONST_CAST(gb_apu_state_t*,&in), false );
|
||||
|
||||
apply_stereo();
|
||||
synth_volume( 0 ); // suppress output for the moment
|
||||
run_until_( last_time ); // get last_amp updated
|
||||
apply_volume(); // now use correct volume
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,190 +1,190 @@
|
|||
// Private oscillators used by Gb_Apu
|
||||
|
||||
// Gb_Snd_Emu 0.2.0
|
||||
#ifndef GB_OSCS_H
|
||||
#define GB_OSCS_H
|
||||
|
||||
#include "blargg_common.h"
|
||||
#include "Blip_Buffer.h"
|
||||
|
||||
#ifndef GB_APU_OVERCLOCK
|
||||
#define GB_APU_OVERCLOCK 1
|
||||
#endif
|
||||
|
||||
#if GB_APU_OVERCLOCK & (GB_APU_OVERCLOCK - 1)
|
||||
#error "GB_APU_OVERCLOCK must be a power of 2"
|
||||
#endif
|
||||
|
||||
class Gb_Osc {
|
||||
protected:
|
||||
|
||||
// 11-bit frequency in NRx3 and NRx4
|
||||
int frequency() const { return (regs [4] & 7) * 0x100 + regs [3]; }
|
||||
|
||||
void update_amp( blip_time_t, int new_amp );
|
||||
int write_trig( int frame_phase, int max_len, int old_data );
|
||||
public:
|
||||
|
||||
enum { clk_mul = GB_APU_OVERCLOCK };
|
||||
enum { dac_bias = 7 };
|
||||
|
||||
Blip_Buffer* outputs [4];// NULL, right, left, center
|
||||
Blip_Buffer* output; // where to output sound
|
||||
BOOST::uint8_t* regs; // osc's 5 registers
|
||||
int mode; // mode_dmg, mode_cgb, mode_agb
|
||||
int dac_off_amp;// amplitude when DAC is off
|
||||
int last_amp; // current amplitude in Blip_Buffer
|
||||
typedef Blip_Synth<blip_good_quality,1> Good_Synth;
|
||||
typedef Blip_Synth<blip_med_quality ,1> Med_Synth;
|
||||
Good_Synth const* good_synth;
|
||||
Med_Synth const* med_synth;
|
||||
|
||||
int delay; // clocks until frequency timer expires
|
||||
int length_ctr; // length counter
|
||||
unsigned phase; // waveform phase (or equivalent)
|
||||
bool enabled; // internal enabled flag
|
||||
|
||||
void clock_length();
|
||||
void reset();
|
||||
};
|
||||
|
||||
class Gb_Env : public Gb_Osc {
|
||||
public:
|
||||
int env_delay;
|
||||
int volume;
|
||||
bool env_enabled;
|
||||
|
||||
void clock_envelope();
|
||||
bool write_register( int frame_phase, int reg, int old_data, int data );
|
||||
|
||||
void reset()
|
||||
{
|
||||
env_delay = 0;
|
||||
volume = 0;
|
||||
Gb_Osc::reset();
|
||||
}
|
||||
protected:
|
||||
// Non-zero if DAC is enabled
|
||||
int dac_enabled() const { return regs [2] & 0xF8; }
|
||||
private:
|
||||
void zombie_volume( int old, int data );
|
||||
int reload_env_timer();
|
||||
};
|
||||
|
||||
class Gb_Square : public Gb_Env {
|
||||
public:
|
||||
bool write_register( int frame_phase, int reg, int old_data, int data );
|
||||
void run( blip_time_t, blip_time_t );
|
||||
|
||||
void reset()
|
||||
{
|
||||
Gb_Env::reset();
|
||||
delay = 0x40000000; // TODO: something less hacky (never clocked until first trigger)
|
||||
}
|
||||
private:
|
||||
// Frequency timer period
|
||||
int period() const { return (2048 - frequency()) * (4 * clk_mul); }
|
||||
};
|
||||
|
||||
class Gb_Sweep_Square : public Gb_Square {
|
||||
public:
|
||||
int sweep_freq;
|
||||
int sweep_delay;
|
||||
bool sweep_enabled;
|
||||
bool sweep_neg;
|
||||
|
||||
void clock_sweep();
|
||||
void write_register( int frame_phase, int reg, int old_data, int data );
|
||||
|
||||
void reset()
|
||||
{
|
||||
sweep_freq = 0;
|
||||
sweep_delay = 0;
|
||||
sweep_enabled = false;
|
||||
sweep_neg = false;
|
||||
Gb_Square::reset();
|
||||
}
|
||||
private:
|
||||
enum { period_mask = 0x70 };
|
||||
enum { shift_mask = 0x07 };
|
||||
|
||||
void calc_sweep( bool update );
|
||||
void reload_sweep_timer();
|
||||
};
|
||||
|
||||
class Gb_Noise : public Gb_Env {
|
||||
public:
|
||||
|
||||
int divider; // noise has more complex frequency divider setup
|
||||
|
||||
void run( blip_time_t, blip_time_t );
|
||||
void write_register( int frame_phase, int reg, int old_data, int data );
|
||||
|
||||
void reset()
|
||||
{
|
||||
divider = 0;
|
||||
Gb_Env::reset();
|
||||
delay = 4 * clk_mul; // TODO: remove?
|
||||
}
|
||||
private:
|
||||
enum { period2_mask = 0x1FFFF };
|
||||
|
||||
int period2_index() const { return regs [3] >> 4; }
|
||||
int period2( int base = 8 ) const { return base << period2_index(); }
|
||||
unsigned lfsr_mask() const { return (regs [3] & 0x08) ? ~0x4040 : ~0x4000; }
|
||||
};
|
||||
|
||||
class Gb_Wave : public Gb_Osc {
|
||||
public:
|
||||
int sample_buf; // last wave RAM byte read (hardware has this as well)
|
||||
|
||||
void write_register( int frame_phase, int reg, int old_data, int data );
|
||||
void run( blip_time_t, blip_time_t );
|
||||
|
||||
// Reads/writes wave RAM
|
||||
int read( unsigned addr ) const;
|
||||
void write( unsigned addr, int data );
|
||||
|
||||
void reset()
|
||||
{
|
||||
sample_buf = 0;
|
||||
Gb_Osc::reset();
|
||||
}
|
||||
|
||||
private:
|
||||
enum { bank40_mask = 0x40 };
|
||||
enum { bank_size = 32 };
|
||||
|
||||
int agb_mask; // 0xFF if AGB features enabled, 0 otherwise
|
||||
BOOST::uint8_t* wave_ram; // 32 bytes (64 nybbles), stored in APU
|
||||
|
||||
friend class Gb_Apu;
|
||||
|
||||
// Frequency timer period
|
||||
int period() const { return (2048 - frequency()) * (2 * clk_mul); }
|
||||
|
||||
// Non-zero if DAC is enabled
|
||||
int dac_enabled() const { return regs [0] & 0x80; }
|
||||
|
||||
void corrupt_wave();
|
||||
|
||||
BOOST::uint8_t* wave_bank() const { return &wave_ram [(~regs [0] & bank40_mask) >> 2 & agb_mask]; }
|
||||
|
||||
// Wave index that would be accessed, or -1 if no access would occur
|
||||
int access( unsigned addr ) const;
|
||||
};
|
||||
|
||||
inline int Gb_Wave::read( unsigned addr ) const
|
||||
{
|
||||
int index = access( addr );
|
||||
return (index < 0 ? 0xFF : wave_bank() [index]);
|
||||
}
|
||||
|
||||
inline void Gb_Wave::write( unsigned addr, int data )
|
||||
{
|
||||
int index = access( addr );
|
||||
if ( index >= 0 )
|
||||
wave_bank() [index] = data;;
|
||||
}
|
||||
|
||||
#endif
|
||||
// Private oscillators used by Gb_Apu
|
||||
|
||||
// Gb_Snd_Emu 0.2.0
|
||||
#ifndef GB_OSCS_H
|
||||
#define GB_OSCS_H
|
||||
|
||||
#include "blargg_common.h"
|
||||
#include "Blip_Buffer.h"
|
||||
|
||||
#ifndef GB_APU_OVERCLOCK
|
||||
#define GB_APU_OVERCLOCK 1
|
||||
#endif
|
||||
|
||||
#if GB_APU_OVERCLOCK & (GB_APU_OVERCLOCK - 1)
|
||||
#error "GB_APU_OVERCLOCK must be a power of 2"
|
||||
#endif
|
||||
|
||||
class Gb_Osc {
|
||||
protected:
|
||||
|
||||
// 11-bit frequency in NRx3 and NRx4
|
||||
int frequency() const { return (regs [4] & 7) * 0x100 + regs [3]; }
|
||||
|
||||
void update_amp( blip_time_t, int new_amp );
|
||||
int write_trig( int frame_phase, int max_len, int old_data );
|
||||
public:
|
||||
|
||||
enum { clk_mul = GB_APU_OVERCLOCK };
|
||||
enum { dac_bias = 7 };
|
||||
|
||||
Blip_Buffer* outputs [4];// NULL, right, left, center
|
||||
Blip_Buffer* output; // where to output sound
|
||||
BOOST::uint8_t* regs; // osc's 5 registers
|
||||
int mode; // mode_dmg, mode_cgb, mode_agb
|
||||
int dac_off_amp;// amplitude when DAC is off
|
||||
int last_amp; // current amplitude in Blip_Buffer
|
||||
typedef Blip_Synth<blip_good_quality,1> Good_Synth;
|
||||
typedef Blip_Synth<blip_med_quality ,1> Med_Synth;
|
||||
Good_Synth const* good_synth;
|
||||
Med_Synth const* med_synth;
|
||||
|
||||
int delay; // clocks until frequency timer expires
|
||||
int length_ctr; // length counter
|
||||
unsigned phase; // waveform phase (or equivalent)
|
||||
bool enabled; // internal enabled flag
|
||||
|
||||
void clock_length();
|
||||
void reset();
|
||||
};
|
||||
|
||||
class Gb_Env : public Gb_Osc {
|
||||
public:
|
||||
int env_delay;
|
||||
int volume;
|
||||
bool env_enabled;
|
||||
|
||||
void clock_envelope();
|
||||
bool write_register( int frame_phase, int reg, int old_data, int data );
|
||||
|
||||
void reset()
|
||||
{
|
||||
env_delay = 0;
|
||||
volume = 0;
|
||||
Gb_Osc::reset();
|
||||
}
|
||||
protected:
|
||||
// Non-zero if DAC is enabled
|
||||
int dac_enabled() const { return regs [2] & 0xF8; }
|
||||
private:
|
||||
void zombie_volume( int old, int data );
|
||||
int reload_env_timer();
|
||||
};
|
||||
|
||||
class Gb_Square : public Gb_Env {
|
||||
public:
|
||||
bool write_register( int frame_phase, int reg, int old_data, int data );
|
||||
void run( blip_time_t, blip_time_t );
|
||||
|
||||
void reset()
|
||||
{
|
||||
Gb_Env::reset();
|
||||
delay = 0x40000000; // TODO: something less hacky (never clocked until first trigger)
|
||||
}
|
||||
private:
|
||||
// Frequency timer period
|
||||
int period() const { return (2048 - frequency()) * (4 * clk_mul); }
|
||||
};
|
||||
|
||||
class Gb_Sweep_Square : public Gb_Square {
|
||||
public:
|
||||
int sweep_freq;
|
||||
int sweep_delay;
|
||||
bool sweep_enabled;
|
||||
bool sweep_neg;
|
||||
|
||||
void clock_sweep();
|
||||
void write_register( int frame_phase, int reg, int old_data, int data );
|
||||
|
||||
void reset()
|
||||
{
|
||||
sweep_freq = 0;
|
||||
sweep_delay = 0;
|
||||
sweep_enabled = false;
|
||||
sweep_neg = false;
|
||||
Gb_Square::reset();
|
||||
}
|
||||
private:
|
||||
enum { period_mask = 0x70 };
|
||||
enum { shift_mask = 0x07 };
|
||||
|
||||
void calc_sweep( bool update );
|
||||
void reload_sweep_timer();
|
||||
};
|
||||
|
||||
class Gb_Noise : public Gb_Env {
|
||||
public:
|
||||
|
||||
int divider; // noise has more complex frequency divider setup
|
||||
|
||||
void run( blip_time_t, blip_time_t );
|
||||
void write_register( int frame_phase, int reg, int old_data, int data );
|
||||
|
||||
void reset()
|
||||
{
|
||||
divider = 0;
|
||||
Gb_Env::reset();
|
||||
delay = 4 * clk_mul; // TODO: remove?
|
||||
}
|
||||
private:
|
||||
enum { period2_mask = 0x1FFFF };
|
||||
|
||||
int period2_index() const { return regs [3] >> 4; }
|
||||
int period2( int base = 8 ) const { return base << period2_index(); }
|
||||
unsigned lfsr_mask() const { return (regs [3] & 0x08) ? ~0x4040 : ~0x4000; }
|
||||
};
|
||||
|
||||
class Gb_Wave : public Gb_Osc {
|
||||
public:
|
||||
int sample_buf; // last wave RAM byte read (hardware has this as well)
|
||||
|
||||
void write_register( int frame_phase, int reg, int old_data, int data );
|
||||
void run( blip_time_t, blip_time_t );
|
||||
|
||||
// Reads/writes wave RAM
|
||||
int read( unsigned addr ) const;
|
||||
void write( unsigned addr, int data );
|
||||
|
||||
void reset()
|
||||
{
|
||||
sample_buf = 0;
|
||||
Gb_Osc::reset();
|
||||
}
|
||||
|
||||
private:
|
||||
enum { bank40_mask = 0x40 };
|
||||
enum { bank_size = 32 };
|
||||
|
||||
int agb_mask; // 0xFF if AGB features enabled, 0 otherwise
|
||||
BOOST::uint8_t* wave_ram; // 32 bytes (64 nybbles), stored in APU
|
||||
|
||||
friend class Gb_Apu;
|
||||
|
||||
// Frequency timer period
|
||||
int period() const { return (2048 - frequency()) * (2 * clk_mul); }
|
||||
|
||||
// Non-zero if DAC is enabled
|
||||
int dac_enabled() const { return regs [0] & 0x80; }
|
||||
|
||||
void corrupt_wave();
|
||||
|
||||
BOOST::uint8_t* wave_bank() const { return &wave_ram [(~regs [0] & bank40_mask) >> 2 & agb_mask]; }
|
||||
|
||||
// Wave index that would be accessed, or -1 if no access would occur
|
||||
int access( unsigned addr ) const;
|
||||
};
|
||||
|
||||
inline int Gb_Wave::read( unsigned addr ) const
|
||||
{
|
||||
int index = access( addr );
|
||||
return (index < 0 ? 0xFF : wave_bank() [index]);
|
||||
}
|
||||
|
||||
inline void Gb_Wave::write( unsigned addr, int data )
|
||||
{
|
||||
int index = access( addr );
|
||||
if ( index >= 0 )
|
||||
wave_bank() [index] = data;;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,281 +1,281 @@
|
|||
// Blip_Buffer 0.4.1. http://www.slack.net/~ant/
|
||||
|
||||
#include "Multi_Buffer.h"
|
||||
|
||||
/* Copyright (C) 2003-2007 Shay Green. This module is free software; you
|
||||
can redistribute it and/or modify it under the terms of the GNU Lesser
|
||||
General Public License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version. This
|
||||
module is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
|
||||
details. You should have received a copy of the GNU Lesser General Public
|
||||
License along with this module; if not, write to the Free Software Foundation,
|
||||
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
|
||||
|
||||
#include "blargg_source.h"
|
||||
|
||||
#ifdef BLARGG_ENABLE_OPTIMIZER
|
||||
#include BLARGG_ENABLE_OPTIMIZER
|
||||
#endif
|
||||
|
||||
Multi_Buffer::Multi_Buffer( int spf ) : samples_per_frame_( spf )
|
||||
{
|
||||
length_ = 0;
|
||||
sample_rate_ = 0;
|
||||
channels_changed_count_ = 1;
|
||||
channel_types_ = 0;
|
||||
channel_count_ = 0;
|
||||
immediate_removal_ = true;
|
||||
}
|
||||
|
||||
Multi_Buffer::channel_t Multi_Buffer::channel( int /*index*/ )
|
||||
{
|
||||
static channel_t const ch = { 0, 0, 0 };
|
||||
return ch;
|
||||
}
|
||||
|
||||
// Silent_Buffer
|
||||
|
||||
Silent_Buffer::Silent_Buffer() : Multi_Buffer( 1 ) // 0 channels would probably confuse
|
||||
{
|
||||
// TODO: better to use empty Blip_Buffer so caller never has to check for NULL?
|
||||
chan.left = 0;
|
||||
chan.center = 0;
|
||||
chan.right = 0;
|
||||
}
|
||||
|
||||
// Mono_Buffer
|
||||
|
||||
Mono_Buffer::Mono_Buffer() : Multi_Buffer( 1 )
|
||||
{
|
||||
chan.center = &buf;
|
||||
chan.left = &buf;
|
||||
chan.right = &buf;
|
||||
}
|
||||
|
||||
Mono_Buffer::~Mono_Buffer() { }
|
||||
|
||||
blargg_err_t Mono_Buffer::set_sample_rate( long rate, int msec )
|
||||
{
|
||||
RETURN_ERR( buf.set_sample_rate( rate, msec ) );
|
||||
return Multi_Buffer::set_sample_rate( buf.sample_rate(), buf.length() );
|
||||
}
|
||||
|
||||
|
||||
// Tracked_Blip_Buffer
|
||||
|
||||
Tracked_Blip_Buffer::Tracked_Blip_Buffer()
|
||||
{
|
||||
last_non_silence = 0;
|
||||
}
|
||||
|
||||
void Tracked_Blip_Buffer::clear()
|
||||
{
|
||||
last_non_silence = 0;
|
||||
Blip_Buffer::clear();
|
||||
}
|
||||
|
||||
void Tracked_Blip_Buffer::end_frame( blip_time_t t )
|
||||
{
|
||||
Blip_Buffer::end_frame( t );
|
||||
if ( clear_modified() )
|
||||
last_non_silence = samples_avail() + blip_buffer_extra_;
|
||||
}
|
||||
|
||||
blip_ulong Tracked_Blip_Buffer::non_silent() const
|
||||
{
|
||||
return last_non_silence | unsettled();
|
||||
}
|
||||
|
||||
inline void Tracked_Blip_Buffer::remove_( long n )
|
||||
{
|
||||
if ( (last_non_silence -= n) < 0 )
|
||||
last_non_silence = 0;
|
||||
}
|
||||
|
||||
void Tracked_Blip_Buffer::remove_silence( long n )
|
||||
{
|
||||
remove_( n );
|
||||
Blip_Buffer::remove_silence( n );
|
||||
}
|
||||
|
||||
void Tracked_Blip_Buffer::remove_samples( long n )
|
||||
{
|
||||
remove_( n );
|
||||
Blip_Buffer::remove_samples( n );
|
||||
}
|
||||
|
||||
void Tracked_Blip_Buffer::remove_all_samples()
|
||||
{
|
||||
long avail = samples_avail();
|
||||
if ( !non_silent() )
|
||||
remove_silence( avail );
|
||||
else
|
||||
remove_samples( avail );
|
||||
}
|
||||
|
||||
long Tracked_Blip_Buffer::read_samples( blip_sample_t* out, long count )
|
||||
{
|
||||
count = Blip_Buffer::read_samples( out, count );
|
||||
remove_( count );
|
||||
return count;
|
||||
}
|
||||
|
||||
// Stereo_Buffer
|
||||
|
||||
int const stereo = 2;
|
||||
|
||||
Stereo_Buffer::Stereo_Buffer() : Multi_Buffer( 2 )
|
||||
{
|
||||
chan.center = mixer.bufs [2] = &bufs [2];
|
||||
chan.left = mixer.bufs [0] = &bufs [0];
|
||||
chan.right = mixer.bufs [1] = &bufs [1];
|
||||
mixer.samples_read = 0;
|
||||
}
|
||||
|
||||
Stereo_Buffer::~Stereo_Buffer() { }
|
||||
|
||||
blargg_err_t Stereo_Buffer::set_sample_rate( long rate, int msec )
|
||||
{
|
||||
mixer.samples_read = 0;
|
||||
for ( int i = bufs_size; --i >= 0; )
|
||||
RETURN_ERR( bufs [i].set_sample_rate( rate, msec ) );
|
||||
return Multi_Buffer::set_sample_rate( bufs [0].sample_rate(), bufs [0].length() );
|
||||
}
|
||||
|
||||
void Stereo_Buffer::clock_rate( long rate )
|
||||
{
|
||||
for ( int i = bufs_size; --i >= 0; )
|
||||
bufs [i].clock_rate( rate );
|
||||
}
|
||||
|
||||
void Stereo_Buffer::bass_freq( int bass )
|
||||
{
|
||||
for ( int i = bufs_size; --i >= 0; )
|
||||
bufs [i].bass_freq( bass );
|
||||
}
|
||||
|
||||
void Stereo_Buffer::clear()
|
||||
{
|
||||
mixer.samples_read = 0;
|
||||
for ( int i = bufs_size; --i >= 0; )
|
||||
bufs [i].clear();
|
||||
}
|
||||
|
||||
void Stereo_Buffer::end_frame( blip_time_t time )
|
||||
{
|
||||
for ( int i = bufs_size; --i >= 0; )
|
||||
bufs [i].end_frame( time );
|
||||
}
|
||||
|
||||
long Stereo_Buffer::read_samples( blip_sample_t* out, long out_size )
|
||||
{
|
||||
require( (out_size & 1) == 0 ); // must read an even number of samples
|
||||
out_size = min( out_size, samples_avail() );
|
||||
|
||||
int pair_count = int (out_size >> 1);
|
||||
if ( pair_count )
|
||||
{
|
||||
mixer.read_pairs( out, pair_count );
|
||||
|
||||
if ( samples_avail() <= 0 || immediate_removal() )
|
||||
{
|
||||
for ( int i = bufs_size; --i >= 0; )
|
||||
{
|
||||
buf_t& b = bufs [i];
|
||||
// TODO: might miss non-silence settling since it checks END of last read
|
||||
if ( !b.non_silent() )
|
||||
b.remove_silence( mixer.samples_read );
|
||||
else
|
||||
b.remove_samples( mixer.samples_read );
|
||||
}
|
||||
mixer.samples_read = 0;
|
||||
}
|
||||
}
|
||||
return out_size;
|
||||
}
|
||||
|
||||
|
||||
// Stereo_Mixer
|
||||
|
||||
// mixers use a single index value to improve performance on register-challenged processors
|
||||
// offset goes from negative to zero
|
||||
|
||||
void Stereo_Mixer::read_pairs( blip_sample_t* out, int count )
|
||||
{
|
||||
// TODO: if caller never marks buffers as modified, uses mono
|
||||
// except that buffer isn't cleared, so caller can encounter
|
||||
// subtle problems and not realize the cause.
|
||||
samples_read += count;
|
||||
if ( bufs [0]->non_silent() | bufs [1]->non_silent() )
|
||||
mix_stereo( out, count );
|
||||
else
|
||||
mix_mono( out, count );
|
||||
}
|
||||
|
||||
void Stereo_Mixer::mix_mono( blip_sample_t* out_, int count )
|
||||
{
|
||||
int const bass = BLIP_READER_BASS( *bufs [2] );
|
||||
BLIP_READER_BEGIN( center, *bufs [2] );
|
||||
BLIP_READER_ADJ_( center, samples_read );
|
||||
|
||||
typedef blip_sample_t stereo_blip_sample_t [stereo];
|
||||
stereo_blip_sample_t* BLIP_RESTRICT out = (stereo_blip_sample_t*) out_ + count;
|
||||
int offset = -count;
|
||||
do
|
||||
{
|
||||
blargg_long s = BLIP_READER_READ( center );
|
||||
BLIP_READER_NEXT_IDX_( center, bass, offset );
|
||||
BLIP_CLAMP( s, s );
|
||||
|
||||
out [offset] [0] = (blip_sample_t) s;
|
||||
out [offset] [1] = (blip_sample_t) s;
|
||||
}
|
||||
while ( ++offset );
|
||||
|
||||
BLIP_READER_END( center, *bufs [2] );
|
||||
}
|
||||
|
||||
void Stereo_Mixer::mix_stereo( blip_sample_t* out_, int count )
|
||||
{
|
||||
blip_sample_t* BLIP_RESTRICT out = out_ + count * stereo;
|
||||
|
||||
// do left + center and right + center separately to reduce register load
|
||||
Tracked_Blip_Buffer* const* buf = &bufs [2];
|
||||
while ( true ) // loop runs twice
|
||||
{
|
||||
--buf;
|
||||
--out;
|
||||
|
||||
int const bass = BLIP_READER_BASS( *bufs [2] );
|
||||
BLIP_READER_BEGIN( side, **buf );
|
||||
BLIP_READER_BEGIN( center, *bufs [2] );
|
||||
|
||||
BLIP_READER_ADJ_( side, samples_read );
|
||||
BLIP_READER_ADJ_( center, samples_read );
|
||||
|
||||
int offset = -count;
|
||||
do
|
||||
{
|
||||
blargg_long s = BLIP_READER_READ_RAW( center ) + BLIP_READER_READ_RAW( side );
|
||||
s >>= blip_sample_bits - 16;
|
||||
BLIP_READER_NEXT_IDX_( side, bass, offset );
|
||||
BLIP_READER_NEXT_IDX_( center, bass, offset );
|
||||
BLIP_CLAMP( s, s );
|
||||
|
||||
++offset; // before write since out is decremented to slightly before end
|
||||
out [offset * stereo] = (blip_sample_t) s;
|
||||
}
|
||||
while ( offset );
|
||||
|
||||
BLIP_READER_END( side, **buf );
|
||||
|
||||
if ( buf != bufs )
|
||||
continue;
|
||||
|
||||
// only end center once
|
||||
BLIP_READER_END( center, *bufs [2] );
|
||||
break;
|
||||
}
|
||||
}
|
||||
// Blip_Buffer 0.4.1. http://www.slack.net/~ant/
|
||||
|
||||
#include "Multi_Buffer.h"
|
||||
|
||||
/* Copyright (C) 2003-2007 Shay Green. This module is free software; you
|
||||
can redistribute it and/or modify it under the terms of the GNU Lesser
|
||||
General Public License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version. This
|
||||
module is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
|
||||
details. You should have received a copy of the GNU Lesser General Public
|
||||
License along with this module; if not, write to the Free Software Foundation,
|
||||
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
|
||||
|
||||
#include "blargg_source.h"
|
||||
|
||||
#ifdef BLARGG_ENABLE_OPTIMIZER
|
||||
#include BLARGG_ENABLE_OPTIMIZER
|
||||
#endif
|
||||
|
||||
Multi_Buffer::Multi_Buffer( int spf ) : samples_per_frame_( spf )
|
||||
{
|
||||
length_ = 0;
|
||||
sample_rate_ = 0;
|
||||
channels_changed_count_ = 1;
|
||||
channel_types_ = 0;
|
||||
channel_count_ = 0;
|
||||
immediate_removal_ = true;
|
||||
}
|
||||
|
||||
Multi_Buffer::channel_t Multi_Buffer::channel( int /*index*/ )
|
||||
{
|
||||
static channel_t const ch = { 0, 0, 0 };
|
||||
return ch;
|
||||
}
|
||||
|
||||
// Silent_Buffer
|
||||
|
||||
Silent_Buffer::Silent_Buffer() : Multi_Buffer( 1 ) // 0 channels would probably confuse
|
||||
{
|
||||
// TODO: better to use empty Blip_Buffer so caller never has to check for NULL?
|
||||
chan.left = 0;
|
||||
chan.center = 0;
|
||||
chan.right = 0;
|
||||
}
|
||||
|
||||
// Mono_Buffer
|
||||
|
||||
Mono_Buffer::Mono_Buffer() : Multi_Buffer( 1 )
|
||||
{
|
||||
chan.center = &buf;
|
||||
chan.left = &buf;
|
||||
chan.right = &buf;
|
||||
}
|
||||
|
||||
Mono_Buffer::~Mono_Buffer() { }
|
||||
|
||||
blargg_err_t Mono_Buffer::set_sample_rate( long rate, int msec )
|
||||
{
|
||||
RETURN_ERR( buf.set_sample_rate( rate, msec ) );
|
||||
return Multi_Buffer::set_sample_rate( buf.sample_rate(), buf.length() );
|
||||
}
|
||||
|
||||
|
||||
// Tracked_Blip_Buffer
|
||||
|
||||
Tracked_Blip_Buffer::Tracked_Blip_Buffer()
|
||||
{
|
||||
last_non_silence = 0;
|
||||
}
|
||||
|
||||
void Tracked_Blip_Buffer::clear()
|
||||
{
|
||||
last_non_silence = 0;
|
||||
Blip_Buffer::clear();
|
||||
}
|
||||
|
||||
void Tracked_Blip_Buffer::end_frame( blip_time_t t )
|
||||
{
|
||||
Blip_Buffer::end_frame( t );
|
||||
if ( clear_modified() )
|
||||
last_non_silence = samples_avail() + blip_buffer_extra_;
|
||||
}
|
||||
|
||||
blip_ulong Tracked_Blip_Buffer::non_silent() const
|
||||
{
|
||||
return last_non_silence | unsettled();
|
||||
}
|
||||
|
||||
inline void Tracked_Blip_Buffer::remove_( long n )
|
||||
{
|
||||
if ( (last_non_silence -= n) < 0 )
|
||||
last_non_silence = 0;
|
||||
}
|
||||
|
||||
void Tracked_Blip_Buffer::remove_silence( long n )
|
||||
{
|
||||
remove_( n );
|
||||
Blip_Buffer::remove_silence( n );
|
||||
}
|
||||
|
||||
void Tracked_Blip_Buffer::remove_samples( long n )
|
||||
{
|
||||
remove_( n );
|
||||
Blip_Buffer::remove_samples( n );
|
||||
}
|
||||
|
||||
void Tracked_Blip_Buffer::remove_all_samples()
|
||||
{
|
||||
long avail = samples_avail();
|
||||
if ( !non_silent() )
|
||||
remove_silence( avail );
|
||||
else
|
||||
remove_samples( avail );
|
||||
}
|
||||
|
||||
long Tracked_Blip_Buffer::read_samples( blip_sample_t* out, long count )
|
||||
{
|
||||
count = Blip_Buffer::read_samples( out, count );
|
||||
remove_( count );
|
||||
return count;
|
||||
}
|
||||
|
||||
// Stereo_Buffer
|
||||
|
||||
int const stereo = 2;
|
||||
|
||||
Stereo_Buffer::Stereo_Buffer() : Multi_Buffer( 2 )
|
||||
{
|
||||
chan.center = mixer.bufs [2] = &bufs [2];
|
||||
chan.left = mixer.bufs [0] = &bufs [0];
|
||||
chan.right = mixer.bufs [1] = &bufs [1];
|
||||
mixer.samples_read = 0;
|
||||
}
|
||||
|
||||
Stereo_Buffer::~Stereo_Buffer() { }
|
||||
|
||||
blargg_err_t Stereo_Buffer::set_sample_rate( long rate, int msec )
|
||||
{
|
||||
mixer.samples_read = 0;
|
||||
for ( int i = bufs_size; --i >= 0; )
|
||||
RETURN_ERR( bufs [i].set_sample_rate( rate, msec ) );
|
||||
return Multi_Buffer::set_sample_rate( bufs [0].sample_rate(), bufs [0].length() );
|
||||
}
|
||||
|
||||
void Stereo_Buffer::clock_rate( long rate )
|
||||
{
|
||||
for ( int i = bufs_size; --i >= 0; )
|
||||
bufs [i].clock_rate( rate );
|
||||
}
|
||||
|
||||
void Stereo_Buffer::bass_freq( int bass )
|
||||
{
|
||||
for ( int i = bufs_size; --i >= 0; )
|
||||
bufs [i].bass_freq( bass );
|
||||
}
|
||||
|
||||
void Stereo_Buffer::clear()
|
||||
{
|
||||
mixer.samples_read = 0;
|
||||
for ( int i = bufs_size; --i >= 0; )
|
||||
bufs [i].clear();
|
||||
}
|
||||
|
||||
void Stereo_Buffer::end_frame( blip_time_t time )
|
||||
{
|
||||
for ( int i = bufs_size; --i >= 0; )
|
||||
bufs [i].end_frame( time );
|
||||
}
|
||||
|
||||
long Stereo_Buffer::read_samples( blip_sample_t* out, long out_size )
|
||||
{
|
||||
require( (out_size & 1) == 0 ); // must read an even number of samples
|
||||
out_size = min( out_size, samples_avail() );
|
||||
|
||||
int pair_count = int (out_size >> 1);
|
||||
if ( pair_count )
|
||||
{
|
||||
mixer.read_pairs( out, pair_count );
|
||||
|
||||
if ( samples_avail() <= 0 || immediate_removal() )
|
||||
{
|
||||
for ( int i = bufs_size; --i >= 0; )
|
||||
{
|
||||
buf_t& b = bufs [i];
|
||||
// TODO: might miss non-silence settling since it checks END of last read
|
||||
if ( !b.non_silent() )
|
||||
b.remove_silence( mixer.samples_read );
|
||||
else
|
||||
b.remove_samples( mixer.samples_read );
|
||||
}
|
||||
mixer.samples_read = 0;
|
||||
}
|
||||
}
|
||||
return out_size;
|
||||
}
|
||||
|
||||
|
||||
// Stereo_Mixer
|
||||
|
||||
// mixers use a single index value to improve performance on register-challenged processors
|
||||
// offset goes from negative to zero
|
||||
|
||||
void Stereo_Mixer::read_pairs( blip_sample_t* out, int count )
|
||||
{
|
||||
// TODO: if caller never marks buffers as modified, uses mono
|
||||
// except that buffer isn't cleared, so caller can encounter
|
||||
// subtle problems and not realize the cause.
|
||||
samples_read += count;
|
||||
if ( bufs [0]->non_silent() | bufs [1]->non_silent() )
|
||||
mix_stereo( out, count );
|
||||
else
|
||||
mix_mono( out, count );
|
||||
}
|
||||
|
||||
void Stereo_Mixer::mix_mono( blip_sample_t* out_, int count )
|
||||
{
|
||||
int const bass = BLIP_READER_BASS( *bufs [2] );
|
||||
BLIP_READER_BEGIN( center, *bufs [2] );
|
||||
BLIP_READER_ADJ_( center, samples_read );
|
||||
|
||||
typedef blip_sample_t stereo_blip_sample_t [stereo];
|
||||
stereo_blip_sample_t* BLIP_RESTRICT out = (stereo_blip_sample_t*) out_ + count;
|
||||
int offset = -count;
|
||||
do
|
||||
{
|
||||
blargg_long s = BLIP_READER_READ( center );
|
||||
BLIP_READER_NEXT_IDX_( center, bass, offset );
|
||||
BLIP_CLAMP( s, s );
|
||||
|
||||
out [offset] [0] = (blip_sample_t) s;
|
||||
out [offset] [1] = (blip_sample_t) s;
|
||||
}
|
||||
while ( ++offset );
|
||||
|
||||
BLIP_READER_END( center, *bufs [2] );
|
||||
}
|
||||
|
||||
void Stereo_Mixer::mix_stereo( blip_sample_t* out_, int count )
|
||||
{
|
||||
blip_sample_t* BLIP_RESTRICT out = out_ + count * stereo;
|
||||
|
||||
// do left + center and right + center separately to reduce register load
|
||||
Tracked_Blip_Buffer* const* buf = &bufs [2];
|
||||
while ( true ) // loop runs twice
|
||||
{
|
||||
--buf;
|
||||
--out;
|
||||
|
||||
int const bass = BLIP_READER_BASS( *bufs [2] );
|
||||
BLIP_READER_BEGIN( side, **buf );
|
||||
BLIP_READER_BEGIN( center, *bufs [2] );
|
||||
|
||||
BLIP_READER_ADJ_( side, samples_read );
|
||||
BLIP_READER_ADJ_( center, samples_read );
|
||||
|
||||
int offset = -count;
|
||||
do
|
||||
{
|
||||
blargg_long s = BLIP_READER_READ_RAW( center ) + BLIP_READER_READ_RAW( side );
|
||||
s >>= blip_sample_bits - 16;
|
||||
BLIP_READER_NEXT_IDX_( side, bass, offset );
|
||||
BLIP_READER_NEXT_IDX_( center, bass, offset );
|
||||
BLIP_CLAMP( s, s );
|
||||
|
||||
++offset; // before write since out is decremented to slightly before end
|
||||
out [offset * stereo] = (blip_sample_t) s;
|
||||
}
|
||||
while ( offset );
|
||||
|
||||
BLIP_READER_END( side, **buf );
|
||||
|
||||
if ( buf != bufs )
|
||||
continue;
|
||||
|
||||
// only end center once
|
||||
BLIP_READER_END( center, *bufs [2] );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,205 +1,205 @@
|
|||
// Multi-channel sound buffer interface, and basic mono and stereo buffers
|
||||
|
||||
// Blip_Buffer 0.4.1
|
||||
#ifndef MULTI_BUFFER_H
|
||||
#define MULTI_BUFFER_H
|
||||
|
||||
#include "blargg_common.h"
|
||||
#include "Blip_Buffer.h"
|
||||
|
||||
// Interface to one or more Blip_Buffers mapped to one or more channels
|
||||
// consisting of left, center, and right buffers.
|
||||
class Multi_Buffer {
|
||||
public:
|
||||
Multi_Buffer( int samples_per_frame );
|
||||
virtual ~Multi_Buffer() { }
|
||||
|
||||
// Sets the number of channels available and optionally their types
|
||||
// (type information used by Effects_Buffer)
|
||||
enum { type_index_mask = 0xFF };
|
||||
enum { wave_type = 0x100, noise_type = 0x200, mixed_type = wave_type | noise_type };
|
||||
virtual blargg_err_t set_channel_count( int, int const* types = 0 );
|
||||
int channel_count() const { return channel_count_; }
|
||||
|
||||
// Gets indexed channel, from 0 to channel count - 1
|
||||
struct channel_t {
|
||||
Blip_Buffer* center;
|
||||
Blip_Buffer* left;
|
||||
Blip_Buffer* right;
|
||||
};
|
||||
virtual channel_t channel( int index ) BLARGG_PURE( ; )
|
||||
|
||||
// See Blip_Buffer.h
|
||||
virtual blargg_err_t set_sample_rate( long rate, int msec = blip_default_length ) BLARGG_PURE( ; )
|
||||
virtual void clock_rate( long ) BLARGG_PURE( { } )
|
||||
virtual void bass_freq( int ) BLARGG_PURE( { } )
|
||||
virtual void clear() BLARGG_PURE( { } )
|
||||
long sample_rate() const;
|
||||
|
||||
// Length of buffer, in milliseconds
|
||||
int length() const;
|
||||
|
||||
// See Blip_Buffer.h
|
||||
virtual void end_frame( blip_time_t ) BLARGG_PURE( { } )
|
||||
|
||||
// Number of samples per output frame (1 = mono, 2 = stereo)
|
||||
int samples_per_frame() const;
|
||||
|
||||
// Count of changes to channel configuration. Incremented whenever
|
||||
// a change is made to any of the Blip_Buffers for any channel.
|
||||
unsigned channels_changed_count() { return channels_changed_count_; }
|
||||
|
||||
// See Blip_Buffer.h
|
||||
virtual long read_samples( blip_sample_t*, long ) BLARGG_PURE( { return 0; } )
|
||||
virtual long samples_avail() const BLARGG_PURE( { return 0; } )
|
||||
|
||||
public:
|
||||
BLARGG_DISABLE_NOTHROW
|
||||
void disable_immediate_removal() { immediate_removal_ = false; }
|
||||
protected:
|
||||
bool immediate_removal() const { return immediate_removal_; }
|
||||
int const* channel_types() const { return channel_types_; }
|
||||
void channels_changed() { channels_changed_count_++; }
|
||||
private:
|
||||
// noncopyable
|
||||
Multi_Buffer( const Multi_Buffer& );
|
||||
Multi_Buffer& operator = ( const Multi_Buffer& );
|
||||
|
||||
unsigned channels_changed_count_;
|
||||
long sample_rate_;
|
||||
int length_;
|
||||
int channel_count_;
|
||||
int const samples_per_frame_;
|
||||
int const* channel_types_;
|
||||
bool immediate_removal_;
|
||||
};
|
||||
|
||||
// Uses a single buffer and outputs mono samples.
|
||||
class Mono_Buffer : public Multi_Buffer {
|
||||
Blip_Buffer buf;
|
||||
channel_t chan;
|
||||
public:
|
||||
// Buffer used for all channels
|
||||
Blip_Buffer* center() { return &buf; }
|
||||
|
||||
public:
|
||||
Mono_Buffer();
|
||||
~Mono_Buffer();
|
||||
blargg_err_t set_sample_rate( long rate, int msec = blip_default_length );
|
||||
void clock_rate( long rate ) { buf.clock_rate( rate ); }
|
||||
void bass_freq( int freq ) { buf.bass_freq( freq ); }
|
||||
void clear() { buf.clear(); }
|
||||
long samples_avail() const { return buf.samples_avail(); }
|
||||
long read_samples( blip_sample_t* p, long s ) { return buf.read_samples( p, s ); }
|
||||
channel_t channel( int ) { return chan; }
|
||||
void end_frame( blip_time_t t ) { buf.end_frame( t ); }
|
||||
};
|
||||
|
||||
class Tracked_Blip_Buffer : public Blip_Buffer {
|
||||
public:
|
||||
// Non-zero if buffer still has non-silent samples in it. Requires that you call
|
||||
// set_modified() appropriately.
|
||||
blip_ulong non_silent() const;
|
||||
|
||||
// remove_samples( samples_avail() )
|
||||
void remove_all_samples();
|
||||
|
||||
public:
|
||||
BLARGG_DISABLE_NOTHROW
|
||||
|
||||
long read_samples( blip_sample_t*, long );
|
||||
void remove_silence( long );
|
||||
void remove_samples( long );
|
||||
Tracked_Blip_Buffer();
|
||||
void clear();
|
||||
void end_frame( blip_time_t );
|
||||
private:
|
||||
blip_long last_non_silence;
|
||||
void remove_( long );
|
||||
};
|
||||
|
||||
class Stereo_Mixer {
|
||||
public:
|
||||
Tracked_Blip_Buffer* bufs [3];
|
||||
blargg_long samples_read;
|
||||
|
||||
Stereo_Mixer() : samples_read( 0 ) { }
|
||||
void read_pairs( blip_sample_t* out, int count );
|
||||
private:
|
||||
void mix_mono ( blip_sample_t* out, int pair_count );
|
||||
void mix_stereo( blip_sample_t* out, int pair_count );
|
||||
};
|
||||
|
||||
// Uses three buffers (one for center) and outputs stereo sample pairs.
|
||||
class Stereo_Buffer : public Multi_Buffer {
|
||||
public:
|
||||
|
||||
// Buffers used for all channels
|
||||
Blip_Buffer* center() { return &bufs [2]; }
|
||||
Blip_Buffer* left() { return &bufs [0]; }
|
||||
Blip_Buffer* right() { return &bufs [1]; }
|
||||
|
||||
public:
|
||||
Stereo_Buffer();
|
||||
~Stereo_Buffer();
|
||||
blargg_err_t set_sample_rate( long, int msec = blip_default_length );
|
||||
void clock_rate( long );
|
||||
void bass_freq( int );
|
||||
void clear();
|
||||
channel_t channel( int ) { return chan; }
|
||||
void end_frame( blip_time_t );
|
||||
|
||||
long samples_avail() const { return (bufs [0].samples_avail() - mixer.samples_read) * 2; }
|
||||
long read_samples( blip_sample_t*, long );
|
||||
|
||||
private:
|
||||
enum { bufs_size = 3 };
|
||||
typedef Tracked_Blip_Buffer buf_t;
|
||||
buf_t bufs [bufs_size];
|
||||
Stereo_Mixer mixer;
|
||||
channel_t chan;
|
||||
long samples_avail_;
|
||||
};
|
||||
|
||||
// Silent_Buffer generates no samples, useful where no sound is wanted
|
||||
class Silent_Buffer : public Multi_Buffer {
|
||||
channel_t chan;
|
||||
public:
|
||||
Silent_Buffer();
|
||||
blargg_err_t set_sample_rate( long rate, int msec = blip_default_length );
|
||||
void clock_rate( long ) { }
|
||||
void bass_freq( int ) { }
|
||||
void clear() { }
|
||||
channel_t channel( int ) { return chan; }
|
||||
void end_frame( blip_time_t ) { }
|
||||
long samples_avail() const { return 0; }
|
||||
long read_samples( blip_sample_t*, long ) { return 0; }
|
||||
};
|
||||
|
||||
|
||||
inline blargg_err_t Multi_Buffer::set_sample_rate( long rate, int msec )
|
||||
{
|
||||
sample_rate_ = rate;
|
||||
length_ = msec;
|
||||
return 0;
|
||||
}
|
||||
|
||||
inline blargg_err_t Silent_Buffer::set_sample_rate( long rate, int msec )
|
||||
{
|
||||
return Multi_Buffer::set_sample_rate( rate, msec );
|
||||
}
|
||||
|
||||
inline int Multi_Buffer::samples_per_frame() const { return samples_per_frame_; }
|
||||
|
||||
inline long Multi_Buffer::sample_rate() const { return sample_rate_; }
|
||||
|
||||
inline int Multi_Buffer::length() const { return length_; }
|
||||
|
||||
inline blargg_err_t Multi_Buffer::set_channel_count( int n, int const* types )
|
||||
{
|
||||
channel_count_ = n;
|
||||
channel_types_ = types;
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
// Multi-channel sound buffer interface, and basic mono and stereo buffers
|
||||
|
||||
// Blip_Buffer 0.4.1
|
||||
#ifndef MULTI_BUFFER_H
|
||||
#define MULTI_BUFFER_H
|
||||
|
||||
#include "blargg_common.h"
|
||||
#include "Blip_Buffer.h"
|
||||
|
||||
// Interface to one or more Blip_Buffers mapped to one or more channels
|
||||
// consisting of left, center, and right buffers.
|
||||
class Multi_Buffer {
|
||||
public:
|
||||
Multi_Buffer( int samples_per_frame );
|
||||
virtual ~Multi_Buffer() { }
|
||||
|
||||
// Sets the number of channels available and optionally their types
|
||||
// (type information used by Effects_Buffer)
|
||||
enum { type_index_mask = 0xFF };
|
||||
enum { wave_type = 0x100, noise_type = 0x200, mixed_type = wave_type | noise_type };
|
||||
virtual blargg_err_t set_channel_count( int, int const* types = 0 );
|
||||
int channel_count() const { return channel_count_; }
|
||||
|
||||
// Gets indexed channel, from 0 to channel count - 1
|
||||
struct channel_t {
|
||||
Blip_Buffer* center;
|
||||
Blip_Buffer* left;
|
||||
Blip_Buffer* right;
|
||||
};
|
||||
virtual channel_t channel( int index ) BLARGG_PURE( ; )
|
||||
|
||||
// See Blip_Buffer.h
|
||||
virtual blargg_err_t set_sample_rate( long rate, int msec = blip_default_length ) BLARGG_PURE( ; )
|
||||
virtual void clock_rate( long ) BLARGG_PURE( { } )
|
||||
virtual void bass_freq( int ) BLARGG_PURE( { } )
|
||||
virtual void clear() BLARGG_PURE( { } )
|
||||
long sample_rate() const;
|
||||
|
||||
// Length of buffer, in milliseconds
|
||||
int length() const;
|
||||
|
||||
// See Blip_Buffer.h
|
||||
virtual void end_frame( blip_time_t ) BLARGG_PURE( { } )
|
||||
|
||||
// Number of samples per output frame (1 = mono, 2 = stereo)
|
||||
int samples_per_frame() const;
|
||||
|
||||
// Count of changes to channel configuration. Incremented whenever
|
||||
// a change is made to any of the Blip_Buffers for any channel.
|
||||
unsigned channels_changed_count() { return channels_changed_count_; }
|
||||
|
||||
// See Blip_Buffer.h
|
||||
virtual long read_samples( blip_sample_t*, long ) BLARGG_PURE( { return 0; } )
|
||||
virtual long samples_avail() const BLARGG_PURE( { return 0; } )
|
||||
|
||||
public:
|
||||
BLARGG_DISABLE_NOTHROW
|
||||
void disable_immediate_removal() { immediate_removal_ = false; }
|
||||
protected:
|
||||
bool immediate_removal() const { return immediate_removal_; }
|
||||
int const* channel_types() const { return channel_types_; }
|
||||
void channels_changed() { channels_changed_count_++; }
|
||||
private:
|
||||
// noncopyable
|
||||
Multi_Buffer( const Multi_Buffer& );
|
||||
Multi_Buffer& operator = ( const Multi_Buffer& );
|
||||
|
||||
unsigned channels_changed_count_;
|
||||
long sample_rate_;
|
||||
int length_;
|
||||
int channel_count_;
|
||||
int const samples_per_frame_;
|
||||
int const* channel_types_;
|
||||
bool immediate_removal_;
|
||||
};
|
||||
|
||||
// Uses a single buffer and outputs mono samples.
|
||||
class Mono_Buffer : public Multi_Buffer {
|
||||
Blip_Buffer buf;
|
||||
channel_t chan;
|
||||
public:
|
||||
// Buffer used for all channels
|
||||
Blip_Buffer* center() { return &buf; }
|
||||
|
||||
public:
|
||||
Mono_Buffer();
|
||||
~Mono_Buffer();
|
||||
blargg_err_t set_sample_rate( long rate, int msec = blip_default_length );
|
||||
void clock_rate( long rate ) { buf.clock_rate( rate ); }
|
||||
void bass_freq( int freq ) { buf.bass_freq( freq ); }
|
||||
void clear() { buf.clear(); }
|
||||
long samples_avail() const { return buf.samples_avail(); }
|
||||
long read_samples( blip_sample_t* p, long s ) { return buf.read_samples( p, s ); }
|
||||
channel_t channel( int ) { return chan; }
|
||||
void end_frame( blip_time_t t ) { buf.end_frame( t ); }
|
||||
};
|
||||
|
||||
class Tracked_Blip_Buffer : public Blip_Buffer {
|
||||
public:
|
||||
// Non-zero if buffer still has non-silent samples in it. Requires that you call
|
||||
// set_modified() appropriately.
|
||||
blip_ulong non_silent() const;
|
||||
|
||||
// remove_samples( samples_avail() )
|
||||
void remove_all_samples();
|
||||
|
||||
public:
|
||||
BLARGG_DISABLE_NOTHROW
|
||||
|
||||
long read_samples( blip_sample_t*, long );
|
||||
void remove_silence( long );
|
||||
void remove_samples( long );
|
||||
Tracked_Blip_Buffer();
|
||||
void clear();
|
||||
void end_frame( blip_time_t );
|
||||
private:
|
||||
blip_long last_non_silence;
|
||||
void remove_( long );
|
||||
};
|
||||
|
||||
class Stereo_Mixer {
|
||||
public:
|
||||
Tracked_Blip_Buffer* bufs [3];
|
||||
blargg_long samples_read;
|
||||
|
||||
Stereo_Mixer() : samples_read( 0 ) { }
|
||||
void read_pairs( blip_sample_t* out, int count );
|
||||
private:
|
||||
void mix_mono ( blip_sample_t* out, int pair_count );
|
||||
void mix_stereo( blip_sample_t* out, int pair_count );
|
||||
};
|
||||
|
||||
// Uses three buffers (one for center) and outputs stereo sample pairs.
|
||||
class Stereo_Buffer : public Multi_Buffer {
|
||||
public:
|
||||
|
||||
// Buffers used for all channels
|
||||
Blip_Buffer* center() { return &bufs [2]; }
|
||||
Blip_Buffer* left() { return &bufs [0]; }
|
||||
Blip_Buffer* right() { return &bufs [1]; }
|
||||
|
||||
public:
|
||||
Stereo_Buffer();
|
||||
~Stereo_Buffer();
|
||||
blargg_err_t set_sample_rate( long, int msec = blip_default_length );
|
||||
void clock_rate( long );
|
||||
void bass_freq( int );
|
||||
void clear();
|
||||
channel_t channel( int ) { return chan; }
|
||||
void end_frame( blip_time_t );
|
||||
|
||||
long samples_avail() const { return (bufs [0].samples_avail() - mixer.samples_read) * 2; }
|
||||
long read_samples( blip_sample_t*, long );
|
||||
|
||||
private:
|
||||
enum { bufs_size = 3 };
|
||||
typedef Tracked_Blip_Buffer buf_t;
|
||||
buf_t bufs [bufs_size];
|
||||
Stereo_Mixer mixer;
|
||||
channel_t chan;
|
||||
long samples_avail_;
|
||||
};
|
||||
|
||||
// Silent_Buffer generates no samples, useful where no sound is wanted
|
||||
class Silent_Buffer : public Multi_Buffer {
|
||||
channel_t chan;
|
||||
public:
|
||||
Silent_Buffer();
|
||||
blargg_err_t set_sample_rate( long rate, int msec = blip_default_length );
|
||||
void clock_rate( long ) { }
|
||||
void bass_freq( int ) { }
|
||||
void clear() { }
|
||||
channel_t channel( int ) { return chan; }
|
||||
void end_frame( blip_time_t ) { }
|
||||
long samples_avail() const { return 0; }
|
||||
long read_samples( blip_sample_t*, long ) { return 0; }
|
||||
};
|
||||
|
||||
|
||||
inline blargg_err_t Multi_Buffer::set_sample_rate( long rate, int msec )
|
||||
{
|
||||
sample_rate_ = rate;
|
||||
length_ = msec;
|
||||
return 0;
|
||||
}
|
||||
|
||||
inline blargg_err_t Silent_Buffer::set_sample_rate( long rate, int msec )
|
||||
{
|
||||
return Multi_Buffer::set_sample_rate( rate, msec );
|
||||
}
|
||||
|
||||
inline int Multi_Buffer::samples_per_frame() const { return samples_per_frame_; }
|
||||
|
||||
inline long Multi_Buffer::sample_rate() const { return sample_rate_; }
|
||||
|
||||
inline int Multi_Buffer::length() const { return length_; }
|
||||
|
||||
inline blargg_err_t Multi_Buffer::set_channel_count( int n, int const* types )
|
||||
{
|
||||
channel_count_ = n;
|
||||
channel_types_ = types;
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,206 +1,206 @@
|
|||
// Sets up common environment for Shay Green's libraries.
|
||||
// To change configuration options, modify blargg_config.h, not this file.
|
||||
|
||||
// Gb_Snd_Emu 0.2.0
|
||||
#ifndef BLARGG_COMMON_H
|
||||
#define BLARGG_COMMON_H
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
#include <limits.h>
|
||||
|
||||
#undef BLARGG_COMMON_H
|
||||
// allow blargg_config.h to #include blargg_common.h
|
||||
#include "blargg_config.h"
|
||||
#ifndef BLARGG_COMMON_H
|
||||
#define BLARGG_COMMON_H
|
||||
|
||||
// BLARGG_RESTRICT: equivalent to restrict, where supported
|
||||
#if __GNUC__ >= 3 || _MSC_VER >= 1100
|
||||
#define BLARGG_RESTRICT __restrict
|
||||
#else
|
||||
#define BLARGG_RESTRICT
|
||||
#endif
|
||||
|
||||
// STATIC_CAST(T,expr): Used in place of static_cast<T> (expr)
|
||||
// CONST_CAST( T,expr): Used in place of const_cast<T> (expr)
|
||||
#ifndef STATIC_CAST
|
||||
#if __GNUC__ >= 4
|
||||
#define STATIC_CAST(T,expr) static_cast<T> (expr)
|
||||
#define CONST_CAST( T,expr) const_cast<T> (expr)
|
||||
#else
|
||||
#define STATIC_CAST(T,expr) ((T) (expr))
|
||||
#define CONST_CAST( T,expr) ((T) (expr))
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// blargg_err_t (0 on success, otherwise error string)
|
||||
#ifndef blargg_err_t
|
||||
typedef const char* blargg_err_t;
|
||||
#endif
|
||||
|
||||
// blargg_vector - very lightweight vector of POD types (no constructor/destructor)
|
||||
template<class T>
|
||||
class blargg_vector {
|
||||
T* begin_;
|
||||
size_t size_;
|
||||
public:
|
||||
blargg_vector() : begin_( 0 ), size_( 0 ) { }
|
||||
~blargg_vector() { free( begin_ ); }
|
||||
size_t size() const { return size_; }
|
||||
T* begin() const { return begin_; }
|
||||
T* end() const { return begin_ + size_; }
|
||||
blargg_err_t resize( size_t n )
|
||||
{
|
||||
// TODO: blargg_common.cpp to hold this as an outline function, ugh
|
||||
void* p = realloc( begin_, n * sizeof (T) );
|
||||
if ( p )
|
||||
begin_ = (T*) p;
|
||||
else if ( n > size_ ) // realloc failure only a problem if expanding
|
||||
return "Out of memory";
|
||||
size_ = n;
|
||||
return 0;
|
||||
}
|
||||
void clear() { void* p = begin_; begin_ = 0; size_ = 0; free( p ); }
|
||||
T& operator [] ( size_t n ) const
|
||||
{
|
||||
assert( n <= size_ ); // <= to allow past-the-end value
|
||||
return begin_ [n];
|
||||
}
|
||||
};
|
||||
|
||||
#ifndef BLARGG_DISABLE_NOTHROW
|
||||
// throw spec mandatory in ISO C++ if operator new can return NULL
|
||||
#if __cplusplus >= 199711 || __GNUC__ >= 3
|
||||
#define BLARGG_THROWS( spec ) throw spec
|
||||
#else
|
||||
#define BLARGG_THROWS( spec )
|
||||
#endif
|
||||
#define BLARGG_DISABLE_NOTHROW \
|
||||
void* operator new ( size_t s ) BLARGG_THROWS(()) { return malloc( s ); }\
|
||||
void operator delete ( void* p ) { free( p ); }
|
||||
#define BLARGG_NEW new
|
||||
#else
|
||||
#include <new>
|
||||
#define BLARGG_NEW new (std::nothrow)
|
||||
#endif
|
||||
|
||||
// BLARGG_4CHAR('a','b','c','d') = 'abcd' (four character integer constant)
|
||||
#define BLARGG_4CHAR( a, b, c, d ) \
|
||||
((a&0xFF)*0x1000000 + (b&0xFF)*0x10000 + (c&0xFF)*0x100 + (d&0xFF))
|
||||
|
||||
// BOOST_STATIC_ASSERT( expr ): Generates compile error if expr is 0.
|
||||
#ifndef BOOST_STATIC_ASSERT
|
||||
#ifdef _MSC_VER
|
||||
// MSVC6 (_MSC_VER < 1300) fails for use of __LINE__ when /Zl is specified
|
||||
#define BOOST_STATIC_ASSERT( expr ) \
|
||||
void blargg_failed_( int (*arg) [2 / (int) !!(expr) - 1] )
|
||||
#else
|
||||
// Some other compilers fail when declaring same function multiple times in class,
|
||||
// so differentiate them by line
|
||||
#define BOOST_STATIC_ASSERT( expr ) \
|
||||
void blargg_failed_( int (*arg) [2 / !!(expr) - 1] [__LINE__] )
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// BLARGG_COMPILER_HAS_BOOL: If 0, provides bool support for old compiler. If 1,
|
||||
// compiler is assumed to support bool. If undefined, availability is determined.
|
||||
#ifndef BLARGG_COMPILER_HAS_BOOL
|
||||
#if defined (__MWERKS__)
|
||||
#if !__option(bool)
|
||||
#define BLARGG_COMPILER_HAS_BOOL 0
|
||||
#endif
|
||||
#elif defined (_MSC_VER)
|
||||
#if _MSC_VER < 1100
|
||||
#define BLARGG_COMPILER_HAS_BOOL 0
|
||||
#endif
|
||||
#elif defined (__GNUC__)
|
||||
// supports bool
|
||||
#elif __cplusplus < 199711
|
||||
#define BLARGG_COMPILER_HAS_BOOL 0
|
||||
#endif
|
||||
#endif
|
||||
#if defined (BLARGG_COMPILER_HAS_BOOL) && !BLARGG_COMPILER_HAS_BOOL
|
||||
// If you get errors here, modify your blargg_config.h file
|
||||
typedef int bool;
|
||||
const bool true = 1;
|
||||
const bool false = 0;
|
||||
#endif
|
||||
|
||||
// blargg_long/blargg_ulong = at least 32 bits, int if it's big enough
|
||||
|
||||
#if INT_MAX < 0x7FFFFFFF || LONG_MAX == 0x7FFFFFFF
|
||||
typedef long blargg_long;
|
||||
#else
|
||||
typedef int blargg_long;
|
||||
#endif
|
||||
|
||||
#if UINT_MAX < 0xFFFFFFFF || ULONG_MAX == 0xFFFFFFFF
|
||||
typedef unsigned long blargg_ulong;
|
||||
#else
|
||||
typedef unsigned blargg_ulong;
|
||||
#endif
|
||||
|
||||
// BOOST::int8_t etc.
|
||||
|
||||
// HAVE_STDINT_H: If defined, use <stdint.h> for int8_t etc.
|
||||
#if defined (HAVE_STDINT_H)
|
||||
#include <stdint.h>
|
||||
#define BOOST
|
||||
|
||||
// HAVE_INTTYPES_H: If defined, use <stdint.h> for int8_t etc.
|
||||
#elif defined (HAVE_INTTYPES_H)
|
||||
#include <inttypes.h>
|
||||
#define BOOST
|
||||
|
||||
#else
|
||||
struct BOOST
|
||||
{
|
||||
#if UCHAR_MAX == 0xFF && SCHAR_MAX == 0x7F
|
||||
typedef signed char int8_t;
|
||||
typedef unsigned char uint8_t;
|
||||
#else
|
||||
// No suitable 8-bit type available
|
||||
typedef struct see_blargg_common_h int8_t;
|
||||
typedef struct see_blargg_common_h uint8_t;
|
||||
#endif
|
||||
|
||||
#if USHRT_MAX == 0xFFFF
|
||||
typedef short int16_t;
|
||||
typedef unsigned short uint16_t;
|
||||
#else
|
||||
// No suitable 16-bit type available
|
||||
typedef struct see_blargg_common_h int16_t;
|
||||
typedef struct see_blargg_common_h uint16_t;
|
||||
#endif
|
||||
|
||||
#if ULONG_MAX == 0xFFFFFFFF
|
||||
typedef long int32_t;
|
||||
typedef unsigned long uint32_t;
|
||||
#elif UINT_MAX == 0xFFFFFFFF
|
||||
typedef int int32_t;
|
||||
typedef unsigned int uint32_t;
|
||||
#else
|
||||
// No suitable 32-bit type available
|
||||
typedef struct see_blargg_common_h int32_t;
|
||||
typedef struct see_blargg_common_h uint32_t;
|
||||
#endif
|
||||
};
|
||||
#endif
|
||||
|
||||
#if __GNUC__ >= 3
|
||||
#define BLARGG_DEPRECATED __attribute__ ((deprecated))
|
||||
#else
|
||||
#define BLARGG_DEPRECATED
|
||||
#endif
|
||||
|
||||
// Use in place of "= 0;" for a pure virtual, since these cause calls to std C++ lib.
|
||||
// During development, BLARGG_PURE( x ) expands to = 0;
|
||||
// virtual int func() BLARGG_PURE( { return 0; } )
|
||||
#ifndef BLARGG_PURE
|
||||
#define BLARGG_PURE( def ) def
|
||||
#endif
|
||||
|
||||
#endif
|
||||
#endif
|
||||
// Sets up common environment for Shay Green's libraries.
|
||||
// To change configuration options, modify blargg_config.h, not this file.
|
||||
|
||||
// Gb_Snd_Emu 0.2.0
|
||||
#ifndef BLARGG_COMMON_H
|
||||
#define BLARGG_COMMON_H
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
#include <limits.h>
|
||||
|
||||
#undef BLARGG_COMMON_H
|
||||
// allow blargg_config.h to #include blargg_common.h
|
||||
#include "blargg_config.h"
|
||||
#ifndef BLARGG_COMMON_H
|
||||
#define BLARGG_COMMON_H
|
||||
|
||||
// BLARGG_RESTRICT: equivalent to restrict, where supported
|
||||
#if __GNUC__ >= 3 || _MSC_VER >= 1100
|
||||
#define BLARGG_RESTRICT __restrict
|
||||
#else
|
||||
#define BLARGG_RESTRICT
|
||||
#endif
|
||||
|
||||
// STATIC_CAST(T,expr): Used in place of static_cast<T> (expr)
|
||||
// CONST_CAST( T,expr): Used in place of const_cast<T> (expr)
|
||||
#ifndef STATIC_CAST
|
||||
#if __GNUC__ >= 4
|
||||
#define STATIC_CAST(T,expr) static_cast<T> (expr)
|
||||
#define CONST_CAST( T,expr) const_cast<T> (expr)
|
||||
#else
|
||||
#define STATIC_CAST(T,expr) ((T) (expr))
|
||||
#define CONST_CAST( T,expr) ((T) (expr))
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// blargg_err_t (0 on success, otherwise error string)
|
||||
#ifndef blargg_err_t
|
||||
typedef const char* blargg_err_t;
|
||||
#endif
|
||||
|
||||
// blargg_vector - very lightweight vector of POD types (no constructor/destructor)
|
||||
template<class T>
|
||||
class blargg_vector {
|
||||
T* begin_;
|
||||
size_t size_;
|
||||
public:
|
||||
blargg_vector() : begin_( 0 ), size_( 0 ) { }
|
||||
~blargg_vector() { free( begin_ ); }
|
||||
size_t size() const { return size_; }
|
||||
T* begin() const { return begin_; }
|
||||
T* end() const { return begin_ + size_; }
|
||||
blargg_err_t resize( size_t n )
|
||||
{
|
||||
// TODO: blargg_common.cpp to hold this as an outline function, ugh
|
||||
void* p = realloc( begin_, n * sizeof (T) );
|
||||
if ( p )
|
||||
begin_ = (T*) p;
|
||||
else if ( n > size_ ) // realloc failure only a problem if expanding
|
||||
return "Out of memory";
|
||||
size_ = n;
|
||||
return 0;
|
||||
}
|
||||
void clear() { void* p = begin_; begin_ = 0; size_ = 0; free( p ); }
|
||||
T& operator [] ( size_t n ) const
|
||||
{
|
||||
assert( n <= size_ ); // <= to allow past-the-end value
|
||||
return begin_ [n];
|
||||
}
|
||||
};
|
||||
|
||||
#ifndef BLARGG_DISABLE_NOTHROW
|
||||
// throw spec mandatory in ISO C++ if operator new can return NULL
|
||||
#if __cplusplus >= 199711 || __GNUC__ >= 3
|
||||
#define BLARGG_THROWS( spec ) throw spec
|
||||
#else
|
||||
#define BLARGG_THROWS( spec )
|
||||
#endif
|
||||
#define BLARGG_DISABLE_NOTHROW \
|
||||
void* operator new ( size_t s ) BLARGG_THROWS(()) { return malloc( s ); }\
|
||||
void operator delete ( void* p ) { free( p ); }
|
||||
#define BLARGG_NEW new
|
||||
#else
|
||||
#include <new>
|
||||
#define BLARGG_NEW new (std::nothrow)
|
||||
#endif
|
||||
|
||||
// BLARGG_4CHAR('a','b','c','d') = 'abcd' (four character integer constant)
|
||||
#define BLARGG_4CHAR( a, b, c, d ) \
|
||||
((a&0xFF)*0x1000000 + (b&0xFF)*0x10000 + (c&0xFF)*0x100 + (d&0xFF))
|
||||
|
||||
// BOOST_STATIC_ASSERT( expr ): Generates compile error if expr is 0.
|
||||
#ifndef BOOST_STATIC_ASSERT
|
||||
#ifdef _MSC_VER
|
||||
// MSVC6 (_MSC_VER < 1300) fails for use of __LINE__ when /Zl is specified
|
||||
#define BOOST_STATIC_ASSERT( expr ) \
|
||||
void blargg_failed_( int (*arg) [2 / (int) !!(expr) - 1] )
|
||||
#else
|
||||
// Some other compilers fail when declaring same function multiple times in class,
|
||||
// so differentiate them by line
|
||||
#define BOOST_STATIC_ASSERT( expr ) \
|
||||
void blargg_failed_( int (*arg) [2 / !!(expr) - 1] [__LINE__] )
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// BLARGG_COMPILER_HAS_BOOL: If 0, provides bool support for old compiler. If 1,
|
||||
// compiler is assumed to support bool. If undefined, availability is determined.
|
||||
#ifndef BLARGG_COMPILER_HAS_BOOL
|
||||
#if defined (__MWERKS__)
|
||||
#if !__option(bool)
|
||||
#define BLARGG_COMPILER_HAS_BOOL 0
|
||||
#endif
|
||||
#elif defined (_MSC_VER)
|
||||
#if _MSC_VER < 1100
|
||||
#define BLARGG_COMPILER_HAS_BOOL 0
|
||||
#endif
|
||||
#elif defined (__GNUC__)
|
||||
// supports bool
|
||||
#elif __cplusplus < 199711
|
||||
#define BLARGG_COMPILER_HAS_BOOL 0
|
||||
#endif
|
||||
#endif
|
||||
#if defined (BLARGG_COMPILER_HAS_BOOL) && !BLARGG_COMPILER_HAS_BOOL
|
||||
// If you get errors here, modify your blargg_config.h file
|
||||
typedef int bool;
|
||||
const bool true = 1;
|
||||
const bool false = 0;
|
||||
#endif
|
||||
|
||||
// blargg_long/blargg_ulong = at least 32 bits, int if it's big enough
|
||||
|
||||
#if INT_MAX < 0x7FFFFFFF || LONG_MAX == 0x7FFFFFFF
|
||||
typedef long blargg_long;
|
||||
#else
|
||||
typedef int blargg_long;
|
||||
#endif
|
||||
|
||||
#if UINT_MAX < 0xFFFFFFFF || ULONG_MAX == 0xFFFFFFFF
|
||||
typedef unsigned long blargg_ulong;
|
||||
#else
|
||||
typedef unsigned blargg_ulong;
|
||||
#endif
|
||||
|
||||
// BOOST::int8_t etc.
|
||||
|
||||
// HAVE_STDINT_H: If defined, use <stdint.h> for int8_t etc.
|
||||
#if defined (HAVE_STDINT_H)
|
||||
#include <stdint.h>
|
||||
#define BOOST
|
||||
|
||||
// HAVE_INTTYPES_H: If defined, use <stdint.h> for int8_t etc.
|
||||
#elif defined (HAVE_INTTYPES_H)
|
||||
#include <inttypes.h>
|
||||
#define BOOST
|
||||
|
||||
#else
|
||||
struct BOOST
|
||||
{
|
||||
#if UCHAR_MAX == 0xFF && SCHAR_MAX == 0x7F
|
||||
typedef signed char int8_t;
|
||||
typedef unsigned char uint8_t;
|
||||
#else
|
||||
// No suitable 8-bit type available
|
||||
typedef struct see_blargg_common_h int8_t;
|
||||
typedef struct see_blargg_common_h uint8_t;
|
||||
#endif
|
||||
|
||||
#if USHRT_MAX == 0xFFFF
|
||||
typedef short int16_t;
|
||||
typedef unsigned short uint16_t;
|
||||
#else
|
||||
// No suitable 16-bit type available
|
||||
typedef struct see_blargg_common_h int16_t;
|
||||
typedef struct see_blargg_common_h uint16_t;
|
||||
#endif
|
||||
|
||||
#if ULONG_MAX == 0xFFFFFFFF
|
||||
typedef long int32_t;
|
||||
typedef unsigned long uint32_t;
|
||||
#elif UINT_MAX == 0xFFFFFFFF
|
||||
typedef int int32_t;
|
||||
typedef unsigned int uint32_t;
|
||||
#else
|
||||
// No suitable 32-bit type available
|
||||
typedef struct see_blargg_common_h int32_t;
|
||||
typedef struct see_blargg_common_h uint32_t;
|
||||
#endif
|
||||
};
|
||||
#endif
|
||||
|
||||
#if __GNUC__ >= 3
|
||||
#define BLARGG_DEPRECATED __attribute__ ((deprecated))
|
||||
#else
|
||||
#define BLARGG_DEPRECATED
|
||||
#endif
|
||||
|
||||
// Use in place of "= 0;" for a pure virtual, since these cause calls to std C++ lib.
|
||||
// During development, BLARGG_PURE( x ) expands to = 0;
|
||||
// virtual int func() BLARGG_PURE( { return 0; } )
|
||||
#ifndef BLARGG_PURE
|
||||
#define BLARGG_PURE( def ) def
|
||||
#endif
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
|
|
@ -1,33 +1,33 @@
|
|||
// $package user configuration file. Don't replace when updating library.
|
||||
|
||||
#ifndef BLARGG_CONFIG_H
|
||||
#define BLARGG_CONFIG_H
|
||||
|
||||
// Uncomment to have Gb_Apu run at 4x normal clock rate (16777216 Hz), useful in
|
||||
// a Game Boy Advance emulator.
|
||||
#define GB_APU_OVERCLOCK 4
|
||||
|
||||
#define GB_APU_CUSTOM_STATE 1
|
||||
|
||||
// Uncomment to enable platform-specific (and possibly non-portable) optimizations.
|
||||
//#define BLARGG_NONPORTABLE 1
|
||||
|
||||
// Uncomment if automatic byte-order determination doesn't work
|
||||
//#define BLARGG_BIG_ENDIAN 1
|
||||
|
||||
// Uncomment to use zlib for transparent decompression of gzipped files
|
||||
//#define HAVE_ZLIB_H
|
||||
|
||||
// Uncomment if you get errors in the bool section of blargg_common.h
|
||||
//#define BLARGG_COMPILER_HAS_BOOL 1
|
||||
|
||||
// Uncomment to disable out-of-memory exceptions
|
||||
//#include <memory>
|
||||
//#define BLARGG_NEW new (std::nothrow)
|
||||
|
||||
// Use standard config.h if present
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#endif
|
||||
// $package user configuration file. Don't replace when updating library.
|
||||
|
||||
#ifndef BLARGG_CONFIG_H
|
||||
#define BLARGG_CONFIG_H
|
||||
|
||||
// Uncomment to have Gb_Apu run at 4x normal clock rate (16777216 Hz), useful in
|
||||
// a Game Boy Advance emulator.
|
||||
#define GB_APU_OVERCLOCK 4
|
||||
|
||||
#define GB_APU_CUSTOM_STATE 1
|
||||
|
||||
// Uncomment to enable platform-specific (and possibly non-portable) optimizations.
|
||||
//#define BLARGG_NONPORTABLE 1
|
||||
|
||||
// Uncomment if automatic byte-order determination doesn't work
|
||||
//#define BLARGG_BIG_ENDIAN 1
|
||||
|
||||
// Uncomment to use zlib for transparent decompression of gzipped files
|
||||
//#define HAVE_ZLIB_H
|
||||
|
||||
// Uncomment if you get errors in the bool section of blargg_common.h
|
||||
//#define BLARGG_COMPILER_HAS_BOOL 1
|
||||
|
||||
// Uncomment to disable out-of-memory exceptions
|
||||
//#include <memory>
|
||||
//#define BLARGG_NEW new (std::nothrow)
|
||||
|
||||
// Use standard config.h if present
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,92 +1,92 @@
|
|||
/* Included at the beginning of library source files, AFTER all other #include lines.
|
||||
Sets up helpful macros and services used in my source code. Since this is only "active"
|
||||
in my source code, I don't have to worry about polluting the global namespace with
|
||||
unprefixed names. */
|
||||
|
||||
// Gb_Snd_Emu 0.2.0
|
||||
#ifndef BLARGG_SOURCE_H
|
||||
#define BLARGG_SOURCE_H
|
||||
|
||||
// The following four macros are for debugging only. Some or all might be defined
|
||||
// to do nothing, depending on the circumstances. Described is what happens when
|
||||
// a particular macro is defined to do something. When defined to do nothing, the
|
||||
// macros do NOT evaluate their argument(s).
|
||||
|
||||
// If expr is false, prints file and line number, then aborts program. Meant for
|
||||
// checking internal state and consistency. A failed assertion indicates a bug
|
||||
// in MY code.
|
||||
//
|
||||
// void assert( bool expr );
|
||||
#include <assert.h>
|
||||
|
||||
// If expr is false, prints file and line number, then aborts program. Meant for
|
||||
// checking caller-supplied parameters and operations that are outside the control
|
||||
// of the module. A failed requirement probably indicates a bug in YOUR code.
|
||||
//
|
||||
// void require( bool expr );
|
||||
#undef require
|
||||
#define require( expr ) assert( expr )
|
||||
|
||||
// Like printf() except output goes to debugging console/file.
|
||||
//
|
||||
// void dprintf( const char* format, ... );
|
||||
static inline void blargg_dprintf_( const char*, ... ) { }
|
||||
#undef dprintf
|
||||
#define dprintf (1) ? (void) 0 : blargg_dprintf_
|
||||
|
||||
// If expr is false, prints file and line number to debug console/log, then
|
||||
// continues execution normally. Meant for flagging potential problems or things
|
||||
// that should be looked into, but that aren't serious problems.
|
||||
//
|
||||
// void check( bool expr );
|
||||
#undef check
|
||||
#define check( expr ) ((void) 0)
|
||||
|
||||
// If expr yields non-NULL error string, returns it from current function,
|
||||
// otherwise continues normally.
|
||||
#undef RETURN_ERR
|
||||
#define RETURN_ERR( expr ) do { \
|
||||
blargg_err_t blargg_return_err_ = (expr); \
|
||||
if ( blargg_return_err_ ) return blargg_return_err_; \
|
||||
} while ( 0 )
|
||||
|
||||
// If ptr is NULL, returns "Out of memory" error string, otherwise continues normally.
|
||||
#undef CHECK_ALLOC
|
||||
#define CHECK_ALLOC( ptr ) do { if ( (ptr) == 0 ) return "Out of memory"; } while ( 0 )
|
||||
|
||||
// The usual min/max functions for built-in types.
|
||||
//
|
||||
// template<typename T> T min( T x, T y ) { return x < y ? x : y; }
|
||||
// template<typename T> T max( T x, T y ) { return x > y ? x : y; }
|
||||
#define BLARGG_DEF_MIN_MAX( type ) \
|
||||
static inline type blargg_min( type x, type y ) { if ( y < x ) x = y; return x; }\
|
||||
static inline type blargg_max( type x, type y ) { if ( x < y ) x = y; return x; }
|
||||
|
||||
BLARGG_DEF_MIN_MAX( int )
|
||||
BLARGG_DEF_MIN_MAX( unsigned )
|
||||
BLARGG_DEF_MIN_MAX( long )
|
||||
BLARGG_DEF_MIN_MAX( unsigned long )
|
||||
BLARGG_DEF_MIN_MAX( float )
|
||||
BLARGG_DEF_MIN_MAX( double )
|
||||
|
||||
#undef min
|
||||
#define min blargg_min
|
||||
|
||||
#undef max
|
||||
#define max blargg_max
|
||||
|
||||
// typedef unsigned char byte;
|
||||
typedef unsigned char blargg_byte;
|
||||
#undef byte
|
||||
#define byte blargg_byte
|
||||
|
||||
// deprecated
|
||||
#define BLARGG_CHECK_ALLOC CHECK_ALLOC
|
||||
#define BLARGG_RETURN_ERR RETURN_ERR
|
||||
|
||||
// BLARGG_SOURCE_BEGIN: If defined, #included, allowing redefition of dprintf and check
|
||||
#ifdef BLARGG_SOURCE_BEGIN
|
||||
#include BLARGG_SOURCE_BEGIN
|
||||
#endif
|
||||
|
||||
#endif
|
||||
/* Included at the beginning of library source files, AFTER all other #include lines.
|
||||
Sets up helpful macros and services used in my source code. Since this is only "active"
|
||||
in my source code, I don't have to worry about polluting the global namespace with
|
||||
unprefixed names. */
|
||||
|
||||
// Gb_Snd_Emu 0.2.0
|
||||
#ifndef BLARGG_SOURCE_H
|
||||
#define BLARGG_SOURCE_H
|
||||
|
||||
// The following four macros are for debugging only. Some or all might be defined
|
||||
// to do nothing, depending on the circumstances. Described is what happens when
|
||||
// a particular macro is defined to do something. When defined to do nothing, the
|
||||
// macros do NOT evaluate their argument(s).
|
||||
|
||||
// If expr is false, prints file and line number, then aborts program. Meant for
|
||||
// checking internal state and consistency. A failed assertion indicates a bug
|
||||
// in MY code.
|
||||
//
|
||||
// void assert( bool expr );
|
||||
#include <assert.h>
|
||||
|
||||
// If expr is false, prints file and line number, then aborts program. Meant for
|
||||
// checking caller-supplied parameters and operations that are outside the control
|
||||
// of the module. A failed requirement probably indicates a bug in YOUR code.
|
||||
//
|
||||
// void require( bool expr );
|
||||
#undef require
|
||||
#define require( expr ) assert( expr )
|
||||
|
||||
// Like printf() except output goes to debugging console/file.
|
||||
//
|
||||
// void dprintf( const char* format, ... );
|
||||
static inline void blargg_dprintf_( const char*, ... ) { }
|
||||
#undef dprintf
|
||||
#define dprintf (1) ? (void) 0 : blargg_dprintf_
|
||||
|
||||
// If expr is false, prints file and line number to debug console/log, then
|
||||
// continues execution normally. Meant for flagging potential problems or things
|
||||
// that should be looked into, but that aren't serious problems.
|
||||
//
|
||||
// void check( bool expr );
|
||||
#undef check
|
||||
#define check( expr ) ((void) 0)
|
||||
|
||||
// If expr yields non-NULL error string, returns it from current function,
|
||||
// otherwise continues normally.
|
||||
#undef RETURN_ERR
|
||||
#define RETURN_ERR( expr ) do { \
|
||||
blargg_err_t blargg_return_err_ = (expr); \
|
||||
if ( blargg_return_err_ ) return blargg_return_err_; \
|
||||
} while ( 0 )
|
||||
|
||||
// If ptr is NULL, returns "Out of memory" error string, otherwise continues normally.
|
||||
#undef CHECK_ALLOC
|
||||
#define CHECK_ALLOC( ptr ) do { if ( (ptr) == 0 ) return "Out of memory"; } while ( 0 )
|
||||
|
||||
// The usual min/max functions for built-in types.
|
||||
//
|
||||
// template<typename T> T min( T x, T y ) { return x < y ? x : y; }
|
||||
// template<typename T> T max( T x, T y ) { return x > y ? x : y; }
|
||||
#define BLARGG_DEF_MIN_MAX( type ) \
|
||||
static inline type blargg_min( type x, type y ) { if ( y < x ) x = y; return x; }\
|
||||
static inline type blargg_max( type x, type y ) { if ( x < y ) x = y; return x; }
|
||||
|
||||
BLARGG_DEF_MIN_MAX( int )
|
||||
BLARGG_DEF_MIN_MAX( unsigned )
|
||||
BLARGG_DEF_MIN_MAX( long )
|
||||
BLARGG_DEF_MIN_MAX( unsigned long )
|
||||
BLARGG_DEF_MIN_MAX( float )
|
||||
BLARGG_DEF_MIN_MAX( double )
|
||||
|
||||
#undef min
|
||||
#define min blargg_min
|
||||
|
||||
#undef max
|
||||
#define max blargg_max
|
||||
|
||||
// typedef unsigned char byte;
|
||||
typedef unsigned char blargg_byte;
|
||||
#undef byte
|
||||
#define byte blargg_byte
|
||||
|
||||
// deprecated
|
||||
#define BLARGG_CHECK_ALLOC CHECK_ALLOC
|
||||
#define BLARGG_RETURN_ERR RETURN_ERR
|
||||
|
||||
// BLARGG_SOURCE_BEGIN: If defined, #included, allowing redefition of dprintf and check
|
||||
#ifdef BLARGG_SOURCE_BEGIN
|
||||
#include BLARGG_SOURCE_BEGIN
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
352
src/qt/emu.cpp
352
src/qt/emu.cpp
|
@ -1,176 +1,176 @@
|
|||
// VBA-M, A Nintendo Handheld Console Emulator
|
||||
// Copyright (C) 2008 VBA-M development team
|
||||
//
|
||||
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
// This file adds all the code required by System.h
|
||||
|
||||
|
||||
#include "emu.h"
|
||||
|
||||
|
||||
int emulating = 0;
|
||||
int systemFrameSkip = 0;
|
||||
int systemSaveUpdateCounter = SYSTEM_SAVE_NOT_UPDATED;
|
||||
bool systemSoundOn = false;
|
||||
u32 systemColorMap32[0x10000];
|
||||
u16 systemColorMap16[0x10000];
|
||||
int systemRedShift = 0;
|
||||
int systemBlueShift = 0;
|
||||
int systemGreenShift = 0;
|
||||
int systemColorDepth = 32;
|
||||
int systemDebug = 0;
|
||||
int systemVerbose = 0;
|
||||
|
||||
void (*dbgSignal)( int sig, int number ) = debuggerSignal;
|
||||
void (*dbgOutput)( const char *s, u32 addr ) = debuggerOutput;
|
||||
|
||||
|
||||
bool systemReadJoypads()
|
||||
{
|
||||
// TODO: implement
|
||||
return false;
|
||||
}
|
||||
|
||||
u32 systemReadJoypad( int which )
|
||||
{
|
||||
// TODO: implement
|
||||
return 0;
|
||||
}
|
||||
|
||||
void systemUpdateMotionSensor()
|
||||
{
|
||||
// TODO: implement
|
||||
}
|
||||
|
||||
|
||||
int systemGetSensorX()
|
||||
{
|
||||
// TODO: implement
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int systemGetSensorY()
|
||||
{
|
||||
// TODO: implement
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
u32 systemGetClock()
|
||||
{
|
||||
// TODO: implement
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void systemMessage( int number, const char *defaultMsg, ... )
|
||||
{
|
||||
// TODO: implement
|
||||
}
|
||||
|
||||
|
||||
void systemScreenCapture( int captureNumber )
|
||||
{
|
||||
// TODO: implement
|
||||
}
|
||||
|
||||
|
||||
void systemDrawScreen()
|
||||
{
|
||||
// TODO: implement
|
||||
}
|
||||
|
||||
|
||||
void systemShowSpeed( int speed )
|
||||
{
|
||||
// TODO: implement
|
||||
}
|
||||
|
||||
|
||||
void system10Frames( int rate )
|
||||
{
|
||||
// TODO: implement
|
||||
}
|
||||
|
||||
|
||||
void systemFrame()
|
||||
{
|
||||
// TODO: implement
|
||||
}
|
||||
|
||||
|
||||
bool systemPauseOnFrame()
|
||||
{
|
||||
// TODO: implement
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
void debuggerOutput( const char *s, u32 addr )
|
||||
{
|
||||
// TODO: implement
|
||||
}
|
||||
|
||||
|
||||
void debuggerSignal( int sig,int number )
|
||||
{
|
||||
// TODO: implement
|
||||
}
|
||||
|
||||
|
||||
void winlog( const char *msg, ... )
|
||||
{
|
||||
// TODO: implement
|
||||
}
|
||||
|
||||
|
||||
void systemWriteDataToSoundBuffer()
|
||||
{
|
||||
// TODO: implement
|
||||
}
|
||||
|
||||
void systemSoundShutdown()
|
||||
{
|
||||
// TODO: implement
|
||||
}
|
||||
|
||||
void systemSoundPause()
|
||||
{
|
||||
// TODO: implement
|
||||
}
|
||||
|
||||
void systemSoundResume()
|
||||
{
|
||||
// TODO: implement
|
||||
}
|
||||
|
||||
void systemSoundReset()
|
||||
{
|
||||
// TODO: implement
|
||||
}
|
||||
|
||||
bool systemSoundInit()
|
||||
{
|
||||
// TODO: implement
|
||||
return false;
|
||||
}
|
||||
|
||||
bool systemCanChangeSoundQuality()
|
||||
{
|
||||
// TODO: implement
|
||||
return false;
|
||||
}
|
||||
// VBA-M, A Nintendo Handheld Console Emulator
|
||||
// Copyright (C) 2008 VBA-M development team
|
||||
//
|
||||
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
// This file adds all the code required by System.h
|
||||
|
||||
|
||||
#include "emu.h"
|
||||
|
||||
|
||||
int emulating = 0;
|
||||
int systemFrameSkip = 0;
|
||||
int systemSaveUpdateCounter = SYSTEM_SAVE_NOT_UPDATED;
|
||||
bool systemSoundOn = false;
|
||||
u32 systemColorMap32[0x10000];
|
||||
u16 systemColorMap16[0x10000];
|
||||
int systemRedShift = 0;
|
||||
int systemBlueShift = 0;
|
||||
int systemGreenShift = 0;
|
||||
int systemColorDepth = 32;
|
||||
int systemDebug = 0;
|
||||
int systemVerbose = 0;
|
||||
|
||||
void (*dbgSignal)( int sig, int number ) = debuggerSignal;
|
||||
void (*dbgOutput)( const char *s, u32 addr ) = debuggerOutput;
|
||||
|
||||
|
||||
bool systemReadJoypads()
|
||||
{
|
||||
// TODO: implement
|
||||
return false;
|
||||
}
|
||||
|
||||
u32 systemReadJoypad( int which )
|
||||
{
|
||||
// TODO: implement
|
||||
return 0;
|
||||
}
|
||||
|
||||
void systemUpdateMotionSensor()
|
||||
{
|
||||
// TODO: implement
|
||||
}
|
||||
|
||||
|
||||
int systemGetSensorX()
|
||||
{
|
||||
// TODO: implement
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int systemGetSensorY()
|
||||
{
|
||||
// TODO: implement
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
u32 systemGetClock()
|
||||
{
|
||||
// TODO: implement
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void systemMessage( int number, const char *defaultMsg, ... )
|
||||
{
|
||||
// TODO: implement
|
||||
}
|
||||
|
||||
|
||||
void systemScreenCapture( int captureNumber )
|
||||
{
|
||||
// TODO: implement
|
||||
}
|
||||
|
||||
|
||||
void systemDrawScreen()
|
||||
{
|
||||
// TODO: implement
|
||||
}
|
||||
|
||||
|
||||
void systemShowSpeed( int speed )
|
||||
{
|
||||
// TODO: implement
|
||||
}
|
||||
|
||||
|
||||
void system10Frames( int rate )
|
||||
{
|
||||
// TODO: implement
|
||||
}
|
||||
|
||||
|
||||
void systemFrame()
|
||||
{
|
||||
// TODO: implement
|
||||
}
|
||||
|
||||
|
||||
bool systemPauseOnFrame()
|
||||
{
|
||||
// TODO: implement
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
void debuggerOutput( const char *s, u32 addr )
|
||||
{
|
||||
// TODO: implement
|
||||
}
|
||||
|
||||
|
||||
void debuggerSignal( int sig,int number )
|
||||
{
|
||||
// TODO: implement
|
||||
}
|
||||
|
||||
|
||||
void winlog( const char *msg, ... )
|
||||
{
|
||||
// TODO: implement
|
||||
}
|
||||
|
||||
|
||||
void systemWriteDataToSoundBuffer()
|
||||
{
|
||||
// TODO: implement
|
||||
}
|
||||
|
||||
void systemSoundShutdown()
|
||||
{
|
||||
// TODO: implement
|
||||
}
|
||||
|
||||
void systemSoundPause()
|
||||
{
|
||||
// TODO: implement
|
||||
}
|
||||
|
||||
void systemSoundResume()
|
||||
{
|
||||
// TODO: implement
|
||||
}
|
||||
|
||||
void systemSoundReset()
|
||||
{
|
||||
// TODO: implement
|
||||
}
|
||||
|
||||
bool systemSoundInit()
|
||||
{
|
||||
// TODO: implement
|
||||
return false;
|
||||
}
|
||||
|
||||
bool systemCanChangeSoundQuality()
|
||||
{
|
||||
// TODO: implement
|
||||
return false;
|
||||
}
|
||||
|
|
142
src/qt/emu.h
142
src/qt/emu.h
|
@ -1,71 +1,71 @@
|
|||
// VBA-M, A Nintendo Handheld Console Emulator
|
||||
// Copyright (C) 2008 VBA-M development team
|
||||
//
|
||||
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
|
||||
#ifndef EMU_H
|
||||
#define EMU_H
|
||||
|
||||
|
||||
#include "../System.h"
|
||||
|
||||
|
||||
// Global Variables
|
||||
extern int emulating;
|
||||
extern int systemFrameSkip;
|
||||
extern int systemSaveUpdateCounter;
|
||||
extern bool systemSoundOn;
|
||||
extern u32 systemColorMap32[0x10000];
|
||||
extern u16 systemColorMap16[0x10000];
|
||||
extern int systemRedShift;
|
||||
extern int systemBlueShift;
|
||||
extern int systemGreenShift;
|
||||
extern int systemColorDepth;
|
||||
extern int systemDebug;
|
||||
extern int systemVerbose;
|
||||
|
||||
|
||||
// Global Functions
|
||||
bool systemReadJoypads();
|
||||
u32 systemReadJoypad( int which );
|
||||
void systemUpdateMotionSensor();
|
||||
int systemGetSensorX();
|
||||
int systemGetSensorY();
|
||||
u32 systemGetClock();
|
||||
|
||||
void systemMessage( int number, const char *defaultMsg, ... );
|
||||
void winlog( const char *msg, ... );
|
||||
|
||||
void debuggerSignal( int sig,int number );
|
||||
void debuggerOutput( const char *s, u32 addr );
|
||||
|
||||
bool systemPauseOnFrame();
|
||||
void systemScreenCapture( int captureNumber );
|
||||
void systemDrawScreen();
|
||||
void systemShowSpeed( int speed );
|
||||
void system10Frames( int rate );
|
||||
void systemFrame();
|
||||
|
||||
void systemWriteDataToSoundBuffer();
|
||||
void systemSoundShutdown();
|
||||
void systemSoundPause();
|
||||
void systemSoundResume();
|
||||
void systemSoundReset();
|
||||
bool systemSoundInit();
|
||||
bool systemCanChangeSoundQuality();
|
||||
|
||||
|
||||
#endif // #ifndef EMU_H
|
||||
// VBA-M, A Nintendo Handheld Console Emulator
|
||||
// Copyright (C) 2008 VBA-M development team
|
||||
//
|
||||
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
|
||||
#ifndef EMU_H
|
||||
#define EMU_H
|
||||
|
||||
|
||||
#include "../System.h"
|
||||
|
||||
|
||||
// Global Variables
|
||||
extern int emulating;
|
||||
extern int systemFrameSkip;
|
||||
extern int systemSaveUpdateCounter;
|
||||
extern bool systemSoundOn;
|
||||
extern u32 systemColorMap32[0x10000];
|
||||
extern u16 systemColorMap16[0x10000];
|
||||
extern int systemRedShift;
|
||||
extern int systemBlueShift;
|
||||
extern int systemGreenShift;
|
||||
extern int systemColorDepth;
|
||||
extern int systemDebug;
|
||||
extern int systemVerbose;
|
||||
|
||||
|
||||
// Global Functions
|
||||
bool systemReadJoypads();
|
||||
u32 systemReadJoypad( int which );
|
||||
void systemUpdateMotionSensor();
|
||||
int systemGetSensorX();
|
||||
int systemGetSensorY();
|
||||
u32 systemGetClock();
|
||||
|
||||
void systemMessage( int number, const char *defaultMsg, ... );
|
||||
void winlog( const char *msg, ... );
|
||||
|
||||
void debuggerSignal( int sig,int number );
|
||||
void debuggerOutput( const char *s, u32 addr );
|
||||
|
||||
bool systemPauseOnFrame();
|
||||
void systemScreenCapture( int captureNumber );
|
||||
void systemDrawScreen();
|
||||
void systemShowSpeed( int speed );
|
||||
void system10Frames( int rate );
|
||||
void systemFrame();
|
||||
|
||||
void systemWriteDataToSoundBuffer();
|
||||
void systemSoundShutdown();
|
||||
void systemSoundPause();
|
||||
void systemSoundResume();
|
||||
void systemSoundReset();
|
||||
bool systemSoundInit();
|
||||
bool systemCanChangeSoundQuality();
|
||||
|
||||
|
||||
#endif // #ifndef EMU_H
|
||||
|
|
|
@ -1,290 +1,290 @@
|
|||
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
|
||||
// Copyright (C) 1999-2003 Forgotten
|
||||
// Copyright (C) 2004 Forgotten and the VBA development team
|
||||
|
||||
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
// AccelEditor.cpp : implementation file
|
||||
//
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "vba.h"
|
||||
#include "AccelEditor.h"
|
||||
#include "CmdAccelOb.h"
|
||||
|
||||
#ifdef _DEBUG
|
||||
#define new DEBUG_NEW
|
||||
#undef THIS_FILE
|
||||
static char THIS_FILE[] = __FILE__;
|
||||
#endif
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// AccelEditor dialog
|
||||
|
||||
|
||||
AccelEditor::AccelEditor(CWnd* pParent /*=NULL*/)
|
||||
: ResizeDlg(AccelEditor::IDD, pParent)
|
||||
{
|
||||
//{{AFX_DATA_INIT(AccelEditor)
|
||||
// NOTE: the ClassWizard will add member initialization here
|
||||
//}}AFX_DATA_INIT
|
||||
mgr = theApp.winAccelMgr;
|
||||
}
|
||||
|
||||
|
||||
void AccelEditor::DoDataExchange(CDataExchange* pDX)
|
||||
{
|
||||
CDialog::DoDataExchange(pDX);
|
||||
//{{AFX_DATA_MAP(AccelEditor)
|
||||
DDX_Control(pDX, IDC_CURRENTS, m_currents);
|
||||
DDX_Control(pDX, IDC_ALREADY_AFFECTED, m_alreadyAffected);
|
||||
DDX_Control(pDX, IDC_COMMANDS, m_commands);
|
||||
DDX_Control(pDX, IDC_EDIT_KEY, m_key);
|
||||
//}}AFX_DATA_MAP
|
||||
}
|
||||
|
||||
|
||||
BEGIN_MESSAGE_MAP(AccelEditor, CDialog)
|
||||
//{{AFX_MSG_MAP(AccelEditor)
|
||||
ON_BN_CLICKED(ID_OK, OnOk)
|
||||
ON_LBN_SELCHANGE(IDC_COMMANDS, OnSelchangeCommands)
|
||||
ON_BN_CLICKED(IDC_RESET, OnReset)
|
||||
ON_BN_CLICKED(IDC_ASSIGN, OnAssign)
|
||||
ON_BN_CLICKED(ID_CANCEL, OnCancel)
|
||||
ON_BN_CLICKED(IDC_REMOVE, OnRemove)
|
||||
//}}AFX_MSG_MAP
|
||||
END_MESSAGE_MAP()
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// AccelEditor message handlers
|
||||
|
||||
BOOL AccelEditor::OnInitDialog()
|
||||
{
|
||||
CDialog::OnInitDialog();
|
||||
|
||||
DIALOG_SIZER_START( sz )
|
||||
DIALOG_SIZER_ENTRY( IDC_STATIC1, DS_MoveX)
|
||||
DIALOG_SIZER_ENTRY( IDC_STATIC2, DS_MoveY)
|
||||
DIALOG_SIZER_ENTRY( IDC_STATIC3, DS_MoveX | DS_MoveY)
|
||||
DIALOG_SIZER_ENTRY( IDC_ALREADY_AFFECTED, DS_MoveY)
|
||||
DIALOG_SIZER_ENTRY( ID_OK, DS_MoveX)
|
||||
DIALOG_SIZER_ENTRY( ID_CANCEL, DS_MoveX)
|
||||
DIALOG_SIZER_ENTRY( IDC_ASSIGN, DS_MoveX)
|
||||
DIALOG_SIZER_ENTRY( IDC_REMOVE, DS_MoveX)
|
||||
DIALOG_SIZER_ENTRY( IDC_RESET, DS_MoveX)
|
||||
DIALOG_SIZER_ENTRY( IDC_CLOSE, DS_MoveY)
|
||||
DIALOG_SIZER_ENTRY( IDC_COMMANDS, DS_SizeX | DS_SizeY)
|
||||
DIALOG_SIZER_ENTRY( IDC_CURRENTS, DS_MoveX | DS_SizeY)
|
||||
DIALOG_SIZER_ENTRY( IDC_EDIT_KEY, DS_MoveX | DS_MoveY)
|
||||
DIALOG_SIZER_END()
|
||||
|
||||
SetData(sz,
|
||||
TRUE,
|
||||
HKEY_CURRENT_USER,
|
||||
"Software\\Emulators\\VisualBoyAdvance\\Viewer\\AccelEditor",
|
||||
NULL);
|
||||
|
||||
InitCommands();
|
||||
|
||||
return TRUE; // return TRUE unless you set the focus to a control
|
||||
// EXCEPTION: OCX Property Pages should return FALSE
|
||||
}
|
||||
|
||||
void AccelEditor::InitCommands()
|
||||
{
|
||||
m_commands.ResetContent();
|
||||
m_alreadyAffected.SetWindowText("");
|
||||
|
||||
POSITION pos = mgr.m_mapAccelString.GetStartPosition();
|
||||
|
||||
while(pos != NULL) {
|
||||
CString command;
|
||||
WORD wID;
|
||||
mgr.m_mapAccelString.GetNextAssoc(pos, command, wID);
|
||||
|
||||
int index = m_commands.AddString(command);
|
||||
m_commands.SetItemData(index, wID);
|
||||
}
|
||||
|
||||
// Update the currents accels associated with the selected command
|
||||
if (m_commands.SetCurSel(0) != LB_ERR)
|
||||
OnSelchangeCommands();
|
||||
}
|
||||
|
||||
void AccelEditor::OnCancel()
|
||||
{
|
||||
EndDialog(FALSE);
|
||||
}
|
||||
|
||||
void AccelEditor::OnOk()
|
||||
{
|
||||
EndDialog(TRUE);
|
||||
}
|
||||
|
||||
void AccelEditor::OnSelchangeCommands()
|
||||
{
|
||||
// Check if some commands exist.
|
||||
int index = m_commands.GetCurSel();
|
||||
if (index == LB_ERR)
|
||||
return;
|
||||
|
||||
WORD wIDCommand = LOWORD(m_commands.GetItemData(index));
|
||||
m_currents.ResetContent();
|
||||
|
||||
CCmdAccelOb* pCmdAccel;
|
||||
|
||||
if (mgr.m_mapAccelTable.Lookup(wIDCommand, pCmdAccel)) {
|
||||
CAccelsOb* pAccel;
|
||||
CString szBuffer;
|
||||
POSITION pos = pCmdAccel->m_Accels.GetHeadPosition();
|
||||
|
||||
// Add the keys to the 'currents keys' listbox.
|
||||
while (pos != NULL) {
|
||||
pAccel = pCmdAccel->m_Accels.GetNext(pos);
|
||||
pAccel->GetString(szBuffer);
|
||||
index = m_currents.AddString(szBuffer);
|
||||
// and a pointer to the accel object.
|
||||
m_currents.SetItemData(index, (DWORD_PTR)pAccel);
|
||||
}
|
||||
}
|
||||
// Init the key editor
|
||||
// m_pKey->ResetKey();
|
||||
|
||||
}
|
||||
|
||||
void AccelEditor::OnReset()
|
||||
{
|
||||
mgr.Default();
|
||||
InitCommands(); // update the listboxes.
|
||||
}
|
||||
|
||||
void AccelEditor::OnAssign()
|
||||
{
|
||||
// Control if it's not already affected
|
||||
CCmdAccelOb* pCmdAccel;
|
||||
CAccelsOb* pAccel;
|
||||
WORD wIDCommand;
|
||||
POSITION pos;
|
||||
|
||||
WORD wKey;
|
||||
bool bCtrl, bAlt, bShift;
|
||||
|
||||
if (!m_key.GetAccelKey(wKey, bCtrl, bAlt, bShift))
|
||||
return; // no valid key, abort
|
||||
|
||||
int count = m_commands.GetCount();
|
||||
int index;
|
||||
for (index = 0; index < count; index++) {
|
||||
|
||||
wIDCommand = LOWORD(m_commands.GetItemData(index));
|
||||
mgr.m_mapAccelTable.Lookup(wIDCommand, pCmdAccel);
|
||||
|
||||
pos = pCmdAccel->m_Accels.GetHeadPosition();
|
||||
while (pos != NULL) {
|
||||
pAccel = pCmdAccel->m_Accels.GetNext(pos);
|
||||
if (pAccel->IsEqual(wKey, bCtrl, bAlt, bShift)) {
|
||||
// the key is already affected (in the same or other command)
|
||||
m_alreadyAffected.SetWindowText(pCmdAccel->m_szCommand);
|
||||
m_key.SetSel(0, -1);
|
||||
return; // abort
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// OK, we can add the accel key in the currently selected group
|
||||
index = m_commands.GetCurSel();
|
||||
if (index == LB_ERR)
|
||||
return;
|
||||
|
||||
// Get the object who manage the accels list, associated to the command.
|
||||
wIDCommand = LOWORD(m_commands.GetItemData(index));
|
||||
|
||||
if (mgr.m_mapAccelTable.Lookup(wIDCommand, pCmdAccel) != TRUE)
|
||||
return;
|
||||
|
||||
BYTE cVirt = 0;
|
||||
if (bCtrl)
|
||||
cVirt |= FCONTROL;
|
||||
if (bAlt)
|
||||
cVirt |= FALT;
|
||||
if (bShift)
|
||||
cVirt |= FSHIFT;
|
||||
|
||||
cVirt |= FVIRTKEY;
|
||||
|
||||
// Create the new key...
|
||||
pAccel = new CAccelsOb(cVirt, wKey, false);
|
||||
ASSERT(pAccel != NULL);
|
||||
// ...and add in the list.
|
||||
pCmdAccel->m_Accels.AddTail(pAccel);
|
||||
|
||||
// Update the listbox.
|
||||
CString szBuffer;
|
||||
pAccel->GetString(szBuffer);
|
||||
|
||||
index = m_currents.AddString(szBuffer);
|
||||
m_currents.SetItemData(index, (DWORD_PTR)pAccel);
|
||||
|
||||
// Reset the key editor.
|
||||
m_key.ResetKey();
|
||||
}
|
||||
|
||||
void AccelEditor::OnRemove()
|
||||
{
|
||||
// Some controls
|
||||
int indexCurrent = m_currents.GetCurSel();
|
||||
if (indexCurrent == LB_ERR)
|
||||
return;
|
||||
|
||||
// 2nd part.
|
||||
int indexCmd = m_commands.GetCurSel();
|
||||
if (indexCmd == LB_ERR)
|
||||
return;
|
||||
|
||||
// Ref to the ID command
|
||||
WORD wIDCommand = LOWORD(m_commands.GetItemData(indexCmd));
|
||||
|
||||
// Run through the accels,and control if it can be deleted.
|
||||
CCmdAccelOb* pCmdAccel;
|
||||
if (mgr.m_mapAccelTable.Lookup(wIDCommand, pCmdAccel) == TRUE) {
|
||||
CAccelsOb* pAccel;
|
||||
CAccelsOb* pAccelCurrent = (CAccelsOb*)(m_currents.GetItemData(indexCurrent));
|
||||
CString szBuffer;
|
||||
POSITION pos = pCmdAccel->m_Accels.GetHeadPosition();
|
||||
POSITION PrevPos;
|
||||
while (pos != NULL) {
|
||||
PrevPos = pos;
|
||||
pAccel = pCmdAccel->m_Accels.GetNext(pos);
|
||||
if (pAccel == pAccelCurrent) {
|
||||
if (!pAccel->m_bLocked) {
|
||||
// not locked, so we delete the key
|
||||
pCmdAccel->m_Accels.RemoveAt(PrevPos);
|
||||
delete pAccel;
|
||||
// and update the listboxes/key editor/static text
|
||||
m_currents.DeleteString(indexCurrent);
|
||||
m_key.ResetKey();
|
||||
m_alreadyAffected.SetWindowText("");
|
||||
return;
|
||||
} else {
|
||||
systemMessage(0,"Unable to remove this\naccelerator (Locked)");
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
systemMessage(0,"internal error (CAccelDlgHelper::Remove : pAccel unavailable)");
|
||||
return;
|
||||
}
|
||||
systemMessage(0,"internal error (CAccelDlgHelper::Remove : Lookup failed)");
|
||||
}
|
||||
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
|
||||
// Copyright (C) 1999-2003 Forgotten
|
||||
// Copyright (C) 2004 Forgotten and the VBA development team
|
||||
|
||||
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
// AccelEditor.cpp : implementation file
|
||||
//
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "vba.h"
|
||||
#include "AccelEditor.h"
|
||||
#include "CmdAccelOb.h"
|
||||
|
||||
#ifdef _DEBUG
|
||||
#define new DEBUG_NEW
|
||||
#undef THIS_FILE
|
||||
static char THIS_FILE[] = __FILE__;
|
||||
#endif
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// AccelEditor dialog
|
||||
|
||||
|
||||
AccelEditor::AccelEditor(CWnd* pParent /*=NULL*/)
|
||||
: ResizeDlg(AccelEditor::IDD, pParent)
|
||||
{
|
||||
//{{AFX_DATA_INIT(AccelEditor)
|
||||
// NOTE: the ClassWizard will add member initialization here
|
||||
//}}AFX_DATA_INIT
|
||||
mgr = theApp.winAccelMgr;
|
||||
}
|
||||
|
||||
|
||||
void AccelEditor::DoDataExchange(CDataExchange* pDX)
|
||||
{
|
||||
CDialog::DoDataExchange(pDX);
|
||||
//{{AFX_DATA_MAP(AccelEditor)
|
||||
DDX_Control(pDX, IDC_CURRENTS, m_currents);
|
||||
DDX_Control(pDX, IDC_ALREADY_AFFECTED, m_alreadyAffected);
|
||||
DDX_Control(pDX, IDC_COMMANDS, m_commands);
|
||||
DDX_Control(pDX, IDC_EDIT_KEY, m_key);
|
||||
//}}AFX_DATA_MAP
|
||||
}
|
||||
|
||||
|
||||
BEGIN_MESSAGE_MAP(AccelEditor, CDialog)
|
||||
//{{AFX_MSG_MAP(AccelEditor)
|
||||
ON_BN_CLICKED(ID_OK, OnOk)
|
||||
ON_LBN_SELCHANGE(IDC_COMMANDS, OnSelchangeCommands)
|
||||
ON_BN_CLICKED(IDC_RESET, OnReset)
|
||||
ON_BN_CLICKED(IDC_ASSIGN, OnAssign)
|
||||
ON_BN_CLICKED(ID_CANCEL, OnCancel)
|
||||
ON_BN_CLICKED(IDC_REMOVE, OnRemove)
|
||||
//}}AFX_MSG_MAP
|
||||
END_MESSAGE_MAP()
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// AccelEditor message handlers
|
||||
|
||||
BOOL AccelEditor::OnInitDialog()
|
||||
{
|
||||
CDialog::OnInitDialog();
|
||||
|
||||
DIALOG_SIZER_START( sz )
|
||||
DIALOG_SIZER_ENTRY( IDC_STATIC1, DS_MoveX)
|
||||
DIALOG_SIZER_ENTRY( IDC_STATIC2, DS_MoveY)
|
||||
DIALOG_SIZER_ENTRY( IDC_STATIC3, DS_MoveX | DS_MoveY)
|
||||
DIALOG_SIZER_ENTRY( IDC_ALREADY_AFFECTED, DS_MoveY)
|
||||
DIALOG_SIZER_ENTRY( ID_OK, DS_MoveX)
|
||||
DIALOG_SIZER_ENTRY( ID_CANCEL, DS_MoveX)
|
||||
DIALOG_SIZER_ENTRY( IDC_ASSIGN, DS_MoveX)
|
||||
DIALOG_SIZER_ENTRY( IDC_REMOVE, DS_MoveX)
|
||||
DIALOG_SIZER_ENTRY( IDC_RESET, DS_MoveX)
|
||||
DIALOG_SIZER_ENTRY( IDC_CLOSE, DS_MoveY)
|
||||
DIALOG_SIZER_ENTRY( IDC_COMMANDS, DS_SizeX | DS_SizeY)
|
||||
DIALOG_SIZER_ENTRY( IDC_CURRENTS, DS_MoveX | DS_SizeY)
|
||||
DIALOG_SIZER_ENTRY( IDC_EDIT_KEY, DS_MoveX | DS_MoveY)
|
||||
DIALOG_SIZER_END()
|
||||
|
||||
SetData(sz,
|
||||
TRUE,
|
||||
HKEY_CURRENT_USER,
|
||||
"Software\\Emulators\\VisualBoyAdvance\\Viewer\\AccelEditor",
|
||||
NULL);
|
||||
|
||||
InitCommands();
|
||||
|
||||
return TRUE; // return TRUE unless you set the focus to a control
|
||||
// EXCEPTION: OCX Property Pages should return FALSE
|
||||
}
|
||||
|
||||
void AccelEditor::InitCommands()
|
||||
{
|
||||
m_commands.ResetContent();
|
||||
m_alreadyAffected.SetWindowText("");
|
||||
|
||||
POSITION pos = mgr.m_mapAccelString.GetStartPosition();
|
||||
|
||||
while(pos != NULL) {
|
||||
CString command;
|
||||
WORD wID;
|
||||
mgr.m_mapAccelString.GetNextAssoc(pos, command, wID);
|
||||
|
||||
int index = m_commands.AddString(command);
|
||||
m_commands.SetItemData(index, wID);
|
||||
}
|
||||
|
||||
// Update the currents accels associated with the selected command
|
||||
if (m_commands.SetCurSel(0) != LB_ERR)
|
||||
OnSelchangeCommands();
|
||||
}
|
||||
|
||||
void AccelEditor::OnCancel()
|
||||
{
|
||||
EndDialog(FALSE);
|
||||
}
|
||||
|
||||
void AccelEditor::OnOk()
|
||||
{
|
||||
EndDialog(TRUE);
|
||||
}
|
||||
|
||||
void AccelEditor::OnSelchangeCommands()
|
||||
{
|
||||
// Check if some commands exist.
|
||||
int index = m_commands.GetCurSel();
|
||||
if (index == LB_ERR)
|
||||
return;
|
||||
|
||||
WORD wIDCommand = LOWORD(m_commands.GetItemData(index));
|
||||
m_currents.ResetContent();
|
||||
|
||||
CCmdAccelOb* pCmdAccel;
|
||||
|
||||
if (mgr.m_mapAccelTable.Lookup(wIDCommand, pCmdAccel)) {
|
||||
CAccelsOb* pAccel;
|
||||
CString szBuffer;
|
||||
POSITION pos = pCmdAccel->m_Accels.GetHeadPosition();
|
||||
|
||||
// Add the keys to the 'currents keys' listbox.
|
||||
while (pos != NULL) {
|
||||
pAccel = pCmdAccel->m_Accels.GetNext(pos);
|
||||
pAccel->GetString(szBuffer);
|
||||
index = m_currents.AddString(szBuffer);
|
||||
// and a pointer to the accel object.
|
||||
m_currents.SetItemData(index, (DWORD_PTR)pAccel);
|
||||
}
|
||||
}
|
||||
// Init the key editor
|
||||
// m_pKey->ResetKey();
|
||||
|
||||
}
|
||||
|
||||
void AccelEditor::OnReset()
|
||||
{
|
||||
mgr.Default();
|
||||
InitCommands(); // update the listboxes.
|
||||
}
|
||||
|
||||
void AccelEditor::OnAssign()
|
||||
{
|
||||
// Control if it's not already affected
|
||||
CCmdAccelOb* pCmdAccel;
|
||||
CAccelsOb* pAccel;
|
||||
WORD wIDCommand;
|
||||
POSITION pos;
|
||||
|
||||
WORD wKey;
|
||||
bool bCtrl, bAlt, bShift;
|
||||
|
||||
if (!m_key.GetAccelKey(wKey, bCtrl, bAlt, bShift))
|
||||
return; // no valid key, abort
|
||||
|
||||
int count = m_commands.GetCount();
|
||||
int index;
|
||||
for (index = 0; index < count; index++) {
|
||||
|
||||
wIDCommand = LOWORD(m_commands.GetItemData(index));
|
||||
mgr.m_mapAccelTable.Lookup(wIDCommand, pCmdAccel);
|
||||
|
||||
pos = pCmdAccel->m_Accels.GetHeadPosition();
|
||||
while (pos != NULL) {
|
||||
pAccel = pCmdAccel->m_Accels.GetNext(pos);
|
||||
if (pAccel->IsEqual(wKey, bCtrl, bAlt, bShift)) {
|
||||
// the key is already affected (in the same or other command)
|
||||
m_alreadyAffected.SetWindowText(pCmdAccel->m_szCommand);
|
||||
m_key.SetSel(0, -1);
|
||||
return; // abort
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// OK, we can add the accel key in the currently selected group
|
||||
index = m_commands.GetCurSel();
|
||||
if (index == LB_ERR)
|
||||
return;
|
||||
|
||||
// Get the object who manage the accels list, associated to the command.
|
||||
wIDCommand = LOWORD(m_commands.GetItemData(index));
|
||||
|
||||
if (mgr.m_mapAccelTable.Lookup(wIDCommand, pCmdAccel) != TRUE)
|
||||
return;
|
||||
|
||||
BYTE cVirt = 0;
|
||||
if (bCtrl)
|
||||
cVirt |= FCONTROL;
|
||||
if (bAlt)
|
||||
cVirt |= FALT;
|
||||
if (bShift)
|
||||
cVirt |= FSHIFT;
|
||||
|
||||
cVirt |= FVIRTKEY;
|
||||
|
||||
// Create the new key...
|
||||
pAccel = new CAccelsOb(cVirt, wKey, false);
|
||||
ASSERT(pAccel != NULL);
|
||||
// ...and add in the list.
|
||||
pCmdAccel->m_Accels.AddTail(pAccel);
|
||||
|
||||
// Update the listbox.
|
||||
CString szBuffer;
|
||||
pAccel->GetString(szBuffer);
|
||||
|
||||
index = m_currents.AddString(szBuffer);
|
||||
m_currents.SetItemData(index, (DWORD_PTR)pAccel);
|
||||
|
||||
// Reset the key editor.
|
||||
m_key.ResetKey();
|
||||
}
|
||||
|
||||
void AccelEditor::OnRemove()
|
||||
{
|
||||
// Some controls
|
||||
int indexCurrent = m_currents.GetCurSel();
|
||||
if (indexCurrent == LB_ERR)
|
||||
return;
|
||||
|
||||
// 2nd part.
|
||||
int indexCmd = m_commands.GetCurSel();
|
||||
if (indexCmd == LB_ERR)
|
||||
return;
|
||||
|
||||
// Ref to the ID command
|
||||
WORD wIDCommand = LOWORD(m_commands.GetItemData(indexCmd));
|
||||
|
||||
// Run through the accels,and control if it can be deleted.
|
||||
CCmdAccelOb* pCmdAccel;
|
||||
if (mgr.m_mapAccelTable.Lookup(wIDCommand, pCmdAccel) == TRUE) {
|
||||
CAccelsOb* pAccel;
|
||||
CAccelsOb* pAccelCurrent = (CAccelsOb*)(m_currents.GetItemData(indexCurrent));
|
||||
CString szBuffer;
|
||||
POSITION pos = pCmdAccel->m_Accels.GetHeadPosition();
|
||||
POSITION PrevPos;
|
||||
while (pos != NULL) {
|
||||
PrevPos = pos;
|
||||
pAccel = pCmdAccel->m_Accels.GetNext(pos);
|
||||
if (pAccel == pAccelCurrent) {
|
||||
if (!pAccel->m_bLocked) {
|
||||
// not locked, so we delete the key
|
||||
pCmdAccel->m_Accels.RemoveAt(PrevPos);
|
||||
delete pAccel;
|
||||
// and update the listboxes/key editor/static text
|
||||
m_currents.DeleteString(indexCurrent);
|
||||
m_key.ResetKey();
|
||||
m_alreadyAffected.SetWindowText("");
|
||||
return;
|
||||
} else {
|
||||
systemMessage(0,"Unable to remove this\naccelerator (Locked)");
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
systemMessage(0,"internal error (CAccelDlgHelper::Remove : pAccel unavailable)");
|
||||
return;
|
||||
}
|
||||
systemMessage(0,"internal error (CAccelDlgHelper::Remove : Lookup failed)");
|
||||
}
|
||||
|
|
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
1528
src/win32/OpenGL.cpp
1528
src/win32/OpenGL.cpp
File diff suppressed because it is too large
Load Diff
5316
src/win32/VBA.cpp
5316
src/win32/VBA.cpp
File diff suppressed because it is too large
Load Diff
556
src/win32/VBA.h
556
src/win32/VBA.h
|
@ -1,278 +1,278 @@
|
|||
// -*- C++ -*-
|
||||
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
|
||||
// Copyright (C) 1999-2003 Forgotten
|
||||
// Copyright (C) 2005 Forgotten and the VBA development team
|
||||
|
||||
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
// VBA.h : main header file for the VBA application
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __AFXWIN_H__
|
||||
#error include 'stdafx.h' before including this file for PCH
|
||||
#endif
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "resource.h"
|
||||
//#include <afxtempl.h>
|
||||
|
||||
#include "AcceleratorManager.h"
|
||||
#include "Display.h"
|
||||
#include "Input.h"
|
||||
#include "IUpdate.h"
|
||||
#include "Sound.h"
|
||||
#include "../System.h"
|
||||
#include "../Util.h"
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// VBA:
|
||||
// See VBA.cpp for the implementation of this class
|
||||
//
|
||||
|
||||
enum VIDEO_SIZE{
|
||||
VIDEO_1X, VIDEO_2X, VIDEO_3X, VIDEO_4X,
|
||||
VIDEO_320x240, VIDEO_640x480, VIDEO_800x600, VIDEO_1024x768, VIDEO_1280x1024,
|
||||
VIDEO_OTHER
|
||||
};
|
||||
|
||||
enum pixelFilterType
|
||||
{
|
||||
FILTER_NONE,
|
||||
|
||||
FILTER_SIMPLE2X, FILTER_PIXELATE, FILTER_TVMODE, FILTER_SCANLINES,
|
||||
FILTER_PLUGIN,
|
||||
FILTER_BILINEAR, FILTER_BILINEARPLUS, FILTER_MAMESCALE2X,
|
||||
FILTER_2XSAI, FILTER_SUPER2XSAI, FILTER_SUPEREAGLE, FILTER_LQ2X, FILTER_HQ2X,
|
||||
|
||||
FILTER_SIMPLE3X, FILTER_HQ3X,
|
||||
|
||||
FILTER_SIMPLE4X, FILTER_HQ4X
|
||||
};
|
||||
|
||||
#define REWIND_SIZE 400000
|
||||
|
||||
class AVIWrite;
|
||||
class WavWriter;
|
||||
|
||||
class VBA : public CWinApp
|
||||
{
|
||||
public:
|
||||
CMenu m_menu;
|
||||
HMENU menu;
|
||||
HMENU popup;
|
||||
bool mode320Available;
|
||||
bool mode640Available;
|
||||
bool mode800Available;
|
||||
bool mode1024Available;
|
||||
bool mode1280Available;
|
||||
int windowPositionX;
|
||||
int windowPositionY;
|
||||
void (*filterFunction)(u8*,u32,u8*,u8*,u32,int,int);
|
||||
void (*ifbFunction)(u8*,u32,int,int);
|
||||
int ifbType;
|
||||
int filterType;
|
||||
char pluginName[MAX_PATH];
|
||||
int filterWidth;
|
||||
int filterHeight;
|
||||
int filterMagnification;
|
||||
int filterLCD;
|
||||
int fsWidth;
|
||||
int fsHeight;
|
||||
int fsColorDepth;
|
||||
int fsFrequency;
|
||||
int fsAdapter;
|
||||
bool fsForceChange;
|
||||
int sizeX;
|
||||
int sizeY;
|
||||
int surfaceSizeX;
|
||||
int surfaceSizeY;
|
||||
int videoOption;
|
||||
bool fullScreenStretch;
|
||||
bool disableStatusMessage;
|
||||
int showSpeed;
|
||||
BOOL showSpeedTransparent;
|
||||
int showRenderedFrames;
|
||||
bool screenMessage;
|
||||
CString screenMessageBuffer;
|
||||
DWORD screenMessageTime;
|
||||
u8 *delta[257*244*4];
|
||||
bool menuToggle;
|
||||
IDisplay *display;
|
||||
IMAGE_TYPE cartridgeType;
|
||||
bool soundInitialized;
|
||||
bool useBiosFileGBA;
|
||||
bool useBiosFileGB;
|
||||
bool skipBiosFile;
|
||||
CString biosFileNameGBA;
|
||||
CString biosFileNameGB;
|
||||
bool active;
|
||||
bool paused;
|
||||
CString recentFiles[10];
|
||||
bool recentFreeze;
|
||||
bool autoSaveLoadCheatList;
|
||||
FILE *winout;
|
||||
bool removeIntros;
|
||||
bool autoIPS;
|
||||
int winGbBorderOn;
|
||||
int winFlashSize;
|
||||
bool winRtcEnable;
|
||||
bool winGenericflashcardEnable;
|
||||
int winSaveType;
|
||||
char *rewindMemory;
|
||||
int rewindPos;
|
||||
int rewindTopPos;
|
||||
int rewindCounter;
|
||||
int rewindCount;
|
||||
bool rewindSaveNeeded;
|
||||
int rewindTimer;
|
||||
int captureFormat;
|
||||
bool tripleBuffering;
|
||||
unsigned short throttle;
|
||||
u32 autoFrameSkipLastTime;
|
||||
bool autoFrameSkip;
|
||||
bool vsync;
|
||||
bool changingVideoSize;
|
||||
DISPLAY_TYPE renderMethod;
|
||||
AUDIO_API audioAPI;
|
||||
#ifndef NO_OAL
|
||||
TCHAR *oalDevice;
|
||||
int oalBufferCount;
|
||||
#endif
|
||||
bool iconic;
|
||||
#ifndef NO_D3D
|
||||
int d3dFilter;
|
||||
bool d3dMotionBlur;
|
||||
#endif
|
||||
int glFilter;
|
||||
bool dinputKeyFocus;
|
||||
bool pauseWhenInactive;
|
||||
bool speedupToggle;
|
||||
bool winGbPrinterEnabled;
|
||||
int threadPriority;
|
||||
bool disableMMX;
|
||||
int languageOption;
|
||||
CString languageName;
|
||||
HMODULE languageModule;
|
||||
int renderedFrames;
|
||||
Input *input;
|
||||
int joypadDefault;
|
||||
int autoFire;
|
||||
bool autoFireToggle;
|
||||
bool winPauseNextFrame;
|
||||
bool soundRecording;
|
||||
WavWriter *soundRecorder;
|
||||
CString soundRecordName;
|
||||
bool dsoundDisableHardwareAcceleration;
|
||||
ISound *sound;
|
||||
bool aviRecording;
|
||||
AVIWrite *aviRecorder;
|
||||
CString aviRecordName;
|
||||
bool painting;
|
||||
unsigned int skipAudioFrames;
|
||||
bool movieRecording;
|
||||
bool moviePlaying;
|
||||
int movieFrame;
|
||||
int moviePlayFrame;
|
||||
FILE *movieFile;
|
||||
u32 movieLastJoypad;
|
||||
u32 movieNextJoypad;
|
||||
int sensorX;
|
||||
int sensorY;
|
||||
int mouseCounter;
|
||||
bool wasPaused;
|
||||
int frameskipadjust;
|
||||
bool autoLoadMostRecent;
|
||||
int fsMaxScale;
|
||||
int romSize;
|
||||
VIDEO_SIZE lastWindowed;
|
||||
VIDEO_SIZE lastFullscreen;
|
||||
|
||||
CList<IUpdateListener *, IUpdateListener*&> updateList;
|
||||
int updateCount;
|
||||
|
||||
CAcceleratorManager winAccelMgr;
|
||||
HACCEL hAccel;
|
||||
|
||||
RECT rect;
|
||||
RECT dest;
|
||||
|
||||
struct EmulatedSystem emulator;
|
||||
|
||||
CString szFile;
|
||||
CString filename;
|
||||
CString dir;
|
||||
|
||||
CString wndClass;
|
||||
|
||||
public:
|
||||
VBA();
|
||||
~VBA();
|
||||
|
||||
void adjustDestRect();
|
||||
void updateIFB();
|
||||
void updateFilter();
|
||||
void updateThrottle( unsigned short throttle );
|
||||
void updateMenuBar();
|
||||
void winAddUpdateListener(IUpdateListener *l);
|
||||
void winRemoveUpdateListener(IUpdateListener *l);
|
||||
CString winLoadFilter(UINT id);
|
||||
|
||||
// Overrides
|
||||
// ClassWizard generated virtual function overrides
|
||||
//{{AFX_VIRTUAL(VBA)
|
||||
public:
|
||||
virtual BOOL InitInstance();
|
||||
virtual BOOL OnIdle(LONG lCount);
|
||||
//}}AFX_VIRTUAL
|
||||
|
||||
// Implementation
|
||||
|
||||
public:
|
||||
void saveSettings();
|
||||
void movieReadNext();
|
||||
bool initInput();
|
||||
HMODULE winLoadLanguage(const char *name);
|
||||
void winSetLanguageOption(int option, bool force);
|
||||
#ifdef MMX
|
||||
bool detectMMX();
|
||||
#endif
|
||||
void updatePriority();
|
||||
void directXMessage(const char *msg);
|
||||
void shutdownDisplay();
|
||||
bool preInitialize();
|
||||
bool updateRenderMethod0(bool force);
|
||||
bool updateRenderMethod(bool force);
|
||||
bool initDisplay();
|
||||
void updateWindowSize(int value);
|
||||
void updateVideoSize(UINT id);
|
||||
void updateFrameSkip();
|
||||
void loadSettings();
|
||||
void addRecentFile(CString file);
|
||||
//{{AFX_MSG(VBA)
|
||||
afx_msg void OnAppAbout();
|
||||
// NOTE - the ClassWizard will add and remove member functions here.
|
||||
// DO NOT EDIT what you see in these blocks of generated code !
|
||||
//}}AFX_MSG
|
||||
DECLARE_MESSAGE_MAP()
|
||||
};
|
||||
|
||||
extern VBA theApp;
|
||||
extern int emulating;
|
||||
|
||||
#ifdef MMX
|
||||
extern "C" bool cpu_mmx;
|
||||
#endif
|
||||
// -*- C++ -*-
|
||||
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
|
||||
// Copyright (C) 1999-2003 Forgotten
|
||||
// Copyright (C) 2005 Forgotten and the VBA development team
|
||||
|
||||
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
// VBA.h : main header file for the VBA application
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __AFXWIN_H__
|
||||
#error include 'stdafx.h' before including this file for PCH
|
||||
#endif
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "resource.h"
|
||||
//#include <afxtempl.h>
|
||||
|
||||
#include "AcceleratorManager.h"
|
||||
#include "Display.h"
|
||||
#include "Input.h"
|
||||
#include "IUpdate.h"
|
||||
#include "Sound.h"
|
||||
#include "../System.h"
|
||||
#include "../Util.h"
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// VBA:
|
||||
// See VBA.cpp for the implementation of this class
|
||||
//
|
||||
|
||||
enum VIDEO_SIZE{
|
||||
VIDEO_1X, VIDEO_2X, VIDEO_3X, VIDEO_4X,
|
||||
VIDEO_320x240, VIDEO_640x480, VIDEO_800x600, VIDEO_1024x768, VIDEO_1280x1024,
|
||||
VIDEO_OTHER
|
||||
};
|
||||
|
||||
enum pixelFilterType
|
||||
{
|
||||
FILTER_NONE,
|
||||
|
||||
FILTER_SIMPLE2X, FILTER_PIXELATE, FILTER_TVMODE, FILTER_SCANLINES,
|
||||
FILTER_PLUGIN,
|
||||
FILTER_BILINEAR, FILTER_BILINEARPLUS, FILTER_MAMESCALE2X,
|
||||
FILTER_2XSAI, FILTER_SUPER2XSAI, FILTER_SUPEREAGLE, FILTER_LQ2X, FILTER_HQ2X,
|
||||
|
||||
FILTER_SIMPLE3X, FILTER_HQ3X,
|
||||
|
||||
FILTER_SIMPLE4X, FILTER_HQ4X
|
||||
};
|
||||
|
||||
#define REWIND_SIZE 400000
|
||||
|
||||
class AVIWrite;
|
||||
class WavWriter;
|
||||
|
||||
class VBA : public CWinApp
|
||||
{
|
||||
public:
|
||||
CMenu m_menu;
|
||||
HMENU menu;
|
||||
HMENU popup;
|
||||
bool mode320Available;
|
||||
bool mode640Available;
|
||||
bool mode800Available;
|
||||
bool mode1024Available;
|
||||
bool mode1280Available;
|
||||
int windowPositionX;
|
||||
int windowPositionY;
|
||||
void (*filterFunction)(u8*,u32,u8*,u8*,u32,int,int);
|
||||
void (*ifbFunction)(u8*,u32,int,int);
|
||||
int ifbType;
|
||||
int filterType;
|
||||
char pluginName[MAX_PATH];
|
||||
int filterWidth;
|
||||
int filterHeight;
|
||||
int filterMagnification;
|
||||
int filterLCD;
|
||||
int fsWidth;
|
||||
int fsHeight;
|
||||
int fsColorDepth;
|
||||
int fsFrequency;
|
||||
int fsAdapter;
|
||||
bool fsForceChange;
|
||||
int sizeX;
|
||||
int sizeY;
|
||||
int surfaceSizeX;
|
||||
int surfaceSizeY;
|
||||
int videoOption;
|
||||
bool fullScreenStretch;
|
||||
bool disableStatusMessage;
|
||||
int showSpeed;
|
||||
BOOL showSpeedTransparent;
|
||||
int showRenderedFrames;
|
||||
bool screenMessage;
|
||||
CString screenMessageBuffer;
|
||||
DWORD screenMessageTime;
|
||||
u8 *delta[257*244*4];
|
||||
bool menuToggle;
|
||||
IDisplay *display;
|
||||
IMAGE_TYPE cartridgeType;
|
||||
bool soundInitialized;
|
||||
bool useBiosFileGBA;
|
||||
bool useBiosFileGB;
|
||||
bool skipBiosFile;
|
||||
CString biosFileNameGBA;
|
||||
CString biosFileNameGB;
|
||||
bool active;
|
||||
bool paused;
|
||||
CString recentFiles[10];
|
||||
bool recentFreeze;
|
||||
bool autoSaveLoadCheatList;
|
||||
FILE *winout;
|
||||
bool removeIntros;
|
||||
bool autoIPS;
|
||||
int winGbBorderOn;
|
||||
int winFlashSize;
|
||||
bool winRtcEnable;
|
||||
bool winGenericflashcardEnable;
|
||||
int winSaveType;
|
||||
char *rewindMemory;
|
||||
int rewindPos;
|
||||
int rewindTopPos;
|
||||
int rewindCounter;
|
||||
int rewindCount;
|
||||
bool rewindSaveNeeded;
|
||||
int rewindTimer;
|
||||
int captureFormat;
|
||||
bool tripleBuffering;
|
||||
unsigned short throttle;
|
||||
u32 autoFrameSkipLastTime;
|
||||
bool autoFrameSkip;
|
||||
bool vsync;
|
||||
bool changingVideoSize;
|
||||
DISPLAY_TYPE renderMethod;
|
||||
AUDIO_API audioAPI;
|
||||
#ifndef NO_OAL
|
||||
TCHAR *oalDevice;
|
||||
int oalBufferCount;
|
||||
#endif
|
||||
bool iconic;
|
||||
#ifndef NO_D3D
|
||||
int d3dFilter;
|
||||
bool d3dMotionBlur;
|
||||
#endif
|
||||
int glFilter;
|
||||
bool dinputKeyFocus;
|
||||
bool pauseWhenInactive;
|
||||
bool speedupToggle;
|
||||
bool winGbPrinterEnabled;
|
||||
int threadPriority;
|
||||
bool disableMMX;
|
||||
int languageOption;
|
||||
CString languageName;
|
||||
HMODULE languageModule;
|
||||
int renderedFrames;
|
||||
Input *input;
|
||||
int joypadDefault;
|
||||
int autoFire;
|
||||
bool autoFireToggle;
|
||||
bool winPauseNextFrame;
|
||||
bool soundRecording;
|
||||
WavWriter *soundRecorder;
|
||||
CString soundRecordName;
|
||||
bool dsoundDisableHardwareAcceleration;
|
||||
ISound *sound;
|
||||
bool aviRecording;
|
||||
AVIWrite *aviRecorder;
|
||||
CString aviRecordName;
|
||||
bool painting;
|
||||
unsigned int skipAudioFrames;
|
||||
bool movieRecording;
|
||||
bool moviePlaying;
|
||||
int movieFrame;
|
||||
int moviePlayFrame;
|
||||
FILE *movieFile;
|
||||
u32 movieLastJoypad;
|
||||
u32 movieNextJoypad;
|
||||
int sensorX;
|
||||
int sensorY;
|
||||
int mouseCounter;
|
||||
bool wasPaused;
|
||||
int frameskipadjust;
|
||||
bool autoLoadMostRecent;
|
||||
int fsMaxScale;
|
||||
int romSize;
|
||||
VIDEO_SIZE lastWindowed;
|
||||
VIDEO_SIZE lastFullscreen;
|
||||
|
||||
CList<IUpdateListener *, IUpdateListener*&> updateList;
|
||||
int updateCount;
|
||||
|
||||
CAcceleratorManager winAccelMgr;
|
||||
HACCEL hAccel;
|
||||
|
||||
RECT rect;
|
||||
RECT dest;
|
||||
|
||||
struct EmulatedSystem emulator;
|
||||
|
||||
CString szFile;
|
||||
CString filename;
|
||||
CString dir;
|
||||
|
||||
CString wndClass;
|
||||
|
||||
public:
|
||||
VBA();
|
||||
~VBA();
|
||||
|
||||
void adjustDestRect();
|
||||
void updateIFB();
|
||||
void updateFilter();
|
||||
void updateThrottle( unsigned short throttle );
|
||||
void updateMenuBar();
|
||||
void winAddUpdateListener(IUpdateListener *l);
|
||||
void winRemoveUpdateListener(IUpdateListener *l);
|
||||
CString winLoadFilter(UINT id);
|
||||
|
||||
// Overrides
|
||||
// ClassWizard generated virtual function overrides
|
||||
//{{AFX_VIRTUAL(VBA)
|
||||
public:
|
||||
virtual BOOL InitInstance();
|
||||
virtual BOOL OnIdle(LONG lCount);
|
||||
//}}AFX_VIRTUAL
|
||||
|
||||
// Implementation
|
||||
|
||||
public:
|
||||
void saveSettings();
|
||||
void movieReadNext();
|
||||
bool initInput();
|
||||
HMODULE winLoadLanguage(const char *name);
|
||||
void winSetLanguageOption(int option, bool force);
|
||||
#ifdef MMX
|
||||
bool detectMMX();
|
||||
#endif
|
||||
void updatePriority();
|
||||
void directXMessage(const char *msg);
|
||||
void shutdownDisplay();
|
||||
bool preInitialize();
|
||||
bool updateRenderMethod0(bool force);
|
||||
bool updateRenderMethod(bool force);
|
||||
bool initDisplay();
|
||||
void updateWindowSize(int value);
|
||||
void updateVideoSize(UINT id);
|
||||
void updateFrameSkip();
|
||||
void loadSettings();
|
||||
void addRecentFile(CString file);
|
||||
//{{AFX_MSG(VBA)
|
||||
afx_msg void OnAppAbout();
|
||||
// NOTE - the ClassWizard will add and remove member functions here.
|
||||
// DO NOT EDIT what you see in these blocks of generated code !
|
||||
//}}AFX_MSG
|
||||
DECLARE_MESSAGE_MAP()
|
||||
};
|
||||
|
||||
extern VBA theApp;
|
||||
extern int emulating;
|
||||
|
||||
#ifdef MMX
|
||||
extern "C" bool cpu_mmx;
|
||||
#endif
|
||||
|
|
4524
src/win32/VBA.rc
4524
src/win32/VBA.rc
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue