[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:
dborth 2008-10-16 01:36:56 +00:00
parent 2f2a1fd518
commit ae514696d4
138 changed files with 37097 additions and 52516 deletions

View File

@ -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

View File

@ -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
#---------------------------------------------------------------------------------

View File

@ -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

View File

@ -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;
}

View File

@ -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

View File

@ -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;
}

View File

@ -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

View File

@ -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

View File

@ -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();

View File

@ -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);
}

View File

@ -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

File diff suppressed because it is too large Load Diff

View File

@ -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

View File

@ -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;
}
}

View File

@ -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();

View File

@ -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);

View File

@ -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);

View File

@ -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 ();
}
/****************************************************************************

View File

@ -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);

View File

@ -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
View 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
View 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

View File

@ -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);

View File

@ -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

View File

@ -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);
}

View File

@ -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;

View File

@ -46,6 +46,4 @@ DefaultSettings ()
GCSettings.smbgcid[0] = 0;
GCSettings.VerifySaves = 0;
GCSettings.NGCZoom = 0; // zooming default off
GCSettings.render = 0; // Unfiltered
}

View File

@ -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;
}
/****************************************************************************

View File

@ -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);

View File

@ -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 ();
}

View File

@ -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

View File

@ -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' */

View File

@ -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 );

View File

@ -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);
}

View File

@ -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

View File

@ -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;
}

View File

@ -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

View File

@ -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);
}

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -1,5 +0,0 @@
/* 7zHeader.c */
#include "7zHeader.h"
Byte k7zSignature[k7zSignatureSize] = {'7', 'z', 0xBC, 0xAF, 0x27, 0x1C};

View File

@ -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

File diff suppressed because it is too large Load Diff

View File

@ -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

View File

@ -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);
}

View File

@ -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

View File

@ -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;
}

View File

@ -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

View File

@ -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

View File

@ -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;
}

View File

@ -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

View File

@ -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

View File

@ -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);
}
}

View File

@ -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

View File

@ -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

View File

@ -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;
}
}

View File

@ -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

View File

@ -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;
}
}

View File

@ -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

File diff suppressed because it is too large Load Diff

View File

@ -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
View 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

View File

@ -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

File diff suppressed because it is too large Load Diff

View File

@ -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;

View File

@ -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

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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

View File

@ -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

View File

@ -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));
}

View File

@ -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

File diff suppressed because it is too large Load Diff

View File

@ -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

View File

@ -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;
}

View File

@ -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

View File

@ -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
View 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
View 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

View File

@ -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

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

View File

@ -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

View File

@ -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

View File

@ -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);
}

View File

@ -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

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