- add secure area decryption from ndstool (little endian host only)

- change how the portable packed structure declarations are made
- reorganize and cleanup changelog
This commit is contained in:
zeromus 2008-12-25 20:43:59 +00:00
parent 296e5e217d
commit f1c135e929
16 changed files with 2659 additions and 1016 deletions

View File

@ -1,265 +1,266 @@
0.8 -> 0.9
There have been so many changes that this list can hardly be considered complete.
General/Core:
- Added "high-level" check for DMAs and Timer for minor (really minor) speed up [shash]
- Changed instruction execution to 16 at a time blocks (tested and stable) [shash]
- Really minor memory access speed up (mainly added for clarity) [shash]
- Added transparency and fixed material alpha support and alpha testing on the 3D core [shash]
- Changed how depth initial values are calculated (fixes SM64DS skybox) [shash]
- Added SSE2 version for some matrix routines [CrazyMax]
- Fixes in IPC FIFO [CrazyMax]
- Add Geometry FIFO simulation (New SMB and others games not freeze now) [CrazyMax]
- Fix in capture display (many games with both 3D screen not blinking now) [CrazyMax]
- Fix in master brightness (this is fix games with black screens) [CrazyMax]
- Some optimizations in code [CrazyMax]
0.8 -> 0.9
There have been so many changes that this list can hardly be considered complete.
The savestate system is totally changed and incompatible with old savestates.
General/Core:
- Convert to c++!
- Added "high-level" check for DMAs and Timer for minor (really minor) speed up [shash]
- Changed instruction execution to 16 at a time blocks (tested and stable) [shash]
- Really minor memory access speed up (mainly added for clarity) [shash]
- Fixes in IPC FIFO [CrazyMax]
- Add Geometry FIFO simulation (New SMB and others games not freeze now) [CrazyMax]
- Add cosine interpolation in the SPU (conditionally compiled) [zeromus,luigi__]
- Experiment: always one silent SPU core at 44.1khz synched with emu for more precision.
The audible core runs with the host, causing music to slow down but not tear or pitch bend. [zeromus]
- Change savestate code to support loosely bound chunks and more easily other parts of the emu (GE, GPU).
The savestate format is changed, but from now on it is in principle more resilient
(though it will continue to break as we tinker with the internals) [zeromus]
- Remove 16MB of WRAM at 0x01****** from arm9. Mapped to unused instead. What was this? [zeromus]
- Add RTC implementations (not fully) [CrazyMax]
- Add a GUI hud system; start adding some HUD elements
- Add functions for a lid open/close. Holding key (default "Backspace" in Windows port) while game is freeze/non freeze. [CrazyMax]
- Added a bunch of crazy templates to the cpu and mmu for minor speed boosts [zeromus]
- Add secure area decryption from ndstool [zeromus]
Graphics:
- Added gfx3d module which emulates the whole GE as part of the core emu. [zeromus]
- Moved the windows/cocoa OGLRender to the emu core and replace ogl_collector.
Now every platform shares the same 3d code. [zeromus]
- Reorganize 3d code to defer rendering to after 3d vblank. eliminates tearing, and texturing artifacts. [zeromus]
- Add optional fragment shading pipeline for more precision [luigi__]
- Many tweaks and improvements to 3d precision [zeromus, CrazyMax, luigi__]
- Rewrite VRAM mapping control and rendering [CrazyMax, luigi__]
- Improvements to 2d/3d compositing aiming at better NSMB rendering; still imperfect [zeromus]
- Fix in capture display (many games with both 3D screen not blinking now) [CrazyMax]
- Fix in master brightness (this is fix games with black screens) [CrazyMax]
- Added SSE2 version for some matrix routines [CrazyMax]
- Make matrix 4x4 multiply routines use W-coordinate. [zeromus]
- Add many matrix and vector functions to matrix.cpp [zeromus]
- Convert to c++!
- Added gfx3d module which emulates the whole GE as part of the core emu. Moved the windows/cocoa OGLRender to the
emu core and replace ogl_collector. Now every platform shares the same 3d code. [zeromus]
- Add in some crude interpolation in the SPU (conditionally compiled) so that I can bear to listen to it. [zeromus]
- Experiment: always one silent SPU core at 44.1khz synched with emu for more precision.
The audible core runs with the host, causing music to slow down but not tear or pitch bend. [zeromus]
- Change savestate code to support loosely bound chunks and more easily other parts of the emu (GE, GPU).
The savestate format is changed, but from now on it is in principle more resilient (it will continue to break though) [zeromus]
- Remove 16MB of WRAM at 0x01****** from arm9. Maped to unused instead. What was this? [zeromus]
- Change SPU to run two spus in parallel. SPU_core is the official one. SPU_user produces output.
This lets us do inaccurate things with SPU_user which might sound better while being more accurate with SPU_core. [zeromus]
- Add RTC implementations (not fully) [CrazyMax]
- Rewrite VRAM mapping control and render (old save states broken) [CrazyMax]
- Add a GUI hud system; start adding some HUD elements
- Add functions for a lid open/close. Holding key (default "Backspace" in Windows port) while game is freeze/non freeze. [CrazyMax]
Mac OS X port:
- Fixed: Filenames and paths with unicode characters now work. [Jeff]
- Fixed: Load state from file button works again. [Jeff]
- Save State panel now pauses emulation while the file selection box is open. [Jeff]
- Fixed: Frozen video output (and/or messed 3d emulation) after loading a state. [Jeff]
- Added option to load the most recent file upon launching the program. [Jeff]
- Added French translation (thanks to Pierre Rudloff). [Jeff]
- Added basic key mapping configuration to application preferences (thanks to Julio GorgŽ). [Jeff]
- Added keyboard shortcuts for Execute, Pause and Reset command (thanks to Julio GorgŽ). [Jeff]
- Default key mappings are no longer case sensitive. [Jeff]
- Added ability to limit speed. [Jeff]
- Fixed: Video output should work on software-only 3D renderers. [Jeff]
Windows port:
- Removed the bug report link with a define, to avoid reports from betas/external builds [shash]
- Added the version on window bar to recognize versions from screenshots [shash]
- Changed graphics render core to DirectDraw (work faster) [CrazyMax]
- Some fixes in 3D core OGL (fixed textures) [CrazyMax]
- Added texture caching (speedup 3D core) [CrazyMax]
- Fixes clear depth (ex. Castlevania now don't flipping) [NHerve]
- Make GE matrix mult and load commands clear out unused rows and cols to identity correctly [zeromus]
- Added transparency and fixed material alpha support and alpha testing on the 3D core [shash]
- Changed how depth initial values are calculated (fixes SM64DS skybox) [shash]
- Some fixes in 3D core OGL (fixed textures) [CrazyMax]
- Added texture caching (speedup 3D core) [CrazyMax]
- Render shadow volumes [zeromus, luigi__]
- Toon shading system [luigi__]
- carry w=1 from vertex() through pipeline (this will be necessary for software 3d rendering) [zeromus]
- Track polycount better. still worthless: at the very least, it doesnt account for clipping and culling [zeromus]
- Fix errors in matrix operations regarding projection mode and pos-vector mode [zeromus]
- Fix error in command unpacking which caused some display lists to totally blow up [zeromus]
- Render shadow volumes [zeromus]
- Convert alpha and material values from [0,31], [0,7] etc ranges to opengl [0,maxint] ranges in a more precise way [zeromus]
- Fix a race condition in NDS_3D_Reset and NDS_glInit [zeromus]
- Add many of NHerve's improvements into OGLRender because I was trying to fix all the 3d issues. [zeromus]
- Toon shading infrastructure and a demo implementation [zeromus]
- Implement lighting model in software instead of using opengl; improves (potential?) compatibility [zeromus]
- Defer rendering until after flush. This was a necessary architectural change, as it permits savestate
for the display list, and allows us eventually to separate the GE emulation from the rendering [zeromus]
- Fix the 2d/3d compositing well enough for NSMB to fix bugs, but it is still bad [zeromus]
- Reorganize 3d code to defer rendering to after vblank. eliminates tearing, and maybe some texturing artifacts. [zeromus]
- Tweak optimization flags and change entire source code to use fastcall [zeromus]
- Add opengl state caching. This is of dubious performance assistance, but it is easy to take out so I am leaving it for now. [zeromus]
- Add MMU->GPU signal for when vram mappings change, which allows it to assume textures are unchanged unless vram has changed [zeromus]
- Added a bunch of crazy templates to the cpu and mmu which speed up a the emu little by optimizing variable accesses [zeromus]
- Add an arm9 cpu load average calculator similar to no$ [zeromus]
? Fix a bug in texture transformation mode 1 [zeromus]
- Fix the buggy auto frameskip logic which made the emu slow to a crawl. Now it runs fast! [zeromus]
- Fix resizing, rotate & aspect ration of main window. Add save window position and parameters [CrazyMax]
- Rewrite all debug tools (autoupdate work now) [CrazyMax]
- Add AVI output [zeromus]
- Remove multithreading from user interface after finding several synchronization issues [zeromus]
- Rewrite input core & replace config input dialog [CrazyMax]
0.7.3 -> 0.8
Cocoa:
- Save State As function now works. [Jeff B]
- Recent Items menu now works. [Jeff B]
- Opening NDS files from Finder now works. [Jeff B]
- Added screenshot feature. [Jeff B]
- Added preferences. [Jeff B]
- Many more strings are translatable now. [Jeff B]
- Default screen color is black (better represents being "off" and easier on eyes at night). [Jeff B]
- Added sound. [Jeff B]
- Now is a universal binary. [Jeff B]
- Leopard resolution icon added. [Jeff B]
- Added a Japanese translation. [Jeff B]
- Added an optional status bar (resize handle no longer overlaps screen). [Jeff B]
- New ROM Info and About DeSmuME windows have been added. [Jeff B]
- Fixed several bugs in window resizing. [Jeff B]
- Added FAT image support for homebrew games (thanks to TypeError). [Jeff B]
- Key config can be changed on the command line. Save/load hotkeys changed (so expose doesn't override). [Jeff B]
- Key bindings may work better on non-US keyboards now (needs testing). [Jeff B]
general:
- Encapsulate GDB debug stub to avoid certain problems [shash]
- Fixed CPU LD*/ST* bugs [shash]
- Fixed New SMB mini-games freeze [shash]
- Fixed possible segfault in ROMReader on ia64 and amd64. [evilynux]
- Fixed a crash bug with 2D background corrupting memory [shash]
- Flag check optimization [carlo_bramini]
- Applied some endian fixes in GPU (thanks to Phazz) [Jeff B]
gtk-glade:
- Added DeSmuME version in about dialog. [evilynux]
- Updated website url in about dialog. [evilynux]
- Added Brazilian Portuguese translation by Dreampeppers99. [evilynux]
- Better desktop menu entry following FreeDesktop specifications. [evilynux]
gtk:
- Updated website url in about dialog. [evilynux]
- Better desktop menu entry following FreeDesktop specifications. [evilynux]
windows port:
- Added an "about" box [shash]
- DirectInput control interface with joystick support [CrazyMax aka mtabachenko]
- Matrix and Light viewer [Acid Burn]
0.7.2 -> 0.7.3
gtk-glade:
- Full localization using intltool/gettext. [evilynux]
general:
- Added a README.TRANSLATION documenting the localization process. [evilynux]
MacOS X:
- Initial version of the Mac interface added. [Jeff B]
0.7.1 -> 0.7.2
spu:
- big endian fixes. [cyberwarriorx]
gpu:
- big endian fixes. [marcus_c]
gtk-glade:
- opengl improvements. [masscat]
general:
- Added support for setting NDS firmware language value. [masscat]
- Function added for setting firmware language. [masscat]
- Mac/msys compilation fixes. [cyberwarriorx]
- Fix compilation when pkg-config macros are not available [evilynux]
0.7.0 -> 0.7.1
general:
- Added GDB debugger stub [masscat]
- Added new/different GBAMP CFlash image reader/writer [masscat]
gpu:
- Major speedup to the 2D core [shash]
gtk-glade:
- Added command line options. [masscat]
- Added FPS limiter [masscat]
cli:
- Added command line options. [masscat]
- Added FPS limiter [masscat]
- Added option to use OpenGl to render window (allows resizing). [masscat]
windows port:
- Added command line options. [masscat]
- Added multiple language support [cyberwarriorx]
- Added Danish language translation [thomas-2007]
0.6.0 -> 0.7.0
general:
- Added support for *.duc files [cyberwarriorx]
gpu:
- Added support for sprite rotation/scaling [shash]
- Added support for the 3D core (openGL and null plugins) [shash]
windows port:
- A bunch of fixes [Dmitry Krutskih]
- Fixed a bug in sound that was causing it to still not work for some
people [cyberwarriorx]
gtk:
- Added 3D emulation
- Added command line options.
- Added option to use OpenGL to render window (allows resizing).
gtk-glade:
- Added 3D emulation
0.5.0 -> 0.6.0
general:
- Added zipped (based on zziplib) and gzipped (based on zlib) rom support.
arm:
- Added relocation interrupt vector.
- Added region access right checks.
- Enabled LDC/STC instructions.
- Fixed powersave (cp15) IRQ wait.
- Fixed MOV instructions
gpu:
- Added special color effects.
- Added windowing feature.
- Fixed transparent direct color backgrounds.
- Fixed disabled sprites showing.
- Fixed 8/32 bit access to gpu registers.
- Fixed missing backgrounds
- Support for master brightness
wifi:
- Added RF chip interface.
- Added BB chip interface.
windows port:
- Fixed address calculation in disassembler.
- Added Force Maintain Ratio option for window stretching
linux port (cli, gtk and gtk-glade):
all:
- Added joystick support.
- Fixed X and Y buttons.
gtk-glade:
- Added joystick configuration.
- Improved I/O registers viewer tool.
- Added save and load states support.
0.3.3 -> 0.5.0
arm:
- Fixed MSR with immediate value opcode.
- Fixed LSR_0 thumb opcode (C flag is correctly set now).
- Fixed LDR*/STR* opcodes.
- Fixed unaligned memory access on THUMB Core.
- Added relocating SWI routines.
bios:
- Added decompression functions.
- Added GetPitchTable function.
- Added GetVolumeTable function.
- Added GetCRC16 function.
- Added experimental SoundBias function.
- Added GetSineTable function.
cart:
- Added CompactFlash/FAT emulation.
- Added Get ROM chip ID Cartridge command.
gpu:
- Added framebuffer emulation.
- Fixed a bug in GPU (xfin could be greater than LG causing a segfault).
- Added support for Display Mode 0(Display Off).
- Added the basic framework for Display Mode 3(Display from Main RAM).
spu:
- Added sound emulation.
- Added sound core system.
- Added WAV write core.
- Added dummy core.
- Added Direct Sound core.
linux port:
- Added GTK+ GUI.
- Added command line interface.
- Added stylus and arm9 keypad support in CLI version.
- Added FPS display.
- Added basic frameskip.
windows port:
- Fixed a bug when displaying a ROM's information.
- Added key configuration.
- Removed the debug key.
- Added new experimental auto frameskip/frame limit code.
- Added sound settings dialog.
- Added a few menu options for accessing the website, forums, and for
submitting bugs.
general:
- Rewrote code in C.
- Fixed warnings.
- Used defines and typedef's to make things more portable and easier to
read.
- Added autotools stuff.
- Changes to logging system.
- Added screenshot function.
- Translated most french to english.
- Added savestate support.
- Added firmware reading support(needs work).
- Added Backup Memory support with autodetection.
- Fixed some endianess issues.
- Fixed things so Visual C++ can compile code.
- Added bsd support.
- Reworked ROM loading so you can load a different rom without any problems.
- Finished NDS_Reset. Now the emulation can be reset even while running.
- Fix clear depth (ex. Castlevania now doesnt flip) [lugi__]
- Make GE matrix mult and load commands clear out unused rows and cols to identity correctly [zeromus]
- Setup to track polycount better, but still worthless, not accounting for clipping and culling [zeromus]
- Fix errors in matrix operations regarding projection mode and pos-vector mode [zeromus]
- Fix error in command unpacking which caused some display lists to totally blow up [zeromus]
- Convert alpha and material values from [0,31], [0,7] etc ranges to opengl [0,maxint] ranges in a more precise way [zeromus]
- Add opengl state caching. This is of dubious performance assistance, but it is easy to take out so I am leaving it for now. [zeromus]
- Add MMU->GPU signal for when vram mappings change, which allows it to assume textures are unchanged unless vram has changed [zeromus]
- Move lighting model to software instead of using opengl for more precision [zeromus]
- Fix a bug in texture transformation mode 1 [zeromus]
Mac OS X port:
- Fixed: Filenames and paths with unicode characters now work. [Jeff]
- Fixed: Load state from file button works again. [Jeff]
- Save State panel now pauses emulation while the file selection box is open. [Jeff]
- Fixed: Frozen video output (and/or messed 3d emulation) after loading a state. [Jeff]
- Added option to load the most recent file upon launching the program. [Jeff]
- Added French translation (thanks to Pierre Rudloff). [Jeff]
- Added basic key mapping configuration to application preferences (thanks to Julio GorgŽ). [Jeff]
- Added keyboard shortcuts for Execute, Pause and Reset command (thanks to Julio GorgŽ). [Jeff]
- Default key mappings are no longer case sensitive. [Jeff]
- Added ability to limit speed. [Jeff]
- Fixed: Video output should work on software-only 3D renderers. [Jeff]
Windows port:
- Removed the bug report link with a define, to avoid reports from betas/external builds [shash]
- Added the version on window bar to recognize versions from screenshots [shash]
- Changed graphics render core to DirectDraw (work faster) [CrazyMax]
- Fix a race condition in NDS_3D_Reset and NDS_glInit [zeromus]
- Tweak optimization flags and change entire source code to use fastcall [zeromus]
- Add an arm9 cpu load average calculator similar to no$ [zeromus]
- Fix the buggy auto frameskip logic which made the emu slow to a crawl. Now it runs fast! [zeromus]
- Fix resizing, rotate & aspect ration of main window. Add save window position and parameters [CrazyMax]
- Rewrite all debug tools (autoupdate works now) [CrazyMax]
- Add AVI output [zeromus]
- Remove multithreading from user interface after finding several synchronization issues [zeromus]
- Rewrite input core & replace config input dialog [CrazyMax]
0.7.3 -> 0.8
Cocoa:
- Save State As function now works. [Jeff B]
- Recent Items menu now works. [Jeff B]
- Opening NDS files from Finder now works. [Jeff B]
- Added screenshot feature. [Jeff B]
- Added preferences. [Jeff B]
- Many more strings are translatable now. [Jeff B]
- Default screen color is black (better represents being "off" and easier on eyes at night). [Jeff B]
- Added sound. [Jeff B]
- Now is a universal binary. [Jeff B]
- Leopard resolution icon added. [Jeff B]
- Added a Japanese translation. [Jeff B]
- Added an optional status bar (resize handle no longer overlaps screen). [Jeff B]
- New ROM Info and About DeSmuME windows have been added. [Jeff B]
- Fixed several bugs in window resizing. [Jeff B]
- Added FAT image support for homebrew games (thanks to TypeError). [Jeff B]
- Key config can be changed on the command line. Save/load hotkeys changed (so expose doesn't override). [Jeff B]
- Key bindings may work better on non-US keyboards now (needs testing). [Jeff B]
general:
- Encapsulate GDB debug stub to avoid certain problems [shash]
- Fixed CPU LD*/ST* bugs [shash]
- Fixed New SMB mini-games freeze [shash]
- Fixed possible segfault in ROMReader on ia64 and amd64. [evilynux]
- Fixed a crash bug with 2D background corrupting memory [shash]
- Flag check optimization [carlo_bramini]
- Applied some endian fixes in GPU (thanks to Phazz) [Jeff B]
gtk-glade:
- Added DeSmuME version in about dialog. [evilynux]
- Updated website url in about dialog. [evilynux]
- Added Brazilian Portuguese translation by Dreampeppers99. [evilynux]
- Better desktop menu entry following FreeDesktop specifications. [evilynux]
gtk:
- Updated website url in about dialog. [evilynux]
- Better desktop menu entry following FreeDesktop specifications. [evilynux]
windows port:
- Added an "about" box [shash]
- DirectInput control interface with joystick support [CrazyMax]
- Matrix and Light viewer [Acid Burn]
0.7.2 -> 0.7.3
gtk-glade:
- Full localization using intltool/gettext. [evilynux]
general:
- Added a README.TRANSLATION documenting the localization process. [evilynux]
MacOS X:
- Initial version of the Mac interface added. [Jeff B]
0.7.1 -> 0.7.2
spu:
- big endian fixes. [cyberwarriorx]
gpu:
- big endian fixes. [marcus_c]
gtk-glade:
- opengl improvements. [masscat]
general:
- Added support for setting NDS firmware language value. [masscat]
- Function added for setting firmware language. [masscat]
- Mac/msys compilation fixes. [cyberwarriorx]
- Fix compilation when pkg-config macros are not available [evilynux]
0.7.0 -> 0.7.1
general:
- Added GDB debugger stub [masscat]
- Added new/different GBAMP CFlash image reader/writer [masscat]
gpu:
- Major speedup to the 2D core [shash]
gtk-glade:
- Added command line options. [masscat]
- Added FPS limiter [masscat]
cli:
- Added command line options. [masscat]
- Added FPS limiter [masscat]
- Added option to use OpenGl to render window (allows resizing). [masscat]
windows port:
- Added command line options. [masscat]
- Added multiple language support [cyberwarriorx]
- Added Danish language translation [thomas-2007]
0.6.0 -> 0.7.0
general:
- Added support for *.duc files [cyberwarriorx]
gpu:
- Added support for sprite rotation/scaling [shash]
- Added support for the 3D core (openGL and null plugins) [shash]
windows port:
- A bunch of fixes [Dmitry Krutskih]
- Fixed a bug in sound that was causing it to still not work for some
people [cyberwarriorx]
gtk:
- Added 3D emulation
- Added command line options.
- Added option to use OpenGL to render window (allows resizing).
gtk-glade:
- Added 3D emulation
0.5.0 -> 0.6.0
general:
- Added zipped (based on zziplib) and gzipped (based on zlib) rom support.
arm:
- Added relocation interrupt vector.
- Added region access right checks.
- Enabled LDC/STC instructions.
- Fixed powersave (cp15) IRQ wait.
- Fixed MOV instructions
gpu:
- Added special color effects.
- Added windowing feature.
- Fixed transparent direct color backgrounds.
- Fixed disabled sprites showing.
- Fixed 8/32 bit access to gpu registers.
- Fixed missing backgrounds
- Support for master brightness
wifi:
- Added RF chip interface.
- Added BB chip interface.
windows port:
- Fixed address calculation in disassembler.
- Added Force Maintain Ratio option for window stretching
linux port (cli, gtk and gtk-glade):
all:
- Added joystick support.
- Fixed X and Y buttons.
gtk-glade:
- Added joystick configuration.
- Improved I/O registers viewer tool.
- Added save and load states support.
0.3.3 -> 0.5.0
arm:
- Fixed MSR with immediate value opcode.
- Fixed LSR_0 thumb opcode (C flag is correctly set now).
- Fixed LDR*/STR* opcodes.
- Fixed unaligned memory access on THUMB Core.
- Added relocating SWI routines.
bios:
- Added decompression functions.
- Added GetPitchTable function.
- Added GetVolumeTable function.
- Added GetCRC16 function.
- Added experimental SoundBias function.
- Added GetSineTable function.
cart:
- Added CompactFlash/FAT emulation.
- Added Get ROM chip ID Cartridge command.
gpu:
- Added framebuffer emulation.
- Fixed a bug in GPU (xfin could be greater than LG causing a segfault).
- Added support for Display Mode 0(Display Off).
- Added the basic framework for Display Mode 3(Display from Main RAM).
spu:
- Added sound emulation.
- Added sound core system.
- Added WAV write core.
- Added dummy core.
- Added Direct Sound core.
linux port:
- Added GTK+ GUI.
- Added command line interface.
- Added stylus and arm9 keypad support in CLI version.
- Added FPS display.
- Added basic frameskip.
windows port:
- Fixed a bug when displaying a ROM's information.
- Added key configuration.
- Removed the debug key.
- Added new experimental auto frameskip/frame limit code.
- Added sound settings dialog.
- Added a few menu options for accessing the website, forums, and for
submitting bugs.
general:
- Rewrote code in C.
- Fixed warnings.
- Used defines and typedef's to make things more portable and easier to
read.
- Added autotools stuff.
- Changes to logging system.
- Added screenshot function.
- Translated most french to english.
- Added savestate support.
- Added firmware reading support(needs work).
- Added Backup Memory support with autodetection.
- Fixed some endianess issues.
- Fixed things so Visual C++ can compile code.
- Added bsd support.
- Reworked ROM loading so you can load a different rom without any problems.
- Finished NDS_Reset. Now the emulation can be reset even while running.

View File

@ -32,6 +32,7 @@
#include "cflash.h"
#include "ROMReader.h"
#include "gfx3d.h"
#include "utils/decrypt/decrypt.h"
#include "debug.h"
@ -314,6 +315,22 @@ enum
ROM_DSGBA
};
//http://www.aggregate.org/MAGIC/#Population%20Count%20(Ones%20Count)
static u32 ones32(u32 x)
{
/* 32-bit recursive reduction using SWAR...
but first step is mapping 2-bit values
into sum of 2 1-bit values in sneaky way
*/
x -= ((x >> 1) & 0x55555555);
x = (((x >> 2) & 0x33333333) + (x & 0x33333333));
x = (((x >> 4) + x) & 0x0f0f0f0f);
x += (x >> 8);
x += (x >> 16);
return(x & 0x0000003f);
}
int NDS_LoadROM( const char *filename, int bmtype, u32 bmsize,
const char *cflash_disk_image_file)
{
@ -358,19 +375,24 @@ int NDS_LoadROM( const char *filename, int bmtype, u32 bmsize,
size -= DSGBA_LOADER_SIZE;
}
/* check that size is at least the size of the header */
if (size < 352+160) {
//check that size is at least the size of the header
//and also that the size is a power of 2
if (size < 352+160 || ones32(size) != 1) {
reader->DeInit(file);
free(noext);
return -1;
}
mask = size;
mask |= (mask >>1);
mask |= (mask >>2);
mask |= (mask >>4);
mask |= (mask >>8);
mask |= (mask >>16);
//zero 25-dec-08 - this used to yield a mask which was 2x large
//mask = size;
//mask |= (mask >>1);
//mask |= (mask >>2);
//mask |= (mask >>4);
//mask |= (mask >>8);
//mask |= (mask >>16);
//but now, we know it is a power of 2 so the mask is easy to create
mask = size-1;
// Make sure old ROM is freed first(at least this way we won't be eating
// up a ton of ram before the old ROM is freed)
@ -386,6 +408,13 @@ int NDS_LoadROM( const char *filename, int bmtype, u32 bmsize,
i = reader->Read(file, data, size);
reader->DeInit(file);
//decrypt if necessary..
//but this is untested and suspected to fail on big endian, so lets not support this on big endian
#ifndef WORDS_BIGENDIAN
DecryptSecureArea(data,size);
#endif
MMU_unsetRom();
NDS_SetROM(data, mask);
NDS_Reset();
@ -586,18 +615,7 @@ typedef struct
u32 numimpcol;
} bmpimgheader_struct;
#if defined(_MSC_VER) || defined(__INTEL_COMPILER)
#pragma pack(push, 1)
typedef struct
{
u16 id;
u32 size;
u16 reserved1;
u16 reserved2;
u32 imgoffset;
} bmpfileheader_struct;
#pragma pack(pop)
#else
#include "PACKED.h"
typedef struct
{
u16 id __PACKED;
@ -606,7 +624,7 @@ typedef struct
u16 reserved2 __PACKED;
u32 imgoffset __PACKED;
} bmpfileheader_struct;
#endif
#include "PACKED_END.h"
int NDS_WriteBMP(const char *filename)
{

14
desmume/src/PACKED.h Normal file
View File

@ -0,0 +1,14 @@
#ifdef __GNUC__
__attribute__((packed))
#else
#pragma pack(push, 1)
#pragma warning(disable : 4103)
#endif
#ifndef __PACKED
#ifdef __GNUC__
#define __PACKED __attribute__((__packed__))
#else
#define __PACKED
#endif
#endif

5
desmume/src/PACKED_END.h Normal file
View File

@ -0,0 +1,5 @@
#if defined(_MSC_VER) || defined(__INTEL_COMPILER)
#pragma pack(pop)
#else
#endif

View File

@ -1,230 +1,230 @@
/* Copyright 2007 Guillaume Duhamel
This file is part of DeSmuME
DeSmuME is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
DeSmuME is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with DeSmuME; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "ROMReader.h"
#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>
#ifdef HAVE_LIBZZIP
#include <zzip/zzip.h>
#endif
#ifdef WIN32
#define stat(...) _stat(__VA_ARGS__)
#define S_IFMT _S_IFMT
#define S_IFREG _S_IFREG
#endif
ROMReader_struct * ROMReaderInit(char ** filename)
{
#ifdef HAVE_LIBZ
if(!strcasecmp(".gz", *filename + (strlen(*filename) - 3)))
{
(*filename)[strlen(*filename) - 3] = '\0';
return &GZIPROMReader;
}
#endif
#ifdef HAVE_LIBZZIP
if (!strcasecmp(".zip", *filename + (strlen(*filename) - 4)))
{
(*filename)[strlen(*filename) - 4] = '\0';
return &ZIPROMReader;
}
#endif
return &STDROMReader;
}
void * STDROMReaderInit(const char * filename);
void STDROMReaderDeInit(void *);
u32 STDROMReaderSize(void *);
int STDROMReaderSeek(void *, int, int);
int STDROMReaderRead(void *, void *, u32);
ROMReader_struct STDROMReader =
{
ROMREADER_STD,
"Standard ROM Reader",
STDROMReaderInit,
STDROMReaderDeInit,
STDROMReaderSize,
STDROMReaderSeek,
STDROMReaderRead
};
void * STDROMReaderInit(const char * filename)
{
/* Copyright 2007 Guillaume Duhamel
This file is part of DeSmuME
DeSmuME is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
DeSmuME is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with DeSmuME; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "ROMReader.h"
#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>
#ifdef HAVE_LIBZZIP
#include <zzip/zzip.h>
#endif
#ifdef WIN32
#define stat(...) _stat(__VA_ARGS__)
#define S_IFMT _S_IFMT
#define S_IFREG _S_IFREG
#endif
ROMReader_struct * ROMReaderInit(char ** filename)
{
#ifdef HAVE_LIBZ
if(!strcasecmp(".gz", *filename + (strlen(*filename) - 3)))
{
(*filename)[strlen(*filename) - 3] = '\0';
return &GZIPROMReader;
}
#endif
#ifdef HAVE_LIBZZIP
if (!strcasecmp(".zip", *filename + (strlen(*filename) - 4)))
{
(*filename)[strlen(*filename) - 4] = '\0';
return &ZIPROMReader;
}
#endif
return &STDROMReader;
}
void * STDROMReaderInit(const char * filename);
void STDROMReaderDeInit(void *);
u32 STDROMReaderSize(void *);
int STDROMReaderSeek(void *, int, int);
int STDROMReaderRead(void *, void *, u32);
ROMReader_struct STDROMReader =
{
ROMREADER_STD,
"Standard ROM Reader",
STDROMReaderInit,
STDROMReaderDeInit,
STDROMReaderSize,
STDROMReaderSeek,
STDROMReaderRead
};
void * STDROMReaderInit(const char * filename)
{
#ifdef WIN32
struct _stat sb;
#else
struct stat sb;
#endif
if (stat(filename, &sb) == -1)
return 0;
if ((sb.st_mode & S_IFMT) != S_IFREG)
return 0;
return (void *) fopen(filename, "rb");
}
void STDROMReaderDeInit(void * file)
{
if (!file) return ;
fclose((FILE*)file);
}
u32 STDROMReaderSize(void * file)
{
u32 size;
if (!file) return 0 ;
fseek((FILE*)file, 0, SEEK_END);
size = ftell((FILE*)file);
fseek((FILE*)file, 0, SEEK_SET);
return size;
}
int STDROMReaderSeek(void * file, int offset, int whence)
{
if (!file) return 0 ;
return fseek((FILE*)file, offset, whence);
}
int STDROMReaderRead(void * file, void * buffer, u32 size)
{
if (!file) return 0 ;
return fread(buffer, 1, size, (FILE*)file);
}
#ifdef HAVE_LIBZ
void * GZIPROMReaderInit(const char * filename);
void GZIPROMReaderDeInit(void *);
u32 GZIPROMReaderSize(void *);
int GZIPROMReaderSeek(void *, int, int);
int GZIPROMReaderRead(void *, void *, u32);
ROMReader_struct GZIPROMReader =
{
ROMREADER_GZIP,
"Gzip ROM Reader",
GZIPROMReaderInit,
GZIPROMReaderDeInit,
GZIPROMReaderSize,
GZIPROMReaderSeek,
GZIPROMReaderRead
};
void * GZIPROMReaderInit(const char * filename)
{
return (void*)gzopen(filename, "rb");
}
void GZIPROMReaderDeInit(void * file)
{
gzclose(file);
}
u32 GZIPROMReaderSize(void * file)
{
char useless[1024];
u32 size = 0;
/* FIXME this function should first save the current
* position and restore it after size calculation */
gzrewind(file);
while (gzeof (file) == 0)
size += gzread(file, useless, 1024);
gzrewind(file);
return size;
}
int GZIPROMReaderSeek(void * file, int offset, int whence)
{
return gzseek(file, offset, whence);
}
int GZIPROMReaderRead(void * file, void * buffer, u32 size)
{
return gzread(file, buffer, size);
}
#endif
#ifdef HAVE_LIBZZIP
void * ZIPROMReaderInit(const char * filename);
void ZIPROMReaderDeInit(void *);
u32 ZIPROMReaderSize(void *);
int ZIPROMReaderSeek(void *, int, int);
int ZIPROMReaderRead(void *, void *, u32);
ROMReader_struct ZIPROMReader =
{
ROMREADER_ZIP,
"Zip ROM Reader",
ZIPROMReaderInit,
ZIPROMReaderDeInit,
ZIPROMReaderSize,
ZIPROMReaderSeek,
ZIPROMReaderRead
};
void * ZIPROMReaderInit(const char * filename)
{
ZZIP_DIR * dir = zzip_opendir(filename);
ZZIP_DIRENT * dirent = zzip_readdir(dir);
if (dir != NULL)
{
char tmp1[1024];
char tmp2[1024];
strncpy(tmp1, filename, strlen(filename) - 4);
sprintf(tmp2, "%s/%s", tmp1, dirent->d_name);
return zzip_fopen(tmp2, "rb");
}
return NULL;
}
void ZIPROMReaderDeInit(void * file)
{
zzip_close((ZZIP_FILE*)file);
}
u32 ZIPROMReaderSize(void * file)
{
u32 size;
zzip_seek((ZZIP_FILE*)file, 0, SEEK_END);
size = zzip_tell((ZZIP_FILE*)file);
zzip_seek((ZZIP_FILE*)file, 0, SEEK_SET);
return size;
}
int ZIPROMReaderSeek(void * file, int offset, int whence)
{
return zzip_seek((ZZIP_FILE*)file, offset, whence);
}
int ZIPROMReaderRead(void * file, void * buffer, u32 size)
{
return zzip_read((ZZIP_FILE*)file, buffer, size);
}
#endif
#endif
if (stat(filename, &sb) == -1)
return 0;
if ((sb.st_mode & S_IFMT) != S_IFREG)
return 0;
return (void *) fopen(filename, "rb");
}
void STDROMReaderDeInit(void * file)
{
if (!file) return ;
fclose((FILE*)file);
}
u32 STDROMReaderSize(void * file)
{
u32 size;
if (!file) return 0 ;
fseek((FILE*)file, 0, SEEK_END);
size = ftell((FILE*)file);
fseek((FILE*)file, 0, SEEK_SET);
return size;
}
int STDROMReaderSeek(void * file, int offset, int whence)
{
if (!file) return 0 ;
return fseek((FILE*)file, offset, whence);
}
int STDROMReaderRead(void * file, void * buffer, u32 size)
{
if (!file) return 0 ;
return fread(buffer, 1, size, (FILE*)file);
}
#ifdef HAVE_LIBZ
void * GZIPROMReaderInit(const char * filename);
void GZIPROMReaderDeInit(void *);
u32 GZIPROMReaderSize(void *);
int GZIPROMReaderSeek(void *, int, int);
int GZIPROMReaderRead(void *, void *, u32);
ROMReader_struct GZIPROMReader =
{
ROMREADER_GZIP,
"Gzip ROM Reader",
GZIPROMReaderInit,
GZIPROMReaderDeInit,
GZIPROMReaderSize,
GZIPROMReaderSeek,
GZIPROMReaderRead
};
void * GZIPROMReaderInit(const char * filename)
{
return (void*)gzopen(filename, "rb");
}
void GZIPROMReaderDeInit(void * file)
{
gzclose(file);
}
u32 GZIPROMReaderSize(void * file)
{
char useless[1024];
u32 size = 0;
/* FIXME this function should first save the current
* position and restore it after size calculation */
gzrewind(file);
while (gzeof (file) == 0)
size += gzread(file, useless, 1024);
gzrewind(file);
return size;
}
int GZIPROMReaderSeek(void * file, int offset, int whence)
{
return gzseek(file, offset, whence);
}
int GZIPROMReaderRead(void * file, void * buffer, u32 size)
{
return gzread(file, buffer, size);
}
#endif
#ifdef HAVE_LIBZZIP
void * ZIPROMReaderInit(const char * filename);
void ZIPROMReaderDeInit(void *);
u32 ZIPROMReaderSize(void *);
int ZIPROMReaderSeek(void *, int, int);
int ZIPROMReaderRead(void *, void *, u32);
ROMReader_struct ZIPROMReader =
{
ROMREADER_ZIP,
"Zip ROM Reader",
ZIPROMReaderInit,
ZIPROMReaderDeInit,
ZIPROMReaderSize,
ZIPROMReaderSeek,
ZIPROMReaderRead
};
void * ZIPROMReaderInit(const char * filename)
{
ZZIP_DIR * dir = zzip_opendir(filename);
ZZIP_DIRENT * dirent = zzip_readdir(dir);
if (dir != NULL)
{
char tmp1[1024];
char tmp2[1024];
strncpy(tmp1, filename, strlen(filename) - 4);
sprintf(tmp2, "%s/%s", tmp1, dirent->d_name);
return zzip_fopen(tmp2, "rb");
}
return NULL;
}
void ZIPROMReaderDeInit(void * file)
{
zzip_close((ZZIP_FILE*)file);
}
u32 ZIPROMReaderSize(void * file)
{
u32 size;
zzip_seek((ZZIP_FILE*)file, 0, SEEK_END);
size = zzip_tell((ZZIP_FILE*)file);
zzip_seek((ZZIP_FILE*)file, 0, SEEK_SET);
return size;
}
int ZIPROMReaderSeek(void * file, int offset, int whence)
{
return zzip_seek((ZZIP_FILE*)file, offset, whence);
}
int ZIPROMReaderRead(void * file, void * buffer, u32 size)
{
return zzip_read((ZZIP_FILE*)file, buffer, size);
}
#endif

View File

@ -8,6 +8,8 @@
#define __FAT_H__
#include "types.h"
#include "PACKED.h"
#include "PACKED_END.h"
#define ATTRIB_DIR 0x10
#define ATTRIB_LFN 0x0F

View File

@ -34,9 +34,9 @@ typedef struct MatrixStack
void MatrixInit (float *matrix);
#if defined(_MSC_VER) || defined(__INTEL_COMPILER)
#define MATRIXFASTCALL __fastcall
#else
#if defined(_MSC_VER) || defined(__INTEL_COMPILER)
#define MATRIXFASTCALL __fastcall
#else
#define MATRIXFASTCALL
#endif

View File

@ -1,254 +1,242 @@
/* Copyright (C) 2005 Guillaume Duhamel
This file is part of DeSmuME
DeSmuME is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
DeSmuME is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with DeSmuME; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef TYPES_HPP
#define TYPES_HPP
#define DESMUME_NAME "DeSmuME"
#define DESMUME_VERSION_STRING "0.9-interim"
#define DESMUME_VERSION_NUMERIC 90000
#define DESMUME_NAME_AND_VERSION DESMUME_NAME " " DESMUME_VERSION_STRING " " VERSION
#ifdef _WIN32
#define strcasecmp(x,y) _stricmp(x,y)
#else
#define WINAPI
#endif
#if defined(_MSC_VER) || defined(__INTEL_COMPILER)
#define ALIGN(X) __declspec(align(X))
#elif __GNUC__
#define ALIGN(X) __attribute__ ((aligned (X)))
#else
#define ALIGN(X)
#endif
#define CACHE_ALIGN ALIGN(32)
#ifndef FASTCALL
#ifdef __MINGW32__
#define FASTCALL __attribute__((fastcall))
#elif defined (__i386__)
#define FASTCALL __attribute__((regparm(3)))
#elif defined(_MSC_VER) || defined(__INTEL_COMPILER)
#define FASTCALL
#else
#define FASTCALL
#endif
#endif
#ifndef INLINE
#if defined(_MSC_VER) || defined(__INTEL_COMPILER)
#define INLINE _inline
#else
#define INLINE inline
#endif
#endif
#ifndef FORCEINLINE
#if defined(_MSC_VER)
#define FORCEINLINE __forceinline
#else
#define FORCEINLINE INLINE
#endif
#endif
#if defined(__LP64__)
typedef unsigned char u8;
typedef unsigned short u16;
typedef unsigned int u32;
typedef unsigned long u64;
typedef unsigned long pointer;
typedef signed char s8;
typedef signed short s16;
typedef signed int s32;
typedef signed long s64;
#else
typedef unsigned char u8;
typedef unsigned short u16;
typedef unsigned long u32;
#if defined(_MSC_VER) || defined(__INTEL_COMPILER)
typedef unsigned __int64 u64;
#else
typedef unsigned long long u64;
#endif
typedef unsigned long pointer;
typedef signed char s8;
typedef signed short s16;
typedef signed long s32;
#if defined(_MSC_VER) || defined(__INTEL_COMPILER)
typedef __int64 s64;
#else
typedef signed long long s64;
#endif
#endif
typedef u8 uint8;
typedef u16 uint16;
#ifndef OBJ_C
typedef u32 uint32;
#else
#define uint32 u32 //uint32 is defined in Leopard somewhere, avoid conflicts
#endif
/*---------- GPU3D fixed-points types -----------*/
typedef s32 f32;
#define inttof32(n) ((n) << 12)
#define f32toint(n) ((n) >> 12)
#define floattof32(n) ((int32)((n) * (1 << 12)))
#define f32tofloat(n) (((float)(n)) / (float)(1<<12))
typedef s16 t16;
#define f32tot16(n) ((t16)(n >> 8))
#define inttot16(n) ((n) << 4)
#define t16toint(n) ((n) >> 4)
#define floattot16(n) ((t16)((n) * (1 << 4)))
#define t16ofloat(n) (((float)(n)) / (float)(1<<4))
typedef s16 v16;
#define inttov16(n) ((n) << 12)
#define f32tov16(n) (n)
#define floattov16(n) ((v16)((n) * (1 << 12)))
#define v16toint(n) ((n) >> 12)
#define v16tofloat(n) (((float)(n)) / (float)(1<<12))
typedef s16 v10;
#define inttov10(n) ((n) << 9)
#define f32tov10(n) ((v10)(n >> 3))
#define v10toint(n) ((n) >> 9)
#define floattov10(n) ((v10)((n) * (1 << 9)))
#define v10tofloat(n) (((float)(n)) / (float)(1<<9))
/*----------------------*/
#ifndef OBJ_C
typedef int BOOL;
#else
//apple also defines BOOL
typedef int desmume_BOOL;
#define BOOL desmume_BOOL
#endif
#ifndef TRUE
#define TRUE 1
#endif
#ifndef FALSE
#define FALSE 0
#endif
#ifdef __GNUC__
#define PACKED __attribute__((packed))
#else
#define PACKED
#endif
#ifdef __BIG_ENDIAN__
#define WORDS_BIGENDIAN
#endif
#ifdef WORDS_BIGENDIAN
# define LOCAL_BE
#else
# define LOCAL_LE
#endif
/* little endian (ds' endianess) to local endianess convert macros */
#ifdef LOCAL_BE /* local arch is big endian */
# define LE_TO_LOCAL_16(x) ((((x)&0xff)<<8)|(((x)>>8)&0xff))
# define LE_TO_LOCAL_32(x) ((((x)&0xff)<<24)|(((x)&0xff00)<<8)|(((x)>>8)&0xff00)|(((x)>>24)&0xff))
# define LE_TO_LOCAL_64(x) ((((x)&0xff)<<56)|(((x)&0xff00)<<40)|(((x)&0xff0000)<<24)|(((x)&0xff000000)<<8)|(((x)>>8)&0xff000000)|(((x)>>24)&0xff00)|(((x)>>40)&0xff00)|(((x)>>56)&0xff))
# define LOCAL_TO_LE_16(x) ((((x)&0xff)<<8)|(((x)>>8)&0xff))
# define LOCAL_TO_LE_32(x) ((((x)&0xff)<<24)|(((x)&0xff00)<<8)|(((x)>>8)&0xff00)|(((x)>>24)&0xff))
# define LOCAL_TO_LE_64(x) ((((x)&0xff)<<56)|(((x)&0xff00)<<40)|(((x)&0xff0000)<<24)|(((x)&0xff000000)<<8)|(((x)>>8)&0xff000000)|(((x)>>24)&0xff00)|(((x)>>40)&0xff00)|(((x)>>56)&0xff))
#else /* local arch is little endian */
# define LE_TO_LOCAL_16(x) (x)
# define LE_TO_LOCAL_32(x) (x)
# define LE_TO_LOCAL_64(x) (x)
# define LOCAL_TO_LE_16(x) (x)
# define LOCAL_TO_LE_32(x) (x)
# define LOCAL_TO_LE_64(x) (x)
#endif
// kilobytes and megabytes macro
#define MB(x) ((x)*1024*1024)
#define KB(x) ((x)*1024)
#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
#define CPU_STR(c) ((c==ARM9)?"ARM9":"ARM7")
typedef enum
{
ARM9 = 0,
ARM7 = 1
} cpu_id_t;
#ifdef __GNUC__
#define __PACKED __attribute__((__packed__))
#else
#define __PACKED
#endif
///endian-flips count bytes. count should be even and nonzero.
inline void FlipByteOrder(u8 *src, u32 count)
{
u8 *start=src;
u8 *end=src+count-1;
if((count&1) || !count) return; /* This shouldn't happen. */
while(count--)
{
u8 tmp;
tmp=*end;
*end=*start;
*start=tmp;
end--;
start++;
}
}
inline u64 double_to_u64(double d) {
union {
u64 a;
double b;
} fuxor;
fuxor.b = d;
return fuxor.a;
}
inline double u64_to_double(u64 u) {
union {
u64 a;
double b;
} fuxor;
fuxor.a = u;
return fuxor.b;
}
/* Copyright (C) 2005 Guillaume Duhamel
This file is part of DeSmuME
DeSmuME is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
DeSmuME is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with DeSmuME; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef TYPES_HPP
#define TYPES_HPP
#define DESMUME_NAME "DeSmuME"
#define DESMUME_VERSION_STRING "0.9-interim"
#define DESMUME_VERSION_NUMERIC 90000
#define DESMUME_NAME_AND_VERSION DESMUME_NAME " " DESMUME_VERSION_STRING " " VERSION
#ifdef _WIN32
#define strcasecmp(x,y) _stricmp(x,y)
#else
#define WINAPI
#endif
#if defined(_MSC_VER) || defined(__INTEL_COMPILER)
#define ALIGN(X) __declspec(align(X))
#elif __GNUC__
#define ALIGN(X) __attribute__ ((aligned (X)))
#else
#define ALIGN(X)
#endif
#define CACHE_ALIGN ALIGN(32)
#ifndef FASTCALL
#ifdef __MINGW32__
#define FASTCALL __attribute__((fastcall))
#elif defined (__i386__)
#define FASTCALL __attribute__((regparm(3)))
#elif defined(_MSC_VER) || defined(__INTEL_COMPILER)
#define FASTCALL
#else
#define FASTCALL
#endif
#endif
#ifndef INLINE
#if defined(_MSC_VER) || defined(__INTEL_COMPILER)
#define INLINE _inline
#else
#define INLINE inline
#endif
#endif
#ifndef FORCEINLINE
#if defined(_MSC_VER)
#define FORCEINLINE __forceinline
#else
#define FORCEINLINE INLINE
#endif
#endif
#if defined(__LP64__)
typedef unsigned char u8;
typedef unsigned short u16;
typedef unsigned int u32;
typedef unsigned long u64;
typedef unsigned long pointer;
typedef signed char s8;
typedef signed short s16;
typedef signed int s32;
typedef signed long s64;
#else
typedef unsigned char u8;
typedef unsigned short u16;
typedef unsigned long u32;
#if defined(_MSC_VER) || defined(__INTEL_COMPILER)
typedef unsigned __int64 u64;
#else
typedef unsigned long long u64;
#endif
typedef unsigned long pointer;
typedef signed char s8;
typedef signed short s16;
typedef signed long s32;
#if defined(_MSC_VER) || defined(__INTEL_COMPILER)
typedef __int64 s64;
#else
typedef signed long long s64;
#endif
#endif
typedef u8 uint8;
typedef u16 uint16;
#ifndef OBJ_C
typedef u32 uint32;
#else
#define uint32 u32 //uint32 is defined in Leopard somewhere, avoid conflicts
#endif
/*---------- GPU3D fixed-points types -----------*/
typedef s32 f32;
#define inttof32(n) ((n) << 12)
#define f32toint(n) ((n) >> 12)
#define floattof32(n) ((int32)((n) * (1 << 12)))
#define f32tofloat(n) (((float)(n)) / (float)(1<<12))
typedef s16 t16;
#define f32tot16(n) ((t16)(n >> 8))
#define inttot16(n) ((n) << 4)
#define t16toint(n) ((n) >> 4)
#define floattot16(n) ((t16)((n) * (1 << 4)))
#define t16ofloat(n) (((float)(n)) / (float)(1<<4))
typedef s16 v16;
#define inttov16(n) ((n) << 12)
#define f32tov16(n) (n)
#define floattov16(n) ((v16)((n) * (1 << 12)))
#define v16toint(n) ((n) >> 12)
#define v16tofloat(n) (((float)(n)) / (float)(1<<12))
typedef s16 v10;
#define inttov10(n) ((n) << 9)
#define f32tov10(n) ((v10)(n >> 3))
#define v10toint(n) ((n) >> 9)
#define floattov10(n) ((v10)((n) * (1 << 9)))
#define v10tofloat(n) (((float)(n)) / (float)(1<<9))
/*----------------------*/
#ifndef OBJ_C
typedef int BOOL;
#else
//apple also defines BOOL
typedef int desmume_BOOL;
#define BOOL desmume_BOOL
#endif
#ifndef TRUE
#define TRUE 1
#endif
#ifndef FALSE
#define FALSE 0
#endif
#ifdef __BIG_ENDIAN__
#define WORDS_BIGENDIAN
#endif
#ifdef WORDS_BIGENDIAN
# define LOCAL_BE
#else
# define LOCAL_LE
#endif
/* little endian (ds' endianess) to local endianess convert macros */
#ifdef LOCAL_BE /* local arch is big endian */
# define LE_TO_LOCAL_16(x) ((((x)&0xff)<<8)|(((x)>>8)&0xff))
# define LE_TO_LOCAL_32(x) ((((x)&0xff)<<24)|(((x)&0xff00)<<8)|(((x)>>8)&0xff00)|(((x)>>24)&0xff))
# define LE_TO_LOCAL_64(x) ((((x)&0xff)<<56)|(((x)&0xff00)<<40)|(((x)&0xff0000)<<24)|(((x)&0xff000000)<<8)|(((x)>>8)&0xff000000)|(((x)>>24)&0xff00)|(((x)>>40)&0xff00)|(((x)>>56)&0xff))
# define LOCAL_TO_LE_16(x) ((((x)&0xff)<<8)|(((x)>>8)&0xff))
# define LOCAL_TO_LE_32(x) ((((x)&0xff)<<24)|(((x)&0xff00)<<8)|(((x)>>8)&0xff00)|(((x)>>24)&0xff))
# define LOCAL_TO_LE_64(x) ((((x)&0xff)<<56)|(((x)&0xff00)<<40)|(((x)&0xff0000)<<24)|(((x)&0xff000000)<<8)|(((x)>>8)&0xff000000)|(((x)>>24)&0xff00)|(((x)>>40)&0xff00)|(((x)>>56)&0xff))
#else /* local arch is little endian */
# define LE_TO_LOCAL_16(x) (x)
# define LE_TO_LOCAL_32(x) (x)
# define LE_TO_LOCAL_64(x) (x)
# define LOCAL_TO_LE_16(x) (x)
# define LOCAL_TO_LE_32(x) (x)
# define LOCAL_TO_LE_64(x) (x)
#endif
// kilobytes and megabytes macro
#define MB(x) ((x)*1024*1024)
#define KB(x) ((x)*1024)
#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
#define CPU_STR(c) ((c==ARM9)?"ARM9":"ARM7")
typedef enum
{
ARM9 = 0,
ARM7 = 1
} cpu_id_t;
///endian-flips count bytes. count should be even and nonzero.
inline void FlipByteOrder(u8 *src, u32 count)
{
u8 *start=src;
u8 *end=src+count-1;
if((count&1) || !count) return; /* This shouldn't happen. */
while(count--)
{
u8 tmp;
tmp=*end;
*end=*start;
*start=tmp;
end--;
start++;
}
}
inline u64 double_to_u64(double d) {
union {
u64 a;
double b;
} fuxor;
fuxor.b = d;
return fuxor.a;
}
inline double u64_to_double(u64 u) {
union {
u64 a;
double b;
} fuxor;
fuxor.a = u;
return fuxor.b;
}
///stores a 32bit value into the provided byte array in guaranteed little endian form
inline void en32lsb(u8 *buf, u32 morp)
@ -282,6 +270,6 @@ inline u16 de16lsb(u8 *morp)
{
return morp[0]|(morp[1]<<8);
}
#endif
#endif

View File

@ -0,0 +1,147 @@
//taken from ndstool
//http://devkitpro.cvs.sourceforge.net/viewvc/devkitpro/tools/nds/ndstool/source/crc.cpp?revision=1.2
/*
Cyclic Redundancy Code (CRC) functions
by Rafael Vuijk (aka DarkFader)
*/
unsigned short ccitt16tab[] =
{
0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50A5, 0x60C6, 0x70E7,
0x8108, 0x9129, 0xA14A, 0xB16B, 0xC18C, 0xD1AD, 0xE1CE, 0xF1EF,
0x1231, 0x0210, 0x3273, 0x2252, 0x52B5, 0x4294, 0x72F7, 0x62D6,
0x9339, 0x8318, 0xB37B, 0xA35A, 0xD3BD, 0xC39C, 0xF3FF, 0xE3DE,
0x2462, 0x3443, 0x0420, 0x1401, 0x64E6, 0x74C7, 0x44A4, 0x5485,
0xA56A, 0xB54B, 0x8528, 0x9509, 0xE5EE, 0xF5CF, 0xC5AC, 0xD58D,
0x3653, 0x2672, 0x1611, 0x0630, 0x76D7, 0x66F6, 0x5695, 0x46B4,
0xB75B, 0xA77A, 0x9719, 0x8738, 0xF7DF, 0xE7FE, 0xD79D, 0xC7BC,
0x48C4, 0x58E5, 0x6886, 0x78A7, 0x0840, 0x1861, 0x2802, 0x3823,
0xC9CC, 0xD9ED, 0xE98E, 0xF9AF, 0x8948, 0x9969, 0xA90A, 0xB92B,
0x5AF5, 0x4AD4, 0x7AB7, 0x6A96, 0x1A71, 0x0A50, 0x3A33, 0x2A12,
0xDBFD, 0xCBDC, 0xFBBF, 0xEB9E, 0x9B79, 0x8B58, 0xBB3B, 0xAB1A,
0x6CA6, 0x7C87, 0x4CE4, 0x5CC5, 0x2C22, 0x3C03, 0x0C60, 0x1C41,
0xEDAE, 0xFD8F, 0xCDEC, 0xDDCD, 0xAD2A, 0xBD0B, 0x8D68, 0x9D49,
0x7E97, 0x6EB6, 0x5ED5, 0x4EF4, 0x3E13, 0x2E32, 0x1E51, 0x0E70,
0xFF9F, 0xEFBE, 0xDFDD, 0xCFFC, 0xBF1B, 0xAF3A, 0x9F59, 0x8F78,
0x9188, 0x81A9, 0xB1CA, 0xA1EB, 0xD10C, 0xC12D, 0xF14E, 0xE16F,
0x1080, 0x00A1, 0x30C2, 0x20E3, 0x5004, 0x4025, 0x7046, 0x6067,
0x83B9, 0x9398, 0xA3FB, 0xB3DA, 0xC33D, 0xD31C, 0xE37F, 0xF35E,
0x02B1, 0x1290, 0x22F3, 0x32D2, 0x4235, 0x5214, 0x6277, 0x7256,
0xB5EA, 0xA5CB, 0x95A8, 0x8589, 0xF56E, 0xE54F, 0xD52C, 0xC50D,
0x34E2, 0x24C3, 0x14A0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405,
0xA7DB, 0xB7FA, 0x8799, 0x97B8, 0xE75F, 0xF77E, 0xC71D, 0xD73C,
0x26D3, 0x36F2, 0x0691, 0x16B0, 0x6657, 0x7676, 0x4615, 0x5634,
0xD94C, 0xC96D, 0xF90E, 0xE92F, 0x99C8, 0x89E9, 0xB98A, 0xA9AB,
0x5844, 0x4865, 0x7806, 0x6827, 0x18C0, 0x08E1, 0x3882, 0x28A3,
0xCB7D, 0xDB5C, 0xEB3F, 0xFB1E, 0x8BF9, 0x9BD8, 0xABBB, 0xBB9A,
0x4A75, 0x5A54, 0x6A37, 0x7A16, 0x0AF1, 0x1AD0, 0x2AB3, 0x3A92,
0xFD2E, 0xED0F, 0xDD6C, 0xCD4D, 0xBDAA, 0xAD8B, 0x9DE8, 0x8DC9,
0x7C26, 0x6C07, 0x5C64, 0x4C45, 0x3CA2, 0x2C83, 0x1CE0, 0x0CC1,
0xEF1F, 0xFF3E, 0xCF5D, 0xDF7C, 0xAF9B, 0xBFBA, 0x8FD9, 0x9FF8,
0x6E17, 0x7E36, 0x4E55, 0x5E74, 0x2E93, 0x3EB2, 0x0ED1, 0x1EF0
};
unsigned short crc16tab[] =
{
0x0000, 0xC0C1, 0xC181, 0x0140, 0xC301, 0x03C0, 0x0280, 0xC241,
0xC601, 0x06C0, 0x0780, 0xC741, 0x0500, 0xC5C1, 0xC481, 0x0440,
0xCC01, 0x0CC0, 0x0D80, 0xCD41, 0x0F00, 0xCFC1, 0xCE81, 0x0E40,
0x0A00, 0xCAC1, 0xCB81, 0x0B40, 0xC901, 0x09C0, 0x0880, 0xC841,
0xD801, 0x18C0, 0x1980, 0xD941, 0x1B00, 0xDBC1, 0xDA81, 0x1A40,
0x1E00, 0xDEC1, 0xDF81, 0x1F40, 0xDD01, 0x1DC0, 0x1C80, 0xDC41,
0x1400, 0xD4C1, 0xD581, 0x1540, 0xD701, 0x17C0, 0x1680, 0xD641,
0xD201, 0x12C0, 0x1380, 0xD341, 0x1100, 0xD1C1, 0xD081, 0x1040,
0xF001, 0x30C0, 0x3180, 0xF141, 0x3300, 0xF3C1, 0xF281, 0x3240,
0x3600, 0xF6C1, 0xF781, 0x3740, 0xF501, 0x35C0, 0x3480, 0xF441,
0x3C00, 0xFCC1, 0xFD81, 0x3D40, 0xFF01, 0x3FC0, 0x3E80, 0xFE41,
0xFA01, 0x3AC0, 0x3B80, 0xFB41, 0x3900, 0xF9C1, 0xF881, 0x3840,
0x2800, 0xE8C1, 0xE981, 0x2940, 0xEB01, 0x2BC0, 0x2A80, 0xEA41,
0xEE01, 0x2EC0, 0x2F80, 0xEF41, 0x2D00, 0xEDC1, 0xEC81, 0x2C40,
0xE401, 0x24C0, 0x2580, 0xE541, 0x2700, 0xE7C1, 0xE681, 0x2640,
0x2200, 0xE2C1, 0xE381, 0x2340, 0xE101, 0x21C0, 0x2080, 0xE041,
0xA001, 0x60C0, 0x6180, 0xA141, 0x6300, 0xA3C1, 0xA281, 0x6240,
0x6600, 0xA6C1, 0xA781, 0x6740, 0xA501, 0x65C0, 0x6480, 0xA441,
0x6C00, 0xACC1, 0xAD81, 0x6D40, 0xAF01, 0x6FC0, 0x6E80, 0xAE41,
0xAA01, 0x6AC0, 0x6B80, 0xAB41, 0x6900, 0xA9C1, 0xA881, 0x6840,
0x7800, 0xB8C1, 0xB981, 0x7940, 0xBB01, 0x7BC0, 0x7A80, 0xBA41,
0xBE01, 0x7EC0, 0x7F80, 0xBF41, 0x7D00, 0xBDC1, 0xBC81, 0x7C40,
0xB401, 0x74C0, 0x7580, 0xB541, 0x7700, 0xB7C1, 0xB681, 0x7640,
0x7200, 0xB2C1, 0xB381, 0x7340, 0xB101, 0x71C0, 0x7080, 0xB041,
0x5000, 0x90C1, 0x9181, 0x5140, 0x9301, 0x53C0, 0x5280, 0x9241,
0x9601, 0x56C0, 0x5780, 0x9741, 0x5500, 0x95C1, 0x9481, 0x5440,
0x9C01, 0x5CC0, 0x5D80, 0x9D41, 0x5F00, 0x9FC1, 0x9E81, 0x5E40,
0x5A00, 0x9AC1, 0x9B81, 0x5B40, 0x9901, 0x59C0, 0x5880, 0x9841,
0x8801, 0x48C0, 0x4980, 0x8941, 0x4B00, 0x8BC1, 0x8A81, 0x4A40,
0x4E00, 0x8EC1, 0x8F81, 0x4F40, 0x8D01, 0x4DC0, 0x4C80, 0x8C41,
0x4400, 0x84C1, 0x8581, 0x4540, 0x8701, 0x47C0, 0x4680, 0x8641,
0x8201, 0x42C0, 0x4380, 0x8341, 0x4100, 0x81C1, 0x8081, 0x4040
};
unsigned long crc32tab[] =
{
0x00000000L, 0x77073096L, 0xEE0E612CL, 0x990951BAL,
0x076DC419L, 0x706AF48FL, 0xE963A535L, 0x9E6495A3L,
0x0EDB8832L, 0x79DCB8A4L, 0xE0D5E91EL, 0x97D2D988L,
0x09B64C2BL, 0x7EB17CBDL, 0xE7B82D07L, 0x90BF1D91L,
0x1DB71064L, 0x6AB020F2L, 0xF3B97148L, 0x84BE41DEL,
0x1ADAD47DL, 0x6DDDE4EBL, 0xF4D4B551L, 0x83D385C7L,
0x136C9856L, 0x646BA8C0L, 0xFD62F97AL, 0x8A65C9ECL,
0x14015C4FL, 0x63066CD9L, 0xFA0F3D63L, 0x8D080DF5L,
0x3B6E20C8L, 0x4C69105EL, 0xD56041E4L, 0xA2677172L,
0x3C03E4D1L, 0x4B04D447L, 0xD20D85FDL, 0xA50AB56BL,
0x35B5A8FAL, 0x42B2986CL, 0xDBBBC9D6L, 0xACBCF940L,
0x32D86CE3L, 0x45DF5C75L, 0xDCD60DCFL, 0xABD13D59L,
0x26D930ACL, 0x51DE003AL, 0xC8D75180L, 0xBFD06116L,
0x21B4F4B5L, 0x56B3C423L, 0xCFBA9599L, 0xB8BDA50FL,
0x2802B89EL, 0x5F058808L, 0xC60CD9B2L, 0xB10BE924L,
0x2F6F7C87L, 0x58684C11L, 0xC1611DABL, 0xB6662D3DL,
0x76DC4190L, 0x01DB7106L, 0x98D220BCL, 0xEFD5102AL,
0x71B18589L, 0x06B6B51FL, 0x9FBFE4A5L, 0xE8B8D433L,
0x7807C9A2L, 0x0F00F934L, 0x9609A88EL, 0xE10E9818L,
0x7F6A0DBBL, 0x086D3D2DL, 0x91646C97L, 0xE6635C01L,
0x6B6B51F4L, 0x1C6C6162L, 0x856530D8L, 0xF262004EL,
0x6C0695EDL, 0x1B01A57BL, 0x8208F4C1L, 0xF50FC457L,
0x65B0D9C6L, 0x12B7E950L, 0x8BBEB8EAL, 0xFCB9887CL,
0x62DD1DDFL, 0x15DA2D49L, 0x8CD37CF3L, 0xFBD44C65L,
0x4DB26158L, 0x3AB551CEL, 0xA3BC0074L, 0xD4BB30E2L,
0x4ADFA541L, 0x3DD895D7L, 0xA4D1C46DL, 0xD3D6F4FBL,
0x4369E96AL, 0x346ED9FCL, 0xAD678846L, 0xDA60B8D0L,
0x44042D73L, 0x33031DE5L, 0xAA0A4C5FL, 0xDD0D7CC9L,
0x5005713CL, 0x270241AAL, 0xBE0B1010L, 0xC90C2086L,
0x5768B525L, 0x206F85B3L, 0xB966D409L, 0xCE61E49FL,
0x5EDEF90EL, 0x29D9C998L, 0xB0D09822L, 0xC7D7A8B4L,
0x59B33D17L, 0x2EB40D81L, 0xB7BD5C3BL, 0xC0BA6CADL,
0xEDB88320L, 0x9ABFB3B6L, 0x03B6E20CL, 0x74B1D29AL,
0xEAD54739L, 0x9DD277AFL, 0x04DB2615L, 0x73DC1683L,
0xE3630B12L, 0x94643B84L, 0x0D6D6A3EL, 0x7A6A5AA8L,
0xE40ECF0BL, 0x9309FF9DL, 0x0A00AE27L, 0x7D079EB1L,
0xF00F9344L, 0x8708A3D2L, 0x1E01F268L, 0x6906C2FEL,
0xF762575DL, 0x806567CBL, 0x196C3671L, 0x6E6B06E7L,
0xFED41B76L, 0x89D32BE0L, 0x10DA7A5AL, 0x67DD4ACCL,
0xF9B9DF6FL, 0x8EBEEFF9L, 0x17B7BE43L, 0x60B08ED5L,
0xD6D6A3E8L, 0xA1D1937EL, 0x38D8C2C4L, 0x4FDFF252L,
0xD1BB67F1L, 0xA6BC5767L, 0x3FB506DDL, 0x48B2364BL,
0xD80D2BDAL, 0xAF0A1B4CL, 0x36034AF6L, 0x41047A60L,
0xDF60EFC3L, 0xA867DF55L, 0x316E8EEFL, 0x4669BE79L,
0xCB61B38CL, 0xBC66831AL, 0x256FD2A0L, 0x5268E236L,
0xCC0C7795L, 0xBB0B4703L, 0x220216B9L, 0x5505262FL,
0xC5BA3BBEL, 0xB2BD0B28L, 0x2BB45A92L, 0x5CB36A04L,
0xC2D7FFA7L, 0xB5D0CF31L, 0x2CD99E8BL, 0x5BDEAE1DL,
0x9B64C2B0L, 0xEC63F226L, 0x756AA39CL, 0x026D930AL,
0x9C0906A9L, 0xEB0E363FL, 0x72076785L, 0x05005713L,
0x95BF4A82L, 0xE2B87A14L, 0x7BB12BAEL, 0x0CB61B38L,
0x92D28E9BL, 0xE5D5BE0DL, 0x7CDCEFB7L, 0x0BDBDF21L,
0x86D3D2D4L, 0xF1D4E242L, 0x68DDB3F8L, 0x1FDA836EL,
0x81BE16CDL, 0xF6B9265BL, 0x6FB077E1L, 0x18B74777L,
0x88085AE6L, 0xFF0F6A70L, 0x66063BCAL, 0x11010B5CL,
0x8F659EFFL, 0xF862AE69L, 0x616BFFD3L, 0x166CCF45L,
0xA00AE278L, 0xD70DD2EEL, 0x4E048354L, 0x3903B3C2L,
0xA7672661L, 0xD06016F7L, 0x4969474DL, 0x3E6E77DBL,
0xAED16A4AL, 0xD9D65ADCL, 0x40DF0B66L, 0x37D83BF0L,
0xA9BCAE53L, 0xDEBB9EC5L, 0x47B2CF7FL, 0x30B5FFE9L,
0xBDBDF21CL, 0xCABAC28AL, 0x53B39330L, 0x24B4A3A6L,
0xBAD03605L, 0xCDD70693L, 0x54DE5729L, 0x23D967BFL,
0xB3667A2EL, 0xC4614AB8L, 0x5D681B02L, 0x2A6F2B94L,
0xB40BBE37L, 0xC30C8EA1L, 0x5A05DF1BL, 0x2D02EF8DL
};

View File

@ -0,0 +1,178 @@
//taken from ndstool
//http://devkitpro.cvs.sourceforge.net/viewvc/devkitpro/tools/nds/ndstool/include/crc.h?revision=1.3
/*
Cyclic Redundancy Code (CRC) functions
by Rafael Vuijk (aka DarkFader)
*/
#ifndef __CRC_H
#define __CRC_H
//#include "little.h" // FixCrc is not yet big endian compatible
/*
* Data
*/
extern unsigned short ccitt16tab[];
extern unsigned short crc16tab[];
extern unsigned long crc32tab[];
/*
* Defines
*/
#define CRC_TEMPLATE template <typename CrcType, CrcType *crcTable>
/*
* CalcCcitt
* Does not perform final inversion.
*/
#define CalcCcitt_ CalcCcitt<CrcType, crcTable>
#define CalcCcitt16 CalcCcitt<typeof(*ccitt16tab), ccitt16tab>
CRC_TEMPLATE inline CrcType CalcCcitt(unsigned char *data, unsigned int length, CrcType crc = (CrcType)0)
{
for (unsigned int i=0; i<length; i++)
{
crc = (crc << 8) ^ crcTable[(crc >> 8) ^ data[i]];
}
return crc;
}
/*
* CalcCrc
* Does not perform final inversion.
*/
#define CalcCrc_ CalcCrc<CrcType, crcTable>
#define CalcCrc16 CalcCrc<typeof(*crc16tab), crc16tab>
#define CalcCrc32 CalcCrc<typeof(*crc32tab), crc32tab>
CRC_TEMPLATE inline CrcType CalcCrc(unsigned char *data, unsigned int length, CrcType crc = (CrcType)~0)
{
for (unsigned int i=0; i<length; i++)
{
crc = (crc >> 8) ^ crcTable[(crc ^ data[i]) & 0xFF];
}
return crc;
}
/*
* FCalcCrc
* Does not perform final inversion.
*/
#define FCalcCrc_ FCalcCrc<CrcType, crcTable>
#define FCalcCrc16 FCalcCrc<typeof(*crc16tab), crc16tab>
#define FCalcCrc32 FCalcCrc<typeof(*crc32tab), crc32tab>
CRC_TEMPLATE inline CrcType FCalcCrc(FILE *f, unsigned int offset, unsigned int length, CrcType crc = (CrcType)~0)
{
fseek(f, offset, SEEK_SET);
for (unsigned int i=0; i<length; i++)
{
crc = (crc >> 8) ^ crcTable[(crc ^ fgetc(f)) & 0xFF];
}
return crc;
}
/*
* RevCrc
* Reverse table lookup.
*/
#define RevCrc_ RevCrc<CrcType, crcTable>
CRC_TEMPLATE inline unsigned char RevCrc(unsigned char x, CrcType *value = 0)
{
for (int y=0; y<256; y++)
{
if ((crcTable[y] >> (8*sizeof(CrcType)-8)) == x)
{
if (value) *value = crcTable[y];
return y;
}
}
return 0;
}
/*
* FixCrc
*/
#define FixCrc_ FixCrc<CrcType, crcTable>
#define FixCrc16 FixCrc<typeof(*crc16tab), crc16tab>
#define FixCrc32 FixCrc<typeof(*crc32tab), crc32tab>
CRC_TEMPLATE void FixCrc
(
unsigned char *data, // data to be patched
unsigned int patch_offset, unsigned char *patch_data, unsigned int patch_length, // patch data
unsigned int fix_offset = 0, // position to write the fix. by default, it is immediately after the patched data
CrcType initial_crc = (CrcType)~0 // useful when manually calculating leading data
)
{
if (!fix_offset) fix_offset = patch_offset + patch_length;
// calculate CRC after leading data
initial_crc = CalcCrc_(data, patch_offset, initial_crc);
// calculate CRC before fix
unsigned char buf[2*sizeof(CrcType)];
CrcType crc_before_fix = CalcCrc_(data + patch_offset, fix_offset - patch_offset);
*(CrcType *)(buf + 0) = crc_before_fix;
// patch
memcpy(data + patch_offset, patch_data, patch_length);
// calculate CRC after unfixed
CrcType crc_after_unfix = CalcCrc_(data + patch_offset, fix_offset - patch_offset + sizeof(CrcType));
*(CrcType *)(buf + sizeof(CrcType)) = crc_after_unfix;
// fix it
for (int i=sizeof(CrcType); i>=1; i--)
{
CrcType value;
unsigned char index = RevCrc_(buf[i + sizeof(CrcType) - 1], &value);
*(CrcType *)(buf + i) ^= value;
buf[i - 1] ^= index;
}
memcpy(data + fix_offset, buf, sizeof(CrcType));
}
/*
* FFixCrc
*/
#define FFixCrc_ FFixCrc<CrcType, crcTable>
#define FFixCrc16 FFixCrc<typeof(*crc16tab), crc16tab>
#define FFixCrc32 FFixCrc<typeof(*crc32tab), crc32tab>
CRC_TEMPLATE void FFixCrc
(
FILE *f, // file to be patched
unsigned int patch_offset, unsigned char *patch_data, unsigned int patch_length, // patch data
unsigned int fix_offset = 0, // position to write the fix. by default, it is immediately after the patched data
CrcType initial_crc = (CrcType)~0 // useful when manually calculating leading data
)
{
if (!fix_offset) fix_offset = patch_offset + patch_length;
// calculate CRC after leading data
initial_crc = FCalcCrc_(f, 0, patch_offset, initial_crc);
// calculate CRC before fix
unsigned char buf[2*sizeof(CrcType)];
CrcType crc_before_fix = FCalcCrc_(f, patch_offset, fix_offset - patch_offset);
*(CrcType *)(buf + 0) = crc_before_fix;
// patch
fseek(f, patch_offset, SEEK_SET);
fwrite(patch_data, 1, patch_length, f);
// calculate CRC after unfixed
CrcType crc_after_unfix = FCalcCrc_(f, patch_offset, fix_offset - patch_offset + sizeof(CrcType));
*(CrcType *)(buf + sizeof(CrcType)) = crc_after_unfix;
// fix it
for (int i=sizeof(CrcType); i>=1; i--)
{
CrcType value=0;
unsigned char index = RevCrc_(buf[i + sizeof(CrcType) - 1], &value);
*(CrcType *)(buf + i) ^= value;
buf[i - 1] ^= index;
}
fseek(f, fix_offset, SEEK_SET);
fwrite(buf, sizeof(CrcType), 1, f);
}
#endif // __CRC_H

View File

@ -0,0 +1,479 @@
//taken from ndstool
//http://devkitpro.cvs.sourceforge.net/viewvc/devkitpro/tools/nds/ndstool/source/encryption.cpp?revision=1.2
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "types.h"
#include "crc.h"
#include "header.h"
const unsigned char encr_data[] =
{
0x99,0xD5,0x20,0x5F,0x57,0x44,0xF5,0xB9,0x6E,0x19,0xA4,0xD9,0x9E,0x6A,0x5A,0x94,
0xD8,0xAE,0xF1,0xEB,0x41,0x75,0xE2,0x3A,0x93,0x82,0xD0,0x32,0x33,0xEE,0x31,0xD5,
0xCC,0x57,0x61,0x9A,0x37,0x06,0xA2,0x1B,0x79,0x39,0x72,0xF5,0x55,0xAE,0xF6,0xBE,
0x5F,0x1B,0x69,0xFB,0xE5,0x9D,0xF1,0xE9,0xCE,0x2C,0xD9,0xA1,0x5E,0x32,0x05,0xE6,
0xFE,0xD3,0xFE,0xCF,0xD4,0x62,0x04,0x0D,0x8B,0xF5,0xEC,0xB7,0x2B,0x60,0x79,0xBB,
0x12,0x95,0x31,0x0D,0x6E,0x3F,0xDA,0x2B,0x88,0x84,0xF0,0xF1,0x3D,0x12,0x7E,0x25,
0x45,0x22,0xF1,0xBB,0x24,0x06,0x1A,0x06,0x11,0xAD,0xDF,0x28,0x8B,0x64,0x81,0x34,
0x2B,0xEB,0x33,0x29,0x99,0xAA,0xF2,0xBD,0x9C,0x14,0x95,0x9D,0x9F,0xF7,0xF5,0x8C,
0x72,0x97,0xA1,0x29,0x9D,0xD1,0x5F,0xCF,0x66,0x4D,0x07,0x1A,0xDE,0xD3,0x4A,0x4B,
0x85,0xC9,0xA7,0xA3,0x17,0x95,0x05,0x3A,0x3D,0x49,0x0A,0xBF,0x0A,0x89,0x8B,0xA2,
0x4A,0x82,0x49,0xDD,0x27,0x90,0xF1,0x0B,0xE9,0xEB,0x1C,0x6A,0x83,0x76,0x45,0x05,
0xBA,0x81,0x70,0x61,0x17,0x3F,0x4B,0xDE,0xAE,0xCF,0xAB,0x39,0x57,0xF2,0x3A,0x56,
0x48,0x11,0xAD,0x8A,0x40,0xE1,0x45,0x3F,0xFA,0x9B,0x02,0x54,0xCA,0xA6,0x93,0xFB,
0xEF,0x4D,0xFE,0x6F,0xA3,0xD8,0x87,0x9C,0x08,0xBA,0xD5,0x48,0x6A,0x8D,0x2D,0xFD,
0x6E,0x15,0xF8,0x74,0xBD,0xBE,0x52,0x8B,0x18,0x22,0x8A,0x9E,0xFB,0x74,0x37,0x07,
0x1B,0x36,0x6C,0x4A,0x19,0xBA,0x42,0x62,0xB9,0x79,0x91,0x10,0x7B,0x67,0x65,0x96,
0xFE,0x02,0x23,0xE8,0xEE,0x99,0x8C,0x77,0x3E,0x5C,0x86,0x64,0x4D,0x6D,0x78,0x86,
0xA5,0x4F,0x65,0xE2,0x1E,0xB2,0xDF,0x5A,0x0A,0xD0,0x7E,0x08,0x14,0xB0,0x71,0xAC,
0xBD,0xDB,0x83,0x1C,0xB9,0xD7,0xA1,0x62,0xCD,0xC6,0x63,0x7C,0x52,0x69,0xC3,0xE6,
0xBF,0x75,0xCE,0x12,0x44,0x5D,0x21,0x04,0xFA,0xFB,0xD3,0x3C,0x38,0x11,0x63,0xD4,
0x95,0x85,0x41,0x49,0x46,0x09,0xF2,0x08,0x43,0x11,0xDC,0x1F,0x76,0xC0,0x15,0x6D,
0x1F,0x3C,0x63,0x70,0xEA,0x87,0x80,0x6C,0xC3,0xBD,0x63,0x8B,0xC2,0x37,0x21,0x37,
0xDC,0xEE,0x09,0x23,0x2E,0x37,0x6A,0x4D,0x73,0x90,0xF7,0x50,0x30,0xAC,0x1C,0x92,
0x04,0x10,0x23,0x91,0x4F,0xD2,0x07,0xAA,0x68,0x3E,0x4F,0x9A,0xC9,0x64,0x60,0x6A,
0xC8,0x14,0x21,0xF3,0xD6,0x22,0x41,0x12,0x44,0x24,0xCF,0xE6,0x8A,0x56,0xDD,0x0D,
0x53,0x4D,0xE1,0x85,0x1E,0x8C,0x52,0x5A,0x9C,0x19,0x84,0xC2,0x03,0x57,0xF1,0x6F,
0xE3,0x00,0xBE,0x58,0xF6,0x4C,0xED,0xD5,0x21,0x64,0x9C,0x1F,0xBE,0x55,0x03,0x3C,
0x4A,0xDC,0xFF,0xAA,0xC9,0xDA,0xE0,0x5D,0x5E,0xBF,0xE6,0xDE,0xF5,0xD8,0xB1,0xF8,
0xFF,0x36,0xB3,0xB9,0x62,0x67,0x95,0xDB,0x31,0x5F,0x37,0xED,0x4C,0x70,0x67,0x99,
0x90,0xB5,0x18,0x31,0x6C,0x3D,0x99,0x99,0xE4,0x42,0xDA,0xD3,0x25,0x42,0x13,0xA0,
0xAE,0xD7,0x70,0x6C,0xB1,0x55,0xCF,0xC7,0xD7,0x46,0xD5,0x43,0x61,0x17,0x3D,0x44,
0x28,0xE9,0x33,0x85,0xD5,0xD0,0xA2,0x93,0xAA,0x25,0x12,0x1F,0xFB,0xC5,0x0B,0x46,
0xF5,0x97,0x76,0x56,0x45,0xA6,0xBE,0x87,0xB1,0x94,0x6B,0xE8,0xB1,0xFE,0x33,0x99,
0xAE,0x1F,0x3E,0x6C,0x39,0x71,0x1D,0x09,0x00,0x90,0x37,0xE4,0x10,0x3E,0x75,0x74,
0xFF,0x8C,0x83,0x3B,0xB0,0xF1,0xB0,0xF9,0x01,0x05,0x47,0x42,0x95,0xF1,0xD6,0xAC,
0x7E,0x38,0xE6,0x9E,0x95,0x74,0x26,0x3F,0xB4,0x68,0x50,0x18,0xD0,0x43,0x30,0xB4,
0x4C,0x4B,0xE3,0x68,0xBF,0xE5,0x4D,0xB6,0x95,0x8B,0x0A,0xA0,0x74,0x25,0x32,0x77,
0xCF,0xA1,0xF7,0x2C,0xD8,0x71,0x13,0x5A,0xAB,0xEA,0xC9,0x51,0xE8,0x0D,0xEE,0xEF,
0xE9,0x93,0x7E,0x19,0xA7,0x1E,0x43,0x38,0x81,0x16,0x2C,0xA1,0x48,0xE3,0x73,0xCC,
0x29,0x21,0x6C,0xD3,0x5D,0xCE,0xA0,0xD9,0x61,0x71,0x43,0xA0,0x15,0x13,0xB5,0x64,
0x92,0xCF,0x2A,0x19,0xDC,0xAD,0xB7,0xA5,0x9F,0x86,0x65,0xF8,0x1A,0x9F,0xE7,0xFB,
0xF7,0xFD,0xB8,0x13,0x6C,0x27,0xDB,0x6F,0xDF,0x35,0x1C,0xF7,0x8D,0x2C,0x5B,0x9B,
0x12,0xAB,0x38,0x64,0x06,0xCC,0xDE,0x31,0xE8,0x4E,0x75,0x11,0x64,0xE3,0xFA,0xEA,
0xEB,0x34,0x54,0xC2,0xAD,0x3F,0x34,0xEB,0x93,0x2C,0x7D,0x26,0x36,0x9D,0x56,0xF3,
0x5A,0xE1,0xF6,0xB3,0x98,0x63,0x4A,0x9E,0x32,0x83,0xE4,0x9A,0x84,0x60,0x7D,0x90,
0x2E,0x13,0x0E,0xEE,0x93,0x4B,0x36,0xA2,0x85,0xEC,0x16,0x38,0xE8,0x88,0x06,0x02,
0xBF,0xF0,0xA0,0x3A,0xED,0xD7,0x6A,0x9A,0x73,0xE1,0x57,0xCF,0xF8,0x44,0xB8,0xDC,
0x2E,0x23,0x59,0xD1,0xDF,0x95,0x52,0x71,0x99,0x61,0xA0,0x4B,0xD5,0x7F,0x6E,0x78,
0xBA,0xA9,0xC5,0x30,0xD3,0x40,0x86,0x32,0x9D,0x32,0x0C,0x9C,0x37,0xB7,0x02,0x2F,
0xBA,0x54,0x98,0xA9,0xC4,0x13,0x04,0xC9,0x8D,0xBE,0xC8,0xE7,0x5D,0x97,0x50,0x2E,
0x93,0xD6,0x22,0x59,0x0C,0x27,0xBC,0x22,0x92,0xE0,0xA7,0x20,0x0F,0x93,0x6F,0x7F,
0x4C,0x9F,0xD3,0xB5,0xA6,0x2A,0x0B,0x74,0x67,0x49,0x7D,0x10,0x26,0xCB,0xD1,0xC5,
0x86,0x71,0xE7,0x8C,0xA0,0x9C,0xE9,0x5B,0xB2,0x1A,0xF6,0x01,0xEE,0x8C,0x9E,0x5E,
0x83,0xF2,0x1A,0xDB,0xE6,0xE5,0xEA,0x84,0x59,0x76,0xD2,0x7C,0xF6,0x8D,0xA5,0x49,
0x36,0x48,0xC2,0x16,0x52,0xBB,0x83,0xA3,0x74,0xB9,0x07,0x0C,0x3B,0xFF,0x61,0x28,
0xE1,0x61,0xE9,0xE4,0xEF,0x6E,0x15,0xAA,0x4E,0xBA,0xE8,0x5D,0x05,0x96,0xBB,0x32,
0x56,0xB0,0xFB,0x72,0x52,0x0F,0x0E,0xC8,0x42,0x25,0x65,0x76,0x89,0xAF,0xF2,0xDE,
0x10,0x27,0xF0,0x01,0x4B,0x74,0xA7,0x97,0x07,0xD5,0x26,0x54,0x54,0x09,0x1F,0x82,
0x0A,0x86,0x7D,0x30,0x39,0x0E,0xB3,0x26,0x9B,0x0B,0x57,0xBB,0x36,0x06,0x31,0xAF,
0xFD,0x79,0xFC,0xD9,0x30,0x10,0x2B,0x0C,0xB3,0xE1,0x9B,0xD7,0x7B,0xDC,0x5F,0xEF,
0xD2,0xF8,0x13,0x45,0x4D,0x47,0x75,0xBD,0x46,0x96,0x3C,0x7E,0x75,0xF3,0x3E,0xB5,
0x67,0xC5,0x9A,0x3B,0xB0,0x5B,0x29,0x6B,0xDE,0x80,0x5B,0xC8,0x15,0x05,0xB1,0x31,
0xB6,0xCE,0x49,0xDD,0xAD,0x84,0xB5,0xAE,0x60,0xDC,0x67,0x31,0x34,0x30,0xFE,0x4E,
0xBD,0x80,0x2F,0xA6,0xBF,0x63,0x39,0x21,0x86,0xD9,0x35,0x7F,0x16,0x68,0x22,0x05,
0x54,0xE9,0x90,0x26,0x8C,0x07,0x6C,0x51,0xA4,0x31,0x55,0xD7,0x09,0x07,0xA8,0x3E,
0x2E,0x53,0x66,0xC1,0xF8,0xF2,0x7B,0xC4,0xF2,0x58,0xCF,0xF1,0x87,0xC5,0xA2,0xE7,
0x27,0x8F,0x30,0x87,0x58,0xA0,0x64,0x62,0x23,0x18,0xB9,0x88,0x7C,0xFA,0xCE,0xC4,
0x98,0xAE,0xAD,0x17,0xCC,0x4A,0x5B,0xF3,0xE9,0x48,0xD5,0x56,0xD3,0x0D,0xF2,0xC8,
0x92,0x73,0x8C,0xDB,0xD7,0x2F,0x56,0xAC,0x81,0xF9,0x92,0x69,0x4D,0xC6,0x32,0xF6,
0xE6,0xC0,0x8D,0x21,0xE2,0x76,0x80,0x61,0x11,0xBC,0xDC,0x6C,0x93,0xAF,0x19,0x69,
0x9B,0xD0,0xBF,0xB9,0x31,0x9F,0x02,0x67,0xA3,0x51,0xEE,0x83,0x06,0x22,0x7B,0x0C,
0xAB,0x49,0x42,0x40,0xB8,0xD5,0x01,0x7D,0xCE,0x5E,0xF7,0x55,0x53,0x39,0xC5,0x99,
0x46,0xD8,0x87,0x9F,0xBA,0xF7,0x64,0xB4,0xE3,0x9A,0xFA,0xA1,0x6D,0x90,0x68,0x10,
0x30,0xCA,0x8A,0x54,0xA7,0x9F,0x60,0xC3,0x19,0xF5,0x6B,0x0D,0x7A,0x51,0x98,0xE6,
0x98,0x43,0x51,0xB4,0xD6,0x35,0xE9,0x4F,0xC3,0xDF,0x0F,0x7B,0xD6,0x2F,0x5C,0xBD,
0x3A,0x15,0x61,0x19,0xF1,0x4B,0xCB,0xAA,0xDC,0x6D,0x64,0xC9,0xD3,0xC6,0x1E,0x56,
0xEF,0x38,0x4C,0x50,0x71,0x86,0x75,0xCC,0x0D,0x0D,0x4E,0xE9,0x28,0xF6,0x06,0x5D,
0x70,0x1B,0xAA,0xD3,0x45,0xCF,0xA8,0x39,0xAC,0x95,0xA6,0x2E,0xB4,0xE4,0x22,0xD4,
0x74,0xA8,0x37,0x5F,0x48,0x7A,0x04,0xCC,0xA5,0x4C,0x40,0xD8,0x28,0xB4,0x28,0x08,
0x0D,0x1C,0x72,0x52,0x41,0xF0,0x7D,0x47,0x19,0x3A,0x53,0x4E,0x58,0x84,0x62,0x6B,
0x93,0xB5,0x8A,0x81,0x21,0x4E,0x0D,0xDC,0xB4,0x3F,0xA2,0xC6,0xFC,0xC9,0x2B,0x40,
0xDA,0x38,0x04,0xE9,0x5E,0x5A,0x86,0x6B,0x0C,0x22,0x25,0x85,0x68,0x11,0x8D,0x7C,
0x92,0x1D,0x95,0x55,0x4D,0xAB,0x8E,0xBB,0xDA,0xA6,0xE6,0xB7,0x51,0xB6,0x32,0x5A,
0x05,0x41,0xDD,0x05,0x2A,0x0A,0x56,0x50,0x91,0x17,0x47,0xCC,0xC9,0xE6,0x7E,0xB5,
0x61,0x4A,0xDB,0x73,0x67,0x51,0xC8,0x33,0xF5,0xDA,0x6E,0x74,0x2E,0x54,0xC3,0x37,
0x0D,0x6D,0xAF,0x08,0xE8,0x15,0x8A,0x5F,0xE2,0x59,0x21,0xCD,0xA8,0xDE,0x0C,0x06,
0x5A,0x77,0x6B,0x5F,0xDB,0x18,0x65,0x3E,0xC8,0x50,0xDE,0x78,0xE0,0xB8,0x82,0xB3,
0x5D,0x4E,0x72,0x32,0x07,0x4F,0xC1,0x34,0x23,0xBA,0x96,0xB7,0x67,0x4E,0xA4,0x28,
0x1E,0x34,0x62,0xEB,0x2D,0x6A,0x70,0xE9,0x2F,0x42,0xC4,0x70,0x4E,0x5A,0x31,0x9C,
0xF9,0x5B,0x47,0x28,0xAA,0xDA,0x71,0x6F,0x38,0x1F,0xB3,0x78,0xC4,0x92,0x6B,0x1C,
0x9E,0xF6,0x35,0x9A,0xB7,0x4D,0x0E,0xBF,0xCC,0x18,0x29,0x41,0x03,0x48,0x35,0x5D,
0x55,0xD0,0x2B,0xC6,0x29,0xAF,0x5C,0x60,0x74,0x69,0x8E,0x5E,0x9B,0x7C,0xD4,0xBD,
0x7B,0x44,0x64,0x7D,0x3F,0x92,0x5D,0x69,0xB6,0x1F,0x00,0x4B,0xD4,0x83,0x35,0xCF,
0x7E,0x64,0x4E,0x17,0xAE,0x8D,0xD5,0x2E,0x9A,0x28,0x12,0x4E,0x2E,0x2B,0x49,0x08,
0x5C,0xAE,0xC6,0x46,0x85,0xAE,0x41,0x61,0x1E,0x6F,0x82,0xD2,0x51,0x37,0x16,0x1F,
0x0B,0xF6,0x59,0xA4,0x9A,0xCA,0x5A,0xAF,0x0D,0xD4,0x33,0x8B,0x20,0x63,0xF1,0x84,
0x80,0x5C,0xCB,0xCF,0x08,0xB4,0xB9,0xD3,0x16,0x05,0xBD,0x62,0x83,0x31,0x9B,0x56,
0x51,0x98,0x9F,0xBA,0xB2,0x5B,0xAA,0xB2,0x22,0x6B,0x2C,0xB5,0xD4,0x48,0xFA,0x63,
0x2B,0x5F,0x58,0xFA,0x61,0xFA,0x64,0x09,0xBB,0x38,0xE0,0xB8,0x9D,0x92,0x60,0xA8,
0x0D,0x67,0x6F,0x0E,0x37,0xF5,0x0D,0x01,0x9F,0xC2,0x77,0xD4,0xFE,0xEC,0xF1,0x73,
0x30,0x39,0xE0,0x7D,0xF5,0x61,0x98,0xE4,0x2C,0x28,0x55,0x04,0x56,0x55,0xDB,0x2F,
0x6B,0xEC,0xE5,0x58,0x06,0xB6,0x64,0x80,0x6A,0x2A,0x1A,0x4E,0x5B,0x0F,0xD8,0xC4,
0x0A,0x2E,0x52,0x19,0xD9,0x62,0xF5,0x30,0x48,0xBE,0x8C,0x7B,0x4F,0x38,0x9B,0xA2,
0xC3,0xAF,0xC9,0xD3,0xC7,0xC1,0x62,0x41,0x86,0xB9,0x61,0x21,0x57,0x6F,0x99,0x4F,
0xC1,0xBA,0xCE,0x7B,0xB5,0x3B,0x4D,0x5E,0x8A,0x8B,0x44,0x57,0x5F,0x13,0x5F,0x70,
0x6D,0x5B,0x29,0x47,0xDC,0x38,0xE2,0xEC,0x04,0x55,0x65,0x12,0x2A,0xE8,0x17,0x43,
0xE1,0x8E,0xDD,0x2A,0xB3,0xE2,0x94,0xF7,0x09,0x6E,0x5C,0xE6,0xEB,0x8A,0xF8,0x6D,
0x89,0x49,0x54,0x48,0xF5,0x2F,0xAD,0xBF,0xEA,0x94,0x4B,0xCA,0xFC,0x39,0x87,0x82,
0x5F,0x8A,0x01,0xF2,0x75,0xF2,0xE6,0x71,0xD6,0xD8,0x42,0xDE,0xF1,0x2D,0x1D,0x28,
0xA6,0x88,0x7E,0xA3,0xA0,0x47,0x1D,0x30,0xD9,0xA3,0x71,0xDF,0x49,0x1C,0xCB,0x01,
0xF8,0x36,0xB1,0xF2,0xF0,0x22,0x58,0x5D,0x45,0x6B,0xBD,0xA0,0xBB,0xB2,0x88,0x42,
0xC7,0x8C,0x28,0xCE,0x93,0xE8,0x90,0x63,0x08,0x90,0x7C,0x89,0x3C,0xF5,0x7D,0xB7,
0x04,0x2D,0x4F,0x55,0x51,0x16,0xFD,0x7E,0x79,0xE8,0xBE,0xC1,0xF2,0x12,0xD4,0xF8,
0xB4,0x84,0x05,0x23,0xA0,0xCC,0xD2,0x2B,0xFD,0xE1,0xAB,0xAD,0x0D,0xD1,0x55,0x6C,
0x23,0x41,0x94,0x4D,0x77,0x37,0x4F,0x05,0x28,0x0C,0xBF,0x17,0xB3,0x12,0x67,0x6C,
0x8C,0xC3,0x5A,0xF7,0x41,0x84,0x2A,0x6D,0xD0,0x94,0x12,0x27,0x2C,0xB4,0xED,0x9C,
0x4D,0xEC,0x47,0x82,0x97,0xD5,0x67,0xB9,0x1B,0x9D,0xC0,0x55,0x07,0x7E,0xE5,0x8E,
0xE2,0xA8,0xE7,0x3E,0x12,0xE4,0x0E,0x3A,0x2A,0x45,0x55,0x34,0xA2,0xF9,0x2D,0x5A,
0x1B,0xAB,0x52,0x7C,0x83,0x10,0x5F,0x55,0xD2,0xF1,0x5A,0x43,0x2B,0xC6,0xA7,0xA4,
0x89,0x15,0x95,0xE8,0xB4,0x4B,0x9D,0xF8,0x75,0xE3,0x9F,0x60,0x78,0x5B,0xD6,0xE6,
0x0D,0x44,0xE6,0x21,0x06,0xBD,0x47,0x22,0x53,0xA4,0x00,0xAD,0x8D,0x43,0x13,0x85,
0x39,0xF7,0xAA,0xFC,0x38,0xAF,0x7B,0xED,0xFC,0xE4,0x2B,0x54,0x50,0x98,0x4C,0xFC,
0x85,0x80,0xF7,0xDF,0x3C,0x80,0x22,0xE1,0x94,0xDA,0xDE,0x24,0xC6,0xB0,0x7A,0x39,
0x38,0xDC,0x0F,0xA1,0xA7,0xF4,0xF9,0x6F,0x63,0x18,0x57,0x8B,0x84,0x41,0x2A,0x2E,
0xD4,0x53,0xF2,0xD9,0x00,0x0F,0xD0,0xDD,0x99,0x6E,0x19,0xA6,0x0A,0xD0,0xEC,0x5B,
0x58,0x24,0xAB,0xC0,0xCB,0x06,0x65,0xEC,0x1A,0x13,0x38,0x94,0x0A,0x67,0x03,0x2F,
0x3F,0xF7,0xE3,0x77,0x44,0x77,0x33,0xC6,0x14,0x39,0xD0,0xE3,0xC0,0xA2,0x08,0x79,
0xBB,0x40,0x99,0x57,0x41,0x0B,0x01,0x90,0xCD,0xE1,0xCC,0x48,0x67,0xDB,0xB3,0xAF,
0x88,0x74,0xF3,0x4C,0x82,0x8F,0x72,0xB1,0xB5,0x23,0x29,0xC4,0x12,0x6C,0x19,0xFC,
0x8E,0x46,0xA4,0x9C,0xC4,0x25,0x65,0x87,0xD3,0x6D,0xBE,0x8A,0x93,0x11,0x03,0x38,
0xED,0x83,0x2B,0xF3,0x46,0xA4,0x93,0xEA,0x3B,0x53,0x85,0x1D,0xCE,0xD4,0xF1,0x08,
0x83,0x27,0xED,0xFC,0x9B,0x1A,0x18,0xBC,0xF9,0x8B,0xAE,0xDC,0x24,0xAB,0x50,0x38,
0xE9,0x72,0x4B,0x10,0x22,0x17,0x7B,0x46,0x5D,0xAB,0x59,0x64,0xF3,0x40,0xAE,0xF8,
0xBB,0xE5,0xC8,0xF9,0x26,0x03,0x4E,0x55,0x7D,0xEB,0xEB,0xFE,0xF7,0x39,0xE6,0xE0,
0x0A,0x11,0xBE,0x2E,0x28,0xFF,0x98,0xED,0xC0,0xC9,0x42,0x56,0x42,0xC3,0xFD,0x00,
0xF6,0xAF,0x87,0xA2,0x5B,0x01,0x3F,0x32,0x92,0x47,0x95,0x9A,0x72,0xA5,0x32,0x3D,
0xAE,0x6B,0xD0,0x9B,0x07,0xD2,0x49,0x92,0xE3,0x78,0x4A,0xFA,0xA1,0x06,0x7D,0xF2,
0x41,0xCF,0x77,0x74,0x04,0x14,0xB2,0x0C,0x86,0x84,0x64,0x16,0xD5,0xBB,0x51,0xA1,
0xE5,0x6F,0xF1,0xD1,0xF2,0xE2,0xF7,0x5F,0x58,0x20,0x4D,0xB8,0x57,0xC7,0xCF,0xDD,
0xC5,0xD8,0xBE,0x76,0x3D,0xF6,0x5F,0x7E,0xE7,0x2A,0x8B,0x88,0x24,0x1B,0x38,0x3F,
0x0E,0x41,0x23,0x77,0xF5,0xF0,0x4B,0xD4,0x0C,0x1F,0xFA,0xA4,0x0B,0x80,0x5F,0xCF,
0x45,0xF6,0xE0,0xDA,0x2F,0x34,0x59,0x53,0xFB,0x20,0x3C,0x52,0x62,0x5E,0x35,0xB5,
0x62,0xFE,0x8B,0x60,0x63,0xE3,0x86,0x5A,0x15,0x1A,0x6E,0xD1,0x47,0x45,0xBC,0x32,
0xB4,0xEB,0x67,0x38,0xAB,0xE4,0x6E,0x33,0x3A,0xB5,0xED,0xA3,0xAD,0x67,0xE0,0x4E,
0x41,0x95,0xEE,0x62,0x62,0x71,0x26,0x1D,0x31,0xEF,0x62,0x30,0xAF,0xD7,0x82,0xAC,
0xC2,0xDC,0x05,0x04,0xF5,0x97,0x07,0xBF,0x11,0x59,0x23,0x07,0xC0,0x64,0x02,0xE8,
0x97,0xE5,0x3E,0xAF,0x18,0xAC,0x59,0xA6,0x8B,0x4A,0x33,0x90,0x1C,0x6E,0x7C,0x9C,
0x20,0x7E,0x4C,0x3C,0x3E,0x61,0x64,0xBB,0xC5,0x6B,0x7C,0x7E,0x3E,0x9F,0xC5,0x4C,
0x9F,0xEA,0x73,0xF5,0xD7,0x89,0xC0,0x4C,0xF4,0xFB,0xF4,0x2D,0xEC,0x14,0x1B,0x51,
0xD5,0xC1,0x12,0xC8,0x10,0xDF,0x0B,0x4A,0x8B,0x9C,0xBC,0x93,0x45,0x6A,0x3E,0x3E,
0x7D,0xC1,0xA9,0xBA,0xCD,0xC1,0xB4,0x07,0xE4,0xE1,0x68,0x86,0x43,0xB2,0x6D,0x38,
0xF3,0xFB,0x0C,0x5C,0x66,0x37,0x71,0xDE,0x56,0xEF,0x6E,0xA0,0x10,0x40,0x65,0xA7,
0x98,0xF7,0xD0,0xBE,0x0E,0xC8,0x37,0x36,0xEC,0x10,0xCA,0x7C,0x9C,0xAB,0x84,0x1E,
0x05,0x17,0x76,0x02,0x1C,0x4F,0x52,0xAA,0x5F,0xC1,0xC6,0xA0,0x56,0xB9,0xD8,0x04,
0x84,0x44,0x4D,0xA7,0x59,0xD8,0xDE,0x60,0xE6,0x38,0x0E,0x05,0x8F,0x03,0xE1,0x3B,
0x6D,0x81,0x04,0x33,0x6F,0x30,0x0B,0xCE,0x69,0x05,0x21,0x33,0xFB,0x26,0xBB,0x89,
0x7D,0xB6,0xAE,0x87,0x7E,0x51,0x07,0xE0,0xAC,0xF7,0x96,0x0A,0x6B,0xF9,0xC4,0x5C,
0x1D,0xE4,0x44,0x47,0xB8,0x5E,0xFA,0xE3,0x78,0x84,0x55,0x42,0x4B,0x48,0x5E,0xF7,
0x7D,0x47,0x35,0x86,0x1D,0x2B,0x43,0x05,0x03,0xEC,0x8A,0xB8,0x1E,0x06,0x3C,0x76,
0x0C,0x48,0x1A,0x43,0xA7,0xB7,0x8A,0xED,0x1E,0x13,0xC6,0x43,0xEE,0x10,0xEF,0xDB,
0xEC,0xFB,0x3C,0x83,0xB2,0x95,0x44,0xEF,0xD8,0x54,0x51,0x4E,0x2D,0x11,0x44,0x1D,
0xFB,0x36,0x59,0x1E,0x7A,0x34,0xC1,0xC3,0xCA,0x57,0x00,0x61,0xEA,0x67,0xA5,0x16,
0x9B,0x55,0xD0,0x55,0xE1,0x7F,0xD9,0x36,0xD2,0x40,0x76,0xAE,0xDC,0x01,0xCE,0xB0,
0x7A,0x83,0xD5,0xCB,0x20,0x98,0xEC,0x6B,0xC1,0x72,0x92,0x34,0xF3,0x82,0x57,0x37,
0x62,0x8A,0x32,0x36,0x0C,0x90,0x43,0xAE,0xAE,0x5C,0x9B,0x78,0x8E,0x13,0x65,0x02,
0xFD,0x68,0x71,0xC1,0xFE,0xB0,0x31,0xA0,0x24,0x82,0xB0,0xC3,0xB1,0x79,0x69,0xA7,
0xF5,0xD2,0xEB,0xD0,0x82,0xC0,0x32,0xDC,0x9E,0xC7,0x26,0x3C,0x6D,0x8D,0x98,0xC1,
0xBB,0x22,0xD4,0xD0,0x0F,0x33,0xEC,0x3E,0xB9,0xCC,0xE1,0xDC,0x6A,0x4C,0x77,0x36,
0x14,0x1C,0xF9,0xBF,0x81,0x9F,0x28,0x5F,0x71,0x85,0x32,0x29,0x90,0x75,0x48,0xC4,
0xB3,0x4A,0xCE,0xD8,0x44,0x8F,0x14,0x2F,0xFD,0x40,0x57,0xEF,0xAA,0x08,0x75,0xD9,
0x46,0xD1,0xD6,0x6E,0x32,0x55,0x1F,0xC3,0x18,0xFE,0x84,0x1F,0xFC,0x84,0xD5,0xFF,
0x71,0x5E,0x1B,0x48,0xC3,0x86,0x95,0x0E,0x28,0x08,0x27,0xD3,0x38,0x83,0x71,0x7B,
0x4C,0x80,0x63,0x54,0x9A,0x56,0xB0,0xAC,0xCF,0x80,0xCA,0x31,0x09,0xEF,0xFE,0xF3,
0xBE,0xAF,0x24,0x7E,0xA6,0xFE,0x53,0x3F,0xC2,0x8D,0x4A,0x33,0x68,0xD1,0x22,0xA6,
0x66,0xAD,0x7B,0xEA,0xDE,0xB6,0x43,0xB0,0xA1,0x25,0x95,0x00,0xA3,0x3F,0x75,0x46,
0x14,0x11,0x44,0xEC,0xD7,0x95,0xBC,0x92,0xF0,0x4F,0xA9,0x16,0x53,0x62,0x97,0x60,
0x2A,0x0F,0x41,0xF1,0x71,0x24,0xBE,0xEE,0x94,0x7F,0x08,0xCD,0x60,0x93,0xB3,0x85,
0x5B,0x07,0x00,0x3F,0xD8,0x0F,0x28,0x83,0x9A,0xD1,0x69,0x9F,0xD1,0xDA,0x2E,0xC3,
0x90,0x01,0xA2,0xB9,0x6B,0x4E,0x2A,0x66,0x9D,0xDA,0xAE,0xA6,0xEA,0x2A,0xD3,0x68,
0x2F,0x0C,0x0C,0x9C,0xD2,0x8C,0x4A,0xED,0xE2,0x9E,0x57,0x65,0x9D,0x09,0x87,0xA3,
0xB4,0xC4,0x32,0x5D,0xC9,0xD4,0x32,0x2B,0xB1,0xE0,0x71,0x1E,0x64,0x4D,0xE6,0x90,
0x71,0xE3,0x1E,0x40,0xED,0x7D,0xF3,0x84,0x0E,0xED,0xC8,0x78,0x76,0xAE,0xC0,0x71,
0x27,0x72,0xBB,0x05,0xEA,0x02,0x64,0xFB,0xF3,0x48,0x6B,0xB5,0x42,0x93,0x3F,0xED,
0x9F,0x13,0x53,0xD2,0xF7,0xFE,0x2A,0xEC,0x1D,0x47,0x25,0xDB,0x3C,0x91,0x86,0xC6,
0x8E,0xF0,0x11,0xFD,0x23,0x74,0x36,0xF7,0xA4,0xF5,0x9E,0x7A,0x7E,0x53,0x50,0x44,
0xD4,0x47,0xCA,0xD3,0xEB,0x38,0x6D,0xE6,0xD9,0x71,0x94,0x7F,0x4A,0xC6,0x69,0x4B,
0x11,0xF4,0x52,0xEA,0x22,0xFE,0x8A,0xB0,0x36,0x67,0x8B,0x59,0xE8,0xE6,0x80,0x2A,
0xEB,0x65,0x04,0x13,0xEE,0xEC,0xDC,0x9E,0x5F,0xB1,0xEC,0x05,0x6A,0x59,0xE6,0x9F,
0x5E,0x59,0x6B,0x89,0xBF,0xF7,0x1A,0xCA,0x44,0xF9,0x5B,0x6A,0x71,0x85,0x03,0xE4,
0x29,0x62,0xE0,0x70,0x6F,0x41,0xC4,0xCF,0xB2,0xB1,0xCC,0xE3,0x7E,0xA6,0x07,0xA8,
0x87,0xE7,0x7F,0x84,0x93,0xDB,0x52,0x4B,0x6C,0xEC,0x7E,0xDD,0xD4,0x24,0x48,0x10,
0x69,0x9F,0x04,0x60,0x74,0xE6,0x48,0x18,0xF3,0xE4,0x2C,0xB9,0x4F,0x2E,0x50,0x7A,
0xDF,0xD4,0x54,0x69,0x2B,0x8B,0xA7,0xF3,0xCE,0xFF,0x1F,0xF3,0x3E,0x26,0x01,0x39,
0x17,0x95,0x84,0x89,0xB0,0xF0,0x4C,0x4B,0x82,0x91,0x9F,0xC4,0x4B,0xAC,0x9D,0xA5,
0x74,0xAF,0x17,0x25,0xC9,0xCA,0x32,0xD3,0xBC,0x89,0x8A,0x84,0x89,0xCC,0x0D,0xAE,
0x7C,0xA2,0xDB,0x9C,0x6A,0x78,0x91,0xEE,0xEA,0x76,0x5D,0x4E,0x87,0x60,0xF5,0x69,
0x15,0x67,0xD4,0x02,0xCF,0xAF,0x48,0x36,0x07,0xEA,0xBF,0x6F,0x66,0x2D,0x06,0x8F,
0xC4,0x9A,0xFE,0xF9,0xF6,0x90,0x87,0x75,0xB8,0xF7,0xAD,0x0F,0x76,0x10,0x5A,0x3D,
0x59,0xB0,0x2E,0xB3,0xC7,0x35,0x2C,0xCC,0x70,0x56,0x2B,0xCB,0xE3,0x37,0x96,0xC5,
0x2F,0x46,0x1B,0x8A,0x22,0x46,0xC7,0x88,0xA7,0x26,0x32,0x98,0x61,0xDF,0x86,0x22,
0x8A,0xF4,0x1C,0x2F,0x87,0xA1,0x09,0xAA,0xCC,0xA9,0xAE,0xD3,0xBD,0x00,0x45,0x1C,
0x9A,0x54,0x87,0x86,0x52,0x87,0xEF,0xFF,0x1E,0x8F,0xA1,0x8F,0xC1,0x89,0x5C,0x35,
0x1B,0xDA,0x2D,0x3A,0x2C,0x16,0xB2,0xC2,0xF1,0x56,0xE2,0x78,0xC1,0x6B,0x63,0x97,
0xC5,0x56,0x8F,0xC9,0x32,0x7F,0x2C,0xAA,0xAF,0xA6,0xA8,0xAC,0x20,0x91,0x22,0x88,
0xDE,0xE4,0x60,0x8B,0xF9,0x4B,0x42,0x25,0x1A,0xE3,0x7F,0x9C,0x2C,0x19,0x89,0x3A,
0x7E,0x05,0xD4,0x36,0xCC,0x69,0x58,0xC2,0xC1,0x32,0x8B,0x2F,0x90,0x85,0xEB,0x7A,
0x39,0x50,0xA5,0xA1,0x27,0x92,0xC5,0x66,0xB0,0x20,0x4F,0x58,0x7E,0x55,0x83,0x43,
0x2B,0x45,0xE2,0x9C,0xE4,0xD8,0x12,0x90,0x2C,0x16,0x83,0x56,0x16,0x79,0x03,0xB3,
0xAD,0x2D,0x61,0x18,0x1A,0x13,0x1F,0x37,0xE2,0xE1,0x9C,0x73,0x7B,0x80,0xD5,0xFD,
0x2D,0x51,0x87,0xFC,0x7B,0xAA,0xD7,0x1F,0x2C,0x7A,0x8E,0xAF,0xF4,0x8D,0xBB,0xCD,
0x95,0x11,0x7C,0x72,0x0B,0xEE,0x6F,0xE2,0xB9,0xAF,0xDE,0x37,0x83,0xDE,0x8C,0x8D,
0x62,0x05,0x67,0xB7,0x96,0xC6,0x8D,0x56,0xB6,0x0D,0xD7,0x62,0xBA,0xD6,0x46,0x36,
0xBD,0x8E,0xC8,0xE6,0xEA,0x2A,0x6C,0x10,0x14,0xFF,0x6B,0x5B,0xFA,0x82,0x3C,0x46,
0xB1,0x30,0x43,0x46,0x51,0x8A,0x7D,0x9B,0x92,0x3E,0x83,0x79,0x5B,0x55,0x5D,0xB2,
0x6C,0x5E,0xCE,0x90,0x62,0x8E,0x53,0x98,0xC9,0x0D,0x6D,0xE5,0x2D,0x57,0xCD,0xC5,
0x81,0x57,0xBA,0xE1,0xE8,0xB8,0x8F,0x72,0xE5,0x4F,0x13,0xDC,0xEA,0x9D,0x71,0x15,
0x10,0xB2,0x11,0x88,0xD5,0x09,0xD4,0x7F,0x5B,0x65,0x7F,0x2C,0x3B,0x38,0x4C,0x11,
0x68,0x50,0x8D,0xFB,0x9E,0xB0,0x59,0xBF,0x94,0x80,0x89,0x4A,0xC5,0x1A,0x18,0x12,
0x89,0x53,0xD1,0x4A,0x10,0x29,0xE8,0x8C,0x1C,0xEC,0xB6,0xEA,0x46,0xC7,0x17,0x8B,
0x25,0x15,0x31,0xA8,0xA2,0x6B,0x43,0xB1,0x9D,0xE2,0xDB,0x0B,0x87,0x9B,0xB0,0x11,
0x04,0x0E,0x71,0xD2,0x29,0x77,0x89,0x82,0x0A,0x66,0x41,0x7F,0x1D,0x0B,0x48,0xFF,
0x72,0xBB,0x24,0xFD,0xC2,0x48,0xA1,0x9B,0xFE,0x7B,0x7F,0xCE,0x88,0xDB,0x86,0xD9,
0x85,0x3B,0x1C,0xB0,0xDC,0xA8,0x33,0x07,0xBF,0x51,0x2E,0xE3,0x0E,0x9A,0x00,0x97,
0x1E,0x06,0xC0,0x97,0x43,0x9D,0xD8,0xB6,0x45,0xC4,0x86,0x67,0x5F,0x00,0xF8,0x88,
0x9A,0xA4,0x52,0x9E,0xC7,0xAA,0x8A,0x83,0x75,0xEC,0xC5,0x18,0xAE,0xCE,0xC3,0x2F,
0x1A,0x2B,0xF9,0x18,0xFF,0xAE,0x1A,0xF5,0x53,0x0B,0xB5,0x33,0x51,0xA7,0xFD,0xE8,
0xA8,0xE1,0xA2,0x64,0xB6,0x22,0x17,0x43,0x80,0xCC,0x0A,0xD8,0xAE,0x3B,0xBA,0x40,
0xD7,0xD9,0x92,0x4A,0x89,0xDF,0x04,0x10,0xEE,0x9B,0x18,0x2B,0x6A,0x77,0x69,0x8A,
0x68,0xF4,0xF9,0xB9,0xA2,0x21,0x15,0x6E,0xE6,0x1E,0x3B,0x03,0x62,0x30,0x9B,0x60,
0x41,0x7E,0x25,0x9B,0x9E,0x8F,0xC5,0x52,0x10,0x08,0xF8,0xC2,0x69,0xA1,0x21,0x11,
0x88,0x37,0x5E,0x79,0x35,0x66,0xFF,0x10,0x42,0x18,0x6E,0xED,0x97,0xB6,0x6B,0x1C,
0x4E,0x36,0xE5,0x6D,0x7D,0xB4,0xE4,0xBF,0x20,0xB9,0xE0,0x05,0x3A,0x69,0xD5,0xB8,
0xE3,0xD5,0xDC,0xE0,0xB9,0xAC,0x53,0x3E,0x07,0xA4,0x57,0xAD,0x77,0xFF,0x48,0x18,
0x76,0x2A,0xAC,0x49,0x2A,0x8E,0x47,0x75,0x6D,0x9F,0x67,0x63,0x30,0x35,0x8C,0x39,
0x05,0x39,0xD5,0x6F,0x64,0x3A,0x5B,0xAD,0xCA,0x0B,0xBB,0x82,0x52,0x99,0x45,0xB1,
0x93,0x36,0x36,0x99,0xAF,0x13,0x20,0x44,0x36,0xD8,0x02,0x44,0x09,0x39,0x92,0x85,
0xFF,0x4A,0x4A,0x97,0x87,0xA6,0x63,0xD7,0xC7,0xB5,0xB5,0x24,0xED,0x0F,0xB4,0x6F,
0x0C,0x58,0x52,0x14,0xD9,0xA6,0x7B,0xD3,0x79,0xBC,0x38,0x58,0xA1,0xBD,0x3B,0x84,
0x06,0xD8,0x1A,0x06,0xFD,0x6B,0xA8,0xEA,0x4B,0x69,0x28,0x04,0x37,0xAD,0x82,0x99,
0xFB,0x0E,0x1B,0x85,0xBD,0xA8,0x5D,0x73,0xCD,0xDC,0x58,0x75,0x0A,0xBE,0x63,0x6C,
0x48,0xE7,0x4C,0xE4,0x30,0x2B,0x04,0x60,0xB9,0x15,0xD8,0xDA,0x86,0x81,0x75,0x8F,
0x96,0xD4,0x8D,0x1C,0x5D,0x70,0x85,0x7C,0x1C,0x67,0x7B,0xD5,0x08,0x67,0xA6,0xCE,
0x4B,0x0A,0x66,0x70,0xB7,0xE5,0x63,0xD4,0x5B,0x8A,0x82,0xEA,0x10,0x67,0xCA,0xE2,
0xF4,0xEF,0x17,0x85,0x2F,0x2A,0x5F,0x8A,0x97,0x82,0xF8,0x6A,0xD6,0x34,0x10,0xEA,
0xEB,0xC9,0x5C,0x3C,0xE1,0x49,0xF8,0x46,0xEB,0xDE,0xBD,0xF6,0xA9,0x92,0xF1,0xAA,
0xA6,0xA0,0x18,0xB0,0x3A,0xD3,0x0F,0x1F,0xF3,0x6F,0xFF,0x31,0x45,0x43,0x44,0xD3,
0x50,0x9A,0xF7,0x88,0x09,0x96,0xC1,0xCE,0x76,0xCC,0xF2,0x2C,0x2C,0xBA,0xAD,0x82,
0x77,0x8F,0x18,0x84,0xC0,0xD2,0x07,0x9C,0x36,0x90,0x83,0x4E,0x0B,0xA5,0x4F,0x43,
0x3E,0x04,0xAB,0x78,0x4F,0xD6,0xFB,0x09,0x01,0x24,0x90,0xDA,0x6F,0x3C,0x3A,0x61,
0x0D,0x7F,0x69,0x4A,0xEB,0x2B,0x30,0x02,0xB4,0xDB,0xE0,0x84,0xA9,0xEC,0xD7,0x35,
0xBF,0x37,0x7D,0x85,0x58,0xCE,0xA9,0x4E,0xE4,0x80,0xC7,0xA8,0xD3,0x30,0x67,0x48,
0xEB,0x29,0xAF,0x2F,0x74,0x6A,0xB4,0xA7,0x3F,0x0F,0x3F,0x92,0xAF,0xF3,0xCA,0xAC,
0xAF,0x4B,0xD9,0x94,0xC0,0x43,0xCA,0x81,0x0D,0x2F,0x48,0xA1,0xB0,0x27,0xD5,0xD2,
0xEF,0x4B,0x05,0x85,0xA3,0xDE,0x4D,0x93,0x30,0x3C,0xF0,0xBB,0x4A,0x8F,0x30,0x27,
0x4C,0xEB,0xE3,0x3E,0x64,0xED,0x9A,0x2F,0x3B,0xF1,0x82,0xF0,0xBA,0xF4,0xCF,0x7F,
0x40,0xCB,0xB0,0xE1,0x7F,0xBC,0xAA,0x57,0xD3,0xC9,0x74,0xF2,0xFA,0x43,0x0D,0x22,
0xD0,0xF4,0x77,0x4E,0x93,0xD7,0x85,0x70,0x1F,0x99,0xBF,0xB6,0xDE,0x35,0xF1,0x30,
0xA7,0x5E,0x71,0xF0,0x6B,0x01,0x2D,0x7B,0x64,0xF0,0x33,0x53,0x0A,0x39,0x88,0xF3,
0x6B,0x3A,0xA6,0x6B,0x35,0xD2,0x2F,0x43,0xCD,0x02,0xFD,0xB5,0xE9,0xBC,0x5B,0xAA,
0xD8,0xA4,0x19,0x7E,0x0E,0x5D,0x94,0x81,0x9E,0x6F,0x77,0xAD,0xD6,0x0E,0x74,0x93,
0x96,0xE7,0xC4,0x18,0x5F,0xAD,0xF5,0x19,
};
u32 card_hash[0x412];
int cardheader_devicetype = 0;
u32 global3_x00, global3_x04; // RTC value
u32 global3_rand1;
u32 global3_rand3;
u32 lookup(u32 *magic, u32 v)
{
u32 a = (v >> 24) & 0xFF;
u32 b = (v >> 16) & 0xFF;
u32 c = (v >> 8) & 0xFF;
u32 d = (v >> 0) & 0xFF;
a = magic[a+18+0];
b = magic[b+18+256];
c = magic[c+18+512];
d = magic[d+18+768];
return d + (c ^ (b + a));
}
void encrypt(u32 *magic, u32 *arg1, u32 *arg2)
{
u32 a,b,c;
a = *arg1;
b = *arg2;
for (int i=0; i<16; i++)
{
c = magic[i] ^ a;
a = b ^ lookup(magic, c);
b = c;
}
*arg2 = a ^ magic[16];
*arg1 = b ^ magic[17];
}
void decrypt(u32 *magic, u32 *arg1, u32 *arg2)
{
u32 a,b,c;
a = *arg1;
b = *arg2;
for (int i=17; i>1; i--)
{
c = magic[i] ^ a;
a = b ^ lookup(magic, c);
b = c;
}
*arg1 = b ^ magic[0];
*arg2 = a ^ magic[1];
}
void encrypt(u32 *magic, u64 &cmd)
{
encrypt(magic, (u32 *)&cmd + 1, (u32 *)&cmd + 0);
}
void decrypt(u32 *magic, u64 &cmd)
{
decrypt(magic, (u32 *)&cmd + 1, (u32 *)&cmd + 0);
}
void update_hashtable(u32* magic, u8 arg1[8])
{
for (int j=0;j<18;j++)
{
u32 r3=0;
for (int i=0;i<4;i++)
{
r3 <<= 8;
r3 |= arg1[(j*4 + i) & 7];
}
magic[j] ^= r3;
}
u32 tmp1 = 0;
u32 tmp2 = 0;
for (int i=0; i<18; i+=2)
{
encrypt(magic,&tmp1,&tmp2);
magic[i+0] = tmp1;
magic[i+1] = tmp2;
}
for (int i=0; i<0x400; i+=2)
{
encrypt(magic,&tmp1,&tmp2);
magic[i+18+0] = tmp1;
magic[i+18+1] = tmp2;
}
}
u32 arg2[3];
void init2(u32 *magic, u32 a[3])
{
encrypt(magic, a+2, a+1);
encrypt(magic, a+1, a+0);
update_hashtable(magic, (u8*)a);
}
void init1(u32 cardheader_gamecode)
{
memcpy(card_hash, &encr_data, 4*(1024 + 18));
arg2[0] = *(u32 *)&cardheader_gamecode;
arg2[1] = (*(u32 *)&cardheader_gamecode) >> 1;
arg2[2] = (*(u32 *)&cardheader_gamecode) << 1;
init2(card_hash, arg2);
init2(card_hash, arg2);
}
void init0(u32 cardheader_gamecode)
{
init1(cardheader_gamecode);
encrypt(card_hash, (u32*)&global3_x04, (u32*)&global3_x00);
global3_rand1 = global3_x00 ^ global3_x04; // more RTC
global3_rand3 = global3_x04 ^ 0x0380FEB2;
encrypt(card_hash, (u32*)&global3_rand3, (u32*)&global3_rand1);
}
// ARM9 decryption check values
#define MAGIC30 0x72636E65
#define MAGIC34 0x6A624F79
/*
* decrypt_arm9
*/
void decrypt_arm9(u32 cardheader_gamecode, unsigned char *data)
{
u32 *p = (u32*)data;
init1(cardheader_gamecode);
decrypt(card_hash, p+1, p);
arg2[1] <<= 1;
arg2[2] >>= 1;
init2(card_hash, arg2);
decrypt(card_hash, p+1, p);
if (p[0] != MAGIC30 || p[1] != MAGIC34)
{
fprintf(stderr, "Decryption failed!\n");
exit(1);
}
*p++ = 0xE7FFDEFF;
*p++ = 0xE7FFDEFF;
u32 size = 0x800 - 8;
while (size > 0)
{
decrypt(card_hash, p+1, p);
p += 2;
size -= 8;
}
}
void DecryptSecureArea(u8 *romdata, long romlen)
{
//this looks like it will only work on little endian hosts
Header* header = (Header*)romdata;
int romType = DetectRomType(*header,(char*)romdata);
unsigned char data[0x4000];
memcpy(data,romdata+0x4000,0x4000);
/*bool do_decrypt = (endecrypt_option == 'd');
bool do_encrypt = (endecrypt_option == 'e') || (endecrypt_option == 'E');
unsigned int rounds_offsets = (endecrypt_option == 'E') ? 0x2000 : 0x1600;
unsigned int sbox_offsets = (endecrypt_option == 'E') ? 0x2400 : 0x2800;*/
unsigned int rounds_offsets = 0x1600;
unsigned int sbox_offsets = 0x2800;
// check if ROM is already encrypted
if (romType == ROMTYPE_NDSDUMPED)
{
printf("Already decrypted.\n");
}
else if (romType >= ROMTYPE_ENCRSECURE) // includes ROMTYPE_MASKROM
{
decrypt_arm9(*(u32 *)header->gamecode, data);
// clear data after header
//fseek(fNDS, 0x200, SEEK_SET);
//for (unsigned int i=0x200; i<0x4000; i++) fputc(0, fNDS);
memset(romdata+0x200,0,(0x4000-0x200));
// write secure 0x800
//fseek(fNDS, 0x4000, SEEK_SET);
//fwrite(data, 1, 0x800, fNDS);
memcpy(romdata+0x4000,data,0x800);
// write header
//(already poked directly)
//fseek(fNDS, 0, SEEK_SET);
//fwrite(&header, 512, 1, fNDS);
printf("Decrypted.\n");
}
else
{
fprintf(stderr, "File doesn't appear to have a secure area!\n"); exit(1);
}
}

View File

@ -0,0 +1,6 @@
#ifndef _DECRYPT_H_
#define _DECRYPT_H_
void DecryptSecureArea(u8 *romdata, long romlen);
#endif

View File

@ -0,0 +1,633 @@
//taken from ndstool
//http://devkitpro.cvs.sourceforge.net/viewvc/devkitpro/tools/nds/ndstool/source/header.cpp?revision=1.23
#include "header.h"
//#include "ndstool.h"
//#include "banner.h"
//#include "sha1.h"
//#include "crc.h"
//#include "bigint.h"
//#include "arm7_sha1_homebrew.h"
//#include "arm7_sha1_nintendo.h"
//#include "encryption.h"
//
///*
// * Data
// */
//unsigned char publicKeyNintendo[] =
//{
// 0x9E, 0xC1, 0xCC, 0xC0, 0x4A, 0x6B, 0xD0, 0xA0, 0x6D, 0x62, 0xED, 0x5F, 0x15, 0x67, 0x87, 0x12,
// 0xE6, 0xF4, 0x77, 0x1F, 0xD8, 0x5C, 0x81, 0xCE, 0x0C, 0xD0, 0x22, 0x31, 0xF5, 0x89, 0x08, 0xF5,
// 0xBE, 0x04, 0xCB, 0xC1, 0x4F, 0x63, 0xD9, 0x5A, 0x98, 0xFF, 0xEB, 0x36, 0x0F, 0x9C, 0x5D, 0xAD,
// 0x15, 0xB9, 0x99, 0xFB, 0xC6, 0x86, 0x2C, 0x0A, 0x0C, 0xFC, 0xE6, 0x86, 0x03, 0x60, 0xD4, 0x87,
// 0x28, 0xD5, 0x66, 0x42, 0x9C, 0xF7, 0x04, 0x14, 0x4E, 0x6F, 0x73, 0x20, 0xC3, 0x3E, 0x3F, 0xF5,
// 0x82, 0x2E, 0x78, 0x18, 0xD6, 0xCD, 0xD5, 0xC2, 0xDC, 0xAA, 0x1D, 0x34, 0x91, 0xEC, 0x99, 0xC9,
// 0xF7, 0xBF, 0xBF, 0xA0, 0x0E, 0x1E, 0xF0, 0x25, 0xF8, 0x66, 0x17, 0x54, 0x34, 0x28, 0x2D, 0x28,
// 0xA3, 0xAE, 0xF0, 0xA9, 0xFA, 0x3A, 0x70, 0x56, 0xD2, 0x34, 0xA9, 0xC5, 0x9E, 0x5D, 0xF5, 0xE1,
//};
//
///*
// * CalcHeaderCRC
// */
//unsigned short CalcHeaderCRC(Header &header)
//{
// return CalcCrc16((unsigned char *)&header, 0x15E);
//}
//
///*
// * CalcLogoCRC
// */
//unsigned short CalcLogoCRC(Header &header)
//{
// return CalcCrc16((unsigned char *)&header + 0xC0, 156);
//}
//
/*
* DetectRomType
*/
int DetectRomType(const Header& header, char* romdata)
{
unsigned int * data = (unsigned int*)(romdata + 0x4000);
if (header.arm9_rom_offset < 0x4000) return ROMTYPE_HOMEBREW;
if (data[0] == 0x00000000 && data[1] == 0x00000000) return ROMTYPE_MULTIBOOT;
if (data[0] == 0xE7FFDEFF && data[1] == 0xE7FFDEFF) return ROMTYPE_NDSDUMPED;
romdata += 0x200;
for (int i=0x200; i<0x4000; i++)
if (*romdata) return ROMTYPE_MASKROM; // found something odd ;)
return ROMTYPE_ENCRSECURE;
}
///*
// * CalcSecureAreaCRC
// */
//unsigned short CalcSecureAreaCRC(bool encrypt)
//{
// fseek(fNDS, 0x4000, SEEK_SET);
// unsigned char data[0x4000];
// fread(data, 1, 0x4000, fNDS);
// if (encrypt) encrypt_arm9(*(u32 *)header.gamecode, data);
// return CalcCrc16(data, 0x4000);
//}
//
///*
// * CalcSecurityDataCRC
// */
//unsigned short CalcSecurityDataCRC()
//{
// fseek(fNDS, 0x1000, SEEK_SET);
// unsigned char data[0x2000];
// fread(data, 1, 0x2000, fNDS);
// return CalcCrc16(data, 0x2000);
//}
//
///*
// * CalcSegment3CRC
// */
//unsigned short CalcSegment3CRC()
//{
// fseek(fNDS, 0x3000, SEEK_SET);
// unsigned char data[0x1000];
// fread(data, 1, 0x1000, fNDS);
// for (int i=0; i<0x1000; i+=2) // swap bytes
// {
// unsigned char t = data[i+1]; data[i+1] = data[i]; data[i] = t;
// }
// return CalcCcitt16(data, 0x1000); // why would they use CRC16-CCITT ?
//}
//
///*
// * FixHeaderCRC
// */
//void FixHeaderCRC(char *ndsfilename)
//{
// fNDS = fopen(ndsfilename, "r+b");
// if (!fNDS) { fprintf(stderr, "Cannot open file '%s'.\n", ndsfilename); exit(1); }
// fread(&header, 512, 1, fNDS);
// header.header_crc = CalcHeaderCRC(header);
// fseek(fNDS, 0, SEEK_SET);
// fwrite(&header, 512, 1, fNDS);
// fclose(fNDS);
//}
//
///*
// * ShowHeaderInfo
// */
//void ShowHeaderInfo(Header &header, int romType, unsigned int length = 0x200)
//{
// printf("0x00\t%-25s\t", "Game title");
//
// for (unsigned int i=0; i<sizeof(header.title); i++)
// if (header.title[i]) putchar(header.title[i]); printf("\n");
//
// printf("0x0C\t%-25s\t", "Game code");
// for (unsigned int i=0; i<sizeof(header.gamecode); i++)
// if (header.gamecode[i]) putchar(header.gamecode[i]);
// for (int i=0; i<NumCountries; i++)
// {
// if (countries[i].countrycode == header.gamecode[3])
// {
// printf(" (NTR-");
// for (unsigned int j=0; j<sizeof(header.gamecode); j++)
// if (header.gamecode[j]) putchar(header.gamecode[j]);
// printf("-%s)", countries[i].name);
// break;
// }
// }
// printf("\n");
//
// printf("0x10\t%-25s\t", "Maker code"); for (unsigned int i=0; i<sizeof(header.makercode); i++)
// if (header.makercode[i]) putchar(header.makercode[i]);
// for (int j=0; j<NumMakers; j++)
// {
// if ((makers[j].makercode[0] == header.makercode[0]) && (makers[j].makercode[1] == header.makercode[1]))
// {
// printf(" (%s)", makers[j].name);
// break;
// }
// }
// printf("\n");
//
// printf("0x12\t%-25s\t0x%02X\n", "Unit code", header.unitcode);
// printf("0x13\t%-25s\t0x%02X\n", "Device type", header.devicetype);
// printf("0x14\t%-25s\t0x%02X (%d Mbit)\n", "Device capacity", header.devicecap, 1<<header.devicecap);
// printf("0x15\t%-25s\t", "reserved 1"); for (unsigned int i=0; i<sizeof(header.reserved1); i++) printf("%02X", header.reserved1[i]); printf("\n");
// printf("0x1E\t%-25s\t0x%02X\n", "ROM version", header.romversion);
// printf("0x1F\t%-25s\t0x%02X\n", "reserved 2", header.reserved2);
// printf("0x20\t%-25s\t0x%X\n", "ARM9 ROM offset", (int)header.arm9_rom_offset);
// printf("0x24\t%-25s\t0x%X\n", "ARM9 entry address", (int)header.arm9_entry_address);
// printf("0x28\t%-25s\t0x%X\n", "ARM9 RAM address", (int)header.arm9_ram_address);
// printf("0x2C\t%-25s\t0x%X\n", "ARM9 code size", (int)header.arm9_size);
// printf("0x30\t%-25s\t0x%X\n", "ARM7 ROM offset", (int)header.arm7_rom_offset);
// printf("0x34\t%-25s\t0x%X\n", "ARM7 entry address", (int)header.arm7_entry_address);
// printf("0x38\t%-25s\t0x%X\n", "ARM7 RAM address", (int)header.arm7_ram_address);
// printf("0x3C\t%-25s\t0x%X\n", "ARM7 code size", (int)header.arm7_size);
// printf("0x40\t%-25s\t0x%X\n", "File name table offset", (int)header.fnt_offset);
// printf("0x44\t%-25s\t0x%X\n", "File name table size", (int)header.fnt_size);
// printf("0x48\t%-25s\t0x%X\n", "FAT offset", (int)header.fat_offset);
// printf("0x4C\t%-25s\t0x%X\n", "FAT size", (int)header.fat_size);
// printf("0x50\t%-25s\t0x%X\n", "ARM9 overlay offset", (int)header.arm9_overlay_offset);
// printf("0x54\t%-25s\t0x%X\n", "ARM9 overlay size", (int)header.arm9_overlay_size);
// printf("0x58\t%-25s\t0x%X\n", "ARM7 overlay offset", (int)header.arm7_overlay_offset);
// printf("0x5C\t%-25s\t0x%X\n", "ARM7 overlay size", (int)header.arm7_overlay_size);
// printf("0x60\t%-25s\t0x%08X\n", "ROM control info 1", (int)header.rom_control_info1);
// printf("0x64\t%-25s\t0x%08X\n", "ROM control info 2", (int)header.rom_control_info2);
// printf("0x68\t%-25s\t0x%X\n", "Icon/title offset", (int)header.banner_offset);
// unsigned short secure_area_crc = CalcSecureAreaCRC((romType == ROMTYPE_NDSDUMPED));
// const char *s1, *s2 = "";
// if (romType == ROMTYPE_HOMEBREW) s1 = "-";
// else if (secure_area_crc == header.secure_area_crc) s1 = "OK";
// else
// {
// s1 = "INVALID";
// }
// switch (romType)
// {
// case ROMTYPE_HOMEBREW: s2 = "homebrew"; break;
// case ROMTYPE_MULTIBOOT: s2 = "multiboot"; break;
// case ROMTYPE_NDSDUMPED: s2 = "decrypted"; break;
// case ROMTYPE_ENCRSECURE: s2 = "encrypted"; break;
// case ROMTYPE_MASKROM: s2 = "mask ROM"; break;
// }
// printf("0x6C\t%-25s\t0x%04X (%s, %s)\n", "Secure area CRC", (int)header.secure_area_crc, s1, s2);
// printf("0x6E\t%-25s\t0x%04X\n", "ROM control info 3", (int)header.rom_control_info3);
// printf("0x70\t%-25s\t0x%X\n", "ARM9 ?", (int)header.offset_0x70);
// printf("0x74\t%-25s\t0x%X\n", "ARM7 ?", (int)header.offset_0x74);
// printf("0x78\t%-25s\t0x%08X\n", "Magic 1", (int)header.offset_0x78);
// printf("0x7C\t%-25s\t0x%08X\n", "Magic 2", (int)header.offset_0x7C);
// printf("0x80\t%-25s\t0x%08X\n", "Application end offset", (int)header.application_end_offset);
// printf("0x84\t%-25s\t0x%08X\n", "ROM header size", (int)header.rom_header_size);
// for (unsigned int i=0x88; i<0xC0; i+=4)
// {
// unsigned_int &x = ((unsigned_int *)&header)[i/4];
// if (x != 0) printf("0x%02X\t%-25s\t0x%08X\n", i, "?", (int)x);
// }
// unsigned short logo_crc = CalcLogoCRC(header);
// printf("0x15C\t%-25s\t0x%04X (%s)\n", "Logo CRC", (int)header.logo_crc, (logo_crc == header.logo_crc) ? "OK" : "INVALID");
// unsigned short header_crc = CalcHeaderCRC(header);
// printf("0x15E\t%-25s\t0x%04X (%s)\n", "Header CRC", (int)header.header_crc, (header_crc == header.header_crc) ? "OK" : "INVALID");
// for (unsigned int i=0x160; i<length; i+=4)
// {
// unsigned_int &x = ((unsigned_int *)&header)[i/4];
// if (x != 0) printf("0x%02X\t%-25s\t0x%08X\n", i, "?", (int)x);
// }
//}
//
///*
// * HeaderSha1
// */
//void HeaderSha1(FILE *fNDS, unsigned char *header_sha1, int romType)
//{
// sha1_ctx m_sha1;
// sha1_begin(&m_sha1);
// unsigned char buf[32 + 0x200];
// fseek(fNDS, 0x200, SEEK_SET); // check for 32 bytes text + alternate header
// fread(buf, 1, sizeof(buf), fNDS);
// if (!memcmp(buf, "DS DOWNLOAD PLAY", 16)) // found?
// {
// sha1_hash(buf + 0x20, 0x160, &m_sha1); // alternate header
// if (verbose >= 2)
// {
// printf("{ DS Download Play(TM) / Wireless MultiBoot header information:\n");
// ShowHeaderInfo(*(Header *)(buf + 0x20), romType, 0x160);
// printf("}\n");
// }
// }
// else
// {
// fseek(fNDS, 0, SEEK_SET);
// fread(buf, 1, sizeof(buf), fNDS);
// sha1_hash(buf, 0x160, &m_sha1);
// }
// sha1_end(header_sha1, &m_sha1);
//}
//
///*
// * Arm9Sha1Multiboot
// */
//void Arm9Sha1Multiboot(FILE *fNDS, unsigned char *arm9_sha1)
//{
// sha1_ctx m_sha1;
// sha1_begin(&m_sha1);
// fseek(fNDS, header.arm9_rom_offset, SEEK_SET);
// unsigned int len = header.arm9_size;
// unsigned char *buf = new unsigned char [len];
// fread(buf, 1, len, fNDS);
// //printf("%u\n", len);
// sha1_hash(buf, len, &m_sha1);
// delete [] buf;
// sha1_end(arm9_sha1, &m_sha1);
//}
//
///*
// * Arm9Sha1ClearedOutArea
// */
//void Arm9Sha1ClearedOutArea(FILE *fNDS, unsigned char *arm9_sha1)
//{
// sha1_ctx m_sha1;
// sha1_begin(&m_sha1);
// fseek(fNDS, header.arm9_rom_offset, SEEK_SET);
// unsigned int len = header.arm9_size;
// unsigned char *buf = new unsigned char [len];
//
// int len1 = (0x5000 - header.arm9_rom_offset); // e.g. 0x5000 - 0x4000 = 0x1000
// int len3 = header.arm9_size - (0x7000 - header.arm9_rom_offset); // e.g. 0x10000 - (0x7000 - 0x4000) = 0xD000
// int len2 = header.arm9_size - len1 - len3; // e.g. 0x10000 - 0x1000 - 0xD000 = 0x2000
// if (len1 > 0) fread(buf, 1, len1, fNDS);
// if (len2 > 0) { memset(buf + len1, 0, len2); fseek(fNDS, len2, SEEK_CUR); } // gets cleared for security?
// if (len3 > 0) fread(buf + len1 + len2, 1, len3, fNDS);
//// printf("%X %X %X\n", len1, len2, len3);
//
//// memset(buf, 0, 0x800); // clear "secure area" too
//
// sha1_hash(buf, len, &m_sha1);
// delete [] buf;
// sha1_end(arm9_sha1, &m_sha1);
//}
//
///*
// * Arm7Sha1
// */
//void Arm7Sha1(FILE *fNDS, unsigned char *arm7_sha1)
//{
// sha1_ctx m_sha1;
// sha1_begin(&m_sha1);
// fseek(fNDS, header.arm7_rom_offset, SEEK_SET);
// unsigned int len = header.arm7_size;
// unsigned char *buf = new unsigned char [len];
// fread(buf, 1, len, fNDS);
// //printf("%u\n", len);
// sha1_hash(buf, len, &m_sha1);
// delete [] buf;
// sha1_end(arm7_sha1, &m_sha1);
//}
//
///*
// * CompareSha1WithList
// */
//int CompareSha1WithList(unsigned char *arm7_sha1, const unsigned char *text, unsigned int textSize)
//{
// while (1)
// {
// //printf("\n");
// for (int i=0; i<SHA1_DIGEST_SIZE; i++)
// {
// unsigned char b = 0;
// for (int n=0; n<2; n++)
// {
// //printf("%c", *text);
// if (!*text) return -1;
// b = b << 4 | ((*text > '9') ? ((*text - 'A') & 7) + 10 : *text - '0');
// text++;
// }
// //printf("%02X", b);
// if (b != arm7_sha1[i]) break; else if (i == 19) return 0;
// }
// while (*text && (*text >= ' ')) text++; // line end
// while (*text && (*text < ' ')) text++; // new line
// }
//}
//
///*
// * HashAndCompareWithList
// * -1=error, 0=match, 1=no match
// */
//int HashAndCompareWithList(char *filename, unsigned char sha1[])
//{
// FILE *f = fopen(filename, "rb");
// if (!f) return -1;
// sha1_ctx m_sha1;
// sha1_begin(&m_sha1);
// unsigned char buf[1024];
// unsigned int r;
// do
// {
// r = fread(buf, 1, 1024, f);
// sha1_hash(buf, r, &m_sha1);
// } while (r > 0);
// fclose(f);
// sha1_end(sha1, &m_sha1);
// if (CompareSha1WithList(sha1, arm7_sha1_homebrew, arm7_sha1_homebrew_size)) return 1; // not yet in list
// return 0;
//}
//
///*
// * strsepc
// */
//char *strsepc(char **s, char d)
//{
// char *r = *s;
// for (char *p = *s; ; p++)
// {
// if (*p == 0) { *s = p; break; }
// if (*p == d) { *s = p+1; *p = 0; break; }
// }
// return r;
//}
//
///*
// * RomListInfo
// */
//void RomListInfo(unsigned int crc32_match)
//{
// if (!romlistfilename) return;
// FILE *fRomList = fopen(romlistfilename, "rt");
// if (!fRomList) { fprintf(stderr, "Cannot open file '%s'.\n", romlistfilename); exit(1); }
// char s[1024];
// while (fgets(s, 1024, fRomList)) // empty, title, title, title, title, filename, CRC32
// {
// char *p = s;
// if (strlen(strsepc(&p, '\xAC')) == 0)
// {
// char *title = strsepc(&p, '\xAC');
// unsigned int index = strtoul(title, 0, 10);
// title += 7;
// char *b1 = strchr(title, '(');
// char *b2 = b1 ? strchr(b1+1, ')') : 0;
// char *b3 = b2 ? strchr(b2+1, '(') : 0;
// char *b4 = b3 ? strchr(b3+1, ')') : 0;
// char *group = 0;
// if (b1 + 2 == b2) if (b3 && b4) { *b3 = 0; *b4 = 0; group = b3+1; } // remove release group name
// strsepc(&p, '\xAC'); strsepc(&p, '\xAC');
// strsepc(&p, '\xAC'); strsepc(&p, '\xAC');
// unsigned long crc32 = strtoul(strsepc(&p, '\xAC'), 0, 16);
// if (crc32 == crc32_match)
// {
// printf("Release index: \t%u\n", index);
// printf("Release title: \t%s\n", title);
// printf("Release group: \t%s\n", group ? group : "");
// }
// //for (int i=0; i<10; i++) printf("%d %s\n", i, strsepc(&p, '\xAC'));
// }
// }
//}
//
///*
// * ShowVerboseInfo
// */
//void ShowVerboseInfo(FILE *fNDS, Header &header, int romType)
//{
// // calculate SHA1 of ARM7 binary
// unsigned char arm7_sha1[SHA1_DIGEST_SIZE];
// Arm7Sha1(fNDS, arm7_sha1);
//
// // find signature data
// unsigned_int signature_id = 0;
// fseek(fNDS, header.application_end_offset, SEEK_SET);
// fread(&signature_id, sizeof(signature_id), 1, fNDS);
// if (signature_id != 0x00016361)
// {
// fseek(fNDS, header.application_end_offset - 136, SEEK_SET); // try again
// fread(&signature_id, sizeof(signature_id), 1, fNDS);
// }
// if (signature_id == 0x00016361)
// {
// printf("\n");
//
// unsigned char signature[128];
// fread(signature, 1, sizeof(signature), fNDS);
//
// unsigned char sha_parts[3*SHA1_DIGEST_SIZE + 4];
// fread(sha_parts + 3*SHA1_DIGEST_SIZE, 4, 1, fNDS); // some number
//
// //printf("%08X\n", *(unsigned int *)(sha_parts + 3*SHA1_DIGEST_SIZE));
//
// unsigned char header_sha1[SHA1_DIGEST_SIZE];
// HeaderSha1(fNDS, header_sha1, romType);
// memcpy(sha_parts + 0*SHA1_DIGEST_SIZE, header_sha1, SHA1_DIGEST_SIZE);
//
// unsigned char arm9_sha1[SHA1_DIGEST_SIZE];
// if (romType == ROMTYPE_MULTIBOOT)
// {
// Arm9Sha1Multiboot(fNDS, arm9_sha1);
// }
// else
// {
// Arm9Sha1ClearedOutArea(fNDS, arm9_sha1);
// }
// memcpy(sha_parts + 1*SHA1_DIGEST_SIZE, arm9_sha1, SHA1_DIGEST_SIZE);
//
// memcpy(sha_parts + 2*SHA1_DIGEST_SIZE, arm7_sha1, SHA1_DIGEST_SIZE);
//
// unsigned char sha_final[SHA1_DIGEST_SIZE];
// {
// sha1_ctx m_sha1;
// sha1_begin(&m_sha1);
// unsigned int len = sizeof(sha_parts);
// unsigned char *buf = sha_parts;
// sha1_hash(buf, len, &m_sha1);
// sha1_end(sha_final, &m_sha1);
// }
//
// // calculate SHA1 from signature
// unsigned char sha1_from_sig[SHA1_DIGEST_SIZE];
// {
// BigInt _signature;
// _signature.Set(signature, sizeof(signature));
// //printf("signature: "); _signature.print();
//
// BigInt _publicKey;
// _publicKey.Set(publicKeyNintendo, sizeof(publicKeyNintendo));
// //printf("public key: "); _publicKey.print();
//
// BigInt big_sha1;
// big_sha1.PowMod(_signature, _publicKey);
// //printf("big_sha1: "); big_sha1.print();
// big_sha1.Get(sha1_from_sig, sizeof(sha1_from_sig));
// }
//
// bool ok = (memcmp(sha_final, sha1_from_sig, SHA1_DIGEST_SIZE) == 0);
// printf("DS Download Play(TM) / Wireless MultiBoot signature: %s\n", ok ? "OK" : "INVALID");
// if (!ok)
// {
// printf("header hash: \t"); for (int i=0; i<SHA1_DIGEST_SIZE; i++) printf("%02X", (sha_parts + 0*SHA1_DIGEST_SIZE)[i]); printf("\n");
// printf("ARM9 hash: \t"); for (int i=0; i<SHA1_DIGEST_SIZE; i++) printf("%02X", (sha_parts + 1*SHA1_DIGEST_SIZE)[i]); printf("\n");
// printf("ARM7 hash: \t"); for (int i=0; i<SHA1_DIGEST_SIZE; i++) printf("%02X", (sha_parts + 2*SHA1_DIGEST_SIZE)[i]); printf("\n");
// printf("combined hash: \t"); for (int i=0; i<SHA1_DIGEST_SIZE; i++) printf("%02X", sha_final[i]); printf("\n");
// printf("signature hash: \t"); for (int i=0; i<SHA1_DIGEST_SIZE; i++) printf("%02X", sha1_from_sig[i]); printf("\n");
// }
// }
//
// // CRC32
// {
// unsigned char *buf = new unsigned char [0x10000];
// fseek(fNDS, 0, SEEK_SET);
// unsigned long crc32 = ~0;
// int r;
// while ((r = fread(buf, 1, 0x10000, fNDS)) > 0)
// {
// crc32 = CalcCrc32(buf, r, crc32);
// }
// crc32 = ~crc32;
// delete [] buf;
//
// printf("\nFile CRC32: \t%08X\n", (unsigned int)crc32);
// RomListInfo(crc32);
// }
//
// // ROM dumper 1.0 bad data
// {
// unsigned char buf[0x200];
// fseek(fNDS, 0x7E00, SEEK_SET);
// fread(buf, 1, 0x200, fNDS);
// unsigned long crc32 = ~CalcCrc32(buf, 0x200);
// printf("\nSMT dumper v1.0 corruption check: \t%s\n", (crc32 == 0x7E8B456F) ? "CORRUPTED" : "OK");
// }
//
// // Verify ARM7 SHA1 hash against known default binaries
// int bKnownArm7 = 0;
// {
// printf("\nARM7 binary hash : \t"); for (int i=0; i<SHA1_DIGEST_SIZE; i++) printf("%02X", arm7_sha1[i]); printf("\n");
//
// if (CompareSha1WithList(arm7_sha1, arm7_sha1_homebrew, arm7_sha1_homebrew_size) == 0)
// {
// bKnownArm7 = 1; printf("ARM7 binary is homebrew verified.\n");
// }
// if (CompareSha1WithList(arm7_sha1, arm7_sha1_nintendo, arm7_sha1_nintendo_size) == 0)
// {
// bKnownArm7 = 2; printf("ARM7 binary is Nintendo verified.\n");
// }
// if (!bKnownArm7) printf("WARNING! ARM7 binary is NOT verified!\n");
// }
//
// // check ARM7 RAM address
// if (bKnownArm7 != 2)
// if ((header.arm7_ram_address < 0x03000000) || (header.arm7_ram_address >= 0x04000000))
// {
// printf("\nWARNING! ARM7 RAM address does not point to shared memory!\n");
// }
//
// // check ARM7 entry address
// if ((header.arm7_entry_address < header.arm7_ram_address) ||
// (header.arm7_entry_address > header.arm7_ram_address + header.arm7_size))
// {
// printf("\nWARNING! ARM7 entry address points outside of ARM7 binary!\n");
// }
//}
//
///*
// * ShowInfo
// */
//void ShowInfo(char *ndsfilename)
//{
// fNDS = fopen(ndsfilename, "rb");
// if (!fNDS) { fprintf(stderr, "Cannot open file '%s'.\n", ndsfilename); exit(1); }
// fread(&header, 512, 1, fNDS);
//
// int romType = DetectRomType();
//
// printf("Header information:\n");
// ShowHeaderInfo(header, romType);
//
// // banner info
// if (header.banner_offset)
// {
// Banner banner;
// fseek(fNDS, header.banner_offset, SEEK_SET);
// if (fread(&banner, 1, sizeof(banner), fNDS))
// {
// unsigned short banner_crc = CalcBannerCRC(banner);
// printf("\n");
// printf("Banner CRC: \t0x%04X (%s)\n", (int)banner.crc, (banner_crc == banner.crc) ? "OK" : "INVALID");
//
// for (int language=1; language<=1; language++)
// {
// int line = 1;
// bool nextline = true;
// for (int i=0; i<128; i++)
// {
// unsigned short c = banner.title[language][i];
// if (c >= 128) c = '_';
// if (c == 0x00) { printf("\n"); break; }
// if (c == 0x0A)
// {
// nextline = true;
// }
// else
// {
// if (nextline)
// {
// if (line != 1) printf("\n");
// printf("%s banner text, line %d:", bannerLanguages[language], line);
// for (unsigned int i=0; i<11 - strlen(bannerLanguages[language]); i++) putchar(' ');
// printf("\t");
// nextline = false;
// line++;
// }
// putchar(c);
// }
// }
// }
// }
// }
//
// // ARM9 footer
// fseek(fNDS, header.arm9_rom_offset + header.arm9_size, SEEK_SET);
// unsigned_int nitrocode;
// if (fread(&nitrocode, sizeof(nitrocode), 1, fNDS) && (nitrocode == 0xDEC00621))
// {
// printf("\n");
// printf("ARM9 footer found.\n");
// unsigned_int x;
// fread(&x, sizeof(x), 1, fNDS);
// fread(&x, sizeof(x), 1, fNDS);
// }
//
// // show security CRCs
// if (romType >= ROMTYPE_NDSDUMPED)
// {
// printf("\n");
// unsigned short securitydata_crc = CalcSecurityDataCRC();
// printf("Security data CRC (0x1000-0x2FFF) 0x%04X\n", (int)securitydata_crc);
// unsigned short segment3_crc = CalcSegment3CRC();
// printf("Segment3 CRC (0x3000-0x3FFF) 0x%04X (%s)\n", (int)segment3_crc, (segment3_crc == 0x0254) ? "OK" : "INVALID");
// }
//
// // more information
// if (verbose >= 1)
// {
// ShowVerboseInfo(fNDS, header, romType);
// }
//
// fclose(fNDS);
//}

View File

@ -0,0 +1,113 @@
//taken from ndstool
//http://devkitpro.cvs.sourceforge.net/viewvc/devkitpro/tools/nds/ndstool/include/header.h?revision=1.14
#ifndef _HEADER_H_
#define _HEADER_H_
#include "types.h"
#include "PACKED.H"
struct __PACKED Header
{
char title[0xC];
char gamecode[0x4];
char makercode[2];
unsigned char unitcode; // product code. 0 = Nintendo DS
unsigned char devicetype; // device code. 0 = normal
unsigned char devicecap; // device size. (1<<n Mbit)
unsigned char reserved1[0x9]; // 0x015..0x01D
unsigned char romversion;
unsigned char reserved2; // 0x01F
u32 arm9_rom_offset; // points to libsyscall and rest of ARM9 binary
u32 arm9_entry_address;
u32 arm9_ram_address;
u32 arm9_size;
u32 arm7_rom_offset;
u32 arm7_entry_address;
u32 arm7_ram_address;
u32 arm7_size;
u32 fnt_offset;
u32 fnt_size;
u32 fat_offset;
u32 fat_size;
u32 arm9_overlay_offset;
u32 arm9_overlay_size;
u32 arm7_overlay_offset;
u32 arm7_overlay_size;
u32 rom_control_info1; // 0x00416657 for OneTimePROM
u32 rom_control_info2; // 0x081808F8 for OneTimePROM
u32 banner_offset;
u16 secure_area_crc;
u16 rom_control_info3; // 0x0D7E for OneTimePROM
u32 offset_0x70; // magic1 (64 bit encrypted magic code to disable LFSR)
u32 offset_0x74; // magic2
u32 offset_0x78; // unique ID for homebrew
u32 offset_0x7C; // unique ID for homebrew
u32 application_end_offset; // rom size
u32 rom_header_size;
u32 offset_0x88; // reserved... ?
u32 offset_0x8C;
// reserved
u32 offset_0x90;
u32 offset_0x94;
u32 offset_0x98;
u32 offset_0x9C;
u32 offset_0xA0;
u32 offset_0xA4;
u32 offset_0xA8;
u32 offset_0xAC;
u32 offset_0xB0;
u32 offset_0xB4;
u32 offset_0xB8;
u32 offset_0xBC;
unsigned char logo[156]; // character data
u16 logo_crc;
u16 header_crc;
// 0x160..0x17F reserved
u32 offset_0x160;
u32 offset_0x164;
u32 offset_0x168;
u32 offset_0x16C;
unsigned char zero[0x90];
};
#include "PACKED_END.H"
struct Country
{
const char countrycode;
const char *name;
};
struct Maker
{
const char *makercode;
const char *name;
};
extern Country countries[];
extern int NumCountries;
extern Maker makers[];
extern int NumMakers;
unsigned short CalcHeaderCRC(Header &header);
unsigned short CalcLogoCRC(Header &header);
void FixHeaderCRC(char *ndsfilename);
void ShowInfo(char *ndsfilename);
int HashAndCompareWithList(char *filename, unsigned char sha1[]);
int DetectRomType(const Header& header, char* romdata);
unsigned short CalcSecureAreaCRC(bool encrypt);
#define ROMTYPE_HOMEBREW 0
#define ROMTYPE_MULTIBOOT 1
#define ROMTYPE_NDSDUMPED 2 // decrypted secure area
#define ROMTYPE_ENCRSECURE 3
#define ROMTYPE_MASKROM 4 // unknown layout
#endif

View File

@ -680,6 +680,10 @@
RelativePath=".\mapView.h"
>
</File>
<File
RelativePath=".\matrixView.cpp"
>
</File>
<File
RelativePath=".\matrixView.h"
>
@ -784,6 +788,61 @@
RelativePath="..\utils\xstring.h"
>
</File>
<Filter
Name="decrypt"
>
<File
RelativePath="..\utils\decrypt\crc.cpp"
>
</File>
<File
RelativePath="..\utils\decrypt\crc.h"
>
</File>
<File
RelativePath="..\utils\decrypt\decrypt.cpp"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
ObjectFile="$(IntDir)\$(InputName)1.obj"
XMLDocumentationFileName="$(IntDir)\$(InputName)1.xdc"
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
ObjectFile="$(IntDir)\$(InputName)1.obj"
XMLDocumentationFileName="$(IntDir)\$(InputName)1.xdc"
/>
</FileConfiguration>
<FileConfiguration
Name="Release (SSE2)|Win32"
>
<Tool
Name="VCCLCompilerTool"
ObjectFile="$(IntDir)\$(InputName)1.obj"
XMLDocumentationFileName="$(IntDir)\$(InputName)1.xdc"
/>
</FileConfiguration>
</File>
<File
RelativePath="..\utils\decrypt\decrypt.h"
>
</File>
<File
RelativePath="..\utils\decrypt\header.cpp"
>
</File>
<File
RelativePath="..\utils\decrypt\header.h"
>
</File>
</Filter>
</Filter>
<File
RelativePath="..\ARM9.h"
@ -1036,10 +1095,6 @@
/>
</FileConfiguration>
</File>
<File
RelativePath=".\matrixView.cpp"
>
</File>
<File
RelativePath="..\mc.cpp"
>
@ -1052,6 +1107,10 @@
RelativePath="..\mem.h"
>
</File>
<File
RelativePath="..\memorystream.h"
>
</File>
<File
RelativePath="..\MMU.cpp"
>

View File

@ -1,256 +1,256 @@
/* Copyright (C) 2007 Acid Burn
This file is part of DeSmuME
DeSmuME is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
DeSmuME is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with DeSmuME; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "matrixView.h"
#include <commctrl.h>
#include "debug.h"
#include "resource.h"
#include "gfx3d.h"
typedef struct
{
u32 autoup_secs;
bool autoup;
} matrixview_struct;
matrixview_struct *MatrixView = NULL;
void MatrixView_SetMatrix(HWND hwnd, const int* idcs, float* matrix)
{
int n;
char buffer[64];
for(n = 0; n < 16; n++)
{
sprintf(buffer, "%.4f", matrix[n]);
//sprintf(buffer, "%.8x", (int)(matrix[n]*4096));
SetWindowText(GetDlgItem(hwnd, idcs[n]), buffer);
}
}
void MatrixView_OnPaintPositionMatrix(HWND hwnd)
{
// IDC for each matrix coefficient
const int idcGroup[16] =
{
IDC_MATRIX_VIEWER_COORD_11_EDIT, IDC_MATRIX_VIEWER_COORD_12_EDIT, IDC_MATRIX_VIEWER_COORD_13_EDIT, IDC_MATRIX_VIEWER_COORD_14_EDIT,
IDC_MATRIX_VIEWER_COORD_21_EDIT, IDC_MATRIX_VIEWER_COORD_22_EDIT, IDC_MATRIX_VIEWER_COORD_23_EDIT, IDC_MATRIX_VIEWER_COORD_24_EDIT,
IDC_MATRIX_VIEWER_COORD_31_EDIT, IDC_MATRIX_VIEWER_COORD_32_EDIT, IDC_MATRIX_VIEWER_COORD_33_EDIT, IDC_MATRIX_VIEWER_COORD_34_EDIT,
IDC_MATRIX_VIEWER_COORD_41_EDIT, IDC_MATRIX_VIEWER_COORD_42_EDIT, IDC_MATRIX_VIEWER_COORD_43_EDIT, IDC_MATRIX_VIEWER_COORD_44_EDIT
};
float matrix[16];
HWND hStackCombo = GetDlgItem(hwnd, IDC_MATRIX_VIEWER_COORD_COMBO);
int stackIndex;
stackIndex = SendMessage(hStackCombo, CB_GETCURSEL, 0, 0) - 1;
gfx3d_glGetMatrix(1, stackIndex, matrix);
MatrixView_SetMatrix(hwnd, idcGroup, matrix);
}
//////////////////////////////////////////////////////////////////////////////
void MatrixView_OnPaintDirectionMatrix(HWND hwnd)
{
// IDC for each matrix coefficient
const int idcGroup[16] =
{
IDC_MATRIX_VIEWER_DIR_11_EDIT, IDC_MATRIX_VIEWER_DIR_12_EDIT, IDC_MATRIX_VIEWER_DIR_13_EDIT, IDC_MATRIX_VIEWER_DIR_14_EDIT,
IDC_MATRIX_VIEWER_DIR_21_EDIT, IDC_MATRIX_VIEWER_DIR_22_EDIT, IDC_MATRIX_VIEWER_DIR_23_EDIT, IDC_MATRIX_VIEWER_DIR_24_EDIT,
IDC_MATRIX_VIEWER_DIR_31_EDIT, IDC_MATRIX_VIEWER_DIR_32_EDIT, IDC_MATRIX_VIEWER_DIR_33_EDIT, IDC_MATRIX_VIEWER_DIR_34_EDIT,
IDC_MATRIX_VIEWER_DIR_41_EDIT, IDC_MATRIX_VIEWER_DIR_42_EDIT, IDC_MATRIX_VIEWER_DIR_43_EDIT, IDC_MATRIX_VIEWER_DIR_44_EDIT
};
float matrix[16];
HWND hStackCombo = GetDlgItem(hwnd, IDC_MATRIX_VIEWER_DIR_COMBO);
int stackIndex;
stackIndex = SendMessage(hStackCombo, CB_GETCURSEL, 0, 0) - 1;
gfx3d_glGetMatrix(2, stackIndex, matrix);
MatrixView_SetMatrix(hwnd, idcGroup, matrix);
}
//////////////////////////////////////////////////////////////////////////////
void MatrixView_OnPaintProjectionMatrix(HWND hwnd)
{
// IDC for each matrix coefficient
const int idcGroup[16] =
{
IDC_MATRIX_VIEWER_PROJ_11_EDIT, IDC_MATRIX_VIEWER_PROJ_12_EDIT, IDC_MATRIX_VIEWER_PROJ_13_EDIT, IDC_MATRIX_VIEWER_PROJ_14_EDIT,
IDC_MATRIX_VIEWER_PROJ_21_EDIT, IDC_MATRIX_VIEWER_PROJ_22_EDIT, IDC_MATRIX_VIEWER_PROJ_23_EDIT, IDC_MATRIX_VIEWER_PROJ_24_EDIT,
IDC_MATRIX_VIEWER_PROJ_31_EDIT, IDC_MATRIX_VIEWER_PROJ_32_EDIT, IDC_MATRIX_VIEWER_PROJ_33_EDIT, IDC_MATRIX_VIEWER_PROJ_34_EDIT,
IDC_MATRIX_VIEWER_PROJ_41_EDIT, IDC_MATRIX_VIEWER_PROJ_42_EDIT, IDC_MATRIX_VIEWER_PROJ_43_EDIT, IDC_MATRIX_VIEWER_PROJ_44_EDIT
};
float mat[16];
gfx3d_glGetMatrix(0, -1, mat);
MatrixView_SetMatrix(hwnd, idcGroup, mat);
}
//////////////////////////////////////////////////////////////////////////////
void MatrixView_OnPaintTextureMatrix(HWND hwnd)
{
// IDC for each matrix coefficient
const int idcGroup[16] =
{
IDC_MATRIX_VIEWER_TEX_11_EDIT, IDC_MATRIX_VIEWER_TEX_12_EDIT, IDC_MATRIX_VIEWER_TEX_13_EDIT, IDC_MATRIX_VIEWER_TEX_14_EDIT,
IDC_MATRIX_VIEWER_TEX_21_EDIT, IDC_MATRIX_VIEWER_TEX_22_EDIT, IDC_MATRIX_VIEWER_TEX_23_EDIT, IDC_MATRIX_VIEWER_TEX_24_EDIT,
IDC_MATRIX_VIEWER_TEX_31_EDIT, IDC_MATRIX_VIEWER_TEX_32_EDIT, IDC_MATRIX_VIEWER_TEX_33_EDIT, IDC_MATRIX_VIEWER_TEX_34_EDIT,
IDC_MATRIX_VIEWER_TEX_41_EDIT, IDC_MATRIX_VIEWER_TEX_42_EDIT, IDC_MATRIX_VIEWER_TEX_43_EDIT, IDC_MATRIX_VIEWER_TEX_44_EDIT
};
float mat[16];
gfx3d_glGetMatrix(3, -1, mat);
MatrixView_SetMatrix(hwnd, idcGroup, mat);
}
BOOL MatrixView_OnPaint( HWND hwnd, WPARAM wParam, LPARAM lParam)
{
HDC hdc;
PAINTSTRUCT ps;
hdc = BeginPaint(hwnd, &ps);
MatrixView_OnPaintProjectionMatrix(hwnd);
MatrixView_OnPaintPositionMatrix(hwnd);
MatrixView_OnPaintDirectionMatrix(hwnd);
MatrixView_OnPaintTextureMatrix(hwnd);
EndPaint(hwnd, &ps);
return TRUE;
}
BOOL CALLBACK ViewMatricesProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_INITDIALOG:
{
MatrixView = new matrixview_struct;
memset(MatrixView, 0, sizeof(matrixview_struct));
MatrixView->autoup_secs = 5;
SendMessage(GetDlgItem(hwnd, IDC_AUTO_UPDATE_SPIN),
UDM_SETRANGE, 0, MAKELONG(99, 1));
SendMessage(GetDlgItem(hwnd, IDC_AUTO_UPDATE_SPIN),
UDM_SETPOS32, 0, MatrixView->autoup_secs);
int n;
HWND hPosCombo = GetDlgItem(hwnd, IDC_MATRIX_VIEWER_COORD_COMBO);
HWND hDirCombo = GetDlgItem(hwnd, IDC_MATRIX_VIEWER_DIR_COMBO);
// Setup position and direction matrix comboboxes with stack indices
SendMessage(hPosCombo, CB_ADDSTRING, 0,(LPARAM)"Current");
SendMessage(hDirCombo, CB_ADDSTRING, 0,(LPARAM)"Current");
for(n = 0; n < 32; n++)
{
char buffer[4];
sprintf(buffer, "%d", n);
SendMessage(hPosCombo, CB_ADDSTRING, 0,(LPARAM)buffer);
SendMessage(hDirCombo, CB_ADDSTRING, 0,(LPARAM)buffer);
}
SendMessage(hPosCombo, CB_SETCURSEL, 0, 0);
SendMessage(hDirCombo, CB_SETCURSEL, 0, 0);
return 1;
}
case WM_CLOSE:
{
if(MatrixView->autoup)
{
KillTimer(hwnd, IDT_VIEW_MATRIX);
MatrixView->autoup = false;
/* Copyright (C) 2007 Acid Burn
This file is part of DeSmuME
DeSmuME is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
DeSmuME is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with DeSmuME; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "matrixView.h"
#include <commctrl.h>
#include "debug.h"
#include "resource.h"
#include "gfx3d.h"
typedef struct
{
u32 autoup_secs;
bool autoup;
} matrixview_struct;
matrixview_struct *MatrixView = NULL;
void MatrixView_SetMatrix(HWND hwnd, const int* idcs, float* matrix)
{
int n;
char buffer[64];
for(n = 0; n < 16; n++)
{
sprintf(buffer, "%.4f", matrix[n]);
//sprintf(buffer, "%.8x", (int)(matrix[n]*4096));
SetWindowText(GetDlgItem(hwnd, idcs[n]), buffer);
}
}
void MatrixView_OnPaintPositionMatrix(HWND hwnd)
{
// IDC for each matrix coefficient
const int idcGroup[16] =
{
IDC_MATRIX_VIEWER_COORD_11_EDIT, IDC_MATRIX_VIEWER_COORD_12_EDIT, IDC_MATRIX_VIEWER_COORD_13_EDIT, IDC_MATRIX_VIEWER_COORD_14_EDIT,
IDC_MATRIX_VIEWER_COORD_21_EDIT, IDC_MATRIX_VIEWER_COORD_22_EDIT, IDC_MATRIX_VIEWER_COORD_23_EDIT, IDC_MATRIX_VIEWER_COORD_24_EDIT,
IDC_MATRIX_VIEWER_COORD_31_EDIT, IDC_MATRIX_VIEWER_COORD_32_EDIT, IDC_MATRIX_VIEWER_COORD_33_EDIT, IDC_MATRIX_VIEWER_COORD_34_EDIT,
IDC_MATRIX_VIEWER_COORD_41_EDIT, IDC_MATRIX_VIEWER_COORD_42_EDIT, IDC_MATRIX_VIEWER_COORD_43_EDIT, IDC_MATRIX_VIEWER_COORD_44_EDIT
};
float matrix[16];
HWND hStackCombo = GetDlgItem(hwnd, IDC_MATRIX_VIEWER_COORD_COMBO);
int stackIndex;
stackIndex = SendMessage(hStackCombo, CB_GETCURSEL, 0, 0) - 1;
gfx3d_glGetMatrix(1, stackIndex, matrix);
MatrixView_SetMatrix(hwnd, idcGroup, matrix);
}
//////////////////////////////////////////////////////////////////////////////
void MatrixView_OnPaintDirectionMatrix(HWND hwnd)
{
// IDC for each matrix coefficient
const int idcGroup[16] =
{
IDC_MATRIX_VIEWER_DIR_11_EDIT, IDC_MATRIX_VIEWER_DIR_12_EDIT, IDC_MATRIX_VIEWER_DIR_13_EDIT, IDC_MATRIX_VIEWER_DIR_14_EDIT,
IDC_MATRIX_VIEWER_DIR_21_EDIT, IDC_MATRIX_VIEWER_DIR_22_EDIT, IDC_MATRIX_VIEWER_DIR_23_EDIT, IDC_MATRIX_VIEWER_DIR_24_EDIT,
IDC_MATRIX_VIEWER_DIR_31_EDIT, IDC_MATRIX_VIEWER_DIR_32_EDIT, IDC_MATRIX_VIEWER_DIR_33_EDIT, IDC_MATRIX_VIEWER_DIR_34_EDIT,
IDC_MATRIX_VIEWER_DIR_41_EDIT, IDC_MATRIX_VIEWER_DIR_42_EDIT, IDC_MATRIX_VIEWER_DIR_43_EDIT, IDC_MATRIX_VIEWER_DIR_44_EDIT
};
float matrix[16];
HWND hStackCombo = GetDlgItem(hwnd, IDC_MATRIX_VIEWER_DIR_COMBO);
int stackIndex;
stackIndex = SendMessage(hStackCombo, CB_GETCURSEL, 0, 0) - 1;
gfx3d_glGetMatrix(2, stackIndex, matrix);
MatrixView_SetMatrix(hwnd, idcGroup, matrix);
}
//////////////////////////////////////////////////////////////////////////////
void MatrixView_OnPaintProjectionMatrix(HWND hwnd)
{
// IDC for each matrix coefficient
const int idcGroup[16] =
{
IDC_MATRIX_VIEWER_PROJ_11_EDIT, IDC_MATRIX_VIEWER_PROJ_12_EDIT, IDC_MATRIX_VIEWER_PROJ_13_EDIT, IDC_MATRIX_VIEWER_PROJ_14_EDIT,
IDC_MATRIX_VIEWER_PROJ_21_EDIT, IDC_MATRIX_VIEWER_PROJ_22_EDIT, IDC_MATRIX_VIEWER_PROJ_23_EDIT, IDC_MATRIX_VIEWER_PROJ_24_EDIT,
IDC_MATRIX_VIEWER_PROJ_31_EDIT, IDC_MATRIX_VIEWER_PROJ_32_EDIT, IDC_MATRIX_VIEWER_PROJ_33_EDIT, IDC_MATRIX_VIEWER_PROJ_34_EDIT,
IDC_MATRIX_VIEWER_PROJ_41_EDIT, IDC_MATRIX_VIEWER_PROJ_42_EDIT, IDC_MATRIX_VIEWER_PROJ_43_EDIT, IDC_MATRIX_VIEWER_PROJ_44_EDIT
};
float mat[16];
gfx3d_glGetMatrix(0, -1, mat);
MatrixView_SetMatrix(hwnd, idcGroup, mat);
}
//////////////////////////////////////////////////////////////////////////////
void MatrixView_OnPaintTextureMatrix(HWND hwnd)
{
// IDC for each matrix coefficient
const int idcGroup[16] =
{
IDC_MATRIX_VIEWER_TEX_11_EDIT, IDC_MATRIX_VIEWER_TEX_12_EDIT, IDC_MATRIX_VIEWER_TEX_13_EDIT, IDC_MATRIX_VIEWER_TEX_14_EDIT,
IDC_MATRIX_VIEWER_TEX_21_EDIT, IDC_MATRIX_VIEWER_TEX_22_EDIT, IDC_MATRIX_VIEWER_TEX_23_EDIT, IDC_MATRIX_VIEWER_TEX_24_EDIT,
IDC_MATRIX_VIEWER_TEX_31_EDIT, IDC_MATRIX_VIEWER_TEX_32_EDIT, IDC_MATRIX_VIEWER_TEX_33_EDIT, IDC_MATRIX_VIEWER_TEX_34_EDIT,
IDC_MATRIX_VIEWER_TEX_41_EDIT, IDC_MATRIX_VIEWER_TEX_42_EDIT, IDC_MATRIX_VIEWER_TEX_43_EDIT, IDC_MATRIX_VIEWER_TEX_44_EDIT
};
float mat[16];
gfx3d_glGetMatrix(3, -1, mat);
MatrixView_SetMatrix(hwnd, idcGroup, mat);
}
BOOL MatrixView_OnPaint( HWND hwnd, WPARAM wParam, LPARAM lParam)
{
HDC hdc;
PAINTSTRUCT ps;
hdc = BeginPaint(hwnd, &ps);
MatrixView_OnPaintProjectionMatrix(hwnd);
MatrixView_OnPaintPositionMatrix(hwnd);
MatrixView_OnPaintDirectionMatrix(hwnd);
MatrixView_OnPaintTextureMatrix(hwnd);
EndPaint(hwnd, &ps);
return TRUE;
}
BOOL CALLBACK ViewMatricesProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_INITDIALOG:
{
MatrixView = new matrixview_struct;
memset(MatrixView, 0, sizeof(matrixview_struct));
MatrixView->autoup_secs = 5;
SendMessage(GetDlgItem(hwnd, IDC_AUTO_UPDATE_SPIN),
UDM_SETRANGE, 0, MAKELONG(99, 1));
SendMessage(GetDlgItem(hwnd, IDC_AUTO_UPDATE_SPIN),
UDM_SETPOS32, 0, MatrixView->autoup_secs);
int n;
HWND hPosCombo = GetDlgItem(hwnd, IDC_MATRIX_VIEWER_COORD_COMBO);
HWND hDirCombo = GetDlgItem(hwnd, IDC_MATRIX_VIEWER_DIR_COMBO);
// Setup position and direction matrix comboboxes with stack indices
SendMessage(hPosCombo, CB_ADDSTRING, 0,(LPARAM)"Current");
SendMessage(hDirCombo, CB_ADDSTRING, 0,(LPARAM)"Current");
for(n = 0; n < 32; n++)
{
char buffer[4];
sprintf(buffer, "%d", n);
SendMessage(hPosCombo, CB_ADDSTRING, 0,(LPARAM)buffer);
SendMessage(hDirCombo, CB_ADDSTRING, 0,(LPARAM)buffer);
}
SendMessage(hPosCombo, CB_SETCURSEL, 0, 0);
SendMessage(hDirCombo, CB_SETCURSEL, 0, 0);
return 1;
}
case WM_CLOSE:
{
if(MatrixView->autoup)
{
KillTimer(hwnd, IDT_VIEW_MATRIX);
MatrixView->autoup = false;
}
if (MatrixView!=NULL)
{
delete MatrixView;
MatrixView = NULL;
}
}
//INFO("Close Matrix view dialog\n");
PostQuitMessage(0);
return 0;
}
case WM_PAINT:
MatrixView_OnPaint(hwnd, wParam, lParam);
return 1;
case WM_TIMER:
SendMessage(hwnd, WM_COMMAND, IDC_REFRESH, 0);
return 1;
case WM_COMMAND:
switch (LOWORD (wParam))
{
case IDOK:
SendMessage(hwnd, WM_CLOSE, 0, 0);
return 1;
case IDC_AUTO_UPDATE :
if(MatrixView->autoup)
{
EnableWindow(GetDlgItem(hwnd, IDC_AUTO_UPDATE_SECS), false);
EnableWindow(GetDlgItem(hwnd, IDC_AUTO_UPDATE_SPIN), false);
KillTimer(hwnd, IDT_VIEW_MATRIX);
MatrixView->autoup = FALSE;
return 1;
}
EnableWindow(GetDlgItem(hwnd, IDC_AUTO_UPDATE_SECS), true);
EnableWindow(GetDlgItem(hwnd, IDC_AUTO_UPDATE_SPIN), true);
MatrixView->autoup = TRUE;
SetTimer(hwnd, IDT_VIEW_MATRIX, MatrixView->autoup_secs*1000, (TIMERPROC) NULL);
return 1;
case IDC_AUTO_UPDATE_SECS:
{
int t = GetDlgItemInt(hwnd, IDC_AUTO_UPDATE_SECS, FALSE, TRUE);
return 0;
}
case WM_PAINT:
MatrixView_OnPaint(hwnd, wParam, lParam);
return 1;
case WM_TIMER:
SendMessage(hwnd, WM_COMMAND, IDC_REFRESH, 0);
return 1;
case WM_COMMAND:
switch (LOWORD (wParam))
{
case IDOK:
SendMessage(hwnd, WM_CLOSE, 0, 0);
return 1;
case IDC_AUTO_UPDATE :
if(MatrixView->autoup)
{
EnableWindow(GetDlgItem(hwnd, IDC_AUTO_UPDATE_SECS), false);
EnableWindow(GetDlgItem(hwnd, IDC_AUTO_UPDATE_SPIN), false);
KillTimer(hwnd, IDT_VIEW_MATRIX);
MatrixView->autoup = FALSE;
return 1;
}
EnableWindow(GetDlgItem(hwnd, IDC_AUTO_UPDATE_SECS), true);
EnableWindow(GetDlgItem(hwnd, IDC_AUTO_UPDATE_SPIN), true);
MatrixView->autoup = TRUE;
SetTimer(hwnd, IDT_VIEW_MATRIX, MatrixView->autoup_secs*1000, (TIMERPROC) NULL);
return 1;
case IDC_AUTO_UPDATE_SECS:
{
int t = GetDlgItemInt(hwnd, IDC_AUTO_UPDATE_SECS, FALSE, TRUE);
if (!MatrixView)
{
SendMessage(hwnd, WM_INITDIALOG, 0, 0);
}
if (t != MatrixView->autoup_secs)
{
MatrixView->autoup_secs = t;
if (MatrixView->autoup)
SetTimer(hwnd, IDT_VIEW_MATRIX,
MatrixView->autoup_secs*1000, (TIMERPROC) NULL);
}
}
return 1;
case IDC_REFRESH:
InvalidateRect(hwnd, NULL, FALSE);
return 1;
case IDC_MATRIX_VIEWER_DIR_COMBO:
case IDC_MATRIX_VIEWER_COORD_COMBO:
InvalidateRect(hwnd, NULL, FALSE);
return 1;
}
return 0;
}
return false;
}
}
if (t != MatrixView->autoup_secs)
{
MatrixView->autoup_secs = t;
if (MatrixView->autoup)
SetTimer(hwnd, IDT_VIEW_MATRIX,
MatrixView->autoup_secs*1000, (TIMERPROC) NULL);
}
}
return 1;
case IDC_REFRESH:
InvalidateRect(hwnd, NULL, FALSE);
return 1;
case IDC_MATRIX_VIEWER_DIR_COMBO:
case IDC_MATRIX_VIEWER_COORD_COMBO:
InvalidateRect(hwnd, NULL, FALSE);
return 1;
}
return 0;
}
return false;
}