mirror of
https://github.com/dborth/vbagx.git
synced 2025-02-21 12:47:11 +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
|
||||
# INCLUDES is a list of directories containing extra header files
|
||||
#---------------------------------------------------------------------------------
|
||||
TARGET := vbagx_gc
|
||||
TARGET := vba172_gc
|
||||
TARGETDIR := executables
|
||||
BUILD := build_gc
|
||||
SOURCES := source/vba source/vba/agb source/vba/dmg source/ngc source/sz
|
||||
INCLUDES := source/vba source/ngc
|
||||
SOURCES := source/vba source/vba/gb source/ngc
|
||||
INCLUDES := source/vba source/vba/gb source/ngc
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# options for code generation
|
||||
#---------------------------------------------------------------------------------
|
||||
|
||||
CFLAGS = -g -O3 -Wall $(MACHDEP) $(INCLUDE) \
|
||||
-DNGC -DUSE_VM -DWORDS_BIGENDIAN \
|
||||
-DC_CORE -D__ppc__ -D__POWERPC__ -DFINAL_VERSION \
|
||||
-DSDL -DNO_PNG -DHAVE_ZUTIL_H \
|
||||
-D_SZ_ONE_DIRECTORY -D_LZMA_IN_CB -D_LZMA_OUT_READ
|
||||
CXXFLAGS = $(CFLAGS)
|
||||
LDFLAGS = -g $(MACHDEP) -Wl,-Map,$(notdir $@).map
|
||||
CFLAGS = -g -Os -Wall $(MACHDEP) $(INCLUDE) \
|
||||
-DNGC -DWORDS_BIGENDIAN -DPACKAGE=\"VisualBoyAdvance\" \
|
||||
-DVERSION=\"1.7.2\" -DC_CORE \
|
||||
-DCHANFFS -DSDL -DNO_DEFLATE
|
||||
CXXFLAGS = -save-temps -Xassembler -aln=$@.lst $(CFLAGS)
|
||||
LDFLAGS = -g $(MACHDEP) -Wl,-Map,$(notdir $@).map -Wl,--cref
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# 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
|
||||
# INCLUDES is a list of directories containing extra header files
|
||||
#---------------------------------------------------------------------------------
|
||||
TARGET := vbagx_wii
|
||||
TARGET := vba172_wii
|
||||
TARGETDIR := executables
|
||||
BUILD := build_wii
|
||||
SOURCES := source/vba source/vba/agb source/vba/dmg source/ngc source/sz
|
||||
INCLUDES := source/vba source/ngc
|
||||
SOURCES := source/vba source/vba/gb source/ngc
|
||||
INCLUDES := source/vba source/vba/gb source/ngc
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# options for code generation
|
||||
#---------------------------------------------------------------------------------
|
||||
|
||||
CFLAGS = -g -O3 -Wall $(MACHDEP) $(INCLUDE) \
|
||||
-DNGC -DWII_DVD -DWORDS_BIGENDIAN -DVIDEO_THREADING \
|
||||
-DC_CORE -D__ppc__ -D__POWERPC__ -DFINAL_VERSION \
|
||||
-DSDL -DNO_PNG -DHAVE_ZUTIL_H \
|
||||
-D_SZ_ONE_DIRECTORY -D_LZMA_IN_CB -D_LZMA_OUT_READ
|
||||
CXXFLAGS = $(CFLAGS)
|
||||
CFLAGS = -g -Os -Wall $(MACHDEP) $(INCLUDE) \
|
||||
-DNGC -DWORDS_BIGENDIAN -DPACKAGE=\"VisualBoyAdvance\" \
|
||||
-DVERSION=\"1.7.2\" -DC_CORE \
|
||||
-DCHANFFS -DSDL -DNO_DEFLATE
|
||||
CXXFLAGS = -save-temps -Xassembler -aln=$@.lst $(CFLAGS)
|
||||
LDFLAGS = -g $(MACHDEP) -Wl,-Map,$(notdir $@).map -Wl,--cref
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
|
40
readme.txt
40
readme.txt
@ -1,13 +1,14 @@
|
||||
¸,ø¤°`°¤ø,¸¸,ø¤°`°¤ø,¸,ø¤°`°¤ø,¸¸,ø¤°`°¤ø,¸,ø¤°`°¤ø,¸¸,ø¤°`°¤ø,¸,ø¤°`°¤ø,¸¸,ø¤
|
||||
|
||||
- Visual Boy Advance GX -
|
||||
Version 1.0.3
|
||||
http://code.google.com/p/vba-wii
|
||||
Version 1.0.0
|
||||
(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.
|
||||
|
||||
-=[ 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
|
||||
* SRAM and State saving
|
||||
* Custom controller configurations
|
||||
* SD, USB, DVD, SMB, GC Memory Card, Zip, and 7z support
|
||||
* GBA compatiblity based on VBA-M r750, GB compatibility based on VBA 1.7.2
|
||||
* Turbo speed feature
|
||||
* SD and USB support
|
||||
|
||||
×—–—–—–—– –—–—–—–—–—–—–—–—–—–— —–—–—–—–—–—–—–—-—–-–•¬
|
||||
|0O×øo· UPDATE HISTORY ·oø×O0|
|
||||
`¨•¨¨¨¨¨ ¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨ ¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨ ¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨ ¨¨¨¨¨¨¨¨¨¨¨¨¨'
|
||||
|
||||
[What's New 1.0.3 - October 15, 2008]
|
||||
* 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]
|
||||
[What's New 1.0.0]
|
||||
|
||||
* Now compiles with devkitpro r15
|
||||
* One makefile to make all versions
|
||||
|
@ -13,7 +13,6 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <malloc.h>
|
||||
|
||||
#ifdef WII_DVD
|
||||
extern "C" {
|
||||
@ -23,12 +22,14 @@ extern "C" {
|
||||
|
||||
#include "menudraw.h"
|
||||
#include "gcunzip.h"
|
||||
#include "filesel.h"
|
||||
#include "vba.h"
|
||||
|
||||
u64 dvddir = 0; // offset of currently selected file or folder
|
||||
int dvddirlength = 0; // length of currently selected file or folder
|
||||
u64 dvdrootdir = 0; // offset of DVD root
|
||||
extern int offset;
|
||||
extern int selection;
|
||||
extern FILEENTRIES filelist[MAXFILES];
|
||||
extern int maxfiles;
|
||||
u64 dvddir = 0;
|
||||
u64 dvdrootdir = 0;
|
||||
int dvddirlength = 0;
|
||||
bool isWii = false;
|
||||
|
||||
#ifdef HW_DOL
|
||||
@ -36,192 +37,63 @@ bool isWii = false;
|
||||
volatile unsigned long *dvd = (volatile unsigned long *) 0xCC006000;
|
||||
#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
|
||||
*
|
||||
* 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
|
||||
***************************************************************************/
|
||||
#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
|
||||
dvd_read (void *dst, unsigned int len, u64 offset)
|
||||
{
|
||||
|
||||
unsigned char *buffer = (unsigned char *) (unsigned int) DVDreadbuffer;
|
||||
|
||||
if (len > 2048)
|
||||
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)
|
||||
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[1] = 0;
|
||||
dvd[2] = 0xA8000000;
|
||||
dvd[3] = (u32)(offset >> 2);
|
||||
dvd[4] = len;
|
||||
dvd[5] = (u32) buffer;
|
||||
dvd[6] = len;
|
||||
dvd[7] = 3;
|
||||
dvd[0] = 0x2E;
|
||||
dvd[1] = 0;
|
||||
dvd[2] = 0xA8000000;
|
||||
dvd[3] = (u32)(offset >> 2);
|
||||
dvd[4] = len;
|
||||
dvd[5] = (u32) buffer;
|
||||
dvd[6] = len;
|
||||
dvd[7] = 3; /*** Enable reading with DMA ***/
|
||||
while (dvd[7] & 1);
|
||||
memcpy (dst, buffer, len);
|
||||
|
||||
// Enable reading with DMA
|
||||
while (dvd[7] & 1);
|
||||
if (dvd[0] & 0x4) /* Ensure it has completed */
|
||||
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;
|
||||
|
||||
#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;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* 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 **/
|
||||
#define RECLEN 0 /* Record length */
|
||||
#define EXTENT 6 /* Extent */
|
||||
@ -245,7 +117,6 @@ getpvd ()
|
||||
{
|
||||
int sector = 16;
|
||||
u32 rootdir32;
|
||||
unsigned char dvdbuffer[2048];
|
||||
|
||||
dvddir = dvddirlength = 0;
|
||||
IsJoliet = -1;
|
||||
@ -330,7 +201,7 @@ bool TestDVD()
|
||||
***************************************************************************/
|
||||
static int diroffset = 0;
|
||||
static int
|
||||
getentry (int entrycount, unsigned char dvdbuffer[])
|
||||
getentry (int entrycount)
|
||||
{
|
||||
char fname[512]; /* Huge, but experience has determined this */
|
||||
char *ptr;
|
||||
@ -450,7 +321,6 @@ ParseDVDdirectory ()
|
||||
u64 rdoffset;
|
||||
int len = 0;
|
||||
int filecount = 0;
|
||||
unsigned char dvdbuffer[2048];
|
||||
|
||||
// initialize selection
|
||||
selection = offset = 0;
|
||||
@ -470,7 +340,7 @@ ParseDVDdirectory ()
|
||||
|
||||
diroffset = 0;
|
||||
|
||||
while (getentry (filecount, dvdbuffer))
|
||||
while (getentry (filecount))
|
||||
{
|
||||
if(strlen(filelist[filecount].filename) > 0 && filecount < MAXFILES)
|
||||
filecount++;
|
||||
@ -559,15 +429,15 @@ bool SwitchDVDFolder(char origdir[])
|
||||
|
||||
/****************************************************************************
|
||||
* 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
|
||||
* dvddirlength.
|
||||
*
|
||||
* The buffer parameter should re-use the initial ROM buffer
|
||||
* The buffer parameter should re-use the initial ROM buffer.
|
||||
***************************************************************************/
|
||||
|
||||
int
|
||||
LoadDVDFile (unsigned char *buffer, int length)
|
||||
LoadDVDFile (unsigned char *buffer)
|
||||
{
|
||||
int offset;
|
||||
int blocks;
|
||||
@ -575,45 +445,34 @@ LoadDVDFile (unsigned char *buffer, int length)
|
||||
u64 discoffset;
|
||||
char readbuffer[2048];
|
||||
|
||||
dvddir = filelist[selection].offset;
|
||||
dvddirlength = filelist[selection].length;
|
||||
|
||||
// How many 2k blocks to read
|
||||
blocks = dvddirlength / 2048;
|
||||
offset = 0;
|
||||
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);
|
||||
|
||||
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 UnZipFile (buffer, discoffset); // unzip from dvd
|
||||
}
|
||||
return dvddirlength;
|
||||
}
|
||||
|
@ -13,17 +13,10 @@
|
||||
|
||||
int getpvd ();
|
||||
int ParseDVDdirectory ();
|
||||
int LoadDVDFile (unsigned char *buffer, int length);
|
||||
int LoadDVDFile (unsigned char *buffer);
|
||||
bool TestDVD();
|
||||
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[]);
|
||||
void SetDVDDriveType();
|
||||
#ifdef HW_DOL
|
||||
void dvd_motor_off ();
|
||||
#endif
|
||||
|
||||
extern u64 dvddir;
|
||||
extern int dvddirlength;
|
||||
|
||||
#endif
|
||||
|
@ -24,8 +24,14 @@
|
||||
#include "filesel.h"
|
||||
#include "preferences.h"
|
||||
|
||||
// FAT file pointer - the only one we should ever use!
|
||||
FILE * fatfile;
|
||||
FILE * filehandle;
|
||||
|
||||
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
|
||||
@ -61,17 +67,18 @@ bool ChangeFATInterface(int method, bool silent)
|
||||
{
|
||||
devFound = true;
|
||||
fatSetDefaultInterface(PI_INTERNAL_SD);
|
||||
fatEnableReadAhead (PI_INTERNAL_SD, 6, 64);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!devFound && FatIsMounted(PI_SDGECKO_A))
|
||||
{
|
||||
devFound = true;
|
||||
fatSetDefaultInterface(PI_SDGECKO_A);
|
||||
}
|
||||
if(!devFound && FatIsMounted(PI_SDGECKO_B))
|
||||
{
|
||||
devFound = true;
|
||||
fatSetDefaultInterface(PI_SDGECKO_B);
|
||||
}
|
||||
if(!devFound)
|
||||
{
|
||||
@ -86,7 +93,6 @@ bool ChangeFATInterface(int method, bool silent)
|
||||
{
|
||||
devFound = true;
|
||||
fatSetDefaultInterface(PI_USBSTORAGE);
|
||||
fatEnableReadAhead (PI_USBSTORAGE, 6, 64);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -164,54 +170,44 @@ ParseFATdirectory(int method)
|
||||
* LoadFATFile
|
||||
***************************************************************************/
|
||||
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];
|
||||
u32 size;
|
||||
|
||||
/* 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!");
|
||||
return -1;
|
||||
}
|
||||
|
||||
fatfile = fopen (filepath, "rb");
|
||||
if (fatfile > 0)
|
||||
return loadVBAROM(filepath);
|
||||
/*
|
||||
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;
|
||||
}
|
||||
else // load whole file
|
||||
{
|
||||
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);
|
||||
fclose (handle);
|
||||
return size;
|
||||
}
|
||||
else
|
||||
@ -219,29 +215,8 @@ LoadFATFile (char * rbuffer, int length)
|
||||
WaitPrompt((char*) "Error opening file");
|
||||
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;
|
||||
}
|
||||
return 0;*/
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
@ -250,11 +225,15 @@ LoadFATSzFile(char * filepath, unsigned char * rbuffer)
|
||||
int
|
||||
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 )
|
||||
{
|
||||
@ -265,13 +244,15 @@ LoadBufferFromFAT (char *filepath, bool silent)
|
||||
return 0;
|
||||
}
|
||||
|
||||
fseek(fatfile, 0, SEEK_END); // go to end of file
|
||||
size = ftell(fatfile); // get filesize
|
||||
fseek(fatfile, 0, SEEK_SET); // go to start of file
|
||||
fread (savebuffer, 1, size, fatfile);
|
||||
fclose (fatfile);
|
||||
/*** This is really nice, just load the file and decode it ***/
|
||||
while ((read = fread (savebuffer + boffset, 1, 1024, handle)) > 0)
|
||||
{
|
||||
boffset += read;
|
||||
}
|
||||
|
||||
return size;
|
||||
fclose (handle);
|
||||
|
||||
return boffset;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
@ -280,11 +261,13 @@ LoadBufferFromFAT (char *filepath, bool silent)
|
||||
int
|
||||
SaveBufferToFAT (char *filepath, int datasize, bool silent)
|
||||
{
|
||||
if (datasize)
|
||||
{
|
||||
fatfile = fopen (filepath, "wb");
|
||||
FILE *handle;
|
||||
|
||||
if (fatfile <= 0)
|
||||
if (datasize)
|
||||
{
|
||||
handle = fopen (filepath, "wb");
|
||||
|
||||
if (handle <= 0)
|
||||
{
|
||||
char msg[100];
|
||||
sprintf(msg, "Couldn't save %s", filepath);
|
||||
@ -292,8 +275,10 @@ SaveBufferToFAT (char *filepath, int datasize, bool silent)
|
||||
return 0;
|
||||
}
|
||||
|
||||
fwrite (savebuffer, 1, datasize, fatfile);
|
||||
fclose (fatfile);
|
||||
fwrite (savebuffer, 1, datasize, handle);
|
||||
fclose (handle);
|
||||
}
|
||||
|
||||
ClearSaveBuffer ();
|
||||
return datasize;
|
||||
}
|
||||
|
@ -23,12 +23,10 @@
|
||||
|
||||
bool ChangeFATInterface(int method, bool silent);
|
||||
int ParseFATdirectory(int method);
|
||||
int LoadFATFile (char * fbuffer, int length);
|
||||
int LoadFATSzFile(char * filepath, unsigned char * rbuffer);
|
||||
int LoadFATFile (char *filename, int length);
|
||||
int SaveBufferToFAT (char *filepath, int datasize, bool silent);
|
||||
int LoadBufferFromFAT (char *filepath, bool silent);
|
||||
|
||||
extern char currFATdir[MAXPATHLEN];
|
||||
extern FILE * fatfile;
|
||||
|
||||
#endif
|
||||
|
@ -14,7 +14,6 @@
|
||||
#include <string.h>
|
||||
#include <wiiuse/wpad.h>
|
||||
#include <sys/dir.h>
|
||||
#include <malloc.h>
|
||||
|
||||
#ifdef WII_DVD
|
||||
extern "C" {
|
||||
@ -32,12 +31,10 @@ extern "C" {
|
||||
#include "input.h"
|
||||
#include "dvd.h"
|
||||
#include "smbop.h"
|
||||
#include "gcunzip.h"
|
||||
|
||||
int offset;
|
||||
int selection;
|
||||
char currentdir[MAXPATHLEN];
|
||||
char szpath[MAXPATHLEN];
|
||||
int maxfiles;
|
||||
extern int screenheight;
|
||||
|
||||
@ -49,38 +46,20 @@ int hasloaded = 0;
|
||||
|
||||
// Global file entry table
|
||||
FILEENTRIES filelist[MAXFILES];
|
||||
bool inSz = false;
|
||||
|
||||
unsigned char savebuffer[SAVEBUFFERSIZE] ATTRIBUTE_ALIGN (32);
|
||||
|
||||
char ROMFilename[512];
|
||||
bool ROMLoaded = false;
|
||||
|
||||
unsigned char *savebuffer = NULL;
|
||||
int ROMSize = 0;
|
||||
|
||||
/****************************************************************************
|
||||
* AllocSaveBuffer ()
|
||||
* Clear and allocate the savebuffer
|
||||
* ClearSaveBuffer ()
|
||||
* Clear the savebuffer
|
||||
***************************************************************************/
|
||||
void
|
||||
AllocSaveBuffer ()
|
||||
ClearSaveBuffer ()
|
||||
{
|
||||
if (savebuffer != NULL)
|
||||
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;
|
||||
memset (savebuffer, 0, SAVEBUFFERSIZE);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
@ -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
|
||||
*
|
||||
@ -241,25 +198,6 @@ int FileSortCallback(const void *f1, const void *f2)
|
||||
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
|
||||
*
|
||||
@ -273,7 +211,7 @@ void StripExt(char* returnstring, char * inputstring)
|
||||
strcpy (returnstring, inputstring);
|
||||
loc_dot = strrchr(returnstring,'.');
|
||||
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);
|
||||
ph = PAD_ButtonsHeld (0);
|
||||
#ifdef HW_RVL
|
||||
wm_ay = WPAD_Stick (0, 0, 0);
|
||||
wm_sx = WPAD_Stick (0, 1, 1);
|
||||
wm_ay = WPAD_StickY (0, 0);
|
||||
wm_sx = WPAD_StickX (0, 1);
|
||||
|
||||
wp = WPAD_ButtonsDown (0);
|
||||
wh = WPAD_ButtonsHeld (0);
|
||||
@ -334,25 +272,7 @@ int FileSelector (int method)
|
||||
if (filelist[selection].flags) // This is directory
|
||||
{
|
||||
/* update current directory and set new entry list if directory has changed */
|
||||
int status;
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
int status = UpdateDirName(method);
|
||||
if (status == 1) // ok, open directory
|
||||
{
|
||||
switch (method)
|
||||
@ -384,42 +304,37 @@ int FileSelector (int method)
|
||||
}
|
||||
else // this is a file
|
||||
{
|
||||
// 7z file - let's open it up to select a file inside
|
||||
if(IsSz())
|
||||
// store the filename (w/o ext) - used for sram/freeze naming
|
||||
StripExt(ROMFilename, filelist[selection].filename);
|
||||
|
||||
ShowAction ((char *)"Loading...");
|
||||
|
||||
switch (method)
|
||||
{
|
||||
// we'll store the 7z filepath for extraction later
|
||||
if(!MakeROMPath(szpath, method))
|
||||
{
|
||||
WaitPrompt((char*) "Maximum filepath length reached!");
|
||||
return -1;
|
||||
}
|
||||
int szfiles = SzParse(szpath, method);
|
||||
if(szfiles)
|
||||
{
|
||||
maxfiles = szfiles;
|
||||
inSz = true;
|
||||
}
|
||||
else
|
||||
WaitPrompt((char*) "Error opening archive!");
|
||||
case METHOD_SD:
|
||||
case METHOD_USB:
|
||||
ROMSize = LoadFATFile (filelist[selection].filename, filelist[selection].length);
|
||||
break;
|
||||
|
||||
case METHOD_DVD:
|
||||
dvddir = filelist[selection].offset;
|
||||
dvddirlength = filelist[selection].length;
|
||||
//ROMSize = LoadDVDFile (Memory.ROM);
|
||||
break;
|
||||
|
||||
case METHOD_SMB:
|
||||
//ROMSize = LoadSMBFile (filelist[selection].filename, filelist[selection].length);
|
||||
break;
|
||||
}
|
||||
|
||||
if (ROMSize > 0)
|
||||
{
|
||||
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
// store the filename (w/o ext) - used for sram/freeze naming
|
||||
StripExt(ROMFilename, filelist[selection].filename);
|
||||
|
||||
ShowAction ((char *)"Loading...");
|
||||
|
||||
ROMLoaded = LoadVBAROM(method);
|
||||
inSz = false;
|
||||
|
||||
if (ROMLoaded)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
WaitPrompt((char*) "Error loading ROM!");
|
||||
}
|
||||
WaitPrompt((char*) "Error loading ROM!");
|
||||
}
|
||||
}
|
||||
redraw = 1;
|
||||
@ -613,7 +528,7 @@ OpenFAT (int method)
|
||||
{
|
||||
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 );
|
||||
|
||||
// Parse initial root directory and get entries list
|
||||
|
@ -11,11 +11,9 @@
|
||||
#ifndef _NGCFILESEL_
|
||||
#define _NGCFILESEL_
|
||||
|
||||
#include <unistd.h>
|
||||
|
||||
#define SAVEBUFFERSIZE (512 * 1024)
|
||||
#define SAVEBUFFERSIZE ((512 * 1024) + 2048 + 64 + 4 + 4)
|
||||
#define MAXJOLIET 255
|
||||
#define MAXDISPLAY 40
|
||||
#define MAXDISPLAY 54
|
||||
|
||||
typedef struct
|
||||
{
|
||||
@ -28,18 +26,9 @@ typedef struct
|
||||
|
||||
#define MAXFILES 2000 // Restrict to 2000 files per dir
|
||||
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];
|
||||
|
||||
void AllocSaveBuffer();
|
||||
void FreeSaveBuffer();
|
||||
bool MakeROMPath(char filepath[], int method);
|
||||
void ClearSaveBuffer ();
|
||||
int OpenROM (int method);
|
||||
int autoLoadMethod();
|
||||
int autoSaveMethod();
|
||||
|
@ -14,19 +14,11 @@
|
||||
#include <string.h>
|
||||
#include <zlib.h>
|
||||
|
||||
extern "C" {
|
||||
#include "../sz/7zCrc.h"
|
||||
#include "../sz/7zIn.h"
|
||||
#include "../sz/7zExtract.h"
|
||||
}
|
||||
|
||||
#include "dvd.h"
|
||||
#include "smbop.h"
|
||||
#include "fileop.h"
|
||||
#include "video.h"
|
||||
#include "menudraw.h"
|
||||
#include "gcunzip.h"
|
||||
#include "vba.h"
|
||||
|
||||
/*
|
||||
* PKWare Zip Header - adopted into zip standard
|
||||
@ -67,7 +59,7 @@ FLIP16 (u16 b)
|
||||
* IsZipFile
|
||||
*
|
||||
* Returns TRUE when PKZIPID is first four characters of buffer
|
||||
***************************************************************************/
|
||||
****************************************************************************/
|
||||
int
|
||||
IsZipFile (char *buffer)
|
||||
{
|
||||
@ -81,14 +73,17 @@ IsZipFile (char *buffer)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* UnZipBuffer
|
||||
*
|
||||
* It should be noted that there is a limit of 5MB total size for any ROM
|
||||
******************************************************************************/
|
||||
/*****************************************************************************
|
||||
* unzip
|
||||
*
|
||||
* 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
|
||||
UnZipBuffer (unsigned char *outbuffer, int method)
|
||||
UnZipBuffer (unsigned char *outbuffer, short where)
|
||||
{
|
||||
PKZIPHEADER pkzip;
|
||||
int zipoffset = 0;
|
||||
@ -100,25 +95,23 @@ UnZipBuffer (unsigned char *outbuffer, int method)
|
||||
int readoffset = 0;
|
||||
int have = 0;
|
||||
char readbuffer[ZIPCHUNK];
|
||||
u64 discoffset = 0;
|
||||
char msg[128];
|
||||
|
||||
// Read Zip Header
|
||||
switch (method)
|
||||
/*** Read Zip Header ***/
|
||||
switch (where)
|
||||
{
|
||||
case METHOD_SD:
|
||||
case METHOD_USB:
|
||||
fseek(fatfile, 0, SEEK_SET);
|
||||
fread (readbuffer, 1, ZIPCHUNK, fatfile);
|
||||
break;
|
||||
case 0: // SD Card
|
||||
fseek(fatfile, 0, SEEK_SET);
|
||||
fread (readbuffer, 1, ZIPCHUNK, fatfile);
|
||||
break;
|
||||
|
||||
case METHOD_DVD:
|
||||
discoffset = dvddir;
|
||||
dvd_read (readbuffer, ZIPCHUNK, discoffset);
|
||||
break;
|
||||
case 1: // DVD
|
||||
dvd_read (readbuffer, ZIPCHUNK, discoffset);
|
||||
break;
|
||||
|
||||
case METHOD_SMB:
|
||||
SMB_ReadFile(readbuffer, ZIPCHUNK, 0, smbfile);
|
||||
break;
|
||||
case 2: // From SMB
|
||||
SMB_ReadFile(readbuffer, ZIPCHUNK, 0, smbfile);
|
||||
break;
|
||||
}
|
||||
|
||||
/*** Copy PKZip header to local, used as info ***/
|
||||
@ -126,7 +119,9 @@ UnZipBuffer (unsigned char *outbuffer, int method)
|
||||
|
||||
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 ***/
|
||||
memset (&zs, 0, sizeof (z_stream));
|
||||
@ -176,28 +171,26 @@ UnZipBuffer (unsigned char *outbuffer, int method)
|
||||
}
|
||||
while (zs.avail_out == 0);
|
||||
|
||||
// Readup the next 2k block
|
||||
/*** Readup the next 2k block ***/
|
||||
zipoffset = 0;
|
||||
zipchunk = ZIPCHUNK;
|
||||
|
||||
switch (method)
|
||||
switch (where)
|
||||
{
|
||||
case METHOD_SD:
|
||||
case METHOD_USB:
|
||||
fread (readbuffer, 1, ZIPCHUNK, fatfile);
|
||||
break;
|
||||
case 0: // SD Card
|
||||
fread (readbuffer, 1, ZIPCHUNK, fatfile);
|
||||
break;
|
||||
|
||||
case METHOD_DVD:
|
||||
readoffset += ZIPCHUNK;
|
||||
dvd_safe_read (readbuffer, ZIPCHUNK, discoffset+readoffset);
|
||||
break;
|
||||
case 1: // DVD
|
||||
readoffset += ZIPCHUNK;
|
||||
dvd_read (readbuffer, ZIPCHUNK, discoffset+readoffset);
|
||||
break;
|
||||
|
||||
case METHOD_SMB:
|
||||
readoffset += ZIPCHUNK;
|
||||
SMB_ReadFile(readbuffer, ZIPCHUNK, readoffset, smbfile);
|
||||
break;
|
||||
case 2: // From SMB
|
||||
readoffset += ZIPCHUNK;
|
||||
SMB_ReadFile(readbuffer, ZIPCHUNK, readoffset, smbfile);
|
||||
break;
|
||||
}
|
||||
ShowProgress ((char *)"Loading...", bufferoffset, pkzip.uncompressedSize);
|
||||
}
|
||||
while (res != Z_STREAM_END);
|
||||
|
||||
@ -213,344 +206,24 @@ UnZipBuffer (unsigned char *outbuffer, int method)
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* 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
|
||||
****************************************************************************/
|
||||
// Reading from FAT
|
||||
int
|
||||
Is7ZipFile (char *buffer)
|
||||
UnZipFile (unsigned char *outbuffer, FILE* infile)
|
||||
{
|
||||
unsigned int *check;
|
||||
check = (unsigned int *) buffer;
|
||||
|
||||
// 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
|
||||
fatfile = infile;
|
||||
return UnZipBuffer(outbuffer, 0);
|
||||
}
|
||||
|
||||
// display an error message
|
||||
void SzDisplayError(SZ_RESULT res)
|
||||
// Reading from DVD
|
||||
int
|
||||
UnZipFile (unsigned char *outbuffer, u64 inoffset)
|
||||
{
|
||||
WaitPrompt(szerrormsg[(res - 1)]);
|
||||
discoffset = inoffset;
|
||||
return UnZipBuffer(outbuffer, 1);
|
||||
}
|
||||
|
||||
// function used by the 7zip SDK to read data from SD/USB/DVD/SMB
|
||||
SZ_RESULT SzFileReadImp(void *object, void **buffer, size_t maxRequiredSize, size_t *processedSize)
|
||||
// Reading from SMB
|
||||
int
|
||||
UnZipFile (unsigned char *outbuffer, SMBFILE infile)
|
||||
{
|
||||
// the void* object is a SzFileInStream
|
||||
SzFileInStream *s = (SzFileInStream *) object;
|
||||
|
||||
// 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;
|
||||
}
|
||||
smbfile = infile;
|
||||
return UnZipBuffer(outbuffer, 2);
|
||||
}
|
||||
|
@ -12,12 +12,11 @@
|
||||
|
||||
#include <smb.h>
|
||||
|
||||
int IsZipFile (char *buffer);
|
||||
char * GetFirstZipFilename(int method);
|
||||
int UnZipBuffer (unsigned char *outbuffer, int method);
|
||||
int SzParse(char * filepath, int method);
|
||||
int SzExtractFile(int i, unsigned char *buffer);
|
||||
void SzClose();
|
||||
extern int IsZipFile (char *buffer);
|
||||
|
||||
int UnZipFile (unsigned char *outbuffer, FILE* infile); // Reading from FAT
|
||||
int UnZipFile (unsigned char *outbuffer, u64 inoffset); // Reading from DVD
|
||||
int UnZipFile (unsigned char *outbuffer, SMBFILE infile); // Reading from SMB
|
||||
|
||||
/*
|
||||
* 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_
|
||||
#define _IMGSAVEICON_
|
||||
|
||||
const unsigned long saveicon[32*32] = {
|
||||
0x579A5753, 0x579A5753, 0x579A5753, 0x579A5753, 0x579A5753, 0x579A5753, 0x579A5753, 0x579A5753,
|
||||
0x579A5753, 0x579A5753, 0x579A5753, 0x579A5753, 0x579A5753, 0x579A5753, 0x579A5753, 0x579A5753,
|
||||
0x589B5852, 0x589B5852, 0x589B5852, 0x589B5852, 0x589B5852, 0x589B5852, 0x589B5852, 0x589B5852,
|
||||
0x589B5852, 0x589B5852, 0x589B5852, 0x589B5852, 0x589B5852, 0x589B5852, 0x589B5852, 0x589B5852,
|
||||
0x589B5852, 0x589B5852, 0x589B5852, 0x589B5852, 0x589B5852, 0x589B5852, 0x589B5852, 0x589B5852,
|
||||
0x589B5852, 0x589B5852, 0x589B5852, 0x589B5852, 0x589B5852, 0x589B5852, 0x589B5852, 0x589B5852,
|
||||
0x599B5951, 0x599B5951, 0x599B5951, 0x599B5951, 0x599B5951, 0x599B5951, 0x599B5951, 0x599B5951,
|
||||
0x599B5951, 0x599B5951, 0x599B5951, 0x599B5951, 0x5A9B5951, 0x599B5951, 0x599B5951, 0x599B5951,
|
||||
0x5A9B5A51, 0x5A9B5A51, 0x5A9B5A51, 0x5A9B5A51, 0x5A9B5A51, 0x5A9B5A51, 0x5A9B5A51, 0x5A9B5A51,
|
||||
0x5A9B5A51, 0x5A9B5A51, 0x5A9B5A51, 0x5A9B5A51, 0x5A9B5A51, 0x5A9B5A51, 0x5A9B5A51, 0x5A9B5A51,
|
||||
0x5B9C5B51, 0x5B9C5B51, 0x5B9C5B51, 0x5B9C5B51, 0x5B9C5B51, 0x5B9C5B51, 0x5B9C5B51, 0x5B9C5B51,
|
||||
0x5B9C5B51, 0x5B9C5B51, 0x5B9C5B51, 0x5B9C5B51, 0x5B9C5B51, 0x5B9C5B51, 0x5B9C5C50, 0x5B9C5B51,
|
||||
0x5C9C5C50, 0x5C9C5C50, 0x5C9C5C50, 0x5C9C5C50, 0x5C9C5C50, 0x5C9C5C50, 0x5C9C5C50, 0x5C9C5C50,
|
||||
0x5C9C5C50, 0x5C9C5C50, 0x5C9C5C50, 0x5C9C5C50, 0x5C9C5C50, 0x5C9C5C50, 0x5C9C5C50, 0x5C9C5C50,
|
||||
0x5D9C5C50, 0x5C9C5D50, 0x5C9C5C50, 0x5D9C5C50, 0x5D9C5C50, 0x5D9C5C50, 0x5D9C5C50, 0x5C9C5C50,
|
||||
0x5C9C5C50, 0x5C9C5D50, 0x5C9C5C50, 0x5C9C5C50, 0x5C9C5C50, 0x5C9C5C50, 0x5C9C5C50, 0x5C9C5D50,
|
||||
0x5D9C5D50, 0x5E9C5E4F, 0x5D9C5E4F, 0x5E9C5D4F, 0x5E9C5E4F, 0x5D9C5E4F, 0x5D9C5E4F, 0x5E9C5D4F,
|
||||
0x5E9C5E4F, 0x5E9C5E4F, 0x5D9C5D50, 0x5D9C5D50, 0x5D9C5D50, 0x5E9C5E4F, 0x5E9C5D4F, 0x5E9C5D4F,
|
||||
0x5E9D5E4F, 0x5E9D5E4F, 0x5E9D5E4F, 0x5E9D5E4F, 0x5E9D5E4F, 0x5E9D5E4F, 0x5F9D5E4F, 0x5E9D5E4F,
|
||||
0x5E9D5E4F, 0x5E9D5F4F, 0x5E9D5E4F, 0x5F9D5E4F, 0x5E9D5F4F, 0x5E9D5E4F, 0x5E9D5E4F, 0x5F9D5E4F,
|
||||
0x5F9B5351, 0x27860075, 0x00862775, 0x5F9D5F4E, 0x27860075, 0x12882770, 0x00800080, 0x00800080,
|
||||
0x00800080, 0x1F8F4765, 0x5F9D5F4F, 0x5A93275E, 0x00800080, 0x26914D62, 0x5F9D5F4E, 0x5F9D5F4E,
|
||||
0x60952C5B, 0x6551C69C, 0xCD631B91, 0x53974658, 0x3761D091, 0xA766468F, 0xD658D898, 0xD85AD897,
|
||||
0xD755D399, 0x89741F81, 0x549B6051, 0x337C6179, 0xD454D49A, 0x7B77267F, 0x609D604E, 0x609D604E,
|
||||
0x609A4654, 0x2F53BB9B, 0xC5595197, 0x3A903363, 0x5E58C998, 0x5D69428D, 0xCA4ACBA0, 0xCC4CCC9F,
|
||||
0xCB49C7A1, 0xC554699A, 0x2D95615B, 0x136EA387, 0xD050D09C, 0xBB67068D, 0x609E604E, 0x619D604E,
|
||||
0x629D624D, 0x0D5E9891, 0xBC4D779F, 0x27881370, 0x9E4AC1A1, 0x326B3E8C, 0xBA3ABBAA, 0x25790084,
|
||||
0x0062A292, 0xBC459AA4, 0x138F5465, 0x1A60C893, 0xBE4DCC9E, 0xC4583198, 0x48996254, 0x629D624D,
|
||||
0x639E624D, 0x276A6386, 0xB03CA4A9, 0x0D7D197F, 0xBE3F9EA7, 0x0D733985, 0xAF31B3B0, 0x24780084,
|
||||
0x00609E93, 0xB94C589F, 0x34903564, 0x5851BF9C, 0x7350B49D, 0xBB466BA3, 0x2795625C, 0x629E634D,
|
||||
0x639E634C, 0x427B3578, 0xA42BB1B4, 0x3167498E, 0xB13E66A8, 0x2776367F, 0xA426A7B7, 0xAC2DAFB2,
|
||||
0xAF30B1B0, 0x786C2186, 0x5E921A60, 0x853EB2A8, 0x2E5D6A94, 0xAE3293AF, 0x0D916363, 0x639E634C,
|
||||
0x659F644C, 0x65900664, 0x9529A3B7, 0x4E4D6F9F, 0xA34041A7, 0x3C7A347A, 0x9F26A0B9, 0xA126A2B9,
|
||||
0xA225A3B8, 0xA74050A6, 0x2F811776, 0xAA2A9AB4, 0x006E418B, 0xA425A4B8, 0x20825070, 0x649F654C,
|
||||
0x659E654C, 0x65931B5F, 0x73349EB2, 0x753695B0, 0x94570799, 0x437B3478, 0x9D289EBB, 0x1F770085,
|
||||
0x005F7595, 0xA12998B7, 0x076B4B8B, 0xA1269FB9, 0x9E289EBB, 0x9E27A0B9, 0x4B73357F, 0x659E654C,
|
||||
0x659F654C, 0x65983C56, 0x3D439AAA, 0x9A299ABC, 0x70641B8F, 0x437C3378, 0x9B299CBB, 0x1F770085,
|
||||
0x00626993, 0x9E2B93B9, 0x07617393, 0x992A97BC, 0x962C96BD, 0x982A9BBC, 0x7E5F1492, 0x659F654C,
|
||||
0x679F674B, 0x669D594E, 0x144F97A2, 0x962C96BD, 0x46743680, 0x447B3278, 0x972B97BD, 0x972B97BD,
|
||||
0x972B97BD, 0x983965B2, 0x0A558D9E, 0x8A560A9F, 0x00800080, 0x454197AD, 0x9A4E14A2, 0x599D674E,
|
||||
0x679F674A, 0x679F674A, 0x14617793, 0x932D93BF, 0x14875A6C, 0x447C3178, 0x932D92BF, 0x922D92BF,
|
||||
0x922D92BF, 0x586C228A, 0x444393AE, 0x6B651B8F, 0x679C534F, 0x1D4D95A5, 0x974148AC, 0x37976756,
|
||||
0x68A0674A, 0x68A0684A, 0x3F8C146A, 0x00800080, 0x2A966859, 0x68962A59, 0x00800080, 0x00800080,
|
||||
0x00800080, 0x2A93545F, 0x2A860075, 0x1B8E4766, 0x68A0674A, 0x2A860075, 0x00862A74, 0x639F674B,
|
||||
0x699F684A, 0x699F694A, 0x699F684A, 0x699F694A, 0x699F694A, 0x699F694A, 0x699F694A, 0x699F694A,
|
||||
0x699F694A, 0x699F694A, 0x699F694A, 0x699F694A, 0x699F694A, 0x699F694A, 0x699F694A, 0x699F694A,
|
||||
0x6AA06949, 0x69A0694A, 0x69A06A49, 0x69A06A49, 0x6AA06949, 0x69A0694A, 0x69A0694A, 0x69A0694A,
|
||||
0x6AA06949, 0x69A06A49, 0x69A06A49, 0x69A0694A, 0x69A0694A, 0x6AA06949, 0x69A0694A, 0x69A0694A,
|
||||
0x6BA06A49, 0x6AA06A49, 0x6BA06B49, 0x6AA06B49, 0x6AA06B49, 0x6BA06B49, 0x6AA06B49, 0x6BA06B49,
|
||||
0x6BA06B49, 0x6BA06A49, 0x6BA06A49, 0x6AA06B49, 0x6BA06B49, 0x6BA06A49, 0x6AA06B49, 0x6BA06B49,
|
||||
0x6CA16B48, 0x6BA16B48, 0x6BA16B48, 0x6BA16B48, 0x6BA16B48, 0x6BA16B48, 0x6BA16B48, 0x6BA16B48,
|
||||
0x6BA16B48, 0x6BA16B48, 0x6BA16B48, 0x6BA16B48, 0x6BA16B48, 0x6BA16B48, 0x6BA16B48, 0x6BA16B48,
|
||||
0x6CA16C48, 0x6CA16C48, 0x6CA16C48, 0x6CA16C48, 0x6CA16C48, 0x6CA16C48, 0x6CA16C48, 0x6CA16C48,
|
||||
0x6CA16C48, 0x6CA16C48, 0x6CA16C48, 0x6CA16C48, 0x6CA16C48, 0x6CA16C48, 0x6CA16C48, 0x6CA16C48,
|
||||
0x6DA16C48, 0x6DA16D48, 0x6DA16D48, 0x6DA16D48, 0x6DA16C48, 0x6CA16D48, 0x6CA16D48, 0x6DA16D48,
|
||||
0x6DA16D48, 0x6DA16D48, 0x6CA16D48, 0x6DA16D48, 0x6DA16D48, 0x6DA16D48, 0x6CA16D48, 0x6DA16D48,
|
||||
0x6EA16E47, 0x6DA16D47, 0x6DA16D47, 0x6DA16D47, 0x6DA16D47, 0x6EA16D47, 0x6DA16D47, 0x6DA16E47,
|
||||
0x6DA16D47, 0x6DA16D47, 0x6DA16E47, 0x6DA16D47, 0x6DA16D47, 0x6EA16D47, 0x6DA16D47, 0x6DA16D47,
|
||||
0x6EA16E46, 0x6EA16E46, 0x6EA16E47, 0x6EA16E46, 0x6EA16E46, 0x6EA16E46, 0x6EA16E46, 0x6EA16E47,
|
||||
0x6EA16E46, 0x6EA16E47, 0x6EA16E46, 0x6EA16E46, 0x6EA16E47, 0x6EA16E46, 0x6EA16E46, 0x6EA16E46,
|
||||
0x6FA26F47, 0x6FA16E46, 0x6FA16E46, 0x6FA26F47, 0x6FA26F47, 0x6FA26F47, 0x6FA26F47, 0x6FA26F47,
|
||||
0x6FA26F47, 0x6FA26F47, 0x6FA26F47, 0x6FA26F47, 0x6FA26F47, 0x6FA26F47, 0x6FA26F47, 0x6FA26F47,
|
||||
0x70A27046, 0x70A27046, 0x70A27046, 0x70A27046, 0x70A27046, 0x70A27046, 0x70A27046, 0x70A27046,
|
||||
0x70A27046, 0x70A27046, 0x70A27046, 0x70A27046, 0x70A27046, 0x70A27046, 0x70A27046, 0x70A27046,
|
||||
const unsigned short saveicon[1024] = {
|
||||
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, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
|
||||
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xE73F,
|
||||
0xFFFF, 0xFFFF, 0xB5BF, 0x801F, 0xFFFF, 0xD29F, 0x801F, 0x801F,
|
||||
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xA11E, 0x843C, 0x8439, 0x9CF7,
|
||||
0x801F, 0x801F, 0x801C, 0x8018, 0x801F, 0x801F, 0x801C, 0x8018,
|
||||
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xEB5C, 0xFFFF, 0xFFFF, 0xFFFF,
|
||||
0x800F, 0xB9D3, 0xFFFF, 0xFFFF, 0x8013, 0x8008, 0xDAD7, 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, 0x801F, 0x801F, 0x885F, 0xFFFF, 0x98D6, 0x801F, 0x801F,
|
||||
0xFFFF, 0xFFFF, 0xFFFF, 0x843C, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
|
||||
0xFBDF, 0x801E, 0x801B, 0x8017, 0x801E, 0x801B, 0x8018, 0x8015,
|
||||
0x801A, 0x8018, 0x8015, 0x8011, 0x8016, 0x8014, 0x8011, 0x800D,
|
||||
0x8012, 0x800B, 0x8848, 0xFFFF, 0x8010, 0x8009, 0x8003, 0xFFFF,
|
||||
0x800C, 0x8007, 0x8006, 0xFFFF, 0x8008, 0x8005, 0xA52E, 0xFFFF,
|
||||
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
|
||||
0xFFFF, 0xFFFF, 0xFBBD, 0xF1EF, 0xFFFF, 0xF508, 0xF000, 0xEC00,
|
||||
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
|
||||
0xE56B, 0xE16B, 0xE673, 0xFFFF, 0xE800, 0xDC00, 0xCC00, 0xB400,
|
||||
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
|
||||
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xDE94, 0xFFFF, 0xFFFF, 0xFFFF,
|
||||
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
|
||||
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xEBBA,
|
||||
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
|
||||
0xFFFF, 0xFFFF, 0xEFBA, 0xE378, 0xB2EB, 0x9AA4, 0x9AA5, 0x9AA5,
|
||||
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
|
||||
0xE778, 0xF3BC, 0xFFFF, 0xFFFF, 0x9A84, 0x9623, 0x91E3, 0xB66C,
|
||||
0xD6BB, 0x800E, 0x800C, 0x8008, 0xFFFF, 0x8C6A, 0x8004, 0x8004,
|
||||
0xFFFF, 0xFFFF, 0xB191, 0xDAD8, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
|
||||
0x8006, 0x8004, 0xFFFF, 0xFFFF, 0x8006, 0xF39D, 0xFFFF, 0xFA94,
|
||||
0xFFFF, 0xFFFF, 0xFFFF, 0xEC21, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
|
||||
0xF484, 0xF800, 0xF800, 0xF000, 0xF800, 0xF800, 0xFD6B, 0xF8C6,
|
||||
0xF400, 0xF400, 0xFDEF, 0xF4A5, 0xFF18, 0xEC63, 0xE400, 0xE000,
|
||||
0xE800, 0xE000, 0xD400, 0xC400, 0xE400, 0xE000, 0xD000, 0xC400,
|
||||
0xE000, 0xD800, 0xCC00, 0xC000, 0xD800, 0xD000, 0xC400, 0xB800,
|
||||
0xA400, 0xD673, 0xFFFF, 0xFFFF, 0xB400, 0x9000, 0xFFFF, 0xFFFF,
|
||||
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
|
||||
|
@ -26,6 +26,8 @@
|
||||
#include "input.h"
|
||||
#include "tbtime.h"
|
||||
|
||||
#define MAXJP 10
|
||||
|
||||
#define VBA_BUTTON_A 1
|
||||
#define VBA_BUTTON_B 2
|
||||
#define VBA_BUTTON_SELECT 4
|
||||
@ -82,13 +84,14 @@ unsigned int ncpadmap[] = {
|
||||
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 ang = 0.0;
|
||||
@ -122,19 +125,63 @@ s8 WPAD_Stick(u8 chan, u8 right, int axis)
|
||||
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;
|
||||
else if (mag < -1.0) mag = -1.0;
|
||||
double val;
|
||||
|
||||
if(axis == 0) // x-axis
|
||||
val = mag * sin((PI * ang)/180.0f);
|
||||
else // y-axis
|
||||
val = mag * cos((PI * ang)/180.0f);
|
||||
double val = mag * sin((PI * ang)/180.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
|
||||
*
|
||||
@ -146,15 +193,16 @@ u32 DecodeJoy(unsigned short pad)
|
||||
{
|
||||
signed char pad_x = PAD_StickX (pad);
|
||||
signed char pad_y = PAD_StickY (pad);
|
||||
signed char gc_px = PAD_SubStickX (0);
|
||||
u32 jp = PAD_ButtonsHeld (pad);
|
||||
u32 J = 0;
|
||||
unsigned char J = 0;
|
||||
|
||||
#ifdef HW_RVL
|
||||
signed char wm_ax = WPAD_Stick ((u8)pad, 0, 0);
|
||||
signed char wm_ay = WPAD_Stick ((u8)pad, 0, 1);
|
||||
u32 wp = WPAD_ButtonsHeld (pad);
|
||||
signed char wm_sx = WPAD_Stick (0,1,0); // CC right joystick
|
||||
signed char wm_ax = 0;
|
||||
signed char wm_ay = 0;
|
||||
u32 wp = 0;
|
||||
wm_ax = WPAD_StickX ((u8)pad, 0);
|
||||
wm_ay = WPAD_StickY ((u8)pad, 0);
|
||||
wp = WPAD_ButtonsHeld (pad);
|
||||
|
||||
u32 exp_type;
|
||||
if ( WPAD_Probe(pad, &exp_type) != 0 ) exp_type = WPAD_EXP_NONE;
|
||||
@ -235,16 +283,6 @@ u32 DecodeJoy(unsigned short pad)
|
||||
}
|
||||
#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) ***/
|
||||
int i;
|
||||
|
||||
@ -260,37 +298,20 @@ u32 DecodeJoy(unsigned short pad)
|
||||
J |= vbapadmap[i];
|
||||
}
|
||||
|
||||
if ((J & 48) == 48)
|
||||
J &= ~16;
|
||||
if ((J & 192) == 192)
|
||||
J &= ~128;
|
||||
|
||||
return J;
|
||||
}
|
||||
u32 GetJoy()
|
||||
{
|
||||
int pad = 0;
|
||||
u32 res = 0;
|
||||
|
||||
s8 gc_px = PAD_SubStickX (0);
|
||||
s8 gc_py = PAD_SubStickY (0);
|
||||
|
||||
#ifdef HW_RVL
|
||||
s8 wm_sx = WPAD_Stick (0,1,0);
|
||||
s8 wm_sy = WPAD_Stick (0,1,1);
|
||||
s8 wm_sx = WPAD_StickX (0,1);
|
||||
u32 wm_pb = WPAD_ButtonsHeld (0); // wiimote / expansion button info
|
||||
#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
|
||||
if ((gc_px < -70)
|
||||
#ifdef HW_RVL
|
||||
@ -302,24 +323,28 @@ u32 GetJoy()
|
||||
{
|
||||
if (GCSettings.AutoSave == 1)
|
||||
{
|
||||
SaveBatteryOrState(GCSettings.SaveMethod, 0, SILENT); // save battery
|
||||
SaveBattery(GCSettings.SaveMethod, SILENT);
|
||||
}
|
||||
else if (GCSettings.AutoSave == 2)
|
||||
{
|
||||
SaveBatteryOrState(GCSettings.SaveMethod, 1, SILENT); // save state
|
||||
SaveState(GCSettings.SaveMethod, SILENT);
|
||||
}
|
||||
else if(GCSettings.AutoSave == 3)
|
||||
{
|
||||
SaveBatteryOrState(GCSettings.SaveMethod, 0, SILENT); // save battery
|
||||
SaveBatteryOrState(GCSettings.SaveMethod, 1, SILENT); // save state
|
||||
SaveBattery(GCSettings.SaveMethod, SILENT);
|
||||
SaveState(GCSettings.SaveMethod, SILENT);
|
||||
}
|
||||
// change to menu video mode
|
||||
ResetVideo_Menu ();
|
||||
MainMenu(3);
|
||||
return 0;
|
||||
}
|
||||
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 PADCAL 50
|
||||
#define MAXJP 10
|
||||
|
||||
extern unsigned int gcpadmap[];
|
||||
extern unsigned int wmpadmap[];
|
||||
extern unsigned int ccpadmap[];
|
||||
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();
|
||||
|
||||
|
@ -25,6 +25,7 @@
|
||||
|
||||
#define VERIFBUFFERSIZE 65536
|
||||
static u8 SysArea[CARD_WORKAREA] ATTRIBUTE_ALIGN (32);
|
||||
extern unsigned char savebuffer[];
|
||||
unsigned char verifbuffer[VERIFBUFFERSIZE] ATTRIBUTE_ALIGN (32);
|
||||
card_dir CardDir;
|
||||
card_file CardFile;
|
||||
@ -67,7 +68,7 @@ bool TestCard(int slot, bool silent)
|
||||
|
||||
/*** Initialize Card System ***/
|
||||
memset (SysArea, 0, CARD_WORKAREA);
|
||||
CARD_Init ("VBA0", "00");
|
||||
CARD_Init ("SNES", "00");
|
||||
|
||||
/*** Try to mount the card ***/
|
||||
if (MountCard(slot, silent) == 0)
|
||||
@ -135,7 +136,7 @@ VerifyMCFile (unsigned char *buf, int slot, char *filename, int datasize)
|
||||
|
||||
/*** Initialize Card System ***/
|
||||
memset (SysArea, 0, CARD_WORKAREA);
|
||||
CARD_Init ("VBA0", "00");
|
||||
CARD_Init ("SNES", "00");
|
||||
|
||||
/*** Try to mount the card ***/
|
||||
CardError = MountCard(slot, NOTSILENT);
|
||||
@ -214,7 +215,7 @@ LoadBufferFromMC (unsigned char *buf, int slot, char *filename, bool silent)
|
||||
|
||||
/*** Initialize Card System ***/
|
||||
memset (SysArea, 0, CARD_WORKAREA);
|
||||
CARD_Init ("VBA0", "00");
|
||||
CARD_Init ("SNES", "00");
|
||||
|
||||
/*** Try to mount the card ***/
|
||||
CardError = MountCard(slot, NOTSILENT);
|
||||
@ -278,7 +279,7 @@ SaveBufferToMC (unsigned char *buf, int slot, char *filename, int datasize, bool
|
||||
|
||||
/*** Initialize Card System ***/
|
||||
memset (SysArea, 0, CARD_WORKAREA);
|
||||
CARD_Init ("VBA0", "00");
|
||||
CARD_Init ("SNES", "00");
|
||||
|
||||
/*** Try to mount the card ***/
|
||||
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 int menu;
|
||||
extern bool ROMLoaded;
|
||||
extern int ROMSize;
|
||||
|
||||
#define SOFTRESET_ADR ((volatile u32*)0xCC003024)
|
||||
|
||||
@ -83,9 +83,9 @@ LoadManager ()
|
||||
if ( loadROM == 1 ) // if ROM was loaded, load the battery / state
|
||||
{
|
||||
if (GCSettings.AutoLoad == 1)
|
||||
LoadBatteryOrState(GCSettings.SaveMethod, 0, SILENT); // load battery
|
||||
LoadBattery(GCSettings.SaveMethod, SILENT);
|
||||
else if (GCSettings.AutoLoad == 2)
|
||||
LoadBatteryOrState(GCSettings.SaveMethod, 1, SILENT); // load state
|
||||
LoadState(GCSettings.SaveMethod, SILENT);
|
||||
}
|
||||
|
||||
return loadROM;
|
||||
@ -94,7 +94,7 @@ LoadManager ()
|
||||
/****************************************************************************
|
||||
* Preferences Menu
|
||||
***************************************************************************/
|
||||
static int prefmenuCount = 11;
|
||||
static int prefmenuCount = 9;
|
||||
static char prefmenu[][50] = {
|
||||
|
||||
"Load Method",
|
||||
@ -105,8 +105,6 @@ static char prefmenu[][50] = {
|
||||
"Auto Load",
|
||||
"Auto Save",
|
||||
"Verify MC Saves",
|
||||
"Enable Zooming",
|
||||
"Video Rendering",
|
||||
|
||||
"Save Preferences",
|
||||
"Back to Main Menu"
|
||||
@ -124,26 +122,40 @@ PreferencesMenu ()
|
||||
// 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
|
||||
|
||||
// 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
|
||||
#ifdef HW_DOL
|
||||
#ifndef HW_RVL
|
||||
if(GCSettings.LoadMethod == METHOD_USB)
|
||||
GCSettings.LoadMethod++;
|
||||
if(GCSettings.SaveMethod == METHOD_USB)
|
||||
GCSettings.SaveMethod++;
|
||||
#endif
|
||||
|
||||
// saving to DVD is impossible
|
||||
if(GCSettings.SaveMethod == METHOD_DVD)
|
||||
GCSettings.SaveMethod++;
|
||||
|
||||
// disable DVD in GC mode (not implemented)
|
||||
#ifdef HW_DOL
|
||||
// check if DVD access in Wii mode is disabled
|
||||
#ifndef WII_DVD
|
||||
if(GCSettings.LoadMethod == METHOD_DVD)
|
||||
GCSettings.LoadMethod++;
|
||||
#endif
|
||||
|
||||
// saving to DVD is impossible
|
||||
if(GCSettings.SaveMethod == METHOD_DVD)
|
||||
GCSettings.SaveMethod++;
|
||||
|
||||
// disable SMB in GC mode (stalls out)
|
||||
#ifdef HW_DOL
|
||||
#ifndef HW_RVL
|
||||
if(GCSettings.LoadMethod == METHOD_SMB)
|
||||
GCSettings.LoadMethod++;
|
||||
if(GCSettings.SaveMethod == METHOD_SMB)
|
||||
@ -156,9 +168,6 @@ PreferencesMenu ()
|
||||
GCSettings.SaveMethod++;
|
||||
if(GCSettings.SaveMethod == METHOD_MC_SLOTB)
|
||||
GCSettings.SaveMethod++;
|
||||
prefmenu[6][0] = 0;
|
||||
#else
|
||||
sprintf (prefmenu[6], "Verify MC Saves %s", GCSettings.VerifySaves == true ? " ON" : "OFF");
|
||||
#endif
|
||||
|
||||
// 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 == 3) sprintf (prefmenu[5],"Auto Save BOTH");
|
||||
|
||||
sprintf (prefmenu[7], "Enable Zooming %s",
|
||||
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");
|
||||
//sprintf (prefmenu[6], "Verify MC Saves %s", GCSettings.VerifySaves == true ? " ON" : "OFF");
|
||||
|
||||
ret = RunMenu (prefmenu, prefmenuCount, (char*)"Preferences", 16);
|
||||
|
||||
@ -240,23 +243,11 @@ PreferencesMenu ()
|
||||
break;
|
||||
|
||||
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);
|
||||
break;
|
||||
|
||||
case -1: /*** Button B ***/
|
||||
case 10:
|
||||
case 8:
|
||||
quit = 1;
|
||||
break;
|
||||
|
||||
@ -272,13 +263,12 @@ PreferencesMenu ()
|
||||
int
|
||||
GameMenu ()
|
||||
{
|
||||
int gamemenuCount = 8;
|
||||
int gamemenuCount = 7;
|
||||
char gamemenu[][50] = {
|
||||
"Return to Game",
|
||||
"Reset Game",
|
||||
"Load SRAM", "Save SRAM",
|
||||
"Load Game Snapshot", "Save Game Snapshot",
|
||||
"Reset Zoom",
|
||||
"Back to Main Menu"
|
||||
};
|
||||
|
||||
@ -305,9 +295,6 @@ GameMenu ()
|
||||
gamemenu[3][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");
|
||||
|
||||
@ -323,29 +310,23 @@ GameMenu ()
|
||||
break;
|
||||
|
||||
case 2: // Load Battery
|
||||
quit = retval = LoadBatteryOrState(GCSettings.SaveMethod, 0, NOTSILENT);
|
||||
emulator.emuReset();
|
||||
quit = retval = LoadBattery(GCSettings.SaveMethod, NOTSILENT);
|
||||
break;
|
||||
|
||||
case 3: // Save Battery
|
||||
SaveBatteryOrState(GCSettings.SaveMethod, 0, NOTSILENT);
|
||||
SaveBattery(GCSettings.SaveMethod, NOTSILENT);
|
||||
break;
|
||||
|
||||
case 4: // Load State
|
||||
quit = retval = LoadBatteryOrState(GCSettings.SaveMethod, 1, NOTSILENT);
|
||||
quit = retval = LoadState(GCSettings.SaveMethod, NOTSILENT);
|
||||
break;
|
||||
|
||||
case 5: // Save State
|
||||
SaveBatteryOrState(GCSettings.SaveMethod, 1, NOTSILENT);
|
||||
break;
|
||||
|
||||
case 6: // Reset Zoom
|
||||
zoom_reset ();
|
||||
quit = retval = 1;
|
||||
SaveState(GCSettings.SaveMethod, NOTSILENT);
|
||||
break;
|
||||
|
||||
case -1: // Button B
|
||||
case 7: // Return to previous menu
|
||||
case 6: // Return to previous menu
|
||||
retval = 0;
|
||||
quit = 1;
|
||||
break;
|
||||
@ -652,7 +633,7 @@ MainMenu (int selectedMenu)
|
||||
int ret;
|
||||
|
||||
// disable game-specific menu items if a ROM isn't loaded
|
||||
if (!ROMLoaded)
|
||||
if (ROMSize == 0 )
|
||||
menuitems[3][0] = '\0';
|
||||
else
|
||||
sprintf (menuitems[3], "Game Menu");
|
||||
@ -719,24 +700,19 @@ MainMenu (int selectedMenu)
|
||||
|
||||
case -1: // Button B
|
||||
// Return to Game
|
||||
if(ROMLoaded)
|
||||
quit = 1;
|
||||
quit = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Wait for buttons to be released
|
||||
int count = 0; // how long we've been waiting for the user to release the button
|
||||
while(count < 50 && (
|
||||
PAD_ButtonsHeld(0)
|
||||
#ifdef HW_RVL
|
||||
|| WPAD_ButtonsHeld(0)
|
||||
#endif
|
||||
))
|
||||
{
|
||||
VIDEO_WaitVSync();
|
||||
count++;
|
||||
}
|
||||
/*** Remove any still held buttons ***/
|
||||
#ifdef HW_RVL
|
||||
while( PAD_ButtonsHeld(0) || WPAD_ButtonsHeld(0) )
|
||||
VIDEO_WaitVSync();
|
||||
#else
|
||||
while( PAD_ButtonsHeld(0) )
|
||||
VIDEO_WaitVSync();
|
||||
#endif
|
||||
|
||||
StartAudio();
|
||||
mftb(&end);
|
||||
|
@ -205,17 +205,6 @@ setfontcolour (u8 r, u8 g, u8 b)
|
||||
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
|
||||
*
|
||||
@ -228,10 +217,10 @@ Credits ()
|
||||
|
||||
setfontcolour (0x00, 0x00, 0x00);
|
||||
|
||||
setfontsize (26);
|
||||
DrawText (-1, 150, (char*)"Credits");
|
||||
setfontsize (28);
|
||||
DrawText (-1, 60, (char*)"Credits");
|
||||
|
||||
int ypos = 120;
|
||||
int ypos = 25;
|
||||
|
||||
if (screenheight == 480)
|
||||
ypos += 52;
|
||||
@ -246,8 +235,6 @@ Credits ()
|
||||
DrawText (375, ypos, (char*)"emukidid");
|
||||
DrawText (100, ypos += 18, (char*)"Original GameCube Port");
|
||||
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 (375, ypos, (char*)"Forgotten");
|
||||
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!");
|
||||
|
||||
setfontsize (12);
|
||||
DrawText (-1, ypos += 40, (char*)"This software is open source and may be copied,");
|
||||
DrawText (-1, ypos += 15, (char*)"distributed, or modified under the terms of");
|
||||
DrawText (-1, ypos += 15, (char*)"the GNU General Public License (GPL) Version 2.");
|
||||
DrawText (-1, ypos += 50, (char*)"This software is open source and may be copied, distributed, or modified");
|
||||
DrawText (-1, ypos += 15, (char*)"under the terms of the GNU General Public License (GPL) Version 2.");
|
||||
|
||||
DrawVersion();
|
||||
showscreen ();
|
||||
}
|
||||
|
||||
@ -368,12 +353,9 @@ WaitPrompt (char *msg)
|
||||
ypos += 32;
|
||||
|
||||
clearscreen ();
|
||||
setfontsize(16);
|
||||
DrawText (-1, ypos, msg);
|
||||
ypos += 30;
|
||||
DrawText (-1, ypos, (char*)"Press A to continue");
|
||||
|
||||
DrawVersion();
|
||||
showscreen ();
|
||||
WaitButtonA ();
|
||||
}
|
||||
@ -393,14 +375,11 @@ WaitPromptChoice (char *msg, char *bmsg, char *amsg)
|
||||
ypos += 17;
|
||||
|
||||
clearscreen ();
|
||||
setfontsize(20);
|
||||
DrawText (-1, ypos, msg);
|
||||
ypos += 60;
|
||||
char txt[80];
|
||||
sprintf (txt, "B = %s : A = %s", bmsg, amsg);
|
||||
DrawText (-1, ypos, txt);
|
||||
|
||||
DrawVersion();
|
||||
showscreen ();
|
||||
return WaitButtonAB ();
|
||||
}
|
||||
@ -419,10 +398,7 @@ ShowAction (char *msg)
|
||||
ypos += 32;
|
||||
|
||||
clearscreen ();
|
||||
setfontsize(20);
|
||||
DrawText (-1, ypos, msg);
|
||||
|
||||
DrawVersion();
|
||||
showscreen ();
|
||||
}
|
||||
|
||||
@ -437,12 +413,12 @@ DrawMenu (char items[][50], char *title, int maxitems, int selected, int fontsiz
|
||||
int n = 1;
|
||||
int line_height;
|
||||
|
||||
ypos = 105;
|
||||
ypos = 45;
|
||||
|
||||
if (screenheight == 480)
|
||||
ypos += 52;
|
||||
else
|
||||
ypos += 42;
|
||||
ypos += 32;
|
||||
|
||||
clearscreen ();
|
||||
|
||||
@ -450,10 +426,13 @@ DrawMenu (char items[][50], char *title, int maxitems, int selected, int fontsiz
|
||||
|
||||
if (title != NULL)
|
||||
{
|
||||
setfontsize (26);
|
||||
DrawText (-1, 150, title);
|
||||
setfontsize (28);
|
||||
DrawText (-1, 60, title);
|
||||
}
|
||||
|
||||
setfontsize (14);
|
||||
DrawText (380, screenheight - 30, (char *)VERSIONSTRFULL);
|
||||
|
||||
// Draw menu items
|
||||
|
||||
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)
|
||||
{
|
||||
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]);
|
||||
//setfontcolour (0x00, 0x00, 0x00);
|
||||
setfontcolour (0x00, 0x00, 0x00);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -483,8 +462,8 @@ DrawMenu (char items[][50], char *title, int maxitems, int selected, int fontsiz
|
||||
}
|
||||
}
|
||||
|
||||
DrawVersion();
|
||||
showscreen ();
|
||||
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
@ -540,7 +519,7 @@ RunMenu (char items[][50], int maxitems, char *title, int fontsize, int x)
|
||||
gc_ay = PAD_StickY (0);
|
||||
p = PAD_ButtonsDown (0);
|
||||
#ifdef HW_RVL
|
||||
wm_ay = WPAD_Stick (0,0,1);
|
||||
wm_ay = WPAD_StickY (0,0);
|
||||
wp = WPAD_ButtonsDown (0);
|
||||
#endif
|
||||
|
||||
@ -605,8 +584,8 @@ ShowFiles (FILEENTRIES filelist[], int maxfiles, int offset, int selection)
|
||||
|
||||
clearscreen ();
|
||||
|
||||
setfontsize (26);
|
||||
DrawText (-1, 150, (char*)"Choose Game");
|
||||
setfontsize (28);
|
||||
DrawText (-1, 60, (char*)"Choose Game");
|
||||
|
||||
setfontsize(18);
|
||||
|
||||
@ -617,8 +596,6 @@ ShowFiles (FILEENTRIES filelist[], int maxfiles, int offset, int selection)
|
||||
else
|
||||
ypos += 10;
|
||||
|
||||
ypos += 30;
|
||||
|
||||
j = 0;
|
||||
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 ***/
|
||||
for ( w = 0; w < 20; w++ )
|
||||
DrawLineFast( 77, 575, ( j * 20 ) + (ypos-16) + w, 0x00, 0x00, 0x00 );
|
||||
DrawText (100, (j * 20) + ypos, text);
|
||||
DrawLineFast( 30, 610, ( j * 20 ) + (ypos-16) + w, 0x80, 0x80, 0x80 );
|
||||
|
||||
setfontcolour (0x00, 0x00, 0xe0);
|
||||
DrawText (50, (j * 20) + ypos, text);
|
||||
setfontcolour (0x00, 0x00, 0x00);
|
||||
}
|
||||
else
|
||||
{
|
||||
/*** Normal entry ***/
|
||||
DrawText (100, (j * 20) + ypos, text);
|
||||
DrawText (50, (j * 20) + ypos, text);
|
||||
}
|
||||
j++;
|
||||
}
|
||||
|
||||
DrawVersion();
|
||||
showscreen ();
|
||||
}
|
||||
|
||||
@ -667,8 +645,8 @@ ShowCheats (char items[][50], char itemvalues[][50], int maxitems, int offset, i
|
||||
|
||||
clearscreen ();
|
||||
|
||||
setfontsize (26);
|
||||
DrawText (-1, 150, (char*)"Cheats");
|
||||
setfontsize (28);
|
||||
DrawText (-1, 60, (char*)"Cheats");
|
||||
|
||||
setfontsize(18);
|
||||
|
||||
@ -698,8 +676,6 @@ ShowCheats (char items[][50], char itemvalues[][50], int maxitems, int offset, i
|
||||
}
|
||||
j++;
|
||||
}
|
||||
|
||||
DrawVersion();
|
||||
showscreen ();
|
||||
}
|
||||
|
||||
@ -797,43 +773,30 @@ DrawLine (int x1, int y1, int x2, int y2, u8 r, u8 g, u8 b)
|
||||
void
|
||||
ShowProgress (char *msg, int done, int total)
|
||||
{
|
||||
if(total <= 0) // division by 0 is bad!
|
||||
return;
|
||||
else if(done > total) // this shouldn't happen
|
||||
done = total;
|
||||
int ypos = (screenheight - 30) >> 1;
|
||||
|
||||
int xpos, ypos;
|
||||
int i;
|
||||
if (screenheight == 480)
|
||||
ypos += 52;
|
||||
else
|
||||
ypos += 32;
|
||||
|
||||
if(done < 5000) // we just started!
|
||||
{
|
||||
ypos = (screenheight - 30) >> 1;
|
||||
int xpos;
|
||||
int i;
|
||||
|
||||
if (screenheight == 480)
|
||||
ypos += 52;
|
||||
else
|
||||
ypos += 32;
|
||||
clearscreen ();
|
||||
DrawText (-1, ypos, msg);
|
||||
|
||||
clearscreen ();
|
||||
setfontsize(20);
|
||||
DrawText (-1, ypos, msg);
|
||||
|
||||
/*** Draw a white outline box ***/
|
||||
for (i = 380; i < 401; i++)
|
||||
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 ***/
|
||||
xpos = (int) (((float) done / (float) total) * 438);
|
||||
xpos = (int) (((float) done / (float) total) * 438);
|
||||
|
||||
for (i = 381; i < 400; i++)
|
||||
DrawLine (101, i, 101 + xpos, i, 0x00, 0x00, 0x80);
|
||||
for (i = 381; i < 400; i++)
|
||||
DrawLine (101, i, 101 + xpos, i, 0x00, 0x00, 0x80);
|
||||
|
||||
if(done < 5000) // we just started!
|
||||
{
|
||||
DrawVersion();
|
||||
showscreen ();
|
||||
}
|
||||
showscreen ();
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
|
@ -19,7 +19,7 @@
|
||||
|
||||
#include "filesel.h"
|
||||
|
||||
#define PAGESIZE 13 // max item listing on a screen
|
||||
#define PAGESIZE 17 // max item listing on a screen
|
||||
|
||||
int FT_Init ();
|
||||
void setfontsize (int pixelsize);
|
||||
|
@ -21,10 +21,16 @@
|
||||
#include "fileop.h"
|
||||
#include "smbop.h"
|
||||
#include "filesel.h"
|
||||
#include "input.h"
|
||||
|
||||
extern unsigned char savebuffer[];
|
||||
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"
|
||||
|
||||
char prefscomment[2][32];
|
||||
@ -40,7 +46,7 @@ mxml_node_t *section;
|
||||
mxml_node_t *item;
|
||||
mxml_node_t *elem;
|
||||
|
||||
char temp[20];
|
||||
char temp[200];
|
||||
|
||||
const char * toStr(int i)
|
||||
{
|
||||
@ -70,7 +76,7 @@ void createXMLController(unsigned int controller[], const char * name, const cha
|
||||
mxmlElementSetAttr(item, "description", description);
|
||||
|
||||
// create buttons
|
||||
for(int i=0; i < MAXJP; i++)
|
||||
for(int i=0; i < 12; i++)
|
||||
{
|
||||
elem = mxmlNewElement(item, "button");
|
||||
mxmlElementSetAttr(elem, "number", toStr(i));
|
||||
@ -110,6 +116,7 @@ int
|
||||
preparePrefsData (int method)
|
||||
{
|
||||
int offset = 0;
|
||||
memset (savebuffer, 0, SAVEBUFFERSIZE);
|
||||
|
||||
// add save icon and comments for Memory Card saves
|
||||
if(method == METHOD_MC_SLOTA || method == METHOD_MC_SLOTB)
|
||||
@ -141,7 +148,7 @@ preparePrefsData (int method)
|
||||
createXMLSetting("LoadFolder", "Load Folder", GCSettings.LoadFolder);
|
||||
createXMLSetting("SaveFolder", "Save Folder", GCSettings.SaveFolder);
|
||||
//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");
|
||||
|
||||
@ -150,10 +157,7 @@ preparePrefsData (int method)
|
||||
createXMLSetting("smbuser", "Share Username", GCSettings.smbuser);
|
||||
createXMLSetting("smbpwd", "Share Password", GCSettings.smbpwd);
|
||||
|
||||
createXMLSection("Emulation", "Emulation Settings");
|
||||
|
||||
createXMLSetting("NGCZoom", "Enable Zoom", toStr(GCSettings.NGCZoom));
|
||||
createXMLSetting("render", "Video Rendering", toStr(GCSettings.render));
|
||||
//createXMLSection("Emulation", "Emulation Settings");
|
||||
|
||||
createXMLSection("Controller", "Controller Settings");
|
||||
|
||||
@ -208,7 +212,7 @@ void loadXMLController(unsigned int controller[], const char * name)
|
||||
if(item)
|
||||
{
|
||||
// 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);
|
||||
if(elem)
|
||||
@ -238,6 +242,7 @@ decodePrefsData (int method)
|
||||
xml = mxmlLoadString(NULL, (char *)savebuffer+offset, MXML_TEXT_CALLBACK);
|
||||
|
||||
// check settings version
|
||||
// we don't do anything with the version #, but we'll store it anyway
|
||||
char * version;
|
||||
item = mxmlFindElement(xml, xml, "file", "version", NULL, MXML_DESCEND);
|
||||
if(item) // a version entry exists
|
||||
@ -245,17 +250,6 @@ decodePrefsData (int method)
|
||||
else // version # not found, must be invalid
|
||||
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
|
||||
|
||||
loadXMLSetting(&GCSettings.AutoLoad, "AutoLoad");
|
||||
@ -276,9 +270,6 @@ decodePrefsData (int method)
|
||||
|
||||
// Emulation Settings
|
||||
|
||||
loadXMLSetting(&GCSettings.NGCZoom, "NGCZoom");
|
||||
loadXMLSetting(&GCSettings.render, "render");
|
||||
|
||||
// Controller Settings
|
||||
|
||||
loadXMLController(gcpadmap, "gcpadmap");
|
||||
@ -297,17 +288,13 @@ decodePrefsData (int method)
|
||||
bool
|
||||
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!
|
||||
// so instead we'll save using whatever other method is available (eg: SD)
|
||||
if(method == METHOD_AUTO || method == METHOD_SMB)
|
||||
if(method == METHOD_AUTO)
|
||||
method = autoSaveMethod();
|
||||
|
||||
char filepath[1024];
|
||||
int datasize;
|
||||
int offset = 0;
|
||||
|
||||
AllocSaveBuffer ();
|
||||
|
||||
datasize = preparePrefsData (method);
|
||||
|
||||
if (!silent)
|
||||
@ -335,8 +322,6 @@ SavePrefs (int method, bool silent)
|
||||
offset = SaveBufferToMC (savebuffer, CARD_SLOTB, (char *)PREFS_FILE_NAME, datasize, silent);
|
||||
}
|
||||
|
||||
FreeSaveBuffer ();
|
||||
|
||||
if (offset > 0)
|
||||
{
|
||||
if (!silent)
|
||||
@ -356,8 +341,6 @@ LoadPrefsFromMethod (int method)
|
||||
char filepath[1024];
|
||||
int offset = 0;
|
||||
|
||||
AllocSaveBuffer ();
|
||||
|
||||
if(method == METHOD_SD || method == METHOD_USB)
|
||||
{
|
||||
if(ChangeFATInterface(method, NOTSILENT))
|
||||
@ -383,8 +366,6 @@ LoadPrefsFromMethod (int method)
|
||||
if (offset > 0)
|
||||
retval = decodePrefsData (method);
|
||||
|
||||
FreeSaveBuffer ();
|
||||
|
||||
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;
|
||||
#define SMBTIMEOUT ( 3600 ) // Some implementations timeout in 10 minutes
|
||||
|
||||
// SMB connection/file handles - the only ones we should ever use!
|
||||
SMBCONN smbconn;
|
||||
SMBFILE smbfile;
|
||||
|
||||
#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
|
||||
* Initializes the Wii/GameCube network interface
|
||||
@ -88,7 +93,7 @@ ConnectShare (bool silent)
|
||||
strlen(GCSettings.smbip) == 0)
|
||||
{
|
||||
if(!silent)
|
||||
WaitPrompt((char*) "Invalid network settings. Check VBAGX.xml.");
|
||||
WaitPrompt((char*) "Invalid network settings. Check SNES9xGX.xml.");
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -213,76 +218,36 @@ ParseSMBdirectory ()
|
||||
return filecount;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Open SMB file
|
||||
***************************************************************************/
|
||||
|
||||
SMBFILE OpenSMBFile(char * filepath)
|
||||
{
|
||||
return SMB_OpenFile (SMBPath(filepath), SMB_OPEN_READING, SMB_OF_OPEN, smbconn);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Load SMB file
|
||||
* rom - pointer to memory where ROM will be stored
|
||||
* length - # bytes to read (0 for all)
|
||||
****************************************************************************/
|
||||
int
|
||||
LoadSMBFile (char * rom, int length)
|
||||
LoadSMBFile (char *filename, int length)
|
||||
{
|
||||
char filepath[MAXPATHLEN];
|
||||
|
||||
/* 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!");
|
||||
return -1;
|
||||
}
|
||||
return LoadBufferFromSMB(rom, filepath, length, 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;
|
||||
}
|
||||
return 0;
|
||||
//return LoadBufferFromSMB((char *)Memory.ROM, SMBPath(filepath), NOTSILENT);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Write savebuffer to SMB file
|
||||
****************************************************************************/
|
||||
// no buffer specified, use savebuffer
|
||||
int
|
||||
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))
|
||||
return 0;
|
||||
|
||||
SMBFILE smbfile;
|
||||
int dsize = datasize;
|
||||
int wrote = 0;
|
||||
int boffset = 0;
|
||||
@ -297,10 +262,10 @@ SaveBufferToSMB (char * sbuffer, char *filepath, int datasize, bool silent)
|
||||
{
|
||||
if (dsize > 1024)
|
||||
wrote =
|
||||
SMB_WriteFile ((char *) sbuffer + boffset, 1024, boffset, smbfile);
|
||||
SMB_WriteFile ((char *) savebuffer + boffset, 1024, boffset, smbfile);
|
||||
else
|
||||
wrote =
|
||||
SMB_WriteFile ((char *) sbuffer + boffset, dsize, boffset, smbfile);
|
||||
SMB_WriteFile ((char *) savebuffer + boffset, dsize, boffset, smbfile);
|
||||
|
||||
boffset += wrote;
|
||||
dsize -= wrote;
|
||||
@ -314,6 +279,7 @@ SaveBufferToSMB (char * sbuffer, char *filepath, int datasize, bool silent)
|
||||
WaitPrompt (msg);
|
||||
}
|
||||
|
||||
ClearSaveBuffer ();
|
||||
return boffset;
|
||||
}
|
||||
|
||||
@ -325,19 +291,22 @@ SaveBufferToSMB (char * sbuffer, char *filepath, int datasize, bool silent)
|
||||
int
|
||||
LoadBufferFromSMB (char *filepath, bool silent)
|
||||
{
|
||||
return LoadBufferFromSMB((char *)savebuffer, filepath, 0, silent);
|
||||
ClearSaveBuffer ();
|
||||
return LoadBufferFromSMB((char *)savebuffer, filepath, silent);
|
||||
}
|
||||
|
||||
int
|
||||
LoadBufferFromSMB (char * sbuffer, char *filepath, int length, bool silent)
|
||||
LoadBufferFromSMB (char * sbuffer, char *filepath, bool silent)
|
||||
{
|
||||
if(!ConnectShare (NOTSILENT))
|
||||
return 0;
|
||||
|
||||
SMBFILE smbfile;
|
||||
int ret;
|
||||
int boffset = 0;
|
||||
|
||||
smbfile = OpenSMBFile(filepath);
|
||||
smbfile =
|
||||
SMB_OpenFile (SMBPath(filepath), SMB_OPEN_READING, SMB_OF_OPEN, smbconn);
|
||||
|
||||
if (!smbfile)
|
||||
{
|
||||
@ -350,27 +319,17 @@ LoadBufferFromSMB (char * sbuffer, char *filepath, int length, bool silent)
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(length > 0 && length <= 2048) // do a partial read (eg: to check file header)
|
||||
{
|
||||
boffset = SMB_ReadFile (sbuffer, length, 0, smbfile);
|
||||
}
|
||||
else // load whole file
|
||||
{
|
||||
ret = SMB_ReadFile (sbuffer, 2048, boffset, smbfile);
|
||||
ret = SMB_ReadFile (sbuffer, 1024, boffset, smbfile);
|
||||
|
||||
if (IsZipFile (sbuffer))
|
||||
{
|
||||
boffset = UnZipBuffer ((unsigned char *)sbuffer, METHOD_SMB); // unzip from SMB
|
||||
}
|
||||
else
|
||||
{
|
||||
// Just load the file up
|
||||
while ((ret = SMB_ReadFile (sbuffer + boffset, 2048, boffset, smbfile)) > 0)
|
||||
{
|
||||
boffset += ret;
|
||||
ShowProgress ((char *)"Loading...", boffset, length);
|
||||
}
|
||||
}
|
||||
if (IsZipFile (sbuffer))
|
||||
{
|
||||
boffset = UnZipFile ((unsigned char *)sbuffer, smbfile); // unzip from SMB
|
||||
}
|
||||
else
|
||||
{
|
||||
// Just load the file up
|
||||
while ((ret = SMB_ReadFile (sbuffer + boffset, 1024, boffset, smbfile)) > 0)
|
||||
boffset += ret;
|
||||
}
|
||||
SMB_CloseFile (smbfile);
|
||||
|
||||
|
@ -12,21 +12,14 @@
|
||||
|
||||
#define _NGCSMB_
|
||||
|
||||
#include <smb.h>
|
||||
|
||||
bool InitializeNetwork(bool silent);
|
||||
bool ConnectShare (bool silent);
|
||||
char * SMBPath(char * path);
|
||||
int UpdateSMBdirname();
|
||||
int ParseSMBdirectory ();
|
||||
SMBFILE OpenSMBFile(char * filepath);
|
||||
int LoadSMBFile (char * fbuffer, int length);
|
||||
int LoadSMBSzFile(char * filepath, unsigned char * rbuffer);
|
||||
int LoadSMBFile (char *filename, int length);
|
||||
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 * sbuffer, char *filepath, int datasize, bool silent);
|
||||
|
||||
extern SMBFILE smbfile;
|
||||
|
||||
#endif
|
||||
|
@ -38,7 +38,7 @@ extern "C" {
|
||||
#include "video.h"
|
||||
#include "vbaconfig.h"
|
||||
|
||||
extern bool ROMLoaded;
|
||||
extern int ROMSize;
|
||||
extern int emulating;
|
||||
|
||||
|
||||
@ -74,10 +74,10 @@ int main()
|
||||
}
|
||||
|
||||
// Initialize libFAT for SD and USB
|
||||
fatInit (8, false);
|
||||
fatInitDefault();
|
||||
|
||||
// Initialize DVD subsystem (GameCube only)
|
||||
#ifdef HW_DOL
|
||||
#ifndef HW_RVL
|
||||
DVD_Init ();
|
||||
#endif
|
||||
|
||||
@ -98,7 +98,7 @@ int main()
|
||||
selectedMenu = 2; // change to preferences menu
|
||||
}
|
||||
|
||||
while (!ROMLoaded)
|
||||
while (ROMSize == 0)
|
||||
{
|
||||
MainMenu (selectedMenu);
|
||||
}
|
||||
|
@ -7,13 +7,14 @@
|
||||
*
|
||||
* This file controls overall program flow. Most things start and end here!
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef _VBA_H_
|
||||
#define _VBA_H_
|
||||
|
||||
#include <gccore.h>
|
||||
#define VERSIONNUM "1.0.3"
|
||||
#define VERSIONSTR "VBA GX 1.0.3"
|
||||
#define VERSIONSTRFULL "Visual Boy Advance GX 1.0.3"
|
||||
#define VERSIONNUM "1.0.0"
|
||||
#define VERSIONSTR "VBA GX 1.0.0"
|
||||
#define VERSIONSTRFULL "Visual Boy Advance GX 1.0.0"
|
||||
|
||||
#define NOTSILENT 0
|
||||
#define SILENT 1
|
||||
@ -45,9 +46,7 @@ struct SGCSettings{
|
||||
char smbgcid[20];
|
||||
char smbsvid[20];
|
||||
char smbshare[20];
|
||||
int NGCZoom; // 0 - off, 1 - on
|
||||
int VerifySaves;
|
||||
int render; // 0 - filtered, 1 - unfiltered
|
||||
};
|
||||
|
||||
extern struct SGCSettings GCSettings;
|
||||
|
@ -46,6 +46,4 @@ DefaultSettings ()
|
||||
GCSettings.smbgcid[0] = 0;
|
||||
|
||||
GCSettings.VerifySaves = 0;
|
||||
GCSettings.NGCZoom = 0; // zooming default off
|
||||
GCSettings.render = 0; // Unfiltered
|
||||
}
|
||||
|
@ -13,40 +13,43 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "agb/GBA.h"
|
||||
#include "agb/agbprint.h"
|
||||
#include "GBA.h"
|
||||
#include "agbprint.h"
|
||||
#include "Flash.h"
|
||||
#include "Port.h"
|
||||
#include "RTC.h"
|
||||
#include "Sound.h"
|
||||
#include "Text.h"
|
||||
#include "unzip.h"
|
||||
#include "Util.h"
|
||||
#include "dmg/GB.h"
|
||||
#include "dmg/gbGlobals.h"
|
||||
#include "images/saveicon.h"
|
||||
//#include "dmg/gbSound.h"
|
||||
#include "gb/GB.h"
|
||||
#include "gb/gbGlobals.h"
|
||||
|
||||
#include "vba.h"
|
||||
#include "fileop.h"
|
||||
#include "dvd.h"
|
||||
#include "smbop.h"
|
||||
#include "memcardop.h"
|
||||
#include "audio.h"
|
||||
#include "vmmem.h"
|
||||
#include "pal60.h"
|
||||
#include "input.h"
|
||||
#include "video.h"
|
||||
#include "menudraw.h"
|
||||
#include "gcunzip.h"
|
||||
|
||||
extern "C"
|
||||
{
|
||||
#include "tbtime.h"
|
||||
#include "sdfileio.h"
|
||||
}
|
||||
|
||||
static tb_t start, now;
|
||||
|
||||
u32 loadtimeradjust;
|
||||
|
||||
int throttle = 100;
|
||||
u32 throttleLastTime = 0;
|
||||
|
||||
static u32 autoFrameSkipLastTime = 0;
|
||||
static int frameskipadjust = 0;
|
||||
|
||||
int vAspect = 0;
|
||||
int hAspect = 0;
|
||||
|
||||
@ -79,7 +82,7 @@ int systemColorDepth = 0;
|
||||
u16 systemGbPalette[24];
|
||||
u16 systemColorMap16[0x10000];
|
||||
//u32 systemColorMap32[0x10000];
|
||||
u32 *systemColorMap32 = NULL;
|
||||
u32 *systemColorMap32 = (u32 *)&systemColorMap16;
|
||||
|
||||
struct EmulatedSystem emulator =
|
||||
{
|
||||
@ -119,7 +122,7 @@ bool systemPauseOnFrame()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
/*
|
||||
|
||||
void GC_Sleep(u32 dwMiliseconds)
|
||||
{
|
||||
int nVBlanks = (dwMiliseconds / 16);
|
||||
@ -128,39 +131,21 @@ void GC_Sleep(u32 dwMiliseconds)
|
||||
VIDEO_WaitVSync();
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
static u32 autoFrameSkipLastTime = 0;
|
||||
|
||||
void system10Frames(int rate)
|
||||
{
|
||||
if (cartridgeType == 1)
|
||||
if ( cartridgeType == 1 )
|
||||
return;
|
||||
|
||||
u32 time = systemGetClock();
|
||||
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;
|
||||
|
||||
if(diff)
|
||||
speed = (1000000/rate)/diff;
|
||||
/* char temp[512];
|
||||
sprintf(temp,"Speed: %i",speed);
|
||||
MENU_DrawString( -1, 450,temp , 1 ); */
|
||||
|
||||
if(speed >= 98)
|
||||
{
|
||||
@ -189,7 +174,6 @@ void system10Frames(int rate)
|
||||
}
|
||||
|
||||
autoFrameSkipLastTime = time;
|
||||
*/
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
@ -197,295 +181,102 @@ void system10Frames(int rate)
|
||||
****************************************************************************/
|
||||
|
||||
void systemGbPrint(u8 *data,int pages,int feed,int palette, int contrast) {}
|
||||
void debuggerOutput(const char *s, u32 addr) {}
|
||||
void (*dbgOutput)(const char *s, u32 addr) = debuggerOutput;
|
||||
void debuggerOutput(char *, u32) {}
|
||||
void (*dbgOutput)(char *, u32) = debuggerOutput;
|
||||
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
|
||||
* Sets the # of bytes written into a file
|
||||
* Used by GBA.cpp and GB.cpp
|
||||
* Saves
|
||||
****************************************************************************/
|
||||
|
||||
void SetFileBytesWritten(int bytes)
|
||||
{
|
||||
//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)
|
||||
bool LoadBattery(int method, bool silent)
|
||||
{
|
||||
char filepath[1024];
|
||||
bool result = false;
|
||||
int offset = 0;
|
||||
char ext[4];
|
||||
|
||||
if(action == 0)
|
||||
sprintf(ext, "sav");
|
||||
else
|
||||
sprintf(ext, "sgm");
|
||||
|
||||
ShowAction ((char*) "Loading...");
|
||||
|
||||
if(method == METHOD_AUTO)
|
||||
method = autoSaveMethod(); // we use 'Save' because we need R/W
|
||||
|
||||
AllocSaveBuffer();
|
||||
|
||||
// load the file into savebuffer
|
||||
|
||||
if(method == METHOD_SD || method == METHOD_USB)
|
||||
{
|
||||
if(ChangeFATInterface(method, NOTSILENT))
|
||||
{
|
||||
sprintf (filepath, "%s/%s/%s.%s", ROOTFATDIR, GCSettings.SaveFolder, ROMFilename, ext);
|
||||
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;
|
||||
ChangeFATInterface(method, NOTSILENT);
|
||||
sprintf (filepath, "%s/%s/%s.sav", ROOTFATDIR, GCSettings.SaveFolder, ROMFilename);
|
||||
result = emulator.emuReadBattery(filepath);
|
||||
}
|
||||
|
||||
// load savebuffer into VBA memory
|
||||
if (offset > 0)
|
||||
{
|
||||
if(action == 0)
|
||||
{
|
||||
if(cartridgeType == 1)
|
||||
result = MemgbReadBatteryFile((char *)savebuffer, offset);
|
||||
else
|
||||
result = MemCPUReadBatteryFile((char *)savebuffer, offset);
|
||||
}
|
||||
else
|
||||
{
|
||||
result = emulator.emuReadMemState((char *)savebuffer, offset);
|
||||
}
|
||||
}
|
||||
if(!result && !silent)
|
||||
WaitPrompt ((char*) "Save file not found");
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
* SaveBatteryOrState
|
||||
* Save Battery/State file into memory
|
||||
* action = 0 - Save battery
|
||||
* action = 1 - Save state
|
||||
****************************************************************************/
|
||||
|
||||
bool SaveBatteryOrState(int method, int action, bool silent)
|
||||
bool SaveBattery(int method, bool silent)
|
||||
{
|
||||
char filepath[1024];
|
||||
char savecomment[2][32];
|
||||
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");
|
||||
sprintf(savetype, "SRAM");
|
||||
ChangeFATInterface(method, NOTSILENT);
|
||||
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");
|
||||
sprintf(savetype, "Freeze");
|
||||
ChangeFATInterface(method, NOTSILENT);
|
||||
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...");
|
||||
|
||||
if(method == METHOD_AUTO)
|
||||
method = autoSaveMethod(); // we use 'Save' because we need R/W
|
||||
|
||||
AllocSaveBuffer();
|
||||
|
||||
// add save icon and comments for Memory Card saves
|
||||
if(method == METHOD_MC_SLOTA || method == METHOD_MC_SLOTB)
|
||||
if(method == METHOD_SD || method == METHOD_USB)
|
||||
{
|
||||
offset = sizeof (saveicon);
|
||||
|
||||
// Copy in save icon
|
||||
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;
|
||||
ChangeFATInterface(method, NOTSILENT);
|
||||
sprintf (filepath, "%s/%s/%s.sgm", ROOTFATDIR, GCSettings.SaveFolder, ROMFilename);
|
||||
result = emulator.emuWriteState(filepath);
|
||||
}
|
||||
|
||||
// put VBA memory into savebuffer, sets datasize to size of memory written
|
||||
if(action == 0)
|
||||
{
|
||||
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();
|
||||
if(!result && !silent)
|
||||
WaitPrompt ((char*) "Save failed");
|
||||
|
||||
return result;
|
||||
}
|
||||
@ -532,73 +323,21 @@ u32 systemReadJoypad(int which)
|
||||
****************************************************************************/
|
||||
void systemDrawScreen()
|
||||
{
|
||||
// GB / GBC Have oodles of time - so sync on VSync
|
||||
GX_Render( srcWidth, srcHeight, pix, srcPitch );
|
||||
|
||||
#ifdef HW_RVL
|
||||
VIDEO_WaitVSync ();
|
||||
#else
|
||||
if ( cartridgeType == 1 )
|
||||
{
|
||||
VIDEO_WaitVSync();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
extern bool gbUpdateSizes();
|
||||
bool LoadGBROM(int method)
|
||||
int loadVBAROM(char filename[])
|
||||
{
|
||||
// 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;
|
||||
srcWidth = 0;
|
||||
srcHeight = 0;
|
||||
@ -606,15 +345,17 @@ bool LoadVBAROM(int method)
|
||||
destHeight = 0;
|
||||
srcPitch = 0;
|
||||
|
||||
IMAGE_TYPE type = utilFindType(filename);
|
||||
|
||||
switch( type )
|
||||
{
|
||||
case 2:
|
||||
case IMAGE_GBA:
|
||||
//WaitPrompt("GameBoy Advance Image");
|
||||
cartridgeType = 2;
|
||||
emulator = GBASystem;
|
||||
srcWidth = 240;
|
||||
srcHeight = 160;
|
||||
loaded = VMCPULoadROM(method);
|
||||
VMCPULoadROM(filename);
|
||||
// Actual Visual Aspect is 1.57
|
||||
hAspect = 70;
|
||||
vAspect = 46;
|
||||
@ -624,13 +365,13 @@ bool LoadVBAROM(int method)
|
||||
cpuSaveType = 0;
|
||||
break;
|
||||
|
||||
case 1:
|
||||
case IMAGE_GB:
|
||||
//WaitPrompt("GameBoy Image");
|
||||
cartridgeType = 1;
|
||||
emulator = GBSystem;
|
||||
srcWidth = 160;
|
||||
srcHeight = 144;
|
||||
loaded = LoadGBROM(method);
|
||||
gbLoadRom(filename);
|
||||
// Actual physical aspect is 1.0
|
||||
hAspect = 60;
|
||||
vAspect = 46;
|
||||
@ -638,52 +379,46 @@ bool LoadVBAROM(int method)
|
||||
soundQuality = 1;
|
||||
soundBufferLen = 1470 * 2;
|
||||
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!");
|
||||
return false;
|
||||
gbSoundReset();
|
||||
gbSoundSetQuality(soundQuality);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Set defaults
|
||||
flashSetSize(0x20000); // 128K saves
|
||||
rtcEnable(true);
|
||||
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;
|
||||
soundSetQuality(soundQuality);
|
||||
CPUInit("/VBA/BIOS/BIOS.GBA", 1);
|
||||
CPUReset();
|
||||
}
|
||||
|
||||
soundVolume = 0;
|
||||
systemSoundOn = true;
|
||||
|
||||
soundInit();
|
||||
|
||||
emulating = 1;
|
||||
|
||||
// Start system clock
|
||||
mftb(&start);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
|
@ -12,7 +12,9 @@
|
||||
|
||||
extern struct EmulatedSystem emulator;
|
||||
extern u32 loadtimeradjust;
|
||||
bool LoadVBAROM(int method);
|
||||
int loadVBAROM(char filename[]);
|
||||
void InitialisePalette();
|
||||
bool LoadBatteryOrState(int method, int action, bool silent);
|
||||
bool SaveBatteryOrState(int method, int action, bool silent);
|
||||
bool LoadBattery(int method, 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.
|
||||
***************************************************************************/
|
||||
#include <gccore.h>
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <malloc.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 ***/
|
||||
/*** 2D Video Globals ***/
|
||||
GXRModeObj *vmode = NULL; // Graphics Mode Object
|
||||
unsigned int *xfb[2]; // Framebuffers
|
||||
int whichfb = 0; // Frame buffer toggle
|
||||
GXRModeObj *vmode; /*** Graphics Mode Object ***/
|
||||
u32 *xfb[2] = { NULL, NULL }; /*** Framebuffers ***/
|
||||
int whichfb = 0; /*** Frame buffer toggle ***/
|
||||
|
||||
int screenheight;
|
||||
|
||||
/*** 3D GX ***/
|
||||
#define DEFAULT_FIFO_SIZE ( 256 * 1024 )
|
||||
static u8 gp_fifo[DEFAULT_FIFO_SIZE] ATTRIBUTE_ALIGN(32);
|
||||
unsigned int copynow = GX_FALSE;
|
||||
|
||||
/*** Texture memory ***/
|
||||
static u8 *texturemem = NULL;
|
||||
static u8 *texturemem;
|
||||
static int texturesize;
|
||||
|
||||
GXTexObj texobj;
|
||||
static Mtx view;
|
||||
static int vwidth, vheight, oldvwidth, oldvheight;
|
||||
static int video_vaspect, video_haspect;
|
||||
int updateScaling;
|
||||
float zoom_level = 1;
|
||||
unsigned int copynow = GX_FALSE;
|
||||
|
||||
#define HASPECT 80
|
||||
#define VASPECT 45
|
||||
@ -81,92 +70,84 @@ static camera cam = { {0.0F, 0.0F, 0.0F},
|
||||
{0.0F, 0.0F, -0.5F}
|
||||
};
|
||||
|
||||
#ifdef VIDEO_THREADING
|
||||
/****************************************************************************
|
||||
* VideoThreading
|
||||
***************************************************************************/
|
||||
#define TSTACK 16384
|
||||
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)
|
||||
* StartGX
|
||||
****************************************************************************/
|
||||
void GX_Start()
|
||||
{
|
||||
while (1)
|
||||
{
|
||||
VIDEO_WaitVSync (); /**< Wait for video vertical blank */
|
||||
LWP_SuspendThread (vbthread);
|
||||
}
|
||||
Mtx p;
|
||||
|
||||
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.
|
||||
* This function sets up a new local queue and attaches the thread to it.
|
||||
* called by postRetraceCallback in InitGCVideo - scans gcpad and wpad
|
||||
***************************************************************************/
|
||||
void
|
||||
InitVideoThread ()
|
||||
UpdatePadsCB ()
|
||||
{
|
||||
/*** Initialise a new queue ***/
|
||||
LWP_InitQueue (&videoblankqueue);
|
||||
|
||||
/*** Create the thread on this queue ***/
|
||||
LWP_CreateThread (&vbthread, vbgetback, NULL, vbstack, TSTACK, 80);
|
||||
}
|
||||
|
||||
#ifdef HW_RVL
|
||||
WPAD_ScanPads();
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* 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++;
|
||||
PAD_ScanPads();
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Drawing screen
|
||||
***************************************************************************/
|
||||
void
|
||||
clearscreen ()
|
||||
* Initialise Video
|
||||
*
|
||||
* Before doing anything in libogc, it's recommended to configure a video
|
||||
* output.
|
||||
****************************************************************************/
|
||||
void InitialiseVideo ()
|
||||
{
|
||||
int colour = COLOR_BLACK;
|
||||
/*** Start VIDEO Subsystem ***/
|
||||
VIDEO_Init();
|
||||
|
||||
whichfb ^= 1;
|
||||
VIDEO_ClearFrameBuffer (vmode, xfb[whichfb], colour);
|
||||
memcpy (xfb[whichfb], &bg, 1280 * 480);
|
||||
}
|
||||
vmode = VIDEO_GetPreferredMode(NULL);
|
||||
VIDEO_Configure(vmode);
|
||||
|
||||
void
|
||||
showscreen ()
|
||||
{
|
||||
VIDEO_SetNextFramebuffer (xfb[whichfb]);
|
||||
VIDEO_Flush ();
|
||||
VIDEO_WaitVSync ();
|
||||
screenheight = vmode->xfbHeight;
|
||||
|
||||
xfb[0] = (u32 *) MEM_K0_TO_K1 (SYS_AllocateFramebuffer (vmode));
|
||||
xfb[1] = (u32 *) MEM_K0_TO_K1 (SYS_AllocateFramebuffer (vmode));
|
||||
|
||||
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)
|
||||
{
|
||||
GX_ClearVtxDesc ();
|
||||
GX_SetVtxDesc (GX_VA_POS, GX_INDEX8);
|
||||
GX_SetVtxDesc (GX_VA_CLR0, GX_INDEX8);
|
||||
GX_SetVtxDesc (GX_VA_TEX0, GX_DIRECT);
|
||||
GX_ClearVtxDesc();
|
||||
GX_SetVtxDesc(GX_VA_POS, GX_INDEX8);
|
||||
GX_SetVtxDesc(GX_VA_CLR0, GX_INDEX8);
|
||||
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_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_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_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_SetNumChans (0);
|
||||
|
||||
GX_SetTexCoordGen (GX_TEXCOORD0, GX_TG_MTX2x4, GX_TG_TEX0, GX_IDENTITY);
|
||||
GX_SetNumTexGens(1);
|
||||
GX_SetTexCoordGen(GX_TEXCOORD0, GX_TG_MTX2x4, GX_TG_TEX0, GX_IDENTITY);
|
||||
|
||||
GX_InvalidateTexAll();
|
||||
memset (&view, 0, sizeof (Mtx));
|
||||
guLookAt(view, &cam.pos, &cam.up, &cam.view);
|
||||
GX_LoadPosMtxImm (view, GX_PNMTX0);
|
||||
|
||||
GX_InitTexObj(&texobj, texturemem, vwidth, vheight, GX_TF_RGB565,
|
||||
GX_CLAMP, GX_CLAMP, GX_FALSE);
|
||||
}
|
||||
|
||||
static void draw_vert(u8 pos, u8 c, f32 s, f32 t)
|
||||
@ -221,234 +200,23 @@ static void draw_square(Mtx v)
|
||||
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)
|
||||
{
|
||||
ResetVideo_Emu (); // reset video to emulator rendering settings
|
||||
|
||||
if (texturemem)
|
||||
free(texturemem);
|
||||
/*** Set new aspect (now with crap AR hack!) ***/
|
||||
square[0] = square[9] = (-haspect - 7);
|
||||
square[3] = square[6] = (haspect + 7);
|
||||
square[1] = square[4] = (vaspect + 7);
|
||||
square[7] = square[10] = (-vaspect - 7);
|
||||
|
||||
/*** Allocate 32byte aligned texture memory ***/
|
||||
texturesize = (width * height) * 2;
|
||||
|
||||
texturemem = (u8 *) memalign(32, texturesize);
|
||||
|
||||
memset(texturemem, 0, texturesize);
|
||||
|
||||
/*** Setup for first call to scaler ***/
|
||||
vwidth = width;
|
||||
vheight = height;
|
||||
oldvwidth = oldvheight = -1;
|
||||
|
||||
video_vaspect = vaspect;
|
||||
video_haspect = haspect;
|
||||
|
||||
UpdateScaling();
|
||||
vwidth = vheight = oldvwidth = oldvheight = -1;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* GX_Render
|
||||
*
|
||||
@ -469,30 +237,24 @@ void GX_Render(int width, int height, u8 * buffer, int pitch)
|
||||
vwidth = width;
|
||||
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;
|
||||
|
||||
if(updateScaling)
|
||||
{
|
||||
UpdateScaling();
|
||||
}
|
||||
|
||||
if ((oldvheight != vheight) || (oldvwidth != vwidth))
|
||||
{
|
||||
/** Update scaling **/
|
||||
oldvwidth = vwidth;
|
||||
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 (w = 0; w < (vwidth >> 2); w++)
|
||||
@ -522,43 +284,49 @@ void GX_Render(int width, int height, u8 * buffer, int pitch)
|
||||
}
|
||||
|
||||
DCFlushRange(texturemem, texturesize);
|
||||
GX_InvalidateTexAll ();
|
||||
|
||||
GX_SetNumChans(1);
|
||||
GX_LoadTexObj(&texobj, GX_TEXMAP0);
|
||||
|
||||
draw_square(view);
|
||||
|
||||
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_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
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Zoom Functions
|
||||
***************************************************************************/
|
||||
void
|
||||
zoom (float speed)
|
||||
showscreen ()
|
||||
{
|
||||
if (zoom_level > 1)
|
||||
zoom_level += (speed / -100.0);
|
||||
else
|
||||
zoom_level += (speed / -200.0);
|
||||
|
||||
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
|
||||
copynow = GX_FALSE;
|
||||
VIDEO_SetNextFramebuffer (xfb[whichfb]);
|
||||
VIDEO_Flush ();
|
||||
VIDEO_WaitVSync ();
|
||||
}
|
||||
|
@ -15,13 +15,9 @@
|
||||
#define __GXHDR__
|
||||
|
||||
void InitialiseVideo ();
|
||||
void GX_Start();
|
||||
void GX_Render_Init(int width, int height, int haspect, int vaspect);
|
||||
void GX_Render(int width, int height, u8 * buffer, int pitch);
|
||||
void clearscreen ();
|
||||
void clearscreen (int colour = COLOR_BLACK);
|
||||
void showscreen ();
|
||||
void zoom (float speed);
|
||||
void zoom_reset ();
|
||||
void ResetVideo_Menu ();
|
||||
|
||||
#endif
|
||||
|
@ -9,6 +9,7 @@
|
||||
***************************************************************************/
|
||||
|
||||
#ifdef HW_RVL
|
||||
#include "sdfileio.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
@ -16,18 +17,12 @@
|
||||
#include <fat.h>
|
||||
#include <sys/dir.h>
|
||||
|
||||
#include "agb/GBA.h"
|
||||
#include "GBA.h"
|
||||
#include "Globals.h"
|
||||
#include "Util.h"
|
||||
#include "Port.h"
|
||||
|
||||
#include "vba.h"
|
||||
#include "smbop.h"
|
||||
#include "fileop.h"
|
||||
#include "dvd.h"
|
||||
#include "menudraw.h"
|
||||
#include "filesel.h"
|
||||
#include "gcunzip.h"
|
||||
|
||||
extern "C" {
|
||||
#include "tbtime.h"
|
||||
@ -40,7 +35,9 @@ extern "C" {
|
||||
unsigned int MEM2Storage = 0x91000000;
|
||||
|
||||
static char *gbabase = NULL;
|
||||
static FILE *romfile = NULL;
|
||||
static u32 GBAROMSize = 0;
|
||||
static char romfilename[1024];
|
||||
|
||||
/**
|
||||
* GBA Memory
|
||||
@ -91,7 +88,12 @@ static void VMClose( void )
|
||||
if ( gbabase != NULL )
|
||||
free(gbabase);
|
||||
|
||||
if ( romfile != NULL )
|
||||
gen_fclose(romfile);
|
||||
|
||||
gbabase = NULL;
|
||||
romfile = NULL;
|
||||
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
@ -99,49 +101,49 @@ static void VMClose( void )
|
||||
*
|
||||
* MEM2 version of GBA CPULoadROM
|
||||
****************************************************************************/
|
||||
|
||||
bool VMCPULoadROM(int method)
|
||||
int VMCPULoadROM( char *filename )
|
||||
{
|
||||
VMClose();
|
||||
VMAllocGBA();
|
||||
GBAROMSize = 0;
|
||||
int res=0;
|
||||
char temp[512];
|
||||
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;
|
||||
|
||||
switch (method)
|
||||
{
|
||||
case METHOD_SD:
|
||||
case METHOD_USB:
|
||||
if(inSz)
|
||||
GBAROMSize = LoadFATSzFile(szpath, (unsigned char *)rom);
|
||||
else
|
||||
GBAROMSize = LoadFATFile((char *)rom, filelist[selection].length);
|
||||
break;
|
||||
/* Always use MEM2, regardless of ROM size */
|
||||
res = gen_fread(rom, 1, GBAROMSize, romfile);
|
||||
|
||||
case METHOD_DVD:
|
||||
if(inSz)
|
||||
GBAROMSize = SzExtractFile(filelist[selection].offset, (unsigned char *)rom);
|
||||
else
|
||||
GBAROMSize = LoadDVDFile((unsigned char *)rom, filelist[selection].length);
|
||||
break;
|
||||
if ( (u32)res != GBAROMSize )
|
||||
{
|
||||
WaitPrompt((char*) "Error reading file!");
|
||||
while(1);
|
||||
}
|
||||
strcpy( romfilename, filename );
|
||||
|
||||
case METHOD_SMB:
|
||||
if(inSz)
|
||||
GBAROMSize = LoadSMBSzFile(szpath, (unsigned char *)rom);
|
||||
else
|
||||
GBAROMSize = LoadSMBFile((char *)rom, filelist[selection].length);
|
||||
break;
|
||||
}
|
||||
CPUUpdateRenderBuffers( true );
|
||||
|
||||
if(GBAROMSize)
|
||||
{
|
||||
CPUUpdateRenderBuffers( true );
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
VMClose();
|
||||
return false;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
@ -161,6 +163,8 @@ u32 VMRead32( u32 address )
|
||||
}
|
||||
|
||||
return READ32LE((rom + address));
|
||||
|
||||
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
@ -198,20 +202,18 @@ u8 VMRead8( u32 address )
|
||||
}
|
||||
#else
|
||||
|
||||
#include "sdfileio.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <malloc.h>
|
||||
|
||||
#include "agb/GBA.h"
|
||||
#include "GBA.h"
|
||||
#include "Globals.h"
|
||||
#include "Util.h"
|
||||
#include "Port.h"
|
||||
|
||||
#include "menudraw.h"
|
||||
#include "filesel.h"
|
||||
#include "vba.h"
|
||||
#include "fileop.h"
|
||||
|
||||
extern "C" {
|
||||
#include "tbtime.h"
|
||||
@ -245,8 +247,9 @@ static int vmpageno = 0;
|
||||
static char *rombase = NULL;
|
||||
static char *gbabase = NULL;
|
||||
static FILE* romfile = NULL;
|
||||
static int useVM = 1;
|
||||
static int useVM = 0;
|
||||
static u32 GBAROMSize = 0;
|
||||
static char romfilename[1024];
|
||||
|
||||
/**
|
||||
* GBA Memory
|
||||
@ -362,7 +365,7 @@ static void VMClose( void )
|
||||
free(gbabase);
|
||||
|
||||
if ( romfile != NULL )
|
||||
fclose(romfile);
|
||||
gen_fclose(romfile);
|
||||
|
||||
rombase = gbabase = NULL;
|
||||
romfile = NULL;
|
||||
@ -374,77 +377,54 @@ static void VMClose( void )
|
||||
*
|
||||
* VM version of GBA CPULoadROM
|
||||
****************************************************************************/
|
||||
|
||||
int VMCPULoadROM(int method)
|
||||
int VMCPULoadROM( char *filename )
|
||||
{
|
||||
int res;
|
||||
char msg[512];
|
||||
char filepath[MAXPATHLEN];
|
||||
int res;
|
||||
char msg[512];
|
||||
|
||||
/** Fix VM **/
|
||||
VMClose();
|
||||
VMInit();
|
||||
VMAllocGBA();
|
||||
/** Fix VM **/
|
||||
VMClose();
|
||||
VMInit();
|
||||
VMAllocGBA();
|
||||
|
||||
loadtimeradjust = GBAROMSize = 0;
|
||||
loadtimeradjust = useVM = GBAROMSize = 0;
|
||||
|
||||
switch (method)
|
||||
{
|
||||
case METHOD_SD:
|
||||
case METHOD_USB:
|
||||
break;
|
||||
printf("Filename %s\n", filename);
|
||||
|
||||
case METHOD_DVD:
|
||||
VMClose();
|
||||
return 0; // not implemented
|
||||
break;
|
||||
romfile = gen_fopen(filename, "rb");
|
||||
if ( romfile == NULL )
|
||||
{
|
||||
WaitPrompt((char*) "Error opening file!");
|
||||
while(1);
|
||||
VMClose();
|
||||
return 0;
|
||||
}
|
||||
|
||||
case METHOD_SMB:
|
||||
VMClose();
|
||||
return 0; // not implemented
|
||||
break;
|
||||
}
|
||||
// printf("ROM Size %d\n", romfile->fsize);
|
||||
|
||||
/* Check filename length */
|
||||
if ((strlen(currentdir)+1+strlen(filelist[selection].filename)) < MAXPATHLEN)
|
||||
sprintf(filepath, "%s/%s",currentdir,filelist[selection].filename);
|
||||
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 ) )
|
||||
{
|
||||
/* Always use VM, regardless of ROM size */
|
||||
res = gen_fread(rom, 1, (1 << VMSHIFTBITS), romfile);
|
||||
if ( res != (1 << VMSHIFTBITS ) )
|
||||
{
|
||||
sprintf(msg, "Error reading file! %i \n",res);
|
||||
WaitPrompt(msg);
|
||||
VMClose();
|
||||
return 0;
|
||||
}
|
||||
while(1);
|
||||
}
|
||||
|
||||
fseek(romfile, 0, SEEK_END);
|
||||
GBAROMSize = ftell(romfile);
|
||||
fseek(romfile, 0, SEEK_SET);
|
||||
vmpageno = 0;
|
||||
vmpage[0].pageptr = rombase;
|
||||
vmpage[0].pageno = 0;
|
||||
vmpage[0].pagetype = MEM_VM;
|
||||
vmpageno = 0;
|
||||
vmpage[0].pageptr = rombase;
|
||||
vmpage[0].pageno = 0;
|
||||
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);
|
||||
|
||||
res = fseek( romfile, pageid << VMSHIFTBITS, SEEK_SET );
|
||||
res = gen_fseek( romfile, pageid << VMSHIFTBITS, SEEK_SET );
|
||||
if ( ! res )
|
||||
{
|
||||
sprintf(msg, "Seek error! - Offset %08x %d\n", pageid << VMSHIFTBITS, res);
|
||||
WaitPrompt(msg);
|
||||
VMClose();
|
||||
return;
|
||||
while(1);
|
||||
}
|
||||
|
||||
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 ) )
|
||||
{
|
||||
sprintf(msg, "Error reading! %d bytes only\n", res);
|
||||
WaitPrompt(msg);
|
||||
VMClose();
|
||||
return;
|
||||
while(1);
|
||||
}
|
||||
|
||||
mftb(&end);
|
||||
@ -538,8 +516,7 @@ u32 VMRead32( u32 address )
|
||||
default:
|
||||
sprintf(msg, "VM32 : Unknown page type! (%d) [%d]", vmpage[pageid].pagetype, pageid);
|
||||
WaitPrompt(msg);
|
||||
VMClose();
|
||||
return 0;
|
||||
while(1);
|
||||
}
|
||||
|
||||
/* Can never get here ... but stops gcc bitchin' */
|
||||
@ -578,8 +555,7 @@ u16 VMRead16( u32 address )
|
||||
|
||||
default:
|
||||
WaitPrompt((char*) "VM16 : Unknown page type!");
|
||||
VMClose();
|
||||
return 0;
|
||||
while(1);
|
||||
}
|
||||
|
||||
/* Can never get here ... but stops gcc bitchin' */
|
||||
@ -618,8 +594,7 @@ u8 VMRead8( u32 address )
|
||||
|
||||
default:
|
||||
WaitPrompt((char*) "VM8 : Unknown page type!");
|
||||
VMClose();
|
||||
return 0;
|
||||
while(1);
|
||||
}
|
||||
|
||||
/* Can never get here ... but stops gcc bitchin' */
|
||||
|
@ -11,7 +11,7 @@
|
||||
#ifndef __VBAVMHDR__
|
||||
#define __VBAVMHDR__
|
||||
|
||||
bool VMCPULoadROM(int method);
|
||||
int VMCPULoadROM( char *filename );
|
||||
u32 VMRead32( u32 address );
|
||||
u16 VMRead16( 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.
|
||||
// Copyright (C) 1999-2003 Forgotten
|
||||
// Copyright (C) 2004 Forgotten and the VBA development team
|
||||
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; either version 2, or(at your option)
|
||||
// any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software Foundation,
|
||||
// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "CheatSearch.h"
|
||||
|
||||
CheatSearchBlock cheatSearchBlocks[4];
|
||||
|
||||
CheatSearchData cheatSearchData = {
|
||||
0,
|
||||
cheatSearchBlocks
|
||||
};
|
||||
|
||||
static bool cheatSearchEQ(u32 a, u32 b)
|
||||
{
|
||||
return a == b;
|
||||
}
|
||||
|
||||
static bool cheatSearchNE(u32 a, u32 b)
|
||||
{
|
||||
return a != b;
|
||||
}
|
||||
|
||||
static bool cheatSearchLT(u32 a, u32 b)
|
||||
{
|
||||
return a < b;
|
||||
}
|
||||
|
||||
static bool cheatSearchLE(u32 a, u32 b)
|
||||
{
|
||||
return a <= b;
|
||||
}
|
||||
|
||||
static bool cheatSearchGT(u32 a, u32 b)
|
||||
{
|
||||
return a > b;
|
||||
}
|
||||
|
||||
static bool cheatSearchGE(u32 a, u32 b)
|
||||
{
|
||||
return a >= b;
|
||||
}
|
||||
|
||||
static bool cheatSearchSignedEQ(s32 a, s32 b)
|
||||
{
|
||||
return a == b;
|
||||
}
|
||||
|
||||
static bool cheatSearchSignedNE(s32 a, s32 b)
|
||||
{
|
||||
return a != b;
|
||||
}
|
||||
|
||||
static bool cheatSearchSignedLT(s32 a, s32 b)
|
||||
{
|
||||
return a < b;
|
||||
}
|
||||
|
||||
static bool cheatSearchSignedLE(s32 a, s32 b)
|
||||
{
|
||||
return a <= b;
|
||||
}
|
||||
|
||||
static bool cheatSearchSignedGT(s32 a, s32 b)
|
||||
{
|
||||
return a > b;
|
||||
}
|
||||
|
||||
static bool cheatSearchSignedGE(s32 a, s32 b)
|
||||
{
|
||||
return a >= b;
|
||||
}
|
||||
|
||||
static bool (*cheatSearchFunc[])(u32,u32) = {
|
||||
cheatSearchEQ,
|
||||
cheatSearchNE,
|
||||
cheatSearchLT,
|
||||
cheatSearchLE,
|
||||
cheatSearchGT,
|
||||
cheatSearchGE
|
||||
};
|
||||
|
||||
static bool (*cheatSearchSignedFunc[])(s32,s32) = {
|
||||
cheatSearchSignedEQ,
|
||||
cheatSearchSignedNE,
|
||||
cheatSearchSignedLT,
|
||||
cheatSearchSignedLE,
|
||||
cheatSearchSignedGT,
|
||||
cheatSearchSignedGE
|
||||
};
|
||||
|
||||
void cheatSearchCleanup(CheatSearchData *cs)
|
||||
{
|
||||
int count = cs->count;
|
||||
|
||||
for(int i = 0; i < count; i++) {
|
||||
free(cs->blocks[i].saved);
|
||||
free(cs->blocks[i].bits);
|
||||
}
|
||||
cs->count = 0;
|
||||
}
|
||||
|
||||
void cheatSearchStart(const CheatSearchData *cs)
|
||||
{
|
||||
int count = cs->count;
|
||||
|
||||
for(int i = 0; i < count; i++) {
|
||||
CheatSearchBlock *block = &cs->blocks[i];
|
||||
|
||||
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++];
|
||||
|
||||
switch(size) {
|
||||
case BITS_8:
|
||||
res <<= 24;
|
||||
return ((s32)res) >> 24;
|
||||
case BITS_16:
|
||||
res |= ((u32)data[off++])<<8;
|
||||
res <<= 16;
|
||||
return ((s32)res) >> 16;
|
||||
case BITS_32:
|
||||
res |= ((u32)data[off++])<<8;
|
||||
res |= ((u32)data[off++])<<16;
|
||||
res |= ((u32)data[off++])<<24;
|
||||
return (s32)res;
|
||||
}
|
||||
return (s32)res;
|
||||
}
|
||||
|
||||
u32 cheatSearchRead(u8 *data, int off, int size)
|
||||
{
|
||||
u32 res = data[off++];
|
||||
if(size == BITS_16)
|
||||
res |= ((u32)data[off++])<<8;
|
||||
else if(size == BITS_32) {
|
||||
res |= ((u32)data[off++])<<8;
|
||||
res |= ((u32)data[off++])<<16;
|
||||
res |= ((u32)data[off++])<<24;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
void cheatSearch(const CheatSearchData *cs, int compare, int size,
|
||||
bool isSigned)
|
||||
{
|
||||
if(compare < 0 || compare > SEARCH_GE)
|
||||
return;
|
||||
int inc = 1;
|
||||
if(size == BITS_16)
|
||||
inc = 2;
|
||||
else if(size == BITS_32)
|
||||
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;
|
||||
u8 *data = block->data;
|
||||
u8 *saved = block->saved;
|
||||
|
||||
for(int j = 0; j < size2; j += inc) {
|
||||
if(IS_BIT_SET(bits, j)) {
|
||||
s32 a = cheatSearchSignedRead(data, j, size);
|
||||
s32 b = cheatSearchSignedRead(saved,j, size);
|
||||
|
||||
if(!func(a, b)) {
|
||||
CLEAR_BIT(bits, j);
|
||||
if(size == BITS_16)
|
||||
CLEAR_BIT(bits, j+1);
|
||||
if(size == BITS_32) {
|
||||
CLEAR_BIT(bits, j+2);
|
||||
CLEAR_BIT(bits, j+3);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
bool (*func)(u32,u32) = cheatSearchFunc[compare];
|
||||
|
||||
for(int i = 0; i < cs->count; i++) {
|
||||
CheatSearchBlock *block = &cs->blocks[i];
|
||||
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)) {
|
||||
u32 a = cheatSearchRead(data, j, size);
|
||||
u32 b = cheatSearchRead(saved,j, size);
|
||||
|
||||
if(!func(a, b)) {
|
||||
CLEAR_BIT(bits, j);
|
||||
if(size == BITS_16)
|
||||
CLEAR_BIT(bits, j+1);
|
||||
if(size == BITS_32) {
|
||||
CLEAR_BIT(bits, j+2);
|
||||
CLEAR_BIT(bits, j+3);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void cheatSearchValue(const CheatSearchData *cs, int compare, int size,
|
||||
bool isSigned, u32 value)
|
||||
{
|
||||
if(compare < 0 || compare > SEARCH_GE)
|
||||
return;
|
||||
int inc = 1;
|
||||
if(size == BITS_16)
|
||||
inc = 2;
|
||||
else if(size == BITS_32)
|
||||
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;
|
||||
u8 *data = block->data;
|
||||
|
||||
for(int j = 0; j < size2; j += inc) {
|
||||
if(IS_BIT_SET(bits, j)) {
|
||||
s32 a = cheatSearchSignedRead(data, j, size);
|
||||
s32 b = (s32)value;
|
||||
|
||||
if(!func(a, b)) {
|
||||
CLEAR_BIT(bits, j);
|
||||
if(size == BITS_16)
|
||||
CLEAR_BIT(bits, j+1);
|
||||
if(size == BITS_32) {
|
||||
CLEAR_BIT(bits, j+2);
|
||||
CLEAR_BIT(bits, j+3);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
bool (*func)(u32,u32) = cheatSearchFunc[compare];
|
||||
|
||||
for(int i = 0; i < cs->count; i++) {
|
||||
CheatSearchBlock *block = &cs->blocks[i];
|
||||
int size2 = block->size;
|
||||
u8 *bits = block->bits;
|
||||
u8 *data = block->data;
|
||||
|
||||
for(int j = 0; j < size2; j += inc) {
|
||||
if(IS_BIT_SET(bits, j)) {
|
||||
u32 a = cheatSearchRead(data, j, size);
|
||||
|
||||
if(!func(a, value)) {
|
||||
CLEAR_BIT(bits, j);
|
||||
if(size == BITS_16)
|
||||
CLEAR_BIT(bits, j+1);
|
||||
if(size == BITS_32) {
|
||||
CLEAR_BIT(bits, j+2);
|
||||
CLEAR_BIT(bits, j+3);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
|
||||
// Copyright (C) 1999-2003 Forgotten
|
||||
// Copyright (C) 2004 Forgotten and the VBA development team
|
||||
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; either version 2, or(at your option)
|
||||
// any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software Foundation,
|
||||
// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "CheatSearch.h"
|
||||
|
||||
CheatSearchBlock cheatSearchBlocks[4];
|
||||
|
||||
CheatSearchData cheatSearchData = {
|
||||
0,
|
||||
cheatSearchBlocks
|
||||
};
|
||||
|
||||
static bool cheatSearchEQ(u32 a, u32 b)
|
||||
{
|
||||
return a == b;
|
||||
}
|
||||
|
||||
static bool cheatSearchNE(u32 a, u32 b)
|
||||
{
|
||||
return a != b;
|
||||
}
|
||||
|
||||
static bool cheatSearchLT(u32 a, u32 b)
|
||||
{
|
||||
return a < b;
|
||||
}
|
||||
|
||||
static bool cheatSearchLE(u32 a, u32 b)
|
||||
{
|
||||
return a <= b;
|
||||
}
|
||||
|
||||
static bool cheatSearchGT(u32 a, u32 b)
|
||||
{
|
||||
return a > b;
|
||||
}
|
||||
|
||||
static bool cheatSearchGE(u32 a, u32 b)
|
||||
{
|
||||
return a >= b;
|
||||
}
|
||||
|
||||
static bool cheatSearchSignedEQ(s32 a, s32 b)
|
||||
{
|
||||
return a == b;
|
||||
}
|
||||
|
||||
static bool cheatSearchSignedNE(s32 a, s32 b)
|
||||
{
|
||||
return a != b;
|
||||
}
|
||||
|
||||
static bool cheatSearchSignedLT(s32 a, s32 b)
|
||||
{
|
||||
return a < b;
|
||||
}
|
||||
|
||||
static bool cheatSearchSignedLE(s32 a, s32 b)
|
||||
{
|
||||
return a <= b;
|
||||
}
|
||||
|
||||
static bool cheatSearchSignedGT(s32 a, s32 b)
|
||||
{
|
||||
return a > b;
|
||||
}
|
||||
|
||||
static bool cheatSearchSignedGE(s32 a, s32 b)
|
||||
{
|
||||
return a >= b;
|
||||
}
|
||||
|
||||
static bool (*cheatSearchFunc[])(u32,u32) = {
|
||||
cheatSearchEQ,
|
||||
cheatSearchNE,
|
||||
cheatSearchLT,
|
||||
cheatSearchLE,
|
||||
cheatSearchGT,
|
||||
cheatSearchGE
|
||||
};
|
||||
|
||||
static bool (*cheatSearchSignedFunc[])(s32,s32) = {
|
||||
cheatSearchSignedEQ,
|
||||
cheatSearchSignedNE,
|
||||
cheatSearchSignedLT,
|
||||
cheatSearchSignedLE,
|
||||
cheatSearchSignedGT,
|
||||
cheatSearchSignedGE
|
||||
};
|
||||
|
||||
void cheatSearchCleanup(CheatSearchData *cs)
|
||||
{
|
||||
int count = cs->count;
|
||||
|
||||
for(int i = 0; i < count; i++)
|
||||
{
|
||||
free(cs->blocks[i].saved);
|
||||
free(cs->blocks[i].bits);
|
||||
}
|
||||
cs->count = 0;
|
||||
}
|
||||
|
||||
void cheatSearchStart(const CheatSearchData *cs)
|
||||
{
|
||||
int count = cs->count;
|
||||
|
||||
for(int i = 0; i < count; i++)
|
||||
{
|
||||
CheatSearchBlock *block = &cs->blocks[i];
|
||||
|
||||
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++];
|
||||
|
||||
switch(size)
|
||||
{
|
||||
case BITS_8:
|
||||
res <<= 24;
|
||||
return ((s32)res) >> 24;
|
||||
case BITS_16:
|
||||
res |= ((u32)data[off++])<<8;
|
||||
res <<= 16;
|
||||
return ((s32)res) >> 16;
|
||||
case BITS_32:
|
||||
res |= ((u32)data[off++])<<8;
|
||||
res |= ((u32)data[off++])<<16;
|
||||
res |= ((u32)data[off++])<<24;
|
||||
return (s32)res;
|
||||
}
|
||||
return (s32)res;
|
||||
}
|
||||
|
||||
u32 cheatSearchRead(u8 *data, int off, int size)
|
||||
{
|
||||
u32 res = data[off++];
|
||||
if(size == BITS_16)
|
||||
res |= ((u32)data[off++])<<8;
|
||||
else if(size == BITS_32)
|
||||
{
|
||||
res |= ((u32)data[off++])<<8;
|
||||
res |= ((u32)data[off++])<<16;
|
||||
res |= ((u32)data[off++])<<24;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
void cheatSearch(const CheatSearchData *cs, int compare, int size,
|
||||
bool isSigned)
|
||||
{
|
||||
if(compare < 0 || compare > SEARCH_GE)
|
||||
return;
|
||||
int inc = 1;
|
||||
if(size == BITS_16)
|
||||
inc = 2;
|
||||
else if(size == BITS_32)
|
||||
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;
|
||||
u8 *data = block->data;
|
||||
u8 *saved = block->saved;
|
||||
|
||||
for(int j = 0; j < size2; j += inc)
|
||||
{
|
||||
if(IS_BIT_SET(bits, j))
|
||||
{
|
||||
s32 a = cheatSearchSignedRead(data, j, size);
|
||||
s32 b = cheatSearchSignedRead(saved,j, size);
|
||||
|
||||
if(!func(a, b))
|
||||
{
|
||||
CLEAR_BIT(bits, j);
|
||||
if(size == BITS_16)
|
||||
CLEAR_BIT(bits, j+1);
|
||||
if(size == BITS_32)
|
||||
{
|
||||
CLEAR_BIT(bits, j+2);
|
||||
CLEAR_BIT(bits, j+3);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
bool (*func)(u32,u32) = cheatSearchFunc[compare];
|
||||
|
||||
for(int i = 0; i < cs->count; i++)
|
||||
{
|
||||
CheatSearchBlock *block = &cs->blocks[i];
|
||||
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))
|
||||
{
|
||||
u32 a = cheatSearchRead(data, j, size);
|
||||
u32 b = cheatSearchRead(saved,j, size);
|
||||
|
||||
if(!func(a, b))
|
||||
{
|
||||
CLEAR_BIT(bits, j);
|
||||
if(size == BITS_16)
|
||||
CLEAR_BIT(bits, j+1);
|
||||
if(size == BITS_32)
|
||||
{
|
||||
CLEAR_BIT(bits, j+2);
|
||||
CLEAR_BIT(bits, j+3);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void cheatSearchValue(const CheatSearchData *cs, int compare, int size,
|
||||
bool isSigned, u32 value)
|
||||
{
|
||||
if(compare < 0 || compare > SEARCH_GE)
|
||||
return;
|
||||
int inc = 1;
|
||||
if(size == BITS_16)
|
||||
inc = 2;
|
||||
else if(size == BITS_32)
|
||||
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;
|
||||
u8 *data = block->data;
|
||||
|
||||
for(int j = 0; j < size2; j += inc)
|
||||
{
|
||||
if(IS_BIT_SET(bits, j))
|
||||
{
|
||||
s32 a = cheatSearchSignedRead(data, j, size);
|
||||
s32 b = (s32)value;
|
||||
|
||||
if(!func(a, b))
|
||||
{
|
||||
CLEAR_BIT(bits, j);
|
||||
if(size == BITS_16)
|
||||
CLEAR_BIT(bits, j+1);
|
||||
if(size == BITS_32)
|
||||
{
|
||||
CLEAR_BIT(bits, j+2);
|
||||
CLEAR_BIT(bits, j+3);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
bool (*func)(u32,u32) = cheatSearchFunc[compare];
|
||||
|
||||
for(int i = 0; i < cs->count; i++)
|
||||
{
|
||||
CheatSearchBlock *block = &cs->blocks[i];
|
||||
int size2 = block->size;
|
||||
u8 *bits = block->bits;
|
||||
u8 *data = block->data;
|
||||
|
||||
for(int j = 0; j < size2; j += inc)
|
||||
{
|
||||
if(IS_BIT_SET(bits, j))
|
||||
{
|
||||
u32 a = cheatSearchRead(data, j, size);
|
||||
|
||||
if(!func(a, value))
|
||||
{
|
||||
CLEAR_BIT(bits, j);
|
||||
if(size == BITS_16)
|
||||
CLEAR_BIT(bits, j+1);
|
||||
if(size == BITS_32)
|
||||
{
|
||||
CLEAR_BIT(bits, j+2);
|
||||
CLEAR_BIT(bits, j+3);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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++ -*-
|
||||
// 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_CHEATSEARCH_H
|
||||
#define VBA_CHEATSEARCH_H
|
||||
|
||||
#include "System.h"
|
||||
|
||||
struct CheatSearchBlock {
|
||||
int size;
|
||||
u32 offset;
|
||||
u8 *bits;
|
||||
u8 *data;
|
||||
u8 *saved;
|
||||
};
|
||||
|
||||
struct CheatSearchData {
|
||||
int count;
|
||||
CheatSearchBlock *blocks;
|
||||
};
|
||||
|
||||
enum {
|
||||
SEARCH_EQ,
|
||||
SEARCH_NE,
|
||||
SEARCH_LT,
|
||||
SEARCH_LE,
|
||||
SEARCH_GT,
|
||||
SEARCH_GE
|
||||
};
|
||||
|
||||
enum {
|
||||
BITS_8,
|
||||
BITS_16,
|
||||
BITS_32
|
||||
};
|
||||
|
||||
#define SET_BIT(bits,off) \
|
||||
(bits)[(off) >> 3] |= (1 << ((off) & 7))
|
||||
|
||||
#define CLEAR_BIT(bits, off) \
|
||||
(bits)[(off) >> 3] &= ~(1 << ((off) & 7))
|
||||
|
||||
#define IS_BIT_SET(bits, off) \
|
||||
(bits)[(off) >> 3] & (1 << ((off) & 7))
|
||||
|
||||
extern CheatSearchData cheatSearchData;
|
||||
extern void cheatSearchCleanup(CheatSearchData *cs);
|
||||
extern void cheatSearchStart(const CheatSearchData *cs);
|
||||
extern void cheatSearch(const CheatSearchData *cs, int compare, int size,
|
||||
bool isSigned);
|
||||
extern void cheatSearchValue(const CheatSearchData *cs, int compare, int size,
|
||||
bool isSigned, u32 value);
|
||||
extern int cheatSearchGetCount(const CheatSearchData *cs, int size);
|
||||
extern void cheatSearchUpdateValues(const CheatSearchData *cs);
|
||||
extern s32 cheatSearchSignedRead(u8 *data, int off, int size);
|
||||
extern u32 cheatSearchRead(u8 *data, int off, int size);
|
||||
#endif
|
||||
// -*- C++ -*-
|
||||
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
|
||||
// Copyright (C) 1999-2003 Forgotten
|
||||
// Copyright (C) 2004 Forgotten and the VBA development team
|
||||
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; either version 2, or(at your option)
|
||||
// any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software Foundation,
|
||||
// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
#ifndef VBA_CHEATSEARCH_H
|
||||
#define VBA_CHEATSEARCH_H
|
||||
|
||||
#include "System.h"
|
||||
|
||||
struct CheatSearchBlock
|
||||
{
|
||||
int size;
|
||||
u32 offset;
|
||||
u8 *bits;
|
||||
u8 *data;
|
||||
u8 *saved;
|
||||
};
|
||||
|
||||
struct CheatSearchData
|
||||
{
|
||||
int count;
|
||||
CheatSearchBlock *blocks;
|
||||
};
|
||||
|
||||
enum {
|
||||
SEARCH_EQ,
|
||||
SEARCH_NE,
|
||||
SEARCH_LT,
|
||||
SEARCH_LE,
|
||||
SEARCH_GT,
|
||||
SEARCH_GE
|
||||
};
|
||||
|
||||
enum {
|
||||
BITS_8,
|
||||
BITS_16,
|
||||
BITS_32
|
||||
};
|
||||
|
||||
#define SET_BIT(bits,off) \
|
||||
(bits)[(off) >> 3] |= (1 << ((off) & 7))
|
||||
|
||||
#define CLEAR_BIT(bits, off) \
|
||||
(bits)[(off) >> 3] &= ~(1 << ((off) & 7))
|
||||
|
||||
#define IS_BIT_SET(bits, off) \
|
||||
(bits)[(off) >> 3] & (1 << ((off) & 7))
|
||||
|
||||
extern CheatSearchData cheatSearchData;
|
||||
extern void cheatSearchCleanup(CheatSearchData *cs);
|
||||
extern void cheatSearchStart(const CheatSearchData *cs);
|
||||
extern void cheatSearch(const CheatSearchData *cs, int compare, int size,
|
||||
bool isSigned);
|
||||
extern void cheatSearchValue(const CheatSearchData *cs, int compare, int size,
|
||||
bool isSigned, u32 value);
|
||||
extern int cheatSearchGetCount(const CheatSearchData *cs, int size);
|
||||
extern void cheatSearchUpdateValues(const CheatSearchData *cs);
|
||||
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++ -*-
|
||||
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
|
||||
// Copyright (C) 1999-2003 Forgotten
|
||||
// Copyright (C) 2004-2006 Forgotten and the VBA development team
|
||||
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; either version 2, or(at your option)
|
||||
// any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software Foundation,
|
||||
// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
#ifndef GBA_CHEATS_H
|
||||
#define GBA_CHEATS_H
|
||||
|
||||
struct CheatsData {
|
||||
int code;
|
||||
int size;
|
||||
int status;
|
||||
bool enabled;
|
||||
u32 rawaddress;
|
||||
u32 address;
|
||||
u32 value;
|
||||
u32 oldValue;
|
||||
char codestring[20];
|
||||
char desc[32];
|
||||
};
|
||||
|
||||
extern void cheatsAdd(const char *,const char *,u32, u32,u32,int,int);
|
||||
extern void cheatsAddCheatCode(const char *code, const char *desc);
|
||||
extern void cheatsAddGSACode(const char *code, const char *desc, bool v3);
|
||||
extern void cheatsAddCBACode(const char *code, const char *desc);
|
||||
extern bool cheatsImportGSACodeFile(const char *name, int game, bool v3);
|
||||
extern void cheatsDelete(int number, bool restore);
|
||||
extern void cheatsDeleteAll(bool restore);
|
||||
extern void cheatsEnable(int number);
|
||||
extern void cheatsDisable(int number);
|
||||
extern void cheatsSaveGame(gzFile file);
|
||||
extern void cheatsReadGame(gzFile file, int version);
|
||||
extern void cheatsSaveCheatList(const char *file);
|
||||
extern bool cheatsLoadCheatList(const char *file);
|
||||
extern void cheatsWriteMemory(u32, u32);
|
||||
extern void cheatsWriteHalfWord(u32, u16);
|
||||
extern void cheatsWriteByte(u32, u8);
|
||||
extern int cheatsCheckKeys(u32,u32);
|
||||
extern int cheatsNumber;
|
||||
extern CheatsData cheatsList[100];
|
||||
#endif // GBA_CHEATS_H
|
||||
// -*- 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 GBA_CHEATS_H
|
||||
#define GBA_CHEATS_H
|
||||
|
||||
struct CheatsData
|
||||
{
|
||||
int code;
|
||||
int size;
|
||||
int status;
|
||||
bool enabled;
|
||||
u32 address;
|
||||
u32 value;
|
||||
u32 oldValue;
|
||||
char codestring[20];
|
||||
char desc[32];
|
||||
};
|
||||
|
||||
extern void cheatsAdd(const char *,const char *,u32,u32,int,int);
|
||||
extern void cheatsAddCheatCode(const char *code, const char *desc);
|
||||
extern void cheatsAddGSACode(const char *code, const char *desc, bool v3);
|
||||
extern void cheatsAddCBACode(const char *code, const char *desc);
|
||||
extern bool cheatsImportGSACodeFile(const char *name, int game, bool v3);
|
||||
extern void cheatsDelete(int number, bool restore);
|
||||
extern void cheatsDeleteAll(bool restore);
|
||||
extern void cheatsEnable(int number);
|
||||
extern void cheatsDisable(int number);
|
||||
extern void cheatsSaveGame(gzFile file);
|
||||
extern void cheatsReadGame(gzFile file);
|
||||
extern void cheatsSaveCheatList(const char *file);
|
||||
extern bool cheatsLoadCheatList(const char *file);
|
||||
extern void cheatsWriteMemory(u32 *, u32, u32);
|
||||
extern void cheatsWriteHalfWord(u16 *, u16, u16);
|
||||
extern void cheatsWriteByte(u8 *, u8);
|
||||
extern int cheatsCheckKeys(u32,u32);
|
||||
extern int cheatsNumber;
|
||||
extern CheatsData cheatsList[100];
|
||||
#endif // GBA_CHEATS_H
|
||||
|
@ -1,206 +1,214 @@
|
||||
// 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.
|
||||
|
||||
#include <string.h>
|
||||
#include "agb/GBA.h"
|
||||
#include "EEprom.h"
|
||||
#include "Util.h"
|
||||
|
||||
extern int cpuDmaCount;
|
||||
|
||||
int eepromMode = EEPROM_IDLE;
|
||||
int eepromByte = 0;
|
||||
int eepromBits = 0;
|
||||
int eepromAddress = 0;
|
||||
u8 eepromData[0x2000];
|
||||
u8 eepromBuffer[16];
|
||||
bool eepromInUse = false;
|
||||
int eepromSize = 512;
|
||||
|
||||
variable_desc eepromSaveData[] = {
|
||||
{ &eepromMode, sizeof(int) },
|
||||
{ &eepromByte, sizeof(int) },
|
||||
{ &eepromBits , sizeof(int) },
|
||||
{ &eepromAddress , sizeof(int) },
|
||||
{ &eepromInUse, sizeof(bool) },
|
||||
{ &eepromData[0], 512 },
|
||||
{ &eepromBuffer[0], 16 },
|
||||
{ NULL, 0 }
|
||||
};
|
||||
|
||||
void eepromInit()
|
||||
{
|
||||
memset(eepromData, 255, sizeof(eepromData));
|
||||
}
|
||||
|
||||
void eepromReset()
|
||||
{
|
||||
eepromMode = EEPROM_IDLE;
|
||||
eepromByte = 0;
|
||||
eepromBits = 0;
|
||||
eepromAddress = 0;
|
||||
eepromInUse = false;
|
||||
eepromSize = 512;
|
||||
}
|
||||
|
||||
void eepromSaveGame(gzFile gzFile)
|
||||
{
|
||||
utilWriteData(gzFile, eepromSaveData);
|
||||
utilWriteInt(gzFile, eepromSize);
|
||||
utilGzWrite(gzFile, eepromData, 0x2000);
|
||||
}
|
||||
|
||||
void eepromReadGame(gzFile gzFile, int version)
|
||||
{
|
||||
utilReadData(gzFile, eepromSaveData);
|
||||
if(version >= SAVE_GAME_VERSION_3) {
|
||||
eepromSize = utilReadInt(gzFile);
|
||||
utilGzRead(gzFile, eepromData, 0x2000);
|
||||
} else {
|
||||
// prior to 0.7.1, only 4K EEPROM was supported
|
||||
eepromSize = 512;
|
||||
}
|
||||
}
|
||||
|
||||
void eepromReadGameSkip(gzFile gzFile, int version)
|
||||
{
|
||||
// skip the eeprom data in a save game
|
||||
utilReadDataSkip(gzFile, eepromSaveData);
|
||||
if(version >= SAVE_GAME_VERSION_3) {
|
||||
utilGzSeek(gzFile, sizeof(int), SEEK_CUR);
|
||||
utilGzSeek(gzFile, 0x2000, SEEK_CUR);
|
||||
}
|
||||
}
|
||||
|
||||
int eepromRead(u32 /* address */)
|
||||
{
|
||||
switch(eepromMode) {
|
||||
case EEPROM_IDLE:
|
||||
case EEPROM_READADDRESS:
|
||||
case EEPROM_WRITEDATA:
|
||||
return 1;
|
||||
case EEPROM_READDATA:
|
||||
{
|
||||
eepromBits++;
|
||||
if(eepromBits == 4) {
|
||||
eepromMode = EEPROM_READDATA2;
|
||||
eepromBits = 0;
|
||||
eepromByte = 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
case EEPROM_READDATA2:
|
||||
{
|
||||
int data = 0;
|
||||
int address = eepromAddress << 3;
|
||||
int mask = 1 << (7 - (eepromBits & 7));
|
||||
data = (eepromData[address+eepromByte] & mask) ? 1 : 0;
|
||||
eepromBits++;
|
||||
if((eepromBits & 7) == 0)
|
||||
eepromByte++;
|
||||
if(eepromBits == 0x40)
|
||||
eepromMode = EEPROM_IDLE;
|
||||
return data;
|
||||
}
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
void eepromWrite(u32 /* address */, u8 value)
|
||||
{
|
||||
if(cpuDmaCount == 0)
|
||||
return;
|
||||
int bit = value & 1;
|
||||
switch(eepromMode) {
|
||||
case EEPROM_IDLE:
|
||||
eepromByte = 0;
|
||||
eepromBits = 1;
|
||||
eepromBuffer[eepromByte] = bit;
|
||||
eepromMode = EEPROM_READADDRESS;
|
||||
break;
|
||||
case EEPROM_READADDRESS:
|
||||
eepromBuffer[eepromByte] <<= 1;
|
||||
eepromBuffer[eepromByte] |= bit;
|
||||
eepromBits++;
|
||||
if((eepromBits & 7) == 0) {
|
||||
eepromByte++;
|
||||
}
|
||||
if(cpuDmaCount == 0x11 || cpuDmaCount == 0x51) {
|
||||
if(eepromBits == 0x11) {
|
||||
eepromInUse = true;
|
||||
eepromSize = 0x2000;
|
||||
eepromAddress = ((eepromBuffer[0] & 0x3F) << 8) |
|
||||
((eepromBuffer[1] & 0xFF));
|
||||
if(!(eepromBuffer[0] & 0x40)) {
|
||||
eepromBuffer[0] = bit;
|
||||
eepromBits = 1;
|
||||
eepromByte = 0;
|
||||
eepromMode = EEPROM_WRITEDATA;
|
||||
} else {
|
||||
eepromMode = EEPROM_READDATA;
|
||||
eepromByte = 0;
|
||||
eepromBits = 0;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if(eepromBits == 9) {
|
||||
eepromInUse = true;
|
||||
eepromAddress = (eepromBuffer[0] & 0x3F);
|
||||
if(!(eepromBuffer[0] & 0x40)) {
|
||||
eepromBuffer[0] = bit;
|
||||
eepromBits = 1;
|
||||
eepromByte = 0;
|
||||
eepromMode = EEPROM_WRITEDATA;
|
||||
} else {
|
||||
eepromMode = EEPROM_READDATA;
|
||||
eepromByte = 0;
|
||||
eepromBits = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case EEPROM_READDATA:
|
||||
case EEPROM_READDATA2:
|
||||
// should we reset here?
|
||||
eepromMode = EEPROM_IDLE;
|
||||
break;
|
||||
case EEPROM_WRITEDATA:
|
||||
eepromBuffer[eepromByte] <<= 1;
|
||||
eepromBuffer[eepromByte] |= bit;
|
||||
eepromBits++;
|
||||
if((eepromBits & 7) == 0) {
|
||||
eepromByte++;
|
||||
}
|
||||
if(eepromBits == 0x40) {
|
||||
eepromInUse = true;
|
||||
// write data;
|
||||
for(int i = 0; i < 8; i++) {
|
||||
eepromData[(eepromAddress << 3) + i] = eepromBuffer[i];
|
||||
}
|
||||
systemSaveUpdateCounter = SYSTEM_SAVE_UPDATED;
|
||||
} else if(eepromBits == 0x41) {
|
||||
eepromMode = EEPROM_IDLE;
|
||||
eepromByte = 0;
|
||||
eepromBits = 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
|
||||
// Copyright (C) 1999-2003 Forgotten
|
||||
// Copyright (C) 2004 Forgotten and the VBA development team
|
||||
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; either version 2, or(at your option)
|
||||
// any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software Foundation,
|
||||
// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
#include "GBA.h"
|
||||
#include "EEprom.h"
|
||||
#include "Util.h"
|
||||
|
||||
extern int cpuDmaCount;
|
||||
|
||||
int eepromMode = EEPROM_IDLE;
|
||||
int eepromByte = 0;
|
||||
int eepromBits = 0;
|
||||
int eepromAddress = 0;
|
||||
u8 eepromData[0x2000];
|
||||
u8 eepromBuffer[16];
|
||||
bool eepromInUse = false;
|
||||
int eepromSize = 512;
|
||||
|
||||
variable_desc eepromSaveData[] = {
|
||||
{ &eepromMode, sizeof(int) },
|
||||
{ &eepromByte, sizeof(int) },
|
||||
{ &eepromBits , sizeof(int) },
|
||||
{ &eepromAddress , sizeof(int) },
|
||||
{ &eepromInUse, sizeof(bool) },
|
||||
{ &eepromData[0], 512 },
|
||||
{ &eepromBuffer[0], 16 },
|
||||
{ NULL, 0 }
|
||||
};
|
||||
|
||||
void eepromReset()
|
||||
{
|
||||
eepromMode = EEPROM_IDLE;
|
||||
eepromByte = 0;
|
||||
eepromBits = 0;
|
||||
eepromAddress = 0;
|
||||
eepromInUse = false;
|
||||
eepromSize = 512;
|
||||
}
|
||||
|
||||
void eepromSaveGame(gzFile gzFile)
|
||||
{
|
||||
utilWriteData(gzFile, eepromSaveData);
|
||||
utilWriteInt(gzFile, eepromSize);
|
||||
utilGzWrite(gzFile, eepromData, 0x2000);
|
||||
}
|
||||
|
||||
void eepromReadGame(gzFile gzFile, int version)
|
||||
{
|
||||
utilReadData(gzFile, eepromSaveData);
|
||||
if(version >= SAVE_GAME_VERSION_3)
|
||||
{
|
||||
eepromSize = utilReadInt(gzFile);
|
||||
utilGzRead(gzFile, eepromData, 0x2000);
|
||||
}
|
||||
else
|
||||
{
|
||||
// prior to 0.7.1, only 4K EEPROM was supported
|
||||
eepromSize = 512;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int eepromRead(u32 /* address */)
|
||||
{
|
||||
switch(eepromMode)
|
||||
{
|
||||
case EEPROM_IDLE:
|
||||
case EEPROM_READADDRESS:
|
||||
case EEPROM_WRITEDATA:
|
||||
return 1;
|
||||
case EEPROM_READDATA:
|
||||
{
|
||||
eepromBits++;
|
||||
if(eepromBits == 4)
|
||||
{
|
||||
eepromMode = EEPROM_READDATA2;
|
||||
eepromBits = 0;
|
||||
eepromByte = 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
case EEPROM_READDATA2:
|
||||
{
|
||||
int data = 0;
|
||||
int address = eepromAddress << 3;
|
||||
int mask = 1 << (7 - (eepromBits & 7));
|
||||
data = (eepromData[address+eepromByte] & mask) ? 1 : 0;
|
||||
eepromBits++;
|
||||
if((eepromBits & 7) == 0)
|
||||
eepromByte++;
|
||||
if(eepromBits == 0x40)
|
||||
eepromMode = EEPROM_IDLE;
|
||||
return data;
|
||||
}
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
void eepromWrite(u32 /* address */, u8 value)
|
||||
{
|
||||
if(cpuDmaCount == 0)
|
||||
return;
|
||||
int bit = value & 1;
|
||||
switch(eepromMode)
|
||||
{
|
||||
case EEPROM_IDLE:
|
||||
eepromByte = 0;
|
||||
eepromBits = 1;
|
||||
eepromBuffer[eepromByte] = bit;
|
||||
eepromMode = EEPROM_READADDRESS;
|
||||
break;
|
||||
case EEPROM_READADDRESS:
|
||||
eepromBuffer[eepromByte] <<= 1;
|
||||
eepromBuffer[eepromByte] |= bit;
|
||||
eepromBits++;
|
||||
if((eepromBits & 7) == 0)
|
||||
{
|
||||
eepromByte++;
|
||||
}
|
||||
if(cpuDmaCount == 0x11 || cpuDmaCount == 0x51)
|
||||
{
|
||||
if(eepromBits == 0x11)
|
||||
{
|
||||
eepromInUse = true;
|
||||
eepromSize = 0x2000;
|
||||
eepromAddress = ((eepromBuffer[0] & 0x3F) << 8) |
|
||||
((eepromBuffer[1] & 0xFF));
|
||||
if(!(eepromBuffer[0] & 0x40))
|
||||
{
|
||||
eepromBuffer[0] = bit;
|
||||
eepromBits = 1;
|
||||
eepromByte = 0;
|
||||
eepromMode = EEPROM_WRITEDATA;
|
||||
}
|
||||
else
|
||||
{
|
||||
eepromMode = EEPROM_READDATA;
|
||||
eepromByte = 0;
|
||||
eepromBits = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(eepromBits == 9)
|
||||
{
|
||||
eepromInUse = true;
|
||||
eepromAddress = (eepromBuffer[0] & 0x3F);
|
||||
if(!(eepromBuffer[0] & 0x40))
|
||||
{
|
||||
eepromBuffer[0] = bit;
|
||||
eepromBits = 1;
|
||||
eepromByte = 0;
|
||||
eepromMode = EEPROM_WRITEDATA;
|
||||
}
|
||||
else
|
||||
{
|
||||
eepromMode = EEPROM_READDATA;
|
||||
eepromByte = 0;
|
||||
eepromBits = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case EEPROM_READDATA:
|
||||
case EEPROM_READDATA2:
|
||||
// should we reset here?
|
||||
eepromMode = EEPROM_IDLE;
|
||||
break;
|
||||
case EEPROM_WRITEDATA:
|
||||
eepromBuffer[eepromByte] <<= 1;
|
||||
eepromBuffer[eepromByte] |= bit;
|
||||
eepromBits++;
|
||||
if((eepromBits & 7) == 0)
|
||||
{
|
||||
eepromByte++;
|
||||
}
|
||||
if(eepromBits == 0x40)
|
||||
{
|
||||
eepromInUse = true;
|
||||
// write data;
|
||||
for(int i = 0; i < 8; i++)
|
||||
{
|
||||
eepromData[(eepromAddress << 3) + i] = eepromBuffer[i];
|
||||
}
|
||||
systemSaveUpdateCounter = SYSTEM_SAVE_UPDATED;
|
||||
}
|
||||
else if(eepromBits == 0x41)
|
||||
{
|
||||
eepromMode = EEPROM_IDLE;
|
||||
eepromByte = 0;
|
||||
eepromBits = 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,40 +1,38 @@
|
||||
// -*- 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_EEPROM_H
|
||||
#define VBA_EEPROM_H
|
||||
|
||||
extern void eepromSaveGame(gzFile _gzFile);
|
||||
extern void eepromReadGame(gzFile _gzFile, int version);
|
||||
extern void eepromReadGameSkip(gzFile _gzFile, int version);
|
||||
extern int eepromRead(u32 address);
|
||||
extern void eepromWrite(u32 address, u8 value);
|
||||
extern void eepromInit();
|
||||
extern void eepromReset();
|
||||
extern u8 eepromData[0x2000];
|
||||
extern bool eepromInUse;
|
||||
extern int eepromSize;
|
||||
|
||||
#define EEPROM_IDLE 0
|
||||
#define EEPROM_READADDRESS 1
|
||||
#define EEPROM_READDATA 2
|
||||
#define EEPROM_READDATA2 3
|
||||
#define EEPROM_WRITEDATA 4
|
||||
|
||||
#endif // VBA_EEPROM_H
|
||||
// -*- 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_EEPROM_H
|
||||
#define VBA_EEPROM_H
|
||||
|
||||
extern void eepromSaveGame(gzFile gzFile);
|
||||
extern void eepromReadGame(gzFile gzFile, int version);
|
||||
extern int eepromRead(u32 address);
|
||||
extern void eepromWrite(u32 address, u8 value);
|
||||
extern void eepromReset();
|
||||
extern u8 eepromData[0x2000];
|
||||
extern bool eepromInUse;
|
||||
extern int eepromSize;
|
||||
|
||||
#define EEPROM_IDLE 0
|
||||
#define EEPROM_READADDRESS 1
|
||||
#define EEPROM_READDATA 2
|
||||
#define EEPROM_READDATA2 3
|
||||
#define EEPROM_WRITEDATA 4
|
||||
|
||||
#endif // VBA_EEPROM_H
|
||||
|
@ -1,275 +1,288 @@
|
||||
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
|
||||
// Copyright (C) 1999-2003 Forgotten
|
||||
// Copyright (C) 2004-2006 Forgotten and the VBA development team
|
||||
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; either version 2, or(at your option)
|
||||
// any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software Foundation,
|
||||
// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "agb/GBA.h"
|
||||
#include "Globals.h"
|
||||
#include "Flash.h"
|
||||
#include "Sram.h"
|
||||
#include "Util.h"
|
||||
|
||||
#define FLASH_READ_ARRAY 0
|
||||
#define FLASH_CMD_1 1
|
||||
#define FLASH_CMD_2 2
|
||||
#define FLASH_AUTOSELECT 3
|
||||
#define FLASH_CMD_3 4
|
||||
#define FLASH_CMD_4 5
|
||||
#define FLASH_CMD_5 6
|
||||
#define FLASH_ERASE_COMPLETE 7
|
||||
#define FLASH_PROGRAM 8
|
||||
#define FLASH_SETBANK 9
|
||||
|
||||
u8 flashSaveMemory[0x20000];
|
||||
int flashState = FLASH_READ_ARRAY;
|
||||
int flashReadState = FLASH_READ_ARRAY;
|
||||
int flashSize = 0x10000;
|
||||
int flashDeviceID = 0x1b;
|
||||
int flashManufacturerID = 0x32;
|
||||
int flashBank = 0;
|
||||
|
||||
static variable_desc flashSaveData[] = {
|
||||
{ &flashState, sizeof(int) },
|
||||
{ &flashReadState, sizeof(int) },
|
||||
{ &flashSaveMemory[0], 0x10000 },
|
||||
{ NULL, 0 }
|
||||
};
|
||||
|
||||
static variable_desc flashSaveData2[] = {
|
||||
{ &flashState, sizeof(int) },
|
||||
{ &flashReadState, sizeof(int) },
|
||||
{ &flashSize, sizeof(int) },
|
||||
{ &flashSaveMemory[0], 0x20000 },
|
||||
{ NULL, 0 }
|
||||
};
|
||||
|
||||
static variable_desc flashSaveData3[] = {
|
||||
{ &flashState, sizeof(int) },
|
||||
{ &flashReadState, sizeof(int) },
|
||||
{ &flashSize, sizeof(int) },
|
||||
{ &flashBank, sizeof(int) },
|
||||
{ &flashSaveMemory[0], 0x20000 },
|
||||
{ NULL, 0 }
|
||||
};
|
||||
|
||||
void flashInit()
|
||||
{
|
||||
memset(flashSaveMemory, 0xff, sizeof(flashSaveMemory));
|
||||
}
|
||||
|
||||
void flashReset()
|
||||
{
|
||||
flashState = FLASH_READ_ARRAY;
|
||||
flashReadState = FLASH_READ_ARRAY;
|
||||
flashBank = 0;
|
||||
}
|
||||
|
||||
void flashSaveGame(gzFile gzFile)
|
||||
{
|
||||
utilWriteData(gzFile, flashSaveData3);
|
||||
}
|
||||
|
||||
void flashReadGame(gzFile gzFile, int version)
|
||||
{
|
||||
if(version < SAVE_GAME_VERSION_5)
|
||||
utilReadData(gzFile, flashSaveData);
|
||||
else if(version < SAVE_GAME_VERSION_7) {
|
||||
utilReadData(gzFile, flashSaveData2);
|
||||
flashBank = 0;
|
||||
flashSetSize(flashSize);
|
||||
} else {
|
||||
utilReadData(gzFile, flashSaveData3);
|
||||
}
|
||||
}
|
||||
|
||||
void flashReadGameSkip(gzFile gzFile, int version)
|
||||
{
|
||||
// skip the flash data in a save game
|
||||
if(version < SAVE_GAME_VERSION_5)
|
||||
utilReadDataSkip(gzFile, flashSaveData);
|
||||
else if(version < SAVE_GAME_VERSION_7) {
|
||||
utilReadDataSkip(gzFile, flashSaveData2);
|
||||
} else {
|
||||
utilReadDataSkip(gzFile, flashSaveData3);
|
||||
}
|
||||
}
|
||||
|
||||
void flashSetSize(int size)
|
||||
{
|
||||
// log("Setting flash size to %d\n", size);
|
||||
if(size == 0x10000) {
|
||||
flashDeviceID = 0x1b;
|
||||
flashManufacturerID = 0x32;
|
||||
} else {
|
||||
flashDeviceID = 0x13; //0x09;
|
||||
flashManufacturerID = 0x62; //0xc2;
|
||||
}
|
||||
// Added to make 64k saves compatible with 128k ones
|
||||
// (allow wrongfuly set 64k saves to work for Pokemon games)
|
||||
if ((size == 0x20000) && (flashSize == 0x10000))
|
||||
memcpy((u8 *)(flashSaveMemory+0x10000), (u8 *)(flashSaveMemory), 0x10000);
|
||||
flashSize = size;
|
||||
}
|
||||
|
||||
u8 flashRead(u32 address)
|
||||
{
|
||||
// log("Reading %08x from %08x\n", address, reg[15].I);
|
||||
// log("Current read state is %d\n", flashReadState);
|
||||
address &= 0xFFFF;
|
||||
|
||||
switch(flashReadState) {
|
||||
case FLASH_READ_ARRAY:
|
||||
return flashSaveMemory[(flashBank << 16) + address];
|
||||
case FLASH_AUTOSELECT:
|
||||
switch(address & 0xFF) {
|
||||
case 0:
|
||||
// manufacturer ID
|
||||
return flashManufacturerID;
|
||||
case 1:
|
||||
// device ID
|
||||
return flashDeviceID;
|
||||
}
|
||||
break;
|
||||
case FLASH_ERASE_COMPLETE:
|
||||
flashState = FLASH_READ_ARRAY;
|
||||
flashReadState = FLASH_READ_ARRAY;
|
||||
return 0xFF;
|
||||
};
|
||||
return 0;
|
||||
}
|
||||
|
||||
void flashSaveDecide(u32 address, u8 byte)
|
||||
{
|
||||
// log("Deciding save type %08x\n", address);
|
||||
if(address == 0x0e005555) {
|
||||
saveType = 2;
|
||||
cpuSaveGameFunc = flashWrite;
|
||||
} else {
|
||||
saveType = 1;
|
||||
cpuSaveGameFunc = sramWrite;
|
||||
}
|
||||
|
||||
(*cpuSaveGameFunc)(address, byte);
|
||||
}
|
||||
|
||||
void flashDelayedWrite(u32 address, u8 byte)
|
||||
{
|
||||
saveType = 2;
|
||||
cpuSaveGameFunc = flashWrite;
|
||||
flashWrite(address, byte);
|
||||
}
|
||||
|
||||
void flashWrite(u32 address, u8 byte)
|
||||
{
|
||||
// log("Writing %02x at %08x\n", byte, address);
|
||||
// log("Current state is %d\n", flashState);
|
||||
address &= 0xFFFF;
|
||||
switch(flashState) {
|
||||
case FLASH_READ_ARRAY:
|
||||
if(address == 0x5555 && byte == 0xAA)
|
||||
flashState = FLASH_CMD_1;
|
||||
break;
|
||||
case FLASH_CMD_1:
|
||||
if(address == 0x2AAA && byte == 0x55)
|
||||
flashState = FLASH_CMD_2;
|
||||
else
|
||||
flashState = FLASH_READ_ARRAY;
|
||||
break;
|
||||
case FLASH_CMD_2:
|
||||
if(address == 0x5555) {
|
||||
if(byte == 0x90) {
|
||||
flashState = FLASH_AUTOSELECT;
|
||||
flashReadState = FLASH_AUTOSELECT;
|
||||
} else if(byte == 0x80) {
|
||||
flashState = FLASH_CMD_3;
|
||||
} else if(byte == 0xF0) {
|
||||
flashState = FLASH_READ_ARRAY;
|
||||
flashReadState = FLASH_READ_ARRAY;
|
||||
} else if(byte == 0xA0) {
|
||||
flashState = FLASH_PROGRAM;
|
||||
} else if(byte == 0xB0 && flashSize == 0x20000) {
|
||||
flashState = FLASH_SETBANK;
|
||||
} else {
|
||||
flashState = FLASH_READ_ARRAY;
|
||||
flashReadState = FLASH_READ_ARRAY;
|
||||
}
|
||||
} else {
|
||||
flashState = FLASH_READ_ARRAY;
|
||||
flashReadState = FLASH_READ_ARRAY;
|
||||
}
|
||||
break;
|
||||
case FLASH_CMD_3:
|
||||
if(address == 0x5555 && byte == 0xAA) {
|
||||
flashState = FLASH_CMD_4;
|
||||
} else {
|
||||
flashState = FLASH_READ_ARRAY;
|
||||
flashReadState = FLASH_READ_ARRAY;
|
||||
}
|
||||
break;
|
||||
case FLASH_CMD_4:
|
||||
if(address == 0x2AAA && byte == 0x55) {
|
||||
flashState = FLASH_CMD_5;
|
||||
} else {
|
||||
flashState = FLASH_READ_ARRAY;
|
||||
flashReadState = FLASH_READ_ARRAY;
|
||||
}
|
||||
break;
|
||||
case FLASH_CMD_5:
|
||||
if(byte == 0x30) {
|
||||
// SECTOR ERASE
|
||||
memset(&flashSaveMemory[(flashBank << 16) + (address & 0xF000)],
|
||||
0,
|
||||
0x1000);
|
||||
systemSaveUpdateCounter = SYSTEM_SAVE_UPDATED;
|
||||
flashReadState = FLASH_ERASE_COMPLETE;
|
||||
} else if(byte == 0x10) {
|
||||
// CHIP ERASE
|
||||
memset(flashSaveMemory, 0, flashSize);
|
||||
systemSaveUpdateCounter = SYSTEM_SAVE_UPDATED;
|
||||
flashReadState = FLASH_ERASE_COMPLETE;
|
||||
} else {
|
||||
flashState = FLASH_READ_ARRAY;
|
||||
flashReadState = FLASH_READ_ARRAY;
|
||||
}
|
||||
break;
|
||||
case FLASH_AUTOSELECT:
|
||||
if(byte == 0xF0) {
|
||||
flashState = FLASH_READ_ARRAY;
|
||||
flashReadState = FLASH_READ_ARRAY;
|
||||
} else if(address == 0x5555 && byte == 0xAA)
|
||||
flashState = FLASH_CMD_1;
|
||||
else {
|
||||
flashState = FLASH_READ_ARRAY;
|
||||
flashReadState = FLASH_READ_ARRAY;
|
||||
}
|
||||
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;
|
||||
}
|
||||
}
|
||||
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
|
||||
// Copyright (C) 1999-2003 Forgotten
|
||||
// Copyright (C) 2004 Forgotten and the VBA development team
|
||||
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; either version 2, or(at your option)
|
||||
// any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software Foundation,
|
||||
// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "GBA.h"
|
||||
#include "Globals.h"
|
||||
#include "Flash.h"
|
||||
#include "Sram.h"
|
||||
#include "Util.h"
|
||||
|
||||
#define FLASH_READ_ARRAY 0
|
||||
#define FLASH_CMD_1 1
|
||||
#define FLASH_CMD_2 2
|
||||
#define FLASH_AUTOSELECT 3
|
||||
#define FLASH_CMD_3 4
|
||||
#define FLASH_CMD_4 5
|
||||
#define FLASH_CMD_5 6
|
||||
#define FLASH_ERASE_COMPLETE 7
|
||||
#define FLASH_PROGRAM 8
|
||||
#define FLASH_SETBANK 9
|
||||
|
||||
u8 flashSaveMemory[0x20000];
|
||||
int flashState = FLASH_READ_ARRAY;
|
||||
int flashReadState = FLASH_READ_ARRAY;
|
||||
int flashSize = 0x10000;
|
||||
int flashDeviceID = 0x1b;
|
||||
int flashManufacturerID = 0x32;
|
||||
int flashBank = 0;
|
||||
|
||||
static variable_desc flashSaveData[] = {
|
||||
{ &flashState, sizeof(int) },
|
||||
{ &flashReadState, sizeof(int) },
|
||||
{ &flashSaveMemory[0], 0x10000 },
|
||||
{ NULL, 0 }
|
||||
};
|
||||
|
||||
static variable_desc flashSaveData2[] = {
|
||||
{ &flashState, sizeof(int) },
|
||||
{ &flashReadState, sizeof(int) },
|
||||
{ &flashSize, sizeof(int) },
|
||||
{ &flashSaveMemory[0], 0x20000 },
|
||||
{ NULL, 0 }
|
||||
};
|
||||
|
||||
static variable_desc flashSaveData3[] = {
|
||||
{ &flashState, sizeof(int) },
|
||||
{ &flashReadState, sizeof(int) },
|
||||
{ &flashSize, sizeof(int) },
|
||||
{ &flashBank, sizeof(int) },
|
||||
{ &flashSaveMemory[0], 0x20000 },
|
||||
{ NULL, 0 }
|
||||
};
|
||||
|
||||
void flashReset()
|
||||
{
|
||||
flashState = FLASH_READ_ARRAY;
|
||||
flashReadState = FLASH_READ_ARRAY;
|
||||
flashBank = 0;
|
||||
}
|
||||
|
||||
void flashSaveGame(gzFile gzFile)
|
||||
{
|
||||
utilWriteData(gzFile, flashSaveData3);
|
||||
}
|
||||
|
||||
void flashReadGame(gzFile gzFile, int version)
|
||||
{
|
||||
if(version < SAVE_GAME_VERSION_5)
|
||||
utilReadData(gzFile, flashSaveData);
|
||||
else if(version < SAVE_GAME_VERSION_7)
|
||||
{
|
||||
utilReadData(gzFile, flashSaveData2);
|
||||
flashBank = 0;
|
||||
flashSetSize(flashSize);
|
||||
}
|
||||
else
|
||||
{
|
||||
utilReadData(gzFile, flashSaveData3);
|
||||
}
|
||||
}
|
||||
|
||||
void flashSetSize(int size)
|
||||
{
|
||||
// log("Setting flash size to %d\n", size);
|
||||
flashSize = size;
|
||||
if(size == 0x10000)
|
||||
{
|
||||
flashDeviceID = 0x1b;
|
||||
flashManufacturerID = 0x32;
|
||||
}
|
||||
else
|
||||
{
|
||||
flashDeviceID = 0x13; //0x09;
|
||||
flashManufacturerID = 0x62; //0xc2;
|
||||
}
|
||||
}
|
||||
|
||||
u8 flashRead(u32 address)
|
||||
{
|
||||
// log("Reading %08x from %08x\n", address, reg[15].I);
|
||||
// log("Current read state is %d\n", flashReadState);
|
||||
address &= 0xFFFF;
|
||||
|
||||
switch(flashReadState)
|
||||
{
|
||||
case FLASH_READ_ARRAY:
|
||||
return flashSaveMemory[(flashBank << 16) + address];
|
||||
case FLASH_AUTOSELECT:
|
||||
switch(address & 0xFF)
|
||||
{
|
||||
case 0:
|
||||
// manufacturer ID
|
||||
return flashManufacturerID;
|
||||
case 1:
|
||||
// device ID
|
||||
return flashDeviceID;
|
||||
}
|
||||
break;
|
||||
case FLASH_ERASE_COMPLETE:
|
||||
flashState = FLASH_READ_ARRAY;
|
||||
flashReadState = FLASH_READ_ARRAY;
|
||||
return 0xFF;
|
||||
};
|
||||
return 0;
|
||||
}
|
||||
|
||||
void flashSaveDecide(u32 address, u8 byte)
|
||||
{
|
||||
// log("Deciding save type %08x\n", address);
|
||||
if(address == 0x0e005555)
|
||||
{
|
||||
saveType = 2;
|
||||
cpuSaveGameFunc = flashWrite;
|
||||
}
|
||||
else
|
||||
{
|
||||
saveType = 1;
|
||||
cpuSaveGameFunc = sramWrite;
|
||||
}
|
||||
|
||||
(*cpuSaveGameFunc)(address, byte);
|
||||
}
|
||||
|
||||
void flashWrite(u32 address, u8 byte)
|
||||
{
|
||||
// log("Writing %02x at %08x\n", byte, address);
|
||||
// log("Current state is %d\n", flashState);
|
||||
address &= 0xFFFF;
|
||||
switch(flashState)
|
||||
{
|
||||
case FLASH_READ_ARRAY:
|
||||
if(address == 0x5555 && byte == 0xAA)
|
||||
flashState = FLASH_CMD_1;
|
||||
break;
|
||||
case FLASH_CMD_1:
|
||||
if(address == 0x2AAA && byte == 0x55)
|
||||
flashState = FLASH_CMD_2;
|
||||
else
|
||||
flashState = FLASH_READ_ARRAY;
|
||||
break;
|
||||
case FLASH_CMD_2:
|
||||
if(address == 0x5555)
|
||||
{
|
||||
if(byte == 0x90)
|
||||
{
|
||||
flashState = FLASH_AUTOSELECT;
|
||||
flashReadState = FLASH_AUTOSELECT;
|
||||
}
|
||||
else if(byte == 0x80)
|
||||
{
|
||||
flashState = FLASH_CMD_3;
|
||||
}
|
||||
else if(byte == 0xF0)
|
||||
{
|
||||
flashState = FLASH_READ_ARRAY;
|
||||
flashReadState = FLASH_READ_ARRAY;
|
||||
}
|
||||
else if(byte == 0xA0)
|
||||
{
|
||||
flashState = FLASH_PROGRAM;
|
||||
}
|
||||
else if(byte == 0xB0 && flashSize == 0x20000)
|
||||
{
|
||||
flashState = FLASH_SETBANK;
|
||||
}
|
||||
else
|
||||
{
|
||||
flashState = FLASH_READ_ARRAY;
|
||||
flashReadState = FLASH_READ_ARRAY;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
flashState = FLASH_READ_ARRAY;
|
||||
flashReadState = FLASH_READ_ARRAY;
|
||||
}
|
||||
break;
|
||||
case FLASH_CMD_3:
|
||||
if(address == 0x5555 && byte == 0xAA)
|
||||
{
|
||||
flashState = FLASH_CMD_4;
|
||||
}
|
||||
else
|
||||
{
|
||||
flashState = FLASH_READ_ARRAY;
|
||||
flashReadState = FLASH_READ_ARRAY;
|
||||
}
|
||||
break;
|
||||
case FLASH_CMD_4:
|
||||
if(address == 0x2AAA && byte == 0x55)
|
||||
{
|
||||
flashState = FLASH_CMD_5;
|
||||
}
|
||||
else
|
||||
{
|
||||
flashState = FLASH_READ_ARRAY;
|
||||
flashReadState = FLASH_READ_ARRAY;
|
||||
}
|
||||
break;
|
||||
case FLASH_CMD_5:
|
||||
if(byte == 0x30)
|
||||
{
|
||||
// SECTOR ERASE
|
||||
memset(&flashSaveMemory[(flashBank << 16) + (address & 0xF000)],
|
||||
0,
|
||||
0x1000);
|
||||
systemSaveUpdateCounter = SYSTEM_SAVE_UPDATED;
|
||||
flashReadState = FLASH_ERASE_COMPLETE;
|
||||
}
|
||||
else if(byte == 0x10)
|
||||
{
|
||||
// CHIP ERASE
|
||||
memset(flashSaveMemory, 0, flashSize);
|
||||
systemSaveUpdateCounter = SYSTEM_SAVE_UPDATED;
|
||||
flashReadState = FLASH_ERASE_COMPLETE;
|
||||
}
|
||||
else
|
||||
{
|
||||
flashState = FLASH_READ_ARRAY;
|
||||
flashReadState = FLASH_READ_ARRAY;
|
||||
}
|
||||
break;
|
||||
case FLASH_AUTOSELECT:
|
||||
if(byte == 0xF0)
|
||||
{
|
||||
flashState = FLASH_READ_ARRAY;
|
||||
flashReadState = FLASH_READ_ARRAY;
|
||||
}
|
||||
else if(address == 0x5555 && byte == 0xAA)
|
||||
flashState = FLASH_CMD_1;
|
||||
else
|
||||
{
|
||||
flashState = FLASH_READ_ARRAY;
|
||||
flashReadState = FLASH_READ_ARRAY;
|
||||
}
|
||||
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++ -*-
|
||||
// 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_FLASH_H
|
||||
#define VBA_FLASH_H
|
||||
|
||||
extern void flashSaveGame(gzFile _gzFile);
|
||||
extern void flashReadGame(gzFile _gzFile, int version);
|
||||
extern void flashReadGameSkip(gzFile _gzFile, int version);
|
||||
extern u8 flashRead(u32 address);
|
||||
extern void flashWrite(u32 address, u8 byte);
|
||||
extern void flashDelayedWrite(u32 address, u8 byte);
|
||||
extern u8 flashSaveMemory[0x20000];
|
||||
extern void flashSaveDecide(u32 address, u8 byte);
|
||||
extern void flashReset();
|
||||
extern void flashSetSize(int size);
|
||||
extern void flashInit();
|
||||
|
||||
extern int flashSize;
|
||||
#endif // VBA_FLASH_H
|
||||
// -*- 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_FLASH_H
|
||||
#define VBA_FLASH_H
|
||||
|
||||
extern void flashSaveGame(gzFile gzFile);
|
||||
extern void flashReadGame(gzFile gzFile, int version);
|
||||
extern u8 flashRead(u32 address);
|
||||
extern void flashWrite(u32 address, u8 byte);
|
||||
extern u8 flashSaveMemory[0x20000];
|
||||
extern void flashSaveDecide(u32 address, u8 byte);
|
||||
extern void flashReset();
|
||||
extern void flashSetSize(int size);
|
||||
|
||||
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++ -*-
|
||||
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
|
||||
// Copyright (C) 1999-2003 Forgotten
|
||||
// Copyright (C) 2005 Forgotten and the VBA development team
|
||||
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; either version 2, or(at your option)
|
||||
// any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software Foundation,
|
||||
// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
#ifndef VBA_GBA_H
|
||||
#define VBA_GBA_H
|
||||
|
||||
#include "../System.h"
|
||||
|
||||
#define SAVE_GAME_VERSION_1 1
|
||||
#define SAVE_GAME_VERSION_2 2
|
||||
#define SAVE_GAME_VERSION_3 3
|
||||
#define SAVE_GAME_VERSION_4 4
|
||||
#define SAVE_GAME_VERSION_5 5
|
||||
#define SAVE_GAME_VERSION_6 6
|
||||
#define SAVE_GAME_VERSION_7 7
|
||||
#define SAVE_GAME_VERSION_8 8
|
||||
#define SAVE_GAME_VERSION_9 9
|
||||
#define SAVE_GAME_VERSION_10 10
|
||||
#define SAVE_GAME_VERSION SAVE_GAME_VERSION_10
|
||||
|
||||
typedef struct {
|
||||
u8 *address;
|
||||
u32 mask;
|
||||
} memoryMap;
|
||||
|
||||
typedef union {
|
||||
struct {
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
u8 B3;
|
||||
u8 B2;
|
||||
u8 B1;
|
||||
u8 B0;
|
||||
#else
|
||||
u8 B0;
|
||||
u8 B1;
|
||||
u8 B2;
|
||||
u8 B3;
|
||||
#endif
|
||||
} B;
|
||||
struct {
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
u16 W1;
|
||||
u16 W0;
|
||||
#else
|
||||
u16 W0;
|
||||
u16 W1;
|
||||
#endif
|
||||
} W;
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
volatile u32 I;
|
||||
#else
|
||||
u32 I;
|
||||
#endif
|
||||
} reg_pair;
|
||||
|
||||
#ifndef NO_GBA_MAP
|
||||
extern memoryMap map[256];
|
||||
#endif
|
||||
|
||||
extern reg_pair reg[45];
|
||||
extern u8 biosProtected[4];
|
||||
|
||||
extern bool N_FLAG;
|
||||
extern bool Z_FLAG;
|
||||
extern bool C_FLAG;
|
||||
extern bool V_FLAG;
|
||||
extern bool armIrqEnable;
|
||||
extern bool armState;
|
||||
extern int armMode;
|
||||
extern void (*cpuSaveGameFunc)(u32,u8);
|
||||
|
||||
#ifdef BKPT_SUPPORT
|
||||
extern u8 freezeWorkRAM[0x40000];
|
||||
extern u8 freezeInternalRAM[0x8000];
|
||||
extern u8 freezeVRAM[0x18000];
|
||||
extern u8 freezeOAM[0x400];
|
||||
extern u8 freezePRAM[0x400];
|
||||
extern bool debugger_last;
|
||||
extern int oldreg[17];
|
||||
extern char oldbuffer[10];
|
||||
#endif
|
||||
|
||||
extern bool CPUReadGSASnapshot(const char *);
|
||||
extern bool CPUWriteGSASnapshot(const char *, const char *, const char *, const char *);
|
||||
extern bool CPUWriteBatteryFile(const char *);
|
||||
extern bool CPUReadBatteryFile(const char *);
|
||||
extern bool CPUExportEepromFile(const char *);
|
||||
extern bool CPUImportEepromFile(const char *);
|
||||
extern bool CPUWritePNGFile(const char *);
|
||||
extern bool CPUWriteBMPFile(const char *);
|
||||
extern void CPUCleanUp();
|
||||
extern void CPUUpdateRender();
|
||||
extern void CPUUpdateRenderBuffers(bool);
|
||||
extern bool CPUReadMemState(char *, int);
|
||||
extern bool CPUReadState(const char *);
|
||||
extern bool CPUWriteMemState(char *, int);
|
||||
extern bool CPUWriteState(const char *);
|
||||
extern int CPULoadRom(const char *);
|
||||
extern void doMirroring(bool);
|
||||
extern void CPUUpdateRegister(u32, u16);
|
||||
extern void applyTimer ();
|
||||
extern void CPUInit(const char *,bool);
|
||||
extern void CPUReset();
|
||||
extern void CPULoop(int);
|
||||
extern void CPUCheckDMA(int,int);
|
||||
extern bool CPUIsGBAImage(const char *);
|
||||
extern bool CPUIsZipFile(const char *);
|
||||
#ifdef PROFILING
|
||||
#include "prof/prof.h"
|
||||
extern void cpuProfil(profile_segment *seg);
|
||||
extern void cpuEnableProfiling(int hz);
|
||||
#endif
|
||||
|
||||
extern struct EmulatedSystem GBASystem;
|
||||
|
||||
#define R13_IRQ 18
|
||||
#define R14_IRQ 19
|
||||
#define SPSR_IRQ 20
|
||||
#define R13_USR 26
|
||||
#define R14_USR 27
|
||||
#define R13_SVC 28
|
||||
#define R14_SVC 29
|
||||
#define SPSR_SVC 30
|
||||
#define R13_ABT 31
|
||||
#define R14_ABT 32
|
||||
#define SPSR_ABT 33
|
||||
#define R13_UND 34
|
||||
#define R14_UND 35
|
||||
#define SPSR_UND 36
|
||||
#define R8_FIQ 37
|
||||
#define R9_FIQ 38
|
||||
#define R10_FIQ 39
|
||||
#define R11_FIQ 40
|
||||
#define R12_FIQ 41
|
||||
#define R13_FIQ 42
|
||||
#define R14_FIQ 43
|
||||
#define SPSR_FIQ 44
|
||||
|
||||
#include "../Cheats.h"
|
||||
#include "../Globals.h"
|
||||
#include "../EEprom.h"
|
||||
#include "../Flash.h"
|
||||
|
||||
#endif //VBA_GBA_H
|
||||
// -*- C++ -*-
|
||||
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
|
||||
// Copyright (C) 1999-2003 Forgotten
|
||||
// Copyright (C) 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_GBA_H
|
||||
#define VBA_GBA_H
|
||||
|
||||
#include "System.h"
|
||||
|
||||
#define SAVE_GAME_VERSION_1 1
|
||||
#define SAVE_GAME_VERSION_2 2
|
||||
#define SAVE_GAME_VERSION_3 3
|
||||
#define SAVE_GAME_VERSION_4 4
|
||||
#define SAVE_GAME_VERSION_5 5
|
||||
#define SAVE_GAME_VERSION_6 6
|
||||
#define SAVE_GAME_VERSION_7 7
|
||||
#define SAVE_GAME_VERSION_8 8
|
||||
#define SAVE_GAME_VERSION SAVE_GAME_VERSION_8
|
||||
|
||||
typedef struct
|
||||
{
|
||||
u8 *address;
|
||||
u32 mask;
|
||||
}
|
||||
memoryMap;
|
||||
|
||||
typedef union {
|
||||
struct
|
||||
{
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
u8 B3;
|
||||
u8 B2;
|
||||
u8 B1;
|
||||
u8 B0;
|
||||
#else
|
||||
u8 B0;
|
||||
u8 B1;
|
||||
u8 B2;
|
||||
u8 B3;
|
||||
#endif
|
||||
}
|
||||
B;
|
||||
struct
|
||||
{
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
u16 W1;
|
||||
u16 W0;
|
||||
#else
|
||||
u16 W0;
|
||||
u16 W1;
|
||||
#endif
|
||||
}
|
||||
W;
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
volatile u32 I;
|
||||
#else
|
||||
u32 I;
|
||||
#endif
|
||||
} reg_pair;
|
||||
|
||||
#ifndef NO_GBA_MAP
|
||||
extern memoryMap map[256];
|
||||
#endif
|
||||
|
||||
extern reg_pair reg[45];
|
||||
extern u8 biosProtected[4];
|
||||
|
||||
extern bool N_FLAG;
|
||||
extern bool Z_FLAG;
|
||||
extern bool C_FLAG;
|
||||
extern bool V_FLAG;
|
||||
extern bool armIrqEnable;
|
||||
extern bool armState;
|
||||
extern int armMode;
|
||||
extern void (*cpuSaveGameFunc)(u32,u8);
|
||||
|
||||
extern bool freezeWorkRAM[0x40000];
|
||||
extern bool freezeInternalRAM[0x8000];
|
||||
extern bool CPUReadGSASnapshot(const char *);
|
||||
extern bool CPUWriteGSASnapshot(const char *, const char *, const char *, const char *);
|
||||
extern bool CPUWriteBatteryFile(const char *);
|
||||
extern bool CPUReadBatteryFile(const char *);
|
||||
extern bool CPUExportEepromFile(const char *);
|
||||
extern bool CPUImportEepromFile(const char *);
|
||||
extern bool CPUWritePNGFile(const char *);
|
||||
extern bool CPUWriteBMPFile(const char *);
|
||||
extern void CPUCleanUp();
|
||||
extern void CPUUpdateRender();
|
||||
extern bool CPUReadMemState(char *, int);
|
||||
extern bool CPUReadState(const char *);
|
||||
extern bool CPUWriteMemState(char *, int);
|
||||
extern bool CPUWriteState(const char *);
|
||||
extern int CPULoadRom(const char *);
|
||||
extern void CPUUpdateRegister(u32, u16);
|
||||
extern void CPUWriteHalfWord(u32, u16);
|
||||
extern void CPUWriteByte(u32, u8);
|
||||
extern void CPUInit(const char *,bool);
|
||||
extern void CPUReset();
|
||||
extern void CPULoop(int);
|
||||
extern void CPUCheckDMA(int,int);
|
||||
extern bool CPUIsGBAImage(const char *);
|
||||
extern bool CPUIsZipFile(const char *);
|
||||
#ifdef PROFILING
|
||||
extern void cpuProfil(char *buffer, int, u32, int);
|
||||
extern void cpuEnableProfiling(int hz);
|
||||
#endif
|
||||
|
||||
extern struct EmulatedSystem GBASystem;
|
||||
|
||||
#define R13_IRQ 18
|
||||
#define R14_IRQ 19
|
||||
#define SPSR_IRQ 20
|
||||
#define R13_USR 26
|
||||
#define R14_USR 27
|
||||
#define R13_SVC 28
|
||||
#define R14_SVC 29
|
||||
#define SPSR_SVC 30
|
||||
#define R13_ABT 31
|
||||
#define R14_ABT 32
|
||||
#define SPSR_ABT 33
|
||||
#define R13_UND 34
|
||||
#define R14_UND 35
|
||||
#define SPSR_UND 36
|
||||
#define R8_FIQ 37
|
||||
#define R9_FIQ 38
|
||||
#define R10_FIQ 39
|
||||
#define R11_FIQ 40
|
||||
#define R12_FIQ 41
|
||||
#define R13_FIQ 42
|
||||
#define R14_FIQ 43
|
||||
#define SPSR_FIQ 44
|
||||
|
||||
#include "Cheats.h"
|
||||
#include "Globals.h"
|
||||
#include "EEprom.h"
|
||||
#include "Flash.h"
|
||||
|
||||
#endif //VBA_GBA_H
|
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.
|
||||
// Copyright (C) 1999-2003 Forgotten
|
||||
// Copyright (C) 2004 Forgotten and the VBA development team
|
||||
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; either version 2, or(at your option)
|
||||
// any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software Foundation,
|
||||
// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
#include "../System.h"
|
||||
|
||||
int coeff[32] = {
|
||||
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
|
||||
16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16};
|
||||
|
||||
u32 line0[240];
|
||||
u32 line1[240];
|
||||
u32 line2[240];
|
||||
u32 line3[240];
|
||||
u32 lineOBJ[240];
|
||||
u32 lineOBJWin[240];
|
||||
u32 lineMix[240];
|
||||
bool gfxInWin0[240];
|
||||
bool gfxInWin1[240];
|
||||
int lineOBJpixleft[128];
|
||||
|
||||
int gfxBG2Changed = 0;
|
||||
int gfxBG3Changed = 0;
|
||||
|
||||
int gfxBG2X = 0;
|
||||
int gfxBG2Y = 0;
|
||||
int gfxBG2LastX = 0;
|
||||
int gfxBG2LastY = 0;
|
||||
int gfxBG3X = 0;
|
||||
int gfxBG3Y = 0;
|
||||
int gfxBG3LastX = 0;
|
||||
int gfxBG3LastY = 0;
|
||||
int gfxLastVCOUNT = 0;
|
||||
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
|
||||
// Copyright (C) 1999-2003 Forgotten
|
||||
// Copyright (C) 2004 Forgotten and the VBA development team
|
||||
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; either version 2, or(at your option)
|
||||
// any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software Foundation,
|
||||
// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
#include "System.h"
|
||||
|
||||
int coeff[32] = {
|
||||
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
|
||||
16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16};
|
||||
|
||||
|
||||
u32 line0[240];
|
||||
u32 line1[240];
|
||||
u32 line2[240];
|
||||
u32 line3[240];
|
||||
u32 lineOBJ[240];
|
||||
u32 lineOBJWin[240];
|
||||
u32 lineMix[240];
|
||||
bool gfxInWin0[240];
|
||||
bool gfxInWin1[240];
|
||||
|
||||
int gfxBG2Changed = 0;
|
||||
int gfxBG3Changed = 0;
|
||||
|
||||
int gfxBG2X = 0;
|
||||
int gfxBG2Y = 0;
|
||||
int gfxBG2LastX = 0;
|
||||
int gfxBG2LastY = 0;
|
||||
int gfxBG3X = 0;
|
||||
int gfxBG3Y = 0;
|
||||
int gfxBG3LastX = 0;
|
||||
int gfxBG3LastY = 0;
|
||||
int gfxLastVCOUNT = 0;
|
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.
|
||||
// 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
|
||||
// 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,
|
||||
// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
#include "agb/GBA.h"
|
||||
|
||||
#ifdef BKPT_SUPPORT
|
||||
int oldreg[17];
|
||||
char oldbuffer[10];
|
||||
#endif
|
||||
#include "GBA.h"
|
||||
|
||||
reg_pair reg[45];
|
||||
memoryMap map[256];
|
||||
@ -43,14 +38,13 @@ bool speedup = false;
|
||||
bool synchronize = true;
|
||||
bool cpuDisableSfx = false;
|
||||
bool cpuIsMultiBoot = false;
|
||||
bool parseDebug = true;
|
||||
bool parseDebug = false;
|
||||
int layerSettings = 0xff00;
|
||||
int layerEnable = 0xff00;
|
||||
bool speedHack = false;
|
||||
int cpuSaveType = 0;
|
||||
bool cheatsEnabled = true;
|
||||
bool mirroringEnable = false;
|
||||
bool skipSaveGameBattery = false;
|
||||
bool cpuEnhancedDetection = true;
|
||||
bool cheatsEnabled = false;
|
||||
|
||||
u8 *bios = NULL;
|
||||
u8 *rom = NULL;
|
||||
|
@ -1,153 +1,149 @@
|
||||
// -*- 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_GLOBALS_H
|
||||
#define VBA_GLOBALS_H
|
||||
|
||||
#include "agb/GBA.h"
|
||||
|
||||
#define VERBOSE_SWI 1
|
||||
#define VERBOSE_UNALIGNED_MEMORY 2
|
||||
#define VERBOSE_ILLEGAL_WRITE 4
|
||||
#define VERBOSE_ILLEGAL_READ 8
|
||||
#define VERBOSE_DMA0 16
|
||||
#define VERBOSE_DMA1 32
|
||||
#define VERBOSE_DMA2 64
|
||||
#define VERBOSE_DMA3 128
|
||||
#define VERBOSE_UNDEFINED 256
|
||||
#define VERBOSE_AGBPRINT 512
|
||||
#define VERBOSE_SOUNDOUTPUT 1024
|
||||
|
||||
extern reg_pair reg[45];
|
||||
extern bool ioReadable[0x400];
|
||||
extern bool N_FLAG;
|
||||
extern bool C_FLAG;
|
||||
extern bool Z_FLAG;
|
||||
extern bool V_FLAG;
|
||||
extern bool armState;
|
||||
extern bool armIrqEnable;
|
||||
extern u32 armNextPC;
|
||||
extern int armMode;
|
||||
extern u32 stop;
|
||||
extern int saveType;
|
||||
extern bool useBios;
|
||||
extern bool skipBios;
|
||||
extern int frameSkip;
|
||||
extern bool speedup;
|
||||
extern bool synchronize;
|
||||
extern bool cpuDisableSfx;
|
||||
extern bool cpuIsMultiBoot;
|
||||
extern bool parseDebug;
|
||||
extern int layerSettings;
|
||||
extern int layerEnable;
|
||||
extern bool speedHack;
|
||||
extern int cpuSaveType;
|
||||
extern bool cheatsEnabled;
|
||||
extern bool mirroringEnable;
|
||||
extern bool skipSaveGameBattery;
|
||||
|
||||
extern u8 *bios;
|
||||
extern u8 *rom;
|
||||
extern u8 *internalRAM;
|
||||
extern u8 *workRAM;
|
||||
extern u8 *paletteRAM;
|
||||
extern u8 *vram;
|
||||
extern u8 *pix;
|
||||
extern u8 *oam;
|
||||
extern u8 *ioMem;
|
||||
|
||||
extern u16 DISPCNT;
|
||||
extern u16 DISPSTAT;
|
||||
extern u16 VCOUNT;
|
||||
extern u16 BG0CNT;
|
||||
extern u16 BG1CNT;
|
||||
extern u16 BG2CNT;
|
||||
extern u16 BG3CNT;
|
||||
extern u16 BG0HOFS;
|
||||
extern u16 BG0VOFS;
|
||||
extern u16 BG1HOFS;
|
||||
extern u16 BG1VOFS;
|
||||
extern u16 BG2HOFS;
|
||||
extern u16 BG2VOFS;
|
||||
extern u16 BG3HOFS;
|
||||
extern u16 BG3VOFS;
|
||||
extern u16 BG2PA;
|
||||
extern u16 BG2PB;
|
||||
extern u16 BG2PC;
|
||||
extern u16 BG2PD;
|
||||
extern u16 BG2X_L;
|
||||
extern u16 BG2X_H;
|
||||
extern u16 BG2Y_L;
|
||||
extern u16 BG2Y_H;
|
||||
extern u16 BG3PA;
|
||||
extern u16 BG3PB;
|
||||
extern u16 BG3PC;
|
||||
extern u16 BG3PD;
|
||||
extern u16 BG3X_L;
|
||||
extern u16 BG3X_H;
|
||||
extern u16 BG3Y_L;
|
||||
extern u16 BG3Y_H;
|
||||
extern u16 WIN0H;
|
||||
extern u16 WIN1H;
|
||||
extern u16 WIN0V;
|
||||
extern u16 WIN1V;
|
||||
extern u16 WININ;
|
||||
extern u16 WINOUT;
|
||||
extern u16 MOSAIC;
|
||||
extern u16 BLDMOD;
|
||||
extern u16 COLEV;
|
||||
extern u16 COLY;
|
||||
extern u16 DM0SAD_L;
|
||||
extern u16 DM0SAD_H;
|
||||
extern u16 DM0DAD_L;
|
||||
extern u16 DM0DAD_H;
|
||||
extern u16 DM0CNT_L;
|
||||
extern u16 DM0CNT_H;
|
||||
extern u16 DM1SAD_L;
|
||||
extern u16 DM1SAD_H;
|
||||
extern u16 DM1DAD_L;
|
||||
extern u16 DM1DAD_H;
|
||||
extern u16 DM1CNT_L;
|
||||
extern u16 DM1CNT_H;
|
||||
extern u16 DM2SAD_L;
|
||||
extern u16 DM2SAD_H;
|
||||
extern u16 DM2DAD_L;
|
||||
extern u16 DM2DAD_H;
|
||||
extern u16 DM2CNT_L;
|
||||
extern u16 DM2CNT_H;
|
||||
extern u16 DM3SAD_L;
|
||||
extern u16 DM3SAD_H;
|
||||
extern u16 DM3DAD_L;
|
||||
extern u16 DM3DAD_H;
|
||||
extern u16 DM3CNT_L;
|
||||
extern u16 DM3CNT_H;
|
||||
extern u16 TM0D;
|
||||
extern u16 TM0CNT;
|
||||
extern u16 TM1D;
|
||||
extern u16 TM1CNT;
|
||||
extern u16 TM2D;
|
||||
extern u16 TM2CNT;
|
||||
extern u16 TM3D;
|
||||
extern u16 TM3CNT;
|
||||
extern u16 P1;
|
||||
extern u16 IE;
|
||||
extern u16 IF;
|
||||
extern u16 IME;
|
||||
|
||||
#endif // VBA_GLOBALS_H
|
||||
// -*- 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_GLOBALS_H
|
||||
#define VBA_GLOBALS_H
|
||||
|
||||
#define VERBOSE_SWI 1
|
||||
#define VERBOSE_UNALIGNED_MEMORY 2
|
||||
#define VERBOSE_ILLEGAL_WRITE 4
|
||||
#define VERBOSE_ILLEGAL_READ 8
|
||||
#define VERBOSE_DMA0 16
|
||||
#define VERBOSE_DMA1 32
|
||||
#define VERBOSE_DMA2 64
|
||||
#define VERBOSE_DMA3 128
|
||||
#define VERBOSE_UNDEFINED 256
|
||||
#define VERBOSE_AGBPRINT 512
|
||||
|
||||
extern reg_pair reg[45];
|
||||
extern bool ioReadable[0x400];
|
||||
extern bool N_FLAG;
|
||||
extern bool C_FLAG;
|
||||
extern bool Z_FLAG;
|
||||
extern bool V_FLAG;
|
||||
extern bool armState;
|
||||
extern bool armIrqEnable;
|
||||
extern u32 armNextPC;
|
||||
extern int armMode;
|
||||
extern u32 stop;
|
||||
extern int saveType;
|
||||
extern bool useBios;
|
||||
extern bool skipBios;
|
||||
extern int frameSkip;
|
||||
extern bool speedup;
|
||||
extern bool synchronize;
|
||||
extern bool cpuDisableSfx;
|
||||
extern bool cpuIsMultiBoot;
|
||||
extern bool parseDebug;
|
||||
extern int layerSettings;
|
||||
extern int layerEnable;
|
||||
extern bool speedHack;
|
||||
extern int cpuSaveType;
|
||||
extern bool cpuEnhancedDetection;
|
||||
extern bool cheatsEnabled;
|
||||
|
||||
extern u8 *bios;
|
||||
extern u8 *rom;
|
||||
extern u8 *internalRAM;
|
||||
extern u8 *workRAM;
|
||||
extern u8 *paletteRAM;
|
||||
extern u8 *vram;
|
||||
extern u8 *pix;
|
||||
extern u8 *oam;
|
||||
extern u8 *ioMem;
|
||||
|
||||
extern u16 DISPCNT;
|
||||
extern u16 DISPSTAT;
|
||||
extern u16 VCOUNT;
|
||||
extern u16 BG0CNT;
|
||||
extern u16 BG1CNT;
|
||||
extern u16 BG2CNT;
|
||||
extern u16 BG3CNT;
|
||||
extern u16 BG0HOFS;
|
||||
extern u16 BG0VOFS;
|
||||
extern u16 BG1HOFS;
|
||||
extern u16 BG1VOFS;
|
||||
extern u16 BG2HOFS;
|
||||
extern u16 BG2VOFS;
|
||||
extern u16 BG3HOFS;
|
||||
extern u16 BG3VOFS;
|
||||
extern u16 BG2PA;
|
||||
extern u16 BG2PB;
|
||||
extern u16 BG2PC;
|
||||
extern u16 BG2PD;
|
||||
extern u16 BG2X_L;
|
||||
extern u16 BG2X_H;
|
||||
extern u16 BG2Y_L;
|
||||
extern u16 BG2Y_H;
|
||||
extern u16 BG3PA;
|
||||
extern u16 BG3PB;
|
||||
extern u16 BG3PC;
|
||||
extern u16 BG3PD;
|
||||
extern u16 BG3X_L;
|
||||
extern u16 BG3X_H;
|
||||
extern u16 BG3Y_L;
|
||||
extern u16 BG3Y_H;
|
||||
extern u16 WIN0H;
|
||||
extern u16 WIN1H;
|
||||
extern u16 WIN0V;
|
||||
extern u16 WIN1V;
|
||||
extern u16 WININ;
|
||||
extern u16 WINOUT;
|
||||
extern u16 MOSAIC;
|
||||
extern u16 BLDMOD;
|
||||
extern u16 COLEV;
|
||||
extern u16 COLY;
|
||||
extern u16 DM0SAD_L;
|
||||
extern u16 DM0SAD_H;
|
||||
extern u16 DM0DAD_L;
|
||||
extern u16 DM0DAD_H;
|
||||
extern u16 DM0CNT_L;
|
||||
extern u16 DM0CNT_H;
|
||||
extern u16 DM1SAD_L;
|
||||
extern u16 DM1SAD_H;
|
||||
extern u16 DM1DAD_L;
|
||||
extern u16 DM1DAD_H;
|
||||
extern u16 DM1CNT_L;
|
||||
extern u16 DM1CNT_H;
|
||||
extern u16 DM2SAD_L;
|
||||
extern u16 DM2SAD_H;
|
||||
extern u16 DM2DAD_L;
|
||||
extern u16 DM2DAD_H;
|
||||
extern u16 DM2CNT_L;
|
||||
extern u16 DM2CNT_H;
|
||||
extern u16 DM3SAD_L;
|
||||
extern u16 DM3SAD_H;
|
||||
extern u16 DM3DAD_L;
|
||||
extern u16 DM3DAD_H;
|
||||
extern u16 DM3CNT_L;
|
||||
extern u16 DM3CNT_H;
|
||||
extern u16 TM0D;
|
||||
extern u16 TM0CNT;
|
||||
extern u16 TM1D;
|
||||
extern u16 TM1CNT;
|
||||
extern u16 TM2D;
|
||||
extern u16 TM2CNT;
|
||||
extern u16 TM3D;
|
||||
extern u16 TM3CNT;
|
||||
extern u16 P1;
|
||||
extern u16 IE;
|
||||
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.
|
||||
// Copyright (C) 1999-2003 Forgotten
|
||||
// Copyright (C) 2004 Forgotten and the VBA development team
|
||||
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; either version 2, or(at your option)
|
||||
// any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software Foundation,
|
||||
// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
#include "agb/GBA.h"
|
||||
#include "Globals.h"
|
||||
#include "agb/GBAGfx.h"
|
||||
|
||||
void mode2RenderLine()
|
||||
{
|
||||
u16 *palette = (u16 *)paletteRAM;
|
||||
|
||||
if(DISPCNT & 0x80) {
|
||||
for(int x = 0; x < 240; x++) {
|
||||
lineMix[x] = 0x7fff;
|
||||
}
|
||||
gfxLastVCOUNT = VCOUNT;
|
||||
return;
|
||||
}
|
||||
|
||||
if(layerEnable & 0x0400) {
|
||||
int changed = gfxBG2Changed;
|
||||
if(gfxLastVCOUNT > VCOUNT)
|
||||
changed = 3;
|
||||
|
||||
gfxDrawRotScreen(BG2CNT, BG2X_L, BG2X_H, BG2Y_L, BG2Y_H,
|
||||
BG2PA, BG2PB, BG2PC, BG2PD, gfxBG2X, gfxBG2Y,
|
||||
changed, line2);
|
||||
}
|
||||
|
||||
if(layerEnable & 0x0800) {
|
||||
int changed = gfxBG3Changed;
|
||||
if(gfxLastVCOUNT > VCOUNT)
|
||||
changed = 3;
|
||||
|
||||
gfxDrawRotScreen(BG3CNT, BG3X_L, BG3X_H, BG3Y_L, BG3Y_H,
|
||||
BG3PA, BG3PB, BG3PC, BG3PD, gfxBG3X, gfxBG3Y,
|
||||
changed, line3);
|
||||
}
|
||||
|
||||
gfxDrawSprites(lineOBJ);
|
||||
|
||||
u32 backdrop = (READ16LE(&palette[0]) | 0x30000000);
|
||||
|
||||
for(int x = 0; x < 240; x++) {
|
||||
u32 color = backdrop;
|
||||
u8 top = 0x20;
|
||||
|
||||
|
||||
if((u8)(line2[x]>>24) < (u8)(color >> 24)) {
|
||||
color = line2[x];
|
||||
top = 0x04;
|
||||
}
|
||||
|
||||
if((u8)(line3[x]>>24) < (u8)(color >> 24)) {
|
||||
color = line3[x];
|
||||
top = 0x08;
|
||||
}
|
||||
|
||||
if((u8)(lineOBJ[x]>>24) < (u8)(color >> 24)) {
|
||||
color = lineOBJ[x];
|
||||
top = 0x10;
|
||||
}
|
||||
|
||||
if((top & 0x10) && (color & 0x00010000)) {
|
||||
// semi-transparent OBJ
|
||||
u32 back = backdrop;
|
||||
u8 top2 = 0x20;
|
||||
|
||||
if((u8)(line2[x]>>24) < (u8)(back >> 24)) {
|
||||
back = line2[x];
|
||||
top2 = 0x04;
|
||||
}
|
||||
|
||||
if((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;
|
||||
}
|
||||
|
||||
void mode2RenderLineNoWindow()
|
||||
{
|
||||
u16 *palette = (u16 *)paletteRAM;
|
||||
|
||||
if(DISPCNT & 0x80) {
|
||||
for(int x = 0; x < 240; x++) {
|
||||
lineMix[x] = 0x7fff;
|
||||
}
|
||||
gfxLastVCOUNT = VCOUNT;
|
||||
return;
|
||||
}
|
||||
|
||||
if(layerEnable & 0x0400) {
|
||||
int changed = gfxBG2Changed;
|
||||
if(gfxLastVCOUNT > VCOUNT)
|
||||
changed = 3;
|
||||
|
||||
gfxDrawRotScreen(BG2CNT, BG2X_L, BG2X_H, BG2Y_L, BG2Y_H,
|
||||
BG2PA, BG2PB, BG2PC, BG2PD, gfxBG2X, gfxBG2Y,
|
||||
changed, line2);
|
||||
}
|
||||
|
||||
if(layerEnable & 0x0800) {
|
||||
int changed = gfxBG3Changed;
|
||||
if(gfxLastVCOUNT > VCOUNT)
|
||||
changed = 3;
|
||||
|
||||
gfxDrawRotScreen(BG3CNT, BG3X_L, BG3X_H, BG3Y_L, BG3Y_H,
|
||||
BG3PA, BG3PB, BG3PC, BG3PD, gfxBG3X, gfxBG3Y,
|
||||
changed, line3);
|
||||
}
|
||||
|
||||
gfxDrawSprites(lineOBJ);
|
||||
|
||||
u32 backdrop = (READ16LE(&palette[0]) | 0x30000000);
|
||||
|
||||
for(int x = 0; x < 240; x++) {
|
||||
u32 color = backdrop;
|
||||
u8 top = 0x20;
|
||||
|
||||
|
||||
if((u8)(line2[x]>>24) < (u8)(color >> 24)) {
|
||||
color = line2[x];
|
||||
top = 0x04;
|
||||
}
|
||||
|
||||
if((u8)(line3[x]>>24) < (u8)(color >> 24)) {
|
||||
color = line3[x];
|
||||
top = 0x08;
|
||||
}
|
||||
|
||||
if((u8)(lineOBJ[x]>>24) < (u8)(color >> 24)) {
|
||||
color = lineOBJ[x];
|
||||
top = 0x10;
|
||||
}
|
||||
|
||||
if(!(color & 0x00010000)) {
|
||||
switch((BLDMOD >> 6) & 3) {
|
||||
case 0:
|
||||
break;
|
||||
case 1:
|
||||
{
|
||||
if(top & BLDMOD) {
|
||||
u32 back = backdrop;
|
||||
u8 top2 = 0x20;
|
||||
|
||||
if((u8)(line2[x]>>24) < (u8)(back >> 24)) {
|
||||
if(top != 0x04) {
|
||||
back = line2[x];
|
||||
top2 = 0x04;
|
||||
}
|
||||
}
|
||||
|
||||
if((u8)(line3[x]>>24) < (u8)(back >> 24)) {
|
||||
if(top != 0x08) {
|
||||
back = line3[x];
|
||||
top2 = 0x08;
|
||||
}
|
||||
}
|
||||
|
||||
if((u8)(lineOBJ[x]>>24) < (u8)(back >> 24)) {
|
||||
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((u8)(line2[x]>>24) < (u8)(back >> 24)) {
|
||||
back = line2[x];
|
||||
top2 = 0x04;
|
||||
}
|
||||
|
||||
if((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;
|
||||
}
|
||||
|
||||
void mode2RenderLineAll()
|
||||
{
|
||||
u16 *palette = (u16 *)paletteRAM;
|
||||
|
||||
if(DISPCNT & 0x80) {
|
||||
for(int x = 0; x < 240; x++) {
|
||||
lineMix[x] = 0x7fff;
|
||||
}
|
||||
gfxLastVCOUNT = VCOUNT;
|
||||
return;
|
||||
}
|
||||
|
||||
bool inWindow0 = false;
|
||||
bool inWindow1 = false;
|
||||
|
||||
if(layerEnable & 0x2000) {
|
||||
u8 v0 = WIN0V >> 8;
|
||||
u8 v1 = WIN0V & 255;
|
||||
inWindow0 = ((v0 == v1) && (v0 >= 0xe8));
|
||||
if(v1 >= v0)
|
||||
inWindow0 |= (VCOUNT >= v0 && VCOUNT < v1);
|
||||
else
|
||||
inWindow0 |= (VCOUNT >= v0 || VCOUNT < v1);
|
||||
}
|
||||
if(layerEnable & 0x4000) {
|
||||
u8 v0 = WIN1V >> 8;
|
||||
u8 v1 = WIN1V & 255;
|
||||
inWindow1 = ((v0 == v1) && (v0 >= 0xe8));
|
||||
if(v1 >= v0)
|
||||
inWindow1 |= (VCOUNT >= v0 && VCOUNT < v1);
|
||||
else
|
||||
inWindow1 |= (VCOUNT >= v0 || VCOUNT < v1);
|
||||
}
|
||||
|
||||
if(layerEnable & 0x0400) {
|
||||
int changed = gfxBG2Changed;
|
||||
if(gfxLastVCOUNT > VCOUNT)
|
||||
changed = 3;
|
||||
|
||||
gfxDrawRotScreen(BG2CNT, BG2X_L, BG2X_H, BG2Y_L, BG2Y_H,
|
||||
BG2PA, BG2PB, BG2PC, BG2PD, gfxBG2X, gfxBG2Y,
|
||||
changed, line2);
|
||||
}
|
||||
|
||||
if(layerEnable & 0x0800) {
|
||||
int changed = gfxBG3Changed;
|
||||
if(gfxLastVCOUNT > VCOUNT)
|
||||
changed = 3;
|
||||
|
||||
gfxDrawRotScreen(BG3CNT, BG3X_L, BG3X_H, BG3Y_L, BG3Y_H,
|
||||
BG3PA, BG3PB, BG3PC, BG3PD, gfxBG3X, gfxBG3Y,
|
||||
changed, line3);
|
||||
}
|
||||
|
||||
gfxDrawSprites(lineOBJ);
|
||||
gfxDrawOBJWin(lineOBJWin);
|
||||
|
||||
u32 backdrop = (READ16LE(&palette[0]) | 0x30000000);
|
||||
|
||||
u8 inWin0Mask = WININ & 0xFF;
|
||||
u8 inWin1Mask = WININ >> 8;
|
||||
u8 outMask = WINOUT & 0xFF;
|
||||
|
||||
for(int x = 0; x < 240; x++) {
|
||||
u32 color = backdrop;
|
||||
u8 top = 0x20;
|
||||
u8 mask = outMask;
|
||||
|
||||
if(!(lineOBJWin[x] & 0x80000000)) {
|
||||
mask = WINOUT >> 8;
|
||||
}
|
||||
|
||||
if(inWindow1) {
|
||||
if(gfxInWin1[x])
|
||||
mask = inWin1Mask;
|
||||
}
|
||||
|
||||
if(inWindow0) {
|
||||
if(gfxInWin0[x]) {
|
||||
mask = inWin0Mask;
|
||||
}
|
||||
}
|
||||
|
||||
if(line2[x] < color && (mask & 4)) {
|
||||
color = line2[x];
|
||||
top = 0x04;
|
||||
}
|
||||
|
||||
if((u8)(line3[x]>>24) < (u8)(color >> 24) && (mask & 8)) {
|
||||
color = line3[x];
|
||||
top = 0x08;
|
||||
}
|
||||
|
||||
if((u8)(lineOBJ[x]>>24) < (u8)(color >> 24) && (mask & 16)) {
|
||||
color = lineOBJ[x];
|
||||
top = 0x10;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
} else if(mask & 32) {
|
||||
// special FX on the window
|
||||
switch((BLDMOD >> 6) & 3) {
|
||||
case 0:
|
||||
break;
|
||||
case 1:
|
||||
{
|
||||
if(top & BLDMOD) {
|
||||
u32 back = backdrop;
|
||||
u8 top2 = 0x20;
|
||||
|
||||
if((mask & 4) && line2[x] < back) {
|
||||
if(top != 0x04) {
|
||||
back = line2[x];
|
||||
top2 = 0x04;
|
||||
}
|
||||
}
|
||||
|
||||
if((mask & 8) && (u8)(line3[x]>>24) < (u8)(back >> 24)) {
|
||||
if(top != 0x08) {
|
||||
back = line3[x];
|
||||
top2 = 0x08;
|
||||
}
|
||||
}
|
||||
|
||||
if((mask & 16) && (u8)(lineOBJ[x]>>24) < (u8)(back >> 24)) {
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
lineMix[x] = color;
|
||||
}
|
||||
gfxBG2Changed = 0;
|
||||
gfxBG3Changed = 0;
|
||||
gfxLastVCOUNT = VCOUNT;
|
||||
}
|
||||
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
|
||||
// Copyright (C) 1999-2003 Forgotten
|
||||
// Copyright (C) 2004 Forgotten and the VBA development team
|
||||
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; either version 2, or(at your option)
|
||||
// any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software Foundation,
|
||||
// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
#include "GBA.h"
|
||||
#include "Globals.h"
|
||||
#include "Gfx.h"
|
||||
|
||||
void mode2RenderLine()
|
||||
{
|
||||
u16 *palette = (u16 *)paletteRAM;
|
||||
|
||||
if(DISPCNT & 0x80)
|
||||
{
|
||||
for(int x = 0; x < 240; x++)
|
||||
{
|
||||
lineMix[x] = 0x7fff;
|
||||
}
|
||||
gfxLastVCOUNT = VCOUNT;
|
||||
return;
|
||||
}
|
||||
|
||||
if(layerEnable & 0x0400)
|
||||
{
|
||||
int changed = gfxBG2Changed;
|
||||
if(gfxLastVCOUNT > VCOUNT)
|
||||
changed = 3;
|
||||
|
||||
gfxDrawRotScreen(BG2CNT, BG2X_L, BG2X_H, BG2Y_L, BG2Y_H,
|
||||
BG2PA, BG2PB, BG2PC, BG2PD, gfxBG2X, gfxBG2Y,
|
||||
changed, line2);
|
||||
}
|
||||
|
||||
if(layerEnable & 0x0800)
|
||||
{
|
||||
int changed = gfxBG3Changed;
|
||||
if(gfxLastVCOUNT > VCOUNT)
|
||||
changed = 3;
|
||||
|
||||
gfxDrawRotScreen(BG3CNT, BG3X_L, BG3X_H, BG3Y_L, BG3Y_H,
|
||||
BG3PA, BG3PB, BG3PC, BG3PD, gfxBG3X, gfxBG3Y,
|
||||
changed, line3);
|
||||
}
|
||||
|
||||
gfxDrawSprites(lineOBJ);
|
||||
|
||||
u32 backdrop = (READ16LE(&palette[0]) | 0x30000000);
|
||||
|
||||
for(int x = 0; x < 240; x++)
|
||||
{
|
||||
u32 color = backdrop;
|
||||
u8 top = 0x20;
|
||||
|
||||
|
||||
if((u8)(line2[x]>>24) < (u8)(color >> 24))
|
||||
{
|
||||
color = line2[x];
|
||||
top = 0x04;
|
||||
}
|
||||
|
||||
if((u8)(line3[x]>>24) < (u8)(color >> 24))
|
||||
{
|
||||
color = line3[x];
|
||||
top = 0x08;
|
||||
}
|
||||
|
||||
if((u8)(lineOBJ[x]>>24) < (u8)(color >> 24))
|
||||
{
|
||||
color = lineOBJ[x];
|
||||
top = 0x10;
|
||||
}
|
||||
|
||||
if((top & 0x10) && (color & 0x00010000))
|
||||
{
|
||||
// semi-transparent OBJ
|
||||
u32 back = backdrop;
|
||||
u8 top2 = 0x20;
|
||||
|
||||
if((u8)(line2[x]>>24) < (u8)(back >> 24))
|
||||
{
|
||||
back = line2[x];
|
||||
top2 = 0x04;
|
||||
}
|
||||
|
||||
if((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;
|
||||
}
|
||||
|
||||
void mode2RenderLineNoWindow()
|
||||
{
|
||||
u16 *palette = (u16 *)paletteRAM;
|
||||
|
||||
if(DISPCNT & 0x80)
|
||||
{
|
||||
for(int x = 0; x < 240; x++)
|
||||
{
|
||||
lineMix[x] = 0x7fff;
|
||||
}
|
||||
gfxLastVCOUNT = VCOUNT;
|
||||
return;
|
||||
}
|
||||
|
||||
if(layerEnable & 0x0400)
|
||||
{
|
||||
int changed = gfxBG2Changed;
|
||||
if(gfxLastVCOUNT > VCOUNT)
|
||||
changed = 3;
|
||||
|
||||
gfxDrawRotScreen(BG2CNT, BG2X_L, BG2X_H, BG2Y_L, BG2Y_H,
|
||||
BG2PA, BG2PB, BG2PC, BG2PD, gfxBG2X, gfxBG2Y,
|
||||
changed, line2);
|
||||
}
|
||||
|
||||
if(layerEnable & 0x0800)
|
||||
{
|
||||
int changed = gfxBG3Changed;
|
||||
if(gfxLastVCOUNT > VCOUNT)
|
||||
changed = 3;
|
||||
|
||||
gfxDrawRotScreen(BG3CNT, BG3X_L, BG3X_H, BG3Y_L, BG3Y_H,
|
||||
BG3PA, BG3PB, BG3PC, BG3PD, gfxBG3X, gfxBG3Y,
|
||||
changed, line3);
|
||||
}
|
||||
|
||||
gfxDrawSprites(lineOBJ);
|
||||
|
||||
u32 backdrop = (READ16LE(&palette[0]) | 0x30000000);
|
||||
|
||||
for(int x = 0; x < 240; x++)
|
||||
{
|
||||
u32 color = backdrop;
|
||||
u8 top = 0x20;
|
||||
|
||||
|
||||
if((u8)(line2[x]>>24) < (u8)(color >> 24))
|
||||
{
|
||||
color = line2[x];
|
||||
top = 0x04;
|
||||
}
|
||||
|
||||
if((u8)(line3[x]>>24) < (u8)(color >> 24))
|
||||
{
|
||||
color = line3[x];
|
||||
top = 0x08;
|
||||
}
|
||||
|
||||
if((u8)(lineOBJ[x]>>24) < (u8)(color >> 24))
|
||||
{
|
||||
color = lineOBJ[x];
|
||||
top = 0x10;
|
||||
}
|
||||
|
||||
if(!(color & 0x00010000))
|
||||
{
|
||||
switch((BLDMOD >> 6) & 3)
|
||||
{
|
||||
case 0:
|
||||
break;
|
||||
case 1:
|
||||
{
|
||||
if(top & BLDMOD)
|
||||
{
|
||||
u32 back = backdrop;
|
||||
u8 top2 = 0x20;
|
||||
|
||||
if((u8)(line2[x]>>24) < (u8)(back >> 24))
|
||||
{
|
||||
if(top != 0x04)
|
||||
{
|
||||
back = line2[x];
|
||||
top2 = 0x04;
|
||||
}
|
||||
}
|
||||
|
||||
if((u8)(line3[x]>>24) < (u8)(back >> 24))
|
||||
{
|
||||
if(top != 0x08)
|
||||
{
|
||||
back = line3[x];
|
||||
top2 = 0x08;
|
||||
}
|
||||
}
|
||||
|
||||
if((u8)(lineOBJ[x]>>24) < (u8)(back >> 24))
|
||||
{
|
||||
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((u8)(line2[x]>>24) < (u8)(back >> 24))
|
||||
{
|
||||
back = line2[x];
|
||||
top2 = 0x04;
|
||||
}
|
||||
|
||||
if((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;
|
||||
}
|
||||
|
||||
void mode2RenderLineAll()
|
||||
{
|
||||
u16 *palette = (u16 *)paletteRAM;
|
||||
|
||||
if(DISPCNT & 0x80)
|
||||
{
|
||||
for(int x = 0; x < 240; x++)
|
||||
{
|
||||
lineMix[x] = 0x7fff;
|
||||
}
|
||||
gfxLastVCOUNT = VCOUNT;
|
||||
return;
|
||||
}
|
||||
|
||||
bool inWindow0 = false;
|
||||
bool inWindow1 = false;
|
||||
|
||||
if(layerEnable & 0x2000)
|
||||
{
|
||||
u8 v0 = WIN0V >> 8;
|
||||
u8 v1 = WIN0V & 255;
|
||||
inWindow0 = ((v0 == v1) && (v0 >= 0xe8));
|
||||
if(v1 >= v0)
|
||||
inWindow0 |= (VCOUNT >= v0 && VCOUNT < v1);
|
||||
else
|
||||
inWindow0 |= (VCOUNT >= v0 || VCOUNT < v1);
|
||||
}
|
||||
if(layerEnable & 0x4000)
|
||||
{
|
||||
u8 v0 = WIN1V >> 8;
|
||||
u8 v1 = WIN1V & 255;
|
||||
inWindow1 = ((v0 == v1) && (v0 >= 0xe8));
|
||||
if(v1 >= v0)
|
||||
inWindow1 |= (VCOUNT >= v0 && VCOUNT < v1);
|
||||
else
|
||||
inWindow1 |= (VCOUNT >= v0 || VCOUNT < v1);
|
||||
}
|
||||
|
||||
if(layerEnable & 0x0400)
|
||||
{
|
||||
int changed = gfxBG2Changed;
|
||||
if(gfxLastVCOUNT > VCOUNT)
|
||||
changed = 3;
|
||||
|
||||
gfxDrawRotScreen(BG2CNT, BG2X_L, BG2X_H, BG2Y_L, BG2Y_H,
|
||||
BG2PA, BG2PB, BG2PC, BG2PD, gfxBG2X, gfxBG2Y,
|
||||
changed, line2);
|
||||
}
|
||||
|
||||
if(layerEnable & 0x0800)
|
||||
{
|
||||
int changed = gfxBG3Changed;
|
||||
if(gfxLastVCOUNT > VCOUNT)
|
||||
changed = 3;
|
||||
|
||||
gfxDrawRotScreen(BG3CNT, BG3X_L, BG3X_H, BG3Y_L, BG3Y_H,
|
||||
BG3PA, BG3PB, BG3PC, BG3PD, gfxBG3X, gfxBG3Y,
|
||||
changed, line3);
|
||||
}
|
||||
|
||||
gfxDrawSprites(lineOBJ);
|
||||
gfxDrawOBJWin(lineOBJWin);
|
||||
|
||||
u32 backdrop = (READ16LE(&palette[0]) | 0x30000000);
|
||||
|
||||
u8 inWin0Mask = WININ & 0xFF;
|
||||
u8 inWin1Mask = WININ >> 8;
|
||||
u8 outMask = WINOUT & 0xFF;
|
||||
|
||||
for(int x = 0; x < 240; x++)
|
||||
{
|
||||
u32 color = backdrop;
|
||||
u8 top = 0x20;
|
||||
u8 mask = outMask;
|
||||
|
||||
if(!(lineOBJWin[x] & 0x80000000))
|
||||
{
|
||||
mask = WINOUT >> 8;
|
||||
}
|
||||
|
||||
if(inWindow1)
|
||||
{
|
||||
if(gfxInWin1[x])
|
||||
mask = inWin1Mask;
|
||||
}
|
||||
|
||||
if(inWindow0)
|
||||
{
|
||||
if(gfxInWin0[x])
|
||||
{
|
||||
mask = inWin0Mask;
|
||||
}
|
||||
}
|
||||
|
||||
if(line2[x] < color && (mask & 4))
|
||||
{
|
||||
color = line2[x];
|
||||
top = 0x04;
|
||||
}
|
||||
|
||||
if((u8)(line3[x]>>24) < (u8)(color >> 24) && (mask & 8))
|
||||
{
|
||||
color = line3[x];
|
||||
top = 0x08;
|
||||
}
|
||||
|
||||
if((u8)(lineOBJ[x]>>24) < (u8)(color >> 24) && (mask & 16))
|
||||
{
|
||||
color = lineOBJ[x];
|
||||
top = 0x10;
|
||||
}
|
||||
|
||||
if(mask & 32)
|
||||
{
|
||||
if(!(color & 0x00010000))
|
||||
{
|
||||
switch((BLDMOD >> 6) & 3)
|
||||
{
|
||||
case 0:
|
||||
break;
|
||||
case 1:
|
||||
{
|
||||
if(top & BLDMOD)
|
||||
{
|
||||
u32 back = backdrop;
|
||||
u8 top2 = 0x20;
|
||||
|
||||
if((mask & 4) && line2[x] < back)
|
||||
{
|
||||
if(top != 0x04)
|
||||
{
|
||||
back = line2[x];
|
||||
top2 = 0x04;
|
||||
}
|
||||
}
|
||||
|
||||
if((mask & 8) && (u8)(line3[x]>>24) < (u8)(back >> 24))
|
||||
{
|
||||
if(top != 0x08)
|
||||
{
|
||||
back = line3[x];
|
||||
top2 = 0x08;
|
||||
}
|
||||
}
|
||||
|
||||
if((mask & 16) && (u8)(lineOBJ[x]>>24) < (u8)(back >> 24))
|
||||
{
|
||||
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.
|
||||
// Copyright (C) 1999-2003 Forgotten
|
||||
// Copyright (C) 2004 Forgotten and the VBA development team
|
||||
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; either version 2, or(at your option)
|
||||
// any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software Foundation,
|
||||
// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
#include "agb/GBA.h"
|
||||
#include "Globals.h"
|
||||
#include "agb/GBAGfx.h"
|
||||
|
||||
void mode3RenderLine()
|
||||
{
|
||||
u16 *palette = (u16 *)paletteRAM;
|
||||
|
||||
if(DISPCNT & 0x80) {
|
||||
for(int x = 0; x < 240; x++) {
|
||||
lineMix[x] = 0x7fff;
|
||||
}
|
||||
gfxLastVCOUNT = VCOUNT;
|
||||
return;
|
||||
}
|
||||
|
||||
if(layerEnable & 0x0400) {
|
||||
int changed = gfxBG2Changed;
|
||||
|
||||
if(gfxLastVCOUNT > VCOUNT)
|
||||
changed = 3;
|
||||
|
||||
gfxDrawRotScreen16Bit(BG2CNT, BG2X_L, BG2X_H,
|
||||
BG2Y_L, BG2Y_H, BG2PA, BG2PB,
|
||||
BG2PC, BG2PD,
|
||||
gfxBG2X, gfxBG2Y, changed,
|
||||
line2);
|
||||
}
|
||||
|
||||
gfxDrawSprites(lineOBJ);
|
||||
|
||||
u32 background = (READ16LE(&palette[0]) | 0x30000000);
|
||||
|
||||
for(int x = 0; x < 240; x++) {
|
||||
u32 color = background;
|
||||
u8 top = 0x20;
|
||||
|
||||
if(line2[x] < color) {
|
||||
color = line2[x];
|
||||
top = 0x04;
|
||||
}
|
||||
|
||||
if((u8)(lineOBJ[x]>>24) < (u8)(color >>24)) {
|
||||
color = lineOBJ[x];
|
||||
top = 0x10;
|
||||
}
|
||||
|
||||
if((top & 0x10) && (color & 0x00010000)) {
|
||||
// semi-transparent OBJ
|
||||
u32 back = background;
|
||||
u8 top2 = 0x20;
|
||||
|
||||
if(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;
|
||||
}
|
||||
|
||||
void mode3RenderLineNoWindow()
|
||||
{
|
||||
u16 *palette = (u16 *)paletteRAM;
|
||||
|
||||
if(DISPCNT & 0x80) {
|
||||
for(int x = 0; x < 240; x++) {
|
||||
lineMix[x] = 0x7fff;
|
||||
}
|
||||
gfxLastVCOUNT = VCOUNT;
|
||||
return;
|
||||
}
|
||||
|
||||
if(layerEnable & 0x0400) {
|
||||
int changed = gfxBG2Changed;
|
||||
|
||||
if(gfxLastVCOUNT > VCOUNT)
|
||||
changed = 3;
|
||||
|
||||
gfxDrawRotScreen16Bit(BG2CNT, BG2X_L, BG2X_H,
|
||||
BG2Y_L, BG2Y_H, BG2PA, BG2PB,
|
||||
BG2PC, BG2PD,
|
||||
gfxBG2X, gfxBG2Y, changed,
|
||||
line2);
|
||||
}
|
||||
|
||||
gfxDrawSprites(lineOBJ);
|
||||
|
||||
u32 background = (READ16LE(&palette[0]) | 0x30000000);
|
||||
|
||||
for(int x = 0; x < 240; x++) {
|
||||
u32 color = background;
|
||||
u8 top = 0x20;
|
||||
|
||||
if(line2[x] < color) {
|
||||
color = line2[x];
|
||||
top = 0x04;
|
||||
}
|
||||
|
||||
if((u8)(lineOBJ[x]>>24) < (u8)(color >>24)) {
|
||||
color = lineOBJ[x];
|
||||
top = 0x10;
|
||||
}
|
||||
|
||||
if(!(color & 0x00010000)) {
|
||||
switch((BLDMOD >> 6) & 3) {
|
||||
case 0:
|
||||
break;
|
||||
case 1:
|
||||
{
|
||||
if(top & BLDMOD) {
|
||||
u32 back = background;
|
||||
u8 top2 = 0x20;
|
||||
|
||||
if(line2[x] < back) {
|
||||
if(top != 0x04) {
|
||||
back = line2[x];
|
||||
top2 = 0x04;
|
||||
}
|
||||
}
|
||||
|
||||
if((u8)(lineOBJ[x]>>24) < (u8)(back >> 24)) {
|
||||
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 = background;
|
||||
u8 top2 = 0x20;
|
||||
|
||||
if(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;
|
||||
}
|
||||
|
||||
void mode3RenderLineAll()
|
||||
{
|
||||
u16 *palette = (u16 *)paletteRAM;
|
||||
|
||||
if(DISPCNT & 0x80) {
|
||||
for(int x = 0; x < 240; x++) {
|
||||
lineMix[x] = 0x7fff;
|
||||
}
|
||||
gfxLastVCOUNT = VCOUNT;
|
||||
return;
|
||||
}
|
||||
|
||||
bool inWindow0 = false;
|
||||
bool inWindow1 = false;
|
||||
|
||||
if(layerEnable & 0x2000) {
|
||||
u8 v0 = WIN0V >> 8;
|
||||
u8 v1 = WIN0V & 255;
|
||||
inWindow0 = ((v0 == v1) && (v0 >= 0xe8));
|
||||
if(v1 >= v0)
|
||||
inWindow0 |= (VCOUNT >= v0 && VCOUNT < v1);
|
||||
else
|
||||
inWindow0 |= (VCOUNT >= v0 || VCOUNT < v1);
|
||||
}
|
||||
if(layerEnable & 0x4000) {
|
||||
u8 v0 = WIN1V >> 8;
|
||||
u8 v1 = WIN1V & 255;
|
||||
inWindow1 = ((v0 == v1) && (v0 >= 0xe8));
|
||||
if(v1 >= v0)
|
||||
inWindow1 |= (VCOUNT >= v0 && VCOUNT < v1);
|
||||
else
|
||||
inWindow1 |= (VCOUNT >= v0 || VCOUNT < v1);
|
||||
}
|
||||
|
||||
if(layerEnable & 0x0400) {
|
||||
int changed = gfxBG2Changed;
|
||||
|
||||
if(gfxLastVCOUNT > VCOUNT)
|
||||
changed = 3;
|
||||
|
||||
gfxDrawRotScreen16Bit(BG2CNT, BG2X_L, BG2X_H,
|
||||
BG2Y_L, BG2Y_H, BG2PA, BG2PB,
|
||||
BG2PC, BG2PD,
|
||||
gfxBG2X, gfxBG2Y, changed,
|
||||
line2);
|
||||
}
|
||||
|
||||
gfxDrawSprites(lineOBJ);
|
||||
gfxDrawOBJWin(lineOBJWin);
|
||||
|
||||
u8 inWin0Mask = WININ & 0xFF;
|
||||
u8 inWin1Mask = WININ >> 8;
|
||||
u8 outMask = WINOUT & 0xFF;
|
||||
|
||||
u32 background = (READ16LE(&palette[0]) | 0x30000000);
|
||||
|
||||
for(int x = 0; x < 240; x++) {
|
||||
u32 color = background;
|
||||
u8 top = 0x20;
|
||||
u8 mask = outMask;
|
||||
|
||||
if(!(lineOBJWin[x] & 0x80000000)) {
|
||||
mask = WINOUT >> 8;
|
||||
}
|
||||
|
||||
if(inWindow1) {
|
||||
if(gfxInWin1[x])
|
||||
mask = inWin1Mask;
|
||||
}
|
||||
|
||||
if(inWindow0) {
|
||||
if(gfxInWin0[x]) {
|
||||
mask = inWin0Mask;
|
||||
}
|
||||
}
|
||||
|
||||
if((mask & 4) && (line2[x] < color)) {
|
||||
color = line2[x];
|
||||
top = 0x04;
|
||||
}
|
||||
|
||||
if((mask & 16) && ((u8)(lineOBJ[x]>>24) < (u8)(color >>24))) {
|
||||
color = lineOBJ[x];
|
||||
top = 0x10;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
} else if(mask & 32) {
|
||||
switch((BLDMOD >> 6) & 3) {
|
||||
case 0:
|
||||
break;
|
||||
case 1:
|
||||
{
|
||||
if(top & BLDMOD) {
|
||||
u32 back = background;
|
||||
u8 top2 = 0x20;
|
||||
|
||||
if((mask & 4) && line2[x] < back) {
|
||||
if(top != 0x04) {
|
||||
back = line2[x];
|
||||
top2 = 0x04;
|
||||
}
|
||||
}
|
||||
|
||||
if((mask & 16) && (u8)(lineOBJ[x]>>24) < (u8)(back >> 24)) {
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
lineMix[x] = color;
|
||||
}
|
||||
gfxBG2Changed = 0;
|
||||
gfxLastVCOUNT = VCOUNT;
|
||||
}
|
||||
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
|
||||
// Copyright (C) 1999-2003 Forgotten
|
||||
// Copyright (C) 2004 Forgotten and the VBA development team
|
||||
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; either version 2, or(at your option)
|
||||
// any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software Foundation,
|
||||
// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
#include "GBA.h"
|
||||
#include "Globals.h"
|
||||
#include "Gfx.h"
|
||||
|
||||
void mode3RenderLine()
|
||||
{
|
||||
u16 *palette = (u16 *)paletteRAM;
|
||||
|
||||
if(DISPCNT & 0x80)
|
||||
{
|
||||
for(int x = 0; x < 240; x++)
|
||||
{
|
||||
lineMix[x] = 0x7fff;
|
||||
}
|
||||
gfxLastVCOUNT = VCOUNT;
|
||||
return;
|
||||
}
|
||||
|
||||
if(layerEnable & 0x0400)
|
||||
{
|
||||
int changed = gfxBG2Changed;
|
||||
|
||||
if(gfxLastVCOUNT > VCOUNT)
|
||||
changed = 3;
|
||||
|
||||
gfxDrawRotScreen16Bit(BG2CNT, BG2X_L, BG2X_H,
|
||||
BG2Y_L, BG2Y_H, BG2PA, BG2PB,
|
||||
BG2PC, BG2PD,
|
||||
gfxBG2X, gfxBG2Y, changed,
|
||||
line2);
|
||||
}
|
||||
|
||||
gfxDrawSprites(lineOBJ);
|
||||
|
||||
u32 background = (READ16LE(&palette[0]) | 0x30000000);
|
||||
|
||||
for(int x = 0; x < 240; x++)
|
||||
{
|
||||
u32 color = background;
|
||||
u8 top = 0x20;
|
||||
|
||||
if(line2[x] < color)
|
||||
{
|
||||
color = line2[x];
|
||||
top = 0x04;
|
||||
}
|
||||
|
||||
if((u8)(lineOBJ[x]>>24) < (u8)(color >>24))
|
||||
{
|
||||
color = lineOBJ[x];
|
||||
top = 0x10;
|
||||
}
|
||||
|
||||
if((top & 0x10) && (color & 0x00010000))
|
||||
{
|
||||
// semi-transparent OBJ
|
||||
u32 back = background;
|
||||
u8 top2 = 0x20;
|
||||
|
||||
if(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;
|
||||
}
|
||||
|
||||
void mode3RenderLineNoWindow()
|
||||
{
|
||||
u16 *palette = (u16 *)paletteRAM;
|
||||
|
||||
if(DISPCNT & 0x80)
|
||||
{
|
||||
for(int x = 0; x < 240; x++)
|
||||
{
|
||||
lineMix[x] = 0x7fff;
|
||||
}
|
||||
gfxLastVCOUNT = VCOUNT;
|
||||
return;
|
||||
}
|
||||
|
||||
if(layerEnable & 0x0400)
|
||||
{
|
||||
int changed = gfxBG2Changed;
|
||||
|
||||
if(gfxLastVCOUNT > VCOUNT)
|
||||
changed = 3;
|
||||
|
||||
gfxDrawRotScreen16Bit(BG2CNT, BG2X_L, BG2X_H,
|
||||
BG2Y_L, BG2Y_H, BG2PA, BG2PB,
|
||||
BG2PC, BG2PD,
|
||||
gfxBG2X, gfxBG2Y, changed,
|
||||
line2);
|
||||
}
|
||||
|
||||
gfxDrawSprites(lineOBJ);
|
||||
|
||||
u32 background = (READ16LE(&palette[0]) | 0x30000000);
|
||||
|
||||
for(int x = 0; x < 240; x++)
|
||||
{
|
||||
u32 color = background;
|
||||
u8 top = 0x20;
|
||||
|
||||
if(line2[x] < color)
|
||||
{
|
||||
color = line2[x];
|
||||
top = 0x04;
|
||||
}
|
||||
|
||||
if((u8)(lineOBJ[x]>>24) < (u8)(color >>24))
|
||||
{
|
||||
color = lineOBJ[x];
|
||||
top = 0x10;
|
||||
}
|
||||
|
||||
if(!(color & 0x00010000))
|
||||
{
|
||||
switch((BLDMOD >> 6) & 3)
|
||||
{
|
||||
case 0:
|
||||
break;
|
||||
case 1:
|
||||
{
|
||||
if(top & BLDMOD)
|
||||
{
|
||||
u32 back = background;
|
||||
u8 top2 = 0x20;
|
||||
|
||||
if(line2[x] < back)
|
||||
{
|
||||
if(top != 0x04)
|
||||
{
|
||||
back = line2[x];
|
||||
top2 = 0x04;
|
||||
}
|
||||
}
|
||||
|
||||
if((u8)(lineOBJ[x]>>24) < (u8)(back >> 24))
|
||||
{
|
||||
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 = background;
|
||||
u8 top2 = 0x20;
|
||||
|
||||
if(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;
|
||||
}
|
||||
|
||||
void mode3RenderLineAll()
|
||||
{
|
||||
u16 *palette = (u16 *)paletteRAM;
|
||||
|
||||
if(DISPCNT & 0x80)
|
||||
{
|
||||
for(int x = 0; x < 240; x++)
|
||||
{
|
||||
lineMix[x] = 0x7fff;
|
||||
}
|
||||
gfxLastVCOUNT = VCOUNT;
|
||||
return;
|
||||
}
|
||||
|
||||
bool inWindow0 = false;
|
||||
bool inWindow1 = false;
|
||||
|
||||
if(layerEnable & 0x2000)
|
||||
{
|
||||
u8 v0 = WIN0V >> 8;
|
||||
u8 v1 = WIN0V & 255;
|
||||
inWindow0 = ((v0 == v1) && (v0 >= 0xe8));
|
||||
if(v1 >= v0)
|
||||
inWindow0 |= (VCOUNT >= v0 && VCOUNT < v1);
|
||||
else
|
||||
inWindow0 |= (VCOUNT >= v0 || VCOUNT < v1);
|
||||
}
|
||||
if(layerEnable & 0x4000)
|
||||
{
|
||||
u8 v0 = WIN1V >> 8;
|
||||
u8 v1 = WIN1V & 255;
|
||||
inWindow1 = ((v0 == v1) && (v0 >= 0xe8));
|
||||
if(v1 >= v0)
|
||||
inWindow1 |= (VCOUNT >= v0 && VCOUNT < v1);
|
||||
else
|
||||
inWindow1 |= (VCOUNT >= v0 || VCOUNT < v1);
|
||||
}
|
||||
|
||||
if(layerEnable & 0x0400)
|
||||
{
|
||||
int changed = gfxBG2Changed;
|
||||
|
||||
if(gfxLastVCOUNT > VCOUNT)
|
||||
changed = 3;
|
||||
|
||||
gfxDrawRotScreen16Bit(BG2CNT, BG2X_L, BG2X_H,
|
||||
BG2Y_L, BG2Y_H, BG2PA, BG2PB,
|
||||
BG2PC, BG2PD,
|
||||
gfxBG2X, gfxBG2Y, changed,
|
||||
line2);
|
||||
}
|
||||
|
||||
gfxDrawSprites(lineOBJ);
|
||||
gfxDrawOBJWin(lineOBJWin);
|
||||
|
||||
u8 inWin0Mask = WININ & 0xFF;
|
||||
u8 inWin1Mask = WININ >> 8;
|
||||
u8 outMask = WINOUT & 0xFF;
|
||||
|
||||
u32 background = (READ16LE(&palette[0]) | 0x30000000);
|
||||
|
||||
for(int x = 0; x < 240; x++)
|
||||
{
|
||||
u32 color = background;
|
||||
u8 top = 0x20;
|
||||
u8 mask = outMask;
|
||||
|
||||
if(!(lineOBJWin[x] & 0x80000000))
|
||||
{
|
||||
mask = WINOUT >> 8;
|
||||
}
|
||||
|
||||
if(inWindow1)
|
||||
{
|
||||
if(gfxInWin1[x])
|
||||
mask = inWin1Mask;
|
||||
}
|
||||
|
||||
if(inWindow0)
|
||||
{
|
||||
if(gfxInWin0[x])
|
||||
{
|
||||
mask = inWin0Mask;
|
||||
}
|
||||
}
|
||||
|
||||
if((mask & 4) && (line2[x] < color))
|
||||
{
|
||||
color = line2[x];
|
||||
top = 0x04;
|
||||
}
|
||||
|
||||
if((mask & 16) && ((u8)(lineOBJ[x]>>24) < (u8)(color >>24)))
|
||||
{
|
||||
color = lineOBJ[x];
|
||||
top = 0x10;
|
||||
}
|
||||
|
||||
if(mask & 32)
|
||||
{
|
||||
if(!(color & 0x00010000))
|
||||
{
|
||||
switch((BLDMOD >> 6) & 3)
|
||||
{
|
||||
case 0:
|
||||
break;
|
||||
case 1:
|
||||
{
|
||||
if(top & BLDMOD)
|
||||
{
|
||||
u32 back = background;
|
||||
u8 top2 = 0x20;
|
||||
|
||||
if((mask & 4) && line2[x] < back)
|
||||
{
|
||||
if(top != 0x04)
|
||||
{
|
||||
back = line2[x];
|
||||
top2 = 0x04;
|
||||
}
|
||||
}
|
||||
|
||||
if((mask & 16) && (u8)(lineOBJ[x]>>24) < (u8)(back >> 24))
|
||||
{
|
||||
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 = 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.
|
||||
// Copyright (C) 1999-2003 Forgotten
|
||||
// Copyright (C) 2004 Forgotten and the VBA development team
|
||||
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; either version 2, or(at your option)
|
||||
// any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software Foundation,
|
||||
// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
#include "agb/GBA.h"
|
||||
#include "agb/GBAGfx.h"
|
||||
#include "Globals.h"
|
||||
|
||||
void mode4RenderLine()
|
||||
{
|
||||
u16 *palette = (u16 *)paletteRAM;
|
||||
|
||||
if(DISPCNT & 0x0080) {
|
||||
for(int x = 0; x < 240; x++) {
|
||||
lineMix[x] = 0x7fff;
|
||||
}
|
||||
gfxLastVCOUNT = VCOUNT;
|
||||
return;
|
||||
}
|
||||
|
||||
if(layerEnable & 0x400) {
|
||||
int changed = gfxBG2Changed;
|
||||
|
||||
if(gfxLastVCOUNT > VCOUNT)
|
||||
changed = 3;
|
||||
|
||||
gfxDrawRotScreen256(BG2CNT, BG2X_L, BG2X_H, BG2Y_L, BG2Y_H,
|
||||
BG2PA, BG2PB, BG2PC, BG2PD,
|
||||
gfxBG2X, gfxBG2Y, changed,
|
||||
line2);
|
||||
}
|
||||
|
||||
gfxDrawSprites(lineOBJ);
|
||||
|
||||
u32 backdrop = (READ16LE(&palette[0]) | 0x30000000);
|
||||
|
||||
for(int x = 0; x < 240; x++) {
|
||||
u32 color = backdrop;
|
||||
u8 top = 0x20;
|
||||
|
||||
if(line2[x] < color) {
|
||||
color = line2[x];
|
||||
top = 0x04;
|
||||
}
|
||||
|
||||
if((u8)(lineOBJ[x]>>24) < (u8)(color >> 24)) {
|
||||
color = lineOBJ[x];
|
||||
top = 0x10;
|
||||
}
|
||||
|
||||
if((top & 0x10) && (color & 0x00010000)) {
|
||||
// semi-transparent OBJ
|
||||
u32 back = backdrop;
|
||||
u8 top2 = 0x20;
|
||||
|
||||
if(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;
|
||||
}
|
||||
|
||||
void mode4RenderLineNoWindow()
|
||||
{
|
||||
u16 *palette = (u16 *)paletteRAM;
|
||||
|
||||
if(DISPCNT & 0x0080) {
|
||||
for(int x = 0; x < 240; x++) {
|
||||
lineMix[x] = 0x7fff;
|
||||
}
|
||||
gfxLastVCOUNT = VCOUNT;
|
||||
return;
|
||||
}
|
||||
|
||||
if(layerEnable & 0x400) {
|
||||
int changed = gfxBG2Changed;
|
||||
|
||||
if(gfxLastVCOUNT > VCOUNT)
|
||||
changed = 3;
|
||||
|
||||
gfxDrawRotScreen256(BG2CNT, BG2X_L, BG2X_H, BG2Y_L, BG2Y_H,
|
||||
BG2PA, BG2PB, BG2PC, BG2PD,
|
||||
gfxBG2X, gfxBG2Y, changed,
|
||||
line2);
|
||||
}
|
||||
|
||||
gfxDrawSprites(lineOBJ);
|
||||
|
||||
u32 backdrop = (READ16LE(&palette[0]) | 0x30000000);
|
||||
|
||||
for(int x = 0; x < 240; x++) {
|
||||
u32 color = backdrop;
|
||||
u8 top = 0x20;
|
||||
|
||||
if(line2[x] < color) {
|
||||
color = line2[x];
|
||||
top = 0x04;
|
||||
}
|
||||
|
||||
if((u8)(lineOBJ[x]>>24) < (u8)(color >> 24)) {
|
||||
color = lineOBJ[x];
|
||||
top = 0x10;
|
||||
}
|
||||
|
||||
if(!(color & 0x00010000)) {
|
||||
switch((BLDMOD >> 6) & 3) {
|
||||
case 0:
|
||||
break;
|
||||
case 1:
|
||||
{
|
||||
if(top & BLDMOD) {
|
||||
u32 back = backdrop;
|
||||
u8 top2 = 0x20;
|
||||
|
||||
if(line2[x] < back) {
|
||||
if(top != 0x04) {
|
||||
back = line2[x];
|
||||
top2 = 0x04;
|
||||
}
|
||||
}
|
||||
|
||||
if((u8)(lineOBJ[x]>>24) < (u8)(back >> 24)) {
|
||||
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(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;
|
||||
}
|
||||
|
||||
void mode4RenderLineAll()
|
||||
{
|
||||
u16 *palette = (u16 *)paletteRAM;
|
||||
|
||||
if(DISPCNT & 0x0080) {
|
||||
for(int x = 0; x < 240; x++) {
|
||||
lineMix[x] = 0x7fff;
|
||||
}
|
||||
gfxLastVCOUNT = VCOUNT;
|
||||
return;
|
||||
}
|
||||
|
||||
bool inWindow0 = false;
|
||||
bool inWindow1 = false;
|
||||
|
||||
if(layerEnable & 0x2000) {
|
||||
u8 v0 = WIN0V >> 8;
|
||||
u8 v1 = WIN0V & 255;
|
||||
inWindow0 = ((v0 == v1) && (v0 >= 0xe8));
|
||||
if(v1 >= v0)
|
||||
inWindow0 |= (VCOUNT >= v0 && VCOUNT < v1);
|
||||
else
|
||||
inWindow0 |= (VCOUNT >= v0 || VCOUNT < v1);
|
||||
}
|
||||
if(layerEnable & 0x4000) {
|
||||
u8 v0 = WIN1V >> 8;
|
||||
u8 v1 = WIN1V & 255;
|
||||
inWindow1 = ((v0 == v1) && (v0 >= 0xe8));
|
||||
if(v1 >= v0)
|
||||
inWindow1 |= (VCOUNT >= v0 && VCOUNT < v1);
|
||||
else
|
||||
inWindow1 |= (VCOUNT >= v0 || VCOUNT < v1);
|
||||
}
|
||||
|
||||
if(layerEnable & 0x400) {
|
||||
int changed = gfxBG2Changed;
|
||||
|
||||
if(gfxLastVCOUNT > VCOUNT)
|
||||
changed = 3;
|
||||
|
||||
gfxDrawRotScreen256(BG2CNT, BG2X_L, BG2X_H, BG2Y_L, BG2Y_H,
|
||||
BG2PA, BG2PB, BG2PC, BG2PD,
|
||||
gfxBG2X, gfxBG2Y, changed,
|
||||
line2);
|
||||
}
|
||||
|
||||
gfxDrawSprites(lineOBJ);
|
||||
gfxDrawOBJWin(lineOBJWin);
|
||||
|
||||
u32 backdrop = (READ16LE(&palette[0]) | 0x30000000);
|
||||
|
||||
u8 inWin0Mask = WININ & 0xFF;
|
||||
u8 inWin1Mask = WININ >> 8;
|
||||
u8 outMask = WINOUT & 0xFF;
|
||||
|
||||
for(int x = 0; x < 240; x++) {
|
||||
u32 color = backdrop;
|
||||
u8 top = 0x20;
|
||||
u8 mask = outMask;
|
||||
|
||||
if(!(lineOBJWin[x] & 0x80000000)) {
|
||||
mask = WINOUT >> 8;
|
||||
}
|
||||
|
||||
if(inWindow1) {
|
||||
if(gfxInWin1[x])
|
||||
mask = inWin1Mask;
|
||||
}
|
||||
|
||||
if(inWindow0) {
|
||||
if(gfxInWin0[x]) {
|
||||
mask = inWin0Mask;
|
||||
}
|
||||
}
|
||||
|
||||
if((mask & 4) && (line2[x] < color)) {
|
||||
color = line2[x];
|
||||
top = 0x04;
|
||||
}
|
||||
|
||||
if((mask & 16) && ((u8)(lineOBJ[x]>>24) < (u8)(color >>24))) {
|
||||
color = lineOBJ[x];
|
||||
top = 0x10;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
} else if(mask & 32) {
|
||||
switch((BLDMOD >> 6) & 3) {
|
||||
case 0:
|
||||
break;
|
||||
case 1:
|
||||
{
|
||||
if(top & BLDMOD) {
|
||||
u32 back = backdrop;
|
||||
u8 top2 = 0x20;
|
||||
|
||||
if((mask & 4) && line2[x] < back) {
|
||||
if(top != 0x04) {
|
||||
back = line2[x];
|
||||
top2 = 0x04;
|
||||
}
|
||||
}
|
||||
|
||||
if((mask & 16) && (u8)(lineOBJ[x]>>24) < (u8)(back >> 24)) {
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
lineMix[x] = color;
|
||||
}
|
||||
gfxBG2Changed = 0;
|
||||
gfxLastVCOUNT = VCOUNT;
|
||||
}
|
||||
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
|
||||
// Copyright (C) 1999-2003 Forgotten
|
||||
// Copyright (C) 2004 Forgotten and the VBA development team
|
||||
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; either version 2, or(at your option)
|
||||
// any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software Foundation,
|
||||
// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
#include "GBA.h"
|
||||
#include "Gfx.h"
|
||||
#include "Globals.h"
|
||||
|
||||
void mode4RenderLine()
|
||||
{
|
||||
u16 *palette = (u16 *)paletteRAM;
|
||||
|
||||
if(DISPCNT & 0x0080)
|
||||
{
|
||||
for(int x = 0; x < 240; x++)
|
||||
{
|
||||
lineMix[x] = 0x7fff;
|
||||
}
|
||||
gfxLastVCOUNT = VCOUNT;
|
||||
return;
|
||||
}
|
||||
|
||||
if(layerEnable & 0x400)
|
||||
{
|
||||
int changed = gfxBG2Changed;
|
||||
|
||||
if(gfxLastVCOUNT > VCOUNT)
|
||||
changed = 3;
|
||||
|
||||
gfxDrawRotScreen256(BG2CNT, BG2X_L, BG2X_H, BG2Y_L, BG2Y_H,
|
||||
BG2PA, BG2PB, BG2PC, BG2PD,
|
||||
gfxBG2X, gfxBG2Y, changed,
|
||||
line2);
|
||||
}
|
||||
|
||||
gfxDrawSprites(lineOBJ);
|
||||
|
||||
u32 backdrop = (READ16LE(&palette[0]) | 0x30000000);
|
||||
|
||||
for(int x = 0; x < 240; x++)
|
||||
{
|
||||
u32 color = backdrop;
|
||||
u8 top = 0x20;
|
||||
|
||||
if(line2[x] < color)
|
||||
{
|
||||
color = line2[x];
|
||||
top = 0x04;
|
||||
}
|
||||
|
||||
if((u8)(lineOBJ[x]>>24) < (u8)(color >> 24))
|
||||
{
|
||||
color = lineOBJ[x];
|
||||
top = 0x10;
|
||||
}
|
||||
|
||||
if((top & 0x10) && (color & 0x00010000))
|
||||
{
|
||||
// semi-transparent OBJ
|
||||
u32 back = backdrop;
|
||||
u8 top2 = 0x20;
|
||||
|
||||
if(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;
|
||||
}
|
||||
|
||||
void mode4RenderLineNoWindow()
|
||||
{
|
||||
u16 *palette = (u16 *)paletteRAM;
|
||||
|
||||
if(DISPCNT & 0x0080)
|
||||
{
|
||||
for(int x = 0; x < 240; x++)
|
||||
{
|
||||
lineMix[x] = 0x7fff;
|
||||
}
|
||||
gfxLastVCOUNT = VCOUNT;
|
||||
return;
|
||||
}
|
||||
|
||||
if(layerEnable & 0x400)
|
||||
{
|
||||
int changed = gfxBG2Changed;
|
||||
|
||||
if(gfxLastVCOUNT > VCOUNT)
|
||||
changed = 3;
|
||||
|
||||
gfxDrawRotScreen256(BG2CNT, BG2X_L, BG2X_H, BG2Y_L, BG2Y_H,
|
||||
BG2PA, BG2PB, BG2PC, BG2PD,
|
||||
gfxBG2X, gfxBG2Y, changed,
|
||||
line2);
|
||||
}
|
||||
|
||||
gfxDrawSprites(lineOBJ);
|
||||
|
||||
u32 backdrop = (READ16LE(&palette[0]) | 0x30000000);
|
||||
|
||||
for(int x = 0; x < 240; x++)
|
||||
{
|
||||
u32 color = backdrop;
|
||||
u8 top = 0x20;
|
||||
|
||||
if(line2[x] < color)
|
||||
{
|
||||
color = line2[x];
|
||||
top = 0x04;
|
||||
}
|
||||
|
||||
if((u8)(lineOBJ[x]>>24) < (u8)(color >> 24))
|
||||
{
|
||||
color = lineOBJ[x];
|
||||
top = 0x10;
|
||||
}
|
||||
|
||||
if(!(color & 0x00010000))
|
||||
{
|
||||
switch((BLDMOD >> 6) & 3)
|
||||
{
|
||||
case 0:
|
||||
break;
|
||||
case 1:
|
||||
{
|
||||
if(top & BLDMOD)
|
||||
{
|
||||
u32 back = backdrop;
|
||||
u8 top2 = 0x20;
|
||||
|
||||
if(line2[x] < back)
|
||||
{
|
||||
if(top != 0x04)
|
||||
{
|
||||
back = line2[x];
|
||||
top2 = 0x04;
|
||||
}
|
||||
}
|
||||
|
||||
if((u8)(lineOBJ[x]>>24) < (u8)(back >> 24))
|
||||
{
|
||||
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(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;
|
||||
}
|
||||
|
||||
void mode4RenderLineAll()
|
||||
{
|
||||
u16 *palette = (u16 *)paletteRAM;
|
||||
|
||||
if(DISPCNT & 0x0080)
|
||||
{
|
||||
for(int x = 0; x < 240; x++)
|
||||
{
|
||||
lineMix[x] = 0x7fff;
|
||||
}
|
||||
gfxLastVCOUNT = VCOUNT;
|
||||
return;
|
||||
}
|
||||
|
||||
bool inWindow0 = false;
|
||||
bool inWindow1 = false;
|
||||
|
||||
if(layerEnable & 0x2000)
|
||||
{
|
||||
u8 v0 = WIN0V >> 8;
|
||||
u8 v1 = WIN0V & 255;
|
||||
inWindow0 = ((v0 == v1) && (v0 >= 0xe8));
|
||||
if(v1 >= v0)
|
||||
inWindow0 |= (VCOUNT >= v0 && VCOUNT < v1);
|
||||
else
|
||||
inWindow0 |= (VCOUNT >= v0 || VCOUNT < v1);
|
||||
}
|
||||
if(layerEnable & 0x4000)
|
||||
{
|
||||
u8 v0 = WIN1V >> 8;
|
||||
u8 v1 = WIN1V & 255;
|
||||
inWindow1 = ((v0 == v1) && (v0 >= 0xe8));
|
||||
if(v1 >= v0)
|
||||
inWindow1 |= (VCOUNT >= v0 && VCOUNT < v1);
|
||||
else
|
||||
inWindow1 |= (VCOUNT >= v0 || VCOUNT < v1);
|
||||
}
|
||||
|
||||
if(layerEnable & 0x400)
|
||||
{
|
||||
int changed = gfxBG2Changed;
|
||||
|
||||
if(gfxLastVCOUNT > VCOUNT)
|
||||
changed = 3;
|
||||
|
||||
gfxDrawRotScreen256(BG2CNT, BG2X_L, BG2X_H, BG2Y_L, BG2Y_H,
|
||||
BG2PA, BG2PB, BG2PC, BG2PD,
|
||||
gfxBG2X, gfxBG2Y, changed,
|
||||
line2);
|
||||
}
|
||||
|
||||
gfxDrawSprites(lineOBJ);
|
||||
gfxDrawOBJWin(lineOBJWin);
|
||||
|
||||
u32 backdrop = (READ16LE(&palette[0]) | 0x30000000);
|
||||
|
||||
u8 inWin0Mask = WININ & 0xFF;
|
||||
u8 inWin1Mask = WININ >> 8;
|
||||
u8 outMask = WINOUT & 0xFF;
|
||||
|
||||
for(int x = 0; x < 240; x++)
|
||||
{
|
||||
u32 color = backdrop;
|
||||
u8 top = 0x20;
|
||||
u8 mask = outMask;
|
||||
|
||||
if(!(lineOBJWin[x] & 0x80000000))
|
||||
{
|
||||
mask = WINOUT >> 8;
|
||||
}
|
||||
|
||||
if(inWindow1)
|
||||
{
|
||||
if(gfxInWin1[x])
|
||||
mask = inWin1Mask;
|
||||
}
|
||||
|
||||
if(inWindow0)
|
||||
{
|
||||
if(gfxInWin0[x])
|
||||
{
|
||||
mask = inWin0Mask;
|
||||
}
|
||||
}
|
||||
|
||||
if((mask & 4) && (line2[x] < color))
|
||||
{
|
||||
color = line2[x];
|
||||
top = 0x04;
|
||||
}
|
||||
|
||||
if((mask & 16) && ((u8)(lineOBJ[x]>>24) < (u8)(color >>24)))
|
||||
{
|
||||
color = lineOBJ[x];
|
||||
top = 0x10;
|
||||
}
|
||||
|
||||
if(mask & 32)
|
||||
{
|
||||
if(!(color & 0x00010000))
|
||||
{
|
||||
switch((BLDMOD >> 6) & 3)
|
||||
{
|
||||
case 0:
|
||||
break;
|
||||
case 1:
|
||||
{
|
||||
if(top & BLDMOD)
|
||||
{
|
||||
u32 back = backdrop;
|
||||
u8 top2 = 0x20;
|
||||
|
||||
if((mask & 4) && line2[x] < back)
|
||||
{
|
||||
if(top != 0x04)
|
||||
{
|
||||
back = line2[x];
|
||||
top2 = 0x04;
|
||||
}
|
||||
}
|
||||
|
||||
if((mask & 16) && (u8)(lineOBJ[x]>>24) < (u8)(back >> 24))
|
||||
{
|
||||
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(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.
|
||||
// Copyright (C) 1999-2003 Forgotten
|
||||
// Copyright (C) 2004 Forgotten and the VBA development team
|
||||
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; either version 2, or(at your option)
|
||||
// any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software Foundation,
|
||||
// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
#include "agb/GBA.h"
|
||||
#include "Globals.h"
|
||||
#include "agb/GBAGfx.h"
|
||||
|
||||
void mode5RenderLine()
|
||||
{
|
||||
if(DISPCNT & 0x0080) {
|
||||
for(int x = 0; x < 240; x++) {
|
||||
lineMix[x] = 0x7fff;
|
||||
}
|
||||
gfxLastVCOUNT = VCOUNT;
|
||||
return;
|
||||
}
|
||||
|
||||
u16 *palette = (u16 *)paletteRAM;
|
||||
|
||||
if(layerEnable & 0x0400) {
|
||||
int changed = gfxBG2Changed;
|
||||
|
||||
if(gfxLastVCOUNT > VCOUNT)
|
||||
changed = 3;
|
||||
|
||||
gfxDrawRotScreen16Bit160(BG2CNT, BG2X_L, BG2X_H,
|
||||
BG2Y_L, BG2Y_H, BG2PA, BG2PB,
|
||||
BG2PC, BG2PD,
|
||||
gfxBG2X, gfxBG2Y, changed,
|
||||
line2);
|
||||
}
|
||||
|
||||
gfxDrawSprites(lineOBJ);
|
||||
|
||||
u32 background = (READ16LE(&palette[0]) | 0x30000000);
|
||||
|
||||
for(int x = 0; x < 240; x++) {
|
||||
u32 color = background;
|
||||
u8 top = 0x20;
|
||||
|
||||
if(line2[x] < color) {
|
||||
color = line2[x];
|
||||
top = 0x04;
|
||||
}
|
||||
|
||||
if((u8)(lineOBJ[x]>>24) < (u8)(color >>24)) {
|
||||
color = lineOBJ[x];
|
||||
top = 0x10;
|
||||
}
|
||||
|
||||
if((top & 0x10) && (color & 0x00010000)) {
|
||||
// semi-transparent OBJ
|
||||
u32 back = background;
|
||||
u8 top2 = 0x20;
|
||||
|
||||
if(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;
|
||||
}
|
||||
|
||||
void mode5RenderLineNoWindow()
|
||||
{
|
||||
if(DISPCNT & 0x0080) {
|
||||
for(int x = 0; x < 240; x++) {
|
||||
lineMix[x] = 0x7fff;
|
||||
}
|
||||
gfxLastVCOUNT = VCOUNT;
|
||||
return;
|
||||
}
|
||||
|
||||
u16 *palette = (u16 *)paletteRAM;
|
||||
|
||||
if(layerEnable & 0x0400) {
|
||||
int changed = gfxBG2Changed;
|
||||
|
||||
if(gfxLastVCOUNT > VCOUNT)
|
||||
changed = 3;
|
||||
|
||||
gfxDrawRotScreen16Bit160(BG2CNT, BG2X_L, BG2X_H,
|
||||
BG2Y_L, BG2Y_H, BG2PA, BG2PB,
|
||||
BG2PC, BG2PD,
|
||||
gfxBG2X, gfxBG2Y, changed,
|
||||
line2);
|
||||
}
|
||||
|
||||
gfxDrawSprites(lineOBJ);
|
||||
|
||||
u32 background = ( READ16LE(&palette[0]) | 0x30000000);
|
||||
|
||||
for(int x = 0; x < 240; x++) {
|
||||
u32 color = background;
|
||||
u8 top = 0x20;
|
||||
|
||||
if(line2[x] < color) {
|
||||
color = line2[x];
|
||||
top = 0x04;
|
||||
}
|
||||
|
||||
if((u8)(lineOBJ[x]>>24) < (u8)(color >>24)) {
|
||||
color = lineOBJ[x];
|
||||
top = 0x10;
|
||||
}
|
||||
|
||||
if(!(color & 0x00010000)) {
|
||||
switch((BLDMOD >> 6) & 3) {
|
||||
case 0:
|
||||
break;
|
||||
case 1:
|
||||
{
|
||||
if(top & BLDMOD) {
|
||||
u32 back = background;
|
||||
u8 top2 = 0x20;
|
||||
|
||||
if(line2[x] < back) {
|
||||
if(top != 0x04) {
|
||||
back = line2[x];
|
||||
top2 = 0x04;
|
||||
}
|
||||
}
|
||||
|
||||
if((u8)(lineOBJ[x]>>24) < (u8)(back >> 24)) {
|
||||
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 = background;
|
||||
u8 top2 = 0x20;
|
||||
|
||||
if(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;
|
||||
}
|
||||
|
||||
void mode5RenderLineAll()
|
||||
{
|
||||
if(DISPCNT & 0x0080) {
|
||||
for(int x = 0; x < 240; x++) {
|
||||
lineMix[x] = 0x7fff;
|
||||
}
|
||||
gfxLastVCOUNT = VCOUNT;
|
||||
return;
|
||||
}
|
||||
|
||||
u16 *palette = (u16 *)paletteRAM;
|
||||
|
||||
if(layerEnable & 0x0400) {
|
||||
int changed = gfxBG2Changed;
|
||||
|
||||
if(gfxLastVCOUNT > VCOUNT)
|
||||
changed = 3;
|
||||
|
||||
gfxDrawRotScreen16Bit160(BG2CNT, BG2X_L, BG2X_H,
|
||||
BG2Y_L, BG2Y_H, BG2PA, BG2PB,
|
||||
BG2PC, BG2PD,
|
||||
gfxBG2X, gfxBG2Y, changed,
|
||||
line2);
|
||||
}
|
||||
|
||||
gfxDrawSprites(lineOBJ);
|
||||
gfxDrawOBJWin(lineOBJWin);
|
||||
|
||||
bool inWindow0 = false;
|
||||
bool inWindow1 = false;
|
||||
|
||||
if(layerEnable & 0x2000) {
|
||||
u8 v0 = WIN0V >> 8;
|
||||
u8 v1 = WIN0V & 255;
|
||||
inWindow0 = ((v0 == v1) && (v0 >= 0xe8));
|
||||
if(v1 >= v0)
|
||||
inWindow0 |= (VCOUNT >= v0 && VCOUNT < v1);
|
||||
else
|
||||
inWindow0 |= (VCOUNT >= v0 || VCOUNT < v1);
|
||||
}
|
||||
if(layerEnable & 0x4000) {
|
||||
u8 v0 = WIN1V >> 8;
|
||||
u8 v1 = WIN1V & 255;
|
||||
inWindow1 = ((v0 == v1) && (v0 >= 0xe8));
|
||||
if(v1 >= v0)
|
||||
inWindow1 |= (VCOUNT >= v0 && VCOUNT < v1);
|
||||
else
|
||||
inWindow1 |= (VCOUNT >= v0 || VCOUNT < v1);
|
||||
}
|
||||
|
||||
u8 inWin0Mask = WININ & 0xFF;
|
||||
u8 inWin1Mask = WININ >> 8;
|
||||
u8 outMask = WINOUT & 0xFF;
|
||||
|
||||
u32 background = (READ16LE(&palette[0]) | 0x30000000);
|
||||
|
||||
for(int x = 0; x < 240; x++) {
|
||||
u32 color = background;
|
||||
u8 top = 0x20;
|
||||
u8 mask = outMask;
|
||||
|
||||
if(!(lineOBJWin[x] & 0x80000000)) {
|
||||
mask = WINOUT >> 8;
|
||||
}
|
||||
|
||||
if(inWindow1) {
|
||||
if(gfxInWin1[x])
|
||||
mask = inWin1Mask;
|
||||
}
|
||||
|
||||
if(inWindow0) {
|
||||
if(gfxInWin0[x]) {
|
||||
mask = inWin0Mask;
|
||||
}
|
||||
}
|
||||
|
||||
if((mask & 4) && (line2[x] < color)) {
|
||||
color = line2[x];
|
||||
top = 0x04;
|
||||
}
|
||||
|
||||
if((mask & 16) && ((u8)(lineOBJ[x]>>24) < (u8)(color >>24))) {
|
||||
color = lineOBJ[x];
|
||||
top = 0x10;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
} else if(mask & 32) {
|
||||
switch((BLDMOD >> 6) & 3) {
|
||||
case 0:
|
||||
break;
|
||||
case 1:
|
||||
{
|
||||
if(top & BLDMOD) {
|
||||
u32 back = background;
|
||||
u8 top2 = 0x20;
|
||||
|
||||
if((mask & 4) && line2[x] < back) {
|
||||
if(top != 0x04) {
|
||||
back = line2[x];
|
||||
top2 = 0x04;
|
||||
}
|
||||
}
|
||||
|
||||
if((mask & 16) && (u8)(lineOBJ[x]>>24) < (u8)(back >> 24)) {
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
lineMix[x] = color;
|
||||
}
|
||||
gfxBG2Changed = 0;
|
||||
gfxLastVCOUNT = VCOUNT;
|
||||
}
|
||||
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
|
||||
// Copyright (C) 1999-2003 Forgotten
|
||||
// Copyright (C) 2004 Forgotten and the VBA development team
|
||||
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; either version 2, or(at your option)
|
||||
// any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software Foundation,
|
||||
// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
#include "GBA.h"
|
||||
#include "Globals.h"
|
||||
#include "Gfx.h"
|
||||
|
||||
void mode5RenderLine()
|
||||
{
|
||||
if(DISPCNT & 0x0080)
|
||||
{
|
||||
for(int x = 0; x < 240; x++)
|
||||
{
|
||||
lineMix[x] = 0x7fff;
|
||||
}
|
||||
gfxLastVCOUNT = VCOUNT;
|
||||
return;
|
||||
}
|
||||
|
||||
u16 *palette = (u16 *)paletteRAM;
|
||||
|
||||
if(layerEnable & 0x0400)
|
||||
{
|
||||
int changed = gfxBG2Changed;
|
||||
|
||||
if(gfxLastVCOUNT > VCOUNT)
|
||||
changed = 3;
|
||||
|
||||
gfxDrawRotScreen16Bit160(BG2CNT, BG2X_L, BG2X_H,
|
||||
BG2Y_L, BG2Y_H, BG2PA, BG2PB,
|
||||
BG2PC, BG2PD,
|
||||
gfxBG2X, gfxBG2Y, changed,
|
||||
line2);
|
||||
}
|
||||
|
||||
gfxDrawSprites(lineOBJ);
|
||||
|
||||
u32 background = (READ16LE(&palette[0]) | 0x30000000);
|
||||
|
||||
for(int x = 0; x < 240; x++)
|
||||
{
|
||||
u32 color = background;
|
||||
u8 top = 0x20;
|
||||
|
||||
if(line2[x] < color)
|
||||
{
|
||||
color = line2[x];
|
||||
top = 0x04;
|
||||
}
|
||||
|
||||
if((u8)(lineOBJ[x]>>24) < (u8)(color >>24))
|
||||
{
|
||||
color = lineOBJ[x];
|
||||
top = 0x10;
|
||||
}
|
||||
|
||||
if((top & 0x10) && (color & 0x00010000))
|
||||
{
|
||||
// semi-transparent OBJ
|
||||
u32 back = background;
|
||||
u8 top2 = 0x20;
|
||||
|
||||
if(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;
|
||||
}
|
||||
|
||||
void mode5RenderLineNoWindow()
|
||||
{
|
||||
if(DISPCNT & 0x0080)
|
||||
{
|
||||
for(int x = 0; x < 240; x++)
|
||||
{
|
||||
lineMix[x] = 0x7fff;
|
||||
}
|
||||
gfxLastVCOUNT = VCOUNT;
|
||||
return;
|
||||
}
|
||||
|
||||
u16 *palette = (u16 *)paletteRAM;
|
||||
|
||||
if(layerEnable & 0x0400)
|
||||
{
|
||||
int changed = gfxBG2Changed;
|
||||
|
||||
if(gfxLastVCOUNT > VCOUNT)
|
||||
changed = 3;
|
||||
|
||||
gfxDrawRotScreen16Bit160(BG2CNT, BG2X_L, BG2X_H,
|
||||
BG2Y_L, BG2Y_H, BG2PA, BG2PB,
|
||||
BG2PC, BG2PD,
|
||||
gfxBG2X, gfxBG2Y, changed,
|
||||
line2);
|
||||
}
|
||||
|
||||
gfxDrawSprites(lineOBJ);
|
||||
|
||||
u32 background = ( READ16LE(&palette[0]) | 0x30000000);
|
||||
|
||||
for(int x = 0; x < 240; x++)
|
||||
{
|
||||
u32 color = background;
|
||||
u8 top = 0x20;
|
||||
|
||||
if(line2[x] < color)
|
||||
{
|
||||
color = line2[x];
|
||||
top = 0x04;
|
||||
}
|
||||
|
||||
if((u8)(lineOBJ[x]>>24) < (u8)(color >>24))
|
||||
{
|
||||
color = lineOBJ[x];
|
||||
top = 0x10;
|
||||
}
|
||||
|
||||
if(!(color & 0x00010000))
|
||||
{
|
||||
switch((BLDMOD >> 6) & 3)
|
||||
{
|
||||
case 0:
|
||||
break;
|
||||
case 1:
|
||||
{
|
||||
if(top & BLDMOD)
|
||||
{
|
||||
u32 back = background;
|
||||
u8 top2 = 0x20;
|
||||
|
||||
if(line2[x] < back)
|
||||
{
|
||||
if(top != 0x04)
|
||||
{
|
||||
back = line2[x];
|
||||
top2 = 0x04;
|
||||
}
|
||||
}
|
||||
|
||||
if((u8)(lineOBJ[x]>>24) < (u8)(back >> 24))
|
||||
{
|
||||
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 = background;
|
||||
u8 top2 = 0x20;
|
||||
|
||||
if(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;
|
||||
}
|
||||
|
||||
void mode5RenderLineAll()
|
||||
{
|
||||
if(DISPCNT & 0x0080)
|
||||
{
|
||||
for(int x = 0; x < 240; x++)
|
||||
{
|
||||
lineMix[x] = 0x7fff;
|
||||
}
|
||||
gfxLastVCOUNT = VCOUNT;
|
||||
return;
|
||||
}
|
||||
|
||||
u16 *palette = (u16 *)paletteRAM;
|
||||
|
||||
if(layerEnable & 0x0400)
|
||||
{
|
||||
int changed = gfxBG2Changed;
|
||||
|
||||
if(gfxLastVCOUNT > VCOUNT)
|
||||
changed = 3;
|
||||
|
||||
gfxDrawRotScreen16Bit160(BG2CNT, BG2X_L, BG2X_H,
|
||||
BG2Y_L, BG2Y_H, BG2PA, BG2PB,
|
||||
BG2PC, BG2PD,
|
||||
gfxBG2X, gfxBG2Y, changed,
|
||||
line2);
|
||||
}
|
||||
|
||||
gfxDrawSprites(lineOBJ);
|
||||
gfxDrawOBJWin(lineOBJWin);
|
||||
|
||||
bool inWindow0 = false;
|
||||
bool inWindow1 = false;
|
||||
|
||||
if(layerEnable & 0x2000)
|
||||
{
|
||||
u8 v0 = WIN0V >> 8;
|
||||
u8 v1 = WIN0V & 255;
|
||||
inWindow0 = ((v0 == v1) && (v0 >= 0xe8));
|
||||
if(v1 >= v0)
|
||||
inWindow0 |= (VCOUNT >= v0 && VCOUNT < v1);
|
||||
else
|
||||
inWindow0 |= (VCOUNT >= v0 || VCOUNT < v1);
|
||||
}
|
||||
if(layerEnable & 0x4000)
|
||||
{
|
||||
u8 v0 = WIN1V >> 8;
|
||||
u8 v1 = WIN1V & 255;
|
||||
inWindow1 = ((v0 == v1) && (v0 >= 0xe8));
|
||||
if(v1 >= v0)
|
||||
inWindow1 |= (VCOUNT >= v0 && VCOUNT < v1);
|
||||
else
|
||||
inWindow1 |= (VCOUNT >= v0 || VCOUNT < v1);
|
||||
}
|
||||
|
||||
u8 inWin0Mask = WININ & 0xFF;
|
||||
u8 inWin1Mask = WININ >> 8;
|
||||
u8 outMask = WINOUT & 0xFF;
|
||||
|
||||
u32 background = (READ16LE(&palette[0]) | 0x30000000);
|
||||
|
||||
for(int x = 0; x < 240; x++)
|
||||
{
|
||||
u32 color = background;
|
||||
u8 top = 0x20;
|
||||
u8 mask = outMask;
|
||||
|
||||
if(!(lineOBJWin[x] & 0x80000000))
|
||||
{
|
||||
mask = WINOUT >> 8;
|
||||
}
|
||||
|
||||
if(inWindow1)
|
||||
{
|
||||
if(gfxInWin1[x])
|
||||
mask = inWin1Mask;
|
||||
}
|
||||
|
||||
if(inWindow0)
|
||||
{
|
||||
if(gfxInWin0[x])
|
||||
{
|
||||
mask = inWin0Mask;
|
||||
}
|
||||
}
|
||||
|
||||
if((mask & 4) && (line2[x] < color))
|
||||
{
|
||||
color = line2[x];
|
||||
top = 0x04;
|
||||
}
|
||||
|
||||
if((mask & 16) && ((u8)(lineOBJ[x]>>24) < (u8)(color >>24)))
|
||||
{
|
||||
color = lineOBJ[x];
|
||||
top = 0x10;
|
||||
}
|
||||
|
||||
if(mask & 32)
|
||||
{
|
||||
if(!(color & 0x00010000))
|
||||
{
|
||||
switch((BLDMOD >> 6) & 3)
|
||||
{
|
||||
case 0:
|
||||
break;
|
||||
case 1:
|
||||
{
|
||||
if(top & BLDMOD)
|
||||
{
|
||||
u32 back = background;
|
||||
u8 top2 = 0x20;
|
||||
|
||||
if((mask & 4) && line2[x] < back)
|
||||
{
|
||||
if(top != 0x04)
|
||||
{
|
||||
back = line2[x];
|
||||
top2 = 0x04;
|
||||
}
|
||||
}
|
||||
|
||||
if((mask & 16) && (u8)(lineOBJ[x]>>24) < (u8)(back >> 24))
|
||||
{
|
||||
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 = 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++ -*-
|
||||
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
|
||||
// Copyright (C) 1999-2003 Forgotten
|
||||
// Copyright (C) 2004 Forgotten and the VBA development team
|
||||
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; either version 2, or(at your option)
|
||||
// any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software Foundation,
|
||||
// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
#define N_(String) (String)
|
||||
|
||||
#define MSG_UNSUPPORTED_VBA_SGM 1
|
||||
#define MSG_CANNOT_LOAD_SGM 2
|
||||
#define MSG_SAVE_GAME_NOT_USING_BIOS 3
|
||||
#define MSG_SAVE_GAME_USING_BIOS 4
|
||||
#define MSG_UNSUPPORTED_SAVE_TYPE 5
|
||||
#define MSG_CANNOT_OPEN_FILE 6
|
||||
#define MSG_BAD_ZIP_FILE 7
|
||||
#define MSG_NO_IMAGE_ON_ZIP 8
|
||||
#define MSG_ERROR_OPENING_IMAGE 9
|
||||
#define MSG_ERROR_READING_IMAGE 10
|
||||
#define MSG_UNSUPPORTED_BIOS_FUNCTION 11
|
||||
#define MSG_INVALID_BIOS_FILE_SIZE 12
|
||||
#define MSG_INVALID_CHEAT_CODE 13
|
||||
#define MSG_UNKNOWN_ARM_OPCODE 14
|
||||
#define MSG_UNKNOWN_THUMB_OPCODE 15
|
||||
#define MSG_ERROR_CREATING_FILE 16
|
||||
#define MSG_FAILED_TO_READ_SGM 17
|
||||
#define MSG_FAILED_TO_READ_RTC 18
|
||||
#define MSG_UNSUPPORTED_VB_SGM 19
|
||||
#define MSG_CANNOT_LOAD_SGM_FOR 20
|
||||
#define MSG_ERROR_OPENING_IMAGE_FROM 21
|
||||
#define MSG_ERROR_READING_IMAGE_FROM 22
|
||||
#define MSG_UNSUPPORTED_ROM_SIZE 23
|
||||
#define MSG_UNSUPPORTED_RAM_SIZE 24
|
||||
#define MSG_UNKNOWN_CARTRIDGE_TYPE 25
|
||||
#define MSG_MAXIMUM_NUMBER_OF_CHEATS 26
|
||||
#define MSG_INVALID_GAMESHARK_CODE 27
|
||||
#define MSG_INVALID_GAMEGENIE_CODE 28
|
||||
#define MSG_INVALID_CHEAT_TO_REMOVE 29
|
||||
#define MSG_INVALID_CHEAT_CODE_ADDRESS 30
|
||||
#define MSG_UNSUPPORTED_CHEAT_LIST_VERSION 31
|
||||
#define MSG_UNSUPPORTED_CHEAT_LIST_TYPE 32
|
||||
#define MSG_INVALID_GSA_CODE 33
|
||||
#define MSG_CANNOT_IMPORT_SNAPSHOT_FOR 34
|
||||
#define MSG_UNSUPPORTED_SNAPSHOT_FILE 35
|
||||
#define MSG_UNSUPPORTED_ARM_MODE 36
|
||||
#define MSG_UNSUPPORTED_CODE_FILE 37
|
||||
#define MSG_GBA_CODE_WARNING 38
|
||||
#define MSG_INVALID_CBA_CODE 39
|
||||
#define MSG_CBA_CODE_WARNING 40
|
||||
#define MSG_OUT_OF_MEMORY 41
|
||||
#define MSG_WRONG_GAMESHARK_CODE 42
|
||||
#define MSG_UNSUPPORTED_GAMESHARK_CODE 43
|
||||
// -*- C++ -*-
|
||||
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
|
||||
// Copyright (C) 1999-2003 Forgotten
|
||||
// Copyright (C) 2004 Forgotten and the VBA development team
|
||||
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; either version 2, or(at your option)
|
||||
// any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software Foundation,
|
||||
// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
#define N_(String) (String)
|
||||
|
||||
#define MSG_UNSUPPORTED_VBA_SGM 1
|
||||
#define MSG_CANNOT_LOAD_SGM 2
|
||||
#define MSG_SAVE_GAME_NOT_USING_BIOS 3
|
||||
#define MSG_SAVE_GAME_USING_BIOS 4
|
||||
#define MSG_UNSUPPORTED_SAVE_TYPE 5
|
||||
#define MSG_CANNOT_OPEN_FILE 6
|
||||
#define MSG_BAD_ZIP_FILE 7
|
||||
#define MSG_NO_IMAGE_ON_ZIP 8
|
||||
#define MSG_ERROR_OPENING_IMAGE 9
|
||||
#define MSG_ERROR_READING_IMAGE 10
|
||||
#define MSG_UNSUPPORTED_BIOS_FUNCTION 11
|
||||
#define MSG_INVALID_BIOS_FILE_SIZE 12
|
||||
#define MSG_INVALID_CHEAT_CODE 13
|
||||
#define MSG_UNKNOWN_ARM_OPCODE 14
|
||||
#define MSG_UNKNOWN_THUMB_OPCODE 15
|
||||
#define MSG_ERROR_CREATING_FILE 16
|
||||
#define MSG_FAILED_TO_READ_SGM 17
|
||||
#define MSG_FAILED_TO_READ_RTC 18
|
||||
#define MSG_UNSUPPORTED_VB_SGM 19
|
||||
#define MSG_CANNOT_LOAD_SGM_FOR 20
|
||||
#define MSG_ERROR_OPENING_IMAGE_FROM 21
|
||||
#define MSG_ERROR_READING_IMAGE_FROM 22
|
||||
#define MSG_UNSUPPORTED_ROM_SIZE 23
|
||||
#define MSG_UNSUPPORTED_RAM_SIZE 24
|
||||
#define MSG_UNKNOWN_CARTRIDGE_TYPE 25
|
||||
#define MSG_MAXIMUM_NUMBER_OF_CHEATS 26
|
||||
#define MSG_INVALID_GAMESHARK_CODE 27
|
||||
#define MSG_INVALID_GAMEGENIE_CODE 28
|
||||
#define MSG_INVALID_CHEAT_TO_REMOVE 29
|
||||
#define MSG_INVALID_CHEAT_CODE_ADDRESS 30
|
||||
#define MSG_UNSUPPORTED_CHEAT_LIST_VERSION 31
|
||||
#define MSG_UNSUPPORTED_CHEAT_LIST_TYPE 32
|
||||
#define MSG_INVALID_GSA_CODE 33
|
||||
#define MSG_CANNOT_IMPORT_SNAPSHOT_FOR 34
|
||||
#define MSG_UNSUPPORTED_SNAPSHOT_FILE 35
|
||||
#define MSG_UNSUPPORTED_ARM_MODE 36
|
||||
#define MSG_UNSUPPORTED_CODE_FILE 37
|
||||
#define MSG_GBA_CODE_WARNING 38
|
||||
#define MSG_INVALID_CBA_CODE 39
|
||||
#define MSG_CBA_CODE_WARNING 40
|
||||
#define MSG_OUT_OF_MEMORY 41
|
||||
|
@ -1,75 +1,77 @@
|
||||
// -*- 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_PORT_H
|
||||
#define VBA_PORT_H
|
||||
|
||||
// swaps a 16-bit value
|
||||
static inline u16 swap16(u16 v)
|
||||
{
|
||||
return (v<<8)|(v>>8);
|
||||
}
|
||||
|
||||
// swaps a 32-bit value
|
||||
static inline u32 swap32(u32 v)
|
||||
{
|
||||
return (v<<24)|((v<<8)&0xff0000)|((v>>8)&0xff00)|(v>>24);
|
||||
}
|
||||
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
#if defined(__GNUC__) && defined(__ppc__)
|
||||
|
||||
#define READ16LE(base) \
|
||||
({ unsigned short lhbrxResult; \
|
||||
__asm__ ("lhbrx %0, 0, %1" : "=r" (lhbrxResult) : "r" (base) : "memory"); \
|
||||
lhbrxResult; })
|
||||
|
||||
#define READ32LE(base) \
|
||||
({ unsigned long lwbrxResult; \
|
||||
__asm__ ("lwbrx %0, 0, %1" : "=r" (lwbrxResult) : "r" (base) : "memory"); \
|
||||
lwbrxResult; })
|
||||
|
||||
#define WRITE16LE(base, value) \
|
||||
__asm__ ("sthbrx %0, 0, %1" : : "r" (value), "r" (base) : "memory")
|
||||
|
||||
#define WRITE32LE(base, value) \
|
||||
__asm__ ("stwbrx %0, 0, %1" : : "r" (value), "r" (base) : "memory")
|
||||
|
||||
#else
|
||||
#define READ16LE(x) \
|
||||
swap16(*((u16 *)(x)))
|
||||
#define READ32LE(x) \
|
||||
swap32(*((u32 *)(x)))
|
||||
#define WRITE16LE(x,v) \
|
||||
*((u16 *)x) = swap16((v))
|
||||
#define WRITE32LE(x,v) \
|
||||
*((u32 *)x) = swap32((v))
|
||||
#endif
|
||||
#else
|
||||
#define READ16LE(x) \
|
||||
*((u16 *)x)
|
||||
#define READ32LE(x) \
|
||||
*((u32 *)x)
|
||||
#define WRITE16LE(x,v) \
|
||||
*((u16 *)x) = (v)
|
||||
#define WRITE32LE(x,v) \
|
||||
*((u32 *)x) = (v)
|
||||
#endif
|
||||
|
||||
#endif
|
||||
// -*- C++ -*-
|
||||
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
|
||||
// Copyright (C) 1999-2003 Forgotten
|
||||
// Copyright (C) 2004 Forgotten and the VBA development team
|
||||
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; either version 2, or(at your option)
|
||||
// any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software Foundation,
|
||||
// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
#ifndef VBA_PORT_H
|
||||
#define VBA_PORT_H
|
||||
|
||||
// swaps a 16-bit value
|
||||
static inline u16 swap16(u16 v)
|
||||
{
|
||||
return (v<<8)|(v>>8);
|
||||
}
|
||||
|
||||
// swaps a 32-bit value
|
||||
static inline u32 swap32(u32 v)
|
||||
{
|
||||
return (v<<24)|((v<<8)&0xff0000)|((v>>8)&0xff00)|(v>>24);
|
||||
}
|
||||
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
#define __ppc__
|
||||
|
||||
#if defined(__GNUC__) && defined(__ppc__)
|
||||
|
||||
#define READ16LE(base) \
|
||||
({ unsigned short lhbrxResult; \
|
||||
__asm__ ("lhbrx %0, 0, %1" : "=r" (lhbrxResult) : "r" (base) : "memory"); \
|
||||
lhbrxResult; })
|
||||
|
||||
#define READ32LE(base) \
|
||||
({ unsigned long lwbrxResult; \
|
||||
__asm__ ("lwbrx %0, 0, %1" : "=r" (lwbrxResult) : "r" (base) : "memory"); \
|
||||
lwbrxResult; })
|
||||
|
||||
#define WRITE16LE(base, value) \
|
||||
__asm__ ("sthbrx %0, 0, %1" : : "r" (value), "r" (base) : "memory")
|
||||
|
||||
#define WRITE32LE(base, value) \
|
||||
__asm__ ("stwbrx %0, 0, %1" : : "r" (value), "r" (base) : "memory")
|
||||
|
||||
#else
|
||||
#define READ16LE(x) \
|
||||
swap16(*((u16 *)(x)))
|
||||
#define READ32LE(x) \
|
||||
swap32(*((u32 *)(x)))
|
||||
#define WRITE16LE(x,v) \
|
||||
*((u16 *)x) = swap16((v))
|
||||
#define WRITE32LE(x,v) \
|
||||
*((u32 *)x) = swap32((v))
|
||||
#endif
|
||||
#else
|
||||
#define READ16LE(x) \
|
||||
*((u16 *)x)
|
||||
#define READ32LE(x) \
|
||||
*((u32 *)x)
|
||||
#define WRITE16LE(x,v) \
|
||||
*((u16 *)x) = (v)
|
||||
#define WRITE32LE(x,v) \
|
||||
*((u32 *)x) = (v)
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
@ -1,230 +1,245 @@
|
||||
// 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.
|
||||
|
||||
#include "System.h"
|
||||
#include "agb/GBA.h"
|
||||
#include "Globals.h"
|
||||
#include "Port.h"
|
||||
#include "Util.h"
|
||||
#include "NLS.h"
|
||||
#include "vmmem.h"
|
||||
|
||||
#include <time.h>
|
||||
#include <string.h>
|
||||
|
||||
enum RTCSTATE { IDLE, COMMAND, DATA, READDATA };
|
||||
|
||||
typedef struct {
|
||||
u8 byte0;
|
||||
u8 byte1;
|
||||
u8 byte2;
|
||||
u8 command;
|
||||
int dataLen;
|
||||
int bits;
|
||||
RTCSTATE state;
|
||||
u8 data[12];
|
||||
// reserved variables for future
|
||||
u8 reserved[12];
|
||||
bool reserved2;
|
||||
u32 reserved3;
|
||||
} RTCCLOCKDATA;
|
||||
|
||||
static RTCCLOCKDATA rtcClockData;
|
||||
static bool rtcEnabled = false;
|
||||
|
||||
void rtcEnable(bool e)
|
||||
{
|
||||
rtcEnabled = e;
|
||||
}
|
||||
|
||||
bool rtcIsEnabled()
|
||||
{
|
||||
return rtcEnabled;
|
||||
}
|
||||
|
||||
u16 rtcRead(u32 address)
|
||||
{
|
||||
if(rtcEnabled) {
|
||||
switch(address){
|
||||
case 0x80000c8:
|
||||
return rtcClockData.byte2;
|
||||
break;
|
||||
case 0x80000c6:
|
||||
return rtcClockData.byte1;
|
||||
break;
|
||||
case 0x80000c4:
|
||||
return rtcClockData.byte0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
#ifdef USE_VM
|
||||
return VMRead16( address & 0x1FFFFFE );
|
||||
#else
|
||||
return READ16LE((&rom[address & 0x1FFFFFE]));
|
||||
#endif
|
||||
}
|
||||
|
||||
static u8 toBCD(u8 value)
|
||||
{
|
||||
value = value % 100;
|
||||
int l = value % 10;
|
||||
int h = value / 10;
|
||||
return h * 16 + l;
|
||||
}
|
||||
|
||||
bool rtcWrite(u32 address, u16 value)
|
||||
{
|
||||
if(!rtcEnabled)
|
||||
return false;
|
||||
|
||||
if(address == 0x80000c8) {
|
||||
rtcClockData.byte2 = (u8)value; // enable ?
|
||||
} else if(address == 0x80000c6) {
|
||||
rtcClockData.byte1 = (u8)value; // read/write
|
||||
} else if(address == 0x80000c4) {
|
||||
if(rtcClockData.byte2 & 1) {
|
||||
if(rtcClockData.state == IDLE && rtcClockData.byte0 == 1 && value == 5) {
|
||||
rtcClockData.state = COMMAND;
|
||||
rtcClockData.bits = 0;
|
||||
rtcClockData.command = 0;
|
||||
} else if(!(rtcClockData.byte0 & 1) && (value & 1)) { // bit transfer
|
||||
rtcClockData.byte0 = (u8)value;
|
||||
switch(rtcClockData.state) {
|
||||
case COMMAND:
|
||||
rtcClockData.command |= ((value & 2) >> 1) << (7-rtcClockData.bits);
|
||||
rtcClockData.bits++;
|
||||
if(rtcClockData.bits == 8) {
|
||||
rtcClockData.bits = 0;
|
||||
switch(rtcClockData.command) {
|
||||
case 0x60:
|
||||
// not sure what this command does but it doesn't take parameters
|
||||
// maybe it is a reset or stop
|
||||
rtcClockData.state = IDLE;
|
||||
rtcClockData.bits = 0;
|
||||
break;
|
||||
case 0x62:
|
||||
// this sets the control state but not sure what those values are
|
||||
rtcClockData.state = READDATA;
|
||||
rtcClockData.dataLen = 1;
|
||||
break;
|
||||
case 0x63:
|
||||
rtcClockData.dataLen = 1;
|
||||
rtcClockData.data[0] = 0x40;
|
||||
rtcClockData.state = DATA;
|
||||
break;
|
||||
case 0x64:
|
||||
break;
|
||||
case 0x65:
|
||||
{
|
||||
struct tm *newtime;
|
||||
time_t long_time;
|
||||
|
||||
time( &long_time ); /* Get time as long integer. */
|
||||
newtime = localtime( &long_time ); /* Convert to local time. */
|
||||
|
||||
rtcClockData.dataLen = 7;
|
||||
rtcClockData.data[0] = toBCD(newtime->tm_year);
|
||||
rtcClockData.data[1] = toBCD(newtime->tm_mon+1);
|
||||
rtcClockData.data[2] = toBCD(newtime->tm_mday);
|
||||
rtcClockData.data[3] = toBCD(newtime->tm_wday);
|
||||
rtcClockData.data[4] = toBCD(newtime->tm_hour);
|
||||
rtcClockData.data[5] = toBCD(newtime->tm_min);
|
||||
rtcClockData.data[6] = toBCD(newtime->tm_sec);
|
||||
rtcClockData.state = DATA;
|
||||
}
|
||||
break;
|
||||
case 0x67:
|
||||
{
|
||||
struct tm *newtime;
|
||||
time_t long_time;
|
||||
|
||||
time( &long_time ); /* Get time as long integer. */
|
||||
newtime = localtime( &long_time ); /* Convert to local time. */
|
||||
|
||||
rtcClockData.dataLen = 3;
|
||||
rtcClockData.data[0] = toBCD(newtime->tm_hour);
|
||||
rtcClockData.data[1] = toBCD(newtime->tm_min);
|
||||
rtcClockData.data[2] = toBCD(newtime->tm_sec);
|
||||
rtcClockData.state = DATA;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
systemMessage(0, N_("Unknown RTC command %02x"), rtcClockData.command);
|
||||
rtcClockData.state = IDLE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case DATA:
|
||||
if(rtcClockData.byte1 & 2) {
|
||||
} else {
|
||||
rtcClockData.byte0 = (rtcClockData.byte0 & ~2) |
|
||||
((rtcClockData.data[rtcClockData.bits >> 3] >>
|
||||
(rtcClockData.bits & 7)) & 1)*2;
|
||||
rtcClockData.bits++;
|
||||
if(rtcClockData.bits == 8*rtcClockData.dataLen) {
|
||||
rtcClockData.bits = 0;
|
||||
rtcClockData.state = IDLE;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case READDATA:
|
||||
if(!(rtcClockData.byte1 & 2)) {
|
||||
} else {
|
||||
rtcClockData.data[rtcClockData.bits >> 3] =
|
||||
(rtcClockData.data[rtcClockData.bits >> 3] >> 1) |
|
||||
((value << 6) & 128);
|
||||
rtcClockData.bits++;
|
||||
if(rtcClockData.bits == 8*rtcClockData.dataLen) {
|
||||
rtcClockData.bits = 0;
|
||||
rtcClockData.state = IDLE;
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} else
|
||||
rtcClockData.byte0 = (u8)value;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void rtcReset()
|
||||
{
|
||||
memset(&rtcClockData, 0, sizeof(rtcClockData));
|
||||
|
||||
rtcClockData.byte0 = 0;
|
||||
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));
|
||||
}
|
||||
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
|
||||
// Copyright (C) 1999-2003 Forgotten
|
||||
// Copyright (C) 2004 Forgotten and the VBA development team
|
||||
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; either version 2, or(at your option)
|
||||
// any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software Foundation,
|
||||
// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
#include "System.h"
|
||||
#include "GBA.h"
|
||||
#include "Globals.h"
|
||||
#include "Port.h"
|
||||
#include "Util.h"
|
||||
#include "NLS.h"
|
||||
#include "vmmem.h"
|
||||
|
||||
#include <time.h>
|
||||
#include <string.h>
|
||||
|
||||
enum RTCSTATE { IDLE, COMMAND, DATA, READDATA };
|
||||
|
||||
typedef struct
|
||||
{
|
||||
u8 byte0;
|
||||
u8 byte1;
|
||||
u8 byte2;
|
||||
u8 command;
|
||||
int dataLen;
|
||||
int bits;
|
||||
RTCSTATE state;
|
||||
u8 data[12];
|
||||
// reserved variables for future
|
||||
u8 reserved[12];
|
||||
bool reserved2;
|
||||
u32 reserved3;
|
||||
}
|
||||
RTCCLOCKDATA;
|
||||
|
||||
static RTCCLOCKDATA rtcClockData;
|
||||
static bool rtcEnabled = false;
|
||||
|
||||
void rtcEnable(bool e)
|
||||
{
|
||||
rtcEnabled = e;
|
||||
}
|
||||
|
||||
bool rtcIsEnabled()
|
||||
{
|
||||
return rtcEnabled;
|
||||
}
|
||||
|
||||
u16 rtcRead(u32 address)
|
||||
{
|
||||
if(rtcEnabled)
|
||||
{
|
||||
if(address == 0x80000c8)
|
||||
return rtcClockData.byte2;
|
||||
else if(address == 0x80000c6)
|
||||
return rtcClockData.byte1;
|
||||
else if(address == 0x80000c4)
|
||||
{
|
||||
return rtcClockData.byte0;
|
||||
}
|
||||
}
|
||||
|
||||
//return READ16LE((&rom[address & 0x1FFFFFE]));
|
||||
return VMRead16( address & 0x1FFFFFE );
|
||||
}
|
||||
|
||||
static u8 toBCD(u8 value)
|
||||
{
|
||||
value = value % 100;
|
||||
int l = value % 10;
|
||||
int h = value / 10;
|
||||
return h * 16 + l;
|
||||
}
|
||||
|
||||
bool rtcWrite(u32 address, u16 value)
|
||||
{
|
||||
if(!rtcEnabled)
|
||||
return false;
|
||||
|
||||
if(address == 0x80000c8)
|
||||
{
|
||||
rtcClockData.byte2 = (u8)value; // enable ?
|
||||
}
|
||||
else if(address == 0x80000c6)
|
||||
{
|
||||
rtcClockData.byte1 = (u8)value; // read/write
|
||||
}
|
||||
else if(address == 0x80000c4)
|
||||
{
|
||||
if(rtcClockData.byte2 & 1)
|
||||
{
|
||||
if(rtcClockData.state == IDLE && rtcClockData.byte0 == 1 && value == 5)
|
||||
{
|
||||
rtcClockData.state = COMMAND;
|
||||
rtcClockData.bits = 0;
|
||||
rtcClockData.command = 0;
|
||||
}
|
||||
else if(!(rtcClockData.byte0 & 1) && (value & 1))
|
||||
{ // bit transfer
|
||||
rtcClockData.byte0 = (u8)value;
|
||||
switch(rtcClockData.state)
|
||||
{
|
||||
case COMMAND:
|
||||
rtcClockData.command |= ((value & 2) >> 1) << (7-rtcClockData.bits);
|
||||
rtcClockData.bits++;
|
||||
if(rtcClockData.bits == 8)
|
||||
{
|
||||
rtcClockData.bits = 0;
|
||||
switch(rtcClockData.command)
|
||||
{
|
||||
case 0x60:
|
||||
// not sure what this command does but it doesn't take parameters
|
||||
// maybe it is a reset or stop
|
||||
rtcClockData.state = IDLE;
|
||||
rtcClockData.bits = 0;
|
||||
break;
|
||||
case 0x62:
|
||||
// this sets the control state but not sure what those values are
|
||||
rtcClockData.state = READDATA;
|
||||
rtcClockData.dataLen = 1;
|
||||
break;
|
||||
case 0x63:
|
||||
rtcClockData.dataLen = 1;
|
||||
rtcClockData.data[0] = 0x40;
|
||||
rtcClockData.state = DATA;
|
||||
break;
|
||||
case 0x65:
|
||||
{
|
||||
struct tm *newtime;
|
||||
time_t long_time;
|
||||
|
||||
time( &long_time ); /* Get time as long integer. */
|
||||
newtime = localtime( &long_time ); /* Convert to local time. */
|
||||
|
||||
rtcClockData.dataLen = 7;
|
||||
rtcClockData.data[0] = toBCD(newtime->tm_year);
|
||||
rtcClockData.data[1] = toBCD(newtime->tm_mon+1);
|
||||
rtcClockData.data[2] = toBCD(newtime->tm_mday);
|
||||
rtcClockData.data[3] = 0;
|
||||
rtcClockData.data[4] = toBCD(newtime->tm_hour);
|
||||
rtcClockData.data[5] = toBCD(newtime->tm_min);
|
||||
rtcClockData.data[6] = toBCD(newtime->tm_sec);
|
||||
rtcClockData.state = DATA;
|
||||
}
|
||||
break;
|
||||
case 0x67:
|
||||
{
|
||||
struct tm *newtime;
|
||||
time_t long_time;
|
||||
|
||||
time( &long_time ); /* Get time as long integer. */
|
||||
newtime = localtime( &long_time ); /* Convert to local time. */
|
||||
|
||||
rtcClockData.dataLen = 3;
|
||||
rtcClockData.data[0] = toBCD(newtime->tm_hour);
|
||||
rtcClockData.data[1] = toBCD(newtime->tm_min);
|
||||
rtcClockData.data[2] = toBCD(newtime->tm_sec);
|
||||
rtcClockData.state = DATA;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
systemMessage(0, N_("Unknown RTC command %02x"), rtcClockData.command);
|
||||
rtcClockData.state = IDLE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case DATA:
|
||||
if(rtcClockData.byte1 & 2)
|
||||
{}
|
||||
else
|
||||
{
|
||||
rtcClockData.byte0 = (rtcClockData.byte0 & ~2) |
|
||||
((rtcClockData.data[rtcClockData.bits >> 3] >>
|
||||
(rtcClockData.bits & 7)) & 1)*2;
|
||||
rtcClockData.bits++;
|
||||
if(rtcClockData.bits == 8*rtcClockData.dataLen)
|
||||
{
|
||||
rtcClockData.bits = 0;
|
||||
rtcClockData.state = IDLE;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case READDATA:
|
||||
if(!(rtcClockData.byte1 & 2))
|
||||
{}
|
||||
else
|
||||
{
|
||||
rtcClockData.data[rtcClockData.bits >> 3] =
|
||||
(rtcClockData.data[rtcClockData.bits >> 3] >> 1) |
|
||||
((value << 6) & 128);
|
||||
rtcClockData.bits++;
|
||||
if(rtcClockData.bits == 8*rtcClockData.dataLen)
|
||||
{
|
||||
rtcClockData.bits = 0;
|
||||
rtcClockData.state = IDLE;
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
rtcClockData.byte0 = (u8)value;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void rtcReset()
|
||||
{
|
||||
memset(&rtcClockData, 0, sizeof(rtcClockData));
|
||||
|
||||
rtcClockData.byte0 = 0;
|
||||
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++ -*-
|
||||
// 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_RTC_H
|
||||
#define VBA_RTC_H
|
||||
extern u16 rtcRead(u32 address);
|
||||
extern bool rtcWrite(u32 address, u16 value);
|
||||
extern void rtcEnable(bool);
|
||||
extern bool rtcIsEnabled();
|
||||
extern void rtcReset();
|
||||
|
||||
extern void rtcReadGame(gzFile gzFile);
|
||||
extern void rtcSaveGame(gzFile gzFile);
|
||||
|
||||
#endif
|
||||
// -*- C++ -*-
|
||||
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
|
||||
// Copyright (C) 1999-2003 Forgotten
|
||||
// Copyright (C) 2004 Forgotten and the VBA development team
|
||||
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; either version 2, or(at your option)
|
||||
// any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software Foundation,
|
||||
// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
#ifndef VBA_RTC_H
|
||||
#define VBA_RTC_H
|
||||
extern u16 rtcRead(u32 address);
|
||||
extern bool rtcWrite(u32 address, u16 value);
|
||||
extern void rtcEnable(bool);
|
||||
extern bool rtcIsEnabled();
|
||||
extern void rtcReset();
|
||||
|
||||
extern void rtcReadGame(gzFile gzFile);
|
||||
extern void rtcSaveGame(gzFile gzFile);
|
||||
|
||||
#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++ -*-
|
||||
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
|
||||
// Copyright (C) 1999-2003 Forgotten
|
||||
// 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
|
||||
// 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_SOUND_H
|
||||
#define VBA_SOUND_H
|
||||
|
||||
#include "System.h"
|
||||
|
||||
#define NR10 0x60
|
||||
#define NR11 0x62
|
||||
#define NR12 0x63
|
||||
#define NR13 0x64
|
||||
#define NR14 0x65
|
||||
#define NR21 0x68
|
||||
#define NR22 0x69
|
||||
#define NR23 0x6c
|
||||
#define NR24 0x6d
|
||||
#define NR30 0x70
|
||||
#define NR31 0x72
|
||||
#define NR32 0x73
|
||||
#define NR33 0x74
|
||||
#define NR34 0x75
|
||||
#define NR41 0x78
|
||||
#define NR42 0x79
|
||||
#define NR43 0x7c
|
||||
#define NR44 0x7d
|
||||
#define NR50 0x80
|
||||
#define NR51 0x81
|
||||
#define NR52 0x84
|
||||
#define SGCNT0_H 0x82
|
||||
#define FIFOA_L 0xa0
|
||||
#define FIFOA_H 0xa2
|
||||
#define FIFOB_L 0xa4
|
||||
#define FIFOB_H 0xa6
|
||||
|
||||
void soundTick();
|
||||
void soundShutdown();
|
||||
bool soundInit();
|
||||
void soundPause();
|
||||
void soundResume();
|
||||
void soundEnable(int);
|
||||
void soundDisable(int);
|
||||
int soundGetEnable();
|
||||
void soundReset();
|
||||
void soundSaveGame(gzFile);
|
||||
void soundReadGame(gzFile, int);
|
||||
void soundEvent(u32, u8);
|
||||
void soundEvent(u32, u16);
|
||||
void soundTimerOverflow(int);
|
||||
void soundSetQuality(int);
|
||||
|
||||
extern int SOUND_CLOCK_TICKS;
|
||||
extern int soundTicks;
|
||||
extern int soundPaused;
|
||||
extern bool soundOffFlag;
|
||||
extern int soundQuality;
|
||||
extern int soundBufferLen;
|
||||
extern int soundBufferTotalLen;
|
||||
extern u32 soundNextPosition;
|
||||
extern u16 soundFinalWave[1470];
|
||||
extern int soundVolume;
|
||||
|
||||
extern bool soundEcho;
|
||||
extern bool soundLowPass;
|
||||
extern bool soundReverse;
|
||||
|
||||
#endif // VBA_SOUND_H
|
||||
// -*- 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_SOUND_H
|
||||
#define VBA_SOUND_H
|
||||
|
||||
#define NR10 0x60
|
||||
#define NR11 0x62
|
||||
#define NR12 0x63
|
||||
#define NR13 0x64
|
||||
#define NR14 0x65
|
||||
#define NR21 0x68
|
||||
#define NR22 0x69
|
||||
#define NR23 0x6c
|
||||
#define NR24 0x6d
|
||||
#define NR30 0x70
|
||||
#define NR31 0x72
|
||||
#define NR32 0x73
|
||||
#define NR33 0x74
|
||||
#define NR34 0x75
|
||||
#define NR41 0x78
|
||||
#define NR42 0x79
|
||||
#define NR43 0x7c
|
||||
#define NR44 0x7d
|
||||
#define NR50 0x80
|
||||
#define NR51 0x81
|
||||
#define NR52 0x84
|
||||
#define SGCNT0_H 0x82
|
||||
#define FIFOA_L 0xa0
|
||||
#define FIFOA_H 0xa2
|
||||
#define FIFOB_L 0xa4
|
||||
#define FIFOB_H 0xa6
|
||||
|
||||
extern void soundTick();
|
||||
extern void soundShutdown();
|
||||
extern bool soundInit();
|
||||
extern void soundPause();
|
||||
extern void soundResume();
|
||||
extern void soundEnable(int);
|
||||
extern void soundDisable(int);
|
||||
extern int soundGetEnable();
|
||||
extern void soundReset();
|
||||
extern void soundSaveGame(gzFile);
|
||||
extern void soundReadGame(gzFile, int);
|
||||
extern void soundEvent(u32, u8);
|
||||
extern void soundEvent(u32, u16);
|
||||
extern void soundTimerOverflow(int);
|
||||
extern void soundSetQuality(int);
|
||||
|
||||
//extern int SOUND_TICKS;
|
||||
extern int SOUND_CLOCK_TICKS;
|
||||
extern int soundTicks;
|
||||
extern int soundPaused;
|
||||
extern bool soundOffFlag;
|
||||
extern int soundQuality;
|
||||
extern int soundBufferLen;
|
||||
extern int soundBufferTotalLen;
|
||||
extern u32 soundNextPosition;
|
||||
extern u16 soundFinalWave[1470];
|
||||
extern int soundVolume;
|
||||
|
||||
extern bool soundEcho;
|
||||
extern bool soundLowPass;
|
||||
extern bool soundReverse;
|
||||
|
||||
#endif // VBA_SOUND_H
|
||||
|
@ -1,39 +1,32 @@
|
||||
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
|
||||
// Copyright (C) 1999-2003 Forgotten
|
||||
// Copyright (C) 2004 Forgotten and the VBA development team
|
||||
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; either version 2, or(at your option)
|
||||
// any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software Foundation,
|
||||
// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
#include "agb/GBA.h"
|
||||
#include "Globals.h"
|
||||
#include "Flash.h"
|
||||
#include "Sram.h"
|
||||
|
||||
u8 sramRead(u32 address)
|
||||
{
|
||||
return flashSaveMemory[address & 0xFFFF];
|
||||
}
|
||||
void sramDelayedWrite(u32 address, u8 byte)
|
||||
{
|
||||
saveType = 1;
|
||||
cpuSaveGameFunc = sramWrite;
|
||||
sramWrite(address, byte);
|
||||
}
|
||||
|
||||
void sramWrite(u32 address, u8 byte)
|
||||
{
|
||||
flashSaveMemory[address & 0xFFFF] = byte;
|
||||
systemSaveUpdateCounter = SYSTEM_SAVE_UPDATED;
|
||||
}
|
||||
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
|
||||
// Copyright (C) 1999-2003 Forgotten
|
||||
// Copyright (C) 2004 Forgotten and the VBA development team
|
||||
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; either version 2, or(at your option)
|
||||
// any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software Foundation,
|
||||
// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
#include "GBA.h"
|
||||
#include "Flash.h"
|
||||
#include "Sram.h"
|
||||
|
||||
u8 sramRead(u32 address)
|
||||
{
|
||||
return flashSaveMemory[address & 0xFFFF];
|
||||
}
|
||||
|
||||
void sramWrite(u32 address, u8 byte)
|
||||
{
|
||||
flashSaveMemory[address & 0xFFFF] = byte;
|
||||
systemSaveUpdateCounter = SYSTEM_SAVE_UPDATED;
|
||||
}
|
||||
|
@ -1,27 +1,26 @@
|
||||
// -*- 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_SRAM_H
|
||||
#define VBA_SRAM_H
|
||||
|
||||
extern u8 sramRead(u32 address);
|
||||
extern void sramWrite(u32 address, u8 byte);
|
||||
extern void sramDelayedWrite(u32 address, u8 byte);
|
||||
|
||||
#endif // VBA_SRAM_H
|
||||
// -*- 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_SRAM_H
|
||||
#define VBA_SRAM_H
|
||||
|
||||
extern u8 sramRead(u32 address);
|
||||
extern void sramWrite(u32 address, u8 byte);
|
||||
|
||||
#endif // VBA_SRAM_H
|
||||
|
@ -1,135 +1,127 @@
|
||||
// -*- 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_SYSTEM_H
|
||||
#define VBA_SYSTEM_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include "unzip.h"
|
||||
|
||||
#ifndef NULL
|
||||
#define NULL 0
|
||||
#endif
|
||||
|
||||
|
||||
typedef uint8_t u8;
|
||||
typedef uint16_t u16;
|
||||
typedef uint32_t u32;
|
||||
typedef uint64_t u64;
|
||||
|
||||
typedef int8_t s8;
|
||||
typedef int16_t s16;
|
||||
typedef int32_t s32;
|
||||
typedef int64_t s64;
|
||||
|
||||
|
||||
|
||||
typedef unsigned char u8;
|
||||
typedef unsigned short u16;
|
||||
typedef unsigned int u32;
|
||||
|
||||
struct EmulatedSystem {
|
||||
// main emulation function
|
||||
void (*emuMain)(int);
|
||||
// reset emulator
|
||||
void (*emuReset)();
|
||||
// clean up memory
|
||||
void (*emuCleanUp)();
|
||||
// load battery file
|
||||
bool (*emuReadBattery)(const char *);
|
||||
// write battery file
|
||||
bool (*emuWriteBattery)(const char *);
|
||||
// load state
|
||||
bool (*emuReadState)(const char *);
|
||||
// save state
|
||||
bool (*emuWriteState)(const char *);
|
||||
// load memory state (rewind)
|
||||
bool (*emuReadMemState)(char *, int);
|
||||
// write memory state (rewind)
|
||||
bool (*emuWriteMemState)(char *, int);
|
||||
// write PNG file
|
||||
bool (*emuWritePNG)(const char *);
|
||||
// write BMP file
|
||||
bool (*emuWriteBMP)(const char *);
|
||||
// emulator update CPSR (ARM only)
|
||||
void (*emuUpdateCPSR)();
|
||||
// emulator has debugger
|
||||
bool emuHasDebugger;
|
||||
// clock ticks to emulate
|
||||
int emuCount;
|
||||
};
|
||||
|
||||
extern void log(const char *,...);
|
||||
|
||||
extern bool systemPauseOnFrame();
|
||||
extern void systemGbPrint(u8 *,int,int,int,int);
|
||||
extern void systemScreenCapture(int);
|
||||
extern void systemDrawScreen();
|
||||
// updates the joystick data
|
||||
extern bool systemReadJoypads();
|
||||
// return information about the given joystick, -1 for default joystick
|
||||
extern u32 systemReadJoypad(int);
|
||||
extern u32 systemGetClock();
|
||||
extern void systemMessage(int, const char *, ...);
|
||||
extern void systemSetTitle(const char *);
|
||||
extern void systemWriteDataToSoundBuffer();
|
||||
extern void systemSoundShutdown();
|
||||
extern void systemSoundPause();
|
||||
extern void systemSoundResume();
|
||||
extern void systemSoundReset();
|
||||
extern bool systemSoundInit();
|
||||
extern void systemScreenMessage(const char *);
|
||||
extern void systemUpdateMotionSensor();
|
||||
extern int systemGetSensorX();
|
||||
extern int systemGetSensorY();
|
||||
extern bool systemCanChangeSoundQuality();
|
||||
extern void systemShowSpeed(int);
|
||||
extern void system10Frames(int);
|
||||
extern void systemFrame();
|
||||
extern void systemGbBorderOn();
|
||||
|
||||
extern void Sm60FPS_Init();
|
||||
extern bool Sm60FPS_CanSkipFrame();
|
||||
extern void Sm60FPS_Sleep();
|
||||
extern void DbgMsg(const char *msg, ...);
|
||||
extern void winlog(const char *,...);
|
||||
|
||||
extern void (*dbgOutput)(const char *s, u32 addr);
|
||||
extern void (*dbgSignal)(int sig,int number);
|
||||
|
||||
extern bool systemSoundOn; // old sound system
|
||||
extern u16 systemColorMap16[0x10000];
|
||||
//extern u32 systemColorMap32[0x10000];
|
||||
extern u32 *systemColorMap32;
|
||||
extern u16 systemGbPalette[24];
|
||||
extern int systemRedShift;
|
||||
extern int systemGreenShift;
|
||||
extern int systemBlueShift;
|
||||
extern int systemColorDepth;
|
||||
extern int systemDebug;
|
||||
extern int systemVerbose;
|
||||
extern int systemFrameSkip;
|
||||
extern int systemSaveUpdateCounter;
|
||||
extern int systemSpeed;
|
||||
extern int systemThrottle;
|
||||
|
||||
#define SYSTEM_SAVE_UPDATED 30
|
||||
#define SYSTEM_SAVE_NOT_UPDATED 0
|
||||
|
||||
#endif //VBA_SYSTEM_H
|
||||
// -*- 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_SYSTEM_H
|
||||
#define VBA_SYSTEM_H
|
||||
|
||||
#include "unzip.h"
|
||||
|
||||
#ifndef NULL
|
||||
#define NULL 0
|
||||
#endif
|
||||
|
||||
typedef unsigned char u8;
|
||||
typedef unsigned short u16;
|
||||
typedef unsigned int u32;
|
||||
|
||||
#ifdef _MSC_VER
|
||||
typedef unsigned __int64 u64;
|
||||
#else
|
||||
typedef unsigned long long u64;
|
||||
#endif
|
||||
|
||||
typedef signed char s8;
|
||||
typedef signed short s16;
|
||||
typedef signed int s32;
|
||||
|
||||
#ifdef _MSC_VER
|
||||
typedef signed __int64 s64;
|
||||
#else
|
||||
typedef signed long long s64;
|
||||
#endif
|
||||
|
||||
struct EmulatedSystem
|
||||
{
|
||||
// main emulation function
|
||||
void (*emuMain)(int);
|
||||
// reset emulator
|
||||
void (*emuReset)();
|
||||
// clean up memory
|
||||
void (*emuCleanUp)();
|
||||
// load battery file
|
||||
bool (*emuReadBattery)(const char *);
|
||||
// write battery file
|
||||
bool (*emuWriteBattery)(const char *);
|
||||
// load state
|
||||
bool (*emuReadState)(const char *);
|
||||
// save state
|
||||
bool (*emuWriteState)(const char *);
|
||||
// load memory state (rewind)
|
||||
bool (*emuReadMemState)(char *, int);
|
||||
// write memory state (rewind)
|
||||
bool (*emuWriteMemState)(char *, int);
|
||||
// write PNG file
|
||||
bool (*emuWritePNG)(const char *);
|
||||
// write BMP file
|
||||
bool (*emuWriteBMP)(const char *);
|
||||
// emulator update CPSR (ARM only)
|
||||
void (*emuUpdateCPSR)();
|
||||
// emulator has debugger
|
||||
bool emuHasDebugger;
|
||||
// clock ticks to emulate
|
||||
int emuCount;
|
||||
};
|
||||
|
||||
extern void log(const char *,...);
|
||||
|
||||
extern bool systemPauseOnFrame();
|
||||
extern void systemGbPrint(u8 *,int,int,int,int);
|
||||
extern void systemScreenCapture(int);
|
||||
extern void systemDrawScreen();
|
||||
// updates the joystick data
|
||||
extern bool systemReadJoypads();
|
||||
// return information about the given joystick, -1 for default joystick
|
||||
extern u32 systemReadJoypad(int);
|
||||
extern u32 systemGetClock();
|
||||
extern void systemMessage(int, const char *, ...);
|
||||
extern void systemSetTitle(const char *);
|
||||
extern void systemWriteDataToSoundBuffer();
|
||||
extern void systemSoundShutdown();
|
||||
extern void systemSoundPause();
|
||||
extern void systemSoundResume();
|
||||
extern void systemSoundReset();
|
||||
extern bool systemSoundInit();
|
||||
extern void systemScreenMessage(const char *);
|
||||
extern void systemUpdateMotionSensor();
|
||||
extern int systemGetSensorX();
|
||||
extern int systemGetSensorY();
|
||||
extern bool systemCanChangeSoundQuality();
|
||||
extern void systemShowSpeed(int);
|
||||
extern void system10Frames(int);
|
||||
extern void systemFrame();
|
||||
extern void systemGbBorderOn();
|
||||
|
||||
extern bool systemSoundOn;
|
||||
extern u16 systemColorMap16[0x10000];
|
||||
//extern u32 systemColorMap32[0x10000];
|
||||
extern u32 *systemColorMap32;
|
||||
extern u16 systemGbPalette[24];
|
||||
extern int systemRedShift;
|
||||
extern int systemGreenShift;
|
||||
extern int systemBlueShift;
|
||||
extern int systemColorDepth;
|
||||
extern int systemDebug;
|
||||
extern int systemVerbose;
|
||||
extern int systemFrameSkip;
|
||||
extern int systemSaveUpdateCounter;
|
||||
|
||||
#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
|
||||
#define VBA_UTIL_H
|
||||
|
||||
#include "System.h"
|
||||
|
||||
enum IMAGE_TYPE {
|
||||
IMAGE_UNKNOWN = -1,
|
||||
IMAGE_GBA = 0,
|
||||
@ -30,40 +27,40 @@ enum IMAGE_TYPE {
|
||||
|
||||
// save game
|
||||
|
||||
typedef struct {
|
||||
void *address;
|
||||
int size;
|
||||
} variable_desc;
|
||||
typedef struct
|
||||
{
|
||||
void *address;
|
||||
int size;
|
||||
}
|
||||
variable_desc;
|
||||
|
||||
extern int utilGetSize(int size);
|
||||
extern bool utilWritePNGFile(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 utilWriteBMP(char *, int, int, u8 *);
|
||||
extern bool utilIsGBAImage(const char *);
|
||||
extern bool utilIsGBImage(const char *);
|
||||
extern bool utilIsGzipFile(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 u8 *utilLoad(const char *,
|
||||
bool (*)(const char*),
|
||||
u8 *,
|
||||
int &);
|
||||
bool (*)(const char*),
|
||||
u8 *,
|
||||
int &);
|
||||
|
||||
extern void utilPutDword(u8 *, u32);
|
||||
extern void utilPutWord(u8 *, u16);
|
||||
extern void utilWriteData(gzFile, variable_desc *);
|
||||
extern void utilReadData(gzFile, variable_desc *);
|
||||
extern void utilReadDataSkip(gzFile, variable_desc *);
|
||||
extern int utilReadInt(gzFile);
|
||||
extern void utilWriteInt(gzFile, int);
|
||||
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 utilGzRead(gzFile file, voidp buffer, unsigned int len);
|
||||
extern int utilGzClose(gzFile file);
|
||||
extern z_off_t utilGzSeek(gzFile file, z_off_t offset, int whence);
|
||||
extern long utilGzMemTell(gzFile file);
|
||||
extern void utilGBAFindSave(const u8 *, const int);
|
||||
extern void utilUpdateSystemColorMaps();
|
||||
#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.
|
||||
// Copyright (C) 1999-2003 Forgotten
|
||||
// Copyright (C) 2004 Forgotten and the VBA development team
|
||||
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; either version 2, or(at your option)
|
||||
// any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software Foundation,
|
||||
// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "GBA.h"
|
||||
#include "Globals.h"
|
||||
#include "Port.h"
|
||||
#include "System.h"
|
||||
|
||||
#define debuggerWriteHalfWord(addr, value) \
|
||||
WRITE16LE((u16*)&map[(addr)>>24].address[(addr) & map[(addr)>>24].mask], (value))
|
||||
|
||||
#define debuggerReadHalfWord(addr) \
|
||||
READ16LE(((u16*)&map[(addr)>>24].address[(addr) & map[(addr)>>24].mask]))
|
||||
|
||||
static bool agbPrintEnabled = false;
|
||||
static bool agbPrintProtect = false;
|
||||
|
||||
bool agbPrintWrite(u32 address, u16 value)
|
||||
{
|
||||
if(agbPrintEnabled) {
|
||||
if(address == 0x9fe2ffe) { // protect
|
||||
agbPrintProtect = (value != 0);
|
||||
debuggerWriteHalfWord(address, value);
|
||||
return true;
|
||||
} else {
|
||||
if(agbPrintProtect &&
|
||||
((address >= 0x9fe20f8 && address <= 0x9fe20ff) // control structure
|
||||
|| (address >= 0x8fd0000 && address <= 0x8fdffff)
|
||||
|| (address >= 0x9fd0000 && address <= 0x9fdffff))) {
|
||||
debuggerWriteHalfWord(address, value);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void agbPrintReset()
|
||||
{
|
||||
agbPrintProtect = false;
|
||||
}
|
||||
|
||||
void agbPrintEnable(bool enable)
|
||||
{
|
||||
agbPrintEnabled = enable;
|
||||
}
|
||||
|
||||
bool agbPrintIsEnabled()
|
||||
{
|
||||
return agbPrintEnabled;
|
||||
}
|
||||
|
||||
void agbPrintFlush()
|
||||
{
|
||||
u16 get = debuggerReadHalfWord(0x9fe20fc);
|
||||
u16 put = debuggerReadHalfWord(0x9fe20fe);
|
||||
|
||||
u32 address = (debuggerReadHalfWord(0x9fe20fa) << 16);
|
||||
if(address != 0xfd0000 && address != 0x1fd0000) {
|
||||
dbgOutput("Did you forget to call AGBPrintInit?\n", 0);
|
||||
// get rid of the text otherwise we will continue to be called
|
||||
debuggerWriteHalfWord(0x9fe20fc, put);
|
||||
return;
|
||||
}
|
||||
|
||||
u8 *data = &rom[address];
|
||||
|
||||
while(get != put) {
|
||||
char c = data[get++];
|
||||
char s[2];
|
||||
s[0] = c;
|
||||
s[1] = 0;
|
||||
|
||||
if(systemVerbose & VERBOSE_AGBPRINT)
|
||||
dbgOutput(s, 0);
|
||||
if(c == '\n')
|
||||
break;
|
||||
}
|
||||
debuggerWriteHalfWord(0x9fe20fc, get);
|
||||
}
|
||||
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
|
||||
// Copyright (C) 1999-2003 Forgotten
|
||||
// Copyright (C) 2004 Forgotten and the VBA development team
|
||||
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; either version 2, or(at your option)
|
||||
// any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software Foundation,
|
||||
// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "GBA.h"
|
||||
#include "Globals.h"
|
||||
#include "Port.h"
|
||||
|
||||
#define debuggerWriteHalfWord(addr, value) \
|
||||
WRITE16LE((u16*)&map[(addr)>>24].address[(addr) & map[(addr)>>24].mask], (value))
|
||||
|
||||
#define debuggerReadHalfWord(addr) \
|
||||
READ16LE(((u16*)&map[(addr)>>24].address[(addr) & map[(addr)>>24].mask]))
|
||||
|
||||
static bool agbPrintEnabled = false;
|
||||
static bool agbPrintProtect = false;
|
||||
|
||||
bool agbPrintWrite(u32 address, u16 value)
|
||||
{
|
||||
if(agbPrintEnabled)
|
||||
{
|
||||
if(address == 0x9fe2ffe)
|
||||
{ // protect
|
||||
agbPrintProtect = (value != 0);
|
||||
debuggerWriteHalfWord(address, value);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(agbPrintProtect &&
|
||||
((address >= 0x9fe20f8 && address <= 0x9fe20ff) // control structure
|
||||
|| (address >= 0x8fd0000 && address <= 0x8fdffff)
|
||||
|| (address >= 0x9fd0000 && address <= 0x9fdffff)))
|
||||
{
|
||||
debuggerWriteHalfWord(address, value);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void agbPrintReset()
|
||||
{
|
||||
agbPrintProtect = false;
|
||||
}
|
||||
|
||||
void agbPrintEnable(bool enable)
|
||||
{
|
||||
agbPrintEnabled = enable;
|
||||
}
|
||||
|
||||
bool agbPrintIsEnabled()
|
||||
{
|
||||
return agbPrintEnabled;
|
||||
}
|
||||
|
||||
extern void (*dbgOutput)(char *, u32);
|
||||
|
||||
void agbPrintFlush()
|
||||
{
|
||||
u16 get = debuggerReadHalfWord(0x9fe20fc);
|
||||
u16 put = debuggerReadHalfWord(0x9fe20fe);
|
||||
|
||||
u32 address = (debuggerReadHalfWord(0x9fe20fa) << 16);
|
||||
if(address != 0xfd0000 && address != 0x1fd0000)
|
||||
{
|
||||
dbgOutput("Did you forget to call AGBPrintInit?\n", 0);
|
||||
// get rid of the text otherwise we will continue to be called
|
||||
debuggerWriteHalfWord(0x9fe20fc, put);
|
||||
return;
|
||||
}
|
||||
|
||||
u8 *data = &rom[address];
|
||||
|
||||
while(get != put)
|
||||
{
|
||||
char c = data[get++];
|
||||
char s[2];
|
||||
s[0] = c;
|
||||
s[1] = 0;
|
||||
|
||||
if(systemVerbose & VERBOSE_AGBPRINT)
|
||||
dbgOutput(s, 0);
|
||||
if(c == '\n')
|
||||
break;
|
||||
}
|
||||
debuggerWriteHalfWord(0x9fe20fc, get);
|
||||
}
|
@ -1,27 +1,27 @@
|
||||
// -*- C++ -*-
|
||||
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
|
||||
// Copyright (C) 1999-2003 Forgotten
|
||||
// Copyright (C) 2004 Forgotten and the VBA development team
|
||||
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; either version 2, or(at your option)
|
||||
// any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software Foundation,
|
||||
// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
#ifndef VBA_AGBPRINT_H
|
||||
#define VBA_AGBPRINT_H
|
||||
extern void agbPrintEnable(bool);
|
||||
extern bool agbPrintIsEnabled();
|
||||
extern void agbPrintReset();
|
||||
extern bool agbPrintWrite(u32, u16);
|
||||
extern void agbPrintFlush();
|
||||
#endif
|
||||
// -*- C++ -*-
|
||||
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
|
||||
// Copyright (C) 1999-2003 Forgotten
|
||||
// Copyright (C) 2004 Forgotten and the VBA development team
|
||||
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; either version 2, or(at your option)
|
||||
// any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software Foundation,
|
||||
// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
#ifndef VBA_AGBPRINT_H
|
||||
#define VBA_AGBPRINT_H
|
||||
extern void agbPrintEnable(bool);
|
||||
extern bool agbPrintIsEnabled();
|
||||
extern void agbPrintReset();
|
||||
extern bool agbPrintWrite(u32, u16);
|
||||
extern void agbPrintFlush();
|
||||
#endif
|
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