mirror of
https://github.com/dborth/vbagx.git
synced 2025-02-22 21:27:09 +01:00
[What's New 1.0.0 - September 16, 2008]
* Now compiles with devkitpro r15 * One makefile to make all versions * Complete rewrite based on code from SNES9x GX * Now has a menu! ROM selector, preferences, controller mapping, etc * Wiimote, Nunchuk, and Classic controller support * Button mapping for all controller types * Full support for SD and USB * Load/save preference selector. ROMs, saves, and preferences are saved/loaded according to these * 'Auto' settings for save/load - attempts to automatically determine your load/save device(s) - SD, USB * Preferences are loaded and saved in XML format. You can open VBAGX.xml edit all settings, including some not available within the program
This commit is contained in:
parent
2f2a1fd518
commit
ae514696d4
19
Makefile.gc
19
Makefile.gc
@ -15,23 +15,22 @@ include $(DEVKITPPC)/gamecube_rules
|
|||||||
# SOURCES is a list of directories containing source code
|
# SOURCES is a list of directories containing source code
|
||||||
# INCLUDES is a list of directories containing extra header files
|
# INCLUDES is a list of directories containing extra header files
|
||||||
#---------------------------------------------------------------------------------
|
#---------------------------------------------------------------------------------
|
||||||
TARGET := vbagx_gc
|
TARGET := vba172_gc
|
||||||
TARGETDIR := executables
|
TARGETDIR := executables
|
||||||
BUILD := build_gc
|
BUILD := build_gc
|
||||||
SOURCES := source/vba source/vba/agb source/vba/dmg source/ngc source/sz
|
SOURCES := source/vba source/vba/gb source/ngc
|
||||||
INCLUDES := source/vba source/ngc
|
INCLUDES := source/vba source/vba/gb source/ngc
|
||||||
|
|
||||||
#---------------------------------------------------------------------------------
|
#---------------------------------------------------------------------------------
|
||||||
# options for code generation
|
# options for code generation
|
||||||
#---------------------------------------------------------------------------------
|
#---------------------------------------------------------------------------------
|
||||||
|
|
||||||
CFLAGS = -g -O3 -Wall $(MACHDEP) $(INCLUDE) \
|
CFLAGS = -g -Os -Wall $(MACHDEP) $(INCLUDE) \
|
||||||
-DNGC -DUSE_VM -DWORDS_BIGENDIAN \
|
-DNGC -DWORDS_BIGENDIAN -DPACKAGE=\"VisualBoyAdvance\" \
|
||||||
-DC_CORE -D__ppc__ -D__POWERPC__ -DFINAL_VERSION \
|
-DVERSION=\"1.7.2\" -DC_CORE \
|
||||||
-DSDL -DNO_PNG -DHAVE_ZUTIL_H \
|
-DCHANFFS -DSDL -DNO_DEFLATE
|
||||||
-D_SZ_ONE_DIRECTORY -D_LZMA_IN_CB -D_LZMA_OUT_READ
|
CXXFLAGS = -save-temps -Xassembler -aln=$@.lst $(CFLAGS)
|
||||||
CXXFLAGS = $(CFLAGS)
|
LDFLAGS = -g $(MACHDEP) -Wl,-Map,$(notdir $@).map -Wl,--cref
|
||||||
LDFLAGS = -g $(MACHDEP) -Wl,-Map,$(notdir $@).map
|
|
||||||
|
|
||||||
#---------------------------------------------------------------------------------
|
#---------------------------------------------------------------------------------
|
||||||
# any extra libraries we wish to link with
|
# any extra libraries we wish to link with
|
||||||
|
17
Makefile.wii
17
Makefile.wii
@ -15,22 +15,21 @@ include $(DEVKITPPC)/wii_rules
|
|||||||
# SOURCES is a list of directories containing source code
|
# SOURCES is a list of directories containing source code
|
||||||
# INCLUDES is a list of directories containing extra header files
|
# INCLUDES is a list of directories containing extra header files
|
||||||
#---------------------------------------------------------------------------------
|
#---------------------------------------------------------------------------------
|
||||||
TARGET := vbagx_wii
|
TARGET := vba172_wii
|
||||||
TARGETDIR := executables
|
TARGETDIR := executables
|
||||||
BUILD := build_wii
|
BUILD := build_wii
|
||||||
SOURCES := source/vba source/vba/agb source/vba/dmg source/ngc source/sz
|
SOURCES := source/vba source/vba/gb source/ngc
|
||||||
INCLUDES := source/vba source/ngc
|
INCLUDES := source/vba source/vba/gb source/ngc
|
||||||
|
|
||||||
#---------------------------------------------------------------------------------
|
#---------------------------------------------------------------------------------
|
||||||
# options for code generation
|
# options for code generation
|
||||||
#---------------------------------------------------------------------------------
|
#---------------------------------------------------------------------------------
|
||||||
|
|
||||||
CFLAGS = -g -O3 -Wall $(MACHDEP) $(INCLUDE) \
|
CFLAGS = -g -Os -Wall $(MACHDEP) $(INCLUDE) \
|
||||||
-DNGC -DWII_DVD -DWORDS_BIGENDIAN -DVIDEO_THREADING \
|
-DNGC -DWORDS_BIGENDIAN -DPACKAGE=\"VisualBoyAdvance\" \
|
||||||
-DC_CORE -D__ppc__ -D__POWERPC__ -DFINAL_VERSION \
|
-DVERSION=\"1.7.2\" -DC_CORE \
|
||||||
-DSDL -DNO_PNG -DHAVE_ZUTIL_H \
|
-DCHANFFS -DSDL -DNO_DEFLATE
|
||||||
-D_SZ_ONE_DIRECTORY -D_LZMA_IN_CB -D_LZMA_OUT_READ
|
CXXFLAGS = -save-temps -Xassembler -aln=$@.lst $(CFLAGS)
|
||||||
CXXFLAGS = $(CFLAGS)
|
|
||||||
LDFLAGS = -g $(MACHDEP) -Wl,-Map,$(notdir $@).map -Wl,--cref
|
LDFLAGS = -g $(MACHDEP) -Wl,-Map,$(notdir $@).map -Wl,--cref
|
||||||
|
|
||||||
#---------------------------------------------------------------------------------
|
#---------------------------------------------------------------------------------
|
||||||
|
40
readme.txt
40
readme.txt
@ -1,13 +1,14 @@
|
|||||||
¸,ø¤°`°¤ø,¸¸,ø¤°`°¤ø,¸,ø¤°`°¤ø,¸¸,ø¤°`°¤ø,¸,ø¤°`°¤ø,¸¸,ø¤°`°¤ø,¸,ø¤°`°¤ø,¸¸,ø¤
|
¸,ø¤°`°¤ø,¸¸,ø¤°`°¤ø,¸,ø¤°`°¤ø,¸¸,ø¤°`°¤ø,¸,ø¤°`°¤ø,¸¸,ø¤°`°¤ø,¸,ø¤°`°¤ø,¸¸,ø¤
|
||||||
|
|
||||||
- Visual Boy Advance GX -
|
- Visual Boy Advance GX -
|
||||||
Version 1.0.3
|
Version 1.0.0
|
||||||
http://code.google.com/p/vba-wii
|
|
||||||
(Under GPL License)
|
(Under GPL License)
|
||||||
|
|
||||||
¸,ø¤°`°¤ø,¸¸,ø¤°`°¤ø,¸,ø¤°`°¤ø,¸¸,ø¤°`°¤ø,¸,ø¤°`°¤ø,¸¸,ø¤°`°¤ø,¸,ø¤°`°¤ø,¸¸,ø¤
|
¸,ø¤°`°¤ø,¸¸,ø¤°`°¤ø,¸,ø¤°`°¤ø,¸¸,ø¤°`°¤ø,¸,ø¤°`°¤ø,¸¸,ø¤°`°¤ø,¸,ø¤°`°¤ø,¸¸,ø¤
|
||||||
|
|
||||||
Visual Boy Advance GX is a modified port of VBA-M / VBA 1.7.2.
|
-=[ Explanation ]=-
|
||||||
|
|
||||||
|
Visual Boy Advance GX is a port of Visual Boy Advance 1.7.2.
|
||||||
With it you can play GBA/Game Boy Color/Game Boy games on your Wii/GameCube.
|
With it you can play GBA/Game Boy Color/Game Boy games on your Wii/GameCube.
|
||||||
|
|
||||||
-=[ Features ]=-
|
-=[ Features ]=-
|
||||||
@ -15,42 +16,13 @@ With it you can play GBA/Game Boy Color/Game Boy games on your Wii/GameCube.
|
|||||||
* Wiimote, Nunchuk, Classic, and Gamecube controller support
|
* Wiimote, Nunchuk, Classic, and Gamecube controller support
|
||||||
* SRAM and State saving
|
* SRAM and State saving
|
||||||
* Custom controller configurations
|
* Custom controller configurations
|
||||||
* SD, USB, DVD, SMB, GC Memory Card, Zip, and 7z support
|
* SD and USB support
|
||||||
* GBA compatiblity based on VBA-M r750, GB compatibility based on VBA 1.7.2
|
|
||||||
* Turbo speed feature
|
|
||||||
|
|
||||||
×—–—–—–—– –—–—–—–—–—–—–—–—–—–— —–—–—–—–—–—–—–—-—–-–•¬
|
×—–—–—–—– –—–—–—–—–—–—–—–—–—–— —–—–—–—–—–—–—–—-—–-–•¬
|
||||||
|0O×øo· UPDATE HISTORY ·oø×O0|
|
|0O×øo· UPDATE HISTORY ·oø×O0|
|
||||||
`¨•¨¨¨¨¨ ¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨ ¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨ ¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨ ¨¨¨¨¨¨¨¨¨¨¨¨¨'
|
`¨•¨¨¨¨¨ ¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨ ¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨ ¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨ ¨¨¨¨¨¨¨¨¨¨¨¨¨'
|
||||||
|
|
||||||
[What's New 1.0.3 - October 15, 2008]
|
[What's New 1.0.0]
|
||||||
* New timing / frameskip algorithm - should (hopefully) work 100% better!
|
|
||||||
* Performance improvements - video threading, PPC core partly activated
|
|
||||||
* Video zooming option
|
|
||||||
* Unfiltered video option
|
|
||||||
* 7z support
|
|
||||||
* Loading progress bars added
|
|
||||||
|
|
||||||
[What's New 1.0.2 - October 6, 2008]
|
|
||||||
* New core! The core is now a custom combination of VBA-M and VBA 1.72
|
|
||||||
* Added DVD, SMB, ZIP, GameCube MC support
|
|
||||||
* Faster USB/SD speeds
|
|
||||||
* Screen alignment and flickering problems fixed
|
|
||||||
* 128K save support added
|
|
||||||
* Better emulation speeds. Should now be nearly full speed all the time
|
|
||||||
for most games.
|
|
||||||
* Turbo speed feature. Mapped to right C-stick (classic controller &
|
|
||||||
Gamecube controller), and A+B for wiimote
|
|
||||||
* Controller mapping preferences bug fixed. Your preferences will reset
|
|
||||||
automatically to correct any problems in your preferences file
|
|
||||||
* Many other tweaks behind the scenes
|
|
||||||
|
|
||||||
[What's New 1.0.1 - September 18, 2008]
|
|
||||||
* GBA games now run at full speed
|
|
||||||
* Menu improvements, with spiffy new background - thanks brakken!
|
|
||||||
* Fixed L/R buttons - they work now
|
|
||||||
|
|
||||||
[What's New 1.0.0 - September 16, 2008]
|
|
||||||
|
|
||||||
* Now compiles with devkitpro r15
|
* Now compiles with devkitpro r15
|
||||||
* One makefile to make all versions
|
* One makefile to make all versions
|
||||||
|
@ -13,7 +13,6 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <malloc.h>
|
|
||||||
|
|
||||||
#ifdef WII_DVD
|
#ifdef WII_DVD
|
||||||
extern "C" {
|
extern "C" {
|
||||||
@ -23,12 +22,14 @@ extern "C" {
|
|||||||
|
|
||||||
#include "menudraw.h"
|
#include "menudraw.h"
|
||||||
#include "gcunzip.h"
|
#include "gcunzip.h"
|
||||||
#include "filesel.h"
|
|
||||||
#include "vba.h"
|
|
||||||
|
|
||||||
u64 dvddir = 0; // offset of currently selected file or folder
|
extern int offset;
|
||||||
int dvddirlength = 0; // length of currently selected file or folder
|
extern int selection;
|
||||||
u64 dvdrootdir = 0; // offset of DVD root
|
extern FILEENTRIES filelist[MAXFILES];
|
||||||
|
extern int maxfiles;
|
||||||
|
u64 dvddir = 0;
|
||||||
|
u64 dvdrootdir = 0;
|
||||||
|
int dvddirlength = 0;
|
||||||
bool isWii = false;
|
bool isWii = false;
|
||||||
|
|
||||||
#ifdef HW_DOL
|
#ifdef HW_DOL
|
||||||
@ -36,30 +37,34 @@ 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 **/
|
||||||
|
|
||||||
// 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)))
|
|
||||||
{
|
|
||||||
u8 * buffer = (u8 *)memalign(32, 0x8000);
|
|
||||||
u32 off_size = 0;
|
|
||||||
|
|
||||||
DCInvalidateRange ((void *) buffer, len);
|
DCInvalidateRange ((void *) buffer, len);
|
||||||
|
|
||||||
|
// don't read past the end of the DVD (1.5 GB for GC DVD, 4.7 GB for DVD)
|
||||||
|
if(offset < 0x57057C00 || (isWii && offset < 0x118244F00LL))
|
||||||
|
{
|
||||||
|
|
||||||
#ifdef HW_DOL
|
#ifdef HW_DOL
|
||||||
|
|
||||||
dvd[0] = 0x2E;
|
dvd[0] = 0x2E;
|
||||||
dvd[1] = 0;
|
dvd[1] = 0;
|
||||||
dvd[2] = 0xA8000000;
|
dvd[2] = 0xA8000000;
|
||||||
@ -67,161 +72,28 @@ dvd_read (void *dst, unsigned int len, u64 offset)
|
|||||||
dvd[4] = len;
|
dvd[4] = len;
|
||||||
dvd[5] = (u32) buffer;
|
dvd[5] = (u32) buffer;
|
||||||
dvd[6] = len;
|
dvd[6] = len;
|
||||||
dvd[7] = 3;
|
dvd[7] = 3; /*** Enable reading with DMA ***/
|
||||||
|
|
||||||
// Enable reading with DMA
|
|
||||||
while (dvd[7] & 1);
|
while (dvd[7] & 1);
|
||||||
|
memcpy (dst, buffer, len);
|
||||||
|
|
||||||
// Ensure it has completed
|
if (dvd[0] & 0x4) /* Ensure it has completed */
|
||||||
if (dvd[0] & 0x4)
|
|
||||||
return 0;
|
return 0;
|
||||||
#else
|
|
||||||
off_size = offset - ALIGN_BACKWARD(offset,0x800);
|
return 1;
|
||||||
if (DI_ReadDVD(
|
|
||||||
buffer,
|
#elif WII_DVD
|
||||||
(ALIGN_FORWARD(offset + len,0x800) - ALIGN_BACKWARD(offset,0x800)) >> 11,
|
int ret = 1;
|
||||||
(u32)(ALIGN_BACKWARD(offset, 0x800) >> 11)
|
ret = DI_ReadDVD(dst, len >> 11, (u32)(offset >> 11));
|
||||||
))
|
if (ret==0)
|
||||||
|
return 1;
|
||||||
|
else
|
||||||
return 0;
|
return 0;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
memcpy (dst, buffer+off_size, len);
|
|
||||||
free(buffer);
|
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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,20 +445,11 @@ 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...");
|
||||||
if(length > 0 && length <= 2048) // do a partial read (eg: to check file header)
|
|
||||||
{
|
|
||||||
dvd_read (buffer, length, discoffset);
|
|
||||||
}
|
|
||||||
else // load whole file
|
|
||||||
{
|
|
||||||
dvd_read (readbuffer, 2048, discoffset);
|
dvd_read (readbuffer, 2048, discoffset);
|
||||||
|
|
||||||
if (!IsZipFile (readbuffer))
|
if (!IsZipFile (readbuffer))
|
||||||
@ -599,7 +460,6 @@ LoadDVDFile (unsigned char *buffer, int length)
|
|||||||
memcpy (buffer + offset, readbuffer, 2048);
|
memcpy (buffer + offset, readbuffer, 2048);
|
||||||
offset += 2048;
|
offset += 2048;
|
||||||
discoffset += 2048;
|
discoffset += 2048;
|
||||||
ShowProgress ((char *)"Loading...", offset, length);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*** And final cleanup ***/
|
/*** And final cleanup ***/
|
||||||
@ -612,8 +472,7 @@ LoadDVDFile (unsigned char *buffer, int length)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
return UnZipBuffer (buffer, METHOD_DVD); // unzip from dvd
|
return UnZipFile (buffer, discoffset); // unzip from dvd
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return dvddirlength;
|
return dvddirlength;
|
||||||
}
|
}
|
||||||
|
@ -13,17 +13,10 @@
|
|||||||
|
|
||||||
int getpvd ();
|
int getpvd ();
|
||||||
int ParseDVDdirectory ();
|
int ParseDVDdirectory ();
|
||||||
int LoadDVDFile (unsigned char *buffer, int length);
|
int LoadDVDFile (unsigned char *buffer);
|
||||||
bool TestDVD();
|
bool TestDVD();
|
||||||
int dvd_read (void *dst, unsigned int len, u64 offset);
|
int dvd_read (void *dst, unsigned int len, u64 offset);
|
||||||
int dvd_safe_read (void *dst, unsigned int len, u64 offset);
|
|
||||||
bool SwitchDVDFolder(char dir[]);
|
bool SwitchDVDFolder(char dir[]);
|
||||||
void SetDVDDriveType();
|
void SetDVDDriveType();
|
||||||
#ifdef HW_DOL
|
|
||||||
void dvd_motor_off ();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
extern u64 dvddir;
|
|
||||||
extern int dvddirlength;
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -24,8 +24,14 @@
|
|||||||
#include "filesel.h"
|
#include "filesel.h"
|
||||||
#include "preferences.h"
|
#include "preferences.h"
|
||||||
|
|
||||||
// FAT file pointer - the only one we should ever use!
|
FILE * filehandle;
|
||||||
FILE * fatfile;
|
|
||||||
|
extern unsigned char savebuffer[];
|
||||||
|
extern char output[16384];
|
||||||
|
extern int offset;
|
||||||
|
extern int selection;
|
||||||
|
extern char currentdir[MAXPATHLEN];
|
||||||
|
extern FILEENTRIES filelist[MAXFILES];
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* fat_is_mounted
|
* fat_is_mounted
|
||||||
@ -61,17 +67,18 @@ bool ChangeFATInterface(int method, bool silent)
|
|||||||
{
|
{
|
||||||
devFound = true;
|
devFound = true;
|
||||||
fatSetDefaultInterface(PI_INTERNAL_SD);
|
fatSetDefaultInterface(PI_INTERNAL_SD);
|
||||||
fatEnableReadAhead (PI_INTERNAL_SD, 6, 64);
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (!devFound && FatIsMounted(PI_SDGECKO_A))
|
if (!devFound && FatIsMounted(PI_SDGECKO_A))
|
||||||
{
|
{
|
||||||
devFound = true;
|
devFound = true;
|
||||||
|
fatSetDefaultInterface(PI_SDGECKO_A);
|
||||||
}
|
}
|
||||||
if(!devFound && FatIsMounted(PI_SDGECKO_B))
|
if(!devFound && FatIsMounted(PI_SDGECKO_B))
|
||||||
{
|
{
|
||||||
devFound = true;
|
devFound = true;
|
||||||
|
fatSetDefaultInterface(PI_SDGECKO_B);
|
||||||
}
|
}
|
||||||
if(!devFound)
|
if(!devFound)
|
||||||
{
|
{
|
||||||
@ -86,7 +93,6 @@ bool ChangeFATInterface(int method, bool silent)
|
|||||||
{
|
{
|
||||||
devFound = true;
|
devFound = true;
|
||||||
fatSetDefaultInterface(PI_USBSTORAGE);
|
fatSetDefaultInterface(PI_USBSTORAGE);
|
||||||
fatEnableReadAhead (PI_USBSTORAGE, 6, 64);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -164,54 +170,44 @@ ParseFATdirectory(int method)
|
|||||||
* LoadFATFile
|
* LoadFATFile
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
int
|
int
|
||||||
LoadFATFile (char * rbuffer, int length)
|
LoadFATFile (char *filename, int length)
|
||||||
{
|
{
|
||||||
char zipbuffer[2048];
|
/*char zipbuffer[2048];
|
||||||
|
FILE *handle;
|
||||||
|
unsigned char *rbuffer;
|
||||||
|
u32 size;*/
|
||||||
char filepath[MAXPATHLEN];
|
char filepath[MAXPATHLEN];
|
||||||
u32 size;
|
|
||||||
|
|
||||||
/* Check filename length */
|
/* Check filename length */
|
||||||
if (!MakeROMPath(filepath, METHOD_SD))
|
if ((strlen(currentdir)+1+strlen(filelist[selection].filename)) < MAXPATHLEN)
|
||||||
|
sprintf(filepath, "%s/%s",currentdir,filelist[selection].filename);
|
||||||
|
else
|
||||||
{
|
{
|
||||||
WaitPrompt((char*) "Maximum filepath length reached!");
|
WaitPrompt((char*) "Maximum filepath length reached!");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
return loadVBAROM(filepath);
|
||||||
fatfile = fopen (filepath, "rb");
|
/*
|
||||||
if (fatfile > 0)
|
handle = fopen (filepath, "rb");
|
||||||
|
if (handle > 0)
|
||||||
{
|
{
|
||||||
if(length > 0 && length <= 2048) // do a partial read (eg: to check file header)
|
fread (zipbuffer, 1, 2048, handle);
|
||||||
{
|
|
||||||
fread (rbuffer, 1, length, fatfile);
|
|
||||||
size = length;
|
|
||||||
}
|
|
||||||
else // load whole file
|
|
||||||
{
|
|
||||||
fread (zipbuffer, 1, 2048, fatfile);
|
|
||||||
|
|
||||||
if (IsZipFile (zipbuffer))
|
if (IsZipFile (zipbuffer))
|
||||||
{
|
{
|
||||||
size = UnZipBuffer ((unsigned char *)rbuffer, METHOD_SD); // unzip from FAT
|
size = UnZipFile (rbuffer, handle); // unzip from FAT
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Just load the file up
|
// Just load the file up
|
||||||
fseek(fatfile, 0, SEEK_END);
|
fseek(handle, 0, SEEK_END);
|
||||||
size = ftell(fatfile); // get filesize
|
length = ftell(handle); // get filesize
|
||||||
fseek(fatfile, 2048, SEEK_SET); // seek back to point where we left off
|
fseek(handle, 2048, SEEK_SET); // seek back to point where we left off
|
||||||
memcpy (rbuffer, zipbuffer, 2048); // copy what we already read
|
memcpy (rbuffer, zipbuffer, 2048); // copy what we already read
|
||||||
|
fread (rbuffer + 2048, 1, length - 2048, handle);
|
||||||
ShowProgress ((char *)"Loading...", 2048, size);
|
size = length;
|
||||||
|
|
||||||
u32 offset = 2048;
|
|
||||||
while(offset < size)
|
|
||||||
{
|
|
||||||
offset += fread (rbuffer + offset, 1, (1024*512), fatfile); // read in 512K chunks
|
|
||||||
ShowProgress ((char *)"Loading...", offset, size);
|
|
||||||
}
|
}
|
||||||
}
|
fclose (handle);
|
||||||
}
|
|
||||||
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)
|
||||||
{
|
{
|
||||||
|
FILE *handle;
|
||||||
|
|
||||||
if (datasize)
|
if (datasize)
|
||||||
{
|
{
|
||||||
fatfile = fopen (filepath, "wb");
|
handle = fopen (filepath, "wb");
|
||||||
|
|
||||||
if (fatfile <= 0)
|
if (handle <= 0)
|
||||||
{
|
{
|
||||||
char msg[100];
|
char msg[100];
|
||||||
sprintf(msg, "Couldn't save %s", filepath);
|
sprintf(msg, "Couldn't save %s", filepath);
|
||||||
@ -292,8 +275,10 @@ SaveBufferToFAT (char *filepath, int datasize, bool silent)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
fwrite (savebuffer, 1, datasize, fatfile);
|
fwrite (savebuffer, 1, datasize, handle);
|
||||||
fclose (fatfile);
|
fclose (handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ClearSaveBuffer ();
|
||||||
return datasize;
|
return datasize;
|
||||||
}
|
}
|
||||||
|
@ -23,12 +23,10 @@
|
|||||||
|
|
||||||
bool ChangeFATInterface(int method, bool silent);
|
bool ChangeFATInterface(int method, bool silent);
|
||||||
int ParseFATdirectory(int method);
|
int ParseFATdirectory(int method);
|
||||||
int LoadFATFile (char * fbuffer, int length);
|
int LoadFATFile (char *filename, int length);
|
||||||
int LoadFATSzFile(char * filepath, unsigned char * rbuffer);
|
|
||||||
int SaveBufferToFAT (char *filepath, int datasize, bool silent);
|
int SaveBufferToFAT (char *filepath, int datasize, bool silent);
|
||||||
int LoadBufferFromFAT (char *filepath, bool silent);
|
int LoadBufferFromFAT (char *filepath, bool silent);
|
||||||
|
|
||||||
extern char currFATdir[MAXPATHLEN];
|
extern char currFATdir[MAXPATHLEN];
|
||||||
extern FILE * fatfile;
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -14,7 +14,6 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <wiiuse/wpad.h>
|
#include <wiiuse/wpad.h>
|
||||||
#include <sys/dir.h>
|
#include <sys/dir.h>
|
||||||
#include <malloc.h>
|
|
||||||
|
|
||||||
#ifdef WII_DVD
|
#ifdef WII_DVD
|
||||||
extern "C" {
|
extern "C" {
|
||||||
@ -32,12 +31,10 @@ extern "C" {
|
|||||||
#include "input.h"
|
#include "input.h"
|
||||||
#include "dvd.h"
|
#include "dvd.h"
|
||||||
#include "smbop.h"
|
#include "smbop.h"
|
||||||
#include "gcunzip.h"
|
|
||||||
|
|
||||||
int offset;
|
int offset;
|
||||||
int selection;
|
int selection;
|
||||||
char currentdir[MAXPATHLEN];
|
char currentdir[MAXPATHLEN];
|
||||||
char szpath[MAXPATHLEN];
|
|
||||||
int maxfiles;
|
int maxfiles;
|
||||||
extern int screenheight;
|
extern int screenheight;
|
||||||
|
|
||||||
@ -49,40 +46,22 @@ 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)
|
|
||||||
free(savebuffer);
|
|
||||||
|
|
||||||
savebuffer = (unsigned char *) memalign(32, SAVEBUFFERSIZE);
|
|
||||||
memset (savebuffer, 0, SAVEBUFFERSIZE);
|
memset (savebuffer, 0, SAVEBUFFERSIZE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
* FreeSaveBuffer ()
|
|
||||||
* Free the savebuffer memory
|
|
||||||
***************************************************************************/
|
|
||||||
void
|
|
||||||
FreeSaveBuffer ()
|
|
||||||
{
|
|
||||||
if (savebuffer != NULL)
|
|
||||||
free(savebuffer);
|
|
||||||
|
|
||||||
savebuffer = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* autoLoadMethod()
|
* autoLoadMethod()
|
||||||
* Auto-determines and sets the load method
|
* Auto-determines and sets the load method
|
||||||
@ -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)
|
||||||
@ -383,37 +303,33 @@ 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
|
|
||||||
if(IsSz())
|
|
||||||
{
|
|
||||||
// we'll store the 7z filepath for extraction later
|
|
||||||
if(!MakeROMPath(szpath, method))
|
|
||||||
{
|
|
||||||
WaitPrompt((char*) "Maximum filepath length reached!");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
int szfiles = SzParse(szpath, method);
|
|
||||||
if(szfiles)
|
|
||||||
{
|
|
||||||
maxfiles = szfiles;
|
|
||||||
inSz = true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
WaitPrompt((char*) "Error opening archive!");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
// store the filename (w/o ext) - used for sram/freeze naming
|
// store the filename (w/o ext) - used for sram/freeze naming
|
||||||
StripExt(ROMFilename, filelist[selection].filename);
|
StripExt(ROMFilename, filelist[selection].filename);
|
||||||
|
|
||||||
ShowAction ((char *)"Loading...");
|
ShowAction ((char *)"Loading...");
|
||||||
|
|
||||||
ROMLoaded = LoadVBAROM(method);
|
switch (method)
|
||||||
inSz = false;
|
|
||||||
|
|
||||||
if (ROMLoaded)
|
|
||||||
{
|
{
|
||||||
|
case METHOD_SD:
|
||||||
|
case METHOD_USB:
|
||||||
|
ROMSize = LoadFATFile (filelist[selection].filename, filelist[selection].length);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case METHOD_DVD:
|
||||||
|
dvddir = filelist[selection].offset;
|
||||||
|
dvddirlength = filelist[selection].length;
|
||||||
|
//ROMSize = LoadDVDFile (Memory.ROM);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case METHOD_SMB:
|
||||||
|
//ROMSize = LoadSMBFile (filelist[selection].filename, filelist[selection].length);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ROMSize > 0)
|
||||||
|
{
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -421,7 +337,6 @@ int FileSelector (int method)
|
|||||||
WaitPrompt((char*) "Error loading ROM!");
|
WaitPrompt((char*) "Error loading ROM!");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
redraw = 1;
|
redraw = 1;
|
||||||
} // End of A
|
} // End of A
|
||||||
if ( (p & PAD_BUTTON_B) || (wp & (WPAD_BUTTON_B | WPAD_CLASSIC_BUTTON_B)) )
|
if ( (p & PAD_BUTTON_B) || (wp & (WPAD_BUTTON_B | WPAD_CLASSIC_BUTTON_B)) )
|
||||||
@ -613,7 +528,7 @@ OpenFAT (int method)
|
|||||||
{
|
{
|
||||||
if(ChangeFATInterface(method, NOTSILENT))
|
if(ChangeFATInterface(method, NOTSILENT))
|
||||||
{
|
{
|
||||||
// change current dir to vba roms directory
|
// change current dir to snes roms directory
|
||||||
sprintf ( currentdir, "%s/%s", ROOTFATDIR, GCSettings.LoadFolder );
|
sprintf ( currentdir, "%s/%s", ROOTFATDIR, GCSettings.LoadFolder );
|
||||||
|
|
||||||
// Parse initial root directory and get entries list
|
// Parse initial root directory and get entries list
|
||||||
|
@ -11,11 +11,9 @@
|
|||||||
#ifndef _NGCFILESEL_
|
#ifndef _NGCFILESEL_
|
||||||
#define _NGCFILESEL_
|
#define _NGCFILESEL_
|
||||||
|
|
||||||
#include <unistd.h>
|
#define SAVEBUFFERSIZE ((512 * 1024) + 2048 + 64 + 4 + 4)
|
||||||
|
|
||||||
#define SAVEBUFFERSIZE (512 * 1024)
|
|
||||||
#define MAXJOLIET 255
|
#define MAXJOLIET 255
|
||||||
#define MAXDISPLAY 40
|
#define MAXDISPLAY 54
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
@ -28,18 +26,9 @@ typedef struct
|
|||||||
|
|
||||||
#define MAXFILES 2000 // Restrict to 2000 files per dir
|
#define MAXFILES 2000 // Restrict to 2000 files per dir
|
||||||
extern FILEENTRIES filelist[MAXFILES];
|
extern FILEENTRIES filelist[MAXFILES];
|
||||||
extern unsigned char *savebuffer;
|
|
||||||
extern int offset;
|
|
||||||
extern int selection;
|
|
||||||
extern char currentdir[MAXPATHLEN];
|
|
||||||
extern char szpath[MAXPATHLEN];
|
|
||||||
extern bool inSz;
|
|
||||||
extern int maxfiles;
|
|
||||||
extern char ROMFilename[512];
|
extern char ROMFilename[512];
|
||||||
|
|
||||||
void AllocSaveBuffer();
|
void ClearSaveBuffer ();
|
||||||
void FreeSaveBuffer();
|
|
||||||
bool MakeROMPath(char filepath[], int method);
|
|
||||||
int OpenROM (int method);
|
int OpenROM (int method);
|
||||||
int autoLoadMethod();
|
int autoLoadMethod();
|
||||||
int autoSaveMethod();
|
int autoSaveMethod();
|
||||||
|
@ -14,19 +14,11 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <zlib.h>
|
#include <zlib.h>
|
||||||
|
|
||||||
extern "C" {
|
|
||||||
#include "../sz/7zCrc.h"
|
|
||||||
#include "../sz/7zIn.h"
|
|
||||||
#include "../sz/7zExtract.h"
|
|
||||||
}
|
|
||||||
|
|
||||||
#include "dvd.h"
|
#include "dvd.h"
|
||||||
#include "smbop.h"
|
#include "smbop.h"
|
||||||
#include "fileop.h"
|
|
||||||
#include "video.h"
|
#include "video.h"
|
||||||
#include "menudraw.h"
|
#include "menudraw.h"
|
||||||
#include "gcunzip.h"
|
#include "gcunzip.h"
|
||||||
#include "vba.h"
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* PKWare Zip Header - adopted into zip standard
|
* PKWare Zip Header - adopted into zip standard
|
||||||
@ -67,7 +59,7 @@ FLIP16 (u16 b)
|
|||||||
* IsZipFile
|
* IsZipFile
|
||||||
*
|
*
|
||||||
* Returns TRUE when PKZIPID is first four characters of buffer
|
* Returns TRUE when PKZIPID is first four characters of buffer
|
||||||
***************************************************************************/
|
****************************************************************************/
|
||||||
int
|
int
|
||||||
IsZipFile (char *buffer)
|
IsZipFile (char *buffer)
|
||||||
{
|
{
|
||||||
@ -82,13 +74,16 @@ IsZipFile (char *buffer)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
* 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,23 +95,21 @@ 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;
|
||||||
}
|
}
|
||||||
@ -126,7 +119,9 @@ UnZipBuffer (unsigned char *outbuffer, int method)
|
|||||||
|
|
||||||
pkzip.uncompressedSize = FLIP32 (pkzip.uncompressedSize);
|
pkzip.uncompressedSize = FLIP32 (pkzip.uncompressedSize);
|
||||||
|
|
||||||
ShowProgress ((char *)"Loading...", 0, pkzip.uncompressedSize);
|
sprintf (msg, "Unzipping %d bytes ... Wait",
|
||||||
|
pkzip.uncompressedSize);
|
||||||
|
ShowAction (msg);
|
||||||
|
|
||||||
/*** Prepare the zip stream ***/
|
/*** Prepare the zip stream ***/
|
||||||
memset (&zs, 0, sizeof (z_stream));
|
memset (&zs, 0, sizeof (z_stream));
|
||||||
@ -176,28 +171,26 @@ UnZipBuffer (unsigned char *outbuffer, int method)
|
|||||||
}
|
}
|
||||||
while (zs.avail_out == 0);
|
while (zs.avail_out == 0);
|
||||||
|
|
||||||
// Readup the next 2k block
|
/*** Readup the next 2k block ***/
|
||||||
zipoffset = 0;
|
zipoffset = 0;
|
||||||
zipchunk = ZIPCHUNK;
|
zipchunk = ZIPCHUNK;
|
||||||
|
|
||||||
switch (method)
|
switch (where)
|
||||||
{
|
{
|
||||||
case METHOD_SD:
|
case 0: // SD Card
|
||||||
case METHOD_USB:
|
|
||||||
fread (readbuffer, 1, ZIPCHUNK, fatfile);
|
fread (readbuffer, 1, ZIPCHUNK, fatfile);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case METHOD_DVD:
|
case 1: // DVD
|
||||||
readoffset += ZIPCHUNK;
|
readoffset += ZIPCHUNK;
|
||||||
dvd_safe_read (readbuffer, ZIPCHUNK, discoffset+readoffset);
|
dvd_read (readbuffer, ZIPCHUNK, discoffset+readoffset);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case METHOD_SMB:
|
case 2: // From SMB
|
||||||
readoffset += ZIPCHUNK;
|
readoffset += ZIPCHUNK;
|
||||||
SMB_ReadFile(readbuffer, ZIPCHUNK, readoffset, smbfile);
|
SMB_ReadFile(readbuffer, ZIPCHUNK, readoffset, smbfile);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
ShowProgress ((char *)"Loading...", bufferoffset, pkzip.uncompressedSize);
|
|
||||||
}
|
}
|
||||||
while (res != Z_STREAM_END);
|
while (res != Z_STREAM_END);
|
||||||
|
|
||||||
@ -213,344 +206,24 @@ UnZipBuffer (unsigned char *outbuffer, int method)
|
|||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
// Reading from FAT
|
||||||
/****************************************************************************
|
|
||||||
* GetFirstZipFilename
|
|
||||||
*
|
|
||||||
* Returns the filename of the first file in the zipped archive
|
|
||||||
* The idea here is to do the least amount of work required
|
|
||||||
***************************************************************************/
|
|
||||||
|
|
||||||
char *
|
|
||||||
GetFirstZipFilename (int method)
|
|
||||||
{
|
|
||||||
char * firstFilename = NULL;
|
|
||||||
char tempbuffer[ZIPCHUNK];
|
|
||||||
|
|
||||||
// read start of ZIP
|
|
||||||
switch (method)
|
|
||||||
{
|
|
||||||
case METHOD_SD: // SD Card
|
|
||||||
case METHOD_USB: // USB
|
|
||||||
LoadFATFile (tempbuffer, ZIPCHUNK);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case METHOD_DVD: // DVD
|
|
||||||
LoadDVDFile ((unsigned char *)tempbuffer, ZIPCHUNK);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case METHOD_SMB: // From SMB
|
|
||||||
LoadSMBFile (tempbuffer, ZIPCHUNK);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
tempbuffer[28] = 0; // truncate - filename length is 2 bytes long (bytes 26-27)
|
|
||||||
int namelength = tempbuffer[26]; // filename length starts 26 bytes in
|
|
||||||
|
|
||||||
firstFilename = &tempbuffer[30]; // first filename of a ZIP starts 31 bytes in
|
|
||||||
firstFilename[namelength] = 0; // truncate at filename length
|
|
||||||
|
|
||||||
return firstFilename;
|
|
||||||
}
|
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
* 7z functions
|
|
||||||
***************************************************************************/
|
|
||||||
|
|
||||||
typedef struct _SzFileInStream
|
|
||||||
{
|
|
||||||
ISzInStream InStream;
|
|
||||||
u64 offset; // offset of the file
|
|
||||||
unsigned int len; // length of the file
|
|
||||||
u64 pos; // current position of the file pointer
|
|
||||||
} SzFileInStream;
|
|
||||||
|
|
||||||
// 7zip error list
|
|
||||||
char szerrormsg[][30] = {
|
|
||||||
"7z: Data error",
|
|
||||||
"7z: Out of memory",
|
|
||||||
"7z: CRC Error",
|
|
||||||
"7z: Not implemented",
|
|
||||||
"7z: Fail",
|
|
||||||
"7z: Archive error",
|
|
||||||
"7z: Dictionary too large",
|
|
||||||
};
|
|
||||||
|
|
||||||
SZ_RESULT SzRes;
|
|
||||||
|
|
||||||
SzFileInStream SzArchiveStream;
|
|
||||||
CArchiveDatabaseEx SzDb;
|
|
||||||
ISzAlloc SzAllocImp;
|
|
||||||
ISzAlloc SzAllocTempImp;
|
|
||||||
UInt32 SzBlockIndex = 0xFFFFFFFF;
|
|
||||||
size_t SzBufferSize;
|
|
||||||
size_t SzOffset;
|
|
||||||
size_t SzOutSizeProcessed;
|
|
||||||
CFileItem *SzF;
|
|
||||||
|
|
||||||
char sz_buffer[2048];
|
|
||||||
int szMethod = 0;
|
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
* Is7ZipFile
|
|
||||||
*
|
|
||||||
* Returns 1 when 7z signature is found
|
|
||||||
****************************************************************************/
|
|
||||||
int
|
int
|
||||||
Is7ZipFile (char *buffer)
|
UnZipFile (unsigned char *outbuffer, FILE* infile)
|
||||||
{
|
{
|
||||||
unsigned int *check;
|
fatfile = infile;
|
||||||
check = (unsigned int *) buffer;
|
return UnZipBuffer(outbuffer, 0);
|
||||||
|
|
||||||
// 7z signature
|
|
||||||
static Byte Signature[6] = {'7', 'z', 0xBC, 0xAF, 0x27, 0x1C};
|
|
||||||
|
|
||||||
int i;
|
|
||||||
for(i = 0; i < 6; i++)
|
|
||||||
if(buffer[i] != Signature[i])
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
return 1; // 7z archive found
|
|
||||||
}
|
}
|
||||||
|
// Reading from DVD
|
||||||
// display an error message
|
int
|
||||||
void SzDisplayError(SZ_RESULT res)
|
UnZipFile (unsigned char *outbuffer, u64 inoffset)
|
||||||
{
|
{
|
||||||
WaitPrompt(szerrormsg[(res - 1)]);
|
discoffset = inoffset;
|
||||||
|
return UnZipBuffer(outbuffer, 1);
|
||||||
}
|
}
|
||||||
|
// Reading from SMB
|
||||||
// function used by the 7zip SDK to read data from SD/USB/DVD/SMB
|
int
|
||||||
SZ_RESULT SzFileReadImp(void *object, void **buffer, size_t maxRequiredSize, size_t *processedSize)
|
UnZipFile (unsigned char *outbuffer, SMBFILE infile)
|
||||||
{
|
{
|
||||||
// the void* object is a SzFileInStream
|
smbfile = infile;
|
||||||
SzFileInStream *s = (SzFileInStream *) object;
|
return UnZipBuffer(outbuffer, 2);
|
||||||
|
|
||||||
// calculate offset
|
|
||||||
u64 offset = (u64) (s->offset + s->pos);
|
|
||||||
|
|
||||||
if (maxRequiredSize > 2048)
|
|
||||||
maxRequiredSize = 2048;
|
|
||||||
|
|
||||||
// read data
|
|
||||||
switch (szMethod)
|
|
||||||
{
|
|
||||||
case METHOD_SD:
|
|
||||||
case METHOD_USB:
|
|
||||||
fseek(fatfile, offset, SEEK_SET);
|
|
||||||
fread(sz_buffer, 1, maxRequiredSize, fatfile);
|
|
||||||
break;
|
|
||||||
case METHOD_DVD:
|
|
||||||
dvd_safe_read(sz_buffer, maxRequiredSize, offset);
|
|
||||||
break;
|
|
||||||
case METHOD_SMB:
|
|
||||||
SMB_ReadFile(sz_buffer, maxRequiredSize, offset, smbfile);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
*buffer = sz_buffer;
|
|
||||||
*processedSize = maxRequiredSize;
|
|
||||||
s->pos += *processedSize;
|
|
||||||
|
|
||||||
if(maxRequiredSize > 1024) // only show progress for large reads
|
|
||||||
// this isn't quite right, but oh well
|
|
||||||
ShowProgress ((char *)"Loading...", s->pos, filelist[selection].length);
|
|
||||||
|
|
||||||
return SZ_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
// function used by the 7zip SDK to change the filepointer
|
|
||||||
SZ_RESULT SzFileSeekImp(void *object, CFileSize pos)
|
|
||||||
{
|
|
||||||
// the void* object is a SzFileInStream
|
|
||||||
SzFileInStream *s = (SzFileInStream *) object;
|
|
||||||
|
|
||||||
// check if the 7z SDK wants to move the pointer to somewhere after the EOF
|
|
||||||
if (pos >= s->len)
|
|
||||||
{
|
|
||||||
WaitPrompt((char *) "7z: Error - attempt to read after EOF!");
|
|
||||||
return SZE_FAIL;
|
|
||||||
}
|
|
||||||
|
|
||||||
// save new position and return
|
|
||||||
s->pos = pos;
|
|
||||||
return SZ_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
* SzParse
|
|
||||||
*
|
|
||||||
* Opens a 7z file, and parses it
|
|
||||||
* Right now doesn't parse 7z, since we'll always use the first file
|
|
||||||
* But it could parse the entire 7z for full browsing capability
|
|
||||||
***************************************************************************/
|
|
||||||
|
|
||||||
int SzParse(char * filepath, int method)
|
|
||||||
{
|
|
||||||
int nbfiles = 0;
|
|
||||||
|
|
||||||
// save the offset and the length of this file inside the archive stream structure
|
|
||||||
SzArchiveStream.offset = filelist[selection].offset;
|
|
||||||
SzArchiveStream.len = filelist[selection].length;
|
|
||||||
SzArchiveStream.pos = 0;
|
|
||||||
|
|
||||||
// open file
|
|
||||||
switch (method)
|
|
||||||
{
|
|
||||||
case METHOD_SD:
|
|
||||||
case METHOD_USB:
|
|
||||||
fatfile = fopen (filepath, "rb");
|
|
||||||
if(!fatfile)
|
|
||||||
return 0;
|
|
||||||
break;
|
|
||||||
case METHOD_SMB:
|
|
||||||
smbfile = OpenSMBFile(filepath);
|
|
||||||
if(!smbfile)
|
|
||||||
return 0;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// set szMethod to current chosen load method
|
|
||||||
szMethod = method;
|
|
||||||
|
|
||||||
// set handler functions for reading data from FAT/SMB/DVD
|
|
||||||
SzArchiveStream.InStream.Read = SzFileReadImp;
|
|
||||||
SzArchiveStream.InStream.Seek = SzFileSeekImp;
|
|
||||||
|
|
||||||
// set default 7Zip SDK handlers for allocation and freeing memory
|
|
||||||
SzAllocImp.Alloc = SzAlloc;
|
|
||||||
SzAllocImp.Free = SzFree;
|
|
||||||
SzAllocTempImp.Alloc = SzAllocTemp;
|
|
||||||
SzAllocTempImp.Free = SzFreeTemp;
|
|
||||||
|
|
||||||
// prepare CRC and 7Zip database structures
|
|
||||||
InitCrcTable();
|
|
||||||
SzArDbExInit(&SzDb);
|
|
||||||
|
|
||||||
// open the archive
|
|
||||||
SzRes = SzArchiveOpen(&SzArchiveStream.InStream, &SzDb, &SzAllocImp,
|
|
||||||
&SzAllocTempImp);
|
|
||||||
|
|
||||||
if (SzRes != SZ_OK)
|
|
||||||
{
|
|
||||||
SzDisplayError(SzRes);
|
|
||||||
// free memory used by the 7z SDK
|
|
||||||
SzClose();
|
|
||||||
}
|
|
||||||
else // archive opened successfully
|
|
||||||
{
|
|
||||||
if(SzDb.Database.NumFiles > 0)
|
|
||||||
{
|
|
||||||
// Parses the 7z into a full file listing
|
|
||||||
|
|
||||||
// erase all previous entries
|
|
||||||
memset(&filelist, 0, sizeof(FILEENTRIES) * MAXFILES);
|
|
||||||
|
|
||||||
// add '..' folder in case the user wants exit the 7z
|
|
||||||
strncpy(filelist[0].displayname, "..", 2);
|
|
||||||
filelist[0].flags = 1;
|
|
||||||
filelist[0].offset = dvddir;
|
|
||||||
filelist[0].length = dvddirlength;
|
|
||||||
|
|
||||||
// get contents and parse them into file list structure
|
|
||||||
unsigned int SzI, SzJ;
|
|
||||||
SzJ = 1;
|
|
||||||
for (SzI = 0; SzI < SzDb.Database.NumFiles; SzI++)
|
|
||||||
{
|
|
||||||
SzF = SzDb.Database.Files + SzI;
|
|
||||||
|
|
||||||
// skip directories
|
|
||||||
if (SzF->IsDirectory)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
// do not exceed MAXFILES to avoid possible buffer overflows
|
|
||||||
if (SzJ == (MAXFILES - 1))
|
|
||||||
break;
|
|
||||||
|
|
||||||
// parse information about this file to the dvd file list structure
|
|
||||||
strncpy(filelist[SzJ].filename, SzF->Name, MAXJOLIET); // copy joliet name (useless...)
|
|
||||||
filelist[SzJ].filename[MAXJOLIET] = 0; // terminate string
|
|
||||||
strncpy(filelist[SzJ].displayname, SzF->Name, MAXDISPLAY+1); // crop name for display
|
|
||||||
filelist[SzJ].length = SzF->Size; // filesize
|
|
||||||
filelist[SzJ].offset = SzI; // the extraction function identifies the file with this number
|
|
||||||
filelist[SzJ].flags = 0; // only files will be displayed (-> no flags)
|
|
||||||
SzJ++;
|
|
||||||
}
|
|
||||||
|
|
||||||
// update maxfiles and select the first entry
|
|
||||||
offset = selection = 0;
|
|
||||||
nbfiles = SzJ;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
SzArDbExFree(&SzDb, SzAllocImp.Free);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// close file
|
|
||||||
switch (method)
|
|
||||||
{
|
|
||||||
case METHOD_SD:
|
|
||||||
case METHOD_USB:
|
|
||||||
fclose(fatfile);
|
|
||||||
break;
|
|
||||||
case METHOD_SMB:
|
|
||||||
SMB_CloseFile (smbfile);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return nbfiles;
|
|
||||||
}
|
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
* SzClose
|
|
||||||
*
|
|
||||||
* Closes a 7z file
|
|
||||||
***************************************************************************/
|
|
||||||
|
|
||||||
void SzClose()
|
|
||||||
{
|
|
||||||
if(SzDb.Database.NumFiles > 0)
|
|
||||||
SzArDbExFree(&SzDb, SzAllocImp.Free);
|
|
||||||
}
|
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
* SzExtractFile
|
|
||||||
*
|
|
||||||
* Extracts the given file # into the buffer specified
|
|
||||||
* Must parse the 7z BEFORE running this function
|
|
||||||
***************************************************************************/
|
|
||||||
|
|
||||||
int SzExtractFile(int i, unsigned char *buffer)
|
|
||||||
{
|
|
||||||
// prepare some variables
|
|
||||||
SzBlockIndex = 0xFFFFFFFF;
|
|
||||||
SzOffset = 0;
|
|
||||||
|
|
||||||
// Unzip the file
|
|
||||||
|
|
||||||
SzRes = SzExtract2(
|
|
||||||
&SzArchiveStream.InStream,
|
|
||||||
&SzDb,
|
|
||||||
i, // index of file
|
|
||||||
&SzBlockIndex, // index of solid block
|
|
||||||
&buffer,
|
|
||||||
&SzBufferSize,
|
|
||||||
&SzOffset, // offset of stream for required file in *outBuffer
|
|
||||||
&SzOutSizeProcessed, // size of file in *outBuffer
|
|
||||||
&SzAllocImp,
|
|
||||||
&SzAllocTempImp);
|
|
||||||
|
|
||||||
// close 7Zip archive and free memory
|
|
||||||
SzClose();
|
|
||||||
|
|
||||||
// check for errors
|
|
||||||
if(SzRes != SZ_OK)
|
|
||||||
{
|
|
||||||
// display error message
|
|
||||||
SzDisplayError(SzRes);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return SzOutSizeProcessed;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -12,12 +12,11 @@
|
|||||||
|
|
||||||
#include <smb.h>
|
#include <smb.h>
|
||||||
|
|
||||||
int IsZipFile (char *buffer);
|
extern int IsZipFile (char *buffer);
|
||||||
char * GetFirstZipFilename(int method);
|
|
||||||
int UnZipBuffer (unsigned char *outbuffer, int method);
|
int UnZipFile (unsigned char *outbuffer, FILE* infile); // Reading from FAT
|
||||||
int SzParse(char * filepath, int method);
|
int UnZipFile (unsigned char *outbuffer, u64 inoffset); // Reading from DVD
|
||||||
int SzExtractFile(int i, unsigned char *buffer);
|
int UnZipFile (unsigned char *outbuffer, SMBFILE infile); // Reading from SMB
|
||||||
void SzClose();
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Zip file header definition
|
* Zip file header definition
|
||||||
|
19212
source/ngc/images/bg.h
19212
source/ngc/images/bg.h
File diff suppressed because it is too large
Load Diff
@ -5,71 +5,135 @@
|
|||||||
#ifndef _IMGSAVEICON_
|
#ifndef _IMGSAVEICON_
|
||||||
#define _IMGSAVEICON_
|
#define _IMGSAVEICON_
|
||||||
|
|
||||||
const unsigned long saveicon[32*32] = {
|
const unsigned short saveicon[1024] = {
|
||||||
0x579A5753, 0x579A5753, 0x579A5753, 0x579A5753, 0x579A5753, 0x579A5753, 0x579A5753, 0x579A5753,
|
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
|
||||||
0x579A5753, 0x579A5753, 0x579A5753, 0x579A5753, 0x579A5753, 0x579A5753, 0x579A5753, 0x579A5753,
|
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
|
||||||
0x589B5852, 0x589B5852, 0x589B5852, 0x589B5852, 0x589B5852, 0x589B5852, 0x589B5852, 0x589B5852,
|
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
|
||||||
0x589B5852, 0x589B5852, 0x589B5852, 0x589B5852, 0x589B5852, 0x589B5852, 0x589B5852, 0x589B5852,
|
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
|
||||||
0x589B5852, 0x589B5852, 0x589B5852, 0x589B5852, 0x589B5852, 0x589B5852, 0x589B5852, 0x589B5852,
|
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
|
||||||
0x589B5852, 0x589B5852, 0x589B5852, 0x589B5852, 0x589B5852, 0x589B5852, 0x589B5852, 0x589B5852,
|
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
|
||||||
0x599B5951, 0x599B5951, 0x599B5951, 0x599B5951, 0x599B5951, 0x599B5951, 0x599B5951, 0x599B5951,
|
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
|
||||||
0x599B5951, 0x599B5951, 0x599B5951, 0x599B5951, 0x5A9B5951, 0x599B5951, 0x599B5951, 0x599B5951,
|
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
|
||||||
0x5A9B5A51, 0x5A9B5A51, 0x5A9B5A51, 0x5A9B5A51, 0x5A9B5A51, 0x5A9B5A51, 0x5A9B5A51, 0x5A9B5A51,
|
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
|
||||||
0x5A9B5A51, 0x5A9B5A51, 0x5A9B5A51, 0x5A9B5A51, 0x5A9B5A51, 0x5A9B5A51, 0x5A9B5A51, 0x5A9B5A51,
|
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
|
||||||
0x5B9C5B51, 0x5B9C5B51, 0x5B9C5B51, 0x5B9C5B51, 0x5B9C5B51, 0x5B9C5B51, 0x5B9C5B51, 0x5B9C5B51,
|
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
|
||||||
0x5B9C5B51, 0x5B9C5B51, 0x5B9C5B51, 0x5B9C5B51, 0x5B9C5B51, 0x5B9C5B51, 0x5B9C5C50, 0x5B9C5B51,
|
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
|
||||||
0x5C9C5C50, 0x5C9C5C50, 0x5C9C5C50, 0x5C9C5C50, 0x5C9C5C50, 0x5C9C5C50, 0x5C9C5C50, 0x5C9C5C50,
|
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
|
||||||
0x5C9C5C50, 0x5C9C5C50, 0x5C9C5C50, 0x5C9C5C50, 0x5C9C5C50, 0x5C9C5C50, 0x5C9C5C50, 0x5C9C5C50,
|
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
|
||||||
0x5D9C5C50, 0x5C9C5D50, 0x5C9C5C50, 0x5D9C5C50, 0x5D9C5C50, 0x5D9C5C50, 0x5D9C5C50, 0x5C9C5C50,
|
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
|
||||||
0x5C9C5C50, 0x5C9C5D50, 0x5C9C5C50, 0x5C9C5C50, 0x5C9C5C50, 0x5C9C5C50, 0x5C9C5C50, 0x5C9C5D50,
|
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
|
||||||
0x5D9C5D50, 0x5E9C5E4F, 0x5D9C5E4F, 0x5E9C5D4F, 0x5E9C5E4F, 0x5D9C5E4F, 0x5D9C5E4F, 0x5E9C5D4F,
|
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
|
||||||
0x5E9C5E4F, 0x5E9C5E4F, 0x5D9C5D50, 0x5D9C5D50, 0x5D9C5D50, 0x5E9C5E4F, 0x5E9C5D4F, 0x5E9C5D4F,
|
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
|
||||||
0x5E9D5E4F, 0x5E9D5E4F, 0x5E9D5E4F, 0x5E9D5E4F, 0x5E9D5E4F, 0x5E9D5E4F, 0x5F9D5E4F, 0x5E9D5E4F,
|
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
|
||||||
0x5E9D5E4F, 0x5E9D5F4F, 0x5E9D5E4F, 0x5F9D5E4F, 0x5E9D5F4F, 0x5E9D5E4F, 0x5E9D5E4F, 0x5F9D5E4F,
|
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
|
||||||
0x5F9B5351, 0x27860075, 0x00862775, 0x5F9D5F4E, 0x27860075, 0x12882770, 0x00800080, 0x00800080,
|
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xE73F,
|
||||||
0x00800080, 0x1F8F4765, 0x5F9D5F4F, 0x5A93275E, 0x00800080, 0x26914D62, 0x5F9D5F4E, 0x5F9D5F4E,
|
0xFFFF, 0xFFFF, 0xB5BF, 0x801F, 0xFFFF, 0xD29F, 0x801F, 0x801F,
|
||||||
0x60952C5B, 0x6551C69C, 0xCD631B91, 0x53974658, 0x3761D091, 0xA766468F, 0xD658D898, 0xD85AD897,
|
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xA11E, 0x843C, 0x8439, 0x9CF7,
|
||||||
0xD755D399, 0x89741F81, 0x549B6051, 0x337C6179, 0xD454D49A, 0x7B77267F, 0x609D604E, 0x609D604E,
|
0x801F, 0x801F, 0x801C, 0x8018, 0x801F, 0x801F, 0x801C, 0x8018,
|
||||||
0x609A4654, 0x2F53BB9B, 0xC5595197, 0x3A903363, 0x5E58C998, 0x5D69428D, 0xCA4ACBA0, 0xCC4CCC9F,
|
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xEB5C, 0xFFFF, 0xFFFF, 0xFFFF,
|
||||||
0xCB49C7A1, 0xC554699A, 0x2D95615B, 0x136EA387, 0xD050D09C, 0xBB67068D, 0x609E604E, 0x619D604E,
|
0x800F, 0xB9D3, 0xFFFF, 0xFFFF, 0x8013, 0x8008, 0xDAD7, 0xFFFF,
|
||||||
0x629D624D, 0x0D5E9891, 0xBC4D779F, 0x27881370, 0x9E4AC1A1, 0x326B3E8C, 0xBA3ABBAA, 0x25790084,
|
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
|
||||||
0x0062A292, 0xBC459AA4, 0x138F5465, 0x1A60C893, 0xBE4DCC9E, 0xC4583198, 0x48996254, 0x629D624D,
|
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
|
||||||
0x639E624D, 0x276A6386, 0xB03CA4A9, 0x0D7D197F, 0xBE3F9EA7, 0x0D733985, 0xAF31B3B0, 0x24780084,
|
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
|
||||||
0x00609E93, 0xB94C589F, 0x34903564, 0x5851BF9C, 0x7350B49D, 0xBB466BA3, 0x2795625C, 0x629E634D,
|
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
|
||||||
0x639E634C, 0x427B3578, 0xA42BB1B4, 0x3167498E, 0xB13E66A8, 0x2776367F, 0xA426A7B7, 0xAC2DAFB2,
|
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
|
||||||
0xAF30B1B0, 0x786C2186, 0x5E921A60, 0x853EB2A8, 0x2E5D6A94, 0xAE3293AF, 0x0D916363, 0x639E634C,
|
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
|
||||||
0x659F644C, 0x65900664, 0x9529A3B7, 0x4E4D6F9F, 0xA34041A7, 0x3C7A347A, 0x9F26A0B9, 0xA126A2B9,
|
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
|
||||||
0xA225A3B8, 0xA74050A6, 0x2F811776, 0xAA2A9AB4, 0x006E418B, 0xA425A4B8, 0x20825070, 0x649F654C,
|
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
|
||||||
0x659E654C, 0x65931B5F, 0x73349EB2, 0x753695B0, 0x94570799, 0x437B3478, 0x9D289EBB, 0x1F770085,
|
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
|
||||||
0x005F7595, 0xA12998B7, 0x076B4B8B, 0xA1269FB9, 0x9E289EBB, 0x9E27A0B9, 0x4B73357F, 0x659E654C,
|
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
|
||||||
0x659F654C, 0x65983C56, 0x3D439AAA, 0x9A299ABC, 0x70641B8F, 0x437C3378, 0x9B299CBB, 0x1F770085,
|
0xFFFF, 0x801F, 0x801F, 0x885F, 0xFFFF, 0x98D6, 0x801F, 0x801F,
|
||||||
0x00626993, 0x9E2B93B9, 0x07617393, 0x992A97BC, 0x962C96BD, 0x982A9BBC, 0x7E5F1492, 0x659F654C,
|
0xFFFF, 0xFFFF, 0xFFFF, 0x843C, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
|
||||||
0x679F674B, 0x669D594E, 0x144F97A2, 0x962C96BD, 0x46743680, 0x447B3278, 0x972B97BD, 0x972B97BD,
|
0xFBDF, 0x801E, 0x801B, 0x8017, 0x801E, 0x801B, 0x8018, 0x8015,
|
||||||
0x972B97BD, 0x983965B2, 0x0A558D9E, 0x8A560A9F, 0x00800080, 0x454197AD, 0x9A4E14A2, 0x599D674E,
|
0x801A, 0x8018, 0x8015, 0x8011, 0x8016, 0x8014, 0x8011, 0x800D,
|
||||||
0x679F674A, 0x679F674A, 0x14617793, 0x932D93BF, 0x14875A6C, 0x447C3178, 0x932D92BF, 0x922D92BF,
|
0x8012, 0x800B, 0x8848, 0xFFFF, 0x8010, 0x8009, 0x8003, 0xFFFF,
|
||||||
0x922D92BF, 0x586C228A, 0x444393AE, 0x6B651B8F, 0x679C534F, 0x1D4D95A5, 0x974148AC, 0x37976756,
|
0x800C, 0x8007, 0x8006, 0xFFFF, 0x8008, 0x8005, 0xA52E, 0xFFFF,
|
||||||
0x68A0674A, 0x68A0684A, 0x3F8C146A, 0x00800080, 0x2A966859, 0x68962A59, 0x00800080, 0x00800080,
|
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
|
||||||
0x00800080, 0x2A93545F, 0x2A860075, 0x1B8E4766, 0x68A0674A, 0x2A860075, 0x00862A74, 0x639F674B,
|
0xFFFF, 0xFFFF, 0xFBBD, 0xF1EF, 0xFFFF, 0xF508, 0xF000, 0xEC00,
|
||||||
0x699F684A, 0x699F694A, 0x699F684A, 0x699F694A, 0x699F694A, 0x699F694A, 0x699F694A, 0x699F694A,
|
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
|
||||||
0x699F694A, 0x699F694A, 0x699F694A, 0x699F694A, 0x699F694A, 0x699F694A, 0x699F694A, 0x699F694A,
|
0xE56B, 0xE16B, 0xE673, 0xFFFF, 0xE800, 0xDC00, 0xCC00, 0xB400,
|
||||||
0x6AA06949, 0x69A0694A, 0x69A06A49, 0x69A06A49, 0x6AA06949, 0x69A0694A, 0x69A0694A, 0x69A0694A,
|
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
|
||||||
0x6AA06949, 0x69A06A49, 0x69A06A49, 0x69A0694A, 0x69A0694A, 0x6AA06949, 0x69A0694A, 0x69A0694A,
|
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xDE94, 0xFFFF, 0xFFFF, 0xFFFF,
|
||||||
0x6BA06A49, 0x6AA06A49, 0x6BA06B49, 0x6AA06B49, 0x6AA06B49, 0x6BA06B49, 0x6AA06B49, 0x6BA06B49,
|
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
|
||||||
0x6BA06B49, 0x6BA06A49, 0x6BA06A49, 0x6AA06B49, 0x6BA06B49, 0x6BA06A49, 0x6AA06B49, 0x6BA06B49,
|
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xEBBA,
|
||||||
0x6CA16B48, 0x6BA16B48, 0x6BA16B48, 0x6BA16B48, 0x6BA16B48, 0x6BA16B48, 0x6BA16B48, 0x6BA16B48,
|
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
|
||||||
0x6BA16B48, 0x6BA16B48, 0x6BA16B48, 0x6BA16B48, 0x6BA16B48, 0x6BA16B48, 0x6BA16B48, 0x6BA16B48,
|
0xFFFF, 0xFFFF, 0xEFBA, 0xE378, 0xB2EB, 0x9AA4, 0x9AA5, 0x9AA5,
|
||||||
0x6CA16C48, 0x6CA16C48, 0x6CA16C48, 0x6CA16C48, 0x6CA16C48, 0x6CA16C48, 0x6CA16C48, 0x6CA16C48,
|
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
|
||||||
0x6CA16C48, 0x6CA16C48, 0x6CA16C48, 0x6CA16C48, 0x6CA16C48, 0x6CA16C48, 0x6CA16C48, 0x6CA16C48,
|
0xE778, 0xF3BC, 0xFFFF, 0xFFFF, 0x9A84, 0x9623, 0x91E3, 0xB66C,
|
||||||
0x6DA16C48, 0x6DA16D48, 0x6DA16D48, 0x6DA16D48, 0x6DA16C48, 0x6CA16D48, 0x6CA16D48, 0x6DA16D48,
|
0xD6BB, 0x800E, 0x800C, 0x8008, 0xFFFF, 0x8C6A, 0x8004, 0x8004,
|
||||||
0x6DA16D48, 0x6DA16D48, 0x6CA16D48, 0x6DA16D48, 0x6DA16D48, 0x6DA16D48, 0x6CA16D48, 0x6DA16D48,
|
0xFFFF, 0xFFFF, 0xB191, 0xDAD8, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
|
||||||
0x6EA16E47, 0x6DA16D47, 0x6DA16D47, 0x6DA16D47, 0x6DA16D47, 0x6EA16D47, 0x6DA16D47, 0x6DA16E47,
|
0x8006, 0x8004, 0xFFFF, 0xFFFF, 0x8006, 0xF39D, 0xFFFF, 0xFA94,
|
||||||
0x6DA16D47, 0x6DA16D47, 0x6DA16E47, 0x6DA16D47, 0x6DA16D47, 0x6EA16D47, 0x6DA16D47, 0x6DA16D47,
|
0xFFFF, 0xFFFF, 0xFFFF, 0xEC21, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
|
||||||
0x6EA16E46, 0x6EA16E46, 0x6EA16E47, 0x6EA16E46, 0x6EA16E46, 0x6EA16E46, 0x6EA16E46, 0x6EA16E47,
|
0xF484, 0xF800, 0xF800, 0xF000, 0xF800, 0xF800, 0xFD6B, 0xF8C6,
|
||||||
0x6EA16E46, 0x6EA16E47, 0x6EA16E46, 0x6EA16E46, 0x6EA16E47, 0x6EA16E46, 0x6EA16E46, 0x6EA16E46,
|
0xF400, 0xF400, 0xFDEF, 0xF4A5, 0xFF18, 0xEC63, 0xE400, 0xE000,
|
||||||
0x6FA26F47, 0x6FA16E46, 0x6FA16E46, 0x6FA26F47, 0x6FA26F47, 0x6FA26F47, 0x6FA26F47, 0x6FA26F47,
|
0xE800, 0xE000, 0xD400, 0xC400, 0xE400, 0xE000, 0xD000, 0xC400,
|
||||||
0x6FA26F47, 0x6FA26F47, 0x6FA26F47, 0x6FA26F47, 0x6FA26F47, 0x6FA26F47, 0x6FA26F47, 0x6FA26F47,
|
0xE000, 0xD800, 0xCC00, 0xC000, 0xD800, 0xD000, 0xC400, 0xB800,
|
||||||
0x70A27046, 0x70A27046, 0x70A27046, 0x70A27046, 0x70A27046, 0x70A27046, 0x70A27046, 0x70A27046,
|
0xA400, 0xD673, 0xFFFF, 0xFFFF, 0xB400, 0x9000, 0xFFFF, 0xFFFF,
|
||||||
0x70A27046, 0x70A27046, 0x70A27046, 0x70A27046, 0x70A27046, 0x70A27046, 0x70A27046, 0x70A27046,
|
0xB000, 0x9000, 0xFFFF, 0xFFFF, 0xA800, 0x9000, 0xFFFF, 0xFFFF,
|
||||||
|
0xFFFF, 0xFFFF, 0xDB75, 0x9AE4, 0xFFFF, 0xFFFF, 0x9A84, 0xA6E7,
|
||||||
|
0xFFFF, 0xFFFF, 0xA1E7, 0x9604, 0xFFFF, 0xFFFF, 0xFFFF, 0x8D03,
|
||||||
|
0xA707, 0xA708, 0xAF2A, 0xAF2A, 0xA6E7, 0xA2C7, 0xBF4E, 0xCB71,
|
||||||
|
0x9E46, 0x9E26, 0x9A25, 0x9604, 0x80E0, 0x8922, 0x8D22, 0x8D22,
|
||||||
|
0xA2C7, 0xA2A7, 0x9E66, 0x95E4, 0xA2A6, 0x9E46, 0x9E25, 0x95C4,
|
||||||
|
0x99E5, 0x95C4, 0x9163, 0x8D02, 0x88E2, 0x84A1, 0x8060, 0x8020,
|
||||||
|
0x8500, 0xF7BD, 0xFFFF, 0xFFFF, 0x8901, 0xA148, 0xFFFF, 0xFFFF,
|
||||||
|
0x8040, 0xB9ED, 0xFFFF, 0xFFFF, 0x9926, 0xFFFF, 0xFFFF, 0xFFFF,
|
||||||
|
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
|
||||||
|
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
|
||||||
|
0xFFFF, 0xFFFF, 0xE529, 0xD400, 0xFFFF, 0xFFFF, 0xFFFF, 0xD4C6,
|
||||||
|
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
|
||||||
|
0xD000, 0xC400, 0xBC00, 0xB000, 0xC000, 0xB800, 0xAC00, 0xA000,
|
||||||
|
0xA800, 0xA800, 0x9C00, 0x9400, 0xC18C, 0x8C00, 0x8C00, 0x8C00,
|
||||||
|
0x9C00, 0x8C00, 0xFFFF, 0xFFFF, 0x9400, 0x8C00, 0xFFFF, 0xFFFF,
|
||||||
|
0x8800, 0xDEB5, 0xFFFF, 0xFFFF, 0xE2D6, 0xFFFF, 0xFFFF, 0xFFFF,
|
||||||
|
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
|
||||||
|
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
|
||||||
|
0xD6D5, 0xAD8A, 0x8CC3, 0x8060, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
|
||||||
|
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
|
||||||
|
0x8060, 0x90E4, 0xB1CC, 0xE759, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
|
||||||
|
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFF, 0xF7AF,
|
||||||
|
0xFFFF, 0xFFFF, 0xFBDC, 0xF7B1, 0xFFFB, 0xFFE2, 0xFFE0, 0xFFE0,
|
||||||
|
0xFFE0, 0xFFE0, 0xFFE0, 0xFFE0, 0xFFE0, 0xFFE0, 0xFFE0, 0xFFE5,
|
||||||
|
0xF38C, 0xEF6A, 0xEB4B, 0xEB4F, 0xFFE0, 0xFBC0, 0xF7A0, 0xEB40,
|
||||||
|
0xFFE0, 0xFFE0, 0xFBC0, 0xF7A0, 0xFFF5, 0xFFE4, 0xF380, 0xEF60,
|
||||||
|
0xEF76, 0xFFFF, 0xFFFF, 0xFFFF, 0xE300, 0xCE60, 0xD6AB, 0xFFFF,
|
||||||
|
0xEB40, 0xE300, 0xCE60, 0xB180, 0xE720, 0xDEE0, 0xCE60, 0xB180,
|
||||||
|
0xF7BD, 0xB96B, 0xDAB4, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
|
||||||
|
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xB9CA, 0xFFFF, 0xFFFF, 0xFFFF,
|
||||||
|
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
|
||||||
|
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
|
||||||
|
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
|
||||||
|
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
|
||||||
|
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
|
||||||
|
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
|
||||||
|
0xFFFF, 0xFFFF, 0xFFFF, 0xF399, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
|
||||||
|
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
|
||||||
|
0xD280, 0xEB40, 0xEB40, 0xEB40, 0xDAD1, 0xAD60, 0xC200, 0xCA40,
|
||||||
|
0xFFFF, 0xF7BE, 0xBDEB, 0x98C0, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
|
||||||
|
0xEB40, 0xE720, 0xE300, 0xDAC0, 0xCA40, 0xC620, 0xC200, 0xBDE0,
|
||||||
|
0x9080, 0x94A0, 0x94A0, 0x9080, 0xFBDD, 0xE738, 0xE337, 0xE738,
|
||||||
|
0xD280, 0xCA40, 0xB5A0, 0x98C0, 0xB180, 0xA100, 0x94A0, 0x9080,
|
||||||
|
0x8C60, 0x9080, 0xC20C, 0xFFFF, 0xF7BD, 0xFFFF, 0xFFFF, 0xFFFF,
|
||||||
|
0xB9C9, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFF,
|
||||||
|
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
|
||||||
|
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
|
||||||
|
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
|
||||||
|
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
|
||||||
|
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
|
||||||
|
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
|
||||||
|
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
|
||||||
|
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
|
||||||
|
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
|
||||||
|
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
|
||||||
|
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
|
||||||
|
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
|
||||||
|
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
|
||||||
|
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
|
||||||
|
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
|
||||||
|
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
|
||||||
|
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
|
||||||
|
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
|
||||||
|
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -26,6 +26,8 @@
|
|||||||
#include "input.h"
|
#include "input.h"
|
||||||
#include "tbtime.h"
|
#include "tbtime.h"
|
||||||
|
|
||||||
|
#define MAXJP 10
|
||||||
|
|
||||||
#define VBA_BUTTON_A 1
|
#define VBA_BUTTON_A 1
|
||||||
#define VBA_BUTTON_B 2
|
#define VBA_BUTTON_B 2
|
||||||
#define VBA_BUTTON_SELECT 4
|
#define VBA_BUTTON_SELECT 4
|
||||||
@ -82,13 +84,14 @@ unsigned int ncpadmap[] = {
|
|||||||
WPAD_BUTTON_2, WPAD_BUTTON_1
|
WPAD_BUTTON_2, WPAD_BUTTON_1
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#ifdef HW_RVL
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* WPAD_Stick
|
* WPAD_StickX
|
||||||
*
|
*
|
||||||
* Get X/Y value from Wii Joystick (classic, nunchuk) input
|
* Get X value from Wii Joystick (classic, nunchuk) input
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
|
|
||||||
s8 WPAD_Stick(u8 chan, u8 right, int axis)
|
s8 WPAD_StickX(u8 chan,u8 right)
|
||||||
{
|
{
|
||||||
float mag = 0.0;
|
float mag = 0.0;
|
||||||
float ang = 0.0;
|
float ang = 0.0;
|
||||||
@ -122,19 +125,63 @@ s8 WPAD_Stick(u8 chan, u8 right, int axis)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* calculate x/y value (angle need to be converted into radian) */
|
/* calculate X value (angle need to be converted into radian) */
|
||||||
if (mag > 1.0) mag = 1.0;
|
if (mag > 1.0) mag = 1.0;
|
||||||
else if (mag < -1.0) mag = -1.0;
|
else if (mag < -1.0) mag = -1.0;
|
||||||
double val;
|
double val = mag * sin((PI * ang)/180.0f);
|
||||||
|
|
||||||
if(axis == 0) // x-axis
|
|
||||||
val = mag * sin((PI * ang)/180.0f);
|
|
||||||
else // y-axis
|
|
||||||
val = mag * cos((PI * ang)/180.0f);
|
|
||||||
|
|
||||||
return (s8)(val * 128.0f);
|
return (s8)(val * 128.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* WPAD_StickY
|
||||||
|
*
|
||||||
|
* Get Y value from Wii Joystick (classic, nunchuk) input
|
||||||
|
***************************************************************************/
|
||||||
|
|
||||||
|
s8 WPAD_StickY(u8 chan, u8 right)
|
||||||
|
{
|
||||||
|
float mag = 0.0;
|
||||||
|
float ang = 0.0;
|
||||||
|
WPADData *data = WPAD_Data(chan);
|
||||||
|
|
||||||
|
switch (data->exp.type)
|
||||||
|
{
|
||||||
|
case WPAD_EXP_NUNCHUK:
|
||||||
|
case WPAD_EXP_GUITARHERO3:
|
||||||
|
if (right == 0)
|
||||||
|
{
|
||||||
|
mag = data->exp.nunchuk.js.mag;
|
||||||
|
ang = data->exp.nunchuk.js.ang;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case WPAD_EXP_CLASSIC:
|
||||||
|
if (right == 0)
|
||||||
|
{
|
||||||
|
mag = data->exp.classic.ljs.mag;
|
||||||
|
ang = data->exp.classic.ljs.ang;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mag = data->exp.classic.rjs.mag;
|
||||||
|
ang = data->exp.classic.rjs.ang;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* calculate X value (angle need to be converted into radian) */
|
||||||
|
if (mag > 1.0) mag = 1.0;
|
||||||
|
else if (mag < -1.0) mag = -1.0;
|
||||||
|
double val = mag * cos((PI * ang)/180.0f);
|
||||||
|
|
||||||
|
return (s8)(val * 128.0f);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* DecodeJoy
|
* DecodeJoy
|
||||||
*
|
*
|
||||||
@ -146,15 +193,16 @@ u32 DecodeJoy(unsigned short pad)
|
|||||||
{
|
{
|
||||||
signed char pad_x = PAD_StickX (pad);
|
signed char pad_x = PAD_StickX (pad);
|
||||||
signed char pad_y = PAD_StickY (pad);
|
signed char pad_y = PAD_StickY (pad);
|
||||||
signed char gc_px = PAD_SubStickX (0);
|
|
||||||
u32 jp = PAD_ButtonsHeld (pad);
|
u32 jp = PAD_ButtonsHeld (pad);
|
||||||
u32 J = 0;
|
unsigned char J = 0;
|
||||||
|
|
||||||
#ifdef HW_RVL
|
#ifdef HW_RVL
|
||||||
signed char wm_ax = WPAD_Stick ((u8)pad, 0, 0);
|
signed char wm_ax = 0;
|
||||||
signed char wm_ay = WPAD_Stick ((u8)pad, 0, 1);
|
signed char wm_ay = 0;
|
||||||
u32 wp = WPAD_ButtonsHeld (pad);
|
u32 wp = 0;
|
||||||
signed char wm_sx = WPAD_Stick (0,1,0); // CC right joystick
|
wm_ax = WPAD_StickX ((u8)pad, 0);
|
||||||
|
wm_ay = WPAD_StickY ((u8)pad, 0);
|
||||||
|
wp = WPAD_ButtonsHeld (pad);
|
||||||
|
|
||||||
u32 exp_type;
|
u32 exp_type;
|
||||||
if ( WPAD_Probe(pad, &exp_type) != 0 ) exp_type = WPAD_EXP_NONE;
|
if ( WPAD_Probe(pad, &exp_type) != 0 ) exp_type = WPAD_EXP_NONE;
|
||||||
@ -235,16 +283,6 @@ u32 DecodeJoy(unsigned short pad)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Turbo feature
|
|
||||||
if(
|
|
||||||
(gc_px > 70)
|
|
||||||
#ifdef HW_RVL
|
|
||||||
|| (wm_sx > 70)
|
|
||||||
|| ((wp & WPAD_BUTTON_A) && (wp & WPAD_BUTTON_B))
|
|
||||||
#endif
|
|
||||||
)
|
|
||||||
J |= VBA_SPEED;
|
|
||||||
|
|
||||||
/*** Report pressed buttons (gamepads) ***/
|
/*** Report pressed buttons (gamepads) ***/
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
@ -260,37 +298,20 @@ u32 DecodeJoy(unsigned short pad)
|
|||||||
J |= vbapadmap[i];
|
J |= vbapadmap[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((J & 48) == 48)
|
|
||||||
J &= ~16;
|
|
||||||
if ((J & 192) == 192)
|
|
||||||
J &= ~128;
|
|
||||||
|
|
||||||
return J;
|
return J;
|
||||||
}
|
}
|
||||||
u32 GetJoy()
|
u32 GetJoy()
|
||||||
{
|
{
|
||||||
int pad = 0;
|
int pad = 0;
|
||||||
|
u32 res = 0;
|
||||||
|
|
||||||
s8 gc_px = PAD_SubStickX (0);
|
s8 gc_px = PAD_SubStickX (0);
|
||||||
s8 gc_py = PAD_SubStickY (0);
|
|
||||||
|
|
||||||
#ifdef HW_RVL
|
#ifdef HW_RVL
|
||||||
s8 wm_sx = WPAD_Stick (0,1,0);
|
s8 wm_sx = WPAD_StickX (0,1);
|
||||||
s8 wm_sy = WPAD_Stick (0,1,1);
|
|
||||||
u32 wm_pb = WPAD_ButtonsHeld (0); // wiimote / expansion button info
|
u32 wm_pb = WPAD_ButtonsHeld (0); // wiimote / expansion button info
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Check for video zoom
|
|
||||||
if (GCSettings.NGCZoom)
|
|
||||||
{
|
|
||||||
if (gc_py < -36 || gc_py > 36)
|
|
||||||
zoom ((float) gc_py / -36);
|
|
||||||
#ifdef HW_RVL
|
|
||||||
if (wm_sy < -36 || wm_sy > 36)
|
|
||||||
zoom ((float) wm_sy / -36);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
// request to go back to menu
|
// request to go back to menu
|
||||||
if ((gc_px < -70)
|
if ((gc_px < -70)
|
||||||
#ifdef HW_RVL
|
#ifdef HW_RVL
|
||||||
@ -302,24 +323,28 @@ u32 GetJoy()
|
|||||||
{
|
{
|
||||||
if (GCSettings.AutoSave == 1)
|
if (GCSettings.AutoSave == 1)
|
||||||
{
|
{
|
||||||
SaveBatteryOrState(GCSettings.SaveMethod, 0, SILENT); // save battery
|
SaveBattery(GCSettings.SaveMethod, SILENT);
|
||||||
}
|
}
|
||||||
else if (GCSettings.AutoSave == 2)
|
else if (GCSettings.AutoSave == 2)
|
||||||
{
|
{
|
||||||
SaveBatteryOrState(GCSettings.SaveMethod, 1, SILENT); // save state
|
SaveState(GCSettings.SaveMethod, SILENT);
|
||||||
}
|
}
|
||||||
else if(GCSettings.AutoSave == 3)
|
else if(GCSettings.AutoSave == 3)
|
||||||
{
|
{
|
||||||
SaveBatteryOrState(GCSettings.SaveMethod, 0, SILENT); // save battery
|
SaveBattery(GCSettings.SaveMethod, SILENT);
|
||||||
SaveBatteryOrState(GCSettings.SaveMethod, 1, SILENT); // save state
|
SaveState(GCSettings.SaveMethod, SILENT);
|
||||||
}
|
}
|
||||||
// change to menu video mode
|
|
||||||
ResetVideo_Menu ();
|
|
||||||
MainMenu(3);
|
MainMenu(3);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
return DecodeJoy(pad);
|
res = DecodeJoy(pad);
|
||||||
|
if ((res & 48) == 48)
|
||||||
|
res &= ~16;
|
||||||
|
if ((res & 192) == 192)
|
||||||
|
res &= ~128;
|
||||||
|
|
||||||
|
return res;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -15,14 +15,14 @@
|
|||||||
|
|
||||||
#define PI 3.14159265f
|
#define PI 3.14159265f
|
||||||
#define PADCAL 50
|
#define PADCAL 50
|
||||||
#define MAXJP 10
|
|
||||||
|
|
||||||
extern unsigned int gcpadmap[];
|
extern unsigned int gcpadmap[];
|
||||||
extern unsigned int wmpadmap[];
|
extern unsigned int wmpadmap[];
|
||||||
extern unsigned int ccpadmap[];
|
extern unsigned int ccpadmap[];
|
||||||
extern unsigned int ncpadmap[];
|
extern unsigned int ncpadmap[];
|
||||||
|
|
||||||
s8 WPAD_Stick(u8 chan,u8 right, int axis);
|
s8 WPAD_StickX(u8 chan,u8 right);
|
||||||
|
s8 WPAD_StickY(u8 chan, u8 right);
|
||||||
|
|
||||||
u32 GetJoy();
|
u32 GetJoy();
|
||||||
|
|
||||||
|
@ -25,6 +25,7 @@
|
|||||||
|
|
||||||
#define VERIFBUFFERSIZE 65536
|
#define VERIFBUFFERSIZE 65536
|
||||||
static u8 SysArea[CARD_WORKAREA] ATTRIBUTE_ALIGN (32);
|
static u8 SysArea[CARD_WORKAREA] ATTRIBUTE_ALIGN (32);
|
||||||
|
extern unsigned char savebuffer[];
|
||||||
unsigned char verifbuffer[VERIFBUFFERSIZE] ATTRIBUTE_ALIGN (32);
|
unsigned char verifbuffer[VERIFBUFFERSIZE] ATTRIBUTE_ALIGN (32);
|
||||||
card_dir CardDir;
|
card_dir CardDir;
|
||||||
card_file CardFile;
|
card_file CardFile;
|
||||||
@ -67,7 +68,7 @@ bool TestCard(int slot, bool silent)
|
|||||||
|
|
||||||
/*** Initialize Card System ***/
|
/*** Initialize Card System ***/
|
||||||
memset (SysArea, 0, CARD_WORKAREA);
|
memset (SysArea, 0, CARD_WORKAREA);
|
||||||
CARD_Init ("VBA0", "00");
|
CARD_Init ("SNES", "00");
|
||||||
|
|
||||||
/*** Try to mount the card ***/
|
/*** Try to mount the card ***/
|
||||||
if (MountCard(slot, silent) == 0)
|
if (MountCard(slot, silent) == 0)
|
||||||
@ -135,7 +136,7 @@ VerifyMCFile (unsigned char *buf, int slot, char *filename, int datasize)
|
|||||||
|
|
||||||
/*** Initialize Card System ***/
|
/*** Initialize Card System ***/
|
||||||
memset (SysArea, 0, CARD_WORKAREA);
|
memset (SysArea, 0, CARD_WORKAREA);
|
||||||
CARD_Init ("VBA0", "00");
|
CARD_Init ("SNES", "00");
|
||||||
|
|
||||||
/*** Try to mount the card ***/
|
/*** Try to mount the card ***/
|
||||||
CardError = MountCard(slot, NOTSILENT);
|
CardError = MountCard(slot, NOTSILENT);
|
||||||
@ -214,7 +215,7 @@ LoadBufferFromMC (unsigned char *buf, int slot, char *filename, bool silent)
|
|||||||
|
|
||||||
/*** Initialize Card System ***/
|
/*** Initialize Card System ***/
|
||||||
memset (SysArea, 0, CARD_WORKAREA);
|
memset (SysArea, 0, CARD_WORKAREA);
|
||||||
CARD_Init ("VBA0", "00");
|
CARD_Init ("SNES", "00");
|
||||||
|
|
||||||
/*** Try to mount the card ***/
|
/*** Try to mount the card ***/
|
||||||
CardError = MountCard(slot, NOTSILENT);
|
CardError = MountCard(slot, NOTSILENT);
|
||||||
@ -278,7 +279,7 @@ SaveBufferToMC (unsigned char *buf, int slot, char *filename, int datasize, bool
|
|||||||
|
|
||||||
/*** Initialize Card System ***/
|
/*** Initialize Card System ***/
|
||||||
memset (SysArea, 0, CARD_WORKAREA);
|
memset (SysArea, 0, CARD_WORKAREA);
|
||||||
CARD_Init ("VBA0", "00");
|
CARD_Init ("SNES", "00");
|
||||||
|
|
||||||
/*** Try to mount the card ***/
|
/*** Try to mount the card ***/
|
||||||
CardError = MountCard(slot, NOTSILENT);
|
CardError = MountCard(slot, NOTSILENT);
|
||||||
|
@ -44,7 +44,7 @@ extern "C"
|
|||||||
extern void DrawMenu (char items[][50], char *title, int maxitems, int selected, int fontsize);
|
extern void DrawMenu (char items[][50], char *title, int maxitems, int selected, int fontsize);
|
||||||
|
|
||||||
extern int menu;
|
extern int menu;
|
||||||
extern bool ROMLoaded;
|
extern int ROMSize;
|
||||||
|
|
||||||
#define SOFTRESET_ADR ((volatile u32*)0xCC003024)
|
#define SOFTRESET_ADR ((volatile u32*)0xCC003024)
|
||||||
|
|
||||||
@ -83,9 +83,9 @@ LoadManager ()
|
|||||||
if ( loadROM == 1 ) // if ROM was loaded, load the battery / state
|
if ( loadROM == 1 ) // if ROM was loaded, load the battery / state
|
||||||
{
|
{
|
||||||
if (GCSettings.AutoLoad == 1)
|
if (GCSettings.AutoLoad == 1)
|
||||||
LoadBatteryOrState(GCSettings.SaveMethod, 0, SILENT); // load battery
|
LoadBattery(GCSettings.SaveMethod, SILENT);
|
||||||
else if (GCSettings.AutoLoad == 2)
|
else if (GCSettings.AutoLoad == 2)
|
||||||
LoadBatteryOrState(GCSettings.SaveMethod, 1, SILENT); // load state
|
LoadState(GCSettings.SaveMethod, SILENT);
|
||||||
}
|
}
|
||||||
|
|
||||||
return loadROM;
|
return loadROM;
|
||||||
@ -94,7 +94,7 @@ LoadManager ()
|
|||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Preferences Menu
|
* Preferences Menu
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
static int prefmenuCount = 11;
|
static int prefmenuCount = 9;
|
||||||
static char prefmenu[][50] = {
|
static char prefmenu[][50] = {
|
||||||
|
|
||||||
"Load Method",
|
"Load Method",
|
||||||
@ -105,8 +105,6 @@ static char prefmenu[][50] = {
|
|||||||
"Auto Load",
|
"Auto Load",
|
||||||
"Auto Save",
|
"Auto Save",
|
||||||
"Verify MC Saves",
|
"Verify MC Saves",
|
||||||
"Enable Zooming",
|
|
||||||
"Video Rendering",
|
|
||||||
|
|
||||||
"Save Preferences",
|
"Save Preferences",
|
||||||
"Back to Main Menu"
|
"Back to Main Menu"
|
||||||
@ -124,26 +122,40 @@ PreferencesMenu ()
|
|||||||
// some load/save methods are not implemented - here's where we skip them
|
// some load/save methods are not implemented - here's where we skip them
|
||||||
// they need to be skipped in the order they were enumerated in vba.h
|
// they need to be skipped in the order they were enumerated in vba.h
|
||||||
|
|
||||||
|
// skip
|
||||||
|
if(GCSettings.LoadMethod == METHOD_DVD)
|
||||||
|
GCSettings.LoadMethod++;
|
||||||
|
if(GCSettings.LoadMethod == METHOD_SMB)
|
||||||
|
GCSettings.LoadMethod++;
|
||||||
|
if(GCSettings.SaveMethod == METHOD_SMB)
|
||||||
|
GCSettings.SaveMethod++;
|
||||||
|
if(GCSettings.SaveMethod == METHOD_MC_SLOTA)
|
||||||
|
GCSettings.SaveMethod++;
|
||||||
|
if(GCSettings.SaveMethod == METHOD_MC_SLOTB)
|
||||||
|
GCSettings.SaveMethod++;
|
||||||
|
|
||||||
|
prefmenu[6][0] = '\0'; // MC saving not implemented
|
||||||
|
|
||||||
// no USB ports on GameCube
|
// no USB ports on GameCube
|
||||||
#ifdef HW_DOL
|
#ifndef HW_RVL
|
||||||
if(GCSettings.LoadMethod == METHOD_USB)
|
if(GCSettings.LoadMethod == METHOD_USB)
|
||||||
GCSettings.LoadMethod++;
|
GCSettings.LoadMethod++;
|
||||||
if(GCSettings.SaveMethod == METHOD_USB)
|
if(GCSettings.SaveMethod == METHOD_USB)
|
||||||
GCSettings.SaveMethod++;
|
GCSettings.SaveMethod++;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// saving to DVD is impossible
|
// check if DVD access in Wii mode is disabled
|
||||||
if(GCSettings.SaveMethod == METHOD_DVD)
|
#ifndef WII_DVD
|
||||||
GCSettings.SaveMethod++;
|
|
||||||
|
|
||||||
// disable DVD in GC mode (not implemented)
|
|
||||||
#ifdef HW_DOL
|
|
||||||
if(GCSettings.LoadMethod == METHOD_DVD)
|
if(GCSettings.LoadMethod == METHOD_DVD)
|
||||||
GCSettings.LoadMethod++;
|
GCSettings.LoadMethod++;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// saving to DVD is impossible
|
||||||
|
if(GCSettings.SaveMethod == METHOD_DVD)
|
||||||
|
GCSettings.SaveMethod++;
|
||||||
|
|
||||||
// disable SMB in GC mode (stalls out)
|
// disable SMB in GC mode (stalls out)
|
||||||
#ifdef HW_DOL
|
#ifndef HW_RVL
|
||||||
if(GCSettings.LoadMethod == METHOD_SMB)
|
if(GCSettings.LoadMethod == METHOD_SMB)
|
||||||
GCSettings.LoadMethod++;
|
GCSettings.LoadMethod++;
|
||||||
if(GCSettings.SaveMethod == METHOD_SMB)
|
if(GCSettings.SaveMethod == METHOD_SMB)
|
||||||
@ -156,9 +168,6 @@ PreferencesMenu ()
|
|||||||
GCSettings.SaveMethod++;
|
GCSettings.SaveMethod++;
|
||||||
if(GCSettings.SaveMethod == METHOD_MC_SLOTB)
|
if(GCSettings.SaveMethod == METHOD_MC_SLOTB)
|
||||||
GCSettings.SaveMethod++;
|
GCSettings.SaveMethod++;
|
||||||
prefmenu[6][0] = 0;
|
|
||||||
#else
|
|
||||||
sprintf (prefmenu[6], "Verify MC Saves %s", GCSettings.VerifySaves == true ? " ON" : "OFF");
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// correct load/save methods out of bounds
|
// correct load/save methods out of bounds
|
||||||
@ -197,13 +206,7 @@ PreferencesMenu ()
|
|||||||
else if (GCSettings.AutoSave == 2) sprintf (prefmenu[5],"Auto Save SNAPSHOT");
|
else if (GCSettings.AutoSave == 2) sprintf (prefmenu[5],"Auto Save SNAPSHOT");
|
||||||
else if (GCSettings.AutoSave == 3) sprintf (prefmenu[5],"Auto Save BOTH");
|
else if (GCSettings.AutoSave == 3) sprintf (prefmenu[5],"Auto Save BOTH");
|
||||||
|
|
||||||
sprintf (prefmenu[7], "Enable Zooming %s",
|
//sprintf (prefmenu[6], "Verify MC Saves %s", GCSettings.VerifySaves == true ? " ON" : "OFF");
|
||||||
GCSettings.NGCZoom == true ? " ON" : "OFF");
|
|
||||||
|
|
||||||
if ( GCSettings.render == 0)
|
|
||||||
sprintf (prefmenu[8], "Video Rendering Filtered");
|
|
||||||
if ( GCSettings.render == 1)
|
|
||||||
sprintf (prefmenu[8], "Video Rendering Unfiltered");
|
|
||||||
|
|
||||||
ret = RunMenu (prefmenu, prefmenuCount, (char*)"Preferences", 16);
|
ret = RunMenu (prefmenu, prefmenuCount, (char*)"Preferences", 16);
|
||||||
|
|
||||||
@ -240,23 +243,11 @@ PreferencesMenu ()
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case 7:
|
case 7:
|
||||||
GCSettings.NGCZoom ^= 1;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 8:
|
|
||||||
GCSettings.render++;
|
|
||||||
if (GCSettings.render > 1 )
|
|
||||||
GCSettings.render = 0;
|
|
||||||
// reset zoom
|
|
||||||
zoom_reset ();
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 9:
|
|
||||||
SavePrefs(GCSettings.SaveMethod, NOTSILENT);
|
SavePrefs(GCSettings.SaveMethod, NOTSILENT);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case -1: /*** Button B ***/
|
case -1: /*** Button B ***/
|
||||||
case 10:
|
case 8:
|
||||||
quit = 1;
|
quit = 1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -272,13 +263,12 @@ PreferencesMenu ()
|
|||||||
int
|
int
|
||||||
GameMenu ()
|
GameMenu ()
|
||||||
{
|
{
|
||||||
int gamemenuCount = 8;
|
int gamemenuCount = 7;
|
||||||
char gamemenu[][50] = {
|
char gamemenu[][50] = {
|
||||||
"Return to Game",
|
"Return to Game",
|
||||||
"Reset Game",
|
"Reset Game",
|
||||||
"Load SRAM", "Save SRAM",
|
"Load SRAM", "Save SRAM",
|
||||||
"Load Game Snapshot", "Save Game Snapshot",
|
"Load Game Snapshot", "Save Game Snapshot",
|
||||||
"Reset Zoom",
|
|
||||||
"Back to Main Menu"
|
"Back to Main Menu"
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -305,9 +295,6 @@ GameMenu ()
|
|||||||
gamemenu[3][0] = '\0';
|
gamemenu[3][0] = '\0';
|
||||||
gamemenu[5][0] = '\0';
|
gamemenu[5][0] = '\0';
|
||||||
}
|
}
|
||||||
// disable Reset Zoom if Zooming is off
|
|
||||||
if(!GCSettings.NGCZoom)
|
|
||||||
gamemenu[6][0] = '\0';
|
|
||||||
|
|
||||||
ret = RunMenu (gamemenu, gamemenuCount, (char*)"Game Menu");
|
ret = RunMenu (gamemenu, gamemenuCount, (char*)"Game Menu");
|
||||||
|
|
||||||
@ -323,29 +310,23 @@ GameMenu ()
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case 2: // Load Battery
|
case 2: // Load Battery
|
||||||
quit = retval = LoadBatteryOrState(GCSettings.SaveMethod, 0, NOTSILENT);
|
quit = retval = LoadBattery(GCSettings.SaveMethod, NOTSILENT);
|
||||||
emulator.emuReset();
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 3: // Save Battery
|
case 3: // Save Battery
|
||||||
SaveBatteryOrState(GCSettings.SaveMethod, 0, NOTSILENT);
|
SaveBattery(GCSettings.SaveMethod, NOTSILENT);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 4: // Load State
|
case 4: // Load State
|
||||||
quit = retval = LoadBatteryOrState(GCSettings.SaveMethod, 1, NOTSILENT);
|
quit = retval = LoadState(GCSettings.SaveMethod, NOTSILENT);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 5: // Save State
|
case 5: // Save State
|
||||||
SaveBatteryOrState(GCSettings.SaveMethod, 1, NOTSILENT);
|
SaveState(GCSettings.SaveMethod, NOTSILENT);
|
||||||
break;
|
|
||||||
|
|
||||||
case 6: // Reset Zoom
|
|
||||||
zoom_reset ();
|
|
||||||
quit = retval = 1;
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case -1: // Button B
|
case -1: // Button B
|
||||||
case 7: // Return to previous menu
|
case 6: // Return to previous menu
|
||||||
retval = 0;
|
retval = 0;
|
||||||
quit = 1;
|
quit = 1;
|
||||||
break;
|
break;
|
||||||
@ -652,7 +633,7 @@ MainMenu (int selectedMenu)
|
|||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
// disable game-specific menu items if a ROM isn't loaded
|
// disable game-specific menu items if a ROM isn't loaded
|
||||||
if (!ROMLoaded)
|
if (ROMSize == 0 )
|
||||||
menuitems[3][0] = '\0';
|
menuitems[3][0] = '\0';
|
||||||
else
|
else
|
||||||
sprintf (menuitems[3], "Game Menu");
|
sprintf (menuitems[3], "Game Menu");
|
||||||
@ -719,24 +700,19 @@ MainMenu (int selectedMenu)
|
|||||||
|
|
||||||
case -1: // Button B
|
case -1: // Button B
|
||||||
// Return to Game
|
// Return to Game
|
||||||
if(ROMLoaded)
|
|
||||||
quit = 1;
|
quit = 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Wait for buttons to be released
|
/*** Remove any still held buttons ***/
|
||||||
int count = 0; // how long we've been waiting for the user to release the button
|
|
||||||
while(count < 50 && (
|
|
||||||
PAD_ButtonsHeld(0)
|
|
||||||
#ifdef HW_RVL
|
#ifdef HW_RVL
|
||||||
|| WPAD_ButtonsHeld(0)
|
while( PAD_ButtonsHeld(0) || WPAD_ButtonsHeld(0) )
|
||||||
#endif
|
|
||||||
))
|
|
||||||
{
|
|
||||||
VIDEO_WaitVSync();
|
VIDEO_WaitVSync();
|
||||||
count++;
|
#else
|
||||||
}
|
while( PAD_ButtonsHeld(0) )
|
||||||
|
VIDEO_WaitVSync();
|
||||||
|
#endif
|
||||||
|
|
||||||
StartAudio();
|
StartAudio();
|
||||||
mftb(&end);
|
mftb(&end);
|
||||||
|
@ -205,17 +205,6 @@ setfontcolour (u8 r, u8 g, u8 b)
|
|||||||
fontlo = fontcolour & 0xffff;
|
fontlo = fontcolour & 0xffff;
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
* Draws Version # on screen
|
|
||||||
***************************************************************************/
|
|
||||||
|
|
||||||
void DrawVersion()
|
|
||||||
{
|
|
||||||
setfontsize (12);
|
|
||||||
setfontcolour (0,0,0);
|
|
||||||
DrawText (115, screenheight - 34, (char *)VERSIONSTRFULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Display credits, legal copyright and licence
|
* Display credits, legal copyright and licence
|
||||||
*
|
*
|
||||||
@ -228,10 +217,10 @@ Credits ()
|
|||||||
|
|
||||||
setfontcolour (0x00, 0x00, 0x00);
|
setfontcolour (0x00, 0x00, 0x00);
|
||||||
|
|
||||||
setfontsize (26);
|
setfontsize (28);
|
||||||
DrawText (-1, 150, (char*)"Credits");
|
DrawText (-1, 60, (char*)"Credits");
|
||||||
|
|
||||||
int ypos = 120;
|
int ypos = 25;
|
||||||
|
|
||||||
if (screenheight == 480)
|
if (screenheight == 480)
|
||||||
ypos += 52;
|
ypos += 52;
|
||||||
@ -246,8 +235,6 @@ Credits ()
|
|||||||
DrawText (375, ypos, (char*)"emukidid");
|
DrawText (375, ypos, (char*)"emukidid");
|
||||||
DrawText (100, ypos += 18, (char*)"Original GameCube Port");
|
DrawText (100, ypos += 18, (char*)"Original GameCube Port");
|
||||||
DrawText (375, ypos, (char*)"SoftDev");
|
DrawText (375, ypos, (char*)"SoftDev");
|
||||||
DrawText (100, ypos += 18, (char*)"Visual Boy Advance - M");
|
|
||||||
DrawText (375, ypos, (char*)"VBA-M Team");
|
|
||||||
DrawText (100, ypos += 18, (char*)"Visual Boy Advance 1.7.2");
|
DrawText (100, ypos += 18, (char*)"Visual Boy Advance 1.7.2");
|
||||||
DrawText (375, ypos, (char*)"Forgotten");
|
DrawText (375, ypos, (char*)"Forgotten");
|
||||||
DrawText (100, ypos += 18, (char*)"libogc");
|
DrawText (100, ypos += 18, (char*)"libogc");
|
||||||
@ -258,11 +245,9 @@ Credits ()
|
|||||||
DrawText (-1, ypos += 36, (char*)"And many others who have contributed over the years!");
|
DrawText (-1, ypos += 36, (char*)"And many others who have contributed over the years!");
|
||||||
|
|
||||||
setfontsize (12);
|
setfontsize (12);
|
||||||
DrawText (-1, ypos += 40, (char*)"This software is open source and may be copied,");
|
DrawText (-1, ypos += 50, (char*)"This software is open source and may be copied, distributed, or modified");
|
||||||
DrawText (-1, ypos += 15, (char*)"distributed, or modified under the terms of");
|
DrawText (-1, ypos += 15, (char*)"under the terms of the GNU General Public License (GPL) Version 2.");
|
||||||
DrawText (-1, ypos += 15, (char*)"the GNU General Public License (GPL) Version 2.");
|
|
||||||
|
|
||||||
DrawVersion();
|
|
||||||
showscreen ();
|
showscreen ();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -368,12 +353,9 @@ WaitPrompt (char *msg)
|
|||||||
ypos += 32;
|
ypos += 32;
|
||||||
|
|
||||||
clearscreen ();
|
clearscreen ();
|
||||||
setfontsize(16);
|
|
||||||
DrawText (-1, ypos, msg);
|
DrawText (-1, ypos, msg);
|
||||||
ypos += 30;
|
ypos += 30;
|
||||||
DrawText (-1, ypos, (char*)"Press A to continue");
|
DrawText (-1, ypos, (char*)"Press A to continue");
|
||||||
|
|
||||||
DrawVersion();
|
|
||||||
showscreen ();
|
showscreen ();
|
||||||
WaitButtonA ();
|
WaitButtonA ();
|
||||||
}
|
}
|
||||||
@ -393,14 +375,11 @@ WaitPromptChoice (char *msg, char *bmsg, char *amsg)
|
|||||||
ypos += 17;
|
ypos += 17;
|
||||||
|
|
||||||
clearscreen ();
|
clearscreen ();
|
||||||
setfontsize(20);
|
|
||||||
DrawText (-1, ypos, msg);
|
DrawText (-1, ypos, msg);
|
||||||
ypos += 60;
|
ypos += 60;
|
||||||
char txt[80];
|
char txt[80];
|
||||||
sprintf (txt, "B = %s : A = %s", bmsg, amsg);
|
sprintf (txt, "B = %s : A = %s", bmsg, amsg);
|
||||||
DrawText (-1, ypos, txt);
|
DrawText (-1, ypos, txt);
|
||||||
|
|
||||||
DrawVersion();
|
|
||||||
showscreen ();
|
showscreen ();
|
||||||
return WaitButtonAB ();
|
return WaitButtonAB ();
|
||||||
}
|
}
|
||||||
@ -419,10 +398,7 @@ ShowAction (char *msg)
|
|||||||
ypos += 32;
|
ypos += 32;
|
||||||
|
|
||||||
clearscreen ();
|
clearscreen ();
|
||||||
setfontsize(20);
|
|
||||||
DrawText (-1, ypos, msg);
|
DrawText (-1, ypos, msg);
|
||||||
|
|
||||||
DrawVersion();
|
|
||||||
showscreen ();
|
showscreen ();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -437,12 +413,12 @@ DrawMenu (char items[][50], char *title, int maxitems, int selected, int fontsiz
|
|||||||
int n = 1;
|
int n = 1;
|
||||||
int line_height;
|
int line_height;
|
||||||
|
|
||||||
ypos = 105;
|
ypos = 45;
|
||||||
|
|
||||||
if (screenheight == 480)
|
if (screenheight == 480)
|
||||||
ypos += 52;
|
ypos += 52;
|
||||||
else
|
else
|
||||||
ypos += 42;
|
ypos += 32;
|
||||||
|
|
||||||
clearscreen ();
|
clearscreen ();
|
||||||
|
|
||||||
@ -450,10 +426,13 @@ DrawMenu (char items[][50], char *title, int maxitems, int selected, int fontsiz
|
|||||||
|
|
||||||
if (title != NULL)
|
if (title != NULL)
|
||||||
{
|
{
|
||||||
setfontsize (26);
|
setfontsize (28);
|
||||||
DrawText (-1, 150, title);
|
DrawText (-1, 60, title);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
setfontsize (14);
|
||||||
|
DrawText (380, screenheight - 30, (char *)VERSIONSTRFULL);
|
||||||
|
|
||||||
// Draw menu items
|
// Draw menu items
|
||||||
|
|
||||||
setfontsize (fontsize); // set font size
|
setfontsize (fontsize); // set font size
|
||||||
@ -469,11 +448,11 @@ DrawMenu (char items[][50], char *title, int maxitems, int selected, int fontsiz
|
|||||||
else if (i == selected)
|
else if (i == selected)
|
||||||
{
|
{
|
||||||
for( w = 0; w < line_height; w++ )
|
for( w = 0; w < line_height; w++ )
|
||||||
DrawLineFast( 77, 575, n * line_height + (ypos-line_height+6) + w, 0x00, 0x00, 0x00 );
|
DrawLineFast( 30, 610, n * line_height + (ypos-line_height+6) + w, 0x80, 0x80, 0x80 );
|
||||||
|
|
||||||
//setfontcolour (0xff, 0xff, 0xff);
|
setfontcolour (0xff, 0xff, 0xff);
|
||||||
DrawText (x, n * line_height + ypos, items[i]);
|
DrawText (x, n * line_height + ypos, items[i]);
|
||||||
//setfontcolour (0x00, 0x00, 0x00);
|
setfontcolour (0x00, 0x00, 0x00);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -483,8 +462,8 @@ DrawMenu (char items[][50], char *title, int maxitems, int selected, int fontsiz
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
DrawVersion();
|
|
||||||
showscreen ();
|
showscreen ();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
@ -540,7 +519,7 @@ RunMenu (char items[][50], int maxitems, char *title, int fontsize, int x)
|
|||||||
gc_ay = PAD_StickY (0);
|
gc_ay = PAD_StickY (0);
|
||||||
p = PAD_ButtonsDown (0);
|
p = PAD_ButtonsDown (0);
|
||||||
#ifdef HW_RVL
|
#ifdef HW_RVL
|
||||||
wm_ay = WPAD_Stick (0,0,1);
|
wm_ay = WPAD_StickY (0,0);
|
||||||
wp = WPAD_ButtonsDown (0);
|
wp = WPAD_ButtonsDown (0);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -605,8 +584,8 @@ ShowFiles (FILEENTRIES filelist[], int maxfiles, int offset, int selection)
|
|||||||
|
|
||||||
clearscreen ();
|
clearscreen ();
|
||||||
|
|
||||||
setfontsize (26);
|
setfontsize (28);
|
||||||
DrawText (-1, 150, (char*)"Choose Game");
|
DrawText (-1, 60, (char*)"Choose Game");
|
||||||
|
|
||||||
setfontsize(18);
|
setfontsize(18);
|
||||||
|
|
||||||
@ -617,8 +596,6 @@ ShowFiles (FILEENTRIES filelist[], int maxfiles, int offset, int selection)
|
|||||||
else
|
else
|
||||||
ypos += 10;
|
ypos += 10;
|
||||||
|
|
||||||
ypos += 30;
|
|
||||||
|
|
||||||
j = 0;
|
j = 0;
|
||||||
for (i = offset; i < (offset + PAGESIZE) && (i < maxfiles); i++)
|
for (i = offset; i < (offset + PAGESIZE) && (i < maxfiles); i++)
|
||||||
{
|
{
|
||||||
@ -637,18 +614,19 @@ ShowFiles (FILEENTRIES filelist[], int maxfiles, int offset, int selection)
|
|||||||
{
|
{
|
||||||
/*** Highlighted text entry ***/
|
/*** Highlighted text entry ***/
|
||||||
for ( w = 0; w < 20; w++ )
|
for ( w = 0; w < 20; w++ )
|
||||||
DrawLineFast( 77, 575, ( j * 20 ) + (ypos-16) + w, 0x00, 0x00, 0x00 );
|
DrawLineFast( 30, 610, ( j * 20 ) + (ypos-16) + w, 0x80, 0x80, 0x80 );
|
||||||
DrawText (100, (j * 20) + ypos, text);
|
|
||||||
|
setfontcolour (0x00, 0x00, 0xe0);
|
||||||
|
DrawText (50, (j * 20) + ypos, text);
|
||||||
|
setfontcolour (0x00, 0x00, 0x00);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/*** Normal entry ***/
|
/*** Normal entry ***/
|
||||||
DrawText (100, (j * 20) + ypos, text);
|
DrawText (50, (j * 20) + ypos, text);
|
||||||
}
|
}
|
||||||
j++;
|
j++;
|
||||||
}
|
}
|
||||||
|
|
||||||
DrawVersion();
|
|
||||||
showscreen ();
|
showscreen ();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -667,8 +645,8 @@ ShowCheats (char items[][50], char itemvalues[][50], int maxitems, int offset, i
|
|||||||
|
|
||||||
clearscreen ();
|
clearscreen ();
|
||||||
|
|
||||||
setfontsize (26);
|
setfontsize (28);
|
||||||
DrawText (-1, 150, (char*)"Cheats");
|
DrawText (-1, 60, (char*)"Cheats");
|
||||||
|
|
||||||
setfontsize(18);
|
setfontsize(18);
|
||||||
|
|
||||||
@ -698,8 +676,6 @@ ShowCheats (char items[][50], char itemvalues[][50], int maxitems, int offset, i
|
|||||||
}
|
}
|
||||||
j++;
|
j++;
|
||||||
}
|
}
|
||||||
|
|
||||||
DrawVersion();
|
|
||||||
showscreen ();
|
showscreen ();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -797,31 +773,22 @@ 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;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
if(done < 5000) // we just started!
|
|
||||||
{
|
|
||||||
ypos = (screenheight - 30) >> 1;
|
|
||||||
|
|
||||||
if (screenheight == 480)
|
if (screenheight == 480)
|
||||||
ypos += 52;
|
ypos += 52;
|
||||||
else
|
else
|
||||||
ypos += 32;
|
ypos += 32;
|
||||||
|
|
||||||
|
int xpos;
|
||||||
|
int i;
|
||||||
|
|
||||||
clearscreen ();
|
clearscreen ();
|
||||||
setfontsize(20);
|
|
||||||
DrawText (-1, ypos, msg);
|
DrawText (-1, ypos, msg);
|
||||||
|
|
||||||
/*** Draw a white outline box ***/
|
/*** Draw a white outline box ***/
|
||||||
for (i = 380; i < 401; i++)
|
for (i = 380; i < 401; i++)
|
||||||
DrawLine (100, i, 540, i, 0xff, 0xff, 0xff);
|
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);
|
||||||
@ -829,12 +796,8 @@ ShowProgress (char *msg, int done, int total)
|
|||||||
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!
|
|
||||||
{
|
|
||||||
DrawVersion();
|
|
||||||
showscreen ();
|
showscreen ();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* DrawPolygon
|
* DrawPolygon
|
||||||
|
@ -19,7 +19,7 @@
|
|||||||
|
|
||||||
#include "filesel.h"
|
#include "filesel.h"
|
||||||
|
|
||||||
#define PAGESIZE 13 // max item listing on a screen
|
#define PAGESIZE 17 // max item listing on a screen
|
||||||
|
|
||||||
int FT_Init ();
|
int FT_Init ();
|
||||||
void setfontsize (int pixelsize);
|
void setfontsize (int pixelsize);
|
||||||
|
@ -21,10 +21,16 @@
|
|||||||
#include "fileop.h"
|
#include "fileop.h"
|
||||||
#include "smbop.h"
|
#include "smbop.h"
|
||||||
#include "filesel.h"
|
#include "filesel.h"
|
||||||
#include "input.h"
|
|
||||||
|
|
||||||
|
extern unsigned char savebuffer[];
|
||||||
extern int currconfig[4];
|
extern int currconfig[4];
|
||||||
|
|
||||||
|
// button map configurations
|
||||||
|
extern unsigned int gcpadmap[];
|
||||||
|
extern unsigned int wmpadmap[];
|
||||||
|
extern unsigned int ccpadmap[];
|
||||||
|
extern unsigned int ncpadmap[];
|
||||||
|
|
||||||
#define PREFS_FILE_NAME "VBAGX.xml"
|
#define PREFS_FILE_NAME "VBAGX.xml"
|
||||||
|
|
||||||
char prefscomment[2][32];
|
char prefscomment[2][32];
|
||||||
@ -40,7 +46,7 @@ mxml_node_t *section;
|
|||||||
mxml_node_t *item;
|
mxml_node_t *item;
|
||||||
mxml_node_t *elem;
|
mxml_node_t *elem;
|
||||||
|
|
||||||
char temp[20];
|
char temp[200];
|
||||||
|
|
||||||
const char * toStr(int i)
|
const char * toStr(int i)
|
||||||
{
|
{
|
||||||
@ -70,7 +76,7 @@ void createXMLController(unsigned int controller[], const char * name, const cha
|
|||||||
mxmlElementSetAttr(item, "description", description);
|
mxmlElementSetAttr(item, "description", description);
|
||||||
|
|
||||||
// create buttons
|
// create buttons
|
||||||
for(int i=0; i < MAXJP; i++)
|
for(int i=0; i < 12; i++)
|
||||||
{
|
{
|
||||||
elem = mxmlNewElement(item, "button");
|
elem = mxmlNewElement(item, "button");
|
||||||
mxmlElementSetAttr(elem, "number", toStr(i));
|
mxmlElementSetAttr(elem, "number", toStr(i));
|
||||||
@ -110,6 +116,7 @@ int
|
|||||||
preparePrefsData (int method)
|
preparePrefsData (int method)
|
||||||
{
|
{
|
||||||
int offset = 0;
|
int offset = 0;
|
||||||
|
memset (savebuffer, 0, SAVEBUFFERSIZE);
|
||||||
|
|
||||||
// add save icon and comments for Memory Card saves
|
// add save icon and comments for Memory Card saves
|
||||||
if(method == METHOD_MC_SLOTA || method == METHOD_MC_SLOTB)
|
if(method == METHOD_MC_SLOTA || method == METHOD_MC_SLOTB)
|
||||||
@ -141,7 +148,7 @@ preparePrefsData (int method)
|
|||||||
createXMLSetting("LoadFolder", "Load Folder", GCSettings.LoadFolder);
|
createXMLSetting("LoadFolder", "Load Folder", GCSettings.LoadFolder);
|
||||||
createXMLSetting("SaveFolder", "Save Folder", GCSettings.SaveFolder);
|
createXMLSetting("SaveFolder", "Save Folder", GCSettings.SaveFolder);
|
||||||
//createXMLSetting("CheatFolder", "Cheats Folder", GCSettings.CheatFolder);
|
//createXMLSetting("CheatFolder", "Cheats Folder", GCSettings.CheatFolder);
|
||||||
createXMLSetting("VerifySaves", "Verify Memory Card Saves", toStr(GCSettings.VerifySaves));
|
//createXMLSetting("VerifySaves", "Verify Memory Card Saves", toStr(GCSettings.VerifySaves));
|
||||||
|
|
||||||
createXMLSection("Network", "Network Settings");
|
createXMLSection("Network", "Network Settings");
|
||||||
|
|
||||||
@ -150,10 +157,7 @@ preparePrefsData (int method)
|
|||||||
createXMLSetting("smbuser", "Share Username", GCSettings.smbuser);
|
createXMLSetting("smbuser", "Share Username", GCSettings.smbuser);
|
||||||
createXMLSetting("smbpwd", "Share Password", GCSettings.smbpwd);
|
createXMLSetting("smbpwd", "Share Password", GCSettings.smbpwd);
|
||||||
|
|
||||||
createXMLSection("Emulation", "Emulation Settings");
|
//createXMLSection("Emulation", "Emulation Settings");
|
||||||
|
|
||||||
createXMLSetting("NGCZoom", "Enable Zoom", toStr(GCSettings.NGCZoom));
|
|
||||||
createXMLSetting("render", "Video Rendering", toStr(GCSettings.render));
|
|
||||||
|
|
||||||
createXMLSection("Controller", "Controller Settings");
|
createXMLSection("Controller", "Controller Settings");
|
||||||
|
|
||||||
@ -208,7 +212,7 @@ void loadXMLController(unsigned int controller[], const char * name)
|
|||||||
if(item)
|
if(item)
|
||||||
{
|
{
|
||||||
// populate buttons
|
// populate buttons
|
||||||
for(int i=0; i < MAXJP; i++)
|
for(int i=0; i < 12; i++)
|
||||||
{
|
{
|
||||||
elem = mxmlFindElement(item, xml, "button", "number", toStr(i), MXML_DESCEND);
|
elem = mxmlFindElement(item, xml, "button", "number", toStr(i), MXML_DESCEND);
|
||||||
if(elem)
|
if(elem)
|
||||||
@ -238,6 +242,7 @@ decodePrefsData (int method)
|
|||||||
xml = mxmlLoadString(NULL, (char *)savebuffer+offset, MXML_TEXT_CALLBACK);
|
xml = mxmlLoadString(NULL, (char *)savebuffer+offset, MXML_TEXT_CALLBACK);
|
||||||
|
|
||||||
// check settings version
|
// check settings version
|
||||||
|
// we don't do anything with the version #, but we'll store it anyway
|
||||||
char * version;
|
char * version;
|
||||||
item = mxmlFindElement(xml, xml, "file", "version", NULL, MXML_DESCEND);
|
item = mxmlFindElement(xml, xml, "file", "version", NULL, MXML_DESCEND);
|
||||||
if(item) // a version entry exists
|
if(item) // a version entry exists
|
||||||
@ -245,17 +250,6 @@ decodePrefsData (int method)
|
|||||||
else // version # not found, must be invalid
|
else // version # not found, must be invalid
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// this code assumes version in format X.X.X
|
|
||||||
// XX.X.X, X.XX.X, or X.X.XX will NOT work
|
|
||||||
char verMajor = version[7];
|
|
||||||
char verMinor = version[9];
|
|
||||||
char verPoint = version[11];
|
|
||||||
|
|
||||||
if(verPoint < '3' && verMajor == '1') // less than version 1.0.3
|
|
||||||
return false; // reset settings
|
|
||||||
else if(verMajor > '1' || verMinor > '0' || verPoint > '3') // some future version
|
|
||||||
return false; // reset settings
|
|
||||||
|
|
||||||
// File Settings
|
// File Settings
|
||||||
|
|
||||||
loadXMLSetting(&GCSettings.AutoLoad, "AutoLoad");
|
loadXMLSetting(&GCSettings.AutoLoad, "AutoLoad");
|
||||||
@ -276,9 +270,6 @@ decodePrefsData (int method)
|
|||||||
|
|
||||||
// Emulation Settings
|
// Emulation Settings
|
||||||
|
|
||||||
loadXMLSetting(&GCSettings.NGCZoom, "NGCZoom");
|
|
||||||
loadXMLSetting(&GCSettings.render, "render");
|
|
||||||
|
|
||||||
// Controller Settings
|
// Controller Settings
|
||||||
|
|
||||||
loadXMLController(gcpadmap, "gcpadmap");
|
loadXMLController(gcpadmap, "gcpadmap");
|
||||||
@ -297,17 +288,13 @@ decodePrefsData (int method)
|
|||||||
bool
|
bool
|
||||||
SavePrefs (int method, bool silent)
|
SavePrefs (int method, bool silent)
|
||||||
{
|
{
|
||||||
// there's no point in saving SMB settings TO SMB, because then we'll have no way to load them the next time!
|
if(method == METHOD_AUTO)
|
||||||
// so instead we'll save using whatever other method is available (eg: SD)
|
|
||||||
if(method == METHOD_AUTO || method == METHOD_SMB)
|
|
||||||
method = autoSaveMethod();
|
method = autoSaveMethod();
|
||||||
|
|
||||||
char filepath[1024];
|
char filepath[1024];
|
||||||
int datasize;
|
int datasize;
|
||||||
int offset = 0;
|
int offset = 0;
|
||||||
|
|
||||||
AllocSaveBuffer ();
|
|
||||||
|
|
||||||
datasize = preparePrefsData (method);
|
datasize = preparePrefsData (method);
|
||||||
|
|
||||||
if (!silent)
|
if (!silent)
|
||||||
@ -335,8 +322,6 @@ SavePrefs (int method, bool silent)
|
|||||||
offset = SaveBufferToMC (savebuffer, CARD_SLOTB, (char *)PREFS_FILE_NAME, datasize, silent);
|
offset = SaveBufferToMC (savebuffer, CARD_SLOTB, (char *)PREFS_FILE_NAME, datasize, silent);
|
||||||
}
|
}
|
||||||
|
|
||||||
FreeSaveBuffer ();
|
|
||||||
|
|
||||||
if (offset > 0)
|
if (offset > 0)
|
||||||
{
|
{
|
||||||
if (!silent)
|
if (!silent)
|
||||||
@ -356,8 +341,6 @@ LoadPrefsFromMethod (int method)
|
|||||||
char filepath[1024];
|
char filepath[1024];
|
||||||
int offset = 0;
|
int offset = 0;
|
||||||
|
|
||||||
AllocSaveBuffer ();
|
|
||||||
|
|
||||||
if(method == METHOD_SD || method == METHOD_USB)
|
if(method == METHOD_SD || method == METHOD_USB)
|
||||||
{
|
{
|
||||||
if(ChangeFATInterface(method, NOTSILENT))
|
if(ChangeFATInterface(method, NOTSILENT))
|
||||||
@ -383,8 +366,6 @@ LoadPrefsFromMethod (int method)
|
|||||||
if (offset > 0)
|
if (offset > 0)
|
||||||
retval = decodePrefsData (method);
|
retval = decodePrefsData (method);
|
||||||
|
|
||||||
FreeSaveBuffer ();
|
|
||||||
|
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
115
source/ngc/sdfileio.c
Normal file
115
source/ngc/sdfileio.c
Normal file
@ -0,0 +1,115 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
* Visual Boy Advance GX
|
||||||
|
*
|
||||||
|
* Tantric September 2008
|
||||||
|
*
|
||||||
|
* sdfileio.c
|
||||||
|
*
|
||||||
|
* Generic File I/O for VisualBoyAdvance
|
||||||
|
* Currently only supports SD/USB
|
||||||
|
****************************************************************************/
|
||||||
|
#include <gccore.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <fat.h>
|
||||||
|
#include <sys/dir.h>
|
||||||
|
|
||||||
|
#define MAXDIRENTRIES 1000
|
||||||
|
char direntries[MAXDIRENTRIES][255];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SDInit
|
||||||
|
*/
|
||||||
|
void SDInit( void )
|
||||||
|
{
|
||||||
|
fatInitDefault();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SD Card f_open
|
||||||
|
*/
|
||||||
|
FILE* gen_fopen( const char *filename, const char *mode )
|
||||||
|
{
|
||||||
|
return fopen( filename, mode );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SD Card f_write
|
||||||
|
*/
|
||||||
|
int gen_fwrite( const void *buffer, int len, int block, FILE* f )
|
||||||
|
{
|
||||||
|
return fwrite(buffer, len, block, f);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SD Card f_read
|
||||||
|
*/
|
||||||
|
int gen_fread( void *buffer, int len, int block, FILE* f )
|
||||||
|
{
|
||||||
|
|
||||||
|
return fread(buffer, len, block, f);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SD Card fclose
|
||||||
|
*/
|
||||||
|
void gen_fclose( FILE* f )
|
||||||
|
{
|
||||||
|
fclose(f);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SD Card fseek
|
||||||
|
*
|
||||||
|
* NB: Only supports SEEK_SET
|
||||||
|
*/
|
||||||
|
int gen_fseek(FILE* f, int where, int whence)
|
||||||
|
{
|
||||||
|
fseek(f, where, whence);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Simple fgetc
|
||||||
|
*/
|
||||||
|
int gen_fgetc( FILE* f )
|
||||||
|
{
|
||||||
|
return fgetc(f);
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct stat _fstat;
|
||||||
|
char filename[1024];
|
||||||
|
int fcount = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get directory listing
|
||||||
|
*/
|
||||||
|
int gen_getdir( char *thisdir )
|
||||||
|
{
|
||||||
|
memset(&direntries[0],0,MAXDIRENTRIES*255);
|
||||||
|
|
||||||
|
DIR_ITER* dp = diropen( thisdir );
|
||||||
|
|
||||||
|
if ( dp )
|
||||||
|
{
|
||||||
|
while ( dirnext(dp, filename, &_fstat) == 0 )
|
||||||
|
{
|
||||||
|
|
||||||
|
// Skip any sub directories
|
||||||
|
if ( !(_fstat.st_mode & S_IFDIR) )
|
||||||
|
{
|
||||||
|
memcpy(&direntries[fcount],&filename,strlen(filename));
|
||||||
|
fcount++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dirclose(dp);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
|
||||||
|
return fcount;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
38
source/ngc/sdfileio.h
Normal file
38
source/ngc/sdfileio.h
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
* Visual Boy Advance GX
|
||||||
|
*
|
||||||
|
* Tantric September 2008
|
||||||
|
*
|
||||||
|
* sdfileio.h
|
||||||
|
*
|
||||||
|
* Generic File I/O for VisualBoyAdvance
|
||||||
|
* Currently only supports SD/USB
|
||||||
|
****************************************************************************/
|
||||||
|
#ifndef __SDFILEIO__
|
||||||
|
#define __SDFILEIO__
|
||||||
|
|
||||||
|
|
||||||
|
#define MAXDIRENTRIES 1000
|
||||||
|
#include <fat.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <sys/dir.h>
|
||||||
|
|
||||||
|
extern "C"
|
||||||
|
{
|
||||||
|
|
||||||
|
/* Required Functions */
|
||||||
|
FILE* gen_fopen( const char *filename, const char *mode );
|
||||||
|
int gen_fwrite( const void *buffer, int len, int block, FILE* f );
|
||||||
|
int gen_fread( void *buffer, int len, int block, FILE* f );
|
||||||
|
void gen_fclose( FILE* f );
|
||||||
|
int gen_fseek(FILE* f, int where, int whence);
|
||||||
|
int gen_fgetc( FILE* f );
|
||||||
|
int SDInit( void );
|
||||||
|
int gen_getdir( char *thisdir );
|
||||||
|
extern char direntries[MAXDIRENTRIES][255];
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
@ -30,12 +30,17 @@ bool networkShareInit = false;
|
|||||||
unsigned int SMBTimer = 0;
|
unsigned int SMBTimer = 0;
|
||||||
#define SMBTIMEOUT ( 3600 ) // Some implementations timeout in 10 minutes
|
#define SMBTIMEOUT ( 3600 ) // Some implementations timeout in 10 minutes
|
||||||
|
|
||||||
// SMB connection/file handles - the only ones we should ever use!
|
|
||||||
SMBCONN smbconn;
|
SMBCONN smbconn;
|
||||||
SMBFILE smbfile;
|
|
||||||
|
|
||||||
#define ZIPCHUNK 16384
|
#define ZIPCHUNK 16384
|
||||||
|
|
||||||
|
extern unsigned char savebuffer[];
|
||||||
|
extern char output[16384];
|
||||||
|
extern int offset;
|
||||||
|
extern int selection;
|
||||||
|
extern char currentdir[MAXPATHLEN];
|
||||||
|
extern FILEENTRIES filelist[MAXFILES];
|
||||||
|
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* InitializeNetwork
|
* InitializeNetwork
|
||||||
* Initializes the Wii/GameCube network interface
|
* Initializes the Wii/GameCube network interface
|
||||||
@ -88,7 +93,7 @@ ConnectShare (bool silent)
|
|||||||
strlen(GCSettings.smbip) == 0)
|
strlen(GCSettings.smbip) == 0)
|
||||||
{
|
{
|
||||||
if(!silent)
|
if(!silent)
|
||||||
WaitPrompt((char*) "Invalid network settings. Check VBAGX.xml.");
|
WaitPrompt((char*) "Invalid network settings. Check SNES9xGX.xml.");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -213,76 +218,36 @@ ParseSMBdirectory ()
|
|||||||
return filecount;
|
return filecount;
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
* Open SMB file
|
|
||||||
***************************************************************************/
|
|
||||||
|
|
||||||
SMBFILE OpenSMBFile(char * filepath)
|
|
||||||
{
|
|
||||||
return SMB_OpenFile (SMBPath(filepath), SMB_OPEN_READING, SMB_OF_OPEN, smbconn);
|
|
||||||
}
|
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Load SMB file
|
* Load SMB file
|
||||||
* rom - pointer to memory where ROM will be stored
|
|
||||||
* length - # bytes to read (0 for all)
|
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
int
|
int
|
||||||
LoadSMBFile (char * rom, int length)
|
LoadSMBFile (char *filename, int length)
|
||||||
{
|
{
|
||||||
char filepath[MAXPATHLEN];
|
char filepath[MAXPATHLEN];
|
||||||
|
|
||||||
/* Check filename length */
|
/* Check filename length */
|
||||||
if (!MakeROMPath(filepath, METHOD_SMB))
|
if ((strlen(currentdir)+1+strlen(filelist[selection].filename)) < MAXPATHLEN)
|
||||||
|
sprintf(filepath, "%s/%s",currentdir,filelist[selection].filename);
|
||||||
|
else
|
||||||
{
|
{
|
||||||
WaitPrompt((char*) "Maximum filepath length reached!");
|
WaitPrompt((char*) "Maximum filepath length reached!");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
return LoadBufferFromSMB(rom, filepath, length, NOTSILENT);
|
|
||||||
}
|
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
* 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;
|
return 0;
|
||||||
|
//return LoadBufferFromSMB((char *)Memory.ROM, SMBPath(filepath), NOTSILENT);
|
||||||
smbfile = OpenSMBFile(filepath);
|
|
||||||
|
|
||||||
if (smbfile)
|
|
||||||
{
|
|
||||||
u32 size = SzExtractFile(filelist[selection].offset, rbuffer);
|
|
||||||
SMB_CloseFile (smbfile);
|
|
||||||
return size;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
WaitPrompt((char*) "Error opening file");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Write savebuffer to SMB file
|
* Write savebuffer to SMB file
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
// no buffer specified, use savebuffer
|
|
||||||
int
|
int
|
||||||
SaveBufferToSMB (char *filepath, int datasize, bool silent)
|
SaveBufferToSMB (char *filepath, int datasize, bool silent)
|
||||||
{
|
|
||||||
return SaveBufferToSMB((char *)savebuffer, filepath, datasize, silent);
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
SaveBufferToSMB (char * sbuffer, char *filepath, int datasize, bool silent)
|
|
||||||
{
|
{
|
||||||
if(!ConnectShare (NOTSILENT))
|
if(!ConnectShare (NOTSILENT))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
SMBFILE smbfile;
|
||||||
int dsize = datasize;
|
int dsize = datasize;
|
||||||
int wrote = 0;
|
int wrote = 0;
|
||||||
int boffset = 0;
|
int boffset = 0;
|
||||||
@ -297,10 +262,10 @@ SaveBufferToSMB (char * sbuffer, char *filepath, int datasize, bool silent)
|
|||||||
{
|
{
|
||||||
if (dsize > 1024)
|
if (dsize > 1024)
|
||||||
wrote =
|
wrote =
|
||||||
SMB_WriteFile ((char *) sbuffer + boffset, 1024, boffset, smbfile);
|
SMB_WriteFile ((char *) savebuffer + boffset, 1024, boffset, smbfile);
|
||||||
else
|
else
|
||||||
wrote =
|
wrote =
|
||||||
SMB_WriteFile ((char *) sbuffer + boffset, dsize, boffset, smbfile);
|
SMB_WriteFile ((char *) savebuffer + boffset, dsize, boffset, smbfile);
|
||||||
|
|
||||||
boffset += wrote;
|
boffset += wrote;
|
||||||
dsize -= wrote;
|
dsize -= wrote;
|
||||||
@ -314,6 +279,7 @@ SaveBufferToSMB (char * sbuffer, char *filepath, int datasize, bool silent)
|
|||||||
WaitPrompt (msg);
|
WaitPrompt (msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ClearSaveBuffer ();
|
||||||
return boffset;
|
return boffset;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -325,19 +291,22 @@ SaveBufferToSMB (char * sbuffer, char *filepath, int datasize, bool silent)
|
|||||||
int
|
int
|
||||||
LoadBufferFromSMB (char *filepath, bool silent)
|
LoadBufferFromSMB (char *filepath, bool silent)
|
||||||
{
|
{
|
||||||
return LoadBufferFromSMB((char *)savebuffer, filepath, 0, silent);
|
ClearSaveBuffer ();
|
||||||
|
return LoadBufferFromSMB((char *)savebuffer, filepath, silent);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
LoadBufferFromSMB (char * sbuffer, char *filepath, int length, bool silent)
|
LoadBufferFromSMB (char * sbuffer, char *filepath, bool silent)
|
||||||
{
|
{
|
||||||
if(!ConnectShare (NOTSILENT))
|
if(!ConnectShare (NOTSILENT))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
SMBFILE smbfile;
|
||||||
int ret;
|
int ret;
|
||||||
int boffset = 0;
|
int boffset = 0;
|
||||||
|
|
||||||
smbfile = OpenSMBFile(filepath);
|
smbfile =
|
||||||
|
SMB_OpenFile (SMBPath(filepath), SMB_OPEN_READING, SMB_OF_OPEN, smbconn);
|
||||||
|
|
||||||
if (!smbfile)
|
if (!smbfile)
|
||||||
{
|
{
|
||||||
@ -350,27 +319,17 @@ LoadBufferFromSMB (char * sbuffer, char *filepath, int length, bool silent)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(length > 0 && length <= 2048) // do a partial read (eg: to check file header)
|
ret = SMB_ReadFile (sbuffer, 1024, boffset, smbfile);
|
||||||
{
|
|
||||||
boffset = SMB_ReadFile (sbuffer, length, 0, smbfile);
|
|
||||||
}
|
|
||||||
else // load whole file
|
|
||||||
{
|
|
||||||
ret = SMB_ReadFile (sbuffer, 2048, boffset, smbfile);
|
|
||||||
|
|
||||||
if (IsZipFile (sbuffer))
|
if (IsZipFile (sbuffer))
|
||||||
{
|
{
|
||||||
boffset = UnZipBuffer ((unsigned char *)sbuffer, METHOD_SMB); // unzip from SMB
|
boffset = UnZipFile ((unsigned char *)sbuffer, smbfile); // unzip from SMB
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Just load the file up
|
// Just load the file up
|
||||||
while ((ret = SMB_ReadFile (sbuffer + boffset, 2048, boffset, smbfile)) > 0)
|
while ((ret = SMB_ReadFile (sbuffer + boffset, 1024, boffset, smbfile)) > 0)
|
||||||
{
|
|
||||||
boffset += ret;
|
boffset += ret;
|
||||||
ShowProgress ((char *)"Loading...", boffset, length);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
SMB_CloseFile (smbfile);
|
SMB_CloseFile (smbfile);
|
||||||
|
|
||||||
|
@ -12,21 +12,14 @@
|
|||||||
|
|
||||||
#define _NGCSMB_
|
#define _NGCSMB_
|
||||||
|
|
||||||
#include <smb.h>
|
|
||||||
|
|
||||||
bool InitializeNetwork(bool silent);
|
bool InitializeNetwork(bool silent);
|
||||||
bool ConnectShare (bool silent);
|
bool ConnectShare (bool silent);
|
||||||
char * SMBPath(char * path);
|
char * SMBPath(char * path);
|
||||||
int UpdateSMBdirname();
|
int UpdateSMBdirname();
|
||||||
int ParseSMBdirectory ();
|
int ParseSMBdirectory ();
|
||||||
SMBFILE OpenSMBFile(char * filepath);
|
int LoadSMBFile (char *filename, int length);
|
||||||
int LoadSMBFile (char * fbuffer, int length);
|
|
||||||
int LoadSMBSzFile(char * filepath, unsigned char * rbuffer);
|
|
||||||
int LoadBufferFromSMB (char *filepath, bool silent);
|
int LoadBufferFromSMB (char *filepath, bool silent);
|
||||||
int LoadBufferFromSMB (char * sbuffer, char *filepath, int length, bool silent);
|
int LoadBufferFromSMB (char * sbuffer, char *filepath, bool silent);
|
||||||
int SaveBufferToSMB (char *filepath, int datasize, bool silent);
|
int SaveBufferToSMB (char *filepath, int datasize, bool silent);
|
||||||
int SaveBufferToSMB (char * sbuffer, char *filepath, int datasize, bool silent);
|
|
||||||
|
|
||||||
extern SMBFILE smbfile;
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -38,7 +38,7 @@ extern "C" {
|
|||||||
#include "video.h"
|
#include "video.h"
|
||||||
#include "vbaconfig.h"
|
#include "vbaconfig.h"
|
||||||
|
|
||||||
extern bool ROMLoaded;
|
extern int ROMSize;
|
||||||
extern int emulating;
|
extern int emulating;
|
||||||
|
|
||||||
|
|
||||||
@ -74,10 +74,10 @@ int main()
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Initialize libFAT for SD and USB
|
// Initialize libFAT for SD and USB
|
||||||
fatInit (8, false);
|
fatInitDefault();
|
||||||
|
|
||||||
// Initialize DVD subsystem (GameCube only)
|
// Initialize DVD subsystem (GameCube only)
|
||||||
#ifdef HW_DOL
|
#ifndef HW_RVL
|
||||||
DVD_Init ();
|
DVD_Init ();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -98,7 +98,7 @@ int main()
|
|||||||
selectedMenu = 2; // change to preferences menu
|
selectedMenu = 2; // change to preferences menu
|
||||||
}
|
}
|
||||||
|
|
||||||
while (!ROMLoaded)
|
while (ROMSize == 0)
|
||||||
{
|
{
|
||||||
MainMenu (selectedMenu);
|
MainMenu (selectedMenu);
|
||||||
}
|
}
|
||||||
|
@ -7,13 +7,14 @@
|
|||||||
*
|
*
|
||||||
* This file controls overall program flow. Most things start and end here!
|
* This file controls overall program flow. Most things start and end here!
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
|
|
||||||
#ifndef _VBA_H_
|
#ifndef _VBA_H_
|
||||||
#define _VBA_H_
|
#define _VBA_H_
|
||||||
|
|
||||||
#include <gccore.h>
|
#include <gccore.h>
|
||||||
#define VERSIONNUM "1.0.3"
|
#define VERSIONNUM "1.0.0"
|
||||||
#define VERSIONSTR "VBA GX 1.0.3"
|
#define VERSIONSTR "VBA GX 1.0.0"
|
||||||
#define VERSIONSTRFULL "Visual Boy Advance GX 1.0.3"
|
#define VERSIONSTRFULL "Visual Boy Advance GX 1.0.0"
|
||||||
|
|
||||||
#define NOTSILENT 0
|
#define NOTSILENT 0
|
||||||
#define SILENT 1
|
#define SILENT 1
|
||||||
@ -45,9 +46,7 @@ struct SGCSettings{
|
|||||||
char smbgcid[20];
|
char smbgcid[20];
|
||||||
char smbsvid[20];
|
char smbsvid[20];
|
||||||
char smbshare[20];
|
char smbshare[20];
|
||||||
int NGCZoom; // 0 - off, 1 - on
|
|
||||||
int VerifySaves;
|
int VerifySaves;
|
||||||
int render; // 0 - filtered, 1 - unfiltered
|
|
||||||
};
|
};
|
||||||
|
|
||||||
extern struct SGCSettings GCSettings;
|
extern struct SGCSettings GCSettings;
|
||||||
|
@ -46,6 +46,4 @@ DefaultSettings ()
|
|||||||
GCSettings.smbgcid[0] = 0;
|
GCSettings.smbgcid[0] = 0;
|
||||||
|
|
||||||
GCSettings.VerifySaves = 0;
|
GCSettings.VerifySaves = 0;
|
||||||
GCSettings.NGCZoom = 0; // zooming default off
|
|
||||||
GCSettings.render = 0; // Unfiltered
|
|
||||||
}
|
}
|
||||||
|
@ -13,40 +13,43 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "agb/GBA.h"
|
#include "GBA.h"
|
||||||
#include "agb/agbprint.h"
|
#include "agbprint.h"
|
||||||
#include "Flash.h"
|
#include "Flash.h"
|
||||||
#include "Port.h"
|
#include "Port.h"
|
||||||
#include "RTC.h"
|
#include "RTC.h"
|
||||||
#include "Sound.h"
|
#include "Sound.h"
|
||||||
|
#include "Text.h"
|
||||||
#include "unzip.h"
|
#include "unzip.h"
|
||||||
#include "Util.h"
|
#include "Util.h"
|
||||||
#include "dmg/GB.h"
|
#include "gb/GB.h"
|
||||||
#include "dmg/gbGlobals.h"
|
#include "gb/gbGlobals.h"
|
||||||
#include "images/saveicon.h"
|
|
||||||
//#include "dmg/gbSound.h"
|
|
||||||
|
|
||||||
#include "vba.h"
|
#include "vba.h"
|
||||||
#include "fileop.h"
|
#include "fileop.h"
|
||||||
#include "dvd.h"
|
|
||||||
#include "smbop.h"
|
|
||||||
#include "memcardop.h"
|
|
||||||
#include "audio.h"
|
#include "audio.h"
|
||||||
#include "vmmem.h"
|
#include "vmmem.h"
|
||||||
|
#include "pal60.h"
|
||||||
#include "input.h"
|
#include "input.h"
|
||||||
#include "video.h"
|
#include "video.h"
|
||||||
#include "menudraw.h"
|
#include "menudraw.h"
|
||||||
#include "gcunzip.h"
|
|
||||||
|
|
||||||
extern "C"
|
extern "C"
|
||||||
{
|
{
|
||||||
#include "tbtime.h"
|
#include "tbtime.h"
|
||||||
|
#include "sdfileio.h"
|
||||||
}
|
}
|
||||||
|
|
||||||
static tb_t start, now;
|
static tb_t start, now;
|
||||||
|
|
||||||
u32 loadtimeradjust;
|
u32 loadtimeradjust;
|
||||||
|
|
||||||
|
int throttle = 100;
|
||||||
|
u32 throttleLastTime = 0;
|
||||||
|
|
||||||
|
static u32 autoFrameSkipLastTime = 0;
|
||||||
|
static int frameskipadjust = 0;
|
||||||
|
|
||||||
int vAspect = 0;
|
int vAspect = 0;
|
||||||
int hAspect = 0;
|
int hAspect = 0;
|
||||||
|
|
||||||
@ -79,7 +82,7 @@ int systemColorDepth = 0;
|
|||||||
u16 systemGbPalette[24];
|
u16 systemGbPalette[24];
|
||||||
u16 systemColorMap16[0x10000];
|
u16 systemColorMap16[0x10000];
|
||||||
//u32 systemColorMap32[0x10000];
|
//u32 systemColorMap32[0x10000];
|
||||||
u32 *systemColorMap32 = NULL;
|
u32 *systemColorMap32 = (u32 *)&systemColorMap16;
|
||||||
|
|
||||||
struct EmulatedSystem emulator =
|
struct EmulatedSystem emulator =
|
||||||
{
|
{
|
||||||
@ -119,7 +122,7 @@ bool systemPauseOnFrame()
|
|||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
/*
|
|
||||||
void GC_Sleep(u32 dwMiliseconds)
|
void GC_Sleep(u32 dwMiliseconds)
|
||||||
{
|
{
|
||||||
int nVBlanks = (dwMiliseconds / 16);
|
int nVBlanks = (dwMiliseconds / 16);
|
||||||
@ -128,9 +131,6 @@ void GC_Sleep(u32 dwMiliseconds)
|
|||||||
VIDEO_WaitVSync();
|
VIDEO_WaitVSync();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
|
|
||||||
static u32 autoFrameSkipLastTime = 0;
|
|
||||||
|
|
||||||
void system10Frames(int rate)
|
void system10Frames(int rate)
|
||||||
{
|
{
|
||||||
@ -139,28 +139,13 @@ void system10Frames(int rate)
|
|||||||
|
|
||||||
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)
|
|
||||||
{
|
|
||||||
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");
|
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)
|
|
||||||
{
|
|
||||||
sprintf(ext, "sav");
|
|
||||||
sprintf(savetype, "SRAM");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
sprintf(ext, "sgm");
|
|
||||||
sprintf(savetype, "Freeze");
|
|
||||||
}
|
|
||||||
|
|
||||||
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();
|
|
||||||
|
|
||||||
// add save icon and comments for Memory Card saves
|
|
||||||
if(method == METHOD_MC_SLOTA || method == METHOD_MC_SLOTB)
|
|
||||||
{
|
|
||||||
offset = sizeof (saveicon);
|
|
||||||
|
|
||||||
// Copy in save icon
|
|
||||||
memcpy (savebuffer, saveicon, offset);
|
|
||||||
|
|
||||||
// And the comments
|
|
||||||
sprintf (savecomment[0], "%s %s", VERSIONSTR, savetype);
|
|
||||||
strncpy(savecomment[1], ROMFilename, 31); // truncate filename to 31 chars
|
|
||||||
savecomment[1][31] = 0; // make sure last char is null byte
|
|
||||||
memcpy (savebuffer + offset, savecomment, 64);
|
|
||||||
offset += 64;
|
|
||||||
}
|
|
||||||
|
|
||||||
// put VBA memory into savebuffer, sets datasize to size of memory written
|
|
||||||
if(action == 0)
|
|
||||||
{
|
|
||||||
if(cartridgeType == 1)
|
|
||||||
datasize = MemgbWriteBatteryFile((char *)savebuffer+offset);
|
|
||||||
else
|
|
||||||
datasize = MemCPUWriteBatteryFile((char *)savebuffer+offset);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
bool written = emulator.emuWriteMemState((char *)savebuffer+offset, SAVEBUFFERSIZE-offset);
|
|
||||||
// we really should set datasize to the exact memory size written
|
|
||||||
// but instead we'll set it at 128K - although much of it will go unused
|
|
||||||
if(written)
|
|
||||||
datasize = (1024*128);
|
|
||||||
}
|
|
||||||
|
|
||||||
// write savebuffer into file
|
|
||||||
if(datasize > 0)
|
|
||||||
{
|
|
||||||
if(method == METHOD_SD || method == METHOD_USB)
|
if(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.emuWriteBattery(filepath);
|
||||||
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(!result && !silent)
|
||||||
{
|
WaitPrompt ((char*) "Save failed");
|
||||||
if(!silent)
|
|
||||||
WaitPrompt ((char*) "Save successful");
|
return result;
|
||||||
result = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if(!silent)
|
|
||||||
WaitPrompt((char *)"No data to save!");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
FreeSaveBuffer();
|
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)
|
||||||
|
{
|
||||||
|
ChangeFATInterface(method, NOTSILENT);
|
||||||
|
sprintf (filepath, "%s/%s/%s.sgm", ROOTFATDIR, GCSettings.SaveFolder, ROMFilename);
|
||||||
|
result = emulator.emuReadState(filepath);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!result && !silent)
|
||||||
|
WaitPrompt ((char*) "State file not found");
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SaveState(int method, bool silent)
|
||||||
|
{
|
||||||
|
char filepath[1024];
|
||||||
|
bool result = false;
|
||||||
|
|
||||||
|
ShowAction ((char*) "Saving...");
|
||||||
|
|
||||||
|
if(method == METHOD_AUTO)
|
||||||
|
method = autoSaveMethod(); // we use 'Save' because we need R/W
|
||||||
|
|
||||||
|
if(method == METHOD_SD || method == METHOD_USB)
|
||||||
|
{
|
||||||
|
ChangeFATInterface(method, NOTSILENT);
|
||||||
|
sprintf (filepath, "%s/%s/%s.sgm", ROOTFATDIR, GCSettings.SaveFolder, ROMFilename);
|
||||||
|
result = emulator.emuWriteState(filepath);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!result && !silent)
|
||||||
|
WaitPrompt ((char*) "Save failed");
|
||||||
|
|
||||||
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,17 +379,15 @@ 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)
|
|
||||||
{
|
|
||||||
WaitPrompt((char *)"Error loading game!");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Set defaults
|
// Set defaults
|
||||||
flashSetSize(0x20000); // 128K saves
|
flashSetSize(0x10000);
|
||||||
rtcEnable(true);
|
rtcEnable(true);
|
||||||
agbPrintEnable(false);
|
agbPrintEnable(false);
|
||||||
soundOffFlag = false;
|
soundOffFlag = false;
|
||||||
@ -676,14 +415,10 @@ bool LoadVBAROM(int method)
|
|||||||
|
|
||||||
emulating = 1;
|
emulating = 1;
|
||||||
|
|
||||||
// reset frameskip variables
|
|
||||||
autoFrameSkipLastTime = systemFrameSkip = 0;
|
|
||||||
|
|
||||||
// Start system clock
|
// Start system clock
|
||||||
mftb(&start);
|
mftb(&start);
|
||||||
|
|
||||||
return true;
|
return 1;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
|
@ -12,7 +12,9 @@
|
|||||||
|
|
||||||
extern struct EmulatedSystem emulator;
|
extern struct EmulatedSystem emulator;
|
||||||
extern u32 loadtimeradjust;
|
extern u32 loadtimeradjust;
|
||||||
bool LoadVBAROM(int method);
|
int loadVBAROM(char filename[]);
|
||||||
void InitialisePalette();
|
void InitialisePalette();
|
||||||
bool LoadBatteryOrState(int method, int action, bool silent);
|
bool LoadBattery(int method, bool silent);
|
||||||
bool SaveBatteryOrState(int method, int action, bool silent);
|
bool SaveBattery(int method, bool silent);
|
||||||
|
bool LoadState(int method, bool silent);
|
||||||
|
bool SaveState(int method, bool silent);
|
||||||
|
@ -11,43 +11,32 @@
|
|||||||
* These are pretty standard functions to setup and use GX scaling.
|
* These are pretty standard functions to setup and use GX scaling.
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
#include <gccore.h>
|
#include <gccore.h>
|
||||||
#include <unistd.h>
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <malloc.h>
|
#include <malloc.h>
|
||||||
#include <wiiuse/wpad.h>
|
#include <wiiuse/wpad.h>
|
||||||
#include "images/bg.h"
|
|
||||||
#include "vba.h"
|
|
||||||
#include "menudraw.h"
|
|
||||||
//#include "pal60.h"
|
|
||||||
|
|
||||||
extern unsigned int SMBTimer; // timer to reset SMB connection
|
|
||||||
u32 FrameTimer = 0;
|
|
||||||
|
|
||||||
/*** External 2D Video ***/
|
/*** External 2D Video ***/
|
||||||
/*** 2D Video Globals ***/
|
/*** 2D Video Globals ***/
|
||||||
GXRModeObj *vmode = NULL; // Graphics Mode Object
|
GXRModeObj *vmode; /*** Graphics Mode Object ***/
|
||||||
unsigned int *xfb[2]; // Framebuffers
|
u32 *xfb[2] = { NULL, NULL }; /*** Framebuffers ***/
|
||||||
int whichfb = 0; // Frame buffer toggle
|
int whichfb = 0; /*** Frame buffer toggle ***/
|
||||||
|
|
||||||
int screenheight;
|
int screenheight;
|
||||||
|
|
||||||
/*** 3D GX ***/
|
/*** 3D GX ***/
|
||||||
#define DEFAULT_FIFO_SIZE ( 256 * 1024 )
|
#define DEFAULT_FIFO_SIZE ( 256 * 1024 )
|
||||||
static u8 gp_fifo[DEFAULT_FIFO_SIZE] ATTRIBUTE_ALIGN(32);
|
static u8 gp_fifo[DEFAULT_FIFO_SIZE] ATTRIBUTE_ALIGN(32);
|
||||||
unsigned int copynow = GX_FALSE;
|
|
||||||
|
|
||||||
/*** Texture memory ***/
|
/*** Texture memory ***/
|
||||||
static u8 *texturemem = NULL;
|
static u8 *texturemem;
|
||||||
static int texturesize;
|
static int texturesize;
|
||||||
|
|
||||||
GXTexObj texobj;
|
GXTexObj texobj;
|
||||||
static Mtx view;
|
static Mtx view;
|
||||||
static int vwidth, vheight, oldvwidth, oldvheight;
|
static int vwidth, vheight, oldvwidth, oldvheight;
|
||||||
static int video_vaspect, video_haspect;
|
unsigned int copynow = GX_FALSE;
|
||||||
int updateScaling;
|
|
||||||
float zoom_level = 1;
|
|
||||||
|
|
||||||
#define HASPECT 80
|
#define HASPECT 80
|
||||||
#define VASPECT 45
|
#define VASPECT 45
|
||||||
@ -81,146 +70,6 @@ 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
|
|
||||||
***************************************************************************/
|
|
||||||
#define TSTACK 16384
|
|
||||||
lwpq_t videoblankqueue;
|
|
||||||
lwp_t vbthread;
|
|
||||||
static unsigned char vbstack[TSTACK];
|
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
* vbgetback
|
|
||||||
*
|
|
||||||
* This callback enables the emulator to keep running while waiting for a
|
|
||||||
* vertical blank.
|
|
||||||
*
|
|
||||||
* Putting LWP to good use :)
|
|
||||||
***************************************************************************/
|
|
||||||
static void *
|
|
||||||
vbgetback (void *arg)
|
|
||||||
{
|
|
||||||
while (1)
|
|
||||||
{
|
|
||||||
VIDEO_WaitVSync (); /**< Wait for video vertical blank */
|
|
||||||
LWP_SuspendThread (vbthread);
|
|
||||||
}
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
* InitVideoThread
|
|
||||||
*
|
|
||||||
* libOGC provides a nice wrapper for LWP access.
|
|
||||||
* This function sets up a new local queue and attaches the thread to it.
|
|
||||||
***************************************************************************/
|
|
||||||
void
|
|
||||||
InitVideoThread ()
|
|
||||||
{
|
|
||||||
/*** Initialise a new queue ***/
|
|
||||||
LWP_InitQueue (&videoblankqueue);
|
|
||||||
|
|
||||||
/*** Create the thread on this queue ***/
|
|
||||||
LWP_CreateThread (&vbthread, vbgetback, NULL, vbstack, TSTACK, 80);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
* copy_to_xfb
|
|
||||||
*
|
|
||||||
* Stock code to copy the GX buffer to the current display mode.
|
|
||||||
* Also increments the frameticker, as it's called for each vb.
|
|
||||||
***************************************************************************/
|
|
||||||
static void
|
|
||||||
copy_to_xfb (u32 arg)
|
|
||||||
{
|
|
||||||
if (copynow == GX_TRUE)
|
|
||||||
{
|
|
||||||
GX_CopyDisp (xfb[whichfb], GX_TRUE);
|
|
||||||
GX_Flush ();
|
|
||||||
copynow = GX_FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
FrameTimer++;
|
|
||||||
SMBTimer++;
|
|
||||||
}
|
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
* Drawing screen
|
|
||||||
***************************************************************************/
|
|
||||||
void
|
|
||||||
clearscreen ()
|
|
||||||
{
|
|
||||||
int colour = COLOR_BLACK;
|
|
||||||
|
|
||||||
whichfb ^= 1;
|
|
||||||
VIDEO_ClearFrameBuffer (vmode, xfb[whichfb], colour);
|
|
||||||
memcpy (xfb[whichfb], &bg, 1280 * 480);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
showscreen ()
|
|
||||||
{
|
|
||||||
VIDEO_SetNextFramebuffer (xfb[whichfb]);
|
|
||||||
VIDEO_Flush ();
|
|
||||||
VIDEO_WaitVSync ();
|
|
||||||
}
|
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
* Scaler Support Functions
|
|
||||||
****************************************************************************/
|
|
||||||
static void draw_init(void)
|
|
||||||
{
|
|
||||||
GX_ClearVtxDesc ();
|
|
||||||
GX_SetVtxDesc (GX_VA_POS, GX_INDEX8);
|
|
||||||
GX_SetVtxDesc (GX_VA_CLR0, GX_INDEX8);
|
|
||||||
GX_SetVtxDesc (GX_VA_TEX0, GX_DIRECT);
|
|
||||||
|
|
||||||
GX_SetVtxAttrFmt (GX_VTXFMT0, GX_VA_POS, GX_POS_XYZ, GX_S16, 0);
|
|
||||||
GX_SetVtxAttrFmt (GX_VTXFMT0, GX_VA_CLR0, GX_CLR_RGBA, GX_RGBA8, 0);
|
|
||||||
GX_SetVtxAttrFmt (GX_VTXFMT0, GX_VA_TEX0, GX_TEX_ST, GX_F32, 0);
|
|
||||||
|
|
||||||
GX_SetArray (GX_VA_POS, square, 3 * sizeof (s16));
|
|
||||||
|
|
||||||
GX_SetNumTexGens (1);
|
|
||||||
GX_SetNumChans (0);
|
|
||||||
|
|
||||||
GX_SetTexCoordGen (GX_TEXCOORD0, GX_TG_MTX2x4, GX_TG_TEX0, GX_IDENTITY);
|
|
||||||
|
|
||||||
GX_InvalidateTexAll();
|
|
||||||
memset (&view, 0, sizeof (Mtx));
|
|
||||||
guLookAt(view, &cam.pos, &cam.up, &cam.view);
|
|
||||||
GX_LoadPosMtxImm (view, GX_PNMTX0);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void draw_vert(u8 pos, u8 c, f32 s, f32 t)
|
|
||||||
{
|
|
||||||
GX_Position1x8(pos);
|
|
||||||
GX_Color1x8(c);
|
|
||||||
GX_TexCoord2f32(s, t);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void draw_square(Mtx v)
|
|
||||||
{
|
|
||||||
Mtx m; // model matrix.
|
|
||||||
Mtx mv; // modelview matrix.
|
|
||||||
|
|
||||||
guMtxIdentity(m);
|
|
||||||
guMtxTransApply(m, m, 0, 0, -100);
|
|
||||||
guMtxConcat(v, m, mv);
|
|
||||||
|
|
||||||
GX_LoadPosMtxImm(mv, GX_PNMTX0);
|
|
||||||
GX_Begin(GX_QUADS, GX_VTXFMT0, 4);
|
|
||||||
draw_vert(0, 0, 0.0, 0.0);
|
|
||||||
draw_vert(1, 0, 1.0, 0.0);
|
|
||||||
draw_vert(2, 0, 1.0, 1.0);
|
|
||||||
draw_vert(3, 0, 0.0, 1.0);
|
|
||||||
GX_End();
|
|
||||||
}
|
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* StartGX
|
* StartGX
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
@ -228,39 +77,32 @@ void GX_Start()
|
|||||||
{
|
{
|
||||||
Mtx p;
|
Mtx p;
|
||||||
|
|
||||||
GXColor background = { 0, 0, 0, 0xff };
|
GXColor gxbackground = { 0, 0, 0, 0xff };
|
||||||
|
|
||||||
/*** Clear out FIFO area ***/
|
/*** Clear out FIFO area ***/
|
||||||
memset(&gp_fifo, 0, DEFAULT_FIFO_SIZE);
|
memset(&gp_fifo, 0, DEFAULT_FIFO_SIZE);
|
||||||
|
|
||||||
/*** Initialise GX ***/
|
/*** Initialise GX ***/
|
||||||
GX_Init(&gp_fifo, DEFAULT_FIFO_SIZE);
|
GX_Init(&gp_fifo, DEFAULT_FIFO_SIZE);
|
||||||
GX_SetCopyClear (background, 0x00ffffff);
|
GX_SetCopyClear(gxbackground, 0x00ffffff);
|
||||||
|
|
||||||
|
|
||||||
GX_SetViewport(0, 0, vmode->fbWidth, vmode->efbHeight, 0, 1);
|
GX_SetViewport(0, 0, vmode->fbWidth, vmode->efbHeight, 0, 1);
|
||||||
GX_SetDispCopyYScale((f32) vmode->xfbHeight / (f32) vmode->efbHeight);
|
GX_SetDispCopyYScale((f32) vmode->xfbHeight / (f32) vmode->efbHeight);
|
||||||
GX_SetScissor(0, 0, vmode->fbWidth, vmode->efbHeight);
|
GX_SetScissor(0, 0, vmode->fbWidth, vmode->efbHeight);
|
||||||
|
|
||||||
GX_SetDispCopySrc(0, 0, vmode->fbWidth, vmode->efbHeight);
|
GX_SetDispCopySrc(0, 0, vmode->fbWidth, vmode->efbHeight);
|
||||||
GX_SetDispCopyDst(vmode->fbWidth, vmode->xfbHeight);
|
GX_SetDispCopyDst(vmode->fbWidth, vmode->xfbHeight);
|
||||||
GX_SetCopyFilter (vmode->aa, vmode->sample_pattern, GX_TRUE, vmode->vfilter);
|
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_SetFieldMode(vmode->field_rendering,
|
||||||
|
((vmode->viHeight ==
|
||||||
|
2 * vmode->xfbHeight) ? GX_ENABLE : GX_DISABLE));
|
||||||
GX_SetPixelFmt(GX_PF_RGB8_Z24, GX_ZC_LINEAR);
|
GX_SetPixelFmt(GX_PF_RGB8_Z24, GX_ZC_LINEAR);
|
||||||
GX_SetCullMode(GX_CULL_NONE);
|
GX_SetCullMode(GX_CULL_NONE);
|
||||||
|
GX_CopyDisp(xfb[whichfb ^ 1], GX_TRUE);
|
||||||
GX_SetDispCopyGamma(GX_GM_1_0);
|
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);
|
guPerspective(p, 60, 1.33F, 10.0F, 1000.0F);
|
||||||
GX_LoadProjectionMtx(p, GX_PERSPECTIVE);
|
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
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
@ -289,15 +131,6 @@ void InitialiseVideo ()
|
|||||||
VIDEO_Init();
|
VIDEO_Init();
|
||||||
|
|
||||||
vmode = VIDEO_GetPreferredMode(NULL);
|
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);
|
VIDEO_Configure(vmode);
|
||||||
|
|
||||||
screenheight = vmode->xfbHeight;
|
screenheight = vmode->xfbHeight;
|
||||||
@ -305,150 +138,85 @@ void InitialiseVideo ()
|
|||||||
xfb[0] = (u32 *) MEM_K0_TO_K1 (SYS_AllocateFramebuffer (vmode));
|
xfb[0] = (u32 *) MEM_K0_TO_K1 (SYS_AllocateFramebuffer (vmode));
|
||||||
xfb[1] = (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_SetNextFramebuffer(xfb[0]);
|
||||||
VIDEO_SetBlack(FALSE);
|
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_Flush();
|
||||||
VIDEO_WaitVSync();
|
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();
|
if(vmode->viTVMode&VI_NON_INTERLACE) VIDEO_WaitVSync();
|
||||||
else while (VIDEO_GetNextField()) VIDEO_WaitVSync();
|
VIDEO_SetPostRetraceCallback((VIRetraceCallback)UpdatePadsCB);
|
||||||
|
VIDEO_SetNextFramebuffer(xfb[0]);
|
||||||
|
|
||||||
GX_SetViewport (0, 0, vmode->fbWidth, vmode->efbHeight, 0, 1);
|
GX_Start();
|
||||||
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()
|
/****************************************************************************
|
||||||
|
* Scaler Support Functions
|
||||||
|
****************************************************************************/
|
||||||
|
static void draw_init(void)
|
||||||
{
|
{
|
||||||
// Update scaling
|
GX_ClearVtxDesc();
|
||||||
int xscale = video_haspect;
|
GX_SetVtxDesc(GX_VA_POS, GX_INDEX8);
|
||||||
int yscale = video_vaspect;
|
GX_SetVtxDesc(GX_VA_CLR0, GX_INDEX8);
|
||||||
|
GX_SetVtxDesc(GX_VA_TEX0, GX_DIRECT);
|
||||||
|
|
||||||
// change zoom
|
GX_SetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_POS_XYZ, GX_S16, 0);
|
||||||
xscale *= zoom_level;
|
GX_SetVtxAttrFmt(GX_VTXFMT0, GX_VA_CLR0, GX_CLR_RGBA, GX_RGBA8, 0);
|
||||||
yscale *= zoom_level;
|
GX_SetVtxAttrFmt(GX_VTXFMT0, GX_VA_TEX0, GX_TEX_ST, GX_F32, 0);
|
||||||
|
|
||||||
// Set new aspect (now with crap AR hack!)
|
GX_SetArray(GX_VA_POS, square, 3 * sizeof(s16));
|
||||||
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_SetNumTexGens(1);
|
||||||
|
GX_SetTexCoordGen(GX_TEXCOORD0, GX_TG_MTX2x4, GX_TG_TEX0, GX_IDENTITY);
|
||||||
|
|
||||||
GX_InitTexObj (&texobj, texturemem, vwidth, vheight, GX_TF_RGB565, GX_CLAMP, GX_CLAMP, GX_FALSE); // initialize the texture obj we are going to use
|
GX_InvalidateTexAll();
|
||||||
|
|
||||||
if (GCSettings.render == 1)
|
GX_InitTexObj(&texobj, texturemem, vwidth, vheight, GX_TF_RGB565,
|
||||||
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_CLAMP, GX_CLAMP, GX_FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
GX_LoadTexObj (&texobj, GX_TEXMAP0); // load texture object so its ready to use
|
static void draw_vert(u8 pos, u8 c, f32 s, f32 t)
|
||||||
|
{
|
||||||
|
GX_Position1x8(pos);
|
||||||
|
GX_Color1x8(c);
|
||||||
|
GX_TexCoord2f32(s, t);
|
||||||
|
}
|
||||||
|
|
||||||
draw_init();
|
static void draw_square(Mtx v)
|
||||||
updateScaling = 0;
|
{
|
||||||
|
Mtx m; // model matrix.
|
||||||
|
Mtx mv; // modelview matrix.
|
||||||
|
|
||||||
|
guMtxIdentity(m);
|
||||||
|
guMtxTransApply(m, m, 0, 0, -100);
|
||||||
|
guMtxConcat(v, m, mv);
|
||||||
|
|
||||||
|
GX_LoadPosMtxImm(mv, GX_PNMTX0);
|
||||||
|
GX_Begin(GX_QUADS, GX_VTXFMT0, 4);
|
||||||
|
draw_vert(0, 0, 0.0, 0.0);
|
||||||
|
draw_vert(1, 0, 1.0, 0.0);
|
||||||
|
draw_vert(2, 0, 1.0, 1.0);
|
||||||
|
draw_vert(3, 0, 0.0, 1.0);
|
||||||
|
GX_End();
|
||||||
}
|
}
|
||||||
|
|
||||||
void GX_Render_Init(int width, int height, int haspect, int vaspect)
|
void GX_Render_Init(int width, int height, int haspect, int vaspect)
|
||||||
{
|
{
|
||||||
ResetVideo_Emu (); // reset video to emulator rendering settings
|
/*** Set new aspect (now with crap AR hack!) ***/
|
||||||
|
square[0] = square[9] = (-haspect - 7);
|
||||||
if (texturemem)
|
square[3] = square[6] = (haspect + 7);
|
||||||
free(texturemem);
|
square[1] = square[4] = (vaspect + 7);
|
||||||
|
square[7] = square[10] = (-vaspect - 7);
|
||||||
|
|
||||||
/*** Allocate 32byte aligned texture memory ***/
|
/*** Allocate 32byte aligned texture memory ***/
|
||||||
texturesize = (width * height) * 2;
|
texturesize = (width * height) * 2;
|
||||||
|
|
||||||
texturemem = (u8 *) memalign(32, texturesize);
|
texturemem = (u8 *) memalign(32, texturesize);
|
||||||
|
|
||||||
memset(texturemem, 0, texturesize);
|
memset(texturemem, 0, texturesize);
|
||||||
|
|
||||||
/*** Setup for first call to scaler ***/
|
/*** Setup for first call to scaler ***/
|
||||||
vwidth = width;
|
vwidth = vheight = oldvwidth = oldvheight = -1;
|
||||||
vheight = height;
|
|
||||||
oldvwidth = oldvheight = -1;
|
|
||||||
|
|
||||||
video_vaspect = vaspect;
|
|
||||||
video_haspect = haspect;
|
|
||||||
|
|
||||||
UpdateScaling();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* GX_Render
|
* GX_Render
|
||||||
*
|
*
|
||||||
@ -469,30 +237,24 @@ void GX_Render(int width, int height, u8 * buffer, int pitch)
|
|||||||
vwidth = width;
|
vwidth = width;
|
||||||
vheight = height;
|
vheight = height;
|
||||||
|
|
||||||
#ifdef VIDEO_THREADING
|
|
||||||
// Ensure previous vb has complete
|
|
||||||
while ((LWP_ThreadIsSuspended (vbthread) == 0) || (copynow == GX_TRUE))
|
|
||||||
#else
|
|
||||||
while (copynow == GX_TRUE)
|
|
||||||
#endif
|
|
||||||
{
|
|
||||||
usleep (50);
|
|
||||||
}
|
|
||||||
|
|
||||||
whichfb ^= 1;
|
whichfb ^= 1;
|
||||||
|
|
||||||
if(updateScaling)
|
|
||||||
{
|
|
||||||
UpdateScaling();
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((oldvheight != vheight) || (oldvwidth != vwidth))
|
if ((oldvheight != vheight) || (oldvwidth != vwidth))
|
||||||
{
|
{
|
||||||
|
/** Update scaling **/
|
||||||
oldvwidth = vwidth;
|
oldvwidth = vwidth;
|
||||||
oldvheight = vheight;
|
oldvheight = vheight;
|
||||||
updateScaling = 1;
|
draw_init();
|
||||||
|
memset(&view, 0, sizeof(Mtx));
|
||||||
|
guLookAt(view, &cam.pos, &cam.up, &cam.view);
|
||||||
|
GX_SetViewport(0, 0, vmode->fbWidth, vmode->efbHeight, 0, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GX_InvVtxCache();
|
||||||
|
GX_InvalidateTexAll();
|
||||||
|
GX_SetTevOp(GX_TEVSTAGE0, GX_DECAL);
|
||||||
|
GX_SetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD0, GX_TEXMAP0, GX_COLOR0A0);
|
||||||
|
|
||||||
for (h = 0; h < vheight; h += 4)
|
for (h = 0; h < vheight; h += 4)
|
||||||
{
|
{
|
||||||
for (w = 0; w < (vwidth >> 2); w++)
|
for (w = 0; w < (vwidth >> 2); w++)
|
||||||
@ -522,43 +284,49 @@ void GX_Render(int width, int height, u8 * buffer, int pitch)
|
|||||||
}
|
}
|
||||||
|
|
||||||
DCFlushRange(texturemem, texturesize);
|
DCFlushRange(texturemem, texturesize);
|
||||||
GX_InvalidateTexAll ();
|
|
||||||
|
GX_SetNumChans(1);
|
||||||
|
GX_LoadTexObj(&texobj, GX_TEXMAP0);
|
||||||
|
|
||||||
draw_square(view);
|
draw_square(view);
|
||||||
|
|
||||||
GX_DrawDone();
|
GX_DrawDone();
|
||||||
|
|
||||||
|
GX_SetZMode(GX_TRUE, GX_LEQUAL, GX_TRUE);
|
||||||
|
GX_SetColorUpdate(GX_TRUE);
|
||||||
|
GX_CopyDisp(xfb[whichfb], GX_TRUE);
|
||||||
|
GX_Flush();
|
||||||
|
|
||||||
VIDEO_SetNextFramebuffer(xfb[whichfb]);
|
VIDEO_SetNextFramebuffer(xfb[whichfb]);
|
||||||
VIDEO_Flush();
|
VIDEO_Flush();
|
||||||
copynow = GX_TRUE;
|
//VIDEO_WaitVSync();
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef VIDEO_THREADING
|
|
||||||
// Return to caller, don't waste time waiting for vb
|
/****************************************************************************
|
||||||
LWP_ResumeThread (vbthread);
|
* Drawing screen
|
||||||
|
***************************************************************************/
|
||||||
|
void
|
||||||
|
clearscreen (int c)
|
||||||
|
{
|
||||||
|
int colour = COLOR_WHITE;
|
||||||
|
|
||||||
|
whichfb ^= 1;
|
||||||
|
VIDEO_ClearFrameBuffer (vmode, xfb[whichfb], colour);
|
||||||
|
#ifdef HW_RVL
|
||||||
|
// on wii copy from memory
|
||||||
|
//memcpy ((char *) xfb[whichfb], (char *) backdrop, 640 * screenheight * 2);
|
||||||
|
#else
|
||||||
|
// on gc copy from aram
|
||||||
|
//ARAMFetch ((char *) xfb[whichfb], (char *) AR_BACKDROP, 640 * screenheight * 2);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
* Zoom Functions
|
|
||||||
***************************************************************************/
|
|
||||||
void
|
void
|
||||||
zoom (float speed)
|
showscreen ()
|
||||||
{
|
{
|
||||||
if (zoom_level > 1)
|
copynow = GX_FALSE;
|
||||||
zoom_level += (speed / -100.0);
|
VIDEO_SetNextFramebuffer (xfb[whichfb]);
|
||||||
else
|
VIDEO_Flush ();
|
||||||
zoom_level += (speed / -200.0);
|
VIDEO_WaitVSync ();
|
||||||
|
|
||||||
if (zoom_level < 0.5) zoom_level = 0.5;
|
|
||||||
else if (zoom_level > 10.0) zoom_level = 10.0;
|
|
||||||
|
|
||||||
oldvheight = 0; // update video
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
zoom_reset ()
|
|
||||||
{
|
|
||||||
zoom_level = 1.0;
|
|
||||||
|
|
||||||
oldvheight = 0; // update video
|
|
||||||
}
|
}
|
||||||
|
@ -15,13 +15,9 @@
|
|||||||
#define __GXHDR__
|
#define __GXHDR__
|
||||||
|
|
||||||
void InitialiseVideo ();
|
void InitialiseVideo ();
|
||||||
void GX_Start();
|
|
||||||
void GX_Render_Init(int width, int height, int haspect, int vaspect);
|
void GX_Render_Init(int width, int height, int haspect, int vaspect);
|
||||||
void GX_Render(int width, int height, u8 * buffer, int pitch);
|
void GX_Render(int width, int height, u8 * buffer, int pitch);
|
||||||
void clearscreen ();
|
void clearscreen (int colour = COLOR_BLACK);
|
||||||
void showscreen ();
|
void showscreen ();
|
||||||
void zoom (float speed);
|
|
||||||
void zoom_reset ();
|
|
||||||
void ResetVideo_Menu ();
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -9,6 +9,7 @@
|
|||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
|
|
||||||
#ifdef HW_RVL
|
#ifdef HW_RVL
|
||||||
|
#include "sdfileio.h"
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
@ -16,18 +17,12 @@
|
|||||||
#include <fat.h>
|
#include <fat.h>
|
||||||
#include <sys/dir.h>
|
#include <sys/dir.h>
|
||||||
|
|
||||||
#include "agb/GBA.h"
|
#include "GBA.h"
|
||||||
#include "Globals.h"
|
#include "Globals.h"
|
||||||
#include "Util.h"
|
#include "Util.h"
|
||||||
#include "Port.h"
|
#include "Port.h"
|
||||||
|
|
||||||
#include "vba.h"
|
|
||||||
#include "smbop.h"
|
|
||||||
#include "fileop.h"
|
|
||||||
#include "dvd.h"
|
|
||||||
#include "menudraw.h"
|
#include "menudraw.h"
|
||||||
#include "filesel.h"
|
|
||||||
#include "gcunzip.h"
|
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#include "tbtime.h"
|
#include "tbtime.h"
|
||||||
@ -40,7 +35,9 @@ extern "C" {
|
|||||||
unsigned int MEM2Storage = 0x91000000;
|
unsigned int MEM2Storage = 0x91000000;
|
||||||
|
|
||||||
static char *gbabase = NULL;
|
static char *gbabase = NULL;
|
||||||
|
static FILE *romfile = NULL;
|
||||||
static u32 GBAROMSize = 0;
|
static u32 GBAROMSize = 0;
|
||||||
|
static char romfilename[1024];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* GBA Memory
|
* GBA Memory
|
||||||
@ -91,7 +88,12 @@ static void VMClose( void )
|
|||||||
if ( gbabase != NULL )
|
if ( gbabase != NULL )
|
||||||
free(gbabase);
|
free(gbabase);
|
||||||
|
|
||||||
|
if ( romfile != NULL )
|
||||||
|
gen_fclose(romfile);
|
||||||
|
|
||||||
gbabase = NULL;
|
gbabase = NULL;
|
||||||
|
romfile = NULL;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
@ -99,49 +101,49 @@ static void VMClose( void )
|
|||||||
*
|
*
|
||||||
* MEM2 version of GBA CPULoadROM
|
* MEM2 version of GBA CPULoadROM
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
int VMCPULoadROM( char *filename )
|
||||||
bool VMCPULoadROM(int method)
|
|
||||||
{
|
{
|
||||||
|
int res=0;
|
||||||
|
char temp[512];
|
||||||
VMClose();
|
VMClose();
|
||||||
VMAllocGBA();
|
VMAllocGBA();
|
||||||
|
|
||||||
GBAROMSize = 0;
|
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);
|
||||||
|
|
||||||
|
if ( (u32)res != GBAROMSize )
|
||||||
{
|
{
|
||||||
case METHOD_SD:
|
WaitPrompt((char*) "Error reading file!");
|
||||||
case METHOD_USB:
|
while(1);
|
||||||
if(inSz)
|
|
||||||
GBAROMSize = LoadFATSzFile(szpath, (unsigned char *)rom);
|
|
||||||
else
|
|
||||||
GBAROMSize = LoadFATFile((char *)rom, filelist[selection].length);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case METHOD_DVD:
|
|
||||||
if(inSz)
|
|
||||||
GBAROMSize = SzExtractFile(filelist[selection].offset, (unsigned char *)rom);
|
|
||||||
else
|
|
||||||
GBAROMSize = LoadDVDFile((unsigned char *)rom, filelist[selection].length);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case METHOD_SMB:
|
|
||||||
if(inSz)
|
|
||||||
GBAROMSize = LoadSMBSzFile(szpath, (unsigned char *)rom);
|
|
||||||
else
|
|
||||||
GBAROMSize = LoadSMBFile((char *)rom, filelist[selection].length);
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
strcpy( romfilename, filename );
|
||||||
|
|
||||||
if(GBAROMSize)
|
|
||||||
{
|
|
||||||
CPUUpdateRenderBuffers( true );
|
CPUUpdateRenderBuffers( true );
|
||||||
return true;
|
|
||||||
}
|
return 1;
|
||||||
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,50 +377,25 @@ 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();
|
|
||||||
return 0; // not implemented
|
|
||||||
break;
|
|
||||||
|
|
||||||
case METHOD_SMB:
|
|
||||||
VMClose();
|
|
||||||
return 0; // not implemented
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Check filename length */
|
|
||||||
if ((strlen(currentdir)+1+strlen(filelist[selection].filename)) < MAXPATHLEN)
|
|
||||||
sprintf(filepath, "%s/%s",currentdir,filelist[selection].filename);
|
|
||||||
else
|
|
||||||
{
|
|
||||||
WaitPrompt((char*) "Maximum filepath length reached!");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
romfile = fopen(filepath, "rb");
|
|
||||||
if ( romfile == NULL )
|
if ( romfile == NULL )
|
||||||
{
|
{
|
||||||
WaitPrompt((char*) "Error opening file!");
|
WaitPrompt((char*) "Error opening file!");
|
||||||
|
while(1);
|
||||||
VMClose();
|
VMClose();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -425,13 +403,12 @@ int VMCPULoadROM(int method)
|
|||||||
// printf("ROM Size %d\n", romfile->fsize);
|
// printf("ROM Size %d\n", romfile->fsize);
|
||||||
|
|
||||||
/* Always use VM, regardless of ROM size */
|
/* Always use VM, regardless of ROM size */
|
||||||
res = fread(rom, 1, (1 << VMSHIFTBITS), romfile);
|
res = gen_fread(rom, 1, (1 << VMSHIFTBITS), romfile);
|
||||||
if ( res != (1 << VMSHIFTBITS ) )
|
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);
|
||||||
@ -441,6 +418,9 @@ int VMCPULoadROM(int method)
|
|||||||
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;
|
||||||
|
|
||||||
|
strcpy( romfilename, filename );
|
||||||
|
|
||||||
CPUUpdateRenderBuffers( true );
|
CPUUpdateRenderBuffers( true );
|
||||||
|
|
||||||
@ -461,24 +441,22 @@ static void VMNewPage( int pageid )
|
|||||||
|
|
||||||
mftb(&start);
|
mftb(&start);
|
||||||
|
|
||||||
res = fseek( romfile, pageid << VMSHIFTBITS, SEEK_SET );
|
res = gen_fseek( romfile, pageid << VMSHIFTBITS, SEEK_SET );
|
||||||
if ( ! res )
|
if ( ! res )
|
||||||
{
|
{
|
||||||
sprintf(msg, "Seek error! - Offset %08x %d\n", pageid << VMSHIFTBITS, res);
|
sprintf(msg, "Seek error! - Offset %08x %d\n", pageid << VMSHIFTBITS, res);
|
||||||
WaitPrompt(msg);
|
WaitPrompt(msg);
|
||||||
VMClose();
|
while(1);
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
VMAllocate( pageid );
|
VMAllocate( pageid );
|
||||||
|
|
||||||
res = fread( vmpage[pageid].pageptr, 1, 1 << VMSHIFTBITS, romfile );
|
res = gen_fread( vmpage[pageid].pageptr, 1, 1 << VMSHIFTBITS, romfile );
|
||||||
if ( res != ( 1 << VMSHIFTBITS ) )
|
if ( res != ( 1 << VMSHIFTBITS ) )
|
||||||
{
|
{
|
||||||
sprintf(msg, "Error reading! %d bytes only\n", res);
|
sprintf(msg, "Error reading! %d bytes only\n", res);
|
||||||
WaitPrompt(msg);
|
WaitPrompt(msg);
|
||||||
VMClose();
|
while(1);
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
mftb(&end);
|
mftb(&end);
|
||||||
@ -538,8 +516,7 @@ u32 VMRead32( u32 address )
|
|||||||
default:
|
default:
|
||||||
sprintf(msg, "VM32 : Unknown page type! (%d) [%d]", vmpage[pageid].pagetype, pageid);
|
sprintf(msg, "VM32 : Unknown page type! (%d) [%d]", vmpage[pageid].pagetype, pageid);
|
||||||
WaitPrompt(msg);
|
WaitPrompt(msg);
|
||||||
VMClose();
|
while(1);
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Can never get here ... but stops gcc bitchin' */
|
/* Can never get here ... but stops gcc bitchin' */
|
||||||
@ -578,8 +555,7 @@ u16 VMRead16( u32 address )
|
|||||||
|
|
||||||
default:
|
default:
|
||||||
WaitPrompt((char*) "VM16 : Unknown page type!");
|
WaitPrompt((char*) "VM16 : Unknown page type!");
|
||||||
VMClose();
|
while(1);
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Can never get here ... but stops gcc bitchin' */
|
/* Can never get here ... but stops gcc bitchin' */
|
||||||
@ -618,8 +594,7 @@ u8 VMRead8( u32 address )
|
|||||||
|
|
||||||
default:
|
default:
|
||||||
WaitPrompt((char*) "VM8 : Unknown page type!");
|
WaitPrompt((char*) "VM8 : Unknown page type!");
|
||||||
VMClose();
|
while(1);
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Can never get here ... but stops gcc bitchin' */
|
/* Can never get here ... but stops gcc bitchin' */
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
#ifndef __VBAVMHDR__
|
#ifndef __VBAVMHDR__
|
||||||
#define __VBAVMHDR__
|
#define __VBAVMHDR__
|
||||||
|
|
||||||
bool VMCPULoadROM(int method);
|
int VMCPULoadROM( char *filename );
|
||||||
u32 VMRead32( u32 address );
|
u32 VMRead32( u32 address );
|
||||||
u16 VMRead16( u32 address );
|
u16 VMRead16( u32 address );
|
||||||
u8 VMRead8( u32 address );
|
u8 VMRead8( u32 address );
|
||||||
|
@ -1,70 +0,0 @@
|
|||||||
/* 7zAlloc.c */
|
|
||||||
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include "7zAlloc.h"
|
|
||||||
|
|
||||||
/* #define _SZ_ALLOC_DEBUG */
|
|
||||||
/* use _SZ_ALLOC_DEBUG to debug alloc/free operations */
|
|
||||||
|
|
||||||
#ifdef _SZ_ALLOC_DEBUG
|
|
||||||
|
|
||||||
#ifdef _WIN32
|
|
||||||
#include <windows.h>
|
|
||||||
#endif
|
|
||||||
#include <stdio.h>
|
|
||||||
int g_allocCount = 0;
|
|
||||||
int g_allocCountTemp = 0;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void *SzAlloc(size_t size)
|
|
||||||
{
|
|
||||||
if (size == 0)
|
|
||||||
return 0;
|
|
||||||
#ifdef _SZ_ALLOC_DEBUG
|
|
||||||
fprintf(stderr, "\nAlloc %10d bytes; count = %10d", size, g_allocCount);
|
|
||||||
g_allocCount++;
|
|
||||||
#endif
|
|
||||||
return malloc(size);
|
|
||||||
}
|
|
||||||
|
|
||||||
void SzFree(void *address)
|
|
||||||
{
|
|
||||||
#ifdef _SZ_ALLOC_DEBUG
|
|
||||||
if (address != 0)
|
|
||||||
{
|
|
||||||
g_allocCount--;
|
|
||||||
fprintf(stderr, "\nFree; count = %10d", g_allocCount);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
free(address);
|
|
||||||
}
|
|
||||||
|
|
||||||
void *SzAllocTemp(size_t size)
|
|
||||||
{
|
|
||||||
if (size == 0)
|
|
||||||
return 0;
|
|
||||||
#ifdef _SZ_ALLOC_DEBUG
|
|
||||||
fprintf(stderr, "\nAlloc_temp %10d bytes; count = %10d", size, g_allocCountTemp);
|
|
||||||
g_allocCountTemp++;
|
|
||||||
#ifdef _WIN32
|
|
||||||
return HeapAlloc(GetProcessHeap(), 0, size);
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
return malloc(size);
|
|
||||||
}
|
|
||||||
|
|
||||||
void SzFreeTemp(void *address)
|
|
||||||
{
|
|
||||||
#ifdef _SZ_ALLOC_DEBUG
|
|
||||||
if (address != 0)
|
|
||||||
{
|
|
||||||
g_allocCountTemp--;
|
|
||||||
fprintf(stderr, "\nFree_temp; count = %10d", g_allocCountTemp);
|
|
||||||
}
|
|
||||||
#ifdef _WIN32
|
|
||||||
HeapFree(GetProcessHeap(), 0, address);
|
|
||||||
return;
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
free(address);
|
|
||||||
}
|
|
@ -1,20 +0,0 @@
|
|||||||
/* 7zAlloc.h */
|
|
||||||
|
|
||||||
#ifndef __7Z_ALLOC_H
|
|
||||||
#define __7Z_ALLOC_H
|
|
||||||
|
|
||||||
#include <stddef.h>
|
|
||||||
|
|
||||||
typedef struct _ISzAlloc
|
|
||||||
{
|
|
||||||
void *(*Alloc)(size_t size);
|
|
||||||
void (*Free)(void *address); /* address can be 0 */
|
|
||||||
} ISzAlloc;
|
|
||||||
|
|
||||||
void *SzAlloc(size_t size);
|
|
||||||
void SzFree(void *address);
|
|
||||||
|
|
||||||
void *SzAllocTemp(size_t size);
|
|
||||||
void SzFreeTemp(void *address);
|
|
||||||
|
|
||||||
#endif
|
|
@ -1,29 +0,0 @@
|
|||||||
/* 7zBuffer.c */
|
|
||||||
|
|
||||||
#include "7zBuffer.h"
|
|
||||||
#include "7zAlloc.h"
|
|
||||||
|
|
||||||
void SzByteBufferInit(CSzByteBuffer *buffer)
|
|
||||||
{
|
|
||||||
buffer->Capacity = 0;
|
|
||||||
buffer->Items = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int SzByteBufferCreate(CSzByteBuffer *buffer, size_t newCapacity, void * (*allocFunc)(size_t size))
|
|
||||||
{
|
|
||||||
buffer->Capacity = newCapacity;
|
|
||||||
if (newCapacity == 0)
|
|
||||||
{
|
|
||||||
buffer->Items = 0;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
buffer->Items = (Byte *)allocFunc(newCapacity);
|
|
||||||
return (buffer->Items != 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void SzByteBufferFree(CSzByteBuffer *buffer, void (*freeFunc)(void *))
|
|
||||||
{
|
|
||||||
freeFunc(buffer->Items);
|
|
||||||
buffer->Items = 0;
|
|
||||||
buffer->Capacity = 0;
|
|
||||||
}
|
|
@ -1,19 +0,0 @@
|
|||||||
/* 7zBuffer.h */
|
|
||||||
|
|
||||||
#ifndef __7Z_BUFFER_H
|
|
||||||
#define __7Z_BUFFER_H
|
|
||||||
|
|
||||||
#include <stddef.h>
|
|
||||||
#include "7zTypes.h"
|
|
||||||
|
|
||||||
typedef struct _CSzByteBuffer
|
|
||||||
{
|
|
||||||
size_t Capacity;
|
|
||||||
Byte *Items;
|
|
||||||
}CSzByteBuffer;
|
|
||||||
|
|
||||||
void SzByteBufferInit(CSzByteBuffer *buffer);
|
|
||||||
int SzByteBufferCreate(CSzByteBuffer *buffer, size_t newCapacity, void * (*allocFunc)(size_t size));
|
|
||||||
void SzByteBufferFree(CSzByteBuffer *buffer, void (*freeFunc)(void *));
|
|
||||||
|
|
||||||
#endif
|
|
@ -1,76 +0,0 @@
|
|||||||
/* 7zCrc.c */
|
|
||||||
|
|
||||||
#include "7zCrc.h"
|
|
||||||
|
|
||||||
#define kCrcPoly 0xEDB88320
|
|
||||||
|
|
||||||
UInt32 g_CrcTable[256];
|
|
||||||
|
|
||||||
void InitCrcTable()
|
|
||||||
{
|
|
||||||
UInt32 i;
|
|
||||||
for (i = 0; i < 256; i++)
|
|
||||||
{
|
|
||||||
UInt32 r = i;
|
|
||||||
int j;
|
|
||||||
for (j = 0; j < 8; j++)
|
|
||||||
if (r & 1)
|
|
||||||
r = (r >> 1) ^ kCrcPoly;
|
|
||||||
else
|
|
||||||
r >>= 1;
|
|
||||||
g_CrcTable[i] = r;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void CrcInit(UInt32 *crc) { *crc = 0xFFFFFFFF; }
|
|
||||||
UInt32 CrcGetDigest(UInt32 *crc) { return *crc ^ 0xFFFFFFFF; }
|
|
||||||
|
|
||||||
void CrcUpdateByte(UInt32 *crc, Byte b)
|
|
||||||
{
|
|
||||||
*crc = g_CrcTable[((Byte)(*crc)) ^ b] ^ (*crc >> 8);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CrcUpdateUInt16(UInt32 *crc, UInt16 v)
|
|
||||||
{
|
|
||||||
CrcUpdateByte(crc, (Byte)v);
|
|
||||||
CrcUpdateByte(crc, (Byte)(v >> 8));
|
|
||||||
}
|
|
||||||
|
|
||||||
void CrcUpdateUInt32(UInt32 *crc, UInt32 v)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
for (i = 0; i < 4; i++)
|
|
||||||
CrcUpdateByte(crc, (Byte)(v >> (8 * i)));
|
|
||||||
}
|
|
||||||
|
|
||||||
void CrcUpdateUInt64(UInt32 *crc, UInt64 v)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
for (i = 0; i < 8; i++)
|
|
||||||
{
|
|
||||||
CrcUpdateByte(crc, (Byte)(v));
|
|
||||||
v >>= 8;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void CrcUpdate(UInt32 *crc, const void *data, size_t size)
|
|
||||||
{
|
|
||||||
UInt32 v = *crc;
|
|
||||||
const Byte *p = (const Byte *)data;
|
|
||||||
for (; size > 0 ; size--, p++)
|
|
||||||
v = g_CrcTable[((Byte)(v)) ^ *p] ^ (v >> 8);
|
|
||||||
*crc = v;
|
|
||||||
}
|
|
||||||
|
|
||||||
UInt32 CrcCalculateDigest(const void *data, size_t size)
|
|
||||||
{
|
|
||||||
UInt32 crc;
|
|
||||||
CrcInit(&crc);
|
|
||||||
CrcUpdate(&crc, data, size);
|
|
||||||
return CrcGetDigest(&crc);
|
|
||||||
}
|
|
||||||
|
|
||||||
int CrcVerifyDigest(UInt32 digest, const void *data, size_t size)
|
|
||||||
{
|
|
||||||
return (CrcCalculateDigest(data, size) == digest);
|
|
||||||
}
|
|
@ -1,24 +0,0 @@
|
|||||||
/* 7zCrc.h */
|
|
||||||
|
|
||||||
#ifndef __7Z_CRC_H
|
|
||||||
#define __7Z_CRC_H
|
|
||||||
|
|
||||||
#include <stddef.h>
|
|
||||||
|
|
||||||
#include "7zTypes.h"
|
|
||||||
|
|
||||||
extern UInt32 g_CrcTable[256];
|
|
||||||
void InitCrcTable();
|
|
||||||
|
|
||||||
void CrcInit(UInt32 *crc);
|
|
||||||
UInt32 CrcGetDigest(UInt32 *crc);
|
|
||||||
void CrcUpdateByte(UInt32 *crc, Byte v);
|
|
||||||
void CrcUpdateUInt16(UInt32 *crc, UInt16 v);
|
|
||||||
void CrcUpdateUInt32(UInt32 *crc, UInt32 v);
|
|
||||||
void CrcUpdateUInt64(UInt32 *crc, UInt64 v);
|
|
||||||
void CrcUpdate(UInt32 *crc, const void *data, size_t size);
|
|
||||||
|
|
||||||
UInt32 CrcCalculateDigest(const void *data, size_t size);
|
|
||||||
int CrcVerifyDigest(UInt32 digest, const void *data, size_t size);
|
|
||||||
|
|
||||||
#endif
|
|
@ -1,361 +0,0 @@
|
|||||||
/* 7zDecode.c */
|
|
||||||
|
|
||||||
#include "7zDecode.h"
|
|
||||||
#ifdef _SZ_ONE_DIRECTORY
|
|
||||||
#include "LzmaDecode.h"
|
|
||||||
#else
|
|
||||||
#include "../../Compress/LZMA_C/LzmaDecode.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef _LZMA_OUT_READ
|
|
||||||
#include <string.h> // for memcpy
|
|
||||||
#endif
|
|
||||||
|
|
||||||
CMethodID k_Copy = { { 0x0 }, 1 };
|
|
||||||
CMethodID k_LZMA = { { 0x3, 0x1, 0x1 }, 3 };
|
|
||||||
|
|
||||||
#ifdef _LZMA_IN_CB
|
|
||||||
|
|
||||||
typedef struct _CLzmaInCallbackImp
|
|
||||||
{
|
|
||||||
ILzmaInCallback InCallback;
|
|
||||||
ISzInStream *InStream;
|
|
||||||
size_t Size;
|
|
||||||
} CLzmaInCallbackImp;
|
|
||||||
|
|
||||||
int LzmaReadImp(void *object, const unsigned char **buffer, SizeT *size)
|
|
||||||
{
|
|
||||||
CLzmaInCallbackImp *cb = (CLzmaInCallbackImp *)object;
|
|
||||||
size_t processedSize;
|
|
||||||
SZ_RESULT res;
|
|
||||||
*size = 0;
|
|
||||||
res = cb->InStream->Read((void *)cb->InStream, (void **)buffer, cb->Size, &processedSize);
|
|
||||||
*size = (SizeT)processedSize;
|
|
||||||
if (processedSize > cb->Size)
|
|
||||||
return (int)SZE_FAIL;
|
|
||||||
cb->Size -= processedSize;
|
|
||||||
if (res == SZ_OK)
|
|
||||||
return 0;
|
|
||||||
return (int)res;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
SZ_RESULT SzDecode(const CFileSize *packSizes, const CFolder *folder,
|
|
||||||
#ifdef _LZMA_IN_CB
|
|
||||||
ISzInStream *inStream,
|
|
||||||
#else
|
|
||||||
const Byte *inBuffer,
|
|
||||||
#endif
|
|
||||||
Byte *outBuffer, size_t outSize,
|
|
||||||
size_t *outSizeProcessed, ISzAlloc *allocMain)
|
|
||||||
{
|
|
||||||
UInt32 si;
|
|
||||||
size_t inSize = 0;
|
|
||||||
CCoderInfo *coder;
|
|
||||||
if (folder->NumPackStreams != 1)
|
|
||||||
return SZE_NOTIMPL;
|
|
||||||
if (folder->NumCoders != 1)
|
|
||||||
return SZE_NOTIMPL;
|
|
||||||
coder = folder->Coders;
|
|
||||||
*outSizeProcessed = 0;
|
|
||||||
|
|
||||||
for (si = 0; si < folder->NumPackStreams; si++)
|
|
||||||
inSize += (size_t)packSizes[si];
|
|
||||||
|
|
||||||
if (AreMethodsEqual(&coder->MethodID, &k_Copy))
|
|
||||||
{
|
|
||||||
size_t i;
|
|
||||||
if (inSize != outSize)
|
|
||||||
return SZE_DATA_ERROR;
|
|
||||||
#ifdef _LZMA_IN_CB
|
|
||||||
for (i = 0; i < inSize;)
|
|
||||||
{
|
|
||||||
size_t j;
|
|
||||||
Byte *inBuffer;
|
|
||||||
size_t bufferSize;
|
|
||||||
RINOK(inStream->Read((void *)inStream, (void **)&inBuffer, inSize - i, &bufferSize));
|
|
||||||
if (bufferSize == 0)
|
|
||||||
return SZE_DATA_ERROR;
|
|
||||||
if (bufferSize > inSize - i)
|
|
||||||
return SZE_FAIL;
|
|
||||||
*outSizeProcessed += bufferSize;
|
|
||||||
for (j = 0; j < bufferSize && i < inSize; j++, i++)
|
|
||||||
outBuffer[i] = inBuffer[j];
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
for (i = 0; i < inSize; i++)
|
|
||||||
outBuffer[i] = inBuffer[i];
|
|
||||||
*outSizeProcessed = inSize;
|
|
||||||
#endif
|
|
||||||
return SZ_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (AreMethodsEqual(&coder->MethodID, &k_LZMA))
|
|
||||||
{
|
|
||||||
#ifdef _LZMA_IN_CB
|
|
||||||
CLzmaInCallbackImp lzmaCallback;
|
|
||||||
#else
|
|
||||||
SizeT inProcessed;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
CLzmaDecoderState state; /* it's about 24-80 bytes structure, if int is 32-bit */
|
|
||||||
int result;
|
|
||||||
SizeT outSizeProcessedLoc;
|
|
||||||
|
|
||||||
#ifdef _LZMA_IN_CB
|
|
||||||
lzmaCallback.Size = inSize;
|
|
||||||
lzmaCallback.InStream = inStream;
|
|
||||||
lzmaCallback.InCallback.Read = LzmaReadImp;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (LzmaDecodeProperties(&state.Properties, coder->Properties.Items,
|
|
||||||
coder->Properties.Capacity) != LZMA_RESULT_OK)
|
|
||||||
return SZE_FAIL;
|
|
||||||
|
|
||||||
state.Probs = (CProb *)allocMain->Alloc(LzmaGetNumProbs(&state.Properties) * sizeof(CProb));
|
|
||||||
if (state.Probs == 0)
|
|
||||||
return SZE_OUTOFMEMORY;
|
|
||||||
|
|
||||||
#ifdef _LZMA_OUT_READ
|
|
||||||
if (state.Properties.DictionarySize == 0)
|
|
||||||
state.Dictionary = 0;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
state.Dictionary = (unsigned char *)allocMain->Alloc(state.Properties.DictionarySize);
|
|
||||||
if (state.Dictionary == 0)
|
|
||||||
{
|
|
||||||
allocMain->Free(state.Probs);
|
|
||||||
return SZE_OUTOFMEMORYDIC;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
LzmaDecoderInit(&state);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
result = LzmaDecode(&state,
|
|
||||||
#ifdef _LZMA_IN_CB
|
|
||||||
&lzmaCallback.InCallback,
|
|
||||||
#else
|
|
||||||
inBuffer, (SizeT)inSize, &inProcessed,
|
|
||||||
#endif
|
|
||||||
outBuffer, (SizeT)outSize, &outSizeProcessedLoc);
|
|
||||||
*outSizeProcessed = (size_t)outSizeProcessedLoc;
|
|
||||||
allocMain->Free(state.Probs);
|
|
||||||
#ifdef _LZMA_OUT_READ
|
|
||||||
allocMain->Free(state.Dictionary);
|
|
||||||
#endif
|
|
||||||
if (result == LZMA_RESULT_DATA_ERROR)
|
|
||||||
return SZE_DATA_ERROR;
|
|
||||||
if (result != LZMA_RESULT_OK)
|
|
||||||
return SZE_FAIL;
|
|
||||||
return SZ_OK;
|
|
||||||
}
|
|
||||||
return SZE_NOTIMPL;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef _LZMA_OUT_READ
|
|
||||||
// like SzDecode but uses less memory
|
|
||||||
SZ_RESULT SzDecode2(const CFileSize *packSizes, const CFolder *folder,
|
|
||||||
ISzInStream *inStream,
|
|
||||||
Byte *outBuffer, size_t outSize,
|
|
||||||
size_t *outSizeProcessed, ISzAlloc *allocMain,
|
|
||||||
size_t *fileOffset, size_t *fileSize)
|
|
||||||
{
|
|
||||||
UInt32 si;
|
|
||||||
size_t inSize = 0;
|
|
||||||
CCoderInfo *coder;
|
|
||||||
if (folder->NumPackStreams != 1)
|
|
||||||
return SZE_NOTIMPL;
|
|
||||||
if (folder->NumCoders != 1)
|
|
||||||
return SZE_NOTIMPL;
|
|
||||||
coder = folder->Coders;
|
|
||||||
*outSizeProcessed = 0;
|
|
||||||
|
|
||||||
for (si = 0; si < folder->NumPackStreams; si++)
|
|
||||||
inSize += (size_t)packSizes[si];
|
|
||||||
|
|
||||||
if (AreMethodsEqual(&coder->MethodID, &k_Copy))
|
|
||||||
{
|
|
||||||
size_t i;
|
|
||||||
if (inSize != outSize)
|
|
||||||
return SZE_DATA_ERROR;
|
|
||||||
#ifdef _LZMA_IN_CB
|
|
||||||
for (i = 0; i < inSize;)
|
|
||||||
{
|
|
||||||
size_t j;
|
|
||||||
Byte *inBuffer;
|
|
||||||
size_t bufferSize;
|
|
||||||
RINOK(inStream->Read((void *)inStream, (void **)&inBuffer, inSize - i, &bufferSize));
|
|
||||||
if (bufferSize == 0)
|
|
||||||
return SZE_DATA_ERROR;
|
|
||||||
if (bufferSize > inSize - i)
|
|
||||||
return SZE_FAIL;
|
|
||||||
*outSizeProcessed += bufferSize;
|
|
||||||
for (j = 0; j < bufferSize && i < inSize; j++, i++)
|
|
||||||
outBuffer[i] = inBuffer[j];
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
for (i = 0; i < inSize; i++)
|
|
||||||
outBuffer[i] = inBuffer[i];
|
|
||||||
*outSizeProcessed = inSize;
|
|
||||||
#endif
|
|
||||||
return SZ_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (AreMethodsEqual(&coder->MethodID, &k_LZMA))
|
|
||||||
{
|
|
||||||
#ifdef _LZMA_IN_CB
|
|
||||||
CLzmaInCallbackImp lzmaCallback;
|
|
||||||
#else
|
|
||||||
SizeT inProcessed;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
CLzmaDecoderState state; /* it's about 24-80 bytes structure, if int is 32-bit */
|
|
||||||
int result;
|
|
||||||
SizeT outSizeProcessedLoc;
|
|
||||||
|
|
||||||
#ifdef _LZMA_IN_CB
|
|
||||||
lzmaCallback.Size = inSize;
|
|
||||||
lzmaCallback.InStream = inStream;
|
|
||||||
lzmaCallback.InCallback.Read = LzmaReadImp;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (LzmaDecodeProperties(&state.Properties, coder->Properties.Items,
|
|
||||||
coder->Properties.Capacity) != LZMA_RESULT_OK)
|
|
||||||
return SZE_FAIL;
|
|
||||||
|
|
||||||
state.Probs = (CProb *)allocMain->Alloc(LzmaGetNumProbs(&state.Properties) * sizeof(CProb));
|
|
||||||
if (state.Probs == 0)
|
|
||||||
return SZE_OUTOFMEMORY;
|
|
||||||
|
|
||||||
if (state.Properties.DictionarySize == 0)
|
|
||||||
state.Dictionary = 0;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
state.Dictionary = (unsigned char *)allocMain->Alloc(state.Properties.DictionarySize);
|
|
||||||
if (state.Dictionary == 0)
|
|
||||||
{
|
|
||||||
allocMain->Free(state.Probs);
|
|
||||||
return SZE_OUTOFMEMORY;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
LzmaDecoderInit(&state);
|
|
||||||
|
|
||||||
// allocate memory for the temporary buffer
|
|
||||||
Byte *tmpBuffer = (Byte *)allocMain->Alloc(_LZMA_TEMP_BUFFER_SIZE);
|
|
||||||
|
|
||||||
// variables containing the number of the first and the last bytes of the buffer
|
|
||||||
size_t bufferStart, bufferEnd;
|
|
||||||
bufferStart = bufferEnd = 0;
|
|
||||||
|
|
||||||
// integers contains the offset, the size and the already copied data which will be
|
|
||||||
// copied from the tmpBuffer to outBuffer
|
|
||||||
size_t copyOffset, copySize, copyDone;
|
|
||||||
copyOffset = copySize = copyDone = 0;
|
|
||||||
|
|
||||||
UInt32 i = 0;
|
|
||||||
int bytesToCopy = 0;
|
|
||||||
|
|
||||||
// decompress data in _LZMA_TEMP_BUFFER_SIZE byte steps and copy the wanted file to outBuffer
|
|
||||||
do
|
|
||||||
{
|
|
||||||
if((*fileSize - copyDone) >= _LZMA_TEMP_BUFFER_SIZE)
|
|
||||||
bytesToCopy = _LZMA_TEMP_BUFFER_SIZE;
|
|
||||||
else
|
|
||||||
bytesToCopy = (*fileSize - copyDone);
|
|
||||||
|
|
||||||
// decompress next bytes
|
|
||||||
result = LzmaDecode(&state,
|
|
||||||
#ifdef _LZMA_IN_CB
|
|
||||||
&lzmaCallback.InCallback,
|
|
||||||
#else
|
|
||||||
//inBuffer, (SizeT)inSize, &inProcessed, //TODO!
|
|
||||||
#endif
|
|
||||||
tmpBuffer, bytesToCopy, &outSizeProcessedLoc
|
|
||||||
);
|
|
||||||
|
|
||||||
// check result
|
|
||||||
if(result == LZMA_RESULT_DATA_ERROR)
|
|
||||||
{
|
|
||||||
return SZE_DATA_ERROR;
|
|
||||||
}
|
|
||||||
if(result != LZMA_RESULT_OK)
|
|
||||||
{
|
|
||||||
return SZE_FAIL;
|
|
||||||
}
|
|
||||||
|
|
||||||
// normally this should never happen
|
|
||||||
if(outSizeProcessedLoc > _LZMA_TEMP_BUFFER_SIZE)
|
|
||||||
{
|
|
||||||
return SZE_FAIL;
|
|
||||||
}
|
|
||||||
|
|
||||||
// update bufferStart and bufferEnd
|
|
||||||
bufferStart = _LZMA_TEMP_BUFFER_SIZE * i;
|
|
||||||
bufferEnd = bufferStart + outSizeProcessedLoc;
|
|
||||||
i++;
|
|
||||||
|
|
||||||
// calculate copy offset and size
|
|
||||||
if(*fileOffset > bufferEnd)
|
|
||||||
{
|
|
||||||
// we haven't reached the start of the file yet
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// calculate offset
|
|
||||||
if(*fileOffset < bufferStart)
|
|
||||||
{
|
|
||||||
// the file has already started before this decompression step
|
|
||||||
copyOffset = 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// the file starts somewhere inside this buffer
|
|
||||||
copyDone = 0;
|
|
||||||
copyOffset = _LZMA_TEMP_BUFFER_SIZE - (bufferEnd - *fileOffset);
|
|
||||||
}
|
|
||||||
|
|
||||||
// calculate size
|
|
||||||
if((*fileOffset + *fileSize) > bufferEnd)
|
|
||||||
{
|
|
||||||
// we'll need the whole buffer after copyOffset
|
|
||||||
copySize = _LZMA_TEMP_BUFFER_SIZE - copyOffset;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// we'll stop somewhere inside the buffer
|
|
||||||
copySize = (*fileOffset + *fileSize) - (bufferStart + copyOffset);
|
|
||||||
}
|
|
||||||
|
|
||||||
// copy bytes to the real output buffer
|
|
||||||
if(copySize == 0)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
// printf("memcpy(outBuffer + %d, tmpBuffer + %d, %d)\n", copyDone, copyOffset, copySize);
|
|
||||||
memcpy(outBuffer + copyDone, tmpBuffer + copyOffset, copySize);
|
|
||||||
copyDone += copySize;
|
|
||||||
}
|
|
||||||
while((*fileOffset + *fileSize) > bufferEnd);
|
|
||||||
|
|
||||||
/* result = LzmaDecode(&state,
|
|
||||||
#ifdef _LZMA_IN_CB
|
|
||||||
&lzmaCallback.InCallback,
|
|
||||||
#else
|
|
||||||
inBuffer, (SizeT)inSize, &inProcessed,
|
|
||||||
#endif
|
|
||||||
outBuffer, (SizeT)outSize, &outSizeProcessedLoc);*/
|
|
||||||
//*outSizeProcessed = (size_t)outSizeProcessedLoc;
|
|
||||||
*outSizeProcessed = copyDone;
|
|
||||||
allocMain->Free(tmpBuffer); // free the temporary buffer again
|
|
||||||
allocMain->Free(state.Probs);
|
|
||||||
allocMain->Free(state.Dictionary);
|
|
||||||
/* if (result == LZMA_RESULT_DATA_ERROR)
|
|
||||||
return SZE_DATA_ERROR;
|
|
||||||
if (result != LZMA_RESULT_OK)
|
|
||||||
return SZE_FAIL;*/
|
|
||||||
return SZ_OK;
|
|
||||||
}
|
|
||||||
return SZE_NOTIMPL;
|
|
||||||
}
|
|
||||||
#endif
|
|
@ -1,37 +0,0 @@
|
|||||||
/* 7zDecode.h */
|
|
||||||
|
|
||||||
#if defined(_LZMA_OUT_READ) && !defined(_LZMA_IN_CB)
|
|
||||||
#error "Fixme: _LZMA_OUT_READ && _LZMA_IN_CB isn't currently possible!"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef __7Z_DECODE_H
|
|
||||||
#define __7Z_DECODE_H
|
|
||||||
|
|
||||||
#include "7zItem.h"
|
|
||||||
#include "7zAlloc.h"
|
|
||||||
#ifdef _LZMA_IN_CB
|
|
||||||
#include "7zIn.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
SZ_RESULT SzDecode(const CFileSize *packSizes, const CFolder *folder,
|
|
||||||
#ifdef _LZMA_IN_CB
|
|
||||||
ISzInStream *stream,
|
|
||||||
#else
|
|
||||||
const Byte *inBuffer,
|
|
||||||
#endif
|
|
||||||
Byte *outBuffer, size_t outSize,
|
|
||||||
size_t *outSizeProcessed, ISzAlloc *allocMain);
|
|
||||||
|
|
||||||
#ifdef _LZMA_OUT_READ
|
|
||||||
#ifndef _LZMA_TEMP_BUFFER_SIZE
|
|
||||||
#define _LZMA_TEMP_BUFFER_SIZE (2048) // size of the temporary buffer in bytes
|
|
||||||
#endif
|
|
||||||
|
|
||||||
SZ_RESULT SzDecode2(const CFileSize *packSizes, const CFolder *folder,
|
|
||||||
ISzInStream *stream,
|
|
||||||
Byte *outBuffer, size_t outSize,
|
|
||||||
size_t *outSizeProcessed, ISzAlloc *allocMain,
|
|
||||||
size_t *fileOffset, size_t *fileSize);
|
|
||||||
#endif // #ifdef _LZMA_OUT_READ
|
|
||||||
|
|
||||||
#endif
|
|
@ -1,254 +0,0 @@
|
|||||||
/* 7zExtract.c */
|
|
||||||
|
|
||||||
#include "7zExtract.h"
|
|
||||||
#include "7zDecode.h"
|
|
||||||
#include "7zCrc.h"
|
|
||||||
|
|
||||||
SZ_RESULT SzExtract(
|
|
||||||
ISzInStream *inStream,
|
|
||||||
CArchiveDatabaseEx *db,
|
|
||||||
UInt32 fileIndex,
|
|
||||||
UInt32 *blockIndex,
|
|
||||||
Byte **outBuffer,
|
|
||||||
size_t *outBufferSize,
|
|
||||||
size_t *offset,
|
|
||||||
size_t *outSizeProcessed,
|
|
||||||
ISzAlloc *allocMain,
|
|
||||||
ISzAlloc *allocTemp)
|
|
||||||
{
|
|
||||||
UInt32 folderIndex = db->FileIndexToFolderIndexMap[fileIndex];
|
|
||||||
SZ_RESULT res = SZ_OK;
|
|
||||||
*offset = 0;
|
|
||||||
*outSizeProcessed = 0;
|
|
||||||
if (folderIndex == (UInt32)-1)
|
|
||||||
{
|
|
||||||
allocMain->Free(*outBuffer);
|
|
||||||
*blockIndex = folderIndex;
|
|
||||||
*outBuffer = 0;
|
|
||||||
*outBufferSize = 0;
|
|
||||||
return SZ_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (*outBuffer == 0 || *blockIndex != folderIndex)
|
|
||||||
{
|
|
||||||
CFolder *folder = db->Database.Folders + folderIndex;
|
|
||||||
CFileSize unPackSize = SzFolderGetUnPackSize(folder);
|
|
||||||
#ifndef _LZMA_IN_CB
|
|
||||||
CFileSize packSize = SzArDbGetFolderFullPackSize(db, folderIndex);
|
|
||||||
Byte *inBuffer = 0;
|
|
||||||
size_t processedSize;
|
|
||||||
#endif
|
|
||||||
*blockIndex = folderIndex;
|
|
||||||
allocMain->Free(*outBuffer);
|
|
||||||
*outBuffer = 0;
|
|
||||||
|
|
||||||
RINOK(inStream->Seek(inStream, SzArDbGetFolderStreamPos(db, folderIndex, 0)));
|
|
||||||
|
|
||||||
#ifndef _LZMA_IN_CB
|
|
||||||
if (packSize != 0)
|
|
||||||
{
|
|
||||||
inBuffer = (Byte *)allocTemp->Alloc((size_t)packSize);
|
|
||||||
if (inBuffer == 0)
|
|
||||||
return SZE_OUTOFMEMORY;
|
|
||||||
}
|
|
||||||
res = inStream->Read(inStream, inBuffer, (size_t)packSize, &processedSize);
|
|
||||||
if (res == SZ_OK && processedSize != (size_t)packSize)
|
|
||||||
res = SZE_FAIL;
|
|
||||||
#endif
|
|
||||||
if (res == SZ_OK)
|
|
||||||
{
|
|
||||||
*outBufferSize = (size_t)unPackSize;
|
|
||||||
if (unPackSize != 0)
|
|
||||||
{
|
|
||||||
*outBuffer = (Byte *)allocMain->Alloc((size_t)unPackSize);
|
|
||||||
if (*outBuffer == 0)
|
|
||||||
res = SZE_OUTOFMEMORY;
|
|
||||||
}
|
|
||||||
if (res == SZ_OK)
|
|
||||||
{
|
|
||||||
size_t outRealSize;
|
|
||||||
res = SzDecode(db->Database.PackSizes +
|
|
||||||
db->FolderStartPackStreamIndex[folderIndex], folder,
|
|
||||||
#ifdef _LZMA_IN_CB
|
|
||||||
inStream,
|
|
||||||
#else
|
|
||||||
inBuffer,
|
|
||||||
#endif
|
|
||||||
*outBuffer, (size_t)unPackSize, &outRealSize, allocTemp);
|
|
||||||
if (res == SZ_OK)
|
|
||||||
{
|
|
||||||
if (outRealSize == (size_t)unPackSize)
|
|
||||||
{
|
|
||||||
if (folder->UnPackCRCDefined)
|
|
||||||
{
|
|
||||||
if (!CrcVerifyDigest(folder->UnPackCRC, *outBuffer, (size_t)unPackSize))
|
|
||||||
res = SZE_FAIL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
res = SZE_FAIL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#ifndef _LZMA_IN_CB
|
|
||||||
allocTemp->Free(inBuffer);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
if (res == SZ_OK)
|
|
||||||
{
|
|
||||||
UInt32 i;
|
|
||||||
CFileItem *fileItem = db->Database.Files + fileIndex;
|
|
||||||
*offset = 0;
|
|
||||||
for(i = db->FolderStartFileIndex[folderIndex]; i < fileIndex; i++)
|
|
||||||
*offset += (UInt32)db->Database.Files[i].Size;
|
|
||||||
*outSizeProcessed = (size_t)fileItem->Size;
|
|
||||||
if (*offset + *outSizeProcessed > *outBufferSize)
|
|
||||||
return SZE_FAIL;
|
|
||||||
{
|
|
||||||
if (fileItem->IsFileCRCDefined)
|
|
||||||
{
|
|
||||||
if (!CrcVerifyDigest(fileItem->FileCRC, *outBuffer + *offset, *outSizeProcessed))
|
|
||||||
res = SZE_FAIL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef _LZMA_OUT_READ
|
|
||||||
// similar to SzExtract but needs less memory
|
|
||||||
SZ_RESULT SzExtract2(
|
|
||||||
ISzInStream *inStream,
|
|
||||||
CArchiveDatabaseEx *db,
|
|
||||||
UInt32 fileIndex,
|
|
||||||
UInt32 *blockIndex,
|
|
||||||
Byte **outBuffer,
|
|
||||||
size_t *outBufferSize,
|
|
||||||
size_t *offset,
|
|
||||||
size_t *outSizeProcessed,
|
|
||||||
ISzAlloc *allocMain,
|
|
||||||
ISzAlloc *allocTemp)
|
|
||||||
{
|
|
||||||
UInt32 folderIndex = db->FileIndexToFolderIndexMap[fileIndex];
|
|
||||||
SZ_RESULT res = SZ_OK;
|
|
||||||
*offset = 0;
|
|
||||||
*outSizeProcessed = 0;
|
|
||||||
if (folderIndex == (UInt32)-1)
|
|
||||||
{
|
|
||||||
*blockIndex = folderIndex;
|
|
||||||
#ifndef NGC
|
|
||||||
allocMain->Free(*outBuffer);
|
|
||||||
*outBuffer = 0;
|
|
||||||
#endif
|
|
||||||
*outBufferSize = 0;
|
|
||||||
return SZ_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
// if (*outBuffer == 0 || *blockIndex != folderIndex)
|
|
||||||
// {
|
|
||||||
CFolder *folder = db->Database.Folders + folderIndex;
|
|
||||||
CFileSize unPackSize = SzFolderGetUnPackSize(folder);
|
|
||||||
#ifndef _LZMA_IN_CB
|
|
||||||
CFileSize packSize = SzArDbGetFolderFullPackSize(db, folderIndex);
|
|
||||||
Byte *inBuffer = 0;
|
|
||||||
size_t processedSize;
|
|
||||||
#endif
|
|
||||||
*blockIndex = folderIndex;
|
|
||||||
#ifndef NGC
|
|
||||||
allocMain->Free(*outBuffer);
|
|
||||||
*outBuffer = 0;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
RINOK(inStream->Seek(inStream, SzArDbGetFolderStreamPos(db, folderIndex, 0)));
|
|
||||||
|
|
||||||
#ifndef _LZMA_IN_CB
|
|
||||||
if (packSize != 0)
|
|
||||||
{
|
|
||||||
inBuffer = (Byte *)allocTemp->Alloc((size_t)packSize);
|
|
||||||
if (inBuffer == 0)
|
|
||||||
return SZE_OUTOFMEMORY;
|
|
||||||
}
|
|
||||||
res = inStream->Read(inStream, inBuffer, (size_t)packSize, &processedSize);
|
|
||||||
if (res == SZ_OK && processedSize != (size_t)packSize)
|
|
||||||
res = SZE_FAIL;
|
|
||||||
#endif
|
|
||||||
if (res == SZ_OK)
|
|
||||||
{
|
|
||||||
// calculate file offset and filesize
|
|
||||||
CFileItem *fileItem = db->Database.Files + fileIndex;
|
|
||||||
UInt32 i;
|
|
||||||
*offset = 0;
|
|
||||||
for(i = db->FolderStartFileIndex[folderIndex]; i < fileIndex; i++)
|
|
||||||
*offset += (UInt32)db->Database.Files[i].Size;
|
|
||||||
*outSizeProcessed = (size_t)fileItem->Size;
|
|
||||||
*outBufferSize = (size_t)fileItem->Size;
|
|
||||||
if (unPackSize != 0)
|
|
||||||
{
|
|
||||||
#ifndef NGC
|
|
||||||
*outBuffer = (Byte *)allocMain->Alloc((size_t)fileItem->Size);
|
|
||||||
if (*outBuffer == 0)
|
|
||||||
res = SZE_OUTOFMEMORY;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
if (res == SZ_OK)
|
|
||||||
{
|
|
||||||
|
|
||||||
size_t outRealSize;
|
|
||||||
res = SzDecode2(db->Database.PackSizes +
|
|
||||||
db->FolderStartPackStreamIndex[folderIndex], folder,
|
|
||||||
#ifdef _LZMA_IN_CB
|
|
||||||
inStream,
|
|
||||||
#else
|
|
||||||
inBuffer,
|
|
||||||
#endif
|
|
||||||
*outBuffer, (size_t)unPackSize, &outRealSize, allocTemp,
|
|
||||||
offset, outSizeProcessed
|
|
||||||
);
|
|
||||||
*outSizeProcessed = outRealSize;
|
|
||||||
/* if (res == SZ_OK) // we can't validate the CRC of the whole data stream because we only extracted the wanted file
|
|
||||||
{
|
|
||||||
if (outRealSize == (size_t)unPackSize)
|
|
||||||
{
|
|
||||||
if (folder->UnPackCRCDefined)
|
|
||||||
{
|
|
||||||
if (!CrcVerifyDigest(folder->UnPackCRC, *outBuffer, (size_t)unPackSize))
|
|
||||||
res = SZE_FAIL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
res = SZE_FAIL;
|
|
||||||
}*/
|
|
||||||
}
|
|
||||||
// }
|
|
||||||
#ifndef _LZMA_IN_CB
|
|
||||||
allocTemp->Free(inBuffer);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
if (res == SZ_OK)
|
|
||||||
{
|
|
||||||
/* UInt32 i;
|
|
||||||
CFileItem *fileItem = db->Database.Files + fileIndex;
|
|
||||||
*offset = 0;
|
|
||||||
for(i = db->FolderStartFileIndex[folderIndex]; i < fileIndex; i++)
|
|
||||||
*offset += (UInt32)db->Database.Files[i].Size;
|
|
||||||
*outSizeProcessed = (size_t)fileItem->Size;*/
|
|
||||||
//CFileItem *fileItem = db->Database.Files + fileIndex;
|
|
||||||
if (/**offset +*/ *outSizeProcessed > *outBufferSize)
|
|
||||||
return SZE_FAIL;
|
|
||||||
{
|
|
||||||
//if (fileItem->IsFileCRCDefined)
|
|
||||||
//{
|
|
||||||
// if (!CrcVerifyDigest(fileItem->FileCRC, *outBuffer/* + *offset*/, *outSizeProcessed))
|
|
||||||
// res = SZE_CRC_ERROR; // why does SzExtract return SZE_FAIL when we can return SZE_CRC_ERROR?
|
|
||||||
//}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// change *offset to 0 because SzExtract normally decompresses the whole solid block
|
|
||||||
// and sets *offset to the offset of the wanted file.
|
|
||||||
// SzDecode2 does only copy the needed file to the output buffer and has to set *offset
|
|
||||||
// to 0 to ensure compatibility with SzExtract
|
|
||||||
*offset = 0;
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
#endif
|
|
@ -1,60 +0,0 @@
|
|||||||
/* 7zExtract.h */
|
|
||||||
|
|
||||||
#if defined(_LZMA_OUT_READ) && !defined(_LZMA_IN_CB)
|
|
||||||
#error "Fixme: _LZMA_OUT_READ && _LZMA_IN_CB isn't currently possible!"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef __7Z_EXTRACT_H
|
|
||||||
#define __7Z_EXTRACT_H
|
|
||||||
|
|
||||||
#include "7zIn.h"
|
|
||||||
|
|
||||||
/*
|
|
||||||
SzExtract extracts file from archive
|
|
||||||
|
|
||||||
SzExtract2 does the same but needs less memory
|
|
||||||
|
|
||||||
*outBuffer must be 0 before first call for each new archive.
|
|
||||||
|
|
||||||
Extracting cache:
|
|
||||||
If you need to decompress more than one file, you can send
|
|
||||||
these values from previous call:
|
|
||||||
*blockIndex,
|
|
||||||
*outBuffer,
|
|
||||||
*outBufferSize
|
|
||||||
You can consider "*outBuffer" as cache of solid block. If your archive is solid,
|
|
||||||
it will increase decompression speed.
|
|
||||||
|
|
||||||
If you use external function, you can declare these 3 cache variables
|
|
||||||
(blockIndex, outBuffer, outBufferSize) as static in that external function.
|
|
||||||
|
|
||||||
Free *outBuffer and set *outBuffer to 0, if you want to flush cache.
|
|
||||||
*/
|
|
||||||
|
|
||||||
SZ_RESULT SzExtract(
|
|
||||||
ISzInStream *inStream,
|
|
||||||
CArchiveDatabaseEx *db,
|
|
||||||
UInt32 fileIndex, /* index of file */
|
|
||||||
UInt32 *blockIndex, /* index of solid block */
|
|
||||||
Byte **outBuffer, /* pointer to pointer to output buffer (allocated with allocMain) */
|
|
||||||
size_t *outBufferSize, /* buffer size for output buffer */
|
|
||||||
size_t *offset, /* offset of stream for required file in *outBuffer */
|
|
||||||
size_t *outSizeProcessed, /* size of file in *outBuffer */
|
|
||||||
ISzAlloc *allocMain,
|
|
||||||
ISzAlloc *allocTemp);
|
|
||||||
|
|
||||||
#ifdef _LZMA_OUT_READ
|
|
||||||
SZ_RESULT SzExtract2(
|
|
||||||
ISzInStream *inStream,
|
|
||||||
CArchiveDatabaseEx *db,
|
|
||||||
UInt32 fileIndex, /* index of file */
|
|
||||||
UInt32 *blockIndex, /* index of solid block */
|
|
||||||
Byte **outBuffer, /* pointer to pointer to output buffer (allocated with allocMain) */
|
|
||||||
size_t *outBufferSize, /* buffer size for output buffer */
|
|
||||||
size_t *offset, /* offset of stream for required file in *outBuffer */
|
|
||||||
size_t *outSizeProcessed, /* size of file in *outBuffer */
|
|
||||||
ISzAlloc *allocMain,
|
|
||||||
ISzAlloc *allocTemp);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
|
@ -1,5 +0,0 @@
|
|||||||
/* 7zHeader.c */
|
|
||||||
|
|
||||||
#include "7zHeader.h"
|
|
||||||
|
|
||||||
Byte k7zSignature[k7zSignatureSize] = {'7', 'z', 0xBC, 0xAF, 0x27, 0x1C};
|
|
@ -1,55 +0,0 @@
|
|||||||
/* 7zHeader.h */
|
|
||||||
|
|
||||||
#ifndef __7Z_HEADER_H
|
|
||||||
#define __7Z_HEADER_H
|
|
||||||
|
|
||||||
#include "7zTypes.h"
|
|
||||||
|
|
||||||
#define k7zSignatureSize 6
|
|
||||||
extern Byte k7zSignature[k7zSignatureSize];
|
|
||||||
|
|
||||||
#define k7zMajorVersion 0
|
|
||||||
|
|
||||||
#define k7zStartHeaderSize 0x20
|
|
||||||
|
|
||||||
enum EIdEnum
|
|
||||||
{
|
|
||||||
k7zIdEnd,
|
|
||||||
|
|
||||||
k7zIdHeader,
|
|
||||||
|
|
||||||
k7zIdArchiveProperties,
|
|
||||||
|
|
||||||
k7zIdAdditionalStreamsInfo,
|
|
||||||
k7zIdMainStreamsInfo,
|
|
||||||
k7zIdFilesInfo,
|
|
||||||
|
|
||||||
k7zIdPackInfo,
|
|
||||||
k7zIdUnPackInfo,
|
|
||||||
k7zIdSubStreamsInfo,
|
|
||||||
|
|
||||||
k7zIdSize,
|
|
||||||
k7zIdCRC,
|
|
||||||
|
|
||||||
k7zIdFolder,
|
|
||||||
|
|
||||||
k7zIdCodersUnPackSize,
|
|
||||||
k7zIdNumUnPackStream,
|
|
||||||
|
|
||||||
k7zIdEmptyStream,
|
|
||||||
k7zIdEmptyFile,
|
|
||||||
k7zIdAnti,
|
|
||||||
|
|
||||||
k7zIdName,
|
|
||||||
k7zIdCreationTime,
|
|
||||||
k7zIdLastAccessTime,
|
|
||||||
k7zIdLastWriteTime,
|
|
||||||
k7zIdWinAttributes,
|
|
||||||
k7zIdComment,
|
|
||||||
|
|
||||||
k7zIdEncodedHeader,
|
|
||||||
|
|
||||||
k7zIdStartPos
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
1281
source/sz/7zIn.c
1281
source/sz/7zIn.c
File diff suppressed because it is too large
Load Diff
@ -1,55 +0,0 @@
|
|||||||
/* 7zIn.h */
|
|
||||||
|
|
||||||
#ifndef __7Z_IN_H
|
|
||||||
#define __7Z_IN_H
|
|
||||||
|
|
||||||
#include "7zHeader.h"
|
|
||||||
#include "7zItem.h"
|
|
||||||
#include "7zAlloc.h"
|
|
||||||
|
|
||||||
typedef struct _CInArchiveInfo
|
|
||||||
{
|
|
||||||
CFileSize StartPositionAfterHeader;
|
|
||||||
CFileSize DataStartPosition;
|
|
||||||
}CInArchiveInfo;
|
|
||||||
|
|
||||||
typedef struct _CArchiveDatabaseEx
|
|
||||||
{
|
|
||||||
CArchiveDatabase Database;
|
|
||||||
CInArchiveInfo ArchiveInfo;
|
|
||||||
UInt32 *FolderStartPackStreamIndex;
|
|
||||||
CFileSize *PackStreamStartPositions;
|
|
||||||
UInt32 *FolderStartFileIndex;
|
|
||||||
UInt32 *FileIndexToFolderIndexMap;
|
|
||||||
}CArchiveDatabaseEx;
|
|
||||||
|
|
||||||
void SzArDbExInit(CArchiveDatabaseEx *db);
|
|
||||||
void SzArDbExFree(CArchiveDatabaseEx *db, void (*freeFunc)(void *));
|
|
||||||
CFileSize SzArDbGetFolderStreamPos(CArchiveDatabaseEx *db, UInt32 folderIndex, UInt32 indexInFolder);
|
|
||||||
CFileSize SzArDbGetFolderFullPackSize(CArchiveDatabaseEx *db, UInt32 folderIndex);
|
|
||||||
|
|
||||||
typedef struct _ISzInStream
|
|
||||||
{
|
|
||||||
#ifdef _LZMA_IN_CB
|
|
||||||
SZ_RESULT (*Read)(
|
|
||||||
void *object, /* pointer to ISzInStream itself */
|
|
||||||
void **buffer, /* out: pointer to buffer with data */
|
|
||||||
size_t maxRequiredSize, /* max required size to read */
|
|
||||||
size_t *processedSize); /* real processed size.
|
|
||||||
processedSize can be less than maxRequiredSize.
|
|
||||||
If processedSize == 0, then there are no more
|
|
||||||
bytes in stream. */
|
|
||||||
#else
|
|
||||||
SZ_RESULT (*Read)(void *object, void *buffer, size_t size, size_t *processedSize);
|
|
||||||
#endif
|
|
||||||
SZ_RESULT (*Seek)(void *object, CFileSize pos);
|
|
||||||
} ISzInStream;
|
|
||||||
|
|
||||||
|
|
||||||
int SzArchiveOpen(
|
|
||||||
ISzInStream *inStream,
|
|
||||||
CArchiveDatabaseEx *db,
|
|
||||||
ISzAlloc *allocMain,
|
|
||||||
ISzAlloc *allocTemp);
|
|
||||||
|
|
||||||
#endif
|
|
@ -1,133 +0,0 @@
|
|||||||
/* 7zItem.c */
|
|
||||||
|
|
||||||
#include "7zItem.h"
|
|
||||||
#include "7zAlloc.h"
|
|
||||||
|
|
||||||
void SzCoderInfoInit(CCoderInfo *coder)
|
|
||||||
{
|
|
||||||
SzByteBufferInit(&coder->Properties);
|
|
||||||
}
|
|
||||||
|
|
||||||
void SzCoderInfoFree(CCoderInfo *coder, void (*freeFunc)(void *p))
|
|
||||||
{
|
|
||||||
SzByteBufferFree(&coder->Properties, freeFunc);
|
|
||||||
SzCoderInfoInit(coder);
|
|
||||||
}
|
|
||||||
|
|
||||||
void SzFolderInit(CFolder *folder)
|
|
||||||
{
|
|
||||||
folder->NumCoders = 0;
|
|
||||||
folder->Coders = 0;
|
|
||||||
folder->NumBindPairs = 0;
|
|
||||||
folder->BindPairs = 0;
|
|
||||||
folder->NumPackStreams = 0;
|
|
||||||
folder->PackStreams = 0;
|
|
||||||
folder->UnPackSizes = 0;
|
|
||||||
folder->UnPackCRCDefined = 0;
|
|
||||||
folder->UnPackCRC = 0;
|
|
||||||
folder->NumUnPackStreams = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SzFolderFree(CFolder *folder, void (*freeFunc)(void *p))
|
|
||||||
{
|
|
||||||
UInt32 i;
|
|
||||||
for (i = 0; i < folder->NumCoders; i++)
|
|
||||||
SzCoderInfoFree(&folder->Coders[i], freeFunc);
|
|
||||||
freeFunc(folder->Coders);
|
|
||||||
freeFunc(folder->BindPairs);
|
|
||||||
freeFunc(folder->PackStreams);
|
|
||||||
freeFunc(folder->UnPackSizes);
|
|
||||||
SzFolderInit(folder);
|
|
||||||
}
|
|
||||||
|
|
||||||
UInt32 SzFolderGetNumOutStreams(CFolder *folder)
|
|
||||||
{
|
|
||||||
UInt32 result = 0;
|
|
||||||
UInt32 i;
|
|
||||||
for (i = 0; i < folder->NumCoders; i++)
|
|
||||||
result += folder->Coders[i].NumOutStreams;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
int SzFolderFindBindPairForInStream(CFolder *folder, UInt32 inStreamIndex)
|
|
||||||
{
|
|
||||||
UInt32 i;
|
|
||||||
for(i = 0; i < folder->NumBindPairs; i++)
|
|
||||||
if (folder->BindPairs[i].InIndex == inStreamIndex)
|
|
||||||
return i;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int SzFolderFindBindPairForOutStream(CFolder *folder, UInt32 outStreamIndex)
|
|
||||||
{
|
|
||||||
UInt32 i;
|
|
||||||
for(i = 0; i < folder->NumBindPairs; i++)
|
|
||||||
if (folder->BindPairs[i].OutIndex == outStreamIndex)
|
|
||||||
return i;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
CFileSize SzFolderGetUnPackSize(CFolder *folder)
|
|
||||||
{
|
|
||||||
int i = (int)SzFolderGetNumOutStreams(folder);
|
|
||||||
if (i == 0)
|
|
||||||
return 0;
|
|
||||||
for (i--; i >= 0; i--)
|
|
||||||
if (SzFolderFindBindPairForOutStream(folder, i) < 0)
|
|
||||||
return folder->UnPackSizes[i];
|
|
||||||
/* throw 1; */
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
int FindPackStreamArrayIndex(int inStreamIndex) const
|
|
||||||
{
|
|
||||||
for(int i = 0; i < PackStreams.Size(); i++)
|
|
||||||
if (PackStreams[i] == inStreamIndex)
|
|
||||||
return i;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
void SzFileInit(CFileItem *fileItem)
|
|
||||||
{
|
|
||||||
fileItem->IsFileCRCDefined = 0;
|
|
||||||
fileItem->HasStream = 1;
|
|
||||||
fileItem->IsDirectory = 0;
|
|
||||||
fileItem->IsAnti = 0;
|
|
||||||
fileItem->Name = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SzFileFree(CFileItem *fileItem, void (*freeFunc)(void *p))
|
|
||||||
{
|
|
||||||
freeFunc(fileItem->Name);
|
|
||||||
SzFileInit(fileItem);
|
|
||||||
}
|
|
||||||
|
|
||||||
void SzArchiveDatabaseInit(CArchiveDatabase *db)
|
|
||||||
{
|
|
||||||
db->NumPackStreams = 0;
|
|
||||||
db->PackSizes = 0;
|
|
||||||
db->PackCRCsDefined = 0;
|
|
||||||
db->PackCRCs = 0;
|
|
||||||
db->NumFolders = 0;
|
|
||||||
db->Folders = 0;
|
|
||||||
db->NumFiles = 0;
|
|
||||||
db->Files = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SzArchiveDatabaseFree(CArchiveDatabase *db, void (*freeFunc)(void *))
|
|
||||||
{
|
|
||||||
UInt32 i;
|
|
||||||
for (i = 0; i < db->NumFolders; i++)
|
|
||||||
SzFolderFree(&db->Folders[i], freeFunc);
|
|
||||||
for (i = 0; i < db->NumFiles; i++)
|
|
||||||
SzFileFree(&db->Files[i], freeFunc);
|
|
||||||
freeFunc(db->PackSizes);
|
|
||||||
freeFunc(db->PackCRCsDefined);
|
|
||||||
freeFunc(db->PackCRCs);
|
|
||||||
freeFunc(db->Folders);
|
|
||||||
freeFunc(db->Files);
|
|
||||||
SzArchiveDatabaseInit(db);
|
|
||||||
}
|
|
@ -1,90 +0,0 @@
|
|||||||
/* 7zItem.h */
|
|
||||||
|
|
||||||
#ifndef __7Z_ITEM_H
|
|
||||||
#define __7Z_ITEM_H
|
|
||||||
|
|
||||||
#include "7zMethodID.h"
|
|
||||||
#include "7zHeader.h"
|
|
||||||
#include "7zBuffer.h"
|
|
||||||
|
|
||||||
typedef struct _CCoderInfo
|
|
||||||
{
|
|
||||||
UInt32 NumInStreams;
|
|
||||||
UInt32 NumOutStreams;
|
|
||||||
CMethodID MethodID;
|
|
||||||
CSzByteBuffer Properties;
|
|
||||||
}CCoderInfo;
|
|
||||||
|
|
||||||
void SzCoderInfoInit(CCoderInfo *coder);
|
|
||||||
void SzCoderInfoFree(CCoderInfo *coder, void (*freeFunc)(void *p));
|
|
||||||
|
|
||||||
typedef struct _CBindPair
|
|
||||||
{
|
|
||||||
UInt32 InIndex;
|
|
||||||
UInt32 OutIndex;
|
|
||||||
}CBindPair;
|
|
||||||
|
|
||||||
typedef struct _CFolder
|
|
||||||
{
|
|
||||||
UInt32 NumCoders;
|
|
||||||
CCoderInfo *Coders;
|
|
||||||
UInt32 NumBindPairs;
|
|
||||||
CBindPair *BindPairs;
|
|
||||||
UInt32 NumPackStreams;
|
|
||||||
UInt32 *PackStreams;
|
|
||||||
CFileSize *UnPackSizes;
|
|
||||||
int UnPackCRCDefined;
|
|
||||||
UInt32 UnPackCRC;
|
|
||||||
|
|
||||||
UInt32 NumUnPackStreams;
|
|
||||||
}CFolder;
|
|
||||||
|
|
||||||
void SzFolderInit(CFolder *folder);
|
|
||||||
CFileSize SzFolderGetUnPackSize(CFolder *folder);
|
|
||||||
int SzFolderFindBindPairForInStream(CFolder *folder, UInt32 inStreamIndex);
|
|
||||||
UInt32 SzFolderGetNumOutStreams(CFolder *folder);
|
|
||||||
CFileSize SzFolderGetUnPackSize(CFolder *folder);
|
|
||||||
|
|
||||||
/* #define CArchiveFileTime UInt64 */
|
|
||||||
|
|
||||||
typedef struct _CFileItem
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
CArchiveFileTime LastWriteTime;
|
|
||||||
CFileSize StartPos;
|
|
||||||
UInt32 Attributes;
|
|
||||||
*/
|
|
||||||
CFileSize Size;
|
|
||||||
UInt32 FileCRC;
|
|
||||||
char *Name;
|
|
||||||
|
|
||||||
Byte IsFileCRCDefined;
|
|
||||||
Byte HasStream;
|
|
||||||
Byte IsDirectory;
|
|
||||||
Byte IsAnti;
|
|
||||||
/*
|
|
||||||
int AreAttributesDefined;
|
|
||||||
int IsLastWriteTimeDefined;
|
|
||||||
int IsStartPosDefined;
|
|
||||||
*/
|
|
||||||
}CFileItem;
|
|
||||||
|
|
||||||
void SzFileInit(CFileItem *fileItem);
|
|
||||||
|
|
||||||
typedef struct _CArchiveDatabase
|
|
||||||
{
|
|
||||||
UInt32 NumPackStreams;
|
|
||||||
CFileSize *PackSizes;
|
|
||||||
Byte *PackCRCsDefined;
|
|
||||||
UInt32 *PackCRCs;
|
|
||||||
UInt32 NumFolders;
|
|
||||||
CFolder *Folders;
|
|
||||||
UInt32 NumFiles;
|
|
||||||
CFileItem *Files;
|
|
||||||
}CArchiveDatabase;
|
|
||||||
|
|
||||||
void SzArchiveDatabaseInit(CArchiveDatabase *db);
|
|
||||||
void SzArchiveDatabaseFree(CArchiveDatabase *db, void (*freeFunc)(void *));
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
@ -1,14 +0,0 @@
|
|||||||
/* 7zMethodID.c */
|
|
||||||
|
|
||||||
#include "7zMethodID.h"
|
|
||||||
|
|
||||||
int AreMethodsEqual(CMethodID *a1, CMethodID *a2)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
if (a1->IDSize != a2->IDSize)
|
|
||||||
return 0;
|
|
||||||
for (i = 0; i < a1->IDSize; i++)
|
|
||||||
if (a1->ID[i] != a2->ID[i])
|
|
||||||
return 0;
|
|
||||||
return 1;
|
|
||||||
}
|
|
@ -1,18 +0,0 @@
|
|||||||
/* 7zMethodID.h */
|
|
||||||
|
|
||||||
#ifndef __7Z_METHOD_ID_H
|
|
||||||
#define __7Z_METHOD_ID_H
|
|
||||||
|
|
||||||
#include "7zTypes.h"
|
|
||||||
|
|
||||||
#define kMethodIDSize 15
|
|
||||||
|
|
||||||
typedef struct _CMethodID
|
|
||||||
{
|
|
||||||
Byte ID[kMethodIDSize];
|
|
||||||
Byte IDSize;
|
|
||||||
} CMethodID;
|
|
||||||
|
|
||||||
int AreMethodsEqual(CMethodID *a1, CMethodID *a2);
|
|
||||||
|
|
||||||
#endif
|
|
@ -1,71 +0,0 @@
|
|||||||
/* 7zTypes.h */
|
|
||||||
|
|
||||||
#ifndef __COMMON_TYPES_H
|
|
||||||
#define __COMMON_TYPES_H
|
|
||||||
|
|
||||||
#ifndef _7ZIP_BYTE_DEFINED
|
|
||||||
#define _7ZIP_BYTE_DEFINED
|
|
||||||
#ifndef ZCONF_H
|
|
||||||
typedef unsigned char Byte;
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef _7ZIP_UINT16_DEFINED
|
|
||||||
#define _7ZIP_UINT16_DEFINED
|
|
||||||
typedef unsigned short UInt16;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef _7ZIP_UINT32_DEFINED
|
|
||||||
#define _7ZIP_UINT32_DEFINED
|
|
||||||
#ifdef _LZMA_UINT32_IS_ULONG
|
|
||||||
typedef unsigned long UInt32;
|
|
||||||
#else
|
|
||||||
typedef unsigned int UInt32;
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* #define _SZ_NO_INT_64 */
|
|
||||||
/* define it your compiler doesn't support long long int */
|
|
||||||
|
|
||||||
#ifndef _7ZIP_UINT64_DEFINED
|
|
||||||
#define _7ZIP_UINT64_DEFINED
|
|
||||||
#ifdef _SZ_NO_INT_64
|
|
||||||
typedef unsigned long UInt64;
|
|
||||||
#else
|
|
||||||
#ifdef _MSC_VER
|
|
||||||
typedef unsigned __int64 UInt64;
|
|
||||||
#else
|
|
||||||
typedef unsigned long long int UInt64;
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/* #define _SZ_FILE_SIZE_64 */
|
|
||||||
/* Use _SZ_FILE_SIZE_64 if you need support for files larger than 4 GB*/
|
|
||||||
|
|
||||||
#ifndef CFileSize
|
|
||||||
#ifdef _SZ_FILE_SIZE_64
|
|
||||||
typedef UInt64 CFileSize;
|
|
||||||
#else
|
|
||||||
typedef UInt32 CFileSize;
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define SZ_RESULT int
|
|
||||||
|
|
||||||
#define SZ_OK (0)
|
|
||||||
#define SZE_DATA_ERROR (1)
|
|
||||||
#define SZE_OUTOFMEMORY (2)
|
|
||||||
#define SZE_CRC_ERROR (3)
|
|
||||||
|
|
||||||
#define SZE_NOTIMPL (4)
|
|
||||||
#define SZE_FAIL (5)
|
|
||||||
|
|
||||||
#define SZE_ARCHIVE_ERROR (6)
|
|
||||||
|
|
||||||
#define SZE_OUTOFMEMORYDIC (7)
|
|
||||||
|
|
||||||
#define RINOK(x) { int __result_ = (x); if(__result_ != 0) return __result_; }
|
|
||||||
|
|
||||||
#endif
|
|
@ -1,584 +0,0 @@
|
|||||||
/*
|
|
||||||
LzmaDecode.c
|
|
||||||
LZMA Decoder (optimized for Speed version)
|
|
||||||
|
|
||||||
LZMA SDK 4.40 Copyright (c) 1999-2006 Igor Pavlov (2006-05-01)
|
|
||||||
http://www.7-zip.org/
|
|
||||||
|
|
||||||
LZMA SDK is licensed under two licenses:
|
|
||||||
1) GNU Lesser General Public License (GNU LGPL)
|
|
||||||
2) Common Public License (CPL)
|
|
||||||
It means that you can select one of these two licenses and
|
|
||||||
follow rules of that license.
|
|
||||||
|
|
||||||
SPECIAL EXCEPTION:
|
|
||||||
Igor Pavlov, as the author of this Code, expressly permits you to
|
|
||||||
statically or dynamically link your Code (or bind by name) to the
|
|
||||||
interfaces of this file without subjecting your linked Code to the
|
|
||||||
terms of the CPL or GNU LGPL. Any modifications or additions
|
|
||||||
to this file, however, are subject to the LGPL or CPL terms.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "LzmaDecode.h"
|
|
||||||
|
|
||||||
#define kNumTopBits 24
|
|
||||||
#define kTopValue ((UInt32)1 << kNumTopBits)
|
|
||||||
|
|
||||||
#define kNumBitModelTotalBits 11
|
|
||||||
#define kBitModelTotal (1 << kNumBitModelTotalBits)
|
|
||||||
#define kNumMoveBits 5
|
|
||||||
|
|
||||||
#define RC_READ_BYTE (*Buffer++)
|
|
||||||
|
|
||||||
#define RC_INIT2 Code = 0; Range = 0xFFFFFFFF; \
|
|
||||||
{ int i; for(i = 0; i < 5; i++) { RC_TEST; Code = (Code << 8) | RC_READ_BYTE; }}
|
|
||||||
|
|
||||||
#ifdef _LZMA_IN_CB
|
|
||||||
|
|
||||||
#define RC_TEST { if (Buffer == BufferLim) \
|
|
||||||
{ SizeT size; int result = InCallback->Read(InCallback, &Buffer, &size); if (result != LZMA_RESULT_OK) return result; \
|
|
||||||
BufferLim = Buffer + size; if (size == 0) return LZMA_RESULT_DATA_ERROR; }}
|
|
||||||
|
|
||||||
#define RC_INIT Buffer = BufferLim = 0; RC_INIT2
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
#define RC_TEST { if (Buffer == BufferLim) return LZMA_RESULT_DATA_ERROR; }
|
|
||||||
|
|
||||||
#define RC_INIT(buffer, bufferSize) Buffer = buffer; BufferLim = buffer + bufferSize; RC_INIT2
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define RC_NORMALIZE if (Range < kTopValue) { RC_TEST; Range <<= 8; Code = (Code << 8) | RC_READ_BYTE; }
|
|
||||||
|
|
||||||
#define IfBit0(p) RC_NORMALIZE; bound = (Range >> kNumBitModelTotalBits) * *(p); if (Code < bound)
|
|
||||||
#define UpdateBit0(p) Range = bound; *(p) += (kBitModelTotal - *(p)) >> kNumMoveBits;
|
|
||||||
#define UpdateBit1(p) Range -= bound; Code -= bound; *(p) -= (*(p)) >> kNumMoveBits;
|
|
||||||
|
|
||||||
#define RC_GET_BIT2(p, mi, A0, A1) IfBit0(p) \
|
|
||||||
{ UpdateBit0(p); mi <<= 1; A0; } else \
|
|
||||||
{ UpdateBit1(p); mi = (mi + mi) + 1; A1; }
|
|
||||||
|
|
||||||
#define RC_GET_BIT(p, mi) RC_GET_BIT2(p, mi, ; , ;)
|
|
||||||
|
|
||||||
#define RangeDecoderBitTreeDecode(probs, numLevels, res) \
|
|
||||||
{ int i = numLevels; res = 1; \
|
|
||||||
do { CProb *p = probs + res; RC_GET_BIT(p, res) } while(--i != 0); \
|
|
||||||
res -= (1 << numLevels); }
|
|
||||||
|
|
||||||
|
|
||||||
#define kNumPosBitsMax 4
|
|
||||||
#define kNumPosStatesMax (1 << kNumPosBitsMax)
|
|
||||||
|
|
||||||
#define kLenNumLowBits 3
|
|
||||||
#define kLenNumLowSymbols (1 << kLenNumLowBits)
|
|
||||||
#define kLenNumMidBits 3
|
|
||||||
#define kLenNumMidSymbols (1 << kLenNumMidBits)
|
|
||||||
#define kLenNumHighBits 8
|
|
||||||
#define kLenNumHighSymbols (1 << kLenNumHighBits)
|
|
||||||
|
|
||||||
#define LenChoice 0
|
|
||||||
#define LenChoice2 (LenChoice + 1)
|
|
||||||
#define LenLow (LenChoice2 + 1)
|
|
||||||
#define LenMid (LenLow + (kNumPosStatesMax << kLenNumLowBits))
|
|
||||||
#define LenHigh (LenMid + (kNumPosStatesMax << kLenNumMidBits))
|
|
||||||
#define kNumLenProbs (LenHigh + kLenNumHighSymbols)
|
|
||||||
|
|
||||||
|
|
||||||
#define kNumStates 12
|
|
||||||
#define kNumLitStates 7
|
|
||||||
|
|
||||||
#define kStartPosModelIndex 4
|
|
||||||
#define kEndPosModelIndex 14
|
|
||||||
#define kNumFullDistances (1 << (kEndPosModelIndex >> 1))
|
|
||||||
|
|
||||||
#define kNumPosSlotBits 6
|
|
||||||
#define kNumLenToPosStates 4
|
|
||||||
|
|
||||||
#define kNumAlignBits 4
|
|
||||||
#define kAlignTableSize (1 << kNumAlignBits)
|
|
||||||
|
|
||||||
#define kMatchMinLen 2
|
|
||||||
|
|
||||||
#define IsMatch 0
|
|
||||||
#define IsRep (IsMatch + (kNumStates << kNumPosBitsMax))
|
|
||||||
#define IsRepG0 (IsRep + kNumStates)
|
|
||||||
#define IsRepG1 (IsRepG0 + kNumStates)
|
|
||||||
#define IsRepG2 (IsRepG1 + kNumStates)
|
|
||||||
#define IsRep0Long (IsRepG2 + kNumStates)
|
|
||||||
#define PosSlot (IsRep0Long + (kNumStates << kNumPosBitsMax))
|
|
||||||
#define SpecPos (PosSlot + (kNumLenToPosStates << kNumPosSlotBits))
|
|
||||||
#define Align (SpecPos + kNumFullDistances - kEndPosModelIndex)
|
|
||||||
#define LenCoder (Align + kAlignTableSize)
|
|
||||||
#define RepLenCoder (LenCoder + kNumLenProbs)
|
|
||||||
#define Literal (RepLenCoder + kNumLenProbs)
|
|
||||||
|
|
||||||
#if Literal != LZMA_BASE_SIZE
|
|
||||||
StopCompilingDueBUG
|
|
||||||
#endif
|
|
||||||
|
|
||||||
int LzmaDecodeProperties(CLzmaProperties *propsRes, const unsigned char *propsData, int size)
|
|
||||||
{
|
|
||||||
unsigned char prop0;
|
|
||||||
if (size < LZMA_PROPERTIES_SIZE)
|
|
||||||
return LZMA_RESULT_DATA_ERROR;
|
|
||||||
prop0 = propsData[0];
|
|
||||||
if (prop0 >= (9 * 5 * 5))
|
|
||||||
return LZMA_RESULT_DATA_ERROR;
|
|
||||||
{
|
|
||||||
for (propsRes->pb = 0; prop0 >= (9 * 5); propsRes->pb++, prop0 -= (9 * 5));
|
|
||||||
for (propsRes->lp = 0; prop0 >= 9; propsRes->lp++, prop0 -= 9);
|
|
||||||
propsRes->lc = prop0;
|
|
||||||
/*
|
|
||||||
unsigned char remainder = (unsigned char)(prop0 / 9);
|
|
||||||
propsRes->lc = prop0 % 9;
|
|
||||||
propsRes->pb = remainder / 5;
|
|
||||||
propsRes->lp = remainder % 5;
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef _LZMA_OUT_READ
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
propsRes->DictionarySize = 0;
|
|
||||||
for (i = 0; i < 4; i++)
|
|
||||||
propsRes->DictionarySize += (UInt32)(propsData[1 + i]) << (i * 8);
|
|
||||||
if (propsRes->DictionarySize == 0)
|
|
||||||
propsRes->DictionarySize = 1;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
return LZMA_RESULT_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
#define kLzmaStreamWasFinishedId (-1)
|
|
||||||
|
|
||||||
int LzmaDecode(CLzmaDecoderState *vs,
|
|
||||||
#ifdef _LZMA_IN_CB
|
|
||||||
ILzmaInCallback *InCallback,
|
|
||||||
#else
|
|
||||||
const unsigned char *inStream, SizeT inSize, SizeT *inSizeProcessed,
|
|
||||||
#endif
|
|
||||||
unsigned char *outStream, SizeT outSize, SizeT *outSizeProcessed)
|
|
||||||
{
|
|
||||||
CProb *p = vs->Probs;
|
|
||||||
SizeT nowPos = 0;
|
|
||||||
Byte previousByte = 0;
|
|
||||||
UInt32 posStateMask = (1 << (vs->Properties.pb)) - 1;
|
|
||||||
UInt32 literalPosMask = (1 << (vs->Properties.lp)) - 1;
|
|
||||||
int lc = vs->Properties.lc;
|
|
||||||
|
|
||||||
#ifdef _LZMA_OUT_READ
|
|
||||||
|
|
||||||
UInt32 Range = vs->Range;
|
|
||||||
UInt32 Code = vs->Code;
|
|
||||||
#ifdef _LZMA_IN_CB
|
|
||||||
const Byte *Buffer = vs->Buffer;
|
|
||||||
const Byte *BufferLim = vs->BufferLim;
|
|
||||||
#else
|
|
||||||
const Byte *Buffer = inStream;
|
|
||||||
const Byte *BufferLim = inStream + inSize;
|
|
||||||
#endif
|
|
||||||
int state = vs->State;
|
|
||||||
UInt32 rep0 = vs->Reps[0], rep1 = vs->Reps[1], rep2 = vs->Reps[2], rep3 = vs->Reps[3];
|
|
||||||
int len = vs->RemainLen;
|
|
||||||
UInt32 globalPos = vs->GlobalPos;
|
|
||||||
UInt32 distanceLimit = vs->DistanceLimit;
|
|
||||||
|
|
||||||
Byte *dictionary = vs->Dictionary;
|
|
||||||
UInt32 dictionarySize = vs->Properties.DictionarySize;
|
|
||||||
UInt32 dictionaryPos = vs->DictionaryPos;
|
|
||||||
|
|
||||||
Byte tempDictionary[4];
|
|
||||||
|
|
||||||
#ifndef _LZMA_IN_CB
|
|
||||||
*inSizeProcessed = 0;
|
|
||||||
#endif
|
|
||||||
*outSizeProcessed = 0;
|
|
||||||
if (len == kLzmaStreamWasFinishedId)
|
|
||||||
return LZMA_RESULT_OK;
|
|
||||||
|
|
||||||
if (dictionarySize == 0)
|
|
||||||
{
|
|
||||||
dictionary = tempDictionary;
|
|
||||||
dictionarySize = 1;
|
|
||||||
tempDictionary[0] = vs->TempDictionary[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
if (len == kLzmaNeedInitId)
|
|
||||||
{
|
|
||||||
{
|
|
||||||
UInt32 numProbs = Literal + ((UInt32)LZMA_LIT_SIZE << (lc + vs->Properties.lp));
|
|
||||||
UInt32 i;
|
|
||||||
for (i = 0; i < numProbs; i++)
|
|
||||||
p[i] = kBitModelTotal >> 1;
|
|
||||||
rep0 = rep1 = rep2 = rep3 = 1;
|
|
||||||
state = 0;
|
|
||||||
globalPos = 0;
|
|
||||||
distanceLimit = 0;
|
|
||||||
dictionaryPos = 0;
|
|
||||||
dictionary[dictionarySize - 1] = 0;
|
|
||||||
#ifdef _LZMA_IN_CB
|
|
||||||
RC_INIT;
|
|
||||||
#else
|
|
||||||
RC_INIT(inStream, inSize);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
len = 0;
|
|
||||||
}
|
|
||||||
while(len != 0 && nowPos < outSize)
|
|
||||||
{
|
|
||||||
UInt32 pos = dictionaryPos - rep0;
|
|
||||||
if (pos >= dictionarySize)
|
|
||||||
pos += dictionarySize;
|
|
||||||
outStream[nowPos++] = dictionary[dictionaryPos] = dictionary[pos];
|
|
||||||
if (++dictionaryPos == dictionarySize)
|
|
||||||
dictionaryPos = 0;
|
|
||||||
len--;
|
|
||||||
}
|
|
||||||
if (dictionaryPos == 0)
|
|
||||||
previousByte = dictionary[dictionarySize - 1];
|
|
||||||
else
|
|
||||||
previousByte = dictionary[dictionaryPos - 1];
|
|
||||||
|
|
||||||
#else /* if !_LZMA_OUT_READ */
|
|
||||||
|
|
||||||
int state = 0;
|
|
||||||
UInt32 rep0 = 1, rep1 = 1, rep2 = 1, rep3 = 1;
|
|
||||||
int len = 0;
|
|
||||||
const Byte *Buffer;
|
|
||||||
const Byte *BufferLim;
|
|
||||||
UInt32 Range;
|
|
||||||
UInt32 Code;
|
|
||||||
|
|
||||||
#ifndef _LZMA_IN_CB
|
|
||||||
*inSizeProcessed = 0;
|
|
||||||
#endif
|
|
||||||
*outSizeProcessed = 0;
|
|
||||||
|
|
||||||
{
|
|
||||||
UInt32 i;
|
|
||||||
UInt32 numProbs = Literal + ((UInt32)LZMA_LIT_SIZE << (lc + vs->Properties.lp));
|
|
||||||
for (i = 0; i < numProbs; i++)
|
|
||||||
p[i] = kBitModelTotal >> 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef _LZMA_IN_CB
|
|
||||||
RC_INIT;
|
|
||||||
#else
|
|
||||||
RC_INIT(inStream, inSize);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* _LZMA_OUT_READ */
|
|
||||||
|
|
||||||
while(nowPos < outSize)
|
|
||||||
{
|
|
||||||
CProb *prob;
|
|
||||||
UInt32 bound;
|
|
||||||
int posState = (int)(
|
|
||||||
(nowPos
|
|
||||||
#ifdef _LZMA_OUT_READ
|
|
||||||
+ globalPos
|
|
||||||
#endif
|
|
||||||
)
|
|
||||||
& posStateMask);
|
|
||||||
|
|
||||||
prob = p + IsMatch + (state << kNumPosBitsMax) + posState;
|
|
||||||
IfBit0(prob)
|
|
||||||
{
|
|
||||||
int symbol = 1;
|
|
||||||
UpdateBit0(prob)
|
|
||||||
prob = p + Literal + (LZMA_LIT_SIZE *
|
|
||||||
(((
|
|
||||||
(nowPos
|
|
||||||
#ifdef _LZMA_OUT_READ
|
|
||||||
+ globalPos
|
|
||||||
#endif
|
|
||||||
)
|
|
||||||
& literalPosMask) << lc) + (previousByte >> (8 - lc))));
|
|
||||||
|
|
||||||
if (state >= kNumLitStates)
|
|
||||||
{
|
|
||||||
int matchByte;
|
|
||||||
#ifdef _LZMA_OUT_READ
|
|
||||||
UInt32 pos = dictionaryPos - rep0;
|
|
||||||
if (pos >= dictionarySize)
|
|
||||||
pos += dictionarySize;
|
|
||||||
matchByte = dictionary[pos];
|
|
||||||
#else
|
|
||||||
matchByte = outStream[nowPos - rep0];
|
|
||||||
#endif
|
|
||||||
do
|
|
||||||
{
|
|
||||||
int bit;
|
|
||||||
CProb *probLit;
|
|
||||||
matchByte <<= 1;
|
|
||||||
bit = (matchByte & 0x100);
|
|
||||||
probLit = prob + 0x100 + bit + symbol;
|
|
||||||
RC_GET_BIT2(probLit, symbol, if (bit != 0) break, if (bit == 0) break)
|
|
||||||
}
|
|
||||||
while (symbol < 0x100);
|
|
||||||
}
|
|
||||||
while (symbol < 0x100)
|
|
||||||
{
|
|
||||||
CProb *probLit = prob + symbol;
|
|
||||||
RC_GET_BIT(probLit, symbol)
|
|
||||||
}
|
|
||||||
previousByte = (Byte)symbol;
|
|
||||||
|
|
||||||
outStream[nowPos++] = previousByte;
|
|
||||||
#ifdef _LZMA_OUT_READ
|
|
||||||
if (distanceLimit < dictionarySize)
|
|
||||||
distanceLimit++;
|
|
||||||
|
|
||||||
dictionary[dictionaryPos] = previousByte;
|
|
||||||
if (++dictionaryPos == dictionarySize)
|
|
||||||
dictionaryPos = 0;
|
|
||||||
#endif
|
|
||||||
if (state < 4) state = 0;
|
|
||||||
else if (state < 10) state -= 3;
|
|
||||||
else state -= 6;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
UpdateBit1(prob);
|
|
||||||
prob = p + IsRep + state;
|
|
||||||
IfBit0(prob)
|
|
||||||
{
|
|
||||||
UpdateBit0(prob);
|
|
||||||
rep3 = rep2;
|
|
||||||
rep2 = rep1;
|
|
||||||
rep1 = rep0;
|
|
||||||
state = state < kNumLitStates ? 0 : 3;
|
|
||||||
prob = p + LenCoder;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
UpdateBit1(prob);
|
|
||||||
prob = p + IsRepG0 + state;
|
|
||||||
IfBit0(prob)
|
|
||||||
{
|
|
||||||
UpdateBit0(prob);
|
|
||||||
prob = p + IsRep0Long + (state << kNumPosBitsMax) + posState;
|
|
||||||
IfBit0(prob)
|
|
||||||
{
|
|
||||||
#ifdef _LZMA_OUT_READ
|
|
||||||
UInt32 pos;
|
|
||||||
#endif
|
|
||||||
UpdateBit0(prob);
|
|
||||||
|
|
||||||
#ifdef _LZMA_OUT_READ
|
|
||||||
if (distanceLimit == 0)
|
|
||||||
#else
|
|
||||||
if (nowPos == 0)
|
|
||||||
#endif
|
|
||||||
return LZMA_RESULT_DATA_ERROR;
|
|
||||||
|
|
||||||
state = state < kNumLitStates ? 9 : 11;
|
|
||||||
#ifdef _LZMA_OUT_READ
|
|
||||||
pos = dictionaryPos - rep0;
|
|
||||||
if (pos >= dictionarySize)
|
|
||||||
pos += dictionarySize;
|
|
||||||
previousByte = dictionary[pos];
|
|
||||||
dictionary[dictionaryPos] = previousByte;
|
|
||||||
if (++dictionaryPos == dictionarySize)
|
|
||||||
dictionaryPos = 0;
|
|
||||||
#else
|
|
||||||
previousByte = outStream[nowPos - rep0];
|
|
||||||
#endif
|
|
||||||
outStream[nowPos++] = previousByte;
|
|
||||||
#ifdef _LZMA_OUT_READ
|
|
||||||
if (distanceLimit < dictionarySize)
|
|
||||||
distanceLimit++;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
UpdateBit1(prob);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
UInt32 distance;
|
|
||||||
UpdateBit1(prob);
|
|
||||||
prob = p + IsRepG1 + state;
|
|
||||||
IfBit0(prob)
|
|
||||||
{
|
|
||||||
UpdateBit0(prob);
|
|
||||||
distance = rep1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
UpdateBit1(prob);
|
|
||||||
prob = p + IsRepG2 + state;
|
|
||||||
IfBit0(prob)
|
|
||||||
{
|
|
||||||
UpdateBit0(prob);
|
|
||||||
distance = rep2;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
UpdateBit1(prob);
|
|
||||||
distance = rep3;
|
|
||||||
rep3 = rep2;
|
|
||||||
}
|
|
||||||
rep2 = rep1;
|
|
||||||
}
|
|
||||||
rep1 = rep0;
|
|
||||||
rep0 = distance;
|
|
||||||
}
|
|
||||||
state = state < kNumLitStates ? 8 : 11;
|
|
||||||
prob = p + RepLenCoder;
|
|
||||||
}
|
|
||||||
{
|
|
||||||
int numBits, offset;
|
|
||||||
CProb *probLen = prob + LenChoice;
|
|
||||||
IfBit0(probLen)
|
|
||||||
{
|
|
||||||
UpdateBit0(probLen);
|
|
||||||
probLen = prob + LenLow + (posState << kLenNumLowBits);
|
|
||||||
offset = 0;
|
|
||||||
numBits = kLenNumLowBits;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
UpdateBit1(probLen);
|
|
||||||
probLen = prob + LenChoice2;
|
|
||||||
IfBit0(probLen)
|
|
||||||
{
|
|
||||||
UpdateBit0(probLen);
|
|
||||||
probLen = prob + LenMid + (posState << kLenNumMidBits);
|
|
||||||
offset = kLenNumLowSymbols;
|
|
||||||
numBits = kLenNumMidBits;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
UpdateBit1(probLen);
|
|
||||||
probLen = prob + LenHigh;
|
|
||||||
offset = kLenNumLowSymbols + kLenNumMidSymbols;
|
|
||||||
numBits = kLenNumHighBits;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
RangeDecoderBitTreeDecode(probLen, numBits, len);
|
|
||||||
len += offset;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (state < 4)
|
|
||||||
{
|
|
||||||
int posSlot;
|
|
||||||
state += kNumLitStates;
|
|
||||||
prob = p + PosSlot +
|
|
||||||
((len < kNumLenToPosStates ? len : kNumLenToPosStates - 1) <<
|
|
||||||
kNumPosSlotBits);
|
|
||||||
RangeDecoderBitTreeDecode(prob, kNumPosSlotBits, posSlot);
|
|
||||||
if (posSlot >= kStartPosModelIndex)
|
|
||||||
{
|
|
||||||
int numDirectBits = ((posSlot >> 1) - 1);
|
|
||||||
rep0 = (2 | ((UInt32)posSlot & 1));
|
|
||||||
if (posSlot < kEndPosModelIndex)
|
|
||||||
{
|
|
||||||
rep0 <<= numDirectBits;
|
|
||||||
prob = p + SpecPos + rep0 - posSlot - 1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
numDirectBits -= kNumAlignBits;
|
|
||||||
do
|
|
||||||
{
|
|
||||||
RC_NORMALIZE
|
|
||||||
Range >>= 1;
|
|
||||||
rep0 <<= 1;
|
|
||||||
if (Code >= Range)
|
|
||||||
{
|
|
||||||
Code -= Range;
|
|
||||||
rep0 |= 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
while (--numDirectBits != 0);
|
|
||||||
prob = p + Align;
|
|
||||||
rep0 <<= kNumAlignBits;
|
|
||||||
numDirectBits = kNumAlignBits;
|
|
||||||
}
|
|
||||||
{
|
|
||||||
int i = 1;
|
|
||||||
int mi = 1;
|
|
||||||
do
|
|
||||||
{
|
|
||||||
CProb *prob3 = prob + mi;
|
|
||||||
RC_GET_BIT2(prob3, mi, ; , rep0 |= i);
|
|
||||||
i <<= 1;
|
|
||||||
}
|
|
||||||
while(--numDirectBits != 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
rep0 = posSlot;
|
|
||||||
if (++rep0 == (UInt32)(0))
|
|
||||||
{
|
|
||||||
/* it's for stream version */
|
|
||||||
len = kLzmaStreamWasFinishedId;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
len += kMatchMinLen;
|
|
||||||
#ifdef _LZMA_OUT_READ
|
|
||||||
if (rep0 > distanceLimit)
|
|
||||||
#else
|
|
||||||
if (rep0 > nowPos)
|
|
||||||
#endif
|
|
||||||
return LZMA_RESULT_DATA_ERROR;
|
|
||||||
|
|
||||||
#ifdef _LZMA_OUT_READ
|
|
||||||
if (dictionarySize - distanceLimit > (UInt32)len)
|
|
||||||
distanceLimit += len;
|
|
||||||
else
|
|
||||||
distanceLimit = dictionarySize;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
do
|
|
||||||
{
|
|
||||||
#ifdef _LZMA_OUT_READ
|
|
||||||
UInt32 pos = dictionaryPos - rep0;
|
|
||||||
if (pos >= dictionarySize)
|
|
||||||
pos += dictionarySize;
|
|
||||||
previousByte = dictionary[pos];
|
|
||||||
dictionary[dictionaryPos] = previousByte;
|
|
||||||
if (++dictionaryPos == dictionarySize)
|
|
||||||
dictionaryPos = 0;
|
|
||||||
#else
|
|
||||||
previousByte = outStream[nowPos - rep0];
|
|
||||||
#endif
|
|
||||||
len--;
|
|
||||||
outStream[nowPos++] = previousByte;
|
|
||||||
}
|
|
||||||
while(len != 0 && nowPos < outSize);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
RC_NORMALIZE;
|
|
||||||
|
|
||||||
#ifdef _LZMA_OUT_READ
|
|
||||||
vs->Range = Range;
|
|
||||||
vs->Code = Code;
|
|
||||||
vs->DictionaryPos = dictionaryPos;
|
|
||||||
vs->GlobalPos = globalPos + (UInt32)nowPos;
|
|
||||||
vs->DistanceLimit = distanceLimit;
|
|
||||||
vs->Reps[0] = rep0;
|
|
||||||
vs->Reps[1] = rep1;
|
|
||||||
vs->Reps[2] = rep2;
|
|
||||||
vs->Reps[3] = rep3;
|
|
||||||
vs->State = state;
|
|
||||||
vs->RemainLen = len;
|
|
||||||
vs->TempDictionary[0] = tempDictionary[0];
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef _LZMA_IN_CB
|
|
||||||
vs->Buffer = Buffer;
|
|
||||||
vs->BufferLim = BufferLim;
|
|
||||||
#else
|
|
||||||
*inSizeProcessed = (SizeT)(Buffer - inStream);
|
|
||||||
#endif
|
|
||||||
*outSizeProcessed = nowPos;
|
|
||||||
return LZMA_RESULT_OK;
|
|
||||||
}
|
|
@ -1,113 +0,0 @@
|
|||||||
/*
|
|
||||||
LzmaDecode.h
|
|
||||||
LZMA Decoder interface
|
|
||||||
|
|
||||||
LZMA SDK 4.40 Copyright (c) 1999-2006 Igor Pavlov (2006-05-01)
|
|
||||||
http://www.7-zip.org/
|
|
||||||
|
|
||||||
LZMA SDK is licensed under two licenses:
|
|
||||||
1) GNU Lesser General Public License (GNU LGPL)
|
|
||||||
2) Common Public License (CPL)
|
|
||||||
It means that you can select one of these two licenses and
|
|
||||||
follow rules of that license.
|
|
||||||
|
|
||||||
SPECIAL EXCEPTION:
|
|
||||||
Igor Pavlov, as the author of this code, expressly permits you to
|
|
||||||
statically or dynamically link your code (or bind by name) to the
|
|
||||||
interfaces of this file without subjecting your linked code to the
|
|
||||||
terms of the CPL or GNU LGPL. Any modifications or additions
|
|
||||||
to this file, however, are subject to the LGPL or CPL terms.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef __LZMADECODE_H
|
|
||||||
#define __LZMADECODE_H
|
|
||||||
|
|
||||||
#include "LzmaTypes.h"
|
|
||||||
|
|
||||||
/* #define _LZMA_IN_CB */
|
|
||||||
/* Use callback for input data */
|
|
||||||
|
|
||||||
/* #define _LZMA_OUT_READ */
|
|
||||||
/* Use read function for output data */
|
|
||||||
|
|
||||||
/* #define _LZMA_PROB32 */
|
|
||||||
/* It can increase speed on some 32-bit CPUs,
|
|
||||||
but memory usage will be doubled in that case */
|
|
||||||
|
|
||||||
/* #define _LZMA_LOC_OPT */
|
|
||||||
/* Enable local speed optimizations inside code */
|
|
||||||
|
|
||||||
#ifdef _LZMA_PROB32
|
|
||||||
#define CProb UInt32
|
|
||||||
#else
|
|
||||||
#define CProb UInt16
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define LZMA_RESULT_OK 0
|
|
||||||
#define LZMA_RESULT_DATA_ERROR 1
|
|
||||||
|
|
||||||
#ifdef _LZMA_IN_CB
|
|
||||||
typedef struct _ILzmaInCallback
|
|
||||||
{
|
|
||||||
int (*Read)(void *object, const unsigned char **buffer, SizeT *bufferSize);
|
|
||||||
} ILzmaInCallback;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define LZMA_BASE_SIZE 1846
|
|
||||||
#define LZMA_LIT_SIZE 768
|
|
||||||
|
|
||||||
#define LZMA_PROPERTIES_SIZE 5
|
|
||||||
|
|
||||||
typedef struct _CLzmaProperties
|
|
||||||
{
|
|
||||||
int lc;
|
|
||||||
int lp;
|
|
||||||
int pb;
|
|
||||||
#ifdef _LZMA_OUT_READ
|
|
||||||
UInt32 DictionarySize;
|
|
||||||
#endif
|
|
||||||
}CLzmaProperties;
|
|
||||||
|
|
||||||
int LzmaDecodeProperties(CLzmaProperties *propsRes, const unsigned char *propsData, int size);
|
|
||||||
|
|
||||||
#define LzmaGetNumProbs(Properties) (LZMA_BASE_SIZE + (LZMA_LIT_SIZE << ((Properties)->lc + (Properties)->lp)))
|
|
||||||
|
|
||||||
#define kLzmaNeedInitId (-2)
|
|
||||||
|
|
||||||
typedef struct _CLzmaDecoderState
|
|
||||||
{
|
|
||||||
CLzmaProperties Properties;
|
|
||||||
CProb *Probs;
|
|
||||||
|
|
||||||
#ifdef _LZMA_IN_CB
|
|
||||||
const unsigned char *Buffer;
|
|
||||||
const unsigned char *BufferLim;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef _LZMA_OUT_READ
|
|
||||||
unsigned char *Dictionary;
|
|
||||||
UInt32 Range;
|
|
||||||
UInt32 Code;
|
|
||||||
UInt32 DictionaryPos;
|
|
||||||
UInt32 GlobalPos;
|
|
||||||
UInt32 DistanceLimit;
|
|
||||||
UInt32 Reps[4];
|
|
||||||
int State;
|
|
||||||
int RemainLen;
|
|
||||||
unsigned char TempDictionary[4];
|
|
||||||
#endif
|
|
||||||
} CLzmaDecoderState;
|
|
||||||
|
|
||||||
#ifdef _LZMA_OUT_READ
|
|
||||||
#define LzmaDecoderInit(vs) { (vs)->RemainLen = kLzmaNeedInitId; }
|
|
||||||
#endif
|
|
||||||
|
|
||||||
int LzmaDecode(CLzmaDecoderState *vs,
|
|
||||||
#ifdef _LZMA_IN_CB
|
|
||||||
ILzmaInCallback *inCallback,
|
|
||||||
#else
|
|
||||||
const unsigned char *inStream, SizeT inSize, SizeT *inSizeProcessed,
|
|
||||||
#endif
|
|
||||||
unsigned char *outStream, SizeT outSize, SizeT *outSizeProcessed);
|
|
||||||
|
|
||||||
#endif
|
|
@ -1,45 +0,0 @@
|
|||||||
/*
|
|
||||||
LzmaTypes.h
|
|
||||||
|
|
||||||
Types for LZMA Decoder
|
|
||||||
|
|
||||||
This file written and distributed to public domain by Igor Pavlov.
|
|
||||||
This file is part of LZMA SDK 4.40 (2006-05-01)
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef __LZMATYPES_H
|
|
||||||
#define __LZMATYPES_H
|
|
||||||
|
|
||||||
#ifndef _7ZIP_BYTE_DEFINED
|
|
||||||
#define _7ZIP_BYTE_DEFINED
|
|
||||||
typedef unsigned char Byte;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef _7ZIP_UINT16_DEFINED
|
|
||||||
#define _7ZIP_UINT16_DEFINED
|
|
||||||
typedef unsigned short UInt16;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef _7ZIP_UINT32_DEFINED
|
|
||||||
#define _7ZIP_UINT32_DEFINED
|
|
||||||
#ifdef _LZMA_UINT32_IS_ULONG
|
|
||||||
typedef unsigned long UInt32;
|
|
||||||
#else
|
|
||||||
typedef unsigned int UInt32;
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* #define _LZMA_SYSTEM_SIZE_T */
|
|
||||||
/* Use system's size_t. You can use it to enable 64-bit sizes supporting */
|
|
||||||
|
|
||||||
#ifndef _7ZIP_SIZET_DEFINED
|
|
||||||
#define _7ZIP_SIZET_DEFINED
|
|
||||||
#ifdef _LZMA_SYSTEM_SIZE_T
|
|
||||||
#include <stddef.h>
|
|
||||||
typedef size_t SizeT;
|
|
||||||
#else
|
|
||||||
typedef UInt32 SizeT;
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
|
@ -110,7 +110,8 @@ 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].saved);
|
||||||
free(cs->blocks[i].bits);
|
free(cs->blocks[i].bits);
|
||||||
}
|
}
|
||||||
@ -121,7 +122,8 @@ 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);
|
||||||
@ -133,7 +135,8 @@ s32 cheatSearchSignedRead(u8 *data, int off, int size)
|
|||||||
{
|
{
|
||||||
u32 res = data[off++];
|
u32 res = data[off++];
|
||||||
|
|
||||||
switch(size) {
|
switch(size)
|
||||||
|
{
|
||||||
case BITS_8:
|
case BITS_8:
|
||||||
res <<= 24;
|
res <<= 24;
|
||||||
return ((s32)res) >> 24;
|
return ((s32)res) >> 24;
|
||||||
@ -155,7 +158,8 @@ 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++])<<8;
|
||||||
res |= ((u32)data[off++])<<16;
|
res |= ((u32)data[off++])<<16;
|
||||||
res |= ((u32)data[off++])<<24;
|
res |= ((u32)data[off++])<<24;
|
||||||
@ -174,26 +178,32 @@ 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];
|
CheatSearchBlock *block = &cs->blocks[i];
|
||||||
int size2 = block->size;
|
int size2 = block->size;
|
||||||
u8 *bits = block->bits;
|
u8 *bits = block->bits;
|
||||||
u8 *data = block->data;
|
u8 *data = block->data;
|
||||||
u8 *saved = block->saved;
|
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)) {
|
{
|
||||||
|
if(IS_BIT_SET(bits, j))
|
||||||
|
{
|
||||||
s32 a = cheatSearchSignedRead(data, j, size);
|
s32 a = cheatSearchSignedRead(data, j, size);
|
||||||
s32 b = cheatSearchSignedRead(saved,j, size);
|
s32 b = cheatSearchSignedRead(saved,j, size);
|
||||||
|
|
||||||
if(!func(a, b)) {
|
if(!func(a, b))
|
||||||
|
{
|
||||||
CLEAR_BIT(bits, j);
|
CLEAR_BIT(bits, j);
|
||||||
if(size == BITS_16)
|
if(size == BITS_16)
|
||||||
CLEAR_BIT(bits, j+1);
|
CLEAR_BIT(bits, j+1);
|
||||||
if(size == BITS_32) {
|
if(size == BITS_32)
|
||||||
|
{
|
||||||
CLEAR_BIT(bits, j+2);
|
CLEAR_BIT(bits, j+2);
|
||||||
CLEAR_BIT(bits, j+3);
|
CLEAR_BIT(bits, j+3);
|
||||||
}
|
}
|
||||||
@ -201,26 +211,33 @@ void cheatSearch(const CheatSearchData *cs, int compare, int size,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} 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];
|
CheatSearchBlock *block = &cs->blocks[i];
|
||||||
int size2 = block->size;
|
int size2 = block->size;
|
||||||
u8 *bits = block->bits;
|
u8 *bits = block->bits;
|
||||||
u8 *data = block->data;
|
u8 *data = block->data;
|
||||||
u8 *saved = block->saved;
|
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)) {
|
{
|
||||||
|
if(IS_BIT_SET(bits, j))
|
||||||
|
{
|
||||||
u32 a = cheatSearchRead(data, j, size);
|
u32 a = cheatSearchRead(data, j, size);
|
||||||
u32 b = cheatSearchRead(saved,j, size);
|
u32 b = cheatSearchRead(saved,j, size);
|
||||||
|
|
||||||
if(!func(a, b)) {
|
if(!func(a, b))
|
||||||
|
{
|
||||||
CLEAR_BIT(bits, j);
|
CLEAR_BIT(bits, j);
|
||||||
if(size == BITS_16)
|
if(size == BITS_16)
|
||||||
CLEAR_BIT(bits, j+1);
|
CLEAR_BIT(bits, j+1);
|
||||||
if(size == BITS_32) {
|
if(size == BITS_32)
|
||||||
|
{
|
||||||
CLEAR_BIT(bits, j+2);
|
CLEAR_BIT(bits, j+2);
|
||||||
CLEAR_BIT(bits, j+3);
|
CLEAR_BIT(bits, j+3);
|
||||||
}
|
}
|
||||||
@ -242,25 +259,31 @@ 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];
|
CheatSearchBlock *block = &cs->blocks[i];
|
||||||
int size2 = block->size;
|
int size2 = block->size;
|
||||||
u8 *bits = block->bits;
|
u8 *bits = block->bits;
|
||||||
u8 *data = block->data;
|
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)) {
|
{
|
||||||
|
if(IS_BIT_SET(bits, j))
|
||||||
|
{
|
||||||
s32 a = cheatSearchSignedRead(data, j, size);
|
s32 a = cheatSearchSignedRead(data, j, size);
|
||||||
s32 b = (s32)value;
|
s32 b = (s32)value;
|
||||||
|
|
||||||
if(!func(a, b)) {
|
if(!func(a, b))
|
||||||
|
{
|
||||||
CLEAR_BIT(bits, j);
|
CLEAR_BIT(bits, j);
|
||||||
if(size == BITS_16)
|
if(size == BITS_16)
|
||||||
CLEAR_BIT(bits, j+1);
|
CLEAR_BIT(bits, j+1);
|
||||||
if(size == BITS_32) {
|
if(size == BITS_32)
|
||||||
|
{
|
||||||
CLEAR_BIT(bits, j+2);
|
CLEAR_BIT(bits, j+2);
|
||||||
CLEAR_BIT(bits, j+3);
|
CLEAR_BIT(bits, j+3);
|
||||||
}
|
}
|
||||||
@ -268,24 +291,31 @@ void cheatSearchValue(const CheatSearchData *cs, int compare, int size,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} 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];
|
CheatSearchBlock *block = &cs->blocks[i];
|
||||||
int size2 = block->size;
|
int size2 = block->size;
|
||||||
u8 *bits = block->bits;
|
u8 *bits = block->bits;
|
||||||
u8 *data = block->data;
|
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)) {
|
{
|
||||||
|
if(IS_BIT_SET(bits, j))
|
||||||
|
{
|
||||||
u32 a = cheatSearchRead(data, j, size);
|
u32 a = cheatSearchRead(data, j, size);
|
||||||
|
|
||||||
if(!func(a, value)) {
|
if(!func(a, value))
|
||||||
|
{
|
||||||
CLEAR_BIT(bits, j);
|
CLEAR_BIT(bits, j);
|
||||||
if(size == BITS_16)
|
if(size == BITS_16)
|
||||||
CLEAR_BIT(bits, j+1);
|
CLEAR_BIT(bits, j+1);
|
||||||
if(size == BITS_32) {
|
if(size == BITS_32)
|
||||||
|
{
|
||||||
CLEAR_BIT(bits, j+2);
|
CLEAR_BIT(bits, j+2);
|
||||||
CLEAR_BIT(bits, j+3);
|
CLEAR_BIT(bits, j+3);
|
||||||
}
|
}
|
||||||
@ -305,12 +335,14 @@ 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))
|
if(IS_BIT_SET(bits, j))
|
||||||
res++;
|
res++;
|
||||||
}
|
}
|
||||||
@ -320,7 +352,8 @@ int cheatSearchGetCount(const CheatSearchData *cs, int size)
|
|||||||
|
|
||||||
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);
|
||||||
|
@ -22,7 +22,8 @@
|
|||||||
|
|
||||||
#include "System.h"
|
#include "System.h"
|
||||||
|
|
||||||
struct CheatSearchBlock {
|
struct CheatSearchBlock
|
||||||
|
{
|
||||||
int size;
|
int size;
|
||||||
u32 offset;
|
u32 offset;
|
||||||
u8 *bits;
|
u8 *bits;
|
||||||
@ -30,7 +31,8 @@ struct CheatSearchBlock {
|
|||||||
u8 *saved;
|
u8 *saved;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct CheatSearchData {
|
struct CheatSearchData
|
||||||
|
{
|
||||||
int count;
|
int count;
|
||||||
CheatSearchBlock *blocks;
|
CheatSearchBlock *blocks;
|
||||||
};
|
};
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -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,12 +20,12 @@
|
|||||||
#ifndef GBA_CHEATS_H
|
#ifndef GBA_CHEATS_H
|
||||||
#define GBA_CHEATS_H
|
#define GBA_CHEATS_H
|
||||||
|
|
||||||
struct CheatsData {
|
struct CheatsData
|
||||||
|
{
|
||||||
int code;
|
int code;
|
||||||
int size;
|
int size;
|
||||||
int status;
|
int status;
|
||||||
bool enabled;
|
bool enabled;
|
||||||
u32 rawaddress;
|
|
||||||
u32 address;
|
u32 address;
|
||||||
u32 value;
|
u32 value;
|
||||||
u32 oldValue;
|
u32 oldValue;
|
||||||
@ -33,7 +33,7 @@ struct CheatsData {
|
|||||||
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];
|
||||||
|
@ -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"
|
||||||
|
|
||||||
@ -43,11 +42,6 @@ variable_desc eepromSaveData[] = {
|
|||||||
{ NULL, 0 }
|
{ NULL, 0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
void eepromInit()
|
|
||||||
{
|
|
||||||
memset(eepromData, 255, sizeof(eepromData));
|
|
||||||
}
|
|
||||||
|
|
||||||
void eepromReset()
|
void eepromReset()
|
||||||
{
|
{
|
||||||
eepromMode = EEPROM_IDLE;
|
eepromMode = EEPROM_IDLE;
|
||||||
@ -68,28 +62,23 @@ 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);
|
eepromSize = utilReadInt(gzFile);
|
||||||
utilGzRead(gzFile, eepromData, 0x2000);
|
utilGzRead(gzFile, eepromData, 0x2000);
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
// prior to 0.7.1, only 4K EEPROM was supported
|
// prior to 0.7.1, only 4K EEPROM was supported
|
||||||
eepromSize = 512;
|
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_IDLE:
|
||||||
case EEPROM_READADDRESS:
|
case EEPROM_READADDRESS:
|
||||||
case EEPROM_WRITEDATA:
|
case EEPROM_WRITEDATA:
|
||||||
@ -97,7 +86,8 @@ int eepromRead(u32 /* address */)
|
|||||||
case EEPROM_READDATA:
|
case EEPROM_READDATA:
|
||||||
{
|
{
|
||||||
eepromBits++;
|
eepromBits++;
|
||||||
if(eepromBits == 4) {
|
if(eepromBits == 4)
|
||||||
|
{
|
||||||
eepromMode = EEPROM_READDATA2;
|
eepromMode = EEPROM_READDATA2;
|
||||||
eepromBits = 0;
|
eepromBits = 0;
|
||||||
eepromByte = 0;
|
eepromByte = 0;
|
||||||
@ -128,7 +118,8 @@ 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:
|
case EEPROM_IDLE:
|
||||||
eepromByte = 0;
|
eepromByte = 0;
|
||||||
eepromBits = 1;
|
eepromBits = 1;
|
||||||
@ -139,36 +130,48 @@ void eepromWrite(u32 /* address */, u8 value)
|
|||||||
eepromBuffer[eepromByte] <<= 1;
|
eepromBuffer[eepromByte] <<= 1;
|
||||||
eepromBuffer[eepromByte] |= bit;
|
eepromBuffer[eepromByte] |= bit;
|
||||||
eepromBits++;
|
eepromBits++;
|
||||||
if((eepromBits & 7) == 0) {
|
if((eepromBits & 7) == 0)
|
||||||
|
{
|
||||||
eepromByte++;
|
eepromByte++;
|
||||||
}
|
}
|
||||||
if(cpuDmaCount == 0x11 || cpuDmaCount == 0x51) {
|
if(cpuDmaCount == 0x11 || cpuDmaCount == 0x51)
|
||||||
if(eepromBits == 0x11) {
|
{
|
||||||
|
if(eepromBits == 0x11)
|
||||||
|
{
|
||||||
eepromInUse = true;
|
eepromInUse = true;
|
||||||
eepromSize = 0x2000;
|
eepromSize = 0x2000;
|
||||||
eepromAddress = ((eepromBuffer[0] & 0x3F) << 8) |
|
eepromAddress = ((eepromBuffer[0] & 0x3F) << 8) |
|
||||||
((eepromBuffer[1] & 0xFF));
|
((eepromBuffer[1] & 0xFF));
|
||||||
if(!(eepromBuffer[0] & 0x40)) {
|
if(!(eepromBuffer[0] & 0x40))
|
||||||
|
{
|
||||||
eepromBuffer[0] = bit;
|
eepromBuffer[0] = bit;
|
||||||
eepromBits = 1;
|
eepromBits = 1;
|
||||||
eepromByte = 0;
|
eepromByte = 0;
|
||||||
eepromMode = EEPROM_WRITEDATA;
|
eepromMode = EEPROM_WRITEDATA;
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
eepromMode = EEPROM_READDATA;
|
eepromMode = EEPROM_READDATA;
|
||||||
eepromByte = 0;
|
eepromByte = 0;
|
||||||
eepromBits = 0;
|
eepromBits = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
if(eepromBits == 9) {
|
else
|
||||||
|
{
|
||||||
|
if(eepromBits == 9)
|
||||||
|
{
|
||||||
eepromInUse = true;
|
eepromInUse = true;
|
||||||
eepromAddress = (eepromBuffer[0] & 0x3F);
|
eepromAddress = (eepromBuffer[0] & 0x3F);
|
||||||
if(!(eepromBuffer[0] & 0x40)) {
|
if(!(eepromBuffer[0] & 0x40))
|
||||||
|
{
|
||||||
eepromBuffer[0] = bit;
|
eepromBuffer[0] = bit;
|
||||||
eepromBits = 1;
|
eepromBits = 1;
|
||||||
eepromByte = 0;
|
eepromByte = 0;
|
||||||
eepromMode = EEPROM_WRITEDATA;
|
eepromMode = EEPROM_WRITEDATA;
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
eepromMode = EEPROM_READDATA;
|
eepromMode = EEPROM_READDATA;
|
||||||
eepromByte = 0;
|
eepromByte = 0;
|
||||||
eepromBits = 0;
|
eepromBits = 0;
|
||||||
@ -185,17 +188,22 @@ void eepromWrite(u32 /* address */, u8 value)
|
|||||||
eepromBuffer[eepromByte] <<= 1;
|
eepromBuffer[eepromByte] <<= 1;
|
||||||
eepromBuffer[eepromByte] |= bit;
|
eepromBuffer[eepromByte] |= bit;
|
||||||
eepromBits++;
|
eepromBits++;
|
||||||
if((eepromBits & 7) == 0) {
|
if((eepromBits & 7) == 0)
|
||||||
|
{
|
||||||
eepromByte++;
|
eepromByte++;
|
||||||
}
|
}
|
||||||
if(eepromBits == 0x40) {
|
if(eepromBits == 0x40)
|
||||||
|
{
|
||||||
eepromInUse = true;
|
eepromInUse = true;
|
||||||
// write data;
|
// write data;
|
||||||
for(int i = 0; i < 8; i++) {
|
for(int i = 0; i < 8; i++)
|
||||||
|
{
|
||||||
eepromData[(eepromAddress << 3) + i] = eepromBuffer[i];
|
eepromData[(eepromAddress << 3) + i] = eepromBuffer[i];
|
||||||
}
|
}
|
||||||
systemSaveUpdateCounter = SYSTEM_SAVE_UPDATED;
|
systemSaveUpdateCounter = SYSTEM_SAVE_UPDATED;
|
||||||
} else if(eepromBits == 0x41) {
|
}
|
||||||
|
else if(eepromBits == 0x41)
|
||||||
|
{
|
||||||
eepromMode = EEPROM_IDLE;
|
eepromMode = EEPROM_IDLE;
|
||||||
eepromByte = 0;
|
eepromByte = 0;
|
||||||
eepromBits = 0;
|
eepromBits = 0;
|
||||||
|
@ -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;
|
||||||
|
@ -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"
|
||||||
@ -67,11 +67,6 @@ static variable_desc flashSaveData3[] = {
|
|||||||
{ NULL, 0 }
|
{ NULL, 0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
void flashInit()
|
|
||||||
{
|
|
||||||
memset(flashSaveMemory, 0xff, sizeof(flashSaveMemory));
|
|
||||||
}
|
|
||||||
|
|
||||||
void flashReset()
|
void flashReset()
|
||||||
{
|
{
|
||||||
flashState = FLASH_READ_ARRAY;
|
flashState = FLASH_READ_ARRAY;
|
||||||
@ -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);
|
utilReadData(gzFile, flashSaveData2);
|
||||||
flashBank = 0;
|
flashBank = 0;
|
||||||
flashSetSize(flashSize);
|
flashSetSize(flashSize);
|
||||||
} else {
|
|
||||||
utilReadData(gzFile, flashSaveData3);
|
|
||||||
}
|
}
|
||||||
}
|
else
|
||||||
|
|
||||||
void flashReadGameSkip(gzFile gzFile, int version)
|
|
||||||
{
|
{
|
||||||
// skip the flash data in a save game
|
utilReadData(gzFile, flashSaveData3);
|
||||||
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) {
|
flashSize = size;
|
||||||
|
if(size == 0x10000)
|
||||||
|
{
|
||||||
flashDeviceID = 0x1b;
|
flashDeviceID = 0x1b;
|
||||||
flashManufacturerID = 0x32;
|
flashManufacturerID = 0x32;
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
flashDeviceID = 0x13; //0x09;
|
flashDeviceID = 0x13; //0x09;
|
||||||
flashManufacturerID = 0x62; //0xc2;
|
flashManufacturerID = 0x62; //0xc2;
|
||||||
}
|
}
|
||||||
// Added to make 64k saves compatible with 128k ones
|
|
||||||
// (allow wrongfuly set 64k saves to work for Pokemon games)
|
|
||||||
if ((size == 0x20000) && (flashSize == 0x10000))
|
|
||||||
memcpy((u8 *)(flashSaveMemory+0x10000), (u8 *)(flashSaveMemory), 0x10000);
|
|
||||||
flashSize = size;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
u8 flashRead(u32 address)
|
u8 flashRead(u32 address)
|
||||||
@ -132,11 +117,13 @@ 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:
|
case FLASH_READ_ARRAY:
|
||||||
return flashSaveMemory[(flashBank << 16) + address];
|
return flashSaveMemory[(flashBank << 16) + address];
|
||||||
case FLASH_AUTOSELECT:
|
case FLASH_AUTOSELECT:
|
||||||
switch(address & 0xFF) {
|
switch(address & 0xFF)
|
||||||
|
{
|
||||||
case 0:
|
case 0:
|
||||||
// manufacturer ID
|
// manufacturer ID
|
||||||
return flashManufacturerID;
|
return flashManufacturerID;
|
||||||
@ -156,10 +143,13 @@ u8 flashRead(u32 address)
|
|||||||
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;
|
saveType = 2;
|
||||||
cpuSaveGameFunc = flashWrite;
|
cpuSaveGameFunc = flashWrite;
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
saveType = 1;
|
saveType = 1;
|
||||||
cpuSaveGameFunc = sramWrite;
|
cpuSaveGameFunc = sramWrite;
|
||||||
}
|
}
|
||||||
@ -167,19 +157,13 @@ void flashSaveDecide(u32 address, u8 byte)
|
|||||||
(*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:
|
case FLASH_READ_ARRAY:
|
||||||
if(address == 0x5555 && byte == 0xAA)
|
if(address == 0x5555 && byte == 0xAA)
|
||||||
flashState = FLASH_CMD_1;
|
flashState = FLASH_CMD_1;
|
||||||
@ -191,69 +175,97 @@ void flashWrite(u32 address, u8 byte)
|
|||||||
flashState = FLASH_READ_ARRAY;
|
flashState = FLASH_READ_ARRAY;
|
||||||
break;
|
break;
|
||||||
case FLASH_CMD_2:
|
case FLASH_CMD_2:
|
||||||
if(address == 0x5555) {
|
if(address == 0x5555)
|
||||||
if(byte == 0x90) {
|
{
|
||||||
|
if(byte == 0x90)
|
||||||
|
{
|
||||||
flashState = FLASH_AUTOSELECT;
|
flashState = FLASH_AUTOSELECT;
|
||||||
flashReadState = FLASH_AUTOSELECT;
|
flashReadState = FLASH_AUTOSELECT;
|
||||||
} else if(byte == 0x80) {
|
}
|
||||||
|
else if(byte == 0x80)
|
||||||
|
{
|
||||||
flashState = FLASH_CMD_3;
|
flashState = FLASH_CMD_3;
|
||||||
} else if(byte == 0xF0) {
|
}
|
||||||
flashState = FLASH_READ_ARRAY;
|
else if(byte == 0xF0)
|
||||||
flashReadState = FLASH_READ_ARRAY;
|
{
|
||||||
} else if(byte == 0xA0) {
|
|
||||||
flashState = FLASH_PROGRAM;
|
|
||||||
} else if(byte == 0xB0 && flashSize == 0x20000) {
|
|
||||||
flashState = FLASH_SETBANK;
|
|
||||||
} else {
|
|
||||||
flashState = FLASH_READ_ARRAY;
|
flashState = FLASH_READ_ARRAY;
|
||||||
flashReadState = FLASH_READ_ARRAY;
|
flashReadState = FLASH_READ_ARRAY;
|
||||||
}
|
}
|
||||||
} else {
|
else if(byte == 0xA0)
|
||||||
|
{
|
||||||
|
flashState = FLASH_PROGRAM;
|
||||||
|
}
|
||||||
|
else if(byte == 0xB0 && flashSize == 0x20000)
|
||||||
|
{
|
||||||
|
flashState = FLASH_SETBANK;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
flashState = FLASH_READ_ARRAY;
|
||||||
|
flashReadState = FLASH_READ_ARRAY;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
flashState = FLASH_READ_ARRAY;
|
flashState = FLASH_READ_ARRAY;
|
||||||
flashReadState = FLASH_READ_ARRAY;
|
flashReadState = FLASH_READ_ARRAY;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case FLASH_CMD_3:
|
case FLASH_CMD_3:
|
||||||
if(address == 0x5555 && byte == 0xAA) {
|
if(address == 0x5555 && byte == 0xAA)
|
||||||
|
{
|
||||||
flashState = FLASH_CMD_4;
|
flashState = FLASH_CMD_4;
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
flashState = FLASH_READ_ARRAY;
|
flashState = FLASH_READ_ARRAY;
|
||||||
flashReadState = FLASH_READ_ARRAY;
|
flashReadState = FLASH_READ_ARRAY;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case FLASH_CMD_4:
|
case FLASH_CMD_4:
|
||||||
if(address == 0x2AAA && byte == 0x55) {
|
if(address == 0x2AAA && byte == 0x55)
|
||||||
|
{
|
||||||
flashState = FLASH_CMD_5;
|
flashState = FLASH_CMD_5;
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
flashState = FLASH_READ_ARRAY;
|
flashState = FLASH_READ_ARRAY;
|
||||||
flashReadState = FLASH_READ_ARRAY;
|
flashReadState = FLASH_READ_ARRAY;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case FLASH_CMD_5:
|
case FLASH_CMD_5:
|
||||||
if(byte == 0x30) {
|
if(byte == 0x30)
|
||||||
|
{
|
||||||
// SECTOR ERASE
|
// SECTOR ERASE
|
||||||
memset(&flashSaveMemory[(flashBank << 16) + (address & 0xF000)],
|
memset(&flashSaveMemory[(flashBank << 16) + (address & 0xF000)],
|
||||||
0,
|
0,
|
||||||
0x1000);
|
0x1000);
|
||||||
systemSaveUpdateCounter = SYSTEM_SAVE_UPDATED;
|
systemSaveUpdateCounter = SYSTEM_SAVE_UPDATED;
|
||||||
flashReadState = FLASH_ERASE_COMPLETE;
|
flashReadState = FLASH_ERASE_COMPLETE;
|
||||||
} else if(byte == 0x10) {
|
}
|
||||||
|
else if(byte == 0x10)
|
||||||
|
{
|
||||||
// CHIP ERASE
|
// CHIP ERASE
|
||||||
memset(flashSaveMemory, 0, flashSize);
|
memset(flashSaveMemory, 0, flashSize);
|
||||||
systemSaveUpdateCounter = SYSTEM_SAVE_UPDATED;
|
systemSaveUpdateCounter = SYSTEM_SAVE_UPDATED;
|
||||||
flashReadState = FLASH_ERASE_COMPLETE;
|
flashReadState = FLASH_ERASE_COMPLETE;
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
flashState = FLASH_READ_ARRAY;
|
flashState = FLASH_READ_ARRAY;
|
||||||
flashReadState = FLASH_READ_ARRAY;
|
flashReadState = FLASH_READ_ARRAY;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case FLASH_AUTOSELECT:
|
case FLASH_AUTOSELECT:
|
||||||
if(byte == 0xF0) {
|
if(byte == 0xF0)
|
||||||
|
{
|
||||||
flashState = FLASH_READ_ARRAY;
|
flashState = FLASH_READ_ARRAY;
|
||||||
flashReadState = FLASH_READ_ARRAY;
|
flashReadState = FLASH_READ_ARRAY;
|
||||||
} else if(address == 0x5555 && byte == 0xAA)
|
}
|
||||||
|
else if(address == 0x5555 && byte == 0xAA)
|
||||||
flashState = FLASH_CMD_1;
|
flashState = FLASH_CMD_1;
|
||||||
else {
|
else
|
||||||
|
{
|
||||||
flashState = FLASH_READ_ARRAY;
|
flashState = FLASH_READ_ARRAY;
|
||||||
flashReadState = FLASH_READ_ARRAY;
|
flashReadState = FLASH_READ_ARRAY;
|
||||||
}
|
}
|
||||||
@ -265,7 +277,8 @@ void flashWrite(u32 address, u8 byte)
|
|||||||
flashReadState = FLASH_READ_ARRAY;
|
flashReadState = FLASH_READ_ARRAY;
|
||||||
break;
|
break;
|
||||||
case FLASH_SETBANK:
|
case FLASH_SETBANK:
|
||||||
if(address == 0) {
|
if(address == 0)
|
||||||
|
{
|
||||||
flashBank = (byte & 1);
|
flashBank = (byte & 1);
|
||||||
}
|
}
|
||||||
flashState = FLASH_READ_ARRAY;
|
flashState = FLASH_READ_ARRAY;
|
||||||
|
@ -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
4361
source/vba/GBA.cpp
Normal file
File diff suppressed because it is too large
Load Diff
@ -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,17 +30,18 @@
|
|||||||
#define SAVE_GAME_VERSION_6 6
|
#define SAVE_GAME_VERSION_6 6
|
||||||
#define SAVE_GAME_VERSION_7 7
|
#define SAVE_GAME_VERSION_7 7
|
||||||
#define SAVE_GAME_VERSION_8 8
|
#define SAVE_GAME_VERSION_8 8
|
||||||
#define SAVE_GAME_VERSION_9 9
|
#define SAVE_GAME_VERSION SAVE_GAME_VERSION_8
|
||||||
#define SAVE_GAME_VERSION_10 10
|
|
||||||
#define SAVE_GAME_VERSION SAVE_GAME_VERSION_10
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct
|
||||||
|
{
|
||||||
u8 *address;
|
u8 *address;
|
||||||
u32 mask;
|
u32 mask;
|
||||||
} memoryMap;
|
}
|
||||||
|
memoryMap;
|
||||||
|
|
||||||
typedef union {
|
typedef union {
|
||||||
struct {
|
struct
|
||||||
|
{
|
||||||
#ifdef WORDS_BIGENDIAN
|
#ifdef WORDS_BIGENDIAN
|
||||||
u8 B3;
|
u8 B3;
|
||||||
u8 B2;
|
u8 B2;
|
||||||
@ -52,8 +53,10 @@ typedef union {
|
|||||||
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;
|
||||||
@ -61,7 +64,8 @@ typedef union {
|
|||||||
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
|
||||||
@ -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
556
source/vba/GBAinline.h
Normal file
@ -0,0 +1,556 @@
|
|||||||
|
// -*- C++ -*-
|
||||||
|
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
|
||||||
|
// Copyright (C) 1999-2003 Forgotten
|
||||||
|
// Copyright (C) 2004 Forgotten and the VBA development team
|
||||||
|
|
||||||
|
// This program is free software; you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation; either version 2, or(at your option)
|
||||||
|
// any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with this program; if not, write to the Free Software Foundation,
|
||||||
|
// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
|
#ifndef VBA_GBAinline_H
|
||||||
|
#define VBA_GBAinline_H
|
||||||
|
|
||||||
|
#include "System.h"
|
||||||
|
#include "Port.h"
|
||||||
|
#include "RTC.h"
|
||||||
|
#include "vmmem.h"
|
||||||
|
|
||||||
|
extern bool cpuSramEnabled;
|
||||||
|
extern bool cpuFlashEnabled;
|
||||||
|
extern bool cpuEEPROMEnabled;
|
||||||
|
extern bool cpuEEPROMSensorEnabled;
|
||||||
|
|
||||||
|
#define VM_USED 1
|
||||||
|
|
||||||
|
#define CPUReadByteQuickDef(addr) \
|
||||||
|
map[(addr)>>24].address[(addr) & map[(addr)>>24].mask]
|
||||||
|
|
||||||
|
#define CPUReadHalfWordQuickDef(addr) \
|
||||||
|
READ16LE(((u16*)&map[(addr)>>24].address[(addr) & map[(addr)>>24].mask]))
|
||||||
|
|
||||||
|
#define CPUReadMemoryQuickDef(addr) \
|
||||||
|
READ32LE(((u32*)&map[(addr)>>24].address[(addr) & map[(addr)>>24].mask]))
|
||||||
|
|
||||||
|
u8 inline CPUReadByteQuick( u32 addr )
|
||||||
|
{
|
||||||
|
switch(addr >> 24 )
|
||||||
|
{
|
||||||
|
case 8:
|
||||||
|
case 9:
|
||||||
|
case 10:
|
||||||
|
case 12:
|
||||||
|
return VMRead8( addr & 0x1FFFFFF );
|
||||||
|
|
||||||
|
default:
|
||||||
|
return CPUReadByteQuickDef(addr);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
u16 inline CPUReadHalfWordQuick( u32 addr )
|
||||||
|
{
|
||||||
|
switch(addr >> 24)
|
||||||
|
{
|
||||||
|
case 8:
|
||||||
|
case 9:
|
||||||
|
case 10:
|
||||||
|
case 12:
|
||||||
|
return VMRead16( addr & 0x1FFFFFF );
|
||||||
|
default:
|
||||||
|
return CPUReadHalfWordQuickDef(addr);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
u32 inline CPUReadMemoryQuick( u32 addr )
|
||||||
|
{
|
||||||
|
switch(addr >> 24)
|
||||||
|
{
|
||||||
|
case 8:
|
||||||
|
case 9:
|
||||||
|
case 10:
|
||||||
|
case 12:
|
||||||
|
return VMRead32( addr & 0x1FFFFFF );
|
||||||
|
default:
|
||||||
|
return CPUReadMemoryQuickDef(addr);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline u32 CPUReadMemory(u32 address)
|
||||||
|
{
|
||||||
|
|
||||||
|
#ifdef DEV_VERSION
|
||||||
|
if(address & 3)
|
||||||
|
{
|
||||||
|
if(systemVerbose & VERBOSE_UNALIGNED_MEMORY)
|
||||||
|
{
|
||||||
|
log("Unaligned word read: %08x at %08x\n", address, armMode ?
|
||||||
|
armNextPC - 4 : armNextPC - 2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
u32 value;
|
||||||
|
switch(address >> 24)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
if(reg[15].I >> 24)
|
||||||
|
{
|
||||||
|
if(address < 0x4000)
|
||||||
|
{
|
||||||
|
#ifdef DEV_VERSION
|
||||||
|
if(systemVerbose & VERBOSE_ILLEGAL_READ)
|
||||||
|
{
|
||||||
|
log("Illegal word read: %08x at %08x\n", address, armMode ?
|
||||||
|
armNextPC - 4 : armNextPC - 2);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
value = READ32LE(((u32 *)&biosProtected));
|
||||||
|
}
|
||||||
|
else goto unreadable;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
value = READ32LE(((u32 *)&bios[address & 0x3FFC]));
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
value = READ32LE(((u32 *)&workRAM[address & 0x3FFFC]));
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
value = READ32LE(((u32 *)&internalRAM[address & 0x7ffC]));
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
if((address < 0x4000400) && ioReadable[address & 0x3fc])
|
||||||
|
{
|
||||||
|
if(ioReadable[(address & 0x3fc) + 2])
|
||||||
|
value = READ32LE(((u32 *)&ioMem[address & 0x3fC]));
|
||||||
|
else
|
||||||
|
value = READ16LE(((u16 *)&ioMem[address & 0x3fc]));
|
||||||
|
}
|
||||||
|
else goto unreadable;
|
||||||
|
break;
|
||||||
|
case 5:
|
||||||
|
value = READ32LE(((u32 *)&paletteRAM[address & 0x3fC]));
|
||||||
|
break;
|
||||||
|
case 6:
|
||||||
|
value = READ32LE(((u32 *)&vram[address & 0x1fffc]));
|
||||||
|
break;
|
||||||
|
case 7:
|
||||||
|
value = READ32LE(((u32 *)&oam[address & 0x3FC]));
|
||||||
|
break;
|
||||||
|
case 8:
|
||||||
|
case 9:
|
||||||
|
case 10:
|
||||||
|
case 11:
|
||||||
|
case 12:
|
||||||
|
/** Need NGC VM here **/
|
||||||
|
//value = READ32LE(((u32 *)&rom[address&0x1FFFFFC]));
|
||||||
|
value = VMRead32( address & 0x1FFFFFC );
|
||||||
|
break;
|
||||||
|
case 13:
|
||||||
|
if(cpuEEPROMEnabled)
|
||||||
|
// no need to swap this
|
||||||
|
return eepromRead(address);
|
||||||
|
goto unreadable;
|
||||||
|
case 14:
|
||||||
|
if(cpuFlashEnabled | cpuSramEnabled)
|
||||||
|
// no need to swap this
|
||||||
|
return flashRead(address);
|
||||||
|
// default
|
||||||
|
default:
|
||||||
|
unreadable:
|
||||||
|
#ifdef DEV_VERSION
|
||||||
|
if(systemVerbose & VERBOSE_ILLEGAL_READ)
|
||||||
|
{
|
||||||
|
log("Illegal word read: %08x at %08x\n", address, armMode ?
|
||||||
|
armNextPC - 4 : armNextPC - 2);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// if(ioMem[0x205] & 0x40) {
|
||||||
|
if(armState)
|
||||||
|
{
|
||||||
|
#if VM_USED
|
||||||
|
value = CPUReadMemoryQuick(reg[15].I);
|
||||||
|
#else
|
||||||
|
value = CPUReadMemoryQuickDef(reg[15].I);
|
||||||
|
#endif
|
||||||
|
//value = VMRead32(reg[15].I);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
#if VM_USED
|
||||||
|
value = CPUReadHalfWordQuick(reg[15].I) |
|
||||||
|
CPUReadHalfWordQuick(reg[15].I) << 16;
|
||||||
|
#else
|
||||||
|
value = CPUReadHalfWordQuickDef(reg[15].I) |
|
||||||
|
CPUReadHalfWordQuickDef(reg[15].I) << 16;
|
||||||
|
#endif
|
||||||
|
//value = VMRead16(reg[15].I) | VMRead16(reg[15].I) << 16;
|
||||||
|
}
|
||||||
|
// } else {
|
||||||
|
// value = *((u32 *)&bios[address & 0x3ffc]);
|
||||||
|
// }
|
||||||
|
// return 0xFFFFFFFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(address & 3)
|
||||||
|
{
|
||||||
|
#ifdef C_CORE
|
||||||
|
int shift = (address & 3) << 3;
|
||||||
|
value = (value >> shift) | (value << (32 - shift));
|
||||||
|
#else
|
||||||
|
#ifdef __GNUC__
|
||||||
|
asm("and $3, %%ecx;"
|
||||||
|
"shl $3 ,%%ecx;"
|
||||||
|
"ror %%cl, %0"
|
||||||
|
: "=r" (value)
|
||||||
|
: "r" (value), "c" (address));
|
||||||
|
#else
|
||||||
|
__asm {
|
||||||
|
mov ecx, address;
|
||||||
|
and ecx, 3;
|
||||||
|
shl ecx, 3;
|
||||||
|
ror [dword ptr value], cl;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
extern u32 myROM[];
|
||||||
|
|
||||||
|
inline u32 CPUReadHalfWord(u32 address)
|
||||||
|
{
|
||||||
|
#ifdef DEV_VERSION
|
||||||
|
if(address & 1)
|
||||||
|
{
|
||||||
|
if(systemVerbose & VERBOSE_UNALIGNED_MEMORY)
|
||||||
|
{
|
||||||
|
log("Unaligned halfword read: %08x at %08x\n", address, armMode ?
|
||||||
|
armNextPC - 4 : armNextPC - 2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
u32 value;
|
||||||
|
|
||||||
|
switch(address >> 24)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
if (reg[15].I >> 24)
|
||||||
|
{
|
||||||
|
if(address < 0x4000)
|
||||||
|
{
|
||||||
|
#ifdef DEV_VERSION
|
||||||
|
if(systemVerbose & VERBOSE_ILLEGAL_READ)
|
||||||
|
{
|
||||||
|
log("Illegal halfword read: %08x at %08x\n", address, armMode ?
|
||||||
|
armNextPC - 4 : armNextPC - 2);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
value = READ16LE(((u16 *)&biosProtected[address&2]));
|
||||||
|
}
|
||||||
|
else goto unreadable;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
value = READ16LE(((u16 *)&bios[address & 0x3FFE]));
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
value = READ16LE(((u16 *)&workRAM[address & 0x3FFFE]));
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
value = READ16LE(((u16 *)&internalRAM[address & 0x7ffe]));
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
if((address < 0x4000400) && ioReadable[address & 0x3fe])
|
||||||
|
value = READ16LE(((u16 *)&ioMem[address & 0x3fe]));
|
||||||
|
else goto unreadable;
|
||||||
|
break;
|
||||||
|
case 5:
|
||||||
|
value = READ16LE(((u16 *)&paletteRAM[address & 0x3fe]));
|
||||||
|
break;
|
||||||
|
case 6:
|
||||||
|
value = READ16LE(((u16 *)&vram[address & 0x1fffe]));
|
||||||
|
break;
|
||||||
|
case 7:
|
||||||
|
value = READ16LE(((u16 *)&oam[address & 0x3fe]));
|
||||||
|
break;
|
||||||
|
case 8:
|
||||||
|
case 9:
|
||||||
|
case 10:
|
||||||
|
case 11:
|
||||||
|
case 12:
|
||||||
|
if(address == 0x80000c4 || address == 0x80000c6 || address == 0x80000c8)
|
||||||
|
value = rtcRead(address);
|
||||||
|
else
|
||||||
|
/** Need NGC VM Here **/
|
||||||
|
//value = READ16LE(((u16 *)&rom[address & 0x1FFFFFE]));
|
||||||
|
value = VMRead16( address & 0x1FFFFFE );
|
||||||
|
break;
|
||||||
|
case 13:
|
||||||
|
if(cpuEEPROMEnabled)
|
||||||
|
// no need to swap this
|
||||||
|
return eepromRead(address);
|
||||||
|
goto unreadable;
|
||||||
|
case 14:
|
||||||
|
if(cpuFlashEnabled | cpuSramEnabled)
|
||||||
|
// no need to swap this
|
||||||
|
return flashRead(address);
|
||||||
|
// default
|
||||||
|
default:
|
||||||
|
unreadable:
|
||||||
|
#ifdef DEV_VERSION
|
||||||
|
if(systemVerbose & VERBOSE_ILLEGAL_READ)
|
||||||
|
{
|
||||||
|
log("Illegal halfword read: %08x at %08x\n", address, armMode ?
|
||||||
|
armNextPC - 4 : armNextPC - 2);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
extern bool cpuDmaHack;
|
||||||
|
extern u32 cpuDmaLast;
|
||||||
|
extern int cpuDmaCount;
|
||||||
|
if(cpuDmaHack && cpuDmaCount)
|
||||||
|
{
|
||||||
|
value = (u16)cpuDmaLast;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(armState)
|
||||||
|
{
|
||||||
|
#if VM_USED
|
||||||
|
value = CPUReadHalfWordQuick(reg[15].I + (address & 2));
|
||||||
|
#else
|
||||||
|
value = CPUReadHalfWordQuickDef(reg[15].I + (address & 2));
|
||||||
|
#endif
|
||||||
|
//value = VMRead16(reg[15].I + (address & 2));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
#if VM_USED
|
||||||
|
value = CPUReadHalfWordQuick(reg[15].I);
|
||||||
|
#else
|
||||||
|
value = CPUReadHalfWordQuickDef(reg[15].I);
|
||||||
|
#endif
|
||||||
|
//value = VMRead16(reg[15].I);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// return value;
|
||||||
|
// if(address & 1)
|
||||||
|
// value = (value >> 8) | ((value & 0xFF) << 24);
|
||||||
|
// return 0xFFFF;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(address & 1)
|
||||||
|
{
|
||||||
|
value = (value >> 8) | (value << 24);
|
||||||
|
}
|
||||||
|
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline u16 CPUReadHalfWordSigned(u32 address)
|
||||||
|
{
|
||||||
|
u16 value = CPUReadHalfWord(address);
|
||||||
|
if((address & 1))
|
||||||
|
value = (s8)value;
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline u8 CPUReadByte(u32 address)
|
||||||
|
{
|
||||||
|
switch(address >> 24)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
if (reg[15].I >> 24)
|
||||||
|
{
|
||||||
|
if(address < 0x4000)
|
||||||
|
{
|
||||||
|
#ifdef DEV_VERSION
|
||||||
|
if(systemVerbose & VERBOSE_ILLEGAL_READ)
|
||||||
|
{
|
||||||
|
log("Illegal byte read: %08x at %08x\n", address, armMode ?
|
||||||
|
armNextPC - 4 : armNextPC - 2);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
return biosProtected[address & 3];
|
||||||
|
}
|
||||||
|
else goto unreadable;
|
||||||
|
}
|
||||||
|
return bios[address & 0x3FFF];
|
||||||
|
case 2:
|
||||||
|
return workRAM[address & 0x3FFFF];
|
||||||
|
case 3:
|
||||||
|
return internalRAM[address & 0x7fff];
|
||||||
|
case 4:
|
||||||
|
if((address < 0x4000400) && ioReadable[address & 0x3ff])
|
||||||
|
return ioMem[address & 0x3ff];
|
||||||
|
else goto unreadable;
|
||||||
|
case 5:
|
||||||
|
return paletteRAM[address & 0x3ff];
|
||||||
|
case 6:
|
||||||
|
return vram[address & 0x1ffff];
|
||||||
|
case 7:
|
||||||
|
return oam[address & 0x3ff];
|
||||||
|
case 8:
|
||||||
|
case 9:
|
||||||
|
case 10:
|
||||||
|
case 11:
|
||||||
|
case 12:
|
||||||
|
/** Need NGC VM Here **/
|
||||||
|
//return rom[address & 0x1FFFFFF];
|
||||||
|
return VMRead8( address & 0x1FFFFFF );
|
||||||
|
case 13:
|
||||||
|
if(cpuEEPROMEnabled)
|
||||||
|
return eepromRead(address);
|
||||||
|
goto unreadable;
|
||||||
|
case 14:
|
||||||
|
if(cpuSramEnabled | cpuFlashEnabled)
|
||||||
|
return flashRead(address);
|
||||||
|
if(cpuEEPROMSensorEnabled)
|
||||||
|
{
|
||||||
|
switch(address & 0x00008f00)
|
||||||
|
{
|
||||||
|
case 0x8200:
|
||||||
|
return systemGetSensorX() & 255;
|
||||||
|
case 0x8300:
|
||||||
|
return (systemGetSensorX() >> 8)|0x80;
|
||||||
|
case 0x8400:
|
||||||
|
return systemGetSensorY() & 255;
|
||||||
|
case 0x8500:
|
||||||
|
return systemGetSensorY() >> 8;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// default
|
||||||
|
default:
|
||||||
|
unreadable:
|
||||||
|
#ifdef DEV_VERSION
|
||||||
|
if(systemVerbose & VERBOSE_ILLEGAL_READ)
|
||||||
|
{
|
||||||
|
log("Illegal byte read: %08x at %08x\n", address, armMode ?
|
||||||
|
armNextPC - 4 : armNextPC - 2);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if(armState)
|
||||||
|
{
|
||||||
|
#if VM_USED
|
||||||
|
return CPUReadByteQuick(reg[15].I+(address & 3));
|
||||||
|
#else
|
||||||
|
return CPUReadByteQuickDef(reg[15].I+(address & 3));
|
||||||
|
#endif
|
||||||
|
//return VMRead8(reg[15].I+(address & 3));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
#if VM_USED
|
||||||
|
return CPUReadByteQuick(reg[15].I+(address & 1));
|
||||||
|
#else
|
||||||
|
return CPUReadByteQuickDef(reg[15].I+(address & 1));
|
||||||
|
#endif
|
||||||
|
//return VMRead8(reg[15].I+(address & 1));
|
||||||
|
}
|
||||||
|
// return 0xFF;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void CPUWriteMemory(u32 address, u32 value)
|
||||||
|
{
|
||||||
|
#ifdef DEV_VERSION
|
||||||
|
if(address & 3)
|
||||||
|
{
|
||||||
|
if(systemVerbose & VERBOSE_UNALIGNED_MEMORY)
|
||||||
|
{
|
||||||
|
log("Unaliagned word write: %08x to %08x from %08x\n",
|
||||||
|
value,
|
||||||
|
address,
|
||||||
|
armMode ? armNextPC - 4 : armNextPC - 2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
switch(address >> 24)
|
||||||
|
{
|
||||||
|
case 0x02:
|
||||||
|
#ifdef SDL
|
||||||
|
if(*((u32 *)&freezeWorkRAM[address & 0x3FFFC]))
|
||||||
|
cheatsWriteMemory((u32 *)&workRAM[address & 0x3FFFC],
|
||||||
|
value,
|
||||||
|
*((u32 *)&freezeWorkRAM[address & 0x3FFFC]));
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
WRITE32LE(((u32 *)&workRAM[address & 0x3FFFC]), value);
|
||||||
|
break;
|
||||||
|
case 0x03:
|
||||||
|
#ifdef SDL
|
||||||
|
if(*((u32 *)&freezeInternalRAM[address & 0x7ffc]))
|
||||||
|
cheatsWriteMemory((u32 *)&internalRAM[address & 0x7FFC],
|
||||||
|
value,
|
||||||
|
*((u32 *)&freezeInternalRAM[address & 0x7ffc]));
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
WRITE32LE(((u32 *)&internalRAM[address & 0x7ffC]), value);
|
||||||
|
break;
|
||||||
|
case 0x04:
|
||||||
|
CPUUpdateRegister((address & 0x3FC), value & 0xFFFF);
|
||||||
|
CPUUpdateRegister((address & 0x3FC) + 2, (value >> 16));
|
||||||
|
break;
|
||||||
|
case 0x05:
|
||||||
|
WRITE32LE(((u32 *)&paletteRAM[address & 0x3FC]), value);
|
||||||
|
break;
|
||||||
|
case 0x06:
|
||||||
|
if(address & 0x10000)
|
||||||
|
WRITE32LE(((u32 *)&vram[address & 0x17ffc]), value);
|
||||||
|
else
|
||||||
|
WRITE32LE(((u32 *)&vram[address & 0x1fffc]), value);
|
||||||
|
break;
|
||||||
|
case 0x07:
|
||||||
|
WRITE32LE(((u32 *)&oam[address & 0x3fc]), value);
|
||||||
|
break;
|
||||||
|
case 0x0D:
|
||||||
|
if(cpuEEPROMEnabled)
|
||||||
|
{
|
||||||
|
eepromWrite(address, value);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
goto unwritable;
|
||||||
|
case 0x0E:
|
||||||
|
if(!eepromInUse | cpuSramEnabled | cpuFlashEnabled)
|
||||||
|
{
|
||||||
|
(*cpuSaveGameFunc)(address, (u8)value);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
// default
|
||||||
|
default:
|
||||||
|
unwritable:
|
||||||
|
#ifdef DEV_VERSION
|
||||||
|
if(systemVerbose & VERBOSE_ILLEGAL_WRITE)
|
||||||
|
{
|
||||||
|
log("Illegal word write: %08x to %08x from %08x\n",
|
||||||
|
value,
|
||||||
|
address,
|
||||||
|
armMode ? armNextPC - 4 : armNextPC - 2);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif //VBA_GBAinline_H
|
@ -16,12 +16,13 @@
|
|||||||
// 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];
|
||||||
u32 line2[240];
|
u32 line2[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
1809
source/vba/Gfx.h
Normal file
File diff suppressed because it is too large
Load Diff
@ -1,6 +1,6 @@
|
|||||||
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
|
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
|
||||||
// Copyright (C) 1999-2003 Forgotten
|
// Copyright (C) 1999-2003 Forgotten
|
||||||
// Copyright (C) 2005 Forgotten and the VBA development team
|
// Copyright (C) 2004 Forgotten and the VBA development team
|
||||||
|
|
||||||
// This program is free software; you can redistribute it and/or modify
|
// This program is free software; you can redistribute it and/or modify
|
||||||
// it under the terms of the GNU General Public License as published by
|
// it under the terms of the GNU General Public License as published by
|
||||||
@ -16,12 +16,7 @@
|
|||||||
// along with this program; if not, write to the Free Software Foundation,
|
// along with this program; if not, write to the Free Software Foundation,
|
||||||
// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
#include "agb/GBA.h"
|
#include "GBA.h"
|
||||||
|
|
||||||
#ifdef BKPT_SUPPORT
|
|
||||||
int oldreg[17];
|
|
||||||
char oldbuffer[10];
|
|
||||||
#endif
|
|
||||||
|
|
||||||
reg_pair reg[45];
|
reg_pair reg[45];
|
||||||
memoryMap map[256];
|
memoryMap map[256];
|
||||||
@ -43,14 +38,13 @@ bool speedup = false;
|
|||||||
bool synchronize = true;
|
bool synchronize = true;
|
||||||
bool cpuDisableSfx = false;
|
bool cpuDisableSfx = false;
|
||||||
bool cpuIsMultiBoot = false;
|
bool cpuIsMultiBoot = false;
|
||||||
bool parseDebug = true;
|
bool parseDebug = false;
|
||||||
int layerSettings = 0xff00;
|
int layerSettings = 0xff00;
|
||||||
int layerEnable = 0xff00;
|
int layerEnable = 0xff00;
|
||||||
bool speedHack = false;
|
bool speedHack = false;
|
||||||
int cpuSaveType = 0;
|
int cpuSaveType = 0;
|
||||||
bool cheatsEnabled = true;
|
bool cpuEnhancedDetection = true;
|
||||||
bool mirroringEnable = false;
|
bool cheatsEnabled = false;
|
||||||
bool skipSaveGameBattery = false;
|
|
||||||
|
|
||||||
u8 *bios = NULL;
|
u8 *bios = NULL;
|
||||||
u8 *rom = NULL;
|
u8 *rom = NULL;
|
||||||
|
@ -1,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;
|
||||||
|
@ -16,34 +16,40 @@
|
|||||||
// 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 mode0RenderLine()
|
void mode0RenderLine()
|
||||||
{
|
{
|
||||||
u16 *palette = (u16 *)paletteRAM;
|
u16 *palette = (u16 *)paletteRAM;
|
||||||
|
|
||||||
if(DISPCNT & 0x80) {
|
if(DISPCNT & 0x80)
|
||||||
for(int x = 0; x < 240; x++) {
|
{
|
||||||
|
for(int x = 0; x < 240; x++)
|
||||||
|
{
|
||||||
lineMix[x] = 0x7fff;
|
lineMix[x] = 0x7fff;
|
||||||
}
|
}
|
||||||
return;
|
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)
|
||||||
|
{
|
||||||
gfxDrawTextScreen(BG2CNT, BG2HOFS, BG2VOFS, line2);
|
gfxDrawTextScreen(BG2CNT, BG2HOFS, BG2VOFS, line2);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(layerEnable & 0x0800) {
|
if(layerEnable & 0x0800)
|
||||||
|
{
|
||||||
gfxDrawTextScreen(BG3CNT, BG3HOFS, BG3VOFS, line3);
|
gfxDrawTextScreen(BG3CNT, BG3HOFS, BG3VOFS, line3);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -51,56 +57,67 @@ void mode0RenderLine()
|
|||||||
|
|
||||||
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;
|
u32 color = backdrop;
|
||||||
u8 top = 0x20;
|
u8 top = 0x20;
|
||||||
|
|
||||||
if(line0[x] < color) {
|
if(line0[x] < color)
|
||||||
|
{
|
||||||
color = line0[x];
|
color = line0[x];
|
||||||
top = 0x01;
|
top = 0x01;
|
||||||
}
|
}
|
||||||
|
|
||||||
if((u8)(line1[x]>>24) < (u8)(color >> 24)) {
|
if((u8)(line1[x]>>24) < (u8)(color >> 24))
|
||||||
|
{
|
||||||
color = line1[x];
|
color = line1[x];
|
||||||
top = 0x02;
|
top = 0x02;
|
||||||
}
|
}
|
||||||
|
|
||||||
if((u8)(line2[x]>>24) < (u8)(color >> 24)) {
|
if((u8)(line2[x]>>24) < (u8)(color >> 24))
|
||||||
|
{
|
||||||
color = line2[x];
|
color = line2[x];
|
||||||
top = 0x04;
|
top = 0x04;
|
||||||
}
|
}
|
||||||
|
|
||||||
if((u8)(line3[x]>>24) < (u8)(color >> 24)) {
|
if((u8)(line3[x]>>24) < (u8)(color >> 24))
|
||||||
|
{
|
||||||
color = line3[x];
|
color = line3[x];
|
||||||
top = 0x08;
|
top = 0x08;
|
||||||
}
|
}
|
||||||
|
|
||||||
if((u8)(lineOBJ[x]>>24) < (u8)(color >> 24)) {
|
if((u8)(lineOBJ[x]>>24) < (u8)(color >> 24))
|
||||||
|
{
|
||||||
color = lineOBJ[x];
|
color = lineOBJ[x];
|
||||||
top = 0x10;
|
top = 0x10;
|
||||||
}
|
}
|
||||||
|
|
||||||
if((top & 0x10) && (color & 0x00010000)) {
|
if((top & 0x10) && (color & 0x00010000))
|
||||||
|
{
|
||||||
// semi-transparent OBJ
|
// semi-transparent OBJ
|
||||||
u32 back = backdrop;
|
u32 back = backdrop;
|
||||||
u8 top2 = 0x20;
|
u8 top2 = 0x20;
|
||||||
|
|
||||||
if((u8)(line0[x]>>24) < (u8)(back >> 24)) {
|
if((u8)(line0[x]>>24) < (u8)(back >> 24))
|
||||||
|
{
|
||||||
back = line0[x];
|
back = line0[x];
|
||||||
top2 = 0x01;
|
top2 = 0x01;
|
||||||
}
|
}
|
||||||
|
|
||||||
if((u8)(line1[x]>>24) < (u8)(back >> 24)) {
|
if((u8)(line1[x]>>24) < (u8)(back >> 24))
|
||||||
|
{
|
||||||
back = line1[x];
|
back = line1[x];
|
||||||
top2 = 0x02;
|
top2 = 0x02;
|
||||||
}
|
}
|
||||||
|
|
||||||
if((u8)(line2[x]>>24) < (u8)(back >> 24)) {
|
if((u8)(line2[x]>>24) < (u8)(back >> 24))
|
||||||
|
{
|
||||||
back = line2[x];
|
back = line2[x];
|
||||||
top2 = 0x04;
|
top2 = 0x04;
|
||||||
}
|
}
|
||||||
|
|
||||||
if((u8)(line3[x]>>24) < (u8)(back >> 24)) {
|
if((u8)(line3[x]>>24) < (u8)(back >> 24))
|
||||||
|
{
|
||||||
back = line3[x];
|
back = line3[x];
|
||||||
top2 = 0x08;
|
top2 = 0x08;
|
||||||
}
|
}
|
||||||
@ -109,8 +126,10 @@ void mode0RenderLine()
|
|||||||
color = gfxAlphaBlend(color, back,
|
color = gfxAlphaBlend(color, back,
|
||||||
coeff[COLEV & 0x1F],
|
coeff[COLEV & 0x1F],
|
||||||
coeff[(COLEV >> 8) & 0x1F]);
|
coeff[(COLEV >> 8) & 0x1F]);
|
||||||
else {
|
else
|
||||||
switch((BLDMOD >> 6) & 3) {
|
{
|
||||||
|
switch((BLDMOD >> 6) & 3)
|
||||||
|
{
|
||||||
case 2:
|
case 2:
|
||||||
if(BLDMOD & top)
|
if(BLDMOD & top)
|
||||||
color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]);
|
color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]);
|
||||||
@ -131,26 +150,32 @@ void mode0RenderLineNoWindow()
|
|||||||
{
|
{
|
||||||
u16 *palette = (u16 *)paletteRAM;
|
u16 *palette = (u16 *)paletteRAM;
|
||||||
|
|
||||||
if(DISPCNT & 0x80) {
|
if(DISPCNT & 0x80)
|
||||||
for(int x = 0; x < 240; x++) {
|
{
|
||||||
|
for(int x = 0; x < 240; x++)
|
||||||
|
{
|
||||||
lineMix[x] = 0x7fff;
|
lineMix[x] = 0x7fff;
|
||||||
}
|
}
|
||||||
return;
|
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)
|
||||||
|
{
|
||||||
gfxDrawTextScreen(BG2CNT, BG2HOFS, BG2VOFS, line2);
|
gfxDrawTextScreen(BG2CNT, BG2HOFS, BG2VOFS, line2);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(layerEnable & 0x0800) {
|
if(layerEnable & 0x0800)
|
||||||
|
{
|
||||||
gfxDrawTextScreen(BG3CNT, BG3HOFS, BG3VOFS, line3);
|
gfxDrawTextScreen(BG3CNT, BG3HOFS, BG3VOFS, line3);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -160,74 +185,93 @@ void mode0RenderLineNoWindow()
|
|||||||
|
|
||||||
int effect = (BLDMOD >> 6) & 3;
|
int effect = (BLDMOD >> 6) & 3;
|
||||||
|
|
||||||
for(int x = 0; x < 240; x++) {
|
for(int x = 0; x < 240; x++)
|
||||||
|
{
|
||||||
u32 color = backdrop;
|
u32 color = backdrop;
|
||||||
u8 top = 0x20;
|
u8 top = 0x20;
|
||||||
|
|
||||||
if(line0[x] < color) {
|
if(line0[x] < color)
|
||||||
|
{
|
||||||
color = line0[x];
|
color = line0[x];
|
||||||
top = 0x01;
|
top = 0x01;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(line1[x] < (color & 0xFF000000)) {
|
if(line1[x] < (color & 0xFF000000))
|
||||||
|
{
|
||||||
color = line1[x];
|
color = line1[x];
|
||||||
top = 0x02;
|
top = 0x02;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(line2[x] < (color & 0xFF000000)) {
|
if(line2[x] < (color & 0xFF000000))
|
||||||
|
{
|
||||||
color = line2[x];
|
color = line2[x];
|
||||||
top = 0x04;
|
top = 0x04;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(line3[x] < (color & 0xFF000000)) {
|
if(line3[x] < (color & 0xFF000000))
|
||||||
|
{
|
||||||
color = line3[x];
|
color = line3[x];
|
||||||
top = 0x08;
|
top = 0x08;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(lineOBJ[x] < (color & 0xFF000000)) {
|
if(lineOBJ[x] < (color & 0xFF000000))
|
||||||
|
{
|
||||||
color = lineOBJ[x];
|
color = lineOBJ[x];
|
||||||
top = 0x10;
|
top = 0x10;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!(color & 0x00010000)) {
|
if(!(color & 0x00010000))
|
||||||
switch(effect) {
|
{
|
||||||
|
switch(effect)
|
||||||
|
{
|
||||||
case 0:
|
case 0:
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
{
|
{
|
||||||
if(top & BLDMOD) {
|
if(top & BLDMOD)
|
||||||
|
{
|
||||||
u32 back = backdrop;
|
u32 back = backdrop;
|
||||||
u8 top2 = 0x20;
|
u8 top2 = 0x20;
|
||||||
if(line0[x] < back) {
|
if(line0[x] < back)
|
||||||
if(top != 0x01) {
|
{
|
||||||
|
if(top != 0x01)
|
||||||
|
{
|
||||||
back = line0[x];
|
back = line0[x];
|
||||||
top2 = 0x01;
|
top2 = 0x01;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(line1[x] < (back & 0xFF000000)) {
|
if(line1[x] < (back & 0xFF000000))
|
||||||
if(top != 0x02) {
|
{
|
||||||
|
if(top != 0x02)
|
||||||
|
{
|
||||||
back = line1[x];
|
back = line1[x];
|
||||||
top2 = 0x02;
|
top2 = 0x02;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(line2[x] < (back & 0xFF000000)) {
|
if(line2[x] < (back & 0xFF000000))
|
||||||
if(top != 0x04) {
|
{
|
||||||
|
if(top != 0x04)
|
||||||
|
{
|
||||||
back = line2[x];
|
back = line2[x];
|
||||||
top2 = 0x04;
|
top2 = 0x04;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(line3[x] < (back & 0xFF000000)) {
|
if(line3[x] < (back & 0xFF000000))
|
||||||
if(top != 0x08) {
|
{
|
||||||
|
if(top != 0x08)
|
||||||
|
{
|
||||||
back = line3[x];
|
back = line3[x];
|
||||||
top2 = 0x08;
|
top2 = 0x08;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(lineOBJ[x] < (back & 0xFF000000)) {
|
if(lineOBJ[x] < (back & 0xFF000000))
|
||||||
if(top != 0x10) {
|
{
|
||||||
|
if(top != 0x10)
|
||||||
|
{
|
||||||
back = lineOBJ[x];
|
back = lineOBJ[x];
|
||||||
top2 = 0x10;
|
top2 = 0x10;
|
||||||
}
|
}
|
||||||
@ -250,27 +294,33 @@ void mode0RenderLineNoWindow()
|
|||||||
color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]);
|
color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
// semi-transparent OBJ
|
// semi-transparent OBJ
|
||||||
u32 back = backdrop;
|
u32 back = backdrop;
|
||||||
u8 top2 = 0x20;
|
u8 top2 = 0x20;
|
||||||
|
|
||||||
if(line0[x] < back) {
|
if(line0[x] < back)
|
||||||
|
{
|
||||||
back = line0[x];
|
back = line0[x];
|
||||||
top2 = 0x01;
|
top2 = 0x01;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(line1[x] < (back & 0xFF000000)) {
|
if(line1[x] < (back & 0xFF000000))
|
||||||
|
{
|
||||||
back = line1[x];
|
back = line1[x];
|
||||||
top2 = 0x02;
|
top2 = 0x02;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(line2[x] < (back & 0xFF000000)) {
|
if(line2[x] < (back & 0xFF000000))
|
||||||
|
{
|
||||||
back = line2[x];
|
back = line2[x];
|
||||||
top2 = 0x04;
|
top2 = 0x04;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(line3[x] < (back & 0xFF000000)) {
|
if(line3[x] < (back & 0xFF000000))
|
||||||
|
{
|
||||||
back = line3[x];
|
back = line3[x];
|
||||||
top2 = 0x08;
|
top2 = 0x08;
|
||||||
}
|
}
|
||||||
@ -279,8 +329,10 @@ void mode0RenderLineNoWindow()
|
|||||||
color = gfxAlphaBlend(color, back,
|
color = gfxAlphaBlend(color, back,
|
||||||
coeff[COLEV & 0x1F],
|
coeff[COLEV & 0x1F],
|
||||||
coeff[(COLEV >> 8) & 0x1F]);
|
coeff[(COLEV >> 8) & 0x1F]);
|
||||||
else {
|
else
|
||||||
switch((BLDMOD >> 6) & 3) {
|
{
|
||||||
|
switch((BLDMOD >> 6) & 3)
|
||||||
|
{
|
||||||
case 2:
|
case 2:
|
||||||
if(BLDMOD & top)
|
if(BLDMOD & top)
|
||||||
color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]);
|
color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]);
|
||||||
@ -301,8 +353,10 @@ void mode0RenderLineAll()
|
|||||||
{
|
{
|
||||||
u16 *palette = (u16 *)paletteRAM;
|
u16 *palette = (u16 *)paletteRAM;
|
||||||
|
|
||||||
if(DISPCNT & 0x80) {
|
if(DISPCNT & 0x80)
|
||||||
for(int x = 0; x < 240; x++) {
|
{
|
||||||
|
for(int x = 0; x < 240; x++)
|
||||||
|
{
|
||||||
lineMix[x] = 0x7fff;
|
lineMix[x] = 0x7fff;
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
@ -311,7 +365,8 @@ void mode0RenderLineAll()
|
|||||||
bool inWindow0 = false;
|
bool inWindow0 = false;
|
||||||
bool inWindow1 = false;
|
bool inWindow1 = false;
|
||||||
|
|
||||||
if(layerEnable & 0x2000) {
|
if(layerEnable & 0x2000)
|
||||||
|
{
|
||||||
u8 v0 = WIN0V >> 8;
|
u8 v0 = WIN0V >> 8;
|
||||||
u8 v1 = WIN0V & 255;
|
u8 v1 = WIN0V & 255;
|
||||||
inWindow0 = ((v0 == v1) && (v0 >= 0xe8));
|
inWindow0 = ((v0 == v1) && (v0 >= 0xe8));
|
||||||
@ -320,7 +375,8 @@ void mode0RenderLineAll()
|
|||||||
else
|
else
|
||||||
inWindow0 |= (VCOUNT >= v0 || VCOUNT < v1);
|
inWindow0 |= (VCOUNT >= v0 || VCOUNT < v1);
|
||||||
}
|
}
|
||||||
if(layerEnable & 0x4000) {
|
if(layerEnable & 0x4000)
|
||||||
|
{
|
||||||
u8 v0 = WIN1V >> 8;
|
u8 v0 = WIN1V >> 8;
|
||||||
u8 v1 = WIN1V & 255;
|
u8 v1 = WIN1V & 255;
|
||||||
inWindow1 = ((v0 == v1) && (v0 >= 0xe8));
|
inWindow1 = ((v0 == v1) && (v0 >= 0xe8));
|
||||||
@ -330,19 +386,23 @@ void mode0RenderLineAll()
|
|||||||
inWindow1 |= (VCOUNT >= v0 || VCOUNT < v1);
|
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))
|
||||||
|
{
|
||||||
gfxDrawTextScreen(BG2CNT, BG2HOFS, BG2VOFS, line2);
|
gfxDrawTextScreen(BG2CNT, BG2HOFS, BG2VOFS, line2);
|
||||||
}
|
}
|
||||||
|
|
||||||
if((layerEnable & 0x0800)) {
|
if((layerEnable & 0x0800))
|
||||||
|
{
|
||||||
gfxDrawTextScreen(BG3CNT, BG3HOFS, BG3VOFS, line3);
|
gfxDrawTextScreen(BG3CNT, BG3HOFS, BG3VOFS, line3);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -355,132 +415,116 @@ void mode0RenderLineAll()
|
|||||||
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;
|
u32 color = backdrop;
|
||||||
u8 top = 0x20;
|
u8 top = 0x20;
|
||||||
u8 mask = outMask;
|
u8 mask = outMask;
|
||||||
|
|
||||||
if(!(lineOBJWin[x] & 0x80000000)) {
|
if(!(lineOBJWin[x] & 0x80000000))
|
||||||
|
{
|
||||||
mask = WINOUT >> 8;
|
mask = WINOUT >> 8;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(inWindow1) {
|
if(inWindow1)
|
||||||
|
{
|
||||||
if(gfxInWin1[x])
|
if(gfxInWin1[x])
|
||||||
mask = inWin1Mask;
|
mask = inWin1Mask;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(inWindow0) {
|
if(inWindow0)
|
||||||
if(gfxInWin0[x]) {
|
{
|
||||||
|
if(gfxInWin0[x])
|
||||||
|
{
|
||||||
mask = inWin0Mask;
|
mask = inWin0Mask;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if((mask & 1) && (line0[x] < color)) {
|
if((mask & 1) && (line0[x] < color))
|
||||||
|
{
|
||||||
color = line0[x];
|
color = line0[x];
|
||||||
top = 0x01;
|
top = 0x01;
|
||||||
}
|
}
|
||||||
|
|
||||||
if((mask & 2) && ((u8)(line1[x]>>24) < (u8)(color >> 24))) {
|
if((mask & 2) && ((u8)(line1[x]>>24) < (u8)(color >> 24)))
|
||||||
|
{
|
||||||
color = line1[x];
|
color = line1[x];
|
||||||
top = 0x02;
|
top = 0x02;
|
||||||
}
|
}
|
||||||
|
|
||||||
if((mask & 4) && ((u8)(line2[x]>>24) < (u8)(color >> 24))) {
|
if((mask & 4) && ((u8)(line2[x]>>24) < (u8)(color >> 24)))
|
||||||
|
{
|
||||||
color = line2[x];
|
color = line2[x];
|
||||||
top = 0x04;
|
top = 0x04;
|
||||||
}
|
}
|
||||||
|
|
||||||
if((mask & 8) && ((u8)(line3[x]>>24) < (u8)(color >> 24))) {
|
if((mask & 8) && ((u8)(line3[x]>>24) < (u8)(color >> 24)))
|
||||||
|
{
|
||||||
color = line3[x];
|
color = line3[x];
|
||||||
top = 0x08;
|
top = 0x08;
|
||||||
}
|
}
|
||||||
|
|
||||||
if((mask & 16) && ((u8)(lineOBJ[x]>>24) < (u8)(color >> 24))) {
|
if((mask & 16) && ((u8)(lineOBJ[x]>>24) < (u8)(color >> 24)))
|
||||||
|
{
|
||||||
color = lineOBJ[x];
|
color = lineOBJ[x];
|
||||||
top = 0x10;
|
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((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 in the window
|
// special FX on in the window
|
||||||
switch((BLDMOD >> 6) & 3) {
|
if(mask & 32)
|
||||||
|
{
|
||||||
|
if(!(color & 0x00010000))
|
||||||
|
{
|
||||||
|
switch((BLDMOD >> 6) & 3)
|
||||||
|
{
|
||||||
case 0:
|
case 0:
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
{
|
{
|
||||||
if(top & BLDMOD) {
|
if(top & BLDMOD)
|
||||||
|
{
|
||||||
u32 back = backdrop;
|
u32 back = backdrop;
|
||||||
u8 top2 = 0x20;
|
u8 top2 = 0x20;
|
||||||
if((mask & 1) && (u8)(line0[x]>>24) < (u8)(back >> 24)) {
|
if((mask & 1) && (u8)(line0[x]>>24) < (u8)(back >> 24))
|
||||||
if(top != 0x01) {
|
{
|
||||||
|
if(top != 0x01)
|
||||||
|
{
|
||||||
back = line0[x];
|
back = line0[x];
|
||||||
top2 = 0x01;
|
top2 = 0x01;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if((mask & 2) && (u8)(line1[x]>>24) < (u8)(back >> 24)) {
|
if((mask & 2) && (u8)(line1[x]>>24) < (u8)(back >> 24))
|
||||||
if(top != 0x02) {
|
{
|
||||||
|
if(top != 0x02)
|
||||||
|
{
|
||||||
back = line1[x];
|
back = line1[x];
|
||||||
top2 = 0x02;
|
top2 = 0x02;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if((mask & 4) && (u8)(line2[x]>>24) < (u8)(back >> 24)) {
|
if((mask & 4) && (u8)(line2[x]>>24) < (u8)(back >> 24))
|
||||||
if(top != 0x04) {
|
{
|
||||||
|
if(top != 0x04)
|
||||||
|
{
|
||||||
back = line2[x];
|
back = line2[x];
|
||||||
top2 = 0x04;
|
top2 = 0x04;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if((mask & 8) && (u8)(line3[x]>>24) < (u8)(back >> 24)) {
|
if((mask & 8) && (u8)(line3[x]>>24) < (u8)(back >> 24))
|
||||||
if(top != 0x08) {
|
{
|
||||||
|
if(top != 0x08)
|
||||||
|
{
|
||||||
back = line3[x];
|
back = line3[x];
|
||||||
top2 = 0x08;
|
top2 = 0x08;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if((mask & 16) && (u8)(lineOBJ[x]>>24) < (u8)(back >> 24)) {
|
if((mask & 16) && (u8)(lineOBJ[x]>>24) < (u8)(back >> 24))
|
||||||
if(top != 0x10) {
|
{
|
||||||
|
if(top != 0x10)
|
||||||
|
{
|
||||||
back = lineOBJ[x];
|
back = lineOBJ[x];
|
||||||
top2 = 0x10;
|
top2 = 0x10;
|
||||||
}
|
}
|
||||||
@ -503,6 +547,105 @@ void mode0RenderLineAll()
|
|||||||
break;
|
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((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 & 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((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;
|
lineMix[x] = color;
|
||||||
}
|
}
|
||||||
|
@ -16,31 +16,36 @@
|
|||||||
// 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++) {
|
{
|
||||||
|
for(int x = 0; x < 240; x++)
|
||||||
|
{
|
||||||
lineMix[x] = 0x7fff;
|
lineMix[x] = 0x7fff;
|
||||||
}
|
}
|
||||||
gfxLastVCOUNT = VCOUNT;
|
gfxLastVCOUNT = VCOUNT;
|
||||||
return;
|
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;
|
int changed = gfxBG2Changed;
|
||||||
if(gfxLastVCOUNT > VCOUNT)
|
if(gfxLastVCOUNT > VCOUNT)
|
||||||
changed = 3;
|
changed = 3;
|
||||||
@ -53,46 +58,55 @@ void mode1RenderLine()
|
|||||||
|
|
||||||
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;
|
u32 color = backdrop;
|
||||||
u8 top = 0x20;
|
u8 top = 0x20;
|
||||||
|
|
||||||
if(line0[x] < color) {
|
if(line0[x] < color)
|
||||||
|
{
|
||||||
color = line0[x];
|
color = line0[x];
|
||||||
top = 0x01;
|
top = 0x01;
|
||||||
}
|
}
|
||||||
|
|
||||||
if((u8)(line1[x]>>24) < (u8)(color >> 24)) {
|
if((u8)(line1[x]>>24) < (u8)(color >> 24))
|
||||||
|
{
|
||||||
color = line1[x];
|
color = line1[x];
|
||||||
top = 0x02;
|
top = 0x02;
|
||||||
}
|
}
|
||||||
|
|
||||||
if((u8)(line2[x]>>24) < (u8)(color >> 24)) {
|
if((u8)(line2[x]>>24) < (u8)(color >> 24))
|
||||||
|
{
|
||||||
color = line2[x];
|
color = line2[x];
|
||||||
top = 0x04;
|
top = 0x04;
|
||||||
}
|
}
|
||||||
|
|
||||||
if((u8)(lineOBJ[x]>>24) < (u8)(color >> 24)) {
|
if((u8)(lineOBJ[x]>>24) < (u8)(color >> 24))
|
||||||
|
{
|
||||||
color = lineOBJ[x];
|
color = lineOBJ[x];
|
||||||
top = 0x10;
|
top = 0x10;
|
||||||
}
|
}
|
||||||
|
|
||||||
if((top & 0x10) && (color & 0x00010000)) {
|
if((top & 0x10) && (color & 0x00010000))
|
||||||
|
{
|
||||||
// semi-transparent OBJ
|
// semi-transparent OBJ
|
||||||
u32 back = backdrop;
|
u32 back = backdrop;
|
||||||
u8 top2 = 0x20;
|
u8 top2 = 0x20;
|
||||||
|
|
||||||
if((u8)(line0[x]>>24) < (u8)(back >> 24)) {
|
if((u8)(line0[x]>>24) < (u8)(back >> 24))
|
||||||
|
{
|
||||||
back = line0[x];
|
back = line0[x];
|
||||||
top2 = 0x01;
|
top2 = 0x01;
|
||||||
}
|
}
|
||||||
|
|
||||||
if((u8)(line1[x]>>24) < (u8)(back >> 24)) {
|
if((u8)(line1[x]>>24) < (u8)(back >> 24))
|
||||||
|
{
|
||||||
back = line1[x];
|
back = line1[x];
|
||||||
top2 = 0x02;
|
top2 = 0x02;
|
||||||
}
|
}
|
||||||
|
|
||||||
if((u8)(line2[x]>>24) < (u8)(back >> 24)) {
|
if((u8)(line2[x]>>24) < (u8)(back >> 24))
|
||||||
|
{
|
||||||
back = line2[x];
|
back = line2[x];
|
||||||
top2 = 0x04;
|
top2 = 0x04;
|
||||||
}
|
}
|
||||||
@ -101,8 +115,10 @@ void mode1RenderLine()
|
|||||||
color = gfxAlphaBlend(color, back,
|
color = gfxAlphaBlend(color, back,
|
||||||
coeff[COLEV & 0x1F],
|
coeff[COLEV & 0x1F],
|
||||||
coeff[(COLEV >> 8) & 0x1F]);
|
coeff[(COLEV >> 8) & 0x1F]);
|
||||||
else {
|
else
|
||||||
switch((BLDMOD >> 6) & 3) {
|
{
|
||||||
|
switch((BLDMOD >> 6) & 3)
|
||||||
|
{
|
||||||
case 2:
|
case 2:
|
||||||
if(BLDMOD & top)
|
if(BLDMOD & top)
|
||||||
color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]);
|
color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]);
|
||||||
@ -125,24 +141,29 @@ void mode1RenderLineNoWindow()
|
|||||||
{
|
{
|
||||||
u16 *palette = (u16 *)paletteRAM;
|
u16 *palette = (u16 *)paletteRAM;
|
||||||
|
|
||||||
if(DISPCNT & 0x80) {
|
if(DISPCNT & 0x80)
|
||||||
for(int x = 0; x < 240; x++) {
|
{
|
||||||
|
for(int x = 0; x < 240; x++)
|
||||||
|
{
|
||||||
lineMix[x] = 0x7fff;
|
lineMix[x] = 0x7fff;
|
||||||
}
|
}
|
||||||
gfxLastVCOUNT = VCOUNT;
|
gfxLastVCOUNT = VCOUNT;
|
||||||
return;
|
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;
|
int changed = gfxBG2Changed;
|
||||||
if(gfxLastVCOUNT > VCOUNT)
|
if(gfxLastVCOUNT > VCOUNT)
|
||||||
changed = 3;
|
changed = 3;
|
||||||
@ -155,62 +176,78 @@ void mode1RenderLineNoWindow()
|
|||||||
|
|
||||||
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;
|
u32 color = backdrop;
|
||||||
u8 top = 0x20;
|
u8 top = 0x20;
|
||||||
|
|
||||||
if(line0[x] < color) {
|
if(line0[x] < color)
|
||||||
|
{
|
||||||
color = line0[x];
|
color = line0[x];
|
||||||
top = 0x01;
|
top = 0x01;
|
||||||
}
|
}
|
||||||
|
|
||||||
if((u8)(line1[x]>>24) < (u8)(color >> 24)) {
|
if((u8)(line1[x]>>24) < (u8)(color >> 24))
|
||||||
|
{
|
||||||
color = line1[x];
|
color = line1[x];
|
||||||
top = 0x02;
|
top = 0x02;
|
||||||
}
|
}
|
||||||
|
|
||||||
if((u8)(line2[x]>>24) < (u8)(color >> 24)) {
|
if((u8)(line2[x]>>24) < (u8)(color >> 24))
|
||||||
|
{
|
||||||
color = line2[x];
|
color = line2[x];
|
||||||
top = 0x04;
|
top = 0x04;
|
||||||
}
|
}
|
||||||
|
|
||||||
if((u8)(lineOBJ[x]>>24) < (u8)(color >> 24)) {
|
if((u8)(lineOBJ[x]>>24) < (u8)(color >> 24))
|
||||||
|
{
|
||||||
color = lineOBJ[x];
|
color = lineOBJ[x];
|
||||||
top = 0x10;
|
top = 0x10;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!(color & 0x00010000)) {
|
if(!(color & 0x00010000))
|
||||||
switch((BLDMOD >> 6) & 3) {
|
{
|
||||||
|
switch((BLDMOD >> 6) & 3)
|
||||||
|
{
|
||||||
case 0:
|
case 0:
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
{
|
{
|
||||||
if(top & BLDMOD) {
|
if(top & BLDMOD)
|
||||||
|
{
|
||||||
u32 back = backdrop;
|
u32 back = backdrop;
|
||||||
u8 top2 = 0x20;
|
u8 top2 = 0x20;
|
||||||
if((u8)(line0[x]>>24) < (u8)(back >> 24)) {
|
if((u8)(line0[x]>>24) < (u8)(back >> 24))
|
||||||
if(top != 0x01) {
|
{
|
||||||
|
if(top != 0x01)
|
||||||
|
{
|
||||||
back = line0[x];
|
back = line0[x];
|
||||||
top2 = 0x01;
|
top2 = 0x01;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if((u8)(line1[x]>>24) < (u8)(back >> 24)) {
|
if((u8)(line1[x]>>24) < (u8)(back >> 24))
|
||||||
if(top != 0x02) {
|
{
|
||||||
|
if(top != 0x02)
|
||||||
|
{
|
||||||
back = line1[x];
|
back = line1[x];
|
||||||
top2 = 0x02;
|
top2 = 0x02;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if((u8)(line2[x]>>24) < (u8)(back >> 24)) {
|
if((u8)(line2[x]>>24) < (u8)(back >> 24))
|
||||||
if(top != 0x04) {
|
{
|
||||||
|
if(top != 0x04)
|
||||||
|
{
|
||||||
back = line2[x];
|
back = line2[x];
|
||||||
top2 = 0x04;
|
top2 = 0x04;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if((u8)(lineOBJ[x]>>24) < (u8)(back >> 24)) {
|
if((u8)(lineOBJ[x]>>24) < (u8)(back >> 24))
|
||||||
if(top != 0x10) {
|
{
|
||||||
|
if(top != 0x10)
|
||||||
|
{
|
||||||
back = lineOBJ[x];
|
back = lineOBJ[x];
|
||||||
top2 = 0x10;
|
top2 = 0x10;
|
||||||
}
|
}
|
||||||
@ -232,22 +269,27 @@ void mode1RenderLineNoWindow()
|
|||||||
color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]);
|
color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
// semi-transparent OBJ
|
// semi-transparent OBJ
|
||||||
u32 back = backdrop;
|
u32 back = backdrop;
|
||||||
u8 top2 = 0x20;
|
u8 top2 = 0x20;
|
||||||
|
|
||||||
if((u8)(line0[x]>>24) < (u8)(back >> 24)) {
|
if((u8)(line0[x]>>24) < (u8)(back >> 24))
|
||||||
|
{
|
||||||
back = line0[x];
|
back = line0[x];
|
||||||
top2 = 0x01;
|
top2 = 0x01;
|
||||||
}
|
}
|
||||||
|
|
||||||
if((u8)(line1[x]>>24) < (u8)(back >> 24)) {
|
if((u8)(line1[x]>>24) < (u8)(back >> 24))
|
||||||
|
{
|
||||||
back = line1[x];
|
back = line1[x];
|
||||||
top2 = 0x02;
|
top2 = 0x02;
|
||||||
}
|
}
|
||||||
|
|
||||||
if((u8)(line2[x]>>24) < (u8)(back >> 24)) {
|
if((u8)(line2[x]>>24) < (u8)(back >> 24))
|
||||||
|
{
|
||||||
back = line2[x];
|
back = line2[x];
|
||||||
top2 = 0x04;
|
top2 = 0x04;
|
||||||
}
|
}
|
||||||
@ -256,8 +298,10 @@ void mode1RenderLineNoWindow()
|
|||||||
color = gfxAlphaBlend(color, back,
|
color = gfxAlphaBlend(color, back,
|
||||||
coeff[COLEV & 0x1F],
|
coeff[COLEV & 0x1F],
|
||||||
coeff[(COLEV >> 8) & 0x1F]);
|
coeff[(COLEV >> 8) & 0x1F]);
|
||||||
else {
|
else
|
||||||
switch((BLDMOD >> 6) & 3) {
|
{
|
||||||
|
switch((BLDMOD >> 6) & 3)
|
||||||
|
{
|
||||||
case 2:
|
case 2:
|
||||||
if(BLDMOD & top)
|
if(BLDMOD & top)
|
||||||
color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]);
|
color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]);
|
||||||
@ -280,8 +324,10 @@ void mode1RenderLineAll()
|
|||||||
{
|
{
|
||||||
u16 *palette = (u16 *)paletteRAM;
|
u16 *palette = (u16 *)paletteRAM;
|
||||||
|
|
||||||
if(DISPCNT & 0x80) {
|
if(DISPCNT & 0x80)
|
||||||
for(int x = 0; x < 240; x++) {
|
{
|
||||||
|
for(int x = 0; x < 240; x++)
|
||||||
|
{
|
||||||
lineMix[x] = 0x7fff;
|
lineMix[x] = 0x7fff;
|
||||||
}
|
}
|
||||||
gfxLastVCOUNT = VCOUNT;
|
gfxLastVCOUNT = VCOUNT;
|
||||||
@ -291,7 +337,8 @@ void mode1RenderLineAll()
|
|||||||
bool inWindow0 = false;
|
bool inWindow0 = false;
|
||||||
bool inWindow1 = false;
|
bool inWindow1 = false;
|
||||||
|
|
||||||
if(layerEnable & 0x2000) {
|
if(layerEnable & 0x2000)
|
||||||
|
{
|
||||||
u8 v0 = WIN0V >> 8;
|
u8 v0 = WIN0V >> 8;
|
||||||
u8 v1 = WIN0V & 255;
|
u8 v1 = WIN0V & 255;
|
||||||
inWindow0 = ((v0 == v1) && (v0 >= 0xe8));
|
inWindow0 = ((v0 == v1) && (v0 >= 0xe8));
|
||||||
@ -300,7 +347,8 @@ void mode1RenderLineAll()
|
|||||||
else
|
else
|
||||||
inWindow0 |= (VCOUNT >= v0 || VCOUNT < v1);
|
inWindow0 |= (VCOUNT >= v0 || VCOUNT < v1);
|
||||||
}
|
}
|
||||||
if(layerEnable & 0x4000) {
|
if(layerEnable & 0x4000)
|
||||||
|
{
|
||||||
u8 v0 = WIN1V >> 8;
|
u8 v0 = WIN1V >> 8;
|
||||||
u8 v1 = WIN1V & 255;
|
u8 v1 = WIN1V & 255;
|
||||||
inWindow1 = ((v0 == v1) && (v0 >= 0xe8));
|
inWindow1 = ((v0 == v1) && (v0 >= 0xe8));
|
||||||
@ -310,15 +358,18 @@ void mode1RenderLineAll()
|
|||||||
inWindow1 |= (VCOUNT >= v0 || VCOUNT < v1);
|
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;
|
int changed = gfxBG2Changed;
|
||||||
if(gfxLastVCOUNT > VCOUNT)
|
if(gfxLastVCOUNT > VCOUNT)
|
||||||
changed = 3;
|
changed = 3;
|
||||||
@ -336,116 +387,101 @@ 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;
|
u32 color = backdrop;
|
||||||
u8 top = 0x20;
|
u8 top = 0x20;
|
||||||
u8 mask = outMask;
|
u8 mask = outMask;
|
||||||
|
|
||||||
if(!(lineOBJWin[x] & 0x80000000)) {
|
if(!(lineOBJWin[x] & 0x80000000))
|
||||||
|
{
|
||||||
mask = WINOUT >> 8;
|
mask = WINOUT >> 8;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(inWindow1) {
|
if(inWindow1)
|
||||||
|
{
|
||||||
if(gfxInWin1[x])
|
if(gfxInWin1[x])
|
||||||
mask = inWin1Mask;
|
mask = inWin1Mask;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(inWindow0) {
|
if(inWindow0)
|
||||||
if(gfxInWin0[x]) {
|
{
|
||||||
|
if(gfxInWin0[x])
|
||||||
|
{
|
||||||
mask = inWin0Mask;
|
mask = inWin0Mask;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(line0[x] < color && (mask & 1)) {
|
if(line0[x] < color && (mask & 1))
|
||||||
|
{
|
||||||
color = line0[x];
|
color = line0[x];
|
||||||
top = 0x01;
|
top = 0x01;
|
||||||
}
|
}
|
||||||
|
|
||||||
if((u8)(line1[x]>>24) < (u8)(color >> 24) && (mask & 2)) {
|
if((u8)(line1[x]>>24) < (u8)(color >> 24) && (mask & 2))
|
||||||
|
{
|
||||||
color = line1[x];
|
color = line1[x];
|
||||||
top = 0x02;
|
top = 0x02;
|
||||||
}
|
}
|
||||||
|
|
||||||
if((u8)(line2[x]>>24) < (u8)(color >> 24) && (mask & 4)) {
|
if((u8)(line2[x]>>24) < (u8)(color >> 24) && (mask & 4))
|
||||||
|
{
|
||||||
color = line2[x];
|
color = line2[x];
|
||||||
top = 0x04;
|
top = 0x04;
|
||||||
}
|
}
|
||||||
|
|
||||||
if((u8)(lineOBJ[x]>>24) < (u8)(color >> 24) && (mask & 16)) {
|
if((u8)(lineOBJ[x]>>24) < (u8)(color >> 24) && (mask & 16))
|
||||||
|
{
|
||||||
color = lineOBJ[x];
|
color = lineOBJ[x];
|
||||||
top = 0x10;
|
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
|
// special FX on the window
|
||||||
switch((BLDMOD >> 6) & 3) {
|
if(mask & 32)
|
||||||
|
{
|
||||||
|
if(!(color & 0x00010000))
|
||||||
|
{
|
||||||
|
switch((BLDMOD >> 6) & 3)
|
||||||
|
{
|
||||||
case 0:
|
case 0:
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
{
|
{
|
||||||
if(top & BLDMOD) {
|
if(top & BLDMOD)
|
||||||
|
{
|
||||||
u32 back = backdrop;
|
u32 back = backdrop;
|
||||||
u8 top2 = 0x20;
|
u8 top2 = 0x20;
|
||||||
|
if((mask & 1) && (u8)(line0[x]>>24) < (u8)(back >> 24))
|
||||||
if((mask & 1) && (u8)(line0[x]>>24) < (u8)(back >> 24)) {
|
{
|
||||||
if(top != 0x01) {
|
if(top != 0x01)
|
||||||
|
{
|
||||||
back = line0[x];
|
back = line0[x];
|
||||||
top2 = 0x01;
|
top2 = 0x01;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if((mask & 2) && (u8)(line1[x]>>24) < (u8)(back >> 24)) {
|
if((mask & 2) && (u8)(line1[x]>>24) < (u8)(back >> 24))
|
||||||
if(top != 0x02) {
|
{
|
||||||
|
if(top != 0x02)
|
||||||
|
{
|
||||||
back = line1[x];
|
back = line1[x];
|
||||||
top2 = 0x02;
|
top2 = 0x02;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if((mask & 4) && (u8)(line2[x]>>24) < (u8)(back >> 24)) {
|
if((mask & 4) && (u8)(line2[x]>>24) < (u8)(back >> 24))
|
||||||
if(top != 0x04) {
|
{
|
||||||
|
if(top != 0x04)
|
||||||
|
{
|
||||||
back = line2[x];
|
back = line2[x];
|
||||||
top2 = 0x04;
|
top2 = 0x04;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if((mask & 16) && (u8)(lineOBJ[x]>>24) < (u8)(back >> 24)) {
|
if((mask & 16) && (u8)(lineOBJ[x]>>24) < (u8)(back >> 24))
|
||||||
if(top != 0x10) {
|
{
|
||||||
|
if(top != 0x10)
|
||||||
|
{
|
||||||
back = lineOBJ[x];
|
back = lineOBJ[x];
|
||||||
top2 = 0x10;
|
top2 = 0x10;
|
||||||
}
|
}
|
||||||
@ -468,6 +504,93 @@ void mode1RenderLineAll()
|
|||||||
break;
|
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;
|
lineMix[x] = color;
|
||||||
}
|
}
|
||||||
|
@ -16,23 +16,26 @@
|
|||||||
// 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++) {
|
{
|
||||||
|
for(int x = 0; x < 240; x++)
|
||||||
|
{
|
||||||
lineMix[x] = 0x7fff;
|
lineMix[x] = 0x7fff;
|
||||||
}
|
}
|
||||||
gfxLastVCOUNT = VCOUNT;
|
gfxLastVCOUNT = VCOUNT;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(layerEnable & 0x0400) {
|
if(layerEnable & 0x0400)
|
||||||
|
{
|
||||||
int changed = gfxBG2Changed;
|
int changed = gfxBG2Changed;
|
||||||
if(gfxLastVCOUNT > VCOUNT)
|
if(gfxLastVCOUNT > VCOUNT)
|
||||||
changed = 3;
|
changed = 3;
|
||||||
@ -42,7 +45,8 @@ void mode2RenderLine()
|
|||||||
changed, line2);
|
changed, line2);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(layerEnable & 0x0800) {
|
if(layerEnable & 0x0800)
|
||||||
|
{
|
||||||
int changed = gfxBG3Changed;
|
int changed = gfxBG3Changed;
|
||||||
if(gfxLastVCOUNT > VCOUNT)
|
if(gfxLastVCOUNT > VCOUNT)
|
||||||
changed = 3;
|
changed = 3;
|
||||||
@ -56,37 +60,44 @@ void mode2RenderLine()
|
|||||||
|
|
||||||
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;
|
u32 color = backdrop;
|
||||||
u8 top = 0x20;
|
u8 top = 0x20;
|
||||||
|
|
||||||
|
|
||||||
if((u8)(line2[x]>>24) < (u8)(color >> 24)) {
|
if((u8)(line2[x]>>24) < (u8)(color >> 24))
|
||||||
|
{
|
||||||
color = line2[x];
|
color = line2[x];
|
||||||
top = 0x04;
|
top = 0x04;
|
||||||
}
|
}
|
||||||
|
|
||||||
if((u8)(line3[x]>>24) < (u8)(color >> 24)) {
|
if((u8)(line3[x]>>24) < (u8)(color >> 24))
|
||||||
|
{
|
||||||
color = line3[x];
|
color = line3[x];
|
||||||
top = 0x08;
|
top = 0x08;
|
||||||
}
|
}
|
||||||
|
|
||||||
if((u8)(lineOBJ[x]>>24) < (u8)(color >> 24)) {
|
if((u8)(lineOBJ[x]>>24) < (u8)(color >> 24))
|
||||||
|
{
|
||||||
color = lineOBJ[x];
|
color = lineOBJ[x];
|
||||||
top = 0x10;
|
top = 0x10;
|
||||||
}
|
}
|
||||||
|
|
||||||
if((top & 0x10) && (color & 0x00010000)) {
|
if((top & 0x10) && (color & 0x00010000))
|
||||||
|
{
|
||||||
// semi-transparent OBJ
|
// semi-transparent OBJ
|
||||||
u32 back = backdrop;
|
u32 back = backdrop;
|
||||||
u8 top2 = 0x20;
|
u8 top2 = 0x20;
|
||||||
|
|
||||||
if((u8)(line2[x]>>24) < (u8)(back >> 24)) {
|
if((u8)(line2[x]>>24) < (u8)(back >> 24))
|
||||||
|
{
|
||||||
back = line2[x];
|
back = line2[x];
|
||||||
top2 = 0x04;
|
top2 = 0x04;
|
||||||
}
|
}
|
||||||
|
|
||||||
if((u8)(line3[x]>>24) < (u8)(back >> 24)) {
|
if((u8)(line3[x]>>24) < (u8)(back >> 24))
|
||||||
|
{
|
||||||
back = line3[x];
|
back = line3[x];
|
||||||
top2 = 0x08;
|
top2 = 0x08;
|
||||||
}
|
}
|
||||||
@ -95,8 +106,10 @@ void mode2RenderLine()
|
|||||||
color = gfxAlphaBlend(color, back,
|
color = gfxAlphaBlend(color, back,
|
||||||
coeff[COLEV & 0x1F],
|
coeff[COLEV & 0x1F],
|
||||||
coeff[(COLEV >> 8) & 0x1F]);
|
coeff[(COLEV >> 8) & 0x1F]);
|
||||||
else {
|
else
|
||||||
switch((BLDMOD >> 6) & 3) {
|
{
|
||||||
|
switch((BLDMOD >> 6) & 3)
|
||||||
|
{
|
||||||
case 2:
|
case 2:
|
||||||
if(BLDMOD & top)
|
if(BLDMOD & top)
|
||||||
color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]);
|
color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]);
|
||||||
@ -120,15 +133,18 @@ void mode2RenderLineNoWindow()
|
|||||||
{
|
{
|
||||||
u16 *palette = (u16 *)paletteRAM;
|
u16 *palette = (u16 *)paletteRAM;
|
||||||
|
|
||||||
if(DISPCNT & 0x80) {
|
if(DISPCNT & 0x80)
|
||||||
for(int x = 0; x < 240; x++) {
|
{
|
||||||
|
for(int x = 0; x < 240; x++)
|
||||||
|
{
|
||||||
lineMix[x] = 0x7fff;
|
lineMix[x] = 0x7fff;
|
||||||
}
|
}
|
||||||
gfxLastVCOUNT = VCOUNT;
|
gfxLastVCOUNT = VCOUNT;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(layerEnable & 0x0400) {
|
if(layerEnable & 0x0400)
|
||||||
|
{
|
||||||
int changed = gfxBG2Changed;
|
int changed = gfxBG2Changed;
|
||||||
if(gfxLastVCOUNT > VCOUNT)
|
if(gfxLastVCOUNT > VCOUNT)
|
||||||
changed = 3;
|
changed = 3;
|
||||||
@ -138,7 +154,8 @@ void mode2RenderLineNoWindow()
|
|||||||
changed, line2);
|
changed, line2);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(layerEnable & 0x0800) {
|
if(layerEnable & 0x0800)
|
||||||
|
{
|
||||||
int changed = gfxBG3Changed;
|
int changed = gfxBG3Changed;
|
||||||
if(gfxLastVCOUNT > VCOUNT)
|
if(gfxLastVCOUNT > VCOUNT)
|
||||||
changed = 3;
|
changed = 3;
|
||||||
@ -152,52 +169,65 @@ void mode2RenderLineNoWindow()
|
|||||||
|
|
||||||
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;
|
u32 color = backdrop;
|
||||||
u8 top = 0x20;
|
u8 top = 0x20;
|
||||||
|
|
||||||
|
|
||||||
if((u8)(line2[x]>>24) < (u8)(color >> 24)) {
|
if((u8)(line2[x]>>24) < (u8)(color >> 24))
|
||||||
|
{
|
||||||
color = line2[x];
|
color = line2[x];
|
||||||
top = 0x04;
|
top = 0x04;
|
||||||
}
|
}
|
||||||
|
|
||||||
if((u8)(line3[x]>>24) < (u8)(color >> 24)) {
|
if((u8)(line3[x]>>24) < (u8)(color >> 24))
|
||||||
|
{
|
||||||
color = line3[x];
|
color = line3[x];
|
||||||
top = 0x08;
|
top = 0x08;
|
||||||
}
|
}
|
||||||
|
|
||||||
if((u8)(lineOBJ[x]>>24) < (u8)(color >> 24)) {
|
if((u8)(lineOBJ[x]>>24) < (u8)(color >> 24))
|
||||||
|
{
|
||||||
color = lineOBJ[x];
|
color = lineOBJ[x];
|
||||||
top = 0x10;
|
top = 0x10;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!(color & 0x00010000)) {
|
if(!(color & 0x00010000))
|
||||||
switch((BLDMOD >> 6) & 3) {
|
{
|
||||||
|
switch((BLDMOD >> 6) & 3)
|
||||||
|
{
|
||||||
case 0:
|
case 0:
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
{
|
{
|
||||||
if(top & BLDMOD) {
|
if(top & BLDMOD)
|
||||||
|
{
|
||||||
u32 back = backdrop;
|
u32 back = backdrop;
|
||||||
u8 top2 = 0x20;
|
u8 top2 = 0x20;
|
||||||
|
|
||||||
if((u8)(line2[x]>>24) < (u8)(back >> 24)) {
|
if((u8)(line2[x]>>24) < (u8)(back >> 24))
|
||||||
if(top != 0x04) {
|
{
|
||||||
|
if(top != 0x04)
|
||||||
|
{
|
||||||
back = line2[x];
|
back = line2[x];
|
||||||
top2 = 0x04;
|
top2 = 0x04;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if((u8)(line3[x]>>24) < (u8)(back >> 24)) {
|
if((u8)(line3[x]>>24) < (u8)(back >> 24))
|
||||||
if(top != 0x08) {
|
{
|
||||||
|
if(top != 0x08)
|
||||||
|
{
|
||||||
back = line3[x];
|
back = line3[x];
|
||||||
top2 = 0x08;
|
top2 = 0x08;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if((u8)(lineOBJ[x]>>24) < (u8)(back >> 24)) {
|
if((u8)(lineOBJ[x]>>24) < (u8)(back >> 24))
|
||||||
if(top != 0x10) {
|
{
|
||||||
|
if(top != 0x10)
|
||||||
|
{
|
||||||
back = lineOBJ[x];
|
back = lineOBJ[x];
|
||||||
top2 = 0x10;
|
top2 = 0x10;
|
||||||
}
|
}
|
||||||
@ -219,17 +249,21 @@ void mode2RenderLineNoWindow()
|
|||||||
color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]);
|
color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
// semi-transparent OBJ
|
// semi-transparent OBJ
|
||||||
u32 back = backdrop;
|
u32 back = backdrop;
|
||||||
u8 top2 = 0x20;
|
u8 top2 = 0x20;
|
||||||
|
|
||||||
if((u8)(line2[x]>>24) < (u8)(back >> 24)) {
|
if((u8)(line2[x]>>24) < (u8)(back >> 24))
|
||||||
|
{
|
||||||
back = line2[x];
|
back = line2[x];
|
||||||
top2 = 0x04;
|
top2 = 0x04;
|
||||||
}
|
}
|
||||||
|
|
||||||
if((u8)(line3[x]>>24) < (u8)(back >> 24)) {
|
if((u8)(line3[x]>>24) < (u8)(back >> 24))
|
||||||
|
{
|
||||||
back = line3[x];
|
back = line3[x];
|
||||||
top2 = 0x08;
|
top2 = 0x08;
|
||||||
}
|
}
|
||||||
@ -238,8 +272,10 @@ void mode2RenderLineNoWindow()
|
|||||||
color = gfxAlphaBlend(color, back,
|
color = gfxAlphaBlend(color, back,
|
||||||
coeff[COLEV & 0x1F],
|
coeff[COLEV & 0x1F],
|
||||||
coeff[(COLEV >> 8) & 0x1F]);
|
coeff[(COLEV >> 8) & 0x1F]);
|
||||||
else {
|
else
|
||||||
switch((BLDMOD >> 6) & 3) {
|
{
|
||||||
|
switch((BLDMOD >> 6) & 3)
|
||||||
|
{
|
||||||
case 2:
|
case 2:
|
||||||
if(BLDMOD & top)
|
if(BLDMOD & top)
|
||||||
color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]);
|
color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]);
|
||||||
@ -263,8 +299,10 @@ void mode2RenderLineAll()
|
|||||||
{
|
{
|
||||||
u16 *palette = (u16 *)paletteRAM;
|
u16 *palette = (u16 *)paletteRAM;
|
||||||
|
|
||||||
if(DISPCNT & 0x80) {
|
if(DISPCNT & 0x80)
|
||||||
for(int x = 0; x < 240; x++) {
|
{
|
||||||
|
for(int x = 0; x < 240; x++)
|
||||||
|
{
|
||||||
lineMix[x] = 0x7fff;
|
lineMix[x] = 0x7fff;
|
||||||
}
|
}
|
||||||
gfxLastVCOUNT = VCOUNT;
|
gfxLastVCOUNT = VCOUNT;
|
||||||
@ -274,7 +312,8 @@ void mode2RenderLineAll()
|
|||||||
bool inWindow0 = false;
|
bool inWindow0 = false;
|
||||||
bool inWindow1 = false;
|
bool inWindow1 = false;
|
||||||
|
|
||||||
if(layerEnable & 0x2000) {
|
if(layerEnable & 0x2000)
|
||||||
|
{
|
||||||
u8 v0 = WIN0V >> 8;
|
u8 v0 = WIN0V >> 8;
|
||||||
u8 v1 = WIN0V & 255;
|
u8 v1 = WIN0V & 255;
|
||||||
inWindow0 = ((v0 == v1) && (v0 >= 0xe8));
|
inWindow0 = ((v0 == v1) && (v0 >= 0xe8));
|
||||||
@ -283,7 +322,8 @@ void mode2RenderLineAll()
|
|||||||
else
|
else
|
||||||
inWindow0 |= (VCOUNT >= v0 || VCOUNT < v1);
|
inWindow0 |= (VCOUNT >= v0 || VCOUNT < v1);
|
||||||
}
|
}
|
||||||
if(layerEnable & 0x4000) {
|
if(layerEnable & 0x4000)
|
||||||
|
{
|
||||||
u8 v0 = WIN1V >> 8;
|
u8 v0 = WIN1V >> 8;
|
||||||
u8 v1 = WIN1V & 255;
|
u8 v1 = WIN1V & 255;
|
||||||
inWindow1 = ((v0 == v1) && (v0 >= 0xe8));
|
inWindow1 = ((v0 == v1) && (v0 >= 0xe8));
|
||||||
@ -293,7 +333,8 @@ void mode2RenderLineAll()
|
|||||||
inWindow1 |= (VCOUNT >= v0 || VCOUNT < v1);
|
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;
|
||||||
@ -303,7 +344,8 @@ void mode2RenderLineAll()
|
|||||||
changed, line2);
|
changed, line2);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(layerEnable & 0x0800) {
|
if(layerEnable & 0x0800)
|
||||||
|
{
|
||||||
int changed = gfxBG3Changed;
|
int changed = gfxBG3Changed;
|
||||||
if(gfxLastVCOUNT > VCOUNT)
|
if(gfxLastVCOUNT > VCOUNT)
|
||||||
changed = 3;
|
changed = 3;
|
||||||
@ -322,99 +364,86 @@ 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;
|
u32 color = backdrop;
|
||||||
u8 top = 0x20;
|
u8 top = 0x20;
|
||||||
u8 mask = outMask;
|
u8 mask = outMask;
|
||||||
|
|
||||||
if(!(lineOBJWin[x] & 0x80000000)) {
|
if(!(lineOBJWin[x] & 0x80000000))
|
||||||
|
{
|
||||||
mask = WINOUT >> 8;
|
mask = WINOUT >> 8;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(inWindow1) {
|
if(inWindow1)
|
||||||
|
{
|
||||||
if(gfxInWin1[x])
|
if(gfxInWin1[x])
|
||||||
mask = inWin1Mask;
|
mask = inWin1Mask;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(inWindow0) {
|
if(inWindow0)
|
||||||
if(gfxInWin0[x]) {
|
{
|
||||||
|
if(gfxInWin0[x])
|
||||||
|
{
|
||||||
mask = inWin0Mask;
|
mask = inWin0Mask;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(line2[x] < color && (mask & 4)) {
|
if(line2[x] < color && (mask & 4))
|
||||||
|
{
|
||||||
color = line2[x];
|
color = line2[x];
|
||||||
top = 0x04;
|
top = 0x04;
|
||||||
}
|
}
|
||||||
|
|
||||||
if((u8)(line3[x]>>24) < (u8)(color >> 24) && (mask & 8)) {
|
if((u8)(line3[x]>>24) < (u8)(color >> 24) && (mask & 8))
|
||||||
|
{
|
||||||
color = line3[x];
|
color = line3[x];
|
||||||
top = 0x08;
|
top = 0x08;
|
||||||
}
|
}
|
||||||
|
|
||||||
if((u8)(lineOBJ[x]>>24) < (u8)(color >> 24) && (mask & 16)) {
|
if((u8)(lineOBJ[x]>>24) < (u8)(color >> 24) && (mask & 16))
|
||||||
|
{
|
||||||
color = lineOBJ[x];
|
color = lineOBJ[x];
|
||||||
top = 0x10;
|
top = 0x10;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(color & 0x00010000) {
|
if(mask & 32)
|
||||||
// semi-transparent OBJ
|
{
|
||||||
u32 back = backdrop;
|
if(!(color & 0x00010000))
|
||||||
u8 top2 = 0x20;
|
{
|
||||||
|
switch((BLDMOD >> 6) & 3)
|
||||||
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:
|
case 0:
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
{
|
{
|
||||||
if(top & BLDMOD) {
|
if(top & BLDMOD)
|
||||||
|
{
|
||||||
u32 back = backdrop;
|
u32 back = backdrop;
|
||||||
u8 top2 = 0x20;
|
u8 top2 = 0x20;
|
||||||
|
|
||||||
if((mask & 4) && line2[x] < back) {
|
if((mask & 4) && line2[x] < back)
|
||||||
if(top != 0x04) {
|
{
|
||||||
|
if(top != 0x04)
|
||||||
|
{
|
||||||
back = line2[x];
|
back = line2[x];
|
||||||
top2 = 0x04;
|
top2 = 0x04;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if((mask & 8) && (u8)(line3[x]>>24) < (u8)(back >> 24)) {
|
if((mask & 8) && (u8)(line3[x]>>24) < (u8)(back >> 24))
|
||||||
if(top != 0x08) {
|
{
|
||||||
|
if(top != 0x08)
|
||||||
|
{
|
||||||
back = line3[x];
|
back = line3[x];
|
||||||
top2 = 0x08;
|
top2 = 0x08;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if((mask & 16) && (u8)(lineOBJ[x]>>24) < (u8)(back >> 24)) {
|
if((mask & 16) && (u8)(lineOBJ[x]>>24) < (u8)(back >> 24))
|
||||||
if(top != 0x10) {
|
{
|
||||||
|
if(top != 0x10)
|
||||||
|
{
|
||||||
back = lineOBJ[x];
|
back = lineOBJ[x];
|
||||||
top2 = 0x10;
|
top2 = 0x10;
|
||||||
}
|
}
|
||||||
@ -437,6 +466,81 @@ void mode2RenderLineAll()
|
|||||||
break;
|
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;
|
lineMix[x] = color;
|
||||||
}
|
}
|
||||||
|
@ -16,23 +16,26 @@
|
|||||||
// 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++) {
|
{
|
||||||
|
for(int x = 0; x < 240; x++)
|
||||||
|
{
|
||||||
lineMix[x] = 0x7fff;
|
lineMix[x] = 0x7fff;
|
||||||
}
|
}
|
||||||
gfxLastVCOUNT = VCOUNT;
|
gfxLastVCOUNT = VCOUNT;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(layerEnable & 0x0400) {
|
if(layerEnable & 0x0400)
|
||||||
|
{
|
||||||
int changed = gfxBG2Changed;
|
int changed = gfxBG2Changed;
|
||||||
|
|
||||||
if(gfxLastVCOUNT > VCOUNT)
|
if(gfxLastVCOUNT > VCOUNT)
|
||||||
@ -49,26 +52,31 @@ void mode3RenderLine()
|
|||||||
|
|
||||||
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;
|
u32 color = background;
|
||||||
u8 top = 0x20;
|
u8 top = 0x20;
|
||||||
|
|
||||||
if(line2[x] < color) {
|
if(line2[x] < color)
|
||||||
|
{
|
||||||
color = line2[x];
|
color = line2[x];
|
||||||
top = 0x04;
|
top = 0x04;
|
||||||
}
|
}
|
||||||
|
|
||||||
if((u8)(lineOBJ[x]>>24) < (u8)(color >>24)) {
|
if((u8)(lineOBJ[x]>>24) < (u8)(color >>24))
|
||||||
|
{
|
||||||
color = lineOBJ[x];
|
color = lineOBJ[x];
|
||||||
top = 0x10;
|
top = 0x10;
|
||||||
}
|
}
|
||||||
|
|
||||||
if((top & 0x10) && (color & 0x00010000)) {
|
if((top & 0x10) && (color & 0x00010000))
|
||||||
|
{
|
||||||
// semi-transparent OBJ
|
// semi-transparent OBJ
|
||||||
u32 back = background;
|
u32 back = background;
|
||||||
u8 top2 = 0x20;
|
u8 top2 = 0x20;
|
||||||
|
|
||||||
if(line2[x] < back) {
|
if(line2[x] < back)
|
||||||
|
{
|
||||||
back = line2[x];
|
back = line2[x];
|
||||||
top2 = 0x04;
|
top2 = 0x04;
|
||||||
}
|
}
|
||||||
@ -77,8 +85,10 @@ void mode3RenderLine()
|
|||||||
color = gfxAlphaBlend(color, back,
|
color = gfxAlphaBlend(color, back,
|
||||||
coeff[COLEV & 0x1F],
|
coeff[COLEV & 0x1F],
|
||||||
coeff[(COLEV >> 8) & 0x1F]);
|
coeff[(COLEV >> 8) & 0x1F]);
|
||||||
else {
|
else
|
||||||
switch((BLDMOD >> 6) & 3) {
|
{
|
||||||
|
switch((BLDMOD >> 6) & 3)
|
||||||
|
{
|
||||||
case 2:
|
case 2:
|
||||||
if(BLDMOD & top)
|
if(BLDMOD & top)
|
||||||
color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]);
|
color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]);
|
||||||
@ -101,15 +111,18 @@ void mode3RenderLineNoWindow()
|
|||||||
{
|
{
|
||||||
u16 *palette = (u16 *)paletteRAM;
|
u16 *palette = (u16 *)paletteRAM;
|
||||||
|
|
||||||
if(DISPCNT & 0x80) {
|
if(DISPCNT & 0x80)
|
||||||
for(int x = 0; x < 240; x++) {
|
{
|
||||||
|
for(int x = 0; x < 240; x++)
|
||||||
|
{
|
||||||
lineMix[x] = 0x7fff;
|
lineMix[x] = 0x7fff;
|
||||||
}
|
}
|
||||||
gfxLastVCOUNT = VCOUNT;
|
gfxLastVCOUNT = VCOUNT;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(layerEnable & 0x0400) {
|
if(layerEnable & 0x0400)
|
||||||
|
{
|
||||||
int changed = gfxBG2Changed;
|
int changed = gfxBG2Changed;
|
||||||
|
|
||||||
if(gfxLastVCOUNT > VCOUNT)
|
if(gfxLastVCOUNT > VCOUNT)
|
||||||
@ -126,39 +139,49 @@ void mode3RenderLineNoWindow()
|
|||||||
|
|
||||||
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;
|
u32 color = background;
|
||||||
u8 top = 0x20;
|
u8 top = 0x20;
|
||||||
|
|
||||||
if(line2[x] < color) {
|
if(line2[x] < color)
|
||||||
|
{
|
||||||
color = line2[x];
|
color = line2[x];
|
||||||
top = 0x04;
|
top = 0x04;
|
||||||
}
|
}
|
||||||
|
|
||||||
if((u8)(lineOBJ[x]>>24) < (u8)(color >>24)) {
|
if((u8)(lineOBJ[x]>>24) < (u8)(color >>24))
|
||||||
|
{
|
||||||
color = lineOBJ[x];
|
color = lineOBJ[x];
|
||||||
top = 0x10;
|
top = 0x10;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!(color & 0x00010000)) {
|
if(!(color & 0x00010000))
|
||||||
switch((BLDMOD >> 6) & 3) {
|
{
|
||||||
|
switch((BLDMOD >> 6) & 3)
|
||||||
|
{
|
||||||
case 0:
|
case 0:
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
{
|
{
|
||||||
if(top & BLDMOD) {
|
if(top & BLDMOD)
|
||||||
|
{
|
||||||
u32 back = background;
|
u32 back = background;
|
||||||
u8 top2 = 0x20;
|
u8 top2 = 0x20;
|
||||||
|
|
||||||
if(line2[x] < back) {
|
if(line2[x] < back)
|
||||||
if(top != 0x04) {
|
{
|
||||||
|
if(top != 0x04)
|
||||||
|
{
|
||||||
back = line2[x];
|
back = line2[x];
|
||||||
top2 = 0x04;
|
top2 = 0x04;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if((u8)(lineOBJ[x]>>24) < (u8)(back >> 24)) {
|
if((u8)(lineOBJ[x]>>24) < (u8)(back >> 24))
|
||||||
if(top != 0x10) {
|
{
|
||||||
|
if(top != 0x10)
|
||||||
|
{
|
||||||
back = lineOBJ[x];
|
back = lineOBJ[x];
|
||||||
top2 = 0x10;
|
top2 = 0x10;
|
||||||
}
|
}
|
||||||
@ -181,12 +204,15 @@ void mode3RenderLineNoWindow()
|
|||||||
color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]);
|
color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
// semi-transparent OBJ
|
// semi-transparent OBJ
|
||||||
u32 back = background;
|
u32 back = background;
|
||||||
u8 top2 = 0x20;
|
u8 top2 = 0x20;
|
||||||
|
|
||||||
if(line2[x] < back) {
|
if(line2[x] < back)
|
||||||
|
{
|
||||||
back = line2[x];
|
back = line2[x];
|
||||||
top2 = 0x04;
|
top2 = 0x04;
|
||||||
}
|
}
|
||||||
@ -195,8 +221,10 @@ void mode3RenderLineNoWindow()
|
|||||||
color = gfxAlphaBlend(color, back,
|
color = gfxAlphaBlend(color, back,
|
||||||
coeff[COLEV & 0x1F],
|
coeff[COLEV & 0x1F],
|
||||||
coeff[(COLEV >> 8) & 0x1F]);
|
coeff[(COLEV >> 8) & 0x1F]);
|
||||||
else {
|
else
|
||||||
switch((BLDMOD >> 6) & 3) {
|
{
|
||||||
|
switch((BLDMOD >> 6) & 3)
|
||||||
|
{
|
||||||
case 2:
|
case 2:
|
||||||
if(BLDMOD & top)
|
if(BLDMOD & top)
|
||||||
color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]);
|
color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]);
|
||||||
@ -219,8 +247,10 @@ void mode3RenderLineAll()
|
|||||||
{
|
{
|
||||||
u16 *palette = (u16 *)paletteRAM;
|
u16 *palette = (u16 *)paletteRAM;
|
||||||
|
|
||||||
if(DISPCNT & 0x80) {
|
if(DISPCNT & 0x80)
|
||||||
for(int x = 0; x < 240; x++) {
|
{
|
||||||
|
for(int x = 0; x < 240; x++)
|
||||||
|
{
|
||||||
lineMix[x] = 0x7fff;
|
lineMix[x] = 0x7fff;
|
||||||
}
|
}
|
||||||
gfxLastVCOUNT = VCOUNT;
|
gfxLastVCOUNT = VCOUNT;
|
||||||
@ -230,7 +260,8 @@ void mode3RenderLineAll()
|
|||||||
bool inWindow0 = false;
|
bool inWindow0 = false;
|
||||||
bool inWindow1 = false;
|
bool inWindow1 = false;
|
||||||
|
|
||||||
if(layerEnable & 0x2000) {
|
if(layerEnable & 0x2000)
|
||||||
|
{
|
||||||
u8 v0 = WIN0V >> 8;
|
u8 v0 = WIN0V >> 8;
|
||||||
u8 v1 = WIN0V & 255;
|
u8 v1 = WIN0V & 255;
|
||||||
inWindow0 = ((v0 == v1) && (v0 >= 0xe8));
|
inWindow0 = ((v0 == v1) && (v0 >= 0xe8));
|
||||||
@ -239,7 +270,8 @@ void mode3RenderLineAll()
|
|||||||
else
|
else
|
||||||
inWindow0 |= (VCOUNT >= v0 || VCOUNT < v1);
|
inWindow0 |= (VCOUNT >= v0 || VCOUNT < v1);
|
||||||
}
|
}
|
||||||
if(layerEnable & 0x4000) {
|
if(layerEnable & 0x4000)
|
||||||
|
{
|
||||||
u8 v0 = WIN1V >> 8;
|
u8 v0 = WIN1V >> 8;
|
||||||
u8 v1 = WIN1V & 255;
|
u8 v1 = WIN1V & 255;
|
||||||
inWindow1 = ((v0 == v1) && (v0 >= 0xe8));
|
inWindow1 = ((v0 == v1) && (v0 >= 0xe8));
|
||||||
@ -249,7 +281,8 @@ void mode3RenderLineAll()
|
|||||||
inWindow1 |= (VCOUNT >= v0 || VCOUNT < v1);
|
inWindow1 |= (VCOUNT >= v0 || VCOUNT < v1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(layerEnable & 0x0400) {
|
if(layerEnable & 0x0400)
|
||||||
|
{
|
||||||
int changed = gfxBG2Changed;
|
int changed = gfxBG2Changed;
|
||||||
|
|
||||||
if(gfxLastVCOUNT > VCOUNT)
|
if(gfxLastVCOUNT > VCOUNT)
|
||||||
@ -271,81 +304,71 @@ 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;
|
u32 color = background;
|
||||||
u8 top = 0x20;
|
u8 top = 0x20;
|
||||||
u8 mask = outMask;
|
u8 mask = outMask;
|
||||||
|
|
||||||
if(!(lineOBJWin[x] & 0x80000000)) {
|
if(!(lineOBJWin[x] & 0x80000000))
|
||||||
|
{
|
||||||
mask = WINOUT >> 8;
|
mask = WINOUT >> 8;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(inWindow1) {
|
if(inWindow1)
|
||||||
|
{
|
||||||
if(gfxInWin1[x])
|
if(gfxInWin1[x])
|
||||||
mask = inWin1Mask;
|
mask = inWin1Mask;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(inWindow0) {
|
if(inWindow0)
|
||||||
if(gfxInWin0[x]) {
|
{
|
||||||
|
if(gfxInWin0[x])
|
||||||
|
{
|
||||||
mask = inWin0Mask;
|
mask = inWin0Mask;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if((mask & 4) && (line2[x] < color)) {
|
if((mask & 4) && (line2[x] < color))
|
||||||
|
{
|
||||||
color = line2[x];
|
color = line2[x];
|
||||||
top = 0x04;
|
top = 0x04;
|
||||||
}
|
}
|
||||||
|
|
||||||
if((mask & 16) && ((u8)(lineOBJ[x]>>24) < (u8)(color >>24))) {
|
if((mask & 16) && ((u8)(lineOBJ[x]>>24) < (u8)(color >>24)))
|
||||||
|
{
|
||||||
color = lineOBJ[x];
|
color = lineOBJ[x];
|
||||||
top = 0x10;
|
top = 0x10;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(color & 0x00010000) {
|
if(mask & 32)
|
||||||
// semi-transparent OBJ
|
{
|
||||||
u32 back = background;
|
if(!(color & 0x00010000))
|
||||||
u8 top2 = 0x20;
|
{
|
||||||
|
switch((BLDMOD >> 6) & 3)
|
||||||
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:
|
case 0:
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
{
|
{
|
||||||
if(top & BLDMOD) {
|
if(top & BLDMOD)
|
||||||
|
{
|
||||||
u32 back = background;
|
u32 back = background;
|
||||||
u8 top2 = 0x20;
|
u8 top2 = 0x20;
|
||||||
|
|
||||||
if((mask & 4) && line2[x] < back) {
|
if((mask & 4) && line2[x] < back)
|
||||||
if(top != 0x04) {
|
{
|
||||||
|
if(top != 0x04)
|
||||||
|
{
|
||||||
back = line2[x];
|
back = line2[x];
|
||||||
top2 = 0x04;
|
top2 = 0x04;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if((mask & 16) && (u8)(lineOBJ[x]>>24) < (u8)(back >> 24)) {
|
if((mask & 16) && (u8)(lineOBJ[x]>>24) < (u8)(back >> 24))
|
||||||
if(top != 0x10) {
|
{
|
||||||
|
if(top != 0x10)
|
||||||
|
{
|
||||||
back = lineOBJ[x];
|
back = lineOBJ[x];
|
||||||
top2 = 0x10;
|
top2 = 0x10;
|
||||||
}
|
}
|
||||||
@ -369,6 +392,69 @@ void mode3RenderLineAll()
|
|||||||
break;
|
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;
|
lineMix[x] = color;
|
||||||
}
|
}
|
||||||
|
@ -16,23 +16,26 @@
|
|||||||
// 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++) {
|
{
|
||||||
|
for(int x = 0; x < 240; x++)
|
||||||
|
{
|
||||||
lineMix[x] = 0x7fff;
|
lineMix[x] = 0x7fff;
|
||||||
}
|
}
|
||||||
gfxLastVCOUNT = VCOUNT;
|
gfxLastVCOUNT = VCOUNT;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(layerEnable & 0x400) {
|
if(layerEnable & 0x400)
|
||||||
|
{
|
||||||
int changed = gfxBG2Changed;
|
int changed = gfxBG2Changed;
|
||||||
|
|
||||||
if(gfxLastVCOUNT > VCOUNT)
|
if(gfxLastVCOUNT > VCOUNT)
|
||||||
@ -48,26 +51,31 @@ void mode4RenderLine()
|
|||||||
|
|
||||||
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;
|
u32 color = backdrop;
|
||||||
u8 top = 0x20;
|
u8 top = 0x20;
|
||||||
|
|
||||||
if(line2[x] < color) {
|
if(line2[x] < color)
|
||||||
|
{
|
||||||
color = line2[x];
|
color = line2[x];
|
||||||
top = 0x04;
|
top = 0x04;
|
||||||
}
|
}
|
||||||
|
|
||||||
if((u8)(lineOBJ[x]>>24) < (u8)(color >> 24)) {
|
if((u8)(lineOBJ[x]>>24) < (u8)(color >> 24))
|
||||||
|
{
|
||||||
color = lineOBJ[x];
|
color = lineOBJ[x];
|
||||||
top = 0x10;
|
top = 0x10;
|
||||||
}
|
}
|
||||||
|
|
||||||
if((top & 0x10) && (color & 0x00010000)) {
|
if((top & 0x10) && (color & 0x00010000))
|
||||||
|
{
|
||||||
// semi-transparent OBJ
|
// semi-transparent OBJ
|
||||||
u32 back = backdrop;
|
u32 back = backdrop;
|
||||||
u8 top2 = 0x20;
|
u8 top2 = 0x20;
|
||||||
|
|
||||||
if(line2[x] < back) {
|
if(line2[x] < back)
|
||||||
|
{
|
||||||
back = line2[x];
|
back = line2[x];
|
||||||
top2 = 0x04;
|
top2 = 0x04;
|
||||||
}
|
}
|
||||||
@ -76,8 +84,10 @@ void mode4RenderLine()
|
|||||||
color = gfxAlphaBlend(color, back,
|
color = gfxAlphaBlend(color, back,
|
||||||
coeff[COLEV & 0x1F],
|
coeff[COLEV & 0x1F],
|
||||||
coeff[(COLEV >> 8) & 0x1F]);
|
coeff[(COLEV >> 8) & 0x1F]);
|
||||||
else {
|
else
|
||||||
switch((BLDMOD >> 6) & 3) {
|
{
|
||||||
|
switch((BLDMOD >> 6) & 3)
|
||||||
|
{
|
||||||
case 2:
|
case 2:
|
||||||
if(BLDMOD & top)
|
if(BLDMOD & top)
|
||||||
color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]);
|
color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]);
|
||||||
@ -100,15 +110,18 @@ void mode4RenderLineNoWindow()
|
|||||||
{
|
{
|
||||||
u16 *palette = (u16 *)paletteRAM;
|
u16 *palette = (u16 *)paletteRAM;
|
||||||
|
|
||||||
if(DISPCNT & 0x0080) {
|
if(DISPCNT & 0x0080)
|
||||||
for(int x = 0; x < 240; x++) {
|
{
|
||||||
|
for(int x = 0; x < 240; x++)
|
||||||
|
{
|
||||||
lineMix[x] = 0x7fff;
|
lineMix[x] = 0x7fff;
|
||||||
}
|
}
|
||||||
gfxLastVCOUNT = VCOUNT;
|
gfxLastVCOUNT = VCOUNT;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(layerEnable & 0x400) {
|
if(layerEnable & 0x400)
|
||||||
|
{
|
||||||
int changed = gfxBG2Changed;
|
int changed = gfxBG2Changed;
|
||||||
|
|
||||||
if(gfxLastVCOUNT > VCOUNT)
|
if(gfxLastVCOUNT > VCOUNT)
|
||||||
@ -124,39 +137,49 @@ void mode4RenderLineNoWindow()
|
|||||||
|
|
||||||
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;
|
u32 color = backdrop;
|
||||||
u8 top = 0x20;
|
u8 top = 0x20;
|
||||||
|
|
||||||
if(line2[x] < color) {
|
if(line2[x] < color)
|
||||||
|
{
|
||||||
color = line2[x];
|
color = line2[x];
|
||||||
top = 0x04;
|
top = 0x04;
|
||||||
}
|
}
|
||||||
|
|
||||||
if((u8)(lineOBJ[x]>>24) < (u8)(color >> 24)) {
|
if((u8)(lineOBJ[x]>>24) < (u8)(color >> 24))
|
||||||
|
{
|
||||||
color = lineOBJ[x];
|
color = lineOBJ[x];
|
||||||
top = 0x10;
|
top = 0x10;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!(color & 0x00010000)) {
|
if(!(color & 0x00010000))
|
||||||
switch((BLDMOD >> 6) & 3) {
|
{
|
||||||
|
switch((BLDMOD >> 6) & 3)
|
||||||
|
{
|
||||||
case 0:
|
case 0:
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
{
|
{
|
||||||
if(top & BLDMOD) {
|
if(top & BLDMOD)
|
||||||
|
{
|
||||||
u32 back = backdrop;
|
u32 back = backdrop;
|
||||||
u8 top2 = 0x20;
|
u8 top2 = 0x20;
|
||||||
|
|
||||||
if(line2[x] < back) {
|
if(line2[x] < back)
|
||||||
if(top != 0x04) {
|
{
|
||||||
|
if(top != 0x04)
|
||||||
|
{
|
||||||
back = line2[x];
|
back = line2[x];
|
||||||
top2 = 0x04;
|
top2 = 0x04;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if((u8)(lineOBJ[x]>>24) < (u8)(back >> 24)) {
|
if((u8)(lineOBJ[x]>>24) < (u8)(back >> 24))
|
||||||
if(top != 0x10) {
|
{
|
||||||
|
if(top != 0x10)
|
||||||
|
{
|
||||||
back = lineOBJ[x];
|
back = lineOBJ[x];
|
||||||
top2 = 0x10;
|
top2 = 0x10;
|
||||||
}
|
}
|
||||||
@ -179,12 +202,15 @@ void mode4RenderLineNoWindow()
|
|||||||
color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]);
|
color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
// semi-transparent OBJ
|
// semi-transparent OBJ
|
||||||
u32 back = backdrop;
|
u32 back = backdrop;
|
||||||
u8 top2 = 0x20;
|
u8 top2 = 0x20;
|
||||||
|
|
||||||
if(line2[x] < back) {
|
if(line2[x] < back)
|
||||||
|
{
|
||||||
back = line2[x];
|
back = line2[x];
|
||||||
top2 = 0x04;
|
top2 = 0x04;
|
||||||
}
|
}
|
||||||
@ -193,8 +219,10 @@ void mode4RenderLineNoWindow()
|
|||||||
color = gfxAlphaBlend(color, back,
|
color = gfxAlphaBlend(color, back,
|
||||||
coeff[COLEV & 0x1F],
|
coeff[COLEV & 0x1F],
|
||||||
coeff[(COLEV >> 8) & 0x1F]);
|
coeff[(COLEV >> 8) & 0x1F]);
|
||||||
else {
|
else
|
||||||
switch((BLDMOD >> 6) & 3) {
|
{
|
||||||
|
switch((BLDMOD >> 6) & 3)
|
||||||
|
{
|
||||||
case 2:
|
case 2:
|
||||||
if(BLDMOD & top)
|
if(BLDMOD & top)
|
||||||
color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]);
|
color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]);
|
||||||
@ -217,8 +245,10 @@ void mode4RenderLineAll()
|
|||||||
{
|
{
|
||||||
u16 *palette = (u16 *)paletteRAM;
|
u16 *palette = (u16 *)paletteRAM;
|
||||||
|
|
||||||
if(DISPCNT & 0x0080) {
|
if(DISPCNT & 0x0080)
|
||||||
for(int x = 0; x < 240; x++) {
|
{
|
||||||
|
for(int x = 0; x < 240; x++)
|
||||||
|
{
|
||||||
lineMix[x] = 0x7fff;
|
lineMix[x] = 0x7fff;
|
||||||
}
|
}
|
||||||
gfxLastVCOUNT = VCOUNT;
|
gfxLastVCOUNT = VCOUNT;
|
||||||
@ -228,7 +258,8 @@ void mode4RenderLineAll()
|
|||||||
bool inWindow0 = false;
|
bool inWindow0 = false;
|
||||||
bool inWindow1 = false;
|
bool inWindow1 = false;
|
||||||
|
|
||||||
if(layerEnable & 0x2000) {
|
if(layerEnable & 0x2000)
|
||||||
|
{
|
||||||
u8 v0 = WIN0V >> 8;
|
u8 v0 = WIN0V >> 8;
|
||||||
u8 v1 = WIN0V & 255;
|
u8 v1 = WIN0V & 255;
|
||||||
inWindow0 = ((v0 == v1) && (v0 >= 0xe8));
|
inWindow0 = ((v0 == v1) && (v0 >= 0xe8));
|
||||||
@ -237,7 +268,8 @@ void mode4RenderLineAll()
|
|||||||
else
|
else
|
||||||
inWindow0 |= (VCOUNT >= v0 || VCOUNT < v1);
|
inWindow0 |= (VCOUNT >= v0 || VCOUNT < v1);
|
||||||
}
|
}
|
||||||
if(layerEnable & 0x4000) {
|
if(layerEnable & 0x4000)
|
||||||
|
{
|
||||||
u8 v0 = WIN1V >> 8;
|
u8 v0 = WIN1V >> 8;
|
||||||
u8 v1 = WIN1V & 255;
|
u8 v1 = WIN1V & 255;
|
||||||
inWindow1 = ((v0 == v1) && (v0 >= 0xe8));
|
inWindow1 = ((v0 == v1) && (v0 >= 0xe8));
|
||||||
@ -247,7 +279,8 @@ void mode4RenderLineAll()
|
|||||||
inWindow1 |= (VCOUNT >= v0 || VCOUNT < v1);
|
inWindow1 |= (VCOUNT >= v0 || VCOUNT < v1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(layerEnable & 0x400) {
|
if(layerEnable & 0x400)
|
||||||
|
{
|
||||||
int changed = gfxBG2Changed;
|
int changed = gfxBG2Changed;
|
||||||
|
|
||||||
if(gfxLastVCOUNT > VCOUNT)
|
if(gfxLastVCOUNT > VCOUNT)
|
||||||
@ -268,81 +301,71 @@ 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;
|
u32 color = backdrop;
|
||||||
u8 top = 0x20;
|
u8 top = 0x20;
|
||||||
u8 mask = outMask;
|
u8 mask = outMask;
|
||||||
|
|
||||||
if(!(lineOBJWin[x] & 0x80000000)) {
|
if(!(lineOBJWin[x] & 0x80000000))
|
||||||
|
{
|
||||||
mask = WINOUT >> 8;
|
mask = WINOUT >> 8;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(inWindow1) {
|
if(inWindow1)
|
||||||
|
{
|
||||||
if(gfxInWin1[x])
|
if(gfxInWin1[x])
|
||||||
mask = inWin1Mask;
|
mask = inWin1Mask;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(inWindow0) {
|
if(inWindow0)
|
||||||
if(gfxInWin0[x]) {
|
{
|
||||||
|
if(gfxInWin0[x])
|
||||||
|
{
|
||||||
mask = inWin0Mask;
|
mask = inWin0Mask;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if((mask & 4) && (line2[x] < color)) {
|
if((mask & 4) && (line2[x] < color))
|
||||||
|
{
|
||||||
color = line2[x];
|
color = line2[x];
|
||||||
top = 0x04;
|
top = 0x04;
|
||||||
}
|
}
|
||||||
|
|
||||||
if((mask & 16) && ((u8)(lineOBJ[x]>>24) < (u8)(color >>24))) {
|
if((mask & 16) && ((u8)(lineOBJ[x]>>24) < (u8)(color >>24)))
|
||||||
|
{
|
||||||
color = lineOBJ[x];
|
color = lineOBJ[x];
|
||||||
top = 0x10;
|
top = 0x10;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(color & 0x00010000) {
|
if(mask & 32)
|
||||||
// semi-transparent OBJ
|
{
|
||||||
u32 back = backdrop;
|
if(!(color & 0x00010000))
|
||||||
u8 top2 = 0x20;
|
{
|
||||||
|
switch((BLDMOD >> 6) & 3)
|
||||||
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:
|
case 0:
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
{
|
{
|
||||||
if(top & BLDMOD) {
|
if(top & BLDMOD)
|
||||||
|
{
|
||||||
u32 back = backdrop;
|
u32 back = backdrop;
|
||||||
u8 top2 = 0x20;
|
u8 top2 = 0x20;
|
||||||
|
|
||||||
if((mask & 4) && line2[x] < back) {
|
if((mask & 4) && line2[x] < back)
|
||||||
if(top != 0x04) {
|
{
|
||||||
|
if(top != 0x04)
|
||||||
|
{
|
||||||
back = line2[x];
|
back = line2[x];
|
||||||
top2 = 0x04;
|
top2 = 0x04;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if((mask & 16) && (u8)(lineOBJ[x]>>24) < (u8)(back >> 24)) {
|
if((mask & 16) && (u8)(lineOBJ[x]>>24) < (u8)(back >> 24))
|
||||||
if(top != 0x10) {
|
{
|
||||||
|
if(top != 0x10)
|
||||||
|
{
|
||||||
back = lineOBJ[x];
|
back = lineOBJ[x];
|
||||||
top2 = 0x10;
|
top2 = 0x10;
|
||||||
}
|
}
|
||||||
@ -366,6 +389,69 @@ void mode4RenderLineAll()
|
|||||||
break;
|
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;
|
lineMix[x] = color;
|
||||||
}
|
}
|
||||||
|
@ -16,14 +16,16 @@
|
|||||||
// 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++) {
|
{
|
||||||
|
for(int x = 0; x < 240; x++)
|
||||||
|
{
|
||||||
lineMix[x] = 0x7fff;
|
lineMix[x] = 0x7fff;
|
||||||
}
|
}
|
||||||
gfxLastVCOUNT = VCOUNT;
|
gfxLastVCOUNT = VCOUNT;
|
||||||
@ -32,7 +34,8 @@ void mode5RenderLine()
|
|||||||
|
|
||||||
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)
|
||||||
@ -49,26 +52,31 @@ void mode5RenderLine()
|
|||||||
|
|
||||||
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;
|
u32 color = background;
|
||||||
u8 top = 0x20;
|
u8 top = 0x20;
|
||||||
|
|
||||||
if(line2[x] < color) {
|
if(line2[x] < color)
|
||||||
|
{
|
||||||
color = line2[x];
|
color = line2[x];
|
||||||
top = 0x04;
|
top = 0x04;
|
||||||
}
|
}
|
||||||
|
|
||||||
if((u8)(lineOBJ[x]>>24) < (u8)(color >>24)) {
|
if((u8)(lineOBJ[x]>>24) < (u8)(color >>24))
|
||||||
|
{
|
||||||
color = lineOBJ[x];
|
color = lineOBJ[x];
|
||||||
top = 0x10;
|
top = 0x10;
|
||||||
}
|
}
|
||||||
|
|
||||||
if((top & 0x10) && (color & 0x00010000)) {
|
if((top & 0x10) && (color & 0x00010000))
|
||||||
|
{
|
||||||
// semi-transparent OBJ
|
// semi-transparent OBJ
|
||||||
u32 back = background;
|
u32 back = background;
|
||||||
u8 top2 = 0x20;
|
u8 top2 = 0x20;
|
||||||
|
|
||||||
if(line2[x] < back) {
|
if(line2[x] < back)
|
||||||
|
{
|
||||||
back = line2[x];
|
back = line2[x];
|
||||||
top2 = 0x04;
|
top2 = 0x04;
|
||||||
}
|
}
|
||||||
@ -77,8 +85,10 @@ void mode5RenderLine()
|
|||||||
color = gfxAlphaBlend(color, back,
|
color = gfxAlphaBlend(color, back,
|
||||||
coeff[COLEV & 0x1F],
|
coeff[COLEV & 0x1F],
|
||||||
coeff[(COLEV >> 8) & 0x1F]);
|
coeff[(COLEV >> 8) & 0x1F]);
|
||||||
else {
|
else
|
||||||
switch((BLDMOD >> 6) & 3) {
|
{
|
||||||
|
switch((BLDMOD >> 6) & 3)
|
||||||
|
{
|
||||||
case 2:
|
case 2:
|
||||||
if(BLDMOD & top)
|
if(BLDMOD & top)
|
||||||
color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]);
|
color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]);
|
||||||
@ -99,8 +109,10 @@ void mode5RenderLine()
|
|||||||
|
|
||||||
void mode5RenderLineNoWindow()
|
void mode5RenderLineNoWindow()
|
||||||
{
|
{
|
||||||
if(DISPCNT & 0x0080) {
|
if(DISPCNT & 0x0080)
|
||||||
for(int x = 0; x < 240; x++) {
|
{
|
||||||
|
for(int x = 0; x < 240; x++)
|
||||||
|
{
|
||||||
lineMix[x] = 0x7fff;
|
lineMix[x] = 0x7fff;
|
||||||
}
|
}
|
||||||
gfxLastVCOUNT = VCOUNT;
|
gfxLastVCOUNT = VCOUNT;
|
||||||
@ -109,7 +121,8 @@ void mode5RenderLineNoWindow()
|
|||||||
|
|
||||||
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)
|
||||||
@ -126,39 +139,49 @@ void mode5RenderLineNoWindow()
|
|||||||
|
|
||||||
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;
|
u32 color = background;
|
||||||
u8 top = 0x20;
|
u8 top = 0x20;
|
||||||
|
|
||||||
if(line2[x] < color) {
|
if(line2[x] < color)
|
||||||
|
{
|
||||||
color = line2[x];
|
color = line2[x];
|
||||||
top = 0x04;
|
top = 0x04;
|
||||||
}
|
}
|
||||||
|
|
||||||
if((u8)(lineOBJ[x]>>24) < (u8)(color >>24)) {
|
if((u8)(lineOBJ[x]>>24) < (u8)(color >>24))
|
||||||
|
{
|
||||||
color = lineOBJ[x];
|
color = lineOBJ[x];
|
||||||
top = 0x10;
|
top = 0x10;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!(color & 0x00010000)) {
|
if(!(color & 0x00010000))
|
||||||
switch((BLDMOD >> 6) & 3) {
|
{
|
||||||
|
switch((BLDMOD >> 6) & 3)
|
||||||
|
{
|
||||||
case 0:
|
case 0:
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
{
|
{
|
||||||
if(top & BLDMOD) {
|
if(top & BLDMOD)
|
||||||
|
{
|
||||||
u32 back = background;
|
u32 back = background;
|
||||||
u8 top2 = 0x20;
|
u8 top2 = 0x20;
|
||||||
|
|
||||||
if(line2[x] < back) {
|
if(line2[x] < back)
|
||||||
if(top != 0x04) {
|
{
|
||||||
|
if(top != 0x04)
|
||||||
|
{
|
||||||
back = line2[x];
|
back = line2[x];
|
||||||
top2 = 0x04;
|
top2 = 0x04;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if((u8)(lineOBJ[x]>>24) < (u8)(back >> 24)) {
|
if((u8)(lineOBJ[x]>>24) < (u8)(back >> 24))
|
||||||
if(top != 0x10) {
|
{
|
||||||
|
if(top != 0x10)
|
||||||
|
{
|
||||||
back = lineOBJ[x];
|
back = lineOBJ[x];
|
||||||
top2 = 0x10;
|
top2 = 0x10;
|
||||||
}
|
}
|
||||||
@ -181,12 +204,15 @@ void mode5RenderLineNoWindow()
|
|||||||
color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]);
|
color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
// semi-transparent OBJ
|
// semi-transparent OBJ
|
||||||
u32 back = background;
|
u32 back = background;
|
||||||
u8 top2 = 0x20;
|
u8 top2 = 0x20;
|
||||||
|
|
||||||
if(line2[x] < back) {
|
if(line2[x] < back)
|
||||||
|
{
|
||||||
back = line2[x];
|
back = line2[x];
|
||||||
top2 = 0x04;
|
top2 = 0x04;
|
||||||
}
|
}
|
||||||
@ -195,8 +221,10 @@ void mode5RenderLineNoWindow()
|
|||||||
color = gfxAlphaBlend(color, back,
|
color = gfxAlphaBlend(color, back,
|
||||||
coeff[COLEV & 0x1F],
|
coeff[COLEV & 0x1F],
|
||||||
coeff[(COLEV >> 8) & 0x1F]);
|
coeff[(COLEV >> 8) & 0x1F]);
|
||||||
else {
|
else
|
||||||
switch((BLDMOD >> 6) & 3) {
|
{
|
||||||
|
switch((BLDMOD >> 6) & 3)
|
||||||
|
{
|
||||||
case 2:
|
case 2:
|
||||||
if(BLDMOD & top)
|
if(BLDMOD & top)
|
||||||
color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]);
|
color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]);
|
||||||
@ -217,8 +245,10 @@ void mode5RenderLineNoWindow()
|
|||||||
|
|
||||||
void mode5RenderLineAll()
|
void mode5RenderLineAll()
|
||||||
{
|
{
|
||||||
if(DISPCNT & 0x0080) {
|
if(DISPCNT & 0x0080)
|
||||||
for(int x = 0; x < 240; x++) {
|
{
|
||||||
|
for(int x = 0; x < 240; x++)
|
||||||
|
{
|
||||||
lineMix[x] = 0x7fff;
|
lineMix[x] = 0x7fff;
|
||||||
}
|
}
|
||||||
gfxLastVCOUNT = VCOUNT;
|
gfxLastVCOUNT = VCOUNT;
|
||||||
@ -227,7 +257,8 @@ void mode5RenderLineAll()
|
|||||||
|
|
||||||
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)
|
||||||
@ -246,7 +277,8 @@ 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 v0 = WIN0V >> 8;
|
||||||
u8 v1 = WIN0V & 255;
|
u8 v1 = WIN0V & 255;
|
||||||
inWindow0 = ((v0 == v1) && (v0 >= 0xe8));
|
inWindow0 = ((v0 == v1) && (v0 >= 0xe8));
|
||||||
@ -255,7 +287,8 @@ void mode5RenderLineAll()
|
|||||||
else
|
else
|
||||||
inWindow0 |= (VCOUNT >= v0 || VCOUNT < v1);
|
inWindow0 |= (VCOUNT >= v0 || VCOUNT < v1);
|
||||||
}
|
}
|
||||||
if(layerEnable & 0x4000) {
|
if(layerEnable & 0x4000)
|
||||||
|
{
|
||||||
u8 v0 = WIN1V >> 8;
|
u8 v0 = WIN1V >> 8;
|
||||||
u8 v1 = WIN1V & 255;
|
u8 v1 = WIN1V & 255;
|
||||||
inWindow1 = ((v0 == v1) && (v0 >= 0xe8));
|
inWindow1 = ((v0 == v1) && (v0 >= 0xe8));
|
||||||
@ -271,81 +304,71 @@ 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;
|
u32 color = background;
|
||||||
u8 top = 0x20;
|
u8 top = 0x20;
|
||||||
u8 mask = outMask;
|
u8 mask = outMask;
|
||||||
|
|
||||||
if(!(lineOBJWin[x] & 0x80000000)) {
|
if(!(lineOBJWin[x] & 0x80000000))
|
||||||
|
{
|
||||||
mask = WINOUT >> 8;
|
mask = WINOUT >> 8;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(inWindow1) {
|
if(inWindow1)
|
||||||
|
{
|
||||||
if(gfxInWin1[x])
|
if(gfxInWin1[x])
|
||||||
mask = inWin1Mask;
|
mask = inWin1Mask;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(inWindow0) {
|
if(inWindow0)
|
||||||
if(gfxInWin0[x]) {
|
{
|
||||||
|
if(gfxInWin0[x])
|
||||||
|
{
|
||||||
mask = inWin0Mask;
|
mask = inWin0Mask;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if((mask & 4) && (line2[x] < color)) {
|
if((mask & 4) && (line2[x] < color))
|
||||||
|
{
|
||||||
color = line2[x];
|
color = line2[x];
|
||||||
top = 0x04;
|
top = 0x04;
|
||||||
}
|
}
|
||||||
|
|
||||||
if((mask & 16) && ((u8)(lineOBJ[x]>>24) < (u8)(color >>24))) {
|
if((mask & 16) && ((u8)(lineOBJ[x]>>24) < (u8)(color >>24)))
|
||||||
|
{
|
||||||
color = lineOBJ[x];
|
color = lineOBJ[x];
|
||||||
top = 0x10;
|
top = 0x10;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(color & 0x00010000) {
|
if(mask & 32)
|
||||||
// semi-transparent OBJ
|
{
|
||||||
u32 back = background;
|
if(!(color & 0x00010000))
|
||||||
u8 top2 = 0x20;
|
{
|
||||||
|
switch((BLDMOD >> 6) & 3)
|
||||||
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:
|
case 0:
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
{
|
{
|
||||||
if(top & BLDMOD) {
|
if(top & BLDMOD)
|
||||||
|
{
|
||||||
u32 back = background;
|
u32 back = background;
|
||||||
u8 top2 = 0x20;
|
u8 top2 = 0x20;
|
||||||
|
|
||||||
if((mask & 4) && line2[x] < back) {
|
if((mask & 4) && line2[x] < back)
|
||||||
if(top != 0x04) {
|
{
|
||||||
|
if(top != 0x04)
|
||||||
|
{
|
||||||
back = line2[x];
|
back = line2[x];
|
||||||
top2 = 0x04;
|
top2 = 0x04;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if((mask & 16) && (u8)(lineOBJ[x]>>24) < (u8)(back >> 24)) {
|
if((mask & 16) && (u8)(lineOBJ[x]>>24) < (u8)(back >> 24))
|
||||||
if(top != 0x10) {
|
{
|
||||||
|
if(top != 0x10)
|
||||||
|
{
|
||||||
back = lineOBJ[x];
|
back = lineOBJ[x];
|
||||||
top2 = 0x10;
|
top2 = 0x10;
|
||||||
}
|
}
|
||||||
@ -369,6 +392,69 @@ void mode5RenderLineAll()
|
|||||||
break;
|
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;
|
lineMix[x] = color;
|
||||||
}
|
}
|
||||||
|
@ -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
|
|
||||||
|
@ -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) \
|
||||||
|
@ -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,7 +29,8 @@
|
|||||||
|
|
||||||
enum RTCSTATE { IDLE, COMMAND, DATA, READDATA };
|
enum RTCSTATE { IDLE, COMMAND, DATA, READDATA };
|
||||||
|
|
||||||
typedef struct {
|
typedef struct
|
||||||
|
{
|
||||||
u8 byte0;
|
u8 byte0;
|
||||||
u8 byte1;
|
u8 byte1;
|
||||||
u8 byte2;
|
u8 byte2;
|
||||||
@ -42,7 +43,8 @@ typedef struct {
|
|||||||
u8 reserved[12];
|
u8 reserved[12];
|
||||||
bool reserved2;
|
bool reserved2;
|
||||||
u32 reserved3;
|
u32 reserved3;
|
||||||
} RTCCLOCKDATA;
|
}
|
||||||
|
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;
|
||||||
break;
|
else if(address == 0x80000c4)
|
||||||
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,25 +90,37 @@ 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 ?
|
rtcClockData.byte2 = (u8)value; // enable ?
|
||||||
} else if(address == 0x80000c6) {
|
}
|
||||||
|
else if(address == 0x80000c6)
|
||||||
|
{
|
||||||
rtcClockData.byte1 = (u8)value; // read/write
|
rtcClockData.byte1 = (u8)value; // read/write
|
||||||
} else if(address == 0x80000c4) {
|
}
|
||||||
if(rtcClockData.byte2 & 1) {
|
else if(address == 0x80000c4)
|
||||||
if(rtcClockData.state == IDLE && rtcClockData.byte0 == 1 && value == 5) {
|
{
|
||||||
|
if(rtcClockData.byte2 & 1)
|
||||||
|
{
|
||||||
|
if(rtcClockData.state == IDLE && rtcClockData.byte0 == 1 && value == 5)
|
||||||
|
{
|
||||||
rtcClockData.state = COMMAND;
|
rtcClockData.state = COMMAND;
|
||||||
rtcClockData.bits = 0;
|
rtcClockData.bits = 0;
|
||||||
rtcClockData.command = 0;
|
rtcClockData.command = 0;
|
||||||
} else if(!(rtcClockData.byte0 & 1) && (value & 1)) { // bit transfer
|
}
|
||||||
|
else if(!(rtcClockData.byte0 & 1) && (value & 1))
|
||||||
|
{ // bit transfer
|
||||||
rtcClockData.byte0 = (u8)value;
|
rtcClockData.byte0 = (u8)value;
|
||||||
switch(rtcClockData.state) {
|
switch(rtcClockData.state)
|
||||||
|
{
|
||||||
case COMMAND:
|
case COMMAND:
|
||||||
rtcClockData.command |= ((value & 2) >> 1) << (7-rtcClockData.bits);
|
rtcClockData.command |= ((value & 2) >> 1) << (7-rtcClockData.bits);
|
||||||
rtcClockData.bits++;
|
rtcClockData.bits++;
|
||||||
if(rtcClockData.bits == 8) {
|
if(rtcClockData.bits == 8)
|
||||||
|
{
|
||||||
rtcClockData.bits = 0;
|
rtcClockData.bits = 0;
|
||||||
switch(rtcClockData.command) {
|
switch(rtcClockData.command)
|
||||||
|
{
|
||||||
case 0x60:
|
case 0x60:
|
||||||
// not sure what this command does but it doesn't take parameters
|
// not sure what this command does but it doesn't take parameters
|
||||||
// maybe it is a reset or stop
|
// maybe it is a reset or stop
|
||||||
@ -127,8 +137,6 @@ bool rtcWrite(u32 address, u16 value)
|
|||||||
rtcClockData.data[0] = 0x40;
|
rtcClockData.data[0] = 0x40;
|
||||||
rtcClockData.state = DATA;
|
rtcClockData.state = DATA;
|
||||||
break;
|
break;
|
||||||
case 0x64:
|
|
||||||
break;
|
|
||||||
case 0x65:
|
case 0x65:
|
||||||
{
|
{
|
||||||
struct tm *newtime;
|
struct tm *newtime;
|
||||||
@ -141,7 +149,7 @@ bool rtcWrite(u32 address, u16 value)
|
|||||||
rtcClockData.data[0] = toBCD(newtime->tm_year);
|
rtcClockData.data[0] = toBCD(newtime->tm_year);
|
||||||
rtcClockData.data[1] = toBCD(newtime->tm_mon+1);
|
rtcClockData.data[1] = toBCD(newtime->tm_mon+1);
|
||||||
rtcClockData.data[2] = toBCD(newtime->tm_mday);
|
rtcClockData.data[2] = toBCD(newtime->tm_mday);
|
||||||
rtcClockData.data[3] = toBCD(newtime->tm_wday);
|
rtcClockData.data[3] = 0;
|
||||||
rtcClockData.data[4] = toBCD(newtime->tm_hour);
|
rtcClockData.data[4] = toBCD(newtime->tm_hour);
|
||||||
rtcClockData.data[5] = toBCD(newtime->tm_min);
|
rtcClockData.data[5] = toBCD(newtime->tm_min);
|
||||||
rtcClockData.data[6] = toBCD(newtime->tm_sec);
|
rtcClockData.data[6] = toBCD(newtime->tm_sec);
|
||||||
@ -171,26 +179,32 @@ bool rtcWrite(u32 address, u16 value)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case DATA:
|
case DATA:
|
||||||
if(rtcClockData.byte1 & 2) {
|
if(rtcClockData.byte1 & 2)
|
||||||
} else {
|
{}
|
||||||
|
else
|
||||||
|
{
|
||||||
rtcClockData.byte0 = (rtcClockData.byte0 & ~2) |
|
rtcClockData.byte0 = (rtcClockData.byte0 & ~2) |
|
||||||
((rtcClockData.data[rtcClockData.bits >> 3] >>
|
((rtcClockData.data[rtcClockData.bits >> 3] >>
|
||||||
(rtcClockData.bits & 7)) & 1)*2;
|
(rtcClockData.bits & 7)) & 1)*2;
|
||||||
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;
|
||||||
case READDATA:
|
case READDATA:
|
||||||
if(!(rtcClockData.byte1 & 2)) {
|
if(!(rtcClockData.byte1 & 2))
|
||||||
} else {
|
{}
|
||||||
|
else
|
||||||
|
{
|
||||||
rtcClockData.data[rtcClockData.bits >> 3] =
|
rtcClockData.data[rtcClockData.bits >> 3] =
|
||||||
(rtcClockData.data[rtcClockData.bits >> 3] >> 1) |
|
(rtcClockData.data[rtcClockData.bits >> 3] >> 1) |
|
||||||
((value << 6) & 128);
|
((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;
|
||||||
}
|
}
|
||||||
@ -199,7 +213,8 @@ bool rtcWrite(u32 address, u16 value)
|
|||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} else
|
}
|
||||||
|
else
|
||||||
rtcClockData.byte0 = (u8)value;
|
rtcClockData.byte0 = (u8)value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,7 +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 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
|
||||||
@ -19,10 +18,9 @@
|
|||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "Sound.h"
|
#include "GBA.h"
|
||||||
|
|
||||||
#include "agb/GBA.h"
|
|
||||||
#include "Globals.h"
|
#include "Globals.h"
|
||||||
|
#include "Sound.h"
|
||||||
#include "Util.h"
|
#include "Util.h"
|
||||||
|
|
||||||
#define USE_TICKS_AS 380
|
#define USE_TICKS_AS 380
|
||||||
@ -290,7 +288,8 @@ void soundEvent(u32 address, u8 data)
|
|||||||
{
|
{
|
||||||
int freq = 0;
|
int freq = 0;
|
||||||
|
|
||||||
switch(address) {
|
switch(address)
|
||||||
|
{
|
||||||
case NR10:
|
case NR10:
|
||||||
data &= 0x7f;
|
data &= 0x7f;
|
||||||
sound1SweepATL = sound1SweepATLReload = 344 * ((data >> 4) & 7);
|
sound1SweepATL = sound1SweepATLReload = 344 * ((data >> 4) & 7);
|
||||||
@ -315,9 +314,11 @@ void soundEvent(u32 address, u8 data)
|
|||||||
freq = (((int)(ioMem[NR14] & 7)) << 8) | data;
|
freq = (((int)(ioMem[NR14] & 7)) << 8) | data;
|
||||||
sound1ATL = 172 * (64 - (ioMem[NR11] & 0x3f));
|
sound1ATL = 172 * (64 - (ioMem[NR11] & 0x3f));
|
||||||
freq = 2048 - freq;
|
freq = 2048 - freq;
|
||||||
if(freq) {
|
if(freq)
|
||||||
|
{
|
||||||
sound1Skip = SOUND_MAGIC / freq;
|
sound1Skip = SOUND_MAGIC / freq;
|
||||||
} else
|
}
|
||||||
|
else
|
||||||
sound1Skip = 0;
|
sound1Skip = 0;
|
||||||
ioMem[address] = data;
|
ioMem[address] = data;
|
||||||
break;
|
break;
|
||||||
@ -327,11 +328,14 @@ void soundEvent(u32 address, u8 data)
|
|||||||
freq = 2048 - freq;
|
freq = 2048 - freq;
|
||||||
sound1ATL = 172 * (64 - (ioMem[NR11] & 0x3f));
|
sound1ATL = 172 * (64 - (ioMem[NR11] & 0x3f));
|
||||||
sound1Continue = data & 0x40;
|
sound1Continue = data & 0x40;
|
||||||
if(freq) {
|
if(freq)
|
||||||
|
{
|
||||||
sound1Skip = SOUND_MAGIC / freq;
|
sound1Skip = SOUND_MAGIC / freq;
|
||||||
} else
|
}
|
||||||
|
else
|
||||||
sound1Skip = 0;
|
sound1Skip = 0;
|
||||||
if(data & 0x80) {
|
if(data & 0x80)
|
||||||
|
{
|
||||||
ioMem[NR52] |= 1;
|
ioMem[NR52] |= 1;
|
||||||
sound1EnvelopeVolume = ioMem[NR12] >> 4;
|
sound1EnvelopeVolume = ioMem[NR12] >> 4;
|
||||||
sound1EnvelopeUpDown = ioMem[NR12] & 0x08;
|
sound1EnvelopeUpDown = ioMem[NR12] & 0x08;
|
||||||
@ -363,9 +367,11 @@ void soundEvent(u32 address, u8 data)
|
|||||||
freq = (((int)(ioMem[NR24] & 7)) << 8) | data;
|
freq = (((int)(ioMem[NR24] & 7)) << 8) | data;
|
||||||
sound2ATL = 172 * (64 - (ioMem[NR21] & 0x3f));
|
sound2ATL = 172 * (64 - (ioMem[NR21] & 0x3f));
|
||||||
freq = 2048 - freq;
|
freq = 2048 - freq;
|
||||||
if(freq) {
|
if(freq)
|
||||||
|
{
|
||||||
sound2Skip = SOUND_MAGIC / freq;
|
sound2Skip = SOUND_MAGIC / freq;
|
||||||
} else
|
}
|
||||||
|
else
|
||||||
sound2Skip = 0;
|
sound2Skip = 0;
|
||||||
ioMem[address] = data;
|
ioMem[address] = data;
|
||||||
break;
|
break;
|
||||||
@ -375,11 +381,14 @@ void soundEvent(u32 address, u8 data)
|
|||||||
freq = 2048 - freq;
|
freq = 2048 - freq;
|
||||||
sound2ATL = 172 * (64 - (ioMem[NR21] & 0x3f));
|
sound2ATL = 172 * (64 - (ioMem[NR21] & 0x3f));
|
||||||
sound2Continue = data & 0x40;
|
sound2Continue = data & 0x40;
|
||||||
if(freq) {
|
if(freq)
|
||||||
|
{
|
||||||
sound2Skip = SOUND_MAGIC / freq;
|
sound2Skip = SOUND_MAGIC / freq;
|
||||||
} else
|
}
|
||||||
|
else
|
||||||
sound2Skip = 0;
|
sound2Skip = 0;
|
||||||
if(data & 0x80) {
|
if(data & 0x80)
|
||||||
|
{
|
||||||
ioMem[NR52] |= 2;
|
ioMem[NR52] |= 2;
|
||||||
sound2EnvelopeVolume = ioMem[NR22] >> 4;
|
sound2EnvelopeVolume = ioMem[NR22] >> 4;
|
||||||
sound2EnvelopeUpDown = ioMem[NR22] & 0x08;
|
sound2EnvelopeUpDown = ioMem[NR22] & 0x08;
|
||||||
@ -389,11 +398,12 @@ void soundEvent(u32 address, u8 data)
|
|||||||
sound2Index = 0;
|
sound2Index = 0;
|
||||||
sound2On = 1;
|
sound2On = 1;
|
||||||
}
|
}
|
||||||
ioMem[address] = data;
|
|
||||||
break;
|
break;
|
||||||
|
ioMem[address] = data;
|
||||||
case NR30:
|
case NR30:
|
||||||
data &= 0xe0;
|
data &= 0xe0;
|
||||||
if(!(data & 0x80)) {
|
if(!(data & 0x80))
|
||||||
|
{
|
||||||
ioMem[NR52] &= 0xfb;
|
ioMem[NR52] &= 0xfb;
|
||||||
sound3On = 0;
|
sound3On = 0;
|
||||||
}
|
}
|
||||||
@ -416,22 +426,28 @@ void soundEvent(u32 address, u8 data)
|
|||||||
break;
|
break;
|
||||||
case NR33:
|
case NR33:
|
||||||
freq = 2048 - (((int)(ioMem[NR34]&7) << 8) | data);
|
freq = 2048 - (((int)(ioMem[NR34]&7) << 8) | data);
|
||||||
if(freq) {
|
if(freq)
|
||||||
|
{
|
||||||
sound3Skip = SOUND_MAGIC_2 / freq;
|
sound3Skip = SOUND_MAGIC_2 / freq;
|
||||||
} else
|
}
|
||||||
|
else
|
||||||
sound3Skip = 0;
|
sound3Skip = 0;
|
||||||
ioMem[address] = data;
|
ioMem[address] = data;
|
||||||
break;
|
break;
|
||||||
case NR34:
|
case NR34:
|
||||||
data &= 0xc7;
|
data &= 0xc7;
|
||||||
freq = 2048 - (((data &7) << 8) | (int)ioMem[NR33]);
|
freq = 2048 - (((data &7) << 8) | (int)ioMem[NR33]);
|
||||||
if(freq) {
|
if(freq)
|
||||||
|
{
|
||||||
sound3Skip = SOUND_MAGIC_2 / freq;
|
sound3Skip = SOUND_MAGIC_2 / freq;
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
sound3Skip = 0;
|
sound3Skip = 0;
|
||||||
}
|
}
|
||||||
sound3Continue = data & 0x40;
|
sound3Continue = data & 0x40;
|
||||||
if((data & 0x80) && (ioMem[NR30] & 0x80)) {
|
if((data & 0x80) && (ioMem[NR30] & 0x80))
|
||||||
|
{
|
||||||
ioMem[NR52] |= 4;
|
ioMem[NR52] |= 4;
|
||||||
sound3ATL = 172 * (256 - ioMem[NR31]);
|
sound3ATL = 172 * (256 - ioMem[NR31]);
|
||||||
sound3Index = 0;
|
sound3Index = 0;
|
||||||
@ -467,7 +483,8 @@ void soundEvent(u32 address, u8 data)
|
|||||||
case NR44:
|
case NR44:
|
||||||
data &= 0xc0;
|
data &= 0xc0;
|
||||||
sound4Continue = data & 0x40;
|
sound4Continue = data & 0x40;
|
||||||
if(data & 0x80) {
|
if(data & 0x80)
|
||||||
|
{
|
||||||
ioMem[NR52] |= 8;
|
ioMem[NR52] |= 8;
|
||||||
sound4EnvelopeVolume = ioMem[NR42] >> 4;
|
sound4EnvelopeVolume = ioMem[NR42] >> 4;
|
||||||
sound4EnvelopeUpDown = ioMem[NR42] & 0x08;
|
sound4EnvelopeUpDown = ioMem[NR42] & 0x08;
|
||||||
@ -509,7 +526,8 @@ void soundEvent(u32 address, u8 data)
|
|||||||
data &= 0x80;
|
data &= 0x80;
|
||||||
data |= ioMem[NR52] & 15;
|
data |= ioMem[NR52] & 15;
|
||||||
soundMasterOn = data & 0x80;
|
soundMasterOn = data & 0x80;
|
||||||
if(!(data & 0x80)) {
|
if(!(data & 0x80))
|
||||||
|
{
|
||||||
sound1On = 0;
|
sound1On = 0;
|
||||||
sound2On = 0;
|
sound2On = 0;
|
||||||
sound3On = 0;
|
sound3On = 0;
|
||||||
@ -540,11 +558,14 @@ void soundEvent(u32 address, u8 data)
|
|||||||
|
|
||||||
void soundEvent(u32 address, u16 data)
|
void soundEvent(u32 address, u16 data)
|
||||||
{
|
{
|
||||||
switch(address) {
|
switch(address)
|
||||||
|
{
|
||||||
case SGCNT0_H:
|
case SGCNT0_H:
|
||||||
data &= 0xFF0F;
|
data &= 0xFF0F;
|
||||||
soundControl = data & 0x770F;
|
soundControl = data & 0x770F;
|
||||||
if(data & 0x0800) {
|
;
|
||||||
|
if(data & 0x0800)
|
||||||
|
{
|
||||||
soundDSFifoAWriteIndex = 0;
|
soundDSFifoAWriteIndex = 0;
|
||||||
soundDSFifoAIndex = 0;
|
soundDSFifoAIndex = 0;
|
||||||
soundDSFifoACount = 0;
|
soundDSFifoACount = 0;
|
||||||
@ -553,7 +574,8 @@ void soundEvent(u32 address, u16 data)
|
|||||||
}
|
}
|
||||||
soundDSAEnabled = (data & 0x0300) ? true : false;
|
soundDSAEnabled = (data & 0x0300) ? true : false;
|
||||||
soundDSATimer = (data & 0x0400) ? 1 : 0;
|
soundDSATimer = (data & 0x0400) ? 1 : 0;
|
||||||
if(data & 0x8000) {
|
if(data & 0x8000)
|
||||||
|
{
|
||||||
soundDSFifoBWriteIndex = 0;
|
soundDSFifoBWriteIndex = 0;
|
||||||
soundDSFifoBIndex = 0;
|
soundDSFifoBIndex = 0;
|
||||||
soundDSFifoBCount = 0;
|
soundDSFifoBCount = 0;
|
||||||
@ -562,7 +584,7 @@ void soundEvent(u32 address, u16 data)
|
|||||||
}
|
}
|
||||||
soundDSBEnabled = (data & 0x3000) ? true : false;
|
soundDSBEnabled = (data & 0x3000) ? true : false;
|
||||||
soundDSBTimer = (data & 0x4000) ? 1 : 0;
|
soundDSBTimer = (data & 0x4000) ? 1 : 0;
|
||||||
*((u16 *)&ioMem[address]) = soundControl;
|
*((u16 *)&ioMem[address]) = data;
|
||||||
break;
|
break;
|
||||||
case FIFOA_L:
|
case FIFOA_L:
|
||||||
case FIFOA_H:
|
case FIFOA_H:
|
||||||
@ -605,7 +627,8 @@ void soundChannel1()
|
|||||||
int freq = 0;
|
int freq = 0;
|
||||||
int value = 0;
|
int value = 0;
|
||||||
|
|
||||||
if(sound1On && (sound1ATL || !sound1Continue)) {
|
if(sound1On && (sound1ATL || !sound1Continue))
|
||||||
|
{
|
||||||
sound1Index += soundQuality*sound1Skip;
|
sound1Index += soundQuality*sound1Skip;
|
||||||
sound1Index &= 0x1fffffff;
|
sound1Index &= 0x1fffffff;
|
||||||
|
|
||||||
@ -615,24 +638,32 @@ void soundChannel1()
|
|||||||
soundBuffer[0][soundIndex] = value;
|
soundBuffer[0][soundIndex] = value;
|
||||||
|
|
||||||
|
|
||||||
if(sound1On) {
|
if(sound1On)
|
||||||
if(sound1ATL) {
|
{
|
||||||
|
if(sound1ATL)
|
||||||
|
{
|
||||||
sound1ATL-=soundQuality;
|
sound1ATL-=soundQuality;
|
||||||
|
|
||||||
if(sound1ATL <=0 && sound1Continue) {
|
if(sound1ATL <=0 && sound1Continue)
|
||||||
|
{
|
||||||
ioMem[NR52] &= 0xfe;
|
ioMem[NR52] &= 0xfe;
|
||||||
sound1On = 0;
|
sound1On = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(sound1EnvelopeATL) {
|
if(sound1EnvelopeATL)
|
||||||
|
{
|
||||||
sound1EnvelopeATL-=soundQuality;
|
sound1EnvelopeATL-=soundQuality;
|
||||||
|
|
||||||
if(sound1EnvelopeATL<=0) {
|
if(sound1EnvelopeATL<=0)
|
||||||
if(sound1EnvelopeUpDown) {
|
{
|
||||||
|
if(sound1EnvelopeUpDown)
|
||||||
|
{
|
||||||
if(sound1EnvelopeVolume < 15)
|
if(sound1EnvelopeVolume < 15)
|
||||||
sound1EnvelopeVolume++;
|
sound1EnvelopeVolume++;
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
if(sound1EnvelopeVolume)
|
if(sound1EnvelopeVolume)
|
||||||
sound1EnvelopeVolume--;
|
sound1EnvelopeVolume--;
|
||||||
}
|
}
|
||||||
@ -641,10 +672,12 @@ void soundChannel1()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(sound1SweepATL) {
|
if(sound1SweepATL)
|
||||||
|
{
|
||||||
sound1SweepATL-=soundQuality;
|
sound1SweepATL-=soundQuality;
|
||||||
|
|
||||||
if(sound1SweepATL<=0) {
|
if(sound1SweepATL<=0)
|
||||||
|
{
|
||||||
freq = (((int)(ioMem[NR14]&7) << 8) | ioMem[NR13]);
|
freq = (((int)(ioMem[NR14]&7) << 8) | ioMem[NR13]);
|
||||||
|
|
||||||
int updown = 1;
|
int updown = 1;
|
||||||
@ -653,20 +686,27 @@ void soundChannel1()
|
|||||||
updown = -1;
|
updown = -1;
|
||||||
|
|
||||||
int newfreq = 0;
|
int newfreq = 0;
|
||||||
if(sound1SweepSteps) {
|
if(sound1SweepSteps)
|
||||||
|
{
|
||||||
newfreq = freq + updown * freq / (1 << sound1SweepSteps);
|
newfreq = freq + updown * freq / (1 << sound1SweepSteps);
|
||||||
if(newfreq == freq)
|
if(newfreq == freq)
|
||||||
newfreq = 0;
|
newfreq = 0;
|
||||||
} else
|
}
|
||||||
|
else
|
||||||
newfreq = freq;
|
newfreq = freq;
|
||||||
|
|
||||||
if(newfreq < 0) {
|
if(newfreq < 0)
|
||||||
|
{
|
||||||
sound1SweepATL += sound1SweepATLReload;
|
sound1SweepATL += sound1SweepATLReload;
|
||||||
} else if(newfreq > 2047) {
|
}
|
||||||
|
else if(newfreq > 2047)
|
||||||
|
{
|
||||||
sound1SweepATL = 0;
|
sound1SweepATL = 0;
|
||||||
sound1On = 0;
|
sound1On = 0;
|
||||||
ioMem[NR52] &= 0xfe;
|
ioMem[NR52] &= 0xfe;
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
sound1SweepATL += sound1SweepATLReload;
|
sound1SweepATL += sound1SweepATLReload;
|
||||||
sound1Skip = SOUND_MAGIC/(2048 - newfreq);
|
sound1Skip = SOUND_MAGIC/(2048 - newfreq);
|
||||||
|
|
||||||
@ -685,7 +725,8 @@ void soundChannel2()
|
|||||||
|
|
||||||
int value = 0;
|
int value = 0;
|
||||||
|
|
||||||
if(sound2On && (sound2ATL || !sound2Continue)) {
|
if(sound2On && (sound2ATL || !sound2Continue))
|
||||||
|
{
|
||||||
sound2Index += soundQuality*sound2Skip;
|
sound2Index += soundQuality*sound2Skip;
|
||||||
sound2Index &= 0x1fffffff;
|
sound2Index &= 0x1fffffff;
|
||||||
|
|
||||||
@ -694,24 +735,32 @@ void soundChannel2()
|
|||||||
|
|
||||||
soundBuffer[1][soundIndex] = value;
|
soundBuffer[1][soundIndex] = value;
|
||||||
|
|
||||||
if(sound2On) {
|
if(sound2On)
|
||||||
if(sound2ATL) {
|
{
|
||||||
|
if(sound2ATL)
|
||||||
|
{
|
||||||
sound2ATL-=soundQuality;
|
sound2ATL-=soundQuality;
|
||||||
|
|
||||||
if(sound2ATL <= 0 && sound2Continue) {
|
if(sound2ATL <= 0 && sound2Continue)
|
||||||
|
{
|
||||||
ioMem[NR52] &= 0xfd;
|
ioMem[NR52] &= 0xfd;
|
||||||
sound2On = 0;
|
sound2On = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(sound2EnvelopeATL) {
|
if(sound2EnvelopeATL)
|
||||||
|
{
|
||||||
sound2EnvelopeATL-=soundQuality;
|
sound2EnvelopeATL-=soundQuality;
|
||||||
|
|
||||||
if(sound2EnvelopeATL <= 0) {
|
if(sound2EnvelopeATL <= 0)
|
||||||
if(sound2EnvelopeUpDown) {
|
{
|
||||||
|
if(sound2EnvelopeUpDown)
|
||||||
|
{
|
||||||
if(sound2EnvelopeVolume < 15)
|
if(sound2EnvelopeVolume < 15)
|
||||||
sound2EnvelopeVolume++;
|
sound2EnvelopeVolume++;
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
if(sound2EnvelopeVolume)
|
if(sound2EnvelopeVolume)
|
||||||
sound2EnvelopeVolume--;
|
sound2EnvelopeVolume--;
|
||||||
}
|
}
|
||||||
@ -725,29 +774,41 @@ void soundChannel3()
|
|||||||
{
|
{
|
||||||
int value = sound3Last;
|
int value = sound3Last;
|
||||||
|
|
||||||
if(sound3On && (sound3ATL || !sound3Continue)) {
|
if(sound3On && (sound3ATL || !sound3Continue))
|
||||||
|
{
|
||||||
sound3Index += soundQuality*sound3Skip;
|
sound3Index += soundQuality*sound3Skip;
|
||||||
if(sound3DataSize) {
|
if(sound3DataSize)
|
||||||
|
{
|
||||||
sound3Index &= 0x3fffffff;
|
sound3Index &= 0x3fffffff;
|
||||||
value = sound3WaveRam[sound3Index>>25];
|
value = sound3WaveRam[sound3Index>>25];
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
sound3Index &= 0x1fffffff;
|
sound3Index &= 0x1fffffff;
|
||||||
value = sound3WaveRam[sound3Bank*0x10 + (sound3Index>>25)];
|
value = sound3WaveRam[sound3Bank*0x10 + (sound3Index>>25)];
|
||||||
}
|
}
|
||||||
|
|
||||||
if( (sound3Index & 0x01000000)) {
|
if( (sound3Index & 0x01000000))
|
||||||
|
{
|
||||||
value &= 0x0f;
|
value &= 0x0f;
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
value >>= 4;
|
value >>= 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
value -= 8;
|
value -= 8;
|
||||||
value *= 2;
|
//value *= 2;
|
||||||
|
value <<= 1;
|
||||||
|
|
||||||
if(sound3ForcedOutput) {
|
if(sound3ForcedOutput)
|
||||||
|
{
|
||||||
value = ((value >> 1) + value) >> 1;
|
value = ((value >> 1) + value) >> 1;
|
||||||
} else {
|
}
|
||||||
switch(sound3OutputLevel) {
|
else
|
||||||
|
{
|
||||||
|
switch(sound3OutputLevel)
|
||||||
|
{
|
||||||
case 0:
|
case 0:
|
||||||
value = 0;
|
value = 0;
|
||||||
break;
|
break;
|
||||||
@ -766,11 +827,14 @@ void soundChannel3()
|
|||||||
|
|
||||||
soundBuffer[2][soundIndex] = value;
|
soundBuffer[2][soundIndex] = value;
|
||||||
|
|
||||||
if(sound3On) {
|
if(sound3On)
|
||||||
if(sound3ATL) {
|
{
|
||||||
|
if(sound3ATL)
|
||||||
|
{
|
||||||
sound3ATL-=soundQuality;
|
sound3ATL-=soundQuality;
|
||||||
|
|
||||||
if(sound3ATL <= 0 && sound3Continue) {
|
if(sound3ATL <= 0 && sound3Continue)
|
||||||
|
{
|
||||||
ioMem[NR52] &= 0xfb;
|
ioMem[NR52] &= 0xfb;
|
||||||
sound3On = 0;
|
sound3On = 0;
|
||||||
}
|
}
|
||||||
@ -784,20 +848,27 @@ void soundChannel4()
|
|||||||
|
|
||||||
int value = 0;
|
int value = 0;
|
||||||
|
|
||||||
if(sound4Clock <= 0x0c) {
|
if(sound4Clock <= 0x0c)
|
||||||
if(sound4On && (sound4ATL || !sound4Continue)) {
|
{
|
||||||
|
if(sound4On && (sound4ATL || !sound4Continue))
|
||||||
|
{
|
||||||
sound4Index += soundQuality*sound4Skip;
|
sound4Index += soundQuality*sound4Skip;
|
||||||
sound4ShiftIndex += soundQuality*sound4ShiftSkip;
|
sound4ShiftIndex += soundQuality*sound4ShiftSkip;
|
||||||
|
|
||||||
if(sound4NSteps) {
|
if(sound4NSteps)
|
||||||
while(sound4ShiftIndex > 0x1fffff) {
|
{
|
||||||
|
while(sound4ShiftIndex > 0x1fffff)
|
||||||
|
{
|
||||||
sound4ShiftRight = (((sound4ShiftRight << 6) ^
|
sound4ShiftRight = (((sound4ShiftRight << 6) ^
|
||||||
(sound4ShiftRight << 5)) & 0x40) |
|
(sound4ShiftRight << 5)) & 0x40) |
|
||||||
(sound4ShiftRight >> 1);
|
(sound4ShiftRight >> 1);
|
||||||
sound4ShiftIndex -= 0x200000;
|
sound4ShiftIndex -= 0x200000;
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
while(sound4ShiftIndex > 0x1fffff) {
|
else
|
||||||
|
{
|
||||||
|
while(sound4ShiftIndex > 0x1fffff)
|
||||||
|
{
|
||||||
sound4ShiftRight = (((sound4ShiftRight << 14) ^
|
sound4ShiftRight = (((sound4ShiftRight << 14) ^
|
||||||
(sound4ShiftRight << 13)) & 0x4000) |
|
(sound4ShiftRight << 13)) & 0x4000) |
|
||||||
(sound4ShiftRight >> 1);
|
(sound4ShiftRight >> 1);
|
||||||
@ -810,31 +881,41 @@ void soundChannel4()
|
|||||||
sound4ShiftIndex &= 0x1fffff;
|
sound4ShiftIndex &= 0x1fffff;
|
||||||
|
|
||||||
value = ((sound4ShiftRight & 1)*2-1) * vol;
|
value = ((sound4ShiftRight & 1)*2-1) * vol;
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
value = 0;
|
value = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
soundBuffer[3][soundIndex] = value;
|
soundBuffer[3][soundIndex] = value;
|
||||||
|
|
||||||
if(sound4On) {
|
if(sound4On)
|
||||||
if(sound4ATL) {
|
{
|
||||||
|
if(sound4ATL)
|
||||||
|
{
|
||||||
sound4ATL-=soundQuality;
|
sound4ATL-=soundQuality;
|
||||||
|
|
||||||
if(sound4ATL <= 0 && sound4Continue) {
|
if(sound4ATL <= 0 && sound4Continue)
|
||||||
|
{
|
||||||
ioMem[NR52] &= 0xfd;
|
ioMem[NR52] &= 0xfd;
|
||||||
sound4On = 0;
|
sound4On = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(sound4EnvelopeATL) {
|
if(sound4EnvelopeATL)
|
||||||
|
{
|
||||||
sound4EnvelopeATL-=soundQuality;
|
sound4EnvelopeATL-=soundQuality;
|
||||||
|
|
||||||
if(sound4EnvelopeATL <= 0) {
|
if(sound4EnvelopeATL <= 0)
|
||||||
if(sound4EnvelopeUpDown) {
|
{
|
||||||
|
if(sound4EnvelopeUpDown)
|
||||||
|
{
|
||||||
if(sound4EnvelopeVolume < 15)
|
if(sound4EnvelopeVolume < 15)
|
||||||
sound4EnvelopeVolume++;
|
sound4EnvelopeVolume++;
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
if(sound4EnvelopeVolume)
|
if(sound4EnvelopeVolume)
|
||||||
sound4EnvelopeVolume--;
|
sound4EnvelopeVolume--;
|
||||||
}
|
}
|
||||||
@ -851,10 +932,13 @@ void soundDirectSoundA()
|
|||||||
|
|
||||||
void soundDirectSoundATimer()
|
void soundDirectSoundATimer()
|
||||||
{
|
{
|
||||||
if(soundDSAEnabled) {
|
if(soundDSAEnabled)
|
||||||
if(soundDSFifoACount <= 16) {
|
{
|
||||||
|
if(soundDSFifoACount <= 16)
|
||||||
|
{
|
||||||
CPUCheckDMA(3, 2);
|
CPUCheckDMA(3, 2);
|
||||||
if(soundDSFifoACount <= 16) {
|
if(soundDSFifoACount <= 16)
|
||||||
|
{
|
||||||
soundEvent(FIFOA_L, (u16)0);
|
soundEvent(FIFOA_L, (u16)0);
|
||||||
soundEvent(FIFOA_H, (u16)0);
|
soundEvent(FIFOA_H, (u16)0);
|
||||||
soundEvent(FIFOA_L, (u16)0);
|
soundEvent(FIFOA_L, (u16)0);
|
||||||
@ -867,9 +951,10 @@ void soundDirectSoundATimer()
|
|||||||
}
|
}
|
||||||
|
|
||||||
soundDSAValue = (soundDSFifoA[soundDSFifoAIndex]);
|
soundDSAValue = (soundDSFifoA[soundDSFifoAIndex]);
|
||||||
soundDSFifoAIndex = (soundDSFifoAIndex + 1) & 31;
|
soundDSFifoAIndex = (++soundDSFifoAIndex) & 31;
|
||||||
soundDSFifoACount--;
|
soundDSFifoACount--;
|
||||||
} else
|
}
|
||||||
|
else
|
||||||
soundDSAValue = 0;
|
soundDSAValue = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -880,10 +965,13 @@ void soundDirectSoundB()
|
|||||||
|
|
||||||
void soundDirectSoundBTimer()
|
void soundDirectSoundBTimer()
|
||||||
{
|
{
|
||||||
if(soundDSBEnabled) {
|
if(soundDSBEnabled)
|
||||||
if(soundDSFifoBCount <= 16) {
|
{
|
||||||
|
if(soundDSFifoBCount <= 16)
|
||||||
|
{
|
||||||
CPUCheckDMA(3, 4);
|
CPUCheckDMA(3, 4);
|
||||||
if(soundDSFifoBCount <= 16) {
|
if(soundDSFifoBCount <= 16)
|
||||||
|
{
|
||||||
soundEvent(FIFOB_L, (u16)0);
|
soundEvent(FIFOB_L, (u16)0);
|
||||||
soundEvent(FIFOB_H, (u16)0);
|
soundEvent(FIFOB_H, (u16)0);
|
||||||
soundEvent(FIFOB_L, (u16)0);
|
soundEvent(FIFOB_L, (u16)0);
|
||||||
@ -896,19 +984,23 @@ void soundDirectSoundBTimer()
|
|||||||
}
|
}
|
||||||
|
|
||||||
soundDSBValue = (soundDSFifoB[soundDSFifoBIndex]);
|
soundDSBValue = (soundDSFifoB[soundDSFifoBIndex]);
|
||||||
soundDSFifoBIndex = (soundDSFifoBIndex + 1) & 31;
|
soundDSFifoBIndex = (++soundDSFifoBIndex) & 31;
|
||||||
soundDSFifoBCount--;
|
soundDSFifoBCount--;
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
soundDSBValue = 0;
|
soundDSBValue = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void soundTimerOverflow(int timer)
|
void soundTimerOverflow(int timer)
|
||||||
{
|
{
|
||||||
if(soundDSAEnabled && (soundDSATimer == timer)) {
|
if(soundDSAEnabled && (soundDSATimer == timer))
|
||||||
|
{
|
||||||
soundDirectSoundATimer();
|
soundDirectSoundATimer();
|
||||||
}
|
}
|
||||||
if(soundDSBEnabled && (soundDSBTimer == timer)) {
|
if(soundDSBEnabled && (soundDSBTimer == timer))
|
||||||
|
{
|
||||||
soundDirectSoundBTimer();
|
soundDirectSoundBTimer();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -925,27 +1017,33 @@ void soundMix()
|
|||||||
int dsaRatio = ioMem[0x82] & 4;
|
int dsaRatio = ioMem[0x82] & 4;
|
||||||
int dsbRatio = ioMem[0x82] & 8;
|
int dsbRatio = ioMem[0x82] & 8;
|
||||||
|
|
||||||
if(soundBalance & 16) {
|
if(soundBalance & 16)
|
||||||
|
{
|
||||||
cgbRes = ((s8)soundBuffer[0][soundIndex]);
|
cgbRes = ((s8)soundBuffer[0][soundIndex]);
|
||||||
}
|
}
|
||||||
if(soundBalance & 32) {
|
if(soundBalance & 32)
|
||||||
|
{
|
||||||
cgbRes += ((s8)soundBuffer[1][soundIndex]);
|
cgbRes += ((s8)soundBuffer[1][soundIndex]);
|
||||||
}
|
}
|
||||||
if(soundBalance & 64) {
|
if(soundBalance & 64)
|
||||||
|
{
|
||||||
cgbRes += ((s8)soundBuffer[2][soundIndex]);
|
cgbRes += ((s8)soundBuffer[2][soundIndex]);
|
||||||
}
|
}
|
||||||
if(soundBalance & 128) {
|
if(soundBalance & 128)
|
||||||
|
{
|
||||||
cgbRes += ((s8)soundBuffer[3][soundIndex]);
|
cgbRes += ((s8)soundBuffer[3][soundIndex]);
|
||||||
}
|
}
|
||||||
|
|
||||||
if((soundControl & 0x0200) && (soundEnableFlag & 0x100)){
|
if((soundControl & 0x0200) && (soundEnableFlag & 0x100))
|
||||||
|
{
|
||||||
if(!dsaRatio)
|
if(!dsaRatio)
|
||||||
res = ((s8)soundBuffer[4][soundIndex])>>1;
|
res = ((s8)soundBuffer[4][soundIndex])>>1;
|
||||||
else
|
else
|
||||||
res = ((s8)soundBuffer[4][soundIndex]);
|
res = ((s8)soundBuffer[4][soundIndex]);
|
||||||
}
|
}
|
||||||
|
|
||||||
if((soundControl & 0x2000) && (soundEnableFlag & 0x200)){
|
if((soundControl & 0x2000) && (soundEnableFlag & 0x200))
|
||||||
|
{
|
||||||
if(!dsbRatio)
|
if(!dsbRatio)
|
||||||
res += ((s8)soundBuffer[5][soundIndex])>>1;
|
res += ((s8)soundBuffer[5][soundIndex])>>1;
|
||||||
else
|
else
|
||||||
@ -955,7 +1053,8 @@ void soundMix()
|
|||||||
res = (res * 170);
|
res = (res * 170);
|
||||||
cgbRes = (cgbRes * 52 * soundLevel1);
|
cgbRes = (cgbRes * 52 * soundLevel1);
|
||||||
|
|
||||||
switch(ratio) {
|
switch(ratio)
|
||||||
|
{
|
||||||
case 0:
|
case 0:
|
||||||
case 3: // prohibited, but 25%
|
case 3: // prohibited, but 25%
|
||||||
cgbRes >>= 2;
|
cgbRes >>= 2;
|
||||||
@ -969,14 +1068,16 @@ void soundMix()
|
|||||||
|
|
||||||
res += cgbRes;
|
res += cgbRes;
|
||||||
|
|
||||||
if(soundEcho) {
|
if(soundEcho)
|
||||||
|
{
|
||||||
res *= 2;
|
res *= 2;
|
||||||
res += soundFilter[soundEchoIndex];
|
res += soundFilter[soundEchoIndex];
|
||||||
res /= 2;
|
res /= 2;
|
||||||
soundFilter[soundEchoIndex++] = res;
|
soundFilter[soundEchoIndex++] = res;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(soundLowPass) {
|
if(soundLowPass)
|
||||||
|
{
|
||||||
soundLeft[4] = soundLeft[3];
|
soundLeft[4] = soundLeft[3];
|
||||||
soundLeft[3] = soundLeft[2];
|
soundLeft[3] = soundLeft[2];
|
||||||
soundLeft[2] = soundLeft[1];
|
soundLeft[2] = soundLeft[1];
|
||||||
@ -986,7 +1087,8 @@ void soundMix()
|
|||||||
soundLeft[0])/14;
|
soundLeft[0])/14;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch(soundVolume) {
|
switch(soundVolume)
|
||||||
|
{
|
||||||
case 0:
|
case 0:
|
||||||
case 1:
|
case 1:
|
||||||
case 2:
|
case 2:
|
||||||
@ -1014,27 +1116,33 @@ void soundMix()
|
|||||||
res = 0;
|
res = 0;
|
||||||
cgbRes = 0;
|
cgbRes = 0;
|
||||||
|
|
||||||
if(soundBalance & 1) {
|
if(soundBalance & 1)
|
||||||
|
{
|
||||||
cgbRes = ((s8)soundBuffer[0][soundIndex]);
|
cgbRes = ((s8)soundBuffer[0][soundIndex]);
|
||||||
}
|
}
|
||||||
if(soundBalance & 2) {
|
if(soundBalance & 2)
|
||||||
|
{
|
||||||
cgbRes += ((s8)soundBuffer[1][soundIndex]);
|
cgbRes += ((s8)soundBuffer[1][soundIndex]);
|
||||||
}
|
}
|
||||||
if(soundBalance & 4) {
|
if(soundBalance & 4)
|
||||||
|
{
|
||||||
cgbRes += ((s8)soundBuffer[2][soundIndex]);
|
cgbRes += ((s8)soundBuffer[2][soundIndex]);
|
||||||
}
|
}
|
||||||
if(soundBalance & 8) {
|
if(soundBalance & 8)
|
||||||
|
{
|
||||||
cgbRes += ((s8)soundBuffer[3][soundIndex]);
|
cgbRes += ((s8)soundBuffer[3][soundIndex]);
|
||||||
}
|
}
|
||||||
|
|
||||||
if((soundControl & 0x0100) && (soundEnableFlag & 0x100)){
|
if((soundControl & 0x0100) && (soundEnableFlag & 0x100))
|
||||||
|
{
|
||||||
if(!dsaRatio)
|
if(!dsaRatio)
|
||||||
res = ((s8)soundBuffer[4][soundIndex])>>1;
|
res = ((s8)soundBuffer[4][soundIndex])>>1;
|
||||||
else
|
else
|
||||||
res = ((s8)soundBuffer[4][soundIndex]);
|
res = ((s8)soundBuffer[4][soundIndex]);
|
||||||
}
|
}
|
||||||
|
|
||||||
if((soundControl & 0x1000) && (soundEnableFlag & 0x200)){
|
if((soundControl & 0x1000) && (soundEnableFlag & 0x200))
|
||||||
|
{
|
||||||
if(!dsbRatio)
|
if(!dsbRatio)
|
||||||
res += ((s8)soundBuffer[5][soundIndex])>>1;
|
res += ((s8)soundBuffer[5][soundIndex])>>1;
|
||||||
else
|
else
|
||||||
@ -1044,7 +1152,8 @@ void soundMix()
|
|||||||
res = (res * 170);
|
res = (res * 170);
|
||||||
cgbRes = (cgbRes * 52 * soundLevel1);
|
cgbRes = (cgbRes * 52 * soundLevel1);
|
||||||
|
|
||||||
switch(ratio) {
|
switch(ratio)
|
||||||
|
{
|
||||||
case 0:
|
case 0:
|
||||||
case 3: // prohibited, but 25%
|
case 3: // prohibited, but 25%
|
||||||
cgbRes >>= 2;
|
cgbRes >>= 2;
|
||||||
@ -1058,7 +1167,8 @@ void soundMix()
|
|||||||
|
|
||||||
res += cgbRes;
|
res += cgbRes;
|
||||||
|
|
||||||
if(soundEcho) {
|
if(soundEcho)
|
||||||
|
{
|
||||||
res *= 2;
|
res *= 2;
|
||||||
res += soundFilter[soundEchoIndex];
|
res += soundFilter[soundEchoIndex];
|
||||||
res /= 2;
|
res /= 2;
|
||||||
@ -1068,7 +1178,8 @@ void soundMix()
|
|||||||
soundEchoIndex = 0;
|
soundEchoIndex = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(soundLowPass) {
|
if(soundLowPass)
|
||||||
|
{
|
||||||
soundRight[4] = soundRight[3];
|
soundRight[4] = soundRight[3];
|
||||||
soundRight[3] = soundRight[2];
|
soundRight[3] = soundRight[2];
|
||||||
soundRight[2] = soundRight[1];
|
soundRight[2] = soundRight[1];
|
||||||
@ -1078,7 +1189,8 @@ void soundMix()
|
|||||||
soundRight[0])/14;
|
soundRight[0])/14;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch(soundVolume) {
|
switch(soundVolume)
|
||||||
|
{
|
||||||
case 0:
|
case 0:
|
||||||
case 1:
|
case 1:
|
||||||
case 2:
|
case 2:
|
||||||
@ -1106,8 +1218,10 @@ void soundMix()
|
|||||||
|
|
||||||
void soundTick()
|
void soundTick()
|
||||||
{
|
{
|
||||||
if(systemSoundOn) {
|
if(systemSoundOn)
|
||||||
if(soundMasterOn && !stopState) {
|
{
|
||||||
|
if(soundMasterOn && !stopState)
|
||||||
|
{
|
||||||
soundChannel1();
|
soundChannel1();
|
||||||
soundChannel2();
|
soundChannel2();
|
||||||
soundChannel3();
|
soundChannel3();
|
||||||
@ -1115,16 +1229,21 @@ void soundTick()
|
|||||||
soundDirectSoundA();
|
soundDirectSoundA();
|
||||||
soundDirectSoundB();
|
soundDirectSoundB();
|
||||||
soundMix();
|
soundMix();
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
soundFinalWave[soundBufferIndex++] = 0;
|
soundFinalWave[soundBufferIndex++] = 0;
|
||||||
soundFinalWave[soundBufferIndex++] = 0;
|
soundFinalWave[soundBufferIndex++] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
soundIndex++;
|
soundIndex++;
|
||||||
|
|
||||||
if(2*soundBufferIndex >= soundBufferLen) {
|
if(2*soundBufferIndex >= soundBufferLen)
|
||||||
if(systemSoundOn) {
|
{
|
||||||
if(soundPaused) {
|
if(systemSoundOn)
|
||||||
|
{
|
||||||
|
if(soundPaused)
|
||||||
|
{
|
||||||
soundResume();
|
soundResume();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1250,13 +1369,15 @@ void soundReset()
|
|||||||
|
|
||||||
int addr = 0x90;
|
int addr = 0x90;
|
||||||
|
|
||||||
while(addr < 0xA0) {
|
while(addr < 0xA0)
|
||||||
|
{
|
||||||
ioMem[addr++] = 0x00;
|
ioMem[addr++] = 0x00;
|
||||||
ioMem[addr++] = 0xff;
|
ioMem[addr++] = 0xff;
|
||||||
}
|
}
|
||||||
|
|
||||||
addr = 0;
|
addr = 0;
|
||||||
while(addr < 0x20) {
|
while(addr < 0x20)
|
||||||
|
{
|
||||||
sound3WaveRam[addr++] = 0x00;
|
sound3WaveRam[addr++] = 0x00;
|
||||||
sound3WaveRam[addr++] = 0xff;
|
sound3WaveRam[addr++] = 0xff;
|
||||||
}
|
}
|
||||||
@ -1269,7 +1390,8 @@ void soundReset()
|
|||||||
|
|
||||||
bool soundInit()
|
bool soundInit()
|
||||||
{
|
{
|
||||||
if(systemSoundInit()) {
|
if(systemSoundInit())
|
||||||
|
{
|
||||||
memset(soundBuffer[0], 0, 735*2);
|
memset(soundBuffer[0], 0, 735*2);
|
||||||
memset(soundBuffer[1], 0, 735*2);
|
memset(soundBuffer[1], 0, 735*2);
|
||||||
memset(soundBuffer[2], 0, 735*2);
|
memset(soundBuffer[2], 0, 735*2);
|
||||||
@ -1285,7 +1407,8 @@ bool soundInit()
|
|||||||
|
|
||||||
void soundSetQuality(int quality)
|
void soundSetQuality(int quality)
|
||||||
{
|
{
|
||||||
if(soundQuality != quality && systemCanChangeSoundQuality()) {
|
if(soundQuality != quality && systemCanChangeSoundQuality())
|
||||||
|
{
|
||||||
if(!soundOffFlag)
|
if(!soundOffFlag)
|
||||||
soundShutdown();
|
soundShutdown();
|
||||||
soundQuality = quality;
|
soundQuality = quality;
|
||||||
@ -1295,7 +1418,9 @@ void soundSetQuality(int quality)
|
|||||||
SOUND_CLOCK_TICKS = USE_TICKS_AS * soundQuality;
|
SOUND_CLOCK_TICKS = USE_TICKS_AS * soundQuality;
|
||||||
soundIndex = 0;
|
soundIndex = 0;
|
||||||
soundBufferIndex = 0;
|
soundBufferIndex = 0;
|
||||||
} else if(soundQuality != quality) {
|
}
|
||||||
|
else if(soundQuality != quality)
|
||||||
|
{
|
||||||
soundNextPosition = 0;
|
soundNextPosition = 0;
|
||||||
SOUND_CLOCK_TICKS = USE_TICKS_AS * soundQuality;
|
SOUND_CLOCK_TICKS = USE_TICKS_AS * soundQuality;
|
||||||
soundIndex = 0;
|
soundIndex = 0;
|
||||||
@ -1314,9 +1439,12 @@ void soundSaveGame(gzFile gzFile)
|
|||||||
void soundReadGame(gzFile gzFile, int version)
|
void soundReadGame(gzFile gzFile, int version)
|
||||||
{
|
{
|
||||||
utilReadData(gzFile, soundSaveStruct);
|
utilReadData(gzFile, soundSaveStruct);
|
||||||
if(version >= SAVE_GAME_VERSION_3) {
|
if(version >= SAVE_GAME_VERSION_3)
|
||||||
|
{
|
||||||
utilReadData(gzFile, soundSaveStructV2);
|
utilReadData(gzFile, soundSaveStructV2);
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
sound3Bank = (ioMem[NR30] >> 6) & 1;
|
sound3Bank = (ioMem[NR30] >> 6) & 1;
|
||||||
sound3DataSize = (ioMem[NR30] >> 5) & 1;
|
sound3DataSize = (ioMem[NR30] >> 5) & 1;
|
||||||
sound3ForcedOutput = (ioMem[NR32] >> 7) & 1;
|
sound3ForcedOutput = (ioMem[NR32] >> 7) & 1;
|
||||||
|
@ -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;
|
||||||
|
@ -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)
|
||||||
{
|
{
|
||||||
|
@ -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
|
||||||
|
@ -20,31 +20,34 @@
|
|||||||
#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
|
||||||
|
typedef unsigned __int64 u64;
|
||||||
|
#else
|
||||||
|
typedef unsigned long long u64;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef signed char s8;
|
||||||
|
typedef signed short s16;
|
||||||
|
typedef signed int s32;
|
||||||
|
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
typedef signed __int64 s64;
|
||||||
|
#else
|
||||||
|
typedef signed long long s64;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
struct EmulatedSystem
|
||||||
|
{
|
||||||
// main emulation function
|
// main emulation function
|
||||||
void (*emuMain)(int);
|
void (*emuMain)(int);
|
||||||
// reset emulator
|
// reset emulator
|
||||||
@ -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
180
source/vba/Text.cpp
Normal file
@ -0,0 +1,180 @@
|
|||||||
|
/* FCE Ultra - NES/Famicom Emulator
|
||||||
|
*
|
||||||
|
* Copyright notice for this file:
|
||||||
|
* Copyright (C) 2002 Ben Parnell
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Code originally from fceu/drawing.h file, adapted by Forgotten
|
||||||
|
*/
|
||||||
|
#include "System.h"
|
||||||
|
|
||||||
|
extern int RGB_LOW_BITS_MASK;
|
||||||
|
|
||||||
|
static const u8 fontdata2[2048] =
|
||||||
|
{
|
||||||
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7e,0x81,0xa5,0x81,0xbd,0x99,0x81,0x7e,0x7e,0xff,0xdb,0xff,0xc3,0xe7,0xff,0x7e,0x36,0x7f,0x7f,0x7f,0x3e,0x1c,0x08,0x00,0x08,0x1c,0x3e,0x7f,0x3e,0x1c,0x08,0x00,0x1c,0x3e,0x1c,0x7f,0x7f,0x3e,0x1c,0x3e,0x08,0x08,0x1c,0x3e,0x7f,0x3e,0x1c,0x3e,0x00,0x00,0x18,0x3c,0x3c,0x18,0x00,0x00,0xff,0xff,0xe7,0xc3,0xc3,0xe7,0xff,0xff,0x00,0x3c,0x66,0x42,0x42,0x66,0x3c,0x00,0xff,0xc3,0x99,0xbd,0xbd,0x99,0xc3,0xff,0xf0,0xe0,0xf0,0xbe,0x33,0x33,0x33,0x1e,0x3c,0x66,0x66,0x66,0x3c,0x18,0x7e,0x18,0xfc,0xcc,0xfc,0x0c,0x0c,0x0e,0x0f,0x07,0xfe,0xc6,0xfe,0xc6,0xc6,0xe6,0x67,0x03,0x99,0x5a,0x3c,0xe7,0xe7,0x3c,0x5a,0x99,0x01,0x07,0x1f,0x7f,0x1f,0x07,0x01,0x00,0x40,0x70,0x7c,0x7f,0x7c,0x70,0x40,0x00,0x18,0x3c,0x7e,0x18,0x18,0x7e,0x3c,0x18,0x66,0x66,0x66,0x66,0x66,0x00,0x66,0x00,0xfe,0xdb,0xdb,0xde,0xd8,0xd8,0xd8,0x00,0x7c,0xc6,0x1c,0x36,0x36,0x1c,0x33,0x1e,0x00,0x00,0x00,0x00,0x7e,0x7e,0x7e,0x00,0x18,0x3c,0x7e,0x18,0x7e,0x3c,0x18,0xff,0x18,0x3c,0x7e,0x18,0x18,0x18,0x18,0x00,0x18,0x18,0x18,0x18,0x7e,0x3c,0x18,0x00,0x00,0x18,0x30,0x7f,0x30,0x18,0x00,0x00,0x00,0x0c,0x06,0x7f,0x06,0x0c,0x00,0x00,0x00,0x00,0x03,0x03,0x03,0x7f,0x00,0x00,0x00,0x24,0x66,0xff,0x66,0x24,0x00,0x00,0x00,0x18,0x3c,0x7e,0xff,0xff,0x00,0x00,0x00,0xff,0xff,0x7e,0x3c,0x18,0x00,0x00,
|
||||||
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0c,0x1e,0x1e,0x0c,0x0c,0x00,0x0c,0x00,0x36,0x36,0x36,0x00,0x00,0x00,0x00,0x00,0x36,0x36,0x7f,0x36,0x7f,0x36,0x36,0x00,0x0c,0x3e,0x03,0x1e,0x30,0x1f,0x0c,0x00,0x00,0x63,0x33,0x18,0x0c,0x66,0x63,0x00,0x1c,0x36,0x1c,0x6e,0x3b,0x33,0x6e,0x00,0x06,0x06,0x03,0x00,0x00,0x00,0x00,0x00,0x18,0x0c,0x06,0x06,0x06,0x0c,0x18,0x00,0x06,0x0c,0x18,0x18,0x18,0x0c,0x06,0x00,0x00,0x66,0x3c,0xff,0x3c,0x66,0x00,0x00,0x00,0x0c,0x0c,0x3f,0x0c,0x0c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0c,0x0c,0x06,0x00,0x00,0x00,0x3f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0c,0x0c,0x00,0x60,0x30,0x18,0x0c,0x06,0x03,0x01,0x00,0x3e,0x63,0x73,0x7b,0x6f,0x67,0x3e,0x00,0x0c,0x0e,0x0c,0x0c,0x0c,0x0c,0x3f,0x00,0x1e,0x33,0x30,0x1c,0x06,0x33,0x3f,0x00,0x1e,0x33,0x30,0x1c,0x30,0x33,0x1e,0x00,0x38,0x3c,0x36,0x33,0x7f,0x30,0x78,0x00,0x3f,0x03,0x1f,0x30,0x30,0x33,0x1e,0x00,0x1c,0x06,0x03,0x1f,0x33,0x33,0x1e,0x00,0x3f,0x33,0x30,0x18,0x0c,0x0c,0x0c,0x00,0x1e,0x33,0x33,0x1e,0x33,0x33,0x1e,0x00,0x1e,0x33,0x33,0x3e,0x30,0x18,0x0e,0x00,0x00,0x0c,0x0c,0x00,0x00,0x0c,0x0c,0x00,0x00,0x0c,0x0c,0x00,0x00,0x0c,0x0c,0x06,0x18,0x0c,0x06,0x03,0x06,0x0c,0x18,0x00,0x00,0x00,0x3f,0x00,0x00,0x3f,0x00,0x00,0x06,0x0c,0x18,0x30,0x18,0x0c,0x06,0x00,0x1e,0x33,0x30,0x18,0x0c,0x00,0x0c,0x00,
|
||||||
|
0x3e,0x63,0x7b,0x7b,0x7b,0x03,0x1e,0x00,0x0c,0x1e,0x33,0x33,0x3f,0x33,0x33,0x00,0x3f,0x66,0x66,0x3e,0x66,0x66,0x3f,0x00,0x3c,0x66,0x03,0x03,0x03,0x66,0x3c,0x00,0x1f,0x36,0x66,0x66,0x66,0x36,0x1f,0x00,0x7f,0x46,0x16,0x1e,0x16,0x46,0x7f,0x00,0x7f,0x46,0x16,0x1e,0x16,0x06,0x0f,0x00,0x3c,0x66,0x03,0x03,0x73,0x66,0x7c,0x00,0x33,0x33,0x33,0x3f,0x33,0x33,0x33,0x00,0x1e,0x0c,0x0c,0x0c,0x0c,0x0c,0x1e,0x00,0x78,0x30,0x30,0x30,0x33,0x33,0x1e,0x00,0x67,0x66,0x36,0x1e,0x36,0x66,0x67,0x00,0x0f,0x06,0x06,0x06,0x46,0x66,0x7f,0x00,0x63,0x77,0x7f,0x7f,0x6b,0x63,0x63,0x00,0x63,0x67,0x6f,0x7b,0x73,0x63,0x63,0x00,0x1c,0x36,0x63,0x63,0x63,0x36,0x1c,0x00,0x3f,0x66,0x66,0x3e,0x06,0x06,0x0f,0x00,0x1e,0x33,0x33,0x33,0x3b,0x1e,0x38,0x00,0x3f,0x66,0x66,0x3e,0x36,0x66,0x67,0x00,0x1e,0x33,0x07,0x0e,0x38,0x33,0x1e,0x00,0x3f,0x2d,0x0c,0x0c,0x0c,0x0c,0x1e,0x00,0x33,0x33,0x33,0x33,0x33,0x33,0x3f,0x00,0x33,0x33,0x33,0x33,0x33,0x1e,0x0c,0x00,0x63,0x63,0x63,0x6b,0x7f,0x77,0x63,0x00,0x63,0x63,0x36,0x1c,0x1c,0x36,0x63,0x00,0x33,0x33,0x33,0x1e,0x0c,0x0c,0x1e,0x00,0x7f,0x63,0x31,0x18,0x4c,0x66,0x7f,0x00,0x1e,0x06,0x06,0x06,0x06,0x06,0x1e,0x00,0x03,0x06,0x0c,0x18,0x30,0x60,0x40,0x00,0x1e,0x18,0x18,0x18,0x18,0x18,0x1e,0x00,0x08,0x1c,0x36,0x63,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,
|
||||||
|
0x0c,0x0c,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1e,0x30,0x3e,0x33,0x6e,0x00,0x07,0x06,0x06,0x3e,0x66,0x66,0x3b,0x00,0x00,0x00,0x1e,0x33,0x03,0x33,0x1e,0x00,0x38,0x30,0x30,0x3e,0x33,0x33,0x6e,0x00,0x00,0x00,0x1e,0x33,0x3f,0x03,0x1e,0x00,0x1c,0x36,0x06,0x0f,0x06,0x06,0x0f,0x00,0x00,0x00,0x6e,0x33,0x33,0x3e,0x30,0x1f,0x07,0x06,0x36,0x6e,0x66,0x66,0x67,0x00,0x0c,0x00,0x0e,0x0c,0x0c,0x0c,0x1e,0x00,0x30,0x00,0x30,0x30,0x30,0x33,0x33,0x1e,0x07,0x06,0x66,0x36,0x1e,0x36,0x67,0x00,0x0e,0x0c,0x0c,0x0c,0x0c,0x0c,0x1e,0x00,0x00,0x00,0x33,0x7f,0x7f,0x6b,0x63,0x00,0x00,0x00,0x1f,0x33,0x33,0x33,0x33,0x00,0x00,0x00,0x1e,0x33,0x33,0x33,0x1e,0x00,0x00,0x00,0x3b,0x66,0x66,0x3e,0x06,0x0f,0x00,0x00,0x6e,0x33,0x33,0x3e,0x30,0x78,0x00,0x00,0x3b,0x6e,0x66,0x06,0x0f,0x00,0x00,0x00,0x3e,0x03,0x1e,0x30,0x1f,0x00,0x08,0x0c,0x3e,0x0c,0x0c,0x2c,0x18,0x00,0x00,0x00,0x33,0x33,0x33,0x33,0x6e,0x00,0x00,0x00,0x33,0x33,0x33,0x1e,0x0c,0x00,0x00,0x00,0x63,0x6b,0x7f,0x7f,0x36,0x00,0x00,0x00,0x63,0x36,0x1c,0x36,0x63,0x00,0x00,0x00,0x33,0x33,0x33,0x3e,0x30,0x1f,0x00,0x00,0x3f,0x19,0x0c,0x26,0x3f,0x00,0x38,0x0c,0x0c,0x07,0x0c,0x0c,0x38,0x00,0x18,0x18,0x18,0x00,0x18,0x18,0x18,0x00,0x07,0x0c,0x0c,0x38,0x0c,0x0c,0x07,0x00,0x6e,0x3b,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x1c,0x36,0x63,0x63,0x7f,0x00,
|
||||||
|
0x1e,0x33,0x03,0x33,0x1e,0x18,0x30,0x1e,0x00,0x33,0x00,0x33,0x33,0x33,0x7e,0x00,0x38,0x00,0x1e,0x33,0x3f,0x03,0x1e,0x00,0x7e,0xc3,0x3c,0x60,0x7c,0x66,0xfc,0x00,0x33,0x00,0x1e,0x30,0x3e,0x33,0x7e,0x00,0x07,0x00,0x1e,0x30,0x3e,0x33,0x7e,0x00,0x0c,0x0c,0x1e,0x30,0x3e,0x33,0x7e,0x00,0x00,0x00,0x1e,0x03,0x03,0x1e,0x30,0x1c,0x7e,0xc3,0x3c,0x66,0x7e,0x06,0x3c,0x00,0x33,0x00,0x1e,0x33,0x3f,0x03,0x1e,0x00,0x07,0x00,0x1e,0x33,0x3f,0x03,0x1e,0x00,0x33,0x00,0x0e,0x0c,0x0c,0x0c,0x1e,0x00,0x3e,0x63,0x1c,0x18,0x18,0x18,0x3c,0x00,0x07,0x00,0x0e,0x0c,0x0c,0x0c,0x1e,0x00,0x63,0x1c,0x36,0x63,0x7f,0x63,0x63,0x00,0x0c,0x0c,0x00,0x1e,0x33,0x3f,0x33,0x00,0x38,0x00,0x3f,0x06,0x1e,0x06,0x3f,0x00,0x00,0x00,0xfe,0x30,0xfe,0x33,0xfe,0x00,0x7c,0x36,0x33,0x7f,0x33,0x33,0x73,0x00,0x1e,0x33,0x00,0x1e,0x33,0x33,0x1e,0x00,0x00,0x33,0x00,0x1e,0x33,0x33,0x1e,0x00,0x00,0x07,0x00,0x1e,0x33,0x33,0x1e,0x00,0x1e,0x33,0x00,0x33,0x33,0x33,0x7e,0x00,0x00,0x07,0x00,0x33,0x33,0x33,0x7e,0x00,0x00,0x33,0x00,0x33,0x33,0x3e,0x30,0x1f,0xc3,0x18,0x3c,0x66,0x66,0x3c,0x18,0x00,0x33,0x00,0x33,0x33,0x33,0x33,0x1e,0x00,0x18,0x18,0x7e,0x03,0x03,0x7e,0x18,0x18,0x1c,0x36,0x26,0x0f,0x06,0x67,0x3f,0x00,0x33,0x33,0x1e,0x3f,0x0c,0x3f,0x0c,0x0c,0x1f,0x33,0x33,0x5f,0x63,0xf3,0x63,0xe3,0x70,0xd8,0x18,0x3c,0x18,0x18,0x1b,0x0e,
|
||||||
|
0x38,0x00,0x1e,0x30,0x3e,0x33,0x7e,0x00,0x1c,0x00,0x0e,0x0c,0x0c,0x0c,0x1e,0x00,0x00,0x38,0x00,0x1e,0x33,0x33,0x1e,0x00,0x00,0x38,0x00,0x33,0x33,0x33,0x7e,0x00,0x00,0x1f,0x00,0x1f,0x33,0x33,0x33,0x00,0x3f,0x00,0x33,0x37,0x3f,0x3b,0x33,0x00,0x3c,0x36,0x36,0x7c,0x00,0x7e,0x00,0x00,0x1c,0x36,0x36,0x1c,0x00,0x3e,0x00,0x00,0x0c,0x00,0x0c,0x06,0x03,0x33,0x1e,0x00,0x00,0x00,0x00,0x3f,0x03,0x03,0x00,0x00,0x00,0x00,0x00,0x3f,0x30,0x30,0x00,0x00,0xc3,0x63,0x33,0x7b,0xcc,0x66,0x33,0xf0,0xc3,0x63,0x33,0xdb,0xec,0xf6,0xf3,0xc0,0x18,0x18,0x00,0x18,0x18,0x18,0x18,0x00,0x00,0xcc,0x66,0x33,0x66,0xcc,0x00,0x00,0x00,0x33,0x66,0xcc,0x66,0x33,0x00,0x00,0x44,0x11,0x44,0x11,0x44,0x11,0x44,0x11,0xaa,0x55,0xaa,0x55,0xaa,0x55,0xaa,0x55,0xdb,0xee,0xdb,0x77,0xdb,0xee,0xdb,0x77,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x1f,0x18,0x18,0x18,0x18,0x18,0x1f,0x18,0x1f,0x18,0x18,0x18,0x6c,0x6c,0x6c,0x6c,0x6f,0x6c,0x6c,0x6c,0x00,0x00,0x00,0x00,0x7f,0x6c,0x6c,0x6c,0x00,0x00,0x1f,0x18,0x1f,0x18,0x18,0x18,0x6c,0x6c,0x6f,0x60,0x6f,0x6c,0x6c,0x6c,0x6c,0x6c,0x6c,0x6c,0x6c,0x6c,0x6c,0x6c,0x00,0x00,0x7f,0x60,0x6f,0x6c,0x6c,0x6c,0x6c,0x6c,0x6f,0x60,0x7f,0x00,0x00,0x00,0x6c,0x6c,0x6c,0x6c,0x7f,0x00,0x00,0x00,0x18,0x18,0x1f,0x18,0x1f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1f,0x18,0x18,0x18,
|
||||||
|
0x18,0x18,0x18,0x18,0xf8,0x00,0x00,0x00,0x18,0x18,0x18,0x18,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0xf8,0x18,0x18,0x18,0x00,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0x18,0x18,0x18,0x18,0xff,0x18,0x18,0x18,0x18,0x18,0xf8,0x18,0xf8,0x18,0x18,0x18,0x6c,0x6c,0x6c,0x6c,0xec,0x6c,0x6c,0x6c,0x6c,0x6c,0xec,0x0c,0xfc,0x00,0x00,0x00,0x00,0x00,0xfc,0x0c,0xec,0x6c,0x6c,0x6c,0x6c,0x6c,0xef,0x00,0xff,0x00,0x00,0x00,0x00,0x00,0xff,0x00,0xef,0x6c,0x6c,0x6c,0x6c,0x6c,0xec,0x0c,0xec,0x6c,0x6c,0x6c,0x00,0x00,0xff,0x00,0xff,0x00,0x00,0x00,0x6c,0x6c,0xef,0x00,0xef,0x6c,0x6c,0x6c,0x18,0x18,0xff,0x00,0xff,0x00,0x00,0x00,0x6c,0x6c,0x6c,0x6c,0xff,0x00,0x00,0x00,0x00,0x00,0xff,0x00,0xff,0x18,0x18,0x18,0x00,0x00,0x00,0x00,0xff,0x6c,0x6c,0x6c,0x6c,0x6c,0x6c,0x6c,0xfc,0x00,0x00,0x00,0x18,0x18,0xf8,0x18,0xf8,0x00,0x00,0x00,0x00,0x00,0xf8,0x18,0xf8,0x18,0x18,0x18,0x00,0x00,0x00,0x00,0xfc,0x6c,0x6c,0x6c,0x6c,0x6c,0x6c,0x6c,0xff,0x6c,0x6c,0x6c,0x18,0x18,0xff,0x18,0xff,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x1f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf8,0x18,0x18,0x18,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,
|
||||||
|
0x00,0x00,0x6e,0x3b,0x13,0x3b,0x6e,0x00,0x00,0x1e,0x33,0x1f,0x33,0x1f,0x03,0x03,0x00,0x3f,0x33,0x03,0x03,0x03,0x03,0x00,0x00,0x7f,0x36,0x36,0x36,0x36,0x36,0x00,0x3f,0x33,0x06,0x0c,0x06,0x33,0x3f,0x00,0x00,0x00,0x7e,0x1b,0x1b,0x1b,0x0e,0x00,0x00,0x66,0x66,0x66,0x66,0x3e,0x06,0x03,0x00,0x6e,0x3b,0x18,0x18,0x18,0x18,0x00,0x3f,0x0c,0x1e,0x33,0x33,0x1e,0x0c,0x3f,0x1c,0x36,0x63,0x7f,0x63,0x36,0x1c,0x00,0x1c,0x36,0x63,0x63,0x36,0x36,0x77,0x00,0x38,0x0c,0x18,0x3e,0x33,0x33,0x1e,0x00,0x00,0x00,0x7e,0xdb,0xdb,0x7e,0x00,0x00,0x60,0x30,0x7e,0xdb,0xdb,0x7e,0x06,0x03,0x1c,0x06,0x03,0x1f,0x03,0x06,0x1c,0x00,0x1e,0x33,0x33,0x33,0x33,0x33,0x33,0x00,0x00,0x3f,0x00,0x3f,0x00,0x3f,0x00,0x00,0x0c,0x0c,0x3f,0x0c,0x0c,0x00,0x3f,0x00,0x06,0x0c,0x18,0x0c,0x06,0x00,0x3f,0x00,0x18,0x0c,0x06,0x0c,0x18,0x00,0x3f,0x00,0x70,0xd8,0xd8,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x1b,0x1b,0x0e,0x0c,0x0c,0x00,0x3f,0x00,0x0c,0x0c,0x00,0x00,0x6e,0x3b,0x00,0x6e,0x3b,0x00,0x00,0x1c,0x36,0x36,0x1c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x00,0x00,0x00,0xf0,0x30,0x30,0x30,0x37,0x36,0x3c,0x38,0x1e,0x36,0x36,0x36,0x36,0x00,0x00,0x00,0x0e,0x18,0x0c,0x06,0x1e,0x00,0x00,0x00,0x00,0x00,0x3c,0x3c,0x3c,0x3c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
|
||||||
|
};
|
||||||
|
|
||||||
|
static void drawTextInternal(u8 *screen, int pitch, int x, int y,
|
||||||
|
const char *string, bool trans)
|
||||||
|
{
|
||||||
|
screen += y*pitch;
|
||||||
|
int inc = 2;
|
||||||
|
switch(systemColorDepth)
|
||||||
|
{
|
||||||
|
case 24:
|
||||||
|
inc = 3;
|
||||||
|
break;
|
||||||
|
case 32:
|
||||||
|
inc = 4;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
screen += x*inc;
|
||||||
|
|
||||||
|
switch(systemColorDepth)
|
||||||
|
{
|
||||||
|
case 16:
|
||||||
|
{
|
||||||
|
while(*string)
|
||||||
|
{
|
||||||
|
char c = *string++;
|
||||||
|
u8 *scr = screen;
|
||||||
|
|
||||||
|
u16 mask = ~RGB_LOW_BITS_MASK;
|
||||||
|
int h, w;
|
||||||
|
u16 *s = (u16 *)scr;
|
||||||
|
for (h = 0; h < 8; h++)
|
||||||
|
{
|
||||||
|
for (w = 0; w < 8; w++, s++)
|
||||||
|
{
|
||||||
|
int on = (fontdata2[(c<<3)+h]>>w)&1;
|
||||||
|
|
||||||
|
if(trans)
|
||||||
|
{
|
||||||
|
if(on)
|
||||||
|
*s = ((0xf) << systemRedShift) +
|
||||||
|
((*s & mask) >>1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(on)
|
||||||
|
*s = (0x1f) << systemRedShift;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
scr += pitch;
|
||||||
|
s = (u16 *)scr;
|
||||||
|
}
|
||||||
|
screen += inc*8;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 24:
|
||||||
|
{
|
||||||
|
while(*string)
|
||||||
|
{
|
||||||
|
char c = *string++;
|
||||||
|
u8 *scr = screen;
|
||||||
|
|
||||||
|
int h, w;
|
||||||
|
u8 *s = (u8 *)scr;
|
||||||
|
for (h = 0; h < 8; h++)
|
||||||
|
{
|
||||||
|
for (w = 0; w < 8; w++, s+=3)
|
||||||
|
{
|
||||||
|
int on = (fontdata2[(c<<3)+h]>>w)&1;
|
||||||
|
|
||||||
|
if(trans)
|
||||||
|
{
|
||||||
|
if(on)
|
||||||
|
{
|
||||||
|
u32 color = (0x1f) << systemRedShift;
|
||||||
|
*s = ((color & 255)>>1)+(*s>>1);
|
||||||
|
*(s+1) = (((color >> 8) & 255)>>1)+(*(s+1)>>1);
|
||||||
|
*(s+2) = (((color >> 16) & 255)>>1)+(*(s+2)>>1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(on)
|
||||||
|
{
|
||||||
|
u32 color = (0x1f) << systemRedShift;
|
||||||
|
*s = (color & 255);
|
||||||
|
*(s+1) = (color >> 8) & 255;
|
||||||
|
*(s+2) = (color >> 16) & 255;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
scr += pitch;
|
||||||
|
s = (u8 *)scr;
|
||||||
|
}
|
||||||
|
screen += inc*8;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 32:
|
||||||
|
{
|
||||||
|
while(*string)
|
||||||
|
{
|
||||||
|
char c = *string++;
|
||||||
|
u8 *scr = screen;
|
||||||
|
|
||||||
|
int h, w;
|
||||||
|
u32 mask = 0xfefefe;
|
||||||
|
u32 *s = (u32 *)scr;
|
||||||
|
for (h = 0; h < 8; h++)
|
||||||
|
{
|
||||||
|
for (w = 0; w < 8; w++, s++)
|
||||||
|
{
|
||||||
|
int on = (fontdata2[(c<<3)+h]>>w)&1;
|
||||||
|
|
||||||
|
if(trans)
|
||||||
|
{
|
||||||
|
if(on)
|
||||||
|
*s = ((0xf) << systemRedShift) + ((*s & mask)>>1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(on)
|
||||||
|
*s = (0x1f) << systemRedShift;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
scr += pitch;
|
||||||
|
s = (u32 *)scr;
|
||||||
|
}
|
||||||
|
screen += inc*8;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void drawText(u8 *screen, int pitch, int x, int y, const char *string)
|
||||||
|
{
|
||||||
|
drawTextInternal(screen, pitch, x, y, string, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
void drawTextTransp(u8 *screen, int pitch, int x, int y, const char *string)
|
||||||
|
{
|
||||||
|
drawTextInternal(screen, pitch, x, y, string, true);
|
||||||
|
}
|
21
source/vba/Text.h
Normal file
21
source/vba/Text.h
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
// -*- C++ -*-
|
||||||
|
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
|
||||||
|
// Copyright (C) 1999-2003 Forgotten
|
||||||
|
// Copyright (C) 2004 Forgotten and the VBA development team
|
||||||
|
|
||||||
|
// This program is free software; you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation; either version 2, or(at your option)
|
||||||
|
// any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with this program; if not, write to the Free Software Foundation,
|
||||||
|
// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
|
extern void drawText(u8 *, int, int, int, const char *);
|
||||||
|
extern void drawTextTransp(u8 *, int, int, int, const char *);
|
File diff suppressed because it is too large
Load Diff
@ -19,9 +19,6 @@
|
|||||||
|
|
||||||
#ifndef VBA_UTIL_H
|
#ifndef VBA_UTIL_H
|
||||||
#define VBA_UTIL_H
|
#define VBA_UTIL_H
|
||||||
|
|
||||||
#include "System.h"
|
|
||||||
|
|
||||||
enum IMAGE_TYPE {
|
enum IMAGE_TYPE {
|
||||||
IMAGE_UNKNOWN = -1,
|
IMAGE_UNKNOWN = -1,
|
||||||
IMAGE_GBA = 0,
|
IMAGE_GBA = 0,
|
||||||
@ -30,20 +27,23 @@ enum IMAGE_TYPE {
|
|||||||
|
|
||||||
// save game
|
// save game
|
||||||
|
|
||||||
typedef struct {
|
typedef struct
|
||||||
|
{
|
||||||
void *address;
|
void *address;
|
||||||
int size;
|
int size;
|
||||||
} variable_desc;
|
}
|
||||||
|
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*),
|
||||||
@ -54,16 +54,13 @@ extern void utilPutDword(u8 *, u32);
|
|||||||
extern void utilPutWord(u8 *, u16);
|
extern void utilPutWord(u8 *, u16);
|
||||||
extern void utilWriteData(gzFile, variable_desc *);
|
extern void utilWriteData(gzFile, variable_desc *);
|
||||||
extern void utilReadData(gzFile, variable_desc *);
|
extern void utilReadData(gzFile, variable_desc *);
|
||||||
extern void utilReadDataSkip(gzFile, variable_desc *);
|
|
||||||
extern int utilReadInt(gzFile);
|
extern int utilReadInt(gzFile);
|
||||||
extern void utilWriteInt(gzFile, int);
|
extern void utilWriteInt(gzFile, int);
|
||||||
extern gzFile utilGzOpen(const char *file, const char *mode);
|
extern gzFile utilGzOpen(const char *file, const char *mode);
|
||||||
extern gzFile utilMemGzOpen(char *memory, int available, const char *mode);
|
extern gzFile utilMemGzOpen(char *memory, int available, char *mode);
|
||||||
extern int utilGzWrite(gzFile file, const voidp buffer, unsigned int len);
|
extern int utilGzWrite(gzFile file, const voidp buffer, unsigned int len);
|
||||||
extern int utilGzRead(gzFile file, voidp buffer, unsigned int len);
|
extern int utilGzRead(gzFile file, voidp buffer, unsigned int len);
|
||||||
extern int utilGzClose(gzFile file);
|
extern int utilGzClose(gzFile file);
|
||||||
extern z_off_t utilGzSeek(gzFile file, z_off_t offset, int whence);
|
|
||||||
extern long utilGzMemTell(gzFile file);
|
extern long utilGzMemTell(gzFile file);
|
||||||
extern void utilGBAFindSave(const u8 *, const int);
|
extern void utilGBAFindSave(const u8 *, const int);
|
||||||
extern void utilUpdateSystemColorMaps();
|
|
||||||
#endif
|
#endif
|
||||||
|
1033
source/vba/admame.cpp
Normal file
1033
source/vba/admame.cpp
Normal file
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -1,302 +0,0 @@
|
|||||||
// -*- C++ -*-
|
|
||||||
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
|
|
||||||
// Copyright (C) 1999-2003 Forgotten
|
|
||||||
// Copyright (C) 2005 Forgotten and the VBA development team
|
|
||||||
|
|
||||||
// This program is free software; you can redistribute it and/or modify
|
|
||||||
// it under the terms of the GNU General Public License as published by
|
|
||||||
// the Free Software Foundation; either version 2, or(at your option)
|
|
||||||
// any later version.
|
|
||||||
//
|
|
||||||
// This program is distributed in the hope that it will be useful,
|
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
// GNU General Public License for more details.
|
|
||||||
//
|
|
||||||
// You should have received a copy of the GNU General Public License
|
|
||||||
// along with this program; if not, write to the Free Software Foundation,
|
|
||||||
// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
||||||
|
|
||||||
#ifndef VBA_GBAcpu_H
|
|
||||||
#define VBA_GBAcpu_H
|
|
||||||
|
|
||||||
extern int armExecute();
|
|
||||||
extern int thumbExecute();
|
|
||||||
|
|
||||||
#ifdef __GNUC__
|
|
||||||
# define INSN_REGPARM __attribute__((regparm(1)))
|
|
||||||
# define LIKELY(x) __builtin_expect(!!(x),1)
|
|
||||||
# define UNLIKELY(x) __builtin_expect(!!(x),0)
|
|
||||||
#else
|
|
||||||
# define INSN_REGPARM /*nothing*/
|
|
||||||
# define LIKELY(x) (x)
|
|
||||||
# define UNLIKELY(x) (x)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define UPDATE_REG(address, value)\
|
|
||||||
{\
|
|
||||||
WRITE16LE(((u16 *)&ioMem[address]),value);\
|
|
||||||
}\
|
|
||||||
|
|
||||||
#define ARM_PREFETCH \
|
|
||||||
{\
|
|
||||||
cpuPrefetch[0] = CPUReadMemoryQuick(armNextPC);\
|
|
||||||
cpuPrefetch[1] = CPUReadMemoryQuick(armNextPC+4);\
|
|
||||||
}
|
|
||||||
|
|
||||||
#define THUMB_PREFETCH \
|
|
||||||
{\
|
|
||||||
cpuPrefetch[0] = CPUReadHalfWordQuick(armNextPC);\
|
|
||||||
cpuPrefetch[1] = CPUReadHalfWordQuick(armNextPC+2);\
|
|
||||||
}
|
|
||||||
|
|
||||||
#define ARM_PREFETCH_NEXT \
|
|
||||||
cpuPrefetch[1] = CPUReadMemoryQuick(armNextPC+4);
|
|
||||||
|
|
||||||
#define THUMB_PREFETCH_NEXT\
|
|
||||||
cpuPrefetch[1] = CPUReadHalfWordQuick(armNextPC+2);
|
|
||||||
|
|
||||||
|
|
||||||
extern int SWITicks;
|
|
||||||
extern u32 mastercode;
|
|
||||||
extern bool busPrefetch;
|
|
||||||
extern bool busPrefetchEnable;
|
|
||||||
extern u32 busPrefetchCount;
|
|
||||||
extern int cpuNextEvent;
|
|
||||||
extern bool holdState;
|
|
||||||
extern u32 cpuPrefetch[2];
|
|
||||||
extern int cpuTotalTicks;
|
|
||||||
extern u8 memoryWait[16];
|
|
||||||
extern u8 memoryWait32[16];
|
|
||||||
extern u8 memoryWaitSeq[16];
|
|
||||||
extern u8 memoryWaitSeq32[16];
|
|
||||||
extern u8 cpuBitsSet[256];
|
|
||||||
extern u8 cpuLowestBitSet[256];
|
|
||||||
extern void CPUSwitchMode(int mode, bool saveState, bool breakLoop);
|
|
||||||
extern void CPUSwitchMode(int mode, bool saveState);
|
|
||||||
extern void CPUUpdateCPSR();
|
|
||||||
extern void CPUUpdateFlags(bool breakLoop);
|
|
||||||
extern void CPUUpdateFlags();
|
|
||||||
extern void CPUUndefinedException();
|
|
||||||
extern void CPUSoftwareInterrupt();
|
|
||||||
extern void CPUSoftwareInterrupt(int comment);
|
|
||||||
|
|
||||||
|
|
||||||
// Waitstates when accessing data
|
|
||||||
inline int dataTicksAccess16(u32 address) // DATA 8/16bits NON SEQ
|
|
||||||
{
|
|
||||||
int addr = (address>>24)&15;
|
|
||||||
int value = memoryWait[addr];
|
|
||||||
|
|
||||||
if ((addr>=0x08) || (addr < 0x02))
|
|
||||||
{
|
|
||||||
busPrefetchCount=0;
|
|
||||||
busPrefetch=false;
|
|
||||||
}
|
|
||||||
else if (busPrefetch)
|
|
||||||
{
|
|
||||||
int waitState = value;
|
|
||||||
if (!waitState)
|
|
||||||
waitState = 1;
|
|
||||||
busPrefetchCount = ((busPrefetchCount+1)<<waitState) - 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline int dataTicksAccess32(u32 address) // DATA 32bits NON SEQ
|
|
||||||
{
|
|
||||||
int addr = (address>>24)&15;
|
|
||||||
int value = memoryWait32[addr];
|
|
||||||
|
|
||||||
if ((addr>=0x08) || (addr < 0x02))
|
|
||||||
{
|
|
||||||
busPrefetchCount=0;
|
|
||||||
busPrefetch=false;
|
|
||||||
}
|
|
||||||
else if (busPrefetch)
|
|
||||||
{
|
|
||||||
int waitState = value;
|
|
||||||
if (!waitState)
|
|
||||||
waitState = 1;
|
|
||||||
busPrefetchCount = ((busPrefetchCount+1)<<waitState) - 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline int dataTicksAccessSeq16(u32 address)// DATA 8/16bits SEQ
|
|
||||||
{
|
|
||||||
int addr = (address>>24)&15;
|
|
||||||
int value = memoryWaitSeq[addr];
|
|
||||||
|
|
||||||
if ((addr>=0x08) || (addr < 0x02))
|
|
||||||
{
|
|
||||||
busPrefetchCount=0;
|
|
||||||
busPrefetch=false;
|
|
||||||
}
|
|
||||||
else if (busPrefetch)
|
|
||||||
{
|
|
||||||
int waitState = value;
|
|
||||||
if (!waitState)
|
|
||||||
waitState = 1;
|
|
||||||
busPrefetchCount = ((busPrefetchCount+1)<<waitState) - 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline int dataTicksAccessSeq32(u32 address)// DATA 32bits SEQ
|
|
||||||
{
|
|
||||||
int addr = (address>>24)&15;
|
|
||||||
int value = memoryWaitSeq32[addr];
|
|
||||||
|
|
||||||
if ((addr>=0x08) || (addr < 0x02))
|
|
||||||
{
|
|
||||||
busPrefetchCount=0;
|
|
||||||
busPrefetch=false;
|
|
||||||
}
|
|
||||||
else if (busPrefetch)
|
|
||||||
{
|
|
||||||
int waitState = value;
|
|
||||||
if (!waitState)
|
|
||||||
waitState = 1;
|
|
||||||
busPrefetchCount = ((busPrefetchCount+1)<<waitState) - 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Waitstates when executing opcode
|
|
||||||
inline int codeTicksAccess16(u32 address) // THUMB NON SEQ
|
|
||||||
{
|
|
||||||
int addr = (address>>24)&15;
|
|
||||||
|
|
||||||
if ((addr>=0x08) && (addr<=0x0D))
|
|
||||||
{
|
|
||||||
if (busPrefetchCount&0x1)
|
|
||||||
{
|
|
||||||
if (busPrefetchCount&0x2)
|
|
||||||
{
|
|
||||||
busPrefetchCount = ((busPrefetchCount&0xFF)>>2) | (busPrefetchCount&0xFFFFFF00);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
busPrefetchCount = ((busPrefetchCount&0xFF)>>1) | (busPrefetchCount&0xFFFFFF00);
|
|
||||||
return memoryWaitSeq[addr]-1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
busPrefetchCount=0;
|
|
||||||
return memoryWait[addr];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
busPrefetchCount = 0;
|
|
||||||
return memoryWait[addr];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
inline int codeTicksAccess32(u32 address) // ARM NON SEQ
|
|
||||||
{
|
|
||||||
int addr = (address>>24)&15;
|
|
||||||
|
|
||||||
if ((addr>=0x08) && (addr<=0x0D))
|
|
||||||
{
|
|
||||||
if (busPrefetchCount&0x1)
|
|
||||||
{
|
|
||||||
if (busPrefetchCount&0x2)
|
|
||||||
{
|
|
||||||
busPrefetchCount = ((busPrefetchCount&0xFF)>>2) | (busPrefetchCount&0xFFFFFF00);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
busPrefetchCount = ((busPrefetchCount&0xFF)>>1) | (busPrefetchCount&0xFFFFFF00);
|
|
||||||
return memoryWaitSeq[addr] - 1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
busPrefetchCount = 0;
|
|
||||||
return memoryWait32[addr];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
busPrefetchCount = 0;
|
|
||||||
return memoryWait32[addr];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
inline int codeTicksAccessSeq16(u32 address) // THUMB SEQ
|
|
||||||
{
|
|
||||||
int addr = (address>>24)&15;
|
|
||||||
|
|
||||||
if ((addr>=0x08) && (addr<=0x0D))
|
|
||||||
{
|
|
||||||
if (busPrefetchCount&0x1)
|
|
||||||
{
|
|
||||||
busPrefetchCount = ((busPrefetchCount&0xFF)>>1) | (busPrefetchCount&0xFFFFFF00);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
if (busPrefetchCount>0xFF)
|
|
||||||
{
|
|
||||||
busPrefetchCount=0;
|
|
||||||
return memoryWait[addr];
|
|
||||||
}
|
|
||||||
else
|
|
||||||
return memoryWaitSeq[addr];
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
busPrefetchCount = 0;
|
|
||||||
return memoryWaitSeq[addr];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
inline int codeTicksAccessSeq32(u32 address) // ARM SEQ
|
|
||||||
{
|
|
||||||
int addr = (address>>24)&15;
|
|
||||||
|
|
||||||
if ((addr>=0x08) && (addr<=0x0D))
|
|
||||||
{
|
|
||||||
if (busPrefetchCount&0x1)
|
|
||||||
{
|
|
||||||
if (busPrefetchCount&0x2)
|
|
||||||
{
|
|
||||||
busPrefetchCount = ((busPrefetchCount&0xFF)>>2) | (busPrefetchCount&0xFFFFFF00);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
busPrefetchCount = ((busPrefetchCount&0xFF)>>1) | (busPrefetchCount&0xFFFFFF00);
|
|
||||||
return memoryWaitSeq[addr];
|
|
||||||
}
|
|
||||||
else
|
|
||||||
if (busPrefetchCount>0xFF)
|
|
||||||
{
|
|
||||||
busPrefetchCount=0;
|
|
||||||
return memoryWait32[addr];
|
|
||||||
}
|
|
||||||
else
|
|
||||||
return memoryWaitSeq32[addr];
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return memoryWaitSeq32[addr];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Emulates the Cheat System (m) code
|
|
||||||
inline void cpuMasterCodeCheck()
|
|
||||||
{
|
|
||||||
if((mastercode) && (mastercode == armNextPC))
|
|
||||||
{
|
|
||||||
u32 joy = 0;
|
|
||||||
if(systemReadJoypads())
|
|
||||||
joy = systemReadJoypad(-1);
|
|
||||||
u32 ext = (joy >> 10);
|
|
||||||
cpuTotalTicks += cheatsCheckKeys(P1^0x3FF, ext);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif //VBA_GBAcpu_H
|
|
@ -1,834 +0,0 @@
|
|||||||
// -*- C++ -*-
|
|
||||||
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
|
|
||||||
// Copyright (C) 1999-2003 Forgotten
|
|
||||||
// Copyright (C) 2005 Forgotten and the VBA development team
|
|
||||||
|
|
||||||
// This program is free software; you can redistribute it and/or modify
|
|
||||||
// it under the terms of the GNU General Public License as published by
|
|
||||||
// the Free Software Foundation; either version 2, or(at your option)
|
|
||||||
// any later version.
|
|
||||||
//
|
|
||||||
// This program is distributed in the hope that it will be useful,
|
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
// GNU General Public License for more details.
|
|
||||||
//
|
|
||||||
// You should have received a copy of the GNU General Public License
|
|
||||||
// along with this program; if not, write to the Free Software Foundation,
|
|
||||||
// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
||||||
|
|
||||||
#ifndef VBA_GBAinline_H
|
|
||||||
#define VBA_GBAinline_H
|
|
||||||
|
|
||||||
#include "../System.h"
|
|
||||||
#include "../Port.h"
|
|
||||||
#include "../RTC.h"
|
|
||||||
#include "../Sound.h"
|
|
||||||
#include "agbprint.h"
|
|
||||||
#include "vmmem.h" // Nintendo GC Virtual Memory
|
|
||||||
|
|
||||||
extern const u32 objTilesAddress[3];
|
|
||||||
|
|
||||||
extern bool stopState;
|
|
||||||
extern bool holdState;
|
|
||||||
extern int holdType;
|
|
||||||
extern int cpuNextEvent;
|
|
||||||
extern bool cpuSramEnabled;
|
|
||||||
extern bool cpuFlashEnabled;
|
|
||||||
extern bool cpuEEPROMEnabled;
|
|
||||||
extern bool cpuEEPROMSensorEnabled;
|
|
||||||
extern bool cpuDmaHack;
|
|
||||||
extern u32 cpuDmaLast;
|
|
||||||
extern bool timer0On;
|
|
||||||
extern int timer0Ticks;
|
|
||||||
extern int timer0ClockReload;
|
|
||||||
extern bool timer1On;
|
|
||||||
extern int timer1Ticks;
|
|
||||||
extern int timer1ClockReload;
|
|
||||||
extern bool timer2On;
|
|
||||||
extern int timer2Ticks;
|
|
||||||
extern int timer2ClockReload;
|
|
||||||
extern bool timer3On;
|
|
||||||
extern int timer3Ticks;
|
|
||||||
extern int timer3ClockReload;
|
|
||||||
extern int cpuTotalTicks;
|
|
||||||
|
|
||||||
/*****************************************************************************
|
|
||||||
* Nintendo GC Virtual Memory function override
|
|
||||||
* Tantric September 2008
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
#define CPUReadByteQuickDef(addr) \
|
|
||||||
map[(addr)>>24].address[(addr) & map[(addr)>>24].mask]
|
|
||||||
|
|
||||||
#define CPUReadHalfWordQuickDef(addr) \
|
|
||||||
READ16LE(((u16*)&map[(addr)>>24].address[(addr) & map[(addr)>>24].mask]))
|
|
||||||
|
|
||||||
#define CPUReadMemoryQuickDef(addr) \
|
|
||||||
READ32LE(((u32*)&map[(addr)>>24].address[(addr) & map[(addr)>>24].mask]))
|
|
||||||
|
|
||||||
u8 inline CPUReadByteQuick( u32 addr )
|
|
||||||
{
|
|
||||||
switch(addr >> 24 )
|
|
||||||
{
|
|
||||||
case 8:
|
|
||||||
case 9:
|
|
||||||
case 10:
|
|
||||||
case 12:
|
|
||||||
return VMRead8( addr & 0x1FFFFFF );
|
|
||||||
|
|
||||||
default:
|
|
||||||
return CPUReadByteQuickDef(addr);
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
u16 inline CPUReadHalfWordQuick( u32 addr )
|
|
||||||
{
|
|
||||||
switch(addr >> 24)
|
|
||||||
{
|
|
||||||
case 8:
|
|
||||||
case 9:
|
|
||||||
case 10:
|
|
||||||
case 12:
|
|
||||||
return VMRead16( addr & 0x1FFFFFF );
|
|
||||||
default:
|
|
||||||
return CPUReadHalfWordQuickDef(addr);
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
u32 inline CPUReadMemoryQuick( u32 addr )
|
|
||||||
{
|
|
||||||
switch(addr >> 24)
|
|
||||||
{
|
|
||||||
case 8:
|
|
||||||
case 9:
|
|
||||||
case 10:
|
|
||||||
case 12:
|
|
||||||
return VMRead32( addr & 0x1FFFFFF );
|
|
||||||
default:
|
|
||||||
return CPUReadMemoryQuickDef(addr);
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*****************************************************************************
|
|
||||||
* End of NGC VM override
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
static inline u32 CPUReadMemory(u32 address)
|
|
||||||
{
|
|
||||||
#ifdef GBA_LOGGING
|
|
||||||
if(address & 3) {
|
|
||||||
if(systemVerbose & VERBOSE_UNALIGNED_MEMORY) {
|
|
||||||
log("Unaligned word read: %08x at %08x\n", address, armMode ?
|
|
||||||
armNextPC - 4 : armNextPC - 2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
u32 value;
|
|
||||||
switch(address >> 24) {
|
|
||||||
case 0:
|
|
||||||
if(reg[15].I >> 24) {
|
|
||||||
if(address < 0x4000) {
|
|
||||||
#ifdef GBA_LOGGING
|
|
||||||
if(systemVerbose & VERBOSE_ILLEGAL_READ) {
|
|
||||||
log("Illegal word read: %08x at %08x\n", address, armMode ?
|
|
||||||
armNextPC - 4 : armNextPC - 2);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
value = READ32LE(((u32 *)&biosProtected));
|
|
||||||
}
|
|
||||||
else goto unreadable;
|
|
||||||
} else
|
|
||||||
value = READ32LE(((u32 *)&bios[address & 0x3FFC]));
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
value = READ32LE(((u32 *)&workRAM[address & 0x3FFFC]));
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
value = READ32LE(((u32 *)&internalRAM[address & 0x7ffC]));
|
|
||||||
break;
|
|
||||||
case 4:
|
|
||||||
if((address < 0x4000400) && ioReadable[address & 0x3fc]) {
|
|
||||||
if(ioReadable[(address & 0x3fc) + 2])
|
|
||||||
value = READ32LE(((u32 *)&ioMem[address & 0x3fC]));
|
|
||||||
else
|
|
||||||
value = READ16LE(((u16 *)&ioMem[address & 0x3fc]));
|
|
||||||
} else goto unreadable;
|
|
||||||
break;
|
|
||||||
case 5:
|
|
||||||
value = READ32LE(((u32 *)&paletteRAM[address & 0x3fC]));
|
|
||||||
break;
|
|
||||||
case 6:
|
|
||||||
address = (address & 0x1fffc);
|
|
||||||
if (((DISPCNT & 7) >2) && ((address & 0x1C000) == 0x18000))
|
|
||||||
{
|
|
||||||
value = 0;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if ((address & 0x18000) == 0x18000)
|
|
||||||
address &= 0x17fff;
|
|
||||||
value = READ32LE(((u32 *)&vram[address]));
|
|
||||||
break;
|
|
||||||
case 7:
|
|
||||||
value = READ32LE(((u32 *)&oam[address & 0x3FC]));
|
|
||||||
break;
|
|
||||||
case 8:
|
|
||||||
case 9:
|
|
||||||
case 10:
|
|
||||||
case 11:
|
|
||||||
case 12:
|
|
||||||
#ifdef USE_VM // Nintendo GC Virtual Memory
|
|
||||||
value = VMRead32( address & 0x1FFFFFC );
|
|
||||||
#else
|
|
||||||
value = READ32LE(((u32 *)&rom[address&0x1FFFFFC]));
|
|
||||||
#endif
|
|
||||||
break;
|
|
||||||
case 13:
|
|
||||||
if(cpuEEPROMEnabled)
|
|
||||||
// no need to swap this
|
|
||||||
return eepromRead(address);
|
|
||||||
goto unreadable;
|
|
||||||
case 14:
|
|
||||||
if(cpuFlashEnabled | cpuSramEnabled)
|
|
||||||
// no need to swap this
|
|
||||||
return flashRead(address);
|
|
||||||
// default
|
|
||||||
default:
|
|
||||||
unreadable:
|
|
||||||
#ifdef GBA_LOGGING
|
|
||||||
if(systemVerbose & VERBOSE_ILLEGAL_READ) {
|
|
||||||
log("Illegal word read: %08x at %08x\n", address, armMode ?
|
|
||||||
armNextPC - 4 : armNextPC - 2);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if(cpuDmaHack) {
|
|
||||||
value = cpuDmaLast;
|
|
||||||
} else {
|
|
||||||
if(armState) {
|
|
||||||
#ifdef USE_VM // Nintendo GC Virtual Memory
|
|
||||||
value = CPUReadMemoryQuick(reg[15].I);
|
|
||||||
#else
|
|
||||||
value = CPUReadMemoryQuickDef(reg[15].I);
|
|
||||||
#endif
|
|
||||||
} else {
|
|
||||||
#ifdef USE_VM // Nintendo GC Virtual Memory
|
|
||||||
value = CPUReadHalfWordQuick(reg[15].I) |
|
|
||||||
CPUReadHalfWordQuick(reg[15].I) << 16;
|
|
||||||
#else
|
|
||||||
value = CPUReadHalfWordQuickDef(reg[15].I) |
|
|
||||||
CPUReadHalfWordQuickDef(reg[15].I) << 16;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(address & 3) {
|
|
||||||
#ifdef C_CORE
|
|
||||||
int shift = (address & 3) << 3;
|
|
||||||
value = (value >> shift) | (value << (32 - shift));
|
|
||||||
#else
|
|
||||||
#ifdef __GNUC__
|
|
||||||
asm("and $3, %%ecx;"
|
|
||||||
"shl $3 ,%%ecx;"
|
|
||||||
"ror %%cl, %0"
|
|
||||||
: "=r" (value)
|
|
||||||
: "r" (value), "c" (address));
|
|
||||||
#else
|
|
||||||
__asm {
|
|
||||||
mov ecx, address;
|
|
||||||
and ecx, 3;
|
|
||||||
shl ecx, 3;
|
|
||||||
ror [dword ptr value], cl;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
extern u32 myROM[];
|
|
||||||
|
|
||||||
static inline u32 CPUReadHalfWord(u32 address)
|
|
||||||
{
|
|
||||||
#ifdef GBA_LOGGING
|
|
||||||
if(address & 1) {
|
|
||||||
if(systemVerbose & VERBOSE_UNALIGNED_MEMORY) {
|
|
||||||
log("Unaligned halfword read: %08x at %08x\n", address, armMode ?
|
|
||||||
armNextPC - 4 : armNextPC - 2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
u32 value;
|
|
||||||
|
|
||||||
switch(address >> 24) {
|
|
||||||
case 0:
|
|
||||||
if (reg[15].I >> 24) {
|
|
||||||
if(address < 0x4000) {
|
|
||||||
#ifdef GBA_LOGGING
|
|
||||||
if(systemVerbose & VERBOSE_ILLEGAL_READ) {
|
|
||||||
log("Illegal halfword read: %08x at %08x\n", address, armMode ?
|
|
||||||
armNextPC - 4 : armNextPC - 2);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
value = READ16LE(((u16 *)&biosProtected[address&2]));
|
|
||||||
} else goto unreadable;
|
|
||||||
} else
|
|
||||||
value = READ16LE(((u16 *)&bios[address & 0x3FFE]));
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
value = READ16LE(((u16 *)&workRAM[address & 0x3FFFE]));
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
value = READ16LE(((u16 *)&internalRAM[address & 0x7ffe]));
|
|
||||||
break;
|
|
||||||
case 4:
|
|
||||||
if((address < 0x4000400) && ioReadable[address & 0x3fe])
|
|
||||||
{
|
|
||||||
value = READ16LE(((u16 *)&ioMem[address & 0x3fe]));
|
|
||||||
if (((address & 0x3fe)>0xFF) && ((address & 0x3fe)<0x10E))
|
|
||||||
{
|
|
||||||
if (((address & 0x3fe) == 0x100) && timer0On)
|
|
||||||
value = 0xFFFF - ((timer0Ticks-cpuTotalTicks) >> timer0ClockReload);
|
|
||||||
else
|
|
||||||
if (((address & 0x3fe) == 0x104) && timer1On && !(TM1CNT & 4))
|
|
||||||
value = 0xFFFF - ((timer1Ticks-cpuTotalTicks) >> timer1ClockReload);
|
|
||||||
else
|
|
||||||
if (((address & 0x3fe) == 0x108) && timer2On && !(TM2CNT & 4))
|
|
||||||
value = 0xFFFF - ((timer2Ticks-cpuTotalTicks) >> timer2ClockReload);
|
|
||||||
else
|
|
||||||
if (((address & 0x3fe) == 0x10C) && timer3On && !(TM3CNT & 4))
|
|
||||||
value = 0xFFFF - ((timer3Ticks-cpuTotalTicks) >> timer3ClockReload);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else goto unreadable;
|
|
||||||
break;
|
|
||||||
case 5:
|
|
||||||
value = READ16LE(((u16 *)&paletteRAM[address & 0x3fe]));
|
|
||||||
break;
|
|
||||||
case 6:
|
|
||||||
address = (address & 0x1fffe);
|
|
||||||
if (((DISPCNT & 7) >2) && ((address & 0x1C000) == 0x18000))
|
|
||||||
{
|
|
||||||
value = 0;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if ((address & 0x18000) == 0x18000)
|
|
||||||
address &= 0x17fff;
|
|
||||||
value = READ16LE(((u16 *)&vram[address]));
|
|
||||||
break;
|
|
||||||
case 7:
|
|
||||||
value = READ16LE(((u16 *)&oam[address & 0x3fe]));
|
|
||||||
break;
|
|
||||||
case 8:
|
|
||||||
case 9:
|
|
||||||
case 10:
|
|
||||||
case 11:
|
|
||||||
case 12:
|
|
||||||
if(address == 0x80000c4 || address == 0x80000c6 || address == 0x80000c8)
|
|
||||||
value = rtcRead(address);
|
|
||||||
else
|
|
||||||
#ifdef USE_VM // Nintendo GC Virtual Memory
|
|
||||||
value = VMRead16( address & 0x1FFFFFE );
|
|
||||||
#else
|
|
||||||
value = READ16LE(((u16 *)&rom[address & 0x1FFFFFE]));
|
|
||||||
#endif
|
|
||||||
break;
|
|
||||||
case 13:
|
|
||||||
if(cpuEEPROMEnabled)
|
|
||||||
// no need to swap this
|
|
||||||
return eepromRead(address);
|
|
||||||
goto unreadable;
|
|
||||||
case 14:
|
|
||||||
if(cpuFlashEnabled | cpuSramEnabled)
|
|
||||||
// no need to swap this
|
|
||||||
return flashRead(address);
|
|
||||||
// default
|
|
||||||
default:
|
|
||||||
unreadable:
|
|
||||||
#ifdef GBA_LOGGING
|
|
||||||
if(systemVerbose & VERBOSE_ILLEGAL_READ) {
|
|
||||||
log("Illegal halfword read: %08x at %08x\n", address, armMode ?
|
|
||||||
armNextPC - 4 : armNextPC - 2);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
if(cpuDmaHack) {
|
|
||||||
value = cpuDmaLast & 0xFFFF;
|
|
||||||
} else {
|
|
||||||
if(armState) {
|
|
||||||
#ifdef USE_VM // Nintendo GC Virtual Memory
|
|
||||||
value = CPUReadHalfWordQuick(reg[15].I + (address & 2));
|
|
||||||
#else
|
|
||||||
value = CPUReadHalfWordQuickDef(reg[15].I + (address & 2));
|
|
||||||
#endif
|
|
||||||
} else {
|
|
||||||
#ifdef USE_VM // Nintendo GC Virtual Memory
|
|
||||||
value = CPUReadHalfWordQuick(reg[15].I);
|
|
||||||
#else
|
|
||||||
value = CPUReadHalfWordQuickDef(reg[15].I);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(address & 1) {
|
|
||||||
value = (value >> 8) | (value << 24);
|
|
||||||
}
|
|
||||||
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline u16 CPUReadHalfWordSigned(u32 address)
|
|
||||||
{
|
|
||||||
u16 value = CPUReadHalfWord(address);
|
|
||||||
if((address & 1))
|
|
||||||
value = (s8)value;
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline u8 CPUReadByte(u32 address)
|
|
||||||
{
|
|
||||||
switch(address >> 24) {
|
|
||||||
case 0:
|
|
||||||
if (reg[15].I >> 24) {
|
|
||||||
if(address < 0x4000) {
|
|
||||||
#ifdef GBA_LOGGING
|
|
||||||
if(systemVerbose & VERBOSE_ILLEGAL_READ) {
|
|
||||||
log("Illegal byte read: %08x at %08x\n", address, armMode ?
|
|
||||||
armNextPC - 4 : armNextPC - 2);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
return biosProtected[address & 3];
|
|
||||||
} else goto unreadable;
|
|
||||||
}
|
|
||||||
return bios[address & 0x3FFF];
|
|
||||||
case 2:
|
|
||||||
return workRAM[address & 0x3FFFF];
|
|
||||||
case 3:
|
|
||||||
return internalRAM[address & 0x7fff];
|
|
||||||
case 4:
|
|
||||||
if((address < 0x4000400) && ioReadable[address & 0x3ff])
|
|
||||||
return ioMem[address & 0x3ff];
|
|
||||||
else goto unreadable;
|
|
||||||
case 5:
|
|
||||||
return paletteRAM[address & 0x3ff];
|
|
||||||
case 6:
|
|
||||||
address = (address & 0x1ffff);
|
|
||||||
if (((DISPCNT & 7) >2) && ((address & 0x1C000) == 0x18000))
|
|
||||||
return 0;
|
|
||||||
if ((address & 0x18000) == 0x18000)
|
|
||||||
address &= 0x17fff;
|
|
||||||
return vram[address];
|
|
||||||
case 7:
|
|
||||||
return oam[address & 0x3ff];
|
|
||||||
case 8:
|
|
||||||
case 9:
|
|
||||||
case 10:
|
|
||||||
case 11:
|
|
||||||
case 12:
|
|
||||||
#ifdef USE_VM // Nintendo GC Virtual Memory
|
|
||||||
return VMRead8( address & 0x1FFFFFF );
|
|
||||||
#else
|
|
||||||
return rom[address & 0x1FFFFFF];
|
|
||||||
#endif
|
|
||||||
case 13:
|
|
||||||
if(cpuEEPROMEnabled)
|
|
||||||
return eepromRead(address);
|
|
||||||
goto unreadable;
|
|
||||||
case 14:
|
|
||||||
if(cpuSramEnabled | cpuFlashEnabled)
|
|
||||||
return flashRead(address);
|
|
||||||
if(cpuEEPROMSensorEnabled) {
|
|
||||||
switch(address & 0x00008f00) {
|
|
||||||
case 0x8200:
|
|
||||||
return systemGetSensorX() & 255;
|
|
||||||
case 0x8300:
|
|
||||||
return (systemGetSensorX() >> 8)|0x80;
|
|
||||||
case 0x8400:
|
|
||||||
return systemGetSensorY() & 255;
|
|
||||||
case 0x8500:
|
|
||||||
return systemGetSensorY() >> 8;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// default
|
|
||||||
default:
|
|
||||||
unreadable:
|
|
||||||
#ifdef GBA_LOGGING
|
|
||||||
if(systemVerbose & VERBOSE_ILLEGAL_READ) {
|
|
||||||
log("Illegal byte read: %08x at %08x\n", address, armMode ?
|
|
||||||
armNextPC - 4 : armNextPC - 2);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
if(cpuDmaHack) {
|
|
||||||
return cpuDmaLast & 0xFF;
|
|
||||||
} else {
|
|
||||||
if(armState) {
|
|
||||||
#ifdef USE_VM // Nintendo GC Virtual Memory
|
|
||||||
return CPUReadByteQuick(reg[15].I+(address & 3));
|
|
||||||
#else
|
|
||||||
return CPUReadByteQuickDef(reg[15].I+(address & 3));
|
|
||||||
#endif
|
|
||||||
} else {
|
|
||||||
#ifdef USE_VM // Nintendo GC Virtual Memory
|
|
||||||
return CPUReadByteQuick(reg[15].I+(address & 1));
|
|
||||||
#else
|
|
||||||
return CPUReadByteQuickDef(reg[15].I+(address & 1));
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void CPUWriteMemory(u32 address, u32 value)
|
|
||||||
{
|
|
||||||
|
|
||||||
#ifdef GBA_LOGGING
|
|
||||||
if(address & 3) {
|
|
||||||
if(systemVerbose & VERBOSE_UNALIGNED_MEMORY) {
|
|
||||||
log("Unaligned word write: %08x to %08x from %08x\n",
|
|
||||||
value,
|
|
||||||
address,
|
|
||||||
armMode ? armNextPC - 4 : armNextPC - 2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
switch(address >> 24) {
|
|
||||||
case 0x02:
|
|
||||||
#ifdef BKPT_SUPPORT
|
|
||||||
if(*((u32 *)&freezeWorkRAM[address & 0x3FFFC]))
|
|
||||||
cheatsWriteMemory(address & 0x203FFFC,
|
|
||||||
value);
|
|
||||||
else
|
|
||||||
#endif
|
|
||||||
WRITE32LE(((u32 *)&workRAM[address & 0x3FFFC]), value);
|
|
||||||
break;
|
|
||||||
case 0x03:
|
|
||||||
#ifdef BKPT_SUPPORT
|
|
||||||
if(*((u32 *)&freezeInternalRAM[address & 0x7ffc]))
|
|
||||||
cheatsWriteMemory(address & 0x3007FFC,
|
|
||||||
value);
|
|
||||||
else
|
|
||||||
#endif
|
|
||||||
WRITE32LE(((u32 *)&internalRAM[address & 0x7ffC]), value);
|
|
||||||
break;
|
|
||||||
case 0x04:
|
|
||||||
if(address < 0x4000400) {
|
|
||||||
CPUUpdateRegister((address & 0x3FC), value & 0xFFFF);
|
|
||||||
CPUUpdateRegister((address & 0x3FC) + 2, (value >> 16));
|
|
||||||
} else goto unwritable;
|
|
||||||
break;
|
|
||||||
case 0x05:
|
|
||||||
#ifdef BKPT_SUPPORT
|
|
||||||
if(*((u32 *)&freezePRAM[address & 0x3fc]))
|
|
||||||
cheatsWriteMemory(address & 0x70003FC,
|
|
||||||
value);
|
|
||||||
else
|
|
||||||
#endif
|
|
||||||
WRITE32LE(((u32 *)&paletteRAM[address & 0x3FC]), value);
|
|
||||||
break;
|
|
||||||
case 0x06:
|
|
||||||
address = (address & 0x1fffc);
|
|
||||||
if (((DISPCNT & 7) >2) && ((address & 0x1C000) == 0x18000))
|
|
||||||
return;
|
|
||||||
if ((address & 0x18000) == 0x18000)
|
|
||||||
address &= 0x17fff;
|
|
||||||
|
|
||||||
#ifdef BKPT_SUPPORT
|
|
||||||
if(*((u32 *)&freezeVRAM[address]))
|
|
||||||
cheatsWriteMemory(address + 0x06000000, value);
|
|
||||||
else
|
|
||||||
#endif
|
|
||||||
|
|
||||||
WRITE32LE(((u32 *)&vram[address]), value);
|
|
||||||
break;
|
|
||||||
case 0x07:
|
|
||||||
#ifdef BKPT_SUPPORT
|
|
||||||
if(*((u32 *)&freezeOAM[address & 0x3fc]))
|
|
||||||
cheatsWriteMemory(address & 0x70003FC,
|
|
||||||
value);
|
|
||||||
else
|
|
||||||
#endif
|
|
||||||
WRITE32LE(((u32 *)&oam[address & 0x3fc]), value);
|
|
||||||
break;
|
|
||||||
case 0x0D:
|
|
||||||
if(cpuEEPROMEnabled) {
|
|
||||||
eepromWrite(address, value);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
goto unwritable;
|
|
||||||
case 0x0E:
|
|
||||||
if(!eepromInUse | cpuSramEnabled | cpuFlashEnabled) {
|
|
||||||
(*cpuSaveGameFunc)(address, (u8)value);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
// default
|
|
||||||
default:
|
|
||||||
unwritable:
|
|
||||||
#ifdef GBA_LOGGING
|
|
||||||
if(systemVerbose & VERBOSE_ILLEGAL_WRITE) {
|
|
||||||
log("Illegal word write: %08x to %08x from %08x\n",
|
|
||||||
value,
|
|
||||||
address,
|
|
||||||
armMode ? armNextPC - 4 : armNextPC - 2);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void CPUWriteHalfWord(u32 address, u16 value)
|
|
||||||
{
|
|
||||||
#ifdef GBA_LOGGING
|
|
||||||
if(address & 1) {
|
|
||||||
if(systemVerbose & VERBOSE_UNALIGNED_MEMORY) {
|
|
||||||
log("Unaligned halfword write: %04x to %08x from %08x\n",
|
|
||||||
value,
|
|
||||||
address,
|
|
||||||
armMode ? armNextPC - 4 : armNextPC - 2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
switch(address >> 24) {
|
|
||||||
case 2:
|
|
||||||
#ifdef BKPT_SUPPORT
|
|
||||||
if(*((u16 *)&freezeWorkRAM[address & 0x3FFFE]))
|
|
||||||
cheatsWriteHalfWord(address & 0x203FFFE,
|
|
||||||
value);
|
|
||||||
else
|
|
||||||
#endif
|
|
||||||
WRITE16LE(((u16 *)&workRAM[address & 0x3FFFE]),value);
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
#ifdef BKPT_SUPPORT
|
|
||||||
if(*((u16 *)&freezeInternalRAM[address & 0x7ffe]))
|
|
||||||
cheatsWriteHalfWord(address & 0x3007ffe,
|
|
||||||
value);
|
|
||||||
else
|
|
||||||
#endif
|
|
||||||
WRITE16LE(((u16 *)&internalRAM[address & 0x7ffe]), value);
|
|
||||||
break;
|
|
||||||
case 4:
|
|
||||||
if(address < 0x4000400)
|
|
||||||
CPUUpdateRegister(address & 0x3fe, value);
|
|
||||||
else goto unwritable;
|
|
||||||
break;
|
|
||||||
case 5:
|
|
||||||
#ifdef BKPT_SUPPORT
|
|
||||||
if(*((u16 *)&freezePRAM[address & 0x03fe]))
|
|
||||||
cheatsWriteHalfWord(address & 0x70003fe,
|
|
||||||
value);
|
|
||||||
else
|
|
||||||
#endif
|
|
||||||
WRITE16LE(((u16 *)&paletteRAM[address & 0x3fe]), value);
|
|
||||||
break;
|
|
||||||
case 6:
|
|
||||||
address = (address & 0x1fffe);
|
|
||||||
if (((DISPCNT & 7) >2) && ((address & 0x1C000) == 0x18000))
|
|
||||||
return;
|
|
||||||
if ((address & 0x18000) == 0x18000)
|
|
||||||
address &= 0x17fff;
|
|
||||||
#ifdef BKPT_SUPPORT
|
|
||||||
if(*((u16 *)&freezeVRAM[address]))
|
|
||||||
cheatsWriteHalfWord(address + 0x06000000,
|
|
||||||
value);
|
|
||||||
else
|
|
||||||
#endif
|
|
||||||
WRITE16LE(((u16 *)&vram[address]), value);
|
|
||||||
break;
|
|
||||||
case 7:
|
|
||||||
#ifdef BKPT_SUPPORT
|
|
||||||
if(*((u16 *)&freezeOAM[address & 0x03fe]))
|
|
||||||
cheatsWriteHalfWord(address & 0x70003fe,
|
|
||||||
value);
|
|
||||||
else
|
|
||||||
#endif
|
|
||||||
WRITE16LE(((u16 *)&oam[address & 0x3fe]), value);
|
|
||||||
break;
|
|
||||||
case 8:
|
|
||||||
case 9:
|
|
||||||
if(address == 0x80000c4 || address == 0x80000c6 || address == 0x80000c8) {
|
|
||||||
if(!rtcWrite(address, value))
|
|
||||||
goto unwritable;
|
|
||||||
} else if(!agbPrintWrite(address, value)) goto unwritable;
|
|
||||||
break;
|
|
||||||
case 13:
|
|
||||||
if(cpuEEPROMEnabled) {
|
|
||||||
eepromWrite(address, (u8)value);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
goto unwritable;
|
|
||||||
case 14:
|
|
||||||
if(!eepromInUse | cpuSramEnabled | cpuFlashEnabled) {
|
|
||||||
(*cpuSaveGameFunc)(address, (u8)value);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
goto unwritable;
|
|
||||||
default:
|
|
||||||
unwritable:
|
|
||||||
#ifdef GBA_LOGGING
|
|
||||||
if(systemVerbose & VERBOSE_ILLEGAL_WRITE) {
|
|
||||||
log("Illegal halfword write: %04x to %08x from %08x\n",
|
|
||||||
value,
|
|
||||||
address,
|
|
||||||
armMode ? armNextPC - 4 : armNextPC - 2);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void CPUWriteByte(u32 address, u8 b)
|
|
||||||
{
|
|
||||||
switch(address >> 24) {
|
|
||||||
case 2:
|
|
||||||
#ifdef BKPT_SUPPORT
|
|
||||||
if(freezeWorkRAM[address & 0x3FFFF])
|
|
||||||
cheatsWriteByte(address & 0x203FFFF, b);
|
|
||||||
else
|
|
||||||
#endif
|
|
||||||
workRAM[address & 0x3FFFF] = b;
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
#ifdef BKPT_SUPPORT
|
|
||||||
if(freezeInternalRAM[address & 0x7fff])
|
|
||||||
cheatsWriteByte(address & 0x3007fff, b);
|
|
||||||
else
|
|
||||||
#endif
|
|
||||||
internalRAM[address & 0x7fff] = b;
|
|
||||||
break;
|
|
||||||
case 4:
|
|
||||||
if(address < 0x4000400) {
|
|
||||||
switch(address & 0x3FF) {
|
|
||||||
case 0x301:
|
|
||||||
if(b == 0x80)
|
|
||||||
stopState = true;
|
|
||||||
holdState = 1;
|
|
||||||
holdType = -1;
|
|
||||||
cpuNextEvent = cpuTotalTicks;
|
|
||||||
break;
|
|
||||||
case 0x60:
|
|
||||||
case 0x61:
|
|
||||||
case 0x62:
|
|
||||||
case 0x63:
|
|
||||||
case 0x64:
|
|
||||||
case 0x65:
|
|
||||||
case 0x68:
|
|
||||||
case 0x69:
|
|
||||||
case 0x6c:
|
|
||||||
case 0x6d:
|
|
||||||
case 0x70:
|
|
||||||
case 0x71:
|
|
||||||
case 0x72:
|
|
||||||
case 0x73:
|
|
||||||
case 0x74:
|
|
||||||
case 0x75:
|
|
||||||
case 0x78:
|
|
||||||
case 0x79:
|
|
||||||
case 0x7c:
|
|
||||||
case 0x7d:
|
|
||||||
case 0x80:
|
|
||||||
case 0x81:
|
|
||||||
case 0x84:
|
|
||||||
case 0x85:
|
|
||||||
case 0x90:
|
|
||||||
case 0x91:
|
|
||||||
case 0x92:
|
|
||||||
case 0x93:
|
|
||||||
case 0x94:
|
|
||||||
case 0x95:
|
|
||||||
case 0x96:
|
|
||||||
case 0x97:
|
|
||||||
case 0x98:
|
|
||||||
case 0x99:
|
|
||||||
case 0x9a:
|
|
||||||
case 0x9b:
|
|
||||||
case 0x9c:
|
|
||||||
case 0x9d:
|
|
||||||
case 0x9e:
|
|
||||||
case 0x9f:
|
|
||||||
soundEvent(address&0xFF, b);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
if(address & 1)
|
|
||||||
CPUUpdateRegister(address & 0x3fe,
|
|
||||||
((READ16LE(((u16 *)&ioMem[address & 0x3fe])))
|
|
||||||
& 0x00FF) |
|
|
||||||
b<<8);
|
|
||||||
else
|
|
||||||
CPUUpdateRegister(address & 0x3fe,
|
|
||||||
((READ16LE(((u16 *)&ioMem[address & 0x3fe])) & 0xFF00) | b));
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
} else goto unwritable;
|
|
||||||
break;
|
|
||||||
case 5:
|
|
||||||
// no need to switch
|
|
||||||
*((u16 *)&paletteRAM[address & 0x3FE]) = (b << 8) | b;
|
|
||||||
break;
|
|
||||||
case 6:
|
|
||||||
address = (address & 0x1fffe);
|
|
||||||
if (((DISPCNT & 7) >2) && ((address & 0x1C000) == 0x18000))
|
|
||||||
return;
|
|
||||||
if ((address & 0x18000) == 0x18000)
|
|
||||||
address &= 0x17fff;
|
|
||||||
|
|
||||||
// no need to switch
|
|
||||||
// byte writes to OBJ VRAM are ignored
|
|
||||||
if ((address) < objTilesAddress[((DISPCNT&7)+1)>>2])
|
|
||||||
{
|
|
||||||
#ifdef BKPT_SUPPORT
|
|
||||||
if(freezeVRAM[address])
|
|
||||||
cheatsWriteByte(address + 0x06000000, b);
|
|
||||||
else
|
|
||||||
#endif
|
|
||||||
*((u16 *)&vram[address]) = (b << 8) | b;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 7:
|
|
||||||
// no need to switch
|
|
||||||
// byte writes to OAM are ignored
|
|
||||||
// *((u16 *)&oam[address & 0x3FE]) = (b << 8) | b;
|
|
||||||
break;
|
|
||||||
case 13:
|
|
||||||
if(cpuEEPROMEnabled) {
|
|
||||||
eepromWrite(address, b);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
goto unwritable;
|
|
||||||
case 14:
|
|
||||||
if (!(saveType == 5) && (!eepromInUse | cpuSramEnabled | cpuFlashEnabled)) {
|
|
||||||
|
|
||||||
//if(!cpuEEPROMEnabled && (cpuSramEnabled | cpuFlashEnabled)) {
|
|
||||||
|
|
||||||
(*cpuSaveGameFunc)(address, b);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
// default
|
|
||||||
default:
|
|
||||||
unwritable:
|
|
||||||
#ifdef GBA_LOGGING
|
|
||||||
if(systemVerbose & VERBOSE_ILLEGAL_WRITE) {
|
|
||||||
log("Illegal byte write: %02x to %08x from %08x\n",
|
|
||||||
b,
|
|
||||||
address,
|
|
||||||
armMode ? armNextPC - 4 : armNextPC -2 );
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif //VBA_GBAinline_H
|
|
@ -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,16 +34,21 @@ static bool agbPrintProtect = false;
|
|||||||
|
|
||||||
bool agbPrintWrite(u32 address, u16 value)
|
bool agbPrintWrite(u32 address, u16 value)
|
||||||
{
|
{
|
||||||
if(agbPrintEnabled) {
|
if(agbPrintEnabled)
|
||||||
if(address == 0x9fe2ffe) { // protect
|
{
|
||||||
|
if(address == 0x9fe2ffe)
|
||||||
|
{ // protect
|
||||||
agbPrintProtect = (value != 0);
|
agbPrintProtect = (value != 0);
|
||||||
debuggerWriteHalfWord(address, value);
|
debuggerWriteHalfWord(address, value);
|
||||||
return true;
|
return true;
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
if(agbPrintProtect &&
|
if(agbPrintProtect &&
|
||||||
((address >= 0x9fe20f8 && address <= 0x9fe20ff) // control structure
|
((address >= 0x9fe20f8 && address <= 0x9fe20ff) // control structure
|
||||||
|| (address >= 0x8fd0000 && address <= 0x8fdffff)
|
|| (address >= 0x8fd0000 && address <= 0x8fdffff)
|
||||||
|| (address >= 0x9fd0000 && address <= 0x9fdffff))) {
|
|| (address >= 0x9fd0000 && address <= 0x9fdffff)))
|
||||||
|
{
|
||||||
debuggerWriteHalfWord(address, value);
|
debuggerWriteHalfWord(address, value);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -68,13 +72,16 @@ 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);
|
dbgOutput("Did you forget to call AGBPrintInit?\n", 0);
|
||||||
// get rid of the text otherwise we will continue to be called
|
// get rid of the text otherwise we will continue to be called
|
||||||
debuggerWriteHalfWord(0x9fe20fc, put);
|
debuggerWriteHalfWord(0x9fe20fc, put);
|
||||||
@ -83,7 +90,8 @@ void agbPrintFlush()
|
|||||||
|
|
||||||
u8 *data = &rom[address];
|
u8 *data = &rom[address];
|
||||||
|
|
||||||
while(get != put) {
|
while(get != put)
|
||||||
|
{
|
||||||
char c = data[get++];
|
char c = data[get++];
|
||||||
char s[2];
|
char s[2];
|
||||||
s[0] = c;
|
s[0] = c;
|
7472
source/vba/arm-new.h
Normal file
7472
source/vba/arm-new.h
Normal file
File diff suppressed because it is too large
Load Diff
@ -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
|
||||||
@ -23,14 +23,15 @@
|
|||||||
|
|
||||||
#include "System.h"
|
#include "System.h"
|
||||||
#include "Port.h"
|
#include "Port.h"
|
||||||
#include "agb/GBA.h"
|
#include "GBA.h"
|
||||||
#include "armdis.h"
|
#include "armdis.h"
|
||||||
#include "elf.h"
|
#include "elf.h"
|
||||||
|
|
||||||
struct Opcodes {
|
struct Opcodes
|
||||||
|
{
|
||||||
u32 mask;
|
u32 mask;
|
||||||
u32 cval;
|
u32 cval;
|
||||||
const char *mnemonic;
|
char *mnemonic;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define debuggerReadMemory(addr) \
|
#define debuggerReadMemory(addr) \
|
||||||
@ -44,26 +45,31 @@ struct Opcodes {
|
|||||||
|
|
||||||
const char hdig[] = "0123456789abcdef";
|
const char hdig[] = "0123456789abcdef";
|
||||||
|
|
||||||
const char *decVals[16] = {
|
const char *decVals[16] =
|
||||||
|
{
|
||||||
"0","1","2","3","4","5","6","7","8",
|
"0","1","2","3","4","5","6","7","8",
|
||||||
"9","10","11","12","13","14","15"
|
"9","10","11","12","13","14","15"
|
||||||
};
|
};
|
||||||
|
|
||||||
const char *regs[16] = {
|
const char *regs[16] =
|
||||||
|
{
|
||||||
"r0","r1","r2","r3","r4","r5","r6","r7",
|
"r0","r1","r2","r3","r4","r5","r6","r7",
|
||||||
"r8","r9","r10","r11","r12","sp","lr","pc"
|
"r8","r9","r10","r11","r12","sp","lr","pc"
|
||||||
};
|
};
|
||||||
|
|
||||||
const char *conditions[16] = {
|
const char *conditions[16] =
|
||||||
|
{
|
||||||
"eq","ne","cs","cc","mi","pl","vs","vc",
|
"eq","ne","cs","cc","mi","pl","vs","vc",
|
||||||
"hi","ls","ge","lt","gt","le","","nv"
|
"hi","ls","ge","lt","gt","le","","nv"
|
||||||
};
|
};
|
||||||
|
|
||||||
const char *shifts[5] = {
|
const char *shifts[5] =
|
||||||
|
{
|
||||||
"lsl","lsr","asr","ror","rrx"
|
"lsl","lsr","asr","ror","rrx"
|
||||||
};
|
};
|
||||||
|
|
||||||
const char *armMultLoadStore[12] = {
|
const char *armMultLoadStore[12] =
|
||||||
|
{
|
||||||
// non-stack
|
// non-stack
|
||||||
"da","ia","db","ib",
|
"da","ia","db","ib",
|
||||||
// stack store
|
// stack store
|
||||||
@ -72,7 +78,8 @@ const char *armMultLoadStore[12] = {
|
|||||||
"fa","fd","ea","ed"
|
"fa","fd","ea","ed"
|
||||||
};
|
};
|
||||||
|
|
||||||
const Opcodes thumbOpcodes[] = {
|
const Opcodes thumbOpcodes[] =
|
||||||
|
{
|
||||||
// Format 1
|
// Format 1
|
||||||
{0xf800, 0x0000, "lsl %r0, %r3, %o"},
|
{0xf800, 0x0000, "lsl %r0, %r3, %o"},
|
||||||
{0xf800, 0x0800, "lsr %r0, %r3, %o"},
|
{0xf800, 0x0800, "lsr %r0, %r3, %o"},
|
||||||
@ -117,8 +124,8 @@ const Opcodes thumbOpcodes[] = {
|
|||||||
{0xfa00, 0x5800, "ldr%b %r0, [%r3, %r6]"},
|
{0xfa00, 0x5800, "ldr%b %r0, [%r3, %r6]"},
|
||||||
// Format 8
|
// Format 8
|
||||||
{0xfe00, 0x5200, "strh %r0, [%r3, %r6]"},
|
{0xfe00, 0x5200, "strh %r0, [%r3, %r6]"},
|
||||||
{0xfe00, 0x5600, "ldsb %r0, [%r3, %r6]"},
|
{0xfe00, 0x5600, "ldrh %r0, [%r3, %r6]"},
|
||||||
{0xfe00, 0x5a00, "ldrh %r0, [%r3, %r6]"},
|
{0xfe00, 0x5a00, "ldsb %r0, [%r3, %r6]"},
|
||||||
{0xfe00, 0x5e00, "ldsh %r0, [%r3, %r6]"},
|
{0xfe00, 0x5e00, "ldsh %r0, [%r3, %r6]"},
|
||||||
// Format 9
|
// Format 9
|
||||||
{0xe800, 0x6000, "str%B %r0, [%r3, %p]"},
|
{0xe800, 0x6000, "str%B %r0, [%r3, %p]"},
|
||||||
@ -158,7 +165,8 @@ const Opcodes thumbOpcodes[] = {
|
|||||||
{0x0000, 0x0000, "[ ??? ]"}
|
{0x0000, 0x0000, "[ ??? ]"}
|
||||||
};
|
};
|
||||||
|
|
||||||
const Opcodes armOpcodes[] = {
|
const Opcodes armOpcodes[] =
|
||||||
|
{
|
||||||
// Undefined
|
// Undefined
|
||||||
{0x0e000010, 0x06000010, "[ undefined ]"},
|
{0x0e000010, 0x06000010, "[ undefined ]"},
|
||||||
// Branch instructions
|
// Branch instructions
|
||||||
@ -209,50 +217,61 @@ const Opcodes armOpcodes[] = {
|
|||||||
{0x00000000, 0x00000000, "[ ??? ]"}
|
{0x00000000, 0x00000000, "[ ??? ]"}
|
||||||
};
|
};
|
||||||
|
|
||||||
char* addStr(char *dest, const char *src){
|
char* addStr(char *dest, const char *src)
|
||||||
while (*src){
|
{
|
||||||
|
while (*src)
|
||||||
|
{
|
||||||
*dest++ = *src++;
|
*dest++ = *src++;
|
||||||
}
|
}
|
||||||
return dest;
|
return dest;
|
||||||
}
|
}
|
||||||
|
|
||||||
char* addHex(char *dest, int siz, u32 val){
|
char* addHex(char *dest, int siz, u32 val)
|
||||||
if (siz==0){
|
{
|
||||||
|
if (siz==0)
|
||||||
|
{
|
||||||
siz = 28;
|
siz = 28;
|
||||||
while ( (((val>>siz)&15)==0) && (siz>=4) )
|
while ( (((val>>siz)&15)==0) && (siz>=4) )
|
||||||
siz -= 4;
|
siz -= 4;
|
||||||
siz += 4;
|
siz += 4;
|
||||||
}
|
}
|
||||||
while (siz>0){
|
while (siz>0)
|
||||||
|
{
|
||||||
siz -= 4;
|
siz -= 4;
|
||||||
*dest++ = hdig[(val>>siz)&15];
|
*dest++ = hdig[(val>>siz)&15];
|
||||||
}
|
}
|
||||||
return dest;
|
return dest;
|
||||||
}
|
}
|
||||||
|
|
||||||
int disArm(u32 offset, char *dest, int flags){
|
int disArm(u32 offset, char *dest, int flags)
|
||||||
|
{
|
||||||
u32 opcode = debuggerReadMemory(offset);
|
u32 opcode = debuggerReadMemory(offset);
|
||||||
|
|
||||||
const Opcodes *sp = armOpcodes;
|
const Opcodes *sp = armOpcodes;
|
||||||
while( sp->cval != (opcode & sp->mask) )
|
while( sp->cval != (opcode & sp->mask) )
|
||||||
sp++;
|
sp++;
|
||||||
|
|
||||||
if (flags&DIS_VIEW_ADDRESS){
|
if (flags&DIS_VIEW_ADDRESS)
|
||||||
|
{
|
||||||
dest = addHex(dest, 32, offset);
|
dest = addHex(dest, 32, offset);
|
||||||
*dest++ = ' ';
|
*dest++ = ' ';
|
||||||
}
|
}
|
||||||
if (flags&DIS_VIEW_CODE){
|
if (flags&DIS_VIEW_CODE)
|
||||||
|
{
|
||||||
dest = addHex(dest, 32, opcode);
|
dest = addHex(dest, 32, opcode);
|
||||||
*dest++ = ' ';
|
*dest++ = ' ';
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *src = sp->mnemonic;
|
char *src = sp->mnemonic;
|
||||||
while (*src){
|
while (*src)
|
||||||
|
{
|
||||||
if (*src!='%')
|
if (*src!='%')
|
||||||
*dest++ = *src++;
|
*dest++ = *src++;
|
||||||
else{
|
else
|
||||||
|
{
|
||||||
src++;
|
src++;
|
||||||
switch (*src){
|
switch (*src)
|
||||||
|
{
|
||||||
case 'c':
|
case 'c':
|
||||||
dest = addStr(dest, conditions[opcode>>28]);
|
dest = addStr(dest, conditions[opcode>>28]);
|
||||||
break;
|
break;
|
||||||
@ -270,28 +289,36 @@ int disArm(u32 offset, char *dest, int flags){
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'i':
|
case 'i':
|
||||||
if (opcode&(1<<25)){
|
if (opcode&(1<<25))
|
||||||
|
{
|
||||||
dest = addStr(dest, "#0x");
|
dest = addStr(dest, "#0x");
|
||||||
int imm = opcode&0xff;
|
int imm = opcode&0xff;
|
||||||
int rot = (opcode&0xf00)>>7;
|
int rot = (opcode&0xf00)>>7;
|
||||||
int val = (imm<<(32-rot))|(imm>>rot);
|
int val = (imm<<(32-rot))|(imm>>rot);
|
||||||
dest = addHex(dest, 0, val);
|
dest = addHex(dest, 0, val);
|
||||||
} else{
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
dest = addStr(dest, regs[opcode&0x0f]);
|
dest = addStr(dest, regs[opcode&0x0f]);
|
||||||
int shi = (opcode>>5)&3;
|
int shi = (opcode>>5)&3;
|
||||||
int sdw = (opcode>>7)&0x1f;
|
int sdw = (opcode>>7)&0x1f;
|
||||||
if ((sdw==0)&&(shi==3))
|
if ((sdw==0)&&(shi==3))
|
||||||
shi = 4;
|
shi = 4;
|
||||||
if ( (sdw) || (opcode&0x10) || (shi)) {
|
if ( (sdw) || (opcode&0x10) || (shi))
|
||||||
|
{
|
||||||
dest = addStr(dest, ", ");
|
dest = addStr(dest, ", ");
|
||||||
dest = addStr(dest, shifts[shi]);
|
dest = addStr(dest, shifts[shi]);
|
||||||
if (opcode&0x10){
|
if (opcode&0x10)
|
||||||
|
{
|
||||||
*dest++ = ' ';
|
*dest++ = ' ';
|
||||||
dest = addStr(dest, regs[(opcode>>8)&15]);
|
dest = addStr(dest, regs[(opcode>>8)&15]);
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
if (sdw==0 && ( (shi==1) || (shi==2) ))
|
if (sdw==0 && ( (shi==1) || (shi==2) ))
|
||||||
sdw = 32;
|
sdw = 32;
|
||||||
if(shi != 4) {
|
if(shi != 4)
|
||||||
|
{
|
||||||
dest = addStr(dest, " #0x");
|
dest = addStr(dest, " #0x");
|
||||||
dest = addHex(dest, 8, sdw);
|
dest = addHex(dest, 8, sdw);
|
||||||
}
|
}
|
||||||
@ -304,7 +331,8 @@ int disArm(u32 offset, char *dest, int flags){
|
|||||||
dest = addStr(dest, "spsr");
|
dest = addStr(dest, "spsr");
|
||||||
else
|
else
|
||||||
dest = addStr(dest, "cpsr");
|
dest = addStr(dest, "cpsr");
|
||||||
if(opcode & 0x00F00000) {
|
if(opcode & 0x00F00000)
|
||||||
|
{
|
||||||
*dest++ = '_';
|
*dest++ = '_';
|
||||||
if(opcode & 0x00080000)
|
if(opcode & 0x00080000)
|
||||||
*dest++ = 'f';
|
*dest++ = 'f';
|
||||||
@ -335,7 +363,8 @@ int disArm(u32 offset, char *dest, int flags){
|
|||||||
*dest++ = 'b';
|
*dest++ = 'b';
|
||||||
break;
|
break;
|
||||||
case 'a':
|
case 'a':
|
||||||
if ((opcode&0x076f0000)==0x004f0000){
|
if ((opcode&0x076f0000)==0x004f0000)
|
||||||
|
{
|
||||||
*dest++ = '[';
|
*dest++ = '[';
|
||||||
*dest++ = '$';
|
*dest++ = '$';
|
||||||
int adr = offset+8;
|
int adr = offset+8;
|
||||||
@ -351,7 +380,8 @@ int disArm(u32 offset, char *dest, int flags){
|
|||||||
dest = addHex(dest ,32, debuggerReadMemory(adr));
|
dest = addHex(dest ,32, debuggerReadMemory(adr));
|
||||||
*dest++=')';
|
*dest++=')';
|
||||||
}
|
}
|
||||||
if ((opcode&0x072f0000)==0x050f0000){
|
if ((opcode&0x072f0000)==0x050f0000)
|
||||||
|
{
|
||||||
*dest++ = '[';
|
*dest++ = '[';
|
||||||
*dest++ = '$';
|
*dest++ = '$';
|
||||||
int adr = offset+8;
|
int adr = offset+8;
|
||||||
@ -365,26 +395,34 @@ int disArm(u32 offset, char *dest, int flags){
|
|||||||
*dest++ = '$';
|
*dest++ = '$';
|
||||||
dest = addHex(dest ,32, debuggerReadMemory(adr));
|
dest = addHex(dest ,32, debuggerReadMemory(adr));
|
||||||
*dest++=')';
|
*dest++=')';
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
int reg = (opcode>>16)&15;
|
int reg = (opcode>>16)&15;
|
||||||
*dest++ = '[';
|
*dest++ = '[';
|
||||||
dest = addStr(dest, regs[reg]);
|
dest = addStr(dest, regs[reg]);
|
||||||
if (!(opcode&(1<<24)))
|
if (!(opcode&(1<<24)))
|
||||||
*dest++ = ']';
|
*dest++ = ']';
|
||||||
if ( ((opcode&(1<<25))&&(opcode&(1<<26))) || (!(opcode&(1<<22))&&!(opcode&(1<<26))) ){
|
if ( ((opcode&(1<<25))&&(opcode&(1<<26))) || (!(opcode&(1<<22))&&!(opcode&(1<<26))) )
|
||||||
|
{
|
||||||
dest = addStr(dest, ", ");
|
dest = addStr(dest, ", ");
|
||||||
if (!(opcode&(1<<23)))
|
if (!(opcode&(1<<23)))
|
||||||
*dest++ = '-';
|
*dest++ = '-';
|
||||||
dest = addStr(dest, regs[opcode&0x0f]);
|
dest = addStr(dest, regs[opcode&0x0f]);
|
||||||
int shi = (opcode>>5)&3;
|
int shi = (opcode>>5)&3;
|
||||||
if (opcode&(1<<26)){
|
if (opcode&(1<<26))
|
||||||
if ( ((opcode>>7)&0x1f) || (opcode&0x10) || (shi==1) || (shi==2)){
|
{
|
||||||
|
if ( ((opcode>>7)&0x1f) || (opcode&0x10) || (shi==1) || (shi==2))
|
||||||
|
{
|
||||||
dest = addStr(dest, ", ");
|
dest = addStr(dest, ", ");
|
||||||
dest = addStr(dest, shifts[shi]);
|
dest = addStr(dest, shifts[shi]);
|
||||||
if (opcode&0x10){
|
if (opcode&0x10)
|
||||||
|
{
|
||||||
*dest++ = ' ';
|
*dest++ = ' ';
|
||||||
dest = addStr(dest, regs[(opcode>>8)&15]);
|
dest = addStr(dest, regs[(opcode>>8)&15]);
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
int sdw = (opcode>>7)&0x1f;
|
int sdw = (opcode>>7)&0x1f;
|
||||||
if (sdw==0 && ( (shi==1) || (shi==2) ))
|
if (sdw==0 && ( (shi==1) || (shi==2) ))
|
||||||
sdw = 32;
|
sdw = 32;
|
||||||
@ -393,13 +431,16 @@ int disArm(u32 offset, char *dest, int flags){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
int off;
|
int off;
|
||||||
if (opcode&(1<<26))
|
if (opcode&(1<<26))
|
||||||
off = opcode&0xfff;
|
off = opcode&0xfff;
|
||||||
else
|
else
|
||||||
off = (opcode&15)|((opcode>>4)&0xf0);
|
off = (opcode&15)|((opcode>>4)&0xf0);
|
||||||
if (off){
|
if (off)
|
||||||
|
{
|
||||||
dest = addStr(dest, ", ");
|
dest = addStr(dest, ", ");
|
||||||
if (!(opcode&(1<<23)))
|
if (!(opcode&(1<<23)))
|
||||||
*dest++ = '-';
|
*dest++ = '-';
|
||||||
@ -407,7 +448,8 @@ int disArm(u32 offset, char *dest, int flags){
|
|||||||
dest = addHex(dest, 0, off);
|
dest = addHex(dest, 0, off);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (opcode&(1<<24)){
|
if (opcode&(1<<24))
|
||||||
|
{
|
||||||
*dest++ = ']';
|
*dest++ = ']';
|
||||||
if (opcode&(1<<21))
|
if (opcode&(1<<21))
|
||||||
*dest++ = '!';
|
*dest++ = '!';
|
||||||
@ -427,12 +469,14 @@ int disArm(u32 offset, char *dest, int flags){
|
|||||||
*dest++ = 'b';
|
*dest++ = 'b';
|
||||||
break;
|
break;
|
||||||
case 'm':
|
case 'm':
|
||||||
if (((opcode>>16)&15)==13) {
|
if (((opcode>>16)&15)==13)
|
||||||
|
{
|
||||||
if(opcode & 0x00100000)
|
if(opcode & 0x00100000)
|
||||||
dest = addStr(dest, armMultLoadStore[8+((opcode>>23)&3)]);
|
dest = addStr(dest, armMultLoadStore[8+((opcode>>23)&3)]);
|
||||||
else
|
else
|
||||||
dest = addStr(dest, armMultLoadStore[4+((opcode>>23)&3)]);
|
dest = addStr(dest, armMultLoadStore[4+((opcode>>23)&3)]);
|
||||||
} else
|
}
|
||||||
|
else
|
||||||
dest = addStr(dest, armMultLoadStore[(opcode>>23)&3]);
|
dest = addStr(dest, armMultLoadStore[(opcode>>23)&3]);
|
||||||
break;
|
break;
|
||||||
case 'l':
|
case 'l':
|
||||||
@ -443,8 +487,10 @@ int disArm(u32 offset, char *dest, int flags){
|
|||||||
int rlst = opcode&0xffff;
|
int rlst = opcode&0xffff;
|
||||||
int msk = 0;
|
int msk = 0;
|
||||||
int not_first = 0;
|
int not_first = 0;
|
||||||
while (msk<16){
|
while (msk<16)
|
||||||
if (rlst&(1<<msk)){
|
{
|
||||||
|
if (rlst&(1<<msk))
|
||||||
|
{
|
||||||
int fr = msk;
|
int fr = msk;
|
||||||
while (rlst&(1<<msk))
|
while (rlst&(1<<msk))
|
||||||
msk++;
|
msk++;
|
||||||
@ -453,7 +499,8 @@ int disArm(u32 offset, char *dest, int flags){
|
|||||||
//dest = addStr(dest, ", ");
|
//dest = addStr(dest, ", ");
|
||||||
*dest++ = ',';
|
*dest++ = ',';
|
||||||
dest = addStr(dest, regs[fr]);
|
dest = addStr(dest, regs[fr]);
|
||||||
if (fr!=to){
|
if (fr!=to)
|
||||||
|
{
|
||||||
if (fr==to-1)
|
if (fr==to-1)
|
||||||
//dest = addStr(", ");
|
//dest = addStr(", ");
|
||||||
*dest++ = ',';
|
*dest++ = ',';
|
||||||
@ -462,7 +509,8 @@ int disArm(u32 offset, char *dest, int flags){
|
|||||||
dest = addStr(dest, regs[to]);
|
dest = addStr(dest, regs[to]);
|
||||||
}
|
}
|
||||||
not_first = 1;
|
not_first = 1;
|
||||||
} else
|
}
|
||||||
|
else
|
||||||
msk++;
|
msk++;
|
||||||
}
|
}
|
||||||
*dest++ = '}';
|
*dest++ = '}';
|
||||||
@ -495,7 +543,8 @@ int disArm(u32 offset, char *dest, int flags){
|
|||||||
case 'V':
|
case 'V':
|
||||||
{
|
{
|
||||||
int val = (opcode>>5)&7;
|
int val = (opcode>>5)&7;
|
||||||
if (val){
|
if (val)
|
||||||
|
{
|
||||||
dest = addStr(dest, ", ");
|
dest = addStr(dest, ", ");
|
||||||
dest = addStr(dest, decVals[val]);
|
dest = addStr(dest, decVals[val]);
|
||||||
}
|
}
|
||||||
@ -506,7 +555,8 @@ int disArm(u32 offset, char *dest, int flags){
|
|||||||
*dest++ = 'l';
|
*dest++ = 'l';
|
||||||
break;
|
break;
|
||||||
case 'A':
|
case 'A':
|
||||||
if ((opcode&0x012f0000)==0x010f0000){
|
if ((opcode&0x012f0000)==0x010f0000)
|
||||||
|
{
|
||||||
int adr = offset+8;
|
int adr = offset+8;
|
||||||
int add = (opcode&0xff)<<2;
|
int add = (opcode&0xff)<<2;
|
||||||
if (opcode&(1<<23))
|
if (opcode&(1<<23))
|
||||||
@ -515,20 +565,24 @@ int disArm(u32 offset, char *dest, int flags){
|
|||||||
adr -= add;
|
adr -= add;
|
||||||
*dest++ = '$';
|
*dest++ = '$';
|
||||||
addHex(dest, 32, adr);
|
addHex(dest, 32, adr);
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
*dest++ = '[';
|
*dest++ = '[';
|
||||||
dest = addStr(dest, regs[(opcode>>16)&15]);
|
dest = addStr(dest, regs[(opcode>>16)&15]);
|
||||||
if (!(opcode&(1<<24)))
|
if (!(opcode&(1<<24)))
|
||||||
*dest++ = ']';
|
*dest++ = ']';
|
||||||
int off = (opcode&0xff)<<2;
|
int off = (opcode&0xff)<<2;
|
||||||
if (off){
|
if (off)
|
||||||
|
{
|
||||||
dest = addStr(dest, ", ");
|
dest = addStr(dest, ", ");
|
||||||
if (!(opcode&(1<<23)))
|
if (!(opcode&(1<<23)))
|
||||||
*dest++ = '-';
|
*dest++ = '-';
|
||||||
dest = addStr(dest, "#0x");
|
dest = addStr(dest, "#0x");
|
||||||
dest = addHex(dest, 0, off);
|
dest = addHex(dest, 0, off);
|
||||||
}
|
}
|
||||||
if (opcode&(1<<24)){
|
if (opcode&(1<<24))
|
||||||
|
{
|
||||||
*dest++ = ']';
|
*dest++ = ']';
|
||||||
if (opcode&(1<<21))
|
if (opcode&(1<<21))
|
||||||
*dest++ = '!';
|
*dest++ = '!';
|
||||||
@ -544,7 +598,8 @@ int disArm(u32 offset, char *dest, int flags){
|
|||||||
return 4;
|
return 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
int disThumb(u32 offset, char *dest, int flags){
|
int disThumb(u32 offset, char *dest, int flags)
|
||||||
|
{
|
||||||
u32 opcode = debuggerReadHalfWord(offset);
|
u32 opcode = debuggerReadHalfWord(offset);
|
||||||
|
|
||||||
const Opcodes *sp = thumbOpcodes;
|
const Opcodes *sp = thumbOpcodes;
|
||||||
@ -552,22 +607,27 @@ int disThumb(u32 offset, char *dest, int flags){
|
|||||||
while( sp->cval != (opcode & sp->mask) )
|
while( sp->cval != (opcode & sp->mask) )
|
||||||
sp++;
|
sp++;
|
||||||
|
|
||||||
if (flags&DIS_VIEW_ADDRESS){
|
if (flags&DIS_VIEW_ADDRESS)
|
||||||
|
{
|
||||||
dest = addHex(dest, 32, offset);
|
dest = addHex(dest, 32, offset);
|
||||||
*dest++ = ' ';
|
*dest++ = ' ';
|
||||||
}
|
}
|
||||||
if (flags&DIS_VIEW_CODE){
|
if (flags&DIS_VIEW_CODE)
|
||||||
|
{
|
||||||
dest = addHex(dest, 16, opcode);
|
dest = addHex(dest, 16, opcode);
|
||||||
*dest++ = ' ';
|
*dest++ = ' ';
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *src = sp->mnemonic;
|
char *src = sp->mnemonic;
|
||||||
while (*src){
|
while (*src)
|
||||||
|
{
|
||||||
if (*src!='%')
|
if (*src!='%')
|
||||||
*dest++ = *src++;
|
*dest++ = *src++;
|
||||||
else {
|
else
|
||||||
|
{
|
||||||
src++;
|
src++;
|
||||||
switch (*src){
|
switch (*src)
|
||||||
|
{
|
||||||
case 'r':
|
case 'r':
|
||||||
src++;
|
src++;
|
||||||
dest = addStr(dest, regs[(opcode>>(*src-'0'))&7]);
|
dest = addStr(dest, regs[(opcode>>(*src-'0'))&7]);
|
||||||
@ -620,8 +680,9 @@ int disThumb(u32 offset, char *dest, int flags){
|
|||||||
((opcode & 0xff)<<2));
|
((opcode & 0xff)<<2));
|
||||||
*dest++ = '$';
|
*dest++ = '$';
|
||||||
dest = addHex(dest, 32, value);
|
dest = addHex(dest, 32, value);
|
||||||
const char *s = elfGetAddressSymbol(value);
|
char *s = elfGetAddressSymbol(value);
|
||||||
if(*s) {
|
if(*s)
|
||||||
|
{
|
||||||
*dest++ = ' ';
|
*dest++ = ' ';
|
||||||
dest = addStr(dest, s);
|
dest = addStr(dest, s);
|
||||||
}
|
}
|
||||||
@ -632,8 +693,9 @@ int disThumb(u32 offset, char *dest, int flags){
|
|||||||
u32 value = (offset&0xfffffffc)+4+((opcode & 0xff)<<2);
|
u32 value = (offset&0xfffffffc)+4+((opcode & 0xff)<<2);
|
||||||
*dest++ = '$';
|
*dest++ = '$';
|
||||||
dest = addHex(dest, 32, value);
|
dest = addHex(dest, 32, value);
|
||||||
const char *s = elfGetAddressSymbol(value);
|
char *s = elfGetAddressSymbol(value);
|
||||||
if(*s) {
|
if(*s)
|
||||||
|
{
|
||||||
*dest++ = ' ';
|
*dest++ = ' ';
|
||||||
dest = addStr(dest, s);
|
dest = addStr(dest, s);
|
||||||
}
|
}
|
||||||
@ -674,8 +736,10 @@ int disThumb(u32 offset, char *dest, int flags){
|
|||||||
int rlst = opcode&0xff;
|
int rlst = opcode&0xff;
|
||||||
int msk = 0;
|
int msk = 0;
|
||||||
int not_first = 0;
|
int not_first = 0;
|
||||||
while (msk<8){
|
while (msk<8)
|
||||||
if (rlst&(1<<msk)){
|
{
|
||||||
|
if (rlst&(1<<msk))
|
||||||
|
{
|
||||||
int fr = msk;
|
int fr = msk;
|
||||||
while (rlst&(1<<msk))
|
while (rlst&(1<<msk))
|
||||||
msk++;
|
msk++;
|
||||||
@ -683,7 +747,8 @@ int disThumb(u32 offset, char *dest, int flags){
|
|||||||
if (not_first)
|
if (not_first)
|
||||||
*dest++ = ',';
|
*dest++ = ',';
|
||||||
dest = addStr(dest, regs[fr]);
|
dest = addStr(dest, regs[fr]);
|
||||||
if (fr!=to){
|
if (fr!=to)
|
||||||
|
{
|
||||||
if (fr==to-1)
|
if (fr==to-1)
|
||||||
*dest++ = ',';
|
*dest++ = ',';
|
||||||
else
|
else
|
||||||
@ -691,7 +756,8 @@ int disThumb(u32 offset, char *dest, int flags){
|
|||||||
dest = addStr(dest, regs[to]);
|
dest = addStr(dest, regs[to]);
|
||||||
}
|
}
|
||||||
not_first = 1;
|
not_first = 1;
|
||||||
} else
|
}
|
||||||
|
else
|
||||||
msk++;
|
msk++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -723,8 +789,9 @@ int disThumb(u32 offset, char *dest, int flags){
|
|||||||
add = (add<<12)|((nopcode&0x7ff)<<1);
|
add = (add<<12)|((nopcode&0x7ff)<<1);
|
||||||
*dest++ = '$';
|
*dest++ = '$';
|
||||||
dest = addHex(dest,32, offset+4+add);
|
dest = addHex(dest,32, offset+4+add);
|
||||||
const char *s = elfGetAddressSymbol(offset+4+add);
|
char *s = elfGetAddressSymbol(offset+4+add);
|
||||||
if(*s) {
|
if(*s)
|
||||||
|
{
|
||||||
*dest++ = ' ';
|
*dest++ = ' ';
|
||||||
*dest++ = '(';
|
*dest++ = '(';
|
||||||
dest = addStr(dest, s);
|
dest = addStr(dest, s);
|
||||||
|
432
source/vba/bilinear.cpp
Normal file
432
source/vba/bilinear.cpp
Normal 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
Loading…
x
Reference in New Issue
Block a user