mirror of
https://github.com/dborth/vbagx.git
synced 2025-02-22 05:07:10 +01:00
[What's New 1.0.0 - September 16, 2008]
* Now compiles with devkitpro r15 * One makefile to make all versions * Complete rewrite based on code from SNES9x GX * Now has a menu! ROM selector, preferences, controller mapping, etc * Wiimote, Nunchuk, and Classic controller support * Button mapping for all controller types * Full support for SD and USB * Load/save preference selector. ROMs, saves, and preferences are saved/loaded according to these * 'Auto' settings for save/load - attempts to automatically determine your load/save device(s) - SD, USB * Preferences are loaded and saved in XML format. You can open VBAGX.xml edit all settings, including some not available within the program
This commit is contained in:
parent
2f2a1fd518
commit
ae514696d4
19
Makefile.gc
19
Makefile.gc
@ -15,23 +15,22 @@ include $(DEVKITPPC)/gamecube_rules
|
|||||||
# SOURCES is a list of directories containing source code
|
# SOURCES is a list of directories containing source code
|
||||||
# INCLUDES is a list of directories containing extra header files
|
# INCLUDES is a list of directories containing extra header files
|
||||||
#---------------------------------------------------------------------------------
|
#---------------------------------------------------------------------------------
|
||||||
TARGET := vbagx_gc
|
TARGET := vba172_gc
|
||||||
TARGETDIR := executables
|
TARGETDIR := executables
|
||||||
BUILD := build_gc
|
BUILD := build_gc
|
||||||
SOURCES := source/vba source/vba/agb source/vba/dmg source/ngc source/sz
|
SOURCES := source/vba source/vba/gb source/ngc
|
||||||
INCLUDES := source/vba source/ngc
|
INCLUDES := source/vba source/vba/gb source/ngc
|
||||||
|
|
||||||
#---------------------------------------------------------------------------------
|
#---------------------------------------------------------------------------------
|
||||||
# options for code generation
|
# options for code generation
|
||||||
#---------------------------------------------------------------------------------
|
#---------------------------------------------------------------------------------
|
||||||
|
|
||||||
CFLAGS = -g -O3 -Wall $(MACHDEP) $(INCLUDE) \
|
CFLAGS = -g -Os -Wall $(MACHDEP) $(INCLUDE) \
|
||||||
-DNGC -DUSE_VM -DWORDS_BIGENDIAN \
|
-DNGC -DWORDS_BIGENDIAN -DPACKAGE=\"VisualBoyAdvance\" \
|
||||||
-DC_CORE -D__ppc__ -D__POWERPC__ -DFINAL_VERSION \
|
-DVERSION=\"1.7.2\" -DC_CORE \
|
||||||
-DSDL -DNO_PNG -DHAVE_ZUTIL_H \
|
-DCHANFFS -DSDL -DNO_DEFLATE
|
||||||
-D_SZ_ONE_DIRECTORY -D_LZMA_IN_CB -D_LZMA_OUT_READ
|
CXXFLAGS = -save-temps -Xassembler -aln=$@.lst $(CFLAGS)
|
||||||
CXXFLAGS = $(CFLAGS)
|
LDFLAGS = -g $(MACHDEP) -Wl,-Map,$(notdir $@).map -Wl,--cref
|
||||||
LDFLAGS = -g $(MACHDEP) -Wl,-Map,$(notdir $@).map
|
|
||||||
|
|
||||||
#---------------------------------------------------------------------------------
|
#---------------------------------------------------------------------------------
|
||||||
# any extra libraries we wish to link with
|
# any extra libraries we wish to link with
|
||||||
|
17
Makefile.wii
17
Makefile.wii
@ -15,22 +15,21 @@ include $(DEVKITPPC)/wii_rules
|
|||||||
# SOURCES is a list of directories containing source code
|
# SOURCES is a list of directories containing source code
|
||||||
# INCLUDES is a list of directories containing extra header files
|
# INCLUDES is a list of directories containing extra header files
|
||||||
#---------------------------------------------------------------------------------
|
#---------------------------------------------------------------------------------
|
||||||
TARGET := vbagx_wii
|
TARGET := vba172_wii
|
||||||
TARGETDIR := executables
|
TARGETDIR := executables
|
||||||
BUILD := build_wii
|
BUILD := build_wii
|
||||||
SOURCES := source/vba source/vba/agb source/vba/dmg source/ngc source/sz
|
SOURCES := source/vba source/vba/gb source/ngc
|
||||||
INCLUDES := source/vba source/ngc
|
INCLUDES := source/vba source/vba/gb source/ngc
|
||||||
|
|
||||||
#---------------------------------------------------------------------------------
|
#---------------------------------------------------------------------------------
|
||||||
# options for code generation
|
# options for code generation
|
||||||
#---------------------------------------------------------------------------------
|
#---------------------------------------------------------------------------------
|
||||||
|
|
||||||
CFLAGS = -g -O3 -Wall $(MACHDEP) $(INCLUDE) \
|
CFLAGS = -g -Os -Wall $(MACHDEP) $(INCLUDE) \
|
||||||
-DNGC -DWII_DVD -DWORDS_BIGENDIAN -DVIDEO_THREADING \
|
-DNGC -DWORDS_BIGENDIAN -DPACKAGE=\"VisualBoyAdvance\" \
|
||||||
-DC_CORE -D__ppc__ -D__POWERPC__ -DFINAL_VERSION \
|
-DVERSION=\"1.7.2\" -DC_CORE \
|
||||||
-DSDL -DNO_PNG -DHAVE_ZUTIL_H \
|
-DCHANFFS -DSDL -DNO_DEFLATE
|
||||||
-D_SZ_ONE_DIRECTORY -D_LZMA_IN_CB -D_LZMA_OUT_READ
|
CXXFLAGS = -save-temps -Xassembler -aln=$@.lst $(CFLAGS)
|
||||||
CXXFLAGS = $(CFLAGS)
|
|
||||||
LDFLAGS = -g $(MACHDEP) -Wl,-Map,$(notdir $@).map -Wl,--cref
|
LDFLAGS = -g $(MACHDEP) -Wl,-Map,$(notdir $@).map -Wl,--cref
|
||||||
|
|
||||||
#---------------------------------------------------------------------------------
|
#---------------------------------------------------------------------------------
|
||||||
|
40
readme.txt
40
readme.txt
@ -1,13 +1,14 @@
|
|||||||
¸,ø¤°`°¤ø,¸¸,ø¤°`°¤ø,¸,ø¤°`°¤ø,¸¸,ø¤°`°¤ø,¸,ø¤°`°¤ø,¸¸,ø¤°`°¤ø,¸,ø¤°`°¤ø,¸¸,ø¤
|
¸,ø¤°`°¤ø,¸¸,ø¤°`°¤ø,¸,ø¤°`°¤ø,¸¸,ø¤°`°¤ø,¸,ø¤°`°¤ø,¸¸,ø¤°`°¤ø,¸,ø¤°`°¤ø,¸¸,ø¤
|
||||||
|
|
||||||
- Visual Boy Advance GX -
|
- Visual Boy Advance GX -
|
||||||
Version 1.0.3
|
Version 1.0.0
|
||||||
http://code.google.com/p/vba-wii
|
|
||||||
(Under GPL License)
|
(Under GPL License)
|
||||||
|
|
||||||
¸,ø¤°`°¤ø,¸¸,ø¤°`°¤ø,¸,ø¤°`°¤ø,¸¸,ø¤°`°¤ø,¸,ø¤°`°¤ø,¸¸,ø¤°`°¤ø,¸,ø¤°`°¤ø,¸¸,ø¤
|
¸,ø¤°`°¤ø,¸¸,ø¤°`°¤ø,¸,ø¤°`°¤ø,¸¸,ø¤°`°¤ø,¸,ø¤°`°¤ø,¸¸,ø¤°`°¤ø,¸,ø¤°`°¤ø,¸¸,ø¤
|
||||||
|
|
||||||
Visual Boy Advance GX is a modified port of VBA-M / VBA 1.7.2.
|
-=[ Explanation ]=-
|
||||||
|
|
||||||
|
Visual Boy Advance GX is a port of Visual Boy Advance 1.7.2.
|
||||||
With it you can play GBA/Game Boy Color/Game Boy games on your Wii/GameCube.
|
With it you can play GBA/Game Boy Color/Game Boy games on your Wii/GameCube.
|
||||||
|
|
||||||
-=[ Features ]=-
|
-=[ Features ]=-
|
||||||
@ -15,42 +16,13 @@ With it you can play GBA/Game Boy Color/Game Boy games on your Wii/GameCube.
|
|||||||
* Wiimote, Nunchuk, Classic, and Gamecube controller support
|
* Wiimote, Nunchuk, Classic, and Gamecube controller support
|
||||||
* SRAM and State saving
|
* SRAM and State saving
|
||||||
* Custom controller configurations
|
* Custom controller configurations
|
||||||
* SD, USB, DVD, SMB, GC Memory Card, Zip, and 7z support
|
* SD and USB support
|
||||||
* GBA compatiblity based on VBA-M r750, GB compatibility based on VBA 1.7.2
|
|
||||||
* Turbo speed feature
|
|
||||||
|
|
||||||
×—–—–—–—– –—–—–—–—–—–—–—–—–—–— —–—–—–—–—–—–—–—-—–-–•¬
|
×—–—–—–—– –—–—–—–—–—–—–—–—–—–— —–—–—–—–—–—–—–—-—–-–•¬
|
||||||
|0O×øo· UPDATE HISTORY ·oø×O0|
|
|0O×øo· UPDATE HISTORY ·oø×O0|
|
||||||
`¨•¨¨¨¨¨ ¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨ ¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨ ¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨ ¨¨¨¨¨¨¨¨¨¨¨¨¨'
|
`¨•¨¨¨¨¨ ¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨ ¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨ ¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨ ¨¨¨¨¨¨¨¨¨¨¨¨¨'
|
||||||
|
|
||||||
[What's New 1.0.3 - October 15, 2008]
|
[What's New 1.0.0]
|
||||||
* New timing / frameskip algorithm - should (hopefully) work 100% better!
|
|
||||||
* Performance improvements - video threading, PPC core partly activated
|
|
||||||
* Video zooming option
|
|
||||||
* Unfiltered video option
|
|
||||||
* 7z support
|
|
||||||
* Loading progress bars added
|
|
||||||
|
|
||||||
[What's New 1.0.2 - October 6, 2008]
|
|
||||||
* New core! The core is now a custom combination of VBA-M and VBA 1.72
|
|
||||||
* Added DVD, SMB, ZIP, GameCube MC support
|
|
||||||
* Faster USB/SD speeds
|
|
||||||
* Screen alignment and flickering problems fixed
|
|
||||||
* 128K save support added
|
|
||||||
* Better emulation speeds. Should now be nearly full speed all the time
|
|
||||||
for most games.
|
|
||||||
* Turbo speed feature. Mapped to right C-stick (classic controller &
|
|
||||||
Gamecube controller), and A+B for wiimote
|
|
||||||
* Controller mapping preferences bug fixed. Your preferences will reset
|
|
||||||
automatically to correct any problems in your preferences file
|
|
||||||
* Many other tweaks behind the scenes
|
|
||||||
|
|
||||||
[What's New 1.0.1 - September 18, 2008]
|
|
||||||
* GBA games now run at full speed
|
|
||||||
* Menu improvements, with spiffy new background - thanks brakken!
|
|
||||||
* Fixed L/R buttons - they work now
|
|
||||||
|
|
||||||
[What's New 1.0.0 - September 16, 2008]
|
|
||||||
|
|
||||||
* Now compiles with devkitpro r15
|
* Now compiles with devkitpro r15
|
||||||
* One makefile to make all versions
|
* One makefile to make all versions
|
||||||
|
@ -13,7 +13,6 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <malloc.h>
|
|
||||||
|
|
||||||
#ifdef WII_DVD
|
#ifdef WII_DVD
|
||||||
extern "C" {
|
extern "C" {
|
||||||
@ -23,12 +22,14 @@ extern "C" {
|
|||||||
|
|
||||||
#include "menudraw.h"
|
#include "menudraw.h"
|
||||||
#include "gcunzip.h"
|
#include "gcunzip.h"
|
||||||
#include "filesel.h"
|
|
||||||
#include "vba.h"
|
|
||||||
|
|
||||||
u64 dvddir = 0; // offset of currently selected file or folder
|
extern int offset;
|
||||||
int dvddirlength = 0; // length of currently selected file or folder
|
extern int selection;
|
||||||
u64 dvdrootdir = 0; // offset of DVD root
|
extern FILEENTRIES filelist[MAXFILES];
|
||||||
|
extern int maxfiles;
|
||||||
|
u64 dvddir = 0;
|
||||||
|
u64 dvdrootdir = 0;
|
||||||
|
int dvddirlength = 0;
|
||||||
bool isWii = false;
|
bool isWii = false;
|
||||||
|
|
||||||
#ifdef HW_DOL
|
#ifdef HW_DOL
|
||||||
@ -36,192 +37,63 @@ bool isWii = false;
|
|||||||
volatile unsigned long *dvd = (volatile unsigned long *) 0xCC006000;
|
volatile unsigned long *dvd = (volatile unsigned long *) 0xCC006000;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/** Due to lack of memory, we'll use this little 2k keyhole for all DVD operations **/
|
||||||
|
unsigned char DVDreadbuffer[2048] ATTRIBUTE_ALIGN (32);
|
||||||
|
unsigned char dvdbuffer[2048];
|
||||||
|
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* dvd_read
|
* dvd_read
|
||||||
*
|
*
|
||||||
* Main DVD function, everything else uses this!
|
* The only DVD function we need - you gotta luv gc-linux self-boots!
|
||||||
* returns: 1 - ok ; 0 - error
|
* returns: 1 - ok ; 0 - error
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
#define ALIGN_FORWARD(x,align) ((typeof(x))((((uint32_t)(x)) + (align) - 1) & (~(align-1))))
|
|
||||||
#define ALIGN_BACKWARD(x,align) ((typeof(x))(((uint32_t)(x)) & (~(align-1))))
|
|
||||||
|
|
||||||
int
|
int
|
||||||
dvd_read (void *dst, unsigned int len, u64 offset)
|
dvd_read (void *dst, unsigned int len, u64 offset)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
unsigned char *buffer = (unsigned char *) (unsigned int) DVDreadbuffer;
|
||||||
|
|
||||||
if (len > 2048)
|
if (len > 2048)
|
||||||
return 0; /*** We only allow 2k reads **/
|
return 0; /*** We only allow 2k reads **/
|
||||||
|
|
||||||
|
DCInvalidateRange ((void *) buffer, len);
|
||||||
|
|
||||||
// don't read past the end of the DVD (1.5 GB for GC DVD, 4.7 GB for DVD)
|
// don't read past the end of the DVD (1.5 GB for GC DVD, 4.7 GB for DVD)
|
||||||
if((offset < 0x57057C00) || (isWii && (offset < 0x118244F00LL)))
|
if(offset < 0x57057C00 || (isWii && offset < 0x118244F00LL))
|
||||||
{
|
{
|
||||||
u8 * buffer = (u8 *)memalign(32, 0x8000);
|
|
||||||
u32 off_size = 0;
|
|
||||||
|
|
||||||
DCInvalidateRange ((void *) buffer, len);
|
#ifdef HW_DOL
|
||||||
|
|
||||||
#ifdef HW_DOL
|
dvd[0] = 0x2E;
|
||||||
dvd[0] = 0x2E;
|
dvd[1] = 0;
|
||||||
dvd[1] = 0;
|
dvd[2] = 0xA8000000;
|
||||||
dvd[2] = 0xA8000000;
|
dvd[3] = (u32)(offset >> 2);
|
||||||
dvd[3] = (u32)(offset >> 2);
|
dvd[4] = len;
|
||||||
dvd[4] = len;
|
dvd[5] = (u32) buffer;
|
||||||
dvd[5] = (u32) buffer;
|
dvd[6] = len;
|
||||||
dvd[6] = len;
|
dvd[7] = 3; /*** Enable reading with DMA ***/
|
||||||
dvd[7] = 3;
|
while (dvd[7] & 1);
|
||||||
|
memcpy (dst, buffer, len);
|
||||||
|
|
||||||
// Enable reading with DMA
|
if (dvd[0] & 0x4) /* Ensure it has completed */
|
||||||
while (dvd[7] & 1);
|
return 0;
|
||||||
|
|
||||||
// Ensure it has completed
|
|
||||||
if (dvd[0] & 0x4)
|
|
||||||
return 0;
|
|
||||||
#else
|
|
||||||
off_size = offset - ALIGN_BACKWARD(offset,0x800);
|
|
||||||
if (DI_ReadDVD(
|
|
||||||
buffer,
|
|
||||||
(ALIGN_FORWARD(offset + len,0x800) - ALIGN_BACKWARD(offset,0x800)) >> 11,
|
|
||||||
(u32)(ALIGN_BACKWARD(offset, 0x800) >> 11)
|
|
||||||
))
|
|
||||||
return 0;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
memcpy (dst, buffer+off_size, len);
|
|
||||||
free(buffer);
|
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
|
#elif WII_DVD
|
||||||
|
int ret = 1;
|
||||||
|
ret = DI_ReadDVD(dst, len >> 11, (u32)(offset >> 11));
|
||||||
|
if (ret==0)
|
||||||
|
return 1;
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
* dvd_buffered_read
|
|
||||||
*
|
|
||||||
* the GC's dvd drive only supports offsets and length which are a multiple
|
|
||||||
* of 32 bytes additionally the max length of a read is 2048 bytes
|
|
||||||
* this function removes these limitations
|
|
||||||
* additionally the 7zip SDK does often read data in 1 byte parts from the
|
|
||||||
* DVD even when it could read 32 bytes. the dvdsf_buffer has been added to
|
|
||||||
* avoid having to read the same sector over and over again
|
|
||||||
***************************************************************************/
|
|
||||||
|
|
||||||
#define DVD_LENGTH_MULTIPLY 32
|
|
||||||
#define DVD_OFFSET_MULTIPLY 32
|
|
||||||
#define DVD_MAX_READ_LENGTH 2048
|
|
||||||
#define DVD_SECTOR_SIZE 2048
|
|
||||||
|
|
||||||
unsigned char dvdsf_buffer[DVD_SECTOR_SIZE];
|
|
||||||
u64 dvdsf_last_offset = 0;
|
|
||||||
u64 dvdsf_last_length = 0;
|
|
||||||
|
|
||||||
int dvd_buffered_read(void *dst, u32 len, u64 offset)
|
|
||||||
{
|
|
||||||
int ret = 0;
|
|
||||||
|
|
||||||
// only read data if the data inside dvdsf_buffer cannot be used
|
|
||||||
if(offset != dvdsf_last_offset || len > dvdsf_last_length)
|
|
||||||
{
|
|
||||||
memset(&dvdsf_buffer, '\0', DVD_SECTOR_SIZE);
|
|
||||||
ret = dvd_read(&dvdsf_buffer, len, offset);
|
|
||||||
dvdsf_last_offset = offset;
|
|
||||||
dvdsf_last_length = len;
|
|
||||||
}
|
|
||||||
|
|
||||||
memcpy(dst, &dvdsf_buffer, len);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
int dvd_safe_read(void *dst_v, u32 len, u64 offset)
|
|
||||||
{
|
|
||||||
unsigned char buffer[DVD_SECTOR_SIZE]; // buffer for one dvd sector
|
|
||||||
|
|
||||||
// if read size and length are a multiply of DVD_(OFFSET,LENGTH)_MULTIPLY and length < DVD_MAX_READ_LENGTH
|
|
||||||
// we don't need to fix anything
|
|
||||||
if(len % DVD_LENGTH_MULTIPLY == 0 && offset % DVD_OFFSET_MULTIPLY == 0 && len <= DVD_MAX_READ_LENGTH)
|
|
||||||
{
|
|
||||||
int ret = dvd_buffered_read(buffer, len, offset);
|
|
||||||
memcpy(dst_v, &buffer, len);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// no errors yet -> ret = 0
|
|
||||||
// the return value of dvd_read will be OR'd with ret
|
|
||||||
// because dvd_read does return 1 on error and 0 on success and
|
|
||||||
// because 0 | 1 = 1 ret will also contain 1 if at least one error
|
|
||||||
// occured and 0 otherwise ;)
|
|
||||||
int ret = 0; // return value of dvd_read
|
|
||||||
|
|
||||||
// we might need to fix all 3 issues
|
|
||||||
unsigned char *dst = (unsigned char *)dst_v; // gcc will not allow to use var[num] on void* types
|
|
||||||
u64 bytesToRead; // the number of bytes we still need to read & copy to the output buffer
|
|
||||||
u64 currentOffset; // the current dvd offset
|
|
||||||
u64 bufferOffset; // the current buffer offset
|
|
||||||
u64 i, j, k; // temporary variables which might be used for different stuff
|
|
||||||
// unsigned char buffer[DVD_SECTOR_SIZE]; // buffer for one dvd sector
|
|
||||||
|
|
||||||
currentOffset = offset;
|
|
||||||
bytesToRead = len;
|
|
||||||
bufferOffset = 0;
|
|
||||||
|
|
||||||
// fix first issue (offset is not a multiply of 32)
|
|
||||||
if(offset % DVD_OFFSET_MULTIPLY)
|
|
||||||
{
|
|
||||||
// calculate offset of the prior 32 byte position
|
|
||||||
i = currentOffset - (currentOffset % DVD_OFFSET_MULTIPLY);
|
|
||||||
|
|
||||||
// calculate the offset from which the data of the dvd buffer will be copied
|
|
||||||
j = currentOffset % DVD_OFFSET_MULTIPLY;
|
|
||||||
|
|
||||||
// calculate the number of bytes needed to reach the next DVD_OFFSET_MULTIPLY byte mark
|
|
||||||
k = DVD_OFFSET_MULTIPLY - j;
|
|
||||||
|
|
||||||
// maybe we'll only need to copy a few bytes and we therefore don't even reach the next sector
|
|
||||||
if(k > len)
|
|
||||||
{
|
|
||||||
k = len;
|
|
||||||
}
|
|
||||||
|
|
||||||
// read 32 bytes from the last 32 byte position
|
|
||||||
ret |= dvd_buffered_read(buffer, DVD_OFFSET_MULTIPLY, i);
|
|
||||||
|
|
||||||
// copy the bytes to the output buffer and update currentOffset, bufferOffset and bytesToRead
|
|
||||||
memcpy(&dst[bufferOffset], &buffer[j], k);
|
|
||||||
currentOffset += k;
|
|
||||||
bufferOffset += k;
|
|
||||||
bytesToRead -= k;
|
|
||||||
}
|
|
||||||
|
|
||||||
// fix second issue (more than 2048 bytes are needed)
|
|
||||||
if(bytesToRead > DVD_MAX_READ_LENGTH)
|
|
||||||
{
|
|
||||||
// calculate the number of 2048 bytes sector needed to get all data
|
|
||||||
i = (bytesToRead - (bytesToRead % DVD_MAX_READ_LENGTH)) / DVD_MAX_READ_LENGTH;
|
|
||||||
|
|
||||||
// read data in 2048 byte sector
|
|
||||||
for(j = 0; j < i; j++)
|
|
||||||
{
|
|
||||||
ret |= dvd_buffered_read(buffer, DVD_MAX_READ_LENGTH, currentOffset); // read sector
|
|
||||||
memcpy(&dst[bufferOffset], buffer, DVD_MAX_READ_LENGTH); // copy to output buffer
|
|
||||||
|
|
||||||
// update currentOffset, bufferOffset and bytesToRead
|
|
||||||
currentOffset += DVD_MAX_READ_LENGTH;
|
|
||||||
bufferOffset += DVD_MAX_READ_LENGTH;
|
|
||||||
bytesToRead -= DVD_MAX_READ_LENGTH;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// fix third issue (length is not a multiply of 32)
|
|
||||||
if(bytesToRead)
|
|
||||||
{
|
|
||||||
ret |= dvd_buffered_read(buffer, DVD_MAX_READ_LENGTH, currentOffset); // read 32 byte from the dvd
|
|
||||||
memcpy(&dst[bufferOffset], buffer, bytesToRead); // copy bytes to output buffer
|
|
||||||
}
|
|
||||||
|
|
||||||
//free(tmp);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Minimal ISO Directory Definition **/
|
/** Minimal ISO Directory Definition **/
|
||||||
#define RECLEN 0 /* Record length */
|
#define RECLEN 0 /* Record length */
|
||||||
#define EXTENT 6 /* Extent */
|
#define EXTENT 6 /* Extent */
|
||||||
@ -245,7 +117,6 @@ getpvd ()
|
|||||||
{
|
{
|
||||||
int sector = 16;
|
int sector = 16;
|
||||||
u32 rootdir32;
|
u32 rootdir32;
|
||||||
unsigned char dvdbuffer[2048];
|
|
||||||
|
|
||||||
dvddir = dvddirlength = 0;
|
dvddir = dvddirlength = 0;
|
||||||
IsJoliet = -1;
|
IsJoliet = -1;
|
||||||
@ -330,7 +201,7 @@ bool TestDVD()
|
|||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
static int diroffset = 0;
|
static int diroffset = 0;
|
||||||
static int
|
static int
|
||||||
getentry (int entrycount, unsigned char dvdbuffer[])
|
getentry (int entrycount)
|
||||||
{
|
{
|
||||||
char fname[512]; /* Huge, but experience has determined this */
|
char fname[512]; /* Huge, but experience has determined this */
|
||||||
char *ptr;
|
char *ptr;
|
||||||
@ -450,7 +321,6 @@ ParseDVDdirectory ()
|
|||||||
u64 rdoffset;
|
u64 rdoffset;
|
||||||
int len = 0;
|
int len = 0;
|
||||||
int filecount = 0;
|
int filecount = 0;
|
||||||
unsigned char dvdbuffer[2048];
|
|
||||||
|
|
||||||
// initialize selection
|
// initialize selection
|
||||||
selection = offset = 0;
|
selection = offset = 0;
|
||||||
@ -470,7 +340,7 @@ ParseDVDdirectory ()
|
|||||||
|
|
||||||
diroffset = 0;
|
diroffset = 0;
|
||||||
|
|
||||||
while (getentry (filecount, dvdbuffer))
|
while (getentry (filecount))
|
||||||
{
|
{
|
||||||
if(strlen(filelist[filecount].filename) > 0 && filecount < MAXFILES)
|
if(strlen(filelist[filecount].filename) > 0 && filecount < MAXFILES)
|
||||||
filecount++;
|
filecount++;
|
||||||
@ -559,15 +429,15 @@ bool SwitchDVDFolder(char origdir[])
|
|||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* LoadDVDFile
|
* LoadDVDFile
|
||||||
* This function will load a file from DVD
|
* This function will load a file from DVD, in BIN, SMD or ZIP format.
|
||||||
* The values for offset and length are inherited from dvddir and
|
* The values for offset and length are inherited from dvddir and
|
||||||
* dvddirlength.
|
* dvddirlength.
|
||||||
*
|
*
|
||||||
* The buffer parameter should re-use the initial ROM buffer
|
* The buffer parameter should re-use the initial ROM buffer.
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
|
|
||||||
int
|
int
|
||||||
LoadDVDFile (unsigned char *buffer, int length)
|
LoadDVDFile (unsigned char *buffer)
|
||||||
{
|
{
|
||||||
int offset;
|
int offset;
|
||||||
int blocks;
|
int blocks;
|
||||||
@ -575,45 +445,34 @@ LoadDVDFile (unsigned char *buffer, int length)
|
|||||||
u64 discoffset;
|
u64 discoffset;
|
||||||
char readbuffer[2048];
|
char readbuffer[2048];
|
||||||
|
|
||||||
dvddir = filelist[selection].offset;
|
|
||||||
dvddirlength = filelist[selection].length;
|
|
||||||
|
|
||||||
// How many 2k blocks to read
|
// How many 2k blocks to read
|
||||||
blocks = dvddirlength / 2048;
|
blocks = dvddirlength / 2048;
|
||||||
offset = 0;
|
offset = 0;
|
||||||
discoffset = dvddir;
|
discoffset = dvddir;
|
||||||
|
ShowAction ((char*) "Loading...");
|
||||||
|
dvd_read (readbuffer, 2048, discoffset);
|
||||||
|
|
||||||
if(length > 0 && length <= 2048) // do a partial read (eg: to check file header)
|
if (!IsZipFile (readbuffer))
|
||||||
{
|
{
|
||||||
dvd_read (buffer, length, discoffset);
|
for (i = 0; i < blocks; i++)
|
||||||
|
{
|
||||||
|
dvd_read (readbuffer, 2048, discoffset);
|
||||||
|
memcpy (buffer + offset, readbuffer, 2048);
|
||||||
|
offset += 2048;
|
||||||
|
discoffset += 2048;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*** And final cleanup ***/
|
||||||
|
if (dvddirlength % 2048)
|
||||||
|
{
|
||||||
|
i = dvddirlength % 2048;
|
||||||
|
dvd_read (readbuffer, 2048, discoffset);
|
||||||
|
memcpy (buffer + offset, readbuffer, i);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else // load whole file
|
else
|
||||||
{
|
{
|
||||||
dvd_read (readbuffer, 2048, discoffset);
|
return UnZipFile (buffer, discoffset); // unzip from dvd
|
||||||
|
|
||||||
if (!IsZipFile (readbuffer))
|
|
||||||
{
|
|
||||||
for (i = 0; i < blocks; i++)
|
|
||||||
{
|
|
||||||
dvd_read (readbuffer, 2048, discoffset);
|
|
||||||
memcpy (buffer + offset, readbuffer, 2048);
|
|
||||||
offset += 2048;
|
|
||||||
discoffset += 2048;
|
|
||||||
ShowProgress ((char *)"Loading...", offset, length);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*** And final cleanup ***/
|
|
||||||
if (dvddirlength % 2048)
|
|
||||||
{
|
|
||||||
i = dvddirlength % 2048;
|
|
||||||
dvd_read (readbuffer, 2048, discoffset);
|
|
||||||
memcpy (buffer + offset, readbuffer, i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return UnZipBuffer (buffer, METHOD_DVD); // unzip from dvd
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return dvddirlength;
|
return dvddirlength;
|
||||||
}
|
}
|
||||||
|
@ -13,17 +13,10 @@
|
|||||||
|
|
||||||
int getpvd ();
|
int getpvd ();
|
||||||
int ParseDVDdirectory ();
|
int ParseDVDdirectory ();
|
||||||
int LoadDVDFile (unsigned char *buffer, int length);
|
int LoadDVDFile (unsigned char *buffer);
|
||||||
bool TestDVD();
|
bool TestDVD();
|
||||||
int dvd_read (void *dst, unsigned int len, u64 offset);
|
int dvd_read (void *dst, unsigned int len, u64 offset);
|
||||||
int dvd_safe_read (void *dst, unsigned int len, u64 offset);
|
|
||||||
bool SwitchDVDFolder(char dir[]);
|
bool SwitchDVDFolder(char dir[]);
|
||||||
void SetDVDDriveType();
|
void SetDVDDriveType();
|
||||||
#ifdef HW_DOL
|
|
||||||
void dvd_motor_off ();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
extern u64 dvddir;
|
|
||||||
extern int dvddirlength;
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -24,8 +24,14 @@
|
|||||||
#include "filesel.h"
|
#include "filesel.h"
|
||||||
#include "preferences.h"
|
#include "preferences.h"
|
||||||
|
|
||||||
// FAT file pointer - the only one we should ever use!
|
FILE * filehandle;
|
||||||
FILE * fatfile;
|
|
||||||
|
extern unsigned char savebuffer[];
|
||||||
|
extern char output[16384];
|
||||||
|
extern int offset;
|
||||||
|
extern int selection;
|
||||||
|
extern char currentdir[MAXPATHLEN];
|
||||||
|
extern FILEENTRIES filelist[MAXFILES];
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* fat_is_mounted
|
* fat_is_mounted
|
||||||
@ -61,17 +67,18 @@ bool ChangeFATInterface(int method, bool silent)
|
|||||||
{
|
{
|
||||||
devFound = true;
|
devFound = true;
|
||||||
fatSetDefaultInterface(PI_INTERNAL_SD);
|
fatSetDefaultInterface(PI_INTERNAL_SD);
|
||||||
fatEnableReadAhead (PI_INTERNAL_SD, 6, 64);
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (!devFound && FatIsMounted(PI_SDGECKO_A))
|
if (!devFound && FatIsMounted(PI_SDGECKO_A))
|
||||||
{
|
{
|
||||||
devFound = true;
|
devFound = true;
|
||||||
|
fatSetDefaultInterface(PI_SDGECKO_A);
|
||||||
}
|
}
|
||||||
if(!devFound && FatIsMounted(PI_SDGECKO_B))
|
if(!devFound && FatIsMounted(PI_SDGECKO_B))
|
||||||
{
|
{
|
||||||
devFound = true;
|
devFound = true;
|
||||||
|
fatSetDefaultInterface(PI_SDGECKO_B);
|
||||||
}
|
}
|
||||||
if(!devFound)
|
if(!devFound)
|
||||||
{
|
{
|
||||||
@ -86,7 +93,6 @@ bool ChangeFATInterface(int method, bool silent)
|
|||||||
{
|
{
|
||||||
devFound = true;
|
devFound = true;
|
||||||
fatSetDefaultInterface(PI_USBSTORAGE);
|
fatSetDefaultInterface(PI_USBSTORAGE);
|
||||||
fatEnableReadAhead (PI_USBSTORAGE, 6, 64);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -164,54 +170,44 @@ ParseFATdirectory(int method)
|
|||||||
* LoadFATFile
|
* LoadFATFile
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
int
|
int
|
||||||
LoadFATFile (char * rbuffer, int length)
|
LoadFATFile (char *filename, int length)
|
||||||
{
|
{
|
||||||
char zipbuffer[2048];
|
/*char zipbuffer[2048];
|
||||||
|
FILE *handle;
|
||||||
|
unsigned char *rbuffer;
|
||||||
|
u32 size;*/
|
||||||
char filepath[MAXPATHLEN];
|
char filepath[MAXPATHLEN];
|
||||||
u32 size;
|
|
||||||
|
|
||||||
/* Check filename length */
|
/* Check filename length */
|
||||||
if (!MakeROMPath(filepath, METHOD_SD))
|
if ((strlen(currentdir)+1+strlen(filelist[selection].filename)) < MAXPATHLEN)
|
||||||
|
sprintf(filepath, "%s/%s",currentdir,filelist[selection].filename);
|
||||||
|
else
|
||||||
{
|
{
|
||||||
WaitPrompt((char*) "Maximum filepath length reached!");
|
WaitPrompt((char*) "Maximum filepath length reached!");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
return loadVBAROM(filepath);
|
||||||
fatfile = fopen (filepath, "rb");
|
/*
|
||||||
if (fatfile > 0)
|
handle = fopen (filepath, "rb");
|
||||||
|
if (handle > 0)
|
||||||
{
|
{
|
||||||
if(length > 0 && length <= 2048) // do a partial read (eg: to check file header)
|
fread (zipbuffer, 1, 2048, handle);
|
||||||
|
|
||||||
|
if (IsZipFile (zipbuffer))
|
||||||
{
|
{
|
||||||
fread (rbuffer, 1, length, fatfile);
|
size = UnZipFile (rbuffer, handle); // unzip from FAT
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Just load the file up
|
||||||
|
fseek(handle, 0, SEEK_END);
|
||||||
|
length = ftell(handle); // get filesize
|
||||||
|
fseek(handle, 2048, SEEK_SET); // seek back to point where we left off
|
||||||
|
memcpy (rbuffer, zipbuffer, 2048); // copy what we already read
|
||||||
|
fread (rbuffer + 2048, 1, length - 2048, handle);
|
||||||
size = length;
|
size = length;
|
||||||
}
|
}
|
||||||
else // load whole file
|
fclose (handle);
|
||||||
{
|
|
||||||
fread (zipbuffer, 1, 2048, fatfile);
|
|
||||||
|
|
||||||
if (IsZipFile (zipbuffer))
|
|
||||||
{
|
|
||||||
size = UnZipBuffer ((unsigned char *)rbuffer, METHOD_SD); // unzip from FAT
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Just load the file up
|
|
||||||
fseek(fatfile, 0, SEEK_END);
|
|
||||||
size = ftell(fatfile); // get filesize
|
|
||||||
fseek(fatfile, 2048, SEEK_SET); // seek back to point where we left off
|
|
||||||
memcpy (rbuffer, zipbuffer, 2048); // copy what we already read
|
|
||||||
|
|
||||||
ShowProgress ((char *)"Loading...", 2048, size);
|
|
||||||
|
|
||||||
u32 offset = 2048;
|
|
||||||
while(offset < size)
|
|
||||||
{
|
|
||||||
offset += fread (rbuffer + offset, 1, (1024*512), fatfile); // read in 512K chunks
|
|
||||||
ShowProgress ((char *)"Loading...", offset, size);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fclose (fatfile);
|
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -219,29 +215,8 @@ LoadFATFile (char * rbuffer, int length)
|
|||||||
WaitPrompt((char*) "Error opening file");
|
WaitPrompt((char*) "Error opening file");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/****************************************************************************
|
return 0;*/
|
||||||
* LoadFATSzFile
|
|
||||||
* Loads the selected file # from the specified 7z into rbuffer
|
|
||||||
* Returns file size
|
|
||||||
***************************************************************************/
|
|
||||||
int
|
|
||||||
LoadFATSzFile(char * filepath, unsigned char * rbuffer)
|
|
||||||
{
|
|
||||||
u32 size;
|
|
||||||
fatfile = fopen (filepath, "rb");
|
|
||||||
if (fatfile > 0)
|
|
||||||
{
|
|
||||||
size = SzExtractFile(filelist[selection].offset, rbuffer);
|
|
||||||
fclose (fatfile);
|
|
||||||
return size;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
WaitPrompt((char*) "Error opening file");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
@ -250,11 +225,15 @@ LoadFATSzFile(char * filepath, unsigned char * rbuffer)
|
|||||||
int
|
int
|
||||||
LoadBufferFromFAT (char *filepath, bool silent)
|
LoadBufferFromFAT (char *filepath, bool silent)
|
||||||
{
|
{
|
||||||
int size = 0;
|
FILE *handle;
|
||||||
|
int boffset = 0;
|
||||||
|
int read = 0;
|
||||||
|
|
||||||
fatfile = fopen (filepath, "rb");
|
ClearSaveBuffer ();
|
||||||
|
|
||||||
if (fatfile <= 0)
|
handle = fopen (filepath, "rb");
|
||||||
|
|
||||||
|
if (handle <= 0)
|
||||||
{
|
{
|
||||||
if ( !silent )
|
if ( !silent )
|
||||||
{
|
{
|
||||||
@ -265,13 +244,15 @@ LoadBufferFromFAT (char *filepath, bool silent)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
fseek(fatfile, 0, SEEK_END); // go to end of file
|
/*** This is really nice, just load the file and decode it ***/
|
||||||
size = ftell(fatfile); // get filesize
|
while ((read = fread (savebuffer + boffset, 1, 1024, handle)) > 0)
|
||||||
fseek(fatfile, 0, SEEK_SET); // go to start of file
|
{
|
||||||
fread (savebuffer, 1, size, fatfile);
|
boffset += read;
|
||||||
fclose (fatfile);
|
}
|
||||||
|
|
||||||
return size;
|
fclose (handle);
|
||||||
|
|
||||||
|
return boffset;
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
@ -280,11 +261,13 @@ LoadBufferFromFAT (char *filepath, bool silent)
|
|||||||
int
|
int
|
||||||
SaveBufferToFAT (char *filepath, int datasize, bool silent)
|
SaveBufferToFAT (char *filepath, int datasize, bool silent)
|
||||||
{
|
{
|
||||||
if (datasize)
|
FILE *handle;
|
||||||
{
|
|
||||||
fatfile = fopen (filepath, "wb");
|
|
||||||
|
|
||||||
if (fatfile <= 0)
|
if (datasize)
|
||||||
|
{
|
||||||
|
handle = fopen (filepath, "wb");
|
||||||
|
|
||||||
|
if (handle <= 0)
|
||||||
{
|
{
|
||||||
char msg[100];
|
char msg[100];
|
||||||
sprintf(msg, "Couldn't save %s", filepath);
|
sprintf(msg, "Couldn't save %s", filepath);
|
||||||
@ -292,8 +275,10 @@ SaveBufferToFAT (char *filepath, int datasize, bool silent)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
fwrite (savebuffer, 1, datasize, fatfile);
|
fwrite (savebuffer, 1, datasize, handle);
|
||||||
fclose (fatfile);
|
fclose (handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ClearSaveBuffer ();
|
||||||
return datasize;
|
return datasize;
|
||||||
}
|
}
|
||||||
|
@ -23,12 +23,10 @@
|
|||||||
|
|
||||||
bool ChangeFATInterface(int method, bool silent);
|
bool ChangeFATInterface(int method, bool silent);
|
||||||
int ParseFATdirectory(int method);
|
int ParseFATdirectory(int method);
|
||||||
int LoadFATFile (char * fbuffer, int length);
|
int LoadFATFile (char *filename, int length);
|
||||||
int LoadFATSzFile(char * filepath, unsigned char * rbuffer);
|
|
||||||
int SaveBufferToFAT (char *filepath, int datasize, bool silent);
|
int SaveBufferToFAT (char *filepath, int datasize, bool silent);
|
||||||
int LoadBufferFromFAT (char *filepath, bool silent);
|
int LoadBufferFromFAT (char *filepath, bool silent);
|
||||||
|
|
||||||
extern char currFATdir[MAXPATHLEN];
|
extern char currFATdir[MAXPATHLEN];
|
||||||
extern FILE * fatfile;
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -14,7 +14,6 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <wiiuse/wpad.h>
|
#include <wiiuse/wpad.h>
|
||||||
#include <sys/dir.h>
|
#include <sys/dir.h>
|
||||||
#include <malloc.h>
|
|
||||||
|
|
||||||
#ifdef WII_DVD
|
#ifdef WII_DVD
|
||||||
extern "C" {
|
extern "C" {
|
||||||
@ -32,12 +31,10 @@ extern "C" {
|
|||||||
#include "input.h"
|
#include "input.h"
|
||||||
#include "dvd.h"
|
#include "dvd.h"
|
||||||
#include "smbop.h"
|
#include "smbop.h"
|
||||||
#include "gcunzip.h"
|
|
||||||
|
|
||||||
int offset;
|
int offset;
|
||||||
int selection;
|
int selection;
|
||||||
char currentdir[MAXPATHLEN];
|
char currentdir[MAXPATHLEN];
|
||||||
char szpath[MAXPATHLEN];
|
|
||||||
int maxfiles;
|
int maxfiles;
|
||||||
extern int screenheight;
|
extern int screenheight;
|
||||||
|
|
||||||
@ -49,38 +46,20 @@ int hasloaded = 0;
|
|||||||
|
|
||||||
// Global file entry table
|
// Global file entry table
|
||||||
FILEENTRIES filelist[MAXFILES];
|
FILEENTRIES filelist[MAXFILES];
|
||||||
bool inSz = false;
|
|
||||||
|
unsigned char savebuffer[SAVEBUFFERSIZE] ATTRIBUTE_ALIGN (32);
|
||||||
|
|
||||||
char ROMFilename[512];
|
char ROMFilename[512];
|
||||||
bool ROMLoaded = false;
|
int ROMSize = 0;
|
||||||
|
|
||||||
unsigned char *savebuffer = NULL;
|
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* AllocSaveBuffer ()
|
* ClearSaveBuffer ()
|
||||||
* Clear and allocate the savebuffer
|
* Clear the savebuffer
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
void
|
void
|
||||||
AllocSaveBuffer ()
|
ClearSaveBuffer ()
|
||||||
{
|
{
|
||||||
if (savebuffer != NULL)
|
memset (savebuffer, 0, SAVEBUFFERSIZE);
|
||||||
free(savebuffer);
|
|
||||||
|
|
||||||
savebuffer = (unsigned char *) memalign(32, SAVEBUFFERSIZE);
|
|
||||||
memset (savebuffer, 0, SAVEBUFFERSIZE);
|
|
||||||
}
|
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
* FreeSaveBuffer ()
|
|
||||||
* Free the savebuffer memory
|
|
||||||
***************************************************************************/
|
|
||||||
void
|
|
||||||
FreeSaveBuffer ()
|
|
||||||
{
|
|
||||||
if (savebuffer != NULL)
|
|
||||||
free(savebuffer);
|
|
||||||
|
|
||||||
savebuffer = NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
@ -192,28 +171,6 @@ int UpdateDirName(int method)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MakeROMPath(char filepath[], int method)
|
|
||||||
{
|
|
||||||
char temppath[MAXPATHLEN];
|
|
||||||
|
|
||||||
// Check filename length
|
|
||||||
if ((strlen(currentdir)+1+strlen(filelist[selection].filename)) < MAXPATHLEN)
|
|
||||||
{
|
|
||||||
sprintf(temppath, "%s/%s",currentdir,filelist[selection].filename);
|
|
||||||
|
|
||||||
if(method == METHOD_SMB)
|
|
||||||
strcpy(filepath, SMBPath(temppath));
|
|
||||||
else
|
|
||||||
strcpy(filepath, temppath);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
filepath[0] = 0;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* FileSortCallback
|
* FileSortCallback
|
||||||
*
|
*
|
||||||
@ -241,25 +198,6 @@ int FileSortCallback(const void *f1, const void *f2)
|
|||||||
return stricmp(((FILEENTRIES *)f1)->filename, ((FILEENTRIES *)f2)->filename);
|
return stricmp(((FILEENTRIES *)f1)->filename, ((FILEENTRIES *)f2)->filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
* IsSz
|
|
||||||
*
|
|
||||||
* Checks if the specified file is a 7z
|
|
||||||
***************************************************************************/
|
|
||||||
|
|
||||||
bool IsSz()
|
|
||||||
{
|
|
||||||
if (strlen(filelist[selection].filename) > 4)
|
|
||||||
{
|
|
||||||
char * p = strrchr(filelist[selection].filename, '.');
|
|
||||||
|
|
||||||
if (p != NULL)
|
|
||||||
if(stricmp(p, ".7z") == 0)
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* StripExt
|
* StripExt
|
||||||
*
|
*
|
||||||
@ -273,7 +211,7 @@ void StripExt(char* returnstring, char * inputstring)
|
|||||||
strcpy (returnstring, inputstring);
|
strcpy (returnstring, inputstring);
|
||||||
loc_dot = strrchr(returnstring,'.');
|
loc_dot = strrchr(returnstring,'.');
|
||||||
if (loc_dot != NULL)
|
if (loc_dot != NULL)
|
||||||
*loc_dot = 0; // strip file extension
|
*loc_dot = '\0'; // strip file extension
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
@ -315,8 +253,8 @@ int FileSelector (int method)
|
|||||||
p = PAD_ButtonsDown (0);
|
p = PAD_ButtonsDown (0);
|
||||||
ph = PAD_ButtonsHeld (0);
|
ph = PAD_ButtonsHeld (0);
|
||||||
#ifdef HW_RVL
|
#ifdef HW_RVL
|
||||||
wm_ay = WPAD_Stick (0, 0, 0);
|
wm_ay = WPAD_StickY (0, 0);
|
||||||
wm_sx = WPAD_Stick (0, 1, 1);
|
wm_sx = WPAD_StickX (0, 1);
|
||||||
|
|
||||||
wp = WPAD_ButtonsDown (0);
|
wp = WPAD_ButtonsDown (0);
|
||||||
wh = WPAD_ButtonsHeld (0);
|
wh = WPAD_ButtonsHeld (0);
|
||||||
@ -334,25 +272,7 @@ int FileSelector (int method)
|
|||||||
if (filelist[selection].flags) // This is directory
|
if (filelist[selection].flags) // This is directory
|
||||||
{
|
{
|
||||||
/* update current directory and set new entry list if directory has changed */
|
/* update current directory and set new entry list if directory has changed */
|
||||||
int status;
|
int status = UpdateDirName(method);
|
||||||
|
|
||||||
if(inSz && selection == 0) // inside a 7z, requesting to leave
|
|
||||||
{
|
|
||||||
if(method == METHOD_DVD)
|
|
||||||
{
|
|
||||||
// go to directory the 7z was in
|
|
||||||
dvddir = filelist[0].offset;
|
|
||||||
dvddirlength = filelist[0].length;
|
|
||||||
}
|
|
||||||
inSz = false;
|
|
||||||
status = 1;
|
|
||||||
SzClose();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
status = UpdateDirName(method);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (status == 1) // ok, open directory
|
if (status == 1) // ok, open directory
|
||||||
{
|
{
|
||||||
switch (method)
|
switch (method)
|
||||||
@ -384,42 +304,37 @@ int FileSelector (int method)
|
|||||||
}
|
}
|
||||||
else // this is a file
|
else // this is a file
|
||||||
{
|
{
|
||||||
// 7z file - let's open it up to select a file inside
|
// store the filename (w/o ext) - used for sram/freeze naming
|
||||||
if(IsSz())
|
StripExt(ROMFilename, filelist[selection].filename);
|
||||||
|
|
||||||
|
ShowAction ((char *)"Loading...");
|
||||||
|
|
||||||
|
switch (method)
|
||||||
{
|
{
|
||||||
// we'll store the 7z filepath for extraction later
|
case METHOD_SD:
|
||||||
if(!MakeROMPath(szpath, method))
|
case METHOD_USB:
|
||||||
{
|
ROMSize = LoadFATFile (filelist[selection].filename, filelist[selection].length);
|
||||||
WaitPrompt((char*) "Maximum filepath length reached!");
|
break;
|
||||||
return -1;
|
|
||||||
}
|
case METHOD_DVD:
|
||||||
int szfiles = SzParse(szpath, method);
|
dvddir = filelist[selection].offset;
|
||||||
if(szfiles)
|
dvddirlength = filelist[selection].length;
|
||||||
{
|
//ROMSize = LoadDVDFile (Memory.ROM);
|
||||||
maxfiles = szfiles;
|
break;
|
||||||
inSz = true;
|
|
||||||
}
|
case METHOD_SMB:
|
||||||
else
|
//ROMSize = LoadSMBFile (filelist[selection].filename, filelist[selection].length);
|
||||||
WaitPrompt((char*) "Error opening archive!");
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ROMSize > 0)
|
||||||
|
{
|
||||||
|
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// store the filename (w/o ext) - used for sram/freeze naming
|
WaitPrompt((char*) "Error loading ROM!");
|
||||||
StripExt(ROMFilename, filelist[selection].filename);
|
|
||||||
|
|
||||||
ShowAction ((char *)"Loading...");
|
|
||||||
|
|
||||||
ROMLoaded = LoadVBAROM(method);
|
|
||||||
inSz = false;
|
|
||||||
|
|
||||||
if (ROMLoaded)
|
|
||||||
{
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
WaitPrompt((char*) "Error loading ROM!");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
redraw = 1;
|
redraw = 1;
|
||||||
@ -613,7 +528,7 @@ OpenFAT (int method)
|
|||||||
{
|
{
|
||||||
if(ChangeFATInterface(method, NOTSILENT))
|
if(ChangeFATInterface(method, NOTSILENT))
|
||||||
{
|
{
|
||||||
// change current dir to vba roms directory
|
// change current dir to snes roms directory
|
||||||
sprintf ( currentdir, "%s/%s", ROOTFATDIR, GCSettings.LoadFolder );
|
sprintf ( currentdir, "%s/%s", ROOTFATDIR, GCSettings.LoadFolder );
|
||||||
|
|
||||||
// Parse initial root directory and get entries list
|
// Parse initial root directory and get entries list
|
||||||
|
@ -11,11 +11,9 @@
|
|||||||
#ifndef _NGCFILESEL_
|
#ifndef _NGCFILESEL_
|
||||||
#define _NGCFILESEL_
|
#define _NGCFILESEL_
|
||||||
|
|
||||||
#include <unistd.h>
|
#define SAVEBUFFERSIZE ((512 * 1024) + 2048 + 64 + 4 + 4)
|
||||||
|
|
||||||
#define SAVEBUFFERSIZE (512 * 1024)
|
|
||||||
#define MAXJOLIET 255
|
#define MAXJOLIET 255
|
||||||
#define MAXDISPLAY 40
|
#define MAXDISPLAY 54
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
@ -28,18 +26,9 @@ typedef struct
|
|||||||
|
|
||||||
#define MAXFILES 2000 // Restrict to 2000 files per dir
|
#define MAXFILES 2000 // Restrict to 2000 files per dir
|
||||||
extern FILEENTRIES filelist[MAXFILES];
|
extern FILEENTRIES filelist[MAXFILES];
|
||||||
extern unsigned char *savebuffer;
|
|
||||||
extern int offset;
|
|
||||||
extern int selection;
|
|
||||||
extern char currentdir[MAXPATHLEN];
|
|
||||||
extern char szpath[MAXPATHLEN];
|
|
||||||
extern bool inSz;
|
|
||||||
extern int maxfiles;
|
|
||||||
extern char ROMFilename[512];
|
extern char ROMFilename[512];
|
||||||
|
|
||||||
void AllocSaveBuffer();
|
void ClearSaveBuffer ();
|
||||||
void FreeSaveBuffer();
|
|
||||||
bool MakeROMPath(char filepath[], int method);
|
|
||||||
int OpenROM (int method);
|
int OpenROM (int method);
|
||||||
int autoLoadMethod();
|
int autoLoadMethod();
|
||||||
int autoSaveMethod();
|
int autoSaveMethod();
|
||||||
|
@ -14,19 +14,11 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <zlib.h>
|
#include <zlib.h>
|
||||||
|
|
||||||
extern "C" {
|
|
||||||
#include "../sz/7zCrc.h"
|
|
||||||
#include "../sz/7zIn.h"
|
|
||||||
#include "../sz/7zExtract.h"
|
|
||||||
}
|
|
||||||
|
|
||||||
#include "dvd.h"
|
#include "dvd.h"
|
||||||
#include "smbop.h"
|
#include "smbop.h"
|
||||||
#include "fileop.h"
|
|
||||||
#include "video.h"
|
#include "video.h"
|
||||||
#include "menudraw.h"
|
#include "menudraw.h"
|
||||||
#include "gcunzip.h"
|
#include "gcunzip.h"
|
||||||
#include "vba.h"
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* PKWare Zip Header - adopted into zip standard
|
* PKWare Zip Header - adopted into zip standard
|
||||||
@ -67,7 +59,7 @@ FLIP16 (u16 b)
|
|||||||
* IsZipFile
|
* IsZipFile
|
||||||
*
|
*
|
||||||
* Returns TRUE when PKZIPID is first four characters of buffer
|
* Returns TRUE when PKZIPID is first four characters of buffer
|
||||||
***************************************************************************/
|
****************************************************************************/
|
||||||
int
|
int
|
||||||
IsZipFile (char *buffer)
|
IsZipFile (char *buffer)
|
||||||
{
|
{
|
||||||
@ -81,14 +73,17 @@ IsZipFile (char *buffer)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
* UnZipBuffer
|
* unzip
|
||||||
*
|
*
|
||||||
* It should be noted that there is a limit of 5MB total size for any ROM
|
* It should be noted that there is a limit of 5MB total size for any ROM
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
FILE* fatfile; // FAT
|
||||||
|
u64 discoffset; // DVD
|
||||||
|
SMBFILE smbfile; // SMB
|
||||||
|
|
||||||
int
|
int
|
||||||
UnZipBuffer (unsigned char *outbuffer, int method)
|
UnZipBuffer (unsigned char *outbuffer, short where)
|
||||||
{
|
{
|
||||||
PKZIPHEADER pkzip;
|
PKZIPHEADER pkzip;
|
||||||
int zipoffset = 0;
|
int zipoffset = 0;
|
||||||
@ -100,25 +95,23 @@ UnZipBuffer (unsigned char *outbuffer, int method)
|
|||||||
int readoffset = 0;
|
int readoffset = 0;
|
||||||
int have = 0;
|
int have = 0;
|
||||||
char readbuffer[ZIPCHUNK];
|
char readbuffer[ZIPCHUNK];
|
||||||
u64 discoffset = 0;
|
char msg[128];
|
||||||
|
|
||||||
// Read Zip Header
|
/*** Read Zip Header ***/
|
||||||
switch (method)
|
switch (where)
|
||||||
{
|
{
|
||||||
case METHOD_SD:
|
case 0: // SD Card
|
||||||
case METHOD_USB:
|
fseek(fatfile, 0, SEEK_SET);
|
||||||
fseek(fatfile, 0, SEEK_SET);
|
fread (readbuffer, 1, ZIPCHUNK, fatfile);
|
||||||
fread (readbuffer, 1, ZIPCHUNK, fatfile);
|
break;
|
||||||
break;
|
|
||||||
|
|
||||||
case METHOD_DVD:
|
case 1: // DVD
|
||||||
discoffset = dvddir;
|
dvd_read (readbuffer, ZIPCHUNK, discoffset);
|
||||||
dvd_read (readbuffer, ZIPCHUNK, discoffset);
|
break;
|
||||||
break;
|
|
||||||
|
|
||||||
case METHOD_SMB:
|
case 2: // From SMB
|
||||||
SMB_ReadFile(readbuffer, ZIPCHUNK, 0, smbfile);
|
SMB_ReadFile(readbuffer, ZIPCHUNK, 0, smbfile);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*** Copy PKZip header to local, used as info ***/
|
/*** Copy PKZip header to local, used as info ***/
|
||||||
@ -126,7 +119,9 @@ UnZipBuffer (unsigned char *outbuffer, int method)
|
|||||||
|
|
||||||
pkzip.uncompressedSize = FLIP32 (pkzip.uncompressedSize);
|
pkzip.uncompressedSize = FLIP32 (pkzip.uncompressedSize);
|
||||||
|
|
||||||
ShowProgress ((char *)"Loading...", 0, pkzip.uncompressedSize);
|
sprintf (msg, "Unzipping %d bytes ... Wait",
|
||||||
|
pkzip.uncompressedSize);
|
||||||
|
ShowAction (msg);
|
||||||
|
|
||||||
/*** Prepare the zip stream ***/
|
/*** Prepare the zip stream ***/
|
||||||
memset (&zs, 0, sizeof (z_stream));
|
memset (&zs, 0, sizeof (z_stream));
|
||||||
@ -176,28 +171,26 @@ UnZipBuffer (unsigned char *outbuffer, int method)
|
|||||||
}
|
}
|
||||||
while (zs.avail_out == 0);
|
while (zs.avail_out == 0);
|
||||||
|
|
||||||
// Readup the next 2k block
|
/*** Readup the next 2k block ***/
|
||||||
zipoffset = 0;
|
zipoffset = 0;
|
||||||
zipchunk = ZIPCHUNK;
|
zipchunk = ZIPCHUNK;
|
||||||
|
|
||||||
switch (method)
|
switch (where)
|
||||||
{
|
{
|
||||||
case METHOD_SD:
|
case 0: // SD Card
|
||||||
case METHOD_USB:
|
fread (readbuffer, 1, ZIPCHUNK, fatfile);
|
||||||
fread (readbuffer, 1, ZIPCHUNK, fatfile);
|
break;
|
||||||
break;
|
|
||||||
|
|
||||||
case METHOD_DVD:
|
case 1: // DVD
|
||||||
readoffset += ZIPCHUNK;
|
readoffset += ZIPCHUNK;
|
||||||
dvd_safe_read (readbuffer, ZIPCHUNK, discoffset+readoffset);
|
dvd_read (readbuffer, ZIPCHUNK, discoffset+readoffset);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case METHOD_SMB:
|
case 2: // From SMB
|
||||||
readoffset += ZIPCHUNK;
|
readoffset += ZIPCHUNK;
|
||||||
SMB_ReadFile(readbuffer, ZIPCHUNK, readoffset, smbfile);
|
SMB_ReadFile(readbuffer, ZIPCHUNK, readoffset, smbfile);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
ShowProgress ((char *)"Loading...", bufferoffset, pkzip.uncompressedSize);
|
|
||||||
}
|
}
|
||||||
while (res != Z_STREAM_END);
|
while (res != Z_STREAM_END);
|
||||||
|
|
||||||
@ -213,344 +206,24 @@ UnZipBuffer (unsigned char *outbuffer, int method)
|
|||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
// Reading from FAT
|
||||||
/****************************************************************************
|
|
||||||
* GetFirstZipFilename
|
|
||||||
*
|
|
||||||
* Returns the filename of the first file in the zipped archive
|
|
||||||
* The idea here is to do the least amount of work required
|
|
||||||
***************************************************************************/
|
|
||||||
|
|
||||||
char *
|
|
||||||
GetFirstZipFilename (int method)
|
|
||||||
{
|
|
||||||
char * firstFilename = NULL;
|
|
||||||
char tempbuffer[ZIPCHUNK];
|
|
||||||
|
|
||||||
// read start of ZIP
|
|
||||||
switch (method)
|
|
||||||
{
|
|
||||||
case METHOD_SD: // SD Card
|
|
||||||
case METHOD_USB: // USB
|
|
||||||
LoadFATFile (tempbuffer, ZIPCHUNK);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case METHOD_DVD: // DVD
|
|
||||||
LoadDVDFile ((unsigned char *)tempbuffer, ZIPCHUNK);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case METHOD_SMB: // From SMB
|
|
||||||
LoadSMBFile (tempbuffer, ZIPCHUNK);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
tempbuffer[28] = 0; // truncate - filename length is 2 bytes long (bytes 26-27)
|
|
||||||
int namelength = tempbuffer[26]; // filename length starts 26 bytes in
|
|
||||||
|
|
||||||
firstFilename = &tempbuffer[30]; // first filename of a ZIP starts 31 bytes in
|
|
||||||
firstFilename[namelength] = 0; // truncate at filename length
|
|
||||||
|
|
||||||
return firstFilename;
|
|
||||||
}
|
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
* 7z functions
|
|
||||||
***************************************************************************/
|
|
||||||
|
|
||||||
typedef struct _SzFileInStream
|
|
||||||
{
|
|
||||||
ISzInStream InStream;
|
|
||||||
u64 offset; // offset of the file
|
|
||||||
unsigned int len; // length of the file
|
|
||||||
u64 pos; // current position of the file pointer
|
|
||||||
} SzFileInStream;
|
|
||||||
|
|
||||||
// 7zip error list
|
|
||||||
char szerrormsg[][30] = {
|
|
||||||
"7z: Data error",
|
|
||||||
"7z: Out of memory",
|
|
||||||
"7z: CRC Error",
|
|
||||||
"7z: Not implemented",
|
|
||||||
"7z: Fail",
|
|
||||||
"7z: Archive error",
|
|
||||||
"7z: Dictionary too large",
|
|
||||||
};
|
|
||||||
|
|
||||||
SZ_RESULT SzRes;
|
|
||||||
|
|
||||||
SzFileInStream SzArchiveStream;
|
|
||||||
CArchiveDatabaseEx SzDb;
|
|
||||||
ISzAlloc SzAllocImp;
|
|
||||||
ISzAlloc SzAllocTempImp;
|
|
||||||
UInt32 SzBlockIndex = 0xFFFFFFFF;
|
|
||||||
size_t SzBufferSize;
|
|
||||||
size_t SzOffset;
|
|
||||||
size_t SzOutSizeProcessed;
|
|
||||||
CFileItem *SzF;
|
|
||||||
|
|
||||||
char sz_buffer[2048];
|
|
||||||
int szMethod = 0;
|
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
* Is7ZipFile
|
|
||||||
*
|
|
||||||
* Returns 1 when 7z signature is found
|
|
||||||
****************************************************************************/
|
|
||||||
int
|
int
|
||||||
Is7ZipFile (char *buffer)
|
UnZipFile (unsigned char *outbuffer, FILE* infile)
|
||||||
{
|
{
|
||||||
unsigned int *check;
|
fatfile = infile;
|
||||||
check = (unsigned int *) buffer;
|
return UnZipBuffer(outbuffer, 0);
|
||||||
|
|
||||||
// 7z signature
|
|
||||||
static Byte Signature[6] = {'7', 'z', 0xBC, 0xAF, 0x27, 0x1C};
|
|
||||||
|
|
||||||
int i;
|
|
||||||
for(i = 0; i < 6; i++)
|
|
||||||
if(buffer[i] != Signature[i])
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
return 1; // 7z archive found
|
|
||||||
}
|
}
|
||||||
|
// Reading from DVD
|
||||||
// display an error message
|
int
|
||||||
void SzDisplayError(SZ_RESULT res)
|
UnZipFile (unsigned char *outbuffer, u64 inoffset)
|
||||||
{
|
{
|
||||||
WaitPrompt(szerrormsg[(res - 1)]);
|
discoffset = inoffset;
|
||||||
|
return UnZipBuffer(outbuffer, 1);
|
||||||
}
|
}
|
||||||
|
// Reading from SMB
|
||||||
// function used by the 7zip SDK to read data from SD/USB/DVD/SMB
|
int
|
||||||
SZ_RESULT SzFileReadImp(void *object, void **buffer, size_t maxRequiredSize, size_t *processedSize)
|
UnZipFile (unsigned char *outbuffer, SMBFILE infile)
|
||||||
{
|
{
|
||||||
// the void* object is a SzFileInStream
|
smbfile = infile;
|
||||||
SzFileInStream *s = (SzFileInStream *) object;
|
return UnZipBuffer(outbuffer, 2);
|
||||||
|
|
||||||
// calculate offset
|
|
||||||
u64 offset = (u64) (s->offset + s->pos);
|
|
||||||
|
|
||||||
if (maxRequiredSize > 2048)
|
|
||||||
maxRequiredSize = 2048;
|
|
||||||
|
|
||||||
// read data
|
|
||||||
switch (szMethod)
|
|
||||||
{
|
|
||||||
case METHOD_SD:
|
|
||||||
case METHOD_USB:
|
|
||||||
fseek(fatfile, offset, SEEK_SET);
|
|
||||||
fread(sz_buffer, 1, maxRequiredSize, fatfile);
|
|
||||||
break;
|
|
||||||
case METHOD_DVD:
|
|
||||||
dvd_safe_read(sz_buffer, maxRequiredSize, offset);
|
|
||||||
break;
|
|
||||||
case METHOD_SMB:
|
|
||||||
SMB_ReadFile(sz_buffer, maxRequiredSize, offset, smbfile);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
*buffer = sz_buffer;
|
|
||||||
*processedSize = maxRequiredSize;
|
|
||||||
s->pos += *processedSize;
|
|
||||||
|
|
||||||
if(maxRequiredSize > 1024) // only show progress for large reads
|
|
||||||
// this isn't quite right, but oh well
|
|
||||||
ShowProgress ((char *)"Loading...", s->pos, filelist[selection].length);
|
|
||||||
|
|
||||||
return SZ_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
// function used by the 7zip SDK to change the filepointer
|
|
||||||
SZ_RESULT SzFileSeekImp(void *object, CFileSize pos)
|
|
||||||
{
|
|
||||||
// the void* object is a SzFileInStream
|
|
||||||
SzFileInStream *s = (SzFileInStream *) object;
|
|
||||||
|
|
||||||
// check if the 7z SDK wants to move the pointer to somewhere after the EOF
|
|
||||||
if (pos >= s->len)
|
|
||||||
{
|
|
||||||
WaitPrompt((char *) "7z: Error - attempt to read after EOF!");
|
|
||||||
return SZE_FAIL;
|
|
||||||
}
|
|
||||||
|
|
||||||
// save new position and return
|
|
||||||
s->pos = pos;
|
|
||||||
return SZ_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
* SzParse
|
|
||||||
*
|
|
||||||
* Opens a 7z file, and parses it
|
|
||||||
* Right now doesn't parse 7z, since we'll always use the first file
|
|
||||||
* But it could parse the entire 7z for full browsing capability
|
|
||||||
***************************************************************************/
|
|
||||||
|
|
||||||
int SzParse(char * filepath, int method)
|
|
||||||
{
|
|
||||||
int nbfiles = 0;
|
|
||||||
|
|
||||||
// save the offset and the length of this file inside the archive stream structure
|
|
||||||
SzArchiveStream.offset = filelist[selection].offset;
|
|
||||||
SzArchiveStream.len = filelist[selection].length;
|
|
||||||
SzArchiveStream.pos = 0;
|
|
||||||
|
|
||||||
// open file
|
|
||||||
switch (method)
|
|
||||||
{
|
|
||||||
case METHOD_SD:
|
|
||||||
case METHOD_USB:
|
|
||||||
fatfile = fopen (filepath, "rb");
|
|
||||||
if(!fatfile)
|
|
||||||
return 0;
|
|
||||||
break;
|
|
||||||
case METHOD_SMB:
|
|
||||||
smbfile = OpenSMBFile(filepath);
|
|
||||||
if(!smbfile)
|
|
||||||
return 0;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// set szMethod to current chosen load method
|
|
||||||
szMethod = method;
|
|
||||||
|
|
||||||
// set handler functions for reading data from FAT/SMB/DVD
|
|
||||||
SzArchiveStream.InStream.Read = SzFileReadImp;
|
|
||||||
SzArchiveStream.InStream.Seek = SzFileSeekImp;
|
|
||||||
|
|
||||||
// set default 7Zip SDK handlers for allocation and freeing memory
|
|
||||||
SzAllocImp.Alloc = SzAlloc;
|
|
||||||
SzAllocImp.Free = SzFree;
|
|
||||||
SzAllocTempImp.Alloc = SzAllocTemp;
|
|
||||||
SzAllocTempImp.Free = SzFreeTemp;
|
|
||||||
|
|
||||||
// prepare CRC and 7Zip database structures
|
|
||||||
InitCrcTable();
|
|
||||||
SzArDbExInit(&SzDb);
|
|
||||||
|
|
||||||
// open the archive
|
|
||||||
SzRes = SzArchiveOpen(&SzArchiveStream.InStream, &SzDb, &SzAllocImp,
|
|
||||||
&SzAllocTempImp);
|
|
||||||
|
|
||||||
if (SzRes != SZ_OK)
|
|
||||||
{
|
|
||||||
SzDisplayError(SzRes);
|
|
||||||
// free memory used by the 7z SDK
|
|
||||||
SzClose();
|
|
||||||
}
|
|
||||||
else // archive opened successfully
|
|
||||||
{
|
|
||||||
if(SzDb.Database.NumFiles > 0)
|
|
||||||
{
|
|
||||||
// Parses the 7z into a full file listing
|
|
||||||
|
|
||||||
// erase all previous entries
|
|
||||||
memset(&filelist, 0, sizeof(FILEENTRIES) * MAXFILES);
|
|
||||||
|
|
||||||
// add '..' folder in case the user wants exit the 7z
|
|
||||||
strncpy(filelist[0].displayname, "..", 2);
|
|
||||||
filelist[0].flags = 1;
|
|
||||||
filelist[0].offset = dvddir;
|
|
||||||
filelist[0].length = dvddirlength;
|
|
||||||
|
|
||||||
// get contents and parse them into file list structure
|
|
||||||
unsigned int SzI, SzJ;
|
|
||||||
SzJ = 1;
|
|
||||||
for (SzI = 0; SzI < SzDb.Database.NumFiles; SzI++)
|
|
||||||
{
|
|
||||||
SzF = SzDb.Database.Files + SzI;
|
|
||||||
|
|
||||||
// skip directories
|
|
||||||
if (SzF->IsDirectory)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
// do not exceed MAXFILES to avoid possible buffer overflows
|
|
||||||
if (SzJ == (MAXFILES - 1))
|
|
||||||
break;
|
|
||||||
|
|
||||||
// parse information about this file to the dvd file list structure
|
|
||||||
strncpy(filelist[SzJ].filename, SzF->Name, MAXJOLIET); // copy joliet name (useless...)
|
|
||||||
filelist[SzJ].filename[MAXJOLIET] = 0; // terminate string
|
|
||||||
strncpy(filelist[SzJ].displayname, SzF->Name, MAXDISPLAY+1); // crop name for display
|
|
||||||
filelist[SzJ].length = SzF->Size; // filesize
|
|
||||||
filelist[SzJ].offset = SzI; // the extraction function identifies the file with this number
|
|
||||||
filelist[SzJ].flags = 0; // only files will be displayed (-> no flags)
|
|
||||||
SzJ++;
|
|
||||||
}
|
|
||||||
|
|
||||||
// update maxfiles and select the first entry
|
|
||||||
offset = selection = 0;
|
|
||||||
nbfiles = SzJ;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
SzArDbExFree(&SzDb, SzAllocImp.Free);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// close file
|
|
||||||
switch (method)
|
|
||||||
{
|
|
||||||
case METHOD_SD:
|
|
||||||
case METHOD_USB:
|
|
||||||
fclose(fatfile);
|
|
||||||
break;
|
|
||||||
case METHOD_SMB:
|
|
||||||
SMB_CloseFile (smbfile);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return nbfiles;
|
|
||||||
}
|
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
* SzClose
|
|
||||||
*
|
|
||||||
* Closes a 7z file
|
|
||||||
***************************************************************************/
|
|
||||||
|
|
||||||
void SzClose()
|
|
||||||
{
|
|
||||||
if(SzDb.Database.NumFiles > 0)
|
|
||||||
SzArDbExFree(&SzDb, SzAllocImp.Free);
|
|
||||||
}
|
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
* SzExtractFile
|
|
||||||
*
|
|
||||||
* Extracts the given file # into the buffer specified
|
|
||||||
* Must parse the 7z BEFORE running this function
|
|
||||||
***************************************************************************/
|
|
||||||
|
|
||||||
int SzExtractFile(int i, unsigned char *buffer)
|
|
||||||
{
|
|
||||||
// prepare some variables
|
|
||||||
SzBlockIndex = 0xFFFFFFFF;
|
|
||||||
SzOffset = 0;
|
|
||||||
|
|
||||||
// Unzip the file
|
|
||||||
|
|
||||||
SzRes = SzExtract2(
|
|
||||||
&SzArchiveStream.InStream,
|
|
||||||
&SzDb,
|
|
||||||
i, // index of file
|
|
||||||
&SzBlockIndex, // index of solid block
|
|
||||||
&buffer,
|
|
||||||
&SzBufferSize,
|
|
||||||
&SzOffset, // offset of stream for required file in *outBuffer
|
|
||||||
&SzOutSizeProcessed, // size of file in *outBuffer
|
|
||||||
&SzAllocImp,
|
|
||||||
&SzAllocTempImp);
|
|
||||||
|
|
||||||
// close 7Zip archive and free memory
|
|
||||||
SzClose();
|
|
||||||
|
|
||||||
// check for errors
|
|
||||||
if(SzRes != SZ_OK)
|
|
||||||
{
|
|
||||||
// display error message
|
|
||||||
SzDisplayError(SzRes);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return SzOutSizeProcessed;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -12,12 +12,11 @@
|
|||||||
|
|
||||||
#include <smb.h>
|
#include <smb.h>
|
||||||
|
|
||||||
int IsZipFile (char *buffer);
|
extern int IsZipFile (char *buffer);
|
||||||
char * GetFirstZipFilename(int method);
|
|
||||||
int UnZipBuffer (unsigned char *outbuffer, int method);
|
int UnZipFile (unsigned char *outbuffer, FILE* infile); // Reading from FAT
|
||||||
int SzParse(char * filepath, int method);
|
int UnZipFile (unsigned char *outbuffer, u64 inoffset); // Reading from DVD
|
||||||
int SzExtractFile(int i, unsigned char *buffer);
|
int UnZipFile (unsigned char *outbuffer, SMBFILE infile); // Reading from SMB
|
||||||
void SzClose();
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Zip file header definition
|
* Zip file header definition
|
||||||
|
19212
source/ngc/images/bg.h
19212
source/ngc/images/bg.h
File diff suppressed because it is too large
Load Diff
@ -5,71 +5,135 @@
|
|||||||
#ifndef _IMGSAVEICON_
|
#ifndef _IMGSAVEICON_
|
||||||
#define _IMGSAVEICON_
|
#define _IMGSAVEICON_
|
||||||
|
|
||||||
const unsigned long saveicon[32*32] = {
|
const unsigned short saveicon[1024] = {
|
||||||
0x579A5753, 0x579A5753, 0x579A5753, 0x579A5753, 0x579A5753, 0x579A5753, 0x579A5753, 0x579A5753,
|
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
|
||||||
0x579A5753, 0x579A5753, 0x579A5753, 0x579A5753, 0x579A5753, 0x579A5753, 0x579A5753, 0x579A5753,
|
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
|
||||||
0x589B5852, 0x589B5852, 0x589B5852, 0x589B5852, 0x589B5852, 0x589B5852, 0x589B5852, 0x589B5852,
|
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
|
||||||
0x589B5852, 0x589B5852, 0x589B5852, 0x589B5852, 0x589B5852, 0x589B5852, 0x589B5852, 0x589B5852,
|
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
|
||||||
0x589B5852, 0x589B5852, 0x589B5852, 0x589B5852, 0x589B5852, 0x589B5852, 0x589B5852, 0x589B5852,
|
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
|
||||||
0x589B5852, 0x589B5852, 0x589B5852, 0x589B5852, 0x589B5852, 0x589B5852, 0x589B5852, 0x589B5852,
|
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
|
||||||
0x599B5951, 0x599B5951, 0x599B5951, 0x599B5951, 0x599B5951, 0x599B5951, 0x599B5951, 0x599B5951,
|
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
|
||||||
0x599B5951, 0x599B5951, 0x599B5951, 0x599B5951, 0x5A9B5951, 0x599B5951, 0x599B5951, 0x599B5951,
|
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
|
||||||
0x5A9B5A51, 0x5A9B5A51, 0x5A9B5A51, 0x5A9B5A51, 0x5A9B5A51, 0x5A9B5A51, 0x5A9B5A51, 0x5A9B5A51,
|
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
|
||||||
0x5A9B5A51, 0x5A9B5A51, 0x5A9B5A51, 0x5A9B5A51, 0x5A9B5A51, 0x5A9B5A51, 0x5A9B5A51, 0x5A9B5A51,
|
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
|
||||||
0x5B9C5B51, 0x5B9C5B51, 0x5B9C5B51, 0x5B9C5B51, 0x5B9C5B51, 0x5B9C5B51, 0x5B9C5B51, 0x5B9C5B51,
|
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
|
||||||
0x5B9C5B51, 0x5B9C5B51, 0x5B9C5B51, 0x5B9C5B51, 0x5B9C5B51, 0x5B9C5B51, 0x5B9C5C50, 0x5B9C5B51,
|
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
|
||||||
0x5C9C5C50, 0x5C9C5C50, 0x5C9C5C50, 0x5C9C5C50, 0x5C9C5C50, 0x5C9C5C50, 0x5C9C5C50, 0x5C9C5C50,
|
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
|
||||||
0x5C9C5C50, 0x5C9C5C50, 0x5C9C5C50, 0x5C9C5C50, 0x5C9C5C50, 0x5C9C5C50, 0x5C9C5C50, 0x5C9C5C50,
|
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
|
||||||
0x5D9C5C50, 0x5C9C5D50, 0x5C9C5C50, 0x5D9C5C50, 0x5D9C5C50, 0x5D9C5C50, 0x5D9C5C50, 0x5C9C5C50,
|
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
|
||||||
0x5C9C5C50, 0x5C9C5D50, 0x5C9C5C50, 0x5C9C5C50, 0x5C9C5C50, 0x5C9C5C50, 0x5C9C5C50, 0x5C9C5D50,
|
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
|
||||||
0x5D9C5D50, 0x5E9C5E4F, 0x5D9C5E4F, 0x5E9C5D4F, 0x5E9C5E4F, 0x5D9C5E4F, 0x5D9C5E4F, 0x5E9C5D4F,
|
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
|
||||||
0x5E9C5E4F, 0x5E9C5E4F, 0x5D9C5D50, 0x5D9C5D50, 0x5D9C5D50, 0x5E9C5E4F, 0x5E9C5D4F, 0x5E9C5D4F,
|
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
|
||||||
0x5E9D5E4F, 0x5E9D5E4F, 0x5E9D5E4F, 0x5E9D5E4F, 0x5E9D5E4F, 0x5E9D5E4F, 0x5F9D5E4F, 0x5E9D5E4F,
|
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
|
||||||
0x5E9D5E4F, 0x5E9D5F4F, 0x5E9D5E4F, 0x5F9D5E4F, 0x5E9D5F4F, 0x5E9D5E4F, 0x5E9D5E4F, 0x5F9D5E4F,
|
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
|
||||||
0x5F9B5351, 0x27860075, 0x00862775, 0x5F9D5F4E, 0x27860075, 0x12882770, 0x00800080, 0x00800080,
|
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xE73F,
|
||||||
0x00800080, 0x1F8F4765, 0x5F9D5F4F, 0x5A93275E, 0x00800080, 0x26914D62, 0x5F9D5F4E, 0x5F9D5F4E,
|
0xFFFF, 0xFFFF, 0xB5BF, 0x801F, 0xFFFF, 0xD29F, 0x801F, 0x801F,
|
||||||
0x60952C5B, 0x6551C69C, 0xCD631B91, 0x53974658, 0x3761D091, 0xA766468F, 0xD658D898, 0xD85AD897,
|
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xA11E, 0x843C, 0x8439, 0x9CF7,
|
||||||
0xD755D399, 0x89741F81, 0x549B6051, 0x337C6179, 0xD454D49A, 0x7B77267F, 0x609D604E, 0x609D604E,
|
0x801F, 0x801F, 0x801C, 0x8018, 0x801F, 0x801F, 0x801C, 0x8018,
|
||||||
0x609A4654, 0x2F53BB9B, 0xC5595197, 0x3A903363, 0x5E58C998, 0x5D69428D, 0xCA4ACBA0, 0xCC4CCC9F,
|
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xEB5C, 0xFFFF, 0xFFFF, 0xFFFF,
|
||||||
0xCB49C7A1, 0xC554699A, 0x2D95615B, 0x136EA387, 0xD050D09C, 0xBB67068D, 0x609E604E, 0x619D604E,
|
0x800F, 0xB9D3, 0xFFFF, 0xFFFF, 0x8013, 0x8008, 0xDAD7, 0xFFFF,
|
||||||
0x629D624D, 0x0D5E9891, 0xBC4D779F, 0x27881370, 0x9E4AC1A1, 0x326B3E8C, 0xBA3ABBAA, 0x25790084,
|
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
|
||||||
0x0062A292, 0xBC459AA4, 0x138F5465, 0x1A60C893, 0xBE4DCC9E, 0xC4583198, 0x48996254, 0x629D624D,
|
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
|
||||||
0x639E624D, 0x276A6386, 0xB03CA4A9, 0x0D7D197F, 0xBE3F9EA7, 0x0D733985, 0xAF31B3B0, 0x24780084,
|
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
|
||||||
0x00609E93, 0xB94C589F, 0x34903564, 0x5851BF9C, 0x7350B49D, 0xBB466BA3, 0x2795625C, 0x629E634D,
|
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
|
||||||
0x639E634C, 0x427B3578, 0xA42BB1B4, 0x3167498E, 0xB13E66A8, 0x2776367F, 0xA426A7B7, 0xAC2DAFB2,
|
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
|
||||||
0xAF30B1B0, 0x786C2186, 0x5E921A60, 0x853EB2A8, 0x2E5D6A94, 0xAE3293AF, 0x0D916363, 0x639E634C,
|
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
|
||||||
0x659F644C, 0x65900664, 0x9529A3B7, 0x4E4D6F9F, 0xA34041A7, 0x3C7A347A, 0x9F26A0B9, 0xA126A2B9,
|
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
|
||||||
0xA225A3B8, 0xA74050A6, 0x2F811776, 0xAA2A9AB4, 0x006E418B, 0xA425A4B8, 0x20825070, 0x649F654C,
|
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
|
||||||
0x659E654C, 0x65931B5F, 0x73349EB2, 0x753695B0, 0x94570799, 0x437B3478, 0x9D289EBB, 0x1F770085,
|
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
|
||||||
0x005F7595, 0xA12998B7, 0x076B4B8B, 0xA1269FB9, 0x9E289EBB, 0x9E27A0B9, 0x4B73357F, 0x659E654C,
|
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
|
||||||
0x659F654C, 0x65983C56, 0x3D439AAA, 0x9A299ABC, 0x70641B8F, 0x437C3378, 0x9B299CBB, 0x1F770085,
|
0xFFFF, 0x801F, 0x801F, 0x885F, 0xFFFF, 0x98D6, 0x801F, 0x801F,
|
||||||
0x00626993, 0x9E2B93B9, 0x07617393, 0x992A97BC, 0x962C96BD, 0x982A9BBC, 0x7E5F1492, 0x659F654C,
|
0xFFFF, 0xFFFF, 0xFFFF, 0x843C, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
|
||||||
0x679F674B, 0x669D594E, 0x144F97A2, 0x962C96BD, 0x46743680, 0x447B3278, 0x972B97BD, 0x972B97BD,
|
0xFBDF, 0x801E, 0x801B, 0x8017, 0x801E, 0x801B, 0x8018, 0x8015,
|
||||||
0x972B97BD, 0x983965B2, 0x0A558D9E, 0x8A560A9F, 0x00800080, 0x454197AD, 0x9A4E14A2, 0x599D674E,
|
0x801A, 0x8018, 0x8015, 0x8011, 0x8016, 0x8014, 0x8011, 0x800D,
|
||||||
0x679F674A, 0x679F674A, 0x14617793, 0x932D93BF, 0x14875A6C, 0x447C3178, 0x932D92BF, 0x922D92BF,
|
0x8012, 0x800B, 0x8848, 0xFFFF, 0x8010, 0x8009, 0x8003, 0xFFFF,
|
||||||
0x922D92BF, 0x586C228A, 0x444393AE, 0x6B651B8F, 0x679C534F, 0x1D4D95A5, 0x974148AC, 0x37976756,
|
0x800C, 0x8007, 0x8006, 0xFFFF, 0x8008, 0x8005, 0xA52E, 0xFFFF,
|
||||||
0x68A0674A, 0x68A0684A, 0x3F8C146A, 0x00800080, 0x2A966859, 0x68962A59, 0x00800080, 0x00800080,
|
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
|
||||||
0x00800080, 0x2A93545F, 0x2A860075, 0x1B8E4766, 0x68A0674A, 0x2A860075, 0x00862A74, 0x639F674B,
|
0xFFFF, 0xFFFF, 0xFBBD, 0xF1EF, 0xFFFF, 0xF508, 0xF000, 0xEC00,
|
||||||
0x699F684A, 0x699F694A, 0x699F684A, 0x699F694A, 0x699F694A, 0x699F694A, 0x699F694A, 0x699F694A,
|
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
|
||||||
0x699F694A, 0x699F694A, 0x699F694A, 0x699F694A, 0x699F694A, 0x699F694A, 0x699F694A, 0x699F694A,
|
0xE56B, 0xE16B, 0xE673, 0xFFFF, 0xE800, 0xDC00, 0xCC00, 0xB400,
|
||||||
0x6AA06949, 0x69A0694A, 0x69A06A49, 0x69A06A49, 0x6AA06949, 0x69A0694A, 0x69A0694A, 0x69A0694A,
|
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
|
||||||
0x6AA06949, 0x69A06A49, 0x69A06A49, 0x69A0694A, 0x69A0694A, 0x6AA06949, 0x69A0694A, 0x69A0694A,
|
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xDE94, 0xFFFF, 0xFFFF, 0xFFFF,
|
||||||
0x6BA06A49, 0x6AA06A49, 0x6BA06B49, 0x6AA06B49, 0x6AA06B49, 0x6BA06B49, 0x6AA06B49, 0x6BA06B49,
|
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
|
||||||
0x6BA06B49, 0x6BA06A49, 0x6BA06A49, 0x6AA06B49, 0x6BA06B49, 0x6BA06A49, 0x6AA06B49, 0x6BA06B49,
|
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xEBBA,
|
||||||
0x6CA16B48, 0x6BA16B48, 0x6BA16B48, 0x6BA16B48, 0x6BA16B48, 0x6BA16B48, 0x6BA16B48, 0x6BA16B48,
|
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
|
||||||
0x6BA16B48, 0x6BA16B48, 0x6BA16B48, 0x6BA16B48, 0x6BA16B48, 0x6BA16B48, 0x6BA16B48, 0x6BA16B48,
|
0xFFFF, 0xFFFF, 0xEFBA, 0xE378, 0xB2EB, 0x9AA4, 0x9AA5, 0x9AA5,
|
||||||
0x6CA16C48, 0x6CA16C48, 0x6CA16C48, 0x6CA16C48, 0x6CA16C48, 0x6CA16C48, 0x6CA16C48, 0x6CA16C48,
|
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
|
||||||
0x6CA16C48, 0x6CA16C48, 0x6CA16C48, 0x6CA16C48, 0x6CA16C48, 0x6CA16C48, 0x6CA16C48, 0x6CA16C48,
|
0xE778, 0xF3BC, 0xFFFF, 0xFFFF, 0x9A84, 0x9623, 0x91E3, 0xB66C,
|
||||||
0x6DA16C48, 0x6DA16D48, 0x6DA16D48, 0x6DA16D48, 0x6DA16C48, 0x6CA16D48, 0x6CA16D48, 0x6DA16D48,
|
0xD6BB, 0x800E, 0x800C, 0x8008, 0xFFFF, 0x8C6A, 0x8004, 0x8004,
|
||||||
0x6DA16D48, 0x6DA16D48, 0x6CA16D48, 0x6DA16D48, 0x6DA16D48, 0x6DA16D48, 0x6CA16D48, 0x6DA16D48,
|
0xFFFF, 0xFFFF, 0xB191, 0xDAD8, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
|
||||||
0x6EA16E47, 0x6DA16D47, 0x6DA16D47, 0x6DA16D47, 0x6DA16D47, 0x6EA16D47, 0x6DA16D47, 0x6DA16E47,
|
0x8006, 0x8004, 0xFFFF, 0xFFFF, 0x8006, 0xF39D, 0xFFFF, 0xFA94,
|
||||||
0x6DA16D47, 0x6DA16D47, 0x6DA16E47, 0x6DA16D47, 0x6DA16D47, 0x6EA16D47, 0x6DA16D47, 0x6DA16D47,
|
0xFFFF, 0xFFFF, 0xFFFF, 0xEC21, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
|
||||||
0x6EA16E46, 0x6EA16E46, 0x6EA16E47, 0x6EA16E46, 0x6EA16E46, 0x6EA16E46, 0x6EA16E46, 0x6EA16E47,
|
0xF484, 0xF800, 0xF800, 0xF000, 0xF800, 0xF800, 0xFD6B, 0xF8C6,
|
||||||
0x6EA16E46, 0x6EA16E47, 0x6EA16E46, 0x6EA16E46, 0x6EA16E47, 0x6EA16E46, 0x6EA16E46, 0x6EA16E46,
|
0xF400, 0xF400, 0xFDEF, 0xF4A5, 0xFF18, 0xEC63, 0xE400, 0xE000,
|
||||||
0x6FA26F47, 0x6FA16E46, 0x6FA16E46, 0x6FA26F47, 0x6FA26F47, 0x6FA26F47, 0x6FA26F47, 0x6FA26F47,
|
0xE800, 0xE000, 0xD400, 0xC400, 0xE400, 0xE000, 0xD000, 0xC400,
|
||||||
0x6FA26F47, 0x6FA26F47, 0x6FA26F47, 0x6FA26F47, 0x6FA26F47, 0x6FA26F47, 0x6FA26F47, 0x6FA26F47,
|
0xE000, 0xD800, 0xCC00, 0xC000, 0xD800, 0xD000, 0xC400, 0xB800,
|
||||||
0x70A27046, 0x70A27046, 0x70A27046, 0x70A27046, 0x70A27046, 0x70A27046, 0x70A27046, 0x70A27046,
|
0xA400, 0xD673, 0xFFFF, 0xFFFF, 0xB400, 0x9000, 0xFFFF, 0xFFFF,
|
||||||
0x70A27046, 0x70A27046, 0x70A27046, 0x70A27046, 0x70A27046, 0x70A27046, 0x70A27046, 0x70A27046,
|
0xB000, 0x9000, 0xFFFF, 0xFFFF, 0xA800, 0x9000, 0xFFFF, 0xFFFF,
|
||||||
|
0xFFFF, 0xFFFF, 0xDB75, 0x9AE4, 0xFFFF, 0xFFFF, 0x9A84, 0xA6E7,
|
||||||
|
0xFFFF, 0xFFFF, 0xA1E7, 0x9604, 0xFFFF, 0xFFFF, 0xFFFF, 0x8D03,
|
||||||
|
0xA707, 0xA708, 0xAF2A, 0xAF2A, 0xA6E7, 0xA2C7, 0xBF4E, 0xCB71,
|
||||||
|
0x9E46, 0x9E26, 0x9A25, 0x9604, 0x80E0, 0x8922, 0x8D22, 0x8D22,
|
||||||
|
0xA2C7, 0xA2A7, 0x9E66, 0x95E4, 0xA2A6, 0x9E46, 0x9E25, 0x95C4,
|
||||||
|
0x99E5, 0x95C4, 0x9163, 0x8D02, 0x88E2, 0x84A1, 0x8060, 0x8020,
|
||||||
|
0x8500, 0xF7BD, 0xFFFF, 0xFFFF, 0x8901, 0xA148, 0xFFFF, 0xFFFF,
|
||||||
|
0x8040, 0xB9ED, 0xFFFF, 0xFFFF, 0x9926, 0xFFFF, 0xFFFF, 0xFFFF,
|
||||||
|
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
|
||||||
|
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
|
||||||
|
0xFFFF, 0xFFFF, 0xE529, 0xD400, 0xFFFF, 0xFFFF, 0xFFFF, 0xD4C6,
|
||||||
|
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
|
||||||
|
0xD000, 0xC400, 0xBC00, 0xB000, 0xC000, 0xB800, 0xAC00, 0xA000,
|
||||||
|
0xA800, 0xA800, 0x9C00, 0x9400, 0xC18C, 0x8C00, 0x8C00, 0x8C00,
|
||||||
|
0x9C00, 0x8C00, 0xFFFF, 0xFFFF, 0x9400, 0x8C00, 0xFFFF, 0xFFFF,
|
||||||
|
0x8800, 0xDEB5, 0xFFFF, 0xFFFF, 0xE2D6, 0xFFFF, 0xFFFF, 0xFFFF,
|
||||||
|
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
|
||||||
|
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
|
||||||
|
0xD6D5, 0xAD8A, 0x8CC3, 0x8060, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
|
||||||
|
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
|
||||||
|
0x8060, 0x90E4, 0xB1CC, 0xE759, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
|
||||||
|
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFF, 0xF7AF,
|
||||||
|
0xFFFF, 0xFFFF, 0xFBDC, 0xF7B1, 0xFFFB, 0xFFE2, 0xFFE0, 0xFFE0,
|
||||||
|
0xFFE0, 0xFFE0, 0xFFE0, 0xFFE0, 0xFFE0, 0xFFE0, 0xFFE0, 0xFFE5,
|
||||||
|
0xF38C, 0xEF6A, 0xEB4B, 0xEB4F, 0xFFE0, 0xFBC0, 0xF7A0, 0xEB40,
|
||||||
|
0xFFE0, 0xFFE0, 0xFBC0, 0xF7A0, 0xFFF5, 0xFFE4, 0xF380, 0xEF60,
|
||||||
|
0xEF76, 0xFFFF, 0xFFFF, 0xFFFF, 0xE300, 0xCE60, 0xD6AB, 0xFFFF,
|
||||||
|
0xEB40, 0xE300, 0xCE60, 0xB180, 0xE720, 0xDEE0, 0xCE60, 0xB180,
|
||||||
|
0xF7BD, 0xB96B, 0xDAB4, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
|
||||||
|
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xB9CA, 0xFFFF, 0xFFFF, 0xFFFF,
|
||||||
|
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
|
||||||
|
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
|
||||||
|
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
|
||||||
|
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
|
||||||
|
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
|
||||||
|
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
|
||||||
|
0xFFFF, 0xFFFF, 0xFFFF, 0xF399, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
|
||||||
|
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
|
||||||
|
0xD280, 0xEB40, 0xEB40, 0xEB40, 0xDAD1, 0xAD60, 0xC200, 0xCA40,
|
||||||
|
0xFFFF, 0xF7BE, 0xBDEB, 0x98C0, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
|
||||||
|
0xEB40, 0xE720, 0xE300, 0xDAC0, 0xCA40, 0xC620, 0xC200, 0xBDE0,
|
||||||
|
0x9080, 0x94A0, 0x94A0, 0x9080, 0xFBDD, 0xE738, 0xE337, 0xE738,
|
||||||
|
0xD280, 0xCA40, 0xB5A0, 0x98C0, 0xB180, 0xA100, 0x94A0, 0x9080,
|
||||||
|
0x8C60, 0x9080, 0xC20C, 0xFFFF, 0xF7BD, 0xFFFF, 0xFFFF, 0xFFFF,
|
||||||
|
0xB9C9, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFF,
|
||||||
|
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
|
||||||
|
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
|
||||||
|
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
|
||||||
|
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
|
||||||
|
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
|
||||||
|
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
|
||||||
|
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
|
||||||
|
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
|
||||||
|
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
|
||||||
|
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
|
||||||
|
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
|
||||||
|
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
|
||||||
|
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
|
||||||
|
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
|
||||||
|
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
|
||||||
|
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
|
||||||
|
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
|
||||||
|
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
|
||||||
|
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -26,6 +26,8 @@
|
|||||||
#include "input.h"
|
#include "input.h"
|
||||||
#include "tbtime.h"
|
#include "tbtime.h"
|
||||||
|
|
||||||
|
#define MAXJP 10
|
||||||
|
|
||||||
#define VBA_BUTTON_A 1
|
#define VBA_BUTTON_A 1
|
||||||
#define VBA_BUTTON_B 2
|
#define VBA_BUTTON_B 2
|
||||||
#define VBA_BUTTON_SELECT 4
|
#define VBA_BUTTON_SELECT 4
|
||||||
@ -82,13 +84,14 @@ unsigned int ncpadmap[] = {
|
|||||||
WPAD_BUTTON_2, WPAD_BUTTON_1
|
WPAD_BUTTON_2, WPAD_BUTTON_1
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#ifdef HW_RVL
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* WPAD_Stick
|
* WPAD_StickX
|
||||||
*
|
*
|
||||||
* Get X/Y value from Wii Joystick (classic, nunchuk) input
|
* Get X value from Wii Joystick (classic, nunchuk) input
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
|
|
||||||
s8 WPAD_Stick(u8 chan, u8 right, int axis)
|
s8 WPAD_StickX(u8 chan,u8 right)
|
||||||
{
|
{
|
||||||
float mag = 0.0;
|
float mag = 0.0;
|
||||||
float ang = 0.0;
|
float ang = 0.0;
|
||||||
@ -122,19 +125,63 @@ s8 WPAD_Stick(u8 chan, u8 right, int axis)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* calculate x/y value (angle need to be converted into radian) */
|
/* calculate X value (angle need to be converted into radian) */
|
||||||
if (mag > 1.0) mag = 1.0;
|
if (mag > 1.0) mag = 1.0;
|
||||||
else if (mag < -1.0) mag = -1.0;
|
else if (mag < -1.0) mag = -1.0;
|
||||||
double val;
|
double val = mag * sin((PI * ang)/180.0f);
|
||||||
|
|
||||||
if(axis == 0) // x-axis
|
|
||||||
val = mag * sin((PI * ang)/180.0f);
|
|
||||||
else // y-axis
|
|
||||||
val = mag * cos((PI * ang)/180.0f);
|
|
||||||
|
|
||||||
return (s8)(val * 128.0f);
|
return (s8)(val * 128.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* WPAD_StickY
|
||||||
|
*
|
||||||
|
* Get Y value from Wii Joystick (classic, nunchuk) input
|
||||||
|
***************************************************************************/
|
||||||
|
|
||||||
|
s8 WPAD_StickY(u8 chan, u8 right)
|
||||||
|
{
|
||||||
|
float mag = 0.0;
|
||||||
|
float ang = 0.0;
|
||||||
|
WPADData *data = WPAD_Data(chan);
|
||||||
|
|
||||||
|
switch (data->exp.type)
|
||||||
|
{
|
||||||
|
case WPAD_EXP_NUNCHUK:
|
||||||
|
case WPAD_EXP_GUITARHERO3:
|
||||||
|
if (right == 0)
|
||||||
|
{
|
||||||
|
mag = data->exp.nunchuk.js.mag;
|
||||||
|
ang = data->exp.nunchuk.js.ang;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case WPAD_EXP_CLASSIC:
|
||||||
|
if (right == 0)
|
||||||
|
{
|
||||||
|
mag = data->exp.classic.ljs.mag;
|
||||||
|
ang = data->exp.classic.ljs.ang;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mag = data->exp.classic.rjs.mag;
|
||||||
|
ang = data->exp.classic.rjs.ang;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* calculate X value (angle need to be converted into radian) */
|
||||||
|
if (mag > 1.0) mag = 1.0;
|
||||||
|
else if (mag < -1.0) mag = -1.0;
|
||||||
|
double val = mag * cos((PI * ang)/180.0f);
|
||||||
|
|
||||||
|
return (s8)(val * 128.0f);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* DecodeJoy
|
* DecodeJoy
|
||||||
*
|
*
|
||||||
@ -146,15 +193,16 @@ u32 DecodeJoy(unsigned short pad)
|
|||||||
{
|
{
|
||||||
signed char pad_x = PAD_StickX (pad);
|
signed char pad_x = PAD_StickX (pad);
|
||||||
signed char pad_y = PAD_StickY (pad);
|
signed char pad_y = PAD_StickY (pad);
|
||||||
signed char gc_px = PAD_SubStickX (0);
|
|
||||||
u32 jp = PAD_ButtonsHeld (pad);
|
u32 jp = PAD_ButtonsHeld (pad);
|
||||||
u32 J = 0;
|
unsigned char J = 0;
|
||||||
|
|
||||||
#ifdef HW_RVL
|
#ifdef HW_RVL
|
||||||
signed char wm_ax = WPAD_Stick ((u8)pad, 0, 0);
|
signed char wm_ax = 0;
|
||||||
signed char wm_ay = WPAD_Stick ((u8)pad, 0, 1);
|
signed char wm_ay = 0;
|
||||||
u32 wp = WPAD_ButtonsHeld (pad);
|
u32 wp = 0;
|
||||||
signed char wm_sx = WPAD_Stick (0,1,0); // CC right joystick
|
wm_ax = WPAD_StickX ((u8)pad, 0);
|
||||||
|
wm_ay = WPAD_StickY ((u8)pad, 0);
|
||||||
|
wp = WPAD_ButtonsHeld (pad);
|
||||||
|
|
||||||
u32 exp_type;
|
u32 exp_type;
|
||||||
if ( WPAD_Probe(pad, &exp_type) != 0 ) exp_type = WPAD_EXP_NONE;
|
if ( WPAD_Probe(pad, &exp_type) != 0 ) exp_type = WPAD_EXP_NONE;
|
||||||
@ -235,16 +283,6 @@ u32 DecodeJoy(unsigned short pad)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Turbo feature
|
|
||||||
if(
|
|
||||||
(gc_px > 70)
|
|
||||||
#ifdef HW_RVL
|
|
||||||
|| (wm_sx > 70)
|
|
||||||
|| ((wp & WPAD_BUTTON_A) && (wp & WPAD_BUTTON_B))
|
|
||||||
#endif
|
|
||||||
)
|
|
||||||
J |= VBA_SPEED;
|
|
||||||
|
|
||||||
/*** Report pressed buttons (gamepads) ***/
|
/*** Report pressed buttons (gamepads) ***/
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
@ -260,37 +298,20 @@ u32 DecodeJoy(unsigned short pad)
|
|||||||
J |= vbapadmap[i];
|
J |= vbapadmap[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((J & 48) == 48)
|
|
||||||
J &= ~16;
|
|
||||||
if ((J & 192) == 192)
|
|
||||||
J &= ~128;
|
|
||||||
|
|
||||||
return J;
|
return J;
|
||||||
}
|
}
|
||||||
u32 GetJoy()
|
u32 GetJoy()
|
||||||
{
|
{
|
||||||
int pad = 0;
|
int pad = 0;
|
||||||
|
u32 res = 0;
|
||||||
|
|
||||||
s8 gc_px = PAD_SubStickX (0);
|
s8 gc_px = PAD_SubStickX (0);
|
||||||
s8 gc_py = PAD_SubStickY (0);
|
|
||||||
|
|
||||||
#ifdef HW_RVL
|
#ifdef HW_RVL
|
||||||
s8 wm_sx = WPAD_Stick (0,1,0);
|
s8 wm_sx = WPAD_StickX (0,1);
|
||||||
s8 wm_sy = WPAD_Stick (0,1,1);
|
|
||||||
u32 wm_pb = WPAD_ButtonsHeld (0); // wiimote / expansion button info
|
u32 wm_pb = WPAD_ButtonsHeld (0); // wiimote / expansion button info
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Check for video zoom
|
|
||||||
if (GCSettings.NGCZoom)
|
|
||||||
{
|
|
||||||
if (gc_py < -36 || gc_py > 36)
|
|
||||||
zoom ((float) gc_py / -36);
|
|
||||||
#ifdef HW_RVL
|
|
||||||
if (wm_sy < -36 || wm_sy > 36)
|
|
||||||
zoom ((float) wm_sy / -36);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
// request to go back to menu
|
// request to go back to menu
|
||||||
if ((gc_px < -70)
|
if ((gc_px < -70)
|
||||||
#ifdef HW_RVL
|
#ifdef HW_RVL
|
||||||
@ -302,24 +323,28 @@ u32 GetJoy()
|
|||||||
{
|
{
|
||||||
if (GCSettings.AutoSave == 1)
|
if (GCSettings.AutoSave == 1)
|
||||||
{
|
{
|
||||||
SaveBatteryOrState(GCSettings.SaveMethod, 0, SILENT); // save battery
|
SaveBattery(GCSettings.SaveMethod, SILENT);
|
||||||
}
|
}
|
||||||
else if (GCSettings.AutoSave == 2)
|
else if (GCSettings.AutoSave == 2)
|
||||||
{
|
{
|
||||||
SaveBatteryOrState(GCSettings.SaveMethod, 1, SILENT); // save state
|
SaveState(GCSettings.SaveMethod, SILENT);
|
||||||
}
|
}
|
||||||
else if(GCSettings.AutoSave == 3)
|
else if(GCSettings.AutoSave == 3)
|
||||||
{
|
{
|
||||||
SaveBatteryOrState(GCSettings.SaveMethod, 0, SILENT); // save battery
|
SaveBattery(GCSettings.SaveMethod, SILENT);
|
||||||
SaveBatteryOrState(GCSettings.SaveMethod, 1, SILENT); // save state
|
SaveState(GCSettings.SaveMethod, SILENT);
|
||||||
}
|
}
|
||||||
// change to menu video mode
|
|
||||||
ResetVideo_Menu ();
|
|
||||||
MainMenu(3);
|
MainMenu(3);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
return DecodeJoy(pad);
|
res = DecodeJoy(pad);
|
||||||
|
if ((res & 48) == 48)
|
||||||
|
res &= ~16;
|
||||||
|
if ((res & 192) == 192)
|
||||||
|
res &= ~128;
|
||||||
|
|
||||||
|
return res;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -15,14 +15,14 @@
|
|||||||
|
|
||||||
#define PI 3.14159265f
|
#define PI 3.14159265f
|
||||||
#define PADCAL 50
|
#define PADCAL 50
|
||||||
#define MAXJP 10
|
|
||||||
|
|
||||||
extern unsigned int gcpadmap[];
|
extern unsigned int gcpadmap[];
|
||||||
extern unsigned int wmpadmap[];
|
extern unsigned int wmpadmap[];
|
||||||
extern unsigned int ccpadmap[];
|
extern unsigned int ccpadmap[];
|
||||||
extern unsigned int ncpadmap[];
|
extern unsigned int ncpadmap[];
|
||||||
|
|
||||||
s8 WPAD_Stick(u8 chan,u8 right, int axis);
|
s8 WPAD_StickX(u8 chan,u8 right);
|
||||||
|
s8 WPAD_StickY(u8 chan, u8 right);
|
||||||
|
|
||||||
u32 GetJoy();
|
u32 GetJoy();
|
||||||
|
|
||||||
|
@ -25,6 +25,7 @@
|
|||||||
|
|
||||||
#define VERIFBUFFERSIZE 65536
|
#define VERIFBUFFERSIZE 65536
|
||||||
static u8 SysArea[CARD_WORKAREA] ATTRIBUTE_ALIGN (32);
|
static u8 SysArea[CARD_WORKAREA] ATTRIBUTE_ALIGN (32);
|
||||||
|
extern unsigned char savebuffer[];
|
||||||
unsigned char verifbuffer[VERIFBUFFERSIZE] ATTRIBUTE_ALIGN (32);
|
unsigned char verifbuffer[VERIFBUFFERSIZE] ATTRIBUTE_ALIGN (32);
|
||||||
card_dir CardDir;
|
card_dir CardDir;
|
||||||
card_file CardFile;
|
card_file CardFile;
|
||||||
@ -67,7 +68,7 @@ bool TestCard(int slot, bool silent)
|
|||||||
|
|
||||||
/*** Initialize Card System ***/
|
/*** Initialize Card System ***/
|
||||||
memset (SysArea, 0, CARD_WORKAREA);
|
memset (SysArea, 0, CARD_WORKAREA);
|
||||||
CARD_Init ("VBA0", "00");
|
CARD_Init ("SNES", "00");
|
||||||
|
|
||||||
/*** Try to mount the card ***/
|
/*** Try to mount the card ***/
|
||||||
if (MountCard(slot, silent) == 0)
|
if (MountCard(slot, silent) == 0)
|
||||||
@ -135,7 +136,7 @@ VerifyMCFile (unsigned char *buf, int slot, char *filename, int datasize)
|
|||||||
|
|
||||||
/*** Initialize Card System ***/
|
/*** Initialize Card System ***/
|
||||||
memset (SysArea, 0, CARD_WORKAREA);
|
memset (SysArea, 0, CARD_WORKAREA);
|
||||||
CARD_Init ("VBA0", "00");
|
CARD_Init ("SNES", "00");
|
||||||
|
|
||||||
/*** Try to mount the card ***/
|
/*** Try to mount the card ***/
|
||||||
CardError = MountCard(slot, NOTSILENT);
|
CardError = MountCard(slot, NOTSILENT);
|
||||||
@ -214,7 +215,7 @@ LoadBufferFromMC (unsigned char *buf, int slot, char *filename, bool silent)
|
|||||||
|
|
||||||
/*** Initialize Card System ***/
|
/*** Initialize Card System ***/
|
||||||
memset (SysArea, 0, CARD_WORKAREA);
|
memset (SysArea, 0, CARD_WORKAREA);
|
||||||
CARD_Init ("VBA0", "00");
|
CARD_Init ("SNES", "00");
|
||||||
|
|
||||||
/*** Try to mount the card ***/
|
/*** Try to mount the card ***/
|
||||||
CardError = MountCard(slot, NOTSILENT);
|
CardError = MountCard(slot, NOTSILENT);
|
||||||
@ -278,7 +279,7 @@ SaveBufferToMC (unsigned char *buf, int slot, char *filename, int datasize, bool
|
|||||||
|
|
||||||
/*** Initialize Card System ***/
|
/*** Initialize Card System ***/
|
||||||
memset (SysArea, 0, CARD_WORKAREA);
|
memset (SysArea, 0, CARD_WORKAREA);
|
||||||
CARD_Init ("VBA0", "00");
|
CARD_Init ("SNES", "00");
|
||||||
|
|
||||||
/*** Try to mount the card ***/
|
/*** Try to mount the card ***/
|
||||||
CardError = MountCard(slot, NOTSILENT);
|
CardError = MountCard(slot, NOTSILENT);
|
||||||
|
@ -44,7 +44,7 @@ extern "C"
|
|||||||
extern void DrawMenu (char items[][50], char *title, int maxitems, int selected, int fontsize);
|
extern void DrawMenu (char items[][50], char *title, int maxitems, int selected, int fontsize);
|
||||||
|
|
||||||
extern int menu;
|
extern int menu;
|
||||||
extern bool ROMLoaded;
|
extern int ROMSize;
|
||||||
|
|
||||||
#define SOFTRESET_ADR ((volatile u32*)0xCC003024)
|
#define SOFTRESET_ADR ((volatile u32*)0xCC003024)
|
||||||
|
|
||||||
@ -83,9 +83,9 @@ LoadManager ()
|
|||||||
if ( loadROM == 1 ) // if ROM was loaded, load the battery / state
|
if ( loadROM == 1 ) // if ROM was loaded, load the battery / state
|
||||||
{
|
{
|
||||||
if (GCSettings.AutoLoad == 1)
|
if (GCSettings.AutoLoad == 1)
|
||||||
LoadBatteryOrState(GCSettings.SaveMethod, 0, SILENT); // load battery
|
LoadBattery(GCSettings.SaveMethod, SILENT);
|
||||||
else if (GCSettings.AutoLoad == 2)
|
else if (GCSettings.AutoLoad == 2)
|
||||||
LoadBatteryOrState(GCSettings.SaveMethod, 1, SILENT); // load state
|
LoadState(GCSettings.SaveMethod, SILENT);
|
||||||
}
|
}
|
||||||
|
|
||||||
return loadROM;
|
return loadROM;
|
||||||
@ -94,7 +94,7 @@ LoadManager ()
|
|||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Preferences Menu
|
* Preferences Menu
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
static int prefmenuCount = 11;
|
static int prefmenuCount = 9;
|
||||||
static char prefmenu[][50] = {
|
static char prefmenu[][50] = {
|
||||||
|
|
||||||
"Load Method",
|
"Load Method",
|
||||||
@ -105,8 +105,6 @@ static char prefmenu[][50] = {
|
|||||||
"Auto Load",
|
"Auto Load",
|
||||||
"Auto Save",
|
"Auto Save",
|
||||||
"Verify MC Saves",
|
"Verify MC Saves",
|
||||||
"Enable Zooming",
|
|
||||||
"Video Rendering",
|
|
||||||
|
|
||||||
"Save Preferences",
|
"Save Preferences",
|
||||||
"Back to Main Menu"
|
"Back to Main Menu"
|
||||||
@ -124,26 +122,40 @@ PreferencesMenu ()
|
|||||||
// some load/save methods are not implemented - here's where we skip them
|
// some load/save methods are not implemented - here's where we skip them
|
||||||
// they need to be skipped in the order they were enumerated in vba.h
|
// they need to be skipped in the order they were enumerated in vba.h
|
||||||
|
|
||||||
|
// skip
|
||||||
|
if(GCSettings.LoadMethod == METHOD_DVD)
|
||||||
|
GCSettings.LoadMethod++;
|
||||||
|
if(GCSettings.LoadMethod == METHOD_SMB)
|
||||||
|
GCSettings.LoadMethod++;
|
||||||
|
if(GCSettings.SaveMethod == METHOD_SMB)
|
||||||
|
GCSettings.SaveMethod++;
|
||||||
|
if(GCSettings.SaveMethod == METHOD_MC_SLOTA)
|
||||||
|
GCSettings.SaveMethod++;
|
||||||
|
if(GCSettings.SaveMethod == METHOD_MC_SLOTB)
|
||||||
|
GCSettings.SaveMethod++;
|
||||||
|
|
||||||
|
prefmenu[6][0] = '\0'; // MC saving not implemented
|
||||||
|
|
||||||
// no USB ports on GameCube
|
// no USB ports on GameCube
|
||||||
#ifdef HW_DOL
|
#ifndef HW_RVL
|
||||||
if(GCSettings.LoadMethod == METHOD_USB)
|
if(GCSettings.LoadMethod == METHOD_USB)
|
||||||
GCSettings.LoadMethod++;
|
GCSettings.LoadMethod++;
|
||||||
if(GCSettings.SaveMethod == METHOD_USB)
|
if(GCSettings.SaveMethod == METHOD_USB)
|
||||||
GCSettings.SaveMethod++;
|
GCSettings.SaveMethod++;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// saving to DVD is impossible
|
// check if DVD access in Wii mode is disabled
|
||||||
if(GCSettings.SaveMethod == METHOD_DVD)
|
#ifndef WII_DVD
|
||||||
GCSettings.SaveMethod++;
|
|
||||||
|
|
||||||
// disable DVD in GC mode (not implemented)
|
|
||||||
#ifdef HW_DOL
|
|
||||||
if(GCSettings.LoadMethod == METHOD_DVD)
|
if(GCSettings.LoadMethod == METHOD_DVD)
|
||||||
GCSettings.LoadMethod++;
|
GCSettings.LoadMethod++;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// saving to DVD is impossible
|
||||||
|
if(GCSettings.SaveMethod == METHOD_DVD)
|
||||||
|
GCSettings.SaveMethod++;
|
||||||
|
|
||||||
// disable SMB in GC mode (stalls out)
|
// disable SMB in GC mode (stalls out)
|
||||||
#ifdef HW_DOL
|
#ifndef HW_RVL
|
||||||
if(GCSettings.LoadMethod == METHOD_SMB)
|
if(GCSettings.LoadMethod == METHOD_SMB)
|
||||||
GCSettings.LoadMethod++;
|
GCSettings.LoadMethod++;
|
||||||
if(GCSettings.SaveMethod == METHOD_SMB)
|
if(GCSettings.SaveMethod == METHOD_SMB)
|
||||||
@ -156,9 +168,6 @@ PreferencesMenu ()
|
|||||||
GCSettings.SaveMethod++;
|
GCSettings.SaveMethod++;
|
||||||
if(GCSettings.SaveMethod == METHOD_MC_SLOTB)
|
if(GCSettings.SaveMethod == METHOD_MC_SLOTB)
|
||||||
GCSettings.SaveMethod++;
|
GCSettings.SaveMethod++;
|
||||||
prefmenu[6][0] = 0;
|
|
||||||
#else
|
|
||||||
sprintf (prefmenu[6], "Verify MC Saves %s", GCSettings.VerifySaves == true ? " ON" : "OFF");
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// correct load/save methods out of bounds
|
// correct load/save methods out of bounds
|
||||||
@ -197,13 +206,7 @@ PreferencesMenu ()
|
|||||||
else if (GCSettings.AutoSave == 2) sprintf (prefmenu[5],"Auto Save SNAPSHOT");
|
else if (GCSettings.AutoSave == 2) sprintf (prefmenu[5],"Auto Save SNAPSHOT");
|
||||||
else if (GCSettings.AutoSave == 3) sprintf (prefmenu[5],"Auto Save BOTH");
|
else if (GCSettings.AutoSave == 3) sprintf (prefmenu[5],"Auto Save BOTH");
|
||||||
|
|
||||||
sprintf (prefmenu[7], "Enable Zooming %s",
|
//sprintf (prefmenu[6], "Verify MC Saves %s", GCSettings.VerifySaves == true ? " ON" : "OFF");
|
||||||
GCSettings.NGCZoom == true ? " ON" : "OFF");
|
|
||||||
|
|
||||||
if ( GCSettings.render == 0)
|
|
||||||
sprintf (prefmenu[8], "Video Rendering Filtered");
|
|
||||||
if ( GCSettings.render == 1)
|
|
||||||
sprintf (prefmenu[8], "Video Rendering Unfiltered");
|
|
||||||
|
|
||||||
ret = RunMenu (prefmenu, prefmenuCount, (char*)"Preferences", 16);
|
ret = RunMenu (prefmenu, prefmenuCount, (char*)"Preferences", 16);
|
||||||
|
|
||||||
@ -240,23 +243,11 @@ PreferencesMenu ()
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case 7:
|
case 7:
|
||||||
GCSettings.NGCZoom ^= 1;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 8:
|
|
||||||
GCSettings.render++;
|
|
||||||
if (GCSettings.render > 1 )
|
|
||||||
GCSettings.render = 0;
|
|
||||||
// reset zoom
|
|
||||||
zoom_reset ();
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 9:
|
|
||||||
SavePrefs(GCSettings.SaveMethod, NOTSILENT);
|
SavePrefs(GCSettings.SaveMethod, NOTSILENT);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case -1: /*** Button B ***/
|
case -1: /*** Button B ***/
|
||||||
case 10:
|
case 8:
|
||||||
quit = 1;
|
quit = 1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -272,13 +263,12 @@ PreferencesMenu ()
|
|||||||
int
|
int
|
||||||
GameMenu ()
|
GameMenu ()
|
||||||
{
|
{
|
||||||
int gamemenuCount = 8;
|
int gamemenuCount = 7;
|
||||||
char gamemenu[][50] = {
|
char gamemenu[][50] = {
|
||||||
"Return to Game",
|
"Return to Game",
|
||||||
"Reset Game",
|
"Reset Game",
|
||||||
"Load SRAM", "Save SRAM",
|
"Load SRAM", "Save SRAM",
|
||||||
"Load Game Snapshot", "Save Game Snapshot",
|
"Load Game Snapshot", "Save Game Snapshot",
|
||||||
"Reset Zoom",
|
|
||||||
"Back to Main Menu"
|
"Back to Main Menu"
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -305,9 +295,6 @@ GameMenu ()
|
|||||||
gamemenu[3][0] = '\0';
|
gamemenu[3][0] = '\0';
|
||||||
gamemenu[5][0] = '\0';
|
gamemenu[5][0] = '\0';
|
||||||
}
|
}
|
||||||
// disable Reset Zoom if Zooming is off
|
|
||||||
if(!GCSettings.NGCZoom)
|
|
||||||
gamemenu[6][0] = '\0';
|
|
||||||
|
|
||||||
ret = RunMenu (gamemenu, gamemenuCount, (char*)"Game Menu");
|
ret = RunMenu (gamemenu, gamemenuCount, (char*)"Game Menu");
|
||||||
|
|
||||||
@ -323,29 +310,23 @@ GameMenu ()
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case 2: // Load Battery
|
case 2: // Load Battery
|
||||||
quit = retval = LoadBatteryOrState(GCSettings.SaveMethod, 0, NOTSILENT);
|
quit = retval = LoadBattery(GCSettings.SaveMethod, NOTSILENT);
|
||||||
emulator.emuReset();
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 3: // Save Battery
|
case 3: // Save Battery
|
||||||
SaveBatteryOrState(GCSettings.SaveMethod, 0, NOTSILENT);
|
SaveBattery(GCSettings.SaveMethod, NOTSILENT);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 4: // Load State
|
case 4: // Load State
|
||||||
quit = retval = LoadBatteryOrState(GCSettings.SaveMethod, 1, NOTSILENT);
|
quit = retval = LoadState(GCSettings.SaveMethod, NOTSILENT);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 5: // Save State
|
case 5: // Save State
|
||||||
SaveBatteryOrState(GCSettings.SaveMethod, 1, NOTSILENT);
|
SaveState(GCSettings.SaveMethod, NOTSILENT);
|
||||||
break;
|
|
||||||
|
|
||||||
case 6: // Reset Zoom
|
|
||||||
zoom_reset ();
|
|
||||||
quit = retval = 1;
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case -1: // Button B
|
case -1: // Button B
|
||||||
case 7: // Return to previous menu
|
case 6: // Return to previous menu
|
||||||
retval = 0;
|
retval = 0;
|
||||||
quit = 1;
|
quit = 1;
|
||||||
break;
|
break;
|
||||||
@ -652,7 +633,7 @@ MainMenu (int selectedMenu)
|
|||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
// disable game-specific menu items if a ROM isn't loaded
|
// disable game-specific menu items if a ROM isn't loaded
|
||||||
if (!ROMLoaded)
|
if (ROMSize == 0 )
|
||||||
menuitems[3][0] = '\0';
|
menuitems[3][0] = '\0';
|
||||||
else
|
else
|
||||||
sprintf (menuitems[3], "Game Menu");
|
sprintf (menuitems[3], "Game Menu");
|
||||||
@ -719,24 +700,19 @@ MainMenu (int selectedMenu)
|
|||||||
|
|
||||||
case -1: // Button B
|
case -1: // Button B
|
||||||
// Return to Game
|
// Return to Game
|
||||||
if(ROMLoaded)
|
quit = 1;
|
||||||
quit = 1;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Wait for buttons to be released
|
/*** Remove any still held buttons ***/
|
||||||
int count = 0; // how long we've been waiting for the user to release the button
|
#ifdef HW_RVL
|
||||||
while(count < 50 && (
|
while( PAD_ButtonsHeld(0) || WPAD_ButtonsHeld(0) )
|
||||||
PAD_ButtonsHeld(0)
|
VIDEO_WaitVSync();
|
||||||
#ifdef HW_RVL
|
#else
|
||||||
|| WPAD_ButtonsHeld(0)
|
while( PAD_ButtonsHeld(0) )
|
||||||
#endif
|
VIDEO_WaitVSync();
|
||||||
))
|
#endif
|
||||||
{
|
|
||||||
VIDEO_WaitVSync();
|
|
||||||
count++;
|
|
||||||
}
|
|
||||||
|
|
||||||
StartAudio();
|
StartAudio();
|
||||||
mftb(&end);
|
mftb(&end);
|
||||||
|
@ -205,17 +205,6 @@ setfontcolour (u8 r, u8 g, u8 b)
|
|||||||
fontlo = fontcolour & 0xffff;
|
fontlo = fontcolour & 0xffff;
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
* Draws Version # on screen
|
|
||||||
***************************************************************************/
|
|
||||||
|
|
||||||
void DrawVersion()
|
|
||||||
{
|
|
||||||
setfontsize (12);
|
|
||||||
setfontcolour (0,0,0);
|
|
||||||
DrawText (115, screenheight - 34, (char *)VERSIONSTRFULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Display credits, legal copyright and licence
|
* Display credits, legal copyright and licence
|
||||||
*
|
*
|
||||||
@ -228,10 +217,10 @@ Credits ()
|
|||||||
|
|
||||||
setfontcolour (0x00, 0x00, 0x00);
|
setfontcolour (0x00, 0x00, 0x00);
|
||||||
|
|
||||||
setfontsize (26);
|
setfontsize (28);
|
||||||
DrawText (-1, 150, (char*)"Credits");
|
DrawText (-1, 60, (char*)"Credits");
|
||||||
|
|
||||||
int ypos = 120;
|
int ypos = 25;
|
||||||
|
|
||||||
if (screenheight == 480)
|
if (screenheight == 480)
|
||||||
ypos += 52;
|
ypos += 52;
|
||||||
@ -246,8 +235,6 @@ Credits ()
|
|||||||
DrawText (375, ypos, (char*)"emukidid");
|
DrawText (375, ypos, (char*)"emukidid");
|
||||||
DrawText (100, ypos += 18, (char*)"Original GameCube Port");
|
DrawText (100, ypos += 18, (char*)"Original GameCube Port");
|
||||||
DrawText (375, ypos, (char*)"SoftDev");
|
DrawText (375, ypos, (char*)"SoftDev");
|
||||||
DrawText (100, ypos += 18, (char*)"Visual Boy Advance - M");
|
|
||||||
DrawText (375, ypos, (char*)"VBA-M Team");
|
|
||||||
DrawText (100, ypos += 18, (char*)"Visual Boy Advance 1.7.2");
|
DrawText (100, ypos += 18, (char*)"Visual Boy Advance 1.7.2");
|
||||||
DrawText (375, ypos, (char*)"Forgotten");
|
DrawText (375, ypos, (char*)"Forgotten");
|
||||||
DrawText (100, ypos += 18, (char*)"libogc");
|
DrawText (100, ypos += 18, (char*)"libogc");
|
||||||
@ -258,11 +245,9 @@ Credits ()
|
|||||||
DrawText (-1, ypos += 36, (char*)"And many others who have contributed over the years!");
|
DrawText (-1, ypos += 36, (char*)"And many others who have contributed over the years!");
|
||||||
|
|
||||||
setfontsize (12);
|
setfontsize (12);
|
||||||
DrawText (-1, ypos += 40, (char*)"This software is open source and may be copied,");
|
DrawText (-1, ypos += 50, (char*)"This software is open source and may be copied, distributed, or modified");
|
||||||
DrawText (-1, ypos += 15, (char*)"distributed, or modified under the terms of");
|
DrawText (-1, ypos += 15, (char*)"under the terms of the GNU General Public License (GPL) Version 2.");
|
||||||
DrawText (-1, ypos += 15, (char*)"the GNU General Public License (GPL) Version 2.");
|
|
||||||
|
|
||||||
DrawVersion();
|
|
||||||
showscreen ();
|
showscreen ();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -368,12 +353,9 @@ WaitPrompt (char *msg)
|
|||||||
ypos += 32;
|
ypos += 32;
|
||||||
|
|
||||||
clearscreen ();
|
clearscreen ();
|
||||||
setfontsize(16);
|
|
||||||
DrawText (-1, ypos, msg);
|
DrawText (-1, ypos, msg);
|
||||||
ypos += 30;
|
ypos += 30;
|
||||||
DrawText (-1, ypos, (char*)"Press A to continue");
|
DrawText (-1, ypos, (char*)"Press A to continue");
|
||||||
|
|
||||||
DrawVersion();
|
|
||||||
showscreen ();
|
showscreen ();
|
||||||
WaitButtonA ();
|
WaitButtonA ();
|
||||||
}
|
}
|
||||||
@ -393,14 +375,11 @@ WaitPromptChoice (char *msg, char *bmsg, char *amsg)
|
|||||||
ypos += 17;
|
ypos += 17;
|
||||||
|
|
||||||
clearscreen ();
|
clearscreen ();
|
||||||
setfontsize(20);
|
|
||||||
DrawText (-1, ypos, msg);
|
DrawText (-1, ypos, msg);
|
||||||
ypos += 60;
|
ypos += 60;
|
||||||
char txt[80];
|
char txt[80];
|
||||||
sprintf (txt, "B = %s : A = %s", bmsg, amsg);
|
sprintf (txt, "B = %s : A = %s", bmsg, amsg);
|
||||||
DrawText (-1, ypos, txt);
|
DrawText (-1, ypos, txt);
|
||||||
|
|
||||||
DrawVersion();
|
|
||||||
showscreen ();
|
showscreen ();
|
||||||
return WaitButtonAB ();
|
return WaitButtonAB ();
|
||||||
}
|
}
|
||||||
@ -419,10 +398,7 @@ ShowAction (char *msg)
|
|||||||
ypos += 32;
|
ypos += 32;
|
||||||
|
|
||||||
clearscreen ();
|
clearscreen ();
|
||||||
setfontsize(20);
|
|
||||||
DrawText (-1, ypos, msg);
|
DrawText (-1, ypos, msg);
|
||||||
|
|
||||||
DrawVersion();
|
|
||||||
showscreen ();
|
showscreen ();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -437,12 +413,12 @@ DrawMenu (char items[][50], char *title, int maxitems, int selected, int fontsiz
|
|||||||
int n = 1;
|
int n = 1;
|
||||||
int line_height;
|
int line_height;
|
||||||
|
|
||||||
ypos = 105;
|
ypos = 45;
|
||||||
|
|
||||||
if (screenheight == 480)
|
if (screenheight == 480)
|
||||||
ypos += 52;
|
ypos += 52;
|
||||||
else
|
else
|
||||||
ypos += 42;
|
ypos += 32;
|
||||||
|
|
||||||
clearscreen ();
|
clearscreen ();
|
||||||
|
|
||||||
@ -450,10 +426,13 @@ DrawMenu (char items[][50], char *title, int maxitems, int selected, int fontsiz
|
|||||||
|
|
||||||
if (title != NULL)
|
if (title != NULL)
|
||||||
{
|
{
|
||||||
setfontsize (26);
|
setfontsize (28);
|
||||||
DrawText (-1, 150, title);
|
DrawText (-1, 60, title);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
setfontsize (14);
|
||||||
|
DrawText (380, screenheight - 30, (char *)VERSIONSTRFULL);
|
||||||
|
|
||||||
// Draw menu items
|
// Draw menu items
|
||||||
|
|
||||||
setfontsize (fontsize); // set font size
|
setfontsize (fontsize); // set font size
|
||||||
@ -469,11 +448,11 @@ DrawMenu (char items[][50], char *title, int maxitems, int selected, int fontsiz
|
|||||||
else if (i == selected)
|
else if (i == selected)
|
||||||
{
|
{
|
||||||
for( w = 0; w < line_height; w++ )
|
for( w = 0; w < line_height; w++ )
|
||||||
DrawLineFast( 77, 575, n * line_height + (ypos-line_height+6) + w, 0x00, 0x00, 0x00 );
|
DrawLineFast( 30, 610, n * line_height + (ypos-line_height+6) + w, 0x80, 0x80, 0x80 );
|
||||||
|
|
||||||
//setfontcolour (0xff, 0xff, 0xff);
|
setfontcolour (0xff, 0xff, 0xff);
|
||||||
DrawText (x, n * line_height + ypos, items[i]);
|
DrawText (x, n * line_height + ypos, items[i]);
|
||||||
//setfontcolour (0x00, 0x00, 0x00);
|
setfontcolour (0x00, 0x00, 0x00);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -483,8 +462,8 @@ DrawMenu (char items[][50], char *title, int maxitems, int selected, int fontsiz
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
DrawVersion();
|
|
||||||
showscreen ();
|
showscreen ();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
@ -540,7 +519,7 @@ RunMenu (char items[][50], int maxitems, char *title, int fontsize, int x)
|
|||||||
gc_ay = PAD_StickY (0);
|
gc_ay = PAD_StickY (0);
|
||||||
p = PAD_ButtonsDown (0);
|
p = PAD_ButtonsDown (0);
|
||||||
#ifdef HW_RVL
|
#ifdef HW_RVL
|
||||||
wm_ay = WPAD_Stick (0,0,1);
|
wm_ay = WPAD_StickY (0,0);
|
||||||
wp = WPAD_ButtonsDown (0);
|
wp = WPAD_ButtonsDown (0);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -605,8 +584,8 @@ ShowFiles (FILEENTRIES filelist[], int maxfiles, int offset, int selection)
|
|||||||
|
|
||||||
clearscreen ();
|
clearscreen ();
|
||||||
|
|
||||||
setfontsize (26);
|
setfontsize (28);
|
||||||
DrawText (-1, 150, (char*)"Choose Game");
|
DrawText (-1, 60, (char*)"Choose Game");
|
||||||
|
|
||||||
setfontsize(18);
|
setfontsize(18);
|
||||||
|
|
||||||
@ -617,8 +596,6 @@ ShowFiles (FILEENTRIES filelist[], int maxfiles, int offset, int selection)
|
|||||||
else
|
else
|
||||||
ypos += 10;
|
ypos += 10;
|
||||||
|
|
||||||
ypos += 30;
|
|
||||||
|
|
||||||
j = 0;
|
j = 0;
|
||||||
for (i = offset; i < (offset + PAGESIZE) && (i < maxfiles); i++)
|
for (i = offset; i < (offset + PAGESIZE) && (i < maxfiles); i++)
|
||||||
{
|
{
|
||||||
@ -637,18 +614,19 @@ ShowFiles (FILEENTRIES filelist[], int maxfiles, int offset, int selection)
|
|||||||
{
|
{
|
||||||
/*** Highlighted text entry ***/
|
/*** Highlighted text entry ***/
|
||||||
for ( w = 0; w < 20; w++ )
|
for ( w = 0; w < 20; w++ )
|
||||||
DrawLineFast( 77, 575, ( j * 20 ) + (ypos-16) + w, 0x00, 0x00, 0x00 );
|
DrawLineFast( 30, 610, ( j * 20 ) + (ypos-16) + w, 0x80, 0x80, 0x80 );
|
||||||
DrawText (100, (j * 20) + ypos, text);
|
|
||||||
|
setfontcolour (0x00, 0x00, 0xe0);
|
||||||
|
DrawText (50, (j * 20) + ypos, text);
|
||||||
|
setfontcolour (0x00, 0x00, 0x00);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/*** Normal entry ***/
|
/*** Normal entry ***/
|
||||||
DrawText (100, (j * 20) + ypos, text);
|
DrawText (50, (j * 20) + ypos, text);
|
||||||
}
|
}
|
||||||
j++;
|
j++;
|
||||||
}
|
}
|
||||||
|
|
||||||
DrawVersion();
|
|
||||||
showscreen ();
|
showscreen ();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -667,8 +645,8 @@ ShowCheats (char items[][50], char itemvalues[][50], int maxitems, int offset, i
|
|||||||
|
|
||||||
clearscreen ();
|
clearscreen ();
|
||||||
|
|
||||||
setfontsize (26);
|
setfontsize (28);
|
||||||
DrawText (-1, 150, (char*)"Cheats");
|
DrawText (-1, 60, (char*)"Cheats");
|
||||||
|
|
||||||
setfontsize(18);
|
setfontsize(18);
|
||||||
|
|
||||||
@ -698,8 +676,6 @@ ShowCheats (char items[][50], char itemvalues[][50], int maxitems, int offset, i
|
|||||||
}
|
}
|
||||||
j++;
|
j++;
|
||||||
}
|
}
|
||||||
|
|
||||||
DrawVersion();
|
|
||||||
showscreen ();
|
showscreen ();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -797,43 +773,30 @@ DrawLine (int x1, int y1, int x2, int y2, u8 r, u8 g, u8 b)
|
|||||||
void
|
void
|
||||||
ShowProgress (char *msg, int done, int total)
|
ShowProgress (char *msg, int done, int total)
|
||||||
{
|
{
|
||||||
if(total <= 0) // division by 0 is bad!
|
int ypos = (screenheight - 30) >> 1;
|
||||||
return;
|
|
||||||
else if(done > total) // this shouldn't happen
|
|
||||||
done = total;
|
|
||||||
|
|
||||||
int xpos, ypos;
|
if (screenheight == 480)
|
||||||
int i;
|
ypos += 52;
|
||||||
|
else
|
||||||
|
ypos += 32;
|
||||||
|
|
||||||
if(done < 5000) // we just started!
|
int xpos;
|
||||||
{
|
int i;
|
||||||
ypos = (screenheight - 30) >> 1;
|
|
||||||
|
|
||||||
if (screenheight == 480)
|
clearscreen ();
|
||||||
ypos += 52;
|
DrawText (-1, ypos, msg);
|
||||||
else
|
|
||||||
ypos += 32;
|
|
||||||
|
|
||||||
clearscreen ();
|
/*** Draw a white outline box ***/
|
||||||
setfontsize(20);
|
for (i = 380; i < 401; i++)
|
||||||
DrawText (-1, ypos, msg);
|
DrawLine (100, i, 540, i, 0xff, 0xff, 0xff);
|
||||||
|
|
||||||
/*** Draw a white outline box ***/
|
|
||||||
for (i = 380; i < 401; i++)
|
|
||||||
DrawLine (100, i, 540, i, 0xff, 0xff, 0xff);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*** Show progess ***/
|
/*** Show progess ***/
|
||||||
xpos = (int) (((float) done / (float) total) * 438);
|
xpos = (int) (((float) done / (float) total) * 438);
|
||||||
|
|
||||||
for (i = 381; i < 400; i++)
|
for (i = 381; i < 400; i++)
|
||||||
DrawLine (101, i, 101 + xpos, i, 0x00, 0x00, 0x80);
|
DrawLine (101, i, 101 + xpos, i, 0x00, 0x00, 0x80);
|
||||||
|
|
||||||
if(done < 5000) // we just started!
|
showscreen ();
|
||||||
{
|
|
||||||
DrawVersion();
|
|
||||||
showscreen ();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
|
@ -19,7 +19,7 @@
|
|||||||
|
|
||||||
#include "filesel.h"
|
#include "filesel.h"
|
||||||
|
|
||||||
#define PAGESIZE 13 // max item listing on a screen
|
#define PAGESIZE 17 // max item listing on a screen
|
||||||
|
|
||||||
int FT_Init ();
|
int FT_Init ();
|
||||||
void setfontsize (int pixelsize);
|
void setfontsize (int pixelsize);
|
||||||
|
@ -21,10 +21,16 @@
|
|||||||
#include "fileop.h"
|
#include "fileop.h"
|
||||||
#include "smbop.h"
|
#include "smbop.h"
|
||||||
#include "filesel.h"
|
#include "filesel.h"
|
||||||
#include "input.h"
|
|
||||||
|
|
||||||
|
extern unsigned char savebuffer[];
|
||||||
extern int currconfig[4];
|
extern int currconfig[4];
|
||||||
|
|
||||||
|
// button map configurations
|
||||||
|
extern unsigned int gcpadmap[];
|
||||||
|
extern unsigned int wmpadmap[];
|
||||||
|
extern unsigned int ccpadmap[];
|
||||||
|
extern unsigned int ncpadmap[];
|
||||||
|
|
||||||
#define PREFS_FILE_NAME "VBAGX.xml"
|
#define PREFS_FILE_NAME "VBAGX.xml"
|
||||||
|
|
||||||
char prefscomment[2][32];
|
char prefscomment[2][32];
|
||||||
@ -40,7 +46,7 @@ mxml_node_t *section;
|
|||||||
mxml_node_t *item;
|
mxml_node_t *item;
|
||||||
mxml_node_t *elem;
|
mxml_node_t *elem;
|
||||||
|
|
||||||
char temp[20];
|
char temp[200];
|
||||||
|
|
||||||
const char * toStr(int i)
|
const char * toStr(int i)
|
||||||
{
|
{
|
||||||
@ -70,7 +76,7 @@ void createXMLController(unsigned int controller[], const char * name, const cha
|
|||||||
mxmlElementSetAttr(item, "description", description);
|
mxmlElementSetAttr(item, "description", description);
|
||||||
|
|
||||||
// create buttons
|
// create buttons
|
||||||
for(int i=0; i < MAXJP; i++)
|
for(int i=0; i < 12; i++)
|
||||||
{
|
{
|
||||||
elem = mxmlNewElement(item, "button");
|
elem = mxmlNewElement(item, "button");
|
||||||
mxmlElementSetAttr(elem, "number", toStr(i));
|
mxmlElementSetAttr(elem, "number", toStr(i));
|
||||||
@ -110,6 +116,7 @@ int
|
|||||||
preparePrefsData (int method)
|
preparePrefsData (int method)
|
||||||
{
|
{
|
||||||
int offset = 0;
|
int offset = 0;
|
||||||
|
memset (savebuffer, 0, SAVEBUFFERSIZE);
|
||||||
|
|
||||||
// add save icon and comments for Memory Card saves
|
// add save icon and comments for Memory Card saves
|
||||||
if(method == METHOD_MC_SLOTA || method == METHOD_MC_SLOTB)
|
if(method == METHOD_MC_SLOTA || method == METHOD_MC_SLOTB)
|
||||||
@ -141,7 +148,7 @@ preparePrefsData (int method)
|
|||||||
createXMLSetting("LoadFolder", "Load Folder", GCSettings.LoadFolder);
|
createXMLSetting("LoadFolder", "Load Folder", GCSettings.LoadFolder);
|
||||||
createXMLSetting("SaveFolder", "Save Folder", GCSettings.SaveFolder);
|
createXMLSetting("SaveFolder", "Save Folder", GCSettings.SaveFolder);
|
||||||
//createXMLSetting("CheatFolder", "Cheats Folder", GCSettings.CheatFolder);
|
//createXMLSetting("CheatFolder", "Cheats Folder", GCSettings.CheatFolder);
|
||||||
createXMLSetting("VerifySaves", "Verify Memory Card Saves", toStr(GCSettings.VerifySaves));
|
//createXMLSetting("VerifySaves", "Verify Memory Card Saves", toStr(GCSettings.VerifySaves));
|
||||||
|
|
||||||
createXMLSection("Network", "Network Settings");
|
createXMLSection("Network", "Network Settings");
|
||||||
|
|
||||||
@ -150,10 +157,7 @@ preparePrefsData (int method)
|
|||||||
createXMLSetting("smbuser", "Share Username", GCSettings.smbuser);
|
createXMLSetting("smbuser", "Share Username", GCSettings.smbuser);
|
||||||
createXMLSetting("smbpwd", "Share Password", GCSettings.smbpwd);
|
createXMLSetting("smbpwd", "Share Password", GCSettings.smbpwd);
|
||||||
|
|
||||||
createXMLSection("Emulation", "Emulation Settings");
|
//createXMLSection("Emulation", "Emulation Settings");
|
||||||
|
|
||||||
createXMLSetting("NGCZoom", "Enable Zoom", toStr(GCSettings.NGCZoom));
|
|
||||||
createXMLSetting("render", "Video Rendering", toStr(GCSettings.render));
|
|
||||||
|
|
||||||
createXMLSection("Controller", "Controller Settings");
|
createXMLSection("Controller", "Controller Settings");
|
||||||
|
|
||||||
@ -208,7 +212,7 @@ void loadXMLController(unsigned int controller[], const char * name)
|
|||||||
if(item)
|
if(item)
|
||||||
{
|
{
|
||||||
// populate buttons
|
// populate buttons
|
||||||
for(int i=0; i < MAXJP; i++)
|
for(int i=0; i < 12; i++)
|
||||||
{
|
{
|
||||||
elem = mxmlFindElement(item, xml, "button", "number", toStr(i), MXML_DESCEND);
|
elem = mxmlFindElement(item, xml, "button", "number", toStr(i), MXML_DESCEND);
|
||||||
if(elem)
|
if(elem)
|
||||||
@ -238,6 +242,7 @@ decodePrefsData (int method)
|
|||||||
xml = mxmlLoadString(NULL, (char *)savebuffer+offset, MXML_TEXT_CALLBACK);
|
xml = mxmlLoadString(NULL, (char *)savebuffer+offset, MXML_TEXT_CALLBACK);
|
||||||
|
|
||||||
// check settings version
|
// check settings version
|
||||||
|
// we don't do anything with the version #, but we'll store it anyway
|
||||||
char * version;
|
char * version;
|
||||||
item = mxmlFindElement(xml, xml, "file", "version", NULL, MXML_DESCEND);
|
item = mxmlFindElement(xml, xml, "file", "version", NULL, MXML_DESCEND);
|
||||||
if(item) // a version entry exists
|
if(item) // a version entry exists
|
||||||
@ -245,17 +250,6 @@ decodePrefsData (int method)
|
|||||||
else // version # not found, must be invalid
|
else // version # not found, must be invalid
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// this code assumes version in format X.X.X
|
|
||||||
// XX.X.X, X.XX.X, or X.X.XX will NOT work
|
|
||||||
char verMajor = version[7];
|
|
||||||
char verMinor = version[9];
|
|
||||||
char verPoint = version[11];
|
|
||||||
|
|
||||||
if(verPoint < '3' && verMajor == '1') // less than version 1.0.3
|
|
||||||
return false; // reset settings
|
|
||||||
else if(verMajor > '1' || verMinor > '0' || verPoint > '3') // some future version
|
|
||||||
return false; // reset settings
|
|
||||||
|
|
||||||
// File Settings
|
// File Settings
|
||||||
|
|
||||||
loadXMLSetting(&GCSettings.AutoLoad, "AutoLoad");
|
loadXMLSetting(&GCSettings.AutoLoad, "AutoLoad");
|
||||||
@ -276,9 +270,6 @@ decodePrefsData (int method)
|
|||||||
|
|
||||||
// Emulation Settings
|
// Emulation Settings
|
||||||
|
|
||||||
loadXMLSetting(&GCSettings.NGCZoom, "NGCZoom");
|
|
||||||
loadXMLSetting(&GCSettings.render, "render");
|
|
||||||
|
|
||||||
// Controller Settings
|
// Controller Settings
|
||||||
|
|
||||||
loadXMLController(gcpadmap, "gcpadmap");
|
loadXMLController(gcpadmap, "gcpadmap");
|
||||||
@ -297,17 +288,13 @@ decodePrefsData (int method)
|
|||||||
bool
|
bool
|
||||||
SavePrefs (int method, bool silent)
|
SavePrefs (int method, bool silent)
|
||||||
{
|
{
|
||||||
// there's no point in saving SMB settings TO SMB, because then we'll have no way to load them the next time!
|
if(method == METHOD_AUTO)
|
||||||
// so instead we'll save using whatever other method is available (eg: SD)
|
|
||||||
if(method == METHOD_AUTO || method == METHOD_SMB)
|
|
||||||
method = autoSaveMethod();
|
method = autoSaveMethod();
|
||||||
|
|
||||||
char filepath[1024];
|
char filepath[1024];
|
||||||
int datasize;
|
int datasize;
|
||||||
int offset = 0;
|
int offset = 0;
|
||||||
|
|
||||||
AllocSaveBuffer ();
|
|
||||||
|
|
||||||
datasize = preparePrefsData (method);
|
datasize = preparePrefsData (method);
|
||||||
|
|
||||||
if (!silent)
|
if (!silent)
|
||||||
@ -335,8 +322,6 @@ SavePrefs (int method, bool silent)
|
|||||||
offset = SaveBufferToMC (savebuffer, CARD_SLOTB, (char *)PREFS_FILE_NAME, datasize, silent);
|
offset = SaveBufferToMC (savebuffer, CARD_SLOTB, (char *)PREFS_FILE_NAME, datasize, silent);
|
||||||
}
|
}
|
||||||
|
|
||||||
FreeSaveBuffer ();
|
|
||||||
|
|
||||||
if (offset > 0)
|
if (offset > 0)
|
||||||
{
|
{
|
||||||
if (!silent)
|
if (!silent)
|
||||||
@ -356,8 +341,6 @@ LoadPrefsFromMethod (int method)
|
|||||||
char filepath[1024];
|
char filepath[1024];
|
||||||
int offset = 0;
|
int offset = 0;
|
||||||
|
|
||||||
AllocSaveBuffer ();
|
|
||||||
|
|
||||||
if(method == METHOD_SD || method == METHOD_USB)
|
if(method == METHOD_SD || method == METHOD_USB)
|
||||||
{
|
{
|
||||||
if(ChangeFATInterface(method, NOTSILENT))
|
if(ChangeFATInterface(method, NOTSILENT))
|
||||||
@ -383,8 +366,6 @@ LoadPrefsFromMethod (int method)
|
|||||||
if (offset > 0)
|
if (offset > 0)
|
||||||
retval = decodePrefsData (method);
|
retval = decodePrefsData (method);
|
||||||
|
|
||||||
FreeSaveBuffer ();
|
|
||||||
|
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
115
source/ngc/sdfileio.c
Normal file
115
source/ngc/sdfileio.c
Normal file
@ -0,0 +1,115 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
* Visual Boy Advance GX
|
||||||
|
*
|
||||||
|
* Tantric September 2008
|
||||||
|
*
|
||||||
|
* sdfileio.c
|
||||||
|
*
|
||||||
|
* Generic File I/O for VisualBoyAdvance
|
||||||
|
* Currently only supports SD/USB
|
||||||
|
****************************************************************************/
|
||||||
|
#include <gccore.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <fat.h>
|
||||||
|
#include <sys/dir.h>
|
||||||
|
|
||||||
|
#define MAXDIRENTRIES 1000
|
||||||
|
char direntries[MAXDIRENTRIES][255];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SDInit
|
||||||
|
*/
|
||||||
|
void SDInit( void )
|
||||||
|
{
|
||||||
|
fatInitDefault();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SD Card f_open
|
||||||
|
*/
|
||||||
|
FILE* gen_fopen( const char *filename, const char *mode )
|
||||||
|
{
|
||||||
|
return fopen( filename, mode );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SD Card f_write
|
||||||
|
*/
|
||||||
|
int gen_fwrite( const void *buffer, int len, int block, FILE* f )
|
||||||
|
{
|
||||||
|
return fwrite(buffer, len, block, f);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SD Card f_read
|
||||||
|
*/
|
||||||
|
int gen_fread( void *buffer, int len, int block, FILE* f )
|
||||||
|
{
|
||||||
|
|
||||||
|
return fread(buffer, len, block, f);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SD Card fclose
|
||||||
|
*/
|
||||||
|
void gen_fclose( FILE* f )
|
||||||
|
{
|
||||||
|
fclose(f);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SD Card fseek
|
||||||
|
*
|
||||||
|
* NB: Only supports SEEK_SET
|
||||||
|
*/
|
||||||
|
int gen_fseek(FILE* f, int where, int whence)
|
||||||
|
{
|
||||||
|
fseek(f, where, whence);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Simple fgetc
|
||||||
|
*/
|
||||||
|
int gen_fgetc( FILE* f )
|
||||||
|
{
|
||||||
|
return fgetc(f);
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct stat _fstat;
|
||||||
|
char filename[1024];
|
||||||
|
int fcount = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get directory listing
|
||||||
|
*/
|
||||||
|
int gen_getdir( char *thisdir )
|
||||||
|
{
|
||||||
|
memset(&direntries[0],0,MAXDIRENTRIES*255);
|
||||||
|
|
||||||
|
DIR_ITER* dp = diropen( thisdir );
|
||||||
|
|
||||||
|
if ( dp )
|
||||||
|
{
|
||||||
|
while ( dirnext(dp, filename, &_fstat) == 0 )
|
||||||
|
{
|
||||||
|
|
||||||
|
// Skip any sub directories
|
||||||
|
if ( !(_fstat.st_mode & S_IFDIR) )
|
||||||
|
{
|
||||||
|
memcpy(&direntries[fcount],&filename,strlen(filename));
|
||||||
|
fcount++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dirclose(dp);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
|
||||||
|
return fcount;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
38
source/ngc/sdfileio.h
Normal file
38
source/ngc/sdfileio.h
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
* Visual Boy Advance GX
|
||||||
|
*
|
||||||
|
* Tantric September 2008
|
||||||
|
*
|
||||||
|
* sdfileio.h
|
||||||
|
*
|
||||||
|
* Generic File I/O for VisualBoyAdvance
|
||||||
|
* Currently only supports SD/USB
|
||||||
|
****************************************************************************/
|
||||||
|
#ifndef __SDFILEIO__
|
||||||
|
#define __SDFILEIO__
|
||||||
|
|
||||||
|
|
||||||
|
#define MAXDIRENTRIES 1000
|
||||||
|
#include <fat.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <sys/dir.h>
|
||||||
|
|
||||||
|
extern "C"
|
||||||
|
{
|
||||||
|
|
||||||
|
/* Required Functions */
|
||||||
|
FILE* gen_fopen( const char *filename, const char *mode );
|
||||||
|
int gen_fwrite( const void *buffer, int len, int block, FILE* f );
|
||||||
|
int gen_fread( void *buffer, int len, int block, FILE* f );
|
||||||
|
void gen_fclose( FILE* f );
|
||||||
|
int gen_fseek(FILE* f, int where, int whence);
|
||||||
|
int gen_fgetc( FILE* f );
|
||||||
|
int SDInit( void );
|
||||||
|
int gen_getdir( char *thisdir );
|
||||||
|
extern char direntries[MAXDIRENTRIES][255];
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
@ -30,12 +30,17 @@ bool networkShareInit = false;
|
|||||||
unsigned int SMBTimer = 0;
|
unsigned int SMBTimer = 0;
|
||||||
#define SMBTIMEOUT ( 3600 ) // Some implementations timeout in 10 minutes
|
#define SMBTIMEOUT ( 3600 ) // Some implementations timeout in 10 minutes
|
||||||
|
|
||||||
// SMB connection/file handles - the only ones we should ever use!
|
|
||||||
SMBCONN smbconn;
|
SMBCONN smbconn;
|
||||||
SMBFILE smbfile;
|
|
||||||
|
|
||||||
#define ZIPCHUNK 16384
|
#define ZIPCHUNK 16384
|
||||||
|
|
||||||
|
extern unsigned char savebuffer[];
|
||||||
|
extern char output[16384];
|
||||||
|
extern int offset;
|
||||||
|
extern int selection;
|
||||||
|
extern char currentdir[MAXPATHLEN];
|
||||||
|
extern FILEENTRIES filelist[MAXFILES];
|
||||||
|
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* InitializeNetwork
|
* InitializeNetwork
|
||||||
* Initializes the Wii/GameCube network interface
|
* Initializes the Wii/GameCube network interface
|
||||||
@ -88,7 +93,7 @@ ConnectShare (bool silent)
|
|||||||
strlen(GCSettings.smbip) == 0)
|
strlen(GCSettings.smbip) == 0)
|
||||||
{
|
{
|
||||||
if(!silent)
|
if(!silent)
|
||||||
WaitPrompt((char*) "Invalid network settings. Check VBAGX.xml.");
|
WaitPrompt((char*) "Invalid network settings. Check SNES9xGX.xml.");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -213,76 +218,36 @@ ParseSMBdirectory ()
|
|||||||
return filecount;
|
return filecount;
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
* Open SMB file
|
|
||||||
***************************************************************************/
|
|
||||||
|
|
||||||
SMBFILE OpenSMBFile(char * filepath)
|
|
||||||
{
|
|
||||||
return SMB_OpenFile (SMBPath(filepath), SMB_OPEN_READING, SMB_OF_OPEN, smbconn);
|
|
||||||
}
|
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Load SMB file
|
* Load SMB file
|
||||||
* rom - pointer to memory where ROM will be stored
|
|
||||||
* length - # bytes to read (0 for all)
|
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
int
|
int
|
||||||
LoadSMBFile (char * rom, int length)
|
LoadSMBFile (char *filename, int length)
|
||||||
{
|
{
|
||||||
char filepath[MAXPATHLEN];
|
char filepath[MAXPATHLEN];
|
||||||
|
|
||||||
/* Check filename length */
|
/* Check filename length */
|
||||||
if (!MakeROMPath(filepath, METHOD_SMB))
|
if ((strlen(currentdir)+1+strlen(filelist[selection].filename)) < MAXPATHLEN)
|
||||||
|
sprintf(filepath, "%s/%s",currentdir,filelist[selection].filename);
|
||||||
|
else
|
||||||
{
|
{
|
||||||
WaitPrompt((char*) "Maximum filepath length reached!");
|
WaitPrompt((char*) "Maximum filepath length reached!");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
return LoadBufferFromSMB(rom, filepath, length, NOTSILENT);
|
return 0;
|
||||||
}
|
//return LoadBufferFromSMB((char *)Memory.ROM, SMBPath(filepath), NOTSILENT);
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
* LoadSMBSzFile
|
|
||||||
* Loads the selected file # from the specified 7z into rbuffer
|
|
||||||
* Returns file size
|
|
||||||
***************************************************************************/
|
|
||||||
int
|
|
||||||
LoadSMBSzFile(char * filepath, unsigned char * rbuffer)
|
|
||||||
{
|
|
||||||
if(!ConnectShare (NOTSILENT))
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
smbfile = OpenSMBFile(filepath);
|
|
||||||
|
|
||||||
if (smbfile)
|
|
||||||
{
|
|
||||||
u32 size = SzExtractFile(filelist[selection].offset, rbuffer);
|
|
||||||
SMB_CloseFile (smbfile);
|
|
||||||
return size;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
WaitPrompt((char*) "Error opening file");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Write savebuffer to SMB file
|
* Write savebuffer to SMB file
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
// no buffer specified, use savebuffer
|
|
||||||
int
|
int
|
||||||
SaveBufferToSMB (char *filepath, int datasize, bool silent)
|
SaveBufferToSMB (char *filepath, int datasize, bool silent)
|
||||||
{
|
|
||||||
return SaveBufferToSMB((char *)savebuffer, filepath, datasize, silent);
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
SaveBufferToSMB (char * sbuffer, char *filepath, int datasize, bool silent)
|
|
||||||
{
|
{
|
||||||
if(!ConnectShare (NOTSILENT))
|
if(!ConnectShare (NOTSILENT))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
SMBFILE smbfile;
|
||||||
int dsize = datasize;
|
int dsize = datasize;
|
||||||
int wrote = 0;
|
int wrote = 0;
|
||||||
int boffset = 0;
|
int boffset = 0;
|
||||||
@ -297,10 +262,10 @@ SaveBufferToSMB (char * sbuffer, char *filepath, int datasize, bool silent)
|
|||||||
{
|
{
|
||||||
if (dsize > 1024)
|
if (dsize > 1024)
|
||||||
wrote =
|
wrote =
|
||||||
SMB_WriteFile ((char *) sbuffer + boffset, 1024, boffset, smbfile);
|
SMB_WriteFile ((char *) savebuffer + boffset, 1024, boffset, smbfile);
|
||||||
else
|
else
|
||||||
wrote =
|
wrote =
|
||||||
SMB_WriteFile ((char *) sbuffer + boffset, dsize, boffset, smbfile);
|
SMB_WriteFile ((char *) savebuffer + boffset, dsize, boffset, smbfile);
|
||||||
|
|
||||||
boffset += wrote;
|
boffset += wrote;
|
||||||
dsize -= wrote;
|
dsize -= wrote;
|
||||||
@ -314,6 +279,7 @@ SaveBufferToSMB (char * sbuffer, char *filepath, int datasize, bool silent)
|
|||||||
WaitPrompt (msg);
|
WaitPrompt (msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ClearSaveBuffer ();
|
||||||
return boffset;
|
return boffset;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -325,19 +291,22 @@ SaveBufferToSMB (char * sbuffer, char *filepath, int datasize, bool silent)
|
|||||||
int
|
int
|
||||||
LoadBufferFromSMB (char *filepath, bool silent)
|
LoadBufferFromSMB (char *filepath, bool silent)
|
||||||
{
|
{
|
||||||
return LoadBufferFromSMB((char *)savebuffer, filepath, 0, silent);
|
ClearSaveBuffer ();
|
||||||
|
return LoadBufferFromSMB((char *)savebuffer, filepath, silent);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
LoadBufferFromSMB (char * sbuffer, char *filepath, int length, bool silent)
|
LoadBufferFromSMB (char * sbuffer, char *filepath, bool silent)
|
||||||
{
|
{
|
||||||
if(!ConnectShare (NOTSILENT))
|
if(!ConnectShare (NOTSILENT))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
SMBFILE smbfile;
|
||||||
int ret;
|
int ret;
|
||||||
int boffset = 0;
|
int boffset = 0;
|
||||||
|
|
||||||
smbfile = OpenSMBFile(filepath);
|
smbfile =
|
||||||
|
SMB_OpenFile (SMBPath(filepath), SMB_OPEN_READING, SMB_OF_OPEN, smbconn);
|
||||||
|
|
||||||
if (!smbfile)
|
if (!smbfile)
|
||||||
{
|
{
|
||||||
@ -350,27 +319,17 @@ LoadBufferFromSMB (char * sbuffer, char *filepath, int length, bool silent)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(length > 0 && length <= 2048) // do a partial read (eg: to check file header)
|
ret = SMB_ReadFile (sbuffer, 1024, boffset, smbfile);
|
||||||
{
|
|
||||||
boffset = SMB_ReadFile (sbuffer, length, 0, smbfile);
|
|
||||||
}
|
|
||||||
else // load whole file
|
|
||||||
{
|
|
||||||
ret = SMB_ReadFile (sbuffer, 2048, boffset, smbfile);
|
|
||||||
|
|
||||||
if (IsZipFile (sbuffer))
|
if (IsZipFile (sbuffer))
|
||||||
{
|
{
|
||||||
boffset = UnZipBuffer ((unsigned char *)sbuffer, METHOD_SMB); // unzip from SMB
|
boffset = UnZipFile ((unsigned char *)sbuffer, smbfile); // unzip from SMB
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Just load the file up
|
// Just load the file up
|
||||||
while ((ret = SMB_ReadFile (sbuffer + boffset, 2048, boffset, smbfile)) > 0)
|
while ((ret = SMB_ReadFile (sbuffer + boffset, 1024, boffset, smbfile)) > 0)
|
||||||
{
|
boffset += ret;
|
||||||
boffset += ret;
|
|
||||||
ShowProgress ((char *)"Loading...", boffset, length);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
SMB_CloseFile (smbfile);
|
SMB_CloseFile (smbfile);
|
||||||
|
|
||||||
|
@ -12,21 +12,14 @@
|
|||||||
|
|
||||||
#define _NGCSMB_
|
#define _NGCSMB_
|
||||||
|
|
||||||
#include <smb.h>
|
|
||||||
|
|
||||||
bool InitializeNetwork(bool silent);
|
bool InitializeNetwork(bool silent);
|
||||||
bool ConnectShare (bool silent);
|
bool ConnectShare (bool silent);
|
||||||
char * SMBPath(char * path);
|
char * SMBPath(char * path);
|
||||||
int UpdateSMBdirname();
|
int UpdateSMBdirname();
|
||||||
int ParseSMBdirectory ();
|
int ParseSMBdirectory ();
|
||||||
SMBFILE OpenSMBFile(char * filepath);
|
int LoadSMBFile (char *filename, int length);
|
||||||
int LoadSMBFile (char * fbuffer, int length);
|
|
||||||
int LoadSMBSzFile(char * filepath, unsigned char * rbuffer);
|
|
||||||
int LoadBufferFromSMB (char *filepath, bool silent);
|
int LoadBufferFromSMB (char *filepath, bool silent);
|
||||||
int LoadBufferFromSMB (char * sbuffer, char *filepath, int length, bool silent);
|
int LoadBufferFromSMB (char * sbuffer, char *filepath, bool silent);
|
||||||
int SaveBufferToSMB (char *filepath, int datasize, bool silent);
|
int SaveBufferToSMB (char *filepath, int datasize, bool silent);
|
||||||
int SaveBufferToSMB (char * sbuffer, char *filepath, int datasize, bool silent);
|
|
||||||
|
|
||||||
extern SMBFILE smbfile;
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -38,7 +38,7 @@ extern "C" {
|
|||||||
#include "video.h"
|
#include "video.h"
|
||||||
#include "vbaconfig.h"
|
#include "vbaconfig.h"
|
||||||
|
|
||||||
extern bool ROMLoaded;
|
extern int ROMSize;
|
||||||
extern int emulating;
|
extern int emulating;
|
||||||
|
|
||||||
|
|
||||||
@ -74,10 +74,10 @@ int main()
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Initialize libFAT for SD and USB
|
// Initialize libFAT for SD and USB
|
||||||
fatInit (8, false);
|
fatInitDefault();
|
||||||
|
|
||||||
// Initialize DVD subsystem (GameCube only)
|
// Initialize DVD subsystem (GameCube only)
|
||||||
#ifdef HW_DOL
|
#ifndef HW_RVL
|
||||||
DVD_Init ();
|
DVD_Init ();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -98,7 +98,7 @@ int main()
|
|||||||
selectedMenu = 2; // change to preferences menu
|
selectedMenu = 2; // change to preferences menu
|
||||||
}
|
}
|
||||||
|
|
||||||
while (!ROMLoaded)
|
while (ROMSize == 0)
|
||||||
{
|
{
|
||||||
MainMenu (selectedMenu);
|
MainMenu (selectedMenu);
|
||||||
}
|
}
|
||||||
|
@ -7,13 +7,14 @@
|
|||||||
*
|
*
|
||||||
* This file controls overall program flow. Most things start and end here!
|
* This file controls overall program flow. Most things start and end here!
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
|
|
||||||
#ifndef _VBA_H_
|
#ifndef _VBA_H_
|
||||||
#define _VBA_H_
|
#define _VBA_H_
|
||||||
|
|
||||||
#include <gccore.h>
|
#include <gccore.h>
|
||||||
#define VERSIONNUM "1.0.3"
|
#define VERSIONNUM "1.0.0"
|
||||||
#define VERSIONSTR "VBA GX 1.0.3"
|
#define VERSIONSTR "VBA GX 1.0.0"
|
||||||
#define VERSIONSTRFULL "Visual Boy Advance GX 1.0.3"
|
#define VERSIONSTRFULL "Visual Boy Advance GX 1.0.0"
|
||||||
|
|
||||||
#define NOTSILENT 0
|
#define NOTSILENT 0
|
||||||
#define SILENT 1
|
#define SILENT 1
|
||||||
@ -45,9 +46,7 @@ struct SGCSettings{
|
|||||||
char smbgcid[20];
|
char smbgcid[20];
|
||||||
char smbsvid[20];
|
char smbsvid[20];
|
||||||
char smbshare[20];
|
char smbshare[20];
|
||||||
int NGCZoom; // 0 - off, 1 - on
|
|
||||||
int VerifySaves;
|
int VerifySaves;
|
||||||
int render; // 0 - filtered, 1 - unfiltered
|
|
||||||
};
|
};
|
||||||
|
|
||||||
extern struct SGCSettings GCSettings;
|
extern struct SGCSettings GCSettings;
|
||||||
|
@ -46,6 +46,4 @@ DefaultSettings ()
|
|||||||
GCSettings.smbgcid[0] = 0;
|
GCSettings.smbgcid[0] = 0;
|
||||||
|
|
||||||
GCSettings.VerifySaves = 0;
|
GCSettings.VerifySaves = 0;
|
||||||
GCSettings.NGCZoom = 0; // zooming default off
|
|
||||||
GCSettings.render = 0; // Unfiltered
|
|
||||||
}
|
}
|
||||||
|
@ -13,40 +13,43 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "agb/GBA.h"
|
#include "GBA.h"
|
||||||
#include "agb/agbprint.h"
|
#include "agbprint.h"
|
||||||
#include "Flash.h"
|
#include "Flash.h"
|
||||||
#include "Port.h"
|
#include "Port.h"
|
||||||
#include "RTC.h"
|
#include "RTC.h"
|
||||||
#include "Sound.h"
|
#include "Sound.h"
|
||||||
|
#include "Text.h"
|
||||||
#include "unzip.h"
|
#include "unzip.h"
|
||||||
#include "Util.h"
|
#include "Util.h"
|
||||||
#include "dmg/GB.h"
|
#include "gb/GB.h"
|
||||||
#include "dmg/gbGlobals.h"
|
#include "gb/gbGlobals.h"
|
||||||
#include "images/saveicon.h"
|
|
||||||
//#include "dmg/gbSound.h"
|
|
||||||
|
|
||||||
#include "vba.h"
|
#include "vba.h"
|
||||||
#include "fileop.h"
|
#include "fileop.h"
|
||||||
#include "dvd.h"
|
|
||||||
#include "smbop.h"
|
|
||||||
#include "memcardop.h"
|
|
||||||
#include "audio.h"
|
#include "audio.h"
|
||||||
#include "vmmem.h"
|
#include "vmmem.h"
|
||||||
|
#include "pal60.h"
|
||||||
#include "input.h"
|
#include "input.h"
|
||||||
#include "video.h"
|
#include "video.h"
|
||||||
#include "menudraw.h"
|
#include "menudraw.h"
|
||||||
#include "gcunzip.h"
|
|
||||||
|
|
||||||
extern "C"
|
extern "C"
|
||||||
{
|
{
|
||||||
#include "tbtime.h"
|
#include "tbtime.h"
|
||||||
|
#include "sdfileio.h"
|
||||||
}
|
}
|
||||||
|
|
||||||
static tb_t start, now;
|
static tb_t start, now;
|
||||||
|
|
||||||
u32 loadtimeradjust;
|
u32 loadtimeradjust;
|
||||||
|
|
||||||
|
int throttle = 100;
|
||||||
|
u32 throttleLastTime = 0;
|
||||||
|
|
||||||
|
static u32 autoFrameSkipLastTime = 0;
|
||||||
|
static int frameskipadjust = 0;
|
||||||
|
|
||||||
int vAspect = 0;
|
int vAspect = 0;
|
||||||
int hAspect = 0;
|
int hAspect = 0;
|
||||||
|
|
||||||
@ -79,7 +82,7 @@ int systemColorDepth = 0;
|
|||||||
u16 systemGbPalette[24];
|
u16 systemGbPalette[24];
|
||||||
u16 systemColorMap16[0x10000];
|
u16 systemColorMap16[0x10000];
|
||||||
//u32 systemColorMap32[0x10000];
|
//u32 systemColorMap32[0x10000];
|
||||||
u32 *systemColorMap32 = NULL;
|
u32 *systemColorMap32 = (u32 *)&systemColorMap16;
|
||||||
|
|
||||||
struct EmulatedSystem emulator =
|
struct EmulatedSystem emulator =
|
||||||
{
|
{
|
||||||
@ -119,7 +122,7 @@ bool systemPauseOnFrame()
|
|||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
/*
|
|
||||||
void GC_Sleep(u32 dwMiliseconds)
|
void GC_Sleep(u32 dwMiliseconds)
|
||||||
{
|
{
|
||||||
int nVBlanks = (dwMiliseconds / 16);
|
int nVBlanks = (dwMiliseconds / 16);
|
||||||
@ -128,39 +131,21 @@ void GC_Sleep(u32 dwMiliseconds)
|
|||||||
VIDEO_WaitVSync();
|
VIDEO_WaitVSync();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
|
|
||||||
static u32 autoFrameSkipLastTime = 0;
|
|
||||||
|
|
||||||
void system10Frames(int rate)
|
void system10Frames(int rate)
|
||||||
{
|
{
|
||||||
if (cartridgeType == 1)
|
if ( cartridgeType == 1 )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
u32 time = systemGetClock();
|
u32 time = systemGetClock();
|
||||||
u32 diff = time - autoFrameSkipLastTime;
|
u32 diff = time - autoFrameSkipLastTime;
|
||||||
|
|
||||||
// difference should be 1/6 second or (1/6)*1000 ms or 167 ms
|
|
||||||
int timeOff = (167 - diff);
|
|
||||||
|
|
||||||
if(timeOff > 3 && timeOff < 60) // we're running ahead!
|
|
||||||
usleep(timeOff*1000); // let's take a nap
|
|
||||||
else
|
|
||||||
timeOff = 0; // timeoff was not valid
|
|
||||||
|
|
||||||
if(diff > 175 && systemFrameSkip < 9)
|
|
||||||
systemFrameSkip++;
|
|
||||||
else if(diff < 150 && systemFrameSkip > 0)
|
|
||||||
systemFrameSkip--;
|
|
||||||
|
|
||||||
autoFrameSkipLastTime = time + timeOff; // total time = processing time + sleep time
|
|
||||||
|
|
||||||
/*
|
|
||||||
// Original VBA SDL frameskip algorithm
|
|
||||||
int speed = 100;
|
int speed = 100;
|
||||||
|
|
||||||
if(diff)
|
if(diff)
|
||||||
speed = (1000000/rate)/diff;
|
speed = (1000000/rate)/diff;
|
||||||
|
/* char temp[512];
|
||||||
|
sprintf(temp,"Speed: %i",speed);
|
||||||
|
MENU_DrawString( -1, 450,temp , 1 ); */
|
||||||
|
|
||||||
if(speed >= 98)
|
if(speed >= 98)
|
||||||
{
|
{
|
||||||
@ -189,7 +174,6 @@ void system10Frames(int rate)
|
|||||||
}
|
}
|
||||||
|
|
||||||
autoFrameSkipLastTime = time;
|
autoFrameSkipLastTime = time;
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
@ -197,295 +181,102 @@ void system10Frames(int rate)
|
|||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
void systemGbPrint(u8 *data,int pages,int feed,int palette, int contrast) {}
|
void systemGbPrint(u8 *data,int pages,int feed,int palette, int contrast) {}
|
||||||
void debuggerOutput(const char *s, u32 addr) {}
|
void debuggerOutput(char *, u32) {}
|
||||||
void (*dbgOutput)(const char *s, u32 addr) = debuggerOutput;
|
void (*dbgOutput)(char *, u32) = debuggerOutput;
|
||||||
void systemMessage(int num, const char *msg, ...) {}
|
void systemMessage(int num, const char *msg, ...) {}
|
||||||
|
|
||||||
bool MemCPUReadBatteryFile(char * membuffer, int size)
|
|
||||||
{
|
|
||||||
systemSaveUpdateCounter = SYSTEM_SAVE_NOT_UPDATED;
|
|
||||||
|
|
||||||
if(size == 512 || size == 0x2000)
|
|
||||||
{
|
|
||||||
memcpy(eepromData, membuffer, size);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if(size == 0x20000)
|
|
||||||
{
|
|
||||||
memcpy(flashSaveMemory, membuffer, 0x20000);
|
|
||||||
flashSetSize(0x20000);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
memcpy(flashSaveMemory, membuffer, 0x10000);
|
|
||||||
flashSetSize(0x10000);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
extern int gbaSaveType;
|
|
||||||
|
|
||||||
int MemCPUWriteBatteryFile(char * membuffer)
|
|
||||||
{
|
|
||||||
int result = 0;
|
|
||||||
if(gbaSaveType == 0)
|
|
||||||
{
|
|
||||||
if(eepromInUse)
|
|
||||||
gbaSaveType = 3;
|
|
||||||
else
|
|
||||||
switch(saveType)
|
|
||||||
{
|
|
||||||
case 1:
|
|
||||||
gbaSaveType = 1;
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
gbaSaveType = 2;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if((gbaSaveType) && (gbaSaveType!=5))
|
|
||||||
{
|
|
||||||
// only save if Flash/Sram in use or EEprom in use
|
|
||||||
if(gbaSaveType != 3)
|
|
||||||
{
|
|
||||||
if(gbaSaveType == 2)
|
|
||||||
{
|
|
||||||
memcpy(membuffer, flashSaveMemory, flashSize);
|
|
||||||
result = flashSize;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
memcpy(membuffer, flashSaveMemory, 0x10000);
|
|
||||||
result = 0x10000;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
memcpy(membuffer, eepromData, eepromSize);
|
|
||||||
result = eepromSize;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* SetFileBytesWritten
|
* Saves
|
||||||
* Sets the # of bytes written into a file
|
|
||||||
* Used by GBA.cpp and GB.cpp
|
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
void SetFileBytesWritten(int bytes)
|
bool LoadBattery(int method, bool silent)
|
||||||
{
|
|
||||||
//datasize = bytes;
|
|
||||||
}
|
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
* LoadBatteryOrState
|
|
||||||
* Load Battery/State file into memory
|
|
||||||
* action = 0 - Load battery
|
|
||||||
* action = 1 - Load state
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
bool LoadBatteryOrState(int method, int action, bool silent)
|
|
||||||
{
|
{
|
||||||
char filepath[1024];
|
char filepath[1024];
|
||||||
bool result = false;
|
bool result = false;
|
||||||
int offset = 0;
|
|
||||||
char ext[4];
|
|
||||||
|
|
||||||
if(action == 0)
|
|
||||||
sprintf(ext, "sav");
|
|
||||||
else
|
|
||||||
sprintf(ext, "sgm");
|
|
||||||
|
|
||||||
ShowAction ((char*) "Loading...");
|
ShowAction ((char*) "Loading...");
|
||||||
|
|
||||||
if(method == METHOD_AUTO)
|
if(method == METHOD_AUTO)
|
||||||
method = autoSaveMethod(); // we use 'Save' because we need R/W
|
method = autoSaveMethod(); // we use 'Save' because we need R/W
|
||||||
|
|
||||||
AllocSaveBuffer();
|
|
||||||
|
|
||||||
// load the file into savebuffer
|
|
||||||
|
|
||||||
if(method == METHOD_SD || method == METHOD_USB)
|
if(method == METHOD_SD || method == METHOD_USB)
|
||||||
{
|
{
|
||||||
if(ChangeFATInterface(method, NOTSILENT))
|
ChangeFATInterface(method, NOTSILENT);
|
||||||
{
|
sprintf (filepath, "%s/%s/%s.sav", ROOTFATDIR, GCSettings.SaveFolder, ROMFilename);
|
||||||
sprintf (filepath, "%s/%s/%s.%s", ROOTFATDIR, GCSettings.SaveFolder, ROMFilename, ext);
|
result = emulator.emuReadBattery(filepath);
|
||||||
offset = LoadBufferFromFAT (filepath, silent);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if(method == METHOD_SMB)
|
|
||||||
{
|
|
||||||
sprintf (filepath, "%s/%s.%s", GCSettings.SaveFolder, ROMFilename, ext);
|
|
||||||
offset = LoadBufferFromSMB (filepath, silent);
|
|
||||||
}
|
|
||||||
else if(method == METHOD_MC_SLOTA || method == METHOD_MC_SLOTB)
|
|
||||||
{
|
|
||||||
sprintf (filepath, "%s.%s", ROMFilename, ext);
|
|
||||||
|
|
||||||
if(method == METHOD_MC_SLOTA)
|
|
||||||
offset = LoadBufferFromMC (savebuffer, CARD_SLOTA, filepath, silent);
|
|
||||||
else
|
|
||||||
offset = LoadBufferFromMC (savebuffer, CARD_SLOTB, filepath, silent);
|
|
||||||
|
|
||||||
// skip save icon and comments for Memory Card saves
|
|
||||||
int skip = sizeof (saveicon);
|
|
||||||
skip += 64; // sizeof savecomment
|
|
||||||
memmove(savebuffer, savebuffer+skip, offset-skip);
|
|
||||||
offset -= skip;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// load savebuffer into VBA memory
|
if(!result && !silent)
|
||||||
if (offset > 0)
|
WaitPrompt ((char*) "Save file not found");
|
||||||
{
|
|
||||||
if(action == 0)
|
|
||||||
{
|
|
||||||
if(cartridgeType == 1)
|
|
||||||
result = MemgbReadBatteryFile((char *)savebuffer, offset);
|
|
||||||
else
|
|
||||||
result = MemCPUReadBatteryFile((char *)savebuffer, offset);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
result = emulator.emuReadMemState((char *)savebuffer, offset);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
FreeSaveBuffer();
|
|
||||||
|
|
||||||
if(!silent && !result)
|
|
||||||
{
|
|
||||||
if(offset == 0)
|
|
||||||
{
|
|
||||||
if(action == 0)
|
|
||||||
WaitPrompt ((char*) "Save file not found");
|
|
||||||
else
|
|
||||||
WaitPrompt ((char*) "State file not found");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if(action == 0)
|
|
||||||
WaitPrompt ((char*) "Invalid save file");
|
|
||||||
else
|
|
||||||
WaitPrompt ((char*) "Invalid state file");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool SaveBattery(int method, bool silent)
|
||||||
/****************************************************************************
|
|
||||||
* SaveBatteryOrState
|
|
||||||
* Save Battery/State file into memory
|
|
||||||
* action = 0 - Save battery
|
|
||||||
* action = 1 - Save state
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
bool SaveBatteryOrState(int method, int action, bool silent)
|
|
||||||
{
|
{
|
||||||
char filepath[1024];
|
char filepath[1024];
|
||||||
char savecomment[2][32];
|
|
||||||
bool result = false;
|
bool result = false;
|
||||||
int offset = 0;
|
|
||||||
char ext[4];
|
|
||||||
char savetype[10];
|
|
||||||
int datasize = 0; // we need the actual size of the data written
|
|
||||||
|
|
||||||
if(action == 0)
|
ShowAction ((char*) "Saving...");
|
||||||
|
|
||||||
|
if(method == METHOD_AUTO)
|
||||||
|
method = autoSaveMethod(); // we use 'Save' because we need R/W
|
||||||
|
|
||||||
|
if(method == METHOD_SD || method == METHOD_USB)
|
||||||
{
|
{
|
||||||
sprintf(ext, "sav");
|
ChangeFATInterface(method, NOTSILENT);
|
||||||
sprintf(savetype, "SRAM");
|
sprintf (filepath, "%s/%s/%s.sav", ROOTFATDIR, GCSettings.SaveFolder, ROMFilename);
|
||||||
|
result = emulator.emuWriteBattery(filepath);
|
||||||
}
|
}
|
||||||
else
|
|
||||||
|
if(!result && !silent)
|
||||||
|
WaitPrompt ((char*) "Save failed");
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool LoadState(int method, bool silent)
|
||||||
|
{
|
||||||
|
char filepath[1024];
|
||||||
|
bool result = false;
|
||||||
|
|
||||||
|
ShowAction ((char*) "Loading...");
|
||||||
|
|
||||||
|
if(method == METHOD_AUTO)
|
||||||
|
method = autoSaveMethod(); // we use 'Save' because we need R/W
|
||||||
|
|
||||||
|
if(method == METHOD_SD || method == METHOD_USB)
|
||||||
{
|
{
|
||||||
sprintf(ext, "sgm");
|
ChangeFATInterface(method, NOTSILENT);
|
||||||
sprintf(savetype, "Freeze");
|
sprintf (filepath, "%s/%s/%s.sgm", ROOTFATDIR, GCSettings.SaveFolder, ROMFilename);
|
||||||
|
result = emulator.emuReadState(filepath);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(!result && !silent)
|
||||||
|
WaitPrompt ((char*) "State file not found");
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SaveState(int method, bool silent)
|
||||||
|
{
|
||||||
|
char filepath[1024];
|
||||||
|
bool result = false;
|
||||||
|
|
||||||
ShowAction ((char*) "Saving...");
|
ShowAction ((char*) "Saving...");
|
||||||
|
|
||||||
if(method == METHOD_AUTO)
|
if(method == METHOD_AUTO)
|
||||||
method = autoSaveMethod(); // we use 'Save' because we need R/W
|
method = autoSaveMethod(); // we use 'Save' because we need R/W
|
||||||
|
|
||||||
AllocSaveBuffer();
|
if(method == METHOD_SD || method == METHOD_USB)
|
||||||
|
|
||||||
// add save icon and comments for Memory Card saves
|
|
||||||
if(method == METHOD_MC_SLOTA || method == METHOD_MC_SLOTB)
|
|
||||||
{
|
{
|
||||||
offset = sizeof (saveicon);
|
ChangeFATInterface(method, NOTSILENT);
|
||||||
|
sprintf (filepath, "%s/%s/%s.sgm", ROOTFATDIR, GCSettings.SaveFolder, ROMFilename);
|
||||||
// Copy in save icon
|
result = emulator.emuWriteState(filepath);
|
||||||
memcpy (savebuffer, saveicon, offset);
|
|
||||||
|
|
||||||
// And the comments
|
|
||||||
sprintf (savecomment[0], "%s %s", VERSIONSTR, savetype);
|
|
||||||
strncpy(savecomment[1], ROMFilename, 31); // truncate filename to 31 chars
|
|
||||||
savecomment[1][31] = 0; // make sure last char is null byte
|
|
||||||
memcpy (savebuffer + offset, savecomment, 64);
|
|
||||||
offset += 64;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// put VBA memory into savebuffer, sets datasize to size of memory written
|
if(!result && !silent)
|
||||||
if(action == 0)
|
WaitPrompt ((char*) "Save failed");
|
||||||
{
|
|
||||||
if(cartridgeType == 1)
|
|
||||||
datasize = MemgbWriteBatteryFile((char *)savebuffer+offset);
|
|
||||||
else
|
|
||||||
datasize = MemCPUWriteBatteryFile((char *)savebuffer+offset);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
bool written = emulator.emuWriteMemState((char *)savebuffer+offset, SAVEBUFFERSIZE-offset);
|
|
||||||
// we really should set datasize to the exact memory size written
|
|
||||||
// but instead we'll set it at 128K - although much of it will go unused
|
|
||||||
if(written)
|
|
||||||
datasize = (1024*128);
|
|
||||||
}
|
|
||||||
|
|
||||||
// write savebuffer into file
|
|
||||||
if(datasize > 0)
|
|
||||||
{
|
|
||||||
if(method == METHOD_SD || method == METHOD_USB)
|
|
||||||
{
|
|
||||||
if(ChangeFATInterface(method, NOTSILENT))
|
|
||||||
{
|
|
||||||
sprintf (filepath, "%s/%s/%s.%s", ROOTFATDIR, GCSettings.SaveFolder, ROMFilename, ext);
|
|
||||||
offset = SaveBufferToFAT (filepath, datasize, silent);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if(method == METHOD_SMB)
|
|
||||||
{
|
|
||||||
sprintf (filepath, "%s/%s.%s", GCSettings.SaveFolder, ROMFilename, ext);
|
|
||||||
offset = SaveBufferToSMB (filepath, datasize, silent);
|
|
||||||
}
|
|
||||||
else if(method == METHOD_MC_SLOTA || method == METHOD_MC_SLOTB)
|
|
||||||
{
|
|
||||||
sprintf (filepath, "%s.%s", ROMFilename, ext);
|
|
||||||
|
|
||||||
if(method == METHOD_MC_SLOTA)
|
|
||||||
offset = SaveBufferToMC (savebuffer, CARD_SLOTA, filepath, datasize+offset, silent);
|
|
||||||
else
|
|
||||||
offset = SaveBufferToMC (savebuffer, CARD_SLOTB, filepath, datasize+offset, silent);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(offset > 0)
|
|
||||||
{
|
|
||||||
if(!silent)
|
|
||||||
WaitPrompt ((char*) "Save successful");
|
|
||||||
result = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if(!silent)
|
|
||||||
WaitPrompt((char *)"No data to save!");
|
|
||||||
}
|
|
||||||
|
|
||||||
FreeSaveBuffer();
|
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@ -532,73 +323,21 @@ u32 systemReadJoypad(int which)
|
|||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
void systemDrawScreen()
|
void systemDrawScreen()
|
||||||
{
|
{
|
||||||
|
// GB / GBC Have oodles of time - so sync on VSync
|
||||||
GX_Render( srcWidth, srcHeight, pix, srcPitch );
|
GX_Render( srcWidth, srcHeight, pix, srcPitch );
|
||||||
|
|
||||||
|
#ifdef HW_RVL
|
||||||
|
VIDEO_WaitVSync ();
|
||||||
|
#else
|
||||||
|
if ( cartridgeType == 1 )
|
||||||
|
{
|
||||||
|
VIDEO_WaitVSync();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
extern bool gbUpdateSizes();
|
int loadVBAROM(char filename[])
|
||||||
bool LoadGBROM(int method)
|
|
||||||
{
|
{
|
||||||
// cleanup GB memory
|
|
||||||
if(gbRom != NULL)
|
|
||||||
gbCleanUp();
|
|
||||||
|
|
||||||
gbRom = (u8 *)malloc(1024*1024*4); // allocate 4 MB to GB ROM
|
|
||||||
|
|
||||||
systemSaveUpdateCounter = SYSTEM_SAVE_NOT_UPDATED;
|
|
||||||
|
|
||||||
switch (method)
|
|
||||||
{
|
|
||||||
case METHOD_SD:
|
|
||||||
case METHOD_USB:
|
|
||||||
gbRomSize = LoadFATFile ((char *)gbRom, 0);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case METHOD_DVD:
|
|
||||||
gbRomSize = LoadDVDFile ((unsigned char *)gbRom, 0);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case METHOD_SMB:
|
|
||||||
gbRomSize = LoadSMBFile ((char *)gbRom, 0);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!gbRom)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
return gbUpdateSizes();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool LoadVBAROM(int method)
|
|
||||||
{
|
|
||||||
int type = 0;
|
|
||||||
bool loaded = false;
|
|
||||||
|
|
||||||
// image type (checks file extension)
|
|
||||||
if(utilIsGBAImage(filelist[selection].filename))
|
|
||||||
type = 2;
|
|
||||||
else if(utilIsGBImage(filelist[selection].filename))
|
|
||||||
type = 1;
|
|
||||||
else if(utilIsZipFile(filelist[selection].filename))
|
|
||||||
{
|
|
||||||
// we need to check the file extension of the first file in the archive
|
|
||||||
char * zippedFilename = GetFirstZipFilename (method);
|
|
||||||
|
|
||||||
if(strlen(zippedFilename) > 0)
|
|
||||||
{
|
|
||||||
if(utilIsGBAImage(zippedFilename))
|
|
||||||
type = 2;
|
|
||||||
else if(utilIsGBImage(zippedFilename))
|
|
||||||
type = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// leave before we do anything
|
|
||||||
if(type != 1 && type != 2)
|
|
||||||
{
|
|
||||||
WaitPrompt((char *)"Unknown game image!");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
cartridgeType = 0;
|
cartridgeType = 0;
|
||||||
srcWidth = 0;
|
srcWidth = 0;
|
||||||
srcHeight = 0;
|
srcHeight = 0;
|
||||||
@ -606,15 +345,17 @@ bool LoadVBAROM(int method)
|
|||||||
destHeight = 0;
|
destHeight = 0;
|
||||||
srcPitch = 0;
|
srcPitch = 0;
|
||||||
|
|
||||||
|
IMAGE_TYPE type = utilFindType(filename);
|
||||||
|
|
||||||
switch( type )
|
switch( type )
|
||||||
{
|
{
|
||||||
case 2:
|
case IMAGE_GBA:
|
||||||
//WaitPrompt("GameBoy Advance Image");
|
//WaitPrompt("GameBoy Advance Image");
|
||||||
cartridgeType = 2;
|
cartridgeType = 2;
|
||||||
emulator = GBASystem;
|
emulator = GBASystem;
|
||||||
srcWidth = 240;
|
srcWidth = 240;
|
||||||
srcHeight = 160;
|
srcHeight = 160;
|
||||||
loaded = VMCPULoadROM(method);
|
VMCPULoadROM(filename);
|
||||||
// Actual Visual Aspect is 1.57
|
// Actual Visual Aspect is 1.57
|
||||||
hAspect = 70;
|
hAspect = 70;
|
||||||
vAspect = 46;
|
vAspect = 46;
|
||||||
@ -624,13 +365,13 @@ bool LoadVBAROM(int method)
|
|||||||
cpuSaveType = 0;
|
cpuSaveType = 0;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 1:
|
case IMAGE_GB:
|
||||||
//WaitPrompt("GameBoy Image");
|
//WaitPrompt("GameBoy Image");
|
||||||
cartridgeType = 1;
|
cartridgeType = 1;
|
||||||
emulator = GBSystem;
|
emulator = GBSystem;
|
||||||
srcWidth = 160;
|
srcWidth = 160;
|
||||||
srcHeight = 144;
|
srcHeight = 144;
|
||||||
loaded = LoadGBROM(method);
|
gbLoadRom(filename);
|
||||||
// Actual physical aspect is 1.0
|
// Actual physical aspect is 1.0
|
||||||
hAspect = 60;
|
hAspect = 60;
|
||||||
vAspect = 46;
|
vAspect = 46;
|
||||||
@ -638,52 +379,46 @@ bool LoadVBAROM(int method)
|
|||||||
soundQuality = 1;
|
soundQuality = 1;
|
||||||
soundBufferLen = 1470 * 2;
|
soundBufferLen = 1470 * 2;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
WaitPrompt((char *)"Unknown Image");
|
||||||
|
return 0;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!loaded)
|
// Set defaults
|
||||||
|
flashSetSize(0x10000);
|
||||||
|
rtcEnable(true);
|
||||||
|
agbPrintEnable(false);
|
||||||
|
soundOffFlag = false;
|
||||||
|
soundLowPass = true;
|
||||||
|
|
||||||
|
// Setup GX
|
||||||
|
GX_Render_Init( srcWidth, srcHeight, hAspect, vAspect );
|
||||||
|
|
||||||
|
if ( cartridgeType == 1 )
|
||||||
{
|
{
|
||||||
WaitPrompt((char *)"Error loading game!");
|
gbSoundReset();
|
||||||
return false;
|
gbSoundSetQuality(soundQuality);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Set defaults
|
soundSetQuality(soundQuality);
|
||||||
flashSetSize(0x20000); // 128K saves
|
CPUInit("/VBA/BIOS/BIOS.GBA", 1);
|
||||||
rtcEnable(true);
|
CPUReset();
|
||||||
agbPrintEnable(false);
|
|
||||||
soundOffFlag = false;
|
|
||||||
soundLowPass = true;
|
|
||||||
|
|
||||||
// Setup GX
|
|
||||||
GX_Render_Init( srcWidth, srcHeight, hAspect, vAspect );
|
|
||||||
|
|
||||||
if ( cartridgeType == 1 )
|
|
||||||
{
|
|
||||||
gbSoundReset();
|
|
||||||
gbSoundSetQuality(soundQuality);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
soundSetQuality(soundQuality);
|
|
||||||
CPUInit("/VBA/BIOS/BIOS.GBA", 1);
|
|
||||||
CPUReset();
|
|
||||||
}
|
|
||||||
|
|
||||||
soundVolume = 0;
|
|
||||||
systemSoundOn = true;
|
|
||||||
|
|
||||||
soundInit();
|
|
||||||
|
|
||||||
emulating = 1;
|
|
||||||
|
|
||||||
// reset frameskip variables
|
|
||||||
autoFrameSkipLastTime = systemFrameSkip = 0;
|
|
||||||
|
|
||||||
// Start system clock
|
|
||||||
mftb(&start);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
soundVolume = 0;
|
||||||
|
systemSoundOn = true;
|
||||||
|
|
||||||
|
soundInit();
|
||||||
|
|
||||||
|
emulating = 1;
|
||||||
|
|
||||||
|
// Start system clock
|
||||||
|
mftb(&start);
|
||||||
|
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
|
@ -12,7 +12,9 @@
|
|||||||
|
|
||||||
extern struct EmulatedSystem emulator;
|
extern struct EmulatedSystem emulator;
|
||||||
extern u32 loadtimeradjust;
|
extern u32 loadtimeradjust;
|
||||||
bool LoadVBAROM(int method);
|
int loadVBAROM(char filename[]);
|
||||||
void InitialisePalette();
|
void InitialisePalette();
|
||||||
bool LoadBatteryOrState(int method, int action, bool silent);
|
bool LoadBattery(int method, bool silent);
|
||||||
bool SaveBatteryOrState(int method, int action, bool silent);
|
bool SaveBattery(int method, bool silent);
|
||||||
|
bool LoadState(int method, bool silent);
|
||||||
|
bool SaveState(int method, bool silent);
|
||||||
|
@ -11,43 +11,32 @@
|
|||||||
* These are pretty standard functions to setup and use GX scaling.
|
* These are pretty standard functions to setup and use GX scaling.
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
#include <gccore.h>
|
#include <gccore.h>
|
||||||
#include <unistd.h>
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <malloc.h>
|
#include <malloc.h>
|
||||||
#include <wiiuse/wpad.h>
|
#include <wiiuse/wpad.h>
|
||||||
#include "images/bg.h"
|
|
||||||
#include "vba.h"
|
|
||||||
#include "menudraw.h"
|
|
||||||
//#include "pal60.h"
|
|
||||||
|
|
||||||
extern unsigned int SMBTimer; // timer to reset SMB connection
|
|
||||||
u32 FrameTimer = 0;
|
|
||||||
|
|
||||||
/*** External 2D Video ***/
|
/*** External 2D Video ***/
|
||||||
/*** 2D Video Globals ***/
|
/*** 2D Video Globals ***/
|
||||||
GXRModeObj *vmode = NULL; // Graphics Mode Object
|
GXRModeObj *vmode; /*** Graphics Mode Object ***/
|
||||||
unsigned int *xfb[2]; // Framebuffers
|
u32 *xfb[2] = { NULL, NULL }; /*** Framebuffers ***/
|
||||||
int whichfb = 0; // Frame buffer toggle
|
int whichfb = 0; /*** Frame buffer toggle ***/
|
||||||
|
|
||||||
int screenheight;
|
int screenheight;
|
||||||
|
|
||||||
/*** 3D GX ***/
|
/*** 3D GX ***/
|
||||||
#define DEFAULT_FIFO_SIZE ( 256 * 1024 )
|
#define DEFAULT_FIFO_SIZE ( 256 * 1024 )
|
||||||
static u8 gp_fifo[DEFAULT_FIFO_SIZE] ATTRIBUTE_ALIGN(32);
|
static u8 gp_fifo[DEFAULT_FIFO_SIZE] ATTRIBUTE_ALIGN(32);
|
||||||
unsigned int copynow = GX_FALSE;
|
|
||||||
|
|
||||||
/*** Texture memory ***/
|
/*** Texture memory ***/
|
||||||
static u8 *texturemem = NULL;
|
static u8 *texturemem;
|
||||||
static int texturesize;
|
static int texturesize;
|
||||||
|
|
||||||
GXTexObj texobj;
|
GXTexObj texobj;
|
||||||
static Mtx view;
|
static Mtx view;
|
||||||
static int vwidth, vheight, oldvwidth, oldvheight;
|
static int vwidth, vheight, oldvwidth, oldvheight;
|
||||||
static int video_vaspect, video_haspect;
|
unsigned int copynow = GX_FALSE;
|
||||||
int updateScaling;
|
|
||||||
float zoom_level = 1;
|
|
||||||
|
|
||||||
#define HASPECT 80
|
#define HASPECT 80
|
||||||
#define VASPECT 45
|
#define VASPECT 45
|
||||||
@ -81,92 +70,84 @@ static camera cam = { {0.0F, 0.0F, 0.0F},
|
|||||||
{0.0F, 0.0F, -0.5F}
|
{0.0F, 0.0F, -0.5F}
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef VIDEO_THREADING
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* VideoThreading
|
* StartGX
|
||||||
***************************************************************************/
|
****************************************************************************/
|
||||||
#define TSTACK 16384
|
void GX_Start()
|
||||||
lwpq_t videoblankqueue;
|
|
||||||
lwp_t vbthread;
|
|
||||||
static unsigned char vbstack[TSTACK];
|
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
* vbgetback
|
|
||||||
*
|
|
||||||
* This callback enables the emulator to keep running while waiting for a
|
|
||||||
* vertical blank.
|
|
||||||
*
|
|
||||||
* Putting LWP to good use :)
|
|
||||||
***************************************************************************/
|
|
||||||
static void *
|
|
||||||
vbgetback (void *arg)
|
|
||||||
{
|
{
|
||||||
while (1)
|
Mtx p;
|
||||||
{
|
|
||||||
VIDEO_WaitVSync (); /**< Wait for video vertical blank */
|
|
||||||
LWP_SuspendThread (vbthread);
|
|
||||||
}
|
|
||||||
|
|
||||||
return NULL;
|
GXColor gxbackground = { 0, 0, 0, 0xff };
|
||||||
|
|
||||||
|
/*** Clear out FIFO area ***/
|
||||||
|
memset(&gp_fifo, 0, DEFAULT_FIFO_SIZE);
|
||||||
|
|
||||||
|
/*** Initialise GX ***/
|
||||||
|
GX_Init(&gp_fifo, DEFAULT_FIFO_SIZE);
|
||||||
|
GX_SetCopyClear(gxbackground, 0x00ffffff);
|
||||||
|
|
||||||
|
GX_SetViewport(0, 0, vmode->fbWidth, vmode->efbHeight, 0, 1);
|
||||||
|
GX_SetDispCopyYScale((f32) vmode->xfbHeight / (f32) vmode->efbHeight);
|
||||||
|
GX_SetScissor(0, 0, vmode->fbWidth, vmode->efbHeight);
|
||||||
|
GX_SetDispCopySrc(0, 0, vmode->fbWidth, vmode->efbHeight);
|
||||||
|
GX_SetDispCopyDst(vmode->fbWidth, vmode->xfbHeight);
|
||||||
|
GX_SetCopyFilter(vmode->aa, vmode->sample_pattern, GX_TRUE,
|
||||||
|
vmode->vfilter);
|
||||||
|
GX_SetFieldMode(vmode->field_rendering,
|
||||||
|
((vmode->viHeight ==
|
||||||
|
2 * vmode->xfbHeight) ? GX_ENABLE : GX_DISABLE));
|
||||||
|
GX_SetPixelFmt(GX_PF_RGB8_Z24, GX_ZC_LINEAR);
|
||||||
|
GX_SetCullMode(GX_CULL_NONE);
|
||||||
|
GX_CopyDisp(xfb[whichfb ^ 1], GX_TRUE);
|
||||||
|
GX_SetDispCopyGamma(GX_GM_1_0);
|
||||||
|
|
||||||
|
guPerspective(p, 60, 1.33F, 10.0F, 1000.0F);
|
||||||
|
GX_LoadProjectionMtx(p, GX_PERSPECTIVE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* InitVideoThread
|
* UpdatePadsCB
|
||||||
*
|
*
|
||||||
* libOGC provides a nice wrapper for LWP access.
|
* called by postRetraceCallback in InitGCVideo - scans gcpad and wpad
|
||||||
* This function sets up a new local queue and attaches the thread to it.
|
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
void
|
void
|
||||||
InitVideoThread ()
|
UpdatePadsCB ()
|
||||||
{
|
{
|
||||||
/*** Initialise a new queue ***/
|
#ifdef HW_RVL
|
||||||
LWP_InitQueue (&videoblankqueue);
|
WPAD_ScanPads();
|
||||||
|
|
||||||
/*** Create the thread on this queue ***/
|
|
||||||
LWP_CreateThread (&vbthread, vbgetback, NULL, vbstack, TSTACK, 80);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
PAD_ScanPads();
|
||||||
/****************************************************************************
|
|
||||||
* copy_to_xfb
|
|
||||||
*
|
|
||||||
* Stock code to copy the GX buffer to the current display mode.
|
|
||||||
* Also increments the frameticker, as it's called for each vb.
|
|
||||||
***************************************************************************/
|
|
||||||
static void
|
|
||||||
copy_to_xfb (u32 arg)
|
|
||||||
{
|
|
||||||
if (copynow == GX_TRUE)
|
|
||||||
{
|
|
||||||
GX_CopyDisp (xfb[whichfb], GX_TRUE);
|
|
||||||
GX_Flush ();
|
|
||||||
copynow = GX_FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
FrameTimer++;
|
|
||||||
SMBTimer++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Drawing screen
|
* Initialise Video
|
||||||
***************************************************************************/
|
*
|
||||||
void
|
* Before doing anything in libogc, it's recommended to configure a video
|
||||||
clearscreen ()
|
* output.
|
||||||
|
****************************************************************************/
|
||||||
|
void InitialiseVideo ()
|
||||||
{
|
{
|
||||||
int colour = COLOR_BLACK;
|
/*** Start VIDEO Subsystem ***/
|
||||||
|
VIDEO_Init();
|
||||||
|
|
||||||
whichfb ^= 1;
|
vmode = VIDEO_GetPreferredMode(NULL);
|
||||||
VIDEO_ClearFrameBuffer (vmode, xfb[whichfb], colour);
|
VIDEO_Configure(vmode);
|
||||||
memcpy (xfb[whichfb], &bg, 1280 * 480);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
screenheight = vmode->xfbHeight;
|
||||||
showscreen ()
|
|
||||||
{
|
xfb[0] = (u32 *) MEM_K0_TO_K1 (SYS_AllocateFramebuffer (vmode));
|
||||||
VIDEO_SetNextFramebuffer (xfb[whichfb]);
|
xfb[1] = (u32 *) MEM_K0_TO_K1 (SYS_AllocateFramebuffer (vmode));
|
||||||
VIDEO_Flush ();
|
|
||||||
VIDEO_WaitVSync ();
|
VIDEO_SetNextFramebuffer(xfb[0]);
|
||||||
|
VIDEO_SetBlack(FALSE);
|
||||||
|
VIDEO_Flush();
|
||||||
|
VIDEO_WaitVSync();
|
||||||
|
|
||||||
|
if(vmode->viTVMode&VI_NON_INTERLACE) VIDEO_WaitVSync();
|
||||||
|
VIDEO_SetPostRetraceCallback((VIRetraceCallback)UpdatePadsCB);
|
||||||
|
VIDEO_SetNextFramebuffer(xfb[0]);
|
||||||
|
|
||||||
|
GX_Start();
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
@ -174,26 +155,24 @@ showscreen ()
|
|||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
static void draw_init(void)
|
static void draw_init(void)
|
||||||
{
|
{
|
||||||
GX_ClearVtxDesc ();
|
GX_ClearVtxDesc();
|
||||||
GX_SetVtxDesc (GX_VA_POS, GX_INDEX8);
|
GX_SetVtxDesc(GX_VA_POS, GX_INDEX8);
|
||||||
GX_SetVtxDesc (GX_VA_CLR0, GX_INDEX8);
|
GX_SetVtxDesc(GX_VA_CLR0, GX_INDEX8);
|
||||||
GX_SetVtxDesc (GX_VA_TEX0, GX_DIRECT);
|
GX_SetVtxDesc(GX_VA_TEX0, GX_DIRECT);
|
||||||
|
|
||||||
GX_SetVtxAttrFmt (GX_VTXFMT0, GX_VA_POS, GX_POS_XYZ, GX_S16, 0);
|
GX_SetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_POS_XYZ, GX_S16, 0);
|
||||||
GX_SetVtxAttrFmt (GX_VTXFMT0, GX_VA_CLR0, GX_CLR_RGBA, GX_RGBA8, 0);
|
GX_SetVtxAttrFmt(GX_VTXFMT0, GX_VA_CLR0, GX_CLR_RGBA, GX_RGBA8, 0);
|
||||||
GX_SetVtxAttrFmt (GX_VTXFMT0, GX_VA_TEX0, GX_TEX_ST, GX_F32, 0);
|
GX_SetVtxAttrFmt(GX_VTXFMT0, GX_VA_TEX0, GX_TEX_ST, GX_F32, 0);
|
||||||
|
|
||||||
GX_SetArray (GX_VA_POS, square, 3 * sizeof (s16));
|
GX_SetArray(GX_VA_POS, square, 3 * sizeof(s16));
|
||||||
|
|
||||||
GX_SetNumTexGens (1);
|
GX_SetNumTexGens(1);
|
||||||
GX_SetNumChans (0);
|
GX_SetTexCoordGen(GX_TEXCOORD0, GX_TG_MTX2x4, GX_TG_TEX0, GX_IDENTITY);
|
||||||
|
|
||||||
GX_SetTexCoordGen (GX_TEXCOORD0, GX_TG_MTX2x4, GX_TG_TEX0, GX_IDENTITY);
|
|
||||||
|
|
||||||
GX_InvalidateTexAll();
|
GX_InvalidateTexAll();
|
||||||
memset (&view, 0, sizeof (Mtx));
|
|
||||||
guLookAt(view, &cam.pos, &cam.up, &cam.view);
|
GX_InitTexObj(&texobj, texturemem, vwidth, vheight, GX_TF_RGB565,
|
||||||
GX_LoadPosMtxImm (view, GX_PNMTX0);
|
GX_CLAMP, GX_CLAMP, GX_FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void draw_vert(u8 pos, u8 c, f32 s, f32 t)
|
static void draw_vert(u8 pos, u8 c, f32 s, f32 t)
|
||||||
@ -221,234 +200,23 @@ static void draw_square(Mtx v)
|
|||||||
GX_End();
|
GX_End();
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
* StartGX
|
|
||||||
****************************************************************************/
|
|
||||||
void GX_Start()
|
|
||||||
{
|
|
||||||
Mtx p;
|
|
||||||
|
|
||||||
GXColor background = { 0, 0, 0, 0xff };
|
|
||||||
|
|
||||||
/*** Clear out FIFO area ***/
|
|
||||||
memset (&gp_fifo, 0, DEFAULT_FIFO_SIZE);
|
|
||||||
|
|
||||||
/*** Initialise GX ***/
|
|
||||||
GX_Init (&gp_fifo, DEFAULT_FIFO_SIZE);
|
|
||||||
GX_SetCopyClear (background, 0x00ffffff);
|
|
||||||
|
|
||||||
|
|
||||||
GX_SetViewport (0, 0, vmode->fbWidth, vmode->efbHeight, 0, 1);
|
|
||||||
GX_SetDispCopyYScale ((f32) vmode->xfbHeight / (f32) vmode->efbHeight);
|
|
||||||
GX_SetScissor (0, 0, vmode->fbWidth, vmode->efbHeight);
|
|
||||||
|
|
||||||
GX_SetDispCopySrc (0, 0, vmode->fbWidth, vmode->efbHeight);
|
|
||||||
GX_SetDispCopyDst (vmode->fbWidth, vmode->xfbHeight);
|
|
||||||
GX_SetCopyFilter (vmode->aa, vmode->sample_pattern, GX_TRUE, vmode->vfilter);
|
|
||||||
|
|
||||||
GX_SetFieldMode (vmode->field_rendering, ((vmode->viHeight == 2 * vmode->xfbHeight) ? GX_ENABLE : GX_DISABLE));
|
|
||||||
|
|
||||||
GX_SetPixelFmt (GX_PF_RGB8_Z24, GX_ZC_LINEAR);
|
|
||||||
GX_SetCullMode (GX_CULL_NONE);
|
|
||||||
GX_SetDispCopyGamma (GX_GM_1_0);
|
|
||||||
GX_SetZMode (GX_TRUE, GX_LEQUAL, GX_TRUE);
|
|
||||||
GX_SetColorUpdate (GX_TRUE);
|
|
||||||
|
|
||||||
guPerspective(p, 60, 1.33F, 10.0F, 1000.0F);
|
|
||||||
GX_LoadProjectionMtx(p, GX_PERSPECTIVE);
|
|
||||||
|
|
||||||
GX_SetTevOp(GX_TEVSTAGE0, GX_DECAL);
|
|
||||||
GX_SetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD0, GX_TEXMAP0, GX_COLOR0A0);
|
|
||||||
|
|
||||||
GX_CopyDisp (xfb[whichfb], GX_TRUE); // reset xfb
|
|
||||||
}
|
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
* UpdatePadsCB
|
|
||||||
*
|
|
||||||
* called by postRetraceCallback in InitGCVideo - scans gcpad and wpad
|
|
||||||
***************************************************************************/
|
|
||||||
void
|
|
||||||
UpdatePadsCB ()
|
|
||||||
{
|
|
||||||
#ifdef HW_RVL
|
|
||||||
WPAD_ScanPads();
|
|
||||||
#endif
|
|
||||||
PAD_ScanPads();
|
|
||||||
}
|
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
* Initialise Video
|
|
||||||
*
|
|
||||||
* Before doing anything in libogc, it's recommended to configure a video
|
|
||||||
* output.
|
|
||||||
****************************************************************************/
|
|
||||||
void InitialiseVideo ()
|
|
||||||
{
|
|
||||||
/*** Start VIDEO Subsystem ***/
|
|
||||||
VIDEO_Init();
|
|
||||||
|
|
||||||
vmode = VIDEO_GetPreferredMode(NULL);
|
|
||||||
|
|
||||||
#ifdef HW_DOL
|
|
||||||
/* we have component cables, but the preferred mode is interlaced
|
|
||||||
* why don't we switch into progressive?
|
|
||||||
* on the Wii, the user can do this themselves on their Wii Settings */
|
|
||||||
if(VIDEO_HaveComponentCable() && vmode == &TVNtsc480IntDf)
|
|
||||||
vmode = &TVNtsc480Prog;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
VIDEO_Configure(vmode);
|
|
||||||
|
|
||||||
screenheight = vmode->xfbHeight;
|
|
||||||
|
|
||||||
xfb[0] = (u32 *) MEM_K0_TO_K1 (SYS_AllocateFramebuffer (vmode));
|
|
||||||
xfb[1] = (u32 *) MEM_K0_TO_K1 (SYS_AllocateFramebuffer (vmode));
|
|
||||||
|
|
||||||
// Clear framebuffers etc.
|
|
||||||
VIDEO_ClearFrameBuffer (vmode, xfb[0], COLOR_BLACK);
|
|
||||||
VIDEO_ClearFrameBuffer (vmode, xfb[1], COLOR_BLACK);
|
|
||||||
VIDEO_SetNextFramebuffer (xfb[0]);
|
|
||||||
|
|
||||||
// video callbacks
|
|
||||||
VIDEO_SetPostRetraceCallback ((VIRetraceCallback)UpdatePadsCB);
|
|
||||||
VIDEO_SetPreRetraceCallback ((VIRetraceCallback)copy_to_xfb);
|
|
||||||
|
|
||||||
VIDEO_SetNextFramebuffer(xfb[0]);
|
|
||||||
VIDEO_SetBlack(FALSE);
|
|
||||||
|
|
||||||
// set timings in VI to PAL60
|
|
||||||
/*u32 *vreg = (u32 *)0xCC002000;
|
|
||||||
for (int i = 0; i < 64; i++ )
|
|
||||||
vreg[i] = vpal60[i];*/
|
|
||||||
|
|
||||||
VIDEO_Flush();
|
|
||||||
VIDEO_WaitVSync();
|
|
||||||
|
|
||||||
if(vmode->viTVMode&VI_NON_INTERLACE)
|
|
||||||
VIDEO_WaitVSync();
|
|
||||||
|
|
||||||
copynow = GX_FALSE;
|
|
||||||
GX_Start();
|
|
||||||
|
|
||||||
#ifdef VIDEO_THREADING
|
|
||||||
InitVideoThread ();
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
* ResetVideo_Emu
|
|
||||||
*
|
|
||||||
* Reset the video/rendering mode for the emulator rendering
|
|
||||||
****************************************************************************/
|
|
||||||
void
|
|
||||||
ResetVideo_Emu ()
|
|
||||||
{
|
|
||||||
GXRModeObj *rmode;
|
|
||||||
|
|
||||||
rmode = vmode; // same mode as menu
|
|
||||||
|
|
||||||
VIDEO_Configure (rmode);
|
|
||||||
VIDEO_ClearFrameBuffer (rmode, xfb[0], COLOR_BLACK);
|
|
||||||
VIDEO_ClearFrameBuffer (rmode, xfb[1], COLOR_BLACK);
|
|
||||||
VIDEO_Flush();
|
|
||||||
VIDEO_WaitVSync();
|
|
||||||
if (rmode->viTVMode & VI_NON_INTERLACE) VIDEO_WaitVSync();
|
|
||||||
else while (VIDEO_GetNextField()) VIDEO_WaitVSync();
|
|
||||||
|
|
||||||
GX_SetViewport (0, 0, rmode->fbWidth, rmode->efbHeight, 0, 1);
|
|
||||||
GX_SetDispCopyYScale ((f32) rmode->xfbHeight / (f32) rmode->efbHeight);
|
|
||||||
GX_SetScissor (0, 0, rmode->fbWidth, rmode->efbHeight);
|
|
||||||
|
|
||||||
GX_SetDispCopySrc (0, 0, rmode->fbWidth, rmode->efbHeight);
|
|
||||||
GX_SetDispCopyDst (rmode->fbWidth, rmode->xfbHeight);
|
|
||||||
GX_SetCopyFilter (rmode->aa, rmode->sample_pattern, (GCSettings.render == 0) ? GX_TRUE : GX_FALSE, rmode->vfilter); // AA on only for filtered mode
|
|
||||||
|
|
||||||
GX_SetFieldMode (rmode->field_rendering, ((rmode->viHeight == 2 * rmode->xfbHeight) ? GX_ENABLE : GX_DISABLE));
|
|
||||||
GX_SetPixelFmt (GX_PF_RGB8_Z24, GX_ZC_LINEAR);
|
|
||||||
}
|
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
* ResetVideo_Menu
|
|
||||||
*
|
|
||||||
* Reset the video/rendering mode for the menu
|
|
||||||
****************************************************************************/
|
|
||||||
void
|
|
||||||
ResetVideo_Menu ()
|
|
||||||
{
|
|
||||||
VIDEO_Configure (vmode);
|
|
||||||
VIDEO_ClearFrameBuffer (vmode, xfb[whichfb], COLOR_BLACK);
|
|
||||||
VIDEO_Flush();
|
|
||||||
VIDEO_WaitVSync();
|
|
||||||
if (vmode->viTVMode & VI_NON_INTERLACE) VIDEO_WaitVSync();
|
|
||||||
else while (VIDEO_GetNextField()) VIDEO_WaitVSync();
|
|
||||||
|
|
||||||
GX_SetViewport (0, 0, vmode->fbWidth, vmode->efbHeight, 0, 1);
|
|
||||||
GX_SetDispCopyYScale ((f32) vmode->xfbHeight / (f32) vmode->efbHeight);
|
|
||||||
GX_SetScissor (0, 0, vmode->fbWidth, vmode->efbHeight);
|
|
||||||
|
|
||||||
GX_SetDispCopySrc (0, 0, vmode->fbWidth, vmode->efbHeight);
|
|
||||||
GX_SetDispCopyDst (vmode->fbWidth, vmode->xfbHeight);
|
|
||||||
GX_SetCopyFilter (vmode->aa, vmode->sample_pattern, GX_TRUE, vmode->vfilter);
|
|
||||||
|
|
||||||
GX_SetFieldMode (vmode->field_rendering, ((vmode->viHeight == 2 * vmode->xfbHeight) ? GX_ENABLE : GX_DISABLE));
|
|
||||||
GX_SetPixelFmt (GX_PF_RGB8_Z24, GX_ZC_LINEAR);
|
|
||||||
}
|
|
||||||
|
|
||||||
void UpdateScaling()
|
|
||||||
{
|
|
||||||
// Update scaling
|
|
||||||
int xscale = video_haspect;
|
|
||||||
int yscale = video_vaspect;
|
|
||||||
|
|
||||||
// change zoom
|
|
||||||
xscale *= zoom_level;
|
|
||||||
yscale *= zoom_level;
|
|
||||||
|
|
||||||
// Set new aspect (now with crap AR hack!)
|
|
||||||
square[0] = square[9] = (-xscale - 7);
|
|
||||||
square[3] = square[6] = (xscale + 7);
|
|
||||||
square[1] = square[4] = (yscale + 7);
|
|
||||||
square[7] = square[10] = (-yscale - 7);
|
|
||||||
|
|
||||||
GX_InvVtxCache (); // update vertex cache
|
|
||||||
|
|
||||||
GX_InitTexObj (&texobj, texturemem, vwidth, vheight, GX_TF_RGB565, GX_CLAMP, GX_CLAMP, GX_FALSE); // initialize the texture obj we are going to use
|
|
||||||
|
|
||||||
if (GCSettings.render == 1)
|
|
||||||
GX_InitTexObjLOD(&texobj,GX_NEAR,GX_NEAR_MIP_NEAR,2.5,9.0,0.0,GX_FALSE,GX_FALSE,GX_ANISO_1); // original/unfiltered video mode: force texture filtering OFF
|
|
||||||
|
|
||||||
GX_LoadTexObj (&texobj, GX_TEXMAP0); // load texture object so its ready to use
|
|
||||||
|
|
||||||
draw_init();
|
|
||||||
updateScaling = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void GX_Render_Init(int width, int height, int haspect, int vaspect)
|
void GX_Render_Init(int width, int height, int haspect, int vaspect)
|
||||||
{
|
{
|
||||||
ResetVideo_Emu (); // reset video to emulator rendering settings
|
/*** Set new aspect (now with crap AR hack!) ***/
|
||||||
|
square[0] = square[9] = (-haspect - 7);
|
||||||
if (texturemem)
|
square[3] = square[6] = (haspect + 7);
|
||||||
free(texturemem);
|
square[1] = square[4] = (vaspect + 7);
|
||||||
|
square[7] = square[10] = (-vaspect - 7);
|
||||||
|
|
||||||
/*** Allocate 32byte aligned texture memory ***/
|
/*** Allocate 32byte aligned texture memory ***/
|
||||||
texturesize = (width * height) * 2;
|
texturesize = (width * height) * 2;
|
||||||
|
|
||||||
texturemem = (u8 *) memalign(32, texturesize);
|
texturemem = (u8 *) memalign(32, texturesize);
|
||||||
|
|
||||||
memset(texturemem, 0, texturesize);
|
memset(texturemem, 0, texturesize);
|
||||||
|
|
||||||
/*** Setup for first call to scaler ***/
|
/*** Setup for first call to scaler ***/
|
||||||
vwidth = width;
|
vwidth = vheight = oldvwidth = oldvheight = -1;
|
||||||
vheight = height;
|
|
||||||
oldvwidth = oldvheight = -1;
|
|
||||||
|
|
||||||
video_vaspect = vaspect;
|
|
||||||
video_haspect = haspect;
|
|
||||||
|
|
||||||
UpdateScaling();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* GX_Render
|
* GX_Render
|
||||||
*
|
*
|
||||||
@ -469,30 +237,24 @@ void GX_Render(int width, int height, u8 * buffer, int pitch)
|
|||||||
vwidth = width;
|
vwidth = width;
|
||||||
vheight = height;
|
vheight = height;
|
||||||
|
|
||||||
#ifdef VIDEO_THREADING
|
|
||||||
// Ensure previous vb has complete
|
|
||||||
while ((LWP_ThreadIsSuspended (vbthread) == 0) || (copynow == GX_TRUE))
|
|
||||||
#else
|
|
||||||
while (copynow == GX_TRUE)
|
|
||||||
#endif
|
|
||||||
{
|
|
||||||
usleep (50);
|
|
||||||
}
|
|
||||||
|
|
||||||
whichfb ^= 1;
|
whichfb ^= 1;
|
||||||
|
|
||||||
if(updateScaling)
|
|
||||||
{
|
|
||||||
UpdateScaling();
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((oldvheight != vheight) || (oldvwidth != vwidth))
|
if ((oldvheight != vheight) || (oldvwidth != vwidth))
|
||||||
{
|
{
|
||||||
|
/** Update scaling **/
|
||||||
oldvwidth = vwidth;
|
oldvwidth = vwidth;
|
||||||
oldvheight = vheight;
|
oldvheight = vheight;
|
||||||
updateScaling = 1;
|
draw_init();
|
||||||
|
memset(&view, 0, sizeof(Mtx));
|
||||||
|
guLookAt(view, &cam.pos, &cam.up, &cam.view);
|
||||||
|
GX_SetViewport(0, 0, vmode->fbWidth, vmode->efbHeight, 0, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GX_InvVtxCache();
|
||||||
|
GX_InvalidateTexAll();
|
||||||
|
GX_SetTevOp(GX_TEVSTAGE0, GX_DECAL);
|
||||||
|
GX_SetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD0, GX_TEXMAP0, GX_COLOR0A0);
|
||||||
|
|
||||||
for (h = 0; h < vheight; h += 4)
|
for (h = 0; h < vheight; h += 4)
|
||||||
{
|
{
|
||||||
for (w = 0; w < (vwidth >> 2); w++)
|
for (w = 0; w < (vwidth >> 2); w++)
|
||||||
@ -522,43 +284,49 @@ void GX_Render(int width, int height, u8 * buffer, int pitch)
|
|||||||
}
|
}
|
||||||
|
|
||||||
DCFlushRange(texturemem, texturesize);
|
DCFlushRange(texturemem, texturesize);
|
||||||
GX_InvalidateTexAll ();
|
|
||||||
|
GX_SetNumChans(1);
|
||||||
|
GX_LoadTexObj(&texobj, GX_TEXMAP0);
|
||||||
|
|
||||||
draw_square(view);
|
draw_square(view);
|
||||||
|
|
||||||
GX_DrawDone();
|
GX_DrawDone();
|
||||||
|
|
||||||
|
GX_SetZMode(GX_TRUE, GX_LEQUAL, GX_TRUE);
|
||||||
|
GX_SetColorUpdate(GX_TRUE);
|
||||||
|
GX_CopyDisp(xfb[whichfb], GX_TRUE);
|
||||||
|
GX_Flush();
|
||||||
|
|
||||||
VIDEO_SetNextFramebuffer(xfb[whichfb]);
|
VIDEO_SetNextFramebuffer(xfb[whichfb]);
|
||||||
VIDEO_Flush();
|
VIDEO_Flush();
|
||||||
copynow = GX_TRUE;
|
//VIDEO_WaitVSync();
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef VIDEO_THREADING
|
|
||||||
// Return to caller, don't waste time waiting for vb
|
/****************************************************************************
|
||||||
LWP_ResumeThread (vbthread);
|
* Drawing screen
|
||||||
|
***************************************************************************/
|
||||||
|
void
|
||||||
|
clearscreen (int c)
|
||||||
|
{
|
||||||
|
int colour = COLOR_WHITE;
|
||||||
|
|
||||||
|
whichfb ^= 1;
|
||||||
|
VIDEO_ClearFrameBuffer (vmode, xfb[whichfb], colour);
|
||||||
|
#ifdef HW_RVL
|
||||||
|
// on wii copy from memory
|
||||||
|
//memcpy ((char *) xfb[whichfb], (char *) backdrop, 640 * screenheight * 2);
|
||||||
|
#else
|
||||||
|
// on gc copy from aram
|
||||||
|
//ARAMFetch ((char *) xfb[whichfb], (char *) AR_BACKDROP, 640 * screenheight * 2);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
* Zoom Functions
|
|
||||||
***************************************************************************/
|
|
||||||
void
|
void
|
||||||
zoom (float speed)
|
showscreen ()
|
||||||
{
|
{
|
||||||
if (zoom_level > 1)
|
copynow = GX_FALSE;
|
||||||
zoom_level += (speed / -100.0);
|
VIDEO_SetNextFramebuffer (xfb[whichfb]);
|
||||||
else
|
VIDEO_Flush ();
|
||||||
zoom_level += (speed / -200.0);
|
VIDEO_WaitVSync ();
|
||||||
|
|
||||||
if (zoom_level < 0.5) zoom_level = 0.5;
|
|
||||||
else if (zoom_level > 10.0) zoom_level = 10.0;
|
|
||||||
|
|
||||||
oldvheight = 0; // update video
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
zoom_reset ()
|
|
||||||
{
|
|
||||||
zoom_level = 1.0;
|
|
||||||
|
|
||||||
oldvheight = 0; // update video
|
|
||||||
}
|
}
|
||||||
|
@ -15,13 +15,9 @@
|
|||||||
#define __GXHDR__
|
#define __GXHDR__
|
||||||
|
|
||||||
void InitialiseVideo ();
|
void InitialiseVideo ();
|
||||||
void GX_Start();
|
|
||||||
void GX_Render_Init(int width, int height, int haspect, int vaspect);
|
void GX_Render_Init(int width, int height, int haspect, int vaspect);
|
||||||
void GX_Render(int width, int height, u8 * buffer, int pitch);
|
void GX_Render(int width, int height, u8 * buffer, int pitch);
|
||||||
void clearscreen ();
|
void clearscreen (int colour = COLOR_BLACK);
|
||||||
void showscreen ();
|
void showscreen ();
|
||||||
void zoom (float speed);
|
|
||||||
void zoom_reset ();
|
|
||||||
void ResetVideo_Menu ();
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -9,6 +9,7 @@
|
|||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
|
|
||||||
#ifdef HW_RVL
|
#ifdef HW_RVL
|
||||||
|
#include "sdfileio.h"
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
@ -16,18 +17,12 @@
|
|||||||
#include <fat.h>
|
#include <fat.h>
|
||||||
#include <sys/dir.h>
|
#include <sys/dir.h>
|
||||||
|
|
||||||
#include "agb/GBA.h"
|
#include "GBA.h"
|
||||||
#include "Globals.h"
|
#include "Globals.h"
|
||||||
#include "Util.h"
|
#include "Util.h"
|
||||||
#include "Port.h"
|
#include "Port.h"
|
||||||
|
|
||||||
#include "vba.h"
|
|
||||||
#include "smbop.h"
|
|
||||||
#include "fileop.h"
|
|
||||||
#include "dvd.h"
|
|
||||||
#include "menudraw.h"
|
#include "menudraw.h"
|
||||||
#include "filesel.h"
|
|
||||||
#include "gcunzip.h"
|
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#include "tbtime.h"
|
#include "tbtime.h"
|
||||||
@ -40,7 +35,9 @@ extern "C" {
|
|||||||
unsigned int MEM2Storage = 0x91000000;
|
unsigned int MEM2Storage = 0x91000000;
|
||||||
|
|
||||||
static char *gbabase = NULL;
|
static char *gbabase = NULL;
|
||||||
|
static FILE *romfile = NULL;
|
||||||
static u32 GBAROMSize = 0;
|
static u32 GBAROMSize = 0;
|
||||||
|
static char romfilename[1024];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* GBA Memory
|
* GBA Memory
|
||||||
@ -91,7 +88,12 @@ static void VMClose( void )
|
|||||||
if ( gbabase != NULL )
|
if ( gbabase != NULL )
|
||||||
free(gbabase);
|
free(gbabase);
|
||||||
|
|
||||||
|
if ( romfile != NULL )
|
||||||
|
gen_fclose(romfile);
|
||||||
|
|
||||||
gbabase = NULL;
|
gbabase = NULL;
|
||||||
|
romfile = NULL;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
@ -99,49 +101,49 @@ static void VMClose( void )
|
|||||||
*
|
*
|
||||||
* MEM2 version of GBA CPULoadROM
|
* MEM2 version of GBA CPULoadROM
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
int VMCPULoadROM( char *filename )
|
||||||
bool VMCPULoadROM(int method)
|
|
||||||
{
|
{
|
||||||
VMClose();
|
int res=0;
|
||||||
VMAllocGBA();
|
char temp[512];
|
||||||
GBAROMSize = 0;
|
VMClose();
|
||||||
|
VMAllocGBA();
|
||||||
|
|
||||||
|
GBAROMSize = 0;
|
||||||
|
|
||||||
|
sprintf(temp,"Filename %s\n", filename);
|
||||||
|
//WaitPrompt(temp);
|
||||||
|
|
||||||
|
romfile = gen_fopen(filename, "rb");
|
||||||
|
if ( romfile == NULL )
|
||||||
|
{
|
||||||
|
WaitPrompt((char*) "Error opening file!");
|
||||||
|
//while(1);
|
||||||
|
VMClose();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
fseek(romfile, 0, SEEK_END);
|
||||||
|
GBAROMSize = ftell(romfile);
|
||||||
|
fseek(romfile, 0, SEEK_SET);
|
||||||
|
|
||||||
|
sprintf(temp,"ROM Size %dMb (%dMBit)", GBAROMSize/1024/1024,(GBAROMSize*8)/1024/1024);
|
||||||
|
//WaitPrompt(temp);
|
||||||
|
|
||||||
rom = (u8 *)MEM2Storage;
|
rom = (u8 *)MEM2Storage;
|
||||||
|
|
||||||
switch (method)
|
/* Always use MEM2, regardless of ROM size */
|
||||||
{
|
res = gen_fread(rom, 1, GBAROMSize, romfile);
|
||||||
case METHOD_SD:
|
|
||||||
case METHOD_USB:
|
|
||||||
if(inSz)
|
|
||||||
GBAROMSize = LoadFATSzFile(szpath, (unsigned char *)rom);
|
|
||||||
else
|
|
||||||
GBAROMSize = LoadFATFile((char *)rom, filelist[selection].length);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case METHOD_DVD:
|
if ( (u32)res != GBAROMSize )
|
||||||
if(inSz)
|
{
|
||||||
GBAROMSize = SzExtractFile(filelist[selection].offset, (unsigned char *)rom);
|
WaitPrompt((char*) "Error reading file!");
|
||||||
else
|
while(1);
|
||||||
GBAROMSize = LoadDVDFile((unsigned char *)rom, filelist[selection].length);
|
}
|
||||||
break;
|
strcpy( romfilename, filename );
|
||||||
|
|
||||||
case METHOD_SMB:
|
CPUUpdateRenderBuffers( true );
|
||||||
if(inSz)
|
|
||||||
GBAROMSize = LoadSMBSzFile(szpath, (unsigned char *)rom);
|
|
||||||
else
|
|
||||||
GBAROMSize = LoadSMBFile((char *)rom, filelist[selection].length);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(GBAROMSize)
|
return 1;
|
||||||
{
|
|
||||||
CPUUpdateRenderBuffers( true );
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
VMClose();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -161,6 +163,8 @@ u32 VMRead32( u32 address )
|
|||||||
}
|
}
|
||||||
|
|
||||||
return READ32LE((rom + address));
|
return READ32LE((rom + address));
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
@ -198,20 +202,18 @@ u8 VMRead8( u32 address )
|
|||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
|
|
||||||
|
#include "sdfileio.h"
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <malloc.h>
|
#include <malloc.h>
|
||||||
|
|
||||||
#include "agb/GBA.h"
|
#include "GBA.h"
|
||||||
#include "Globals.h"
|
#include "Globals.h"
|
||||||
#include "Util.h"
|
#include "Util.h"
|
||||||
#include "Port.h"
|
#include "Port.h"
|
||||||
|
|
||||||
#include "menudraw.h"
|
#include "menudraw.h"
|
||||||
#include "filesel.h"
|
|
||||||
#include "vba.h"
|
|
||||||
#include "fileop.h"
|
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#include "tbtime.h"
|
#include "tbtime.h"
|
||||||
@ -245,8 +247,9 @@ static int vmpageno = 0;
|
|||||||
static char *rombase = NULL;
|
static char *rombase = NULL;
|
||||||
static char *gbabase = NULL;
|
static char *gbabase = NULL;
|
||||||
static FILE* romfile = NULL;
|
static FILE* romfile = NULL;
|
||||||
static int useVM = 1;
|
static int useVM = 0;
|
||||||
static u32 GBAROMSize = 0;
|
static u32 GBAROMSize = 0;
|
||||||
|
static char romfilename[1024];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* GBA Memory
|
* GBA Memory
|
||||||
@ -362,7 +365,7 @@ static void VMClose( void )
|
|||||||
free(gbabase);
|
free(gbabase);
|
||||||
|
|
||||||
if ( romfile != NULL )
|
if ( romfile != NULL )
|
||||||
fclose(romfile);
|
gen_fclose(romfile);
|
||||||
|
|
||||||
rombase = gbabase = NULL;
|
rombase = gbabase = NULL;
|
||||||
romfile = NULL;
|
romfile = NULL;
|
||||||
@ -374,77 +377,54 @@ static void VMClose( void )
|
|||||||
*
|
*
|
||||||
* VM version of GBA CPULoadROM
|
* VM version of GBA CPULoadROM
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
int VMCPULoadROM( char *filename )
|
||||||
int VMCPULoadROM(int method)
|
|
||||||
{
|
{
|
||||||
int res;
|
int res;
|
||||||
char msg[512];
|
char msg[512];
|
||||||
char filepath[MAXPATHLEN];
|
|
||||||
|
|
||||||
/** Fix VM **/
|
/** Fix VM **/
|
||||||
VMClose();
|
VMClose();
|
||||||
VMInit();
|
VMInit();
|
||||||
VMAllocGBA();
|
VMAllocGBA();
|
||||||
|
|
||||||
loadtimeradjust = GBAROMSize = 0;
|
loadtimeradjust = useVM = GBAROMSize = 0;
|
||||||
|
|
||||||
switch (method)
|
printf("Filename %s\n", filename);
|
||||||
{
|
|
||||||
case METHOD_SD:
|
|
||||||
case METHOD_USB:
|
|
||||||
break;
|
|
||||||
|
|
||||||
case METHOD_DVD:
|
romfile = gen_fopen(filename, "rb");
|
||||||
VMClose();
|
if ( romfile == NULL )
|
||||||
return 0; // not implemented
|
{
|
||||||
break;
|
WaitPrompt((char*) "Error opening file!");
|
||||||
|
while(1);
|
||||||
|
VMClose();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
case METHOD_SMB:
|
// printf("ROM Size %d\n", romfile->fsize);
|
||||||
VMClose();
|
|
||||||
return 0; // not implemented
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Check filename length */
|
/* Always use VM, regardless of ROM size */
|
||||||
if ((strlen(currentdir)+1+strlen(filelist[selection].filename)) < MAXPATHLEN)
|
res = gen_fread(rom, 1, (1 << VMSHIFTBITS), romfile);
|
||||||
sprintf(filepath, "%s/%s",currentdir,filelist[selection].filename);
|
if ( res != (1 << VMSHIFTBITS ) )
|
||||||
else
|
{
|
||||||
{
|
|
||||||
WaitPrompt((char*) "Maximum filepath length reached!");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
romfile = fopen(filepath, "rb");
|
|
||||||
if ( romfile == NULL )
|
|
||||||
{
|
|
||||||
WaitPrompt((char*) "Error opening file!");
|
|
||||||
VMClose();
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// printf("ROM Size %d\n", romfile->fsize);
|
|
||||||
|
|
||||||
/* Always use VM, regardless of ROM size */
|
|
||||||
res = fread(rom, 1, (1 << VMSHIFTBITS), romfile);
|
|
||||||
if ( res != (1 << VMSHIFTBITS ) )
|
|
||||||
{
|
|
||||||
sprintf(msg, "Error reading file! %i \n",res);
|
sprintf(msg, "Error reading file! %i \n",res);
|
||||||
WaitPrompt(msg);
|
WaitPrompt(msg);
|
||||||
VMClose();
|
while(1);
|
||||||
return 0;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
fseek(romfile, 0, SEEK_END);
|
fseek(romfile, 0, SEEK_END);
|
||||||
GBAROMSize = ftell(romfile);
|
GBAROMSize = ftell(romfile);
|
||||||
fseek(romfile, 0, SEEK_SET);
|
fseek(romfile, 0, SEEK_SET);
|
||||||
vmpageno = 0;
|
vmpageno = 0;
|
||||||
vmpage[0].pageptr = rombase;
|
vmpage[0].pageptr = rombase;
|
||||||
vmpage[0].pageno = 0;
|
vmpage[0].pageno = 0;
|
||||||
vmpage[0].pagetype = MEM_VM;
|
vmpage[0].pagetype = MEM_VM;
|
||||||
|
useVM = 1;
|
||||||
|
|
||||||
CPUUpdateRenderBuffers( true );
|
strcpy( romfilename, filename );
|
||||||
|
|
||||||
return 1;
|
CPUUpdateRenderBuffers( true );
|
||||||
|
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
@ -461,24 +441,22 @@ static void VMNewPage( int pageid )
|
|||||||
|
|
||||||
mftb(&start);
|
mftb(&start);
|
||||||
|
|
||||||
res = fseek( romfile, pageid << VMSHIFTBITS, SEEK_SET );
|
res = gen_fseek( romfile, pageid << VMSHIFTBITS, SEEK_SET );
|
||||||
if ( ! res )
|
if ( ! res )
|
||||||
{
|
{
|
||||||
sprintf(msg, "Seek error! - Offset %08x %d\n", pageid << VMSHIFTBITS, res);
|
sprintf(msg, "Seek error! - Offset %08x %d\n", pageid << VMSHIFTBITS, res);
|
||||||
WaitPrompt(msg);
|
WaitPrompt(msg);
|
||||||
VMClose();
|
while(1);
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
VMAllocate( pageid );
|
VMAllocate( pageid );
|
||||||
|
|
||||||
res = fread( vmpage[pageid].pageptr, 1, 1 << VMSHIFTBITS, romfile );
|
res = gen_fread( vmpage[pageid].pageptr, 1, 1 << VMSHIFTBITS, romfile );
|
||||||
if ( res != ( 1 << VMSHIFTBITS ) )
|
if ( res != ( 1 << VMSHIFTBITS ) )
|
||||||
{
|
{
|
||||||
sprintf(msg, "Error reading! %d bytes only\n", res);
|
sprintf(msg, "Error reading! %d bytes only\n", res);
|
||||||
WaitPrompt(msg);
|
WaitPrompt(msg);
|
||||||
VMClose();
|
while(1);
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
mftb(&end);
|
mftb(&end);
|
||||||
@ -538,8 +516,7 @@ u32 VMRead32( u32 address )
|
|||||||
default:
|
default:
|
||||||
sprintf(msg, "VM32 : Unknown page type! (%d) [%d]", vmpage[pageid].pagetype, pageid);
|
sprintf(msg, "VM32 : Unknown page type! (%d) [%d]", vmpage[pageid].pagetype, pageid);
|
||||||
WaitPrompt(msg);
|
WaitPrompt(msg);
|
||||||
VMClose();
|
while(1);
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Can never get here ... but stops gcc bitchin' */
|
/* Can never get here ... but stops gcc bitchin' */
|
||||||
@ -578,8 +555,7 @@ u16 VMRead16( u32 address )
|
|||||||
|
|
||||||
default:
|
default:
|
||||||
WaitPrompt((char*) "VM16 : Unknown page type!");
|
WaitPrompt((char*) "VM16 : Unknown page type!");
|
||||||
VMClose();
|
while(1);
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Can never get here ... but stops gcc bitchin' */
|
/* Can never get here ... but stops gcc bitchin' */
|
||||||
@ -618,8 +594,7 @@ u8 VMRead8( u32 address )
|
|||||||
|
|
||||||
default:
|
default:
|
||||||
WaitPrompt((char*) "VM8 : Unknown page type!");
|
WaitPrompt((char*) "VM8 : Unknown page type!");
|
||||||
VMClose();
|
while(1);
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Can never get here ... but stops gcc bitchin' */
|
/* Can never get here ... but stops gcc bitchin' */
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
#ifndef __VBAVMHDR__
|
#ifndef __VBAVMHDR__
|
||||||
#define __VBAVMHDR__
|
#define __VBAVMHDR__
|
||||||
|
|
||||||
bool VMCPULoadROM(int method);
|
int VMCPULoadROM( char *filename );
|
||||||
u32 VMRead32( u32 address );
|
u32 VMRead32( u32 address );
|
||||||
u16 VMRead16( u32 address );
|
u16 VMRead16( u32 address );
|
||||||
u8 VMRead8( u32 address );
|
u8 VMRead8( u32 address );
|
||||||
|
@ -1,70 +0,0 @@
|
|||||||
/* 7zAlloc.c */
|
|
||||||
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include "7zAlloc.h"
|
|
||||||
|
|
||||||
/* #define _SZ_ALLOC_DEBUG */
|
|
||||||
/* use _SZ_ALLOC_DEBUG to debug alloc/free operations */
|
|
||||||
|
|
||||||
#ifdef _SZ_ALLOC_DEBUG
|
|
||||||
|
|
||||||
#ifdef _WIN32
|
|
||||||
#include <windows.h>
|
|
||||||
#endif
|
|
||||||
#include <stdio.h>
|
|
||||||
int g_allocCount = 0;
|
|
||||||
int g_allocCountTemp = 0;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void *SzAlloc(size_t size)
|
|
||||||
{
|
|
||||||
if (size == 0)
|
|
||||||
return 0;
|
|
||||||
#ifdef _SZ_ALLOC_DEBUG
|
|
||||||
fprintf(stderr, "\nAlloc %10d bytes; count = %10d", size, g_allocCount);
|
|
||||||
g_allocCount++;
|
|
||||||
#endif
|
|
||||||
return malloc(size);
|
|
||||||
}
|
|
||||||
|
|
||||||
void SzFree(void *address)
|
|
||||||
{
|
|
||||||
#ifdef _SZ_ALLOC_DEBUG
|
|
||||||
if (address != 0)
|
|
||||||
{
|
|
||||||
g_allocCount--;
|
|
||||||
fprintf(stderr, "\nFree; count = %10d", g_allocCount);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
free(address);
|
|
||||||
}
|
|
||||||
|
|
||||||
void *SzAllocTemp(size_t size)
|
|
||||||
{
|
|
||||||
if (size == 0)
|
|
||||||
return 0;
|
|
||||||
#ifdef _SZ_ALLOC_DEBUG
|
|
||||||
fprintf(stderr, "\nAlloc_temp %10d bytes; count = %10d", size, g_allocCountTemp);
|
|
||||||
g_allocCountTemp++;
|
|
||||||
#ifdef _WIN32
|
|
||||||
return HeapAlloc(GetProcessHeap(), 0, size);
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
return malloc(size);
|
|
||||||
}
|
|
||||||
|
|
||||||
void SzFreeTemp(void *address)
|
|
||||||
{
|
|
||||||
#ifdef _SZ_ALLOC_DEBUG
|
|
||||||
if (address != 0)
|
|
||||||
{
|
|
||||||
g_allocCountTemp--;
|
|
||||||
fprintf(stderr, "\nFree_temp; count = %10d", g_allocCountTemp);
|
|
||||||
}
|
|
||||||
#ifdef _WIN32
|
|
||||||
HeapFree(GetProcessHeap(), 0, address);
|
|
||||||
return;
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
free(address);
|
|
||||||
}
|
|
@ -1,20 +0,0 @@
|
|||||||
/* 7zAlloc.h */
|
|
||||||
|
|
||||||
#ifndef __7Z_ALLOC_H
|
|
||||||
#define __7Z_ALLOC_H
|
|
||||||
|
|
||||||
#include <stddef.h>
|
|
||||||
|
|
||||||
typedef struct _ISzAlloc
|
|
||||||
{
|
|
||||||
void *(*Alloc)(size_t size);
|
|
||||||
void (*Free)(void *address); /* address can be 0 */
|
|
||||||
} ISzAlloc;
|
|
||||||
|
|
||||||
void *SzAlloc(size_t size);
|
|
||||||
void SzFree(void *address);
|
|
||||||
|
|
||||||
void *SzAllocTemp(size_t size);
|
|
||||||
void SzFreeTemp(void *address);
|
|
||||||
|
|
||||||
#endif
|
|
@ -1,29 +0,0 @@
|
|||||||
/* 7zBuffer.c */
|
|
||||||
|
|
||||||
#include "7zBuffer.h"
|
|
||||||
#include "7zAlloc.h"
|
|
||||||
|
|
||||||
void SzByteBufferInit(CSzByteBuffer *buffer)
|
|
||||||
{
|
|
||||||
buffer->Capacity = 0;
|
|
||||||
buffer->Items = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int SzByteBufferCreate(CSzByteBuffer *buffer, size_t newCapacity, void * (*allocFunc)(size_t size))
|
|
||||||
{
|
|
||||||
buffer->Capacity = newCapacity;
|
|
||||||
if (newCapacity == 0)
|
|
||||||
{
|
|
||||||
buffer->Items = 0;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
buffer->Items = (Byte *)allocFunc(newCapacity);
|
|
||||||
return (buffer->Items != 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void SzByteBufferFree(CSzByteBuffer *buffer, void (*freeFunc)(void *))
|
|
||||||
{
|
|
||||||
freeFunc(buffer->Items);
|
|
||||||
buffer->Items = 0;
|
|
||||||
buffer->Capacity = 0;
|
|
||||||
}
|
|
@ -1,19 +0,0 @@
|
|||||||
/* 7zBuffer.h */
|
|
||||||
|
|
||||||
#ifndef __7Z_BUFFER_H
|
|
||||||
#define __7Z_BUFFER_H
|
|
||||||
|
|
||||||
#include <stddef.h>
|
|
||||||
#include "7zTypes.h"
|
|
||||||
|
|
||||||
typedef struct _CSzByteBuffer
|
|
||||||
{
|
|
||||||
size_t Capacity;
|
|
||||||
Byte *Items;
|
|
||||||
}CSzByteBuffer;
|
|
||||||
|
|
||||||
void SzByteBufferInit(CSzByteBuffer *buffer);
|
|
||||||
int SzByteBufferCreate(CSzByteBuffer *buffer, size_t newCapacity, void * (*allocFunc)(size_t size));
|
|
||||||
void SzByteBufferFree(CSzByteBuffer *buffer, void (*freeFunc)(void *));
|
|
||||||
|
|
||||||
#endif
|
|
@ -1,76 +0,0 @@
|
|||||||
/* 7zCrc.c */
|
|
||||||
|
|
||||||
#include "7zCrc.h"
|
|
||||||
|
|
||||||
#define kCrcPoly 0xEDB88320
|
|
||||||
|
|
||||||
UInt32 g_CrcTable[256];
|
|
||||||
|
|
||||||
void InitCrcTable()
|
|
||||||
{
|
|
||||||
UInt32 i;
|
|
||||||
for (i = 0; i < 256; i++)
|
|
||||||
{
|
|
||||||
UInt32 r = i;
|
|
||||||
int j;
|
|
||||||
for (j = 0; j < 8; j++)
|
|
||||||
if (r & 1)
|
|
||||||
r = (r >> 1) ^ kCrcPoly;
|
|
||||||
else
|
|
||||||
r >>= 1;
|
|
||||||
g_CrcTable[i] = r;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void CrcInit(UInt32 *crc) { *crc = 0xFFFFFFFF; }
|
|
||||||
UInt32 CrcGetDigest(UInt32 *crc) { return *crc ^ 0xFFFFFFFF; }
|
|
||||||
|
|
||||||
void CrcUpdateByte(UInt32 *crc, Byte b)
|
|
||||||
{
|
|
||||||
*crc = g_CrcTable[((Byte)(*crc)) ^ b] ^ (*crc >> 8);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CrcUpdateUInt16(UInt32 *crc, UInt16 v)
|
|
||||||
{
|
|
||||||
CrcUpdateByte(crc, (Byte)v);
|
|
||||||
CrcUpdateByte(crc, (Byte)(v >> 8));
|
|
||||||
}
|
|
||||||
|
|
||||||
void CrcUpdateUInt32(UInt32 *crc, UInt32 v)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
for (i = 0; i < 4; i++)
|
|
||||||
CrcUpdateByte(crc, (Byte)(v >> (8 * i)));
|
|
||||||
}
|
|
||||||
|
|
||||||
void CrcUpdateUInt64(UInt32 *crc, UInt64 v)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
for (i = 0; i < 8; i++)
|
|
||||||
{
|
|
||||||
CrcUpdateByte(crc, (Byte)(v));
|
|
||||||
v >>= 8;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void CrcUpdate(UInt32 *crc, const void *data, size_t size)
|
|
||||||
{
|
|
||||||
UInt32 v = *crc;
|
|
||||||
const Byte *p = (const Byte *)data;
|
|
||||||
for (; size > 0 ; size--, p++)
|
|
||||||
v = g_CrcTable[((Byte)(v)) ^ *p] ^ (v >> 8);
|
|
||||||
*crc = v;
|
|
||||||
}
|
|
||||||
|
|
||||||
UInt32 CrcCalculateDigest(const void *data, size_t size)
|
|
||||||
{
|
|
||||||
UInt32 crc;
|
|
||||||
CrcInit(&crc);
|
|
||||||
CrcUpdate(&crc, data, size);
|
|
||||||
return CrcGetDigest(&crc);
|
|
||||||
}
|
|
||||||
|
|
||||||
int CrcVerifyDigest(UInt32 digest, const void *data, size_t size)
|
|
||||||
{
|
|
||||||
return (CrcCalculateDigest(data, size) == digest);
|
|
||||||
}
|
|
@ -1,24 +0,0 @@
|
|||||||
/* 7zCrc.h */
|
|
||||||
|
|
||||||
#ifndef __7Z_CRC_H
|
|
||||||
#define __7Z_CRC_H
|
|
||||||
|
|
||||||
#include <stddef.h>
|
|
||||||
|
|
||||||
#include "7zTypes.h"
|
|
||||||
|
|
||||||
extern UInt32 g_CrcTable[256];
|
|
||||||
void InitCrcTable();
|
|
||||||
|
|
||||||
void CrcInit(UInt32 *crc);
|
|
||||||
UInt32 CrcGetDigest(UInt32 *crc);
|
|
||||||
void CrcUpdateByte(UInt32 *crc, Byte v);
|
|
||||||
void CrcUpdateUInt16(UInt32 *crc, UInt16 v);
|
|
||||||
void CrcUpdateUInt32(UInt32 *crc, UInt32 v);
|
|
||||||
void CrcUpdateUInt64(UInt32 *crc, UInt64 v);
|
|
||||||
void CrcUpdate(UInt32 *crc, const void *data, size_t size);
|
|
||||||
|
|
||||||
UInt32 CrcCalculateDigest(const void *data, size_t size);
|
|
||||||
int CrcVerifyDigest(UInt32 digest, const void *data, size_t size);
|
|
||||||
|
|
||||||
#endif
|
|
@ -1,361 +0,0 @@
|
|||||||
/* 7zDecode.c */
|
|
||||||
|
|
||||||
#include "7zDecode.h"
|
|
||||||
#ifdef _SZ_ONE_DIRECTORY
|
|
||||||
#include "LzmaDecode.h"
|
|
||||||
#else
|
|
||||||
#include "../../Compress/LZMA_C/LzmaDecode.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef _LZMA_OUT_READ
|
|
||||||
#include <string.h> // for memcpy
|
|
||||||
#endif
|
|
||||||
|
|
||||||
CMethodID k_Copy = { { 0x0 }, 1 };
|
|
||||||
CMethodID k_LZMA = { { 0x3, 0x1, 0x1 }, 3 };
|
|
||||||
|
|
||||||
#ifdef _LZMA_IN_CB
|
|
||||||
|
|
||||||
typedef struct _CLzmaInCallbackImp
|
|
||||||
{
|
|
||||||
ILzmaInCallback InCallback;
|
|
||||||
ISzInStream *InStream;
|
|
||||||
size_t Size;
|
|
||||||
} CLzmaInCallbackImp;
|
|
||||||
|
|
||||||
int LzmaReadImp(void *object, const unsigned char **buffer, SizeT *size)
|
|
||||||
{
|
|
||||||
CLzmaInCallbackImp *cb = (CLzmaInCallbackImp *)object;
|
|
||||||
size_t processedSize;
|
|
||||||
SZ_RESULT res;
|
|
||||||
*size = 0;
|
|
||||||
res = cb->InStream->Read((void *)cb->InStream, (void **)buffer, cb->Size, &processedSize);
|
|
||||||
*size = (SizeT)processedSize;
|
|
||||||
if (processedSize > cb->Size)
|
|
||||||
return (int)SZE_FAIL;
|
|
||||||
cb->Size -= processedSize;
|
|
||||||
if (res == SZ_OK)
|
|
||||||
return 0;
|
|
||||||
return (int)res;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
SZ_RESULT SzDecode(const CFileSize *packSizes, const CFolder *folder,
|
|
||||||
#ifdef _LZMA_IN_CB
|
|
||||||
ISzInStream *inStream,
|
|
||||||
#else
|
|
||||||
const Byte *inBuffer,
|
|
||||||
#endif
|
|
||||||
Byte *outBuffer, size_t outSize,
|
|
||||||
size_t *outSizeProcessed, ISzAlloc *allocMain)
|
|
||||||
{
|
|
||||||
UInt32 si;
|
|
||||||
size_t inSize = 0;
|
|
||||||
CCoderInfo *coder;
|
|
||||||
if (folder->NumPackStreams != 1)
|
|
||||||
return SZE_NOTIMPL;
|
|
||||||
if (folder->NumCoders != 1)
|
|
||||||
return SZE_NOTIMPL;
|
|
||||||
coder = folder->Coders;
|
|
||||||
*outSizeProcessed = 0;
|
|
||||||
|
|
||||||
for (si = 0; si < folder->NumPackStreams; si++)
|
|
||||||
inSize += (size_t)packSizes[si];
|
|
||||||
|
|
||||||
if (AreMethodsEqual(&coder->MethodID, &k_Copy))
|
|
||||||
{
|
|
||||||
size_t i;
|
|
||||||
if (inSize != outSize)
|
|
||||||
return SZE_DATA_ERROR;
|
|
||||||
#ifdef _LZMA_IN_CB
|
|
||||||
for (i = 0; i < inSize;)
|
|
||||||
{
|
|
||||||
size_t j;
|
|
||||||
Byte *inBuffer;
|
|
||||||
size_t bufferSize;
|
|
||||||
RINOK(inStream->Read((void *)inStream, (void **)&inBuffer, inSize - i, &bufferSize));
|
|
||||||
if (bufferSize == 0)
|
|
||||||
return SZE_DATA_ERROR;
|
|
||||||
if (bufferSize > inSize - i)
|
|
||||||
return SZE_FAIL;
|
|
||||||
*outSizeProcessed += bufferSize;
|
|
||||||
for (j = 0; j < bufferSize && i < inSize; j++, i++)
|
|
||||||
outBuffer[i] = inBuffer[j];
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
for (i = 0; i < inSize; i++)
|
|
||||||
outBuffer[i] = inBuffer[i];
|
|
||||||
*outSizeProcessed = inSize;
|
|
||||||
#endif
|
|
||||||
return SZ_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (AreMethodsEqual(&coder->MethodID, &k_LZMA))
|
|
||||||
{
|
|
||||||
#ifdef _LZMA_IN_CB
|
|
||||||
CLzmaInCallbackImp lzmaCallback;
|
|
||||||
#else
|
|
||||||
SizeT inProcessed;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
CLzmaDecoderState state; /* it's about 24-80 bytes structure, if int is 32-bit */
|
|
||||||
int result;
|
|
||||||
SizeT outSizeProcessedLoc;
|
|
||||||
|
|
||||||
#ifdef _LZMA_IN_CB
|
|
||||||
lzmaCallback.Size = inSize;
|
|
||||||
lzmaCallback.InStream = inStream;
|
|
||||||
lzmaCallback.InCallback.Read = LzmaReadImp;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (LzmaDecodeProperties(&state.Properties, coder->Properties.Items,
|
|
||||||
coder->Properties.Capacity) != LZMA_RESULT_OK)
|
|
||||||
return SZE_FAIL;
|
|
||||||
|
|
||||||
state.Probs = (CProb *)allocMain->Alloc(LzmaGetNumProbs(&state.Properties) * sizeof(CProb));
|
|
||||||
if (state.Probs == 0)
|
|
||||||
return SZE_OUTOFMEMORY;
|
|
||||||
|
|
||||||
#ifdef _LZMA_OUT_READ
|
|
||||||
if (state.Properties.DictionarySize == 0)
|
|
||||||
state.Dictionary = 0;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
state.Dictionary = (unsigned char *)allocMain->Alloc(state.Properties.DictionarySize);
|
|
||||||
if (state.Dictionary == 0)
|
|
||||||
{
|
|
||||||
allocMain->Free(state.Probs);
|
|
||||||
return SZE_OUTOFMEMORYDIC;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
LzmaDecoderInit(&state);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
result = LzmaDecode(&state,
|
|
||||||
#ifdef _LZMA_IN_CB
|
|
||||||
&lzmaCallback.InCallback,
|
|
||||||
#else
|
|
||||||
inBuffer, (SizeT)inSize, &inProcessed,
|
|
||||||
#endif
|
|
||||||
outBuffer, (SizeT)outSize, &outSizeProcessedLoc);
|
|
||||||
*outSizeProcessed = (size_t)outSizeProcessedLoc;
|
|
||||||
allocMain->Free(state.Probs);
|
|
||||||
#ifdef _LZMA_OUT_READ
|
|
||||||
allocMain->Free(state.Dictionary);
|
|
||||||
#endif
|
|
||||||
if (result == LZMA_RESULT_DATA_ERROR)
|
|
||||||
return SZE_DATA_ERROR;
|
|
||||||
if (result != LZMA_RESULT_OK)
|
|
||||||
return SZE_FAIL;
|
|
||||||
return SZ_OK;
|
|
||||||
}
|
|
||||||
return SZE_NOTIMPL;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef _LZMA_OUT_READ
|
|
||||||
// like SzDecode but uses less memory
|
|
||||||
SZ_RESULT SzDecode2(const CFileSize *packSizes, const CFolder *folder,
|
|
||||||
ISzInStream *inStream,
|
|
||||||
Byte *outBuffer, size_t outSize,
|
|
||||||
size_t *outSizeProcessed, ISzAlloc *allocMain,
|
|
||||||
size_t *fileOffset, size_t *fileSize)
|
|
||||||
{
|
|
||||||
UInt32 si;
|
|
||||||
size_t inSize = 0;
|
|
||||||
CCoderInfo *coder;
|
|
||||||
if (folder->NumPackStreams != 1)
|
|
||||||
return SZE_NOTIMPL;
|
|
||||||
if (folder->NumCoders != 1)
|
|
||||||
return SZE_NOTIMPL;
|
|
||||||
coder = folder->Coders;
|
|
||||||
*outSizeProcessed = 0;
|
|
||||||
|
|
||||||
for (si = 0; si < folder->NumPackStreams; si++)
|
|
||||||
inSize += (size_t)packSizes[si];
|
|
||||||
|
|
||||||
if (AreMethodsEqual(&coder->MethodID, &k_Copy))
|
|
||||||
{
|
|
||||||
size_t i;
|
|
||||||
if (inSize != outSize)
|
|
||||||
return SZE_DATA_ERROR;
|
|
||||||
#ifdef _LZMA_IN_CB
|
|
||||||
for (i = 0; i < inSize;)
|
|
||||||
{
|
|
||||||
size_t j;
|
|
||||||
Byte *inBuffer;
|
|
||||||
size_t bufferSize;
|
|
||||||
RINOK(inStream->Read((void *)inStream, (void **)&inBuffer, inSize - i, &bufferSize));
|
|
||||||
if (bufferSize == 0)
|
|
||||||
return SZE_DATA_ERROR;
|
|
||||||
if (bufferSize > inSize - i)
|
|
||||||
return SZE_FAIL;
|
|
||||||
*outSizeProcessed += bufferSize;
|
|
||||||
for (j = 0; j < bufferSize && i < inSize; j++, i++)
|
|
||||||
outBuffer[i] = inBuffer[j];
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
for (i = 0; i < inSize; i++)
|
|
||||||
outBuffer[i] = inBuffer[i];
|
|
||||||
*outSizeProcessed = inSize;
|
|
||||||
#endif
|
|
||||||
return SZ_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (AreMethodsEqual(&coder->MethodID, &k_LZMA))
|
|
||||||
{
|
|
||||||
#ifdef _LZMA_IN_CB
|
|
||||||
CLzmaInCallbackImp lzmaCallback;
|
|
||||||
#else
|
|
||||||
SizeT inProcessed;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
CLzmaDecoderState state; /* it's about 24-80 bytes structure, if int is 32-bit */
|
|
||||||
int result;
|
|
||||||
SizeT outSizeProcessedLoc;
|
|
||||||
|
|
||||||
#ifdef _LZMA_IN_CB
|
|
||||||
lzmaCallback.Size = inSize;
|
|
||||||
lzmaCallback.InStream = inStream;
|
|
||||||
lzmaCallback.InCallback.Read = LzmaReadImp;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (LzmaDecodeProperties(&state.Properties, coder->Properties.Items,
|
|
||||||
coder->Properties.Capacity) != LZMA_RESULT_OK)
|
|
||||||
return SZE_FAIL;
|
|
||||||
|
|
||||||
state.Probs = (CProb *)allocMain->Alloc(LzmaGetNumProbs(&state.Properties) * sizeof(CProb));
|
|
||||||
if (state.Probs == 0)
|
|
||||||
return SZE_OUTOFMEMORY;
|
|
||||||
|
|
||||||
if (state.Properties.DictionarySize == 0)
|
|
||||||
state.Dictionary = 0;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
state.Dictionary = (unsigned char *)allocMain->Alloc(state.Properties.DictionarySize);
|
|
||||||
if (state.Dictionary == 0)
|
|
||||||
{
|
|
||||||
allocMain->Free(state.Probs);
|
|
||||||
return SZE_OUTOFMEMORY;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
LzmaDecoderInit(&state);
|
|
||||||
|
|
||||||
// allocate memory for the temporary buffer
|
|
||||||
Byte *tmpBuffer = (Byte *)allocMain->Alloc(_LZMA_TEMP_BUFFER_SIZE);
|
|
||||||
|
|
||||||
// variables containing the number of the first and the last bytes of the buffer
|
|
||||||
size_t bufferStart, bufferEnd;
|
|
||||||
bufferStart = bufferEnd = 0;
|
|
||||||
|
|
||||||
// integers contains the offset, the size and the already copied data which will be
|
|
||||||
// copied from the tmpBuffer to outBuffer
|
|
||||||
size_t copyOffset, copySize, copyDone;
|
|
||||||
copyOffset = copySize = copyDone = 0;
|
|
||||||
|
|
||||||
UInt32 i = 0;
|
|
||||||
int bytesToCopy = 0;
|
|
||||||
|
|
||||||
// decompress data in _LZMA_TEMP_BUFFER_SIZE byte steps and copy the wanted file to outBuffer
|
|
||||||
do
|
|
||||||
{
|
|
||||||
if((*fileSize - copyDone) >= _LZMA_TEMP_BUFFER_SIZE)
|
|
||||||
bytesToCopy = _LZMA_TEMP_BUFFER_SIZE;
|
|
||||||
else
|
|
||||||
bytesToCopy = (*fileSize - copyDone);
|
|
||||||
|
|
||||||
// decompress next bytes
|
|
||||||
result = LzmaDecode(&state,
|
|
||||||
#ifdef _LZMA_IN_CB
|
|
||||||
&lzmaCallback.InCallback,
|
|
||||||
#else
|
|
||||||
//inBuffer, (SizeT)inSize, &inProcessed, //TODO!
|
|
||||||
#endif
|
|
||||||
tmpBuffer, bytesToCopy, &outSizeProcessedLoc
|
|
||||||
);
|
|
||||||
|
|
||||||
// check result
|
|
||||||
if(result == LZMA_RESULT_DATA_ERROR)
|
|
||||||
{
|
|
||||||
return SZE_DATA_ERROR;
|
|
||||||
}
|
|
||||||
if(result != LZMA_RESULT_OK)
|
|
||||||
{
|
|
||||||
return SZE_FAIL;
|
|
||||||
}
|
|
||||||
|
|
||||||
// normally this should never happen
|
|
||||||
if(outSizeProcessedLoc > _LZMA_TEMP_BUFFER_SIZE)
|
|
||||||
{
|
|
||||||
return SZE_FAIL;
|
|
||||||
}
|
|
||||||
|
|
||||||
// update bufferStart and bufferEnd
|
|
||||||
bufferStart = _LZMA_TEMP_BUFFER_SIZE * i;
|
|
||||||
bufferEnd = bufferStart + outSizeProcessedLoc;
|
|
||||||
i++;
|
|
||||||
|
|
||||||
// calculate copy offset and size
|
|
||||||
if(*fileOffset > bufferEnd)
|
|
||||||
{
|
|
||||||
// we haven't reached the start of the file yet
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// calculate offset
|
|
||||||
if(*fileOffset < bufferStart)
|
|
||||||
{
|
|
||||||
// the file has already started before this decompression step
|
|
||||||
copyOffset = 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// the file starts somewhere inside this buffer
|
|
||||||
copyDone = 0;
|
|
||||||
copyOffset = _LZMA_TEMP_BUFFER_SIZE - (bufferEnd - *fileOffset);
|
|
||||||
}
|
|
||||||
|
|
||||||
// calculate size
|
|
||||||
if((*fileOffset + *fileSize) > bufferEnd)
|
|
||||||
{
|
|
||||||
// we'll need the whole buffer after copyOffset
|
|
||||||
copySize = _LZMA_TEMP_BUFFER_SIZE - copyOffset;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// we'll stop somewhere inside the buffer
|
|
||||||
copySize = (*fileOffset + *fileSize) - (bufferStart + copyOffset);
|
|
||||||
}
|
|
||||||
|
|
||||||
// copy bytes to the real output buffer
|
|
||||||
if(copySize == 0)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
// printf("memcpy(outBuffer + %d, tmpBuffer + %d, %d)\n", copyDone, copyOffset, copySize);
|
|
||||||
memcpy(outBuffer + copyDone, tmpBuffer + copyOffset, copySize);
|
|
||||||
copyDone += copySize;
|
|
||||||
}
|
|
||||||
while((*fileOffset + *fileSize) > bufferEnd);
|
|
||||||
|
|
||||||
/* result = LzmaDecode(&state,
|
|
||||||
#ifdef _LZMA_IN_CB
|
|
||||||
&lzmaCallback.InCallback,
|
|
||||||
#else
|
|
||||||
inBuffer, (SizeT)inSize, &inProcessed,
|
|
||||||
#endif
|
|
||||||
outBuffer, (SizeT)outSize, &outSizeProcessedLoc);*/
|
|
||||||
//*outSizeProcessed = (size_t)outSizeProcessedLoc;
|
|
||||||
*outSizeProcessed = copyDone;
|
|
||||||
allocMain->Free(tmpBuffer); // free the temporary buffer again
|
|
||||||
allocMain->Free(state.Probs);
|
|
||||||
allocMain->Free(state.Dictionary);
|
|
||||||
/* if (result == LZMA_RESULT_DATA_ERROR)
|
|
||||||
return SZE_DATA_ERROR;
|
|
||||||
if (result != LZMA_RESULT_OK)
|
|
||||||
return SZE_FAIL;*/
|
|
||||||
return SZ_OK;
|
|
||||||
}
|
|
||||||
return SZE_NOTIMPL;
|
|
||||||
}
|
|
||||||
#endif
|
|
@ -1,37 +0,0 @@
|
|||||||
/* 7zDecode.h */
|
|
||||||
|
|
||||||
#if defined(_LZMA_OUT_READ) && !defined(_LZMA_IN_CB)
|
|
||||||
#error "Fixme: _LZMA_OUT_READ && _LZMA_IN_CB isn't currently possible!"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef __7Z_DECODE_H
|
|
||||||
#define __7Z_DECODE_H
|
|
||||||
|
|
||||||
#include "7zItem.h"
|
|
||||||
#include "7zAlloc.h"
|
|
||||||
#ifdef _LZMA_IN_CB
|
|
||||||
#include "7zIn.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
SZ_RESULT SzDecode(const CFileSize *packSizes, const CFolder *folder,
|
|
||||||
#ifdef _LZMA_IN_CB
|
|
||||||
ISzInStream *stream,
|
|
||||||
#else
|
|
||||||
const Byte *inBuffer,
|
|
||||||
#endif
|
|
||||||
Byte *outBuffer, size_t outSize,
|
|
||||||
size_t *outSizeProcessed, ISzAlloc *allocMain);
|
|
||||||
|
|
||||||
#ifdef _LZMA_OUT_READ
|
|
||||||
#ifndef _LZMA_TEMP_BUFFER_SIZE
|
|
||||||
#define _LZMA_TEMP_BUFFER_SIZE (2048) // size of the temporary buffer in bytes
|
|
||||||
#endif
|
|
||||||
|
|
||||||
SZ_RESULT SzDecode2(const CFileSize *packSizes, const CFolder *folder,
|
|
||||||
ISzInStream *stream,
|
|
||||||
Byte *outBuffer, size_t outSize,
|
|
||||||
size_t *outSizeProcessed, ISzAlloc *allocMain,
|
|
||||||
size_t *fileOffset, size_t *fileSize);
|
|
||||||
#endif // #ifdef _LZMA_OUT_READ
|
|
||||||
|
|
||||||
#endif
|
|
@ -1,254 +0,0 @@
|
|||||||
/* 7zExtract.c */
|
|
||||||
|
|
||||||
#include "7zExtract.h"
|
|
||||||
#include "7zDecode.h"
|
|
||||||
#include "7zCrc.h"
|
|
||||||
|
|
||||||
SZ_RESULT SzExtract(
|
|
||||||
ISzInStream *inStream,
|
|
||||||
CArchiveDatabaseEx *db,
|
|
||||||
UInt32 fileIndex,
|
|
||||||
UInt32 *blockIndex,
|
|
||||||
Byte **outBuffer,
|
|
||||||
size_t *outBufferSize,
|
|
||||||
size_t *offset,
|
|
||||||
size_t *outSizeProcessed,
|
|
||||||
ISzAlloc *allocMain,
|
|
||||||
ISzAlloc *allocTemp)
|
|
||||||
{
|
|
||||||
UInt32 folderIndex = db->FileIndexToFolderIndexMap[fileIndex];
|
|
||||||
SZ_RESULT res = SZ_OK;
|
|
||||||
*offset = 0;
|
|
||||||
*outSizeProcessed = 0;
|
|
||||||
if (folderIndex == (UInt32)-1)
|
|
||||||
{
|
|
||||||
allocMain->Free(*outBuffer);
|
|
||||||
*blockIndex = folderIndex;
|
|
||||||
*outBuffer = 0;
|
|
||||||
*outBufferSize = 0;
|
|
||||||
return SZ_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (*outBuffer == 0 || *blockIndex != folderIndex)
|
|
||||||
{
|
|
||||||
CFolder *folder = db->Database.Folders + folderIndex;
|
|
||||||
CFileSize unPackSize = SzFolderGetUnPackSize(folder);
|
|
||||||
#ifndef _LZMA_IN_CB
|
|
||||||
CFileSize packSize = SzArDbGetFolderFullPackSize(db, folderIndex);
|
|
||||||
Byte *inBuffer = 0;
|
|
||||||
size_t processedSize;
|
|
||||||
#endif
|
|
||||||
*blockIndex = folderIndex;
|
|
||||||
allocMain->Free(*outBuffer);
|
|
||||||
*outBuffer = 0;
|
|
||||||
|
|
||||||
RINOK(inStream->Seek(inStream, SzArDbGetFolderStreamPos(db, folderIndex, 0)));
|
|
||||||
|
|
||||||
#ifndef _LZMA_IN_CB
|
|
||||||
if (packSize != 0)
|
|
||||||
{
|
|
||||||
inBuffer = (Byte *)allocTemp->Alloc((size_t)packSize);
|
|
||||||
if (inBuffer == 0)
|
|
||||||
return SZE_OUTOFMEMORY;
|
|
||||||
}
|
|
||||||
res = inStream->Read(inStream, inBuffer, (size_t)packSize, &processedSize);
|
|
||||||
if (res == SZ_OK && processedSize != (size_t)packSize)
|
|
||||||
res = SZE_FAIL;
|
|
||||||
#endif
|
|
||||||
if (res == SZ_OK)
|
|
||||||
{
|
|
||||||
*outBufferSize = (size_t)unPackSize;
|
|
||||||
if (unPackSize != 0)
|
|
||||||
{
|
|
||||||
*outBuffer = (Byte *)allocMain->Alloc((size_t)unPackSize);
|
|
||||||
if (*outBuffer == 0)
|
|
||||||
res = SZE_OUTOFMEMORY;
|
|
||||||
}
|
|
||||||
if (res == SZ_OK)
|
|
||||||
{
|
|
||||||
size_t outRealSize;
|
|
||||||
res = SzDecode(db->Database.PackSizes +
|
|
||||||
db->FolderStartPackStreamIndex[folderIndex], folder,
|
|
||||||
#ifdef _LZMA_IN_CB
|
|
||||||
inStream,
|
|
||||||
#else
|
|
||||||
inBuffer,
|
|
||||||
#endif
|
|
||||||
*outBuffer, (size_t)unPackSize, &outRealSize, allocTemp);
|
|
||||||
if (res == SZ_OK)
|
|
||||||
{
|
|
||||||
if (outRealSize == (size_t)unPackSize)
|
|
||||||
{
|
|
||||||
if (folder->UnPackCRCDefined)
|
|
||||||
{
|
|
||||||
if (!CrcVerifyDigest(folder->UnPackCRC, *outBuffer, (size_t)unPackSize))
|
|
||||||
res = SZE_FAIL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
res = SZE_FAIL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#ifndef _LZMA_IN_CB
|
|
||||||
allocTemp->Free(inBuffer);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
if (res == SZ_OK)
|
|
||||||
{
|
|
||||||
UInt32 i;
|
|
||||||
CFileItem *fileItem = db->Database.Files + fileIndex;
|
|
||||||
*offset = 0;
|
|
||||||
for(i = db->FolderStartFileIndex[folderIndex]; i < fileIndex; i++)
|
|
||||||
*offset += (UInt32)db->Database.Files[i].Size;
|
|
||||||
*outSizeProcessed = (size_t)fileItem->Size;
|
|
||||||
if (*offset + *outSizeProcessed > *outBufferSize)
|
|
||||||
return SZE_FAIL;
|
|
||||||
{
|
|
||||||
if (fileItem->IsFileCRCDefined)
|
|
||||||
{
|
|
||||||
if (!CrcVerifyDigest(fileItem->FileCRC, *outBuffer + *offset, *outSizeProcessed))
|
|
||||||
res = SZE_FAIL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef _LZMA_OUT_READ
|
|
||||||
// similar to SzExtract but needs less memory
|
|
||||||
SZ_RESULT SzExtract2(
|
|
||||||
ISzInStream *inStream,
|
|
||||||
CArchiveDatabaseEx *db,
|
|
||||||
UInt32 fileIndex,
|
|
||||||
UInt32 *blockIndex,
|
|
||||||
Byte **outBuffer,
|
|
||||||
size_t *outBufferSize,
|
|
||||||
size_t *offset,
|
|
||||||
size_t *outSizeProcessed,
|
|
||||||
ISzAlloc *allocMain,
|
|
||||||
ISzAlloc *allocTemp)
|
|
||||||
{
|
|
||||||
UInt32 folderIndex = db->FileIndexToFolderIndexMap[fileIndex];
|
|
||||||
SZ_RESULT res = SZ_OK;
|
|
||||||
*offset = 0;
|
|
||||||
*outSizeProcessed = 0;
|
|
||||||
if (folderIndex == (UInt32)-1)
|
|
||||||
{
|
|
||||||
*blockIndex = folderIndex;
|
|
||||||
#ifndef NGC
|
|
||||||
allocMain->Free(*outBuffer);
|
|
||||||
*outBuffer = 0;
|
|
||||||
#endif
|
|
||||||
*outBufferSize = 0;
|
|
||||||
return SZ_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
// if (*outBuffer == 0 || *blockIndex != folderIndex)
|
|
||||||
// {
|
|
||||||
CFolder *folder = db->Database.Folders + folderIndex;
|
|
||||||
CFileSize unPackSize = SzFolderGetUnPackSize(folder);
|
|
||||||
#ifndef _LZMA_IN_CB
|
|
||||||
CFileSize packSize = SzArDbGetFolderFullPackSize(db, folderIndex);
|
|
||||||
Byte *inBuffer = 0;
|
|
||||||
size_t processedSize;
|
|
||||||
#endif
|
|
||||||
*blockIndex = folderIndex;
|
|
||||||
#ifndef NGC
|
|
||||||
allocMain->Free(*outBuffer);
|
|
||||||
*outBuffer = 0;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
RINOK(inStream->Seek(inStream, SzArDbGetFolderStreamPos(db, folderIndex, 0)));
|
|
||||||
|
|
||||||
#ifndef _LZMA_IN_CB
|
|
||||||
if (packSize != 0)
|
|
||||||
{
|
|
||||||
inBuffer = (Byte *)allocTemp->Alloc((size_t)packSize);
|
|
||||||
if (inBuffer == 0)
|
|
||||||
return SZE_OUTOFMEMORY;
|
|
||||||
}
|
|
||||||
res = inStream->Read(inStream, inBuffer, (size_t)packSize, &processedSize);
|
|
||||||
if (res == SZ_OK && processedSize != (size_t)packSize)
|
|
||||||
res = SZE_FAIL;
|
|
||||||
#endif
|
|
||||||
if (res == SZ_OK)
|
|
||||||
{
|
|
||||||
// calculate file offset and filesize
|
|
||||||
CFileItem *fileItem = db->Database.Files + fileIndex;
|
|
||||||
UInt32 i;
|
|
||||||
*offset = 0;
|
|
||||||
for(i = db->FolderStartFileIndex[folderIndex]; i < fileIndex; i++)
|
|
||||||
*offset += (UInt32)db->Database.Files[i].Size;
|
|
||||||
*outSizeProcessed = (size_t)fileItem->Size;
|
|
||||||
*outBufferSize = (size_t)fileItem->Size;
|
|
||||||
if (unPackSize != 0)
|
|
||||||
{
|
|
||||||
#ifndef NGC
|
|
||||||
*outBuffer = (Byte *)allocMain->Alloc((size_t)fileItem->Size);
|
|
||||||
if (*outBuffer == 0)
|
|
||||||
res = SZE_OUTOFMEMORY;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
if (res == SZ_OK)
|
|
||||||
{
|
|
||||||
|
|
||||||
size_t outRealSize;
|
|
||||||
res = SzDecode2(db->Database.PackSizes +
|
|
||||||
db->FolderStartPackStreamIndex[folderIndex], folder,
|
|
||||||
#ifdef _LZMA_IN_CB
|
|
||||||
inStream,
|
|
||||||
#else
|
|
||||||
inBuffer,
|
|
||||||
#endif
|
|
||||||
*outBuffer, (size_t)unPackSize, &outRealSize, allocTemp,
|
|
||||||
offset, outSizeProcessed
|
|
||||||
);
|
|
||||||
*outSizeProcessed = outRealSize;
|
|
||||||
/* if (res == SZ_OK) // we can't validate the CRC of the whole data stream because we only extracted the wanted file
|
|
||||||
{
|
|
||||||
if (outRealSize == (size_t)unPackSize)
|
|
||||||
{
|
|
||||||
if (folder->UnPackCRCDefined)
|
|
||||||
{
|
|
||||||
if (!CrcVerifyDigest(folder->UnPackCRC, *outBuffer, (size_t)unPackSize))
|
|
||||||
res = SZE_FAIL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
res = SZE_FAIL;
|
|
||||||
}*/
|
|
||||||
}
|
|
||||||
// }
|
|
||||||
#ifndef _LZMA_IN_CB
|
|
||||||
allocTemp->Free(inBuffer);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
if (res == SZ_OK)
|
|
||||||
{
|
|
||||||
/* UInt32 i;
|
|
||||||
CFileItem *fileItem = db->Database.Files + fileIndex;
|
|
||||||
*offset = 0;
|
|
||||||
for(i = db->FolderStartFileIndex[folderIndex]; i < fileIndex; i++)
|
|
||||||
*offset += (UInt32)db->Database.Files[i].Size;
|
|
||||||
*outSizeProcessed = (size_t)fileItem->Size;*/
|
|
||||||
//CFileItem *fileItem = db->Database.Files + fileIndex;
|
|
||||||
if (/**offset +*/ *outSizeProcessed > *outBufferSize)
|
|
||||||
return SZE_FAIL;
|
|
||||||
{
|
|
||||||
//if (fileItem->IsFileCRCDefined)
|
|
||||||
//{
|
|
||||||
// if (!CrcVerifyDigest(fileItem->FileCRC, *outBuffer/* + *offset*/, *outSizeProcessed))
|
|
||||||
// res = SZE_CRC_ERROR; // why does SzExtract return SZE_FAIL when we can return SZE_CRC_ERROR?
|
|
||||||
//}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// change *offset to 0 because SzExtract normally decompresses the whole solid block
|
|
||||||
// and sets *offset to the offset of the wanted file.
|
|
||||||
// SzDecode2 does only copy the needed file to the output buffer and has to set *offset
|
|
||||||
// to 0 to ensure compatibility with SzExtract
|
|
||||||
*offset = 0;
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
#endif
|
|
@ -1,60 +0,0 @@
|
|||||||
/* 7zExtract.h */
|
|
||||||
|
|
||||||
#if defined(_LZMA_OUT_READ) && !defined(_LZMA_IN_CB)
|
|
||||||
#error "Fixme: _LZMA_OUT_READ && _LZMA_IN_CB isn't currently possible!"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef __7Z_EXTRACT_H
|
|
||||||
#define __7Z_EXTRACT_H
|
|
||||||
|
|
||||||
#include "7zIn.h"
|
|
||||||
|
|
||||||
/*
|
|
||||||
SzExtract extracts file from archive
|
|
||||||
|
|
||||||
SzExtract2 does the same but needs less memory
|
|
||||||
|
|
||||||
*outBuffer must be 0 before first call for each new archive.
|
|
||||||
|
|
||||||
Extracting cache:
|
|
||||||
If you need to decompress more than one file, you can send
|
|
||||||
these values from previous call:
|
|
||||||
*blockIndex,
|
|
||||||
*outBuffer,
|
|
||||||
*outBufferSize
|
|
||||||
You can consider "*outBuffer" as cache of solid block. If your archive is solid,
|
|
||||||
it will increase decompression speed.
|
|
||||||
|
|
||||||
If you use external function, you can declare these 3 cache variables
|
|
||||||
(blockIndex, outBuffer, outBufferSize) as static in that external function.
|
|
||||||
|
|
||||||
Free *outBuffer and set *outBuffer to 0, if you want to flush cache.
|
|
||||||
*/
|
|
||||||
|
|
||||||
SZ_RESULT SzExtract(
|
|
||||||
ISzInStream *inStream,
|
|
||||||
CArchiveDatabaseEx *db,
|
|
||||||
UInt32 fileIndex, /* index of file */
|
|
||||||
UInt32 *blockIndex, /* index of solid block */
|
|
||||||
Byte **outBuffer, /* pointer to pointer to output buffer (allocated with allocMain) */
|
|
||||||
size_t *outBufferSize, /* buffer size for output buffer */
|
|
||||||
size_t *offset, /* offset of stream for required file in *outBuffer */
|
|
||||||
size_t *outSizeProcessed, /* size of file in *outBuffer */
|
|
||||||
ISzAlloc *allocMain,
|
|
||||||
ISzAlloc *allocTemp);
|
|
||||||
|
|
||||||
#ifdef _LZMA_OUT_READ
|
|
||||||
SZ_RESULT SzExtract2(
|
|
||||||
ISzInStream *inStream,
|
|
||||||
CArchiveDatabaseEx *db,
|
|
||||||
UInt32 fileIndex, /* index of file */
|
|
||||||
UInt32 *blockIndex, /* index of solid block */
|
|
||||||
Byte **outBuffer, /* pointer to pointer to output buffer (allocated with allocMain) */
|
|
||||||
size_t *outBufferSize, /* buffer size for output buffer */
|
|
||||||
size_t *offset, /* offset of stream for required file in *outBuffer */
|
|
||||||
size_t *outSizeProcessed, /* size of file in *outBuffer */
|
|
||||||
ISzAlloc *allocMain,
|
|
||||||
ISzAlloc *allocTemp);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
|
@ -1,5 +0,0 @@
|
|||||||
/* 7zHeader.c */
|
|
||||||
|
|
||||||
#include "7zHeader.h"
|
|
||||||
|
|
||||||
Byte k7zSignature[k7zSignatureSize] = {'7', 'z', 0xBC, 0xAF, 0x27, 0x1C};
|
|
@ -1,55 +0,0 @@
|
|||||||
/* 7zHeader.h */
|
|
||||||
|
|
||||||
#ifndef __7Z_HEADER_H
|
|
||||||
#define __7Z_HEADER_H
|
|
||||||
|
|
||||||
#include "7zTypes.h"
|
|
||||||
|
|
||||||
#define k7zSignatureSize 6
|
|
||||||
extern Byte k7zSignature[k7zSignatureSize];
|
|
||||||
|
|
||||||
#define k7zMajorVersion 0
|
|
||||||
|
|
||||||
#define k7zStartHeaderSize 0x20
|
|
||||||
|
|
||||||
enum EIdEnum
|
|
||||||
{
|
|
||||||
k7zIdEnd,
|
|
||||||
|
|
||||||
k7zIdHeader,
|
|
||||||
|
|
||||||
k7zIdArchiveProperties,
|
|
||||||
|
|
||||||
k7zIdAdditionalStreamsInfo,
|
|
||||||
k7zIdMainStreamsInfo,
|
|
||||||
k7zIdFilesInfo,
|
|
||||||
|
|
||||||
k7zIdPackInfo,
|
|
||||||
k7zIdUnPackInfo,
|
|
||||||
k7zIdSubStreamsInfo,
|
|
||||||
|
|
||||||
k7zIdSize,
|
|
||||||
k7zIdCRC,
|
|
||||||
|
|
||||||
k7zIdFolder,
|
|
||||||
|
|
||||||
k7zIdCodersUnPackSize,
|
|
||||||
k7zIdNumUnPackStream,
|
|
||||||
|
|
||||||
k7zIdEmptyStream,
|
|
||||||
k7zIdEmptyFile,
|
|
||||||
k7zIdAnti,
|
|
||||||
|
|
||||||
k7zIdName,
|
|
||||||
k7zIdCreationTime,
|
|
||||||
k7zIdLastAccessTime,
|
|
||||||
k7zIdLastWriteTime,
|
|
||||||
k7zIdWinAttributes,
|
|
||||||
k7zIdComment,
|
|
||||||
|
|
||||||
k7zIdEncodedHeader,
|
|
||||||
|
|
||||||
k7zIdStartPos
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
1281
source/sz/7zIn.c
1281
source/sz/7zIn.c
File diff suppressed because it is too large
Load Diff
@ -1,55 +0,0 @@
|
|||||||
/* 7zIn.h */
|
|
||||||
|
|
||||||
#ifndef __7Z_IN_H
|
|
||||||
#define __7Z_IN_H
|
|
||||||
|
|
||||||
#include "7zHeader.h"
|
|
||||||
#include "7zItem.h"
|
|
||||||
#include "7zAlloc.h"
|
|
||||||
|
|
||||||
typedef struct _CInArchiveInfo
|
|
||||||
{
|
|
||||||
CFileSize StartPositionAfterHeader;
|
|
||||||
CFileSize DataStartPosition;
|
|
||||||
}CInArchiveInfo;
|
|
||||||
|
|
||||||
typedef struct _CArchiveDatabaseEx
|
|
||||||
{
|
|
||||||
CArchiveDatabase Database;
|
|
||||||
CInArchiveInfo ArchiveInfo;
|
|
||||||
UInt32 *FolderStartPackStreamIndex;
|
|
||||||
CFileSize *PackStreamStartPositions;
|
|
||||||
UInt32 *FolderStartFileIndex;
|
|
||||||
UInt32 *FileIndexToFolderIndexMap;
|
|
||||||
}CArchiveDatabaseEx;
|
|
||||||
|
|
||||||
void SzArDbExInit(CArchiveDatabaseEx *db);
|
|
||||||
void SzArDbExFree(CArchiveDatabaseEx *db, void (*freeFunc)(void *));
|
|
||||||
CFileSize SzArDbGetFolderStreamPos(CArchiveDatabaseEx *db, UInt32 folderIndex, UInt32 indexInFolder);
|
|
||||||
CFileSize SzArDbGetFolderFullPackSize(CArchiveDatabaseEx *db, UInt32 folderIndex);
|
|
||||||
|
|
||||||
typedef struct _ISzInStream
|
|
||||||
{
|
|
||||||
#ifdef _LZMA_IN_CB
|
|
||||||
SZ_RESULT (*Read)(
|
|
||||||
void *object, /* pointer to ISzInStream itself */
|
|
||||||
void **buffer, /* out: pointer to buffer with data */
|
|
||||||
size_t maxRequiredSize, /* max required size to read */
|
|
||||||
size_t *processedSize); /* real processed size.
|
|
||||||
processedSize can be less than maxRequiredSize.
|
|
||||||
If processedSize == 0, then there are no more
|
|
||||||
bytes in stream. */
|
|
||||||
#else
|
|
||||||
SZ_RESULT (*Read)(void *object, void *buffer, size_t size, size_t *processedSize);
|
|
||||||
#endif
|
|
||||||
SZ_RESULT (*Seek)(void *object, CFileSize pos);
|
|
||||||
} ISzInStream;
|
|
||||||
|
|
||||||
|
|
||||||
int SzArchiveOpen(
|
|
||||||
ISzInStream *inStream,
|
|
||||||
CArchiveDatabaseEx *db,
|
|
||||||
ISzAlloc *allocMain,
|
|
||||||
ISzAlloc *allocTemp);
|
|
||||||
|
|
||||||
#endif
|
|
@ -1,133 +0,0 @@
|
|||||||
/* 7zItem.c */
|
|
||||||
|
|
||||||
#include "7zItem.h"
|
|
||||||
#include "7zAlloc.h"
|
|
||||||
|
|
||||||
void SzCoderInfoInit(CCoderInfo *coder)
|
|
||||||
{
|
|
||||||
SzByteBufferInit(&coder->Properties);
|
|
||||||
}
|
|
||||||
|
|
||||||
void SzCoderInfoFree(CCoderInfo *coder, void (*freeFunc)(void *p))
|
|
||||||
{
|
|
||||||
SzByteBufferFree(&coder->Properties, freeFunc);
|
|
||||||
SzCoderInfoInit(coder);
|
|
||||||
}
|
|
||||||
|
|
||||||
void SzFolderInit(CFolder *folder)
|
|
||||||
{
|
|
||||||
folder->NumCoders = 0;
|
|
||||||
folder->Coders = 0;
|
|
||||||
folder->NumBindPairs = 0;
|
|
||||||
folder->BindPairs = 0;
|
|
||||||
folder->NumPackStreams = 0;
|
|
||||||
folder->PackStreams = 0;
|
|
||||||
folder->UnPackSizes = 0;
|
|
||||||
folder->UnPackCRCDefined = 0;
|
|
||||||
folder->UnPackCRC = 0;
|
|
||||||
folder->NumUnPackStreams = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SzFolderFree(CFolder *folder, void (*freeFunc)(void *p))
|
|
||||||
{
|
|
||||||
UInt32 i;
|
|
||||||
for (i = 0; i < folder->NumCoders; i++)
|
|
||||||
SzCoderInfoFree(&folder->Coders[i], freeFunc);
|
|
||||||
freeFunc(folder->Coders);
|
|
||||||
freeFunc(folder->BindPairs);
|
|
||||||
freeFunc(folder->PackStreams);
|
|
||||||
freeFunc(folder->UnPackSizes);
|
|
||||||
SzFolderInit(folder);
|
|
||||||
}
|
|
||||||
|
|
||||||
UInt32 SzFolderGetNumOutStreams(CFolder *folder)
|
|
||||||
{
|
|
||||||
UInt32 result = 0;
|
|
||||||
UInt32 i;
|
|
||||||
for (i = 0; i < folder->NumCoders; i++)
|
|
||||||
result += folder->Coders[i].NumOutStreams;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
int SzFolderFindBindPairForInStream(CFolder *folder, UInt32 inStreamIndex)
|
|
||||||
{
|
|
||||||
UInt32 i;
|
|
||||||
for(i = 0; i < folder->NumBindPairs; i++)
|
|
||||||
if (folder->BindPairs[i].InIndex == inStreamIndex)
|
|
||||||
return i;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int SzFolderFindBindPairForOutStream(CFolder *folder, UInt32 outStreamIndex)
|
|
||||||
{
|
|
||||||
UInt32 i;
|
|
||||||
for(i = 0; i < folder->NumBindPairs; i++)
|
|
||||||
if (folder->BindPairs[i].OutIndex == outStreamIndex)
|
|
||||||
return i;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
CFileSize SzFolderGetUnPackSize(CFolder *folder)
|
|
||||||
{
|
|
||||||
int i = (int)SzFolderGetNumOutStreams(folder);
|
|
||||||
if (i == 0)
|
|
||||||
return 0;
|
|
||||||
for (i--; i >= 0; i--)
|
|
||||||
if (SzFolderFindBindPairForOutStream(folder, i) < 0)
|
|
||||||
return folder->UnPackSizes[i];
|
|
||||||
/* throw 1; */
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
int FindPackStreamArrayIndex(int inStreamIndex) const
|
|
||||||
{
|
|
||||||
for(int i = 0; i < PackStreams.Size(); i++)
|
|
||||||
if (PackStreams[i] == inStreamIndex)
|
|
||||||
return i;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
void SzFileInit(CFileItem *fileItem)
|
|
||||||
{
|
|
||||||
fileItem->IsFileCRCDefined = 0;
|
|
||||||
fileItem->HasStream = 1;
|
|
||||||
fileItem->IsDirectory = 0;
|
|
||||||
fileItem->IsAnti = 0;
|
|
||||||
fileItem->Name = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SzFileFree(CFileItem *fileItem, void (*freeFunc)(void *p))
|
|
||||||
{
|
|
||||||
freeFunc(fileItem->Name);
|
|
||||||
SzFileInit(fileItem);
|
|
||||||
}
|
|
||||||
|
|
||||||
void SzArchiveDatabaseInit(CArchiveDatabase *db)
|
|
||||||
{
|
|
||||||
db->NumPackStreams = 0;
|
|
||||||
db->PackSizes = 0;
|
|
||||||
db->PackCRCsDefined = 0;
|
|
||||||
db->PackCRCs = 0;
|
|
||||||
db->NumFolders = 0;
|
|
||||||
db->Folders = 0;
|
|
||||||
db->NumFiles = 0;
|
|
||||||
db->Files = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SzArchiveDatabaseFree(CArchiveDatabase *db, void (*freeFunc)(void *))
|
|
||||||
{
|
|
||||||
UInt32 i;
|
|
||||||
for (i = 0; i < db->NumFolders; i++)
|
|
||||||
SzFolderFree(&db->Folders[i], freeFunc);
|
|
||||||
for (i = 0; i < db->NumFiles; i++)
|
|
||||||
SzFileFree(&db->Files[i], freeFunc);
|
|
||||||
freeFunc(db->PackSizes);
|
|
||||||
freeFunc(db->PackCRCsDefined);
|
|
||||||
freeFunc(db->PackCRCs);
|
|
||||||
freeFunc(db->Folders);
|
|
||||||
freeFunc(db->Files);
|
|
||||||
SzArchiveDatabaseInit(db);
|
|
||||||
}
|
|
@ -1,90 +0,0 @@
|
|||||||
/* 7zItem.h */
|
|
||||||
|
|
||||||
#ifndef __7Z_ITEM_H
|
|
||||||
#define __7Z_ITEM_H
|
|
||||||
|
|
||||||
#include "7zMethodID.h"
|
|
||||||
#include "7zHeader.h"
|
|
||||||
#include "7zBuffer.h"
|
|
||||||
|
|
||||||
typedef struct _CCoderInfo
|
|
||||||
{
|
|
||||||
UInt32 NumInStreams;
|
|
||||||
UInt32 NumOutStreams;
|
|
||||||
CMethodID MethodID;
|
|
||||||
CSzByteBuffer Properties;
|
|
||||||
}CCoderInfo;
|
|
||||||
|
|
||||||
void SzCoderInfoInit(CCoderInfo *coder);
|
|
||||||
void SzCoderInfoFree(CCoderInfo *coder, void (*freeFunc)(void *p));
|
|
||||||
|
|
||||||
typedef struct _CBindPair
|
|
||||||
{
|
|
||||||
UInt32 InIndex;
|
|
||||||
UInt32 OutIndex;
|
|
||||||
}CBindPair;
|
|
||||||
|
|
||||||
typedef struct _CFolder
|
|
||||||
{
|
|
||||||
UInt32 NumCoders;
|
|
||||||
CCoderInfo *Coders;
|
|
||||||
UInt32 NumBindPairs;
|
|
||||||
CBindPair *BindPairs;
|
|
||||||
UInt32 NumPackStreams;
|
|
||||||
UInt32 *PackStreams;
|
|
||||||
CFileSize *UnPackSizes;
|
|
||||||
int UnPackCRCDefined;
|
|
||||||
UInt32 UnPackCRC;
|
|
||||||
|
|
||||||
UInt32 NumUnPackStreams;
|
|
||||||
}CFolder;
|
|
||||||
|
|
||||||
void SzFolderInit(CFolder *folder);
|
|
||||||
CFileSize SzFolderGetUnPackSize(CFolder *folder);
|
|
||||||
int SzFolderFindBindPairForInStream(CFolder *folder, UInt32 inStreamIndex);
|
|
||||||
UInt32 SzFolderGetNumOutStreams(CFolder *folder);
|
|
||||||
CFileSize SzFolderGetUnPackSize(CFolder *folder);
|
|
||||||
|
|
||||||
/* #define CArchiveFileTime UInt64 */
|
|
||||||
|
|
||||||
typedef struct _CFileItem
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
CArchiveFileTime LastWriteTime;
|
|
||||||
CFileSize StartPos;
|
|
||||||
UInt32 Attributes;
|
|
||||||
*/
|
|
||||||
CFileSize Size;
|
|
||||||
UInt32 FileCRC;
|
|
||||||
char *Name;
|
|
||||||
|
|
||||||
Byte IsFileCRCDefined;
|
|
||||||
Byte HasStream;
|
|
||||||
Byte IsDirectory;
|
|
||||||
Byte IsAnti;
|
|
||||||
/*
|
|
||||||
int AreAttributesDefined;
|
|
||||||
int IsLastWriteTimeDefined;
|
|
||||||
int IsStartPosDefined;
|
|
||||||
*/
|
|
||||||
}CFileItem;
|
|
||||||
|
|
||||||
void SzFileInit(CFileItem *fileItem);
|
|
||||||
|
|
||||||
typedef struct _CArchiveDatabase
|
|
||||||
{
|
|
||||||
UInt32 NumPackStreams;
|
|
||||||
CFileSize *PackSizes;
|
|
||||||
Byte *PackCRCsDefined;
|
|
||||||
UInt32 *PackCRCs;
|
|
||||||
UInt32 NumFolders;
|
|
||||||
CFolder *Folders;
|
|
||||||
UInt32 NumFiles;
|
|
||||||
CFileItem *Files;
|
|
||||||
}CArchiveDatabase;
|
|
||||||
|
|
||||||
void SzArchiveDatabaseInit(CArchiveDatabase *db);
|
|
||||||
void SzArchiveDatabaseFree(CArchiveDatabase *db, void (*freeFunc)(void *));
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
@ -1,14 +0,0 @@
|
|||||||
/* 7zMethodID.c */
|
|
||||||
|
|
||||||
#include "7zMethodID.h"
|
|
||||||
|
|
||||||
int AreMethodsEqual(CMethodID *a1, CMethodID *a2)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
if (a1->IDSize != a2->IDSize)
|
|
||||||
return 0;
|
|
||||||
for (i = 0; i < a1->IDSize; i++)
|
|
||||||
if (a1->ID[i] != a2->ID[i])
|
|
||||||
return 0;
|
|
||||||
return 1;
|
|
||||||
}
|
|
@ -1,18 +0,0 @@
|
|||||||
/* 7zMethodID.h */
|
|
||||||
|
|
||||||
#ifndef __7Z_METHOD_ID_H
|
|
||||||
#define __7Z_METHOD_ID_H
|
|
||||||
|
|
||||||
#include "7zTypes.h"
|
|
||||||
|
|
||||||
#define kMethodIDSize 15
|
|
||||||
|
|
||||||
typedef struct _CMethodID
|
|
||||||
{
|
|
||||||
Byte ID[kMethodIDSize];
|
|
||||||
Byte IDSize;
|
|
||||||
} CMethodID;
|
|
||||||
|
|
||||||
int AreMethodsEqual(CMethodID *a1, CMethodID *a2);
|
|
||||||
|
|
||||||
#endif
|
|
@ -1,71 +0,0 @@
|
|||||||
/* 7zTypes.h */
|
|
||||||
|
|
||||||
#ifndef __COMMON_TYPES_H
|
|
||||||
#define __COMMON_TYPES_H
|
|
||||||
|
|
||||||
#ifndef _7ZIP_BYTE_DEFINED
|
|
||||||
#define _7ZIP_BYTE_DEFINED
|
|
||||||
#ifndef ZCONF_H
|
|
||||||
typedef unsigned char Byte;
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef _7ZIP_UINT16_DEFINED
|
|
||||||
#define _7ZIP_UINT16_DEFINED
|
|
||||||
typedef unsigned short UInt16;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef _7ZIP_UINT32_DEFINED
|
|
||||||
#define _7ZIP_UINT32_DEFINED
|
|
||||||
#ifdef _LZMA_UINT32_IS_ULONG
|
|
||||||
typedef unsigned long UInt32;
|
|
||||||
#else
|
|
||||||
typedef unsigned int UInt32;
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* #define _SZ_NO_INT_64 */
|
|
||||||
/* define it your compiler doesn't support long long int */
|
|
||||||
|
|
||||||
#ifndef _7ZIP_UINT64_DEFINED
|
|
||||||
#define _7ZIP_UINT64_DEFINED
|
|
||||||
#ifdef _SZ_NO_INT_64
|
|
||||||
typedef unsigned long UInt64;
|
|
||||||
#else
|
|
||||||
#ifdef _MSC_VER
|
|
||||||
typedef unsigned __int64 UInt64;
|
|
||||||
#else
|
|
||||||
typedef unsigned long long int UInt64;
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/* #define _SZ_FILE_SIZE_64 */
|
|
||||||
/* Use _SZ_FILE_SIZE_64 if you need support for files larger than 4 GB*/
|
|
||||||
|
|
||||||
#ifndef CFileSize
|
|
||||||
#ifdef _SZ_FILE_SIZE_64
|
|
||||||
typedef UInt64 CFileSize;
|
|
||||||
#else
|
|
||||||
typedef UInt32 CFileSize;
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define SZ_RESULT int
|
|
||||||
|
|
||||||
#define SZ_OK (0)
|
|
||||||
#define SZE_DATA_ERROR (1)
|
|
||||||
#define SZE_OUTOFMEMORY (2)
|
|
||||||
#define SZE_CRC_ERROR (3)
|
|
||||||
|
|
||||||
#define SZE_NOTIMPL (4)
|
|
||||||
#define SZE_FAIL (5)
|
|
||||||
|
|
||||||
#define SZE_ARCHIVE_ERROR (6)
|
|
||||||
|
|
||||||
#define SZE_OUTOFMEMORYDIC (7)
|
|
||||||
|
|
||||||
#define RINOK(x) { int __result_ = (x); if(__result_ != 0) return __result_; }
|
|
||||||
|
|
||||||
#endif
|
|
@ -1,584 +0,0 @@
|
|||||||
/*
|
|
||||||
LzmaDecode.c
|
|
||||||
LZMA Decoder (optimized for Speed version)
|
|
||||||
|
|
||||||
LZMA SDK 4.40 Copyright (c) 1999-2006 Igor Pavlov (2006-05-01)
|
|
||||||
http://www.7-zip.org/
|
|
||||||
|
|
||||||
LZMA SDK is licensed under two licenses:
|
|
||||||
1) GNU Lesser General Public License (GNU LGPL)
|
|
||||||
2) Common Public License (CPL)
|
|
||||||
It means that you can select one of these two licenses and
|
|
||||||
follow rules of that license.
|
|
||||||
|
|
||||||
SPECIAL EXCEPTION:
|
|
||||||
Igor Pavlov, as the author of this Code, expressly permits you to
|
|
||||||
statically or dynamically link your Code (or bind by name) to the
|
|
||||||
interfaces of this file without subjecting your linked Code to the
|
|
||||||
terms of the CPL or GNU LGPL. Any modifications or additions
|
|
||||||
to this file, however, are subject to the LGPL or CPL terms.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "LzmaDecode.h"
|
|
||||||
|
|
||||||
#define kNumTopBits 24
|
|
||||||
#define kTopValue ((UInt32)1 << kNumTopBits)
|
|
||||||
|
|
||||||
#define kNumBitModelTotalBits 11
|
|
||||||
#define kBitModelTotal (1 << kNumBitModelTotalBits)
|
|
||||||
#define kNumMoveBits 5
|
|
||||||
|
|
||||||
#define RC_READ_BYTE (*Buffer++)
|
|
||||||
|
|
||||||
#define RC_INIT2 Code = 0; Range = 0xFFFFFFFF; \
|
|
||||||
{ int i; for(i = 0; i < 5; i++) { RC_TEST; Code = (Code << 8) | RC_READ_BYTE; }}
|
|
||||||
|
|
||||||
#ifdef _LZMA_IN_CB
|
|
||||||
|
|
||||||
#define RC_TEST { if (Buffer == BufferLim) \
|
|
||||||
{ SizeT size; int result = InCallback->Read(InCallback, &Buffer, &size); if (result != LZMA_RESULT_OK) return result; \
|
|
||||||
BufferLim = Buffer + size; if (size == 0) return LZMA_RESULT_DATA_ERROR; }}
|
|
||||||
|
|
||||||
#define RC_INIT Buffer = BufferLim = 0; RC_INIT2
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
#define RC_TEST { if (Buffer == BufferLim) return LZMA_RESULT_DATA_ERROR; }
|
|
||||||
|
|
||||||
#define RC_INIT(buffer, bufferSize) Buffer = buffer; BufferLim = buffer + bufferSize; RC_INIT2
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define RC_NORMALIZE if (Range < kTopValue) { RC_TEST; Range <<= 8; Code = (Code << 8) | RC_READ_BYTE; }
|
|
||||||
|
|
||||||
#define IfBit0(p) RC_NORMALIZE; bound = (Range >> kNumBitModelTotalBits) * *(p); if (Code < bound)
|
|
||||||
#define UpdateBit0(p) Range = bound; *(p) += (kBitModelTotal - *(p)) >> kNumMoveBits;
|
|
||||||
#define UpdateBit1(p) Range -= bound; Code -= bound; *(p) -= (*(p)) >> kNumMoveBits;
|
|
||||||
|
|
||||||
#define RC_GET_BIT2(p, mi, A0, A1) IfBit0(p) \
|
|
||||||
{ UpdateBit0(p); mi <<= 1; A0; } else \
|
|
||||||
{ UpdateBit1(p); mi = (mi + mi) + 1; A1; }
|
|
||||||
|
|
||||||
#define RC_GET_BIT(p, mi) RC_GET_BIT2(p, mi, ; , ;)
|
|
||||||
|
|
||||||
#define RangeDecoderBitTreeDecode(probs, numLevels, res) \
|
|
||||||
{ int i = numLevels; res = 1; \
|
|
||||||
do { CProb *p = probs + res; RC_GET_BIT(p, res) } while(--i != 0); \
|
|
||||||
res -= (1 << numLevels); }
|
|
||||||
|
|
||||||
|
|
||||||
#define kNumPosBitsMax 4
|
|
||||||
#define kNumPosStatesMax (1 << kNumPosBitsMax)
|
|
||||||
|
|
||||||
#define kLenNumLowBits 3
|
|
||||||
#define kLenNumLowSymbols (1 << kLenNumLowBits)
|
|
||||||
#define kLenNumMidBits 3
|
|
||||||
#define kLenNumMidSymbols (1 << kLenNumMidBits)
|
|
||||||
#define kLenNumHighBits 8
|
|
||||||
#define kLenNumHighSymbols (1 << kLenNumHighBits)
|
|
||||||
|
|
||||||
#define LenChoice 0
|
|
||||||
#define LenChoice2 (LenChoice + 1)
|
|
||||||
#define LenLow (LenChoice2 + 1)
|
|
||||||
#define LenMid (LenLow + (kNumPosStatesMax << kLenNumLowBits))
|
|
||||||
#define LenHigh (LenMid + (kNumPosStatesMax << kLenNumMidBits))
|
|
||||||
#define kNumLenProbs (LenHigh + kLenNumHighSymbols)
|
|
||||||
|
|
||||||
|
|
||||||
#define kNumStates 12
|
|
||||||
#define kNumLitStates 7
|
|
||||||
|
|
||||||
#define kStartPosModelIndex 4
|
|
||||||
#define kEndPosModelIndex 14
|
|
||||||
#define kNumFullDistances (1 << (kEndPosModelIndex >> 1))
|
|
||||||
|
|
||||||
#define kNumPosSlotBits 6
|
|
||||||
#define kNumLenToPosStates 4
|
|
||||||
|
|
||||||
#define kNumAlignBits 4
|
|
||||||
#define kAlignTableSize (1 << kNumAlignBits)
|
|
||||||
|
|
||||||
#define kMatchMinLen 2
|
|
||||||
|
|
||||||
#define IsMatch 0
|
|
||||||
#define IsRep (IsMatch + (kNumStates << kNumPosBitsMax))
|
|
||||||
#define IsRepG0 (IsRep + kNumStates)
|
|
||||||
#define IsRepG1 (IsRepG0 + kNumStates)
|
|
||||||
#define IsRepG2 (IsRepG1 + kNumStates)
|
|
||||||
#define IsRep0Long (IsRepG2 + kNumStates)
|
|
||||||
#define PosSlot (IsRep0Long + (kNumStates << kNumPosBitsMax))
|
|
||||||
#define SpecPos (PosSlot + (kNumLenToPosStates << kNumPosSlotBits))
|
|
||||||
#define Align (SpecPos + kNumFullDistances - kEndPosModelIndex)
|
|
||||||
#define LenCoder (Align + kAlignTableSize)
|
|
||||||
#define RepLenCoder (LenCoder + kNumLenProbs)
|
|
||||||
#define Literal (RepLenCoder + kNumLenProbs)
|
|
||||||
|
|
||||||
#if Literal != LZMA_BASE_SIZE
|
|
||||||
StopCompilingDueBUG
|
|
||||||
#endif
|
|
||||||
|
|
||||||
int LzmaDecodeProperties(CLzmaProperties *propsRes, const unsigned char *propsData, int size)
|
|
||||||
{
|
|
||||||
unsigned char prop0;
|
|
||||||
if (size < LZMA_PROPERTIES_SIZE)
|
|
||||||
return LZMA_RESULT_DATA_ERROR;
|
|
||||||
prop0 = propsData[0];
|
|
||||||
if (prop0 >= (9 * 5 * 5))
|
|
||||||
return LZMA_RESULT_DATA_ERROR;
|
|
||||||
{
|
|
||||||
for (propsRes->pb = 0; prop0 >= (9 * 5); propsRes->pb++, prop0 -= (9 * 5));
|
|
||||||
for (propsRes->lp = 0; prop0 >= 9; propsRes->lp++, prop0 -= 9);
|
|
||||||
propsRes->lc = prop0;
|
|
||||||
/*
|
|
||||||
unsigned char remainder = (unsigned char)(prop0 / 9);
|
|
||||||
propsRes->lc = prop0 % 9;
|
|
||||||
propsRes->pb = remainder / 5;
|
|
||||||
propsRes->lp = remainder % 5;
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef _LZMA_OUT_READ
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
propsRes->DictionarySize = 0;
|
|
||||||
for (i = 0; i < 4; i++)
|
|
||||||
propsRes->DictionarySize += (UInt32)(propsData[1 + i]) << (i * 8);
|
|
||||||
if (propsRes->DictionarySize == 0)
|
|
||||||
propsRes->DictionarySize = 1;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
return LZMA_RESULT_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
#define kLzmaStreamWasFinishedId (-1)
|
|
||||||
|
|
||||||
int LzmaDecode(CLzmaDecoderState *vs,
|
|
||||||
#ifdef _LZMA_IN_CB
|
|
||||||
ILzmaInCallback *InCallback,
|
|
||||||
#else
|
|
||||||
const unsigned char *inStream, SizeT inSize, SizeT *inSizeProcessed,
|
|
||||||
#endif
|
|
||||||
unsigned char *outStream, SizeT outSize, SizeT *outSizeProcessed)
|
|
||||||
{
|
|
||||||
CProb *p = vs->Probs;
|
|
||||||
SizeT nowPos = 0;
|
|
||||||
Byte previousByte = 0;
|
|
||||||
UInt32 posStateMask = (1 << (vs->Properties.pb)) - 1;
|
|
||||||
UInt32 literalPosMask = (1 << (vs->Properties.lp)) - 1;
|
|
||||||
int lc = vs->Properties.lc;
|
|
||||||
|
|
||||||
#ifdef _LZMA_OUT_READ
|
|
||||||
|
|
||||||
UInt32 Range = vs->Range;
|
|
||||||
UInt32 Code = vs->Code;
|
|
||||||
#ifdef _LZMA_IN_CB
|
|
||||||
const Byte *Buffer = vs->Buffer;
|
|
||||||
const Byte *BufferLim = vs->BufferLim;
|
|
||||||
#else
|
|
||||||
const Byte *Buffer = inStream;
|
|
||||||
const Byte *BufferLim = inStream + inSize;
|
|
||||||
#endif
|
|
||||||
int state = vs->State;
|
|
||||||
UInt32 rep0 = vs->Reps[0], rep1 = vs->Reps[1], rep2 = vs->Reps[2], rep3 = vs->Reps[3];
|
|
||||||
int len = vs->RemainLen;
|
|
||||||
UInt32 globalPos = vs->GlobalPos;
|
|
||||||
UInt32 distanceLimit = vs->DistanceLimit;
|
|
||||||
|
|
||||||
Byte *dictionary = vs->Dictionary;
|
|
||||||
UInt32 dictionarySize = vs->Properties.DictionarySize;
|
|
||||||
UInt32 dictionaryPos = vs->DictionaryPos;
|
|
||||||
|
|
||||||
Byte tempDictionary[4];
|
|
||||||
|
|
||||||
#ifndef _LZMA_IN_CB
|
|
||||||
*inSizeProcessed = 0;
|
|
||||||
#endif
|
|
||||||
*outSizeProcessed = 0;
|
|
||||||
if (len == kLzmaStreamWasFinishedId)
|
|
||||||
return LZMA_RESULT_OK;
|
|
||||||
|
|
||||||
if (dictionarySize == 0)
|
|
||||||
{
|
|
||||||
dictionary = tempDictionary;
|
|
||||||
dictionarySize = 1;
|
|
||||||
tempDictionary[0] = vs->TempDictionary[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
if (len == kLzmaNeedInitId)
|
|
||||||
{
|
|
||||||
{
|
|
||||||
UInt32 numProbs = Literal + ((UInt32)LZMA_LIT_SIZE << (lc + vs->Properties.lp));
|
|
||||||
UInt32 i;
|
|
||||||
for (i = 0; i < numProbs; i++)
|
|
||||||
p[i] = kBitModelTotal >> 1;
|
|
||||||
rep0 = rep1 = rep2 = rep3 = 1;
|
|
||||||
state = 0;
|
|
||||||
globalPos = 0;
|
|
||||||
distanceLimit = 0;
|
|
||||||
dictionaryPos = 0;
|
|
||||||
dictionary[dictionarySize - 1] = 0;
|
|
||||||
#ifdef _LZMA_IN_CB
|
|
||||||
RC_INIT;
|
|
||||||
#else
|
|
||||||
RC_INIT(inStream, inSize);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
len = 0;
|
|
||||||
}
|
|
||||||
while(len != 0 && nowPos < outSize)
|
|
||||||
{
|
|
||||||
UInt32 pos = dictionaryPos - rep0;
|
|
||||||
if (pos >= dictionarySize)
|
|
||||||
pos += dictionarySize;
|
|
||||||
outStream[nowPos++] = dictionary[dictionaryPos] = dictionary[pos];
|
|
||||||
if (++dictionaryPos == dictionarySize)
|
|
||||||
dictionaryPos = 0;
|
|
||||||
len--;
|
|
||||||
}
|
|
||||||
if (dictionaryPos == 0)
|
|
||||||
previousByte = dictionary[dictionarySize - 1];
|
|
||||||
else
|
|
||||||
previousByte = dictionary[dictionaryPos - 1];
|
|
||||||
|
|
||||||
#else /* if !_LZMA_OUT_READ */
|
|
||||||
|
|
||||||
int state = 0;
|
|
||||||
UInt32 rep0 = 1, rep1 = 1, rep2 = 1, rep3 = 1;
|
|
||||||
int len = 0;
|
|
||||||
const Byte *Buffer;
|
|
||||||
const Byte *BufferLim;
|
|
||||||
UInt32 Range;
|
|
||||||
UInt32 Code;
|
|
||||||
|
|
||||||
#ifndef _LZMA_IN_CB
|
|
||||||
*inSizeProcessed = 0;
|
|
||||||
#endif
|
|
||||||
*outSizeProcessed = 0;
|
|
||||||
|
|
||||||
{
|
|
||||||
UInt32 i;
|
|
||||||
UInt32 numProbs = Literal + ((UInt32)LZMA_LIT_SIZE << (lc + vs->Properties.lp));
|
|
||||||
for (i = 0; i < numProbs; i++)
|
|
||||||
p[i] = kBitModelTotal >> 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef _LZMA_IN_CB
|
|
||||||
RC_INIT;
|
|
||||||
#else
|
|
||||||
RC_INIT(inStream, inSize);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* _LZMA_OUT_READ */
|
|
||||||
|
|
||||||
while(nowPos < outSize)
|
|
||||||
{
|
|
||||||
CProb *prob;
|
|
||||||
UInt32 bound;
|
|
||||||
int posState = (int)(
|
|
||||||
(nowPos
|
|
||||||
#ifdef _LZMA_OUT_READ
|
|
||||||
+ globalPos
|
|
||||||
#endif
|
|
||||||
)
|
|
||||||
& posStateMask);
|
|
||||||
|
|
||||||
prob = p + IsMatch + (state << kNumPosBitsMax) + posState;
|
|
||||||
IfBit0(prob)
|
|
||||||
{
|
|
||||||
int symbol = 1;
|
|
||||||
UpdateBit0(prob)
|
|
||||||
prob = p + Literal + (LZMA_LIT_SIZE *
|
|
||||||
(((
|
|
||||||
(nowPos
|
|
||||||
#ifdef _LZMA_OUT_READ
|
|
||||||
+ globalPos
|
|
||||||
#endif
|
|
||||||
)
|
|
||||||
& literalPosMask) << lc) + (previousByte >> (8 - lc))));
|
|
||||||
|
|
||||||
if (state >= kNumLitStates)
|
|
||||||
{
|
|
||||||
int matchByte;
|
|
||||||
#ifdef _LZMA_OUT_READ
|
|
||||||
UInt32 pos = dictionaryPos - rep0;
|
|
||||||
if (pos >= dictionarySize)
|
|
||||||
pos += dictionarySize;
|
|
||||||
matchByte = dictionary[pos];
|
|
||||||
#else
|
|
||||||
matchByte = outStream[nowPos - rep0];
|
|
||||||
#endif
|
|
||||||
do
|
|
||||||
{
|
|
||||||
int bit;
|
|
||||||
CProb *probLit;
|
|
||||||
matchByte <<= 1;
|
|
||||||
bit = (matchByte & 0x100);
|
|
||||||
probLit = prob + 0x100 + bit + symbol;
|
|
||||||
RC_GET_BIT2(probLit, symbol, if (bit != 0) break, if (bit == 0) break)
|
|
||||||
}
|
|
||||||
while (symbol < 0x100);
|
|
||||||
}
|
|
||||||
while (symbol < 0x100)
|
|
||||||
{
|
|
||||||
CProb *probLit = prob + symbol;
|
|
||||||
RC_GET_BIT(probLit, symbol)
|
|
||||||
}
|
|
||||||
previousByte = (Byte)symbol;
|
|
||||||
|
|
||||||
outStream[nowPos++] = previousByte;
|
|
||||||
#ifdef _LZMA_OUT_READ
|
|
||||||
if (distanceLimit < dictionarySize)
|
|
||||||
distanceLimit++;
|
|
||||||
|
|
||||||
dictionary[dictionaryPos] = previousByte;
|
|
||||||
if (++dictionaryPos == dictionarySize)
|
|
||||||
dictionaryPos = 0;
|
|
||||||
#endif
|
|
||||||
if (state < 4) state = 0;
|
|
||||||
else if (state < 10) state -= 3;
|
|
||||||
else state -= 6;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
UpdateBit1(prob);
|
|
||||||
prob = p + IsRep + state;
|
|
||||||
IfBit0(prob)
|
|
||||||
{
|
|
||||||
UpdateBit0(prob);
|
|
||||||
rep3 = rep2;
|
|
||||||
rep2 = rep1;
|
|
||||||
rep1 = rep0;
|
|
||||||
state = state < kNumLitStates ? 0 : 3;
|
|
||||||
prob = p + LenCoder;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
UpdateBit1(prob);
|
|
||||||
prob = p + IsRepG0 + state;
|
|
||||||
IfBit0(prob)
|
|
||||||
{
|
|
||||||
UpdateBit0(prob);
|
|
||||||
prob = p + IsRep0Long + (state << kNumPosBitsMax) + posState;
|
|
||||||
IfBit0(prob)
|
|
||||||
{
|
|
||||||
#ifdef _LZMA_OUT_READ
|
|
||||||
UInt32 pos;
|
|
||||||
#endif
|
|
||||||
UpdateBit0(prob);
|
|
||||||
|
|
||||||
#ifdef _LZMA_OUT_READ
|
|
||||||
if (distanceLimit == 0)
|
|
||||||
#else
|
|
||||||
if (nowPos == 0)
|
|
||||||
#endif
|
|
||||||
return LZMA_RESULT_DATA_ERROR;
|
|
||||||
|
|
||||||
state = state < kNumLitStates ? 9 : 11;
|
|
||||||
#ifdef _LZMA_OUT_READ
|
|
||||||
pos = dictionaryPos - rep0;
|
|
||||||
if (pos >= dictionarySize)
|
|
||||||
pos += dictionarySize;
|
|
||||||
previousByte = dictionary[pos];
|
|
||||||
dictionary[dictionaryPos] = previousByte;
|
|
||||||
if (++dictionaryPos == dictionarySize)
|
|
||||||
dictionaryPos = 0;
|
|
||||||
#else
|
|
||||||
previousByte = outStream[nowPos - rep0];
|
|
||||||
#endif
|
|
||||||
outStream[nowPos++] = previousByte;
|
|
||||||
#ifdef _LZMA_OUT_READ
|
|
||||||
if (distanceLimit < dictionarySize)
|
|
||||||
distanceLimit++;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
UpdateBit1(prob);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
UInt32 distance;
|
|
||||||
UpdateBit1(prob);
|
|
||||||
prob = p + IsRepG1 + state;
|
|
||||||
IfBit0(prob)
|
|
||||||
{
|
|
||||||
UpdateBit0(prob);
|
|
||||||
distance = rep1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
UpdateBit1(prob);
|
|
||||||
prob = p + IsRepG2 + state;
|
|
||||||
IfBit0(prob)
|
|
||||||
{
|
|
||||||
UpdateBit0(prob);
|
|
||||||
distance = rep2;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
UpdateBit1(prob);
|
|
||||||
distance = rep3;
|
|
||||||
rep3 = rep2;
|
|
||||||
}
|
|
||||||
rep2 = rep1;
|
|
||||||
}
|
|
||||||
rep1 = rep0;
|
|
||||||
rep0 = distance;
|
|
||||||
}
|
|
||||||
state = state < kNumLitStates ? 8 : 11;
|
|
||||||
prob = p + RepLenCoder;
|
|
||||||
}
|
|
||||||
{
|
|
||||||
int numBits, offset;
|
|
||||||
CProb *probLen = prob + LenChoice;
|
|
||||||
IfBit0(probLen)
|
|
||||||
{
|
|
||||||
UpdateBit0(probLen);
|
|
||||||
probLen = prob + LenLow + (posState << kLenNumLowBits);
|
|
||||||
offset = 0;
|
|
||||||
numBits = kLenNumLowBits;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
UpdateBit1(probLen);
|
|
||||||
probLen = prob + LenChoice2;
|
|
||||||
IfBit0(probLen)
|
|
||||||
{
|
|
||||||
UpdateBit0(probLen);
|
|
||||||
probLen = prob + LenMid + (posState << kLenNumMidBits);
|
|
||||||
offset = kLenNumLowSymbols;
|
|
||||||
numBits = kLenNumMidBits;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
UpdateBit1(probLen);
|
|
||||||
probLen = prob + LenHigh;
|
|
||||||
offset = kLenNumLowSymbols + kLenNumMidSymbols;
|
|
||||||
numBits = kLenNumHighBits;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
RangeDecoderBitTreeDecode(probLen, numBits, len);
|
|
||||||
len += offset;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (state < 4)
|
|
||||||
{
|
|
||||||
int posSlot;
|
|
||||||
state += kNumLitStates;
|
|
||||||
prob = p + PosSlot +
|
|
||||||
((len < kNumLenToPosStates ? len : kNumLenToPosStates - 1) <<
|
|
||||||
kNumPosSlotBits);
|
|
||||||
RangeDecoderBitTreeDecode(prob, kNumPosSlotBits, posSlot);
|
|
||||||
if (posSlot >= kStartPosModelIndex)
|
|
||||||
{
|
|
||||||
int numDirectBits = ((posSlot >> 1) - 1);
|
|
||||||
rep0 = (2 | ((UInt32)posSlot & 1));
|
|
||||||
if (posSlot < kEndPosModelIndex)
|
|
||||||
{
|
|
||||||
rep0 <<= numDirectBits;
|
|
||||||
prob = p + SpecPos + rep0 - posSlot - 1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
numDirectBits -= kNumAlignBits;
|
|
||||||
do
|
|
||||||
{
|
|
||||||
RC_NORMALIZE
|
|
||||||
Range >>= 1;
|
|
||||||
rep0 <<= 1;
|
|
||||||
if (Code >= Range)
|
|
||||||
{
|
|
||||||
Code -= Range;
|
|
||||||
rep0 |= 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
while (--numDirectBits != 0);
|
|
||||||
prob = p + Align;
|
|
||||||
rep0 <<= kNumAlignBits;
|
|
||||||
numDirectBits = kNumAlignBits;
|
|
||||||
}
|
|
||||||
{
|
|
||||||
int i = 1;
|
|
||||||
int mi = 1;
|
|
||||||
do
|
|
||||||
{
|
|
||||||
CProb *prob3 = prob + mi;
|
|
||||||
RC_GET_BIT2(prob3, mi, ; , rep0 |= i);
|
|
||||||
i <<= 1;
|
|
||||||
}
|
|
||||||
while(--numDirectBits != 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
rep0 = posSlot;
|
|
||||||
if (++rep0 == (UInt32)(0))
|
|
||||||
{
|
|
||||||
/* it's for stream version */
|
|
||||||
len = kLzmaStreamWasFinishedId;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
len += kMatchMinLen;
|
|
||||||
#ifdef _LZMA_OUT_READ
|
|
||||||
if (rep0 > distanceLimit)
|
|
||||||
#else
|
|
||||||
if (rep0 > nowPos)
|
|
||||||
#endif
|
|
||||||
return LZMA_RESULT_DATA_ERROR;
|
|
||||||
|
|
||||||
#ifdef _LZMA_OUT_READ
|
|
||||||
if (dictionarySize - distanceLimit > (UInt32)len)
|
|
||||||
distanceLimit += len;
|
|
||||||
else
|
|
||||||
distanceLimit = dictionarySize;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
do
|
|
||||||
{
|
|
||||||
#ifdef _LZMA_OUT_READ
|
|
||||||
UInt32 pos = dictionaryPos - rep0;
|
|
||||||
if (pos >= dictionarySize)
|
|
||||||
pos += dictionarySize;
|
|
||||||
previousByte = dictionary[pos];
|
|
||||||
dictionary[dictionaryPos] = previousByte;
|
|
||||||
if (++dictionaryPos == dictionarySize)
|
|
||||||
dictionaryPos = 0;
|
|
||||||
#else
|
|
||||||
previousByte = outStream[nowPos - rep0];
|
|
||||||
#endif
|
|
||||||
len--;
|
|
||||||
outStream[nowPos++] = previousByte;
|
|
||||||
}
|
|
||||||
while(len != 0 && nowPos < outSize);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
RC_NORMALIZE;
|
|
||||||
|
|
||||||
#ifdef _LZMA_OUT_READ
|
|
||||||
vs->Range = Range;
|
|
||||||
vs->Code = Code;
|
|
||||||
vs->DictionaryPos = dictionaryPos;
|
|
||||||
vs->GlobalPos = globalPos + (UInt32)nowPos;
|
|
||||||
vs->DistanceLimit = distanceLimit;
|
|
||||||
vs->Reps[0] = rep0;
|
|
||||||
vs->Reps[1] = rep1;
|
|
||||||
vs->Reps[2] = rep2;
|
|
||||||
vs->Reps[3] = rep3;
|
|
||||||
vs->State = state;
|
|
||||||
vs->RemainLen = len;
|
|
||||||
vs->TempDictionary[0] = tempDictionary[0];
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef _LZMA_IN_CB
|
|
||||||
vs->Buffer = Buffer;
|
|
||||||
vs->BufferLim = BufferLim;
|
|
||||||
#else
|
|
||||||
*inSizeProcessed = (SizeT)(Buffer - inStream);
|
|
||||||
#endif
|
|
||||||
*outSizeProcessed = nowPos;
|
|
||||||
return LZMA_RESULT_OK;
|
|
||||||
}
|
|
@ -1,113 +0,0 @@
|
|||||||
/*
|
|
||||||
LzmaDecode.h
|
|
||||||
LZMA Decoder interface
|
|
||||||
|
|
||||||
LZMA SDK 4.40 Copyright (c) 1999-2006 Igor Pavlov (2006-05-01)
|
|
||||||
http://www.7-zip.org/
|
|
||||||
|
|
||||||
LZMA SDK is licensed under two licenses:
|
|
||||||
1) GNU Lesser General Public License (GNU LGPL)
|
|
||||||
2) Common Public License (CPL)
|
|
||||||
It means that you can select one of these two licenses and
|
|
||||||
follow rules of that license.
|
|
||||||
|
|
||||||
SPECIAL EXCEPTION:
|
|
||||||
Igor Pavlov, as the author of this code, expressly permits you to
|
|
||||||
statically or dynamically link your code (or bind by name) to the
|
|
||||||
interfaces of this file without subjecting your linked code to the
|
|
||||||
terms of the CPL or GNU LGPL. Any modifications or additions
|
|
||||||
to this file, however, are subject to the LGPL or CPL terms.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef __LZMADECODE_H
|
|
||||||
#define __LZMADECODE_H
|
|
||||||
|
|
||||||
#include "LzmaTypes.h"
|
|
||||||
|
|
||||||
/* #define _LZMA_IN_CB */
|
|
||||||
/* Use callback for input data */
|
|
||||||
|
|
||||||
/* #define _LZMA_OUT_READ */
|
|
||||||
/* Use read function for output data */
|
|
||||||
|
|
||||||
/* #define _LZMA_PROB32 */
|
|
||||||
/* It can increase speed on some 32-bit CPUs,
|
|
||||||
but memory usage will be doubled in that case */
|
|
||||||
|
|
||||||
/* #define _LZMA_LOC_OPT */
|
|
||||||
/* Enable local speed optimizations inside code */
|
|
||||||
|
|
||||||
#ifdef _LZMA_PROB32
|
|
||||||
#define CProb UInt32
|
|
||||||
#else
|
|
||||||
#define CProb UInt16
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define LZMA_RESULT_OK 0
|
|
||||||
#define LZMA_RESULT_DATA_ERROR 1
|
|
||||||
|
|
||||||
#ifdef _LZMA_IN_CB
|
|
||||||
typedef struct _ILzmaInCallback
|
|
||||||
{
|
|
||||||
int (*Read)(void *object, const unsigned char **buffer, SizeT *bufferSize);
|
|
||||||
} ILzmaInCallback;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define LZMA_BASE_SIZE 1846
|
|
||||||
#define LZMA_LIT_SIZE 768
|
|
||||||
|
|
||||||
#define LZMA_PROPERTIES_SIZE 5
|
|
||||||
|
|
||||||
typedef struct _CLzmaProperties
|
|
||||||
{
|
|
||||||
int lc;
|
|
||||||
int lp;
|
|
||||||
int pb;
|
|
||||||
#ifdef _LZMA_OUT_READ
|
|
||||||
UInt32 DictionarySize;
|
|
||||||
#endif
|
|
||||||
}CLzmaProperties;
|
|
||||||
|
|
||||||
int LzmaDecodeProperties(CLzmaProperties *propsRes, const unsigned char *propsData, int size);
|
|
||||||
|
|
||||||
#define LzmaGetNumProbs(Properties) (LZMA_BASE_SIZE + (LZMA_LIT_SIZE << ((Properties)->lc + (Properties)->lp)))
|
|
||||||
|
|
||||||
#define kLzmaNeedInitId (-2)
|
|
||||||
|
|
||||||
typedef struct _CLzmaDecoderState
|
|
||||||
{
|
|
||||||
CLzmaProperties Properties;
|
|
||||||
CProb *Probs;
|
|
||||||
|
|
||||||
#ifdef _LZMA_IN_CB
|
|
||||||
const unsigned char *Buffer;
|
|
||||||
const unsigned char *BufferLim;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef _LZMA_OUT_READ
|
|
||||||
unsigned char *Dictionary;
|
|
||||||
UInt32 Range;
|
|
||||||
UInt32 Code;
|
|
||||||
UInt32 DictionaryPos;
|
|
||||||
UInt32 GlobalPos;
|
|
||||||
UInt32 DistanceLimit;
|
|
||||||
UInt32 Reps[4];
|
|
||||||
int State;
|
|
||||||
int RemainLen;
|
|
||||||
unsigned char TempDictionary[4];
|
|
||||||
#endif
|
|
||||||
} CLzmaDecoderState;
|
|
||||||
|
|
||||||
#ifdef _LZMA_OUT_READ
|
|
||||||
#define LzmaDecoderInit(vs) { (vs)->RemainLen = kLzmaNeedInitId; }
|
|
||||||
#endif
|
|
||||||
|
|
||||||
int LzmaDecode(CLzmaDecoderState *vs,
|
|
||||||
#ifdef _LZMA_IN_CB
|
|
||||||
ILzmaInCallback *inCallback,
|
|
||||||
#else
|
|
||||||
const unsigned char *inStream, SizeT inSize, SizeT *inSizeProcessed,
|
|
||||||
#endif
|
|
||||||
unsigned char *outStream, SizeT outSize, SizeT *outSizeProcessed);
|
|
||||||
|
|
||||||
#endif
|
|
@ -1,45 +0,0 @@
|
|||||||
/*
|
|
||||||
LzmaTypes.h
|
|
||||||
|
|
||||||
Types for LZMA Decoder
|
|
||||||
|
|
||||||
This file written and distributed to public domain by Igor Pavlov.
|
|
||||||
This file is part of LZMA SDK 4.40 (2006-05-01)
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef __LZMATYPES_H
|
|
||||||
#define __LZMATYPES_H
|
|
||||||
|
|
||||||
#ifndef _7ZIP_BYTE_DEFINED
|
|
||||||
#define _7ZIP_BYTE_DEFINED
|
|
||||||
typedef unsigned char Byte;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef _7ZIP_UINT16_DEFINED
|
|
||||||
#define _7ZIP_UINT16_DEFINED
|
|
||||||
typedef unsigned short UInt16;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef _7ZIP_UINT32_DEFINED
|
|
||||||
#define _7ZIP_UINT32_DEFINED
|
|
||||||
#ifdef _LZMA_UINT32_IS_ULONG
|
|
||||||
typedef unsigned long UInt32;
|
|
||||||
#else
|
|
||||||
typedef unsigned int UInt32;
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* #define _LZMA_SYSTEM_SIZE_T */
|
|
||||||
/* Use system's size_t. You can use it to enable 64-bit sizes supporting */
|
|
||||||
|
|
||||||
#ifndef _7ZIP_SIZET_DEFINED
|
|
||||||
#define _7ZIP_SIZET_DEFINED
|
|
||||||
#ifdef _LZMA_SYSTEM_SIZE_T
|
|
||||||
#include <stddef.h>
|
|
||||||
typedef size_t SizeT;
|
|
||||||
#else
|
|
||||||
typedef UInt32 SizeT;
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
|
@ -1,329 +1,362 @@
|
|||||||
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
|
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
|
||||||
// Copyright (C) 1999-2003 Forgotten
|
// Copyright (C) 1999-2003 Forgotten
|
||||||
// Copyright (C) 2004 Forgotten and the VBA development team
|
// Copyright (C) 2004 Forgotten and the VBA development team
|
||||||
|
|
||||||
// This program is free software; you can redistribute it and/or modify
|
// This program is free software; you can redistribute it and/or modify
|
||||||
// it under the terms of the GNU General Public License as published by
|
// it under the terms of the GNU General Public License as published by
|
||||||
// the Free Software Foundation; either version 2, or(at your option)
|
// the Free Software Foundation; either version 2, or(at your option)
|
||||||
// any later version.
|
// any later version.
|
||||||
//
|
//
|
||||||
// This program is distributed in the hope that it will be useful,
|
// This program is distributed in the hope that it will be useful,
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
// GNU General Public License for more details.
|
// GNU General Public License for more details.
|
||||||
//
|
//
|
||||||
// You should have received a copy of the GNU General Public License
|
// You should have received a copy of the GNU General Public License
|
||||||
// along with this program; if not, write to the Free Software Foundation,
|
// along with this program; if not, write to the Free Software Foundation,
|
||||||
// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "CheatSearch.h"
|
#include "CheatSearch.h"
|
||||||
|
|
||||||
CheatSearchBlock cheatSearchBlocks[4];
|
CheatSearchBlock cheatSearchBlocks[4];
|
||||||
|
|
||||||
CheatSearchData cheatSearchData = {
|
CheatSearchData cheatSearchData = {
|
||||||
0,
|
0,
|
||||||
cheatSearchBlocks
|
cheatSearchBlocks
|
||||||
};
|
};
|
||||||
|
|
||||||
static bool cheatSearchEQ(u32 a, u32 b)
|
static bool cheatSearchEQ(u32 a, u32 b)
|
||||||
{
|
{
|
||||||
return a == b;
|
return a == b;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool cheatSearchNE(u32 a, u32 b)
|
static bool cheatSearchNE(u32 a, u32 b)
|
||||||
{
|
{
|
||||||
return a != b;
|
return a != b;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool cheatSearchLT(u32 a, u32 b)
|
static bool cheatSearchLT(u32 a, u32 b)
|
||||||
{
|
{
|
||||||
return a < b;
|
return a < b;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool cheatSearchLE(u32 a, u32 b)
|
static bool cheatSearchLE(u32 a, u32 b)
|
||||||
{
|
{
|
||||||
return a <= b;
|
return a <= b;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool cheatSearchGT(u32 a, u32 b)
|
static bool cheatSearchGT(u32 a, u32 b)
|
||||||
{
|
{
|
||||||
return a > b;
|
return a > b;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool cheatSearchGE(u32 a, u32 b)
|
static bool cheatSearchGE(u32 a, u32 b)
|
||||||
{
|
{
|
||||||
return a >= b;
|
return a >= b;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool cheatSearchSignedEQ(s32 a, s32 b)
|
static bool cheatSearchSignedEQ(s32 a, s32 b)
|
||||||
{
|
{
|
||||||
return a == b;
|
return a == b;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool cheatSearchSignedNE(s32 a, s32 b)
|
static bool cheatSearchSignedNE(s32 a, s32 b)
|
||||||
{
|
{
|
||||||
return a != b;
|
return a != b;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool cheatSearchSignedLT(s32 a, s32 b)
|
static bool cheatSearchSignedLT(s32 a, s32 b)
|
||||||
{
|
{
|
||||||
return a < b;
|
return a < b;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool cheatSearchSignedLE(s32 a, s32 b)
|
static bool cheatSearchSignedLE(s32 a, s32 b)
|
||||||
{
|
{
|
||||||
return a <= b;
|
return a <= b;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool cheatSearchSignedGT(s32 a, s32 b)
|
static bool cheatSearchSignedGT(s32 a, s32 b)
|
||||||
{
|
{
|
||||||
return a > b;
|
return a > b;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool cheatSearchSignedGE(s32 a, s32 b)
|
static bool cheatSearchSignedGE(s32 a, s32 b)
|
||||||
{
|
{
|
||||||
return a >= b;
|
return a >= b;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool (*cheatSearchFunc[])(u32,u32) = {
|
static bool (*cheatSearchFunc[])(u32,u32) = {
|
||||||
cheatSearchEQ,
|
cheatSearchEQ,
|
||||||
cheatSearchNE,
|
cheatSearchNE,
|
||||||
cheatSearchLT,
|
cheatSearchLT,
|
||||||
cheatSearchLE,
|
cheatSearchLE,
|
||||||
cheatSearchGT,
|
cheatSearchGT,
|
||||||
cheatSearchGE
|
cheatSearchGE
|
||||||
};
|
};
|
||||||
|
|
||||||
static bool (*cheatSearchSignedFunc[])(s32,s32) = {
|
static bool (*cheatSearchSignedFunc[])(s32,s32) = {
|
||||||
cheatSearchSignedEQ,
|
cheatSearchSignedEQ,
|
||||||
cheatSearchSignedNE,
|
cheatSearchSignedNE,
|
||||||
cheatSearchSignedLT,
|
cheatSearchSignedLT,
|
||||||
cheatSearchSignedLE,
|
cheatSearchSignedLE,
|
||||||
cheatSearchSignedGT,
|
cheatSearchSignedGT,
|
||||||
cheatSearchSignedGE
|
cheatSearchSignedGE
|
||||||
};
|
};
|
||||||
|
|
||||||
void cheatSearchCleanup(CheatSearchData *cs)
|
void cheatSearchCleanup(CheatSearchData *cs)
|
||||||
{
|
{
|
||||||
int count = cs->count;
|
int count = cs->count;
|
||||||
|
|
||||||
for(int i = 0; i < count; i++) {
|
for(int i = 0; i < count; i++)
|
||||||
free(cs->blocks[i].saved);
|
{
|
||||||
free(cs->blocks[i].bits);
|
free(cs->blocks[i].saved);
|
||||||
}
|
free(cs->blocks[i].bits);
|
||||||
cs->count = 0;
|
}
|
||||||
}
|
cs->count = 0;
|
||||||
|
}
|
||||||
void cheatSearchStart(const CheatSearchData *cs)
|
|
||||||
{
|
void cheatSearchStart(const CheatSearchData *cs)
|
||||||
int count = cs->count;
|
{
|
||||||
|
int count = cs->count;
|
||||||
for(int i = 0; i < count; i++) {
|
|
||||||
CheatSearchBlock *block = &cs->blocks[i];
|
for(int i = 0; i < count; i++)
|
||||||
|
{
|
||||||
memset(block->bits, 0xff, block->size >> 3);
|
CheatSearchBlock *block = &cs->blocks[i];
|
||||||
memcpy(block->saved, block->data, block->size);
|
|
||||||
}
|
memset(block->bits, 0xff, block->size >> 3);
|
||||||
}
|
memcpy(block->saved, block->data, block->size);
|
||||||
|
}
|
||||||
s32 cheatSearchSignedRead(u8 *data, int off, int size)
|
}
|
||||||
{
|
|
||||||
u32 res = data[off++];
|
s32 cheatSearchSignedRead(u8 *data, int off, int size)
|
||||||
|
{
|
||||||
switch(size) {
|
u32 res = data[off++];
|
||||||
case BITS_8:
|
|
||||||
res <<= 24;
|
switch(size)
|
||||||
return ((s32)res) >> 24;
|
{
|
||||||
case BITS_16:
|
case BITS_8:
|
||||||
res |= ((u32)data[off++])<<8;
|
res <<= 24;
|
||||||
res <<= 16;
|
return ((s32)res) >> 24;
|
||||||
return ((s32)res) >> 16;
|
case BITS_16:
|
||||||
case BITS_32:
|
res |= ((u32)data[off++])<<8;
|
||||||
res |= ((u32)data[off++])<<8;
|
res <<= 16;
|
||||||
res |= ((u32)data[off++])<<16;
|
return ((s32)res) >> 16;
|
||||||
res |= ((u32)data[off++])<<24;
|
case BITS_32:
|
||||||
return (s32)res;
|
res |= ((u32)data[off++])<<8;
|
||||||
}
|
res |= ((u32)data[off++])<<16;
|
||||||
return (s32)res;
|
res |= ((u32)data[off++])<<24;
|
||||||
}
|
return (s32)res;
|
||||||
|
}
|
||||||
u32 cheatSearchRead(u8 *data, int off, int size)
|
return (s32)res;
|
||||||
{
|
}
|
||||||
u32 res = data[off++];
|
|
||||||
if(size == BITS_16)
|
u32 cheatSearchRead(u8 *data, int off, int size)
|
||||||
res |= ((u32)data[off++])<<8;
|
{
|
||||||
else if(size == BITS_32) {
|
u32 res = data[off++];
|
||||||
res |= ((u32)data[off++])<<8;
|
if(size == BITS_16)
|
||||||
res |= ((u32)data[off++])<<16;
|
res |= ((u32)data[off++])<<8;
|
||||||
res |= ((u32)data[off++])<<24;
|
else if(size == BITS_32)
|
||||||
}
|
{
|
||||||
return res;
|
res |= ((u32)data[off++])<<8;
|
||||||
}
|
res |= ((u32)data[off++])<<16;
|
||||||
|
res |= ((u32)data[off++])<<24;
|
||||||
void cheatSearch(const CheatSearchData *cs, int compare, int size,
|
}
|
||||||
bool isSigned)
|
return res;
|
||||||
{
|
}
|
||||||
if(compare < 0 || compare > SEARCH_GE)
|
|
||||||
return;
|
void cheatSearch(const CheatSearchData *cs, int compare, int size,
|
||||||
int inc = 1;
|
bool isSigned)
|
||||||
if(size == BITS_16)
|
{
|
||||||
inc = 2;
|
if(compare < 0 || compare > SEARCH_GE)
|
||||||
else if(size == BITS_32)
|
return;
|
||||||
inc = 4;
|
int inc = 1;
|
||||||
|
if(size == BITS_16)
|
||||||
if(isSigned) {
|
inc = 2;
|
||||||
bool (*func)(s32,s32) = cheatSearchSignedFunc[compare];
|
else if(size == BITS_32)
|
||||||
|
inc = 4;
|
||||||
for(int i = 0; i < cs->count; i++) {
|
|
||||||
CheatSearchBlock *block = &cs->blocks[i];
|
if(isSigned)
|
||||||
int size2 = block->size;
|
{
|
||||||
u8 *bits = block->bits;
|
bool (*func)(s32,s32) = cheatSearchSignedFunc[compare];
|
||||||
u8 *data = block->data;
|
|
||||||
u8 *saved = block->saved;
|
for(int i = 0; i < cs->count; i++)
|
||||||
|
{
|
||||||
for(int j = 0; j < size2; j += inc) {
|
CheatSearchBlock *block = &cs->blocks[i];
|
||||||
if(IS_BIT_SET(bits, j)) {
|
int size2 = block->size;
|
||||||
s32 a = cheatSearchSignedRead(data, j, size);
|
u8 *bits = block->bits;
|
||||||
s32 b = cheatSearchSignedRead(saved,j, size);
|
u8 *data = block->data;
|
||||||
|
u8 *saved = block->saved;
|
||||||
if(!func(a, b)) {
|
|
||||||
CLEAR_BIT(bits, j);
|
for(int j = 0; j < size2; j += inc)
|
||||||
if(size == BITS_16)
|
{
|
||||||
CLEAR_BIT(bits, j+1);
|
if(IS_BIT_SET(bits, j))
|
||||||
if(size == BITS_32) {
|
{
|
||||||
CLEAR_BIT(bits, j+2);
|
s32 a = cheatSearchSignedRead(data, j, size);
|
||||||
CLEAR_BIT(bits, j+3);
|
s32 b = cheatSearchSignedRead(saved,j, size);
|
||||||
}
|
|
||||||
}
|
if(!func(a, b))
|
||||||
}
|
{
|
||||||
}
|
CLEAR_BIT(bits, j);
|
||||||
}
|
if(size == BITS_16)
|
||||||
} else {
|
CLEAR_BIT(bits, j+1);
|
||||||
bool (*func)(u32,u32) = cheatSearchFunc[compare];
|
if(size == BITS_32)
|
||||||
|
{
|
||||||
for(int i = 0; i < cs->count; i++) {
|
CLEAR_BIT(bits, j+2);
|
||||||
CheatSearchBlock *block = &cs->blocks[i];
|
CLEAR_BIT(bits, j+3);
|
||||||
int size2 = block->size;
|
}
|
||||||
u8 *bits = block->bits;
|
}
|
||||||
u8 *data = block->data;
|
}
|
||||||
u8 *saved = block->saved;
|
}
|
||||||
|
}
|
||||||
for(int j = 0; j < size2; j += inc) {
|
}
|
||||||
if(IS_BIT_SET(bits, j)) {
|
else
|
||||||
u32 a = cheatSearchRead(data, j, size);
|
{
|
||||||
u32 b = cheatSearchRead(saved,j, size);
|
bool (*func)(u32,u32) = cheatSearchFunc[compare];
|
||||||
|
|
||||||
if(!func(a, b)) {
|
for(int i = 0; i < cs->count; i++)
|
||||||
CLEAR_BIT(bits, j);
|
{
|
||||||
if(size == BITS_16)
|
CheatSearchBlock *block = &cs->blocks[i];
|
||||||
CLEAR_BIT(bits, j+1);
|
int size2 = block->size;
|
||||||
if(size == BITS_32) {
|
u8 *bits = block->bits;
|
||||||
CLEAR_BIT(bits, j+2);
|
u8 *data = block->data;
|
||||||
CLEAR_BIT(bits, j+3);
|
u8 *saved = block->saved;
|
||||||
}
|
|
||||||
}
|
for(int j = 0; j < size2; j += inc)
|
||||||
}
|
{
|
||||||
}
|
if(IS_BIT_SET(bits, j))
|
||||||
}
|
{
|
||||||
}
|
u32 a = cheatSearchRead(data, j, size);
|
||||||
}
|
u32 b = cheatSearchRead(saved,j, size);
|
||||||
|
|
||||||
void cheatSearchValue(const CheatSearchData *cs, int compare, int size,
|
if(!func(a, b))
|
||||||
bool isSigned, u32 value)
|
{
|
||||||
{
|
CLEAR_BIT(bits, j);
|
||||||
if(compare < 0 || compare > SEARCH_GE)
|
if(size == BITS_16)
|
||||||
return;
|
CLEAR_BIT(bits, j+1);
|
||||||
int inc = 1;
|
if(size == BITS_32)
|
||||||
if(size == BITS_16)
|
{
|
||||||
inc = 2;
|
CLEAR_BIT(bits, j+2);
|
||||||
else if(size == BITS_32)
|
CLEAR_BIT(bits, j+3);
|
||||||
inc = 4;
|
}
|
||||||
|
}
|
||||||
if(isSigned) {
|
}
|
||||||
bool (*func)(s32,s32) = cheatSearchSignedFunc[compare];
|
}
|
||||||
|
}
|
||||||
for(int i = 0; i < cs->count; i++) {
|
}
|
||||||
CheatSearchBlock *block = &cs->blocks[i];
|
}
|
||||||
int size2 = block->size;
|
|
||||||
u8 *bits = block->bits;
|
void cheatSearchValue(const CheatSearchData *cs, int compare, int size,
|
||||||
u8 *data = block->data;
|
bool isSigned, u32 value)
|
||||||
|
{
|
||||||
for(int j = 0; j < size2; j += inc) {
|
if(compare < 0 || compare > SEARCH_GE)
|
||||||
if(IS_BIT_SET(bits, j)) {
|
return;
|
||||||
s32 a = cheatSearchSignedRead(data, j, size);
|
int inc = 1;
|
||||||
s32 b = (s32)value;
|
if(size == BITS_16)
|
||||||
|
inc = 2;
|
||||||
if(!func(a, b)) {
|
else if(size == BITS_32)
|
||||||
CLEAR_BIT(bits, j);
|
inc = 4;
|
||||||
if(size == BITS_16)
|
|
||||||
CLEAR_BIT(bits, j+1);
|
if(isSigned)
|
||||||
if(size == BITS_32) {
|
{
|
||||||
CLEAR_BIT(bits, j+2);
|
bool (*func)(s32,s32) = cheatSearchSignedFunc[compare];
|
||||||
CLEAR_BIT(bits, j+3);
|
|
||||||
}
|
for(int i = 0; i < cs->count; i++)
|
||||||
}
|
{
|
||||||
}
|
CheatSearchBlock *block = &cs->blocks[i];
|
||||||
}
|
int size2 = block->size;
|
||||||
}
|
u8 *bits = block->bits;
|
||||||
} else {
|
u8 *data = block->data;
|
||||||
bool (*func)(u32,u32) = cheatSearchFunc[compare];
|
|
||||||
|
for(int j = 0; j < size2; j += inc)
|
||||||
for(int i = 0; i < cs->count; i++) {
|
{
|
||||||
CheatSearchBlock *block = &cs->blocks[i];
|
if(IS_BIT_SET(bits, j))
|
||||||
int size2 = block->size;
|
{
|
||||||
u8 *bits = block->bits;
|
s32 a = cheatSearchSignedRead(data, j, size);
|
||||||
u8 *data = block->data;
|
s32 b = (s32)value;
|
||||||
|
|
||||||
for(int j = 0; j < size2; j += inc) {
|
if(!func(a, b))
|
||||||
if(IS_BIT_SET(bits, j)) {
|
{
|
||||||
u32 a = cheatSearchRead(data, j, size);
|
CLEAR_BIT(bits, j);
|
||||||
|
if(size == BITS_16)
|
||||||
if(!func(a, value)) {
|
CLEAR_BIT(bits, j+1);
|
||||||
CLEAR_BIT(bits, j);
|
if(size == BITS_32)
|
||||||
if(size == BITS_16)
|
{
|
||||||
CLEAR_BIT(bits, j+1);
|
CLEAR_BIT(bits, j+2);
|
||||||
if(size == BITS_32) {
|
CLEAR_BIT(bits, j+3);
|
||||||
CLEAR_BIT(bits, j+2);
|
}
|
||||||
CLEAR_BIT(bits, j+3);
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
else
|
||||||
}
|
{
|
||||||
}
|
bool (*func)(u32,u32) = cheatSearchFunc[compare];
|
||||||
|
|
||||||
int cheatSearchGetCount(const CheatSearchData *cs, int size)
|
for(int i = 0; i < cs->count; i++)
|
||||||
{
|
{
|
||||||
int res = 0;
|
CheatSearchBlock *block = &cs->blocks[i];
|
||||||
int inc = 1;
|
int size2 = block->size;
|
||||||
if(size == BITS_16)
|
u8 *bits = block->bits;
|
||||||
inc = 2;
|
u8 *data = block->data;
|
||||||
else if(size == BITS_32)
|
|
||||||
inc = 4;
|
for(int j = 0; j < size2; j += inc)
|
||||||
|
{
|
||||||
for(int i = 0; i < cs->count; i++) {
|
if(IS_BIT_SET(bits, j))
|
||||||
CheatSearchBlock *block = &cs->blocks[i];
|
{
|
||||||
|
u32 a = cheatSearchRead(data, j, size);
|
||||||
int size2 = block->size;
|
|
||||||
u8 *bits = block->bits;
|
if(!func(a, value))
|
||||||
for(int j = 0; j < size2; j += inc) {
|
{
|
||||||
if(IS_BIT_SET(bits, j))
|
CLEAR_BIT(bits, j);
|
||||||
res++;
|
if(size == BITS_16)
|
||||||
}
|
CLEAR_BIT(bits, j+1);
|
||||||
}
|
if(size == BITS_32)
|
||||||
return res;
|
{
|
||||||
}
|
CLEAR_BIT(bits, j+2);
|
||||||
|
CLEAR_BIT(bits, j+3);
|
||||||
void cheatSearchUpdateValues(const CheatSearchData *cs)
|
}
|
||||||
{
|
}
|
||||||
for(int i = 0; i < cs->count; i++) {
|
}
|
||||||
CheatSearchBlock *block = &cs->blocks[i];
|
}
|
||||||
|
}
|
||||||
memcpy(block->saved, block->data, block->size);
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
int cheatSearchGetCount(const CheatSearchData *cs, int size)
|
||||||
|
{
|
||||||
|
int res = 0;
|
||||||
|
int inc = 1;
|
||||||
|
if(size == BITS_16)
|
||||||
|
inc = 2;
|
||||||
|
else if(size == BITS_32)
|
||||||
|
inc = 4;
|
||||||
|
|
||||||
|
for(int i = 0; i < cs->count; i++)
|
||||||
|
{
|
||||||
|
CheatSearchBlock *block = &cs->blocks[i];
|
||||||
|
|
||||||
|
int size2 = block->size;
|
||||||
|
u8 *bits = block->bits;
|
||||||
|
for(int j = 0; j < size2; j += inc)
|
||||||
|
{
|
||||||
|
if(IS_BIT_SET(bits, j))
|
||||||
|
res++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
void cheatSearchUpdateValues(const CheatSearchData *cs)
|
||||||
|
{
|
||||||
|
for(int i = 0; i < cs->count; i++)
|
||||||
|
{
|
||||||
|
CheatSearchBlock *block = &cs->blocks[i];
|
||||||
|
|
||||||
|
memcpy(block->saved, block->data, block->size);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -1,73 +1,75 @@
|
|||||||
// -*- C++ -*-
|
// -*- C++ -*-
|
||||||
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
|
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
|
||||||
// Copyright (C) 1999-2003 Forgotten
|
// Copyright (C) 1999-2003 Forgotten
|
||||||
// Copyright (C) 2004 Forgotten and the VBA development team
|
// Copyright (C) 2004 Forgotten and the VBA development team
|
||||||
|
|
||||||
// This program is free software; you can redistribute it and/or modify
|
// This program is free software; you can redistribute it and/or modify
|
||||||
// it under the terms of the GNU General Public License as published by
|
// it under the terms of the GNU General Public License as published by
|
||||||
// the Free Software Foundation; either version 2, or(at your option)
|
// the Free Software Foundation; either version 2, or(at your option)
|
||||||
// any later version.
|
// any later version.
|
||||||
//
|
//
|
||||||
// This program is distributed in the hope that it will be useful,
|
// This program is distributed in the hope that it will be useful,
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
// GNU General Public License for more details.
|
// GNU General Public License for more details.
|
||||||
//
|
//
|
||||||
// You should have received a copy of the GNU General Public License
|
// You should have received a copy of the GNU General Public License
|
||||||
// along with this program; if not, write to the Free Software Foundation,
|
// along with this program; if not, write to the Free Software Foundation,
|
||||||
// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
#ifndef VBA_CHEATSEARCH_H
|
#ifndef VBA_CHEATSEARCH_H
|
||||||
#define VBA_CHEATSEARCH_H
|
#define VBA_CHEATSEARCH_H
|
||||||
|
|
||||||
#include "System.h"
|
#include "System.h"
|
||||||
|
|
||||||
struct CheatSearchBlock {
|
struct CheatSearchBlock
|
||||||
int size;
|
{
|
||||||
u32 offset;
|
int size;
|
||||||
u8 *bits;
|
u32 offset;
|
||||||
u8 *data;
|
u8 *bits;
|
||||||
u8 *saved;
|
u8 *data;
|
||||||
};
|
u8 *saved;
|
||||||
|
};
|
||||||
struct CheatSearchData {
|
|
||||||
int count;
|
struct CheatSearchData
|
||||||
CheatSearchBlock *blocks;
|
{
|
||||||
};
|
int count;
|
||||||
|
CheatSearchBlock *blocks;
|
||||||
enum {
|
};
|
||||||
SEARCH_EQ,
|
|
||||||
SEARCH_NE,
|
enum {
|
||||||
SEARCH_LT,
|
SEARCH_EQ,
|
||||||
SEARCH_LE,
|
SEARCH_NE,
|
||||||
SEARCH_GT,
|
SEARCH_LT,
|
||||||
SEARCH_GE
|
SEARCH_LE,
|
||||||
};
|
SEARCH_GT,
|
||||||
|
SEARCH_GE
|
||||||
enum {
|
};
|
||||||
BITS_8,
|
|
||||||
BITS_16,
|
enum {
|
||||||
BITS_32
|
BITS_8,
|
||||||
};
|
BITS_16,
|
||||||
|
BITS_32
|
||||||
#define SET_BIT(bits,off) \
|
};
|
||||||
(bits)[(off) >> 3] |= (1 << ((off) & 7))
|
|
||||||
|
#define SET_BIT(bits,off) \
|
||||||
#define CLEAR_BIT(bits, off) \
|
(bits)[(off) >> 3] |= (1 << ((off) & 7))
|
||||||
(bits)[(off) >> 3] &= ~(1 << ((off) & 7))
|
|
||||||
|
#define CLEAR_BIT(bits, off) \
|
||||||
#define IS_BIT_SET(bits, off) \
|
(bits)[(off) >> 3] &= ~(1 << ((off) & 7))
|
||||||
(bits)[(off) >> 3] & (1 << ((off) & 7))
|
|
||||||
|
#define IS_BIT_SET(bits, off) \
|
||||||
extern CheatSearchData cheatSearchData;
|
(bits)[(off) >> 3] & (1 << ((off) & 7))
|
||||||
extern void cheatSearchCleanup(CheatSearchData *cs);
|
|
||||||
extern void cheatSearchStart(const CheatSearchData *cs);
|
extern CheatSearchData cheatSearchData;
|
||||||
extern void cheatSearch(const CheatSearchData *cs, int compare, int size,
|
extern void cheatSearchCleanup(CheatSearchData *cs);
|
||||||
bool isSigned);
|
extern void cheatSearchStart(const CheatSearchData *cs);
|
||||||
extern void cheatSearchValue(const CheatSearchData *cs, int compare, int size,
|
extern void cheatSearch(const CheatSearchData *cs, int compare, int size,
|
||||||
bool isSigned, u32 value);
|
bool isSigned);
|
||||||
extern int cheatSearchGetCount(const CheatSearchData *cs, int size);
|
extern void cheatSearchValue(const CheatSearchData *cs, int compare, int size,
|
||||||
extern void cheatSearchUpdateValues(const CheatSearchData *cs);
|
bool isSigned, u32 value);
|
||||||
extern s32 cheatSearchSignedRead(u8 *data, int off, int size);
|
extern int cheatSearchGetCount(const CheatSearchData *cs, int size);
|
||||||
extern u32 cheatSearchRead(u8 *data, int off, int size);
|
extern void cheatSearchUpdateValues(const CheatSearchData *cs);
|
||||||
#endif
|
extern s32 cheatSearchSignedRead(u8 *data, int off, int size);
|
||||||
|
extern u32 cheatSearchRead(u8 *data, int off, int size);
|
||||||
|
#endif
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -1,55 +1,55 @@
|
|||||||
// -*- C++ -*-
|
// -*- C++ -*-
|
||||||
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
|
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
|
||||||
// Copyright (C) 1999-2003 Forgotten
|
// Copyright (C) 1999-2003 Forgotten
|
||||||
// Copyright (C) 2004-2006 Forgotten and the VBA development team
|
// Copyright (C) 2004 Forgotten and the VBA development team
|
||||||
|
|
||||||
// This program is free software; you can redistribute it and/or modify
|
// This program is free software; you can redistribute it and/or modify
|
||||||
// it under the terms of the GNU General Public License as published by
|
// it under the terms of the GNU General Public License as published by
|
||||||
// the Free Software Foundation; either version 2, or(at your option)
|
// the Free Software Foundation; either version 2, or(at your option)
|
||||||
// any later version.
|
// any later version.
|
||||||
//
|
//
|
||||||
// This program is distributed in the hope that it will be useful,
|
// This program is distributed in the hope that it will be useful,
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
// GNU General Public License for more details.
|
// GNU General Public License for more details.
|
||||||
//
|
//
|
||||||
// You should have received a copy of the GNU General Public License
|
// You should have received a copy of the GNU General Public License
|
||||||
// along with this program; if not, write to the Free Software Foundation,
|
// along with this program; if not, write to the Free Software Foundation,
|
||||||
// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
#ifndef GBA_CHEATS_H
|
#ifndef GBA_CHEATS_H
|
||||||
#define GBA_CHEATS_H
|
#define GBA_CHEATS_H
|
||||||
|
|
||||||
struct CheatsData {
|
struct CheatsData
|
||||||
int code;
|
{
|
||||||
int size;
|
int code;
|
||||||
int status;
|
int size;
|
||||||
bool enabled;
|
int status;
|
||||||
u32 rawaddress;
|
bool enabled;
|
||||||
u32 address;
|
u32 address;
|
||||||
u32 value;
|
u32 value;
|
||||||
u32 oldValue;
|
u32 oldValue;
|
||||||
char codestring[20];
|
char codestring[20];
|
||||||
char desc[32];
|
char desc[32];
|
||||||
};
|
};
|
||||||
|
|
||||||
extern void cheatsAdd(const char *,const char *,u32, u32,u32,int,int);
|
extern void cheatsAdd(const char *,const char *,u32,u32,int,int);
|
||||||
extern void cheatsAddCheatCode(const char *code, const char *desc);
|
extern void cheatsAddCheatCode(const char *code, const char *desc);
|
||||||
extern void cheatsAddGSACode(const char *code, const char *desc, bool v3);
|
extern void cheatsAddGSACode(const char *code, const char *desc, bool v3);
|
||||||
extern void cheatsAddCBACode(const char *code, const char *desc);
|
extern void cheatsAddCBACode(const char *code, const char *desc);
|
||||||
extern bool cheatsImportGSACodeFile(const char *name, int game, bool v3);
|
extern bool cheatsImportGSACodeFile(const char *name, int game, bool v3);
|
||||||
extern void cheatsDelete(int number, bool restore);
|
extern void cheatsDelete(int number, bool restore);
|
||||||
extern void cheatsDeleteAll(bool restore);
|
extern void cheatsDeleteAll(bool restore);
|
||||||
extern void cheatsEnable(int number);
|
extern void cheatsEnable(int number);
|
||||||
extern void cheatsDisable(int number);
|
extern void cheatsDisable(int number);
|
||||||
extern void cheatsSaveGame(gzFile file);
|
extern void cheatsSaveGame(gzFile file);
|
||||||
extern void cheatsReadGame(gzFile file, int version);
|
extern void cheatsReadGame(gzFile file);
|
||||||
extern void cheatsSaveCheatList(const char *file);
|
extern void cheatsSaveCheatList(const char *file);
|
||||||
extern bool cheatsLoadCheatList(const char *file);
|
extern bool cheatsLoadCheatList(const char *file);
|
||||||
extern void cheatsWriteMemory(u32, u32);
|
extern void cheatsWriteMemory(u32 *, u32, u32);
|
||||||
extern void cheatsWriteHalfWord(u32, u16);
|
extern void cheatsWriteHalfWord(u16 *, u16, u16);
|
||||||
extern void cheatsWriteByte(u32, u8);
|
extern void cheatsWriteByte(u8 *, u8);
|
||||||
extern int cheatsCheckKeys(u32,u32);
|
extern int cheatsCheckKeys(u32,u32);
|
||||||
extern int cheatsNumber;
|
extern int cheatsNumber;
|
||||||
extern CheatsData cheatsList[100];
|
extern CheatsData cheatsList[100];
|
||||||
#endif // GBA_CHEATS_H
|
#endif // GBA_CHEATS_H
|
||||||
|
@ -1,206 +1,214 @@
|
|||||||
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
|
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
|
||||||
// Copyright (C) 1999-2003 Forgotten
|
// Copyright (C) 1999-2003 Forgotten
|
||||||
// Copyright (C) 2005 Forgotten and the VBA development team
|
// Copyright (C) 2004 Forgotten and the VBA development team
|
||||||
|
|
||||||
// This program is free software; you can redistribute it and/or modify
|
// This program is free software; you can redistribute it and/or modify
|
||||||
// it under the terms of the GNU General Public License as published by
|
// it under the terms of the GNU General Public License as published by
|
||||||
// the Free Software Foundation; either version 2, or(at your option)
|
// the Free Software Foundation; either version 2, or(at your option)
|
||||||
// any later version.
|
// any later version.
|
||||||
//
|
//
|
||||||
// This program is distributed in the hope that it will be useful,
|
// This program is distributed in the hope that it will be useful,
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
// GNU General Public License for more details.
|
// GNU General Public License for more details.
|
||||||
//
|
//
|
||||||
// You should have received a copy of the GNU General Public License
|
// You should have received a copy of the GNU General Public License
|
||||||
// along with this program; if not, write to the Free Software Foundation,
|
// along with this program; if not, write to the Free Software Foundation,
|
||||||
// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
#include <string.h>
|
#include "GBA.h"
|
||||||
#include "agb/GBA.h"
|
#include "EEprom.h"
|
||||||
#include "EEprom.h"
|
#include "Util.h"
|
||||||
#include "Util.h"
|
|
||||||
|
extern int cpuDmaCount;
|
||||||
extern int cpuDmaCount;
|
|
||||||
|
int eepromMode = EEPROM_IDLE;
|
||||||
int eepromMode = EEPROM_IDLE;
|
int eepromByte = 0;
|
||||||
int eepromByte = 0;
|
int eepromBits = 0;
|
||||||
int eepromBits = 0;
|
int eepromAddress = 0;
|
||||||
int eepromAddress = 0;
|
u8 eepromData[0x2000];
|
||||||
u8 eepromData[0x2000];
|
u8 eepromBuffer[16];
|
||||||
u8 eepromBuffer[16];
|
bool eepromInUse = false;
|
||||||
bool eepromInUse = false;
|
int eepromSize = 512;
|
||||||
int eepromSize = 512;
|
|
||||||
|
variable_desc eepromSaveData[] = {
|
||||||
variable_desc eepromSaveData[] = {
|
{ &eepromMode, sizeof(int) },
|
||||||
{ &eepromMode, sizeof(int) },
|
{ &eepromByte, sizeof(int) },
|
||||||
{ &eepromByte, sizeof(int) },
|
{ &eepromBits , sizeof(int) },
|
||||||
{ &eepromBits , sizeof(int) },
|
{ &eepromAddress , sizeof(int) },
|
||||||
{ &eepromAddress , sizeof(int) },
|
{ &eepromInUse, sizeof(bool) },
|
||||||
{ &eepromInUse, sizeof(bool) },
|
{ &eepromData[0], 512 },
|
||||||
{ &eepromData[0], 512 },
|
{ &eepromBuffer[0], 16 },
|
||||||
{ &eepromBuffer[0], 16 },
|
{ NULL, 0 }
|
||||||
{ NULL, 0 }
|
};
|
||||||
};
|
|
||||||
|
void eepromReset()
|
||||||
void eepromInit()
|
{
|
||||||
{
|
eepromMode = EEPROM_IDLE;
|
||||||
memset(eepromData, 255, sizeof(eepromData));
|
eepromByte = 0;
|
||||||
}
|
eepromBits = 0;
|
||||||
|
eepromAddress = 0;
|
||||||
void eepromReset()
|
eepromInUse = false;
|
||||||
{
|
eepromSize = 512;
|
||||||
eepromMode = EEPROM_IDLE;
|
}
|
||||||
eepromByte = 0;
|
|
||||||
eepromBits = 0;
|
void eepromSaveGame(gzFile gzFile)
|
||||||
eepromAddress = 0;
|
{
|
||||||
eepromInUse = false;
|
utilWriteData(gzFile, eepromSaveData);
|
||||||
eepromSize = 512;
|
utilWriteInt(gzFile, eepromSize);
|
||||||
}
|
utilGzWrite(gzFile, eepromData, 0x2000);
|
||||||
|
}
|
||||||
void eepromSaveGame(gzFile gzFile)
|
|
||||||
{
|
void eepromReadGame(gzFile gzFile, int version)
|
||||||
utilWriteData(gzFile, eepromSaveData);
|
{
|
||||||
utilWriteInt(gzFile, eepromSize);
|
utilReadData(gzFile, eepromSaveData);
|
||||||
utilGzWrite(gzFile, eepromData, 0x2000);
|
if(version >= SAVE_GAME_VERSION_3)
|
||||||
}
|
{
|
||||||
|
eepromSize = utilReadInt(gzFile);
|
||||||
void eepromReadGame(gzFile gzFile, int version)
|
utilGzRead(gzFile, eepromData, 0x2000);
|
||||||
{
|
}
|
||||||
utilReadData(gzFile, eepromSaveData);
|
else
|
||||||
if(version >= SAVE_GAME_VERSION_3) {
|
{
|
||||||
eepromSize = utilReadInt(gzFile);
|
// prior to 0.7.1, only 4K EEPROM was supported
|
||||||
utilGzRead(gzFile, eepromData, 0x2000);
|
eepromSize = 512;
|
||||||
} else {
|
}
|
||||||
// prior to 0.7.1, only 4K EEPROM was supported
|
}
|
||||||
eepromSize = 512;
|
|
||||||
}
|
|
||||||
}
|
int eepromRead(u32 /* address */)
|
||||||
|
{
|
||||||
void eepromReadGameSkip(gzFile gzFile, int version)
|
switch(eepromMode)
|
||||||
{
|
{
|
||||||
// skip the eeprom data in a save game
|
case EEPROM_IDLE:
|
||||||
utilReadDataSkip(gzFile, eepromSaveData);
|
case EEPROM_READADDRESS:
|
||||||
if(version >= SAVE_GAME_VERSION_3) {
|
case EEPROM_WRITEDATA:
|
||||||
utilGzSeek(gzFile, sizeof(int), SEEK_CUR);
|
return 1;
|
||||||
utilGzSeek(gzFile, 0x2000, SEEK_CUR);
|
case EEPROM_READDATA:
|
||||||
}
|
{
|
||||||
}
|
eepromBits++;
|
||||||
|
if(eepromBits == 4)
|
||||||
int eepromRead(u32 /* address */)
|
{
|
||||||
{
|
eepromMode = EEPROM_READDATA2;
|
||||||
switch(eepromMode) {
|
eepromBits = 0;
|
||||||
case EEPROM_IDLE:
|
eepromByte = 0;
|
||||||
case EEPROM_READADDRESS:
|
}
|
||||||
case EEPROM_WRITEDATA:
|
return 0;
|
||||||
return 1;
|
}
|
||||||
case EEPROM_READDATA:
|
case EEPROM_READDATA2:
|
||||||
{
|
{
|
||||||
eepromBits++;
|
int data = 0;
|
||||||
if(eepromBits == 4) {
|
int address = eepromAddress << 3;
|
||||||
eepromMode = EEPROM_READDATA2;
|
int mask = 1 << (7 - (eepromBits & 7));
|
||||||
eepromBits = 0;
|
data = (eepromData[address+eepromByte] & mask) ? 1 : 0;
|
||||||
eepromByte = 0;
|
eepromBits++;
|
||||||
}
|
if((eepromBits & 7) == 0)
|
||||||
return 0;
|
eepromByte++;
|
||||||
}
|
if(eepromBits == 0x40)
|
||||||
case EEPROM_READDATA2:
|
eepromMode = EEPROM_IDLE;
|
||||||
{
|
return data;
|
||||||
int data = 0;
|
}
|
||||||
int address = eepromAddress << 3;
|
default:
|
||||||
int mask = 1 << (7 - (eepromBits & 7));
|
return 0;
|
||||||
data = (eepromData[address+eepromByte] & mask) ? 1 : 0;
|
}
|
||||||
eepromBits++;
|
return 1;
|
||||||
if((eepromBits & 7) == 0)
|
}
|
||||||
eepromByte++;
|
|
||||||
if(eepromBits == 0x40)
|
void eepromWrite(u32 /* address */, u8 value)
|
||||||
eepromMode = EEPROM_IDLE;
|
{
|
||||||
return data;
|
if(cpuDmaCount == 0)
|
||||||
}
|
return;
|
||||||
default:
|
int bit = value & 1;
|
||||||
return 0;
|
switch(eepromMode)
|
||||||
}
|
{
|
||||||
return 1;
|
case EEPROM_IDLE:
|
||||||
}
|
eepromByte = 0;
|
||||||
|
eepromBits = 1;
|
||||||
void eepromWrite(u32 /* address */, u8 value)
|
eepromBuffer[eepromByte] = bit;
|
||||||
{
|
eepromMode = EEPROM_READADDRESS;
|
||||||
if(cpuDmaCount == 0)
|
break;
|
||||||
return;
|
case EEPROM_READADDRESS:
|
||||||
int bit = value & 1;
|
eepromBuffer[eepromByte] <<= 1;
|
||||||
switch(eepromMode) {
|
eepromBuffer[eepromByte] |= bit;
|
||||||
case EEPROM_IDLE:
|
eepromBits++;
|
||||||
eepromByte = 0;
|
if((eepromBits & 7) == 0)
|
||||||
eepromBits = 1;
|
{
|
||||||
eepromBuffer[eepromByte] = bit;
|
eepromByte++;
|
||||||
eepromMode = EEPROM_READADDRESS;
|
}
|
||||||
break;
|
if(cpuDmaCount == 0x11 || cpuDmaCount == 0x51)
|
||||||
case EEPROM_READADDRESS:
|
{
|
||||||
eepromBuffer[eepromByte] <<= 1;
|
if(eepromBits == 0x11)
|
||||||
eepromBuffer[eepromByte] |= bit;
|
{
|
||||||
eepromBits++;
|
eepromInUse = true;
|
||||||
if((eepromBits & 7) == 0) {
|
eepromSize = 0x2000;
|
||||||
eepromByte++;
|
eepromAddress = ((eepromBuffer[0] & 0x3F) << 8) |
|
||||||
}
|
((eepromBuffer[1] & 0xFF));
|
||||||
if(cpuDmaCount == 0x11 || cpuDmaCount == 0x51) {
|
if(!(eepromBuffer[0] & 0x40))
|
||||||
if(eepromBits == 0x11) {
|
{
|
||||||
eepromInUse = true;
|
eepromBuffer[0] = bit;
|
||||||
eepromSize = 0x2000;
|
eepromBits = 1;
|
||||||
eepromAddress = ((eepromBuffer[0] & 0x3F) << 8) |
|
eepromByte = 0;
|
||||||
((eepromBuffer[1] & 0xFF));
|
eepromMode = EEPROM_WRITEDATA;
|
||||||
if(!(eepromBuffer[0] & 0x40)) {
|
}
|
||||||
eepromBuffer[0] = bit;
|
else
|
||||||
eepromBits = 1;
|
{
|
||||||
eepromByte = 0;
|
eepromMode = EEPROM_READDATA;
|
||||||
eepromMode = EEPROM_WRITEDATA;
|
eepromByte = 0;
|
||||||
} else {
|
eepromBits = 0;
|
||||||
eepromMode = EEPROM_READDATA;
|
}
|
||||||
eepromByte = 0;
|
}
|
||||||
eepromBits = 0;
|
}
|
||||||
}
|
else
|
||||||
}
|
{
|
||||||
} else {
|
if(eepromBits == 9)
|
||||||
if(eepromBits == 9) {
|
{
|
||||||
eepromInUse = true;
|
eepromInUse = true;
|
||||||
eepromAddress = (eepromBuffer[0] & 0x3F);
|
eepromAddress = (eepromBuffer[0] & 0x3F);
|
||||||
if(!(eepromBuffer[0] & 0x40)) {
|
if(!(eepromBuffer[0] & 0x40))
|
||||||
eepromBuffer[0] = bit;
|
{
|
||||||
eepromBits = 1;
|
eepromBuffer[0] = bit;
|
||||||
eepromByte = 0;
|
eepromBits = 1;
|
||||||
eepromMode = EEPROM_WRITEDATA;
|
eepromByte = 0;
|
||||||
} else {
|
eepromMode = EEPROM_WRITEDATA;
|
||||||
eepromMode = EEPROM_READDATA;
|
}
|
||||||
eepromByte = 0;
|
else
|
||||||
eepromBits = 0;
|
{
|
||||||
}
|
eepromMode = EEPROM_READDATA;
|
||||||
}
|
eepromByte = 0;
|
||||||
}
|
eepromBits = 0;
|
||||||
break;
|
}
|
||||||
case EEPROM_READDATA:
|
}
|
||||||
case EEPROM_READDATA2:
|
}
|
||||||
// should we reset here?
|
break;
|
||||||
eepromMode = EEPROM_IDLE;
|
case EEPROM_READDATA:
|
||||||
break;
|
case EEPROM_READDATA2:
|
||||||
case EEPROM_WRITEDATA:
|
// should we reset here?
|
||||||
eepromBuffer[eepromByte] <<= 1;
|
eepromMode = EEPROM_IDLE;
|
||||||
eepromBuffer[eepromByte] |= bit;
|
break;
|
||||||
eepromBits++;
|
case EEPROM_WRITEDATA:
|
||||||
if((eepromBits & 7) == 0) {
|
eepromBuffer[eepromByte] <<= 1;
|
||||||
eepromByte++;
|
eepromBuffer[eepromByte] |= bit;
|
||||||
}
|
eepromBits++;
|
||||||
if(eepromBits == 0x40) {
|
if((eepromBits & 7) == 0)
|
||||||
eepromInUse = true;
|
{
|
||||||
// write data;
|
eepromByte++;
|
||||||
for(int i = 0; i < 8; i++) {
|
}
|
||||||
eepromData[(eepromAddress << 3) + i] = eepromBuffer[i];
|
if(eepromBits == 0x40)
|
||||||
}
|
{
|
||||||
systemSaveUpdateCounter = SYSTEM_SAVE_UPDATED;
|
eepromInUse = true;
|
||||||
} else if(eepromBits == 0x41) {
|
// write data;
|
||||||
eepromMode = EEPROM_IDLE;
|
for(int i = 0; i < 8; i++)
|
||||||
eepromByte = 0;
|
{
|
||||||
eepromBits = 0;
|
eepromData[(eepromAddress << 3) + i] = eepromBuffer[i];
|
||||||
}
|
}
|
||||||
break;
|
systemSaveUpdateCounter = SYSTEM_SAVE_UPDATED;
|
||||||
}
|
}
|
||||||
}
|
else if(eepromBits == 0x41)
|
||||||
|
{
|
||||||
|
eepromMode = EEPROM_IDLE;
|
||||||
|
eepromByte = 0;
|
||||||
|
eepromBits = 0;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -1,40 +1,38 @@
|
|||||||
// -*- C++ -*-
|
// -*- C++ -*-
|
||||||
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
|
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
|
||||||
// Copyright (C) 1999-2003 Forgotten
|
// Copyright (C) 1999-2003 Forgotten
|
||||||
// Copyright (C) 2005 Forgotten and the VBA development team
|
// Copyright (C) 2004 Forgotten and the VBA development team
|
||||||
|
|
||||||
// This program is free software; you can redistribute it and/or modify
|
// This program is free software; you can redistribute it and/or modify
|
||||||
// it under the terms of the GNU General Public License as published by
|
// it under the terms of the GNU General Public License as published by
|
||||||
// the Free Software Foundation; either version 2, or(at your option)
|
// the Free Software Foundation; either version 2, or(at your option)
|
||||||
// any later version.
|
// any later version.
|
||||||
//
|
//
|
||||||
// This program is distributed in the hope that it will be useful,
|
// This program is distributed in the hope that it will be useful,
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
// GNU General Public License for more details.
|
// GNU General Public License for more details.
|
||||||
//
|
//
|
||||||
// You should have received a copy of the GNU General Public License
|
// You should have received a copy of the GNU General Public License
|
||||||
// along with this program; if not, write to the Free Software Foundation,
|
// along with this program; if not, write to the Free Software Foundation,
|
||||||
// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
#ifndef VBA_EEPROM_H
|
#ifndef VBA_EEPROM_H
|
||||||
#define VBA_EEPROM_H
|
#define VBA_EEPROM_H
|
||||||
|
|
||||||
extern void eepromSaveGame(gzFile _gzFile);
|
extern void eepromSaveGame(gzFile gzFile);
|
||||||
extern void eepromReadGame(gzFile _gzFile, int version);
|
extern void eepromReadGame(gzFile gzFile, int version);
|
||||||
extern void eepromReadGameSkip(gzFile _gzFile, int version);
|
extern int eepromRead(u32 address);
|
||||||
extern int eepromRead(u32 address);
|
extern void eepromWrite(u32 address, u8 value);
|
||||||
extern void eepromWrite(u32 address, u8 value);
|
extern void eepromReset();
|
||||||
extern void eepromInit();
|
extern u8 eepromData[0x2000];
|
||||||
extern void eepromReset();
|
extern bool eepromInUse;
|
||||||
extern u8 eepromData[0x2000];
|
extern int eepromSize;
|
||||||
extern bool eepromInUse;
|
|
||||||
extern int eepromSize;
|
#define EEPROM_IDLE 0
|
||||||
|
#define EEPROM_READADDRESS 1
|
||||||
#define EEPROM_IDLE 0
|
#define EEPROM_READDATA 2
|
||||||
#define EEPROM_READADDRESS 1
|
#define EEPROM_READDATA2 3
|
||||||
#define EEPROM_READDATA 2
|
#define EEPROM_WRITEDATA 4
|
||||||
#define EEPROM_READDATA2 3
|
|
||||||
#define EEPROM_WRITEDATA 4
|
#endif // VBA_EEPROM_H
|
||||||
|
|
||||||
#endif // VBA_EEPROM_H
|
|
||||||
|
@ -1,275 +1,288 @@
|
|||||||
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
|
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
|
||||||
// Copyright (C) 1999-2003 Forgotten
|
// Copyright (C) 1999-2003 Forgotten
|
||||||
// Copyright (C) 2004-2006 Forgotten and the VBA development team
|
// Copyright (C) 2004 Forgotten and the VBA development team
|
||||||
|
|
||||||
// This program is free software; you can redistribute it and/or modify
|
// This program is free software; you can redistribute it and/or modify
|
||||||
// it under the terms of the GNU General Public License as published by
|
// it under the terms of the GNU General Public License as published by
|
||||||
// the Free Software Foundation; either version 2, or(at your option)
|
// the Free Software Foundation; either version 2, or(at your option)
|
||||||
// any later version.
|
// any later version.
|
||||||
//
|
//
|
||||||
// This program is distributed in the hope that it will be useful,
|
// This program is distributed in the hope that it will be useful,
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
// GNU General Public License for more details.
|
// GNU General Public License for more details.
|
||||||
//
|
//
|
||||||
// You should have received a copy of the GNU General Public License
|
// You should have received a copy of the GNU General Public License
|
||||||
// along with this program; if not, write to the Free Software Foundation,
|
// along with this program; if not, write to the Free Software Foundation,
|
||||||
// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include "agb/GBA.h"
|
#include "GBA.h"
|
||||||
#include "Globals.h"
|
#include "Globals.h"
|
||||||
#include "Flash.h"
|
#include "Flash.h"
|
||||||
#include "Sram.h"
|
#include "Sram.h"
|
||||||
#include "Util.h"
|
#include "Util.h"
|
||||||
|
|
||||||
#define FLASH_READ_ARRAY 0
|
#define FLASH_READ_ARRAY 0
|
||||||
#define FLASH_CMD_1 1
|
#define FLASH_CMD_1 1
|
||||||
#define FLASH_CMD_2 2
|
#define FLASH_CMD_2 2
|
||||||
#define FLASH_AUTOSELECT 3
|
#define FLASH_AUTOSELECT 3
|
||||||
#define FLASH_CMD_3 4
|
#define FLASH_CMD_3 4
|
||||||
#define FLASH_CMD_4 5
|
#define FLASH_CMD_4 5
|
||||||
#define FLASH_CMD_5 6
|
#define FLASH_CMD_5 6
|
||||||
#define FLASH_ERASE_COMPLETE 7
|
#define FLASH_ERASE_COMPLETE 7
|
||||||
#define FLASH_PROGRAM 8
|
#define FLASH_PROGRAM 8
|
||||||
#define FLASH_SETBANK 9
|
#define FLASH_SETBANK 9
|
||||||
|
|
||||||
u8 flashSaveMemory[0x20000];
|
u8 flashSaveMemory[0x20000];
|
||||||
int flashState = FLASH_READ_ARRAY;
|
int flashState = FLASH_READ_ARRAY;
|
||||||
int flashReadState = FLASH_READ_ARRAY;
|
int flashReadState = FLASH_READ_ARRAY;
|
||||||
int flashSize = 0x10000;
|
int flashSize = 0x10000;
|
||||||
int flashDeviceID = 0x1b;
|
int flashDeviceID = 0x1b;
|
||||||
int flashManufacturerID = 0x32;
|
int flashManufacturerID = 0x32;
|
||||||
int flashBank = 0;
|
int flashBank = 0;
|
||||||
|
|
||||||
static variable_desc flashSaveData[] = {
|
static variable_desc flashSaveData[] = {
|
||||||
{ &flashState, sizeof(int) },
|
{ &flashState, sizeof(int) },
|
||||||
{ &flashReadState, sizeof(int) },
|
{ &flashReadState, sizeof(int) },
|
||||||
{ &flashSaveMemory[0], 0x10000 },
|
{ &flashSaveMemory[0], 0x10000 },
|
||||||
{ NULL, 0 }
|
{ NULL, 0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
static variable_desc flashSaveData2[] = {
|
static variable_desc flashSaveData2[] = {
|
||||||
{ &flashState, sizeof(int) },
|
{ &flashState, sizeof(int) },
|
||||||
{ &flashReadState, sizeof(int) },
|
{ &flashReadState, sizeof(int) },
|
||||||
{ &flashSize, sizeof(int) },
|
{ &flashSize, sizeof(int) },
|
||||||
{ &flashSaveMemory[0], 0x20000 },
|
{ &flashSaveMemory[0], 0x20000 },
|
||||||
{ NULL, 0 }
|
{ NULL, 0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
static variable_desc flashSaveData3[] = {
|
static variable_desc flashSaveData3[] = {
|
||||||
{ &flashState, sizeof(int) },
|
{ &flashState, sizeof(int) },
|
||||||
{ &flashReadState, sizeof(int) },
|
{ &flashReadState, sizeof(int) },
|
||||||
{ &flashSize, sizeof(int) },
|
{ &flashSize, sizeof(int) },
|
||||||
{ &flashBank, sizeof(int) },
|
{ &flashBank, sizeof(int) },
|
||||||
{ &flashSaveMemory[0], 0x20000 },
|
{ &flashSaveMemory[0], 0x20000 },
|
||||||
{ NULL, 0 }
|
{ NULL, 0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
void flashInit()
|
void flashReset()
|
||||||
{
|
{
|
||||||
memset(flashSaveMemory, 0xff, sizeof(flashSaveMemory));
|
flashState = FLASH_READ_ARRAY;
|
||||||
}
|
flashReadState = FLASH_READ_ARRAY;
|
||||||
|
flashBank = 0;
|
||||||
void flashReset()
|
}
|
||||||
{
|
|
||||||
flashState = FLASH_READ_ARRAY;
|
void flashSaveGame(gzFile gzFile)
|
||||||
flashReadState = FLASH_READ_ARRAY;
|
{
|
||||||
flashBank = 0;
|
utilWriteData(gzFile, flashSaveData3);
|
||||||
}
|
}
|
||||||
|
|
||||||
void flashSaveGame(gzFile gzFile)
|
void flashReadGame(gzFile gzFile, int version)
|
||||||
{
|
{
|
||||||
utilWriteData(gzFile, flashSaveData3);
|
if(version < SAVE_GAME_VERSION_5)
|
||||||
}
|
utilReadData(gzFile, flashSaveData);
|
||||||
|
else if(version < SAVE_GAME_VERSION_7)
|
||||||
void flashReadGame(gzFile gzFile, int version)
|
{
|
||||||
{
|
utilReadData(gzFile, flashSaveData2);
|
||||||
if(version < SAVE_GAME_VERSION_5)
|
flashBank = 0;
|
||||||
utilReadData(gzFile, flashSaveData);
|
flashSetSize(flashSize);
|
||||||
else if(version < SAVE_GAME_VERSION_7) {
|
}
|
||||||
utilReadData(gzFile, flashSaveData2);
|
else
|
||||||
flashBank = 0;
|
{
|
||||||
flashSetSize(flashSize);
|
utilReadData(gzFile, flashSaveData3);
|
||||||
} else {
|
}
|
||||||
utilReadData(gzFile, flashSaveData3);
|
}
|
||||||
}
|
|
||||||
}
|
void flashSetSize(int size)
|
||||||
|
{
|
||||||
void flashReadGameSkip(gzFile gzFile, int version)
|
// log("Setting flash size to %d\n", size);
|
||||||
{
|
flashSize = size;
|
||||||
// skip the flash data in a save game
|
if(size == 0x10000)
|
||||||
if(version < SAVE_GAME_VERSION_5)
|
{
|
||||||
utilReadDataSkip(gzFile, flashSaveData);
|
flashDeviceID = 0x1b;
|
||||||
else if(version < SAVE_GAME_VERSION_7) {
|
flashManufacturerID = 0x32;
|
||||||
utilReadDataSkip(gzFile, flashSaveData2);
|
}
|
||||||
} else {
|
else
|
||||||
utilReadDataSkip(gzFile, flashSaveData3);
|
{
|
||||||
}
|
flashDeviceID = 0x13; //0x09;
|
||||||
}
|
flashManufacturerID = 0x62; //0xc2;
|
||||||
|
}
|
||||||
void flashSetSize(int size)
|
}
|
||||||
{
|
|
||||||
// log("Setting flash size to %d\n", size);
|
u8 flashRead(u32 address)
|
||||||
if(size == 0x10000) {
|
{
|
||||||
flashDeviceID = 0x1b;
|
// log("Reading %08x from %08x\n", address, reg[15].I);
|
||||||
flashManufacturerID = 0x32;
|
// log("Current read state is %d\n", flashReadState);
|
||||||
} else {
|
address &= 0xFFFF;
|
||||||
flashDeviceID = 0x13; //0x09;
|
|
||||||
flashManufacturerID = 0x62; //0xc2;
|
switch(flashReadState)
|
||||||
}
|
{
|
||||||
// Added to make 64k saves compatible with 128k ones
|
case FLASH_READ_ARRAY:
|
||||||
// (allow wrongfuly set 64k saves to work for Pokemon games)
|
return flashSaveMemory[(flashBank << 16) + address];
|
||||||
if ((size == 0x20000) && (flashSize == 0x10000))
|
case FLASH_AUTOSELECT:
|
||||||
memcpy((u8 *)(flashSaveMemory+0x10000), (u8 *)(flashSaveMemory), 0x10000);
|
switch(address & 0xFF)
|
||||||
flashSize = size;
|
{
|
||||||
}
|
case 0:
|
||||||
|
// manufacturer ID
|
||||||
u8 flashRead(u32 address)
|
return flashManufacturerID;
|
||||||
{
|
case 1:
|
||||||
// log("Reading %08x from %08x\n", address, reg[15].I);
|
// device ID
|
||||||
// log("Current read state is %d\n", flashReadState);
|
return flashDeviceID;
|
||||||
address &= 0xFFFF;
|
}
|
||||||
|
break;
|
||||||
switch(flashReadState) {
|
case FLASH_ERASE_COMPLETE:
|
||||||
case FLASH_READ_ARRAY:
|
flashState = FLASH_READ_ARRAY;
|
||||||
return flashSaveMemory[(flashBank << 16) + address];
|
flashReadState = FLASH_READ_ARRAY;
|
||||||
case FLASH_AUTOSELECT:
|
return 0xFF;
|
||||||
switch(address & 0xFF) {
|
};
|
||||||
case 0:
|
return 0;
|
||||||
// manufacturer ID
|
}
|
||||||
return flashManufacturerID;
|
|
||||||
case 1:
|
void flashSaveDecide(u32 address, u8 byte)
|
||||||
// device ID
|
{
|
||||||
return flashDeviceID;
|
// log("Deciding save type %08x\n", address);
|
||||||
}
|
if(address == 0x0e005555)
|
||||||
break;
|
{
|
||||||
case FLASH_ERASE_COMPLETE:
|
saveType = 2;
|
||||||
flashState = FLASH_READ_ARRAY;
|
cpuSaveGameFunc = flashWrite;
|
||||||
flashReadState = FLASH_READ_ARRAY;
|
}
|
||||||
return 0xFF;
|
else
|
||||||
};
|
{
|
||||||
return 0;
|
saveType = 1;
|
||||||
}
|
cpuSaveGameFunc = sramWrite;
|
||||||
|
}
|
||||||
void flashSaveDecide(u32 address, u8 byte)
|
|
||||||
{
|
(*cpuSaveGameFunc)(address, byte);
|
||||||
// log("Deciding save type %08x\n", address);
|
}
|
||||||
if(address == 0x0e005555) {
|
|
||||||
saveType = 2;
|
void flashWrite(u32 address, u8 byte)
|
||||||
cpuSaveGameFunc = flashWrite;
|
{
|
||||||
} else {
|
// log("Writing %02x at %08x\n", byte, address);
|
||||||
saveType = 1;
|
// log("Current state is %d\n", flashState);
|
||||||
cpuSaveGameFunc = sramWrite;
|
address &= 0xFFFF;
|
||||||
}
|
switch(flashState)
|
||||||
|
{
|
||||||
(*cpuSaveGameFunc)(address, byte);
|
case FLASH_READ_ARRAY:
|
||||||
}
|
if(address == 0x5555 && byte == 0xAA)
|
||||||
|
flashState = FLASH_CMD_1;
|
||||||
void flashDelayedWrite(u32 address, u8 byte)
|
break;
|
||||||
{
|
case FLASH_CMD_1:
|
||||||
saveType = 2;
|
if(address == 0x2AAA && byte == 0x55)
|
||||||
cpuSaveGameFunc = flashWrite;
|
flashState = FLASH_CMD_2;
|
||||||
flashWrite(address, byte);
|
else
|
||||||
}
|
flashState = FLASH_READ_ARRAY;
|
||||||
|
break;
|
||||||
void flashWrite(u32 address, u8 byte)
|
case FLASH_CMD_2:
|
||||||
{
|
if(address == 0x5555)
|
||||||
// log("Writing %02x at %08x\n", byte, address);
|
{
|
||||||
// log("Current state is %d\n", flashState);
|
if(byte == 0x90)
|
||||||
address &= 0xFFFF;
|
{
|
||||||
switch(flashState) {
|
flashState = FLASH_AUTOSELECT;
|
||||||
case FLASH_READ_ARRAY:
|
flashReadState = FLASH_AUTOSELECT;
|
||||||
if(address == 0x5555 && byte == 0xAA)
|
}
|
||||||
flashState = FLASH_CMD_1;
|
else if(byte == 0x80)
|
||||||
break;
|
{
|
||||||
case FLASH_CMD_1:
|
flashState = FLASH_CMD_3;
|
||||||
if(address == 0x2AAA && byte == 0x55)
|
}
|
||||||
flashState = FLASH_CMD_2;
|
else if(byte == 0xF0)
|
||||||
else
|
{
|
||||||
flashState = FLASH_READ_ARRAY;
|
flashState = FLASH_READ_ARRAY;
|
||||||
break;
|
flashReadState = FLASH_READ_ARRAY;
|
||||||
case FLASH_CMD_2:
|
}
|
||||||
if(address == 0x5555) {
|
else if(byte == 0xA0)
|
||||||
if(byte == 0x90) {
|
{
|
||||||
flashState = FLASH_AUTOSELECT;
|
flashState = FLASH_PROGRAM;
|
||||||
flashReadState = FLASH_AUTOSELECT;
|
}
|
||||||
} else if(byte == 0x80) {
|
else if(byte == 0xB0 && flashSize == 0x20000)
|
||||||
flashState = FLASH_CMD_3;
|
{
|
||||||
} else if(byte == 0xF0) {
|
flashState = FLASH_SETBANK;
|
||||||
flashState = FLASH_READ_ARRAY;
|
}
|
||||||
flashReadState = FLASH_READ_ARRAY;
|
else
|
||||||
} else if(byte == 0xA0) {
|
{
|
||||||
flashState = FLASH_PROGRAM;
|
flashState = FLASH_READ_ARRAY;
|
||||||
} else if(byte == 0xB0 && flashSize == 0x20000) {
|
flashReadState = FLASH_READ_ARRAY;
|
||||||
flashState = FLASH_SETBANK;
|
}
|
||||||
} else {
|
}
|
||||||
flashState = FLASH_READ_ARRAY;
|
else
|
||||||
flashReadState = FLASH_READ_ARRAY;
|
{
|
||||||
}
|
flashState = FLASH_READ_ARRAY;
|
||||||
} else {
|
flashReadState = FLASH_READ_ARRAY;
|
||||||
flashState = FLASH_READ_ARRAY;
|
}
|
||||||
flashReadState = FLASH_READ_ARRAY;
|
break;
|
||||||
}
|
case FLASH_CMD_3:
|
||||||
break;
|
if(address == 0x5555 && byte == 0xAA)
|
||||||
case FLASH_CMD_3:
|
{
|
||||||
if(address == 0x5555 && byte == 0xAA) {
|
flashState = FLASH_CMD_4;
|
||||||
flashState = FLASH_CMD_4;
|
}
|
||||||
} else {
|
else
|
||||||
flashState = FLASH_READ_ARRAY;
|
{
|
||||||
flashReadState = FLASH_READ_ARRAY;
|
flashState = FLASH_READ_ARRAY;
|
||||||
}
|
flashReadState = FLASH_READ_ARRAY;
|
||||||
break;
|
}
|
||||||
case FLASH_CMD_4:
|
break;
|
||||||
if(address == 0x2AAA && byte == 0x55) {
|
case FLASH_CMD_4:
|
||||||
flashState = FLASH_CMD_5;
|
if(address == 0x2AAA && byte == 0x55)
|
||||||
} else {
|
{
|
||||||
flashState = FLASH_READ_ARRAY;
|
flashState = FLASH_CMD_5;
|
||||||
flashReadState = FLASH_READ_ARRAY;
|
}
|
||||||
}
|
else
|
||||||
break;
|
{
|
||||||
case FLASH_CMD_5:
|
flashState = FLASH_READ_ARRAY;
|
||||||
if(byte == 0x30) {
|
flashReadState = FLASH_READ_ARRAY;
|
||||||
// SECTOR ERASE
|
}
|
||||||
memset(&flashSaveMemory[(flashBank << 16) + (address & 0xF000)],
|
break;
|
||||||
0,
|
case FLASH_CMD_5:
|
||||||
0x1000);
|
if(byte == 0x30)
|
||||||
systemSaveUpdateCounter = SYSTEM_SAVE_UPDATED;
|
{
|
||||||
flashReadState = FLASH_ERASE_COMPLETE;
|
// SECTOR ERASE
|
||||||
} else if(byte == 0x10) {
|
memset(&flashSaveMemory[(flashBank << 16) + (address & 0xF000)],
|
||||||
// CHIP ERASE
|
0,
|
||||||
memset(flashSaveMemory, 0, flashSize);
|
0x1000);
|
||||||
systemSaveUpdateCounter = SYSTEM_SAVE_UPDATED;
|
systemSaveUpdateCounter = SYSTEM_SAVE_UPDATED;
|
||||||
flashReadState = FLASH_ERASE_COMPLETE;
|
flashReadState = FLASH_ERASE_COMPLETE;
|
||||||
} else {
|
}
|
||||||
flashState = FLASH_READ_ARRAY;
|
else if(byte == 0x10)
|
||||||
flashReadState = FLASH_READ_ARRAY;
|
{
|
||||||
}
|
// CHIP ERASE
|
||||||
break;
|
memset(flashSaveMemory, 0, flashSize);
|
||||||
case FLASH_AUTOSELECT:
|
systemSaveUpdateCounter = SYSTEM_SAVE_UPDATED;
|
||||||
if(byte == 0xF0) {
|
flashReadState = FLASH_ERASE_COMPLETE;
|
||||||
flashState = FLASH_READ_ARRAY;
|
}
|
||||||
flashReadState = FLASH_READ_ARRAY;
|
else
|
||||||
} else if(address == 0x5555 && byte == 0xAA)
|
{
|
||||||
flashState = FLASH_CMD_1;
|
flashState = FLASH_READ_ARRAY;
|
||||||
else {
|
flashReadState = FLASH_READ_ARRAY;
|
||||||
flashState = FLASH_READ_ARRAY;
|
}
|
||||||
flashReadState = FLASH_READ_ARRAY;
|
break;
|
||||||
}
|
case FLASH_AUTOSELECT:
|
||||||
break;
|
if(byte == 0xF0)
|
||||||
case FLASH_PROGRAM:
|
{
|
||||||
flashSaveMemory[(flashBank<<16)+address] = byte;
|
flashState = FLASH_READ_ARRAY;
|
||||||
systemSaveUpdateCounter = SYSTEM_SAVE_UPDATED;
|
flashReadState = FLASH_READ_ARRAY;
|
||||||
flashState = FLASH_READ_ARRAY;
|
}
|
||||||
flashReadState = FLASH_READ_ARRAY;
|
else if(address == 0x5555 && byte == 0xAA)
|
||||||
break;
|
flashState = FLASH_CMD_1;
|
||||||
case FLASH_SETBANK:
|
else
|
||||||
if(address == 0) {
|
{
|
||||||
flashBank = (byte & 1);
|
flashState = FLASH_READ_ARRAY;
|
||||||
}
|
flashReadState = FLASH_READ_ARRAY;
|
||||||
flashState = FLASH_READ_ARRAY;
|
}
|
||||||
flashReadState = FLASH_READ_ARRAY;
|
break;
|
||||||
break;
|
case FLASH_PROGRAM:
|
||||||
}
|
flashSaveMemory[(flashBank<<16)+address] = byte;
|
||||||
}
|
systemSaveUpdateCounter = SYSTEM_SAVE_UPDATED;
|
||||||
|
flashState = FLASH_READ_ARRAY;
|
||||||
|
flashReadState = FLASH_READ_ARRAY;
|
||||||
|
break;
|
||||||
|
case FLASH_SETBANK:
|
||||||
|
if(address == 0)
|
||||||
|
{
|
||||||
|
flashBank = (byte & 1);
|
||||||
|
}
|
||||||
|
flashState = FLASH_READ_ARRAY;
|
||||||
|
flashReadState = FLASH_READ_ARRAY;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -1,36 +1,33 @@
|
|||||||
// -*- C++ -*-
|
// -*- C++ -*-
|
||||||
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
|
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
|
||||||
// Copyright (C) 1999-2003 Forgotten
|
// Copyright (C) 1999-2003 Forgotten
|
||||||
// Copyright (C) 2004 Forgotten and the VBA development team
|
// Copyright (C) 2004 Forgotten and the VBA development team
|
||||||
|
|
||||||
// This program is free software; you can redistribute it and/or modify
|
// This program is free software; you can redistribute it and/or modify
|
||||||
// it under the terms of the GNU General Public License as published by
|
// it under the terms of the GNU General Public License as published by
|
||||||
// the Free Software Foundation; either version 2, or(at your option)
|
// the Free Software Foundation; either version 2, or(at your option)
|
||||||
// any later version.
|
// any later version.
|
||||||
//
|
//
|
||||||
// This program is distributed in the hope that it will be useful,
|
// This program is distributed in the hope that it will be useful,
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
// GNU General Public License for more details.
|
// GNU General Public License for more details.
|
||||||
//
|
//
|
||||||
// You should have received a copy of the GNU General Public License
|
// You should have received a copy of the GNU General Public License
|
||||||
// along with this program; if not, write to the Free Software Foundation,
|
// along with this program; if not, write to the Free Software Foundation,
|
||||||
// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
#ifndef VBA_FLASH_H
|
#ifndef VBA_FLASH_H
|
||||||
#define VBA_FLASH_H
|
#define VBA_FLASH_H
|
||||||
|
|
||||||
extern void flashSaveGame(gzFile _gzFile);
|
extern void flashSaveGame(gzFile gzFile);
|
||||||
extern void flashReadGame(gzFile _gzFile, int version);
|
extern void flashReadGame(gzFile gzFile, int version);
|
||||||
extern void flashReadGameSkip(gzFile _gzFile, int version);
|
extern u8 flashRead(u32 address);
|
||||||
extern u8 flashRead(u32 address);
|
extern void flashWrite(u32 address, u8 byte);
|
||||||
extern void flashWrite(u32 address, u8 byte);
|
extern u8 flashSaveMemory[0x20000];
|
||||||
extern void flashDelayedWrite(u32 address, u8 byte);
|
extern void flashSaveDecide(u32 address, u8 byte);
|
||||||
extern u8 flashSaveMemory[0x20000];
|
extern void flashReset();
|
||||||
extern void flashSaveDecide(u32 address, u8 byte);
|
extern void flashSetSize(int size);
|
||||||
extern void flashReset();
|
|
||||||
extern void flashSetSize(int size);
|
extern int flashSize;
|
||||||
extern void flashInit();
|
#endif // VBA_FLASH_H
|
||||||
|
|
||||||
extern int flashSize;
|
|
||||||
#endif // VBA_FLASH_H
|
|
||||||
|
4361
source/vba/GBA.cpp
Normal file
4361
source/vba/GBA.cpp
Normal file
File diff suppressed because it is too large
Load Diff
@ -1,160 +1,153 @@
|
|||||||
// -*- C++ -*-
|
// -*- C++ -*-
|
||||||
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
|
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
|
||||||
// Copyright (C) 1999-2003 Forgotten
|
// Copyright (C) 1999-2003 Forgotten
|
||||||
// Copyright (C) 2005 Forgotten and the VBA development team
|
// Copyright (C) 2004 Forgotten and the VBA development team
|
||||||
|
|
||||||
// This program is free software; you can redistribute it and/or modify
|
// This program is free software; you can redistribute it and/or modify
|
||||||
// it under the terms of the GNU General Public License as published by
|
// it under the terms of the GNU General Public License as published by
|
||||||
// the Free Software Foundation; either version 2, or(at your option)
|
// the Free Software Foundation; either version 2, or(at your option)
|
||||||
// any later version.
|
// any later version.
|
||||||
//
|
//
|
||||||
// This program is distributed in the hope that it will be useful,
|
// This program is distributed in the hope that it will be useful,
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
// GNU General Public License for more details.
|
// GNU General Public License for more details.
|
||||||
//
|
//
|
||||||
// You should have received a copy of the GNU General Public License
|
// You should have received a copy of the GNU General Public License
|
||||||
// along with this program; if not, write to the Free Software Foundation,
|
// along with this program; if not, write to the Free Software Foundation,
|
||||||
// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
#ifndef VBA_GBA_H
|
#ifndef VBA_GBA_H
|
||||||
#define VBA_GBA_H
|
#define VBA_GBA_H
|
||||||
|
|
||||||
#include "../System.h"
|
#include "System.h"
|
||||||
|
|
||||||
#define SAVE_GAME_VERSION_1 1
|
#define SAVE_GAME_VERSION_1 1
|
||||||
#define SAVE_GAME_VERSION_2 2
|
#define SAVE_GAME_VERSION_2 2
|
||||||
#define SAVE_GAME_VERSION_3 3
|
#define SAVE_GAME_VERSION_3 3
|
||||||
#define SAVE_GAME_VERSION_4 4
|
#define SAVE_GAME_VERSION_4 4
|
||||||
#define SAVE_GAME_VERSION_5 5
|
#define SAVE_GAME_VERSION_5 5
|
||||||
#define SAVE_GAME_VERSION_6 6
|
#define SAVE_GAME_VERSION_6 6
|
||||||
#define SAVE_GAME_VERSION_7 7
|
#define SAVE_GAME_VERSION_7 7
|
||||||
#define SAVE_GAME_VERSION_8 8
|
#define SAVE_GAME_VERSION_8 8
|
||||||
#define SAVE_GAME_VERSION_9 9
|
#define SAVE_GAME_VERSION SAVE_GAME_VERSION_8
|
||||||
#define SAVE_GAME_VERSION_10 10
|
|
||||||
#define SAVE_GAME_VERSION SAVE_GAME_VERSION_10
|
typedef struct
|
||||||
|
{
|
||||||
typedef struct {
|
u8 *address;
|
||||||
u8 *address;
|
u32 mask;
|
||||||
u32 mask;
|
}
|
||||||
} memoryMap;
|
memoryMap;
|
||||||
|
|
||||||
typedef union {
|
typedef union {
|
||||||
struct {
|
struct
|
||||||
#ifdef WORDS_BIGENDIAN
|
{
|
||||||
u8 B3;
|
#ifdef WORDS_BIGENDIAN
|
||||||
u8 B2;
|
u8 B3;
|
||||||
u8 B1;
|
u8 B2;
|
||||||
u8 B0;
|
u8 B1;
|
||||||
#else
|
u8 B0;
|
||||||
u8 B0;
|
#else
|
||||||
u8 B1;
|
u8 B0;
|
||||||
u8 B2;
|
u8 B1;
|
||||||
u8 B3;
|
u8 B2;
|
||||||
#endif
|
u8 B3;
|
||||||
} B;
|
#endif
|
||||||
struct {
|
}
|
||||||
#ifdef WORDS_BIGENDIAN
|
B;
|
||||||
u16 W1;
|
struct
|
||||||
u16 W0;
|
{
|
||||||
#else
|
#ifdef WORDS_BIGENDIAN
|
||||||
u16 W0;
|
u16 W1;
|
||||||
u16 W1;
|
u16 W0;
|
||||||
#endif
|
#else
|
||||||
} W;
|
u16 W0;
|
||||||
#ifdef WORDS_BIGENDIAN
|
u16 W1;
|
||||||
volatile u32 I;
|
#endif
|
||||||
#else
|
}
|
||||||
u32 I;
|
W;
|
||||||
#endif
|
#ifdef WORDS_BIGENDIAN
|
||||||
} reg_pair;
|
volatile u32 I;
|
||||||
|
#else
|
||||||
#ifndef NO_GBA_MAP
|
u32 I;
|
||||||
extern memoryMap map[256];
|
#endif
|
||||||
#endif
|
} reg_pair;
|
||||||
|
|
||||||
extern reg_pair reg[45];
|
#ifndef NO_GBA_MAP
|
||||||
extern u8 biosProtected[4];
|
extern memoryMap map[256];
|
||||||
|
#endif
|
||||||
extern bool N_FLAG;
|
|
||||||
extern bool Z_FLAG;
|
extern reg_pair reg[45];
|
||||||
extern bool C_FLAG;
|
extern u8 biosProtected[4];
|
||||||
extern bool V_FLAG;
|
|
||||||
extern bool armIrqEnable;
|
extern bool N_FLAG;
|
||||||
extern bool armState;
|
extern bool Z_FLAG;
|
||||||
extern int armMode;
|
extern bool C_FLAG;
|
||||||
extern void (*cpuSaveGameFunc)(u32,u8);
|
extern bool V_FLAG;
|
||||||
|
extern bool armIrqEnable;
|
||||||
#ifdef BKPT_SUPPORT
|
extern bool armState;
|
||||||
extern u8 freezeWorkRAM[0x40000];
|
extern int armMode;
|
||||||
extern u8 freezeInternalRAM[0x8000];
|
extern void (*cpuSaveGameFunc)(u32,u8);
|
||||||
extern u8 freezeVRAM[0x18000];
|
|
||||||
extern u8 freezeOAM[0x400];
|
extern bool freezeWorkRAM[0x40000];
|
||||||
extern u8 freezePRAM[0x400];
|
extern bool freezeInternalRAM[0x8000];
|
||||||
extern bool debugger_last;
|
extern bool CPUReadGSASnapshot(const char *);
|
||||||
extern int oldreg[17];
|
extern bool CPUWriteGSASnapshot(const char *, const char *, const char *, const char *);
|
||||||
extern char oldbuffer[10];
|
extern bool CPUWriteBatteryFile(const char *);
|
||||||
#endif
|
extern bool CPUReadBatteryFile(const char *);
|
||||||
|
extern bool CPUExportEepromFile(const char *);
|
||||||
extern bool CPUReadGSASnapshot(const char *);
|
extern bool CPUImportEepromFile(const char *);
|
||||||
extern bool CPUWriteGSASnapshot(const char *, const char *, const char *, const char *);
|
extern bool CPUWritePNGFile(const char *);
|
||||||
extern bool CPUWriteBatteryFile(const char *);
|
extern bool CPUWriteBMPFile(const char *);
|
||||||
extern bool CPUReadBatteryFile(const char *);
|
extern void CPUCleanUp();
|
||||||
extern bool CPUExportEepromFile(const char *);
|
extern void CPUUpdateRender();
|
||||||
extern bool CPUImportEepromFile(const char *);
|
extern bool CPUReadMemState(char *, int);
|
||||||
extern bool CPUWritePNGFile(const char *);
|
extern bool CPUReadState(const char *);
|
||||||
extern bool CPUWriteBMPFile(const char *);
|
extern bool CPUWriteMemState(char *, int);
|
||||||
extern void CPUCleanUp();
|
extern bool CPUWriteState(const char *);
|
||||||
extern void CPUUpdateRender();
|
extern int CPULoadRom(const char *);
|
||||||
extern void CPUUpdateRenderBuffers(bool);
|
extern void CPUUpdateRegister(u32, u16);
|
||||||
extern bool CPUReadMemState(char *, int);
|
extern void CPUWriteHalfWord(u32, u16);
|
||||||
extern bool CPUReadState(const char *);
|
extern void CPUWriteByte(u32, u8);
|
||||||
extern bool CPUWriteMemState(char *, int);
|
extern void CPUInit(const char *,bool);
|
||||||
extern bool CPUWriteState(const char *);
|
extern void CPUReset();
|
||||||
extern int CPULoadRom(const char *);
|
extern void CPULoop(int);
|
||||||
extern void doMirroring(bool);
|
extern void CPUCheckDMA(int,int);
|
||||||
extern void CPUUpdateRegister(u32, u16);
|
extern bool CPUIsGBAImage(const char *);
|
||||||
extern void applyTimer ();
|
extern bool CPUIsZipFile(const char *);
|
||||||
extern void CPUInit(const char *,bool);
|
#ifdef PROFILING
|
||||||
extern void CPUReset();
|
extern void cpuProfil(char *buffer, int, u32, int);
|
||||||
extern void CPULoop(int);
|
extern void cpuEnableProfiling(int hz);
|
||||||
extern void CPUCheckDMA(int,int);
|
#endif
|
||||||
extern bool CPUIsGBAImage(const char *);
|
|
||||||
extern bool CPUIsZipFile(const char *);
|
extern struct EmulatedSystem GBASystem;
|
||||||
#ifdef PROFILING
|
|
||||||
#include "prof/prof.h"
|
#define R13_IRQ 18
|
||||||
extern void cpuProfil(profile_segment *seg);
|
#define R14_IRQ 19
|
||||||
extern void cpuEnableProfiling(int hz);
|
#define SPSR_IRQ 20
|
||||||
#endif
|
#define R13_USR 26
|
||||||
|
#define R14_USR 27
|
||||||
extern struct EmulatedSystem GBASystem;
|
#define R13_SVC 28
|
||||||
|
#define R14_SVC 29
|
||||||
#define R13_IRQ 18
|
#define SPSR_SVC 30
|
||||||
#define R14_IRQ 19
|
#define R13_ABT 31
|
||||||
#define SPSR_IRQ 20
|
#define R14_ABT 32
|
||||||
#define R13_USR 26
|
#define SPSR_ABT 33
|
||||||
#define R14_USR 27
|
#define R13_UND 34
|
||||||
#define R13_SVC 28
|
#define R14_UND 35
|
||||||
#define R14_SVC 29
|
#define SPSR_UND 36
|
||||||
#define SPSR_SVC 30
|
#define R8_FIQ 37
|
||||||
#define R13_ABT 31
|
#define R9_FIQ 38
|
||||||
#define R14_ABT 32
|
#define R10_FIQ 39
|
||||||
#define SPSR_ABT 33
|
#define R11_FIQ 40
|
||||||
#define R13_UND 34
|
#define R12_FIQ 41
|
||||||
#define R14_UND 35
|
#define R13_FIQ 42
|
||||||
#define SPSR_UND 36
|
#define R14_FIQ 43
|
||||||
#define R8_FIQ 37
|
#define SPSR_FIQ 44
|
||||||
#define R9_FIQ 38
|
|
||||||
#define R10_FIQ 39
|
#include "Cheats.h"
|
||||||
#define R11_FIQ 40
|
#include "Globals.h"
|
||||||
#define R12_FIQ 41
|
#include "EEprom.h"
|
||||||
#define R13_FIQ 42
|
#include "Flash.h"
|
||||||
#define R14_FIQ 43
|
|
||||||
#define SPSR_FIQ 44
|
#endif //VBA_GBA_H
|
||||||
|
|
||||||
#include "../Cheats.h"
|
|
||||||
#include "../Globals.h"
|
|
||||||
#include "../EEprom.h"
|
|
||||||
#include "../Flash.h"
|
|
||||||
|
|
||||||
#endif //VBA_GBA_H
|
|
556
source/vba/GBAinline.h
Normal file
556
source/vba/GBAinline.h
Normal file
@ -0,0 +1,556 @@
|
|||||||
|
// -*- C++ -*-
|
||||||
|
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
|
||||||
|
// Copyright (C) 1999-2003 Forgotten
|
||||||
|
// Copyright (C) 2004 Forgotten and the VBA development team
|
||||||
|
|
||||||
|
// This program is free software; you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation; either version 2, or(at your option)
|
||||||
|
// any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with this program; if not, write to the Free Software Foundation,
|
||||||
|
// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
|
#ifndef VBA_GBAinline_H
|
||||||
|
#define VBA_GBAinline_H
|
||||||
|
|
||||||
|
#include "System.h"
|
||||||
|
#include "Port.h"
|
||||||
|
#include "RTC.h"
|
||||||
|
#include "vmmem.h"
|
||||||
|
|
||||||
|
extern bool cpuSramEnabled;
|
||||||
|
extern bool cpuFlashEnabled;
|
||||||
|
extern bool cpuEEPROMEnabled;
|
||||||
|
extern bool cpuEEPROMSensorEnabled;
|
||||||
|
|
||||||
|
#define VM_USED 1
|
||||||
|
|
||||||
|
#define CPUReadByteQuickDef(addr) \
|
||||||
|
map[(addr)>>24].address[(addr) & map[(addr)>>24].mask]
|
||||||
|
|
||||||
|
#define CPUReadHalfWordQuickDef(addr) \
|
||||||
|
READ16LE(((u16*)&map[(addr)>>24].address[(addr) & map[(addr)>>24].mask]))
|
||||||
|
|
||||||
|
#define CPUReadMemoryQuickDef(addr) \
|
||||||
|
READ32LE(((u32*)&map[(addr)>>24].address[(addr) & map[(addr)>>24].mask]))
|
||||||
|
|
||||||
|
u8 inline CPUReadByteQuick( u32 addr )
|
||||||
|
{
|
||||||
|
switch(addr >> 24 )
|
||||||
|
{
|
||||||
|
case 8:
|
||||||
|
case 9:
|
||||||
|
case 10:
|
||||||
|
case 12:
|
||||||
|
return VMRead8( addr & 0x1FFFFFF );
|
||||||
|
|
||||||
|
default:
|
||||||
|
return CPUReadByteQuickDef(addr);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
u16 inline CPUReadHalfWordQuick( u32 addr )
|
||||||
|
{
|
||||||
|
switch(addr >> 24)
|
||||||
|
{
|
||||||
|
case 8:
|
||||||
|
case 9:
|
||||||
|
case 10:
|
||||||
|
case 12:
|
||||||
|
return VMRead16( addr & 0x1FFFFFF );
|
||||||
|
default:
|
||||||
|
return CPUReadHalfWordQuickDef(addr);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
u32 inline CPUReadMemoryQuick( u32 addr )
|
||||||
|
{
|
||||||
|
switch(addr >> 24)
|
||||||
|
{
|
||||||
|
case 8:
|
||||||
|
case 9:
|
||||||
|
case 10:
|
||||||
|
case 12:
|
||||||
|
return VMRead32( addr & 0x1FFFFFF );
|
||||||
|
default:
|
||||||
|
return CPUReadMemoryQuickDef(addr);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline u32 CPUReadMemory(u32 address)
|
||||||
|
{
|
||||||
|
|
||||||
|
#ifdef DEV_VERSION
|
||||||
|
if(address & 3)
|
||||||
|
{
|
||||||
|
if(systemVerbose & VERBOSE_UNALIGNED_MEMORY)
|
||||||
|
{
|
||||||
|
log("Unaligned word read: %08x at %08x\n", address, armMode ?
|
||||||
|
armNextPC - 4 : armNextPC - 2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
u32 value;
|
||||||
|
switch(address >> 24)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
if(reg[15].I >> 24)
|
||||||
|
{
|
||||||
|
if(address < 0x4000)
|
||||||
|
{
|
||||||
|
#ifdef DEV_VERSION
|
||||||
|
if(systemVerbose & VERBOSE_ILLEGAL_READ)
|
||||||
|
{
|
||||||
|
log("Illegal word read: %08x at %08x\n", address, armMode ?
|
||||||
|
armNextPC - 4 : armNextPC - 2);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
value = READ32LE(((u32 *)&biosProtected));
|
||||||
|
}
|
||||||
|
else goto unreadable;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
value = READ32LE(((u32 *)&bios[address & 0x3FFC]));
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
value = READ32LE(((u32 *)&workRAM[address & 0x3FFFC]));
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
value = READ32LE(((u32 *)&internalRAM[address & 0x7ffC]));
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
if((address < 0x4000400) && ioReadable[address & 0x3fc])
|
||||||
|
{
|
||||||
|
if(ioReadable[(address & 0x3fc) + 2])
|
||||||
|
value = READ32LE(((u32 *)&ioMem[address & 0x3fC]));
|
||||||
|
else
|
||||||
|
value = READ16LE(((u16 *)&ioMem[address & 0x3fc]));
|
||||||
|
}
|
||||||
|
else goto unreadable;
|
||||||
|
break;
|
||||||
|
case 5:
|
||||||
|
value = READ32LE(((u32 *)&paletteRAM[address & 0x3fC]));
|
||||||
|
break;
|
||||||
|
case 6:
|
||||||
|
value = READ32LE(((u32 *)&vram[address & 0x1fffc]));
|
||||||
|
break;
|
||||||
|
case 7:
|
||||||
|
value = READ32LE(((u32 *)&oam[address & 0x3FC]));
|
||||||
|
break;
|
||||||
|
case 8:
|
||||||
|
case 9:
|
||||||
|
case 10:
|
||||||
|
case 11:
|
||||||
|
case 12:
|
||||||
|
/** Need NGC VM here **/
|
||||||
|
//value = READ32LE(((u32 *)&rom[address&0x1FFFFFC]));
|
||||||
|
value = VMRead32( address & 0x1FFFFFC );
|
||||||
|
break;
|
||||||
|
case 13:
|
||||||
|
if(cpuEEPROMEnabled)
|
||||||
|
// no need to swap this
|
||||||
|
return eepromRead(address);
|
||||||
|
goto unreadable;
|
||||||
|
case 14:
|
||||||
|
if(cpuFlashEnabled | cpuSramEnabled)
|
||||||
|
// no need to swap this
|
||||||
|
return flashRead(address);
|
||||||
|
// default
|
||||||
|
default:
|
||||||
|
unreadable:
|
||||||
|
#ifdef DEV_VERSION
|
||||||
|
if(systemVerbose & VERBOSE_ILLEGAL_READ)
|
||||||
|
{
|
||||||
|
log("Illegal word read: %08x at %08x\n", address, armMode ?
|
||||||
|
armNextPC - 4 : armNextPC - 2);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// if(ioMem[0x205] & 0x40) {
|
||||||
|
if(armState)
|
||||||
|
{
|
||||||
|
#if VM_USED
|
||||||
|
value = CPUReadMemoryQuick(reg[15].I);
|
||||||
|
#else
|
||||||
|
value = CPUReadMemoryQuickDef(reg[15].I);
|
||||||
|
#endif
|
||||||
|
//value = VMRead32(reg[15].I);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
#if VM_USED
|
||||||
|
value = CPUReadHalfWordQuick(reg[15].I) |
|
||||||
|
CPUReadHalfWordQuick(reg[15].I) << 16;
|
||||||
|
#else
|
||||||
|
value = CPUReadHalfWordQuickDef(reg[15].I) |
|
||||||
|
CPUReadHalfWordQuickDef(reg[15].I) << 16;
|
||||||
|
#endif
|
||||||
|
//value = VMRead16(reg[15].I) | VMRead16(reg[15].I) << 16;
|
||||||
|
}
|
||||||
|
// } else {
|
||||||
|
// value = *((u32 *)&bios[address & 0x3ffc]);
|
||||||
|
// }
|
||||||
|
// return 0xFFFFFFFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(address & 3)
|
||||||
|
{
|
||||||
|
#ifdef C_CORE
|
||||||
|
int shift = (address & 3) << 3;
|
||||||
|
value = (value >> shift) | (value << (32 - shift));
|
||||||
|
#else
|
||||||
|
#ifdef __GNUC__
|
||||||
|
asm("and $3, %%ecx;"
|
||||||
|
"shl $3 ,%%ecx;"
|
||||||
|
"ror %%cl, %0"
|
||||||
|
: "=r" (value)
|
||||||
|
: "r" (value), "c" (address));
|
||||||
|
#else
|
||||||
|
__asm {
|
||||||
|
mov ecx, address;
|
||||||
|
and ecx, 3;
|
||||||
|
shl ecx, 3;
|
||||||
|
ror [dword ptr value], cl;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
extern u32 myROM[];
|
||||||
|
|
||||||
|
inline u32 CPUReadHalfWord(u32 address)
|
||||||
|
{
|
||||||
|
#ifdef DEV_VERSION
|
||||||
|
if(address & 1)
|
||||||
|
{
|
||||||
|
if(systemVerbose & VERBOSE_UNALIGNED_MEMORY)
|
||||||
|
{
|
||||||
|
log("Unaligned halfword read: %08x at %08x\n", address, armMode ?
|
||||||
|
armNextPC - 4 : armNextPC - 2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
u32 value;
|
||||||
|
|
||||||
|
switch(address >> 24)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
if (reg[15].I >> 24)
|
||||||
|
{
|
||||||
|
if(address < 0x4000)
|
||||||
|
{
|
||||||
|
#ifdef DEV_VERSION
|
||||||
|
if(systemVerbose & VERBOSE_ILLEGAL_READ)
|
||||||
|
{
|
||||||
|
log("Illegal halfword read: %08x at %08x\n", address, armMode ?
|
||||||
|
armNextPC - 4 : armNextPC - 2);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
value = READ16LE(((u16 *)&biosProtected[address&2]));
|
||||||
|
}
|
||||||
|
else goto unreadable;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
value = READ16LE(((u16 *)&bios[address & 0x3FFE]));
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
value = READ16LE(((u16 *)&workRAM[address & 0x3FFFE]));
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
value = READ16LE(((u16 *)&internalRAM[address & 0x7ffe]));
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
if((address < 0x4000400) && ioReadable[address & 0x3fe])
|
||||||
|
value = READ16LE(((u16 *)&ioMem[address & 0x3fe]));
|
||||||
|
else goto unreadable;
|
||||||
|
break;
|
||||||
|
case 5:
|
||||||
|
value = READ16LE(((u16 *)&paletteRAM[address & 0x3fe]));
|
||||||
|
break;
|
||||||
|
case 6:
|
||||||
|
value = READ16LE(((u16 *)&vram[address & 0x1fffe]));
|
||||||
|
break;
|
||||||
|
case 7:
|
||||||
|
value = READ16LE(((u16 *)&oam[address & 0x3fe]));
|
||||||
|
break;
|
||||||
|
case 8:
|
||||||
|
case 9:
|
||||||
|
case 10:
|
||||||
|
case 11:
|
||||||
|
case 12:
|
||||||
|
if(address == 0x80000c4 || address == 0x80000c6 || address == 0x80000c8)
|
||||||
|
value = rtcRead(address);
|
||||||
|
else
|
||||||
|
/** Need NGC VM Here **/
|
||||||
|
//value = READ16LE(((u16 *)&rom[address & 0x1FFFFFE]));
|
||||||
|
value = VMRead16( address & 0x1FFFFFE );
|
||||||
|
break;
|
||||||
|
case 13:
|
||||||
|
if(cpuEEPROMEnabled)
|
||||||
|
// no need to swap this
|
||||||
|
return eepromRead(address);
|
||||||
|
goto unreadable;
|
||||||
|
case 14:
|
||||||
|
if(cpuFlashEnabled | cpuSramEnabled)
|
||||||
|
// no need to swap this
|
||||||
|
return flashRead(address);
|
||||||
|
// default
|
||||||
|
default:
|
||||||
|
unreadable:
|
||||||
|
#ifdef DEV_VERSION
|
||||||
|
if(systemVerbose & VERBOSE_ILLEGAL_READ)
|
||||||
|
{
|
||||||
|
log("Illegal halfword read: %08x at %08x\n", address, armMode ?
|
||||||
|
armNextPC - 4 : armNextPC - 2);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
extern bool cpuDmaHack;
|
||||||
|
extern u32 cpuDmaLast;
|
||||||
|
extern int cpuDmaCount;
|
||||||
|
if(cpuDmaHack && cpuDmaCount)
|
||||||
|
{
|
||||||
|
value = (u16)cpuDmaLast;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(armState)
|
||||||
|
{
|
||||||
|
#if VM_USED
|
||||||
|
value = CPUReadHalfWordQuick(reg[15].I + (address & 2));
|
||||||
|
#else
|
||||||
|
value = CPUReadHalfWordQuickDef(reg[15].I + (address & 2));
|
||||||
|
#endif
|
||||||
|
//value = VMRead16(reg[15].I + (address & 2));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
#if VM_USED
|
||||||
|
value = CPUReadHalfWordQuick(reg[15].I);
|
||||||
|
#else
|
||||||
|
value = CPUReadHalfWordQuickDef(reg[15].I);
|
||||||
|
#endif
|
||||||
|
//value = VMRead16(reg[15].I);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// return value;
|
||||||
|
// if(address & 1)
|
||||||
|
// value = (value >> 8) | ((value & 0xFF) << 24);
|
||||||
|
// return 0xFFFF;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(address & 1)
|
||||||
|
{
|
||||||
|
value = (value >> 8) | (value << 24);
|
||||||
|
}
|
||||||
|
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline u16 CPUReadHalfWordSigned(u32 address)
|
||||||
|
{
|
||||||
|
u16 value = CPUReadHalfWord(address);
|
||||||
|
if((address & 1))
|
||||||
|
value = (s8)value;
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline u8 CPUReadByte(u32 address)
|
||||||
|
{
|
||||||
|
switch(address >> 24)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
if (reg[15].I >> 24)
|
||||||
|
{
|
||||||
|
if(address < 0x4000)
|
||||||
|
{
|
||||||
|
#ifdef DEV_VERSION
|
||||||
|
if(systemVerbose & VERBOSE_ILLEGAL_READ)
|
||||||
|
{
|
||||||
|
log("Illegal byte read: %08x at %08x\n", address, armMode ?
|
||||||
|
armNextPC - 4 : armNextPC - 2);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
return biosProtected[address & 3];
|
||||||
|
}
|
||||||
|
else goto unreadable;
|
||||||
|
}
|
||||||
|
return bios[address & 0x3FFF];
|
||||||
|
case 2:
|
||||||
|
return workRAM[address & 0x3FFFF];
|
||||||
|
case 3:
|
||||||
|
return internalRAM[address & 0x7fff];
|
||||||
|
case 4:
|
||||||
|
if((address < 0x4000400) && ioReadable[address & 0x3ff])
|
||||||
|
return ioMem[address & 0x3ff];
|
||||||
|
else goto unreadable;
|
||||||
|
case 5:
|
||||||
|
return paletteRAM[address & 0x3ff];
|
||||||
|
case 6:
|
||||||
|
return vram[address & 0x1ffff];
|
||||||
|
case 7:
|
||||||
|
return oam[address & 0x3ff];
|
||||||
|
case 8:
|
||||||
|
case 9:
|
||||||
|
case 10:
|
||||||
|
case 11:
|
||||||
|
case 12:
|
||||||
|
/** Need NGC VM Here **/
|
||||||
|
//return rom[address & 0x1FFFFFF];
|
||||||
|
return VMRead8( address & 0x1FFFFFF );
|
||||||
|
case 13:
|
||||||
|
if(cpuEEPROMEnabled)
|
||||||
|
return eepromRead(address);
|
||||||
|
goto unreadable;
|
||||||
|
case 14:
|
||||||
|
if(cpuSramEnabled | cpuFlashEnabled)
|
||||||
|
return flashRead(address);
|
||||||
|
if(cpuEEPROMSensorEnabled)
|
||||||
|
{
|
||||||
|
switch(address & 0x00008f00)
|
||||||
|
{
|
||||||
|
case 0x8200:
|
||||||
|
return systemGetSensorX() & 255;
|
||||||
|
case 0x8300:
|
||||||
|
return (systemGetSensorX() >> 8)|0x80;
|
||||||
|
case 0x8400:
|
||||||
|
return systemGetSensorY() & 255;
|
||||||
|
case 0x8500:
|
||||||
|
return systemGetSensorY() >> 8;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// default
|
||||||
|
default:
|
||||||
|
unreadable:
|
||||||
|
#ifdef DEV_VERSION
|
||||||
|
if(systemVerbose & VERBOSE_ILLEGAL_READ)
|
||||||
|
{
|
||||||
|
log("Illegal byte read: %08x at %08x\n", address, armMode ?
|
||||||
|
armNextPC - 4 : armNextPC - 2);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if(armState)
|
||||||
|
{
|
||||||
|
#if VM_USED
|
||||||
|
return CPUReadByteQuick(reg[15].I+(address & 3));
|
||||||
|
#else
|
||||||
|
return CPUReadByteQuickDef(reg[15].I+(address & 3));
|
||||||
|
#endif
|
||||||
|
//return VMRead8(reg[15].I+(address & 3));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
#if VM_USED
|
||||||
|
return CPUReadByteQuick(reg[15].I+(address & 1));
|
||||||
|
#else
|
||||||
|
return CPUReadByteQuickDef(reg[15].I+(address & 1));
|
||||||
|
#endif
|
||||||
|
//return VMRead8(reg[15].I+(address & 1));
|
||||||
|
}
|
||||||
|
// return 0xFF;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void CPUWriteMemory(u32 address, u32 value)
|
||||||
|
{
|
||||||
|
#ifdef DEV_VERSION
|
||||||
|
if(address & 3)
|
||||||
|
{
|
||||||
|
if(systemVerbose & VERBOSE_UNALIGNED_MEMORY)
|
||||||
|
{
|
||||||
|
log("Unaliagned word write: %08x to %08x from %08x\n",
|
||||||
|
value,
|
||||||
|
address,
|
||||||
|
armMode ? armNextPC - 4 : armNextPC - 2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
switch(address >> 24)
|
||||||
|
{
|
||||||
|
case 0x02:
|
||||||
|
#ifdef SDL
|
||||||
|
if(*((u32 *)&freezeWorkRAM[address & 0x3FFFC]))
|
||||||
|
cheatsWriteMemory((u32 *)&workRAM[address & 0x3FFFC],
|
||||||
|
value,
|
||||||
|
*((u32 *)&freezeWorkRAM[address & 0x3FFFC]));
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
WRITE32LE(((u32 *)&workRAM[address & 0x3FFFC]), value);
|
||||||
|
break;
|
||||||
|
case 0x03:
|
||||||
|
#ifdef SDL
|
||||||
|
if(*((u32 *)&freezeInternalRAM[address & 0x7ffc]))
|
||||||
|
cheatsWriteMemory((u32 *)&internalRAM[address & 0x7FFC],
|
||||||
|
value,
|
||||||
|
*((u32 *)&freezeInternalRAM[address & 0x7ffc]));
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
WRITE32LE(((u32 *)&internalRAM[address & 0x7ffC]), value);
|
||||||
|
break;
|
||||||
|
case 0x04:
|
||||||
|
CPUUpdateRegister((address & 0x3FC), value & 0xFFFF);
|
||||||
|
CPUUpdateRegister((address & 0x3FC) + 2, (value >> 16));
|
||||||
|
break;
|
||||||
|
case 0x05:
|
||||||
|
WRITE32LE(((u32 *)&paletteRAM[address & 0x3FC]), value);
|
||||||
|
break;
|
||||||
|
case 0x06:
|
||||||
|
if(address & 0x10000)
|
||||||
|
WRITE32LE(((u32 *)&vram[address & 0x17ffc]), value);
|
||||||
|
else
|
||||||
|
WRITE32LE(((u32 *)&vram[address & 0x1fffc]), value);
|
||||||
|
break;
|
||||||
|
case 0x07:
|
||||||
|
WRITE32LE(((u32 *)&oam[address & 0x3fc]), value);
|
||||||
|
break;
|
||||||
|
case 0x0D:
|
||||||
|
if(cpuEEPROMEnabled)
|
||||||
|
{
|
||||||
|
eepromWrite(address, value);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
goto unwritable;
|
||||||
|
case 0x0E:
|
||||||
|
if(!eepromInUse | cpuSramEnabled | cpuFlashEnabled)
|
||||||
|
{
|
||||||
|
(*cpuSaveGameFunc)(address, (u8)value);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
// default
|
||||||
|
default:
|
||||||
|
unwritable:
|
||||||
|
#ifdef DEV_VERSION
|
||||||
|
if(systemVerbose & VERBOSE_ILLEGAL_WRITE)
|
||||||
|
{
|
||||||
|
log("Illegal word write: %08x to %08x from %08x\n",
|
||||||
|
value,
|
||||||
|
address,
|
||||||
|
armMode ? armNextPC - 4 : armNextPC - 2);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif //VBA_GBAinline_H
|
@ -1,47 +1,47 @@
|
|||||||
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
|
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
|
||||||
// Copyright (C) 1999-2003 Forgotten
|
// Copyright (C) 1999-2003 Forgotten
|
||||||
// Copyright (C) 2004 Forgotten and the VBA development team
|
// Copyright (C) 2004 Forgotten and the VBA development team
|
||||||
|
|
||||||
// This program is free software; you can redistribute it and/or modify
|
// This program is free software; you can redistribute it and/or modify
|
||||||
// it under the terms of the GNU General Public License as published by
|
// it under the terms of the GNU General Public License as published by
|
||||||
// the Free Software Foundation; either version 2, or(at your option)
|
// the Free Software Foundation; either version 2, or(at your option)
|
||||||
// any later version.
|
// any later version.
|
||||||
//
|
//
|
||||||
// This program is distributed in the hope that it will be useful,
|
// This program is distributed in the hope that it will be useful,
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
// GNU General Public License for more details.
|
// GNU General Public License for more details.
|
||||||
//
|
//
|
||||||
// You should have received a copy of the GNU General Public License
|
// You should have received a copy of the GNU General Public License
|
||||||
// along with this program; if not, write to the Free Software Foundation,
|
// along with this program; if not, write to the Free Software Foundation,
|
||||||
// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
#include "../System.h"
|
#include "System.h"
|
||||||
|
|
||||||
int coeff[32] = {
|
int coeff[32] = {
|
||||||
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
|
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
|
||||||
16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16};
|
16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16};
|
||||||
|
|
||||||
u32 line0[240];
|
|
||||||
u32 line1[240];
|
u32 line0[240];
|
||||||
u32 line2[240];
|
u32 line1[240];
|
||||||
u32 line3[240];
|
u32 line2[240];
|
||||||
u32 lineOBJ[240];
|
u32 line3[240];
|
||||||
u32 lineOBJWin[240];
|
u32 lineOBJ[240];
|
||||||
u32 lineMix[240];
|
u32 lineOBJWin[240];
|
||||||
bool gfxInWin0[240];
|
u32 lineMix[240];
|
||||||
bool gfxInWin1[240];
|
bool gfxInWin0[240];
|
||||||
int lineOBJpixleft[128];
|
bool gfxInWin1[240];
|
||||||
|
|
||||||
int gfxBG2Changed = 0;
|
int gfxBG2Changed = 0;
|
||||||
int gfxBG3Changed = 0;
|
int gfxBG3Changed = 0;
|
||||||
|
|
||||||
int gfxBG2X = 0;
|
int gfxBG2X = 0;
|
||||||
int gfxBG2Y = 0;
|
int gfxBG2Y = 0;
|
||||||
int gfxBG2LastX = 0;
|
int gfxBG2LastX = 0;
|
||||||
int gfxBG2LastY = 0;
|
int gfxBG2LastY = 0;
|
||||||
int gfxBG3X = 0;
|
int gfxBG3X = 0;
|
||||||
int gfxBG3Y = 0;
|
int gfxBG3Y = 0;
|
||||||
int gfxBG3LastX = 0;
|
int gfxBG3LastX = 0;
|
||||||
int gfxBG3LastY = 0;
|
int gfxBG3LastY = 0;
|
||||||
int gfxLastVCOUNT = 0;
|
int gfxLastVCOUNT = 0;
|
1809
source/vba/Gfx.h
Normal file
1809
source/vba/Gfx.h
Normal file
File diff suppressed because it is too large
Load Diff
@ -1,6 +1,6 @@
|
|||||||
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
|
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
|
||||||
// Copyright (C) 1999-2003 Forgotten
|
// Copyright (C) 1999-2003 Forgotten
|
||||||
// Copyright (C) 2005 Forgotten and the VBA development team
|
// Copyright (C) 2004 Forgotten and the VBA development team
|
||||||
|
|
||||||
// This program is free software; you can redistribute it and/or modify
|
// This program is free software; you can redistribute it and/or modify
|
||||||
// it under the terms of the GNU General Public License as published by
|
// it under the terms of the GNU General Public License as published by
|
||||||
@ -16,12 +16,7 @@
|
|||||||
// along with this program; if not, write to the Free Software Foundation,
|
// along with this program; if not, write to the Free Software Foundation,
|
||||||
// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
#include "agb/GBA.h"
|
#include "GBA.h"
|
||||||
|
|
||||||
#ifdef BKPT_SUPPORT
|
|
||||||
int oldreg[17];
|
|
||||||
char oldbuffer[10];
|
|
||||||
#endif
|
|
||||||
|
|
||||||
reg_pair reg[45];
|
reg_pair reg[45];
|
||||||
memoryMap map[256];
|
memoryMap map[256];
|
||||||
@ -43,14 +38,13 @@ bool speedup = false;
|
|||||||
bool synchronize = true;
|
bool synchronize = true;
|
||||||
bool cpuDisableSfx = false;
|
bool cpuDisableSfx = false;
|
||||||
bool cpuIsMultiBoot = false;
|
bool cpuIsMultiBoot = false;
|
||||||
bool parseDebug = true;
|
bool parseDebug = false;
|
||||||
int layerSettings = 0xff00;
|
int layerSettings = 0xff00;
|
||||||
int layerEnable = 0xff00;
|
int layerEnable = 0xff00;
|
||||||
bool speedHack = false;
|
bool speedHack = false;
|
||||||
int cpuSaveType = 0;
|
int cpuSaveType = 0;
|
||||||
bool cheatsEnabled = true;
|
bool cpuEnhancedDetection = true;
|
||||||
bool mirroringEnable = false;
|
bool cheatsEnabled = false;
|
||||||
bool skipSaveGameBattery = false;
|
|
||||||
|
|
||||||
u8 *bios = NULL;
|
u8 *bios = NULL;
|
||||||
u8 *rom = NULL;
|
u8 *rom = NULL;
|
||||||
|
@ -1,153 +1,149 @@
|
|||||||
// -*- C++ -*-
|
// -*- C++ -*-
|
||||||
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
|
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
|
||||||
// Copyright (C) 1999-2003 Forgotten
|
// Copyright (C) 1999-2003 Forgotten
|
||||||
// Copyright (C) 2005 Forgotten and the VBA development team
|
// Copyright (C) 2004 Forgotten and the VBA development team
|
||||||
|
|
||||||
// This program is free software; you can redistribute it and/or modify
|
// This program is free software; you can redistribute it and/or modify
|
||||||
// it under the terms of the GNU General Public License as published by
|
// it under the terms of the GNU General Public License as published by
|
||||||
// the Free Software Foundation; either version 2, or(at your option)
|
// the Free Software Foundation; either version 2, or(at your option)
|
||||||
// any later version.
|
// any later version.
|
||||||
//
|
//
|
||||||
// This program is distributed in the hope that it will be useful,
|
// This program is distributed in the hope that it will be useful,
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
// GNU General Public License for more details.
|
// GNU General Public License for more details.
|
||||||
//
|
//
|
||||||
// You should have received a copy of the GNU General Public License
|
// You should have received a copy of the GNU General Public License
|
||||||
// along with this program; if not, write to the Free Software Foundation,
|
// along with this program; if not, write to the Free Software Foundation,
|
||||||
// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
#ifndef VBA_GLOBALS_H
|
#ifndef VBA_GLOBALS_H
|
||||||
#define VBA_GLOBALS_H
|
#define VBA_GLOBALS_H
|
||||||
|
|
||||||
#include "agb/GBA.h"
|
#define VERBOSE_SWI 1
|
||||||
|
#define VERBOSE_UNALIGNED_MEMORY 2
|
||||||
#define VERBOSE_SWI 1
|
#define VERBOSE_ILLEGAL_WRITE 4
|
||||||
#define VERBOSE_UNALIGNED_MEMORY 2
|
#define VERBOSE_ILLEGAL_READ 8
|
||||||
#define VERBOSE_ILLEGAL_WRITE 4
|
#define VERBOSE_DMA0 16
|
||||||
#define VERBOSE_ILLEGAL_READ 8
|
#define VERBOSE_DMA1 32
|
||||||
#define VERBOSE_DMA0 16
|
#define VERBOSE_DMA2 64
|
||||||
#define VERBOSE_DMA1 32
|
#define VERBOSE_DMA3 128
|
||||||
#define VERBOSE_DMA2 64
|
#define VERBOSE_UNDEFINED 256
|
||||||
#define VERBOSE_DMA3 128
|
#define VERBOSE_AGBPRINT 512
|
||||||
#define VERBOSE_UNDEFINED 256
|
|
||||||
#define VERBOSE_AGBPRINT 512
|
extern reg_pair reg[45];
|
||||||
#define VERBOSE_SOUNDOUTPUT 1024
|
extern bool ioReadable[0x400];
|
||||||
|
extern bool N_FLAG;
|
||||||
extern reg_pair reg[45];
|
extern bool C_FLAG;
|
||||||
extern bool ioReadable[0x400];
|
extern bool Z_FLAG;
|
||||||
extern bool N_FLAG;
|
extern bool V_FLAG;
|
||||||
extern bool C_FLAG;
|
extern bool armState;
|
||||||
extern bool Z_FLAG;
|
extern bool armIrqEnable;
|
||||||
extern bool V_FLAG;
|
extern u32 armNextPC;
|
||||||
extern bool armState;
|
extern int armMode;
|
||||||
extern bool armIrqEnable;
|
extern u32 stop;
|
||||||
extern u32 armNextPC;
|
extern int saveType;
|
||||||
extern int armMode;
|
extern bool useBios;
|
||||||
extern u32 stop;
|
extern bool skipBios;
|
||||||
extern int saveType;
|
extern int frameSkip;
|
||||||
extern bool useBios;
|
extern bool speedup;
|
||||||
extern bool skipBios;
|
extern bool synchronize;
|
||||||
extern int frameSkip;
|
extern bool cpuDisableSfx;
|
||||||
extern bool speedup;
|
extern bool cpuIsMultiBoot;
|
||||||
extern bool synchronize;
|
extern bool parseDebug;
|
||||||
extern bool cpuDisableSfx;
|
extern int layerSettings;
|
||||||
extern bool cpuIsMultiBoot;
|
extern int layerEnable;
|
||||||
extern bool parseDebug;
|
extern bool speedHack;
|
||||||
extern int layerSettings;
|
extern int cpuSaveType;
|
||||||
extern int layerEnable;
|
extern bool cpuEnhancedDetection;
|
||||||
extern bool speedHack;
|
extern bool cheatsEnabled;
|
||||||
extern int cpuSaveType;
|
|
||||||
extern bool cheatsEnabled;
|
extern u8 *bios;
|
||||||
extern bool mirroringEnable;
|
extern u8 *rom;
|
||||||
extern bool skipSaveGameBattery;
|
extern u8 *internalRAM;
|
||||||
|
extern u8 *workRAM;
|
||||||
extern u8 *bios;
|
extern u8 *paletteRAM;
|
||||||
extern u8 *rom;
|
extern u8 *vram;
|
||||||
extern u8 *internalRAM;
|
extern u8 *pix;
|
||||||
extern u8 *workRAM;
|
extern u8 *oam;
|
||||||
extern u8 *paletteRAM;
|
extern u8 *ioMem;
|
||||||
extern u8 *vram;
|
|
||||||
extern u8 *pix;
|
extern u16 DISPCNT;
|
||||||
extern u8 *oam;
|
extern u16 DISPSTAT;
|
||||||
extern u8 *ioMem;
|
extern u16 VCOUNT;
|
||||||
|
extern u16 BG0CNT;
|
||||||
extern u16 DISPCNT;
|
extern u16 BG1CNT;
|
||||||
extern u16 DISPSTAT;
|
extern u16 BG2CNT;
|
||||||
extern u16 VCOUNT;
|
extern u16 BG3CNT;
|
||||||
extern u16 BG0CNT;
|
extern u16 BG0HOFS;
|
||||||
extern u16 BG1CNT;
|
extern u16 BG0VOFS;
|
||||||
extern u16 BG2CNT;
|
extern u16 BG1HOFS;
|
||||||
extern u16 BG3CNT;
|
extern u16 BG1VOFS;
|
||||||
extern u16 BG0HOFS;
|
extern u16 BG2HOFS;
|
||||||
extern u16 BG0VOFS;
|
extern u16 BG2VOFS;
|
||||||
extern u16 BG1HOFS;
|
extern u16 BG3HOFS;
|
||||||
extern u16 BG1VOFS;
|
extern u16 BG3VOFS;
|
||||||
extern u16 BG2HOFS;
|
extern u16 BG2PA;
|
||||||
extern u16 BG2VOFS;
|
extern u16 BG2PB;
|
||||||
extern u16 BG3HOFS;
|
extern u16 BG2PC;
|
||||||
extern u16 BG3VOFS;
|
extern u16 BG2PD;
|
||||||
extern u16 BG2PA;
|
extern u16 BG2X_L;
|
||||||
extern u16 BG2PB;
|
extern u16 BG2X_H;
|
||||||
extern u16 BG2PC;
|
extern u16 BG2Y_L;
|
||||||
extern u16 BG2PD;
|
extern u16 BG2Y_H;
|
||||||
extern u16 BG2X_L;
|
extern u16 BG3PA;
|
||||||
extern u16 BG2X_H;
|
extern u16 BG3PB;
|
||||||
extern u16 BG2Y_L;
|
extern u16 BG3PC;
|
||||||
extern u16 BG2Y_H;
|
extern u16 BG3PD;
|
||||||
extern u16 BG3PA;
|
extern u16 BG3X_L;
|
||||||
extern u16 BG3PB;
|
extern u16 BG3X_H;
|
||||||
extern u16 BG3PC;
|
extern u16 BG3Y_L;
|
||||||
extern u16 BG3PD;
|
extern u16 BG3Y_H;
|
||||||
extern u16 BG3X_L;
|
extern u16 WIN0H;
|
||||||
extern u16 BG3X_H;
|
extern u16 WIN1H;
|
||||||
extern u16 BG3Y_L;
|
extern u16 WIN0V;
|
||||||
extern u16 BG3Y_H;
|
extern u16 WIN1V;
|
||||||
extern u16 WIN0H;
|
extern u16 WININ;
|
||||||
extern u16 WIN1H;
|
extern u16 WINOUT;
|
||||||
extern u16 WIN0V;
|
extern u16 MOSAIC;
|
||||||
extern u16 WIN1V;
|
extern u16 BLDMOD;
|
||||||
extern u16 WININ;
|
extern u16 COLEV;
|
||||||
extern u16 WINOUT;
|
extern u16 COLY;
|
||||||
extern u16 MOSAIC;
|
extern u16 DM0SAD_L;
|
||||||
extern u16 BLDMOD;
|
extern u16 DM0SAD_H;
|
||||||
extern u16 COLEV;
|
extern u16 DM0DAD_L;
|
||||||
extern u16 COLY;
|
extern u16 DM0DAD_H;
|
||||||
extern u16 DM0SAD_L;
|
extern u16 DM0CNT_L;
|
||||||
extern u16 DM0SAD_H;
|
extern u16 DM0CNT_H;
|
||||||
extern u16 DM0DAD_L;
|
extern u16 DM1SAD_L;
|
||||||
extern u16 DM0DAD_H;
|
extern u16 DM1SAD_H;
|
||||||
extern u16 DM0CNT_L;
|
extern u16 DM1DAD_L;
|
||||||
extern u16 DM0CNT_H;
|
extern u16 DM1DAD_H;
|
||||||
extern u16 DM1SAD_L;
|
extern u16 DM1CNT_L;
|
||||||
extern u16 DM1SAD_H;
|
extern u16 DM1CNT_H;
|
||||||
extern u16 DM1DAD_L;
|
extern u16 DM2SAD_L;
|
||||||
extern u16 DM1DAD_H;
|
extern u16 DM2SAD_H;
|
||||||
extern u16 DM1CNT_L;
|
extern u16 DM2DAD_L;
|
||||||
extern u16 DM1CNT_H;
|
extern u16 DM2DAD_H;
|
||||||
extern u16 DM2SAD_L;
|
extern u16 DM2CNT_L;
|
||||||
extern u16 DM2SAD_H;
|
extern u16 DM2CNT_H;
|
||||||
extern u16 DM2DAD_L;
|
extern u16 DM3SAD_L;
|
||||||
extern u16 DM2DAD_H;
|
extern u16 DM3SAD_H;
|
||||||
extern u16 DM2CNT_L;
|
extern u16 DM3DAD_L;
|
||||||
extern u16 DM2CNT_H;
|
extern u16 DM3DAD_H;
|
||||||
extern u16 DM3SAD_L;
|
extern u16 DM3CNT_L;
|
||||||
extern u16 DM3SAD_H;
|
extern u16 DM3CNT_H;
|
||||||
extern u16 DM3DAD_L;
|
extern u16 TM0D;
|
||||||
extern u16 DM3DAD_H;
|
extern u16 TM0CNT;
|
||||||
extern u16 DM3CNT_L;
|
extern u16 TM1D;
|
||||||
extern u16 DM3CNT_H;
|
extern u16 TM1CNT;
|
||||||
extern u16 TM0D;
|
extern u16 TM2D;
|
||||||
extern u16 TM0CNT;
|
extern u16 TM2CNT;
|
||||||
extern u16 TM1D;
|
extern u16 TM3D;
|
||||||
extern u16 TM1CNT;
|
extern u16 TM3CNT;
|
||||||
extern u16 TM2D;
|
extern u16 P1;
|
||||||
extern u16 TM2CNT;
|
extern u16 IE;
|
||||||
extern u16 TM3D;
|
extern u16 IF;
|
||||||
extern u16 TM3CNT;
|
extern u16 IME;
|
||||||
extern u16 P1;
|
|
||||||
extern u16 IE;
|
#endif // VBA_GLOBALS_H
|
||||||
extern u16 IF;
|
|
||||||
extern u16 IME;
|
|
||||||
|
|
||||||
#endif // VBA_GLOBALS_H
|
|
||||||
|
1161
source/vba/Mode0.cpp
1161
source/vba/Mode0.cpp
File diff suppressed because it is too large
Load Diff
1075
source/vba/Mode1.cpp
1075
source/vba/Mode1.cpp
File diff suppressed because it is too large
Load Diff
@ -1,446 +1,550 @@
|
|||||||
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
|
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
|
||||||
// Copyright (C) 1999-2003 Forgotten
|
// Copyright (C) 1999-2003 Forgotten
|
||||||
// Copyright (C) 2004 Forgotten and the VBA development team
|
// Copyright (C) 2004 Forgotten and the VBA development team
|
||||||
|
|
||||||
// This program is free software; you can redistribute it and/or modify
|
// This program is free software; you can redistribute it and/or modify
|
||||||
// it under the terms of the GNU General Public License as published by
|
// it under the terms of the GNU General Public License as published by
|
||||||
// the Free Software Foundation; either version 2, or(at your option)
|
// the Free Software Foundation; either version 2, or(at your option)
|
||||||
// any later version.
|
// any later version.
|
||||||
//
|
//
|
||||||
// This program is distributed in the hope that it will be useful,
|
// This program is distributed in the hope that it will be useful,
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
// GNU General Public License for more details.
|
// GNU General Public License for more details.
|
||||||
//
|
//
|
||||||
// You should have received a copy of the GNU General Public License
|
// You should have received a copy of the GNU General Public License
|
||||||
// along with this program; if not, write to the Free Software Foundation,
|
// along with this program; if not, write to the Free Software Foundation,
|
||||||
// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
#include "agb/GBA.h"
|
#include "GBA.h"
|
||||||
#include "Globals.h"
|
#include "Globals.h"
|
||||||
#include "agb/GBAGfx.h"
|
#include "Gfx.h"
|
||||||
|
|
||||||
void mode2RenderLine()
|
void mode2RenderLine()
|
||||||
{
|
{
|
||||||
u16 *palette = (u16 *)paletteRAM;
|
u16 *palette = (u16 *)paletteRAM;
|
||||||
|
|
||||||
if(DISPCNT & 0x80) {
|
if(DISPCNT & 0x80)
|
||||||
for(int x = 0; x < 240; x++) {
|
{
|
||||||
lineMix[x] = 0x7fff;
|
for(int x = 0; x < 240; x++)
|
||||||
}
|
{
|
||||||
gfxLastVCOUNT = VCOUNT;
|
lineMix[x] = 0x7fff;
|
||||||
return;
|
}
|
||||||
}
|
gfxLastVCOUNT = VCOUNT;
|
||||||
|
return;
|
||||||
if(layerEnable & 0x0400) {
|
}
|
||||||
int changed = gfxBG2Changed;
|
|
||||||
if(gfxLastVCOUNT > VCOUNT)
|
if(layerEnable & 0x0400)
|
||||||
changed = 3;
|
{
|
||||||
|
int changed = gfxBG2Changed;
|
||||||
gfxDrawRotScreen(BG2CNT, BG2X_L, BG2X_H, BG2Y_L, BG2Y_H,
|
if(gfxLastVCOUNT > VCOUNT)
|
||||||
BG2PA, BG2PB, BG2PC, BG2PD, gfxBG2X, gfxBG2Y,
|
changed = 3;
|
||||||
changed, line2);
|
|
||||||
}
|
gfxDrawRotScreen(BG2CNT, BG2X_L, BG2X_H, BG2Y_L, BG2Y_H,
|
||||||
|
BG2PA, BG2PB, BG2PC, BG2PD, gfxBG2X, gfxBG2Y,
|
||||||
if(layerEnable & 0x0800) {
|
changed, line2);
|
||||||
int changed = gfxBG3Changed;
|
}
|
||||||
if(gfxLastVCOUNT > VCOUNT)
|
|
||||||
changed = 3;
|
if(layerEnable & 0x0800)
|
||||||
|
{
|
||||||
gfxDrawRotScreen(BG3CNT, BG3X_L, BG3X_H, BG3Y_L, BG3Y_H,
|
int changed = gfxBG3Changed;
|
||||||
BG3PA, BG3PB, BG3PC, BG3PD, gfxBG3X, gfxBG3Y,
|
if(gfxLastVCOUNT > VCOUNT)
|
||||||
changed, line3);
|
changed = 3;
|
||||||
}
|
|
||||||
|
gfxDrawRotScreen(BG3CNT, BG3X_L, BG3X_H, BG3Y_L, BG3Y_H,
|
||||||
gfxDrawSprites(lineOBJ);
|
BG3PA, BG3PB, BG3PC, BG3PD, gfxBG3X, gfxBG3Y,
|
||||||
|
changed, line3);
|
||||||
u32 backdrop = (READ16LE(&palette[0]) | 0x30000000);
|
}
|
||||||
|
|
||||||
for(int x = 0; x < 240; x++) {
|
gfxDrawSprites(lineOBJ);
|
||||||
u32 color = backdrop;
|
|
||||||
u8 top = 0x20;
|
u32 backdrop = (READ16LE(&palette[0]) | 0x30000000);
|
||||||
|
|
||||||
|
for(int x = 0; x < 240; x++)
|
||||||
if((u8)(line2[x]>>24) < (u8)(color >> 24)) {
|
{
|
||||||
color = line2[x];
|
u32 color = backdrop;
|
||||||
top = 0x04;
|
u8 top = 0x20;
|
||||||
}
|
|
||||||
|
|
||||||
if((u8)(line3[x]>>24) < (u8)(color >> 24)) {
|
if((u8)(line2[x]>>24) < (u8)(color >> 24))
|
||||||
color = line3[x];
|
{
|
||||||
top = 0x08;
|
color = line2[x];
|
||||||
}
|
top = 0x04;
|
||||||
|
}
|
||||||
if((u8)(lineOBJ[x]>>24) < (u8)(color >> 24)) {
|
|
||||||
color = lineOBJ[x];
|
if((u8)(line3[x]>>24) < (u8)(color >> 24))
|
||||||
top = 0x10;
|
{
|
||||||
}
|
color = line3[x];
|
||||||
|
top = 0x08;
|
||||||
if((top & 0x10) && (color & 0x00010000)) {
|
}
|
||||||
// semi-transparent OBJ
|
|
||||||
u32 back = backdrop;
|
if((u8)(lineOBJ[x]>>24) < (u8)(color >> 24))
|
||||||
u8 top2 = 0x20;
|
{
|
||||||
|
color = lineOBJ[x];
|
||||||
if((u8)(line2[x]>>24) < (u8)(back >> 24)) {
|
top = 0x10;
|
||||||
back = line2[x];
|
}
|
||||||
top2 = 0x04;
|
|
||||||
}
|
if((top & 0x10) && (color & 0x00010000))
|
||||||
|
{
|
||||||
if((u8)(line3[x]>>24) < (u8)(back >> 24)) {
|
// semi-transparent OBJ
|
||||||
back = line3[x];
|
u32 back = backdrop;
|
||||||
top2 = 0x08;
|
u8 top2 = 0x20;
|
||||||
}
|
|
||||||
|
if((u8)(line2[x]>>24) < (u8)(back >> 24))
|
||||||
if(top2 & (BLDMOD>>8))
|
{
|
||||||
color = gfxAlphaBlend(color, back,
|
back = line2[x];
|
||||||
coeff[COLEV & 0x1F],
|
top2 = 0x04;
|
||||||
coeff[(COLEV >> 8) & 0x1F]);
|
}
|
||||||
else {
|
|
||||||
switch((BLDMOD >> 6) & 3) {
|
if((u8)(line3[x]>>24) < (u8)(back >> 24))
|
||||||
case 2:
|
{
|
||||||
if(BLDMOD & top)
|
back = line3[x];
|
||||||
color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]);
|
top2 = 0x08;
|
||||||
break;
|
}
|
||||||
case 3:
|
|
||||||
if(BLDMOD & top)
|
if(top2 & (BLDMOD>>8))
|
||||||
color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]);
|
color = gfxAlphaBlend(color, back,
|
||||||
break;
|
coeff[COLEV & 0x1F],
|
||||||
}
|
coeff[(COLEV >> 8) & 0x1F]);
|
||||||
}
|
else
|
||||||
}
|
{
|
||||||
|
switch((BLDMOD >> 6) & 3)
|
||||||
lineMix[x] = color;
|
{
|
||||||
}
|
case 2:
|
||||||
gfxBG2Changed = 0;
|
if(BLDMOD & top)
|
||||||
gfxBG3Changed = 0;
|
color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]);
|
||||||
gfxLastVCOUNT = VCOUNT;
|
break;
|
||||||
}
|
case 3:
|
||||||
|
if(BLDMOD & top)
|
||||||
void mode2RenderLineNoWindow()
|
color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]);
|
||||||
{
|
break;
|
||||||
u16 *palette = (u16 *)paletteRAM;
|
}
|
||||||
|
}
|
||||||
if(DISPCNT & 0x80) {
|
}
|
||||||
for(int x = 0; x < 240; x++) {
|
|
||||||
lineMix[x] = 0x7fff;
|
lineMix[x] = color;
|
||||||
}
|
}
|
||||||
gfxLastVCOUNT = VCOUNT;
|
gfxBG2Changed = 0;
|
||||||
return;
|
gfxBG3Changed = 0;
|
||||||
}
|
gfxLastVCOUNT = VCOUNT;
|
||||||
|
}
|
||||||
if(layerEnable & 0x0400) {
|
|
||||||
int changed = gfxBG2Changed;
|
void mode2RenderLineNoWindow()
|
||||||
if(gfxLastVCOUNT > VCOUNT)
|
{
|
||||||
changed = 3;
|
u16 *palette = (u16 *)paletteRAM;
|
||||||
|
|
||||||
gfxDrawRotScreen(BG2CNT, BG2X_L, BG2X_H, BG2Y_L, BG2Y_H,
|
if(DISPCNT & 0x80)
|
||||||
BG2PA, BG2PB, BG2PC, BG2PD, gfxBG2X, gfxBG2Y,
|
{
|
||||||
changed, line2);
|
for(int x = 0; x < 240; x++)
|
||||||
}
|
{
|
||||||
|
lineMix[x] = 0x7fff;
|
||||||
if(layerEnable & 0x0800) {
|
}
|
||||||
int changed = gfxBG3Changed;
|
gfxLastVCOUNT = VCOUNT;
|
||||||
if(gfxLastVCOUNT > VCOUNT)
|
return;
|
||||||
changed = 3;
|
}
|
||||||
|
|
||||||
gfxDrawRotScreen(BG3CNT, BG3X_L, BG3X_H, BG3Y_L, BG3Y_H,
|
if(layerEnable & 0x0400)
|
||||||
BG3PA, BG3PB, BG3PC, BG3PD, gfxBG3X, gfxBG3Y,
|
{
|
||||||
changed, line3);
|
int changed = gfxBG2Changed;
|
||||||
}
|
if(gfxLastVCOUNT > VCOUNT)
|
||||||
|
changed = 3;
|
||||||
gfxDrawSprites(lineOBJ);
|
|
||||||
|
gfxDrawRotScreen(BG2CNT, BG2X_L, BG2X_H, BG2Y_L, BG2Y_H,
|
||||||
u32 backdrop = (READ16LE(&palette[0]) | 0x30000000);
|
BG2PA, BG2PB, BG2PC, BG2PD, gfxBG2X, gfxBG2Y,
|
||||||
|
changed, line2);
|
||||||
for(int x = 0; x < 240; x++) {
|
}
|
||||||
u32 color = backdrop;
|
|
||||||
u8 top = 0x20;
|
if(layerEnable & 0x0800)
|
||||||
|
{
|
||||||
|
int changed = gfxBG3Changed;
|
||||||
if((u8)(line2[x]>>24) < (u8)(color >> 24)) {
|
if(gfxLastVCOUNT > VCOUNT)
|
||||||
color = line2[x];
|
changed = 3;
|
||||||
top = 0x04;
|
|
||||||
}
|
gfxDrawRotScreen(BG3CNT, BG3X_L, BG3X_H, BG3Y_L, BG3Y_H,
|
||||||
|
BG3PA, BG3PB, BG3PC, BG3PD, gfxBG3X, gfxBG3Y,
|
||||||
if((u8)(line3[x]>>24) < (u8)(color >> 24)) {
|
changed, line3);
|
||||||
color = line3[x];
|
}
|
||||||
top = 0x08;
|
|
||||||
}
|
gfxDrawSprites(lineOBJ);
|
||||||
|
|
||||||
if((u8)(lineOBJ[x]>>24) < (u8)(color >> 24)) {
|
u32 backdrop = (READ16LE(&palette[0]) | 0x30000000);
|
||||||
color = lineOBJ[x];
|
|
||||||
top = 0x10;
|
for(int x = 0; x < 240; x++)
|
||||||
}
|
{
|
||||||
|
u32 color = backdrop;
|
||||||
if(!(color & 0x00010000)) {
|
u8 top = 0x20;
|
||||||
switch((BLDMOD >> 6) & 3) {
|
|
||||||
case 0:
|
|
||||||
break;
|
if((u8)(line2[x]>>24) < (u8)(color >> 24))
|
||||||
case 1:
|
{
|
||||||
{
|
color = line2[x];
|
||||||
if(top & BLDMOD) {
|
top = 0x04;
|
||||||
u32 back = backdrop;
|
}
|
||||||
u8 top2 = 0x20;
|
|
||||||
|
if((u8)(line3[x]>>24) < (u8)(color >> 24))
|
||||||
if((u8)(line2[x]>>24) < (u8)(back >> 24)) {
|
{
|
||||||
if(top != 0x04) {
|
color = line3[x];
|
||||||
back = line2[x];
|
top = 0x08;
|
||||||
top2 = 0x04;
|
}
|
||||||
}
|
|
||||||
}
|
if((u8)(lineOBJ[x]>>24) < (u8)(color >> 24))
|
||||||
|
{
|
||||||
if((u8)(line3[x]>>24) < (u8)(back >> 24)) {
|
color = lineOBJ[x];
|
||||||
if(top != 0x08) {
|
top = 0x10;
|
||||||
back = line3[x];
|
}
|
||||||
top2 = 0x08;
|
|
||||||
}
|
if(!(color & 0x00010000))
|
||||||
}
|
{
|
||||||
|
switch((BLDMOD >> 6) & 3)
|
||||||
if((u8)(lineOBJ[x]>>24) < (u8)(back >> 24)) {
|
{
|
||||||
if(top != 0x10) {
|
case 0:
|
||||||
back = lineOBJ[x];
|
break;
|
||||||
top2 = 0x10;
|
case 1:
|
||||||
}
|
{
|
||||||
}
|
if(top & BLDMOD)
|
||||||
|
{
|
||||||
if(top2 & (BLDMOD>>8))
|
u32 back = backdrop;
|
||||||
color = gfxAlphaBlend(color, back,
|
u8 top2 = 0x20;
|
||||||
coeff[COLEV & 0x1F],
|
|
||||||
coeff[(COLEV >> 8) & 0x1F]);
|
if((u8)(line2[x]>>24) < (u8)(back >> 24))
|
||||||
}
|
{
|
||||||
}
|
if(top != 0x04)
|
||||||
break;
|
{
|
||||||
case 2:
|
back = line2[x];
|
||||||
if(BLDMOD & top)
|
top2 = 0x04;
|
||||||
color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]);
|
}
|
||||||
break;
|
}
|
||||||
case 3:
|
|
||||||
if(BLDMOD & top)
|
if((u8)(line3[x]>>24) < (u8)(back >> 24))
|
||||||
color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]);
|
{
|
||||||
break;
|
if(top != 0x08)
|
||||||
}
|
{
|
||||||
} else {
|
back = line3[x];
|
||||||
// semi-transparent OBJ
|
top2 = 0x08;
|
||||||
u32 back = backdrop;
|
}
|
||||||
u8 top2 = 0x20;
|
}
|
||||||
|
|
||||||
if((u8)(line2[x]>>24) < (u8)(back >> 24)) {
|
if((u8)(lineOBJ[x]>>24) < (u8)(back >> 24))
|
||||||
back = line2[x];
|
{
|
||||||
top2 = 0x04;
|
if(top != 0x10)
|
||||||
}
|
{
|
||||||
|
back = lineOBJ[x];
|
||||||
if((u8)(line3[x]>>24) < (u8)(back >> 24)) {
|
top2 = 0x10;
|
||||||
back = line3[x];
|
}
|
||||||
top2 = 0x08;
|
}
|
||||||
}
|
|
||||||
|
if(top2 & (BLDMOD>>8))
|
||||||
if(top2 & (BLDMOD>>8))
|
color = gfxAlphaBlend(color, back,
|
||||||
color = gfxAlphaBlend(color, back,
|
coeff[COLEV & 0x1F],
|
||||||
coeff[COLEV & 0x1F],
|
coeff[(COLEV >> 8) & 0x1F]);
|
||||||
coeff[(COLEV >> 8) & 0x1F]);
|
}
|
||||||
else {
|
}
|
||||||
switch((BLDMOD >> 6) & 3) {
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
if(BLDMOD & top)
|
if(BLDMOD & top)
|
||||||
color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]);
|
color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]);
|
||||||
break;
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
if(BLDMOD & top)
|
if(BLDMOD & top)
|
||||||
color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]);
|
color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
else
|
||||||
|
{
|
||||||
lineMix[x] = color;
|
// semi-transparent OBJ
|
||||||
}
|
u32 back = backdrop;
|
||||||
gfxBG2Changed = 0;
|
u8 top2 = 0x20;
|
||||||
gfxBG3Changed = 0;
|
|
||||||
gfxLastVCOUNT = VCOUNT;
|
if((u8)(line2[x]>>24) < (u8)(back >> 24))
|
||||||
}
|
{
|
||||||
|
back = line2[x];
|
||||||
void mode2RenderLineAll()
|
top2 = 0x04;
|
||||||
{
|
}
|
||||||
u16 *palette = (u16 *)paletteRAM;
|
|
||||||
|
if((u8)(line3[x]>>24) < (u8)(back >> 24))
|
||||||
if(DISPCNT & 0x80) {
|
{
|
||||||
for(int x = 0; x < 240; x++) {
|
back = line3[x];
|
||||||
lineMix[x] = 0x7fff;
|
top2 = 0x08;
|
||||||
}
|
}
|
||||||
gfxLastVCOUNT = VCOUNT;
|
|
||||||
return;
|
if(top2 & (BLDMOD>>8))
|
||||||
}
|
color = gfxAlphaBlend(color, back,
|
||||||
|
coeff[COLEV & 0x1F],
|
||||||
bool inWindow0 = false;
|
coeff[(COLEV >> 8) & 0x1F]);
|
||||||
bool inWindow1 = false;
|
else
|
||||||
|
{
|
||||||
if(layerEnable & 0x2000) {
|
switch((BLDMOD >> 6) & 3)
|
||||||
u8 v0 = WIN0V >> 8;
|
{
|
||||||
u8 v1 = WIN0V & 255;
|
case 2:
|
||||||
inWindow0 = ((v0 == v1) && (v0 >= 0xe8));
|
if(BLDMOD & top)
|
||||||
if(v1 >= v0)
|
color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]);
|
||||||
inWindow0 |= (VCOUNT >= v0 && VCOUNT < v1);
|
break;
|
||||||
else
|
case 3:
|
||||||
inWindow0 |= (VCOUNT >= v0 || VCOUNT < v1);
|
if(BLDMOD & top)
|
||||||
}
|
color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]);
|
||||||
if(layerEnable & 0x4000) {
|
break;
|
||||||
u8 v0 = WIN1V >> 8;
|
}
|
||||||
u8 v1 = WIN1V & 255;
|
}
|
||||||
inWindow1 = ((v0 == v1) && (v0 >= 0xe8));
|
}
|
||||||
if(v1 >= v0)
|
|
||||||
inWindow1 |= (VCOUNT >= v0 && VCOUNT < v1);
|
lineMix[x] = color;
|
||||||
else
|
}
|
||||||
inWindow1 |= (VCOUNT >= v0 || VCOUNT < v1);
|
gfxBG2Changed = 0;
|
||||||
}
|
gfxBG3Changed = 0;
|
||||||
|
gfxLastVCOUNT = VCOUNT;
|
||||||
if(layerEnable & 0x0400) {
|
}
|
||||||
int changed = gfxBG2Changed;
|
|
||||||
if(gfxLastVCOUNT > VCOUNT)
|
void mode2RenderLineAll()
|
||||||
changed = 3;
|
{
|
||||||
|
u16 *palette = (u16 *)paletteRAM;
|
||||||
gfxDrawRotScreen(BG2CNT, BG2X_L, BG2X_H, BG2Y_L, BG2Y_H,
|
|
||||||
BG2PA, BG2PB, BG2PC, BG2PD, gfxBG2X, gfxBG2Y,
|
if(DISPCNT & 0x80)
|
||||||
changed, line2);
|
{
|
||||||
}
|
for(int x = 0; x < 240; x++)
|
||||||
|
{
|
||||||
if(layerEnable & 0x0800) {
|
lineMix[x] = 0x7fff;
|
||||||
int changed = gfxBG3Changed;
|
}
|
||||||
if(gfxLastVCOUNT > VCOUNT)
|
gfxLastVCOUNT = VCOUNT;
|
||||||
changed = 3;
|
return;
|
||||||
|
}
|
||||||
gfxDrawRotScreen(BG3CNT, BG3X_L, BG3X_H, BG3Y_L, BG3Y_H,
|
|
||||||
BG3PA, BG3PB, BG3PC, BG3PD, gfxBG3X, gfxBG3Y,
|
bool inWindow0 = false;
|
||||||
changed, line3);
|
bool inWindow1 = false;
|
||||||
}
|
|
||||||
|
if(layerEnable & 0x2000)
|
||||||
gfxDrawSprites(lineOBJ);
|
{
|
||||||
gfxDrawOBJWin(lineOBJWin);
|
u8 v0 = WIN0V >> 8;
|
||||||
|
u8 v1 = WIN0V & 255;
|
||||||
u32 backdrop = (READ16LE(&palette[0]) | 0x30000000);
|
inWindow0 = ((v0 == v1) && (v0 >= 0xe8));
|
||||||
|
if(v1 >= v0)
|
||||||
u8 inWin0Mask = WININ & 0xFF;
|
inWindow0 |= (VCOUNT >= v0 && VCOUNT < v1);
|
||||||
u8 inWin1Mask = WININ >> 8;
|
else
|
||||||
u8 outMask = WINOUT & 0xFF;
|
inWindow0 |= (VCOUNT >= v0 || VCOUNT < v1);
|
||||||
|
}
|
||||||
for(int x = 0; x < 240; x++) {
|
if(layerEnable & 0x4000)
|
||||||
u32 color = backdrop;
|
{
|
||||||
u8 top = 0x20;
|
u8 v0 = WIN1V >> 8;
|
||||||
u8 mask = outMask;
|
u8 v1 = WIN1V & 255;
|
||||||
|
inWindow1 = ((v0 == v1) && (v0 >= 0xe8));
|
||||||
if(!(lineOBJWin[x] & 0x80000000)) {
|
if(v1 >= v0)
|
||||||
mask = WINOUT >> 8;
|
inWindow1 |= (VCOUNT >= v0 && VCOUNT < v1);
|
||||||
}
|
else
|
||||||
|
inWindow1 |= (VCOUNT >= v0 || VCOUNT < v1);
|
||||||
if(inWindow1) {
|
}
|
||||||
if(gfxInWin1[x])
|
|
||||||
mask = inWin1Mask;
|
if(layerEnable & 0x0400)
|
||||||
}
|
{
|
||||||
|
int changed = gfxBG2Changed;
|
||||||
if(inWindow0) {
|
if(gfxLastVCOUNT > VCOUNT)
|
||||||
if(gfxInWin0[x]) {
|
changed = 3;
|
||||||
mask = inWin0Mask;
|
|
||||||
}
|
gfxDrawRotScreen(BG2CNT, BG2X_L, BG2X_H, BG2Y_L, BG2Y_H,
|
||||||
}
|
BG2PA, BG2PB, BG2PC, BG2PD, gfxBG2X, gfxBG2Y,
|
||||||
|
changed, line2);
|
||||||
if(line2[x] < color && (mask & 4)) {
|
}
|
||||||
color = line2[x];
|
|
||||||
top = 0x04;
|
if(layerEnable & 0x0800)
|
||||||
}
|
{
|
||||||
|
int changed = gfxBG3Changed;
|
||||||
if((u8)(line3[x]>>24) < (u8)(color >> 24) && (mask & 8)) {
|
if(gfxLastVCOUNT > VCOUNT)
|
||||||
color = line3[x];
|
changed = 3;
|
||||||
top = 0x08;
|
|
||||||
}
|
gfxDrawRotScreen(BG3CNT, BG3X_L, BG3X_H, BG3Y_L, BG3Y_H,
|
||||||
|
BG3PA, BG3PB, BG3PC, BG3PD, gfxBG3X, gfxBG3Y,
|
||||||
if((u8)(lineOBJ[x]>>24) < (u8)(color >> 24) && (mask & 16)) {
|
changed, line3);
|
||||||
color = lineOBJ[x];
|
}
|
||||||
top = 0x10;
|
|
||||||
}
|
gfxDrawSprites(lineOBJ);
|
||||||
|
gfxDrawOBJWin(lineOBJWin);
|
||||||
if(color & 0x00010000) {
|
|
||||||
// semi-transparent OBJ
|
u32 backdrop = (READ16LE(&palette[0]) | 0x30000000);
|
||||||
u32 back = backdrop;
|
|
||||||
u8 top2 = 0x20;
|
u8 inWin0Mask = WININ & 0xFF;
|
||||||
|
u8 inWin1Mask = WININ >> 8;
|
||||||
if((mask & 4) && line2[x] < back) {
|
u8 outMask = WINOUT & 0xFF;
|
||||||
back = line2[x];
|
|
||||||
top2 = 0x04;
|
for(int x = 0; x < 240; x++)
|
||||||
}
|
{
|
||||||
|
u32 color = backdrop;
|
||||||
if((mask & 8) && (u8)(line3[x]>>24) < (u8)(back >> 24)) {
|
u8 top = 0x20;
|
||||||
back = line3[x];
|
u8 mask = outMask;
|
||||||
top2 = 0x08;
|
|
||||||
}
|
if(!(lineOBJWin[x] & 0x80000000))
|
||||||
|
{
|
||||||
if(top2 & (BLDMOD>>8))
|
mask = WINOUT >> 8;
|
||||||
color = gfxAlphaBlend(color, back,
|
}
|
||||||
coeff[COLEV & 0x1F],
|
|
||||||
coeff[(COLEV >> 8) & 0x1F]);
|
if(inWindow1)
|
||||||
else {
|
{
|
||||||
switch((BLDMOD >> 6) & 3) {
|
if(gfxInWin1[x])
|
||||||
case 2:
|
mask = inWin1Mask;
|
||||||
if(BLDMOD & top)
|
}
|
||||||
color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]);
|
|
||||||
break;
|
if(inWindow0)
|
||||||
case 3:
|
{
|
||||||
if(BLDMOD & top)
|
if(gfxInWin0[x])
|
||||||
color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]);
|
{
|
||||||
break;
|
mask = inWin0Mask;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if(mask & 32) {
|
|
||||||
// special FX on the window
|
if(line2[x] < color && (mask & 4))
|
||||||
switch((BLDMOD >> 6) & 3) {
|
{
|
||||||
case 0:
|
color = line2[x];
|
||||||
break;
|
top = 0x04;
|
||||||
case 1:
|
}
|
||||||
{
|
|
||||||
if(top & BLDMOD) {
|
if((u8)(line3[x]>>24) < (u8)(color >> 24) && (mask & 8))
|
||||||
u32 back = backdrop;
|
{
|
||||||
u8 top2 = 0x20;
|
color = line3[x];
|
||||||
|
top = 0x08;
|
||||||
if((mask & 4) && line2[x] < back) {
|
}
|
||||||
if(top != 0x04) {
|
|
||||||
back = line2[x];
|
if((u8)(lineOBJ[x]>>24) < (u8)(color >> 24) && (mask & 16))
|
||||||
top2 = 0x04;
|
{
|
||||||
}
|
color = lineOBJ[x];
|
||||||
}
|
top = 0x10;
|
||||||
|
}
|
||||||
if((mask & 8) && (u8)(line3[x]>>24) < (u8)(back >> 24)) {
|
|
||||||
if(top != 0x08) {
|
if(mask & 32)
|
||||||
back = line3[x];
|
{
|
||||||
top2 = 0x08;
|
if(!(color & 0x00010000))
|
||||||
}
|
{
|
||||||
}
|
switch((BLDMOD >> 6) & 3)
|
||||||
|
{
|
||||||
if((mask & 16) && (u8)(lineOBJ[x]>>24) < (u8)(back >> 24)) {
|
case 0:
|
||||||
if(top != 0x10) {
|
break;
|
||||||
back = lineOBJ[x];
|
case 1:
|
||||||
top2 = 0x10;
|
{
|
||||||
}
|
if(top & BLDMOD)
|
||||||
}
|
{
|
||||||
|
u32 back = backdrop;
|
||||||
if(top2 & (BLDMOD>>8))
|
u8 top2 = 0x20;
|
||||||
color = gfxAlphaBlend(color, back,
|
|
||||||
coeff[COLEV & 0x1F],
|
if((mask & 4) && line2[x] < back)
|
||||||
coeff[(COLEV >> 8) & 0x1F]);
|
{
|
||||||
}
|
if(top != 0x04)
|
||||||
}
|
{
|
||||||
break;
|
back = line2[x];
|
||||||
case 2:
|
top2 = 0x04;
|
||||||
if(BLDMOD & top)
|
}
|
||||||
color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]);
|
}
|
||||||
break;
|
|
||||||
case 3:
|
if((mask & 8) && (u8)(line3[x]>>24) < (u8)(back >> 24))
|
||||||
if(BLDMOD & top)
|
{
|
||||||
color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]);
|
if(top != 0x08)
|
||||||
break;
|
{
|
||||||
}
|
back = line3[x];
|
||||||
}
|
top2 = 0x08;
|
||||||
|
}
|
||||||
lineMix[x] = color;
|
}
|
||||||
}
|
|
||||||
gfxBG2Changed = 0;
|
if((mask & 16) && (u8)(lineOBJ[x]>>24) < (u8)(back >> 24))
|
||||||
gfxBG3Changed = 0;
|
{
|
||||||
gfxLastVCOUNT = VCOUNT;
|
if(top != 0x10)
|
||||||
}
|
{
|
||||||
|
back = lineOBJ[x];
|
||||||
|
top2 = 0x10;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(top2 & (BLDMOD>>8))
|
||||||
|
color = gfxAlphaBlend(color, back,
|
||||||
|
coeff[COLEV & 0x1F],
|
||||||
|
coeff[(COLEV >> 8) & 0x1F]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
if(BLDMOD & top)
|
||||||
|
color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]);
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
if(BLDMOD & top)
|
||||||
|
color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// semi-transparent OBJ
|
||||||
|
u32 back = backdrop;
|
||||||
|
u8 top2 = 0x20;
|
||||||
|
|
||||||
|
if((mask & 4) && line2[x] < back)
|
||||||
|
{
|
||||||
|
back = line2[x];
|
||||||
|
top2 = 0x04;
|
||||||
|
}
|
||||||
|
|
||||||
|
if((mask & 8) && (u8)(line3[x]>>24) < (u8)(back >> 24))
|
||||||
|
{
|
||||||
|
back = line3[x];
|
||||||
|
top2 = 0x08;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(top2 & (BLDMOD>>8))
|
||||||
|
color = gfxAlphaBlend(color, back,
|
||||||
|
coeff[COLEV & 0x1F],
|
||||||
|
coeff[(COLEV >> 8) & 0x1F]);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
switch((BLDMOD >> 6) & 3)
|
||||||
|
{
|
||||||
|
case 2:
|
||||||
|
if(BLDMOD & top)
|
||||||
|
color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]);
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
if(BLDMOD & top)
|
||||||
|
color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(color & 0x00010000)
|
||||||
|
{
|
||||||
|
// semi-transparent OBJ
|
||||||
|
u32 back = backdrop;
|
||||||
|
u8 top2 = 0x20;
|
||||||
|
|
||||||
|
if((mask & 4) && line2[x] < back)
|
||||||
|
{
|
||||||
|
back = line2[x];
|
||||||
|
top2 = 0x04;
|
||||||
|
}
|
||||||
|
|
||||||
|
if((mask & 8) && (u8)(line3[x]>>24) < (u8)(back >> 24))
|
||||||
|
{
|
||||||
|
back = line3[x];
|
||||||
|
top2 = 0x08;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(top2 & (BLDMOD>>8))
|
||||||
|
color = gfxAlphaBlend(color, back,
|
||||||
|
coeff[COLEV & 0x1F],
|
||||||
|
coeff[(COLEV >> 8) & 0x1F]);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
switch((BLDMOD >> 6) & 3)
|
||||||
|
{
|
||||||
|
case 2:
|
||||||
|
if(BLDMOD & top)
|
||||||
|
color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]);
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
if(BLDMOD & top)
|
||||||
|
color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
lineMix[x] = color;
|
||||||
|
}
|
||||||
|
gfxBG2Changed = 0;
|
||||||
|
gfxBG3Changed = 0;
|
||||||
|
gfxLastVCOUNT = VCOUNT;
|
||||||
|
}
|
||||||
|
@ -1,377 +1,463 @@
|
|||||||
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
|
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
|
||||||
// Copyright (C) 1999-2003 Forgotten
|
// Copyright (C) 1999-2003 Forgotten
|
||||||
// Copyright (C) 2004 Forgotten and the VBA development team
|
// Copyright (C) 2004 Forgotten and the VBA development team
|
||||||
|
|
||||||
// This program is free software; you can redistribute it and/or modify
|
// This program is free software; you can redistribute it and/or modify
|
||||||
// it under the terms of the GNU General Public License as published by
|
// it under the terms of the GNU General Public License as published by
|
||||||
// the Free Software Foundation; either version 2, or(at your option)
|
// the Free Software Foundation; either version 2, or(at your option)
|
||||||
// any later version.
|
// any later version.
|
||||||
//
|
//
|
||||||
// This program is distributed in the hope that it will be useful,
|
// This program is distributed in the hope that it will be useful,
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
// GNU General Public License for more details.
|
// GNU General Public License for more details.
|
||||||
//
|
//
|
||||||
// You should have received a copy of the GNU General Public License
|
// You should have received a copy of the GNU General Public License
|
||||||
// along with this program; if not, write to the Free Software Foundation,
|
// along with this program; if not, write to the Free Software Foundation,
|
||||||
// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
#include "agb/GBA.h"
|
#include "GBA.h"
|
||||||
#include "Globals.h"
|
#include "Globals.h"
|
||||||
#include "agb/GBAGfx.h"
|
#include "Gfx.h"
|
||||||
|
|
||||||
void mode3RenderLine()
|
void mode3RenderLine()
|
||||||
{
|
{
|
||||||
u16 *palette = (u16 *)paletteRAM;
|
u16 *palette = (u16 *)paletteRAM;
|
||||||
|
|
||||||
if(DISPCNT & 0x80) {
|
if(DISPCNT & 0x80)
|
||||||
for(int x = 0; x < 240; x++) {
|
{
|
||||||
lineMix[x] = 0x7fff;
|
for(int x = 0; x < 240; x++)
|
||||||
}
|
{
|
||||||
gfxLastVCOUNT = VCOUNT;
|
lineMix[x] = 0x7fff;
|
||||||
return;
|
}
|
||||||
}
|
gfxLastVCOUNT = VCOUNT;
|
||||||
|
return;
|
||||||
if(layerEnable & 0x0400) {
|
}
|
||||||
int changed = gfxBG2Changed;
|
|
||||||
|
if(layerEnable & 0x0400)
|
||||||
if(gfxLastVCOUNT > VCOUNT)
|
{
|
||||||
changed = 3;
|
int changed = gfxBG2Changed;
|
||||||
|
|
||||||
gfxDrawRotScreen16Bit(BG2CNT, BG2X_L, BG2X_H,
|
if(gfxLastVCOUNT > VCOUNT)
|
||||||
BG2Y_L, BG2Y_H, BG2PA, BG2PB,
|
changed = 3;
|
||||||
BG2PC, BG2PD,
|
|
||||||
gfxBG2X, gfxBG2Y, changed,
|
gfxDrawRotScreen16Bit(BG2CNT, BG2X_L, BG2X_H,
|
||||||
line2);
|
BG2Y_L, BG2Y_H, BG2PA, BG2PB,
|
||||||
}
|
BG2PC, BG2PD,
|
||||||
|
gfxBG2X, gfxBG2Y, changed,
|
||||||
gfxDrawSprites(lineOBJ);
|
line2);
|
||||||
|
}
|
||||||
u32 background = (READ16LE(&palette[0]) | 0x30000000);
|
|
||||||
|
gfxDrawSprites(lineOBJ);
|
||||||
for(int x = 0; x < 240; x++) {
|
|
||||||
u32 color = background;
|
u32 background = (READ16LE(&palette[0]) | 0x30000000);
|
||||||
u8 top = 0x20;
|
|
||||||
|
for(int x = 0; x < 240; x++)
|
||||||
if(line2[x] < color) {
|
{
|
||||||
color = line2[x];
|
u32 color = background;
|
||||||
top = 0x04;
|
u8 top = 0x20;
|
||||||
}
|
|
||||||
|
if(line2[x] < color)
|
||||||
if((u8)(lineOBJ[x]>>24) < (u8)(color >>24)) {
|
{
|
||||||
color = lineOBJ[x];
|
color = line2[x];
|
||||||
top = 0x10;
|
top = 0x04;
|
||||||
}
|
}
|
||||||
|
|
||||||
if((top & 0x10) && (color & 0x00010000)) {
|
if((u8)(lineOBJ[x]>>24) < (u8)(color >>24))
|
||||||
// semi-transparent OBJ
|
{
|
||||||
u32 back = background;
|
color = lineOBJ[x];
|
||||||
u8 top2 = 0x20;
|
top = 0x10;
|
||||||
|
}
|
||||||
if(line2[x] < back) {
|
|
||||||
back = line2[x];
|
if((top & 0x10) && (color & 0x00010000))
|
||||||
top2 = 0x04;
|
{
|
||||||
}
|
// semi-transparent OBJ
|
||||||
|
u32 back = background;
|
||||||
if(top2 & (BLDMOD>>8))
|
u8 top2 = 0x20;
|
||||||
color = gfxAlphaBlend(color, back,
|
|
||||||
coeff[COLEV & 0x1F],
|
if(line2[x] < back)
|
||||||
coeff[(COLEV >> 8) & 0x1F]);
|
{
|
||||||
else {
|
back = line2[x];
|
||||||
switch((BLDMOD >> 6) & 3) {
|
top2 = 0x04;
|
||||||
case 2:
|
}
|
||||||
if(BLDMOD & top)
|
|
||||||
color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]);
|
if(top2 & (BLDMOD>>8))
|
||||||
break;
|
color = gfxAlphaBlend(color, back,
|
||||||
case 3:
|
coeff[COLEV & 0x1F],
|
||||||
if(BLDMOD & top)
|
coeff[(COLEV >> 8) & 0x1F]);
|
||||||
color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]);
|
else
|
||||||
break;
|
{
|
||||||
}
|
switch((BLDMOD >> 6) & 3)
|
||||||
}
|
{
|
||||||
}
|
case 2:
|
||||||
|
if(BLDMOD & top)
|
||||||
lineMix[x] = color;
|
color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]);
|
||||||
}
|
break;
|
||||||
gfxBG2Changed = 0;
|
case 3:
|
||||||
gfxLastVCOUNT = VCOUNT;
|
if(BLDMOD & top)
|
||||||
}
|
color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]);
|
||||||
|
break;
|
||||||
void mode3RenderLineNoWindow()
|
}
|
||||||
{
|
}
|
||||||
u16 *palette = (u16 *)paletteRAM;
|
}
|
||||||
|
|
||||||
if(DISPCNT & 0x80) {
|
lineMix[x] = color;
|
||||||
for(int x = 0; x < 240; x++) {
|
}
|
||||||
lineMix[x] = 0x7fff;
|
gfxBG2Changed = 0;
|
||||||
}
|
gfxLastVCOUNT = VCOUNT;
|
||||||
gfxLastVCOUNT = VCOUNT;
|
}
|
||||||
return;
|
|
||||||
}
|
void mode3RenderLineNoWindow()
|
||||||
|
{
|
||||||
if(layerEnable & 0x0400) {
|
u16 *palette = (u16 *)paletteRAM;
|
||||||
int changed = gfxBG2Changed;
|
|
||||||
|
if(DISPCNT & 0x80)
|
||||||
if(gfxLastVCOUNT > VCOUNT)
|
{
|
||||||
changed = 3;
|
for(int x = 0; x < 240; x++)
|
||||||
|
{
|
||||||
gfxDrawRotScreen16Bit(BG2CNT, BG2X_L, BG2X_H,
|
lineMix[x] = 0x7fff;
|
||||||
BG2Y_L, BG2Y_H, BG2PA, BG2PB,
|
}
|
||||||
BG2PC, BG2PD,
|
gfxLastVCOUNT = VCOUNT;
|
||||||
gfxBG2X, gfxBG2Y, changed,
|
return;
|
||||||
line2);
|
}
|
||||||
}
|
|
||||||
|
if(layerEnable & 0x0400)
|
||||||
gfxDrawSprites(lineOBJ);
|
{
|
||||||
|
int changed = gfxBG2Changed;
|
||||||
u32 background = (READ16LE(&palette[0]) | 0x30000000);
|
|
||||||
|
if(gfxLastVCOUNT > VCOUNT)
|
||||||
for(int x = 0; x < 240; x++) {
|
changed = 3;
|
||||||
u32 color = background;
|
|
||||||
u8 top = 0x20;
|
gfxDrawRotScreen16Bit(BG2CNT, BG2X_L, BG2X_H,
|
||||||
|
BG2Y_L, BG2Y_H, BG2PA, BG2PB,
|
||||||
if(line2[x] < color) {
|
BG2PC, BG2PD,
|
||||||
color = line2[x];
|
gfxBG2X, gfxBG2Y, changed,
|
||||||
top = 0x04;
|
line2);
|
||||||
}
|
}
|
||||||
|
|
||||||
if((u8)(lineOBJ[x]>>24) < (u8)(color >>24)) {
|
gfxDrawSprites(lineOBJ);
|
||||||
color = lineOBJ[x];
|
|
||||||
top = 0x10;
|
u32 background = (READ16LE(&palette[0]) | 0x30000000);
|
||||||
}
|
|
||||||
|
for(int x = 0; x < 240; x++)
|
||||||
if(!(color & 0x00010000)) {
|
{
|
||||||
switch((BLDMOD >> 6) & 3) {
|
u32 color = background;
|
||||||
case 0:
|
u8 top = 0x20;
|
||||||
break;
|
|
||||||
case 1:
|
if(line2[x] < color)
|
||||||
{
|
{
|
||||||
if(top & BLDMOD) {
|
color = line2[x];
|
||||||
u32 back = background;
|
top = 0x04;
|
||||||
u8 top2 = 0x20;
|
}
|
||||||
|
|
||||||
if(line2[x] < back) {
|
if((u8)(lineOBJ[x]>>24) < (u8)(color >>24))
|
||||||
if(top != 0x04) {
|
{
|
||||||
back = line2[x];
|
color = lineOBJ[x];
|
||||||
top2 = 0x04;
|
top = 0x10;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
if(!(color & 0x00010000))
|
||||||
if((u8)(lineOBJ[x]>>24) < (u8)(back >> 24)) {
|
{
|
||||||
if(top != 0x10) {
|
switch((BLDMOD >> 6) & 3)
|
||||||
back = lineOBJ[x];
|
{
|
||||||
top2 = 0x10;
|
case 0:
|
||||||
}
|
break;
|
||||||
}
|
case 1:
|
||||||
|
{
|
||||||
if(top2 & (BLDMOD>>8))
|
if(top & BLDMOD)
|
||||||
color = gfxAlphaBlend(color, back,
|
{
|
||||||
coeff[COLEV & 0x1F],
|
u32 back = background;
|
||||||
coeff[(COLEV >> 8) & 0x1F]);
|
u8 top2 = 0x20;
|
||||||
|
|
||||||
}
|
if(line2[x] < back)
|
||||||
}
|
{
|
||||||
break;
|
if(top != 0x04)
|
||||||
case 2:
|
{
|
||||||
if(BLDMOD & top)
|
back = line2[x];
|
||||||
color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]);
|
top2 = 0x04;
|
||||||
break;
|
}
|
||||||
case 3:
|
}
|
||||||
if(BLDMOD & top)
|
|
||||||
color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]);
|
if((u8)(lineOBJ[x]>>24) < (u8)(back >> 24))
|
||||||
break;
|
{
|
||||||
}
|
if(top != 0x10)
|
||||||
} else {
|
{
|
||||||
// semi-transparent OBJ
|
back = lineOBJ[x];
|
||||||
u32 back = background;
|
top2 = 0x10;
|
||||||
u8 top2 = 0x20;
|
}
|
||||||
|
}
|
||||||
if(line2[x] < back) {
|
|
||||||
back = line2[x];
|
if(top2 & (BLDMOD>>8))
|
||||||
top2 = 0x04;
|
color = gfxAlphaBlend(color, back,
|
||||||
}
|
coeff[COLEV & 0x1F],
|
||||||
|
coeff[(COLEV >> 8) & 0x1F]);
|
||||||
if(top2 & (BLDMOD>>8))
|
|
||||||
color = gfxAlphaBlend(color, back,
|
}
|
||||||
coeff[COLEV & 0x1F],
|
}
|
||||||
coeff[(COLEV >> 8) & 0x1F]);
|
break;
|
||||||
else {
|
case 2:
|
||||||
switch((BLDMOD >> 6) & 3) {
|
if(BLDMOD & top)
|
||||||
case 2:
|
color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]);
|
||||||
if(BLDMOD & top)
|
break;
|
||||||
color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]);
|
case 3:
|
||||||
break;
|
if(BLDMOD & top)
|
||||||
case 3:
|
color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]);
|
||||||
if(BLDMOD & top)
|
break;
|
||||||
color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]);
|
}
|
||||||
break;
|
}
|
||||||
}
|
else
|
||||||
}
|
{
|
||||||
}
|
// semi-transparent OBJ
|
||||||
|
u32 back = background;
|
||||||
lineMix[x] = color;
|
u8 top2 = 0x20;
|
||||||
}
|
|
||||||
gfxBG2Changed = 0;
|
if(line2[x] < back)
|
||||||
gfxLastVCOUNT = VCOUNT;
|
{
|
||||||
}
|
back = line2[x];
|
||||||
|
top2 = 0x04;
|
||||||
void mode3RenderLineAll()
|
}
|
||||||
{
|
|
||||||
u16 *palette = (u16 *)paletteRAM;
|
if(top2 & (BLDMOD>>8))
|
||||||
|
color = gfxAlphaBlend(color, back,
|
||||||
if(DISPCNT & 0x80) {
|
coeff[COLEV & 0x1F],
|
||||||
for(int x = 0; x < 240; x++) {
|
coeff[(COLEV >> 8) & 0x1F]);
|
||||||
lineMix[x] = 0x7fff;
|
else
|
||||||
}
|
{
|
||||||
gfxLastVCOUNT = VCOUNT;
|
switch((BLDMOD >> 6) & 3)
|
||||||
return;
|
{
|
||||||
}
|
case 2:
|
||||||
|
if(BLDMOD & top)
|
||||||
bool inWindow0 = false;
|
color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]);
|
||||||
bool inWindow1 = false;
|
break;
|
||||||
|
case 3:
|
||||||
if(layerEnable & 0x2000) {
|
if(BLDMOD & top)
|
||||||
u8 v0 = WIN0V >> 8;
|
color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]);
|
||||||
u8 v1 = WIN0V & 255;
|
break;
|
||||||
inWindow0 = ((v0 == v1) && (v0 >= 0xe8));
|
}
|
||||||
if(v1 >= v0)
|
}
|
||||||
inWindow0 |= (VCOUNT >= v0 && VCOUNT < v1);
|
}
|
||||||
else
|
|
||||||
inWindow0 |= (VCOUNT >= v0 || VCOUNT < v1);
|
lineMix[x] = color;
|
||||||
}
|
}
|
||||||
if(layerEnable & 0x4000) {
|
gfxBG2Changed = 0;
|
||||||
u8 v0 = WIN1V >> 8;
|
gfxLastVCOUNT = VCOUNT;
|
||||||
u8 v1 = WIN1V & 255;
|
}
|
||||||
inWindow1 = ((v0 == v1) && (v0 >= 0xe8));
|
|
||||||
if(v1 >= v0)
|
void mode3RenderLineAll()
|
||||||
inWindow1 |= (VCOUNT >= v0 && VCOUNT < v1);
|
{
|
||||||
else
|
u16 *palette = (u16 *)paletteRAM;
|
||||||
inWindow1 |= (VCOUNT >= v0 || VCOUNT < v1);
|
|
||||||
}
|
if(DISPCNT & 0x80)
|
||||||
|
{
|
||||||
if(layerEnable & 0x0400) {
|
for(int x = 0; x < 240; x++)
|
||||||
int changed = gfxBG2Changed;
|
{
|
||||||
|
lineMix[x] = 0x7fff;
|
||||||
if(gfxLastVCOUNT > VCOUNT)
|
}
|
||||||
changed = 3;
|
gfxLastVCOUNT = VCOUNT;
|
||||||
|
return;
|
||||||
gfxDrawRotScreen16Bit(BG2CNT, BG2X_L, BG2X_H,
|
}
|
||||||
BG2Y_L, BG2Y_H, BG2PA, BG2PB,
|
|
||||||
BG2PC, BG2PD,
|
bool inWindow0 = false;
|
||||||
gfxBG2X, gfxBG2Y, changed,
|
bool inWindow1 = false;
|
||||||
line2);
|
|
||||||
}
|
if(layerEnable & 0x2000)
|
||||||
|
{
|
||||||
gfxDrawSprites(lineOBJ);
|
u8 v0 = WIN0V >> 8;
|
||||||
gfxDrawOBJWin(lineOBJWin);
|
u8 v1 = WIN0V & 255;
|
||||||
|
inWindow0 = ((v0 == v1) && (v0 >= 0xe8));
|
||||||
u8 inWin0Mask = WININ & 0xFF;
|
if(v1 >= v0)
|
||||||
u8 inWin1Mask = WININ >> 8;
|
inWindow0 |= (VCOUNT >= v0 && VCOUNT < v1);
|
||||||
u8 outMask = WINOUT & 0xFF;
|
else
|
||||||
|
inWindow0 |= (VCOUNT >= v0 || VCOUNT < v1);
|
||||||
u32 background = (READ16LE(&palette[0]) | 0x30000000);
|
}
|
||||||
|
if(layerEnable & 0x4000)
|
||||||
for(int x = 0; x < 240; x++) {
|
{
|
||||||
u32 color = background;
|
u8 v0 = WIN1V >> 8;
|
||||||
u8 top = 0x20;
|
u8 v1 = WIN1V & 255;
|
||||||
u8 mask = outMask;
|
inWindow1 = ((v0 == v1) && (v0 >= 0xe8));
|
||||||
|
if(v1 >= v0)
|
||||||
if(!(lineOBJWin[x] & 0x80000000)) {
|
inWindow1 |= (VCOUNT >= v0 && VCOUNT < v1);
|
||||||
mask = WINOUT >> 8;
|
else
|
||||||
}
|
inWindow1 |= (VCOUNT >= v0 || VCOUNT < v1);
|
||||||
|
}
|
||||||
if(inWindow1) {
|
|
||||||
if(gfxInWin1[x])
|
if(layerEnable & 0x0400)
|
||||||
mask = inWin1Mask;
|
{
|
||||||
}
|
int changed = gfxBG2Changed;
|
||||||
|
|
||||||
if(inWindow0) {
|
if(gfxLastVCOUNT > VCOUNT)
|
||||||
if(gfxInWin0[x]) {
|
changed = 3;
|
||||||
mask = inWin0Mask;
|
|
||||||
}
|
gfxDrawRotScreen16Bit(BG2CNT, BG2X_L, BG2X_H,
|
||||||
}
|
BG2Y_L, BG2Y_H, BG2PA, BG2PB,
|
||||||
|
BG2PC, BG2PD,
|
||||||
if((mask & 4) && (line2[x] < color)) {
|
gfxBG2X, gfxBG2Y, changed,
|
||||||
color = line2[x];
|
line2);
|
||||||
top = 0x04;
|
}
|
||||||
}
|
|
||||||
|
gfxDrawSprites(lineOBJ);
|
||||||
if((mask & 16) && ((u8)(lineOBJ[x]>>24) < (u8)(color >>24))) {
|
gfxDrawOBJWin(lineOBJWin);
|
||||||
color = lineOBJ[x];
|
|
||||||
top = 0x10;
|
u8 inWin0Mask = WININ & 0xFF;
|
||||||
}
|
u8 inWin1Mask = WININ >> 8;
|
||||||
|
u8 outMask = WINOUT & 0xFF;
|
||||||
if(color & 0x00010000) {
|
|
||||||
// semi-transparent OBJ
|
u32 background = (READ16LE(&palette[0]) | 0x30000000);
|
||||||
u32 back = background;
|
|
||||||
u8 top2 = 0x20;
|
for(int x = 0; x < 240; x++)
|
||||||
|
{
|
||||||
if((mask & 4) && line2[x] < back) {
|
u32 color = background;
|
||||||
back = line2[x];
|
u8 top = 0x20;
|
||||||
top2 = 0x04;
|
u8 mask = outMask;
|
||||||
}
|
|
||||||
|
if(!(lineOBJWin[x] & 0x80000000))
|
||||||
if(top2 & (BLDMOD>>8))
|
{
|
||||||
color = gfxAlphaBlend(color, back,
|
mask = WINOUT >> 8;
|
||||||
coeff[COLEV & 0x1F],
|
}
|
||||||
coeff[(COLEV >> 8) & 0x1F]);
|
|
||||||
else {
|
if(inWindow1)
|
||||||
switch((BLDMOD >> 6) & 3) {
|
{
|
||||||
case 2:
|
if(gfxInWin1[x])
|
||||||
if(BLDMOD & top)
|
mask = inWin1Mask;
|
||||||
color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]);
|
}
|
||||||
break;
|
|
||||||
case 3:
|
if(inWindow0)
|
||||||
if(BLDMOD & top)
|
{
|
||||||
color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]);
|
if(gfxInWin0[x])
|
||||||
break;
|
{
|
||||||
}
|
mask = inWin0Mask;
|
||||||
}
|
}
|
||||||
} else if(mask & 32) {
|
}
|
||||||
switch((BLDMOD >> 6) & 3) {
|
|
||||||
case 0:
|
if((mask & 4) && (line2[x] < color))
|
||||||
break;
|
{
|
||||||
case 1:
|
color = line2[x];
|
||||||
{
|
top = 0x04;
|
||||||
if(top & BLDMOD) {
|
}
|
||||||
u32 back = background;
|
|
||||||
u8 top2 = 0x20;
|
if((mask & 16) && ((u8)(lineOBJ[x]>>24) < (u8)(color >>24)))
|
||||||
|
{
|
||||||
if((mask & 4) && line2[x] < back) {
|
color = lineOBJ[x];
|
||||||
if(top != 0x04) {
|
top = 0x10;
|
||||||
back = line2[x];
|
}
|
||||||
top2 = 0x04;
|
|
||||||
}
|
if(mask & 32)
|
||||||
}
|
{
|
||||||
|
if(!(color & 0x00010000))
|
||||||
if((mask & 16) && (u8)(lineOBJ[x]>>24) < (u8)(back >> 24)) {
|
{
|
||||||
if(top != 0x10) {
|
switch((BLDMOD >> 6) & 3)
|
||||||
back = lineOBJ[x];
|
{
|
||||||
top2 = 0x10;
|
case 0:
|
||||||
}
|
break;
|
||||||
}
|
case 1:
|
||||||
|
{
|
||||||
if(top2 & (BLDMOD>>8))
|
if(top & BLDMOD)
|
||||||
color = gfxAlphaBlend(color, back,
|
{
|
||||||
coeff[COLEV & 0x1F],
|
u32 back = background;
|
||||||
coeff[(COLEV >> 8) & 0x1F]);
|
u8 top2 = 0x20;
|
||||||
|
|
||||||
}
|
if((mask & 4) && line2[x] < back)
|
||||||
}
|
{
|
||||||
break;
|
if(top != 0x04)
|
||||||
case 2:
|
{
|
||||||
if(BLDMOD & top)
|
back = line2[x];
|
||||||
color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]);
|
top2 = 0x04;
|
||||||
break;
|
}
|
||||||
case 3:
|
}
|
||||||
if(BLDMOD & top)
|
|
||||||
color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]);
|
if((mask & 16) && (u8)(lineOBJ[x]>>24) < (u8)(back >> 24))
|
||||||
break;
|
{
|
||||||
}
|
if(top != 0x10)
|
||||||
}
|
{
|
||||||
|
back = lineOBJ[x];
|
||||||
lineMix[x] = color;
|
top2 = 0x10;
|
||||||
}
|
}
|
||||||
gfxBG2Changed = 0;
|
}
|
||||||
gfxLastVCOUNT = VCOUNT;
|
|
||||||
}
|
if(top2 & (BLDMOD>>8))
|
||||||
|
color = gfxAlphaBlend(color, back,
|
||||||
|
coeff[COLEV & 0x1F],
|
||||||
|
coeff[(COLEV >> 8) & 0x1F]);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
if(BLDMOD & top)
|
||||||
|
color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]);
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
if(BLDMOD & top)
|
||||||
|
color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// semi-transparent OBJ
|
||||||
|
u32 back = background;
|
||||||
|
u8 top2 = 0x20;
|
||||||
|
|
||||||
|
if((mask & 4) && line2[x] < back)
|
||||||
|
{
|
||||||
|
back = line2[x];
|
||||||
|
top2 = 0x04;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(top2 & (BLDMOD>>8))
|
||||||
|
color = gfxAlphaBlend(color, back,
|
||||||
|
coeff[COLEV & 0x1F],
|
||||||
|
coeff[(COLEV >> 8) & 0x1F]);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
switch((BLDMOD >> 6) & 3)
|
||||||
|
{
|
||||||
|
case 2:
|
||||||
|
if(BLDMOD & top)
|
||||||
|
color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]);
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
if(BLDMOD & top)
|
||||||
|
color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(color & 0x00010000)
|
||||||
|
{
|
||||||
|
// semi-transparent OBJ
|
||||||
|
u32 back = background;
|
||||||
|
u8 top2 = 0x20;
|
||||||
|
|
||||||
|
if((mask & 4) && line2[x] < back)
|
||||||
|
{
|
||||||
|
back = line2[x];
|
||||||
|
top2 = 0x04;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(top2 & (BLDMOD>>8))
|
||||||
|
color = gfxAlphaBlend(color, back,
|
||||||
|
coeff[COLEV & 0x1F],
|
||||||
|
coeff[(COLEV >> 8) & 0x1F]);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
switch((BLDMOD >> 6) & 3)
|
||||||
|
{
|
||||||
|
case 2:
|
||||||
|
if(BLDMOD & top)
|
||||||
|
color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]);
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
if(BLDMOD & top)
|
||||||
|
color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
lineMix[x] = color;
|
||||||
|
}
|
||||||
|
gfxBG2Changed = 0;
|
||||||
|
gfxLastVCOUNT = VCOUNT;
|
||||||
|
}
|
||||||
|
@ -1,374 +1,460 @@
|
|||||||
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
|
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
|
||||||
// Copyright (C) 1999-2003 Forgotten
|
// Copyright (C) 1999-2003 Forgotten
|
||||||
// Copyright (C) 2004 Forgotten and the VBA development team
|
// Copyright (C) 2004 Forgotten and the VBA development team
|
||||||
|
|
||||||
// This program is free software; you can redistribute it and/or modify
|
// This program is free software; you can redistribute it and/or modify
|
||||||
// it under the terms of the GNU General Public License as published by
|
// it under the terms of the GNU General Public License as published by
|
||||||
// the Free Software Foundation; either version 2, or(at your option)
|
// the Free Software Foundation; either version 2, or(at your option)
|
||||||
// any later version.
|
// any later version.
|
||||||
//
|
//
|
||||||
// This program is distributed in the hope that it will be useful,
|
// This program is distributed in the hope that it will be useful,
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
// GNU General Public License for more details.
|
// GNU General Public License for more details.
|
||||||
//
|
//
|
||||||
// You should have received a copy of the GNU General Public License
|
// You should have received a copy of the GNU General Public License
|
||||||
// along with this program; if not, write to the Free Software Foundation,
|
// along with this program; if not, write to the Free Software Foundation,
|
||||||
// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
#include "agb/GBA.h"
|
#include "GBA.h"
|
||||||
#include "agb/GBAGfx.h"
|
#include "Gfx.h"
|
||||||
#include "Globals.h"
|
#include "Globals.h"
|
||||||
|
|
||||||
void mode4RenderLine()
|
void mode4RenderLine()
|
||||||
{
|
{
|
||||||
u16 *palette = (u16 *)paletteRAM;
|
u16 *palette = (u16 *)paletteRAM;
|
||||||
|
|
||||||
if(DISPCNT & 0x0080) {
|
if(DISPCNT & 0x0080)
|
||||||
for(int x = 0; x < 240; x++) {
|
{
|
||||||
lineMix[x] = 0x7fff;
|
for(int x = 0; x < 240; x++)
|
||||||
}
|
{
|
||||||
gfxLastVCOUNT = VCOUNT;
|
lineMix[x] = 0x7fff;
|
||||||
return;
|
}
|
||||||
}
|
gfxLastVCOUNT = VCOUNT;
|
||||||
|
return;
|
||||||
if(layerEnable & 0x400) {
|
}
|
||||||
int changed = gfxBG2Changed;
|
|
||||||
|
if(layerEnable & 0x400)
|
||||||
if(gfxLastVCOUNT > VCOUNT)
|
{
|
||||||
changed = 3;
|
int changed = gfxBG2Changed;
|
||||||
|
|
||||||
gfxDrawRotScreen256(BG2CNT, BG2X_L, BG2X_H, BG2Y_L, BG2Y_H,
|
if(gfxLastVCOUNT > VCOUNT)
|
||||||
BG2PA, BG2PB, BG2PC, BG2PD,
|
changed = 3;
|
||||||
gfxBG2X, gfxBG2Y, changed,
|
|
||||||
line2);
|
gfxDrawRotScreen256(BG2CNT, BG2X_L, BG2X_H, BG2Y_L, BG2Y_H,
|
||||||
}
|
BG2PA, BG2PB, BG2PC, BG2PD,
|
||||||
|
gfxBG2X, gfxBG2Y, changed,
|
||||||
gfxDrawSprites(lineOBJ);
|
line2);
|
||||||
|
}
|
||||||
u32 backdrop = (READ16LE(&palette[0]) | 0x30000000);
|
|
||||||
|
gfxDrawSprites(lineOBJ);
|
||||||
for(int x = 0; x < 240; x++) {
|
|
||||||
u32 color = backdrop;
|
u32 backdrop = (READ16LE(&palette[0]) | 0x30000000);
|
||||||
u8 top = 0x20;
|
|
||||||
|
for(int x = 0; x < 240; x++)
|
||||||
if(line2[x] < color) {
|
{
|
||||||
color = line2[x];
|
u32 color = backdrop;
|
||||||
top = 0x04;
|
u8 top = 0x20;
|
||||||
}
|
|
||||||
|
if(line2[x] < color)
|
||||||
if((u8)(lineOBJ[x]>>24) < (u8)(color >> 24)) {
|
{
|
||||||
color = lineOBJ[x];
|
color = line2[x];
|
||||||
top = 0x10;
|
top = 0x04;
|
||||||
}
|
}
|
||||||
|
|
||||||
if((top & 0x10) && (color & 0x00010000)) {
|
if((u8)(lineOBJ[x]>>24) < (u8)(color >> 24))
|
||||||
// semi-transparent OBJ
|
{
|
||||||
u32 back = backdrop;
|
color = lineOBJ[x];
|
||||||
u8 top2 = 0x20;
|
top = 0x10;
|
||||||
|
}
|
||||||
if(line2[x] < back) {
|
|
||||||
back = line2[x];
|
if((top & 0x10) && (color & 0x00010000))
|
||||||
top2 = 0x04;
|
{
|
||||||
}
|
// semi-transparent OBJ
|
||||||
|
u32 back = backdrop;
|
||||||
if(top2 & (BLDMOD>>8))
|
u8 top2 = 0x20;
|
||||||
color = gfxAlphaBlend(color, back,
|
|
||||||
coeff[COLEV & 0x1F],
|
if(line2[x] < back)
|
||||||
coeff[(COLEV >> 8) & 0x1F]);
|
{
|
||||||
else {
|
back = line2[x];
|
||||||
switch((BLDMOD >> 6) & 3) {
|
top2 = 0x04;
|
||||||
case 2:
|
}
|
||||||
if(BLDMOD & top)
|
|
||||||
color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]);
|
if(top2 & (BLDMOD>>8))
|
||||||
break;
|
color = gfxAlphaBlend(color, back,
|
||||||
case 3:
|
coeff[COLEV & 0x1F],
|
||||||
if(BLDMOD & top)
|
coeff[(COLEV >> 8) & 0x1F]);
|
||||||
color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]);
|
else
|
||||||
break;
|
{
|
||||||
}
|
switch((BLDMOD >> 6) & 3)
|
||||||
}
|
{
|
||||||
}
|
case 2:
|
||||||
|
if(BLDMOD & top)
|
||||||
lineMix[x] = color;
|
color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]);
|
||||||
}
|
break;
|
||||||
gfxBG2Changed = 0;
|
case 3:
|
||||||
gfxLastVCOUNT = VCOUNT;
|
if(BLDMOD & top)
|
||||||
}
|
color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]);
|
||||||
|
break;
|
||||||
void mode4RenderLineNoWindow()
|
}
|
||||||
{
|
}
|
||||||
u16 *palette = (u16 *)paletteRAM;
|
}
|
||||||
|
|
||||||
if(DISPCNT & 0x0080) {
|
lineMix[x] = color;
|
||||||
for(int x = 0; x < 240; x++) {
|
}
|
||||||
lineMix[x] = 0x7fff;
|
gfxBG2Changed = 0;
|
||||||
}
|
gfxLastVCOUNT = VCOUNT;
|
||||||
gfxLastVCOUNT = VCOUNT;
|
}
|
||||||
return;
|
|
||||||
}
|
void mode4RenderLineNoWindow()
|
||||||
|
{
|
||||||
if(layerEnable & 0x400) {
|
u16 *palette = (u16 *)paletteRAM;
|
||||||
int changed = gfxBG2Changed;
|
|
||||||
|
if(DISPCNT & 0x0080)
|
||||||
if(gfxLastVCOUNT > VCOUNT)
|
{
|
||||||
changed = 3;
|
for(int x = 0; x < 240; x++)
|
||||||
|
{
|
||||||
gfxDrawRotScreen256(BG2CNT, BG2X_L, BG2X_H, BG2Y_L, BG2Y_H,
|
lineMix[x] = 0x7fff;
|
||||||
BG2PA, BG2PB, BG2PC, BG2PD,
|
}
|
||||||
gfxBG2X, gfxBG2Y, changed,
|
gfxLastVCOUNT = VCOUNT;
|
||||||
line2);
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
gfxDrawSprites(lineOBJ);
|
if(layerEnable & 0x400)
|
||||||
|
{
|
||||||
u32 backdrop = (READ16LE(&palette[0]) | 0x30000000);
|
int changed = gfxBG2Changed;
|
||||||
|
|
||||||
for(int x = 0; x < 240; x++) {
|
if(gfxLastVCOUNT > VCOUNT)
|
||||||
u32 color = backdrop;
|
changed = 3;
|
||||||
u8 top = 0x20;
|
|
||||||
|
gfxDrawRotScreen256(BG2CNT, BG2X_L, BG2X_H, BG2Y_L, BG2Y_H,
|
||||||
if(line2[x] < color) {
|
BG2PA, BG2PB, BG2PC, BG2PD,
|
||||||
color = line2[x];
|
gfxBG2X, gfxBG2Y, changed,
|
||||||
top = 0x04;
|
line2);
|
||||||
}
|
}
|
||||||
|
|
||||||
if((u8)(lineOBJ[x]>>24) < (u8)(color >> 24)) {
|
gfxDrawSprites(lineOBJ);
|
||||||
color = lineOBJ[x];
|
|
||||||
top = 0x10;
|
u32 backdrop = (READ16LE(&palette[0]) | 0x30000000);
|
||||||
}
|
|
||||||
|
for(int x = 0; x < 240; x++)
|
||||||
if(!(color & 0x00010000)) {
|
{
|
||||||
switch((BLDMOD >> 6) & 3) {
|
u32 color = backdrop;
|
||||||
case 0:
|
u8 top = 0x20;
|
||||||
break;
|
|
||||||
case 1:
|
if(line2[x] < color)
|
||||||
{
|
{
|
||||||
if(top & BLDMOD) {
|
color = line2[x];
|
||||||
u32 back = backdrop;
|
top = 0x04;
|
||||||
u8 top2 = 0x20;
|
}
|
||||||
|
|
||||||
if(line2[x] < back) {
|
if((u8)(lineOBJ[x]>>24) < (u8)(color >> 24))
|
||||||
if(top != 0x04) {
|
{
|
||||||
back = line2[x];
|
color = lineOBJ[x];
|
||||||
top2 = 0x04;
|
top = 0x10;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
if(!(color & 0x00010000))
|
||||||
if((u8)(lineOBJ[x]>>24) < (u8)(back >> 24)) {
|
{
|
||||||
if(top != 0x10) {
|
switch((BLDMOD >> 6) & 3)
|
||||||
back = lineOBJ[x];
|
{
|
||||||
top2 = 0x10;
|
case 0:
|
||||||
}
|
break;
|
||||||
}
|
case 1:
|
||||||
|
{
|
||||||
if(top2 & (BLDMOD>>8))
|
if(top & BLDMOD)
|
||||||
color = gfxAlphaBlend(color, back,
|
{
|
||||||
coeff[COLEV & 0x1F],
|
u32 back = backdrop;
|
||||||
coeff[(COLEV >> 8) & 0x1F]);
|
u8 top2 = 0x20;
|
||||||
|
|
||||||
}
|
if(line2[x] < back)
|
||||||
}
|
{
|
||||||
break;
|
if(top != 0x04)
|
||||||
case 2:
|
{
|
||||||
if(BLDMOD & top)
|
back = line2[x];
|
||||||
color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]);
|
top2 = 0x04;
|
||||||
break;
|
}
|
||||||
case 3:
|
}
|
||||||
if(BLDMOD & top)
|
|
||||||
color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]);
|
if((u8)(lineOBJ[x]>>24) < (u8)(back >> 24))
|
||||||
break;
|
{
|
||||||
}
|
if(top != 0x10)
|
||||||
} else {
|
{
|
||||||
// semi-transparent OBJ
|
back = lineOBJ[x];
|
||||||
u32 back = backdrop;
|
top2 = 0x10;
|
||||||
u8 top2 = 0x20;
|
}
|
||||||
|
}
|
||||||
if(line2[x] < back) {
|
|
||||||
back = line2[x];
|
if(top2 & (BLDMOD>>8))
|
||||||
top2 = 0x04;
|
color = gfxAlphaBlend(color, back,
|
||||||
}
|
coeff[COLEV & 0x1F],
|
||||||
|
coeff[(COLEV >> 8) & 0x1F]);
|
||||||
if(top2 & (BLDMOD>>8))
|
|
||||||
color = gfxAlphaBlend(color, back,
|
}
|
||||||
coeff[COLEV & 0x1F],
|
}
|
||||||
coeff[(COLEV >> 8) & 0x1F]);
|
break;
|
||||||
else {
|
case 2:
|
||||||
switch((BLDMOD >> 6) & 3) {
|
if(BLDMOD & top)
|
||||||
case 2:
|
color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]);
|
||||||
if(BLDMOD & top)
|
break;
|
||||||
color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]);
|
case 3:
|
||||||
break;
|
if(BLDMOD & top)
|
||||||
case 3:
|
color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]);
|
||||||
if(BLDMOD & top)
|
break;
|
||||||
color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]);
|
}
|
||||||
break;
|
}
|
||||||
}
|
else
|
||||||
}
|
{
|
||||||
}
|
// semi-transparent OBJ
|
||||||
|
u32 back = backdrop;
|
||||||
lineMix[x] = color;
|
u8 top2 = 0x20;
|
||||||
}
|
|
||||||
gfxBG2Changed = 0;
|
if(line2[x] < back)
|
||||||
gfxLastVCOUNT = VCOUNT;
|
{
|
||||||
}
|
back = line2[x];
|
||||||
|
top2 = 0x04;
|
||||||
void mode4RenderLineAll()
|
}
|
||||||
{
|
|
||||||
u16 *palette = (u16 *)paletteRAM;
|
if(top2 & (BLDMOD>>8))
|
||||||
|
color = gfxAlphaBlend(color, back,
|
||||||
if(DISPCNT & 0x0080) {
|
coeff[COLEV & 0x1F],
|
||||||
for(int x = 0; x < 240; x++) {
|
coeff[(COLEV >> 8) & 0x1F]);
|
||||||
lineMix[x] = 0x7fff;
|
else
|
||||||
}
|
{
|
||||||
gfxLastVCOUNT = VCOUNT;
|
switch((BLDMOD >> 6) & 3)
|
||||||
return;
|
{
|
||||||
}
|
case 2:
|
||||||
|
if(BLDMOD & top)
|
||||||
bool inWindow0 = false;
|
color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]);
|
||||||
bool inWindow1 = false;
|
break;
|
||||||
|
case 3:
|
||||||
if(layerEnable & 0x2000) {
|
if(BLDMOD & top)
|
||||||
u8 v0 = WIN0V >> 8;
|
color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]);
|
||||||
u8 v1 = WIN0V & 255;
|
break;
|
||||||
inWindow0 = ((v0 == v1) && (v0 >= 0xe8));
|
}
|
||||||
if(v1 >= v0)
|
}
|
||||||
inWindow0 |= (VCOUNT >= v0 && VCOUNT < v1);
|
}
|
||||||
else
|
|
||||||
inWindow0 |= (VCOUNT >= v0 || VCOUNT < v1);
|
lineMix[x] = color;
|
||||||
}
|
}
|
||||||
if(layerEnable & 0x4000) {
|
gfxBG2Changed = 0;
|
||||||
u8 v0 = WIN1V >> 8;
|
gfxLastVCOUNT = VCOUNT;
|
||||||
u8 v1 = WIN1V & 255;
|
}
|
||||||
inWindow1 = ((v0 == v1) && (v0 >= 0xe8));
|
|
||||||
if(v1 >= v0)
|
void mode4RenderLineAll()
|
||||||
inWindow1 |= (VCOUNT >= v0 && VCOUNT < v1);
|
{
|
||||||
else
|
u16 *palette = (u16 *)paletteRAM;
|
||||||
inWindow1 |= (VCOUNT >= v0 || VCOUNT < v1);
|
|
||||||
}
|
if(DISPCNT & 0x0080)
|
||||||
|
{
|
||||||
if(layerEnable & 0x400) {
|
for(int x = 0; x < 240; x++)
|
||||||
int changed = gfxBG2Changed;
|
{
|
||||||
|
lineMix[x] = 0x7fff;
|
||||||
if(gfxLastVCOUNT > VCOUNT)
|
}
|
||||||
changed = 3;
|
gfxLastVCOUNT = VCOUNT;
|
||||||
|
return;
|
||||||
gfxDrawRotScreen256(BG2CNT, BG2X_L, BG2X_H, BG2Y_L, BG2Y_H,
|
}
|
||||||
BG2PA, BG2PB, BG2PC, BG2PD,
|
|
||||||
gfxBG2X, gfxBG2Y, changed,
|
bool inWindow0 = false;
|
||||||
line2);
|
bool inWindow1 = false;
|
||||||
}
|
|
||||||
|
if(layerEnable & 0x2000)
|
||||||
gfxDrawSprites(lineOBJ);
|
{
|
||||||
gfxDrawOBJWin(lineOBJWin);
|
u8 v0 = WIN0V >> 8;
|
||||||
|
u8 v1 = WIN0V & 255;
|
||||||
u32 backdrop = (READ16LE(&palette[0]) | 0x30000000);
|
inWindow0 = ((v0 == v1) && (v0 >= 0xe8));
|
||||||
|
if(v1 >= v0)
|
||||||
u8 inWin0Mask = WININ & 0xFF;
|
inWindow0 |= (VCOUNT >= v0 && VCOUNT < v1);
|
||||||
u8 inWin1Mask = WININ >> 8;
|
else
|
||||||
u8 outMask = WINOUT & 0xFF;
|
inWindow0 |= (VCOUNT >= v0 || VCOUNT < v1);
|
||||||
|
}
|
||||||
for(int x = 0; x < 240; x++) {
|
if(layerEnable & 0x4000)
|
||||||
u32 color = backdrop;
|
{
|
||||||
u8 top = 0x20;
|
u8 v0 = WIN1V >> 8;
|
||||||
u8 mask = outMask;
|
u8 v1 = WIN1V & 255;
|
||||||
|
inWindow1 = ((v0 == v1) && (v0 >= 0xe8));
|
||||||
if(!(lineOBJWin[x] & 0x80000000)) {
|
if(v1 >= v0)
|
||||||
mask = WINOUT >> 8;
|
inWindow1 |= (VCOUNT >= v0 && VCOUNT < v1);
|
||||||
}
|
else
|
||||||
|
inWindow1 |= (VCOUNT >= v0 || VCOUNT < v1);
|
||||||
if(inWindow1) {
|
}
|
||||||
if(gfxInWin1[x])
|
|
||||||
mask = inWin1Mask;
|
if(layerEnable & 0x400)
|
||||||
}
|
{
|
||||||
|
int changed = gfxBG2Changed;
|
||||||
if(inWindow0) {
|
|
||||||
if(gfxInWin0[x]) {
|
if(gfxLastVCOUNT > VCOUNT)
|
||||||
mask = inWin0Mask;
|
changed = 3;
|
||||||
}
|
|
||||||
}
|
gfxDrawRotScreen256(BG2CNT, BG2X_L, BG2X_H, BG2Y_L, BG2Y_H,
|
||||||
|
BG2PA, BG2PB, BG2PC, BG2PD,
|
||||||
if((mask & 4) && (line2[x] < color)) {
|
gfxBG2X, gfxBG2Y, changed,
|
||||||
color = line2[x];
|
line2);
|
||||||
top = 0x04;
|
}
|
||||||
}
|
|
||||||
|
gfxDrawSprites(lineOBJ);
|
||||||
if((mask & 16) && ((u8)(lineOBJ[x]>>24) < (u8)(color >>24))) {
|
gfxDrawOBJWin(lineOBJWin);
|
||||||
color = lineOBJ[x];
|
|
||||||
top = 0x10;
|
u32 backdrop = (READ16LE(&palette[0]) | 0x30000000);
|
||||||
}
|
|
||||||
|
u8 inWin0Mask = WININ & 0xFF;
|
||||||
if(color & 0x00010000) {
|
u8 inWin1Mask = WININ >> 8;
|
||||||
// semi-transparent OBJ
|
u8 outMask = WINOUT & 0xFF;
|
||||||
u32 back = backdrop;
|
|
||||||
u8 top2 = 0x20;
|
for(int x = 0; x < 240; x++)
|
||||||
|
{
|
||||||
if((mask & 4) && line2[x] < back) {
|
u32 color = backdrop;
|
||||||
back = line2[x];
|
u8 top = 0x20;
|
||||||
top2 = 0x04;
|
u8 mask = outMask;
|
||||||
}
|
|
||||||
|
if(!(lineOBJWin[x] & 0x80000000))
|
||||||
if(top2 & (BLDMOD>>8))
|
{
|
||||||
color = gfxAlphaBlend(color, back,
|
mask = WINOUT >> 8;
|
||||||
coeff[COLEV & 0x1F],
|
}
|
||||||
coeff[(COLEV >> 8) & 0x1F]);
|
|
||||||
else {
|
if(inWindow1)
|
||||||
switch((BLDMOD >> 6) & 3) {
|
{
|
||||||
case 2:
|
if(gfxInWin1[x])
|
||||||
if(BLDMOD & top)
|
mask = inWin1Mask;
|
||||||
color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]);
|
}
|
||||||
break;
|
|
||||||
case 3:
|
if(inWindow0)
|
||||||
if(BLDMOD & top)
|
{
|
||||||
color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]);
|
if(gfxInWin0[x])
|
||||||
break;
|
{
|
||||||
}
|
mask = inWin0Mask;
|
||||||
}
|
}
|
||||||
} else if(mask & 32) {
|
}
|
||||||
switch((BLDMOD >> 6) & 3) {
|
|
||||||
case 0:
|
if((mask & 4) && (line2[x] < color))
|
||||||
break;
|
{
|
||||||
case 1:
|
color = line2[x];
|
||||||
{
|
top = 0x04;
|
||||||
if(top & BLDMOD) {
|
}
|
||||||
u32 back = backdrop;
|
|
||||||
u8 top2 = 0x20;
|
if((mask & 16) && ((u8)(lineOBJ[x]>>24) < (u8)(color >>24)))
|
||||||
|
{
|
||||||
if((mask & 4) && line2[x] < back) {
|
color = lineOBJ[x];
|
||||||
if(top != 0x04) {
|
top = 0x10;
|
||||||
back = line2[x];
|
}
|
||||||
top2 = 0x04;
|
|
||||||
}
|
if(mask & 32)
|
||||||
}
|
{
|
||||||
|
if(!(color & 0x00010000))
|
||||||
if((mask & 16) && (u8)(lineOBJ[x]>>24) < (u8)(back >> 24)) {
|
{
|
||||||
if(top != 0x10) {
|
switch((BLDMOD >> 6) & 3)
|
||||||
back = lineOBJ[x];
|
{
|
||||||
top2 = 0x10;
|
case 0:
|
||||||
}
|
break;
|
||||||
}
|
case 1:
|
||||||
|
{
|
||||||
if(top2 & (BLDMOD>>8))
|
if(top & BLDMOD)
|
||||||
color = gfxAlphaBlend(color, back,
|
{
|
||||||
coeff[COLEV & 0x1F],
|
u32 back = backdrop;
|
||||||
coeff[(COLEV >> 8) & 0x1F]);
|
u8 top2 = 0x20;
|
||||||
|
|
||||||
}
|
if((mask & 4) && line2[x] < back)
|
||||||
}
|
{
|
||||||
break;
|
if(top != 0x04)
|
||||||
case 2:
|
{
|
||||||
if(BLDMOD & top)
|
back = line2[x];
|
||||||
color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]);
|
top2 = 0x04;
|
||||||
break;
|
}
|
||||||
case 3:
|
}
|
||||||
if(BLDMOD & top)
|
|
||||||
color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]);
|
if((mask & 16) && (u8)(lineOBJ[x]>>24) < (u8)(back >> 24))
|
||||||
break;
|
{
|
||||||
}
|
if(top != 0x10)
|
||||||
}
|
{
|
||||||
|
back = lineOBJ[x];
|
||||||
lineMix[x] = color;
|
top2 = 0x10;
|
||||||
}
|
}
|
||||||
gfxBG2Changed = 0;
|
}
|
||||||
gfxLastVCOUNT = VCOUNT;
|
|
||||||
}
|
if(top2 & (BLDMOD>>8))
|
||||||
|
color = gfxAlphaBlend(color, back,
|
||||||
|
coeff[COLEV & 0x1F],
|
||||||
|
coeff[(COLEV >> 8) & 0x1F]);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
if(BLDMOD & top)
|
||||||
|
color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]);
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
if(BLDMOD & top)
|
||||||
|
color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// semi-transparent OBJ
|
||||||
|
u32 back = backdrop;
|
||||||
|
u8 top2 = 0x20;
|
||||||
|
|
||||||
|
if((mask & 4) && line2[x] < back)
|
||||||
|
{
|
||||||
|
back = line2[x];
|
||||||
|
top2 = 0x04;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(top2 & (BLDMOD>>8))
|
||||||
|
color = gfxAlphaBlend(color, back,
|
||||||
|
coeff[COLEV & 0x1F],
|
||||||
|
coeff[(COLEV >> 8) & 0x1F]);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
switch((BLDMOD >> 6) & 3)
|
||||||
|
{
|
||||||
|
case 2:
|
||||||
|
if(BLDMOD & top)
|
||||||
|
color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]);
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
if(BLDMOD & top)
|
||||||
|
color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(color & 0x00010000)
|
||||||
|
{
|
||||||
|
// semi-transparent OBJ
|
||||||
|
u32 back = backdrop;
|
||||||
|
u8 top2 = 0x20;
|
||||||
|
|
||||||
|
if((mask & 4) && line2[x] < back)
|
||||||
|
{
|
||||||
|
back = line2[x];
|
||||||
|
top2 = 0x04;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(top2 & (BLDMOD>>8))
|
||||||
|
color = gfxAlphaBlend(color, back,
|
||||||
|
coeff[COLEV & 0x1F],
|
||||||
|
coeff[(COLEV >> 8) & 0x1F]);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
switch((BLDMOD >> 6) & 3)
|
||||||
|
{
|
||||||
|
case 2:
|
||||||
|
if(BLDMOD & top)
|
||||||
|
color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]);
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
if(BLDMOD & top)
|
||||||
|
color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
lineMix[x] = color;
|
||||||
|
}
|
||||||
|
gfxBG2Changed = 0;
|
||||||
|
gfxLastVCOUNT = VCOUNT;
|
||||||
|
}
|
||||||
|
@ -1,377 +1,463 @@
|
|||||||
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
|
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
|
||||||
// Copyright (C) 1999-2003 Forgotten
|
// Copyright (C) 1999-2003 Forgotten
|
||||||
// Copyright (C) 2004 Forgotten and the VBA development team
|
// Copyright (C) 2004 Forgotten and the VBA development team
|
||||||
|
|
||||||
// This program is free software; you can redistribute it and/or modify
|
// This program is free software; you can redistribute it and/or modify
|
||||||
// it under the terms of the GNU General Public License as published by
|
// it under the terms of the GNU General Public License as published by
|
||||||
// the Free Software Foundation; either version 2, or(at your option)
|
// the Free Software Foundation; either version 2, or(at your option)
|
||||||
// any later version.
|
// any later version.
|
||||||
//
|
//
|
||||||
// This program is distributed in the hope that it will be useful,
|
// This program is distributed in the hope that it will be useful,
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
// GNU General Public License for more details.
|
// GNU General Public License for more details.
|
||||||
//
|
//
|
||||||
// You should have received a copy of the GNU General Public License
|
// You should have received a copy of the GNU General Public License
|
||||||
// along with this program; if not, write to the Free Software Foundation,
|
// along with this program; if not, write to the Free Software Foundation,
|
||||||
// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
#include "agb/GBA.h"
|
#include "GBA.h"
|
||||||
#include "Globals.h"
|
#include "Globals.h"
|
||||||
#include "agb/GBAGfx.h"
|
#include "Gfx.h"
|
||||||
|
|
||||||
void mode5RenderLine()
|
void mode5RenderLine()
|
||||||
{
|
{
|
||||||
if(DISPCNT & 0x0080) {
|
if(DISPCNT & 0x0080)
|
||||||
for(int x = 0; x < 240; x++) {
|
{
|
||||||
lineMix[x] = 0x7fff;
|
for(int x = 0; x < 240; x++)
|
||||||
}
|
{
|
||||||
gfxLastVCOUNT = VCOUNT;
|
lineMix[x] = 0x7fff;
|
||||||
return;
|
}
|
||||||
}
|
gfxLastVCOUNT = VCOUNT;
|
||||||
|
return;
|
||||||
u16 *palette = (u16 *)paletteRAM;
|
}
|
||||||
|
|
||||||
if(layerEnable & 0x0400) {
|
u16 *palette = (u16 *)paletteRAM;
|
||||||
int changed = gfxBG2Changed;
|
|
||||||
|
if(layerEnable & 0x0400)
|
||||||
if(gfxLastVCOUNT > VCOUNT)
|
{
|
||||||
changed = 3;
|
int changed = gfxBG2Changed;
|
||||||
|
|
||||||
gfxDrawRotScreen16Bit160(BG2CNT, BG2X_L, BG2X_H,
|
if(gfxLastVCOUNT > VCOUNT)
|
||||||
BG2Y_L, BG2Y_H, BG2PA, BG2PB,
|
changed = 3;
|
||||||
BG2PC, BG2PD,
|
|
||||||
gfxBG2X, gfxBG2Y, changed,
|
gfxDrawRotScreen16Bit160(BG2CNT, BG2X_L, BG2X_H,
|
||||||
line2);
|
BG2Y_L, BG2Y_H, BG2PA, BG2PB,
|
||||||
}
|
BG2PC, BG2PD,
|
||||||
|
gfxBG2X, gfxBG2Y, changed,
|
||||||
gfxDrawSprites(lineOBJ);
|
line2);
|
||||||
|
}
|
||||||
u32 background = (READ16LE(&palette[0]) | 0x30000000);
|
|
||||||
|
gfxDrawSprites(lineOBJ);
|
||||||
for(int x = 0; x < 240; x++) {
|
|
||||||
u32 color = background;
|
u32 background = (READ16LE(&palette[0]) | 0x30000000);
|
||||||
u8 top = 0x20;
|
|
||||||
|
for(int x = 0; x < 240; x++)
|
||||||
if(line2[x] < color) {
|
{
|
||||||
color = line2[x];
|
u32 color = background;
|
||||||
top = 0x04;
|
u8 top = 0x20;
|
||||||
}
|
|
||||||
|
if(line2[x] < color)
|
||||||
if((u8)(lineOBJ[x]>>24) < (u8)(color >>24)) {
|
{
|
||||||
color = lineOBJ[x];
|
color = line2[x];
|
||||||
top = 0x10;
|
top = 0x04;
|
||||||
}
|
}
|
||||||
|
|
||||||
if((top & 0x10) && (color & 0x00010000)) {
|
if((u8)(lineOBJ[x]>>24) < (u8)(color >>24))
|
||||||
// semi-transparent OBJ
|
{
|
||||||
u32 back = background;
|
color = lineOBJ[x];
|
||||||
u8 top2 = 0x20;
|
top = 0x10;
|
||||||
|
}
|
||||||
if(line2[x] < back) {
|
|
||||||
back = line2[x];
|
if((top & 0x10) && (color & 0x00010000))
|
||||||
top2 = 0x04;
|
{
|
||||||
}
|
// semi-transparent OBJ
|
||||||
|
u32 back = background;
|
||||||
if(top2 & (BLDMOD>>8))
|
u8 top2 = 0x20;
|
||||||
color = gfxAlphaBlend(color, back,
|
|
||||||
coeff[COLEV & 0x1F],
|
if(line2[x] < back)
|
||||||
coeff[(COLEV >> 8) & 0x1F]);
|
{
|
||||||
else {
|
back = line2[x];
|
||||||
switch((BLDMOD >> 6) & 3) {
|
top2 = 0x04;
|
||||||
case 2:
|
}
|
||||||
if(BLDMOD & top)
|
|
||||||
color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]);
|
if(top2 & (BLDMOD>>8))
|
||||||
break;
|
color = gfxAlphaBlend(color, back,
|
||||||
case 3:
|
coeff[COLEV & 0x1F],
|
||||||
if(BLDMOD & top)
|
coeff[(COLEV >> 8) & 0x1F]);
|
||||||
color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]);
|
else
|
||||||
break;
|
{
|
||||||
}
|
switch((BLDMOD >> 6) & 3)
|
||||||
}
|
{
|
||||||
}
|
case 2:
|
||||||
|
if(BLDMOD & top)
|
||||||
lineMix[x] = color;
|
color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]);
|
||||||
}
|
break;
|
||||||
gfxBG2Changed = 0;
|
case 3:
|
||||||
gfxLastVCOUNT = VCOUNT;
|
if(BLDMOD & top)
|
||||||
}
|
color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]);
|
||||||
|
break;
|
||||||
void mode5RenderLineNoWindow()
|
}
|
||||||
{
|
}
|
||||||
if(DISPCNT & 0x0080) {
|
}
|
||||||
for(int x = 0; x < 240; x++) {
|
|
||||||
lineMix[x] = 0x7fff;
|
lineMix[x] = color;
|
||||||
}
|
}
|
||||||
gfxLastVCOUNT = VCOUNT;
|
gfxBG2Changed = 0;
|
||||||
return;
|
gfxLastVCOUNT = VCOUNT;
|
||||||
}
|
}
|
||||||
|
|
||||||
u16 *palette = (u16 *)paletteRAM;
|
void mode5RenderLineNoWindow()
|
||||||
|
{
|
||||||
if(layerEnable & 0x0400) {
|
if(DISPCNT & 0x0080)
|
||||||
int changed = gfxBG2Changed;
|
{
|
||||||
|
for(int x = 0; x < 240; x++)
|
||||||
if(gfxLastVCOUNT > VCOUNT)
|
{
|
||||||
changed = 3;
|
lineMix[x] = 0x7fff;
|
||||||
|
}
|
||||||
gfxDrawRotScreen16Bit160(BG2CNT, BG2X_L, BG2X_H,
|
gfxLastVCOUNT = VCOUNT;
|
||||||
BG2Y_L, BG2Y_H, BG2PA, BG2PB,
|
return;
|
||||||
BG2PC, BG2PD,
|
}
|
||||||
gfxBG2X, gfxBG2Y, changed,
|
|
||||||
line2);
|
u16 *palette = (u16 *)paletteRAM;
|
||||||
}
|
|
||||||
|
if(layerEnable & 0x0400)
|
||||||
gfxDrawSprites(lineOBJ);
|
{
|
||||||
|
int changed = gfxBG2Changed;
|
||||||
u32 background = ( READ16LE(&palette[0]) | 0x30000000);
|
|
||||||
|
if(gfxLastVCOUNT > VCOUNT)
|
||||||
for(int x = 0; x < 240; x++) {
|
changed = 3;
|
||||||
u32 color = background;
|
|
||||||
u8 top = 0x20;
|
gfxDrawRotScreen16Bit160(BG2CNT, BG2X_L, BG2X_H,
|
||||||
|
BG2Y_L, BG2Y_H, BG2PA, BG2PB,
|
||||||
if(line2[x] < color) {
|
BG2PC, BG2PD,
|
||||||
color = line2[x];
|
gfxBG2X, gfxBG2Y, changed,
|
||||||
top = 0x04;
|
line2);
|
||||||
}
|
}
|
||||||
|
|
||||||
if((u8)(lineOBJ[x]>>24) < (u8)(color >>24)) {
|
gfxDrawSprites(lineOBJ);
|
||||||
color = lineOBJ[x];
|
|
||||||
top = 0x10;
|
u32 background = ( READ16LE(&palette[0]) | 0x30000000);
|
||||||
}
|
|
||||||
|
for(int x = 0; x < 240; x++)
|
||||||
if(!(color & 0x00010000)) {
|
{
|
||||||
switch((BLDMOD >> 6) & 3) {
|
u32 color = background;
|
||||||
case 0:
|
u8 top = 0x20;
|
||||||
break;
|
|
||||||
case 1:
|
if(line2[x] < color)
|
||||||
{
|
{
|
||||||
if(top & BLDMOD) {
|
color = line2[x];
|
||||||
u32 back = background;
|
top = 0x04;
|
||||||
u8 top2 = 0x20;
|
}
|
||||||
|
|
||||||
if(line2[x] < back) {
|
if((u8)(lineOBJ[x]>>24) < (u8)(color >>24))
|
||||||
if(top != 0x04) {
|
{
|
||||||
back = line2[x];
|
color = lineOBJ[x];
|
||||||
top2 = 0x04;
|
top = 0x10;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
if(!(color & 0x00010000))
|
||||||
if((u8)(lineOBJ[x]>>24) < (u8)(back >> 24)) {
|
{
|
||||||
if(top != 0x10) {
|
switch((BLDMOD >> 6) & 3)
|
||||||
back = lineOBJ[x];
|
{
|
||||||
top2 = 0x10;
|
case 0:
|
||||||
}
|
break;
|
||||||
}
|
case 1:
|
||||||
|
{
|
||||||
if(top2 & (BLDMOD>>8))
|
if(top & BLDMOD)
|
||||||
color = gfxAlphaBlend(color, back,
|
{
|
||||||
coeff[COLEV & 0x1F],
|
u32 back = background;
|
||||||
coeff[(COLEV >> 8) & 0x1F]);
|
u8 top2 = 0x20;
|
||||||
|
|
||||||
}
|
if(line2[x] < back)
|
||||||
}
|
{
|
||||||
break;
|
if(top != 0x04)
|
||||||
case 2:
|
{
|
||||||
if(BLDMOD & top)
|
back = line2[x];
|
||||||
color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]);
|
top2 = 0x04;
|
||||||
break;
|
}
|
||||||
case 3:
|
}
|
||||||
if(BLDMOD & top)
|
|
||||||
color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]);
|
if((u8)(lineOBJ[x]>>24) < (u8)(back >> 24))
|
||||||
break;
|
{
|
||||||
}
|
if(top != 0x10)
|
||||||
} else {
|
{
|
||||||
// semi-transparent OBJ
|
back = lineOBJ[x];
|
||||||
u32 back = background;
|
top2 = 0x10;
|
||||||
u8 top2 = 0x20;
|
}
|
||||||
|
}
|
||||||
if(line2[x] < back) {
|
|
||||||
back = line2[x];
|
if(top2 & (BLDMOD>>8))
|
||||||
top2 = 0x04;
|
color = gfxAlphaBlend(color, back,
|
||||||
}
|
coeff[COLEV & 0x1F],
|
||||||
|
coeff[(COLEV >> 8) & 0x1F]);
|
||||||
if(top2 & (BLDMOD>>8))
|
|
||||||
color = gfxAlphaBlend(color, back,
|
}
|
||||||
coeff[COLEV & 0x1F],
|
}
|
||||||
coeff[(COLEV >> 8) & 0x1F]);
|
break;
|
||||||
else {
|
case 2:
|
||||||
switch((BLDMOD >> 6) & 3) {
|
if(BLDMOD & top)
|
||||||
case 2:
|
color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]);
|
||||||
if(BLDMOD & top)
|
break;
|
||||||
color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]);
|
case 3:
|
||||||
break;
|
if(BLDMOD & top)
|
||||||
case 3:
|
color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]);
|
||||||
if(BLDMOD & top)
|
break;
|
||||||
color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]);
|
}
|
||||||
break;
|
}
|
||||||
}
|
else
|
||||||
}
|
{
|
||||||
}
|
// semi-transparent OBJ
|
||||||
|
u32 back = background;
|
||||||
lineMix[x] = color;
|
u8 top2 = 0x20;
|
||||||
}
|
|
||||||
gfxBG2Changed = 0;
|
if(line2[x] < back)
|
||||||
gfxLastVCOUNT = VCOUNT;
|
{
|
||||||
}
|
back = line2[x];
|
||||||
|
top2 = 0x04;
|
||||||
void mode5RenderLineAll()
|
}
|
||||||
{
|
|
||||||
if(DISPCNT & 0x0080) {
|
if(top2 & (BLDMOD>>8))
|
||||||
for(int x = 0; x < 240; x++) {
|
color = gfxAlphaBlend(color, back,
|
||||||
lineMix[x] = 0x7fff;
|
coeff[COLEV & 0x1F],
|
||||||
}
|
coeff[(COLEV >> 8) & 0x1F]);
|
||||||
gfxLastVCOUNT = VCOUNT;
|
else
|
||||||
return;
|
{
|
||||||
}
|
switch((BLDMOD >> 6) & 3)
|
||||||
|
{
|
||||||
u16 *palette = (u16 *)paletteRAM;
|
case 2:
|
||||||
|
if(BLDMOD & top)
|
||||||
if(layerEnable & 0x0400) {
|
color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]);
|
||||||
int changed = gfxBG2Changed;
|
break;
|
||||||
|
case 3:
|
||||||
if(gfxLastVCOUNT > VCOUNT)
|
if(BLDMOD & top)
|
||||||
changed = 3;
|
color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]);
|
||||||
|
break;
|
||||||
gfxDrawRotScreen16Bit160(BG2CNT, BG2X_L, BG2X_H,
|
}
|
||||||
BG2Y_L, BG2Y_H, BG2PA, BG2PB,
|
}
|
||||||
BG2PC, BG2PD,
|
}
|
||||||
gfxBG2X, gfxBG2Y, changed,
|
|
||||||
line2);
|
lineMix[x] = color;
|
||||||
}
|
}
|
||||||
|
gfxBG2Changed = 0;
|
||||||
gfxDrawSprites(lineOBJ);
|
gfxLastVCOUNT = VCOUNT;
|
||||||
gfxDrawOBJWin(lineOBJWin);
|
}
|
||||||
|
|
||||||
bool inWindow0 = false;
|
void mode5RenderLineAll()
|
||||||
bool inWindow1 = false;
|
{
|
||||||
|
if(DISPCNT & 0x0080)
|
||||||
if(layerEnable & 0x2000) {
|
{
|
||||||
u8 v0 = WIN0V >> 8;
|
for(int x = 0; x < 240; x++)
|
||||||
u8 v1 = WIN0V & 255;
|
{
|
||||||
inWindow0 = ((v0 == v1) && (v0 >= 0xe8));
|
lineMix[x] = 0x7fff;
|
||||||
if(v1 >= v0)
|
}
|
||||||
inWindow0 |= (VCOUNT >= v0 && VCOUNT < v1);
|
gfxLastVCOUNT = VCOUNT;
|
||||||
else
|
return;
|
||||||
inWindow0 |= (VCOUNT >= v0 || VCOUNT < v1);
|
}
|
||||||
}
|
|
||||||
if(layerEnable & 0x4000) {
|
u16 *palette = (u16 *)paletteRAM;
|
||||||
u8 v0 = WIN1V >> 8;
|
|
||||||
u8 v1 = WIN1V & 255;
|
if(layerEnable & 0x0400)
|
||||||
inWindow1 = ((v0 == v1) && (v0 >= 0xe8));
|
{
|
||||||
if(v1 >= v0)
|
int changed = gfxBG2Changed;
|
||||||
inWindow1 |= (VCOUNT >= v0 && VCOUNT < v1);
|
|
||||||
else
|
if(gfxLastVCOUNT > VCOUNT)
|
||||||
inWindow1 |= (VCOUNT >= v0 || VCOUNT < v1);
|
changed = 3;
|
||||||
}
|
|
||||||
|
gfxDrawRotScreen16Bit160(BG2CNT, BG2X_L, BG2X_H,
|
||||||
u8 inWin0Mask = WININ & 0xFF;
|
BG2Y_L, BG2Y_H, BG2PA, BG2PB,
|
||||||
u8 inWin1Mask = WININ >> 8;
|
BG2PC, BG2PD,
|
||||||
u8 outMask = WINOUT & 0xFF;
|
gfxBG2X, gfxBG2Y, changed,
|
||||||
|
line2);
|
||||||
u32 background = (READ16LE(&palette[0]) | 0x30000000);
|
}
|
||||||
|
|
||||||
for(int x = 0; x < 240; x++) {
|
gfxDrawSprites(lineOBJ);
|
||||||
u32 color = background;
|
gfxDrawOBJWin(lineOBJWin);
|
||||||
u8 top = 0x20;
|
|
||||||
u8 mask = outMask;
|
bool inWindow0 = false;
|
||||||
|
bool inWindow1 = false;
|
||||||
if(!(lineOBJWin[x] & 0x80000000)) {
|
|
||||||
mask = WINOUT >> 8;
|
if(layerEnable & 0x2000)
|
||||||
}
|
{
|
||||||
|
u8 v0 = WIN0V >> 8;
|
||||||
if(inWindow1) {
|
u8 v1 = WIN0V & 255;
|
||||||
if(gfxInWin1[x])
|
inWindow0 = ((v0 == v1) && (v0 >= 0xe8));
|
||||||
mask = inWin1Mask;
|
if(v1 >= v0)
|
||||||
}
|
inWindow0 |= (VCOUNT >= v0 && VCOUNT < v1);
|
||||||
|
else
|
||||||
if(inWindow0) {
|
inWindow0 |= (VCOUNT >= v0 || VCOUNT < v1);
|
||||||
if(gfxInWin0[x]) {
|
}
|
||||||
mask = inWin0Mask;
|
if(layerEnable & 0x4000)
|
||||||
}
|
{
|
||||||
}
|
u8 v0 = WIN1V >> 8;
|
||||||
|
u8 v1 = WIN1V & 255;
|
||||||
if((mask & 4) && (line2[x] < color)) {
|
inWindow1 = ((v0 == v1) && (v0 >= 0xe8));
|
||||||
color = line2[x];
|
if(v1 >= v0)
|
||||||
top = 0x04;
|
inWindow1 |= (VCOUNT >= v0 && VCOUNT < v1);
|
||||||
}
|
else
|
||||||
|
inWindow1 |= (VCOUNT >= v0 || VCOUNT < v1);
|
||||||
if((mask & 16) && ((u8)(lineOBJ[x]>>24) < (u8)(color >>24))) {
|
}
|
||||||
color = lineOBJ[x];
|
|
||||||
top = 0x10;
|
u8 inWin0Mask = WININ & 0xFF;
|
||||||
}
|
u8 inWin1Mask = WININ >> 8;
|
||||||
|
u8 outMask = WINOUT & 0xFF;
|
||||||
if(color & 0x00010000) {
|
|
||||||
// semi-transparent OBJ
|
u32 background = (READ16LE(&palette[0]) | 0x30000000);
|
||||||
u32 back = background;
|
|
||||||
u8 top2 = 0x20;
|
for(int x = 0; x < 240; x++)
|
||||||
|
{
|
||||||
if((mask & 4) && line2[x] < back) {
|
u32 color = background;
|
||||||
back = line2[x];
|
u8 top = 0x20;
|
||||||
top2 = 0x04;
|
u8 mask = outMask;
|
||||||
}
|
|
||||||
|
if(!(lineOBJWin[x] & 0x80000000))
|
||||||
if(top2 & (BLDMOD>>8))
|
{
|
||||||
color = gfxAlphaBlend(color, back,
|
mask = WINOUT >> 8;
|
||||||
coeff[COLEV & 0x1F],
|
}
|
||||||
coeff[(COLEV >> 8) & 0x1F]);
|
|
||||||
else {
|
if(inWindow1)
|
||||||
switch((BLDMOD >> 6) & 3) {
|
{
|
||||||
case 2:
|
if(gfxInWin1[x])
|
||||||
if(BLDMOD & top)
|
mask = inWin1Mask;
|
||||||
color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]);
|
}
|
||||||
break;
|
|
||||||
case 3:
|
if(inWindow0)
|
||||||
if(BLDMOD & top)
|
{
|
||||||
color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]);
|
if(gfxInWin0[x])
|
||||||
break;
|
{
|
||||||
}
|
mask = inWin0Mask;
|
||||||
}
|
}
|
||||||
} else if(mask & 32) {
|
}
|
||||||
switch((BLDMOD >> 6) & 3) {
|
|
||||||
case 0:
|
if((mask & 4) && (line2[x] < color))
|
||||||
break;
|
{
|
||||||
case 1:
|
color = line2[x];
|
||||||
{
|
top = 0x04;
|
||||||
if(top & BLDMOD) {
|
}
|
||||||
u32 back = background;
|
|
||||||
u8 top2 = 0x20;
|
if((mask & 16) && ((u8)(lineOBJ[x]>>24) < (u8)(color >>24)))
|
||||||
|
{
|
||||||
if((mask & 4) && line2[x] < back) {
|
color = lineOBJ[x];
|
||||||
if(top != 0x04) {
|
top = 0x10;
|
||||||
back = line2[x];
|
}
|
||||||
top2 = 0x04;
|
|
||||||
}
|
if(mask & 32)
|
||||||
}
|
{
|
||||||
|
if(!(color & 0x00010000))
|
||||||
if((mask & 16) && (u8)(lineOBJ[x]>>24) < (u8)(back >> 24)) {
|
{
|
||||||
if(top != 0x10) {
|
switch((BLDMOD >> 6) & 3)
|
||||||
back = lineOBJ[x];
|
{
|
||||||
top2 = 0x10;
|
case 0:
|
||||||
}
|
break;
|
||||||
}
|
case 1:
|
||||||
|
{
|
||||||
if(top2 & (BLDMOD>>8))
|
if(top & BLDMOD)
|
||||||
color = gfxAlphaBlend(color, back,
|
{
|
||||||
coeff[COLEV & 0x1F],
|
u32 back = background;
|
||||||
coeff[(COLEV >> 8) & 0x1F]);
|
u8 top2 = 0x20;
|
||||||
|
|
||||||
}
|
if((mask & 4) && line2[x] < back)
|
||||||
}
|
{
|
||||||
break;
|
if(top != 0x04)
|
||||||
case 2:
|
{
|
||||||
if(BLDMOD & top)
|
back = line2[x];
|
||||||
color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]);
|
top2 = 0x04;
|
||||||
break;
|
}
|
||||||
case 3:
|
}
|
||||||
if(BLDMOD & top)
|
|
||||||
color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]);
|
if((mask & 16) && (u8)(lineOBJ[x]>>24) < (u8)(back >> 24))
|
||||||
break;
|
{
|
||||||
}
|
if(top != 0x10)
|
||||||
}
|
{
|
||||||
|
back = lineOBJ[x];
|
||||||
lineMix[x] = color;
|
top2 = 0x10;
|
||||||
}
|
}
|
||||||
gfxBG2Changed = 0;
|
}
|
||||||
gfxLastVCOUNT = VCOUNT;
|
|
||||||
}
|
if(top2 & (BLDMOD>>8))
|
||||||
|
color = gfxAlphaBlend(color, back,
|
||||||
|
coeff[COLEV & 0x1F],
|
||||||
|
coeff[(COLEV >> 8) & 0x1F]);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
if(BLDMOD & top)
|
||||||
|
color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]);
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
if(BLDMOD & top)
|
||||||
|
color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// semi-transparent OBJ
|
||||||
|
u32 back = background;
|
||||||
|
u8 top2 = 0x20;
|
||||||
|
|
||||||
|
if((mask & 4) && line2[x] < back)
|
||||||
|
{
|
||||||
|
back = line2[x];
|
||||||
|
top2 = 0x04;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(top2 & (BLDMOD>>8))
|
||||||
|
color = gfxAlphaBlend(color, back,
|
||||||
|
coeff[COLEV & 0x1F],
|
||||||
|
coeff[(COLEV >> 8) & 0x1F]);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
switch((BLDMOD >> 6) & 3)
|
||||||
|
{
|
||||||
|
case 2:
|
||||||
|
if(BLDMOD & top)
|
||||||
|
color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]);
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
if(BLDMOD & top)
|
||||||
|
color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(color & 0x00010000)
|
||||||
|
{
|
||||||
|
// semi-transparent OBJ
|
||||||
|
u32 back = background;
|
||||||
|
u8 top2 = 0x20;
|
||||||
|
|
||||||
|
if((mask & 4) && line2[x] < back)
|
||||||
|
{
|
||||||
|
back = line2[x];
|
||||||
|
top2 = 0x04;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(top2 & (BLDMOD>>8))
|
||||||
|
color = gfxAlphaBlend(color, back,
|
||||||
|
coeff[COLEV & 0x1F],
|
||||||
|
coeff[(COLEV >> 8) & 0x1F]);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
switch((BLDMOD >> 6) & 3)
|
||||||
|
{
|
||||||
|
case 2:
|
||||||
|
if(BLDMOD & top)
|
||||||
|
color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]);
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
if(BLDMOD & top)
|
||||||
|
color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
lineMix[x] = color;
|
||||||
|
}
|
||||||
|
gfxBG2Changed = 0;
|
||||||
|
gfxLastVCOUNT = VCOUNT;
|
||||||
|
}
|
||||||
|
126
source/vba/NLS.h
126
source/vba/NLS.h
@ -1,64 +1,62 @@
|
|||||||
// -*- C++ -*-
|
// -*- C++ -*-
|
||||||
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
|
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
|
||||||
// Copyright (C) 1999-2003 Forgotten
|
// Copyright (C) 1999-2003 Forgotten
|
||||||
// Copyright (C) 2004 Forgotten and the VBA development team
|
// Copyright (C) 2004 Forgotten and the VBA development team
|
||||||
|
|
||||||
// This program is free software; you can redistribute it and/or modify
|
// This program is free software; you can redistribute it and/or modify
|
||||||
// it under the terms of the GNU General Public License as published by
|
// it under the terms of the GNU General Public License as published by
|
||||||
// the Free Software Foundation; either version 2, or(at your option)
|
// the Free Software Foundation; either version 2, or(at your option)
|
||||||
// any later version.
|
// any later version.
|
||||||
//
|
//
|
||||||
// This program is distributed in the hope that it will be useful,
|
// This program is distributed in the hope that it will be useful,
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
// GNU General Public License for more details.
|
// GNU General Public License for more details.
|
||||||
//
|
//
|
||||||
// You should have received a copy of the GNU General Public License
|
// You should have received a copy of the GNU General Public License
|
||||||
// along with this program; if not, write to the Free Software Foundation,
|
// along with this program; if not, write to the Free Software Foundation,
|
||||||
// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
#define N_(String) (String)
|
#define N_(String) (String)
|
||||||
|
|
||||||
#define MSG_UNSUPPORTED_VBA_SGM 1
|
#define MSG_UNSUPPORTED_VBA_SGM 1
|
||||||
#define MSG_CANNOT_LOAD_SGM 2
|
#define MSG_CANNOT_LOAD_SGM 2
|
||||||
#define MSG_SAVE_GAME_NOT_USING_BIOS 3
|
#define MSG_SAVE_GAME_NOT_USING_BIOS 3
|
||||||
#define MSG_SAVE_GAME_USING_BIOS 4
|
#define MSG_SAVE_GAME_USING_BIOS 4
|
||||||
#define MSG_UNSUPPORTED_SAVE_TYPE 5
|
#define MSG_UNSUPPORTED_SAVE_TYPE 5
|
||||||
#define MSG_CANNOT_OPEN_FILE 6
|
#define MSG_CANNOT_OPEN_FILE 6
|
||||||
#define MSG_BAD_ZIP_FILE 7
|
#define MSG_BAD_ZIP_FILE 7
|
||||||
#define MSG_NO_IMAGE_ON_ZIP 8
|
#define MSG_NO_IMAGE_ON_ZIP 8
|
||||||
#define MSG_ERROR_OPENING_IMAGE 9
|
#define MSG_ERROR_OPENING_IMAGE 9
|
||||||
#define MSG_ERROR_READING_IMAGE 10
|
#define MSG_ERROR_READING_IMAGE 10
|
||||||
#define MSG_UNSUPPORTED_BIOS_FUNCTION 11
|
#define MSG_UNSUPPORTED_BIOS_FUNCTION 11
|
||||||
#define MSG_INVALID_BIOS_FILE_SIZE 12
|
#define MSG_INVALID_BIOS_FILE_SIZE 12
|
||||||
#define MSG_INVALID_CHEAT_CODE 13
|
#define MSG_INVALID_CHEAT_CODE 13
|
||||||
#define MSG_UNKNOWN_ARM_OPCODE 14
|
#define MSG_UNKNOWN_ARM_OPCODE 14
|
||||||
#define MSG_UNKNOWN_THUMB_OPCODE 15
|
#define MSG_UNKNOWN_THUMB_OPCODE 15
|
||||||
#define MSG_ERROR_CREATING_FILE 16
|
#define MSG_ERROR_CREATING_FILE 16
|
||||||
#define MSG_FAILED_TO_READ_SGM 17
|
#define MSG_FAILED_TO_READ_SGM 17
|
||||||
#define MSG_FAILED_TO_READ_RTC 18
|
#define MSG_FAILED_TO_READ_RTC 18
|
||||||
#define MSG_UNSUPPORTED_VB_SGM 19
|
#define MSG_UNSUPPORTED_VB_SGM 19
|
||||||
#define MSG_CANNOT_LOAD_SGM_FOR 20
|
#define MSG_CANNOT_LOAD_SGM_FOR 20
|
||||||
#define MSG_ERROR_OPENING_IMAGE_FROM 21
|
#define MSG_ERROR_OPENING_IMAGE_FROM 21
|
||||||
#define MSG_ERROR_READING_IMAGE_FROM 22
|
#define MSG_ERROR_READING_IMAGE_FROM 22
|
||||||
#define MSG_UNSUPPORTED_ROM_SIZE 23
|
#define MSG_UNSUPPORTED_ROM_SIZE 23
|
||||||
#define MSG_UNSUPPORTED_RAM_SIZE 24
|
#define MSG_UNSUPPORTED_RAM_SIZE 24
|
||||||
#define MSG_UNKNOWN_CARTRIDGE_TYPE 25
|
#define MSG_UNKNOWN_CARTRIDGE_TYPE 25
|
||||||
#define MSG_MAXIMUM_NUMBER_OF_CHEATS 26
|
#define MSG_MAXIMUM_NUMBER_OF_CHEATS 26
|
||||||
#define MSG_INVALID_GAMESHARK_CODE 27
|
#define MSG_INVALID_GAMESHARK_CODE 27
|
||||||
#define MSG_INVALID_GAMEGENIE_CODE 28
|
#define MSG_INVALID_GAMEGENIE_CODE 28
|
||||||
#define MSG_INVALID_CHEAT_TO_REMOVE 29
|
#define MSG_INVALID_CHEAT_TO_REMOVE 29
|
||||||
#define MSG_INVALID_CHEAT_CODE_ADDRESS 30
|
#define MSG_INVALID_CHEAT_CODE_ADDRESS 30
|
||||||
#define MSG_UNSUPPORTED_CHEAT_LIST_VERSION 31
|
#define MSG_UNSUPPORTED_CHEAT_LIST_VERSION 31
|
||||||
#define MSG_UNSUPPORTED_CHEAT_LIST_TYPE 32
|
#define MSG_UNSUPPORTED_CHEAT_LIST_TYPE 32
|
||||||
#define MSG_INVALID_GSA_CODE 33
|
#define MSG_INVALID_GSA_CODE 33
|
||||||
#define MSG_CANNOT_IMPORT_SNAPSHOT_FOR 34
|
#define MSG_CANNOT_IMPORT_SNAPSHOT_FOR 34
|
||||||
#define MSG_UNSUPPORTED_SNAPSHOT_FILE 35
|
#define MSG_UNSUPPORTED_SNAPSHOT_FILE 35
|
||||||
#define MSG_UNSUPPORTED_ARM_MODE 36
|
#define MSG_UNSUPPORTED_ARM_MODE 36
|
||||||
#define MSG_UNSUPPORTED_CODE_FILE 37
|
#define MSG_UNSUPPORTED_CODE_FILE 37
|
||||||
#define MSG_GBA_CODE_WARNING 38
|
#define MSG_GBA_CODE_WARNING 38
|
||||||
#define MSG_INVALID_CBA_CODE 39
|
#define MSG_INVALID_CBA_CODE 39
|
||||||
#define MSG_CBA_CODE_WARNING 40
|
#define MSG_CBA_CODE_WARNING 40
|
||||||
#define MSG_OUT_OF_MEMORY 41
|
#define MSG_OUT_OF_MEMORY 41
|
||||||
#define MSG_WRONG_GAMESHARK_CODE 42
|
|
||||||
#define MSG_UNSUPPORTED_GAMESHARK_CODE 43
|
|
||||||
|
@ -1,75 +1,77 @@
|
|||||||
// -*- C++ -*-
|
// -*- C++ -*-
|
||||||
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
|
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
|
||||||
// Copyright (C) 1999-2003 Forgotten
|
// Copyright (C) 1999-2003 Forgotten
|
||||||
// Copyright (C) 2004 Forgotten and the VBA development team
|
// Copyright (C) 2004 Forgotten and the VBA development team
|
||||||
|
|
||||||
// This program is free software; you can redistribute it and/or modify
|
// This program is free software; you can redistribute it and/or modify
|
||||||
// it under the terms of the GNU General Public License as published by
|
// it under the terms of the GNU General Public License as published by
|
||||||
// the Free Software Foundation; either version 2, or(at your option)
|
// the Free Software Foundation; either version 2, or(at your option)
|
||||||
// any later version.
|
// any later version.
|
||||||
//
|
//
|
||||||
// This program is distributed in the hope that it will be useful,
|
// This program is distributed in the hope that it will be useful,
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
// GNU General Public License for more details.
|
// GNU General Public License for more details.
|
||||||
//
|
//
|
||||||
// You should have received a copy of the GNU General Public License
|
// You should have received a copy of the GNU General Public License
|
||||||
// along with this program; if not, write to the Free Software Foundation,
|
// along with this program; if not, write to the Free Software Foundation,
|
||||||
// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
#ifndef VBA_PORT_H
|
#ifndef VBA_PORT_H
|
||||||
#define VBA_PORT_H
|
#define VBA_PORT_H
|
||||||
|
|
||||||
// swaps a 16-bit value
|
// swaps a 16-bit value
|
||||||
static inline u16 swap16(u16 v)
|
static inline u16 swap16(u16 v)
|
||||||
{
|
{
|
||||||
return (v<<8)|(v>>8);
|
return (v<<8)|(v>>8);
|
||||||
}
|
}
|
||||||
|
|
||||||
// swaps a 32-bit value
|
// swaps a 32-bit value
|
||||||
static inline u32 swap32(u32 v)
|
static inline u32 swap32(u32 v)
|
||||||
{
|
{
|
||||||
return (v<<24)|((v<<8)&0xff0000)|((v>>8)&0xff00)|(v>>24);
|
return (v<<24)|((v<<8)&0xff0000)|((v>>8)&0xff00)|(v>>24);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef WORDS_BIGENDIAN
|
#ifdef WORDS_BIGENDIAN
|
||||||
#if defined(__GNUC__) && defined(__ppc__)
|
#define __ppc__
|
||||||
|
|
||||||
#define READ16LE(base) \
|
#if defined(__GNUC__) && defined(__ppc__)
|
||||||
({ unsigned short lhbrxResult; \
|
|
||||||
__asm__ ("lhbrx %0, 0, %1" : "=r" (lhbrxResult) : "r" (base) : "memory"); \
|
#define READ16LE(base) \
|
||||||
lhbrxResult; })
|
({ unsigned short lhbrxResult; \
|
||||||
|
__asm__ ("lhbrx %0, 0, %1" : "=r" (lhbrxResult) : "r" (base) : "memory"); \
|
||||||
#define READ32LE(base) \
|
lhbrxResult; })
|
||||||
({ unsigned long lwbrxResult; \
|
|
||||||
__asm__ ("lwbrx %0, 0, %1" : "=r" (lwbrxResult) : "r" (base) : "memory"); \
|
#define READ32LE(base) \
|
||||||
lwbrxResult; })
|
({ unsigned long lwbrxResult; \
|
||||||
|
__asm__ ("lwbrx %0, 0, %1" : "=r" (lwbrxResult) : "r" (base) : "memory"); \
|
||||||
#define WRITE16LE(base, value) \
|
lwbrxResult; })
|
||||||
__asm__ ("sthbrx %0, 0, %1" : : "r" (value), "r" (base) : "memory")
|
|
||||||
|
#define WRITE16LE(base, value) \
|
||||||
#define WRITE32LE(base, value) \
|
__asm__ ("sthbrx %0, 0, %1" : : "r" (value), "r" (base) : "memory")
|
||||||
__asm__ ("stwbrx %0, 0, %1" : : "r" (value), "r" (base) : "memory")
|
|
||||||
|
#define WRITE32LE(base, value) \
|
||||||
#else
|
__asm__ ("stwbrx %0, 0, %1" : : "r" (value), "r" (base) : "memory")
|
||||||
#define READ16LE(x) \
|
|
||||||
swap16(*((u16 *)(x)))
|
#else
|
||||||
#define READ32LE(x) \
|
#define READ16LE(x) \
|
||||||
swap32(*((u32 *)(x)))
|
swap16(*((u16 *)(x)))
|
||||||
#define WRITE16LE(x,v) \
|
#define READ32LE(x) \
|
||||||
*((u16 *)x) = swap16((v))
|
swap32(*((u32 *)(x)))
|
||||||
#define WRITE32LE(x,v) \
|
#define WRITE16LE(x,v) \
|
||||||
*((u32 *)x) = swap32((v))
|
*((u16 *)x) = swap16((v))
|
||||||
#endif
|
#define WRITE32LE(x,v) \
|
||||||
#else
|
*((u32 *)x) = swap32((v))
|
||||||
#define READ16LE(x) \
|
#endif
|
||||||
*((u16 *)x)
|
#else
|
||||||
#define READ32LE(x) \
|
#define READ16LE(x) \
|
||||||
*((u32 *)x)
|
*((u16 *)x)
|
||||||
#define WRITE16LE(x,v) \
|
#define READ32LE(x) \
|
||||||
*((u16 *)x) = (v)
|
*((u32 *)x)
|
||||||
#define WRITE32LE(x,v) \
|
#define WRITE16LE(x,v) \
|
||||||
*((u32 *)x) = (v)
|
*((u16 *)x) = (v)
|
||||||
#endif
|
#define WRITE32LE(x,v) \
|
||||||
|
*((u32 *)x) = (v)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
|
@ -1,230 +1,245 @@
|
|||||||
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
|
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
|
||||||
// Copyright (C) 1999-2003 Forgotten
|
// Copyright (C) 1999-2003 Forgotten
|
||||||
// Copyright (C) 2005 Forgotten and the VBA development team
|
// Copyright (C) 2004 Forgotten and the VBA development team
|
||||||
|
|
||||||
// This program is free software; you can redistribute it and/or modify
|
// This program is free software; you can redistribute it and/or modify
|
||||||
// it under the terms of the GNU General Public License as published by
|
// it under the terms of the GNU General Public License as published by
|
||||||
// the Free Software Foundation; either version 2, or(at your option)
|
// the Free Software Foundation; either version 2, or(at your option)
|
||||||
// any later version.
|
// any later version.
|
||||||
//
|
//
|
||||||
// This program is distributed in the hope that it will be useful,
|
// This program is distributed in the hope that it will be useful,
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
// GNU General Public License for more details.
|
// GNU General Public License for more details.
|
||||||
//
|
//
|
||||||
// You should have received a copy of the GNU General Public License
|
// You should have received a copy of the GNU General Public License
|
||||||
// along with this program; if not, write to the Free Software Foundation,
|
// along with this program; if not, write to the Free Software Foundation,
|
||||||
// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
#include "System.h"
|
#include "System.h"
|
||||||
#include "agb/GBA.h"
|
#include "GBA.h"
|
||||||
#include "Globals.h"
|
#include "Globals.h"
|
||||||
#include "Port.h"
|
#include "Port.h"
|
||||||
#include "Util.h"
|
#include "Util.h"
|
||||||
#include "NLS.h"
|
#include "NLS.h"
|
||||||
#include "vmmem.h"
|
#include "vmmem.h"
|
||||||
|
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
enum RTCSTATE { IDLE, COMMAND, DATA, READDATA };
|
enum RTCSTATE { IDLE, COMMAND, DATA, READDATA };
|
||||||
|
|
||||||
typedef struct {
|
typedef struct
|
||||||
u8 byte0;
|
{
|
||||||
u8 byte1;
|
u8 byte0;
|
||||||
u8 byte2;
|
u8 byte1;
|
||||||
u8 command;
|
u8 byte2;
|
||||||
int dataLen;
|
u8 command;
|
||||||
int bits;
|
int dataLen;
|
||||||
RTCSTATE state;
|
int bits;
|
||||||
u8 data[12];
|
RTCSTATE state;
|
||||||
// reserved variables for future
|
u8 data[12];
|
||||||
u8 reserved[12];
|
// reserved variables for future
|
||||||
bool reserved2;
|
u8 reserved[12];
|
||||||
u32 reserved3;
|
bool reserved2;
|
||||||
} RTCCLOCKDATA;
|
u32 reserved3;
|
||||||
|
}
|
||||||
static RTCCLOCKDATA rtcClockData;
|
RTCCLOCKDATA;
|
||||||
static bool rtcEnabled = false;
|
|
||||||
|
static RTCCLOCKDATA rtcClockData;
|
||||||
void rtcEnable(bool e)
|
static bool rtcEnabled = false;
|
||||||
{
|
|
||||||
rtcEnabled = e;
|
void rtcEnable(bool e)
|
||||||
}
|
{
|
||||||
|
rtcEnabled = e;
|
||||||
bool rtcIsEnabled()
|
}
|
||||||
{
|
|
||||||
return rtcEnabled;
|
bool rtcIsEnabled()
|
||||||
}
|
{
|
||||||
|
return rtcEnabled;
|
||||||
u16 rtcRead(u32 address)
|
}
|
||||||
{
|
|
||||||
if(rtcEnabled) {
|
u16 rtcRead(u32 address)
|
||||||
switch(address){
|
{
|
||||||
case 0x80000c8:
|
if(rtcEnabled)
|
||||||
return rtcClockData.byte2;
|
{
|
||||||
break;
|
if(address == 0x80000c8)
|
||||||
case 0x80000c6:
|
return rtcClockData.byte2;
|
||||||
return rtcClockData.byte1;
|
else if(address == 0x80000c6)
|
||||||
break;
|
return rtcClockData.byte1;
|
||||||
case 0x80000c4:
|
else if(address == 0x80000c4)
|
||||||
return rtcClockData.byte0;
|
{
|
||||||
break;
|
return rtcClockData.byte0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#ifdef USE_VM
|
|
||||||
return VMRead16( address & 0x1FFFFFE );
|
//return READ16LE((&rom[address & 0x1FFFFFE]));
|
||||||
#else
|
return VMRead16( address & 0x1FFFFFE );
|
||||||
return READ16LE((&rom[address & 0x1FFFFFE]));
|
}
|
||||||
#endif
|
|
||||||
}
|
static u8 toBCD(u8 value)
|
||||||
|
{
|
||||||
static u8 toBCD(u8 value)
|
value = value % 100;
|
||||||
{
|
int l = value % 10;
|
||||||
value = value % 100;
|
int h = value / 10;
|
||||||
int l = value % 10;
|
return h * 16 + l;
|
||||||
int h = value / 10;
|
}
|
||||||
return h * 16 + l;
|
|
||||||
}
|
bool rtcWrite(u32 address, u16 value)
|
||||||
|
{
|
||||||
bool rtcWrite(u32 address, u16 value)
|
if(!rtcEnabled)
|
||||||
{
|
return false;
|
||||||
if(!rtcEnabled)
|
|
||||||
return false;
|
if(address == 0x80000c8)
|
||||||
|
{
|
||||||
if(address == 0x80000c8) {
|
rtcClockData.byte2 = (u8)value; // enable ?
|
||||||
rtcClockData.byte2 = (u8)value; // enable ?
|
}
|
||||||
} else if(address == 0x80000c6) {
|
else if(address == 0x80000c6)
|
||||||
rtcClockData.byte1 = (u8)value; // read/write
|
{
|
||||||
} else if(address == 0x80000c4) {
|
rtcClockData.byte1 = (u8)value; // read/write
|
||||||
if(rtcClockData.byte2 & 1) {
|
}
|
||||||
if(rtcClockData.state == IDLE && rtcClockData.byte0 == 1 && value == 5) {
|
else if(address == 0x80000c4)
|
||||||
rtcClockData.state = COMMAND;
|
{
|
||||||
rtcClockData.bits = 0;
|
if(rtcClockData.byte2 & 1)
|
||||||
rtcClockData.command = 0;
|
{
|
||||||
} else if(!(rtcClockData.byte0 & 1) && (value & 1)) { // bit transfer
|
if(rtcClockData.state == IDLE && rtcClockData.byte0 == 1 && value == 5)
|
||||||
rtcClockData.byte0 = (u8)value;
|
{
|
||||||
switch(rtcClockData.state) {
|
rtcClockData.state = COMMAND;
|
||||||
case COMMAND:
|
rtcClockData.bits = 0;
|
||||||
rtcClockData.command |= ((value & 2) >> 1) << (7-rtcClockData.bits);
|
rtcClockData.command = 0;
|
||||||
rtcClockData.bits++;
|
}
|
||||||
if(rtcClockData.bits == 8) {
|
else if(!(rtcClockData.byte0 & 1) && (value & 1))
|
||||||
rtcClockData.bits = 0;
|
{ // bit transfer
|
||||||
switch(rtcClockData.command) {
|
rtcClockData.byte0 = (u8)value;
|
||||||
case 0x60:
|
switch(rtcClockData.state)
|
||||||
// not sure what this command does but it doesn't take parameters
|
{
|
||||||
// maybe it is a reset or stop
|
case COMMAND:
|
||||||
rtcClockData.state = IDLE;
|
rtcClockData.command |= ((value & 2) >> 1) << (7-rtcClockData.bits);
|
||||||
rtcClockData.bits = 0;
|
rtcClockData.bits++;
|
||||||
break;
|
if(rtcClockData.bits == 8)
|
||||||
case 0x62:
|
{
|
||||||
// this sets the control state but not sure what those values are
|
rtcClockData.bits = 0;
|
||||||
rtcClockData.state = READDATA;
|
switch(rtcClockData.command)
|
||||||
rtcClockData.dataLen = 1;
|
{
|
||||||
break;
|
case 0x60:
|
||||||
case 0x63:
|
// not sure what this command does but it doesn't take parameters
|
||||||
rtcClockData.dataLen = 1;
|
// maybe it is a reset or stop
|
||||||
rtcClockData.data[0] = 0x40;
|
rtcClockData.state = IDLE;
|
||||||
rtcClockData.state = DATA;
|
rtcClockData.bits = 0;
|
||||||
break;
|
break;
|
||||||
case 0x64:
|
case 0x62:
|
||||||
break;
|
// this sets the control state but not sure what those values are
|
||||||
case 0x65:
|
rtcClockData.state = READDATA;
|
||||||
{
|
rtcClockData.dataLen = 1;
|
||||||
struct tm *newtime;
|
break;
|
||||||
time_t long_time;
|
case 0x63:
|
||||||
|
rtcClockData.dataLen = 1;
|
||||||
time( &long_time ); /* Get time as long integer. */
|
rtcClockData.data[0] = 0x40;
|
||||||
newtime = localtime( &long_time ); /* Convert to local time. */
|
rtcClockData.state = DATA;
|
||||||
|
break;
|
||||||
rtcClockData.dataLen = 7;
|
case 0x65:
|
||||||
rtcClockData.data[0] = toBCD(newtime->tm_year);
|
{
|
||||||
rtcClockData.data[1] = toBCD(newtime->tm_mon+1);
|
struct tm *newtime;
|
||||||
rtcClockData.data[2] = toBCD(newtime->tm_mday);
|
time_t long_time;
|
||||||
rtcClockData.data[3] = toBCD(newtime->tm_wday);
|
|
||||||
rtcClockData.data[4] = toBCD(newtime->tm_hour);
|
time( &long_time ); /* Get time as long integer. */
|
||||||
rtcClockData.data[5] = toBCD(newtime->tm_min);
|
newtime = localtime( &long_time ); /* Convert to local time. */
|
||||||
rtcClockData.data[6] = toBCD(newtime->tm_sec);
|
|
||||||
rtcClockData.state = DATA;
|
rtcClockData.dataLen = 7;
|
||||||
}
|
rtcClockData.data[0] = toBCD(newtime->tm_year);
|
||||||
break;
|
rtcClockData.data[1] = toBCD(newtime->tm_mon+1);
|
||||||
case 0x67:
|
rtcClockData.data[2] = toBCD(newtime->tm_mday);
|
||||||
{
|
rtcClockData.data[3] = 0;
|
||||||
struct tm *newtime;
|
rtcClockData.data[4] = toBCD(newtime->tm_hour);
|
||||||
time_t long_time;
|
rtcClockData.data[5] = toBCD(newtime->tm_min);
|
||||||
|
rtcClockData.data[6] = toBCD(newtime->tm_sec);
|
||||||
time( &long_time ); /* Get time as long integer. */
|
rtcClockData.state = DATA;
|
||||||
newtime = localtime( &long_time ); /* Convert to local time. */
|
}
|
||||||
|
break;
|
||||||
rtcClockData.dataLen = 3;
|
case 0x67:
|
||||||
rtcClockData.data[0] = toBCD(newtime->tm_hour);
|
{
|
||||||
rtcClockData.data[1] = toBCD(newtime->tm_min);
|
struct tm *newtime;
|
||||||
rtcClockData.data[2] = toBCD(newtime->tm_sec);
|
time_t long_time;
|
||||||
rtcClockData.state = DATA;
|
|
||||||
}
|
time( &long_time ); /* Get time as long integer. */
|
||||||
break;
|
newtime = localtime( &long_time ); /* Convert to local time. */
|
||||||
default:
|
|
||||||
systemMessage(0, N_("Unknown RTC command %02x"), rtcClockData.command);
|
rtcClockData.dataLen = 3;
|
||||||
rtcClockData.state = IDLE;
|
rtcClockData.data[0] = toBCD(newtime->tm_hour);
|
||||||
break;
|
rtcClockData.data[1] = toBCD(newtime->tm_min);
|
||||||
}
|
rtcClockData.data[2] = toBCD(newtime->tm_sec);
|
||||||
}
|
rtcClockData.state = DATA;
|
||||||
break;
|
}
|
||||||
case DATA:
|
break;
|
||||||
if(rtcClockData.byte1 & 2) {
|
default:
|
||||||
} else {
|
systemMessage(0, N_("Unknown RTC command %02x"), rtcClockData.command);
|
||||||
rtcClockData.byte0 = (rtcClockData.byte0 & ~2) |
|
rtcClockData.state = IDLE;
|
||||||
((rtcClockData.data[rtcClockData.bits >> 3] >>
|
break;
|
||||||
(rtcClockData.bits & 7)) & 1)*2;
|
}
|
||||||
rtcClockData.bits++;
|
}
|
||||||
if(rtcClockData.bits == 8*rtcClockData.dataLen) {
|
break;
|
||||||
rtcClockData.bits = 0;
|
case DATA:
|
||||||
rtcClockData.state = IDLE;
|
if(rtcClockData.byte1 & 2)
|
||||||
}
|
{}
|
||||||
}
|
else
|
||||||
break;
|
{
|
||||||
case READDATA:
|
rtcClockData.byte0 = (rtcClockData.byte0 & ~2) |
|
||||||
if(!(rtcClockData.byte1 & 2)) {
|
((rtcClockData.data[rtcClockData.bits >> 3] >>
|
||||||
} else {
|
(rtcClockData.bits & 7)) & 1)*2;
|
||||||
rtcClockData.data[rtcClockData.bits >> 3] =
|
rtcClockData.bits++;
|
||||||
(rtcClockData.data[rtcClockData.bits >> 3] >> 1) |
|
if(rtcClockData.bits == 8*rtcClockData.dataLen)
|
||||||
((value << 6) & 128);
|
{
|
||||||
rtcClockData.bits++;
|
rtcClockData.bits = 0;
|
||||||
if(rtcClockData.bits == 8*rtcClockData.dataLen) {
|
rtcClockData.state = IDLE;
|
||||||
rtcClockData.bits = 0;
|
}
|
||||||
rtcClockData.state = IDLE;
|
}
|
||||||
}
|
break;
|
||||||
}
|
case READDATA:
|
||||||
break;
|
if(!(rtcClockData.byte1 & 2))
|
||||||
default:
|
{}
|
||||||
break;
|
else
|
||||||
}
|
{
|
||||||
} else
|
rtcClockData.data[rtcClockData.bits >> 3] =
|
||||||
rtcClockData.byte0 = (u8)value;
|
(rtcClockData.data[rtcClockData.bits >> 3] >> 1) |
|
||||||
}
|
((value << 6) & 128);
|
||||||
}
|
rtcClockData.bits++;
|
||||||
return true;
|
if(rtcClockData.bits == 8*rtcClockData.dataLen)
|
||||||
}
|
{
|
||||||
|
rtcClockData.bits = 0;
|
||||||
void rtcReset()
|
rtcClockData.state = IDLE;
|
||||||
{
|
}
|
||||||
memset(&rtcClockData, 0, sizeof(rtcClockData));
|
}
|
||||||
|
break;
|
||||||
rtcClockData.byte0 = 0;
|
default:
|
||||||
rtcClockData.byte1 = 0;
|
break;
|
||||||
rtcClockData.byte2 = 0;
|
}
|
||||||
rtcClockData.command = 0;
|
}
|
||||||
rtcClockData.dataLen = 0;
|
else
|
||||||
rtcClockData.bits = 0;
|
rtcClockData.byte0 = (u8)value;
|
||||||
rtcClockData.state = IDLE;
|
}
|
||||||
}
|
}
|
||||||
|
return true;
|
||||||
void rtcSaveGame(gzFile gzFile)
|
}
|
||||||
{
|
|
||||||
utilGzWrite(gzFile, &rtcClockData, sizeof(rtcClockData));
|
void rtcReset()
|
||||||
}
|
{
|
||||||
|
memset(&rtcClockData, 0, sizeof(rtcClockData));
|
||||||
void rtcReadGame(gzFile gzFile)
|
|
||||||
{
|
rtcClockData.byte0 = 0;
|
||||||
utilGzRead(gzFile, &rtcClockData, sizeof(rtcClockData));
|
rtcClockData.byte1 = 0;
|
||||||
}
|
rtcClockData.byte2 = 0;
|
||||||
|
rtcClockData.command = 0;
|
||||||
|
rtcClockData.dataLen = 0;
|
||||||
|
rtcClockData.bits = 0;
|
||||||
|
rtcClockData.state = IDLE;
|
||||||
|
}
|
||||||
|
|
||||||
|
void rtcSaveGame(gzFile gzFile)
|
||||||
|
{
|
||||||
|
utilGzWrite(gzFile, &rtcClockData, sizeof(rtcClockData));
|
||||||
|
}
|
||||||
|
|
||||||
|
void rtcReadGame(gzFile gzFile)
|
||||||
|
{
|
||||||
|
utilGzRead(gzFile, &rtcClockData, sizeof(rtcClockData));
|
||||||
|
}
|
||||||
|
@ -1,31 +1,31 @@
|
|||||||
// -*- C++ -*-
|
// -*- C++ -*-
|
||||||
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
|
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
|
||||||
// Copyright (C) 1999-2003 Forgotten
|
// Copyright (C) 1999-2003 Forgotten
|
||||||
// Copyright (C) 2004 Forgotten and the VBA development team
|
// Copyright (C) 2004 Forgotten and the VBA development team
|
||||||
|
|
||||||
// This program is free software; you can redistribute it and/or modify
|
// This program is free software; you can redistribute it and/or modify
|
||||||
// it under the terms of the GNU General Public License as published by
|
// it under the terms of the GNU General Public License as published by
|
||||||
// the Free Software Foundation; either version 2, or(at your option)
|
// the Free Software Foundation; either version 2, or(at your option)
|
||||||
// any later version.
|
// any later version.
|
||||||
//
|
//
|
||||||
// This program is distributed in the hope that it will be useful,
|
// This program is distributed in the hope that it will be useful,
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
// GNU General Public License for more details.
|
// GNU General Public License for more details.
|
||||||
//
|
//
|
||||||
// You should have received a copy of the GNU General Public License
|
// You should have received a copy of the GNU General Public License
|
||||||
// along with this program; if not, write to the Free Software Foundation,
|
// along with this program; if not, write to the Free Software Foundation,
|
||||||
// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
#ifndef VBA_RTC_H
|
#ifndef VBA_RTC_H
|
||||||
#define VBA_RTC_H
|
#define VBA_RTC_H
|
||||||
extern u16 rtcRead(u32 address);
|
extern u16 rtcRead(u32 address);
|
||||||
extern bool rtcWrite(u32 address, u16 value);
|
extern bool rtcWrite(u32 address, u16 value);
|
||||||
extern void rtcEnable(bool);
|
extern void rtcEnable(bool);
|
||||||
extern bool rtcIsEnabled();
|
extern bool rtcIsEnabled();
|
||||||
extern void rtcReset();
|
extern void rtcReset();
|
||||||
|
|
||||||
extern void rtcReadGame(gzFile gzFile);
|
extern void rtcReadGame(gzFile gzFile);
|
||||||
extern void rtcSaveGame(gzFile gzFile);
|
extern void rtcSaveGame(gzFile gzFile);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
1928
source/vba/Sound.cpp
1928
source/vba/Sound.cpp
File diff suppressed because it is too large
Load Diff
@ -1,84 +1,82 @@
|
|||||||
// -*- C++ -*-
|
// -*- C++ -*-
|
||||||
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
|
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
|
||||||
// Copyright (C) 1999-2003 Forgotten
|
// Copyright (C) 1999-2003 Forgotten
|
||||||
// Copyright (C) 2004 Forgotten and the VBA development team
|
// Copyright (C) 2004 Forgotten and the VBA development team
|
||||||
// Copyright (C) 2004-2006 VBA development team
|
|
||||||
|
// This program is free software; you can redistribute it and/or modify
|
||||||
// This program is free software; you can redistribute it and/or modify
|
// it under the terms of the GNU General Public License as published by
|
||||||
// it under the terms of the GNU General Public License as published by
|
// the Free Software Foundation; either version 2, or(at your option)
|
||||||
// the Free Software Foundation; either version 2, or(at your option)
|
// any later version.
|
||||||
// any later version.
|
//
|
||||||
//
|
// This program is distributed in the hope that it will be useful,
|
||||||
// This program is distributed in the hope that it will be useful,
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
// GNU General Public License for more details.
|
||||||
// GNU General Public License for more details.
|
//
|
||||||
//
|
// You should have received a copy of the GNU General Public License
|
||||||
// You should have received a copy of the GNU General Public License
|
// along with this program; if not, write to the Free Software Foundation,
|
||||||
// along with this program; if not, write to the Free Software Foundation,
|
// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
||||||
|
#ifndef VBA_SOUND_H
|
||||||
#ifndef VBA_SOUND_H
|
#define VBA_SOUND_H
|
||||||
#define VBA_SOUND_H
|
|
||||||
|
#define NR10 0x60
|
||||||
#include "System.h"
|
#define NR11 0x62
|
||||||
|
#define NR12 0x63
|
||||||
#define NR10 0x60
|
#define NR13 0x64
|
||||||
#define NR11 0x62
|
#define NR14 0x65
|
||||||
#define NR12 0x63
|
#define NR21 0x68
|
||||||
#define NR13 0x64
|
#define NR22 0x69
|
||||||
#define NR14 0x65
|
#define NR23 0x6c
|
||||||
#define NR21 0x68
|
#define NR24 0x6d
|
||||||
#define NR22 0x69
|
#define NR30 0x70
|
||||||
#define NR23 0x6c
|
#define NR31 0x72
|
||||||
#define NR24 0x6d
|
#define NR32 0x73
|
||||||
#define NR30 0x70
|
#define NR33 0x74
|
||||||
#define NR31 0x72
|
#define NR34 0x75
|
||||||
#define NR32 0x73
|
#define NR41 0x78
|
||||||
#define NR33 0x74
|
#define NR42 0x79
|
||||||
#define NR34 0x75
|
#define NR43 0x7c
|
||||||
#define NR41 0x78
|
#define NR44 0x7d
|
||||||
#define NR42 0x79
|
#define NR50 0x80
|
||||||
#define NR43 0x7c
|
#define NR51 0x81
|
||||||
#define NR44 0x7d
|
#define NR52 0x84
|
||||||
#define NR50 0x80
|
#define SGCNT0_H 0x82
|
||||||
#define NR51 0x81
|
#define FIFOA_L 0xa0
|
||||||
#define NR52 0x84
|
#define FIFOA_H 0xa2
|
||||||
#define SGCNT0_H 0x82
|
#define FIFOB_L 0xa4
|
||||||
#define FIFOA_L 0xa0
|
#define FIFOB_H 0xa6
|
||||||
#define FIFOA_H 0xa2
|
|
||||||
#define FIFOB_L 0xa4
|
extern void soundTick();
|
||||||
#define FIFOB_H 0xa6
|
extern void soundShutdown();
|
||||||
|
extern bool soundInit();
|
||||||
void soundTick();
|
extern void soundPause();
|
||||||
void soundShutdown();
|
extern void soundResume();
|
||||||
bool soundInit();
|
extern void soundEnable(int);
|
||||||
void soundPause();
|
extern void soundDisable(int);
|
||||||
void soundResume();
|
extern int soundGetEnable();
|
||||||
void soundEnable(int);
|
extern void soundReset();
|
||||||
void soundDisable(int);
|
extern void soundSaveGame(gzFile);
|
||||||
int soundGetEnable();
|
extern void soundReadGame(gzFile, int);
|
||||||
void soundReset();
|
extern void soundEvent(u32, u8);
|
||||||
void soundSaveGame(gzFile);
|
extern void soundEvent(u32, u16);
|
||||||
void soundReadGame(gzFile, int);
|
extern void soundTimerOverflow(int);
|
||||||
void soundEvent(u32, u8);
|
extern void soundSetQuality(int);
|
||||||
void soundEvent(u32, u16);
|
|
||||||
void soundTimerOverflow(int);
|
//extern int SOUND_TICKS;
|
||||||
void soundSetQuality(int);
|
extern int SOUND_CLOCK_TICKS;
|
||||||
|
extern int soundTicks;
|
||||||
extern int SOUND_CLOCK_TICKS;
|
extern int soundPaused;
|
||||||
extern int soundTicks;
|
extern bool soundOffFlag;
|
||||||
extern int soundPaused;
|
extern int soundQuality;
|
||||||
extern bool soundOffFlag;
|
extern int soundBufferLen;
|
||||||
extern int soundQuality;
|
extern int soundBufferTotalLen;
|
||||||
extern int soundBufferLen;
|
extern u32 soundNextPosition;
|
||||||
extern int soundBufferTotalLen;
|
extern u16 soundFinalWave[1470];
|
||||||
extern u32 soundNextPosition;
|
extern int soundVolume;
|
||||||
extern u16 soundFinalWave[1470];
|
|
||||||
extern int soundVolume;
|
extern bool soundEcho;
|
||||||
|
extern bool soundLowPass;
|
||||||
extern bool soundEcho;
|
extern bool soundReverse;
|
||||||
extern bool soundLowPass;
|
|
||||||
extern bool soundReverse;
|
#endif // VBA_SOUND_H
|
||||||
|
|
||||||
#endif // VBA_SOUND_H
|
|
||||||
|
@ -1,39 +1,32 @@
|
|||||||
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
|
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
|
||||||
// Copyright (C) 1999-2003 Forgotten
|
// Copyright (C) 1999-2003 Forgotten
|
||||||
// Copyright (C) 2004 Forgotten and the VBA development team
|
// Copyright (C) 2004 Forgotten and the VBA development team
|
||||||
|
|
||||||
// This program is free software; you can redistribute it and/or modify
|
// This program is free software; you can redistribute it and/or modify
|
||||||
// it under the terms of the GNU General Public License as published by
|
// it under the terms of the GNU General Public License as published by
|
||||||
// the Free Software Foundation; either version 2, or(at your option)
|
// the Free Software Foundation; either version 2, or(at your option)
|
||||||
// any later version.
|
// any later version.
|
||||||
//
|
//
|
||||||
// This program is distributed in the hope that it will be useful,
|
// This program is distributed in the hope that it will be useful,
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
// GNU General Public License for more details.
|
// GNU General Public License for more details.
|
||||||
//
|
//
|
||||||
// You should have received a copy of the GNU General Public License
|
// You should have received a copy of the GNU General Public License
|
||||||
// along with this program; if not, write to the Free Software Foundation,
|
// along with this program; if not, write to the Free Software Foundation,
|
||||||
// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
#include "agb/GBA.h"
|
#include "GBA.h"
|
||||||
#include "Globals.h"
|
#include "Flash.h"
|
||||||
#include "Flash.h"
|
#include "Sram.h"
|
||||||
#include "Sram.h"
|
|
||||||
|
u8 sramRead(u32 address)
|
||||||
u8 sramRead(u32 address)
|
{
|
||||||
{
|
return flashSaveMemory[address & 0xFFFF];
|
||||||
return flashSaveMemory[address & 0xFFFF];
|
}
|
||||||
}
|
|
||||||
void sramDelayedWrite(u32 address, u8 byte)
|
void sramWrite(u32 address, u8 byte)
|
||||||
{
|
{
|
||||||
saveType = 1;
|
flashSaveMemory[address & 0xFFFF] = byte;
|
||||||
cpuSaveGameFunc = sramWrite;
|
systemSaveUpdateCounter = SYSTEM_SAVE_UPDATED;
|
||||||
sramWrite(address, byte);
|
}
|
||||||
}
|
|
||||||
|
|
||||||
void sramWrite(u32 address, u8 byte)
|
|
||||||
{
|
|
||||||
flashSaveMemory[address & 0xFFFF] = byte;
|
|
||||||
systemSaveUpdateCounter = SYSTEM_SAVE_UPDATED;
|
|
||||||
}
|
|
||||||
|
@ -1,27 +1,26 @@
|
|||||||
// -*- C++ -*-
|
// -*- C++ -*-
|
||||||
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
|
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
|
||||||
// Copyright (C) 1999-2003 Forgotten
|
// Copyright (C) 1999-2003 Forgotten
|
||||||
// Copyright (C) 2004 Forgotten and the VBA development team
|
// Copyright (C) 2004 Forgotten and the VBA development team
|
||||||
|
|
||||||
// This program is free software; you can redistribute it and/or modify
|
// This program is free software; you can redistribute it and/or modify
|
||||||
// it under the terms of the GNU General Public License as published by
|
// it under the terms of the GNU General Public License as published by
|
||||||
// the Free Software Foundation; either version 2, or(at your option)
|
// the Free Software Foundation; either version 2, or(at your option)
|
||||||
// any later version.
|
// any later version.
|
||||||
//
|
//
|
||||||
// This program is distributed in the hope that it will be useful,
|
// This program is distributed in the hope that it will be useful,
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
// GNU General Public License for more details.
|
// GNU General Public License for more details.
|
||||||
//
|
//
|
||||||
// You should have received a copy of the GNU General Public License
|
// You should have received a copy of the GNU General Public License
|
||||||
// along with this program; if not, write to the Free Software Foundation,
|
// along with this program; if not, write to the Free Software Foundation,
|
||||||
// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
#ifndef VBA_SRAM_H
|
#ifndef VBA_SRAM_H
|
||||||
#define VBA_SRAM_H
|
#define VBA_SRAM_H
|
||||||
|
|
||||||
extern u8 sramRead(u32 address);
|
extern u8 sramRead(u32 address);
|
||||||
extern void sramWrite(u32 address, u8 byte);
|
extern void sramWrite(u32 address, u8 byte);
|
||||||
extern void sramDelayedWrite(u32 address, u8 byte);
|
|
||||||
|
#endif // VBA_SRAM_H
|
||||||
#endif // VBA_SRAM_H
|
|
||||||
|
@ -1,135 +1,127 @@
|
|||||||
// -*- C++ -*-
|
// -*- C++ -*-
|
||||||
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
|
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
|
||||||
// Copyright (C) 1999-2003 Forgotten
|
// Copyright (C) 1999-2003 Forgotten
|
||||||
// Copyright (C) 2004 Forgotten and the VBA development team
|
// Copyright (C) 2004 Forgotten and the VBA development team
|
||||||
|
|
||||||
// This program is free software; you can redistribute it and/or modify
|
// This program is free software; you can redistribute it and/or modify
|
||||||
// it under the terms of the GNU General Public License as published by
|
// it under the terms of the GNU General Public License as published by
|
||||||
// the Free Software Foundation; either version 2, or(at your option)
|
// the Free Software Foundation; either version 2, or(at your option)
|
||||||
// any later version.
|
// any later version.
|
||||||
//
|
//
|
||||||
// This program is distributed in the hope that it will be useful,
|
// This program is distributed in the hope that it will be useful,
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
// GNU General Public License for more details.
|
// GNU General Public License for more details.
|
||||||
//
|
//
|
||||||
// You should have received a copy of the GNU General Public License
|
// You should have received a copy of the GNU General Public License
|
||||||
// along with this program; if not, write to the Free Software Foundation,
|
// along with this program; if not, write to the Free Software Foundation,
|
||||||
// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
#ifndef VBA_SYSTEM_H
|
#ifndef VBA_SYSTEM_H
|
||||||
#define VBA_SYSTEM_H
|
#define VBA_SYSTEM_H
|
||||||
|
|
||||||
#include <stdint.h>
|
#include "unzip.h"
|
||||||
#include "unzip.h"
|
|
||||||
|
#ifndef NULL
|
||||||
#ifndef NULL
|
#define NULL 0
|
||||||
#define NULL 0
|
#endif
|
||||||
#endif
|
|
||||||
|
typedef unsigned char u8;
|
||||||
|
typedef unsigned short u16;
|
||||||
typedef uint8_t u8;
|
typedef unsigned int u32;
|
||||||
typedef uint16_t u16;
|
|
||||||
typedef uint32_t u32;
|
#ifdef _MSC_VER
|
||||||
typedef uint64_t u64;
|
typedef unsigned __int64 u64;
|
||||||
|
#else
|
||||||
typedef int8_t s8;
|
typedef unsigned long long u64;
|
||||||
typedef int16_t s16;
|
#endif
|
||||||
typedef int32_t s32;
|
|
||||||
typedef int64_t s64;
|
typedef signed char s8;
|
||||||
|
typedef signed short s16;
|
||||||
|
typedef signed int s32;
|
||||||
|
|
||||||
typedef unsigned char u8;
|
#ifdef _MSC_VER
|
||||||
typedef unsigned short u16;
|
typedef signed __int64 s64;
|
||||||
typedef unsigned int u32;
|
#else
|
||||||
|
typedef signed long long s64;
|
||||||
struct EmulatedSystem {
|
#endif
|
||||||
// main emulation function
|
|
||||||
void (*emuMain)(int);
|
struct EmulatedSystem
|
||||||
// reset emulator
|
{
|
||||||
void (*emuReset)();
|
// main emulation function
|
||||||
// clean up memory
|
void (*emuMain)(int);
|
||||||
void (*emuCleanUp)();
|
// reset emulator
|
||||||
// load battery file
|
void (*emuReset)();
|
||||||
bool (*emuReadBattery)(const char *);
|
// clean up memory
|
||||||
// write battery file
|
void (*emuCleanUp)();
|
||||||
bool (*emuWriteBattery)(const char *);
|
// load battery file
|
||||||
// load state
|
bool (*emuReadBattery)(const char *);
|
||||||
bool (*emuReadState)(const char *);
|
// write battery file
|
||||||
// save state
|
bool (*emuWriteBattery)(const char *);
|
||||||
bool (*emuWriteState)(const char *);
|
// load state
|
||||||
// load memory state (rewind)
|
bool (*emuReadState)(const char *);
|
||||||
bool (*emuReadMemState)(char *, int);
|
// save state
|
||||||
// write memory state (rewind)
|
bool (*emuWriteState)(const char *);
|
||||||
bool (*emuWriteMemState)(char *, int);
|
// load memory state (rewind)
|
||||||
// write PNG file
|
bool (*emuReadMemState)(char *, int);
|
||||||
bool (*emuWritePNG)(const char *);
|
// write memory state (rewind)
|
||||||
// write BMP file
|
bool (*emuWriteMemState)(char *, int);
|
||||||
bool (*emuWriteBMP)(const char *);
|
// write PNG file
|
||||||
// emulator update CPSR (ARM only)
|
bool (*emuWritePNG)(const char *);
|
||||||
void (*emuUpdateCPSR)();
|
// write BMP file
|
||||||
// emulator has debugger
|
bool (*emuWriteBMP)(const char *);
|
||||||
bool emuHasDebugger;
|
// emulator update CPSR (ARM only)
|
||||||
// clock ticks to emulate
|
void (*emuUpdateCPSR)();
|
||||||
int emuCount;
|
// emulator has debugger
|
||||||
};
|
bool emuHasDebugger;
|
||||||
|
// clock ticks to emulate
|
||||||
extern void log(const char *,...);
|
int emuCount;
|
||||||
|
};
|
||||||
extern bool systemPauseOnFrame();
|
|
||||||
extern void systemGbPrint(u8 *,int,int,int,int);
|
extern void log(const char *,...);
|
||||||
extern void systemScreenCapture(int);
|
|
||||||
extern void systemDrawScreen();
|
extern bool systemPauseOnFrame();
|
||||||
// updates the joystick data
|
extern void systemGbPrint(u8 *,int,int,int,int);
|
||||||
extern bool systemReadJoypads();
|
extern void systemScreenCapture(int);
|
||||||
// return information about the given joystick, -1 for default joystick
|
extern void systemDrawScreen();
|
||||||
extern u32 systemReadJoypad(int);
|
// updates the joystick data
|
||||||
extern u32 systemGetClock();
|
extern bool systemReadJoypads();
|
||||||
extern void systemMessage(int, const char *, ...);
|
// return information about the given joystick, -1 for default joystick
|
||||||
extern void systemSetTitle(const char *);
|
extern u32 systemReadJoypad(int);
|
||||||
extern void systemWriteDataToSoundBuffer();
|
extern u32 systemGetClock();
|
||||||
extern void systemSoundShutdown();
|
extern void systemMessage(int, const char *, ...);
|
||||||
extern void systemSoundPause();
|
extern void systemSetTitle(const char *);
|
||||||
extern void systemSoundResume();
|
extern void systemWriteDataToSoundBuffer();
|
||||||
extern void systemSoundReset();
|
extern void systemSoundShutdown();
|
||||||
extern bool systemSoundInit();
|
extern void systemSoundPause();
|
||||||
extern void systemScreenMessage(const char *);
|
extern void systemSoundResume();
|
||||||
extern void systemUpdateMotionSensor();
|
extern void systemSoundReset();
|
||||||
extern int systemGetSensorX();
|
extern bool systemSoundInit();
|
||||||
extern int systemGetSensorY();
|
extern void systemScreenMessage(const char *);
|
||||||
extern bool systemCanChangeSoundQuality();
|
extern void systemUpdateMotionSensor();
|
||||||
extern void systemShowSpeed(int);
|
extern int systemGetSensorX();
|
||||||
extern void system10Frames(int);
|
extern int systemGetSensorY();
|
||||||
extern void systemFrame();
|
extern bool systemCanChangeSoundQuality();
|
||||||
extern void systemGbBorderOn();
|
extern void systemShowSpeed(int);
|
||||||
|
extern void system10Frames(int);
|
||||||
extern void Sm60FPS_Init();
|
extern void systemFrame();
|
||||||
extern bool Sm60FPS_CanSkipFrame();
|
extern void systemGbBorderOn();
|
||||||
extern void Sm60FPS_Sleep();
|
|
||||||
extern void DbgMsg(const char *msg, ...);
|
extern bool systemSoundOn;
|
||||||
extern void winlog(const char *,...);
|
extern u16 systemColorMap16[0x10000];
|
||||||
|
//extern u32 systemColorMap32[0x10000];
|
||||||
extern void (*dbgOutput)(const char *s, u32 addr);
|
extern u32 *systemColorMap32;
|
||||||
extern void (*dbgSignal)(int sig,int number);
|
extern u16 systemGbPalette[24];
|
||||||
|
extern int systemRedShift;
|
||||||
extern bool systemSoundOn; // old sound system
|
extern int systemGreenShift;
|
||||||
extern u16 systemColorMap16[0x10000];
|
extern int systemBlueShift;
|
||||||
//extern u32 systemColorMap32[0x10000];
|
extern int systemColorDepth;
|
||||||
extern u32 *systemColorMap32;
|
extern int systemDebug;
|
||||||
extern u16 systemGbPalette[24];
|
extern int systemVerbose;
|
||||||
extern int systemRedShift;
|
extern int systemFrameSkip;
|
||||||
extern int systemGreenShift;
|
extern int systemSaveUpdateCounter;
|
||||||
extern int systemBlueShift;
|
|
||||||
extern int systemColorDepth;
|
#define SYSTEM_SAVE_UPDATED 30
|
||||||
extern int systemDebug;
|
#define SYSTEM_SAVE_NOT_UPDATED 0
|
||||||
extern int systemVerbose;
|
|
||||||
extern int systemFrameSkip;
|
#endif //VBA_SYSTEM_H
|
||||||
extern int systemSaveUpdateCounter;
|
|
||||||
extern int systemSpeed;
|
|
||||||
extern int systemThrottle;
|
|
||||||
|
|
||||||
#define SYSTEM_SAVE_UPDATED 30
|
|
||||||
#define SYSTEM_SAVE_NOT_UPDATED 0
|
|
||||||
|
|
||||||
#endif //VBA_SYSTEM_H
|
|
||||||
|
180
source/vba/Text.cpp
Normal file
180
source/vba/Text.cpp
Normal file
@ -0,0 +1,180 @@
|
|||||||
|
/* FCE Ultra - NES/Famicom Emulator
|
||||||
|
*
|
||||||
|
* Copyright notice for this file:
|
||||||
|
* Copyright (C) 2002 Ben Parnell
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Code originally from fceu/drawing.h file, adapted by Forgotten
|
||||||
|
*/
|
||||||
|
#include "System.h"
|
||||||
|
|
||||||
|
extern int RGB_LOW_BITS_MASK;
|
||||||
|
|
||||||
|
static const u8 fontdata2[2048] =
|
||||||
|
{
|
||||||
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7e,0x81,0xa5,0x81,0xbd,0x99,0x81,0x7e,0x7e,0xff,0xdb,0xff,0xc3,0xe7,0xff,0x7e,0x36,0x7f,0x7f,0x7f,0x3e,0x1c,0x08,0x00,0x08,0x1c,0x3e,0x7f,0x3e,0x1c,0x08,0x00,0x1c,0x3e,0x1c,0x7f,0x7f,0x3e,0x1c,0x3e,0x08,0x08,0x1c,0x3e,0x7f,0x3e,0x1c,0x3e,0x00,0x00,0x18,0x3c,0x3c,0x18,0x00,0x00,0xff,0xff,0xe7,0xc3,0xc3,0xe7,0xff,0xff,0x00,0x3c,0x66,0x42,0x42,0x66,0x3c,0x00,0xff,0xc3,0x99,0xbd,0xbd,0x99,0xc3,0xff,0xf0,0xe0,0xf0,0xbe,0x33,0x33,0x33,0x1e,0x3c,0x66,0x66,0x66,0x3c,0x18,0x7e,0x18,0xfc,0xcc,0xfc,0x0c,0x0c,0x0e,0x0f,0x07,0xfe,0xc6,0xfe,0xc6,0xc6,0xe6,0x67,0x03,0x99,0x5a,0x3c,0xe7,0xe7,0x3c,0x5a,0x99,0x01,0x07,0x1f,0x7f,0x1f,0x07,0x01,0x00,0x40,0x70,0x7c,0x7f,0x7c,0x70,0x40,0x00,0x18,0x3c,0x7e,0x18,0x18,0x7e,0x3c,0x18,0x66,0x66,0x66,0x66,0x66,0x00,0x66,0x00,0xfe,0xdb,0xdb,0xde,0xd8,0xd8,0xd8,0x00,0x7c,0xc6,0x1c,0x36,0x36,0x1c,0x33,0x1e,0x00,0x00,0x00,0x00,0x7e,0x7e,0x7e,0x00,0x18,0x3c,0x7e,0x18,0x7e,0x3c,0x18,0xff,0x18,0x3c,0x7e,0x18,0x18,0x18,0x18,0x00,0x18,0x18,0x18,0x18,0x7e,0x3c,0x18,0x00,0x00,0x18,0x30,0x7f,0x30,0x18,0x00,0x00,0x00,0x0c,0x06,0x7f,0x06,0x0c,0x00,0x00,0x00,0x00,0x03,0x03,0x03,0x7f,0x00,0x00,0x00,0x24,0x66,0xff,0x66,0x24,0x00,0x00,0x00,0x18,0x3c,0x7e,0xff,0xff,0x00,0x00,0x00,0xff,0xff,0x7e,0x3c,0x18,0x00,0x00,
|
||||||
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0c,0x1e,0x1e,0x0c,0x0c,0x00,0x0c,0x00,0x36,0x36,0x36,0x00,0x00,0x00,0x00,0x00,0x36,0x36,0x7f,0x36,0x7f,0x36,0x36,0x00,0x0c,0x3e,0x03,0x1e,0x30,0x1f,0x0c,0x00,0x00,0x63,0x33,0x18,0x0c,0x66,0x63,0x00,0x1c,0x36,0x1c,0x6e,0x3b,0x33,0x6e,0x00,0x06,0x06,0x03,0x00,0x00,0x00,0x00,0x00,0x18,0x0c,0x06,0x06,0x06,0x0c,0x18,0x00,0x06,0x0c,0x18,0x18,0x18,0x0c,0x06,0x00,0x00,0x66,0x3c,0xff,0x3c,0x66,0x00,0x00,0x00,0x0c,0x0c,0x3f,0x0c,0x0c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0c,0x0c,0x06,0x00,0x00,0x00,0x3f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0c,0x0c,0x00,0x60,0x30,0x18,0x0c,0x06,0x03,0x01,0x00,0x3e,0x63,0x73,0x7b,0x6f,0x67,0x3e,0x00,0x0c,0x0e,0x0c,0x0c,0x0c,0x0c,0x3f,0x00,0x1e,0x33,0x30,0x1c,0x06,0x33,0x3f,0x00,0x1e,0x33,0x30,0x1c,0x30,0x33,0x1e,0x00,0x38,0x3c,0x36,0x33,0x7f,0x30,0x78,0x00,0x3f,0x03,0x1f,0x30,0x30,0x33,0x1e,0x00,0x1c,0x06,0x03,0x1f,0x33,0x33,0x1e,0x00,0x3f,0x33,0x30,0x18,0x0c,0x0c,0x0c,0x00,0x1e,0x33,0x33,0x1e,0x33,0x33,0x1e,0x00,0x1e,0x33,0x33,0x3e,0x30,0x18,0x0e,0x00,0x00,0x0c,0x0c,0x00,0x00,0x0c,0x0c,0x00,0x00,0x0c,0x0c,0x00,0x00,0x0c,0x0c,0x06,0x18,0x0c,0x06,0x03,0x06,0x0c,0x18,0x00,0x00,0x00,0x3f,0x00,0x00,0x3f,0x00,0x00,0x06,0x0c,0x18,0x30,0x18,0x0c,0x06,0x00,0x1e,0x33,0x30,0x18,0x0c,0x00,0x0c,0x00,
|
||||||
|
0x3e,0x63,0x7b,0x7b,0x7b,0x03,0x1e,0x00,0x0c,0x1e,0x33,0x33,0x3f,0x33,0x33,0x00,0x3f,0x66,0x66,0x3e,0x66,0x66,0x3f,0x00,0x3c,0x66,0x03,0x03,0x03,0x66,0x3c,0x00,0x1f,0x36,0x66,0x66,0x66,0x36,0x1f,0x00,0x7f,0x46,0x16,0x1e,0x16,0x46,0x7f,0x00,0x7f,0x46,0x16,0x1e,0x16,0x06,0x0f,0x00,0x3c,0x66,0x03,0x03,0x73,0x66,0x7c,0x00,0x33,0x33,0x33,0x3f,0x33,0x33,0x33,0x00,0x1e,0x0c,0x0c,0x0c,0x0c,0x0c,0x1e,0x00,0x78,0x30,0x30,0x30,0x33,0x33,0x1e,0x00,0x67,0x66,0x36,0x1e,0x36,0x66,0x67,0x00,0x0f,0x06,0x06,0x06,0x46,0x66,0x7f,0x00,0x63,0x77,0x7f,0x7f,0x6b,0x63,0x63,0x00,0x63,0x67,0x6f,0x7b,0x73,0x63,0x63,0x00,0x1c,0x36,0x63,0x63,0x63,0x36,0x1c,0x00,0x3f,0x66,0x66,0x3e,0x06,0x06,0x0f,0x00,0x1e,0x33,0x33,0x33,0x3b,0x1e,0x38,0x00,0x3f,0x66,0x66,0x3e,0x36,0x66,0x67,0x00,0x1e,0x33,0x07,0x0e,0x38,0x33,0x1e,0x00,0x3f,0x2d,0x0c,0x0c,0x0c,0x0c,0x1e,0x00,0x33,0x33,0x33,0x33,0x33,0x33,0x3f,0x00,0x33,0x33,0x33,0x33,0x33,0x1e,0x0c,0x00,0x63,0x63,0x63,0x6b,0x7f,0x77,0x63,0x00,0x63,0x63,0x36,0x1c,0x1c,0x36,0x63,0x00,0x33,0x33,0x33,0x1e,0x0c,0x0c,0x1e,0x00,0x7f,0x63,0x31,0x18,0x4c,0x66,0x7f,0x00,0x1e,0x06,0x06,0x06,0x06,0x06,0x1e,0x00,0x03,0x06,0x0c,0x18,0x30,0x60,0x40,0x00,0x1e,0x18,0x18,0x18,0x18,0x18,0x1e,0x00,0x08,0x1c,0x36,0x63,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,
|
||||||
|
0x0c,0x0c,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1e,0x30,0x3e,0x33,0x6e,0x00,0x07,0x06,0x06,0x3e,0x66,0x66,0x3b,0x00,0x00,0x00,0x1e,0x33,0x03,0x33,0x1e,0x00,0x38,0x30,0x30,0x3e,0x33,0x33,0x6e,0x00,0x00,0x00,0x1e,0x33,0x3f,0x03,0x1e,0x00,0x1c,0x36,0x06,0x0f,0x06,0x06,0x0f,0x00,0x00,0x00,0x6e,0x33,0x33,0x3e,0x30,0x1f,0x07,0x06,0x36,0x6e,0x66,0x66,0x67,0x00,0x0c,0x00,0x0e,0x0c,0x0c,0x0c,0x1e,0x00,0x30,0x00,0x30,0x30,0x30,0x33,0x33,0x1e,0x07,0x06,0x66,0x36,0x1e,0x36,0x67,0x00,0x0e,0x0c,0x0c,0x0c,0x0c,0x0c,0x1e,0x00,0x00,0x00,0x33,0x7f,0x7f,0x6b,0x63,0x00,0x00,0x00,0x1f,0x33,0x33,0x33,0x33,0x00,0x00,0x00,0x1e,0x33,0x33,0x33,0x1e,0x00,0x00,0x00,0x3b,0x66,0x66,0x3e,0x06,0x0f,0x00,0x00,0x6e,0x33,0x33,0x3e,0x30,0x78,0x00,0x00,0x3b,0x6e,0x66,0x06,0x0f,0x00,0x00,0x00,0x3e,0x03,0x1e,0x30,0x1f,0x00,0x08,0x0c,0x3e,0x0c,0x0c,0x2c,0x18,0x00,0x00,0x00,0x33,0x33,0x33,0x33,0x6e,0x00,0x00,0x00,0x33,0x33,0x33,0x1e,0x0c,0x00,0x00,0x00,0x63,0x6b,0x7f,0x7f,0x36,0x00,0x00,0x00,0x63,0x36,0x1c,0x36,0x63,0x00,0x00,0x00,0x33,0x33,0x33,0x3e,0x30,0x1f,0x00,0x00,0x3f,0x19,0x0c,0x26,0x3f,0x00,0x38,0x0c,0x0c,0x07,0x0c,0x0c,0x38,0x00,0x18,0x18,0x18,0x00,0x18,0x18,0x18,0x00,0x07,0x0c,0x0c,0x38,0x0c,0x0c,0x07,0x00,0x6e,0x3b,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x1c,0x36,0x63,0x63,0x7f,0x00,
|
||||||
|
0x1e,0x33,0x03,0x33,0x1e,0x18,0x30,0x1e,0x00,0x33,0x00,0x33,0x33,0x33,0x7e,0x00,0x38,0x00,0x1e,0x33,0x3f,0x03,0x1e,0x00,0x7e,0xc3,0x3c,0x60,0x7c,0x66,0xfc,0x00,0x33,0x00,0x1e,0x30,0x3e,0x33,0x7e,0x00,0x07,0x00,0x1e,0x30,0x3e,0x33,0x7e,0x00,0x0c,0x0c,0x1e,0x30,0x3e,0x33,0x7e,0x00,0x00,0x00,0x1e,0x03,0x03,0x1e,0x30,0x1c,0x7e,0xc3,0x3c,0x66,0x7e,0x06,0x3c,0x00,0x33,0x00,0x1e,0x33,0x3f,0x03,0x1e,0x00,0x07,0x00,0x1e,0x33,0x3f,0x03,0x1e,0x00,0x33,0x00,0x0e,0x0c,0x0c,0x0c,0x1e,0x00,0x3e,0x63,0x1c,0x18,0x18,0x18,0x3c,0x00,0x07,0x00,0x0e,0x0c,0x0c,0x0c,0x1e,0x00,0x63,0x1c,0x36,0x63,0x7f,0x63,0x63,0x00,0x0c,0x0c,0x00,0x1e,0x33,0x3f,0x33,0x00,0x38,0x00,0x3f,0x06,0x1e,0x06,0x3f,0x00,0x00,0x00,0xfe,0x30,0xfe,0x33,0xfe,0x00,0x7c,0x36,0x33,0x7f,0x33,0x33,0x73,0x00,0x1e,0x33,0x00,0x1e,0x33,0x33,0x1e,0x00,0x00,0x33,0x00,0x1e,0x33,0x33,0x1e,0x00,0x00,0x07,0x00,0x1e,0x33,0x33,0x1e,0x00,0x1e,0x33,0x00,0x33,0x33,0x33,0x7e,0x00,0x00,0x07,0x00,0x33,0x33,0x33,0x7e,0x00,0x00,0x33,0x00,0x33,0x33,0x3e,0x30,0x1f,0xc3,0x18,0x3c,0x66,0x66,0x3c,0x18,0x00,0x33,0x00,0x33,0x33,0x33,0x33,0x1e,0x00,0x18,0x18,0x7e,0x03,0x03,0x7e,0x18,0x18,0x1c,0x36,0x26,0x0f,0x06,0x67,0x3f,0x00,0x33,0x33,0x1e,0x3f,0x0c,0x3f,0x0c,0x0c,0x1f,0x33,0x33,0x5f,0x63,0xf3,0x63,0xe3,0x70,0xd8,0x18,0x3c,0x18,0x18,0x1b,0x0e,
|
||||||
|
0x38,0x00,0x1e,0x30,0x3e,0x33,0x7e,0x00,0x1c,0x00,0x0e,0x0c,0x0c,0x0c,0x1e,0x00,0x00,0x38,0x00,0x1e,0x33,0x33,0x1e,0x00,0x00,0x38,0x00,0x33,0x33,0x33,0x7e,0x00,0x00,0x1f,0x00,0x1f,0x33,0x33,0x33,0x00,0x3f,0x00,0x33,0x37,0x3f,0x3b,0x33,0x00,0x3c,0x36,0x36,0x7c,0x00,0x7e,0x00,0x00,0x1c,0x36,0x36,0x1c,0x00,0x3e,0x00,0x00,0x0c,0x00,0x0c,0x06,0x03,0x33,0x1e,0x00,0x00,0x00,0x00,0x3f,0x03,0x03,0x00,0x00,0x00,0x00,0x00,0x3f,0x30,0x30,0x00,0x00,0xc3,0x63,0x33,0x7b,0xcc,0x66,0x33,0xf0,0xc3,0x63,0x33,0xdb,0xec,0xf6,0xf3,0xc0,0x18,0x18,0x00,0x18,0x18,0x18,0x18,0x00,0x00,0xcc,0x66,0x33,0x66,0xcc,0x00,0x00,0x00,0x33,0x66,0xcc,0x66,0x33,0x00,0x00,0x44,0x11,0x44,0x11,0x44,0x11,0x44,0x11,0xaa,0x55,0xaa,0x55,0xaa,0x55,0xaa,0x55,0xdb,0xee,0xdb,0x77,0xdb,0xee,0xdb,0x77,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x1f,0x18,0x18,0x18,0x18,0x18,0x1f,0x18,0x1f,0x18,0x18,0x18,0x6c,0x6c,0x6c,0x6c,0x6f,0x6c,0x6c,0x6c,0x00,0x00,0x00,0x00,0x7f,0x6c,0x6c,0x6c,0x00,0x00,0x1f,0x18,0x1f,0x18,0x18,0x18,0x6c,0x6c,0x6f,0x60,0x6f,0x6c,0x6c,0x6c,0x6c,0x6c,0x6c,0x6c,0x6c,0x6c,0x6c,0x6c,0x00,0x00,0x7f,0x60,0x6f,0x6c,0x6c,0x6c,0x6c,0x6c,0x6f,0x60,0x7f,0x00,0x00,0x00,0x6c,0x6c,0x6c,0x6c,0x7f,0x00,0x00,0x00,0x18,0x18,0x1f,0x18,0x1f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1f,0x18,0x18,0x18,
|
||||||
|
0x18,0x18,0x18,0x18,0xf8,0x00,0x00,0x00,0x18,0x18,0x18,0x18,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0xf8,0x18,0x18,0x18,0x00,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0x18,0x18,0x18,0x18,0xff,0x18,0x18,0x18,0x18,0x18,0xf8,0x18,0xf8,0x18,0x18,0x18,0x6c,0x6c,0x6c,0x6c,0xec,0x6c,0x6c,0x6c,0x6c,0x6c,0xec,0x0c,0xfc,0x00,0x00,0x00,0x00,0x00,0xfc,0x0c,0xec,0x6c,0x6c,0x6c,0x6c,0x6c,0xef,0x00,0xff,0x00,0x00,0x00,0x00,0x00,0xff,0x00,0xef,0x6c,0x6c,0x6c,0x6c,0x6c,0xec,0x0c,0xec,0x6c,0x6c,0x6c,0x00,0x00,0xff,0x00,0xff,0x00,0x00,0x00,0x6c,0x6c,0xef,0x00,0xef,0x6c,0x6c,0x6c,0x18,0x18,0xff,0x00,0xff,0x00,0x00,0x00,0x6c,0x6c,0x6c,0x6c,0xff,0x00,0x00,0x00,0x00,0x00,0xff,0x00,0xff,0x18,0x18,0x18,0x00,0x00,0x00,0x00,0xff,0x6c,0x6c,0x6c,0x6c,0x6c,0x6c,0x6c,0xfc,0x00,0x00,0x00,0x18,0x18,0xf8,0x18,0xf8,0x00,0x00,0x00,0x00,0x00,0xf8,0x18,0xf8,0x18,0x18,0x18,0x00,0x00,0x00,0x00,0xfc,0x6c,0x6c,0x6c,0x6c,0x6c,0x6c,0x6c,0xff,0x6c,0x6c,0x6c,0x18,0x18,0xff,0x18,0xff,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x1f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf8,0x18,0x18,0x18,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,
|
||||||
|
0x00,0x00,0x6e,0x3b,0x13,0x3b,0x6e,0x00,0x00,0x1e,0x33,0x1f,0x33,0x1f,0x03,0x03,0x00,0x3f,0x33,0x03,0x03,0x03,0x03,0x00,0x00,0x7f,0x36,0x36,0x36,0x36,0x36,0x00,0x3f,0x33,0x06,0x0c,0x06,0x33,0x3f,0x00,0x00,0x00,0x7e,0x1b,0x1b,0x1b,0x0e,0x00,0x00,0x66,0x66,0x66,0x66,0x3e,0x06,0x03,0x00,0x6e,0x3b,0x18,0x18,0x18,0x18,0x00,0x3f,0x0c,0x1e,0x33,0x33,0x1e,0x0c,0x3f,0x1c,0x36,0x63,0x7f,0x63,0x36,0x1c,0x00,0x1c,0x36,0x63,0x63,0x36,0x36,0x77,0x00,0x38,0x0c,0x18,0x3e,0x33,0x33,0x1e,0x00,0x00,0x00,0x7e,0xdb,0xdb,0x7e,0x00,0x00,0x60,0x30,0x7e,0xdb,0xdb,0x7e,0x06,0x03,0x1c,0x06,0x03,0x1f,0x03,0x06,0x1c,0x00,0x1e,0x33,0x33,0x33,0x33,0x33,0x33,0x00,0x00,0x3f,0x00,0x3f,0x00,0x3f,0x00,0x00,0x0c,0x0c,0x3f,0x0c,0x0c,0x00,0x3f,0x00,0x06,0x0c,0x18,0x0c,0x06,0x00,0x3f,0x00,0x18,0x0c,0x06,0x0c,0x18,0x00,0x3f,0x00,0x70,0xd8,0xd8,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x1b,0x1b,0x0e,0x0c,0x0c,0x00,0x3f,0x00,0x0c,0x0c,0x00,0x00,0x6e,0x3b,0x00,0x6e,0x3b,0x00,0x00,0x1c,0x36,0x36,0x1c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x00,0x00,0x00,0xf0,0x30,0x30,0x30,0x37,0x36,0x3c,0x38,0x1e,0x36,0x36,0x36,0x36,0x00,0x00,0x00,0x0e,0x18,0x0c,0x06,0x1e,0x00,0x00,0x00,0x00,0x00,0x3c,0x3c,0x3c,0x3c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
|
||||||
|
};
|
||||||
|
|
||||||
|
static void drawTextInternal(u8 *screen, int pitch, int x, int y,
|
||||||
|
const char *string, bool trans)
|
||||||
|
{
|
||||||
|
screen += y*pitch;
|
||||||
|
int inc = 2;
|
||||||
|
switch(systemColorDepth)
|
||||||
|
{
|
||||||
|
case 24:
|
||||||
|
inc = 3;
|
||||||
|
break;
|
||||||
|
case 32:
|
||||||
|
inc = 4;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
screen += x*inc;
|
||||||
|
|
||||||
|
switch(systemColorDepth)
|
||||||
|
{
|
||||||
|
case 16:
|
||||||
|
{
|
||||||
|
while(*string)
|
||||||
|
{
|
||||||
|
char c = *string++;
|
||||||
|
u8 *scr = screen;
|
||||||
|
|
||||||
|
u16 mask = ~RGB_LOW_BITS_MASK;
|
||||||
|
int h, w;
|
||||||
|
u16 *s = (u16 *)scr;
|
||||||
|
for (h = 0; h < 8; h++)
|
||||||
|
{
|
||||||
|
for (w = 0; w < 8; w++, s++)
|
||||||
|
{
|
||||||
|
int on = (fontdata2[(c<<3)+h]>>w)&1;
|
||||||
|
|
||||||
|
if(trans)
|
||||||
|
{
|
||||||
|
if(on)
|
||||||
|
*s = ((0xf) << systemRedShift) +
|
||||||
|
((*s & mask) >>1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(on)
|
||||||
|
*s = (0x1f) << systemRedShift;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
scr += pitch;
|
||||||
|
s = (u16 *)scr;
|
||||||
|
}
|
||||||
|
screen += inc*8;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 24:
|
||||||
|
{
|
||||||
|
while(*string)
|
||||||
|
{
|
||||||
|
char c = *string++;
|
||||||
|
u8 *scr = screen;
|
||||||
|
|
||||||
|
int h, w;
|
||||||
|
u8 *s = (u8 *)scr;
|
||||||
|
for (h = 0; h < 8; h++)
|
||||||
|
{
|
||||||
|
for (w = 0; w < 8; w++, s+=3)
|
||||||
|
{
|
||||||
|
int on = (fontdata2[(c<<3)+h]>>w)&1;
|
||||||
|
|
||||||
|
if(trans)
|
||||||
|
{
|
||||||
|
if(on)
|
||||||
|
{
|
||||||
|
u32 color = (0x1f) << systemRedShift;
|
||||||
|
*s = ((color & 255)>>1)+(*s>>1);
|
||||||
|
*(s+1) = (((color >> 8) & 255)>>1)+(*(s+1)>>1);
|
||||||
|
*(s+2) = (((color >> 16) & 255)>>1)+(*(s+2)>>1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(on)
|
||||||
|
{
|
||||||
|
u32 color = (0x1f) << systemRedShift;
|
||||||
|
*s = (color & 255);
|
||||||
|
*(s+1) = (color >> 8) & 255;
|
||||||
|
*(s+2) = (color >> 16) & 255;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
scr += pitch;
|
||||||
|
s = (u8 *)scr;
|
||||||
|
}
|
||||||
|
screen += inc*8;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 32:
|
||||||
|
{
|
||||||
|
while(*string)
|
||||||
|
{
|
||||||
|
char c = *string++;
|
||||||
|
u8 *scr = screen;
|
||||||
|
|
||||||
|
int h, w;
|
||||||
|
u32 mask = 0xfefefe;
|
||||||
|
u32 *s = (u32 *)scr;
|
||||||
|
for (h = 0; h < 8; h++)
|
||||||
|
{
|
||||||
|
for (w = 0; w < 8; w++, s++)
|
||||||
|
{
|
||||||
|
int on = (fontdata2[(c<<3)+h]>>w)&1;
|
||||||
|
|
||||||
|
if(trans)
|
||||||
|
{
|
||||||
|
if(on)
|
||||||
|
*s = ((0xf) << systemRedShift) + ((*s & mask)>>1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(on)
|
||||||
|
*s = (0x1f) << systemRedShift;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
scr += pitch;
|
||||||
|
s = (u32 *)scr;
|
||||||
|
}
|
||||||
|
screen += inc*8;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void drawText(u8 *screen, int pitch, int x, int y, const char *string)
|
||||||
|
{
|
||||||
|
drawTextInternal(screen, pitch, x, y, string, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
void drawTextTransp(u8 *screen, int pitch, int x, int y, const char *string)
|
||||||
|
{
|
||||||
|
drawTextInternal(screen, pitch, x, y, string, true);
|
||||||
|
}
|
21
source/vba/Text.h
Normal file
21
source/vba/Text.h
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
// -*- C++ -*-
|
||||||
|
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
|
||||||
|
// Copyright (C) 1999-2003 Forgotten
|
||||||
|
// Copyright (C) 2004 Forgotten and the VBA development team
|
||||||
|
|
||||||
|
// This program is free software; you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation; either version 2, or(at your option)
|
||||||
|
// any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with this program; if not, write to the Free Software Foundation,
|
||||||
|
// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
|
extern void drawText(u8 *, int, int, int, const char *);
|
||||||
|
extern void drawTextTransp(u8 *, int, int, int, const char *);
|
File diff suppressed because it is too large
Load Diff
@ -19,9 +19,6 @@
|
|||||||
|
|
||||||
#ifndef VBA_UTIL_H
|
#ifndef VBA_UTIL_H
|
||||||
#define VBA_UTIL_H
|
#define VBA_UTIL_H
|
||||||
|
|
||||||
#include "System.h"
|
|
||||||
|
|
||||||
enum IMAGE_TYPE {
|
enum IMAGE_TYPE {
|
||||||
IMAGE_UNKNOWN = -1,
|
IMAGE_UNKNOWN = -1,
|
||||||
IMAGE_GBA = 0,
|
IMAGE_GBA = 0,
|
||||||
@ -30,40 +27,40 @@ enum IMAGE_TYPE {
|
|||||||
|
|
||||||
// save game
|
// save game
|
||||||
|
|
||||||
typedef struct {
|
typedef struct
|
||||||
void *address;
|
{
|
||||||
int size;
|
void *address;
|
||||||
} variable_desc;
|
int size;
|
||||||
|
}
|
||||||
|
variable_desc;
|
||||||
|
|
||||||
extern int utilGetSize(int size);
|
|
||||||
extern bool utilWritePNGFile(const char *, int, int, u8 *);
|
extern bool utilWritePNGFile(const char *, int, int, u8 *);
|
||||||
extern bool utilWriteBMPFile(const char *, int, int, u8 *);
|
extern bool utilWriteBMPFile(const char *, int, int, u8 *);
|
||||||
extern void utilApplyIPS(const char *ips, u8 **rom, int *size);
|
extern void utilApplyIPS(const char *ips, u8 **rom, int *size);
|
||||||
|
extern void utilWriteBMP(char *, int, int, u8 *);
|
||||||
extern bool utilIsGBAImage(const char *);
|
extern bool utilIsGBAImage(const char *);
|
||||||
extern bool utilIsGBImage(const char *);
|
extern bool utilIsGBImage(const char *);
|
||||||
extern bool utilIsGzipFile(const char *);
|
|
||||||
extern bool utilIsZipFile(const char *);
|
extern bool utilIsZipFile(const char *);
|
||||||
extern void utilStripDoubleExtension(const char *, char *);
|
extern bool utilIsGzipFile(const char *);
|
||||||
|
extern bool utilIsRarFile(const char *);
|
||||||
|
extern void utilGetBaseName(const char *, char *);
|
||||||
extern IMAGE_TYPE utilFindType(const char *);
|
extern IMAGE_TYPE utilFindType(const char *);
|
||||||
extern u8 *utilLoad(const char *,
|
extern u8 *utilLoad(const char *,
|
||||||
bool (*)(const char*),
|
bool (*)(const char*),
|
||||||
u8 *,
|
u8 *,
|
||||||
int &);
|
int &);
|
||||||
|
|
||||||
extern void utilPutDword(u8 *, u32);
|
extern void utilPutDword(u8 *, u32);
|
||||||
extern void utilPutWord(u8 *, u16);
|
extern void utilPutWord(u8 *, u16);
|
||||||
extern void utilWriteData(gzFile, variable_desc *);
|
extern void utilWriteData(gzFile, variable_desc *);
|
||||||
extern void utilReadData(gzFile, variable_desc *);
|
extern void utilReadData(gzFile, variable_desc *);
|
||||||
extern void utilReadDataSkip(gzFile, variable_desc *);
|
|
||||||
extern int utilReadInt(gzFile);
|
extern int utilReadInt(gzFile);
|
||||||
extern void utilWriteInt(gzFile, int);
|
extern void utilWriteInt(gzFile, int);
|
||||||
extern gzFile utilGzOpen(const char *file, const char *mode);
|
extern gzFile utilGzOpen(const char *file, const char *mode);
|
||||||
extern gzFile utilMemGzOpen(char *memory, int available, const char *mode);
|
extern gzFile utilMemGzOpen(char *memory, int available, char *mode);
|
||||||
extern int utilGzWrite(gzFile file, const voidp buffer, unsigned int len);
|
extern int utilGzWrite(gzFile file, const voidp buffer, unsigned int len);
|
||||||
extern int utilGzRead(gzFile file, voidp buffer, unsigned int len);
|
extern int utilGzRead(gzFile file, voidp buffer, unsigned int len);
|
||||||
extern int utilGzClose(gzFile file);
|
extern int utilGzClose(gzFile file);
|
||||||
extern z_off_t utilGzSeek(gzFile file, z_off_t offset, int whence);
|
|
||||||
extern long utilGzMemTell(gzFile file);
|
extern long utilGzMemTell(gzFile file);
|
||||||
extern void utilGBAFindSave(const u8 *, const int);
|
extern void utilGBAFindSave(const u8 *, const int);
|
||||||
extern void utilUpdateSystemColorMaps();
|
|
||||||
#endif
|
#endif
|
||||||
|
1033
source/vba/admame.cpp
Normal file
1033
source/vba/admame.cpp
Normal file
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -1,302 +0,0 @@
|
|||||||
// -*- C++ -*-
|
|
||||||
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
|
|
||||||
// Copyright (C) 1999-2003 Forgotten
|
|
||||||
// Copyright (C) 2005 Forgotten and the VBA development team
|
|
||||||
|
|
||||||
// This program is free software; you can redistribute it and/or modify
|
|
||||||
// it under the terms of the GNU General Public License as published by
|
|
||||||
// the Free Software Foundation; either version 2, or(at your option)
|
|
||||||
// any later version.
|
|
||||||
//
|
|
||||||
// This program is distributed in the hope that it will be useful,
|
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
// GNU General Public License for more details.
|
|
||||||
//
|
|
||||||
// You should have received a copy of the GNU General Public License
|
|
||||||
// along with this program; if not, write to the Free Software Foundation,
|
|
||||||
// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
||||||
|
|
||||||
#ifndef VBA_GBAcpu_H
|
|
||||||
#define VBA_GBAcpu_H
|
|
||||||
|
|
||||||
extern int armExecute();
|
|
||||||
extern int thumbExecute();
|
|
||||||
|
|
||||||
#ifdef __GNUC__
|
|
||||||
# define INSN_REGPARM __attribute__((regparm(1)))
|
|
||||||
# define LIKELY(x) __builtin_expect(!!(x),1)
|
|
||||||
# define UNLIKELY(x) __builtin_expect(!!(x),0)
|
|
||||||
#else
|
|
||||||
# define INSN_REGPARM /*nothing*/
|
|
||||||
# define LIKELY(x) (x)
|
|
||||||
# define UNLIKELY(x) (x)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define UPDATE_REG(address, value)\
|
|
||||||
{\
|
|
||||||
WRITE16LE(((u16 *)&ioMem[address]),value);\
|
|
||||||
}\
|
|
||||||
|
|
||||||
#define ARM_PREFETCH \
|
|
||||||
{\
|
|
||||||
cpuPrefetch[0] = CPUReadMemoryQuick(armNextPC);\
|
|
||||||
cpuPrefetch[1] = CPUReadMemoryQuick(armNextPC+4);\
|
|
||||||
}
|
|
||||||
|
|
||||||
#define THUMB_PREFETCH \
|
|
||||||
{\
|
|
||||||
cpuPrefetch[0] = CPUReadHalfWordQuick(armNextPC);\
|
|
||||||
cpuPrefetch[1] = CPUReadHalfWordQuick(armNextPC+2);\
|
|
||||||
}
|
|
||||||
|
|
||||||
#define ARM_PREFETCH_NEXT \
|
|
||||||
cpuPrefetch[1] = CPUReadMemoryQuick(armNextPC+4);
|
|
||||||
|
|
||||||
#define THUMB_PREFETCH_NEXT\
|
|
||||||
cpuPrefetch[1] = CPUReadHalfWordQuick(armNextPC+2);
|
|
||||||
|
|
||||||
|
|
||||||
extern int SWITicks;
|
|
||||||
extern u32 mastercode;
|
|
||||||
extern bool busPrefetch;
|
|
||||||
extern bool busPrefetchEnable;
|
|
||||||
extern u32 busPrefetchCount;
|
|
||||||
extern int cpuNextEvent;
|
|
||||||
extern bool holdState;
|
|
||||||
extern u32 cpuPrefetch[2];
|
|
||||||
extern int cpuTotalTicks;
|
|
||||||
extern u8 memoryWait[16];
|
|
||||||
extern u8 memoryWait32[16];
|
|
||||||
extern u8 memoryWaitSeq[16];
|
|
||||||
extern u8 memoryWaitSeq32[16];
|
|
||||||
extern u8 cpuBitsSet[256];
|
|
||||||
extern u8 cpuLowestBitSet[256];
|
|
||||||
extern void CPUSwitchMode(int mode, bool saveState, bool breakLoop);
|
|
||||||
extern void CPUSwitchMode(int mode, bool saveState);
|
|
||||||
extern void CPUUpdateCPSR();
|
|
||||||
extern void CPUUpdateFlags(bool breakLoop);
|
|
||||||
extern void CPUUpdateFlags();
|
|
||||||
extern void CPUUndefinedException();
|
|
||||||
extern void CPUSoftwareInterrupt();
|
|
||||||
extern void CPUSoftwareInterrupt(int comment);
|
|
||||||
|
|
||||||
|
|
||||||
// Waitstates when accessing data
|
|
||||||
inline int dataTicksAccess16(u32 address) // DATA 8/16bits NON SEQ
|
|
||||||
{
|
|
||||||
int addr = (address>>24)&15;
|
|
||||||
int value = memoryWait[addr];
|
|
||||||
|
|
||||||
if ((addr>=0x08) || (addr < 0x02))
|
|
||||||
{
|
|
||||||
busPrefetchCount=0;
|
|
||||||
busPrefetch=false;
|
|
||||||
}
|
|
||||||
else if (busPrefetch)
|
|
||||||
{
|
|
||||||
int waitState = value;
|
|
||||||
if (!waitState)
|
|
||||||
waitState = 1;
|
|
||||||
busPrefetchCount = ((busPrefetchCount+1)<<waitState) - 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline int dataTicksAccess32(u32 address) // DATA 32bits NON SEQ
|
|
||||||
{
|
|
||||||
int addr = (address>>24)&15;
|
|
||||||
int value = memoryWait32[addr];
|
|
||||||
|
|
||||||
if ((addr>=0x08) || (addr < 0x02))
|
|
||||||
{
|
|
||||||
busPrefetchCount=0;
|
|
||||||
busPrefetch=false;
|
|
||||||
}
|
|
||||||
else if (busPrefetch)
|
|
||||||
{
|
|
||||||
int waitState = value;
|
|
||||||
if (!waitState)
|
|
||||||
waitState = 1;
|
|
||||||
busPrefetchCount = ((busPrefetchCount+1)<<waitState) - 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline int dataTicksAccessSeq16(u32 address)// DATA 8/16bits SEQ
|
|
||||||
{
|
|
||||||
int addr = (address>>24)&15;
|
|
||||||
int value = memoryWaitSeq[addr];
|
|
||||||
|
|
||||||
if ((addr>=0x08) || (addr < 0x02))
|
|
||||||
{
|
|
||||||
busPrefetchCount=0;
|
|
||||||
busPrefetch=false;
|
|
||||||
}
|
|
||||||
else if (busPrefetch)
|
|
||||||
{
|
|
||||||
int waitState = value;
|
|
||||||
if (!waitState)
|
|
||||||
waitState = 1;
|
|
||||||
busPrefetchCount = ((busPrefetchCount+1)<<waitState) - 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline int dataTicksAccessSeq32(u32 address)// DATA 32bits SEQ
|
|
||||||
{
|
|
||||||
int addr = (address>>24)&15;
|
|
||||||
int value = memoryWaitSeq32[addr];
|
|
||||||
|
|
||||||
if ((addr>=0x08) || (addr < 0x02))
|
|
||||||
{
|
|
||||||
busPrefetchCount=0;
|
|
||||||
busPrefetch=false;
|
|
||||||
}
|
|
||||||
else if (busPrefetch)
|
|
||||||
{
|
|
||||||
int waitState = value;
|
|
||||||
if (!waitState)
|
|
||||||
waitState = 1;
|
|
||||||
busPrefetchCount = ((busPrefetchCount+1)<<waitState) - 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Waitstates when executing opcode
|
|
||||||
inline int codeTicksAccess16(u32 address) // THUMB NON SEQ
|
|
||||||
{
|
|
||||||
int addr = (address>>24)&15;
|
|
||||||
|
|
||||||
if ((addr>=0x08) && (addr<=0x0D))
|
|
||||||
{
|
|
||||||
if (busPrefetchCount&0x1)
|
|
||||||
{
|
|
||||||
if (busPrefetchCount&0x2)
|
|
||||||
{
|
|
||||||
busPrefetchCount = ((busPrefetchCount&0xFF)>>2) | (busPrefetchCount&0xFFFFFF00);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
busPrefetchCount = ((busPrefetchCount&0xFF)>>1) | (busPrefetchCount&0xFFFFFF00);
|
|
||||||
return memoryWaitSeq[addr]-1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
busPrefetchCount=0;
|
|
||||||
return memoryWait[addr];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
busPrefetchCount = 0;
|
|
||||||
return memoryWait[addr];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
inline int codeTicksAccess32(u32 address) // ARM NON SEQ
|
|
||||||
{
|
|
||||||
int addr = (address>>24)&15;
|
|
||||||
|
|
||||||
if ((addr>=0x08) && (addr<=0x0D))
|
|
||||||
{
|
|
||||||
if (busPrefetchCount&0x1)
|
|
||||||
{
|
|
||||||
if (busPrefetchCount&0x2)
|
|
||||||
{
|
|
||||||
busPrefetchCount = ((busPrefetchCount&0xFF)>>2) | (busPrefetchCount&0xFFFFFF00);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
busPrefetchCount = ((busPrefetchCount&0xFF)>>1) | (busPrefetchCount&0xFFFFFF00);
|
|
||||||
return memoryWaitSeq[addr] - 1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
busPrefetchCount = 0;
|
|
||||||
return memoryWait32[addr];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
busPrefetchCount = 0;
|
|
||||||
return memoryWait32[addr];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
inline int codeTicksAccessSeq16(u32 address) // THUMB SEQ
|
|
||||||
{
|
|
||||||
int addr = (address>>24)&15;
|
|
||||||
|
|
||||||
if ((addr>=0x08) && (addr<=0x0D))
|
|
||||||
{
|
|
||||||
if (busPrefetchCount&0x1)
|
|
||||||
{
|
|
||||||
busPrefetchCount = ((busPrefetchCount&0xFF)>>1) | (busPrefetchCount&0xFFFFFF00);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
if (busPrefetchCount>0xFF)
|
|
||||||
{
|
|
||||||
busPrefetchCount=0;
|
|
||||||
return memoryWait[addr];
|
|
||||||
}
|
|
||||||
else
|
|
||||||
return memoryWaitSeq[addr];
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
busPrefetchCount = 0;
|
|
||||||
return memoryWaitSeq[addr];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
inline int codeTicksAccessSeq32(u32 address) // ARM SEQ
|
|
||||||
{
|
|
||||||
int addr = (address>>24)&15;
|
|
||||||
|
|
||||||
if ((addr>=0x08) && (addr<=0x0D))
|
|
||||||
{
|
|
||||||
if (busPrefetchCount&0x1)
|
|
||||||
{
|
|
||||||
if (busPrefetchCount&0x2)
|
|
||||||
{
|
|
||||||
busPrefetchCount = ((busPrefetchCount&0xFF)>>2) | (busPrefetchCount&0xFFFFFF00);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
busPrefetchCount = ((busPrefetchCount&0xFF)>>1) | (busPrefetchCount&0xFFFFFF00);
|
|
||||||
return memoryWaitSeq[addr];
|
|
||||||
}
|
|
||||||
else
|
|
||||||
if (busPrefetchCount>0xFF)
|
|
||||||
{
|
|
||||||
busPrefetchCount=0;
|
|
||||||
return memoryWait32[addr];
|
|
||||||
}
|
|
||||||
else
|
|
||||||
return memoryWaitSeq32[addr];
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return memoryWaitSeq32[addr];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Emulates the Cheat System (m) code
|
|
||||||
inline void cpuMasterCodeCheck()
|
|
||||||
{
|
|
||||||
if((mastercode) && (mastercode == armNextPC))
|
|
||||||
{
|
|
||||||
u32 joy = 0;
|
|
||||||
if(systemReadJoypads())
|
|
||||||
joy = systemReadJoypad(-1);
|
|
||||||
u32 ext = (joy >> 10);
|
|
||||||
cpuTotalTicks += cheatsCheckKeys(P1^0x3FF, ext);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif //VBA_GBAcpu_H
|
|
@ -1,834 +0,0 @@
|
|||||||
// -*- C++ -*-
|
|
||||||
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
|
|
||||||
// Copyright (C) 1999-2003 Forgotten
|
|
||||||
// Copyright (C) 2005 Forgotten and the VBA development team
|
|
||||||
|
|
||||||
// This program is free software; you can redistribute it and/or modify
|
|
||||||
// it under the terms of the GNU General Public License as published by
|
|
||||||
// the Free Software Foundation; either version 2, or(at your option)
|
|
||||||
// any later version.
|
|
||||||
//
|
|
||||||
// This program is distributed in the hope that it will be useful,
|
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
// GNU General Public License for more details.
|
|
||||||
//
|
|
||||||
// You should have received a copy of the GNU General Public License
|
|
||||||
// along with this program; if not, write to the Free Software Foundation,
|
|
||||||
// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
||||||
|
|
||||||
#ifndef VBA_GBAinline_H
|
|
||||||
#define VBA_GBAinline_H
|
|
||||||
|
|
||||||
#include "../System.h"
|
|
||||||
#include "../Port.h"
|
|
||||||
#include "../RTC.h"
|
|
||||||
#include "../Sound.h"
|
|
||||||
#include "agbprint.h"
|
|
||||||
#include "vmmem.h" // Nintendo GC Virtual Memory
|
|
||||||
|
|
||||||
extern const u32 objTilesAddress[3];
|
|
||||||
|
|
||||||
extern bool stopState;
|
|
||||||
extern bool holdState;
|
|
||||||
extern int holdType;
|
|
||||||
extern int cpuNextEvent;
|
|
||||||
extern bool cpuSramEnabled;
|
|
||||||
extern bool cpuFlashEnabled;
|
|
||||||
extern bool cpuEEPROMEnabled;
|
|
||||||
extern bool cpuEEPROMSensorEnabled;
|
|
||||||
extern bool cpuDmaHack;
|
|
||||||
extern u32 cpuDmaLast;
|
|
||||||
extern bool timer0On;
|
|
||||||
extern int timer0Ticks;
|
|
||||||
extern int timer0ClockReload;
|
|
||||||
extern bool timer1On;
|
|
||||||
extern int timer1Ticks;
|
|
||||||
extern int timer1ClockReload;
|
|
||||||
extern bool timer2On;
|
|
||||||
extern int timer2Ticks;
|
|
||||||
extern int timer2ClockReload;
|
|
||||||
extern bool timer3On;
|
|
||||||
extern int timer3Ticks;
|
|
||||||
extern int timer3ClockReload;
|
|
||||||
extern int cpuTotalTicks;
|
|
||||||
|
|
||||||
/*****************************************************************************
|
|
||||||
* Nintendo GC Virtual Memory function override
|
|
||||||
* Tantric September 2008
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
#define CPUReadByteQuickDef(addr) \
|
|
||||||
map[(addr)>>24].address[(addr) & map[(addr)>>24].mask]
|
|
||||||
|
|
||||||
#define CPUReadHalfWordQuickDef(addr) \
|
|
||||||
READ16LE(((u16*)&map[(addr)>>24].address[(addr) & map[(addr)>>24].mask]))
|
|
||||||
|
|
||||||
#define CPUReadMemoryQuickDef(addr) \
|
|
||||||
READ32LE(((u32*)&map[(addr)>>24].address[(addr) & map[(addr)>>24].mask]))
|
|
||||||
|
|
||||||
u8 inline CPUReadByteQuick( u32 addr )
|
|
||||||
{
|
|
||||||
switch(addr >> 24 )
|
|
||||||
{
|
|
||||||
case 8:
|
|
||||||
case 9:
|
|
||||||
case 10:
|
|
||||||
case 12:
|
|
||||||
return VMRead8( addr & 0x1FFFFFF );
|
|
||||||
|
|
||||||
default:
|
|
||||||
return CPUReadByteQuickDef(addr);
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
u16 inline CPUReadHalfWordQuick( u32 addr )
|
|
||||||
{
|
|
||||||
switch(addr >> 24)
|
|
||||||
{
|
|
||||||
case 8:
|
|
||||||
case 9:
|
|
||||||
case 10:
|
|
||||||
case 12:
|
|
||||||
return VMRead16( addr & 0x1FFFFFF );
|
|
||||||
default:
|
|
||||||
return CPUReadHalfWordQuickDef(addr);
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
u32 inline CPUReadMemoryQuick( u32 addr )
|
|
||||||
{
|
|
||||||
switch(addr >> 24)
|
|
||||||
{
|
|
||||||
case 8:
|
|
||||||
case 9:
|
|
||||||
case 10:
|
|
||||||
case 12:
|
|
||||||
return VMRead32( addr & 0x1FFFFFF );
|
|
||||||
default:
|
|
||||||
return CPUReadMemoryQuickDef(addr);
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*****************************************************************************
|
|
||||||
* End of NGC VM override
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
static inline u32 CPUReadMemory(u32 address)
|
|
||||||
{
|
|
||||||
#ifdef GBA_LOGGING
|
|
||||||
if(address & 3) {
|
|
||||||
if(systemVerbose & VERBOSE_UNALIGNED_MEMORY) {
|
|
||||||
log("Unaligned word read: %08x at %08x\n", address, armMode ?
|
|
||||||
armNextPC - 4 : armNextPC - 2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
u32 value;
|
|
||||||
switch(address >> 24) {
|
|
||||||
case 0:
|
|
||||||
if(reg[15].I >> 24) {
|
|
||||||
if(address < 0x4000) {
|
|
||||||
#ifdef GBA_LOGGING
|
|
||||||
if(systemVerbose & VERBOSE_ILLEGAL_READ) {
|
|
||||||
log("Illegal word read: %08x at %08x\n", address, armMode ?
|
|
||||||
armNextPC - 4 : armNextPC - 2);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
value = READ32LE(((u32 *)&biosProtected));
|
|
||||||
}
|
|
||||||
else goto unreadable;
|
|
||||||
} else
|
|
||||||
value = READ32LE(((u32 *)&bios[address & 0x3FFC]));
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
value = READ32LE(((u32 *)&workRAM[address & 0x3FFFC]));
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
value = READ32LE(((u32 *)&internalRAM[address & 0x7ffC]));
|
|
||||||
break;
|
|
||||||
case 4:
|
|
||||||
if((address < 0x4000400) && ioReadable[address & 0x3fc]) {
|
|
||||||
if(ioReadable[(address & 0x3fc) + 2])
|
|
||||||
value = READ32LE(((u32 *)&ioMem[address & 0x3fC]));
|
|
||||||
else
|
|
||||||
value = READ16LE(((u16 *)&ioMem[address & 0x3fc]));
|
|
||||||
} else goto unreadable;
|
|
||||||
break;
|
|
||||||
case 5:
|
|
||||||
value = READ32LE(((u32 *)&paletteRAM[address & 0x3fC]));
|
|
||||||
break;
|
|
||||||
case 6:
|
|
||||||
address = (address & 0x1fffc);
|
|
||||||
if (((DISPCNT & 7) >2) && ((address & 0x1C000) == 0x18000))
|
|
||||||
{
|
|
||||||
value = 0;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if ((address & 0x18000) == 0x18000)
|
|
||||||
address &= 0x17fff;
|
|
||||||
value = READ32LE(((u32 *)&vram[address]));
|
|
||||||
break;
|
|
||||||
case 7:
|
|
||||||
value = READ32LE(((u32 *)&oam[address & 0x3FC]));
|
|
||||||
break;
|
|
||||||
case 8:
|
|
||||||
case 9:
|
|
||||||
case 10:
|
|
||||||
case 11:
|
|
||||||
case 12:
|
|
||||||
#ifdef USE_VM // Nintendo GC Virtual Memory
|
|
||||||
value = VMRead32( address & 0x1FFFFFC );
|
|
||||||
#else
|
|
||||||
value = READ32LE(((u32 *)&rom[address&0x1FFFFFC]));
|
|
||||||
#endif
|
|
||||||
break;
|
|
||||||
case 13:
|
|
||||||
if(cpuEEPROMEnabled)
|
|
||||||
// no need to swap this
|
|
||||||
return eepromRead(address);
|
|
||||||
goto unreadable;
|
|
||||||
case 14:
|
|
||||||
if(cpuFlashEnabled | cpuSramEnabled)
|
|
||||||
// no need to swap this
|
|
||||||
return flashRead(address);
|
|
||||||
// default
|
|
||||||
default:
|
|
||||||
unreadable:
|
|
||||||
#ifdef GBA_LOGGING
|
|
||||||
if(systemVerbose & VERBOSE_ILLEGAL_READ) {
|
|
||||||
log("Illegal word read: %08x at %08x\n", address, armMode ?
|
|
||||||
armNextPC - 4 : armNextPC - 2);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if(cpuDmaHack) {
|
|
||||||
value = cpuDmaLast;
|
|
||||||
} else {
|
|
||||||
if(armState) {
|
|
||||||
#ifdef USE_VM // Nintendo GC Virtual Memory
|
|
||||||
value = CPUReadMemoryQuick(reg[15].I);
|
|
||||||
#else
|
|
||||||
value = CPUReadMemoryQuickDef(reg[15].I);
|
|
||||||
#endif
|
|
||||||
} else {
|
|
||||||
#ifdef USE_VM // Nintendo GC Virtual Memory
|
|
||||||
value = CPUReadHalfWordQuick(reg[15].I) |
|
|
||||||
CPUReadHalfWordQuick(reg[15].I) << 16;
|
|
||||||
#else
|
|
||||||
value = CPUReadHalfWordQuickDef(reg[15].I) |
|
|
||||||
CPUReadHalfWordQuickDef(reg[15].I) << 16;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(address & 3) {
|
|
||||||
#ifdef C_CORE
|
|
||||||
int shift = (address & 3) << 3;
|
|
||||||
value = (value >> shift) | (value << (32 - shift));
|
|
||||||
#else
|
|
||||||
#ifdef __GNUC__
|
|
||||||
asm("and $3, %%ecx;"
|
|
||||||
"shl $3 ,%%ecx;"
|
|
||||||
"ror %%cl, %0"
|
|
||||||
: "=r" (value)
|
|
||||||
: "r" (value), "c" (address));
|
|
||||||
#else
|
|
||||||
__asm {
|
|
||||||
mov ecx, address;
|
|
||||||
and ecx, 3;
|
|
||||||
shl ecx, 3;
|
|
||||||
ror [dword ptr value], cl;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
extern u32 myROM[];
|
|
||||||
|
|
||||||
static inline u32 CPUReadHalfWord(u32 address)
|
|
||||||
{
|
|
||||||
#ifdef GBA_LOGGING
|
|
||||||
if(address & 1) {
|
|
||||||
if(systemVerbose & VERBOSE_UNALIGNED_MEMORY) {
|
|
||||||
log("Unaligned halfword read: %08x at %08x\n", address, armMode ?
|
|
||||||
armNextPC - 4 : armNextPC - 2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
u32 value;
|
|
||||||
|
|
||||||
switch(address >> 24) {
|
|
||||||
case 0:
|
|
||||||
if (reg[15].I >> 24) {
|
|
||||||
if(address < 0x4000) {
|
|
||||||
#ifdef GBA_LOGGING
|
|
||||||
if(systemVerbose & VERBOSE_ILLEGAL_READ) {
|
|
||||||
log("Illegal halfword read: %08x at %08x\n", address, armMode ?
|
|
||||||
armNextPC - 4 : armNextPC - 2);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
value = READ16LE(((u16 *)&biosProtected[address&2]));
|
|
||||||
} else goto unreadable;
|
|
||||||
} else
|
|
||||||
value = READ16LE(((u16 *)&bios[address & 0x3FFE]));
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
value = READ16LE(((u16 *)&workRAM[address & 0x3FFFE]));
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
value = READ16LE(((u16 *)&internalRAM[address & 0x7ffe]));
|
|
||||||
break;
|
|
||||||
case 4:
|
|
||||||
if((address < 0x4000400) && ioReadable[address & 0x3fe])
|
|
||||||
{
|
|
||||||
value = READ16LE(((u16 *)&ioMem[address & 0x3fe]));
|
|
||||||
if (((address & 0x3fe)>0xFF) && ((address & 0x3fe)<0x10E))
|
|
||||||
{
|
|
||||||
if (((address & 0x3fe) == 0x100) && timer0On)
|
|
||||||
value = 0xFFFF - ((timer0Ticks-cpuTotalTicks) >> timer0ClockReload);
|
|
||||||
else
|
|
||||||
if (((address & 0x3fe) == 0x104) && timer1On && !(TM1CNT & 4))
|
|
||||||
value = 0xFFFF - ((timer1Ticks-cpuTotalTicks) >> timer1ClockReload);
|
|
||||||
else
|
|
||||||
if (((address & 0x3fe) == 0x108) && timer2On && !(TM2CNT & 4))
|
|
||||||
value = 0xFFFF - ((timer2Ticks-cpuTotalTicks) >> timer2ClockReload);
|
|
||||||
else
|
|
||||||
if (((address & 0x3fe) == 0x10C) && timer3On && !(TM3CNT & 4))
|
|
||||||
value = 0xFFFF - ((timer3Ticks-cpuTotalTicks) >> timer3ClockReload);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else goto unreadable;
|
|
||||||
break;
|
|
||||||
case 5:
|
|
||||||
value = READ16LE(((u16 *)&paletteRAM[address & 0x3fe]));
|
|
||||||
break;
|
|
||||||
case 6:
|
|
||||||
address = (address & 0x1fffe);
|
|
||||||
if (((DISPCNT & 7) >2) && ((address & 0x1C000) == 0x18000))
|
|
||||||
{
|
|
||||||
value = 0;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if ((address & 0x18000) == 0x18000)
|
|
||||||
address &= 0x17fff;
|
|
||||||
value = READ16LE(((u16 *)&vram[address]));
|
|
||||||
break;
|
|
||||||
case 7:
|
|
||||||
value = READ16LE(((u16 *)&oam[address & 0x3fe]));
|
|
||||||
break;
|
|
||||||
case 8:
|
|
||||||
case 9:
|
|
||||||
case 10:
|
|
||||||
case 11:
|
|
||||||
case 12:
|
|
||||||
if(address == 0x80000c4 || address == 0x80000c6 || address == 0x80000c8)
|
|
||||||
value = rtcRead(address);
|
|
||||||
else
|
|
||||||
#ifdef USE_VM // Nintendo GC Virtual Memory
|
|
||||||
value = VMRead16( address & 0x1FFFFFE );
|
|
||||||
#else
|
|
||||||
value = READ16LE(((u16 *)&rom[address & 0x1FFFFFE]));
|
|
||||||
#endif
|
|
||||||
break;
|
|
||||||
case 13:
|
|
||||||
if(cpuEEPROMEnabled)
|
|
||||||
// no need to swap this
|
|
||||||
return eepromRead(address);
|
|
||||||
goto unreadable;
|
|
||||||
case 14:
|
|
||||||
if(cpuFlashEnabled | cpuSramEnabled)
|
|
||||||
// no need to swap this
|
|
||||||
return flashRead(address);
|
|
||||||
// default
|
|
||||||
default:
|
|
||||||
unreadable:
|
|
||||||
#ifdef GBA_LOGGING
|
|
||||||
if(systemVerbose & VERBOSE_ILLEGAL_READ) {
|
|
||||||
log("Illegal halfword read: %08x at %08x\n", address, armMode ?
|
|
||||||
armNextPC - 4 : armNextPC - 2);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
if(cpuDmaHack) {
|
|
||||||
value = cpuDmaLast & 0xFFFF;
|
|
||||||
} else {
|
|
||||||
if(armState) {
|
|
||||||
#ifdef USE_VM // Nintendo GC Virtual Memory
|
|
||||||
value = CPUReadHalfWordQuick(reg[15].I + (address & 2));
|
|
||||||
#else
|
|
||||||
value = CPUReadHalfWordQuickDef(reg[15].I + (address & 2));
|
|
||||||
#endif
|
|
||||||
} else {
|
|
||||||
#ifdef USE_VM // Nintendo GC Virtual Memory
|
|
||||||
value = CPUReadHalfWordQuick(reg[15].I);
|
|
||||||
#else
|
|
||||||
value = CPUReadHalfWordQuickDef(reg[15].I);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(address & 1) {
|
|
||||||
value = (value >> 8) | (value << 24);
|
|
||||||
}
|
|
||||||
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline u16 CPUReadHalfWordSigned(u32 address)
|
|
||||||
{
|
|
||||||
u16 value = CPUReadHalfWord(address);
|
|
||||||
if((address & 1))
|
|
||||||
value = (s8)value;
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline u8 CPUReadByte(u32 address)
|
|
||||||
{
|
|
||||||
switch(address >> 24) {
|
|
||||||
case 0:
|
|
||||||
if (reg[15].I >> 24) {
|
|
||||||
if(address < 0x4000) {
|
|
||||||
#ifdef GBA_LOGGING
|
|
||||||
if(systemVerbose & VERBOSE_ILLEGAL_READ) {
|
|
||||||
log("Illegal byte read: %08x at %08x\n", address, armMode ?
|
|
||||||
armNextPC - 4 : armNextPC - 2);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
return biosProtected[address & 3];
|
|
||||||
} else goto unreadable;
|
|
||||||
}
|
|
||||||
return bios[address & 0x3FFF];
|
|
||||||
case 2:
|
|
||||||
return workRAM[address & 0x3FFFF];
|
|
||||||
case 3:
|
|
||||||
return internalRAM[address & 0x7fff];
|
|
||||||
case 4:
|
|
||||||
if((address < 0x4000400) && ioReadable[address & 0x3ff])
|
|
||||||
return ioMem[address & 0x3ff];
|
|
||||||
else goto unreadable;
|
|
||||||
case 5:
|
|
||||||
return paletteRAM[address & 0x3ff];
|
|
||||||
case 6:
|
|
||||||
address = (address & 0x1ffff);
|
|
||||||
if (((DISPCNT & 7) >2) && ((address & 0x1C000) == 0x18000))
|
|
||||||
return 0;
|
|
||||||
if ((address & 0x18000) == 0x18000)
|
|
||||||
address &= 0x17fff;
|
|
||||||
return vram[address];
|
|
||||||
case 7:
|
|
||||||
return oam[address & 0x3ff];
|
|
||||||
case 8:
|
|
||||||
case 9:
|
|
||||||
case 10:
|
|
||||||
case 11:
|
|
||||||
case 12:
|
|
||||||
#ifdef USE_VM // Nintendo GC Virtual Memory
|
|
||||||
return VMRead8( address & 0x1FFFFFF );
|
|
||||||
#else
|
|
||||||
return rom[address & 0x1FFFFFF];
|
|
||||||
#endif
|
|
||||||
case 13:
|
|
||||||
if(cpuEEPROMEnabled)
|
|
||||||
return eepromRead(address);
|
|
||||||
goto unreadable;
|
|
||||||
case 14:
|
|
||||||
if(cpuSramEnabled | cpuFlashEnabled)
|
|
||||||
return flashRead(address);
|
|
||||||
if(cpuEEPROMSensorEnabled) {
|
|
||||||
switch(address & 0x00008f00) {
|
|
||||||
case 0x8200:
|
|
||||||
return systemGetSensorX() & 255;
|
|
||||||
case 0x8300:
|
|
||||||
return (systemGetSensorX() >> 8)|0x80;
|
|
||||||
case 0x8400:
|
|
||||||
return systemGetSensorY() & 255;
|
|
||||||
case 0x8500:
|
|
||||||
return systemGetSensorY() >> 8;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// default
|
|
||||||
default:
|
|
||||||
unreadable:
|
|
||||||
#ifdef GBA_LOGGING
|
|
||||||
if(systemVerbose & VERBOSE_ILLEGAL_READ) {
|
|
||||||
log("Illegal byte read: %08x at %08x\n", address, armMode ?
|
|
||||||
armNextPC - 4 : armNextPC - 2);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
if(cpuDmaHack) {
|
|
||||||
return cpuDmaLast & 0xFF;
|
|
||||||
} else {
|
|
||||||
if(armState) {
|
|
||||||
#ifdef USE_VM // Nintendo GC Virtual Memory
|
|
||||||
return CPUReadByteQuick(reg[15].I+(address & 3));
|
|
||||||
#else
|
|
||||||
return CPUReadByteQuickDef(reg[15].I+(address & 3));
|
|
||||||
#endif
|
|
||||||
} else {
|
|
||||||
#ifdef USE_VM // Nintendo GC Virtual Memory
|
|
||||||
return CPUReadByteQuick(reg[15].I+(address & 1));
|
|
||||||
#else
|
|
||||||
return CPUReadByteQuickDef(reg[15].I+(address & 1));
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void CPUWriteMemory(u32 address, u32 value)
|
|
||||||
{
|
|
||||||
|
|
||||||
#ifdef GBA_LOGGING
|
|
||||||
if(address & 3) {
|
|
||||||
if(systemVerbose & VERBOSE_UNALIGNED_MEMORY) {
|
|
||||||
log("Unaligned word write: %08x to %08x from %08x\n",
|
|
||||||
value,
|
|
||||||
address,
|
|
||||||
armMode ? armNextPC - 4 : armNextPC - 2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
switch(address >> 24) {
|
|
||||||
case 0x02:
|
|
||||||
#ifdef BKPT_SUPPORT
|
|
||||||
if(*((u32 *)&freezeWorkRAM[address & 0x3FFFC]))
|
|
||||||
cheatsWriteMemory(address & 0x203FFFC,
|
|
||||||
value);
|
|
||||||
else
|
|
||||||
#endif
|
|
||||||
WRITE32LE(((u32 *)&workRAM[address & 0x3FFFC]), value);
|
|
||||||
break;
|
|
||||||
case 0x03:
|
|
||||||
#ifdef BKPT_SUPPORT
|
|
||||||
if(*((u32 *)&freezeInternalRAM[address & 0x7ffc]))
|
|
||||||
cheatsWriteMemory(address & 0x3007FFC,
|
|
||||||
value);
|
|
||||||
else
|
|
||||||
#endif
|
|
||||||
WRITE32LE(((u32 *)&internalRAM[address & 0x7ffC]), value);
|
|
||||||
break;
|
|
||||||
case 0x04:
|
|
||||||
if(address < 0x4000400) {
|
|
||||||
CPUUpdateRegister((address & 0x3FC), value & 0xFFFF);
|
|
||||||
CPUUpdateRegister((address & 0x3FC) + 2, (value >> 16));
|
|
||||||
} else goto unwritable;
|
|
||||||
break;
|
|
||||||
case 0x05:
|
|
||||||
#ifdef BKPT_SUPPORT
|
|
||||||
if(*((u32 *)&freezePRAM[address & 0x3fc]))
|
|
||||||
cheatsWriteMemory(address & 0x70003FC,
|
|
||||||
value);
|
|
||||||
else
|
|
||||||
#endif
|
|
||||||
WRITE32LE(((u32 *)&paletteRAM[address & 0x3FC]), value);
|
|
||||||
break;
|
|
||||||
case 0x06:
|
|
||||||
address = (address & 0x1fffc);
|
|
||||||
if (((DISPCNT & 7) >2) && ((address & 0x1C000) == 0x18000))
|
|
||||||
return;
|
|
||||||
if ((address & 0x18000) == 0x18000)
|
|
||||||
address &= 0x17fff;
|
|
||||||
|
|
||||||
#ifdef BKPT_SUPPORT
|
|
||||||
if(*((u32 *)&freezeVRAM[address]))
|
|
||||||
cheatsWriteMemory(address + 0x06000000, value);
|
|
||||||
else
|
|
||||||
#endif
|
|
||||||
|
|
||||||
WRITE32LE(((u32 *)&vram[address]), value);
|
|
||||||
break;
|
|
||||||
case 0x07:
|
|
||||||
#ifdef BKPT_SUPPORT
|
|
||||||
if(*((u32 *)&freezeOAM[address & 0x3fc]))
|
|
||||||
cheatsWriteMemory(address & 0x70003FC,
|
|
||||||
value);
|
|
||||||
else
|
|
||||||
#endif
|
|
||||||
WRITE32LE(((u32 *)&oam[address & 0x3fc]), value);
|
|
||||||
break;
|
|
||||||
case 0x0D:
|
|
||||||
if(cpuEEPROMEnabled) {
|
|
||||||
eepromWrite(address, value);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
goto unwritable;
|
|
||||||
case 0x0E:
|
|
||||||
if(!eepromInUse | cpuSramEnabled | cpuFlashEnabled) {
|
|
||||||
(*cpuSaveGameFunc)(address, (u8)value);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
// default
|
|
||||||
default:
|
|
||||||
unwritable:
|
|
||||||
#ifdef GBA_LOGGING
|
|
||||||
if(systemVerbose & VERBOSE_ILLEGAL_WRITE) {
|
|
||||||
log("Illegal word write: %08x to %08x from %08x\n",
|
|
||||||
value,
|
|
||||||
address,
|
|
||||||
armMode ? armNextPC - 4 : armNextPC - 2);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void CPUWriteHalfWord(u32 address, u16 value)
|
|
||||||
{
|
|
||||||
#ifdef GBA_LOGGING
|
|
||||||
if(address & 1) {
|
|
||||||
if(systemVerbose & VERBOSE_UNALIGNED_MEMORY) {
|
|
||||||
log("Unaligned halfword write: %04x to %08x from %08x\n",
|
|
||||||
value,
|
|
||||||
address,
|
|
||||||
armMode ? armNextPC - 4 : armNextPC - 2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
switch(address >> 24) {
|
|
||||||
case 2:
|
|
||||||
#ifdef BKPT_SUPPORT
|
|
||||||
if(*((u16 *)&freezeWorkRAM[address & 0x3FFFE]))
|
|
||||||
cheatsWriteHalfWord(address & 0x203FFFE,
|
|
||||||
value);
|
|
||||||
else
|
|
||||||
#endif
|
|
||||||
WRITE16LE(((u16 *)&workRAM[address & 0x3FFFE]),value);
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
#ifdef BKPT_SUPPORT
|
|
||||||
if(*((u16 *)&freezeInternalRAM[address & 0x7ffe]))
|
|
||||||
cheatsWriteHalfWord(address & 0x3007ffe,
|
|
||||||
value);
|
|
||||||
else
|
|
||||||
#endif
|
|
||||||
WRITE16LE(((u16 *)&internalRAM[address & 0x7ffe]), value);
|
|
||||||
break;
|
|
||||||
case 4:
|
|
||||||
if(address < 0x4000400)
|
|
||||||
CPUUpdateRegister(address & 0x3fe, value);
|
|
||||||
else goto unwritable;
|
|
||||||
break;
|
|
||||||
case 5:
|
|
||||||
#ifdef BKPT_SUPPORT
|
|
||||||
if(*((u16 *)&freezePRAM[address & 0x03fe]))
|
|
||||||
cheatsWriteHalfWord(address & 0x70003fe,
|
|
||||||
value);
|
|
||||||
else
|
|
||||||
#endif
|
|
||||||
WRITE16LE(((u16 *)&paletteRAM[address & 0x3fe]), value);
|
|
||||||
break;
|
|
||||||
case 6:
|
|
||||||
address = (address & 0x1fffe);
|
|
||||||
if (((DISPCNT & 7) >2) && ((address & 0x1C000) == 0x18000))
|
|
||||||
return;
|
|
||||||
if ((address & 0x18000) == 0x18000)
|
|
||||||
address &= 0x17fff;
|
|
||||||
#ifdef BKPT_SUPPORT
|
|
||||||
if(*((u16 *)&freezeVRAM[address]))
|
|
||||||
cheatsWriteHalfWord(address + 0x06000000,
|
|
||||||
value);
|
|
||||||
else
|
|
||||||
#endif
|
|
||||||
WRITE16LE(((u16 *)&vram[address]), value);
|
|
||||||
break;
|
|
||||||
case 7:
|
|
||||||
#ifdef BKPT_SUPPORT
|
|
||||||
if(*((u16 *)&freezeOAM[address & 0x03fe]))
|
|
||||||
cheatsWriteHalfWord(address & 0x70003fe,
|
|
||||||
value);
|
|
||||||
else
|
|
||||||
#endif
|
|
||||||
WRITE16LE(((u16 *)&oam[address & 0x3fe]), value);
|
|
||||||
break;
|
|
||||||
case 8:
|
|
||||||
case 9:
|
|
||||||
if(address == 0x80000c4 || address == 0x80000c6 || address == 0x80000c8) {
|
|
||||||
if(!rtcWrite(address, value))
|
|
||||||
goto unwritable;
|
|
||||||
} else if(!agbPrintWrite(address, value)) goto unwritable;
|
|
||||||
break;
|
|
||||||
case 13:
|
|
||||||
if(cpuEEPROMEnabled) {
|
|
||||||
eepromWrite(address, (u8)value);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
goto unwritable;
|
|
||||||
case 14:
|
|
||||||
if(!eepromInUse | cpuSramEnabled | cpuFlashEnabled) {
|
|
||||||
(*cpuSaveGameFunc)(address, (u8)value);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
goto unwritable;
|
|
||||||
default:
|
|
||||||
unwritable:
|
|
||||||
#ifdef GBA_LOGGING
|
|
||||||
if(systemVerbose & VERBOSE_ILLEGAL_WRITE) {
|
|
||||||
log("Illegal halfword write: %04x to %08x from %08x\n",
|
|
||||||
value,
|
|
||||||
address,
|
|
||||||
armMode ? armNextPC - 4 : armNextPC - 2);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void CPUWriteByte(u32 address, u8 b)
|
|
||||||
{
|
|
||||||
switch(address >> 24) {
|
|
||||||
case 2:
|
|
||||||
#ifdef BKPT_SUPPORT
|
|
||||||
if(freezeWorkRAM[address & 0x3FFFF])
|
|
||||||
cheatsWriteByte(address & 0x203FFFF, b);
|
|
||||||
else
|
|
||||||
#endif
|
|
||||||
workRAM[address & 0x3FFFF] = b;
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
#ifdef BKPT_SUPPORT
|
|
||||||
if(freezeInternalRAM[address & 0x7fff])
|
|
||||||
cheatsWriteByte(address & 0x3007fff, b);
|
|
||||||
else
|
|
||||||
#endif
|
|
||||||
internalRAM[address & 0x7fff] = b;
|
|
||||||
break;
|
|
||||||
case 4:
|
|
||||||
if(address < 0x4000400) {
|
|
||||||
switch(address & 0x3FF) {
|
|
||||||
case 0x301:
|
|
||||||
if(b == 0x80)
|
|
||||||
stopState = true;
|
|
||||||
holdState = 1;
|
|
||||||
holdType = -1;
|
|
||||||
cpuNextEvent = cpuTotalTicks;
|
|
||||||
break;
|
|
||||||
case 0x60:
|
|
||||||
case 0x61:
|
|
||||||
case 0x62:
|
|
||||||
case 0x63:
|
|
||||||
case 0x64:
|
|
||||||
case 0x65:
|
|
||||||
case 0x68:
|
|
||||||
case 0x69:
|
|
||||||
case 0x6c:
|
|
||||||
case 0x6d:
|
|
||||||
case 0x70:
|
|
||||||
case 0x71:
|
|
||||||
case 0x72:
|
|
||||||
case 0x73:
|
|
||||||
case 0x74:
|
|
||||||
case 0x75:
|
|
||||||
case 0x78:
|
|
||||||
case 0x79:
|
|
||||||
case 0x7c:
|
|
||||||
case 0x7d:
|
|
||||||
case 0x80:
|
|
||||||
case 0x81:
|
|
||||||
case 0x84:
|
|
||||||
case 0x85:
|
|
||||||
case 0x90:
|
|
||||||
case 0x91:
|
|
||||||
case 0x92:
|
|
||||||
case 0x93:
|
|
||||||
case 0x94:
|
|
||||||
case 0x95:
|
|
||||||
case 0x96:
|
|
||||||
case 0x97:
|
|
||||||
case 0x98:
|
|
||||||
case 0x99:
|
|
||||||
case 0x9a:
|
|
||||||
case 0x9b:
|
|
||||||
case 0x9c:
|
|
||||||
case 0x9d:
|
|
||||||
case 0x9e:
|
|
||||||
case 0x9f:
|
|
||||||
soundEvent(address&0xFF, b);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
if(address & 1)
|
|
||||||
CPUUpdateRegister(address & 0x3fe,
|
|
||||||
((READ16LE(((u16 *)&ioMem[address & 0x3fe])))
|
|
||||||
& 0x00FF) |
|
|
||||||
b<<8);
|
|
||||||
else
|
|
||||||
CPUUpdateRegister(address & 0x3fe,
|
|
||||||
((READ16LE(((u16 *)&ioMem[address & 0x3fe])) & 0xFF00) | b));
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
} else goto unwritable;
|
|
||||||
break;
|
|
||||||
case 5:
|
|
||||||
// no need to switch
|
|
||||||
*((u16 *)&paletteRAM[address & 0x3FE]) = (b << 8) | b;
|
|
||||||
break;
|
|
||||||
case 6:
|
|
||||||
address = (address & 0x1fffe);
|
|
||||||
if (((DISPCNT & 7) >2) && ((address & 0x1C000) == 0x18000))
|
|
||||||
return;
|
|
||||||
if ((address & 0x18000) == 0x18000)
|
|
||||||
address &= 0x17fff;
|
|
||||||
|
|
||||||
// no need to switch
|
|
||||||
// byte writes to OBJ VRAM are ignored
|
|
||||||
if ((address) < objTilesAddress[((DISPCNT&7)+1)>>2])
|
|
||||||
{
|
|
||||||
#ifdef BKPT_SUPPORT
|
|
||||||
if(freezeVRAM[address])
|
|
||||||
cheatsWriteByte(address + 0x06000000, b);
|
|
||||||
else
|
|
||||||
#endif
|
|
||||||
*((u16 *)&vram[address]) = (b << 8) | b;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 7:
|
|
||||||
// no need to switch
|
|
||||||
// byte writes to OAM are ignored
|
|
||||||
// *((u16 *)&oam[address & 0x3FE]) = (b << 8) | b;
|
|
||||||
break;
|
|
||||||
case 13:
|
|
||||||
if(cpuEEPROMEnabled) {
|
|
||||||
eepromWrite(address, b);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
goto unwritable;
|
|
||||||
case 14:
|
|
||||||
if (!(saveType == 5) && (!eepromInUse | cpuSramEnabled | cpuFlashEnabled)) {
|
|
||||||
|
|
||||||
//if(!cpuEEPROMEnabled && (cpuSramEnabled | cpuFlashEnabled)) {
|
|
||||||
|
|
||||||
(*cpuSaveGameFunc)(address, b);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
// default
|
|
||||||
default:
|
|
||||||
unwritable:
|
|
||||||
#ifdef GBA_LOGGING
|
|
||||||
if(systemVerbose & VERBOSE_ILLEGAL_WRITE) {
|
|
||||||
log("Illegal byte write: %02x to %08x from %08x\n",
|
|
||||||
b,
|
|
||||||
address,
|
|
||||||
armMode ? armNextPC - 4 : armNextPC -2 );
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif //VBA_GBAinline_H
|
|
@ -1,98 +1,106 @@
|
|||||||
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
|
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
|
||||||
// Copyright (C) 1999-2003 Forgotten
|
// Copyright (C) 1999-2003 Forgotten
|
||||||
// Copyright (C) 2004 Forgotten and the VBA development team
|
// Copyright (C) 2004 Forgotten and the VBA development team
|
||||||
|
|
||||||
// This program is free software; you can redistribute it and/or modify
|
// This program is free software; you can redistribute it and/or modify
|
||||||
// it under the terms of the GNU General Public License as published by
|
// it under the terms of the GNU General Public License as published by
|
||||||
// the Free Software Foundation; either version 2, or(at your option)
|
// the Free Software Foundation; either version 2, or(at your option)
|
||||||
// any later version.
|
// any later version.
|
||||||
//
|
//
|
||||||
// This program is distributed in the hope that it will be useful,
|
// This program is distributed in the hope that it will be useful,
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
// GNU General Public License for more details.
|
// GNU General Public License for more details.
|
||||||
//
|
//
|
||||||
// You should have received a copy of the GNU General Public License
|
// You should have received a copy of the GNU General Public License
|
||||||
// along with this program; if not, write to the Free Software Foundation,
|
// along with this program; if not, write to the Free Software Foundation,
|
||||||
// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "GBA.h"
|
#include "GBA.h"
|
||||||
#include "Globals.h"
|
#include "Globals.h"
|
||||||
#include "Port.h"
|
#include "Port.h"
|
||||||
#include "System.h"
|
|
||||||
|
#define debuggerWriteHalfWord(addr, value) \
|
||||||
#define debuggerWriteHalfWord(addr, value) \
|
WRITE16LE((u16*)&map[(addr)>>24].address[(addr) & map[(addr)>>24].mask], (value))
|
||||||
WRITE16LE((u16*)&map[(addr)>>24].address[(addr) & map[(addr)>>24].mask], (value))
|
|
||||||
|
#define debuggerReadHalfWord(addr) \
|
||||||
#define debuggerReadHalfWord(addr) \
|
READ16LE(((u16*)&map[(addr)>>24].address[(addr) & map[(addr)>>24].mask]))
|
||||||
READ16LE(((u16*)&map[(addr)>>24].address[(addr) & map[(addr)>>24].mask]))
|
|
||||||
|
static bool agbPrintEnabled = false;
|
||||||
static bool agbPrintEnabled = false;
|
static bool agbPrintProtect = false;
|
||||||
static bool agbPrintProtect = false;
|
|
||||||
|
bool agbPrintWrite(u32 address, u16 value)
|
||||||
bool agbPrintWrite(u32 address, u16 value)
|
{
|
||||||
{
|
if(agbPrintEnabled)
|
||||||
if(agbPrintEnabled) {
|
{
|
||||||
if(address == 0x9fe2ffe) { // protect
|
if(address == 0x9fe2ffe)
|
||||||
agbPrintProtect = (value != 0);
|
{ // protect
|
||||||
debuggerWriteHalfWord(address, value);
|
agbPrintProtect = (value != 0);
|
||||||
return true;
|
debuggerWriteHalfWord(address, value);
|
||||||
} else {
|
return true;
|
||||||
if(agbPrintProtect &&
|
}
|
||||||
((address >= 0x9fe20f8 && address <= 0x9fe20ff) // control structure
|
else
|
||||||
|| (address >= 0x8fd0000 && address <= 0x8fdffff)
|
{
|
||||||
|| (address >= 0x9fd0000 && address <= 0x9fdffff))) {
|
if(agbPrintProtect &&
|
||||||
debuggerWriteHalfWord(address, value);
|
((address >= 0x9fe20f8 && address <= 0x9fe20ff) // control structure
|
||||||
return true;
|
|| (address >= 0x8fd0000 && address <= 0x8fdffff)
|
||||||
}
|
|| (address >= 0x9fd0000 && address <= 0x9fdffff)))
|
||||||
}
|
{
|
||||||
}
|
debuggerWriteHalfWord(address, value);
|
||||||
return false;
|
return true;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
void agbPrintReset()
|
}
|
||||||
{
|
return false;
|
||||||
agbPrintProtect = false;
|
}
|
||||||
}
|
|
||||||
|
void agbPrintReset()
|
||||||
void agbPrintEnable(bool enable)
|
{
|
||||||
{
|
agbPrintProtect = false;
|
||||||
agbPrintEnabled = enable;
|
}
|
||||||
}
|
|
||||||
|
void agbPrintEnable(bool enable)
|
||||||
bool agbPrintIsEnabled()
|
{
|
||||||
{
|
agbPrintEnabled = enable;
|
||||||
return agbPrintEnabled;
|
}
|
||||||
}
|
|
||||||
|
bool agbPrintIsEnabled()
|
||||||
void agbPrintFlush()
|
{
|
||||||
{
|
return agbPrintEnabled;
|
||||||
u16 get = debuggerReadHalfWord(0x9fe20fc);
|
}
|
||||||
u16 put = debuggerReadHalfWord(0x9fe20fe);
|
|
||||||
|
extern void (*dbgOutput)(char *, u32);
|
||||||
u32 address = (debuggerReadHalfWord(0x9fe20fa) << 16);
|
|
||||||
if(address != 0xfd0000 && address != 0x1fd0000) {
|
void agbPrintFlush()
|
||||||
dbgOutput("Did you forget to call AGBPrintInit?\n", 0);
|
{
|
||||||
// get rid of the text otherwise we will continue to be called
|
u16 get = debuggerReadHalfWord(0x9fe20fc);
|
||||||
debuggerWriteHalfWord(0x9fe20fc, put);
|
u16 put = debuggerReadHalfWord(0x9fe20fe);
|
||||||
return;
|
|
||||||
}
|
u32 address = (debuggerReadHalfWord(0x9fe20fa) << 16);
|
||||||
|
if(address != 0xfd0000 && address != 0x1fd0000)
|
||||||
u8 *data = &rom[address];
|
{
|
||||||
|
dbgOutput("Did you forget to call AGBPrintInit?\n", 0);
|
||||||
while(get != put) {
|
// get rid of the text otherwise we will continue to be called
|
||||||
char c = data[get++];
|
debuggerWriteHalfWord(0x9fe20fc, put);
|
||||||
char s[2];
|
return;
|
||||||
s[0] = c;
|
}
|
||||||
s[1] = 0;
|
|
||||||
|
u8 *data = &rom[address];
|
||||||
if(systemVerbose & VERBOSE_AGBPRINT)
|
|
||||||
dbgOutput(s, 0);
|
while(get != put)
|
||||||
if(c == '\n')
|
{
|
||||||
break;
|
char c = data[get++];
|
||||||
}
|
char s[2];
|
||||||
debuggerWriteHalfWord(0x9fe20fc, get);
|
s[0] = c;
|
||||||
}
|
s[1] = 0;
|
||||||
|
|
||||||
|
if(systemVerbose & VERBOSE_AGBPRINT)
|
||||||
|
dbgOutput(s, 0);
|
||||||
|
if(c == '\n')
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
debuggerWriteHalfWord(0x9fe20fc, get);
|
||||||
|
}
|
@ -1,27 +1,27 @@
|
|||||||
// -*- C++ -*-
|
// -*- C++ -*-
|
||||||
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
|
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
|
||||||
// Copyright (C) 1999-2003 Forgotten
|
// Copyright (C) 1999-2003 Forgotten
|
||||||
// Copyright (C) 2004 Forgotten and the VBA development team
|
// Copyright (C) 2004 Forgotten and the VBA development team
|
||||||
|
|
||||||
// This program is free software; you can redistribute it and/or modify
|
// This program is free software; you can redistribute it and/or modify
|
||||||
// it under the terms of the GNU General Public License as published by
|
// it under the terms of the GNU General Public License as published by
|
||||||
// the Free Software Foundation; either version 2, or(at your option)
|
// the Free Software Foundation; either version 2, or(at your option)
|
||||||
// any later version.
|
// any later version.
|
||||||
//
|
//
|
||||||
// This program is distributed in the hope that it will be useful,
|
// This program is distributed in the hope that it will be useful,
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
// GNU General Public License for more details.
|
// GNU General Public License for more details.
|
||||||
//
|
//
|
||||||
// You should have received a copy of the GNU General Public License
|
// You should have received a copy of the GNU General Public License
|
||||||
// along with this program; if not, write to the Free Software Foundation,
|
// along with this program; if not, write to the Free Software Foundation,
|
||||||
// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
#ifndef VBA_AGBPRINT_H
|
#ifndef VBA_AGBPRINT_H
|
||||||
#define VBA_AGBPRINT_H
|
#define VBA_AGBPRINT_H
|
||||||
extern void agbPrintEnable(bool);
|
extern void agbPrintEnable(bool);
|
||||||
extern bool agbPrintIsEnabled();
|
extern bool agbPrintIsEnabled();
|
||||||
extern void agbPrintReset();
|
extern void agbPrintReset();
|
||||||
extern bool agbPrintWrite(u32, u16);
|
extern bool agbPrintWrite(u32, u16);
|
||||||
extern void agbPrintFlush();
|
extern void agbPrintFlush();
|
||||||
#endif
|
#endif
|
7472
source/vba/arm-new.h
Normal file
7472
source/vba/arm-new.h
Normal file
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user