Compare commits
22 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 42d9266038 | |||
| 2a0611cd32 | |||
| e8d3c6ca76 | |||
| e47e9dc66a | |||
| aee471fb3f | |||
| 514109a0ac | |||
| 1e8fcbc37f | |||
| c43aeebecd | |||
| 9ec2347451 | |||
| 20b0744e2a | |||
| 7d5ac35ada | |||
| 43bdc01a64 | |||
| a5c6d11348 | |||
| 464b72b64b | |||
| 94f13711c6 | |||
| d1c1d702a1 | |||
| 9ccda03447 | |||
| f7d0113d53 | |||
| 71cff21815 | |||
| 77be2fd8b6 | |||
| 0eabcaabcd | |||
| 2f122a79ff |
+14
-12
@@ -1,6 +1,18 @@
|
||||
# Xcode
|
||||
.DS_Store
|
||||
*/build/*
|
||||
|
||||
# Xcode
|
||||
|
||||
## User settings
|
||||
xcuserdata/
|
||||
|
||||
## compatibility with Xcode 8 and earlier (ignoring not required starting Xcode 9)
|
||||
*.xcscmblueprint
|
||||
*.xccheckout
|
||||
|
||||
## compatibility with Xcode 3 and earlier (ignoring not required starting Xcode 4)
|
||||
build/
|
||||
DerivedData/
|
||||
*.moved-aside
|
||||
*.pbxuser
|
||||
!default.pbxuser
|
||||
*.mode1v3
|
||||
@@ -9,13 +21,3 @@
|
||||
!default.mode2v3
|
||||
*.perspectivev3
|
||||
!default.perspectivev3
|
||||
xcuserdata
|
||||
profile
|
||||
*.moved-aside
|
||||
DerivedData
|
||||
.idea/
|
||||
*.hmap
|
||||
*.xccheckout
|
||||
|
||||
#CocoaPods
|
||||
Pods
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
Original author
|
||||
---------------
|
||||
yopyop
|
||||
|
||||
Current team
|
||||
------------
|
||||
Guillaume Duhamel
|
||||
Normmatt
|
||||
Riccardo Magliocchetti
|
||||
CrazyMax
|
||||
zeromus
|
||||
rogerman
|
||||
Luigi__
|
||||
|
||||
Contributors
|
||||
------------
|
||||
Bernat Muñoz (shash)
|
||||
Allustar
|
||||
amponzi
|
||||
Anthony Molinaro
|
||||
ape
|
||||
Damien Nozay (damdoum)
|
||||
delfare
|
||||
Romain Vallet
|
||||
snkmad
|
||||
Theo Berkau
|
||||
thoduv
|
||||
Tim Seidel (Mighty Max)
|
||||
Pascal Giard (evilynux)
|
||||
Ben Jaques (masscat)
|
||||
Jeff Bland
|
||||
Bernat Muñoz (shash)
|
||||
matusz
|
||||
nitsuja
|
||||
gocha
|
||||
pa__
|
||||
adelikat
|
||||
hi-coder
|
||||
WinterMute
|
||||
pengvado
|
||||
dormito
|
||||
ldesnogue
|
||||
mtheall
|
||||
thelemonman
|
||||
nash679
|
||||
pokefan999
|
||||
dottorleo
|
||||
@@ -0,0 +1,339 @@
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
License is intended to guarantee your freedom to share and change free
|
||||
software--to make sure the software is free for all its users. This
|
||||
General Public License applies to most of the Free Software
|
||||
Foundation's software and to any other program whose authors commit to
|
||||
using it. (Some other Free Software Foundation software is covered by
|
||||
the GNU Lesser General Public License instead.) You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
this service if you wish), that you receive source code or can get it
|
||||
if you want it, that you can change the software or use pieces of it
|
||||
in new free programs; and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
anyone to deny you these rights or to ask you to surrender the rights.
|
||||
These restrictions translate to certain responsibilities for you if you
|
||||
distribute copies of the software, or if you modify it.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must give the recipients all the rights that
|
||||
you have. You must make sure that they, too, receive or can get the
|
||||
source code. And you must show them these terms so they know their
|
||||
rights.
|
||||
|
||||
We protect your rights with two steps: (1) copyright the software, and
|
||||
(2) offer you this license which gives you legal permission to copy,
|
||||
distribute and/or modify the software.
|
||||
|
||||
Also, for each author's protection and ours, we want to make certain
|
||||
that everyone understands that there is no warranty for this free
|
||||
software. If the software is modified by someone else and passed on, we
|
||||
want its recipients to know that what they have is not the original, so
|
||||
that any problems introduced by others will not reflect on the original
|
||||
authors' reputations.
|
||||
|
||||
Finally, any free program is threatened constantly by software
|
||||
patents. We wish to avoid the danger that redistributors of a free
|
||||
program will individually obtain patent licenses, in effect making the
|
||||
program proprietary. To prevent this, we have made it clear that any
|
||||
patent must be licensed for everyone's free use or not licensed at all.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License applies to any program or other work which contains
|
||||
a notice placed by the copyright holder saying it may be distributed
|
||||
under the terms of this General Public License. The "Program", below,
|
||||
refers to any such program or work, and a "work based on the Program"
|
||||
means either the Program or any derivative work under copyright law:
|
||||
that is to say, a work containing the Program or a portion of it,
|
||||
either verbatim or with modifications and/or translated into another
|
||||
language. (Hereinafter, translation is included without limitation in
|
||||
the term "modification".) Each licensee is addressed as "you".
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running the Program is not restricted, and the output from the Program
|
||||
is covered only if its contents constitute a work based on the
|
||||
Program (independent of having been made by running the Program).
|
||||
Whether that is true depends on what the Program does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Program's
|
||||
source code as you receive it, in any medium, provided that you
|
||||
conspicuously and appropriately publish on each copy an appropriate
|
||||
copyright notice and disclaimer of warranty; keep intact all the
|
||||
notices that refer to this License and to the absence of any warranty;
|
||||
and give any other recipients of the Program a copy of this License
|
||||
along with the Program.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy, and
|
||||
you may at your option offer warranty protection in exchange for a fee.
|
||||
|
||||
2. You may modify your copy or copies of the Program or any portion
|
||||
of it, thus forming a work based on the Program, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) You must cause the modified files to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
b) You must cause any work that you distribute or publish, that in
|
||||
whole or in part contains or is derived from the Program or any
|
||||
part thereof, to be licensed as a whole at no charge to all third
|
||||
parties under the terms of this License.
|
||||
|
||||
c) If the modified program normally reads commands interactively
|
||||
when run, you must cause it, when started running for such
|
||||
interactive use in the most ordinary way, to print or display an
|
||||
announcement including an appropriate copyright notice and a
|
||||
notice that there is no warranty (or else, saying that you provide
|
||||
a warranty) and that users may redistribute the program under
|
||||
these conditions, and telling the user how to view a copy of this
|
||||
License. (Exception: if the Program itself is interactive but
|
||||
does not normally print such an announcement, your work based on
|
||||
the Program is not required to print an announcement.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Program,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Program, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Program.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Program
|
||||
with the Program (or with a work based on the Program) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may copy and distribute the Program (or a work based on it,
|
||||
under Section 2) in object code or executable form under the terms of
|
||||
Sections 1 and 2 above provided that you also do one of the following:
|
||||
|
||||
a) Accompany it with the complete corresponding machine-readable
|
||||
source code, which must be distributed under the terms of Sections
|
||||
1 and 2 above on a medium customarily used for software interchange; or,
|
||||
|
||||
b) Accompany it with a written offer, valid for at least three
|
||||
years, to give any third party, for a charge no more than your
|
||||
cost of physically performing source distribution, a complete
|
||||
machine-readable copy of the corresponding source code, to be
|
||||
distributed under the terms of Sections 1 and 2 above on a medium
|
||||
customarily used for software interchange; or,
|
||||
|
||||
c) Accompany it with the information you received as to the offer
|
||||
to distribute corresponding source code. (This alternative is
|
||||
allowed only for noncommercial distribution and only if you
|
||||
received the program in object code or executable form with such
|
||||
an offer, in accord with Subsection b above.)
|
||||
|
||||
The source code for a work means the preferred form of the work for
|
||||
making modifications to it. For an executable work, complete source
|
||||
code means all the source code for all modules it contains, plus any
|
||||
associated interface definition files, plus the scripts used to
|
||||
control compilation and installation of the executable. However, as a
|
||||
special exception, the source code distributed need not include
|
||||
anything that is normally distributed (in either source or binary
|
||||
form) with the major components (compiler, kernel, and so on) of the
|
||||
operating system on which the executable runs, unless that component
|
||||
itself accompanies the executable.
|
||||
|
||||
If distribution of executable or object code is made by offering
|
||||
access to copy from a designated place, then offering equivalent
|
||||
access to copy the source code from the same place counts as
|
||||
distribution of the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
4. You may not copy, modify, sublicense, or distribute the Program
|
||||
except as expressly provided under this License. Any attempt
|
||||
otherwise to copy, modify, sublicense or distribute the Program is
|
||||
void, and will automatically terminate your rights under this License.
|
||||
However, parties who have received copies, or rights, from you under
|
||||
this License will not have their licenses terminated so long as such
|
||||
parties remain in full compliance.
|
||||
|
||||
5. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Program or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Program (or any work based on the
|
||||
Program), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Program or works based on it.
|
||||
|
||||
6. Each time you redistribute the Program (or any work based on the
|
||||
Program), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute or modify the Program subject to
|
||||
these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties to
|
||||
this License.
|
||||
|
||||
7. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Program at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Program by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Program.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under
|
||||
any particular circumstance, the balance of the section is intended to
|
||||
apply and the section as a whole is intended to apply in other
|
||||
circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system, which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
8. If the distribution and/or use of the Program is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Program under this License
|
||||
may add an explicit geographical distribution limitation excluding
|
||||
those countries, so that distribution is permitted only in or among
|
||||
countries not thus excluded. In such case, this License incorporates
|
||||
the limitation as if written in the body of this License.
|
||||
|
||||
9. The Free Software Foundation may publish revised and/or new versions
|
||||
of the General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Program
|
||||
specifies a version number of this License which applies to it and "any
|
||||
later version", you have the option of following the terms and conditions
|
||||
either of that version or of any later version published by the Free
|
||||
Software Foundation. If the Program does not specify a version number of
|
||||
this License, you may choose any version ever published by the Free Software
|
||||
Foundation.
|
||||
|
||||
10. If you wish to incorporate parts of the Program into other free
|
||||
programs whose distribution conditions are different, write to the author
|
||||
to ask for permission. For software which is copyrighted by the Free
|
||||
Software Foundation, write to the Free Software Foundation; we sometimes
|
||||
make exceptions for this. Our decision will be guided by the two goals
|
||||
of preserving the free status of all derivatives of our free software and
|
||||
of promoting the sharing and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
||||
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
||||
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
||||
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
||||
REPAIR OR CORRECTION.
|
||||
|
||||
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
||||
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
||||
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
|
||||
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
|
||||
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
||||
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
convey the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program is interactive, make it output a short notice like this
|
||||
when it starts in an interactive mode:
|
||||
|
||||
Gnomovision version 69, Copyright (C) year name of author
|
||||
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, the commands you use may
|
||||
be called something other than `show w' and `show c'; they could even be
|
||||
mouse-clicks or menu items--whatever suits your program.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the program, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
|
||||
`Gnomovision' (which makes passes at compilers) written by James Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1989
|
||||
Ty Coon, President of Vice
|
||||
|
||||
This General Public License does not permit incorporating your program into
|
||||
proprietary programs. If your program is a subroutine library, you may
|
||||
consider it more useful to permit linking proprietary applications with the
|
||||
library. If this is what you want to do, use the GNU Lesser General
|
||||
Public License instead of this License.
|
||||
@@ -0,0 +1,875 @@
|
||||
0.9.10 -> 0.9.11 (r4908-r5146)
|
||||
|
||||
In this version, we have focused on the Cocoa frontend, but there have been some good core fixes over so long.
|
||||
Notably, the save-related issues resulting in the advice "dont use 0.9.10" have been resolved.
|
||||
|
||||
General/Core:
|
||||
bug: fix large numbers of games not being able to save anymore
|
||||
bug: fix some missing sound effects due to wrong volumes in some boot scenarios and other things
|
||||
bug: fix freezes due to tiny looping sounds
|
||||
bug: fix many big endian issues
|
||||
bug: fix some apparently rarely-used CPU instructions, no known consequences
|
||||
bug: fix (block) reading of some GPU registers
|
||||
bug: fix action replay code type 0xE
|
||||
bug: fix reading of last 4 bytes of rom
|
||||
bug: large improvements to stability of GDB stub
|
||||
bug: support w-buffer support in OpenGL renderers
|
||||
bug: fix unpredictable crashes in some 3d scenes from w=0
|
||||
enh: better loading of roms (bad patches) with wrong size info in header
|
||||
enh: warn user sometimes when 'stream rom from disk' will create malfunctions
|
||||
enh: add xBRZ filters
|
||||
enh: add "TXT Hack" for software rasterizer to improve text rendering in some games
|
||||
|
||||
Windows:
|
||||
bug: fix 5x filters
|
||||
enh: support import of action replay save files (.dss)
|
||||
enh: add antialiasing option for OpenGL renderers
|
||||
enh: don't malfunction if saveram is unavailable or read-only
|
||||
|
||||
Cocoa:
|
||||
bug: 16-bit to 32-bit color space conversions no longer darken video or images
|
||||
bug: fix intermittent issues with loading user defaults on app startup
|
||||
bug: fix rendering inaccuracies of the video preview in the app display preferences
|
||||
bug: fix various UI font rendering and text alignment issues on OS X Yosemite
|
||||
bug: fix crackly sound from N-sync and Z-sync methods
|
||||
enh: make N-sync method the default sound sync method since it has much lower latency than P-sync method
|
||||
enh: add support for gdbstub (Tools > Show GDB Stub Control) (only available on custom builds using the dev+ build target)
|
||||
enh: optimize input handling to use less CPU
|
||||
enh: add support for App Nap when the app is in an idle state (only supported on OS X Mavericks and later)
|
||||
enh: add Execution Control panel (Emulation > Show Execution Control), now with frame advance and frame jump controls
|
||||
enh: auto frame skip is now smoother
|
||||
enh: further improve execution timing accuracy
|
||||
enh: improve overall video performance
|
||||
enh: render video through a 3-stage filtering pipeline, (Video Source)-->(Pixel Scaler)-->(Video Output)
|
||||
enh: add the following video source filters - Deposterize
|
||||
enh: add the following video output filters - Bicubic B-Spline, Bicubic Mitchell-Netravali, Lanczos2, Lanczos3
|
||||
enh: add ability to run all existing pixel scalers on either the CPU or the GPU
|
||||
enh: add ability to toggle the main and touch display positions (View > Toggle All Displays)
|
||||
enh: add preliminary support for replay playback and recording
|
||||
enh: add support for turbo and autohold
|
||||
enh: add support for the entire suite of slot-2 devices (Emulation > Show SLOT-2 Manager)
|
||||
enh: add support for using the host machine's audio input device for emulating the NDS microphone (Emulation > Show Microphone Settings)
|
||||
enh: change the sine wave tone generator's range from 100Hz-5000Hz to 40Hz-4000Hz
|
||||
enh: reorganize the menu options to more logical locations
|
||||
enh: greatly improve the File Migration Assistant (now renamed Game Data Migration Assistant) and ROM Info panel with a more modern and space efficient look and feel
|
||||
enh: miscellaneous user interface improvements
|
||||
|
||||
Linux:
|
||||
bug: fix screen gap bug
|
||||
bug: workaround for std::bad_alloc exceptions compiler bugs
|
||||
enh: add experimental AV recording
|
||||
enh: generally improve main loop throttling and skipping
|
||||
enh: massive improvements to HUD and menu layout
|
||||
enh: add window sizing options and sound interpolation options
|
||||
enh: add Lid button; disallow U+D, L+R; manual option saving
|
||||
|
||||
0.9.9 -> 0.9.10 (r4623-r4908)
|
||||
|
||||
In this version, we have focused on trying to clean up some complexities in the user experience and emulator internals. Pretty unglamorous stuff, but some games are newly compatible.
|
||||
|
||||
General/Core:
|
||||
enh: break savestate back-compatibility
|
||||
bug: improve save size autodetection for some games
|
||||
bug: cpu: fix many basic jit cpu bugs
|
||||
bug: 3d: tweak softrasterizer edge marking
|
||||
bug: 3d: fix stale 4x4 texture palettes
|
||||
bug: fix some GPU sprite blending scenarios
|
||||
bug: fix bios HLE BitUnPack, UnCompHuffman
|
||||
enh: modular slot-1 device system, emulate GC bus more faithfully
|
||||
enh: support NAND slot-1 device
|
||||
enh: auto-detect appropriate slot-1 and slot-2 device
|
||||
enh: many revisions to firmware boot process for more authenticity. iQue and FlashME versions function, .dfc rewritten.
|
||||
enh: support streaming NDS file from disk (like an ISO, to avoid long initial load time)
|
||||
enh: run .dsv directly on disk, to save long flushing times. should speed backup operations.
|
||||
enh: spu synch mode and method on commandline
|
||||
|
||||
Windows:
|
||||
bug: fixes to advanscene DB import
|
||||
bug: save opengl display method filter option
|
||||
bug: general bugfixes to various screen layout modes
|
||||
enh: add option to stop non-integer scaling during fullscreen or maximize
|
||||
enh: improvements to save import dialog
|
||||
enh: improved memory viewer tool
|
||||
enh: operate better when run, against our advice, from a zipfile
|
||||
enh: add slot-1 Nitro Filesystem viewer tool
|
||||
|
||||
Cocoa:
|
||||
bug: fix slot1-R4 path saving
|
||||
bug: fix bug with mic samples < 16khz
|
||||
bug: fix bugs and enhancements in multi display windows
|
||||
bug: fix handling of some joystick analog inputs
|
||||
enh: save display windows configuration and emulation speed on app exit
|
||||
|
||||
0.9.8 -> 0.9.9 (r4228-r4623)
|
||||
|
||||
Yes, it's been a while since the last release, but we haven't been completely idle. There's a brand new jit cpu core which yields some impressive speedups!
|
||||
|
||||
General/Core:
|
||||
!!!: add optional arm cpu jit (functioning on x86 and x64 hosts only)
|
||||
bug: we're not going to list 70% of the emulation fixes, as is traditional.
|
||||
bug: savestate reliability fixes related to halt states, gxstat, firmware
|
||||
bug: lua: fix readbyterange, gdscreenshot functions
|
||||
bug: commandline slot-1 handling straightened out
|
||||
enh: fixes and additions to resize filter options
|
||||
|
||||
Graphics:
|
||||
enh: opengl 3d driver compatibility improvements
|
||||
bug: fix giant regression from 0.9.7 that left garbage from previous frames on the screen in some games
|
||||
bug: 3d: fix some single poly pixels
|
||||
bug: 3d: fix some polygon and texture coloring bugs on big-endian systems
|
||||
|
||||
Windows:
|
||||
bug: fix some full screen stretching bugs
|
||||
enh: add xaudio2 output driver
|
||||
enh: add opengl display method (as opposed to directdraw), with controllable bilinear filter
|
||||
enh: upgrade archive handling system, lzma2 supported
|
||||
enh: reorganize main menu quite a bit
|
||||
enh: add rotation hotkeys, and hotkey to control mouse cursor visibility
|
||||
enh: memory viewer improvements and fixes
|
||||
enh: improve interface for rom eject to prevent accidents and improve usefulness (hide in slot-1 config screen)
|
||||
|
||||
Cocoa:
|
||||
bug: fix missing display when running on OS X v10.8 Mountain Lion
|
||||
bug: fix possible sound crash when using Dual SPU Synch/Asynch
|
||||
bug: fix File menu items being disabled after the file migration sheet is used
|
||||
bug: fix window resizing issues
|
||||
bug: fix text rendering in About box
|
||||
enh: show the icon and name of the loaded ROM
|
||||
enh: add Support Request and Bug Report forms to the Help menu
|
||||
enh: add more detailed info to the About box
|
||||
enh: add OpenGL as a 3D rendering option
|
||||
enh: add support for MSAA when using OpenGL as the 3D rendering engine
|
||||
enh: add V-Sync option
|
||||
enh: add Display Orientation, Display Order, and Display Separation options for Combo Display mode
|
||||
enh: add HQ4xS filter
|
||||
enh: completely revamp the user interface for Input Preferences
|
||||
enh: many emulator commands may now be mapped
|
||||
enh: add ability to map an input to user-defined touch screen coordinates
|
||||
enh: add support for saving and applying input profiles
|
||||
enh: add support for using an audio file for the microphone input
|
||||
enh: add sine wave tone generator for microphone input
|
||||
enh: add support for multiple display windows (File > New Display Window)
|
||||
enh: add support for SLOT-1 devices (Emulation > Show SLOT-1 Manager)
|
||||
enh: overall performance and stability improvements
|
||||
enh: miscellaneous user interface improvements
|
||||
|
||||
0.9.7 -> 0.9.8 (r3812-r4228)
|
||||
|
||||
Yes, it's been a while since the last release, but we haven't been completely idle. There's a brand new top shelf Cocoa frontend to make life far more pleasant for OSX users, and a host of compatibility fixes.
|
||||
|
||||
General/Core:
|
||||
bug: fix more IPC FIFO errors
|
||||
bug: import more save files correctly
|
||||
bug: don't autopatch already-patched roms
|
||||
bug: fix bugs in piano and guitar grip
|
||||
bug: fix ARM7's VRAMSTAT register
|
||||
bug: fix memory leaks on compact flash emulation
|
||||
bug: fix reading of rom from low header area
|
||||
bug: spu: fix some poppy interpolation audio quality issues
|
||||
bug: improve timing of dma operations by running through normal mem cycle accounting; fixes an annoying number of games and graphical glitches
|
||||
bug: fix opcode MRC and fake bios CRC16
|
||||
enh: jitter some related register and irq events to simulate pipeline effects and stimulate some race conditions to other outcomes
|
||||
enh: fake (deterministic) some tiny jitter from human's hand holding stylus; some games were accidentally depending on this
|
||||
enh: support nocash-style prints from arm
|
||||
enh: add lua apis for accessing vram
|
||||
enh: platforms other than windows receive threading optimizations
|
||||
enh: provide diagnostics when system powers off (useful for homebrewers returning from main())
|
||||
enh: clarify handling of different console types within the family (ds,dslite,debug)
|
||||
enh: vfat support for slot-1 devices
|
||||
enh: emulate temperature register
|
||||
enh: add paddle emulation
|
||||
|
||||
Graphics:
|
||||
bug: fix occasional crash from uninitialized blending table
|
||||
bug: fix some 2d alpha blending cases resulting in white screens
|
||||
bug: fix VRAM_I B_OBJ mirroring and fix sprites rendering across the end of vram
|
||||
bug: fix rotoscaled sprites wrapping around screen
|
||||
bug: dont fix rotscaled bitmap sprites with alpha==0
|
||||
bug: opengl: fix degradation of toon rendering during loadstate
|
||||
bug: opengl: alpha blending fixes
|
||||
bug: many refinements to opengl renderer
|
||||
bug: opengl: support rear-plane/ClearImage emulation (fixes many graphics)
|
||||
bug: rasterizer: fix some rare alpha blending cases
|
||||
bug: fix bug in environment mapping introduced after 0.9.6
|
||||
bug: fix totally glitched out 3d graphics with several improvements involving matrix stack
|
||||
bug: fix memory overflows in epx filter
|
||||
bug: prevent backdrop from blending with ???
|
||||
enh: opengl: better depth buffering emulation
|
||||
enh: better support for line segment "polys" by detection and special rendering logic
|
||||
enh: opengl: support quad primitives directly
|
||||
enh: add hq4x filter
|
||||
|
||||
Windows:
|
||||
bug: fix a long-standing loadstate crash
|
||||
bug: fix lag frame accounting
|
||||
bug: fix glitches in cheat entry menu
|
||||
bug: stop compact flash emulation from accidentally scanning c:\ sometimes
|
||||
enh: add support for game database for improved save type detection
|
||||
enh: hotkey for limit framerate toggle
|
||||
enh: remove stop and reset toolbar buttons which were accidentally getting used
|
||||
enh: additional complexification to desmume's behaviour run from a console prompt. whether it's better is uncertain.
|
||||
enh: add support for cheats databases
|
||||
enh: improvements to ram search tool
|
||||
enh: preliminary support for varying stylus pressure
|
||||
enh: add [Display] Show Console=1 to ini file
|
||||
enh: more graceful cheat parsing and add some hotkeys
|
||||
enh: add 5x window size
|
||||
enh: add big endian and 20.12 toggle to memview and ramwatch
|
||||
enh: improve FPS throttle feedback and granularity
|
||||
enh: add lua menu API
|
||||
enh: hud font switching
|
||||
enh: add optional file association for .nds to path config dialog
|
||||
|
||||
Cocoa:
|
||||
enh: Big update to cocoa frontend. Pretty much entirely new. (rogerman)
|
||||
|
||||
Linux:
|
||||
bug: gtk: glitches in rom and recent rom loading
|
||||
bug: glade: normalize savestate slot to hotkey mapping
|
||||
enh: support soundtouch for use by metaspu
|
||||
enh: gtk: add SPU mode selection (Tobias Jakobi)
|
||||
enh: cli: better fps limiting (Thomas Jones)
|
||||
|
||||
Wx:
|
||||
bug: some small fixes here and there (Jan Bücken)
|
||||
enh: lot of code cleanup (Jan Bücken)
|
||||
|
||||
0.9.6 -> 0.9.7 (r3493-r3812)
|
||||
|
||||
General/Core:
|
||||
bug: fix a ton of old, broken cpu opcodes and CP15 logic
|
||||
bug: return Z1 and Z2 from TSC (fixes some touch logic)
|
||||
bug: gba slot save type detection improved
|
||||
bug: handle unusual rom headers more correctly
|
||||
bug: dont confuse motion pack commands with save memory commands
|
||||
bug: make cheat system a little less flaky and add AR 1.54 support
|
||||
bug: fix nondeterministic backup memory behaviour while rerecording
|
||||
bug: correct emulation of register accesses of wrong size and during powerdown
|
||||
bug: rewrite --cflash-path emulation
|
||||
bug: rewrite IPC/GX FIFO, IRQ flag generation, and wait-for-IRQ logics
|
||||
bug: rewrite RTC calendar handling; now supports years > 2038
|
||||
enh: auto-DLDI patching for homebrew
|
||||
enh: --gbaslot-rom=self mounts self.nds in slot2
|
||||
enh: more realistic exception handling
|
||||
enh: piano controller emulation
|
||||
enh: modular slot-1 system for exact emulation of homebrew cards
|
||||
|
||||
Graphics:
|
||||
bug: edge marking colors were wrong
|
||||
bug: handle some "invalid" vram configurations correctly
|
||||
bug: convert half of geometry engine to fixed point
|
||||
bug: fix sprite blend+fadein/fadeout
|
||||
bug: improve rasterizer shadows
|
||||
bug: fix main memory display DMA
|
||||
bug: fix some raster fx timing bugs
|
||||
enh: add a hack for improving some non-stencil shadows
|
||||
|
||||
Windows:
|
||||
bug: misc fixes and improvements to gpu viewer tools
|
||||
bug: sub screen layer display toggling fixed
|
||||
bug: fixes and improvements to ram watch, ram search, cheats list
|
||||
bug: fix start-paused commandline
|
||||
bug: fix memory leaks when sound disabled
|
||||
bug: improve load average calculators and add arm7 load average
|
||||
enh: background input support
|
||||
enh: add vsync option
|
||||
enh: support more knobs on joysticks
|
||||
enh: import cheats from R4 database
|
||||
enh: add xinput rumble for 360 pads
|
||||
|
||||
Linux/OSX:
|
||||
bug: crash less in recent roms list
|
||||
enh: Add horizontal screen layout and swap screen ability to gtk frontend (noodlebox)
|
||||
enh: Big improvement to joystick support, support complex configurations and multiple devices (noodlebox)
|
||||
|
||||
|
||||
0.9.5 -> 0.9.6 (r3075-r3493)
|
||||
|
||||
Users of gtk, cli and gtk-glade frontends please note that now we
|
||||
have a common directory in ~/.config/desmume for config file,
|
||||
saves and savestates. The old .desmume.ini will be moved
|
||||
automatically with the name config but you have to move your saves
|
||||
manually.
|
||||
|
||||
Some save files may be invalidated due to use of broken crc logic.
|
||||
Back up your DSV files before using this version of the emulator or else
|
||||
the game might wipe it.
|
||||
|
||||
General/Core:
|
||||
bug: emulate keypad interrupt
|
||||
bug: spu overhaul, add capture support
|
||||
bug: fix dma address reloading
|
||||
bug: fix rom close memory corruption
|
||||
bug: fix div and sqrt busy flag bug
|
||||
bug: fix vectest
|
||||
bug: fix lid savestate desync
|
||||
bug: fix texcache memory GB explosion when games use tons of tiny 3d sprites
|
||||
bug: fix huge rerecording movie file handle leak
|
||||
bug: fix EXXXXXXX cheat codes and some add/edit/save/load bugs
|
||||
bug: add 8MBit - 512MBit flash emulation
|
||||
bug: fix firmware booted-from-card flag
|
||||
bug: fix some failures to wake
|
||||
bug: fix some rtc calendar logic
|
||||
bug: op_bkpt emulation
|
||||
bug: correctly emulate POWCNT1 and POWCNT2 and SPI power device
|
||||
bug: corrections to bootup stack configuration
|
||||
bug: protect bios from being overwritten
|
||||
bug: initialize save data to 0xFF instead of 0x00
|
||||
bug: handle relocated irq vectors
|
||||
bug: support patched firmwares
|
||||
bug: handle 8bit auxspidata, 32bit BLDY, 32bit div regs
|
||||
bug: fix some divide by zero cases
|
||||
bug: don't print \n in ideas debug message
|
||||
bug: don't let games read off end of cart and crash emulator
|
||||
bug: fix SWI 0x0E crc16 ; some save files using wrong crc may be invalidated
|
||||
bug: fix many big endian bugs
|
||||
bug: fix CPSR.I idle wakeup
|
||||
bug: fix loadstate crashes, mostly when sound is enabled
|
||||
enh: support devkitpro argv
|
||||
enh: add gbaslot-rom commandline
|
||||
enh: add no$gba debug message
|
||||
enh: add rtc start to dsm header
|
||||
|
||||
Graphics:
|
||||
bug: fix a mistakenly rendered OBJ window and 3d blend effects
|
||||
bug: fixes to matrix stacks, fixing lots of garbled geometry
|
||||
bug: fix fog density registers
|
||||
bug: fix hblank dma to run also on scanline 262
|
||||
bug: fix w/z depth flags for broken GUIs in dual screen 3d games
|
||||
bug: fixes to poly sorting
|
||||
bug: block 8bit vram writes
|
||||
enh: improve accuracy of opengl shaders
|
||||
|
||||
Windows:
|
||||
bug: fix 16bpp display
|
||||
bug: more fixes to multi-gamepads
|
||||
bug: cheat windows robustification
|
||||
bug: fix that sticky pause state when resetting and loading roms
|
||||
bug: dont crash when no sound device is available
|
||||
bug: change F10 to be save slot 0
|
||||
bug: fix --start-paused
|
||||
enh: try not to screensave while using gamepad
|
||||
enh: add EPX and EPX1.5X resize filters
|
||||
enh: add a japanese translation which will soon be stale like the others
|
||||
enh: add fancy ctrl+printscreen with emulator info on it
|
||||
enh: add "lockdown" window mode to keep window safe from fast stylus action
|
||||
enh: add alt+enter fullscreen command
|
||||
enh: add card eject command
|
||||
enh: add ddraw software mode forcer
|
||||
enh: improve oam viewer
|
||||
enh: default 3d to rasterizer so we dont have to suggest it 1000 times a day
|
||||
enh: add dump-all-memory tool
|
||||
enh: add reload rom menu/hotkey
|
||||
|
||||
Linux/OSX:
|
||||
bug: fix building for nosse2 systems
|
||||
bug: fix --num-cores
|
||||
bug: fix occasional touchscreen failures
|
||||
bug: fix crash starting dsm record
|
||||
enh: add --nojoy=1 to fix laptops with accelerometers
|
||||
enh: add simple auto frameskip mode in the gtk frontend
|
||||
enh: add gui for configuring joystick in the gtk frontend
|
||||
enh: make the cli frontend read the ini config file too
|
||||
enh: additional OpenAL microphone backend (ncalexan)
|
||||
enh: common place for config and saves (Jan Steffens)
|
||||
enh: libagg is now optional if you don't need the hud
|
||||
|
||||
0.9.4 -> 0.9.5 (r2437-r3075)
|
||||
|
||||
0.9.5 introduces an entirely rewritten main emulation loop
|
||||
This totally changes the timing, and totally breaks old savestates.
|
||||
The OSX build is now based on the GTK port which is more up-to-date.
|
||||
|
||||
Assorted Highlights:
|
||||
* synchronous SPU mode to fix streaming sounds
|
||||
* win32: lua engine, path configuration, 7z dearchiving support
|
||||
|
||||
General/Core:
|
||||
bug: rewrite main emulation loop and cycle accounting, fixes a lot of timings
|
||||
bug: add more detailed timing emulation, removes much bogus lag
|
||||
bug: rewrite DMA,gxfifo,gxstat; fix many games and no more alternate flush mode
|
||||
bug: fix cflash directory support for non-windows and sector-writing
|
||||
bug: fix freeze in cart irq
|
||||
bug: correctly emulate dma to/from tcm
|
||||
bug: fix in thumb LSR carryflag
|
||||
bug: fix thumb BX PC switch to arm state
|
||||
bug: fix adpcm looping, remove adpcm caching (no longer necessary)
|
||||
bug: fixes to swi 3,4,5,8,0x10
|
||||
bug: fixes to exmemstat and ipc sync registers
|
||||
bug: support new backup commands
|
||||
bug: improve bootup bios/firmware emulation steps
|
||||
enh: gbaslot: add guitar grip, gbagame flash support, expansion memory pak
|
||||
enh: add more powerful antigrain-based drawing library and rewrite OSD system
|
||||
enh: ideas-style debugging prints
|
||||
enh: most optimizations now SSE instead of SSE2
|
||||
enh: more improvements to frameskipping and frame advance/speed controls
|
||||
|
||||
Graphics:
|
||||
bug: fix backdrop blending with garbage
|
||||
bug: fix 256B granularity sprite addressing for sub gpu
|
||||
bug: fix obj blending, bmp obj rendering, and some obj window cases
|
||||
bug: fix 128-wide captures
|
||||
bug: fix 16color BG line buffer overflow
|
||||
bug: fix color overflow in capture blending
|
||||
bug: fix disp fifo capture
|
||||
bug: fix simultaneous vram display and capture via same bank
|
||||
bug: fix 3d overflow acknowledge registers
|
||||
bug: fix 32bit toon table writes
|
||||
bug: change 3d cores to use 18bit color
|
||||
bug: fix boxtest (addition overflow!), move clipper to main graphics engine
|
||||
bug: fix failure in some cases of polygon clipping
|
||||
bug: fix disp3dcnt emulations
|
||||
bug: fixes to poly sorting
|
||||
bug: fix ogl renderer wireframe support
|
||||
bug: swrast: fix backface culling of nonconvex polys
|
||||
bug: swrast: add clear image and scroll emulation
|
||||
bug: swrast: add fog emulation
|
||||
bug: swrast: fixes to shadow rendering
|
||||
bug: swrast: preliminary edge marking, works decent
|
||||
enh: swrast: multicore optimization for a few fps speedup
|
||||
|
||||
Windows:
|
||||
bug: fix support for multiple gamepads and gamepad hotkeys
|
||||
bug: fix mic noise code and load wav instead of raw; effective in more cases
|
||||
bug: fix for several sticky and broken hotkeys, and f10 hotkeys
|
||||
bug: fixes in ram search, add DTCM and ITCM searching, ...
|
||||
bug: fix sound settings vol slider
|
||||
bug: recover from missing window -32000 problem
|
||||
bug: don't turn on mic unless mic input is enabled
|
||||
enh: x64 build type now supported
|
||||
enh: side-by-side and single screen view modes, many fixes to window resizing
|
||||
enh: choose any gap size by dragging bottom window edge (must be enabled)
|
||||
enh: choose a gap color
|
||||
enh: import/export no$GBA savefiles directly
|
||||
enh: multicore optimization for filters, rotation, OSD
|
||||
enh: soundview can now mute channels
|
||||
enh: new ioregview
|
||||
enh: common commandline system, many arguments shared with linux
|
||||
enh: improve map view tool to support more modes
|
||||
enh: add "FORCE AS CURRENT" recovery tool for mis-sized savefiles
|
||||
enh: add some kind of very small savestate rewinding buffer
|
||||
enh: autoframeskip works better
|
||||
enh: add Italian translation
|
||||
enh: added 2x resizing filters (hq2x, hq2xs, lq2x, lq2xs, 2xsai, supereagle)
|
||||
(scanlines, nearest2x, bilinear)
|
||||
|
||||
Linux:
|
||||
enh: alsa microphone support
|
||||
enh: hud and osd notification for gtk and cli frontends
|
||||
enh: add support for the SSE optimizations
|
||||
|
||||
0.9.2 -> 0.9.4 (r1844->r2352->r2437)
|
||||
|
||||
0.9.3 was skipped due to emu news sites sneaking it out of our staging area and
|
||||
releasing it prematurely while it still had bugs. I was going to curse them
|
||||
individually, but then I decided that they would just like the publicity.
|
||||
|
||||
Highlights:
|
||||
* New save autodetection and save file format
|
||||
* Full rerecording support
|
||||
|
||||
General/Core:
|
||||
bug: fix many 64 bit and endian issues
|
||||
bug: fix mic input, which was nearly useless before
|
||||
bug: fix failures of large dmas
|
||||
bug: fix in ipc sync which broke devkitpro touch
|
||||
bug: screenshots now exclude hud and rotation
|
||||
bug: rewritten vram mapping (fixes corrupted or missing BG)
|
||||
enh: add universal commandline system (same commandline options on every port)
|
||||
enh: cheats: added Action Replay code parser
|
||||
enh: more reliable and useful frameskipping
|
||||
enh: SPU: speedup: add adpcm caching
|
||||
enh: SPU: speedup: interpolation is now optional
|
||||
enh: print svn build number so we can identify people's svn builds from screenshots
|
||||
|
||||
Graphics:
|
||||
bug: add polygon y-sorting (fixes 3d guis)
|
||||
bug: fix texcoordgen mode 3; fixes some ortho sprites and some entirely broken games
|
||||
bug: display capture fixes
|
||||
bug: fix a number of OBJ modes
|
||||
bug: fixes to affine BG modes
|
||||
bug: better emulate some translucent OBJ
|
||||
bug: more correct handling of color effect windows and backdrop colors
|
||||
bug: fix matrix stack overrun which crashed emulator
|
||||
bug: swrast: add clear depth image emulation and other fixes to depth buffering
|
||||
bug: swrast: fix some toon and highlight cases
|
||||
bug: fix bug in matrix stack, fixes some broken models
|
||||
enh: add alternate flush mode HACK 3d config toggle, fixes some entirely broken 3d games
|
||||
|
||||
Windows:
|
||||
bug: more robust cheats engine and dialog
|
||||
enh: more solid avi and wav recording
|
||||
enh: improved tools: memory viewer
|
||||
enh: added tools: spu viewer, ram watch, ram search
|
||||
enh: change build configuration system
|
||||
enh: speedup: add gpu core disabling to hide useless screens
|
||||
enh: add background pause feature (for when emulator loses focus)
|
||||
enh: add missing autohold for L and R
|
||||
enh: add chinese translation
|
||||
|
||||
Gtk frontend:
|
||||
enh: switch all of menu/toolbar system to GtkAction + GtkUIManager
|
||||
enh: remove the gtglext 3d code
|
||||
enh: improve/speedup screen resize and final presentation logic in gtk frontend
|
||||
enh: minimal rerecording hookups
|
||||
|
||||
Cli frontend:
|
||||
enh: hooked the frameskip (szigor)
|
||||
enh: misc usability improvements: auto pause switch for pausing when focus is lost and exit on escape pressing (szigor)
|
||||
enh: hook the fake noise mic; use m to toggle
|
||||
|
||||
0.9.1 -> 0.9.2
|
||||
General/Core:
|
||||
bug: fix error in SBCS/RSCS flags; fixes many odd behaviors and crashes [zeromus]
|
||||
bug: add support for sleep mode and power registers [luigi__]
|
||||
bug: important fixes to RTC so correct time is actually told [luigi__]
|
||||
bug: fix card reads below 0x8000; fixes some game freezes [normatt]
|
||||
bug: fix 4 mbit save type; fix non-autodetect savefile dumping [zeromus, matusz]
|
||||
enh: add sram to GBA game addon emulation for importing savefiles [zeromus]
|
||||
enh: many improvements and feature hookups in linux ports [matusz, luigi__]
|
||||
|
||||
Graphics:
|
||||
bug: fix specular texture mapping mode [luigi__]
|
||||
bug: repairs to some capture modes and vram mapping [zeromus, CrazyMax]
|
||||
bug: viewports finally correctly handled [zeromus]
|
||||
enh: add software rasterizer. quirky, but on par with opengl [zeromus]
|
||||
|
||||
Windows:
|
||||
bug: mitigate bad frameskipper; default to old frameskipping mode [zeromus]
|
||||
bug: fixes with recent roms and zipfile loading [zeromus]
|
||||
bug: fix window position memory [zeromus]
|
||||
enh: bios and firmware may now be used and booted [luigi__]
|
||||
enh: many display, OSD, and input enhancements [luigi__]
|
||||
enh: brand new hotkey and controls binding system [zeromus]
|
||||
enh: configurable screen separation [luigi__]
|
||||
enh: fast forward key [pa__]
|
||||
enh: improvements to mic [luigi__]
|
||||
enh: faster updates in debug tools, up to once per frame [pa__]
|
||||
|
||||
Mac OS X Port:
|
||||
enh: added Italian translation thanks to Paolo Bernini [jeff]
|
||||
enh: resurrection of GDB stub [sigmaris]
|
||||
|
||||
0.9 -> 0.9.1
|
||||
General/Core:
|
||||
enh: GBA slot emulation [CrazyMax]
|
||||
- Rumble support (windows only)
|
||||
- GBA game
|
||||
enh: Mic support (windows only?) [luigi__]
|
||||
enh: Preliminary cheats system [CrazyMax]
|
||||
enh: Savestates invalidated, as more variables have been added.
|
||||
bug: Added PSG white noise [luigi__]
|
||||
bug: fix arm/thumb ROR [zeromus]
|
||||
bug: [ 2550645 ] Super Princess Peach: crash when starting a puzzle [zeromus]
|
||||
bug: win32: fix spu wav file writer (regression from 0.8) [zeromus,luigi__]
|
||||
bug: Much work on FIFOs, still not finished [CrazyMax]
|
||||
bug: Many fixes to dma [zeromus, CrazyMax]
|
||||
bug: bios WaitForVblank and WaitForInterrupt fixed [luigi__]
|
||||
|
||||
Graphics:
|
||||
bug: Added sprite blending [luigi__]
|
||||
bug: more correct mosaic effects, still imperfect [zeromus]
|
||||
bug: Many fixes to tile rendering; all graphics tests now pass [luigi__]
|
||||
bug: fix crashes in some affine BG [zeromus]
|
||||
bug: Implement some pos test function [luigi__]
|
||||
bug: fix texture mapping across texture and palette banks and to unmapped banks [zeromus]
|
||||
bug: fix texture handling for texels with MSB set (fixes some texture corruption) [zeromus]
|
||||
bug: fix texture coordinate generation, including environment mapping [zeromus]
|
||||
bug: texture cache invalidates when palettes change, prevents some texture corruption [zeromus]
|
||||
bug: fix display capturing from 2d+3d source when display mode is display-vram [zeromus]
|
||||
bug: [ 2488334 ].1 fixes to layer compositing [luigi__]
|
||||
bug: [ 2488334 ].3 fix bug in support for hdma affine bg parameters [zeromus]
|
||||
bug: Improvements to 3d h-scrolling [luigi__]
|
||||
bug: Fix some errors in rendering 512 tall BG [zeromus,CrazyMax] (still not fully resolved)
|
||||
bug: Add optional fragment shading pipeline (more precision) [luigi__]
|
||||
bug: Fix bug where some sprites got cut of on x=255 [zeromus]
|
||||
bug: Implement GXSTAT register [CrazyMax]
|
||||
|
||||
Windows:
|
||||
bug: resizing and rotating work in vista [luigi__]
|
||||
enh: 0 frameskip now lets emulator run at excess speed [zeromus]
|
||||
|
||||
Mac OS X Port:
|
||||
bug: left key setting no longer gets confused with the right key [jeff]
|
||||
enh: more keys can be mapped
|
||||
|
||||
0.8 -> 0.9
|
||||
There have been so many changes that this list can hardly be considered complete.
|
||||
For this release, we have formatted the list into a high level overview of big changes and bad bugs relative to the previous release. Hopefully what you're interested in.
|
||||
This list does not include items which are solely performance boosts, for let us just say that virtually every system has been speeded up.
|
||||
|
||||
* The savestate system is totally changed and incompatible with old savestates.
|
||||
* The 3d system should be considered rewritten.
|
||||
|
||||
General/Core:
|
||||
enh: Convert to c++
|
||||
enh: Add functions for a lid open/close. Holding key (default "Backspace" in Windows port) while game is freeze/non freeze. [CrazyMax]
|
||||
enh: Add secure area decryption from ndstool [zeromus]
|
||||
enh: Change savestate code to support loosely bound chunks and more easily other parts of the emu (GE, GPU).
|
||||
The savestate format is changed, but from now on it is in principle more resilient
|
||||
(though it will continue to break as we tinker with the internals) [zeromus]
|
||||
enh: Added SSE2 optimizations for matrices. Since we now make an SSE2 build, more optimizations can be made. [CrazyMax]
|
||||
enh: Add a preliminary GUI hud system [CrazyMax,zeromus]
|
||||
|
||||
CPU/MMU:
|
||||
bug: Many fixes in IPC and GE FIFOs. Fixes freezes in NSMB, dsracing, and others. [CrazyMax,luigi__,shash]
|
||||
bug: Fix ARM instructions SBC and RSC (likewise SBC in thumb) [normatt]
|
||||
bug: Fixed Thumb LDMIA (fixes ingame Dead'n'Furious) [shash]
|
||||
bug: Fix repeating DMA (fixes NSMB parallax BG) [zeromus]
|
||||
bug: Proper handling for unaligned CPU accesses [luigi__]
|
||||
bug: Proper handling for undefined instruction exceptions [Salva Peiró]
|
||||
bug: correctly return vram control register values (fixes homebrew 3d games) [zeromus]
|
||||
enh: Remove 16MB of WRAM at 0x01****** from arm9. Mapped to unused instead. Nobody knows what this was. [zeromus]
|
||||
enh: Changed instruction execution to 16 at a time blocks (tested and stable) [shash]
|
||||
|
||||
Hardware:
|
||||
bug: Newer and better sqrt and div emulation; makes SM64DS playable [luigi__,shash,zeromus]
|
||||
bug: Add preliminary RTC implementations [CrazyMax]
|
||||
enh: Add cosine interpolation in the SPU (conditionally compiled) [zeromus,luigi__]
|
||||
enh: Experimental: always one silent non-mixing SPU core at 44.1khz synched with emu, for more precision.
|
||||
The audible core runs with the host, causing music to slow down but not tear or pitch bend. [zeromus]
|
||||
|
||||
Graphics:
|
||||
- Overhaul 3d:
|
||||
. Move entire GE to core emu.
|
||||
. Move OpenGL renderer to emu core for optional use by platforms, removing ogl_collector. Now every platform shares the same 3d code.
|
||||
. Reorganize 3d code to defer rendering to after 3d vblank. Eliminates tearing, and texturing artifacts. [zeromus]
|
||||
. Add optional fragment shading pipeline (more precision) [luigi__]
|
||||
. Move lighting model to software instead of using opengl's fixed function model [zeromus]
|
||||
. Render shadow volumes; toon shading and highlight table [zeromus, luigi__]
|
||||
. Added texture caching! big speed up. [CrazyMax]
|
||||
|
||||
bug: Many assorted tweaks and improvements to 3d and 2d precision [zeromus,CrazyMax,luigi__]
|
||||
bug: Fixes to GE: command unpacking, projection and pos-vector mode matrix handling, mult and load commands [zeromus]
|
||||
bug: Fix a bug in texture transformation mode 1 [zeromus]
|
||||
bug: Fixed GPU rendering bugs in sprites and BG [CrazyMax]
|
||||
bug: Fixes to texture conversion [CrazyMax,zeromus]
|
||||
bug: Fixes in capture display (no blinking in many games with dual 3D) [CrazyMax]
|
||||
bug: Fixes in master brightness (this fixes some games with black screens) [CrazyMax]
|
||||
bug: Fixes in screen, backdrop, and sprite blending [luigi__]
|
||||
bug: Changed clear depths and how depth initial values are calculated (fixes SM64DS skybox, Castlevania) [shash,lugi__]
|
||||
bug: Add 3d layer h-scrolling [zeromus]
|
||||
bug: Added transparency and fixed material alpha support and alpha testing on the 3D core [shash]
|
||||
bug: Rewrite VRAM mapping control and rendering (more accurate) [CrazyMax,luigi__]
|
||||
|
||||
bug: convert colors to opengl better to prevent alpha=31 polys from being ever so slightly transparent [zeromus]
|
||||
enh: Add MMU->GPU signal for when vram mappings change to function as a texture cache invalidate signal [zeromus]
|
||||
enh: Make matrix 4x4 multiply routines use W-coordinate; carry w coord through pipeline [zeromus]
|
||||
|
||||
Mac OS X port:
|
||||
bug: Fixed: Filenames and paths with unicode characters now work. [Jeff]
|
||||
bug: Fixed: Load state from file button works again. [Jeff]
|
||||
enh: Save State panel now pauses emulation while the file selection box is open. [Jeff]
|
||||
bug: Fixed: Frozen video output (and/or messed 3d emulation) after loading a state. [Jeff]
|
||||
bug: Added option to load the most recent file upon launching the program. [Jeff]
|
||||
enh: Added French translation (thanks to Pierre Rudloff). [Jeff]
|
||||
enh: Added basic key mapping configuration to application preferences (thanks to Julio GorgŽ). [Jeff]
|
||||
enh: Added keyboard shortcuts for Execute, Pause and Reset command (thanks to Julio GorgŽ). [Jeff]
|
||||
enh: Default key mappings are no longer case sensitive. [Jeff]
|
||||
enh: Added ability to limit speed. [Jeff]
|
||||
enh: Fixed: Video output should work on software-only 3D renderers. [Jeff]
|
||||
|
||||
Windows port:
|
||||
bug: Fix a race condition in NDS_3D_Reset and NDS_glInit [zeromus]
|
||||
bug: Fix the buggy auto frameskip logic which made the emu slow to a crawl. Now it runs fast! [zeromus]
|
||||
bug: Fix resizing, rotate & aspect ration of main window. [CrazyMax,_zeromus]
|
||||
bug: Remove multithreading from user interface after finding several synchronization issues [zeromus]
|
||||
enh: recent roms menu [luigi_]
|
||||
enh: Changed graphics render core to DirectDraw (work faster) [CrazyMax]
|
||||
enh: Add an arm9 cpu load average calculator similar to no$. but I dont think it works right. [zeromus]
|
||||
enh: Rewrite all debug tools (autoupdate works now) [CrazyMax]
|
||||
enh: Rewrite input core & replace config input dialog [CrazyMax]
|
||||
enh: Add AVI output [zeromus]
|
||||
enh: Add pause toggle and frame advance hotkeys [adelikat]
|
||||
enh: Add frame counter display and hud messages framework [adelikat]
|
||||
enh: Main window remembers position, size, and a few other emu preferences [adelikat]
|
||||
enh: Removed directx sdk dependency for easier building. [zeromus]
|
||||
enh: Savestate doesnt unpause emu if it is already paused [adelikat]
|
||||
|
||||
0.7.3 -> 0.8
|
||||
Cocoa:
|
||||
- Save State As function now works. [Jeff B]
|
||||
- Recent Items menu now works. [Jeff B]
|
||||
- Opening NDS files from Finder now works. [Jeff B]
|
||||
- Added screenshot feature. [Jeff B]
|
||||
- Added preferences. [Jeff B]
|
||||
- Many more strings are translatable now. [Jeff B]
|
||||
- Default screen color is black (better represents being "off" and easier on eyes at night). [Jeff B]
|
||||
- Added sound. [Jeff B]
|
||||
- Now is a universal binary. [Jeff B]
|
||||
- Leopard resolution icon added. [Jeff B]
|
||||
- Added a Japanese translation. [Jeff B]
|
||||
- Added an optional status bar (resize handle no longer overlaps screen). [Jeff B]
|
||||
- New ROM Info and About DeSmuME windows have been added. [Jeff B]
|
||||
- Fixed several bugs in window resizing. [Jeff B]
|
||||
- Added FAT image support for homebrew games (thanks to TypeError). [Jeff B]
|
||||
- Key config can be changed on the command line. Save/load hotkeys changed (so expose doesn't override). [Jeff B]
|
||||
- Key bindings may work better on non-US keyboards now (needs testing). [Jeff B]
|
||||
general:
|
||||
- Encapsulate GDB debug stub to avoid certain problems [shash]
|
||||
- Fixed CPU LD*/ST* bugs [shash]
|
||||
- Fixed New SMB mini-games freeze [shash]
|
||||
- Fixed possible segfault in ROMReader on ia64 and amd64. [evilynux]
|
||||
- Fixed a crash bug with 2D background corrupting memory [shash]
|
||||
- Flag check optimization [carlo_bramini]
|
||||
- Applied some endian fixes in GPU (thanks to Phazz) [Jeff B]
|
||||
gtk-glade:
|
||||
- Added DeSmuME version in about dialog. [evilynux]
|
||||
- Updated website url in about dialog. [evilynux]
|
||||
- Added Brazilian Portuguese translation by Dreampeppers99. [evilynux]
|
||||
- Better desktop menu entry following FreeDesktop specifications. [evilynux]
|
||||
gtk:
|
||||
- Updated website url in about dialog. [evilynux]
|
||||
- Better desktop menu entry following FreeDesktop specifications. [evilynux]
|
||||
windows port:
|
||||
- Added an "about" box [shash]
|
||||
- DirectInput control interface with joystick support [CrazyMax]
|
||||
- Matrix and Light viewer [Acid Burn]
|
||||
|
||||
0.7.2 -> 0.7.3
|
||||
gtk-glade:
|
||||
- Full localization using intltool/gettext. [evilynux]
|
||||
general:
|
||||
- Added a README.TRANSLATION documenting the localization process. [evilynux]
|
||||
MacOS X:
|
||||
- Initial version of the Mac interface added. [Jeff B]
|
||||
|
||||
0.7.1 -> 0.7.2
|
||||
spu:
|
||||
- big endian fixes. [cyberwarriorx]
|
||||
gpu:
|
||||
- big endian fixes. [marcus_c]
|
||||
gtk-glade:
|
||||
- opengl improvements. [masscat]
|
||||
general:
|
||||
- Added support for setting NDS firmware language value. [masscat]
|
||||
- Function added for setting firmware language. [masscat]
|
||||
- Mac/msys compilation fixes. [cyberwarriorx]
|
||||
- Fix compilation when pkg-config macros are not available [evilynux]
|
||||
|
||||
0.7.0 -> 0.7.1
|
||||
general:
|
||||
- Added GDB debugger stub [masscat]
|
||||
- Added new/different GBAMP CFlash image reader/writer [masscat]
|
||||
gpu:
|
||||
- Major speedup to the 2D core [shash]
|
||||
gtk-glade:
|
||||
- Added command line options. [masscat]
|
||||
- Added FPS limiter [masscat]
|
||||
cli:
|
||||
- Added command line options. [masscat]
|
||||
- Added FPS limiter [masscat]
|
||||
- Added option to use OpenGl to render window (allows resizing). [masscat]
|
||||
windows port:
|
||||
- Added command line options. [masscat]
|
||||
- Added multiple language support [cyberwarriorx]
|
||||
- Added Danish language translation [thomas-2007]
|
||||
|
||||
0.6.0 -> 0.7.0
|
||||
general:
|
||||
- Added support for *.duc files [cyberwarriorx]
|
||||
gpu:
|
||||
- Added support for sprite rotation/scaling [shash]
|
||||
- Added support for the 3D core (openGL and null plugins) [shash]
|
||||
windows port:
|
||||
- A bunch of fixes [Dmitry Krutskih]
|
||||
- Fixed a bug in sound that was causing it to still not work for some
|
||||
people [cyberwarriorx]
|
||||
gtk:
|
||||
- Added 3D emulation
|
||||
- Added command line options.
|
||||
- Added option to use OpenGL to render window (allows resizing).
|
||||
gtk-glade:
|
||||
- Added 3D emulation
|
||||
|
||||
0.5.0 -> 0.6.0
|
||||
general:
|
||||
- Added zipped (based on zziplib) and gzipped (based on zlib) rom support.
|
||||
arm:
|
||||
- Added relocation interrupt vector.
|
||||
- Added region access right checks.
|
||||
- Enabled LDC/STC instructions.
|
||||
- Fixed powersave (cp15) IRQ wait.
|
||||
- Fixed MOV instructions
|
||||
gpu:
|
||||
- Added special color effects.
|
||||
- Added windowing feature.
|
||||
- Fixed transparent direct color backgrounds.
|
||||
- Fixed disabled sprites showing.
|
||||
- Fixed 8/32 bit access to gpu registers.
|
||||
- Fixed missing backgrounds
|
||||
- Support for master brightness
|
||||
wifi:
|
||||
- Added RF chip interface.
|
||||
- Added BB chip interface.
|
||||
windows port:
|
||||
- Fixed address calculation in disassembler.
|
||||
- Added Force Maintain Ratio option for window stretching
|
||||
linux port (cli, gtk and gtk-glade):
|
||||
all:
|
||||
- Added joystick support.
|
||||
- Fixed X and Y buttons.
|
||||
gtk-glade:
|
||||
- Added joystick configuration.
|
||||
- Improved I/O registers viewer tool.
|
||||
- Added save and load states support.
|
||||
|
||||
0.3.3 -> 0.5.0
|
||||
arm:
|
||||
- Fixed MSR with immediate value opcode.
|
||||
- Fixed LSR_0 thumb opcode (C flag is correctly set now).
|
||||
- Fixed LDR*/STR* opcodes.
|
||||
- Fixed unaligned memory access on THUMB Core.
|
||||
- Added relocating SWI routines.
|
||||
bios:
|
||||
- Added decompression functions.
|
||||
- Added GetPitchTable function.
|
||||
- Added GetVolumeTable function.
|
||||
- Added GetCRC16 function.
|
||||
- Added experimental SoundBias function.
|
||||
- Added GetSineTable function.
|
||||
cart:
|
||||
- Added CompactFlash/FAT emulation.
|
||||
- Added Get ROM chip ID Cartridge command.
|
||||
gpu:
|
||||
- Added framebuffer emulation.
|
||||
- Fixed a bug in GPU (xfin could be greater than LG causing a segfault).
|
||||
- Added support for Display Mode 0(Display Off).
|
||||
- Added the basic framework for Display Mode 3(Display from Main RAM).
|
||||
spu:
|
||||
- Added sound emulation.
|
||||
- Added sound core system.
|
||||
- Added WAV write core.
|
||||
- Added dummy core.
|
||||
- Added Direct Sound core.
|
||||
linux port:
|
||||
- Added GTK+ GUI.
|
||||
- Added command line interface.
|
||||
- Added stylus and arm9 keypad support in CLI version.
|
||||
- Added FPS display.
|
||||
- Added basic frameskip.
|
||||
windows port:
|
||||
- Fixed a bug when displaying a ROM's information.
|
||||
- Added key configuration.
|
||||
- Removed the debug key.
|
||||
- Added new experimental auto frameskip/frame limit code.
|
||||
- Added sound settings dialog.
|
||||
- Added a few menu options for accessing the website, forums, and for
|
||||
submitting bugs.
|
||||
general:
|
||||
- Rewrote code in C.
|
||||
- Fixed warnings.
|
||||
- Used defines and typedef's to make things more portable and easier to
|
||||
read.
|
||||
- Added autotools stuff.
|
||||
- Changes to logging system.
|
||||
- Added screenshot function.
|
||||
- Translated most french to english.
|
||||
- Added savestate support.
|
||||
- Added firmware reading support(needs work).
|
||||
- Added Backup Memory support with autodetection.
|
||||
- Fixed some endianess issues.
|
||||
- Fixed things so Visual C++ can compile code.
|
||||
- Added bsd support.
|
||||
- Reworked ROM loading so you can load a different rom without any problems.
|
||||
- Finished NDS_Reset. Now the emulation can be reset even while running.
|
||||
@@ -0,0 +1,97 @@
|
||||
DeSmuME
|
||||
_________________________________________
|
||||
Copyright (C) 2006 yopyop
|
||||
Copyright (C) 2006-2015 DeSmuME team
|
||||
Last Updated: March 28, 2015
|
||||
|
||||
Contents:
|
||||
1) About ................................................................... 14
|
||||
2) Credits ................................................................. 59
|
||||
3) Contact Information ..................................................... 72
|
||||
4) License ................................................................. 82
|
||||
|
||||
|
||||
1) About ______________________________________________________________________
|
||||
|
||||
DeSmuME is software that allows you to emulate a Nintendo DS system. Think of
|
||||
it as a Swiss-Army knife for Nintendo DS emulation, giving you access to many
|
||||
powerful tools for testing DS features, from viewing ROM properties to managing
|
||||
Action Replay cheats. And best of all, this software is completely free and
|
||||
open-source.
|
||||
|
||||
For information on how to install or operate DeSmuME for your operating system,
|
||||
please see the README file that should be present with your installation.
|
||||
|
||||
Port-specific README files:
|
||||
* README.LIN for the Linux port
|
||||
* README.WIN for the Windows port
|
||||
* README.MAC for the Macintosh port
|
||||
|
||||
Note that each DeSmuME port may have a different feature set from another port.
|
||||
You may see more feature parity between ports over time as we continue
|
||||
developing DeSmuME.
|
||||
|
||||
You can find our documentation on our online Wiki page. The major pages of
|
||||
interest are:
|
||||
|
||||
* Official Documentation: http://wiki.desmume.org/index.php?title=Main_Page
|
||||
|
||||
This is the main Wiki page that contains all of our official documentation.
|
||||
|
||||
* Manuals: http://wiki.desmume.org/index.php?title=Manual
|
||||
|
||||
The manuals contain detailed information about how to operate DeSmuME for each
|
||||
port.
|
||||
|
||||
* FAQ: http://wiki.desmume.org/index.php?title=Faq
|
||||
|
||||
The Frequently Asked Questions (FAQ) page has a lot of useful general
|
||||
information about DeSmuME. Do note that some of the information may be platform
|
||||
specific, and may not directly apply to your version of DeSmuME.
|
||||
|
||||
* Build Instructions:
|
||||
http://wiki.desmume.org/index.php?title=Installing_DeSmuME_from_source
|
||||
|
||||
This page contains detailed port-specific instructions about how to make your
|
||||
own build of DeSmuME directly from the source code.
|
||||
|
||||
|
||||
2) Credits ____________________________________________________________________
|
||||
|
||||
See the AUTHORS file for list of DeSmuME team members.
|
||||
|
||||
Special thanks go to:
|
||||
|
||||
* yopyop (original author of DeSmuME),
|
||||
for releasing the source code of this great emulator.
|
||||
|
||||
* Martin Korth (author of GBATEK),
|
||||
for his well-written Gameboy Advance and Nintendo DS documentation.
|
||||
|
||||
|
||||
3) Contact Information ________________________________________________________
|
||||
|
||||
Official Website: http://desmume.org
|
||||
Public Forum: http://forums.desmume.org
|
||||
Developer Chat: irc://irc.freenode.net/desmume
|
||||
Bug Reports: http://sourceforge.net/p/desmume/bugs
|
||||
|
||||
Please don't ask for ROMs, BIOS files, or any other copyrighted stuff.
|
||||
|
||||
|
||||
4) License ____________________________________________________________________
|
||||
|
||||
This file is free software: you can redistribute it and/or modify it under the
|
||||
terms of the GNU General Public License as published by the Free Software
|
||||
Foundation, either version 2 of the License, or (at your option) any later
|
||||
version.
|
||||
|
||||
This file is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along with
|
||||
this software. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
* See the GNU General Public License details in COPYING.
|
||||
Executable
+3782
File diff suppressed because it is too large
Load Diff
Executable
+31
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
Copyright (C) 2006 yopyop
|
||||
Copyright (C) 2006-2009 DeSmuME team
|
||||
|
||||
This file is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This file is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with the this software. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef DISASSEMBLER_H
|
||||
#define DISASSEMBLER_H
|
||||
|
||||
#include "types.h"
|
||||
|
||||
typedef char* (* DisasmOpFunc)(u32 adr, u32 i, char * txt);
|
||||
|
||||
extern const DisasmOpFunc des_arm_instructions_set[4096];
|
||||
extern const DisasmOpFunc des_thumb_instructions_set[1024];
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
Executable
+328
@@ -0,0 +1,328 @@
|
||||
/*
|
||||
Copyright 2006 yopyop
|
||||
Copyright 2007 shash
|
||||
Copyright 2007-2015 DeSmuME team
|
||||
|
||||
This file is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This file is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with the this software. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "FIFO.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "armcpu.h"
|
||||
#include "debug.h"
|
||||
#include "mem.h"
|
||||
#include "MMU.h"
|
||||
#include "registers.h"
|
||||
#include "NDSSystem.h"
|
||||
#include "gfx3d.h"
|
||||
|
||||
// ========================================================= IPC FIFO
|
||||
IPC_FIFO ipc_fifo[2];
|
||||
|
||||
void IPC_FIFOinit(u8 proc)
|
||||
{
|
||||
memset(&ipc_fifo[proc], 0, sizeof(IPC_FIFO));
|
||||
T1WriteWord(MMU.MMU_MEM[proc][0x40], 0x184, 0x00000101);
|
||||
}
|
||||
|
||||
void IPC_FIFOsend(u8 proc, u32 val)
|
||||
{
|
||||
u16 cnt_l = T1ReadWord(MMU.MMU_MEM[proc][0x40], 0x184);
|
||||
if (!(cnt_l & IPCFIFOCNT_FIFOENABLE)) return; // FIFO disabled
|
||||
u8 proc_remote = proc ^ 1;
|
||||
|
||||
if (ipc_fifo[proc].size > 15)
|
||||
{
|
||||
cnt_l |= IPCFIFOCNT_FIFOERROR;
|
||||
T1WriteWord(MMU.MMU_MEM[proc][0x40], 0x184, cnt_l);
|
||||
return;
|
||||
}
|
||||
|
||||
u16 cnt_r = T1ReadWord(MMU.MMU_MEM[proc_remote][0x40], 0x184);
|
||||
|
||||
//LOG("IPC%s send FIFO 0x%08X size %03i (l 0x%X, tail %02i) (r 0x%X, tail %02i)\n",
|
||||
// proc?"7":"9", val, ipc_fifo[proc].size, cnt_l, ipc_fifo[proc].tail, cnt_r, ipc_fifo[proc^1].tail);
|
||||
|
||||
cnt_l &= 0xBFFC; // clear send empty bit & full
|
||||
cnt_r &= 0xBCFF; // set recv empty bit & full
|
||||
ipc_fifo[proc].buf[ipc_fifo[proc].tail] = val;
|
||||
ipc_fifo[proc].tail++;
|
||||
ipc_fifo[proc].size++;
|
||||
if (ipc_fifo[proc].tail > 15) ipc_fifo[proc].tail = 0;
|
||||
|
||||
if (ipc_fifo[proc].size > 15)
|
||||
{
|
||||
cnt_l |= IPCFIFOCNT_SENDFULL; // set send full bit
|
||||
cnt_r |= IPCFIFOCNT_RECVFULL; // set recv full bit
|
||||
}
|
||||
|
||||
T1WriteWord(MMU.MMU_MEM[proc][0x40], 0x184, cnt_l);
|
||||
T1WriteWord(MMU.MMU_MEM[proc_remote][0x40], 0x184, cnt_r);
|
||||
|
||||
if(cnt_r&IPCFIFOCNT_RECVIRQEN)
|
||||
NDS_makeIrq(proc_remote, IRQ_BIT_IPCFIFO_RECVNONEMPTY);
|
||||
|
||||
NDS_Reschedule();
|
||||
}
|
||||
|
||||
u32 IPC_FIFOrecv(u8 proc)
|
||||
{
|
||||
u16 cnt_l = T1ReadWord(MMU.MMU_MEM[proc][0x40], 0x184);
|
||||
if (!(cnt_l & IPCFIFOCNT_FIFOENABLE)) return (0); // FIFO disabled
|
||||
u8 proc_remote = proc ^ 1;
|
||||
|
||||
u32 val = 0;
|
||||
|
||||
if ( ipc_fifo[proc_remote].size == 0 ) // remote FIFO error
|
||||
{
|
||||
cnt_l |= IPCFIFOCNT_FIFOERROR;
|
||||
T1WriteWord(MMU.MMU_MEM[proc][0x40], 0x184, cnt_l);
|
||||
return (0);
|
||||
}
|
||||
|
||||
u16 cnt_r = T1ReadWord(MMU.MMU_MEM[proc_remote][0x40], 0x184);
|
||||
|
||||
cnt_l &= 0xBCFF; // clear send full bit & empty
|
||||
cnt_r &= 0xBFFC; // set recv full bit & empty
|
||||
|
||||
val = ipc_fifo[proc_remote].buf[ipc_fifo[proc_remote].head];
|
||||
ipc_fifo[proc_remote].head++;
|
||||
ipc_fifo[proc_remote].size--;
|
||||
if (ipc_fifo[proc_remote].head > 15) ipc_fifo[proc_remote].head = 0;
|
||||
|
||||
//LOG("IPC%s recv FIFO 0x%08X size %03i (l 0x%X, tail %02i) (r 0x%X, tail %02i)\n",
|
||||
// proc?"7":"9", val, ipc_fifo[proc].size, cnt_l, ipc_fifo[proc].tail, cnt_r, ipc_fifo[proc^1].tail);
|
||||
|
||||
if ( ipc_fifo[proc_remote].size == 0 ) // FIFO empty
|
||||
{
|
||||
cnt_l |= IPCFIFOCNT_RECVEMPTY;
|
||||
cnt_r |= IPCFIFOCNT_SENDEMPTY;
|
||||
|
||||
if(cnt_r&IPCFIFOCNT_SENDIRQEN)
|
||||
NDS_makeIrq(proc_remote, IRQ_BIT_IPCFIFO_SENDEMPTY);
|
||||
}
|
||||
|
||||
T1WriteWord(MMU.MMU_MEM[proc][0x40], 0x184, cnt_l);
|
||||
T1WriteWord(MMU.MMU_MEM[proc_remote][0x40], 0x184, cnt_r);
|
||||
|
||||
NDS_Reschedule();
|
||||
|
||||
return (val);
|
||||
}
|
||||
|
||||
void IPC_FIFOcnt(u8 proc, u16 val)
|
||||
{
|
||||
u16 cnt_l = T1ReadWord(MMU.MMU_MEM[proc][0x40], 0x184);
|
||||
u16 cnt_r = T1ReadWord(MMU.MMU_MEM[proc^1][0x40], 0x184);
|
||||
|
||||
if (val & IPCFIFOCNT_FIFOERROR)
|
||||
{
|
||||
//at least SPP uses this, maybe every retail game
|
||||
cnt_l &= ~IPCFIFOCNT_FIFOERROR;
|
||||
}
|
||||
|
||||
if (val & IPCFIFOCNT_SENDCLEAR)
|
||||
{
|
||||
ipc_fifo[proc].head = 0; ipc_fifo[proc].tail = 0; ipc_fifo[proc].size = 0;
|
||||
|
||||
cnt_l |= IPCFIFOCNT_SENDEMPTY;
|
||||
cnt_r |= IPCFIFOCNT_RECVEMPTY;
|
||||
|
||||
cnt_l &= ~IPCFIFOCNT_SENDFULL;
|
||||
cnt_r &= ~IPCFIFOCNT_RECVFULL;
|
||||
|
||||
}
|
||||
cnt_l &= ~IPCFIFOCNT_WRITEABLE;
|
||||
cnt_l |= val & IPCFIFOCNT_WRITEABLE;
|
||||
|
||||
//IPCFIFOCNT_SENDIRQEN may have been set (and/or the fifo may have been cleared) so we may need to trigger this irq
|
||||
//(this approach is used by libnds fifo system on occasion in fifoInternalSend, and began happening frequently for value32 with r4326)
|
||||
if(cnt_l&IPCFIFOCNT_SENDIRQEN) if(cnt_l & IPCFIFOCNT_SENDEMPTY)
|
||||
NDS_makeIrq(proc, IRQ_BIT_IPCFIFO_SENDEMPTY);
|
||||
|
||||
//IPCFIFOCNT_RECVIRQEN may have been set so we may need to trigger this irq
|
||||
if(cnt_l&IPCFIFOCNT_RECVIRQEN) if(!(cnt_l & IPCFIFOCNT_RECVEMPTY))
|
||||
NDS_makeIrq(proc, IRQ_BIT_IPCFIFO_RECVNONEMPTY);
|
||||
|
||||
T1WriteWord(MMU.MMU_MEM[proc][0x40], 0x184, cnt_l);
|
||||
T1WriteWord(MMU.MMU_MEM[proc^1][0x40], 0x184, cnt_r);
|
||||
|
||||
NDS_Reschedule();
|
||||
}
|
||||
|
||||
// ========================================================= GFX FIFO
|
||||
GFX_PIPE gxPIPE;
|
||||
GFX_FIFO gxFIFO;
|
||||
|
||||
void GFX_PIPEclear()
|
||||
{
|
||||
gxPIPE.head = 0;
|
||||
gxPIPE.tail = 0;
|
||||
gxPIPE.size = 0;
|
||||
gxFIFO.matrix_stack_op_size = 0;
|
||||
}
|
||||
|
||||
void GFX_FIFOclear()
|
||||
{
|
||||
gxFIFO.head = 0;
|
||||
gxFIFO.tail = 0;
|
||||
gxFIFO.size = 0;
|
||||
gxFIFO.matrix_stack_op_size = 0;
|
||||
}
|
||||
|
||||
static void GXF_FIFO_handleEvents()
|
||||
{
|
||||
bool low = gxFIFO.size <= 127;
|
||||
bool lowchange = MMU_new.gxstat.fifo_low ^ low;
|
||||
MMU_new.gxstat.fifo_low = low;
|
||||
if(low) triggerDma(EDMAMode_GXFifo);
|
||||
|
||||
bool empty = gxFIFO.size == 0;
|
||||
bool emptychange = MMU_new.gxstat.fifo_empty ^ empty;
|
||||
MMU_new.gxstat.fifo_empty = empty;
|
||||
|
||||
|
||||
MMU_new.gxstat.sb = gxFIFO.matrix_stack_op_size != 0;
|
||||
|
||||
if(emptychange||lowchange) NDS_Reschedule();
|
||||
}
|
||||
|
||||
static bool IsMatrixStackCommand(u8 cmd)
|
||||
{
|
||||
return cmd == 0x11 || cmd == 0x12;
|
||||
}
|
||||
|
||||
void GFX_FIFOsend(u8 cmd, u32 param)
|
||||
{
|
||||
//INFO("gxFIFO: send 0x%02X = 0x%08X (size %03i/0x%02X) gxstat 0x%08X\n", cmd, param, gxFIFO.size, gxFIFO.size, gxstat);
|
||||
//printf("fifo recv: %02X: %08X upto:%d\n",cmd,param,gxFIFO.size+1);
|
||||
|
||||
//TODO - WOAH ! NOT HANDLING A TOO-BIG FIFO RIGHT NOW!
|
||||
//if (gxFIFO.size > 255)
|
||||
//{
|
||||
// GXF_FIFO_handleEvents();
|
||||
// //NEED TO HANDLE THIS!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
|
||||
// //gxstat |= 0x08000000; // busy
|
||||
// NDS_RescheduleGXFIFO(1);
|
||||
// //INFO("ERROR: gxFIFO is full (cmd 0x%02X = 0x%08X) (prev cmd 0x%02X = 0x%08X)\n", cmd, param, gxFIFO.cmd[255], gxFIFO.param[255]);
|
||||
// return;
|
||||
//}
|
||||
|
||||
|
||||
gxFIFO.cmd[gxFIFO.tail] = cmd;
|
||||
gxFIFO.param[gxFIFO.tail] = param;
|
||||
gxFIFO.tail++;
|
||||
gxFIFO.size++;
|
||||
if (gxFIFO.tail > HACK_GXIFO_SIZE-1) gxFIFO.tail = 0;
|
||||
|
||||
//if a matrix op is entering the pipeline, do accounting for it
|
||||
//(this is tested by wild west, which will jam a few ops in the fifo and then wait for the matrix stack to be
|
||||
//un-busy so it can read back the current matrix stack position).
|
||||
//it is definitely only pushes and pops which set this flag.
|
||||
//seems like it would be less work in the HW to make a counter than do cmps on all the command bytes, so maybe we're even doing it right.
|
||||
if(IsMatrixStackCommand(cmd))
|
||||
gxFIFO.matrix_stack_op_size++;
|
||||
|
||||
if(gxFIFO.size>=HACK_GXIFO_SIZE) {
|
||||
printf("--FIFO FULL-- : %d\n",gxFIFO.size);
|
||||
}
|
||||
|
||||
//gxstat |= 0x08000000; // set busy flag
|
||||
|
||||
GXF_FIFO_handleEvents();
|
||||
|
||||
NDS_RescheduleGXFIFO(1);
|
||||
}
|
||||
|
||||
// this function used ONLY in gxFIFO
|
||||
BOOL GFX_PIPErecv(u8 *cmd, u32 *param)
|
||||
{
|
||||
//gxstat &= 0xF7FFFFFF; // clear busy flag
|
||||
|
||||
if (gxFIFO.size == 0)
|
||||
{
|
||||
GXF_FIFO_handleEvents();
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
*cmd = gxFIFO.cmd[gxFIFO.head];
|
||||
*param = gxFIFO.param[gxFIFO.head];
|
||||
|
||||
//see the associated increment in another function
|
||||
if(IsMatrixStackCommand(*cmd))
|
||||
{
|
||||
gxFIFO.matrix_stack_op_size--;
|
||||
if(gxFIFO.matrix_stack_op_size>0x10000000)
|
||||
printf("bad news disaster in matrix_stack_op_size\n");
|
||||
}
|
||||
|
||||
gxFIFO.head++;
|
||||
gxFIFO.size--;
|
||||
if (gxFIFO.head > HACK_GXIFO_SIZE-1) gxFIFO.head = 0;
|
||||
|
||||
GXF_FIFO_handleEvents();
|
||||
|
||||
return (TRUE);
|
||||
}
|
||||
|
||||
void GFX_FIFOcnt(u32 val)
|
||||
{
|
||||
////INFO("gxFIFO: write cnt 0x%08X (prev 0x%08X) FIFO size %03i PIPE size %03i\n", val, gxstat, gxFIFO.size, gxPIPE.size);
|
||||
|
||||
if (val & (1<<29)) // clear? (only in homebrew?)
|
||||
{
|
||||
GFX_PIPEclear();
|
||||
GFX_FIFOclear();
|
||||
return;
|
||||
}
|
||||
|
||||
//zeromus says: what happened to clear stack?
|
||||
//if (val & (1<<15)) // projection stack pointer reset
|
||||
//{
|
||||
// gfx3d_ClearStack();
|
||||
// val &= 0xFFFF5FFF; // clear reset (bit15) & stack level (bit13)
|
||||
//}
|
||||
|
||||
T1WriteLong(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x600, val);
|
||||
}
|
||||
|
||||
// ========================================================= DISP FIFO
|
||||
DISP_FIFO disp_fifo;
|
||||
|
||||
void DISP_FIFOinit()
|
||||
{
|
||||
memset(&disp_fifo, 0, sizeof(DISP_FIFO));
|
||||
}
|
||||
|
||||
void DISP_FIFOsend(u32 val)
|
||||
{
|
||||
//INFO("DISP_FIFO send value 0x%08X (head 0x%06X, tail 0x%06X)\n", val, disp_fifo.head, disp_fifo.tail);
|
||||
disp_fifo.buf[disp_fifo.tail] = val;
|
||||
disp_fifo.tail++;
|
||||
if (disp_fifo.tail > 0x5FFF)
|
||||
disp_fifo.tail = 0;
|
||||
}
|
||||
|
||||
u32 DISP_FIFOrecv()
|
||||
{
|
||||
//if (disp_fifo.tail == disp_fifo.head) return (0); // FIFO is empty
|
||||
u32 val = disp_fifo.buf[disp_fifo.head];
|
||||
disp_fifo.head++;
|
||||
if (disp_fifo.head > 0x5FFF)
|
||||
disp_fifo.head = 0;
|
||||
return (val);
|
||||
}
|
||||
Executable
+91
@@ -0,0 +1,91 @@
|
||||
/*
|
||||
Copyright 2006 yopyop
|
||||
Copyright 2007 shash
|
||||
Copyright 2007-2011 DeSmuME team
|
||||
|
||||
This file is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This file is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with the this software. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef FIFO_H
|
||||
#define FIFO_H
|
||||
|
||||
#include "types.h"
|
||||
|
||||
//=================================================== IPC FIFO
|
||||
typedef struct
|
||||
{
|
||||
u32 buf[16];
|
||||
|
||||
u8 head;
|
||||
u8 tail;
|
||||
u8 size;
|
||||
} IPC_FIFO;
|
||||
|
||||
extern IPC_FIFO ipc_fifo[2];
|
||||
extern void IPC_FIFOinit(u8 proc);
|
||||
extern void IPC_FIFOsend(u8 proc, u32 val);
|
||||
extern u32 IPC_FIFOrecv(u8 proc);
|
||||
extern void IPC_FIFOcnt(u8 proc, u16 val);
|
||||
|
||||
//=================================================== GFX FIFO
|
||||
|
||||
//yeah, its oversize for now. thats a simpler solution
|
||||
//moon seems to overdrive the fifo with immediate dmas
|
||||
//i think this might be nintendo code too
|
||||
#define HACK_GXIFO_SIZE 200000
|
||||
|
||||
typedef struct
|
||||
{
|
||||
u8 cmd[HACK_GXIFO_SIZE];
|
||||
u32 param[HACK_GXIFO_SIZE];
|
||||
|
||||
u32 head; // start position
|
||||
u32 tail; // tail
|
||||
u32 size; // size FIFO buffer
|
||||
u32 matrix_stack_op_size; //number of matrix stack items in the fifo (stack is busy when this is nonzero)
|
||||
} GFX_FIFO;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
u8 cmd[4];
|
||||
u32 param[4];
|
||||
|
||||
u8 head;
|
||||
u8 tail;
|
||||
u8 size;
|
||||
} GFX_PIPE;
|
||||
|
||||
extern GFX_PIPE gxPIPE;
|
||||
extern GFX_FIFO gxFIFO;
|
||||
extern void GFX_PIPEclear();
|
||||
extern void GFX_FIFOclear();
|
||||
extern void GFX_FIFOsend(u8 cmd, u32 param);
|
||||
extern BOOL GFX_PIPErecv(u8 *cmd, u32 *param);
|
||||
extern void GFX_FIFOcnt(u32 val);
|
||||
|
||||
//=================================================== Display memory FIFO
|
||||
typedef struct
|
||||
{
|
||||
u32 buf[0x6000]; // 256x192 32K color
|
||||
u32 head; // head
|
||||
u32 tail; // tail
|
||||
} DISP_FIFO;
|
||||
|
||||
extern DISP_FIFO disp_fifo;
|
||||
extern void DISP_FIFOinit();
|
||||
extern void DISP_FIFOsend(u32 val);
|
||||
extern u32 DISP_FIFOrecv();
|
||||
|
||||
#endif
|
||||
Executable
+2760
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,923 @@
|
||||
/*
|
||||
Copyright (C) 2006 yopyop
|
||||
Copyright (C) 2006-2007 Theo Berkau
|
||||
Copyright (C) 2007 shash
|
||||
Copyright (C) 2009-2015 DeSmuME team
|
||||
|
||||
This file is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This file is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with the this software. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef GPU_H
|
||||
#define GPU_H
|
||||
|
||||
#include <stdio.h>
|
||||
#include <iosfwd>
|
||||
|
||||
#include "types.h"
|
||||
|
||||
class EMUFILE;
|
||||
struct MMU_struct;
|
||||
|
||||
//#undef FORCEINLINE
|
||||
//#define FORCEINLINE
|
||||
|
||||
void gpu_savestate(EMUFILE* os);
|
||||
bool gpu_loadstate(EMUFILE* is, int size);
|
||||
|
||||
/*******************************************************************************
|
||||
this structure is for display control,
|
||||
it holds flags for general display
|
||||
*******************************************************************************/
|
||||
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
struct _DISPCNT
|
||||
{
|
||||
/* 7*/ u8 ForceBlank:1; // A+B:
|
||||
/* 6*/ u8 OBJ_BMP_mapping:1; // A+B: 0=2D (128KB), 1=1D (128..256KB)
|
||||
/* 5*/ u8 OBJ_BMP_2D_dim:1; // A+B: 0=128x512, 1=256x256 pixels
|
||||
/* 4*/ u8 OBJ_Tile_mapping:1;// A+B: 0=2D (32KB), 1=1D (32..256KB)
|
||||
/* 3*/ u8 BG0_3D:1; // A : 0=2D, 1=3D
|
||||
/* 0*/ u8 BG_Mode:3; // A+B:
|
||||
/*15*/ u8 WinOBJ_Enable:1; // A+B: 0=disable, 1=Enable
|
||||
/*14*/ u8 Win1_Enable:1; // A+B: 0=disable, 1=Enable
|
||||
/*13*/ u8 Win0_Enable:1; // A+B: 0=disable, 1=Enable
|
||||
/*12*/ u8 OBJ_Enable:1; // A+B: 0=disable, 1=Enable
|
||||
/*11*/ u8 BG3_Enable:1; // A+B: 0=disable, 1=Enable
|
||||
/*10*/ u8 BG2_Enable:1; // A+B: 0=disable, 1=Enable
|
||||
/* 9*/ u8 BG1_Enable:1; // A+B: 0=disable, 1=Enable
|
||||
/* 8*/ u8 BG0_Enable:1; // A+B: 0=disable, 1=Enable
|
||||
/*23*/ u8 OBJ_HBlank_process:1; // A+B: OBJ processed during HBlank (GBA bit5)
|
||||
/*22*/ u8 OBJ_BMP_1D_Bound:1; // A :
|
||||
/*20*/ u8 OBJ_Tile_1D_Bound:2; // A+B:
|
||||
/*18*/ u8 VRAM_Block:2; // A : VRAM block (0..3=A..D)
|
||||
|
||||
/*16*/ u8 DisplayMode:2; // A+B: coreA(0..3) coreB(0..1) GBA(Green Swap)
|
||||
// 0=off (white screen)
|
||||
// 1=on (normal BG & OBJ layers)
|
||||
// 2=VRAM display (coreA only)
|
||||
// 3=RAM display (coreA only, DMA transfers)
|
||||
|
||||
/*31*/ u8 ExOBJPalette_Enable:1; // A+B: 0=disable, 1=Enable OBJ extended Palette
|
||||
/*30*/ u8 ExBGxPalette_Enable:1; // A+B: 0=disable, 1=Enable BG extended Palette
|
||||
/*27*/ u8 ScreenBase_Block:3; // A : Screen Base (64K step)
|
||||
/*24*/ u8 CharacBase_Block:3; // A : Character Base (64K step)
|
||||
};
|
||||
#else
|
||||
struct _DISPCNT
|
||||
{
|
||||
/* 0*/ u8 BG_Mode:3; // A+B:
|
||||
/* 3*/ u8 BG0_3D:1; // A : 0=2D, 1=3D
|
||||
/* 4*/ u8 OBJ_Tile_mapping:1; // A+B: 0=2D (32KB), 1=1D (32..256KB)
|
||||
/* 5*/ u8 OBJ_BMP_2D_dim:1; // A+B: 0=128x512, 1=256x256 pixels
|
||||
/* 6*/ u8 OBJ_BMP_mapping:1; // A+B: 0=2D (128KB), 1=1D (128..256KB)
|
||||
|
||||
// 7-15 same as GBA
|
||||
/* 7*/ u8 ForceBlank:1; // A+B:
|
||||
/* 8*/ u8 BG0_Enable:1; // A+B: 0=disable, 1=Enable
|
||||
/* 9*/ u8 BG1_Enable:1; // A+B: 0=disable, 1=Enable
|
||||
/*10*/ u8 BG2_Enable:1; // A+B: 0=disable, 1=Enable
|
||||
/*11*/ u8 BG3_Enable:1; // A+B: 0=disable, 1=Enable
|
||||
/*12*/ u8 OBJ_Enable:1; // A+B: 0=disable, 1=Enable
|
||||
/*13*/ u8 Win0_Enable:1; // A+B: 0=disable, 1=Enable
|
||||
/*14*/ u8 Win1_Enable:1; // A+B: 0=disable, 1=Enable
|
||||
/*15*/ u8 WinOBJ_Enable:1; // A+B: 0=disable, 1=Enable
|
||||
|
||||
/*16*/ u8 DisplayMode:2; // A+B: coreA(0..3) coreB(0..1) GBA(Green Swap)
|
||||
// 0=off (white screen)
|
||||
// 1=on (normal BG & OBJ layers)
|
||||
// 2=VRAM display (coreA only)
|
||||
// 3=RAM display (coreA only, DMA transfers)
|
||||
|
||||
/*18*/ u8 VRAM_Block:2; // A : VRAM block (0..3=A..D)
|
||||
/*20*/ u8 OBJ_Tile_1D_Bound:2; // A+B:
|
||||
/*22*/ u8 OBJ_BMP_1D_Bound:1; // A :
|
||||
/*23*/ u8 OBJ_HBlank_process:1; // A+B: OBJ processed during HBlank (GBA bit5)
|
||||
/*24*/ u8 CharacBase_Block:3; // A : Character Base (64K step)
|
||||
/*27*/ u8 ScreenBase_Block:3; // A : Screen Base (64K step)
|
||||
/*30*/ u8 ExBGxPalette_Enable:1; // A+B: 0=disable, 1=Enable BG extended Palette
|
||||
/*31*/ u8 ExOBJPalette_Enable:1; // A+B: 0=disable, 1=Enable OBJ extended Palette
|
||||
};
|
||||
#endif
|
||||
|
||||
typedef union
|
||||
{
|
||||
struct _DISPCNT bits;
|
||||
u32 val;
|
||||
} DISPCNT;
|
||||
#define BGxENABLED(cnt,num) ((num<8)? ((cnt.val>>8) & num):0)
|
||||
|
||||
|
||||
enum BlendFunc
|
||||
{
|
||||
NoBlend, Blend, Increase, Decrease
|
||||
};
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
this structure is for display control of a specific layer,
|
||||
there are 4 background layers
|
||||
their priority indicate which one to draw on top of the other
|
||||
some flags indicate special drawing mode, size, FX
|
||||
*******************************************************************************/
|
||||
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
struct _BGxCNT
|
||||
{
|
||||
/* 7*/ u8 Palette_256:1; // 0=16x16, 1=1*256 palette
|
||||
/* 6*/ u8 Mosaic_Enable:1; // 0=disable, 1=Enable mosaic
|
||||
/* 2*/ u8 CharacBase_Block:4; // individual character base offset (n*16KB)
|
||||
/* 0*/ u8 Priority:2; // 0..3=high..low
|
||||
/*14*/ u8 ScreenSize:2; // text : 256x256 512x256 256x512 512x512
|
||||
// x/rot/s : 128x128 256x256 512x512 1024x1024
|
||||
// bmp : 128x128 256x256 512x256 512x512
|
||||
// large : 512x1024 1024x512 - -
|
||||
/*13*/ u8 PaletteSet_Wrap:1; // BG0 extended palette set 0=set0, 1=set2
|
||||
// BG1 extended palette set 0=set1, 1=set3
|
||||
// BG2 overflow area wraparound 0=off, 1=wrap
|
||||
// BG3 overflow area wraparound 0=off, 1=wrap
|
||||
/* 8*/ u8 ScreenBase_Block:5; // individual screen base offset (text n*2KB, BMP n*16KB)
|
||||
};
|
||||
#else
|
||||
struct _BGxCNT
|
||||
{
|
||||
/* 0*/ u8 Priority:2; // 0..3=high..low
|
||||
/* 2*/ u8 CharacBase_Block:4; // individual character base offset (n*16KB)
|
||||
/* 6*/ u8 Mosaic_Enable:1; // 0=disable, 1=Enable mosaic
|
||||
/* 7*/ u8 Palette_256:1; // 0=16x16, 1=1*256 palette
|
||||
/* 8*/ u8 ScreenBase_Block:5; // individual screen base offset (text n*2KB, BMP n*16KB)
|
||||
/*13*/ u8 PaletteSet_Wrap:1; // BG0 extended palette set 0=set0, 1=set2
|
||||
// BG1 extended palette set 0=set1, 1=set3
|
||||
// BG2 overflow area wraparound 0=off, 1=wrap
|
||||
// BG3 overflow area wraparound 0=off, 1=wrap
|
||||
/*14*/ u8 ScreenSize:2; // text : 256x256 512x256 256x512 512x512
|
||||
// x/rot/s : 128x128 256x256 512x512 1024x1024
|
||||
// bmp : 128x128 256x256 512x256 512x512
|
||||
// large : 512x1024 1024x512 - -
|
||||
};
|
||||
#endif
|
||||
|
||||
|
||||
typedef union
|
||||
{
|
||||
struct _BGxCNT bits;
|
||||
u16 val;
|
||||
} BGxCNT;
|
||||
|
||||
/*******************************************************************************
|
||||
this structure is for background offset
|
||||
*******************************************************************************/
|
||||
|
||||
typedef struct {
|
||||
u16 BGxHOFS;
|
||||
u16 BGxVOFS;
|
||||
} BGxOFS;
|
||||
|
||||
/*******************************************************************************
|
||||
this structure is for rotoscale parameters
|
||||
*******************************************************************************/
|
||||
|
||||
typedef struct {
|
||||
s16 BGxPA;
|
||||
s16 BGxPB;
|
||||
s16 BGxPC;
|
||||
s16 BGxPD;
|
||||
s32 BGxX;
|
||||
s32 BGxY;
|
||||
} BGxPARMS;
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
these structures are for window description,
|
||||
windows are square regions and can "subclass"
|
||||
background layers or object layers (i.e window controls the layers)
|
||||
|
||||
screen
|
||||
|
|
||||
+-- Window0/Window1/OBJwindow/OutOfWindows
|
||||
|
|
||||
+-- BG0/BG1/BG2/BG3/OBJ
|
||||
*******************************************************************************/
|
||||
|
||||
typedef union {
|
||||
struct {
|
||||
u8 end:8;
|
||||
u8 start:8;
|
||||
} bits ;
|
||||
u16 val;
|
||||
} WINxDIM;
|
||||
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
typedef struct {
|
||||
/* 6*/ u8 :2;
|
||||
/* 5*/ u8 WINx_Effect_Enable:1;
|
||||
/* 4*/ u8 WINx_OBJ_Enable:1;
|
||||
/* 3*/ u8 WINx_BG3_Enable:1;
|
||||
/* 2*/ u8 WINx_BG2_Enable:1;
|
||||
/* 1*/ u8 WINx_BG1_Enable:1;
|
||||
/* 0*/ u8 WINx_BG0_Enable:1;
|
||||
} WINxBIT;
|
||||
#else
|
||||
typedef struct {
|
||||
/* 0*/ u8 WINx_BG0_Enable:1;
|
||||
/* 1*/ u8 WINx_BG1_Enable:1;
|
||||
/* 2*/ u8 WINx_BG2_Enable:1;
|
||||
/* 3*/ u8 WINx_BG3_Enable:1;
|
||||
/* 4*/ u8 WINx_OBJ_Enable:1;
|
||||
/* 5*/ u8 WINx_Effect_Enable:1;
|
||||
/* 6*/ u8 :2;
|
||||
} WINxBIT;
|
||||
#endif
|
||||
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
typedef union {
|
||||
struct {
|
||||
WINxBIT win0;
|
||||
WINxBIT win1;
|
||||
} bits;
|
||||
struct {
|
||||
u8 :3;
|
||||
u8 win0_en:5;
|
||||
u8 :3;
|
||||
u8 win1_en:5;
|
||||
} packed_bits;
|
||||
struct {
|
||||
u8 low;
|
||||
u8 high;
|
||||
} bytes;
|
||||
u16 val ;
|
||||
} WINxCNT ;
|
||||
#else
|
||||
typedef union {
|
||||
struct {
|
||||
WINxBIT win0;
|
||||
WINxBIT win1;
|
||||
} bits;
|
||||
struct {
|
||||
u8 win0_en:5;
|
||||
u8 :3;
|
||||
u8 win1_en:5;
|
||||
u8 :3;
|
||||
} packed_bits;
|
||||
struct {
|
||||
u8 low;
|
||||
u8 high;
|
||||
} bytes;
|
||||
u16 val ;
|
||||
} WINxCNT ;
|
||||
#endif
|
||||
|
||||
/*
|
||||
typedef struct {
|
||||
WINxDIM WIN0H;
|
||||
WINxDIM WIN1H;
|
||||
WINxDIM WIN0V;
|
||||
WINxDIM WIN1V;
|
||||
WINxCNT WININ;
|
||||
WINxCNT WINOUT;
|
||||
} WINCNT;
|
||||
*/
|
||||
|
||||
/*******************************************************************************
|
||||
this structure is for miscellanous settings
|
||||
//TODO: needs further description
|
||||
*******************************************************************************/
|
||||
|
||||
typedef struct {
|
||||
u16 MOSAIC;
|
||||
u16 unused1;
|
||||
u16 unused2;//BLDCNT;
|
||||
u16 unused3;//BLDALPHA;
|
||||
u16 unused4;//BLDY;
|
||||
u16 unused5;
|
||||
/*
|
||||
u16 unused6;
|
||||
u16 unused7;
|
||||
u16 unused8;
|
||||
u16 unused9;
|
||||
*/
|
||||
} MISCCNT;
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
this structure is for 3D settings
|
||||
*******************************************************************************/
|
||||
|
||||
struct _DISP3DCNT
|
||||
{
|
||||
/* 0*/ u8 EnableTexMapping:1; //
|
||||
/* 1*/ u8 PolygonShading:1; // 0=Toon Shading, 1=Highlight Shading
|
||||
/* 2*/ u8 EnableAlphaTest:1; // see ALPHA_TEST_REF
|
||||
/* 3*/ u8 EnableAlphaBlending:1; // see various Alpha values
|
||||
/* 4*/ u8 EnableAntiAliasing:1; //
|
||||
/* 5*/ u8 EnableEdgeMarking:1; // see EDGE_COLOR
|
||||
/* 6*/ u8 FogOnlyAlpha:1; // 0=Alpha and Color, 1=Only Alpha (see FOG_COLOR)
|
||||
/* 7*/ u8 EnableFog:1; // Fog Master Enable
|
||||
/* 8*/ u8 FogShiftSHR:4; // 0..10 SHR-Divider (see FOG_OFFSET)
|
||||
/*12*/ u8 AckColorBufferUnderflow:1; // Color Buffer RDLINES Underflow (0=None, 1=Underflow/Acknowledge)
|
||||
/*13*/ u8 AckVertexRAMOverflow:1; // Polygon/Vertex RAM Overflow (0=None, 1=Overflow/Acknowledge)
|
||||
/*14*/ u8 RearPlaneMode:1; // 0=Blank, 1=Bitmap
|
||||
/*15*/ u8 :1;
|
||||
/*16*/ u16 :16;
|
||||
};
|
||||
|
||||
typedef union
|
||||
{
|
||||
struct _DISP3DCNT bits;
|
||||
u32 val;
|
||||
} DISP3DCNT;
|
||||
|
||||
/*******************************************************************************
|
||||
this structure is for capture control (core A only)
|
||||
|
||||
source:
|
||||
http://nocash.emubase.de/gbatek.htm#dsvideocaptureandmainmemorydisplaymode
|
||||
*******************************************************************************/
|
||||
struct DISPCAPCNT
|
||||
{
|
||||
enum CAPX {
|
||||
_128, _256
|
||||
} capx;
|
||||
u32 val;
|
||||
BOOL enabled;
|
||||
u8 EVA;
|
||||
u8 EVB;
|
||||
u8 writeBlock;
|
||||
u8 writeOffset;
|
||||
u16 capy;
|
||||
u8 srcA;
|
||||
u8 srcB;
|
||||
u8 readBlock;
|
||||
u8 readOffset;
|
||||
u8 capSrc;
|
||||
} ;
|
||||
|
||||
/*******************************************************************************
|
||||
this structure holds everything and should be mapped to
|
||||
* core A : 0x04000000
|
||||
* core B : 0x04001000
|
||||
*******************************************************************************/
|
||||
|
||||
typedef struct _reg_dispx {
|
||||
DISPCNT dispx_DISPCNT; // 0x0400x000
|
||||
u16 dispA_DISPSTAT; // 0x04000004
|
||||
u16 dispx_VCOUNT; // 0x0400x006
|
||||
BGxCNT dispx_BGxCNT[4]; // 0x0400x008
|
||||
BGxOFS dispx_BGxOFS[4]; // 0x0400x010
|
||||
BGxPARMS dispx_BG2PARMS; // 0x0400x020
|
||||
BGxPARMS dispx_BG3PARMS; // 0x0400x030
|
||||
u8 filler[12]; // 0x0400x040
|
||||
MISCCNT dispx_MISC; // 0x0400x04C
|
||||
DISP3DCNT dispA_DISP3DCNT; // 0x04000060
|
||||
DISPCAPCNT dispA_DISPCAPCNT; // 0x04000064
|
||||
u32 dispA_DISPMMEMFIFO; // 0x04000068
|
||||
} REG_DISPx ;
|
||||
|
||||
|
||||
typedef BOOL (*fun_gl_Begin) (int screen);
|
||||
typedef void (*fun_gl_End) (int screen);
|
||||
// the GUI should use this function prior to all gl calls
|
||||
// if call to beg succeeds opengl draw
|
||||
void register_gl_fun(fun_gl_Begin beg,fun_gl_End end);
|
||||
|
||||
#define GPU_MAIN 0
|
||||
#define GPU_SUB 1
|
||||
|
||||
/* human readable bitmask names */
|
||||
#define ADDRESS_STEP_512B 0x00200
|
||||
#define ADDRESS_STEP_1KB 0x00400
|
||||
#define ADDRESS_STEP_2KB 0x00800
|
||||
#define ADDRESS_STEP_4KB 0x01000
|
||||
#define ADDRESS_STEP_8KB 0x02000
|
||||
#define ADDRESS_STEP_16KB 0x04000
|
||||
#define ADDRESS_STEP_32KB 0x08000
|
||||
#define ADDRESS_STEP_64KB 0x10000
|
||||
#define ADDRESS_STEP_128KB 0x20000
|
||||
#define ADDRESS_STEP_256KB 0x40000
|
||||
#define ADDRESS_STEP_512KB 0x80000
|
||||
#define ADDRESS_MASK_256KB (ADDRESS_STEP_256KB-1)
|
||||
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
struct _TILEENTRY
|
||||
{
|
||||
/*14*/ unsigned Palette:4;
|
||||
/*13*/ unsigned VFlip:1; // VERTICAL FLIP (top<-->bottom)
|
||||
/*12*/ unsigned HFlip:1; // HORIZONTAL FLIP (left<-->right)
|
||||
/* 0*/ unsigned TileNum:10;
|
||||
};
|
||||
#else
|
||||
struct _TILEENTRY
|
||||
{
|
||||
/* 0*/ unsigned TileNum:10;
|
||||
/*12*/ unsigned HFlip:1; // HORIZONTAL FLIP (left<-->right)
|
||||
/*13*/ unsigned VFlip:1; // VERTICAL FLIP (top<-->bottom)
|
||||
/*14*/ unsigned Palette:4;
|
||||
};
|
||||
#endif
|
||||
typedef union
|
||||
{
|
||||
struct _TILEENTRY bits;
|
||||
u16 val;
|
||||
} TILEENTRY;
|
||||
|
||||
struct _ROTOCOORD
|
||||
{
|
||||
u32 Fraction:8;
|
||||
s32 Integer:20;
|
||||
u32 pad:4;
|
||||
};
|
||||
typedef union
|
||||
{
|
||||
struct _ROTOCOORD bits;
|
||||
s32 val;
|
||||
} ROTOCOORD;
|
||||
|
||||
|
||||
/*
|
||||
this structure is for color representation,
|
||||
it holds 5 meaningful bits per color channel (red,green,blue)
|
||||
and 1 meaningful bit for alpha representation
|
||||
this bit can be unused or used for special FX
|
||||
*/
|
||||
|
||||
struct _COLOR { // abgr x555
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
unsigned alpha:1; // sometimes it is unused (pad)
|
||||
unsigned blue:5;
|
||||
unsigned green:5;
|
||||
unsigned red:5;
|
||||
#else
|
||||
unsigned red:5;
|
||||
unsigned green:5;
|
||||
unsigned blue:5;
|
||||
unsigned alpha:1; // sometimes it is unused (pad)
|
||||
#endif
|
||||
};
|
||||
struct _COLORx { // abgr x555
|
||||
unsigned bgr:15;
|
||||
unsigned alpha:1; // sometimes it is unused (pad)
|
||||
};
|
||||
|
||||
typedef union
|
||||
{
|
||||
struct _COLOR bits;
|
||||
struct _COLORx bitx;
|
||||
u16 val;
|
||||
} COLOR;
|
||||
|
||||
struct _COLOR32 { // ARGB
|
||||
unsigned :3;
|
||||
unsigned blue:5;
|
||||
unsigned :3;
|
||||
unsigned green:5;
|
||||
unsigned :3;
|
||||
unsigned red:5;
|
||||
unsigned :7;
|
||||
unsigned alpha:1; // sometimes it is unused (pad)
|
||||
};
|
||||
|
||||
typedef union
|
||||
{
|
||||
struct _COLOR32 bits;
|
||||
u32 val;
|
||||
} COLOR32;
|
||||
|
||||
#define COLOR_16_32(w,i) \
|
||||
/* doesnt matter who's 16bit who's 32bit */ \
|
||||
i.bits.red = w.bits.red; \
|
||||
i.bits.green = w.bits.green; \
|
||||
i.bits.blue = w.bits.blue; \
|
||||
i.bits.alpha = w.bits.alpha;
|
||||
|
||||
|
||||
|
||||
// (00: Normal, 01: Transparent, 10: Object window, 11: Bitmap)
|
||||
enum GPU_OBJ_MODE
|
||||
{
|
||||
GPU_OBJ_MODE_Normal = 0,
|
||||
GPU_OBJ_MODE_Transparent = 1,
|
||||
GPU_OBJ_MODE_Window = 2,
|
||||
GPU_OBJ_MODE_Bitmap = 3
|
||||
};
|
||||
|
||||
struct _OAM_
|
||||
{
|
||||
//attr0
|
||||
u8 Y;
|
||||
u8 RotScale;
|
||||
u8 Mode;
|
||||
u8 Mosaic;
|
||||
u8 Depth;
|
||||
u8 Shape;
|
||||
//att1
|
||||
s16 X;
|
||||
u8 RotScalIndex;
|
||||
u8 HFlip, VFlip;
|
||||
u8 Size;
|
||||
//attr2
|
||||
u16 TileIndex;
|
||||
u8 Priority;
|
||||
u8 PaletteIndex;
|
||||
//attr3
|
||||
u16 attr3;
|
||||
};
|
||||
|
||||
void SlurpOAM(_OAM_* oam_output, void* oam_buffer, int oam_index);
|
||||
u16 SlurpOAMAffineParam(void* oam_buffer, int oam_index);
|
||||
|
||||
typedef struct
|
||||
{
|
||||
s16 x;
|
||||
s16 y;
|
||||
} size;
|
||||
|
||||
|
||||
#define NB_PRIORITIES 4
|
||||
#define NB_BG 4
|
||||
//this structure holds information for rendering.
|
||||
typedef struct
|
||||
{
|
||||
u8 PixelsX[256];
|
||||
u8 BGs[NB_BG], nbBGs;
|
||||
u8 pad[1];
|
||||
u16 nbPixelsX;
|
||||
//256+8:
|
||||
u8 pad2[248];
|
||||
|
||||
//things were slower when i organized this struct this way. whatever.
|
||||
//u8 PixelsX[256];
|
||||
//int BGs[NB_BG], nbBGs;
|
||||
//int nbPixelsX;
|
||||
////<-- 256 + 24
|
||||
//u8 pad2[256-24];
|
||||
} itemsForPriority_t;
|
||||
#define MMU_ABG 0x06000000
|
||||
#define MMU_BBG 0x06200000
|
||||
#define MMU_AOBJ 0x06400000
|
||||
#define MMU_BOBJ 0x06600000
|
||||
#define MMU_LCDC 0x06800000
|
||||
|
||||
extern CACHE_ALIGN u8 gpuBlendTable555[17][17][32][32];
|
||||
|
||||
enum BGType {
|
||||
BGType_Invalid=0, BGType_Text=1, BGType_Affine=2, BGType_Large8bpp=3,
|
||||
BGType_AffineExt=4, BGType_AffineExt_256x16=5, BGType_AffineExt_256x1=6, BGType_AffineExt_Direct=7
|
||||
};
|
||||
|
||||
extern const BGType GPU_mode2type[8][4];
|
||||
|
||||
struct GPU
|
||||
{
|
||||
GPU()
|
||||
: debug(false)
|
||||
{}
|
||||
|
||||
// some structs are becoming redundant
|
||||
// some functions too (no need to recopy some vars as it is done by MMU)
|
||||
REG_DISPx * dispx_st;
|
||||
|
||||
//this indicates whether this gpu is handling debug tools
|
||||
bool debug;
|
||||
|
||||
_BGxCNT & bgcnt(int num) { return (dispx_st)->dispx_BGxCNT[num].bits; }
|
||||
_DISPCNT & dispCnt() { return dispx_st->dispx_DISPCNT.bits; }
|
||||
template<bool MOSAIC> void modeRender(int layer);
|
||||
|
||||
DISPCAPCNT dispCapCnt;
|
||||
BOOL LayersEnable[5];
|
||||
itemsForPriority_t itemsForPriority[NB_PRIORITIES];
|
||||
|
||||
#define BGBmpBB BG_bmp_ram
|
||||
#define BGChBB BG_tile_ram
|
||||
|
||||
u32 BG_bmp_large_ram[4];
|
||||
u32 BG_bmp_ram[4];
|
||||
u32 BG_tile_ram[4];
|
||||
u32 BG_map_ram[4];
|
||||
|
||||
u8 BGExtPalSlot[4];
|
||||
u32 BGSize[4][2];
|
||||
BGType BGTypes[4];
|
||||
|
||||
struct MosaicColor {
|
||||
u16 bg[4][256];
|
||||
struct Obj {
|
||||
u16 color;
|
||||
u8 alpha, opaque;
|
||||
} obj[256];
|
||||
} mosaicColors;
|
||||
|
||||
u8 sprNum[256];
|
||||
u8 h_win[2][256];
|
||||
const u8 *curr_win[2];
|
||||
void update_winh(int WIN_NUM);
|
||||
bool need_update_winh[2];
|
||||
|
||||
template<int WIN_NUM> void setup_windows();
|
||||
|
||||
u8 core;
|
||||
|
||||
u8 dispMode;
|
||||
u8 vramBlock;
|
||||
u8 *VRAMaddr;
|
||||
|
||||
//FIFO fifo;
|
||||
|
||||
u8 bgPrio[5];
|
||||
|
||||
BOOL bg0HasHighestPrio;
|
||||
|
||||
void * oam;
|
||||
u32 sprMem;
|
||||
u8 sprBoundary;
|
||||
u8 sprBMPBoundary;
|
||||
u8 sprBMPMode;
|
||||
u32 sprEnable;
|
||||
|
||||
u8 WIN0H0;
|
||||
u8 WIN0H1;
|
||||
u8 WIN0V0;
|
||||
u8 WIN0V1;
|
||||
|
||||
u8 WIN1H0;
|
||||
u8 WIN1H1;
|
||||
u8 WIN1V0;
|
||||
u8 WIN1V1;
|
||||
|
||||
u8 WININ0;
|
||||
bool WININ0_SPECIAL;
|
||||
u8 WININ1;
|
||||
bool WININ1_SPECIAL;
|
||||
|
||||
u8 WINOUT;
|
||||
bool WINOUT_SPECIAL;
|
||||
u8 WINOBJ;
|
||||
bool WINOBJ_SPECIAL;
|
||||
|
||||
u8 WIN0_ENABLED;
|
||||
u8 WIN1_ENABLED;
|
||||
u8 WINOBJ_ENABLED;
|
||||
|
||||
u16 BLDCNT;
|
||||
u8 BLDALPHA_EVA;
|
||||
u8 BLDALPHA_EVB;
|
||||
u8 BLDY_EVY;
|
||||
u16 *currentFadeInColors, *currentFadeOutColors;
|
||||
bool blend2[8];
|
||||
|
||||
CACHE_ALIGN u16 tempScanlineBuffer[256];
|
||||
u8 *tempScanline;
|
||||
|
||||
u8 MasterBrightMode;
|
||||
u32 MasterBrightFactor;
|
||||
|
||||
CACHE_ALIGN u8 bgPixels[1024]; //yes indeed, this is oversized. map debug tools try to write to it
|
||||
|
||||
u32 currLine;
|
||||
u8 currBgNum;
|
||||
bool blend1;
|
||||
u8* currDst;
|
||||
|
||||
u8* _3dColorLine;
|
||||
|
||||
|
||||
static struct MosaicLookup {
|
||||
|
||||
struct TableEntry {
|
||||
u8 begin, trunc;
|
||||
} table[16][256];
|
||||
|
||||
MosaicLookup() {
|
||||
for(int m=0;m<16;m++)
|
||||
for(int i=0;i<256;i++) {
|
||||
int mosaic = m+1;
|
||||
TableEntry &te = table[m][i];
|
||||
te.begin = (i%mosaic==0);
|
||||
te.trunc = i/mosaic*mosaic;
|
||||
}
|
||||
}
|
||||
|
||||
TableEntry *width, *height;
|
||||
int widthValue, heightValue;
|
||||
|
||||
} mosaicLookup;
|
||||
bool curr_mosaic_enabled;
|
||||
|
||||
u16 blend(u16 colA, u16 colB);
|
||||
|
||||
template<bool BACKDROP, BlendFunc FUNC, bool WINDOW>
|
||||
FORCEINLINE FASTCALL bool _master_setFinalBGColor(u16 &color, const u32 x);
|
||||
|
||||
template<BlendFunc FUNC, bool WINDOW>
|
||||
FORCEINLINE FASTCALL void _master_setFinal3dColor(int dstX, int srcX);
|
||||
|
||||
int setFinalColorBck_funcNum;
|
||||
int bgFunc;
|
||||
int setFinalColor3d_funcNum;
|
||||
int setFinalColorSpr_funcNum;
|
||||
//Final3DColFunct setFinalColor3D;
|
||||
enum SpriteRenderMode {
|
||||
SPRITE_1D, SPRITE_2D
|
||||
} spriteRenderMode;
|
||||
|
||||
template<GPU::SpriteRenderMode MODE>
|
||||
void _spriteRender(u8 * dst, u8 * dst_alpha, u8 * typeTab, u8 * prioTab);
|
||||
|
||||
inline void spriteRender(u8 * dst, u8 * dst_alpha, u8 * typeTab, u8 * prioTab)
|
||||
{
|
||||
if(spriteRenderMode == SPRITE_1D)
|
||||
_spriteRender<SPRITE_1D>(dst,dst_alpha,typeTab, prioTab);
|
||||
else
|
||||
_spriteRender<SPRITE_2D>(dst,dst_alpha,typeTab, prioTab);
|
||||
}
|
||||
|
||||
|
||||
void setFinalColor3d(int dstX, int srcX);
|
||||
|
||||
template<bool BACKDROP, int FUNCNUM> void setFinalColorBG(u16 color, const u32 x);
|
||||
template<bool MOSAIC, bool BACKDROP> FORCEINLINE void __setFinalColorBck(u16 color, const u32 x, const int opaque);
|
||||
template<bool MOSAIC, bool BACKDROP, int FUNCNUM> FORCEINLINE void ___setFinalColorBck(u16 color, const u32 x, const int opaque);
|
||||
|
||||
void setAffineStart(int layer, int xy, u32 val);
|
||||
void setAffineStartWord(int layer, int xy, u16 val, int word);
|
||||
u32 getAffineStart(int layer, int xy);
|
||||
void refreshAffineStartRegs(const int num, const int xy);
|
||||
|
||||
struct AffineInfo {
|
||||
AffineInfo() : x(0), y(0) {}
|
||||
u32 x, y;
|
||||
} affineInfo[2];
|
||||
|
||||
void renderline_checkWindows(u16 x, bool &draw, bool &effect) const;
|
||||
|
||||
// check whether (x,y) is within the rectangle (including wraparounds)
|
||||
template<int WIN_NUM>
|
||||
u8 withinRect(u16 x) const;
|
||||
|
||||
void setBLDALPHA(u16 val)
|
||||
{
|
||||
BLDALPHA_EVA = (val&0x1f) > 16 ? 16 : (val&0x1f);
|
||||
BLDALPHA_EVB = ((val>>8)&0x1f) > 16 ? 16 : ((val>>8)&0x1f);
|
||||
updateBLDALPHA();
|
||||
}
|
||||
|
||||
void setBLDALPHA_EVA(u8 val)
|
||||
{
|
||||
BLDALPHA_EVA = (val&0x1f) > 16 ? 16 : (val&0x1f);
|
||||
updateBLDALPHA();
|
||||
}
|
||||
|
||||
void setBLDALPHA_EVB(u8 val)
|
||||
{
|
||||
BLDALPHA_EVB = (val&0x1f) > 16 ? 16 : (val&0x1f);
|
||||
updateBLDALPHA();
|
||||
}
|
||||
|
||||
u32 getHOFS(int bg);
|
||||
u32 getVOFS(int bg);
|
||||
|
||||
typedef u8 TBlendTable[32][32];
|
||||
TBlendTable *blendTable;
|
||||
|
||||
void updateBLDALPHA()
|
||||
{
|
||||
blendTable = (TBlendTable*)&gpuBlendTable555[BLDALPHA_EVA][BLDALPHA_EVB][0][0];
|
||||
}
|
||||
|
||||
};
|
||||
#if 0
|
||||
// normally should have same addresses
|
||||
static void REG_DISPx_pack_test(GPU * gpu)
|
||||
{
|
||||
REG_DISPx * r = gpu->dispx_st;
|
||||
printf ("%08x %02x\n", (u32)r, (u32)(&r->dispx_DISPCNT) - (u32)r);
|
||||
printf ("\t%02x\n", (u32)(&r->dispA_DISPSTAT) - (u32)r);
|
||||
printf ("\t%02x\n", (u32)(&r->dispx_VCOUNT) - (u32)r);
|
||||
printf ("\t%02x\n", (u32)(&r->dispx_BGxCNT[0]) - (u32)r);
|
||||
printf ("\t%02x\n", (u32)(&r->dispx_BGxOFS[0]) - (u32)r);
|
||||
printf ("\t%02x\n", (u32)(&r->dispx_BG2PARMS) - (u32)r);
|
||||
printf ("\t%02x\n", (u32)(&r->dispx_BG3PARMS) - (u32)r);
|
||||
// printf ("\t%02x\n", (u32)(&r->dispx_WINCNT) - (u32)r);
|
||||
printf ("\t%02x\n", (u32)(&r->dispx_MISC) - (u32)r);
|
||||
printf ("\t%02x\n", (u32)(&r->dispA_DISP3DCNT) - (u32)r);
|
||||
printf ("\t%02x\n", (u32)(&r->dispA_DISPCAPCNT) - (u32)r);
|
||||
printf ("\t%02x\n", (u32)(&r->dispA_DISPMMEMFIFO) - (u32)r);
|
||||
}
|
||||
#endif
|
||||
|
||||
CACHE_ALIGN extern u8 GPU_screen[4*256*192];
|
||||
|
||||
|
||||
GPU * GPU_Init(u8 l);
|
||||
void GPU_Reset(GPU *g, u8 l);
|
||||
void GPU_DeInit(GPU *);
|
||||
|
||||
//these are functions used by debug tools which want to render layers etc outside the context of the emulation
|
||||
namespace GPU_EXT
|
||||
{
|
||||
void textBG(GPU * gpu, u8 num, u8 * DST); //Draw text based background
|
||||
void rotBG(GPU * gpu, u8 num, u8 * DST);
|
||||
void extRotBG(GPU * gpu, u8 num, u8 * DST);
|
||||
};
|
||||
void sprite1D(GPU * gpu, u16 l, u8 * dst, u8 * dst_alpha, u8 * typeTab, u8 * prioTab);
|
||||
void sprite2D(GPU * gpu, u16 l, u8 * dst, u8 * dst_alpha, u8 * typeTab, u8 * prioTab);
|
||||
|
||||
extern const size sprSizeTab[4][4];
|
||||
|
||||
typedef struct {
|
||||
GPU * gpu;
|
||||
u16 offset;
|
||||
} NDS_Screen;
|
||||
|
||||
extern NDS_Screen MainScreen;
|
||||
extern NDS_Screen SubScreen;
|
||||
|
||||
int Screen_Init();
|
||||
void Screen_Reset(void);
|
||||
void Screen_DeInit(void);
|
||||
|
||||
extern MMU_struct MMU;
|
||||
|
||||
void GPU_setVideoProp(GPU *, u32 p);
|
||||
void GPU_setBGProp(GPU *, u16 num, u16 p);
|
||||
|
||||
void GPU_setBLDCNT(GPU *gpu, u16 v) ;
|
||||
void GPU_setBLDY(GPU *gpu, u16 v) ;
|
||||
void GPU_setMOSAIC(GPU *gpu, u16 v) ;
|
||||
|
||||
|
||||
void GPU_remove(GPU *, u8 num);
|
||||
void GPU_addBack(GPU *, u8 num);
|
||||
|
||||
int GPU_ChangeGraphicsCore(int coreid);
|
||||
|
||||
void GPU_set_DISPCAPCNT(u32 val) ;
|
||||
void GPU_RenderLine(NDS_Screen * screen, u16 l, bool skip = false) ;
|
||||
void GPU_setMasterBrightness (GPU *gpu, u16 val);
|
||||
|
||||
inline void GPU_setWIN0_H(GPU* gpu, u16 val) { gpu->WIN0H0 = val >> 8; gpu->WIN0H1 = val&0xFF; gpu->need_update_winh[0] = true; }
|
||||
inline void GPU_setWIN0_H0(GPU* gpu, u8 val) { gpu->WIN0H0 = val; gpu->need_update_winh[0] = true; }
|
||||
inline void GPU_setWIN0_H1(GPU* gpu, u8 val) { gpu->WIN0H1 = val; gpu->need_update_winh[0] = true; }
|
||||
|
||||
inline void GPU_setWIN0_V(GPU* gpu, u16 val) { gpu->WIN0V0 = val >> 8; gpu->WIN0V1 = val&0xFF;}
|
||||
inline void GPU_setWIN0_V0(GPU* gpu, u8 val) { gpu->WIN0V0 = val; }
|
||||
inline void GPU_setWIN0_V1(GPU* gpu, u8 val) { gpu->WIN0V1 = val; }
|
||||
|
||||
inline void GPU_setWIN1_H(GPU* gpu, u16 val) {gpu->WIN1H0 = val >> 8; gpu->WIN1H1 = val&0xFF; gpu->need_update_winh[1] = true; }
|
||||
inline void GPU_setWIN1_H0(GPU* gpu, u8 val) { gpu->WIN1H0 = val; gpu->need_update_winh[1] = true; }
|
||||
inline void GPU_setWIN1_H1(GPU* gpu, u8 val) { gpu->WIN1H1 = val; gpu->need_update_winh[1] = true; }
|
||||
|
||||
inline void GPU_setWIN1_V(GPU* gpu, u16 val) { gpu->WIN1V0 = val >> 8; gpu->WIN1V1 = val&0xFF; }
|
||||
inline void GPU_setWIN1_V0(GPU* gpu, u8 val) { gpu->WIN1V0 = val; }
|
||||
inline void GPU_setWIN1_V1(GPU* gpu, u8 val) { gpu->WIN1V1 = val; }
|
||||
|
||||
inline void GPU_setWININ(GPU* gpu, u16 val) {
|
||||
gpu->WININ0=val&0x1F;
|
||||
gpu->WININ0_SPECIAL=((val>>5)&1)!=0;
|
||||
gpu->WININ1=(val>>8)&0x1F;
|
||||
gpu->WININ1_SPECIAL=((val>>13)&1)!=0;
|
||||
}
|
||||
|
||||
inline void GPU_setWININ0(GPU* gpu, u8 val) { gpu->WININ0 = val&0x1F; gpu->WININ0_SPECIAL = (val>>5)&1; }
|
||||
inline void GPU_setWININ1(GPU* gpu, u8 val) { gpu->WININ1 = val&0x1F; gpu->WININ1_SPECIAL = (val>>5)&1; }
|
||||
|
||||
inline void GPU_setWINOUT16(GPU* gpu, u16 val) {
|
||||
gpu->WINOUT=val&0x1F;
|
||||
gpu->WINOUT_SPECIAL=((val>>5)&1)!=0;
|
||||
gpu->WINOBJ=(val>>8)&0x1F;
|
||||
gpu->WINOBJ_SPECIAL=((val>>13)&1)!=0;
|
||||
}
|
||||
inline void GPU_setWINOUT(GPU* gpu, u8 val) { gpu->WINOUT = val&0x1F; gpu->WINOUT_SPECIAL = (val>>5)&1; }
|
||||
inline void GPU_setWINOBJ(GPU* gpu, u8 val) { gpu->WINOBJ = val&0x1F; gpu->WINOBJ_SPECIAL = (val>>5)&1; }
|
||||
|
||||
// Blending
|
||||
void SetupFinalPixelBlitter (GPU *gpu);
|
||||
#define GPU_setBLDCNT_LOW(gpu, val) {gpu->BLDCNT = (gpu->BLDCNT&0xFF00) | (val); SetupFinalPixelBlitter (gpu);}
|
||||
#define GPU_setBLDCNT_HIGH(gpu, val) {gpu->BLDCNT = (gpu->BLDCNT&0xFF) | (val<<8); SetupFinalPixelBlitter (gpu);}
|
||||
#define GPU_setBLDCNT(gpu, val) {gpu->BLDCNT = (val); SetupFinalPixelBlitter (gpu);}
|
||||
|
||||
|
||||
|
||||
#define GPU_setBLDY_EVY(gpu, val) {gpu->BLDY_EVY = ((val)&0x1f) > 16 ? 16 : ((val)&0x1f);}
|
||||
|
||||
//these arent needed right now since the values get poked into memory via default mmu handling and dispx_st
|
||||
//#define GPU_setBGxHOFS(bg, gpu, val) gpu->dispx_st->dispx_BGxOFS[bg].BGxHOFS = ((val) & 0x1FF)
|
||||
//#define GPU_setBGxVOFS(bg, gpu, val) gpu->dispx_st->dispx_BGxOFS[bg].BGxVOFS = ((val) & 0x1FF)
|
||||
|
||||
void gpu_SetRotateScreen(u16 angle);
|
||||
|
||||
//#undef FORCEINLINE
|
||||
//#define FORCEINLINE __forceinline
|
||||
|
||||
#endif
|
||||
|
||||
Executable
+750
@@ -0,0 +1,750 @@
|
||||
/*
|
||||
Copyright (C) 2006 yopyop
|
||||
Copyright (C) 2006-2015 DeSmuME team
|
||||
|
||||
This file is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This file is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with the this software. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "GPU_osd.h"
|
||||
#include "driver.h"
|
||||
#include "GPU.h"
|
||||
#include "mem.h"
|
||||
#include <string.h> //mem funcs
|
||||
#include <stdarg.h> //va_start, etc
|
||||
#include <sstream>
|
||||
#include <stdio.h>
|
||||
#include <time.h>
|
||||
#include <glib.h>
|
||||
#include "debug.h"
|
||||
|
||||
#include "aggdraw.h"
|
||||
#include "movie.h"
|
||||
#include "rtc.h"
|
||||
#include "NDSSystem.h"
|
||||
#include "mic.h"
|
||||
#include "saves.h"
|
||||
|
||||
bool HudEditorMode = false;
|
||||
OSDCLASS *osd = NULL;
|
||||
HudStruct Hud;
|
||||
|
||||
//contains a timer to be used for well-timed hud components
|
||||
static s64 hudTimer;
|
||||
|
||||
static void SetHudDummy (HudCoordinates *hud)
|
||||
{
|
||||
hud->x=666;
|
||||
hud->y=666;
|
||||
}
|
||||
|
||||
static bool IsHudDummy (HudCoordinates *hud)
|
||||
{
|
||||
return (hud->x == 666 && hud->y == 666);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
static T calcY(T y) // alters a GUI element y coordinate as necessary to obey swapScreens and singleScreen settings
|
||||
{
|
||||
if(osd->singleScreen)
|
||||
{
|
||||
if(y >= 192)
|
||||
y -= 192;
|
||||
if(osd->swapScreens)
|
||||
y += 192;
|
||||
}
|
||||
else if(osd->swapScreens)
|
||||
{
|
||||
if(y >= 192)
|
||||
y -= 192;
|
||||
else
|
||||
y += 192;
|
||||
}
|
||||
return y;
|
||||
}
|
||||
|
||||
void EditHud(s32 x, s32 y, HudStruct *hudstruct) {
|
||||
|
||||
u32 i = 0;
|
||||
|
||||
while (!IsHudDummy(&hudstruct->hud(i))) {
|
||||
HudCoordinates &hud = hudstruct->hud(i);
|
||||
|
||||
//reset
|
||||
if(!hud.clicked) {
|
||||
hud.storedx=0;
|
||||
hud.storedy=0;
|
||||
}
|
||||
|
||||
if((x >= hud.x && x <= hud.x + hud.xsize) &&
|
||||
(calcY(y) >= calcY(hud.y) && calcY(y) <= calcY(hud.y) + hud.ysize) && !hudstruct->clicked ) {
|
||||
|
||||
hud.clicked=1;
|
||||
hud.storedx = x - hud.x;
|
||||
hud.storedy = y - hud.y;
|
||||
}
|
||||
|
||||
if(hud.clicked) {
|
||||
hud.x = x - hud.storedx;
|
||||
hud.y = y - hud.storedy;
|
||||
}
|
||||
|
||||
//sanity checks
|
||||
if(hud.x < 0) hud.x = 0;
|
||||
if(hud.y < 0) hud.y = 0;
|
||||
if(hud.x > 245)hud.x = 245; //margins
|
||||
if(hud.y > 384-16)hud.y = 384-16;
|
||||
|
||||
if(hud.clicked)
|
||||
{
|
||||
hudstruct->clicked = true;
|
||||
break;//prevent items from grouping together
|
||||
}
|
||||
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
void HudClickRelease(HudStruct *hudstruct) {
|
||||
|
||||
u32 i = 0;
|
||||
|
||||
while (!IsHudDummy(&hudstruct->hud(i))) {
|
||||
HudCoordinates &hud = hudstruct->hud(i);
|
||||
hud.clicked=0;
|
||||
i++;
|
||||
}
|
||||
|
||||
hudstruct->clicked = false;
|
||||
}
|
||||
|
||||
void HudStruct::reset()
|
||||
{
|
||||
FpsDisplay.x=0;
|
||||
FpsDisplay.y=5;
|
||||
FpsDisplay.xsize=166;
|
||||
FpsDisplay.ysize=10;
|
||||
|
||||
FrameCounter.x=0;
|
||||
FrameCounter.y=25;
|
||||
FrameCounter.xsize=60;
|
||||
FrameCounter.ysize=10;
|
||||
|
||||
InputDisplay.x=0;
|
||||
InputDisplay.y=45;
|
||||
InputDisplay.xsize=220;
|
||||
InputDisplay.ysize=10;
|
||||
|
||||
GraphicalInputDisplay.x=8;
|
||||
GraphicalInputDisplay.y=328;
|
||||
GraphicalInputDisplay.xsize=102;
|
||||
GraphicalInputDisplay.ysize=50;
|
||||
|
||||
LagFrameCounter.x=0;
|
||||
LagFrameCounter.y=65;
|
||||
LagFrameCounter.xsize=30;
|
||||
LagFrameCounter.ysize=10;
|
||||
|
||||
Microphone.x=0;
|
||||
Microphone.y=85;
|
||||
Microphone.xsize=20;
|
||||
Microphone.ysize=10;
|
||||
|
||||
RTCDisplay.x=0;
|
||||
RTCDisplay.y=105;
|
||||
RTCDisplay.xsize=220;
|
||||
RTCDisplay.ysize=10;
|
||||
|
||||
SavestateSlots.x = 8;
|
||||
SavestateSlots.y = 160;
|
||||
SavestateSlots.xsize = 240;
|
||||
SavestateSlots.ysize = 24;
|
||||
|
||||
SetHudDummy(&Dummy);
|
||||
clicked = false;
|
||||
}
|
||||
|
||||
static void joyFill(int n) {
|
||||
|
||||
bool pressedForGame = NDS_getFinalUserInput().buttons.array[n];
|
||||
bool physicallyPressed = NDS_getRawUserInput().buttons.array[n];
|
||||
if(pressedForGame && physicallyPressed)
|
||||
aggDraw.hud->fillColor(0,0,0,255);
|
||||
else if(pressedForGame)
|
||||
aggDraw.hud->fillColor(255,0,0,255);
|
||||
else if(physicallyPressed)
|
||||
aggDraw.hud->fillColor(0,255,0,255);
|
||||
else
|
||||
aggDraw.hud->fillColor(255,255,255,255);
|
||||
}
|
||||
|
||||
static void joyEllipse(double ex, double ey, int xc, int yc, int x, int y, double ratio, double rad, int button) {
|
||||
|
||||
joyFill(button);
|
||||
aggDraw.hud->lineWidth(rad);
|
||||
aggDraw.hud->ellipse(x+((xc*ex)*ratio), y+((yc*ey)*ratio), rad*ratio, rad*ratio);
|
||||
}
|
||||
|
||||
static void joyRoundedRect(double x1, double y1, int x2, int y2, int alpha1, int alpha2, int button)
|
||||
{
|
||||
bool pressedForGame = NDS_getFinalUserInput().buttons.array[button];
|
||||
bool physicallyPressed = NDS_getRawUserInput().buttons.array[button];
|
||||
if(pressedForGame && physicallyPressed)
|
||||
aggDraw.hud->fillLinearGradient(x1,y1,x2,y2,agg::rgba8(0,0,0,alpha1), agg::rgba8(0,0,0,alpha2));
|
||||
else if(pressedForGame)
|
||||
aggDraw.hud->fillLinearGradient(x1,y1,x2,y2,agg::rgba8(255,0,0,alpha1), agg::rgba8(255,0,0,alpha2));
|
||||
else if(physicallyPressed)
|
||||
aggDraw.hud->fillLinearGradient(x1,y1,x2,y2,agg::rgba8(0,255,0,alpha1), agg::rgba8(0,255,0,alpha2));
|
||||
else
|
||||
return; //aggDraw.hud->fillLinearGradient(x1,y1,x2,y2,agg::rgba8(255,255,255,alpha1), agg::rgba8(255,255,255,alpha2));
|
||||
|
||||
aggDraw.hud->roundedRect(x1,y1,x2,y2,1);
|
||||
}
|
||||
|
||||
|
||||
static void drawPad(double x, double y, double ratio) {
|
||||
|
||||
// you might notice black/red/green colors used to show what buttons are pressed.
|
||||
// the logic is roughly:
|
||||
// RED == PAST (the button was held last frame)
|
||||
// GREEN == FUTURE (the button is physically held now)
|
||||
// BLACK == PRESENT (the button was held last frame and is still physically held now)
|
||||
|
||||
// aligning to odd half-pixel boundaries prevents agg2d from blurring thin straight lines
|
||||
x = floor(x) + 0.5;
|
||||
y = floor(calcY(y)) + 0.5;
|
||||
double xc = 41 - 0.5;
|
||||
double yc = 20 - 0.5;
|
||||
|
||||
aggDraw.hud->lineColor(128,128,128,255);
|
||||
|
||||
aggDraw.hud->fillLinearGradient(x, y, x+(xc*ratio), y+(yc*ratio), agg::rgba8(222,222,222,128), agg::rgba8(255,255,255,255));
|
||||
|
||||
aggDraw.hud->roundedRect (x, y, floor(x+(xc*ratio))+0.5, floor(y+(yc*ratio))+0.5, 1);
|
||||
|
||||
double screenLeft = x+(xc*.25*ratio);
|
||||
double screenTop = y+(yc*.1*ratio);
|
||||
double screenRight = x+(xc*.745*ratio);
|
||||
double screenBottom = y+(yc*.845*ratio);
|
||||
aggDraw.hud->fillLinearGradient(screenLeft, screenTop, screenRight, screenBottom, agg::rgba8(128,128,128,128), agg::rgba8(255,255,255,255));
|
||||
aggDraw.hud->roundedRect (screenLeft, screenTop, screenRight, screenBottom, 1);
|
||||
|
||||
|
||||
joyEllipse(.89,.45,xc,yc,x,y,ratio,1,6);//B
|
||||
joyEllipse(.89,.22,xc,yc,x,y,ratio,1,3);//X
|
||||
joyEllipse(.83,.34,xc,yc,x,y,ratio,1,4);//Y
|
||||
joyEllipse(.95,.34,xc,yc,x,y,ratio,1,5);//A
|
||||
joyEllipse(.82,.716,xc,yc,x,y,ratio,.5,7);//Start
|
||||
joyEllipse(.82,.842,xc,yc,x,y,ratio,.5,8);//Select
|
||||
|
||||
|
||||
double dpadPoints [][2] = {
|
||||
{.04,.33}, // top-left corner of left button
|
||||
{.08,.33},
|
||||
{.08,.24}, // top-left corner of up button
|
||||
{.13,.24}, // top-right corner of up button
|
||||
{.13,.33},
|
||||
{.17,.33}, // top-right corner of right button
|
||||
{.17,.43}, // bottom-right corner of right button
|
||||
{.13,.43},
|
||||
{.13,.516}, // bottom-right corner of down button
|
||||
{.08,.516}, // bottom-left corner of down button
|
||||
{.08,.43},
|
||||
{.04,.43}, // bottom-left corner of left button
|
||||
};
|
||||
static const int numdpadPoints = sizeof(dpadPoints)/sizeof(dpadPoints[0]);
|
||||
for(int i = 0; i < numdpadPoints; i++)
|
||||
{
|
||||
dpadPoints[i][0] = x+(xc*(dpadPoints[i][0]+.01)*ratio);
|
||||
dpadPoints[i][1] = y+(yc*(dpadPoints[i][1]+.00)*ratio);
|
||||
}
|
||||
|
||||
// dpad outline
|
||||
aggDraw.hud->fillColor(255,255,255,200);
|
||||
aggDraw.hud->polygon((double*)dpadPoints, numdpadPoints);
|
||||
|
||||
aggDraw.hud->noLine();
|
||||
|
||||
// left
|
||||
joyRoundedRect(dpadPoints[0][0], dpadPoints[0][1], dpadPoints[7][0], dpadPoints[7][1], 255, 0, 11);
|
||||
|
||||
// right
|
||||
joyRoundedRect(dpadPoints[1][0], dpadPoints[1][1], dpadPoints[6][0], dpadPoints[6][1], 0, 255, 12);
|
||||
|
||||
// up
|
||||
joyRoundedRect(dpadPoints[2][0], dpadPoints[2][1], dpadPoints[7][0], dpadPoints[7][1], 255, 0, 9);
|
||||
|
||||
// right
|
||||
joyRoundedRect(dpadPoints[1][0], dpadPoints[1][1], dpadPoints[8][0], dpadPoints[8][1], 0, 255, 10);
|
||||
|
||||
// left shoulder
|
||||
joyRoundedRect(x+(xc*.00*ratio), y+(yc*.00*ratio), x+(xc*.15*ratio), y+(yc*.07*ratio), 255, 200, 2);
|
||||
|
||||
// right shoulder
|
||||
joyRoundedRect(x+(xc*.85*ratio), y+(yc*.00*ratio), x+(xc*1.0*ratio), y+(yc*.07*ratio), 200, 255, 1);
|
||||
|
||||
// lid...
|
||||
joyRoundedRect(x+(xc*.4*ratio), y+(yc*.96*ratio), x+(xc*0.6*ratio), y+(yc*1.0*ratio), 200, 200, 13);
|
||||
|
||||
// touch pad
|
||||
{
|
||||
BOOL gameTouchOn = nds.isTouch;
|
||||
double gameTouchX = screenLeft+1 + (nds.scr_touchX * 0.0625) * (screenRight - screenLeft - 2) / 256.0;
|
||||
double gameTouchY = screenTop+1 + (nds.scr_touchY * 0.0625) * (screenBottom - screenTop - 2) / 192.0;
|
||||
bool physicalTouchOn = NDS_getRawUserInput().touch.isTouch;
|
||||
double physicalTouchX = screenLeft+1 + (NDS_getRawUserInput().touch.touchX * 0.0625) * (screenRight - screenLeft - 2) / 256.0;
|
||||
double physicalTouchY = screenTop+1 + (NDS_getRawUserInput().touch.touchY * 0.0625) * (screenBottom - screenTop - 2) / 192.0;
|
||||
if(gameTouchOn && physicalTouchOn && gameTouchX == physicalTouchX && gameTouchY == physicalTouchY)
|
||||
{
|
||||
aggDraw.hud->fillColor(0,0,0,255);
|
||||
aggDraw.hud->ellipse(gameTouchX, gameTouchY, ratio*0.37, ratio*0.37);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(physicalTouchOn)
|
||||
{
|
||||
aggDraw.hud->fillColor(0,0,0,128);
|
||||
aggDraw.hud->ellipse(physicalTouchX, physicalTouchY, ratio*0.5, ratio*0.5);
|
||||
aggDraw.hud->fillColor(0,255,0,255);
|
||||
aggDraw.hud->ellipse(physicalTouchX, physicalTouchY, ratio*0.37, ratio*0.37);
|
||||
}
|
||||
if(gameTouchOn)
|
||||
{
|
||||
aggDraw.hud->fillColor(255,0,0,255);
|
||||
aggDraw.hud->ellipse(gameTouchX, gameTouchY, ratio*0.37, ratio*0.37);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
struct TouchInfo{
|
||||
u16 X;
|
||||
u16 Y;
|
||||
};
|
||||
static int touchalpha[8]= {31, 63, 95, 127, 159, 191, 223, 255};
|
||||
static TouchInfo temptouch;
|
||||
static const bool touchshadow = false;//true; // sorry, it's cool but also distracting and looks cleaner with it off. maybe if it drew line segments between touch points instead of isolated crosses...
|
||||
static std::vector<TouchInfo> touch (8);
|
||||
|
||||
static void TextualInputDisplay() {
|
||||
|
||||
// drawing the whole string at once looks ugly
|
||||
// (because of variable width font and the "shadow" appearing over blank space)
|
||||
// and can't give us the color-coded effects we want anyway (see drawPad for info)
|
||||
|
||||
const UserButtons& gameButtons = NDS_getFinalUserInput().buttons;
|
||||
const UserButtons& physicalButtons = NDS_getRawUserInput().buttons;
|
||||
|
||||
double x = Hud.InputDisplay.x;
|
||||
|
||||
// from order FRLDUTSBAYXWEG where G is 0
|
||||
static const char* buttonChars = "<^>vABXYLRSsgf";
|
||||
static const int buttonIndex [14] = {11,9,12,10,5,6,3,4,2,1,7,8,0,13};
|
||||
for(int i = 0; i < 14; i++, x+=11.0)
|
||||
{
|
||||
bool pressedForGame = gameButtons.array[buttonIndex[i]];
|
||||
bool physicallyPressed = physicalButtons.array[buttonIndex[i]];
|
||||
if(pressedForGame && physicallyPressed)
|
||||
aggDraw.hud->lineColor(255,255,255,255);
|
||||
else if(pressedForGame)
|
||||
aggDraw.hud->lineColor(255,48,48,255);
|
||||
else if(physicallyPressed)
|
||||
aggDraw.hud->lineColor(0,192,0,255);
|
||||
else
|
||||
continue;
|
||||
|
||||
// cast from char to std::string is a bit awkward
|
||||
std::string str(buttonChars+i, 2);
|
||||
str[1] = '\0';
|
||||
|
||||
aggDraw.hud->renderTextDropshadowed(x, calcY(Hud.InputDisplay.y), str);
|
||||
}
|
||||
|
||||
// touch pad
|
||||
{
|
||||
char str [32];
|
||||
BOOL gameTouchOn = nds.isTouch;
|
||||
int gameTouchX = nds.adc_touchX >> 4;
|
||||
int gameTouchY = nds.adc_touchY >> 4;
|
||||
bool physicalTouchOn = NDS_getRawUserInput().touch.isTouch;
|
||||
int physicalTouchX = NDS_getRawUserInput().touch.touchX >> 4;
|
||||
int physicalTouchY = NDS_getRawUserInput().touch.touchY >> 4;
|
||||
if(gameTouchOn && physicalTouchOn && gameTouchX == physicalTouchX && gameTouchY == physicalTouchY)
|
||||
{
|
||||
sprintf(str, "%d,%d", gameTouchX, gameTouchY);
|
||||
aggDraw.hud->lineColor(255,255,255,255);
|
||||
aggDraw.hud->renderTextDropshadowed(x, calcY(Hud.InputDisplay.y), str);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(gameTouchOn)
|
||||
{
|
||||
sprintf(str, "%d,%d", gameTouchX, gameTouchY);
|
||||
aggDraw.hud->lineColor(255,48,48,255);
|
||||
aggDraw.hud->renderTextDropshadowed(x, calcY(Hud.InputDisplay.y)-(physicalTouchOn?8:0), str);
|
||||
}
|
||||
if(physicalTouchOn)
|
||||
{
|
||||
sprintf(str, "%d,%d", physicalTouchX, physicalTouchY);
|
||||
aggDraw.hud->lineColor(0,192,0,255);
|
||||
aggDraw.hud->renderTextDropshadowed(x, calcY(Hud.InputDisplay.y)+(gameTouchOn?8:0), str);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void TouchDisplay() {
|
||||
// note: calcY should not be used in this function.
|
||||
aggDraw.hud->lineWidth(1.0);
|
||||
|
||||
temptouch.X = NDS_getRawUserInput().touch.touchX >> 4;
|
||||
temptouch.Y = NDS_getRawUserInput().touch.touchY >> 4;
|
||||
|
||||
if(touchshadow) {
|
||||
|
||||
touch.push_back(temptouch);
|
||||
if(touch.size() > 8) touch.erase(touch.begin());
|
||||
|
||||
for (int i = 0; i < 8; i++) {
|
||||
temptouch = touch[i];
|
||||
if(temptouch.X != 0 || temptouch.Y != 0) {
|
||||
aggDraw.hud->lineColor(0, 255, 0, touchalpha[i]);
|
||||
aggDraw.hud->line(temptouch.X - 256, temptouch.Y + 192, temptouch.X + 256, temptouch.Y + 192); //horiz
|
||||
aggDraw.hud->line(temptouch.X, temptouch.Y - 256, temptouch.X, temptouch.Y + 384); //vert
|
||||
aggDraw.hud->fillColor(0, 0, 0, touchalpha[i]);
|
||||
aggDraw.hud->rectangle(temptouch.X-1, temptouch.Y + 192-1, temptouch.X+1, temptouch.Y + 192+1);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
if(NDS_getRawUserInput().touch.isTouch) {
|
||||
aggDraw.hud->lineColor(0, 255, 0, 128);
|
||||
aggDraw.hud->line(temptouch.X - 256, temptouch.Y + 192, temptouch.X + 256, temptouch.Y + 192); //horiz
|
||||
aggDraw.hud->line(temptouch.X, temptouch.Y - 256, temptouch.X, temptouch.Y + 384); //vert
|
||||
}
|
||||
|
||||
if(nds.isTouch)
|
||||
{
|
||||
temptouch.X = nds.scr_touchX / 16;
|
||||
temptouch.Y = nds.scr_touchY / 16;
|
||||
aggDraw.hud->lineColor(255, 0, 0, 128);
|
||||
aggDraw.hud->line(temptouch.X - 256, temptouch.Y + 192, temptouch.X + 256, temptouch.Y + 192); //horiz
|
||||
aggDraw.hud->line(temptouch.X, temptouch.Y - 256, temptouch.X, temptouch.Y + 384); //vert
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static int previousslot = 0;
|
||||
static char number[10];
|
||||
static s64 slotTimer=0;
|
||||
|
||||
static void DrawStateSlots(){
|
||||
|
||||
const int yloc = calcY(Hud.SavestateSlots.y); //160
|
||||
const int xloc = Hud.SavestateSlots.x; //8
|
||||
|
||||
s64 fadecounter = 512 - (hudTimer-slotTimer)/4; //change constant to alter fade speed
|
||||
if(fadecounter < 1) fadecounter = 0;
|
||||
if(fadecounter>255) fadecounter = 255;
|
||||
|
||||
int alpha = (int)fadecounter;
|
||||
if(HudEditorMode)
|
||||
alpha = 255;
|
||||
|
||||
if(alpha!=0)
|
||||
{
|
||||
aggDraw.hud->lineWidth(1.0);
|
||||
aggDraw.hud->lineColor(0, 0, 0, alpha);
|
||||
aggDraw.hud->fillColor(255, 255, 255, alpha);
|
||||
|
||||
for ( int i = 0, xpos=0; i < 10; xpos=xpos+24) {
|
||||
|
||||
int yheight=0;
|
||||
|
||||
aggDraw.hud->fillLinearGradient(xloc + xpos, yloc - yheight, xloc + 22 + xpos, yloc + 20 + yheight+20, agg::rgba8(100,200,255,alpha), agg::rgba8(255,255,255,0));
|
||||
|
||||
if(lastSaveState == i) {
|
||||
yheight = 5;
|
||||
aggDraw.hud->fillLinearGradient(xloc + xpos, yloc - yheight, 22 + xloc + xpos, yloc + 20 + yheight+20, agg::rgba8(100,255,255,alpha), agg::rgba8(255,255,255,0));
|
||||
}
|
||||
|
||||
aggDraw.hud->rectangle(xloc + xpos , yloc - yheight, xloc + 22 + xpos , yloc + 20 + yheight);
|
||||
snprintf(number, 10, "%d", i);
|
||||
aggDraw.hud->renderText(xloc + 1 + xpos + 4, yloc+4, std::string(number));
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
if(lastSaveState != previousslot)
|
||||
slotTimer = hudTimer;
|
||||
|
||||
previousslot = lastSaveState;
|
||||
}
|
||||
|
||||
static void DrawEditableElementIndicators()
|
||||
{
|
||||
u32 i = 0;
|
||||
while (!IsHudDummy(&Hud.hud(i))) {
|
||||
HudCoordinates &hud = Hud.hud(i);
|
||||
aggDraw.hud->fillColor(0,0,0,0);
|
||||
aggDraw.hud->lineColor(0,0,0,64);
|
||||
aggDraw.hud->lineWidth(2.0);
|
||||
aggDraw.hud->rectangle(hud.x,calcY(hud.y),hud.x+hud.xsize+1.0,calcY(hud.y)+hud.ysize+1.0);
|
||||
aggDraw.hud->lineColor(255,hud.clicked?127:255,0,255);
|
||||
aggDraw.hud->lineWidth(1.0);
|
||||
aggDraw.hud->rectangle(hud.x-0.5,calcY(hud.y)-0.5,hud.x+hud.xsize+0.5,calcY(hud.y)+hud.ysize+0.5);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void DrawHUD()
|
||||
{
|
||||
GTimeVal time;
|
||||
g_get_current_time(&time);
|
||||
hudTimer = ((s64)time.tv_sec * 1000) + ((s64)time.tv_usec/1000);
|
||||
|
||||
if (HudEditorMode)
|
||||
{
|
||||
DrawEditableElementIndicators();
|
||||
}
|
||||
|
||||
if (CommonSettings.hud.ShowInputDisplay)
|
||||
{
|
||||
TextualInputDisplay();
|
||||
TouchDisplay();
|
||||
}
|
||||
|
||||
if (CommonSettings.hud.FpsDisplay)
|
||||
{
|
||||
osd->addFixed(Hud.FpsDisplay.x, Hud.FpsDisplay.y, "Fps:%02d/%02d (%02d%%/%02d%%)%s", Hud.fps, Hud.fps3d, Hud.cpuload[0], Hud.cpuload[1], driver->EMU_IsEmulationPaused() ? " (paused)" : "");
|
||||
}
|
||||
|
||||
if (CommonSettings.hud.FrameCounterDisplay)
|
||||
{
|
||||
if(movieMode == MOVIEMODE_RECORD)
|
||||
osd->addFixed(Hud.FrameCounter.x, Hud.FrameCounter.y, "%d",currFrameCounter);
|
||||
else if (movieMode == MOVIEMODE_PLAY)
|
||||
osd->addFixed(Hud.FrameCounter.x, Hud.FrameCounter.y, "%d/%d",currFrameCounter,currMovieData.records.size());
|
||||
else if (movieMode == MOVIEMODE_FINISHED)
|
||||
osd->addFixed(Hud.FrameCounter.x, Hud.FrameCounter.y, "%d/%d (finished)",currFrameCounter,currMovieData.records.size());
|
||||
else
|
||||
osd->addFixed(Hud.FrameCounter.x, Hud.FrameCounter.y, "%d (no movie)",currFrameCounter);
|
||||
}
|
||||
|
||||
if (CommonSettings.hud.ShowLagFrameCounter)
|
||||
{
|
||||
osd->addFixed(Hud.LagFrameCounter.x, Hud.LagFrameCounter.y, "%d",TotalLagFrames);
|
||||
}
|
||||
|
||||
if (CommonSettings.hud.ShowGraphicalInputDisplay)
|
||||
{
|
||||
drawPad(Hud.GraphicalInputDisplay.x, Hud.GraphicalInputDisplay.y, 2.5);
|
||||
}
|
||||
|
||||
#if defined(WIN32) && !defined(DESMUME_QT)
|
||||
if (CommonSettings.hud.ShowMicrophone)
|
||||
{
|
||||
osd->addFixed(Hud.Microphone.x, Hud.Microphone.y, "%03d [%07d]",MicDisplay, Hud.cpuloopIterationCount);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (CommonSettings.hud.ShowRTC)
|
||||
{
|
||||
DateTime tm = rtcGetTime();
|
||||
static const char *wday[] = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" };
|
||||
osd->addFixed(Hud.RTCDisplay.x, Hud.RTCDisplay.y, "%04d-%03s-%02d %s %02d:%02d:%02d", tm.get_Year(), DateTime::GetNameOfMonth(tm.get_Month()), tm.get_Day(), wday[tm.get_DayOfWeek()%7], tm.get_Hour(), tm.get_Minute(), tm.get_Second());
|
||||
}
|
||||
|
||||
DrawStateSlots();
|
||||
}
|
||||
|
||||
|
||||
|
||||
OSDCLASS::OSDCLASS(u8 core)
|
||||
{
|
||||
memset(name,0,7);
|
||||
|
||||
mode=core;
|
||||
offset=0;
|
||||
|
||||
lastLineText=0;
|
||||
lineText_x = 5;
|
||||
lineText_y = 120;
|
||||
lineText_color = AggColor(255, 255, 255);
|
||||
for (int i=0; i < OSD_MAX_LINES+1; i++)
|
||||
{
|
||||
lineText[i] = new char[1024];
|
||||
memset(lineText[i], 0, 1024);
|
||||
lineTimer[i] = 0;
|
||||
lineColor[i] = lineText_color;
|
||||
}
|
||||
|
||||
rotAngle = 0;
|
||||
|
||||
singleScreen = false;
|
||||
swapScreens = false;
|
||||
|
||||
needUpdate = false;
|
||||
|
||||
if (core==0)
|
||||
strcpy(name,"Core A");
|
||||
else
|
||||
if (core==1)
|
||||
strcpy(name,"Core B");
|
||||
else
|
||||
{
|
||||
strcpy(name,"Main");
|
||||
mode=255;
|
||||
}
|
||||
|
||||
//border(false);
|
||||
|
||||
LOG("OSD_Init (%s)\n",name);
|
||||
}
|
||||
|
||||
OSDCLASS::~OSDCLASS()
|
||||
{
|
||||
LOG("OSD_Deinit (%s)\n",name);
|
||||
|
||||
for (int i=0; i < OSD_MAX_LINES+1; i++)
|
||||
{
|
||||
if (lineText[i])
|
||||
delete [] lineText[i];
|
||||
lineText[i] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void OSDCLASS::setOffset(u16 ofs)
|
||||
{
|
||||
offset=ofs;
|
||||
}
|
||||
|
||||
void OSDCLASS::setRotate(u16 angle)
|
||||
{
|
||||
rotAngle = angle;
|
||||
}
|
||||
|
||||
void OSDCLASS::clear()
|
||||
{
|
||||
needUpdate=false;
|
||||
}
|
||||
|
||||
bool OSDCLASS::checkTimers()
|
||||
{
|
||||
if (lastLineText == 0) return false;
|
||||
|
||||
time_t tmp_time = time(NULL);
|
||||
|
||||
for (int i=0; i < lastLineText; i++)
|
||||
{
|
||||
if (tmp_time > (lineTimer[i] + OSD_TIMER_SECS) )
|
||||
{
|
||||
if (i < lastLineText)
|
||||
{
|
||||
for (int j=i; j < lastLineText; j++)
|
||||
{
|
||||
strcpy(lineText[j], lineText[j+1]);
|
||||
lineTimer[j] = lineTimer[j+1];
|
||||
lineColor[j] = lineColor[j+1];
|
||||
}
|
||||
}
|
||||
lineTimer[lastLineText] = 0;
|
||||
lastLineText--;
|
||||
if (lastLineText == 0) return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void OSDCLASS::update()
|
||||
{
|
||||
if ( (!needUpdate) && (!lastLineText) ) return; // don't update if buffer empty (speed up)
|
||||
if (lastLineText)
|
||||
{
|
||||
if (checkTimers())
|
||||
{
|
||||
for (int i=0; i < lastLineText; i++)
|
||||
{
|
||||
aggDraw.hud->lineColor(lineColor[i]);
|
||||
aggDraw.hud->renderTextDropshadowed(lineText_x,lineText_y+(i*16),lineText[i]);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!needUpdate) return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void OSDCLASS::setListCoord(u16 x, u16 y)
|
||||
{
|
||||
lineText_x = x;
|
||||
lineText_y = y;
|
||||
}
|
||||
|
||||
void OSDCLASS::setLineColor(u8 r=255, u8 g=255, u8 b=255)
|
||||
{
|
||||
lineText_color = AggColor(r,g,b);
|
||||
}
|
||||
|
||||
void OSDCLASS::addLine(const char *fmt, ...)
|
||||
{
|
||||
va_list list;
|
||||
|
||||
if (lastLineText > OSD_MAX_LINES) lastLineText = OSD_MAX_LINES;
|
||||
if (lastLineText == OSD_MAX_LINES) // full
|
||||
{
|
||||
lastLineText--;
|
||||
for (int j=0; j < lastLineText; j++)
|
||||
{
|
||||
strcpy(lineText[j], lineText[j+1]);
|
||||
lineTimer[j] = lineTimer[j+1];
|
||||
lineColor[j] = lineColor[j+1];
|
||||
}
|
||||
}
|
||||
|
||||
va_start(list,fmt);
|
||||
#if defined(_MSC_VER) || defined(__INTEL_COMPILER)
|
||||
_vsnprintf(lineText[lastLineText],1023,fmt,list);
|
||||
#else
|
||||
vsnprintf(lineText[lastLineText],1023,fmt,list);
|
||||
#endif
|
||||
va_end(list);
|
||||
lineColor[lastLineText] = lineText_color;
|
||||
lineTimer[lastLineText] = time(NULL);
|
||||
needUpdate = true;
|
||||
|
||||
lastLineText++;
|
||||
}
|
||||
|
||||
void OSDCLASS::addFixed(u16 x, u16 y, const char *fmt, ...)
|
||||
{
|
||||
va_list list;
|
||||
char msg[1024];
|
||||
|
||||
va_start(list,fmt);
|
||||
vsnprintf(msg,1023,fmt,list);
|
||||
va_end(list);
|
||||
|
||||
aggDraw.hud->lineColor(255,255,255);
|
||||
aggDraw.hud->renderTextDropshadowed(x,calcY(y),msg);
|
||||
|
||||
needUpdate = true;
|
||||
}
|
||||
|
||||
void OSDCLASS::border(bool enabled)
|
||||
{
|
||||
//render51.setTextBoxBorder(enabled);
|
||||
}
|
||||
Executable
+141
@@ -0,0 +1,141 @@
|
||||
/*
|
||||
Copyright (C) 2006 yopyop
|
||||
Copyright (C) 2008-2012 DeSmuME team
|
||||
|
||||
This file is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This file is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with the this software. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __GPU_OSD_
|
||||
#define __GPU_OSD_
|
||||
|
||||
#include "types.h"
|
||||
|
||||
#ifdef HAVE_LIBAGG
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "aggdraw.h"
|
||||
|
||||
#define OSD_MAX_LINES 4
|
||||
#define OSD_TIMER_SECS 2
|
||||
|
||||
|
||||
struct HudCoordinates{
|
||||
int x;
|
||||
int y;
|
||||
int xsize;
|
||||
int ysize;
|
||||
int storedx;
|
||||
int storedy;
|
||||
int clicked;
|
||||
};
|
||||
|
||||
struct HudStruct
|
||||
{
|
||||
public:
|
||||
HudStruct()
|
||||
{
|
||||
resetTransient();
|
||||
}
|
||||
|
||||
void resetTransient()
|
||||
{
|
||||
fps = 0;
|
||||
fps3d = 0;
|
||||
cpuload[0] = cpuload[1] = 0;
|
||||
cpuloopIterationCount = 0;
|
||||
clicked = false;
|
||||
}
|
||||
|
||||
HudCoordinates SavestateSlots;
|
||||
HudCoordinates FpsDisplay;
|
||||
HudCoordinates FrameCounter;
|
||||
HudCoordinates InputDisplay;
|
||||
HudCoordinates GraphicalInputDisplay;
|
||||
HudCoordinates LagFrameCounter;
|
||||
HudCoordinates Microphone;
|
||||
HudCoordinates RTCDisplay;
|
||||
HudCoordinates Dummy;
|
||||
|
||||
HudCoordinates &hud(int i) { return ((HudCoordinates*)this)[i]; }
|
||||
void reset();
|
||||
|
||||
int fps, fps3d, cpuload[2], cpuloopIterationCount;
|
||||
bool clicked;
|
||||
};
|
||||
|
||||
void EditHud(s32 x, s32 y, HudStruct *hudstruct);
|
||||
void HudClickRelease(HudStruct *hudstruct);
|
||||
|
||||
void DrawHUD();
|
||||
|
||||
extern HudStruct Hud;
|
||||
extern bool HudEditorMode;
|
||||
|
||||
class OSDCLASS
|
||||
{
|
||||
private:
|
||||
u64 offset;
|
||||
u8 mode;
|
||||
|
||||
u16 rotAngle;
|
||||
|
||||
u16 lineText_x;
|
||||
u16 lineText_y;
|
||||
AggColor lineText_color;
|
||||
u8 lastLineText;
|
||||
char *lineText[OSD_MAX_LINES+1];
|
||||
time_t lineTimer[OSD_MAX_LINES+1];
|
||||
AggColor lineColor[OSD_MAX_LINES+1];
|
||||
|
||||
bool needUpdate;
|
||||
|
||||
bool checkTimers();
|
||||
|
||||
public:
|
||||
char name[7]; // for debuging
|
||||
bool singleScreen;
|
||||
bool swapScreens;
|
||||
|
||||
OSDCLASS(u8 core);
|
||||
~OSDCLASS();
|
||||
|
||||
void setOffset(u16 ofs);
|
||||
void setRotate(u16 angle);
|
||||
void update();
|
||||
void clear();
|
||||
void setListCoord(u16 x, u16 y);
|
||||
void setLineColor(u8 r, u8 b, u8 g);
|
||||
void addLine(const char *fmt, ...);
|
||||
void addFixed(u16 x, u16 y, const char *fmt, ...);
|
||||
void border(bool enabled);
|
||||
};
|
||||
|
||||
extern OSDCLASS *osd;
|
||||
#else /* HAVE_LIBAGG */
|
||||
void DrawHUD();
|
||||
|
||||
class OSDCLASS {
|
||||
public:
|
||||
OSDCLASS(u8 core);
|
||||
~OSDCLASS();
|
||||
void update();
|
||||
void clear();
|
||||
void setLineColor(u8 r, u8 b, u8 g);
|
||||
void addLine(const char *fmt, ...);
|
||||
};
|
||||
|
||||
extern OSDCLASS *osd;
|
||||
#endif
|
||||
#endif
|
||||
Executable
+30
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
Copyright (C) 2010 DeSmumE team
|
||||
|
||||
This file is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This file is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with the this software. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "types.h"
|
||||
#include "GPU_osd.h"
|
||||
|
||||
OSDCLASS *osd;
|
||||
|
||||
OSDCLASS::OSDCLASS(u8 core) {}
|
||||
OSDCLASS::~OSDCLASS() {}
|
||||
void OSDCLASS::update() {}
|
||||
void OSDCLASS::clear() {}
|
||||
void OSDCLASS::setLineColor(u8 r, u8 b, u8 g) {}
|
||||
void OSDCLASS::addLine(const char *fmt, ...) {}
|
||||
|
||||
void DrawHUD() {}
|
||||
Executable
+5751
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,963 @@
|
||||
/*
|
||||
Copyright (C) 2006 yopyop
|
||||
Copyright (C) 2007 shash
|
||||
Copyright (C) 2007-2015 DeSmuME team
|
||||
|
||||
This file is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This file is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with the this software. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef MMU_H
|
||||
#define MMU_H
|
||||
|
||||
#include "debug.h"
|
||||
#include "firmware.h"
|
||||
#include "mc.h"
|
||||
#include "mem.h"
|
||||
|
||||
#ifdef HAVE_LUA
|
||||
#include "lua-engine.h"
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_JIT
|
||||
#include "arm_jit.h"
|
||||
#endif
|
||||
|
||||
#define ARMCPU_ARM7 1
|
||||
#define ARMCPU_ARM9 0
|
||||
#define ARMPROC (PROCNUM ? NDS_ARM7:NDS_ARM9)
|
||||
|
||||
class EMUFILE;
|
||||
|
||||
typedef const u8 TWaitState;
|
||||
|
||||
enum EDMAMode
|
||||
{
|
||||
EDMAMode_Immediate = 0,
|
||||
EDMAMode_VBlank = 1,
|
||||
EDMAMode_HBlank = 2,
|
||||
EDMAMode_HStart = 3,
|
||||
EDMAMode_MemDisplay = 4,
|
||||
EDMAMode_Card = 5,
|
||||
EDMAMode_GBASlot = 6,
|
||||
EDMAMode_GXFifo = 7,
|
||||
EDMAMode7_Wifi = 8,
|
||||
EDMAMode7_GBASlot = 9,
|
||||
};
|
||||
|
||||
enum EDMABitWidth
|
||||
{
|
||||
EDMABitWidth_16 = 0,
|
||||
EDMABitWidth_32 = 1
|
||||
};
|
||||
|
||||
enum EDMASourceUpdate
|
||||
{
|
||||
EDMASourceUpdate_Increment = 0,
|
||||
EDMASourceUpdate_Decrement = 1,
|
||||
EDMASourceUpdate_Fixed = 2,
|
||||
EDMASourceUpdate_Invalid = 3,
|
||||
};
|
||||
|
||||
enum EDMADestinationUpdate
|
||||
{
|
||||
EDMADestinationUpdate_Increment = 0,
|
||||
EDMADestinationUpdate_Decrement = 1,
|
||||
EDMADestinationUpdate_Fixed = 2,
|
||||
EDMADestinationUpdate_IncrementReload = 3,
|
||||
};
|
||||
|
||||
//TODO
|
||||
//n.b. this may be a bad idea, for complex registers like the dma control register.
|
||||
//we need to know exactly what part was written to, instead of assuming all 32bits were written.
|
||||
class TRegister_32
|
||||
{
|
||||
public:
|
||||
virtual u32 read32() = 0;
|
||||
virtual void write32(const u32 val) = 0;
|
||||
void write(const int size, const u32 adr, const u32 val) {
|
||||
if(size==32) write32(val);
|
||||
else {
|
||||
const u32 offset = adr&3;
|
||||
if(size==8) {
|
||||
printf("WARNING! 8BIT DMA ACCESS\n");
|
||||
u32 mask = 0xFF<<(offset<<3);
|
||||
write32((read32()&~mask)|(val<<(offset<<3)));
|
||||
}
|
||||
else if(size==16) {
|
||||
u32 mask = 0xFFFF<<(offset<<3);
|
||||
write32((read32()&~mask)|(val<<(offset<<3)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
u32 read(const int size, const u32 adr)
|
||||
{
|
||||
if(size==32) return read32();
|
||||
else {
|
||||
const u32 offset = adr&3;
|
||||
if(size==8) { printf("WARNING! 8BIT DMA ACCESS\n"); return (read32()>>(offset<<3))&0xFF; }
|
||||
else return (read32()>>(offset<<3))&0xFFFF;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
struct TGXSTAT : public TRegister_32
|
||||
{
|
||||
TGXSTAT() {
|
||||
gxfifo_irq = se = tr = tb = sb = 0;
|
||||
fifo_empty = true;
|
||||
fifo_low = false;
|
||||
}
|
||||
u8 tb; //test busy
|
||||
u8 tr; //test result
|
||||
u8 se; //stack error
|
||||
u8 sb; //stack busy
|
||||
u8 gxfifo_irq; //irq configuration
|
||||
|
||||
bool fifo_empty, fifo_low;
|
||||
|
||||
virtual u32 read32();
|
||||
virtual void write32(const u32 val);
|
||||
|
||||
void savestate(EMUFILE *f);
|
||||
bool loadstate(EMUFILE *f);
|
||||
};
|
||||
|
||||
void triggerDma(EDMAMode mode);
|
||||
|
||||
class DivController
|
||||
{
|
||||
public:
|
||||
DivController()
|
||||
: mode(0), busy(0)
|
||||
{}
|
||||
void exec();
|
||||
u8 mode, busy, div0;
|
||||
u16 read16() { return mode|(busy<<15)|(div0<<14); }
|
||||
void write16(u16 val) {
|
||||
mode = val&3;
|
||||
//todo - do we clear the div0 flag here or is that strictly done by the divider unit?
|
||||
}
|
||||
void savestate(EMUFILE* os);
|
||||
bool loadstate(EMUFILE* is, int version);
|
||||
};
|
||||
|
||||
class SqrtController
|
||||
{
|
||||
public:
|
||||
SqrtController()
|
||||
: mode(0), busy(0)
|
||||
{}
|
||||
void exec();
|
||||
u8 mode, busy;
|
||||
u16 read16() { return mode|(busy<<15); }
|
||||
void write16(u16 val) { mode = val&1; }
|
||||
void savestate(EMUFILE* os);
|
||||
bool loadstate(EMUFILE* is, int version);
|
||||
};
|
||||
|
||||
|
||||
class DmaController
|
||||
{
|
||||
public:
|
||||
u8 enable, irq, repeatMode, _startmode;
|
||||
u8 userEnable;
|
||||
u32 wordcount;
|
||||
EDMAMode startmode;
|
||||
EDMABitWidth bitWidth;
|
||||
EDMASourceUpdate sar;
|
||||
EDMADestinationUpdate dar;
|
||||
u32 saddr, daddr;
|
||||
u32 saddr_user, daddr_user;
|
||||
|
||||
//indicates whether the dma needs to be checked for triggering
|
||||
BOOL dmaCheck;
|
||||
|
||||
//indicates whether the dma right now is logically running
|
||||
//(though for now we copy all the data when it triggers)
|
||||
BOOL running;
|
||||
|
||||
BOOL paused;
|
||||
|
||||
//this flag will sometimes be set when a start condition is triggered
|
||||
//other conditions may be automatically triggered based on scanning conditions
|
||||
BOOL triggered;
|
||||
|
||||
u64 nextEvent;
|
||||
|
||||
int procnum, chan;
|
||||
|
||||
void savestate(EMUFILE *f);
|
||||
bool loadstate(EMUFILE *f);
|
||||
|
||||
void exec();
|
||||
template<int PROCNUM> void doCopy();
|
||||
void doPause();
|
||||
void doStop();
|
||||
void doSchedule();
|
||||
void tryTrigger(EDMAMode mode);
|
||||
|
||||
DmaController() :
|
||||
enable(0), irq(0), repeatMode(0), _startmode(0),
|
||||
wordcount(0), startmode(EDMAMode_Immediate),
|
||||
bitWidth(EDMABitWidth_16),
|
||||
sar(EDMASourceUpdate_Increment), dar(EDMADestinationUpdate_Increment),
|
||||
//if saddr isnt cleared then rings of fate will trigger copy protection
|
||||
//by inspecting dma3 saddr when it boots
|
||||
saddr(0), daddr(0),
|
||||
saddr_user(0), daddr_user(0),
|
||||
dmaCheck(FALSE),
|
||||
running(FALSE),
|
||||
paused(FALSE),
|
||||
triggered(FALSE),
|
||||
nextEvent(0),
|
||||
sad(&saddr_user),
|
||||
dad(&daddr_user)
|
||||
{
|
||||
sad.controller = this;
|
||||
dad.controller = this;
|
||||
ctrl.controller = this;
|
||||
regs[0] = &sad;
|
||||
regs[1] = &dad;
|
||||
regs[2] = &ctrl;
|
||||
}
|
||||
|
||||
class AddressRegister : public TRegister_32 {
|
||||
public:
|
||||
//we pass in a pointer to the controller here so we can alert it if anything changes
|
||||
DmaController* controller;
|
||||
u32 * const ptr;
|
||||
AddressRegister(u32* _ptr)
|
||||
: ptr(_ptr)
|
||||
{}
|
||||
virtual u32 read32() {
|
||||
return *ptr;
|
||||
}
|
||||
virtual void write32(const u32 val) {
|
||||
*ptr = val;
|
||||
}
|
||||
};
|
||||
|
||||
class ControlRegister : public TRegister_32 {
|
||||
public:
|
||||
//we pass in a pointer to the controller here so we can alert it if anything changes
|
||||
DmaController* controller;
|
||||
ControlRegister() {}
|
||||
virtual u32 read32() {
|
||||
return controller->read32();
|
||||
}
|
||||
virtual void write32(const u32 val) {
|
||||
return controller->write32(val);
|
||||
}
|
||||
};
|
||||
|
||||
AddressRegister sad, dad;
|
||||
ControlRegister ctrl;
|
||||
TRegister_32* regs[3];
|
||||
|
||||
void write32(const u32 val);
|
||||
u32 read32();
|
||||
|
||||
};
|
||||
|
||||
enum eCardMode
|
||||
{
|
||||
//when the GC system is first booted up, the protocol is in raw mode
|
||||
eCardMode_RAW = 0,
|
||||
|
||||
//an intermediate stage during the protocol bootup process. commands are KEY1 encrypted.
|
||||
eCardMode_KEY1,
|
||||
|
||||
//an intermediate stage during the protocol bootup process. commands are KEY1 encrypted, while replies are KEY2 encrypted
|
||||
eCardMode_KEY2,
|
||||
|
||||
//the final stage of the protocol bootup process. "main data load" mode. commands are KEY2 encrypted, and replies are KEY2 encrypted.
|
||||
//optionally, according to some flag we havent designed yet but should probably go in GCBUS_Controller, the whole KEY2 part can be bypassed
|
||||
//(this is typical when skipping the firmware boot process)
|
||||
eCardMode_NORMAL,
|
||||
|
||||
//help fix to 32bit
|
||||
eCardMode_Pad = 0xFFFFFFFF
|
||||
};
|
||||
|
||||
//#define GCLOG(...) printf(__VA_ARGS__);
|
||||
#define GCLOG(...)
|
||||
|
||||
void MMU_GC_endTransfer(u32 PROCNUM);
|
||||
|
||||
struct GC_Command
|
||||
{
|
||||
u8 bytes[8];
|
||||
|
||||
void print();
|
||||
void toCryptoBuffer(u32 buf[2]);
|
||||
void fromCryptoBuffer(u32 buf[2]);
|
||||
};
|
||||
|
||||
//should rather be known as GCBUS controller, or somesuch
|
||||
struct GCBUS_Controller
|
||||
{
|
||||
int transfer_count;
|
||||
eCardMode mode; //probably only one of these
|
||||
};
|
||||
|
||||
#define DUP2(x) x, x
|
||||
#define DUP4(x) x, x, x, x
|
||||
#define DUP8(x) x, x, x, x, x, x, x, x
|
||||
#define DUP16(x) x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x
|
||||
|
||||
struct MMU_struct
|
||||
{
|
||||
//ARM9 mem
|
||||
u8 ARM9_ITCM[0x8000];
|
||||
u8 ARM9_DTCM[0x4000];
|
||||
|
||||
//u8 MAIN_MEM[4*1024*1024]; //expanded from 4MB to 8MB to support debug consoles
|
||||
//u8 MAIN_MEM[8*1024*1024]; //expanded from 8MB to 16MB to support dsi
|
||||
u8 MAIN_MEM[16*1024*1024]; //expanded from 8MB to 16MB to support dsi
|
||||
u8 ARM9_REG[0x1000000]; //this variable is evil and should be removed by correctly emulating all registers.
|
||||
u8 ARM9_BIOS[0x8000];
|
||||
u8 ARM9_VMEM[0x800];
|
||||
|
||||
#include "PACKED.h"
|
||||
struct {
|
||||
u8 ARM9_LCD[0xA4000];
|
||||
//an extra 128KB for blank memory, directly after arm9_lcd, so that
|
||||
//we can easily map things to the end of arm9_lcd to represent
|
||||
//an unmapped state
|
||||
u8 blank_memory[0x20000];
|
||||
};
|
||||
#include "PACKED_END.h"
|
||||
|
||||
u8 ARM9_OAM[0x800];
|
||||
|
||||
u8* ExtPal[2][4];
|
||||
u8* ObjExtPal[2][2];
|
||||
|
||||
struct TextureInfo {
|
||||
u8* texPalSlot[6];
|
||||
u8* textureSlotAddr[4];
|
||||
} texInfo;
|
||||
|
||||
//ARM7 mem
|
||||
u8 ARM7_BIOS[0x4000];
|
||||
u8 ARM7_ERAM[0x10000]; //64KB of exclusive WRAM
|
||||
u8 ARM7_REG[0x10000];
|
||||
u8 ARM7_WIRAM[0x10000]; //WIFI ram
|
||||
|
||||
// VRAM mapping
|
||||
u8 VRAM_MAP[4][32];
|
||||
u32 LCD_VRAM_ADDR[10];
|
||||
u8 LCDCenable[10];
|
||||
|
||||
//32KB of shared WRAM - can be switched between ARM7 & ARM9 in two blocks
|
||||
u8 SWIRAM[0x8000];
|
||||
|
||||
//Unused ram
|
||||
u8 UNUSED_RAM[4];
|
||||
|
||||
//this is here so that we can trap glitchy emulator code
|
||||
//which is accessing offsets 5,6,7 of unused ram due to unaligned accesses
|
||||
//(also since the emulator doesn't prevent unaligned accesses)
|
||||
u8 MORE_UNUSED_RAM[4];
|
||||
|
||||
static u8 * MMU_MEM[2][256];
|
||||
static u32 MMU_MASK[2][256];
|
||||
|
||||
u8 ARM9_RW_MODE;
|
||||
|
||||
u32 DTCMRegion;
|
||||
u32 ITCMRegion;
|
||||
|
||||
u16 timer[2][4];
|
||||
s32 timerMODE[2][4];
|
||||
u32 timerON[2][4];
|
||||
u32 timerRUN[2][4];
|
||||
u16 timerReload[2][4];
|
||||
|
||||
u32 reg_IME[2];
|
||||
u32 reg_IE[2];
|
||||
|
||||
//these are the user-controlled IF bits. some IF bits are generated as necessary from hardware conditions
|
||||
u32 reg_IF_bits[2];
|
||||
//these flags are set occasionally to indicate that an irq should have entered the pipeline, and processing will be deferred a tiny bit to help emulate things
|
||||
u32 reg_IF_pending[2];
|
||||
|
||||
u32 reg_DISP3DCNT_bits;
|
||||
|
||||
template<int PROCNUM> u32 gen_IF();
|
||||
|
||||
BOOL divRunning;
|
||||
s64 divResult;
|
||||
s64 divMod;
|
||||
u64 divCycles;
|
||||
|
||||
BOOL sqrtRunning;
|
||||
u32 sqrtResult;
|
||||
u64 sqrtCycles;
|
||||
|
||||
u16 SPI_CNT;
|
||||
u16 SPI_CMD;
|
||||
u16 AUX_SPI_CNT;
|
||||
//u16 AUX_SPI_CMD; //zero 20-aug-2013 - this seems pointless
|
||||
|
||||
u8 WRAMCNT;
|
||||
|
||||
u64 gfx3dCycles;
|
||||
|
||||
u8 powerMan_CntReg;
|
||||
BOOL powerMan_CntRegWritten;
|
||||
u8 powerMan_Reg[5];
|
||||
|
||||
fw_memory_chip fw;
|
||||
|
||||
GCBUS_Controller dscard[2];
|
||||
};
|
||||
|
||||
|
||||
//everything in here is derived from libnds behaviours. no hardware tests yet
|
||||
class DSI_TSC
|
||||
{
|
||||
public:
|
||||
DSI_TSC();
|
||||
void reset_command();
|
||||
u16 write16(u16 val);
|
||||
bool save_state(EMUFILE* os);
|
||||
bool load_state(EMUFILE* is);
|
||||
|
||||
private:
|
||||
u16 read16();
|
||||
u8 reg_selection;
|
||||
u8 read_flag;
|
||||
s32 state;
|
||||
s32 readcount;
|
||||
|
||||
//registers[0] contains the current page.
|
||||
//we are going to go ahead and save these out in case we want to change the way this is emulated in the future..
|
||||
//we may want to poke registers in here at more convenient times and have the TSC dumbly pluck them out,
|
||||
//rather than generate the values on the fly
|
||||
u8 registers[0x80];
|
||||
};
|
||||
|
||||
|
||||
//this contains things which can't be memzeroed because they are smarter classes
|
||||
struct MMU_struct_new
|
||||
{
|
||||
MMU_struct_new() ;
|
||||
BackupDevice backupDevice;
|
||||
DmaController dma[2][4];
|
||||
TGXSTAT gxstat;
|
||||
SqrtController sqrt;
|
||||
DivController div;
|
||||
DSI_TSC dsi_tsc;
|
||||
|
||||
void write_dma(const int proc, const int size, const u32 adr, const u32 val);
|
||||
u32 read_dma(const int proc, const int size, const u32 adr);
|
||||
bool is_dma(const u32 adr);
|
||||
};
|
||||
|
||||
extern MMU_struct MMU;
|
||||
extern MMU_struct_new MMU_new;
|
||||
|
||||
|
||||
struct armcpu_memory_iface
|
||||
{
|
||||
/** the 32 bit instruction prefetch */
|
||||
u32 FASTCALL (*prefetch32)( void *data, u32 adr);
|
||||
|
||||
/** the 16 bit instruction prefetch */
|
||||
u16 FASTCALL (*prefetch16)( void *data, u32 adr);
|
||||
|
||||
/** read 8 bit data value */
|
||||
u8 FASTCALL (*read8)( void *data, u32 adr);
|
||||
/** read 16 bit data value */
|
||||
u16 FASTCALL (*read16)( void *data, u32 adr);
|
||||
/** read 32 bit data value */
|
||||
u32 FASTCALL (*read32)( void *data, u32 adr);
|
||||
|
||||
/** write 8 bit data value */
|
||||
void FASTCALL (*write8)( void *data, u32 adr, u8 val);
|
||||
/** write 16 bit data value */
|
||||
void FASTCALL (*write16)( void *data, u32 adr, u16 val);
|
||||
/** write 32 bit data value */
|
||||
void FASTCALL (*write32)( void *data, u32 adr, u32 val);
|
||||
|
||||
void *data;
|
||||
};
|
||||
|
||||
|
||||
void MMU_Init(void);
|
||||
void MMU_DeInit(void);
|
||||
|
||||
void MMU_Reset( void);
|
||||
|
||||
void print_memory_profiling( void);
|
||||
|
||||
// Memory reading/writing (old)
|
||||
u8 FASTCALL MMU_read8(u32 proc, u32 adr);
|
||||
u16 FASTCALL MMU_read16(u32 proc, u32 adr);
|
||||
u32 FASTCALL MMU_read32(u32 proc, u32 adr);
|
||||
void FASTCALL MMU_write8(u32 proc, u32 adr, u8 val);
|
||||
void FASTCALL MMU_write16(u32 proc, u32 adr, u16 val);
|
||||
void FASTCALL MMU_write32(u32 proc, u32 adr, u32 val);
|
||||
|
||||
//template<int PROCNUM> void FASTCALL MMU_doDMA(u32 num);
|
||||
|
||||
//The base ARM memory interfaces
|
||||
extern const armcpu_memory_iface arm9_base_memory_iface;
|
||||
extern const armcpu_memory_iface arm7_base_memory_iface;
|
||||
extern const armcpu_memory_iface arm9_direct_memory_iface;
|
||||
|
||||
#define VRAM_BANKS 9
|
||||
#define VRAM_BANK_A 0
|
||||
#define VRAM_BANK_B 1
|
||||
#define VRAM_BANK_C 2
|
||||
#define VRAM_BANK_D 3
|
||||
#define VRAM_BANK_E 4
|
||||
#define VRAM_BANK_F 5
|
||||
#define VRAM_BANK_G 6
|
||||
#define VRAM_BANK_H 7
|
||||
#define VRAM_BANK_I 8
|
||||
|
||||
#define VRAM_PAGE_ABG 0
|
||||
#define VRAM_PAGE_BBG 128
|
||||
#define VRAM_PAGE_AOBJ 256
|
||||
#define VRAM_PAGE_BOBJ 384
|
||||
|
||||
|
||||
struct VramConfiguration {
|
||||
|
||||
enum Purpose {
|
||||
OFF, INVALID, ABG, BBG, AOBJ, BOBJ, LCDC, ARM7, TEX, TEXPAL, ABGEXTPAL, BBGEXTPAL, AOBJEXTPAL, BOBJEXTPAL
|
||||
};
|
||||
|
||||
struct BankInfo {
|
||||
Purpose purpose;
|
||||
int ofs;
|
||||
} banks[VRAM_BANKS];
|
||||
|
||||
inline void clear() {
|
||||
for(int i=0;i<VRAM_BANKS;i++) {
|
||||
banks[i].ofs = 0;
|
||||
banks[i].purpose = OFF;
|
||||
}
|
||||
}
|
||||
|
||||
std::string describePurpose(Purpose p);
|
||||
std::string describe();
|
||||
};
|
||||
|
||||
extern VramConfiguration vramConfiguration;
|
||||
|
||||
#define VRAM_ARM9_PAGES 512
|
||||
extern u8 vram_arm9_map[VRAM_ARM9_PAGES];
|
||||
FORCEINLINE void* MMU_gpu_map(u32 vram_addr)
|
||||
{
|
||||
//this is supposed to map a single gpu vram address to emulator host memory
|
||||
//but it returns a pointer to some zero memory in case of accesses to unmapped memory.
|
||||
//this correctly handles the case with tile accesses to unmapped memory.
|
||||
//it could also potentially go through a different LUT than vram_arm9_map in case we discover
|
||||
//that it needs to be set up with different or no mirroring
|
||||
//(I think it is a reasonable possibility that only the cpu has the nutty mirroring rules)
|
||||
//
|
||||
//if this system isn't used, Fantasy Aquarium displays garbage in the first ingame screen
|
||||
//due to it storing 0x0F0F or somesuch in screen memory which points to a ridiculously big tile
|
||||
//which should contain all 0 pixels
|
||||
|
||||
u32 vram_page = (vram_addr>>14)&(VRAM_ARM9_PAGES-1);
|
||||
u32 ofs = vram_addr & 0x3FFF;
|
||||
vram_page = vram_arm9_map[vram_page];
|
||||
//blank pages are handled by the extra 16KB of blank memory at the end of ARM9_LCD
|
||||
//and the fact that blank pages are mapped to appear at that location
|
||||
return MMU.ARM9_LCD + (vram_page<<14) + ofs;
|
||||
}
|
||||
|
||||
|
||||
template<int PROCNUM, MMU_ACCESS_TYPE AT> u8 _MMU_read08(u32 addr);
|
||||
template<int PROCNUM, MMU_ACCESS_TYPE AT> u16 _MMU_read16(u32 addr);
|
||||
template<int PROCNUM, MMU_ACCESS_TYPE AT> u32 _MMU_read32(u32 addr);
|
||||
template<int PROCNUM, MMU_ACCESS_TYPE AT> void _MMU_write08(u32 addr, u8 val);
|
||||
template<int PROCNUM, MMU_ACCESS_TYPE AT> void _MMU_write16(u32 addr, u16 val);
|
||||
template<int PROCNUM, MMU_ACCESS_TYPE AT> void _MMU_write32(u32 addr, u32 val);
|
||||
|
||||
template<int PROCNUM> FORCEINLINE u8 _MMU_read08(u32 addr) { return _MMU_read08<PROCNUM, MMU_AT_DATA>(addr); }
|
||||
template<int PROCNUM> FORCEINLINE u16 _MMU_read16(u32 addr) { return _MMU_read16<PROCNUM, MMU_AT_DATA>(addr); }
|
||||
template<int PROCNUM> FORCEINLINE u32 _MMU_read32(u32 addr) { return _MMU_read32<PROCNUM, MMU_AT_DATA>(addr); }
|
||||
template<int PROCNUM> FORCEINLINE void _MMU_write08(u32 addr, u8 val) { _MMU_write08<PROCNUM, MMU_AT_DATA>(addr,val); }
|
||||
template<int PROCNUM> FORCEINLINE void _MMU_write16(u32 addr, u16 val) { _MMU_write16<PROCNUM, MMU_AT_DATA>(addr,val); }
|
||||
template<int PROCNUM> FORCEINLINE void _MMU_write32(u32 addr, u32 val) { _MMU_write32<PROCNUM, MMU_AT_DATA>(addr,val); }
|
||||
|
||||
void FASTCALL _MMU_ARM9_write08(u32 adr, u8 val);
|
||||
void FASTCALL _MMU_ARM9_write16(u32 adr, u16 val);
|
||||
void FASTCALL _MMU_ARM9_write32(u32 adr, u32 val);
|
||||
u8 FASTCALL _MMU_ARM9_read08(u32 adr);
|
||||
u16 FASTCALL _MMU_ARM9_read16(u32 adr);
|
||||
u32 FASTCALL _MMU_ARM9_read32(u32 adr);
|
||||
|
||||
void FASTCALL _MMU_ARM7_write08(u32 adr, u8 val);
|
||||
void FASTCALL _MMU_ARM7_write16(u32 adr, u16 val);
|
||||
void FASTCALL _MMU_ARM7_write32(u32 adr, u32 val);
|
||||
u8 FASTCALL _MMU_ARM7_read08(u32 adr);
|
||||
u16 FASTCALL _MMU_ARM7_read16(u32 adr);
|
||||
u32 FASTCALL _MMU_ARM7_read32(u32 adr);
|
||||
|
||||
extern u32 partie;
|
||||
|
||||
extern u32 _MMU_MAIN_MEM_MASK;
|
||||
extern u32 _MMU_MAIN_MEM_MASK16;
|
||||
extern u32 _MMU_MAIN_MEM_MASK32;
|
||||
void SetupMMU(bool debugConsole, bool dsi);
|
||||
|
||||
FORCEINLINE void CheckMemoryDebugEvent(EDEBUG_EVENT event, const MMU_ACCESS_TYPE type, const u32 procnum, const u32 addr, const u32 size, const u32 val)
|
||||
{
|
||||
//TODO - ugh work out a better prefetch event system
|
||||
if(type == MMU_AT_CODE && event == DEBUG_EVENT_READ)
|
||||
event = DEBUG_EVENT_EXECUTE;
|
||||
if(CheckDebugEvent(event))
|
||||
{
|
||||
DebugEventData.memAccessType = type;
|
||||
DebugEventData.procnum = procnum;
|
||||
DebugEventData.addr = addr;
|
||||
DebugEventData.size = size;
|
||||
DebugEventData.val = val;
|
||||
HandleDebugEvent(event);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//ALERT!!!!!!!!!!!!!!
|
||||
//the following inline functions dont do the 0x0FFFFFFF mask.
|
||||
//this may result in some unexpected behavior
|
||||
|
||||
FORCEINLINE u8 _MMU_read08(const int PROCNUM, const MMU_ACCESS_TYPE AT, const u32 addr)
|
||||
{
|
||||
CheckMemoryDebugEvent(DEBUG_EVENT_READ,AT,PROCNUM,addr,8,0);
|
||||
|
||||
//special handling to un-protect the ARM7 bios during debug reading
|
||||
if(PROCNUM == ARMCPU_ARM7 && AT == MMU_AT_DEBUG && addr<0x00004000)
|
||||
{
|
||||
return T1ReadByte(MMU.ARM7_BIOS, addr);
|
||||
}
|
||||
|
||||
//special handling for DMA: read 0 from TCM
|
||||
if(PROCNUM==ARMCPU_ARM9 && AT == MMU_AT_DMA)
|
||||
{
|
||||
if(addr<0x02000000) return 0; //itcm
|
||||
if((addr&(~0x3FFF)) == MMU.DTCMRegion) return 0; //dtcm
|
||||
}
|
||||
|
||||
#ifdef HAVE_LUA
|
||||
CallRegisteredLuaMemHook(addr, 1, /*FIXME*/ 0, LUAMEMHOOK_READ);
|
||||
#endif
|
||||
|
||||
if(PROCNUM==ARMCPU_ARM9)
|
||||
if((addr&(~0x3FFF)) == MMU.DTCMRegion)
|
||||
{
|
||||
//Returns data from DTCM (ARM9 only)
|
||||
return T1ReadByte(MMU.ARM9_DTCM, addr & 0x3FFF);
|
||||
}
|
||||
|
||||
if ( (addr & 0x0F000000) == 0x02000000)
|
||||
return T1ReadByte( MMU.MAIN_MEM, addr & _MMU_MAIN_MEM_MASK);
|
||||
|
||||
if(PROCNUM==ARMCPU_ARM9) return _MMU_ARM9_read08(addr);
|
||||
else return _MMU_ARM7_read08(addr);
|
||||
}
|
||||
|
||||
FORCEINLINE u16 _MMU_read16(const int PROCNUM, const MMU_ACCESS_TYPE AT, const u32 addr)
|
||||
{
|
||||
CheckMemoryDebugEvent(DEBUG_EVENT_READ,AT,PROCNUM,addr,16,0);
|
||||
|
||||
//special handling to un-protect the ARM7 bios during debug reading
|
||||
if(PROCNUM == ARMCPU_ARM7 && AT == MMU_AT_DEBUG && addr<0x00004000)
|
||||
{
|
||||
return T1ReadWord_guaranteedAligned(MMU.ARM7_BIOS, addr);
|
||||
}
|
||||
|
||||
//special handling for DMA: read 0 from TCM
|
||||
if(PROCNUM==ARMCPU_ARM9 && AT == MMU_AT_DMA)
|
||||
{
|
||||
if(addr<0x02000000) return 0; //itcm
|
||||
if((addr&(~0x3FFF)) == MMU.DTCMRegion) return 0; //dtcm
|
||||
}
|
||||
|
||||
#ifdef HAVE_LUA
|
||||
CallRegisteredLuaMemHook(addr, 2, /*FIXME*/ 0, LUAMEMHOOK_READ);
|
||||
#endif
|
||||
|
||||
//special handling for execution from arm9, since we spend so much time in there
|
||||
if(PROCNUM==ARMCPU_ARM9 && AT == MMU_AT_CODE)
|
||||
{
|
||||
if ((addr & 0x0F000000) == 0x02000000)
|
||||
return T1ReadWord_guaranteedAligned( MMU.MAIN_MEM, addr & _MMU_MAIN_MEM_MASK16);
|
||||
|
||||
if(addr<0x02000000)
|
||||
return T1ReadWord_guaranteedAligned(MMU.ARM9_ITCM, addr&0x7FFE);
|
||||
|
||||
goto dunno;
|
||||
}
|
||||
|
||||
if(PROCNUM==ARMCPU_ARM9)
|
||||
if((addr&(~0x3FFF)) == MMU.DTCMRegion)
|
||||
{
|
||||
//Returns data from DTCM (ARM9 only)
|
||||
return T1ReadWord_guaranteedAligned(MMU.ARM9_DTCM, addr & 0x3FFE);
|
||||
}
|
||||
|
||||
if ( (addr & 0x0F000000) == 0x02000000)
|
||||
return T1ReadWord_guaranteedAligned( MMU.MAIN_MEM, addr & _MMU_MAIN_MEM_MASK16);
|
||||
|
||||
dunno:
|
||||
if(PROCNUM==ARMCPU_ARM9) return _MMU_ARM9_read16(addr);
|
||||
else return _MMU_ARM7_read16(addr);
|
||||
}
|
||||
|
||||
FORCEINLINE u32 _MMU_read32(const int PROCNUM, const MMU_ACCESS_TYPE AT, const u32 addr)
|
||||
{
|
||||
CheckMemoryDebugEvent(DEBUG_EVENT_READ,AT,PROCNUM,addr,32,0);
|
||||
|
||||
//special handling to un-protect the ARM7 bios during debug reading
|
||||
if(PROCNUM == ARMCPU_ARM7 && AT == MMU_AT_DEBUG && addr<0x00004000)
|
||||
{
|
||||
return T1ReadLong_guaranteedAligned(MMU.ARM7_BIOS, addr);
|
||||
}
|
||||
|
||||
//special handling for DMA: read 0 from TCM
|
||||
if(PROCNUM==ARMCPU_ARM9 && AT == MMU_AT_DMA)
|
||||
{
|
||||
if(addr<0x02000000) return 0; //itcm
|
||||
if((addr&(~0x3FFF)) == MMU.DTCMRegion) return 0; //dtcm
|
||||
}
|
||||
|
||||
#ifdef HAVE_LUA
|
||||
CallRegisteredLuaMemHook(addr, 4, /*FIXME*/ 0, LUAMEMHOOK_READ);
|
||||
#endif
|
||||
|
||||
//special handling for execution from arm9, since we spend so much time in there
|
||||
if(PROCNUM==ARMCPU_ARM9 && AT == MMU_AT_CODE)
|
||||
{
|
||||
if ( (addr & 0x0F000000) == 0x02000000)
|
||||
return T1ReadLong_guaranteedAligned( MMU.MAIN_MEM, addr & _MMU_MAIN_MEM_MASK32);
|
||||
|
||||
if(addr<0x02000000)
|
||||
return T1ReadLong_guaranteedAligned(MMU.ARM9_ITCM, addr&0x7FFC);
|
||||
|
||||
//what happens when we execute from DTCM? nocash makes it look like we get 0xFFFFFFFF but i can't seem to verify it
|
||||
//historically, desmume would fall through to its old memory map struct
|
||||
//which would return unused memory (0)
|
||||
//it seems the hardware returns 0 or something benign because in actuality 0xFFFFFFFF is an undefined opcode
|
||||
//and we know our handling for that is solid
|
||||
|
||||
goto dunno;
|
||||
}
|
||||
|
||||
//special handling for execution from arm7. try reading from main memory first
|
||||
if(PROCNUM==ARMCPU_ARM7)
|
||||
{
|
||||
if ( (addr & 0x0F000000) == 0x02000000)
|
||||
return T1ReadLong_guaranteedAligned( MMU.MAIN_MEM, addr & _MMU_MAIN_MEM_MASK32);
|
||||
}
|
||||
|
||||
|
||||
//for other arm9 cases, we have to check from dtcm first because it is patched on top of the main memory range
|
||||
if(PROCNUM==ARMCPU_ARM9)
|
||||
{
|
||||
if((addr&(~0x3FFF)) == MMU.DTCMRegion)
|
||||
{
|
||||
//Returns data from DTCM (ARM9 only)
|
||||
return T1ReadLong_guaranteedAligned(MMU.ARM9_DTCM, addr & 0x3FFC);
|
||||
}
|
||||
|
||||
if ( (addr & 0x0F000000) == 0x02000000)
|
||||
return T1ReadLong_guaranteedAligned( MMU.MAIN_MEM, addr & _MMU_MAIN_MEM_MASK32);
|
||||
}
|
||||
|
||||
dunno:
|
||||
if(PROCNUM==ARMCPU_ARM9) return _MMU_ARM9_read32(addr);
|
||||
else return _MMU_ARM7_read32(addr);
|
||||
}
|
||||
|
||||
FORCEINLINE void _MMU_write08(const int PROCNUM, const MMU_ACCESS_TYPE AT, const u32 addr, u8 val)
|
||||
{
|
||||
CheckMemoryDebugEvent(DEBUG_EVENT_WRITE,AT,PROCNUM,addr,8,val);
|
||||
|
||||
//special handling for DMA: discard writes to TCM
|
||||
if(PROCNUM==ARMCPU_ARM9 && AT == MMU_AT_DMA)
|
||||
{
|
||||
if(addr<0x02000000) return; //itcm
|
||||
if((addr&(~0x3FFF)) == MMU.DTCMRegion) return; //dtcm
|
||||
}
|
||||
|
||||
if(PROCNUM==ARMCPU_ARM9)
|
||||
if((addr&(~0x3FFF)) == MMU.DTCMRegion)
|
||||
{
|
||||
T1WriteByte(MMU.ARM9_DTCM, addr & 0x3FFF, val);
|
||||
#ifdef HAVE_LUA
|
||||
CallRegisteredLuaMemHook(addr, 1, val, LUAMEMHOOK_WRITE);
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
if ( (addr & 0x0F000000) == 0x02000000) {
|
||||
#ifdef HAVE_JIT
|
||||
JIT_COMPILED_FUNC_KNOWNBANK(addr, MAIN_MEM, _MMU_MAIN_MEM_MASK, 0) = 0;
|
||||
#endif
|
||||
T1WriteByte( MMU.MAIN_MEM, addr & _MMU_MAIN_MEM_MASK, val);
|
||||
#ifdef HAVE_LUA
|
||||
CallRegisteredLuaMemHook(addr, 1, val, LUAMEMHOOK_WRITE);
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
if(PROCNUM==ARMCPU_ARM9) _MMU_ARM9_write08(addr,val);
|
||||
else _MMU_ARM7_write08(addr,val);
|
||||
#ifdef HAVE_LUA
|
||||
CallRegisteredLuaMemHook(addr, 1, val, LUAMEMHOOK_WRITE);
|
||||
#endif
|
||||
}
|
||||
|
||||
FORCEINLINE void _MMU_write16(const int PROCNUM, const MMU_ACCESS_TYPE AT, const u32 addr, u16 val)
|
||||
{
|
||||
CheckMemoryDebugEvent(DEBUG_EVENT_WRITE,AT,PROCNUM,addr,16,val);
|
||||
|
||||
//special handling for DMA: discard writes to TCM
|
||||
if(PROCNUM==ARMCPU_ARM9 && AT == MMU_AT_DMA)
|
||||
{
|
||||
if(addr<0x02000000) return; //itcm
|
||||
if((addr&(~0x3FFF)) == MMU.DTCMRegion) return; //dtcm
|
||||
}
|
||||
|
||||
if(PROCNUM==ARMCPU_ARM9)
|
||||
if((addr&(~0x3FFF)) == MMU.DTCMRegion)
|
||||
{
|
||||
T1WriteWord(MMU.ARM9_DTCM, addr & 0x3FFE, val);
|
||||
#ifdef HAVE_LUA
|
||||
CallRegisteredLuaMemHook(addr, 2, val, LUAMEMHOOK_WRITE);
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
if ( (addr & 0x0F000000) == 0x02000000) {
|
||||
#ifdef HAVE_JIT
|
||||
JIT_COMPILED_FUNC_KNOWNBANK(addr, MAIN_MEM, _MMU_MAIN_MEM_MASK16, 0) = 0;
|
||||
#endif
|
||||
T1WriteWord( MMU.MAIN_MEM, addr & _MMU_MAIN_MEM_MASK16, val);
|
||||
#ifdef HAVE_LUA
|
||||
CallRegisteredLuaMemHook(addr, 2, val, LUAMEMHOOK_WRITE);
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
if(PROCNUM==ARMCPU_ARM9) _MMU_ARM9_write16(addr,val);
|
||||
else _MMU_ARM7_write16(addr,val);
|
||||
#ifdef HAVE_LUA
|
||||
CallRegisteredLuaMemHook(addr, 2, val, LUAMEMHOOK_WRITE);
|
||||
#endif
|
||||
}
|
||||
|
||||
FORCEINLINE void _MMU_write32(const int PROCNUM, const MMU_ACCESS_TYPE AT, const u32 addr, u32 val)
|
||||
{
|
||||
CheckMemoryDebugEvent(DEBUG_EVENT_WRITE,AT,PROCNUM,addr,32,val);
|
||||
|
||||
//special handling for DMA: discard writes to TCM
|
||||
if(PROCNUM==ARMCPU_ARM9 && AT == MMU_AT_DMA)
|
||||
{
|
||||
if(addr<0x02000000) return; //itcm
|
||||
if((addr&(~0x3FFF)) == MMU.DTCMRegion) return; //dtcm
|
||||
}
|
||||
|
||||
if(PROCNUM==ARMCPU_ARM9)
|
||||
if((addr&(~0x3FFF)) == MMU.DTCMRegion)
|
||||
{
|
||||
T1WriteLong(MMU.ARM9_DTCM, addr & 0x3FFC, val);
|
||||
#ifdef HAVE_LUA
|
||||
CallRegisteredLuaMemHook(addr, 4, val, LUAMEMHOOK_WRITE);
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
if ( (addr & 0x0F000000) == 0x02000000) {
|
||||
#ifdef HAVE_JIT
|
||||
JIT_COMPILED_FUNC_KNOWNBANK(addr, MAIN_MEM, _MMU_MAIN_MEM_MASK32, 0) = 0;
|
||||
JIT_COMPILED_FUNC_KNOWNBANK(addr, MAIN_MEM, _MMU_MAIN_MEM_MASK32, 1) = 0;
|
||||
#endif
|
||||
T1WriteLong( MMU.MAIN_MEM, addr & _MMU_MAIN_MEM_MASK32, val);
|
||||
#ifdef HAVE_LUA
|
||||
CallRegisteredLuaMemHook(addr, 4, val, LUAMEMHOOK_WRITE);
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
if(PROCNUM==ARMCPU_ARM9) _MMU_ARM9_write32(addr,val);
|
||||
else _MMU_ARM7_write32(addr,val);
|
||||
#ifdef HAVE_LUA
|
||||
CallRegisteredLuaMemHook(addr, 4, val, LUAMEMHOOK_WRITE);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
//#ifdef MMU_ENABLE_ACL
|
||||
// void FASTCALL MMU_write8_acl(u32 proc, u32 adr, u8 val);
|
||||
// void FASTCALL MMU_write16_acl(u32 proc, u32 adr, u16 val);
|
||||
// void FASTCALL MMU_write32_acl(u32 proc, u32 adr, u32 val);
|
||||
// u8 FASTCALL MMU_read8_acl(u32 proc, u32 adr, u32 access);
|
||||
// u16 FASTCALL MMU_read16_acl(u32 proc, u32 adr, u32 access);
|
||||
// u32 FASTCALL MMU_read32_acl(u32 proc, u32 adr, u32 access);
|
||||
//#else
|
||||
// #define MMU_write8_acl(proc, adr, val) _MMU_write08<proc>(adr, val)
|
||||
// #define MMU_write16_acl(proc, adr, val) _MMU_write16<proc>(adr, val)
|
||||
// #define MMU_write32_acl(proc, adr, val) _MMU_write32<proc>(adr, val)
|
||||
// #define MMU_read8_acl(proc,adr,access) _MMU_read08<proc>(adr)
|
||||
// #define MMU_read16_acl(proc,adr,access) ((access==CP15_ACCESS_EXECUTE)?_MMU_read16<proc,MMU_AT_CODE>(adr):_MMU_read16<proc,MMU_AT_DATA>(adr))
|
||||
// #define MMU_read32_acl(proc,adr,access) ((access==CP15_ACCESS_EXECUTE)?_MMU_read32<proc,MMU_AT_CODE>(adr):_MMU_read32<proc,MMU_AT_DATA>(adr))
|
||||
//#endif
|
||||
|
||||
// Use this macros for reading/writing, so the GDB stub isn't broken
|
||||
#ifdef GDB_STUB
|
||||
#define READ32(a,b) cpu->mem_if->read32(a,(b) & 0xFFFFFFFC)
|
||||
#define WRITE32(a,b,c) cpu->mem_if->write32(a,(b) & 0xFFFFFFFC,c)
|
||||
#define READ16(a,b) cpu->mem_if->read16(a,(b) & 0xFFFFFFFE)
|
||||
#define WRITE16(a,b,c) cpu->mem_if->write16(a,(b) & 0xFFFFFFFE,c)
|
||||
#define READ8(a,b) cpu->mem_if->read8(a,b)
|
||||
#define WRITE8(a,b,c) cpu->mem_if->write8(a,b,c)
|
||||
#else
|
||||
#define READ32(a,b) _MMU_read32<PROCNUM>((b) & 0xFFFFFFFC)
|
||||
#define WRITE32(a,b,c) _MMU_write32<PROCNUM>((b) & 0xFFFFFFFC,c)
|
||||
#define READ16(a,b) _MMU_read16<PROCNUM>((b) & 0xFFFFFFFE)
|
||||
#define WRITE16(a,b,c) _MMU_write16<PROCNUM>((b) & 0xFFFFFFFE,c)
|
||||
#define READ8(a,b) _MMU_read08<PROCNUM>(b)
|
||||
#define WRITE8(a,b,c) _MMU_write08<PROCNUM>(b, c)
|
||||
#endif
|
||||
|
||||
template<int PROCNUM, MMU_ACCESS_TYPE AT>
|
||||
FORCEINLINE u8 _MMU_read08(u32 addr) { return _MMU_read08(PROCNUM, AT, addr); }
|
||||
|
||||
template<int PROCNUM, MMU_ACCESS_TYPE AT>
|
||||
FORCEINLINE u16 _MMU_read16(u32 addr) { return _MMU_read16(PROCNUM, AT, addr); }
|
||||
|
||||
template<int PROCNUM, MMU_ACCESS_TYPE AT>
|
||||
FORCEINLINE u32 _MMU_read32(u32 addr) { return _MMU_read32(PROCNUM, AT, addr); }
|
||||
|
||||
template<int PROCNUM, MMU_ACCESS_TYPE AT>
|
||||
FORCEINLINE void _MMU_write08(u32 addr, u8 val) { _MMU_write08(PROCNUM, AT, addr, val); }
|
||||
|
||||
template<int PROCNUM, MMU_ACCESS_TYPE AT>
|
||||
FORCEINLINE void _MMU_write16(u32 addr, u16 val) { _MMU_write16(PROCNUM, AT, addr, val); }
|
||||
|
||||
template<int PROCNUM, MMU_ACCESS_TYPE AT>
|
||||
FORCEINLINE void _MMU_write32(u32 addr, u32 val) { _MMU_write32(PROCNUM, AT, addr, val); }
|
||||
|
||||
void FASTCALL MMU_DumpMemBlock(u8 proc, u32 address, u32 size, u8 *buffer);
|
||||
|
||||
#endif
|
||||
Executable
+459
@@ -0,0 +1,459 @@
|
||||
/*
|
||||
Copyright (C) 2006 yopyop
|
||||
Copyright (C) 2007 shash
|
||||
Copyright (C) 2007-2011 DeSmuME team
|
||||
|
||||
This file is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This file is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with the this software. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
// this file is split from MMU.h for the purpose of avoiding ridiculous recompile times
|
||||
// when changing it, because practically everything includes MMU.h.
|
||||
#ifndef MMUTIMING_H
|
||||
#define MMUTIMING_H
|
||||
|
||||
#include <algorithm>
|
||||
#include "MMU.h"
|
||||
#include "cp15.h"
|
||||
#include "readwrite.h"
|
||||
#include "debug.h"
|
||||
#include "NDSSystem.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
// MEMORY TIMING ACCURACY CONFIGURATION
|
||||
//
|
||||
// the more of these are enabled,
|
||||
// the more accurate memory access timing _should_ become.
|
||||
// they should be listed roughly in order of most to least important.
|
||||
// it's reasonable to disable some of these as a speed hack.
|
||||
// obviously, these defines don't cover all the variables or features needed,
|
||||
// and in particular, DMA or code+data access bus contention is still missing.
|
||||
|
||||
//disable this to prevent the advanced timing logic from ever running at all
|
||||
#define ENABLE_ADVANCED_TIMING
|
||||
|
||||
#ifdef ENABLE_ADVANCED_TIMING
|
||||
// makes non-sequential accesses slower than sequential ones.
|
||||
#define ACCOUNT_FOR_NON_SEQUENTIAL_ACCESS
|
||||
//(SOMETIMES THIS IS A BIG SPEED HIT!)
|
||||
|
||||
// enables emulation of code fetch waits.
|
||||
#define ACCOUNT_FOR_CODE_FETCH_CYCLES
|
||||
|
||||
// makes access to DTCM (arm9 only) fast.
|
||||
#define ACCOUNT_FOR_DATA_TCM_SPEED
|
||||
|
||||
// enables simulation of cache hits and cache misses.
|
||||
#define ENABLE_CACHE_CONTROLLER_EMULATION
|
||||
|
||||
#endif //ENABLE_ADVANCED_TIMING
|
||||
|
||||
//
|
||||
////////////////////////////////////////////////////////////////
|
||||
|
||||
FORCEINLINE bool USE_TIMING() {
|
||||
#ifdef ENABLE_ADVANCED_TIMING
|
||||
return CommonSettings.advanced_timing;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
enum MMU_ACCESS_DIRECTION
|
||||
{
|
||||
MMU_AD_READ, MMU_AD_WRITE
|
||||
};
|
||||
|
||||
|
||||
// note that we don't actually emulate the cache contents here,
|
||||
// only enough to guess what would be a cache hit or a cache miss.
|
||||
// this doesn't really get used unless ENABLE_CACHE_CONTROLLER_EMULATION is defined.
|
||||
template<int SIZESHIFT, int ASSOCIATIVESHIFT, int BLOCKSIZESHIFT>
|
||||
class CacheController
|
||||
{
|
||||
public:
|
||||
template<MMU_ACCESS_DIRECTION DIR>
|
||||
FORCEINLINE bool Cached(u32 addr)
|
||||
{
|
||||
u32 blockMasked = addr & BLOCKMASK;
|
||||
if(blockMasked == m_cacheCache)
|
||||
return true;
|
||||
else
|
||||
return this->CachedInternal<DIR>(addr, blockMasked);
|
||||
}
|
||||
|
||||
void Reset()
|
||||
{
|
||||
for(int blockIndex = 0; blockIndex < NUMBLOCKS; blockIndex++)
|
||||
m_blocks[blockIndex].Reset();
|
||||
m_cacheCache = ~0;
|
||||
}
|
||||
CacheController()
|
||||
{
|
||||
Reset();
|
||||
}
|
||||
|
||||
void savestate(EMUFILE* os, int version)
|
||||
{
|
||||
write32le(m_cacheCache, os);
|
||||
for(int i = 0; i < NUMBLOCKS; i++)
|
||||
{
|
||||
for(int j = 0; j < ASSOCIATIVITY; j++)
|
||||
write32le(m_blocks[i].tag[j],os);
|
||||
write32le(m_blocks[i].nextWay,os);
|
||||
}
|
||||
}
|
||||
bool loadstate(EMUFILE* is, int version)
|
||||
{
|
||||
read32le(&m_cacheCache, is);
|
||||
for(int i = 0; i < NUMBLOCKS; i++)
|
||||
{
|
||||
for(int j = 0; j < ASSOCIATIVITY; j++)
|
||||
read32le(&m_blocks[i].tag[j],is);
|
||||
read32le(&m_blocks[i].nextWay,is);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
template<MMU_ACCESS_DIRECTION DIR>
|
||||
bool CachedInternal(u32 addr, u32 blockMasked)
|
||||
{
|
||||
u32 blockIndex = blockMasked >> BLOCKSIZESHIFT;
|
||||
CacheBlock& block = m_blocks[blockIndex];
|
||||
addr &= TAGMASK;
|
||||
|
||||
for(int way = 0; way < ASSOCIATIVITY; way++)
|
||||
if(addr == block.tag[way])
|
||||
{
|
||||
// found it, already allocated
|
||||
m_cacheCache = blockMasked;
|
||||
return true;
|
||||
}
|
||||
if(DIR == MMU_AD_READ)
|
||||
{
|
||||
// TODO: support other allocation orders?
|
||||
block.tag[block.nextWay++] = addr;
|
||||
block.nextWay %= ASSOCIATIVITY;
|
||||
m_cacheCache = blockMasked;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
enum { SIZE = 1 << SIZESHIFT };
|
||||
enum { ASSOCIATIVITY = 1 << ASSOCIATIVESHIFT };
|
||||
enum { BLOCKSIZE = 1 << BLOCKSIZESHIFT };
|
||||
enum { TAGSHIFT = SIZESHIFT - ASSOCIATIVESHIFT };
|
||||
enum { TAGMASK = (u32)(~0 << TAGSHIFT) };
|
||||
enum { BLOCKMASK = ((u32)~0 >> (32 - TAGSHIFT)) & (u32)(~0 << BLOCKSIZESHIFT) };
|
||||
enum { WORDSIZE = sizeof(u32) };
|
||||
enum { WORDSPERBLOCK = (1 << BLOCKSIZESHIFT) / WORDSIZE };
|
||||
enum { DATAPERWORD = WORDSIZE * ASSOCIATIVITY };
|
||||
enum { DATAPERBLOCK = DATAPERWORD * WORDSPERBLOCK };
|
||||
enum { NUMBLOCKS = SIZE / DATAPERBLOCK };
|
||||
|
||||
struct CacheBlock
|
||||
{
|
||||
u32 tag [ASSOCIATIVITY];
|
||||
u32 nextWay;
|
||||
|
||||
void Reset()
|
||||
{
|
||||
nextWay = 0;
|
||||
for(int way = 0; way < ASSOCIATIVITY; way++)
|
||||
tag[way] = 0;
|
||||
}
|
||||
};
|
||||
|
||||
u32 m_cacheCache; // optimization
|
||||
|
||||
CacheBlock m_blocks [NUMBLOCKS];
|
||||
};
|
||||
|
||||
|
||||
template<int PROCNUM, MMU_ACCESS_TYPE AT, int READSIZE, MMU_ACCESS_DIRECTION DIRECTION, bool TIMING>
|
||||
FORCEINLINE u32 _MMU_accesstime(u32 addr, bool sequential);
|
||||
|
||||
|
||||
template<int PROCNUM, MMU_ACCESS_TYPE AT>
|
||||
class FetchAccessUnit
|
||||
{
|
||||
public:
|
||||
template<int READSIZE, MMU_ACCESS_DIRECTION DIRECTION, bool TIMING>
|
||||
FORCEINLINE u32 Fetch(u32 address)
|
||||
{
|
||||
#ifdef ACCOUNT_FOR_CODE_FETCH_CYCLES
|
||||
const bool prohibit = TIMING;
|
||||
#else
|
||||
const bool prohibit = false;
|
||||
#endif
|
||||
|
||||
if(AT == MMU_AT_CODE && !prohibit)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
u32 time = _MMU_accesstime<PROCNUM, AT, READSIZE, DIRECTION,TIMING>(address,
|
||||
#ifdef ACCOUNT_FOR_NON_SEQUENTIAL_ACCESS
|
||||
(TIMING?
|
||||
(address == (m_lastAddress + (READSIZE>>3)))
|
||||
:true
|
||||
)
|
||||
#else
|
||||
true
|
||||
#endif
|
||||
);
|
||||
|
||||
#ifdef ACCOUNT_FOR_NON_SEQUENTIAL_ACCESS
|
||||
m_lastAddress = address;
|
||||
#endif
|
||||
|
||||
return time;
|
||||
}
|
||||
|
||||
void Reset()
|
||||
{
|
||||
m_lastAddress = ~0;
|
||||
}
|
||||
FetchAccessUnit() { this->Reset(); }
|
||||
|
||||
void savestate(EMUFILE* os, int version)
|
||||
{
|
||||
write32le(m_lastAddress,os);
|
||||
}
|
||||
bool loadstate(EMUFILE* is, int version)
|
||||
{
|
||||
read32le(&m_lastAddress,is);
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
u32 m_lastAddress;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
struct MMU_struct_timing
|
||||
{
|
||||
// technically part of the cp15, but I didn't want the dereferencing penalty.
|
||||
// these template values correspond with the value of armcp15->cacheType.
|
||||
CacheController<13,2,5> arm9codeCache; // 8192 bytes, 4-way associative, 32-byte blocks
|
||||
CacheController<12,2,5> arm9dataCache; // 4096 bytes, 4-way associative, 32-byte blocks
|
||||
|
||||
// technically part of armcpu_t, but that struct isn't templated on PROCNUM
|
||||
FetchAccessUnit<0,MMU_AT_CODE> arm9codeFetch;
|
||||
FetchAccessUnit<0,MMU_AT_DATA> arm9dataFetch;
|
||||
FetchAccessUnit<1,MMU_AT_CODE> arm7codeFetch;
|
||||
FetchAccessUnit<1,MMU_AT_DATA> arm7dataFetch;
|
||||
|
||||
template<int PROCNUM> FORCEINLINE FetchAccessUnit<PROCNUM,MMU_AT_CODE>& armCodeFetch();
|
||||
template<int PROCNUM> FORCEINLINE FetchAccessUnit<PROCNUM,MMU_AT_DATA>& armDataFetch();
|
||||
};
|
||||
template<> FORCEINLINE FetchAccessUnit<0,MMU_AT_CODE>& MMU_struct_timing::armCodeFetch<0>() { return this->arm9codeFetch; }
|
||||
template<> FORCEINLINE FetchAccessUnit<1,MMU_AT_CODE>& MMU_struct_timing::armCodeFetch<1>() { return this->arm7codeFetch; }
|
||||
template<> FORCEINLINE FetchAccessUnit<0,MMU_AT_DATA>& MMU_struct_timing::armDataFetch<0>() { return this->arm9dataFetch; }
|
||||
template<> FORCEINLINE FetchAccessUnit<1,MMU_AT_DATA>& MMU_struct_timing::armDataFetch<1>() { return this->arm7dataFetch; }
|
||||
|
||||
|
||||
extern MMU_struct_timing MMU_timing;
|
||||
|
||||
|
||||
|
||||
// calculates the time a single memory access takes,
|
||||
// in units of cycles of the current processor.
|
||||
// this function replaces what used to be MMU_WAIT16 and MMU_WAIT32.
|
||||
// this may have side effects, so don't call it more than necessary.
|
||||
template<int PROCNUM, MMU_ACCESS_TYPE AT, int READSIZE, MMU_ACCESS_DIRECTION DIRECTION, bool TIMING>
|
||||
FORCEINLINE u32 _MMU_accesstime(u32 addr, bool sequential)
|
||||
{
|
||||
static const int MC = 1; // cached or tcm memory speed
|
||||
static const int M32 = (PROCNUM==ARMCPU_ARM9) ? 2 : 1; // access through 32-bit bus
|
||||
static const int M16 = M32 * ((READSIZE>16) ? 2 : 1); // access through 16-bit bus
|
||||
static const int MSLW = M16 * 8; // this needs tuning
|
||||
|
||||
if(PROCNUM==ARMCPU_ARM9 && AT == MMU_AT_CODE && addr < 0x02000000)
|
||||
return MC; // ITCM
|
||||
|
||||
#ifdef ACCOUNT_FOR_DATA_TCM_SPEED
|
||||
if(TIMING && PROCNUM==ARMCPU_ARM9 && AT==MMU_AT_DATA && (addr&(~0x3FFF)) == MMU.DTCMRegion)
|
||||
return MC; // DTCM
|
||||
#endif
|
||||
|
||||
// for now, assume the cache is always enabled for all of main memory
|
||||
if(AT != MMU_AT_DMA && TIMING && PROCNUM==ARMCPU_ARM9 && (addr & 0x0F000000) == 0x02000000)
|
||||
{
|
||||
#ifdef ENABLE_CACHE_CONTROLLER_EMULATION
|
||||
bool cached = false;
|
||||
if(AT==MMU_AT_CODE)
|
||||
cached = MMU_timing.arm9codeCache.Cached<DIRECTION>(addr);
|
||||
if(AT==MMU_AT_DATA)
|
||||
cached = MMU_timing.arm9dataCache.Cached<DIRECTION>(addr);
|
||||
if(cached)
|
||||
return MC;
|
||||
u32 c;
|
||||
if(sequential && AT==MMU_AT_DATA)
|
||||
c = M16; // bonus for sequential data access
|
||||
else if(DIRECTION == MMU_AD_READ)
|
||||
c = M16 * 5;
|
||||
else
|
||||
c = M16 * 2; // should be 4, but write buffer isn't emulated yet.
|
||||
if(DIRECTION == MMU_AD_READ)
|
||||
{
|
||||
// cache miss while reading means it has to fill a whole cache line
|
||||
// by reading 32 bytes...
|
||||
c += 8 * M32*2;
|
||||
}
|
||||
|
||||
if(CheckDebugEvent(DEBUG_EVENT_CACHE_MISS))
|
||||
{
|
||||
DebugEventData.addr = addr;
|
||||
DebugEventData.size = READSIZE;
|
||||
HandleDebugEvent(DEBUG_EVENT_CACHE_MISS);
|
||||
}
|
||||
|
||||
return c;
|
||||
#elif defined(ACCOUNT_FOR_NON_SEQUENTIAL_ACCESS)
|
||||
// this is the closest approximation I could find
|
||||
// to the with-cache-controller timing
|
||||
// that doesn't do any actual caching logic.
|
||||
return sequential ? MC : M16;
|
||||
#endif
|
||||
}
|
||||
|
||||
static const TWaitState MMU_WAIT[16*16] = {
|
||||
// ITCM, ITCM, MAIN, SWI, REG, VMEM, LCD, OAM, ROM, ROM, RAM, U, U, U, U, BIOS
|
||||
#define X MC, MC, M16, M32, M32, M16, M16, M32, MSLW, MSLW, MSLW, M32,M32,M32,M32, M32,
|
||||
// duplicate it 16 times (this was somehow faster than using a mask of 0xF)
|
||||
X X X X X X X X X X X X X X X X
|
||||
#undef X
|
||||
};
|
||||
|
||||
u32 c = MMU_WAIT[(addr >> 24)];
|
||||
|
||||
#ifdef ACCOUNT_FOR_NON_SEQUENTIAL_ACCESS
|
||||
if(TIMING && !sequential)
|
||||
{
|
||||
//if(c != MC || PROCNUM==ARMCPU_ARM7) // check not needed anymore because ITCM/DTCM return earlier
|
||||
{
|
||||
c += (PROCNUM==ARMCPU_ARM9) ? 3*2 : 1;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// calculates the cycle time of a single memory access in the MEM stage.
|
||||
// to be used to calculate the memCycles argument for MMU_aluMemCycles.
|
||||
// this may have side effects, so don't call it more than necessary.
|
||||
template<int PROCNUM, int READSIZE, MMU_ACCESS_DIRECTION DIRECTION, bool TIMING>
|
||||
FORCEINLINE u32 MMU_memAccessCycles(u32 addr)
|
||||
{
|
||||
if(TIMING)
|
||||
return MMU_timing.armDataFetch<PROCNUM>().template Fetch<READSIZE,DIRECTION,true>((addr)&(~((READSIZE>>3)-1)));
|
||||
else
|
||||
return MMU_timing.armDataFetch<PROCNUM>().template Fetch<READSIZE,DIRECTION,false>((addr)&(~((READSIZE>>3)-1)));
|
||||
}
|
||||
|
||||
template<int PROCNUM, int READSIZE, MMU_ACCESS_DIRECTION DIRECTION>
|
||||
FORCEINLINE u32 MMU_memAccessCycles(u32 addr)
|
||||
{
|
||||
if(USE_TIMING())
|
||||
return MMU_memAccessCycles<PROCNUM,READSIZE,DIRECTION,true>(addr);
|
||||
else
|
||||
return MMU_memAccessCycles<PROCNUM,READSIZE,DIRECTION,false>(addr);
|
||||
}
|
||||
|
||||
// calculates the cycle time of a single code fetch in the FETCH stage
|
||||
// to be used to calculate the fetchCycles argument for MMU_fetchExecuteCycles.
|
||||
// this may have side effects, so don't call it more than necessary.
|
||||
template<int PROCNUM, int READSIZE>
|
||||
FORCEINLINE u32 MMU_codeFetchCycles(u32 addr)
|
||||
{
|
||||
if(USE_TIMING())
|
||||
return MMU_timing.armCodeFetch<PROCNUM>().template Fetch<READSIZE,MMU_AD_READ,true>((addr)&(~((READSIZE>>3)-1)));
|
||||
else
|
||||
return MMU_timing.armCodeFetch<PROCNUM>().template Fetch<READSIZE,MMU_AD_READ,false>((addr)&(~((READSIZE>>3)-1)));
|
||||
}
|
||||
|
||||
// calculates the cycle contribution of ALU + MEM stages (= EXECUTE)
|
||||
// given ALU cycle time and the summation of multiple memory access cycle times.
|
||||
// this function might belong more in armcpu, but I don't think it matters.
|
||||
template<int PROCNUM>
|
||||
FORCEINLINE u32 MMU_aluMemCycles(u32 aluCycles, u32 memCycles)
|
||||
{
|
||||
if(PROCNUM==ARMCPU_ARM9)
|
||||
{
|
||||
// ALU and MEM are different stages of the 5-stage pipeline.
|
||||
// we approximate the pipeline throughput using max,
|
||||
// since simply adding the cycles of each instruction together
|
||||
// fails to take into account the parallelism of the arm pipeline
|
||||
// and would make the emulated system unnaturally slow.
|
||||
return std::max(aluCycles, memCycles);
|
||||
}
|
||||
else
|
||||
{
|
||||
// ALU and MEM are part of the same stage of the 3-stage pipeline,
|
||||
// thus they occur in sequence and we can simply add the counts together.
|
||||
return aluCycles + memCycles;
|
||||
}
|
||||
}
|
||||
|
||||
// calculates the cycle contribution of ALU + MEM stages (= EXECUTE)
|
||||
// given ALU cycle time and the description of a single memory access.
|
||||
// this may have side effects, so don't call it more than necessary.
|
||||
template<int PROCNUM, int READSIZE, MMU_ACCESS_DIRECTION DIRECTION>
|
||||
FORCEINLINE u32 MMU_aluMemAccessCycles(u32 aluCycles, u32 addr)
|
||||
{
|
||||
u32 memCycles;
|
||||
if(USE_TIMING())
|
||||
memCycles = MMU_memAccessCycles<PROCNUM,READSIZE,DIRECTION,true>(addr);
|
||||
else memCycles = MMU_memAccessCycles<PROCNUM,READSIZE,DIRECTION,false>(addr);
|
||||
return MMU_aluMemCycles<PROCNUM>(aluCycles, memCycles);
|
||||
}
|
||||
|
||||
// calculates the cycle contribution of FETCH + EXECUTE stages
|
||||
// given executeCycles = the combined ALU+MEM cycles
|
||||
// and fetchCycles = the cycle time of the FETCH stage
|
||||
// this function might belong more in armcpu, but I don't think it matters.
|
||||
template<int PROCNUM>
|
||||
FORCEINLINE u32 MMU_fetchExecuteCycles(u32 executeCycles, u32 fetchCycles)
|
||||
{
|
||||
#ifdef ACCOUNT_FOR_CODE_FETCH_CYCLES
|
||||
const bool allow = true;
|
||||
#else
|
||||
const bool allow = false;
|
||||
#endif
|
||||
|
||||
if(USE_TIMING() && allow)
|
||||
{
|
||||
// execute and fetch are different stages of the pipeline for both arm7 and arm9.
|
||||
// again, we approximate the pipeline throughput using max.
|
||||
return std::max(executeCycles, fetchCycles);
|
||||
// TODO: add an option to support conflict between MEM and FETCH cycles
|
||||
// if they're both using the same data bus.
|
||||
// in the case of a conflict this should be:
|
||||
// return std::max(aluCycles, memCycles + fetchCycles);
|
||||
}
|
||||
return executeCycles;
|
||||
}
|
||||
|
||||
|
||||
#endif //MMUTIMING_H
|
||||
+206
@@ -0,0 +1,206 @@
|
||||
include $(top_srcdir)/src/desmume.mk
|
||||
|
||||
AM_CPPFLAGS += $(SDL_CFLAGS) $(GTHREAD_CFLAGS) $(X_CFLAGS) $(ALSA_CFLAGS) $(LIBAGG_CFLAGS) $(LIBSOUNDTOUCH_CFLAGS)
|
||||
|
||||
EXTRA_DIST = build.bat instruction_tabdef.inc thumb_tabdef.inc fs-linux.cpp fs-windows.cpp cocoa
|
||||
if HAVE_GDB_STUB
|
||||
SUBDIRS = . gdbstub $(UI_DIR)
|
||||
else
|
||||
SUBDIRS = . $(UI_DIR)
|
||||
endif
|
||||
DIST_SUBDIRS = . gdbstub cli gtk gtk-glade
|
||||
noinst_LIBRARIES = libdesmume.a
|
||||
libdesmume_a_SOURCES = \
|
||||
armcpu.cpp armcpu.h \
|
||||
arm_instructions.cpp \
|
||||
agg2d.h agg2d.inl \
|
||||
bios.cpp bios.h bits.h cp15.cpp cp15.h \
|
||||
commandline.h commandline.cpp \
|
||||
common.cpp common.h \
|
||||
debug.cpp debug.h \
|
||||
Disassembler.cpp Disassembler.h \
|
||||
emufile.h emufile.cpp emufile_types.h encrypt.h encrypt.cpp FIFO.cpp FIFO.h \
|
||||
firmware.cpp firmware.h GPU.cpp GPU.h \
|
||||
fs.h \
|
||||
GPU_osd.h \
|
||||
instructions.h \
|
||||
mem.h mc.cpp mc.h \
|
||||
path.cpp path.h \
|
||||
readwrite.cpp readwrite.h \
|
||||
wifi.cpp wifi.h \
|
||||
mic.h \
|
||||
MMU.cpp MMU.h MMU_timing.h NDSSystem.cpp NDSSystem.h registers.h \
|
||||
OGLRender.h OGLRender_3_2.h \
|
||||
ROMReader.cpp ROMReader.h \
|
||||
render3D.cpp render3D.h \
|
||||
rtc.cpp rtc.h \
|
||||
saves.cpp saves.h \
|
||||
slot1.cpp slot1.h \
|
||||
slot2.cpp slot2.h \
|
||||
SPU.cpp SPU.h \
|
||||
matrix.cpp matrix.h \
|
||||
gfx3d.cpp gfx3d.h \
|
||||
thumb_instructions.cpp types.h \
|
||||
movie.cpp movie.h \
|
||||
PACKED.h PACKED_END.h \
|
||||
utils/advanscene.cpp utils/advanscene.h \
|
||||
utils/datetime.cpp utils/datetime.h \
|
||||
utils/ConvertUTF.c utils/ConvertUTF.h utils/guid.cpp utils/guid.h \
|
||||
utils/emufat.cpp utils/emufat.h utils/emufat_types.h \
|
||||
utils/fsnitro.cpp utils/fsnitro.h \
|
||||
utils/md5.cpp utils/md5.h utils/valuearray.h utils/xstring.cpp utils/xstring.h \
|
||||
utils/decrypt/crc.cpp utils/decrypt/crc.h utils/decrypt/decrypt.cpp \
|
||||
utils/decrypt/decrypt.h utils/decrypt/header.cpp utils/decrypt/header.h \
|
||||
utils/task.cpp utils/task.h \
|
||||
utils/vfat.h utils/vfat.cpp \
|
||||
utils/dlditool.cpp \
|
||||
utils/libfat/bit_ops.h \
|
||||
utils/libfat/cache.cpp \
|
||||
utils/libfat/cache.h \
|
||||
utils/libfat/common.h \
|
||||
utils/libfat/directory.cpp \
|
||||
utils/libfat/directory.h \
|
||||
utils/libfat/disc.cpp \
|
||||
utils/libfat/disc.h \
|
||||
utils/libfat/disc_io.h \
|
||||
utils/libfat/fat.h \
|
||||
utils/libfat/fatdir.cpp \
|
||||
utils/libfat/fatdir.h \
|
||||
utils/libfat/fatfile.cpp \
|
||||
utils/libfat/fatfile.h \
|
||||
utils/libfat/filetime.cpp \
|
||||
utils/libfat/filetime.h \
|
||||
utils/libfat/file_allocation_table.cpp \
|
||||
utils/libfat/file_allocation_table.h \
|
||||
utils/libfat/libfat.cpp \
|
||||
utils/libfat/libfat_pc.h \
|
||||
utils/libfat/libfat_public_api.cpp \
|
||||
utils/libfat/libfat_public_api.h \
|
||||
utils/libfat/lock.cpp \
|
||||
utils/libfat/lock.h \
|
||||
utils/libfat/mem_allocate.h \
|
||||
utils/libfat/partition.cpp \
|
||||
utils/libfat/partition.h \
|
||||
utils/tinyxml/tinystr.cpp \
|
||||
utils/tinyxml/tinystr.h \
|
||||
utils/tinyxml/tinyxml.cpp \
|
||||
utils/tinyxml/tinyxml.h \
|
||||
utils/tinyxml/tinyxmlerror.cpp \
|
||||
utils/tinyxml/tinyxmlparser.cpp \
|
||||
utils/glcorearb.h \
|
||||
addons/slot2_auto.cpp addons/slot2_mpcf.cpp addons/slot2_paddle.cpp addons/slot2_gbagame.cpp addons/slot2_none.cpp addons/slot2_rumblepak.cpp addons/slot2_guitarGrip.cpp addons/slot2_expMemory.cpp addons/slot2_piano.cpp addons/slot2_passme.cpp addons/slot1_none.cpp addons/slot1_r4.cpp addons/slot1_retail_nand.cpp addons/slot1_retail_auto.cpp addons/slot1_retail_mcrom.cpp addons/slot1_retail_mcrom_debug.cpp addons/slot1comp_mc.cpp addons/slot1comp_mc.h addons/slot1comp_rom.h addons/slot1comp_rom.cpp addons/slot1comp_protocol.h addons/slot1comp_protocol.cpp \
|
||||
cheatSystem.cpp cheatSystem.h \
|
||||
texcache.cpp texcache.h rasterize.cpp rasterize.h \
|
||||
metaspu/metaspu.cpp metaspu/metaspu.h \
|
||||
filter/2xsai.cpp filter/bilinear.cpp filter/epx.cpp filter/filter.h \
|
||||
filter/hq2x.cpp filter/hq2x.h filter/hq4x.cpp filter/hq4x.dat filter/hq4x.h \
|
||||
filter/interp.h filter/lq2x.cpp filter/lq2x.h filter/scanline.cpp \
|
||||
filter/videofilter.cpp filter/videofilter.h \
|
||||
filter/xbrz.cpp filter/xbrz.h \
|
||||
version.cpp version.h \
|
||||
desmume_config.cpp desmume_config.h
|
||||
|
||||
if HAVE_JIT
|
||||
libdesmume_a_SOURCES += \
|
||||
arm_jit.cpp arm_jit.h instruction_attributes.h \
|
||||
utils/AsmJit/AsmJit.h \
|
||||
utils/AsmJit/Config.h \
|
||||
utils/AsmJit/core.h \
|
||||
utils/AsmJit/x86.h \
|
||||
utils/AsmJit/core/apibegin.h \
|
||||
utils/AsmJit/core/apiend.h \
|
||||
utils/AsmJit/core/assembler.cpp \
|
||||
utils/AsmJit/core/assembler.h \
|
||||
utils/AsmJit/core/assert.cpp \
|
||||
utils/AsmJit/core/assert.h \
|
||||
utils/AsmJit/core/buffer.cpp \
|
||||
utils/AsmJit/core/buffer.h \
|
||||
utils/AsmJit/core/build.h \
|
||||
utils/AsmJit/core/compiler.cpp \
|
||||
utils/AsmJit/core/compiler.h \
|
||||
utils/AsmJit/core/compilercontext.cpp \
|
||||
utils/AsmJit/core/compilercontext.h \
|
||||
utils/AsmJit/core/compilerfunc.cpp \
|
||||
utils/AsmJit/core/compilerfunc.h \
|
||||
utils/AsmJit/core/compileritem.cpp \
|
||||
utils/AsmJit/core/compileritem.h \
|
||||
utils/AsmJit/core/context.cpp \
|
||||
utils/AsmJit/core/context.h \
|
||||
utils/AsmJit/core/cpuinfo.cpp \
|
||||
utils/AsmJit/core/cpuinfo.h \
|
||||
utils/AsmJit/core/defs.cpp \
|
||||
utils/AsmJit/core/defs.h \
|
||||
utils/AsmJit/core/func.cpp \
|
||||
utils/AsmJit/core/func.h \
|
||||
utils/AsmJit/core/intutil.h \
|
||||
utils/AsmJit/core/lock.h \
|
||||
utils/AsmJit/core/logger.cpp \
|
||||
utils/AsmJit/core/logger.h \
|
||||
utils/AsmJit/core/memorymanager.cpp \
|
||||
utils/AsmJit/core/memorymanager.h \
|
||||
utils/AsmJit/core/memorymarker.cpp \
|
||||
utils/AsmJit/core/memorymarker.h \
|
||||
utils/AsmJit/core/operand.cpp \
|
||||
utils/AsmJit/core/operand.h \
|
||||
utils/AsmJit/core/podvector.h \
|
||||
utils/AsmJit/core/stringbuilder.cpp \
|
||||
utils/AsmJit/core/stringbuilder.h \
|
||||
utils/AsmJit/core/stringutil.cpp \
|
||||
utils/AsmJit/core/stringutil.h \
|
||||
utils/AsmJit/core/virtualmemory.cpp \
|
||||
utils/AsmJit/core/virtualmemory.h \
|
||||
utils/AsmJit/core/zonememory.cpp \
|
||||
utils/AsmJit/core/zonememory.h \
|
||||
utils/AsmJit/x86/x86assembler.cpp \
|
||||
utils/AsmJit/x86/x86assembler.h \
|
||||
utils/AsmJit/x86/x86compiler.cpp \
|
||||
utils/AsmJit/x86/x86compiler.h \
|
||||
utils/AsmJit/x86/x86compilercontext.cpp \
|
||||
utils/AsmJit/x86/x86compilercontext.h \
|
||||
utils/AsmJit/x86/x86compilerfunc.cpp \
|
||||
utils/AsmJit/x86/x86compilerfunc.h \
|
||||
utils/AsmJit/x86/x86compileritem.cpp \
|
||||
utils/AsmJit/x86/x86compileritem.h \
|
||||
utils/AsmJit/x86/x86cpuinfo.cpp \
|
||||
utils/AsmJit/x86/x86cpuinfo.h \
|
||||
utils/AsmJit/x86/x86defs.cpp \
|
||||
utils/AsmJit/x86/x86defs.h \
|
||||
utils/AsmJit/x86/x86func.cpp \
|
||||
utils/AsmJit/x86/x86func.h \
|
||||
utils/AsmJit/x86/x86operand.cpp \
|
||||
utils/AsmJit/x86/x86operand.h \
|
||||
utils/AsmJit/x86/x86util.cpp \
|
||||
utils/AsmJit/x86/x86util.h
|
||||
endif
|
||||
|
||||
if HAVE_GL
|
||||
libdesmume_a_SOURCES += OGLRender.cpp OGLRender_3_2.cpp
|
||||
endif
|
||||
|
||||
if HAVE_OPENAL
|
||||
libdesmume_a_SOURCES += mic_openal.cpp
|
||||
else
|
||||
if HAVE_ALSA
|
||||
libdesmume_a_SOURCES += mic_alsa.cpp
|
||||
else
|
||||
libdesmume_a_SOURCES += mic.cpp
|
||||
endif
|
||||
endif
|
||||
|
||||
if HAVE_LIBSOUNDTOUCH
|
||||
libdesmume_a_SOURCES += metaspu/SndOut.cpp metaspu/SndOut.h metaspu/Timestretcher.cpp
|
||||
endif
|
||||
|
||||
if HAVE_LIBAGG
|
||||
libdesmume_a_SOURCES += aggdraw.cpp aggdraw.h GPU_osd.cpp
|
||||
else
|
||||
libdesmume_a_SOURCES += GPU_osd_stub.cpp
|
||||
endif
|
||||
if HAVE_LUA
|
||||
AM_CPPFLAGS += $(LUA_CFLAGS)
|
||||
libdesmume_a_SOURCES += lua-engine.cpp
|
||||
endif
|
||||
if HAVE_GDB_STUB
|
||||
libdesmume_a_SOURCES += gdbstub.h
|
||||
endif
|
||||
libdesmume_a_LIBADD = fs-$(desmume_arch).$(OBJEXT)
|
||||
Executable
+2942
File diff suppressed because it is too large
Load Diff
Executable
+649
@@ -0,0 +1,649 @@
|
||||
/*
|
||||
Copyright (C) 2006 yopyop
|
||||
Copyright (C) 2008-2015 DeSmuME team
|
||||
|
||||
This file is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This file is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with the this software. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef NDSSYSTEM_H
|
||||
#define NDSSYSTEM_H
|
||||
|
||||
#include <string.h>
|
||||
#include <string>
|
||||
|
||||
#include "types.h"
|
||||
|
||||
class BaseDriver;
|
||||
class CFIRMWARE;
|
||||
class EMUFILE;
|
||||
|
||||
template<typename Type>
|
||||
struct buttonstruct {
|
||||
union {
|
||||
struct {
|
||||
// changing the order of these fields would break stuff
|
||||
//fRLDUTSBAYXWEg
|
||||
Type G; // debug
|
||||
Type E; // right shoulder
|
||||
Type W; // left shoulder
|
||||
Type X;
|
||||
Type Y;
|
||||
Type A;
|
||||
Type B;
|
||||
Type S; // start
|
||||
Type T; // select
|
||||
Type U; // up
|
||||
Type D; // down
|
||||
Type L; // left
|
||||
Type R; // right
|
||||
Type F; // lid
|
||||
};
|
||||
Type array[14];
|
||||
};
|
||||
};
|
||||
|
||||
extern buttonstruct<bool> Turbo;
|
||||
extern buttonstruct<int> TurboTime;
|
||||
extern buttonstruct<bool> AutoHold;
|
||||
extern volatile bool execute;
|
||||
extern BOOL click;
|
||||
|
||||
/*
|
||||
* The firmware language values
|
||||
*/
|
||||
#define NDS_FW_LANG_JAP 0
|
||||
#define NDS_FW_LANG_ENG 1
|
||||
#define NDS_FW_LANG_FRE 2
|
||||
#define NDS_FW_LANG_GER 3
|
||||
#define NDS_FW_LANG_ITA 4
|
||||
#define NDS_FW_LANG_SPA 5
|
||||
#define NDS_FW_LANG_CHI 6
|
||||
#define NDS_FW_LANG_RES 7
|
||||
|
||||
extern BaseDriver *driver;
|
||||
extern CFIRMWARE *firmware;
|
||||
|
||||
#define DSGBA_LOADER_SIZE 512
|
||||
enum
|
||||
{
|
||||
ROM_NDS = 0,
|
||||
ROM_DSGBA
|
||||
};
|
||||
|
||||
//#define LOG_ARM9
|
||||
//#define LOG_ARM7
|
||||
|
||||
#include "PACKED.h"
|
||||
struct NDS_header
|
||||
{
|
||||
char gameTile[12]; // 000 - Game Title (uppercase ASCII, padded with 00h)
|
||||
char gameCode[4]; // 00C - Gamecode (uppercase ASCII, NTR-<code>, 0=homebrew)
|
||||
u16 makerCode; // 010 - Makercode (uppercase ASCII, 0=homebrew)
|
||||
u8 unitCode; // 012 - Unitcode (00h=Nintendo DS)
|
||||
u8 deviceCode; // 013 - Encryption Seed Select (00..07h, usually 00h)
|
||||
u8 cardSize; // 014 - Devicecapacity (Chipsize = 128KB SHL nn) (eg. 7 = 16MB)
|
||||
u8 reserved1[8]; // 015 - Must be set to 0x00
|
||||
u8 region; // 01D - Specific region: 0x80 - China, 0x40 - Korea, 0x00 - Other
|
||||
u8 romversion; // 01E - ROM Version (usually 00h)
|
||||
u8 autostart; // 01F - Autostart (Bit2: Skip "Press Button" after Health and Safety)
|
||||
// (Also skips bootmenu, even in Manual mode & even Start pressed)
|
||||
u32 ARM9src; // 020 - ARM9 rom_offset (4000h and up, align 1000h)
|
||||
u32 ARM9exe; // 024 - ARM9 entry_address (2000000h..23BFE00h)
|
||||
u32 ARM9cpy; // 028 - ARM9 ram_address (2000000h..23BFE00h)
|
||||
u32 ARM9binSize; // 02C - ARM9 size (max 3BFE00h) (3839.5KB)
|
||||
|
||||
u32 ARM7src; // 030 - ARM7 rom_offset (8000h and up)
|
||||
u32 ARM7exe; // 034 - ARM7 entry_address (2000000h..23BFE00h, or 37F8000h..3807E00h)
|
||||
u32 ARM7cpy; // 038 - ARM7 ram_address (2000000h..23BFE00h, or 37F8000h..3807E00h)
|
||||
u32 ARM7binSize; // 03C - ARM7 size (max 3BFE00h, or FE00h) (3839.5KB, 63.5KB)
|
||||
|
||||
u32 FNameTblOff; // 040 - File Name Table (FNT) offset
|
||||
u32 FNameTblSize; // 044 - File Name Table (FNT) size
|
||||
|
||||
u32 FATOff; // 048 - File Allocation Table (FAT) offset
|
||||
u32 FATSize; // 04C - File Allocation Table (FAT) size
|
||||
|
||||
u32 ARM9OverlayOff; // 050 - File ARM9 overlay_offset
|
||||
u32 ARM9OverlaySize; // 054 - File ARM9 overlay_size
|
||||
u32 ARM7OverlayOff; // 058 - File ARM7 overlay_offset
|
||||
u32 ARM7OverlaySize; // 05C - File ARM7 overlay_size
|
||||
|
||||
u32 normalCmd; // 060 - Port 40001A4h setting for normal commands (usually 00586000h)
|
||||
u32 Key1Cmd; // 064 - Port 40001A4h setting for KEY1 commands (usually 001808F8h)
|
||||
|
||||
u32 IconOff; // 068 - Icon_title_offset (0=None) (8000h and up)
|
||||
u16 CRC16; // 06C - Secure Area Checksum, CRC-16 of [ [20h]..7FFFh] - Calculations with this algorithm use 0xffff as the initial value
|
||||
u16 ROMtimeout; // 06E - Secure Area Loading Timeout (usually 051Eh)
|
||||
u32 ARM9autoload; // 070 - ARM9 Auto Load List RAM Address
|
||||
u32 ARM7autoload; // 074 - ARM7 Auto Load List RAM Address
|
||||
|
||||
u8 infoResevedRegion[8]; // 078 - ROM Information Reserved Region (must be set to 0x00)
|
||||
u32 endROMoffset; // 080 - Total Used ROM size (remaining/unused bytes usually FFh-padded)
|
||||
u32 HeaderSize; // 084 - ROM Header Size (4000h)
|
||||
u32 ARM9module; // 088 - ARM9 Module Parameter Address (auto-load parameters)
|
||||
u32 ARM7module; // 08C - ARM7 Module Parameter Address (auto-load parameters)
|
||||
u8 reserved2[48]; // 090 - Must be set to 0x00 - "PASS" is contained within here?
|
||||
u8 logo[156]; // 0C0 - Nintendo Logo (compressed bitmap, same as in GBA Headers)
|
||||
u16 logoCRC16; // 15C - Nintendo Logo Checksum, CRC-16 of [0C0h-15Bh], fixed CF56h
|
||||
u16 headerCRC16; // 15E - Header Checksum, CRC-16 of [000h-15Dh]
|
||||
u8 reserved[160]; // Must be set to 0x00
|
||||
};
|
||||
#include "PACKED_END.h"
|
||||
|
||||
extern void debug();
|
||||
void emu_halt();
|
||||
|
||||
extern u64 nds_timer;
|
||||
void NDS_Reschedule();
|
||||
void NDS_RescheduleGXFIFO(u32 cost);
|
||||
void NDS_RescheduleDMA();
|
||||
void NDS_RescheduleTimers();
|
||||
|
||||
enum ENSATA_HANDSHAKE
|
||||
{
|
||||
ENSATA_HANDSHAKE_none = 0,
|
||||
ENSATA_HANDSHAKE_query = 1,
|
||||
ENSATA_HANDSHAKE_ack = 2,
|
||||
ENSATA_HANDSHAKE_confirm = 3,
|
||||
ENSATA_HANDSHAKE_complete = 4,
|
||||
};
|
||||
|
||||
enum NDS_CONSOLE_TYPE
|
||||
{
|
||||
NDS_CONSOLE_TYPE_FAT = 0xFF,
|
||||
NDS_CONSOLE_TYPE_LITE = 0x20,
|
||||
NDS_CONSOLE_TYPE_IQUE = 0x43,
|
||||
NDS_CONSOLE_TYPE_IQUE_LIE = 0x63,
|
||||
NDS_CONSOLE_TYPE_DSI = 0xFE
|
||||
};
|
||||
|
||||
struct NDSSystem
|
||||
{
|
||||
s32 wifiCycle;
|
||||
s32 cycles;
|
||||
u64 timerCycle[2][4];
|
||||
u32 VCount;
|
||||
u32 old;
|
||||
|
||||
//raw adc touch coords for old NDS
|
||||
u16 adc_touchX;
|
||||
u16 adc_touchY;
|
||||
s32 adc_jitterctr;
|
||||
BOOL stylusJitter;
|
||||
|
||||
//the DSI returns calibrated touch coords from its TSC (?), so we need to save these separately
|
||||
u16 scr_touchX;
|
||||
u16 scr_touchY;
|
||||
|
||||
//whether the console is using our faked-bootup process
|
||||
BOOL isFakeBooted;
|
||||
|
||||
BOOL isTouch;
|
||||
u16 pad;
|
||||
|
||||
u16 paddle;
|
||||
|
||||
u8 *FW_ARM9BootCode;
|
||||
u8 *FW_ARM7BootCode;
|
||||
u32 FW_ARM9BootCodeAddr;
|
||||
u32 FW_ARM7BootCodeAddr;
|
||||
u32 FW_ARM9BootCodeSize;
|
||||
u32 FW_ARM7BootCodeSize;
|
||||
|
||||
BOOL sleeping;
|
||||
BOOL cardEjected;
|
||||
u32 freezeBus;
|
||||
|
||||
//this is not essential NDS runtime state.
|
||||
//it was perhaps a mistake to put it here.
|
||||
//it is far less important than the above.
|
||||
//maybe I should move it.
|
||||
s32 idleCycles[2];
|
||||
s32 runCycleCollector[2][16];
|
||||
s32 idleFrameCounter;
|
||||
s32 cpuloopIterationCount; //counts the number of times during a frame that a reschedule happened
|
||||
|
||||
//console type must be copied in when the system boots. it can't be changed on the fly.
|
||||
int ConsoleType;
|
||||
bool Is_DSI() { return ConsoleType == NDS_CONSOLE_TYPE_DSI; }
|
||||
bool Is_DebugConsole() { return _DebugConsole!=0; }
|
||||
BOOL _DebugConsole;
|
||||
|
||||
//set if the user requests ensata emulation
|
||||
BOOL ensataEmulation;
|
||||
|
||||
//there is a hack in the ipc sync for ensata. this tracks its state
|
||||
u32 ensataIpcSyncCounter;
|
||||
|
||||
//maintains the state of the ensata handshaking protocol
|
||||
u32 ensataHandshake;
|
||||
|
||||
struct {
|
||||
u8 lcd, gpuMain, gfx3d_render, gfx3d_geometry, gpuSub, dispswap;
|
||||
} power1; //POWCNT1
|
||||
|
||||
struct {
|
||||
u8 speakers, wifi /*(initial value=0)*/;
|
||||
} power2; //POWCNT2
|
||||
|
||||
bool isInVblank() const { return VCount >= 192; }
|
||||
bool isIn3dVblank() const { return VCount >= 192 && VCount<215; }
|
||||
};
|
||||
|
||||
/** /brief A touchscreen calibration point.
|
||||
*/
|
||||
struct NDS_fw_touchscreen_cal {
|
||||
u16 adc_x;
|
||||
u16 adc_y;
|
||||
|
||||
u8 screen_x;
|
||||
u8 screen_y;
|
||||
};
|
||||
|
||||
#define MAX_FW_NICKNAME_LENGTH 10
|
||||
#define MAX_FW_MESSAGE_LENGTH 26
|
||||
|
||||
struct NDS_fw_config_data
|
||||
{
|
||||
NDS_CONSOLE_TYPE ds_type;
|
||||
|
||||
u8 fav_colour;
|
||||
u8 birth_month;
|
||||
u8 birth_day;
|
||||
|
||||
u16 nickname[MAX_FW_NICKNAME_LENGTH];
|
||||
u8 nickname_len;
|
||||
|
||||
u16 message[MAX_FW_MESSAGE_LENGTH];
|
||||
u8 message_len;
|
||||
|
||||
u8 language;
|
||||
|
||||
//touchscreen calibration
|
||||
NDS_fw_touchscreen_cal touch_cal[2];
|
||||
};
|
||||
|
||||
extern NDSSystem nds;
|
||||
|
||||
int NDS_Init();
|
||||
|
||||
void Desmume_InitOnce();
|
||||
|
||||
void NDS_DeInit(void);
|
||||
|
||||
BOOL NDS_SetROM(u8 * rom, u32 mask);
|
||||
NDS_header * NDS_getROMHeader(void);
|
||||
|
||||
struct RomBanner
|
||||
{
|
||||
RomBanner(bool defaultInit = true);
|
||||
u16 version; //Version (0001h)
|
||||
u16 crc16; //CRC16 across entries 020h..83Fh
|
||||
u8 reserved[0x1C]; //Reserved (zero-filled)
|
||||
u8 bitmap[0x200]; //Icon Bitmap (32x32 pix) (4x4 tiles, each 4x8 bytes, 4bit depth)
|
||||
u16 palette[0x10]; //Icon Palette (16 colors, 16bit, range 0000h-7FFFh) (Color 0 is transparent, so the 1st palette entry is ignored)
|
||||
enum { NUM_TITLES = 6 };
|
||||
union {
|
||||
struct {
|
||||
u16 title_jp[0x80]; //Title 0 Japanese (128 characters, 16bit Unicode)
|
||||
u16 title_en[0x80]; //Title 1 English ("")
|
||||
u16 title_fr[0x80]; //Title 2 French ("")
|
||||
u16 title_de[0x80]; //Title 3 German ("")
|
||||
u16 title_it[0x80]; //Title 4 Italian ("")
|
||||
u16 title_es[0x80]; //Title 5 Spanish ("")
|
||||
};
|
||||
u16 titles[NUM_TITLES][0x80];
|
||||
};
|
||||
u8 end0xFF[0x1C0];
|
||||
//840h ? (Maybe newer/chinese firmware do also support chinese title?)
|
||||
//840h - End of Icon/Title structure (next 1C0h bytes usually FFh-filled)
|
||||
};
|
||||
|
||||
struct GameInfo
|
||||
{
|
||||
FILE *fROM;
|
||||
u8 *romdata;
|
||||
u32 romsize;
|
||||
u32 cardSize;
|
||||
u32 mask;
|
||||
u32 crc;
|
||||
u32 chipID;
|
||||
u32 lastReadPos;
|
||||
u32 romType;
|
||||
u32 headerOffset;
|
||||
char ROMserial[20];
|
||||
char ROMname[20];
|
||||
bool _isDSiEnhanced;
|
||||
NDS_header header;
|
||||
//a copy of the pristine secure area from the rom
|
||||
u8 secureArea[0x4000];
|
||||
RomBanner banner;
|
||||
const RomBanner& getRomBanner();
|
||||
|
||||
GameInfo() : fROM(NULL),
|
||||
romdata(NULL),
|
||||
crc(0),
|
||||
chipID(0x00000FC2),
|
||||
romsize(0),
|
||||
cardSize(0),
|
||||
mask(0),
|
||||
lastReadPos(0xFFFFFFFF),
|
||||
romType(ROM_NDS),
|
||||
headerOffset(0),
|
||||
_isDSiEnhanced(false)
|
||||
{
|
||||
memset(&header, 0, sizeof(header));
|
||||
memset(&ROMserial[0], 0, sizeof(ROMserial));
|
||||
memset(&ROMname[0], 0, sizeof(ROMname));
|
||||
}
|
||||
|
||||
~GameInfo() { closeROM(); }
|
||||
|
||||
bool loadROM(std::string fname, u32 type = ROM_NDS);
|
||||
void closeROM();
|
||||
u32 readROM(u32 pos);
|
||||
void populate();
|
||||
bool isDSiEnhanced();
|
||||
bool isHomebrew();
|
||||
bool hasRomBanner();
|
||||
|
||||
};
|
||||
|
||||
typedef struct TSCalInfo
|
||||
{
|
||||
struct
|
||||
{
|
||||
u16 x1, x2;
|
||||
u16 y1, y2;
|
||||
u16 width;
|
||||
u16 height;
|
||||
} adc;
|
||||
|
||||
struct
|
||||
{
|
||||
u8 x1, x2;
|
||||
u8 y1, y2;
|
||||
u16 width;
|
||||
u16 height;
|
||||
} scr;
|
||||
|
||||
} TSCalInfo;
|
||||
|
||||
extern GameInfo gameInfo;
|
||||
|
||||
|
||||
struct UserButtons : buttonstruct<bool>
|
||||
{
|
||||
};
|
||||
struct UserTouch
|
||||
{
|
||||
u16 touchX;
|
||||
u16 touchY;
|
||||
bool isTouch;
|
||||
};
|
||||
struct UserMicrophone
|
||||
{
|
||||
u32 micButtonPressed;
|
||||
};
|
||||
struct UserInput
|
||||
{
|
||||
UserButtons buttons;
|
||||
UserTouch touch;
|
||||
UserMicrophone mic;
|
||||
};
|
||||
|
||||
// set physical user input
|
||||
// these functions merely request the input to be changed.
|
||||
// the actual change happens later at a specific time during the frame.
|
||||
// this is to minimize the risk of desyncs.
|
||||
void NDS_setTouchPos(u16 x, u16 y);
|
||||
void NDS_releaseTouch(void);
|
||||
void NDS_setPad(bool right,bool left,bool down,bool up,bool select,bool start,bool B,bool A,bool Y,bool X,bool leftShoulder,bool rightShoulder,bool debug, bool lid);
|
||||
void NDS_setMic(bool pressed);
|
||||
|
||||
// get physical user input
|
||||
// not including the results of autofire/etc.
|
||||
// the effects of calls to "set physical user input" functions will be immediately reflected here though.
|
||||
const UserInput& NDS_getRawUserInput();
|
||||
const UserInput& NDS_getPrevRawUserInput();
|
||||
|
||||
// get final (fully processed) user input
|
||||
// this should match whatever was or would be sent to the game
|
||||
const UserInput& NDS_getFinalUserInput();
|
||||
|
||||
// set/get to-be-processed or in-the-middle-of-being-processed user input
|
||||
// to process input, simply call this function and edit the return value.
|
||||
// (applying autofire is one example of processing the input.)
|
||||
// (movie playback is another example.)
|
||||
// this must be done after the raw user input is set
|
||||
// and before that input is sent to the game's memory.
|
||||
UserInput& NDS_getProcessingUserInput();
|
||||
bool NDS_isProcessingUserInput();
|
||||
// call once per frame to prepare input for processing
|
||||
void NDS_beginProcessingInput();
|
||||
// call once per frame to copy the processed input to the final input
|
||||
void NDS_endProcessingInput();
|
||||
|
||||
// this is in case something needs reentrancy while processing input
|
||||
void NDS_suspendProcessingInput(bool suspend);
|
||||
|
||||
|
||||
|
||||
int NDS_LoadROM(const char *filename, const char* physicalFilename=0, const char* logicalFilename=0);
|
||||
void NDS_FreeROM(void);
|
||||
void NDS_Reset();
|
||||
|
||||
bool NDS_LegitBoot();
|
||||
bool NDS_FakeBoot();
|
||||
|
||||
void nds_savestate(EMUFILE* os);
|
||||
bool nds_loadstate(EMUFILE* is, int size);
|
||||
|
||||
void NDS_Sleep();
|
||||
void NDS_TriggerCardEjectIRQ();
|
||||
|
||||
void NDS_SkipNextFrame();
|
||||
#define NDS_SkipFrame(s) if(s) NDS_SkipNext2DFrame();
|
||||
void NDS_OmitFrameSkip(int force=0);
|
||||
|
||||
void NDS_debug_break();
|
||||
void NDS_debug_continue();
|
||||
void NDS_debug_step();
|
||||
|
||||
int NDS_GetCPUCoreCount();
|
||||
void NDS_SetupDefaultFirmware();
|
||||
|
||||
//void execHardware_doAllDma(EDMAMode modeNum);
|
||||
|
||||
template<bool FORCE> void NDS_exec(s32 nb = 560190<<1);
|
||||
|
||||
extern int lagframecounter;
|
||||
|
||||
extern struct TCommonSettings {
|
||||
TCommonSettings()
|
||||
: GFX3D_HighResolutionInterpolateColor(true)
|
||||
, GFX3D_EdgeMark(true)
|
||||
, GFX3D_Fog(true)
|
||||
, GFX3D_Texture(true)
|
||||
, GFX3D_LineHack(true)
|
||||
, GFX3D_Zelda_Shadow_Depth_Hack(0)
|
||||
, GFX3D_Renderer_Multisample(false)
|
||||
, GFX3D_TXTHack(false)
|
||||
, jit_max_block_size(100)
|
||||
, loadToMemory(false)
|
||||
, UseExtBIOS(false)
|
||||
, SWIFromBIOS(false)
|
||||
, PatchSWI3(false)
|
||||
, UseExtFirmware(false)
|
||||
, UseExtFirmwareSettings(false)
|
||||
, BootFromFirmware(false)
|
||||
, DebugConsole(false)
|
||||
, EnsataEmulation(false)
|
||||
, cheatsDisable(false)
|
||||
, rigorous_timing(false)
|
||||
, advanced_timing(true)
|
||||
, micMode(InternalNoise)
|
||||
, spuInterpolationMode(1)
|
||||
, manualBackupType(0)
|
||||
, autodetectBackupMethod(0)
|
||||
, spu_captureMuted(false)
|
||||
, spu_advanced(false)
|
||||
, StylusPressure(50)
|
||||
, ConsoleType(NDS_CONSOLE_TYPE_FAT)
|
||||
, StylusJitter(false)
|
||||
, backupSave(false)
|
||||
, SPU_sync_mode(0)
|
||||
, SPU_sync_method(0)
|
||||
{
|
||||
strcpy(ARM9BIOS, "biosnds9.bin");
|
||||
strcpy(ARM7BIOS, "biosnds7.bin");
|
||||
strcpy(Firmware, "firmware.bin");
|
||||
|
||||
/* WIFI mode: adhoc = 0, infrastructure = 1 */
|
||||
wifi.mode = 1;
|
||||
wifi.infraBridgeAdapter = 0;
|
||||
|
||||
for(int i=0;i<16;i++)
|
||||
spu_muteChannels[i] = false;
|
||||
|
||||
for(int g=0;g<2;g++)
|
||||
for(int x=0;x<5;x++)
|
||||
dispLayers[g][x]=true;
|
||||
#ifdef HAVE_JIT
|
||||
//zero 06-sep-2012 - shouldnt be defaulting this to true for now, since the jit is buggy.
|
||||
//id rather have people discover a bonus speedhack than discover new bugs in a new version
|
||||
use_jit = false;
|
||||
#else
|
||||
use_jit = false;
|
||||
#endif
|
||||
|
||||
num_cores = NDS_GetCPUCoreCount();
|
||||
NDS_SetupDefaultFirmware();
|
||||
}
|
||||
bool GFX3D_HighResolutionInterpolateColor;
|
||||
bool GFX3D_EdgeMark;
|
||||
bool GFX3D_Fog;
|
||||
bool GFX3D_Texture;
|
||||
bool GFX3D_LineHack;
|
||||
int GFX3D_Zelda_Shadow_Depth_Hack;
|
||||
bool GFX3D_Renderer_Multisample;
|
||||
bool GFX3D_TXTHack;
|
||||
|
||||
bool loadToMemory;
|
||||
|
||||
bool UseExtBIOS;
|
||||
char ARM9BIOS[256];
|
||||
char ARM7BIOS[256];
|
||||
bool SWIFromBIOS;
|
||||
bool PatchSWI3;
|
||||
|
||||
bool UseExtFirmware;
|
||||
bool UseExtFirmwareSettings;
|
||||
char Firmware[256];
|
||||
bool BootFromFirmware;
|
||||
NDS_fw_config_data fw_config;
|
||||
|
||||
NDS_CONSOLE_TYPE ConsoleType;
|
||||
bool DebugConsole;
|
||||
bool EnsataEmulation;
|
||||
|
||||
bool cheatsDisable;
|
||||
|
||||
int num_cores;
|
||||
bool single_core() { return num_cores==1; }
|
||||
bool rigorous_timing;
|
||||
|
||||
int StylusPressure;
|
||||
bool StylusJitter;
|
||||
|
||||
bool dispLayers[2][5];
|
||||
|
||||
FAST_ALIGN bool advanced_timing;
|
||||
|
||||
bool use_jit;
|
||||
u32 jit_max_block_size;
|
||||
|
||||
struct _Wifi {
|
||||
int mode;
|
||||
int infraBridgeAdapter;
|
||||
} wifi;
|
||||
|
||||
enum MicMode
|
||||
{
|
||||
InternalNoise = 0,
|
||||
Sample = 1,
|
||||
Random = 2,
|
||||
Physical = 3,
|
||||
} micMode;
|
||||
|
||||
|
||||
int spuInterpolationMode;
|
||||
|
||||
//this is a temporary hack until we straighten out the flushing logic and/or gxfifo
|
||||
//int gfx3d_flushMode;
|
||||
|
||||
int autodetectBackupMethod;
|
||||
//this is the user's choice of manual backup type, for cases when the autodetection can't be trusted
|
||||
int manualBackupType;
|
||||
bool backupSave;
|
||||
|
||||
int SPU_sync_mode;
|
||||
int SPU_sync_method;
|
||||
|
||||
bool spu_muteChannels[16];
|
||||
bool spu_captureMuted;
|
||||
bool spu_advanced;
|
||||
|
||||
struct _ShowGpu {
|
||||
_ShowGpu() : main(true), sub(true) {}
|
||||
union {
|
||||
struct { bool main,sub; };
|
||||
bool screens[2];
|
||||
};
|
||||
} showGpu;
|
||||
|
||||
struct _Hud {
|
||||
_Hud()
|
||||
: ShowInputDisplay(false)
|
||||
, ShowGraphicalInputDisplay(false)
|
||||
, FpsDisplay(false)
|
||||
, FrameCounterDisplay(false)
|
||||
, ShowLagFrameCounter(false)
|
||||
, ShowMicrophone(false)
|
||||
, ShowRTC(false)
|
||||
{}
|
||||
bool ShowInputDisplay, ShowGraphicalInputDisplay, FpsDisplay, FrameCounterDisplay, ShowLagFrameCounter, ShowMicrophone, ShowRTC;
|
||||
} hud;
|
||||
|
||||
std::string run_advanscene_import;
|
||||
|
||||
} CommonSettings;
|
||||
|
||||
void NDS_RunAdvansceneAutoImport();
|
||||
|
||||
extern std::string InputDisplayString;
|
||||
extern int LagFrameFlag;
|
||||
extern int lastLag, TotalLagFrames;
|
||||
|
||||
void MovieSRAM();
|
||||
|
||||
void ClearAutoHold(void);
|
||||
|
||||
bool ValidateSlot2Access(u32 procnum, u32 demandSRAMSpeed, u32 demand1stROMSpeed, u32 demand2ndROMSpeed, int clockbits);
|
||||
|
||||
//MUSTANG
|
||||
//extern ADVANsCEne advsc;
|
||||
|
||||
#endif
|
||||
|
||||
Executable
+2896
File diff suppressed because it is too large
Load Diff
Executable
+610
@@ -0,0 +1,610 @@
|
||||
/*
|
||||
Copyright (C) 2006 yopyop
|
||||
Copyright (C) 2006-2007 shash
|
||||
Copyright (C) 2008-2015 DeSmuME team
|
||||
|
||||
This file is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This file is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with the this software. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef OGLRENDER_H
|
||||
#define OGLRENDER_H
|
||||
|
||||
#include <queue>
|
||||
#include <set>
|
||||
#include <string>
|
||||
#include "render3D.h"
|
||||
#include "types.h"
|
||||
|
||||
#ifndef OGLRENDER_3_2_H
|
||||
|
||||
#if defined(_WIN32)
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
#include <GL/gl.h>
|
||||
#include <GL/glext.h>
|
||||
|
||||
#define OGLEXT(procPtr, func) procPtr func = NULL;
|
||||
#define INITOGLEXT(procPtr, func) func = (procPtr)wglGetProcAddress(#func);
|
||||
#define EXTERNOGLEXT(procPtr, func) extern procPtr func;
|
||||
#elif defined(__APPLE__)
|
||||
#include <OpenGL/gl.h>
|
||||
#include <OpenGL/glext.h>
|
||||
|
||||
// Ignore dynamic linking on Apple OS
|
||||
#define OGLEXT(procPtr, func)
|
||||
#define INITOGLEXT(procPtr, func)
|
||||
#define EXTERNOGLEXT(procPtr, func)
|
||||
|
||||
// We're not exactly committing to OpenGL 3.2 Core Profile just yet, so redefine APPLE
|
||||
// extensions as a temporary measure.
|
||||
#if defined(GL_APPLE_vertex_array_object) && !defined(GL_ARB_vertex_array_object)
|
||||
#define glGenVertexArrays(n, ids) glGenVertexArraysAPPLE(n, ids)
|
||||
#define glBindVertexArray(id) glBindVertexArrayAPPLE(id)
|
||||
#define glDeleteVertexArrays(n, ids) glDeleteVertexArraysAPPLE(n, ids)
|
||||
#endif
|
||||
#else
|
||||
#include <GL/gl.h>
|
||||
#include <GL/glext.h>
|
||||
#include <GL/glx.h>
|
||||
|
||||
/* This is a workaround needed to compile against nvidia GL headers */
|
||||
#ifndef GL_ALPHA_BLEND_EQUATION_ATI
|
||||
#undef GL_VERSION_1_3
|
||||
#endif
|
||||
|
||||
#define OGLEXT(procPtr, func) procPtr func = NULL;
|
||||
#define INITOGLEXT(procPtr, func) func = (procPtr)glXGetProcAddress((const GLubyte *) #func);
|
||||
#define EXTERNOGLEXT(procPtr, func) extern procPtr func;
|
||||
#endif
|
||||
|
||||
// Check minimum OpenGL header version
|
||||
#if !defined(GL_VERSION_2_1)
|
||||
#if defined(GL_VERSION_2_0)
|
||||
#warning Using OpenGL v2.0 headers with v2.1 overrides. Some features will be disabled.
|
||||
|
||||
#if !defined(GL_ARB_framebuffer_object)
|
||||
// Overrides for GL_EXT_framebuffer_blit
|
||||
#if !defined(GL_EXT_framebuffer_blit)
|
||||
#define GL_READ_FRAMEBUFFER_EXT GL_FRAMEBUFFER_EXT
|
||||
#define GL_DRAW_FRAMEBUFFER_EXT GL_FRAMEBUFFER_EXT
|
||||
#define glBlitFramebufferEXT(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter)
|
||||
#endif
|
||||
|
||||
// Overrides for GL_EXT_framebuffer_multisample
|
||||
#if !defined(GL_EXT_framebuffer_multisample)
|
||||
#define GL_MAX_SAMPLES_EXT 0
|
||||
#define glRenderbufferStorageMultisampleEXT(target, samples, internalformat, width, height)
|
||||
#endif
|
||||
|
||||
// Overrides for GL_ARB_pixel_buffer_object
|
||||
#if !defined(GL_PIXEL_PACK_BUFFER) && defined(GL_PIXEL_PACK_BUFFER_ARB)
|
||||
#define GL_PIXEL_PACK_BUFFER GL_PIXEL_PACK_BUFFER_ARB
|
||||
#endif
|
||||
#endif
|
||||
#else
|
||||
#error OpenGL requires v2.1 headers or later.
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// Textures
|
||||
#if !defined(GLX_H)
|
||||
EXTERNOGLEXT(PFNGLACTIVETEXTUREPROC, glActiveTexture) // Core in v1.3
|
||||
EXTERNOGLEXT(PFNGLACTIVETEXTUREARBPROC, glActiveTextureARB)
|
||||
#endif
|
||||
|
||||
// Blending
|
||||
EXTERNOGLEXT(PFNGLBLENDFUNCSEPARATEPROC, glBlendFuncSeparate) // Core in v1.4
|
||||
EXTERNOGLEXT(PFNGLBLENDEQUATIONSEPARATEPROC, glBlendEquationSeparate) // Core in v2.0
|
||||
|
||||
EXTERNOGLEXT(PFNGLBLENDFUNCSEPARATEEXTPROC, glBlendFuncSeparateEXT)
|
||||
EXTERNOGLEXT(PFNGLBLENDEQUATIONSEPARATEEXTPROC, glBlendEquationSeparateEXT)
|
||||
|
||||
// Shaders
|
||||
EXTERNOGLEXT(PFNGLCREATESHADERPROC, glCreateShader) // Core in v2.0
|
||||
EXTERNOGLEXT(PFNGLSHADERSOURCEPROC, glShaderSource) // Core in v2.0
|
||||
EXTERNOGLEXT(PFNGLCOMPILESHADERPROC, glCompileShader) // Core in v2.0
|
||||
EXTERNOGLEXT(PFNGLCREATEPROGRAMPROC, glCreateProgram) // Core in v2.0
|
||||
EXTERNOGLEXT(PFNGLATTACHSHADERPROC, glAttachShader) // Core in v2.0
|
||||
EXTERNOGLEXT(PFNGLDETACHSHADERPROC, glDetachShader) // Core in v2.0
|
||||
EXTERNOGLEXT(PFNGLLINKPROGRAMPROC, glLinkProgram) // Core in v2.0
|
||||
EXTERNOGLEXT(PFNGLUSEPROGRAMPROC, glUseProgram) // Core in v2.0
|
||||
EXTERNOGLEXT(PFNGLGETSHADERIVPROC, glGetShaderiv) // Core in v2.0
|
||||
EXTERNOGLEXT(PFNGLGETSHADERINFOLOGPROC, glGetShaderInfoLog) // Core in v2.0
|
||||
EXTERNOGLEXT(PFNGLDELETESHADERPROC, glDeleteShader) // Core in v2.0
|
||||
EXTERNOGLEXT(PFNGLDELETEPROGRAMPROC, glDeleteProgram) // Core in v2.0
|
||||
EXTERNOGLEXT(PFNGLGETPROGRAMIVPROC, glGetProgramiv) // Core in v2.0
|
||||
EXTERNOGLEXT(PFNGLGETPROGRAMINFOLOGPROC, glGetProgramInfoLog) // Core in v2.0
|
||||
EXTERNOGLEXT(PFNGLVALIDATEPROGRAMPROC, glValidateProgram) // Core in v2.0
|
||||
EXTERNOGLEXT(PFNGLGETUNIFORMLOCATIONPROC, glGetUniformLocation) // Core in v2.0
|
||||
EXTERNOGLEXT(PFNGLUNIFORM1IPROC, glUniform1i) // Core in v2.0
|
||||
EXTERNOGLEXT(PFNGLUNIFORM1IVPROC, glUniform1iv) // Core in v2.0
|
||||
EXTERNOGLEXT(PFNGLUNIFORM1FPROC, glUniform1f) // Core in v2.0
|
||||
EXTERNOGLEXT(PFNGLUNIFORM2FPROC, glUniform2f) // Core in v2.0
|
||||
EXTERNOGLEXT(PFNGLDRAWBUFFERSPROC, glDrawBuffers) // Core in v2.0
|
||||
|
||||
// Generic vertex attributes
|
||||
EXTERNOGLEXT(PFNGLBINDATTRIBLOCATIONPROC, glBindAttribLocation) // Core in v2.0
|
||||
EXTERNOGLEXT(PFNGLENABLEVERTEXATTRIBARRAYPROC, glEnableVertexAttribArray) // Core in v2.0
|
||||
EXTERNOGLEXT(PFNGLDISABLEVERTEXATTRIBARRAYPROC, glDisableVertexAttribArray) // Core in v2.0
|
||||
EXTERNOGLEXT(PFNGLVERTEXATTRIBPOINTERPROC, glVertexAttribPointer) // Core in v2.0
|
||||
|
||||
// VAO
|
||||
EXTERNOGLEXT(PFNGLGENVERTEXARRAYSPROC, glGenVertexArrays)
|
||||
EXTERNOGLEXT(PFNGLDELETEVERTEXARRAYSPROC, glDeleteVertexArrays)
|
||||
EXTERNOGLEXT(PFNGLBINDVERTEXARRAYPROC, glBindVertexArray)
|
||||
|
||||
// VBO and PBO
|
||||
EXTERNOGLEXT(PFNGLGENBUFFERSARBPROC, glGenBuffersARB)
|
||||
EXTERNOGLEXT(PFNGLDELETEBUFFERSARBPROC, glDeleteBuffersARB)
|
||||
EXTERNOGLEXT(PFNGLBINDBUFFERARBPROC, glBindBufferARB)
|
||||
EXTERNOGLEXT(PFNGLBUFFERDATAARBPROC, glBufferDataARB)
|
||||
EXTERNOGLEXT(PFNGLBUFFERSUBDATAARBPROC, glBufferSubDataARB)
|
||||
EXTERNOGLEXT(PFNGLMAPBUFFERARBPROC, glMapBufferARB)
|
||||
EXTERNOGLEXT(PFNGLUNMAPBUFFERARBPROC, glUnmapBufferARB)
|
||||
|
||||
EXTERNOGLEXT(PFNGLGENBUFFERSPROC, glGenBuffers) // Core in v1.5
|
||||
EXTERNOGLEXT(PFNGLDELETEBUFFERSPROC, glDeleteBuffers) // Core in v1.5
|
||||
EXTERNOGLEXT(PFNGLBINDBUFFERPROC, glBindBuffer) // Core in v1.5
|
||||
EXTERNOGLEXT(PFNGLBUFFERDATAPROC, glBufferData) // Core in v1.5
|
||||
EXTERNOGLEXT(PFNGLBUFFERSUBDATAPROC, glBufferSubData) // Core in v1.5
|
||||
EXTERNOGLEXT(PFNGLMAPBUFFERPROC, glMapBuffer) // Core in v1.5
|
||||
EXTERNOGLEXT(PFNGLUNMAPBUFFERPROC, glUnmapBuffer) // Core in v1.5
|
||||
|
||||
// FBO
|
||||
EXTERNOGLEXT(PFNGLGENFRAMEBUFFERSEXTPROC, glGenFramebuffersEXT)
|
||||
EXTERNOGLEXT(PFNGLBINDFRAMEBUFFEREXTPROC, glBindFramebufferEXT)
|
||||
EXTERNOGLEXT(PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC, glFramebufferRenderbufferEXT)
|
||||
EXTERNOGLEXT(PFNGLFRAMEBUFFERTEXTURE2DEXTPROC, glFramebufferTexture2DEXT)
|
||||
EXTERNOGLEXT(PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC, glCheckFramebufferStatusEXT)
|
||||
EXTERNOGLEXT(PFNGLDELETEFRAMEBUFFERSEXTPROC, glDeleteFramebuffersEXT)
|
||||
EXTERNOGLEXT(PFNGLBLITFRAMEBUFFEREXTPROC, glBlitFramebufferEXT)
|
||||
|
||||
// Multisampled FBO
|
||||
EXTERNOGLEXT(PFNGLGENRENDERBUFFERSEXTPROC, glGenRenderbuffersEXT)
|
||||
EXTERNOGLEXT(PFNGLBINDRENDERBUFFEREXTPROC, glBindRenderbufferEXT)
|
||||
EXTERNOGLEXT(PFNGLRENDERBUFFERSTORAGEEXTPROC, glRenderbufferStorageEXT)
|
||||
EXTERNOGLEXT(PFNGLRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC, glRenderbufferStorageMultisampleEXT)
|
||||
EXTERNOGLEXT(PFNGLDELETERENDERBUFFERSEXTPROC, glDeleteRenderbuffersEXT)
|
||||
|
||||
#else // OGLRENDER_3_2_H
|
||||
|
||||
// Basic Functions
|
||||
EXTERNOGLEXT(PFNGLGETSTRINGIPROC, glGetStringi) // Core in v3.0
|
||||
|
||||
// Textures
|
||||
#if !defined(GLX_H)
|
||||
EXTERNOGLEXT(PFNGLACTIVETEXTUREPROC, glActiveTexture) // Core in v1.3
|
||||
#endif
|
||||
|
||||
// Blending
|
||||
EXTERNOGLEXT(PFNGLBLENDFUNCSEPARATEPROC, glBlendFuncSeparate) // Core in v1.4
|
||||
EXTERNOGLEXT(PFNGLBLENDEQUATIONSEPARATEPROC, glBlendEquationSeparate) // Core in v2.0
|
||||
|
||||
// Shaders
|
||||
EXTERNOGLEXT(PFNGLCREATESHADERPROC, glCreateShader) // Core in v2.0
|
||||
EXTERNOGLEXT(PFNGLSHADERSOURCEPROC, glShaderSource) // Core in v2.0
|
||||
EXTERNOGLEXT(PFNGLCOMPILESHADERPROC, glCompileShader) // Core in v2.0
|
||||
EXTERNOGLEXT(PFNGLCREATEPROGRAMPROC, glCreateProgram) // Core in v2.0
|
||||
EXTERNOGLEXT(PFNGLATTACHSHADERPROC, glAttachShader) // Core in v2.0
|
||||
EXTERNOGLEXT(PFNGLDETACHSHADERPROC, glDetachShader) // Core in v2.0
|
||||
EXTERNOGLEXT(PFNGLLINKPROGRAMPROC, glLinkProgram) // Core in v2.0
|
||||
EXTERNOGLEXT(PFNGLUSEPROGRAMPROC, glUseProgram) // Core in v2.0
|
||||
EXTERNOGLEXT(PFNGLGETSHADERIVPROC, glGetShaderiv) // Core in v2.0
|
||||
EXTERNOGLEXT(PFNGLGETSHADERINFOLOGPROC, glGetShaderInfoLog) // Core in v2.0
|
||||
EXTERNOGLEXT(PFNGLDELETESHADERPROC, glDeleteShader) // Core in v2.0
|
||||
EXTERNOGLEXT(PFNGLDELETEPROGRAMPROC, glDeleteProgram) // Core in v2.0
|
||||
EXTERNOGLEXT(PFNGLGETPROGRAMIVPROC, glGetProgramiv) // Core in v2.0
|
||||
EXTERNOGLEXT(PFNGLGETPROGRAMINFOLOGPROC, glGetProgramInfoLog) // Core in v2.0
|
||||
EXTERNOGLEXT(PFNGLVALIDATEPROGRAMPROC, glValidateProgram) // Core in v2.0
|
||||
EXTERNOGLEXT(PFNGLGETUNIFORMLOCATIONPROC, glGetUniformLocation) // Core in v2.0
|
||||
EXTERNOGLEXT(PFNGLUNIFORM1IPROC, glUniform1i) // Core in v2.0
|
||||
EXTERNOGLEXT(PFNGLUNIFORM1IVPROC, glUniform1iv) // Core in v2.0
|
||||
EXTERNOGLEXT(PFNGLUNIFORM1FPROC, glUniform1f) // Core in v2.0
|
||||
EXTERNOGLEXT(PFNGLUNIFORM2FPROC, glUniform2f) // Core in v2.0
|
||||
EXTERNOGLEXT(PFNGLDRAWBUFFERSPROC, glDrawBuffers) // Core in v2.0
|
||||
|
||||
// Generic vertex attributes
|
||||
EXTERNOGLEXT(PFNGLBINDATTRIBLOCATIONPROC, glBindAttribLocation) // Core in v2.0
|
||||
EXTERNOGLEXT(PFNGLBINDFRAGDATALOCATIONPROC, glBindFragDataLocation) // Core in v3.0
|
||||
EXTERNOGLEXT(PFNGLENABLEVERTEXATTRIBARRAYPROC, glEnableVertexAttribArray) // Core in v2.0
|
||||
EXTERNOGLEXT(PFNGLDISABLEVERTEXATTRIBARRAYPROC, glDisableVertexAttribArray) // Core in v2.0
|
||||
EXTERNOGLEXT(PFNGLVERTEXATTRIBPOINTERPROC, glVertexAttribPointer) // Core in v2.0
|
||||
|
||||
// VAO
|
||||
EXTERNOGLEXT(PFNGLGENVERTEXARRAYSPROC, glGenVertexArrays) // Core in v3.0
|
||||
EXTERNOGLEXT(PFNGLDELETEVERTEXARRAYSPROC, glDeleteVertexArrays) // Core in v3.0
|
||||
EXTERNOGLEXT(PFNGLBINDVERTEXARRAYPROC, glBindVertexArray) // Core in v3.0
|
||||
|
||||
// VBO and PBO
|
||||
EXTERNOGLEXT(PFNGLGENBUFFERSPROC, glGenBuffers) // Core in v1.5
|
||||
EXTERNOGLEXT(PFNGLDELETEBUFFERSPROC, glDeleteBuffers) // Core in v1.5
|
||||
EXTERNOGLEXT(PFNGLBINDBUFFERPROC, glBindBuffer) // Core in v1.5
|
||||
EXTERNOGLEXT(PFNGLBUFFERDATAPROC, glBufferData) // Core in v1.5
|
||||
EXTERNOGLEXT(PFNGLBUFFERSUBDATAPROC, glBufferSubData) // Core in v1.5
|
||||
EXTERNOGLEXT(PFNGLMAPBUFFERPROC, glMapBuffer) // Core in v1.5
|
||||
EXTERNOGLEXT(PFNGLUNMAPBUFFERPROC, glUnmapBuffer) // Core in v1.5
|
||||
|
||||
// FBO
|
||||
EXTERNOGLEXT(PFNGLGENFRAMEBUFFERSPROC, glGenFramebuffers) // Core in v3.0
|
||||
EXTERNOGLEXT(PFNGLBINDFRAMEBUFFERPROC, glBindFramebuffer) // Core in v3.0
|
||||
EXTERNOGLEXT(PFNGLFRAMEBUFFERRENDERBUFFERPROC, glFramebufferRenderbuffer) // Core in v3.0
|
||||
EXTERNOGLEXT(PFNGLFRAMEBUFFERTEXTURE2DPROC, glFramebufferTexture2D) // Core in v3.0
|
||||
EXTERNOGLEXT(PFNGLCHECKFRAMEBUFFERSTATUSPROC, glCheckFramebufferStatus) // Core in v3.0
|
||||
EXTERNOGLEXT(PFNGLDELETEFRAMEBUFFERSPROC, glDeleteFramebuffers) // Core in v3.0
|
||||
EXTERNOGLEXT(PFNGLBLITFRAMEBUFFERPROC, glBlitFramebuffer) // Core in v3.0
|
||||
EXTERNOGLEXT(PFNGLDRAWBUFFERSPROC, glDrawBuffers) // Core in v2.0
|
||||
|
||||
// Multisampled FBO
|
||||
EXTERNOGLEXT(PFNGLGENRENDERBUFFERSPROC, glGenRenderbuffers) // Core in v3.0
|
||||
EXTERNOGLEXT(PFNGLBINDRENDERBUFFERPROC, glBindRenderbuffer) // Core in v3.0
|
||||
EXTERNOGLEXT(PFNGLRENDERBUFFERSTORAGEPROC, glRenderbufferStorage) // Core in v3.0
|
||||
EXTERNOGLEXT(PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC, glRenderbufferStorageMultisample) // Core in v3.0
|
||||
EXTERNOGLEXT(PFNGLDELETERENDERBUFFERSPROC, glDeleteRenderbuffers) // Core in v3.0
|
||||
|
||||
#endif // OGLRENDER_3_2_H
|
||||
|
||||
// Define the minimum required OpenGL version for the driver to support
|
||||
#define OGLRENDER_MINIMUM_DRIVER_VERSION_REQUIRED_MAJOR 1
|
||||
#define OGLRENDER_MINIMUM_DRIVER_VERSION_REQUIRED_MINOR 2
|
||||
#define OGLRENDER_MINIMUM_DRIVER_VERSION_REQUIRED_REVISION 0
|
||||
|
||||
#define OGLRENDER_MAX_MULTISAMPLES 16
|
||||
#define OGLRENDER_VERT_INDEX_BUFFER_COUNT 131072
|
||||
|
||||
enum OGLVertexAttributeID
|
||||
{
|
||||
OGLVertexAttributeID_Position = 0,
|
||||
OGLVertexAttributeID_TexCoord0 = 8,
|
||||
OGLVertexAttributeID_Color = 3,
|
||||
};
|
||||
|
||||
enum OGLTextureUnitID
|
||||
{
|
||||
// Main textures will always be on texture unit 0.
|
||||
OGLTextureUnitID_ToonTable = 1,
|
||||
OGLTextureUnitID_ClearImage
|
||||
};
|
||||
|
||||
enum OGLErrorCode
|
||||
{
|
||||
OGLERROR_NOERR = RENDER3DERROR_NOERR,
|
||||
|
||||
OGLERROR_FEATURE_UNSUPPORTED,
|
||||
OGLERROR_VBO_UNSUPPORTED,
|
||||
OGLERROR_PBO_UNSUPPORTED,
|
||||
OGLERROR_SHADER_UNSUPPORTED,
|
||||
OGLERROR_VAO_UNSUPPORTED,
|
||||
OGLERROR_FBO_UNSUPPORTED,
|
||||
OGLERROR_MULTISAMPLED_FBO_UNSUPPORTED,
|
||||
|
||||
OGLERROR_VERTEX_SHADER_PROGRAM_LOAD_ERROR,
|
||||
OGLERROR_FRAGMENT_SHADER_PROGRAM_LOAD_ERROR,
|
||||
OGLERROR_SHADER_CREATE_ERROR,
|
||||
|
||||
OGLERROR_FBO_CREATE_ERROR
|
||||
};
|
||||
|
||||
struct OGLRenderRef
|
||||
{
|
||||
// OpenGL Feature Support
|
||||
GLint stateTexMirroredRepeat;
|
||||
|
||||
// VBO
|
||||
GLuint vboVertexID;
|
||||
GLuint iboIndexID;
|
||||
|
||||
// PBO
|
||||
GLuint pboRenderDataID[2];
|
||||
|
||||
// FBO
|
||||
GLuint texClearImageColorID;
|
||||
GLuint texClearImageDepthStencilID;
|
||||
|
||||
GLuint rboFragColorID;
|
||||
GLuint rboFragDepthStencilID;
|
||||
GLuint rboMSFragColorID;
|
||||
GLuint rboMSFragDepthStencilID;
|
||||
|
||||
GLuint fboClearImageID;
|
||||
GLuint fboMSIntermediateRenderID;
|
||||
GLuint fboRenderID;
|
||||
GLuint selectedRenderingFBO;
|
||||
|
||||
// Shader states
|
||||
GLuint vertexShaderID;
|
||||
GLuint fragmentShaderID;
|
||||
GLuint shaderProgram;
|
||||
|
||||
GLint uniformTexScale;
|
||||
|
||||
GLint uniformStateToonShadingMode;
|
||||
GLint uniformStateEnableAlphaTest;
|
||||
GLint uniformStateUseWDepth;
|
||||
GLint uniformStateAlphaTestRef;
|
||||
|
||||
GLint uniformPolyMode;
|
||||
GLint uniformPolyAlpha;
|
||||
GLint uniformPolyID;
|
||||
|
||||
GLint uniformPolyEnableTexture;
|
||||
|
||||
GLuint texToonTableID;
|
||||
|
||||
// VAO
|
||||
GLuint vaoMainStatesID;
|
||||
|
||||
// Textures
|
||||
std::queue<GLuint> freeTextureIDs;
|
||||
|
||||
// Client-side Buffers
|
||||
GLfloat *color4fBuffer;
|
||||
CACHE_ALIGN GLushort vertIndexBuffer[OGLRENDER_VERT_INDEX_BUFFER_COUNT];
|
||||
};
|
||||
|
||||
struct GFX3D_State;
|
||||
struct VERTLIST;
|
||||
struct POLYLIST;
|
||||
struct INDEXLIST;
|
||||
struct POLY;
|
||||
class TexCacheItem;
|
||||
class OpenGLRenderer;
|
||||
|
||||
extern GPU3DInterface gpu3Dgl;
|
||||
extern GPU3DInterface gpu3DglOld;
|
||||
extern GPU3DInterface gpu3Dgl_3_2;
|
||||
|
||||
//This is called by OGLRender whenever it initializes.
|
||||
//Platforms, please be sure to set this up.
|
||||
//return true if you successfully init.
|
||||
extern bool (*oglrender_init)();
|
||||
|
||||
//This is called by OGLRender before it uses opengl.
|
||||
//return true if youre OK with using opengl
|
||||
extern bool (*oglrender_beginOpenGL)();
|
||||
|
||||
//This is called by OGLRender after it is done using opengl.
|
||||
extern void (*oglrender_endOpenGL)();
|
||||
|
||||
// These functions need to be assigned by ports that support using an
|
||||
// OpenGL 3.2 Core Profile context. The OGLRender_3_2.cpp file includes
|
||||
// the corresponding functions to assign to each function pointer.
|
||||
//
|
||||
// If any of these functions are unassigned, then one of the legacy OpenGL
|
||||
// renderers will be used instead.
|
||||
extern void (*OGLLoadEntryPoints_3_2_Func)();
|
||||
extern void (*OGLCreateRenderer_3_2_Func)(OpenGLRenderer **rendererPtr);
|
||||
|
||||
FORCEINLINE u32 BGRA8888_32_To_RGBA6665_32(const u32 srcPix);
|
||||
FORCEINLINE u32 BGRA8888_32Rev_To_RGBA6665_32Rev(const u32 srcPix);
|
||||
bool IsVersionSupported(unsigned int checkVersionMajor, unsigned int checkVersionMinor, unsigned int checkVersionRevision);
|
||||
|
||||
class OpenGLRenderer : public Render3D
|
||||
{
|
||||
private:
|
||||
// Driver's OpenGL Version
|
||||
unsigned int versionMajor;
|
||||
unsigned int versionMinor;
|
||||
unsigned int versionRevision;
|
||||
|
||||
protected:
|
||||
// OpenGL-specific References
|
||||
OGLRenderRef *ref;
|
||||
|
||||
// OpenGL Feature Support
|
||||
bool isVBOSupported;
|
||||
bool isPBOSupported;
|
||||
bool isFBOSupported;
|
||||
bool isMultisampledFBOSupported;
|
||||
bool isShaderSupported;
|
||||
bool isVAOSupported;
|
||||
|
||||
// Textures
|
||||
TexCacheItem *currTexture;
|
||||
|
||||
CACHE_ALIGN u32 GPU_screen3D[2][GFX3D_FRAMEBUFFER_WIDTH * GFX3D_FRAMEBUFFER_HEIGHT * sizeof(u32)];
|
||||
bool gpuScreen3DHasNewData[2];
|
||||
size_t doubleBufferIndex;
|
||||
u8 clearImageStencilValue;
|
||||
|
||||
// OpenGL-specific methods
|
||||
virtual Render3DError CreateVBOs() = 0;
|
||||
virtual void DestroyVBOs() = 0;
|
||||
virtual Render3DError CreatePBOs() = 0;
|
||||
virtual void DestroyPBOs() = 0;
|
||||
virtual Render3DError CreateFBOs() = 0;
|
||||
virtual void DestroyFBOs() = 0;
|
||||
virtual Render3DError CreateMultisampledFBO() = 0;
|
||||
virtual void DestroyMultisampledFBO() = 0;
|
||||
virtual Render3DError CreateShaders(const std::string *vertexShaderProgram, const std::string *fragmentShaderProgram) = 0;
|
||||
virtual void DestroyShaders() = 0;
|
||||
virtual Render3DError CreateVAOs() = 0;
|
||||
virtual void DestroyVAOs() = 0;
|
||||
virtual Render3DError InitTextures() = 0;
|
||||
virtual Render3DError InitFinalRenderStates(const std::set<std::string> *oglExtensionSet) = 0;
|
||||
virtual Render3DError InitTables() = 0;
|
||||
|
||||
virtual Render3DError LoadShaderPrograms(std::string *outVertexShaderProgram, std::string *outFragmentShaderProgram) = 0;
|
||||
virtual Render3DError SetupShaderIO() = 0;
|
||||
virtual Render3DError CreateToonTable() = 0;
|
||||
virtual Render3DError DestroyToonTable() = 0;
|
||||
virtual Render3DError UploadToonTable(const u16 *toonTableBuffer) = 0;
|
||||
virtual Render3DError UploadClearImage(const u16 *clearImageColor16Buffer, const u32 *clearImageDepthStencilBuffer) = 0;
|
||||
|
||||
virtual void GetExtensionSet(std::set<std::string> *oglExtensionSet) = 0;
|
||||
virtual Render3DError ExpandFreeTextures() = 0;
|
||||
virtual Render3DError SetupVertices(const VERTLIST *vertList, const POLYLIST *polyList, const INDEXLIST *indexList, GLushort *outIndexBuffer, size_t *outIndexCount) = 0;
|
||||
virtual Render3DError EnableVertexAttributes(const VERTLIST *vertList, const GLushort *indexBuffer, const size_t vertIndexCount) = 0;
|
||||
virtual Render3DError DisableVertexAttributes() = 0;
|
||||
virtual Render3DError SelectRenderingFramebuffer() = 0;
|
||||
virtual Render3DError DownsampleFBO() = 0;
|
||||
virtual Render3DError ReadBackPixels() = 0;
|
||||
|
||||
// Base rendering methods
|
||||
virtual Render3DError BeginRender(const GFX3D_State *renderState) = 0;
|
||||
virtual Render3DError PreRender(const GFX3D_State *renderState, const VERTLIST *vertList, const POLYLIST *polyList, const INDEXLIST *indexList) = 0;
|
||||
virtual Render3DError DoRender(const GFX3D_State *renderState, const VERTLIST *vertList, const POLYLIST *polyList, const INDEXLIST *indexList) = 0;
|
||||
virtual Render3DError PostRender() = 0;
|
||||
virtual Render3DError EndRender(const u64 frameCount) = 0;
|
||||
|
||||
virtual Render3DError UpdateClearImage(const u16 *__restrict colorBuffer, const u32 *__restrict depthStencilBuffer) = 0;
|
||||
virtual Render3DError UpdateToonTable(const u16 *toonTableBuffer) = 0;
|
||||
|
||||
virtual Render3DError ClearUsingImage() const = 0;
|
||||
virtual Render3DError ClearUsingValues(const u8 r, const u8 g, const u8 b, const u8 a, const u32 clearDepth, const u8 clearStencil) const = 0;
|
||||
|
||||
virtual Render3DError SetupPolygon(const POLY *thePoly) = 0;
|
||||
virtual Render3DError SetupTexture(const POLY *thePoly, bool enableTexturing) = 0;
|
||||
virtual Render3DError SetupViewport(const u32 viewportValue) = 0;
|
||||
|
||||
public:
|
||||
OpenGLRenderer();
|
||||
virtual ~OpenGLRenderer() {};
|
||||
|
||||
virtual Render3DError InitExtensions() = 0;
|
||||
virtual Render3DError Reset() = 0;
|
||||
virtual Render3DError RenderFinish() = 0;
|
||||
|
||||
virtual Render3DError DeleteTexture(const TexCacheItem *item) = 0;
|
||||
|
||||
bool IsExtensionPresent(const std::set<std::string> *oglExtensionSet, const std::string extensionName) const;
|
||||
bool ValidateShaderCompile(GLuint theShader) const;
|
||||
bool ValidateShaderProgramLink(GLuint theProgram) const;
|
||||
void GetVersion(unsigned int *major, unsigned int *minor, unsigned int *revision) const;
|
||||
void SetVersion(unsigned int major, unsigned int minor, unsigned int revision);
|
||||
void ConvertFramebuffer(const u32 *__restrict srcBuffer, u32 *dstBuffer);
|
||||
};
|
||||
|
||||
class OpenGLRenderer_1_2 : public OpenGLRenderer
|
||||
{
|
||||
protected:
|
||||
// OpenGL-specific methods
|
||||
virtual Render3DError CreateVBOs();
|
||||
virtual void DestroyVBOs();
|
||||
virtual Render3DError CreatePBOs();
|
||||
virtual void DestroyPBOs();
|
||||
virtual Render3DError CreateFBOs();
|
||||
virtual void DestroyFBOs();
|
||||
virtual Render3DError CreateMultisampledFBO();
|
||||
virtual void DestroyMultisampledFBO();
|
||||
virtual Render3DError CreateShaders(const std::string *vertexShaderProgram, const std::string *fragmentShaderProgram);
|
||||
virtual void DestroyShaders();
|
||||
virtual Render3DError CreateVAOs();
|
||||
virtual void DestroyVAOs();
|
||||
virtual Render3DError InitTextures();
|
||||
virtual Render3DError InitFinalRenderStates(const std::set<std::string> *oglExtensionSet);
|
||||
virtual Render3DError InitTables();
|
||||
|
||||
virtual Render3DError LoadShaderPrograms(std::string *outVertexShaderProgram, std::string *outFragmentShaderProgram);
|
||||
virtual Render3DError SetupShaderIO();
|
||||
virtual Render3DError CreateToonTable();
|
||||
virtual Render3DError DestroyToonTable();
|
||||
virtual Render3DError UploadToonTable(const u16 *toonTableBuffer);
|
||||
virtual Render3DError UploadClearImage(const u16 *clearImageColor16Buffer, const u32 *clearImageDepthStencilBuffer);
|
||||
|
||||
virtual void GetExtensionSet(std::set<std::string> *oglExtensionSet);
|
||||
virtual Render3DError ExpandFreeTextures();
|
||||
virtual Render3DError SetupVertices(const VERTLIST *vertList, const POLYLIST *polyList, const INDEXLIST *indexList, GLushort *outIndexBuffer, size_t *outIndexCount);
|
||||
virtual Render3DError EnableVertexAttributes(const VERTLIST *vertList, const GLushort *indexBuffer, const size_t vertIndexCount);
|
||||
virtual Render3DError DisableVertexAttributes();
|
||||
virtual Render3DError SelectRenderingFramebuffer();
|
||||
virtual Render3DError DownsampleFBO();
|
||||
virtual Render3DError ReadBackPixels();
|
||||
|
||||
// Base rendering methods
|
||||
virtual Render3DError BeginRender(const GFX3D_State *renderState);
|
||||
virtual Render3DError PreRender(const GFX3D_State *renderState, const VERTLIST *vertList, const POLYLIST *polyList, const INDEXLIST *indexList);
|
||||
virtual Render3DError DoRender(const GFX3D_State *renderState, const VERTLIST *vertList, const POLYLIST *polyList, const INDEXLIST *indexList);
|
||||
virtual Render3DError PostRender();
|
||||
virtual Render3DError EndRender(const u64 frameCount);
|
||||
|
||||
virtual Render3DError UpdateClearImage(const u16 *__restrict colorBuffer, const u32 *__restrict depthStencilBuffer);
|
||||
virtual Render3DError UpdateToonTable(const u16 *toonTableBuffer);
|
||||
|
||||
virtual Render3DError ClearUsingImage() const;
|
||||
virtual Render3DError ClearUsingValues(const u8 r, const u8 g, const u8 b, const u8 a, const u32 clearDepth, const u8 clearStencil) const;
|
||||
|
||||
virtual Render3DError SetupPolygon(const POLY *thePoly);
|
||||
virtual Render3DError SetupTexture(const POLY *thePoly, bool enableTexturing);
|
||||
virtual Render3DError SetupViewport(const u32 viewportValue);
|
||||
|
||||
public:
|
||||
OpenGLRenderer_1_2();
|
||||
~OpenGLRenderer_1_2();
|
||||
|
||||
virtual Render3DError InitExtensions();
|
||||
virtual Render3DError Reset();
|
||||
virtual Render3DError RenderFinish();
|
||||
|
||||
virtual Render3DError DeleteTexture(const TexCacheItem *item);
|
||||
};
|
||||
|
||||
class OpenGLRenderer_1_3 : public OpenGLRenderer_1_2
|
||||
{
|
||||
protected:
|
||||
virtual Render3DError UploadToonTable(const u16 *toonTableBuffer);
|
||||
virtual Render3DError UploadClearImage(const u16 *clearImageColor16Buffer, const u32 *clearImageDepthStencilBuffer);
|
||||
};
|
||||
|
||||
class OpenGLRenderer_1_4 : public OpenGLRenderer_1_3
|
||||
{
|
||||
protected:
|
||||
virtual Render3DError InitFinalRenderStates(const std::set<std::string> *oglExtensionSet);
|
||||
};
|
||||
|
||||
class OpenGLRenderer_1_5 : public OpenGLRenderer_1_4
|
||||
{
|
||||
protected:
|
||||
virtual Render3DError CreateVBOs();
|
||||
virtual void DestroyVBOs();
|
||||
virtual Render3DError CreatePBOs();
|
||||
virtual void DestroyPBOs();
|
||||
virtual Render3DError CreateVAOs();
|
||||
|
||||
virtual Render3DError EnableVertexAttributes(const VERTLIST *vertList, const GLushort *indexBuffer, const size_t vertIndexCount);
|
||||
virtual Render3DError DisableVertexAttributes();
|
||||
virtual Render3DError ReadBackPixels();
|
||||
|
||||
public:
|
||||
~OpenGLRenderer_1_5();
|
||||
|
||||
virtual Render3DError RenderFinish();
|
||||
};
|
||||
|
||||
class OpenGLRenderer_2_0 : public OpenGLRenderer_1_5
|
||||
{
|
||||
protected:
|
||||
virtual Render3DError InitExtensions();
|
||||
virtual Render3DError InitFinalRenderStates(const std::set<std::string> *oglExtensionSet);
|
||||
|
||||
virtual Render3DError SetupVertices(const VERTLIST *vertList, const POLYLIST *polyList, const INDEXLIST *indexList, GLushort *outIndexBuffer, size_t *outIndexCount);
|
||||
virtual Render3DError EnableVertexAttributes(const VERTLIST *vertList, const GLushort *indexBuffer, const size_t vertIndexCount);
|
||||
virtual Render3DError DisableVertexAttributes();
|
||||
|
||||
virtual Render3DError BeginRender(const GFX3D_State *renderState);
|
||||
virtual Render3DError PreRender(const GFX3D_State *renderState, const VERTLIST *vertList, const POLYLIST *polyList, const INDEXLIST *indexList);
|
||||
|
||||
virtual Render3DError SetupPolygon(const POLY *thePoly);
|
||||
virtual Render3DError SetupTexture(const POLY *thePoly, bool enableTexturing);
|
||||
};
|
||||
|
||||
class OpenGLRenderer_2_1 : public OpenGLRenderer_2_0
|
||||
{
|
||||
protected:
|
||||
virtual Render3DError ReadBackPixels();
|
||||
|
||||
public:
|
||||
virtual Render3DError RenderFinish();
|
||||
};
|
||||
|
||||
#endif
|
||||
Executable
+550
@@ -0,0 +1,550 @@
|
||||
/*
|
||||
Copyright (C) 2006 yopyop
|
||||
Copyright (C) 2006-2007 shash
|
||||
Copyright (C) 2008-2015 DeSmuME team
|
||||
|
||||
This file is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This file is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with the this software. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "OGLRender_3_2.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "debug.h"
|
||||
#include "gfx3d.h"
|
||||
#include "NDSSystem.h"
|
||||
#include "texcache.h"
|
||||
|
||||
//------------------------------------------------------------
|
||||
|
||||
// Basic Functions
|
||||
OGLEXT(PFNGLGETSTRINGIPROC, glGetStringi) // Core in v3.0
|
||||
|
||||
// Shaders
|
||||
OGLEXT(PFNGLBINDFRAGDATALOCATIONPROC, glBindFragDataLocation) // Core in v3.0
|
||||
|
||||
// FBO
|
||||
OGLEXT(PFNGLGENFRAMEBUFFERSPROC, glGenFramebuffers) // Core in v3.0
|
||||
OGLEXT(PFNGLBINDFRAMEBUFFERPROC, glBindFramebuffer) // Core in v3.0
|
||||
OGLEXT(PFNGLFRAMEBUFFERRENDERBUFFERPROC, glFramebufferRenderbuffer) // Core in v3.0
|
||||
OGLEXT(PFNGLFRAMEBUFFERTEXTURE2DPROC, glFramebufferTexture2D) // Core in v3.0
|
||||
OGLEXT(PFNGLCHECKFRAMEBUFFERSTATUSPROC, glCheckFramebufferStatus) // Core in v3.0
|
||||
OGLEXT(PFNGLDELETEFRAMEBUFFERSPROC, glDeleteFramebuffers) // Core in v3.0
|
||||
OGLEXT(PFNGLBLITFRAMEBUFFERPROC, glBlitFramebuffer) // Core in v3.0
|
||||
OGLEXT(PFNGLGENRENDERBUFFERSPROC, glGenRenderbuffers) // Core in v3.0
|
||||
OGLEXT(PFNGLBINDRENDERBUFFERPROC, glBindRenderbuffer) // Core in v3.0
|
||||
OGLEXT(PFNGLRENDERBUFFERSTORAGEPROC, glRenderbufferStorage) // Core in v3.0
|
||||
OGLEXT(PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC, glRenderbufferStorageMultisample) // Core in v3.0
|
||||
OGLEXT(PFNGLDELETERENDERBUFFERSPROC, glDeleteRenderbuffers) // Core in v3.0
|
||||
|
||||
void OGLLoadEntryPoints_3_2()
|
||||
{
|
||||
// Basic Functions
|
||||
INITOGLEXT(PFNGLGETSTRINGIPROC, glGetStringi)
|
||||
|
||||
// Shaders
|
||||
INITOGLEXT(PFNGLBINDFRAGDATALOCATIONPROC, glBindFragDataLocation)
|
||||
|
||||
// FBO
|
||||
INITOGLEXT(PFNGLGENFRAMEBUFFERSPROC, glGenFramebuffers) // Promote to core version
|
||||
INITOGLEXT(PFNGLBINDFRAMEBUFFERPROC, glBindFramebuffer) // Promote to core version
|
||||
INITOGLEXT(PFNGLFRAMEBUFFERRENDERBUFFERPROC, glFramebufferRenderbuffer) // Promote to core version
|
||||
INITOGLEXT(PFNGLFRAMEBUFFERTEXTURE2DPROC, glFramebufferTexture2D) // Promote to core version
|
||||
INITOGLEXT(PFNGLCHECKFRAMEBUFFERSTATUSPROC, glCheckFramebufferStatus) // Promote to core version
|
||||
INITOGLEXT(PFNGLDELETEFRAMEBUFFERSPROC, glDeleteFramebuffers) // Promote to core version
|
||||
INITOGLEXT(PFNGLBLITFRAMEBUFFERPROC, glBlitFramebuffer) // Promote to core version
|
||||
INITOGLEXT(PFNGLGENRENDERBUFFERSPROC, glGenRenderbuffers) // Promote to core version
|
||||
INITOGLEXT(PFNGLBINDRENDERBUFFERPROC, glBindRenderbuffer) // Promote to core version
|
||||
INITOGLEXT(PFNGLRENDERBUFFERSTORAGEPROC, glRenderbufferStorage) // Promote to core version
|
||||
INITOGLEXT(PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC, glRenderbufferStorageMultisample) // Promote to core version
|
||||
INITOGLEXT(PFNGLDELETERENDERBUFFERSPROC, glDeleteRenderbuffers) // Promote to core version
|
||||
}
|
||||
|
||||
// Vertex Shader GLSL 1.50
|
||||
static const char *vertexShader_150 = {"\
|
||||
#version 150 \n\
|
||||
\n\
|
||||
in vec4 inPosition; \n\
|
||||
in vec2 inTexCoord0; \n\
|
||||
in vec3 inColor; \n\
|
||||
\n\
|
||||
uniform float polyAlpha; \n\
|
||||
uniform vec2 texScale; \n\
|
||||
\n\
|
||||
out vec4 vtxPosition; \n\
|
||||
out vec2 vtxTexCoord; \n\
|
||||
out vec4 vtxColor; \n\
|
||||
\n\
|
||||
void main() \n\
|
||||
{ \n\
|
||||
mat2 texScaleMtx = mat2( vec2(texScale.x, 0.0), \n\
|
||||
vec2( 0.0, texScale.y)); \n\
|
||||
\n\
|
||||
vtxPosition = inPosition; \n\
|
||||
vtxTexCoord = texScaleMtx * inTexCoord0; \n\
|
||||
vtxColor = vec4(inColor * 4.0, polyAlpha); \n\
|
||||
\n\
|
||||
gl_Position = vtxPosition; \n\
|
||||
} \n\
|
||||
"};
|
||||
|
||||
// Fragment Shader GLSL 1.50
|
||||
static const char *fragmentShader_150 = {"\
|
||||
#version 150 \n\
|
||||
\n\
|
||||
in vec4 vtxPosition; \n\
|
||||
in vec2 vtxTexCoord; \n\
|
||||
in vec4 vtxColor; \n\
|
||||
\n\
|
||||
uniform sampler2D texMainRender; \n\
|
||||
uniform sampler1D texToonTable; \n\
|
||||
\n\
|
||||
uniform int stateToonShadingMode; \n\
|
||||
uniform bool stateEnableAlphaTest; \n\
|
||||
uniform bool stateUseWDepth; \n\
|
||||
uniform float stateAlphaTestRef; \n\
|
||||
\n\
|
||||
uniform int polyMode; \n\
|
||||
uniform int polyID; \n\
|
||||
\n\
|
||||
uniform bool polyEnableTexture; \n\
|
||||
\n\
|
||||
out vec4 outFragColor; \n\
|
||||
\n\
|
||||
void main() \n\
|
||||
{ \n\
|
||||
vec4 mainTexColor = (polyEnableTexture) ? texture(texMainRender, vtxTexCoord) : vec4(1.0, 1.0, 1.0, 1.0); \n\
|
||||
vec4 tempFragColor = mainTexColor; \n\
|
||||
\n\
|
||||
if(polyMode == 0) \n\
|
||||
{ \n\
|
||||
tempFragColor = vtxColor * mainTexColor; \n\
|
||||
} \n\
|
||||
else if(polyMode == 1) \n\
|
||||
{ \n\
|
||||
tempFragColor.rgb = (polyEnableTexture) ? (mainTexColor.rgb * mainTexColor.a) + (vtxColor.rgb * (1.0 - mainTexColor.a)) : vtxColor.rgb; \n\
|
||||
tempFragColor.a = vtxColor.a; \n\
|
||||
} \n\
|
||||
else if(polyMode == 2) \n\
|
||||
{ \n\
|
||||
vec3 toonColor = vec3(texture(texToonTable, vtxColor.r).rgb); \n\
|
||||
tempFragColor.rgb = (stateToonShadingMode == 0) ? mainTexColor.rgb * toonColor.rgb : min((mainTexColor.rgb * vtxColor.rgb) + toonColor.rgb, 1.0); \n\
|
||||
tempFragColor.a = mainTexColor.a * vtxColor.a; \n\
|
||||
} \n\
|
||||
else if(polyMode == 3) \n\
|
||||
{ \n\
|
||||
if (polyID != 0) \n\
|
||||
{ \n\
|
||||
tempFragColor = vtxColor; \n\
|
||||
} \n\
|
||||
} \n\
|
||||
\n\
|
||||
if (tempFragColor.a == 0.0 || (stateEnableAlphaTest && tempFragColor.a < stateAlphaTestRef)) \n\
|
||||
{ \n\
|
||||
discard; \n\
|
||||
} \n\
|
||||
\n\
|
||||
float vertW = (vtxPosition.w == 0.0) ? 0.00000001 : vtxPosition.w; \n\
|
||||
gl_FragDepth = (stateUseWDepth) ? vtxPosition.w/4096.0 : clamp((vtxPosition.z/vertW) * 0.5 + 0.5, 0.0, 1.0); \n\
|
||||
outFragColor = tempFragColor; \n\
|
||||
} \n\
|
||||
"};
|
||||
|
||||
void OGLCreateRenderer_3_2(OpenGLRenderer **rendererPtr)
|
||||
{
|
||||
if (IsVersionSupported(3, 2, 0))
|
||||
{
|
||||
*rendererPtr = new OpenGLRenderer_3_2;
|
||||
(*rendererPtr)->SetVersion(3, 2, 0);
|
||||
}
|
||||
}
|
||||
|
||||
OpenGLRenderer_3_2::~OpenGLRenderer_3_2()
|
||||
{
|
||||
glFinish();
|
||||
|
||||
DestroyVAOs();
|
||||
DestroyFBOs();
|
||||
DestroyMultisampledFBO();
|
||||
}
|
||||
|
||||
Render3DError OpenGLRenderer_3_2::InitExtensions()
|
||||
{
|
||||
Render3DError error = OGLERROR_NOERR;
|
||||
OGLRenderRef &OGLRef = *this->ref;
|
||||
|
||||
// Get OpenGL extensions
|
||||
std::set<std::string> oglExtensionSet;
|
||||
this->GetExtensionSet(&oglExtensionSet);
|
||||
|
||||
// Initialize OpenGL
|
||||
this->InitTables();
|
||||
|
||||
// Load and create shaders. Return on any error, since v3.2 Core Profile makes shaders mandatory.
|
||||
this->isShaderSupported = true;
|
||||
|
||||
std::string vertexShaderProgram;
|
||||
std::string fragmentShaderProgram;
|
||||
error = this->LoadShaderPrograms(&vertexShaderProgram, &fragmentShaderProgram);
|
||||
if (error != OGLERROR_NOERR)
|
||||
{
|
||||
this->isShaderSupported = false;
|
||||
return error;
|
||||
}
|
||||
|
||||
error = this->CreateShaders(&vertexShaderProgram, &fragmentShaderProgram);
|
||||
if (error != OGLERROR_NOERR)
|
||||
{
|
||||
this->isShaderSupported = false;
|
||||
return error;
|
||||
}
|
||||
|
||||
this->CreateToonTable();
|
||||
|
||||
this->isVBOSupported = true;
|
||||
this->CreateVBOs();
|
||||
|
||||
this->isPBOSupported = true;
|
||||
this->CreatePBOs();
|
||||
|
||||
this->isVAOSupported = true;
|
||||
this->CreateVAOs();
|
||||
|
||||
// Load and create FBOs. Return on any error, since v3.2 Core Profile makes FBOs mandatory.
|
||||
this->isFBOSupported = true;
|
||||
error = this->CreateFBOs();
|
||||
if (error != OGLERROR_NOERR)
|
||||
{
|
||||
OGLRef.fboRenderID = 0;
|
||||
this->isFBOSupported = false;
|
||||
return error;
|
||||
}
|
||||
|
||||
this->isMultisampledFBOSupported = true;
|
||||
error = this->CreateMultisampledFBO();
|
||||
if (error != OGLERROR_NOERR)
|
||||
{
|
||||
OGLRef.selectedRenderingFBO = 0;
|
||||
this->isMultisampledFBOSupported = false;
|
||||
|
||||
if (error == OGLERROR_FBO_CREATE_ERROR)
|
||||
{
|
||||
// Return on OGLERROR_FBO_CREATE_ERROR, since a v3.0 driver should be able to
|
||||
// support FBOs.
|
||||
return error;
|
||||
}
|
||||
}
|
||||
|
||||
this->InitTextures();
|
||||
this->InitFinalRenderStates(&oglExtensionSet); // This must be done last
|
||||
|
||||
return OGLERROR_NOERR;
|
||||
}
|
||||
|
||||
Render3DError OpenGLRenderer_3_2::CreateFBOs()
|
||||
{
|
||||
OGLRenderRef &OGLRef = *this->ref;
|
||||
|
||||
// Set up FBO render targets
|
||||
glGenTextures(1, &OGLRef.texClearImageColorID);
|
||||
glGenTextures(1, &OGLRef.texClearImageDepthStencilID);
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, OGLRef.texClearImageColorID);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, GFX3D_FRAMEBUFFER_WIDTH, GFX3D_FRAMEBUFFER_HEIGHT, 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, NULL);
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, OGLRef.texClearImageDepthStencilID);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_NONE);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH24_STENCIL8, GFX3D_FRAMEBUFFER_WIDTH, GFX3D_FRAMEBUFFER_HEIGHT, 0, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, NULL);
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
|
||||
// Set up FBOs
|
||||
glGenFramebuffers(1, &OGLRef.fboClearImageID);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, OGLRef.fboClearImageID);
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, OGLRef.texClearImageColorID, 0);
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D, OGLRef.texClearImageDepthStencilID, 0);
|
||||
|
||||
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
|
||||
{
|
||||
INFO("OpenGL: Failed to created FBOs. Some emulation features will be disabled.\n");
|
||||
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
glDeleteFramebuffers(1, &OGLRef.fboClearImageID);
|
||||
glDeleteTextures(1, &OGLRef.texClearImageColorID);
|
||||
glDeleteTextures(1, &OGLRef.texClearImageDepthStencilID);
|
||||
|
||||
return OGLERROR_FBO_CREATE_ERROR;
|
||||
}
|
||||
|
||||
// Set up final output FBO
|
||||
glGenRenderbuffers(1, &OGLRef.rboFragColorID);
|
||||
glGenRenderbuffers(1, &OGLRef.rboFragDepthStencilID);
|
||||
glBindRenderbuffer(GL_RENDERBUFFER, OGLRef.rboFragColorID);
|
||||
glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA, GFX3D_FRAMEBUFFER_WIDTH, GFX3D_FRAMEBUFFER_HEIGHT);
|
||||
glBindRenderbuffer(GL_RENDERBUFFER, OGLRef.rboFragDepthStencilID);
|
||||
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, GFX3D_FRAMEBUFFER_WIDTH, GFX3D_FRAMEBUFFER_HEIGHT);
|
||||
|
||||
glGenFramebuffers(1, &OGLRef.fboRenderID);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, OGLRef.fboRenderID);
|
||||
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, OGLRef.rboFragColorID);
|
||||
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, OGLRef.rboFragDepthStencilID);
|
||||
|
||||
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
|
||||
{
|
||||
INFO("OpenGL: Failed to created FBOs. Some emulation features will be disabled.\n");
|
||||
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
glDeleteFramebuffers(1, &OGLRef.fboClearImageID);
|
||||
glDeleteTextures(1, &OGLRef.texClearImageColorID);
|
||||
glDeleteTextures(1, &OGLRef.texClearImageDepthStencilID);
|
||||
|
||||
glDeleteFramebuffers(1, &OGLRef.fboRenderID);
|
||||
glDeleteRenderbuffers(1, &OGLRef.rboFragColorID);
|
||||
glDeleteRenderbuffers(1, &OGLRef.rboFragDepthStencilID);
|
||||
|
||||
OGLRef.fboRenderID = 0;
|
||||
return OGLERROR_FBO_CREATE_ERROR;
|
||||
}
|
||||
|
||||
glReadBuffer(GL_COLOR_ATTACHMENT0);
|
||||
|
||||
INFO("OpenGL: Successfully created FBOs.\n");
|
||||
|
||||
return OGLERROR_NOERR;
|
||||
}
|
||||
|
||||
void OpenGLRenderer_3_2::DestroyFBOs()
|
||||
{
|
||||
if (!this->isFBOSupported)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
OGLRenderRef &OGLRef = *this->ref;
|
||||
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
glDeleteFramebuffers(1, &OGLRef.fboClearImageID);
|
||||
glDeleteTextures(1, &OGLRef.texClearImageColorID);
|
||||
glDeleteTextures(1, &OGLRef.texClearImageDepthStencilID);
|
||||
|
||||
glDeleteFramebuffers(1, &OGLRef.fboRenderID);
|
||||
glDeleteRenderbuffers(1, &OGLRef.rboFragColorID);
|
||||
glDeleteRenderbuffers(1, &OGLRef.rboFragDepthStencilID);
|
||||
|
||||
this->isFBOSupported = false;
|
||||
}
|
||||
|
||||
Render3DError OpenGLRenderer_3_2::CreateMultisampledFBO()
|
||||
{
|
||||
// Check the maximum number of samples that the GPU supports and use that.
|
||||
// Since our target resolution is only 256x192 pixels, using the most samples
|
||||
// possible is the best thing to do.
|
||||
GLint maxSamples = 0;
|
||||
glGetIntegerv(GL_MAX_SAMPLES, &maxSamples);
|
||||
|
||||
if (maxSamples < 2)
|
||||
{
|
||||
INFO("OpenGL: GPU does not support at least 2x multisampled FBOs. Multisample antialiasing will be disabled.\n");
|
||||
return OGLERROR_FEATURE_UNSUPPORTED;
|
||||
}
|
||||
else if (maxSamples > OGLRENDER_MAX_MULTISAMPLES)
|
||||
{
|
||||
maxSamples = OGLRENDER_MAX_MULTISAMPLES;
|
||||
}
|
||||
|
||||
OGLRenderRef &OGLRef = *this->ref;
|
||||
|
||||
// Set up FBO render targets
|
||||
glGenRenderbuffers(1, &OGLRef.rboMSFragColorID);
|
||||
glGenRenderbuffers(1, &OGLRef.rboMSFragDepthStencilID);
|
||||
|
||||
glBindRenderbuffer(GL_RENDERBUFFER, OGLRef.rboMSFragColorID);
|
||||
glRenderbufferStorageMultisample(GL_RENDERBUFFER, maxSamples, GL_RGBA, GFX3D_FRAMEBUFFER_WIDTH, GFX3D_FRAMEBUFFER_HEIGHT);
|
||||
glBindRenderbuffer(GL_RENDERBUFFER, OGLRef.rboMSFragDepthStencilID);
|
||||
glRenderbufferStorageMultisample(GL_RENDERBUFFER, maxSamples, GL_DEPTH24_STENCIL8, GFX3D_FRAMEBUFFER_WIDTH, GFX3D_FRAMEBUFFER_HEIGHT);
|
||||
|
||||
// Set up multisampled rendering FBO
|
||||
glGenFramebuffers(1, &OGLRef.fboMSIntermediateRenderID);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, OGLRef.fboMSIntermediateRenderID);
|
||||
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, OGLRef.rboMSFragColorID);
|
||||
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, OGLRef.rboMSFragDepthStencilID);
|
||||
|
||||
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
|
||||
{
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
glDeleteFramebuffers(1, &OGLRef.fboMSIntermediateRenderID);
|
||||
glDeleteRenderbuffers(1, &OGLRef.rboMSFragColorID);
|
||||
glDeleteRenderbuffers(1, &OGLRef.rboMSFragDepthStencilID);
|
||||
|
||||
INFO("OpenGL: Failed to create multisampled FBO. Multisample antialiasing will be disabled.\n");
|
||||
return OGLERROR_FBO_CREATE_ERROR;
|
||||
}
|
||||
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, OGLRef.fboRenderID);
|
||||
INFO("OpenGL: Successfully created multisampled FBO.\n");
|
||||
|
||||
return OGLERROR_NOERR;
|
||||
}
|
||||
|
||||
void OpenGLRenderer_3_2::DestroyMultisampledFBO()
|
||||
{
|
||||
if (!this->isMultisampledFBOSupported)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
OGLRenderRef &OGLRef = *this->ref;
|
||||
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
glDeleteFramebuffers(1, &OGLRef.fboMSIntermediateRenderID);
|
||||
glDeleteRenderbuffers(1, &OGLRef.rboMSFragColorID);
|
||||
glDeleteRenderbuffers(1, &OGLRef.rboMSFragDepthStencilID);
|
||||
|
||||
this->isMultisampledFBOSupported = false;
|
||||
}
|
||||
|
||||
Render3DError OpenGLRenderer_3_2::CreateVAOs()
|
||||
{
|
||||
OGLRenderRef &OGLRef = *this->ref;
|
||||
|
||||
glGenVertexArrays(1, &OGLRef.vaoMainStatesID);
|
||||
glBindVertexArray(OGLRef.vaoMainStatesID);
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, OGLRef.vboVertexID);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, OGLRef.iboIndexID);
|
||||
|
||||
glEnableVertexAttribArray(OGLVertexAttributeID_Position);
|
||||
glEnableVertexAttribArray(OGLVertexAttributeID_TexCoord0);
|
||||
glEnableVertexAttribArray(OGLVertexAttributeID_Color);
|
||||
|
||||
glVertexAttribPointer(OGLVertexAttributeID_Position, 4, GL_FLOAT, GL_FALSE, sizeof(VERT), (const GLvoid *)offsetof(VERT, coord));
|
||||
glVertexAttribPointer(OGLVertexAttributeID_TexCoord0, 2, GL_FLOAT, GL_FALSE, sizeof(VERT), (const GLvoid *)offsetof(VERT, texcoord));
|
||||
glVertexAttribPointer(OGLVertexAttributeID_Color, 3, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(VERT), (const GLvoid *)offsetof(VERT, color));
|
||||
|
||||
glBindVertexArray(0);
|
||||
|
||||
return OGLERROR_NOERR;
|
||||
}
|
||||
|
||||
void OpenGLRenderer_3_2::DestroyVAOs()
|
||||
{
|
||||
if (!this->isVAOSupported)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
glBindVertexArray(0);
|
||||
glDeleteVertexArrays(1, &this->ref->vaoMainStatesID);
|
||||
|
||||
this->isVAOSupported = false;
|
||||
}
|
||||
|
||||
Render3DError OpenGLRenderer_3_2::LoadShaderPrograms(std::string *outVertexShaderProgram, std::string *outFragmentShaderProgram)
|
||||
{
|
||||
*outVertexShaderProgram = std::string(vertexShader_150);
|
||||
*outFragmentShaderProgram = std::string(fragmentShader_150);
|
||||
|
||||
return OGLERROR_NOERR;
|
||||
}
|
||||
|
||||
Render3DError OpenGLRenderer_3_2::SetupShaderIO()
|
||||
{
|
||||
OGLRenderRef &OGLRef = *this->ref;
|
||||
|
||||
glBindAttribLocation(OGLRef.shaderProgram, OGLVertexAttributeID_Position, "inPosition");
|
||||
glBindAttribLocation(OGLRef.shaderProgram, OGLVertexAttributeID_TexCoord0, "inTexCoord0");
|
||||
glBindAttribLocation(OGLRef.shaderProgram, OGLVertexAttributeID_Color, "inColor");
|
||||
glBindFragDataLocation(OGLRef.shaderProgram, 0, "outFragColor");
|
||||
|
||||
return OGLERROR_NOERR;
|
||||
}
|
||||
|
||||
void OpenGLRenderer_3_2::GetExtensionSet(std::set<std::string> *oglExtensionSet)
|
||||
{
|
||||
GLint extensionCount = 0;
|
||||
|
||||
glGetIntegerv(GL_NUM_EXTENSIONS, &extensionCount);
|
||||
for (size_t i = 0; i < extensionCount; i++)
|
||||
{
|
||||
std::string extensionName = std::string((const char *)glGetStringi(GL_EXTENSIONS, i));
|
||||
oglExtensionSet->insert(extensionName);
|
||||
}
|
||||
}
|
||||
|
||||
Render3DError OpenGLRenderer_3_2::EnableVertexAttributes(const VERTLIST *vertList, const GLushort *indexBuffer, const size_t vertIndexCount)
|
||||
{
|
||||
OGLRenderRef &OGLRef = *this->ref;
|
||||
|
||||
glBindVertexArray(OGLRef.vaoMainStatesID);
|
||||
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(VERT) * vertList->count, vertList);
|
||||
glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, vertIndexCount * sizeof(GLushort), indexBuffer);
|
||||
|
||||
return OGLERROR_NOERR;
|
||||
}
|
||||
|
||||
Render3DError OpenGLRenderer_3_2::DisableVertexAttributes()
|
||||
{
|
||||
glBindVertexArray(0);
|
||||
return OGLERROR_NOERR;
|
||||
}
|
||||
|
||||
Render3DError OpenGLRenderer_3_2::SelectRenderingFramebuffer()
|
||||
{
|
||||
OGLRenderRef &OGLRef = *this->ref;
|
||||
static const GLenum drawDirect[1] = {GL_COLOR_ATTACHMENT0};
|
||||
|
||||
OGLRef.selectedRenderingFBO = (CommonSettings.GFX3D_Renderer_Multisample) ? OGLRef.fboMSIntermediateRenderID : OGLRef.fboRenderID;
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, OGLRef.selectedRenderingFBO);
|
||||
glDrawBuffers(1, &drawDirect[0]);
|
||||
|
||||
return OGLERROR_NOERR;
|
||||
}
|
||||
|
||||
Render3DError OpenGLRenderer_3_2::DownsampleFBO()
|
||||
{
|
||||
OGLRenderRef &OGLRef = *this->ref;
|
||||
|
||||
if (OGLRef.selectedRenderingFBO != OGLRef.fboMSIntermediateRenderID)
|
||||
{
|
||||
return OGLERROR_NOERR;
|
||||
}
|
||||
|
||||
glBindFramebuffer(GL_READ_FRAMEBUFFER, OGLRef.selectedRenderingFBO);
|
||||
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, OGLRef.fboRenderID);
|
||||
glBlitFramebuffer(0, 0, GFX3D_FRAMEBUFFER_WIDTH, GFX3D_FRAMEBUFFER_HEIGHT, 0, 0, GFX3D_FRAMEBUFFER_WIDTH, GFX3D_FRAMEBUFFER_HEIGHT, GL_COLOR_BUFFER_BIT, GL_NEAREST);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, OGLRef.fboRenderID);
|
||||
|
||||
return OGLERROR_NOERR;
|
||||
}
|
||||
|
||||
Render3DError OpenGLRenderer_3_2::ClearUsingImage() const
|
||||
{
|
||||
OGLRenderRef &OGLRef = *this->ref;
|
||||
|
||||
glBindFramebuffer(GL_READ_FRAMEBUFFER, OGLRef.fboClearImageID);
|
||||
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, OGLRef.selectedRenderingFBO);
|
||||
glBlitFramebuffer(0, 0, GFX3D_FRAMEBUFFER_WIDTH, GFX3D_FRAMEBUFFER_HEIGHT, 0, 0, GFX3D_FRAMEBUFFER_WIDTH, GFX3D_FRAMEBUFFER_HEIGHT, GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT, GL_NEAREST);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, OGLRef.selectedRenderingFBO);
|
||||
|
||||
return OGLERROR_NOERR;
|
||||
}
|
||||
@@ -0,0 +1,86 @@
|
||||
/*
|
||||
Copyright (C) 2006 yopyop
|
||||
Copyright (C) 2006-2007 shash
|
||||
Copyright (C) 2008-2013 DeSmuME team
|
||||
|
||||
This file is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This file is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with the this software. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef OGLRENDER_3_2_H
|
||||
#define OGLRENDER_3_2_H
|
||||
|
||||
#if defined(_WIN32)
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
#include <GL/gl.h>
|
||||
#include <GL/glcorearb.h>
|
||||
|
||||
#define OGLEXT(procPtr, func) procPtr func = NULL;
|
||||
#define INITOGLEXT(procPtr, func) func = (procPtr)wglGetProcAddress(#func);
|
||||
#define EXTERNOGLEXT(procPtr, func) extern procPtr func;
|
||||
#elif defined(__APPLE__)
|
||||
#include <OpenGL/gl3.h>
|
||||
#include <OpenGL/gl3ext.h>
|
||||
|
||||
// Ignore dynamic linking on Apple OS
|
||||
#define OGLEXT(procPtr, func)
|
||||
#define INITOGLEXT(procPtr, func)
|
||||
#define EXTERNOGLEXT(procPtr, func)
|
||||
#else
|
||||
#include <GL/gl.h>
|
||||
#include <GL/glx.h>
|
||||
#include "utils/glcorearb.h"
|
||||
|
||||
#define OGLEXT(procPtr, func) procPtr func = NULL;
|
||||
#define INITOGLEXT(procPtr, func) func = (procPtr)glXGetProcAddress((const GLubyte *) #func);
|
||||
#define EXTERNOGLEXT(procPtr, func) extern procPtr func;
|
||||
#endif
|
||||
|
||||
// Check minimum OpenGL header version
|
||||
#if !defined(GL_VERSION_3_2)
|
||||
#error OpenGL requires v3.2 headers or later.
|
||||
#endif
|
||||
|
||||
#include "OGLRender.h"
|
||||
|
||||
void OGLLoadEntryPoints_3_2();
|
||||
void OGLCreateRenderer_3_2(OpenGLRenderer **rendererPtr);
|
||||
|
||||
class OpenGLRenderer_3_2 : public OpenGLRenderer_2_1
|
||||
{
|
||||
protected:
|
||||
virtual Render3DError InitExtensions();
|
||||
virtual Render3DError CreateFBOs();
|
||||
virtual void DestroyFBOs();
|
||||
virtual Render3DError CreateMultisampledFBO();
|
||||
virtual void DestroyMultisampledFBO();
|
||||
virtual Render3DError CreateVAOs();
|
||||
virtual void DestroyVAOs();
|
||||
|
||||
virtual Render3DError LoadShaderPrograms(std::string *outVertexShaderProgram, std::string *outFragmentShaderProgram);
|
||||
virtual Render3DError SetupShaderIO();
|
||||
|
||||
virtual void GetExtensionSet(std::set<std::string> *oglExtensionSet);
|
||||
virtual Render3DError EnableVertexAttributes(const VERTLIST *vertList, const GLushort *indexBuffer, const size_t vertIndexCount);
|
||||
virtual Render3DError DisableVertexAttributes();
|
||||
virtual Render3DError SelectRenderingFramebuffer();
|
||||
virtual Render3DError DownsampleFBO();
|
||||
|
||||
virtual Render3DError ClearUsingImage() const;
|
||||
|
||||
public:
|
||||
~OpenGLRenderer_3_2();
|
||||
};
|
||||
|
||||
#endif
|
||||
Executable
+12
@@ -0,0 +1,12 @@
|
||||
#ifndef __GNUC__
|
||||
#pragma pack(push, 1)
|
||||
#pragma warning(disable : 4103)
|
||||
#endif
|
||||
|
||||
#ifndef __PACKED
|
||||
#ifdef __GNUC__
|
||||
#define __PACKED __attribute__((__packed__))
|
||||
#else
|
||||
#define __PACKED
|
||||
#endif
|
||||
#endif
|
||||
Executable
+3
@@ -0,0 +1,3 @@
|
||||
#ifndef __GNUC__
|
||||
#pragma pack(pop)
|
||||
#endif
|
||||
Executable
+235
@@ -0,0 +1,235 @@
|
||||
/*
|
||||
Copyright 2007 Guillaume Duhamel
|
||||
Copyright 2007-2012 DeSmuME team
|
||||
|
||||
This file is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This file is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with the this software. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "ROMReader.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <stdio.h>
|
||||
#ifdef HAVE_LIBZZIP
|
||||
#include <zzip/zzip.h>
|
||||
#endif
|
||||
|
||||
#ifdef WIN32
|
||||
#define stat(...) _stat(__VA_ARGS__)
|
||||
#define S_IFMT _S_IFMT
|
||||
#define S_IFREG _S_IFREG
|
||||
#endif
|
||||
|
||||
ROMReader_struct * ROMReaderInit(char ** filename)
|
||||
{
|
||||
#ifdef HAVE_LIBZ
|
||||
if(!strcasecmp(".gz", *filename + (strlen(*filename) - 3)))
|
||||
{
|
||||
(*filename)[strlen(*filename) - 3] = '\0';
|
||||
return &GZIPROMReader;
|
||||
}
|
||||
#endif
|
||||
#ifdef HAVE_LIBZZIP
|
||||
if (!strcasecmp(".zip", *filename + (strlen(*filename) - 4)))
|
||||
{
|
||||
(*filename)[strlen(*filename) - 4] = '\0';
|
||||
return &ZIPROMReader;
|
||||
}
|
||||
#endif
|
||||
return &STDROMReader;
|
||||
}
|
||||
|
||||
void * STDROMReaderInit(const char * filename);
|
||||
void STDROMReaderDeInit(void *);
|
||||
u32 STDROMReaderSize(void *);
|
||||
int STDROMReaderSeek(void *, int, int);
|
||||
int STDROMReaderRead(void *, void *, u32);
|
||||
|
||||
ROMReader_struct STDROMReader =
|
||||
{
|
||||
ROMREADER_STD,
|
||||
"Standard ROM Reader",
|
||||
STDROMReaderInit,
|
||||
STDROMReaderDeInit,
|
||||
STDROMReaderSize,
|
||||
STDROMReaderSeek,
|
||||
STDROMReaderRead
|
||||
};
|
||||
|
||||
void * STDROMReaderInit(const char * filename)
|
||||
{
|
||||
#ifdef WIN32
|
||||
struct _stat sb;
|
||||
#else
|
||||
struct stat sb;
|
||||
#endif
|
||||
if (stat(filename, &sb) == -1)
|
||||
return 0;
|
||||
|
||||
if ((sb.st_mode & S_IFMT) != S_IFREG)
|
||||
return 0;
|
||||
|
||||
return (void *) fopen(filename, "rb");
|
||||
}
|
||||
|
||||
void STDROMReaderDeInit(void * file)
|
||||
{
|
||||
if (!file) return ;
|
||||
fclose((FILE*)file);
|
||||
}
|
||||
|
||||
u32 STDROMReaderSize(void * file)
|
||||
{
|
||||
u32 size;
|
||||
|
||||
if (!file) return 0 ;
|
||||
|
||||
fseek((FILE*)file, 0, SEEK_END);
|
||||
size = ftell((FILE*)file);
|
||||
fseek((FILE*)file, 0, SEEK_SET);
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
int STDROMReaderSeek(void * file, int offset, int whence)
|
||||
{
|
||||
if (!file) return 0 ;
|
||||
return fseek((FILE*)file, offset, whence);
|
||||
}
|
||||
|
||||
int STDROMReaderRead(void * file, void * buffer, u32 size)
|
||||
{
|
||||
if (!file) return 0 ;
|
||||
return fread(buffer, 1, size, (FILE*)file);
|
||||
}
|
||||
|
||||
#ifdef HAVE_LIBZ
|
||||
void * GZIPROMReaderInit(const char * filename);
|
||||
void GZIPROMReaderDeInit(void *);
|
||||
u32 GZIPROMReaderSize(void *);
|
||||
int GZIPROMReaderSeek(void *, int, int);
|
||||
int GZIPROMReaderRead(void *, void *, u32);
|
||||
|
||||
ROMReader_struct GZIPROMReader =
|
||||
{
|
||||
ROMREADER_GZIP,
|
||||
"Gzip ROM Reader",
|
||||
GZIPROMReaderInit,
|
||||
GZIPROMReaderDeInit,
|
||||
GZIPROMReaderSize,
|
||||
GZIPROMReaderSeek,
|
||||
GZIPROMReaderRead
|
||||
};
|
||||
|
||||
void * GZIPROMReaderInit(const char * filename)
|
||||
{
|
||||
return (void*)gzopen(filename, "rb");
|
||||
}
|
||||
|
||||
void GZIPROMReaderDeInit(void * file)
|
||||
{
|
||||
gzclose((gzFile)file);
|
||||
}
|
||||
|
||||
u32 GZIPROMReaderSize(void * file)
|
||||
{
|
||||
char useless[1024];
|
||||
u32 size = 0;
|
||||
|
||||
/* FIXME this function should first save the current
|
||||
* position and restore it after size calculation */
|
||||
gzrewind((gzFile)file);
|
||||
while (gzeof ((gzFile)file) == 0)
|
||||
size += gzread((gzFile)file, useless, 1024);
|
||||
gzrewind((gzFile)file);
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
int GZIPROMReaderSeek(void * file, int offset, int whence)
|
||||
{
|
||||
return gzseek((gzFile)file, offset, whence);
|
||||
}
|
||||
|
||||
int GZIPROMReaderRead(void * file, void * buffer, u32 size)
|
||||
{
|
||||
return gzread((gzFile)file, buffer, size);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_LIBZZIP
|
||||
void * ZIPROMReaderInit(const char * filename);
|
||||
void ZIPROMReaderDeInit(void *);
|
||||
u32 ZIPROMReaderSize(void *);
|
||||
int ZIPROMReaderSeek(void *, int, int);
|
||||
int ZIPROMReaderRead(void *, void *, u32);
|
||||
|
||||
ROMReader_struct ZIPROMReader =
|
||||
{
|
||||
ROMREADER_ZIP,
|
||||
"Zip ROM Reader",
|
||||
ZIPROMReaderInit,
|
||||
ZIPROMReaderDeInit,
|
||||
ZIPROMReaderSize,
|
||||
ZIPROMReaderSeek,
|
||||
ZIPROMReaderRead
|
||||
};
|
||||
|
||||
void * ZIPROMReaderInit(const char * filename)
|
||||
{
|
||||
ZZIP_DIR * dir = zzip_opendir(filename);
|
||||
ZZIP_DIRENT * dirent = zzip_readdir(dir);
|
||||
if (dir != NULL)
|
||||
{
|
||||
char tmp1[1024];
|
||||
char tmp2[1024];
|
||||
memset(tmp1,0,sizeof(tmp1));
|
||||
memset(tmp2,0,sizeof(tmp2));
|
||||
strncpy(tmp1, filename, strlen(filename) - 4);
|
||||
sprintf(tmp2, "%s/%s", tmp1, dirent->d_name);
|
||||
return zzip_fopen(tmp2, "rb");
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void ZIPROMReaderDeInit(void * file)
|
||||
{
|
||||
zzip_close((ZZIP_FILE*)file);
|
||||
}
|
||||
|
||||
u32 ZIPROMReaderSize(void * file)
|
||||
{
|
||||
u32 size;
|
||||
|
||||
zzip_seek((ZZIP_FILE*)file, 0, SEEK_END);
|
||||
size = zzip_tell((ZZIP_FILE*)file);
|
||||
zzip_seek((ZZIP_FILE*)file, 0, SEEK_SET);
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
int ZIPROMReaderSeek(void * file, int offset, int whence)
|
||||
{
|
||||
return zzip_seek((ZZIP_FILE*)file, offset, whence);
|
||||
}
|
||||
|
||||
int ZIPROMReaderRead(void * file, void * buffer, u32 size)
|
||||
{
|
||||
#ifdef ZZIP_OLD_READ
|
||||
return zzip_read((ZZIP_FILE*)file, (char *) buffer, size);
|
||||
#else
|
||||
return zzip_read((ZZIP_FILE*)file, buffer, size);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
Executable
+50
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
Copyright (C) 2007 Guillaume Duhamel
|
||||
Copyright (C) 2007 DeSmuME team
|
||||
|
||||
This file is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This file is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with the this software. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_LIBZ
|
||||
#include <zlib.h>
|
||||
#endif
|
||||
#include <string.h>
|
||||
|
||||
#include "types.h"
|
||||
|
||||
#define ROMREADER_DEFAULT -1
|
||||
#define ROMREADER_STD 0
|
||||
#define ROMREADER_GZIP 1
|
||||
#define ROMREADER_ZIP 2
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int id;
|
||||
const char * Name;
|
||||
void * (*Init)(const char * filename);
|
||||
void (*DeInit)(void * file);
|
||||
u32 (*Size)(void * file);
|
||||
int (*Seek)(void * file, int offset, int whence);
|
||||
int (*Read)(void * file, void * buffer, u32 size);
|
||||
} ROMReader_struct;
|
||||
|
||||
extern ROMReader_struct STDROMReader;
|
||||
#ifdef HAVE_LIBZ
|
||||
extern ROMReader_struct GZIPROMReader;
|
||||
#endif
|
||||
#ifdef HAVE_LIBZZIP
|
||||
extern ROMReader_struct ZIPROMReader;
|
||||
#endif
|
||||
|
||||
ROMReader_struct * ROMReaderInit(char ** filename);
|
||||
Executable
+2073
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,303 @@
|
||||
/*
|
||||
Copyright 2006 Theo Berkau
|
||||
Copyright (C) 2006-2015 DeSmuME team
|
||||
|
||||
This file is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This file is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with the this software. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef SPU_H
|
||||
#define SPU_H
|
||||
|
||||
#include <iosfwd>
|
||||
#include <string>
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "types.h"
|
||||
#include "matrix.h"
|
||||
#include "metaspu/metaspu.h"
|
||||
|
||||
class EMUFILE;
|
||||
|
||||
#define SNDCORE_DEFAULT -1
|
||||
#define SNDCORE_DUMMY 0
|
||||
|
||||
#define CHANSTAT_STOPPED 0
|
||||
#define CHANSTAT_PLAY 1
|
||||
|
||||
|
||||
//who made these static? theyre used in multiple places.
|
||||
FORCEINLINE u32 sputrunc(float f) { return u32floor(f); }
|
||||
FORCEINLINE u32 sputrunc(double d) { return u32floor(d); }
|
||||
FORCEINLINE s32 spumuldiv7(s32 val, u8 multiplier) {
|
||||
assert(multiplier <= 127);
|
||||
return (multiplier == 127) ? val : ((val * multiplier) >> 7);
|
||||
}
|
||||
|
||||
enum SPUInterpolationMode
|
||||
{
|
||||
SPUInterpolation_None = 0,
|
||||
SPUInterpolation_Linear = 1,
|
||||
SPUInterpolation_Cosine = 2
|
||||
};
|
||||
|
||||
struct SoundInterface_struct
|
||||
{
|
||||
int id;
|
||||
const char *Name;
|
||||
int (*Init)(int buffersize);
|
||||
void (*DeInit)();
|
||||
void (*UpdateAudio)(s16 *buffer, u32 num_samples);
|
||||
u32 (*GetAudioSpace)();
|
||||
void (*MuteAudio)();
|
||||
void (*UnMuteAudio)();
|
||||
void (*SetVolume)(int volume);
|
||||
void (*ClearBuffer)();
|
||||
void (*FetchSamples)(s16 *sampleBuffer, size_t sampleCount, ESynchMode synchMode, ISynchronizingAudioBuffer *theSynchronizer);
|
||||
size_t (*PostProcessSamples)(s16 *postProcessBuffer, size_t requestedSampleCount, ESynchMode synchMode, ISynchronizingAudioBuffer *theSynchronizer);
|
||||
};
|
||||
|
||||
extern SoundInterface_struct SNDDummy;
|
||||
extern SoundInterface_struct SNDFile;
|
||||
extern int SPU_currentCoreNum;
|
||||
|
||||
struct channel_struct
|
||||
{
|
||||
channel_struct() : num(0),
|
||||
vol(0),
|
||||
volumeDiv(0),
|
||||
hold(0),
|
||||
pan(0),
|
||||
waveduty(0),
|
||||
repeat(0),
|
||||
format(0),
|
||||
keyon(0),
|
||||
status(0),
|
||||
addr(0),
|
||||
timer(0),
|
||||
loopstart(0),
|
||||
length(0),
|
||||
totlength(0),
|
||||
double_totlength_shifted(0.0),
|
||||
sampcnt(0.0),
|
||||
sampinc(0.0),
|
||||
lastsampcnt(0),
|
||||
pcm16b(0),
|
||||
pcm16b_last(0),
|
||||
loop_pcm16b(0),
|
||||
index(0),
|
||||
loop_index(0),
|
||||
x(0),
|
||||
psgnoise_last(0)
|
||||
{}
|
||||
u32 num;
|
||||
u8 vol;
|
||||
u8 volumeDiv;
|
||||
u8 hold;
|
||||
u8 pan;
|
||||
u8 waveduty;
|
||||
u8 repeat;
|
||||
u8 format;
|
||||
u8 keyon;
|
||||
u8 status;
|
||||
u32 addr;
|
||||
u16 timer;
|
||||
u16 loopstart;
|
||||
u32 length;
|
||||
u32 totlength;
|
||||
double double_totlength_shifted;
|
||||
double sampcnt;
|
||||
double sampinc;
|
||||
// ADPCM specific
|
||||
u32 lastsampcnt;
|
||||
s16 pcm16b, pcm16b_last;
|
||||
s16 loop_pcm16b;
|
||||
int index;
|
||||
int loop_index;
|
||||
u16 x;
|
||||
s16 psgnoise_last;
|
||||
};
|
||||
|
||||
class SPUFifo
|
||||
{
|
||||
public:
|
||||
SPUFifo();
|
||||
void enqueue(s16 val);
|
||||
s16 dequeue();
|
||||
s16 buffer[16];
|
||||
s32 head,tail,size;
|
||||
void save(EMUFILE* fp);
|
||||
bool load(EMUFILE* fp);
|
||||
void reset();
|
||||
};
|
||||
|
||||
class SPU_struct
|
||||
{
|
||||
public:
|
||||
SPU_struct(int buffersize);
|
||||
u32 bufpos;
|
||||
u32 buflength;
|
||||
s32 *sndbuf;
|
||||
s32 lastdata; //the last sample that a channel generated
|
||||
s16 *outbuf;
|
||||
u32 bufsize;
|
||||
channel_struct channels[16];
|
||||
|
||||
//registers
|
||||
struct REGS {
|
||||
REGS()
|
||||
: mastervol(0)
|
||||
, ctl_left(0)
|
||||
, ctl_right(0)
|
||||
, ctl_ch1bypass(0)
|
||||
, ctl_ch3bypass(0)
|
||||
, masteren(0)
|
||||
, soundbias(0)
|
||||
{}
|
||||
|
||||
u8 mastervol;
|
||||
u8 ctl_left, ctl_right;
|
||||
u8 ctl_ch1bypass, ctl_ch3bypass;
|
||||
u8 masteren;
|
||||
u16 soundbias;
|
||||
|
||||
enum LeftOutputMode
|
||||
{
|
||||
LOM_LEFT_MIXER=0, LOM_CH1=1, LOM_CH3=2, LOM_CH1_PLUS_CH3=3
|
||||
};
|
||||
|
||||
enum RightOutputMode
|
||||
{
|
||||
ROM_RIGHT_MIXER=0, ROM_CH1=1, ROM_CH3=2, ROM_CH1_PLUS_CH3=3
|
||||
};
|
||||
|
||||
struct CAP {
|
||||
CAP()
|
||||
: add(0), source(0), oneshot(0), bits8(0), active(0), dad(0), len(0)
|
||||
{}
|
||||
u8 add, source, oneshot, bits8, active;
|
||||
u32 dad;
|
||||
u16 len;
|
||||
struct Runtime {
|
||||
Runtime()
|
||||
: running(0), curdad(0), maxdad(0)
|
||||
{}
|
||||
u8 running;
|
||||
u32 curdad;
|
||||
u32 maxdad;
|
||||
double sampcnt;
|
||||
SPUFifo fifo;
|
||||
} runtime;
|
||||
} cap[2];
|
||||
} regs;
|
||||
|
||||
void reset();
|
||||
~SPU_struct();
|
||||
void KeyOff(int channel);
|
||||
void KeyOn(int channel);
|
||||
void KeyProbe(int channel);
|
||||
void ProbeCapture(int which);
|
||||
void WriteByte(u32 addr, u8 val);
|
||||
void WriteWord(u32 addr, u16 val);
|
||||
void WriteLong(u32 addr, u32 val);
|
||||
u8 ReadByte(u32 addr);
|
||||
u16 ReadWord(u32 addr);
|
||||
u32 ReadLong(u32 addr);
|
||||
bool isSPU(u32 addr) { return ((addr >= 0x04000400) && (addr < 0x04000520)); }
|
||||
|
||||
//kills all channels but leaves SPU otherwise running normally
|
||||
void ShutUp();
|
||||
};
|
||||
|
||||
extern SPU_struct *SPU_core, *SPU_user;
|
||||
extern int spu_core_samples;
|
||||
|
||||
int SPU_ChangeSoundCore(int coreid, int buffersize);
|
||||
SoundInterface_struct *SPU_SoundCore();
|
||||
|
||||
void SPU_ReInit(bool fakeBoot = false);
|
||||
int SPU_Init(int coreid, int buffersize);
|
||||
void SPU_Pause(int pause);
|
||||
void SPU_SetVolume(int volume);
|
||||
void SPU_SetSynchMode(int mode, int method);
|
||||
void SPU_ClearOutputBuffer(void);
|
||||
void SPU_Reset(void);
|
||||
void SPU_DeInit(void);
|
||||
void SPU_KeyOn(int channel);
|
||||
static FORCEINLINE void SPU_WriteByte(u32 addr, u8 val)
|
||||
{
|
||||
addr &= 0xFFF;
|
||||
|
||||
SPU_core->WriteByte(addr,val);
|
||||
if(SPU_user)
|
||||
SPU_user->WriteByte(addr,val);
|
||||
}
|
||||
static FORCEINLINE void SPU_WriteWord(u32 addr, u16 val)
|
||||
{
|
||||
addr &= 0xFFF;
|
||||
|
||||
SPU_core->WriteWord(addr,val);
|
||||
if(SPU_user)
|
||||
SPU_user->WriteWord(addr,val);
|
||||
}
|
||||
static FORCEINLINE void SPU_WriteLong(u32 addr, u32 val)
|
||||
{
|
||||
addr &= 0xFFF;
|
||||
|
||||
SPU_core->WriteLong(addr,val);
|
||||
if(SPU_user)
|
||||
SPU_user->WriteLong(addr,val);
|
||||
}
|
||||
static FORCEINLINE u8 SPU_ReadByte(u32 addr) { return SPU_core->ReadByte(addr & 0x0FFF); }
|
||||
static FORCEINLINE u16 SPU_ReadWord(u32 addr) { return SPU_core->ReadWord(addr & 0x0FFF); }
|
||||
static FORCEINLINE u32 SPU_ReadLong(u32 addr) { return SPU_core->ReadLong(addr & 0x0FFF); }
|
||||
void SPU_Emulate_core(void);
|
||||
void SPU_Emulate_user(bool mix = true);
|
||||
void SPU_DefaultFetchSamples(s16 *sampleBuffer, size_t sampleCount, ESynchMode synchMode, ISynchronizingAudioBuffer *theSynchronizer);
|
||||
size_t SPU_DefaultPostProcessSamples(s16 *postProcessBuffer, size_t requestedSampleCount, ESynchMode synchMode, ISynchronizingAudioBuffer *theSynchronizer);
|
||||
|
||||
void spu_savestate(EMUFILE* os);
|
||||
bool spu_loadstate(EMUFILE* is, int size);
|
||||
|
||||
enum WAVMode
|
||||
{
|
||||
WAVMODE_ANY = -1,
|
||||
WAVMODE_CORE = 0,
|
||||
WAVMODE_USER = 1
|
||||
};
|
||||
|
||||
class WavWriter
|
||||
{
|
||||
public:
|
||||
WavWriter();
|
||||
bool open(const std::string & fname);
|
||||
void close();
|
||||
void update(void* soundData, int numSamples);
|
||||
bool isRecording() const;
|
||||
WAVMode mode;
|
||||
private:
|
||||
FILE *spufp;
|
||||
};
|
||||
|
||||
void WAV_End();
|
||||
bool WAV_Begin(const char* fname, WAVMode mode=WAVMODE_CORE);
|
||||
bool WAV_IsRecording(WAVMode mode=WAVMODE_ANY);
|
||||
void WAV_WavSoundUpdate(void* soundData, int numSamples, WAVMode mode=WAVMODE_CORE);
|
||||
|
||||
// we should make this configurable eventually
|
||||
// but at least defining it somewhere is probably a step in the right direction
|
||||
#define DESMUME_SAMPLE_RATE 44100
|
||||
//#define DESMUME_SAMPLE_RATE 48000
|
||||
|
||||
#endif
|
||||
Executable
+35
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
Copyright (C) 2010-2015 DeSmuME team
|
||||
|
||||
This file is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This file is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with the this software. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "../slot1.h"
|
||||
|
||||
class Slot1_None : public ISlot1Interface
|
||||
{
|
||||
public:
|
||||
virtual Slot1Info const* info()
|
||||
{
|
||||
static Slot1InfoSimple info("None","Slot1 no-card emulation", 0xFF);
|
||||
return &info;
|
||||
}
|
||||
|
||||
//pretty much every access to the card should just be ignored and reading HIGH-Z off the GC bus.
|
||||
//so, nothing really to do here
|
||||
//(notably, it results in a 0xFFFFFFFF card ID)
|
||||
|
||||
};
|
||||
|
||||
ISlot1Interface* construct_Slot1_None() { return new Slot1_None(); }
|
||||
Executable
+242
@@ -0,0 +1,242 @@
|
||||
/*
|
||||
Copyright (C) 2010-2015 DeSmuME team
|
||||
|
||||
This file is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This file is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with the this software. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "slot1comp_protocol.h"
|
||||
|
||||
#include <time.h>
|
||||
|
||||
#include "../slot1.h"
|
||||
#include "../NDSSystem.h"
|
||||
#include "../emufile.h"
|
||||
|
||||
class Slot1_R4 : public ISlot1Interface, public ISlot1Comp_Protocol_Client
|
||||
{
|
||||
private:
|
||||
EMUFILE *img;
|
||||
Slot1Comp_Protocol protocol;
|
||||
u32 write_count;
|
||||
u32 write_enabled;
|
||||
|
||||
public:
|
||||
Slot1_R4()
|
||||
: img(NULL)
|
||||
, write_count(0)
|
||||
, write_enabled(0)
|
||||
{
|
||||
}
|
||||
|
||||
virtual Slot1Info const* info()
|
||||
{
|
||||
static Slot1InfoSimple info("R4", "Slot1 R4 emulation", 0x03);
|
||||
return &info;
|
||||
}
|
||||
|
||||
//called once when the emulator starts up, or when the device springs into existence
|
||||
virtual bool init()
|
||||
{
|
||||
//strange to do this here but we need to make sure its done at some point
|
||||
srand(time(NULL));
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual void connect()
|
||||
{
|
||||
img = slot1_GetFatImage();
|
||||
|
||||
if(!img)
|
||||
INFO("slot1 fat not successfully mounted\n");
|
||||
|
||||
protocol.reset(this);
|
||||
protocol.chipId = 0xFC2;
|
||||
protocol.gameCode = T1ReadLong((u8*)gameInfo.header.gameCode,0);
|
||||
}
|
||||
|
||||
//called when the emulator disconnects the device
|
||||
virtual void disconnect()
|
||||
{
|
||||
img = NULL;
|
||||
}
|
||||
|
||||
//called when the emulator shuts down, or when the device disappears from existence
|
||||
virtual void shutdown()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
virtual void write_command(u8 PROCNUM, GC_Command command)
|
||||
{
|
||||
protocol.write_command(command);
|
||||
}
|
||||
virtual void write_GCDATAIN(u8 PROCNUM, u32 val)
|
||||
{
|
||||
protocol.write_GCDATAIN(PROCNUM, val);
|
||||
}
|
||||
virtual u32 read_GCDATAIN(u8 PROCNUM)
|
||||
{
|
||||
return protocol.read_GCDATAIN(PROCNUM);
|
||||
}
|
||||
|
||||
virtual void slot1client_startOperation(eSlot1Operation operation)
|
||||
{
|
||||
if(operation != eSlot1Operation_Unknown)
|
||||
return;
|
||||
|
||||
u32 address;
|
||||
int cmd = protocol.command.bytes[0];
|
||||
switch(cmd)
|
||||
{
|
||||
case 0xB0:
|
||||
break;
|
||||
case 0xB9:
|
||||
case 0xBA:
|
||||
address = (protocol.command.bytes[1] << 24) | (protocol.command.bytes[2] << 16) | (protocol.command.bytes[3] << 8) | protocol.command.bytes[4];
|
||||
img->fseek(address,SEEK_SET);
|
||||
break;
|
||||
case 0xBB:
|
||||
write_enabled = 1;
|
||||
write_count = 0x80;
|
||||
//passthrough on purpose?
|
||||
case 0xBC:
|
||||
address = (protocol.command.bytes[1] << 24) | (protocol.command.bytes[2] << 16) | (protocol.command.bytes[3] << 8) | protocol.command.bytes[4];
|
||||
img->fseek(address,SEEK_SET);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
virtual u32 slot1client_read_GCDATAIN(eSlot1Operation operation)
|
||||
{
|
||||
if(operation != eSlot1Operation_Unknown)
|
||||
return 0;
|
||||
|
||||
u32 val;
|
||||
int cmd = protocol.command.bytes[0];
|
||||
switch(cmd)
|
||||
{
|
||||
case 0xB0:
|
||||
val = (img) ? 0x1F4 : 0x1F2;
|
||||
break;
|
||||
case 0xB9:
|
||||
val = (rand() % 100) ? (img) ? 0x1F4 : 0x1F2 : 0;
|
||||
break;
|
||||
case 0xBB:
|
||||
case 0xBC:
|
||||
val = 0;
|
||||
break;
|
||||
case 0xBA:
|
||||
//INFO("Read from sd at sector %08X at adr %08X ",card.address/512,ftell(img));
|
||||
img->fread(&val, 4);
|
||||
//INFO("val %08X\n",val);
|
||||
break;
|
||||
default:
|
||||
val = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
void slot1client_write_GCDATAIN(eSlot1Operation operation, u32 val)
|
||||
{
|
||||
if(operation != eSlot1Operation_Unknown)
|
||||
return;
|
||||
|
||||
int cmd = protocol.command.bytes[0];
|
||||
switch(cmd)
|
||||
{
|
||||
case 0xBB:
|
||||
{
|
||||
if(write_count && write_enabled)
|
||||
{
|
||||
img->fwrite(&val, 4);
|
||||
img->fflush();
|
||||
write_count--;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
virtual void post_fakeboot(int PROCNUM)
|
||||
{
|
||||
// The BIOS leaves the card in NORMAL mode
|
||||
protocol.mode = eCardMode_NORMAL;
|
||||
}
|
||||
|
||||
void write32_GCDATAIN(u32 val)
|
||||
{
|
||||
//bool log = false;
|
||||
|
||||
//last_write_count = write_count;
|
||||
|
||||
//can someone tell me ... what the hell is this doing, anyway?
|
||||
//seems odd to use card.command[4] for this... isnt it part of the address?
|
||||
if(protocol.command.bytes[4])
|
||||
{
|
||||
// transfer is done
|
||||
//are you SURE this is logical? there doesnt seem to be any way for the card to signal that
|
||||
T1WriteLong(MMU.MMU_MEM[0][0x40], 0x1A4,val & 0x7F7FFFFF);
|
||||
|
||||
MMU_GC_endTransfer(0);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
int cmd = protocol.command.bytes[0];
|
||||
switch(cmd)
|
||||
{
|
||||
case 0xBB:
|
||||
{
|
||||
if(write_count && write_enabled)
|
||||
{
|
||||
img->fwrite(&val, 4);
|
||||
img->fflush();
|
||||
write_count--;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if(write_count==0)
|
||||
{
|
||||
write_enabled = 0;
|
||||
|
||||
//transfer is done
|
||||
|
||||
//are you SURE this is logical? there doesnt seem to be any way for the card to signal that
|
||||
T1WriteLong(MMU.MMU_MEM[0][0x40], 0x1A4,val & 0x7F7FFFFF);
|
||||
|
||||
//but isnt this a different IRQ? IREQ_MC perhaps
|
||||
MMU_GC_endTransfer(0);
|
||||
}
|
||||
|
||||
/*if(log)
|
||||
{
|
||||
INFO("WRITE CARD command: %02X%02X%02X%02X%02X%02X%02X%02X\t",
|
||||
card.command[0], card.command[1], card.command[2], card.command[3],
|
||||
card.command[4], card.command[5], card.command[6], card.command[7]);
|
||||
INFO("FROM: %08X\t", NDS_ARM9.instruct_adr);
|
||||
INFO("VAL: %08X\n", val);
|
||||
}*/
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
ISlot1Interface* construct_Slot1_R4() { return new Slot1_R4(); }
|
||||
Executable
+102
@@ -0,0 +1,102 @@
|
||||
/*
|
||||
Copyright (C) 2013-2105 DeSmuME team
|
||||
|
||||
This file is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This file is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with the this software. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "../slot1.h"
|
||||
#include "../NDSSystem.h"
|
||||
|
||||
class Slot1_Retail_Auto : public ISlot1Interface
|
||||
{
|
||||
private:
|
||||
ISlot1Interface *mSelectedImplementation;
|
||||
|
||||
public:
|
||||
Slot1_Retail_Auto()
|
||||
: mSelectedImplementation(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
virtual Slot1Info const* info()
|
||||
{
|
||||
static Slot1InfoSimple info("Retail (Auto)","Slot1 Retail (auto-selection) card emulation", 0xFE);
|
||||
return &info;
|
||||
}
|
||||
|
||||
virtual void connect()
|
||||
{
|
||||
|
||||
NDS_SLOT1_TYPE selection = NDS_SLOT1_RETAIL_MCROM;
|
||||
|
||||
//check game ID in core emulator and select right implementation
|
||||
if ((memcmp(gameInfo.header.gameCode, "UOR", 3) == 0) || // WarioWare - D.I.Y. (U)(E)(EUR) / Made in Ore (J)
|
||||
(memcmp(gameInfo.header.gameCode, "UXBP", 4) == 0) // Jam with the Band (EUR)
|
||||
)
|
||||
selection = NDS_SLOT1_RETAIL_NAND;
|
||||
|
||||
slot1_selected_type = selection;
|
||||
mSelectedImplementation = slot1_List[selection];
|
||||
mSelectedImplementation->connect();
|
||||
printf("Slot1 auto-selected device type: %s\n",mSelectedImplementation->info()->name());
|
||||
}
|
||||
|
||||
virtual void disconnect()
|
||||
{
|
||||
if(mSelectedImplementation) mSelectedImplementation->disconnect();
|
||||
mSelectedImplementation = NULL;
|
||||
}
|
||||
|
||||
virtual void write_command(u8 PROCNUM, GC_Command command)
|
||||
{
|
||||
mSelectedImplementation->write_command(PROCNUM, command);
|
||||
}
|
||||
|
||||
virtual void write_GCDATAIN(u8 PROCNUM, u32 val)
|
||||
{
|
||||
mSelectedImplementation->write_GCDATAIN(PROCNUM, val);
|
||||
}
|
||||
|
||||
virtual u32 read_GCDATAIN(u8 PROCNUM)
|
||||
{
|
||||
return mSelectedImplementation->read_GCDATAIN(PROCNUM);
|
||||
}
|
||||
|
||||
virtual u8 auxspi_transaction(int PROCNUM, u8 value)
|
||||
{
|
||||
return mSelectedImplementation->auxspi_transaction(PROCNUM, value);
|
||||
}
|
||||
|
||||
virtual void auxspi_reset(int PROCNUM)
|
||||
{
|
||||
mSelectedImplementation->auxspi_reset(PROCNUM);
|
||||
}
|
||||
|
||||
virtual void post_fakeboot(int PROCNUM)
|
||||
{
|
||||
mSelectedImplementation->post_fakeboot(PROCNUM);
|
||||
}
|
||||
|
||||
virtual void savestate(EMUFILE* os)
|
||||
{
|
||||
mSelectedImplementation->savestate(os);
|
||||
}
|
||||
|
||||
virtual void loadstate(EMUFILE* is)
|
||||
{
|
||||
mSelectedImplementation->loadstate(is);
|
||||
}
|
||||
};
|
||||
|
||||
ISlot1Interface* construct_Slot1_Retail_Auto() { return new Slot1_Retail_Auto(); }
|
||||
Executable
+107
@@ -0,0 +1,107 @@
|
||||
/*
|
||||
Copyright (C) 2010-2015 DeSmuME team
|
||||
|
||||
This file is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This file is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with the this software. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "slot1comp_mc.h"
|
||||
#include "slot1comp_rom.h"
|
||||
#include "slot1comp_protocol.h"
|
||||
|
||||
#include "../slot1.h"
|
||||
#include "../NDSSystem.h"
|
||||
|
||||
//quick architecture overview:
|
||||
//MCROM receives GC bus commands from MMU.cpp
|
||||
//those are passed on to the protocol component for parsing
|
||||
//protocol calls back into MCROM via ISlot1Comp_Protocol_Client interface for things the protocol doesnt know about (the contents of the rom, chiefly)
|
||||
//MCROM utilizes the rom component for address logic and delivering data
|
||||
|
||||
class Slot1_Retail_MCROM : public ISlot1Interface, public ISlot1Comp_Protocol_Client
|
||||
{
|
||||
private:
|
||||
Slot1Comp_Protocol protocol;
|
||||
Slot1Comp_Rom rom;
|
||||
|
||||
public:
|
||||
|
||||
virtual Slot1Info const* info()
|
||||
{
|
||||
static Slot1InfoSimple info("Retail MC+ROM", "Slot1 Retail MC+ROM (standard) card emulation", 0x01);
|
||||
return &info;
|
||||
}
|
||||
|
||||
virtual void connect()
|
||||
{
|
||||
protocol.reset(this);
|
||||
protocol.chipId = gameInfo.chipID;
|
||||
protocol.gameCode = T1ReadLong((u8*)gameInfo.header.gameCode,0);
|
||||
g_Slot1Comp_MC.connect();
|
||||
}
|
||||
|
||||
virtual u8 auxspi_transaction(int PROCNUM, u8 value)
|
||||
{
|
||||
return g_Slot1Comp_MC.auxspi_transaction(PROCNUM,value);
|
||||
}
|
||||
|
||||
virtual void auxspi_reset(int PROCNUM)
|
||||
{
|
||||
g_Slot1Comp_MC.auxspi_reset(PROCNUM);
|
||||
}
|
||||
|
||||
virtual void write_command(u8 PROCNUM, GC_Command command)
|
||||
{
|
||||
protocol.write_command(command);
|
||||
}
|
||||
virtual void write_GCDATAIN(u8 PROCNUM, u32 val)
|
||||
{
|
||||
protocol.write_GCDATAIN(PROCNUM, val);
|
||||
}
|
||||
virtual u32 read_GCDATAIN(u8 PROCNUM)
|
||||
{
|
||||
return protocol.read_GCDATAIN(PROCNUM);
|
||||
}
|
||||
|
||||
virtual void slot1client_startOperation(eSlot1Operation operation)
|
||||
{
|
||||
rom.start(operation,protocol.address);
|
||||
}
|
||||
|
||||
virtual void post_fakeboot(int PROCNUM)
|
||||
{
|
||||
// The BIOS leaves the card in NORMAL mode
|
||||
protocol.mode = eCardMode_NORMAL;
|
||||
}
|
||||
|
||||
virtual void savestate(EMUFILE* os)
|
||||
{
|
||||
protocol.savestate(os);
|
||||
rom.savestate(os);
|
||||
}
|
||||
|
||||
virtual void loadstate(EMUFILE* is)
|
||||
{
|
||||
protocol.loadstate(is);
|
||||
rom.loadstate(is);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
u32 slot1client_read_GCDATAIN(eSlot1Operation operation)
|
||||
{
|
||||
return rom.read();
|
||||
}
|
||||
};
|
||||
|
||||
ISlot1Interface* construct_Slot1_Retail_MCROM() { return new Slot1_Retail_MCROM(); }
|
||||
Executable
+220
@@ -0,0 +1,220 @@
|
||||
/*
|
||||
Copyright (C) 2013-2015 DeSmuME team
|
||||
|
||||
This file is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This file is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with the this software. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "slot1comp_mc.h"
|
||||
#include "slot1comp_rom.h"
|
||||
#include "slot1comp_protocol.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string>
|
||||
|
||||
#include "../slot1.h"
|
||||
#include "../path.h"
|
||||
#include "../NDSSystem.h"
|
||||
#include "../utils/fsnitro.h"
|
||||
|
||||
//quick architecture overview:
|
||||
//MCROM receives GC bus commands from MMU.cpp
|
||||
//those are passed on to the protocol component for parsing
|
||||
//protocol calls back into MCROM via ISlot1Comp_Protocol_Client interface for things the protocol doesnt know about (the contents of the rom, chiefly)
|
||||
//MCROM utilizes the rom component for address logic and delivering data
|
||||
|
||||
class Slot1_Retail_DEBUG : public ISlot1Interface, public ISlot1Comp_Protocol_Client
|
||||
{
|
||||
private:
|
||||
Slot1Comp_Protocol protocol;
|
||||
Slot1Comp_Rom rom;
|
||||
FILE *fpROM;
|
||||
FS_NITRO *fs;
|
||||
u16 curr_file_id;
|
||||
string pathData;
|
||||
|
||||
public:
|
||||
|
||||
virtual Slot1Info const* info()
|
||||
{
|
||||
static Slot1InfoSimple info("Retail DEBUG","Slot1 Retail (standard) card emulation + FS Nitro DEBUG", 0x04);
|
||||
return &info;
|
||||
}
|
||||
|
||||
virtual void connect()
|
||||
{
|
||||
protocol.reset(this);
|
||||
protocol.chipId = gameInfo.chipID;
|
||||
protocol.gameCode = T1ReadLong((u8*)gameInfo.header.gameCode,0);
|
||||
|
||||
curr_file_id = 0xFFFF;
|
||||
fpROM = NULL;
|
||||
fs = NULL;
|
||||
|
||||
if (!CommonSettings.loadToMemory)
|
||||
{
|
||||
printf("NitroFS: change load type to \"Load to RAM\"\n");
|
||||
return;
|
||||
}
|
||||
pathData = path.getpath(path.SLOT1D) + path.GetRomNameWithoutExtension();
|
||||
printf("Path to Slot1 data: %s\n", pathData.c_str());
|
||||
|
||||
fs = new FS_NITRO(gameInfo.romdata);
|
||||
fs->rebuildFAT(pathData);
|
||||
}
|
||||
|
||||
virtual u8 auxspi_transaction(int PROCNUM, u8 value)
|
||||
{
|
||||
return g_Slot1Comp_MC.auxspi_transaction(PROCNUM,value);
|
||||
}
|
||||
|
||||
virtual void auxspi_reset(int PROCNUM)
|
||||
{
|
||||
g_Slot1Comp_MC.auxspi_reset(PROCNUM);
|
||||
}
|
||||
|
||||
virtual void write_command(u8 PROCNUM, GC_Command command)
|
||||
{
|
||||
protocol.write_command(command);
|
||||
}
|
||||
virtual void write_GCDATAIN(u8 PROCNUM, u32 val)
|
||||
{
|
||||
protocol.write_GCDATAIN(PROCNUM, val);
|
||||
}
|
||||
virtual u32 read_GCDATAIN(u8 PROCNUM)
|
||||
{
|
||||
return protocol.read_GCDATAIN(PROCNUM);
|
||||
}
|
||||
|
||||
virtual void post_fakeboot(int PROCNUM)
|
||||
{
|
||||
// The BIOS leaves the card in NORMAL mode
|
||||
protocol.mode = eCardMode_NORMAL;
|
||||
}
|
||||
|
||||
virtual void savestate(EMUFILE* os)
|
||||
{
|
||||
protocol.savestate(os);
|
||||
rom.savestate(os);
|
||||
}
|
||||
|
||||
virtual void loadstate(EMUFILE* is)
|
||||
{
|
||||
protocol.loadstate(is);
|
||||
rom.loadstate(is);
|
||||
}
|
||||
|
||||
virtual void slot1client_startOperation(eSlot1Operation operation)
|
||||
{
|
||||
if (protocol.operation == eSlot1Operation_B7_Read)
|
||||
{
|
||||
u16 file_id = 0xFFFF; u32 offset = 0;
|
||||
bool bFromFile = false;
|
||||
|
||||
if (fs && fs->isFAT(protocol.address))
|
||||
{
|
||||
fs->rebuildFAT(protocol.address, protocol.length, pathData);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (fs && fs->getFileIdByAddr(protocol.address, file_id, offset))
|
||||
{
|
||||
if (file_id != curr_file_id)
|
||||
{
|
||||
string tmp = fs->getFullPathByFileID(file_id);
|
||||
printf("%04X:[%08X, ofs %08X] %s\n", file_id, protocol.address, offset, tmp.c_str());
|
||||
|
||||
if (fpROM)
|
||||
{
|
||||
fclose(fpROM);
|
||||
fpROM = NULL;
|
||||
}
|
||||
tmp = pathData + tmp;
|
||||
|
||||
fpROM = fopen(tmp.c_str(), "rb");
|
||||
if (fpROM)
|
||||
{
|
||||
bFromFile = true;
|
||||
printf("\t * found at disk, offset %08X\n", offset);
|
||||
if (fseek(fpROM, offset, SEEK_SET) != 0)
|
||||
{
|
||||
printf("\t\t - ERROR seek file position\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (fpROM)
|
||||
{
|
||||
bFromFile = true;
|
||||
if (ftell(fpROM) != offset)
|
||||
{
|
||||
printf("\t * new file seek %08Xh\n", offset);
|
||||
fseek(fpROM, offset, SEEK_SET);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!bFromFile && fpROM)
|
||||
{
|
||||
fclose(fpROM);
|
||||
fpROM = NULL;
|
||||
}
|
||||
|
||||
curr_file_id = file_id;
|
||||
}
|
||||
rom.start(operation, protocol.address);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
u32 slot1client_read_GCDATAIN(eSlot1Operation operation)
|
||||
{
|
||||
if (protocol.operation == eSlot1Operation_B7_Read)
|
||||
{
|
||||
|
||||
u32 address = rom.getAddress();
|
||||
|
||||
if (fs && fs->isFAT(address))
|
||||
{
|
||||
u32 res = fs->getFATRecord(address);
|
||||
if (res != 0xFFFFFFFF)
|
||||
{
|
||||
rom.incAddress();
|
||||
return res;
|
||||
}
|
||||
}
|
||||
else
|
||||
if (fpROM)
|
||||
{
|
||||
u32 data = 0;
|
||||
u32 readed = fread(&data, 1, 4, fpROM);
|
||||
if (readed)
|
||||
{
|
||||
rom.incAddress();
|
||||
if (readed < 4)
|
||||
data |= ((u32)0xFFFFFFFF << (readed * 8));
|
||||
return data;
|
||||
}
|
||||
|
||||
fclose(fpROM);
|
||||
fpROM = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return rom.read();
|
||||
}
|
||||
};
|
||||
|
||||
ISlot1Interface* construct_Slot1_Retail_DEBUG() { return new Slot1_Retail_DEBUG(); }
|
||||
Executable
+318
@@ -0,0 +1,318 @@
|
||||
/*
|
||||
Copyright (C) 2010-2015 DeSmuME team
|
||||
|
||||
This file is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This file is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with the this software. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
// Games with NAND Flash:
|
||||
// Ore/WarioWare D.I.Y. - chip: SAMSUNG 004
|
||||
// KLC2811ANB-P204
|
||||
// NTR-UORE-0
|
||||
// - 128Mbit
|
||||
|
||||
#include "slot1comp_rom.h"
|
||||
#include "slot1comp_protocol.h"
|
||||
|
||||
#include "../slot1.h"
|
||||
#include "../NDSSystem.h"
|
||||
#include "../emufile.h"
|
||||
|
||||
//quick architecture overview:
|
||||
//NAND receives GC bus commands from MMU.cpp
|
||||
//those are passed on to the protocol component for parsing
|
||||
//protocol calls back into NAND via ISlot1Comp_Protocol_Client interface for things the protocol doesn't know about (the contents of the rom, chiefly)
|
||||
//NAND utilizes the rom component for address logic and delivering data.
|
||||
//it also processes some commands itself which aren't rom-related (the NANDy stuff)
|
||||
|
||||
class Slot1_Retail_NAND : public ISlot1Interface, public ISlot1Comp_Protocol_Client
|
||||
{
|
||||
private:
|
||||
u32 subAdr;
|
||||
|
||||
Slot1Comp_Protocol protocol;
|
||||
Slot1Comp_Rom rom;
|
||||
|
||||
u32 mode;
|
||||
u32 handle_save;
|
||||
|
||||
//current NAND read/write start position
|
||||
//when this is changed, the read/write cursor will be reset to it
|
||||
//when it is set to the same value, the read/write cursor will NOT be reset
|
||||
//(this is since some value must necessarily come in on the protocol address, so the 'current save_start' is used as a special 'dont change' value
|
||||
u32 save_start;
|
||||
|
||||
//current NAND read/write cursor
|
||||
u32 save_adr;
|
||||
|
||||
public:
|
||||
virtual Slot1Info const* info()
|
||||
{
|
||||
static Slot1InfoSimple info("Retail NAND","Slot1 retail NAND card emulation", 0x02);
|
||||
return &info;
|
||||
}
|
||||
|
||||
virtual void connect()
|
||||
{
|
||||
protocol.reset(this);
|
||||
protocol.chipId = gameInfo.chipID;
|
||||
protocol.gameCode = T1ReadLong((u8*)gameInfo.header.gameCode,0);
|
||||
|
||||
save_adr = 0;
|
||||
handle_save = 0;
|
||||
mode = 0;
|
||||
subAdr = T1ReadWord(gameInfo.header.reserved2, 0x6) << 17;
|
||||
}
|
||||
|
||||
virtual void write_command(u8 PROCNUM, GC_Command command)
|
||||
{
|
||||
protocol.write_command(command);
|
||||
}
|
||||
|
||||
virtual void write_GCDATAIN(u8 PROCNUM, u32 val)
|
||||
{
|
||||
protocol.write_GCDATAIN(PROCNUM, val);
|
||||
}
|
||||
virtual u32 read_GCDATAIN(u8 PROCNUM)
|
||||
{
|
||||
return protocol.read_GCDATAIN(PROCNUM);
|
||||
}
|
||||
|
||||
virtual void slot1client_startOperation(eSlot1Operation operation)
|
||||
{
|
||||
//INFO("Start command: %02X%02X%02X%02X%02X%02X%02X%02X\t",
|
||||
// protocol.command.bytes[0], protocol.command.bytes[1], protocol.command.bytes[2], protocol.command.bytes[3],
|
||||
// protocol.command.bytes[4], protocol.command.bytes[5], protocol.command.bytes[6], protocol.command.bytes[7]);
|
||||
//INFO("FROM: %08X\n", NDS_ARM9.instruct_adr);
|
||||
|
||||
u32 addressFromProtocol = (protocol.command.bytes[1] << 24) | (protocol.command.bytes[2] << 16) | (protocol.command.bytes[3] << 8) | protocol.command.bytes[4];
|
||||
|
||||
//pass the normal rom operations along to the rom component
|
||||
switch(operation)
|
||||
{
|
||||
case eSlot1Operation_00_ReadHeader_Unencrypted:
|
||||
rom.start(operation,addressFromProtocol);
|
||||
return;
|
||||
|
||||
case eSlot1Operation_2x_SecureAreaLoad:
|
||||
rom.start(operation,protocol.address);
|
||||
return;
|
||||
}
|
||||
|
||||
//handle special commands ourselves
|
||||
int cmd = protocol.command.bytes[0];
|
||||
switch(cmd)
|
||||
{
|
||||
// Nand Init
|
||||
case 0x94:
|
||||
mode = cmd;
|
||||
break;
|
||||
|
||||
// Nand Error?
|
||||
case 0xD6:
|
||||
break;
|
||||
|
||||
//Nand Write Page
|
||||
case 0x81:
|
||||
mode = cmd;
|
||||
if(addressFromProtocol != save_start)
|
||||
{
|
||||
save_start = addressFromProtocol;
|
||||
save_adr = (addressFromProtocol & gameInfo.mask) - subAdr;
|
||||
}
|
||||
handle_save = 1;
|
||||
break;
|
||||
|
||||
case 0x84: //Write disable
|
||||
case 0x85: //Write enable
|
||||
mode = cmd;
|
||||
break;
|
||||
case 0x8B:
|
||||
mode = cmd;
|
||||
handle_save = 0;
|
||||
MMU_new.backupDevice.flushBackup();
|
||||
break;
|
||||
|
||||
//Start read mode
|
||||
case 0xB7:
|
||||
if (handle_save)
|
||||
{
|
||||
mode = cmd;
|
||||
if(addressFromProtocol != save_start)
|
||||
{
|
||||
save_start = addressFromProtocol;
|
||||
save_adr = (addressFromProtocol & gameInfo.mask) - subAdr;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
rom.start(operation, addressFromProtocol);
|
||||
}
|
||||
break;
|
||||
|
||||
case 0xB2: //Set save position
|
||||
mode = cmd;
|
||||
save_start = addressFromProtocol;
|
||||
//cursor resets regardless of whether save_start changed, that's what makes this special.
|
||||
//the cursor could be reset to the beginning of the previous save_start region
|
||||
save_adr = (addressFromProtocol & gameInfo.mask) - subAdr;
|
||||
handle_save = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
virtual u32 slot1client_read_GCDATAIN(eSlot1Operation operation)
|
||||
{
|
||||
//pass the normal rom operations along to the rom component
|
||||
switch(operation)
|
||||
{
|
||||
case eSlot1Operation_00_ReadHeader_Unencrypted:
|
||||
case eSlot1Operation_2x_SecureAreaLoad:
|
||||
//case eSlot1Operation_B7_Read:
|
||||
return rom.read();
|
||||
}
|
||||
|
||||
//handle special commands ourselves
|
||||
int cmd = protocol.command.bytes[0];
|
||||
int val = 0;
|
||||
switch(cmd)
|
||||
{
|
||||
// Nand Init?
|
||||
case 0x94:
|
||||
val = 0;
|
||||
mode = 0;
|
||||
break;
|
||||
|
||||
//Rom/Save Read
|
||||
case 0xB7:
|
||||
{
|
||||
if(handle_save)
|
||||
{
|
||||
MMU_new.backupDevice.ensure(save_adr+4, (u8)0);
|
||||
|
||||
val = MMU_new.backupDevice.readLong(save_adr, 0);
|
||||
|
||||
save_adr += 4;
|
||||
}
|
||||
else
|
||||
{
|
||||
val = rom.read();
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
// Nand Status?
|
||||
case 0xD6:
|
||||
//0x80 == busy
|
||||
//0x40 == ??
|
||||
//0x20 == ready?
|
||||
//0x10 == write enabled?
|
||||
switch (mode)
|
||||
{
|
||||
case 0x84: //Write disable
|
||||
val = 0x20202020;
|
||||
break;
|
||||
case 0x85: //Write enable
|
||||
val = 0x20202020 | 0x10101010;
|
||||
break;
|
||||
case 0x8B:
|
||||
val = 0x60606060 | 0x10101010;
|
||||
break;
|
||||
case 0xB2: //Set save position
|
||||
val = 0x20202020;
|
||||
break;
|
||||
default:
|
||||
val = 0x60606060; //0x20 == ready
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
virtual void slot1client_write_GCDATAIN(eSlot1Operation operation, u32 val)
|
||||
{
|
||||
//pass the normal rom operations along to the rom component
|
||||
switch(operation)
|
||||
{
|
||||
case eSlot1Operation_00_ReadHeader_Unencrypted:
|
||||
case eSlot1Operation_B7_Read:
|
||||
case eSlot1Operation_2x_SecureAreaLoad:
|
||||
return;
|
||||
}
|
||||
|
||||
//handle special commands ourselves
|
||||
int cmd = protocol.command.bytes[0];
|
||||
u32 value = val;
|
||||
u32 adr = save_adr;
|
||||
switch(cmd)
|
||||
{
|
||||
case 0x81: //Nand Write
|
||||
|
||||
MMU_new.backupDevice.ensure(adr+4, (u8)0);
|
||||
MMU_new.backupDevice.writeLong(adr, val);
|
||||
|
||||
save_adr += 4;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
virtual void post_fakeboot(int PROCNUM)
|
||||
{
|
||||
// The BIOS leaves the card in NORMAL mode
|
||||
protocol.mode = eCardMode_NORMAL;
|
||||
}
|
||||
|
||||
virtual void savestate(EMUFILE* os)
|
||||
{
|
||||
s32 version = 0;
|
||||
|
||||
protocol.savestate(os);
|
||||
rom.savestate(os);
|
||||
|
||||
os->write32le(version);
|
||||
|
||||
os->write32le(mode);
|
||||
os->write32le(handle_save);
|
||||
os->write32le(save_adr);
|
||||
os->write32le(save_start);
|
||||
os->write32le(subAdr);
|
||||
}
|
||||
|
||||
virtual void loadstate(EMUFILE* is)
|
||||
{
|
||||
s32 version = 0;
|
||||
|
||||
protocol.loadstate(is);
|
||||
rom.loadstate(is);
|
||||
|
||||
is->read32le(&version);
|
||||
|
||||
// version 0
|
||||
if (version >= 0)
|
||||
{
|
||||
is->read32le(&mode);
|
||||
is->read32le(&handle_save);
|
||||
is->read32le(&save_adr);
|
||||
is->read32le(&save_start);
|
||||
is->read32le(&subAdr);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
|
||||
ISlot1Interface* construct_Slot1_Retail_NAND() { return new Slot1_Retail_NAND(); }
|
||||
|
||||
|
||||
Executable
+41
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
Copyright (C) 2013-2015 DeSmuME team
|
||||
|
||||
This file is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This file is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with the this software. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
//this file contains the components used for emulating standard gamecard "MC" devices (eeprom, fram, flash)
|
||||
//this is largely done by accessing the BackupDevice resources in the core emulator
|
||||
|
||||
#include "slot1comp_mc.h"
|
||||
|
||||
#include "../MMU.h"
|
||||
#include "../NDSSystem.h"
|
||||
|
||||
Slot1Comp_MC g_Slot1Comp_MC;
|
||||
|
||||
u8 Slot1Comp_MC::auxspi_transaction(int PROCNUM, u8 value)
|
||||
{
|
||||
return MMU_new.backupDevice.data_command(value, PROCNUM);
|
||||
}
|
||||
|
||||
void Slot1Comp_MC::auxspi_reset(int PROCNUM)
|
||||
{
|
||||
MMU_new.backupDevice.reset_command();
|
||||
}
|
||||
|
||||
void Slot1Comp_MC::connect()
|
||||
{
|
||||
if(!memcmp(gameInfo.header.gameCode,"AXBJ", 4)) MMU_new.backupDevice.uninitializedValue = 0x00; // Daigassou! Band Brothers DX (JP)
|
||||
}
|
||||
Executable
+35
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
Copyright (C) 2013-2015 DeSmuME team
|
||||
|
||||
This file is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This file is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with the this software. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
//this file contains the components used for emulating standard gamecard "MC" devices (eeprom, fram, flash)
|
||||
|
||||
#ifndef _SLOT1COMP_MC_H
|
||||
#define _SLOT1COMP_MC_H
|
||||
|
||||
#include "../types.h"
|
||||
|
||||
class Slot1Comp_MC
|
||||
{
|
||||
public:
|
||||
u8 auxspi_transaction(int PROCNUM, u8 value);
|
||||
void auxspi_reset(int PROCNUM);
|
||||
void connect();
|
||||
};
|
||||
|
||||
extern Slot1Comp_MC g_Slot1Comp_MC;
|
||||
|
||||
#endif
|
||||
Executable
+256
@@ -0,0 +1,256 @@
|
||||
/*
|
||||
Copyright (C) 2012-2015 DeSmuME team
|
||||
|
||||
This file is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This file is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with the this software. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "slot1comp_protocol.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "../armcpu.h"
|
||||
#include "../encrypt.h"
|
||||
#include "../emufile.h"
|
||||
#include "../utils/decrypt/decrypt.h"
|
||||
|
||||
static _KEY1 key1((const u8*)arm7_key);
|
||||
|
||||
void Slot1Comp_Protocol::reset(ISlot1Comp_Protocol_Client* client)
|
||||
{
|
||||
this->client = client;
|
||||
|
||||
//we have to initialize this to something.. lets use dummy.
|
||||
//(need to clean this up...)
|
||||
memcpy(&command,"\x9F\0\0\0\0\0\0\0",8);
|
||||
operation = eSlot1Operation_9F_Dummy;
|
||||
|
||||
length = 0;
|
||||
delay = 0;
|
||||
mode = eCardMode_RAW;
|
||||
}
|
||||
|
||||
void Slot1Comp_Protocol::write_command_RAW(GC_Command command)
|
||||
{
|
||||
int cmd = command.bytes[0];
|
||||
if(cmd == 0x9F)
|
||||
{
|
||||
operation = eSlot1Operation_9F_Dummy;
|
||||
length = 0x2000;
|
||||
}
|
||||
if(cmd == 0x90)
|
||||
{
|
||||
operation = eSlot1Operation_90_ChipID;
|
||||
length = 4;
|
||||
//we handle this operation ourselves
|
||||
}
|
||||
if(cmd == 0x3C)
|
||||
{
|
||||
//switch to KEY1
|
||||
length = 0;
|
||||
mode = eCardMode_KEY1;
|
||||
|
||||
//defer initialization of KEY1 until we know we need it, just to save some CPU time.
|
||||
//TODO - some information about these parameters
|
||||
//level == 2
|
||||
//modulo == 8
|
||||
key1.init(gameCode, 2, 0x08);
|
||||
GCLOG("[GC] KEY1 ACTIVATED\n");
|
||||
}
|
||||
if(cmd == 0x00)
|
||||
{
|
||||
operation = eSlot1Operation_00_ReadHeader_Unencrypted;
|
||||
client->slot1client_startOperation(operation);
|
||||
}
|
||||
}
|
||||
|
||||
void Slot1Comp_Protocol::write_command_KEY1(GC_Command command)
|
||||
{
|
||||
//decrypt the KEY1-format command
|
||||
u32 temp[2];
|
||||
command.toCryptoBuffer(temp);
|
||||
key1.decrypt(temp);
|
||||
command.fromCryptoBuffer(temp);
|
||||
GCLOG("[GC] (key1-decrypted):"); command.print();
|
||||
|
||||
//and process it:
|
||||
int cmd = command.bytes[0];
|
||||
switch(cmd&0xF0)
|
||||
{
|
||||
case 0x10:
|
||||
operation = eSlot1Operation_1x_ChipID;
|
||||
delay = 0x910, length = 4;
|
||||
//we handle this operation ourselves
|
||||
break;
|
||||
|
||||
case 0x20:
|
||||
operation = eSlot1Operation_2x_SecureAreaLoad;
|
||||
delay = 0x910, length = 0x11A8;
|
||||
|
||||
//TODO - more endian-safe way of doing this (theres examples in R4)
|
||||
{
|
||||
#ifdef LOCAL_LE
|
||||
u64 cmd64 = bswap64(*(u64*)command.bytes);
|
||||
#else
|
||||
u64 cmd64 = *(u64*)command.bytes;
|
||||
#endif
|
||||
//todo - parse into blocknumber
|
||||
u32 blocknumber = (cmd64>>44)&0xFFFF;
|
||||
if(blocknumber<4||blocknumber>7)
|
||||
printf("SLOT1 WARNING: INVALID BLOCKNUMBER FOR \"Get Secure Area Block\": 0x%04X\n",blocknumber);
|
||||
address = blocknumber*0x1000;
|
||||
}
|
||||
client->slot1client_startOperation(operation);
|
||||
break;
|
||||
|
||||
case 0x40:
|
||||
//switch to KEY2
|
||||
delay = 0x910, length = 0;
|
||||
//well.. not really... yet.
|
||||
GCLOG("[GC] KEY2 ACTIVATED\n");
|
||||
break;
|
||||
|
||||
case 0x60:
|
||||
//KEY2 disable? any info?
|
||||
break;
|
||||
|
||||
case 0xA0:
|
||||
delay = 0x910, length = 0;
|
||||
mode = eCardMode_NORMAL;
|
||||
GCLOG("[GC] NORMAL MODE ACTIVATED\n");
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void Slot1Comp_Protocol::write_command_NORMAL(GC_Command command)
|
||||
{
|
||||
switch(command.bytes[0])
|
||||
{
|
||||
case 0xB7:
|
||||
{
|
||||
operation = eSlot1Operation_B7_Read;
|
||||
|
||||
//TODO - more endian-safe way of doing this (theres examples in R4)
|
||||
#ifdef LOCAL_LE
|
||||
u64 cmd64 = bswap64(*(u64*)command.bytes);
|
||||
#else
|
||||
u64 cmd64 = *(u64*)command.bytes;
|
||||
#endif
|
||||
address = (u32)((cmd64 >> 24));
|
||||
length = 0x200;
|
||||
|
||||
client->slot1client_startOperation(operation);
|
||||
}
|
||||
break;
|
||||
|
||||
case 0xB8:
|
||||
operation = eSlot1Operation_B8_ChipID;
|
||||
delay = 0, length = 4;
|
||||
//we handle this operation ourselves
|
||||
break;
|
||||
|
||||
default:
|
||||
operation = eSlot1Operation_Unknown;
|
||||
client->slot1client_startOperation(operation);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void Slot1Comp_Protocol::write_command(GC_Command command)
|
||||
{
|
||||
this->command = command;
|
||||
|
||||
//unrecognized commands will do something depending on the current state of the card
|
||||
delay = 0;
|
||||
length = 0;
|
||||
address = 0;
|
||||
|
||||
switch(mode)
|
||||
{
|
||||
case eCardMode_RAW:
|
||||
write_command_RAW(command);
|
||||
break;
|
||||
|
||||
case eCardMode_KEY1:
|
||||
write_command_KEY1(command);
|
||||
break;
|
||||
|
||||
case eCardMode_NORMAL:
|
||||
write_command_NORMAL(command);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void Slot1Comp_Protocol::write_GCDATAIN(u8 PROCNUM, u32 val)
|
||||
{
|
||||
switch(operation)
|
||||
{
|
||||
case eSlot1Operation_Unknown:
|
||||
client->slot1client_write_GCDATAIN(operation,val);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
u32 Slot1Comp_Protocol::read_GCDATAIN(u8 PROCNUM)
|
||||
{
|
||||
switch(operation)
|
||||
{
|
||||
default:
|
||||
return client->slot1client_read_GCDATAIN(operation);
|
||||
|
||||
case eSlot1Operation_9F_Dummy:
|
||||
return 0xFFFFFFFF;
|
||||
|
||||
case eSlot1Operation_1x_ChipID:
|
||||
return chipId;
|
||||
|
||||
case eSlot1Operation_90_ChipID:
|
||||
case eSlot1Operation_B8_ChipID:
|
||||
|
||||
//Most games continuously compare the current chipId with the value in
|
||||
//stored in memory at boot-up, probably to know if the card was removed.
|
||||
|
||||
//staff of kings verifies this (it also uses the arm7 IRQ 20 to detect card ejects)
|
||||
return chipId;
|
||||
}
|
||||
|
||||
return 0xFFFFFFFF;
|
||||
}
|
||||
|
||||
void Slot1Comp_Protocol::savestate(EMUFILE* os)
|
||||
{
|
||||
s32 version = 0;
|
||||
os->write32le(version);
|
||||
os->write32le((s32)mode);
|
||||
os->write32le((s32)operation);
|
||||
os->fwrite(command.bytes,8);
|
||||
os->write32le(address);
|
||||
os->write32le(length);
|
||||
os->write32le(delay);
|
||||
os->write32le(chipId);
|
||||
os->write32le(gameCode);
|
||||
}
|
||||
|
||||
void Slot1Comp_Protocol::loadstate(EMUFILE* is)
|
||||
{
|
||||
s32 version = is->read32le();
|
||||
mode = (eCardMode)is->read32le();
|
||||
operation = (eSlot1Operation)is->read32le();
|
||||
is->fread(command.bytes,8);
|
||||
address = is->read32le();
|
||||
length = is->read32le();
|
||||
delay = is->read32le();
|
||||
chipId = is->read32le();
|
||||
gameCode = is->read32le();
|
||||
}
|
||||
Executable
+114
@@ -0,0 +1,114 @@
|
||||
/*
|
||||
Copyright (C) 2013-2015 DeSmuME team
|
||||
|
||||
This file is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This file is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with the this software. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
//this file contains the components used for emulating standard gamecard protocol.
|
||||
//this largely means the complex boot-up process.
|
||||
//i think there's no reason why proprietary cards couldn't speak any protocol they wish, as long as they didn't mind being unbootable.
|
||||
//TODO - could this be refactored into a base class? that's probably more reasonable. but we've gone with this modular mix-in architecture so... not yet.
|
||||
|
||||
#ifndef _SLOT1COMP_PROTOCOL_H
|
||||
#define _SLOT1COMP_PROTOCOL_H
|
||||
|
||||
#include "../types.h"
|
||||
#include "../MMU.h"
|
||||
|
||||
class EMUFILE;
|
||||
|
||||
enum eSlot1Operation
|
||||
{
|
||||
//----------
|
||||
//RAW mode operations
|
||||
//before encrypted communications can be established, some values from the rom header must be read.
|
||||
//this is the only way to read the header, actually, since the only reading commands available to games (after KEY2 mode is set) are
|
||||
eSlot1Operation_00_ReadHeader_Unencrypted,
|
||||
//it's not clear why this exists
|
||||
eSlot1Operation_9F_Dummy,
|
||||
eSlot1Operation_90_ChipID,
|
||||
//----------
|
||||
|
||||
//----------
|
||||
//KEY1 mode operations
|
||||
eSlot1Operation_1x_ChipID,
|
||||
eSlot1Operation_2x_SecureAreaLoad,
|
||||
//----------
|
||||
|
||||
//----------
|
||||
//NORMAL mode operations
|
||||
//the main rom data reading command
|
||||
eSlot1Operation_B7_Read,
|
||||
eSlot1Operation_B8_ChipID,
|
||||
//----------
|
||||
|
||||
eSlot1Operation_Unknown
|
||||
};
|
||||
|
||||
class ISlot1Comp_Protocol_Client
|
||||
{
|
||||
public:
|
||||
virtual void slot1client_startOperation(eSlot1Operation operation) {}
|
||||
virtual u32 slot1client_read_GCDATAIN(eSlot1Operation operation) = 0;
|
||||
virtual void slot1client_write_GCDATAIN(eSlot1Operation operation, u32 val) {}
|
||||
};
|
||||
|
||||
|
||||
class Slot1Comp_Protocol
|
||||
{
|
||||
public:
|
||||
|
||||
void savestate(EMUFILE* os);
|
||||
void loadstate(EMUFILE* is);
|
||||
|
||||
//set some kind of protocol/hardware reset state
|
||||
void reset(ISlot1Comp_Protocol_Client* client);
|
||||
|
||||
//signals from the GC bus
|
||||
void write_command(GC_Command command);
|
||||
void write_GCDATAIN(u8 PROCNUM, u32 val);
|
||||
u32 read_GCDATAIN(u8 PROCNUM);
|
||||
|
||||
//helpers for write_command()
|
||||
void write_command_RAW(GC_Command command);
|
||||
void write_command_KEY1(GC_Command command);
|
||||
void write_command_NORMAL(GC_Command command);
|
||||
|
||||
//operations not related to obscurities of the protocol or otherwise unknown are passed through to the client here
|
||||
ISlot1Comp_Protocol_Client* client;
|
||||
|
||||
//--state--
|
||||
|
||||
//the major operational mode. the protocol shifts modes and interprets commands into operations differently depending on the mode
|
||||
eCardMode mode;
|
||||
|
||||
//the current operational state
|
||||
eSlot1Operation operation;
|
||||
|
||||
//the command we're currently crunching on
|
||||
GC_Command command;
|
||||
|
||||
//most operations are defined in terms of returning a series of bytes
|
||||
//the meaning of these varies by operation. they are provided publicly as a service to clients
|
||||
u32 address;
|
||||
s32 length, delay; //the expected length and delay of this state
|
||||
|
||||
//chipId which should be returned by the various chipId commands
|
||||
u32 chipId;
|
||||
|
||||
//gameCode used by the protocol KEY1 crypto
|
||||
u32 gameCode;
|
||||
};
|
||||
|
||||
#endif //_SLOT1COMP_PROTOCOL_H
|
||||
Executable
+122
@@ -0,0 +1,122 @@
|
||||
/*
|
||||
Copyright (C) 2010-2015 DeSmuME team
|
||||
|
||||
This file is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This file is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with the this software. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "slot1comp_rom.h"
|
||||
|
||||
#include "../NDSSystem.h"
|
||||
#include "../emufile.h"
|
||||
|
||||
|
||||
void Slot1Comp_Rom::start(eSlot1Operation operation, u32 addr)
|
||||
{
|
||||
this->operation = operation;
|
||||
this->address = addr;
|
||||
}
|
||||
|
||||
u32 Slot1Comp_Rom::read()
|
||||
{
|
||||
switch(operation)
|
||||
{
|
||||
case eSlot1Operation_00_ReadHeader_Unencrypted:
|
||||
{
|
||||
u32 ret = gameInfo.readROM(address);
|
||||
address = (address + 4) & 0xFFF;
|
||||
return ret;
|
||||
}
|
||||
break;
|
||||
|
||||
case eSlot1Operation_2x_SecureAreaLoad:
|
||||
{
|
||||
//see B7 for details
|
||||
|
||||
//zero 15-sep-2014 - this is meaningless. newer mask is actually reasonable
|
||||
//address &= gameInfo.mask; //sanity check
|
||||
u32 secureAreaAddress = (address - 0x4000);
|
||||
secureAreaAddress &= 0x3FFF; //memory safe sanity test
|
||||
u32 ret = LE_TO_LOCAL_32(*(u32*)(gameInfo.secureArea + secureAreaAddress));
|
||||
address = (address&~0xFFF) + ((address+4)&0xFFF);
|
||||
return ret;
|
||||
}
|
||||
|
||||
case eSlot1Operation_B7_Read:
|
||||
{
|
||||
//TODO - check about non-4-byte aligned addresses
|
||||
|
||||
//it seems that etrian odyssey 3 doesnt work unless we mask this to cart size.
|
||||
//but, a thought: does the internal rom address counter register wrap around? we may be making a mistake by keeping the extra precision
|
||||
//but there is no test case yet
|
||||
address &= gameInfo.mask;
|
||||
|
||||
//feature of retail carts:
|
||||
//B7 "Can be used only for addresses 8000h and up, smaller addresses will be silently redirected to address `8000h+(addr AND 1FFh)`"
|
||||
if(address < 0x8000)
|
||||
address = (0x8000 + (address & 0x1FF));
|
||||
|
||||
//1. as a sanity measure for funny-sized roms (homebrew and perhaps truncated retail roms) we need to protect ourselves by returning 0xFF for things still out of range.
|
||||
//2. this isnt right, unless someone documents otherwise:
|
||||
//if (address > gameInfo.header.endROMoffset)
|
||||
// ... the cart hardware doesnt know anything about the rom header. if it has a totally bogus endROMoffset, the cart will probably work just fine. and, the +4 is missing anyway:
|
||||
//3. this is better: it just allows us to read 0xFF anywhere we dont have rom data. forget what the header says
|
||||
if(address+4 > gameInfo.romsize)
|
||||
{
|
||||
DEBUG_Notify.ReadBeyondEndOfCart(address,gameInfo.romsize);
|
||||
return 0xFFFFFFFF;
|
||||
}
|
||||
|
||||
//actually read from the ROM provider
|
||||
u32 ret = gameInfo.readROM(address);
|
||||
|
||||
//"However, the datastream wraps to the begin of the current 4K block when address+length crosses a 4K boundary (1000h bytes)"
|
||||
address = (address&~0xFFF) + ((address+4)&0xFFF);
|
||||
|
||||
return ret;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
return 0;
|
||||
|
||||
} //switch(operation)
|
||||
} //Slot1Comp_Rom::read()
|
||||
|
||||
u32 Slot1Comp_Rom::getAddress()
|
||||
{
|
||||
return address & gameInfo.mask;
|
||||
} //Slot1Comp_Rom::getAddress()
|
||||
|
||||
u32 Slot1Comp_Rom::incAddress()
|
||||
{
|
||||
address &= gameInfo.mask;
|
||||
address = (address&~0xFFF) + ((address+4)&0xFFF);
|
||||
return address;
|
||||
}
|
||||
|
||||
|
||||
void Slot1Comp_Rom::savestate(EMUFILE* os)
|
||||
{
|
||||
s32 version = 0;
|
||||
os->write32le(version);
|
||||
os->write32le((s32)operation);
|
||||
os->write32le(address);
|
||||
}
|
||||
|
||||
void Slot1Comp_Rom::loadstate(EMUFILE* is)
|
||||
{
|
||||
s32 version = is->read32le();
|
||||
operation = (eSlot1Operation)is->read32le();
|
||||
address = is->read32le();
|
||||
}
|
||||
Executable
+45
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
Copyright (C) 2010-2015 DeSmuME team
|
||||
|
||||
This file is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This file is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with the this software. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
//this file contains the components used for emulating standard gamecard ROMs
|
||||
//this is largely done by accessing the rom provided in the core emulator
|
||||
|
||||
#ifndef _SLOT1COMP_ROM_H
|
||||
#define _SLOT1COMP_ROM_H
|
||||
|
||||
#include "slot1comp_protocol.h"
|
||||
#include "../types.h"
|
||||
|
||||
class EMUFILE;
|
||||
|
||||
class Slot1Comp_Rom
|
||||
{
|
||||
public:
|
||||
void start(eSlot1Operation operation, u32 addr);
|
||||
u32 read();
|
||||
u32 getAddress();
|
||||
u32 incAddress();
|
||||
|
||||
void savestate(EMUFILE* os);
|
||||
void loadstate(EMUFILE* is);
|
||||
|
||||
private:
|
||||
u32 address;
|
||||
eSlot1Operation operation;
|
||||
};
|
||||
|
||||
#endif
|
||||
Executable
+72
@@ -0,0 +1,72 @@
|
||||
/*
|
||||
Copyright (C) 2013-2015 DeSmuME team
|
||||
|
||||
This file is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This file is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with the this software. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "../slot2.h"
|
||||
|
||||
class Slot2_Auto : public ISlot2Interface
|
||||
{
|
||||
private:
|
||||
ISlot2Interface *mSelectedImplementation;
|
||||
|
||||
public:
|
||||
Slot2_Auto()
|
||||
: mSelectedImplementation(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
virtual Slot2Info const* info()
|
||||
{
|
||||
static Slot2InfoSimple info("Auto","Slot2 (auto-selection) device emulation", 0xFE);
|
||||
return &info;
|
||||
}
|
||||
|
||||
virtual void connect()
|
||||
{
|
||||
slot2_selected_type = slot2_DetermineType();
|
||||
mSelectedImplementation = slot2_List[slot2_selected_type];
|
||||
mSelectedImplementation->connect();
|
||||
printf("Slot2 auto-selected device type: %s (0x%02X)\n", mSelectedImplementation->info()->name(), mSelectedImplementation->info()->id());
|
||||
}
|
||||
|
||||
virtual void disconnect()
|
||||
{
|
||||
if(mSelectedImplementation) mSelectedImplementation->disconnect();
|
||||
mSelectedImplementation = NULL;
|
||||
}
|
||||
|
||||
virtual void writeByte(u8 PROCNUM, u32 addr, u8 val) { mSelectedImplementation->writeByte(PROCNUM, addr, val); }
|
||||
virtual void writeWord(u8 PROCNUM, u32 addr, u16 val) { mSelectedImplementation->writeWord(PROCNUM, addr, val); }
|
||||
virtual void writeLong(u8 PROCNUM, u32 addr, u32 val) { mSelectedImplementation->writeLong(PROCNUM, addr, val); }
|
||||
|
||||
virtual u8 readByte(u8 PROCNUM, u32 addr) { return mSelectedImplementation->readByte(PROCNUM, addr); }
|
||||
virtual u16 readWord(u8 PROCNUM, u32 addr) { return mSelectedImplementation->readWord(PROCNUM, addr); }
|
||||
virtual u32 readLong(u8 PROCNUM, u32 addr) { return mSelectedImplementation->readLong(PROCNUM, addr); }
|
||||
|
||||
virtual void savestate(EMUFILE* os)
|
||||
{
|
||||
mSelectedImplementation->savestate(os);
|
||||
}
|
||||
|
||||
virtual void loadstate(EMUFILE* is)
|
||||
{
|
||||
mSelectedImplementation->loadstate(is);
|
||||
}
|
||||
};
|
||||
|
||||
ISlot2Interface* construct_Slot2_Auto() { return new Slot2_Auto(); }
|
||||
Executable
+198
@@ -0,0 +1,198 @@
|
||||
/*
|
||||
Copyright (C) 2009 CrazyMax
|
||||
Copyright (C) 2009-2015 DeSmuME team
|
||||
|
||||
This file is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This file is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with the this software. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "../slot2.h"
|
||||
#include "../emufile.h"
|
||||
#include "../mem.h"
|
||||
|
||||
#if 0
|
||||
#define EXPINFO(...) INFO(__VA_ARGS__)
|
||||
#else
|
||||
#define EXPINFO(...)
|
||||
#endif
|
||||
|
||||
#define EXPANSION_MEMORY_SIZE (8 * 1024 * 1024)
|
||||
|
||||
static u8 header_0x00B0[] =
|
||||
{ 0xFF, 0xFF, 0x96, 0x00, //this 0x96 is strange. it can't be read from the pak when it boots, it must appear later
|
||||
0x00, 0x24, 0x24, 0x24,
|
||||
0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0x7F
|
||||
};
|
||||
|
||||
class Slot2_ExpansionPak : public ISlot2Interface
|
||||
{
|
||||
private:
|
||||
u8 *expMemory;
|
||||
bool ext_ram_lock;
|
||||
public:
|
||||
|
||||
Slot2_ExpansionPak()
|
||||
{
|
||||
expMemory = NULL;
|
||||
ext_ram_lock = true;
|
||||
}
|
||||
|
||||
virtual Slot2Info const* info()
|
||||
{
|
||||
static Slot2InfoSimple info("Memory Expansion Pak", "Official RAM expansion for Opera browser", 0x05);
|
||||
return &info;
|
||||
}
|
||||
|
||||
virtual void connect()
|
||||
{
|
||||
if (expMemory == NULL)
|
||||
{
|
||||
expMemory = new u8[EXPANSION_MEMORY_SIZE];
|
||||
}
|
||||
memset(expMemory, 0xFF, EXPANSION_MEMORY_SIZE);
|
||||
ext_ram_lock = true;
|
||||
}
|
||||
|
||||
virtual void disconnect()
|
||||
{
|
||||
delete[] expMemory;
|
||||
expMemory = NULL;
|
||||
}
|
||||
|
||||
virtual void writeByte(u8 PROCNUM, u32 addr, u8 val)
|
||||
{
|
||||
if (ext_ram_lock) return;
|
||||
|
||||
if (addr >= 0x09000000)
|
||||
{
|
||||
u32 offs = (addr - 0x09000000);
|
||||
if (offs >= EXPANSION_MEMORY_SIZE) return;
|
||||
T1WriteByte(expMemory, offs, val);
|
||||
}
|
||||
EXPINFO("ExpMemory: write 08 at 0x%08X = 0x%02X\n", addr, val);
|
||||
}
|
||||
virtual void writeWord(u8 PROCNUM, u32 addr, u16 val)
|
||||
{
|
||||
if (addr == 0x08240000)
|
||||
{
|
||||
if (val == 0)
|
||||
ext_ram_lock = true;
|
||||
else
|
||||
if (val == 1)
|
||||
ext_ram_lock = false;
|
||||
return;
|
||||
}
|
||||
|
||||
if (ext_ram_lock) return;
|
||||
|
||||
if (addr >= 0x09000000)
|
||||
{
|
||||
u32 offs = (addr - 0x09000000);
|
||||
if (offs >= EXPANSION_MEMORY_SIZE) return;
|
||||
T1WriteWord(expMemory, offs, val);
|
||||
}
|
||||
EXPINFO("ExpMemory: write 16 at 0x%08X = 0x%04X\n", addr, val);
|
||||
}
|
||||
virtual void writeLong(u8 PROCNUM, u32 addr, u32 val)
|
||||
{
|
||||
if (ext_ram_lock) return;
|
||||
|
||||
if (addr >= 0x09000000)
|
||||
{
|
||||
u32 offs = (addr - 0x09000000);
|
||||
if (offs >= EXPANSION_MEMORY_SIZE) return;
|
||||
T1WriteLong(expMemory, offs, val);
|
||||
}
|
||||
EXPINFO("ExpMemory: write 32 at 0x%08X = 0x%08X\n", addr, val);
|
||||
}
|
||||
|
||||
virtual u8 readByte(u8 PROCNUM, u32 addr)
|
||||
{
|
||||
EXPINFO("ExpMemory: read 08 at 0x%08X\n", addr);
|
||||
|
||||
if ((addr >= 0x080000B0) && (addr < 0x080000C0))
|
||||
return T1ReadByte(header_0x00B0, (addr - 0x080000B0));
|
||||
|
||||
if (addr >= 0x09000000)
|
||||
{
|
||||
u32 offs = (addr - 0x09000000);
|
||||
if (offs >= EXPANSION_MEMORY_SIZE) return (0xFF);
|
||||
return T1ReadByte(expMemory, offs);
|
||||
}
|
||||
|
||||
return 0xFF;
|
||||
}
|
||||
virtual u16 readWord(u8 PROCNUM, u32 addr)
|
||||
{
|
||||
EXPINFO("ExpMemory: read 16 at 0x%08X\n", addr);
|
||||
|
||||
if ((addr >= 0x080000B0) && (addr < 0x080000C0))
|
||||
return T1ReadWord(header_0x00B0, (addr - 0x080000B0));
|
||||
|
||||
if (addr == 0x0801FFFC) return 0x7FFF;
|
||||
if (addr == 0x08240002) return 0; //this can't be 0xFFFF. dunno why, we just guessed 0
|
||||
|
||||
if (addr >= 0x09000000)
|
||||
{
|
||||
u32 offs = (addr - 0x09000000);
|
||||
if (offs >= EXPANSION_MEMORY_SIZE) return (0xFFFF);
|
||||
return T1ReadWord(expMemory, offs);
|
||||
}
|
||||
|
||||
return 0xFFFF;
|
||||
}
|
||||
virtual u32 readLong(u8 PROCNUM, u32 addr)
|
||||
{
|
||||
EXPINFO("ExpMemory: read 32 at 0x%08X\n", addr);
|
||||
|
||||
if((addr >= 0x080000B0) && (addr < 0x080000C0))
|
||||
return T1ReadLong(header_0x00B0, (addr - 0x080000B0));
|
||||
|
||||
if (addr >= 0x09000000)
|
||||
{
|
||||
u32 offs = (addr - 0x09000000);
|
||||
if (offs >= EXPANSION_MEMORY_SIZE) return 0xFFFFFFFF;
|
||||
return T1ReadLong(expMemory, offs);
|
||||
}
|
||||
|
||||
return 0xFFFFFFFF;
|
||||
}
|
||||
|
||||
virtual void savestate(EMUFILE* os)
|
||||
{
|
||||
s32 version = 0;
|
||||
EMUFILE_MEMORY *ram = new EMUFILE_MEMORY(expMemory, EXPANSION_MEMORY_SIZE);
|
||||
os->write32le(version);
|
||||
os->write32le((u32)ext_ram_lock);
|
||||
os->writeMemoryStream(ram);
|
||||
delete ram;
|
||||
}
|
||||
|
||||
virtual void loadstate(EMUFILE* is)
|
||||
{
|
||||
EMUFILE_MEMORY *ram = new EMUFILE_MEMORY();
|
||||
|
||||
s32 version = is->read32le();
|
||||
|
||||
if (version >= 0)
|
||||
{
|
||||
is->read32le((u32*)&ext_ram_lock);
|
||||
is->readMemoryStream(ram);
|
||||
memcpy(expMemory, ram->buf(), std::min(EXPANSION_MEMORY_SIZE, ram->size()));
|
||||
}
|
||||
delete ram;
|
||||
}
|
||||
};
|
||||
|
||||
ISlot2Interface* construct_Slot2_ExpansionPak() { return new Slot2_ExpansionPak(); }
|
||||
Executable
+464
@@ -0,0 +1,464 @@
|
||||
/*
|
||||
Copyright (C) 2009 CrazyMax
|
||||
Copyright (C) 2009-2015 DeSmuME team
|
||||
|
||||
This file is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This file is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with the this software. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "../slot2.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "../debug.h"
|
||||
#include "../NDSSystem.h"
|
||||
#include "../path.h"
|
||||
#include "../emufile.h"
|
||||
|
||||
#define EEPROM 0x52504545
|
||||
#define SRAM_ 0x4D415253
|
||||
#define FLASH 0x53414C46
|
||||
#define FLASH1M_ 0x5F4D3148
|
||||
#define SIIRTC_V 0x52494953
|
||||
|
||||
static const char *saveTypes[] = {
|
||||
"EEPROM",
|
||||
"SRAM",
|
||||
"FLASH",
|
||||
"FLASH1M",
|
||||
"SIIRTC_V",
|
||||
};
|
||||
|
||||
class Slot2_GbaCart : public ISlot2Interface
|
||||
{
|
||||
private:
|
||||
EMUFILE* fROM;
|
||||
EMUFILE* fSRAM;
|
||||
u32 romSize;
|
||||
u32 sramSize;
|
||||
u32 saveType;
|
||||
|
||||
struct
|
||||
{
|
||||
u32 size;
|
||||
u8 state;
|
||||
u8 cmd;
|
||||
u8 idDevice;
|
||||
u8 idManufacturer;
|
||||
u8 bank;
|
||||
} gbaFlash;
|
||||
|
||||
u32 readRom(const u32 pos, const u8 size)
|
||||
{
|
||||
if (!fROM) return 0xFFFFFFFF;
|
||||
|
||||
fROM->fseek(pos, SEEK_SET);
|
||||
|
||||
u32 data = 0xFFFFFFFF;
|
||||
u32 readed = fROM->fread(&data, size);
|
||||
return data;
|
||||
}
|
||||
|
||||
u32 readSRAM(const u32 pos, const u8 size)
|
||||
{
|
||||
if (!fSRAM)
|
||||
return 0xFFFFFFFF;
|
||||
|
||||
fSRAM->fseek(pos, SEEK_SET);
|
||||
|
||||
u32 data = 0xFFFFFFFF;
|
||||
u32 readed = fSRAM->fread(&data, size);
|
||||
return data;
|
||||
}
|
||||
|
||||
void writeSRAM(const u32 pos, const u8 *data, u32 size)
|
||||
{
|
||||
if (!fSRAM)
|
||||
return;
|
||||
|
||||
fSRAM->fseek(pos, SEEK_SET);
|
||||
|
||||
u32 writed = size;
|
||||
fSRAM->fwrite(data, size);
|
||||
fSRAM->fflush();
|
||||
}
|
||||
|
||||
|
||||
u32 scanSaveTypeGBA()
|
||||
{
|
||||
if (!fROM) return 0xFF;
|
||||
|
||||
fROM->fseek(0, SEEK_SET);
|
||||
int size = fROM->size();
|
||||
|
||||
int lastpct=1;
|
||||
|
||||
int len = fROM->size();
|
||||
for(;;)
|
||||
{
|
||||
u32 tmp;
|
||||
u32 readed = fROM->fread(&tmp, 4);
|
||||
|
||||
int pos = fROM->ftell();
|
||||
int currPct = pos*100/(size-1);
|
||||
for(int i=lastpct;i<currPct;i++)
|
||||
{
|
||||
if(i%10==0)
|
||||
printf(" %d%%\n",i/10*10);
|
||||
else printf(".");
|
||||
lastpct = currPct;
|
||||
}
|
||||
|
||||
if (readed < 4)
|
||||
break;
|
||||
|
||||
if(pos >= len)
|
||||
break;
|
||||
|
||||
|
||||
switch (tmp)
|
||||
{
|
||||
case EEPROM:
|
||||
return 1;
|
||||
case SRAM_:
|
||||
return 2;
|
||||
case FLASH:
|
||||
{
|
||||
u32 tmp = fROM->read32le();
|
||||
return ((tmp == FLASH1M_)?3:5);
|
||||
}
|
||||
case SIIRTC_V:
|
||||
return 4;
|
||||
}
|
||||
}
|
||||
|
||||
return 0xFF;
|
||||
}
|
||||
|
||||
void gbaWriteFlash(u32 adr, u8 val)
|
||||
{
|
||||
if (!fSRAM) return;
|
||||
switch (gbaFlash.state)
|
||||
{
|
||||
case 0:
|
||||
if (adr == 0x0A005555)
|
||||
{
|
||||
if (val == 0xF0)
|
||||
{
|
||||
//INFO("GBAgame: Flash: reset\n");
|
||||
gbaFlash.state = 0;
|
||||
gbaFlash.cmd = 0;
|
||||
return;
|
||||
}
|
||||
if (val == 0xAA)
|
||||
{
|
||||
gbaFlash.state = 1;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (adr == 0x0A000000)
|
||||
{
|
||||
if (gbaFlash.cmd == 0xB0)
|
||||
{
|
||||
gbaFlash.bank = val;
|
||||
gbaFlash.cmd = 0;
|
||||
//INFO("GBAgame: Flash: change bank %i\n", val);
|
||||
return;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
if ( (adr == 0x0A002AAA) && (val == 0x55) )
|
||||
{
|
||||
gbaFlash.state = 2;
|
||||
return;
|
||||
}
|
||||
gbaFlash.state = 0;
|
||||
break;
|
||||
case 2:
|
||||
if (adr == 0x0A005555)
|
||||
{
|
||||
//INFO("GBAgame: Flash: send command flash 0x%02X\n", val);
|
||||
switch (val)
|
||||
{
|
||||
case 0x80: // Erase
|
||||
gbaFlash.state = 0x80;
|
||||
break;
|
||||
|
||||
case 0x90: // Chip Identification
|
||||
gbaFlash.state = 0x90;
|
||||
break;
|
||||
|
||||
case 0xA0: // Write
|
||||
gbaFlash.state = 0;
|
||||
break;
|
||||
|
||||
default:
|
||||
gbaFlash.state = 0;
|
||||
break;
|
||||
}
|
||||
gbaFlash.cmd = val;
|
||||
return;
|
||||
}
|
||||
gbaFlash.state = 0;
|
||||
break;
|
||||
|
||||
// erase
|
||||
case 0x80:
|
||||
if ( (adr == 0x0A005555) && (val == 0xAA) )
|
||||
{
|
||||
gbaFlash.state = 0x81;
|
||||
return;
|
||||
}
|
||||
gbaFlash.state = 0;
|
||||
break;
|
||||
|
||||
case 0x81:
|
||||
if ( (adr == 0x0A002AAA) && (val == 0x55) )
|
||||
{
|
||||
gbaFlash.state = 0x82;
|
||||
return;
|
||||
}
|
||||
gbaFlash.state = 0;
|
||||
break;
|
||||
|
||||
case 0x82:
|
||||
if (val == 0x30)
|
||||
{
|
||||
u32 ofs = (adr & 0x0000F000) + (0x10000 * gbaFlash.bank);
|
||||
//INFO("GBAgame: Flash: erase from 0x%08X to 0x%08X\n", ofs + 0x0A000000, ofs + 0x0A001000);
|
||||
u8 *tmp = new u8[0x1000];
|
||||
memset(tmp, 0xFF, 0x1000);
|
||||
writeSRAM(ofs, tmp, 0x1000);
|
||||
delete [] tmp;
|
||||
}
|
||||
gbaFlash.state = 0;
|
||||
gbaFlash.cmd = 0;
|
||||
return;
|
||||
|
||||
// Chip Identification
|
||||
case 0x90:
|
||||
if ( (adr == 0x0A005555) && (val == 0xAA) )
|
||||
{
|
||||
gbaFlash.state = 0x91;
|
||||
return;
|
||||
}
|
||||
gbaFlash.state = 0;
|
||||
break;
|
||||
|
||||
case 0x91:
|
||||
if ( (adr == 0x0A002AAA) && (val == 0x55) )
|
||||
{
|
||||
gbaFlash.state = 0x92;
|
||||
return;
|
||||
}
|
||||
gbaFlash.state = 0;
|
||||
break;
|
||||
|
||||
case 0x92:
|
||||
gbaFlash.state = 0;
|
||||
gbaFlash.cmd = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
if (gbaFlash.cmd == 0xA0) // write
|
||||
{
|
||||
writeSRAM((adr & 0x1FFFF) + (0x10000 * gbaFlash.bank), &val, 1);
|
||||
gbaFlash.state = 0;
|
||||
gbaFlash.cmd = 0;
|
||||
return;
|
||||
}
|
||||
INFO("GBAgame: Flash: write unknown atn 0x%08X = 0x%02X\n", adr, val);
|
||||
}
|
||||
|
||||
u8 gbaReadFlash(u32 adr)
|
||||
{
|
||||
if (!fSRAM) return 0xFF;
|
||||
if (gbaFlash.cmd == 0)
|
||||
return readSRAM((adr & 0x1FFFF) + (0x10000 * gbaFlash.bank), 1);
|
||||
|
||||
//INFO("GBAgame: flash read at 0x%08X\n", adr);
|
||||
|
||||
switch (gbaFlash.cmd)
|
||||
{
|
||||
case 0x90: // Chip Identification
|
||||
if (adr == 0x0A000000) return gbaFlash.idManufacturer;
|
||||
if (adr == 0x0A000001) return gbaFlash.idDevice;
|
||||
break;
|
||||
|
||||
case 0xF0: //
|
||||
gbaFlash.state = 0;
|
||||
gbaFlash.cmd = 0;
|
||||
break;
|
||||
|
||||
case 0xB0: // Bank switching
|
||||
break;
|
||||
|
||||
default:
|
||||
INFO("GBAgame: Flash: read - unknown command at 0x%08X = 0x%02X\n", adr, gbaFlash.cmd);
|
||||
break;
|
||||
}
|
||||
|
||||
return 0xFF;
|
||||
}
|
||||
|
||||
void Close()
|
||||
{
|
||||
delete fROM; fROM = NULL;
|
||||
delete fSRAM; fSRAM = NULL;
|
||||
romSize = 0;
|
||||
sramSize = 0;
|
||||
}
|
||||
|
||||
public:
|
||||
Slot2_GbaCart()
|
||||
: fROM(NULL)
|
||||
, fSRAM(NULL)
|
||||
{
|
||||
Close();
|
||||
}
|
||||
|
||||
virtual Slot2Info const* info()
|
||||
{
|
||||
static Slot2InfoSimple info("GBA Cartridge", "GBA cartridge in slot", 0x03);
|
||||
return &info;
|
||||
}
|
||||
|
||||
virtual void connect()
|
||||
{
|
||||
Close();
|
||||
romSize = 0;
|
||||
sramSize = 0;
|
||||
|
||||
if (gameInfo.romsize == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (GBACartridge_RomPath.empty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!strcasecmp(GBACartridge_RomPath.c_str(), "self"))
|
||||
{
|
||||
GBACartridge_RomPath = path.path;
|
||||
GBACartridge_SRAMPath = Path::GetFileNameWithoutExt(GBACartridge_RomPath) + "." + GBA_SRAM_FILE_EXT;
|
||||
}
|
||||
|
||||
printf("GBASlot opening ROM: %s\n", GBACartridge_RomPath.c_str());
|
||||
EMUFILE_FILE *inf = new EMUFILE_FILE(GBACartridge_RomPath, "rb");
|
||||
inf->EnablePositionCache();
|
||||
fROM = inf;
|
||||
if (fROM->fail())
|
||||
{
|
||||
printf(" - Failed\n");
|
||||
Close();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
romSize = fROM->size();
|
||||
printf(" - Success (%u bytes)\n", romSize);
|
||||
|
||||
// Load the GBA cartridge SRAM.
|
||||
inf = new EMUFILE_FILE(GBACartridge_SRAMPath, "rb+");
|
||||
fSRAM = inf;
|
||||
if(fSRAM->fail())
|
||||
{
|
||||
delete fSRAM;
|
||||
fSRAM = NULL;
|
||||
printf("GBASlot did not load associated SRAM.\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
inf->EnablePositionCache();
|
||||
sramSize = fSRAM->size();
|
||||
printf("Scanning GBA rom to ID save type\n");
|
||||
saveType = scanSaveTypeGBA();
|
||||
printf("\nGBASlot found SRAM (%s - %u bytes) at:\n%s\n", (saveType == 0xFF)?"Unknown":saveTypes[saveType], sramSize, GBACartridge_SRAMPath.c_str());
|
||||
gbaFlash.size = sramSize;
|
||||
if (gbaFlash.size <= (64 * 1024))
|
||||
{
|
||||
gbaFlash.idDevice = 0x1B;
|
||||
gbaFlash.idManufacturer = 0x32;
|
||||
}
|
||||
else
|
||||
{
|
||||
gbaFlash.idDevice = 0x09;
|
||||
gbaFlash.idManufacturer = 0xC2;
|
||||
}
|
||||
gbaFlash.state = 0;
|
||||
}
|
||||
}
|
||||
|
||||
virtual void disconnect()
|
||||
{
|
||||
Close();
|
||||
}
|
||||
|
||||
virtual void writeByte(u8 PROCNUM, u32 addr, u8 val)
|
||||
{
|
||||
if ((addr >= 0x0A000000) && (addr < 0x0A010000))
|
||||
{
|
||||
switch (saveType)
|
||||
{
|
||||
case 3: // Flash
|
||||
case 5:
|
||||
gbaWriteFlash(addr, val);
|
||||
break;
|
||||
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
virtual u8 readByte(u8 PROCNUM, u32 addr)
|
||||
{
|
||||
if (addr < 0x0A000000)
|
||||
return (u8)readRom(addr - 0x08000000, 1);
|
||||
|
||||
if (addr < 0x0A010000)
|
||||
{
|
||||
if ((saveType == 3) || (saveType == 5))
|
||||
return gbaReadFlash(addr);
|
||||
|
||||
return (u8)readSRAM(addr - 0x0A000000, 1);
|
||||
}
|
||||
|
||||
return 0xFF;
|
||||
}
|
||||
virtual u16 readWord(u8 PROCNUM, u32 addr)
|
||||
{
|
||||
if (addr < 0x0A000000)
|
||||
return (u16)readRom(addr - 0x08000000, 2);
|
||||
|
||||
if (addr < 0x0A010000)
|
||||
return (u16)readSRAM(addr - 0x0A000000, 2);
|
||||
|
||||
return 0xFFFF;
|
||||
}
|
||||
virtual u32 readLong(u8 PROCNUM, u32 addr)
|
||||
{
|
||||
if (addr < 0x0A000000)
|
||||
return (u32)readRom(addr - 0x08000000, 4);
|
||||
|
||||
if (addr < 0x0A010000)
|
||||
return (u32)readSRAM(addr - 0x0A000000, 4);
|
||||
|
||||
return 0xFFFFFFFF;
|
||||
}
|
||||
};
|
||||
|
||||
ISlot2Interface* construct_Slot2_GbaCart() { return new Slot2_GbaCart(); }
|
||||
Executable
+52
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
Copyright (C) 2009 CrazyMax
|
||||
Copyright (C) 2009-2013 DeSmuME team
|
||||
|
||||
This file is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This file is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with the this software. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "../slot2.h"
|
||||
static u8 guitarKeyStatus;
|
||||
|
||||
class Slot2_GuitarGrip : public ISlot2Interface
|
||||
{
|
||||
private:
|
||||
|
||||
public:
|
||||
virtual Slot2Info const* info()
|
||||
{
|
||||
static Slot2InfoSimple info("Guitar Grip", "Guitar Grip for Guitar Hero games", 0x04);
|
||||
return &info;
|
||||
}
|
||||
|
||||
virtual void connect()
|
||||
{
|
||||
guitarKeyStatus = 0;
|
||||
}
|
||||
|
||||
virtual u8 readByte(u8 PROCNUM, u32 addr)
|
||||
{
|
||||
if (addr == 0x0A000000) return (~guitarKeyStatus);
|
||||
return (addr & 1)?0xF9:0xFF;
|
||||
}
|
||||
virtual u16 readWord(u8 PROCNUM, u32 addr) { return 0xF9FF; }
|
||||
virtual u32 readLong(u8 PROCNUM, u32 addr) { return 0xF9FFF9FF; }
|
||||
};
|
||||
|
||||
ISlot2Interface* construct_Slot2_GuitarGrip() { return new Slot2_GuitarGrip(); }
|
||||
|
||||
void guitarGrip_setKey(bool green, bool red, bool yellow, bool blue)
|
||||
{
|
||||
guitarKeyStatus = 0 | (green << 6) | (red << 5) | (yellow << 4) | (blue << 3);
|
||||
}
|
||||
Executable
+301
@@ -0,0 +1,301 @@
|
||||
/*
|
||||
Copyright (C) 2006 yopyop
|
||||
Copyright (C) 2006 Mic
|
||||
Copyright (C) 2009-2015 DeSmuME team
|
||||
|
||||
This file is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This file is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with the this software. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <string>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "../slot2.h"
|
||||
#include "../debug.h"
|
||||
#include "../emufile.h"
|
||||
#include "../path.h"
|
||||
#include "../utils/vfat.h"
|
||||
|
||||
// Set up addresses for GBAMP
|
||||
#define CF_REG_DATA 0x9000000
|
||||
#define CF_REG_ERR 0x9020000
|
||||
#define CF_REG_SEC 0x9040000
|
||||
#define CF_REG_LBA1 0x9060000
|
||||
#define CF_REG_LBA2 0x9080000
|
||||
#define CF_REG_LBA3 0x90A0000
|
||||
#define CF_REG_LBA4 0x90C0000
|
||||
#define CF_REG_CMD 0x90E0000
|
||||
#define CF_REG_STS 0x98C0000
|
||||
|
||||
// CF Card commands
|
||||
#define CF_CMD_LBA 0xE0
|
||||
#define CF_CMD_READ 0x20
|
||||
#define CF_CMD_WRITE 0x30
|
||||
|
||||
static u16 cf_reg_sts,
|
||||
cf_reg_lba1,
|
||||
cf_reg_lba2,
|
||||
cf_reg_lba3,
|
||||
cf_reg_lba4,
|
||||
cf_reg_cmd;
|
||||
static off_t currLBA;
|
||||
|
||||
static const int lfnPos[13] = {1,3,5,7,9,14,16,18,20,22,24,28,30};
|
||||
|
||||
static u32 fileStartLBA,fileEndLBA;
|
||||
static std::string sFlashPath;
|
||||
static BOOL cflashDeviceEnabled = FALSE;
|
||||
|
||||
static EMUFILE* file = NULL;
|
||||
|
||||
// ===========================
|
||||
BOOL inited;
|
||||
|
||||
enum EListCallbackArg {
|
||||
EListCallbackArg_Item, EListCallbackArg_Pop
|
||||
};
|
||||
|
||||
static BOOL cflash_init()
|
||||
{
|
||||
if (inited) return FALSE;
|
||||
BOOL init_good = FALSE;
|
||||
|
||||
CFLASHLOG("CFlash_Mode: %d\n",CFlash_Mode);
|
||||
|
||||
if (CFlash_Mode == ADDON_CFLASH_MODE_RomPath)
|
||||
{
|
||||
sFlashPath = path.RomDirectory;
|
||||
INFO("Using CFlash directory of rom: %s\n", sFlashPath.c_str());
|
||||
}
|
||||
else if(CFlash_Mode == ADDON_CFLASH_MODE_Path)
|
||||
{
|
||||
sFlashPath = CFlash_Path;
|
||||
INFO("Using CFlash directory: %s\n", sFlashPath.c_str());
|
||||
}
|
||||
else if(CFlash_Mode == ADDON_CFLASH_MODE_File)
|
||||
{
|
||||
sFlashPath = CFlash_Path;
|
||||
INFO("Using CFlash disk image file %s\n", sFlashPath.c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (sFlashPath == "") return FALSE;
|
||||
|
||||
if(CFlash_IsUsingPath())
|
||||
{
|
||||
cflashDeviceEnabled = FALSE;
|
||||
currLBA = 0;
|
||||
|
||||
fileStartLBA = fileEndLBA = 0xFFFFFFFF;
|
||||
VFAT vfat;
|
||||
bool ret = vfat.build(sFlashPath.c_str(),16); //allocate 16MB extra for writing. this is probably enough for anyone, but maybe it should be configurable.
|
||||
//we could always suggest to users to add a big file to their directory to overwrite (that would cause the image to get padded)
|
||||
|
||||
if(!ret)
|
||||
{
|
||||
CFLASHLOG("FAILED cflash_build_fat\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
file = vfat.detach();
|
||||
|
||||
cf_reg_sts = 0x58; // READY
|
||||
|
||||
cflashDeviceEnabled = TRUE;
|
||||
init_good = TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
file = new EMUFILE_FILE(sFlashPath.c_str(),"rb+");
|
||||
if(file->fail())
|
||||
{
|
||||
INFO("Failed to open file %s\n", sFlashPath.c_str());
|
||||
delete file;
|
||||
file = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
// READY
|
||||
cf_reg_sts = 0x58;
|
||||
|
||||
currLBA = 0;
|
||||
cf_reg_lba1 = cf_reg_lba2 =
|
||||
cf_reg_lba3 = cf_reg_lba4 = 0;
|
||||
|
||||
inited = TRUE;
|
||||
return init_good;
|
||||
}
|
||||
|
||||
static unsigned int cflash_read(unsigned int address)
|
||||
{
|
||||
unsigned int ret_value = 0;
|
||||
size_t elems_read = 0;
|
||||
|
||||
switch (address)
|
||||
{
|
||||
case CF_REG_STS:
|
||||
ret_value = cf_reg_sts;
|
||||
break;
|
||||
|
||||
case CF_REG_DATA:
|
||||
if (cf_reg_cmd == CF_CMD_READ)
|
||||
{
|
||||
if(file)
|
||||
{
|
||||
u8 data[2];
|
||||
file->fseek(currLBA, SEEK_SET);
|
||||
elems_read += file->fread(data,2);
|
||||
ret_value = data[1] << 8 | data[0];
|
||||
}
|
||||
currLBA += 2;
|
||||
}
|
||||
break;
|
||||
|
||||
case CF_REG_CMD:
|
||||
break;
|
||||
|
||||
case CF_REG_LBA1:
|
||||
ret_value = cf_reg_lba1;
|
||||
break;
|
||||
}
|
||||
|
||||
return ret_value;
|
||||
}
|
||||
|
||||
static void cflash_write(unsigned int address,unsigned int data)
|
||||
{
|
||||
static u8 sector_data[512];
|
||||
static u32 sector_write_index = 0;
|
||||
|
||||
switch (address)
|
||||
{
|
||||
case CF_REG_STS:
|
||||
cf_reg_sts = data&0xFFFF;
|
||||
break;
|
||||
|
||||
case CF_REG_DATA:
|
||||
if (cf_reg_cmd == CF_CMD_WRITE)
|
||||
{
|
||||
{
|
||||
sector_data[sector_write_index] = (data >> 0) & 0xff;
|
||||
sector_data[sector_write_index + 1] = (data >> 8) & 0xff;
|
||||
|
||||
sector_write_index += 2;
|
||||
|
||||
if (sector_write_index == 512)
|
||||
{
|
||||
CFLASHLOG( "Write sector to %ld\n", currLBA);
|
||||
size_t written = 0;
|
||||
|
||||
if(file)
|
||||
if(currLBA + 512 < file->size())
|
||||
{
|
||||
file->fseek(currLBA,SEEK_SET);
|
||||
|
||||
while(written < 512)
|
||||
{
|
||||
size_t todo = 512-written;
|
||||
file->fwrite(§or_data[written], todo);
|
||||
size_t cur_write = todo;
|
||||
written += cur_write;
|
||||
if ( cur_write == (size_t)-1) break;
|
||||
}
|
||||
}
|
||||
|
||||
CFLASHLOG("Wrote %u bytes\n", written);
|
||||
|
||||
currLBA += 512;
|
||||
sector_write_index = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case CF_REG_CMD:
|
||||
cf_reg_cmd = data&0xFF;
|
||||
cf_reg_sts = 0x58; // READY
|
||||
break;
|
||||
|
||||
case CF_REG_LBA1:
|
||||
cf_reg_lba1 = data&0xFF;
|
||||
currLBA = (currLBA&0xFFFFFF00)| cf_reg_lba1;
|
||||
break;
|
||||
|
||||
case CF_REG_LBA2:
|
||||
cf_reg_lba2 = data&0xFF;
|
||||
currLBA = (currLBA&0xFFFF00FF)|(cf_reg_lba2<<8);
|
||||
break;
|
||||
|
||||
case CF_REG_LBA3:
|
||||
cf_reg_lba3 = data&0xFF;
|
||||
currLBA = (currLBA&0xFF00FFFF)|(cf_reg_lba3<<16);
|
||||
break;
|
||||
|
||||
case CF_REG_LBA4:
|
||||
cf_reg_lba4 = data&0xFF;
|
||||
|
||||
if ((cf_reg_lba4 & 0xf0) == CF_CMD_LBA)
|
||||
{
|
||||
currLBA = (currLBA&0x00FFFFFF)|((cf_reg_lba4&0x0F)<<24);
|
||||
currLBA *= 512;
|
||||
sector_write_index = 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void cflash_close( void)
|
||||
{
|
||||
if (!inited) return;
|
||||
if(file) delete file;
|
||||
cflashDeviceEnabled = FALSE;
|
||||
file = NULL;
|
||||
inited = FALSE;
|
||||
}
|
||||
|
||||
class Slot2_CFlash : public ISlot2Interface
|
||||
{
|
||||
public:
|
||||
virtual Slot2Info const* info()
|
||||
{
|
||||
static Slot2InfoSimple info("MPCF Flash Card Device", "MPCF Flash Card Device", 0x01);
|
||||
return &info;
|
||||
}
|
||||
|
||||
virtual void connect()
|
||||
{
|
||||
cflash_close();
|
||||
cflash_init();
|
||||
}
|
||||
virtual void disconnect()
|
||||
{
|
||||
cflash_close();
|
||||
}
|
||||
|
||||
virtual void writeByte(u8 PROCNUM, u32 addr, u8 val) { cflash_write(addr, val); }
|
||||
virtual void writeWord(u8 PROCNUM, u32 addr, u16 val) { cflash_write(addr, val); }
|
||||
virtual void writeLong(u8 PROCNUM, u32 addr, u32 val) { cflash_write(addr, val); }
|
||||
|
||||
virtual u8 readByte(u8 PROCNUM, u32 addr) { return (cflash_read(addr)); }
|
||||
virtual u16 readWord(u8 PROCNUM, u32 addr) { return (cflash_read(addr)); }
|
||||
virtual u32 readLong(u8 PROCNUM, u32 addr) { return (cflash_read(addr)); }
|
||||
|
||||
};
|
||||
|
||||
ISlot2Interface* construct_Slot2_CFlash() { return new Slot2_CFlash(); }
|
||||
Executable
+31
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
Copyright (C) 2009 CrazyMax
|
||||
Copyright (C) 2009-2013 DeSmuME team
|
||||
|
||||
This file is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This file is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with the this software. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "../slot2.h"
|
||||
|
||||
class Slot2_None : public ISlot2Interface
|
||||
{
|
||||
public:
|
||||
virtual Slot2Info const* info()
|
||||
{
|
||||
static Slot2InfoSimple info("None", "Slot2 no-device emulation", 0xFF);
|
||||
return &info;
|
||||
}
|
||||
};
|
||||
|
||||
ISlot2Interface* construct_Slot2_None() { return new Slot2_None(); }
|
||||
Executable
+143
@@ -0,0 +1,143 @@
|
||||
/*
|
||||
Copyright (C) 2011-2015 DeSmuME team
|
||||
|
||||
This file is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This file is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with the this software. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/*
|
||||
this device seems to have a 12bit value (like 20.12 fixed point.. get it?) located at 0x0A000000
|
||||
clockwise = right = increases.
|
||||
it returns the correct little endian bytes through byte reads.
|
||||
through halfword reads, it returns the LSB twice
|
||||
through full word reads, it returns the LSB four times.
|
||||
after that everything is 0x00.
|
||||
if the slot2 timings are wrong, then this device will return glitchy or 0xFF output.
|
||||
so this emulation code will attempt to validate that.
|
||||
arkanoid was setting REG_EXMEMCNT = 0x082F
|
||||
|
||||
the rom returns 0xEFFF for all addresses and should be used to detect this device
|
||||
|
||||
writing any byte to SRAM or writing any halfword/word to rom results in a reset or some kind of recalibrate
|
||||
the resulting value may be 0x000,0x001, or 0xFFF. seems mostly random, though once it is reset, resetting again won't change it.
|
||||
you must wait until the paddle has been moved.
|
||||
|
||||
conclusion:
|
||||
The emulation in all the handling of erroneous cases is not perfect, and some other users of the paddle (do any other games use it?)
|
||||
maybe legally configure the paddle differently, which could be rejected here; in which case this code will need finetuning
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "../slot2.h"
|
||||
#include "../NDSSystem.h"
|
||||
|
||||
class Slot2_Paddle : public ISlot2Interface
|
||||
{
|
||||
private:
|
||||
void calibrate() { nds.paddle = 0; }
|
||||
bool Validate(u32 procnum, bool rom)
|
||||
{
|
||||
if(rom)
|
||||
return ValidateSlot2Access(procnum, 0, 0, 0, -1);
|
||||
else
|
||||
return ValidateSlot2Access(procnum, 18, 0, 0, 1);
|
||||
}
|
||||
|
||||
public:
|
||||
virtual Slot2Info const* info()
|
||||
{
|
||||
static Slot2InfoSimple info("Paddle Controller", "Taito Paddle Controller", 0x07);
|
||||
return &info;
|
||||
}
|
||||
|
||||
virtual void writeByte(u8 PROCNUM, u32 addr, u8 val)
|
||||
{
|
||||
if (addr < 0x0A000000)
|
||||
calibrate();
|
||||
}
|
||||
virtual void writeWord(u8 PROCNUM, u32 addr, u16 val)
|
||||
{
|
||||
if (addr < 0x0A000000)
|
||||
calibrate();
|
||||
}
|
||||
virtual void writeLong(u8 PROCNUM, u32 addr, u32 val)
|
||||
{
|
||||
if (addr < 0x0A000000)
|
||||
calibrate();
|
||||
}
|
||||
|
||||
virtual u8 readByte(u8 PROCNUM, u32 addr)
|
||||
{
|
||||
//printf("paddle: read 08 at 0x%08X\n", addr);
|
||||
if (!Validate(PROCNUM, (addr < 0x0A000000)))
|
||||
return 0xFF;
|
||||
|
||||
if (addr < 0x0A000000)
|
||||
return (addr & 1)?0xFF:0xEF;
|
||||
|
||||
if (addr == 0x0A000000)
|
||||
return (nds.paddle & 0xFF);
|
||||
|
||||
if (addr == 0x0A000001)
|
||||
return ((nds.paddle >> 8) & 0x0F);
|
||||
|
||||
return 0x00;
|
||||
}
|
||||
virtual u16 readWord(u8 PROCNUM, u32 addr)
|
||||
{
|
||||
//printf("paddle: read 16 at 0x%08X\n", addr);
|
||||
if (!Validate(PROCNUM, (addr < 0x0A000000)))
|
||||
return 0xFFFF;
|
||||
|
||||
if (addr < 0x0A000000)
|
||||
return 0xEFFF;
|
||||
|
||||
if (addr == 0x0A000000)
|
||||
{
|
||||
u8 val = (nds.paddle & 0xFF);
|
||||
return (val | (val << 8));
|
||||
}
|
||||
|
||||
return 0x0000;
|
||||
}
|
||||
virtual u32 readLong(u8 PROCNUM, u32 addr)
|
||||
{
|
||||
//printf("paddle: read 32 at 0x%08X\n", addr);
|
||||
if (!Validate(PROCNUM, (addr < 0x0A000000)))
|
||||
return 0xFFFFFFFF;
|
||||
|
||||
if (addr < 0x0A000000)
|
||||
return 0xEFFFEFFF;
|
||||
|
||||
if (addr == 0x0A000000)
|
||||
{
|
||||
u8 val = (nds.paddle & 0xFF);
|
||||
return (val | (val << 8) | (val << 16) | (val << 24));
|
||||
}
|
||||
|
||||
return 0x00000000;
|
||||
}
|
||||
};
|
||||
|
||||
u16 Paddle_GetValue()
|
||||
{
|
||||
return nds.paddle;
|
||||
}
|
||||
|
||||
void Paddle_SetValue(u16 theValue)
|
||||
{
|
||||
nds.paddle = theValue;
|
||||
}
|
||||
|
||||
ISlot2Interface* construct_Slot2_Paddle() { return new Slot2_Paddle(); }
|
||||
Executable
+56
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
Copyright (C) 2013-2015 DeSmuME team
|
||||
|
||||
This file is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This file is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with the this software. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "../slot2.h"
|
||||
#include "../NDSSystem.h"
|
||||
|
||||
class Slot2_PassME : public ISlot2Interface
|
||||
{
|
||||
public:
|
||||
virtual Slot2Info const* info()
|
||||
{
|
||||
static Slot2InfoSimple info("PassME", "PassME in GBA slot", 0x08);
|
||||
return &info;
|
||||
}
|
||||
|
||||
virtual u8 readByte(u8 PROCNUM, u32 addr)
|
||||
{
|
||||
u32 tmp_addr = (addr & 0x07FFFFFF);
|
||||
if (tmp_addr < gameInfo.romsize)
|
||||
return (u8)gameInfo.readROM(tmp_addr);
|
||||
|
||||
return (0xFF);
|
||||
}
|
||||
virtual u16 readWord(u8 PROCNUM, u32 addr)
|
||||
{
|
||||
u32 tmp_addr = (addr & 0x07FFFFFF);
|
||||
if (tmp_addr < gameInfo.romsize)
|
||||
return (u16)gameInfo.readROM(tmp_addr);
|
||||
|
||||
return (0xFFFF);
|
||||
}
|
||||
virtual u32 readLong(u8 PROCNUM, u32 addr)
|
||||
{
|
||||
u32 tmp_addr = (addr & 0x07FFFFFF);
|
||||
if (tmp_addr < gameInfo.romsize)
|
||||
return (u32)gameInfo.readROM(tmp_addr);
|
||||
|
||||
return (0xFFFFFFFF);
|
||||
}
|
||||
};
|
||||
|
||||
ISlot2Interface* construct_Slot2_PassME() { return new Slot2_PassME(); }
|
||||
Executable
+117
@@ -0,0 +1,117 @@
|
||||
/*
|
||||
Copyright (C) 2010-2013 DeSmuME team
|
||||
|
||||
This file is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This file is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with the this software. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "../slot2.h"
|
||||
|
||||
static u16 pianoKeyStatus = 0;
|
||||
|
||||
class Slot2_EasyPiano : public ISlot2Interface
|
||||
{
|
||||
public:
|
||||
virtual Slot2Info const* info()
|
||||
{
|
||||
static Slot2InfoSimple info("Piano", "Piano for EasyPiano", 0x06);
|
||||
return &info;
|
||||
}
|
||||
|
||||
virtual void connect()
|
||||
{
|
||||
pianoKeyStatus = 0;
|
||||
}
|
||||
|
||||
virtual u8 readByte(u8 PROCNUM, u32 addr)
|
||||
{
|
||||
//printf("piano: read 08 at 0x%08X\n", adr);
|
||||
|
||||
//the actual keyboard output
|
||||
|
||||
//byte:bit
|
||||
//0x09FFFFFE:0 = C
|
||||
//0x09FFFFFE:1 = C#
|
||||
//0x09FFFFFE:2 = D
|
||||
//0x09FFFFFE:3 = D#
|
||||
//0x09FFFFFE:4 = E
|
||||
//0x09FFFFFE:5 = F
|
||||
//0x09FFFFFE:6 = F#
|
||||
//0x09FFFFFE:7 = G
|
||||
//0x09FFFFFF:0 = G#
|
||||
//0x09FFFFFF:1 = A
|
||||
//0x09FFFFFF:2 = A#
|
||||
//0x09FFFFFF:3 = ?
|
||||
//0x09FFFFFF:4 = ?
|
||||
//0x09FFFFFF:5 = B
|
||||
//0x09FFFFFF:6 = hiC
|
||||
//0x09FFFFFF:7 = ?
|
||||
|
||||
//deassert bit if key is pressed
|
||||
|
||||
//LOG("PIANO: %04X\n",pianoKeyStatus);
|
||||
|
||||
if(addr == 0x09FFFFFE) return (~(pianoKeyStatus&0xFF));
|
||||
if(addr == 0x09FFFFFF) return (~((pianoKeyStatus>>8)&0xFF))&~(0x18);
|
||||
|
||||
return (addr & 1)?0xE7:0xFF;
|
||||
}
|
||||
virtual u16 readWord(u8 PROCNUM, u32 addr)
|
||||
{
|
||||
if (addr != 0x09FFFFFE)
|
||||
return 0xE7FF;
|
||||
|
||||
return readByte(PROCNUM, 0x09FFFFFE) | (readByte(PROCNUM,0x09FFFFFF) << 8);
|
||||
}
|
||||
virtual u32 readLong(u8 PROCNUM, u32 addr) { return 0xE7FFE7FF; }
|
||||
|
||||
};
|
||||
|
||||
ISlot2Interface* construct_Slot2_EasyPiano() { return new Slot2_EasyPiano(); }
|
||||
|
||||
void piano_setKey(bool c, bool cs, bool d, bool ds, bool e, bool f, bool fs, bool g, bool gs, bool a, bool as, bool b, bool hic)
|
||||
{
|
||||
//0x09FFFFFE:0 = C
|
||||
//0x09FFFFFE:1 = C#
|
||||
//0x09FFFFFE:2 = D
|
||||
//0x09FFFFFE:3 = D#
|
||||
//0x09FFFFFE:4 = E
|
||||
//0x09FFFFFE:5 = F
|
||||
//0x09FFFFFE:6 = F#
|
||||
//0x09FFFFFE:7 = G
|
||||
//0x09FFFFFE:0 = G#
|
||||
//0x09FFFFFE:1 = A
|
||||
//0x09FFFFFF:2 = A#
|
||||
//0x09FFFFFF:3 = ?
|
||||
//0x09FFFFFF:4 = ?
|
||||
//0x09FFFFFF:5 = B
|
||||
//0x09FFFFFF:6 = hiC
|
||||
//0x09FFFFFF:7 = ?
|
||||
|
||||
#define BIT_P(N,v) ((v)?(1<<(N)):0)
|
||||
pianoKeyStatus =
|
||||
BIT_P(0,c) |
|
||||
BIT_P(1,cs) |
|
||||
BIT_P(2,d) |
|
||||
BIT_P(3,ds) |
|
||||
BIT_P(4,e) |
|
||||
BIT_P(5,f) |
|
||||
BIT_P(6,fs) |
|
||||
BIT_P(7,g) |
|
||||
BIT_P(8,gs) |
|
||||
BIT_P(9,a) |
|
||||
BIT_P(10,as) |
|
||||
BIT_P(13,b) |
|
||||
BIT_P(14,hic)
|
||||
;
|
||||
}
|
||||
Executable
+62
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
Copyright (C) 2009 CrazyMax
|
||||
Copyright (C) 2009-2013 DeSmuME team
|
||||
|
||||
This file is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This file is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with the this software. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "../slot2.h"
|
||||
|
||||
void (*FeedbackON)(bool enable) = NULL;
|
||||
|
||||
class Slot2_RumblePak : public ISlot2Interface
|
||||
{
|
||||
private:
|
||||
u16 old_val_rumble;
|
||||
|
||||
public:
|
||||
virtual Slot2Info const* info()
|
||||
{
|
||||
static Slot2InfoSimple info("Rumble Pak", "NDS Rumble Pak (need joystick with Feedback)", 0x02);
|
||||
return &info;
|
||||
}
|
||||
|
||||
virtual void connect()
|
||||
{
|
||||
old_val_rumble = 0;
|
||||
if (!FeedbackON) return;
|
||||
FeedbackON(false);
|
||||
}
|
||||
|
||||
virtual void disconnect()
|
||||
{
|
||||
FeedbackON(false);
|
||||
}
|
||||
|
||||
virtual void writeWord(u8 PROCNUM, u32 addr, u16 val)
|
||||
{
|
||||
if (!FeedbackON) return;
|
||||
if (old_val_rumble == val) return;
|
||||
|
||||
old_val_rumble = val;
|
||||
if ((addr == 0x08000000) || (addr == 0x08001000))
|
||||
FeedbackON(val);
|
||||
}
|
||||
|
||||
virtual u8 readByte(u8 PROCNUM, u32 addr) { return (addr & 1)?0xFF:0xFD; };
|
||||
virtual u16 readWord(u8 PROCNUM, u32 addr) { return 0xFFFD; };
|
||||
virtual u32 readLong(u8 PROCNUM, u32 addr) { return 0xFFFDFFFD; };
|
||||
};
|
||||
|
||||
ISlot2Interface* construct_Slot2_RumblePak() { return new Slot2_RumblePak(); }
|
||||
Executable
+932
@@ -0,0 +1,932 @@
|
||||
//----------------------------------------------------------------------------
|
||||
// Agg2D - Version 1.0
|
||||
// Based on Anti-Grain Geometry
|
||||
// Copyright (C) 2005 Maxim Shemanarev (http://www.antigrain.com)
|
||||
//
|
||||
// Permission to copy, use, modify, sell and distribute this software
|
||||
// is granted provided this copyright notice appears in all copies.
|
||||
// This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
// Contact: mcseem@antigrain.com
|
||||
// mcseemagg@yahoo.com
|
||||
// http://www.antigrain.com
|
||||
//----------------------------------------------------------------------------
|
||||
//----------------------------------------------------------------------------
|
||||
//
|
||||
// 25 Jan 2007 - Ported to AGG 2.4 Jerry Evans (jerry@novadsp.com)
|
||||
// 11 Jul 2009 - significant refactors for introduction to desmume
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
#ifndef AGG2D_INCLUDED
|
||||
#define AGG2D_INCLUDED
|
||||
|
||||
//we're not using vector fonts right now.
|
||||
//#define AGG2D_USE_VECTORFONTS
|
||||
|
||||
#ifdef AGG2D_USE_VECTORFONTS
|
||||
#if defined(UNDER_CE) || not defined(WIN32)
|
||||
#define AGG2D_USE_FREETYPE
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(disable: 4786)
|
||||
#endif
|
||||
|
||||
// JME
|
||||
#include "agg_basics.h"
|
||||
#include "agg_math_stroke.h"
|
||||
#include "agg_trans_affine.h"
|
||||
#include "agg_trans_viewport.h"
|
||||
#include "agg_path_storage.h"
|
||||
#include "agg_conv_stroke.h"
|
||||
#include "agg_conv_transform.h"
|
||||
#include "agg_conv_curve.h"
|
||||
#include "agg_rendering_buffer.h"
|
||||
#include "agg_renderer_base.h"
|
||||
#include "agg_renderer_scanline.h"
|
||||
#include "agg_span_gradient.h"
|
||||
#include "agg_span_image_filter_rgba.h"
|
||||
|
||||
//+ JME
|
||||
#include "agg_span_allocator.h"
|
||||
#include "agg_span_converter.h"
|
||||
#include "agg_span_interpolator_linear.h"
|
||||
#include "agg_rasterizer_scanline_aa.h"
|
||||
#include "agg_gamma_functions.h"
|
||||
#include "agg_scanline_u.h"
|
||||
#include "agg_bezier_arc.h"
|
||||
#include "agg_rounded_rect.h"
|
||||
#include "agg_font_cache_manager.h"
|
||||
|
||||
#include "agg_glyph_raster_bin.h"
|
||||
#include "agg_renderer_raster_text.h"
|
||||
#include "agg_embedded_raster_fonts.h"
|
||||
|
||||
|
||||
#include <string>
|
||||
|
||||
#ifdef AGG2D_USE_VECTORFONTS
|
||||
#ifdef AGG2D_USE_FREETYPE
|
||||
#ifndef WIN32
|
||||
#include "agg_font_freetype.h"
|
||||
#else
|
||||
#include "../font_freetype/agg_font_freetype.h"
|
||||
#endif
|
||||
#else
|
||||
#include "../font_win32_tt/agg_font_win32_tt.h"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include "agg_pixfmt_rgba.h"
|
||||
//+ JME
|
||||
#include "agg_image_accessors.h"
|
||||
|
||||
#define AGG2D_TEMPLATE template<typename PixFormatSet>
|
||||
#define AGG2D_TEMPLATE_WITH_IMAGE template<typename PixFormatSet, typename ImagePixFormatSet>
|
||||
#define AGG2D_TEMPLATE_ARG <PixFormatSet>
|
||||
#define AGG2D_IMAGE_TEMPLATE template<typename ImagePixFormatSet>
|
||||
#define AGG2D_IMAGE_TEMPLATE_ARG <ImagePixFormatSet>
|
||||
#define TIMAGE Agg2DBase :: Image AGG2D_IMAGE_TEMPLATE_ARG
|
||||
|
||||
|
||||
template<typename Main, typename Pre, typename SG>
|
||||
class PixFormatSetDeclaration
|
||||
{
|
||||
public:
|
||||
typedef Main PixFormat;
|
||||
typedef Pre PixFormatPre;
|
||||
typedef SG SpanGenerator;
|
||||
};
|
||||
|
||||
class Agg2DBase
|
||||
{
|
||||
public:
|
||||
// JME
|
||||
//typedef agg::rect Rect;
|
||||
typedef agg::rect_i Rect;
|
||||
typedef agg::rect_d RectD;
|
||||
typedef agg::trans_affine Affine;
|
||||
|
||||
enum LineJoin
|
||||
{
|
||||
JOIN_MITER = agg::miter_join,
|
||||
JOIN_ROUND = agg::round_join,
|
||||
JOIN_BEVEL = agg::bevel_join
|
||||
};
|
||||
|
||||
enum LineCap
|
||||
{
|
||||
CAP_BUTT = agg::butt_cap,
|
||||
CAP_SQUARE = agg::square_cap,
|
||||
CAP_ROUND = agg::round_cap
|
||||
};
|
||||
|
||||
enum TextAlignment
|
||||
{
|
||||
AlignLeft,
|
||||
AlignRight,
|
||||
AlignCenter,
|
||||
AlignBaseline,
|
||||
AlignTop = AlignRight,
|
||||
AlignBottom = AlignLeft
|
||||
};
|
||||
|
||||
|
||||
enum DrawPathFlag
|
||||
{
|
||||
FillOnly,
|
||||
StrokeOnly,
|
||||
FillAndStroke,
|
||||
FillWithLineColor
|
||||
};
|
||||
|
||||
enum ViewportOption
|
||||
{
|
||||
Anisotropic,
|
||||
XMinYMin,
|
||||
XMidYMin,
|
||||
XMaxYMin,
|
||||
XMinYMid,
|
||||
XMidYMid,
|
||||
XMaxYMid,
|
||||
XMinYMax,
|
||||
XMidYMax,
|
||||
XMaxYMax
|
||||
};
|
||||
|
||||
enum WindowFitLogic
|
||||
{
|
||||
WindowFitLogic_meet,
|
||||
WindowFitLogic_slice
|
||||
};
|
||||
|
||||
struct Transformations
|
||||
{
|
||||
double affineMatrix[6];
|
||||
};
|
||||
|
||||
AGG2D_IMAGE_TEMPLATE struct Image
|
||||
{
|
||||
agg::rendering_buffer renBuf;
|
||||
|
||||
Image(const agg::rendering_buffer& srcBuf)
|
||||
: renBuf(srcBuf)
|
||||
{}
|
||||
Image(unsigned char* buf, unsigned width, unsigned height, int stride) :
|
||||
renBuf(buf, width, height, stride) {}
|
||||
void attach(unsigned char* buf, unsigned width, unsigned height, int stride)
|
||||
{
|
||||
renBuf.attach(buf, width, height, stride);
|
||||
}
|
||||
int width() const { return renBuf.width(); }
|
||||
int height() const { return renBuf.height(); }
|
||||
|
||||
AGG2D_TEMPLATE void premultiply()
|
||||
{
|
||||
typename PixFormatSet::PixFormat pixf(renBuf);
|
||||
pixf.premultiply();
|
||||
}
|
||||
|
||||
AGG2D_TEMPLATE void demultiply()
|
||||
{
|
||||
typename PixFormatSet::PixFormat pixf(renBuf);
|
||||
pixf.demultiply();
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
enum ImageFilter
|
||||
{
|
||||
NoFilter,
|
||||
Bilinear,
|
||||
Hanning,
|
||||
Hermite,
|
||||
Quadric,
|
||||
Bicubic,
|
||||
Catrom,
|
||||
Spline16,
|
||||
Spline36,
|
||||
Blackman144
|
||||
};
|
||||
|
||||
enum ImageResample
|
||||
{
|
||||
NoResample,
|
||||
ResampleAlways,
|
||||
ResampleOnZoomOut
|
||||
};
|
||||
|
||||
enum FontCacheType
|
||||
{
|
||||
RasterFontCache,
|
||||
VectorFontCache
|
||||
};
|
||||
|
||||
enum BlendMode
|
||||
{
|
||||
BlendAlpha = agg::end_of_comp_op_e,
|
||||
BlendClear = agg::comp_op_clear,
|
||||
BlendSrc = agg::comp_op_src,
|
||||
BlendDst = agg::comp_op_dst,
|
||||
BlendSrcOver = agg::comp_op_src_over,
|
||||
BlendDstOver = agg::comp_op_dst_over,
|
||||
BlendSrcIn = agg::comp_op_src_in,
|
||||
BlendDstIn = agg::comp_op_dst_in,
|
||||
BlendSrcOut = agg::comp_op_src_out,
|
||||
BlendDstOut = agg::comp_op_dst_out,
|
||||
BlendSrcAtop = agg::comp_op_src_atop,
|
||||
BlendDstAtop = agg::comp_op_dst_atop,
|
||||
BlendXor = agg::comp_op_xor,
|
||||
BlendAdd = agg::comp_op_plus,
|
||||
BlendSub = agg::comp_op_minus,
|
||||
BlendMultiply = agg::comp_op_multiply,
|
||||
BlendScreen = agg::comp_op_screen,
|
||||
BlendOverlay = agg::comp_op_overlay,
|
||||
BlendDarken = agg::comp_op_darken,
|
||||
BlendLighten = agg::comp_op_lighten,
|
||||
BlendColorDodge = agg::comp_op_color_dodge,
|
||||
BlendColorBurn = agg::comp_op_color_burn,
|
||||
BlendHardLight = agg::comp_op_hard_light,
|
||||
BlendSoftLight = agg::comp_op_soft_light,
|
||||
BlendDifference = agg::comp_op_difference,
|
||||
BlendExclusion = agg::comp_op_exclusion,
|
||||
BlendContrast = agg::comp_op_contrast
|
||||
};
|
||||
|
||||
enum Direction
|
||||
{
|
||||
CW, CCW
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
template<typename,typename> class Agg2DRenderer;
|
||||
|
||||
template<typename PixFormatSet> class Agg2D : public Agg2DBase
|
||||
{
|
||||
public:
|
||||
typedef typename PixFormatSet::PixFormat PixFormat;
|
||||
typedef Image<PixFormatSet> MyImage;
|
||||
typedef agg::order_bgra ComponentOrder; // Platform dependent!
|
||||
|
||||
typedef agg::rgba8 ColorType;
|
||||
typedef agg::blender_rgba<ColorType, ComponentOrder> Blender;
|
||||
typedef agg::comp_op_adaptor_rgba<ColorType, ComponentOrder> BlenderComp;
|
||||
typedef agg::blender_rgba_pre<ColorType, ComponentOrder> BlenderPre;
|
||||
typedef agg::comp_op_adaptor_rgba_pre<ColorType, ComponentOrder> BlenderCompPre;
|
||||
|
||||
// JME
|
||||
//typedef agg::pixel_formats_rgba<Blender, agg::pixel32_type> PixFormat;
|
||||
//typedef agg::pixfmt_bgra32 PixFormat;
|
||||
// JME
|
||||
//typedef agg::pixfmt_custom_blend_rgba<BlenderComp,> PixFormatComp;
|
||||
typedef agg::pixfmt_custom_blend_rgba<BlenderComp,agg::rendering_buffer> PixFormatComp;
|
||||
// JME
|
||||
//typedef agg::pixel_formats_rgba<BlenderPre, agg::pixel32_type> PixFormatPre;
|
||||
typedef typename PixFormatSet::PixFormatPre PixFormatPre;
|
||||
// JME
|
||||
//typedef agg::pixfmt_custom_blend_rgba<BlenderCompPre> PixFormatCompPre;
|
||||
typedef agg::pixfmt_custom_blend_rgba<BlenderCompPre,agg::rendering_buffer> PixFormatCompPre;
|
||||
|
||||
typedef agg::renderer_base<PixFormat> RendererBase;
|
||||
typedef agg::renderer_base<PixFormatComp> RendererBaseComp;
|
||||
typedef agg::renderer_base<PixFormatPre> RendererBasePre;
|
||||
typedef agg::renderer_base<PixFormatCompPre> RendererBaseCompPre;
|
||||
|
||||
typedef agg::renderer_scanline_aa_solid<RendererBase> RendererSolid;
|
||||
typedef agg::renderer_scanline_aa_solid<RendererBaseComp> RendererSolidComp;
|
||||
|
||||
typedef agg::span_allocator<ColorType> SpanAllocator;
|
||||
typedef agg::pod_auto_array<ColorType, 256> GradientArray;
|
||||
|
||||
typedef agg::span_gradient<ColorType, agg::span_interpolator_linear<>, agg::gradient_x, GradientArray> LinearGradientSpan;
|
||||
typedef agg::span_gradient<ColorType, agg::span_interpolator_linear<>, agg::gradient_circle, GradientArray> RadialGradientSpan;
|
||||
|
||||
#ifdef AGG2D_USE_VECTORFONTS
|
||||
#ifdef AGG2D_USE_FREETYPE
|
||||
typedef agg::font_engine_freetype_int32 FontEngine;
|
||||
#else
|
||||
typedef agg::font_engine_win32_tt_int32 FontEngine;
|
||||
#endif
|
||||
|
||||
typedef agg::font_cache_manager<FontEngine> FontCacheManager;
|
||||
typedef FontCacheManager::gray8_adaptor_type FontRasterizer;
|
||||
typedef FontCacheManager::gray8_scanline_type FontScanline;
|
||||
#endif
|
||||
|
||||
typedef agg::conv_curve<agg::path_storage> ConvCurve;
|
||||
typedef agg::conv_stroke<ConvCurve> ConvStroke;
|
||||
typedef agg::conv_transform<ConvCurve> PathTransform;
|
||||
typedef agg::conv_transform<ConvStroke> StrokeTransform;
|
||||
enum Gradient
|
||||
{
|
||||
Solid,
|
||||
Linear,
|
||||
Radial
|
||||
};
|
||||
|
||||
public:
|
||||
template<typename,typename> friend class Agg2DRenderer;
|
||||
|
||||
typedef ColorType Color;
|
||||
|
||||
|
||||
|
||||
struct State
|
||||
{
|
||||
RectD m_clipBox;
|
||||
|
||||
BlendMode m_blendMode;
|
||||
BlendMode m_imageBlendMode;
|
||||
Color m_imageBlendColor;
|
||||
|
||||
double m_masterAlpha;
|
||||
double m_antiAliasGamma;
|
||||
|
||||
const agg::int8u* m_font;
|
||||
|
||||
Color m_fillColor;
|
||||
Color m_lineColor;
|
||||
GradientArray m_fillGradient;
|
||||
GradientArray m_lineGradient;
|
||||
|
||||
LineCap m_lineCap;
|
||||
LineJoin m_lineJoin;
|
||||
|
||||
Gradient m_fillGradientFlag;
|
||||
Gradient m_lineGradientFlag;
|
||||
agg::trans_affine m_fillGradientMatrix;
|
||||
agg::trans_affine m_lineGradientMatrix;
|
||||
double m_fillGradientD1;
|
||||
double m_lineGradientD1;
|
||||
double m_fillGradientD2;
|
||||
double m_lineGradientD2;
|
||||
|
||||
double m_textAngle;
|
||||
TextAlignment m_textAlignX;
|
||||
TextAlignment m_textAlignY;
|
||||
bool m_textHints;
|
||||
double m_fontHeight;
|
||||
double m_fontAscent;
|
||||
double m_fontDescent;
|
||||
FontCacheType m_fontCacheType;
|
||||
|
||||
double m_lineWidth;
|
||||
bool m_evenOddFlag;
|
||||
|
||||
agg::trans_affine m_transform;
|
||||
agg::trans_affine m_affine;
|
||||
|
||||
};
|
||||
|
||||
|
||||
~Agg2D();
|
||||
Agg2D();
|
||||
|
||||
// Setup
|
||||
//-----------------------
|
||||
void attach(unsigned char* buf, unsigned width, unsigned height, int stride);
|
||||
void attach(MyImage& img);
|
||||
|
||||
void clipBox(double x1, double y1, double x2, double y2);
|
||||
RectD clipBox() const;
|
||||
|
||||
void clearAll(Color c);
|
||||
void clearAll(unsigned r, unsigned g, unsigned b, unsigned a = 255);
|
||||
|
||||
void clearClipBox(Color c);
|
||||
void clearClipBox(unsigned r, unsigned g, unsigned b, unsigned a = 255);
|
||||
|
||||
unsigned width() const { return m_rbuf.width(); }
|
||||
unsigned height() const { return m_rbuf.height(); }
|
||||
unsigned stride() const { return m_rbuf.stride(); }
|
||||
|
||||
// Conversions
|
||||
//-----------------------
|
||||
void worldToScreen(double& x, double& y) const;
|
||||
void screenToWorld(double& x, double& y) const;
|
||||
double worldToScreen(double scalar) const;
|
||||
double screenToWorld(double scalar) const;
|
||||
void alignPoint(double& x, double& y) const;
|
||||
bool inBox(double worldX, double worldY) const;
|
||||
|
||||
// General Attributes
|
||||
//-----------------------
|
||||
void blendMode(BlendMode m);
|
||||
BlendMode blendMode() const;
|
||||
|
||||
void imageBlendMode(BlendMode m);
|
||||
BlendMode imageBlendMode() const;
|
||||
|
||||
void imageBlendColor(Color c);
|
||||
void imageBlendColor(unsigned r, unsigned g, unsigned b, unsigned a = 255);
|
||||
Color imageBlendColor() const;
|
||||
|
||||
void masterAlpha(double a);
|
||||
double masterAlpha() const;
|
||||
|
||||
void antiAliasGamma(double g);
|
||||
double antiAliasGamma() const;
|
||||
|
||||
void font(const agg::int8u* font) { m_font = font; }
|
||||
const agg::int8u* font() { return m_font; }
|
||||
|
||||
void fillColor(Color c);
|
||||
void fillColor(unsigned r, unsigned g, unsigned b, unsigned a = 255);
|
||||
void noFill();
|
||||
|
||||
void lineColor(Color c);
|
||||
void lineColor(unsigned r, unsigned g, unsigned b, unsigned a = 255);
|
||||
void noLine();
|
||||
|
||||
Color fillColor() const;
|
||||
Color lineColor() const;
|
||||
|
||||
void fillLinearGradient(double x1, double y1, double x2, double y2, Color c1, Color c2, double profile=1.0);
|
||||
void lineLinearGradient(double x1, double y1, double x2, double y2, Color c1, Color c2, double profile=1.0);
|
||||
|
||||
void fillRadialGradient(double x, double y, double r, Color c1, Color c2, double profile=1.0);
|
||||
void lineRadialGradient(double x, double y, double r, Color c1, Color c2, double profile=1.0);
|
||||
|
||||
void fillRadialGradient(double x, double y, double r, Color c1, Color c2, Color c3);
|
||||
void lineRadialGradient(double x, double y, double r, Color c1, Color c2, Color c3);
|
||||
|
||||
void fillRadialGradient(double x, double y, double r);
|
||||
void lineRadialGradient(double x, double y, double r);
|
||||
|
||||
void lineWidth(double w);
|
||||
double lineWidth() const;
|
||||
|
||||
void lineCap(LineCap cap);
|
||||
LineCap lineCap() const;
|
||||
|
||||
void lineJoin(LineJoin join);
|
||||
LineJoin lineJoin() const;
|
||||
|
||||
void fillEvenOdd(bool evenOddFlag);
|
||||
bool fillEvenOdd() const;
|
||||
|
||||
// Transformations
|
||||
//-----------------------
|
||||
Transformations transformations() const;
|
||||
void transformations(const Transformations& tr);
|
||||
|
||||
const Affine& affine() const;
|
||||
void affine(const Affine&);
|
||||
|
||||
void resetTransformations();
|
||||
void matrix(const Affine& tr);
|
||||
void matrix(const Transformations& tr);
|
||||
void rotate(double angle);
|
||||
void rotate(double angle, double cx, double cy);
|
||||
void scale(double s);
|
||||
void scale(double sx, double sy);
|
||||
void skew(double sx, double sy);
|
||||
void translate(double x, double y);
|
||||
void parallelogram(double x1, double y1, double x2, double y2, const double* para);
|
||||
void viewport(double worldX1, double worldY1, double worldX2, double worldY2,
|
||||
double screenX1, double screenY1, double screenX2, double screenY2,
|
||||
ViewportOption opt=XMidYMid, WindowFitLogic fl = WindowFitLogic_meet);
|
||||
|
||||
// Basic Shapes
|
||||
//-----------------------
|
||||
void line(double x1, double y1, double x2, double y2);
|
||||
void triangle(double x1, double y1, double x2, double y2, double x3, double y3);
|
||||
void rectangle(double x1, double y1, double x2, double y2);
|
||||
void roundedRect(double x1, double y1, double x2, double y2, double r);
|
||||
void roundedRect(double x1, double y1, double x2, double y2, double rx, double ry);
|
||||
void roundedRect(double x1, double y1, double x2, double y2,
|
||||
double rxBottom, double ryBottom,
|
||||
double rxTop, double ryTop);
|
||||
void ellipse(double cx, double cy, double rx, double ry);
|
||||
void arc(double cx, double cy, double rx, double ry, double start, double sweep);
|
||||
void star(double cx, double cy, double r1, double r2, double startAngle, int numRays);
|
||||
void curve(double x1, double y1, double x2, double y2, double x3, double y3);
|
||||
void curve(double x1, double y1, double x2, double y2, double x3, double y3, double x4, double y4);
|
||||
void polygon(double* xy, int numPoints);
|
||||
void polyline(double* xy, int numPoints);
|
||||
|
||||
|
||||
// Text
|
||||
//-----------------------
|
||||
#ifdef AGG2D_USE_VECTORFONTS
|
||||
void flipText(bool flip);
|
||||
void font(const char* fileName, double height,
|
||||
bool bold = false,
|
||||
bool italic = false,
|
||||
FontCacheType ch = RasterFontCache,
|
||||
double angle = 0.0);
|
||||
double fontHeight() const;
|
||||
double fontAscent() const;
|
||||
|
||||
void textAlignment(TextAlignment alignX, TextAlignment alignY);
|
||||
bool textHints() const;
|
||||
void textHints(bool hints);
|
||||
double textWidth(const char* str, unsigned int len);
|
||||
double textWidth(const wchar_t* str, unsigned int len);
|
||||
void text(double x, double y, const char* str, unsigned int len, bool roundOff=false, double dx=0.0, double dy=0.0);
|
||||
void text(double x, double y, const wchar_t* str, unsigned int len, bool roundOff=false, double dx=0.0, double dy=0.0);
|
||||
|
||||
double textWidth(const char* str);
|
||||
void text(double x, double y, const char* str, bool roundOff=false, double dx=0.0, double dy=0.0);
|
||||
#endif
|
||||
|
||||
// Path commands
|
||||
//-----------------------
|
||||
void resetPath();
|
||||
|
||||
void moveTo(double x, double y);
|
||||
void moveRel(double dx, double dy);
|
||||
|
||||
void lineTo(double x, double y);
|
||||
void lineRel(double dx, double dy);
|
||||
|
||||
void horLineTo(double x);
|
||||
void horLineRel(double dx);
|
||||
|
||||
void verLineTo(double y);
|
||||
void verLineRel(double dy);
|
||||
|
||||
void arcTo(double rx, double ry,
|
||||
double angle,
|
||||
bool largeArcFlag,
|
||||
bool sweepFlag,
|
||||
double x, double y);
|
||||
|
||||
void arcRel(double rx, double ry,
|
||||
double angle,
|
||||
bool largeArcFlag,
|
||||
bool sweepFlag,
|
||||
double dx, double dy);
|
||||
|
||||
void quadricCurveTo(double xCtrl, double yCtrl,
|
||||
double xTo, double yTo);
|
||||
void quadricCurveRel(double dxCtrl, double dyCtrl,
|
||||
double dxTo, double dyTo);
|
||||
void quadricCurveTo(double xTo, double yTo);
|
||||
void quadricCurveRel(double dxTo, double dyTo);
|
||||
|
||||
void cubicCurveTo(double xCtrl1, double yCtrl1,
|
||||
double xCtrl2, double yCtrl2,
|
||||
double xTo, double yTo);
|
||||
|
||||
void cubicCurveRel(double dxCtrl1, double dyCtrl1,
|
||||
double dxCtrl2, double dyCtrl2,
|
||||
double dxTo, double dyTo);
|
||||
|
||||
void cubicCurveTo(double xCtrl2, double yCtrl2,
|
||||
double xTo, double yTo);
|
||||
|
||||
void cubicCurveRel(double xCtrl2, double yCtrl2,
|
||||
double xTo, double yTo);
|
||||
|
||||
void addEllipse(double cx, double cy, double rx, double ry, Direction dir);
|
||||
void closePolygon();
|
||||
|
||||
void drawPath(DrawPathFlag flag = FillAndStroke);
|
||||
void drawPathNoTransform(DrawPathFlag flag = FillAndStroke);
|
||||
|
||||
|
||||
// Image Transformations
|
||||
//-----------------------
|
||||
void imageFilter(ImageFilter f);
|
||||
ImageFilter imageFilter() const;
|
||||
|
||||
void imageResample(ImageResample f);
|
||||
ImageResample imageResample() const;
|
||||
|
||||
//---------
|
||||
//if anyone can figure out how to put these in the .inl file, theyre more than welcome to. I couldnt declare them correctly to match
|
||||
//the .h file declaration
|
||||
|
||||
AGG2D_IMAGE_TEMPLATE void transformImage(const TIMAGE& img,
|
||||
int imgX1, int imgY1, int imgX2, int imgY2,
|
||||
double dstX1, double dstY1, double dstX2, double dstY2)
|
||||
{
|
||||
resetPath();
|
||||
moveTo(dstX1, dstY1);
|
||||
lineTo(dstX2, dstY1);
|
||||
lineTo(dstX2, dstY2);
|
||||
lineTo(dstX1, dstY2);
|
||||
closePolygon();
|
||||
double parallelogram[6] = { dstX1, dstY1, dstX2, dstY1, dstX2, dstY2 };
|
||||
renderImage <typename ImagePixFormatSet::ImagePixFormat> (img, imgX1, imgY1, imgX2, imgY2, parallelogram);
|
||||
}
|
||||
|
||||
AGG2D_IMAGE_TEMPLATE void transformImage(const TIMAGE& img,
|
||||
double dstX1, double dstY1, double dstX2, double dstY2)
|
||||
{
|
||||
resetPath();
|
||||
moveTo(dstX1, dstY1);
|
||||
lineTo(dstX2, dstY1);
|
||||
lineTo(dstX2, dstY2);
|
||||
lineTo(dstX1, dstY2);
|
||||
closePolygon();
|
||||
double parallelogram[6] = { dstX1, dstY1, dstX2, dstY1, dstX2, dstY2 };
|
||||
renderImage(img, 0, 0, img.renBuf.width(), img.renBuf.height(), parallelogram);
|
||||
}
|
||||
|
||||
|
||||
AGG2D_IMAGE_TEMPLATE void transformImage(const TIMAGE& img,
|
||||
int imgX1, int imgY1, int imgX2, int imgY2,
|
||||
const double* parallelogram)
|
||||
{
|
||||
resetPath();
|
||||
moveTo(parallelogram[0], parallelogram[1]);
|
||||
lineTo(parallelogram[2], parallelogram[3]);
|
||||
lineTo(parallelogram[4], parallelogram[5]);
|
||||
lineTo(parallelogram[0] + parallelogram[4] - parallelogram[2],
|
||||
parallelogram[1] + parallelogram[5] - parallelogram[3]);
|
||||
closePolygon();
|
||||
renderImage(img, imgX1, imgY1, imgX2, imgY2, parallelogram);
|
||||
}
|
||||
|
||||
|
||||
AGG2D_IMAGE_TEMPLATE void transformImage(const TIMAGE& img, const double* parallelogram)
|
||||
{
|
||||
resetPath();
|
||||
moveTo(parallelogram[0], parallelogram[1]);
|
||||
lineTo(parallelogram[2], parallelogram[3]);
|
||||
lineTo(parallelogram[4], parallelogram[5]);
|
||||
lineTo(parallelogram[0] + parallelogram[4] - parallelogram[2],
|
||||
parallelogram[1] + parallelogram[5] - parallelogram[3]);
|
||||
closePolygon();
|
||||
renderImage(img, 0, 0, img.renBuf.width(), img.renBuf.height(), parallelogram);
|
||||
}
|
||||
|
||||
|
||||
|
||||
AGG2D_IMAGE_TEMPLATE void transformImagePath(const TIMAGE& img,
|
||||
int imgX1, int imgY1, int imgX2, int imgY2,
|
||||
double dstX1, double dstY1, double dstX2, double dstY2)
|
||||
{
|
||||
double parallelogram[6] = { dstX1, dstY1, dstX2, dstY1, dstX2, dstY2 };
|
||||
renderImage(img, imgX1, imgY1, imgX2, imgY2, parallelogram);
|
||||
}
|
||||
|
||||
|
||||
AGG2D_IMAGE_TEMPLATE void transformImagePath(const TIMAGE& img,
|
||||
double dstX1, double dstY1, double dstX2, double dstY2)
|
||||
{
|
||||
double parallelogram[6] = { dstX1, dstY1, dstX2, dstY1, dstX2, dstY2 };
|
||||
renderImage(img, 0, 0, img.renBuf.width(), img.renBuf.height(), parallelogram);
|
||||
}
|
||||
|
||||
|
||||
|
||||
AGG2D_IMAGE_TEMPLATE void transformImagePath(const TIMAGE& img,
|
||||
int imgX1, int imgY1, int imgX2, int imgY2,
|
||||
const double* parallelogram)
|
||||
{
|
||||
renderImage(img, imgX1, imgY1, imgX2, imgY2, parallelogram);
|
||||
}
|
||||
|
||||
|
||||
AGG2D_IMAGE_TEMPLATE void transformImagePath(const TIMAGE& img, const double* parallelogram)
|
||||
{
|
||||
renderImage(img, 0, 0, img.renBuf.width(), img.renBuf.height(), parallelogram);
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Image Blending (no transformations available)
|
||||
AGG2D_IMAGE_TEMPLATE void blendImage(TIMAGE& img,
|
||||
int imgX1, int imgY1, int imgX2, int imgY2,
|
||||
double dstX, double dstY, unsigned alpha=255)
|
||||
{
|
||||
worldToScreen(dstX, dstY);
|
||||
PixFormat pixF(img.renBuf);
|
||||
// JME
|
||||
//agg::rect r(imgX1, imgY1, imgX2, imgY2);
|
||||
Rect r(imgX1, imgY1, imgX2, imgY2);
|
||||
if(m_blendMode == BlendAlpha)
|
||||
{
|
||||
m_renBasePre.blend_from(pixF, &r, int(dstX)-imgX1, int(dstY)-imgY1, alpha);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_renBaseCompPre.blend_from(pixF, &r, int(dstX)-imgX1, int(dstY)-imgY1, alpha);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void renderText(double dstX, double dstY, const std::string& str)
|
||||
{
|
||||
worldToScreen(dstX, dstY);
|
||||
PixFormat pixF(m_rbuf);
|
||||
//Rect r(imgX1, imgY1, imgX2, imgY2);
|
||||
|
||||
typedef agg::glyph_raster_bin<agg::rgba8> glyph_gen;
|
||||
glyph_gen glyph(0);
|
||||
|
||||
if(m_blendMode == BlendAlpha)
|
||||
{
|
||||
typedef agg::renderer_base<PixFormatPre> ren_base;
|
||||
agg::renderer_raster_htext_solid<ren_base, glyph_gen> rt(m_renBasePre,glyph);
|
||||
rt.color(m_lineColor);
|
||||
glyph.font(m_font);
|
||||
rt.render_text(dstX, dstY, str.c_str(), true); //flipy
|
||||
}
|
||||
else
|
||||
{
|
||||
typedef agg::renderer_base<PixFormatCompPre> ren_base;
|
||||
agg::renderer_raster_htext_solid<ren_base, glyph_gen> rt(m_renBaseCompPre,glyph);
|
||||
rt.color(m_lineColor);
|
||||
glyph.font(m_font);
|
||||
rt.render_text(dstX, dstY, str.c_str(), true); //flipy
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
AGG2D_IMAGE_TEMPLATE void blendImage(TIMAGE& img, double dstX, double dstY, unsigned alpha=255)
|
||||
{
|
||||
worldToScreen(dstX, dstY);
|
||||
PixFormat pixF(img.renBuf);
|
||||
m_renBasePre.blend_from(pixF, 0, int(dstX), int(dstY), alpha);
|
||||
if(m_blendMode == BlendAlpha)
|
||||
{
|
||||
m_renBasePre.blend_from(pixF, 0, int(dstX), int(dstY), alpha);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_renBaseCompPre.blend_from(pixF, 0, int(dstX), int(dstY), alpha);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Copy image directly, together with alpha-channel
|
||||
AGG2D_IMAGE_TEMPLATE void copyImage(TIMAGE& img,
|
||||
int imgX1, int imgY1, int imgX2, int imgY2,
|
||||
double dstX, double dstY)
|
||||
{
|
||||
worldToScreen(dstX, dstY);
|
||||
// JME
|
||||
//agg::rect r(imgX1, imgY1, imgX2, imgY2);
|
||||
Rect r(imgX1, imgY1, imgX2, imgY2);
|
||||
m_renBase.copy_from(img.renBuf, &r, int(dstX)-imgX1, int(dstY)-imgY1);
|
||||
}
|
||||
|
||||
AGG2D_IMAGE_TEMPLATE void copyImage(TIMAGE& img, double dstX, double dstY)
|
||||
{
|
||||
worldToScreen(dstX, dstY);
|
||||
m_renBase.copy_from(img.renBuf, 0, int(dstX), int(dstY));
|
||||
}
|
||||
|
||||
// State
|
||||
//-----------------------
|
||||
|
||||
void saveStateTo(State& st);
|
||||
void restoreStateFrom(const State& st);
|
||||
|
||||
|
||||
|
||||
// Auxiliary
|
||||
//-----------------------
|
||||
static double pi() { return agg::pi; }
|
||||
static double deg2Rad(double v) { return v * agg::pi / 180.0; }
|
||||
static double rad2Deg(double v) { return v * 180.0 / agg::pi; }
|
||||
|
||||
PixFormat & pixFormat() { return m_pixFormat; }
|
||||
agg::rendering_buffer & buf() { return m_rbuf; }
|
||||
|
||||
private:
|
||||
void render(bool fillColor);
|
||||
|
||||
#ifdef AGG2D_USE_VECTORFONTS
|
||||
#if !defined( UNDER_CE )
|
||||
void render(FontRasterizer& ras, FontScanline& sl);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
void addLine(double x1, double y1, double x2, double y2);
|
||||
void updateRasterizerGamma();
|
||||
AGG2D_IMAGE_TEMPLATE void renderImage(const TIMAGE& img, int x1, int y1, int x2, int y2, const double* parl)
|
||||
{
|
||||
agg::trans_affine mtx((double)x1,
|
||||
(double)y1,
|
||||
(double)x2,
|
||||
(double)y2,
|
||||
parl);
|
||||
mtx *= m_transform;
|
||||
mtx.invert();
|
||||
|
||||
m_rasterizer.reset();
|
||||
m_rasterizer.add_path(m_pathTransform);
|
||||
|
||||
typedef agg::span_interpolator_linear<agg::trans_affine> Interpolator;
|
||||
Interpolator interpolator(mtx);
|
||||
|
||||
if(m_blendMode == BlendAlpha)
|
||||
{
|
||||
// JME audit -
|
||||
Agg2DRenderer<PixFormatSet,ImagePixFormatSet>::renderImage(*this, img, m_renBasePre, interpolator);
|
||||
}
|
||||
else
|
||||
{
|
||||
Agg2DRenderer<PixFormatSet,ImagePixFormatSet>::renderImage(*this, img, m_renBaseCompPre, interpolator);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void updateTransformations();
|
||||
|
||||
agg::rendering_buffer m_rbuf;
|
||||
PixFormat m_pixFormat;
|
||||
PixFormatComp m_pixFormatComp;
|
||||
PixFormatPre m_pixFormatPre;
|
||||
PixFormatCompPre m_pixFormatCompPre;
|
||||
RendererBase m_renBase;
|
||||
RendererBaseComp m_renBaseComp;
|
||||
RendererBasePre m_renBasePre;
|
||||
RendererBaseCompPre m_renBaseCompPre;
|
||||
RendererSolid m_renSolid;
|
||||
RendererSolidComp m_renSolidComp;
|
||||
|
||||
SpanAllocator m_allocator;
|
||||
RectD m_clipBox;
|
||||
|
||||
BlendMode m_blendMode;
|
||||
BlendMode m_imageBlendMode;
|
||||
Color m_imageBlendColor;
|
||||
|
||||
agg::scanline_u8 m_scanline;
|
||||
agg::rasterizer_scanline_aa<> m_rasterizer;
|
||||
|
||||
double m_masterAlpha;
|
||||
double m_antiAliasGamma;
|
||||
|
||||
const agg::int8u* m_font;
|
||||
|
||||
Color m_fillColor;
|
||||
Color m_lineColor;
|
||||
GradientArray m_fillGradient;
|
||||
GradientArray m_lineGradient;
|
||||
|
||||
LineCap m_lineCap;
|
||||
LineJoin m_lineJoin;
|
||||
|
||||
Gradient m_fillGradientFlag;
|
||||
Gradient m_lineGradientFlag;
|
||||
agg::trans_affine m_fillGradientMatrix;
|
||||
agg::trans_affine m_lineGradientMatrix;
|
||||
double m_fillGradientD1;
|
||||
double m_lineGradientD1;
|
||||
double m_fillGradientD2;
|
||||
double m_lineGradientD2;
|
||||
|
||||
double m_textAngle;
|
||||
TextAlignment m_textAlignX;
|
||||
TextAlignment m_textAlignY;
|
||||
bool m_textHints;
|
||||
double m_fontHeight;
|
||||
double m_fontAscent;
|
||||
double m_fontDescent;
|
||||
FontCacheType m_fontCacheType;
|
||||
|
||||
ImageFilter m_imageFilter;
|
||||
ImageResample m_imageResample;
|
||||
agg::image_filter_lut m_imageFilterLut;
|
||||
|
||||
agg::span_interpolator_linear<> m_fillGradientInterpolator;
|
||||
agg::span_interpolator_linear<> m_lineGradientInterpolator;
|
||||
|
||||
agg::gradient_x m_linearGradientFunction;
|
||||
agg::gradient_circle m_radialGradientFunction;
|
||||
|
||||
double m_lineWidth;
|
||||
bool m_evenOddFlag;
|
||||
|
||||
double m_start_x;
|
||||
double m_start_y;
|
||||
|
||||
agg::path_storage m_path;
|
||||
agg::trans_affine m_transform;
|
||||
|
||||
agg::trans_affine m_viewport;
|
||||
agg::trans_affine m_affine;
|
||||
|
||||
ConvCurve m_convCurve;
|
||||
ConvStroke m_convStroke;
|
||||
|
||||
PathTransform m_pathTransform;
|
||||
StrokeTransform m_strokeTransform;
|
||||
|
||||
#ifdef AGG2D_USE_VECTORFONTS
|
||||
#ifndef AGG2D_USE_FREETYPE
|
||||
HDC m_fontDC;
|
||||
#endif
|
||||
FontEngine m_fontEngine;
|
||||
FontCacheManager m_fontCacheManager;
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
|
||||
#include "agg2d.inl"
|
||||
|
||||
#endif
|
||||
Executable
+1979
File diff suppressed because it is too large
Load Diff
Executable
+591
@@ -0,0 +1,591 @@
|
||||
/*
|
||||
The MIT License
|
||||
|
||||
Copyright (C) 2009-2010 DeSmuME team
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <map>
|
||||
|
||||
#include "GPU.h"
|
||||
#include "NDSSystem.h"
|
||||
|
||||
#include "aggdraw.h"
|
||||
|
||||
#include "agg_renderer_base.h"
|
||||
#include "agg_renderer_primitives.h"
|
||||
#include "agg_renderer_scanline.h"
|
||||
#include "agg_bounding_rect.h"
|
||||
#include "agg_trans_affine.h"
|
||||
#include "agg_path_storage.h"
|
||||
#include "agg_color_rgba.h"
|
||||
|
||||
#include "agg_rasterizer_scanline_aa.h"
|
||||
#include "agg_scanline_u.h"
|
||||
#include "agg_renderer_scanline.h"
|
||||
#include "agg_scanline_p.h"
|
||||
|
||||
//raster text
|
||||
#include "agg_glyph_raster_bin.h"
|
||||
#include "agg_embedded_raster_fonts.h"
|
||||
#include "agg_renderer_raster_text.h"
|
||||
|
||||
#include "ctrl/agg_bezier_ctrl.h"
|
||||
#include "platform/agg_platform_support.h"
|
||||
#include "agg_pattern_filters_rgba.h"
|
||||
#include "agg_renderer_outline_image.h"
|
||||
#include "agg_rasterizer_outline_aa.h"
|
||||
|
||||
#include "agg_image_accessors.h"
|
||||
#include "agg_span_interpolator_linear.h"
|
||||
#include "agg_span_image_filter_rgb.h"
|
||||
#include "agg_span_image_filter_rgba.h"
|
||||
#include "agg_span_image_filter_gray.h"
|
||||
|
||||
#include "agg_span_allocator.h"
|
||||
|
||||
typedef std::map<std::string, const agg::int8u*> TAgg_Font_Table;
|
||||
static TAgg_Font_Table font_table;
|
||||
|
||||
font_type fonts_list[] =
|
||||
{
|
||||
{ agg::gse4x6, "gse4x6" },
|
||||
{ agg::gse4x8, "gse4x8" },
|
||||
{ agg::gse5x7, "gse5x7" },
|
||||
{ agg::gse5x9, "gse5x9" },
|
||||
{ agg::gse6x9, "gse6x9" },
|
||||
{ agg::gse6x12, "gse6x12" },
|
||||
{ agg::gse7x11, "gse7x11" },
|
||||
{ agg::gse7x11_bold, "gse7x11_bold" },
|
||||
{ agg::gse7x15, "gse7x15" },
|
||||
{ agg::gse7x15_bold, "gse7x15_bold" },
|
||||
{ agg::gse8x16, "gse8x16" },
|
||||
{ agg::gse8x16_bold, "gse8x16_bold" },
|
||||
{ agg::mcs11_prop, "mcs11_prop" },
|
||||
{ agg::mcs11_prop_condensed, "mcs11_prop_condensed" },
|
||||
{ agg::mcs12_prop, "mcs12_prop" },
|
||||
{ agg::mcs13_prop, "mcs13_prop" },
|
||||
{ agg::mcs5x10_mono, "mcs5x10_mono" },
|
||||
{ agg::mcs5x11_mono, "mcs5x11_mono" },
|
||||
{ agg::mcs6x10_mono, "mcs6x10_mono" },
|
||||
{ agg::mcs6x11_mono, "mcs6x11_mono" },
|
||||
{ agg::mcs7x12_mono_high, "mcs7x12_mono_high" },
|
||||
{ agg::mcs7x12_mono_low, "mcs7x12_mono_low" },
|
||||
{ agg::verdana12, "verdana12" },
|
||||
{ agg::verdana12_bold, "verdana12_bold" },
|
||||
{ agg::verdana13, "verdana13" },
|
||||
{ agg::verdana13_bold, "verdana13_bold" },
|
||||
{ agg::verdana14, "verdana14" },
|
||||
{ agg::verdana14_bold, "verdana14_bold" },
|
||||
{ agg::verdana16, "verdana16" },
|
||||
{ agg::verdana16_bold, "verdana16_bold" },
|
||||
{ agg::verdana17, "verdana17" },
|
||||
{ agg::verdana17_bold, "verdana17_bold" },
|
||||
{ agg::verdana18, "verdana18" },
|
||||
{ agg::verdana18_bold, "verdana18_bold" },
|
||||
};
|
||||
int font_Nums = ARRAY_SIZE(fonts_list);
|
||||
|
||||
const agg::int8u* AggDrawTarget::lookupFont(const std::string& name)
|
||||
{
|
||||
TAgg_Font_Table::iterator it(font_table.find(name));
|
||||
if(it == font_table.end()) return NULL;
|
||||
else return it->second;
|
||||
}
|
||||
|
||||
static void Agg_init_fonts()
|
||||
{
|
||||
for(u32 i=0;i<font_Nums;i++)
|
||||
font_table[fonts_list[i].name] = fonts_list[i].font;
|
||||
}
|
||||
|
||||
AggDraw_Desmume aggDraw;
|
||||
|
||||
#if defined(WIN32) || defined(HOST_LINUX)
|
||||
T_AGG_RGBA agg_targetScreen(0, 256, 384, 1024);
|
||||
#else
|
||||
T_AGG_RGB555 agg_targetScreen(0, 256, 384, 1512);
|
||||
#endif
|
||||
|
||||
static u32 luaBuffer[256*192*2];
|
||||
T_AGG_RGBA agg_targetLua((u8*)luaBuffer, 256, 384, 1024);
|
||||
|
||||
static u32 hudBuffer[256*192*2];
|
||||
T_AGG_RGBA agg_targetHud((u8*)hudBuffer, 256, 384, 1024);
|
||||
|
||||
static AggDrawTarget* targets[] = {
|
||||
&agg_targetScreen,
|
||||
&agg_targetHud,
|
||||
&agg_targetLua,
|
||||
};
|
||||
|
||||
void Agg_init()
|
||||
{
|
||||
Agg_init_fonts();
|
||||
aggDraw.screen = targets[0];
|
||||
aggDraw.hud = targets[1];
|
||||
aggDraw.lua = targets[2];
|
||||
|
||||
aggDraw.target = targets[0];
|
||||
|
||||
//if we're single core, we don't want to waste time compositing
|
||||
//and the more clever compositing isnt supported in non-windows
|
||||
#ifdef WIN32
|
||||
if(CommonSettings.single_core())
|
||||
aggDraw.hud = &agg_targetScreen;
|
||||
#else
|
||||
aggDraw.hud = &agg_targetScreen;
|
||||
#endif
|
||||
|
||||
aggDraw.hud->setFont("verdana18_bold");
|
||||
}
|
||||
|
||||
void AggDraw_Desmume::setTarget(AggTarget newTarget)
|
||||
{
|
||||
target = targets[newTarget];
|
||||
}
|
||||
|
||||
|
||||
|
||||
////temporary, just for testing the lib
|
||||
//void AGGDraw() {
|
||||
////
|
||||
// aggDraw.setTarget(AggTarget_Screen);
|
||||
//
|
||||
//// aggDraw.target->clear();
|
||||
////
|
||||
//// aggDraw.target->clipBox(0,0,255,383);
|
||||
////
|
||||
// aggDraw.target->lineColor(0, 0, 255, 128);
|
||||
// aggDraw.target->fillColor(0, 0, 255, 128);
|
||||
//// //aggDraw.target->noFill();
|
||||
// aggDraw.target->lineWidth(1.0);
|
||||
// aggDraw.target->roundedRect(10,30,256-10,192-10,4);
|
||||
////
|
||||
//// aggDraw.target->setFont("verdana18_bold");
|
||||
//// aggDraw.target->renderText(60,60, "testing testing testing");
|
||||
////
|
||||
//// // Gradients (Aqua Buttons)
|
||||
//// //=======================================
|
||||
////// m_graphics.font("Verdana", 20.0, false, false, TAGG2D::VectorFontCache);
|
||||
//// double xb1 = 10;
|
||||
//// double yb1 = 80;
|
||||
//// double xb2 = xb1 + 150;
|
||||
//// double yb2 = yb1 + 36;
|
||||
////
|
||||
//// aggDraw.target->fillColor(0,50,180,180);
|
||||
//// aggDraw.target->lineColor(0,0,80, 255);
|
||||
//// aggDraw.target->lineWidth(1.0);
|
||||
//// aggDraw.target->roundedRect(xb1, yb1, xb2, yb2, 12, 18);
|
||||
////
|
||||
//// aggDraw.target->lineColor(0,0,0,0);
|
||||
//// aggDraw.target->fillLinearGradient(xb1, yb1, xb1, yb1+30,
|
||||
//// agg::rgba8(100,200,255,255),
|
||||
//// agg::rgba8(255,255,255,0));
|
||||
//// aggDraw.target->roundedRect(xb1+3, yb1+2.5, xb2-3, yb1+30, 9, 18, 1, 1);
|
||||
////
|
||||
//// aggDraw.target->fillColor(0,0,50, 200);
|
||||
//// aggDraw.target->noLine();
|
||||
/////* m_graphics.textAlignment(TAGG2D::AlignCenter, TAGG2D::AlignCenter);
|
||||
//// m_graphics.text((xb1 + xb2) / 2.0, (yb1 + yb2) / 2.0, "Aqua Button", true, 0.0, 0.0);
|
||||
////*/
|
||||
//// aggDraw.target->fillLinearGradient(xb1, yb2-20, xb1, yb2-3,
|
||||
//// agg::rgba8(0, 0, 255,0),
|
||||
//// agg::rgba8(100,255,255,255));
|
||||
//// aggDraw.target->roundedRect(xb1+3, yb2-20, xb2-3, yb2-2, 1, 1, 9, 18);
|
||||
////
|
||||
//// // Basic Shapes -- Ellipse
|
||||
//// //===========================================
|
||||
//// aggDraw.target->lineWidth(3.5);
|
||||
//// aggDraw.target->lineColor(20, 80, 80);
|
||||
//// aggDraw.target->fillColor(200, 255, 80, 200);
|
||||
//// aggDraw.target->ellipse(150, 200, 50, 90);
|
||||
////
|
||||
//// // Paths
|
||||
//// //===========================================
|
||||
//// aggDraw.target->resetPath();
|
||||
//// aggDraw.target->fillColor(255, 0, 0, 100);
|
||||
//// aggDraw.target->lineColor(0, 0, 255, 100);
|
||||
//// aggDraw.target->lineWidth(2);
|
||||
//// aggDraw.target->moveTo(300/2, 200/2);
|
||||
//// aggDraw.target->horLineRel(-150/2);
|
||||
//// aggDraw.target->arcRel(150/2, 150/2, 0, 1, 0, 150/2, -150/2);
|
||||
//// aggDraw.target->closePolygon();
|
||||
//// aggDraw.target->drawPath();
|
||||
////
|
||||
//// aggDraw.target->resetPath();
|
||||
//// aggDraw.target->fillColor(255, 255, 0, 100);
|
||||
//// aggDraw.target->lineColor(0, 0, 255, 100);
|
||||
//// aggDraw.target->lineWidth(2);
|
||||
//// aggDraw.target->moveTo(275/2, 175/2);
|
||||
//// aggDraw.target->verLineRel(-150/2);
|
||||
//// aggDraw.target->arcRel(150/2, 150/2, 0, 0, 0, -150/2, 150/2);
|
||||
//// aggDraw.target->closePolygon();
|
||||
//// aggDraw.target->drawPath();
|
||||
////
|
||||
//// aggDraw.target->resetPath();
|
||||
//// aggDraw.target->noFill();
|
||||
//// aggDraw.target->lineColor(127, 0, 0);
|
||||
//// aggDraw.target->lineWidth(5);
|
||||
//// aggDraw.target->moveTo(600/2, 350/2);
|
||||
//// aggDraw.target->lineRel(50/2, -25/2);
|
||||
//// aggDraw.target->arcRel(25/2, 25/2, aggDraw.target->deg2Rad(-30), 0, 1, 50/2, -25/2);
|
||||
//// aggDraw.target->lineRel(50/2, -25/2);
|
||||
//// aggDraw.target->arcRel(25/2, 50/2, aggDraw.target->deg2Rad(-30), 0, 1, 50/2, -25/2);
|
||||
//// aggDraw.target->lineRel(50/2, -25/2);
|
||||
//// aggDraw.target->arcRel(25/2, 75/2, aggDraw.target->deg2Rad(-30), 0, 1, 50/2, -25/2);
|
||||
//// aggDraw.target->lineRel(50, -25);
|
||||
//// aggDraw.target->arcRel(25/2, 100/2, aggDraw.target->deg2Rad(-30), 0, 1, 50/2, -25/2);
|
||||
//// aggDraw.target->lineRel(50/2, -25/2);
|
||||
//// aggDraw.target->drawPath();
|
||||
//}
|
||||
////
|
||||
|
||||
|
||||
//
|
||||
////========================
|
||||
////testing stufff
|
||||
//
|
||||
//int width = 256;
|
||||
//int height = 384;
|
||||
//
|
||||
//Agg2D m_graphics;
|
||||
//
|
||||
//void AGGDraw(unsigned char * buffer)
|
||||
// {
|
||||
// m_graphics.attach(buffer,
|
||||
// 256,
|
||||
// 384,
|
||||
// 512);
|
||||
//
|
||||
// m_graphics.clearAll(255, 255, 255);
|
||||
// //m_graphics.clearAll(0, 0, 0);
|
||||
//
|
||||
// //m_graphics.blendMode(TAGG2D::BlendSub);
|
||||
// //m_graphics.blendMode(TAGG2D::BlendAdd);
|
||||
//
|
||||
// m_graphics.antiAliasGamma(1.4);
|
||||
//
|
||||
// // Set flipText(true) if you have the Y axis upside down.
|
||||
// //m_graphics.flipText(true);
|
||||
//
|
||||
//
|
||||
// // ClipBox.
|
||||
// //m_graphics.clipBox(50, 50, rbuf_window().width() - 50, rbuf_window().height() - 50);
|
||||
//
|
||||
// // Transfornations - Rotate around (300,300) to 5 degree
|
||||
// //m_graphics.translate(-300, -300);
|
||||
// //m_graphics.rotate(TAGG2D::deg2Rad(5.0));
|
||||
// //m_graphics.translate(300, 300);
|
||||
//
|
||||
// // Viewport - set 0,0,600,600 to the actual window size
|
||||
// // preserving aspect ratio and placing the viewport in the center.
|
||||
// // To ignore aspect ratio use TAGG2D::Anisotropic
|
||||
// // Note that the viewport just adds transformations to the current
|
||||
// // affine matrix. So that, set the viewport *after* all transformations!
|
||||
// m_graphics.viewport(0, 0, 600, 600,
|
||||
// 0, 0, width, height,
|
||||
// //TAGG2D::Anisotropic);
|
||||
// TAGG2D::XMidYMid);
|
||||
//
|
||||
//
|
||||
// // Rounded Rect
|
||||
// m_graphics.lineColor(0, 0, 0);
|
||||
// m_graphics.noFill();
|
||||
// m_graphics.roundedRect(0.5, 0.5, 600-0.5, 600-0.5, 20.0);
|
||||
///*
|
||||
//
|
||||
// // Reglar Text
|
||||
// m_graphics.font("Times New Roman", 14.0, false, false);
|
||||
// m_graphics.fillColor(0, 0, 0);
|
||||
// m_graphics.noLine();
|
||||
// m_graphics.text(100, 20, "Regular Raster Text -- Fast, but can't be rotated");
|
||||
//
|
||||
// // Outlined Text
|
||||
// m_graphics.font("Times New Roman", 50.0, false, false, TAGG2D::VectorFontCache);
|
||||
// m_graphics.lineColor(50, 0, 0);
|
||||
// m_graphics.fillColor(180, 200, 100);
|
||||
// m_graphics.lineWidth(1.0);
|
||||
// m_graphics.text(100.5, 50.5, "Outlined Text");
|
||||
//
|
||||
// // Text Alignment
|
||||
// m_graphics.line(250.5-150, 150.5, 250.5+150, 150.5);
|
||||
// m_graphics.line(250.5, 150.5-20, 250.5, 150.5+20);
|
||||
// m_graphics.line(250.5-150, 200.5, 250.5+150, 200.5);
|
||||
// m_graphics.line(250.5, 200.5-20, 250.5, 200.5+20);
|
||||
// m_graphics.line(250.5-150, 250.5, 250.5+150, 250.5);
|
||||
// m_graphics.line(250.5, 250.5-20, 250.5, 250.5+20);
|
||||
// m_graphics.line(250.5-150, 300.5, 250.5+150, 300.5);
|
||||
// m_graphics.line(250.5, 300.5-20, 250.5, 300.5+20);
|
||||
// m_graphics.line(250.5-150, 350.5, 250.5+150, 350.5);
|
||||
// m_graphics.line(250.5, 350.5-20, 250.5, 350.5+20);
|
||||
// m_graphics.line(250.5-150, 400.5, 250.5+150, 400.5);
|
||||
// m_graphics.line(250.5, 400.5-20, 250.5, 400.5+20);
|
||||
// m_graphics.line(250.5-150, 450.5, 250.5+150, 450.5);
|
||||
// m_graphics.line(250.5, 450.5-20, 250.5, 450.5+20);
|
||||
// m_graphics.line(250.5-150, 500.5, 250.5+150, 500.5);
|
||||
// m_graphics.line(250.5, 500.5-20, 250.5, 500.5+20);
|
||||
// m_graphics.line(250.5-150, 550.5, 250.5+150, 550.5);
|
||||
// m_graphics.line(250.5, 550.5-20, 250.5, 550.5+20);
|
||||
//*/
|
||||
///*
|
||||
// m_graphics.fillColor(100, 50, 50);
|
||||
// m_graphics.noLine();
|
||||
// //m_graphics.textHints(false);
|
||||
// m_graphics.font("Times New Roman", 40.0, false, false, TAGG2D::VectorFontCache);
|
||||
//
|
||||
// m_graphics.textAlignment(TAGG2D::AlignLeft, TAGG2D::AlignBottom);
|
||||
// m_graphics.text(250.0, 150.0, "Left-Bottom", true, 0, 0);
|
||||
//
|
||||
// m_graphics.textAlignment(TAGG2D::AlignCenter, TAGG2D::AlignBottom);
|
||||
// m_graphics.text(250.0, 200.0, "Center-Bottom", true, 0, 0);
|
||||
//
|
||||
// m_graphics.textAlignment(TAGG2D::AlignRight, TAGG2D::AlignBottom);
|
||||
// m_graphics.text(250.0, 250.0, "Right-Bottom", true, 0, 0);
|
||||
//
|
||||
// m_graphics.textAlignment(TAGG2D::AlignLeft, TAGG2D::AlignCenter);
|
||||
// m_graphics.text(250.0, 300.0, "Left-Center", true, 0, 0);
|
||||
//
|
||||
// m_graphics.textAlignment(TAGG2D::AlignCenter, TAGG2D::AlignCenter);
|
||||
// m_graphics.text(250.0, 350.0, "Center-Center", true, 0, 0);
|
||||
//
|
||||
// m_graphics.textAlignment(TAGG2D::AlignRight, TAGG2D::AlignCenter);
|
||||
// m_graphics.text(250.0, 400.0, "Right-Center", true, 0, 0);
|
||||
//
|
||||
// m_graphics.textAlignment(TAGG2D::AlignLeft, TAGG2D::AlignTop);
|
||||
// m_graphics.text(250.0, 450.0, "Left-Top", true, 0, 0);
|
||||
//
|
||||
// m_graphics.textAlignment(TAGG2D::AlignCenter, TAGG2D::AlignTop);
|
||||
// m_graphics.text(250.0, 500.0, "Center-Top", true, 0, 0);
|
||||
//
|
||||
// m_graphics.textAlignment(TAGG2D::AlignRight, TAGG2D::AlignTop);
|
||||
// m_graphics.text(250.0, 550.0, "Right-Top", true, 0, 0);
|
||||
//
|
||||
//*/
|
||||
// // Gradients (Aqua Buttons)
|
||||
// //=======================================
|
||||
// m_graphics.font("Verdana", 20.0, false, false, TAGG2D::VectorFontCache);
|
||||
// double xb1 = 400;
|
||||
// double yb1 = 80;
|
||||
// double xb2 = xb1 + 150;
|
||||
// double yb2 = yb1 + 36;
|
||||
//
|
||||
// m_graphics.fillColor(TAGG2D::Color(0,50,180,180));
|
||||
// m_graphics.lineColor(TAGG2D::Color(0,0,80, 255));
|
||||
// m_graphics.lineWidth(1.0);
|
||||
// m_graphics.roundedRect(xb1, yb1, xb2, yb2, 12, 18);
|
||||
//
|
||||
// m_graphics.lineColor(TAGG2D::Color(0,0,0,0));
|
||||
// m_graphics.fillLinearGradient(xb1, yb1, xb1, yb1+30,
|
||||
// TAGG2D::Color(100,200,255,255),
|
||||
// TAGG2D::Color(255,255,255,0));
|
||||
// m_graphics.roundedRect(xb1+3, yb1+2.5, xb2-3, yb1+30, 9, 18, 1, 1);
|
||||
//
|
||||
// m_graphics.fillColor(TAGG2D::Color(0,0,50, 200));
|
||||
// m_graphics.noLine();
|
||||
///* m_graphics.textAlignment(TAGG2D::AlignCenter, TAGG2D::AlignCenter);
|
||||
// m_graphics.text((xb1 + xb2) / 2.0, (yb1 + yb2) / 2.0, "Aqua Button", true, 0.0, 0.0);
|
||||
//*/
|
||||
// m_graphics.fillLinearGradient(xb1, yb2-20, xb1, yb2-3,
|
||||
// TAGG2D::Color(0, 0, 255,0),
|
||||
// TAGG2D::Color(100,255,255,255));
|
||||
// m_graphics.roundedRect(xb1+3, yb2-20, xb2-3, yb2-2, 1, 1, 9, 18);
|
||||
//
|
||||
//
|
||||
// // Aqua Button Pressed
|
||||
// xb1 = 400;
|
||||
// yb1 = 30;
|
||||
// xb2 = xb1 + 150;
|
||||
// yb2 = yb1 + 36;
|
||||
//
|
||||
// m_graphics.fillColor(TAGG2D::Color(0,50,180,180));
|
||||
// m_graphics.lineColor(TAGG2D::Color(0,0,0, 255));
|
||||
// m_graphics.lineWidth(2.0);
|
||||
// m_graphics.roundedRect(xb1, yb1, xb2, yb2, 12, 18);
|
||||
//
|
||||
// m_graphics.lineColor(TAGG2D::Color(0,0,0,0));
|
||||
// m_graphics.fillLinearGradient(xb1, yb1+2, xb1, yb1+25,
|
||||
// TAGG2D::Color(60, 160,255,255),
|
||||
// TAGG2D::Color(100,255,255,0));
|
||||
// m_graphics.roundedRect(xb1+3, yb1+2.5, xb2-3, yb1+30, 9, 18, 1, 1);
|
||||
//
|
||||
// m_graphics.fillColor(TAGG2D::Color(0,0,50, 255));
|
||||
// m_graphics.noLine();
|
||||
///* m_graphics.textAlignment(TAGG2D::AlignCenter, TAGG2D::AlignCenter);
|
||||
// m_graphics.text((xb1 + xb2) / 2.0, (yb1 + yb2) / 2.0, "Aqua Pressed", 0.0, 0.0);
|
||||
//*/
|
||||
// m_graphics.fillLinearGradient(xb1, yb2-25, xb1, yb2-5,
|
||||
// TAGG2D::Color(0, 180,255,0),
|
||||
// TAGG2D::Color(0, 200,255,255));
|
||||
// m_graphics.roundedRect(xb1+3, yb2-25, xb2-3, yb2-2, 1, 1, 9, 18);
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
// // Basic Shapes -- Ellipse
|
||||
// //===========================================
|
||||
// m_graphics.lineWidth(3.5);
|
||||
// m_graphics.lineColor(20, 80, 80);
|
||||
// m_graphics.fillColor(200, 255, 80, 200);
|
||||
// m_graphics.ellipse(450, 200, 50, 90);
|
||||
//
|
||||
//
|
||||
// // Paths
|
||||
// //===========================================
|
||||
// m_graphics.resetPath();
|
||||
// m_graphics.fillColor(255, 0, 0, 100);
|
||||
// m_graphics.lineColor(0, 0, 255, 100);
|
||||
// m_graphics.lineWidth(2);
|
||||
// m_graphics.moveTo(300/2, 200/2);
|
||||
// m_graphics.horLineRel(-150/2);
|
||||
// m_graphics.arcRel(150/2, 150/2, 0, 1, 0, 150/2, -150/2);
|
||||
// m_graphics.closePolygon();
|
||||
// m_graphics.drawPath();
|
||||
//
|
||||
// m_graphics.resetPath();
|
||||
// m_graphics.fillColor(255, 255, 0, 100);
|
||||
// m_graphics.lineColor(0, 0, 255, 100);
|
||||
// m_graphics.lineWidth(2);
|
||||
// m_graphics.moveTo(275/2, 175/2);
|
||||
// m_graphics.verLineRel(-150/2);
|
||||
// m_graphics.arcRel(150/2, 150/2, 0, 0, 0, -150/2, 150/2);
|
||||
// m_graphics.closePolygon();
|
||||
// m_graphics.drawPath();
|
||||
//
|
||||
//
|
||||
// m_graphics.resetPath();
|
||||
// m_graphics.noFill();
|
||||
// m_graphics.lineColor(127, 0, 0);
|
||||
// m_graphics.lineWidth(5);
|
||||
// m_graphics.moveTo(600/2, 350/2);
|
||||
// m_graphics.lineRel(50/2, -25/2);
|
||||
// m_graphics.arcRel(25/2, 25/2, TAGG2D::deg2Rad(-30), 0, 1, 50/2, -25/2);
|
||||
// m_graphics.lineRel(50/2, -25/2);
|
||||
// m_graphics.arcRel(25/2, 50/2, TAGG2D::deg2Rad(-30), 0, 1, 50/2, -25/2);
|
||||
// m_graphics.lineRel(50/2, -25/2);
|
||||
// m_graphics.arcRel(25/2, 75/2, TAGG2D::deg2Rad(-30), 0, 1, 50/2, -25/2);
|
||||
// m_graphics.lineRel(50, -25);
|
||||
// m_graphics.arcRel(25/2, 100/2, TAGG2D::deg2Rad(-30), 0, 1, 50/2, -25/2);
|
||||
// m_graphics.lineRel(50/2, -25/2);
|
||||
// m_graphics.drawPath();
|
||||
//
|
||||
//
|
||||
// // Master Alpha. From now on everything will be translucent
|
||||
// //===========================================
|
||||
// m_graphics.masterAlpha(0.85);
|
||||
//
|
||||
//
|
||||
// // Image Transformations
|
||||
// //===========================================
|
||||
///* TAGG2D::Image img(rbuf_img(0).buf(),
|
||||
// rbuf_img(0).width(),
|
||||
// rbuf_img(0).height(),
|
||||
// rbuf_img(0).stride());
|
||||
// m_graphics.imageFilter(TAGG2D::Bilinear);
|
||||
//
|
||||
// //m_graphics.imageResample(TAGG2D::NoResample);
|
||||
// //m_graphics.imageResample(TAGG2D::ResampleAlways);
|
||||
// m_graphics.imageResample(TAGG2D::ResampleOnZoomOut);
|
||||
//
|
||||
// // Set the initial image blending operation as BlendDst, that actually
|
||||
// // does nothing.
|
||||
// //-----------------
|
||||
// m_graphics.imageBlendMode(TAGG2D::BlendDst);
|
||||
//
|
||||
//
|
||||
// // Transform the whole image to the destination rectangle
|
||||
// //-----------------
|
||||
// //m_graphics.transformImage(img, 450, 200, 595, 350);
|
||||
//
|
||||
// // Transform the rectangular part of the image to the destination rectangle
|
||||
// //-----------------
|
||||
// //m_graphics.transformImage(img, 60, 60, img.width()-60, img.height()-60,
|
||||
// // 450, 200, 595, 350);
|
||||
//
|
||||
// // Transform the whole image to the destination parallelogram
|
||||
// //-----------------
|
||||
// //double parl[6] = { 450, 200, 595, 220, 575, 350 };
|
||||
// //m_graphics.transformImage(img, parl);
|
||||
//
|
||||
// // Transform the rectangular part of the image to the destination parallelogram
|
||||
// //-----------------
|
||||
// //double parl[6] = { 450, 200, 595, 220, 575, 350 };
|
||||
// //m_graphics.transformImage(img, 60, 60, img.width()-60, img.height()-60, parl);
|
||||
//
|
||||
// // Transform image to the destination path. The scale is determined by a rectangle
|
||||
// //-----------------
|
||||
// //m_graphics.resetPath();
|
||||
// //m_graphics.moveTo(450, 200);
|
||||
// //m_graphics.cubicCurveTo(595, 220, 575, 350, 595, 350);
|
||||
// //m_graphics.lineTo(470, 340);
|
||||
// //m_graphics.transformImagePath(img, 450, 200, 595, 350);
|
||||
//
|
||||
//
|
||||
// // Transform image to the destination path.
|
||||
// // The scale is determined by a rectangle
|
||||
// //-----------------
|
||||
// m_graphics.resetPath();
|
||||
// m_graphics.moveTo(450, 200);
|
||||
// m_graphics.cubicCurveTo(595, 220, 575, 350, 595, 350);
|
||||
// m_graphics.lineTo(470, 340);
|
||||
// m_graphics.transformImagePath(img, 60, 60, img.width()-60, img.height()-60,
|
||||
// 450, 200, 595, 350);
|
||||
//
|
||||
// // Transform image to the destination path.
|
||||
// // The transformation is determined by a parallelogram
|
||||
// //m_graphics.resetPath();
|
||||
// //m_graphics.moveTo(450, 200);
|
||||
// //m_graphics.cubicCurveTo(595, 220, 575, 350, 595, 350);
|
||||
// //m_graphics.lineTo(470, 340);
|
||||
// //double parl[6] = { 450, 200, 595, 220, 575, 350 };
|
||||
// //m_graphics.transformImagePath(img, parl);
|
||||
//
|
||||
// // Transform the rectangular part of the image to the destination path.
|
||||
// // The transformation is determined by a parallelogram
|
||||
// //m_graphics.resetPath();
|
||||
// //m_graphics.moveTo(450, 200);
|
||||
// //m_graphics.cubicCurveTo(595, 220, 575, 350, 595, 350);
|
||||
// //m_graphics.lineTo(470, 340);
|
||||
// //double parl[6] = { 450, 200, 595, 220, 575, 350 };
|
||||
// //m_graphics.transformImagePath(img, 60, 60, img.width()-60, img.height()-60, parl);
|
||||
//*/
|
||||
//
|
||||
// // Add/Sub/Contrast Blending Modes
|
||||
// m_graphics.noLine();
|
||||
// m_graphics.fillColor(70, 70, 0);
|
||||
// m_graphics.blendMode(TAGG2D::BlendAdd);
|
||||
// m_graphics.ellipse(500, 280, 20, 40);
|
||||
//
|
||||
// m_graphics.fillColor(255, 255, 255);
|
||||
// m_graphics.blendMode(TAGG2D::BlendContrast);
|
||||
// m_graphics.ellipse(500+40, 280, 20, 40);
|
||||
//
|
||||
//
|
||||
//
|
||||
// // Radial gradient.
|
||||
// m_graphics.blendMode(TAGG2D::BlendAlpha);
|
||||
// m_graphics.fillRadialGradient(400, 500, 40,
|
||||
// TAGG2D::Color(255, 255, 0, 0),
|
||||
// TAGG2D::Color(0, 0, 127),
|
||||
// TAGG2D::Color(0, 255, 0, 0));
|
||||
// m_graphics.ellipse(400, 500, 40, 40);
|
||||
//
|
||||
// }
|
||||
//
|
||||
Executable
+674
@@ -0,0 +1,674 @@
|
||||
/*
|
||||
The MIT License
|
||||
|
||||
Copyright (C) 2009-2010 DeSmuME team
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
*/
|
||||
|
||||
|
||||
//This file contains code designed to be used by hud and lua systems in any emulator
|
||||
|
||||
|
||||
#ifndef _AGGDRAW_H_
|
||||
#define _AGGDRAW_H_
|
||||
|
||||
#include "agg_color_rgba.h"
|
||||
#include "agg_rendering_buffer.h"
|
||||
|
||||
#include "agg_renderer_base.h"
|
||||
#include "agg_renderer_primitives.h"
|
||||
#include "agg_renderer_scanline.h"
|
||||
#include "agg_bounding_rect.h"
|
||||
|
||||
#include "agg_renderer_mclip.h"
|
||||
#include "agg_renderer_outline_aa.h"
|
||||
#include "agg_renderer_markers.h"
|
||||
|
||||
#include "agg_pixfmt_rgb.h"
|
||||
#include "agg_pixfmt_rgba.h"
|
||||
#include "agg_pixfmt_rgb_packed.h"
|
||||
|
||||
#include "agg2d.h"
|
||||
|
||||
typedef agg::rgba8 AggColor;
|
||||
|
||||
namespace agg
|
||||
{
|
||||
//NOTE - these blenders are necessary to change the rgb order from the defaults, which are incorrect for us
|
||||
|
||||
//this custom blender does more correct blending math than the default
|
||||
//which is necessary or else drawing transparent pixels on (31,31,31) will yield (30,30,30)
|
||||
struct my_blender_rgb555_pre
|
||||
{
|
||||
typedef rgba8 color_type;
|
||||
typedef color_type::value_type value_type;
|
||||
typedef color_type::calc_type calc_type;
|
||||
typedef int16u pixel_type;
|
||||
|
||||
static AGG_INLINE void blend_pix(pixel_type* p,
|
||||
unsigned cr, unsigned cg, unsigned cb,
|
||||
unsigned alpha,
|
||||
unsigned cover)
|
||||
{
|
||||
//not sure whether this is right...
|
||||
alpha = color_type::base_mask - alpha;
|
||||
pixel_type rgb = *p;
|
||||
calc_type b = (rgb >> 10) & 31;
|
||||
calc_type g = (rgb >> 5) & 31;
|
||||
calc_type r = (rgb ) & 31;
|
||||
b = ((b+1)*(alpha+1) + (cb)*(cover)-1)>>8;
|
||||
g = ((g+1)*(alpha+1) + (cg)*(cover)-1)>>8;
|
||||
r = ((r+1)*(alpha+1) + (cr)*(cover)-1)>>8;
|
||||
*p = (b<<10)|(g<<5)|r;
|
||||
}
|
||||
|
||||
static AGG_INLINE pixel_type make_pix(unsigned r, unsigned g, unsigned b)
|
||||
{
|
||||
return (pixel_type)(((b & 0xF8) << 7) |
|
||||
((g & 0xF8) << 2) |
|
||||
(r >> 3) | 0x8000);
|
||||
}
|
||||
|
||||
static AGG_INLINE color_type make_color(pixel_type p)
|
||||
{
|
||||
return color_type((p << 3) & 0xF8,
|
||||
(p >> 2) & 0xF8,
|
||||
(p >> 7) & 0xF8);
|
||||
}
|
||||
};
|
||||
|
||||
struct my_blender_rgb555
|
||||
{
|
||||
typedef rgba8 color_type;
|
||||
typedef color_type::value_type value_type;
|
||||
typedef color_type::calc_type calc_type;
|
||||
typedef int16u pixel_type;
|
||||
|
||||
static AGG_INLINE void blend_pix(pixel_type* p,
|
||||
unsigned cr, unsigned cg, unsigned cb,
|
||||
unsigned alpha,
|
||||
unsigned)
|
||||
{
|
||||
pixel_type rgb = *p;
|
||||
calc_type b = (rgb >> 7) & 0xF8;
|
||||
calc_type g = (rgb >> 2) & 0xF8;
|
||||
calc_type r = (rgb << 3) & 0xF8;
|
||||
*p = (pixel_type)
|
||||
(((((cb - b) * alpha + (b << 8)) >> 1) & 0x7C00) |
|
||||
((((cg - g) * alpha + (g << 8)) >> 6) & 0x03E0) |
|
||||
(((cr - r) * alpha + (r << 8)) >> 11) | 0x8000);
|
||||
}
|
||||
|
||||
static AGG_INLINE pixel_type make_pix(unsigned r, unsigned g, unsigned b)
|
||||
{
|
||||
return (pixel_type)(((b & 0xF8) << 7) |
|
||||
((g & 0xF8) << 2) |
|
||||
(r >> 3) | 0x8000);
|
||||
}
|
||||
|
||||
static AGG_INLINE color_type make_color(pixel_type p)
|
||||
{
|
||||
return color_type((p << 3) & 0xF8,
|
||||
(p >> 2) & 0xF8,
|
||||
(p >> 7) & 0xF8);
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
//this is a prototype span generator which should be able to generate 8888 and 555 spans
|
||||
//it would be used in agg2d.inl renderImage()
|
||||
//but it isn't being used yet.
|
||||
//this will need to be completed before we can use 555 as a source imge
|
||||
template<class Order> class span_simple_blur_rgb24
|
||||
{
|
||||
public:
|
||||
//--------------------------------------------------------------------
|
||||
typedef rgba8 color_type;
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
span_simple_blur_rgb24() : m_source_image(0) {}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
span_simple_blur_rgb24(const rendering_buffer& src) :
|
||||
m_source_image(&src) {}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void source_image(const rendering_buffer& src) { m_source_image = &src; }
|
||||
const rendering_buffer& source_image() const { return *m_source_image; }
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void prepare() {}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void generate(color_type* span, int x, int y, int len)
|
||||
{
|
||||
if(y < 1 || y >= int(m_source_image->height() - 1))
|
||||
{
|
||||
do
|
||||
{
|
||||
*span++ = rgba8(0,0,0,0);
|
||||
}
|
||||
while(--len);
|
||||
return;
|
||||
}
|
||||
|
||||
do
|
||||
{
|
||||
int color[4];
|
||||
color[0] = color[1] = color[2] = color[3] = 0;
|
||||
if(x > 0 && x < int(m_source_image->width()-1))
|
||||
{
|
||||
int i = 3;
|
||||
do
|
||||
{
|
||||
const int8u* ptr = m_source_image->row_ptr(y - i + 2) + (x - 1) * 3;
|
||||
|
||||
color[0] += *ptr++;
|
||||
color[1] += *ptr++;
|
||||
color[2] += *ptr++;
|
||||
color[3] += 255;
|
||||
|
||||
color[0] += *ptr++;
|
||||
color[1] += *ptr++;
|
||||
color[2] += *ptr++;
|
||||
color[3] += 255;
|
||||
|
||||
color[0] += *ptr++;
|
||||
color[1] += *ptr++;
|
||||
color[2] += *ptr++;
|
||||
color[3] += 255;
|
||||
}
|
||||
while(--i);
|
||||
color[0] /= 9;
|
||||
color[1] /= 9;
|
||||
color[2] /= 9;
|
||||
color[3] /= 9;
|
||||
}
|
||||
*span++ = rgba8(color[Order::R], color[Order::G], color[Order::B], color[3]);
|
||||
++x;
|
||||
}
|
||||
while(--len);
|
||||
}
|
||||
|
||||
private:
|
||||
const rendering_buffer* m_source_image;
|
||||
};
|
||||
|
||||
typedef pixfmt_alpha_blend_rgb_packed<my_blender_rgb555_pre, rendering_buffer> my_pixfmt_rgb555_pre; //----pixfmt_rgb555_pre
|
||||
|
||||
typedef pixfmt_alpha_blend_rgb_packed<my_blender_rgb555, rendering_buffer> my_pixfmt_rgb555; //----pixfmt_rgb555_pre
|
||||
}
|
||||
|
||||
|
||||
|
||||
typedef PixFormatSetDeclaration<agg::my_pixfmt_rgb555,agg::my_pixfmt_rgb555_pre,agg::span_simple_blur_rgb24<agg::order_rgba> > T_AGG_PF_RGB555;
|
||||
typedef PixFormatSetDeclaration<agg::pixfmt_bgra32,agg::pixfmt_bgra32_pre,agg::span_simple_blur_rgb24<agg::order_rgba> > T_AGG_PF_RGBA;
|
||||
class AggDrawTarget
|
||||
{
|
||||
public:
|
||||
AggDrawTarget()
|
||||
: empty(true)
|
||||
{
|
||||
}
|
||||
|
||||
protected:
|
||||
void dirty() { empty = false; }
|
||||
void undirty() { empty = true; }
|
||||
|
||||
public:
|
||||
|
||||
bool empty;
|
||||
|
||||
virtual void clear() = 0;
|
||||
|
||||
virtual agg::rendering_buffer & buf() = 0;
|
||||
|
||||
//returns an image for this target. you must provide the pixel type, but if it is wrong,
|
||||
//then you have just created trouble for yourself
|
||||
AGG2D_IMAGE_TEMPLATE TIMAGE image() { return TIMAGE(buf()); }
|
||||
|
||||
// Setup
|
||||
virtual void attach(unsigned char* buf, unsigned width, unsigned height, int stride) = 0;
|
||||
// virtual void attach(Agg2DBase::Image& img) {attach(img);};
|
||||
|
||||
virtual void clipBox(double x1, double y1, double x2, double y2) = 0;
|
||||
virtual Agg2DBase::RectD clipBox() const = 0;
|
||||
|
||||
virtual void clearAll(AggColor c) = 0;
|
||||
virtual void clearAll(unsigned r, unsigned g, unsigned b, unsigned a = 255) = 0;
|
||||
|
||||
virtual void clearClipBox(AggColor c) = 0;
|
||||
virtual void clearClipBox(unsigned r, unsigned g, unsigned b, unsigned a = 255) = 0;
|
||||
|
||||
// virtual unsigned width() const { return Agg2DBase::m_rbuf.width(); }
|
||||
// virtual unsigned height() const { return Agg2DBase::m_rbuf.height(); }
|
||||
|
||||
// Conversions
|
||||
virtual void worldToScreen(double& x, double& y) const = 0;
|
||||
virtual void screenToWorld(double& x, double& y) const = 0;
|
||||
virtual double worldToScreen(double scalar) const = 0;
|
||||
virtual double screenToWorld(double scalar) const = 0;
|
||||
virtual void alignPoint(double& x, double& y) const = 0;
|
||||
virtual bool inBox(double worldX, double worldY) const = 0;
|
||||
|
||||
// General Attributes
|
||||
virtual void blendMode(Agg2DBase::BlendMode m) = 0;
|
||||
virtual Agg2DBase::BlendMode blendMode() = 0;
|
||||
|
||||
virtual void imageBlendMode(Agg2DBase::BlendMode m) = 0;
|
||||
virtual Agg2DBase::BlendMode imageBlendMode() = 0;
|
||||
|
||||
virtual void imageBlendColor(AggColor c) = 0;
|
||||
virtual void imageBlendColor(unsigned r, unsigned g, unsigned b, unsigned a = 255) = 0;
|
||||
virtual AggColor imageBlendColor() = 0;
|
||||
|
||||
virtual void masterAlpha(double a) = 0;
|
||||
virtual double masterAlpha() = 0;
|
||||
|
||||
virtual void antiAliasGamma(double g) = 0;
|
||||
virtual double antiAliasGamma() = 0;
|
||||
|
||||
// virtual void font(const agg::int8u* font) { m_font = font; }
|
||||
// const agg::int8u* font() { return m_font; }
|
||||
|
||||
virtual void fillColor(AggColor c) = 0;
|
||||
virtual void fillColor(unsigned r, unsigned g, unsigned b, unsigned a = 255) = 0;
|
||||
virtual void noFill() = 0;
|
||||
|
||||
virtual void lineColor(AggColor c) = 0;
|
||||
virtual void lineColor(unsigned r, unsigned g, unsigned b, unsigned a = 255) = 0;
|
||||
virtual void noLine() = 0;
|
||||
|
||||
virtual void transformImage(const Agg2DBase::Image<T_AGG_PF_RGBA> &img, double dstX1, double dstY1, double dstX2, double dstY2) = 0;
|
||||
//virtual void transformImage(const Agg2DBase::Image<T_AGG_PF_RGB555> &img, double dstX1, double dstY1, double dstX2, double dstY2) = 0;
|
||||
|
||||
virtual AggColor fillColor() = 0;
|
||||
virtual AggColor lineColor() = 0;
|
||||
|
||||
virtual void fillLinearGradient(double x1, double y1, double x2, double y2, AggColor c1, AggColor c2, double profile=1.0) = 0;
|
||||
virtual void lineLinearGradient(double x1, double y1, double x2, double y2, AggColor c1, AggColor c2, double profile=1.0) = 0;
|
||||
|
||||
virtual void fillRadialGradient(double x, double y, double r, AggColor c1, AggColor c2, double profile=1.0) = 0;
|
||||
virtual void lineRadialGradient(double x, double y, double r, AggColor c1, AggColor c2, double profile=1.0) = 0;
|
||||
|
||||
virtual void fillRadialGradient(double x, double y, double r, AggColor c1, AggColor c2, AggColor c3) = 0;
|
||||
virtual void lineRadialGradient(double x, double y, double r, AggColor c1, AggColor c2, AggColor c3) = 0;
|
||||
|
||||
virtual void fillRadialGradient(double x, double y, double r) = 0;
|
||||
virtual void lineRadialGradient(double x, double y, double r) = 0;
|
||||
|
||||
virtual void lineWidth(double w) = 0;
|
||||
virtual double lineWidth() = 0;
|
||||
|
||||
virtual void lineCap(Agg2DBase::LineCap cap) = 0;
|
||||
virtual Agg2DBase::LineCap lineCap() = 0;
|
||||
|
||||
virtual void lineJoin(Agg2DBase::LineJoin join) = 0;
|
||||
virtual Agg2DBase::LineJoin lineJoin() = 0;
|
||||
|
||||
virtual void fillEvenOdd(bool evenOddFlag) = 0;
|
||||
virtual bool fillEvenOdd() = 0;
|
||||
|
||||
// Transformations
|
||||
virtual Agg2DBase::Transformations transformations() = 0;
|
||||
virtual void transformations(const Agg2DBase::Transformations& tr) = 0;
|
||||
|
||||
virtual const Agg2DBase::Affine& affine() = 0;
|
||||
// virtual void affine(const Agg2DBase::Affine&) = 0;
|
||||
|
||||
virtual void resetTransformations() = 0;
|
||||
virtual void matrix(const Agg2DBase::Affine& tr) = 0;
|
||||
virtual void matrix(const Agg2DBase::Transformations& tr) = 0;
|
||||
virtual void rotate(double angle) = 0;
|
||||
virtual void rotate(double angle, double cx, double cy) = 0;
|
||||
virtual void scale(double s) = 0;
|
||||
virtual void scale(double sx, double sy) = 0;
|
||||
virtual void skew(double sx, double sy) = 0;
|
||||
virtual void translate(double x, double y) = 0;
|
||||
virtual void parallelogram(double x1, double y1, double x2, double y2, const double* para) = 0;
|
||||
virtual void viewport(double worldX1, double worldY1, double worldX2, double worldY2, double screenX1, double screenY1, double screenX2, double screenY2, Agg2DBase::ViewportOption opt=Agg2DBase::XMidYMid, Agg2DBase::WindowFitLogic fl = Agg2DBase::WindowFitLogic_meet) = 0;
|
||||
|
||||
// Basic Shapes
|
||||
virtual void line(double x1, double y1, double x2, double y2) = 0;
|
||||
virtual void triangle(double x1, double y1, double x2, double y2, double x3, double y3) = 0;
|
||||
virtual void rectangle(double x1, double y1, double x2, double y2) = 0;
|
||||
virtual void roundedRect(double x1, double y1, double x2, double y2, double r) = 0;
|
||||
virtual void roundedRect(double x1, double y1, double x2, double y2, double rx, double ry) = 0;
|
||||
virtual void roundedRect(double x1, double y1, double x2, double y2, double rxBottom, double ryBottom, double rxTop, double ryTop) = 0;
|
||||
virtual void ellipse(double cx, double cy, double rx, double ry) = 0;
|
||||
virtual void arc(double cx, double cy, double rx, double ry, double start, double sweep) = 0;
|
||||
virtual void star(double cx, double cy, double r1, double r2, double startAngle, int numRays) = 0;
|
||||
virtual void curve(double x1, double y1, double x2, double y2, double x3, double y3) = 0;
|
||||
virtual void curve(double x1, double y1, double x2, double y2, double x3, double y3, double x4, double y4) = 0;
|
||||
virtual void polygon(double* xy, int numPoints) = 0;
|
||||
virtual void polyline(double* xy, int numPoints) = 0;
|
||||
|
||||
// Path commands
|
||||
virtual void resetPath() = 0;
|
||||
|
||||
virtual void moveTo(double x, double y)= 0;
|
||||
virtual void moveRel(double dx, double dy) = 0;
|
||||
|
||||
virtual void lineTo(double x, double y) = 0;
|
||||
virtual void lineRel(double dx, double dy) = 0;
|
||||
|
||||
virtual void horLineTo(double x) = 0;
|
||||
virtual void horLineRel(double dx) = 0;
|
||||
|
||||
virtual void verLineTo(double y) = 0;
|
||||
virtual void verLineRel(double dy) = 0;
|
||||
|
||||
virtual void arcTo(double rx, double ry,double angle, bool largeArcFlag,bool sweepFlag,double x, double y) = 0;
|
||||
|
||||
virtual void arcRel(double rx, double ry,double angle, bool largeArcFlag,bool sweepFlag,double dx, double dy) = 0;
|
||||
|
||||
virtual void quadricCurveTo(double xCtrl, double yCtrl,double xTo, double yTo) = 0;
|
||||
virtual void quadricCurveRel(double dxCtrl, double dyCtrl,double dxTo, double dyTo) = 0;
|
||||
virtual void quadricCurveTo(double xTo, double yTo) = 0;
|
||||
virtual void quadricCurveRel(double dxTo, double dyTo) = 0;
|
||||
|
||||
virtual void cubicCurveTo(double xCtrl1, double yCtrl1,double xCtrl2, double yCtrl2,double xTo, double yTo) = 0;
|
||||
virtual void cubicCurveRel(double dxCtrl1, double dyCtrl1,double dxCtrl2, double dyCtrl2,double dxTo, double dyTo) = 0;
|
||||
virtual void cubicCurveTo(double xCtrl2, double yCtrl2,double xTo, double yTo) = 0;
|
||||
virtual void cubicCurveRel(double xCtrl2, double yCtrl2,double xTo, double yTo) = 0;
|
||||
|
||||
virtual void addEllipse(double cx, double cy, double rx, double ry, Agg2DBase::Direction dir) = 0;
|
||||
virtual void closePolygon() = 0;
|
||||
|
||||
virtual void drawPath(Agg2DBase::DrawPathFlag flag = Agg2DBase::FillAndStroke) = 0;
|
||||
// virtual void drawPathNoTransform(Agg2DBase::DrawPathFlag flag = Agg2DBase::FillAndStroke) = 0;
|
||||
|
||||
// Image Transformations
|
||||
virtual void imageFilter(Agg2DBase::ImageFilter f) = 0;
|
||||
virtual Agg2DBase::ImageFilter imageFilter() = 0;
|
||||
|
||||
virtual void imageResample(Agg2DBase::ImageResample f) = 0;
|
||||
virtual Agg2DBase::ImageResample imageResample() = 0;
|
||||
static const agg::int8u* lookupFont(const std::string& name);
|
||||
virtual void setFont(const std::string& name) = 0;
|
||||
virtual void renderText(double dstX, double dstY, const std::string& str) = 0;
|
||||
virtual void renderTextDropshadowed(double dstX, double dstY, const std::string& str)
|
||||
{
|
||||
AggColor lineColorOld = lineColor();
|
||||
if(lineColorOld.r+lineColorOld.g+lineColorOld.b<192)
|
||||
lineColor(255-lineColorOld.r,255-lineColorOld.g,255-lineColorOld.b);
|
||||
else
|
||||
lineColor(0,0,0);
|
||||
renderText(dstX-1,dstY-1,str);
|
||||
renderText(dstX,dstY-1,str);
|
||||
renderText(dstX+1,dstY-1,str);
|
||||
renderText(dstX-1,dstY,str);
|
||||
renderText(dstX+1,dstY,str);
|
||||
renderText(dstX-1,dstY+1,str);
|
||||
renderText(dstX,dstY+1,str);
|
||||
renderText(dstX+1,dstY+1,str);
|
||||
lineColor(lineColorOld);
|
||||
renderText(dstX,dstY,str);
|
||||
}
|
||||
|
||||
|
||||
// Auxiliary
|
||||
virtual double pi() { return agg::pi; }
|
||||
virtual double deg2Rad(double v) { return v * agg::pi / 180.0; }
|
||||
virtual double rad2Deg(double v) { return v * 180.0 / agg::pi; }
|
||||
};
|
||||
|
||||
|
||||
template<typename PixFormatSet>
|
||||
class AggDrawTargetImplementation : public AggDrawTarget, public Agg2D<PixFormatSet>
|
||||
{
|
||||
public:
|
||||
typedef typename PixFormatSet::PixFormat pixfmt;
|
||||
typedef typename pixfmt::color_type color_type;
|
||||
|
||||
typedef Agg2D<PixFormatSet> BASE;
|
||||
AggDrawTargetImplementation(agg::int8u* buf, int width, int height, int stride)
|
||||
{
|
||||
BASE::attach(buf,width,height,stride);
|
||||
|
||||
BASE::viewport(0, 0, width-1, height-1, 0, 0, width-1, height-1, TAGG2D::Anisotropic);
|
||||
}
|
||||
|
||||
virtual void clear() {
|
||||
if(!empty)
|
||||
{
|
||||
BASE::clearAll(0,0,0,0);
|
||||
undirty();
|
||||
}
|
||||
}
|
||||
|
||||
virtual agg::rendering_buffer & buf() { dirty(); return BASE::buf(); } // buf() might not always require calling dirty()
|
||||
typename BASE::MyImage image() { return BASE::MyImage(buf()); }
|
||||
|
||||
// Setup
|
||||
virtual void attach(unsigned char* buf, unsigned width, unsigned height, int stride) {BASE::attach(buf, width, height, stride);};
|
||||
// virtual void attach(Agg2DBase::Image& img) {attach(img);};
|
||||
|
||||
virtual void clipBox(double x1, double y1, double x2, double y2) { BASE::clipBox(x1,y1,x2,y2); }
|
||||
virtual Agg2DBase::RectD clipBox() const {return BASE::clipBox();};
|
||||
|
||||
virtual void clearAll(AggColor c) {BASE::clearAll(c);};
|
||||
virtual void clearAll(unsigned r, unsigned g, unsigned b, unsigned a = 255) {BASE::clearAll(r, g, b, a);};
|
||||
|
||||
virtual void clearClipBox(AggColor c) {BASE::clearClipBox(c);};
|
||||
virtual void clearClipBox(unsigned r, unsigned g, unsigned b, unsigned a = 255) {BASE::clearClipBox(r, g, b, a);};
|
||||
|
||||
// virtual unsigned width() const { return Agg2DBase::m_rbuf.width(); }
|
||||
// virtual unsigned height() const { return Agg2DBase::m_rbuf.height(); }
|
||||
|
||||
// Conversions
|
||||
virtual void worldToScreen(double& x, double& y) const {BASE::worldToScreen(x, y);};
|
||||
virtual void screenToWorld(double& x, double& y) const {BASE::screenToWorld(x, y);};
|
||||
virtual double worldToScreen(double scalar) const {return BASE::worldToScreen(scalar);};
|
||||
virtual double screenToWorld(double scalar) const {return BASE::screenToWorld(scalar);};
|
||||
virtual void alignPoint(double& x, double& y) const {BASE::alignPoint(x, y);};
|
||||
virtual bool inBox(double worldX, double worldY) const {return BASE::inBox(worldX, worldY);};
|
||||
|
||||
// General Attributes
|
||||
virtual void blendMode(Agg2DBase::BlendMode m) {BASE::blendMode(m);};
|
||||
virtual Agg2DBase::BlendMode blendMode() {return BASE::blendMode();};
|
||||
|
||||
virtual void imageBlendMode(Agg2DBase::BlendMode m) {BASE::imageBlendMode(m);};
|
||||
virtual Agg2DBase::BlendMode imageBlendMode() {return BASE::imageBlendMode();};
|
||||
|
||||
virtual void imageBlendColor(AggColor c) {BASE::imageBlendColor(c);};
|
||||
virtual void imageBlendColor(unsigned r, unsigned g, unsigned b, unsigned a = 255) {BASE::imageBlendColor(r, g, b, a);};
|
||||
virtual AggColor imageBlendColor() {return BASE::imageBlendColor();};
|
||||
|
||||
virtual void masterAlpha(double a) {BASE::masterAlpha(a);};
|
||||
virtual double masterAlpha() {return BASE::masterAlpha();};
|
||||
|
||||
virtual void antiAliasGamma(double g) {BASE::antiAliasGamma(g);};
|
||||
virtual double antiAliasGamma() {return BASE::antiAliasGamma();};
|
||||
|
||||
// virtual void font(const agg::int8u* font) { m_font = font; }
|
||||
// const agg::int8u* font() { return m_font; }
|
||||
|
||||
virtual void fillColor(AggColor c) {BASE::fillColor(c);};
|
||||
virtual void fillColor(unsigned r, unsigned g, unsigned b, unsigned a = 255) {BASE::fillColor(r,g,b,a);};
|
||||
virtual void noFill() {BASE::noFill();};
|
||||
|
||||
virtual void lineColor(AggColor c) {BASE::lineColor(c);};
|
||||
virtual void lineColor(unsigned r, unsigned g, unsigned b, unsigned a = 255) {BASE::lineColor(r,g,b,a);};
|
||||
virtual void noLine() {BASE::noLine();};
|
||||
|
||||
virtual AggColor fillColor() {return BASE::fillColor();};
|
||||
virtual AggColor lineColor() {return BASE::lineColor();};
|
||||
|
||||
virtual void fillLinearGradient(double x1, double y1, double x2, double y2, AggColor c1, AggColor c2, double profile=1.0) {dirty(); BASE::fillLinearGradient(x1, y1, x2, y2, c1, c2, profile);};
|
||||
virtual void lineLinearGradient(double x1, double y1, double x2, double y2, AggColor c1, AggColor c2, double profile=1.0) {dirty(); BASE::lineLinearGradient(x1, y1, x2, y2, c1, c2, profile);};
|
||||
|
||||
virtual void fillRadialGradient(double x, double y, double r, AggColor c1, AggColor c2, double profile=1.0) {dirty(); BASE::fillRadialGradient(x, y, r, c1, c2, profile);};
|
||||
virtual void lineRadialGradient(double x, double y, double r, AggColor c1, AggColor c2, double profile=1.0) {dirty(); BASE::lineRadialGradient(x, y, r, c1, c2, profile);};
|
||||
|
||||
virtual void fillRadialGradient(double x, double y, double r, AggColor c1, AggColor c2, AggColor c3) {dirty(); BASE::fillRadialGradient(x, y, r, c1, c2, c3);};
|
||||
virtual void lineRadialGradient(double x, double y, double r, AggColor c1, AggColor c2, AggColor c3) {dirty(); BASE::lineRadialGradient(x, y, r, c1, c2, c3);};
|
||||
virtual void fillRadialGradient(double x, double y, double r) {dirty(); BASE::fillRadialGradient(x, y, r);};
|
||||
virtual void lineRadialGradient(double x, double y, double r) {dirty(); BASE::lineRadialGradient(x, y, r);};
|
||||
|
||||
virtual void lineWidth(double w) {BASE::lineWidth(w);};
|
||||
virtual double lineWidth() {return BASE::lineWidth();};
|
||||
|
||||
virtual void lineCap(Agg2DBase::LineCap cap) {BASE::lineCap(cap);};
|
||||
virtual Agg2DBase::LineCap lineCap() {return BASE::lineCap();};
|
||||
|
||||
virtual void lineJoin(Agg2DBase::LineJoin join) {BASE::lineJoin(join);};
|
||||
virtual Agg2DBase::LineJoin lineJoin() {return BASE::lineJoin();};
|
||||
|
||||
virtual void fillEvenOdd(bool evenOddFlag) {BASE::fillEvenOdd(evenOddFlag);};
|
||||
virtual bool fillEvenOdd() {return BASE::fillEvenOdd();};
|
||||
|
||||
virtual void transformImage(const Agg2DBase::Image<T_AGG_PF_RGBA>& img, double dstX1, double dstY1, double dstX2, double dstY2) { BASE::transformImage(img,dstX1,dstY1,dstX2,dstY2); }
|
||||
//virtual void transformImage(const Agg2DBase::Image<T_AGG_PF_RGB555> &img, double dstX1, double dstY1, double dstX2, double dstY2) { BASE::transformImage(img,dstX1,dstY1,dstX2,dstY2); }
|
||||
|
||||
// Transformations
|
||||
virtual Agg2DBase::Transformations transformations() {return BASE::transformations();};
|
||||
virtual void transformations(const Agg2DBase::Transformations& tr) {BASE::transformations(tr);};
|
||||
|
||||
virtual const Agg2DBase::Affine& affine() {return BASE::affine();};
|
||||
// virtual void affine(const Agg2DBase::Affine&) {BASE::affine();};
|
||||
|
||||
virtual void resetTransformations() {BASE::resetTransformations();};
|
||||
virtual void matrix(const Agg2DBase::Affine& tr) {BASE::matrix(tr);};
|
||||
virtual void matrix(const Agg2DBase::Transformations& tr) {BASE::matrix(tr);};
|
||||
virtual void rotate(double angle) {BASE::rotate(angle);};
|
||||
virtual void rotate(double angle, double cx, double cy) {BASE::rotate(angle, cx, cy);};
|
||||
virtual void scale(double s) {BASE::scale(s);};
|
||||
virtual void scale(double sx, double sy) {BASE::scale(sx, sy);};
|
||||
virtual void skew(double sx, double sy) {BASE::skew(sx, sy);};
|
||||
virtual void translate(double x, double y) {BASE::translate(x, y);};
|
||||
virtual void parallelogram(double x1, double y1, double x2, double y2, const double* para) {BASE::parallelogram(x1, y1, x2, y2, para);};
|
||||
virtual void viewport(double worldX1, double worldY1, double worldX2, double worldY2, double screenX1, double screenY1, double screenX2, double screenY2, Agg2DBase::ViewportOption opt=Agg2DBase::XMidYMid, Agg2DBase::WindowFitLogic fl = Agg2DBase::WindowFitLogic_meet) {BASE::viewport(worldX1, worldY1, worldX2, worldY2, screenX1, screenY1, screenX2, screenY2, opt, fl);};
|
||||
|
||||
// Basic Shapes
|
||||
virtual void line(double x1, double y1, double x2, double y2) {dirty(); BASE::line(x1, y1, x2, y2);};
|
||||
virtual void triangle(double x1, double y1, double x2, double y2, double x3, double y3) {dirty(); BASE::triangle(x1, y1, x2, y2, x3, y3);};
|
||||
virtual void rectangle(double x1, double y1, double x2, double y2) {dirty(); BASE::rectangle(x1, y1, x2, y2);};
|
||||
virtual void roundedRect(double x1, double y1, double x2, double y2, double r) { dirty(); BASE::roundedRect(x1,y1,x2,y2,r); }
|
||||
virtual void roundedRect(double x1, double y1, double x2, double y2, double rx, double ry) { dirty(); BASE::roundedRect(x1,y1,x2,y2,rx,ry); }
|
||||
virtual void roundedRect(double x1, double y1, double x2, double y2,double rx_bottom, double ry_bottom,double rx_top,double ry_top) { dirty(); BASE::roundedRect(x1,y1,x2,y2,rx_bottom,ry_bottom,rx_top,ry_top); }
|
||||
virtual void ellipse(double cx, double cy, double rx, double ry) {dirty(); BASE::ellipse(cx, cy, rx, ry);}
|
||||
virtual void arc(double cx, double cy, double rx, double ry, double start, double sweep) {dirty(); BASE::arc(cx, cy, rx, ry, start, sweep);};
|
||||
virtual void star(double cx, double cy, double r1, double r2, double startAngle, int numRays) {dirty(); BASE::star(cx, cy, r1, r2, startAngle, numRays);};
|
||||
virtual void curve(double x1, double y1, double x2, double y2, double x3, double y3) {dirty(); BASE::curve(x1, y1, x2, y2, x3, y3);};
|
||||
virtual void curve(double x1, double y1, double x2, double y2, double x3, double y3, double x4, double y4) {dirty(); BASE::curve(x1, y1, x2, y2, x3, y3, x4, y4);};
|
||||
virtual void polygon(double* xy, int numPoints) {dirty(); BASE::polygon(xy, numPoints);};
|
||||
virtual void polyline(double* xy, int numPoints) {dirty(); BASE::polyline(xy, numPoints);};
|
||||
|
||||
virtual void setFont(const std::string& name) { BASE::font(lookupFont(name)); }
|
||||
virtual void renderText(double dstX, double dstY, const std::string& str) {
|
||||
dirty();
|
||||
int height = BASE::font()[0];
|
||||
int base = BASE::font()[1];
|
||||
int offset = height-base*2;
|
||||
BASE::renderText(dstX, dstY + offset, str);
|
||||
}
|
||||
|
||||
// Path commands
|
||||
virtual void resetPath() {BASE::resetPath();};
|
||||
|
||||
virtual void moveTo(double x, double y) {BASE::moveTo(x, y);}
|
||||
virtual void moveRel(double dx, double dy) {BASE::moveRel(dx,dy);};
|
||||
|
||||
virtual void lineTo(double x, double y) {BASE::lineTo(x, y);};
|
||||
virtual void lineRel(double dx, double dy) {BASE::lineRel(dx, dy);};
|
||||
|
||||
virtual void horLineTo(double x) {BASE::horLineTo(x);};
|
||||
virtual void horLineRel(double dx) {BASE::horLineRel(dx);};
|
||||
|
||||
virtual void verLineTo(double y) {BASE::verLineTo(y);};
|
||||
virtual void verLineRel(double dy) {BASE::verLineRel(dy);};
|
||||
|
||||
virtual void arcTo(double rx, double ry, double angle, bool largeArcFlag, bool sweepFlag, double x, double y) {BASE::arcTo(rx, ry, angle, largeArcFlag, sweepFlag, x, y);};
|
||||
|
||||
virtual void arcRel(double rx, double ry, double angle, bool largeArcFlag, bool sweepFlag, double dx, double dy) {BASE::arcRel(rx, ry, angle, largeArcFlag, sweepFlag, dx, dy);};
|
||||
|
||||
virtual void quadricCurveTo(double xCtrl, double yCtrl, double xTo, double yTo) {BASE::quadricCurveTo(xCtrl, yCtrl, xTo, yTo);};
|
||||
virtual void quadricCurveRel(double dxCtrl, double dyCtrl, double dxTo, double dyTo) {BASE::quadricCurveRel(dxCtrl, dyCtrl, dxTo, dyTo);};
|
||||
virtual void quadricCurveTo(double xTo, double yTo) {BASE::quadricCurveTo(xTo, yTo);};
|
||||
virtual void quadricCurveRel(double dxTo, double dyTo) {BASE::quadricCurveRel(dxTo, dyTo);};
|
||||
|
||||
virtual void cubicCurveTo(double xCtrl1, double yCtrl1, double xCtrl2, double yCtrl2, double xTo, double yTo) {BASE::cubicCurveTo(xCtrl1, yCtrl1, xCtrl2, yCtrl2, xTo, yTo);};
|
||||
virtual void cubicCurveRel(double dxCtrl1, double dyCtrl1, double dxCtrl2, double dyCtrl2, double dxTo, double dyTo) {BASE::cubicCurveRel(dxCtrl1, dyCtrl1, dxCtrl2, dyCtrl2, dxTo, dyTo);};
|
||||
virtual void cubicCurveTo(double xCtrl2, double yCtrl2, double xTo, double yTo) {BASE::cubicCurveTo(xCtrl2, yCtrl2, xTo, yTo);};
|
||||
virtual void cubicCurveRel(double xCtrl2, double yCtrl2, double xTo, double yTo) {BASE::cubicCurveRel(xCtrl2, yCtrl2, xTo, yTo);};
|
||||
|
||||
virtual void addEllipse(double cx, double cy, double rx, double ry, Agg2DBase::Direction dir) {BASE::addEllipse(cx, cy, rx, ry, dir);};
|
||||
virtual void closePolygon() {BASE::closePolygon();};
|
||||
|
||||
virtual void drawPath(Agg2DBase::DrawPathFlag flag = Agg2DBase::FillAndStroke) {dirty(); BASE::drawPath(flag);};
|
||||
// virtual void drawPathNoTransform(DrawPathFlag flag = FillAndStroke) {dirty(); BASE::drawPathNoTransform(flag);};
|
||||
|
||||
// Image Transformations
|
||||
virtual void imageFilter(Agg2DBase::ImageFilter f) {BASE::imageFilter(f);};
|
||||
virtual Agg2DBase::ImageFilter imageFilter() {return BASE::imageFilter();};
|
||||
|
||||
virtual void imageResample(Agg2DBase::ImageResample f) {BASE::imageResample(f);};
|
||||
virtual Agg2DBase::ImageResample imageResample() {return BASE::imageResample();};
|
||||
|
||||
// Auxiliary
|
||||
virtual double pi() { return agg::pi; }
|
||||
virtual double deg2Rad(double v) { return v * agg::pi / 180.0; }
|
||||
virtual double rad2Deg(double v) { return v * 180.0 / agg::pi; }
|
||||
};
|
||||
|
||||
//the main aggdraw targets for different pixel formats
|
||||
typedef AggDrawTargetImplementation<T_AGG_PF_RGB555> T_AGG_RGB555;
|
||||
typedef AggDrawTargetImplementation<T_AGG_PF_RGBA> T_AGG_RGBA;
|
||||
|
||||
|
||||
class AggDraw
|
||||
{
|
||||
public:
|
||||
AggDraw()
|
||||
: target(NULL)
|
||||
{}
|
||||
AggDrawTarget *target;
|
||||
};
|
||||
|
||||
enum AggTarget
|
||||
{
|
||||
AggTarget_Screen = 0,
|
||||
AggTarget_Hud = 1,
|
||||
AggTarget_Lua = 2,
|
||||
};
|
||||
|
||||
//specialized instance for desmume; should eventually move to another file
|
||||
class AggDraw_Desmume : public AggDraw
|
||||
{
|
||||
public:
|
||||
void setTarget(AggTarget newTarget);
|
||||
//void composite(void* dest);
|
||||
|
||||
AggDrawTarget *screen, *hud, *lua;
|
||||
};
|
||||
|
||||
extern AggDraw_Desmume aggDraw;
|
||||
|
||||
void Agg_init();
|
||||
|
||||
struct font_type
|
||||
{
|
||||
const agg::int8u* font;
|
||||
const char* name;
|
||||
};
|
||||
extern font_type fonts_list[];
|
||||
extern int font_Nums;
|
||||
#endif
|
||||
Executable
+6295
File diff suppressed because it is too large
Load Diff
Executable
+4461
File diff suppressed because it is too large
Load Diff
Executable
+70
@@ -0,0 +1,70 @@
|
||||
/* Copyright (C) 2006 yopyop
|
||||
Copyright (C) 2011 Loren Merritt
|
||||
Copyright (C) 2012-2013 DeSmuME team
|
||||
|
||||
This file is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This file is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with the this software. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef ARM_JIT
|
||||
#define ARM_JIT
|
||||
|
||||
#include "types.h"
|
||||
#ifndef _MSC_VER
|
||||
#include <stdint.h>
|
||||
#endif
|
||||
|
||||
typedef u32 (FASTCALL* ArmOpCompiled)();
|
||||
|
||||
void arm_jit_reset(bool enable, bool suppress_msg = false);
|
||||
void arm_jit_close();
|
||||
void arm_jit_sync();
|
||||
template<int PROCNUM> u32 arm_jit_compile();
|
||||
|
||||
#if defined(HOST_WINDOWS) || defined(DESMUME_COCOA)
|
||||
#define MAPPED_JIT_FUNCS
|
||||
#endif
|
||||
#ifdef MAPPED_JIT_FUNCS
|
||||
struct JIT_struct
|
||||
{
|
||||
// only include the memory types that code can execute from
|
||||
uintptr_t MAIN_MEM[16*1024*1024/2];
|
||||
uintptr_t SWIRAM[0x8000/2];
|
||||
uintptr_t ARM9_ITCM[0x8000/2];
|
||||
uintptr_t ARM9_LCDC[0xA4000/2];
|
||||
uintptr_t ARM9_BIOS[0x8000/2];
|
||||
uintptr_t ARM7_BIOS[0x4000/2];
|
||||
uintptr_t ARM7_ERAM[0x10000/2];
|
||||
uintptr_t ARM7_WIRAM[0x10000/2];
|
||||
uintptr_t ARM7_WRAM[0x40000/2];
|
||||
|
||||
static uintptr_t *JIT_MEM[2][0x4000];
|
||||
};
|
||||
extern CACHE_ALIGN JIT_struct JIT;
|
||||
#define JIT_COMPILED_FUNC(adr, PROCNUM) JIT.JIT_MEM[PROCNUM][((adr)&0x0FFFC000)>>14][((adr)&0x00003FFE)>>1]
|
||||
#define JIT_COMPILED_FUNC_PREMASKED(adr, PROCNUM, ofs) JIT.JIT_MEM[PROCNUM][(adr)>>14][(((adr)&0x00003FFE)>>1)+ofs]
|
||||
#define JIT_COMPILED_FUNC_KNOWNBANK(adr, bank, mask, ofs) JIT.bank[(((adr)&(mask))>>1)+ofs]
|
||||
#define JIT_MAPPED(adr, PROCNUM) JIT.JIT_MEM[PROCNUM][(adr)>>14]
|
||||
#else
|
||||
// actually an array of function pointers, but they fit in 32bit address space, so might as well save memory
|
||||
extern uintptr_t compiled_funcs[];
|
||||
// there isn't anything mapped between 07000000 and 0EFFFFFF, so we can mask off bit 27 and get away with a smaller array
|
||||
#define JIT_COMPILED_FUNC(adr, PROCNUM) compiled_funcs[((adr) & 0x07FFFFFE) >> 1]
|
||||
#define JIT_COMPILED_FUNC_PREMASKED(adr, PROCNUM, ofs) JIT_COMPILED_FUNC(adr+(ofs<<1), PROCNUM)
|
||||
#define JIT_COMPILED_FUNC_KNOWNBANK(adr, bank, mask, ofs) JIT_COMPILED_FUNC(adr+(ofs<<1), PROCNUM)
|
||||
#define JIT_MAPPED(adr, PROCNUM) true
|
||||
#endif
|
||||
|
||||
extern u32 saveBlockSizeJIT;
|
||||
|
||||
#endif
|
||||
Executable
+785
@@ -0,0 +1,785 @@
|
||||
/*
|
||||
Copyright (C) 2006 yopyop
|
||||
Copyright (C) 2009-2015 DeSmuME team
|
||||
|
||||
This file is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This file is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with the this software. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <assert.h>
|
||||
#include <algorithm>
|
||||
|
||||
#include "armcpu.h"
|
||||
#include "common.h"
|
||||
#include "instructions.h"
|
||||
#include "cp15.h"
|
||||
#include "bios.h"
|
||||
#include "debug.h"
|
||||
#include "Disassembler.h"
|
||||
#include "NDSSystem.h"
|
||||
#include "MMU_timing.h"
|
||||
#ifdef HAVE_LUA
|
||||
#include "lua-engine.h"
|
||||
#endif
|
||||
#ifdef HAVE_JIT
|
||||
#include "arm_jit.h"
|
||||
#endif
|
||||
|
||||
template<u32> static u32 armcpu_prefetch();
|
||||
|
||||
FORCEINLINE u32 armcpu_prefetch(armcpu_t *armcpu) {
|
||||
if(armcpu->proc_ID==0) return armcpu_prefetch<0>();
|
||||
else return armcpu_prefetch<1>();
|
||||
}
|
||||
|
||||
armcpu_t NDS_ARM7;
|
||||
armcpu_t NDS_ARM9;
|
||||
|
||||
#define SWAP(a, b, c) do \
|
||||
{ \
|
||||
c=a; \
|
||||
a=b; \
|
||||
b=c; \
|
||||
} \
|
||||
while(0)
|
||||
|
||||
#define STALLED_CYCLE_COUNT 10
|
||||
|
||||
static void
|
||||
stall_cpu( void *instance) {
|
||||
armcpu_t *armcpu = (armcpu_t *)instance;
|
||||
printf("STALL\n");
|
||||
armcpu->stalled = 1;
|
||||
}
|
||||
|
||||
static void
|
||||
unstall_cpu( void *instance) {
|
||||
armcpu_t *armcpu = (armcpu_t *)instance;
|
||||
printf("UNSTALL\n");
|
||||
armcpu->stalled = 0;
|
||||
}
|
||||
|
||||
static void
|
||||
install_post_exec_fn( void *instance,
|
||||
void (*ex_fn)( void *, u32 adr, int thumb),
|
||||
void *fn_data) {
|
||||
armcpu_t *armcpu = (armcpu_t *)instance;
|
||||
|
||||
armcpu->post_ex_fn = ex_fn;
|
||||
armcpu->post_ex_fn_data = fn_data;
|
||||
}
|
||||
|
||||
static void
|
||||
remove_post_exec_fn( void *instance) {
|
||||
armcpu_t *armcpu = (armcpu_t *)instance;
|
||||
|
||||
armcpu->post_ex_fn = NULL;
|
||||
}
|
||||
|
||||
static u32 read_cpu_reg( void *instance, u32 reg_num)
|
||||
{
|
||||
armcpu_t *armcpu = (armcpu_t *)instance;
|
||||
|
||||
if ( reg_num <= 14) {
|
||||
return armcpu->R[reg_num];
|
||||
}
|
||||
else if ( reg_num == 15) {
|
||||
return armcpu->instruct_adr;
|
||||
}
|
||||
else if ( reg_num == 16) {
|
||||
//CPSR
|
||||
return armcpu->CPSR.val;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
set_cpu_reg( void *instance, u32 reg_num, u32 value) {
|
||||
armcpu_t *armcpu = (armcpu_t *)instance;
|
||||
|
||||
if ( reg_num <= 14) {
|
||||
armcpu->R[reg_num] = value;
|
||||
}
|
||||
else if ( reg_num == 15) {
|
||||
armcpu->next_instruction = value;
|
||||
}
|
||||
else if ( reg_num == 16) {
|
||||
/* FIXME: setting the CPSR */
|
||||
}
|
||||
}
|
||||
|
||||
int armcpu_new( armcpu_t *armcpu, u32 id)
|
||||
{
|
||||
armcpu->proc_ID = id;
|
||||
armcpu->stalled = 0;
|
||||
|
||||
armcpu->base_mem_if.prefetch32 = NULL;
|
||||
armcpu->base_mem_if.prefetch16 = NULL;
|
||||
armcpu->base_mem_if.read8 = NULL;
|
||||
armcpu->base_mem_if.read16 = NULL;
|
||||
armcpu->base_mem_if.read32 = NULL;
|
||||
armcpu->base_mem_if.write8 = NULL;
|
||||
armcpu->base_mem_if.write16 = NULL;
|
||||
armcpu->base_mem_if.write32 = NULL;
|
||||
armcpu->base_mem_if.data = NULL;
|
||||
|
||||
armcpu->SetControlInterface(&arm_default_ctrl_iface);
|
||||
armcpu->SetControlInterfaceData(armcpu);
|
||||
armcpu->SetCurrentMemoryInterface(NULL);
|
||||
armcpu->SetCurrentMemoryInterfaceData(NULL);
|
||||
|
||||
armcpu->post_ex_fn = NULL;
|
||||
armcpu->post_ex_fn_data = NULL;
|
||||
|
||||
armcpu_init(armcpu, 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void armcpu_t::SetControlInterface(const armcpu_ctrl_iface *theControlInterface)
|
||||
{
|
||||
this->ctrl_iface = *theControlInterface;
|
||||
}
|
||||
|
||||
armcpu_ctrl_iface* armcpu_t::GetControlInterface()
|
||||
{
|
||||
return &this->ctrl_iface;
|
||||
}
|
||||
|
||||
void armcpu_t::SetControlInterfaceData(void *theData)
|
||||
{
|
||||
this->ctrl_iface.data = theData;
|
||||
}
|
||||
|
||||
void* armcpu_t::GetControlInterfaceData()
|
||||
{
|
||||
return this->ctrl_iface.data;
|
||||
}
|
||||
|
||||
void armcpu_t::SetCurrentMemoryInterface(armcpu_memory_iface *theMemoryInterface)
|
||||
{
|
||||
this->mem_if = theMemoryInterface;
|
||||
}
|
||||
|
||||
armcpu_memory_iface* armcpu_t::GetCurrentMemoryInterface()
|
||||
{
|
||||
return this->mem_if;
|
||||
}
|
||||
|
||||
void armcpu_t::SetCurrentMemoryInterfaceData(void *theData)
|
||||
{
|
||||
if (this->mem_if != NULL)
|
||||
{
|
||||
this->mem_if->data = theData;
|
||||
}
|
||||
}
|
||||
|
||||
void* armcpu_t::GetCurrentMemoryInterfaceData()
|
||||
{
|
||||
return (this->mem_if != NULL) ? this->mem_if->data : NULL;
|
||||
}
|
||||
|
||||
void armcpu_t::SetBaseMemoryInterface(const armcpu_memory_iface *theMemInterface)
|
||||
{
|
||||
this->base_mem_if = *theMemInterface;
|
||||
}
|
||||
|
||||
armcpu_memory_iface* armcpu_t::GetBaseMemoryInterface()
|
||||
{
|
||||
return &this->base_mem_if;
|
||||
}
|
||||
|
||||
void armcpu_t::SetBaseMemoryInterfaceData(void *theData)
|
||||
{
|
||||
this->base_mem_if.data = theData;
|
||||
}
|
||||
|
||||
void* armcpu_t::GetBaseMemoryInterfaceData()
|
||||
{
|
||||
return this->base_mem_if.data;
|
||||
}
|
||||
|
||||
void armcpu_t::ResetMemoryInterfaceToBase()
|
||||
{
|
||||
this->SetCurrentMemoryInterface(this->GetBaseMemoryInterface());
|
||||
this->SetCurrentMemoryInterfaceData(this->GetBaseMemoryInterfaceData());
|
||||
}
|
||||
|
||||
//call this whenever CPSR is changed (other than CNVZQ or T flags); interrupts may need to be unleashed
|
||||
void armcpu_t::changeCPSR()
|
||||
{
|
||||
//but all it does is give them a chance to unleash by forcing an immediate reschedule
|
||||
//TODO - we could actually set CPSR through here and look for a change in the I bit
|
||||
//that would be a little optimization as well as a safety measure if we prevented setting CPSR directly
|
||||
NDS_Reschedule();
|
||||
}
|
||||
|
||||
void armcpu_init(armcpu_t *armcpu, u32 adr)
|
||||
{
|
||||
#if defined(_M_X64) || defined(__x86_64__)
|
||||
memcpy(&armcpu->cond_table[0], &arm_cond_table[0], sizeof(arm_cond_table));
|
||||
#endif
|
||||
|
||||
armcpu->LDTBit = (armcpu->proc_ID==0); //set ARMv5 style bit--different for each processor
|
||||
armcpu->intVector = 0xFFFF0000 * (armcpu->proc_ID==0);
|
||||
armcpu->waitIRQ = FALSE;
|
||||
armcpu->halt_IE_and_IF = FALSE;
|
||||
armcpu->intrWaitARM_state = 0;
|
||||
|
||||
//#ifdef GDB_STUB
|
||||
// armcpu->irq_flag = 0;
|
||||
//#endif
|
||||
|
||||
for(int i = 0; i < 16; ++i)
|
||||
armcpu->R[i] = 0;
|
||||
|
||||
armcpu->CPSR.val = armcpu->SPSR.val = SYS;
|
||||
|
||||
armcpu->R13_usr = armcpu->R14_usr = 0;
|
||||
armcpu->R13_svc = armcpu->R14_svc = 0;
|
||||
armcpu->R13_abt = armcpu->R14_abt = 0;
|
||||
armcpu->R13_und = armcpu->R14_und = 0;
|
||||
armcpu->R13_irq = armcpu->R14_irq = 0;
|
||||
armcpu->R8_fiq = armcpu->R9_fiq = armcpu->R10_fiq = armcpu->R11_fiq = armcpu->R12_fiq = armcpu->R13_fiq = armcpu->R14_fiq = 0;
|
||||
|
||||
armcpu->SPSR_svc.val = armcpu->SPSR_abt.val = armcpu->SPSR_und.val = armcpu->SPSR_irq.val = armcpu->SPSR_fiq.val = 0;
|
||||
|
||||
//#ifdef GDB_STUB
|
||||
// armcpu->instruct_adr = adr;
|
||||
// armcpu->R[15] = adr + 8;
|
||||
//#else
|
||||
//armcpu->R[15] = adr;
|
||||
//#endif
|
||||
|
||||
//do something sensible when booting up to a thumb address
|
||||
armcpu->next_instruction = adr & ~1;
|
||||
armcpu->CPSR.bits.T = BIT0(adr);
|
||||
|
||||
//#ifndef GDB_STUB
|
||||
armcpu_prefetch(armcpu);
|
||||
//#endif
|
||||
}
|
||||
|
||||
u32 armcpu_switchMode(armcpu_t *armcpu, u8 mode)
|
||||
{
|
||||
u32 oldmode = armcpu->CPSR.bits.mode;
|
||||
|
||||
switch(oldmode)
|
||||
{
|
||||
case USR :
|
||||
case SYS :
|
||||
armcpu->R13_usr = armcpu->R[13];
|
||||
armcpu->R14_usr = armcpu->R[14];
|
||||
break;
|
||||
|
||||
case FIQ :
|
||||
{
|
||||
u32 tmp;
|
||||
SWAP(armcpu->R[8], armcpu->R8_fiq, tmp);
|
||||
SWAP(armcpu->R[9], armcpu->R9_fiq, tmp);
|
||||
SWAP(armcpu->R[10], armcpu->R10_fiq, tmp);
|
||||
SWAP(armcpu->R[11], armcpu->R11_fiq, tmp);
|
||||
SWAP(armcpu->R[12], armcpu->R12_fiq, tmp);
|
||||
armcpu->R13_fiq = armcpu->R[13];
|
||||
armcpu->R14_fiq = armcpu->R[14];
|
||||
armcpu->SPSR_fiq = armcpu->SPSR;
|
||||
break;
|
||||
}
|
||||
case IRQ :
|
||||
armcpu->R13_irq = armcpu->R[13];
|
||||
armcpu->R14_irq = armcpu->R[14];
|
||||
armcpu->SPSR_irq = armcpu->SPSR;
|
||||
break;
|
||||
|
||||
case SVC :
|
||||
armcpu->R13_svc = armcpu->R[13];
|
||||
armcpu->R14_svc = armcpu->R[14];
|
||||
armcpu->SPSR_svc = armcpu->SPSR;
|
||||
break;
|
||||
|
||||
case ABT :
|
||||
armcpu->R13_abt = armcpu->R[13];
|
||||
armcpu->R14_abt = armcpu->R[14];
|
||||
armcpu->SPSR_abt = armcpu->SPSR;
|
||||
break;
|
||||
|
||||
case UND :
|
||||
armcpu->R13_und = armcpu->R[13];
|
||||
armcpu->R14_und = armcpu->R[14];
|
||||
armcpu->SPSR_und = armcpu->SPSR;
|
||||
break;
|
||||
default :
|
||||
break;
|
||||
}
|
||||
|
||||
switch(mode)
|
||||
{
|
||||
case USR :
|
||||
case SYS :
|
||||
armcpu->R[13] = armcpu->R13_usr;
|
||||
armcpu->R[14] = armcpu->R14_usr;
|
||||
//SPSR = CPSR;
|
||||
break;
|
||||
|
||||
case FIQ :
|
||||
{
|
||||
u32 tmp;
|
||||
SWAP(armcpu->R[8], armcpu->R8_fiq, tmp);
|
||||
SWAP(armcpu->R[9], armcpu->R9_fiq, tmp);
|
||||
SWAP(armcpu->R[10], armcpu->R10_fiq, tmp);
|
||||
SWAP(armcpu->R[11], armcpu->R11_fiq, tmp);
|
||||
SWAP(armcpu->R[12], armcpu->R12_fiq, tmp);
|
||||
armcpu->R[13] = armcpu->R13_fiq;
|
||||
armcpu->R[14] = armcpu->R14_fiq;
|
||||
armcpu->SPSR = armcpu->SPSR_fiq;
|
||||
break;
|
||||
}
|
||||
|
||||
case IRQ :
|
||||
armcpu->R[13] = armcpu->R13_irq;
|
||||
armcpu->R[14] = armcpu->R14_irq;
|
||||
armcpu->SPSR = armcpu->SPSR_irq;
|
||||
break;
|
||||
|
||||
case SVC :
|
||||
armcpu->R[13] = armcpu->R13_svc;
|
||||
armcpu->R[14] = armcpu->R14_svc;
|
||||
armcpu->SPSR = armcpu->SPSR_svc;
|
||||
break;
|
||||
|
||||
case ABT :
|
||||
armcpu->R[13] = armcpu->R13_abt;
|
||||
armcpu->R[14] = armcpu->R14_abt;
|
||||
armcpu->SPSR = armcpu->SPSR_abt;
|
||||
break;
|
||||
|
||||
case UND :
|
||||
armcpu->R[13] = armcpu->R13_und;
|
||||
armcpu->R[14] = armcpu->R14_und;
|
||||
armcpu->SPSR = armcpu->SPSR_und;
|
||||
break;
|
||||
|
||||
default :
|
||||
printf("switchMode: WRONG mode %02X\n",mode);
|
||||
break;
|
||||
}
|
||||
|
||||
armcpu->CPSR.bits.mode = mode & 0x1F;
|
||||
armcpu->changeCPSR();
|
||||
return oldmode;
|
||||
}
|
||||
|
||||
u32 armcpu_Wait4IRQ(armcpu_t *cpu)
|
||||
{
|
||||
cpu->waitIRQ = TRUE;
|
||||
cpu->halt_IE_and_IF = TRUE;
|
||||
return 1;
|
||||
}
|
||||
|
||||
template<u32 PROCNUM>
|
||||
FORCEINLINE static u32 armcpu_prefetch()
|
||||
{
|
||||
armcpu_t* const armcpu = &ARMPROC;
|
||||
//#ifdef GDB_STUB
|
||||
// u32 temp_instruction;
|
||||
//#endif
|
||||
u32 curInstruction = armcpu->next_instruction;
|
||||
|
||||
if(armcpu->CPSR.bits.T == 0)
|
||||
{
|
||||
//#ifdef GDB_STUB
|
||||
// temp_instruction =
|
||||
// armcpu->mem_if->prefetch32( armcpu->mem_if->data,
|
||||
// armcpu->next_instruction);
|
||||
//
|
||||
// if ( !armcpu->stalled) {
|
||||
// armcpu->instruction = temp_instruction;
|
||||
// armcpu->instruct_adr = armcpu->next_instruction;
|
||||
// armcpu->next_instruction += 4;
|
||||
// armcpu->R[15] = armcpu->next_instruction + 4;
|
||||
// }
|
||||
//#else
|
||||
curInstruction &= 0xFFFFFFFC; //please don't change this to 0x0FFFFFFC -- the NDS will happily run on 0xF******* addresses all day long
|
||||
//please note that we must setup R[15] before reading the instruction since there is a protection
|
||||
//which prevents PC > 0x3FFF from reading the bios region
|
||||
armcpu->instruct_adr = curInstruction;
|
||||
armcpu->next_instruction = curInstruction + 4;
|
||||
armcpu->R[15] = curInstruction + 8;
|
||||
armcpu->instruction = _MMU_read32<PROCNUM, MMU_AT_CODE>(curInstruction);
|
||||
//#endif
|
||||
|
||||
return MMU_codeFetchCycles<PROCNUM,32>(curInstruction);
|
||||
}
|
||||
|
||||
//#ifdef GDB_STUB
|
||||
// temp_instruction =
|
||||
// armcpu->mem_if->prefetch16( armcpu->mem_if->data,
|
||||
// armcpu->next_instruction);
|
||||
//
|
||||
// if ( !armcpu->stalled) {
|
||||
// armcpu->instruction = temp_instruction;
|
||||
// armcpu->instruct_adr = armcpu->next_instruction;
|
||||
// armcpu->next_instruction = armcpu->next_instruction + 2;
|
||||
// armcpu->R[15] = armcpu->next_instruction + 2;
|
||||
// }
|
||||
//#else
|
||||
curInstruction &= 0xFFFFFFFE; //please don't change this to 0x0FFFFFFE -- the NDS will happily run on 0xF******* addresses all day long
|
||||
//please note that we must setup R[15] before reading the instruction since there is a protection
|
||||
//which prevents PC > 0x3FFF from reading the bios region
|
||||
armcpu->instruct_adr = curInstruction;
|
||||
armcpu->next_instruction = curInstruction + 2;
|
||||
armcpu->R[15] = curInstruction + 4;
|
||||
armcpu->instruction = _MMU_read16<PROCNUM, MMU_AT_CODE>(curInstruction);
|
||||
//#endif
|
||||
|
||||
if(PROCNUM==0)
|
||||
{
|
||||
// arm9 fetches 2 instructions at a time in thumb mode
|
||||
if(!(curInstruction == armcpu->instruct_adr + 2 && (curInstruction & 2)))
|
||||
return MMU_codeFetchCycles<PROCNUM,32>(curInstruction);
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
return MMU_codeFetchCycles<PROCNUM,16>(curInstruction);
|
||||
}
|
||||
|
||||
#if 0 /* not used */
|
||||
static BOOL FASTCALL test_EQ(Status_Reg CPSR) { return ( CPSR.bits.Z); }
|
||||
static BOOL FASTCALL test_NE(Status_Reg CPSR) { return (!CPSR.bits.Z); }
|
||||
static BOOL FASTCALL test_CS(Status_Reg CPSR) { return ( CPSR.bits.C); }
|
||||
static BOOL FASTCALL test_CC(Status_Reg CPSR) { return (!CPSR.bits.C); }
|
||||
static BOOL FASTCALL test_MI(Status_Reg CPSR) { return ( CPSR.bits.N); }
|
||||
static BOOL FASTCALL test_PL(Status_Reg CPSR) { return (!CPSR.bits.N); }
|
||||
static BOOL FASTCALL test_VS(Status_Reg CPSR) { return ( CPSR.bits.V); }
|
||||
static BOOL FASTCALL test_VC(Status_Reg CPSR) { return (!CPSR.bits.V); }
|
||||
static BOOL FASTCALL test_HI(Status_Reg CPSR) { return (CPSR.bits.C) && (!CPSR.bits.Z); }
|
||||
static BOOL FASTCALL test_LS(Status_Reg CPSR) { return (CPSR.bits.Z) || (!CPSR.bits.C); }
|
||||
static BOOL FASTCALL test_GE(Status_Reg CPSR) { return (CPSR.bits.N==CPSR.bits.V); }
|
||||
static BOOL FASTCALL test_LT(Status_Reg CPSR) { return (CPSR.bits.N!=CPSR.bits.V); }
|
||||
static BOOL FASTCALL test_GT(Status_Reg CPSR) { return (!CPSR.bits.Z) && (CPSR.bits.N==CPSR.bits.V); }
|
||||
static BOOL FASTCALL test_LE(Status_Reg CPSR) { return ( CPSR.bits.Z) || (CPSR.bits.N!=CPSR.bits.V); }
|
||||
static BOOL FASTCALL test_AL(Status_Reg CPSR) { return 1; }
|
||||
|
||||
static BOOL (FASTCALL* test_conditions[])(Status_Reg CPSR)= {
|
||||
test_EQ , test_NE ,
|
||||
test_CS , test_CC ,
|
||||
test_MI , test_PL ,
|
||||
test_VS , test_VC ,
|
||||
test_HI , test_LS ,
|
||||
test_GE , test_LT ,
|
||||
test_GT , test_LE ,
|
||||
test_AL
|
||||
};
|
||||
#define TEST_COND2(cond, CPSR) \
|
||||
(cond<15&&test_conditions[cond](CPSR))
|
||||
#endif
|
||||
|
||||
//TODO - merge with armcpu_irqException?
|
||||
//http://www.ethernut.de/en/documents/arm-exceptions.html
|
||||
//http://docs.google.com/viewer?a=v&q=cache:V4ht1YkxprMJ:www.cs.nctu.edu.tw/~wjtsai/EmbeddedSystemDesign/Ch3-1.pdf+arm+exception+handling&hl=en&gl=us&pid=bl&srcid=ADGEEShx9VTHbUhWdDOrTVRzLkcCsVfJiijncNDkkgkrlJkLa7D0LCpO8fQ_hhU3DTcgZh9rcZWWQq4TYhhCovJ625h41M0ZUX3WGasyzWQFxYzDCB-VS6bsUmpoJnRxAc-bdkD0qmsu&sig=AHIEtbR9VHvDOCRmZFQDUVwy53iJDjoSPQ
|
||||
void armcpu_exception(armcpu_t *cpu, u32 number)
|
||||
{
|
||||
Mode cpumode = USR;
|
||||
switch(number)
|
||||
{
|
||||
case EXCEPTION_RESET: cpumode = SVC; break;
|
||||
case EXCEPTION_UNDEFINED_INSTRUCTION: cpumode = UND; break;
|
||||
case EXCEPTION_SWI: cpumode = SVC; break;
|
||||
case EXCEPTION_PREFETCH_ABORT: cpumode = ABT; break;
|
||||
case EXCEPTION_DATA_ABORT: cpumode = ABT; break;
|
||||
case EXCEPTION_RESERVED_0x14: emu_halt(); break;
|
||||
case EXCEPTION_IRQ: cpumode = IRQ; break;
|
||||
case EXCEPTION_FAST_IRQ: cpumode = FIQ; break;
|
||||
}
|
||||
|
||||
Status_Reg tmp = cpu->CPSR;
|
||||
armcpu_switchMode(cpu, cpumode); //enter new mode
|
||||
cpu->R[14] = cpu->next_instruction;
|
||||
cpu->SPSR = tmp; //save old CPSR as new SPSR
|
||||
cpu->CPSR.bits.T = 0; //handle as ARM32 code
|
||||
cpu->CPSR.bits.I = 1;
|
||||
cpu->changeCPSR();
|
||||
cpu->R[15] = cpu->intVector + number;
|
||||
cpu->next_instruction = cpu->R[15];
|
||||
printf("armcpu_exception!\n");
|
||||
//extern bool dolog;
|
||||
//dolog=true;
|
||||
|
||||
//HOW DOES THIS WORTK WITHOUT A PREFETCH, LIKE IRQ BELOW?
|
||||
//I REALLY WISH WE DIDNT PREFETCH BEFORE EXECUTING
|
||||
}
|
||||
|
||||
BOOL armcpu_irqException(armcpu_t *armcpu)
|
||||
{
|
||||
Status_Reg tmp;
|
||||
|
||||
//TODO - remove GDB specific code
|
||||
//#ifdef GDB_STUB
|
||||
// armcpu->irq_flag = 0;
|
||||
//#endif
|
||||
|
||||
tmp = armcpu->CPSR;
|
||||
armcpu_switchMode(armcpu, IRQ);
|
||||
|
||||
//TODO - remove GDB specific code
|
||||
//#ifdef GDB_STUB
|
||||
// armcpu->R[14] = armcpu->next_instruction + 4;
|
||||
//#else
|
||||
armcpu->R[14] = armcpu->instruct_adr + 4;
|
||||
//#endif
|
||||
armcpu->SPSR = tmp;
|
||||
armcpu->CPSR.bits.T = 0;
|
||||
armcpu->CPSR.bits.I = 1;
|
||||
armcpu->next_instruction = armcpu->intVector + 0x18;
|
||||
armcpu->waitIRQ = 0;
|
||||
|
||||
//must retain invariant of having next instruction to be executed prefetched
|
||||
//(yucky)
|
||||
armcpu_prefetch(armcpu);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
//TODO - remove GDB specific code
|
||||
//BOOL
|
||||
//armcpu_flagIrq( armcpu_t *armcpu) {
|
||||
// if(armcpu->CPSR.bits.I) return FALSE;
|
||||
//
|
||||
// armcpu->waitIRQ = 0;
|
||||
//
|
||||
//#ifdef GDB_STUB
|
||||
// armcpu->irq_flag = 1;
|
||||
//#endif
|
||||
//
|
||||
// return TRUE;
|
||||
//}
|
||||
|
||||
u32 TRAPUNDEF(armcpu_t* cpu)
|
||||
{
|
||||
INFO("ARM%c: Undefined instruction: 0x%08X (%s) PC=0x%08X\n", cpu->proc_ID?'7':'9', cpu->instruction, decodeIntruction(false, cpu->instruction), cpu->instruct_adr);
|
||||
|
||||
if (((cpu->intVector != 0) ^ (cpu->proc_ID == ARMCPU_ARM9)))
|
||||
{
|
||||
armcpu_exception(&NDS_ARM9,EXCEPTION_UNDEFINED_INSTRUCTION);
|
||||
return 4;
|
||||
}
|
||||
else
|
||||
{
|
||||
emu_halt();
|
||||
return 4;
|
||||
}
|
||||
}
|
||||
|
||||
//BOOL
|
||||
//armcpu_flagIrq( armcpu_t *armcpu) {
|
||||
// if(armcpu->CPSR.bits.I) return FALSE;
|
||||
//
|
||||
// armcpu->waitIRQ = 0;
|
||||
//
|
||||
//#ifdef GDB_STUB
|
||||
// armcpu->irq_flag = 1;
|
||||
//#endif
|
||||
//
|
||||
// return TRUE;
|
||||
//}
|
||||
|
||||
template<int PROCNUM>
|
||||
u32 armcpu_exec()
|
||||
{
|
||||
// Usually, fetching and executing are processed parallelly.
|
||||
// So this function stores the cycles of each process to
|
||||
// the variables below, and returns appropriate cycle count.
|
||||
u32 cFetch = 0;
|
||||
u32 cExecute = 0;
|
||||
|
||||
//this assert is annoying. but sometimes it is handy.
|
||||
//assert(ARMPROC.instruct_adr!=0x00000000);
|
||||
//#ifdef DEVELOPER
|
||||
#if 0
|
||||
if ((((ARMPROC.instruct_adr & 0x0F000000) == 0x0F000000) && (PROCNUM == 0)) ||
|
||||
(((ARMPROC.instruct_adr & 0x0F000000) == 0x00000000) && (PROCNUM == 1)))
|
||||
{
|
||||
switch (ARMPROC.instruct_adr & 0xFFFF)
|
||||
{
|
||||
case 0x00000000:
|
||||
printf("BIOS%c: Reset!!!\n", PROCNUM?'7':'9');
|
||||
emu_halt();
|
||||
break;
|
||||
case 0x00000004:
|
||||
printf("BIOS%c: Undefined instruction\n", PROCNUM?'7':'9');
|
||||
//emu_halt();
|
||||
break;
|
||||
case 0x00000008:
|
||||
//printf("BIOS%c: SWI\n", PROCNUM?'7':'9');
|
||||
break;
|
||||
case 0x0000000C:
|
||||
printf("BIOS%c: Prefetch Abort!!!\n", PROCNUM?'7':'9');
|
||||
//emu_halt();
|
||||
break;
|
||||
case 0x00000010:
|
||||
//printf("BIOS%c: Data Abort!!!\n", PROCNUM?'7':'9');
|
||||
//emu_halt();
|
||||
break;
|
||||
case 0x00000014:
|
||||
printf("BIOS%c: Reserved!!!\n", PROCNUM?'7':'9');
|
||||
break;
|
||||
case 0x00000018:
|
||||
//printf("BIOS%c: IRQ\n", PROCNUM?'7':'9');
|
||||
break;
|
||||
case 0x0000001C:
|
||||
printf("BIOS%c: Fast IRQ\n", PROCNUM?'7':'9');
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if 0 //#ifdef GDB_STUB
|
||||
if (ARMPROC.stalled) {
|
||||
return STALLED_CYCLE_COUNT;
|
||||
}
|
||||
|
||||
/* check for interrupts */
|
||||
if (ARMPROC.irq_flag) {
|
||||
armcpu_irqException(&ARMPROC);
|
||||
}
|
||||
|
||||
cFetch = armcpu_prefetch(&ARMPROC);
|
||||
|
||||
if (ARMPROC.stalled) {
|
||||
return MMU_fetchExecuteCycles<PROCNUM>(cExecute, cFetch);
|
||||
}
|
||||
#endif
|
||||
|
||||
//cFetch = armcpu_prefetch(&ARMPROC);
|
||||
|
||||
//printf("%d: %08X\n",PROCNUM,ARMPROC.instruct_adr);
|
||||
|
||||
if(ARMPROC.CPSR.bits.T == 0)
|
||||
{
|
||||
if(
|
||||
CONDITION(ARMPROC.instruction) == 0x0E //fast path for unconditional instructions
|
||||
|| (TEST_COND(CONDITION(ARMPROC.instruction), CODE(ARMPROC.instruction), ARMPROC.CPSR)) //handles any condition
|
||||
)
|
||||
{
|
||||
#ifdef HAVE_LUA
|
||||
CallRegisteredLuaMemHook(ARMPROC.instruct_adr, 4, ARMPROC.instruction, LUAMEMHOOK_EXEC); // should report even if condition=false?
|
||||
#endif
|
||||
#ifdef DEVELOPER
|
||||
DEBUG_statistics.instructionHits[PROCNUM].arm[INSTRUCTION_INDEX(ARMPROC.instruction)]++;
|
||||
#endif
|
||||
cExecute = arm_instructions_set[PROCNUM][INSTRUCTION_INDEX(ARMPROC.instruction)](ARMPROC.instruction);
|
||||
}
|
||||
else
|
||||
cExecute = 1; // If condition=false: 1S cycle
|
||||
#ifdef GDB_STUB
|
||||
if ( ARMPROC.post_ex_fn != NULL) {
|
||||
/* call the external post execute function */
|
||||
ARMPROC.post_ex_fn(ARMPROC.post_ex_fn_data, ARMPROC.instruct_adr, 0);
|
||||
}
|
||||
ARMPROC.mem_if->prefetch32( ARMPROC.mem_if->data, ARMPROC.next_instruction);
|
||||
#endif
|
||||
cFetch = armcpu_prefetch<PROCNUM>();
|
||||
return MMU_fetchExecuteCycles<PROCNUM>(cExecute, cFetch);
|
||||
}
|
||||
|
||||
#ifdef HAVE_LUA
|
||||
CallRegisteredLuaMemHook(ARMPROC.instruct_adr, 2, ARMPROC.instruction, LUAMEMHOOK_EXEC);
|
||||
#endif
|
||||
#ifdef DEVELOPER
|
||||
DEBUG_statistics.instructionHits[PROCNUM].thumb[ARMPROC.instruction>>6]++;
|
||||
#endif
|
||||
cExecute = thumb_instructions_set[PROCNUM][ARMPROC.instruction>>6](ARMPROC.instruction);
|
||||
|
||||
#ifdef GDB_STUB
|
||||
if ( ARMPROC.post_ex_fn != NULL) {
|
||||
/* call the external post execute function */
|
||||
ARMPROC.post_ex_fn( ARMPROC.post_ex_fn_data, ARMPROC.instruct_adr, 1);
|
||||
}
|
||||
ARMPROC.mem_if->prefetch32( ARMPROC.mem_if->data, ARMPROC.next_instruction);
|
||||
#endif
|
||||
cFetch = armcpu_prefetch<PROCNUM>();
|
||||
return MMU_fetchExecuteCycles<PROCNUM>(cExecute, cFetch);
|
||||
}
|
||||
|
||||
//these templates needed to be instantiated manually
|
||||
template u32 armcpu_exec<0>();
|
||||
template u32 armcpu_exec<1>();
|
||||
|
||||
#ifdef HAVE_JIT
|
||||
void arm_jit_sync()
|
||||
{
|
||||
NDS_ARM7.next_instruction = NDS_ARM7.instruct_adr;
|
||||
NDS_ARM9.next_instruction = NDS_ARM9.instruct_adr;
|
||||
armcpu_prefetch<0>();
|
||||
armcpu_prefetch<1>();
|
||||
}
|
||||
|
||||
template<int PROCNUM, bool jit>
|
||||
u32 armcpu_exec()
|
||||
{
|
||||
if (jit)
|
||||
{
|
||||
ARMPROC.instruct_adr &= ARMPROC.CPSR.bits.T?0xFFFFFFFE:0xFFFFFFFC;
|
||||
ArmOpCompiled f = (ArmOpCompiled)JIT_COMPILED_FUNC(ARMPROC.instruct_adr, PROCNUM);
|
||||
return f ? f() : arm_jit_compile<PROCNUM>();
|
||||
}
|
||||
|
||||
return armcpu_exec<PROCNUM>();
|
||||
}
|
||||
|
||||
template u32 armcpu_exec<0,false>();
|
||||
template u32 armcpu_exec<0,true>();
|
||||
template u32 armcpu_exec<1,false>();
|
||||
template u32 armcpu_exec<1,true>();
|
||||
#endif
|
||||
|
||||
void setIF(int PROCNUM, u32 flag)
|
||||
{
|
||||
//don't set generated bits!!!
|
||||
assert(!(flag&0x00200000));
|
||||
|
||||
MMU.reg_IF_bits[PROCNUM] |= flag;
|
||||
|
||||
NDS_Reschedule();
|
||||
}
|
||||
|
||||
char* decodeIntruction(bool thumb_mode, u32 instr)
|
||||
{
|
||||
char txt[20] = {0};
|
||||
u32 tmp = 0;
|
||||
if (thumb_mode == true)
|
||||
{
|
||||
tmp = (instr >> 6);
|
||||
strcpy(txt, intToBin((u16)tmp)+6);
|
||||
}
|
||||
else
|
||||
{
|
||||
tmp = ((instr >> 16) & 0x0FF0) | ((instr >> 4) & 0x0F);
|
||||
strcpy(txt, intToBin((u32)tmp)+20);
|
||||
}
|
||||
return strdup(txt);
|
||||
}
|
||||
|
||||
const armcpu_ctrl_iface arm_default_ctrl_iface = {
|
||||
stall_cpu,
|
||||
unstall_cpu,
|
||||
read_cpu_reg,
|
||||
set_cpu_reg,
|
||||
install_post_exec_fn,
|
||||
remove_post_exec_fn,
|
||||
NULL
|
||||
};
|
||||
Executable
+352
@@ -0,0 +1,352 @@
|
||||
/*
|
||||
Copyright (C) 2006 yopyop
|
||||
Copyright (C) 2006-2015 DeSmuME team
|
||||
|
||||
This file is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This file is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with the this software. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef ARM_CPU
|
||||
#define ARM_CPU
|
||||
|
||||
#include "types.h"
|
||||
#include "bits.h"
|
||||
#include "MMU.h"
|
||||
|
||||
#define CODE(i) (((i)>>25)&0x7)
|
||||
#define OPCODE(i) (((i)>>21)&0xF)
|
||||
#define SIGNEBIT(i) BIT_N(i,20)
|
||||
|
||||
#define EXCEPTION_RESET 0x00
|
||||
#define EXCEPTION_UNDEFINED_INSTRUCTION 0x04
|
||||
#define EXCEPTION_SWI 0x08
|
||||
#define EXCEPTION_PREFETCH_ABORT 0x0C
|
||||
#define EXCEPTION_DATA_ABORT 0x10
|
||||
#define EXCEPTION_RESERVED_0x14 0x14
|
||||
#define EXCEPTION_IRQ 0x18
|
||||
#define EXCEPTION_FAST_IRQ 0x1C
|
||||
|
||||
#define INSTRUCTION_INDEX(i) ((((i)>>16)&0xFF0)|(((i)>>4)&0xF))
|
||||
|
||||
inline u32 ROR(u32 i, u32 j) { return ((((u32)(i))>>(j)) | (((u32)(i))<<(32-(j)))); }
|
||||
|
||||
template<typename T>
|
||||
inline T UNSIGNED_OVERFLOW(T a,T b,T c) { return BIT31(((a)&(b)) | (((a)|(b))&(~c))); }
|
||||
|
||||
template<typename T>
|
||||
inline T UNSIGNED_UNDERFLOW(T a,T b,T c) { return BIT31(((~a)&(b)) | (((~a)|(b))&(c))); }
|
||||
|
||||
template<typename T>
|
||||
inline T SIGNED_OVERFLOW(T a,T b,T c) { return BIT31(((a)&(b)&(~c)) | ((~a)&(~(b))&(c))); }
|
||||
|
||||
template<typename T>
|
||||
inline T SIGNED_UNDERFLOW(T a,T b,T c) { return BIT31(((a)&(~(b))&(~c)) | ((~a)&(b)&(c))); }
|
||||
|
||||
#if !defined(bswap32)
|
||||
#define bswap32(val) \
|
||||
( (val << 24) & 0xFF000000) | \
|
||||
( (val << 8) & 0x00FF0000) | \
|
||||
( (val >> 8) & 0x0000FF00) | \
|
||||
( (val >> 24) & 0x000000FF)
|
||||
#endif
|
||||
|
||||
#if !defined(bswap64)
|
||||
#define bswap64(x) \
|
||||
( (x << 56) & 0xff00000000000000ULL ) | \
|
||||
( (x << 40) & 0x00ff000000000000ULL ) | \
|
||||
( (x << 24) & 0x0000ff0000000000ULL ) | \
|
||||
( (x << 8) & 0x000000ff00000000ULL ) | \
|
||||
( (x >> 8) & 0x00000000ff000000ULL ) | \
|
||||
( (x >> 24) & 0x0000000000ff0000ULL ) | \
|
||||
( (x >> 40) & 0x000000000000ff00ULL ) | \
|
||||
( (x >> 56) & 0x00000000000000ffULL )
|
||||
#endif
|
||||
|
||||
// ============================= CPRS flags funcs
|
||||
inline bool CarryFrom(s32 left, s32 right)
|
||||
{
|
||||
u32 res = (0xFFFFFFFFU - (u32)left);
|
||||
|
||||
return ((u32)right > res);
|
||||
}
|
||||
|
||||
inline bool BorrowFrom(s32 left, s32 right)
|
||||
{
|
||||
return ((u32)right > (u32)left);
|
||||
}
|
||||
|
||||
inline bool OverflowFromADD(s32 alu_out, s32 left, s32 right)
|
||||
{
|
||||
return ((left >= 0 && right >= 0) || (left < 0 && right < 0))
|
||||
&& ((left < 0 && alu_out >= 0) || (left >= 0 && alu_out < 0));
|
||||
}
|
||||
|
||||
inline bool OverflowFromSUB(s32 alu_out, s32 left, s32 right)
|
||||
{
|
||||
return ((left < 0 && right >= 0) || (left >= 0 && right < 0))
|
||||
&& ((left < 0 && alu_out >= 0) || (left >= 0 && alu_out < 0));
|
||||
}
|
||||
|
||||
//zero 15-feb-2009 - these werent getting used and they were getting in my way
|
||||
//#define EQ 0x0
|
||||
//#define NE 0x1
|
||||
//#define CS 0x2
|
||||
//#define CC 0x3
|
||||
//#define MI 0x4
|
||||
//#define PL 0x5
|
||||
//#define VS 0x6
|
||||
//#define VC 0x7
|
||||
//#define HI 0x8
|
||||
//#define LS 0x9
|
||||
//#define GE 0xA
|
||||
//#define LT 0xB
|
||||
//#define GT 0xC
|
||||
//#define LE 0xD
|
||||
//#define AL 0xE
|
||||
|
||||
static const u8 arm_cond_table[16*16] = {
|
||||
// N=0, Z=0, C=0, V=0
|
||||
0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF, // 0x00
|
||||
0x00,0xFF,0xFF,0x00,0xFF,0x00,0xFF,0x20, // 0x00
|
||||
// N=0, Z=0, C=0, V=1
|
||||
0x00,0xFF,0x00,0xFF,0x00,0xFF,0xFF,0x00, // 0x10
|
||||
0x00,0xFF,0x00,0xFF,0x00,0xFF,0xFF,0x20,
|
||||
// N=0, Z=0, C=1, V=0
|
||||
0x00,0xFF,0xFF,0x00,0x00,0xFF,0x00,0xFF, // 0x20
|
||||
0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF,0x20,
|
||||
// N=0, Z=0, C=1, V=1
|
||||
0x00,0xFF,0xFF,0x00,0x00,0xFF,0xFF,0x00, // 0x30
|
||||
0xFF,0x00,0x00,0xFF,0x00,0xFF,0xFF,0x20,
|
||||
// N=0, Z=1, C=0, V=0
|
||||
0xFF,0x00,0x00,0xFF,0x00,0xFF,0x00,0xFF, // 0x40
|
||||
0x00,0xFF,0xFF,0x00,0x00,0xFF,0xFF,0x20,
|
||||
// N=0, Z=1, C=0, V=1
|
||||
0xFF,0x00,0x00,0xFF,0x00,0xFF,0xFF,0x00, // 0x50
|
||||
0x00,0xFF,0x00,0xFF,0x00,0xFF,0xFF,0x20,
|
||||
// N=0, Z=1, C=1, V=0
|
||||
0xFF,0x00,0xFF,0x00,0x00,0xFF,0x00,0xFF, // 0x60
|
||||
0x00,0xFF,0xFF,0x00,0x00,0xFF,0xFF,0x20,
|
||||
// N=0, Z=1, C=1, V=1
|
||||
0xFF,0x00,0xFF,0x00,0x00,0xFF,0xFF,0x00, // 0x70
|
||||
0x00,0xFF,0x00,0xFF,0x00,0xFF,0xFF,0x20,
|
||||
// N=1, Z=0, C=0, V=0
|
||||
0x00,0xFF,0x00,0xFF,0xFF,0x00,0x00,0xFF, // 0x80
|
||||
0x00,0xFF,0x00,0xFF,0x00,0xFF,0xFF,0x20,
|
||||
// N=1, Z=0, C=0, V=1
|
||||
0x00,0xFF,0x00,0xFF,0xFF,0x00,0xFF,0x00, // 0x90
|
||||
0x00,0xFF,0xFF,0x00,0xFF,0x00,0xFF,0x20,
|
||||
// N=1, Z=0, C=1, V=0
|
||||
0x00,0xFF,0xFF,0x00,0xFF,0x00,0x00,0xFF, // 0xA0
|
||||
0xFF,0x00,0x00,0xFF,0x00,0xFF,0xFF,0x20,
|
||||
// N=1, Z=0, C=1, V=1
|
||||
0x00,0xFF,0xFF,0x00,0xFF,0x00,0xFF,0x00, // 0xB0
|
||||
0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF,0x20,
|
||||
// N=1, Z=1, C=0, V=0
|
||||
0xFF,0x00,0x00,0xFF,0xFF,0x00,0x00,0xFF, // 0xC0
|
||||
0x00,0xFF,0x00,0xFF,0x00,0xFF,0xFF,0x20,
|
||||
// N=1, Z=1, C=0, V=1
|
||||
0xFF,0x00,0x00,0xFF,0xFF,0x00,0xFF,0x00, // 0xD0
|
||||
0x00,0xFF,0xFF,0x00,0x00,0xFF,0xFF,0x20,
|
||||
// N=1, Z=1, C=1, V=0
|
||||
0xFF,0x00,0xFF,0x00,0xFF,0x00,0x00,0xFF, // 0xE0
|
||||
0x00,0xFF,0x00,0xFF,0x00,0xFF,0xFF,0x20,
|
||||
// N=1, Z=1, C=1, V=1
|
||||
0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00, // 0xF0
|
||||
0x00,0xFF,0xFF,0x00,0x00,0xFF,0xFF,0x20
|
||||
};
|
||||
|
||||
#define TEST_COND(cond, inst, CPSR) ((arm_cond_table[((CPSR.val >> 24) & 0xf0)|(cond)]) & (1 << (inst)))
|
||||
|
||||
|
||||
enum Mode
|
||||
{
|
||||
USR = 0x10,
|
||||
FIQ = 0x11,
|
||||
IRQ = 0x12,
|
||||
SVC = 0x13,
|
||||
ABT = 0x17,
|
||||
UND = 0x1B,
|
||||
SYS = 0x1F
|
||||
};
|
||||
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
typedef union
|
||||
{
|
||||
struct
|
||||
{
|
||||
u32 N : 1,
|
||||
Z : 1,
|
||||
C : 1,
|
||||
V : 1,
|
||||
Q : 1,
|
||||
RAZ : 19,
|
||||
I : 1,
|
||||
F : 1,
|
||||
T : 1,
|
||||
mode : 5;
|
||||
} bits;
|
||||
u32 val;
|
||||
} Status_Reg;
|
||||
#else
|
||||
typedef union
|
||||
{
|
||||
struct
|
||||
{
|
||||
u32 mode : 5,
|
||||
T : 1,
|
||||
F : 1,
|
||||
I : 1,
|
||||
RAZ : 19,
|
||||
Q : 1,
|
||||
V : 1,
|
||||
C : 1,
|
||||
Z : 1,
|
||||
N : 1;
|
||||
} bits;
|
||||
u32 val;
|
||||
} Status_Reg;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* The control interface to a CPU
|
||||
*/
|
||||
struct armcpu_ctrl_iface
|
||||
{
|
||||
/** stall the processor */
|
||||
void (*stall)( void *instance);
|
||||
|
||||
/** unstall the processor */
|
||||
void (*unstall)( void *instance);
|
||||
|
||||
/** read a register value */
|
||||
u32 (*read_reg)( void *instance, u32 reg_num);
|
||||
|
||||
/** set a register value */
|
||||
void (*set_reg)( void *instance, u32 reg_num, u32 value);
|
||||
|
||||
/** install the post execute function */
|
||||
void (*install_post_ex_fn)( void *instance,
|
||||
void (*fn)( void *, u32 adr, int thumb),
|
||||
void *fn_data);
|
||||
|
||||
/** remove the post execute function */
|
||||
void (*remove_post_ex_fn)( void *instance);
|
||||
|
||||
/** the private data passed to all interface functions */
|
||||
void *data;
|
||||
};
|
||||
|
||||
|
||||
typedef void* armcp_t;
|
||||
|
||||
struct armcpu_t
|
||||
{
|
||||
u32 proc_ID;
|
||||
u32 instruction; //4
|
||||
u32 instruct_adr; //8
|
||||
u32 next_instruction; //12
|
||||
|
||||
u32 R[16]; //16
|
||||
Status_Reg CPSR; //80
|
||||
Status_Reg SPSR;
|
||||
|
||||
void SetControlInterface(const armcpu_ctrl_iface *theCtrlInterface);
|
||||
armcpu_ctrl_iface* GetControlInterface();
|
||||
void SetControlInterfaceData(void *theData);
|
||||
void* GetControlInterfaceData();
|
||||
|
||||
void SetCurrentMemoryInterface(armcpu_memory_iface *theMemInterface);
|
||||
armcpu_memory_iface* GetCurrentMemoryInterface();
|
||||
void SetCurrentMemoryInterfaceData(void *theData);
|
||||
void* GetCurrentMemoryInterfaceData();
|
||||
|
||||
void SetBaseMemoryInterface(const armcpu_memory_iface *theMemInterface);
|
||||
armcpu_memory_iface* GetBaseMemoryInterface();
|
||||
void SetBaseMemoryInterfaceData(void *theData);
|
||||
void* GetBaseMemoryInterfaceData();
|
||||
|
||||
void ResetMemoryInterfaceToBase();
|
||||
|
||||
void changeCPSR();
|
||||
|
||||
u32 R13_usr, R14_usr;
|
||||
u32 R13_svc, R14_svc;
|
||||
u32 R13_abt, R14_abt;
|
||||
u32 R13_und, R14_und;
|
||||
u32 R13_irq, R14_irq;
|
||||
u32 R8_fiq, R9_fiq, R10_fiq, R11_fiq, R12_fiq, R13_fiq, R14_fiq;
|
||||
Status_Reg SPSR_svc, SPSR_abt, SPSR_und, SPSR_irq, SPSR_fiq;
|
||||
|
||||
u32 intVector;
|
||||
u8 LDTBit; //1 : ARMv5 style 0 : non ARMv5 (earlier)
|
||||
BOOL waitIRQ;
|
||||
BOOL halt_IE_and_IF; //the cpu is halted, waiting for IE&IF to signal something
|
||||
u8 intrWaitARM_state;
|
||||
|
||||
BOOL BIOS_loaded;
|
||||
|
||||
u32 (* *swi_tab)();
|
||||
|
||||
// flag indicating if the processor is stalled (for debugging)
|
||||
int stalled;
|
||||
|
||||
#if defined(_M_X64) || defined(__x86_64__)
|
||||
u8 cond_table[16*16];
|
||||
#endif
|
||||
|
||||
/** there is a pending irq for the cpu */
|
||||
int irq_flag;
|
||||
|
||||
/** the post executed function (if installed) */
|
||||
void (*post_ex_fn)( void *, u32 adr, int thumb);
|
||||
|
||||
/** data for the post executed function */
|
||||
void *post_ex_fn_data;
|
||||
|
||||
/** the memory interface */
|
||||
armcpu_memory_iface *mem_if; // This is the memory interface currently in use.
|
||||
armcpu_memory_iface base_mem_if; // This is the CPU's base memory interface.
|
||||
|
||||
/** the ctrl interface */
|
||||
armcpu_ctrl_iface ctrl_iface;
|
||||
};
|
||||
|
||||
int armcpu_new( armcpu_t *armcpu, u32 id);
|
||||
void armcpu_init(armcpu_t *armcpu, u32 adr);
|
||||
u32 armcpu_switchMode(armcpu_t *armcpu, u8 mode);
|
||||
|
||||
|
||||
BOOL armcpu_irqException(armcpu_t *armcpu);
|
||||
BOOL armcpu_flagIrq( armcpu_t *armcpu);
|
||||
void armcpu_exception(armcpu_t *cpu, u32 number);
|
||||
u32 TRAPUNDEF(armcpu_t* cpu);
|
||||
u32 armcpu_Wait4IRQ(armcpu_t *cpu);
|
||||
|
||||
extern armcpu_t NDS_ARM7;
|
||||
extern armcpu_t NDS_ARM9;
|
||||
extern const armcpu_ctrl_iface arm_default_ctrl_iface;
|
||||
|
||||
template<int PROCNUM> u32 armcpu_exec();
|
||||
#ifdef HAVE_JIT
|
||||
template<int PROCNUM, bool jit> u32 armcpu_exec();
|
||||
#endif
|
||||
|
||||
void setIF(int PROCNUM, u32 flag);
|
||||
char* decodeIntruction(bool thumb_mode, u32 instr);
|
||||
|
||||
static INLINE void NDS_makeIrq(int PROCNUM, u32 num)
|
||||
{
|
||||
setIF(PROCNUM,1<<num);
|
||||
}
|
||||
|
||||
#endif
|
||||
Executable
+1293
File diff suppressed because it is too large
Load Diff
Executable
+28
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
Copyright (C) 2006 yopyop
|
||||
Copyright (C) 2006-2015 DeSmuME team
|
||||
|
||||
This file is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This file is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with the this software. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef BIOS_H
|
||||
#define BIOS_H
|
||||
|
||||
#include "types.h"
|
||||
|
||||
extern u32 (* ARM_swi_tab[2][32])();
|
||||
extern const char* ARM_swi_names[2][32];
|
||||
|
||||
#endif
|
||||
|
||||
Executable
+44
@@ -0,0 +1,44 @@
|
||||
#ifndef BITS_H
|
||||
#define BITS_H
|
||||
|
||||
#define BIT(n) (1<<(n))
|
||||
|
||||
#define BIT_N(i,n) (((i)>>(n))&1)
|
||||
#define BIT0(i) ((i)&1)
|
||||
#define BIT1(i) BIT_N(i,1)
|
||||
#define BIT2(i) BIT_N(i,2)
|
||||
#define BIT3(i) BIT_N(i,3)
|
||||
#define BIT4(i) BIT_N(i,4)
|
||||
#define BIT5(i) BIT_N(i,5)
|
||||
#define BIT6(i) BIT_N(i,6)
|
||||
#define BIT7(i) BIT_N(i,7)
|
||||
#define BIT8(i) BIT_N(i,8)
|
||||
#define BIT9(i) BIT_N(i,9)
|
||||
#define BIT10(i) BIT_N(i,10)
|
||||
#define BIT11(i) BIT_N(i,11)
|
||||
#define BIT12(i) BIT_N(i,12)
|
||||
#define BIT13(i) BIT_N(i,13)
|
||||
#define BIT14(i) BIT_N(i,14)
|
||||
#define BIT15(i) BIT_N(i,15)
|
||||
#define BIT16(i) BIT_N(i,16)
|
||||
#define BIT17(i) BIT_N(i,17)
|
||||
#define BIT18(i) BIT_N(i,18)
|
||||
#define BIT19(i) BIT_N(i,19)
|
||||
#define BIT20(i) BIT_N(i,20)
|
||||
#define BIT21(i) BIT_N(i,21)
|
||||
#define BIT22(i) BIT_N(i,22)
|
||||
#define BIT23(i) BIT_N(i,23)
|
||||
#define BIT24(i) BIT_N(i,24)
|
||||
#define BIT25(i) BIT_N(i,25)
|
||||
#define BIT26(i) BIT_N(i,26)
|
||||
#define BIT27(i) BIT_N(i,27)
|
||||
#define BIT28(i) BIT_N(i,28)
|
||||
#define BIT29(i) BIT_N(i,29)
|
||||
#define BIT30(i) BIT_N(i,30)
|
||||
#define BIT31(i) ((i)>>31)
|
||||
|
||||
#define CONDITION(i) (i)>>28
|
||||
|
||||
#define REG_POS(i,n) (((i)>>n)&0xF)
|
||||
|
||||
#endif
|
||||
Executable
+4
@@ -0,0 +1,4 @@
|
||||
configure
|
||||
make clean
|
||||
make
|
||||
pause
|
||||
Executable
+1445
File diff suppressed because it is too large
Load Diff
Executable
+198
@@ -0,0 +1,198 @@
|
||||
/*
|
||||
Copyright (C) 2009-2015 DeSmuME team
|
||||
|
||||
This file is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This file is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with the this software. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include "types.h"
|
||||
|
||||
#define CHEAT_VERSION_MAJOR 2
|
||||
#define CHEAT_VERSION_MINOR 0
|
||||
#define MAX_CHEAT_LIST 100
|
||||
#define MAX_XX_CODE 1024
|
||||
#define CHEAT_FILE_MIN_FGETS_BUFFER 32768
|
||||
#define CHEAT_DB_GAME_TITLE_SIZE 256
|
||||
|
||||
struct CHEATS_LIST
|
||||
{
|
||||
CHEATS_LIST()
|
||||
{
|
||||
memset(this,0,sizeof(*this));
|
||||
type = 0xFF;
|
||||
}
|
||||
u8 type; // 0 - internal cheat system
|
||||
// 1 - Action Replay
|
||||
// 2 - Codebreakers
|
||||
BOOL enabled;
|
||||
// TODO
|
||||
u8 freezeType; // 0 - normal freeze
|
||||
// 1 - can decrease
|
||||
// 2 - can increase
|
||||
u32 code[MAX_XX_CODE][2];
|
||||
char description[1024];
|
||||
int num;
|
||||
u8 size;
|
||||
};
|
||||
|
||||
class CHEATS
|
||||
{
|
||||
private:
|
||||
std::vector<CHEATS_LIST> list;
|
||||
u8 filename[MAX_PATH];
|
||||
u32 currentGet;
|
||||
|
||||
void clear();
|
||||
void ARparser(CHEATS_LIST& cheat);
|
||||
char *clearCode(char *s);
|
||||
|
||||
public:
|
||||
CHEATS()
|
||||
: currentGet(0)
|
||||
{
|
||||
memset(filename, 0, sizeof(filename));
|
||||
}
|
||||
~CHEATS() {}
|
||||
|
||||
void init(char *path);
|
||||
BOOL add(u8 size, u32 address, u32 val, char *description, BOOL enabled);
|
||||
BOOL update(u8 size, u32 address, u32 val, char *description, BOOL enabled, u32 pos);
|
||||
BOOL add_AR(char *code, char *description, BOOL enabled);
|
||||
BOOL update_AR(char *code, char *description, BOOL enabled, u32 pos);
|
||||
BOOL add_AR_Direct(CHEATS_LIST cheat);
|
||||
BOOL add_CB(char *code, char *description, BOOL enabled);
|
||||
BOOL update_CB(char *code, char *description, BOOL enabled, u32 pos);
|
||||
BOOL remove(u32 pos);
|
||||
void getListReset();
|
||||
BOOL getList(CHEATS_LIST *cheat);
|
||||
CHEATS_LIST* getListPtr();
|
||||
BOOL get(CHEATS_LIST *cheat, u32 pos);
|
||||
CHEATS_LIST* getItemByIndex(const u32 pos);
|
||||
u32 getSize();
|
||||
size_t getActiveCount();
|
||||
void setDescription(const char *description, u32 pos);
|
||||
BOOL save();
|
||||
BOOL load();
|
||||
void process();
|
||||
void getXXcodeString(CHEATS_LIST cheat, char *res_buf);
|
||||
|
||||
static BOOL XXCodeFromString(CHEATS_LIST *cheatItem, const std::string codeString);
|
||||
static BOOL XXCodeFromString(CHEATS_LIST *cheatItem, const char *codeString);
|
||||
};
|
||||
|
||||
class CHEATSEARCH
|
||||
{
|
||||
private:
|
||||
u8 *statMem;
|
||||
u8 *mem;
|
||||
u32 amount;
|
||||
u32 lastRecord;
|
||||
|
||||
u32 _type;
|
||||
u32 _size;
|
||||
u32 _sign;
|
||||
|
||||
public:
|
||||
CHEATSEARCH()
|
||||
: statMem(0), mem(0), amount(0), lastRecord(0), _type(0), _size(0), _sign(0)
|
||||
{}
|
||||
~CHEATSEARCH() { close(); }
|
||||
BOOL start(u8 type, u8 size, u8 sign);
|
||||
BOOL close();
|
||||
u32 search(u32 val);
|
||||
u32 search(u8 comp);
|
||||
u32 getAmount();
|
||||
BOOL getList(u32 *address, u32 *curVal);
|
||||
void getListReset();
|
||||
};
|
||||
|
||||
enum CHEATS_DB_TYPE
|
||||
{
|
||||
CHEATS_DB_R4 = 0
|
||||
};
|
||||
|
||||
#pragma pack(push)
|
||||
#pragma pack(1)
|
||||
typedef struct FAT_R4
|
||||
{
|
||||
u8 serial[4];
|
||||
u32 CRC;
|
||||
u64 addr;
|
||||
} FAT_R4;
|
||||
#pragma pack(pop)
|
||||
|
||||
class CHEATSEXPORT
|
||||
{
|
||||
private:
|
||||
CHEATS_DB_TYPE type;
|
||||
bool encrypted;
|
||||
FILE *fp;
|
||||
u32 fsize;
|
||||
u32 dataSize;
|
||||
u32 encOffset;
|
||||
FAT_R4 fat;
|
||||
bool search();
|
||||
bool getCodes();
|
||||
void R4decrypt(u8 *buf, u32 len, u32 n);
|
||||
|
||||
u32 numCheats;
|
||||
CHEATS_LIST *cheats;
|
||||
|
||||
u8 error; // 0 - no errors
|
||||
// 1 - open failed/file not found
|
||||
// 2 - file format is wrong (no valid header ID)
|
||||
// 3 - cheat not found in database
|
||||
// 4 - export error from database
|
||||
|
||||
public:
|
||||
CHEATSEXPORT() :
|
||||
fp(NULL),
|
||||
fsize(0),
|
||||
dataSize(0),
|
||||
encOffset(0),
|
||||
type(CHEATS_DB_R4),
|
||||
encrypted(false),
|
||||
numCheats(0),
|
||||
cheats(0),
|
||||
CRC(0),
|
||||
error(0)
|
||||
{
|
||||
memset(date, 0, sizeof(date));
|
||||
gametitle = (u8 *)malloc(CHEAT_DB_GAME_TITLE_SIZE);
|
||||
memset(gametitle, 0, CHEAT_DB_GAME_TITLE_SIZE);
|
||||
}
|
||||
~CHEATSEXPORT()
|
||||
{
|
||||
free(gametitle);
|
||||
gametitle = NULL;
|
||||
}
|
||||
|
||||
u8 *gametitle;
|
||||
u8 date[17];
|
||||
u32 CRC;
|
||||
bool load(char *path);
|
||||
void close();
|
||||
CHEATS_LIST *getCheats();
|
||||
u32 getCheatsNum();
|
||||
u8 getErrorCode() { return error; }
|
||||
};
|
||||
|
||||
extern CHEATS *cheats;
|
||||
extern CHEATSEARCH *cheatSearch;
|
||||
|
||||
|
||||
Executable
BIN
Binary file not shown.
Executable
BIN
Binary file not shown.
Executable
BIN
Binary file not shown.
Executable
BIN
Binary file not shown.
Executable
BIN
Binary file not shown.
Executable
BIN
Binary file not shown.
+3787
File diff suppressed because it is too large
Load Diff
+86
@@ -0,0 +1,86 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "0440"
|
||||
version = "1.3">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
buildImplicitDependencies = "YES">
|
||||
<BuildActionEntries>
|
||||
<BuildActionEntry
|
||||
buildForTesting = "YES"
|
||||
buildForRunning = "YES"
|
||||
buildForProfiling = "YES"
|
||||
buildForArchiving = "YES"
|
||||
buildForAnalyzing = "YES">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "AB796CA415CDCBA200C59155"
|
||||
BuildableName = "DeSmuME.app"
|
||||
BlueprintName = "DeSmuME (OS X App)"
|
||||
ReferencedContainer = "container:DeSmuME (Latest).xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildActionEntry>
|
||||
</BuildActionEntries>
|
||||
</BuildAction>
|
||||
<TestAction
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
shouldUseLaunchSchemeArgsEnv = "YES"
|
||||
buildConfiguration = "Debug">
|
||||
<Testables>
|
||||
</Testables>
|
||||
<MacroExpansion>
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "AB796CA415CDCBA200C59155"
|
||||
BuildableName = "DeSmuME.app"
|
||||
BlueprintName = "DeSmuME (OS X App)"
|
||||
ReferencedContainer = "container:DeSmuME (Latest).xcodeproj">
|
||||
</BuildableReference>
|
||||
</MacroExpansion>
|
||||
</TestAction>
|
||||
<LaunchAction
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
launchStyle = "0"
|
||||
useCustomWorkingDirectory = "NO"
|
||||
buildConfiguration = "Debug"
|
||||
ignoresPersistentStateOnLaunch = "NO"
|
||||
debugDocumentVersioning = "YES"
|
||||
allowLocationSimulation = "YES">
|
||||
<BuildableProductRunnable>
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "AB796CA415CDCBA200C59155"
|
||||
BuildableName = "DeSmuME.app"
|
||||
BlueprintName = "DeSmuME (OS X App)"
|
||||
ReferencedContainer = "container:DeSmuME (Latest).xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildableProductRunnable>
|
||||
<AdditionalOptions>
|
||||
</AdditionalOptions>
|
||||
</LaunchAction>
|
||||
<ProfileAction
|
||||
shouldUseLaunchSchemeArgsEnv = "YES"
|
||||
savedToolIdentifier = ""
|
||||
useCustomWorkingDirectory = "NO"
|
||||
buildConfiguration = "Release"
|
||||
debugDocumentVersioning = "YES">
|
||||
<BuildableProductRunnable>
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "AB796CA415CDCBA200C59155"
|
||||
BuildableName = "DeSmuME.app"
|
||||
BlueprintName = "DeSmuME (OS X App)"
|
||||
ReferencedContainer = "container:DeSmuME (Latest).xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildableProductRunnable>
|
||||
</ProfileAction>
|
||||
<AnalyzeAction
|
||||
buildConfiguration = "Debug">
|
||||
</AnalyzeAction>
|
||||
<ArchiveAction
|
||||
buildConfiguration = "Release"
|
||||
revealArchiveInOrganizer = "YES">
|
||||
</ArchiveAction>
|
||||
</Scheme>
|
||||
+58
@@ -0,0 +1,58 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
version = "1.3">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
buildImplicitDependencies = "YES">
|
||||
<BuildActionEntries>
|
||||
<BuildActionEntry
|
||||
buildForTesting = "YES"
|
||||
buildForRunning = "YES"
|
||||
buildForProfiling = "YES"
|
||||
buildForArchiving = "YES"
|
||||
buildForAnalyzing = "YES">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "ABB3C6461501BC6D00E0C22E"
|
||||
BuildableName = "DeSmuME.oecoreplugin"
|
||||
BlueprintName = "DeSmuME (OpenEmu Plug-in)"
|
||||
ReferencedContainer = "container:DeSmuME (Latest).xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildActionEntry>
|
||||
</BuildActionEntries>
|
||||
</BuildAction>
|
||||
<TestAction
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
shouldUseLaunchSchemeArgsEnv = "YES"
|
||||
buildConfiguration = "Debug">
|
||||
<Testables>
|
||||
</Testables>
|
||||
</TestAction>
|
||||
<LaunchAction
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
launchStyle = "0"
|
||||
useCustomWorkingDirectory = "NO"
|
||||
buildConfiguration = "Debug"
|
||||
ignoresPersistentStateOnLaunch = "NO"
|
||||
debugDocumentVersioning = "YES"
|
||||
allowLocationSimulation = "YES">
|
||||
<AdditionalOptions>
|
||||
</AdditionalOptions>
|
||||
</LaunchAction>
|
||||
<ProfileAction
|
||||
shouldUseLaunchSchemeArgsEnv = "YES"
|
||||
savedToolIdentifier = ""
|
||||
useCustomWorkingDirectory = "NO"
|
||||
buildConfiguration = "Release"
|
||||
debugDocumentVersioning = "YES">
|
||||
</ProfileAction>
|
||||
<AnalyzeAction
|
||||
buildConfiguration = "Debug">
|
||||
</AnalyzeAction>
|
||||
<ArchiveAction
|
||||
buildConfiguration = "Release"
|
||||
revealArchiveInOrganizer = "YES">
|
||||
</ArchiveAction>
|
||||
</Scheme>
|
||||
+4443
File diff suppressed because it is too large
Load Diff
Executable
+264
@@ -0,0 +1,264 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
|
||||
<CodeBlocks_project_file>
|
||||
<FileVersion major="1" minor="6" />
|
||||
<Project>
|
||||
<Option title="DeSmuME Cocoa" />
|
||||
<Option platforms="Mac;" />
|
||||
<Option pch_mode="2" />
|
||||
<Option default_target="Cocoa X86" />
|
||||
<Option compiler="gcc" />
|
||||
<Option show_notes="0">
|
||||
<notes>
|
||||
<![CDATA[DeSmuME
|
||||
|
||||
Note that when building DeSmuME with this Code::Blocks project, compatibility may be worse than when building with the XCode project.
|
||||
|
||||
Cocoa Port
|
||||
|
||||
DeSmuME 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.
|
||||
|
||||
DeSmuME 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 DeSmuME; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA]]>
|
||||
</notes>
|
||||
</Option>
|
||||
<Build>
|
||||
<Target title="Cocoa X86">
|
||||
<Option platforms="Mac;" />
|
||||
<Option output="build/codeblocks/DeSmuME.app/Contents/MacOS/DeSmuME" prefix_auto="0" extension_auto="0" />
|
||||
<Option working_dir="build/codeblocks/DeSmuME.app/Contents/MacOS" />
|
||||
<Option object_output="build/codeblocks/x86" />
|
||||
<Option type="1" />
|
||||
<Option compiler="gcc" />
|
||||
<Compiler>
|
||||
<Add option="-march=pentium-m" />
|
||||
<Add option="-msse2" />
|
||||
<Add option="-DDESMUME_COCOA" />
|
||||
<Add option="-DHAVE_LIBZ" />
|
||||
<Add option="-DHAVE_OPENGL" />
|
||||
</Compiler>
|
||||
<ExtraCommands>
|
||||
<Add after="cp DeSmuME.app/Contents/MacOS/DeSmuME DeSmuME.app/Contents/MacOS/DeSmuME_x86" />
|
||||
</ExtraCommands>
|
||||
</Target>
|
||||
<Target title="Cocoa PPC">
|
||||
<Option platforms="Mac;" />
|
||||
<Option output="build/codeblocks/DeSmuME.app/Contents/MacOS/DeSmuME" prefix_auto="0" extension_auto="0" />
|
||||
<Option working_dir="build/codeblocks/DeSmuME.app/Contents/MacOS" />
|
||||
<Option object_output="build/codeblocks/ppc" />
|
||||
<Option type="1" />
|
||||
<Option compiler="gcc" />
|
||||
<Compiler>
|
||||
<Add option="-arch ppc" />
|
||||
<Add option="-DDESMUME_COCOA" />
|
||||
<Add option="-DHAVE_LIBZ" />
|
||||
<Add option="-DHAVE_OPENGL" />
|
||||
</Compiler>
|
||||
<Linker>
|
||||
<Add option="-arch ppc" />
|
||||
</Linker>
|
||||
<ExtraCommands>
|
||||
<Add after="cp DeSmuME.app/Contents/MacOS/DeSmuME DeSmuME.app/Contents/MacOS/DeSmuME_ppc" />
|
||||
</ExtraCommands>
|
||||
</Target>
|
||||
</Build>
|
||||
<VirtualTargets>
|
||||
<Add alias="Cocoa Universal" targets="Cocoa X86;Cocoa PPC;" />
|
||||
</VirtualTargets>
|
||||
<Compiler>
|
||||
<Add option="-fexpensive-optimizations" />
|
||||
<Add option="-O3" />
|
||||
<Add option="-fpascal-strings -fasm-blocks" />
|
||||
<Add option="-DDESMUME_OBJ_C" />
|
||||
</Compiler>
|
||||
<Linker>
|
||||
<Add option="-framework Cocoa" />
|
||||
<Add option="-framework OpenGL" />
|
||||
<Add option="-framework AudioUnit" />
|
||||
<Add option="-lz" />
|
||||
</Linker>
|
||||
<ExtraCommands>
|
||||
<Add after="./makeapp.sh" />
|
||||
<Mode after="always" />
|
||||
</ExtraCommands>
|
||||
<Unit filename="../ARM9.h" />
|
||||
<Unit filename="../Disassembler.cpp" />
|
||||
<Unit filename="../Disassembler.h" />
|
||||
<Unit filename="../FIFO.cpp" />
|
||||
<Unit filename="../FIFO.h" />
|
||||
<Unit filename="../GPU.cpp" />
|
||||
<Unit filename="../GPU.h" />
|
||||
<Unit filename="../GPU_osd.cpp" />
|
||||
<Unit filename="../GPU_osd.h" />
|
||||
<Unit filename="../MMU.cpp" />
|
||||
<Unit filename="../MMU.h" />
|
||||
<Unit filename="../NDSSystem.cpp" />
|
||||
<Unit filename="../NDSSystem.h" />
|
||||
<Unit filename="../OGLRender.cpp" />
|
||||
<Unit filename="../OGLRender.h" />
|
||||
<Unit filename="../PACKED.h" />
|
||||
<Unit filename="../PACKED_END.h" />
|
||||
<Unit filename="../ROMReader.cpp" />
|
||||
<Unit filename="../ROMReader.h" />
|
||||
<Unit filename="../SPU.cpp" />
|
||||
<Unit filename="../SPU.h" />
|
||||
<Unit filename="../addons.cpp" />
|
||||
<Unit filename="../addons.h" />
|
||||
<Unit filename="../addons/compactFlash.cpp" />
|
||||
<Unit filename="../addons/gbagame.cpp" />
|
||||
<Unit filename="../addons/none.cpp" />
|
||||
<Unit filename="../addons/rumblepak.cpp" />
|
||||
<Unit filename="../arm_instructions.cpp" />
|
||||
<Unit filename="../arm_instructions.h" />
|
||||
<Unit filename="../armcpu.cpp" />
|
||||
<Unit filename="../armcpu.h" />
|
||||
<Unit filename="../bios.cpp" />
|
||||
<Unit filename="../bios.h" />
|
||||
<Unit filename="../bits.h" />
|
||||
<Unit filename="../cflash.cpp" />
|
||||
<Unit filename="../cflash.h" />
|
||||
<Unit filename="../cheatSystem.cpp" />
|
||||
<Unit filename="../cheatSystem.h" />
|
||||
<Unit filename="English.strings" />
|
||||
<Unit filename="Japanese.strings" />
|
||||
<Unit filename="about.m">
|
||||
<Option compile="1" />
|
||||
<Option link="1" />
|
||||
</Unit>
|
||||
<Unit filename="cocoa_util.m">
|
||||
<Option compile="1" />
|
||||
<Option link="1" />
|
||||
</Unit>
|
||||
<Unit filename="dialogs/rom_info.h" />
|
||||
<Unit filename="dialogs/rom_info.m">
|
||||
<Option compile="1" />
|
||||
<Option link="1" />
|
||||
</Unit>
|
||||
<Unit filename="dialogs/speed_limit_selection_window.h" />
|
||||
<Unit filename="dialogs/speed_limit_selection_window.m">
|
||||
<Option compile="1" />
|
||||
<Option link="1" />
|
||||
</Unit>
|
||||
<Unit filename="globals.h" />
|
||||
<Unit filename="input.h" />
|
||||
<Unit filename="input.m">
|
||||
<Option compile="1" />
|
||||
<Option link="1" />
|
||||
</Unit>
|
||||
<Unit filename="main.m">
|
||||
<Option compile="1" />
|
||||
<Option link="1" />
|
||||
</Unit>
|
||||
<Unit filename="main_window.h" />
|
||||
<Unit filename="main_window.m">
|
||||
<Option compile="1" />
|
||||
<Option link="1" />
|
||||
</Unit>
|
||||
<Unit filename="nds_control.h" />
|
||||
<Unit filename="nds_control.mm">
|
||||
<Option compile="1" />
|
||||
<Option link="1" />
|
||||
</Unit>
|
||||
<Unit filename="preferences.h" />
|
||||
<Unit filename="preferences.m">
|
||||
<Option compile="1" />
|
||||
<Option link="1" />
|
||||
</Unit>
|
||||
<Unit filename="screen_state.h" />
|
||||
<Unit filename="screen_state.m">
|
||||
<Option compile="1" />
|
||||
<Option link="1" />
|
||||
</Unit>
|
||||
<Unit filename="screenshot.h" />
|
||||
<Unit filename="screenshot.m">
|
||||
<Option compile="1" />
|
||||
<Option link="1" />
|
||||
</Unit>
|
||||
<Unit filename="sndOSX.h" />
|
||||
<Unit filename="sndOSX.mm">
|
||||
<Option compile="1" />
|
||||
<Option link="1" />
|
||||
</Unit>
|
||||
<Unit filename="video_output_view.h" />
|
||||
<Unit filename="video_output_view.m">
|
||||
<Option compile="1" />
|
||||
<Option link="1" />
|
||||
</Unit>
|
||||
<Unit filename="../common.cpp" />
|
||||
<Unit filename="../common.h" />
|
||||
<Unit filename="../cp15.cpp" />
|
||||
<Unit filename="../cp15.h" />
|
||||
<Unit filename="../ctrlssdl.h" />
|
||||
<Unit filename="../debug.cpp" />
|
||||
<Unit filename="../debug.h" />
|
||||
<Unit filename="../dscard.h" />
|
||||
<Unit filename="../fat.h" />
|
||||
<Unit filename="../fs-linux.cpp" />
|
||||
<Unit filename="../fs.h" />
|
||||
<Unit filename="../gdbstub.h" />
|
||||
<Unit filename="../gfx3d.cpp" />
|
||||
<Unit filename="../gfx3d.h" />
|
||||
<Unit filename="../matrix.cpp" />
|
||||
<Unit filename="../matrix.h" />
|
||||
<Unit filename="../mc.cpp" />
|
||||
<Unit filename="../mc.h" />
|
||||
<Unit filename="../mem.h" />
|
||||
<Unit filename="../memorystream.h" />
|
||||
<Unit filename="../mic.cpp" />
|
||||
<Unit filename="../mic.h" />
|
||||
<Unit filename="../movie.cpp" />
|
||||
<Unit filename="../movie.h" />
|
||||
<Unit filename="../readwrite.cpp" />
|
||||
<Unit filename="../readwrite.h" />
|
||||
<Unit filename="../registers.h" />
|
||||
<Unit filename="../render3D.cpp" />
|
||||
<Unit filename="../render3D.h" />
|
||||
<Unit filename="../rtc.cpp" />
|
||||
<Unit filename="../rtc.h" />
|
||||
<Unit filename="../saves.cpp" />
|
||||
<Unit filename="../saves.h" />
|
||||
<Unit filename="../shaders.h" />
|
||||
<Unit filename="../softrender.cpp" />
|
||||
<Unit filename="../softrender.h" />
|
||||
<Unit filename="../softrender_config.h" />
|
||||
<Unit filename="../softrender_desmumefont.h" />
|
||||
<Unit filename="../softrender_v3sysfont.h" />
|
||||
<Unit filename="../texcache.cpp" />
|
||||
<Unit filename="../texcache.h" />
|
||||
<Unit filename="../thumb_instructions.cpp" />
|
||||
<Unit filename="../thumb_instructions.h" />
|
||||
<Unit filename="../types.h" />
|
||||
<Unit filename="../utils/ConvertUTF.c">
|
||||
<Option compilerVar="CC" />
|
||||
</Unit>
|
||||
<Unit filename="../utils/ConvertUTF.h" />
|
||||
<Unit filename="../utils/decrypt/crc.cpp" />
|
||||
<Unit filename="../utils/decrypt/crc.h" />
|
||||
<Unit filename="../utils/decrypt/decrypt.cpp" />
|
||||
<Unit filename="../utils/decrypt/decrypt.h" />
|
||||
<Unit filename="../utils/decrypt/header.cpp" />
|
||||
<Unit filename="../utils/decrypt/header.h" />
|
||||
<Unit filename="../utils/guid.cpp" />
|
||||
<Unit filename="../utils/guid.h" />
|
||||
<Unit filename="../utils/md5.cpp" />
|
||||
<Unit filename="../utils/md5.h" />
|
||||
<Unit filename="../utils/valuearray.h" />
|
||||
<Unit filename="../utils/xstring.cpp" />
|
||||
<Unit filename="../utils/xstring.h" />
|
||||
<Unit filename="../wifi.cpp" />
|
||||
<Unit filename="../wifi.h" />
|
||||
<Extensions>
|
||||
<code_completion />
|
||||
<envvars />
|
||||
<debugger />
|
||||
</Extensions>
|
||||
</Project>
|
||||
</CodeBlocks_project_file>
|
||||
Executable
+32
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
Copyright (C) 2011 Roger Manuel
|
||||
Copyright (C) 2012 DeSmuME team
|
||||
|
||||
This file is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This file is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with the this software. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifdef __OBJC__
|
||||
#define OBJ_C
|
||||
#endif
|
||||
|
||||
#define HOST_DARWIN
|
||||
#define DESMUME_COCOA
|
||||
#define HAVE_OPENGL
|
||||
#define HAVE_LIBZ
|
||||
|
||||
#if defined(__i386__) || defined(__x86_64__)
|
||||
#define HAVE_JIT
|
||||
#endif
|
||||
|
||||
#define PORT_VERSION "Cocoa"
|
||||
Executable
+768
@@ -0,0 +1,768 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CommandTagList</key>
|
||||
<array>
|
||||
<string>Up</string>
|
||||
<string>Down</string>
|
||||
<string>Left</string>
|
||||
<string>Right</string>
|
||||
<string>A</string>
|
||||
<string>B</string>
|
||||
<string>X</string>
|
||||
<string>Y</string>
|
||||
<string>L</string>
|
||||
<string>R</string>
|
||||
<string>Start</string>
|
||||
<string>Select</string>
|
||||
<string>Touch</string>
|
||||
<string>Microphone</string>
|
||||
<string>Lid</string>
|
||||
<string>Debug</string>
|
||||
<string>Guitar Grip: Green</string>
|
||||
<string>Guitar Grip: Red</string>
|
||||
<string>Guitar Grip: Yellow</string>
|
||||
<string>Guitar Grip: Blue</string>
|
||||
<string>Piano: C</string>
|
||||
<string>Piano: C#</string>
|
||||
<string>Piano: D</string>
|
||||
<string>Piano: D#</string>
|
||||
<string>Piano: E</string>
|
||||
<string>Piano: F</string>
|
||||
<string>Piano: F#</string>
|
||||
<string>Piano: G</string>
|
||||
<string>Piano: G#</string>
|
||||
<string>Piano: A</string>
|
||||
<string>Piano: A#</string>
|
||||
<string>Piano: B</string>
|
||||
<string>Piano: High C</string>
|
||||
<string>Paddle</string>
|
||||
<string>Autohold - Set</string>
|
||||
<string>Autohold - Clear</string>
|
||||
<string>Execute/Pause</string>
|
||||
<string>Frame Advance</string>
|
||||
<string>Frame Jump</string>
|
||||
<string>Reset</string>
|
||||
<string>Mute/Unmute</string>
|
||||
<string>Load State Slot</string>
|
||||
<string>Save State Slot</string>
|
||||
<string>Copy Screen</string>
|
||||
<string>Rotate Display Left</string>
|
||||
<string>Rotate Display Right</string>
|
||||
<string>Toggle All Displays</string>
|
||||
<string>Set Speed</string>
|
||||
<string>Enable/Disable Speed Limiter</string>
|
||||
<string>Enable/Disable Auto Frame Skip</string>
|
||||
<string>Enable/Disable Cheats</string>
|
||||
<string>Enable/Disable GPU State</string>
|
||||
</array>
|
||||
<key>DefaultInputProfiles</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>Name</key>
|
||||
<string>Default</string>
|
||||
<key>IsDefaultType</key>
|
||||
<true/>
|
||||
<key>Mappings</key>
|
||||
<dict>
|
||||
<key>Up</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>deviceInfoSummary</key>
|
||||
<string>Keyboard: Up Arrow</string>
|
||||
<key>deviceCode</key>
|
||||
<string>NSEventKeyboard</string>
|
||||
<key>deviceName</key>
|
||||
<string>Keyboard</string>
|
||||
<key>elementCode</key>
|
||||
<string>126</string>
|
||||
<key>elementName</key>
|
||||
<string>Up Arrow</string>
|
||||
<key>intValue1</key>
|
||||
<false/>
|
||||
</dict>
|
||||
</array>
|
||||
<key>Down</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>deviceInfoSummary</key>
|
||||
<string>Keyboard: Down Arrow</string>
|
||||
<key>deviceCode</key>
|
||||
<string>NSEventKeyboard</string>
|
||||
<key>deviceName</key>
|
||||
<string>Keyboard</string>
|
||||
<key>elementCode</key>
|
||||
<string>125</string>
|
||||
<key>elementName</key>
|
||||
<string>Down Arrow</string>
|
||||
<key>intValue1</key>
|
||||
<false/>
|
||||
</dict>
|
||||
</array>
|
||||
<key>Left</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>deviceInfoSummary</key>
|
||||
<string>Keyboard: Left Arrow</string>
|
||||
<key>deviceCode</key>
|
||||
<string>NSEventKeyboard</string>
|
||||
<key>deviceName</key>
|
||||
<string>Keyboard</string>
|
||||
<key>elementCode</key>
|
||||
<string>123</string>
|
||||
<key>elementName</key>
|
||||
<string>Left Arrow</string>
|
||||
<key>intValue1</key>
|
||||
<false/>
|
||||
</dict>
|
||||
</array>
|
||||
<key>Right</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>deviceInfoSummary</key>
|
||||
<string>Keyboard: Right Arrow</string>
|
||||
<key>deviceCode</key>
|
||||
<string>NSEventKeyboard</string>
|
||||
<key>deviceName</key>
|
||||
<string>Keyboard</string>
|
||||
<key>elementCode</key>
|
||||
<string>124</string>
|
||||
<key>elementName</key>
|
||||
<string>Right Arrow</string>
|
||||
<key>intValue1</key>
|
||||
<false/>
|
||||
</dict>
|
||||
</array>
|
||||
<key>A</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>deviceInfoSummary</key>
|
||||
<string>Keyboard: X</string>
|
||||
<key>deviceCode</key>
|
||||
<string>NSEventKeyboard</string>
|
||||
<key>deviceName</key>
|
||||
<string>Keyboard</string>
|
||||
<key>elementCode</key>
|
||||
<string>7</string>
|
||||
<key>elementName</key>
|
||||
<string>X</string>
|
||||
<key>intValue1</key>
|
||||
<false/>
|
||||
</dict>
|
||||
</array>
|
||||
<key>B</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>deviceInfoSummary</key>
|
||||
<string>Keyboard: Z</string>
|
||||
<key>deviceCode</key>
|
||||
<string>NSEventKeyboard</string>
|
||||
<key>deviceName</key>
|
||||
<string>Keyboard</string>
|
||||
<key>elementCode</key>
|
||||
<string>6</string>
|
||||
<key>elementName</key>
|
||||
<string>Z</string>
|
||||
<key>intValue1</key>
|
||||
<false/>
|
||||
</dict>
|
||||
</array>
|
||||
<key>X</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>deviceInfoSummary</key>
|
||||
<string>Keyboard: S</string>
|
||||
<key>deviceCode</key>
|
||||
<string>NSEventKeyboard</string>
|
||||
<key>deviceName</key>
|
||||
<string>Keyboard</string>
|
||||
<key>elementCode</key>
|
||||
<string>1</string>
|
||||
<key>elementName</key>
|
||||
<string>S</string>
|
||||
<key>intValue1</key>
|
||||
<false/>
|
||||
</dict>
|
||||
</array>
|
||||
<key>Y</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>deviceInfoSummary</key>
|
||||
<string>Keyboard: A</string>
|
||||
<key>deviceCode</key>
|
||||
<string>NSEventKeyboard</string>
|
||||
<key>deviceName</key>
|
||||
<string>Keyboard</string>
|
||||
<key>elementCode</key>
|
||||
<string>0</string>
|
||||
<key>elementName</key>
|
||||
<string>A</string>
|
||||
<key>intValue1</key>
|
||||
<false/>
|
||||
</dict>
|
||||
</array>
|
||||
<key>L</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>deviceInfoSummary</key>
|
||||
<string>Keyboard: Q</string>
|
||||
<key>deviceCode</key>
|
||||
<string>NSEventKeyboard</string>
|
||||
<key>deviceName</key>
|
||||
<string>Keyboard</string>
|
||||
<key>elementCode</key>
|
||||
<string>12</string>
|
||||
<key>elementName</key>
|
||||
<string>Q</string>
|
||||
<key>intValue1</key>
|
||||
<false/>
|
||||
</dict>
|
||||
</array>
|
||||
<key>R</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>deviceInfoSummary</key>
|
||||
<string>Keyboard: W</string>
|
||||
<key>deviceCode</key>
|
||||
<string>NSEventKeyboard</string>
|
||||
<key>deviceName</key>
|
||||
<string>Keyboard</string>
|
||||
<key>elementCode</key>
|
||||
<string>13</string>
|
||||
<key>elementName</key>
|
||||
<string>W</string>
|
||||
<key>intValue1</key>
|
||||
<false/>
|
||||
</dict>
|
||||
</array>
|
||||
<key>Start</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>deviceInfoSummary</key>
|
||||
<string>Keyboard: Return</string>
|
||||
<key>deviceCode</key>
|
||||
<string>NSEventKeyboard</string>
|
||||
<key>deviceName</key>
|
||||
<string>Keyboard</string>
|
||||
<key>elementCode</key>
|
||||
<string>36</string>
|
||||
<key>elementName</key>
|
||||
<string>Return</string>
|
||||
<key>intValue1</key>
|
||||
<false/>
|
||||
</dict>
|
||||
</array>
|
||||
<key>Select</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>deviceInfoSummary</key>
|
||||
<string>Keyboard: Tab</string>
|
||||
<key>deviceCode</key>
|
||||
<string>NSEventKeyboard</string>
|
||||
<key>deviceName</key>
|
||||
<string>Keyboard</string>
|
||||
<key>elementCode</key>
|
||||
<string>48</string>
|
||||
<key>elementName</key>
|
||||
<string>Tab</string>
|
||||
<key>intValue1</key>
|
||||
<false/>
|
||||
</dict>
|
||||
</array>
|
||||
<key>Touch</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>deviceInfoSummary</key>
|
||||
<string>Mouse: Primary Button</string>
|
||||
<key>deviceCode</key>
|
||||
<string>NSEventMouse</string>
|
||||
<key>deviceName</key>
|
||||
<string>Mouse</string>
|
||||
<key>elementCode</key>
|
||||
<string>0</string>
|
||||
<key>elementName</key>
|
||||
<string>Primary Button</string>
|
||||
<key>inputSettingsSummary</key>
|
||||
<string>Use Device Coordinates</string>
|
||||
<key>useInputForIntCoord</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</array>
|
||||
<key>Microphone</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>deviceInfoSummary</key>
|
||||
<string>Keyboard: ` (Accent)</string>
|
||||
<key>deviceCode</key>
|
||||
<string>NSEventKeyboard</string>
|
||||
<key>deviceName</key>
|
||||
<string>Keyboard</string>
|
||||
<key>elementCode</key>
|
||||
<string>50</string>
|
||||
<key>elementName</key>
|
||||
<string>` (Accent)</string>
|
||||
<key>inputSettingsSummary</key>
|
||||
<string>Internal Noise Samples</string>
|
||||
<key>intValue1</key>
|
||||
<integer>1</integer>
|
||||
<key>floatValue0</key>
|
||||
<real>250</real>
|
||||
</dict>
|
||||
</array>
|
||||
<key>Lid</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>deviceInfoSummary</key>
|
||||
<string>Keyboard: Delete (Backspace)</string>
|
||||
<key>deviceCode</key>
|
||||
<string>NSEventKeyboard</string>
|
||||
<key>deviceName</key>
|
||||
<string>Keyboard</string>
|
||||
<key>elementCode</key>
|
||||
<string>51</string>
|
||||
<key>elementName</key>
|
||||
<string>Delete (Backspace)</string>
|
||||
</dict>
|
||||
</array>
|
||||
<key>Debug</key>
|
||||
<array/>
|
||||
<key>Guitar Grip: Green</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>deviceInfoSummary</key>
|
||||
<string>Keyboard: E</string>
|
||||
<key>deviceCode</key>
|
||||
<string>NSEventKeyboard</string>
|
||||
<key>deviceName</key>
|
||||
<string>Keyboard</string>
|
||||
<key>elementCode</key>
|
||||
<string>14</string>
|
||||
<key>elementName</key>
|
||||
<string>E</string>
|
||||
</dict>
|
||||
</array>
|
||||
<key>Guitar Grip: Red</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>deviceInfoSummary</key>
|
||||
<string>Keyboard: R</string>
|
||||
<key>deviceCode</key>
|
||||
<string>NSEventKeyboard</string>
|
||||
<key>deviceName</key>
|
||||
<string>Keyboard</string>
|
||||
<key>elementCode</key>
|
||||
<string>15</string>
|
||||
<key>elementName</key>
|
||||
<string>R</string>
|
||||
</dict>
|
||||
</array>
|
||||
<key>Guitar Grip: Yellow</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>deviceInfoSummary</key>
|
||||
<string>Keyboard: T</string>
|
||||
<key>deviceCode</key>
|
||||
<string>NSEventKeyboard</string>
|
||||
<key>deviceName</key>
|
||||
<string>Keyboard</string>
|
||||
<key>elementCode</key>
|
||||
<string>17</string>
|
||||
<key>elementName</key>
|
||||
<string>T</string>
|
||||
</dict>
|
||||
</array>
|
||||
<key>Guitar Grip: Blue</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>deviceInfoSummary</key>
|
||||
<string>Keyboard: Y</string>
|
||||
<key>deviceCode</key>
|
||||
<string>NSEventKeyboard</string>
|
||||
<key>deviceName</key>
|
||||
<string>Keyboard</string>
|
||||
<key>elementCode</key>
|
||||
<string>16</string>
|
||||
<key>elementName</key>
|
||||
<string>Y</string>
|
||||
</dict>
|
||||
</array>
|
||||
<key>Piano: C</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>deviceInfoSummary</key>
|
||||
<string>Keyboard: C</string>
|
||||
<key>deviceCode</key>
|
||||
<string>NSEventKeyboard</string>
|
||||
<key>deviceName</key>
|
||||
<string>Keyboard</string>
|
||||
<key>elementCode</key>
|
||||
<string>8</string>
|
||||
<key>elementName</key>
|
||||
<string>C</string>
|
||||
</dict>
|
||||
</array>
|
||||
<key>Piano: C#</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>deviceInfoSummary</key>
|
||||
<string>Keyboard: F</string>
|
||||
<key>deviceCode</key>
|
||||
<string>NSEventKeyboard</string>
|
||||
<key>deviceName</key>
|
||||
<string>Keyboard</string>
|
||||
<key>elementCode</key>
|
||||
<string>3</string>
|
||||
<key>elementName</key>
|
||||
<string>F</string>
|
||||
</dict>
|
||||
</array>
|
||||
<key>Piano: D</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>deviceInfoSummary</key>
|
||||
<string>Keyboard: V</string>
|
||||
<key>deviceCode</key>
|
||||
<string>NSEventKeyboard</string>
|
||||
<key>deviceName</key>
|
||||
<string>Keyboard</string>
|
||||
<key>elementCode</key>
|
||||
<string>9</string>
|
||||
<key>elementName</key>
|
||||
<string>V</string>
|
||||
</dict>
|
||||
</array>
|
||||
<key>Piano: D#</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>deviceInfoSummary</key>
|
||||
<string>Keyboard: G</string>
|
||||
<key>deviceCode</key>
|
||||
<string>NSEventKeyboard</string>
|
||||
<key>deviceName</key>
|
||||
<string>Keyboard</string>
|
||||
<key>elementCode</key>
|
||||
<string>5</string>
|
||||
<key>elementName</key>
|
||||
<string>G</string>
|
||||
</dict>
|
||||
</array>
|
||||
<key>Piano: E</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>deviceInfoSummary</key>
|
||||
<string>Keyboard: B</string>
|
||||
<key>deviceCode</key>
|
||||
<string>NSEventKeyboard</string>
|
||||
<key>deviceName</key>
|
||||
<string>Keyboard</string>
|
||||
<key>elementCode</key>
|
||||
<string>11</string>
|
||||
<key>elementName</key>
|
||||
<string>B</string>
|
||||
</dict>
|
||||
</array>
|
||||
<key>Piano: F</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>deviceInfoSummary</key>
|
||||
<string>Keyboard: N</string>
|
||||
<key>deviceCode</key>
|
||||
<string>NSEventKeyboard</string>
|
||||
<key>deviceName</key>
|
||||
<string>Keyboard</string>
|
||||
<key>elementCode</key>
|
||||
<string>45</string>
|
||||
<key>elementName</key>
|
||||
<string>N</string>
|
||||
</dict>
|
||||
</array>
|
||||
<key>Piano: F#</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>deviceInfoSummary</key>
|
||||
<string>Keyboard: J</string>
|
||||
<key>deviceCode</key>
|
||||
<string>NSEventKeyboard</string>
|
||||
<key>deviceName</key>
|
||||
<string>Keyboard</string>
|
||||
<key>elementCode</key>
|
||||
<string>38</string>
|
||||
<key>elementName</key>
|
||||
<string>J</string>
|
||||
</dict>
|
||||
</array>
|
||||
<key>Piano: G</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>deviceInfoSummary</key>
|
||||
<string>Keyboard: M</string>
|
||||
<key>deviceCode</key>
|
||||
<string>NSEventKeyboard</string>
|
||||
<key>deviceName</key>
|
||||
<string>Keyboard</string>
|
||||
<key>elementCode</key>
|
||||
<string>46</string>
|
||||
<key>elementName</key>
|
||||
<string>M</string>
|
||||
</dict>
|
||||
</array>
|
||||
<key>Piano: G#</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>deviceInfoSummary</key>
|
||||
<string>Keyboard: K</string>
|
||||
<key>deviceCode</key>
|
||||
<string>NSEventKeyboard</string>
|
||||
<key>deviceName</key>
|
||||
<string>Keyboard</string>
|
||||
<key>elementCode</key>
|
||||
<string>40</string>
|
||||
<key>elementName</key>
|
||||
<string>K</string>
|
||||
</dict>
|
||||
</array>
|
||||
<key>Piano: A</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>deviceInfoSummary</key>
|
||||
<string>Keyboard: , (Comma)</string>
|
||||
<key>deviceCode</key>
|
||||
<string>NSEventKeyboard</string>
|
||||
<key>deviceName</key>
|
||||
<string>Keyboard</string>
|
||||
<key>elementCode</key>
|
||||
<string>43</string>
|
||||
<key>elementName</key>
|
||||
<string>, (Comma)</string>
|
||||
</dict>
|
||||
</array>
|
||||
<key>Piano: A#</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>deviceInfoSummary</key>
|
||||
<string>Keyboard: L</string>
|
||||
<key>deviceCode</key>
|
||||
<string>NSEventKeyboard</string>
|
||||
<key>deviceName</key>
|
||||
<string>Keyboard</string>
|
||||
<key>elementCode</key>
|
||||
<string>37</string>
|
||||
<key>elementName</key>
|
||||
<string>L</string>
|
||||
</dict>
|
||||
</array>
|
||||
<key>Piano: B</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>deviceInfoSummary</key>
|
||||
<string>Keyboard: . (Period)</string>
|
||||
<key>deviceCode</key>
|
||||
<string>NSEventKeyboard</string>
|
||||
<key>deviceName</key>
|
||||
<string>Keyboard</string>
|
||||
<key>elementCode</key>
|
||||
<string>47</string>
|
||||
<key>elementName</key>
|
||||
<string>. (Period)</string>
|
||||
</dict>
|
||||
</array>
|
||||
<key>Piano: High C</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>deviceInfoSummary</key>
|
||||
<string>Keyboard: /</string>
|
||||
<key>deviceCode</key>
|
||||
<string>NSEventKeyboard</string>
|
||||
<key>deviceName</key>
|
||||
<string>Keyboard</string>
|
||||
<key>elementCode</key>
|
||||
<string>44</string>
|
||||
<key>elementName</key>
|
||||
<string>/</string>
|
||||
</dict>
|
||||
</array>
|
||||
<key>Paddle</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>deviceInfoSummary</key>
|
||||
<string>Keyboard: O</string>
|
||||
<key>deviceCode</key>
|
||||
<string>NSEventKeyboard</string>
|
||||
<key>deviceName</key>
|
||||
<string>Keyboard</string>
|
||||
<key>elementCode</key>
|
||||
<string>31</string>
|
||||
<key>elementName</key>
|
||||
<string>O</string>
|
||||
<key>isInputAnalog</key>
|
||||
<false/>
|
||||
<key>inputSettingsSummary</key>
|
||||
<string>Paddle Adjust: -5</string>
|
||||
<key>intValue1</key>
|
||||
<integer>-5</integer>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>deviceInfoSummary</key>
|
||||
<string>Keyboard: P</string>
|
||||
<key>deviceCode</key>
|
||||
<string>NSEventKeyboard</string>
|
||||
<key>deviceName</key>
|
||||
<string>Keyboard</string>
|
||||
<key>elementCode</key>
|
||||
<string>35</string>
|
||||
<key>elementName</key>
|
||||
<string>P</string>
|
||||
<key>isInputAnalog</key>
|
||||
<false/>
|
||||
<key>inputSettingsSummary</key>
|
||||
<string>Paddle Adjust: +5</string>
|
||||
<key>intValue1</key>
|
||||
<integer>5</integer>
|
||||
</dict>
|
||||
</array>
|
||||
<key>Autohold - Set</key>
|
||||
<array/>
|
||||
<key>Autohold - Clear</key>
|
||||
<array/>
|
||||
<key>HUD</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>deviceInfoSummary</key>
|
||||
<string>Keyboard: H</string>
|
||||
<key>deviceCode</key>
|
||||
<string>NSEventKeyboard</string>
|
||||
<key>deviceName</key>
|
||||
<string>Keyboard</string>
|
||||
<key>elementCode</key>
|
||||
<string>4</string>
|
||||
<key>elementName</key>
|
||||
<string>H</string>
|
||||
</dict>
|
||||
</array>
|
||||
<key>Execute/Pause</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>deviceInfoSummary</key>
|
||||
<string>Keyboard: Forward Delete</string>
|
||||
<key>deviceCode</key>
|
||||
<string>NSEventKeyboard</string>
|
||||
<key>deviceName</key>
|
||||
<string>Keyboard</string>
|
||||
<key>elementCode</key>
|
||||
<string>117</string>
|
||||
<key>elementName</key>
|
||||
<string>Forward Delete</string>
|
||||
</dict>
|
||||
</array>
|
||||
<key>Frame Advance</key>
|
||||
<array/>
|
||||
<key>Frame Jump</key>
|
||||
<array/>
|
||||
<key>Reset</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>deviceInfoSummary</key>
|
||||
<string>Keyboard: Page Down</string>
|
||||
<key>deviceCode</key>
|
||||
<string>NSEventKeyboard</string>
|
||||
<key>deviceName</key>
|
||||
<string>Keyboard</string>
|
||||
<key>elementCode</key>
|
||||
<string>121</string>
|
||||
<key>elementName</key>
|
||||
<string>Page Down</string>
|
||||
</dict>
|
||||
</array>
|
||||
<key>Mute/Unmute</key>
|
||||
<array/>
|
||||
<key>Load State Slot</key>
|
||||
<array/>
|
||||
<key>Save State Slot</key>
|
||||
<array/>
|
||||
<key>Copy Screen</key>
|
||||
<array/>
|
||||
<key>Rotate Display Left</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>deviceInfoSummary</key>
|
||||
<string>Keyboard: [</string>
|
||||
<key>deviceCode</key>
|
||||
<string>NSEventKeyboard</string>
|
||||
<key>deviceName</key>
|
||||
<string>Keyboard</string>
|
||||
<key>elementCode</key>
|
||||
<string>33</string>
|
||||
<key>elementName</key>
|
||||
<string>[</string>
|
||||
<key>intValue0</key>
|
||||
<integer>-90</integer>
|
||||
</dict>
|
||||
</array>
|
||||
<key>Rotate Display Right</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>deviceInfoSummary</key>
|
||||
<string>Keyboard: ]</string>
|
||||
<key>deviceCode</key>
|
||||
<string>NSEventKeyboard</string>
|
||||
<key>deviceName</key>
|
||||
<string>Keyboard</string>
|
||||
<key>elementCode</key>
|
||||
<string>30</string>
|
||||
<key>elementName</key>
|
||||
<string>]</string>
|
||||
<key>intValue0</key>
|
||||
<integer>90</integer>
|
||||
</dict>
|
||||
</array>
|
||||
<key>Toggle All Displays</key>
|
||||
<array/>
|
||||
<key>Set Speed</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>deviceInfoSummary</key>
|
||||
<string>Keyboard: - (Dash)</string>
|
||||
<key>deviceCode</key>
|
||||
<string>NSEventKeyboard</string>
|
||||
<key>deviceName</key>
|
||||
<string>Keyboard</string>
|
||||
<key>elementCode</key>
|
||||
<string>27</string>
|
||||
<key>elementName</key>
|
||||
<string>- (Dash)</string>
|
||||
<key>inputSettingsSummary</key>
|
||||
<string>0.50x Speed</string>
|
||||
<key>floatValue0</key>
|
||||
<real>0.5</real>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>deviceInfoSummary</key>
|
||||
<string>Keyboard: =</string>
|
||||
<key>deviceCode</key>
|
||||
<string>NSEventKeyboard</string>
|
||||
<key>deviceName</key>
|
||||
<string>Keyboard</string>
|
||||
<key>elementCode</key>
|
||||
<string>24</string>
|
||||
<key>elementName</key>
|
||||
<string>=</string>
|
||||
<key>inputSettingsSummary</key>
|
||||
<string>2.00x Speed</string>
|
||||
<key>floatValue0</key>
|
||||
<integer>2</integer>
|
||||
</dict>
|
||||
</array>
|
||||
<key>Enable/Disable Speed Limiter</key>
|
||||
<array/>
|
||||
<key>Enable/Disable Auto Frame Skip</key>
|
||||
<array/>
|
||||
<key>Enable/Disable Cheats</key>
|
||||
<array/>
|
||||
<key>Enable/Disable GPU State</key>
|
||||
<array/>
|
||||
</dict>
|
||||
</dict>
|
||||
</array>
|
||||
</dict>
|
||||
</plist>
|
||||
Executable
+746
@@ -0,0 +1,746 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>Advanscene_AutoDetectRomSaveType</key>
|
||||
<true/>
|
||||
<key>CoreControl_EnableAutoFrameSkip</key>
|
||||
<true/>
|
||||
<key>CoreControl_EnableCheats</key>
|
||||
<true/>
|
||||
<key>CoreControl_EnableSpeedLimit</key>
|
||||
<true/>
|
||||
<key>CoreControl_SpeedScalar</key>
|
||||
<real>1</real>
|
||||
<key>Debug_GDBStubEnableARM9</key>
|
||||
<false/>
|
||||
<key>Debug_GDBStubEnableARM7</key>
|
||||
<false/>
|
||||
<key>Debug_GDBStubPortARM9</key>
|
||||
<integer>20000</integer>
|
||||
<key>Debug_GDBStubPortARM7</key>
|
||||
<integer>20001</integer>
|
||||
<key>DisplayView_Deposterize</key>
|
||||
<false/>
|
||||
<key>DisplayView_FiltersPreferGPU</key>
|
||||
<true/>
|
||||
<key>DisplayView_Mode</key>
|
||||
<integer>2</integer>
|
||||
<key>DisplayView_OutputFilter</key>
|
||||
<integer>1</integer>
|
||||
<key>DisplayView_Rotation</key>
|
||||
<integer>0</integer>
|
||||
<key>DisplayView_ShowHUD</key>
|
||||
<true/>
|
||||
<key>DisplayView_ShowStatusBar</key>
|
||||
<true/>
|
||||
<key>DisplayView_Size</key>
|
||||
<integer>100</integer>
|
||||
<key>DisplayView_UseBilinearOutput</key>
|
||||
<true/>
|
||||
<key>DisplayView_UseVerticalSync</key>
|
||||
<false/>
|
||||
<key>DisplayView_VideoFilter</key>
|
||||
<integer>0</integer>
|
||||
<key>DisplayViewCombo_Gap</key>
|
||||
<integer>0</integer>
|
||||
<key>DisplayViewCombo_Order</key>
|
||||
<integer>0</integer>
|
||||
<key>DisplayViewCombo_Orientation</key>
|
||||
<integer>0</integer>
|
||||
<key>Emulation_AdvancedBusLevelTiming</key>
|
||||
<true/>
|
||||
<key>Emulation_BIOSEmulateSWI</key>
|
||||
<true/>
|
||||
<key>Emulation_BIOSPatchDelayLoopSWI</key>
|
||||
<false/>
|
||||
<key>Emulation_CPUEmulationEngine</key>
|
||||
<integer>0</integer>
|
||||
<key>Emulation_EmulateEnsata</key>
|
||||
<false/>
|
||||
<key>Emulation_FirmwareBoot</key>
|
||||
<false/>
|
||||
<key>Emulation_MaxJITBlockSize</key>
|
||||
<integer>12</integer>
|
||||
<key>Emulation_RigorousTiming</key>
|
||||
<false/>
|
||||
<key>Emulation_UseDebugConsole</key>
|
||||
<false/>
|
||||
<key>Emulation_UseExternalBIOSImages</key>
|
||||
<false/>
|
||||
<key>Emulation_UseExternalFirmwareImage</key>
|
||||
<false/>
|
||||
<key>EmulationSlot1_DeviceType</key>
|
||||
<integer>1</integer>
|
||||
<key>FirmwareConfig_Birthday</key>
|
||||
<date>2011-06-23T07:00:00Z</date>
|
||||
<key>FirmwareConfig_FavoriteColor</key>
|
||||
<integer>7</integer>
|
||||
<key>FirmwareConfig_Language</key>
|
||||
<integer>1</integer>
|
||||
<key>FirmwareConfig_Message</key>
|
||||
<string>DeSmuME makes you happy!</string>
|
||||
<key>FirmwareConfig_Nickname</key>
|
||||
<string>DeSmuME</string>
|
||||
<key>General_AppFirstTimeRun</key>
|
||||
<dict/>
|
||||
<key>General_AutoloadROMOption</key>
|
||||
<integer>10000</integer>
|
||||
<key>General_DisplayWindowRestorableStates</key>
|
||||
<array/>
|
||||
<key>General_DoNotAskMigrate</key>
|
||||
<false/>
|
||||
<key>General_ExecuteROMOnLoad</key>
|
||||
<true/>
|
||||
<key>General_StreamLoadRomData</key>
|
||||
<true/>
|
||||
<key>General_WillRestoreDisplayWindows</key>
|
||||
<true/>
|
||||
<key>HUD_FrameCounter</key>
|
||||
<false/>
|
||||
<key>HUD_FramesPerSecond</key>
|
||||
<false/>
|
||||
<key>HUD_GraphicalInput</key>
|
||||
<false/>
|
||||
<key>HUD_Input</key>
|
||||
<false/>
|
||||
<key>HUD_LagCounter</key>
|
||||
<false/>
|
||||
<key>HUD_Microphone</key>
|
||||
<false/>
|
||||
<key>HUD_RealTimeClock</key>
|
||||
<false/>
|
||||
<key>Input_AudioInputMode</key>
|
||||
<integer>1</integer>
|
||||
<key>Input_ControllerMappings</key>
|
||||
<dict>
|
||||
<key>Up</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>deviceCode</key>
|
||||
<string>NSEventKeyboard</string>
|
||||
<key>deviceName</key>
|
||||
<string>Keyboard</string>
|
||||
<key>elementCode</key>
|
||||
<string>126</string>
|
||||
<key>elementName</key>
|
||||
<string>Up Arrow</string>
|
||||
</dict>
|
||||
</array>
|
||||
<key>Down</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>deviceCode</key>
|
||||
<string>NSEventKeyboard</string>
|
||||
<key>deviceName</key>
|
||||
<string>Keyboard</string>
|
||||
<key>elementCode</key>
|
||||
<string>125</string>
|
||||
<key>elementName</key>
|
||||
<string>Down Arrow</string>
|
||||
</dict>
|
||||
</array>
|
||||
<key>Left</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>deviceCode</key>
|
||||
<string>NSEventKeyboard</string>
|
||||
<key>deviceName</key>
|
||||
<string>Keyboard</string>
|
||||
<key>elementCode</key>
|
||||
<string>123</string>
|
||||
<key>elementName</key>
|
||||
<string>Left Arrow</string>
|
||||
</dict>
|
||||
</array>
|
||||
<key>Right</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>deviceCode</key>
|
||||
<string>NSEventKeyboard</string>
|
||||
<key>deviceName</key>
|
||||
<string>Keyboard</string>
|
||||
<key>elementCode</key>
|
||||
<string>124</string>
|
||||
<key>elementName</key>
|
||||
<string>Right Arrow</string>
|
||||
</dict>
|
||||
</array>
|
||||
<key>A</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>deviceCode</key>
|
||||
<string>NSEventKeyboard</string>
|
||||
<key>deviceName</key>
|
||||
<string>Keyboard</string>
|
||||
<key>elementCode</key>
|
||||
<string>7</string>
|
||||
<key>elementName</key>
|
||||
<string>X</string>
|
||||
</dict>
|
||||
</array>
|
||||
<key>B</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>deviceCode</key>
|
||||
<string>NSEventKeyboard</string>
|
||||
<key>deviceName</key>
|
||||
<string>Keyboard</string>
|
||||
<key>elementCode</key>
|
||||
<string>6</string>
|
||||
<key>elementName</key>
|
||||
<string>Z</string>
|
||||
</dict>
|
||||
</array>
|
||||
<key>X</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>deviceCode</key>
|
||||
<string>NSEventKeyboard</string>
|
||||
<key>deviceName</key>
|
||||
<string>Keyboard</string>
|
||||
<key>elementCode</key>
|
||||
<string>1</string>
|
||||
<key>elementName</key>
|
||||
<string>S</string>
|
||||
</dict>
|
||||
</array>
|
||||
<key>Y</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>deviceCode</key>
|
||||
<string>NSEventKeyboard</string>
|
||||
<key>deviceName</key>
|
||||
<string>Keyboard</string>
|
||||
<key>elementCode</key>
|
||||
<string>0</string>
|
||||
<key>elementName</key>
|
||||
<string>A</string>
|
||||
</dict>
|
||||
</array>
|
||||
<key>L</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>deviceCode</key>
|
||||
<string>NSEventKeyboard</string>
|
||||
<key>deviceName</key>
|
||||
<string>Keyboard</string>
|
||||
<key>elementCode</key>
|
||||
<string>12</string>
|
||||
<key>elementName</key>
|
||||
<string>Q</string>
|
||||
</dict>
|
||||
</array>
|
||||
<key>R</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>deviceCode</key>
|
||||
<string>NSEventKeyboard</string>
|
||||
<key>deviceName</key>
|
||||
<string>Keyboard</string>
|
||||
<key>elementCode</key>
|
||||
<string>13</string>
|
||||
<key>elementName</key>
|
||||
<string>W</string>
|
||||
</dict>
|
||||
</array>
|
||||
<key>Start</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>deviceCode</key>
|
||||
<string>NSEventKeyboard</string>
|
||||
<key>deviceName</key>
|
||||
<string>Keyboard</string>
|
||||
<key>elementCode</key>
|
||||
<string>36</string>
|
||||
<key>elementName</key>
|
||||
<string>Return</string>
|
||||
</dict>
|
||||
</array>
|
||||
<key>Select</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>deviceCode</key>
|
||||
<string>NSEventKeyboard</string>
|
||||
<key>deviceName</key>
|
||||
<string>Keyboard</string>
|
||||
<key>elementCode</key>
|
||||
<string>48</string>
|
||||
<key>elementName</key>
|
||||
<string>Tab</string>
|
||||
</dict>
|
||||
</array>
|
||||
<key>Touch</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>deviceCode</key>
|
||||
<string>NSEventMouse</string>
|
||||
<key>deviceName</key>
|
||||
<string>Mouse</string>
|
||||
<key>elementCode</key>
|
||||
<string>0</string>
|
||||
<key>elementName</key>
|
||||
<string>Primary Button</string>
|
||||
<key>useInputForIntCoord</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</array>
|
||||
<key>Microphone</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>deviceCode</key>
|
||||
<string>NSEventKeyboard</string>
|
||||
<key>deviceName</key>
|
||||
<string>Keyboard</string>
|
||||
<key>elementCode</key>
|
||||
<string>50</string>
|
||||
<key>elementName</key>
|
||||
<string>` (Accent)</string>
|
||||
<key>intValue1</key>
|
||||
<integer>1</integer>
|
||||
</dict>
|
||||
</array>
|
||||
<key>Lid</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>deviceCode</key>
|
||||
<string>NSEventKeyboard</string>
|
||||
<key>deviceName</key>
|
||||
<string>Keyboard</string>
|
||||
<key>elementCode</key>
|
||||
<string>51</string>
|
||||
<key>elementName</key>
|
||||
<string>Delete (Backspace)</string>
|
||||
</dict>
|
||||
</array>
|
||||
<key>Debug</key>
|
||||
<array/>
|
||||
<key>Guitar Grip: Green</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>deviceCode</key>
|
||||
<string>NSEventKeyboard</string>
|
||||
<key>deviceName</key>
|
||||
<string>Keyboard</string>
|
||||
<key>elementCode</key>
|
||||
<string>14</string>
|
||||
<key>elementName</key>
|
||||
<string>E</string>
|
||||
</dict>
|
||||
</array>
|
||||
<key>Guitar Grip: Red</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>deviceCode</key>
|
||||
<string>NSEventKeyboard</string>
|
||||
<key>deviceName</key>
|
||||
<string>Keyboard</string>
|
||||
<key>elementCode</key>
|
||||
<string>15</string>
|
||||
<key>elementName</key>
|
||||
<string>R</string>
|
||||
</dict>
|
||||
</array>
|
||||
<key>Guitar Grip: Yellow</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>deviceCode</key>
|
||||
<string>NSEventKeyboard</string>
|
||||
<key>deviceName</key>
|
||||
<string>Keyboard</string>
|
||||
<key>elementCode</key>
|
||||
<string>17</string>
|
||||
<key>elementName</key>
|
||||
<string>T</string>
|
||||
</dict>
|
||||
</array>
|
||||
<key>Guitar Grip: Blue</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>deviceCode</key>
|
||||
<string>NSEventKeyboard</string>
|
||||
<key>deviceName</key>
|
||||
<string>Keyboard</string>
|
||||
<key>elementCode</key>
|
||||
<string>16</string>
|
||||
<key>elementName</key>
|
||||
<string>Y</string>
|
||||
</dict>
|
||||
</array>
|
||||
<key>Piano: C</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>deviceCode</key>
|
||||
<string>NSEventKeyboard</string>
|
||||
<key>deviceName</key>
|
||||
<string>Keyboard</string>
|
||||
<key>elementCode</key>
|
||||
<string>8</string>
|
||||
<key>elementName</key>
|
||||
<string>C</string>
|
||||
</dict>
|
||||
</array>
|
||||
<key>Piano: C#</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>deviceCode</key>
|
||||
<string>NSEventKeyboard</string>
|
||||
<key>deviceName</key>
|
||||
<string>Keyboard</string>
|
||||
<key>elementCode</key>
|
||||
<string>3</string>
|
||||
<key>elementName</key>
|
||||
<string>F</string>
|
||||
</dict>
|
||||
</array>
|
||||
<key>Piano: D</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>deviceCode</key>
|
||||
<string>NSEventKeyboard</string>
|
||||
<key>deviceName</key>
|
||||
<string>Keyboard</string>
|
||||
<key>elementCode</key>
|
||||
<string>9</string>
|
||||
<key>elementName</key>
|
||||
<string>V</string>
|
||||
</dict>
|
||||
</array>
|
||||
<key>Piano: D#</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>deviceCode</key>
|
||||
<string>NSEventKeyboard</string>
|
||||
<key>deviceName</key>
|
||||
<string>Keyboard</string>
|
||||
<key>elementCode</key>
|
||||
<string>5</string>
|
||||
<key>elementName</key>
|
||||
<string>G</string>
|
||||
</dict>
|
||||
</array>
|
||||
<key>Piano: E</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>deviceCode</key>
|
||||
<string>NSEventKeyboard</string>
|
||||
<key>deviceName</key>
|
||||
<string>Keyboard</string>
|
||||
<key>elementCode</key>
|
||||
<string>11</string>
|
||||
<key>elementName</key>
|
||||
<string>B</string>
|
||||
</dict>
|
||||
</array>
|
||||
<key>Piano: F</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>deviceCode</key>
|
||||
<string>NSEventKeyboard</string>
|
||||
<key>deviceName</key>
|
||||
<string>Keyboard</string>
|
||||
<key>elementCode</key>
|
||||
<string>45</string>
|
||||
<key>elementName</key>
|
||||
<string>N</string>
|
||||
</dict>
|
||||
</array>
|
||||
<key>Piano: F#</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>deviceCode</key>
|
||||
<string>NSEventKeyboard</string>
|
||||
<key>deviceName</key>
|
||||
<string>Keyboard</string>
|
||||
<key>elementCode</key>
|
||||
<string>38</string>
|
||||
<key>elementName</key>
|
||||
<string>J</string>
|
||||
</dict>
|
||||
</array>
|
||||
<key>Piano: G</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>deviceCode</key>
|
||||
<string>NSEventKeyboard</string>
|
||||
<key>deviceName</key>
|
||||
<string>Keyboard</string>
|
||||
<key>elementCode</key>
|
||||
<string>46</string>
|
||||
<key>elementName</key>
|
||||
<string>M</string>
|
||||
</dict>
|
||||
</array>
|
||||
<key>Piano: G#</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>deviceCode</key>
|
||||
<string>NSEventKeyboard</string>
|
||||
<key>deviceName</key>
|
||||
<string>Keyboard</string>
|
||||
<key>elementCode</key>
|
||||
<string>40</string>
|
||||
<key>elementName</key>
|
||||
<string>K</string>
|
||||
</dict>
|
||||
</array>
|
||||
<key>Piano: A</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>deviceCode</key>
|
||||
<string>NSEventKeyboard</string>
|
||||
<key>deviceName</key>
|
||||
<string>Keyboard</string>
|
||||
<key>elementCode</key>
|
||||
<string>43</string>
|
||||
<key>elementName</key>
|
||||
<string>, (Comma)</string>
|
||||
</dict>
|
||||
</array>
|
||||
<key>Piano: A#</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>deviceCode</key>
|
||||
<string>NSEventKeyboard</string>
|
||||
<key>deviceName</key>
|
||||
<string>Keyboard</string>
|
||||
<key>elementCode</key>
|
||||
<string>37</string>
|
||||
<key>elementName</key>
|
||||
<string>L</string>
|
||||
</dict>
|
||||
</array>
|
||||
<key>Piano: B</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>deviceCode</key>
|
||||
<string>NSEventKeyboard</string>
|
||||
<key>deviceName</key>
|
||||
<string>Keyboard</string>
|
||||
<key>elementCode</key>
|
||||
<string>47</string>
|
||||
<key>elementName</key>
|
||||
<string>. (Period)</string>
|
||||
</dict>
|
||||
</array>
|
||||
<key>Piano: High C</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>deviceCode</key>
|
||||
<string>NSEventKeyboard</string>
|
||||
<key>deviceName</key>
|
||||
<string>Keyboard</string>
|
||||
<key>elementCode</key>
|
||||
<string>44</string>
|
||||
<key>elementName</key>
|
||||
<string>/</string>
|
||||
</dict>
|
||||
</array>
|
||||
<key>Paddle</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>deviceCode</key>
|
||||
<string>NSEventKeyboard</string>
|
||||
<key>deviceName</key>
|
||||
<string>Keyboard</string>
|
||||
<key>elementCode</key>
|
||||
<string>31</string>
|
||||
<key>elementName</key>
|
||||
<string>O</string>
|
||||
<key>intValue1</key>
|
||||
<integer>-5</integer>
|
||||
<key>isInputAnalog</key>
|
||||
<false/>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>deviceCode</key>
|
||||
<string>NSEventKeyboard</string>
|
||||
<key>deviceName</key>
|
||||
<string>Keyboard</string>
|
||||
<key>elementCode</key>
|
||||
<string>35</string>
|
||||
<key>elementName</key>
|
||||
<string>P</string>
|
||||
<key>intValue1</key>
|
||||
<integer>5</integer>
|
||||
<key>isInputAnalog</key>
|
||||
<false/>
|
||||
</dict>
|
||||
</array>
|
||||
<key>Autohold - Set</key>
|
||||
<array/>
|
||||
<key>Autohold - Clear</key>
|
||||
<array/>
|
||||
<key>HUD</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>deviceCode</key>
|
||||
<string>NSEventKeyboard</string>
|
||||
<key>deviceName</key>
|
||||
<string>Keyboard</string>
|
||||
<key>elementCode</key>
|
||||
<string>4</string>
|
||||
<key>elementName</key>
|
||||
<string>H</string>
|
||||
</dict>
|
||||
</array>
|
||||
<key>Execute/Pause</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>deviceCode</key>
|
||||
<string>NSEventKeyboard</string>
|
||||
<key>deviceName</key>
|
||||
<string>Keyboard</string>
|
||||
<key>elementCode</key>
|
||||
<string>117</string>
|
||||
<key>elementName</key>
|
||||
<string>Forward Delete</string>
|
||||
</dict>
|
||||
</array>
|
||||
<key>Frame Advance</key>
|
||||
<array/>
|
||||
<key>Frame Jump</key>
|
||||
<array/>
|
||||
<key>Reset</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>deviceCode</key>
|
||||
<string>NSEventKeyboard</string>
|
||||
<key>deviceName</key>
|
||||
<string>Keyboard</string>
|
||||
<key>elementCode</key>
|
||||
<string>121</string>
|
||||
<key>elementName</key>
|
||||
<string>Page Down</string>
|
||||
</dict>
|
||||
</array>
|
||||
<key>Mute/Unmute</key>
|
||||
<array/>
|
||||
<key>Load State Slot</key>
|
||||
<array/>
|
||||
<key>Save State Slot</key>
|
||||
<array/>
|
||||
<key>Copy Screen</key>
|
||||
<array/>
|
||||
<key>Rotate Display Left</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>deviceCode</key>
|
||||
<string>NSEventKeyboard</string>
|
||||
<key>deviceName</key>
|
||||
<string>Keyboard</string>
|
||||
<key>elementCode</key>
|
||||
<string>33</string>
|
||||
<key>elementName</key>
|
||||
<string>[</string>
|
||||
<key>intValue0</key>
|
||||
<integer>-90</integer>
|
||||
</dict>
|
||||
</array>
|
||||
<key>Rotate Display Right</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>deviceCode</key>
|
||||
<string>NSEventKeyboard</string>
|
||||
<key>deviceName</key>
|
||||
<string>Keyboard</string>
|
||||
<key>elementCode</key>
|
||||
<string>30</string>
|
||||
<key>elementName</key>
|
||||
<string>]</string>
|
||||
<key>intValue0</key>
|
||||
<integer>90</integer>
|
||||
</dict>
|
||||
</array>
|
||||
<key>Toggle All Displays</key>
|
||||
<array/>
|
||||
<key>Set Speed</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>deviceCode</key>
|
||||
<string>NSEventKeyboard</string>
|
||||
<key>deviceName</key>
|
||||
<string>Keyboard</string>
|
||||
<key>elementCode</key>
|
||||
<string>27</string>
|
||||
<key>elementName</key>
|
||||
<string>- (Dash)</string>
|
||||
<key>floatValue0</key>
|
||||
<string>0.5</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>deviceCode</key>
|
||||
<string>NSEventKeyboard</string>
|
||||
<key>deviceName</key>
|
||||
<string>Keyboard</string>
|
||||
<key>elementCode</key>
|
||||
<string>24</string>
|
||||
<key>elementName</key>
|
||||
<string>=</string>
|
||||
<key>floatValue0</key>
|
||||
<integer>2</integer>
|
||||
</dict>
|
||||
</array>
|
||||
<key>Enable/Disable Speed Limiter</key>
|
||||
<array/>
|
||||
<key>Enable/Disable Auto Frame Skip</key>
|
||||
<array/>
|
||||
<key>Enable/Disable Cheats</key>
|
||||
<array/>
|
||||
<key>Enable/Disable GPU State</key>
|
||||
<array/>
|
||||
</dict>
|
||||
<key>Input_SavedDeviceProperties</key>
|
||||
<dict/>
|
||||
<key>Input_SavedProfiles</key>
|
||||
<array/>
|
||||
<key>Microphone_HardwareMicMute</key>
|
||||
<false/>
|
||||
<key>Render3D_DepthComparisonThreshold</key>
|
||||
<integer>0</integer>
|
||||
<key>Render3D_EdgeMarking</key>
|
||||
<true/>
|
||||
<key>Render3D_Fog</key>
|
||||
<true/>
|
||||
<key>Render3D_FragmentSamplingHack</key>
|
||||
<false/>
|
||||
<key>Render3D_HighPrecisionColorInterpolation</key>
|
||||
<true/>
|
||||
<key>Render3D_LineHack</key>
|
||||
<true/>
|
||||
<key>Render3D_Multisample</key>
|
||||
<false/>
|
||||
<key>Render3D_RenderingEngine</key>
|
||||
<integer>1</integer>
|
||||
<key>Render3D_Textures</key>
|
||||
<true/>
|
||||
<key>Render3D_Threads</key>
|
||||
<integer>0</integer>
|
||||
<key>RomInfoPanel_SectionViewState</key>
|
||||
<dict/>
|
||||
<key>Slot2_GBA_CartridgePath</key>
|
||||
<string></string>
|
||||
<key>Slot2_GBA_SRAMPath</key>
|
||||
<string></string>
|
||||
<key>Slot2_LoadedDevice</key>
|
||||
<integer>1</integer>
|
||||
<key>Slot2_MPCF_DirectoryPath</key>
|
||||
<string></string>
|
||||
<key>Slot2_MPCF_DiskImagePath</key>
|
||||
<string></string>
|
||||
<key>Slot2_MPCF_PathOption</key>
|
||||
<integer>0</integer>
|
||||
<key>Sound_AudioOutputEngine</key>
|
||||
<integer>58325</integer>
|
||||
<key>Sound_Volume</key>
|
||||
<integer>100</integer>
|
||||
<key>SPU_AdvancedLogic</key>
|
||||
<true/>
|
||||
<key>SPU_InterpolationMode</key>
|
||||
<integer>2</integer>
|
||||
<key>SPU_SyncMethod</key>
|
||||
<integer>0</integer>
|
||||
<key>SPU_SyncMode</key>
|
||||
<integer>1</integer>
|
||||
</dict>
|
||||
</plist>
|
||||
Executable
+39
@@ -0,0 +1,39 @@
|
||||
(*
|
||||
Copyright (C) 2013 DeSmuME team
|
||||
|
||||
This file is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This file is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with the this software. If not, see <http://www.gnu.org/licenses/>.
|
||||
*)
|
||||
|
||||
display dialog "Are you sure that you want to delete DeSmuME's preferences?" buttons {"Cancel", "Delete"} default button "Delete" cancel button "Cancel" with title "Delete DeSmuME Preferences"
|
||||
|
||||
try
|
||||
set userDefaultsPath to ((path to "pref" as text) & "org.desmume.DeSmuME.plist")
|
||||
set isUserDefaultsDeleted to false
|
||||
|
||||
tell application "Finder"
|
||||
if exists file userDefaultsPath then
|
||||
set isUserDefaultsDeleted to true
|
||||
delete file userDefaultsPath
|
||||
end if
|
||||
|
||||
if isUserDefaultsDeleted then
|
||||
display dialog "The preference files have been moved to the Trash." buttons {"OK"} default button {"OK"}
|
||||
else
|
||||
display dialog "No preference files were found." buttons {"OK"} default button {"OK"}
|
||||
end if
|
||||
end tell
|
||||
|
||||
on error errorMsg
|
||||
display dialog errorMsg
|
||||
end try
|
||||
Executable
+536
@@ -0,0 +1,536 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>VersionStrings</key>
|
||||
<array>
|
||||
<string>0.9.6</string>
|
||||
<string>0.9.7</string>
|
||||
<string>0.9.8</string>
|
||||
<string>0.9.9</string>
|
||||
<string>0.9.10</string>
|
||||
<string>0.9.11</string>
|
||||
</array>
|
||||
<key>PortStrings</key>
|
||||
<dict>
|
||||
<key>0.9.6</key>
|
||||
<array>
|
||||
<string>GTK</string>
|
||||
</array>
|
||||
<key>0.9.7</key>
|
||||
<array>
|
||||
<string>Cocoa</string>
|
||||
</array>
|
||||
<key>0.9.8</key>
|
||||
<array>
|
||||
<string>Cocoa</string>
|
||||
<string>OpenEmu</string>
|
||||
</array>
|
||||
<key>0.9.9</key>
|
||||
<array>
|
||||
<string>Cocoa</string>
|
||||
<string>OpenEmu</string>
|
||||
</array>
|
||||
<key>0.9.10</key>
|
||||
<array>
|
||||
<string>Cocoa</string>
|
||||
<string>OpenEmu</string>
|
||||
</array>
|
||||
<key>0.9.11</key>
|
||||
<array>
|
||||
<string>Cocoa</string>
|
||||
<string>OpenEmu</string>
|
||||
</array>
|
||||
</dict>
|
||||
<key>DefaultPaths</key>
|
||||
<dict>
|
||||
<key>0.9.6</key>
|
||||
<dict>
|
||||
<key>GTK</key>
|
||||
<dict>
|
||||
<key>ROM Save</key>
|
||||
<string>~/.config/desmume</string>
|
||||
<key>Cheat</key>
|
||||
<string>~/.config/desmume</string>
|
||||
<key>Save State</key>
|
||||
<string>~/.config/desmume</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>0.9.7</key>
|
||||
<dict>
|
||||
<key>Cocoa</key>
|
||||
<dict>
|
||||
<key>ROM Save</key>
|
||||
<string>${WITHROM}</string>
|
||||
<key>Save State</key>
|
||||
<string>${APPSUPPORT}</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>0.9.8</key>
|
||||
<dict>
|
||||
<key>Cocoa</key>
|
||||
<dict>
|
||||
<key>ROM Save</key>
|
||||
<string>${APPSUPPORT}</string>
|
||||
<key>Cheat</key>
|
||||
<string>${APPSUPPORT}</string>
|
||||
<key>Firmware Configuration</key>
|
||||
<string>${APPSUPPORT}</string>
|
||||
<key>Save State</key>
|
||||
<string>${APPSUPPORT}</string>
|
||||
</dict>
|
||||
<key>OpenEmu</key>
|
||||
<dict>
|
||||
<key>ROM Save</key>
|
||||
<string>${OPENEMU}</string>
|
||||
<key>Save State</key>
|
||||
<string>${OPENEMU}</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>0.9.9</key>
|
||||
<dict>
|
||||
<key>Cocoa</key>
|
||||
<dict>
|
||||
<key>ROM Save</key>
|
||||
<string>${APPSUPPORT}</string>
|
||||
<key>Cheat</key>
|
||||
<string>${APPSUPPORT}</string>
|
||||
<key>Firmware Configuration</key>
|
||||
<string>${APPSUPPORT}</string>
|
||||
<key>Save State</key>
|
||||
<string>${APPSUPPORT}</string>
|
||||
</dict>
|
||||
<key>OpenEmu</key>
|
||||
<dict>
|
||||
<key>ROM Save</key>
|
||||
<string>${OPENEMU}</string>
|
||||
<key>Save State</key>
|
||||
<string>${OPENEMU}</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>0.9.10</key>
|
||||
<dict>
|
||||
<key>Cocoa</key>
|
||||
<dict>
|
||||
<key>ROM Save</key>
|
||||
<string>${APPSUPPORT}</string>
|
||||
<key>Cheat</key>
|
||||
<string>${APPSUPPORT}</string>
|
||||
<key>Firmware Configuration</key>
|
||||
<string>${APPSUPPORT}</string>
|
||||
<key>Save State</key>
|
||||
<string>${APPSUPPORT}</string>
|
||||
</dict>
|
||||
<key>OpenEmu</key>
|
||||
<dict>
|
||||
<key>ROM Save</key>
|
||||
<string>${OPENEMU}</string>
|
||||
<key>Save State</key>
|
||||
<string>${OPENEMU}</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>0.9.11</key>
|
||||
<dict>
|
||||
<key>Cocoa</key>
|
||||
<dict>
|
||||
<key>ROM Save</key>
|
||||
<string>${APPSUPPORT}</string>
|
||||
<key>Cheat</key>
|
||||
<string>${APPSUPPORT}</string>
|
||||
<key>Firmware Configuration</key>
|
||||
<string>${APPSUPPORT}</string>
|
||||
<key>Save State</key>
|
||||
<string>${APPSUPPORT}</string>
|
||||
</dict>
|
||||
<key>OpenEmu</key>
|
||||
<dict>
|
||||
<key>ROM Save</key>
|
||||
<string>${OPENEMU}</string>
|
||||
<key>Save State</key>
|
||||
<string>${OPENEMU}</string>
|
||||
</dict>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>DirectoryNames</key>
|
||||
<dict>
|
||||
<key>0.9.6</key>
|
||||
<dict>
|
||||
<key>GTK</key>
|
||||
<dict>
|
||||
<key>ROM Save</key>
|
||||
<string>Battery</string>
|
||||
<key>Cheat</key>
|
||||
<string>Cheats</string>
|
||||
<key>Firmware Configuration</key>
|
||||
<string>Battery</string>
|
||||
<key>Lua Script</key>
|
||||
<string>Lua</string>
|
||||
<key>Video</key>
|
||||
<string>AviFiles</string>
|
||||
<key>R4 Format</key>
|
||||
<string>R4format</string>
|
||||
<key>ROM</key>
|
||||
<string>Roms</string>
|
||||
<key>Save State</key>
|
||||
<string>States</string>
|
||||
<key>Screenshot</key>
|
||||
<string>Screenshots</string>
|
||||
<key>Sound Sample</key>
|
||||
<string>SoundSamples</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>0.9.7</key>
|
||||
<dict>
|
||||
<key>Cocoa</key>
|
||||
<dict>
|
||||
<key>ROM Save</key>
|
||||
<string>Battery</string>
|
||||
<key>Cheat</key>
|
||||
<string>Cheats</string>
|
||||
<key>Firmware Configuration</key>
|
||||
<string>Battery</string>
|
||||
<key>Lua Script</key>
|
||||
<string>Lua</string>
|
||||
<key>Video</key>
|
||||
<string>AviFiles</string>
|
||||
<key>R4 Format</key>
|
||||
<string>R4format</string>
|
||||
<key>ROM</key>
|
||||
<string>Roms</string>
|
||||
<key>Save State</key>
|
||||
<string>States</string>
|
||||
<key>Screenshot</key>
|
||||
<string>Screenshots</string>
|
||||
<key>Sound Sample</key>
|
||||
<string>SoundSamples</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>0.9.8</key>
|
||||
<dict>
|
||||
<key>Cocoa</key>
|
||||
<dict>
|
||||
<key>ROM Save</key>
|
||||
<string>Battery</string>
|
||||
<key>Cheat</key>
|
||||
<string>Cheats</string>
|
||||
<key>Firmware Configuration</key>
|
||||
<string>Battery</string>
|
||||
<key>Lua Script</key>
|
||||
<string>Lua</string>
|
||||
<key>Video</key>
|
||||
<string>AviFiles</string>
|
||||
<key>R4 Format</key>
|
||||
<string>R4format</string>
|
||||
<key>ROM</key>
|
||||
<string>Roms</string>
|
||||
<key>Save State</key>
|
||||
<string>States</string>
|
||||
<key>Screenshot</key>
|
||||
<string>Screenshots</string>
|
||||
<key>Sound Sample</key>
|
||||
<string>SoundSamples</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>0.9.9</key>
|
||||
<dict>
|
||||
<key>Cocoa</key>
|
||||
<dict>
|
||||
<key>ROM Save</key>
|
||||
<string>Battery</string>
|
||||
<key>Cheat</key>
|
||||
<string>Cheats</string>
|
||||
<key>Firmware Configuration</key>
|
||||
<string>Battery</string>
|
||||
<key>Lua Script</key>
|
||||
<string>Lua</string>
|
||||
<key>Video</key>
|
||||
<string>AviFiles</string>
|
||||
<key>R4 Format</key>
|
||||
<string>R4format</string>
|
||||
<key>ROM</key>
|
||||
<string>Roms</string>
|
||||
<key>Save State</key>
|
||||
<string>States</string>
|
||||
<key>Screenshot</key>
|
||||
<string>Screenshots</string>
|
||||
<key>Sound Sample</key>
|
||||
<string>SoundSamples</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>0.9.10</key>
|
||||
<dict>
|
||||
<key>Cocoa</key>
|
||||
<dict>
|
||||
<key>ROM Save</key>
|
||||
<string>Battery</string>
|
||||
<key>Cheat</key>
|
||||
<string>Cheats</string>
|
||||
<key>Firmware Configuration</key>
|
||||
<string>Battery</string>
|
||||
<key>Lua Script</key>
|
||||
<string>Lua</string>
|
||||
<key>Video</key>
|
||||
<string>AviFiles</string>
|
||||
<key>R4 Format</key>
|
||||
<string>R4format</string>
|
||||
<key>ROM</key>
|
||||
<string>Roms</string>
|
||||
<key>Save State</key>
|
||||
<string>States</string>
|
||||
<key>Screenshot</key>
|
||||
<string>Screenshots</string>
|
||||
<key>Sound Sample</key>
|
||||
<string>SoundSamples</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>0.9.11</key>
|
||||
<dict>
|
||||
<key>Cocoa</key>
|
||||
<dict>
|
||||
<key>ROM Save</key>
|
||||
<string>Battery</string>
|
||||
<key>Cheat</key>
|
||||
<string>Cheats</string>
|
||||
<key>Firmware Configuration</key>
|
||||
<string>Battery</string>
|
||||
<key>Lua Script</key>
|
||||
<string>Lua</string>
|
||||
<key>Video</key>
|
||||
<string>AviFiles</string>
|
||||
<key>R4 Format</key>
|
||||
<string>R4format</string>
|
||||
<key>ROM</key>
|
||||
<string>Roms</string>
|
||||
<key>Save State</key>
|
||||
<string>States</string>
|
||||
<key>Screenshot</key>
|
||||
<string>Screenshots</string>
|
||||
<key>Sound Sample</key>
|
||||
<string>SoundSamples</string>
|
||||
</dict>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>FileExtensionByTypes</key>
|
||||
<dict>
|
||||
<key>0.9.6</key>
|
||||
<dict>
|
||||
<key>GTK</key>
|
||||
<dict>
|
||||
<key>ROM Save</key>
|
||||
<string>dsv</string>
|
||||
<key>Cheat</key>
|
||||
<string>dct</string>
|
||||
<key>Firmware Configuration</key>
|
||||
<string>dfc</string>
|
||||
<key>Lua Script</key>
|
||||
<string>lua</string>
|
||||
<key>Save State</key>
|
||||
<string>dst</string>
|
||||
<key>ROM</key>
|
||||
<string>nds</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>0.9.7</key>
|
||||
<dict>
|
||||
<key>Cocoa</key>
|
||||
<dict>
|
||||
<key>ROM Save</key>
|
||||
<string>dsv</string>
|
||||
<key>Cheat</key>
|
||||
<string>dct</string>
|
||||
<key>Firmware Configuration</key>
|
||||
<string>dfc</string>
|
||||
<key>Lua Script</key>
|
||||
<string>lua</string>
|
||||
<key>Save State</key>
|
||||
<string>dst</string>
|
||||
<key>ROM</key>
|
||||
<string>nds</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>0.9.8</key>
|
||||
<dict>
|
||||
<key>Cocoa</key>
|
||||
<dict>
|
||||
<key>ROM Save</key>
|
||||
<string>dsv</string>
|
||||
<key>Cheat</key>
|
||||
<string>dct</string>
|
||||
<key>Firmware Configuration</key>
|
||||
<string>dfc</string>
|
||||
<key>Lua Script</key>
|
||||
<string>lua</string>
|
||||
<key>Save State</key>
|
||||
<string>dst</string>
|
||||
<key>ROM</key>
|
||||
<string>nds</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>0.9.9</key>
|
||||
<dict>
|
||||
<key>Cocoa</key>
|
||||
<dict>
|
||||
<key>ROM Save</key>
|
||||
<string>dsv</string>
|
||||
<key>Cheat</key>
|
||||
<string>dct</string>
|
||||
<key>Firmware Configuration</key>
|
||||
<string>dfc</string>
|
||||
<key>Lua Script</key>
|
||||
<string>lua</string>
|
||||
<key>Save State</key>
|
||||
<string>dst</string>
|
||||
<key>ROM</key>
|
||||
<string>nds</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>0.9.10</key>
|
||||
<dict>
|
||||
<key>Cocoa</key>
|
||||
<dict>
|
||||
<key>ROM Save</key>
|
||||
<string>dsv</string>
|
||||
<key>Cheat</key>
|
||||
<string>dct</string>
|
||||
<key>Firmware Configuration</key>
|
||||
<string>dfc</string>
|
||||
<key>Lua Script</key>
|
||||
<string>lua</string>
|
||||
<key>Save State</key>
|
||||
<string>dst</string>
|
||||
<key>ROM</key>
|
||||
<string>nds</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>0.9.11</key>
|
||||
<dict>
|
||||
<key>Cocoa</key>
|
||||
<dict>
|
||||
<key>ROM Save</key>
|
||||
<string>dsv</string>
|
||||
<key>Cheat</key>
|
||||
<string>dct</string>
|
||||
<key>Firmware Configuration</key>
|
||||
<string>dfc</string>
|
||||
<key>Lua Script</key>
|
||||
<string>lua</string>
|
||||
<key>Save State</key>
|
||||
<string>dst</string>
|
||||
<key>ROM</key>
|
||||
<string>nds</string>
|
||||
</dict>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>FileTypeByExtensions</key>
|
||||
<dict>
|
||||
<key>0.9.6</key>
|
||||
<dict>
|
||||
<key>GTK</key>
|
||||
<dict>
|
||||
<key>dsv</key>
|
||||
<string>ROM Save</string>
|
||||
<key>dct</key>
|
||||
<string>Cheat</string>
|
||||
<key>dfc</key>
|
||||
<string>Firmware Configuration</string>
|
||||
<key>lua</key>
|
||||
<string>Lua Script</string>
|
||||
<key>dst</key>
|
||||
<string>Save State</string>
|
||||
<key>nds</key>
|
||||
<string>ROM</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>0.9.7</key>
|
||||
<dict>
|
||||
<key>Cocoa</key>
|
||||
<dict>
|
||||
<key>dsv</key>
|
||||
<string>ROM Save</string>
|
||||
<key>dct</key>
|
||||
<string>Cheat</string>
|
||||
<key>dfc</key>
|
||||
<string>Firmware Configuration</string>
|
||||
<key>lua</key>
|
||||
<string>Lua Script</string>
|
||||
<key>dst</key>
|
||||
<string>Save State</string>
|
||||
<key>nds</key>
|
||||
<string>ROM</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>0.9.8</key>
|
||||
<dict>
|
||||
<key>Cocoa</key>
|
||||
<dict>
|
||||
<key>dsv</key>
|
||||
<string>ROM Save</string>
|
||||
<key>dct</key>
|
||||
<string>Cheat</string>
|
||||
<key>dfc</key>
|
||||
<string>Firmware Configuration</string>
|
||||
<key>lua</key>
|
||||
<string>Lua Script</string>
|
||||
<key>dst</key>
|
||||
<string>Save State</string>
|
||||
<key>nds</key>
|
||||
<string>ROM</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>0.9.9</key>
|
||||
<dict>
|
||||
<key>Cocoa</key>
|
||||
<dict>
|
||||
<key>dsv</key>
|
||||
<string>ROM Save</string>
|
||||
<key>dct</key>
|
||||
<string>Cheat</string>
|
||||
<key>dfc</key>
|
||||
<string>Firmware Configuration</string>
|
||||
<key>lua</key>
|
||||
<string>Lua Script</string>
|
||||
<key>dst</key>
|
||||
<string>Save State</string>
|
||||
<key>nds</key>
|
||||
<string>ROM</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>0.9.10</key>
|
||||
<dict>
|
||||
<key>Cocoa</key>
|
||||
<dict>
|
||||
<key>dsv</key>
|
||||
<string>ROM Save</string>
|
||||
<key>dct</key>
|
||||
<string>Cheat</string>
|
||||
<key>dfc</key>
|
||||
<string>Firmware Configuration</string>
|
||||
<key>lua</key>
|
||||
<string>Lua Script</string>
|
||||
<key>dst</key>
|
||||
<string>Save State</string>
|
||||
<key>nds</key>
|
||||
<string>ROM</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>0.9.11</key>
|
||||
<dict>
|
||||
<key>Cocoa</key>
|
||||
<dict>
|
||||
<key>dsv</key>
|
||||
<string>ROM Save</string>
|
||||
<key>dct</key>
|
||||
<string>Cheat</string>
|
||||
<key>dfc</key>
|
||||
<string>Firmware Configuration</string>
|
||||
<key>lua</key>
|
||||
<string>Lua Script</string>
|
||||
<key>dst</key>
|
||||
<string>Save State</string>
|
||||
<key>nds</key>
|
||||
<string>ROM</string>
|
||||
</dict>
|
||||
</dict>
|
||||
</dict>
|
||||
</dict>
|
||||
</plist>
|
||||
Executable
+474
@@ -0,0 +1,474 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>English</string>
|
||||
<key>CFBundleDocumentTypes</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>CFBundleTypeExtensions</key>
|
||||
<array>
|
||||
<string>nds</string>
|
||||
</array>
|
||||
<key>CFBundleTypeIconFile</key>
|
||||
<string>AppIcon_NintendoDS_ROM.icns</string>
|
||||
<key>CFBundleTypeName</key>
|
||||
<string>Nintendo DS ROM</string>
|
||||
<key>CFBundleTypeRole</key>
|
||||
<string>Viewer</string>
|
||||
<key>LSItemContentTypes</key>
|
||||
<array>
|
||||
<string>com.nintendo.rom.ds</string>
|
||||
</array>
|
||||
<key>LSTypeIsPackage</key>
|
||||
<false/>
|
||||
<key>NSPersistentStoreTypeKey</key>
|
||||
<string>Binary</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>CFBundleTypeExtensions</key>
|
||||
<array>
|
||||
<string>ds.gba</string>
|
||||
</array>
|
||||
<key>CFBundleTypeIconFile</key>
|
||||
<string>AppIcon_NintendoGBA_ROM.icns</string>
|
||||
<key>CFBundleTypeName</key>
|
||||
<string>Gameboy Advance ROM</string>
|
||||
<key>CFBundleTypeRole</key>
|
||||
<string>Viewer</string>
|
||||
<key>LSItemContentTypes</key>
|
||||
<array>
|
||||
<string>com.nintendo.rom.gba</string>
|
||||
</array>
|
||||
<key>LSTypeIsPackage</key>
|
||||
<false/>
|
||||
<key>NSPersistentStoreTypeKey</key>
|
||||
<string>Binary</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>CFBundleTypeExtensions</key>
|
||||
<array>
|
||||
<string>dst</string>
|
||||
</array>
|
||||
<key>CFBundleTypeIconFile</key>
|
||||
<string>AppIcon_SaveState.icns</string>
|
||||
<key>CFBundleTypeName</key>
|
||||
<string>DeSmuME Save State</string>
|
||||
<key>CFBundleTypeRole</key>
|
||||
<string>Editor</string>
|
||||
<key>LSItemContentTypes</key>
|
||||
<array>
|
||||
<string>com.desmume.savestate</string>
|
||||
</array>
|
||||
<key>LSTypeIsPackage</key>
|
||||
<false/>
|
||||
<key>NSPersistentStoreTypeKey</key>
|
||||
<string>Binary</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>CFBundleTypeExtensions</key>
|
||||
<array>
|
||||
<string>dsv</string>
|
||||
</array>
|
||||
<key>CFBundleTypeIconFile</key>
|
||||
<string>AppIcon_ROMSave.icns</string>
|
||||
<key>CFBundleTypeName</key>
|
||||
<string>DeSmuME ROM Save</string>
|
||||
<key>CFBundleTypeRole</key>
|
||||
<string>Editor</string>
|
||||
<key>LSItemContentTypes</key>
|
||||
<array>
|
||||
<string>com.desmume.romsave</string>
|
||||
</array>
|
||||
<key>LSTypeIsPackage</key>
|
||||
<false/>
|
||||
<key>NSPersistentStoreTypeKey</key>
|
||||
<string>Binary</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>CFBundleTypeExtensions</key>
|
||||
<array>
|
||||
<string>dfc</string>
|
||||
</array>
|
||||
<key>CFBundleTypeIconFile</key>
|
||||
<string>AppIcon_FirmwareConfig.icns</string>
|
||||
<key>CFBundleTypeName</key>
|
||||
<string>DeSmuME Firmware Configuration</string>
|
||||
<key>CFBundleTypeRole</key>
|
||||
<string>Editor</string>
|
||||
<key>LSItemContentTypes</key>
|
||||
<array>
|
||||
<string>com.desmume.firmwareconfig</string>
|
||||
</array>
|
||||
<key>LSTypeIsPackage</key>
|
||||
<false/>
|
||||
<key>NSPersistentStoreTypeKey</key>
|
||||
<string>Binary</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>CFBundleTypeExtensions</key>
|
||||
<array>
|
||||
<string>dct</string>
|
||||
</array>
|
||||
<key>CFBundleTypeIconFile</key>
|
||||
<string>AppIcon_ROMCheats.icns</string>
|
||||
<key>CFBundleTypeName</key>
|
||||
<string>DeSmuME ROM Cheats</string>
|
||||
<key>CFBundleTypeRole</key>
|
||||
<string>Editor</string>
|
||||
<key>LSItemContentTypes</key>
|
||||
<array>
|
||||
<string>com.desmume.romcheats</string>
|
||||
</array>
|
||||
<key>LSTypeIsPackage</key>
|
||||
<false/>
|
||||
<key>NSPersistentStoreTypeKey</key>
|
||||
<string>Binary</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>CFBundleTypeExtensions</key>
|
||||
<array>
|
||||
<string>sav</string>
|
||||
</array>
|
||||
<key>CFBundleTypeIconFile</key>
|
||||
<string>AppIcon_NoGBA_ROMSave.icns</string>
|
||||
<key>CFBundleTypeName</key>
|
||||
<string>No$GBA ROM Save</string>
|
||||
<key>CFBundleTypeRole</key>
|
||||
<string>Viewer</string>
|
||||
<key>LSItemContentTypes</key>
|
||||
<array>
|
||||
<string>de.emubase.nocash.romsave.gba</string>
|
||||
</array>
|
||||
<key>LSTypeIsPackage</key>
|
||||
<false/>
|
||||
<key>NSPersistentStoreTypeKey</key>
|
||||
<string>Binary</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>CFBundleTypeExtensions</key>
|
||||
<array>
|
||||
<string>duc</string>
|
||||
</array>
|
||||
<key>CFBundleTypeIconFile</key>
|
||||
<string>AppIcon_ActionReplaySave.icns</string>
|
||||
<key>CFBundleTypeName</key>
|
||||
<string>Action Replay Save</string>
|
||||
<key>CFBundleTypeRole</key>
|
||||
<string>Viewer</string>
|
||||
<key>LSItemContentTypes</key>
|
||||
<array>
|
||||
<string>com.codejunkies.actionreplay.save.nintendo.ds</string>
|
||||
</array>
|
||||
<key>LSTypeIsPackage</key>
|
||||
<false/>
|
||||
<key>NSPersistentStoreTypeKey</key>
|
||||
<string>Binary</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>CFBundleTypeExtensions</key>
|
||||
<array>
|
||||
<string>bin</string>
|
||||
</array>
|
||||
<key>CFBundleTypeIconFile</key>
|
||||
<string>AppIcon_HWImage_NDS.icns</string>
|
||||
<key>CFBundleTypeName</key>
|
||||
<string>Nintendo DS Hardware Image</string>
|
||||
<key>CFBundleTypeRole</key>
|
||||
<string>Viewer</string>
|
||||
<key>LSItemContentTypes</key>
|
||||
<array>
|
||||
<string>com.nintendo.hwimage.ds</string>
|
||||
</array>
|
||||
<key>LSTypeIsPackage</key>
|
||||
<false/>
|
||||
<key>NSPersistentStoreTypeKey</key>
|
||||
<string>Binary</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>CFBundleTypeExtensions</key>
|
||||
<array>
|
||||
<string>xml</string>
|
||||
</array>
|
||||
<key>CFBundleTypeIconFile</key>
|
||||
<string>AppIcon_ADVANsCEneDatabase.icns</string>
|
||||
<key>CFBundleTypeName</key>
|
||||
<string>ADVANsCEne Database</string>
|
||||
<key>CFBundleTypeRole</key>
|
||||
<string>Viewer</string>
|
||||
<key>LSItemContentTypes</key>
|
||||
<array>
|
||||
<string>com.advanscene.database.nintendo.ds</string>
|
||||
</array>
|
||||
<key>LSTypeIsPackage</key>
|
||||
<false/>
|
||||
<key>NSPersistentStoreTypeKey</key>
|
||||
<string>Binary</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>CFBundleTypeExtensions</key>
|
||||
<array>
|
||||
<string>dat</string>
|
||||
</array>
|
||||
<key>CFBundleTypeIconFile</key>
|
||||
<string>AppIcon_R4CheatDatabase.icns</string>
|
||||
<key>CFBundleTypeName</key>
|
||||
<string>R4 Cheats Database</string>
|
||||
<key>CFBundleTypeRole</key>
|
||||
<string>Viewer</string>
|
||||
<key>LSItemContentTypes</key>
|
||||
<array>
|
||||
<string>net.gbatemp.cheats.database.nintendo.ds</string>
|
||||
</array>
|
||||
<key>LSTypeIsPackage</key>
|
||||
<false/>
|
||||
<key>NSPersistentStoreTypeKey</key>
|
||||
<string>Binary</string>
|
||||
</dict>
|
||||
</array>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>${PRODUCT_NAME}</string>
|
||||
<key>CFBundleIconFile</key>
|
||||
<string>AppIcon_DeSmuME</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>org.desmume.DeSmuME</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>${PRODUCT_NAME}</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>APPL</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>v0.9.11 (Debug)</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>DSmM</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>0.9.11</string>
|
||||
<key>LSApplicationCategoryType</key>
|
||||
<string>public.app-category.entertainment</string>
|
||||
<key>LSMinimumSystemVersion</key>
|
||||
<string>${MACOSX_DEPLOYMENT_TARGET}</string>
|
||||
<key>NSHumanReadableCopyright</key>
|
||||
<string>Copyright ©2007-2015 DeSmuME Team. All rights reserved.</string>
|
||||
<key>NSMainNibFile</key>
|
||||
<string>MainMenu</string>
|
||||
<key>NSPrincipalClass</key>
|
||||
<string>NSApplication</string>
|
||||
<key>UTExportedTypeDeclarations</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>UTTypeConformsTo</key>
|
||||
<array>
|
||||
<string>public.data</string>
|
||||
</array>
|
||||
<key>UTTypeDescription</key>
|
||||
<string>DeSmuME Save State</string>
|
||||
<key>UTTypeIconFile</key>
|
||||
<string>AppIcon_SaveState.icns</string>
|
||||
<key>UTTypeIdentifier</key>
|
||||
<string>com.desmume.savestate</string>
|
||||
<key>UTTypeTagSpecification</key>
|
||||
<dict>
|
||||
<key>public.filename-extension</key>
|
||||
<array>
|
||||
<string>dst</string>
|
||||
</array>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>UTTypeConformsTo</key>
|
||||
<array>
|
||||
<string>public.data</string>
|
||||
</array>
|
||||
<key>UTTypeDescription</key>
|
||||
<string>DeSmuME ROM Save</string>
|
||||
<key>UTTypeIconFile</key>
|
||||
<string>AppIcon_ROMSave.icns</string>
|
||||
<key>UTTypeIdentifier</key>
|
||||
<string>com.desmume.romsave</string>
|
||||
<key>UTTypeTagSpecification</key>
|
||||
<dict>
|
||||
<key>public.filename-extension</key>
|
||||
<array>
|
||||
<string>dsv</string>
|
||||
</array>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>UTTypeConformsTo</key>
|
||||
<array>
|
||||
<string>public.data</string>
|
||||
</array>
|
||||
<key>UTTypeDescription</key>
|
||||
<string>DeSmuME Firmware Configuration</string>
|
||||
<key>UTTypeIconFile</key>
|
||||
<string>AppIcon_FirmwareConfig.icns</string>
|
||||
<key>UTTypeIdentifier</key>
|
||||
<string>com.desmume.firmwareconfig</string>
|
||||
<key>UTTypeTagSpecification</key>
|
||||
<dict>
|
||||
<key>public.filename-extension</key>
|
||||
<array>
|
||||
<string>dfc</string>
|
||||
</array>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>UTTypeConformsTo</key>
|
||||
<array>
|
||||
<string>public.data</string>
|
||||
</array>
|
||||
<key>UTTypeDescription</key>
|
||||
<string>DeSmuME ROM Cheats</string>
|
||||
<key>UTTypeIconFile</key>
|
||||
<string>AppIcon_ROMCheats.icns</string>
|
||||
<key>UTTypeIdentifier</key>
|
||||
<string>com.desmume.romcheats</string>
|
||||
<key>UTTypeTagSpecification</key>
|
||||
<dict>
|
||||
<key>public.filename-extension</key>
|
||||
<array>
|
||||
<string>dct</string>
|
||||
</array>
|
||||
</dict>
|
||||
</dict>
|
||||
</array>
|
||||
<key>UTImportedTypeDeclarations</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>UTTypeConformsTo</key>
|
||||
<array>
|
||||
<string>public.data</string>
|
||||
</array>
|
||||
<key>UTTypeDescription</key>
|
||||
<string>Nintendo DS ROM</string>
|
||||
<key>UTTypeIconFile</key>
|
||||
<string>AppIcon_NintendoDS_ROM.icns</string>
|
||||
<key>UTTypeIdentifier</key>
|
||||
<string>com.nintendo.rom.ds</string>
|
||||
<key>UTTypeTagSpecification</key>
|
||||
<dict>
|
||||
<key>public.filename-extension</key>
|
||||
<array>
|
||||
<string>nds</string>
|
||||
</array>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>UTTypeConformsTo</key>
|
||||
<array>
|
||||
<string>public.data</string>
|
||||
</array>
|
||||
<key>UTTypeDescription</key>
|
||||
<string>Gameboy Advance ROM</string>
|
||||
<key>UTTypeIconFile</key>
|
||||
<string>AppIcon_NintendoGBA_ROM.icns</string>
|
||||
<key>UTTypeIdentifier</key>
|
||||
<string>com.nintendo.rom.gba</string>
|
||||
<key>UTTypeTagSpecification</key>
|
||||
<dict>
|
||||
<key>public.filename-extension</key>
|
||||
<array>
|
||||
<string>ds.gba</string>
|
||||
</array>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>UTTypeConformsTo</key>
|
||||
<array>
|
||||
<string>public.data</string>
|
||||
</array>
|
||||
<key>UTTypeDescription</key>
|
||||
<string>No$GBA ROM Save</string>
|
||||
<key>UTTypeIconFile</key>
|
||||
<string>AppIcon_NoGBA_ROMSave.icns</string>
|
||||
<key>UTTypeIdentifier</key>
|
||||
<string>de.emubase.nocash.romsave.gba</string>
|
||||
<key>UTTypeTagSpecification</key>
|
||||
<dict>
|
||||
<key>public.filename-extension</key>
|
||||
<array>
|
||||
<string>sav</string>
|
||||
</array>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>UTTypeConformsTo</key>
|
||||
<array>
|
||||
<string>public.data</string>
|
||||
</array>
|
||||
<key>UTTypeDescription</key>
|
||||
<string>Action Replay Save</string>
|
||||
<key>UTTypeIconFile</key>
|
||||
<string>AppIcon_ActionReplaySave.icns</string>
|
||||
<key>UTTypeIdentifier</key>
|
||||
<string>com.codejunkies.actionreplay.save.nintendo.ds</string>
|
||||
<key>UTTypeTagSpecification</key>
|
||||
<dict>
|
||||
<key>public.filename-extension</key>
|
||||
<array>
|
||||
<string>duc</string>
|
||||
</array>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>UTTypeConformsTo</key>
|
||||
<array>
|
||||
<string>public.data</string>
|
||||
</array>
|
||||
<key>UTTypeDescription</key>
|
||||
<string>Nintendo DS Hardware Image</string>
|
||||
<key>UTTypeIconFile</key>
|
||||
<string>AppIcon_HWImage_NDS.icns</string>
|
||||
<key>UTTypeIdentifier</key>
|
||||
<string>com.nintendo.hwimage.ds</string>
|
||||
<key>UTTypeTagSpecification</key>
|
||||
<dict>
|
||||
<key>public.filename-extension</key>
|
||||
<array>
|
||||
<string>bin</string>
|
||||
</array>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>UTTypeConformsTo</key>
|
||||
<array>
|
||||
<string>public.xml</string>
|
||||
</array>
|
||||
<key>UTTypeDescription</key>
|
||||
<string>ADVANsCEne Database</string>
|
||||
<key>UTTypeIconFile</key>
|
||||
<string>AppIcon_ADVANsCEneDatabase.icns</string>
|
||||
<key>UTTypeIdentifier</key>
|
||||
<string>com.advanscene.database.nintendo.ds</string>
|
||||
<key>UTTypeTagSpecification</key>
|
||||
<dict>
|
||||
<key>public.filename-extension</key>
|
||||
<array>
|
||||
<string>xml</string>
|
||||
</array>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>UTTypeConformsTo</key>
|
||||
<array>
|
||||
<string>public.data</string>
|
||||
</array>
|
||||
<key>UTTypeDescription</key>
|
||||
<string>R4 Cheats Database</string>
|
||||
<key>UTTypeIconFile</key>
|
||||
<string>AppIcon_R4CheatDatabase.icns</string>
|
||||
<key>UTTypeIdentifier</key>
|
||||
<string>net.gbatemp.cheats.database.nintendo.ds</string>
|
||||
<key>UTTypeTagSpecification</key>
|
||||
<dict>
|
||||
<key>public.filename-extension</key>
|
||||
<array>
|
||||
<string>dat</string>
|
||||
</array>
|
||||
</dict>
|
||||
</dict>
|
||||
</array>
|
||||
</dict>
|
||||
</plist>
|
||||
Executable
+474
@@ -0,0 +1,474 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>English</string>
|
||||
<key>CFBundleDocumentTypes</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>CFBundleTypeExtensions</key>
|
||||
<array>
|
||||
<string>nds</string>
|
||||
</array>
|
||||
<key>CFBundleTypeIconFile</key>
|
||||
<string>AppIcon_NintendoDS_ROM.icns</string>
|
||||
<key>CFBundleTypeName</key>
|
||||
<string>Nintendo DS ROM</string>
|
||||
<key>CFBundleTypeRole</key>
|
||||
<string>Viewer</string>
|
||||
<key>LSItemContentTypes</key>
|
||||
<array>
|
||||
<string>com.nintendo.rom.ds</string>
|
||||
</array>
|
||||
<key>LSTypeIsPackage</key>
|
||||
<false/>
|
||||
<key>NSPersistentStoreTypeKey</key>
|
||||
<string>Binary</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>CFBundleTypeExtensions</key>
|
||||
<array>
|
||||
<string>ds.gba</string>
|
||||
</array>
|
||||
<key>CFBundleTypeIconFile</key>
|
||||
<string>AppIcon_NintendoGBA_ROM.icns</string>
|
||||
<key>CFBundleTypeName</key>
|
||||
<string>Gameboy Advance ROM</string>
|
||||
<key>CFBundleTypeRole</key>
|
||||
<string>Viewer</string>
|
||||
<key>LSItemContentTypes</key>
|
||||
<array>
|
||||
<string>com.nintendo.rom.gba</string>
|
||||
</array>
|
||||
<key>LSTypeIsPackage</key>
|
||||
<false/>
|
||||
<key>NSPersistentStoreTypeKey</key>
|
||||
<string>Binary</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>CFBundleTypeExtensions</key>
|
||||
<array>
|
||||
<string>dst</string>
|
||||
</array>
|
||||
<key>CFBundleTypeIconFile</key>
|
||||
<string>AppIcon_SaveState.icns</string>
|
||||
<key>CFBundleTypeName</key>
|
||||
<string>DeSmuME Save State</string>
|
||||
<key>CFBundleTypeRole</key>
|
||||
<string>Editor</string>
|
||||
<key>LSItemContentTypes</key>
|
||||
<array>
|
||||
<string>com.desmume.savestate</string>
|
||||
</array>
|
||||
<key>LSTypeIsPackage</key>
|
||||
<false/>
|
||||
<key>NSPersistentStoreTypeKey</key>
|
||||
<string>Binary</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>CFBundleTypeExtensions</key>
|
||||
<array>
|
||||
<string>dsv</string>
|
||||
</array>
|
||||
<key>CFBundleTypeIconFile</key>
|
||||
<string>AppIcon_ROMSave.icns</string>
|
||||
<key>CFBundleTypeName</key>
|
||||
<string>DeSmuME ROM Save</string>
|
||||
<key>CFBundleTypeRole</key>
|
||||
<string>Editor</string>
|
||||
<key>LSItemContentTypes</key>
|
||||
<array>
|
||||
<string>com.desmume.romsave</string>
|
||||
</array>
|
||||
<key>LSTypeIsPackage</key>
|
||||
<false/>
|
||||
<key>NSPersistentStoreTypeKey</key>
|
||||
<string>Binary</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>CFBundleTypeExtensions</key>
|
||||
<array>
|
||||
<string>dfc</string>
|
||||
</array>
|
||||
<key>CFBundleTypeIconFile</key>
|
||||
<string>AppIcon_FirmwareConfig.icns</string>
|
||||
<key>CFBundleTypeName</key>
|
||||
<string>DeSmuME Firmware Configuration</string>
|
||||
<key>CFBundleTypeRole</key>
|
||||
<string>Editor</string>
|
||||
<key>LSItemContentTypes</key>
|
||||
<array>
|
||||
<string>com.desmume.firmwareconfig</string>
|
||||
</array>
|
||||
<key>LSTypeIsPackage</key>
|
||||
<false/>
|
||||
<key>NSPersistentStoreTypeKey</key>
|
||||
<string>Binary</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>CFBundleTypeExtensions</key>
|
||||
<array>
|
||||
<string>dct</string>
|
||||
</array>
|
||||
<key>CFBundleTypeIconFile</key>
|
||||
<string>AppIcon_ROMCheats.icns</string>
|
||||
<key>CFBundleTypeName</key>
|
||||
<string>DeSmuME ROM Cheats</string>
|
||||
<key>CFBundleTypeRole</key>
|
||||
<string>Editor</string>
|
||||
<key>LSItemContentTypes</key>
|
||||
<array>
|
||||
<string>com.desmume.romcheats</string>
|
||||
</array>
|
||||
<key>LSTypeIsPackage</key>
|
||||
<false/>
|
||||
<key>NSPersistentStoreTypeKey</key>
|
||||
<string>Binary</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>CFBundleTypeExtensions</key>
|
||||
<array>
|
||||
<string>sav</string>
|
||||
</array>
|
||||
<key>CFBundleTypeIconFile</key>
|
||||
<string>AppIcon_NoGBA_ROMSave.icns</string>
|
||||
<key>CFBundleTypeName</key>
|
||||
<string>No$GBA ROM Save</string>
|
||||
<key>CFBundleTypeRole</key>
|
||||
<string>Viewer</string>
|
||||
<key>LSItemContentTypes</key>
|
||||
<array>
|
||||
<string>de.emubase.nocash.romsave.gba</string>
|
||||
</array>
|
||||
<key>LSTypeIsPackage</key>
|
||||
<false/>
|
||||
<key>NSPersistentStoreTypeKey</key>
|
||||
<string>Binary</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>CFBundleTypeExtensions</key>
|
||||
<array>
|
||||
<string>duc</string>
|
||||
</array>
|
||||
<key>CFBundleTypeIconFile</key>
|
||||
<string>AppIcon_ActionReplaySave.icns</string>
|
||||
<key>CFBundleTypeName</key>
|
||||
<string>Action Replay Save</string>
|
||||
<key>CFBundleTypeRole</key>
|
||||
<string>Viewer</string>
|
||||
<key>LSItemContentTypes</key>
|
||||
<array>
|
||||
<string>com.codejunkies.actionreplay.save.nintendo.ds</string>
|
||||
</array>
|
||||
<key>LSTypeIsPackage</key>
|
||||
<false/>
|
||||
<key>NSPersistentStoreTypeKey</key>
|
||||
<string>Binary</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>CFBundleTypeExtensions</key>
|
||||
<array>
|
||||
<string>bin</string>
|
||||
</array>
|
||||
<key>CFBundleTypeIconFile</key>
|
||||
<string>AppIcon_HWImage_NDS.icns</string>
|
||||
<key>CFBundleTypeName</key>
|
||||
<string>Nintendo DS Hardware Image</string>
|
||||
<key>CFBundleTypeRole</key>
|
||||
<string>Viewer</string>
|
||||
<key>LSItemContentTypes</key>
|
||||
<array>
|
||||
<string>com.nintendo.hwimage.ds</string>
|
||||
</array>
|
||||
<key>LSTypeIsPackage</key>
|
||||
<false/>
|
||||
<key>NSPersistentStoreTypeKey</key>
|
||||
<string>Binary</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>CFBundleTypeExtensions</key>
|
||||
<array>
|
||||
<string>xml</string>
|
||||
</array>
|
||||
<key>CFBundleTypeIconFile</key>
|
||||
<string>AppIcon_ADVANsCEneDatabase.icns</string>
|
||||
<key>CFBundleTypeName</key>
|
||||
<string>ADVANsCEne Database</string>
|
||||
<key>CFBundleTypeRole</key>
|
||||
<string>Viewer</string>
|
||||
<key>LSItemContentTypes</key>
|
||||
<array>
|
||||
<string>com.advanscene.database.nintendo.ds</string>
|
||||
</array>
|
||||
<key>LSTypeIsPackage</key>
|
||||
<false/>
|
||||
<key>NSPersistentStoreTypeKey</key>
|
||||
<string>Binary</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>CFBundleTypeExtensions</key>
|
||||
<array>
|
||||
<string>dat</string>
|
||||
</array>
|
||||
<key>CFBundleTypeIconFile</key>
|
||||
<string>AppIcon_R4CheatDatabase.icns</string>
|
||||
<key>CFBundleTypeName</key>
|
||||
<string>R4 Cheats Database</string>
|
||||
<key>CFBundleTypeRole</key>
|
||||
<string>Viewer</string>
|
||||
<key>LSItemContentTypes</key>
|
||||
<array>
|
||||
<string>net.gbatemp.cheats.database.nintendo.ds</string>
|
||||
</array>
|
||||
<key>LSTypeIsPackage</key>
|
||||
<false/>
|
||||
<key>NSPersistentStoreTypeKey</key>
|
||||
<string>Binary</string>
|
||||
</dict>
|
||||
</array>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>${PRODUCT_NAME}</string>
|
||||
<key>CFBundleIconFile</key>
|
||||
<string>AppIcon_DeSmuME</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>org.desmume.DeSmuME</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>${PRODUCT_NAME}</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>APPL</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>v0.9.11</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>DSmM</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>0.9.11</string>
|
||||
<key>LSApplicationCategoryType</key>
|
||||
<string>public.app-category.entertainment</string>
|
||||
<key>LSMinimumSystemVersion</key>
|
||||
<string>${MACOSX_DEPLOYMENT_TARGET}</string>
|
||||
<key>NSHumanReadableCopyright</key>
|
||||
<string>Copyright ©2007-2015 DeSmuME Team. All rights reserved.</string>
|
||||
<key>NSMainNibFile</key>
|
||||
<string>MainMenu</string>
|
||||
<key>NSPrincipalClass</key>
|
||||
<string>NSApplication</string>
|
||||
<key>UTExportedTypeDeclarations</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>UTTypeConformsTo</key>
|
||||
<array>
|
||||
<string>public.data</string>
|
||||
</array>
|
||||
<key>UTTypeDescription</key>
|
||||
<string>DeSmuME Save State</string>
|
||||
<key>UTTypeIconFile</key>
|
||||
<string>AppIcon_SaveState.icns</string>
|
||||
<key>UTTypeIdentifier</key>
|
||||
<string>com.desmume.savestate</string>
|
||||
<key>UTTypeTagSpecification</key>
|
||||
<dict>
|
||||
<key>public.filename-extension</key>
|
||||
<array>
|
||||
<string>dst</string>
|
||||
</array>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>UTTypeConformsTo</key>
|
||||
<array>
|
||||
<string>public.data</string>
|
||||
</array>
|
||||
<key>UTTypeDescription</key>
|
||||
<string>DeSmuME ROM Save</string>
|
||||
<key>UTTypeIconFile</key>
|
||||
<string>AppIcon_ROMSave.icns</string>
|
||||
<key>UTTypeIdentifier</key>
|
||||
<string>com.desmume.romsave</string>
|
||||
<key>UTTypeTagSpecification</key>
|
||||
<dict>
|
||||
<key>public.filename-extension</key>
|
||||
<array>
|
||||
<string>dsv</string>
|
||||
</array>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>UTTypeConformsTo</key>
|
||||
<array>
|
||||
<string>public.data</string>
|
||||
</array>
|
||||
<key>UTTypeDescription</key>
|
||||
<string>DeSmuME Firmware Configuration</string>
|
||||
<key>UTTypeIconFile</key>
|
||||
<string>AppIcon_FirmwareConfig.icns</string>
|
||||
<key>UTTypeIdentifier</key>
|
||||
<string>com.desmume.firmwareconfig</string>
|
||||
<key>UTTypeTagSpecification</key>
|
||||
<dict>
|
||||
<key>public.filename-extension</key>
|
||||
<array>
|
||||
<string>dfc</string>
|
||||
</array>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>UTTypeConformsTo</key>
|
||||
<array>
|
||||
<string>public.data</string>
|
||||
</array>
|
||||
<key>UTTypeDescription</key>
|
||||
<string>DeSmuME ROM Cheats</string>
|
||||
<key>UTTypeIconFile</key>
|
||||
<string>AppIcon_ROMCheats.icns</string>
|
||||
<key>UTTypeIdentifier</key>
|
||||
<string>com.desmume.romcheats</string>
|
||||
<key>UTTypeTagSpecification</key>
|
||||
<dict>
|
||||
<key>public.filename-extension</key>
|
||||
<array>
|
||||
<string>dct</string>
|
||||
</array>
|
||||
</dict>
|
||||
</dict>
|
||||
</array>
|
||||
<key>UTImportedTypeDeclarations</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>UTTypeConformsTo</key>
|
||||
<array>
|
||||
<string>public.data</string>
|
||||
</array>
|
||||
<key>UTTypeDescription</key>
|
||||
<string>Nintendo DS ROM</string>
|
||||
<key>UTTypeIconFile</key>
|
||||
<string>AppIcon_NintendoDS_ROM.icns</string>
|
||||
<key>UTTypeIdentifier</key>
|
||||
<string>com.nintendo.rom.ds</string>
|
||||
<key>UTTypeTagSpecification</key>
|
||||
<dict>
|
||||
<key>public.filename-extension</key>
|
||||
<array>
|
||||
<string>nds</string>
|
||||
</array>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>UTTypeConformsTo</key>
|
||||
<array>
|
||||
<string>public.data</string>
|
||||
</array>
|
||||
<key>UTTypeDescription</key>
|
||||
<string>Gameboy Advance ROM</string>
|
||||
<key>UTTypeIconFile</key>
|
||||
<string>AppIcon_NintendoGBA_ROM.icns</string>
|
||||
<key>UTTypeIdentifier</key>
|
||||
<string>com.nintendo.rom.gba</string>
|
||||
<key>UTTypeTagSpecification</key>
|
||||
<dict>
|
||||
<key>public.filename-extension</key>
|
||||
<array>
|
||||
<string>ds.gba</string>
|
||||
</array>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>UTTypeConformsTo</key>
|
||||
<array>
|
||||
<string>public.data</string>
|
||||
</array>
|
||||
<key>UTTypeDescription</key>
|
||||
<string>No$GBA ROM Save</string>
|
||||
<key>UTTypeIconFile</key>
|
||||
<string>AppIcon_NoGBA_ROMSave.icns</string>
|
||||
<key>UTTypeIdentifier</key>
|
||||
<string>de.emubase.nocash.romsave.gba</string>
|
||||
<key>UTTypeTagSpecification</key>
|
||||
<dict>
|
||||
<key>public.filename-extension</key>
|
||||
<array>
|
||||
<string>sav</string>
|
||||
</array>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>UTTypeConformsTo</key>
|
||||
<array>
|
||||
<string>public.data</string>
|
||||
</array>
|
||||
<key>UTTypeDescription</key>
|
||||
<string>Action Replay Save</string>
|
||||
<key>UTTypeIconFile</key>
|
||||
<string>AppIcon_ActionReplaySave.icns</string>
|
||||
<key>UTTypeIdentifier</key>
|
||||
<string>com.codejunkies.actionreplay.save.nintendo.ds</string>
|
||||
<key>UTTypeTagSpecification</key>
|
||||
<dict>
|
||||
<key>public.filename-extension</key>
|
||||
<array>
|
||||
<string>duc</string>
|
||||
</array>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>UTTypeConformsTo</key>
|
||||
<array>
|
||||
<string>public.data</string>
|
||||
</array>
|
||||
<key>UTTypeDescription</key>
|
||||
<string>Nintendo DS Hardware Image</string>
|
||||
<key>UTTypeIconFile</key>
|
||||
<string>AppIcon_HWImage_NDS.icns</string>
|
||||
<key>UTTypeIdentifier</key>
|
||||
<string>com.nintendo.hwimage.ds</string>
|
||||
<key>UTTypeTagSpecification</key>
|
||||
<dict>
|
||||
<key>public.filename-extension</key>
|
||||
<array>
|
||||
<string>bin</string>
|
||||
</array>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>UTTypeConformsTo</key>
|
||||
<array>
|
||||
<string>public.xml</string>
|
||||
</array>
|
||||
<key>UTTypeDescription</key>
|
||||
<string>ADVANsCEne Database</string>
|
||||
<key>UTTypeIconFile</key>
|
||||
<string>AppIcon_ADVANsCEneDatabase.icns</string>
|
||||
<key>UTTypeIdentifier</key>
|
||||
<string>com.advanscene.database.nintendo.ds</string>
|
||||
<key>UTTypeTagSpecification</key>
|
||||
<dict>
|
||||
<key>public.filename-extension</key>
|
||||
<array>
|
||||
<string>xml</string>
|
||||
</array>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>UTTypeConformsTo</key>
|
||||
<array>
|
||||
<string>public.data</string>
|
||||
</array>
|
||||
<key>UTTypeDescription</key>
|
||||
<string>R4 Cheats Database</string>
|
||||
<key>UTTypeIconFile</key>
|
||||
<string>AppIcon_R4CheatDatabase.icns</string>
|
||||
<key>UTTypeIdentifier</key>
|
||||
<string>net.gbatemp.cheats.database.nintendo.ds</string>
|
||||
<key>UTTypeTagSpecification</key>
|
||||
<dict>
|
||||
<key>public.filename-extension</key>
|
||||
<array>
|
||||
<string>dat</string>
|
||||
</array>
|
||||
</dict>
|
||||
</dict>
|
||||
</array>
|
||||
</dict>
|
||||
</plist>
|
||||
Executable
+202
@@ -0,0 +1,202 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>12</key>
|
||||
<string>Q</string>
|
||||
<key>13</key>
|
||||
<string>W</string>
|
||||
<key>14</key>
|
||||
<string>E</string>
|
||||
<key>15</key>
|
||||
<string>R</string>
|
||||
<key>17</key>
|
||||
<string>T</string>
|
||||
<key>16</key>
|
||||
<string>Y</string>
|
||||
<key>32</key>
|
||||
<string>U</string>
|
||||
<key>34</key>
|
||||
<string>I</string>
|
||||
<key>31</key>
|
||||
<string>O</string>
|
||||
<key>35</key>
|
||||
<string>P</string>
|
||||
<key>0</key>
|
||||
<string>A</string>
|
||||
<key>1</key>
|
||||
<string>S</string>
|
||||
<key>2</key>
|
||||
<string>D</string>
|
||||
<key>3</key>
|
||||
<string>F</string>
|
||||
<key>5</key>
|
||||
<string>G</string>
|
||||
<key>4</key>
|
||||
<string>H</string>
|
||||
<key>38</key>
|
||||
<string>J</string>
|
||||
<key>40</key>
|
||||
<string>K</string>
|
||||
<key>37</key>
|
||||
<string>L</string>
|
||||
<key>6</key>
|
||||
<string>Z</string>
|
||||
<key>7</key>
|
||||
<string>X</string>
|
||||
<key>8</key>
|
||||
<string>C</string>
|
||||
<key>9</key>
|
||||
<string>V</string>
|
||||
<key>11</key>
|
||||
<string>B</string>
|
||||
<key>45</key>
|
||||
<string>N</string>
|
||||
<key>46</key>
|
||||
<string>M</string>
|
||||
<key>18</key>
|
||||
<string>1</string>
|
||||
<key>19</key>
|
||||
<string>2</string>
|
||||
<key>20</key>
|
||||
<string>3</string>
|
||||
<key>21</key>
|
||||
<string>4</string>
|
||||
<key>23</key>
|
||||
<string>5</string>
|
||||
<key>22</key>
|
||||
<string>6</string>
|
||||
<key>26</key>
|
||||
<string>7</string>
|
||||
<key>28</key>
|
||||
<string>8</string>
|
||||
<key>25</key>
|
||||
<string>9</string>
|
||||
<key>29</key>
|
||||
<string>0</string>
|
||||
<key>122</key>
|
||||
<string>F1</string>
|
||||
<key>120</key>
|
||||
<string>F2</string>
|
||||
<key>99</key>
|
||||
<string>F3</string>
|
||||
<key>118</key>
|
||||
<string>F4</string>
|
||||
<key>96</key>
|
||||
<string>F5</string>
|
||||
<key>97</key>
|
||||
<string>F6</string>
|
||||
<key>98</key>
|
||||
<string>F7</string>
|
||||
<key>100</key>
|
||||
<string>F8</string>
|
||||
<key>101</key>
|
||||
<string>F9</string>
|
||||
<key>109</key>
|
||||
<string>F10</string>
|
||||
<key>103</key>
|
||||
<string>F11</string>
|
||||
<key>111</key>
|
||||
<string>F12</string>
|
||||
<key>105</key>
|
||||
<string>F13</string>
|
||||
<key>107</key>
|
||||
<string>F14</string>
|
||||
<key>113</key>
|
||||
<string>F15</string>
|
||||
<key>106</key>
|
||||
<string>F16</string>
|
||||
<key>64</key>
|
||||
<string>F17</string>
|
||||
<key>79</key>
|
||||
<string>F18</string>
|
||||
<key>80</key>
|
||||
<string>F19</string>
|
||||
<key>50</key>
|
||||
<string>` (Accent)</string>
|
||||
<key>27</key>
|
||||
<string>- (Dash)</string>
|
||||
<key>24</key>
|
||||
<string>=</string>
|
||||
<key>51</key>
|
||||
<string>Delete (Backspace)</string>
|
||||
<key>48</key>
|
||||
<string>Tab</string>
|
||||
<key>33</key>
|
||||
<string>[</string>
|
||||
<key>30</key>
|
||||
<string>]</string>
|
||||
<key>42</key>
|
||||
<string>\</string>
|
||||
<key>41</key>
|
||||
<string>; (Semicolon)</string>
|
||||
<key>39</key>
|
||||
<string>' (Quote)</string>
|
||||
<key>36</key>
|
||||
<string>Return</string>
|
||||
<key>43</key>
|
||||
<string>, (Comma)</string>
|
||||
<key>47</key>
|
||||
<string>. (Period)</string>
|
||||
<key>44</key>
|
||||
<string>/</string>
|
||||
<key>49</key>
|
||||
<string>Space</string>
|
||||
<key>115</key>
|
||||
<string>Home</string>
|
||||
<key>119</key>
|
||||
<string>End</string>
|
||||
<key>116</key>
|
||||
<string>Page Up</string>
|
||||
<key>121</key>
|
||||
<string>Page Down</string>
|
||||
<key>117</key>
|
||||
<string>Forward Delete</string>
|
||||
<key>126</key>
|
||||
<string>Up Arrow</string>
|
||||
<key>125</key>
|
||||
<string>Down Arrow</string>
|
||||
<key>123</key>
|
||||
<string>Left Arrow</string>
|
||||
<key>124</key>
|
||||
<string>Right Arrow</string>
|
||||
<key>82</key>
|
||||
<string>NumPad 0</string>
|
||||
<key>83</key>
|
||||
<string>NumPad 1</string>
|
||||
<key>84</key>
|
||||
<string>NumPad 2</string>
|
||||
<key>85</key>
|
||||
<string>NumPad 3</string>
|
||||
<key>86</key>
|
||||
<string>NumPad 4</string>
|
||||
<key>87</key>
|
||||
<string>NumPad 5</string>
|
||||
<key>88</key>
|
||||
<string>NumPad 6</string>
|
||||
<key>89</key>
|
||||
<string>NumPad 7</string>
|
||||
<key>91</key>
|
||||
<string>NumPad 8</string>
|
||||
<key>92</key>
|
||||
<string>NumPad 9</string>
|
||||
<key>71</key>
|
||||
<string>NumPad Clear</string>
|
||||
<key>81</key>
|
||||
<string>NumPad =</string>
|
||||
<key>75</key>
|
||||
<string>NumPad /</string>
|
||||
<key>67</key>
|
||||
<string>NumPad *</string>
|
||||
<key>78</key>
|
||||
<string>NumPad -</string>
|
||||
<key>69</key>
|
||||
<string>NumPad +</string>
|
||||
<key>65</key>
|
||||
<string>NumPad .</string>
|
||||
<key>76</key>
|
||||
<string>NumPad Enter</string>
|
||||
<key>53</key>
|
||||
<string>Escape</string>
|
||||
</dict>
|
||||
</plist>
|
||||
Executable
+14
@@ -0,0 +1,14 @@
|
||||
EXTRA_DIST = cocoa_util.m DeSmuME.cbp globals.h main.mm main_window.h main_window.mm nds_control.h nds_control.mm preferences.mm \
|
||||
about.m DeSmuME.icns Info.plist InfoPlist.strings input.h input.mm \
|
||||
makeapp.sh PkgInfo preferences.h screenshot.h screenshot.mm \
|
||||
screen_state.h screen_state.m sndOSX.h sndOSX.mm video_output_view.h video_output_view.mm \
|
||||
DeSmuME.xcodeproj/project.pbxproj Rakefile \
|
||||
dialogs/rom_info.h dialogs/rom_info.m dialogs/speed_limit_selection_window.h dialogs/speed_limit_selection_window.mm \
|
||||
translations/English.lproj/Localizable.strings translations/English.lproj/MainMenu.nib/classes.nib \
|
||||
translations/English.lproj/MainMenu.nib/info.nib translations/English.lproj/MainMenu.nib/keyedobjects.nib \
|
||||
translations/French.lproj/Localizable.strings translations/French.lproj/MainMenu.nib/classes.nib \
|
||||
translations/French.lproj/MainMenu.nib/info.nib translations/French.lproj/MainMenu.nib/keyedobjects.nib \
|
||||
translations/Italian.lproj/Localizable.strings translations/Italian.lproj/MainMenu.nib/classes.nib \
|
||||
translations/Italian.lproj/MainMenu.nib/info.nib translations/Italian.lproj/MainMenu.nib/keyedobjects.nib \
|
||||
translations/Japanese.lproj/Localizable.strings translations/Japanese.lproj/MainMenu.nib/classes.nib \
|
||||
translations/Japanese.lproj/MainMenu.nib/info.nib translations/Japanese.lproj/MainMenu.nib/keyedobjects.nib
|
||||
Executable
+6410
File diff suppressed because it is too large
Load Diff
Executable
+410
@@ -0,0 +1,410 @@
|
||||
/*
|
||||
Copyright (C) 2014-2015 DeSmuME team
|
||||
|
||||
This file is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This file is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with the this software. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef _OGLDISPLAYOUTPUT_H_
|
||||
#define _OGLDISPLAYOUTPUT_H_
|
||||
|
||||
#ifndef _OGLDISPLAYOUTPUT_3_2_H_
|
||||
|
||||
#if defined(__APPLE__)
|
||||
#include <OpenGL/gl.h>
|
||||
#include <OpenGL/glext.h>
|
||||
#endif
|
||||
|
||||
#endif // _OGLDISPLAYOUTPUT_3_2_H_
|
||||
|
||||
#include <set>
|
||||
#include <string>
|
||||
#include "../filter/videofilter.h"
|
||||
|
||||
class OGLVideoOutput;
|
||||
|
||||
enum
|
||||
{
|
||||
OutputFilterTypeID_NearestNeighbor = 0,
|
||||
OutputFilterTypeID_Bilinear = 1,
|
||||
OutputFilterTypeID_BicubicBSpline = 2,
|
||||
OutputFilterTypeID_BicubicMitchell = 3,
|
||||
OutputFilterTypeID_Lanczos2 = 4,
|
||||
OutputFilterTypeID_Lanczos3 = 5
|
||||
};
|
||||
|
||||
enum ShaderSupportTier
|
||||
{
|
||||
ShaderSupport_Unsupported = 0,
|
||||
ShaderSupport_BottomTier = 1,
|
||||
ShaderSupport_LowTier = 2,
|
||||
ShaderSupport_MidTier = 3,
|
||||
ShaderSupport_HighTier = 4,
|
||||
ShaderSupport_TopTier = 5,
|
||||
ShaderSupport_FutureTier = 6,
|
||||
};
|
||||
|
||||
class OGLInfo
|
||||
{
|
||||
protected:
|
||||
GLint _versionMajor;
|
||||
GLint _versionMinor;
|
||||
GLint _versionRevision;
|
||||
ShaderSupportTier _shaderSupport;
|
||||
bool _useShader150;
|
||||
|
||||
bool _isVBOSupported;
|
||||
bool _isPBOSupported;
|
||||
bool _isFBOSupported;
|
||||
|
||||
public:
|
||||
OGLInfo();
|
||||
virtual ~OGLInfo() {};
|
||||
|
||||
bool IsUsingShader150();
|
||||
bool IsVBOSupported();
|
||||
bool IsPBOSupported();
|
||||
bool IsShaderSupported();
|
||||
bool IsFBOSupported();
|
||||
ShaderSupportTier GetShaderSupport();
|
||||
|
||||
virtual void GetExtensionSetOGL(std::set<std::string> *oglExtensionSet) = 0;
|
||||
virtual bool IsExtensionPresent(const std::set<std::string> &oglExtensionSet, const std::string &extensionName) const = 0;
|
||||
};
|
||||
|
||||
class OGLInfo_Legacy : public OGLInfo
|
||||
{
|
||||
public:
|
||||
OGLInfo_Legacy();
|
||||
|
||||
virtual void GetExtensionSetOGL(std::set<std::string> *oglExtensionSet);
|
||||
virtual bool IsExtensionPresent(const std::set<std::string> &oglExtensionSet, const std::string &extensionName) const;
|
||||
};
|
||||
|
||||
class OGLShaderProgram
|
||||
{
|
||||
protected:
|
||||
GLuint _vertexID;
|
||||
GLuint _fragmentID;
|
||||
GLuint _programID;
|
||||
ShaderSupportTier _shaderSupport;
|
||||
|
||||
virtual GLuint LoadShaderOGL(GLenum shaderType, const char *shaderProgram, bool useShader150);
|
||||
virtual bool LinkOGL();
|
||||
|
||||
public:
|
||||
OGLShaderProgram();
|
||||
virtual ~OGLShaderProgram();
|
||||
|
||||
ShaderSupportTier GetShaderSupport();
|
||||
void SetShaderSupport(const ShaderSupportTier theTier);
|
||||
GLuint GetVertexShaderID();
|
||||
void SetVertexShaderOGL(const char *shaderProgram, bool useShader150);
|
||||
GLuint GetFragmentShaderID();
|
||||
void SetFragmentShaderOGL(const char *shaderProgram, bool useShader150);
|
||||
void SetVertexAndFragmentShaderOGL(const char *vertShaderProgram, const char *fragShaderProgram, bool useShader150);
|
||||
GLuint GetProgramID();
|
||||
};
|
||||
|
||||
class OGLFilter
|
||||
{
|
||||
protected:
|
||||
OGLShaderProgram *_program;
|
||||
bool _isVAOPresent;
|
||||
GLuint _texDstID;
|
||||
GLint _texCoordBuffer[8];
|
||||
|
||||
GLuint _fboID;
|
||||
GLuint _vaoID;
|
||||
GLuint _vboVtxID;
|
||||
GLuint _vboTexCoordID;
|
||||
GLuint _vboElementID;
|
||||
|
||||
GLfloat _scale;
|
||||
GLsizei _srcWidth;
|
||||
GLsizei _srcHeight;
|
||||
GLsizei _dstWidth;
|
||||
GLsizei _dstHeight;
|
||||
|
||||
virtual void OGLFilterInit(GLsizei srcWidth, GLsizei srcHeight, GLfloat scale);
|
||||
|
||||
public:
|
||||
OGLFilter();
|
||||
OGLFilter(GLsizei srcWidth, GLsizei srcHeight, GLfloat scale);
|
||||
virtual ~OGLFilter();
|
||||
static void GetSupport(int vfTypeID, bool *outSupportCPU, bool *outSupportShader);
|
||||
|
||||
OGLShaderProgram* GetProgram();
|
||||
GLuint GetDstTexID();
|
||||
GLsizei GetSrcWidth();
|
||||
GLsizei GetSrcHeight();
|
||||
GLsizei GetDstWidth();
|
||||
GLsizei GetDstHeight();
|
||||
void SetSrcSizeOGL(GLsizei w, GLsizei h);
|
||||
GLfloat GetScale();
|
||||
void SetScaleOGL(GLfloat scale);
|
||||
virtual GLuint RunFilterOGL(GLuint srcTexID);
|
||||
void DownloadDstBufferOGL(uint32_t *dstBuffer, size_t lineOffset, size_t readLineCount);
|
||||
};
|
||||
|
||||
class OGLFilterDeposterize : public OGLFilter
|
||||
{
|
||||
protected:
|
||||
GLuint _texIntermediateID;
|
||||
|
||||
public:
|
||||
OGLFilterDeposterize(GLsizei srcWidth, GLsizei srcHeight, ShaderSupportTier theTier, bool useShader150);
|
||||
~OGLFilterDeposterize();
|
||||
|
||||
virtual GLuint RunFilterOGL(GLuint srcTexID);
|
||||
};
|
||||
|
||||
class OGLVideoLayer
|
||||
{
|
||||
protected:
|
||||
OGLVideoOutput *_output;
|
||||
GLsizei _viewportWidth;
|
||||
GLsizei _viewportHeight;
|
||||
|
||||
public:
|
||||
OGLVideoLayer() {};
|
||||
~OGLVideoLayer() {};
|
||||
|
||||
void SetViewportSizeOGL(GLsizei w, GLsizei h)
|
||||
{
|
||||
this->_viewportWidth = w;
|
||||
this->_viewportHeight = h;
|
||||
};
|
||||
|
||||
virtual void ProcessOGL() {};
|
||||
virtual void RenderOGL() {};
|
||||
};
|
||||
|
||||
class OGLImage
|
||||
{
|
||||
protected:
|
||||
bool _isVAOPresent;
|
||||
bool _canUseShaderBasedFilters;
|
||||
bool _canUseShaderOutput;
|
||||
bool _useShader150;
|
||||
ShaderSupportTier _shaderSupport;
|
||||
|
||||
bool _needUploadVertices;
|
||||
bool _useDeposterize;
|
||||
bool _useShaderBasedPixelScaler;
|
||||
bool _filtersPreferGPU;
|
||||
int _outputFilter;
|
||||
VideoFilterTypeID _pixelScaler;
|
||||
|
||||
OGLFilter *_filterDeposterize;
|
||||
OGLFilter *_shaderFilter;
|
||||
OGLShaderProgram *_finalOutputProgram;
|
||||
|
||||
VideoFilter *_vf;
|
||||
uint32_t *_vfMasterDstBuffer;
|
||||
|
||||
double _normalWidth;
|
||||
double _normalHeight;
|
||||
GLsizei _viewportWidth;
|
||||
GLsizei _viewportHeight;
|
||||
|
||||
GLubyte *_vtxElementPointer;
|
||||
|
||||
GLint _displayTexFilter;
|
||||
GLuint _texCPUFilterDstID;
|
||||
|
||||
GLuint _texLQ2xLUT;
|
||||
GLuint _texHQ2xLUT;
|
||||
GLuint _texHQ4xLUT;
|
||||
|
||||
GLint _vtxBuffer[8];
|
||||
GLfloat _texCoordBuffer[8];
|
||||
|
||||
GLuint _texVideoInputDataID;
|
||||
GLuint _texVideoSourceID;
|
||||
GLuint _texVideoPixelScalerID;
|
||||
GLuint _texVideoOutputID;
|
||||
GLuint _vaoMainStatesID;
|
||||
GLuint _vboVertexID;
|
||||
GLuint _vboTexCoordID;
|
||||
GLuint _vboElementID;
|
||||
|
||||
GLint _uniformFinalOutputAngleDegrees;
|
||||
GLint _uniformFinalOutputScalar;
|
||||
GLint _uniformFinalOutputViewSize;
|
||||
|
||||
void UploadHQnxLUTs();
|
||||
|
||||
virtual void UploadVerticesOGL();
|
||||
virtual void UploadTexCoordsOGL();
|
||||
virtual void UploadTransformationOGL();
|
||||
|
||||
void UpdateVertices();
|
||||
void UpdateTexCoords(GLfloat s, GLfloat t);
|
||||
|
||||
public:
|
||||
OGLImage() {};
|
||||
OGLImage(OGLInfo *oglInfo, GLsizei imageWidth, GLsizei imageHeight, GLsizei viewportWidth, GLsizei viewportHeight);
|
||||
virtual ~OGLImage();
|
||||
|
||||
bool GetFiltersPreferGPU();
|
||||
void SetFiltersPreferGPUOGL(bool preferGPU);
|
||||
|
||||
bool GetSourceDeposterize();
|
||||
void SetSourceDeposterize(bool useDeposterize);
|
||||
|
||||
bool CanUseShaderBasedFilters();
|
||||
void GetNormalSize(double *w, double *h);
|
||||
|
||||
int GetOutputFilter();
|
||||
virtual void SetOutputFilterOGL(const int filterID);
|
||||
int GetPixelScaler();
|
||||
virtual void SetPixelScalerOGL(const int filterID);
|
||||
virtual bool SetGPUPixelScalerOGL(const VideoFilterTypeID filterID);
|
||||
virtual void SetCPUPixelScalerOGL(const VideoFilterTypeID filterID);
|
||||
virtual void LoadFrameOGL(const uint32_t *frameData, GLint x, GLint y, GLsizei w, GLsizei h);
|
||||
virtual void ProcessOGL();
|
||||
virtual void RenderOGL();
|
||||
};
|
||||
|
||||
class OGLDisplayLayer : public OGLVideoLayer
|
||||
{
|
||||
protected:
|
||||
bool _isVAOPresent;
|
||||
bool _canUseShaderBasedFilters;
|
||||
bool _canUseShaderOutput;
|
||||
bool _useShader150;
|
||||
ShaderSupportTier _shaderSupport;
|
||||
|
||||
bool _needUploadVertices;
|
||||
bool _useDeposterize;
|
||||
bool _useShaderBasedPixelScaler;
|
||||
bool _filtersPreferGPU;
|
||||
int _outputFilter;
|
||||
VideoFilterTypeID _pixelScaler;
|
||||
|
||||
OGLShaderProgram *_finalOutputProgram;
|
||||
OGLFilter *_filterDeposterize[2];
|
||||
OGLFilter *_shaderFilter[2];
|
||||
GLint _displayTexFilter[2];
|
||||
|
||||
GLuint _texVideoInputDataID[2];
|
||||
GLuint _texVideoSourceID[2];
|
||||
GLuint _texVideoPixelScalerID[2];
|
||||
GLuint _texVideoOutputID[2];
|
||||
|
||||
uint32_t *_vfMasterDstBuffer;
|
||||
VideoFilter *_vf[2];
|
||||
VideoFilter *_vfDual;
|
||||
GLuint _texCPUFilterDstID[2];
|
||||
|
||||
int _displayMode;
|
||||
int _displayOrder;
|
||||
int _displayOrientation;
|
||||
double _normalWidth;
|
||||
double _normalHeight;
|
||||
GLfloat _gapScalar;
|
||||
GLfloat _rotation;
|
||||
|
||||
GLuint _texLQ2xLUT;
|
||||
GLuint _texHQ2xLUT;
|
||||
GLuint _texHQ4xLUT;
|
||||
|
||||
GLint vtxBuffer[4 * 8];
|
||||
GLfloat texCoordBuffer[2 * 8];
|
||||
size_t _vtxBufferOffset;
|
||||
|
||||
GLuint _vaoMainStatesID;
|
||||
GLuint _vboVertexID;
|
||||
GLuint _vboTexCoordID;
|
||||
GLuint _vboElementID;
|
||||
|
||||
GLint _uniformFinalOutputAngleDegrees;
|
||||
GLint _uniformFinalOutputScalar;
|
||||
GLint _uniformFinalOutputViewSize;
|
||||
|
||||
void UploadHQnxLUTs();
|
||||
|
||||
virtual void UploadVerticesOGL();
|
||||
virtual void UploadTexCoordsOGL();
|
||||
virtual void UploadTransformationOGL();
|
||||
|
||||
void UpdateVertices();
|
||||
void UpdateTexCoords(GLfloat s, GLfloat t);
|
||||
|
||||
public:
|
||||
OGLDisplayLayer() {};
|
||||
OGLDisplayLayer(OGLVideoOutput *oglVO);
|
||||
virtual ~OGLDisplayLayer();
|
||||
|
||||
bool GetFiltersPreferGPU();
|
||||
void SetFiltersPreferGPUOGL(bool preferGPU);
|
||||
|
||||
int GetMode();
|
||||
void SetMode(int dispMode);
|
||||
int GetOrientation();
|
||||
void SetOrientation(int dispOrientation);
|
||||
int GetOrder();
|
||||
void SetOrder(int dispOrder);
|
||||
GLfloat GetGapScalar();
|
||||
void SetGapScalar(GLfloat theScalar);
|
||||
GLfloat GetRotation();
|
||||
void SetRotation(GLfloat theRotation);
|
||||
bool GetSourceDeposterize();
|
||||
void SetSourceDeposterize(bool useDeposterize);
|
||||
|
||||
bool CanUseShaderBasedFilters();
|
||||
void GetNormalSize(double *w, double *h);
|
||||
|
||||
int GetOutputFilter();
|
||||
virtual void SetOutputFilterOGL(const int filterID);
|
||||
int GetPixelScaler();
|
||||
virtual void SetPixelScalerOGL(const int filterID);
|
||||
virtual bool SetGPUPixelScalerOGL(const VideoFilterTypeID filterID);
|
||||
virtual void SetCPUPixelScalerOGL(const VideoFilterTypeID filterID);
|
||||
virtual void LoadFrameOGL(const uint16_t *frameData, GLint x, GLint y, GLsizei w, GLsizei h);
|
||||
virtual void ProcessOGL();
|
||||
virtual void RenderOGL();
|
||||
};
|
||||
|
||||
class OGLVideoOutput
|
||||
{
|
||||
protected:
|
||||
OGLInfo *_info;
|
||||
GLsizei _viewportWidth;
|
||||
GLsizei _viewportHeight;
|
||||
std::vector<OGLVideoLayer *> *_layerList;
|
||||
|
||||
public:
|
||||
OGLVideoOutput();
|
||||
~OGLVideoOutput();
|
||||
|
||||
virtual void InitLayers();
|
||||
virtual OGLInfo* GetInfo();
|
||||
virtual GLsizei GetViewportWidth();
|
||||
virtual GLsizei GetViewportHeight();
|
||||
OGLDisplayLayer* GetDisplayLayer();
|
||||
|
||||
virtual void ProcessOGL();
|
||||
virtual void RenderOGL();
|
||||
virtual void SetViewportSizeOGL(GLsizei w, GLsizei h);
|
||||
};
|
||||
|
||||
OGLInfo* OGLInfoCreate_Legacy();
|
||||
|
||||
extern OGLInfo* (*OGLInfoCreate_Func)();
|
||||
extern void (*glBindVertexArrayDESMUME)(GLuint id);
|
||||
extern void (*glDeleteVertexArraysDESMUME)(GLsizei n, const GLuint *ids);
|
||||
extern void (*glGenVertexArraysDESMUME)(GLsizei n, GLuint *ids);
|
||||
|
||||
#endif // _OGLDISPLAYOUTPUT_H_
|
||||
Executable
+92
@@ -0,0 +1,92 @@
|
||||
/*
|
||||
Copyright (C) 2015 DeSmuME team
|
||||
|
||||
This file is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This file is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with the this software. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "OGLDisplayOutput_3_2.h"
|
||||
|
||||
enum OGLVertexAttributeID
|
||||
{
|
||||
OGLVertexAttributeID_Position = 0,
|
||||
OGLVertexAttributeID_TexCoord0 = 8
|
||||
};
|
||||
|
||||
OGLInfo* OGLInfoCreate_3_2()
|
||||
{
|
||||
return new OGLInfo_3_2;
|
||||
}
|
||||
|
||||
void glBindVertexArray_3_2(GLuint vaoID)
|
||||
{
|
||||
glBindVertexArray(vaoID);
|
||||
}
|
||||
|
||||
void glDeleteVertexArrays_3_2(GLsizei n, const GLuint *vaoIDs)
|
||||
{
|
||||
glDeleteVertexArrays(n, vaoIDs);
|
||||
}
|
||||
|
||||
void glGenVertexArrays_3_2(GLsizei n, GLuint *vaoIDs)
|
||||
{
|
||||
glGenVertexArrays(n, vaoIDs);
|
||||
}
|
||||
|
||||
OGLInfo_3_2::OGLInfo_3_2()
|
||||
{
|
||||
_useShader150 = true;
|
||||
_isVBOSupported = true;
|
||||
_isPBOSupported = true;
|
||||
_isFBOSupported = true;
|
||||
|
||||
glBindVertexArrayDESMUME = &glBindVertexArray_3_2;
|
||||
glDeleteVertexArraysDESMUME = &glDeleteVertexArrays_3_2;
|
||||
glGenVertexArraysDESMUME = &glGenVertexArrays_3_2;
|
||||
|
||||
_shaderSupport = ShaderSupport_MidTier;
|
||||
|
||||
if (_versionMajor == 4)
|
||||
{
|
||||
if (_versionMinor <= 1)
|
||||
{
|
||||
_shaderSupport = ShaderSupport_HighTier;
|
||||
}
|
||||
else
|
||||
{
|
||||
_shaderSupport = ShaderSupport_TopTier;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void OGLInfo_3_2::GetExtensionSetOGL(std::set<std::string> *oglExtensionSet)
|
||||
{
|
||||
GLint extensionCount = 0;
|
||||
|
||||
glGetIntegerv(GL_NUM_EXTENSIONS, &extensionCount);
|
||||
for (unsigned int i = 0; i < extensionCount; i++)
|
||||
{
|
||||
std::string extensionName = std::string((const char *)glGetStringi(GL_EXTENSIONS, i));
|
||||
oglExtensionSet->insert(extensionName);
|
||||
}
|
||||
}
|
||||
|
||||
bool OGLInfo_3_2::IsExtensionPresent(const std::set<std::string> &oglExtensionSet, const std::string &extensionName) const
|
||||
{
|
||||
if (oglExtensionSet.size() == 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return (oglExtensionSet.find(extensionName) != oglExtensionSet.end());
|
||||
}
|
||||
Executable
+39
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
Copyright (C) 2015 DeSmuME team
|
||||
|
||||
This file is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This file is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with the this software. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef _OGLDISPLAYOUTPUT_3_2_H_
|
||||
#define _OGLDISPLAYOUTPUT_3_2_H_
|
||||
|
||||
#if defined(__APPLE__)
|
||||
#include <OpenGL/gl3.h>
|
||||
#include <OpenGL/gl3ext.h>
|
||||
#endif
|
||||
|
||||
#include "OGLDisplayOutput.h"
|
||||
|
||||
class OGLInfo_3_2 : public OGLInfo
|
||||
{
|
||||
public:
|
||||
OGLInfo_3_2();
|
||||
|
||||
virtual void GetExtensionSetOGL(std::set<std::string> *oglExtensionSet);
|
||||
virtual bool IsExtensionPresent(const std::set<std::string> &oglExtensionSet, const std::string &extensionName) const;
|
||||
};
|
||||
|
||||
OGLInfo* OGLInfoCreate_3_2();
|
||||
|
||||
#endif
|
||||
Executable
+1
@@ -0,0 +1 @@
|
||||
APPL????
|
||||
Executable
+203
@@ -0,0 +1,203 @@
|
||||
require 'tempfile'
|
||||
require "open3"
|
||||
|
||||
# General
|
||||
|
||||
indent = ' '
|
||||
|
||||
# Compile Options
|
||||
|
||||
compile = {
|
||||
:command => 'g++',
|
||||
:files => Dir['*.m'] + Dir['*.mm'] + Dir['dialogs/*.m'] + Dir['dialogs/*.mm'] + ([
|
||||
'MMU', 'SPU', 'emufile', 'fs-linux', 'matrix', 'FIFO', 'NDSSystem', 'arm_instructions', 'cp15', 'mc', 'cheatSystem',
|
||||
'thumb_instructions', 'GPU', 'OGLRender', 'armcpu', 'gfx3d', 'render3D', 'wifi', 'GPU_osd_stub', 'ROMReader', 'texcache',
|
||||
'slot1', 'movie',
|
||||
'bios', 'debug', 'saves', 'readwrite', 'rtc', 'rasterize', 'common', 'mic', 'addons'].map { |core_file| '../' + core_file + '.cpp' } ) +
|
||||
Dir['../utils/*.c'] + Dir['../utils/*.cpp'] + Dir['../utils/decrypt/*.cpp'] + Dir['../addons/*.cpp'],
|
||||
:defines => {
|
||||
:global => ['DESMUME_OBJ_C', 'OBJ_C'],
|
||||
:cocoa => ['DESMUME_COCOA', 'HAVE_LIBZ', 'HAVE_OPENGL']},
|
||||
:options => {
|
||||
:global => [
|
||||
'arch i386',
|
||||
'fmessage-length=0',
|
||||
'pascal-strings',
|
||||
'fasm-blocks',
|
||||
'O3',
|
||||
'mfix-and-continue',
|
||||
'funroll-loops',
|
||||
'fstrict-aliasing',
|
||||
'ftree-vectorize',
|
||||
'mmacosx-version-min=10.4',
|
||||
'gdwarf-2'],
|
||||
:obj_cpp => ['fvisibility-inlines-hidden']
|
||||
}
|
||||
}
|
||||
|
||||
# Link Options
|
||||
|
||||
link = {
|
||||
:command => 'gcc',
|
||||
:files => Dir[File.dirname(__FILE__) + '/build/rake/o/*.o'],
|
||||
:libraries => { :cocoa => ['z', 'stdc++'] },
|
||||
:frameworks => { :cocoa => ['Cocoa', 'OpenGL', 'AudioUnit'] },
|
||||
:options => {}
|
||||
}
|
||||
|
||||
# Params
|
||||
|
||||
def verbose?
|
||||
return false unless ENV.include? 'verbose'
|
||||
return false if ENV['verbose'].downcase == 'false'
|
||||
return true if ENV['verbose'].downcase == 'true'
|
||||
raise StandardError, "verbose must be true or false. Type rake help for help"
|
||||
end
|
||||
|
||||
# Compile Step
|
||||
|
||||
desc 'Compiles the source files'
|
||||
|
||||
task :compile do
|
||||
puts 'Compiling...'
|
||||
|
||||
#create directory to place object files
|
||||
Dir.mkdir(File.dirname(__FILE__) + '/build') rescue nil
|
||||
Dir.mkdir(File.dirname(__FILE__) + '/build/rake') rescue nil
|
||||
Dir.mkdir(File.dirname(__FILE__) + '/build/rake/o') rescue nil
|
||||
|
||||
task_options = []
|
||||
task_options += compile[:options][:global] rescue []
|
||||
task_options += compile[:options][:cocoa ] rescue []
|
||||
task_options += compile[:defines][:global].collect { |d| 'D' + d } rescue []
|
||||
task_options += compile[:defines][:cocoa ].collect { |d| 'D' + d } rescue []
|
||||
|
||||
compile[:files].each do |filename|
|
||||
puts indent + 'Compiling ' + filename
|
||||
|
||||
file_options = []
|
||||
file_options += compile[:options][:obj_c ] rescue [] if filename =~ /.*\.m$/i
|
||||
file_options += compile[:options][:obj_cpp] rescue [] if filename =~ /.*\.mm$/i
|
||||
file_options += compile[:defines][:obj_c ].collect { |d| 'D' + d } rescue [] if filename =~ /.*\.m/i
|
||||
file_options += compile[:defines][:obj_cpp].collect { |d| 'D' + d } rescue [] if filename =~ /.*\.mm/i
|
||||
|
||||
command = [compile[:command]]
|
||||
command << filename
|
||||
command << '-o ' + File.dirname(__FILE__) + '/build/rake/o/' + File.basename(filename) + '.o'
|
||||
command << '-c'
|
||||
|
||||
command += (file_options + task_options).map { |o| '-' + o }
|
||||
command = command.join ' '
|
||||
|
||||
puts indent*2 + command if verbose?
|
||||
|
||||
Open3.popen3(command) do |stdin, stdout, stderr|
|
||||
|
||||
stdout.readlines.each do |line|
|
||||
puts indent*2 + line
|
||||
end
|
||||
|
||||
error = false
|
||||
stderr.readlines.each do |err|
|
||||
error = true if err =~ /:\s*error\s*:/i
|
||||
puts indent*2 + err
|
||||
end
|
||||
raise StandardError, "Didn't compile!" if error
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Link Step
|
||||
|
||||
desc 'Builds an executable out of the object files'
|
||||
|
||||
task :link => :compile do
|
||||
puts 'Linking...'
|
||||
|
||||
Dir.mkdir(File.dirname(__FILE__) + '/build') rescue nil
|
||||
Dir.mkdir(File.dirname(__FILE__) + '/build/rake') rescue nil
|
||||
Dir.mkdir(File.dirname(__FILE__) + '/build/rake/DeSmuME.app') rescue nil
|
||||
Dir.mkdir(File.dirname(__FILE__) + '/build/rake/DeSmuME.app/Contents') rescue nil
|
||||
Dir.mkdir(File.dirname(__FILE__) + '/build/rake/DeSmuME.app/Contents/MacOS/') rescue nil
|
||||
|
||||
command = [link[:command]]
|
||||
command += link[:files]
|
||||
command << '-o ' + File.dirname(__FILE__) + '/build/rake/DeSmuME.app/Contents/MacOS/DeSmuME'
|
||||
command += link[:options ][:global].collect { |o| '-' + o } rescue []
|
||||
command += link[:options ][:cocoa ].collect { |o| '-' + o } rescue []
|
||||
command += link[:libraries ][:global].collect { |l| '-l ' + l } rescue []
|
||||
command += link[:libraries ][:cocoa ].collect { |l| '-l ' + l } rescue []
|
||||
command += link[:frameworks][:global].collect { |f| '-framework ' + f } rescue []
|
||||
command += link[:frameworks][:cocoa ].collect { |f| '-framework ' + f } rescue []
|
||||
command = command.join ' '
|
||||
|
||||
puts indent + command if verbose?
|
||||
|
||||
Open3.popen3(command) do |stdin, stdout, stderr|
|
||||
|
||||
stdout.readlines.each do |line|
|
||||
puts indent + line
|
||||
end
|
||||
|
||||
raise StandardError, 'Couldn\'t link!' unless stderr.readlines.each do |err|
|
||||
puts indent + err
|
||||
end.empty?
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
# Build App
|
||||
|
||||
desc 'Builds a Cocoa application bundle out of the linked files'
|
||||
|
||||
task :build_cocoa_app => :link do
|
||||
puts 'Building Application Bundle...'
|
||||
|
||||
Dir.mkdir(File.dirname(__FILE__) + '/build') rescue nil
|
||||
Dir.mkdir(File.dirname(__FILE__) + '/build/rake') rescue nil
|
||||
Dir.mkdir(File.dirname(__FILE__) + '/build/rake/DeSmuME.app') rescue nil
|
||||
Dir.mkdir(File.dirname(__FILE__) + '/build/rake/DeSmuME.app/Contents') rescue nil
|
||||
Dir.mkdir(File.dirname(__FILE__) + '/build/rake/DeSmuME.app/Contents/Resources') rescue nil
|
||||
|
||||
cp File.dirname(__FILE__) + '../..//Info.plist', File.dirname(__FILE__) + '/build/rake/DeSmuME.app/Contents/Resources/'
|
||||
cp File.dirname(__FILE__) + '/PkgInfo', File.dirname(__FILE__) + '/build/rake/DeSmuME.app/Contents/Resources/'
|
||||
cp File.dirname(__FILE__) + '/InfoPlist.strings', File.dirname(__FILE__) + '/build/rake/DeSmuME.app/Contents/Resources/'
|
||||
cp File.dirname(__FILE__) + '/DeSmuME.icns', File.dirname(__FILE__) + '/build/rake/DeSmuME.app/Contents/Resources/'
|
||||
system 'cp -r ' + File.dirname(__FILE__) + '/translations/*.lproj ' + File.dirname(__FILE__) + '/build/rake/DeSmuME.app/Contents/Resources/'
|
||||
end
|
||||
|
||||
|
||||
# Default Step
|
||||
|
||||
desc 'Makes the executable from scratch'
|
||||
|
||||
task :default => :build_cocoa_app do
|
||||
puts 'Finished!'
|
||||
end
|
||||
|
||||
# Run Task
|
||||
|
||||
desc 'Runs the executable if it exists'
|
||||
|
||||
task :run => :build_cocoa_app do
|
||||
puts 'Running...'
|
||||
system File.dirname(__FILE__) + '/build/rake/DeSmuME.app/Contents/MacOS/DeSmuME'
|
||||
puts File.dirname(__FILE__) + '/build/rake/DeSmuME.app/Contents/MacOS/DeSmuME'
|
||||
end
|
||||
|
||||
# Help
|
||||
|
||||
desc 'Displays helpful information about this Rakefile'
|
||||
|
||||
task :help do
|
||||
puts ""
|
||||
puts "Type rake to build the default task, which will make an executable"
|
||||
puts "Otherwise type rake [taskname] to execute a particular task"
|
||||
puts "Use rake -T to see what all the tasks are"
|
||||
puts ""
|
||||
puts "There are several parameters that you can pass:"
|
||||
puts "(but don't put spaces around the equal signs though)"
|
||||
puts " verbose = [true|false] print extra information (default is false)"
|
||||
puts ""
|
||||
end
|
||||
Executable
+194
@@ -0,0 +1,194 @@
|
||||
/*
|
||||
Copyright (C) 2013-2015 DeSmuME team
|
||||
|
||||
This file is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This file is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with the this software. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifdef __APPLE__
|
||||
#include <Availability.h>
|
||||
#include "utilities.h"
|
||||
#endif // __APPLE__
|
||||
|
||||
#include "audiosamplegenerator.h"
|
||||
#include <math.h>
|
||||
#include "cocoa_globals.h"
|
||||
|
||||
#define NUM_INTERNAL_NOISE_SAMPLES 32
|
||||
|
||||
static const uint8_t noiseSample[NUM_INTERNAL_NOISE_SAMPLES] =
|
||||
{
|
||||
0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF5, 0xFF, 0xFF, 0xFF, 0xFF, 0x8E, 0xFF,
|
||||
0xF4, 0xE1, 0xBF, 0x9A, 0x71, 0x58, 0x5B, 0x5F, 0x62, 0xC2, 0x25, 0x05, 0x01, 0x01, 0x01, 0x01
|
||||
};
|
||||
|
||||
size_t AudioGenerator::generateSampleBlock(size_t sampleCount, uint8_t *outBuffer)
|
||||
{
|
||||
if (outBuffer == NULL)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (uint8_t *i = outBuffer; i < outBuffer + sampleCount; i++)
|
||||
{
|
||||
*i = this->generateSample();
|
||||
}
|
||||
|
||||
return sampleCount;
|
||||
}
|
||||
|
||||
uint8_t AudioGenerator::generateSample()
|
||||
{
|
||||
return MIC_NULL_SAMPLE_VALUE;
|
||||
}
|
||||
|
||||
AudioSampleBlockGenerator::AudioSampleBlockGenerator(const uint8_t *audioBuffer, const size_t sampleCount)
|
||||
{
|
||||
_buffer = (uint8_t *)malloc(sampleCount * sizeof(uint8_t));
|
||||
_sampleCount = sampleCount;
|
||||
_samplePosition = 0;
|
||||
memcpy(_buffer, audioBuffer, _sampleCount * sizeof(uint8_t));
|
||||
}
|
||||
|
||||
AudioSampleBlockGenerator::~AudioSampleBlockGenerator()
|
||||
{
|
||||
free(this->_buffer);
|
||||
this->_buffer = NULL;
|
||||
}
|
||||
|
||||
uint8_t* AudioSampleBlockGenerator::allocate(const size_t sampleCount)
|
||||
{
|
||||
if (this->_buffer != NULL)
|
||||
{
|
||||
free(this->_buffer);
|
||||
}
|
||||
|
||||
this->_buffer = (uint8_t *)malloc(sampleCount * sizeof(uint8_t));
|
||||
this->_sampleCount = sampleCount;
|
||||
this->_samplePosition = 0;
|
||||
memset(this->_buffer, MIC_NULL_SAMPLE_VALUE, this->_sampleCount * sizeof(uint8_t));
|
||||
|
||||
return this->_buffer;
|
||||
}
|
||||
|
||||
uint8_t AudioSampleBlockGenerator::generateSample()
|
||||
{
|
||||
if (this->_samplePosition >= this->_sampleCount)
|
||||
{
|
||||
this->_samplePosition = 0;
|
||||
}
|
||||
|
||||
return this->_buffer[_samplePosition++];
|
||||
}
|
||||
|
||||
uint8_t* AudioSampleBlockGenerator::getBuffer() const
|
||||
{
|
||||
return this->_buffer;
|
||||
}
|
||||
|
||||
size_t AudioSampleBlockGenerator::getSampleCount() const
|
||||
{
|
||||
return this->_sampleCount;
|
||||
}
|
||||
|
||||
size_t AudioSampleBlockGenerator::getSamplePosition() const
|
||||
{
|
||||
return this->_samplePosition;
|
||||
}
|
||||
|
||||
void AudioSampleBlockGenerator::setSamplePosition(size_t thePosition)
|
||||
{
|
||||
this->_samplePosition = thePosition % this->_sampleCount;
|
||||
}
|
||||
|
||||
InternalNoiseGenerator::InternalNoiseGenerator()
|
||||
{
|
||||
_buffer = (uint8_t *)malloc(NUM_INTERNAL_NOISE_SAMPLES * sizeof(uint8_t));
|
||||
_sampleCount = NUM_INTERNAL_NOISE_SAMPLES;
|
||||
_samplePosition = 0;
|
||||
memcpy(_buffer, noiseSample, _sampleCount * sizeof(uint8_t));
|
||||
|
||||
for (size_t i = 0; i < NUM_INTERNAL_NOISE_SAMPLES; i++)
|
||||
{
|
||||
_buffer[i] >>= 1;
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t WhiteNoiseGenerator::generateSample()
|
||||
{
|
||||
#ifdef __APPLE__
|
||||
#ifdef MAC_OS_X_VERSION_10_7
|
||||
if (IsOSXVersionSupported(10, 7, 0))
|
||||
{
|
||||
return (uint8_t)(arc4random_uniform(0x00000080) & 0x7F);
|
||||
}
|
||||
return (uint8_t)((arc4random() % 0x00000080) & 0x7F);
|
||||
#else
|
||||
return (uint8_t)((arc4random() % 0x00000080) & 0x7F);
|
||||
#endif
|
||||
#else
|
||||
return (uint8_t)(rand() & 0x7F);
|
||||
#endif
|
||||
}
|
||||
|
||||
SineWaveGenerator::SineWaveGenerator()
|
||||
{
|
||||
_frequency = 250.0;
|
||||
_sampleRate = MIC_SAMPLE_RATE;
|
||||
_cyclePosition = 0.0;
|
||||
};
|
||||
|
||||
SineWaveGenerator::SineWaveGenerator(const double freq, const double sampleRate)
|
||||
{
|
||||
_frequency = freq;
|
||||
_sampleRate = sampleRate;
|
||||
_cyclePosition = 0.0;
|
||||
}
|
||||
|
||||
uint8_t SineWaveGenerator::generateSample()
|
||||
{
|
||||
const uint8_t sampleValue = (uint8_t)(63.0 * sin(2.0 * M_PI * this->_cyclePosition)) + MIC_NULL_SAMPLE_VALUE;
|
||||
this->_cyclePosition += (this->_frequency / this->_sampleRate);
|
||||
|
||||
return sampleValue;
|
||||
}
|
||||
|
||||
double SineWaveGenerator::getFrequency() const
|
||||
{
|
||||
return this->_frequency;
|
||||
}
|
||||
|
||||
void SineWaveGenerator::setFrequency(double freq)
|
||||
{
|
||||
this->_frequency = freq;
|
||||
}
|
||||
|
||||
double SineWaveGenerator::getSampleRate() const
|
||||
{
|
||||
return this->_sampleRate;
|
||||
}
|
||||
|
||||
void SineWaveGenerator::setSampleRate(double sampleRate)
|
||||
{
|
||||
this->_sampleRate = sampleRate;
|
||||
}
|
||||
|
||||
double SineWaveGenerator::getCyclePosition() const
|
||||
{
|
||||
return this->_cyclePosition;
|
||||
}
|
||||
|
||||
void SineWaveGenerator::setCyclePosition(double thePosition)
|
||||
{
|
||||
this->_cyclePosition = thePosition;
|
||||
}
|
||||
Executable
+94
@@ -0,0 +1,94 @@
|
||||
/*
|
||||
Copyright (C) 2013-2015 DeSmuME team
|
||||
|
||||
This file is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This file is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with the this software. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef _AUDIO_SAMPLE_GENERATOR_
|
||||
#define _AUDIO_SAMPLE_GENERATOR_
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
|
||||
class AudioGenerator
|
||||
{
|
||||
public:
|
||||
AudioGenerator() {};
|
||||
virtual ~AudioGenerator() {};
|
||||
|
||||
virtual size_t generateSampleBlock(size_t sampleCount, uint8_t *outBuffer);
|
||||
virtual uint8_t generateSample();
|
||||
};
|
||||
|
||||
class NullGenerator : public AudioGenerator {};
|
||||
|
||||
class AudioSampleBlockGenerator : public AudioGenerator
|
||||
{
|
||||
protected:
|
||||
uint8_t *_buffer;
|
||||
size_t _sampleCount;
|
||||
size_t _samplePosition;
|
||||
|
||||
public:
|
||||
AudioSampleBlockGenerator()
|
||||
: _buffer(NULL)
|
||||
, _sampleCount(0)
|
||||
, _samplePosition(0)
|
||||
{};
|
||||
AudioSampleBlockGenerator(const uint8_t *audioBuffer, const size_t sampleCount);
|
||||
~AudioSampleBlockGenerator();
|
||||
|
||||
uint8_t* allocate(const size_t sampleCount);
|
||||
uint8_t* getBuffer() const;
|
||||
size_t getSampleCount() const;
|
||||
size_t getSamplePosition() const;
|
||||
void setSamplePosition(size_t thePosition);
|
||||
|
||||
virtual uint8_t generateSample();
|
||||
};
|
||||
|
||||
class InternalNoiseGenerator : public AudioSampleBlockGenerator
|
||||
{
|
||||
public:
|
||||
InternalNoiseGenerator();
|
||||
};
|
||||
|
||||
class WhiteNoiseGenerator : public AudioGenerator
|
||||
{
|
||||
public:
|
||||
virtual uint8_t generateSample();
|
||||
};
|
||||
|
||||
class SineWaveGenerator : public AudioGenerator
|
||||
{
|
||||
protected:
|
||||
double _frequency;
|
||||
double _sampleRate;
|
||||
double _cyclePosition;
|
||||
|
||||
public:
|
||||
SineWaveGenerator();
|
||||
SineWaveGenerator(const double freq, const double sampleRate);
|
||||
|
||||
double getFrequency() const;
|
||||
void setFrequency(double freq);
|
||||
double getSampleRate() const;
|
||||
void setSampleRate(double sampleRate);
|
||||
double getCyclePosition() const;
|
||||
void setCyclePosition(double thePosition);
|
||||
|
||||
virtual uint8_t generateSample();
|
||||
};
|
||||
|
||||
#endif // _AUDIO_SAMPLE_GENERATOR_
|
||||
Executable
+33
@@ -0,0 +1,33 @@
|
||||
# Copyright 2006 Guillaume Duhamel
|
||||
# Copyright 2006 Lawrence Sebald
|
||||
# Copyright 2007 Anders Montonen
|
||||
#
|
||||
# This file is part of Yabause.
|
||||
#
|
||||
# Yabause 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.
|
||||
#
|
||||
# Yabause 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 Yabause; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
|
||||
hdiutil create -megabytes 20 tmp.dmg -layout NONE -fs HFS+ -volname DeSmuME -ov
|
||||
tmp=`hdid tmp.dmg`
|
||||
disk=`echo $tmp | cut -f 1 -d\ `
|
||||
cp -R build/Release/DeSmuME.app /Volumes/DeSmuME/
|
||||
cp ../../ChangeLog /Volumes/DeSmuME/
|
||||
cp ../../README /Volumes/DeSmuME/
|
||||
cp ../../README.MAC /Volumes/DeSmuME/
|
||||
cp ../../AUTHORS /Volumes/DeSmuME/
|
||||
cp ../../COPYING /Volumes/DeSmuME/
|
||||
hdiutil eject $disk
|
||||
hdiutil convert -format UDZO tmp.dmg -o DeSmuME.dmg
|
||||
rm tmp.dmg
|
||||
Executable
+92
@@ -0,0 +1,92 @@
|
||||
/*
|
||||
Copyright (C) 2013-2015 DeSmuME team
|
||||
|
||||
This file is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This file is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with the this software. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#include <pthread.h>
|
||||
#include <libkern/OSAtomic.h>
|
||||
|
||||
|
||||
@interface CocoaDSGPU : NSObject
|
||||
{
|
||||
UInt32 gpuStateFlags;
|
||||
BOOL isCPUCoreCountAuto;
|
||||
|
||||
OSSpinLock spinlockGpuState;
|
||||
pthread_rwlock_t *rwlockProducer;
|
||||
}
|
||||
|
||||
@property (assign) UInt32 gpuStateFlags;
|
||||
@property (assign) pthread_rwlock_t *rwlockProducer;
|
||||
|
||||
@property (assign) BOOL layerMainGPU;
|
||||
@property (assign) BOOL layerMainBG0;
|
||||
@property (assign) BOOL layerMainBG1;
|
||||
@property (assign) BOOL layerMainBG2;
|
||||
@property (assign) BOOL layerMainBG3;
|
||||
@property (assign) BOOL layerMainOBJ;
|
||||
@property (assign) BOOL layerSubGPU;
|
||||
@property (assign) BOOL layerSubBG0;
|
||||
@property (assign) BOOL layerSubBG1;
|
||||
@property (assign) BOOL layerSubBG2;
|
||||
@property (assign) BOOL layerSubBG3;
|
||||
@property (assign) BOOL layerSubOBJ;
|
||||
|
||||
@property (assign) NSInteger render3DRenderingEngine;
|
||||
@property (assign) BOOL render3DHighPrecisionColorInterpolation;
|
||||
@property (assign) BOOL render3DEdgeMarking;
|
||||
@property (assign) BOOL render3DFog;
|
||||
@property (assign) BOOL render3DTextures;
|
||||
@property (assign) NSUInteger render3DDepthComparisonThreshold;
|
||||
@property (assign) NSUInteger render3DThreads;
|
||||
@property (assign) BOOL render3DLineHack;
|
||||
@property (assign) BOOL render3DMultisample;
|
||||
@property (assign) BOOL render3DFragmentSamplingHack;
|
||||
|
||||
- (BOOL) gpuStateByBit:(const UInt32)stateBit;
|
||||
- (BOOL) isGPUTypeDisplayed:(const NSInteger)theGpuType;
|
||||
- (void) hideGPUType:(const NSInteger)theGpuType;
|
||||
- (void) showGPUType:(const NSInteger)theGpuType;
|
||||
|
||||
- (NSString *) render3DRenderingEngineString;
|
||||
|
||||
@end
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
void GPU_FillScreenWithBGRA5551(const uint16_t colorValue);
|
||||
void SetGPULayerState(const int gpuType, const unsigned int i, const bool state);
|
||||
bool GetGPULayerState(const int gpuType, const unsigned int i);
|
||||
void SetGPUDisplayState(const int gpuType, const bool state);
|
||||
bool GetGPUDisplayState(const int gpuType);
|
||||
|
||||
bool OSXOpenGLRendererInit();
|
||||
bool OSXOpenGLRendererBegin();
|
||||
void OSXOpenGLRendererEnd();
|
||||
|
||||
bool CreateOpenGLRenderer();
|
||||
void DestroyOpenGLRenderer();
|
||||
void RequestOpenGLRenderer_3_2(bool request_3_2);
|
||||
void SetOpenGLRendererFunctions(bool (*initFunction)(),
|
||||
bool (*beginOGLFunction)(),
|
||||
void (*endOGLFunction)());
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
Executable
+979
@@ -0,0 +1,979 @@
|
||||
/*
|
||||
Copyright (C) 2013-2015 DeSmuME team
|
||||
|
||||
This file is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This file is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with the this software. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#import "cocoa_GPU.h"
|
||||
#import "cocoa_globals.h"
|
||||
#include "utilities.h"
|
||||
|
||||
#include "../NDSSystem.h"
|
||||
#include "../GPU.h"
|
||||
#include "../rasterize.h"
|
||||
|
||||
#ifdef MAC_OS_X_VERSION_10_7
|
||||
#include "../OGLRender_3_2.h"
|
||||
#else
|
||||
#include "../OGLRender.h"
|
||||
#endif
|
||||
|
||||
#include <OpenGL/OpenGL.h>
|
||||
|
||||
#undef BOOL
|
||||
|
||||
GPU3DInterface *core3DList[] = {
|
||||
&gpu3DNull,
|
||||
&gpu3DRasterize,
|
||||
&gpu3Dgl,
|
||||
NULL
|
||||
};
|
||||
|
||||
@implementation CocoaDSGPU
|
||||
|
||||
@dynamic gpuStateFlags;
|
||||
@synthesize rwlockProducer;
|
||||
|
||||
@dynamic layerMainGPU;
|
||||
@dynamic layerMainBG0;
|
||||
@dynamic layerMainBG1;
|
||||
@dynamic layerMainBG2;
|
||||
@dynamic layerMainBG3;
|
||||
@dynamic layerMainOBJ;
|
||||
@dynamic layerSubGPU;
|
||||
@dynamic layerSubBG0;
|
||||
@dynamic layerSubBG1;
|
||||
@dynamic layerSubBG2;
|
||||
@dynamic layerSubBG3;
|
||||
@dynamic layerSubOBJ;
|
||||
|
||||
@dynamic render3DRenderingEngine;
|
||||
@dynamic render3DHighPrecisionColorInterpolation;
|
||||
@dynamic render3DEdgeMarking;
|
||||
@dynamic render3DFog;
|
||||
@dynamic render3DTextures;
|
||||
@dynamic render3DDepthComparisonThreshold;
|
||||
@dynamic render3DThreads;
|
||||
@dynamic render3DLineHack;
|
||||
@dynamic render3DMultisample;
|
||||
@dynamic render3DFragmentSamplingHack;
|
||||
|
||||
|
||||
- (id)init
|
||||
{
|
||||
self = [super init];
|
||||
if (self == nil)
|
||||
{
|
||||
return self;
|
||||
}
|
||||
|
||||
spinlockGpuState = OS_SPINLOCK_INIT;
|
||||
rwlockProducer = NULL;
|
||||
|
||||
gpuStateFlags = GPUSTATE_MAIN_GPU_MASK |
|
||||
GPUSTATE_MAIN_BG0_MASK |
|
||||
GPUSTATE_MAIN_BG1_MASK |
|
||||
GPUSTATE_MAIN_BG2_MASK |
|
||||
GPUSTATE_MAIN_BG3_MASK |
|
||||
GPUSTATE_MAIN_OBJ_MASK |
|
||||
GPUSTATE_SUB_GPU_MASK |
|
||||
GPUSTATE_SUB_BG0_MASK |
|
||||
GPUSTATE_SUB_BG1_MASK |
|
||||
GPUSTATE_SUB_BG2_MASK |
|
||||
GPUSTATE_SUB_BG3_MASK |
|
||||
GPUSTATE_SUB_OBJ_MASK;
|
||||
|
||||
isCPUCoreCountAuto = NO;
|
||||
|
||||
SetOpenGLRendererFunctions(&OSXOpenGLRendererInit,
|
||||
&OSXOpenGLRendererBegin,
|
||||
&OSXOpenGLRendererEnd);
|
||||
|
||||
GPU_FillScreenWithBGRA5551(0x8000);
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
NDS_3D_ChangeCore(CORE3DLIST_NULL);
|
||||
DestroyOpenGLRenderer();
|
||||
}
|
||||
|
||||
- (void) setGpuStateFlags:(UInt32)flags
|
||||
{
|
||||
OSSpinLockLock(&spinlockGpuState);
|
||||
gpuStateFlags = flags;
|
||||
OSSpinLockUnlock(&spinlockGpuState);
|
||||
|
||||
[self setLayerMainGPU:((flags & GPUSTATE_MAIN_GPU_MASK) != 0)];
|
||||
[self setLayerMainBG0:((flags & GPUSTATE_MAIN_BG0_MASK) != 0)];
|
||||
[self setLayerMainBG1:((flags & GPUSTATE_MAIN_BG1_MASK) != 0)];
|
||||
[self setLayerMainBG2:((flags & GPUSTATE_MAIN_BG2_MASK) != 0)];
|
||||
[self setLayerMainBG3:((flags & GPUSTATE_MAIN_BG3_MASK) != 0)];
|
||||
[self setLayerMainOBJ:((flags & GPUSTATE_MAIN_OBJ_MASK) != 0)];
|
||||
|
||||
[self setLayerSubGPU:((flags & GPUSTATE_SUB_GPU_MASK) != 0)];
|
||||
[self setLayerSubBG0:((flags & GPUSTATE_SUB_BG0_MASK) != 0)];
|
||||
[self setLayerSubBG1:((flags & GPUSTATE_SUB_BG1_MASK) != 0)];
|
||||
[self setLayerSubBG2:((flags & GPUSTATE_SUB_BG2_MASK) != 0)];
|
||||
[self setLayerSubBG3:((flags & GPUSTATE_SUB_BG3_MASK) != 0)];
|
||||
[self setLayerSubOBJ:((flags & GPUSTATE_SUB_OBJ_MASK) != 0)];
|
||||
}
|
||||
|
||||
- (UInt32) gpuStateFlags
|
||||
{
|
||||
OSSpinLockLock(&spinlockGpuState);
|
||||
const UInt32 flags = gpuStateFlags;
|
||||
OSSpinLockUnlock(&spinlockGpuState);
|
||||
|
||||
return flags;
|
||||
}
|
||||
|
||||
- (void) setRender3DRenderingEngine:(NSInteger)methodID
|
||||
{
|
||||
pthread_rwlock_wrlock(self.rwlockProducer);
|
||||
NDS_3D_ChangeCore(methodID);
|
||||
pthread_rwlock_unlock(self.rwlockProducer);
|
||||
}
|
||||
|
||||
- (NSInteger) render3DRenderingEngine
|
||||
{
|
||||
pthread_rwlock_rdlock(self.rwlockProducer);
|
||||
const NSInteger methodID = (NSInteger)cur3DCore;
|
||||
pthread_rwlock_unlock(self.rwlockProducer);
|
||||
|
||||
return methodID;
|
||||
}
|
||||
|
||||
- (void) setRender3DHighPrecisionColorInterpolation:(BOOL)state
|
||||
{
|
||||
pthread_rwlock_wrlock(self.rwlockProducer);
|
||||
CommonSettings.GFX3D_HighResolutionInterpolateColor = state ? true : false;
|
||||
pthread_rwlock_unlock(self.rwlockProducer);
|
||||
}
|
||||
|
||||
- (BOOL) render3DHighPrecisionColorInterpolation
|
||||
{
|
||||
pthread_rwlock_rdlock(self.rwlockProducer);
|
||||
const BOOL state = CommonSettings.GFX3D_HighResolutionInterpolateColor ? YES : NO;
|
||||
pthread_rwlock_unlock(self.rwlockProducer);
|
||||
|
||||
return state;
|
||||
}
|
||||
|
||||
- (void) setRender3DEdgeMarking:(BOOL)state
|
||||
{
|
||||
pthread_rwlock_wrlock(self.rwlockProducer);
|
||||
CommonSettings.GFX3D_EdgeMark = state ? true : false;
|
||||
pthread_rwlock_unlock(self.rwlockProducer);
|
||||
}
|
||||
|
||||
- (BOOL) render3DEdgeMarking
|
||||
{
|
||||
pthread_rwlock_rdlock(self.rwlockProducer);
|
||||
const BOOL state = CommonSettings.GFX3D_EdgeMark ? YES : NO;
|
||||
pthread_rwlock_unlock(self.rwlockProducer);
|
||||
|
||||
return state;
|
||||
}
|
||||
|
||||
- (void) setRender3DFog:(BOOL)state
|
||||
{
|
||||
pthread_rwlock_wrlock(self.rwlockProducer);
|
||||
CommonSettings.GFX3D_Fog = state ? true : false;
|
||||
pthread_rwlock_unlock(self.rwlockProducer);
|
||||
}
|
||||
|
||||
- (BOOL) render3DFog
|
||||
{
|
||||
pthread_rwlock_rdlock(self.rwlockProducer);
|
||||
const BOOL state = CommonSettings.GFX3D_Fog ? YES : NO;
|
||||
pthread_rwlock_unlock(self.rwlockProducer);
|
||||
|
||||
return state;
|
||||
}
|
||||
|
||||
- (void) setRender3DTextures:(BOOL)state
|
||||
{
|
||||
pthread_rwlock_wrlock(self.rwlockProducer);
|
||||
CommonSettings.GFX3D_Texture = state ? true : false;
|
||||
pthread_rwlock_unlock(self.rwlockProducer);
|
||||
}
|
||||
|
||||
- (BOOL) render3DTextures
|
||||
{
|
||||
pthread_rwlock_rdlock(self.rwlockProducer);
|
||||
const BOOL state = CommonSettings.GFX3D_Texture ? YES : NO;
|
||||
pthread_rwlock_unlock(self.rwlockProducer);
|
||||
|
||||
return state;
|
||||
}
|
||||
|
||||
- (void) setRender3DDepthComparisonThreshold:(NSUInteger)threshold
|
||||
{
|
||||
pthread_rwlock_wrlock(self.rwlockProducer);
|
||||
CommonSettings.GFX3D_Zelda_Shadow_Depth_Hack = threshold;
|
||||
pthread_rwlock_unlock(self.rwlockProducer);
|
||||
}
|
||||
|
||||
- (NSUInteger) render3DDepthComparisonThreshold
|
||||
{
|
||||
pthread_rwlock_rdlock(self.rwlockProducer);
|
||||
const NSUInteger threshold = (NSUInteger)CommonSettings.GFX3D_Zelda_Shadow_Depth_Hack;
|
||||
pthread_rwlock_unlock(self.rwlockProducer);
|
||||
|
||||
return threshold;
|
||||
}
|
||||
|
||||
- (void) setRender3DThreads:(NSUInteger)numberThreads
|
||||
{
|
||||
NSUInteger numberCores = [[NSProcessInfo processInfo] activeProcessorCount];
|
||||
if (numberThreads == 0)
|
||||
{
|
||||
isCPUCoreCountAuto = YES;
|
||||
|
||||
if (numberCores >= 8)
|
||||
{
|
||||
numberCores = 8;
|
||||
}
|
||||
else if (numberCores >= 4)
|
||||
{
|
||||
numberCores = 4;
|
||||
}
|
||||
else if (numberCores >= 2)
|
||||
{
|
||||
numberCores = 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
numberCores = 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
isCPUCoreCountAuto = NO;
|
||||
numberCores = numberThreads;
|
||||
}
|
||||
|
||||
const NSInteger renderingEngineID = [self render3DRenderingEngine];
|
||||
|
||||
pthread_rwlock_wrlock(self.rwlockProducer);
|
||||
|
||||
CommonSettings.num_cores = numberCores;
|
||||
|
||||
if (renderingEngineID == CORE3DLIST_SWRASTERIZE || renderingEngineID == CORE3DLIST_OPENGL)
|
||||
{
|
||||
NDS_3D_ChangeCore(renderingEngineID);
|
||||
}
|
||||
|
||||
pthread_rwlock_unlock(self.rwlockProducer);
|
||||
}
|
||||
|
||||
- (NSUInteger) render3DThreads
|
||||
{
|
||||
pthread_rwlock_rdlock(self.rwlockProducer);
|
||||
const NSUInteger numberThreads = isCPUCoreCountAuto ? 0 : (NSUInteger)CommonSettings.num_cores;
|
||||
pthread_rwlock_unlock(self.rwlockProducer);
|
||||
|
||||
return numberThreads;
|
||||
}
|
||||
|
||||
- (void) setRender3DLineHack:(BOOL)state
|
||||
{
|
||||
pthread_rwlock_wrlock(self.rwlockProducer);
|
||||
CommonSettings.GFX3D_LineHack = state ? true : false;
|
||||
pthread_rwlock_unlock(self.rwlockProducer);
|
||||
}
|
||||
|
||||
- (BOOL) render3DLineHack
|
||||
{
|
||||
pthread_rwlock_rdlock(self.rwlockProducer);
|
||||
const BOOL state = CommonSettings.GFX3D_LineHack ? YES : NO;
|
||||
pthread_rwlock_unlock(self.rwlockProducer);
|
||||
|
||||
return state;
|
||||
}
|
||||
|
||||
- (void) setRender3DMultisample:(BOOL)state
|
||||
{
|
||||
pthread_rwlock_wrlock(self.rwlockProducer);
|
||||
CommonSettings.GFX3D_Renderer_Multisample = state ? true : false;
|
||||
pthread_rwlock_unlock(self.rwlockProducer);
|
||||
}
|
||||
|
||||
- (BOOL) render3DMultisample
|
||||
{
|
||||
pthread_rwlock_rdlock(self.rwlockProducer);
|
||||
const BOOL state = CommonSettings.GFX3D_Renderer_Multisample ? YES : NO;
|
||||
pthread_rwlock_unlock(self.rwlockProducer);
|
||||
|
||||
return state;
|
||||
}
|
||||
|
||||
- (void) setRender3DFragmentSamplingHack:(BOOL)state
|
||||
{
|
||||
pthread_rwlock_wrlock(self.rwlockProducer);
|
||||
CommonSettings.GFX3D_TXTHack = state ? true : false;
|
||||
pthread_rwlock_unlock(self.rwlockProducer);
|
||||
}
|
||||
|
||||
- (BOOL) render3DFragmentSamplingHack
|
||||
{
|
||||
pthread_rwlock_rdlock(self.rwlockProducer);
|
||||
const BOOL state = CommonSettings.GFX3D_TXTHack ? YES : NO;
|
||||
pthread_rwlock_unlock(self.rwlockProducer);
|
||||
|
||||
return state;
|
||||
}
|
||||
|
||||
- (void) setLayerMainGPU:(BOOL)gpuState
|
||||
{
|
||||
pthread_rwlock_wrlock(self.rwlockProducer);
|
||||
SetGPUDisplayState(DS_GPU_TYPE_MAIN, (gpuState) ? true : false);
|
||||
pthread_rwlock_unlock(self.rwlockProducer);
|
||||
|
||||
OSSpinLockLock(&spinlockGpuState);
|
||||
gpuStateFlags = (gpuState) ? (gpuStateFlags | GPUSTATE_MAIN_GPU_MASK) : (gpuStateFlags & ~GPUSTATE_MAIN_GPU_MASK);
|
||||
OSSpinLockUnlock(&spinlockGpuState);
|
||||
}
|
||||
|
||||
- (BOOL) layerMainGPU
|
||||
{
|
||||
pthread_rwlock_rdlock(self.rwlockProducer);
|
||||
const BOOL gpuState = GetGPUDisplayState(DS_GPU_TYPE_MAIN) ? YES : NO;
|
||||
pthread_rwlock_unlock(self.rwlockProducer);
|
||||
|
||||
return gpuState;
|
||||
}
|
||||
|
||||
- (void) setLayerMainBG0:(BOOL)layerState
|
||||
{
|
||||
pthread_rwlock_wrlock(self.rwlockProducer);
|
||||
SetGPULayerState(DS_GPU_TYPE_MAIN, 0, (layerState) ? true : false);
|
||||
pthread_rwlock_unlock(self.rwlockProducer);
|
||||
|
||||
OSSpinLockLock(&spinlockGpuState);
|
||||
gpuStateFlags = (layerState) ? (gpuStateFlags | GPUSTATE_MAIN_BG0_MASK) : (gpuStateFlags & ~GPUSTATE_MAIN_BG0_MASK);
|
||||
OSSpinLockUnlock(&spinlockGpuState);
|
||||
}
|
||||
|
||||
- (BOOL) layerMainBG0
|
||||
{
|
||||
pthread_rwlock_rdlock(self.rwlockProducer);
|
||||
const BOOL layerState = GetGPULayerState(DS_GPU_TYPE_MAIN, 0) ? YES : NO;
|
||||
pthread_rwlock_unlock(self.rwlockProducer);
|
||||
|
||||
return layerState;
|
||||
}
|
||||
|
||||
- (void) setLayerMainBG1:(BOOL)layerState
|
||||
{
|
||||
pthread_rwlock_wrlock(self.rwlockProducer);
|
||||
SetGPULayerState(DS_GPU_TYPE_MAIN, 1, (layerState) ? true : false);
|
||||
pthread_rwlock_unlock(self.rwlockProducer);
|
||||
|
||||
OSSpinLockLock(&spinlockGpuState);
|
||||
gpuStateFlags = (layerState) ? (gpuStateFlags | GPUSTATE_MAIN_BG1_MASK) : (gpuStateFlags & ~GPUSTATE_MAIN_BG1_MASK);
|
||||
OSSpinLockUnlock(&spinlockGpuState);
|
||||
}
|
||||
|
||||
- (BOOL) layerMainBG1
|
||||
{
|
||||
pthread_rwlock_rdlock(self.rwlockProducer);
|
||||
const BOOL layerState = GetGPULayerState(DS_GPU_TYPE_MAIN, 1) ? YES : NO;
|
||||
pthread_rwlock_unlock(self.rwlockProducer);
|
||||
|
||||
return layerState;
|
||||
}
|
||||
|
||||
- (void) setLayerMainBG2:(BOOL)layerState
|
||||
{
|
||||
pthread_rwlock_wrlock(self.rwlockProducer);
|
||||
SetGPULayerState(DS_GPU_TYPE_MAIN, 2, (layerState) ? true : false);
|
||||
pthread_rwlock_unlock(self.rwlockProducer);
|
||||
|
||||
OSSpinLockLock(&spinlockGpuState);
|
||||
gpuStateFlags = (layerState) ? (gpuStateFlags | GPUSTATE_MAIN_BG2_MASK) : (gpuStateFlags & ~GPUSTATE_MAIN_BG2_MASK);
|
||||
OSSpinLockUnlock(&spinlockGpuState);
|
||||
}
|
||||
|
||||
- (BOOL) layerMainBG2
|
||||
{
|
||||
pthread_rwlock_rdlock(self.rwlockProducer);
|
||||
const BOOL layerState = GetGPULayerState(DS_GPU_TYPE_MAIN, 2) ? YES : NO;
|
||||
pthread_rwlock_unlock(self.rwlockProducer);
|
||||
|
||||
return layerState;
|
||||
}
|
||||
|
||||
- (void) setLayerMainBG3:(BOOL)layerState
|
||||
{
|
||||
pthread_rwlock_wrlock(self.rwlockProducer);
|
||||
SetGPULayerState(DS_GPU_TYPE_MAIN, 3, (layerState) ? true : false);
|
||||
pthread_rwlock_unlock(self.rwlockProducer);
|
||||
|
||||
OSSpinLockLock(&spinlockGpuState);
|
||||
gpuStateFlags = (layerState) ? (gpuStateFlags | GPUSTATE_MAIN_BG3_MASK) : (gpuStateFlags & ~GPUSTATE_MAIN_BG3_MASK);
|
||||
OSSpinLockUnlock(&spinlockGpuState);
|
||||
}
|
||||
|
||||
- (BOOL) layerMainBG3
|
||||
{
|
||||
pthread_rwlock_rdlock(self.rwlockProducer);
|
||||
const BOOL layerState = GetGPULayerState(DS_GPU_TYPE_MAIN, 3) ? YES : NO;
|
||||
pthread_rwlock_unlock(self.rwlockProducer);
|
||||
|
||||
return layerState;
|
||||
}
|
||||
|
||||
- (void) setLayerMainOBJ:(BOOL)layerState
|
||||
{
|
||||
pthread_rwlock_wrlock(self.rwlockProducer);
|
||||
SetGPULayerState(DS_GPU_TYPE_MAIN, 4, (layerState) ? true : false);
|
||||
pthread_rwlock_unlock(self.rwlockProducer);
|
||||
|
||||
OSSpinLockLock(&spinlockGpuState);
|
||||
gpuStateFlags = (layerState) ? (gpuStateFlags | GPUSTATE_MAIN_OBJ_MASK) : (gpuStateFlags & ~GPUSTATE_MAIN_OBJ_MASK);
|
||||
OSSpinLockUnlock(&spinlockGpuState);
|
||||
}
|
||||
|
||||
- (BOOL) layerMainOBJ
|
||||
{
|
||||
pthread_rwlock_rdlock(self.rwlockProducer);
|
||||
const BOOL layerState = GetGPULayerState(DS_GPU_TYPE_MAIN, 4) ? YES : NO;
|
||||
pthread_rwlock_unlock(self.rwlockProducer);
|
||||
|
||||
return layerState;
|
||||
}
|
||||
|
||||
- (void) setLayerSubGPU:(BOOL)gpuState
|
||||
{
|
||||
pthread_rwlock_wrlock(self.rwlockProducer);
|
||||
SetGPUDisplayState(DS_GPU_TYPE_SUB, (gpuState) ? true : false);
|
||||
pthread_rwlock_unlock(self.rwlockProducer);
|
||||
|
||||
OSSpinLockLock(&spinlockGpuState);
|
||||
gpuStateFlags = (gpuState) ? (gpuStateFlags | GPUSTATE_SUB_GPU_MASK) : (gpuStateFlags & ~GPUSTATE_SUB_GPU_MASK);
|
||||
OSSpinLockUnlock(&spinlockGpuState);
|
||||
}
|
||||
|
||||
- (BOOL) layerSubGPU
|
||||
{
|
||||
pthread_rwlock_rdlock(self.rwlockProducer);
|
||||
const BOOL gpuState = GetGPUDisplayState(DS_GPU_TYPE_SUB) ? YES : NO;
|
||||
pthread_rwlock_unlock(self.rwlockProducer);
|
||||
|
||||
return gpuState;
|
||||
}
|
||||
|
||||
- (void) setLayerSubBG0:(BOOL)layerState
|
||||
{
|
||||
pthread_rwlock_wrlock(self.rwlockProducer);
|
||||
SetGPULayerState(DS_GPU_TYPE_SUB, 0, (layerState) ? true : false);
|
||||
pthread_rwlock_unlock(self.rwlockProducer);
|
||||
|
||||
OSSpinLockLock(&spinlockGpuState);
|
||||
gpuStateFlags = (layerState) ? (gpuStateFlags | GPUSTATE_SUB_BG0_MASK) : (gpuStateFlags & ~GPUSTATE_SUB_BG0_MASK);
|
||||
OSSpinLockUnlock(&spinlockGpuState);
|
||||
}
|
||||
|
||||
- (BOOL) layerSubBG0
|
||||
{
|
||||
pthread_rwlock_rdlock(self.rwlockProducer);
|
||||
const BOOL layerState = GetGPULayerState(DS_GPU_TYPE_SUB, 0) ? YES : NO;
|
||||
pthread_rwlock_unlock(self.rwlockProducer);
|
||||
|
||||
return layerState;
|
||||
}
|
||||
|
||||
- (void) setLayerSubBG1:(BOOL)layerState
|
||||
{
|
||||
pthread_rwlock_wrlock(self.rwlockProducer);
|
||||
SetGPULayerState(DS_GPU_TYPE_SUB, 1, (layerState) ? true : false);
|
||||
pthread_rwlock_unlock(self.rwlockProducer);
|
||||
|
||||
OSSpinLockLock(&spinlockGpuState);
|
||||
gpuStateFlags = (layerState) ? (gpuStateFlags | GPUSTATE_SUB_BG1_MASK) : (gpuStateFlags & ~GPUSTATE_SUB_BG1_MASK);
|
||||
OSSpinLockUnlock(&spinlockGpuState);
|
||||
}
|
||||
|
||||
- (BOOL) layerSubBG1
|
||||
{
|
||||
pthread_rwlock_rdlock(self.rwlockProducer);
|
||||
const BOOL layerState = GetGPULayerState(DS_GPU_TYPE_SUB, 1) ? YES : NO;
|
||||
pthread_rwlock_unlock(self.rwlockProducer);
|
||||
|
||||
return layerState;
|
||||
}
|
||||
|
||||
- (void) setLayerSubBG2:(BOOL)layerState
|
||||
{
|
||||
pthread_rwlock_wrlock(self.rwlockProducer);
|
||||
SetGPULayerState(DS_GPU_TYPE_SUB, 2, (layerState) ? true : false);
|
||||
pthread_rwlock_unlock(self.rwlockProducer);
|
||||
|
||||
OSSpinLockLock(&spinlockGpuState);
|
||||
gpuStateFlags = (layerState) ? (gpuStateFlags | GPUSTATE_SUB_BG2_MASK) : (gpuStateFlags & ~GPUSTATE_SUB_BG2_MASK);
|
||||
OSSpinLockUnlock(&spinlockGpuState);
|
||||
}
|
||||
|
||||
- (BOOL) layerSubBG2
|
||||
{
|
||||
pthread_rwlock_rdlock(self.rwlockProducer);
|
||||
const BOOL layerState = GetGPULayerState(DS_GPU_TYPE_SUB, 2) ? YES : NO;
|
||||
pthread_rwlock_unlock(self.rwlockProducer);
|
||||
|
||||
return layerState;
|
||||
}
|
||||
|
||||
- (void) setLayerSubBG3:(BOOL)layerState
|
||||
{
|
||||
pthread_rwlock_wrlock(self.rwlockProducer);
|
||||
SetGPULayerState(DS_GPU_TYPE_SUB, 3, (layerState) ? true : false);
|
||||
pthread_rwlock_unlock(self.rwlockProducer);
|
||||
|
||||
OSSpinLockLock(&spinlockGpuState);
|
||||
gpuStateFlags = (layerState) ? (gpuStateFlags | GPUSTATE_SUB_BG3_MASK) : (gpuStateFlags & ~GPUSTATE_SUB_BG3_MASK);
|
||||
OSSpinLockUnlock(&spinlockGpuState);
|
||||
}
|
||||
|
||||
- (BOOL) layerSubBG3
|
||||
{
|
||||
pthread_rwlock_rdlock(self.rwlockProducer);
|
||||
const BOOL layerState = GetGPULayerState(DS_GPU_TYPE_SUB, 3) ? YES : NO;
|
||||
pthread_rwlock_unlock(self.rwlockProducer);
|
||||
|
||||
return layerState;
|
||||
}
|
||||
|
||||
- (void) setLayerSubOBJ:(BOOL)layerState
|
||||
{
|
||||
pthread_rwlock_wrlock(self.rwlockProducer);
|
||||
SetGPULayerState(DS_GPU_TYPE_SUB, 4, (layerState) ? true : false);
|
||||
pthread_rwlock_unlock(self.rwlockProducer);
|
||||
|
||||
OSSpinLockLock(&spinlockGpuState);
|
||||
gpuStateFlags = (layerState) ? (gpuStateFlags | GPUSTATE_SUB_OBJ_MASK) : (gpuStateFlags & ~GPUSTATE_SUB_OBJ_MASK);
|
||||
OSSpinLockUnlock(&spinlockGpuState);
|
||||
}
|
||||
|
||||
- (BOOL) layerSubOBJ
|
||||
{
|
||||
pthread_rwlock_rdlock(self.rwlockProducer);
|
||||
const BOOL layerState = GetGPULayerState(DS_GPU_TYPE_SUB, 4) ? YES : NO;
|
||||
pthread_rwlock_unlock(self.rwlockProducer);
|
||||
|
||||
return layerState;
|
||||
}
|
||||
|
||||
- (BOOL) gpuStateByBit:(const UInt32)stateBit
|
||||
{
|
||||
return ([self gpuStateFlags] & (1 << stateBit)) ? YES : NO;
|
||||
}
|
||||
|
||||
- (BOOL) isGPUTypeDisplayed:(const NSInteger)theGpuType
|
||||
{
|
||||
BOOL result = NO;
|
||||
const UInt32 flags = [self gpuStateFlags];
|
||||
|
||||
switch (theGpuType)
|
||||
{
|
||||
case DS_GPU_TYPE_MAIN:
|
||||
if (flags & GPUSTATE_MAIN_GPU_MASK)
|
||||
{
|
||||
result = YES;
|
||||
}
|
||||
break;
|
||||
|
||||
case DS_GPU_TYPE_SUB:
|
||||
if (flags & GPUSTATE_SUB_GPU_MASK)
|
||||
{
|
||||
result = YES;
|
||||
}
|
||||
break;
|
||||
|
||||
case DS_GPU_TYPE_MAIN_AND_SUB:
|
||||
if (flags & (GPUSTATE_MAIN_GPU_MASK | GPUSTATE_SUB_GPU_MASK))
|
||||
{
|
||||
result = YES;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
- (void) hideGPUType:(const NSInteger)theGpuType
|
||||
{
|
||||
UInt32 flags = [self gpuStateFlags];
|
||||
|
||||
switch (theGpuType)
|
||||
{
|
||||
case DS_GPU_TYPE_MAIN:
|
||||
flags &= ~GPUSTATE_MAIN_GPU_MASK;
|
||||
break;
|
||||
|
||||
case DS_GPU_TYPE_SUB:
|
||||
flags &= ~GPUSTATE_SUB_GPU_MASK;
|
||||
break;
|
||||
|
||||
case DS_GPU_TYPE_MAIN_AND_SUB:
|
||||
flags &= ~GPUSTATE_MAIN_GPU_MASK;
|
||||
flags &= ~GPUSTATE_SUB_GPU_MASK;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
[self setGpuStateFlags:flags];
|
||||
}
|
||||
|
||||
- (void) showGPUType:(const NSInteger)theGpuType
|
||||
{
|
||||
UInt32 flags = [self gpuStateFlags];
|
||||
|
||||
switch (theGpuType)
|
||||
{
|
||||
case DS_GPU_TYPE_MAIN:
|
||||
flags |= GPUSTATE_MAIN_GPU_MASK;
|
||||
break;
|
||||
|
||||
case DS_GPU_TYPE_SUB:
|
||||
flags |= GPUSTATE_SUB_GPU_MASK;
|
||||
break;
|
||||
|
||||
case DS_GPU_TYPE_MAIN_AND_SUB:
|
||||
flags |= GPUSTATE_MAIN_GPU_MASK;
|
||||
flags |= GPUSTATE_SUB_GPU_MASK;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
[self setGpuStateFlags:flags];
|
||||
}
|
||||
|
||||
- (NSString *) render3DRenderingEngineString
|
||||
{
|
||||
NSString *theString = @"Uninitialized";
|
||||
|
||||
pthread_rwlock_rdlock(self.rwlockProducer);
|
||||
|
||||
if(gpu3D == NULL)
|
||||
{
|
||||
pthread_rwlock_unlock(self.rwlockProducer);
|
||||
return theString;
|
||||
}
|
||||
|
||||
const char *theName = gpu3D->name;
|
||||
theString = [NSString stringWithCString:theName encoding:NSUTF8StringEncoding];
|
||||
|
||||
pthread_rwlock_unlock(self.rwlockProducer);
|
||||
|
||||
return theString;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
void SetGPULayerState(const int gpuType, const unsigned int i, const bool state)
|
||||
{
|
||||
GPU *theGpu = NULL;
|
||||
|
||||
// Check bounds on the layer index.
|
||||
if(i > 4)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
switch (gpuType)
|
||||
{
|
||||
case DS_GPU_TYPE_SUB:
|
||||
theGpu = SubScreen.gpu;
|
||||
break;
|
||||
|
||||
case DS_GPU_TYPE_MAIN:
|
||||
theGpu = MainScreen.gpu;
|
||||
break;
|
||||
|
||||
case DS_GPU_TYPE_MAIN_AND_SUB:
|
||||
SetGPULayerState(DS_GPU_TYPE_SUB, i, state); // Recursive call
|
||||
theGpu = MainScreen.gpu;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (theGpu != NULL)
|
||||
{
|
||||
if (state)
|
||||
{
|
||||
GPU_addBack(theGpu, i);
|
||||
}
|
||||
else
|
||||
{
|
||||
GPU_remove(theGpu, i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool GetGPULayerState(const int gpuType, const unsigned int i)
|
||||
{
|
||||
bool theState = false;
|
||||
|
||||
// Check bounds on the layer index.
|
||||
if(i > 4)
|
||||
{
|
||||
return theState;
|
||||
}
|
||||
|
||||
switch (gpuType)
|
||||
{
|
||||
case DS_GPU_TYPE_SUB:
|
||||
if (SubScreen.gpu != NULL)
|
||||
{
|
||||
theState = CommonSettings.dispLayers[SubScreen.gpu->core][i];
|
||||
}
|
||||
break;
|
||||
|
||||
case DS_GPU_TYPE_MAIN:
|
||||
if (MainScreen.gpu != NULL)
|
||||
{
|
||||
theState = CommonSettings.dispLayers[MainScreen.gpu->core][i];
|
||||
}
|
||||
break;
|
||||
|
||||
case DS_GPU_TYPE_MAIN_AND_SUB:
|
||||
if (SubScreen.gpu != NULL && MainScreen.gpu != NULL)
|
||||
{
|
||||
theState = (CommonSettings.dispLayers[SubScreen.gpu->core][i] && CommonSettings.dispLayers[MainScreen.gpu->core][i]);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return theState;
|
||||
}
|
||||
|
||||
void SetGPUDisplayState(const int gpuType, const bool state)
|
||||
{
|
||||
switch (gpuType)
|
||||
{
|
||||
case DS_GPU_TYPE_SUB:
|
||||
CommonSettings.showGpu.sub = state;
|
||||
break;
|
||||
|
||||
case DS_GPU_TYPE_MAIN:
|
||||
CommonSettings.showGpu.main = state;
|
||||
break;
|
||||
|
||||
case DS_GPU_TYPE_MAIN_AND_SUB:
|
||||
CommonSettings.showGpu.sub = state;
|
||||
CommonSettings.showGpu.main = state;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
bool GetGPUDisplayState(const int gpuType)
|
||||
{
|
||||
bool theState = false;
|
||||
|
||||
switch (gpuType)
|
||||
{
|
||||
case DS_GPU_TYPE_SUB:
|
||||
theState = CommonSettings.showGpu.sub;
|
||||
break;
|
||||
|
||||
case DS_GPU_TYPE_MAIN:
|
||||
theState = CommonSettings.showGpu.main;
|
||||
break;
|
||||
|
||||
case DS_GPU_TYPE_MAIN_AND_SUB:
|
||||
theState = (CommonSettings.showGpu.sub && CommonSettings.showGpu.main);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return theState;
|
||||
}
|
||||
|
||||
void GPU_FillScreenWithBGRA5551(const uint16_t colorValue)
|
||||
{
|
||||
const size_t pixCount = sizeof(GPU_screen) / sizeof(uint16_t);
|
||||
|
||||
#ifdef __APPLE__
|
||||
if (pixCount % 16 == 0)
|
||||
{
|
||||
const uint16_t colorValuePattern[] = {colorValue, colorValue, colorValue, colorValue, colorValue, colorValue, colorValue, colorValue};
|
||||
memset_pattern16(GPU_screen, colorValuePattern, sizeof(GPU_screen));
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
for (size_t i = 0; i < pixCount; i++)
|
||||
{
|
||||
((uint16_t *)GPU_screen)[i] = colorValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CGLContextObj OSXOpenGLRendererContext = NULL;
|
||||
CGLPBufferObj OSXOpenGLRendererPBuffer = NULL;
|
||||
|
||||
bool OSXOpenGLRendererInit()
|
||||
{
|
||||
static bool isContextAlreadyCreated = false;
|
||||
|
||||
if (!isContextAlreadyCreated)
|
||||
{
|
||||
isContextAlreadyCreated = CreateOpenGLRenderer();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool OSXOpenGLRendererBegin()
|
||||
{
|
||||
CGLSetCurrentContext(OSXOpenGLRendererContext);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void OSXOpenGLRendererEnd()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bool CreateOpenGLRenderer()
|
||||
{
|
||||
bool result = false;
|
||||
bool useContext_3_2 = false;
|
||||
CGLPixelFormatObj cglPixFormat = NULL;
|
||||
CGLContextObj newContext = NULL;
|
||||
CGLPBufferObj newPBuffer = NULL;
|
||||
GLint virtualScreenCount = 0;
|
||||
|
||||
CGLPixelFormatAttribute attrs[] = {
|
||||
kCGLPFAColorSize, (CGLPixelFormatAttribute)24,
|
||||
kCGLPFAAlphaSize, (CGLPixelFormatAttribute)8,
|
||||
kCGLPFADepthSize, (CGLPixelFormatAttribute)24,
|
||||
kCGLPFAStencilSize, (CGLPixelFormatAttribute)8,
|
||||
kCGLPFAAccelerated,
|
||||
(CGLPixelFormatAttribute)0, (CGLPixelFormatAttribute)0,
|
||||
(CGLPixelFormatAttribute)0
|
||||
};
|
||||
|
||||
#ifdef MAC_OS_X_VERSION_10_7
|
||||
// If we can support a 3.2 Core Profile context, then request that in our
|
||||
// pixel format attributes.
|
||||
useContext_3_2 = IsOSXVersionSupported(10, 7, 0);
|
||||
if (useContext_3_2)
|
||||
{
|
||||
attrs[9] = kCGLPFAOpenGLProfile;
|
||||
attrs[10] = (CGLPixelFormatAttribute)kCGLOGLPVersion_3_2_Core;
|
||||
}
|
||||
#endif
|
||||
|
||||
CGLChoosePixelFormat(attrs, &cglPixFormat, &virtualScreenCount);
|
||||
if (cglPixFormat == NULL)
|
||||
{
|
||||
// Remove the HW rendering requirement and try again. Note that this will
|
||||
// result in SW rendering, which will cause a substantial speed hit.
|
||||
attrs[8] = (CGLPixelFormatAttribute)0;
|
||||
CGLChoosePixelFormat(attrs, &cglPixFormat, &virtualScreenCount);
|
||||
if (cglPixFormat == NULL)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
CGLCreateContext(cglPixFormat, NULL, &newContext);
|
||||
CGLReleasePixelFormat(cglPixFormat);
|
||||
|
||||
// Create a PBuffer for legacy contexts since the availability of FBOs
|
||||
// is not guaranteed.
|
||||
if (!useContext_3_2)
|
||||
{
|
||||
CGLCreatePBuffer(GPU_DISPLAY_WIDTH, GPU_DISPLAY_HEIGHT, GL_TEXTURE_2D, GL_RGBA, 0, &newPBuffer);
|
||||
|
||||
if (newPBuffer == NULL)
|
||||
{
|
||||
CGLReleaseContext(newContext);
|
||||
return result;
|
||||
}
|
||||
else
|
||||
{
|
||||
GLint virtualScreenID = 0;
|
||||
|
||||
CGLGetVirtualScreen(newContext, &virtualScreenID);
|
||||
CGLSetPBuffer(newContext, newPBuffer, 0, 0, virtualScreenID);
|
||||
}
|
||||
}
|
||||
|
||||
RequestOpenGLRenderer_3_2(useContext_3_2);
|
||||
OSXOpenGLRendererContext = newContext;
|
||||
OSXOpenGLRendererPBuffer = newPBuffer;
|
||||
|
||||
result = true;
|
||||
return result;
|
||||
}
|
||||
|
||||
void DestroyOpenGLRenderer()
|
||||
{
|
||||
if (OSXOpenGLRendererContext == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
CGLReleasePBuffer(OSXOpenGLRendererPBuffer);
|
||||
CGLReleaseContext(OSXOpenGLRendererContext);
|
||||
OSXOpenGLRendererContext = NULL;
|
||||
OSXOpenGLRendererPBuffer = NULL;
|
||||
}
|
||||
|
||||
void RequestOpenGLRenderer_3_2(bool request_3_2)
|
||||
{
|
||||
#ifdef OGLRENDER_3_2_H
|
||||
if (request_3_2)
|
||||
{
|
||||
OGLLoadEntryPoints_3_2_Func = &OGLLoadEntryPoints_3_2;
|
||||
OGLCreateRenderer_3_2_Func = &OGLCreateRenderer_3_2;
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
OGLLoadEntryPoints_3_2_Func = NULL;
|
||||
OGLCreateRenderer_3_2_Func = NULL;
|
||||
}
|
||||
|
||||
void SetOpenGLRendererFunctions(bool (*initFunction)(),
|
||||
bool (*beginOGLFunction)(),
|
||||
void (*endOGLFunction)())
|
||||
{
|
||||
oglrender_init = initFunction;
|
||||
oglrender_beginOpenGL = beginOGLFunction;
|
||||
oglrender_endOpenGL = endOGLFunction;
|
||||
}
|
||||
Executable
+172
@@ -0,0 +1,172 @@
|
||||
/*
|
||||
Copyright (C) 2011 Roger Manuel
|
||||
Copyright (C) 2011-2015 DeSmuME team
|
||||
|
||||
This file is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This file is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with the this software. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
#undef BOOL
|
||||
|
||||
class CHEATS;
|
||||
class CHEATS_LIST;
|
||||
class CHEATSEARCH;
|
||||
|
||||
|
||||
/********************************************************************************************
|
||||
CocoaDSCheatItem - OBJECTIVE-C CLASS
|
||||
|
||||
This is an Objective-C wrapper class for DeSmuME's cheat item struct.
|
||||
|
||||
The cheat item data is not freed upon release of this object. This is by design.
|
||||
|
||||
Thread Safety:
|
||||
Assume that all methods are not thread-safe. This was done for performance
|
||||
reasons. The caller of this class' methods is expected to handle thread safety.
|
||||
********************************************************************************************/
|
||||
@interface CocoaDSCheatItem : NSObject
|
||||
{
|
||||
CHEATS_LIST *data;
|
||||
CHEATS_LIST *internalData;
|
||||
BOOL willAdd;
|
||||
pthread_mutex_t mutexData;
|
||||
|
||||
CocoaDSCheatItem *workingCopy;
|
||||
CocoaDSCheatItem *__weak parent;
|
||||
}
|
||||
|
||||
@property (assign) CHEATS_LIST *data;
|
||||
@property (assign) BOOL willAdd;
|
||||
@property (assign, nonatomic) BOOL enabled;
|
||||
@property (assign, nonatomic) NSInteger cheatType;
|
||||
@property (strong, nonatomic) NSImage *cheatTypeIcon;
|
||||
@property (assign, nonatomic) BOOL isSupportedCheatType;
|
||||
@property (assign, nonatomic) NSInteger freezeType;
|
||||
@property (copy, nonatomic) NSString *description;
|
||||
@property (assign, nonatomic) NSUInteger codeCount;
|
||||
@property (copy, nonatomic) NSString *code;
|
||||
@property (assign, nonatomic) UInt8 bytes;
|
||||
@property (assign, nonatomic) UInt32 memAddress;
|
||||
@property (copy, nonatomic) NSString *memAddressString;
|
||||
@property (copy, nonatomic) NSString *memAddressSixDigitString;
|
||||
@property (assign, nonatomic) SInt64 value;
|
||||
@property (readonly, strong) CocoaDSCheatItem *workingCopy;
|
||||
@property (weak) CocoaDSCheatItem *parent;
|
||||
|
||||
- (id) initWithCheatData:(CHEATS_LIST *)cheatData;
|
||||
- (BOOL) retainData;
|
||||
@property (readonly) char *descriptionCString NS_RETURNS_INNER_POINTER;
|
||||
- (void) update;
|
||||
- (CocoaDSCheatItem *) createWorkingCopy;
|
||||
- (void) destroyWorkingCopy;
|
||||
- (void) mergeFromWorkingCopy;
|
||||
- (void) mergeToParent;
|
||||
- (void) setDataWithDictionary:(NSDictionary *)dataDict;
|
||||
- (NSDictionary *) dataDictionary;
|
||||
|
||||
@property (class, strong) NSImage *iconInternalCheat;
|
||||
@property (class, strong) NSImage *iconActionReplay;
|
||||
@property (class, strong) NSImage *iconCodeBreaker;
|
||||
|
||||
@end
|
||||
|
||||
/********************************************************************************************
|
||||
CocoaDSCheatManager - OBJECTIVE-C CLASS
|
||||
|
||||
This is an Objective-C wrapper class for DeSmuME's cheat list class.
|
||||
|
||||
Thread Safety:
|
||||
All methods are thread-safe.
|
||||
********************************************************************************************/
|
||||
@interface CocoaDSCheatManager : NSObject
|
||||
{
|
||||
CHEATS *listData;
|
||||
NSMutableArray *list;
|
||||
|
||||
pthread_rwlock_t *rwlockCoreExecute;
|
||||
BOOL isUsingDummyRWlock;
|
||||
|
||||
NSUInteger untitledCount;
|
||||
NSString *dbTitle;
|
||||
NSString *dbDate;
|
||||
}
|
||||
|
||||
@property (readonly) CHEATS *listData;
|
||||
@property (readonly, strong) NSMutableArray *list;
|
||||
@property (assign) pthread_rwlock_t *rwlockCoreExecute;
|
||||
@property (assign) NSUInteger untitledCount;
|
||||
@property (copy) NSString *dbTitle;
|
||||
@property (copy) NSString *dbDate;
|
||||
|
||||
- (id) initWithFileURL:(NSURL *)fileURL;
|
||||
- (id) initWithListData:(CHEATS *)cheatList;
|
||||
- (id) initWithFileURL:(NSURL *)fileURL listData:(CHEATS *)cheatList;
|
||||
|
||||
- (BOOL) add:(CocoaDSCheatItem *)cheatItem;
|
||||
- (void) remove:(CocoaDSCheatItem *)cheatItem;
|
||||
- (BOOL) update:(CocoaDSCheatItem *)cheatItem;
|
||||
- (BOOL) save;
|
||||
- (NSUInteger) activeCount;
|
||||
- (NSMutableArray *) cheatListFromDatabase:(NSURL *)fileURL errorCode:(NSInteger *)error;
|
||||
- (void) applyInternalCheat:(CocoaDSCheatItem *)cheatItem;
|
||||
|
||||
+ (void) setMasterCheatList:(CocoaDSCheatManager *)cheatListManager;
|
||||
+ (void) applyInternalCheatWithItem:(CocoaDSCheatItem *)cheatItem;
|
||||
+ (void) applyInternalCheatWithAddress:(UInt32)address value:(UInt32)value bytes:(NSUInteger)bytes;
|
||||
+ (NSMutableArray *) cheatListWithListObject:(CHEATS *)cheatList;
|
||||
+ (NSMutableArray *) cheatListWithItemStructArray:(CHEATS_LIST *)cheatItemArray count:(NSUInteger)itemCount;
|
||||
+ (NSMutableDictionary *) cheatItemWithType:(NSInteger)cheatTypeID description:(NSString *)description;
|
||||
|
||||
@end
|
||||
|
||||
@interface CocoaDSCheatSearch : NSObject
|
||||
{
|
||||
CHEATSEARCH *listData;
|
||||
NSMutableArray *addressList;
|
||||
|
||||
pthread_rwlock_t *rwlockCoreExecute;
|
||||
BOOL isUsingDummyRWlock;
|
||||
|
||||
NSUInteger searchCount;
|
||||
}
|
||||
|
||||
@property (readonly) CHEATSEARCH *listData;
|
||||
@property (readonly, strong) NSMutableArray<NSDictionary<NSString*,id>*> *addressList;
|
||||
@property (assign) pthread_rwlock_t *rwlockCoreExecute;
|
||||
@property (readonly) NSUInteger searchCount;
|
||||
|
||||
- (NSUInteger) runExactValueSearch:(NSInteger)value byteSize:(UInt8)byteSize signType:(NSInteger)signType;
|
||||
- (void) runExactValueSearchOnThread:(id)object;
|
||||
- (NSUInteger) runComparativeSearch:(NSInteger)typeID byteSize:(UInt8)byteSize signType:(NSInteger)signType;
|
||||
- (void) runComparativeSearchOnThread:(id)object;
|
||||
- (void) reset;
|
||||
|
||||
+ (NSMutableArray<NSDictionary<NSString*,id>*> *) addressListWithListObject:(CHEATSEARCH *)addressList maxItems:(NSUInteger)maxItemCount;
|
||||
|
||||
@end
|
||||
|
||||
@interface CocoaDSCheatSearchParams : NSObject
|
||||
{
|
||||
NSInteger comparativeSearchType;
|
||||
NSInteger value;
|
||||
UInt8 byteSize;
|
||||
NSInteger signType;
|
||||
}
|
||||
|
||||
@property (assign) NSInteger comparativeSearchType;
|
||||
@property (assign) NSInteger value;
|
||||
@property (assign) UInt8 byteSize;
|
||||
@property (assign) NSInteger signType;
|
||||
|
||||
@end
|
||||
Executable
+1342
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user