optimizations from dancinninja

This commit is contained in:
dborth 2010-01-24 18:26:31 +00:00
parent 686a33a760
commit 058ac87b86
8 changed files with 629 additions and 475 deletions

View File

@ -23,14 +23,14 @@ public:
// Global configuration
struct config_t
{
bool enabled; // false = disable all effects
pan_vol_t side_chans [2]; // left and right side channel volume and pan
// Current sound is echoed at adjustable left/right delay,
// with reduced treble and volume (feedback).
float treble; // 1.0 = full treble, 0.1 = very little, 0.0 = silent
int delay [2]; // left, right delays (msec)
float feedback; // 0.0 = no echo, 0.5 = each echo half previous, 1.0 = cacophony
pan_vol_t side_chans [2]; // left and right side channel volume and pan
float treble; // 1.0 = full treble, 0.1 = very little, 0.0 = silent
float feedback; // 0.0 = no echo, 0.5 = each echo half previous, 1.0 = cacophony
int delay [2]; // left, right delays (msec)
bool enabled; // false = disable all effects
};
config_t& config() { return config_; }
@ -123,10 +123,10 @@ class Simple_Effects_Buffer : public Effects_Buffer {
public:
struct config_t
{
bool enabled; // false = disable all effects
float echo; // 0.0 = none, 1.0 = lots
float stereo; // 0.0 = channels in center, 1.0 = channels on left/right
bool surround; // true = put some channels in back
bool enabled; // false = disable all effects
};
config_t& config() { return config_; }

View File

@ -583,7 +583,8 @@ u8 ZeroTable[256] = {
int inline gbGetValue(int min,int max,int v)
{
return (int)(min+(float)(max-min)*(2.0*(v/31.0)-(v/31.0)*(v/31.0)));
float o31 = float(v) / 31.0f;
return (min +((int)((float)(max-min)* o31*(2.0f - o31))));
}
void gbGenFilter()
@ -631,9 +632,9 @@ void gbCopyMemory(u16 d, u16 s, int count)
{
while(count) {
gbMemoryMap[d>>12][d & 0x0fff] = gbMemoryMap[s>>12][s & 0x0fff];
s++;
d++;
count--;
++s;
++d;
--count;
}
}
@ -670,7 +671,7 @@ void gbDoHdma()
gbDmaTicks = 9;
if (IFF & 0x80)
gbDmaTicks++;
++gbDmaTicks;
}
@ -888,16 +889,14 @@ void gbWriteMemory(register u16 address, register u8 value)
{
bool temp = false;
if ((gbTimerOn && !gbTimerModeChange) && (gbTimerMode & 2) &&
if (((gbTimerOn && !gbTimerModeChange) && (gbTimerMode & 2) &&
!(gbInternalTimer & 0x80) && (gbInternalTimer & (gbTimerClockTicks>>1)) &&
!(gbInternalTimer & (gbTimerClockTicks>>5)))
temp = true;
else if ((!gbTimerOn && !gbTimerModeChange && gbTimerOnChange ) && ((gbTimerTicks-1) < (gbTimerClockTicks>>1)))
temp = true;
else if (gbTimerOn && gbTimerModeChange && !gbTimerOnChange)
{
switch(gbTimerMode & 3)
{
!(gbInternalTimer & (gbTimerClockTicks>>5)))
||
((!gbTimerOn && !gbTimerModeChange && gbTimerOnChange ) && ((gbTimerTicks-1) < (gbTimerClockTicks>>1)))){
temp = true;
}else if (gbTimerOn && gbTimerModeChange && !gbTimerOnChange){
switch(gbTimerMode & 3){
case 0x00:
temp = false;
break;
@ -1016,8 +1015,6 @@ void gbWriteMemory(register u16 address, register u8 value)
// systemDrawScreen();
gbRegisterLYLCDCOffOn = (register_LY + 144) % 154;
gbLcdTicks = GBLCD_MODE_2_CLOCK_TICKS - (gbSpeed ? 2 : 1);
@ -1122,13 +1119,24 @@ void gbWriteMemory(register u16 address, register u8 value)
temp = ((GBLY_INCREMENT_CLOCK_TICKS-GBLCD_MODE_2_CLOCK_TICKS) -
gbLcdLYIncrementTicks);
if (temp >=0)
{
for (int i=temp<<(gbSpeed ? 1 : 2);i<300;i++)
if (temp < 300)
gbSCYLine[i] = value;
if (temp >=0){
if (temp < 300){
int i = temp << (gbSpeed ? 1 : 2);
if((i % 2) == 0){ // Divisible by 2
// If it is divisible by 2, it'll go much faster
for (; i < 300; i += 2){
gbSCYLine[i] =
gbSCYLine[i+1] = value;
}
}else{ // Not divisible by 2
for (; i < 300; ++i){
gbSCYLine[i] = value;
}
}
}
}
else
memset(gbSCYLine, value, sizeof(gbSCYLine));
@ -1146,9 +1154,22 @@ void gbWriteMemory(register u16 address, register u8 value)
if (temp >=0)
{
for (int i=temp<<(gbSpeed ? 1 : 2);i<300;i++)
if (temp < 300)
gbSCXLine[i] = value;
if (temp < 300){
int i = temp << (gbSpeed ? 1 : 2);
if((i % 2) == 0){ // Divisible by 2
// If it is divisible by 2, it'll go much faster
for (; i < 300; i += 2){
gbSCXLine[i] =
gbSCXLine[i+1] = value;
}
}else{ // Not divisible by 2
for (; i < 300; ++i){
gbSCXLine[i] = value;
}
}
}
}
else
@ -1178,11 +1199,8 @@ void gbWriteMemory(register u16 address, register u8 value)
// DMA!
case 0x46: {
int source = value * 0x0100;
gbCopyMemory(0xfe00,
source,
0xa0);
int source = value << 8;
gbCopyMemory(0xfe00, source, 0xa0);
gbMemory[0xff46] = register_DMA = value;
return;
}
@ -1200,9 +1218,21 @@ void gbWriteMemory(register u16 address, register u8 value)
if (temp >=0)
{
for (int i=temp<<(gbSpeed ? 1 : 2);i<300;i++)
if (temp < 300)
gbBgpLine[i] = value;
if (temp < 300){
int i = temp << (gbSpeed ? 1 : 2);
if((i % 2) == 0){ // Divisible by 2
// If it is divisible by 2, it'll go much faster
for (; i < 300; i += 2){
gbBgpLine[i] =
gbBgpLine[i+1] = value;
}
}else{ // Not divisible by 2
for (; i < 300; ++i){
gbBgpLine[i] = value;
}
}
}
}
else
memset(gbBgpLine,value,sizeof(gbBgpLine));
@ -1223,9 +1253,21 @@ void gbWriteMemory(register u16 address, register u8 value)
if (temp >=0)
{
for (int i=temp<<(gbSpeed ? 1 : 2);i<300;i++)
if (temp < 300)
gbObp0Line[i] = value;
if (temp < 300){
int i = temp << (gbSpeed ? 1 : 2);
if((i % 2) == 0){ // Divisible by 2
// If it is divisible by 2, it'll go much faster
for (; i < 300; i += 2){
gbObp0Line[i] =
gbObp0Line[i+1] = value;
}
}else{ // Not divisible by 2
for (; i < 300; ++i){
gbObp0Line[i] = value;
}
}
}
}
else
memset(gbObp0Line,value,sizeof(gbObp0Line));
@ -1246,9 +1288,21 @@ void gbWriteMemory(register u16 address, register u8 value)
if (temp >=0)
{
for (int i=temp<<(gbSpeed ? 1 : 2);i<300;i++)
if (temp < 300)
gbObp1Line[i] = value;
if (temp < 300){
int i = temp << (gbSpeed ? 1 : 2);
if((i % 2) == 0){ // Divisible by 2
// If it is divisible by 2, it'll go much faster
for (; i < 300; i += 2){
gbObp1Line[i] =
gbObp1Line[i+1] = value;
}
}else{ // Not divisible by 2
for (; i < 300; ++i){
gbObp1Line[i] = value;
}
}
}
}
else
memset(gbObp1Line,value,sizeof(gbObp1Line));
@ -1284,11 +1338,11 @@ void gbWriteMemory(register u16 address, register u8 value)
// VBK
case 0x4f: {
if(gbCgbMode) {
value = value & 1;
value &= 1;
if(value == gbVramBank)
return;
int vramAddress = value * 0x2000;
int vramAddress = value << 13; //* 0x2000
gbMemoryMap[0x08] = &gbVram[vramAddress];
gbMemoryMap[0x09] = &gbVram[vramAddress + 0x1000];
@ -1365,7 +1419,7 @@ void gbWriteMemory(register u16 address, register u8 value)
case 0x55: {
if(gbCgbMode) {
gbHdmaBytes = 16 + (value & 0x7f) * 16;
gbHdmaBytes = 16 + ((value & 0x7f) <<4);
if(gbHdmaOn) {
if(value & 0x80) {
gbMemory[0xff55] = register_HDMA5 = (value & 0x7f);
@ -1384,10 +1438,10 @@ void gbWriteMemory(register u16 address, register u8 value)
// account... according to GB DEV FAQs, the setup time is the same
// for single and double speed, but the actual transfer takes the
// same time
if(gbSpeed)
gbDmaTicks = 2+16 * ((value & 0x7f) +1);
if(gbSpeed)
gbDmaTicks = 2 + (((value & 0x7f) + 1) << 4);
else
gbDmaTicks = 1+8 * ((value & 0x7f)+1);
gbDmaTicks = 1 + (((value & 0x7f) + 1) << 3);
gbCopyMemory((gbHdmaDestination & 0x1ff0) | 0x8000,
gbHdmaSource & 0xfff0,
@ -1395,11 +1449,17 @@ void gbWriteMemory(register u16 address, register u8 value)
gbHdmaDestination += gbHdmaBytes;
gbHdmaSource += gbHdmaBytes;
gbMemory[0xff51] = register_HDMA1 = 0xff;// = (gbHdmaSource >> 8) & 0xff;
gbMemory[0xff52] = register_HDMA2 = 0xff;// = gbHdmaSource & 0xf0;
gbMemory[0xff53] = register_HDMA3 = 0xff;// = ((gbHdmaDestination - 0x8000) >> 8) & 0x1f;
gbMemory[0xff54] = register_HDMA4 = 0xff;// = gbHdmaDestination & 0xf0;
gbMemory[0xff55] = register_HDMA5 = 0xff;
// Spacial alignemnt
gbMemory[0xff51] =
gbMemory[0xff52] =
gbMemory[0xff53] =
gbMemory[0xff54] =
gbMemory[0xff55] = 0xff;
register_HDMA1 =
register_HDMA2 =
register_HDMA3 =
register_HDMA4 =
register_HDMA5 = 0xff;
}
}
return;
@ -1532,7 +1592,7 @@ void gbWriteMemory(register u16 address, register u8 value)
if(bank == gbWramBank)
return;
int wramAddress = bank * 0x1000;
int wramAddress = bank << 12; //* 0x1000
gbMemoryMap[0x0d] = &gbWram[wramAddress];
gbWramBank = bank;
@ -1777,20 +1837,18 @@ u8 gbReadMemory(register u16 address)
int joy = 0;
if(gbSgbMode && gbSgbMultiplayer) {
switch(gbSgbNextController) {
case 0x0f:
joy = 0;
break;
case 0x0e:
joy = 1;
break;
case 0x0d:
joy = 2;
break;
case 0x0c:
joy = 3;
break;
default:
joy = 0;
case 0x0f:
default:
break;
case 0x0e:
joy = 1;
break;
case 0x0d:
joy = 2;
break;
case 0x0c:
joy = 3;
break;
}
}
int joystate = gbJoymask[joy];
@ -1810,20 +1868,18 @@ u8 gbReadMemory(register u16 address)
int joy = 0;
if(gbSgbMode && gbSgbMultiplayer) {
switch(gbSgbNextController) {
case 0x0f:
joy = 0;
break;
case 0x0e:
joy = 1;
break;
case 0x0d:
joy = 2;
break;
case 0x0c:
joy = 3;
break;
default:
joy = 0;
case 0x0f:
default:
break;
case 0x0e:
joy = 1;
break;
case 0x0d:
joy = 2;
break;
case 0x0c:
joy = 3;
break;
}
}
int joystate = gbJoymask[joy];
@ -2017,24 +2073,24 @@ void gbSpeedSwitch()
gbBlackScreen = true;
if(gbSpeed == 0) {
gbSpeed = 1;
GBLCD_MODE_0_CLOCK_TICKS = 51 * 2;
GBLCD_MODE_1_CLOCK_TICKS = 1140 * 2;
GBLCD_MODE_2_CLOCK_TICKS = 20 * 2;
GBLCD_MODE_3_CLOCK_TICKS = 43 * 2;
GBLY_INCREMENT_CLOCK_TICKS = 114 * 2;
GBLCD_MODE_0_CLOCK_TICKS = 51 << 1;
GBLCD_MODE_1_CLOCK_TICKS = 1140 << 1;
GBLCD_MODE_2_CLOCK_TICKS = 20 << 1;
GBLCD_MODE_3_CLOCK_TICKS = 43 << 1;
GBLY_INCREMENT_CLOCK_TICKS = 114 << 1;
GBDIV_CLOCK_TICKS = 64;
GBTIMER_MODE_0_CLOCK_TICKS = 256;
GBTIMER_MODE_1_CLOCK_TICKS = 4;
GBTIMER_MODE_2_CLOCK_TICKS = 16;
GBTIMER_MODE_3_CLOCK_TICKS = 64;
GBSERIAL_CLOCK_TICKS = 128 * 2;
gbLcdTicks *= 2;
gbLcdTicksDelayed *=2;
gbLcdTicksDelayed--;
gbLcdLYIncrementTicks *= 2;
gbLcdLYIncrementTicksDelayed *= 2;
gbLcdLYIncrementTicksDelayed--;
gbSerialTicks *= 2;
GBSERIAL_CLOCK_TICKS = 128 << 1;
gbLcdTicks <<= 1;
gbLcdTicksDelayed <<= 1;
--gbLcdTicksDelayed;
gbLcdLYIncrementTicks <<= 1;
gbLcdLYIncrementTicksDelayed <<= 1;
--gbLcdLYIncrementTicksDelayed;
gbSerialTicks <<= 1;
//SOUND_CLOCK_TICKS = soundQuality * 24 * 2;
//soundTicks *= 2;
gbLine99Ticks = 3;
@ -2052,17 +2108,17 @@ void gbSpeedSwitch()
GBTIMER_MODE_3_CLOCK_TICKS = 64;
GBSERIAL_CLOCK_TICKS = 128;
gbLcdTicks >>= 1;
gbLcdTicksDelayed++;
++gbLcdTicksDelayed;
gbLcdTicksDelayed >>=1;
gbLcdLYIncrementTicks >>= 1;
gbLcdLYIncrementTicksDelayed++;
++gbLcdLYIncrementTicksDelayed;
gbLcdLYIncrementTicksDelayed >>= 1;
gbSerialTicks /= 2;
gbSerialTicks >>= 1;
//SOUND_CLOCK_TICKS = soundQuality * 24;
//soundTicks /= 2;
gbLine99Ticks = 1;
if (gbHardware & 8)
gbLine99Ticks++;
++gbLine99Ticks;
}
gbDmaTicks += (134)*GBLY_INCREMENT_CLOCK_TICKS + (37<<(gbSpeed ? 1 : 0));
}
@ -2110,18 +2166,15 @@ void gbGetHardwareType()
gbCgbMode = 0;
gbSgbMode = 0;
if(gbRom[0x143] & 0x80) {
if((gbEmulatorType == 0) ||
gbEmulatorType == 1 ||
gbEmulatorType == 4) {
if((1<<gbEmulatorType) & ((1<<0)|(1<<1)|(1<<4))){
gbCgbMode = 1;
}
}
if((gbCgbMode == 0 ) && (gbRom[0x146] == 0x03)) {
if(gbEmulatorType == 0 ||
gbEmulatorType == 2 ||
gbEmulatorType == 5)
if((1<<gbEmulatorType) & ((1<<0)|(1<<2)|(1<<5))){
gbSgbMode = 1;
}
}
gbHardware = 1; // GB
@ -3698,17 +3751,24 @@ static bool gbReadSaveState(gzFile gzFile)
memset(pix, 0, 257*226*sizeof(u32));
if(version < GBSAVE_GAME_VERSION_6) {
utilGzRead(gzFile, gbPalette, 64 * sizeof(u16));
} else
utilGzRead(gzFile, gbPalette, 128 * sizeof(u16));
utilGzRead(gzFile, gbPalette, (sizeof(u16)<<6));
} else{
utilGzRead(gzFile, gbPalette, (sizeof(u16)<<7));
}
if (version < 11)
utilGzRead(gzFile, gbPalette, 128 * sizeof(u16));
if (version < 11){
utilGzRead(gzFile, gbPalette, (sizeof(u16)<<7));
}
if(version < GBSAVE_GAME_VERSION_10) {
if(!gbCgbMode && !gbSgbMode) {
for(int i = 0; i < 8; i++)
gbPalette[i] = systemGbPalette[gbPaletteOption*8+i];
if(gbCgbMode || gbSgbMode) {
int gbp8 = gbPaletteOption << 3;
for(int i = 0; i < 8; i+=4){
gbPalette[i ] = systemGbPalette[gbp8+i ];
gbPalette[i+1] = systemGbPalette[gbp8+i+1];
gbPalette[i+2] = systemGbPalette[gbp8+i+2];
gbPalette[i+3] = systemGbPalette[gbp8+i+3];
}
}
}
@ -3837,9 +3897,9 @@ static bool gbReadSaveState(gzFile gzFile)
if(value == 0)
value = 1;
gbMemoryMap[0x08] = &gbVram[register_VBK * 0x2000];
gbMemoryMap[0x09] = &gbVram[register_VBK * 0x2000 + 0x1000];
gbMemoryMap[0x0d] = &gbWram[value * 0x1000];
gbMemoryMap[0x08] = &gbVram[register_VBK << 13];
gbMemoryMap[0x09] = &gbVram[(register_VBK << 13) + 0x1000];
gbMemoryMap[0x0d] = &gbWram[value << 12];
}
gbSoundReadGame(version, gzFile);
@ -3889,7 +3949,7 @@ static bool gbReadSaveState(gzFile gzFile)
GBDIV_CLOCK_TICKS = 64;
if (gbSpeed)
gbDivTicks /=2;
gbDivTicks >>=1;
if ((gbLcdMode == 0) && (register_STAT & 8))
gbInt48Signal |= 1;
@ -3940,7 +4000,7 @@ static bool gbReadSaveState(gzFile gzFile)
}
if (gbSpeed)
gbLine99Ticks *= 2;
gbLine99Ticks <<= 1;
systemSaveUpdateCounter = SYSTEM_SAVE_NOT_UPDATED;
@ -3949,7 +4009,6 @@ static bool gbReadSaveState(gzFile gzFile)
return true;
}
bool gbReadMemSaveState(char *memory, int available)
{
gzFile gzFile = utilMemGzOpen(memory, available, "r");
@ -4084,8 +4143,11 @@ bool gbUpdateSizes()
if(gbRomSize < gbRomSizes[gbRom[0x148]]) {
gbRom = (u8 *)realloc(gbRom, gbRomSizes[gbRom[0x148]]);
for (int i = gbRomSize; i<gbRomSizes[gbRom[0x148]]; i++)
int gbrSize = gbRomSizes[gbRom[0x148]];
for (int i = gbRomSize; i < gbrSize; ++i){
gbRom[i] = 0x00; // Not sure if it's 0x00, 0xff or random data...
}
}
// (it's in the case a cart is 'lying' on its size.
else if ((gbRomSize>gbRomSizes[gbRom[0x148]]) && (genericflashcardEnable))
@ -4096,10 +4158,10 @@ bool gbUpdateSizes()
{
while (!((gbRomSize & 1) || (gbRom[0x148] == 7)))
{
gbRom[0x148]++;
++gbRom[0x148];
gbRomSize>>=1;
}
gbRom[0x148]++;
++gbRom[0x148];
}
gbRom = (u8 *)realloc(gbRom, gbRomSizes[gbRom[0x148]]);
}
@ -4118,17 +4180,29 @@ bool gbUpdateSizes()
u8 ramsize = genericflashcardEnable ? 5 : gbRom[0x149];
gbRom[0x149] = ramsize;
if ((gbRom[2] == 0x6D) && (gbRom[5] == 0x47) && (gbRom[6] == 0x65) && (gbRom[7] == 0x6E) &&
(gbRom[8] == 0x69) && (gbRom[9] == 0x65) && (gbRom[0xA] == 0x28) && (gbRom[0xB] == 0x54))
if(((gbRom[2] - 0x6D) | (gbRom[5] - 0x47) | (gbRom[6] - 0x65) | (gbRom[7] - 0x6E) |
(gbRom[8] - 0x69) | (gbRom[9] - 0x65) | (gbRom[0xA] - 0x28) | (gbRom[0xB] - 0x54)) == 0)
{
gbCheatingDevice = 1; // GameGenie
for (int i = 0; i < 0x20; i++) // Cleans GG hardware registers
gbRom[0x4000+i] = 0;
for (int i = 0; i < 0x20; i+=8){ // Cleans GG hardware registers
gbRom[0x4000+i] =
gbRom[0x4001+i] =
gbRom[0x4002+i] =
gbRom[0x4003+i] =
gbRom[0x4004+i] =
gbRom[0x4005+i] =
gbRom[0x4006+i] =
gbRom[0x4007+i] = 0;
}
}
else if((((gbRom[0x104] - 0x44) | (gbRom[0x156] - 0xEA) | (gbRom[0x158] - 0x7F) |
(gbRom[0x159] - 0xEA) | (gbRom[0x15B] - 0x7F)) == 0)
|| (((gbRom[0x165] - 0x3E) | (gbRom[0x166] - 0xD9) | (gbRom[0x16D] - 0xE1) | (gbRom[0x16E] - 0x7F)) == 0))
{
gbCheatingDevice = 2; // GameShark
}
else if (((gbRom[0x104] == 0x44) && (gbRom[0x156] == 0xEA) && (gbRom[0x158] == 0x7F) &&
(gbRom[0x159] == 0xEA) && (gbRom[0x15B] == 0x7F)) || ((gbRom[0x165] == 0x3E) &&
(gbRom[0x166] == 0xD9) && (gbRom[0x16D] == 0xE1) && (gbRom[0x16E] == 0x7F)))
gbCheatingDevice = 2; // GameShark
else gbCheatingDevice = 0;
if(ramsize > 5) {
@ -4143,16 +4217,6 @@ bool gbUpdateSizes()
gbRomType = gbRom[0x147];
if (genericflashcardEnable)
{
/*if (gbRomType<2)
gbRomType =3;
else if ((gbRomType == 0xc) || (gbRomType == 0xf) || (gbRomType == 0x12) ||
(gbRomType == 0x16) || (gbRomType == 0x1a) || (gbRomType == 0x1d))
gbRomType++;
else if ((gbRomType == 0xb) || (gbRomType == 0x11) || (gbRomType == 0x15) ||
(gbRomType == 0x19) || (gbRomType == 0x1c))
gbRomType+=2;
else if ((gbRomType == 0x5) || (gbRomType == 0x6))
gbRomType = 0x1a;*/
gbRomType = 0x1b;
}
else if (gbCheatingDevice == 1)
@ -4308,7 +4372,6 @@ bool gbUpdateSizes()
return true;
}
int gbGetNextEvent (int clockTicks)
{
if (register_LCDC & 0x80)
@ -4349,26 +4412,27 @@ void gbDrawLine()
u16 * dest = (u16 *)pix +
(gbBorderLineSkip+2) * (register_LY + gbBorderRowSkip+1)
+ gbBorderColumnSkip;
for(int x = 0; x < 160; ) {
*dest++ = systemColorMap16[gbLineMix[x++]];
*dest++ = systemColorMap16[gbLineMix[x++]];
*dest++ = systemColorMap16[gbLineMix[x++]];
*dest++ = systemColorMap16[gbLineMix[x++]];
for(u32 x = 0; x < 160u; ) {
dest[x ] = systemColorMap16[gbLineMix[x ]];
dest[x+1] = systemColorMap16[gbLineMix[x+1]];
dest[x+2] = systemColorMap16[gbLineMix[x+2]];
dest[x+3] = systemColorMap16[gbLineMix[x+3]];
*dest++ = systemColorMap16[gbLineMix[x++]];
*dest++ = systemColorMap16[gbLineMix[x++]];
*dest++ = systemColorMap16[gbLineMix[x++]];
*dest++ = systemColorMap16[gbLineMix[x++]];
dest[x+4] = systemColorMap16[gbLineMix[x+4]];
dest[x+5] = systemColorMap16[gbLineMix[x+5]];
dest[x+6] = systemColorMap16[gbLineMix[x+6]];
dest[x+7] = systemColorMap16[gbLineMix[x+7]];
*dest++ = systemColorMap16[gbLineMix[x++]];
*dest++ = systemColorMap16[gbLineMix[x++]];
*dest++ = systemColorMap16[gbLineMix[x++]];
*dest++ = systemColorMap16[gbLineMix[x++]];
dest[x+8] = systemColorMap16[gbLineMix[x+8]];
dest[x+9] = systemColorMap16[gbLineMix[x+9]];
dest[x+10] = systemColorMap16[gbLineMix[x+10]];
dest[x+11] = systemColorMap16[gbLineMix[x+11]];
*dest++ = systemColorMap16[gbLineMix[x++]];
*dest++ = systemColorMap16[gbLineMix[x++]];
*dest++ = systemColorMap16[gbLineMix[x++]];
*dest++ = systemColorMap16[gbLineMix[x++]];
dest[x+12] = systemColorMap16[gbLineMix[x+12]];
dest[x+13] = systemColorMap16[gbLineMix[x+13]];
dest[x+14] = systemColorMap16[gbLineMix[x+14]];
dest[x+15] = systemColorMap16[gbLineMix[x+15]];
x += 16;
}
if(gbBorderOn)
dest += gbBorderColumnSkip;
@ -4381,7 +4445,7 @@ void gbDrawLine()
u8 *dest = (u8 *)pix +
3*(gbBorderLineSkip * (register_LY + gbBorderRowSkip) +
gbBorderColumnSkip);
for(int x = 0; x < 160;) {
for(u32 x = 0; x < 160;) {
*((u32 *)dest) = systemColorMap32[gbLineMix[x++]];
dest+= 3;
*((u32 *)dest) = systemColorMap32[gbLineMix[x++]];
@ -4426,32 +4490,32 @@ void gbDrawLine()
u32 * dest = (u32 *)pix +
(gbBorderLineSkip+1) * (register_LY + gbBorderRowSkip+1)
+ gbBorderColumnSkip;
for(int x = 0; x < 160;) {
*dest++ = systemColorMap32[gbLineMix[x++]];
*dest++ = systemColorMap32[gbLineMix[x++]];
*dest++ = systemColorMap32[gbLineMix[x++]];
*dest++ = systemColorMap32[gbLineMix[x++]];
for(u32 x = 0; x < 160u; ) {
dest[x ] = systemColorMap32[gbLineMix[x ]];
dest[x+1] = systemColorMap32[gbLineMix[x+1]];
dest[x+2] = systemColorMap32[gbLineMix[x+2]];
dest[x+3] = systemColorMap32[gbLineMix[x+3]];
*dest++ = systemColorMap32[gbLineMix[x++]];
*dest++ = systemColorMap32[gbLineMix[x++]];
*dest++ = systemColorMap32[gbLineMix[x++]];
*dest++ = systemColorMap32[gbLineMix[x++]];
dest[x+4] = systemColorMap32[gbLineMix[x+4]];
dest[x+5] = systemColorMap32[gbLineMix[x+5]];
dest[x+6] = systemColorMap32[gbLineMix[x+6]];
dest[x+7] = systemColorMap32[gbLineMix[x+7]];
*dest++ = systemColorMap32[gbLineMix[x++]];
*dest++ = systemColorMap32[gbLineMix[x++]];
*dest++ = systemColorMap32[gbLineMix[x++]];
*dest++ = systemColorMap32[gbLineMix[x++]];
dest[x+8] = systemColorMap32[gbLineMix[x+8]];
dest[x+9] = systemColorMap32[gbLineMix[x+9]];
dest[x+10] = systemColorMap32[gbLineMix[x+10]];
dest[x+11] = systemColorMap32[gbLineMix[x+11]];
*dest++ = systemColorMap32[gbLineMix[x++]];
*dest++ = systemColorMap32[gbLineMix[x++]];
*dest++ = systemColorMap32[gbLineMix[x++]];
*dest++ = systemColorMap32[gbLineMix[x++]];
dest[x+12] = systemColorMap32[gbLineMix[x+12]];
dest[x+13] = systemColorMap32[gbLineMix[x+13]];
dest[x+14] = systemColorMap32[gbLineMix[x+14]];
dest[x+15] = systemColorMap32[gbLineMix[x+15]];
x+=16;
}
}
break;
}
}
void gbEmulate(int ticksToStop)
{
gbRegister tempRegister;
@ -4526,7 +4590,7 @@ void gbEmulate(int ticksToStop)
// PC.W is not incremented for the first byte of the next instruction.
if (IFF & 2)
{
PC.W--;
--PC.W;
IFF &= ~2;
}
@ -4791,12 +4855,28 @@ void gbEmulate(int ticksToStop)
if (wx<0)
wx = 0;
if((wx <= 159) && (tempgbWindowLine <= 143))
for (int i = wx; i<300; i++)
if (gbSpeed)
gbSpritesTicks[i]+=3;
else
gbSpritesTicks[i]+=1;
if((wx <= 159) && (tempgbWindowLine <= 143)){
int i = 300 - 4;
if (gbSpeed){
do{
gbSpritesTicks[i]+=3;
gbSpritesTicks[i+1]+=3;
gbSpritesTicks[i+2]+=3;
gbSpritesTicks[i+3]+=3;
i-=4;
}while(i>=0);
}else{
do{
++gbSpritesTicks[i];
++gbSpritesTicks[i+1];
++gbSpritesTicks[i+2];
++gbSpritesTicks[i+3];
i-=4;
}while(i>=0);
}
}
}
}
}
@ -4867,11 +4947,9 @@ void gbEmulate(int ticksToStop)
// set the LY increment counter
if(register_LCDC & 0x80) {
if (gbHardware & 0xa)
{
register_IF |= 1; // V-Blank interrupt
gbInterruptLaunched |=1;
if (gbHardware & 0xa){
register_IF |= 1; // V-Blank interrupt
gbInterruptLaunched |=1;
}
@ -4880,7 +4958,7 @@ void gbEmulate(int ticksToStop)
gbLcdTicksDelayed += GBLCD_MODE_1_CLOCK_TICKS;
gbLcdModeDelayed = 1;
gbFrameCount++;
++gbFrameCount;
systemFrame();
if((gbFrameCount % 10) == 0)
@ -4899,15 +4977,12 @@ void gbEmulate(int ticksToStop)
if(systemReadJoypads()) {
// read joystick
if(gbSgbMode && gbSgbMultiplayer) {
if(gbSgbFourPlayers) {
gbJoymask[0] = systemReadJoypad(0);
gbJoymask[1] = systemReadJoypad(1);
gbJoymask[0] = systemReadJoypad(0);
gbJoymask[1] = systemReadJoypad(1);
if(gbSgbFourPlayers) {
gbJoymask[2] = systemReadJoypad(2);
gbJoymask[3] = systemReadJoypad(3);
} else {
gbJoymask[0] = systemReadJoypad(0);
gbJoymask[1] = systemReadJoypad(1);
}
}
} else {
gbJoymask[0] = systemReadJoypad(-1);
}
@ -4930,7 +5005,7 @@ void gbEmulate(int ticksToStop)
gbCapture = (newmask & 2) ? true : false;
if(gbCapture && !gbCapturePrevious) {
gbCaptureNumber++;
++gbCaptureNumber;
systemScreenCapture(gbCaptureNumber);
}
gbCapturePrevious = gbCapture;
@ -4946,7 +5021,7 @@ void gbEmulate(int ticksToStop)
}
gbFrameSkipCount = 0;
} else
gbFrameSkipCount++;
++gbFrameSkipCount;
} else {
// go the the OAM being accessed mode
@ -4999,11 +5074,19 @@ void gbEmulate(int ticksToStop)
if (!gbCgbMode)
color = gbColorOption ? gbColorFilter[gbPalette[3] & 0x7FFF] :
gbPalette[3] & 0x7FFF;
for(int i = 0; i < 160; i++)
{
gbLineMix[i] = color;
gbLineBuffer[i] = 0;
}
int i = 160-4;
do{
gbLineMix[i ] =
gbLineMix[i+1] =
gbLineMix[i+2] =
gbLineMix[i+3] = color;
gbLineBuffer[i] =
gbLineBuffer[i+1] =
gbLineBuffer[i+2] =
gbLineBuffer[i+3] = 0;
i-=4;
}while(i >= 0);
}
gbDrawLine();
}
@ -5056,7 +5139,7 @@ void gbEmulate(int ticksToStop)
{
// Used to update the screen with white lines when it's off.
// (it looks strange, but it's kinda accurate :p)
// (it looks strange, but it's kinda accurate)
// You can try the Mario Demo Vx.x for exemple
// (check the bottom 2 lines while moving)
if (!gbWhiteScreen)
@ -5072,18 +5155,27 @@ void gbEmulate(int ticksToStop)
{
gbWhiteScreen = 1;
u8 register_LYLcdOff = ((register_LY+154)%154);
for (register_LY=0;register_LY <= 0x90;register_LY++)
for (register_LY=0;register_LY <= 0x90;++register_LY)
{
u16 color = gbColorOption ? gbColorFilter[0x7FFF] :
0x7FFF;
if (!gbCgbMode)
color = gbColorOption ? gbColorFilter[gbPalette[0] & 0x7FFF] :
gbPalette[0] & 0x7FFF;
for(int i = 0; i < 160; i++)
{
gbLineMix[i] = color;
gbLineBuffer[i] = 0;
}
int i = 160 - 4;
do{
gbLineMix[i ] =
gbLineMix[i+1] =
gbLineMix[i+2] =
gbLineMix[i+3] = color;
gbLineBuffer[i] =
gbLineBuffer[i+1] =
gbLineBuffer[i+2] =
gbLineBuffer[i+3] = 0;
i-=4;
}while(i >= 0);
gbDrawLine();
}
register_LY = register_LYLcdOff;
@ -5106,11 +5198,20 @@ void gbEmulate(int ticksToStop)
if (!gbCgbMode)
color = gbColorOption ? gbColorFilter[gbPalette[0] & 0x7FFF] :
gbPalette[0] & 0x7FFF;
for(int i = 0; i < 160; i++)
{
gbLineMix[i] = color;
gbLineBuffer[i] = 0;
}
int i = 160 - 4;
do{
gbLineMix[i ] =
gbLineMix[i+1] =
gbLineMix[i+2] =
gbLineMix[i+3] = color;
gbLineBuffer[i] =
gbLineBuffer[i+1] =
gbLineBuffer[i+2] =
gbLineBuffer[i+3] = 0;
i-=4;
}while(i >= 0);
gbDrawLine();
}
else if ((register_LY==144) && (!systemFrameSkip))
@ -5132,20 +5233,17 @@ void gbEmulate(int ticksToStop)
if(systemReadJoypads()) {
// read joystick
if(gbSgbMode && gbSgbMultiplayer) {
if(gbSgbFourPlayers) {
gbJoymask[0] = systemReadJoypad(0);
gbJoymask[0] = systemReadJoypad(0);
gbJoymask[1] = systemReadJoypad(1);
if(gbSgbFourPlayers) {
gbJoymask[2] = systemReadJoypad(2);
gbJoymask[3] = systemReadJoypad(3);
} else {
gbJoymask[0] = systemReadJoypad(0);
gbJoymask[1] = systemReadJoypad(1);
}
} else {
gbJoymask[0] = systemReadJoypad(-1);
}
}
gbFrameCount++;
++gbFrameCount;
systemFrame();
@ -5176,7 +5274,7 @@ void gbEmulate(int ticksToStop)
while(gbSerialTicks <= 0) {
// increment number of shifted bits
gbSerialBits++;
++gbSerialBits;
linkProc();
if(gbSerialOn && (gbMemory[0xff02] & 1)) {
if(gbSerialBits == 8) {
@ -5200,7 +5298,7 @@ void gbEmulate(int ticksToStop)
// shift serial byte to right and put a 1 bit in its place
// gbMemory[0xff01] = 0x80 | (gbMemory[0xff01]>>1);
// increment number of shifted bits
gbSerialBits++;
++gbSerialBits;
if(gbSerialBits == 8) {
// end of transmission
if(gbSerialFunction) // external device
@ -5239,7 +5337,7 @@ void gbEmulate(int ticksToStop)
gbTimerTicks= ((gbInternalTimer) & gbTimerMask[gbTimerMode])+1-clockTicks;
while(gbTimerTicks <= 0) {
register_TIMA++;
++register_TIMA;
// timer overflow!
if((register_TIMA & 0xff) == 0) {
// reload timer modulo
@ -5334,7 +5432,7 @@ void gbEmulate(int ticksToStop)
if (gbIntBreak == 2)
{
gbDmaTicks--;
--gbDmaTicks;
gbIntBreak = 0;
}
@ -5380,14 +5478,11 @@ void gbEmulate(int ticksToStop)
if(systemReadJoypads()) {
// read joystick
if(gbSgbMode && gbSgbMultiplayer) {
if(gbSgbFourPlayers) {
gbJoymask[0] = systemReadJoypad(0);
gbJoymask[1] = systemReadJoypad(1);
gbJoymask[0] = systemReadJoypad(0);
gbJoymask[1] = systemReadJoypad(1);
if(gbSgbFourPlayers) {
gbJoymask[2] = systemReadJoypad(2);
gbJoymask[3] = systemReadJoypad(3);
} else {
gbJoymask[0] = systemReadJoypad(0);
gbJoymask[1] = systemReadJoypad(1);
}
} else {
gbJoymask[0] = systemReadJoypad(-1);

View File

@ -78,7 +78,7 @@ void gbRenderLine()
if(y >= 144)
return;
int SpritesTicks = gbSpritesTicks[x]*(gbSpeed ? 2 : 4);
int SpritesTicks = gbSpritesTicks[x] << (gbSpeed ? 1 : 2);
int sx = gbSCXLine[(gbSpeed ? 0 : 4)+SpritesTicks];
int sy = gbSCYLine[(gbSpeed ? 11 : 5)+SpritesTicks];
@ -92,7 +92,7 @@ void gbRenderLine()
int bx = 1 << (7 - (sx & 7));
int by = sy & 7;
int tile_map_line_y = tile_map + ty * 32;
int tile_map_line_y = tile_map + (ty <<5);
int tile_map_address = tile_map_line_y + tx;
@ -102,24 +102,22 @@ void gbRenderLine()
u8 tile = bank0[tile_map_address];
tile_map_address++;
++tile_map_address;
if(!(register_LCDC & 0x10))
tile ^= 0x80;
int tile_pattern_address = tile_pattern + tile * 16 + by*2;
int tile_pattern_address = tile_pattern + (tile<< 4) + (by<<1);
if(register_LCDC & 0x80) {
if((register_LCDC & 0x01 || gbCgbMode) && (layerSettings & 0x0100)) {
while(x < 160) {
u8 tile_a = 0;
u8 tile_b = 0;
if(attrs & 0x40) {
tile_pattern_address = tile_pattern + tile * 16 + (7-by)*2;
tile_pattern_address = tile_pattern + (tile<<4) + ((7-by)<<1);
}
if(attrs & 0x08) {
@ -145,7 +143,7 @@ void gbRenderLine()
gbLineBuffer[x] |= 0x300;
if(gbCgbMode) {
c = c + (attrs & 7)*4;
c += (attrs & 7)<<2;
} else {
// Get the background palette to use (from the delayed pipeline)
u8 BgPal = gbBgpLine[x+(gbSpeed ? 5 : 11)+SpritesTicks];
@ -160,7 +158,7 @@ void gbRenderLine()
if(c == 0)
palette = 0;
c = c + 4*palette;
c += palette<<2;
// Mono Game Boy requires special palette handling
} else {
if (BgPal!=oldBgPal) {
@ -168,12 +166,11 @@ void gbRenderLine()
oldBgPal = BgPal;
}
if (!ColorizeGameboy) c = (BgPal>>(c<<1)) &3;
else c += 0;
}
}
gbLineMix[x] = gbColorOption ? gbColorFilter[gbPalette[c] & 0x7FFF] :
gbPalette[c] & 0x7FFF;
x++;
++x;
if(x >= 160)
break;
bx >>= 1;
@ -181,7 +178,7 @@ void gbRenderLine()
bx = 128;
SpritesTicks = gbSpritesTicks[x]*(gbSpeed ? 2 : 4);
SpritesTicks = gbSpritesTicks[x] << (gbSpeed ? 1 : 2);
sx = gbSCXLine[x+(gbSpeed ? 0 : 4)+SpritesTicks];
@ -198,9 +195,9 @@ void gbRenderLine()
by = sy & 7;
tile_pattern_address = tile_pattern + tile * 16 + by * 2;
tile_pattern_address = tile_pattern + (tile<<4) + (by<<1);
tile_map_line_y = tile_map + ty * 32;
tile_map_line_y = tile_map + (ty<<5);
tile_map_address = tile_map_line_y + tx;
@ -212,7 +209,7 @@ void gbRenderLine()
if(!(register_LCDC & 0x10))
tile ^= 0x80;
tile_pattern_address = tile_pattern + tile * 16 + by * 2;
tile_pattern_address = tile_pattern + (tile<<4) + (by<<1);
}
} else {
// Use gbBgp[0] instead of 0 (?)
@ -220,11 +217,11 @@ void gbRenderLine()
// Also added the gbColorOption (fixes Dracula Densetsu II color problems)
for(int i = 0; i < 160; i++)
{
u16 color = gbColorOption ? gbColorFilter[0x7FFF] :
0x7FFF;
u16 color = gbColorOption ? gbColorFilter[0x7FFF] : 0x7FFF;
if (!gbCgbMode) {
// Get the background palette to use (from the delayed pipeline)
u8 BgPal = gbBgpLine[i+(gbSpeed ? 5 : 11)+gbSpritesTicks[i]*(gbSpeed ? 2 : 4)];
u8 BgPal = gbBgpLine[i+(gbSpeed ? 5 : 11)+(gbSpritesTicks[i] << (gbSpeed ? 1 : 2))];
if ((BgPal!=oldBgPal) && !gbSgbMode) {
gbSetBGPalette(BgPal);
oldBgPal = BgPal;
@ -280,7 +277,7 @@ void gbRenderLine()
by = gbWindowLine & 7;
// Tries to emulate the 'window scrolling bug' when wx == 0 (ie. wx-7 == -7).
// Nothing close to perfect, but good enought for now...
// Nothing close to perfect, but good enough for now...
if (wx == -7)
{
swx = 7-((gbSCXLine[0]-1) & 7);
@ -303,7 +300,7 @@ void gbRenderLine()
wx = 0;
}
tile_map_line_y = tile_map + ty * 32;
tile_map_line_y = tile_map + (ty<<5);
tile_map_address = tile_map_line_y + tx;
@ -313,25 +310,29 @@ void gbRenderLine()
u8 attrs = 0;
if(bank1)
attrs = bank1[tile_map_address];
tile_map_address++;
++tile_map_address;
if((register_LCDC & 16) == 0) {
if((register_LCDC & 16) == 0) {
if(tile < 128) tile += 128;
else tile -= 128;
}
tile_pattern_address = tile_pattern + tile * 16 + by*2;
tile_pattern_address = tile_pattern + (tile<<4) + (by<<1);
if (wx)
for (i = 0; i<swx; i++)
gbLineMix[i] = gbWindowColor[i];
if (wx){
i = swx - 1;
do{
gbLineMix[i] = gbWindowColor[i];
--i;
}while(i >= 0);
}
while(x < 160) {
u8 tile_a = 0;
u8 tile_b = 0;
if(attrs & 0x40) {
tile_pattern_address = tile_pattern + tile * 16 + (7-by)*2;
tile_pattern_address = tile_pattern + (tile<<4) + ((7-by)<<1);
}
if(attrs & 0x08) {
@ -359,7 +360,7 @@ void gbRenderLine()
gbLineBuffer[x] = 0x100 + c;
if(gbCgbMode) {
c = c + (attrs & 7) * 4;
c += (attrs & 7) <<2;
} else {
// Get the background palette to use (from the delayed pipeline)
u8 BgPal = gbBgpLine[x+(gbSpeed ? 5 : 11)+gbSpritesTicks[x]*(gbSpeed ? 2 : 4)];
@ -374,7 +375,7 @@ void gbRenderLine()
if(c == 0)
palette = 0;
c = c + 4*palette;
c += palette<<2;
// Mono Game Boy requires special palette handling
} else {
if (BgPal!=oldBgPal) {
@ -388,12 +389,12 @@ void gbRenderLine()
gbLineMix[x] = gbColorOption ? gbColorFilter[gbPalette[c] & 0x7FFF] :
gbPalette[c] & 0x7FFF;
}
x++;
++x;
if(x >= 160)
break;
bx >>= 1;
}
tx++;
++tx;
if(tx == 32)
tx = 0;
bx = 128;
@ -405,12 +406,12 @@ void gbRenderLine()
if(tile < 128) tile += 128;
else tile -= 128;
}
tile_pattern_address = tile_pattern + tile * 16 + by * 2;
tile_pattern_address = tile_pattern + (tile<<4) + (by<<1);
}
//for (i = swx; i<160; i++)
// gbLineMix[i] = gbWindowColor[i];
gbWindowLine++;
++gbWindowLine;
}
}
}
@ -423,16 +424,25 @@ void gbRenderLine()
gbWindowLine = 0;
}
} else {
u16 color = gbColorOption ? gbColorFilter[0x7FFF] :
0x7FFF;
u16 color = gbColorOption ? gbColorFilter[0x7FFF] : 0x7FFF;
if (!gbCgbMode)
color = gbColorOption ? gbColorFilter[gbPalette[0] & 0x7FFF] :
gbPalette[0] & 0x7FFF;
for(int i = 0; i < 160; i++)
{
gbLineMix[i] = color;
gbLineBuffer[i] = 0;
}
int i = 160 - 4;
do{
gbLineMix[i] =
gbLineMix[i+1] =
gbLineMix[i+2] =
gbLineMix[i+3] = color;
gbLineBuffer[i] =
gbLineBuffer[i+1] =
gbLineBuffer[i+2] =
gbLineBuffer[i+3] = 0;
i-=4;
}while(i>=0);
}
}
@ -466,7 +476,7 @@ void gbDrawSpriteTile(int tile, int x,int y,int t, int flags,
if(!gbCgbMode) {
if(flags & 0x10) {
pal = gbObp1;
ObjPal = gbObp1Line[x+11+gbSpritesTicks[x]*(gbSpeed ? 2 : 4)];
ObjPal = gbObp1Line[x+11+(gbSpritesTicks[x] << (gbSpeed ? 1 : 2))];
if (ObjPal!=oldObj1Pal && !gbSgbMode) {
gbSetObj1Palette(ObjPal);
oldObj1Pal = ObjPal;
@ -474,7 +484,7 @@ void gbDrawSpriteTile(int tile, int x,int y,int t, int flags,
PalOffset = 12;
} else {
pal = gbObp0;
ObjPal = gbObp0Line[x+11+gbSpritesTicks[x]*(gbSpeed ? 2 : 4)];
ObjPal = gbObp0Line[x+11+(gbSpritesTicks[x] << (gbSpeed ? 1 : 2))];
if (ObjPal!=oldObj0Pal && !gbSgbMode) {
gbSetObj0Palette(ObjPal);
oldObj0Pal = ObjPal;
@ -492,7 +502,7 @@ void gbDrawSpriteTile(int tile, int x,int y,int t, int flags,
int prio = flags & 0x80;
int address = init + tile * 16 + 2*t;
int address = init + (tile<<4) + (t<<1);
int a = 0;
int b = 0;
@ -504,11 +514,11 @@ void gbDrawSpriteTile(int tile, int x,int y,int t, int flags,
b = bank0[address++];
}
for(int xx = 0; xx < 8; xx++) {
for(int xx = 0; xx < 8; ++xx) {
u8 mask = 1 << (7-xx);
u8 c = 0;
if( (a & mask))
c++;
++c;
if( (b & mask))
c+=2;
@ -519,7 +529,7 @@ void gbDrawSpriteTile(int tile, int x,int y,int t, int flags,
if(flipx)
xxx = (7-xx+x);
if(xxx < 0 || xxx > 159)
if(unsigned(xxx-1) >= 159)
continue;
u16 color = gbLineBuffer[xxx];
@ -530,12 +540,13 @@ void gbDrawSpriteTile(int tile, int x,int y,int t, int flags,
continue;
}
// Fixes OAM-BG priority for Moorhuhn 2
if(color >= 0x300 && color != 0x300 && (register_LCDC & 1))
if(color >= 0x300 && color != 0x300 && (register_LCDC & 1)){
continue;
else if(color >= 0x200 && color < 0x300) {
}else if(color >= 0x200 && color < 0x300) {
int sprite = color & 0xff;
int spriteX = gbMemory[0xfe00 + 4 * sprite + 1] - 8;
int spriteX = gbMemory[0xfe00 + (sprite<<2) + 1] - 8;
if(spriteX == x) {
if(sprite < spriteNumber)
@ -558,7 +569,7 @@ void gbDrawSpriteTile(int tile, int x,int y,int t, int flags,
// make sure that sprites will work even in CGB mode
if(gbCgbMode) {
c = c + (flags & 0x07)*4 + 32;
c += ((flags & 0x07)<<2) + 32;
} else {
// Super Game Boy has its own special palettes
if(gbSgbMode) {
@ -571,7 +582,7 @@ void gbDrawSpriteTile(int tile, int x,int y,int t, int flags,
if(c == 0)
palette = 0;
c = c + 4*palette;
c += palette<<2;
// Monochrome Game Boy
} else {
if (!ColorizeGameboy) c = (ObjPal>>(c<<1)) &3;
@ -602,7 +613,7 @@ void gbDrawSprites(bool draw)
int yc = register_LY;
int address = 0xfe00;
for(int i = 0; i < 40; i++) {
for(int i = 0; i < 40; ++i) {
y = gbMemory[address++];
x = gbMemory[address++];
int tile = gbMemory[address++];
@ -610,24 +621,74 @@ void gbDrawSprites(bool draw)
tile &= 254;
int flags = gbMemory[address++];
if(x > 0 && y > 0 && x < 168 && y < 160) {
// Subtract 1 because we're not checking against greater-equal 0
if(unsigned(x-1) < 167 && unsigned(y-1) < 159) {
// check if sprite intersects current line
int t = yc -y + 16;
if((size && t >=0 && t < 16) || (!size && t >= 0 && t < 8)) {
if((size && (unsigned(t) < 16u)) || (!size && (unsigned(t) < 8u))) {
if (draw)
gbDrawSpriteTile(tile,x-8,yc,t,flags,size,i);
else
{
for (int j = x-8; j<300; j++)
if (j>=0)
{
if (gbSpeed)
gbSpritesTicks[j] += 5;
else
gbSpritesTicks[j] += 2+(count&1);
}
int j = x - 8;
// Less than 0 or divisible by 4
if(j < 0 || (j & 3) == 0){
// If it's less than 0, set it to 0, and then we KNOW
// that it can be incremented by 4.
if(j < 0) j = 0;
// Yeah, we have to check twice. It's either that or
// have a (rather large) duplicate if-else statement
if(gbSpeed){
for (; j<300; j+=4){
gbSpritesTicks[j] += 5;
gbSpritesTicks[j+1] += 5;
gbSpritesTicks[j+2] += 5;
gbSpritesTicks[j+3] += 5;
}
}else{
int count2 = 2 + (count & 1);
for (; j<300; j+=4){
gbSpritesTicks[j] += count2;
gbSpritesTicks[j+1] += count2;
gbSpritesTicks[j+2] += count2;
gbSpritesTicks[j+3] += count2;
}
}
}
//divisible by 2 at least?
else if((j & 1) == 0){
if(gbSpeed){
for (; j<300; j+=2){
gbSpritesTicks[j] += 5;
gbSpritesTicks[j+1] += 5;
}
}else{
int count2 = 2 + (count & 1);
for (; j<300; j+=2){
gbSpritesTicks[j] += count2;
gbSpritesTicks[j+1] += count2;
}
}
}
// Not divisible by 4 OR 2: use the old one
else{
if(gbSpeed){
for (; j<300; ++j){
gbSpritesTicks[j] += 5;
}
}else{
int count2 = 2 + (count & 1);
for (; j<300; ++j){
gbSpritesTicks[j] += count2;
}
}
}
}
count++;
++count;
}
}
// sprite limit reached!

View File

@ -334,7 +334,7 @@ void memoryUpdateMBC3Clock()
gbDataMBC3.mapperSeconds += (int)(diff % 60);
if(gbDataMBC3.mapperSeconds > 59) {
gbDataMBC3.mapperSeconds -= 60;
gbDataMBC3.mapperMinutes++;
++gbDataMBC3.mapperMinutes;
}
diff /= 60;
@ -342,7 +342,7 @@ void memoryUpdateMBC3Clock()
gbDataMBC3.mapperMinutes += (int)(diff % 60);
if(gbDataMBC3.mapperMinutes > 59) {
gbDataMBC3.mapperMinutes -= 60;
gbDataMBC3.mapperHours++;
++gbDataMBC3.mapperHours;
}
diff /= 60;
@ -350,7 +350,7 @@ void memoryUpdateMBC3Clock()
gbDataMBC3.mapperHours += (int)(diff % 24);
if(gbDataMBC3.mapperHours > 23) {
gbDataMBC3.mapperHours -= 24;
gbDataMBC3.mapperDays++;
++gbDataMBC3.mapperDays;
}
diff /= 24;
@ -567,7 +567,7 @@ void mapperMBC5ROM(u16 address, u8 value)
gbMemoryMap[0x07] = &gbRom[tmpAddress + 0x3000];
} else {
value = value & 1;
value &= 1;
if(value == gbDataMBC5.mapperROMHighAddress)
break;
@ -818,7 +818,7 @@ void mapperMBC7RAM(u16 address, u8 value)
// receiving command
gbDataMBC7.buffer <<= 1;
gbDataMBC7.buffer |= (value & 0x02)?1:0;
gbDataMBC7.count++;
++gbDataMBC7.count;
if(gbDataMBC7.count==2) {
// finished receiving command
gbDataMBC7.state=2;
@ -830,7 +830,7 @@ void mapperMBC7RAM(u16 address, u8 value)
// receive address
gbDataMBC7.buffer <<= 1;
gbDataMBC7.buffer |= (value&0x02)?1:0;
gbDataMBC7.count++;
++gbDataMBC7.count;
if(gbDataMBC7.count==8) {
// finish receiving
gbDataMBC7.state=3;
@ -850,7 +850,7 @@ void mapperMBC7RAM(u16 address, u8 value)
case 3:
gbDataMBC7.buffer <<= 1;
gbDataMBC7.buffer |= (value&0x02)?1:0;
gbDataMBC7.count++;
++gbDataMBC7.count;
switch(gbDataMBC7.code) {
case 0:
@ -1238,7 +1238,7 @@ void memoryUpdateTAMA5Clock()
gbDataTAMA5.mapperSeconds += (int)(diff % 60);
if(gbDataTAMA5.mapperSeconds > 59) {
gbDataTAMA5.mapperSeconds -= 60;
gbDataTAMA5.mapperMinutes++;
++gbDataTAMA5.mapperMinutes;
}
diff /= 60;
@ -1246,7 +1246,7 @@ void memoryUpdateTAMA5Clock()
gbDataTAMA5.mapperMinutes += (int)(diff % 60);
if(gbDataTAMA5.mapperMinutes > 59) {
gbDataTAMA5.mapperMinutes -= 60;
gbDataTAMA5.mapperHours++;
++gbDataTAMA5.mapperHours;
}
diff /= 60;
@ -1255,23 +1255,23 @@ void memoryUpdateTAMA5Clock()
diff /= 24;
if(gbDataTAMA5.mapperHours > 23) {
gbDataTAMA5.mapperHours -= 24;
diff++;
++diff;
}
time_t days = diff;
while (days)
{
gbDataTAMA5.mapperDays++;
days--;
++gbDataTAMA5.mapperDays;
--days;
if (gbDataTAMA5.mapperDays>gbDaysinMonth[gbDataTAMA5.mapperMonths-1])
{
gbDataTAMA5.mapperDays = 1;
gbDataTAMA5.mapperMonths++;
++gbDataTAMA5.mapperMonths;
if (gbDataTAMA5.mapperMonths>12)
{
gbDataTAMA5.mapperMonths = 1;
gbDataTAMA5.mapperYears++;
++gbDataTAMA5.mapperYears;
if ((gbDataTAMA5.mapperYears & 3) == 0)
gbDaysinMonth[1] = 29;
else
@ -1376,11 +1376,11 @@ void mapperTAMA5RAM(u16 address, u8 value)
gbDataTAMA5.mapperLYears = gbDataTAMA5.mapperYears;
gbDataTAMA5.mapperLControl = gbDataTAMA5.mapperControl;
int seconds = (gbDataTAMA5.mapperLSeconds / 10)*16 + gbDataTAMA5.mapperLSeconds %10;
int seconds = ((gbDataTAMA5.mapperLSeconds / 10)<<4) + gbDataTAMA5.mapperLSeconds %10;
int secondsL = (gbDataTAMA5.mapperLSeconds % 10);
int secondsH = (gbDataTAMA5.mapperLSeconds / 10);
int minutes = (gbDataTAMA5.mapperLMinutes / 10)*16 + gbDataTAMA5.mapperLMinutes %10;
int hours = (gbDataTAMA5.mapperLHours / 10)*16 + gbDataTAMA5.mapperLHours %10;
int minutes = ((gbDataTAMA5.mapperLMinutes / 10)<<4) + gbDataTAMA5.mapperLMinutes %10;
int hours = ((gbDataTAMA5.mapperLHours / 10)<<4) + gbDataTAMA5.mapperLHours %10;
int DaysL = gbDataTAMA5.mapperLDays % 10;
int DaysH = gbDataTAMA5.mapperLDays /10;
int MonthsL = gbDataTAMA5.mapperLMonths % 10;
@ -1438,11 +1438,11 @@ void mapperTAMA5RAM(u16 address, u8 value)
}
else if (gbDataTAMA5.mapperRamByteSelect == 0x44)
{
gbDataTAMA5.mapperMinutes = (data/16)*10 + data%16;
gbDataTAMA5.mapperMinutes = (data>>4)*10 + (data & 15);
}
else if (gbDataTAMA5.mapperRamByteSelect == 0x54)
{
gbDataTAMA5.mapperHours = (data/16)*10 + data%16;
gbDataTAMA5.mapperHours = (data>>4)*10 + (data & 15);
}
else
{
@ -1462,14 +1462,13 @@ void mapperTAMA5RAM(u16 address, u8 value)
// I put it there...
if (value == 0x0a)
{
for (int i = 0; i<0x10; i++)
for (int j = 0; j<0x10; j++)
if (!(j&2))
gbTAMA5ram[((i*0x10)+j) | 2] = gbTAMA5ram[(i*0x10)+j];
// Enable this to see the content of the flashrom in 0xe000
/*for (int k = 0; k<0x100; k++)
gbMemoryMap[0xe][k] = gbTAMA5ram[k];*/
for (int i = 0; i<0x10; i++){
int i16 = i<<4;
for (int j = 0; j<0x10; j+=4){
gbTAMA5ram[(i16 + j ) | 2] = gbTAMA5ram[i16 + j ];
gbTAMA5ram[(i16 + j + 1) | 2] = gbTAMA5ram[i16 + j + 1];
}
}
gbMemoryMap[0xa][0] = gbDataTAMA5.mapperRAMEnable = 1;
}
else

View File

@ -10,6 +10,7 @@
#include "gbGlobals.h"
#include "vba.h"
#include "../ngc/menu.h"
#include "../ngc/fastmath.h"
#define CARLLOG
@ -37,18 +38,20 @@ const float BL[4] = {0.1f, 0.4f, 0.7f, 1.0f};
// factor is from 0 to 1. 0 = no extra whiteness, 1 = 100% whiteness
u16 changeColourWhiteness(u16 rgb, float factor) {
if (factor==0.0f) return rgb;
int f1factor = (0x1f*factor);
int factorm1 = 1-factor;
int r = (rgb & 0x1f);
r = (r * (1-factor))+(0x1f*factor);
r = (r * factorm1)+ f1factor;
if (r>31) {
r=31;
}
int g = ((rgb >> 5) & 0x1f);
g = (g * (1-factor))+(0x1f*factor);
g = (g * factorm1)+f1factor;
if (g>31) {
g=31;
}
int b = ((rgb >> 10) & 0x1f);
b = (b * (1-factor))+(0x1f*factor);
b = (b * factorm1)+f1factor;
if (b>31) {
b=31;
}
@ -60,27 +63,26 @@ u16 changeColourWhiteness(u16 rgb, float factor) {
u16 changeColourBrightness(u16 rgb, float factor) {
if (factor==1.0f) return rgb;
int bonus = 0;
int r = (rgb & 0x1f);
r = r * factor;
int r = int(float(rgb & 0x1f) * factor);
if (r>31) {
r=31;
bonus+=(r-30)/2;
bonus+= (1 >> 1);
}
int g = ((rgb >> 5) & 0x1f);
g = g * factor;
int g = int(float((rgb >> 5) & 0x1f) * factor);
if (g>31) {
g=31;
bonus+=(g-30)/2;
bonus+=(1 >> 1);
}
int b = ((rgb >> 10) & 0x1f);
b = b * factor;
int b = int(float((rgb >> 10) & 0x1f) * factor);
if (b>31) {
b=31;
bonus+=(b-30)/2;
bonus += (1 >> 1);
}
r+=bonus;
g+=bonus;
b+=bonus;
r += bonus;
g += bonus;
b += bonus;
if (r>31) r=31;
if (g>31) g=31;
if (b>31) b=31;
@ -111,8 +113,8 @@ void gbSetBGPalette(u8 value, bool ColoursChanged=false) {
log("Bg Pal: %c %c %c %c", DN[gbObp0[0]], DN[gbObp0[1]], DN[gbObp0[2]], DN[gbObp0[3]]);
#endif
// check for duplicates
for (int i=0; i<=2; i++)
for (int j=i+1; j<=3; j++)
for (unsigned i=0; i<=2u; ++i)
for (unsigned j=i+1; j<=3u; ++j)
if (gbBgp[i]==gbBgp[j]) {
dup=true;
dupDarkness = gbBgp[i];
@ -120,19 +122,26 @@ void gbSetBGPalette(u8 value, bool ColoursChanged=false) {
}
// We haven't had a full palette yet, so guess...
if (dup && !HadBgPal) {
int index;
if (gbBgp[0]>gbBgp[3]) {
for (int Colour=0; Colour<=3; Colour++) {
index = Colour;
DarkestToBrightestIndex[Colour]=index;
Darkness[Colour]=gbBgp[index];
}
DarkestToBrightestIndex[0] = 0;
DarkestToBrightestIndex[1] = 1;
DarkestToBrightestIndex[2] = 2;
DarkestToBrightestIndex[3] = 3;
Darkness[0] = gbBgp[0];
Darkness[1] = gbBgp[1];
Darkness[2] = gbBgp[2];
Darkness[3] = gbBgp[3];
} else {
for (int Colour=0; Colour<=3; Colour++) {
index = 3-Colour;
DarkestToBrightestIndex[Colour]=index;
Darkness[Colour]=gbBgp[index];
}
DarkestToBrightestIndex[0] = 3;
DarkestToBrightestIndex[1] = 2;
DarkestToBrightestIndex[2] = 1;
DarkestToBrightestIndex[3] = 0;
Darkness[0] = gbBgp[3];
Darkness[1] = gbBgp[2];
Darkness[2] = gbBgp[1];
Darkness[3] = gbBgp[0];
}
// brightness of brightest colour
BrightnessForBrightest = BL[3-gbBgp[DarkestToBrightestIndex[3]]];
@ -141,12 +150,12 @@ void gbSetBGPalette(u8 value, bool ColoursChanged=false) {
HadBgPal = true;
// now we need to map them from darkest to brightest
int Colour = 0;
for (int darkness = 3; darkness>=0; darkness--) {
for (int index=0; index<=3; index++) {
for (int darkness = 3; darkness>=0; --darkness) {
for (int index=0; index<=3; ++index) {
if (gbBgp[index]==darkness) {
DarkestToBrightestIndex[Colour]=index;
Darkness[Colour]=gbBgp[index];
Colour++;
++Colour;
break;
}
}
@ -166,13 +175,16 @@ void gbSetBGPalette(u8 value, bool ColoursChanged=false) {
if (dupDarkness==0) {
// Multiple colours set to white
BrightnessFactor = 0;
float MaxWhiteness = 0;
int i;
for (i=0; i<=3; i++) {
WhitenessFactor+=BL[3-gbBgp[i]]-BL[3-i];
MaxWhiteness+=BL[3]-BL[3-i];
}
WhitenessFactor = WhitenessFactor / (MaxWhiteness+0.4f);
WhitenessFactor += BL[3-gbBgp[0]]
+ BL[3-gbBgp[1]]
+ BL[3-gbBgp[2]]
+ BL[3-gbBgp[3]]
- BL[3] - BL[2] - BL[1]- BL[0];
float MaxWhiteness = BL[3] + BL[3] + BL[3] + BL[3]
-BL[3] -BL[2] -BL[1] -BL[0];
WhitenessFactor /= (MaxWhiteness+0.4f);
// check if they are trying to make the palette brighter
} else if (NewBrightnessForBrightest==1.0f && BrightnessForBrightest==1.0f) {
float NewBrightnessForDarkest = BL[3-gbBgp[DarkestToBrightestIndex[0]]];
@ -184,7 +196,7 @@ void gbSetBGPalette(u8 value, bool ColoursChanged=false) {
}
if (WhitenessFactor) {
// BG colours
for (int colour = 0; colour <= 3; colour++) {
for (int colour = 0; colour <= 3; ++colour) {
u16 colourRGB = systemMonoPalette[colour];
float colourBrightness = BL[colour];
float indexBrightness = BL[3-Darkness[colour]];
@ -192,7 +204,7 @@ void gbSetBGPalette(u8 value, bool ColoursChanged=false) {
gbPalette[0+DarkestToBrightestIndex[colour]] = changeColourWhiteness(colourRGB, WhitenessFactor);
}
// Window colours
for (int colour = 0; colour <= 3; colour++) {
for (int colour = 0; colour <= 3; ++colour) {
u16 colourRGB = systemMonoPalette[4+colour];
float colourBrightness = BL[colour];
float indexBrightness = BL[3-Darkness[colour]];
@ -201,14 +213,14 @@ void gbSetBGPalette(u8 value, bool ColoursChanged=false) {
}
} else {
// BG colours
for (int colour = 0; colour <= 3; colour++) {
for (int colour = 0; colour <= 3; ++colour) {
u16 colourRGB = systemMonoPalette[colour];
float colourBrightness = BL[colour];
float indexBrightness = BL[3-Darkness[colour]]*BrightnessFactor;
gbPalette[0+DarkestToBrightestIndex[colour]] = changeColourBrightness(colourRGB, indexBrightness/colourBrightness);
}
// Window colours
for (int colour = 0; colour <= 3; colour++) {
for (int colour = 0; colour <= 3; ++colour) {
u16 colourRGB = systemMonoPalette[4+colour];
float colourBrightness = BL[colour];
float indexBrightness = BL[3-Darkness[colour]]*BrightnessFactor;
@ -250,19 +262,21 @@ void gbSetObj0Palette(u8 value, bool ColoursChanged = false) {
}
// We haven't had a full palette yet, so guess...
if (dup && !HadObj1Pal) {
int index;
if (gbObp0[1]>gbObp0[3]) {
for (int Colour=0; Colour<=2; Colour++) {
index = Colour+1;
DarkestToBrightestIndex[Colour]=index;
Darkness[Colour]=gbObp0[index];
}
if (gbObp0[1]>gbObp0[3]) {
DarkestToBrightestIndex[0] = 1;
DarkestToBrightestIndex[1] = 2;
DarkestToBrightestIndex[2] = 3;
Darkness[0] = gbObp0[1];
Darkness[1] = gbObp0[2];
Darkness[2] = gbObp0[3];
} else {
for (int Colour=0; Colour<=2; Colour++) {
index = 2-Colour+1;
DarkestToBrightestIndex[Colour]=index;
Darkness[Colour]=gbObp0[index];
}
DarkestToBrightestIndex[0] = 3;
DarkestToBrightestIndex[1] = 2;
DarkestToBrightestIndex[2] = 1;
Darkness[0] = gbObp0[3];
Darkness[1] = gbObp0[2];
Darkness[2] = gbObp0[1];
}
// brightness of brightest colour
BrightnessForBrightest = BL[3-gbObp0[DarkestToBrightestIndex[2]]];
@ -271,12 +285,12 @@ void gbSetObj0Palette(u8 value, bool ColoursChanged = false) {
HadObj0Pal = true;
// now we need to map them from darkest to brightest
int Colour = 0;
for (int darkness = 3; darkness>=0; darkness--) {
for (int darkness = 3; darkness>=0; --darkness) {
for (int index=1; index<=3; index++) {
if (gbObp0[index]==darkness) {
DarkestToBrightestIndex[Colour]=index;
Darkness[Colour]=gbObp0[index];
Colour++;
++Colour;
break;
}
}
@ -296,13 +310,16 @@ void gbSetObj0Palette(u8 value, bool ColoursChanged = false) {
if (dupDarkness==0) {
// Multiple colours set to white
BrightnessFactor = 0;
float MaxWhiteness = 0;
int i;
for (i=1; i<=3; i++) {
WhitenessFactor+=BL[3-gbObp0[i]]-BL[3-(i-1)];
MaxWhiteness+=BL[3]-BL[3-(i-1)];
}
WhitenessFactor = WhitenessFactor / (MaxWhiteness+0.3f);
WhitenessFactor+= BL[3-gbObp0[1]]
+ BL[3-gbObp0[2]]
+ BL[3-gbObp0[3]]
-BL[3] -BL[2] -BL[1];
float MaxWhiteness = BL[3] + BL[3] + BL[3]
- BL[3] - BL[2] - BL[1];
WhitenessFactor /= (MaxWhiteness+0.3f);
// check if they are trying to make the palette brighter
} else if (NewBrightnessForBrightest==1.0f && BrightnessForBrightest==1.0f) {
float NewBrightnessForDarkest = BL[3-gbObp0[DarkestToBrightestIndex[0]]];
@ -362,19 +379,21 @@ void gbSetObj1Palette(u8 value, bool ColoursChanged = false) {
}
// We haven't had a full palette yet, so guess...
if (dup && !HadObj1Pal) {
int index;
if (gbObp1[1]>gbObp1[3]) {
for (int Colour=0; Colour<=2; Colour++) {
index = Colour+1;
DarkestToBrightestIndex[Colour]=index;
Darkness[Colour]=gbObp1[index];
}
if (gbObp0[1]>gbObp0[3]) {
DarkestToBrightestIndex[0] = 1;
DarkestToBrightestIndex[1] = 2;
DarkestToBrightestIndex[2] = 3;
Darkness[0] = gbObp0[1];
Darkness[1] = gbObp0[2];
Darkness[2] = gbObp0[3];
} else {
for (int Colour=0; Colour<=2; Colour++) {
index = 2-Colour+1;
DarkestToBrightestIndex[Colour]=index;
Darkness[Colour]=gbObp1[index];
}
DarkestToBrightestIndex[0] = 3;
DarkestToBrightestIndex[1] = 2;
DarkestToBrightestIndex[2] = 1;
Darkness[0] = gbObp0[3];
Darkness[1] = gbObp0[2];
Darkness[2] = gbObp0[1];
}
// brightness of brightest colour
BrightnessForBrightest = BL[3-gbObp1[DarkestToBrightestIndex[2]]];
@ -408,13 +427,14 @@ void gbSetObj1Palette(u8 value, bool ColoursChanged = false) {
if (dupDarkness==0) {
// Multiple colours set to white
BrightnessFactor = 0;
float MaxWhiteness = 0;
int i;
for (i=1; i<=3; i++) {
WhitenessFactor+=BL[3-gbObp1[i]]-BL[3-(i-1)];
MaxWhiteness+=BL[3]-BL[3-(i-1)];
}
WhitenessFactor = WhitenessFactor / (MaxWhiteness+0.3f);
WhitenessFactor+= BL[3-gbObp1[1]]
+ BL[3-gbObp1[2]]
+ BL[3-gbObp1[3]]
-BL[3] -BL[2] -BL[1];
float MaxWhiteness = BL[3] + BL[3] + BL[3]
- BL[3] - BL[2] - BL[1];
WhitenessFactor /= (MaxWhiteness+0.3f);
// check if they are trying to make the palette brighter
} else if (NewBrightnessForBrightest==1.0f && BrightnessForBrightest==1.0f) {
float NewBrightnessForDarkest = BL[3-gbObp1[DarkestToBrightestIndex[0]]];
@ -453,10 +473,16 @@ bool StartColorizing() {
}
void StopColorizing() {
if(!ColorizeGameboy || gbSgbMode || gbCgbMode) return;
for(int i = 0; i < 12; i++)
gbPalette[i] = systemGbPalette[gbPaletteOption*12+i];
ColorizeGameboy = false;
if(!ColorizeGameboy || gbSgbMode || gbCgbMode) return;
int gbpo12 = gbPaletteOption*12;
for(int i = 0; i < 12; i+=4){
gbPalette[i] = systemGbPalette[gbpo12+i];
gbPalette[i+1] = systemGbPalette[gbpo12+i+1];
gbPalette[i+2] = systemGbPalette[gbpo12+i+2];
gbPalette[i+3] = systemGbPalette[gbpo12+i+3];
}
ColorizeGameboy = false;
}
// convert 0xRRGGBB to our 15 bit format
@ -471,7 +497,9 @@ void gbSetSpritePal(u8 WhichPal, u32 bright, u32 medium, u32 dark) {
// cancel if we already set to these colours
if (WhichPal>0) {
int p = WhichPal-1;
if (OldObpBright[p]==bright && OldObpMedium[p]==medium && OldObpDark[p]==dark) return;
if(((OldObpBright[p] - bright) | (OldObpMedium[p] - medium) | (OldObpDark[p] - dark)) == 0){
return;
}
}
int index = 0;
// check if we are setting both sprite palettes at once
@ -534,9 +562,9 @@ void gbSetBgPal(u8 WhichPal, u32 bright) {
u8 r = (bright >> 16) & 0xFF;
u8 g = (bright >> 8) & 0xFF;
u8 b = (bright >> 0) & 0xFF;
u32 medium = (((u32)(r*0.7f)) << 16) | (((u32)(g*0.7f)) << 8) | (((u32)(b*0.7f)) << 0);
u32 dark = (((u32)(r*0.4f)) << 16) | (((u32)(g*0.4f)) << 8) | (((u32)(b*0.4f)) << 0);
u32 black = (((u32)(r*0.1f)) << 16) | (((u32)(g*0.1f)) << 8) | (((u32)(b*0.1f)) << 0);
u32 medium = ((ftou((utof(r)*0.7f))) << 16) | ((ftou((utof(g)*0.7f))) << 8) | ((ftou((utof(b)*0.7f))) << 0);
u32 dark = ((ftou((utof(r)*0.4f))) << 16) | ((ftou((utof(g)*0.4f))) << 8) | ((ftou((utof(b)*0.4f))) << 0);
u32 black = ((ftou((utof(r)*0.1f))) << 16) | ((ftou((utof(g)*0.1f))) << 8) | ((ftou((utof(b)*0.1f))) << 0);
gbSetBgPal(WhichPal, bright, medium, dark, black);
}
@ -553,7 +581,7 @@ void gbPaletteReset() {
oldBgp = 0xFC;
oldObp0 = oldObp1 = 0xFF;
OldBgBright=0; OldBgMedium=0; OldBgDark=0; OldBgBlack=0;
for (int i=0; i<=1; i++) {
OldObpBright[i]=OldObpMedium[i]=OldObpDark[i]=0;
}
OldObpBright[0]= OldObpBright[1]=
OldObpMedium[0]= OldObpMedium[1]=
OldObpDark[0]= OldObpDark[1] =0;
}

View File

@ -17,10 +17,9 @@ bool gbSoundGetDeclicking();
// Effects configuration
struct gb_effects_config_t
{
bool enabled; // false = disable all effects
float echo; // 0.0 = none, 1.0 = lots
float stereo; // 0.0 = channels in center, 1.0 = channels on left/right
bool enabled; // false = disable all effects
bool surround; // true = put some channels in back
};

View File

@ -155,7 +155,7 @@ inline int codeTicksAccess16(u32 address) // THUMB NON SEQ
{
int addr = (address>>24)&15;
if ((addr>=0x08) && (addr<=0x0D))
if (unsigned(addr - 0x08) <= (0x0D - 0x08))
{
if (busPrefetchCount&0x1)
{
@ -167,24 +167,16 @@ inline int codeTicksAccess16(u32 address) // THUMB NON SEQ
busPrefetchCount = ((busPrefetchCount&0xFF)>>1) | (busPrefetchCount&0xFFFFFF00);
return memoryWaitSeq[addr]-1;
}
else
{
busPrefetchCount=0;
return memoryWait[addr];
}
}
else
{
busPrefetchCount = 0;
return memoryWait[addr];
}
busPrefetchCount = 0;
return memoryWait[addr];
}
inline int codeTicksAccess32(u32 address) // ARM NON SEQ
{
int addr = (address>>24)&15;
if ((addr>=0x08) && (addr<=0x0D))
if (unsigned(addr - 0x08) <= (0x0D - 0x08))
{
if (busPrefetchCount&0x1)
{
@ -196,24 +188,16 @@ inline int codeTicksAccess32(u32 address) // ARM NON SEQ
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 (unsigned(addr - 0x08) <= (0x0D - 0x08))
{
if (busPrefetchCount&0x1)
{
@ -226,26 +210,20 @@ inline int codeTicksAccessSeq16(u32 address) // THUMB SEQ
busPrefetchCount=0;
return memoryWait[addr];
}
else
return memoryWaitSeq[addr];
}
else
{
else{
busPrefetchCount = 0;
return memoryWaitSeq[addr];
}
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)
{
if (unsigned(addr - 0x08) <= (0x0D - 0x08)){
if (busPrefetchCount&0x1){
if (busPrefetchCount&0x2){
busPrefetchCount = ((busPrefetchCount&0xFF)>>2) | (busPrefetchCount&0xFFFFFF00);
return 0;
}
@ -253,18 +231,12 @@ inline int codeTicksAccessSeq32(u32 address) // ARM SEQ
return memoryWaitSeq[addr];
}
else
if (busPrefetchCount>0xFF)
{
if (busPrefetchCount>0xFF){
busPrefetchCount=0;
return memoryWait32[addr];
}
else
return memoryWaitSeq32[addr];
}
else
{
return memoryWaitSeq32[addr];
}
return memoryWaitSeq32[addr];
}

View File

@ -14,23 +14,23 @@ enum LocationType {
struct ELFHeader {
u32 magic;
u8 clazz;
u8 data;
u8 version;
u8 pad[9];
u16 e_type;
u16 e_machine;
u32 e_version;
u32 e_entry;
u32 e_phoff;
u32 e_shoff;
u32 e_flags;
u16 e_type;
u16 e_machine;
u16 e_ehsize;
u16 e_phentsize;
u16 e_phnum;
u16 e_shentsize;
u16 e_shnum;
u16 e_shstrndx;
u8 clazz;
u8 data;
u8 version;
u8 pad[9];
};
struct ELFProgramHeader {
@ -61,9 +61,9 @@ struct ELFSymbol {
u32 name;
u32 value;
u32 size;
u16 shndx;
u8 info;
u8 other;
u16 shndx;
};
struct ELFBlock {
@ -75,21 +75,21 @@ struct ELFAttr {
u32 name;
u32 form;
union {
u32 value;
ELFBlock *block;
u32 value;
char *string;
u8 *data;
bool flag;
ELFBlock *block;
bool flag;
};
};
struct ELFAbbrev {
u32 number;
u32 tag;
bool hasChildren;
int numAttrs;
ELFAttr *attrs;
ELFAbbrev *next;
bool hasChildren;
};
enum TypeEnum {
@ -163,12 +163,12 @@ struct Object {
char *name;
int file;
int line;
bool external;
Type *type;
ELFBlock *location;
u32 startScope;
u32 endScope;
Object *next;
bool external;
};
struct Function {
@ -177,12 +177,12 @@ struct Function {
u32 highPC;
int file;
int line;
bool external;
Type *returnType;
Object *parameters;
Object *variables;
ELFBlock *frameBase;
Function *next;
bool external;
};
struct LineInfoItem {
@ -193,8 +193,8 @@ struct LineInfoItem {
struct LineInfo {
int fileCount;
char **files;
int number;
char **files;
LineInfoItem *lines;
};
@ -219,7 +219,6 @@ struct CompileUnit {
char *compdir;
u32 lowPC;
u32 highPC;
bool hasLineInfo;
u32 lineInfo;
LineInfo *lineInfoTable;
Function *functions;
@ -227,6 +226,7 @@ struct CompileUnit {
Object *variables;
Type *types;
CompileUnit *next;
bool hasLineInfo;
};
struct DebugInfo {