[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 # SOURCES is a list of directories containing source code
# INCLUDES is a list of directories containing extra header files # INCLUDES is a list of directories containing extra header files
#--------------------------------------------------------------------------------- #---------------------------------------------------------------------------------
TARGET := vbagx_gc TARGET := vba172_gc
TARGETDIR := executables TARGETDIR := executables
BUILD := build_gc BUILD := build_gc
SOURCES := source/vba source/vba/agb source/vba/dmg source/ngc source/sz SOURCES := source/vba source/vba/gb source/ngc
INCLUDES := source/vba source/ngc INCLUDES := source/vba source/vba/gb source/ngc
#--------------------------------------------------------------------------------- #---------------------------------------------------------------------------------
# options for code generation # options for code generation
#--------------------------------------------------------------------------------- #---------------------------------------------------------------------------------
CFLAGS = -g -O3 -Wall $(MACHDEP) $(INCLUDE) \ CFLAGS = -g -Os -Wall $(MACHDEP) $(INCLUDE) \
-DNGC -DUSE_VM -DWORDS_BIGENDIAN \ -DNGC -DWORDS_BIGENDIAN -DPACKAGE=\"VisualBoyAdvance\" \
-DC_CORE -D__ppc__ -D__POWERPC__ -DFINAL_VERSION \ -DVERSION=\"1.7.2\" -DC_CORE \
-DSDL -DNO_PNG -DHAVE_ZUTIL_H \ -DCHANFFS -DSDL -DNO_DEFLATE
-D_SZ_ONE_DIRECTORY -D_LZMA_IN_CB -D_LZMA_OUT_READ CXXFLAGS = -save-temps -Xassembler -aln=$@.lst $(CFLAGS)
CXXFLAGS = $(CFLAGS) LDFLAGS = -g $(MACHDEP) -Wl,-Map,$(notdir $@).map -Wl,--cref
LDFLAGS = -g $(MACHDEP) -Wl,-Map,$(notdir $@).map
#--------------------------------------------------------------------------------- #---------------------------------------------------------------------------------
# any extra libraries we wish to link with # any extra libraries we wish to link with

View File

@ -15,22 +15,21 @@ include $(DEVKITPPC)/wii_rules
# SOURCES is a list of directories containing source code # SOURCES is a list of directories containing source code
# INCLUDES is a list of directories containing extra header files # INCLUDES is a list of directories containing extra header files
#--------------------------------------------------------------------------------- #---------------------------------------------------------------------------------
TARGET := vbagx_wii TARGET := vba172_wii
TARGETDIR := executables TARGETDIR := executables
BUILD := build_wii BUILD := build_wii
SOURCES := source/vba source/vba/agb source/vba/dmg source/ngc source/sz SOURCES := source/vba source/vba/gb source/ngc
INCLUDES := source/vba source/ngc INCLUDES := source/vba source/vba/gb source/ngc
#--------------------------------------------------------------------------------- #---------------------------------------------------------------------------------
# options for code generation # options for code generation
#--------------------------------------------------------------------------------- #---------------------------------------------------------------------------------
CFLAGS = -g -O3 -Wall $(MACHDEP) $(INCLUDE) \ CFLAGS = -g -Os -Wall $(MACHDEP) $(INCLUDE) \
-DNGC -DWII_DVD -DWORDS_BIGENDIAN -DVIDEO_THREADING \ -DNGC -DWORDS_BIGENDIAN -DPACKAGE=\"VisualBoyAdvance\" \
-DC_CORE -D__ppc__ -D__POWERPC__ -DFINAL_VERSION \ -DVERSION=\"1.7.2\" -DC_CORE \
-DSDL -DNO_PNG -DHAVE_ZUTIL_H \ -DCHANFFS -DSDL -DNO_DEFLATE
-D_SZ_ONE_DIRECTORY -D_LZMA_IN_CB -D_LZMA_OUT_READ CXXFLAGS = -save-temps -Xassembler -aln=$@.lst $(CFLAGS)
CXXFLAGS = $(CFLAGS)
LDFLAGS = -g $(MACHDEP) -Wl,-Map,$(notdir $@).map -Wl,--cref LDFLAGS = -g $(MACHDEP) -Wl,-Map,$(notdir $@).map -Wl,--cref
#--------------------------------------------------------------------------------- #---------------------------------------------------------------------------------

View File

@ -1,13 +1,14 @@
¸,ø¤°`°¤ø,¸¸,ø¤°`°¤ø,¸,ø¤°`°¤ø,¸¸,ø¤°`°¤ø,¸,ø¤°`°¤ø,¸¸,ø¤°`°¤ø,¸,ø¤°`°¤ø,¸¸,ø¤ ¸,ø¤°`°¤ø,¸¸,ø¤°`°¤ø,¸,ø¤°`°¤ø,¸¸,ø¤°`°¤ø,¸,ø¤°`°¤ø,¸¸,ø¤°`°¤ø,¸,ø¤°`°¤ø,¸¸,ø¤
- Visual Boy Advance GX - - Visual Boy Advance GX -
Version 1.0.3 Version 1.0.0
http://code.google.com/p/vba-wii
(Under GPL License) (Under GPL License)
¸,ø¤°`°¤ø,¸¸,ø¤°`°¤ø,¸,ø¤°`°¤ø,¸¸,ø¤°`°¤ø,¸,ø¤°`°¤ø,¸¸,ø¤°`°¤ø,¸,ø¤°`°¤ø,¸¸,ø¤ ¸,ø¤°`°¤ø,¸¸,ø¤°`°¤ø,¸,ø¤°`°¤ø,¸¸,ø¤°`°¤ø,¸,ø¤°`°¤ø,¸¸,ø¤°`°¤ø,¸,ø¤°`°¤ø,¸¸,ø¤
Visual Boy Advance GX is a modified port of VBA-M / VBA 1.7.2. -=[ Explanation ]=-
Visual Boy Advance GX is a port of Visual Boy Advance 1.7.2.
With it you can play GBA/Game Boy Color/Game Boy games on your Wii/GameCube. With it you can play GBA/Game Boy Color/Game Boy games on your Wii/GameCube.
-=[ Features ]=- -=[ Features ]=-
@ -15,42 +16,13 @@ With it you can play GBA/Game Boy Color/Game Boy games on your Wii/GameCube.
* Wiimote, Nunchuk, Classic, and Gamecube controller support * Wiimote, Nunchuk, Classic, and Gamecube controller support
* SRAM and State saving * SRAM and State saving
* Custom controller configurations * Custom controller configurations
* SD, USB, DVD, SMB, GC Memory Card, Zip, and 7z support * SD and USB support
* GBA compatiblity based on VBA-M r750, GB compatibility based on VBA 1.7.2
* Turbo speed feature
×—–­—–­—–­—–­ –­—–­—–­—–­—–­—–­—–­—–­—–­—–­— ­—–­—–­—–­—–­—–­—–­—–­—-­—–­-–•¬ ×—–­—–­—–­—–­ –­—–­—–­—–­—–­—–­—–­—–­—–­—–­— ­—–­—–­—–­—–­—–­—–­—–­—-­—–­-–•¬
|0O×øo· UPDATE HISTORY ·oø×O0| |0O×øo· UPDATE HISTORY ·oø×O0|
`¨•¨¨¨¨¨ ¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨ ¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨ ¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨ ¨¨¨¨¨¨¨¨¨¨¨¨¨' `¨•¨¨¨¨¨ ¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨ ¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨ ¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨ ¨¨¨¨¨¨¨¨¨¨¨¨¨'
[What's New 1.0.3 - October 15, 2008] [What's New 1.0.0]
* New timing / frameskip algorithm - should (hopefully) work 100% better!
* Performance improvements - video threading, PPC core partly activated
* Video zooming option
* Unfiltered video option
* 7z support
* Loading progress bars added
[What's New 1.0.2 - October 6, 2008]
* New core! The core is now a custom combination of VBA-M and VBA 1.72
* Added DVD, SMB, ZIP, GameCube MC support
* Faster USB/SD speeds
* Screen alignment and flickering problems fixed
* 128K save support added
* Better emulation speeds. Should now be nearly full speed all the time
for most games.
* Turbo speed feature. Mapped to right C-stick (classic controller &
Gamecube controller), and A+B for wiimote
* Controller mapping preferences bug fixed. Your preferences will reset
automatically to correct any problems in your preferences file
* Many other tweaks behind the scenes
[What's New 1.0.1 - September 18, 2008]
* GBA games now run at full speed
* Menu improvements, with spiffy new background - thanks brakken!
* Fixed L/R buttons - they work now
[What's New 1.0.0 - September 16, 2008]
* Now compiles with devkitpro r15 * Now compiles with devkitpro r15
* One makefile to make all versions * One makefile to make all versions

View File

@ -13,7 +13,6 @@
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <malloc.h>
#ifdef WII_DVD #ifdef WII_DVD
extern "C" { extern "C" {
@ -23,12 +22,14 @@ extern "C" {
#include "menudraw.h" #include "menudraw.h"
#include "gcunzip.h" #include "gcunzip.h"
#include "filesel.h"
#include "vba.h"
u64 dvddir = 0; // offset of currently selected file or folder extern int offset;
int dvddirlength = 0; // length of currently selected file or folder extern int selection;
u64 dvdrootdir = 0; // offset of DVD root extern FILEENTRIES filelist[MAXFILES];
extern int maxfiles;
u64 dvddir = 0;
u64 dvdrootdir = 0;
int dvddirlength = 0;
bool isWii = false; bool isWii = false;
#ifdef HW_DOL #ifdef HW_DOL
@ -36,192 +37,63 @@ bool isWii = false;
volatile unsigned long *dvd = (volatile unsigned long *) 0xCC006000; volatile unsigned long *dvd = (volatile unsigned long *) 0xCC006000;
#endif #endif
/** Due to lack of memory, we'll use this little 2k keyhole for all DVD operations **/
unsigned char DVDreadbuffer[2048] ATTRIBUTE_ALIGN (32);
unsigned char dvdbuffer[2048];
/**************************************************************************** /****************************************************************************
* dvd_read * dvd_read
* *
* Main DVD function, everything else uses this! * The only DVD function we need - you gotta luv gc-linux self-boots!
* returns: 1 - ok ; 0 - error * returns: 1 - ok ; 0 - error
***************************************************************************/ ***************************************************************************/
#define ALIGN_FORWARD(x,align) ((typeof(x))((((uint32_t)(x)) + (align) - 1) & (~(align-1))))
#define ALIGN_BACKWARD(x,align) ((typeof(x))(((uint32_t)(x)) & (~(align-1))))
int int
dvd_read (void *dst, unsigned int len, u64 offset) dvd_read (void *dst, unsigned int len, u64 offset)
{ {
unsigned char *buffer = (unsigned char *) (unsigned int) DVDreadbuffer;
if (len > 2048) if (len > 2048)
return 0; /*** We only allow 2k reads **/ return 0; /*** We only allow 2k reads **/
DCInvalidateRange ((void *) buffer, len);
// don't read past the end of the DVD (1.5 GB for GC DVD, 4.7 GB for DVD) // don't read past the end of the DVD (1.5 GB for GC DVD, 4.7 GB for DVD)
if((offset < 0x57057C00) || (isWii && (offset < 0x118244F00LL))) if(offset < 0x57057C00 || (isWii && offset < 0x118244F00LL))
{ {
u8 * buffer = (u8 *)memalign(32, 0x8000);
u32 off_size = 0;
DCInvalidateRange ((void *) buffer, len); #ifdef HW_DOL
#ifdef HW_DOL dvd[0] = 0x2E;
dvd[0] = 0x2E; dvd[1] = 0;
dvd[1] = 0; dvd[2] = 0xA8000000;
dvd[2] = 0xA8000000; dvd[3] = (u32)(offset >> 2);
dvd[3] = (u32)(offset >> 2); dvd[4] = len;
dvd[4] = len; dvd[5] = (u32) buffer;
dvd[5] = (u32) buffer; dvd[6] = len;
dvd[6] = len; dvd[7] = 3; /*** Enable reading with DMA ***/
dvd[7] = 3; while (dvd[7] & 1);
memcpy (dst, buffer, len);
// Enable reading with DMA if (dvd[0] & 0x4) /* Ensure it has completed */
while (dvd[7] & 1); return 0;
// Ensure it has completed
if (dvd[0] & 0x4)
return 0;
#else
off_size = offset - ALIGN_BACKWARD(offset,0x800);
if (DI_ReadDVD(
buffer,
(ALIGN_FORWARD(offset + len,0x800) - ALIGN_BACKWARD(offset,0x800)) >> 11,
(u32)(ALIGN_BACKWARD(offset, 0x800) >> 11)
))
return 0;
#endif
memcpy (dst, buffer+off_size, len);
free(buffer);
return 1; return 1;
#elif WII_DVD
int ret = 1;
ret = DI_ReadDVD(dst, len >> 11, (u32)(offset >> 11));
if (ret==0)
return 1;
else
return 0;
#endif
} }
return 0; return 0;
} }
/****************************************************************************
* dvd_buffered_read
*
* the GC's dvd drive only supports offsets and length which are a multiple
* of 32 bytes additionally the max length of a read is 2048 bytes
* this function removes these limitations
* additionally the 7zip SDK does often read data in 1 byte parts from the
* DVD even when it could read 32 bytes. the dvdsf_buffer has been added to
* avoid having to read the same sector over and over again
***************************************************************************/
#define DVD_LENGTH_MULTIPLY 32
#define DVD_OFFSET_MULTIPLY 32
#define DVD_MAX_READ_LENGTH 2048
#define DVD_SECTOR_SIZE 2048
unsigned char dvdsf_buffer[DVD_SECTOR_SIZE];
u64 dvdsf_last_offset = 0;
u64 dvdsf_last_length = 0;
int dvd_buffered_read(void *dst, u32 len, u64 offset)
{
int ret = 0;
// only read data if the data inside dvdsf_buffer cannot be used
if(offset != dvdsf_last_offset || len > dvdsf_last_length)
{
memset(&dvdsf_buffer, '\0', DVD_SECTOR_SIZE);
ret = dvd_read(&dvdsf_buffer, len, offset);
dvdsf_last_offset = offset;
dvdsf_last_length = len;
}
memcpy(dst, &dvdsf_buffer, len);
return ret;
}
int dvd_safe_read(void *dst_v, u32 len, u64 offset)
{
unsigned char buffer[DVD_SECTOR_SIZE]; // buffer for one dvd sector
// if read size and length are a multiply of DVD_(OFFSET,LENGTH)_MULTIPLY and length < DVD_MAX_READ_LENGTH
// we don't need to fix anything
if(len % DVD_LENGTH_MULTIPLY == 0 && offset % DVD_OFFSET_MULTIPLY == 0 && len <= DVD_MAX_READ_LENGTH)
{
int ret = dvd_buffered_read(buffer, len, offset);
memcpy(dst_v, &buffer, len);
return ret;
}
else
{
// no errors yet -> ret = 0
// the return value of dvd_read will be OR'd with ret
// because dvd_read does return 1 on error and 0 on success and
// because 0 | 1 = 1 ret will also contain 1 if at least one error
// occured and 0 otherwise ;)
int ret = 0; // return value of dvd_read
// we might need to fix all 3 issues
unsigned char *dst = (unsigned char *)dst_v; // gcc will not allow to use var[num] on void* types
u64 bytesToRead; // the number of bytes we still need to read & copy to the output buffer
u64 currentOffset; // the current dvd offset
u64 bufferOffset; // the current buffer offset
u64 i, j, k; // temporary variables which might be used for different stuff
// unsigned char buffer[DVD_SECTOR_SIZE]; // buffer for one dvd sector
currentOffset = offset;
bytesToRead = len;
bufferOffset = 0;
// fix first issue (offset is not a multiply of 32)
if(offset % DVD_OFFSET_MULTIPLY)
{
// calculate offset of the prior 32 byte position
i = currentOffset - (currentOffset % DVD_OFFSET_MULTIPLY);
// calculate the offset from which the data of the dvd buffer will be copied
j = currentOffset % DVD_OFFSET_MULTIPLY;
// calculate the number of bytes needed to reach the next DVD_OFFSET_MULTIPLY byte mark
k = DVD_OFFSET_MULTIPLY - j;
// maybe we'll only need to copy a few bytes and we therefore don't even reach the next sector
if(k > len)
{
k = len;
}
// read 32 bytes from the last 32 byte position
ret |= dvd_buffered_read(buffer, DVD_OFFSET_MULTIPLY, i);
// copy the bytes to the output buffer and update currentOffset, bufferOffset and bytesToRead
memcpy(&dst[bufferOffset], &buffer[j], k);
currentOffset += k;
bufferOffset += k;
bytesToRead -= k;
}
// fix second issue (more than 2048 bytes are needed)
if(bytesToRead > DVD_MAX_READ_LENGTH)
{
// calculate the number of 2048 bytes sector needed to get all data
i = (bytesToRead - (bytesToRead % DVD_MAX_READ_LENGTH)) / DVD_MAX_READ_LENGTH;
// read data in 2048 byte sector
for(j = 0; j < i; j++)
{
ret |= dvd_buffered_read(buffer, DVD_MAX_READ_LENGTH, currentOffset); // read sector
memcpy(&dst[bufferOffset], buffer, DVD_MAX_READ_LENGTH); // copy to output buffer
// update currentOffset, bufferOffset and bytesToRead
currentOffset += DVD_MAX_READ_LENGTH;
bufferOffset += DVD_MAX_READ_LENGTH;
bytesToRead -= DVD_MAX_READ_LENGTH;
}
}
// fix third issue (length is not a multiply of 32)
if(bytesToRead)
{
ret |= dvd_buffered_read(buffer, DVD_MAX_READ_LENGTH, currentOffset); // read 32 byte from the dvd
memcpy(&dst[bufferOffset], buffer, bytesToRead); // copy bytes to output buffer
}
//free(tmp);
return ret;
}
}
/** Minimal ISO Directory Definition **/ /** Minimal ISO Directory Definition **/
#define RECLEN 0 /* Record length */ #define RECLEN 0 /* Record length */
#define EXTENT 6 /* Extent */ #define EXTENT 6 /* Extent */
@ -245,7 +117,6 @@ getpvd ()
{ {
int sector = 16; int sector = 16;
u32 rootdir32; u32 rootdir32;
unsigned char dvdbuffer[2048];
dvddir = dvddirlength = 0; dvddir = dvddirlength = 0;
IsJoliet = -1; IsJoliet = -1;
@ -330,7 +201,7 @@ bool TestDVD()
***************************************************************************/ ***************************************************************************/
static int diroffset = 0; static int diroffset = 0;
static int static int
getentry (int entrycount, unsigned char dvdbuffer[]) getentry (int entrycount)
{ {
char fname[512]; /* Huge, but experience has determined this */ char fname[512]; /* Huge, but experience has determined this */
char *ptr; char *ptr;
@ -450,7 +321,6 @@ ParseDVDdirectory ()
u64 rdoffset; u64 rdoffset;
int len = 0; int len = 0;
int filecount = 0; int filecount = 0;
unsigned char dvdbuffer[2048];
// initialize selection // initialize selection
selection = offset = 0; selection = offset = 0;
@ -470,7 +340,7 @@ ParseDVDdirectory ()
diroffset = 0; diroffset = 0;
while (getentry (filecount, dvdbuffer)) while (getentry (filecount))
{ {
if(strlen(filelist[filecount].filename) > 0 && filecount < MAXFILES) if(strlen(filelist[filecount].filename) > 0 && filecount < MAXFILES)
filecount++; filecount++;
@ -559,15 +429,15 @@ bool SwitchDVDFolder(char origdir[])
/**************************************************************************** /****************************************************************************
* LoadDVDFile * LoadDVDFile
* This function will load a file from DVD * This function will load a file from DVD, in BIN, SMD or ZIP format.
* The values for offset and length are inherited from dvddir and * The values for offset and length are inherited from dvddir and
* dvddirlength. * dvddirlength.
* *
* The buffer parameter should re-use the initial ROM buffer * The buffer parameter should re-use the initial ROM buffer.
***************************************************************************/ ***************************************************************************/
int int
LoadDVDFile (unsigned char *buffer, int length) LoadDVDFile (unsigned char *buffer)
{ {
int offset; int offset;
int blocks; int blocks;
@ -575,45 +445,34 @@ LoadDVDFile (unsigned char *buffer, int length)
u64 discoffset; u64 discoffset;
char readbuffer[2048]; char readbuffer[2048];
dvddir = filelist[selection].offset;
dvddirlength = filelist[selection].length;
// How many 2k blocks to read // How many 2k blocks to read
blocks = dvddirlength / 2048; blocks = dvddirlength / 2048;
offset = 0; offset = 0;
discoffset = dvddir; discoffset = dvddir;
ShowAction ((char*) "Loading...");
dvd_read (readbuffer, 2048, discoffset);
if(length > 0 && length <= 2048) // do a partial read (eg: to check file header) if (!IsZipFile (readbuffer))
{ {
dvd_read (buffer, length, discoffset); for (i = 0; i < blocks; i++)
{
dvd_read (readbuffer, 2048, discoffset);
memcpy (buffer + offset, readbuffer, 2048);
offset += 2048;
discoffset += 2048;
}
/*** And final cleanup ***/
if (dvddirlength % 2048)
{
i = dvddirlength % 2048;
dvd_read (readbuffer, 2048, discoffset);
memcpy (buffer + offset, readbuffer, i);
}
} }
else // load whole file else
{ {
dvd_read (readbuffer, 2048, discoffset); return UnZipFile (buffer, discoffset); // unzip from dvd
if (!IsZipFile (readbuffer))
{
for (i = 0; i < blocks; i++)
{
dvd_read (readbuffer, 2048, discoffset);
memcpy (buffer + offset, readbuffer, 2048);
offset += 2048;
discoffset += 2048;
ShowProgress ((char *)"Loading...", offset, length);
}
/*** And final cleanup ***/
if (dvddirlength % 2048)
{
i = dvddirlength % 2048;
dvd_read (readbuffer, 2048, discoffset);
memcpy (buffer + offset, readbuffer, i);
}
}
else
{
return UnZipBuffer (buffer, METHOD_DVD); // unzip from dvd
}
} }
return dvddirlength; return dvddirlength;
} }

View File

@ -13,17 +13,10 @@
int getpvd (); int getpvd ();
int ParseDVDdirectory (); int ParseDVDdirectory ();
int LoadDVDFile (unsigned char *buffer, int length); int LoadDVDFile (unsigned char *buffer);
bool TestDVD(); bool TestDVD();
int dvd_read (void *dst, unsigned int len, u64 offset); int dvd_read (void *dst, unsigned int len, u64 offset);
int dvd_safe_read (void *dst, unsigned int len, u64 offset);
bool SwitchDVDFolder(char dir[]); bool SwitchDVDFolder(char dir[]);
void SetDVDDriveType(); void SetDVDDriveType();
#ifdef HW_DOL
void dvd_motor_off ();
#endif
extern u64 dvddir;
extern int dvddirlength;
#endif #endif

View File

@ -24,8 +24,14 @@
#include "filesel.h" #include "filesel.h"
#include "preferences.h" #include "preferences.h"
// FAT file pointer - the only one we should ever use! FILE * filehandle;
FILE * fatfile;
extern unsigned char savebuffer[];
extern char output[16384];
extern int offset;
extern int selection;
extern char currentdir[MAXPATHLEN];
extern FILEENTRIES filelist[MAXFILES];
/**************************************************************************** /****************************************************************************
* fat_is_mounted * fat_is_mounted
@ -61,17 +67,18 @@ bool ChangeFATInterface(int method, bool silent)
{ {
devFound = true; devFound = true;
fatSetDefaultInterface(PI_INTERNAL_SD); fatSetDefaultInterface(PI_INTERNAL_SD);
fatEnableReadAhead (PI_INTERNAL_SD, 6, 64);
} }
#endif #endif
if (!devFound && FatIsMounted(PI_SDGECKO_A)) if (!devFound && FatIsMounted(PI_SDGECKO_A))
{ {
devFound = true; devFound = true;
fatSetDefaultInterface(PI_SDGECKO_A);
} }
if(!devFound && FatIsMounted(PI_SDGECKO_B)) if(!devFound && FatIsMounted(PI_SDGECKO_B))
{ {
devFound = true; devFound = true;
fatSetDefaultInterface(PI_SDGECKO_B);
} }
if(!devFound) if(!devFound)
{ {
@ -86,7 +93,6 @@ bool ChangeFATInterface(int method, bool silent)
{ {
devFound = true; devFound = true;
fatSetDefaultInterface(PI_USBSTORAGE); fatSetDefaultInterface(PI_USBSTORAGE);
fatEnableReadAhead (PI_USBSTORAGE, 6, 64);
} }
else else
{ {
@ -164,54 +170,44 @@ ParseFATdirectory(int method)
* LoadFATFile * LoadFATFile
***************************************************************************/ ***************************************************************************/
int int
LoadFATFile (char * rbuffer, int length) LoadFATFile (char *filename, int length)
{ {
char zipbuffer[2048]; /*char zipbuffer[2048];
FILE *handle;
unsigned char *rbuffer;
u32 size;*/
char filepath[MAXPATHLEN]; char filepath[MAXPATHLEN];
u32 size;
/* Check filename length */ /* Check filename length */
if (!MakeROMPath(filepath, METHOD_SD)) if ((strlen(currentdir)+1+strlen(filelist[selection].filename)) < MAXPATHLEN)
sprintf(filepath, "%s/%s",currentdir,filelist[selection].filename);
else
{ {
WaitPrompt((char*) "Maximum filepath length reached!"); WaitPrompt((char*) "Maximum filepath length reached!");
return -1; return -1;
} }
return loadVBAROM(filepath);
fatfile = fopen (filepath, "rb"); /*
if (fatfile > 0) handle = fopen (filepath, "rb");
if (handle > 0)
{ {
if(length > 0 && length <= 2048) // do a partial read (eg: to check file header) fread (zipbuffer, 1, 2048, handle);
if (IsZipFile (zipbuffer))
{ {
fread (rbuffer, 1, length, fatfile); size = UnZipFile (rbuffer, handle); // unzip from FAT
}
else
{
// Just load the file up
fseek(handle, 0, SEEK_END);
length = ftell(handle); // get filesize
fseek(handle, 2048, SEEK_SET); // seek back to point where we left off
memcpy (rbuffer, zipbuffer, 2048); // copy what we already read
fread (rbuffer + 2048, 1, length - 2048, handle);
size = length; size = length;
} }
else // load whole file fclose (handle);
{
fread (zipbuffer, 1, 2048, fatfile);
if (IsZipFile (zipbuffer))
{
size = UnZipBuffer ((unsigned char *)rbuffer, METHOD_SD); // unzip from FAT
}
else
{
// Just load the file up
fseek(fatfile, 0, SEEK_END);
size = ftell(fatfile); // get filesize
fseek(fatfile, 2048, SEEK_SET); // seek back to point where we left off
memcpy (rbuffer, zipbuffer, 2048); // copy what we already read
ShowProgress ((char *)"Loading...", 2048, size);
u32 offset = 2048;
while(offset < size)
{
offset += fread (rbuffer + offset, 1, (1024*512), fatfile); // read in 512K chunks
ShowProgress ((char *)"Loading...", offset, size);
}
}
}
fclose (fatfile);
return size; return size;
} }
else else
@ -219,29 +215,8 @@ LoadFATFile (char * rbuffer, int length)
WaitPrompt((char*) "Error opening file"); WaitPrompt((char*) "Error opening file");
return 0; return 0;
} }
}
/**************************************************************************** return 0;*/
* LoadFATSzFile
* Loads the selected file # from the specified 7z into rbuffer
* Returns file size
***************************************************************************/
int
LoadFATSzFile(char * filepath, unsigned char * rbuffer)
{
u32 size;
fatfile = fopen (filepath, "rb");
if (fatfile > 0)
{
size = SzExtractFile(filelist[selection].offset, rbuffer);
fclose (fatfile);
return size;
}
else
{
WaitPrompt((char*) "Error opening file");
return 0;
}
} }
/**************************************************************************** /****************************************************************************
@ -250,11 +225,15 @@ LoadFATSzFile(char * filepath, unsigned char * rbuffer)
int int
LoadBufferFromFAT (char *filepath, bool silent) LoadBufferFromFAT (char *filepath, bool silent)
{ {
int size = 0; FILE *handle;
int boffset = 0;
int read = 0;
fatfile = fopen (filepath, "rb"); ClearSaveBuffer ();
if (fatfile <= 0) handle = fopen (filepath, "rb");
if (handle <= 0)
{ {
if ( !silent ) if ( !silent )
{ {
@ -265,13 +244,15 @@ LoadBufferFromFAT (char *filepath, bool silent)
return 0; return 0;
} }
fseek(fatfile, 0, SEEK_END); // go to end of file /*** This is really nice, just load the file and decode it ***/
size = ftell(fatfile); // get filesize while ((read = fread (savebuffer + boffset, 1, 1024, handle)) > 0)
fseek(fatfile, 0, SEEK_SET); // go to start of file {
fread (savebuffer, 1, size, fatfile); boffset += read;
fclose (fatfile); }
return size; fclose (handle);
return boffset;
} }
/**************************************************************************** /****************************************************************************
@ -280,11 +261,13 @@ LoadBufferFromFAT (char *filepath, bool silent)
int int
SaveBufferToFAT (char *filepath, int datasize, bool silent) SaveBufferToFAT (char *filepath, int datasize, bool silent)
{ {
if (datasize) FILE *handle;
{
fatfile = fopen (filepath, "wb");
if (fatfile <= 0) if (datasize)
{
handle = fopen (filepath, "wb");
if (handle <= 0)
{ {
char msg[100]; char msg[100];
sprintf(msg, "Couldn't save %s", filepath); sprintf(msg, "Couldn't save %s", filepath);
@ -292,8 +275,10 @@ SaveBufferToFAT (char *filepath, int datasize, bool silent)
return 0; return 0;
} }
fwrite (savebuffer, 1, datasize, fatfile); fwrite (savebuffer, 1, datasize, handle);
fclose (fatfile); fclose (handle);
} }
ClearSaveBuffer ();
return datasize; return datasize;
} }

View File

@ -23,12 +23,10 @@
bool ChangeFATInterface(int method, bool silent); bool ChangeFATInterface(int method, bool silent);
int ParseFATdirectory(int method); int ParseFATdirectory(int method);
int LoadFATFile (char * fbuffer, int length); int LoadFATFile (char *filename, int length);
int LoadFATSzFile(char * filepath, unsigned char * rbuffer);
int SaveBufferToFAT (char *filepath, int datasize, bool silent); int SaveBufferToFAT (char *filepath, int datasize, bool silent);
int LoadBufferFromFAT (char *filepath, bool silent); int LoadBufferFromFAT (char *filepath, bool silent);
extern char currFATdir[MAXPATHLEN]; extern char currFATdir[MAXPATHLEN];
extern FILE * fatfile;
#endif #endif

View File

@ -14,7 +14,6 @@
#include <string.h> #include <string.h>
#include <wiiuse/wpad.h> #include <wiiuse/wpad.h>
#include <sys/dir.h> #include <sys/dir.h>
#include <malloc.h>
#ifdef WII_DVD #ifdef WII_DVD
extern "C" { extern "C" {
@ -32,12 +31,10 @@ extern "C" {
#include "input.h" #include "input.h"
#include "dvd.h" #include "dvd.h"
#include "smbop.h" #include "smbop.h"
#include "gcunzip.h"
int offset; int offset;
int selection; int selection;
char currentdir[MAXPATHLEN]; char currentdir[MAXPATHLEN];
char szpath[MAXPATHLEN];
int maxfiles; int maxfiles;
extern int screenheight; extern int screenheight;
@ -49,38 +46,20 @@ int hasloaded = 0;
// Global file entry table // Global file entry table
FILEENTRIES filelist[MAXFILES]; FILEENTRIES filelist[MAXFILES];
bool inSz = false;
unsigned char savebuffer[SAVEBUFFERSIZE] ATTRIBUTE_ALIGN (32);
char ROMFilename[512]; char ROMFilename[512];
bool ROMLoaded = false; int ROMSize = 0;
unsigned char *savebuffer = NULL;
/**************************************************************************** /****************************************************************************
* AllocSaveBuffer () * ClearSaveBuffer ()
* Clear and allocate the savebuffer * Clear the savebuffer
***************************************************************************/ ***************************************************************************/
void void
AllocSaveBuffer () ClearSaveBuffer ()
{ {
if (savebuffer != NULL) memset (savebuffer, 0, SAVEBUFFERSIZE);
free(savebuffer);
savebuffer = (unsigned char *) memalign(32, SAVEBUFFERSIZE);
memset (savebuffer, 0, SAVEBUFFERSIZE);
}
/****************************************************************************
* FreeSaveBuffer ()
* Free the savebuffer memory
***************************************************************************/
void
FreeSaveBuffer ()
{
if (savebuffer != NULL)
free(savebuffer);
savebuffer = NULL;
} }
/**************************************************************************** /****************************************************************************
@ -192,28 +171,6 @@ int UpdateDirName(int method)
} }
} }
bool MakeROMPath(char filepath[], int method)
{
char temppath[MAXPATHLEN];
// Check filename length
if ((strlen(currentdir)+1+strlen(filelist[selection].filename)) < MAXPATHLEN)
{
sprintf(temppath, "%s/%s",currentdir,filelist[selection].filename);
if(method == METHOD_SMB)
strcpy(filepath, SMBPath(temppath));
else
strcpy(filepath, temppath);
return true;
}
else
{
filepath[0] = 0;
return false;
}
}
/**************************************************************************** /****************************************************************************
* FileSortCallback * FileSortCallback
* *
@ -241,25 +198,6 @@ int FileSortCallback(const void *f1, const void *f2)
return stricmp(((FILEENTRIES *)f1)->filename, ((FILEENTRIES *)f2)->filename); return stricmp(((FILEENTRIES *)f1)->filename, ((FILEENTRIES *)f2)->filename);
} }
/****************************************************************************
* IsSz
*
* Checks if the specified file is a 7z
***************************************************************************/
bool IsSz()
{
if (strlen(filelist[selection].filename) > 4)
{
char * p = strrchr(filelist[selection].filename, '.');
if (p != NULL)
if(stricmp(p, ".7z") == 0)
return true;
}
return false;
}
/**************************************************************************** /****************************************************************************
* StripExt * StripExt
* *
@ -273,7 +211,7 @@ void StripExt(char* returnstring, char * inputstring)
strcpy (returnstring, inputstring); strcpy (returnstring, inputstring);
loc_dot = strrchr(returnstring,'.'); loc_dot = strrchr(returnstring,'.');
if (loc_dot != NULL) if (loc_dot != NULL)
*loc_dot = 0; // strip file extension *loc_dot = '\0'; // strip file extension
} }
/**************************************************************************** /****************************************************************************
@ -315,8 +253,8 @@ int FileSelector (int method)
p = PAD_ButtonsDown (0); p = PAD_ButtonsDown (0);
ph = PAD_ButtonsHeld (0); ph = PAD_ButtonsHeld (0);
#ifdef HW_RVL #ifdef HW_RVL
wm_ay = WPAD_Stick (0, 0, 0); wm_ay = WPAD_StickY (0, 0);
wm_sx = WPAD_Stick (0, 1, 1); wm_sx = WPAD_StickX (0, 1);
wp = WPAD_ButtonsDown (0); wp = WPAD_ButtonsDown (0);
wh = WPAD_ButtonsHeld (0); wh = WPAD_ButtonsHeld (0);
@ -334,25 +272,7 @@ int FileSelector (int method)
if (filelist[selection].flags) // This is directory if (filelist[selection].flags) // This is directory
{ {
/* update current directory and set new entry list if directory has changed */ /* update current directory and set new entry list if directory has changed */
int status; int status = UpdateDirName(method);
if(inSz && selection == 0) // inside a 7z, requesting to leave
{
if(method == METHOD_DVD)
{
// go to directory the 7z was in
dvddir = filelist[0].offset;
dvddirlength = filelist[0].length;
}
inSz = false;
status = 1;
SzClose();
}
else
{
status = UpdateDirName(method);
}
if (status == 1) // ok, open directory if (status == 1) // ok, open directory
{ {
switch (method) switch (method)
@ -384,42 +304,37 @@ int FileSelector (int method)
} }
else // this is a file else // this is a file
{ {
// 7z file - let's open it up to select a file inside // store the filename (w/o ext) - used for sram/freeze naming
if(IsSz()) StripExt(ROMFilename, filelist[selection].filename);
ShowAction ((char *)"Loading...");
switch (method)
{ {
// we'll store the 7z filepath for extraction later case METHOD_SD:
if(!MakeROMPath(szpath, method)) case METHOD_USB:
{ ROMSize = LoadFATFile (filelist[selection].filename, filelist[selection].length);
WaitPrompt((char*) "Maximum filepath length reached!"); break;
return -1;
} case METHOD_DVD:
int szfiles = SzParse(szpath, method); dvddir = filelist[selection].offset;
if(szfiles) dvddirlength = filelist[selection].length;
{ //ROMSize = LoadDVDFile (Memory.ROM);
maxfiles = szfiles; break;
inSz = true;
} case METHOD_SMB:
else //ROMSize = LoadSMBFile (filelist[selection].filename, filelist[selection].length);
WaitPrompt((char*) "Error opening archive!"); break;
}
if (ROMSize > 0)
{
return 1;
} }
else else
{ {
// store the filename (w/o ext) - used for sram/freeze naming WaitPrompt((char*) "Error loading ROM!");
StripExt(ROMFilename, filelist[selection].filename);
ShowAction ((char *)"Loading...");
ROMLoaded = LoadVBAROM(method);
inSz = false;
if (ROMLoaded)
{
return 1;
}
else
{
WaitPrompt((char*) "Error loading ROM!");
}
} }
} }
redraw = 1; redraw = 1;
@ -613,7 +528,7 @@ OpenFAT (int method)
{ {
if(ChangeFATInterface(method, NOTSILENT)) if(ChangeFATInterface(method, NOTSILENT))
{ {
// change current dir to vba roms directory // change current dir to snes roms directory
sprintf ( currentdir, "%s/%s", ROOTFATDIR, GCSettings.LoadFolder ); sprintf ( currentdir, "%s/%s", ROOTFATDIR, GCSettings.LoadFolder );
// Parse initial root directory and get entries list // Parse initial root directory and get entries list

View File

@ -11,11 +11,9 @@
#ifndef _NGCFILESEL_ #ifndef _NGCFILESEL_
#define _NGCFILESEL_ #define _NGCFILESEL_
#include <unistd.h> #define SAVEBUFFERSIZE ((512 * 1024) + 2048 + 64 + 4 + 4)
#define SAVEBUFFERSIZE (512 * 1024)
#define MAXJOLIET 255 #define MAXJOLIET 255
#define MAXDISPLAY 40 #define MAXDISPLAY 54
typedef struct typedef struct
{ {
@ -28,18 +26,9 @@ typedef struct
#define MAXFILES 2000 // Restrict to 2000 files per dir #define MAXFILES 2000 // Restrict to 2000 files per dir
extern FILEENTRIES filelist[MAXFILES]; extern FILEENTRIES filelist[MAXFILES];
extern unsigned char *savebuffer;
extern int offset;
extern int selection;
extern char currentdir[MAXPATHLEN];
extern char szpath[MAXPATHLEN];
extern bool inSz;
extern int maxfiles;
extern char ROMFilename[512]; extern char ROMFilename[512];
void AllocSaveBuffer(); void ClearSaveBuffer ();
void FreeSaveBuffer();
bool MakeROMPath(char filepath[], int method);
int OpenROM (int method); int OpenROM (int method);
int autoLoadMethod(); int autoLoadMethod();
int autoSaveMethod(); int autoSaveMethod();

View File

@ -14,19 +14,11 @@
#include <string.h> #include <string.h>
#include <zlib.h> #include <zlib.h>
extern "C" {
#include "../sz/7zCrc.h"
#include "../sz/7zIn.h"
#include "../sz/7zExtract.h"
}
#include "dvd.h" #include "dvd.h"
#include "smbop.h" #include "smbop.h"
#include "fileop.h"
#include "video.h" #include "video.h"
#include "menudraw.h" #include "menudraw.h"
#include "gcunzip.h" #include "gcunzip.h"
#include "vba.h"
/* /*
* PKWare Zip Header - adopted into zip standard * PKWare Zip Header - adopted into zip standard
@ -67,7 +59,7 @@ FLIP16 (u16 b)
* IsZipFile * IsZipFile
* *
* Returns TRUE when PKZIPID is first four characters of buffer * Returns TRUE when PKZIPID is first four characters of buffer
***************************************************************************/ ****************************************************************************/
int int
IsZipFile (char *buffer) IsZipFile (char *buffer)
{ {
@ -81,14 +73,17 @@ IsZipFile (char *buffer)
return 0; return 0;
} }
/***************************************************************************** /*****************************************************************************
* UnZipBuffer * unzip
* *
* It should be noted that there is a limit of 5MB total size for any ROM * It should be noted that there is a limit of 5MB total size for any ROM
******************************************************************************/ ******************************************************************************/
FILE* fatfile; // FAT
u64 discoffset; // DVD
SMBFILE smbfile; // SMB
int int
UnZipBuffer (unsigned char *outbuffer, int method) UnZipBuffer (unsigned char *outbuffer, short where)
{ {
PKZIPHEADER pkzip; PKZIPHEADER pkzip;
int zipoffset = 0; int zipoffset = 0;
@ -100,25 +95,23 @@ UnZipBuffer (unsigned char *outbuffer, int method)
int readoffset = 0; int readoffset = 0;
int have = 0; int have = 0;
char readbuffer[ZIPCHUNK]; char readbuffer[ZIPCHUNK];
u64 discoffset = 0; char msg[128];
// Read Zip Header /*** Read Zip Header ***/
switch (method) switch (where)
{ {
case METHOD_SD: case 0: // SD Card
case METHOD_USB: fseek(fatfile, 0, SEEK_SET);
fseek(fatfile, 0, SEEK_SET); fread (readbuffer, 1, ZIPCHUNK, fatfile);
fread (readbuffer, 1, ZIPCHUNK, fatfile); break;
break;
case METHOD_DVD: case 1: // DVD
discoffset = dvddir; dvd_read (readbuffer, ZIPCHUNK, discoffset);
dvd_read (readbuffer, ZIPCHUNK, discoffset); break;
break;
case METHOD_SMB: case 2: // From SMB
SMB_ReadFile(readbuffer, ZIPCHUNK, 0, smbfile); SMB_ReadFile(readbuffer, ZIPCHUNK, 0, smbfile);
break; break;
} }
/*** Copy PKZip header to local, used as info ***/ /*** Copy PKZip header to local, used as info ***/
@ -126,7 +119,9 @@ UnZipBuffer (unsigned char *outbuffer, int method)
pkzip.uncompressedSize = FLIP32 (pkzip.uncompressedSize); pkzip.uncompressedSize = FLIP32 (pkzip.uncompressedSize);
ShowProgress ((char *)"Loading...", 0, pkzip.uncompressedSize); sprintf (msg, "Unzipping %d bytes ... Wait",
pkzip.uncompressedSize);
ShowAction (msg);
/*** Prepare the zip stream ***/ /*** Prepare the zip stream ***/
memset (&zs, 0, sizeof (z_stream)); memset (&zs, 0, sizeof (z_stream));
@ -176,28 +171,26 @@ UnZipBuffer (unsigned char *outbuffer, int method)
} }
while (zs.avail_out == 0); while (zs.avail_out == 0);
// Readup the next 2k block /*** Readup the next 2k block ***/
zipoffset = 0; zipoffset = 0;
zipchunk = ZIPCHUNK; zipchunk = ZIPCHUNK;
switch (method) switch (where)
{ {
case METHOD_SD: case 0: // SD Card
case METHOD_USB: fread (readbuffer, 1, ZIPCHUNK, fatfile);
fread (readbuffer, 1, ZIPCHUNK, fatfile); break;
break;
case METHOD_DVD: case 1: // DVD
readoffset += ZIPCHUNK; readoffset += ZIPCHUNK;
dvd_safe_read (readbuffer, ZIPCHUNK, discoffset+readoffset); dvd_read (readbuffer, ZIPCHUNK, discoffset+readoffset);
break; break;
case METHOD_SMB: case 2: // From SMB
readoffset += ZIPCHUNK; readoffset += ZIPCHUNK;
SMB_ReadFile(readbuffer, ZIPCHUNK, readoffset, smbfile); SMB_ReadFile(readbuffer, ZIPCHUNK, readoffset, smbfile);
break; break;
} }
ShowProgress ((char *)"Loading...", bufferoffset, pkzip.uncompressedSize);
} }
while (res != Z_STREAM_END); while (res != Z_STREAM_END);
@ -213,344 +206,24 @@ UnZipBuffer (unsigned char *outbuffer, int method)
return 0; return 0;
} }
// Reading from FAT
/****************************************************************************
* GetFirstZipFilename
*
* Returns the filename of the first file in the zipped archive
* The idea here is to do the least amount of work required
***************************************************************************/
char *
GetFirstZipFilename (int method)
{
char * firstFilename = NULL;
char tempbuffer[ZIPCHUNK];
// read start of ZIP
switch (method)
{
case METHOD_SD: // SD Card
case METHOD_USB: // USB
LoadFATFile (tempbuffer, ZIPCHUNK);
break;
case METHOD_DVD: // DVD
LoadDVDFile ((unsigned char *)tempbuffer, ZIPCHUNK);
break;
case METHOD_SMB: // From SMB
LoadSMBFile (tempbuffer, ZIPCHUNK);
break;
}
tempbuffer[28] = 0; // truncate - filename length is 2 bytes long (bytes 26-27)
int namelength = tempbuffer[26]; // filename length starts 26 bytes in
firstFilename = &tempbuffer[30]; // first filename of a ZIP starts 31 bytes in
firstFilename[namelength] = 0; // truncate at filename length
return firstFilename;
}
/****************************************************************************
* 7z functions
***************************************************************************/
typedef struct _SzFileInStream
{
ISzInStream InStream;
u64 offset; // offset of the file
unsigned int len; // length of the file
u64 pos; // current position of the file pointer
} SzFileInStream;
// 7zip error list
char szerrormsg[][30] = {
"7z: Data error",
"7z: Out of memory",
"7z: CRC Error",
"7z: Not implemented",
"7z: Fail",
"7z: Archive error",
"7z: Dictionary too large",
};
SZ_RESULT SzRes;
SzFileInStream SzArchiveStream;
CArchiveDatabaseEx SzDb;
ISzAlloc SzAllocImp;
ISzAlloc SzAllocTempImp;
UInt32 SzBlockIndex = 0xFFFFFFFF;
size_t SzBufferSize;
size_t SzOffset;
size_t SzOutSizeProcessed;
CFileItem *SzF;
char sz_buffer[2048];
int szMethod = 0;
/****************************************************************************
* Is7ZipFile
*
* Returns 1 when 7z signature is found
****************************************************************************/
int int
Is7ZipFile (char *buffer) UnZipFile (unsigned char *outbuffer, FILE* infile)
{ {
unsigned int *check; fatfile = infile;
check = (unsigned int *) buffer; return UnZipBuffer(outbuffer, 0);
// 7z signature
static Byte Signature[6] = {'7', 'z', 0xBC, 0xAF, 0x27, 0x1C};
int i;
for(i = 0; i < 6; i++)
if(buffer[i] != Signature[i])
return 0;
return 1; // 7z archive found
} }
// Reading from DVD
// display an error message int
void SzDisplayError(SZ_RESULT res) UnZipFile (unsigned char *outbuffer, u64 inoffset)
{ {
WaitPrompt(szerrormsg[(res - 1)]); discoffset = inoffset;
return UnZipBuffer(outbuffer, 1);
} }
// Reading from SMB
// function used by the 7zip SDK to read data from SD/USB/DVD/SMB int
SZ_RESULT SzFileReadImp(void *object, void **buffer, size_t maxRequiredSize, size_t *processedSize) UnZipFile (unsigned char *outbuffer, SMBFILE infile)
{ {
// the void* object is a SzFileInStream smbfile = infile;
SzFileInStream *s = (SzFileInStream *) object; return UnZipBuffer(outbuffer, 2);
// calculate offset
u64 offset = (u64) (s->offset + s->pos);
if (maxRequiredSize > 2048)
maxRequiredSize = 2048;
// read data
switch (szMethod)
{
case METHOD_SD:
case METHOD_USB:
fseek(fatfile, offset, SEEK_SET);
fread(sz_buffer, 1, maxRequiredSize, fatfile);
break;
case METHOD_DVD:
dvd_safe_read(sz_buffer, maxRequiredSize, offset);
break;
case METHOD_SMB:
SMB_ReadFile(sz_buffer, maxRequiredSize, offset, smbfile);
break;
}
*buffer = sz_buffer;
*processedSize = maxRequiredSize;
s->pos += *processedSize;
if(maxRequiredSize > 1024) // only show progress for large reads
// this isn't quite right, but oh well
ShowProgress ((char *)"Loading...", s->pos, filelist[selection].length);
return SZ_OK;
}
// function used by the 7zip SDK to change the filepointer
SZ_RESULT SzFileSeekImp(void *object, CFileSize pos)
{
// the void* object is a SzFileInStream
SzFileInStream *s = (SzFileInStream *) object;
// check if the 7z SDK wants to move the pointer to somewhere after the EOF
if (pos >= s->len)
{
WaitPrompt((char *) "7z: Error - attempt to read after EOF!");
return SZE_FAIL;
}
// save new position and return
s->pos = pos;
return SZ_OK;
}
/****************************************************************************
* SzParse
*
* Opens a 7z file, and parses it
* Right now doesn't parse 7z, since we'll always use the first file
* But it could parse the entire 7z for full browsing capability
***************************************************************************/
int SzParse(char * filepath, int method)
{
int nbfiles = 0;
// save the offset and the length of this file inside the archive stream structure
SzArchiveStream.offset = filelist[selection].offset;
SzArchiveStream.len = filelist[selection].length;
SzArchiveStream.pos = 0;
// open file
switch (method)
{
case METHOD_SD:
case METHOD_USB:
fatfile = fopen (filepath, "rb");
if(!fatfile)
return 0;
break;
case METHOD_SMB:
smbfile = OpenSMBFile(filepath);
if(!smbfile)
return 0;
break;
}
// set szMethod to current chosen load method
szMethod = method;
// set handler functions for reading data from FAT/SMB/DVD
SzArchiveStream.InStream.Read = SzFileReadImp;
SzArchiveStream.InStream.Seek = SzFileSeekImp;
// set default 7Zip SDK handlers for allocation and freeing memory
SzAllocImp.Alloc = SzAlloc;
SzAllocImp.Free = SzFree;
SzAllocTempImp.Alloc = SzAllocTemp;
SzAllocTempImp.Free = SzFreeTemp;
// prepare CRC and 7Zip database structures
InitCrcTable();
SzArDbExInit(&SzDb);
// open the archive
SzRes = SzArchiveOpen(&SzArchiveStream.InStream, &SzDb, &SzAllocImp,
&SzAllocTempImp);
if (SzRes != SZ_OK)
{
SzDisplayError(SzRes);
// free memory used by the 7z SDK
SzClose();
}
else // archive opened successfully
{
if(SzDb.Database.NumFiles > 0)
{
// Parses the 7z into a full file listing
// erase all previous entries
memset(&filelist, 0, sizeof(FILEENTRIES) * MAXFILES);
// add '..' folder in case the user wants exit the 7z
strncpy(filelist[0].displayname, "..", 2);
filelist[0].flags = 1;
filelist[0].offset = dvddir;
filelist[0].length = dvddirlength;
// get contents and parse them into file list structure
unsigned int SzI, SzJ;
SzJ = 1;
for (SzI = 0; SzI < SzDb.Database.NumFiles; SzI++)
{
SzF = SzDb.Database.Files + SzI;
// skip directories
if (SzF->IsDirectory)
continue;
// do not exceed MAXFILES to avoid possible buffer overflows
if (SzJ == (MAXFILES - 1))
break;
// parse information about this file to the dvd file list structure
strncpy(filelist[SzJ].filename, SzF->Name, MAXJOLIET); // copy joliet name (useless...)
filelist[SzJ].filename[MAXJOLIET] = 0; // terminate string
strncpy(filelist[SzJ].displayname, SzF->Name, MAXDISPLAY+1); // crop name for display
filelist[SzJ].length = SzF->Size; // filesize
filelist[SzJ].offset = SzI; // the extraction function identifies the file with this number
filelist[SzJ].flags = 0; // only files will be displayed (-> no flags)
SzJ++;
}
// update maxfiles and select the first entry
offset = selection = 0;
nbfiles = SzJ;
}
else
{
SzArDbExFree(&SzDb, SzAllocImp.Free);
}
}
// close file
switch (method)
{
case METHOD_SD:
case METHOD_USB:
fclose(fatfile);
break;
case METHOD_SMB:
SMB_CloseFile (smbfile);
break;
}
return nbfiles;
}
/****************************************************************************
* SzClose
*
* Closes a 7z file
***************************************************************************/
void SzClose()
{
if(SzDb.Database.NumFiles > 0)
SzArDbExFree(&SzDb, SzAllocImp.Free);
}
/****************************************************************************
* SzExtractFile
*
* Extracts the given file # into the buffer specified
* Must parse the 7z BEFORE running this function
***************************************************************************/
int SzExtractFile(int i, unsigned char *buffer)
{
// prepare some variables
SzBlockIndex = 0xFFFFFFFF;
SzOffset = 0;
// Unzip the file
SzRes = SzExtract2(
&SzArchiveStream.InStream,
&SzDb,
i, // index of file
&SzBlockIndex, // index of solid block
&buffer,
&SzBufferSize,
&SzOffset, // offset of stream for required file in *outBuffer
&SzOutSizeProcessed, // size of file in *outBuffer
&SzAllocImp,
&SzAllocTempImp);
// close 7Zip archive and free memory
SzClose();
// check for errors
if(SzRes != SZ_OK)
{
// display error message
SzDisplayError(SzRes);
return 0;
}
else
{
return SzOutSizeProcessed;
}
} }

View File

@ -12,12 +12,11 @@
#include <smb.h> #include <smb.h>
int IsZipFile (char *buffer); extern int IsZipFile (char *buffer);
char * GetFirstZipFilename(int method);
int UnZipBuffer (unsigned char *outbuffer, int method); int UnZipFile (unsigned char *outbuffer, FILE* infile); // Reading from FAT
int SzParse(char * filepath, int method); int UnZipFile (unsigned char *outbuffer, u64 inoffset); // Reading from DVD
int SzExtractFile(int i, unsigned char *buffer); int UnZipFile (unsigned char *outbuffer, SMBFILE infile); // Reading from SMB
void SzClose();
/* /*
* Zip file header definition * Zip file header definition

File diff suppressed because it is too large Load Diff

View File

@ -5,71 +5,135 @@
#ifndef _IMGSAVEICON_ #ifndef _IMGSAVEICON_
#define _IMGSAVEICON_ #define _IMGSAVEICON_
const unsigned long saveicon[32*32] = { const unsigned short saveicon[1024] = {
0x579A5753, 0x579A5753, 0x579A5753, 0x579A5753, 0x579A5753, 0x579A5753, 0x579A5753, 0x579A5753, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0x579A5753, 0x579A5753, 0x579A5753, 0x579A5753, 0x579A5753, 0x579A5753, 0x579A5753, 0x579A5753, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0x589B5852, 0x589B5852, 0x589B5852, 0x589B5852, 0x589B5852, 0x589B5852, 0x589B5852, 0x589B5852, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0x589B5852, 0x589B5852, 0x589B5852, 0x589B5852, 0x589B5852, 0x589B5852, 0x589B5852, 0x589B5852, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0x589B5852, 0x589B5852, 0x589B5852, 0x589B5852, 0x589B5852, 0x589B5852, 0x589B5852, 0x589B5852, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0x589B5852, 0x589B5852, 0x589B5852, 0x589B5852, 0x589B5852, 0x589B5852, 0x589B5852, 0x589B5852, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0x599B5951, 0x599B5951, 0x599B5951, 0x599B5951, 0x599B5951, 0x599B5951, 0x599B5951, 0x599B5951, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0x599B5951, 0x599B5951, 0x599B5951, 0x599B5951, 0x5A9B5951, 0x599B5951, 0x599B5951, 0x599B5951, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0x5A9B5A51, 0x5A9B5A51, 0x5A9B5A51, 0x5A9B5A51, 0x5A9B5A51, 0x5A9B5A51, 0x5A9B5A51, 0x5A9B5A51, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0x5A9B5A51, 0x5A9B5A51, 0x5A9B5A51, 0x5A9B5A51, 0x5A9B5A51, 0x5A9B5A51, 0x5A9B5A51, 0x5A9B5A51, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0x5B9C5B51, 0x5B9C5B51, 0x5B9C5B51, 0x5B9C5B51, 0x5B9C5B51, 0x5B9C5B51, 0x5B9C5B51, 0x5B9C5B51, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0x5B9C5B51, 0x5B9C5B51, 0x5B9C5B51, 0x5B9C5B51, 0x5B9C5B51, 0x5B9C5B51, 0x5B9C5C50, 0x5B9C5B51, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0x5C9C5C50, 0x5C9C5C50, 0x5C9C5C50, 0x5C9C5C50, 0x5C9C5C50, 0x5C9C5C50, 0x5C9C5C50, 0x5C9C5C50, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0x5C9C5C50, 0x5C9C5C50, 0x5C9C5C50, 0x5C9C5C50, 0x5C9C5C50, 0x5C9C5C50, 0x5C9C5C50, 0x5C9C5C50, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0x5D9C5C50, 0x5C9C5D50, 0x5C9C5C50, 0x5D9C5C50, 0x5D9C5C50, 0x5D9C5C50, 0x5D9C5C50, 0x5C9C5C50, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0x5C9C5C50, 0x5C9C5D50, 0x5C9C5C50, 0x5C9C5C50, 0x5C9C5C50, 0x5C9C5C50, 0x5C9C5C50, 0x5C9C5D50, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0x5D9C5D50, 0x5E9C5E4F, 0x5D9C5E4F, 0x5E9C5D4F, 0x5E9C5E4F, 0x5D9C5E4F, 0x5D9C5E4F, 0x5E9C5D4F, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0x5E9C5E4F, 0x5E9C5E4F, 0x5D9C5D50, 0x5D9C5D50, 0x5D9C5D50, 0x5E9C5E4F, 0x5E9C5D4F, 0x5E9C5D4F, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0x5E9D5E4F, 0x5E9D5E4F, 0x5E9D5E4F, 0x5E9D5E4F, 0x5E9D5E4F, 0x5E9D5E4F, 0x5F9D5E4F, 0x5E9D5E4F, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0x5E9D5E4F, 0x5E9D5F4F, 0x5E9D5E4F, 0x5F9D5E4F, 0x5E9D5F4F, 0x5E9D5E4F, 0x5E9D5E4F, 0x5F9D5E4F, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0x5F9B5351, 0x27860075, 0x00862775, 0x5F9D5F4E, 0x27860075, 0x12882770, 0x00800080, 0x00800080, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xE73F,
0x00800080, 0x1F8F4765, 0x5F9D5F4F, 0x5A93275E, 0x00800080, 0x26914D62, 0x5F9D5F4E, 0x5F9D5F4E, 0xFFFF, 0xFFFF, 0xB5BF, 0x801F, 0xFFFF, 0xD29F, 0x801F, 0x801F,
0x60952C5B, 0x6551C69C, 0xCD631B91, 0x53974658, 0x3761D091, 0xA766468F, 0xD658D898, 0xD85AD897, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xA11E, 0x843C, 0x8439, 0x9CF7,
0xD755D399, 0x89741F81, 0x549B6051, 0x337C6179, 0xD454D49A, 0x7B77267F, 0x609D604E, 0x609D604E, 0x801F, 0x801F, 0x801C, 0x8018, 0x801F, 0x801F, 0x801C, 0x8018,
0x609A4654, 0x2F53BB9B, 0xC5595197, 0x3A903363, 0x5E58C998, 0x5D69428D, 0xCA4ACBA0, 0xCC4CCC9F, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xEB5C, 0xFFFF, 0xFFFF, 0xFFFF,
0xCB49C7A1, 0xC554699A, 0x2D95615B, 0x136EA387, 0xD050D09C, 0xBB67068D, 0x609E604E, 0x619D604E, 0x800F, 0xB9D3, 0xFFFF, 0xFFFF, 0x8013, 0x8008, 0xDAD7, 0xFFFF,
0x629D624D, 0x0D5E9891, 0xBC4D779F, 0x27881370, 0x9E4AC1A1, 0x326B3E8C, 0xBA3ABBAA, 0x25790084, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0x0062A292, 0xBC459AA4, 0x138F5465, 0x1A60C893, 0xBE4DCC9E, 0xC4583198, 0x48996254, 0x629D624D, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0x639E624D, 0x276A6386, 0xB03CA4A9, 0x0D7D197F, 0xBE3F9EA7, 0x0D733985, 0xAF31B3B0, 0x24780084, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0x00609E93, 0xB94C589F, 0x34903564, 0x5851BF9C, 0x7350B49D, 0xBB466BA3, 0x2795625C, 0x629E634D, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0x639E634C, 0x427B3578, 0xA42BB1B4, 0x3167498E, 0xB13E66A8, 0x2776367F, 0xA426A7B7, 0xAC2DAFB2, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0xAF30B1B0, 0x786C2186, 0x5E921A60, 0x853EB2A8, 0x2E5D6A94, 0xAE3293AF, 0x0D916363, 0x639E634C, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0x659F644C, 0x65900664, 0x9529A3B7, 0x4E4D6F9F, 0xA34041A7, 0x3C7A347A, 0x9F26A0B9, 0xA126A2B9, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0xA225A3B8, 0xA74050A6, 0x2F811776, 0xAA2A9AB4, 0x006E418B, 0xA425A4B8, 0x20825070, 0x649F654C, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0x659E654C, 0x65931B5F, 0x73349EB2, 0x753695B0, 0x94570799, 0x437B3478, 0x9D289EBB, 0x1F770085, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0x005F7595, 0xA12998B7, 0x076B4B8B, 0xA1269FB9, 0x9E289EBB, 0x9E27A0B9, 0x4B73357F, 0x659E654C, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0x659F654C, 0x65983C56, 0x3D439AAA, 0x9A299ABC, 0x70641B8F, 0x437C3378, 0x9B299CBB, 0x1F770085, 0xFFFF, 0x801F, 0x801F, 0x885F, 0xFFFF, 0x98D6, 0x801F, 0x801F,
0x00626993, 0x9E2B93B9, 0x07617393, 0x992A97BC, 0x962C96BD, 0x982A9BBC, 0x7E5F1492, 0x659F654C, 0xFFFF, 0xFFFF, 0xFFFF, 0x843C, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0x679F674B, 0x669D594E, 0x144F97A2, 0x962C96BD, 0x46743680, 0x447B3278, 0x972B97BD, 0x972B97BD, 0xFBDF, 0x801E, 0x801B, 0x8017, 0x801E, 0x801B, 0x8018, 0x8015,
0x972B97BD, 0x983965B2, 0x0A558D9E, 0x8A560A9F, 0x00800080, 0x454197AD, 0x9A4E14A2, 0x599D674E, 0x801A, 0x8018, 0x8015, 0x8011, 0x8016, 0x8014, 0x8011, 0x800D,
0x679F674A, 0x679F674A, 0x14617793, 0x932D93BF, 0x14875A6C, 0x447C3178, 0x932D92BF, 0x922D92BF, 0x8012, 0x800B, 0x8848, 0xFFFF, 0x8010, 0x8009, 0x8003, 0xFFFF,
0x922D92BF, 0x586C228A, 0x444393AE, 0x6B651B8F, 0x679C534F, 0x1D4D95A5, 0x974148AC, 0x37976756, 0x800C, 0x8007, 0x8006, 0xFFFF, 0x8008, 0x8005, 0xA52E, 0xFFFF,
0x68A0674A, 0x68A0684A, 0x3F8C146A, 0x00800080, 0x2A966859, 0x68962A59, 0x00800080, 0x00800080, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0x00800080, 0x2A93545F, 0x2A860075, 0x1B8E4766, 0x68A0674A, 0x2A860075, 0x00862A74, 0x639F674B, 0xFFFF, 0xFFFF, 0xFBBD, 0xF1EF, 0xFFFF, 0xF508, 0xF000, 0xEC00,
0x699F684A, 0x699F694A, 0x699F684A, 0x699F694A, 0x699F694A, 0x699F694A, 0x699F694A, 0x699F694A, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0x699F694A, 0x699F694A, 0x699F694A, 0x699F694A, 0x699F694A, 0x699F694A, 0x699F694A, 0x699F694A, 0xE56B, 0xE16B, 0xE673, 0xFFFF, 0xE800, 0xDC00, 0xCC00, 0xB400,
0x6AA06949, 0x69A0694A, 0x69A06A49, 0x69A06A49, 0x6AA06949, 0x69A0694A, 0x69A0694A, 0x69A0694A, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0x6AA06949, 0x69A06A49, 0x69A06A49, 0x69A0694A, 0x69A0694A, 0x6AA06949, 0x69A0694A, 0x69A0694A, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xDE94, 0xFFFF, 0xFFFF, 0xFFFF,
0x6BA06A49, 0x6AA06A49, 0x6BA06B49, 0x6AA06B49, 0x6AA06B49, 0x6BA06B49, 0x6AA06B49, 0x6BA06B49, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0x6BA06B49, 0x6BA06A49, 0x6BA06A49, 0x6AA06B49, 0x6BA06B49, 0x6BA06A49, 0x6AA06B49, 0x6BA06B49, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xEBBA,
0x6CA16B48, 0x6BA16B48, 0x6BA16B48, 0x6BA16B48, 0x6BA16B48, 0x6BA16B48, 0x6BA16B48, 0x6BA16B48, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0x6BA16B48, 0x6BA16B48, 0x6BA16B48, 0x6BA16B48, 0x6BA16B48, 0x6BA16B48, 0x6BA16B48, 0x6BA16B48, 0xFFFF, 0xFFFF, 0xEFBA, 0xE378, 0xB2EB, 0x9AA4, 0x9AA5, 0x9AA5,
0x6CA16C48, 0x6CA16C48, 0x6CA16C48, 0x6CA16C48, 0x6CA16C48, 0x6CA16C48, 0x6CA16C48, 0x6CA16C48, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0x6CA16C48, 0x6CA16C48, 0x6CA16C48, 0x6CA16C48, 0x6CA16C48, 0x6CA16C48, 0x6CA16C48, 0x6CA16C48, 0xE778, 0xF3BC, 0xFFFF, 0xFFFF, 0x9A84, 0x9623, 0x91E3, 0xB66C,
0x6DA16C48, 0x6DA16D48, 0x6DA16D48, 0x6DA16D48, 0x6DA16C48, 0x6CA16D48, 0x6CA16D48, 0x6DA16D48, 0xD6BB, 0x800E, 0x800C, 0x8008, 0xFFFF, 0x8C6A, 0x8004, 0x8004,
0x6DA16D48, 0x6DA16D48, 0x6CA16D48, 0x6DA16D48, 0x6DA16D48, 0x6DA16D48, 0x6CA16D48, 0x6DA16D48, 0xFFFF, 0xFFFF, 0xB191, 0xDAD8, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0x6EA16E47, 0x6DA16D47, 0x6DA16D47, 0x6DA16D47, 0x6DA16D47, 0x6EA16D47, 0x6DA16D47, 0x6DA16E47, 0x8006, 0x8004, 0xFFFF, 0xFFFF, 0x8006, 0xF39D, 0xFFFF, 0xFA94,
0x6DA16D47, 0x6DA16D47, 0x6DA16E47, 0x6DA16D47, 0x6DA16D47, 0x6EA16D47, 0x6DA16D47, 0x6DA16D47, 0xFFFF, 0xFFFF, 0xFFFF, 0xEC21, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0x6EA16E46, 0x6EA16E46, 0x6EA16E47, 0x6EA16E46, 0x6EA16E46, 0x6EA16E46, 0x6EA16E46, 0x6EA16E47, 0xF484, 0xF800, 0xF800, 0xF000, 0xF800, 0xF800, 0xFD6B, 0xF8C6,
0x6EA16E46, 0x6EA16E47, 0x6EA16E46, 0x6EA16E46, 0x6EA16E47, 0x6EA16E46, 0x6EA16E46, 0x6EA16E46, 0xF400, 0xF400, 0xFDEF, 0xF4A5, 0xFF18, 0xEC63, 0xE400, 0xE000,
0x6FA26F47, 0x6FA16E46, 0x6FA16E46, 0x6FA26F47, 0x6FA26F47, 0x6FA26F47, 0x6FA26F47, 0x6FA26F47, 0xE800, 0xE000, 0xD400, 0xC400, 0xE400, 0xE000, 0xD000, 0xC400,
0x6FA26F47, 0x6FA26F47, 0x6FA26F47, 0x6FA26F47, 0x6FA26F47, 0x6FA26F47, 0x6FA26F47, 0x6FA26F47, 0xE000, 0xD800, 0xCC00, 0xC000, 0xD800, 0xD000, 0xC400, 0xB800,
0x70A27046, 0x70A27046, 0x70A27046, 0x70A27046, 0x70A27046, 0x70A27046, 0x70A27046, 0x70A27046, 0xA400, 0xD673, 0xFFFF, 0xFFFF, 0xB400, 0x9000, 0xFFFF, 0xFFFF,
0x70A27046, 0x70A27046, 0x70A27046, 0x70A27046, 0x70A27046, 0x70A27046, 0x70A27046, 0x70A27046, 0xB000, 0x9000, 0xFFFF, 0xFFFF, 0xA800, 0x9000, 0xFFFF, 0xFFFF,
0xFFFF, 0xFFFF, 0xDB75, 0x9AE4, 0xFFFF, 0xFFFF, 0x9A84, 0xA6E7,
0xFFFF, 0xFFFF, 0xA1E7, 0x9604, 0xFFFF, 0xFFFF, 0xFFFF, 0x8D03,
0xA707, 0xA708, 0xAF2A, 0xAF2A, 0xA6E7, 0xA2C7, 0xBF4E, 0xCB71,
0x9E46, 0x9E26, 0x9A25, 0x9604, 0x80E0, 0x8922, 0x8D22, 0x8D22,
0xA2C7, 0xA2A7, 0x9E66, 0x95E4, 0xA2A6, 0x9E46, 0x9E25, 0x95C4,
0x99E5, 0x95C4, 0x9163, 0x8D02, 0x88E2, 0x84A1, 0x8060, 0x8020,
0x8500, 0xF7BD, 0xFFFF, 0xFFFF, 0x8901, 0xA148, 0xFFFF, 0xFFFF,
0x8040, 0xB9ED, 0xFFFF, 0xFFFF, 0x9926, 0xFFFF, 0xFFFF, 0xFFFF,
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0xFFFF, 0xFFFF, 0xE529, 0xD400, 0xFFFF, 0xFFFF, 0xFFFF, 0xD4C6,
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0xD000, 0xC400, 0xBC00, 0xB000, 0xC000, 0xB800, 0xAC00, 0xA000,
0xA800, 0xA800, 0x9C00, 0x9400, 0xC18C, 0x8C00, 0x8C00, 0x8C00,
0x9C00, 0x8C00, 0xFFFF, 0xFFFF, 0x9400, 0x8C00, 0xFFFF, 0xFFFF,
0x8800, 0xDEB5, 0xFFFF, 0xFFFF, 0xE2D6, 0xFFFF, 0xFFFF, 0xFFFF,
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0xD6D5, 0xAD8A, 0x8CC3, 0x8060, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0x8060, 0x90E4, 0xB1CC, 0xE759, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFF, 0xF7AF,
0xFFFF, 0xFFFF, 0xFBDC, 0xF7B1, 0xFFFB, 0xFFE2, 0xFFE0, 0xFFE0,
0xFFE0, 0xFFE0, 0xFFE0, 0xFFE0, 0xFFE0, 0xFFE0, 0xFFE0, 0xFFE5,
0xF38C, 0xEF6A, 0xEB4B, 0xEB4F, 0xFFE0, 0xFBC0, 0xF7A0, 0xEB40,
0xFFE0, 0xFFE0, 0xFBC0, 0xF7A0, 0xFFF5, 0xFFE4, 0xF380, 0xEF60,
0xEF76, 0xFFFF, 0xFFFF, 0xFFFF, 0xE300, 0xCE60, 0xD6AB, 0xFFFF,
0xEB40, 0xE300, 0xCE60, 0xB180, 0xE720, 0xDEE0, 0xCE60, 0xB180,
0xF7BD, 0xB96B, 0xDAB4, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xB9CA, 0xFFFF, 0xFFFF, 0xFFFF,
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0xFFFF, 0xFFFF, 0xFFFF, 0xF399, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0xD280, 0xEB40, 0xEB40, 0xEB40, 0xDAD1, 0xAD60, 0xC200, 0xCA40,
0xFFFF, 0xF7BE, 0xBDEB, 0x98C0, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0xEB40, 0xE720, 0xE300, 0xDAC0, 0xCA40, 0xC620, 0xC200, 0xBDE0,
0x9080, 0x94A0, 0x94A0, 0x9080, 0xFBDD, 0xE738, 0xE337, 0xE738,
0xD280, 0xCA40, 0xB5A0, 0x98C0, 0xB180, 0xA100, 0x94A0, 0x9080,
0x8C60, 0x9080, 0xC20C, 0xFFFF, 0xF7BD, 0xFFFF, 0xFFFF, 0xFFFF,
0xB9C9, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFF,
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
}; };
#endif #endif

View File

@ -26,6 +26,8 @@
#include "input.h" #include "input.h"
#include "tbtime.h" #include "tbtime.h"
#define MAXJP 10
#define VBA_BUTTON_A 1 #define VBA_BUTTON_A 1
#define VBA_BUTTON_B 2 #define VBA_BUTTON_B 2
#define VBA_BUTTON_SELECT 4 #define VBA_BUTTON_SELECT 4
@ -82,13 +84,14 @@ unsigned int ncpadmap[] = {
WPAD_BUTTON_2, WPAD_BUTTON_1 WPAD_BUTTON_2, WPAD_BUTTON_1
}; };
#ifdef HW_RVL
/**************************************************************************** /****************************************************************************
* WPAD_Stick * WPAD_StickX
* *
* Get X/Y value from Wii Joystick (classic, nunchuk) input * Get X value from Wii Joystick (classic, nunchuk) input
***************************************************************************/ ***************************************************************************/
s8 WPAD_Stick(u8 chan, u8 right, int axis) s8 WPAD_StickX(u8 chan,u8 right)
{ {
float mag = 0.0; float mag = 0.0;
float ang = 0.0; float ang = 0.0;
@ -122,19 +125,63 @@ s8 WPAD_Stick(u8 chan, u8 right, int axis)
break; break;
} }
/* calculate x/y value (angle need to be converted into radian) */ /* calculate X value (angle need to be converted into radian) */
if (mag > 1.0) mag = 1.0; if (mag > 1.0) mag = 1.0;
else if (mag < -1.0) mag = -1.0; else if (mag < -1.0) mag = -1.0;
double val; double val = mag * sin((PI * ang)/180.0f);
if(axis == 0) // x-axis
val = mag * sin((PI * ang)/180.0f);
else // y-axis
val = mag * cos((PI * ang)/180.0f);
return (s8)(val * 128.0f); return (s8)(val * 128.0f);
} }
/****************************************************************************
* WPAD_StickY
*
* Get Y value from Wii Joystick (classic, nunchuk) input
***************************************************************************/
s8 WPAD_StickY(u8 chan, u8 right)
{
float mag = 0.0;
float ang = 0.0;
WPADData *data = WPAD_Data(chan);
switch (data->exp.type)
{
case WPAD_EXP_NUNCHUK:
case WPAD_EXP_GUITARHERO3:
if (right == 0)
{
mag = data->exp.nunchuk.js.mag;
ang = data->exp.nunchuk.js.ang;
}
break;
case WPAD_EXP_CLASSIC:
if (right == 0)
{
mag = data->exp.classic.ljs.mag;
ang = data->exp.classic.ljs.ang;
}
else
{
mag = data->exp.classic.rjs.mag;
ang = data->exp.classic.rjs.ang;
}
break;
default:
break;
}
/* calculate X value (angle need to be converted into radian) */
if (mag > 1.0) mag = 1.0;
else if (mag < -1.0) mag = -1.0;
double val = mag * cos((PI * ang)/180.0f);
return (s8)(val * 128.0f);
}
#endif
/**************************************************************************** /****************************************************************************
* DecodeJoy * DecodeJoy
* *
@ -146,15 +193,16 @@ u32 DecodeJoy(unsigned short pad)
{ {
signed char pad_x = PAD_StickX (pad); signed char pad_x = PAD_StickX (pad);
signed char pad_y = PAD_StickY (pad); signed char pad_y = PAD_StickY (pad);
signed char gc_px = PAD_SubStickX (0);
u32 jp = PAD_ButtonsHeld (pad); u32 jp = PAD_ButtonsHeld (pad);
u32 J = 0; unsigned char J = 0;
#ifdef HW_RVL #ifdef HW_RVL
signed char wm_ax = WPAD_Stick ((u8)pad, 0, 0); signed char wm_ax = 0;
signed char wm_ay = WPAD_Stick ((u8)pad, 0, 1); signed char wm_ay = 0;
u32 wp = WPAD_ButtonsHeld (pad); u32 wp = 0;
signed char wm_sx = WPAD_Stick (0,1,0); // CC right joystick wm_ax = WPAD_StickX ((u8)pad, 0);
wm_ay = WPAD_StickY ((u8)pad, 0);
wp = WPAD_ButtonsHeld (pad);
u32 exp_type; u32 exp_type;
if ( WPAD_Probe(pad, &exp_type) != 0 ) exp_type = WPAD_EXP_NONE; if ( WPAD_Probe(pad, &exp_type) != 0 ) exp_type = WPAD_EXP_NONE;
@ -235,16 +283,6 @@ u32 DecodeJoy(unsigned short pad)
} }
#endif #endif
// Turbo feature
if(
(gc_px > 70)
#ifdef HW_RVL
|| (wm_sx > 70)
|| ((wp & WPAD_BUTTON_A) && (wp & WPAD_BUTTON_B))
#endif
)
J |= VBA_SPEED;
/*** Report pressed buttons (gamepads) ***/ /*** Report pressed buttons (gamepads) ***/
int i; int i;
@ -260,37 +298,20 @@ u32 DecodeJoy(unsigned short pad)
J |= vbapadmap[i]; J |= vbapadmap[i];
} }
if ((J & 48) == 48)
J &= ~16;
if ((J & 192) == 192)
J &= ~128;
return J; return J;
} }
u32 GetJoy() u32 GetJoy()
{ {
int pad = 0; int pad = 0;
u32 res = 0;
s8 gc_px = PAD_SubStickX (0); s8 gc_px = PAD_SubStickX (0);
s8 gc_py = PAD_SubStickY (0);
#ifdef HW_RVL #ifdef HW_RVL
s8 wm_sx = WPAD_Stick (0,1,0); s8 wm_sx = WPAD_StickX (0,1);
s8 wm_sy = WPAD_Stick (0,1,1);
u32 wm_pb = WPAD_ButtonsHeld (0); // wiimote / expansion button info u32 wm_pb = WPAD_ButtonsHeld (0); // wiimote / expansion button info
#endif #endif
// Check for video zoom
if (GCSettings.NGCZoom)
{
if (gc_py < -36 || gc_py > 36)
zoom ((float) gc_py / -36);
#ifdef HW_RVL
if (wm_sy < -36 || wm_sy > 36)
zoom ((float) wm_sy / -36);
#endif
}
// request to go back to menu // request to go back to menu
if ((gc_px < -70) if ((gc_px < -70)
#ifdef HW_RVL #ifdef HW_RVL
@ -302,24 +323,28 @@ u32 GetJoy()
{ {
if (GCSettings.AutoSave == 1) if (GCSettings.AutoSave == 1)
{ {
SaveBatteryOrState(GCSettings.SaveMethod, 0, SILENT); // save battery SaveBattery(GCSettings.SaveMethod, SILENT);
} }
else if (GCSettings.AutoSave == 2) else if (GCSettings.AutoSave == 2)
{ {
SaveBatteryOrState(GCSettings.SaveMethod, 1, SILENT); // save state SaveState(GCSettings.SaveMethod, SILENT);
} }
else if(GCSettings.AutoSave == 3) else if(GCSettings.AutoSave == 3)
{ {
SaveBatteryOrState(GCSettings.SaveMethod, 0, SILENT); // save battery SaveBattery(GCSettings.SaveMethod, SILENT);
SaveBatteryOrState(GCSettings.SaveMethod, 1, SILENT); // save state SaveState(GCSettings.SaveMethod, SILENT);
} }
// change to menu video mode
ResetVideo_Menu ();
MainMenu(3); MainMenu(3);
return 0; return 0;
} }
else else
{ {
return DecodeJoy(pad); res = DecodeJoy(pad);
if ((res & 48) == 48)
res &= ~16;
if ((res & 192) == 192)
res &= ~128;
return res;
} }
} }

View File

@ -15,14 +15,14 @@
#define PI 3.14159265f #define PI 3.14159265f
#define PADCAL 50 #define PADCAL 50
#define MAXJP 10
extern unsigned int gcpadmap[]; extern unsigned int gcpadmap[];
extern unsigned int wmpadmap[]; extern unsigned int wmpadmap[];
extern unsigned int ccpadmap[]; extern unsigned int ccpadmap[];
extern unsigned int ncpadmap[]; extern unsigned int ncpadmap[];
s8 WPAD_Stick(u8 chan,u8 right, int axis); s8 WPAD_StickX(u8 chan,u8 right);
s8 WPAD_StickY(u8 chan, u8 right);
u32 GetJoy(); u32 GetJoy();

View File

@ -25,6 +25,7 @@
#define VERIFBUFFERSIZE 65536 #define VERIFBUFFERSIZE 65536
static u8 SysArea[CARD_WORKAREA] ATTRIBUTE_ALIGN (32); static u8 SysArea[CARD_WORKAREA] ATTRIBUTE_ALIGN (32);
extern unsigned char savebuffer[];
unsigned char verifbuffer[VERIFBUFFERSIZE] ATTRIBUTE_ALIGN (32); unsigned char verifbuffer[VERIFBUFFERSIZE] ATTRIBUTE_ALIGN (32);
card_dir CardDir; card_dir CardDir;
card_file CardFile; card_file CardFile;
@ -67,7 +68,7 @@ bool TestCard(int slot, bool silent)
/*** Initialize Card System ***/ /*** Initialize Card System ***/
memset (SysArea, 0, CARD_WORKAREA); memset (SysArea, 0, CARD_WORKAREA);
CARD_Init ("VBA0", "00"); CARD_Init ("SNES", "00");
/*** Try to mount the card ***/ /*** Try to mount the card ***/
if (MountCard(slot, silent) == 0) if (MountCard(slot, silent) == 0)
@ -135,7 +136,7 @@ VerifyMCFile (unsigned char *buf, int slot, char *filename, int datasize)
/*** Initialize Card System ***/ /*** Initialize Card System ***/
memset (SysArea, 0, CARD_WORKAREA); memset (SysArea, 0, CARD_WORKAREA);
CARD_Init ("VBA0", "00"); CARD_Init ("SNES", "00");
/*** Try to mount the card ***/ /*** Try to mount the card ***/
CardError = MountCard(slot, NOTSILENT); CardError = MountCard(slot, NOTSILENT);
@ -214,7 +215,7 @@ LoadBufferFromMC (unsigned char *buf, int slot, char *filename, bool silent)
/*** Initialize Card System ***/ /*** Initialize Card System ***/
memset (SysArea, 0, CARD_WORKAREA); memset (SysArea, 0, CARD_WORKAREA);
CARD_Init ("VBA0", "00"); CARD_Init ("SNES", "00");
/*** Try to mount the card ***/ /*** Try to mount the card ***/
CardError = MountCard(slot, NOTSILENT); CardError = MountCard(slot, NOTSILENT);
@ -278,7 +279,7 @@ SaveBufferToMC (unsigned char *buf, int slot, char *filename, int datasize, bool
/*** Initialize Card System ***/ /*** Initialize Card System ***/
memset (SysArea, 0, CARD_WORKAREA); memset (SysArea, 0, CARD_WORKAREA);
CARD_Init ("VBA0", "00"); CARD_Init ("SNES", "00");
/*** Try to mount the card ***/ /*** Try to mount the card ***/
CardError = MountCard(slot, NOTSILENT); CardError = MountCard(slot, NOTSILENT);

View File

@ -44,7 +44,7 @@ extern "C"
extern void DrawMenu (char items[][50], char *title, int maxitems, int selected, int fontsize); extern void DrawMenu (char items[][50], char *title, int maxitems, int selected, int fontsize);
extern int menu; extern int menu;
extern bool ROMLoaded; extern int ROMSize;
#define SOFTRESET_ADR ((volatile u32*)0xCC003024) #define SOFTRESET_ADR ((volatile u32*)0xCC003024)
@ -83,9 +83,9 @@ LoadManager ()
if ( loadROM == 1 ) // if ROM was loaded, load the battery / state if ( loadROM == 1 ) // if ROM was loaded, load the battery / state
{ {
if (GCSettings.AutoLoad == 1) if (GCSettings.AutoLoad == 1)
LoadBatteryOrState(GCSettings.SaveMethod, 0, SILENT); // load battery LoadBattery(GCSettings.SaveMethod, SILENT);
else if (GCSettings.AutoLoad == 2) else if (GCSettings.AutoLoad == 2)
LoadBatteryOrState(GCSettings.SaveMethod, 1, SILENT); // load state LoadState(GCSettings.SaveMethod, SILENT);
} }
return loadROM; return loadROM;
@ -94,7 +94,7 @@ LoadManager ()
/**************************************************************************** /****************************************************************************
* Preferences Menu * Preferences Menu
***************************************************************************/ ***************************************************************************/
static int prefmenuCount = 11; static int prefmenuCount = 9;
static char prefmenu[][50] = { static char prefmenu[][50] = {
"Load Method", "Load Method",
@ -105,8 +105,6 @@ static char prefmenu[][50] = {
"Auto Load", "Auto Load",
"Auto Save", "Auto Save",
"Verify MC Saves", "Verify MC Saves",
"Enable Zooming",
"Video Rendering",
"Save Preferences", "Save Preferences",
"Back to Main Menu" "Back to Main Menu"
@ -124,26 +122,40 @@ PreferencesMenu ()
// some load/save methods are not implemented - here's where we skip them // some load/save methods are not implemented - here's where we skip them
// they need to be skipped in the order they were enumerated in vba.h // they need to be skipped in the order they were enumerated in vba.h
// skip
if(GCSettings.LoadMethod == METHOD_DVD)
GCSettings.LoadMethod++;
if(GCSettings.LoadMethod == METHOD_SMB)
GCSettings.LoadMethod++;
if(GCSettings.SaveMethod == METHOD_SMB)
GCSettings.SaveMethod++;
if(GCSettings.SaveMethod == METHOD_MC_SLOTA)
GCSettings.SaveMethod++;
if(GCSettings.SaveMethod == METHOD_MC_SLOTB)
GCSettings.SaveMethod++;
prefmenu[6][0] = '\0'; // MC saving not implemented
// no USB ports on GameCube // no USB ports on GameCube
#ifdef HW_DOL #ifndef HW_RVL
if(GCSettings.LoadMethod == METHOD_USB) if(GCSettings.LoadMethod == METHOD_USB)
GCSettings.LoadMethod++; GCSettings.LoadMethod++;
if(GCSettings.SaveMethod == METHOD_USB) if(GCSettings.SaveMethod == METHOD_USB)
GCSettings.SaveMethod++; GCSettings.SaveMethod++;
#endif #endif
// saving to DVD is impossible // check if DVD access in Wii mode is disabled
if(GCSettings.SaveMethod == METHOD_DVD) #ifndef WII_DVD
GCSettings.SaveMethod++;
// disable DVD in GC mode (not implemented)
#ifdef HW_DOL
if(GCSettings.LoadMethod == METHOD_DVD) if(GCSettings.LoadMethod == METHOD_DVD)
GCSettings.LoadMethod++; GCSettings.LoadMethod++;
#endif #endif
// saving to DVD is impossible
if(GCSettings.SaveMethod == METHOD_DVD)
GCSettings.SaveMethod++;
// disable SMB in GC mode (stalls out) // disable SMB in GC mode (stalls out)
#ifdef HW_DOL #ifndef HW_RVL
if(GCSettings.LoadMethod == METHOD_SMB) if(GCSettings.LoadMethod == METHOD_SMB)
GCSettings.LoadMethod++; GCSettings.LoadMethod++;
if(GCSettings.SaveMethod == METHOD_SMB) if(GCSettings.SaveMethod == METHOD_SMB)
@ -156,9 +168,6 @@ PreferencesMenu ()
GCSettings.SaveMethod++; GCSettings.SaveMethod++;
if(GCSettings.SaveMethod == METHOD_MC_SLOTB) if(GCSettings.SaveMethod == METHOD_MC_SLOTB)
GCSettings.SaveMethod++; GCSettings.SaveMethod++;
prefmenu[6][0] = 0;
#else
sprintf (prefmenu[6], "Verify MC Saves %s", GCSettings.VerifySaves == true ? " ON" : "OFF");
#endif #endif
// correct load/save methods out of bounds // correct load/save methods out of bounds
@ -197,13 +206,7 @@ PreferencesMenu ()
else if (GCSettings.AutoSave == 2) sprintf (prefmenu[5],"Auto Save SNAPSHOT"); else if (GCSettings.AutoSave == 2) sprintf (prefmenu[5],"Auto Save SNAPSHOT");
else if (GCSettings.AutoSave == 3) sprintf (prefmenu[5],"Auto Save BOTH"); else if (GCSettings.AutoSave == 3) sprintf (prefmenu[5],"Auto Save BOTH");
sprintf (prefmenu[7], "Enable Zooming %s", //sprintf (prefmenu[6], "Verify MC Saves %s", GCSettings.VerifySaves == true ? " ON" : "OFF");
GCSettings.NGCZoom == true ? " ON" : "OFF");
if ( GCSettings.render == 0)
sprintf (prefmenu[8], "Video Rendering Filtered");
if ( GCSettings.render == 1)
sprintf (prefmenu[8], "Video Rendering Unfiltered");
ret = RunMenu (prefmenu, prefmenuCount, (char*)"Preferences", 16); ret = RunMenu (prefmenu, prefmenuCount, (char*)"Preferences", 16);
@ -240,23 +243,11 @@ PreferencesMenu ()
break; break;
case 7: case 7:
GCSettings.NGCZoom ^= 1;
break;
case 8:
GCSettings.render++;
if (GCSettings.render > 1 )
GCSettings.render = 0;
// reset zoom
zoom_reset ();
break;
case 9:
SavePrefs(GCSettings.SaveMethod, NOTSILENT); SavePrefs(GCSettings.SaveMethod, NOTSILENT);
break; break;
case -1: /*** Button B ***/ case -1: /*** Button B ***/
case 10: case 8:
quit = 1; quit = 1;
break; break;
@ -272,13 +263,12 @@ PreferencesMenu ()
int int
GameMenu () GameMenu ()
{ {
int gamemenuCount = 8; int gamemenuCount = 7;
char gamemenu[][50] = { char gamemenu[][50] = {
"Return to Game", "Return to Game",
"Reset Game", "Reset Game",
"Load SRAM", "Save SRAM", "Load SRAM", "Save SRAM",
"Load Game Snapshot", "Save Game Snapshot", "Load Game Snapshot", "Save Game Snapshot",
"Reset Zoom",
"Back to Main Menu" "Back to Main Menu"
}; };
@ -305,9 +295,6 @@ GameMenu ()
gamemenu[3][0] = '\0'; gamemenu[3][0] = '\0';
gamemenu[5][0] = '\0'; gamemenu[5][0] = '\0';
} }
// disable Reset Zoom if Zooming is off
if(!GCSettings.NGCZoom)
gamemenu[6][0] = '\0';
ret = RunMenu (gamemenu, gamemenuCount, (char*)"Game Menu"); ret = RunMenu (gamemenu, gamemenuCount, (char*)"Game Menu");
@ -323,29 +310,23 @@ GameMenu ()
break; break;
case 2: // Load Battery case 2: // Load Battery
quit = retval = LoadBatteryOrState(GCSettings.SaveMethod, 0, NOTSILENT); quit = retval = LoadBattery(GCSettings.SaveMethod, NOTSILENT);
emulator.emuReset();
break; break;
case 3: // Save Battery case 3: // Save Battery
SaveBatteryOrState(GCSettings.SaveMethod, 0, NOTSILENT); SaveBattery(GCSettings.SaveMethod, NOTSILENT);
break; break;
case 4: // Load State case 4: // Load State
quit = retval = LoadBatteryOrState(GCSettings.SaveMethod, 1, NOTSILENT); quit = retval = LoadState(GCSettings.SaveMethod, NOTSILENT);
break; break;
case 5: // Save State case 5: // Save State
SaveBatteryOrState(GCSettings.SaveMethod, 1, NOTSILENT); SaveState(GCSettings.SaveMethod, NOTSILENT);
break;
case 6: // Reset Zoom
zoom_reset ();
quit = retval = 1;
break; break;
case -1: // Button B case -1: // Button B
case 7: // Return to previous menu case 6: // Return to previous menu
retval = 0; retval = 0;
quit = 1; quit = 1;
break; break;
@ -652,7 +633,7 @@ MainMenu (int selectedMenu)
int ret; int ret;
// disable game-specific menu items if a ROM isn't loaded // disable game-specific menu items if a ROM isn't loaded
if (!ROMLoaded) if (ROMSize == 0 )
menuitems[3][0] = '\0'; menuitems[3][0] = '\0';
else else
sprintf (menuitems[3], "Game Menu"); sprintf (menuitems[3], "Game Menu");
@ -719,24 +700,19 @@ MainMenu (int selectedMenu)
case -1: // Button B case -1: // Button B
// Return to Game // Return to Game
if(ROMLoaded) quit = 1;
quit = 1;
break; break;
} }
} }
// Wait for buttons to be released /*** Remove any still held buttons ***/
int count = 0; // how long we've been waiting for the user to release the button #ifdef HW_RVL
while(count < 50 && ( while( PAD_ButtonsHeld(0) || WPAD_ButtonsHeld(0) )
PAD_ButtonsHeld(0) VIDEO_WaitVSync();
#ifdef HW_RVL #else
|| WPAD_ButtonsHeld(0) while( PAD_ButtonsHeld(0) )
#endif VIDEO_WaitVSync();
)) #endif
{
VIDEO_WaitVSync();
count++;
}
StartAudio(); StartAudio();
mftb(&end); mftb(&end);

View File

@ -205,17 +205,6 @@ setfontcolour (u8 r, u8 g, u8 b)
fontlo = fontcolour & 0xffff; fontlo = fontcolour & 0xffff;
} }
/****************************************************************************
* Draws Version # on screen
***************************************************************************/
void DrawVersion()
{
setfontsize (12);
setfontcolour (0,0,0);
DrawText (115, screenheight - 34, (char *)VERSIONSTRFULL);
}
/**************************************************************************** /****************************************************************************
* Display credits, legal copyright and licence * Display credits, legal copyright and licence
* *
@ -228,10 +217,10 @@ Credits ()
setfontcolour (0x00, 0x00, 0x00); setfontcolour (0x00, 0x00, 0x00);
setfontsize (26); setfontsize (28);
DrawText (-1, 150, (char*)"Credits"); DrawText (-1, 60, (char*)"Credits");
int ypos = 120; int ypos = 25;
if (screenheight == 480) if (screenheight == 480)
ypos += 52; ypos += 52;
@ -246,8 +235,6 @@ Credits ()
DrawText (375, ypos, (char*)"emukidid"); DrawText (375, ypos, (char*)"emukidid");
DrawText (100, ypos += 18, (char*)"Original GameCube Port"); DrawText (100, ypos += 18, (char*)"Original GameCube Port");
DrawText (375, ypos, (char*)"SoftDev"); DrawText (375, ypos, (char*)"SoftDev");
DrawText (100, ypos += 18, (char*)"Visual Boy Advance - M");
DrawText (375, ypos, (char*)"VBA-M Team");
DrawText (100, ypos += 18, (char*)"Visual Boy Advance 1.7.2"); DrawText (100, ypos += 18, (char*)"Visual Boy Advance 1.7.2");
DrawText (375, ypos, (char*)"Forgotten"); DrawText (375, ypos, (char*)"Forgotten");
DrawText (100, ypos += 18, (char*)"libogc"); DrawText (100, ypos += 18, (char*)"libogc");
@ -258,11 +245,9 @@ Credits ()
DrawText (-1, ypos += 36, (char*)"And many others who have contributed over the years!"); DrawText (-1, ypos += 36, (char*)"And many others who have contributed over the years!");
setfontsize (12); setfontsize (12);
DrawText (-1, ypos += 40, (char*)"This software is open source and may be copied,"); DrawText (-1, ypos += 50, (char*)"This software is open source and may be copied, distributed, or modified");
DrawText (-1, ypos += 15, (char*)"distributed, or modified under the terms of"); DrawText (-1, ypos += 15, (char*)"under the terms of the GNU General Public License (GPL) Version 2.");
DrawText (-1, ypos += 15, (char*)"the GNU General Public License (GPL) Version 2.");
DrawVersion();
showscreen (); showscreen ();
} }
@ -368,12 +353,9 @@ WaitPrompt (char *msg)
ypos += 32; ypos += 32;
clearscreen (); clearscreen ();
setfontsize(16);
DrawText (-1, ypos, msg); DrawText (-1, ypos, msg);
ypos += 30; ypos += 30;
DrawText (-1, ypos, (char*)"Press A to continue"); DrawText (-1, ypos, (char*)"Press A to continue");
DrawVersion();
showscreen (); showscreen ();
WaitButtonA (); WaitButtonA ();
} }
@ -393,14 +375,11 @@ WaitPromptChoice (char *msg, char *bmsg, char *amsg)
ypos += 17; ypos += 17;
clearscreen (); clearscreen ();
setfontsize(20);
DrawText (-1, ypos, msg); DrawText (-1, ypos, msg);
ypos += 60; ypos += 60;
char txt[80]; char txt[80];
sprintf (txt, "B = %s : A = %s", bmsg, amsg); sprintf (txt, "B = %s : A = %s", bmsg, amsg);
DrawText (-1, ypos, txt); DrawText (-1, ypos, txt);
DrawVersion();
showscreen (); showscreen ();
return WaitButtonAB (); return WaitButtonAB ();
} }
@ -419,10 +398,7 @@ ShowAction (char *msg)
ypos += 32; ypos += 32;
clearscreen (); clearscreen ();
setfontsize(20);
DrawText (-1, ypos, msg); DrawText (-1, ypos, msg);
DrawVersion();
showscreen (); showscreen ();
} }
@ -437,12 +413,12 @@ DrawMenu (char items[][50], char *title, int maxitems, int selected, int fontsiz
int n = 1; int n = 1;
int line_height; int line_height;
ypos = 105; ypos = 45;
if (screenheight == 480) if (screenheight == 480)
ypos += 52; ypos += 52;
else else
ypos += 42; ypos += 32;
clearscreen (); clearscreen ();
@ -450,10 +426,13 @@ DrawMenu (char items[][50], char *title, int maxitems, int selected, int fontsiz
if (title != NULL) if (title != NULL)
{ {
setfontsize (26); setfontsize (28);
DrawText (-1, 150, title); DrawText (-1, 60, title);
} }
setfontsize (14);
DrawText (380, screenheight - 30, (char *)VERSIONSTRFULL);
// Draw menu items // Draw menu items
setfontsize (fontsize); // set font size setfontsize (fontsize); // set font size
@ -469,11 +448,11 @@ DrawMenu (char items[][50], char *title, int maxitems, int selected, int fontsiz
else if (i == selected) else if (i == selected)
{ {
for( w = 0; w < line_height; w++ ) for( w = 0; w < line_height; w++ )
DrawLineFast( 77, 575, n * line_height + (ypos-line_height+6) + w, 0x00, 0x00, 0x00 ); DrawLineFast( 30, 610, n * line_height + (ypos-line_height+6) + w, 0x80, 0x80, 0x80 );
//setfontcolour (0xff, 0xff, 0xff); setfontcolour (0xff, 0xff, 0xff);
DrawText (x, n * line_height + ypos, items[i]); DrawText (x, n * line_height + ypos, items[i]);
//setfontcolour (0x00, 0x00, 0x00); setfontcolour (0x00, 0x00, 0x00);
} }
else else
{ {
@ -483,8 +462,8 @@ DrawMenu (char items[][50], char *title, int maxitems, int selected, int fontsiz
} }
} }
DrawVersion();
showscreen (); showscreen ();
} }
/**************************************************************************** /****************************************************************************
@ -540,7 +519,7 @@ RunMenu (char items[][50], int maxitems, char *title, int fontsize, int x)
gc_ay = PAD_StickY (0); gc_ay = PAD_StickY (0);
p = PAD_ButtonsDown (0); p = PAD_ButtonsDown (0);
#ifdef HW_RVL #ifdef HW_RVL
wm_ay = WPAD_Stick (0,0,1); wm_ay = WPAD_StickY (0,0);
wp = WPAD_ButtonsDown (0); wp = WPAD_ButtonsDown (0);
#endif #endif
@ -605,8 +584,8 @@ ShowFiles (FILEENTRIES filelist[], int maxfiles, int offset, int selection)
clearscreen (); clearscreen ();
setfontsize (26); setfontsize (28);
DrawText (-1, 150, (char*)"Choose Game"); DrawText (-1, 60, (char*)"Choose Game");
setfontsize(18); setfontsize(18);
@ -617,8 +596,6 @@ ShowFiles (FILEENTRIES filelist[], int maxfiles, int offset, int selection)
else else
ypos += 10; ypos += 10;
ypos += 30;
j = 0; j = 0;
for (i = offset; i < (offset + PAGESIZE) && (i < maxfiles); i++) for (i = offset; i < (offset + PAGESIZE) && (i < maxfiles); i++)
{ {
@ -637,18 +614,19 @@ ShowFiles (FILEENTRIES filelist[], int maxfiles, int offset, int selection)
{ {
/*** Highlighted text entry ***/ /*** Highlighted text entry ***/
for ( w = 0; w < 20; w++ ) for ( w = 0; w < 20; w++ )
DrawLineFast( 77, 575, ( j * 20 ) + (ypos-16) + w, 0x00, 0x00, 0x00 ); DrawLineFast( 30, 610, ( j * 20 ) + (ypos-16) + w, 0x80, 0x80, 0x80 );
DrawText (100, (j * 20) + ypos, text);
setfontcolour (0x00, 0x00, 0xe0);
DrawText (50, (j * 20) + ypos, text);
setfontcolour (0x00, 0x00, 0x00);
} }
else else
{ {
/*** Normal entry ***/ /*** Normal entry ***/
DrawText (100, (j * 20) + ypos, text); DrawText (50, (j * 20) + ypos, text);
} }
j++; j++;
} }
DrawVersion();
showscreen (); showscreen ();
} }
@ -667,8 +645,8 @@ ShowCheats (char items[][50], char itemvalues[][50], int maxitems, int offset, i
clearscreen (); clearscreen ();
setfontsize (26); setfontsize (28);
DrawText (-1, 150, (char*)"Cheats"); DrawText (-1, 60, (char*)"Cheats");
setfontsize(18); setfontsize(18);
@ -698,8 +676,6 @@ ShowCheats (char items[][50], char itemvalues[][50], int maxitems, int offset, i
} }
j++; j++;
} }
DrawVersion();
showscreen (); showscreen ();
} }
@ -797,43 +773,30 @@ DrawLine (int x1, int y1, int x2, int y2, u8 r, u8 g, u8 b)
void void
ShowProgress (char *msg, int done, int total) ShowProgress (char *msg, int done, int total)
{ {
if(total <= 0) // division by 0 is bad! int ypos = (screenheight - 30) >> 1;
return;
else if(done > total) // this shouldn't happen
done = total;
int xpos, ypos; if (screenheight == 480)
int i; ypos += 52;
else
ypos += 32;
if(done < 5000) // we just started! int xpos;
{ int i;
ypos = (screenheight - 30) >> 1;
if (screenheight == 480) clearscreen ();
ypos += 52; DrawText (-1, ypos, msg);
else
ypos += 32;
clearscreen (); /*** Draw a white outline box ***/
setfontsize(20); for (i = 380; i < 401; i++)
DrawText (-1, ypos, msg); DrawLine (100, i, 540, i, 0xff, 0xff, 0xff);
/*** Draw a white outline box ***/
for (i = 380; i < 401; i++)
DrawLine (100, i, 540, i, 0xff, 0xff, 0xff);
}
/*** Show progess ***/ /*** Show progess ***/
xpos = (int) (((float) done / (float) total) * 438); xpos = (int) (((float) done / (float) total) * 438);
for (i = 381; i < 400; i++) for (i = 381; i < 400; i++)
DrawLine (101, i, 101 + xpos, i, 0x00, 0x00, 0x80); DrawLine (101, i, 101 + xpos, i, 0x00, 0x00, 0x80);
if(done < 5000) // we just started! showscreen ();
{
DrawVersion();
showscreen ();
}
} }
/**************************************************************************** /****************************************************************************

View File

@ -19,7 +19,7 @@
#include "filesel.h" #include "filesel.h"
#define PAGESIZE 13 // max item listing on a screen #define PAGESIZE 17 // max item listing on a screen
int FT_Init (); int FT_Init ();
void setfontsize (int pixelsize); void setfontsize (int pixelsize);

View File

@ -21,10 +21,16 @@
#include "fileop.h" #include "fileop.h"
#include "smbop.h" #include "smbop.h"
#include "filesel.h" #include "filesel.h"
#include "input.h"
extern unsigned char savebuffer[];
extern int currconfig[4]; extern int currconfig[4];
// button map configurations
extern unsigned int gcpadmap[];
extern unsigned int wmpadmap[];
extern unsigned int ccpadmap[];
extern unsigned int ncpadmap[];
#define PREFS_FILE_NAME "VBAGX.xml" #define PREFS_FILE_NAME "VBAGX.xml"
char prefscomment[2][32]; char prefscomment[2][32];
@ -40,7 +46,7 @@ mxml_node_t *section;
mxml_node_t *item; mxml_node_t *item;
mxml_node_t *elem; mxml_node_t *elem;
char temp[20]; char temp[200];
const char * toStr(int i) const char * toStr(int i)
{ {
@ -70,7 +76,7 @@ void createXMLController(unsigned int controller[], const char * name, const cha
mxmlElementSetAttr(item, "description", description); mxmlElementSetAttr(item, "description", description);
// create buttons // create buttons
for(int i=0; i < MAXJP; i++) for(int i=0; i < 12; i++)
{ {
elem = mxmlNewElement(item, "button"); elem = mxmlNewElement(item, "button");
mxmlElementSetAttr(elem, "number", toStr(i)); mxmlElementSetAttr(elem, "number", toStr(i));
@ -110,6 +116,7 @@ int
preparePrefsData (int method) preparePrefsData (int method)
{ {
int offset = 0; int offset = 0;
memset (savebuffer, 0, SAVEBUFFERSIZE);
// add save icon and comments for Memory Card saves // add save icon and comments for Memory Card saves
if(method == METHOD_MC_SLOTA || method == METHOD_MC_SLOTB) if(method == METHOD_MC_SLOTA || method == METHOD_MC_SLOTB)
@ -141,7 +148,7 @@ preparePrefsData (int method)
createXMLSetting("LoadFolder", "Load Folder", GCSettings.LoadFolder); createXMLSetting("LoadFolder", "Load Folder", GCSettings.LoadFolder);
createXMLSetting("SaveFolder", "Save Folder", GCSettings.SaveFolder); createXMLSetting("SaveFolder", "Save Folder", GCSettings.SaveFolder);
//createXMLSetting("CheatFolder", "Cheats Folder", GCSettings.CheatFolder); //createXMLSetting("CheatFolder", "Cheats Folder", GCSettings.CheatFolder);
createXMLSetting("VerifySaves", "Verify Memory Card Saves", toStr(GCSettings.VerifySaves)); //createXMLSetting("VerifySaves", "Verify Memory Card Saves", toStr(GCSettings.VerifySaves));
createXMLSection("Network", "Network Settings"); createXMLSection("Network", "Network Settings");
@ -150,10 +157,7 @@ preparePrefsData (int method)
createXMLSetting("smbuser", "Share Username", GCSettings.smbuser); createXMLSetting("smbuser", "Share Username", GCSettings.smbuser);
createXMLSetting("smbpwd", "Share Password", GCSettings.smbpwd); createXMLSetting("smbpwd", "Share Password", GCSettings.smbpwd);
createXMLSection("Emulation", "Emulation Settings"); //createXMLSection("Emulation", "Emulation Settings");
createXMLSetting("NGCZoom", "Enable Zoom", toStr(GCSettings.NGCZoom));
createXMLSetting("render", "Video Rendering", toStr(GCSettings.render));
createXMLSection("Controller", "Controller Settings"); createXMLSection("Controller", "Controller Settings");
@ -208,7 +212,7 @@ void loadXMLController(unsigned int controller[], const char * name)
if(item) if(item)
{ {
// populate buttons // populate buttons
for(int i=0; i < MAXJP; i++) for(int i=0; i < 12; i++)
{ {
elem = mxmlFindElement(item, xml, "button", "number", toStr(i), MXML_DESCEND); elem = mxmlFindElement(item, xml, "button", "number", toStr(i), MXML_DESCEND);
if(elem) if(elem)
@ -238,6 +242,7 @@ decodePrefsData (int method)
xml = mxmlLoadString(NULL, (char *)savebuffer+offset, MXML_TEXT_CALLBACK); xml = mxmlLoadString(NULL, (char *)savebuffer+offset, MXML_TEXT_CALLBACK);
// check settings version // check settings version
// we don't do anything with the version #, but we'll store it anyway
char * version; char * version;
item = mxmlFindElement(xml, xml, "file", "version", NULL, MXML_DESCEND); item = mxmlFindElement(xml, xml, "file", "version", NULL, MXML_DESCEND);
if(item) // a version entry exists if(item) // a version entry exists
@ -245,17 +250,6 @@ decodePrefsData (int method)
else // version # not found, must be invalid else // version # not found, must be invalid
return false; return false;
// this code assumes version in format X.X.X
// XX.X.X, X.XX.X, or X.X.XX will NOT work
char verMajor = version[7];
char verMinor = version[9];
char verPoint = version[11];
if(verPoint < '3' && verMajor == '1') // less than version 1.0.3
return false; // reset settings
else if(verMajor > '1' || verMinor > '0' || verPoint > '3') // some future version
return false; // reset settings
// File Settings // File Settings
loadXMLSetting(&GCSettings.AutoLoad, "AutoLoad"); loadXMLSetting(&GCSettings.AutoLoad, "AutoLoad");
@ -276,9 +270,6 @@ decodePrefsData (int method)
// Emulation Settings // Emulation Settings
loadXMLSetting(&GCSettings.NGCZoom, "NGCZoom");
loadXMLSetting(&GCSettings.render, "render");
// Controller Settings // Controller Settings
loadXMLController(gcpadmap, "gcpadmap"); loadXMLController(gcpadmap, "gcpadmap");
@ -297,17 +288,13 @@ decodePrefsData (int method)
bool bool
SavePrefs (int method, bool silent) SavePrefs (int method, bool silent)
{ {
// there's no point in saving SMB settings TO SMB, because then we'll have no way to load them the next time! if(method == METHOD_AUTO)
// so instead we'll save using whatever other method is available (eg: SD)
if(method == METHOD_AUTO || method == METHOD_SMB)
method = autoSaveMethod(); method = autoSaveMethod();
char filepath[1024]; char filepath[1024];
int datasize; int datasize;
int offset = 0; int offset = 0;
AllocSaveBuffer ();
datasize = preparePrefsData (method); datasize = preparePrefsData (method);
if (!silent) if (!silent)
@ -335,8 +322,6 @@ SavePrefs (int method, bool silent)
offset = SaveBufferToMC (savebuffer, CARD_SLOTB, (char *)PREFS_FILE_NAME, datasize, silent); offset = SaveBufferToMC (savebuffer, CARD_SLOTB, (char *)PREFS_FILE_NAME, datasize, silent);
} }
FreeSaveBuffer ();
if (offset > 0) if (offset > 0)
{ {
if (!silent) if (!silent)
@ -356,8 +341,6 @@ LoadPrefsFromMethod (int method)
char filepath[1024]; char filepath[1024];
int offset = 0; int offset = 0;
AllocSaveBuffer ();
if(method == METHOD_SD || method == METHOD_USB) if(method == METHOD_SD || method == METHOD_USB)
{ {
if(ChangeFATInterface(method, NOTSILENT)) if(ChangeFATInterface(method, NOTSILENT))
@ -383,8 +366,6 @@ LoadPrefsFromMethod (int method)
if (offset > 0) if (offset > 0)
retval = decodePrefsData (method); retval = decodePrefsData (method);
FreeSaveBuffer ();
return retval; return retval;
} }

115
source/ngc/sdfileio.c Normal file
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; unsigned int SMBTimer = 0;
#define SMBTIMEOUT ( 3600 ) // Some implementations timeout in 10 minutes #define SMBTIMEOUT ( 3600 ) // Some implementations timeout in 10 minutes
// SMB connection/file handles - the only ones we should ever use!
SMBCONN smbconn; SMBCONN smbconn;
SMBFILE smbfile;
#define ZIPCHUNK 16384 #define ZIPCHUNK 16384
extern unsigned char savebuffer[];
extern char output[16384];
extern int offset;
extern int selection;
extern char currentdir[MAXPATHLEN];
extern FILEENTRIES filelist[MAXFILES];
/**************************************************************************** /****************************************************************************
* InitializeNetwork * InitializeNetwork
* Initializes the Wii/GameCube network interface * Initializes the Wii/GameCube network interface
@ -88,7 +93,7 @@ ConnectShare (bool silent)
strlen(GCSettings.smbip) == 0) strlen(GCSettings.smbip) == 0)
{ {
if(!silent) if(!silent)
WaitPrompt((char*) "Invalid network settings. Check VBAGX.xml."); WaitPrompt((char*) "Invalid network settings. Check SNES9xGX.xml.");
return false; return false;
} }
@ -213,76 +218,36 @@ ParseSMBdirectory ()
return filecount; return filecount;
} }
/****************************************************************************
* Open SMB file
***************************************************************************/
SMBFILE OpenSMBFile(char * filepath)
{
return SMB_OpenFile (SMBPath(filepath), SMB_OPEN_READING, SMB_OF_OPEN, smbconn);
}
/**************************************************************************** /****************************************************************************
* Load SMB file * Load SMB file
* rom - pointer to memory where ROM will be stored
* length - # bytes to read (0 for all)
****************************************************************************/ ****************************************************************************/
int int
LoadSMBFile (char * rom, int length) LoadSMBFile (char *filename, int length)
{ {
char filepath[MAXPATHLEN]; char filepath[MAXPATHLEN];
/* Check filename length */ /* Check filename length */
if (!MakeROMPath(filepath, METHOD_SMB)) if ((strlen(currentdir)+1+strlen(filelist[selection].filename)) < MAXPATHLEN)
sprintf(filepath, "%s/%s",currentdir,filelist[selection].filename);
else
{ {
WaitPrompt((char*) "Maximum filepath length reached!"); WaitPrompt((char*) "Maximum filepath length reached!");
return -1; return -1;
} }
return LoadBufferFromSMB(rom, filepath, length, NOTSILENT); return 0;
} //return LoadBufferFromSMB((char *)Memory.ROM, SMBPath(filepath), NOTSILENT);
/****************************************************************************
* LoadSMBSzFile
* Loads the selected file # from the specified 7z into rbuffer
* Returns file size
***************************************************************************/
int
LoadSMBSzFile(char * filepath, unsigned char * rbuffer)
{
if(!ConnectShare (NOTSILENT))
return 0;
smbfile = OpenSMBFile(filepath);
if (smbfile)
{
u32 size = SzExtractFile(filelist[selection].offset, rbuffer);
SMB_CloseFile (smbfile);
return size;
}
else
{
WaitPrompt((char*) "Error opening file");
return 0;
}
} }
/**************************************************************************** /****************************************************************************
* Write savebuffer to SMB file * Write savebuffer to SMB file
****************************************************************************/ ****************************************************************************/
// no buffer specified, use savebuffer
int int
SaveBufferToSMB (char *filepath, int datasize, bool silent) SaveBufferToSMB (char *filepath, int datasize, bool silent)
{
return SaveBufferToSMB((char *)savebuffer, filepath, datasize, silent);
}
int
SaveBufferToSMB (char * sbuffer, char *filepath, int datasize, bool silent)
{ {
if(!ConnectShare (NOTSILENT)) if(!ConnectShare (NOTSILENT))
return 0; return 0;
SMBFILE smbfile;
int dsize = datasize; int dsize = datasize;
int wrote = 0; int wrote = 0;
int boffset = 0; int boffset = 0;
@ -297,10 +262,10 @@ SaveBufferToSMB (char * sbuffer, char *filepath, int datasize, bool silent)
{ {
if (dsize > 1024) if (dsize > 1024)
wrote = wrote =
SMB_WriteFile ((char *) sbuffer + boffset, 1024, boffset, smbfile); SMB_WriteFile ((char *) savebuffer + boffset, 1024, boffset, smbfile);
else else
wrote = wrote =
SMB_WriteFile ((char *) sbuffer + boffset, dsize, boffset, smbfile); SMB_WriteFile ((char *) savebuffer + boffset, dsize, boffset, smbfile);
boffset += wrote; boffset += wrote;
dsize -= wrote; dsize -= wrote;
@ -314,6 +279,7 @@ SaveBufferToSMB (char * sbuffer, char *filepath, int datasize, bool silent)
WaitPrompt (msg); WaitPrompt (msg);
} }
ClearSaveBuffer ();
return boffset; return boffset;
} }
@ -325,19 +291,22 @@ SaveBufferToSMB (char * sbuffer, char *filepath, int datasize, bool silent)
int int
LoadBufferFromSMB (char *filepath, bool silent) LoadBufferFromSMB (char *filepath, bool silent)
{ {
return LoadBufferFromSMB((char *)savebuffer, filepath, 0, silent); ClearSaveBuffer ();
return LoadBufferFromSMB((char *)savebuffer, filepath, silent);
} }
int int
LoadBufferFromSMB (char * sbuffer, char *filepath, int length, bool silent) LoadBufferFromSMB (char * sbuffer, char *filepath, bool silent)
{ {
if(!ConnectShare (NOTSILENT)) if(!ConnectShare (NOTSILENT))
return 0; return 0;
SMBFILE smbfile;
int ret; int ret;
int boffset = 0; int boffset = 0;
smbfile = OpenSMBFile(filepath); smbfile =
SMB_OpenFile (SMBPath(filepath), SMB_OPEN_READING, SMB_OF_OPEN, smbconn);
if (!smbfile) if (!smbfile)
{ {
@ -350,27 +319,17 @@ LoadBufferFromSMB (char * sbuffer, char *filepath, int length, bool silent)
return 0; return 0;
} }
if(length > 0 && length <= 2048) // do a partial read (eg: to check file header) ret = SMB_ReadFile (sbuffer, 1024, boffset, smbfile);
{
boffset = SMB_ReadFile (sbuffer, length, 0, smbfile);
}
else // load whole file
{
ret = SMB_ReadFile (sbuffer, 2048, boffset, smbfile);
if (IsZipFile (sbuffer)) if (IsZipFile (sbuffer))
{ {
boffset = UnZipBuffer ((unsigned char *)sbuffer, METHOD_SMB); // unzip from SMB boffset = UnZipFile ((unsigned char *)sbuffer, smbfile); // unzip from SMB
} }
else else
{ {
// Just load the file up // Just load the file up
while ((ret = SMB_ReadFile (sbuffer + boffset, 2048, boffset, smbfile)) > 0) while ((ret = SMB_ReadFile (sbuffer + boffset, 1024, boffset, smbfile)) > 0)
{ boffset += ret;
boffset += ret;
ShowProgress ((char *)"Loading...", boffset, length);
}
}
} }
SMB_CloseFile (smbfile); SMB_CloseFile (smbfile);

View File

@ -12,21 +12,14 @@
#define _NGCSMB_ #define _NGCSMB_
#include <smb.h>
bool InitializeNetwork(bool silent); bool InitializeNetwork(bool silent);
bool ConnectShare (bool silent); bool ConnectShare (bool silent);
char * SMBPath(char * path); char * SMBPath(char * path);
int UpdateSMBdirname(); int UpdateSMBdirname();
int ParseSMBdirectory (); int ParseSMBdirectory ();
SMBFILE OpenSMBFile(char * filepath); int LoadSMBFile (char *filename, int length);
int LoadSMBFile (char * fbuffer, int length);
int LoadSMBSzFile(char * filepath, unsigned char * rbuffer);
int LoadBufferFromSMB (char *filepath, bool silent); int LoadBufferFromSMB (char *filepath, bool silent);
int LoadBufferFromSMB (char * sbuffer, char *filepath, int length, bool silent); int LoadBufferFromSMB (char * sbuffer, char *filepath, bool silent);
int SaveBufferToSMB (char *filepath, int datasize, bool silent); int SaveBufferToSMB (char *filepath, int datasize, bool silent);
int SaveBufferToSMB (char * sbuffer, char *filepath, int datasize, bool silent);
extern SMBFILE smbfile;
#endif #endif

View File

@ -38,7 +38,7 @@ extern "C" {
#include "video.h" #include "video.h"
#include "vbaconfig.h" #include "vbaconfig.h"
extern bool ROMLoaded; extern int ROMSize;
extern int emulating; extern int emulating;
@ -74,10 +74,10 @@ int main()
} }
// Initialize libFAT for SD and USB // Initialize libFAT for SD and USB
fatInit (8, false); fatInitDefault();
// Initialize DVD subsystem (GameCube only) // Initialize DVD subsystem (GameCube only)
#ifdef HW_DOL #ifndef HW_RVL
DVD_Init (); DVD_Init ();
#endif #endif
@ -98,7 +98,7 @@ int main()
selectedMenu = 2; // change to preferences menu selectedMenu = 2; // change to preferences menu
} }
while (!ROMLoaded) while (ROMSize == 0)
{ {
MainMenu (selectedMenu); MainMenu (selectedMenu);
} }

View File

@ -7,13 +7,14 @@
* *
* This file controls overall program flow. Most things start and end here! * This file controls overall program flow. Most things start and end here!
***************************************************************************/ ***************************************************************************/
#ifndef _VBA_H_ #ifndef _VBA_H_
#define _VBA_H_ #define _VBA_H_
#include <gccore.h> #include <gccore.h>
#define VERSIONNUM "1.0.3" #define VERSIONNUM "1.0.0"
#define VERSIONSTR "VBA GX 1.0.3" #define VERSIONSTR "VBA GX 1.0.0"
#define VERSIONSTRFULL "Visual Boy Advance GX 1.0.3" #define VERSIONSTRFULL "Visual Boy Advance GX 1.0.0"
#define NOTSILENT 0 #define NOTSILENT 0
#define SILENT 1 #define SILENT 1
@ -45,9 +46,7 @@ struct SGCSettings{
char smbgcid[20]; char smbgcid[20];
char smbsvid[20]; char smbsvid[20];
char smbshare[20]; char smbshare[20];
int NGCZoom; // 0 - off, 1 - on
int VerifySaves; int VerifySaves;
int render; // 0 - filtered, 1 - unfiltered
}; };
extern struct SGCSettings GCSettings; extern struct SGCSettings GCSettings;

View File

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

View File

@ -13,40 +13,43 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include "agb/GBA.h" #include "GBA.h"
#include "agb/agbprint.h" #include "agbprint.h"
#include "Flash.h" #include "Flash.h"
#include "Port.h" #include "Port.h"
#include "RTC.h" #include "RTC.h"
#include "Sound.h" #include "Sound.h"
#include "Text.h"
#include "unzip.h" #include "unzip.h"
#include "Util.h" #include "Util.h"
#include "dmg/GB.h" #include "gb/GB.h"
#include "dmg/gbGlobals.h" #include "gb/gbGlobals.h"
#include "images/saveicon.h"
//#include "dmg/gbSound.h"
#include "vba.h" #include "vba.h"
#include "fileop.h" #include "fileop.h"
#include "dvd.h"
#include "smbop.h"
#include "memcardop.h"
#include "audio.h" #include "audio.h"
#include "vmmem.h" #include "vmmem.h"
#include "pal60.h"
#include "input.h" #include "input.h"
#include "video.h" #include "video.h"
#include "menudraw.h" #include "menudraw.h"
#include "gcunzip.h"
extern "C" extern "C"
{ {
#include "tbtime.h" #include "tbtime.h"
#include "sdfileio.h"
} }
static tb_t start, now; static tb_t start, now;
u32 loadtimeradjust; u32 loadtimeradjust;
int throttle = 100;
u32 throttleLastTime = 0;
static u32 autoFrameSkipLastTime = 0;
static int frameskipadjust = 0;
int vAspect = 0; int vAspect = 0;
int hAspect = 0; int hAspect = 0;
@ -79,7 +82,7 @@ int systemColorDepth = 0;
u16 systemGbPalette[24]; u16 systemGbPalette[24];
u16 systemColorMap16[0x10000]; u16 systemColorMap16[0x10000];
//u32 systemColorMap32[0x10000]; //u32 systemColorMap32[0x10000];
u32 *systemColorMap32 = NULL; u32 *systemColorMap32 = (u32 *)&systemColorMap16;
struct EmulatedSystem emulator = struct EmulatedSystem emulator =
{ {
@ -119,7 +122,7 @@ bool systemPauseOnFrame()
{ {
return false; return false;
} }
/*
void GC_Sleep(u32 dwMiliseconds) void GC_Sleep(u32 dwMiliseconds)
{ {
int nVBlanks = (dwMiliseconds / 16); int nVBlanks = (dwMiliseconds / 16);
@ -128,39 +131,21 @@ void GC_Sleep(u32 dwMiliseconds)
VIDEO_WaitVSync(); VIDEO_WaitVSync();
} }
} }
*/
static u32 autoFrameSkipLastTime = 0;
void system10Frames(int rate) void system10Frames(int rate)
{ {
if (cartridgeType == 1) if ( cartridgeType == 1 )
return; return;
u32 time = systemGetClock(); u32 time = systemGetClock();
u32 diff = time - autoFrameSkipLastTime; u32 diff = time - autoFrameSkipLastTime;
// difference should be 1/6 second or (1/6)*1000 ms or 167 ms
int timeOff = (167 - diff);
if(timeOff > 3 && timeOff < 60) // we're running ahead!
usleep(timeOff*1000); // let's take a nap
else
timeOff = 0; // timeoff was not valid
if(diff > 175 && systemFrameSkip < 9)
systemFrameSkip++;
else if(diff < 150 && systemFrameSkip > 0)
systemFrameSkip--;
autoFrameSkipLastTime = time + timeOff; // total time = processing time + sleep time
/*
// Original VBA SDL frameskip algorithm
int speed = 100; int speed = 100;
if(diff) if(diff)
speed = (1000000/rate)/diff; speed = (1000000/rate)/diff;
/* char temp[512];
sprintf(temp,"Speed: %i",speed);
MENU_DrawString( -1, 450,temp , 1 ); */
if(speed >= 98) if(speed >= 98)
{ {
@ -189,7 +174,6 @@ void system10Frames(int rate)
} }
autoFrameSkipLastTime = time; autoFrameSkipLastTime = time;
*/
} }
/**************************************************************************** /****************************************************************************
@ -197,295 +181,102 @@ void system10Frames(int rate)
****************************************************************************/ ****************************************************************************/
void systemGbPrint(u8 *data,int pages,int feed,int palette, int contrast) {} void systemGbPrint(u8 *data,int pages,int feed,int palette, int contrast) {}
void debuggerOutput(const char *s, u32 addr) {} void debuggerOutput(char *, u32) {}
void (*dbgOutput)(const char *s, u32 addr) = debuggerOutput; void (*dbgOutput)(char *, u32) = debuggerOutput;
void systemMessage(int num, const char *msg, ...) {} void systemMessage(int num, const char *msg, ...) {}
bool MemCPUReadBatteryFile(char * membuffer, int size)
{
systemSaveUpdateCounter = SYSTEM_SAVE_NOT_UPDATED;
if(size == 512 || size == 0x2000)
{
memcpy(eepromData, membuffer, size);
}
else
{
if(size == 0x20000)
{
memcpy(flashSaveMemory, membuffer, 0x20000);
flashSetSize(0x20000);
}
else
{
memcpy(flashSaveMemory, membuffer, 0x10000);
flashSetSize(0x10000);
}
}
return true;
}
extern int gbaSaveType;
int MemCPUWriteBatteryFile(char * membuffer)
{
int result = 0;
if(gbaSaveType == 0)
{
if(eepromInUse)
gbaSaveType = 3;
else
switch(saveType)
{
case 1:
gbaSaveType = 1;
break;
case 2:
gbaSaveType = 2;
break;
}
}
if((gbaSaveType) && (gbaSaveType!=5))
{
// only save if Flash/Sram in use or EEprom in use
if(gbaSaveType != 3)
{
if(gbaSaveType == 2)
{
memcpy(membuffer, flashSaveMemory, flashSize);
result = flashSize;
}
else
{
memcpy(membuffer, flashSaveMemory, 0x10000);
result = 0x10000;
}
}
else
{
memcpy(membuffer, eepromData, eepromSize);
result = eepromSize;
}
}
return result;
}
/**************************************************************************** /****************************************************************************
* SetFileBytesWritten * Saves
* Sets the # of bytes written into a file
* Used by GBA.cpp and GB.cpp
****************************************************************************/ ****************************************************************************/
void SetFileBytesWritten(int bytes) bool LoadBattery(int method, bool silent)
{
//datasize = bytes;
}
/****************************************************************************
* LoadBatteryOrState
* Load Battery/State file into memory
* action = 0 - Load battery
* action = 1 - Load state
****************************************************************************/
bool LoadBatteryOrState(int method, int action, bool silent)
{ {
char filepath[1024]; char filepath[1024];
bool result = false; bool result = false;
int offset = 0;
char ext[4];
if(action == 0)
sprintf(ext, "sav");
else
sprintf(ext, "sgm");
ShowAction ((char*) "Loading..."); ShowAction ((char*) "Loading...");
if(method == METHOD_AUTO) if(method == METHOD_AUTO)
method = autoSaveMethod(); // we use 'Save' because we need R/W method = autoSaveMethod(); // we use 'Save' because we need R/W
AllocSaveBuffer();
// load the file into savebuffer
if(method == METHOD_SD || method == METHOD_USB) if(method == METHOD_SD || method == METHOD_USB)
{ {
if(ChangeFATInterface(method, NOTSILENT)) ChangeFATInterface(method, NOTSILENT);
{ sprintf (filepath, "%s/%s/%s.sav", ROOTFATDIR, GCSettings.SaveFolder, ROMFilename);
sprintf (filepath, "%s/%s/%s.%s", ROOTFATDIR, GCSettings.SaveFolder, ROMFilename, ext); result = emulator.emuReadBattery(filepath);
offset = LoadBufferFromFAT (filepath, silent);
}
}
else if(method == METHOD_SMB)
{
sprintf (filepath, "%s/%s.%s", GCSettings.SaveFolder, ROMFilename, ext);
offset = LoadBufferFromSMB (filepath, silent);
}
else if(method == METHOD_MC_SLOTA || method == METHOD_MC_SLOTB)
{
sprintf (filepath, "%s.%s", ROMFilename, ext);
if(method == METHOD_MC_SLOTA)
offset = LoadBufferFromMC (savebuffer, CARD_SLOTA, filepath, silent);
else
offset = LoadBufferFromMC (savebuffer, CARD_SLOTB, filepath, silent);
// skip save icon and comments for Memory Card saves
int skip = sizeof (saveicon);
skip += 64; // sizeof savecomment
memmove(savebuffer, savebuffer+skip, offset-skip);
offset -= skip;
} }
// load savebuffer into VBA memory if(!result && !silent)
if (offset > 0) WaitPrompt ((char*) "Save file not found");
{
if(action == 0)
{
if(cartridgeType == 1)
result = MemgbReadBatteryFile((char *)savebuffer, offset);
else
result = MemCPUReadBatteryFile((char *)savebuffer, offset);
}
else
{
result = emulator.emuReadMemState((char *)savebuffer, offset);
}
}
FreeSaveBuffer();
if(!silent && !result)
{
if(offset == 0)
{
if(action == 0)
WaitPrompt ((char*) "Save file not found");
else
WaitPrompt ((char*) "State file not found");
}
else
{
if(action == 0)
WaitPrompt ((char*) "Invalid save file");
else
WaitPrompt ((char*) "Invalid state file");
}
}
return result; return result;
} }
bool SaveBattery(int method, bool silent)
/****************************************************************************
* SaveBatteryOrState
* Save Battery/State file into memory
* action = 0 - Save battery
* action = 1 - Save state
****************************************************************************/
bool SaveBatteryOrState(int method, int action, bool silent)
{ {
char filepath[1024]; char filepath[1024];
char savecomment[2][32];
bool result = false; bool result = false;
int offset = 0;
char ext[4];
char savetype[10];
int datasize = 0; // we need the actual size of the data written
if(action == 0) ShowAction ((char*) "Saving...");
if(method == METHOD_AUTO)
method = autoSaveMethod(); // we use 'Save' because we need R/W
if(method == METHOD_SD || method == METHOD_USB)
{ {
sprintf(ext, "sav"); ChangeFATInterface(method, NOTSILENT);
sprintf(savetype, "SRAM"); sprintf (filepath, "%s/%s/%s.sav", ROOTFATDIR, GCSettings.SaveFolder, ROMFilename);
result = emulator.emuWriteBattery(filepath);
} }
else
if(!result && !silent)
WaitPrompt ((char*) "Save failed");
return result;
}
bool LoadState(int method, bool silent)
{
char filepath[1024];
bool result = false;
ShowAction ((char*) "Loading...");
if(method == METHOD_AUTO)
method = autoSaveMethod(); // we use 'Save' because we need R/W
if(method == METHOD_SD || method == METHOD_USB)
{ {
sprintf(ext, "sgm"); ChangeFATInterface(method, NOTSILENT);
sprintf(savetype, "Freeze"); sprintf (filepath, "%s/%s/%s.sgm", ROOTFATDIR, GCSettings.SaveFolder, ROMFilename);
result = emulator.emuReadState(filepath);
} }
if(!result && !silent)
WaitPrompt ((char*) "State file not found");
return result;
}
bool SaveState(int method, bool silent)
{
char filepath[1024];
bool result = false;
ShowAction ((char*) "Saving..."); ShowAction ((char*) "Saving...");
if(method == METHOD_AUTO) if(method == METHOD_AUTO)
method = autoSaveMethod(); // we use 'Save' because we need R/W method = autoSaveMethod(); // we use 'Save' because we need R/W
AllocSaveBuffer(); if(method == METHOD_SD || method == METHOD_USB)
// add save icon and comments for Memory Card saves
if(method == METHOD_MC_SLOTA || method == METHOD_MC_SLOTB)
{ {
offset = sizeof (saveicon); ChangeFATInterface(method, NOTSILENT);
sprintf (filepath, "%s/%s/%s.sgm", ROOTFATDIR, GCSettings.SaveFolder, ROMFilename);
// Copy in save icon result = emulator.emuWriteState(filepath);
memcpy (savebuffer, saveicon, offset);
// And the comments
sprintf (savecomment[0], "%s %s", VERSIONSTR, savetype);
strncpy(savecomment[1], ROMFilename, 31); // truncate filename to 31 chars
savecomment[1][31] = 0; // make sure last char is null byte
memcpy (savebuffer + offset, savecomment, 64);
offset += 64;
} }
// put VBA memory into savebuffer, sets datasize to size of memory written if(!result && !silent)
if(action == 0) WaitPrompt ((char*) "Save failed");
{
if(cartridgeType == 1)
datasize = MemgbWriteBatteryFile((char *)savebuffer+offset);
else
datasize = MemCPUWriteBatteryFile((char *)savebuffer+offset);
}
else
{
bool written = emulator.emuWriteMemState((char *)savebuffer+offset, SAVEBUFFERSIZE-offset);
// we really should set datasize to the exact memory size written
// but instead we'll set it at 128K - although much of it will go unused
if(written)
datasize = (1024*128);
}
// write savebuffer into file
if(datasize > 0)
{
if(method == METHOD_SD || method == METHOD_USB)
{
if(ChangeFATInterface(method, NOTSILENT))
{
sprintf (filepath, "%s/%s/%s.%s", ROOTFATDIR, GCSettings.SaveFolder, ROMFilename, ext);
offset = SaveBufferToFAT (filepath, datasize, silent);
}
}
else if(method == METHOD_SMB)
{
sprintf (filepath, "%s/%s.%s", GCSettings.SaveFolder, ROMFilename, ext);
offset = SaveBufferToSMB (filepath, datasize, silent);
}
else if(method == METHOD_MC_SLOTA || method == METHOD_MC_SLOTB)
{
sprintf (filepath, "%s.%s", ROMFilename, ext);
if(method == METHOD_MC_SLOTA)
offset = SaveBufferToMC (savebuffer, CARD_SLOTA, filepath, datasize+offset, silent);
else
offset = SaveBufferToMC (savebuffer, CARD_SLOTB, filepath, datasize+offset, silent);
}
if(offset > 0)
{
if(!silent)
WaitPrompt ((char*) "Save successful");
result = true;
}
}
else
{
if(!silent)
WaitPrompt((char *)"No data to save!");
}
FreeSaveBuffer();
return result; return result;
} }
@ -532,73 +323,21 @@ u32 systemReadJoypad(int which)
****************************************************************************/ ****************************************************************************/
void systemDrawScreen() void systemDrawScreen()
{ {
// GB / GBC Have oodles of time - so sync on VSync
GX_Render( srcWidth, srcHeight, pix, srcPitch ); GX_Render( srcWidth, srcHeight, pix, srcPitch );
#ifdef HW_RVL
VIDEO_WaitVSync ();
#else
if ( cartridgeType == 1 )
{
VIDEO_WaitVSync();
}
#endif
} }
extern bool gbUpdateSizes(); int loadVBAROM(char filename[])
bool LoadGBROM(int method)
{ {
// cleanup GB memory
if(gbRom != NULL)
gbCleanUp();
gbRom = (u8 *)malloc(1024*1024*4); // allocate 4 MB to GB ROM
systemSaveUpdateCounter = SYSTEM_SAVE_NOT_UPDATED;
switch (method)
{
case METHOD_SD:
case METHOD_USB:
gbRomSize = LoadFATFile ((char *)gbRom, 0);
break;
case METHOD_DVD:
gbRomSize = LoadDVDFile ((unsigned char *)gbRom, 0);
break;
case METHOD_SMB:
gbRomSize = LoadSMBFile ((char *)gbRom, 0);
break;
}
if(!gbRom)
return false;
return gbUpdateSizes();
}
bool LoadVBAROM(int method)
{
int type = 0;
bool loaded = false;
// image type (checks file extension)
if(utilIsGBAImage(filelist[selection].filename))
type = 2;
else if(utilIsGBImage(filelist[selection].filename))
type = 1;
else if(utilIsZipFile(filelist[selection].filename))
{
// we need to check the file extension of the first file in the archive
char * zippedFilename = GetFirstZipFilename (method);
if(strlen(zippedFilename) > 0)
{
if(utilIsGBAImage(zippedFilename))
type = 2;
else if(utilIsGBImage(zippedFilename))
type = 1;
}
}
// leave before we do anything
if(type != 1 && type != 2)
{
WaitPrompt((char *)"Unknown game image!");
return false;
}
cartridgeType = 0; cartridgeType = 0;
srcWidth = 0; srcWidth = 0;
srcHeight = 0; srcHeight = 0;
@ -606,15 +345,17 @@ bool LoadVBAROM(int method)
destHeight = 0; destHeight = 0;
srcPitch = 0; srcPitch = 0;
IMAGE_TYPE type = utilFindType(filename);
switch( type ) switch( type )
{ {
case 2: case IMAGE_GBA:
//WaitPrompt("GameBoy Advance Image"); //WaitPrompt("GameBoy Advance Image");
cartridgeType = 2; cartridgeType = 2;
emulator = GBASystem; emulator = GBASystem;
srcWidth = 240; srcWidth = 240;
srcHeight = 160; srcHeight = 160;
loaded = VMCPULoadROM(method); VMCPULoadROM(filename);
// Actual Visual Aspect is 1.57 // Actual Visual Aspect is 1.57
hAspect = 70; hAspect = 70;
vAspect = 46; vAspect = 46;
@ -624,13 +365,13 @@ bool LoadVBAROM(int method)
cpuSaveType = 0; cpuSaveType = 0;
break; break;
case 1: case IMAGE_GB:
//WaitPrompt("GameBoy Image"); //WaitPrompt("GameBoy Image");
cartridgeType = 1; cartridgeType = 1;
emulator = GBSystem; emulator = GBSystem;
srcWidth = 160; srcWidth = 160;
srcHeight = 144; srcHeight = 144;
loaded = LoadGBROM(method); gbLoadRom(filename);
// Actual physical aspect is 1.0 // Actual physical aspect is 1.0
hAspect = 60; hAspect = 60;
vAspect = 46; vAspect = 46;
@ -638,52 +379,46 @@ bool LoadVBAROM(int method)
soundQuality = 1; soundQuality = 1;
soundBufferLen = 1470 * 2; soundBufferLen = 1470 * 2;
break; break;
default:
WaitPrompt((char *)"Unknown Image");
return 0;
break;
} }
if(!loaded) // Set defaults
flashSetSize(0x10000);
rtcEnable(true);
agbPrintEnable(false);
soundOffFlag = false;
soundLowPass = true;
// Setup GX
GX_Render_Init( srcWidth, srcHeight, hAspect, vAspect );
if ( cartridgeType == 1 )
{ {
WaitPrompt((char *)"Error loading game!"); gbSoundReset();
return false; gbSoundSetQuality(soundQuality);
} }
else else
{ {
// Set defaults soundSetQuality(soundQuality);
flashSetSize(0x20000); // 128K saves CPUInit("/VBA/BIOS/BIOS.GBA", 1);
rtcEnable(true); CPUReset();
agbPrintEnable(false);
soundOffFlag = false;
soundLowPass = true;
// Setup GX
GX_Render_Init( srcWidth, srcHeight, hAspect, vAspect );
if ( cartridgeType == 1 )
{
gbSoundReset();
gbSoundSetQuality(soundQuality);
}
else
{
soundSetQuality(soundQuality);
CPUInit("/VBA/BIOS/BIOS.GBA", 1);
CPUReset();
}
soundVolume = 0;
systemSoundOn = true;
soundInit();
emulating = 1;
// reset frameskip variables
autoFrameSkipLastTime = systemFrameSkip = 0;
// Start system clock
mftb(&start);
return true;
} }
soundVolume = 0;
systemSoundOn = true;
soundInit();
emulating = 1;
// Start system clock
mftb(&start);
return 1;
} }
/**************************************************************************** /****************************************************************************

View File

@ -12,7 +12,9 @@
extern struct EmulatedSystem emulator; extern struct EmulatedSystem emulator;
extern u32 loadtimeradjust; extern u32 loadtimeradjust;
bool LoadVBAROM(int method); int loadVBAROM(char filename[]);
void InitialisePalette(); void InitialisePalette();
bool LoadBatteryOrState(int method, int action, bool silent); bool LoadBattery(int method, bool silent);
bool SaveBatteryOrState(int method, int action, bool silent); bool SaveBattery(int method, bool silent);
bool LoadState(int method, bool silent);
bool SaveState(int method, bool silent);

View File

@ -11,43 +11,32 @@
* These are pretty standard functions to setup and use GX scaling. * These are pretty standard functions to setup and use GX scaling.
***************************************************************************/ ***************************************************************************/
#include <gccore.h> #include <gccore.h>
#include <unistd.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <malloc.h> #include <malloc.h>
#include <wiiuse/wpad.h> #include <wiiuse/wpad.h>
#include "images/bg.h"
#include "vba.h"
#include "menudraw.h"
//#include "pal60.h"
extern unsigned int SMBTimer; // timer to reset SMB connection
u32 FrameTimer = 0;
/*** External 2D Video ***/ /*** External 2D Video ***/
/*** 2D Video Globals ***/ /*** 2D Video Globals ***/
GXRModeObj *vmode = NULL; // Graphics Mode Object GXRModeObj *vmode; /*** Graphics Mode Object ***/
unsigned int *xfb[2]; // Framebuffers u32 *xfb[2] = { NULL, NULL }; /*** Framebuffers ***/
int whichfb = 0; // Frame buffer toggle int whichfb = 0; /*** Frame buffer toggle ***/
int screenheight; int screenheight;
/*** 3D GX ***/ /*** 3D GX ***/
#define DEFAULT_FIFO_SIZE ( 256 * 1024 ) #define DEFAULT_FIFO_SIZE ( 256 * 1024 )
static u8 gp_fifo[DEFAULT_FIFO_SIZE] ATTRIBUTE_ALIGN(32); static u8 gp_fifo[DEFAULT_FIFO_SIZE] ATTRIBUTE_ALIGN(32);
unsigned int copynow = GX_FALSE;
/*** Texture memory ***/ /*** Texture memory ***/
static u8 *texturemem = NULL; static u8 *texturemem;
static int texturesize; static int texturesize;
GXTexObj texobj; GXTexObj texobj;
static Mtx view; static Mtx view;
static int vwidth, vheight, oldvwidth, oldvheight; static int vwidth, vheight, oldvwidth, oldvheight;
static int video_vaspect, video_haspect; unsigned int copynow = GX_FALSE;
int updateScaling;
float zoom_level = 1;
#define HASPECT 80 #define HASPECT 80
#define VASPECT 45 #define VASPECT 45
@ -81,92 +70,84 @@ static camera cam = { {0.0F, 0.0F, 0.0F},
{0.0F, 0.0F, -0.5F} {0.0F, 0.0F, -0.5F}
}; };
#ifdef VIDEO_THREADING
/**************************************************************************** /****************************************************************************
* VideoThreading * StartGX
***************************************************************************/ ****************************************************************************/
#define TSTACK 16384 void GX_Start()
lwpq_t videoblankqueue;
lwp_t vbthread;
static unsigned char vbstack[TSTACK];
/****************************************************************************
* vbgetback
*
* This callback enables the emulator to keep running while waiting for a
* vertical blank.
*
* Putting LWP to good use :)
***************************************************************************/
static void *
vbgetback (void *arg)
{ {
while (1) Mtx p;
{
VIDEO_WaitVSync (); /**< Wait for video vertical blank */
LWP_SuspendThread (vbthread);
}
return NULL; GXColor gxbackground = { 0, 0, 0, 0xff };
/*** Clear out FIFO area ***/
memset(&gp_fifo, 0, DEFAULT_FIFO_SIZE);
/*** Initialise GX ***/
GX_Init(&gp_fifo, DEFAULT_FIFO_SIZE);
GX_SetCopyClear(gxbackground, 0x00ffffff);
GX_SetViewport(0, 0, vmode->fbWidth, vmode->efbHeight, 0, 1);
GX_SetDispCopyYScale((f32) vmode->xfbHeight / (f32) vmode->efbHeight);
GX_SetScissor(0, 0, vmode->fbWidth, vmode->efbHeight);
GX_SetDispCopySrc(0, 0, vmode->fbWidth, vmode->efbHeight);
GX_SetDispCopyDst(vmode->fbWidth, vmode->xfbHeight);
GX_SetCopyFilter(vmode->aa, vmode->sample_pattern, GX_TRUE,
vmode->vfilter);
GX_SetFieldMode(vmode->field_rendering,
((vmode->viHeight ==
2 * vmode->xfbHeight) ? GX_ENABLE : GX_DISABLE));
GX_SetPixelFmt(GX_PF_RGB8_Z24, GX_ZC_LINEAR);
GX_SetCullMode(GX_CULL_NONE);
GX_CopyDisp(xfb[whichfb ^ 1], GX_TRUE);
GX_SetDispCopyGamma(GX_GM_1_0);
guPerspective(p, 60, 1.33F, 10.0F, 1000.0F);
GX_LoadProjectionMtx(p, GX_PERSPECTIVE);
} }
/**************************************************************************** /****************************************************************************
* InitVideoThread * UpdatePadsCB
* *
* libOGC provides a nice wrapper for LWP access. * called by postRetraceCallback in InitGCVideo - scans gcpad and wpad
* This function sets up a new local queue and attaches the thread to it.
***************************************************************************/ ***************************************************************************/
void void
InitVideoThread () UpdatePadsCB ()
{ {
/*** Initialise a new queue ***/ #ifdef HW_RVL
LWP_InitQueue (&videoblankqueue); WPAD_ScanPads();
/*** Create the thread on this queue ***/
LWP_CreateThread (&vbthread, vbgetback, NULL, vbstack, TSTACK, 80);
}
#endif #endif
PAD_ScanPads();
/****************************************************************************
* copy_to_xfb
*
* Stock code to copy the GX buffer to the current display mode.
* Also increments the frameticker, as it's called for each vb.
***************************************************************************/
static void
copy_to_xfb (u32 arg)
{
if (copynow == GX_TRUE)
{
GX_CopyDisp (xfb[whichfb], GX_TRUE);
GX_Flush ();
copynow = GX_FALSE;
}
FrameTimer++;
SMBTimer++;
} }
/**************************************************************************** /****************************************************************************
* Drawing screen * Initialise Video
***************************************************************************/ *
void * Before doing anything in libogc, it's recommended to configure a video
clearscreen () * output.
****************************************************************************/
void InitialiseVideo ()
{ {
int colour = COLOR_BLACK; /*** Start VIDEO Subsystem ***/
VIDEO_Init();
whichfb ^= 1; vmode = VIDEO_GetPreferredMode(NULL);
VIDEO_ClearFrameBuffer (vmode, xfb[whichfb], colour); VIDEO_Configure(vmode);
memcpy (xfb[whichfb], &bg, 1280 * 480);
}
void screenheight = vmode->xfbHeight;
showscreen ()
{ xfb[0] = (u32 *) MEM_K0_TO_K1 (SYS_AllocateFramebuffer (vmode));
VIDEO_SetNextFramebuffer (xfb[whichfb]); xfb[1] = (u32 *) MEM_K0_TO_K1 (SYS_AllocateFramebuffer (vmode));
VIDEO_Flush ();
VIDEO_WaitVSync (); VIDEO_SetNextFramebuffer(xfb[0]);
VIDEO_SetBlack(FALSE);
VIDEO_Flush();
VIDEO_WaitVSync();
if(vmode->viTVMode&VI_NON_INTERLACE) VIDEO_WaitVSync();
VIDEO_SetPostRetraceCallback((VIRetraceCallback)UpdatePadsCB);
VIDEO_SetNextFramebuffer(xfb[0]);
GX_Start();
} }
/**************************************************************************** /****************************************************************************
@ -174,26 +155,24 @@ showscreen ()
****************************************************************************/ ****************************************************************************/
static void draw_init(void) static void draw_init(void)
{ {
GX_ClearVtxDesc (); GX_ClearVtxDesc();
GX_SetVtxDesc (GX_VA_POS, GX_INDEX8); GX_SetVtxDesc(GX_VA_POS, GX_INDEX8);
GX_SetVtxDesc (GX_VA_CLR0, GX_INDEX8); GX_SetVtxDesc(GX_VA_CLR0, GX_INDEX8);
GX_SetVtxDesc (GX_VA_TEX0, GX_DIRECT); GX_SetVtxDesc(GX_VA_TEX0, GX_DIRECT);
GX_SetVtxAttrFmt (GX_VTXFMT0, GX_VA_POS, GX_POS_XYZ, GX_S16, 0); GX_SetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_POS_XYZ, GX_S16, 0);
GX_SetVtxAttrFmt (GX_VTXFMT0, GX_VA_CLR0, GX_CLR_RGBA, GX_RGBA8, 0); GX_SetVtxAttrFmt(GX_VTXFMT0, GX_VA_CLR0, GX_CLR_RGBA, GX_RGBA8, 0);
GX_SetVtxAttrFmt (GX_VTXFMT0, GX_VA_TEX0, GX_TEX_ST, GX_F32, 0); GX_SetVtxAttrFmt(GX_VTXFMT0, GX_VA_TEX0, GX_TEX_ST, GX_F32, 0);
GX_SetArray (GX_VA_POS, square, 3 * sizeof (s16)); GX_SetArray(GX_VA_POS, square, 3 * sizeof(s16));
GX_SetNumTexGens (1); GX_SetNumTexGens(1);
GX_SetNumChans (0); GX_SetTexCoordGen(GX_TEXCOORD0, GX_TG_MTX2x4, GX_TG_TEX0, GX_IDENTITY);
GX_SetTexCoordGen (GX_TEXCOORD0, GX_TG_MTX2x4, GX_TG_TEX0, GX_IDENTITY);
GX_InvalidateTexAll(); GX_InvalidateTexAll();
memset (&view, 0, sizeof (Mtx));
guLookAt(view, &cam.pos, &cam.up, &cam.view); GX_InitTexObj(&texobj, texturemem, vwidth, vheight, GX_TF_RGB565,
GX_LoadPosMtxImm (view, GX_PNMTX0); GX_CLAMP, GX_CLAMP, GX_FALSE);
} }
static void draw_vert(u8 pos, u8 c, f32 s, f32 t) static void draw_vert(u8 pos, u8 c, f32 s, f32 t)
@ -221,234 +200,23 @@ static void draw_square(Mtx v)
GX_End(); GX_End();
} }
/****************************************************************************
* StartGX
****************************************************************************/
void GX_Start()
{
Mtx p;
GXColor background = { 0, 0, 0, 0xff };
/*** Clear out FIFO area ***/
memset (&gp_fifo, 0, DEFAULT_FIFO_SIZE);
/*** Initialise GX ***/
GX_Init (&gp_fifo, DEFAULT_FIFO_SIZE);
GX_SetCopyClear (background, 0x00ffffff);
GX_SetViewport (0, 0, vmode->fbWidth, vmode->efbHeight, 0, 1);
GX_SetDispCopyYScale ((f32) vmode->xfbHeight / (f32) vmode->efbHeight);
GX_SetScissor (0, 0, vmode->fbWidth, vmode->efbHeight);
GX_SetDispCopySrc (0, 0, vmode->fbWidth, vmode->efbHeight);
GX_SetDispCopyDst (vmode->fbWidth, vmode->xfbHeight);
GX_SetCopyFilter (vmode->aa, vmode->sample_pattern, GX_TRUE, vmode->vfilter);
GX_SetFieldMode (vmode->field_rendering, ((vmode->viHeight == 2 * vmode->xfbHeight) ? GX_ENABLE : GX_DISABLE));
GX_SetPixelFmt (GX_PF_RGB8_Z24, GX_ZC_LINEAR);
GX_SetCullMode (GX_CULL_NONE);
GX_SetDispCopyGamma (GX_GM_1_0);
GX_SetZMode (GX_TRUE, GX_LEQUAL, GX_TRUE);
GX_SetColorUpdate (GX_TRUE);
guPerspective(p, 60, 1.33F, 10.0F, 1000.0F);
GX_LoadProjectionMtx(p, GX_PERSPECTIVE);
GX_SetTevOp(GX_TEVSTAGE0, GX_DECAL);
GX_SetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD0, GX_TEXMAP0, GX_COLOR0A0);
GX_CopyDisp (xfb[whichfb], GX_TRUE); // reset xfb
}
/****************************************************************************
* UpdatePadsCB
*
* called by postRetraceCallback in InitGCVideo - scans gcpad and wpad
***************************************************************************/
void
UpdatePadsCB ()
{
#ifdef HW_RVL
WPAD_ScanPads();
#endif
PAD_ScanPads();
}
/****************************************************************************
* Initialise Video
*
* Before doing anything in libogc, it's recommended to configure a video
* output.
****************************************************************************/
void InitialiseVideo ()
{
/*** Start VIDEO Subsystem ***/
VIDEO_Init();
vmode = VIDEO_GetPreferredMode(NULL);
#ifdef HW_DOL
/* we have component cables, but the preferred mode is interlaced
* why don't we switch into progressive?
* on the Wii, the user can do this themselves on their Wii Settings */
if(VIDEO_HaveComponentCable() && vmode == &TVNtsc480IntDf)
vmode = &TVNtsc480Prog;
#endif
VIDEO_Configure(vmode);
screenheight = vmode->xfbHeight;
xfb[0] = (u32 *) MEM_K0_TO_K1 (SYS_AllocateFramebuffer (vmode));
xfb[1] = (u32 *) MEM_K0_TO_K1 (SYS_AllocateFramebuffer (vmode));
// Clear framebuffers etc.
VIDEO_ClearFrameBuffer (vmode, xfb[0], COLOR_BLACK);
VIDEO_ClearFrameBuffer (vmode, xfb[1], COLOR_BLACK);
VIDEO_SetNextFramebuffer (xfb[0]);
// video callbacks
VIDEO_SetPostRetraceCallback ((VIRetraceCallback)UpdatePadsCB);
VIDEO_SetPreRetraceCallback ((VIRetraceCallback)copy_to_xfb);
VIDEO_SetNextFramebuffer(xfb[0]);
VIDEO_SetBlack(FALSE);
// set timings in VI to PAL60
/*u32 *vreg = (u32 *)0xCC002000;
for (int i = 0; i < 64; i++ )
vreg[i] = vpal60[i];*/
VIDEO_Flush();
VIDEO_WaitVSync();
if(vmode->viTVMode&VI_NON_INTERLACE)
VIDEO_WaitVSync();
copynow = GX_FALSE;
GX_Start();
#ifdef VIDEO_THREADING
InitVideoThread ();
#endif
}
/****************************************************************************
* ResetVideo_Emu
*
* Reset the video/rendering mode for the emulator rendering
****************************************************************************/
void
ResetVideo_Emu ()
{
GXRModeObj *rmode;
rmode = vmode; // same mode as menu
VIDEO_Configure (rmode);
VIDEO_ClearFrameBuffer (rmode, xfb[0], COLOR_BLACK);
VIDEO_ClearFrameBuffer (rmode, xfb[1], COLOR_BLACK);
VIDEO_Flush();
VIDEO_WaitVSync();
if (rmode->viTVMode & VI_NON_INTERLACE) VIDEO_WaitVSync();
else while (VIDEO_GetNextField()) VIDEO_WaitVSync();
GX_SetViewport (0, 0, rmode->fbWidth, rmode->efbHeight, 0, 1);
GX_SetDispCopyYScale ((f32) rmode->xfbHeight / (f32) rmode->efbHeight);
GX_SetScissor (0, 0, rmode->fbWidth, rmode->efbHeight);
GX_SetDispCopySrc (0, 0, rmode->fbWidth, rmode->efbHeight);
GX_SetDispCopyDst (rmode->fbWidth, rmode->xfbHeight);
GX_SetCopyFilter (rmode->aa, rmode->sample_pattern, (GCSettings.render == 0) ? GX_TRUE : GX_FALSE, rmode->vfilter); // AA on only for filtered mode
GX_SetFieldMode (rmode->field_rendering, ((rmode->viHeight == 2 * rmode->xfbHeight) ? GX_ENABLE : GX_DISABLE));
GX_SetPixelFmt (GX_PF_RGB8_Z24, GX_ZC_LINEAR);
}
/****************************************************************************
* ResetVideo_Menu
*
* Reset the video/rendering mode for the menu
****************************************************************************/
void
ResetVideo_Menu ()
{
VIDEO_Configure (vmode);
VIDEO_ClearFrameBuffer (vmode, xfb[whichfb], COLOR_BLACK);
VIDEO_Flush();
VIDEO_WaitVSync();
if (vmode->viTVMode & VI_NON_INTERLACE) VIDEO_WaitVSync();
else while (VIDEO_GetNextField()) VIDEO_WaitVSync();
GX_SetViewport (0, 0, vmode->fbWidth, vmode->efbHeight, 0, 1);
GX_SetDispCopyYScale ((f32) vmode->xfbHeight / (f32) vmode->efbHeight);
GX_SetScissor (0, 0, vmode->fbWidth, vmode->efbHeight);
GX_SetDispCopySrc (0, 0, vmode->fbWidth, vmode->efbHeight);
GX_SetDispCopyDst (vmode->fbWidth, vmode->xfbHeight);
GX_SetCopyFilter (vmode->aa, vmode->sample_pattern, GX_TRUE, vmode->vfilter);
GX_SetFieldMode (vmode->field_rendering, ((vmode->viHeight == 2 * vmode->xfbHeight) ? GX_ENABLE : GX_DISABLE));
GX_SetPixelFmt (GX_PF_RGB8_Z24, GX_ZC_LINEAR);
}
void UpdateScaling()
{
// Update scaling
int xscale = video_haspect;
int yscale = video_vaspect;
// change zoom
xscale *= zoom_level;
yscale *= zoom_level;
// Set new aspect (now with crap AR hack!)
square[0] = square[9] = (-xscale - 7);
square[3] = square[6] = (xscale + 7);
square[1] = square[4] = (yscale + 7);
square[7] = square[10] = (-yscale - 7);
GX_InvVtxCache (); // update vertex cache
GX_InitTexObj (&texobj, texturemem, vwidth, vheight, GX_TF_RGB565, GX_CLAMP, GX_CLAMP, GX_FALSE); // initialize the texture obj we are going to use
if (GCSettings.render == 1)
GX_InitTexObjLOD(&texobj,GX_NEAR,GX_NEAR_MIP_NEAR,2.5,9.0,0.0,GX_FALSE,GX_FALSE,GX_ANISO_1); // original/unfiltered video mode: force texture filtering OFF
GX_LoadTexObj (&texobj, GX_TEXMAP0); // load texture object so its ready to use
draw_init();
updateScaling = 0;
}
void GX_Render_Init(int width, int height, int haspect, int vaspect) void GX_Render_Init(int width, int height, int haspect, int vaspect)
{ {
ResetVideo_Emu (); // reset video to emulator rendering settings /*** Set new aspect (now with crap AR hack!) ***/
square[0] = square[9] = (-haspect - 7);
if (texturemem) square[3] = square[6] = (haspect + 7);
free(texturemem); square[1] = square[4] = (vaspect + 7);
square[7] = square[10] = (-vaspect - 7);
/*** Allocate 32byte aligned texture memory ***/ /*** Allocate 32byte aligned texture memory ***/
texturesize = (width * height) * 2; texturesize = (width * height) * 2;
texturemem = (u8 *) memalign(32, texturesize); texturemem = (u8 *) memalign(32, texturesize);
memset(texturemem, 0, texturesize); memset(texturemem, 0, texturesize);
/*** Setup for first call to scaler ***/ /*** Setup for first call to scaler ***/
vwidth = width; vwidth = vheight = oldvwidth = oldvheight = -1;
vheight = height;
oldvwidth = oldvheight = -1;
video_vaspect = vaspect;
video_haspect = haspect;
UpdateScaling();
} }
/**************************************************************************** /****************************************************************************
* GX_Render * GX_Render
* *
@ -469,30 +237,24 @@ void GX_Render(int width, int height, u8 * buffer, int pitch)
vwidth = width; vwidth = width;
vheight = height; vheight = height;
#ifdef VIDEO_THREADING
// Ensure previous vb has complete
while ((LWP_ThreadIsSuspended (vbthread) == 0) || (copynow == GX_TRUE))
#else
while (copynow == GX_TRUE)
#endif
{
usleep (50);
}
whichfb ^= 1; whichfb ^= 1;
if(updateScaling)
{
UpdateScaling();
}
if ((oldvheight != vheight) || (oldvwidth != vwidth)) if ((oldvheight != vheight) || (oldvwidth != vwidth))
{ {
/** Update scaling **/
oldvwidth = vwidth; oldvwidth = vwidth;
oldvheight = vheight; oldvheight = vheight;
updateScaling = 1; draw_init();
memset(&view, 0, sizeof(Mtx));
guLookAt(view, &cam.pos, &cam.up, &cam.view);
GX_SetViewport(0, 0, vmode->fbWidth, vmode->efbHeight, 0, 1);
} }
GX_InvVtxCache();
GX_InvalidateTexAll();
GX_SetTevOp(GX_TEVSTAGE0, GX_DECAL);
GX_SetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD0, GX_TEXMAP0, GX_COLOR0A0);
for (h = 0; h < vheight; h += 4) for (h = 0; h < vheight; h += 4)
{ {
for (w = 0; w < (vwidth >> 2); w++) for (w = 0; w < (vwidth >> 2); w++)
@ -522,43 +284,49 @@ void GX_Render(int width, int height, u8 * buffer, int pitch)
} }
DCFlushRange(texturemem, texturesize); DCFlushRange(texturemem, texturesize);
GX_InvalidateTexAll ();
GX_SetNumChans(1);
GX_LoadTexObj(&texobj, GX_TEXMAP0);
draw_square(view); draw_square(view);
GX_DrawDone(); GX_DrawDone();
GX_SetZMode(GX_TRUE, GX_LEQUAL, GX_TRUE);
GX_SetColorUpdate(GX_TRUE);
GX_CopyDisp(xfb[whichfb], GX_TRUE);
GX_Flush();
VIDEO_SetNextFramebuffer(xfb[whichfb]); VIDEO_SetNextFramebuffer(xfb[whichfb]);
VIDEO_Flush(); VIDEO_Flush();
copynow = GX_TRUE; //VIDEO_WaitVSync();
}
#ifdef VIDEO_THREADING
// Return to caller, don't waste time waiting for vb /****************************************************************************
LWP_ResumeThread (vbthread); * Drawing screen
***************************************************************************/
void
clearscreen (int c)
{
int colour = COLOR_WHITE;
whichfb ^= 1;
VIDEO_ClearFrameBuffer (vmode, xfb[whichfb], colour);
#ifdef HW_RVL
// on wii copy from memory
//memcpy ((char *) xfb[whichfb], (char *) backdrop, 640 * screenheight * 2);
#else
// on gc copy from aram
//ARAMFetch ((char *) xfb[whichfb], (char *) AR_BACKDROP, 640 * screenheight * 2);
#endif #endif
} }
/****************************************************************************
* Zoom Functions
***************************************************************************/
void void
zoom (float speed) showscreen ()
{ {
if (zoom_level > 1) copynow = GX_FALSE;
zoom_level += (speed / -100.0); VIDEO_SetNextFramebuffer (xfb[whichfb]);
else VIDEO_Flush ();
zoom_level += (speed / -200.0); VIDEO_WaitVSync ();
if (zoom_level < 0.5) zoom_level = 0.5;
else if (zoom_level > 10.0) zoom_level = 10.0;
oldvheight = 0; // update video
}
void
zoom_reset ()
{
zoom_level = 1.0;
oldvheight = 0; // update video
} }

View File

@ -15,13 +15,9 @@
#define __GXHDR__ #define __GXHDR__
void InitialiseVideo (); void InitialiseVideo ();
void GX_Start();
void GX_Render_Init(int width, int height, int haspect, int vaspect); void GX_Render_Init(int width, int height, int haspect, int vaspect);
void GX_Render(int width, int height, u8 * buffer, int pitch); void GX_Render(int width, int height, u8 * buffer, int pitch);
void clearscreen (); void clearscreen (int colour = COLOR_BLACK);
void showscreen (); void showscreen ();
void zoom (float speed);
void zoom_reset ();
void ResetVideo_Menu ();
#endif #endif

View File

@ -9,6 +9,7 @@
***************************************************************************/ ***************************************************************************/
#ifdef HW_RVL #ifdef HW_RVL
#include "sdfileio.h"
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
@ -16,18 +17,12 @@
#include <fat.h> #include <fat.h>
#include <sys/dir.h> #include <sys/dir.h>
#include "agb/GBA.h" #include "GBA.h"
#include "Globals.h" #include "Globals.h"
#include "Util.h" #include "Util.h"
#include "Port.h" #include "Port.h"
#include "vba.h"
#include "smbop.h"
#include "fileop.h"
#include "dvd.h"
#include "menudraw.h" #include "menudraw.h"
#include "filesel.h"
#include "gcunzip.h"
extern "C" { extern "C" {
#include "tbtime.h" #include "tbtime.h"
@ -40,7 +35,9 @@ extern "C" {
unsigned int MEM2Storage = 0x91000000; unsigned int MEM2Storage = 0x91000000;
static char *gbabase = NULL; static char *gbabase = NULL;
static FILE *romfile = NULL;
static u32 GBAROMSize = 0; static u32 GBAROMSize = 0;
static char romfilename[1024];
/** /**
* GBA Memory * GBA Memory
@ -91,7 +88,12 @@ static void VMClose( void )
if ( gbabase != NULL ) if ( gbabase != NULL )
free(gbabase); free(gbabase);
if ( romfile != NULL )
gen_fclose(romfile);
gbabase = NULL; gbabase = NULL;
romfile = NULL;
} }
/**************************************************************************** /****************************************************************************
@ -99,49 +101,49 @@ static void VMClose( void )
* *
* MEM2 version of GBA CPULoadROM * MEM2 version of GBA CPULoadROM
****************************************************************************/ ****************************************************************************/
int VMCPULoadROM( char *filename )
bool VMCPULoadROM(int method)
{ {
VMClose(); int res=0;
VMAllocGBA(); char temp[512];
GBAROMSize = 0; VMClose();
VMAllocGBA();
GBAROMSize = 0;
sprintf(temp,"Filename %s\n", filename);
//WaitPrompt(temp);
romfile = gen_fopen(filename, "rb");
if ( romfile == NULL )
{
WaitPrompt((char*) "Error opening file!");
//while(1);
VMClose();
return 0;
}
fseek(romfile, 0, SEEK_END);
GBAROMSize = ftell(romfile);
fseek(romfile, 0, SEEK_SET);
sprintf(temp,"ROM Size %dMb (%dMBit)", GBAROMSize/1024/1024,(GBAROMSize*8)/1024/1024);
//WaitPrompt(temp);
rom = (u8 *)MEM2Storage; rom = (u8 *)MEM2Storage;
switch (method) /* Always use MEM2, regardless of ROM size */
{ res = gen_fread(rom, 1, GBAROMSize, romfile);
case METHOD_SD:
case METHOD_USB:
if(inSz)
GBAROMSize = LoadFATSzFile(szpath, (unsigned char *)rom);
else
GBAROMSize = LoadFATFile((char *)rom, filelist[selection].length);
break;
case METHOD_DVD: if ( (u32)res != GBAROMSize )
if(inSz) {
GBAROMSize = SzExtractFile(filelist[selection].offset, (unsigned char *)rom); WaitPrompt((char*) "Error reading file!");
else while(1);
GBAROMSize = LoadDVDFile((unsigned char *)rom, filelist[selection].length); }
break; strcpy( romfilename, filename );
case METHOD_SMB: CPUUpdateRenderBuffers( true );
if(inSz)
GBAROMSize = LoadSMBSzFile(szpath, (unsigned char *)rom);
else
GBAROMSize = LoadSMBFile((char *)rom, filelist[selection].length);
break;
}
if(GBAROMSize) return 1;
{
CPUUpdateRenderBuffers( true );
return true;
}
else
{
VMClose();
return false;
}
} }
@ -161,6 +163,8 @@ u32 VMRead32( u32 address )
} }
return READ32LE((rom + address)); return READ32LE((rom + address));
} }
/**************************************************************************** /****************************************************************************
@ -198,20 +202,18 @@ u8 VMRead8( u32 address )
} }
#else #else
#include "sdfileio.h"
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <malloc.h> #include <malloc.h>
#include "agb/GBA.h" #include "GBA.h"
#include "Globals.h" #include "Globals.h"
#include "Util.h" #include "Util.h"
#include "Port.h" #include "Port.h"
#include "menudraw.h" #include "menudraw.h"
#include "filesel.h"
#include "vba.h"
#include "fileop.h"
extern "C" { extern "C" {
#include "tbtime.h" #include "tbtime.h"
@ -245,8 +247,9 @@ static int vmpageno = 0;
static char *rombase = NULL; static char *rombase = NULL;
static char *gbabase = NULL; static char *gbabase = NULL;
static FILE* romfile = NULL; static FILE* romfile = NULL;
static int useVM = 1; static int useVM = 0;
static u32 GBAROMSize = 0; static u32 GBAROMSize = 0;
static char romfilename[1024];
/** /**
* GBA Memory * GBA Memory
@ -362,7 +365,7 @@ static void VMClose( void )
free(gbabase); free(gbabase);
if ( romfile != NULL ) if ( romfile != NULL )
fclose(romfile); gen_fclose(romfile);
rombase = gbabase = NULL; rombase = gbabase = NULL;
romfile = NULL; romfile = NULL;
@ -374,77 +377,54 @@ static void VMClose( void )
* *
* VM version of GBA CPULoadROM * VM version of GBA CPULoadROM
****************************************************************************/ ****************************************************************************/
int VMCPULoadROM( char *filename )
int VMCPULoadROM(int method)
{ {
int res; int res;
char msg[512]; char msg[512];
char filepath[MAXPATHLEN];
/** Fix VM **/ /** Fix VM **/
VMClose(); VMClose();
VMInit(); VMInit();
VMAllocGBA(); VMAllocGBA();
loadtimeradjust = GBAROMSize = 0; loadtimeradjust = useVM = GBAROMSize = 0;
switch (method) printf("Filename %s\n", filename);
{
case METHOD_SD:
case METHOD_USB:
break;
case METHOD_DVD: romfile = gen_fopen(filename, "rb");
VMClose(); if ( romfile == NULL )
return 0; // not implemented {
break; WaitPrompt((char*) "Error opening file!");
while(1);
VMClose();
return 0;
}
case METHOD_SMB: // printf("ROM Size %d\n", romfile->fsize);
VMClose();
return 0; // not implemented
break;
}
/* Check filename length */ /* Always use VM, regardless of ROM size */
if ((strlen(currentdir)+1+strlen(filelist[selection].filename)) < MAXPATHLEN) res = gen_fread(rom, 1, (1 << VMSHIFTBITS), romfile);
sprintf(filepath, "%s/%s",currentdir,filelist[selection].filename); if ( res != (1 << VMSHIFTBITS ) )
else {
{
WaitPrompt((char*) "Maximum filepath length reached!");
return -1;
}
romfile = fopen(filepath, "rb");
if ( romfile == NULL )
{
WaitPrompt((char*) "Error opening file!");
VMClose();
return 0;
}
// printf("ROM Size %d\n", romfile->fsize);
/* Always use VM, regardless of ROM size */
res = fread(rom, 1, (1 << VMSHIFTBITS), romfile);
if ( res != (1 << VMSHIFTBITS ) )
{
sprintf(msg, "Error reading file! %i \n",res); sprintf(msg, "Error reading file! %i \n",res);
WaitPrompt(msg); WaitPrompt(msg);
VMClose(); while(1);
return 0; }
}
fseek(romfile, 0, SEEK_END); fseek(romfile, 0, SEEK_END);
GBAROMSize = ftell(romfile); GBAROMSize = ftell(romfile);
fseek(romfile, 0, SEEK_SET); fseek(romfile, 0, SEEK_SET);
vmpageno = 0; vmpageno = 0;
vmpage[0].pageptr = rombase; vmpage[0].pageptr = rombase;
vmpage[0].pageno = 0; vmpage[0].pageno = 0;
vmpage[0].pagetype = MEM_VM; vmpage[0].pagetype = MEM_VM;
useVM = 1;
CPUUpdateRenderBuffers( true ); strcpy( romfilename, filename );
return 1; CPUUpdateRenderBuffers( true );
return 1;
} }
/**************************************************************************** /****************************************************************************
@ -461,24 +441,22 @@ static void VMNewPage( int pageid )
mftb(&start); mftb(&start);
res = fseek( romfile, pageid << VMSHIFTBITS, SEEK_SET ); res = gen_fseek( romfile, pageid << VMSHIFTBITS, SEEK_SET );
if ( ! res ) if ( ! res )
{ {
sprintf(msg, "Seek error! - Offset %08x %d\n", pageid << VMSHIFTBITS, res); sprintf(msg, "Seek error! - Offset %08x %d\n", pageid << VMSHIFTBITS, res);
WaitPrompt(msg); WaitPrompt(msg);
VMClose(); while(1);
return;
} }
VMAllocate( pageid ); VMAllocate( pageid );
res = fread( vmpage[pageid].pageptr, 1, 1 << VMSHIFTBITS, romfile ); res = gen_fread( vmpage[pageid].pageptr, 1, 1 << VMSHIFTBITS, romfile );
if ( res != ( 1 << VMSHIFTBITS ) ) if ( res != ( 1 << VMSHIFTBITS ) )
{ {
sprintf(msg, "Error reading! %d bytes only\n", res); sprintf(msg, "Error reading! %d bytes only\n", res);
WaitPrompt(msg); WaitPrompt(msg);
VMClose(); while(1);
return;
} }
mftb(&end); mftb(&end);
@ -538,8 +516,7 @@ u32 VMRead32( u32 address )
default: default:
sprintf(msg, "VM32 : Unknown page type! (%d) [%d]", vmpage[pageid].pagetype, pageid); sprintf(msg, "VM32 : Unknown page type! (%d) [%d]", vmpage[pageid].pagetype, pageid);
WaitPrompt(msg); WaitPrompt(msg);
VMClose(); while(1);
return 0;
} }
/* Can never get here ... but stops gcc bitchin' */ /* Can never get here ... but stops gcc bitchin' */
@ -578,8 +555,7 @@ u16 VMRead16( u32 address )
default: default:
WaitPrompt((char*) "VM16 : Unknown page type!"); WaitPrompt((char*) "VM16 : Unknown page type!");
VMClose(); while(1);
return 0;
} }
/* Can never get here ... but stops gcc bitchin' */ /* Can never get here ... but stops gcc bitchin' */
@ -618,8 +594,7 @@ u8 VMRead8( u32 address )
default: default:
WaitPrompt((char*) "VM8 : Unknown page type!"); WaitPrompt((char*) "VM8 : Unknown page type!");
VMClose(); while(1);
return 0;
} }
/* Can never get here ... but stops gcc bitchin' */ /* Can never get here ... but stops gcc bitchin' */

View File

@ -11,7 +11,7 @@
#ifndef __VBAVMHDR__ #ifndef __VBAVMHDR__
#define __VBAVMHDR__ #define __VBAVMHDR__
bool VMCPULoadROM(int method); int VMCPULoadROM( char *filename );
u32 VMRead32( u32 address ); u32 VMRead32( u32 address );
u16 VMRead16( u32 address ); u16 VMRead16( u32 address );
u8 VMRead8( u32 address ); u8 VMRead8( u32 address );

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

@ -24,9 +24,9 @@
CheatSearchBlock cheatSearchBlocks[4]; CheatSearchBlock cheatSearchBlocks[4];
CheatSearchData cheatSearchData = { CheatSearchData cheatSearchData = {
0, 0,
cheatSearchBlocks cheatSearchBlocks
}; };
static bool cheatSearchEQ(u32 a, u32 b) static bool cheatSearchEQ(u32 a, u32 b)
{ {
@ -89,31 +89,32 @@ static bool cheatSearchSignedGE(s32 a, s32 b)
} }
static bool (*cheatSearchFunc[])(u32,u32) = { static bool (*cheatSearchFunc[])(u32,u32) = {
cheatSearchEQ, cheatSearchEQ,
cheatSearchNE, cheatSearchNE,
cheatSearchLT, cheatSearchLT,
cheatSearchLE, cheatSearchLE,
cheatSearchGT, cheatSearchGT,
cheatSearchGE cheatSearchGE
}; };
static bool (*cheatSearchSignedFunc[])(s32,s32) = { static bool (*cheatSearchSignedFunc[])(s32,s32) = {
cheatSearchSignedEQ, cheatSearchSignedEQ,
cheatSearchSignedNE, cheatSearchSignedNE,
cheatSearchSignedLT, cheatSearchSignedLT,
cheatSearchSignedLE, cheatSearchSignedLE,
cheatSearchSignedGT, cheatSearchSignedGT,
cheatSearchSignedGE cheatSearchSignedGE
}; };
void cheatSearchCleanup(CheatSearchData *cs) void cheatSearchCleanup(CheatSearchData *cs)
{ {
int count = cs->count; int count = cs->count;
for(int i = 0; i < count; i++) { for(int i = 0; i < count; i++)
free(cs->blocks[i].saved); {
free(cs->blocks[i].bits); free(cs->blocks[i].saved);
} free(cs->blocks[i].bits);
}
cs->count = 0; cs->count = 0;
} }
@ -121,32 +122,34 @@ void cheatSearchStart(const CheatSearchData *cs)
{ {
int count = cs->count; int count = cs->count;
for(int i = 0; i < count; i++) { for(int i = 0; i < count; i++)
CheatSearchBlock *block = &cs->blocks[i]; {
CheatSearchBlock *block = &cs->blocks[i];
memset(block->bits, 0xff, block->size >> 3); memset(block->bits, 0xff, block->size >> 3);
memcpy(block->saved, block->data, block->size); memcpy(block->saved, block->data, block->size);
} }
} }
s32 cheatSearchSignedRead(u8 *data, int off, int size) s32 cheatSearchSignedRead(u8 *data, int off, int size)
{ {
u32 res = data[off++]; u32 res = data[off++];
switch(size) { switch(size)
case BITS_8: {
res <<= 24; case BITS_8:
return ((s32)res) >> 24; res <<= 24;
case BITS_16: return ((s32)res) >> 24;
res |= ((u32)data[off++])<<8; case BITS_16:
res <<= 16; res |= ((u32)data[off++])<<8;
return ((s32)res) >> 16; res <<= 16;
case BITS_32: return ((s32)res) >> 16;
res |= ((u32)data[off++])<<8; case BITS_32:
res |= ((u32)data[off++])<<16; res |= ((u32)data[off++])<<8;
res |= ((u32)data[off++])<<24; res |= ((u32)data[off++])<<16;
return (s32)res; res |= ((u32)data[off++])<<24;
} return (s32)res;
}
return (s32)res; return (s32)res;
} }
@ -155,11 +158,12 @@ u32 cheatSearchRead(u8 *data, int off, int size)
u32 res = data[off++]; u32 res = data[off++];
if(size == BITS_16) if(size == BITS_16)
res |= ((u32)data[off++])<<8; res |= ((u32)data[off++])<<8;
else if(size == BITS_32) { else if(size == BITS_32)
res |= ((u32)data[off++])<<8; {
res |= ((u32)data[off++])<<16; res |= ((u32)data[off++])<<8;
res |= ((u32)data[off++])<<24; res |= ((u32)data[off++])<<16;
} res |= ((u32)data[off++])<<24;
}
return res; return res;
} }
@ -174,65 +178,78 @@ void cheatSearch(const CheatSearchData *cs, int compare, int size,
else if(size == BITS_32) else if(size == BITS_32)
inc = 4; inc = 4;
if(isSigned) { if(isSigned)
bool (*func)(s32,s32) = cheatSearchSignedFunc[compare]; {
bool (*func)(s32,s32) = cheatSearchSignedFunc[compare];
for(int i = 0; i < cs->count; i++) { for(int i = 0; i < cs->count; i++)
CheatSearchBlock *block = &cs->blocks[i]; {
int size2 = block->size; CheatSearchBlock *block = &cs->blocks[i];
u8 *bits = block->bits; int size2 = block->size;
u8 *data = block->data; u8 *bits = block->bits;
u8 *saved = block->saved; u8 *data = block->data;
u8 *saved = block->saved;
for(int j = 0; j < size2; j += inc) { for(int j = 0; j < size2; j += inc)
if(IS_BIT_SET(bits, j)) { {
s32 a = cheatSearchSignedRead(data, j, size); if(IS_BIT_SET(bits, j))
s32 b = cheatSearchSignedRead(saved,j, size); {
s32 a = cheatSearchSignedRead(data, j, size);
s32 b = cheatSearchSignedRead(saved,j, size);
if(!func(a, b)) { if(!func(a, b))
CLEAR_BIT(bits, j); {
if(size == BITS_16) CLEAR_BIT(bits, j);
CLEAR_BIT(bits, j+1); if(size == BITS_16)
if(size == BITS_32) { CLEAR_BIT(bits, j+1);
CLEAR_BIT(bits, j+2); if(size == BITS_32)
CLEAR_BIT(bits, j+3); {
} CLEAR_BIT(bits, j+2);
} CLEAR_BIT(bits, j+3);
} }
} }
}
}
}
} }
} else { else
bool (*func)(u32,u32) = cheatSearchFunc[compare]; {
bool (*func)(u32,u32) = cheatSearchFunc[compare];
for(int i = 0; i < cs->count; i++) { for(int i = 0; i < cs->count; i++)
CheatSearchBlock *block = &cs->blocks[i]; {
int size2 = block->size; CheatSearchBlock *block = &cs->blocks[i];
u8 *bits = block->bits; int size2 = block->size;
u8 *data = block->data; u8 *bits = block->bits;
u8 *saved = block->saved; u8 *data = block->data;
u8 *saved = block->saved;
for(int j = 0; j < size2; j += inc) { for(int j = 0; j < size2; j += inc)
if(IS_BIT_SET(bits, j)) { {
u32 a = cheatSearchRead(data, j, size); if(IS_BIT_SET(bits, j))
u32 b = cheatSearchRead(saved,j, size); {
u32 a = cheatSearchRead(data, j, size);
u32 b = cheatSearchRead(saved,j, size);
if(!func(a, b)) { if(!func(a, b))
CLEAR_BIT(bits, j); {
if(size == BITS_16) CLEAR_BIT(bits, j);
CLEAR_BIT(bits, j+1); if(size == BITS_16)
if(size == BITS_32) { CLEAR_BIT(bits, j+1);
CLEAR_BIT(bits, j+2); if(size == BITS_32)
CLEAR_BIT(bits, j+3); {
} CLEAR_BIT(bits, j+2);
} CLEAR_BIT(bits, j+3);
} }
} }
}
}
}
} }
}
} }
void cheatSearchValue(const CheatSearchData *cs, int compare, int size, void cheatSearchValue(const CheatSearchData *cs, int compare, int size,
bool isSigned, u32 value) bool isSigned, u32 value)
{ {
if(compare < 0 || compare > SEARCH_GE) if(compare < 0 || compare > SEARCH_GE)
return; return;
@ -242,58 +259,71 @@ void cheatSearchValue(const CheatSearchData *cs, int compare, int size,
else if(size == BITS_32) else if(size == BITS_32)
inc = 4; inc = 4;
if(isSigned) { if(isSigned)
bool (*func)(s32,s32) = cheatSearchSignedFunc[compare]; {
bool (*func)(s32,s32) = cheatSearchSignedFunc[compare];
for(int i = 0; i < cs->count; i++) { for(int i = 0; i < cs->count; i++)
CheatSearchBlock *block = &cs->blocks[i]; {
int size2 = block->size; CheatSearchBlock *block = &cs->blocks[i];
u8 *bits = block->bits; int size2 = block->size;
u8 *data = block->data; u8 *bits = block->bits;
u8 *data = block->data;
for(int j = 0; j < size2; j += inc) { for(int j = 0; j < size2; j += inc)
if(IS_BIT_SET(bits, j)) { {
s32 a = cheatSearchSignedRead(data, j, size); if(IS_BIT_SET(bits, j))
s32 b = (s32)value; {
s32 a = cheatSearchSignedRead(data, j, size);
s32 b = (s32)value;
if(!func(a, b)) { if(!func(a, b))
CLEAR_BIT(bits, j); {
if(size == BITS_16) CLEAR_BIT(bits, j);
CLEAR_BIT(bits, j+1); if(size == BITS_16)
if(size == BITS_32) { CLEAR_BIT(bits, j+1);
CLEAR_BIT(bits, j+2); if(size == BITS_32)
CLEAR_BIT(bits, j+3); {
} CLEAR_BIT(bits, j+2);
} CLEAR_BIT(bits, j+3);
} }
} }
}
}
}
} }
} else { else
bool (*func)(u32,u32) = cheatSearchFunc[compare]; {
bool (*func)(u32,u32) = cheatSearchFunc[compare];
for(int i = 0; i < cs->count; i++) { for(int i = 0; i < cs->count; i++)
CheatSearchBlock *block = &cs->blocks[i]; {
int size2 = block->size; CheatSearchBlock *block = &cs->blocks[i];
u8 *bits = block->bits; int size2 = block->size;
u8 *data = block->data; u8 *bits = block->bits;
u8 *data = block->data;
for(int j = 0; j < size2; j += inc) { for(int j = 0; j < size2; j += inc)
if(IS_BIT_SET(bits, j)) { {
u32 a = cheatSearchRead(data, j, size); if(IS_BIT_SET(bits, j))
{
u32 a = cheatSearchRead(data, j, size);
if(!func(a, value)) { if(!func(a, value))
CLEAR_BIT(bits, j); {
if(size == BITS_16) CLEAR_BIT(bits, j);
CLEAR_BIT(bits, j+1); if(size == BITS_16)
if(size == BITS_32) { CLEAR_BIT(bits, j+1);
CLEAR_BIT(bits, j+2); if(size == BITS_32)
CLEAR_BIT(bits, j+3); {
} CLEAR_BIT(bits, j+2);
} CLEAR_BIT(bits, j+3);
} }
} }
}
}
}
} }
}
} }
int cheatSearchGetCount(const CheatSearchData *cs, int size) int cheatSearchGetCount(const CheatSearchData *cs, int size)
@ -305,25 +335,28 @@ int cheatSearchGetCount(const CheatSearchData *cs, int size)
else if(size == BITS_32) else if(size == BITS_32)
inc = 4; inc = 4;
for(int i = 0; i < cs->count; i++) { for(int i = 0; i < cs->count; i++)
CheatSearchBlock *block = &cs->blocks[i]; {
CheatSearchBlock *block = &cs->blocks[i];
int size2 = block->size; int size2 = block->size;
u8 *bits = block->bits; u8 *bits = block->bits;
for(int j = 0; j < size2; j += inc) { for(int j = 0; j < size2; j += inc)
if(IS_BIT_SET(bits, j)) {
res++; if(IS_BIT_SET(bits, j))
res++;
}
} }
}
return res; return res;
} }
void cheatSearchUpdateValues(const CheatSearchData *cs) void cheatSearchUpdateValues(const CheatSearchData *cs)
{ {
for(int i = 0; i < cs->count; i++) { for(int i = 0; i < cs->count; i++)
CheatSearchBlock *block = &cs->blocks[i]; {
CheatSearchBlock *block = &cs->blocks[i];
memcpy(block->saved, block->data, block->size); memcpy(block->saved, block->data, block->size);
} }
} }

View File

@ -22,18 +22,20 @@
#include "System.h" #include "System.h"
struct CheatSearchBlock { struct CheatSearchBlock
int size; {
u32 offset; int size;
u8 *bits; u32 offset;
u8 *data; u8 *bits;
u8 *saved; u8 *data;
}; u8 *saved;
};
struct CheatSearchData { struct CheatSearchData
int count; {
CheatSearchBlock *blocks; int count;
}; CheatSearchBlock *blocks;
};
enum { enum {
SEARCH_EQ, SEARCH_EQ,
@ -63,9 +65,9 @@ extern CheatSearchData cheatSearchData;
extern void cheatSearchCleanup(CheatSearchData *cs); extern void cheatSearchCleanup(CheatSearchData *cs);
extern void cheatSearchStart(const CheatSearchData *cs); extern void cheatSearchStart(const CheatSearchData *cs);
extern void cheatSearch(const CheatSearchData *cs, int compare, int size, extern void cheatSearch(const CheatSearchData *cs, int compare, int size,
bool isSigned); bool isSigned);
extern void cheatSearchValue(const CheatSearchData *cs, int compare, int size, extern void cheatSearchValue(const CheatSearchData *cs, int compare, int size,
bool isSigned, u32 value); bool isSigned, u32 value);
extern int cheatSearchGetCount(const CheatSearchData *cs, int size); extern int cheatSearchGetCount(const CheatSearchData *cs, int size);
extern void cheatSearchUpdateValues(const CheatSearchData *cs); extern void cheatSearchUpdateValues(const CheatSearchData *cs);
extern s32 cheatSearchSignedRead(u8 *data, int off, int size); extern s32 cheatSearchSignedRead(u8 *data, int off, int size);

File diff suppressed because it is too large Load Diff

View File

@ -1,7 +1,7 @@
// -*- C++ -*- // -*- C++ -*-
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator. // VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
// Copyright (C) 1999-2003 Forgotten // Copyright (C) 1999-2003 Forgotten
// Copyright (C) 2004-2006 Forgotten and the VBA development team // Copyright (C) 2004 Forgotten and the VBA development team
// This program is free software; you can redistribute it and/or modify // This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by // it under the terms of the GNU General Public License as published by
@ -20,20 +20,20 @@
#ifndef GBA_CHEATS_H #ifndef GBA_CHEATS_H
#define GBA_CHEATS_H #define GBA_CHEATS_H
struct CheatsData { struct CheatsData
int code; {
int size; int code;
int status; int size;
bool enabled; int status;
u32 rawaddress; bool enabled;
u32 address; u32 address;
u32 value; u32 value;
u32 oldValue; u32 oldValue;
char codestring[20]; char codestring[20];
char desc[32]; char desc[32];
}; };
extern void cheatsAdd(const char *,const char *,u32, u32,u32,int,int); extern void cheatsAdd(const char *,const char *,u32,u32,int,int);
extern void cheatsAddCheatCode(const char *code, const char *desc); extern void cheatsAddCheatCode(const char *code, const char *desc);
extern void cheatsAddGSACode(const char *code, const char *desc, bool v3); extern void cheatsAddGSACode(const char *code, const char *desc, bool v3);
extern void cheatsAddCBACode(const char *code, const char *desc); extern void cheatsAddCBACode(const char *code, const char *desc);
@ -43,12 +43,12 @@ extern void cheatsDeleteAll(bool restore);
extern void cheatsEnable(int number); extern void cheatsEnable(int number);
extern void cheatsDisable(int number); extern void cheatsDisable(int number);
extern void cheatsSaveGame(gzFile file); extern void cheatsSaveGame(gzFile file);
extern void cheatsReadGame(gzFile file, int version); extern void cheatsReadGame(gzFile file);
extern void cheatsSaveCheatList(const char *file); extern void cheatsSaveCheatList(const char *file);
extern bool cheatsLoadCheatList(const char *file); extern bool cheatsLoadCheatList(const char *file);
extern void cheatsWriteMemory(u32, u32); extern void cheatsWriteMemory(u32 *, u32, u32);
extern void cheatsWriteHalfWord(u32, u16); extern void cheatsWriteHalfWord(u16 *, u16, u16);
extern void cheatsWriteByte(u32, u8); extern void cheatsWriteByte(u8 *, u8);
extern int cheatsCheckKeys(u32,u32); extern int cheatsCheckKeys(u32,u32);
extern int cheatsNumber; extern int cheatsNumber;
extern CheatsData cheatsList[100]; extern CheatsData cheatsList[100];

View File

@ -1,6 +1,6 @@
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator. // VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
// Copyright (C) 1999-2003 Forgotten // Copyright (C) 1999-2003 Forgotten
// Copyright (C) 2005 Forgotten and the VBA development team // Copyright (C) 2004 Forgotten and the VBA development team
// This program is free software; you can redistribute it and/or modify // This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by // it under the terms of the GNU General Public License as published by
@ -16,8 +16,7 @@
// along with this program; if not, write to the Free Software Foundation, // along with this program; if not, write to the Free Software Foundation,
// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include <string.h> #include "GBA.h"
#include "agb/GBA.h"
#include "EEprom.h" #include "EEprom.h"
#include "Util.h" #include "Util.h"
@ -33,20 +32,15 @@ bool eepromInUse = false;
int eepromSize = 512; int eepromSize = 512;
variable_desc eepromSaveData[] = { variable_desc eepromSaveData[] = {
{ &eepromMode, sizeof(int) }, { &eepromMode, sizeof(int) },
{ &eepromByte, sizeof(int) }, { &eepromByte, sizeof(int) },
{ &eepromBits , sizeof(int) }, { &eepromBits , sizeof(int) },
{ &eepromAddress , sizeof(int) }, { &eepromAddress , sizeof(int) },
{ &eepromInUse, sizeof(bool) }, { &eepromInUse, sizeof(bool) },
{ &eepromData[0], 512 }, { &eepromData[0], 512 },
{ &eepromBuffer[0], 16 }, { &eepromBuffer[0], 16 },
{ NULL, 0 } { NULL, 0 }
}; };
void eepromInit()
{
memset(eepromData, 255, sizeof(eepromData));
}
void eepromReset() void eepromReset()
{ {
@ -68,43 +62,39 @@ void eepromSaveGame(gzFile gzFile)
void eepromReadGame(gzFile gzFile, int version) void eepromReadGame(gzFile gzFile, int version)
{ {
utilReadData(gzFile, eepromSaveData); utilReadData(gzFile, eepromSaveData);
if(version >= SAVE_GAME_VERSION_3) { if(version >= SAVE_GAME_VERSION_3)
eepromSize = utilReadInt(gzFile); {
utilGzRead(gzFile, eepromData, 0x2000); eepromSize = utilReadInt(gzFile);
} else { utilGzRead(gzFile, eepromData, 0x2000);
// prior to 0.7.1, only 4K EEPROM was supported }
eepromSize = 512; 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 */) int eepromRead(u32 /* address */)
{ {
switch(eepromMode) { switch(eepromMode)
case EEPROM_IDLE: {
case EEPROM_READADDRESS: case EEPROM_IDLE:
case EEPROM_WRITEDATA: case EEPROM_READADDRESS:
return 1; case EEPROM_WRITEDATA:
case EEPROM_READDATA: return 1;
case EEPROM_READDATA:
{ {
eepromBits++; eepromBits++;
if(eepromBits == 4) { if(eepromBits == 4)
eepromMode = EEPROM_READDATA2; {
eepromBits = 0; eepromMode = EEPROM_READDATA2;
eepromByte = 0; eepromBits = 0;
} eepromByte = 0;
}
return 0; return 0;
} }
case EEPROM_READDATA2: case EEPROM_READDATA2:
{ {
int data = 0; int data = 0;
int address = eepromAddress << 3; int address = eepromAddress << 3;
@ -117,9 +107,9 @@ int eepromRead(u32 /* address */)
eepromMode = EEPROM_IDLE; eepromMode = EEPROM_IDLE;
return data; return data;
} }
default: default:
return 0; return 0;
} }
return 1; return 1;
} }
@ -128,79 +118,97 @@ void eepromWrite(u32 /* address */, u8 value)
if(cpuDmaCount == 0) if(cpuDmaCount == 0)
return; return;
int bit = value & 1; int bit = value & 1;
switch(eepromMode) { switch(eepromMode)
case EEPROM_IDLE: {
eepromByte = 0; case EEPROM_IDLE:
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; eepromByte = 0;
eepromBits = 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;
} }
break;
}
} }

View File

@ -1,7 +1,7 @@
// -*- C++ -*- // -*- C++ -*-
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator. // VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
// Copyright (C) 1999-2003 Forgotten // Copyright (C) 1999-2003 Forgotten
// Copyright (C) 2005 Forgotten and the VBA development team // Copyright (C) 2004 Forgotten and the VBA development team
// This program is free software; you can redistribute it and/or modify // This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by // it under the terms of the GNU General Public License as published by
@ -20,12 +20,10 @@
#ifndef VBA_EEPROM_H #ifndef VBA_EEPROM_H
#define VBA_EEPROM_H #define VBA_EEPROM_H
extern void eepromSaveGame(gzFile _gzFile); extern void eepromSaveGame(gzFile gzFile);
extern void eepromReadGame(gzFile _gzFile, int version); extern void eepromReadGame(gzFile gzFile, int version);
extern void eepromReadGameSkip(gzFile _gzFile, int version);
extern int eepromRead(u32 address); extern int eepromRead(u32 address);
extern void eepromWrite(u32 address, u8 value); extern void eepromWrite(u32 address, u8 value);
extern void eepromInit();
extern void eepromReset(); extern void eepromReset();
extern u8 eepromData[0x2000]; extern u8 eepromData[0x2000];
extern bool eepromInUse; extern bool eepromInUse;

View File

@ -1,6 +1,6 @@
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator. // VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
// Copyright (C) 1999-2003 Forgotten // Copyright (C) 1999-2003 Forgotten
// Copyright (C) 2004-2006 Forgotten and the VBA development team // Copyright (C) 2004 Forgotten and the VBA development team
// This program is free software; you can redistribute it and/or modify // This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by // it under the terms of the GNU General Public License as published by
@ -18,7 +18,7 @@
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include "agb/GBA.h" #include "GBA.h"
#include "Globals.h" #include "Globals.h"
#include "Flash.h" #include "Flash.h"
#include "Sram.h" #include "Sram.h"
@ -44,33 +44,28 @@ int flashManufacturerID = 0x32;
int flashBank = 0; int flashBank = 0;
static variable_desc flashSaveData[] = { static variable_desc flashSaveData[] = {
{ &flashState, sizeof(int) }, { &flashState, sizeof(int) },
{ &flashReadState, sizeof(int) }, { &flashReadState, sizeof(int) },
{ &flashSaveMemory[0], 0x10000 }, { &flashSaveMemory[0], 0x10000 },
{ NULL, 0 } { NULL, 0 }
}; };
static variable_desc flashSaveData2[] = { static variable_desc flashSaveData2[] = {
{ &flashState, sizeof(int) }, { &flashState, sizeof(int) },
{ &flashReadState, sizeof(int) }, { &flashReadState, sizeof(int) },
{ &flashSize, sizeof(int) }, { &flashSize, sizeof(int) },
{ &flashSaveMemory[0], 0x20000 }, { &flashSaveMemory[0], 0x20000 },
{ NULL, 0 } { NULL, 0 }
}; };
static variable_desc flashSaveData3[] = { static variable_desc flashSaveData3[] = {
{ &flashState, sizeof(int) }, { &flashState, sizeof(int) },
{ &flashReadState, sizeof(int) }, { &flashReadState, sizeof(int) },
{ &flashSize, sizeof(int) }, { &flashSize, sizeof(int) },
{ &flashBank, sizeof(int) }, { &flashBank, sizeof(int) },
{ &flashSaveMemory[0], 0x20000 }, { &flashSaveMemory[0], 0x20000 },
{ NULL, 0 } { NULL, 0 }
}; };
void flashInit()
{
memset(flashSaveMemory, 0xff, sizeof(flashSaveMemory));
}
void flashReset() void flashReset()
{ {
@ -88,42 +83,32 @@ void flashReadGame(gzFile gzFile, int version)
{ {
if(version < SAVE_GAME_VERSION_5) if(version < SAVE_GAME_VERSION_5)
utilReadData(gzFile, flashSaveData); utilReadData(gzFile, flashSaveData);
else if(version < SAVE_GAME_VERSION_7) { else if(version < SAVE_GAME_VERSION_7)
utilReadData(gzFile, flashSaveData2); {
flashBank = 0; utilReadData(gzFile, flashSaveData2);
flashSetSize(flashSize); flashBank = 0;
} else { flashSetSize(flashSize);
utilReadData(gzFile, flashSaveData3); }
} 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) void flashSetSize(int size)
{ {
// log("Setting flash size to %d\n", 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; flashSize = size;
if(size == 0x10000)
{
flashDeviceID = 0x1b;
flashManufacturerID = 0x32;
}
else
{
flashDeviceID = 0x13; //0x09;
flashManufacturerID = 0x62; //0xc2;
}
} }
u8 flashRead(u32 address) u8 flashRead(u32 address)
@ -132,144 +117,172 @@ u8 flashRead(u32 address)
// log("Current read state is %d\n", flashReadState); // log("Current read state is %d\n", flashReadState);
address &= 0xFFFF; address &= 0xFFFF;
switch(flashReadState) { switch(flashReadState)
case FLASH_READ_ARRAY: {
return flashSaveMemory[(flashBank << 16) + address]; case FLASH_READ_ARRAY:
case FLASH_AUTOSELECT: return flashSaveMemory[(flashBank << 16) + address];
switch(address & 0xFF) { case FLASH_AUTOSELECT:
case 0: switch(address & 0xFF)
// manufacturer ID {
return flashManufacturerID; case 0:
case 1: // manufacturer ID
// device ID return flashManufacturerID;
return flashDeviceID; case 1:
} // device ID
break; return flashDeviceID;
case FLASH_ERASE_COMPLETE: }
flashState = FLASH_READ_ARRAY; break;
flashReadState = FLASH_READ_ARRAY; case FLASH_ERASE_COMPLETE:
return 0xFF; flashState = FLASH_READ_ARRAY;
}; flashReadState = FLASH_READ_ARRAY;
return 0xFF;
};
return 0; return 0;
} }
void flashSaveDecide(u32 address, u8 byte) void flashSaveDecide(u32 address, u8 byte)
{ {
// log("Deciding save type %08x\n", address); // log("Deciding save type %08x\n", address);
if(address == 0x0e005555) { if(address == 0x0e005555)
saveType = 2; {
cpuSaveGameFunc = flashWrite; saveType = 2;
} else { cpuSaveGameFunc = flashWrite;
saveType = 1; }
cpuSaveGameFunc = sramWrite; else
} {
saveType = 1;
cpuSaveGameFunc = sramWrite;
}
(*cpuSaveGameFunc)(address, byte); (*cpuSaveGameFunc)(address, byte);
} }
void flashDelayedWrite(u32 address, u8 byte)
{
saveType = 2;
cpuSaveGameFunc = flashWrite;
flashWrite(address, byte);
}
void flashWrite(u32 address, u8 byte) void flashWrite(u32 address, u8 byte)
{ {
// log("Writing %02x at %08x\n", byte, address); // log("Writing %02x at %08x\n", byte, address);
// log("Current state is %d\n", flashState); // log("Current state is %d\n", flashState);
address &= 0xFFFF; address &= 0xFFFF;
switch(flashState) { switch(flashState)
case FLASH_READ_ARRAY: {
if(address == 0x5555 && byte == 0xAA) case FLASH_READ_ARRAY:
flashState = FLASH_CMD_1; if(address == 0x5555 && byte == 0xAA)
break; flashState = FLASH_CMD_1;
case FLASH_CMD_1: break;
if(address == 0x2AAA && byte == 0x55) case FLASH_CMD_1:
flashState = FLASH_CMD_2; if(address == 0x2AAA && byte == 0x55)
else flashState = FLASH_CMD_2;
flashState = FLASH_READ_ARRAY; else
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; flashState = FLASH_READ_ARRAY;
flashReadState = FLASH_READ_ARRAY; break;
} else if(byte == 0xA0) { case FLASH_CMD_2:
flashState = FLASH_PROGRAM; if(address == 0x5555)
} else if(byte == 0xB0 && flashSize == 0x20000) { {
flashState = FLASH_SETBANK; if(byte == 0x90)
} else { {
flashState = FLASH_READ_ARRAY; flashState = FLASH_AUTOSELECT;
flashReadState = FLASH_READ_ARRAY; flashReadState = FLASH_AUTOSELECT;
} }
} else { else if(byte == 0x80)
flashState = FLASH_READ_ARRAY; {
flashReadState = FLASH_READ_ARRAY; flashState = FLASH_CMD_3;
} }
break; else if(byte == 0xF0)
case FLASH_CMD_3: {
if(address == 0x5555 && byte == 0xAA) { flashState = FLASH_READ_ARRAY;
flashState = FLASH_CMD_4; flashReadState = FLASH_READ_ARRAY;
} else { }
flashState = FLASH_READ_ARRAY; else if(byte == 0xA0)
flashReadState = FLASH_READ_ARRAY; {
} flashState = FLASH_PROGRAM;
break; }
case FLASH_CMD_4: else if(byte == 0xB0 && flashSize == 0x20000)
if(address == 0x2AAA && byte == 0x55) { {
flashState = FLASH_CMD_5; flashState = FLASH_SETBANK;
} else { }
flashState = FLASH_READ_ARRAY; else
flashReadState = FLASH_READ_ARRAY; {
} flashState = FLASH_READ_ARRAY;
break; flashReadState = FLASH_READ_ARRAY;
case FLASH_CMD_5: }
if(byte == 0x30) { }
// SECTOR ERASE else
memset(&flashSaveMemory[(flashBank << 16) + (address & 0xF000)], {
0, flashState = FLASH_READ_ARRAY;
0x1000); 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; 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; flashState = FLASH_READ_ARRAY;
flashReadState = FLASH_READ_ARRAY; flashReadState = FLASH_READ_ARRAY;
} break;
break; case FLASH_SETBANK:
case FLASH_AUTOSELECT: if(address == 0)
if(byte == 0xF0) { {
flashState = FLASH_READ_ARRAY; flashBank = (byte & 1);
flashReadState = FLASH_READ_ARRAY; }
} else if(address == 0x5555 && byte == 0xAA)
flashState = FLASH_CMD_1;
else {
flashState = FLASH_READ_ARRAY; flashState = FLASH_READ_ARRAY;
flashReadState = FLASH_READ_ARRAY; flashReadState = FLASH_READ_ARRAY;
break;
} }
break;
case FLASH_PROGRAM:
flashSaveMemory[(flashBank<<16)+address] = byte;
systemSaveUpdateCounter = SYSTEM_SAVE_UPDATED;
flashState = FLASH_READ_ARRAY;
flashReadState = FLASH_READ_ARRAY;
break;
case FLASH_SETBANK:
if(address == 0) {
flashBank = (byte & 1);
}
flashState = FLASH_READ_ARRAY;
flashReadState = FLASH_READ_ARRAY;
break;
}
} }

View File

@ -20,17 +20,14 @@
#ifndef VBA_FLASH_H #ifndef VBA_FLASH_H
#define VBA_FLASH_H #define VBA_FLASH_H
extern void flashSaveGame(gzFile _gzFile); extern void flashSaveGame(gzFile gzFile);
extern void flashReadGame(gzFile _gzFile, int version); extern void flashReadGame(gzFile gzFile, int version);
extern void flashReadGameSkip(gzFile _gzFile, int version);
extern u8 flashRead(u32 address); extern u8 flashRead(u32 address);
extern void flashWrite(u32 address, u8 byte); extern void flashWrite(u32 address, u8 byte);
extern void flashDelayedWrite(u32 address, u8 byte);
extern u8 flashSaveMemory[0x20000]; extern u8 flashSaveMemory[0x20000];
extern void flashSaveDecide(u32 address, u8 byte); extern void flashSaveDecide(u32 address, u8 byte);
extern void flashReset(); extern void flashReset();
extern void flashSetSize(int size); extern void flashSetSize(int size);
extern void flashInit();
extern int flashSize; extern int flashSize;
#endif // VBA_FLASH_H #endif // VBA_FLASH_H

4361
source/vba/GBA.cpp Normal file

File diff suppressed because it is too large Load Diff

View File

@ -1,7 +1,7 @@
// -*- C++ -*- // -*- C++ -*-
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator. // VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
// Copyright (C) 1999-2003 Forgotten // Copyright (C) 1999-2003 Forgotten
// Copyright (C) 2005 Forgotten and the VBA development team // Copyright (C) 2004 Forgotten and the VBA development team
// This program is free software; you can redistribute it and/or modify // This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by // it under the terms of the GNU General Public License as published by
@ -20,7 +20,7 @@
#ifndef VBA_GBA_H #ifndef VBA_GBA_H
#define VBA_GBA_H #define VBA_GBA_H
#include "../System.h" #include "System.h"
#define SAVE_GAME_VERSION_1 1 #define SAVE_GAME_VERSION_1 1
#define SAVE_GAME_VERSION_2 2 #define SAVE_GAME_VERSION_2 2
@ -30,44 +30,48 @@
#define SAVE_GAME_VERSION_6 6 #define SAVE_GAME_VERSION_6 6
#define SAVE_GAME_VERSION_7 7 #define SAVE_GAME_VERSION_7 7
#define SAVE_GAME_VERSION_8 8 #define SAVE_GAME_VERSION_8 8
#define SAVE_GAME_VERSION_9 9 #define SAVE_GAME_VERSION SAVE_GAME_VERSION_8
#define SAVE_GAME_VERSION_10 10
#define SAVE_GAME_VERSION SAVE_GAME_VERSION_10
typedef struct { typedef struct
u8 *address; {
u32 mask; u8 *address;
} memoryMap; u32 mask;
}
memoryMap;
typedef union { typedef union {
struct { struct
{
#ifdef WORDS_BIGENDIAN #ifdef WORDS_BIGENDIAN
u8 B3; u8 B3;
u8 B2; u8 B2;
u8 B1; u8 B1;
u8 B0; u8 B0;
#else #else
u8 B0; u8 B0;
u8 B1; u8 B1;
u8 B2; u8 B2;
u8 B3; u8 B3;
#endif #endif
} B; }
struct { B;
struct
{
#ifdef WORDS_BIGENDIAN #ifdef WORDS_BIGENDIAN
u16 W1; u16 W1;
u16 W0; u16 W0;
#else #else
u16 W0; u16 W0;
u16 W1; u16 W1;
#endif #endif
} W; }
W;
#ifdef WORDS_BIGENDIAN #ifdef WORDS_BIGENDIAN
volatile u32 I; volatile u32 I;
#else #else
u32 I; u32 I;
#endif #endif
} reg_pair; } reg_pair;
#ifndef NO_GBA_MAP #ifndef NO_GBA_MAP
extern memoryMap map[256]; extern memoryMap map[256];
@ -85,17 +89,8 @@ extern bool armState;
extern int armMode; extern int armMode;
extern void (*cpuSaveGameFunc)(u32,u8); extern void (*cpuSaveGameFunc)(u32,u8);
#ifdef BKPT_SUPPORT extern bool freezeWorkRAM[0x40000];
extern u8 freezeWorkRAM[0x40000]; extern bool freezeInternalRAM[0x8000];
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 CPUReadGSASnapshot(const char *);
extern bool CPUWriteGSASnapshot(const char *, const char *, const char *, const char *); extern bool CPUWriteGSASnapshot(const char *, const char *, const char *, const char *);
extern bool CPUWriteBatteryFile(const char *); extern bool CPUWriteBatteryFile(const char *);
@ -106,15 +101,14 @@ extern bool CPUWritePNGFile(const char *);
extern bool CPUWriteBMPFile(const char *); extern bool CPUWriteBMPFile(const char *);
extern void CPUCleanUp(); extern void CPUCleanUp();
extern void CPUUpdateRender(); extern void CPUUpdateRender();
extern void CPUUpdateRenderBuffers(bool);
extern bool CPUReadMemState(char *, int); extern bool CPUReadMemState(char *, int);
extern bool CPUReadState(const char *); extern bool CPUReadState(const char *);
extern bool CPUWriteMemState(char *, int); extern bool CPUWriteMemState(char *, int);
extern bool CPUWriteState(const char *); extern bool CPUWriteState(const char *);
extern int CPULoadRom(const char *); extern int CPULoadRom(const char *);
extern void doMirroring(bool);
extern void CPUUpdateRegister(u32, u16); extern void CPUUpdateRegister(u32, u16);
extern void applyTimer (); extern void CPUWriteHalfWord(u32, u16);
extern void CPUWriteByte(u32, u8);
extern void CPUInit(const char *,bool); extern void CPUInit(const char *,bool);
extern void CPUReset(); extern void CPUReset();
extern void CPULoop(int); extern void CPULoop(int);
@ -122,8 +116,7 @@ extern void CPUCheckDMA(int,int);
extern bool CPUIsGBAImage(const char *); extern bool CPUIsGBAImage(const char *);
extern bool CPUIsZipFile(const char *); extern bool CPUIsZipFile(const char *);
#ifdef PROFILING #ifdef PROFILING
#include "prof/prof.h" extern void cpuProfil(char *buffer, int, u32, int);
extern void cpuProfil(profile_segment *seg);
extern void cpuEnableProfiling(int hz); extern void cpuEnableProfiling(int hz);
#endif #endif
@ -152,9 +145,9 @@ extern struct EmulatedSystem GBASystem;
#define R14_FIQ 43 #define R14_FIQ 43
#define SPSR_FIQ 44 #define SPSR_FIQ 44
#include "../Cheats.h" #include "Cheats.h"
#include "../Globals.h" #include "Globals.h"
#include "../EEprom.h" #include "EEprom.h"
#include "../Flash.h" #include "Flash.h"
#endif //VBA_GBA_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

@ -16,11 +16,12 @@
// along with this program; if not, write to the Free Software Foundation, // along with this program; if not, write to the Free Software Foundation,
// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "../System.h" #include "System.h"
int coeff[32] = { int coeff[32] = {
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16}; 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16};
u32 line0[240]; u32 line0[240];
u32 line1[240]; u32 line1[240];
@ -31,7 +32,6 @@ u32 lineOBJWin[240];
u32 lineMix[240]; u32 lineMix[240];
bool gfxInWin0[240]; bool gfxInWin0[240];
bool gfxInWin1[240]; bool gfxInWin1[240];
int lineOBJpixleft[128];
int gfxBG2Changed = 0; int gfxBG2Changed = 0;
int gfxBG3Changed = 0; int gfxBG3Changed = 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. // VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
// Copyright (C) 1999-2003 Forgotten // Copyright (C) 1999-2003 Forgotten
// Copyright (C) 2005 Forgotten and the VBA development team // Copyright (C) 2004 Forgotten and the VBA development team
// This program is free software; you can redistribute it and/or modify // This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by // it under the terms of the GNU General Public License as published by
@ -16,12 +16,7 @@
// along with this program; if not, write to the Free Software Foundation, // along with this program; if not, write to the Free Software Foundation,
// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "agb/GBA.h" #include "GBA.h"
#ifdef BKPT_SUPPORT
int oldreg[17];
char oldbuffer[10];
#endif
reg_pair reg[45]; reg_pair reg[45];
memoryMap map[256]; memoryMap map[256];
@ -43,14 +38,13 @@ bool speedup = false;
bool synchronize = true; bool synchronize = true;
bool cpuDisableSfx = false; bool cpuDisableSfx = false;
bool cpuIsMultiBoot = false; bool cpuIsMultiBoot = false;
bool parseDebug = true; bool parseDebug = false;
int layerSettings = 0xff00; int layerSettings = 0xff00;
int layerEnable = 0xff00; int layerEnable = 0xff00;
bool speedHack = false; bool speedHack = false;
int cpuSaveType = 0; int cpuSaveType = 0;
bool cheatsEnabled = true; bool cpuEnhancedDetection = true;
bool mirroringEnable = false; bool cheatsEnabled = false;
bool skipSaveGameBattery = false;
u8 *bios = NULL; u8 *bios = NULL;
u8 *rom = NULL; u8 *rom = NULL;

View File

@ -1,7 +1,7 @@
// -*- C++ -*- // -*- C++ -*-
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator. // VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
// Copyright (C) 1999-2003 Forgotten // Copyright (C) 1999-2003 Forgotten
// Copyright (C) 2005 Forgotten and the VBA development team // Copyright (C) 2004 Forgotten and the VBA development team
// This program is free software; you can redistribute it and/or modify // This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by // it under the terms of the GNU General Public License as published by
@ -20,8 +20,6 @@
#ifndef VBA_GLOBALS_H #ifndef VBA_GLOBALS_H
#define VBA_GLOBALS_H #define VBA_GLOBALS_H
#include "agb/GBA.h"
#define VERBOSE_SWI 1 #define VERBOSE_SWI 1
#define VERBOSE_UNALIGNED_MEMORY 2 #define VERBOSE_UNALIGNED_MEMORY 2
#define VERBOSE_ILLEGAL_WRITE 4 #define VERBOSE_ILLEGAL_WRITE 4
@ -32,7 +30,6 @@
#define VERBOSE_DMA3 128 #define VERBOSE_DMA3 128
#define VERBOSE_UNDEFINED 256 #define VERBOSE_UNDEFINED 256
#define VERBOSE_AGBPRINT 512 #define VERBOSE_AGBPRINT 512
#define VERBOSE_SOUNDOUTPUT 1024
extern reg_pair reg[45]; extern reg_pair reg[45];
extern bool ioReadable[0x400]; extern bool ioReadable[0x400];
@ -58,9 +55,8 @@ extern int layerSettings;
extern int layerEnable; extern int layerEnable;
extern bool speedHack; extern bool speedHack;
extern int cpuSaveType; extern int cpuSaveType;
extern bool cpuEnhancedDetection;
extern bool cheatsEnabled; extern bool cheatsEnabled;
extern bool mirroringEnable;
extern bool skipSaveGameBattery;
extern u8 *bios; extern u8 *bios;
extern u8 *rom; extern u8 *rom;

File diff suppressed because it is too large Load Diff

View File

@ -16,107 +16,123 @@
// along with this program; if not, write to the Free Software Foundation, // along with this program; if not, write to the Free Software Foundation,
// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "agb/GBA.h" #include "GBA.h"
#include "Globals.h" #include "Globals.h"
#include "agb/GBAGfx.h" #include "Gfx.h"
void mode1RenderLine() void mode1RenderLine()
{ {
u16 *palette = (u16 *)paletteRAM; u16 *palette = (u16 *)paletteRAM;
if(DISPCNT & 0x80) { if(DISPCNT & 0x80)
for(int x = 0; x < 240; x++) { {
lineMix[x] = 0x7fff; for(int x = 0; x < 240; x++)
{
lineMix[x] = 0x7fff;
}
gfxLastVCOUNT = VCOUNT;
return;
} }
gfxLastVCOUNT = VCOUNT;
return;
}
if(layerEnable & 0x0100) { if(layerEnable & 0x0100)
gfxDrawTextScreen(BG0CNT, BG0HOFS, BG0VOFS, line0); {
} gfxDrawTextScreen(BG0CNT, BG0HOFS, BG0VOFS, line0);
}
if(layerEnable & 0x0200) { if(layerEnable & 0x0200)
gfxDrawTextScreen(BG1CNT, BG1HOFS, BG1VOFS, line1); {
} gfxDrawTextScreen(BG1CNT, BG1HOFS, BG1VOFS, line1);
}
if(layerEnable & 0x0400) { if(layerEnable & 0x0400)
int changed = gfxBG2Changed; {
if(gfxLastVCOUNT > VCOUNT) int changed = gfxBG2Changed;
changed = 3; if(gfxLastVCOUNT > VCOUNT)
gfxDrawRotScreen(BG2CNT, BG2X_L, BG2X_H, BG2Y_L, BG2Y_H, changed = 3;
BG2PA, BG2PB, BG2PC, BG2PD, gfxDrawRotScreen(BG2CNT, BG2X_L, BG2X_H, BG2Y_L, BG2Y_H,
gfxBG2X, gfxBG2Y, changed, line2); BG2PA, BG2PB, BG2PC, BG2PD,
} gfxBG2X, gfxBG2Y, changed, line2);
}
gfxDrawSprites(lineOBJ); gfxDrawSprites(lineOBJ);
u32 backdrop = (READ16LE(&palette[0]) | 0x30000000); u32 backdrop = (READ16LE(&palette[0]) | 0x30000000);
for(int x = 0; x < 240; x++) { for(int x = 0; x < 240; x++)
u32 color = backdrop; {
u8 top = 0x20; u32 color = backdrop;
u8 top = 0x20;
if(line0[x] < color) { if(line0[x] < color)
color = line0[x]; {
top = 0x01; color = line0[x];
} top = 0x01;
if((u8)(line1[x]>>24) < (u8)(color >> 24)) {
color = line1[x];
top = 0x02;
}
if((u8)(line2[x]>>24) < (u8)(color >> 24)) {
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((u8)(line0[x]>>24) < (u8)(back >> 24)) {
back = line0[x];
top2 = 0x01;
}
if((u8)(line1[x]>>24) < (u8)(back >> 24)) {
back = line1[x];
top2 = 0x02;
}
if((u8)(line2[x]>>24) < (u8)(back >> 24)) {
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; if((u8)(line1[x]>>24) < (u8)(color >> 24))
} {
color = line1[x];
top = 0x02;
}
if((u8)(line2[x]>>24) < (u8)(color >> 24))
{
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((u8)(line0[x]>>24) < (u8)(back >> 24))
{
back = line0[x];
top2 = 0x01;
}
if((u8)(line1[x]>>24) < (u8)(back >> 24))
{
back = line1[x];
top2 = 0x02;
}
if((u8)(line2[x]>>24) < (u8)(back >> 24))
{
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; gfxBG2Changed = 0;
gfxLastVCOUNT = VCOUNT; gfxLastVCOUNT = VCOUNT;
} }
@ -125,153 +141,181 @@ void mode1RenderLineNoWindow()
{ {
u16 *palette = (u16 *)paletteRAM; u16 *palette = (u16 *)paletteRAM;
if(DISPCNT & 0x80) { if(DISPCNT & 0x80)
for(int x = 0; x < 240; x++) { {
lineMix[x] = 0x7fff; for(int x = 0; x < 240; x++)
{
lineMix[x] = 0x7fff;
}
gfxLastVCOUNT = VCOUNT;
return;
} }
gfxLastVCOUNT = VCOUNT;
return;
}
if(layerEnable & 0x0100) { if(layerEnable & 0x0100)
gfxDrawTextScreen(BG0CNT, BG0HOFS, BG0VOFS, line0); {
} gfxDrawTextScreen(BG0CNT, BG0HOFS, BG0VOFS, line0);
}
if(layerEnable & 0x0200) { if(layerEnable & 0x0200)
gfxDrawTextScreen(BG1CNT, BG1HOFS, BG1VOFS, line1); {
} gfxDrawTextScreen(BG1CNT, BG1HOFS, BG1VOFS, line1);
}
if(layerEnable & 0x0400) { if(layerEnable & 0x0400)
int changed = gfxBG2Changed; {
if(gfxLastVCOUNT > VCOUNT) int changed = gfxBG2Changed;
changed = 3; if(gfxLastVCOUNT > VCOUNT)
gfxDrawRotScreen(BG2CNT, BG2X_L, BG2X_H, BG2Y_L, BG2Y_H, changed = 3;
BG2PA, BG2PB, BG2PC, BG2PD, gfxDrawRotScreen(BG2CNT, BG2X_L, BG2X_H, BG2Y_L, BG2Y_H,
gfxBG2X, gfxBG2Y, changed, line2); BG2PA, BG2PB, BG2PC, BG2PD,
} gfxBG2X, gfxBG2Y, changed, line2);
}
gfxDrawSprites(lineOBJ); gfxDrawSprites(lineOBJ);
u32 backdrop = (READ16LE(&palette[0]) | 0x30000000); u32 backdrop = (READ16LE(&palette[0]) | 0x30000000);
for(int x = 0; x < 240; x++) { for(int x = 0; x < 240; x++)
u32 color = backdrop; {
u8 top = 0x20; u32 color = backdrop;
u8 top = 0x20;
if(line0[x] < color) { if(line0[x] < color)
color = line0[x];
top = 0x01;
}
if((u8)(line1[x]>>24) < (u8)(color >> 24)) {
color = line1[x];
top = 0x02;
}
if((u8)(line2[x]>>24) < (u8)(color >> 24)) {
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) { color = line0[x];
u32 back = backdrop; top = 0x01;
u8 top2 = 0x20;
if((u8)(line0[x]>>24) < (u8)(back >> 24)) {
if(top != 0x01) {
back = line0[x];
top2 = 0x01;
}
}
if((u8)(line1[x]>>24) < (u8)(back >> 24)) {
if(top != 0x02) {
back = line1[x];
top2 = 0x02;
}
}
if((u8)(line2[x]>>24) < (u8)(back >> 24)) {
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((u8)(line0[x]>>24) < (u8)(back >> 24)) { if((u8)(line1[x]>>24) < (u8)(color >> 24))
back = line0[x]; {
top2 = 0x01; color = line1[x];
} top = 0x02;
if((u8)(line1[x]>>24) < (u8)(back >> 24)) {
back = line1[x];
top2 = 0x02;
}
if((u8)(line2[x]>>24) < (u8)(back >> 24)) {
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;
} }
}
if((u8)(line2[x]>>24) < (u8)(color >> 24))
{
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((u8)(line0[x]>>24) < (u8)(back >> 24))
{
if(top != 0x01)
{
back = line0[x];
top2 = 0x01;
}
}
if((u8)(line1[x]>>24) < (u8)(back >> 24))
{
if(top != 0x02)
{
back = line1[x];
top2 = 0x02;
}
}
if((u8)(line2[x]>>24) < (u8)(back >> 24))
{
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((u8)(line0[x]>>24) < (u8)(back >> 24))
{
back = line0[x];
top2 = 0x01;
}
if((u8)(line1[x]>>24) < (u8)(back >> 24))
{
back = line1[x];
top2 = 0x02;
}
if((u8)(line2[x]>>24) < (u8)(back >> 24))
{
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;
} }
lineMix[x] = color;
}
gfxBG2Changed = 0; gfxBG2Changed = 0;
gfxLastVCOUNT = VCOUNT; gfxLastVCOUNT = VCOUNT;
} }
@ -280,52 +324,59 @@ void mode1RenderLineAll()
{ {
u16 *palette = (u16 *)paletteRAM; u16 *palette = (u16 *)paletteRAM;
if(DISPCNT & 0x80) { if(DISPCNT & 0x80)
for(int x = 0; x < 240; x++) { {
lineMix[x] = 0x7fff; for(int x = 0; x < 240; x++)
{
lineMix[x] = 0x7fff;
}
gfxLastVCOUNT = VCOUNT;
return;
} }
gfxLastVCOUNT = VCOUNT;
return;
}
bool inWindow0 = false; bool inWindow0 = false;
bool inWindow1 = false; bool inWindow1 = false;
if(layerEnable & 0x2000) { if(layerEnable & 0x2000)
u8 v0 = WIN0V >> 8; {
u8 v1 = WIN0V & 255; u8 v0 = WIN0V >> 8;
inWindow0 = ((v0 == v1) && (v0 >= 0xe8)); u8 v1 = WIN0V & 255;
if(v1 >= v0) inWindow0 = ((v0 == v1) && (v0 >= 0xe8));
inWindow0 |= (VCOUNT >= v0 && VCOUNT < v1); if(v1 >= v0)
else inWindow0 |= (VCOUNT >= v0 && VCOUNT < v1);
inWindow0 |= (VCOUNT >= v0 || VCOUNT < v1); else
} inWindow0 |= (VCOUNT >= v0 || VCOUNT < v1);
if(layerEnable & 0x4000) { }
u8 v0 = WIN1V >> 8; if(layerEnable & 0x4000)
u8 v1 = WIN1V & 255; {
inWindow1 = ((v0 == v1) && (v0 >= 0xe8)); u8 v0 = WIN1V >> 8;
if(v1 >= v0) u8 v1 = WIN1V & 255;
inWindow1 |= (VCOUNT >= v0 && VCOUNT < v1); inWindow1 = ((v0 == v1) && (v0 >= 0xe8));
else if(v1 >= v0)
inWindow1 |= (VCOUNT >= v0 || VCOUNT < v1); inWindow1 |= (VCOUNT >= v0 && VCOUNT < v1);
} else
inWindow1 |= (VCOUNT >= v0 || VCOUNT < v1);
}
if(layerEnable & 0x0100) { if(layerEnable & 0x0100)
gfxDrawTextScreen(BG0CNT, BG0HOFS, BG0VOFS, line0); {
} gfxDrawTextScreen(BG0CNT, BG0HOFS, BG0VOFS, line0);
}
if(layerEnable & 0x0200) { if(layerEnable & 0x0200)
gfxDrawTextScreen(BG1CNT, BG1HOFS, BG1VOFS, line1); {
} gfxDrawTextScreen(BG1CNT, BG1HOFS, BG1VOFS, line1);
}
if(layerEnable & 0x0400) { if(layerEnable & 0x0400)
int changed = gfxBG2Changed; {
if(gfxLastVCOUNT > VCOUNT) int changed = gfxBG2Changed;
changed = 3; if(gfxLastVCOUNT > VCOUNT)
gfxDrawRotScreen(BG2CNT, BG2X_L, BG2X_H, BG2Y_L, BG2Y_H, changed = 3;
BG2PA, BG2PB, BG2PC, BG2PD, gfxDrawRotScreen(BG2CNT, BG2X_L, BG2X_H, BG2Y_L, BG2Y_H,
gfxBG2X, gfxBG2Y, changed, line2); BG2PA, BG2PB, BG2PC, BG2PD,
} gfxBG2X, gfxBG2Y, changed, line2);
}
gfxDrawSprites(lineOBJ); gfxDrawSprites(lineOBJ);
gfxDrawOBJWin(lineOBJWin); gfxDrawOBJWin(lineOBJWin);
@ -336,141 +387,213 @@ void mode1RenderLineAll()
u8 inWin1Mask = WININ >> 8; u8 inWin1Mask = WININ >> 8;
u8 outMask = WINOUT & 0xFF; u8 outMask = WINOUT & 0xFF;
for(int x = 0; x < 240; x++) { for(int x = 0; x < 240; x++)
u32 color = backdrop; {
u8 top = 0x20; u32 color = backdrop;
u8 mask = outMask; u8 top = 0x20;
u8 mask = outMask;
if(!(lineOBJWin[x] & 0x80000000)) { if(!(lineOBJWin[x] & 0x80000000))
mask = WINOUT >> 8;
}
if(inWindow1) {
if(gfxInWin1[x])
mask = inWin1Mask;
}
if(inWindow0) {
if(gfxInWin0[x]) {
mask = inWin0Mask;
}
}
if(line0[x] < color && (mask & 1)) {
color = line0[x];
top = 0x01;
}
if((u8)(line1[x]>>24) < (u8)(color >> 24) && (mask & 2)) {
color = line1[x];
top = 0x02;
}
if((u8)(line2[x]>>24) < (u8)(color >> 24) && (mask & 4)) {
color = line2[x];
top = 0x04;
}
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 & 1) && (u8)(line0[x]>>24) < (u8)(back >> 24)) {
back = line0[x];
top2 = 0x01;
}
if((mask & 2) && (u8)(line1[x]>>24) < (u8)(back >> 24)) {
back = line1[x];
top2 = 0x02;
}
if((mask & 4) && (u8)(line2[x]>>24) < (u8)(back >> 24)) {
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) {
// special FX on the window
switch((BLDMOD >> 6) & 3) {
case 0:
break;
case 1:
{ {
if(top & BLDMOD) { mask = WINOUT >> 8;
u32 back = backdrop;
u8 top2 = 0x20;
if((mask & 1) && (u8)(line0[x]>>24) < (u8)(back >> 24)) {
if(top != 0x01) {
back = line0[x];
top2 = 0x01;
}
}
if((mask & 2) && (u8)(line1[x]>>24) < (u8)(back >> 24)) {
if(top != 0x02) {
back = line1[x];
top2 = 0x02;
}
}
if((mask & 4) && (u8)(line2[x]>>24) < (u8)(back >> 24)) {
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; if(inWindow1)
} {
if(gfxInWin1[x])
mask = inWin1Mask;
}
if(inWindow0)
{
if(gfxInWin0[x])
{
mask = inWin0Mask;
}
}
if(line0[x] < color && (mask & 1))
{
color = line0[x];
top = 0x01;
}
if((u8)(line1[x]>>24) < (u8)(color >> 24) && (mask & 2))
{
color = line1[x];
top = 0x02;
}
if((u8)(line2[x]>>24) < (u8)(color >> 24) && (mask & 4))
{
color = line2[x];
top = 0x04;
}
if((u8)(lineOBJ[x]>>24) < (u8)(color >> 24) && (mask & 16))
{
color = lineOBJ[x];
top = 0x10;
}
// special FX on the window
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 & 1) && (u8)(line0[x]>>24) < (u8)(back >> 24))
{
if(top != 0x01)
{
back = line0[x];
top2 = 0x01;
}
}
if((mask & 2) && (u8)(line1[x]>>24) < (u8)(back >> 24))
{
if(top != 0x02)
{
back = line1[x];
top2 = 0x02;
}
}
if((mask & 4) && (u8)(line2[x]>>24) < (u8)(back >> 24))
{
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 & 1) && (u8)(line0[x]>>24) < (u8)(back >> 24))
{
back = line0[x];
top2 = 0x01;
}
if((mask & 2) && (u8)(line1[x]>>24) < (u8)(back >> 24))
{
back = line1[x];
top2 = 0x02;
}
if((mask & 4) && (u8)(line2[x]>>24) < (u8)(back >> 24))
{
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 & 1) && (u8)(line0[x]>>24) < (u8)(back >> 24))
{
back = line0[x];
top2 = 0x01;
}
if((mask & 2) && (u8)(line1[x]>>24) < (u8)(back >> 24))
{
back = line1[x];
top2 = 0x02;
}
if((mask & 4) && (u8)(line2[x]>>24) < (u8)(back >> 24))
{
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; gfxBG2Changed = 0;
gfxLastVCOUNT = VCOUNT; gfxLastVCOUNT = VCOUNT;
} }

View File

@ -16,101 +16,114 @@
// along with this program; if not, write to the Free Software Foundation, // along with this program; if not, write to the Free Software Foundation,
// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "agb/GBA.h" #include "GBA.h"
#include "Globals.h" #include "Globals.h"
#include "agb/GBAGfx.h" #include "Gfx.h"
void mode2RenderLine() void mode2RenderLine()
{ {
u16 *palette = (u16 *)paletteRAM; u16 *palette = (u16 *)paletteRAM;
if(DISPCNT & 0x80) { if(DISPCNT & 0x80)
for(int x = 0; x < 240; x++) { {
lineMix[x] = 0x7fff; for(int x = 0; x < 240; x++)
{
lineMix[x] = 0x7fff;
}
gfxLastVCOUNT = VCOUNT;
return;
} }
gfxLastVCOUNT = VCOUNT;
return;
}
if(layerEnable & 0x0400) { if(layerEnable & 0x0400)
int changed = gfxBG2Changed; {
if(gfxLastVCOUNT > VCOUNT) int changed = gfxBG2Changed;
changed = 3; if(gfxLastVCOUNT > VCOUNT)
changed = 3;
gfxDrawRotScreen(BG2CNT, BG2X_L, BG2X_H, BG2Y_L, BG2Y_H, gfxDrawRotScreen(BG2CNT, BG2X_L, BG2X_H, BG2Y_L, BG2Y_H,
BG2PA, BG2PB, BG2PC, BG2PD, gfxBG2X, gfxBG2Y, BG2PA, BG2PB, BG2PC, BG2PD, gfxBG2X, gfxBG2Y,
changed, line2); changed, line2);
} }
if(layerEnable & 0x0800) { if(layerEnable & 0x0800)
int changed = gfxBG3Changed; {
if(gfxLastVCOUNT > VCOUNT) int changed = gfxBG3Changed;
changed = 3; if(gfxLastVCOUNT > VCOUNT)
changed = 3;
gfxDrawRotScreen(BG3CNT, BG3X_L, BG3X_H, BG3Y_L, BG3Y_H, gfxDrawRotScreen(BG3CNT, BG3X_L, BG3X_H, BG3Y_L, BG3Y_H,
BG3PA, BG3PB, BG3PC, BG3PD, gfxBG3X, gfxBG3Y, BG3PA, BG3PB, BG3PC, BG3PD, gfxBG3X, gfxBG3Y,
changed, line3); changed, line3);
} }
gfxDrawSprites(lineOBJ); gfxDrawSprites(lineOBJ);
u32 backdrop = (READ16LE(&palette[0]) | 0x30000000); u32 backdrop = (READ16LE(&palette[0]) | 0x30000000);
for(int x = 0; x < 240; x++) { for(int x = 0; x < 240; x++)
u32 color = backdrop; {
u8 top = 0x20; u32 color = backdrop;
u8 top = 0x20;
if((u8)(line2[x]>>24) < (u8)(color >> 24)) { if((u8)(line2[x]>>24) < (u8)(color >> 24))
color = line2[x]; {
top = 0x04; 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; 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; gfxBG2Changed = 0;
gfxBG3Changed = 0; gfxBG3Changed = 0;
gfxLastVCOUNT = VCOUNT; gfxLastVCOUNT = VCOUNT;
@ -120,140 +133,163 @@ void mode2RenderLineNoWindow()
{ {
u16 *palette = (u16 *)paletteRAM; u16 *palette = (u16 *)paletteRAM;
if(DISPCNT & 0x80) { if(DISPCNT & 0x80)
for(int x = 0; x < 240; x++) { {
lineMix[x] = 0x7fff; for(int x = 0; x < 240; x++)
{
lineMix[x] = 0x7fff;
}
gfxLastVCOUNT = VCOUNT;
return;
} }
gfxLastVCOUNT = VCOUNT;
return;
}
if(layerEnable & 0x0400) { if(layerEnable & 0x0400)
int changed = gfxBG2Changed; {
if(gfxLastVCOUNT > VCOUNT) int changed = gfxBG2Changed;
changed = 3; if(gfxLastVCOUNT > VCOUNT)
changed = 3;
gfxDrawRotScreen(BG2CNT, BG2X_L, BG2X_H, BG2Y_L, BG2Y_H, gfxDrawRotScreen(BG2CNT, BG2X_L, BG2X_H, BG2Y_L, BG2Y_H,
BG2PA, BG2PB, BG2PC, BG2PD, gfxBG2X, gfxBG2Y, BG2PA, BG2PB, BG2PC, BG2PD, gfxBG2X, gfxBG2Y,
changed, line2); changed, line2);
} }
if(layerEnable & 0x0800) { if(layerEnable & 0x0800)
int changed = gfxBG3Changed; {
if(gfxLastVCOUNT > VCOUNT) int changed = gfxBG3Changed;
changed = 3; if(gfxLastVCOUNT > VCOUNT)
changed = 3;
gfxDrawRotScreen(BG3CNT, BG3X_L, BG3X_H, BG3Y_L, BG3Y_H, gfxDrawRotScreen(BG3CNT, BG3X_L, BG3X_H, BG3Y_L, BG3Y_H,
BG3PA, BG3PB, BG3PC, BG3PD, gfxBG3X, gfxBG3Y, BG3PA, BG3PB, BG3PC, BG3PD, gfxBG3X, gfxBG3Y,
changed, line3); changed, line3);
} }
gfxDrawSprites(lineOBJ); gfxDrawSprites(lineOBJ);
u32 backdrop = (READ16LE(&palette[0]) | 0x30000000); u32 backdrop = (READ16LE(&palette[0]) | 0x30000000);
for(int x = 0; x < 240; x++) { for(int x = 0; x < 240; x++)
u32 color = backdrop; {
u8 top = 0x20; u32 color = backdrop;
u8 top = 0x20;
if((u8)(line2[x]>>24) < (u8)(color >> 24)) { 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) { color = line2[x];
u32 back = backdrop; top = 0x04;
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)) { if((u8)(line3[x]>>24) < (u8)(color >> 24))
back = line2[x]; {
top2 = 0x04; color = line3[x];
} top = 0x08;
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;
} }
}
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;
} }
lineMix[x] = color;
}
gfxBG2Changed = 0; gfxBG2Changed = 0;
gfxBG3Changed = 0; gfxBG3Changed = 0;
gfxLastVCOUNT = VCOUNT; gfxLastVCOUNT = VCOUNT;
@ -263,55 +299,61 @@ void mode2RenderLineAll()
{ {
u16 *palette = (u16 *)paletteRAM; u16 *palette = (u16 *)paletteRAM;
if(DISPCNT & 0x80) { if(DISPCNT & 0x80)
for(int x = 0; x < 240; x++) { {
lineMix[x] = 0x7fff; for(int x = 0; x < 240; x++)
{
lineMix[x] = 0x7fff;
}
gfxLastVCOUNT = VCOUNT;
return;
} }
gfxLastVCOUNT = VCOUNT;
return;
}
bool inWindow0 = false; bool inWindow0 = false;
bool inWindow1 = false; bool inWindow1 = false;
if(layerEnable & 0x2000) { if(layerEnable & 0x2000)
u8 v0 = WIN0V >> 8; {
u8 v1 = WIN0V & 255; u8 v0 = WIN0V >> 8;
inWindow0 = ((v0 == v1) && (v0 >= 0xe8)); u8 v1 = WIN0V & 255;
if(v1 >= v0) inWindow0 = ((v0 == v1) && (v0 >= 0xe8));
inWindow0 |= (VCOUNT >= v0 && VCOUNT < v1); if(v1 >= v0)
else inWindow0 |= (VCOUNT >= v0 && VCOUNT < v1);
inWindow0 |= (VCOUNT >= v0 || VCOUNT < v1); else
} inWindow0 |= (VCOUNT >= v0 || VCOUNT < v1);
if(layerEnable & 0x4000) { }
u8 v0 = WIN1V >> 8; if(layerEnable & 0x4000)
u8 v1 = WIN1V & 255; {
inWindow1 = ((v0 == v1) && (v0 >= 0xe8)); u8 v0 = WIN1V >> 8;
if(v1 >= v0) u8 v1 = WIN1V & 255;
inWindow1 |= (VCOUNT >= v0 && VCOUNT < v1); inWindow1 = ((v0 == v1) && (v0 >= 0xe8));
else if(v1 >= v0)
inWindow1 |= (VCOUNT >= v0 || VCOUNT < v1); inWindow1 |= (VCOUNT >= v0 && VCOUNT < v1);
} else
inWindow1 |= (VCOUNT >= v0 || VCOUNT < v1);
}
if(layerEnable & 0x0400) { if(layerEnable & 0x0400)
int changed = gfxBG2Changed; {
if(gfxLastVCOUNT > VCOUNT) int changed = gfxBG2Changed;
changed = 3; if(gfxLastVCOUNT > VCOUNT)
changed = 3;
gfxDrawRotScreen(BG2CNT, BG2X_L, BG2X_H, BG2Y_L, BG2Y_H, gfxDrawRotScreen(BG2CNT, BG2X_L, BG2X_H, BG2Y_L, BG2Y_H,
BG2PA, BG2PB, BG2PC, BG2PD, gfxBG2X, gfxBG2Y, BG2PA, BG2PB, BG2PC, BG2PD, gfxBG2X, gfxBG2Y,
changed, line2); changed, line2);
} }
if(layerEnable & 0x0800) { if(layerEnable & 0x0800)
int changed = gfxBG3Changed; {
if(gfxLastVCOUNT > VCOUNT) int changed = gfxBG3Changed;
changed = 3; if(gfxLastVCOUNT > VCOUNT)
changed = 3;
gfxDrawRotScreen(BG3CNT, BG3X_L, BG3X_H, BG3Y_L, BG3Y_H, gfxDrawRotScreen(BG3CNT, BG3X_L, BG3X_H, BG3Y_L, BG3Y_H,
BG3PA, BG3PB, BG3PC, BG3PD, gfxBG3X, gfxBG3Y, BG3PA, BG3PB, BG3PC, BG3PD, gfxBG3X, gfxBG3Y,
changed, line3); changed, line3);
} }
gfxDrawSprites(lineOBJ); gfxDrawSprites(lineOBJ);
gfxDrawOBJWin(lineOBJWin); gfxDrawOBJWin(lineOBJWin);
@ -322,124 +364,186 @@ void mode2RenderLineAll()
u8 inWin1Mask = WININ >> 8; u8 inWin1Mask = WININ >> 8;
u8 outMask = WINOUT & 0xFF; u8 outMask = WINOUT & 0xFF;
for(int x = 0; x < 240; x++) { for(int x = 0; x < 240; x++)
u32 color = backdrop; {
u8 top = 0x20; u32 color = backdrop;
u8 mask = outMask; u8 top = 0x20;
u8 mask = outMask;
if(!(lineOBJWin[x] & 0x80000000)) { 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) { mask = WINOUT >> 8;
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; 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; gfxBG2Changed = 0;
gfxBG3Changed = 0; gfxBG3Changed = 0;
gfxLastVCOUNT = VCOUNT; gfxLastVCOUNT = VCOUNT;

View File

@ -16,83 +16,93 @@
// along with this program; if not, write to the Free Software Foundation, // along with this program; if not, write to the Free Software Foundation,
// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "agb/GBA.h" #include "GBA.h"
#include "Globals.h" #include "Globals.h"
#include "agb/GBAGfx.h" #include "Gfx.h"
void mode3RenderLine() void mode3RenderLine()
{ {
u16 *palette = (u16 *)paletteRAM; u16 *palette = (u16 *)paletteRAM;
if(DISPCNT & 0x80) { if(DISPCNT & 0x80)
for(int x = 0; x < 240; x++) { {
lineMix[x] = 0x7fff; for(int x = 0; x < 240; x++)
{
lineMix[x] = 0x7fff;
}
gfxLastVCOUNT = VCOUNT;
return;
} }
gfxLastVCOUNT = VCOUNT;
return;
}
if(layerEnable & 0x0400) { if(layerEnable & 0x0400)
int changed = gfxBG2Changed; {
int changed = gfxBG2Changed;
if(gfxLastVCOUNT > VCOUNT) if(gfxLastVCOUNT > VCOUNT)
changed = 3; changed = 3;
gfxDrawRotScreen16Bit(BG2CNT, BG2X_L, BG2X_H, gfxDrawRotScreen16Bit(BG2CNT, BG2X_L, BG2X_H,
BG2Y_L, BG2Y_H, BG2PA, BG2PB, BG2Y_L, BG2Y_H, BG2PA, BG2PB,
BG2PC, BG2PD, BG2PC, BG2PD,
gfxBG2X, gfxBG2Y, changed, gfxBG2X, gfxBG2Y, changed,
line2); line2);
} }
gfxDrawSprites(lineOBJ); gfxDrawSprites(lineOBJ);
u32 background = (READ16LE(&palette[0]) | 0x30000000); u32 background = (READ16LE(&palette[0]) | 0x30000000);
for(int x = 0; x < 240; x++) { for(int x = 0; x < 240; x++)
u32 color = background; {
u8 top = 0x20; u32 color = background;
u8 top = 0x20;
if(line2[x] < color) { if(line2[x] < color)
color = line2[x]; {
top = 0x04; 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; 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; gfxBG2Changed = 0;
gfxLastVCOUNT = VCOUNT; gfxLastVCOUNT = VCOUNT;
} }
@ -101,116 +111,134 @@ void mode3RenderLineNoWindow()
{ {
u16 *palette = (u16 *)paletteRAM; u16 *palette = (u16 *)paletteRAM;
if(DISPCNT & 0x80) { if(DISPCNT & 0x80)
for(int x = 0; x < 240; x++) { {
lineMix[x] = 0x7fff; for(int x = 0; x < 240; x++)
{
lineMix[x] = 0x7fff;
}
gfxLastVCOUNT = VCOUNT;
return;
} }
gfxLastVCOUNT = VCOUNT;
return;
}
if(layerEnable & 0x0400) { if(layerEnable & 0x0400)
int changed = gfxBG2Changed; {
int changed = gfxBG2Changed;
if(gfxLastVCOUNT > VCOUNT) if(gfxLastVCOUNT > VCOUNT)
changed = 3; changed = 3;
gfxDrawRotScreen16Bit(BG2CNT, BG2X_L, BG2X_H, gfxDrawRotScreen16Bit(BG2CNT, BG2X_L, BG2X_H,
BG2Y_L, BG2Y_H, BG2PA, BG2PB, BG2Y_L, BG2Y_H, BG2PA, BG2PB,
BG2PC, BG2PD, BG2PC, BG2PD,
gfxBG2X, gfxBG2Y, changed, gfxBG2X, gfxBG2Y, changed,
line2); line2);
} }
gfxDrawSprites(lineOBJ); gfxDrawSprites(lineOBJ);
u32 background = (READ16LE(&palette[0]) | 0x30000000); u32 background = (READ16LE(&palette[0]) | 0x30000000);
for(int x = 0; x < 240; x++) { for(int x = 0; x < 240; x++)
u32 color = background; {
u8 top = 0x20; u32 color = background;
u8 top = 0x20;
if(line2[x] < color) { 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) { color = line2[x];
u32 back = background; top = 0x04;
u8 top2 = 0x20; }
if(line2[x] < back) { if((u8)(lineOBJ[x]>>24) < (u8)(color >>24))
if(top != 0x04) { {
back = line2[x]; color = lineOBJ[x];
top2 = 0x04; top = 0x10;
} }
if(!(color & 0x00010000))
{
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((u8)(lineOBJ[x]>>24) < (u8)(back >> 24)) { if(top2 & (BLDMOD>>8))
if(top != 0x10) { color = gfxAlphaBlend(color, back,
back = lineOBJ[x]; coeff[COLEV & 0x1F],
top2 = 0x10; 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;
}
} }
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) { lineMix[x] = color;
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; gfxBG2Changed = 0;
gfxLastVCOUNT = VCOUNT; gfxLastVCOUNT = VCOUNT;
} }
@ -219,48 +247,53 @@ void mode3RenderLineAll()
{ {
u16 *palette = (u16 *)paletteRAM; u16 *palette = (u16 *)paletteRAM;
if(DISPCNT & 0x80) { if(DISPCNT & 0x80)
for(int x = 0; x < 240; x++) { {
lineMix[x] = 0x7fff; for(int x = 0; x < 240; x++)
{
lineMix[x] = 0x7fff;
}
gfxLastVCOUNT = VCOUNT;
return;
} }
gfxLastVCOUNT = VCOUNT;
return;
}
bool inWindow0 = false; bool inWindow0 = false;
bool inWindow1 = false; bool inWindow1 = false;
if(layerEnable & 0x2000) { if(layerEnable & 0x2000)
u8 v0 = WIN0V >> 8; {
u8 v1 = WIN0V & 255; u8 v0 = WIN0V >> 8;
inWindow0 = ((v0 == v1) && (v0 >= 0xe8)); u8 v1 = WIN0V & 255;
if(v1 >= v0) inWindow0 = ((v0 == v1) && (v0 >= 0xe8));
inWindow0 |= (VCOUNT >= v0 && VCOUNT < v1); if(v1 >= v0)
else inWindow0 |= (VCOUNT >= v0 && VCOUNT < v1);
inWindow0 |= (VCOUNT >= v0 || VCOUNT < v1); else
} inWindow0 |= (VCOUNT >= v0 || VCOUNT < v1);
if(layerEnable & 0x4000) { }
u8 v0 = WIN1V >> 8; if(layerEnable & 0x4000)
u8 v1 = WIN1V & 255; {
inWindow1 = ((v0 == v1) && (v0 >= 0xe8)); u8 v0 = WIN1V >> 8;
if(v1 >= v0) u8 v1 = WIN1V & 255;
inWindow1 |= (VCOUNT >= v0 && VCOUNT < v1); inWindow1 = ((v0 == v1) && (v0 >= 0xe8));
else if(v1 >= v0)
inWindow1 |= (VCOUNT >= v0 || VCOUNT < v1); inWindow1 |= (VCOUNT >= v0 && VCOUNT < v1);
} else
inWindow1 |= (VCOUNT >= v0 || VCOUNT < v1);
}
if(layerEnable & 0x0400) { if(layerEnable & 0x0400)
int changed = gfxBG2Changed; {
int changed = gfxBG2Changed;
if(gfxLastVCOUNT > VCOUNT) if(gfxLastVCOUNT > VCOUNT)
changed = 3; changed = 3;
gfxDrawRotScreen16Bit(BG2CNT, BG2X_L, BG2X_H, gfxDrawRotScreen16Bit(BG2CNT, BG2X_L, BG2X_H,
BG2Y_L, BG2Y_H, BG2PA, BG2PB, BG2Y_L, BG2Y_H, BG2PA, BG2PB,
BG2PC, BG2PD, BG2PC, BG2PD,
gfxBG2X, gfxBG2Y, changed, gfxBG2X, gfxBG2Y, changed,
line2); line2);
} }
gfxDrawSprites(lineOBJ); gfxDrawSprites(lineOBJ);
gfxDrawOBJWin(lineOBJWin); gfxDrawOBJWin(lineOBJWin);
@ -271,107 +304,160 @@ void mode3RenderLineAll()
u32 background = (READ16LE(&palette[0]) | 0x30000000); u32 background = (READ16LE(&palette[0]) | 0x30000000);
for(int x = 0; x < 240; x++) { for(int x = 0; x < 240; x++)
u32 color = background; {
u8 top = 0x20; u32 color = background;
u8 mask = outMask; u8 top = 0x20;
u8 mask = outMask;
if(!(lineOBJWin[x] & 0x80000000)) { 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) { mask = WINOUT >> 8;
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; 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; gfxBG2Changed = 0;
gfxLastVCOUNT = VCOUNT; gfxLastVCOUNT = VCOUNT;
} }

View File

@ -16,82 +16,92 @@
// along with this program; if not, write to the Free Software Foundation, // along with this program; if not, write to the Free Software Foundation,
// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "agb/GBA.h" #include "GBA.h"
#include "agb/GBAGfx.h" #include "Gfx.h"
#include "Globals.h" #include "Globals.h"
void mode4RenderLine() void mode4RenderLine()
{ {
u16 *palette = (u16 *)paletteRAM; u16 *palette = (u16 *)paletteRAM;
if(DISPCNT & 0x0080) { if(DISPCNT & 0x0080)
for(int x = 0; x < 240; x++) { {
lineMix[x] = 0x7fff; for(int x = 0; x < 240; x++)
{
lineMix[x] = 0x7fff;
}
gfxLastVCOUNT = VCOUNT;
return;
} }
gfxLastVCOUNT = VCOUNT;
return;
}
if(layerEnable & 0x400) { if(layerEnable & 0x400)
int changed = gfxBG2Changed; {
int changed = gfxBG2Changed;
if(gfxLastVCOUNT > VCOUNT) if(gfxLastVCOUNT > VCOUNT)
changed = 3; changed = 3;
gfxDrawRotScreen256(BG2CNT, BG2X_L, BG2X_H, BG2Y_L, BG2Y_H, gfxDrawRotScreen256(BG2CNT, BG2X_L, BG2X_H, BG2Y_L, BG2Y_H,
BG2PA, BG2PB, BG2PC, BG2PD, BG2PA, BG2PB, BG2PC, BG2PD,
gfxBG2X, gfxBG2Y, changed, gfxBG2X, gfxBG2Y, changed,
line2); line2);
} }
gfxDrawSprites(lineOBJ); gfxDrawSprites(lineOBJ);
u32 backdrop = (READ16LE(&palette[0]) | 0x30000000); u32 backdrop = (READ16LE(&palette[0]) | 0x30000000);
for(int x = 0; x < 240; x++) { for(int x = 0; x < 240; x++)
u32 color = backdrop; {
u8 top = 0x20; u32 color = backdrop;
u8 top = 0x20;
if(line2[x] < color) { if(line2[x] < color)
color = line2[x]; {
top = 0x04; 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; 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; gfxBG2Changed = 0;
gfxLastVCOUNT = VCOUNT; gfxLastVCOUNT = VCOUNT;
} }
@ -100,115 +110,133 @@ void mode4RenderLineNoWindow()
{ {
u16 *palette = (u16 *)paletteRAM; u16 *palette = (u16 *)paletteRAM;
if(DISPCNT & 0x0080) { if(DISPCNT & 0x0080)
for(int x = 0; x < 240; x++) { {
lineMix[x] = 0x7fff; for(int x = 0; x < 240; x++)
{
lineMix[x] = 0x7fff;
}
gfxLastVCOUNT = VCOUNT;
return;
} }
gfxLastVCOUNT = VCOUNT;
return;
}
if(layerEnable & 0x400) { if(layerEnable & 0x400)
int changed = gfxBG2Changed; {
int changed = gfxBG2Changed;
if(gfxLastVCOUNT > VCOUNT) if(gfxLastVCOUNT > VCOUNT)
changed = 3; changed = 3;
gfxDrawRotScreen256(BG2CNT, BG2X_L, BG2X_H, BG2Y_L, BG2Y_H, gfxDrawRotScreen256(BG2CNT, BG2X_L, BG2X_H, BG2Y_L, BG2Y_H,
BG2PA, BG2PB, BG2PC, BG2PD, BG2PA, BG2PB, BG2PC, BG2PD,
gfxBG2X, gfxBG2Y, changed, gfxBG2X, gfxBG2Y, changed,
line2); line2);
} }
gfxDrawSprites(lineOBJ); gfxDrawSprites(lineOBJ);
u32 backdrop = (READ16LE(&palette[0]) | 0x30000000); u32 backdrop = (READ16LE(&palette[0]) | 0x30000000);
for(int x = 0; x < 240; x++) { for(int x = 0; x < 240; x++)
u32 color = backdrop; {
u8 top = 0x20; u32 color = backdrop;
u8 top = 0x20;
if(line2[x] < color) { 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) { color = line2[x];
u32 back = backdrop; top = 0x04;
u8 top2 = 0x20; }
if(line2[x] < back) { if((u8)(lineOBJ[x]>>24) < (u8)(color >> 24))
if(top != 0x04) { {
back = line2[x]; color = lineOBJ[x];
top2 = 0x04; top = 0x10;
} }
if(!(color & 0x00010000))
{
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((u8)(lineOBJ[x]>>24) < (u8)(back >> 24)) { if(top2 & (BLDMOD>>8))
if(top != 0x10) { color = gfxAlphaBlend(color, back,
back = lineOBJ[x]; coeff[COLEV & 0x1F],
top2 = 0x10; 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;
}
} }
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) { lineMix[x] = color;
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; gfxBG2Changed = 0;
gfxLastVCOUNT = VCOUNT; gfxLastVCOUNT = VCOUNT;
} }
@ -217,47 +245,52 @@ void mode4RenderLineAll()
{ {
u16 *palette = (u16 *)paletteRAM; u16 *palette = (u16 *)paletteRAM;
if(DISPCNT & 0x0080) { if(DISPCNT & 0x0080)
for(int x = 0; x < 240; x++) { {
lineMix[x] = 0x7fff; for(int x = 0; x < 240; x++)
{
lineMix[x] = 0x7fff;
}
gfxLastVCOUNT = VCOUNT;
return;
} }
gfxLastVCOUNT = VCOUNT;
return;
}
bool inWindow0 = false; bool inWindow0 = false;
bool inWindow1 = false; bool inWindow1 = false;
if(layerEnable & 0x2000) { if(layerEnable & 0x2000)
u8 v0 = WIN0V >> 8; {
u8 v1 = WIN0V & 255; u8 v0 = WIN0V >> 8;
inWindow0 = ((v0 == v1) && (v0 >= 0xe8)); u8 v1 = WIN0V & 255;
if(v1 >= v0) inWindow0 = ((v0 == v1) && (v0 >= 0xe8));
inWindow0 |= (VCOUNT >= v0 && VCOUNT < v1); if(v1 >= v0)
else inWindow0 |= (VCOUNT >= v0 && VCOUNT < v1);
inWindow0 |= (VCOUNT >= v0 || VCOUNT < v1); else
} inWindow0 |= (VCOUNT >= v0 || VCOUNT < v1);
if(layerEnable & 0x4000) { }
u8 v0 = WIN1V >> 8; if(layerEnable & 0x4000)
u8 v1 = WIN1V & 255; {
inWindow1 = ((v0 == v1) && (v0 >= 0xe8)); u8 v0 = WIN1V >> 8;
if(v1 >= v0) u8 v1 = WIN1V & 255;
inWindow1 |= (VCOUNT >= v0 && VCOUNT < v1); inWindow1 = ((v0 == v1) && (v0 >= 0xe8));
else if(v1 >= v0)
inWindow1 |= (VCOUNT >= v0 || VCOUNT < v1); inWindow1 |= (VCOUNT >= v0 && VCOUNT < v1);
} else
inWindow1 |= (VCOUNT >= v0 || VCOUNT < v1);
}
if(layerEnable & 0x400) { if(layerEnable & 0x400)
int changed = gfxBG2Changed; {
int changed = gfxBG2Changed;
if(gfxLastVCOUNT > VCOUNT) if(gfxLastVCOUNT > VCOUNT)
changed = 3; changed = 3;
gfxDrawRotScreen256(BG2CNT, BG2X_L, BG2X_H, BG2Y_L, BG2Y_H, gfxDrawRotScreen256(BG2CNT, BG2X_L, BG2X_H, BG2Y_L, BG2Y_H,
BG2PA, BG2PB, BG2PC, BG2PD, BG2PA, BG2PB, BG2PC, BG2PD,
gfxBG2X, gfxBG2Y, changed, gfxBG2X, gfxBG2Y, changed,
line2); line2);
} }
gfxDrawSprites(lineOBJ); gfxDrawSprites(lineOBJ);
gfxDrawOBJWin(lineOBJWin); gfxDrawOBJWin(lineOBJWin);
@ -268,107 +301,160 @@ void mode4RenderLineAll()
u8 inWin1Mask = WININ >> 8; u8 inWin1Mask = WININ >> 8;
u8 outMask = WINOUT & 0xFF; u8 outMask = WINOUT & 0xFF;
for(int x = 0; x < 240; x++) { for(int x = 0; x < 240; x++)
u32 color = backdrop; {
u8 top = 0x20; u32 color = backdrop;
u8 mask = outMask; u8 top = 0x20;
u8 mask = outMask;
if(!(lineOBJWin[x] & 0x80000000)) { 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) { mask = WINOUT >> 8;
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; 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; gfxBG2Changed = 0;
gfxLastVCOUNT = VCOUNT; gfxLastVCOUNT = VCOUNT;
} }

View File

@ -16,229 +16,260 @@
// along with this program; if not, write to the Free Software Foundation, // along with this program; if not, write to the Free Software Foundation,
// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "agb/GBA.h" #include "GBA.h"
#include "Globals.h" #include "Globals.h"
#include "agb/GBAGfx.h" #include "Gfx.h"
void mode5RenderLine() void mode5RenderLine()
{ {
if(DISPCNT & 0x0080) { if(DISPCNT & 0x0080)
for(int x = 0; x < 240; x++) { {
lineMix[x] = 0x7fff; for(int x = 0; x < 240; x++)
{
lineMix[x] = 0x7fff;
}
gfxLastVCOUNT = VCOUNT;
return;
} }
gfxLastVCOUNT = VCOUNT;
return;
}
u16 *palette = (u16 *)paletteRAM; u16 *palette = (u16 *)paletteRAM;
if(layerEnable & 0x0400) { if(layerEnable & 0x0400)
int changed = gfxBG2Changed; {
int changed = gfxBG2Changed;
if(gfxLastVCOUNT > VCOUNT) if(gfxLastVCOUNT > VCOUNT)
changed = 3; changed = 3;
gfxDrawRotScreen16Bit160(BG2CNT, BG2X_L, BG2X_H, gfxDrawRotScreen16Bit160(BG2CNT, BG2X_L, BG2X_H,
BG2Y_L, BG2Y_H, BG2PA, BG2PB, BG2Y_L, BG2Y_H, BG2PA, BG2PB,
BG2PC, BG2PD, BG2PC, BG2PD,
gfxBG2X, gfxBG2Y, changed, gfxBG2X, gfxBG2Y, changed,
line2); line2);
} }
gfxDrawSprites(lineOBJ); gfxDrawSprites(lineOBJ);
u32 background = (READ16LE(&palette[0]) | 0x30000000); u32 background = (READ16LE(&palette[0]) | 0x30000000);
for(int x = 0; x < 240; x++) { for(int x = 0; x < 240; x++)
u32 color = background; {
u8 top = 0x20; u32 color = background;
u8 top = 0x20;
if(line2[x] < color) { if(line2[x] < color)
color = line2[x]; {
top = 0x04; 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; 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; gfxBG2Changed = 0;
gfxLastVCOUNT = VCOUNT; gfxLastVCOUNT = VCOUNT;
} }
void mode5RenderLineNoWindow() void mode5RenderLineNoWindow()
{ {
if(DISPCNT & 0x0080) { if(DISPCNT & 0x0080)
for(int x = 0; x < 240; x++) { {
lineMix[x] = 0x7fff; for(int x = 0; x < 240; x++)
{
lineMix[x] = 0x7fff;
}
gfxLastVCOUNT = VCOUNT;
return;
} }
gfxLastVCOUNT = VCOUNT;
return;
}
u16 *palette = (u16 *)paletteRAM; u16 *palette = (u16 *)paletteRAM;
if(layerEnable & 0x0400) { if(layerEnable & 0x0400)
int changed = gfxBG2Changed; {
int changed = gfxBG2Changed;
if(gfxLastVCOUNT > VCOUNT) if(gfxLastVCOUNT > VCOUNT)
changed = 3; changed = 3;
gfxDrawRotScreen16Bit160(BG2CNT, BG2X_L, BG2X_H, gfxDrawRotScreen16Bit160(BG2CNT, BG2X_L, BG2X_H,
BG2Y_L, BG2Y_H, BG2PA, BG2PB, BG2Y_L, BG2Y_H, BG2PA, BG2PB,
BG2PC, BG2PD, BG2PC, BG2PD,
gfxBG2X, gfxBG2Y, changed, gfxBG2X, gfxBG2Y, changed,
line2); line2);
} }
gfxDrawSprites(lineOBJ); gfxDrawSprites(lineOBJ);
u32 background = ( READ16LE(&palette[0]) | 0x30000000); u32 background = ( READ16LE(&palette[0]) | 0x30000000);
for(int x = 0; x < 240; x++) { for(int x = 0; x < 240; x++)
u32 color = background; {
u8 top = 0x20; u32 color = background;
u8 top = 0x20;
if(line2[x] < color) { 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) { color = line2[x];
u32 back = background; top = 0x04;
u8 top2 = 0x20; }
if(line2[x] < back) { if((u8)(lineOBJ[x]>>24) < (u8)(color >>24))
if(top != 0x04) { {
back = line2[x]; color = lineOBJ[x];
top2 = 0x04; top = 0x10;
} }
if(!(color & 0x00010000))
{
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((u8)(lineOBJ[x]>>24) < (u8)(back >> 24)) { if(top2 & (BLDMOD>>8))
if(top != 0x10) { color = gfxAlphaBlend(color, back,
back = lineOBJ[x]; coeff[COLEV & 0x1F],
top2 = 0x10; 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;
}
} }
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) { lineMix[x] = color;
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; gfxBG2Changed = 0;
gfxLastVCOUNT = VCOUNT; gfxLastVCOUNT = VCOUNT;
} }
void mode5RenderLineAll() void mode5RenderLineAll()
{ {
if(DISPCNT & 0x0080) { if(DISPCNT & 0x0080)
for(int x = 0; x < 240; x++) { {
lineMix[x] = 0x7fff; for(int x = 0; x < 240; x++)
{
lineMix[x] = 0x7fff;
}
gfxLastVCOUNT = VCOUNT;
return;
} }
gfxLastVCOUNT = VCOUNT;
return;
}
u16 *palette = (u16 *)paletteRAM; u16 *palette = (u16 *)paletteRAM;
if(layerEnable & 0x0400) { if(layerEnable & 0x0400)
int changed = gfxBG2Changed; {
int changed = gfxBG2Changed;
if(gfxLastVCOUNT > VCOUNT) if(gfxLastVCOUNT > VCOUNT)
changed = 3; changed = 3;
gfxDrawRotScreen16Bit160(BG2CNT, BG2X_L, BG2X_H, gfxDrawRotScreen16Bit160(BG2CNT, BG2X_L, BG2X_H,
BG2Y_L, BG2Y_H, BG2PA, BG2PB, BG2Y_L, BG2Y_H, BG2PA, BG2PB,
BG2PC, BG2PD, BG2PC, BG2PD,
gfxBG2X, gfxBG2Y, changed, gfxBG2X, gfxBG2Y, changed,
line2); line2);
} }
gfxDrawSprites(lineOBJ); gfxDrawSprites(lineOBJ);
gfxDrawOBJWin(lineOBJWin); gfxDrawOBJWin(lineOBJWin);
@ -246,24 +277,26 @@ void mode5RenderLineAll()
bool inWindow0 = false; bool inWindow0 = false;
bool inWindow1 = false; bool inWindow1 = false;
if(layerEnable & 0x2000) { if(layerEnable & 0x2000)
u8 v0 = WIN0V >> 8; {
u8 v1 = WIN0V & 255; u8 v0 = WIN0V >> 8;
inWindow0 = ((v0 == v1) && (v0 >= 0xe8)); u8 v1 = WIN0V & 255;
if(v1 >= v0) inWindow0 = ((v0 == v1) && (v0 >= 0xe8));
inWindow0 |= (VCOUNT >= v0 && VCOUNT < v1); if(v1 >= v0)
else inWindow0 |= (VCOUNT >= v0 && VCOUNT < v1);
inWindow0 |= (VCOUNT >= v0 || VCOUNT < v1); else
} inWindow0 |= (VCOUNT >= v0 || VCOUNT < v1);
if(layerEnable & 0x4000) { }
u8 v0 = WIN1V >> 8; if(layerEnable & 0x4000)
u8 v1 = WIN1V & 255; {
inWindow1 = ((v0 == v1) && (v0 >= 0xe8)); u8 v0 = WIN1V >> 8;
if(v1 >= v0) u8 v1 = WIN1V & 255;
inWindow1 |= (VCOUNT >= v0 && VCOUNT < v1); inWindow1 = ((v0 == v1) && (v0 >= 0xe8));
else if(v1 >= v0)
inWindow1 |= (VCOUNT >= v0 || VCOUNT < v1); inWindow1 |= (VCOUNT >= v0 && VCOUNT < v1);
} else
inWindow1 |= (VCOUNT >= v0 || VCOUNT < v1);
}
u8 inWin0Mask = WININ & 0xFF; u8 inWin0Mask = WININ & 0xFF;
u8 inWin1Mask = WININ >> 8; u8 inWin1Mask = WININ >> 8;
@ -271,107 +304,160 @@ void mode5RenderLineAll()
u32 background = (READ16LE(&palette[0]) | 0x30000000); u32 background = (READ16LE(&palette[0]) | 0x30000000);
for(int x = 0; x < 240; x++) { for(int x = 0; x < 240; x++)
u32 color = background; {
u8 top = 0x20; u32 color = background;
u8 mask = outMask; u8 top = 0x20;
u8 mask = outMask;
if(!(lineOBJWin[x] & 0x80000000)) { 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) { mask = WINOUT >> 8;
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; 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; gfxBG2Changed = 0;
gfxLastVCOUNT = VCOUNT; gfxLastVCOUNT = VCOUNT;
} }

View File

@ -60,5 +60,3 @@
#define MSG_INVALID_CBA_CODE 39 #define MSG_INVALID_CBA_CODE 39
#define MSG_CBA_CODE_WARNING 40 #define MSG_CBA_CODE_WARNING 40
#define MSG_OUT_OF_MEMORY 41 #define MSG_OUT_OF_MEMORY 41
#define MSG_WRONG_GAMESHARK_CODE 42
#define MSG_UNSUPPORTED_GAMESHARK_CODE 43

View File

@ -33,6 +33,8 @@ static inline u32 swap32(u32 v)
} }
#ifdef WORDS_BIGENDIAN #ifdef WORDS_BIGENDIAN
#define __ppc__
#if defined(__GNUC__) && defined(__ppc__) #if defined(__GNUC__) && defined(__ppc__)
#define READ16LE(base) \ #define READ16LE(base) \

View File

@ -1,6 +1,6 @@
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator. // VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
// Copyright (C) 1999-2003 Forgotten // Copyright (C) 1999-2003 Forgotten
// Copyright (C) 2005 Forgotten and the VBA development team // Copyright (C) 2004 Forgotten and the VBA development team
// This program is free software; you can redistribute it and/or modify // This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by // it under the terms of the GNU General Public License as published by
@ -17,7 +17,7 @@
// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "System.h" #include "System.h"
#include "agb/GBA.h" #include "GBA.h"
#include "Globals.h" #include "Globals.h"
#include "Port.h" #include "Port.h"
#include "Util.h" #include "Util.h"
@ -29,20 +29,22 @@
enum RTCSTATE { IDLE, COMMAND, DATA, READDATA }; enum RTCSTATE { IDLE, COMMAND, DATA, READDATA };
typedef struct { typedef struct
u8 byte0; {
u8 byte1; u8 byte0;
u8 byte2; u8 byte1;
u8 command; u8 byte2;
int dataLen; u8 command;
int bits; int dataLen;
RTCSTATE state; int bits;
u8 data[12]; RTCSTATE state;
// reserved variables for future u8 data[12];
u8 reserved[12]; // reserved variables for future
bool reserved2; u8 reserved[12];
u32 reserved3; bool reserved2;
} RTCCLOCKDATA; u32 reserved3;
}
RTCCLOCKDATA;
static RTCCLOCKDATA rtcClockData; static RTCCLOCKDATA rtcClockData;
static bool rtcEnabled = false; static bool rtcEnabled = false;
@ -59,24 +61,20 @@ bool rtcIsEnabled()
u16 rtcRead(u32 address) u16 rtcRead(u32 address)
{ {
if(rtcEnabled) { if(rtcEnabled)
switch(address){ {
case 0x80000c8: if(address == 0x80000c8)
return rtcClockData.byte2; return rtcClockData.byte2;
break; else if(address == 0x80000c6)
case 0x80000c6: return rtcClockData.byte1;
return rtcClockData.byte1; else if(address == 0x80000c4)
break; {
case 0x80000c4: return rtcClockData.byte0;
return rtcClockData.byte0; }
break;
} }
}
#ifdef USE_VM //return READ16LE((&rom[address & 0x1FFFFFE]));
return VMRead16( address & 0x1FFFFFE ); return VMRead16( address & 0x1FFFFFE );
#else
return READ16LE((&rom[address & 0x1FFFFFE]));
#endif
} }
static u8 toBCD(u8 value) static u8 toBCD(u8 value)
@ -92,117 +90,134 @@ bool rtcWrite(u32 address, u16 value)
if(!rtcEnabled) if(!rtcEnabled)
return false; return false;
if(address == 0x80000c8) { if(address == 0x80000c8)
rtcClockData.byte2 = (u8)value; // enable ? {
} else if(address == 0x80000c6) { rtcClockData.byte2 = (u8)value; // enable ?
rtcClockData.byte1 = (u8)value; // read/write }
} else if(address == 0x80000c4) { else if(address == 0x80000c6)
if(rtcClockData.byte2 & 1) { {
if(rtcClockData.state == IDLE && rtcClockData.byte0 == 1 && value == 5) { rtcClockData.byte1 = (u8)value; // read/write
rtcClockData.state = COMMAND; }
rtcClockData.bits = 0; else if(address == 0x80000c4)
rtcClockData.command = 0; {
} else if(!(rtcClockData.byte0 & 1) && (value & 1)) { // bit transfer if(rtcClockData.byte2 & 1)
rtcClockData.byte0 = (u8)value; {
switch(rtcClockData.state) { if(rtcClockData.state == IDLE && rtcClockData.byte0 == 1 && value == 5)
case COMMAND: {
rtcClockData.command |= ((value & 2) >> 1) << (7-rtcClockData.bits); rtcClockData.state = COMMAND;
rtcClockData.bits++; rtcClockData.bits = 0;
if(rtcClockData.bits == 8) { rtcClockData.command = 0;
rtcClockData.bits = 0; }
switch(rtcClockData.command) { else if(!(rtcClockData.byte0 & 1) && (value & 1))
case 0x60: { // bit transfer
// not sure what this command does but it doesn't take parameters rtcClockData.byte0 = (u8)value;
// maybe it is a reset or stop switch(rtcClockData.state)
rtcClockData.state = IDLE; {
rtcClockData.bits = 0; case COMMAND:
break; rtcClockData.command |= ((value & 2) >> 1) << (7-rtcClockData.bits);
case 0x62: rtcClockData.bits++;
// this sets the control state but not sure what those values are if(rtcClockData.bits == 8)
rtcClockData.state = READDATA; {
rtcClockData.dataLen = 1; rtcClockData.bits = 0;
break; switch(rtcClockData.command)
case 0x63: {
rtcClockData.dataLen = 1; case 0x60:
rtcClockData.data[0] = 0x40; // not sure what this command does but it doesn't take parameters
rtcClockData.state = DATA; // maybe it is a reset or stop
break; rtcClockData.state = IDLE;
case 0x64: rtcClockData.bits = 0;
break; break;
case 0x65: case 0x62:
{ // this sets the control state but not sure what those values are
struct tm *newtime; rtcClockData.state = READDATA;
time_t long_time; rtcClockData.dataLen = 1;
break;
time( &long_time ); /* Get time as long integer. */ case 0x63:
newtime = localtime( &long_time ); /* Convert to local time. */ rtcClockData.dataLen = 1;
rtcClockData.data[0] = 0x40;
rtcClockData.dataLen = 7; rtcClockData.state = DATA;
rtcClockData.data[0] = toBCD(newtime->tm_year); break;
rtcClockData.data[1] = toBCD(newtime->tm_mon+1); case 0x65:
rtcClockData.data[2] = toBCD(newtime->tm_mday); {
rtcClockData.data[3] = toBCD(newtime->tm_wday); struct tm *newtime;
rtcClockData.data[4] = toBCD(newtime->tm_hour); time_t long_time;
rtcClockData.data[5] = toBCD(newtime->tm_min);
rtcClockData.data[6] = toBCD(newtime->tm_sec); time( &long_time ); /* Get time as long integer. */
rtcClockData.state = DATA; newtime = localtime( &long_time ); /* Convert to local time. */
}
break; rtcClockData.dataLen = 7;
case 0x67: rtcClockData.data[0] = toBCD(newtime->tm_year);
{ rtcClockData.data[1] = toBCD(newtime->tm_mon+1);
struct tm *newtime; rtcClockData.data[2] = toBCD(newtime->tm_mday);
time_t long_time; rtcClockData.data[3] = 0;
rtcClockData.data[4] = toBCD(newtime->tm_hour);
time( &long_time ); /* Get time as long integer. */ rtcClockData.data[5] = toBCD(newtime->tm_min);
newtime = localtime( &long_time ); /* Convert to local time. */ rtcClockData.data[6] = toBCD(newtime->tm_sec);
rtcClockData.state = DATA;
rtcClockData.dataLen = 3; }
rtcClockData.data[0] = toBCD(newtime->tm_hour); break;
rtcClockData.data[1] = toBCD(newtime->tm_min); case 0x67:
rtcClockData.data[2] = toBCD(newtime->tm_sec); {
rtcClockData.state = DATA; struct tm *newtime;
} time_t long_time;
break;
default: time( &long_time ); /* Get time as long integer. */
systemMessage(0, N_("Unknown RTC command %02x"), rtcClockData.command); newtime = localtime( &long_time ); /* Convert to local time. */
rtcClockData.state = IDLE;
break; rtcClockData.dataLen = 3;
} rtcClockData.data[0] = toBCD(newtime->tm_hour);
} rtcClockData.data[1] = toBCD(newtime->tm_min);
break; rtcClockData.data[2] = toBCD(newtime->tm_sec);
case DATA: rtcClockData.state = DATA;
if(rtcClockData.byte1 & 2) { }
} else { break;
rtcClockData.byte0 = (rtcClockData.byte0 & ~2) | default:
((rtcClockData.data[rtcClockData.bits >> 3] >> systemMessage(0, N_("Unknown RTC command %02x"), rtcClockData.command);
(rtcClockData.bits & 7)) & 1)*2; rtcClockData.state = IDLE;
rtcClockData.bits++; break;
if(rtcClockData.bits == 8*rtcClockData.dataLen) { }
rtcClockData.bits = 0; }
rtcClockData.state = IDLE; break;
} case DATA:
} if(rtcClockData.byte1 & 2)
break; {}
case READDATA: else
if(!(rtcClockData.byte1 & 2)) { {
} else { rtcClockData.byte0 = (rtcClockData.byte0 & ~2) |
rtcClockData.data[rtcClockData.bits >> 3] = ((rtcClockData.data[rtcClockData.bits >> 3] >>
(rtcClockData.data[rtcClockData.bits >> 3] >> 1) | (rtcClockData.bits & 7)) & 1)*2;
((value << 6) & 128); rtcClockData.bits++;
rtcClockData.bits++; if(rtcClockData.bits == 8*rtcClockData.dataLen)
if(rtcClockData.bits == 8*rtcClockData.dataLen) { {
rtcClockData.bits = 0; rtcClockData.bits = 0;
rtcClockData.state = IDLE; rtcClockData.state = IDLE;
} }
} }
break; break;
default: case READDATA:
break; if(!(rtcClockData.byte1 & 2))
} {}
} else else
rtcClockData.byte0 = (u8)value; {
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; return true;
} }

File diff suppressed because it is too large Load Diff

View File

@ -2,7 +2,6 @@
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator. // VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
// Copyright (C) 1999-2003 Forgotten // Copyright (C) 1999-2003 Forgotten
// Copyright (C) 2004 Forgotten and the VBA development team // Copyright (C) 2004 Forgotten and the VBA development team
// Copyright (C) 2004-2006 VBA development team
// This program is free software; you can redistribute it and/or modify // This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by // it under the terms of the GNU General Public License as published by
@ -21,8 +20,6 @@
#ifndef VBA_SOUND_H #ifndef VBA_SOUND_H
#define VBA_SOUND_H #define VBA_SOUND_H
#include "System.h"
#define NR10 0x60 #define NR10 0x60
#define NR11 0x62 #define NR11 0x62
#define NR12 0x63 #define NR12 0x63
@ -50,22 +47,23 @@
#define FIFOB_L 0xa4 #define FIFOB_L 0xa4
#define FIFOB_H 0xa6 #define FIFOB_H 0xa6
void soundTick(); extern void soundTick();
void soundShutdown(); extern void soundShutdown();
bool soundInit(); extern bool soundInit();
void soundPause(); extern void soundPause();
void soundResume(); extern void soundResume();
void soundEnable(int); extern void soundEnable(int);
void soundDisable(int); extern void soundDisable(int);
int soundGetEnable(); extern int soundGetEnable();
void soundReset(); extern void soundReset();
void soundSaveGame(gzFile); extern void soundSaveGame(gzFile);
void soundReadGame(gzFile, int); extern void soundReadGame(gzFile, int);
void soundEvent(u32, u8); extern void soundEvent(u32, u8);
void soundEvent(u32, u16); extern void soundEvent(u32, u16);
void soundTimerOverflow(int); extern void soundTimerOverflow(int);
void soundSetQuality(int); extern void soundSetQuality(int);
//extern int SOUND_TICKS;
extern int SOUND_CLOCK_TICKS; extern int SOUND_CLOCK_TICKS;
extern int soundTicks; extern int soundTicks;
extern int soundPaused; extern int soundPaused;

View File

@ -16,8 +16,7 @@
// along with this program; if not, write to the Free Software Foundation, // along with this program; if not, write to the Free Software Foundation,
// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "agb/GBA.h" #include "GBA.h"
#include "Globals.h"
#include "Flash.h" #include "Flash.h"
#include "Sram.h" #include "Sram.h"
@ -25,12 +24,6 @@ u8 sramRead(u32 address)
{ {
return flashSaveMemory[address & 0xFFFF]; return flashSaveMemory[address & 0xFFFF];
} }
void sramDelayedWrite(u32 address, u8 byte)
{
saveType = 1;
cpuSaveGameFunc = sramWrite;
sramWrite(address, byte);
}
void sramWrite(u32 address, u8 byte) void sramWrite(u32 address, u8 byte)
{ {

View File

@ -22,6 +22,5 @@
extern u8 sramRead(u32 address); extern u8 sramRead(u32 address);
extern void sramWrite(u32 address, u8 byte); extern void sramWrite(u32 address, u8 byte);
extern void sramDelayedWrite(u32 address, u8 byte);
#endif // VBA_SRAM_H #endif // VBA_SRAM_H

View File

@ -20,60 +20,63 @@
#ifndef VBA_SYSTEM_H #ifndef VBA_SYSTEM_H
#define VBA_SYSTEM_H #define VBA_SYSTEM_H
#include <stdint.h>
#include "unzip.h" #include "unzip.h"
#ifndef NULL #ifndef NULL
#define NULL 0 #define NULL 0
#endif #endif
typedef 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 char u8;
typedef unsigned short u16; typedef unsigned short u16;
typedef unsigned int u32; typedef unsigned int u32;
struct EmulatedSystem { #ifdef _MSC_VER
// main emulation function typedef unsigned __int64 u64;
void (*emuMain)(int); #else
// reset emulator typedef unsigned long long u64;
void (*emuReset)(); #endif
// clean up memory
void (*emuCleanUp)(); typedef signed char s8;
// load battery file typedef signed short s16;
bool (*emuReadBattery)(const char *); typedef signed int s32;
// write battery file
bool (*emuWriteBattery)(const char *); #ifdef _MSC_VER
// load state typedef signed __int64 s64;
bool (*emuReadState)(const char *); #else
// save state typedef signed long long s64;
bool (*emuWriteState)(const char *); #endif
// load memory state (rewind)
bool (*emuReadMemState)(char *, int); struct EmulatedSystem
// write memory state (rewind) {
bool (*emuWriteMemState)(char *, int); // main emulation function
// write PNG file void (*emuMain)(int);
bool (*emuWritePNG)(const char *); // reset emulator
// write BMP file void (*emuReset)();
bool (*emuWriteBMP)(const char *); // clean up memory
// emulator update CPSR (ARM only) void (*emuCleanUp)();
void (*emuUpdateCPSR)(); // load battery file
// emulator has debugger bool (*emuReadBattery)(const char *);
bool emuHasDebugger; // write battery file
// clock ticks to emulate bool (*emuWriteBattery)(const char *);
int emuCount; // 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 void log(const char *,...);
@ -104,16 +107,7 @@ extern void system10Frames(int);
extern void systemFrame(); extern void systemFrame();
extern void systemGbBorderOn(); extern void systemGbBorderOn();
extern void Sm60FPS_Init(); extern bool systemSoundOn;
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 u16 systemColorMap16[0x10000];
//extern u32 systemColorMap32[0x10000]; //extern u32 systemColorMap32[0x10000];
extern u32 *systemColorMap32; extern u32 *systemColorMap32;
@ -126,8 +120,6 @@ extern int systemDebug;
extern int systemVerbose; extern int systemVerbose;
extern int systemFrameSkip; extern int systemFrameSkip;
extern int systemSaveUpdateCounter; extern int systemSaveUpdateCounter;
extern int systemSpeed;
extern int systemThrottle;
#define SYSTEM_SAVE_UPDATED 30 #define SYSTEM_SAVE_UPDATED 30
#define SYSTEM_SAVE_NOT_UPDATED 0 #define SYSTEM_SAVE_NOT_UPDATED 0

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 #ifndef VBA_UTIL_H
#define VBA_UTIL_H #define VBA_UTIL_H
#include "System.h"
enum IMAGE_TYPE { enum IMAGE_TYPE {
IMAGE_UNKNOWN = -1, IMAGE_UNKNOWN = -1,
IMAGE_GBA = 0, IMAGE_GBA = 0,
@ -30,40 +27,40 @@ enum IMAGE_TYPE {
// save game // save game
typedef struct { typedef struct
void *address; {
int size; void *address;
} variable_desc; int size;
}
variable_desc;
extern int utilGetSize(int size);
extern bool utilWritePNGFile(const char *, int, int, u8 *); extern bool utilWritePNGFile(const char *, int, int, u8 *);
extern bool utilWriteBMPFile(const char *, int, int, u8 *); extern bool utilWriteBMPFile(const char *, int, int, u8 *);
extern void utilApplyIPS(const char *ips, u8 **rom, int *size); extern void utilApplyIPS(const char *ips, u8 **rom, int *size);
extern void utilWriteBMP(char *, int, int, u8 *);
extern bool utilIsGBAImage(const char *); extern bool utilIsGBAImage(const char *);
extern bool utilIsGBImage(const char *); extern bool utilIsGBImage(const char *);
extern bool utilIsGzipFile(const char *);
extern bool utilIsZipFile(const char *); extern bool utilIsZipFile(const char *);
extern void utilStripDoubleExtension(const char *, char *); extern bool utilIsGzipFile(const char *);
extern bool utilIsRarFile(const char *);
extern void utilGetBaseName(const char *, char *);
extern IMAGE_TYPE utilFindType(const char *); extern IMAGE_TYPE utilFindType(const char *);
extern u8 *utilLoad(const char *, extern u8 *utilLoad(const char *,
bool (*)(const char*), bool (*)(const char*),
u8 *, u8 *,
int &); int &);
extern void utilPutDword(u8 *, u32); extern void utilPutDword(u8 *, u32);
extern void utilPutWord(u8 *, u16); extern void utilPutWord(u8 *, u16);
extern void utilWriteData(gzFile, variable_desc *); extern void utilWriteData(gzFile, variable_desc *);
extern void utilReadData(gzFile, variable_desc *); extern void utilReadData(gzFile, variable_desc *);
extern void utilReadDataSkip(gzFile, variable_desc *);
extern int utilReadInt(gzFile); extern int utilReadInt(gzFile);
extern void utilWriteInt(gzFile, int); extern void utilWriteInt(gzFile, int);
extern gzFile utilGzOpen(const char *file, const char *mode); extern gzFile utilGzOpen(const char *file, const char *mode);
extern gzFile utilMemGzOpen(char *memory, int available, const char *mode); extern gzFile utilMemGzOpen(char *memory, int available, char *mode);
extern int utilGzWrite(gzFile file, const voidp buffer, unsigned int len); extern int utilGzWrite(gzFile file, const voidp buffer, unsigned int len);
extern int utilGzRead(gzFile file, voidp buffer, unsigned int len); extern int utilGzRead(gzFile file, voidp buffer, unsigned int len);
extern int utilGzClose(gzFile file); extern int utilGzClose(gzFile file);
extern z_off_t utilGzSeek(gzFile file, z_off_t offset, int whence);
extern long utilGzMemTell(gzFile file); extern long utilGzMemTell(gzFile file);
extern void utilGBAFindSave(const u8 *, const int); extern void utilGBAFindSave(const u8 *, const int);
extern void utilUpdateSystemColorMaps();
#endif #endif

1033
source/vba/admame.cpp Normal file

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

@ -22,7 +22,6 @@
#include "GBA.h" #include "GBA.h"
#include "Globals.h" #include "Globals.h"
#include "Port.h" #include "Port.h"
#include "System.h"
#define debuggerWriteHalfWord(addr, value) \ #define debuggerWriteHalfWord(addr, value) \
WRITE16LE((u16*)&map[(addr)>>24].address[(addr) & map[(addr)>>24].mask], (value)) WRITE16LE((u16*)&map[(addr)>>24].address[(addr) & map[(addr)>>24].mask], (value))
@ -35,21 +34,26 @@ static bool agbPrintProtect = false;
bool agbPrintWrite(u32 address, u16 value) bool agbPrintWrite(u32 address, u16 value)
{ {
if(agbPrintEnabled) { if(agbPrintEnabled)
if(address == 0x9fe2ffe) { // protect {
agbPrintProtect = (value != 0); if(address == 0x9fe2ffe)
debuggerWriteHalfWord(address, value); { // protect
return true; agbPrintProtect = (value != 0);
} else { debuggerWriteHalfWord(address, value);
if(agbPrintProtect && return true;
((address >= 0x9fe20f8 && address <= 0x9fe20ff) // control structure }
|| (address >= 0x8fd0000 && address <= 0x8fdffff) else
|| (address >= 0x9fd0000 && address <= 0x9fdffff))) { {
debuggerWriteHalfWord(address, value); if(agbPrintProtect &&
return true; ((address >= 0x9fe20f8 && address <= 0x9fe20ff) // control structure
} || (address >= 0x8fd0000 && address <= 0x8fdffff)
|| (address >= 0x9fd0000 && address <= 0x9fdffff)))
{
debuggerWriteHalfWord(address, value);
return true;
}
}
} }
}
return false; return false;
} }
@ -68,31 +72,35 @@ bool agbPrintIsEnabled()
return agbPrintEnabled; return agbPrintEnabled;
} }
extern void (*dbgOutput)(char *, u32);
void agbPrintFlush() void agbPrintFlush()
{ {
u16 get = debuggerReadHalfWord(0x9fe20fc); u16 get = debuggerReadHalfWord(0x9fe20fc);
u16 put = debuggerReadHalfWord(0x9fe20fe); u16 put = debuggerReadHalfWord(0x9fe20fe);
u32 address = (debuggerReadHalfWord(0x9fe20fa) << 16); u32 address = (debuggerReadHalfWord(0x9fe20fa) << 16);
if(address != 0xfd0000 && address != 0x1fd0000) { 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 dbgOutput("Did you forget to call AGBPrintInit?\n", 0);
debuggerWriteHalfWord(0x9fe20fc, put); // get rid of the text otherwise we will continue to be called
return; debuggerWriteHalfWord(0x9fe20fc, put);
} return;
}
u8 *data = &rom[address]; u8 *data = &rom[address];
while(get != put) { while(get != put)
char c = data[get++]; {
char s[2]; char c = data[get++];
s[0] = c; char s[2];
s[1] = 0; s[0] = c;
s[1] = 0;
if(systemVerbose & VERBOSE_AGBPRINT) if(systemVerbose & VERBOSE_AGBPRINT)
dbgOutput(s, 0); dbgOutput(s, 0);
if(c == '\n') if(c == '\n')
break; break;
} }
debuggerWriteHalfWord(0x9fe20fc, get); debuggerWriteHalfWord(0x9fe20fc, get);
} }

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

432
source/vba/bilinear.cpp Normal file
View File

@ -0,0 +1,432 @@
// 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.
/** Code adapted from Exult source code by Forgotten
** Scale.cc - Trying to scale with bilinear interpolation.
**
** Written: 6/14/00 - JSF
**/
#include "System.h"
static u8 row_cur[3*322];
static u8 row_next[3*322];
static u8 *rgb_row_cur = row_cur;
static u8 *rgb_row_next = row_next;
#define RGB(r,g,b) ((r)>>3) << systemRedShift |\
((g) >> 3) << systemGreenShift |\
((b) >> 3) << systemBlueShift\
static void fill_rgb_row_16(u16 *from, int src_width, u8 *row, int width)
{
u8 *copy_start = row + src_width*3;
u8 *all_stop = row + width*3;
while (row < copy_start)
{
u16 color = *from++;
*row++ = ((color >> systemRedShift) & 0x1f) << 3;
*row++ = ((color >> systemGreenShift) & 0x1f) << 3;
*row++ = ((color >> systemBlueShift) & 0x1f) << 3;
}
// any remaining elements to be written to 'row' are a replica of the
// preceding pixel
u8 *p = row-3;
while (row < all_stop)
{
// we're guaranteed three elements per pixel; could unroll the loop
// further, especially with a Duff's Device, but the gains would be
// probably limited (judging by profiler output)
*row++ = *p++;
*row++ = *p++;
*row++ = *p++;
}
}
static void fill_rgb_row_32(u32 *from, int src_width, u8 *row, int width)
{
u8 *copy_start = row + src_width*3;
u8 *all_stop = row + width*3;
while (row < copy_start)
{
u32 color = *from++;
*row++ = ((color >> systemRedShift) & 0x1f) << 3;
*row++ = ((color >> systemGreenShift) & 0x1f) << 3;
*row++ = ((color >> systemBlueShift) & 0x1f) << 3;
}
// any remaining elements to be written to 'row' are a replica of the
// preceding pixel
u8 *p = row-3;
while (row < all_stop)
{
// we're guaranteed three elements per pixel; could unroll the loop
// further, especially with a Duff's Device, but the gains would be
// probably limited (judging by profiler output)
*row++ = *p++;
*row++ = *p++;
*row++ = *p++;
}
}
void Bilinear(u8 *srcPtr, u32 srcPitch, u8 * /* deltaPtr */,
u8 *dstPtr, u32 dstPitch, int width, int height)
{
u16 *to = (u16 *)dstPtr;
u16 *to_odd = (u16 *)(dstPtr + dstPitch);
int from_width = width;
u16 *from = (u16 *)srcPtr;
fill_rgb_row_16(from, from_width, rgb_row_cur, width+1);
for(int y = 0; y < height; y++)
{
u16 *from_orig = from;
u16 *to_orig = to;
if (y+1 < height)
fill_rgb_row_16(from+width+2, from_width, rgb_row_next,
width+1);
else
fill_rgb_row_16(from, from_width, rgb_row_next, width+1);
// every pixel in the src region, is extended to 4 pixels in the
// destination, arranged in a square 'quad'; if the current src
// pixel is 'a', then in what follows 'b' is the src pixel to the
// right, 'c' is the src pixel below, and 'd' is the src pixel to
// the right and down
u8 *cur_row = rgb_row_cur;
u8 *next_row = rgb_row_next;
u8 *ar = cur_row++;
u8 *ag = cur_row++;
u8 *ab = cur_row++;
u8 *cr = next_row++;
u8 *cg = next_row++;
u8 *cb = next_row++;
for(int x=0; x < width; x++)
{
u8 *br = cur_row++;
u8 *bg = cur_row++;
u8 *bb = cur_row++;
u8 *dr = next_row++;
u8 *dg = next_row++;
u8 *db = next_row++;
// upper left pixel in quad: just copy it in
*to++ = RGB(*ar, *ag, *ab);
// upper right
*to++ = RGB((*ar+*br)>>1, (*ag+*bg)>>1, (*ab+*bb)>>1);
// lower left
*to_odd++ = RGB((*ar+*cr)>>1, (*ag+*cg)>>1, (*ab+*cb)>>1);
// lower right
*to_odd++ = RGB((*ar+*br+*cr+*dr)>>2,
(*ag+*bg+*cg+*dg)>>2,
(*ab+*bb+*cb+*db)>>2);
// 'b' becomes 'a', 'd' becomes 'c'
ar = br;
ag = bg;
ab = bb;
cr = dr;
cg = dg;
cb = db;
}
// the "next" rgb row becomes the current; the old current rgb row is
// recycled and serves as the new "next" row
u8 *temp;
temp = rgb_row_cur;
rgb_row_cur = rgb_row_next;
rgb_row_next = temp;
// update the pointers for start of next pair of lines
from = (u16 *)((u8 *)from_orig + srcPitch);
to = (u16 *)((u8 *)to_orig + (dstPitch << 1));
to_odd = (u16 *)((u8 *)to + dstPitch);
}
}
void BilinearPlus(u8 *srcPtr, u32 srcPitch, u8 * /* deltaPtr */,
u8 *dstPtr, u32 dstPitch, int width, int height)
{
u16 *to = (u16 *)dstPtr;
u16 *to_odd = (u16 *)(dstPtr + dstPitch);
int from_width = width;
u16 *from = (u16 *)srcPtr;
fill_rgb_row_16(from, from_width, rgb_row_cur, width+1);
for(int y = 0; y < height; y++)
{
u16 *from_orig = from;
u16 *to_orig = to;
if (y+1 < height)
fill_rgb_row_16(from+width+2, from_width, rgb_row_next,
width+1);
else
fill_rgb_row_16(from, from_width, rgb_row_next, width+1);
// every pixel in the src region, is extended to 4 pixels in the
// destination, arranged in a square 'quad'; if the current src
// pixel is 'a', then in what follows 'b' is the src pixel to the
// right, 'c' is the src pixel below, and 'd' is the src pixel to
// the right and down
u8 *cur_row = rgb_row_cur;
u8 *next_row = rgb_row_next;
u8 *ar = cur_row++;
u8 *ag = cur_row++;
u8 *ab = cur_row++;
u8 *cr = next_row++;
u8 *cg = next_row++;
u8 *cb = next_row++;
for(int x=0; x < width; x++)
{
u8 *br = cur_row++;
u8 *bg = cur_row++;
u8 *bb = cur_row++;
u8 *dr = next_row++;
u8 *dg = next_row++;
u8 *db = next_row++;
// upper left pixel in quad: just copy it in
//*to++ = manip.rgb(*ar, *ag, *ab);
#ifdef USE_ORIGINAL_BILINEAR_PLUS
*to++ = RGB(
(((*ar)<<2) +((*ar)) + (*cr+*br+*br) )>> 3,
(((*ag)<<2) +((*ag)) + (*cg+*bg+*bg) )>> 3,
(((*ab)<<2) +((*ab)) + (*cb+*bb+*bb) )>> 3);
#else
*to++ = RGB(
(((*ar)<<3) +((*ar)<<1) + (*cr+*br+*br+*cr) )>> 4,
(((*ag)<<3) +((*ag)<<1) + (*cg+*bg+*bg+*cg) )>> 4,
(((*ab)<<3) +((*ab)<<1) + (*cb+*bb+*bb+*cb) )>> 4);
#endif
// upper right
*to++ = RGB((*ar+*br)>>1, (*ag+*bg)>>1, (*ab+*bb)>>1);
// lower left
*to_odd++ = RGB((*ar+*cr)>>1, (*ag+*cg)>>1, (*ab+*cb)>>1);
// lower right
*to_odd++ = RGB((*ar+*br+*cr+*dr)>>2,
(*ag+*bg+*cg+*dg)>>2,
(*ab+*bb+*cb+*db)>>2);
// 'b' becomes 'a', 'd' becomes 'c'
ar = br;
ag = bg;
ab = bb;
cr = dr;
cg = dg;
cb = db;
}
// the "next" rgb row becomes the current; the old current rgb row is
// recycled and serves as the new "next" row
u8 *temp;
temp = rgb_row_cur;
rgb_row_cur = rgb_row_next;
rgb_row_next = temp;
// update the pointers for start of next pair of lines
from = (u16 *)((u8 *)from_orig + srcPitch);
to = (u16 *)((u8 *)to_orig + (dstPitch << 1));
to_odd = (u16 *)((u8 *)to + dstPitch);
}
}
void Bilinear32(u8 *srcPtr, u32 srcPitch, u8 * /* deltaPtr */,
u8 *dstPtr, u32 dstPitch, int width, int height)
{
u32 *to = (u32 *)dstPtr;
u32 *to_odd = (u32 *)(dstPtr + dstPitch);
int from_width = width;
if(width+1 < from_width)
from_width = width+1;
u32 *from = (u32 *)srcPtr;
fill_rgb_row_32(from, from_width, rgb_row_cur, width+1);
for(int y = 0; y < height; y++)
{
u32 *from_orig = from;
u32 *to_orig = to;
if (y+1 < height)
fill_rgb_row_32(from+width+1, from_width, rgb_row_next,
width+1);
else
fill_rgb_row_32(from, from_width, rgb_row_next, width+1);
// every pixel in the src region, is extended to 4 pixels in the
// destination, arranged in a square 'quad'; if the current src
// pixel is 'a', then in what follows 'b' is the src pixel to the
// right, 'c' is the src pixel below, and 'd' is the src pixel to
// the right and down
u8 *cur_row = rgb_row_cur;
u8 *next_row = rgb_row_next;
u8 *ar = cur_row++;
u8 *ag = cur_row++;
u8 *ab = cur_row++;
u8 *cr = next_row++;
u8 *cg = next_row++;
u8 *cb = next_row++;
for(int x=0; x < width; x++)
{
u8 *br = cur_row++;
u8 *bg = cur_row++;
u8 *bb = cur_row++;
u8 *dr = next_row++;
u8 *dg = next_row++;
u8 *db = next_row++;
// upper left pixel in quad: just copy it in
*to++ = RGB(*ar, *ag, *ab);
// upper right
*to++ = RGB((*ar+*br)>>1, (*ag+*bg)>>1, (*ab+*bb)>>1);
// lower left
*to_odd++ = RGB((*ar+*cr)>>1, (*ag+*cg)>>1, (*ab+*cb)>>1);
// lower right
*to_odd++ = RGB((*ar+*br+*cr+*dr)>>2,
(*ag+*bg+*cg+*dg)>>2,
(*ab+*bb+*cb+*db)>>2);
// 'b' becomes 'a', 'd' becomes 'c'
ar = br;
ag = bg;
ab = bb;
cr = dr;
cg = dg;
cb = db;
}
// the "next" rgb row becomes the current; the old current rgb row is
// recycled and serves as the new "next" row
u8 *temp;
temp = rgb_row_cur;
rgb_row_cur = rgb_row_next;
rgb_row_next = temp;
// update the pointers for start of next pair of lines
from = (u32 *)((u8 *)from_orig + srcPitch);
to = (u32 *)((u8 *)to_orig + (dstPitch << 1));
to_odd = (u32 *)((u8 *)to + dstPitch);
}
}
void BilinearPlus32(u8 *srcPtr, u32 srcPitch, u8 * /* deltaPtr */,
u8 *dstPtr, u32 dstPitch, int width, int height)
{
u32 *to = (u32 *)dstPtr;
u32 *to_odd = (u32 *)(dstPtr + dstPitch);
int from_width = width;
if(width+1 < from_width)
from_width = width+1;
u32 *from = (u32 *)srcPtr;
fill_rgb_row_32(from, from_width, rgb_row_cur, width+1);
for(int y = 0; y < height; y++)
{
u32 *from_orig = from;
u32 *to_orig = to;
if (y+1 < height)
fill_rgb_row_32(from+width+1, from_width, rgb_row_next,
width+1);
else
fill_rgb_row_32(from, from_width, rgb_row_next, width+1);
// every pixel in the src region, is extended to 4 pixels in the
// destination, arranged in a square 'quad'; if the current src
// pixel is 'a', then in what follows 'b' is the src pixel to the
// right, 'c' is the src pixel below, and 'd' is the src pixel to
// the right and down
u8 *cur_row = rgb_row_cur;
u8 *next_row = rgb_row_next;
u8 *ar = cur_row++;
u8 *ag = cur_row++;
u8 *ab = cur_row++;
u8 *cr = next_row++;
u8 *cg = next_row++;
u8 *cb = next_row++;
for(int x=0; x < width; x++)
{
u8 *br = cur_row++;
u8 *bg = cur_row++;
u8 *bb = cur_row++;
u8 *dr = next_row++;
u8 *dg = next_row++;
u8 *db = next_row++;
// upper left pixel in quad: just copy it in
//*to++ = manip.rgb(*ar, *ag, *ab);
#ifdef USE_ORIGINAL_BILINEAR_PLUS
*to++ = RGB(
(((*ar)<<2) +((*ar)) + (*cr+*br+*br) )>> 3,
(((*ag)<<2) +((*ag)) + (*cg+*bg+*bg) )>> 3,
(((*ab)<<2) +((*ab)) + (*cb+*bb+*bb) )>> 3);
#else
*to++ = RGB(
(((*ar)<<3) +((*ar)<<1) + (*cr+*br+*br+*cr) )>> 4,
(((*ag)<<3) +((*ag)<<1) + (*cg+*bg+*bg+*cg) )>> 4,
(((*ab)<<3) +((*ab)<<1) + (*cb+*bb+*bb+*cb) )>> 4);
#endif
// upper right
*to++ = RGB((*ar+*br)>>1, (*ag+*bg)>>1, (*ab+*bb)>>1);
// lower left
*to_odd++ = RGB((*ar+*cr)>>1, (*ag+*cg)>>1, (*ab+*cb)>>1);
// lower right
*to_odd++ = RGB((*ar+*br+*cr+*dr)>>2,
(*ag+*bg+*cg+*dg)>>2,
(*ab+*bb+*cb+*db)>>2);
// 'b' becomes 'a', 'd' becomes 'c'
ar = br;
ag = bg;
ab = bb;
cr = dr;
cg = dg;
cb = db;
}
// the "next" rgb row becomes the current; the old current rgb row is
// recycled and serves as the new "next" row
u8 *temp;
temp = rgb_row_cur;
rgb_row_cur = rgb_row_next;
rgb_row_next = temp;
// update the pointers for start of next pair of lines
from = (u32 *)((u8 *)from_orig + srcPitch);
to = (u32 *)((u8 *)to_orig + (dstPitch << 1));
to_odd = (u32 *)((u8 *)to + dstPitch);
}
}

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