30 Commits

Author SHA1 Message Date
clobber ef91ce464c Cleanup 2023-06-20 21:13:53 -06:00
clobber 0ba54f14d3 Merge pull request #8 from ShutOstrich/master
Update to Gambatte JG 0.5.1
2023-05-03 21:20:11 -06:00
ShutOstrich 0a330b490f Add display mode: CGB color correction 2023-05-01 18:55:17 +02:00
ShutOstrich 65e0083de0 Update to Gambatte JG 0.5.1 2023-05-01 07:39:23 +02:00
ShutOstrich 6237b9f50e Update to Gambatte JG 0.5.0 2023-05-01 07:39:23 +02:00
clobber ba04dbb4ef Merge pull request #7 from OpenEmu/revert-5-master
Revert "Add: Colour Palette Revisions"
2021-12-09 21:05:46 -07:00
clobber 2fffad141d Revert "Add: Colour Palette Revisions" 2021-12-09 21:02:29 -07:00
C.W. Betts 44182cc6eb Merge pull request #5 from TRIFORCE89/master
Add: Colour Palette Revisions
2021-12-09 19:21:12 -07:00
TRIFORCE89 72bb48afdd - Finally accurate SGB colours
- Remove usage of BGB colours
2021-12-02 20:16:14 -05:00
TRIFORCE89 ecbaa4142b correct SGB specific palettes; add real WideBoy values; add missing Smurfs from Goomba 2021-09-18 10:00:50 -04:00
TRIFORCE89 e69312eabd Redo Demo Vision after correcting NES Classic Mini palette in Nestopia 2021-07-23 21:24:24 -04:00
TRIFORCE89 b5a97f1d55 Multiple Revisions
Changes:
 - Double check against TheWolfBunny & nensondubois
 - improved commenting
 - nensondubois' revised Alley Way SGB palette
 - nensondubois' revised Tetris Attack SGB palette
 - Collection of SaGa palette
 - Donkey Kong '94 ending palette
 - SGB Super Mario Land palette for Arne's Unnamed Graphics Hack rather than 1-A
 - Wide-Boy palette option
 - Donkey Kong Land DMGesque menu palette option
 - Game & Watch palette option
 - Demo Vision palette option
 - remove unused palette additions (Superball, Squidlit)
 - update Dream Land GB with TheWolfBunny's version
2021-07-16 12:01:05 -04:00
TRIFORCE89 00e8ac983c Add: SGB Cool Spot from NP. Some unofficial Goomba Color entries for other games 2021-06-11 21:58:02 -04:00
TRIFORCE89 be62b682da MGB is default again (I play with LCD grids), swap Squidlit for proper GB Studio 2021-06-06 12:30:51 -04:00
TRIFORCE89 8868472869 Fix: Kirby Pocket && Add: custom Arne SML2013 (need to edit game header to activate) 2021-05-19 08:53:37 -04:00
TRIFORCE89 beba11c372 Kirby!
Changes:
- Fix: Wii Gray is now the default
- Add: Smash Ultimate Green replaces VC Green
- Fix: revise true color output

Note:
- new green palette was created by pushing LUT (https://scanmountgoat.github.io/Smush-Material-Research/post_processing) through https://hexcolor.co/image-to-colors and increasing brightness by 40%
- 3DS Dreamland GB looked like 3DS VC, so in my view Switch Dreamland GB is a TV-safe revision of that VC palette
2021-05-12 00:24:18 -04:00
TRIFORCE89 5c1a41ec41 Updates:
- rearrange palette menu
- add back SGB 4H (My Life in Gaming endorses it)
- replace 3DS grayscale with the nicer revision from Kirby's Dream Collection
- SGB Pokémon taken from disassembly
- accurate GB Studio
- code cleanup

Notes:
- recommended to not use a LCD-tint (like GBC/GBA/GBI) shader on SGB palettes
2021-05-10 20:21:24 -04:00
TRIFORCE89 01f163576d Fix: locations of the system plugin headers.
Changes:
- Minor Xcode maintenance.
2020-12-25 14:09:15 -05:00
TRIFORCE89 be0e841c42 Add: SGB/GBC support for Lunar Chase prototype 2020-10-23 00:28:03 -04:00
C.W. Betts 40e9ff65bb Poke the plists: get the development language from Xcode build. 2020-10-01 01:51:37 -06:00
C.W. Betts c4bd988726 Fix locations of the system plugin headers.
Minor Xcode maintenance.
2020-10-01 01:26:40 -06:00
C.W. Betts 17ccc013a8 Revert "set deployment target to match OpenEmuCore's, of 10.14.4." 2020-09-22 09:30:09 -06:00
C.W. Betts bb866b0f91 set deployment target to match OpenEmuCore's, of 10.14.4.
Also silence deprecated OpenGL warnings.
2020-09-22 02:53:07 -06:00
TRIFORCE89 ac3ceae429 Add: palette for Analogue Pocket / GB Studio 2020-09-20 19:14:11 -04:00
TRIFORCE89 69a6fe7856 Tweak PkMn palettes to match VBA-M and TheWolfBunny 2020-09-20 19:14:11 -04:00
TRIFORCE89 5fd058a7ea True Colour
Changes:
 - Remove: Gambatte's incorrect colour correction (this should be addressed via shaders)
 - Fix: change up the list of available palette selections again because now they all actually look correct
2020-09-20 19:13:16 -04:00
TRIFORCE89 f463dc6b7a Add: GBC Greyscale option & default to VC Greyscale instead of SGB as it approximates Pocket 2020-09-20 19:06:07 -04:00
TRIFORCE89 d8d6f0d807 Add: VirtualBoy palette 2020-09-20 19:06:07 -04:00
TRIFORCE89 08f893779e Fix: revise palettes used and include VC colours 2020-09-20 19:06:07 -04:00
TRIFORCE89 23b9a5de5a Add: Colour Palette Revisions 2020-09-20 19:06:07 -04:00
145 changed files with 2205 additions and 11862 deletions
+339
View File
@@ -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.
+551
View File
@@ -0,0 +1,551 @@
Version 0.5.1
-------------
- Build improvements
- Increase standards compliance and code quality
- Add the SoX Resampler for higher quality (but higher CPU usage) resampling
- Add SameBoy's "Modern - Accurate" colour correction
Version 0.5.0
-------------
- Initial tagged release after fork from final public revision of Gambatte
- Stricter build flags
- Removal of stale, bitrotten code
- Rearrange and simplify codebase layout
--------------------------------------------------------------------------------
-- 0.4.1 -- 2009-01-10
libgambatte:
- Fix HqXx filter pitch.
- Fix mbc2 not getting a rambank.
- Make sure to reset passed pointers when deleted. Fixes potential crash
when loading ROM during OAM busy.
common:
- Substantially improved rate estimation averaging.
- RateEst: Add a convenient way of filtering measures that extend beyond
a buffer time, and are as such probably invalid.
- RateEst: Allow using a custom timestamp in feed().
- RateEst: Keep a queue of the last ~100 msec worth of samples and
duration, and filter out collective samples that give a pre-estimate
that seems way off.
- Replace "Game Boy / Game Boy Color emulator" with "Game Boy Color
emulator" for now to avoid misleading anyone on the current status.
gambatte_qt:
- Disable BlitterWidget updates (paintEvents) while not paused.
- QGLBlitter: Do a cheap front blit rather than a vsynced flip if audio
buffers are low.
- Allow BlitterWidgets to opt in to get paintEvents while unpaused. Do so
for QGLBlitter since it may need to clear buffers afterwards.
- QGLBlitter: Try to blit right after sync in the case of single buffering.
- Up default audio buffer latency to 100 ms (some common system audio
servers require a lot of buffering to work well).
- Adaptively skip BlitterWidget syncs if audio buffer is low, in a manner
that should minimize wasted skips in sync to vblank situation, and tries
to be non-disturbing. This replaces frame time halving, and blitter
specific rescueing.
- Clear display buffers in DirectDrawBlitter and Direct3DBlitter in
exclusive mode, since blits don't necessarily cover the entire buffers.
- DirectDrawBlitter: Make sure that a minimum amount of time has passed
between calls to WaitForVerticalBlank, since it can return in the same
vblank period twice on a fast system.
- DirectDrawBlitter: Support vsync for refresh rate ~= 2x frame rate.
- DirectDrawBlitter: Refactor somewhat and get rid of a couple minor
potential bugs.
- DirectDrawBlitter: Some tweaks to get updates closer to sync time in
certain situations.
- DirectDrawBlitter: Some tweaks to better support DONOTWAIT.
- DirectDrawBlitter: Make only updating during vblank while page flipping
optional.
- Direct3DBlitter: Some tweaks to get updates closer to sync time in
certain situations.
- Filter out very short frame times in frame time estimation.
- Don't adjust frame time during turbo, but rather skip BlitterWidget
syncs to speed up, which avoids vsync limits without disabling vsync.
- DirectDrawBlitter: Add triple buffering option.
- Direct3DBlitter: Use D3DSWAPEFFECT_DISCARD in non-exclusive mode.
- Direct3DBlitter: Allow triple buffering and vblank-only updates in
non-excusive mode.
- Rename "Page flipping" in Direct3D and DirectDraw blitters to
"Exclusive full screen".
- Pause audio on win32 titlebar clicks/drags to avoid looping audio due to
underruns from blocked timerEvents.
- Use wildcards for platform detection to avoid being unnecessarily
compiler/architecture specific. Fixes bug 2377772.
- Rewrite most of DirectSoundEngine, supporting primary buffer option,
making it more robust, correct and hopefully cleaner. Only use part of
the primary buffer if the desired buffer size is lower than the
primary buffer size.
- Direct3DBlitter and DirectDrawBlitter: Force blocking updates when sync
to vblank is enabled. Some updates only block if there's a prior
unfinished update in progress. This screws up frame time estimation in
turn screwing up vsync. To fix this we do a double update (and extra blit)
if close to a frame time period has passed since the last update when
sync to vblank is enabled. I really should have noticed this earlier as
it pretty much breaks vsync adaption completely.
- Direct3DBlitter: Use the D3DCREATE_FPU_PRESERVE flag when creating
device. Omitting this flag can screw up floating point calculations in
other parts of the code. For instance WASAPI cursor timestamps get
utterly screwed up here.
- Direct3DBlitter: It appears that managed textures are updated before
they are unlocked, which screws up redraws, making things appear choppy
in some situations. Use a default memory texture and a system memory
texture and the UpdateTexure method instead.
- DirectSoundEngine: Make use of the sample period limit feature of
RateEst, rather than duplicating the feature.
- Add polling WASAPI engine with exclusive mode support. Latency and rate
estimation is generally better than DirectSound, and in exclusive mode
there is less blocking as well as exclusive mode being better than
shared mode in the other areas too.
- WasapiEngine: Add device selection.
- WasapiEngine: Add static isUsable() method. Only listed if isUsable().
Default engine if isUsable().
- WasapiEngine: Use default device if there's only one device available,
since we don't show the combobox anyway.
- DirectSoundEngine: Provide the integrated read and status get write
method optimization.
- XvBlitter: Set NosystemBackground attribute rather than OpaquePaintEvent.
Reimplement paintEngine to return NULL as suggested by Qt docs.
- X11Blitter: Reimplement paintEngine to return NULL.
- AlsaEngine: Make use of sample period limit feature of RateEst. Don't
increase estimated sample rate on underrun.
- OssEngine: Make use of sample period limit feature of RateEst. Don't
increase estimated sample rate on underrun.
- Esc exits fullscreen on macx.
- Drop OpenAL from default macx binary.
- Add some useful but commented build flags for macx to .pro files.
-- 0.4.0 -- 2008-10-27
libgambatte:
- less fixed-width type dependencies. don't assume unsigned int > 16 bits
- slightly faster sprite mapping
- Skip potential high frequency events when they don't matter.
- do sprite sorting and cycle calculations pr line as needed instead of all
at once
- fix broken volume on/off event notification
- less int > 16-bits assumptions
- more type width dependency fixes
- int width deps. Gambatte namespace
- wx affects sprite m3 cycles
- cache m3 cycles, related refactoring
- readjust cgb dma cycles to previously changed m3 timing
- clean up goofy lyc calculation.
- cgb dma from various areas results in 0xFF being written.
- 0xFEA0-0xFEFF not writable when OAM isn't
- unusable ioram bits fixes
- dmg ioram startup state fixes.
- various oamdma accuracy
- oamdma bus conflicts with cpu, ppu, cgbdma.
- rewritten memory read/write methods.
- accurate timing of ppu sprite mapping reads.
- fix recent cgb sprite cycles sorting slip up.
- preoffset mem pointers.
- get rid of unused memory.
- save state infrastructure,
- clean up video timing code,
- use save state for initialization and reset,
- do color conversion outside filters
- fast rgb32ToUyvy,
- add overlooked oamdma event,
- adjust subcycle irq timing (shouldn't affect anything),
- various refactoring
- save savedata before loading state
- fix silly initstate ifreg regression
- save state selection
- save state osd preview snapshots
- fix a few potential security holes when loading invalid state
- get rid of some undefined behaviour in statesaver
- always draw in rgb32, color convert afterwards, too bad for maemo/16-bit
depth users
- get rid of silly c string stuff
- add bitmap font rendering with font based on Bitstream Vera Sans
- osd state n saved/loaded text
- empty state osd thumbs marked with "Empty" text
- adjust thumbnail interpolation weighing slightly
- utilize templates for more flexible osd text printing
- use grey osd text with black outline for save/load state messages
- move state 0 OSD pos to rightmost to match kbd layout
- state 1 default on ROM load
- support external save state files
- missing includes
- missing virtual destructor
- std::ifstream construction missing binary flag
- fix gcc-4.3 compilation
- avoid signed overflow in constant (which is both undefined and likely
to cause problems on architectures where sizeof(long) != sizeof(int)) in
rgb2yuv code.
- Fix wrong pitch passed to filter if color conversion is needed.
- Fix potential problem with rgb32ToUyvy cache init values on 16-bit systems
- Correct unhalttime when resetting counters. Fixes perodic infinite halt
issue in Kirby's Star Stacker and probably other games.
- Fix LY display disable regression
- Use deltas and a running sum to decrease buffer writes in sound emulation
sample generation.
- Rearrange sound emulation event loop to optimize for high-frequency event
units.
- Initialize palette arrays to avoid valgrind noise.
- Don't do resampling in libgambatte. Update API to reflect this.
- No rambanks for ROMs that don't request any.
- Route invalid rombank addresses in non-power-of-2 number of rombanks
cases to disabled area assuming ceiled power of 2 address bus.
- no sprites or sprite mapping busy cycles on first line after display
enable. slight cleanup.
- small oam accessibility correction.
- Tile loading and tile rendering can seemingly get out of sync when
modifying scx at a critical time. Another pessimation with little gain in
the name of accuracy.
- Use a look-up table to do tile byte merging.
- Append "_dmg" to save base name when forcing DMG mode, to avoid
corrupting CGB save files and vice versa.
- saner ly write behaviour
- Add adapted and optimized hq3x.
- Revert to big f'ing switch hq2x code, as there's less duplication now.
Also optimized interpolation functions further. No idea how I missed that
initially.
- Lower opacity OSD text.
gambatte_sdl:
- less retarded indenting
- saner placement of fill_buffer function
- int width deps. Gambatte namespace
- Scalebuffer dstpitch aware.
- save state selection
- add number key slot selection shortcuts
- Estimate actual output sample rate in terms of OS timers
and derive frame rate from it.
- Move AudioData and RingBuffer classes to separate files.
- Make underruns slightly less painful, by resetting buffer
positions.
- Skip resampling when fast-forwarding
- Fill available buffer space before waiting for more.
- Audio buffer command line options.
- Use half video frame sleep time if audio buffer is close to underrun.
- Adjust estimated frame time each frame.
gambatte_qt:
- more likely to build on mac os x
- Fix fixed window size issues with various window managers (metacity,
xfwm4...)
- macx build fixes
- hopefully fix opengl clearing issues
- Gambatte namespace
- Decouple Qt GUI from gambatte.
- Lots of cleanups, flexibility added
- setting of various properties, frame time, aspect ratio, button events,
video sources, sample rates, pauseOnDialogExec, custom menus etc.
- Document some interfaces.
- Support for setting approximate sound buffer latency.
- Use rational math for 100% exact timers (even though the actual system
timers are unlikely to be accurate).
- Add fast-forward to input settings.
- timeGetTime() fallback for win32
- Store full screen mode values/text rather than less reliable indexes.
- Repaint on xvblitter port changes to avoid color key not getting
repainted.
- improved ALSA buffer reporting
- add sampleRate info to MediaSource::setSampleBuffer.
- clarify that "samples" refers to stereo samples
- fix 24-bit depth non-shm ximage creation
- fix blittercontainer incorrectly using minimumSize for integer scaling
- add unrestricted fast bilinear and nearest neighbor sw scaling to
x11/qpainter blitter
- swscale: remove forgotten static qualifiers
- swscale: center linear weighing bias
- swscale: exclude iostream
- swscale: less bloated
- macx fixed/variable window size change issue fixed
- macx opengl drawbuffer change issues worked around
- add openal engine, default on macx
- add macx quartz video mode toggler
- multi-head infrastructure
- support multiple monitors in macx quartz toggler
- more work-arounds for Qt failing to set correct geometry on video mode
changes.
- more explicit fast-forward button handling, to avoid missed key
press/release events on macx
- opengl doublebuffer preblitting, try to make actual screen updates as
close to right after sync wait is over as possible
- add xf86vidmode toggler (xrandrtoggler is default)
- x11blitter: check for other supported visuals if the default is
unsupported.
- temporarily return to original video mode and minimize on full screen
alt-tab (except on macx or if there are multiple screens), switch back on
focus-in
- hide mouse cursor after move timeout, or key/joystick pressed (more sane
on macx)
- exit fullscreen rather than toggle menubar on macx (note that the menubar
will automatically pop-up on macx full screen if the mouse is moved to
the top of the primary screen)
- add (independent) pause counter for non-client pauses.
- reset X11 screen saver on joystick activity
- change "turbo"-mode to temporarily set frametime as a way of avoiding
vsync issues (for a laugh, check out the video dialog while in
fast-forward mode and see "Sync to vertical blank in 65535 and 131070 Hz
modes").
- fix win32 compilation
- refix win32 fullscreen geometry correction
- neater win32 BlitterWidget::sync
- avoid misleading minimize on fullscreen close
- refactor Blitterwidget::sync
- directdrawblitter: remove unecessary turbo conditions
- gditoggler: add multi-monitor support (win32)
- videodialog: save actual hz values for real this time
- quartztoggler: avoid potentially reverting to the wrong mode on double
setFullMode(false) in multi-head configs
- make sure window is within screen after mode change, so Qt doesn't reset
it to the primary screen
- revert to previous win32 fullscreen geometry correction behaviour so that
the geometry gets properly reset after fullscreen
- Add directdraw device selection.
- directsoundengine: add device selection.
- directdrawblitter: only list devices if there are more than 2 devices
(including primary)
- directdrawblitter: use private static member rather than global friend
enumeration callback
- capitalization changes
- add direct3d9 blitter with support for vsync, bf, page flipping, triple
buffering, device selection, multi-head etc. d3d9.dll loaded at runtime
- more strict and thorough exclusive mode handling to support d3d fullscreen
- work around file open dialog not returning focus properly
- gditoggler: use current registry settings for return modes
- directsoundengine: set DSBCAPS_GETCURRENTPOSITION2 flag
- revert bad macx return from fullscreen on menu-toggle
- don't build xf86vidmodetoggler by default
- add save state actions to GUI menu
- clean up GUI menu creation code
- move GUI recent files to submenu
- support external save state files
- add number key slot selection shortcuts
- missing includes
- missing virtual destructor
- make sure windows path arguments don't use backslashes by using QFileInfo
- add Play menu with Pause, Frame Step, Dec/Inc/Reset Frame Rate
- Add tab support to input settings dialog.
- Add alternate key support to input settings dialog.
- Auto-focus to next likely input box after settings key in input dialog.
- Add "Play" and "State" input settings dialog tabs.
- Avoid using the most convenient keys as forced menu short-cuts, set them
as default keys in input settings dialog instead. This unfortunately
makes the more useful shortcuts less visible, but it allows remapping
the most convenient keyboard keys.
- Avoid duplicate joystick axis "press" events by keeping a map of axis
states.
- Make sure to discard irrelevant/old joystick events.
- Don't give MediaSource button events when stopped.
- Allow joystick-based button events while paused by using a very
low-frequency poll timer.
- Make some of the joystick event wrapping stuff less messy.
- missing string include
- use QString for videoSourceLabel passed to MainWindow constructor
- store currently selected scheme as string, since it appears ModelIndex
is neither tied to the data it points to nor invalidated by changes.
enforce valid state on reject since the list of schemes may have
changed.
- Direct3DCreate function pointer typedef needs WINAPI macro
- disable page flipping dependent checkboxes in constructor to ensure
correct start state
- add custom sample rate support
- change default buffer latency to 67 ms
- don't auto-repeat buttons bound to keyboard
- use enums for somewhat more robust gambattesource button setup
- fix silly "alsa not using default device by default" bug
- Only ask for xrandr config once to avoid potential server roundtrips in
some xrandr versions.
- Make sure xrandr version is >= 1.1 and < 2
- Prevent all text editing of input boxes.
- Add custom context menu to input boxes.
- Update AudioEngine to support sample rate estimation in terms of OS
timers.
- Implement sample rate estimation in ALSA and OSS audio engines.
- AlsaEngine: Revert to using snd_pcm_avail_update for buffer status since
snd_pcm_delay may consider external latencies.
- AlsaEngine: Use snd_pcm_hw_params_set_buffer_time_near. Don't request a
particular number of periods per buffer.
- AlsaEngine: Use hw as default custom device string, rather than hw:0,0.
- OssEngine: Don't trust GETOSPACE fragment info.
- Estimate optimal frame rate based on sample rate estimations.
- Extend BlitterWidget to support estimation of vsynced frame rate in terms
of OS timers.
- Implement vsync frame rate estimation in QGlBlitter, Direct3DBlitter and
DirectDrawBlitter.
- Use a combination of OS timer sample rate estimation and vsync frame rate
estimation to derive resampling ratio for no-frame-duplication vsync.
- Change API to reflect MediaSources not being responsible for resampling.
- Make sure to parent PaletteDialog list model, so it gets deleted properly.
- Various refactoring, small changes and stuff I forgot.
- limit vsync frame rate estimation deviation
- More averaging in estimation code.
- Stricter estimate deviation limit
- Adjust estimated frame time each frame.
- Use half frame time if audio buffer is close to underrun.
- Provide combined audioengine write and status get, to avoid doing
potentially expensive operations twice. Utilized in OSS and ALSA engines.
- Saner vsync estimate variance protection.
- allow dynamically setting samples per frame
- Don't bother allowing sources the choice of which output sample rates are
selecrable, as it's not really a per source thing at this point. If
resampling avoidance is desired, then that should rather be a user option
(to depend on the OS for resampling, which is mostly nonsensical for the
Game Boy/NES/PSG-system case btw).
- Move Qt media framework to a separate subdir
- postpone buffered x11 blits to after sync.
- Add support for XRandR 1.2 + multi-head
- use crtc mode dimensions rather than crtc dimensions when discarding
modes since crtc dimensions may be rotated
- Fractional bits for intermediate rate estimation averages.
- Add RateEst reset method. Initialize RateEst count to 1.
- Less refresh rate estimation averaging.
- Allow more refresh rate estimation deviation.
- Return NULL paintEngine in windows blitters that use the PaintToScreen
attribute.
- Add checks for things not being initialized in DirectDraw-blitter and
QPainterBlitter paintEvents.
- Don't reparent blitters (mainly to make a bug in Qt 4.4.3 win less
annoying, widgets that do internal reparenting are still affected).
- Check for window position less than screen top-left after mode change,
before full screen, to avoid Qt moving it to the primary screen.
- Add rate estimation to DirectSound engine.
- Better underrun detection in DirectSound engine.
- Don't duplicate blitter pointer in mainwindow.
- Use RateEst.reset rather than re-initing on pause.
- Add CoreAudio engine with rate estimation and buffer status support.
Default engine on Mac OS X.
- 44100 Hz default sample rate on OS X, since OS X tends to resample
everything to 44100 Hz.
- Get rid of buffer status averaging in OpenAlEngine, since it makes
assumptions on usage pattern that shouldn't be made.
- Fix CoreAudio engine reporting buffer status in samples rather than
frames.
- Update SDL_Joystick to SDL-1.2 SVN.
- #undef UNICODE in win32/SDL_mmjoystick.c to avoid joystick name mangling.
- work around annoying random non-updating OpenGL on Mac OS X after full
screen.
common/other:
- Fix GCC 4.3 warnings about people getting confused by operator precedence
by adding parentheses.
- Real-time, sophisticated resampling framework with several
performance/quality profiles for dynamically generated windowed sinc and
CIC chains based on analysis of fourier transforms and optimal cost
equations. Fast 2-tap linear as a low quality alternative.
- Move non-emulation common code to a common directory to avoid duplication.
- Update front-ends to new libgambatte API.
- Utilize resampling framework in front-ends. Selectable resamplers.
- Improved adaptive sleep class that estimates oversleep.
- Various refactoring, small changes and stuff I forgot.
- Do per phase normalization to avoid dc fluctuations.
- More averaging in estimation code.
- Stricter estimate deviation limit
- Fractional bits for intermediate rate estimation averages.
- Add RateEst reset method. Initialize RateEst count to 1.
- Extend ringbuffer.h to support resetting size, and move it to common dir
since gambatte_qt/coreaudioengine uses it too now.
- Add "force DMG mode" option.
- Allow more rate estimation deviation.
hwtests:
- wx affects sprite m3 cycles.
- cgb dma from various areas results in 0xFF being written.
- add hwtests for oam dma
- m3 cycles wo bg
- more oamdma tests
- various oamdma accuracy. oamdma bus conflicts with cpu, ppu, cgbdma.
- accurate timing of ppu sprite mapping reads.
-- 0.3.1 -- 2007-10-26 --
gambatte_qt:
- Enable Joystick POV-Hat events.
-- 0.3.0 -- 2007-10-26 --
libgambatte:
- Fix adc/sbc and add_hl_rr hfc calc, sp_plus_n cf/hcf calc and daa thanks
to blargg.
- document HF2 better
- Update sound core according to blargg's findings.
- Improve resampling quality and performance.
- Fix overlooked "add hl,sp" flag calculation.
- fix initial endtime value
- check for resampling ratio < 1
- Add support for DMG palette customization.
gambatte_sdl:
- use std::map for parser
- Don't bother hashing.
- Add input config support.
- Add joystick support.
- Fix horrid "turbo can affect emulation" bug.
- Add sw and yuv overlay scaling.
- Use cond/mutex for thread syncing, RAII, refactor.
- add option for sample rate choice
- Add option to list valid input keys
- don't die if audio fails
gambatte_qt:
- no point in filter being non-static anymore
- use std::map for input vectors
- remove unused unusedBool
- Fix horrid "turbo can affect emulation" bug.
- remove some useless optimizations
- auto_ptr love.
- support joystick hat.
- nicer input handling.
- Add sound dialog.
- Add custom dev choice for oss, alsa engines.
- Use rgb if available for xv.
- Get rid of BAD_MATCH warnings for setting non-existent xv attributes.
- make subblitters private nested classes
- add reset action
- Add support for DMG palette customization.
- Add global buffer option for dsound engine
-- 0.2.0 -- 2007-09-05 --
libgambatte:
- fix 64-bit compile and segfault. Thanks to Nach for noticing.
- Add zip support. Thanks to Nach for contributing nice, clear code
- fix sound ch4 frequency calculation
- Several PPU reads timings depend on wx. Thanks to franpa for noticing the
corrupt line in The LoZ: Oracle of Seasons.
- remove unused doubleSpeed parameter from m3ExtraCycles call
gambatte_sdl:
- Thread safety, bigger sound buffer
- Compile on more platforms. Thanks to Thristian for the find.
- actually increment iterator so the loop makes some sense (parser.cpp)
gambatte_qt:
- fix 64-bit compile. Thanks to Nach.
- better license info for x11getprocaddress.cpp
- initial joystick support, mostly using SDL's joystick code (separated from
the rest of SDL)
- use binary search for gb inputs.
all:
- make sure to use std:: despite sloppy compilers allowing omission. Thanks
to blargg for the reminder.
- get rid of some valgrind warnings. Thanks to Nach for noticing.
hwtests:
- add tests for wx effects on PPU read timings.
build:
- add -Wextra to default compile flags
doc:
- mention optional zlib dependency
- additions to thanks section
-- 0.1.1 -- 2007-08-29 --
libgambatte:
- fix integer overflow in color conversion to rgb16
- only accept valid filter indexes
gambatte_sdl:
- print version
- print usage
- support command line arguments.
- add option for starting in full-screen
- add option for using video filter
gambatte_qt:
- clean up obsolete includes.
- directdraw: only use alpha if primary surface uses it.
- add support for loading rom from porgam argument.
- s/"a highly accurate"/"an accuracy-focused"/ in about box
- gditoggler: fix unordered video mode listing
build:
- Support external CPPFLAGS
- Use sdl-config
doc:
- fix silly wording in README about section
- s/seperate/separate/
- s/Automake/Make/
- mention XShm dependency
- mention sys/shm.h requirement
- document key mapping better
- s/"a highly accurate"/"an accuracy-focused"/
- add man pages
+56 -43
View File
@@ -68,6 +68,7 @@ public:
- (void)applyCheat:(NSString *)code;
- (void)loadDisplayModeOptions;
- (NSString *)gameInternalName;
- (BOOL)gameHasInternalPalette;
- (void)loadPalette;
@@ -101,7 +102,7 @@ public:
- (BOOL)loadFileAtPath:(NSString *)path error:(NSError **)error
{
memset(pad, 0, sizeof(uint32_t) * OEGBButtonCount);
memset(pad, 0, sizeof(pad));
// Set battery save dir
NSURL *batterySavesDirectory = [NSURL fileURLWithPath:self.batterySavesDirectoryPath];
@@ -127,9 +128,7 @@ public:
if (gb.load(path.fileSystemRepresentation) != 0)
return NO;
// Load built-in GBC palette for monochrome games if supported
if (!gb.isCgb())
[self loadPalette];
[self loadDisplayModeOptions];
return YES;
}
@@ -330,52 +329,49 @@ const int GBMap[] = {gambatte::InputGetter::UP, gambatte::InputGetter::DOWN, gam
- (NSArray <NSDictionary <NSString *, id> *> *)displayModes
{
if (gb.isCgb())
return nil;
if (_availableDisplayModes.count == 0)
{
_availableDisplayModes = [NSMutableArray array];
NSArray <NSDictionary <NSString *, id> *> *availableModesWithDefault =
@[
Option(@"Internal", @"palette"),
Option(@"Grayscale", @"palette"),
Option(@"Greenscale", @"palette"),
Option(@"Pocket", @"palette"),
SeparatorItem(),
Label(@"GBC Palettes"),
Option(@"Blue", @"palette"),
Option(@"Dark Blue", @"palette"),
Option(@"Green", @"palette"),
Option(@"Dark Green", @"palette"),
Option(@"Brown", @"palette"),
Option(@"Dark Brown", @"palette"),
Option(@"Red", @"palette"),
Option(@"Yellow", @"palette"),
Option(@"Orange", @"palette"),
Option(@"Pastel Mix", @"palette"),
Option(@"Inverted", @"palette"),
// @{ OEGameCoreDisplayModeGroupNameKey : @"Test Menu",
// OEGameCoreDisplayModeGroupItemsKey : @[
// OptionToggleable(@"Toggle 1", @"toggle1"),
// OptionToggleable(@"Toggle 2", @"toggle2"),
// SeparatorItem(),
// Label(@"Group 1"),
// OptionIndented(@"Option 1", @"option"),
// OptionIndented(@"Option 2", @"option"),
// SeparatorItem(),
// Label(@"Group 2"),
// OptionIndented(@"Option 3", @"option2"),
// OptionIndented(@"Option 4", @"option2"),
// ]
// },
];
NSArray <NSDictionary <NSString *, id> *> *availableModesWithDefault;
if (gb.isCgb())
{
availableModesWithDefault =
@[
Label(@"Color Correction"),
OptionDefault(@"Default", @"colorCorrection"),
Option(@"Modern", @"colorCorrection"),
];
}
else
{
availableModesWithDefault =
@[
Option(@"Internal", @"palette"),
Option(@"Grayscale", @"palette"),
Option(@"Greenscale", @"palette"),
Option(@"Pocket", @"palette"),
SeparatorItem(),
Label(@"GBC Palettes"),
Option(@"Blue", @"palette"),
Option(@"Dark Blue", @"palette"),
Option(@"Green", @"palette"),
Option(@"Dark Green", @"palette"),
Option(@"Brown", @"palette"),
Option(@"Dark Brown", @"palette"),
Option(@"Red", @"palette"),
Option(@"Yellow", @"palette"),
Option(@"Orange", @"palette"),
Option(@"Pastel Mix", @"palette"),
Option(@"Inverted", @"palette"),
];
}
// Deep mutable copy
_availableDisplayModes = (NSMutableArray *)CFBridgingRelease(CFPropertyListCreateDeepCopy(kCFAllocatorDefault, (CFArrayRef)availableModesWithDefault, kCFPropertyListMutableContainers));
if (![self gameHasInternalPalette])
if (!gb.isCgb() && ![self gameHasInternalPalette])
[_availableDisplayModes removeObjectAtIndex:0];
}
@@ -470,6 +466,8 @@ const int GBMap[] = {gambatte::InputGetter::UP, gambatte::InputGetter::DOWN, gam
// Set the new palette
if ([displayModePrefKey isEqualToString:@"palette"])
[self changePalette:displayMode];
else if ([displayModePrefKey isEqualToString:@"colorCorrection"])
gb.setCgbColorCorrection([displayMode isEqual:@"Modern"] ? 1 : 0);
}
# pragma mark - Misc Helper Methods
@@ -482,7 +480,7 @@ const int GBMap[] = {gambatte::InputGetter::UP, gambatte::InputGetter::DOWN, gam
size_t len = resampler->resample(_outSoundBuffer, reinterpret_cast<const int16_t *>(_inSoundBuffer), frames);
if (len)
[[self ringBufferAtIndex:0] write:_outSoundBuffer maxLength:len << 2];
[[self audioBufferAtIndex:0] write:_outSoundBuffer maxLength:len << 2];
}
- (void)applyCheat:(NSString *)code
@@ -494,6 +492,21 @@ const int GBMap[] = {gambatte::InputGetter::UP, gambatte::InputGetter::DOWN, gam
gb.setGameShark(s);
}
- (void)loadDisplayModeOptions
{
if (gb.isCgb())
{
// Restore color correction
NSString *lastColorCorrection = self.displayModeInfo[@"colorCorrection"] ?: @"Default";
[self changeDisplayWithMode:lastColorCorrection];
}
else
{
// Load built-in GBC palette for monochrome games if supported
[self loadPalette];
}
}
- (NSString *)gameInternalName
{
NSString *title = [NSString stringWithUTF8String:gb.romTitle().c_str()];
+21 -126
View File
@@ -38,6 +38,7 @@
828387BB0E6CDB6500A96E2C /* gameboy.icns in Resources */ = {isa = PBXBuildFile; fileRef = B5F6D8A80E66914F001CA5D3 /* gameboy.icns */; };
828387BD0E6CDB6500A96E2C /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 089C165FFE840EACC02AAC07 /* InfoPlist.strings */; };
828387E20E6CDB6E00A96E2C /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1058C7A7FEA54F5311CA2CBB /* Cocoa.framework */; };
8F14C4F929FF7217000D080B /* statesaver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8F14C4F829FF7217000D080B /* statesaver.cpp */; };
9499B5D81AB242B200276D21 /* chainresampler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9499B54E1AB242B200276D21 /* chainresampler.cpp */; };
9499B5D91AB242B200276D21 /* i0.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9499B5541AB242B200276D21 /* i0.cpp */; };
9499B5DA1AB242B200276D21 /* kaiser50sinc.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9499B5561AB242B200276D21 /* kaiser50sinc.cpp */; };
@@ -67,7 +68,6 @@
9499B5FE1AB242B300276D21 /* length_counter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9499B5BA1AB242B200276D21 /* length_counter.cpp */; };
9499B5FF1AB242B300276D21 /* sound.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9499B5BF1AB242B200276D21 /* sound.cpp */; };
9499B6001AB242B300276D21 /* state_osd_elements.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9499B5C11AB242B200276D21 /* state_osd_elements.cpp */; };
9499B6011AB242B300276D21 /* statesaver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9499B5C31AB242B200276D21 /* statesaver.cpp */; };
9499B6021AB242B300276D21 /* tima.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9499B5C51AB242B200276D21 /* tima.cpp */; };
9499B6031AB242B300276D21 /* ly_counter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9499B5C91AB242B200276D21 /* ly_counter.cpp */; };
9499B6041AB242B300276D21 /* lyc_irq.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9499B5CB1AB242B200276D21 /* lyc_irq.cpp */; };
@@ -113,12 +113,10 @@
1058C7A7FEA54F5311CA2CBB /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = System/Library/Frameworks/Cocoa.framework; sourceTree = SDKROOT; };
828387810E6CDB2200A96E2C /* Gambatte.oecoreplugin */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = Gambatte.oecoreplugin; sourceTree = BUILT_PRODUCTS_DIR; };
828387820E6CDB2200A96E2C /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
9499B5431AB242B200276D21 /* adaptivesleep.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = adaptivesleep.cpp; sourceTree = "<group>"; };
9499B5441AB242B200276D21 /* adaptivesleep.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = adaptivesleep.h; sourceTree = "<group>"; };
8F14C4F729FF7204000D080B /* memfile.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = memfile.h; sourceTree = "<group>"; };
8F14C4F829FF7217000D080B /* statesaver.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = statesaver.cpp; sourceTree = "<group>"; };
9499B5451AB242B200276D21 /* array.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = array.h; sourceTree = "<group>"; };
9499B5461AB242B200276D21 /* defined_ptr.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = defined_ptr.h; sourceTree = "<group>"; };
9499B5471AB242B200276D21 /* rateest.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = rateest.cpp; sourceTree = "<group>"; };
9499B5481AB242B200276D21 /* rateest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = rateest.h; sourceTree = "<group>"; };
9499B54A1AB242B200276D21 /* resampler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = resampler.h; sourceTree = "<group>"; };
9499B54B1AB242B200276D21 /* resamplerinfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = resamplerinfo.h; sourceTree = "<group>"; };
9499B54D1AB242B200276D21 /* blackmansinc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = blackmansinc.h; sourceTree = "<group>"; };
@@ -145,34 +143,14 @@
9499B5621AB242B200276D21 /* u48div.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = u48div.cpp; sourceTree = "<group>"; };
9499B5631AB242B200276D21 /* u48div.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = u48div.h; sourceTree = "<group>"; };
9499B5641AB242B200276D21 /* upsampler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = upsampler.h; sourceTree = "<group>"; };
9499B5651AB242B200276D21 /* ringbuffer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ringbuffer.h; sourceTree = "<group>"; };
9499B5661AB242B200276D21 /* scoped_ptr.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = scoped_ptr.h; sourceTree = "<group>"; };
9499B5671AB242B200276D21 /* skipsched.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = skipsched.cpp; sourceTree = "<group>"; };
9499B5681AB242B200276D21 /* skipsched.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = skipsched.h; sourceTree = "<group>"; };
9499B5691AB242B200276D21 /* transfer_ptr.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = transfer_ptr.h; sourceTree = "<group>"; };
9499B56A1AB242B200276D21 /* uncopyable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = uncopyable.h; sourceTree = "<group>"; };
9499B56B1AB242B200276D21 /* usec.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = usec.h; sourceTree = "<group>"; };
9499B56D1AB242B200276D21 /* rgb32conv.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = rgb32conv.cpp; sourceTree = "<group>"; };
9499B56E1AB242B200276D21 /* rgb32conv.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = rgb32conv.h; sourceTree = "<group>"; };
9499B56F1AB242B200276D21 /* vfilterinfo.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = vfilterinfo.cpp; sourceTree = "<group>"; };
9499B5701AB242B200276D21 /* vfilterinfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = vfilterinfo.h; sourceTree = "<group>"; };
9499B5721AB242B200276D21 /* catrom2x.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = catrom2x.cpp; sourceTree = "<group>"; };
9499B5731AB242B200276D21 /* catrom2x.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = catrom2x.h; sourceTree = "<group>"; };
9499B5741AB242B200276D21 /* catrom3x.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = catrom3x.cpp; sourceTree = "<group>"; };
9499B5751AB242B200276D21 /* catrom3x.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = catrom3x.h; sourceTree = "<group>"; };
9499B5761AB242B200276D21 /* kreed2xsai.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = kreed2xsai.cpp; sourceTree = "<group>"; };
9499B5771AB242B200276D21 /* kreed2xsai.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = kreed2xsai.h; sourceTree = "<group>"; };
9499B5781AB242B200276D21 /* maxsthq2x.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = maxsthq2x.cpp; sourceTree = "<group>"; };
9499B5791AB242B200276D21 /* maxsthq2x.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = maxsthq2x.h; sourceTree = "<group>"; };
9499B57A1AB242B200276D21 /* maxsthq3x.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = maxsthq3x.cpp; sourceTree = "<group>"; };
9499B57B1AB242B200276D21 /* maxsthq3x.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = maxsthq3x.h; sourceTree = "<group>"; };
9499B57C1AB242B200276D21 /* videolink.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = videolink.h; sourceTree = "<group>"; };
9499B57F1AB242B200276D21 /* gambatte.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = gambatte.h; sourceTree = "<group>"; };
9499B5801AB242B200276D21 /* gbint.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = gbint.h; sourceTree = "<group>"; };
9499B5811AB242B200276D21 /* inputgetter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = inputgetter.h; sourceTree = "<group>"; };
9499B5821AB242B200276D21 /* loadres.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = loadres.h; sourceTree = "<group>"; };
9499B5831AB242B200276D21 /* pakinfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = pakinfo.h; sourceTree = "<group>"; };
9499B5841AB242B200276D21 /* SConstruct */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = SConstruct; sourceTree = "<group>"; };
9499B5861AB242B200276D21 /* bitmap_font.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = bitmap_font.cpp; sourceTree = "<group>"; };
9499B5871AB242B200276D21 /* bitmap_font.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = bitmap_font.h; sourceTree = "<group>"; };
9499B5881AB242B200276D21 /* counterdef.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = counterdef.h; sourceTree = "<group>"; };
@@ -180,13 +158,7 @@
9499B58A1AB242B200276D21 /* cpu.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = cpu.h; sourceTree = "<group>"; };
9499B58C1AB242B200276D21 /* file.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = file.cpp; sourceTree = "<group>"; };
9499B58D1AB242B200276D21 /* file.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = file.h; sourceTree = "<group>"; };
9499B58E1AB242B200276D21 /* file_zip.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = file_zip.cpp; sourceTree = "<group>"; };
9499B58F1AB242B200276D21 /* stdfile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = stdfile.h; sourceTree = "<group>"; };
9499B5911AB242B200276D21 /* crypt.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = crypt.h; sourceTree = "<group>"; };
9499B5921AB242B200276D21 /* ioapi.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ioapi.c; sourceTree = "<group>"; };
9499B5931AB242B200276D21 /* ioapi.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ioapi.h; sourceTree = "<group>"; };
9499B5941AB242B200276D21 /* unzip.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = unzip.c; sourceTree = "<group>"; };
9499B5951AB242B200276D21 /* unzip.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = unzip.h; sourceTree = "<group>"; };
9499B5961AB242B200276D21 /* gambatte.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = gambatte.cpp; sourceTree = "<group>"; };
9499B5971AB242B200276D21 /* initstate.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = initstate.cpp; sourceTree = "<group>"; };
9499B5981AB242B200276D21 /* initstate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = initstate.h; sourceTree = "<group>"; };
@@ -239,7 +211,6 @@
9499B5CA1AB242B200276D21 /* ly_counter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ly_counter.h; sourceTree = "<group>"; };
9499B5CB1AB242B200276D21 /* lyc_irq.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = lyc_irq.cpp; sourceTree = "<group>"; };
9499B5CC1AB242B200276D21 /* lyc_irq.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = lyc_irq.h; sourceTree = "<group>"; };
9499B5CD1AB242B200276D21 /* m0_irq.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = m0_irq.h; sourceTree = "<group>"; };
9499B5CE1AB242B200276D21 /* next_m0_time.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = next_m0_time.cpp; sourceTree = "<group>"; };
9499B5CF1AB242B200276D21 /* next_m0_time.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = next_m0_time.h; sourceTree = "<group>"; };
9499B5D01AB242B200276D21 /* ppu.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ppu.cpp; sourceTree = "<group>"; };
@@ -252,7 +223,7 @@
B5EC4D410E6312DF0046BD93 /* GBGameCore.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GBGameCore.h; sourceTree = "<group>"; };
B5EC4D420E6312DF0046BD93 /* GBGameCore.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = GBGameCore.mm; sourceTree = "<group>"; };
B5F6D8A80E66914F001CA5D3 /* gameboy.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; path = gameboy.icns; sourceTree = "<group>"; };
C6B947DE1364FD0C00A425F0 /* OEGBSystemResponderClient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OEGBSystemResponderClient.h; path = ../OpenEmu/GameBoy/OEGBSystemResponderClient.h; sourceTree = "<group>"; };
C6B947DE1364FD0C00A425F0 /* OEGBSystemResponderClient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OEGBSystemResponderClient.h; path = ../OpenEmu/SystemPlugins/GameBoy/OEGBSystemResponderClient.h; sourceTree = "<group>"; };
C6D120ED1711308C00E868A8 /* OpenEmuBase.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = OpenEmuBase.framework; sourceTree = BUILT_PRODUCTS_DIR; };
/* End PBXFileReference section */
@@ -313,6 +284,7 @@
C6B947DE1364FD0C00A425F0 /* OEGBSystemResponderClient.h */,
B5EC4D410E6312DF0046BD93 /* GBGameCore.h */,
B5EC4D420E6312DF0046BD93 /* GBGameCore.mm */,
8F14C4F829FF7217000D080B /* statesaver.cpp */,
);
name = Classes;
sourceTree = "<group>";
@@ -344,26 +316,18 @@
name = Frameworks;
sourceTree = "<group>";
};
9499B5421AB242B200276D21 /* common */ = {
9499B5421AB242B200276D21 /* src */ = {
isa = PBXGroup;
children = (
9499B5431AB242B200276D21 /* adaptivesleep.cpp */,
9499B5441AB242B200276D21 /* adaptivesleep.h */,
9499B5451AB242B200276D21 /* array.h */,
9499B5461AB242B200276D21 /* defined_ptr.h */,
9499B5471AB242B200276D21 /* rateest.cpp */,
9499B5481AB242B200276D21 /* rateest.h */,
9499B5851AB242B200276D21 /* libgambatte */,
9499B5491AB242B200276D21 /* resample */,
9499B5651AB242B200276D21 /* ringbuffer.h */,
9499B5661AB242B200276D21 /* scoped_ptr.h */,
9499B5671AB242B200276D21 /* skipsched.cpp */,
9499B5681AB242B200276D21 /* skipsched.h */,
9499B5691AB242B200276D21 /* transfer_ptr.h */,
9499B56A1AB242B200276D21 /* uncopyable.h */,
9499B56B1AB242B200276D21 /* usec.h */,
9499B56C1AB242B200276D21 /* videolink */,
);
path = common;
path = src;
sourceTree = "<group>";
};
9499B5491AB242B200276D21 /* resample */ = {
@@ -371,14 +335,6 @@
children = (
9499B54A1AB242B200276D21 /* resampler.h */,
9499B54B1AB242B200276D21 /* resamplerinfo.h */,
9499B54C1AB242B200276D21 /* src */,
);
path = resample;
sourceTree = "<group>";
};
9499B54C1AB242B200276D21 /* src */ = {
isa = PBXGroup;
children = (
9499B54D1AB242B200276D21 /* blackmansinc.h */,
9499B54E1AB242B200276D21 /* chainresampler.cpp */,
9499B54F1AB242B200276D21 /* chainresampler.h */,
@@ -404,62 +360,10 @@
9499B5631AB242B200276D21 /* u48div.h */,
9499B5641AB242B200276D21 /* upsampler.h */,
);
path = src;
path = resample;
sourceTree = "<group>";
};
9499B56C1AB242B200276D21 /* videolink */ = {
isa = PBXGroup;
children = (
9499B56D1AB242B200276D21 /* rgb32conv.cpp */,
9499B56E1AB242B200276D21 /* rgb32conv.h */,
9499B56F1AB242B200276D21 /* vfilterinfo.cpp */,
9499B5701AB242B200276D21 /* vfilterinfo.h */,
9499B5711AB242B200276D21 /* vfilters */,
9499B57C1AB242B200276D21 /* videolink.h */,
);
path = videolink;
sourceTree = "<group>";
};
9499B5711AB242B200276D21 /* vfilters */ = {
isa = PBXGroup;
children = (
9499B5721AB242B200276D21 /* catrom2x.cpp */,
9499B5731AB242B200276D21 /* catrom2x.h */,
9499B5741AB242B200276D21 /* catrom3x.cpp */,
9499B5751AB242B200276D21 /* catrom3x.h */,
9499B5761AB242B200276D21 /* kreed2xsai.cpp */,
9499B5771AB242B200276D21 /* kreed2xsai.h */,
9499B5781AB242B200276D21 /* maxsthq2x.cpp */,
9499B5791AB242B200276D21 /* maxsthq2x.h */,
9499B57A1AB242B200276D21 /* maxsthq3x.cpp */,
9499B57B1AB242B200276D21 /* maxsthq3x.h */,
);
path = vfilters;
sourceTree = "<group>";
};
9499B57D1AB242B200276D21 /* libgambatte */ = {
isa = PBXGroup;
children = (
9499B57E1AB242B200276D21 /* include */,
9499B5841AB242B200276D21 /* SConstruct */,
9499B5851AB242B200276D21 /* src */,
);
path = libgambatte;
sourceTree = "<group>";
};
9499B57E1AB242B200276D21 /* include */ = {
isa = PBXGroup;
children = (
9499B57F1AB242B200276D21 /* gambatte.h */,
9499B5801AB242B200276D21 /* gbint.h */,
9499B5811AB242B200276D21 /* inputgetter.h */,
9499B5821AB242B200276D21 /* loadres.h */,
9499B5831AB242B200276D21 /* pakinfo.h */,
);
path = include;
sourceTree = "<group>";
};
9499B5851AB242B200276D21 /* src */ = {
9499B5851AB242B200276D21 /* libgambatte */ = {
isa = PBXGroup;
children = (
9499B5861AB242B200276D21 /* bitmap_font.cpp */,
@@ -469,19 +373,24 @@
9499B58A1AB242B200276D21 /* cpu.h */,
9499B58B1AB242B200276D21 /* file */,
9499B5961AB242B200276D21 /* gambatte.cpp */,
9499B57F1AB242B200276D21 /* gambatte.h */,
9499B5801AB242B200276D21 /* gbint.h */,
9499B5971AB242B200276D21 /* initstate.cpp */,
9499B5981AB242B200276D21 /* initstate.h */,
9499B5811AB242B200276D21 /* inputgetter.h */,
9499B5991AB242B200276D21 /* insertion_sort.h */,
9499B59A1AB242B200276D21 /* interrupter.cpp */,
9499B59B1AB242B200276D21 /* interrupter.h */,
9499B59C1AB242B200276D21 /* interruptrequester.cpp */,
9499B59D1AB242B200276D21 /* interruptrequester.h */,
9499B59E1AB242B200276D21 /* loadres.cpp */,
9499B5821AB242B200276D21 /* loadres.h */,
9499B59F1AB242B200276D21 /* mem */,
9499B5A81AB242B200276D21 /* memory.cpp */,
9499B5A91AB242B200276D21 /* memory.h */,
9499B5AA1AB242B200276D21 /* minkeeper.h */,
9499B5AB1AB242B200276D21 /* osd_element.h */,
9499B5831AB242B200276D21 /* pakinfo.h */,
9499B5AC1AB242B200276D21 /* savestate.h */,
9499B5AD1AB242B200276D21 /* sound */,
9499B5BF1AB242B200276D21 /* sound.cpp */,
@@ -496,7 +405,7 @@
9499B5D41AB242B200276D21 /* video.cpp */,
9499B5D51AB242B200276D21 /* video.h */,
);
path = src;
path = libgambatte;
sourceTree = "<group>";
};
9499B58B1AB242B200276D21 /* file */ = {
@@ -504,25 +413,12 @@
children = (
9499B58C1AB242B200276D21 /* file.cpp */,
9499B58D1AB242B200276D21 /* file.h */,
9499B58E1AB242B200276D21 /* file_zip.cpp */,
8F14C4F729FF7204000D080B /* memfile.h */,
9499B58F1AB242B200276D21 /* stdfile.h */,
9499B5901AB242B200276D21 /* unzip */,
);
path = file;
sourceTree = "<group>";
};
9499B5901AB242B200276D21 /* unzip */ = {
isa = PBXGroup;
children = (
9499B5911AB242B200276D21 /* crypt.h */,
9499B5921AB242B200276D21 /* ioapi.c */,
9499B5931AB242B200276D21 /* ioapi.h */,
9499B5941AB242B200276D21 /* unzip.c */,
9499B5951AB242B200276D21 /* unzip.h */,
);
path = unzip;
sourceTree = "<group>";
};
9499B59F1AB242B200276D21 /* mem */ = {
isa = PBXGroup;
children = (
@@ -570,7 +466,6 @@
9499B5CA1AB242B200276D21 /* ly_counter.h */,
9499B5CB1AB242B200276D21 /* lyc_irq.cpp */,
9499B5CC1AB242B200276D21 /* lyc_irq.h */,
9499B5CD1AB242B200276D21 /* m0_irq.h */,
9499B5CE1AB242B200276D21 /* next_m0_time.cpp */,
9499B5CF1AB242B200276D21 /* next_m0_time.h */,
9499B5D01AB242B200276D21 /* ppu.cpp */,
@@ -584,8 +479,7 @@
B5A6D9310E617C4900622CCF /* Core */ = {
isa = PBXGroup;
children = (
9499B5421AB242B200276D21 /* common */,
9499B57D1AB242B200276D21 /* libgambatte */,
9499B5421AB242B200276D21 /* src */,
);
name = Core;
sourceTree = "<group>";
@@ -616,7 +510,6 @@
2A37F4A9FDCFA73011CA2CEA /* Project object */ = {
isa = PBXProject;
attributes = {
BuildIndependentTargetsInParallel = YES;
LastUpgradeCheck = 1130;
};
buildConfigurationList = C05733CB08A9546B00998B17 /* Build configuration list for PBXProject "Gambatte" */;
@@ -703,7 +596,7 @@
9499B5F71AB242B300276D21 /* memory.cpp in Sources */,
9499B5FF1AB242B300276D21 /* sound.cpp in Sources */,
9499B6001AB242B300276D21 /* state_osd_elements.cpp in Sources */,
9499B6011AB242B300276D21 /* statesaver.cpp in Sources */,
8F14C4F929FF7217000D080B /* statesaver.cpp in Sources */,
9499B6021AB242B300276D21 /* tima.cpp in Sources */,
9499B6081AB242B300276D21 /* video.cpp in Sources */,
9499B5F31AB242B300276D21 /* cartridge.cpp in Sources */,
@@ -867,6 +760,7 @@
GCC_INCREASE_PRECOMPILED_HEADER_SHARING = YES;
GCC_NO_COMMON_BLOCKS = YES;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_PREPROCESSOR_DEFINITIONS = GL_SILENCE_DEPRECATION;
GCC_SYMBOLS_PRIVATE_EXTERN = YES;
GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
@@ -913,6 +807,7 @@
GCC_INCREASE_PRECOMPILED_HEADER_SHARING = YES;
GCC_NO_COMMON_BLOCKS = YES;
GCC_OPTIMIZATION_LEVEL = 3;
GCC_PREPROCESSOR_DEFINITIONS = GL_SILENCE_DEPRECATION;
GCC_SYMBOLS_PRIVATE_EXTERN = YES;
GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+3 -3
View File
@@ -3,7 +3,7 @@
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>English</string>
<string>$(DEVELOPMENT_LANGUAGE)</string>
<key>CFBundleExecutable</key>
<string>${EXECUTABLE_NAME}</string>
<key>CFBundleIconFile</key>
@@ -17,7 +17,7 @@
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>0.5.0.689</string>
<string>0.5.1</string>
<key>NSPrincipalClass</key>
<string>OEGameCoreController</string>
<key>OEGameCoreClass</key>
@@ -41,7 +41,7 @@
<key>OEGameCorePlayerCount</key>
<string>1</string>
<key>OEProjectURL</key>
<string>https://github.com/sinamas/gambatte</string>
<string>https://gitlab.com/jgemu/gambatte</string>
<key>OESystemIdentifiers</key>
<array>
<string>openemu.system.gb</string>
+58
View File
@@ -0,0 +1,58 @@
Gambatte JG
-----------
Gambatte JG is an emulator for the Nintendo Game Boy/Game Boy Color.
This is a fork of the final public revision of Gambatte.
This repository lives at https://gitlab.com/jgemu/gambatte
Compiling
---------
Make sure you have The Jolly Good API's header files installed. If you did
not install them, you will be required to include their path in CXXFLAGS.
GNU Make's default behaviour for compiling C++ sources is to use g++. If your
platform of choice uses an unpatched GNU Make, you will need to override the
CXX implicit variable if you wish to use a different compiler.
Options:
USE_VENDORED_SOXR - Set non-zero to use vendored soxr
Linux:
make
macOS:
make
BSD:
gmake
Windows (MSYS2):
make
The build will be output to "gambatte/". This directory may be used as is
locally by copying it to your local "cores" directory, or may be installed
system-wide using the "install" target specified in the Makefile.
Settings
--------
palette = 0
0 = Internal, 1 = Original Green, 2 = GB Pocket, 3 = Blue, 4 = Brown,
5 = Dark Blue, 6 = Dark Brown, 7 = Dark Green, 8 = Grayscale, 9 = Green,
10 = Inverted, 11 = Orange, 12 = Pastel Mix, 13 = Red, 14 = Yellow
system = 0
0 = Auto (CGB), 1 = DMG, 2 = GBA-CGB
turbo_rate = 3
N = Pulse every N frames
Copyright
---------
Gambatte JG (GPL-2.0-or-later)
Copyright (c) 2007-2020 Sindre Aamås
Copyright (c) 2020-2022 Rupert Carmichael
SoX Resampler Library (LGPL-2.1-or-later)
Copyright (c) 2007-2018 Rob Sykes
See source files in deps/soxr/ (https://sourceforge.net/projects/soxr/)
-52
View File
@@ -1,52 +0,0 @@
/***************************************************************************
* Copyright (C) 2008 by Sindre Aamås *
* sinamas@users.sourceforge.net *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License version 2 as *
* published by the Free Software Foundation. *
* *
* 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 version 2 for more details. *
* *
* You should have received a copy of the GNU General Public License *
* version 2 along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
***************************************************************************/
#include "adaptivesleep.h"
static usec_t absdiff(usec_t a, usec_t b) { return a < b ? b - a : a - b; }
usec_t AdaptiveSleep::sleepUntil(usec_t base, usec_t inc) {
usec_t now = getusecs();
usec_t diff = now - base;
if (diff >= inc)
return diff - inc;
diff = inc - diff;
if (diff > oversleep_ + oversleepVar_) {
diff -= oversleep_ + oversleepVar_;
usecsleep(diff);
usec_t const sleepTarget = now + diff;
now = getusecs();
usec_t curOversleep = now - sleepTarget;
if (curOversleep > usec_t(-1) / 2)
curOversleep = 0;
oversleepVar_ = (oversleepVar_ * 15 + absdiff(curOversleep, oversleep_) + 8) >> 4;
oversleep_ = (oversleep_ * 15 + curOversleep + 8) >> 4;
noSleep_ = 60;
} else if (--noSleep_ == 0) {
noSleep_ = 60;
oversleep_ = oversleepVar_ = 0;
}
while (now - base < inc)
now = getusecs();
return 0;
}
-35
View File
@@ -1,35 +0,0 @@
/***************************************************************************
* Copyright (C) 2008 by Sindre Aamås *
* sinamas@users.sourceforge.net *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License version 2 as *
* published by the Free Software Foundation. *
* *
* 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 version 2 for more details. *
* *
* You should have received a copy of the GNU General Public License *
* version 2 along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
***************************************************************************/
#ifndef ADAPTIVE_SLEEP_H
#define ADAPTIVE_SLEEP_H
#include "usec.h"
class AdaptiveSleep {
public:
AdaptiveSleep() : oversleep_(0), oversleepVar_(0), noSleep_(60) {}
usec_t sleepUntil(usec_t base, usec_t inc);
private:
usec_t oversleep_;
usec_t oversleepVar_;
unsigned noSleep_;
};
#endif
-91
View File
@@ -1,91 +0,0 @@
/***************************************************************************
* Copyright (C) 2008 by Sindre Aamås *
* sinamas@users.sourceforge.net *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License version 2 as *
* published by the Free Software Foundation. *
* *
* 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 version 2 for more details. *
* *
* You should have received a copy of the GNU General Public License *
* version 2 along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
***************************************************************************/
#include "rateest.h"
#include <cstdlib>
void RateEst::SumQueue::push(std::ptrdiff_t const samples, usec_t const usecs) {
q_.push_back(std::make_pair(samples, usecs));
samples_ += samples;
usecs_ += usecs;
}
void RateEst::SumQueue::pop() {
std::pair<std::ptrdiff_t, usec_t> const &f = q_.front();
samples_ -= f.first;
usecs_ -= f.second;
q_.pop_front();
}
static usec_t sampleUsecs(std::ptrdiff_t samples, long rate) {
return usec_t((samples * 1000000.0f) / (rate ? rate : 1) + 0.5f);
}
static long limit(long est, long const reference) {
if (est > reference + (reference >> 6))
est = reference + (reference >> 6);
else if (est < reference - (reference >> 6))
est = reference - (reference >> 6);
return est;
}
RateEst::RateEst(long const nominalSampleRate, std::size_t const maxValidFeedPeriodSamples)
: srate_(nominalSampleRate * est_scale)
, reference_(srate_)
, maxPeriod_(sampleUsecs(maxValidFeedPeriodSamples, nominalSampleRate))
, last_(0)
, t_(6000)
, s_(nominalSampleRate * 6)
, st_(s_ * t_)
, t2_(t_ * t_)
{
}
void RateEst::feed(std::ptrdiff_t samplesIn, usec_t const now) {
usec_t usecsIn = now - last_;
if (last_ && usecsIn < maxPeriod_) {
sumq_.push(samplesIn, usecsIn);
while ((usecsIn = sumq_.usecs()) > 100000) {
samplesIn = sumq_.samples();
sumq_.pop();
long const srateIn = long(samplesIn * (1000000.0f * est_scale) / usecsIn);
if (std::abs(srateIn - reference_) < reference_ >> 1) {
s_ += samplesIn - sumq_.samples() ;
t_ += ( usecsIn - sumq_.usecs() ) * 0.001;
st_ += s_ * t_;
t2_ += t_ * t_;
long est = long(st_ * (1000.0 * est_scale) / t2_ + 0.5);
srate_ = limit((srate_ * 31 + est + 16) >> 5, reference_);
if (t_ > 8000) {
s_ *= 3.0 / 4;
t_ *= 3.0 / 4;
st_ *= 9.0 / 16;
t2_ *= 9.0 / 16;
}
}
}
}
last_ = now;
}
-61
View File
@@ -1,61 +0,0 @@
/***************************************************************************
* Copyright (C) 2008 by Sindre Aamås *
* sinamas@users.sourceforge.net *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License version 2 as *
* published by the Free Software Foundation. *
* *
* 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 version 2 for more details. *
* *
* You should have received a copy of the GNU General Public License *
* version 2 along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
***************************************************************************/
#ifndef RATEEST_H
#define RATEEST_H
#include "usec.h"
#include <cstddef>
#include <deque>
#include <utility>
class RateEst {
public:
RateEst() { *this = RateEst(0, 0); }
RateEst(long nominalSampleRate, std::size_t maxValidFeedPeriodSamples);
void resetLastFeedTimeStamp() { last_ = 0; }
void feed(std::ptrdiff_t samples, usec_t usecsNow = getusecs());
long result() const { return (srate_ + est_scale / 2) >> est_lshift; }
private:
class SumQueue {
public:
SumQueue() : samples_(0), usecs_(0) {}
std::ptrdiff_t samples() const { return samples_; }
usec_t usecs() const { return usecs_; }
void push(std::ptrdiff_t samples, usec_t usecs);
void pop();
private:
std::deque< std::pair<std::ptrdiff_t, usec_t> > q_;
std::ptrdiff_t samples_;
usec_t usecs_;
};
enum { est_lshift = 5 };
enum { est_scale = 1 << est_lshift };
SumQueue sumq_;
long srate_;
long reference_;
usec_t maxPeriod_;
usec_t last_;
double t_, s_, st_, t2_;
};
#endif
-109
View File
@@ -1,109 +0,0 @@
/***************************************************************************
* Copyright (C) 2008 by Sindre Aamås *
* sinamas@users.sourceforge.net *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License version 2 as *
* published by the Free Software Foundation. *
* *
* 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 version 2 for more details. *
* *
* You should have received a copy of the GNU General Public License *
* version 2 along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
***************************************************************************/
#ifndef RINGBUFFER_H
#define RINGBUFFER_H
#include "array.h"
#include <algorithm>
#include <cstddef>
#include <cstring>
template<typename T>
class RingBuffer {
public:
explicit RingBuffer(std::size_t size = 0)
: endpos_(0), rpos_(0), wpos_(0)
{
reset(size);
}
void reset(std::size_t size);
void clear() {
wpos_ = rpos_ = 0;
}
void fill(T value);
void read(T *out, std::size_t num);
void write(T const *in, std::size_t num);
std::size_t avail() const {
return (wpos_ < rpos_ ? 0 : endpos_) + rpos_ - wpos_ - 1;
}
std::size_t used() const {
return (wpos_ < rpos_ ? endpos_ : 0) + wpos_ - rpos_;
}
std::size_t size() const {
return endpos_ - 1;
}
private:
Array<T> buf_;
std::size_t endpos_;
std::size_t rpos_;
std::size_t wpos_;
};
template<typename T>
void RingBuffer<T>::reset(std::size_t size) {
endpos_ = size + 1;
rpos_ = wpos_ = 0;
buf_.reset(size ? endpos_ : 0);
}
template<typename T>
void RingBuffer<T>::fill(T value) {
std::fill(buf_.get(), buf_.get() + buf_.size(), value);
rpos_ = 0;
wpos_ = endpos_ - 1;
}
template<typename T>
void RingBuffer<T>::read(T *out, std::size_t num) {
if (rpos_ + num > endpos_) {
std::size_t const n = endpos_ - rpos_;
std::memcpy(out, buf_ + rpos_, n * sizeof *out);
rpos_ = 0;
num -= n;
out += n;
}
std::memcpy(out, buf_ + rpos_, num * sizeof *out);
if ((rpos_ += num) == endpos_)
rpos_ = 0;
}
template<typename T>
void RingBuffer<T>::write(T const *in, std::size_t num) {
if (wpos_ + num > endpos_) {
std::size_t const n = endpos_ - wpos_;
std::memcpy(buf_ + wpos_, in, n * sizeof *buf_);
wpos_ = 0;
num -= n;
in += n;
}
std::memcpy(buf_ + wpos_, in, num * sizeof *buf_);
if ((wpos_ += num) == endpos_)
wpos_ = 0;
}
#endif
-35
View File
@@ -1,35 +0,0 @@
/***************************************************************************
* Copyright (C) 2008 by Sindre Aamås *
* sinamas@users.sourceforge.net *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License version 2 as *
* published by the Free Software Foundation. *
* *
* 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 version 2 for more details. *
* *
* You should have received a copy of the GNU General Public License *
* version 2 along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
***************************************************************************/
#include "skipsched.h"
bool SkipSched::skipNext(bool skip) {
if (skipped_) {
if (skipped_ < skippedmax_ / 2)
skip = true;
else
skipped_ = skip = 0;
} else if (skip) {
skippedmax_ += skippedmax_ / 2 < 8;
} else if (skippedmax_ / 2)
--skippedmax_;
skipped_ += skip;
return skip;
}
-32
View File
@@ -1,32 +0,0 @@
/***************************************************************************
* Copyright (C) 2008 by Sindre Aamås *
* sinamas@users.sourceforge.net *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License version 2 as *
* published by the Free Software Foundation. *
* *
* 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 version 2 for more details. *
* *
* You should have received a copy of the GNU General Public License *
* version 2 along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
***************************************************************************/
#ifndef SKIPSCHED_H
#define SKIPSCHED_H
class SkipSched {
public:
SkipSched() : skipped_(0), skippedmax_(2 - 1) {}
bool skipNext(bool wantskip);
private:
unsigned skipped_;
unsigned skippedmax_;
};
#endif
-27
View File
@@ -1,27 +0,0 @@
/***************************************************************************
* Copyright (C) 2008 by Sindre Aamås *
* sinamas@users.sourceforge.net *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License version 2 as *
* published by the Free Software Foundation. *
* *
* 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 version 2 for more details. *
* *
* You should have received a copy of the GNU General Public License *
* version 2 along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
***************************************************************************/
#ifndef USEC_H
#define USEC_H
typedef unsigned long usec_t;
usec_t getusecs();
void usecsleep(usec_t usecs);
#endif
-199
View File
@@ -1,199 +0,0 @@
/***************************************************************************
* Copyright (C) 2009 by Sindre Aamås *
* sinamas@users.sourceforge.net *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License version 2 as *
* published by the Free Software Foundation. *
* *
* 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 version 2 for more details. *
* *
* You should have received a copy of the GNU General Public License *
* version 2 along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
***************************************************************************/
#include "rgb32conv.h"
#include "array.h"
#include "gbint.h"
#include "videolink.h"
#include <algorithm>
namespace {
static bool isBigEndian() {
union {
gambatte::uint_least32_t ul32;
unsigned char uc[sizeof(gambatte::uint_least32_t)];
} u;
u.ul32 = -0x10000;
return u.uc[0];
}
class Rgb32ToUyvy {
public:
Rgb32ToUyvy();
void operator()(gambatte::uint_least32_t *d, std::ptrdiff_t dstPitch,
gambatte::uint_least32_t const *s, std::ptrdiff_t srcPitch,
unsigned w, unsigned h);
private:
struct CacheUnit {
gambatte::uint_least32_t rgb32;
gambatte::uint_least32_t uyvy;
};
enum { cache_size = 0x100 };
enum { cache_mask = cache_size - 1 };
CacheUnit cache_[cache_size];
};
Rgb32ToUyvy::Rgb32ToUyvy() {
if (isBigEndian()) {
CacheUnit c = { 0, 128ul << 24 | 16ul << 16 | 128u << 8 | 16 };
std::fill(cache_, cache_ + cache_size, c);
} else {
CacheUnit c = { 0, 16ul << 24 | 128ul << 16 | 16 << 8 | 128 };
std::fill(cache_, cache_ + cache_size, c);
}
}
void Rgb32ToUyvy::operator()(gambatte::uint_least32_t *dst,
std::ptrdiff_t const dstPitch,
gambatte::uint_least32_t const *src,
std::ptrdiff_t const srcPitch,
unsigned const w,
unsigned h)
{
while (h--) {
gambatte::uint_least32_t *d = dst;
gambatte::uint_least32_t const *s = src;
gambatte::uint_least32_t const *const sEnd = s + w - 1;
while (s < sEnd) {
if ((cache_[s[0] & cache_mask].rgb32 - s[0]) | (cache_[s[1] & cache_mask].rgb32 - s[1])) {
cache_[s[0] & cache_mask].rgb32 = s[0];
cache_[s[1] & cache_mask].rgb32 = s[1];
unsigned long const r = (s[0] >> 16 & 0x000000FF) | (s[1] & 0x00FF0000);
unsigned long const g = (s[0] >> 8 & 0x000000FF) | (s[1] << 8 & 0x00FF0000);
unsigned long const b = (s[0] & 0x000000FF) | (s[1] << 16 & 0x00FF0000);
unsigned long const y = r * 66 + g * 129 + b * 25 + ( 16 * 256u + 128) * 0x00010001ul;
unsigned long const u = b * 112 - r * 38 - g * 74 + (128 * 256u + 128) * 0x00010001ul;
unsigned long const v = r * 112 - g * 94 - b * 18 + (128 * 256u + 128) * 0x00010001ul;
if (isBigEndian()) {
d[0] = cache_[s[0] & cache_mask].uyvy = (u << 16 & 0xFF000000)
| (y << 8 & 0x00FF0000)
| (v & 0x0000FF00)
| (y >> 8 & 0x000000FF);
d[1] = cache_[s[1] & cache_mask].uyvy = (u & 0xFF000000)
| (y >> 8 & 0x00FF0000)
| (v >> 16 & 0x0000FF00)
| y >> 24 ;
} else {
d[0] = cache_[s[0] & cache_mask].uyvy = (y << 16 & 0xFF000000)
| (v << 8 & 0x00FF0000)
| (y & 0x0000FF00)
| (u >> 8 & 0x000000FF);
d[1] = cache_[s[1] & cache_mask].uyvy = (y & 0xFF000000)
| (v >> 8 & 0x00FF0000)
| (y >> 16 & 0x0000FF00)
| u >> 24 ;
}
} else {
gambatte::uint_least32_t const s0 = s[0], s1 = s[1];
d[0] = cache_[s0 & cache_mask].uyvy;
d[1] = cache_[s1 & cache_mask].uyvy;
}
s += 2;
d += 2;
}
src += srcPitch;
dst += dstPitch;
}
}
static void rgb32ToRgb16(gambatte::uint_least16_t *d,
std::ptrdiff_t const dstPitch,
gambatte::uint_least32_t const *s,
std::ptrdiff_t const srcPitch,
unsigned const w,
unsigned h)
{
do {
std::ptrdiff_t i = -static_cast<std::ptrdiff_t>(w);
s += w;
d += w;
do {
d[i] = (s[i] >> 8 & 0xF800) | (s[i] & 0xFC00) >> 5 | (s[i] & 0xFF) >> 3;
} while (++i);
s += srcPitch - static_cast<std::ptrdiff_t>(w);
d += dstPitch - static_cast<std::ptrdiff_t>(w);
} while (--h);
}
class Rgb32ToUyvyLink : public VideoLink {
public:
Rgb32ToUyvyLink(unsigned width, unsigned height)
: inbuf_(static_cast<std::size_t>(width) * height)
, width_(width)
, height_(height)
{
}
virtual void * inBuf() const { return inbuf_; }
virtual std::ptrdiff_t inPitch() const { return width_; }
virtual void draw(void *dst, std::ptrdiff_t dstPitch) {
rgb32ToUyvy_(static_cast<gambatte::uint_least32_t *>(dst), dstPitch,
inbuf_, width_, width_, height_);
}
private:
SimpleArray<gambatte::uint_least32_t> const inbuf_;
Rgb32ToUyvy rgb32ToUyvy_;
unsigned const width_;
unsigned const height_;
};
class Rgb32ToRgb16Link : public VideoLink {
public:
Rgb32ToRgb16Link(unsigned width, unsigned height)
: inbuf_(static_cast<std::size_t>(width) * height)
, width_(width)
, height_(height)
{
}
virtual void * inBuf() const { return inbuf_; }
virtual std::ptrdiff_t inPitch() const { return width_; }
virtual void draw(void *dst, std::ptrdiff_t dstPitch) {
if (!inbuf_)
return;
rgb32ToRgb16(static_cast<gambatte::uint_least16_t *>(dst), dstPitch,
inbuf_, width_, width_, height_);
}
private:
SimpleArray<gambatte::uint_least32_t> const inbuf_;
unsigned const width_;
unsigned const height_;
};
} // anon namespace
VideoLink * Rgb32Conv::create(PixelFormat pf, unsigned width, unsigned height) {
switch (pf) {
case RGB16: return new Rgb32ToRgb16Link(width, height);
case UYVY: return new Rgb32ToUyvyLink(width, height);
default: return 0;
}
}
-30
View File
@@ -1,30 +0,0 @@
/***************************************************************************
* Copyright (C) 2009 by Sindre Aamås *
* sinamas@users.sourceforge.net *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License version 2 as *
* published by the Free Software Foundation. *
* *
* 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 version 2 for more details. *
* *
* You should have received a copy of the GNU General Public License *
* version 2 along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
***************************************************************************/
#ifndef RGB32CONV_H
#define RGB32CONV_H
class VideoLink;
class Rgb32Conv {
public:
enum PixelFormat { RGB32, RGB16, UYVY };
static VideoLink * create(PixelFormat pf, unsigned width, unsigned height);
};
#endif
-48
View File
@@ -1,48 +0,0 @@
/***************************************************************************
* Copyright (C) 2009 by Sindre Aamås *
* sinamas@users.sourceforge.net *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License version 2 as *
* published by the Free Software Foundation. *
* *
* 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 version 2 for more details. *
* *
* You should have received a copy of the GNU General Public License *
* version 2 along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
***************************************************************************/
#include "vfilterinfo.h"
#include "vfilters/catrom2x.h"
#include "vfilters/catrom3x.h"
#include "vfilters/kreed2xsai.h"
#include "vfilters/maxsthq2x.h"
#include "vfilters/maxsthq3x.h"
static VideoLink * createNone() { return 0; }
template<class T>
static VideoLink * createT() { return new T; }
#define VFINFO(handle, Type) { handle, Type::out_width, Type::out_height, createT<Type> }
static VfilterInfo const vfinfos[] = {
{ "None", VfilterInfo::in_width, VfilterInfo::in_height, createNone },
VFINFO("Bicubic Catmull-Rom spline 2x", Catrom2x),
VFINFO("Bicubic Catmull-Rom spline 3x", Catrom3x),
VFINFO("Kreed's 2xSaI", Kreed2xSaI),
VFINFO("MaxSt's hq2x", MaxStHq2x),
VFINFO("MaxSt's hq3x", MaxStHq3x),
};
std::size_t VfilterInfo::numVfilters() {
return sizeof vfinfos / sizeof vfinfos[0];
}
VfilterInfo const & VfilterInfo::get(std::size_t n) {
return vfinfos[n];
}
-39
View File
@@ -1,39 +0,0 @@
/***************************************************************************
* Copyright (C) 2009 by Sindre Aamås *
* sinamas@users.sourceforge.net *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License version 2 as *
* published by the Free Software Foundation. *
* *
* 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 version 2 for more details. *
* *
* You should have received a copy of the GNU General Public License *
* version 2 along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
***************************************************************************/
#ifndef VFILTERINFO_H
#define VFILTERINFO_H
#include <cstddef>
class VideoLink;
struct VfilterInfo {
enum { in_width = 160 };
enum { in_height = 144 };
char const *handle;
unsigned outWidth;
unsigned outHeight;
VideoLink * (*create)();
static VfilterInfo const & get(std::size_t n);
static std::size_t numVfilters();
};
#endif
-179
View File
@@ -1,179 +0,0 @@
/***************************************************************************
* Copyright (C) 2007 by Sindre Aamås *
* sinamas@users.sourceforge.net *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License version 2 as *
* published by the Free Software Foundation. *
* *
* 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 version 2 for more details. *
* *
* You should have received a copy of the GNU General Public License *
* version 2 along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
***************************************************************************/
#include "catrom2x.h"
#include <algorithm>
namespace {
enum { in_width = VfilterInfo::in_width };
enum { in_height = VfilterInfo::in_height };
enum { in_pitch = in_width + 3 };
struct Colorsum {
gambatte::uint_least32_t r, g, b;
};
static void mergeColumns(gambatte::uint_least32_t *dest, Colorsum const *sums) {
for (unsigned w = in_width; w--;) {
{
gambatte::uint_least32_t rsum = sums[1].r;
gambatte::uint_least32_t gsum = sums[1].g;
gambatte::uint_least32_t bsum = sums[1].b;
if (rsum >= 0x80000000) rsum = 0;
if (gsum >= 0x80000000) gsum = 0;
if (bsum >= 0x80000000) bsum = 0;
rsum <<= 12;
rsum += 0x008000;
gsum >>= 4;
gsum += 0x0080;
bsum += 0x0008;
bsum >>= 4;
if (rsum > 0xFF0000) rsum = 0xFF0000;
if (gsum > 0x00FF00) gsum = 0x00FF00;
if (bsum > 0x0000FF) bsum = 0x0000FF;
*dest++ = (rsum & 0xFF0000) | (gsum & 0x00FF00) | bsum;
}
{
gambatte::uint_least32_t rsum = sums[1].r * 9;
gambatte::uint_least32_t gsum = sums[1].g * 9;
gambatte::uint_least32_t bsum = sums[1].b * 9;
rsum -= sums[0].r;
gsum -= sums[0].g;
bsum -= sums[0].b;
rsum += sums[2].r * 9;
gsum += sums[2].g * 9;
bsum += sums[2].b * 9;
rsum -= sums[3].r;
gsum -= sums[3].g;
bsum -= sums[3].b;
if (rsum >= 0x80000000) rsum = 0;
if (gsum >= 0x80000000) gsum = 0;
if (bsum >= 0x80000000) bsum = 0;
rsum <<= 8;
rsum += 0x008000;
gsum >>= 8;
gsum += 0x000080;
bsum += 0x000080;
bsum >>= 8;
if (rsum > 0xFF0000) rsum = 0xFF0000;
if (gsum > 0x00FF00) gsum = 0x00FF00;
if (bsum > 0x0000FF) bsum = 0x0000FF;
*dest++ = (rsum & 0xFF0000) | (gsum & 0x00FF00) | bsum;
}
++sums;
}
}
static void filter(gambatte::uint_least32_t *dline,
std::ptrdiff_t const pitch,
gambatte::uint_least32_t const *sline)
{
Colorsum sums[in_pitch];
for (unsigned h = in_height; h--;) {
{
gambatte::uint_least32_t const *s = sline;
Colorsum *sum = sums;
unsigned n = in_pitch;
while (n--) {
unsigned long pixel = *s;
sum->r = pixel >> 12 & 0x000FF0 ;
pixel <<= 4;
sum->g = pixel & 0x0FF000;
sum->b = pixel & 0x000FF0;
++s;
++sum;
}
}
mergeColumns(dline, sums);
dline += pitch;
{
gambatte::uint_least32_t const *s = sline;
Colorsum *sum = sums;
unsigned n = in_pitch;
while (n--) {
unsigned long pixel = *s;
unsigned long rsum = (pixel >> 16) * 9;
unsigned long gsum = (pixel & 0x00FF00) * 9;
unsigned long bsum = (pixel & 0x0000FF) * 9;
pixel = s[-1 * in_pitch];
rsum -= pixel >> 16;
gsum -= pixel & 0x00FF00;
bsum -= pixel & 0x0000FF;
pixel = s[1 * in_pitch];
rsum += (pixel >> 16) * 9;
gsum += (pixel & 0x00FF00) * 9;
bsum += (pixel & 0x0000FF) * 9;
pixel = s[2 * in_pitch];
rsum -= pixel >> 16;
gsum -= pixel & 0x00FF00;
bsum -= pixel & 0x0000FF;
sum->r = rsum;
sum->g = gsum;
sum->b = bsum;
++s;
++sum;
}
}
mergeColumns(dline, sums);
dline += pitch;
sline += in_pitch;
}
}
} // anon namespace
Catrom2x::Catrom2x()
: buffer_((in_height + 3UL) * in_pitch)
{
std::fill_n(buffer_.get(), buffer_.size(), 0);
}
void * Catrom2x::inBuf() const {
return buffer_ + in_pitch + 1;
}
std::ptrdiff_t Catrom2x::inPitch() const {
return in_pitch;
}
void Catrom2x::draw(void *dbuffer, std::ptrdiff_t pitch) {
::filter(static_cast<gambatte::uint_least32_t *>(dbuffer), pitch, buffer_ + in_pitch);
}
-41
View File
@@ -1,41 +0,0 @@
/***************************************************************************
* Copyright (C) 2009 by Sindre Aamås *
* sinamas@users.sourceforge.net *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License version 2 as *
* published by the Free Software Foundation. *
* *
* 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 version 2 for more details. *
* *
* You should have received a copy of the GNU General Public License *
* version 2 along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
***************************************************************************/
#ifndef CATROM2X_H
#define CATROM2X_H
#include "../videolink.h"
#include "../vfilterinfo.h"
#include "array.h"
#include "gbint.h"
class Catrom2x : public VideoLink {
public:
enum { out_width = VfilterInfo::in_width * 2 };
enum { out_height = VfilterInfo::in_height * 2 };
Catrom2x();
virtual void * inBuf() const;
virtual std::ptrdiff_t inPitch() const;
virtual void draw(void *dst, std::ptrdiff_t dstpitch);
private:
Array<gambatte::uint_least32_t> const buffer_;
};
#endif
-345
View File
@@ -1,345 +0,0 @@
/***************************************************************************
* Copyright (C) 2007 by Sindre Aamås *
* sinamas@users.sourceforge.net *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License version 2 as *
* published by the Free Software Foundation. *
* *
* 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 version 2 for more details. *
* *
* You should have received a copy of the GNU General Public License *
* version 2 along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
***************************************************************************/
#include "catrom3x.h"
#include <algorithm>
namespace {
enum { in_width = VfilterInfo::in_width };
enum { in_height = VfilterInfo::in_height };
enum { in_pitch = in_width + 3 };
struct Colorsum {
gambatte::uint_least32_t r, g, b;
};
static void mergeColumns(gambatte::uint_least32_t *dest, Colorsum const *sums) {
for (unsigned w = in_width; w--;) {
{
gambatte::uint_least32_t rsum = sums[1].r;
gambatte::uint_least32_t gsum = sums[1].g;
gambatte::uint_least32_t bsum = sums[1].b;
if (rsum >= 0x80000000) {
rsum = 0;
} else if (rsum > 6869) {
rsum = 0xFF0000;
} else {
rsum *= 607;
rsum <<= 2;
rsum += 0x008000;
rsum &= 0xFF0000;
}
if (gsum >= 0x80000000) {
gsum = 0;
} else if (gsum > 1758567) {
gsum = 0xFF00;
} else {
gsum *= 607;
gsum >>= 14;
gsum += 0x000080;
gsum &= 0x00FF00;
}
if (bsum >= 0x80000000) {
bsum = 0;
} else if (bsum > 6869) {
bsum = 0xFF;
} else {
bsum *= 607;
bsum += 8192;
bsum >>= 14;
}
/*rsum/=27;
rsum<<=8;
gsum/=27;
gsum<<=5;
bsum<<=4;
bsum+=27;
bsum/=54;
rsum+=0x008000;
gsum+=0x000080;
if(rsum>0xFF0000) rsum=0xFF0000;
if(gsum>0x00FF00) gsum=0x00FF00;
if(bsum>0x0000FF) bsum=0x0000FF;*/
*dest++ = rsum/*&0xFF0000*/ | gsum/*&0x00FF00*/ | bsum;
}
{
gambatte::uint_least32_t rsum = sums[1].r * 21;
gambatte::uint_least32_t gsum = sums[1].g * 21;
gambatte::uint_least32_t bsum = sums[1].b * 21;
rsum -= sums[0].r << 1;
gsum -= sums[0].g << 1;
bsum -= sums[0].b << 1;
rsum += sums[2].r * 9;
gsum += sums[2].g * 9;
bsum += sums[2].b * 9;
rsum -= sums[3].r;
gsum -= sums[3].g;
bsum -= sums[3].b;
if (rsum >= 0x80000000) {
rsum = 0;
} else if (rsum > 185578) {
rsum = 0xFF0000;
} else {
rsum *= 719;
rsum >>= 3;
rsum += 0x008000;
rsum &= 0xFF0000;
}
if (gsum >= 0x80000000) {
gsum = 0;
} else if (gsum > 47508223) {
gsum = 0x00FF00;
} else {
gsum >>= 8;
gsum *= 719;
gsum >>= 11;
gsum += 0x000080;
gsum &= 0x00FF00;
}
if (bsum >= 0x80000000) {
bsum = 0;
} else if (bsum > 185578) {
bsum = 0x0000FF;
} else {
bsum *= 719;
bsum += 0x040000;
bsum >>= 19;
}
/*rsum/=729;
rsum<<=8;
gsum/=729;
gsum<<=5;
bsum<<=4;
bsum+=729;
bsum/=1458;
rsum+=0x008000;
gsum+=0x000080;
if(rsum>0xFF0000) rsum=0xFF0000;
if(gsum>0x00FF00) gsum=0x00FF00;
if(bsum>0x0000FF) bsum=0x0000FF;*/
*dest++ = rsum/*&0xFF0000*/ | gsum/*&0x00FF00*/ | bsum;
}
{
gambatte::uint_least32_t rsum = sums[1].r * 9;
gambatte::uint_least32_t gsum = sums[1].g * 9;
gambatte::uint_least32_t bsum = sums[1].b * 9;
rsum -= sums[0].r;
gsum -= sums[0].g;
bsum -= sums[0].b;
rsum += sums[2].r * 21;
gsum += sums[2].g * 21;
bsum += sums[2].b * 21;
rsum -= sums[3].r << 1;
gsum -= sums[3].g << 1;
bsum -= sums[3].b << 1;
if (rsum >= 0x80000000) {
rsum = 0;
} else if (rsum > 185578) {
rsum = 0xFF0000;
} else {
rsum *= 719;
rsum >>= 3;
rsum += 0x008000;
rsum &= 0xFF0000;
}
if (gsum >= 0x80000000) {
gsum = 0;
} else if (gsum > 47508223) {
gsum = 0xFF00;
} else {
gsum >>= 8;
gsum *= 719;
gsum >>= 11;
gsum += 0x000080;
gsum &= 0x00FF00;
}
if (bsum >= 0x80000000) {
bsum = 0;
} else if (bsum > 185578) {
bsum = 0x0000FF;
} else {
bsum *= 719;
bsum += 0x040000;
bsum >>= 19;
}
/*rsum/=729;
rsum<<=8;
gsum/=729;
gsum<<=5;
bsum<<=4;
bsum+=729;
bsum/=1458;
rsum+=0x008000;
gsum+=0x000080;
if(rsum>0xFF0000) rsum=0xFF0000;
if(gsum>0x00FF00) gsum=0x00FF00;
if(bsum>0x0000FF) bsum=0x0000FF;*/
*dest++ = rsum/*&0xFF0000*/ | gsum/*&0x00FF00*/ | bsum;
}
++sums;
}
}
static void filter(gambatte::uint_least32_t *dline,
std::ptrdiff_t const pitch,
gambatte::uint_least32_t const *sline)
{
Colorsum sums[in_pitch];
for (unsigned h = in_height; h--;) {
{
gambatte::uint_least32_t const *s = sline;
Colorsum *sum = sums;
unsigned n = in_pitch;
while (n--) {
unsigned long const pixel = *s;
sum->r = (pixel >> 16) * 27;
sum->g = (pixel & 0x00FF00) * 27;
sum->b = (pixel & 0x0000FF) * 27;
++s;
++sum;
}
}
mergeColumns(dline, sums);
dline += pitch;
{
gambatte::uint_least32_t const *s = sline;
Colorsum *sum = sums;
unsigned n = in_pitch;
while (n--) {
unsigned long pixel = *s;
unsigned long rsum = (pixel >> 16) * 21;
unsigned long gsum = (pixel & 0x00FF00) * 21;
unsigned long bsum = (pixel & 0x0000FF) * 21;
pixel = s[-1 * in_pitch];
rsum -= (pixel >> 16) << 1;
pixel <<= 1;
gsum -= pixel & 0x01FE00;
bsum -= pixel & 0x0001FE;
pixel = s[1 * in_pitch];
rsum += (pixel >> 16) * 9;
gsum += (pixel & 0x00FF00) * 9;
bsum += (pixel & 0x0000FF) * 9;
pixel = s[2 * in_pitch];
rsum -= pixel >> 16;
gsum -= pixel & 0x00FF00;
bsum -= pixel & 0x0000FF;
sum->r = rsum;
sum->g = gsum;
sum->b = bsum;
++s;
++sum;
}
}
mergeColumns(dline, sums);
dline += pitch;
{
gambatte::uint_least32_t const *s = sline;
Colorsum *sum = sums;
unsigned n = in_pitch;
while (n--) {
unsigned long pixel = *s;
unsigned long rsum = (pixel >> 16) * 9;
unsigned long gsum = (pixel & 0x00FF00) * 9;
unsigned long bsum = (pixel & 0x0000FF) * 9;
pixel = s[-1 * in_pitch];
rsum -= pixel >> 16;
gsum -= pixel & 0x00FF00;
bsum -= pixel & 0x0000FF;
pixel = s[1 * in_pitch];
rsum += (pixel >> 16) * 21;
gsum += (pixel & 0x00FF00) * 21;
bsum += (pixel & 0x0000FF) * 21;
pixel = s[2 * in_pitch];
rsum -= (pixel >> 16) << 1;
pixel <<= 1;
gsum -= pixel & 0x01FE00;
bsum -= pixel & 0x0001FE;
sum->r = rsum;
sum->g = gsum;
sum->b = bsum;
++s;
++sum;
}
}
mergeColumns(dline, sums);
dline += pitch;
sline += in_pitch;
}
}
} // anon namespace
Catrom3x::Catrom3x()
: buffer_((in_height + 3UL) * in_pitch)
{
std::fill_n(buffer_.get(), buffer_.size(), 0);
}
void * Catrom3x::inBuf() const {
return buffer_ + in_pitch + 1;
}
std::ptrdiff_t Catrom3x::inPitch() const {
return in_pitch;
}
void Catrom3x::draw(void *dbuffer, std::ptrdiff_t pitch) {
::filter(static_cast<gambatte::uint_least32_t *>(dbuffer), pitch, buffer_ + in_pitch);
}
-41
View File
@@ -1,41 +0,0 @@
/***************************************************************************
* Copyright (C) 2009 by Sindre Aamås *
* sinamas@users.sourceforge.net *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License version 2 as *
* published by the Free Software Foundation. *
* *
* 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 version 2 for more details. *
* *
* You should have received a copy of the GNU General Public License *
* version 2 along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
***************************************************************************/
#ifndef CATROM3X_H
#define CATROM3X_H
#include "../videolink.h"
#include "../vfilterinfo.h"
#include "array.h"
#include "gbint.h"
class Catrom3x : public VideoLink {
public:
enum { out_width = VfilterInfo::in_width * 3 };
enum { out_height = VfilterInfo::in_height * 3 };
Catrom3x();
virtual void * inBuf() const;
virtual std::ptrdiff_t inPitch() const;
virtual void draw(void *dst, std::ptrdiff_t dstpitch);
private:
Array<gambatte::uint_least32_t> const buffer_;
};
#endif
-233
View File
@@ -1,233 +0,0 @@
/***************************************************************************
* Copyright (C) 2007 by Sindre Aamås *
* sinamas@users.sourceforge.net *
* *
* Copyright (C) 1999 Derek Liauw Kie Fa (Kreed) *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License version 2 as *
* published by the Free Software Foundation. *
* *
* 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 version 2 for more details. *
* *
* You should have received a copy of the GNU General Public License *
* version 2 along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
***************************************************************************/
#include "kreed2xsai.h"
#include <algorithm>
namespace {
static int getResult1(unsigned long const a,
unsigned long const b,
unsigned long const c,
unsigned long const d)
{
int x = 0;
int y = 0;
int r = 0;
if (a == c) ++x;
else if (b == c) ++y;
if (a == d) ++x;
else if (b == d) ++y;
if (x <= 1) ++r;
if (y <= 1) --r;
return r;
}
static int getResult2(unsigned long const a,
unsigned long const b,
unsigned long const c,
unsigned long const d)
{
int x = 0;
int y = 0;
int r = 0;
if (a == c) ++x;
else if (b == c) ++y;
if (a == d) ++x;
else if (b == d) ++y;
if (x <= 1) --r;
if (y <= 1) ++r;
return r;
}
static unsigned long interpolate(unsigned long a, unsigned long b) {
return (a + b - ((a ^ b) & 0x010101)) >> 1;
}
static unsigned long qInterpolate(unsigned long const a,
unsigned long const b,
unsigned long const c,
unsigned long const d)
{
unsigned long lowBits = ((a & 0x030303)
+ (b & 0x030303)
+ (c & 0x030303)
+ (d & 0x030303)) & 0x030303;
return (a + b + c + d - lowBits) >> 2;
}
template<std::ptrdiff_t srcPitch, unsigned width, unsigned height>
static void filter(gambatte::uint_least32_t *dstPtr,
std::ptrdiff_t const dstPitch,
gambatte::uint_least32_t const *srcPtr)
{
for (unsigned h = height; h--;) {
gambatte::uint_least32_t const *bP = srcPtr;
gambatte::uint_least32_t *dP = dstPtr;
for (unsigned w = width; w--;) {
unsigned long colorA, colorB, colorC, colorD,
colorE, colorF, colorG, colorH,
colorI, colorJ, colorK, colorL,
colorM, colorN, colorO/*, colorP*/;
//---------------------------------------
// Map of the pixels: I|E F|J
// G|A B|K
// H|C D|L
// M|N O|P
colorI = *(bP - srcPitch - 1);
colorE = *(bP - srcPitch );
colorF = *(bP - srcPitch + 1);
colorJ = *(bP - srcPitch + 2);
colorG = *(bP - 1);
colorA = *(bP );
colorB = *(bP + 1);
colorK = *(bP + 2);
colorH = *(bP + srcPitch - 1);
colorC = *(bP + srcPitch );
colorD = *(bP + srcPitch + 1);
colorL = *(bP + srcPitch + 2);
colorM = *(bP + srcPitch * 2 - 1);
colorN = *(bP + srcPitch * 2 );
colorO = *(bP + srcPitch * 2 + 1);
// colorP = *(bP + srcPitch * 2 + 2);
unsigned long product0, product1, product2;
if (colorA == colorD && colorB != colorC) {
product0 = (colorA == colorE && colorB == colorL)
|| (colorA == colorC && colorA == colorF
&& colorB != colorE && colorB == colorJ)
? colorA
: interpolate(colorA, colorB);
product1 = (colorA == colorG && colorC == colorO)
|| (colorA == colorB && colorA == colorH
&& colorG != colorC && colorC == colorM)
? colorA
: interpolate(colorA, colorC);
product2 = colorA;
} else if (colorB == colorC && colorA != colorD) {
product0 = (colorB == colorF && colorA == colorH)
|| (colorB == colorE && colorB == colorD
&& colorA != colorF && colorA == colorI)
? colorB
: interpolate(colorA, colorB);
product1 = (colorC == colorH && colorA == colorF)
|| (colorC == colorG && colorC == colorD
&& colorA != colorH && colorA == colorI)
? colorC
: interpolate(colorA, colorC);
product2 = colorB;
} else if (colorA == colorD && colorB == colorC) {
if (colorA == colorB) {
product0 = colorA;
product1 = colorA;
product2 = colorA;
} else {
product0 = interpolate(colorA, colorB);
product1 = interpolate(colorA, colorC);
int r = 0;
r += getResult1(colorA, colorB, colorG, colorE);
r += getResult2(colorB, colorA, colorK, colorF);
r += getResult2(colorB, colorA, colorH, colorN);
r += getResult1(colorA, colorB, colorL, colorO);
if (r > 0) {
product2 = colorA;
} else if (r < 0) {
product2 = colorB;
} else {
product2 = qInterpolate(colorA, colorB, colorC, colorD);
}
}
} else {
product2 = qInterpolate(colorA, colorB, colorC, colorD);
if (colorA == colorC && colorA == colorF
&& colorB != colorE && colorB == colorJ) {
product0 = colorA;
} else if (colorB == colorE && colorB == colorD
&& colorA != colorF && colorA == colorI) {
product0 = colorB;
} else {
product0 = interpolate(colorA, colorB);
}
if (colorA == colorB && colorA == colorH
&& colorG != colorC && colorC == colorM) {
product1 = colorA;
} else if (colorC == colorG && colorC == colorD
&& colorA != colorH && colorA == colorI) {
product1 = colorC;
} else {
product1 = interpolate(colorA, colorC);
}
}
*(dP ) = colorA;
*(dP + 1) = product0;
*(dP + dstPitch ) = product1;
*(dP + dstPitch + 1) = product2;
dP += 2;
++bP;
}
srcPtr += srcPitch;
dstPtr += dstPitch * 2;
}
}
enum { in_width = VfilterInfo::in_width };
enum { in_height = VfilterInfo::in_height };
enum { in_pitch = in_width + 3 };
enum { buf_size = (in_height + 3ul) * in_pitch };
enum { buf_offset = in_pitch + 1 };
} // anon namespace
Kreed2xSaI::Kreed2xSaI()
: buffer_(buf_size)
{
std::fill_n(buffer_.get(), buffer_.size(), 0);
}
void * Kreed2xSaI::inBuf() const {
return buffer_ + buf_offset;
}
std::ptrdiff_t Kreed2xSaI::inPitch() const {
return in_pitch;
}
void Kreed2xSaI::draw(void *dbuffer, std::ptrdiff_t dpitch) {
::filter<in_pitch, in_width, in_height>(static_cast<gambatte::uint_least32_t *>(dbuffer),
dpitch, buffer_ + buf_offset);
}
-41
View File
@@ -1,41 +0,0 @@
/***************************************************************************
* Copyright (C) 2009 by Sindre Aamås *
* sinamas@users.sourceforge.net *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License version 2 as *
* published by the Free Software Foundation. *
* *
* 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 version 2 for more details. *
* *
* You should have received a copy of the GNU General Public License *
* version 2 along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
***************************************************************************/
#ifndef KREED2XSAI_H
#define KREED2XSAI_H
#include "../videolink.h"
#include "../vfilterinfo.h"
#include "array.h"
#include "gbint.h"
class Kreed2xSaI : public VideoLink {
public:
enum { out_width = VfilterInfo::in_width * 2 };
enum { out_height = VfilterInfo::in_height * 2 };
Kreed2xSaI();
virtual void * inBuf() const;
virtual std::ptrdiff_t inPitch() const;
virtual void draw(void *dst, std::ptrdiff_t dstpitch);
private:
Array<gambatte::uint_least32_t> const buffer_;
};
#endif
File diff suppressed because it is too large Load Diff
-41
View File
@@ -1,41 +0,0 @@
/***************************************************************************
* Copyright (C) 2009 by Sindre Aamås *
* sinamas@users.sourceforge.net *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License version 2 as *
* published by the Free Software Foundation. *
* *
* 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 version 2 for more details. *
* *
* You should have received a copy of the GNU General Public License *
* version 2 along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
***************************************************************************/
#ifndef MAXSTHQ2X_H
#define MAXSTHQ2X_H
#include "../videolink.h"
#include "../vfilterinfo.h"
#include "array.h"
#include "gbint.h"
class MaxStHq2x : public VideoLink {
public:
enum { out_width = VfilterInfo::in_width * 2 };
enum { out_height = VfilterInfo::in_height * 2 };
MaxStHq2x();
virtual void * inBuf() const;
virtual std::ptrdiff_t inPitch() const;
virtual void draw(void *dst, std::ptrdiff_t dstpitch);
private:
SimpleArray<gambatte::uint_least32_t> const buffer_;
};
#endif
File diff suppressed because it is too large Load Diff
-41
View File
@@ -1,41 +0,0 @@
/***************************************************************************
* Copyright (C) 2009 by Sindre Aamås *
* sinamas@users.sourceforge.net *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License version 2 as *
* published by the Free Software Foundation. *
* *
* 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 version 2 for more details. *
* *
* You should have received a copy of the GNU General Public License *
* version 2 along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
***************************************************************************/
#ifndef MAXSTHQ3X_H
#define MAXSTHQ3X_H
#include "../videolink.h"
#include "../vfilterinfo.h"
#include "array.h"
#include "gbint.h"
class MaxStHq3x : public VideoLink {
public:
enum { out_width = VfilterInfo::in_width * 3 };
enum { out_height = VfilterInfo::in_height * 3 };
MaxStHq3x();
virtual void * inBuf() const;
virtual std::ptrdiff_t inPitch() const;
virtual void draw(void *dst, std::ptrdiff_t dstpitch);
private:
SimpleArray<gambatte::uint_least32_t> const buffer_;
};
#endif
-32
View File
@@ -1,32 +0,0 @@
/***************************************************************************
* Copyright (C) 2009 by Sindre Aamås *
* sinamas@users.sourceforge.net *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License version 2 as *
* published by the Free Software Foundation. *
* *
* 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 version 2 for more details. *
* *
* You should have received a copy of the GNU General Public License *
* version 2 along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
***************************************************************************/
#ifndef VIDEOLINK_H
#define VIDEOLINK_H
#include <cstddef>
class VideoLink {
public:
virtual ~VideoLink() {}
virtual void * inBuf() const = 0;
virtual std::ptrdiff_t inPitch() const = 0;
virtual void draw(void *dst, std::ptrdiff_t dstpitch) = 0;
};
#endif
+506 -506
View File
File diff suppressed because it is too large Load Diff
-56
View File
@@ -1,56 +0,0 @@
global_cflags = ARGUMENTS.get('CFLAGS', '-Wall -Wextra -O2 -fomit-frame-pointer')
global_cxxflags = ARGUMENTS.get('CXXFLAGS', global_cflags + ' -fno-exceptions -fno-rtti')
global_defines = ' -DHAVE_STDINT_H'
vars = Variables()
vars.Add('CC')
vars.Add('CXX')
env = Environment(CPPPATH = ['src', 'include', '../common'],
CFLAGS = global_cflags + global_defines,
CXXFLAGS = global_cxxflags + global_defines,
variables = vars)
sourceFiles = Split('''
src/bitmap_font.cpp
src/cpu.cpp
src/gambatte.cpp
src/initstate.cpp
src/interrupter.cpp
src/interruptrequester.cpp
src/loadres.cpp
src/memory.cpp
src/sound.cpp
src/state_osd_elements.cpp
src/statesaver.cpp
src/tima.cpp
src/video.cpp
src/mem/cartridge.cpp
src/mem/memptrs.cpp
src/mem/pakinfo.cpp
src/mem/rtc.cpp
src/sound/channel1.cpp
src/sound/channel2.cpp
src/sound/channel3.cpp
src/sound/channel4.cpp
src/sound/duty_unit.cpp
src/sound/envelope_unit.cpp
src/sound/length_counter.cpp
src/video/ly_counter.cpp
src/video/lyc_irq.cpp
src/video/next_m0_time.cpp
src/video/ppu.cpp
src/video/sprite_mapper.cpp
''')
conf = env.Configure()
if conf.CheckHeader('zlib.h'):
sourceFiles.append('src/file/unzip/unzip.c')
sourceFiles.append('src/file/unzip/ioapi.c')
sourceFiles.append('src/file/file_zip.cpp')
else:
sourceFiles.append('src/file/file.cpp')
conf.Finish()
env.Library('gambatte', sourceFiles)
-222
View File
@@ -1,222 +0,0 @@
/***************************************************************************
Copyright (C) 2007 by Nach
http://nsrt.edgeemu.com
Copyright (C) 2007-2011 by sinamas <sinamas at users.sourceforge.net>
sinamas@users.sourceforge.net
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License version 2 as
published by the Free Software Foundation.
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 version 2 for more details.
You should have received a copy of the GNU General Public License
version 2 along with this program; if not, write to the
Free Software Foundation, Inc.,
51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
***************************************************************************/
#include "stdfile.h"
#include <cctype>
#include <cstring>
namespace zlib {
#include "unzip/unzip.h"
}
namespace {
class ZipFile : public gambatte::File {
private:
std::size_t fsize, count;
void *zipfile;
bool zip_sub_open;
void zip(const char *filename);
public:
ZipFile(const char *filename);
virtual ~ZipFile();
virtual void rewind();
bool is_open() const;
virtual void close();
virtual std::size_t size() const { return fsize; };
virtual void read(char *buffer, std::size_t amount);
std::size_t gcount() const { return count; }
virtual bool fail() const { return !is_open(); }
};
using namespace std;
using namespace zlib;
static const unsigned int MAX_FILE_NAME = 512;
ZipFile::ZipFile(const char *filename) : fsize(0), count(0)
{
zip(filename);
}
void ZipFile::zip(const char *filename)
{
zipfile = unzOpen(filename);
if (zipfile)
{
zip_sub_open = false;
unz_file_info cFileInfo;
char ourFile[MAX_FILE_NAME] = { '\n' };
for (int cFile = unzGoToFirstFile((unzFile)zipfile); cFile == UNZ_OK; cFile = unzGoToNextFile((unzFile)zipfile))
{
//Temporary char array for file name
char cFileName[MAX_FILE_NAME];
//Gets info on current file, and places it in cFileInfo
unzGetCurrentFileInfo((unzFile)zipfile, &cFileInfo, cFileName, MAX_FILE_NAME, 0, 0, 0, 0);
//Check for largest file which should be the ROM
if ((size_t)cFileInfo.uncompressed_size > fsize)
{
strcpy(ourFile, cFileName);
fsize = (size_t)cFileInfo.uncompressed_size;
}
}
if (ourFile[0] != '\n')
{
//Sets current file to the file we liked before
unzLocateFile((unzFile)zipfile, ourFile, 1);
if (unzOpenCurrentFile((unzFile)zipfile) == UNZ_OK)
{
zip_sub_open = true;
}
}
if (!zip_sub_open)
{
unzClose((unzFile)zipfile);
zipfile = 0;
}
}
}
ZipFile::~ZipFile()
{
close();
}
void ZipFile::rewind()
{
if (is_open())
{
unzCloseCurrentFile((unzFile)zipfile);
unzOpenCurrentFile((unzFile)zipfile);
}
}
bool ZipFile::is_open() const
{
return(zipfile && zip_sub_open);
}
void ZipFile::close()
{
if (is_open())
{
unzOpenCurrentFile((unzFile)zipfile);
unzClose((unzFile)zipfile);
zipfile = 0;
zip_sub_open = false;
}
}
void ZipFile::read(char *buffer, size_t amount)
{
if (is_open())
{
count = (size_t)unzReadCurrentFile((unzFile)zipfile, buffer, amount);
}
else
{
count = 0;
}
}
class GzFile : public gambatte::File {
public:
explicit GzFile(char const *filename)
: file_(gzopen(filename, "rb"))
, fsize_(0)
{
if (file_) {
char buf[256];
int ret;
while ((ret = gzread(file_, buf, sizeof buf)) > 0)
fsize_ += ret;
if (ret < 0) {
close();
fsize_ = 0;
}
}
rewind();
}
virtual ~GzFile() { close(); }
virtual void rewind() {
if (file_ && gzrewind(file_) < 0)
close();
}
virtual std::size_t size() const { return fsize_; };
virtual void read(char *buffer, std::size_t amount) {
if (file_ && gzread(file_, buffer, amount) < 0)
close();
}
virtual bool fail() const { return !file_; }
private:
gzFile file_;
std::size_t fsize_;
GzFile(GzFile const &);
GzFile & operator=(GzFile const &);
void close();
};
void GzFile::close() {
if (file_) {
gzclose(file_);
file_ = 0;
}
}
}
// Avoid checking magic header values, because there are no values that cannot occur in a GB ROM.
transfer_ptr<gambatte::File> gambatte::newFileInstance(std::string const &filepath) {
std::size_t const extpos = filepath.rfind('.');
if (extpos != std::string::npos) {
std::string const &ext = filepath.substr(extpos + 1);
if (ext.length() == 3 && std::tolower(ext[0]) == 'z'
&& std::tolower(ext[1]) == 'i' && std::tolower(ext[2]) == 'p') {
return transfer_ptr<File>(new ZipFile(filepath.c_str()));
}
if (!ext.empty() && std::tolower(ext[ext.length() - 1]) == 'z')
return transfer_ptr<File>(new GzFile(filepath.c_str()));
}
return transfer_ptr<File>(new StdFile(filepath.c_str()));
}
-132
View File
@@ -1,132 +0,0 @@
/* crypt.h -- base code for crypt/uncrypt ZIPfile
Version 1.01e, February 12th, 2005
Copyright (C) 1998-2005 Gilles Vollant
This code is a modified version of crypting code in Infozip distribution
The encryption/decryption parts of this source code (as opposed to the
non-echoing password parts) were originally written in Europe. The
whole source package can be freely distributed, including from the USA.
(Prior to January 2000, re-export from the US was a violation of US law.)
This encryption code is a direct transcription of the algorithm from
Roger Schlafly, described by Phil Katz in the file appnote.txt. This
file (appnote.txt) is distributed with the PKZIP program (even in the
version without encryption capabilities).
If you don't need crypting in your application, just define symbols
NOCRYPT and NOUNCRYPT.
This code support the "Traditional PKWARE Encryption".
The new AES encryption added on Zip format by Winzip (see the page
http://www.winzip.com/aes_info.htm ) and PKWare PKZip 5.x Strong
Encryption is not supported.
*/
#define CRC32(c, b) ((*(pcrc_32_tab+(((int)(c) ^ (b)) & 0xff))) ^ ((c) >> 8))
/***********************************************************************
* Return the next byte in the pseudo-random sequence
*/
static int decrypt_byte(unsigned long* pkeys, const unsigned long* pcrc_32_tab)
{
unsigned temp; /* POTENTIAL BUG: temp*(temp^1) may overflow in an
* unpredictable manner on 16-bit systems; not a problem
* with any known compiler so far, though */
temp = ((unsigned)(*(pkeys+2)) & 0xffff) | 2;
return (int)(((temp * (temp ^ 1)) >> 8) & 0xff);
}
/***********************************************************************
* Update the encryption keys with the next byte of plain text
*/
static int update_keys(unsigned long* pkeys,const unsigned long* pcrc_32_tab,int c)
{
(*(pkeys+0)) = CRC32((*(pkeys+0)), c);
(*(pkeys+1)) += (*(pkeys+0)) & 0xff;
(*(pkeys+1)) = (*(pkeys+1)) * 134775813L + 1;
{
register int keyshift = (int)((*(pkeys+1)) >> 24);
(*(pkeys+2)) = CRC32((*(pkeys+2)), keyshift);
}
return c;
}
/***********************************************************************
* Initialize the encryption keys and the random header according to
* the given password.
*/
static void init_keys(const char* passwd,unsigned long* pkeys,const unsigned long* pcrc_32_tab)
{
*(pkeys+0) = 305419896L;
*(pkeys+1) = 591751049L;
*(pkeys+2) = 878082192L;
while (*passwd != '\0') {
update_keys(pkeys,pcrc_32_tab,(int)*passwd);
passwd++;
}
}
#define zdecode(pkeys,pcrc_32_tab,c) \
(update_keys(pkeys,pcrc_32_tab,c ^= decrypt_byte(pkeys,pcrc_32_tab)))
#define zencode(pkeys,pcrc_32_tab,c,t) \
(t=decrypt_byte(pkeys,pcrc_32_tab), update_keys(pkeys,pcrc_32_tab,c), t^(c))
#ifdef INCLUDECRYPTINGCODE_IFCRYPTALLOWED
#define RAND_HEAD_LEN 12
/* "last resort" source for second part of crypt seed pattern */
# ifndef ZCR_SEED2
# define ZCR_SEED2 3141592654UL /* use PI as default pattern */
# endif
static int crypthead(passwd, buf, bufSize, pkeys, pcrc_32_tab, crcForCrypting)
const char *passwd; /* password string */
unsigned char *buf; /* where to write header */
int bufSize;
unsigned long* pkeys;
const unsigned long* pcrc_32_tab;
unsigned long crcForCrypting;
{
int n; /* index in random header */
int t; /* temporary */
int c; /* random byte */
unsigned char header[RAND_HEAD_LEN-2]; /* random header */
static unsigned calls = 0; /* ensure different random header each time */
if (bufSize<RAND_HEAD_LEN)
return 0;
/* First generate RAND_HEAD_LEN-2 random bytes. We encrypt the
* output of rand() to get less predictability, since rand() is
* often poorly implemented.
*/
if (++calls == 1)
{
srand((unsigned)(time(NULL) ^ ZCR_SEED2));
}
init_keys(passwd, pkeys, pcrc_32_tab);
for (n = 0; n < RAND_HEAD_LEN-2; n++)
{
c = (rand() >> 7) & 0xff;
header[n] = (unsigned char)zencode(pkeys, pcrc_32_tab, c, t);
}
/* Encrypt random header (last two bytes is high word of crc) */
init_keys(passwd, pkeys, pcrc_32_tab);
for (n = 0; n < RAND_HEAD_LEN-2; n++)
{
buf[n] = (unsigned char)zencode(pkeys, pcrc_32_tab, header[n], t);
}
buf[n++] = zencode(pkeys, pcrc_32_tab, (int)(crcForCrypting >> 16) & 0xff, t);
buf[n++] = zencode(pkeys, pcrc_32_tab, (int)(crcForCrypting >> 24) & 0xff, t);
return n;
}
#endif
-177
View File
@@ -1,177 +0,0 @@
/* ioapi.c -- IO base function header for compress/uncompress .zip
files using zlib + zip or unzip API
Version 1.01e, February 12th, 2005
Copyright (C) 1998-2005 Gilles Vollant
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <zlib.h>
#include "ioapi.h"
/* I've found an old Unix (a SunOS 4.1.3_U1) without all SEEK_* defined.... */
#ifndef SEEK_CUR
#define SEEK_CUR 1
#endif
#ifndef SEEK_END
#define SEEK_END 2
#endif
#ifndef SEEK_SET
#define SEEK_SET 0
#endif
voidpf ZCALLBACK fopen_file_func OF((
voidpf opaque,
const char* filename,
int mode));
uLong ZCALLBACK fread_file_func OF((
voidpf opaque,
voidpf stream,
void* buf,
uLong size));
uLong ZCALLBACK fwrite_file_func OF((
voidpf opaque,
voidpf stream,
const void* buf,
uLong size));
long ZCALLBACK ftell_file_func OF((
voidpf opaque,
voidpf stream));
long ZCALLBACK fseek_file_func OF((
voidpf opaque,
voidpf stream,
uLong offset,
int origin));
int ZCALLBACK fclose_file_func OF((
voidpf opaque,
voidpf stream));
int ZCALLBACK ferror_file_func OF((
voidpf opaque,
voidpf stream));
voidpf ZCALLBACK fopen_file_func (opaque, filename, mode)
voidpf opaque;
const char* filename;
int mode;
{
FILE* file = NULL;
const char* mode_fopen = NULL;
if ((mode & ZLIB_FILEFUNC_MODE_READWRITEFILTER)==ZLIB_FILEFUNC_MODE_READ)
mode_fopen = "rb";
else
if (mode & ZLIB_FILEFUNC_MODE_EXISTING)
mode_fopen = "r+b";
else
if (mode & ZLIB_FILEFUNC_MODE_CREATE)
mode_fopen = "wb";
if ((filename!=NULL) && (mode_fopen != NULL))
file = fopen(filename, mode_fopen);
return file;
}
uLong ZCALLBACK fread_file_func (opaque, stream, buf, size)
voidpf opaque;
voidpf stream;
void* buf;
uLong size;
{
uLong ret;
ret = (uLong)fread(buf, 1, (size_t)size, (FILE *)stream);
return ret;
}
uLong ZCALLBACK fwrite_file_func (opaque, stream, buf, size)
voidpf opaque;
voidpf stream;
const void* buf;
uLong size;
{
uLong ret;
ret = (uLong)fwrite(buf, 1, (size_t)size, (FILE *)stream);
return ret;
}
long ZCALLBACK ftell_file_func (opaque, stream)
voidpf opaque;
voidpf stream;
{
long ret;
ret = ftell((FILE *)stream);
return ret;
}
long ZCALLBACK fseek_file_func (opaque, stream, offset, origin)
voidpf opaque;
voidpf stream;
uLong offset;
int origin;
{
int fseek_origin=0;
long ret;
switch (origin)
{
case ZLIB_FILEFUNC_SEEK_CUR :
fseek_origin = SEEK_CUR;
break;
case ZLIB_FILEFUNC_SEEK_END :
fseek_origin = SEEK_END;
break;
case ZLIB_FILEFUNC_SEEK_SET :
fseek_origin = SEEK_SET;
break;
default: return -1;
}
ret = 0;
fseek((FILE *)stream, offset, fseek_origin);
return ret;
}
int ZCALLBACK fclose_file_func (opaque, stream)
voidpf opaque;
voidpf stream;
{
int ret;
ret = fclose((FILE *)stream);
return ret;
}
int ZCALLBACK ferror_file_func (opaque, stream)
voidpf opaque;
voidpf stream;
{
int ret;
ret = ferror((FILE *)stream);
return ret;
}
void fill_fopen_filefunc (pzlib_filefunc_def)
zlib_filefunc_def* pzlib_filefunc_def;
{
pzlib_filefunc_def->zopen_file = fopen_file_func;
pzlib_filefunc_def->zread_file = fread_file_func;
pzlib_filefunc_def->zwrite_file = fwrite_file_func;
pzlib_filefunc_def->ztell_file = ftell_file_func;
pzlib_filefunc_def->zseek_file = fseek_file_func;
pzlib_filefunc_def->zclose_file = fclose_file_func;
pzlib_filefunc_def->zerror_file = ferror_file_func;
pzlib_filefunc_def->opaque = NULL;
}
-75
View File
@@ -1,75 +0,0 @@
/* ioapi.h -- IO base function header for compress/uncompress .zip
files using zlib + zip or unzip API
Version 1.01e, February 12th, 2005
Copyright (C) 1998-2005 Gilles Vollant
*/
#ifndef _ZLIBIOAPI_H
#define _ZLIBIOAPI_H
#define ZLIB_FILEFUNC_SEEK_CUR (1)
#define ZLIB_FILEFUNC_SEEK_END (2)
#define ZLIB_FILEFUNC_SEEK_SET (0)
#define ZLIB_FILEFUNC_MODE_READ (1)
#define ZLIB_FILEFUNC_MODE_WRITE (2)
#define ZLIB_FILEFUNC_MODE_READWRITEFILTER (3)
#define ZLIB_FILEFUNC_MODE_EXISTING (4)
#define ZLIB_FILEFUNC_MODE_CREATE (8)
#ifndef ZCALLBACK
#if (defined(WIN32) || defined (WINDOWS) || defined (_WINDOWS)) && defined(CALLBACK) && defined (USEWINDOWS_CALLBACK)
#define ZCALLBACK CALLBACK
#else
#define ZCALLBACK
#endif
#endif
#ifdef __cplusplus
extern "C" {
#endif
typedef voidpf (ZCALLBACK *open_file_func) OF((voidpf opaque, const char* filename, int mode));
typedef uLong (ZCALLBACK *read_file_func) OF((voidpf opaque, voidpf stream, void* buf, uLong size));
typedef uLong (ZCALLBACK *write_file_func) OF((voidpf opaque, voidpf stream, const void* buf, uLong size));
typedef long (ZCALLBACK *tell_file_func) OF((voidpf opaque, voidpf stream));
typedef long (ZCALLBACK *seek_file_func) OF((voidpf opaque, voidpf stream, uLong offset, int origin));
typedef int (ZCALLBACK *close_file_func) OF((voidpf opaque, voidpf stream));
typedef int (ZCALLBACK *testerror_file_func) OF((voidpf opaque, voidpf stream));
typedef struct zlib_filefunc_def_s
{
open_file_func zopen_file;
read_file_func zread_file;
write_file_func zwrite_file;
tell_file_func ztell_file;
seek_file_func zseek_file;
close_file_func zclose_file;
testerror_file_func zerror_file;
voidpf opaque;
} zlib_filefunc_def;
void fill_fopen_filefunc OF((zlib_filefunc_def* pzlib_filefunc_def));
#define ZREAD(filefunc,filestream,buf,size) ((*((filefunc).zread_file))((filefunc).opaque,filestream,buf,size))
#define ZWRITE(filefunc,filestream,buf,size) ((*((filefunc).zwrite_file))((filefunc).opaque,filestream,buf,size))
#define ZTELL(filefunc,filestream) ((*((filefunc).ztell_file))((filefunc).opaque,filestream))
#define ZSEEK(filefunc,filestream,pos,mode) ((*((filefunc).zseek_file))((filefunc).opaque,filestream,pos,mode))
#define ZCLOSE(filefunc,filestream) ((*((filefunc).zclose_file))((filefunc).opaque,filestream))
#define ZERROR(filefunc,filestream) ((*((filefunc).zerror_file))((filefunc).opaque,filestream))
#ifdef __cplusplus
}
#endif
#endif
File diff suppressed because it is too large Load Diff
-358
View File
@@ -1,358 +0,0 @@
/* unzip.h -- IO for uncompress .zip files using zlib
Version 1.01e, February 12th, 2005
Copyright (C) 1998-2005 Gilles Vollant
This unzip package allow extract file from .ZIP file, compatible with PKZip 2.04g
WinZip, InfoZip tools and compatible.
Multi volume ZipFile (span) are not supported.
Encryption compatible with pkzip 2.04g only supported
Old compressions used by old PKZip 1.x are not supported
I WAIT FEEDBACK at mail info@winimage.com
Visit also http://www.winimage.com/zLibDll/unzip.htm for evolution
Condition of use and distribution are the same than zlib :
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
/* for more info about .ZIP format, see
http://www.info-zip.org/pub/infozip/doc/appnote-981119-iz.zip
http://www.info-zip.org/pub/infozip/doc/
PkWare has also a specification at :
ftp://ftp.pkware.com/probdesc.zip
*/
#ifndef _unz_H
#define _unz_H
#ifdef __cplusplus
extern "C" {
#endif
#ifndef _ZLIB_H
#include <zlib.h>
#endif
#ifndef OF
#define OF(args) args
#endif
#ifndef _ZLIBIOAPI_H
#include "ioapi.h"
#endif
#if defined(STRICTUNZIP) || defined(STRICTZIPUNZIP)
/* like the STRICT of WIN32, we define a pointer that cannot be converted
from (void*) without cast */
typedef struct TagunzFile__ { int unused; } unzFile__;
typedef unzFile__ *unzFile;
#else
typedef voidp unzFile;
#endif
#define UNZ_OK (0)
#define UNZ_END_OF_LIST_OF_FILE (-100)
#define UNZ_ERRNO (Z_ERRNO)
#define UNZ_EOF (0)
#define UNZ_PARAMERROR (-102)
#define UNZ_BADZIPFILE (-103)
#define UNZ_INTERNALERROR (-104)
#define UNZ_CRCERROR (-105)
/* tm_unz contain date/time info */
typedef struct tm_unz_s
{
uInt tm_sec; /* seconds after the minute - [0,59] */
uInt tm_min; /* minutes after the hour - [0,59] */
uInt tm_hour; /* hours since midnight - [0,23] */
uInt tm_mday; /* day of the month - [1,31] */
uInt tm_mon; /* months since January - [0,11] */
uInt tm_year; /* years - [1980..2044] */
} tm_unz;
/* unz_global_info structure contain global data about the ZIPfile
These data comes from the end of central dir */
typedef struct unz_global_info_s
{
uLong number_entry; /* total number of entries in
the central dir on this disk */
uLong size_comment; /* size of the global comment of the zipfile */
} unz_global_info;
/* unz_file_info contain information about a file in the zipfile */
typedef struct unz_file_info_s
{
uLong version; /* version made by 2 bytes */
uLong version_needed; /* version needed to extract 2 bytes */
uLong flag; /* general purpose bit flag 2 bytes */
uLong compression_method; /* compression method 2 bytes */
uLong dosDate; /* last mod file date in Dos fmt 4 bytes */
uLong crc; /* crc-32 4 bytes */
uLong compressed_size; /* compressed size 4 bytes */
uLong uncompressed_size; /* uncompressed size 4 bytes */
uLong size_filename; /* filename length 2 bytes */
uLong size_file_extra; /* extra field length 2 bytes */
uLong size_file_comment; /* file comment length 2 bytes */
uLong disk_num_start; /* disk number start 2 bytes */
uLong internal_fa; /* internal file attributes 2 bytes */
uLong external_fa; /* external file attributes 4 bytes */
tm_unz tmu_date;
} unz_file_info;
extern int ZEXPORT unzStringFileNameCompare OF ((const char* fileName1,
const char* fileName2,
int iCaseSensitivity));
/*
Compare two filename (fileName1,fileName2).
If iCaseSenisivity = 1, comparision is case sensitivity (like strcmp)
If iCaseSenisivity = 2, comparision is not case sensitivity (like strcmpi
or strcasecmp)
If iCaseSenisivity = 0, case sensitivity is defaut of your operating system
(like 1 on Unix, 2 on Windows)
*/
extern unzFile ZEXPORT unzOpen OF((const char *path));
/*
Open a Zip file. path contain the full pathname (by example,
on a Windows XP computer "c:\\zlib\\zlib113.zip" or on an Unix computer
"zlib/zlib113.zip".
If the zipfile cannot be opened (file don't exist or in not valid), the
return value is NULL.
Else, the return value is a unzFile Handle, usable with other function
of this unzip package.
*/
extern unzFile ZEXPORT unzOpen2 OF((const char *path,
zlib_filefunc_def* pzlib_filefunc_def));
/*
Open a Zip file, like unzOpen, but provide a set of file low level API
for read/write the zip file (see ioapi.h)
*/
extern int ZEXPORT unzClose OF((unzFile file));
/*
Close a ZipFile opened with unzipOpen.
If there is files inside the .Zip opened with unzOpenCurrentFile (see later),
these files MUST be closed with unzipCloseCurrentFile before call unzipClose.
return UNZ_OK if there is no problem. */
extern int ZEXPORT unzGetGlobalInfo OF((unzFile file,
unz_global_info *pglobal_info));
/*
Write info about the ZipFile in the *pglobal_info structure.
No preparation of the structure is needed
return UNZ_OK if there is no problem. */
extern int ZEXPORT unzGetGlobalComment OF((unzFile file,
char *szComment,
uLong uSizeBuf));
/*
Get the global comment string of the ZipFile, in the szComment buffer.
uSizeBuf is the size of the szComment buffer.
return the number of byte copied or an error code <0
*/
/***************************************************************************/
/* Unzip package allow you browse the directory of the zipfile */
extern int ZEXPORT unzGoToFirstFile OF((unzFile file));
/*
Set the current file of the zipfile to the first file.
return UNZ_OK if there is no problem
*/
extern int ZEXPORT unzGoToNextFile OF((unzFile file));
/*
Set the current file of the zipfile to the next file.
return UNZ_OK if there is no problem
return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest.
*/
extern int ZEXPORT unzLocateFile OF((unzFile file,
const char *szFileName,
int iCaseSensitivity));
/*
Try locate the file szFileName in the zipfile.
For the iCaseSensitivity signification, see unzStringFileNameCompare
return value :
UNZ_OK if the file is found. It becomes the current file.
UNZ_END_OF_LIST_OF_FILE if the file is not found
*/
/* ****************************************** */
/* Ryan supplied functions */
/* unz_file_info contain information about a file in the zipfile */
typedef struct unz_file_pos_s
{
uLong pos_in_zip_directory; /* offset in zip file directory */
uLong num_of_file; /* # of file */
} unz_file_pos;
extern int ZEXPORT unzGetFilePos(
unzFile file,
unz_file_pos* file_pos);
extern int ZEXPORT unzGoToFilePos(
unzFile file,
unz_file_pos* file_pos);
/* ****************************************** */
extern int ZEXPORT unzGetCurrentFileInfo OF((unzFile file,
unz_file_info *pfile_info,
char *szFileName,
uLong fileNameBufferSize,
void *extraField,
uLong extraFieldBufferSize,
char *szComment,
uLong commentBufferSize));
/*
Get Info about the current file
if pfile_info!=NULL, the *pfile_info structure will contain somes info about
the current file
if szFileName!=NULL, the filemane string will be copied in szFileName
(fileNameBufferSize is the size of the buffer)
if extraField!=NULL, the extra field information will be copied in extraField
(extraFieldBufferSize is the size of the buffer).
This is the Central-header version of the extra field
if szComment!=NULL, the comment string of the file will be copied in szComment
(commentBufferSize is the size of the buffer)
*/
/***************************************************************************/
/* for reading the content of the current zipfile, you can open it, read data
from it, and close it (you can close it before reading all the file)
*/
extern int ZEXPORT unzOpenCurrentFile OF((unzFile file));
/*
Open for reading data the current file in the zipfile.
If there is no error, the return value is UNZ_OK.
*/
extern int ZEXPORT unzOpenCurrentFilePassword OF((unzFile file,
const char* password));
/*
Open for reading data the current file in the zipfile.
password is a crypting password
If there is no error, the return value is UNZ_OK.
*/
extern int ZEXPORT unzOpenCurrentFile2 OF((unzFile file,
int* method,
int* level,
int raw));
/*
Same than unzOpenCurrentFile, but open for read raw the file (not uncompress)
if raw==1
*method will receive method of compression, *level will receive level of
compression
note : you can set level parameter as NULL (if you did not want known level,
but you CANNOT set method parameter as NULL
*/
extern int ZEXPORT unzOpenCurrentFile3 OF((unzFile file,
int* method,
int* level,
int raw,
const char* password));
/*
Same than unzOpenCurrentFile, but open for read raw the file (not uncompress)
if raw==1
*method will receive method of compression, *level will receive level of
compression
note : you can set level parameter as NULL (if you did not want known level,
but you CANNOT set method parameter as NULL
*/
extern int ZEXPORT unzCloseCurrentFile OF((unzFile file));
/*
Close the file in zip opened with unzOpenCurrentFile
Return UNZ_CRCERROR if all the file was read but the CRC is not good
*/
extern int ZEXPORT unzReadCurrentFile OF((unzFile file,
voidp buf,
unsigned len));
/*
Read bytes from the current file (opened by unzOpenCurrentFile)
buf contain buffer where data must be copied
len the size of buf.
return the number of byte copied if somes bytes are copied
return 0 if the end of file was reached
return <0 with error code if there is an error
(UNZ_ERRNO for IO error, or zLib error for uncompress error)
*/
extern z_off_t ZEXPORT unztell OF((unzFile file));
/*
Give the current position in uncompressed data
*/
extern int ZEXPORT unzeof OF((unzFile file));
/*
return 1 if the end of file was reached, 0 elsewhere
*/
extern int ZEXPORT unzGetLocalExtrafield OF((unzFile file,
voidp buf,
unsigned len));
/*
Read extra field from the current file (opened by unzOpenCurrentFile)
This is the local-header version of the extra field (sometimes, there is
more info in the local-header version than in the central-header)
if buf==NULL, it return the size of the local extra field
if buf!=NULL, len is the size of the buffer, the extra header is copied in
buf.
the return value is the number of bytes copied in buf, or (if <0)
the error code
*/
/***************************************************************************/
/* Get the current file offset */
extern uLong ZEXPORT unzGetOffset (unzFile file);
/* Set the current file offset */
extern int ZEXPORT unzSetOffset (unzFile file, uLong pos);
#ifdef __cplusplus
}
#endif
#endif /* _unz_H */
View File
@@ -520,8 +520,8 @@ void CPU::process(unsigned long const cycles) {
if (mem_.halted()) {
if (cycleCounter < mem_.nextEventTime()) {
unsigned long cycles = mem_.nextEventTime() - cycleCounter;
cycleCounter += cycles + (-cycles & 3);
unsigned long cpu_cycles = mem_.nextEventTime() - cycleCounter;
cycleCounter += cpu_cycles + (-cpu_cycles & 3);
}
} else while (cycleCounter < mem_.nextEventTime()) {
unsigned char opcode;
@@ -614,8 +614,8 @@ void CPU::process(unsigned long const cycles) {
PC_READ(opcode_);
cycleCounter = mem_.stop(cycleCounter - 4, prefetched_);
if (cycleCounter < mem_.nextEventTime()) {
unsigned long cycles = mem_.nextEventTime() - cycleCounter;
cycleCounter += cycles + (-cycles & 3);
unsigned long cpu_cycles = mem_.nextEventTime() - cycleCounter;
cycleCounter += cpu_cycles + (-cpu_cycles & 3);
}
break;
@@ -1024,8 +1024,8 @@ void CPU::process(unsigned long const cycles) {
prefetched_ = mem_.halt(cycleCounter);
cycleCounter += 4 + 4 * !mem_.isCgb();
if (cycleCounter < mem_.nextEventTime()) {
unsigned long cycles = mem_.nextEventTime() - cycleCounter;
cycleCounter += cycles + (-cycles & 3);
unsigned long cpu_cycles = mem_.nextEventTime() - cycleCounter;
cycleCounter += cpu_cycles + (-cpu_cycles & 3);
}
}
@@ -23,6 +23,8 @@
namespace gambatte {
class File;
class CPU {
public:
CPU();
@@ -53,8 +55,8 @@ public:
mem_.setOsdElement(osdElement);
}
LoadRes load(std::string const &romfile, bool forceDmg, bool multicartCompat) {
return mem_.loadROM(romfile, forceDmg, multicartCompat);
LoadRes load(File &file, std::string const &filename, bool forceDmg, bool multicartCompat) {
return mem_.loadROM(file, filename, forceDmg, multicartCompat);
}
bool loaded() const { return mem_.loaded(); }
@@ -64,6 +66,10 @@ public:
std::size_t fillSoundBuffer() { return mem_.fillSoundBuffer(cycleCounter_); }
bool isCgb() const { return mem_.isCgb(); }
void setCgbColorCorrection(int optNum) {
mem_.setCgbColorCorrection(optNum);
}
void setDmgPaletteColor(int palNum, int colorNum, unsigned long rgb32) {
mem_.setDmgPaletteColor(palNum, colorNum, rgb32);
}
+58
View File
@@ -0,0 +1,58 @@
/***************************************************************************
Copyright (C) 2007 by Nach
http://nsrt.edgeemu.com
Copyright (C) 2007-2011 by sinamas <sinamas at users.sourceforge.net>
sinamas@users.sourceforge.net
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License version 2 as
published by the Free Software Foundation.
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 version 2 for more details.
You should have received a copy of the GNU General Public License
version 2 along with this program; if not, write to the
Free Software Foundation, Inc.,
51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
***************************************************************************/
#ifndef GAMBATTE_MEMFILE_H
#define GAMBATTE_MEMFILE_H
#include <string.h>
#include "file.h"
namespace gambatte {
class MemFile : public File {
public:
explicit MemFile(const void *data, size_t size)
: data_(static_cast<const char*>(data))
, size_(size)
, offset_(0)
{
}
virtual void read(char *buffer, size_t amount) {
size_t remaining = size_ - offset_;
size_t bytes_to_read = amount < remaining ? amount : remaining;
memcpy(buffer, data_ + offset_, bytes_to_read);
offset_ += bytes_to_read;
}
virtual void rewind() { offset_ = 0; }
virtual size_t size() const { return size_; };
virtual bool fail() const { return false; }
private:
const char *data_;
size_t size_;
size_t offset_;
};
}
#endif
@@ -16,6 +16,8 @@
// 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
//
#include "file/file.h"
#include "file/memfile.h"
#include "gambatte.h"
#include "cpu.h"
#include "initstate.h"
@@ -96,11 +98,24 @@ void GB::setSaveDir(std::string const &sdir) {
p_->cpu.setSaveDir(sdir);
}
LoadRes GB::load(std::string const &romfile, unsigned const flags) {
LoadRes GB::load(const void *rom,
size_t size,
std::string const &filename,
unsigned const flags) {
MemFile file(rom, size);
return load(file, filename, flags);
}
LoadRes GB::load(std::string const &filename, unsigned const flags) {
transfer_ptr<File> file = newFileInstance(filename);
return load(*file, filename, flags);
}
LoadRes GB::load(File &file, std::string const &filename, unsigned const flags) {
if (p_->cpu.loaded())
p_->cpu.saveSavedata();
LoadRes const loadres = p_->cpu.load(romfile,
LoadRes const loadres = p_->cpu.load(file, filename,
flags & FORCE_DMG,
flags & MULTICART_COMPAT);
if (loadres == LOADRES_OK) {
@@ -131,10 +146,15 @@ void GB::saveSavedata() {
p_->cpu.saveSavedata();
}
void GB::setCgbColorCorrection(int optNum) {
p_->cpu.setCgbColorCorrection(optNum);
}
void GB::setDmgPaletteColor(int palNum, int colorNum, unsigned long rgb32) {
p_->cpu.setDmgPaletteColor(palNum, colorNum, rgb32);
}
//> OpenEmu
bool GB::serializeState(std::ostream &stream) {
if (p_->cpu.loaded()) {
SaveState state;
@@ -162,6 +182,7 @@ bool GB::deserializeState(std::istream &stream) {
return false;
}
//< OpenEmu
bool GB::loadState(std::string const &filepath) {
if (p_->cpu.loaded()) {
p_->cpu.saveSavedata();
@@ -27,6 +27,8 @@
namespace gambatte {
class File;
enum { BG_PALETTE = 0, SP1_PALETTE = 1, SP2_PALETTE = 2 };
class GB {
@@ -52,6 +54,17 @@ public:
*/
LoadRes load(std::string const &romfile, unsigned flags = 0);
/**
* Load an in-memory ROM image.
*
* @param rom The ROM image data to load.
* @param size The size of the ROM image, in bytes.
* @param filename A filename, which is only used for naming save files.
* @param flags ORed combination of LoadFlags.
* @return 0 on success, negative value on failure.
*/
LoadRes load(const void *rom, size_t size, std::string const &filename, unsigned flags = 0);
/**
* Emulates until at least 'samples' audio samples are produced in the
* supplied audio buffer, or until a video frame has been drawn.
@@ -89,6 +102,11 @@ public:
*/
void reset();
/**
* @param optNum 0 <= palNum < 1
*/
void setCgbColorCorrection(int optNum);
/**
* @param palNum 0 <= palNum < 3. One of BG_PALETTE, SP1_PALETTE and SP2_PALETTE.
* @param colorNum 0 <= colorNum < 4
@@ -113,6 +131,7 @@ public:
/** Writes persistent cartridge data to disk. Done implicitly on ROM close. */
void saveSavedata();
//> OpenEmu
/** Serializes state data to 'stream'
* @return success
*/
@@ -123,6 +142,7 @@ public:
*/
bool deserializeState(std::istream &stream);
//< OpenEmu
/**
* Saves emulator state to the state slot selected with selectState().
* The data will be stored in the directory given by setSaveDir().
@@ -191,6 +211,8 @@ public:
void setGameShark(std::string const &codes);
private:
LoadRes load(File &file, std::string const &filename, unsigned flags);
struct Priv;
Priv *const p_;
@@ -19,17 +19,6 @@
#ifndef GAMBATTE_INT_H
#define GAMBATTE_INT_H
#ifdef HAVE_CSTDINT
#include <cstdint>
namespace gambatte {
using std::uint_least32_t;
using std::uint_least16_t;
}
#elif defined(HAVE_STDINT_H)
#include <stdint.h>
namespace gambatte {
@@ -37,26 +26,4 @@ using ::uint_least32_t;
using ::uint_least16_t;
}
#else
namespace gambatte {
#ifdef CHAR_LEAST_32
typedef unsigned char uint_least32_t;
#elif defined(SHORT_LEAST_32)
typedef unsigned short uint_least32_t;
#elif defined(INT_LEAST_32)
typedef unsigned uint_least32_t;
#else
typedef unsigned long uint_least32_t;
#endif
#ifdef CHAR_LEAST_16
typedef unsigned char uint_least16_t;
#else
typedef unsigned short uint_least16_t;
#endif
}
#endif
#endif
View File
@@ -78,6 +78,8 @@ void Interrupter::setGameShark(std::string const &codes) {
gsCodes_.clear();
for (std::size_t pos = 0; pos < codes.length(); pos += code.length() + 1) {
// OpenEmu
//code = codes.substr(pos, codes.find(';', pos) - pos);
code = codes.substr(pos, codes.find('+', pos) - pos);
if (code.length() >= 8) {
GsCode gs;
@@ -94,6 +96,8 @@ void Interrupter::setGameShark(std::string const &codes) {
void Interrupter::applyVblankCheats(unsigned long const cc, Memory &memory) {
for (std::size_t i = 0, size = gsCodes_.size(); i < size; ++i) {
// OpenEmu
//if (gsCodes_[i].type == 0x01)
if (gsCodes_[i].type == 0x01 || gsCodes_[i].type == 0x91)
memory.write(gsCodes_[i].address, gsCodes_[i].value, cc);
}
@@ -17,10 +17,13 @@
//
#include "cartridge.h"
#include "file/file.h"
// OpenEmu
//#include "file/file.h"
#include "../file/file.h"
#include "../savestate.h"
#include "pakinfo_internal.h"
#include <algorithm>
#include <cstring>
#include <fstream>
@@ -556,12 +559,12 @@ void Cartridge::setSaveDir(std::string const &dir) {
saveDir_ += '/';
}
LoadRes Cartridge::loadROM(std::string const &romfile,
LoadRes Cartridge::loadROM(File &file,
std::string const &filename,
bool const forceDmg,
bool const multicartCompat)
{
scoped_ptr<File> const rom(newFileInstance(romfile));
if (rom->fail())
if (file.fail())
return LOADRES_IO_ERROR;
enum Cartridgetype { type_plain,
@@ -577,7 +580,7 @@ LoadRes Cartridge::loadROM(std::string const &romfile,
{
unsigned char header[0x150];
rom->read(reinterpret_cast<char *>(header), sizeof header);
file.read(reinterpret_cast<char *>(header), sizeof header);
switch (header[0x0147]) {
case 0x00: type = type_plain; break;
@@ -634,8 +637,8 @@ LoadRes Cartridge::loadROM(std::string const &romfile,
cgb = header[0x0143] >> 7 & (1 ^ forceDmg);
}
std::size_t const filesize = rom->size();
rombanks = std::max(pow2ceil(filesize / rombank_size()), 2u);
std::size_t const filesize = file.size();
rombanks = std::max(pow2ceil(filesize / 0x4000), 2u);
defaultSaveBasePath_.clear();
ggUndoList_.clear();
@@ -643,17 +646,17 @@ LoadRes Cartridge::loadROM(std::string const &romfile,
memptrs_.reset(rombanks, rambanks, cgb ? 8 : 2);
rtc_.set(false, 0);
rom->rewind();
rom->read(reinterpret_cast<char*>(memptrs_.romdata()), filesize / rombank_size() * rombank_size());
std::memset(memptrs_.romdata() + filesize / rombank_size() * rombank_size(),
file.rewind();
file.read(reinterpret_cast<char*>(memptrs_.romdata()), filesize / 0x4000 * 0x4000ul);
std::memset(memptrs_.romdata() + filesize / 0x4000 * 0x4000ul,
0xFF,
(rombanks - filesize / rombank_size()) * rombank_size());
enforce8bit(memptrs_.romdata(), rombanks * rombank_size());
(rombanks - filesize / 0x4000) * 0x4000ul);
enforce8bit(memptrs_.romdata(), rombanks * 0x4000ul);
if (rom->fail())
if (file.fail())
return LOADRES_IO_ERROR;
defaultSaveBasePath_ = stripExtension(romfile);
defaultSaveBasePath_ = stripExtension(filename);
switch (type) {
case type_plain: mbc_.reset(new Mbc0(memptrs_)); break;
@@ -755,6 +758,8 @@ void Cartridge::setGameGenie(std::string const &codes) {
std::string code;
for (std::size_t pos = 0; pos < codes.length(); pos += code.length() + 1) {
// OpenEmu
//code = codes.substr(pos, codes.find(';', pos) - pos);
code = codes.substr(pos, codes.find('+', pos) - pos);
applyGameGenie(code);
}
@@ -30,6 +30,8 @@
namespace gambatte {
class File;
class Mbc {
public:
virtual ~Mbc() {}
@@ -67,7 +69,7 @@ public:
void saveSavedata();
std::string const saveBasePath() const;
void setSaveDir(std::string const &dir);
LoadRes loadROM(std::string const &romfile, bool forceDmg, bool multicartCompat);
LoadRes loadROM(File &file, std::string const &filename, bool forceDmg, bool multicartCompat);
char const * romTitle() const { return reinterpret_cast<char const *>(memptrs_.romdata() + 0x134); }
class PakInfo const pakInfo(bool multicartCompat) const;
void setGameGenie(std::string const &codes);
@@ -76,7 +78,7 @@ private:
struct AddrData {
unsigned long addr;
unsigned char data;
AddrData(unsigned long addr, unsigned data) : addr(addr), data(data) {}
AddrData(unsigned long _addr, unsigned _data) : addr(_addr), data(_data) {}
};
MemPtrs memptrs_;
@@ -4,7 +4,7 @@
namespace gambatte {
enum { flag_multipak = 1, flag_header_checksum_ok = 2, };
enum { flag_multipak = 1, flag_header_checksum_ok = 2 };
static bool isHeaderChecksumOk(unsigned const char header[]) {
unsigned csum = 0;
@@ -1149,8 +1149,8 @@ void Memory::nontrivial_write(unsigned const p, unsigned const data, unsigned lo
ioamhram_[p - mm_oam_begin] = data;
}
LoadRes Memory::loadROM(std::string const &romfile, bool const forceDmg, bool const multicartCompat) {
if (LoadRes const fail = cart_.loadROM(romfile, forceDmg, multicartCompat))
LoadRes Memory::loadROM(File &file, std::string const &filename, bool const forceDmg, bool const multicartCompat) {
if (LoadRes const fail = cart_.loadROM(file, filename, forceDmg, multicartCompat))
return fail;
psg_.init(cart_.isCgb());
@@ -28,8 +28,9 @@
namespace gambatte {
class InputGetter;
class File;
class FilterInfo;
class InputGetter;
class Memory {
public:
@@ -93,7 +94,7 @@ public:
unsigned long event(unsigned long cycleCounter);
unsigned long resetCounters(unsigned long cycleCounter);
LoadRes loadROM(std::string const &romfile, bool forceDmg, bool multicartCompat);
LoadRes loadROM(File &file, std::string const &filename, bool forceDmg, bool multicartCompat);
void setSaveDir(std::string const &dir) { cart_.setSaveDir(dir); }
void setInputGetter(InputGetter *getInput) { getInput_ = getInput; }
void setEndtime(unsigned long cc, unsigned long inc);
@@ -104,6 +105,10 @@ public:
lcd_.setVideoBuffer(videoBuf, pitch);
}
void setCgbColorCorrection(int optNum) {
lcd_.setCgbColorCorrection(optNum);
}
void setDmgPaletteColor(int palNum, int colorNum, unsigned long rgb32) {
lcd_.setDmgPaletteColor(palNum, colorNum, rgb32);
}
+448
View File
@@ -0,0 +1,448 @@
//
// Copyright (C) 2008 by sinamas <sinamas at users.sourceforge.net>
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License version 2 as
// published by the Free Software Foundation.
//
// 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 version 2 for more details.
//
// You should have received a copy of the GNU General Public License
// version 2 along with this program; if not, write to the
// Free Software Foundation, Inc.,
// 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
//
#include "statesaver.h"
#include "savestate.h"
#include "array.h"
#include <algorithm>
#include <fstream>
#include <functional>
#include <vector>
#include <cstring>
namespace {
using namespace gambatte;
enum AsciiChar {
NUL, SOH, STX, ETX, EOT, ENQ, ACK, BEL, BS, TAB, LF, VT, FF, CR, SO, SI,
DLE, DC1, DC2, DC3, DC4, NAK, SYN, ETB, CAN, EM, SUB, ESC, FS, GS, RS, US,
SP, XCL, QOT, HSH, DLR, PRC, AMP, APO, LPA, RPA, AST, PLU, COM, HYP, STP, DIV,
NO0, NO1, NO2, NO3, NO4, NO5, NO6, NO7, NO8, NO9, CLN, SCL, LT, EQL, GT, QTN,
AT, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O,
P, Q, R, S, T, U, V, W, X, Y, Z, LBX, BSL, RBX, CAT, UND,
ACN, a, b, c, d, e, f, g, h, i, j, k, l, m, n, o,
p, q, r, s, t, u, v, w, x, y, z, LBR, BAR, RBR, TLD, DEL
};
struct Saver {
char const *label;
void (*save)(std::ofstream &file, SaveState const &state);
void (*load)(std::ifstream &file, SaveState &state);
std::size_t labelsize;
};
inline bool operator<(Saver const &l, Saver const &r) {
return std::strcmp(l.label, r.label) < 0;
}
void put24(std::ofstream &file, unsigned long data) {
file.put(data >> 16 & 0xFF);
file.put(data >> 8 & 0xFF);
file.put(data & 0xFF);
}
void put32(std::ofstream &file, unsigned long data) {
file.put(data >> 24 & 0xFF);
file.put(data >> 16 & 0xFF);
file.put(data >> 8 & 0xFF);
file.put(data & 0xFF);
}
void write(std::ofstream &file, unsigned char data) {
static char const inf[] = { 0x00, 0x00, 0x01 };
file.write(inf, sizeof inf);
file.put(data & 0xFF);
}
void write(std::ofstream &file, unsigned short data) {
static char const inf[] = { 0x00, 0x00, 0x02 };
file.write(inf, sizeof inf);
file.put(data >> 8 & 0xFF);
file.put(data & 0xFF);
}
void write(std::ofstream &file, unsigned long data) {
static char const inf[] = { 0x00, 0x00, 0x04 };
file.write(inf, sizeof inf);
put32(file, data);
}
void write(std::ofstream &file, unsigned char const *data, std::size_t size) {
put24(file, size);
file.write(reinterpret_cast<char const *>(data), size);
}
void write(std::ofstream &file, bool const *data, std::size_t size) {
put24(file, size);
std::for_each(data, data + size,
std::bind1st(std::mem_fun(&std::ofstream::put), &file));
}
unsigned long get24(std::ifstream &file) {
unsigned long tmp = file.get() & 0xFF;
tmp = tmp << 8 | (file.get() & 0xFF);
return tmp << 8 | (file.get() & 0xFF);
}
unsigned long read(std::ifstream &file) {
unsigned long size = get24(file);
if (size > 4) {
file.ignore(size - 4);
size = 4;
}
unsigned long out = 0;
switch (size) {
case 4: out = (out | (file.get() & 0xFF)) << 8; // fall through.
case 3: out = (out | (file.get() & 0xFF)) << 8; // fall through.
case 2: out = (out | (file.get() & 0xFF)) << 8; // fall through.
case 1: out = out | (file.get() & 0xFF);
}
return out;
}
inline void read(std::ifstream &file, unsigned char &data) {
data = read(file) & 0xFF;
}
inline void read(std::ifstream &file, unsigned short &data) {
data = read(file) & 0xFFFF;
}
inline void read(std::ifstream &file, unsigned long &data) {
data = read(file);
}
void read(std::ifstream &file, unsigned char *buf, std::size_t bufsize) {
std::size_t const size = get24(file);
std::size_t const minsize = std::min(size, bufsize);
file.read(reinterpret_cast<char*>(buf), minsize);
file.ignore(size - minsize);
if (static_cast<unsigned char>(0x100)) {
for (std::size_t i = 0; i < minsize; ++i)
buf[i] &= 0xFF;
}
}
void read(std::ifstream &file, bool *buf, std::size_t bufsize) {
std::size_t const size = get24(file);
std::size_t const minsize = std::min(size, bufsize);
for (std::size_t i = 0; i < minsize; ++i)
buf[i] = file.get();
file.ignore(size - minsize);
}
} // anon namespace
namespace gambatte {
class SaverList {
public:
typedef std::vector<Saver> list_t;
typedef list_t::const_iterator const_iterator;
SaverList();
const_iterator begin() const { return list.begin(); }
const_iterator end() const { return list.end(); }
std::size_t maxLabelsize() const { return maxLabelsize_; }
private:
list_t list;
std::size_t maxLabelsize_;
};
static void push(SaverList::list_t &list, char const *label,
void (*save)(std::ofstream &file, SaveState const &state),
void (*load)(std::ifstream &file, SaveState &state),
std::size_t labelsize) {
Saver saver = { label, save, load, labelsize };
list.push_back(saver);
}
SaverList::SaverList()
: maxLabelsize_(0)
{
#define ADD(arg) do { \
struct Func { \
static void save(std::ofstream &file, SaveState const &state) { write(file, state.arg); } \
static void load(std::ifstream &file, SaveState &state) { read(file, state.arg); } \
}; \
push(list, label, Func::save, Func::load, sizeof label); \
} while (0)
#define ADDPTR(arg) do { \
struct Func { \
static void save(std::ofstream &file, SaveState const &state) { \
write(file, state.arg.get(), state.arg.size()); \
} \
static void load(std::ifstream &file, SaveState &state) { \
read(file, state.arg.ptr, state.arg.size()); \
} \
}; \
push(list, label, Func::save, Func::load, sizeof label); \
} while (0)
#define ADDARRAY(arg) do { \
struct Func { \
static void save(std::ofstream &file, SaveState const &state) { \
write(file, state.arg, sizeof state.arg); \
} \
static void load(std::ifstream &file, SaveState &state) { \
read(file, state.arg, sizeof state.arg); \
} \
}; \
push(list, label, Func::save, Func::load, sizeof label); \
} while (0)
{ static char const label[] = { c,c, NUL }; ADD(cpu.cycleCounter); }
{ static char const label[] = { p,c, NUL }; ADD(cpu.pc); }
{ static char const label[] = { s,p, NUL }; ADD(cpu.sp); }
{ static char const label[] = { a, NUL }; ADD(cpu.a); }
{ static char const label[] = { b, NUL }; ADD(cpu.b); }
{ static char const label[] = { c, NUL }; ADD(cpu.c); }
{ static char const label[] = { d, NUL }; ADD(cpu.d); }
{ static char const label[] = { e, NUL }; ADD(cpu.e); }
{ static char const label[] = { f, NUL }; ADD(cpu.f); }
{ static char const label[] = { h, NUL }; ADD(cpu.h); }
{ static char const label[] = { l, NUL }; ADD(cpu.l); }
{ static char const label[] = { o,p, NUL }; ADD(cpu.opcode); }
{ static char const label[] = { f,e,t,c,h,e,d, NUL }; ADD(cpu.prefetched); }
{ static char const label[] = { s,k,i,p, NUL }; ADD(cpu.skip); }
{ static char const label[] = { h,a,l,t, NUL }; ADD(mem.halted); }
{ static char const label[] = { v,r,a,m, NUL }; ADDPTR(mem.vram); }
{ static char const label[] = { s,r,a,m, NUL }; ADDPTR(mem.sram); }
{ static char const label[] = { w,r,a,m, NUL }; ADDPTR(mem.wram); }
{ static char const label[] = { h,r,a,m, NUL }; ADDPTR(mem.ioamhram); }
{ static char const label[] = { l,d,i,v,u,p, NUL }; ADD(mem.divLastUpdate); }
{ static char const label[] = { l,t,i,m,a,u,p, NUL }; ADD(mem.timaLastUpdate); }
{ static char const label[] = { t,m,a,t,i,m,e, NUL }; ADD(mem.tmatime); }
{ static char const label[] = { s,e,r,i,a,l,t, NUL }; ADD(mem.nextSerialtime); }
{ static char const label[] = { l,o,d,m,a,u,p, NUL }; ADD(mem.lastOamDmaUpdate); }
{ static char const label[] = { m,i,n,i,n,t,t, NUL }; ADD(mem.minIntTime); }
{ static char const label[] = { u,n,h,a,l,t,t, NUL }; ADD(mem.unhaltTime); }
{ static char const label[] = { r,o,m,b,a,n,k, NUL }; ADD(mem.rombank); }
{ static char const label[] = { d,m,a,s,r,c, NUL }; ADD(mem.dmaSource); }
{ static char const label[] = { d,m,a,d,s,t, NUL }; ADD(mem.dmaDestination); }
{ static char const label[] = { r,a,m,b,a,n,k, NUL }; ADD(mem.rambank); }
{ static char const label[] = { o,d,m,a,p,o,s, NUL }; ADD(mem.oamDmaPos); }
{ static char const label[] = { h,l,t,h,d,m,a, NUL }; ADD(mem.haltHdmaState); }
{ static char const label[] = { i,m,e, NUL }; ADD(mem.IME); }
{ static char const label[] = { s,r,a,m,o,n, NUL }; ADD(mem.enableRam); }
{ static char const label[] = { r,a,m,b,m,o,d, NUL }; ADD(mem.rambankMode); }
{ static char const label[] = { h,d,m,a, NUL }; ADD(mem.hdmaTransfer); }
{ static char const label[] = { b,g,p, NUL }; ADDPTR(ppu.bgpData); }
{ static char const label[] = { o,b,j,p, NUL }; ADDPTR(ppu.objpData); }
{ static char const label[] = { s,p,o,s,b,u,f, NUL }; ADDPTR(ppu.oamReaderBuf); }
{ static char const label[] = { s,p,s,z,b,u,f, NUL }; ADDPTR(ppu.oamReaderSzbuf); }
{ static char const label[] = { s,p,a,t,t,r, NUL }; ADDARRAY(ppu.spAttribList); }
{ static char const label[] = { s,p,b,y,t,e,NO0, NUL }; ADDARRAY(ppu.spByte0List); }
{ static char const label[] = { s,p,b,y,t,e,NO1, NUL }; ADDARRAY(ppu.spByte1List); }
{ static char const label[] = { v,c,y,c,l,e,s, NUL }; ADD(ppu.videoCycles); }
{ static char const label[] = { e,d,M,NO0,t,i,m, NUL }; ADD(ppu.enableDisplayM0Time); }
{ static char const label[] = { m,NO0,t,i,m,e, NUL }; ADD(ppu.lastM0Time); }
{ static char const label[] = { n,m,NO0,i,r,q, NUL }; ADD(ppu.nextM0Irq); }
{ static char const label[] = { b,g,t,w, NUL }; ADD(ppu.tileword); }
{ static char const label[] = { b,g,n,t,w, NUL }; ADD(ppu.ntileword); }
{ static char const label[] = { w,i,n,y,p,o,s, NUL }; ADD(ppu.winYPos); }
{ static char const label[] = { x,p,o,s, NUL }; ADD(ppu.xpos); }
{ static char const label[] = { e,n,d,x, NUL }; ADD(ppu.endx); }
{ static char const label[] = { p,p,u,r,NO0, NUL }; ADD(ppu.reg0); }
{ static char const label[] = { p,p,u,r,NO1, NUL }; ADD(ppu.reg1); }
{ static char const label[] = { b,g,a,t,r,b, NUL }; ADD(ppu.attrib); }
{ static char const label[] = { b,g,n,a,t,r,b, NUL }; ADD(ppu.nattrib); }
{ static char const label[] = { p,p,u,s,t,a,t, NUL }; ADD(ppu.state); }
{ static char const label[] = { n,s,p,r,i,t,e, NUL }; ADD(ppu.nextSprite); }
{ static char const label[] = { c,s,p,r,i,t,e, NUL }; ADD(ppu.currentSprite); }
{ static char const label[] = { l,y,c, NUL }; ADD(ppu.lyc); }
{ static char const label[] = { m,NO0,l,y,c, NUL }; ADD(ppu.m0lyc); }
{ static char const label[] = { o,l,d,w,y, NUL }; ADD(ppu.oldWy); }
{ static char const label[] = { w,i,n,d,r,a,w, NUL }; ADD(ppu.winDrawState); }
{ static char const label[] = { w,s,c,x, NUL }; ADD(ppu.wscx); }
{ static char const label[] = { w,e,m,a,s,t,r, NUL }; ADD(ppu.weMaster); }
{ static char const label[] = { l,c,d,s,i,r,q, NUL }; ADD(ppu.pendingLcdstatIrq); }
{ static char const label[] = { s,p,u,c,n,t,r, NUL }; ADD(spu.cycleCounter); }
{ static char const label[] = { s,p,u,c,n,t,l, NUL }; ADD(spu.lastUpdate); }
{ static char const label[] = { s,w,p,c,n,t,r, NUL }; ADD(spu.ch1.sweep.counter); }
{ static char const label[] = { s,w,p,s,h,d,w, NUL }; ADD(spu.ch1.sweep.shadow); }
{ static char const label[] = { s,w,p,n,e,g, NUL }; ADD(spu.ch1.sweep.neg); }
{ static char const label[] = { d,u,t,NO1,c,t,r, NUL }; ADD(spu.ch1.duty.nextPosUpdate); }
{ static char const label[] = { d,u,t,NO1,p,o,s, NUL }; ADD(spu.ch1.duty.pos); }
{ static char const label[] = { d,u,t,NO1,h,i, NUL }; ADD(spu.ch1.duty.high); }
{ static char const label[] = { e,n,v,NO1,c,t,r, NUL }; ADD(spu.ch1.env.counter); }
{ static char const label[] = { e,n,v,NO1,v,o,l, NUL }; ADD(spu.ch1.env.volume); }
{ static char const label[] = { l,e,n,NO1,c,t,r, NUL }; ADD(spu.ch1.lcounter.counter); }
{ static char const label[] = { l,e,n,NO1,v,a,l, NUL }; ADD(spu.ch1.lcounter.lengthCounter); }
{ static char const label[] = { n,r,NO1,NO0, NUL }; ADD(spu.ch1.sweep.nr0); }
{ static char const label[] = { n,r,NO1,NO3, NUL }; ADD(spu.ch1.duty.nr3); }
{ static char const label[] = { n,r,NO1,NO4, NUL }; ADD(spu.ch1.nr4); }
{ static char const label[] = { c,NO1,m,a,s,t,r, NUL }; ADD(spu.ch1.master); }
{ static char const label[] = { d,u,t,NO2,c,t,r, NUL }; ADD(spu.ch2.duty.nextPosUpdate); }
{ static char const label[] = { d,u,t,NO2,p,o,s, NUL }; ADD(spu.ch2.duty.pos); }
{ static char const label[] = { d,u,t,NO2,h,i, NUL }; ADD(spu.ch2.duty.high); }
{ static char const label[] = { e,n,v,NO2,c,t,r, NUL }; ADD(spu.ch2.env.counter); }
{ static char const label[] = { e,n,v,NO2,v,o,l, NUL }; ADD(spu.ch2.env.volume); }
{ static char const label[] = { l,e,n,NO2,c,t,r, NUL }; ADD(spu.ch2.lcounter.counter); }
{ static char const label[] = { l,e,n,NO2,v,a,l, NUL }; ADD(spu.ch2.lcounter.lengthCounter); }
{ static char const label[] = { n,r,NO2,NO3, NUL }; ADD(spu.ch2.duty.nr3); }
{ static char const label[] = { n,r,NO2,NO4, NUL }; ADD(spu.ch2.nr4); }
{ static char const label[] = { c,NO2,m,a,s,t,r, NUL }; ADD(spu.ch2.master); }
{ static char const label[] = { w,a,v,e,r,a,m, NUL }; ADDPTR(spu.ch3.waveRam); }
{ static char const label[] = { l,e,n,NO3,c,t,r, NUL }; ADD(spu.ch3.lcounter.counter); }
{ static char const label[] = { l,e,n,NO3,v,a,l, NUL }; ADD(spu.ch3.lcounter.lengthCounter); }
{ static char const label[] = { w,a,v,e,c,t,r, NUL }; ADD(spu.ch3.waveCounter); }
{ static char const label[] = { l,w,a,v,r,d,t, NUL }; ADD(spu.ch3.lastReadTime); }
{ static char const label[] = { w,a,v,e,p,o,s, NUL }; ADD(spu.ch3.wavePos); }
{ static char const label[] = { w,a,v,s,m,p,l, NUL }; ADD(spu.ch3.sampleBuf); }
{ static char const label[] = { n,r,NO3,NO3, NUL }; ADD(spu.ch3.nr3); }
{ static char const label[] = { n,r,NO3,NO4, NUL }; ADD(spu.ch3.nr4); }
{ static char const label[] = { c,NO3,m,a,s,t,r, NUL }; ADD(spu.ch3.master); }
{ static char const label[] = { l,f,s,r,c,t,r, NUL }; ADD(spu.ch4.lfsr.counter); }
{ static char const label[] = { l,f,s,r,r,e,g, NUL }; ADD(spu.ch4.lfsr.reg); }
{ static char const label[] = { e,n,v,NO4,c,t,r, NUL }; ADD(spu.ch4.env.counter); }
{ static char const label[] = { e,n,v,NO4,v,o,l, NUL }; ADD(spu.ch4.env.volume); }
{ static char const label[] = { l,e,n,NO4,c,t,r, NUL }; ADD(spu.ch4.lcounter.counter); }
{ static char const label[] = { l,e,n,NO4,v,a,l, NUL }; ADD(spu.ch4.lcounter.lengthCounter); }
{ static char const label[] = { n,r,NO4,NO4, NUL }; ADD(spu.ch4.nr4); }
{ static char const label[] = { c,NO4,m,a,s,t,r, NUL }; ADD(spu.ch4.master); }
{ static char const label[] = { r,t,c,b,a,s,e, NUL }; ADD(rtc.baseTime); }
{ static char const label[] = { r,t,c,h,a,l,t, NUL }; ADD(rtc.haltTime); }
{ static char const label[] = { r,t,c,d,h, NUL }; ADD(rtc.dataDh); }
{ static char const label[] = { r,t,c,d,l, NUL }; ADD(rtc.dataDl); }
{ static char const label[] = { r,t,c,h, NUL }; ADD(rtc.dataH); }
{ static char const label[] = { r,t,c,m, NUL }; ADD(rtc.dataM); }
{ static char const label[] = { r,t,c,s, NUL }; ADD(rtc.dataS); }
{ static char const label[] = { r,t,c,l,l,d, NUL }; ADD(rtc.lastLatchData); }
#undef ADD
#undef ADDPTR
#undef ADDARRAY
// sort list for binary search/std::lower_bound use.
std::sort(list.begin(), list.end());
for (const_iterator it = list.begin(); it != list.end(); ++it)
maxLabelsize_ = std::max(maxLabelsize_, it->labelsize);
}
}
namespace {
struct RgbSum { unsigned long rb, g; };
void addPairs(RgbSum *const sum, uint_least32_t const *const p) {
sum[0].rb += (p[0] & 0xFF00FF) + (p[3] & 0xFF00FF);
sum[0].g += (p[0] & 0x00FF00) + (p[3] & 0x00FF00);
sum[1].rb += (p[1] & 0xFF00FF) + (p[2] & 0xFF00FF);
sum[1].g += (p[1] & 0x00FF00) + (p[2] & 0x00FF00);
}
void blendPairs(RgbSum *const dst, RgbSum const *const sums) {
dst->rb = sums[1].rb * 8 + (sums[0].rb - sums[1].rb) * 3;
dst->g = sums[1].g * 8 + (sums[0].g - sums[1].g ) * 3;
}
void writeSnapShot(std::ofstream &file, uint_least32_t const *src, std::ptrdiff_t const pitch) {
put24(file, src ? StateSaver::ss_width * StateSaver::ss_height * sizeof *src : 0);
if (src) {
uint_least32_t buf[StateSaver::ss_width];
for (unsigned h = StateSaver::ss_height; h--;) {
for (unsigned x = 0; x < StateSaver::ss_width; ++x) {
uint_least32_t const *const p = src + x * StateSaver::ss_div;
RgbSum sum[] = { {0, 0}, {0, 0}, {0, 0}, {0, 0} };
addPairs(sum , p );
addPairs(sum + 2, p + pitch );
addPairs(sum + 2, p + pitch * 2);
addPairs(sum , p + pitch * 3);
blendPairs(sum, sum);
blendPairs(sum + 1, sum + 2);
blendPairs(sum, sum);
buf[x] = ((sum[0].rb & 0xFF00FF00) | (sum[0].g & 0x00FF0000)) >> 8;
}
file.write(reinterpret_cast<char const *>(buf), sizeof buf);
src += pitch * StateSaver::ss_div;
}
}
}
SaverList list;
} // anon namespace
bool StateSaver::saveState(SaveState const &state,
uint_least32_t const *const videoBuf,
std::ptrdiff_t const pitch, std::string const &filename) {
std::ofstream file(filename.c_str(), std::ios_base::binary);
if (!file)
return false;
{ static char const ver[] = { 0, 1 }; file.write(ver, sizeof ver); }
writeSnapShot(file, videoBuf, pitch);
for (SaverList::const_iterator it = list.begin(); it != list.end(); ++it) {
file.write(it->label, it->labelsize);
(*it->save)(file, state);
}
return !file.fail();
}
bool StateSaver::loadState(SaveState &state, std::string const &filename) {
std::ifstream file(filename.c_str(), std::ios_base::binary);
if (!file || file.get() != 0)
return false;
file.ignore();
file.ignore(get24(file));
Array<char> const labelbuf(list.maxLabelsize());
Saver const labelbufSaver = { labelbuf, 0, 0, list.maxLabelsize() };
SaverList::const_iterator done = list.begin();
while (file.good() && done != list.end()) {
file.getline(labelbuf, list.maxLabelsize(), NUL);
SaverList::const_iterator it = done;
if (std::strcmp(labelbuf, it->label)) {
it = std::lower_bound(it + 1, list.end(), labelbufSaver);
if (it == list.end() || std::strcmp(labelbuf, it->label)) {
file.ignore(get24(file));
continue;
}
} else
++done;
(*it->load)(file, state);
}
state.cpu.cycleCounter &= 0x7FFFFFFF;
state.spu.cycleCounter &= 0x7FFFFFFF;
return true;
}
@@ -35,9 +35,11 @@ public:
enum { ss_width = 160 >> ss_shift };
enum { ss_height = 144 >> ss_shift };
//> OpenEmu
static bool serializeState(SaveState const &state, std::ostream &stream);
static bool deserializeState(SaveState &state, std::istream &stream);
//< OpenEmu
static bool saveState(SaveState const &state,
uint_least32_t const *videoBuf, std::ptrdiff_t pitch,
std::string const &filename);

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