mirror of
https://github.com/dborth/vbagx.git
synced 2024-11-22 10:39:18 +01:00
restore changes lost from 2.3.0 core upgrade (GameCube virtual memory,
optimizations from dancinninjac, GB color palettes, rotation/tilt for WarioWare Twisted, in-game rumble)
This commit is contained in:
parent
87995ca4f1
commit
eabe325fb0
28
readme.txt
28
readme.txt
@ -38,6 +38,12 @@ https://github.com/dborth/vbagx/releases
|
||||
|0O×øo· UPDATE HISTORY ·oø×O0|
|
||||
`¨•¨¨¨¨¨ ¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨ ¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨ ¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨ ¨¨¨¨¨¨¨¨¨¨¨¨¨'
|
||||
|
||||
[2.3.8]
|
||||
|
||||
* Restored changes lost from 2.3.0 core upgrade (GameCube virtual memory,
|
||||
optimizations from dancinninjac, GB color palettes, rotation/tilt for
|
||||
WarioWare Twisted, in-game rumble)
|
||||
|
||||
[2.3.7 - August 28, 2018]
|
||||
|
||||
* Allow loader to pass two arguments instead of three (libertyernie)
|
||||
@ -724,8 +730,8 @@ Medal Of Honour Underground, Medal Of Honour Infiltrator
|
||||
|
||||
One Piece can be played with One Piece Unlimited Adventure controls.
|
||||
|
||||
Boktai 1, Boktai 2, Boktai 3, and Kirby's Tilt n Tumble can be played with
|
||||
controls designed for them.
|
||||
Boktai 1, Boktai 2, Boktai 3, and Kirby's Tilt n Tumble, and WarioWare Twisted
|
||||
can be played with controls designed for them.
|
||||
|
||||
-=[ Zelda, Match Wii Controls ]=-
|
||||
|
||||
@ -893,6 +899,7 @@ ZR = fast forward (8-bit Game Boy only)
|
||||
In Super Mario World and Super Mario Land 2, you can use the A or R
|
||||
buttons for a spin jump.
|
||||
|
||||
|
||||
-=[ Yoshi's Universal Gravitation (Topsy Turvy), Match Wii Controls ]=-
|
||||
|
||||
Turn "Match Wii Controls" ON to use these controls.
|
||||
@ -984,9 +991,20 @@ Z or 1 = change element, or change subscreen (L)
|
||||
|
||||
-=[ WarioWare Twisted, Match Wii Controls ]=-
|
||||
|
||||
NOTE: For unknown reasons (but probably related to the update of the VBA-M
|
||||
emulator code), WarioWare Twisted will no longer work on VBA-GX. For now, you
|
||||
will need to go back to VBA-GX 2.2.8 to play it.
|
||||
Turn "Match Wii Controls" ON to use these controls.
|
||||
|
||||
WarioWare Twisted uses similar controls to the Gameboy game.
|
||||
|
||||
The Wii WarioWare Twisted controls are:
|
||||
=======================================
|
||||
|
||||
Rotate the Wii Remote to rotate.
|
||||
|
||||
Hold Z to lock the current menu item.
|
||||
|
||||
A = Select
|
||||
B = Cancel
|
||||
+ = Start
|
||||
|
||||
-=[ Kirby's Tilt n Tumble, Match Wii Controls ]=-
|
||||
|
||||
|
@ -1,6 +1,8 @@
|
||||
#ifndef SYSTEM_H
|
||||
#define SYSTEM_H
|
||||
|
||||
#include "common/Types.h"
|
||||
|
||||
#include <zlib.h>
|
||||
|
||||
class SoundDriver;
|
||||
@ -44,6 +46,7 @@ struct EmulatedSystem {
|
||||
};
|
||||
|
||||
extern void log(const char *,...);
|
||||
|
||||
extern bool systemPauseOnFrame();
|
||||
extern void systemGbPrint(u8 *,int,int,int,int,int);
|
||||
extern void systemScreenCapture(int);
|
||||
@ -52,6 +55,11 @@ extern void systemDrawScreen();
|
||||
extern bool systemReadJoypads();
|
||||
// return information about the given joystick, -1 for default joystick
|
||||
extern u32 systemReadJoypad(int);
|
||||
// this function should turn on or off rumble on the gamepad
|
||||
extern void systemCartridgeRumble(bool);
|
||||
extern void systemPossibleCartridgeRumble(bool);
|
||||
// This should be called once per frame
|
||||
extern void updateRumbleFrame();
|
||||
extern u32 systemGetClock();
|
||||
extern void systemMessage(int, const char *, ...);
|
||||
extern void systemSetTitle(const char *);
|
||||
@ -67,6 +75,7 @@ extern void systemShowSpeed(int);
|
||||
extern void system10Frames(int);
|
||||
extern void systemFrame();
|
||||
extern void systemGbBorderOn();
|
||||
|
||||
extern void Sm60FPS_Init();
|
||||
extern bool Sm60FPS_CanSkipFrame();
|
||||
extern void Sm60FPS_Sleep();
|
||||
@ -78,8 +87,10 @@ extern void winlog(const char *,...);
|
||||
#endif
|
||||
extern void (*dbgOutput)(const char *s, u32 addr);
|
||||
extern void (*dbgSignal)(int sig,int number);
|
||||
|
||||
extern u16 systemColorMap16[0x10000];
|
||||
extern u32 systemColorMap32[0x10000];
|
||||
//extern u32 systemColorMap32[0x10000];
|
||||
extern u32 *systemColorMap32;
|
||||
extern u16 systemGbPalette[24];
|
||||
extern int systemRedShift;
|
||||
extern int systemGreenShift;
|
||||
@ -90,6 +101,8 @@ extern int systemVerbose;
|
||||
extern int systemFrameSkip;
|
||||
extern int systemSaveUpdateCounter;
|
||||
extern int systemSpeed;
|
||||
|
||||
#define SYSTEM_SAVE_UPDATED 30
|
||||
#define SYSTEM_SAVE_NOT_UPDATED 0
|
||||
|
||||
#endif // SYSTEM_H
|
||||
|
@ -26,7 +26,6 @@ extern "C" {
|
||||
#include "common/memgzio.h"
|
||||
}
|
||||
|
||||
#include "gba/gbafilter.h"
|
||||
#include "gb/gbGlobals.h"
|
||||
|
||||
#ifndef _MSC_VER
|
||||
@ -39,7 +38,7 @@ extern int systemGreenShift;
|
||||
extern int systemBlueShift;
|
||||
|
||||
extern u16 systemColorMap16[0x10000];
|
||||
extern u32 systemColorMap32[0x10000];
|
||||
extern u32 *systemColorMap32;
|
||||
|
||||
static int (ZEXPORT *utilGzWriteFunc)(gzFile, const voidp, unsigned int) = NULL;
|
||||
static int (ZEXPORT *utilGzReadFunc)(gzFile, voidp, unsigned int) = NULL;
|
||||
@ -657,6 +656,7 @@ long utilGzMemTell(gzFile file)
|
||||
return memtell(file);
|
||||
}
|
||||
|
||||
#ifndef GEKKO
|
||||
void utilGBAFindSave(const u8 *data, const int size)
|
||||
{
|
||||
u32 *p = (u32 *)data;
|
||||
@ -743,3 +743,4 @@ bool utilFileExists( const char *filename )
|
||||
return true;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
@ -29,7 +29,7 @@ int const silent_buf_size = 1; // size used for Silent_Blip_Buffer
|
||||
|
||||
Blip_Buffer::Blip_Buffer()
|
||||
{
|
||||
factor_ = (blip_ulong)LONG_MAX;
|
||||
factor_ = LONG_MAX;
|
||||
buffer_ = 0;
|
||||
buffer_size_ = 0;
|
||||
sample_rate_ = 0;
|
||||
@ -126,7 +126,7 @@ Blip_Buffer::blargg_err_t Blip_Buffer::set_sample_rate( long new_rate, int msec
|
||||
|
||||
blip_resampled_time_t Blip_Buffer::clock_rate_factor( long rate ) const
|
||||
{
|
||||
double ratio = (double) sample_rate_ / rate;
|
||||
double ratio = (double)(sample_rate_) / double(rate);
|
||||
blip_long factor = (blip_long) floor( ratio * (1L << BLIP_BUFFER_ACCURACY) + 0.5 );
|
||||
assert( factor > 0 || !sample_rate_ ); // fails if clock/output ratio is too large
|
||||
return (blip_resampled_time_t) factor;
|
||||
@ -226,15 +226,17 @@ static void gen_sinc( float* out, int count, double oversample, double treble, d
|
||||
treble = 5.0;
|
||||
|
||||
double const maxh = 4096.0;
|
||||
double const rolloff = pow( 10.0, 1.0 / (maxh * 20.0) * treble / (1.0 - cutoff) );
|
||||
double const rolloff = pow( 10.0, treble / (maxh * 20.0 * (1.0 - cutoff)) );
|
||||
double const pow_a_n = pow( rolloff, maxh - maxh * cutoff );
|
||||
double const to_angle = PI / 2 / maxh / oversample;
|
||||
double const to_angle = PI / (2.0 * maxh * oversample);
|
||||
for ( int i = 0; i < count; i++ )
|
||||
{
|
||||
double angle = ((i - count) * 2 + 1) * to_angle;
|
||||
double c = rolloff * cos( (maxh - 1.0) * angle ) - cos( maxh * angle );
|
||||
double cos_nc_angle = cos( maxh * cutoff * angle );
|
||||
double cos_nc1_angle = cos( (maxh * cutoff - 1.0) * angle );
|
||||
double angle = double(((i - count)<<1) + 1) * to_angle;
|
||||
double maxhAngle = maxh * angle;
|
||||
double c = rolloff * cos( maxhAngle - angle ) - cos( maxhAngle );
|
||||
double cos_nc_angle = cos( maxhAngle * cutoff );
|
||||
double cos_nc1_angle = cos( maxhAngle * cutoff - angle );
|
||||
|
||||
double cos_angle = cos( angle );
|
||||
|
||||
c = c * pow_a_n - rolloff * cos_nc1_angle + cos_nc_angle;
|
||||
@ -250,7 +252,7 @@ void blip_eq_t::generate( float* out, int count ) const
|
||||
{
|
||||
// lower cutoff freq for narrow kernels with their wider transition band
|
||||
// (8 points->1.49, 16 points->1.15)
|
||||
double oversample = blip_res * 2.25 / count + 0.85;
|
||||
double oversample = blip_res * 2.25 / double(count) + 0.85;
|
||||
double half_rate = sample_rate * 0.5;
|
||||
if ( cutoff_freq )
|
||||
oversample = half_rate / cutoff_freq;
|
||||
@ -268,7 +270,9 @@ void Blip_Synth_::adjust_impulse()
|
||||
{
|
||||
// sum pairs for each phase and add error correction to end of first half
|
||||
int const size = impulses_size();
|
||||
for ( int p = blip_res; p-- >= blip_res / 2; )
|
||||
|
||||
int blipRes2 = blip_res >> 1;
|
||||
for ( int p = blip_res; p-- >= blipRes2; )
|
||||
{
|
||||
int p2 = blip_res - 2 - p;
|
||||
long error = kernel_unit;
|
||||
@ -290,9 +294,11 @@ void Blip_Synth_::adjust_impulse()
|
||||
|
||||
void Blip_Synth_::treble_eq( blip_eq_t const& eq )
|
||||
{
|
||||
float fimpulse [blip_res / 2 * (blip_widest_impulse_ - 1) + blip_res * 2];
|
||||
int blipRes2 = blip_res >> 1;
|
||||
|
||||
int const half_size = blip_res / 2 * (width - 1);
|
||||
float fimpulse [blipRes2 * (blip_widest_impulse_ - 1) + blip_res * 2];
|
||||
|
||||
int const half_size = blipRes2 * (width - 1);
|
||||
eq.generate( &fimpulse [blip_res], half_size );
|
||||
|
||||
int i;
|
||||
@ -302,25 +308,25 @@ void Blip_Synth_::treble_eq( blip_eq_t const& eq )
|
||||
fimpulse [blip_res + half_size + i] = fimpulse [blip_res + half_size - 1 - i];
|
||||
|
||||
// starts at 0
|
||||
for ( i = 0; i < blip_res; i++ )
|
||||
for ( i = 0; i < blip_res; ++i )
|
||||
fimpulse [i] = 0.0f;
|
||||
|
||||
// find rescale factor
|
||||
double total = 0.0;
|
||||
for ( i = 0; i < half_size; i++ )
|
||||
for ( i = 0; i < half_size; ++i )
|
||||
total += fimpulse [blip_res + i];
|
||||
|
||||
//double const base_unit = 44800.0 - 128 * 18; // allows treble up to +0 dB
|
||||
//double const base_unit = 37888.0; // allows treble to +5 dB
|
||||
double const base_unit = 32768.0; // necessary for blip_unscaled to work
|
||||
double rescale = base_unit / 2 / total;
|
||||
double rescale = base_unit / (2 * total);
|
||||
kernel_unit = (long) base_unit;
|
||||
|
||||
// integrate, first difference, rescale, convert to int
|
||||
double sum = 0.0;
|
||||
double next = 0.0;
|
||||
int const size = this->impulses_size();
|
||||
for ( i = 0; i < size; i++ )
|
||||
for ( i = 0; i < size; ++i )
|
||||
{
|
||||
impulses [i] = (short) (int) floor( (next - sum) * rescale + 0.5 );
|
||||
sum += fimpulse [i];
|
||||
@ -355,7 +361,7 @@ void Blip_Synth_::volume_unit( double new_unit )
|
||||
// if unit is really small, might need to attenuate kernel
|
||||
while ( factor < 2.0 )
|
||||
{
|
||||
shift++;
|
||||
++shift;
|
||||
factor *= 2.0;
|
||||
}
|
||||
|
||||
@ -411,7 +417,7 @@ long Blip_Buffer::read_samples( blip_sample_t* out_, long max_samples, int stere
|
||||
blip_long s = BLIP_READER_READ( reader );
|
||||
BLIP_READER_NEXT_IDX_( reader, bass, offset );
|
||||
BLIP_CLAMP( s, s );
|
||||
out [offset * 2] = (blip_sample_t) s;
|
||||
out [offset << 1] = (blip_sample_t) s;
|
||||
}
|
||||
while ( ++offset );
|
||||
}
|
||||
|
@ -505,7 +505,7 @@ void Effects_Buffer::mix_effects( blip_sample_t* out_, int pair_count )
|
||||
int bufs_remain = bufs_size;
|
||||
do
|
||||
{
|
||||
if ( buf->non_silent() && ( buf->echo == !!echo_phase ) )
|
||||
if ( buf->non_silent() && ( buf->echo == (bool)echo_phase ) )
|
||||
{
|
||||
stereo_fixed_t* BLIP_RESTRICT out = (stereo_fixed_t*) &echo [echo_pos];
|
||||
int const bass = BLIP_READER_BASS( *buf );
|
||||
|
@ -1433,10 +1433,12 @@ void gbWriteMemory(register u16 address, register u8 value)
|
||||
int paletteHiLo = (v & 0x01);
|
||||
|
||||
// No access to gbPalette during mode 3 (Color Panel Demo)
|
||||
if (((gbLcdModeDelayed != 3) && (!((gbLcdMode == 0) && (gbLcdTicks>=(GBLCD_MODE_0_CLOCK_TICKS-gbSpritesTicks[299]-1)))) && (!gbSpeed)) ||
|
||||
(gbSpeed && ((gbLcdMode == 1) || (gbLcdMode == 2) ||
|
||||
((gbLcdMode == 3) && (gbLcdTicks>(GBLCD_MODE_3_CLOCK_TICKS-2))) ||
|
||||
((gbLcdMode == 0) && (gbLcdTicks<=(GBLCD_MODE_0_CLOCK_TICKS-gbSpritesTicks[299]-2))))))
|
||||
// CAK - The following check has to be commented out for
|
||||
// colourised roms like Metroid 2 DX
|
||||
//if (((gbLcdModeDelayed != 3) && (!((gbLcdMode == 0) && (gbLcdTicks>=(GBLCD_MODE_0_CLOCK_TICKS-gbSpritesTicks[299]-1)))) && (!gbSpeed)) ||
|
||||
// (gbSpeed && ((gbLcdMode == 1) || (gbLcdMode == 2) ||
|
||||
// ((gbLcdMode == 3) && (gbLcdTicks>(GBLCD_MODE_3_CLOCK_TICKS-2))) ||
|
||||
// ((gbLcdMode == 0) && (gbLcdTicks<=(GBLCD_MODE_0_CLOCK_TICKS-gbSpritesTicks[299]-2))))))
|
||||
{
|
||||
gbMemory[0xff69] = value;
|
||||
gbPalette[paletteIndex] = (paletteHiLo ?
|
||||
@ -1487,10 +1489,12 @@ void gbWriteMemory(register u16 address, register u8 value)
|
||||
paletteIndex += 32;
|
||||
|
||||
// No access to gbPalette during mode 3 (Color Panel Demo)
|
||||
if (((gbLcdModeDelayed != 3) && (!((gbLcdMode == 0) && (gbLcdTicks>=(GBLCD_MODE_0_CLOCK_TICKS-gbSpritesTicks[299]-1)))) && (!gbSpeed)) ||
|
||||
(gbSpeed && ((gbLcdMode == 1) || (gbLcdMode == 2) ||
|
||||
((gbLcdMode == 3) && (gbLcdTicks>(GBLCD_MODE_3_CLOCK_TICKS-2))) ||
|
||||
((gbLcdMode == 0) && (gbLcdTicks<=(GBLCD_MODE_0_CLOCK_TICKS-gbSpritesTicks[299]-2))))))
|
||||
// CAK - The following check has to be commented out for
|
||||
// colourised roms like Metroid 2 DX
|
||||
//if (((gbLcdModeDelayed != 3) && (!((gbLcdMode == 0) && (gbLcdTicks>=(GBLCD_MODE_0_CLOCK_TICKS-gbSpritesTicks[299]-1)))) && (!gbSpeed)) ||
|
||||
// (gbSpeed && ((gbLcdMode == 1) || (gbLcdMode == 2) ||
|
||||
// ((gbLcdMode == 3) && (gbLcdTicks>(GBLCD_MODE_3_CLOCK_TICKS-2))) ||
|
||||
// ((gbLcdMode == 0) && (gbLcdTicks<=(GBLCD_MODE_0_CLOCK_TICKS-gbSpritesTicks[299]-2))))))
|
||||
{
|
||||
gbMemory[0xff6b] = value;
|
||||
gbPalette[paletteIndex] = (paletteHiLo ?
|
||||
@ -1683,13 +1687,13 @@ u8 gbReadOpcode(register u16 address)
|
||||
if (gbCgbMode)
|
||||
{
|
||||
// No access to gbPalette during mode 3 (Color Panel Demo)
|
||||
if (((gbLcdModeDelayed != 3) && (!((gbLcdMode == 0) && (gbLcdTicks>=(GBLCD_MODE_0_CLOCK_TICKS-gbSpritesTicks[299]-1)))) && (!gbSpeed)) ||
|
||||
(gbSpeed && ((gbLcdMode == 1) || (gbLcdMode == 2) ||
|
||||
((gbLcdMode == 3) && (gbLcdTicks>(GBLCD_MODE_3_CLOCK_TICKS-2))) ||
|
||||
((gbLcdMode == 0) && (gbLcdTicks<=(GBLCD_MODE_0_CLOCK_TICKS-gbSpritesTicks[299]-2))))))
|
||||
//if (((gbLcdModeDelayed != 3) && (!((gbLcdMode == 0) && (gbLcdTicks>=(GBLCD_MODE_0_CLOCK_TICKS-gbSpritesTicks[299]-1)))) && (!gbSpeed)) ||
|
||||
// (gbSpeed && ((gbLcdMode == 1) || (gbLcdMode == 2) ||
|
||||
// ((gbLcdMode == 3) && (gbLcdTicks>(GBLCD_MODE_3_CLOCK_TICKS-2))) ||
|
||||
// ((gbLcdMode == 0) && (gbLcdTicks<=(GBLCD_MODE_0_CLOCK_TICKS-gbSpritesTicks[299]-2))))))
|
||||
return (gbMemory[address]);
|
||||
else
|
||||
return 0xff;
|
||||
//else
|
||||
// return 0xff;
|
||||
}
|
||||
else
|
||||
return 0xff;
|
||||
@ -1733,7 +1737,6 @@ u8 gbReadMemory(register u16 address)
|
||||
if(address < 0x8000)
|
||||
return gbMemoryMap[address>>12][address&0x0fff];
|
||||
|
||||
|
||||
if(address < 0xa000)
|
||||
{
|
||||
// A lot of 'ugly' checks... But only way to emulate this particular behaviour...
|
||||
@ -1760,7 +1763,6 @@ u8 gbReadMemory(register u16 address)
|
||||
)
|
||||
)
|
||||
return gbMemoryMap[address>>12][address&0x0fff];
|
||||
|
||||
return 0xff;
|
||||
}
|
||||
|
||||
@ -1961,13 +1963,13 @@ u8 gbReadMemory(register u16 address)
|
||||
if (gbCgbMode)
|
||||
{
|
||||
// No access to gbPalette during mode 3 (Color Panel Demo)
|
||||
if (((gbLcdModeDelayed != 3) && (!((gbLcdMode == 0) && (gbLcdTicks>=(GBLCD_MODE_0_CLOCK_TICKS-gbSpritesTicks[299]-1)))) && (!gbSpeed)) ||
|
||||
(gbSpeed && ((gbLcdMode == 1) || (gbLcdMode == 2) ||
|
||||
((gbLcdMode == 3) && (gbLcdTicks>(GBLCD_MODE_3_CLOCK_TICKS-2))) ||
|
||||
((gbLcdMode == 0) && (gbLcdTicks<=(GBLCD_MODE_0_CLOCK_TICKS-gbSpritesTicks[299]-2))))))
|
||||
//if (((gbLcdModeDelayed != 3) && (!((gbLcdMode == 0) && (gbLcdTicks>=(GBLCD_MODE_0_CLOCK_TICKS-gbSpritesTicks[299]-1)))) && (!gbSpeed)) ||
|
||||
// (gbSpeed && ((gbLcdMode == 1) || (gbLcdMode == 2) ||
|
||||
// ((gbLcdMode == 3) && (gbLcdTicks>(GBLCD_MODE_3_CLOCK_TICKS-2))) ||
|
||||
// ((gbLcdMode == 0) && (gbLcdTicks<=(GBLCD_MODE_0_CLOCK_TICKS-gbSpritesTicks[299]-2))))))
|
||||
return (gbMemory[address]);
|
||||
else
|
||||
return 0xff;
|
||||
//else
|
||||
// return 0xff;
|
||||
}
|
||||
else
|
||||
return 0xff;
|
||||
@ -2124,7 +2126,7 @@ void gbCPUInit(const char *biosFileName, bool useBiosFile)
|
||||
useBios = false;
|
||||
if (useBiosFile)
|
||||
{
|
||||
int size = 0x100;
|
||||
/* int size = 0x100;
|
||||
if(utilLoad(biosFileName,
|
||||
CPUIsGBBios,
|
||||
bios,
|
||||
@ -2133,7 +2135,7 @@ void gbCPUInit(const char *biosFileName, bool useBiosFile)
|
||||
useBios = true;
|
||||
else
|
||||
systemMessage(MSG_INVALID_BIOS_FILE_SIZE, N_("Invalid BOOTROM file size"));
|
||||
}
|
||||
}*/
|
||||
}
|
||||
}
|
||||
|
||||
@ -2172,7 +2174,9 @@ void gbGetHardwareType()
|
||||
|
||||
void gbReset()
|
||||
{
|
||||
systemCartridgeRumble(false);
|
||||
gbGetHardwareType();
|
||||
gbPaletteReset();
|
||||
|
||||
oldRegister_WY = 146;
|
||||
gbInterruptLaunched = 0;
|
||||
@ -2468,7 +2472,7 @@ void gbReset()
|
||||
gbTimerOn = false;
|
||||
|
||||
if(gbCgbMode) {
|
||||
for (i = 0; i<0x20; i++)
|
||||
for (int i = 0; i<0x20; i++)
|
||||
gbPalette[i] = 0x7fff;
|
||||
|
||||
// This is just to show that the starting values of the OBJ palettes are different
|
||||
@ -2586,12 +2590,12 @@ void gbReset()
|
||||
}
|
||||
} else {
|
||||
if(gbSgbMode) {
|
||||
for(i = 0; i < 8; i++)
|
||||
gbPalette[i] = systemGbPalette[gbPaletteOption*8+i];
|
||||
for(int i = 0; i < 12; i++)
|
||||
gbPalette[i] = systemGbPalette[gbPaletteOption*12+i];
|
||||
|
||||
}
|
||||
for(i = 0; i < 8; i++)
|
||||
gbPalette[i] = systemGbPalette[gbPaletteOption*8+i];
|
||||
for(int i = 0; i < 12; i++)
|
||||
gbPalette[i] = systemGbPalette[gbPaletteOption*12+i];
|
||||
}
|
||||
|
||||
GBTIMER_MODE_0_CLOCK_TICKS = 256;
|
||||
@ -2645,6 +2649,8 @@ void gbReset()
|
||||
|
||||
memset(&gbDataMBC5, 0, sizeof(gbDataMBC5));
|
||||
gbDataMBC5.mapperROMBank = 1;
|
||||
if (gbRomType >= 0x1c && gbRomType<=0x1e)
|
||||
gbDataMBC5.isRumbleCartridge = 1;
|
||||
|
||||
memset(&gbDataHuC1, 0, sizeof(gbDataHuC1));
|
||||
gbDataHuC1.mapperROMBank = 1;
|
||||
@ -2746,7 +2752,7 @@ void gbWriteSaveMBC2(const char * name)
|
||||
return;
|
||||
}
|
||||
|
||||
fwrite(gbMemoryMap[0x0a],
|
||||
fwrite(&gbMemoryMap[0x0a],
|
||||
1,
|
||||
512,
|
||||
file);
|
||||
@ -2928,7 +2934,7 @@ bool gbReadSaveMBC2(const char * name)
|
||||
return false;
|
||||
}
|
||||
|
||||
size_t read = fread(gbMemoryMap[0x0a],
|
||||
size_t read = fread(&gbMemoryMap[0x0a],
|
||||
1,
|
||||
512,
|
||||
file);
|
||||
@ -4007,16 +4013,18 @@ bool gbReadSaveState(const char *name)
|
||||
|
||||
bool gbWritePNGFile(const char *fileName)
|
||||
{
|
||||
if(gbBorderOn)
|
||||
/* if(gbBorderOn)
|
||||
return utilWritePNGFile(fileName, 256, 224, pix);
|
||||
return utilWritePNGFile(fileName, 160, 144, pix);
|
||||
return utilWritePNGFile(fileName, 160, 144, pix);*/
|
||||
return false;
|
||||
}
|
||||
|
||||
bool gbWriteBMPFile(const char *fileName)
|
||||
{
|
||||
if(gbBorderOn)
|
||||
/* if(gbBorderOn)
|
||||
return utilWriteBMPFile(fileName, 256, 224, pix);
|
||||
return utilWriteBMPFile(fileName, 160, 144, pix);
|
||||
return utilWriteBMPFile(fileName, 160, 144, pix);*/
|
||||
return false;
|
||||
}
|
||||
|
||||
void gbCleanUp()
|
||||
@ -4081,10 +4089,10 @@ bool gbLoadRom(const char *szFile)
|
||||
|
||||
systemSaveUpdateCounter = SYSTEM_SAVE_NOT_UPDATED;
|
||||
|
||||
gbRom = utilLoad(szFile,
|
||||
/* gbRom = utilLoad(szFile,
|
||||
utilIsGBImage,
|
||||
NULL,
|
||||
size);
|
||||
size);*/
|
||||
if(!gbRom)
|
||||
return false;
|
||||
|
||||
@ -4513,6 +4521,7 @@ void gbEmulate(int ticksToStop)
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
u16 oldPCW = PC.W;
|
||||
|
||||
if(IFF & 0x80) {
|
||||
|
@ -583,10 +583,18 @@ void mapperMBC5ROM(u16 address, u8 value)
|
||||
gbMemoryMap[0x07] = &gbRom[tmpAddress + 0x3000];
|
||||
}
|
||||
break;
|
||||
case 0x4000: // RAM bank select
|
||||
if(gbDataMBC5.isRumbleCartridge)
|
||||
case 0x4000: // RAM bank select, plus rumble
|
||||
// Some games support rumble, such as Disney Tarzan, but aren't on a
|
||||
// rumble cartridge. As long as the RAM is less than or equal to 256Kbit
|
||||
// we know that the last address line is not used for real RAM addresses,
|
||||
// so it must be a rumble signal instead.
|
||||
if(gbDataMBC5.isRumbleCartridge) {
|
||||
systemCartridgeRumble(value & 0x08);
|
||||
value &= 0x07;
|
||||
else
|
||||
} else if (gbRamSizeMask <= 0x7FFF) {
|
||||
systemPossibleCartridgeRumble(value & 0x08);
|
||||
value &= 0x07;
|
||||
} else
|
||||
value &= 0x0f;
|
||||
if(value == gbDataMBC5.mapperRAMBank)
|
||||
break;
|
||||
|
@ -521,11 +521,11 @@ void CPUUpdateWindow0()
|
||||
int x01 = WIN0H & 255;
|
||||
|
||||
if(x00 <= x01) {
|
||||
for(int i = 0; i < 240; i++) {
|
||||
for(int i = 0; i < 240; ++i) {
|
||||
gfxInWin0[i] = (i >= x00 && i < x01);
|
||||
}
|
||||
} else {
|
||||
for(int i = 0; i < 240; i++) {
|
||||
for(int i = 0; i < 240; ++i) {
|
||||
gfxInWin0[i] = (i >= x00 || i < x01);
|
||||
}
|
||||
}
|
||||
@ -537,11 +537,11 @@ void CPUUpdateWindow1()
|
||||
int x01 = WIN1H & 255;
|
||||
|
||||
if(x00 <= x01) {
|
||||
for(int i = 0; i < 240; i++) {
|
||||
for(int i = 0; i < 240; ++i) {
|
||||
gfxInWin1[i] = (i >= x00 && i < x01);
|
||||
}
|
||||
} else {
|
||||
for(int i = 0; i < 240; i++) {
|
||||
for(int i = 0; i < 240; ++i) {
|
||||
gfxInWin1[i] = (i >= x00 || i < x01);
|
||||
}
|
||||
}
|
||||
@ -667,7 +667,6 @@ bool CPUWriteState(const char *file)
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
bool CPUWriteMemState(char *memory, int available)
|
||||
{
|
||||
gzFile gzFile = utilMemGzOpen(memory, available, "w");
|
||||
@ -1325,12 +1324,12 @@ bool CPUReadBatteryFile(const char *fileName)
|
||||
|
||||
bool CPUWritePNGFile(const char *fileName)
|
||||
{
|
||||
return utilWritePNGFile(fileName, 240, 160, pix);
|
||||
return false; //utilWritePNGFile(fileName, 240, 160, pix);
|
||||
}
|
||||
|
||||
bool CPUWriteBMPFile(const char *fileName)
|
||||
{
|
||||
return utilWriteBMPFile(fileName, 240, 160, pix);
|
||||
return false; //utilWriteBMPFile(fileName, 240, 160, pix);
|
||||
}
|
||||
|
||||
bool CPUIsZipFile(const char * file)
|
||||
@ -1494,7 +1493,7 @@ int CPULoadRom(const char *szFile)
|
||||
return 0;
|
||||
}
|
||||
|
||||
u8 *whereToLoad = cpuIsMultiBoot ? workRAM : rom;
|
||||
//u8 *whereToLoad = cpuIsMultiBoot ? workRAM : rom;
|
||||
|
||||
#ifndef NO_DEBUGGER
|
||||
if(CPUIsELF(szFile)) {
|
||||
@ -1519,7 +1518,7 @@ int CPULoadRom(const char *szFile)
|
||||
}
|
||||
} else
|
||||
#endif //NO_DEBUGGER
|
||||
if(szFile!=NULL)
|
||||
/* if(szFile!=NULL)
|
||||
{
|
||||
if(!utilLoad(szFile,
|
||||
utilIsGBAImage,
|
||||
@ -1538,7 +1537,7 @@ int CPULoadRom(const char *szFile)
|
||||
for(i = (romSize+1)&~1; i < 0x2000000; i+=2) {
|
||||
WRITE16LE(temp, (i >> 1) & 0xFFFF);
|
||||
temp++;
|
||||
}
|
||||
}*/
|
||||
|
||||
bios = (u8 *)calloc(1,0x4000);
|
||||
if(bios == NULL) {
|
||||
@ -2201,7 +2200,7 @@ void CPUCompareVCOUNT()
|
||||
}
|
||||
if (layerEnableDelay>0)
|
||||
{
|
||||
layerEnableDelay--;
|
||||
--layerEnableDelay;
|
||||
if (layerEnableDelay==1)
|
||||
layerEnable = layerSettings & DISPCNT;
|
||||
}
|
||||
@ -2233,7 +2232,7 @@ void doDMA(u32 &s, u32 &d, u32 si, u32 di, u32 c, int transfer32)
|
||||
while(c != 0) {
|
||||
CPUWriteMemory(d, 0);
|
||||
d += di;
|
||||
c--;
|
||||
--c;
|
||||
}
|
||||
} else {
|
||||
while(c != 0) {
|
||||
@ -2241,7 +2240,7 @@ void doDMA(u32 &s, u32 &d, u32 si, u32 di, u32 c, int transfer32)
|
||||
CPUWriteMemory(d, cpuDmaLast);
|
||||
d += di;
|
||||
s += si;
|
||||
c--;
|
||||
--c;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@ -2252,7 +2251,7 @@ void doDMA(u32 &s, u32 &d, u32 si, u32 di, u32 c, int transfer32)
|
||||
while(c != 0) {
|
||||
CPUWriteHalfWord(d, 0);
|
||||
d += di;
|
||||
c--;
|
||||
--c;
|
||||
}
|
||||
} else {
|
||||
while(c != 0) {
|
||||
@ -2261,7 +2260,7 @@ void doDMA(u32 &s, u32 &d, u32 si, u32 di, u32 c, int transfer32)
|
||||
cpuDmaLast |= (cpuDmaLast<<16);
|
||||
d += di;
|
||||
s += si;
|
||||
c--;
|
||||
--c;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2521,7 +2520,6 @@ void CPUCheckDMA(int reason, int dmamask)
|
||||
doDMA(dma3Source, dma3Dest, sourceIncrement, destIncrement,
|
||||
DM3CNT_L ? DM3CNT_L : 0x10000,
|
||||
DM3CNT_H & 0x0400);
|
||||
|
||||
if(DM3CNT_H & 0x4000) {
|
||||
IF |= 0x0800;
|
||||
UPDATE_REG(0x202, IF);
|
||||
@ -2568,7 +2566,7 @@ void CPUUpdateRegister(u32 address, u16 value)
|
||||
windowOn = (layerEnable & 0x6000) ? true : false;
|
||||
if(change && !((value & 0x80))) {
|
||||
if(!(DISPSTAT & 1)) {
|
||||
//lcdTicks = 1008;
|
||||
lcdTicks = 1008;
|
||||
// VCOUNT = 0;
|
||||
// UPDATE_REG(0x06, VCOUNT);
|
||||
DISPSTAT &= 0xFFFC;
|
||||
@ -2963,65 +2961,61 @@ void CPUUpdateRegister(u32 address, u16 value)
|
||||
timerOnOffDelay|=8;
|
||||
cpuNextEvent = cpuTotalTicks;
|
||||
break;
|
||||
|
||||
|
||||
#ifndef NO_LINK
|
||||
case COMM_SIOCNT:
|
||||
case 0x128:
|
||||
#ifdef LINK_EMULATION
|
||||
if (linkenable)
|
||||
{
|
||||
StartLink(value);
|
||||
break;
|
||||
|
||||
case COMM_SIODATA8:
|
||||
UPDATE_REG(COMM_SIODATA8, value);
|
||||
break;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
|
||||
{
|
||||
if(value & 0x80) {
|
||||
value &= 0xff7f;
|
||||
if(value & 1 && (value & 0x4000)) {
|
||||
UPDATE_REG(0x12a, 0xFF);
|
||||
IF |= 0x80;
|
||||
UPDATE_REG(0x202, IF);
|
||||
value &= 0x7f7f;
|
||||
}
|
||||
}
|
||||
UPDATE_REG(0x128, value);
|
||||
}
|
||||
break;
|
||||
case 0x12a:
|
||||
#ifdef LINK_EMULATION
|
||||
if(linkenable && lspeed)
|
||||
LinkSSend(value);
|
||||
#endif
|
||||
{
|
||||
UPDATE_REG(0x134, value);
|
||||
}
|
||||
break;
|
||||
case 0x130:
|
||||
P1 |= (value & 0x3FF);
|
||||
UPDATE_REG(0x130, P1);
|
||||
break;
|
||||
|
||||
case 0x132:
|
||||
UPDATE_REG(0x132, value & 0xC3FF);
|
||||
break;
|
||||
|
||||
#ifndef NO_LINK
|
||||
case COMM_RCNT:
|
||||
case 0x134:
|
||||
#ifdef LINK_EMULATION
|
||||
if (linkenable)
|
||||
StartGPLink(value);
|
||||
break;
|
||||
|
||||
case COMM_JOYCNT:
|
||||
{
|
||||
u16 cur = READ16LE(&ioMem[COMM_JOYCNT]);
|
||||
|
||||
if (value & JOYCNT_RESET) cur &= ~JOYCNT_RESET;
|
||||
if (value & JOYCNT_RECV_COMPLETE) cur &= ~JOYCNT_RECV_COMPLETE;
|
||||
if (value & JOYCNT_SEND_COMPLETE) cur &= ~JOYCNT_SEND_COMPLETE;
|
||||
if (value & JOYCNT_INT_ENABLE) cur |= JOYCNT_INT_ENABLE;
|
||||
|
||||
UPDATE_REG(COMM_JOYCNT, cur);
|
||||
}
|
||||
break;
|
||||
|
||||
case COMM_JOY_RECV_L:
|
||||
UPDATE_REG(COMM_JOY_RECV_L, value);
|
||||
break;
|
||||
case COMM_JOY_RECV_H:
|
||||
UPDATE_REG(COMM_JOY_RECV_H, value);
|
||||
break;
|
||||
|
||||
case COMM_JOY_TRANS_L:
|
||||
UPDATE_REG(COMM_JOY_TRANS_L, value);
|
||||
UPDATE_REG(COMM_JOYSTAT, READ16LE(&ioMem[COMM_JOYSTAT]) | JOYSTAT_SEND);
|
||||
break;
|
||||
case COMM_JOY_TRANS_H:
|
||||
UPDATE_REG(COMM_JOY_TRANS_H, value);
|
||||
break;
|
||||
|
||||
case COMM_JOYSTAT:
|
||||
UPDATE_REG(COMM_JOYSTAT, (READ16LE(&ioMem[COMM_JOYSTAT]) & 0xf) | (value & 0xf0));
|
||||
break;
|
||||
else
|
||||
#endif
|
||||
UPDATE_REG(0x134, value);
|
||||
|
||||
break;
|
||||
case 0x140:
|
||||
#ifdef LINK_EMULATION
|
||||
if (linkenable)
|
||||
StartJOYLink(value);
|
||||
else
|
||||
#endif
|
||||
UPDATE_REG(0x140, value);
|
||||
|
||||
break;
|
||||
case 0x200:
|
||||
IE = value & 0x3FFF;
|
||||
UPDATE_REG(0x200, IE);
|
||||
@ -3061,7 +3055,7 @@ void CPUUpdateRegister(u32 address, u16 value)
|
||||
|
||||
for(int i = 8; i < 15; i++) {
|
||||
memoryWait32[i] = memoryWait[i] + memoryWaitSeq[i] + 1;
|
||||
memoryWaitSeq32[i] = memoryWaitSeq[i]*2 + 1;
|
||||
memoryWaitSeq32[i] = (memoryWaitSeq[i]<<1) + 1;
|
||||
}
|
||||
|
||||
if((value & 0x4000) == 0x4000) {
|
||||
@ -3173,7 +3167,7 @@ void CPUInit(const char *biosFileName, bool useBiosFile)
|
||||
saveType = 0;
|
||||
useBios = false;
|
||||
|
||||
if(useBiosFile) {
|
||||
/* if(useBiosFile) {
|
||||
int size = 0x4000;
|
||||
if(utilLoad(biosFileName,
|
||||
CPUIsGBABios,
|
||||
@ -3184,7 +3178,7 @@ void CPUInit(const char *biosFileName, bool useBiosFile)
|
||||
else
|
||||
systemMessage(MSG_INVALID_BIOS_FILE_SIZE, N_("Invalid BIOS file size"));
|
||||
}
|
||||
}
|
||||
}*/
|
||||
|
||||
if(!useBios) {
|
||||
memcpy(bios, myROM, sizeof(myROM));
|
||||
@ -3256,6 +3250,7 @@ void CPUInit(const char *biosFileName, bool useBiosFile)
|
||||
|
||||
void CPUReset()
|
||||
{
|
||||
systemCartridgeRumble(false);
|
||||
if(gbaSaveType == 0) {
|
||||
if(eepromInUse)
|
||||
gbaSaveType = 3;
|
||||
@ -3552,7 +3547,7 @@ void CPUReset()
|
||||
|
||||
cpuDmaHack = false;
|
||||
|
||||
lastTime = systemGetClock();
|
||||
//lastTime = systemGetClock();
|
||||
|
||||
SWITicks = 0;
|
||||
}
|
||||
@ -3672,7 +3667,7 @@ void CPULoop(int ticks)
|
||||
// if in V-Blank mode, keep computing...
|
||||
if(DISPSTAT & 2) {
|
||||
lcdTicks += 1008;
|
||||
VCOUNT++;
|
||||
++VCOUNT;
|
||||
UPDATE_REG(0x06, VCOUNT);
|
||||
DISPSTAT &= 0xFFFD;
|
||||
UPDATE_REG(0x04, DISPSTAT);
|
||||
@ -3687,7 +3682,7 @@ void CPULoop(int ticks)
|
||||
}
|
||||
}
|
||||
|
||||
if(VCOUNT > 227) { //Reaching last line
|
||||
if(VCOUNT >= 228) { //Reaching last line
|
||||
DISPSTAT &= 0xFFFC;
|
||||
UPDATE_REG(0x04, DISPSTAT);
|
||||
VCOUNT = 0;
|
||||
@ -3701,26 +3696,26 @@ void CPULoop(int ticks)
|
||||
|
||||
if(DISPSTAT & 2) {
|
||||
// if in H-Blank, leave it and move to drawing mode
|
||||
VCOUNT++;
|
||||
++VCOUNT;
|
||||
UPDATE_REG(0x06, VCOUNT);
|
||||
|
||||
lcdTicks += 1008;
|
||||
DISPSTAT &= 0xFFFD;
|
||||
if(VCOUNT == 160) {
|
||||
count++;
|
||||
++count;
|
||||
systemFrame();
|
||||
|
||||
if((count % 10) == 0) {
|
||||
system10Frames(60);
|
||||
}
|
||||
if(count == 60) {
|
||||
u32 time = systemGetClock();
|
||||
/*u32 time = systemGetClock();
|
||||
if(time != lastTime) {
|
||||
u32 t = 100000/(time - lastTime);
|
||||
systemShowSpeed(t);
|
||||
} else
|
||||
systemShowSpeed(0);
|
||||
lastTime = time;
|
||||
lastTime = time;*/
|
||||
count = 0;
|
||||
}
|
||||
u32 joy = 0;
|
||||
@ -3729,7 +3724,7 @@ void CPULoop(int ticks)
|
||||
// read default joystick
|
||||
joy = systemReadJoypad(-1);
|
||||
P1 = 0x03FF ^ (joy & 0x3FF);
|
||||
if(cpuEEPROMSensorEnabled)
|
||||
//if(cpuEEPROMSensorEnabled)
|
||||
systemUpdateMotionSensor();
|
||||
UPDATE_REG(0x130, P1);
|
||||
u16 P1CNT = READ16LE(((u16 *)&ioMem[0x132]));
|
||||
@ -3759,7 +3754,7 @@ void CPULoop(int ticks)
|
||||
capture = (ext & 2) ? true : false;
|
||||
|
||||
if(capture && !capturePrevious) {
|
||||
captureNumber++;
|
||||
++captureNumber;
|
||||
systemScreenCapture(captureNumber);
|
||||
}
|
||||
capturePrevious = capture;
|
||||
@ -3776,7 +3771,7 @@ void CPULoop(int ticks)
|
||||
systemDrawScreen();
|
||||
frameCount = 0;
|
||||
} else
|
||||
frameCount++;
|
||||
++frameCount;
|
||||
if(systemPauseOnFrame())
|
||||
ticks = 0;
|
||||
}
|
||||
@ -3791,8 +3786,8 @@ void CPULoop(int ticks)
|
||||
switch(systemColorDepth) {
|
||||
case 16:
|
||||
{
|
||||
u16 *dest = (u16 *)pix + 242 * VCOUNT;
|
||||
for(int x = 0; x < 240;) {
|
||||
u16 *dest = (u16 *)pix + 242 * (VCOUNT+1);
|
||||
for(u32 x = 0; x < 240u;) {
|
||||
*dest++ = systemColorMap16[lineMix[x++]&0xFFFF];
|
||||
*dest++ = systemColorMap16[lineMix[x++]&0xFFFF];
|
||||
*dest++ = systemColorMap16[lineMix[x++]&0xFFFF];
|
||||
@ -3819,8 +3814,8 @@ void CPULoop(int ticks)
|
||||
break;
|
||||
case 24:
|
||||
{
|
||||
u8 *dest = (u8 *)pix + 240 * VCOUNT * 3;
|
||||
for(int x = 0; x < 240;) {
|
||||
u8 *dest = (u8 *)pix + VCOUNT * 720;
|
||||
for(u32 x = 0; x < 240u;) {
|
||||
*((u32 *)dest) = systemColorMap32[lineMix[x++] & 0xFFFF];
|
||||
dest += 3;
|
||||
*((u32 *)dest) = systemColorMap32[lineMix[x++] & 0xFFFF];
|
||||
@ -3861,8 +3856,8 @@ void CPULoop(int ticks)
|
||||
break;
|
||||
case 32:
|
||||
{
|
||||
u32 *dest = (u32 *)pix + 241 * VCOUNT;
|
||||
for(int x = 0; x < 240; ) {
|
||||
u32 *dest = (u32 *)pix + 241 * (VCOUNT+1);
|
||||
for(u32 x = 0; x < 240u; ) {
|
||||
*dest++ = systemColorMap32[lineMix[x++] & 0xFFFF];
|
||||
*dest++ = systemColorMap32[lineMix[x++] & 0xFFFF];
|
||||
*dest++ = systemColorMap32[lineMix[x++] & 0xFFFF];
|
||||
@ -3928,7 +3923,7 @@ void CPULoop(int ticks)
|
||||
if(timer1On) {
|
||||
if(TM1CNT & 4) {
|
||||
if(timerOverflow & 1) {
|
||||
TM1D++;
|
||||
++TM1D;
|
||||
if(TM1D == 0) {
|
||||
TM1D += timer1Reload;
|
||||
timerOverflow |= 2;
|
||||
@ -3959,7 +3954,7 @@ void CPULoop(int ticks)
|
||||
if(timer2On) {
|
||||
if(TM2CNT & 4) {
|
||||
if(timerOverflow & 2) {
|
||||
TM2D++;
|
||||
++TM2D;
|
||||
if(TM2D == 0) {
|
||||
TM2D += timer2Reload;
|
||||
timerOverflow |= 4;
|
||||
@ -3988,7 +3983,7 @@ void CPULoop(int ticks)
|
||||
if(timer3On) {
|
||||
if(TM3CNT & 4) {
|
||||
if(timerOverflow & 4) {
|
||||
TM3D++;
|
||||
++TM3D;
|
||||
if(TM3D == 0) {
|
||||
TM3D += timer3Reload;
|
||||
if(TM3CNT & 0x40) {
|
||||
@ -4065,7 +4060,6 @@ void CPULoop(int ticks)
|
||||
if(gba_link_enabled)
|
||||
cpuNextEvent = 1;
|
||||
#endif
|
||||
|
||||
if(IF && (IME & 1) && armIrqEnable) {
|
||||
int res = IF & IE;
|
||||
if(stopState)
|
||||
@ -4131,6 +4125,7 @@ void CPULoop(int ticks)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#ifdef TILED_RENDERING
|
||||
union u8h
|
||||
{
|
||||
@ -4398,7 +4393,6 @@ void gfxDrawTextScreen(u16 control, u16 hofs, u16 vofs, u32 *line)
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
struct EmulatedSystem GBASystem = {
|
||||
// emuMain
|
||||
CPULoop,
|
||||
|
@ -5,11 +5,7 @@ extern int armExecute();
|
||||
extern int thumbExecute();
|
||||
|
||||
#ifdef __GNUC__
|
||||
#ifndef __APPLE__
|
||||
# define INSN_REGPARM __attribute__((regparm(1)))
|
||||
#else
|
||||
# define INSN_REGPARM /*nothing*/
|
||||
#endif
|
||||
# define LIKELY(x) __builtin_expect(!!(x),1)
|
||||
# define UNLIKELY(x) __builtin_expect(!!(x),0)
|
||||
#else
|
||||
|
@ -6,8 +6,7 @@
|
||||
#include "RTC.h"
|
||||
#include "Sound.h"
|
||||
#include "agbprint.h"
|
||||
#include "GBAcpu.h"
|
||||
#include "GBALink.h"
|
||||
#include "vmmem.h" // Nintendo GC Virtual Memory
|
||||
|
||||
extern const u32 objTilesAddress[3];
|
||||
|
||||
@ -34,16 +33,83 @@ extern bool timer3On;
|
||||
extern int timer3Ticks;
|
||||
extern int timer3ClockReload;
|
||||
extern int cpuTotalTicks;
|
||||
extern u32 RomIdCode;
|
||||
|
||||
#define CPUReadByteQuick(addr) \
|
||||
#define gid(a,b,c) (a|(b<<8)|(c<<16))
|
||||
#define CORVETTE gid('A','V','C')
|
||||
|
||||
/*****************************************************************************
|
||||
* Nintendo GC Virtual Memory function override
|
||||
* Tantric September 2008
|
||||
****************************************************************************/
|
||||
|
||||
#define CPUReadByteQuickDef(addr) \
|
||||
map[(addr)>>24].address[(addr) & map[(addr)>>24].mask]
|
||||
|
||||
#define CPUReadHalfWordQuick(addr) \
|
||||
#define CPUReadHalfWordQuickDef(addr) \
|
||||
READ16LE(((u16*)&map[(addr)>>24].address[(addr) & map[(addr)>>24].mask]))
|
||||
|
||||
#define CPUReadMemoryQuick(addr) \
|
||||
#define CPUReadMemoryQuickDef(addr) \
|
||||
READ32LE(((u32*)&map[(addr)>>24].address[(addr) & map[(addr)>>24].mask]))
|
||||
|
||||
u8 inline CPUReadByteQuick( u32 addr )
|
||||
{
|
||||
switch(addr >> 24 )
|
||||
{
|
||||
case 0x08:
|
||||
case 0x09:
|
||||
case 0x0A:
|
||||
case 0x0C:
|
||||
#ifdef USE_VM
|
||||
return VMRead8( addr & 0x1FFFFFF );
|
||||
#endif
|
||||
default:
|
||||
return CPUReadByteQuickDef(addr);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
u16 inline CPUReadHalfWordQuick( u32 addr )
|
||||
{
|
||||
switch(addr >> 24)
|
||||
{
|
||||
case 0x08:
|
||||
case 0x09:
|
||||
case 0x0A:
|
||||
case 0x0C:
|
||||
#ifdef USE_VM
|
||||
return VMRead16( addr & 0x1FFFFFF );
|
||||
#endif
|
||||
default:
|
||||
return CPUReadHalfWordQuickDef(addr);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
u32 inline CPUReadMemoryQuick( u32 addr )
|
||||
{
|
||||
switch(addr >> 24)
|
||||
{
|
||||
case 0x08:
|
||||
case 0x09:
|
||||
case 0x0A:
|
||||
case 0x0C:
|
||||
#ifdef USE_VM
|
||||
return VMRead32( addr & 0x1FFFFFF );
|
||||
#endif
|
||||
default:
|
||||
return CPUReadMemoryQuickDef(addr);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* End of VM override
|
||||
****************************************************************************/
|
||||
|
||||
static inline u32 CPUReadMemory(u32 address)
|
||||
{
|
||||
u32 value;
|
||||
@ -80,8 +146,8 @@ static inline u32 CPUReadMemory(u32 address)
|
||||
if((address < 0x4000400) && ioReadable[address & 0x3fc]) {
|
||||
if(ioReadable[(address & 0x3fc) + 2]) {
|
||||
value = READ32LE(((u32 *)&ioMem[address & 0x3fC]));
|
||||
if ((address & 0x3fc) == COMM_JOY_RECV_L)
|
||||
UPDATE_REG(COMM_JOYSTAT, READ16LE(&ioMem[COMM_JOYSTAT]) & ~JOYSTAT_RECV);
|
||||
//if ((address & 0x3fc) == COMM_JOY_RECV_L)
|
||||
// UPDATE_REG(COMM_JOYSTAT, READ16LE(&ioMem[COMM_JOYSTAT]) & ~JOYSTAT_RECV);
|
||||
} else {
|
||||
value = READ16LE(((u16 *)&ioMem[address & 0x3fc]));
|
||||
}
|
||||
@ -107,17 +173,36 @@ static inline u32 CPUReadMemory(u32 address)
|
||||
value = READ32LE(((u32 *)&oam[address & 0x3FC]));
|
||||
break;
|
||||
case 8:
|
||||
// Must be cartridge ROM, reading other sensors doesn't allow 32-bit access.
|
||||
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:
|
||||
value = eepromRead(address);
|
||||
break;
|
||||
case 14:
|
||||
case 15:
|
||||
// Yoshi's Universal Gravitation (Topsy Turvy)
|
||||
// Koro Koro
|
||||
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;
|
||||
}
|
||||
}
|
||||
value = flashRead(address) * 0x01010101;
|
||||
break;
|
||||
// default
|
||||
@ -129,14 +214,24 @@ unreadable:
|
||||
armNextPC - 4 : armNextPC - 2);
|
||||
}
|
||||
#endif
|
||||
|
||||
if(cpuDmaHack) {
|
||||
value = cpuDmaLast;
|
||||
} else {
|
||||
if(armState) {
|
||||
#ifdef USE_VM // Nintendo GC Virtual Memory
|
||||
return CPUReadMemoryQuick(reg[15].I);
|
||||
#else
|
||||
return CPUReadMemoryQuickDef(reg[15].I);
|
||||
#endif
|
||||
} else {
|
||||
#ifdef USE_VM // Nintendo GC Virtual Memory
|
||||
return CPUReadHalfWordQuick(reg[15].I) |
|
||||
CPUReadHalfWordQuick(reg[15].I) << 16;
|
||||
#else
|
||||
return CPUReadHalfWordQuickDef(reg[15].I) |
|
||||
CPUReadHalfWordQuickDef(reg[15].I) << 16;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
break;
|
||||
@ -250,20 +345,44 @@ static inline u32 CPUReadHalfWord(u32 address)
|
||||
value = READ16LE(((u16 *)&oam[address & 0x3fe]));
|
||||
break;
|
||||
case 8:
|
||||
// Use existing case statement and faster test for potential speed improvement
|
||||
// This is possibly the GPIO port that controls the real time clock,
|
||||
// WarioWare Twisted! tilt sensors, rumble, and solar sensors.
|
||||
if(address >= 0x80000c4 && address <= 0x80000c8) {
|
||||
// this function still works if there is no real time clock
|
||||
// and does a normal memory read in that case.
|
||||
value = rtcRead(address & 0xFFFFFFE);
|
||||
break;
|
||||
}
|
||||
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:
|
||||
value = eepromRead(address);
|
||||
break;
|
||||
case 14:
|
||||
case 15:
|
||||
// Yoshi's Universal Gravitation (Topsy Turvy)
|
||||
// Koro Koro
|
||||
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;
|
||||
}
|
||||
}
|
||||
value = flashRead(address) * 0x0101;
|
||||
break;
|
||||
// default
|
||||
@ -273,9 +392,17 @@ unreadable:
|
||||
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
|
||||
}
|
||||
}
|
||||
#ifdef GBA_LOGGING
|
||||
@ -350,16 +477,23 @@ static inline u8 CPUReadByte(u32 address)
|
||||
case 7:
|
||||
return oam[address & 0x3ff];
|
||||
case 8:
|
||||
// the real time clock doesn't support byte reads, so don't bother checking for it.
|
||||
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:
|
||||
return eepromRead(address);
|
||||
case 14:
|
||||
case 15:
|
||||
{
|
||||
// Yoshi's Universal Gravitation (Topsy Turvy)
|
||||
// Koro Koro
|
||||
if(cpuEEPROMSensorEnabled) {
|
||||
switch(address & 0x00008f00) {
|
||||
case 0x8200:
|
||||
@ -387,11 +521,20 @@ unreadable:
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
@ -443,6 +586,7 @@ static inline void CPUWriteMemory(u32 address, u32 value)
|
||||
value);
|
||||
else
|
||||
#endif
|
||||
if(address < 0x5000400 || (RomIdCode & 0xFFFFFF) != CORVETTE)
|
||||
WRITE32LE(((u32 *)&paletteRAM[address & 0x3FC]), value);
|
||||
break;
|
||||
case 0x06:
|
||||
@ -542,6 +686,7 @@ static inline void CPUWriteHalfWord(u32 address, u16 value)
|
||||
value);
|
||||
else
|
||||
#endif
|
||||
if(address < 0x5000400 || (RomIdCode & 0xFFFFFF) != CORVETTE)
|
||||
WRITE16LE(((u16 *)&paletteRAM[address & 0x3fe]), value);
|
||||
break;
|
||||
case 6:
|
||||
|
@ -1,3 +1,11 @@
|
||||
/*
|
||||
Mode 0 is the tiled graphics mode, with all the layers available.
|
||||
There is no rotation or scaling in this mode.
|
||||
It can be either 16 colours (with 16 different palettes) or 256 colors.
|
||||
There are 1024 tiles available.
|
||||
|
||||
These routines only render a single line at a time, because of the way the GBA does events.
|
||||
*/
|
||||
#include "GBA.h"
|
||||
#include "Globals.h"
|
||||
#include "GBAGfx.h"
|
||||
@ -7,9 +15,18 @@ void mode0RenderLine()
|
||||
u16 *palette = (u16 *)paletteRAM;
|
||||
|
||||
if(DISPCNT & 0x80) {
|
||||
for(int x = 0; x < 240; x++) {
|
||||
lineMix[x] = 0x7fff;
|
||||
}
|
||||
int x = 232; //240 - 8
|
||||
do{
|
||||
lineMix[x ] =
|
||||
lineMix[x+1] =
|
||||
lineMix[x+2] =
|
||||
lineMix[x+3] =
|
||||
lineMix[x+4] =
|
||||
lineMix[x+5] =
|
||||
lineMix[x+6] =
|
||||
lineMix[x+7] = 0x7fff;
|
||||
x-=8;
|
||||
}while(x>=0);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -38,10 +55,54 @@ void mode0RenderLine()
|
||||
backdrop = ((customBackdropColor & 0x7FFF) | 0x30000000);
|
||||
}
|
||||
|
||||
for(int x = 0; x < 240; x++) {
|
||||
for(u32 x = 0; x < 240u; ++x) {
|
||||
u32 color = backdrop;
|
||||
u8 top = 0x20;
|
||||
//--DCN
|
||||
//
|
||||
// !NON-PORTABLE!!NON-PORTABLE!
|
||||
//
|
||||
// This takes advantage of the fact that the Wii has far more registers
|
||||
// (32 vs 8) than IA-32 based processors processors (Intel, AMD).
|
||||
// This actually runs SLOWER on those. This code will only show
|
||||
// improvements on a PowerPC machine! (19.5% improvement: isolated tests)
|
||||
//*
|
||||
u8 li1 = (u8)(line1[x]>>24);
|
||||
u8 li2 = (u8)(line2[x]>>24);
|
||||
u8 li3 = (u8)(line3[x]>>24);
|
||||
u8 li4 = (u8)(lineOBJ[x]>>24);
|
||||
|
||||
u8 r = (li2 < li1) ? (li2) : (li1);
|
||||
|
||||
if(li3 < r) {
|
||||
r = (li4 < li3) ? (li4) : (li3);
|
||||
}else if(li4 < r){
|
||||
r = (li4);
|
||||
}
|
||||
|
||||
if(line0[x] < backdrop) {
|
||||
color = line0[x];
|
||||
top = 0x01;
|
||||
}
|
||||
|
||||
if(r < (u8)(color >> 24)) {
|
||||
if(r == li1){
|
||||
color = line1[x];
|
||||
top = 0x02;
|
||||
}else if(r == li2){
|
||||
color = line2[x];
|
||||
top = 0x04;
|
||||
}else if(r == li3){
|
||||
color = line3[x];
|
||||
top = 0x08;
|
||||
}else if(r == li4){
|
||||
color = lineOBJ[x];
|
||||
top = 0x10;
|
||||
}
|
||||
}
|
||||
|
||||
//Original
|
||||
/*
|
||||
if(line0[x] < color) {
|
||||
color = line0[x];
|
||||
top = 0x01;
|
||||
@ -56,41 +117,49 @@ void mode0RenderLine()
|
||||
color = line2[x];
|
||||
top = 0x04;
|
||||
}
|
||||
|
||||
if((u8)(line3[x]>>24) < (u8)(color >> 24)) {
|
||||
color = line3[x];
|
||||
top = 0x08;
|
||||
}
|
||||
|
||||
if((u8)(lineOBJ[x]>>24) < (u8)(color >> 24)) {
|
||||
color = lineOBJ[x];
|
||||
top = 0x10;
|
||||
}
|
||||
//*/
|
||||
|
||||
if((top & 0x10) && (color & 0x00010000)) {
|
||||
// semi-transparent OBJ
|
||||
u32 back = backdrop;
|
||||
u8 top2 = 0x20;
|
||||
|
||||
if((u8)(line0[x]>>24) < (u8)(back >> 24)) {
|
||||
u8 li0 = (u8)(line0[x]>>24);
|
||||
u8 li1 = (u8)(line1[x]>>24);
|
||||
u8 li2 = (u8)(line2[x]>>24);
|
||||
u8 li3 = (u8)(line3[x]>>24);
|
||||
|
||||
u8 r = (li1 < li0) ? (li1) : (li0);
|
||||
|
||||
if(li2 < r) {
|
||||
r = (li3 < li2) ? (li3) : (li2);
|
||||
}else if(li3 < r){
|
||||
r = (li3);
|
||||
}
|
||||
|
||||
if(r < (u8)(color >> 24)) {
|
||||
if(r == li0){
|
||||
back = line0[x];
|
||||
top2 = 0x01;
|
||||
}
|
||||
|
||||
if((u8)(line1[x]>>24) < (u8)(back >> 24)) {
|
||||
}else if(r == li1){
|
||||
back = line1[x];
|
||||
top2 = 0x02;
|
||||
}
|
||||
|
||||
if((u8)(line2[x]>>24) < (u8)(back >> 24)) {
|
||||
}else if(r == li2){
|
||||
back = line2[x];
|
||||
top2 = 0x04;
|
||||
}
|
||||
|
||||
if((u8)(line3[x]>>24) < (u8)(back >> 24)) {
|
||||
}else if(r == li3){
|
||||
back = line3[x];
|
||||
top2 = 0x08;
|
||||
}
|
||||
}
|
||||
|
||||
if(top2 & (BLDMOD>>8))
|
||||
color = gfxAlphaBlend(color, back,
|
||||
@ -119,9 +188,20 @@ void mode0RenderLineNoWindow()
|
||||
u16 *palette = (u16 *)paletteRAM;
|
||||
|
||||
if(DISPCNT & 0x80) {
|
||||
for(int x = 0; x < 240; x++) {
|
||||
lineMix[x] = 0x7fff;
|
||||
}
|
||||
|
||||
int x = 232; //240 - 8
|
||||
do{
|
||||
lineMix[x ] =
|
||||
lineMix[x+1] =
|
||||
lineMix[x+2] =
|
||||
lineMix[x+3] =
|
||||
lineMix[x+4] =
|
||||
lineMix[x+5] =
|
||||
lineMix[x+6] =
|
||||
lineMix[x+7] = 0x7fff;
|
||||
x-=8;
|
||||
}while(x>=0);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@ -156,30 +236,39 @@ void mode0RenderLineNoWindow()
|
||||
u32 color = backdrop;
|
||||
u8 top = 0x20;
|
||||
|
||||
if(line0[x] < color) {
|
||||
u8 li1 = (u8)(line1[x]>>24);
|
||||
u8 li2 = (u8)(line2[x]>>24);
|
||||
u8 li3 = (u8)(line3[x]>>24);
|
||||
u8 li4 = (u8)(lineOBJ[x]>>24);
|
||||
|
||||
u8 r = (li2 < li1) ? (li2) : (li1);
|
||||
|
||||
if(li3 < r) {
|
||||
r = (li4 < li3) ? (li4) : (li3);
|
||||
}else if(li4 < r){
|
||||
r = (li4);
|
||||
}
|
||||
|
||||
if(line0[x] < backdrop) {
|
||||
color = line0[x];
|
||||
top = 0x01;
|
||||
}
|
||||
|
||||
if(line1[x] < (color & 0xFF000000)) {
|
||||
if(r < (u8)(color >> 24)) {
|
||||
if(r == li1){
|
||||
color = line1[x];
|
||||
top = 0x02;
|
||||
}
|
||||
|
||||
if(line2[x] < (color & 0xFF000000)) {
|
||||
}else if(r == li2){
|
||||
color = line2[x];
|
||||
top = 0x04;
|
||||
}
|
||||
|
||||
if(line3[x] < (color & 0xFF000000)) {
|
||||
}else if(r == li3){
|
||||
color = line3[x];
|
||||
top = 0x08;
|
||||
}
|
||||
|
||||
if(lineOBJ[x] < (color & 0xFF000000)) {
|
||||
}else if(r == li4){
|
||||
color = lineOBJ[x];
|
||||
top = 0x10;
|
||||
}
|
||||
}
|
||||
|
||||
if(!(color & 0x00010000)) {
|
||||
switch(effect) {
|
||||
@ -190,40 +279,30 @@ void mode0RenderLineNoWindow()
|
||||
if(top & BLDMOD) {
|
||||
u32 back = backdrop;
|
||||
u8 top2 = 0x20;
|
||||
if(line0[x] < back) {
|
||||
if(top != 0x01) {
|
||||
|
||||
if((top != 0x01) && line0[x] < back) {
|
||||
back = line0[x];
|
||||
top2 = 0x01;
|
||||
}
|
||||
}
|
||||
|
||||
if(line1[x] < (back & 0xFF000000)) {
|
||||
if(top != 0x02) {
|
||||
if((top != 0x02) && line1[x] < (back & 0xFF000000)) {
|
||||
back = line1[x];
|
||||
top2 = 0x02;
|
||||
}
|
||||
}
|
||||
|
||||
if(line2[x] < (back & 0xFF000000)) {
|
||||
if(top != 0x04) {
|
||||
if((top != 0x04) && line2[x] < (back & 0xFF000000)) {
|
||||
back = line2[x];
|
||||
top2 = 0x04;
|
||||
}
|
||||
}
|
||||
|
||||
if(line3[x] < (back & 0xFF000000)) {
|
||||
if(top != 0x08) {
|
||||
if((top != 0x08) && line3[x] < (back & 0xFF000000)) {
|
||||
back = line3[x];
|
||||
top2 = 0x08;
|
||||
}
|
||||
}
|
||||
|
||||
if(lineOBJ[x] < (back & 0xFF000000)) {
|
||||
if(top != 0x10) {
|
||||
if((top != 0x10) && lineOBJ[x] < (back & 0xFF000000)) {
|
||||
back = lineOBJ[x];
|
||||
top2 = 0x10;
|
||||
}
|
||||
}
|
||||
|
||||
if(top2 & (BLDMOD>>8))
|
||||
color = gfxAlphaBlend(color, back,
|
||||
@ -247,25 +326,43 @@ void mode0RenderLineNoWindow()
|
||||
u32 back = backdrop;
|
||||
u8 top2 = 0x20;
|
||||
|
||||
if(line0[x] < back) {
|
||||
//--DCN
|
||||
// This is pretty much the exact same result:
|
||||
// line1[x] < (back & 0xFF000000)
|
||||
//
|
||||
// (u8)(line0[x]>>24) < (u8)(back >> 24)
|
||||
//
|
||||
// The only difference is that the first is stored in a u32,
|
||||
// and the second is stored in a u8
|
||||
//*
|
||||
u8 li0 = (u8)(line0[x]>>24);
|
||||
u8 li1 = (u8)(line1[x]>>24);
|
||||
u8 li2 = (u8)(line2[x]>>24);
|
||||
u8 li3 = (u8)(line3[x]>>24);
|
||||
|
||||
u8 r = (li1 < li0) ? (li1) : (li0);
|
||||
|
||||
if(li2 < r) {
|
||||
r = (li3 < li2) ? (li3) : (li2);
|
||||
}else if(li3 < r){
|
||||
r = (li3);
|
||||
}
|
||||
|
||||
if(r < (u8)(color >> 24)) {
|
||||
if(r == li0){
|
||||
back = line0[x];
|
||||
top2 = 0x01;
|
||||
}
|
||||
|
||||
if(line1[x] < (back & 0xFF000000)) {
|
||||
}else if(r == li1){
|
||||
back = line1[x];
|
||||
top2 = 0x02;
|
||||
}
|
||||
|
||||
if(line2[x] < (back & 0xFF000000)) {
|
||||
}else if(r == li2){
|
||||
back = line2[x];
|
||||
top2 = 0x04;
|
||||
}
|
||||
|
||||
if(line3[x] < (back & 0xFF000000)) {
|
||||
}else if(r == li3){
|
||||
back = line3[x];
|
||||
top2 = 0x08;
|
||||
}
|
||||
}
|
||||
|
||||
if(top2 & (BLDMOD>>8))
|
||||
color = gfxAlphaBlend(color, back,
|
||||
@ -294,9 +391,20 @@ void mode0RenderLineAll()
|
||||
u16 *palette = (u16 *)paletteRAM;
|
||||
|
||||
if(DISPCNT & 0x80) {
|
||||
for(int x = 0; x < 240; x++) {
|
||||
lineMix[x] = 0x7fff;
|
||||
}
|
||||
|
||||
int x = 232; //240 - 8
|
||||
do{
|
||||
lineMix[x ] =
|
||||
lineMix[x+1] =
|
||||
lineMix[x+2] =
|
||||
lineMix[x+3] =
|
||||
lineMix[x+4] =
|
||||
lineMix[x+5] =
|
||||
lineMix[x+6] =
|
||||
lineMix[x+7] = 0x7fff;
|
||||
x-=8;
|
||||
}while(x>=0);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@ -448,40 +556,31 @@ void mode0RenderLineAll()
|
||||
if(top & BLDMOD) {
|
||||
u32 back = backdrop;
|
||||
u8 top2 = 0x20;
|
||||
if((mask & 1) && (u8)(line0[x]>>24) < (u8)(back >> 24)) {
|
||||
if(top != 0x01) {
|
||||
|
||||
if((mask & 1) && (top != 0x01) && (u8)(line0[x]>>24) < (u8)(back >> 24)) {
|
||||
back = line0[x];
|
||||
top2 = 0x01;
|
||||
}
|
||||
}
|
||||
|
||||
if((mask & 2) && (u8)(line1[x]>>24) < (u8)(back >> 24)) {
|
||||
if(top != 0x02) {
|
||||
if((mask & 2) && (top != 0x02) && (u8)(line1[x]>>24) < (u8)(back >> 24)) {
|
||||
back = line1[x];
|
||||
top2 = 0x02;
|
||||
}
|
||||
}
|
||||
|
||||
if((mask & 4) && (u8)(line2[x]>>24) < (u8)(back >> 24)) {
|
||||
if(top != 0x04) {
|
||||
if((mask & 4) && (top != 0x04) && (u8)(line2[x]>>24) < (u8)(back >> 24)) {
|
||||
back = line2[x];
|
||||
top2 = 0x04;
|
||||
}
|
||||
}
|
||||
|
||||
if((mask & 8) && (u8)(line3[x]>>24) < (u8)(back >> 24)) {
|
||||
if(top != 0x08) {
|
||||
if((mask & 8) && (top != 0x08) && (u8)(line3[x]>>24) < (u8)(back >> 24)) {
|
||||
back = line3[x];
|
||||
top2 = 0x08;
|
||||
}
|
||||
}
|
||||
|
||||
if((mask & 16) && (u8)(lineOBJ[x]>>24) < (u8)(back >> 24)) {
|
||||
if(top != 0x10) {
|
||||
if((mask & 16) && (top != 0x10) && (u8)(lineOBJ[x]>>24) < (u8)(back >> 24)) {
|
||||
back = lineOBJ[x];
|
||||
top2 = 0x10;
|
||||
}
|
||||
}
|
||||
|
||||
if(top2 & (BLDMOD>>8))
|
||||
color = gfxAlphaBlend(color, back,
|
||||
|
@ -1,3 +1,12 @@
|
||||
/*
|
||||
Mode 1 is a tiled graphics mode, but with background layer 2 supporting scaling and rotation.
|
||||
There is no layer 3 in this mode.
|
||||
Layers 0 and 1 can be either 16 colours (with 16 different palettes) or 256 colours.
|
||||
There are 1024 tiles available.
|
||||
Layer 2 is 256 colours and allows only 256 tiles.
|
||||
|
||||
These routines only render a single line at a time, because of the way the GBA does events.
|
||||
*/
|
||||
#include "GBA.h"
|
||||
#include "Globals.h"
|
||||
#include "GBAGfx.h"
|
||||
@ -7,9 +16,20 @@ void mode1RenderLine()
|
||||
u16 *palette = (u16 *)paletteRAM;
|
||||
|
||||
if(DISPCNT & 0x80) {
|
||||
for(int x = 0; x < 240; x++) {
|
||||
lineMix[x] = 0x7fff;
|
||||
}
|
||||
|
||||
int x = 232; //240 - 8
|
||||
do{
|
||||
lineMix[x ] =
|
||||
lineMix[x+1] =
|
||||
lineMix[x+2] =
|
||||
lineMix[x+3] =
|
||||
lineMix[x+4] =
|
||||
lineMix[x+5] =
|
||||
lineMix[x+6] =
|
||||
lineMix[x+7] = 0x7fff;
|
||||
x-=8;
|
||||
}while(x>=0);
|
||||
|
||||
gfxLastVCOUNT = VCOUNT;
|
||||
return;
|
||||
}
|
||||
@ -40,49 +60,64 @@ void mode1RenderLine()
|
||||
backdrop = ((customBackdropColor & 0x7FFF) | 0x30000000);
|
||||
}
|
||||
|
||||
for(int x = 0; x < 240; x++) {
|
||||
for(u32 x = 0; x < 240u; ++x) {
|
||||
u32 color = backdrop;
|
||||
u8 top = 0x20;
|
||||
|
||||
if(line0[x] < color) {
|
||||
u8 li1 = (u8)(line1[x]>>24);
|
||||
u8 li2 = (u8)(line2[x]>>24);
|
||||
u8 li4 = (u8)(lineOBJ[x]>>24);
|
||||
|
||||
u8 r = (li2 < li1) ? (li2) : (li1);
|
||||
|
||||
if(li4 < r){
|
||||
r = (li4);
|
||||
}
|
||||
|
||||
if(line0[x] < backdrop) {
|
||||
color = line0[x];
|
||||
top = 0x01;
|
||||
}
|
||||
|
||||
if((u8)(line1[x]>>24) < (u8)(color >> 24)) {
|
||||
if(r < (u8)(color >> 24)) {
|
||||
if(r == li1){
|
||||
color = line1[x];
|
||||
top = 0x02;
|
||||
}
|
||||
|
||||
if((u8)(line2[x]>>24) < (u8)(color >> 24)) {
|
||||
}else if(r == li2){
|
||||
color = line2[x];
|
||||
top = 0x04;
|
||||
}
|
||||
|
||||
if((u8)(lineOBJ[x]>>24) < (u8)(color >> 24)) {
|
||||
}else if(r == li4){
|
||||
color = lineOBJ[x];
|
||||
top = 0x10;
|
||||
}
|
||||
}
|
||||
|
||||
if((top & 0x10) && (color & 0x00010000)) {
|
||||
// semi-transparent OBJ
|
||||
u32 back = backdrop;
|
||||
u8 top2 = 0x20;
|
||||
|
||||
if((u8)(line0[x]>>24) < (u8)(back >> 24)) {
|
||||
u8 li0 = (u8)(line0[x]>>24);
|
||||
u8 li1 = (u8)(line1[x]>>24);
|
||||
u8 li2 = (u8)(line2[x]>>24);
|
||||
u8 r = (li1 < li0) ? (li1) : (li0);
|
||||
|
||||
if(li2 < r) {
|
||||
r = (li2);
|
||||
}
|
||||
|
||||
if(r < (u8)(back >> 24)) {
|
||||
if(r == li0){
|
||||
back = line0[x];
|
||||
top2 = 0x01;
|
||||
}
|
||||
|
||||
if((u8)(line1[x]>>24) < (u8)(back >> 24)) {
|
||||
}else if(r == li1){
|
||||
back = line1[x];
|
||||
top2 = 0x02;
|
||||
}
|
||||
|
||||
if((u8)(line2[x]>>24) < (u8)(back >> 24)) {
|
||||
}else if(r == li2){
|
||||
back = line2[x];
|
||||
top2 = 0x04;
|
||||
}
|
||||
}
|
||||
|
||||
if(top2 & (BLDMOD>>8))
|
||||
color = gfxAlphaBlend(color, back,
|
||||
@ -113,9 +148,20 @@ void mode1RenderLineNoWindow()
|
||||
u16 *palette = (u16 *)paletteRAM;
|
||||
|
||||
if(DISPCNT & 0x80) {
|
||||
for(int x = 0; x < 240; x++) {
|
||||
lineMix[x] = 0x7fff;
|
||||
}
|
||||
|
||||
int x = 232; //240 - 8
|
||||
do{
|
||||
lineMix[x ] =
|
||||
lineMix[x+1] =
|
||||
lineMix[x+2] =
|
||||
lineMix[x+3] =
|
||||
lineMix[x+4] =
|
||||
lineMix[x+5] =
|
||||
lineMix[x+6] =
|
||||
lineMix[x+7] = 0x7fff;
|
||||
x-=8;
|
||||
}while(x>=0);
|
||||
|
||||
gfxLastVCOUNT = VCOUNT;
|
||||
return;
|
||||
}
|
||||
@ -147,29 +193,37 @@ void mode1RenderLineNoWindow()
|
||||
backdrop = ((customBackdropColor & 0x7FFF) | 0x30000000);
|
||||
}
|
||||
|
||||
for(int x = 0; x < 240; x++) {
|
||||
for(int x = 0; x < 240; ++x) {
|
||||
u32 color = backdrop;
|
||||
u8 top = 0x20;
|
||||
|
||||
if(line0[x] < color) {
|
||||
u8 li1 = (u8)(line1[x]>>24);
|
||||
u8 li2 = (u8)(line2[x]>>24);
|
||||
u8 li4 = (u8)(lineOBJ[x]>>24);
|
||||
|
||||
u8 r = (li2 < li1) ? (li2) : (li1);
|
||||
|
||||
if(li4 < r){
|
||||
r = (li4);
|
||||
}
|
||||
|
||||
if(line0[x] < backdrop) {
|
||||
color = line0[x];
|
||||
top = 0x01;
|
||||
}
|
||||
|
||||
if((u8)(line1[x]>>24) < (u8)(color >> 24)) {
|
||||
if(r < (u8)(color >> 24)) {
|
||||
if(r == li1){
|
||||
color = line1[x];
|
||||
top = 0x02;
|
||||
}
|
||||
|
||||
if((u8)(line2[x]>>24) < (u8)(color >> 24)) {
|
||||
}else if(r == li2){
|
||||
color = line2[x];
|
||||
top = 0x04;
|
||||
}
|
||||
|
||||
if((u8)(lineOBJ[x]>>24) < (u8)(color >> 24)) {
|
||||
}else if(r == li4){
|
||||
color = lineOBJ[x];
|
||||
top = 0x10;
|
||||
}
|
||||
}
|
||||
|
||||
if(!(color & 0x00010000)) {
|
||||
switch((BLDMOD >> 6) & 3) {
|
||||
@ -180,33 +234,26 @@ void mode1RenderLineNoWindow()
|
||||
if(top & BLDMOD) {
|
||||
u32 back = backdrop;
|
||||
u8 top2 = 0x20;
|
||||
if((u8)(line0[x]>>24) < (u8)(back >> 24)) {
|
||||
if(top != 0x01) {
|
||||
|
||||
if((top != 0x01) && (u8)(line0[x]>>24) < (u8)(back >> 24)) {
|
||||
back = line0[x];
|
||||
top2 = 0x01;
|
||||
}
|
||||
}
|
||||
|
||||
if((u8)(line1[x]>>24) < (u8)(back >> 24)) {
|
||||
if(top != 0x02) {
|
||||
if((top != 0x02) && (u8)(line1[x]>>24) < (u8)(back >> 24)) {
|
||||
back = line1[x];
|
||||
top2 = 0x02;
|
||||
}
|
||||
}
|
||||
|
||||
if((u8)(line2[x]>>24) < (u8)(back >> 24)) {
|
||||
if(top != 0x04) {
|
||||
if((top != 0x04) && (u8)(line2[x]>>24) < (u8)(back >> 24)) {
|
||||
back = line2[x];
|
||||
top2 = 0x04;
|
||||
}
|
||||
}
|
||||
|
||||
if((u8)(lineOBJ[x]>>24) < (u8)(back >> 24)) {
|
||||
if(top != 0x10) {
|
||||
if((top != 0x10) && (u8)(lineOBJ[x]>>24) < (u8)(back >> 24)) {
|
||||
back = lineOBJ[x];
|
||||
top2 = 0x10;
|
||||
}
|
||||
}
|
||||
|
||||
if(top2 & (BLDMOD>>8))
|
||||
color = gfxAlphaBlend(color, back,
|
||||
@ -229,20 +276,28 @@ void mode1RenderLineNoWindow()
|
||||
u32 back = backdrop;
|
||||
u8 top2 = 0x20;
|
||||
|
||||
if((u8)(line0[x]>>24) < (u8)(back >> 24)) {
|
||||
u8 li0 = (u8)(line0[x]>>24);
|
||||
u8 li1 = (u8)(line1[x]>>24);
|
||||
u8 li2 = (u8)(line2[x]>>24);
|
||||
|
||||
u8 r = (li1 < li0) ? (li1) : (li0);
|
||||
|
||||
if(li2 < r) {
|
||||
r = (li2);
|
||||
}
|
||||
|
||||
if(r < (u8)(back >> 24)) {
|
||||
if(r == li0){
|
||||
back = line0[x];
|
||||
top2 = 0x01;
|
||||
}
|
||||
|
||||
if((u8)(line1[x]>>24) < (u8)(back >> 24)) {
|
||||
}else if(r == li1){
|
||||
back = line1[x];
|
||||
top2 = 0x02;
|
||||
}
|
||||
|
||||
if((u8)(line2[x]>>24) < (u8)(back >> 24)) {
|
||||
}else if(r == li2){
|
||||
back = line2[x];
|
||||
top2 = 0x04;
|
||||
}
|
||||
}
|
||||
|
||||
if(top2 & (BLDMOD>>8))
|
||||
color = gfxAlphaBlend(color, back,
|
||||
@ -273,9 +328,20 @@ void mode1RenderLineAll()
|
||||
u16 *palette = (u16 *)paletteRAM;
|
||||
|
||||
if(DISPCNT & 0x80) {
|
||||
for(int x = 0; x < 240; x++) {
|
||||
lineMix[x] = 0x7fff;
|
||||
}
|
||||
|
||||
int x = 232; //240 - 8
|
||||
do{
|
||||
lineMix[x ] =
|
||||
lineMix[x+1] =
|
||||
lineMix[x+2] =
|
||||
lineMix[x+3] =
|
||||
lineMix[x+4] =
|
||||
lineMix[x+5] =
|
||||
lineMix[x+6] =
|
||||
lineMix[x+7] = 0x7fff;
|
||||
x-=8;
|
||||
}while(x>=0);
|
||||
|
||||
gfxLastVCOUNT = VCOUNT;
|
||||
return;
|
||||
}
|
||||
@ -333,7 +399,7 @@ void mode1RenderLineAll()
|
||||
u8 inWin1Mask = WININ >> 8;
|
||||
u8 outMask = WINOUT & 0xFF;
|
||||
|
||||
for(int x = 0; x < 240; x++) {
|
||||
for(int x = 0; x < 240; ++x) {
|
||||
u32 color = backdrop;
|
||||
u8 top = 0x20;
|
||||
u8 mask = outMask;
|
||||
@ -353,22 +419,23 @@ void mode1RenderLineAll()
|
||||
}
|
||||
}
|
||||
|
||||
if(line0[x] < color && (mask & 1)) {
|
||||
// At the very least, move the inexpensive 'mask' operation up front
|
||||
if((mask & 1) && line0[x] < backdrop) {
|
||||
color = line0[x];
|
||||
top = 0x01;
|
||||
}
|
||||
|
||||
if((u8)(line1[x]>>24) < (u8)(color >> 24) && (mask & 2)) {
|
||||
if((mask & 2) && (u8)(line1[x]>>24) < (u8)(color >> 24)) {
|
||||
color = line1[x];
|
||||
top = 0x02;
|
||||
}
|
||||
|
||||
if((u8)(line2[x]>>24) < (u8)(color >> 24) && (mask & 4)) {
|
||||
if((mask & 4) && (u8)(line2[x]>>24) < (u8)(color >> 24)) {
|
||||
color = line2[x];
|
||||
top = 0x04;
|
||||
}
|
||||
|
||||
if((u8)(lineOBJ[x]>>24) < (u8)(color >> 24) && (mask & 16)) {
|
||||
if((mask & 16) && (u8)(lineOBJ[x]>>24) < (u8)(color >> 24)) {
|
||||
color = lineOBJ[x];
|
||||
top = 0x10;
|
||||
}
|
||||
@ -378,7 +445,7 @@ void mode1RenderLineAll()
|
||||
u32 back = backdrop;
|
||||
u8 top2 = 0x20;
|
||||
|
||||
if((mask & 1) && (u8)(line0[x]>>24) < (u8)(back >> 24)) {
|
||||
if((mask & 1) && (u8)(line0[x]>>24) < (u8)(backdrop >> 24)) {
|
||||
back = line0[x];
|
||||
top2 = 0x01;
|
||||
}
|
||||
@ -420,33 +487,25 @@ void mode1RenderLineAll()
|
||||
u32 back = backdrop;
|
||||
u8 top2 = 0x20;
|
||||
|
||||
if((mask & 1) && (u8)(line0[x]>>24) < (u8)(back >> 24)) {
|
||||
if(top != 0x01) {
|
||||
if((mask & 1) && (top != 0x01) && (u8)(line0[x]>>24) < (u8)(backdrop >> 24)) {
|
||||
back = line0[x];
|
||||
top2 = 0x01;
|
||||
}
|
||||
}
|
||||
|
||||
if((mask & 2) && (u8)(line1[x]>>24) < (u8)(back >> 24)) {
|
||||
if(top != 0x02) {
|
||||
if((mask & 2) && (top != 0x02) && (u8)(line1[x]>>24) < (u8)(back >> 24)) {
|
||||
back = line1[x];
|
||||
top2 = 0x02;
|
||||
}
|
||||
}
|
||||
|
||||
if((mask & 4) && (u8)(line2[x]>>24) < (u8)(back >> 24)) {
|
||||
if(top != 0x04) {
|
||||
if((mask & 4) && (top != 0x04) && (u8)(line2[x]>>24) < (u8)(back >> 24)) {
|
||||
back = line2[x];
|
||||
top2 = 0x04;
|
||||
}
|
||||
}
|
||||
|
||||
if((mask & 16) && (u8)(lineOBJ[x]>>24) < (u8)(back >> 24)) {
|
||||
if(top != 0x10) {
|
||||
if((mask & 16) && (top != 0x10) && (u8)(lineOBJ[x]>>24) < (u8)(back >> 24)) {
|
||||
back = lineOBJ[x];
|
||||
top2 = 0x10;
|
||||
}
|
||||
}
|
||||
|
||||
if(top2 & (BLDMOD>>8))
|
||||
color = gfxAlphaBlend(color, back,
|
||||
|
@ -1,3 +1,11 @@
|
||||
/*
|
||||
Mode 2 is a 256 colour tiled graphics mode which supports scaling and rotation.
|
||||
There is no background layer 0 or 1 in this mode. Only background layers 2 and 3.
|
||||
There are 256 tiles available.
|
||||
It does not support flipping.
|
||||
|
||||
These routines only render a single line at a time, because of the way the GBA does events.
|
||||
*/
|
||||
#include "GBA.h"
|
||||
#include "Globals.h"
|
||||
#include "GBAGfx.h"
|
||||
@ -7,9 +15,20 @@ void mode2RenderLine()
|
||||
u16 *palette = (u16 *)paletteRAM;
|
||||
|
||||
if(DISPCNT & 0x80) {
|
||||
for(int x = 0; x < 240; x++) {
|
||||
lineMix[x] = 0x7fff;
|
||||
}
|
||||
|
||||
int x = 232; //240 - 8
|
||||
do{
|
||||
lineMix[x ] =
|
||||
lineMix[x+1] =
|
||||
lineMix[x+2] =
|
||||
lineMix[x+3] =
|
||||
lineMix[x+4] =
|
||||
lineMix[x+5] =
|
||||
lineMix[x+6] =
|
||||
lineMix[x+7] = 0x7fff;
|
||||
x-=8;
|
||||
}while(x>=0);
|
||||
|
||||
gfxLastVCOUNT = VCOUNT;
|
||||
return;
|
||||
}
|
||||
@ -43,40 +62,51 @@ void mode2RenderLine()
|
||||
backdrop = ((customBackdropColor & 0x7FFF) | 0x30000000);
|
||||
}
|
||||
|
||||
for(int x = 0; x < 240; x++) {
|
||||
for(int x = 0; x < 240; ++x) {
|
||||
u32 color = backdrop;
|
||||
u8 top = 0x20;
|
||||
|
||||
u8 li2 = (u8)(line2[x]>>24);
|
||||
u8 li3 = (u8)(line3[x]>>24);
|
||||
u8 li4 = (u8)(lineOBJ[x]>>24);
|
||||
|
||||
if((u8)(line2[x]>>24) < (u8)(color >> 24)) {
|
||||
u8 r = (li3 < li2) ? (li3) : (li2);
|
||||
|
||||
if(li4 < r){
|
||||
r = (li4);
|
||||
}
|
||||
|
||||
if(r < (u8)(color >> 24)) {
|
||||
if(r == li2){
|
||||
color = line2[x];
|
||||
top = 0x04;
|
||||
}
|
||||
|
||||
if((u8)(line3[x]>>24) < (u8)(color >> 24)) {
|
||||
}else if(r == li3){
|
||||
color = line3[x];
|
||||
top = 0x08;
|
||||
}
|
||||
|
||||
if((u8)(lineOBJ[x]>>24) < (u8)(color >> 24)) {
|
||||
}else if(r == li4){
|
||||
color = lineOBJ[x];
|
||||
top = 0x10;
|
||||
}
|
||||
}
|
||||
|
||||
if((top & 0x10) && (color & 0x00010000)) {
|
||||
// semi-transparent OBJ
|
||||
u32 back = backdrop;
|
||||
u8 top2 = 0x20;
|
||||
|
||||
if((u8)(line2[x]>>24) < (u8)(back >> 24)) {
|
||||
u8 li2 = (u8)(line2[x]>>24);
|
||||
u8 li3 = (u8)(line3[x]>>24);
|
||||
u8 r = (li3 < li2) ? (li3) : (li2);
|
||||
|
||||
if(r < (u8)(back >> 24)) {
|
||||
if(r == li2){
|
||||
back = line2[x];
|
||||
top2 = 0x04;
|
||||
}
|
||||
|
||||
if((u8)(line3[x]>>24) < (u8)(back >> 24)) {
|
||||
}else if(r == li3){
|
||||
back = line3[x];
|
||||
top2 = 0x08;
|
||||
}
|
||||
}
|
||||
|
||||
if(top2 & (BLDMOD>>8))
|
||||
color = gfxAlphaBlend(color, back,
|
||||
@ -108,9 +138,20 @@ void mode2RenderLineNoWindow()
|
||||
u16 *palette = (u16 *)paletteRAM;
|
||||
|
||||
if(DISPCNT & 0x80) {
|
||||
for(int x = 0; x < 240; x++) {
|
||||
lineMix[x] = 0x7fff;
|
||||
}
|
||||
|
||||
int x = 232; //240 - 8
|
||||
do{
|
||||
lineMix[x ] =
|
||||
lineMix[x+1] =
|
||||
lineMix[x+2] =
|
||||
lineMix[x+3] =
|
||||
lineMix[x+4] =
|
||||
lineMix[x+5] =
|
||||
lineMix[x+6] =
|
||||
lineMix[x+7] = 0x7fff;
|
||||
x-=8;
|
||||
}while(x>=0);
|
||||
|
||||
gfxLastVCOUNT = VCOUNT;
|
||||
return;
|
||||
}
|
||||
@ -144,25 +185,32 @@ void mode2RenderLineNoWindow()
|
||||
backdrop = ((customBackdropColor & 0x7FFF) | 0x30000000);
|
||||
}
|
||||
|
||||
for(int x = 0; x < 240; x++) {
|
||||
for(int x = 0; x < 240; ++x) {
|
||||
u32 color = backdrop;
|
||||
u8 top = 0x20;
|
||||
|
||||
u8 li2 = (u8)(line2[x]>>24);
|
||||
u8 li3 = (u8)(line3[x]>>24);
|
||||
u8 li4 = (u8)(lineOBJ[x]>>24);
|
||||
|
||||
if((u8)(line2[x]>>24) < (u8)(color >> 24)) {
|
||||
u8 r = (li3 < li2) ? (li3) : (li2);
|
||||
|
||||
if(li4 < r){
|
||||
r = (li4);
|
||||
}
|
||||
|
||||
if(r < (u8)(color >> 24)) {
|
||||
if(r == li2){
|
||||
color = line2[x];
|
||||
top = 0x04;
|
||||
}
|
||||
|
||||
if((u8)(line3[x]>>24) < (u8)(color >> 24)) {
|
||||
}else if(r == li3){
|
||||
color = line3[x];
|
||||
top = 0x08;
|
||||
}
|
||||
|
||||
if((u8)(lineOBJ[x]>>24) < (u8)(color >> 24)) {
|
||||
}else if(r == li4){
|
||||
color = lineOBJ[x];
|
||||
top = 0x10;
|
||||
}
|
||||
}
|
||||
|
||||
if(!(color & 0x00010000)) {
|
||||
switch((BLDMOD >> 6) & 3) {
|
||||
@ -174,26 +222,20 @@ void mode2RenderLineNoWindow()
|
||||
u32 back = backdrop;
|
||||
u8 top2 = 0x20;
|
||||
|
||||
if((u8)(line2[x]>>24) < (u8)(back >> 24)) {
|
||||
if(top != 0x04) {
|
||||
if((top != 0x04) && (u8)(line2[x]>>24) < (u8)(back >> 24)) {
|
||||
back = line2[x];
|
||||
top2 = 0x04;
|
||||
}
|
||||
}
|
||||
|
||||
if((u8)(line3[x]>>24) < (u8)(back >> 24)) {
|
||||
if(top != 0x08) {
|
||||
if((top != 0x08) && (u8)(line3[x]>>24) < (u8)(back >> 24)) {
|
||||
back = line3[x];
|
||||
top2 = 0x08;
|
||||
}
|
||||
}
|
||||
|
||||
if((u8)(lineOBJ[x]>>24) < (u8)(back >> 24)) {
|
||||
if(top != 0x10) {
|
||||
if((top != 0x10) && (u8)(lineOBJ[x]>>24) < (u8)(back >> 24)) {
|
||||
back = lineOBJ[x];
|
||||
top2 = 0x10;
|
||||
}
|
||||
}
|
||||
|
||||
if(top2 & (BLDMOD>>8))
|
||||
color = gfxAlphaBlend(color, back,
|
||||
@ -216,15 +258,19 @@ void mode2RenderLineNoWindow()
|
||||
u32 back = backdrop;
|
||||
u8 top2 = 0x20;
|
||||
|
||||
if((u8)(line2[x]>>24) < (u8)(back >> 24)) {
|
||||
u8 li2 = (u8)(line2[x]>>24);
|
||||
u8 li3 = (u8)(line3[x]>>24);
|
||||
u8 r = (li3 < li2) ? (li3) : (li2);
|
||||
|
||||
if(r < (u8)(back >> 24)) {
|
||||
if(r == li2){
|
||||
back = line2[x];
|
||||
top2 = 0x04;
|
||||
}
|
||||
|
||||
if((u8)(line3[x]>>24) < (u8)(back >> 24)) {
|
||||
}else if(r == li3){
|
||||
back = line3[x];
|
||||
top2 = 0x08;
|
||||
}
|
||||
}
|
||||
|
||||
if(top2 & (BLDMOD>>8))
|
||||
color = gfxAlphaBlend(color, back,
|
||||
@ -256,9 +302,20 @@ void mode2RenderLineAll()
|
||||
u16 *palette = (u16 *)paletteRAM;
|
||||
|
||||
if(DISPCNT & 0x80) {
|
||||
for(int x = 0; x < 240; x++) {
|
||||
lineMix[x] = 0x7fff;
|
||||
}
|
||||
|
||||
int x = 232; //240 - 8
|
||||
do{
|
||||
lineMix[x ] =
|
||||
lineMix[x+1] =
|
||||
lineMix[x+2] =
|
||||
lineMix[x+3] =
|
||||
lineMix[x+4] =
|
||||
lineMix[x+5] =
|
||||
lineMix[x+6] =
|
||||
lineMix[x+7] = 0x7fff;
|
||||
x-=8;
|
||||
}while(x>=0);
|
||||
|
||||
gfxLastVCOUNT = VCOUNT;
|
||||
return;
|
||||
}
|
||||
@ -339,17 +396,17 @@ void mode2RenderLineAll()
|
||||
}
|
||||
}
|
||||
|
||||
if(line2[x] < color && (mask & 4)) {
|
||||
if((mask & 4) && line2[x] < color) {
|
||||
color = line2[x];
|
||||
top = 0x04;
|
||||
}
|
||||
|
||||
if((u8)(line3[x]>>24) < (u8)(color >> 24) && (mask & 8)) {
|
||||
if((mask & 8) && (u8)(line3[x]>>24) < (u8)(color >> 24)) {
|
||||
color = line3[x];
|
||||
top = 0x08;
|
||||
}
|
||||
|
||||
if((u8)(lineOBJ[x]>>24) < (u8)(color >> 24) && (mask & 16)) {
|
||||
if((mask & 16) && (u8)(lineOBJ[x]>>24) < (u8)(color >> 24)) {
|
||||
color = lineOBJ[x];
|
||||
top = 0x10;
|
||||
}
|
||||
@ -396,26 +453,20 @@ void mode2RenderLineAll()
|
||||
u32 back = backdrop;
|
||||
u8 top2 = 0x20;
|
||||
|
||||
if((mask & 4) && line2[x] < back) {
|
||||
if(top != 0x04) {
|
||||
if((mask & 4) && (top != 0x04) && line2[x] < back) {
|
||||
back = line2[x];
|
||||
top2 = 0x04;
|
||||
}
|
||||
}
|
||||
|
||||
if((mask & 8) && (u8)(line3[x]>>24) < (u8)(back >> 24)) {
|
||||
if(top != 0x08) {
|
||||
if((mask & 8) && (top != 0x08) && (u8)(line3[x]>>24) < (u8)(back >> 24)) {
|
||||
back = line3[x];
|
||||
top2 = 0x08;
|
||||
}
|
||||
}
|
||||
|
||||
if((mask & 16) && (u8)(lineOBJ[x]>>24) < (u8)(back >> 24)) {
|
||||
if(top != 0x10) {
|
||||
if((mask & 16) && (top != 0x10) && (u8)(lineOBJ[x]>>24) < (u8)(back >> 24)) {
|
||||
back = lineOBJ[x];
|
||||
top2 = 0x10;
|
||||
}
|
||||
}
|
||||
|
||||
if(top2 & (BLDMOD>>8))
|
||||
color = gfxAlphaBlend(color, back,
|
||||
|
@ -1,3 +1,10 @@
|
||||
/*
|
||||
Mode 3 is a 15-bit (32768) colour bitmap graphics mode.
|
||||
It has a single layer, background layer 2, the same size as the screen.
|
||||
It doesn't support paging, scrolling, flipping, rotation or tiles.
|
||||
|
||||
These routines only render a single line at a time, because of the way the GBA does events.
|
||||
*/
|
||||
#include "GBA.h"
|
||||
#include "Globals.h"
|
||||
#include "GBAGfx.h"
|
||||
@ -7,9 +14,20 @@ void mode3RenderLine()
|
||||
u16 *palette = (u16 *)paletteRAM;
|
||||
|
||||
if(DISPCNT & 0x80) {
|
||||
for(int x = 0; x < 240; x++) {
|
||||
lineMix[x] = 0x7fff;
|
||||
}
|
||||
|
||||
int x = 232; //240 - 8
|
||||
do{
|
||||
lineMix[x ] =
|
||||
lineMix[x+1] =
|
||||
lineMix[x+2] =
|
||||
lineMix[x+3] =
|
||||
lineMix[x+4] =
|
||||
lineMix[x+5] =
|
||||
lineMix[x+6] =
|
||||
lineMix[x+7] = 0x7fff;
|
||||
x-=8;
|
||||
}while(x>=0);
|
||||
|
||||
gfxLastVCOUNT = VCOUNT;
|
||||
return;
|
||||
}
|
||||
@ -36,7 +54,7 @@ void mode3RenderLine()
|
||||
background = ((customBackdropColor & 0x7FFF) | 0x30000000);
|
||||
}
|
||||
|
||||
for(int x = 0; x < 240; x++) {
|
||||
for(int x = 0; x < 240; ++x) {
|
||||
u32 color = background;
|
||||
u8 top = 0x20;
|
||||
|
||||
@ -55,7 +73,7 @@ void mode3RenderLine()
|
||||
u32 back = background;
|
||||
u8 top2 = 0x20;
|
||||
|
||||
if(line2[x] < back) {
|
||||
if(line2[x] < background) {
|
||||
back = line2[x];
|
||||
top2 = 0x04;
|
||||
}
|
||||
@ -89,9 +107,20 @@ void mode3RenderLineNoWindow()
|
||||
u16 *palette = (u16 *)paletteRAM;
|
||||
|
||||
if(DISPCNT & 0x80) {
|
||||
for(int x = 0; x < 240; x++) {
|
||||
lineMix[x] = 0x7fff;
|
||||
}
|
||||
|
||||
int x = 232; //240 - 8
|
||||
do{
|
||||
lineMix[x ] =
|
||||
lineMix[x+1] =
|
||||
lineMix[x+2] =
|
||||
lineMix[x+3] =
|
||||
lineMix[x+4] =
|
||||
lineMix[x+5] =
|
||||
lineMix[x+6] =
|
||||
lineMix[x+7] = 0x7fff;
|
||||
x-=8;
|
||||
}while(x>=0);
|
||||
|
||||
gfxLastVCOUNT = VCOUNT;
|
||||
return;
|
||||
}
|
||||
@ -118,11 +147,11 @@ void mode3RenderLineNoWindow()
|
||||
background = ((customBackdropColor & 0x7FFF) | 0x30000000);
|
||||
}
|
||||
|
||||
for(int x = 0; x < 240; x++) {
|
||||
for(int x = 0; x < 240; ++x) {
|
||||
u32 color = background;
|
||||
u8 top = 0x20;
|
||||
|
||||
if(line2[x] < color) {
|
||||
if(line2[x] < background) {
|
||||
color = line2[x];
|
||||
top = 0x04;
|
||||
}
|
||||
@ -142,19 +171,15 @@ void mode3RenderLineNoWindow()
|
||||
u32 back = background;
|
||||
u8 top2 = 0x20;
|
||||
|
||||
if(line2[x] < back) {
|
||||
if(top != 0x04) {
|
||||
if(top != 0x04 && (line2[x] < background) ) {
|
||||
back = line2[x];
|
||||
top2 = 0x04;
|
||||
}
|
||||
}
|
||||
|
||||
if((u8)(lineOBJ[x]>>24) < (u8)(back >> 24)) {
|
||||
if(top != 0x10) {
|
||||
if(top != 0x10 && ((u8)(lineOBJ[x]>>24) < (u8)(back >> 24))) {
|
||||
back = lineOBJ[x];
|
||||
top2 = 0x10;
|
||||
}
|
||||
}
|
||||
|
||||
if(top2 & (BLDMOD>>8))
|
||||
color = gfxAlphaBlend(color, back,
|
||||
@ -178,7 +203,7 @@ void mode3RenderLineNoWindow()
|
||||
u32 back = background;
|
||||
u8 top2 = 0x20;
|
||||
|
||||
if(line2[x] < back) {
|
||||
if(line2[x] < background) {
|
||||
back = line2[x];
|
||||
top2 = 0x04;
|
||||
}
|
||||
@ -212,9 +237,20 @@ void mode3RenderLineAll()
|
||||
u16 *palette = (u16 *)paletteRAM;
|
||||
|
||||
if(DISPCNT & 0x80) {
|
||||
for(int x = 0; x < 240; x++) {
|
||||
lineMix[x] = 0x7fff;
|
||||
}
|
||||
|
||||
int x = 232; //240 - 8
|
||||
do{
|
||||
lineMix[x ] =
|
||||
lineMix[x+1] =
|
||||
lineMix[x+2] =
|
||||
lineMix[x+3] =
|
||||
lineMix[x+4] =
|
||||
lineMix[x+5] =
|
||||
lineMix[x+6] =
|
||||
lineMix[x+7] = 0x7fff;
|
||||
x-=8;
|
||||
}while(x>=0);
|
||||
|
||||
gfxLastVCOUNT = VCOUNT;
|
||||
return;
|
||||
}
|
||||
@ -268,7 +304,7 @@ void mode3RenderLineAll()
|
||||
background = ((customBackdropColor & 0x7FFF) | 0x30000000);
|
||||
}
|
||||
|
||||
for(int x = 0; x < 240; x++) {
|
||||
for(int x = 0; x < 240; ++x) {
|
||||
u32 color = background;
|
||||
u8 top = 0x20;
|
||||
u8 mask = outMask;
|
||||
@ -288,7 +324,7 @@ void mode3RenderLineAll()
|
||||
}
|
||||
}
|
||||
|
||||
if((mask & 4) && (line2[x] < color)) {
|
||||
if((mask & 4) && line2[x] < background) {
|
||||
color = line2[x];
|
||||
top = 0x04;
|
||||
}
|
||||
@ -303,7 +339,7 @@ void mode3RenderLineAll()
|
||||
u32 back = background;
|
||||
u8 top2 = 0x20;
|
||||
|
||||
if((mask & 4) && line2[x] < back) {
|
||||
if((mask & 4) && line2[x] < background) {
|
||||
back = line2[x];
|
||||
top2 = 0x04;
|
||||
}
|
||||
@ -334,25 +370,20 @@ void mode3RenderLineAll()
|
||||
u32 back = background;
|
||||
u8 top2 = 0x20;
|
||||
|
||||
if((mask & 4) && line2[x] < back) {
|
||||
if(top != 0x04) {
|
||||
if((mask & 4) && (top != 0x04) && line2[x] < back) {
|
||||
back = line2[x];
|
||||
top2 = 0x04;
|
||||
}
|
||||
}
|
||||
|
||||
if((mask & 16) && (u8)(lineOBJ[x]>>24) < (u8)(back >> 24)) {
|
||||
if(top != 0x10) {
|
||||
if((mask & 16) && (top != 0x10) && (u8)(lineOBJ[x]>>24) < (u8)(back >> 24)) {
|
||||
back = lineOBJ[x];
|
||||
top2 = 0x10;
|
||||
}
|
||||
}
|
||||
|
||||
if(top2 & (BLDMOD>>8))
|
||||
color = gfxAlphaBlend(color, back,
|
||||
coeff[COLEV & 0x1F],
|
||||
coeff[(COLEV >> 8) & 0x1F]);
|
||||
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -1,3 +1,10 @@
|
||||
/*
|
||||
Mode 4 is a 256 colour bitmap graphics mode with 2 swappable pages.
|
||||
It has a single layer, background layer 2, the same size as the screen.
|
||||
It doesn't support scrolling, flipping, rotation or tiles.
|
||||
|
||||
These routines only render a single line at a time, because of the way the GBA does events.
|
||||
*/
|
||||
#include "GBA.h"
|
||||
#include "GBAGfx.h"
|
||||
#include "Globals.h"
|
||||
@ -7,9 +14,20 @@ void mode4RenderLine()
|
||||
u16 *palette = (u16 *)paletteRAM;
|
||||
|
||||
if(DISPCNT & 0x0080) {
|
||||
for(int x = 0; x < 240; x++) {
|
||||
lineMix[x] = 0x7fff;
|
||||
}
|
||||
|
||||
int x = 232; //240 - 8
|
||||
do{
|
||||
lineMix[x ] =
|
||||
lineMix[x+1] =
|
||||
lineMix[x+2] =
|
||||
lineMix[x+3] =
|
||||
lineMix[x+4] =
|
||||
lineMix[x+5] =
|
||||
lineMix[x+6] =
|
||||
lineMix[x+7] = 0x7fff;
|
||||
x-=8;
|
||||
}while(x>=0);
|
||||
|
||||
gfxLastVCOUNT = VCOUNT;
|
||||
return;
|
||||
}
|
||||
@ -35,11 +53,11 @@ void mode4RenderLine()
|
||||
backdrop = ((customBackdropColor & 0x7FFF) | 0x30000000);
|
||||
}
|
||||
|
||||
for(int x = 0; x < 240; x++) {
|
||||
for(int x = 0; x < 240; ++x) {
|
||||
u32 color = backdrop;
|
||||
u8 top = 0x20;
|
||||
|
||||
if(line2[x] < color) {
|
||||
if(line2[x] < backdrop) {
|
||||
color = line2[x];
|
||||
top = 0x04;
|
||||
}
|
||||
@ -54,7 +72,7 @@ void mode4RenderLine()
|
||||
u32 back = backdrop;
|
||||
u8 top2 = 0x20;
|
||||
|
||||
if(line2[x] < back) {
|
||||
if(line2[x] < backdrop) {
|
||||
back = line2[x];
|
||||
top2 = 0x04;
|
||||
}
|
||||
@ -88,9 +106,20 @@ void mode4RenderLineNoWindow()
|
||||
u16 *palette = (u16 *)paletteRAM;
|
||||
|
||||
if(DISPCNT & 0x0080) {
|
||||
for(int x = 0; x < 240; x++) {
|
||||
lineMix[x] = 0x7fff;
|
||||
}
|
||||
|
||||
int x = 232; //240 - 8
|
||||
do{
|
||||
lineMix[x ] =
|
||||
lineMix[x+1] =
|
||||
lineMix[x+2] =
|
||||
lineMix[x+3] =
|
||||
lineMix[x+4] =
|
||||
lineMix[x+5] =
|
||||
lineMix[x+6] =
|
||||
lineMix[x+7] = 0x7fff;
|
||||
x-=8;
|
||||
}while(x>=0);
|
||||
|
||||
gfxLastVCOUNT = VCOUNT;
|
||||
return;
|
||||
}
|
||||
@ -116,11 +145,11 @@ void mode4RenderLineNoWindow()
|
||||
backdrop = ((customBackdropColor & 0x7FFF) | 0x30000000);
|
||||
}
|
||||
|
||||
for(int x = 0; x < 240; x++) {
|
||||
for(int x = 0; x < 240; ++x) {
|
||||
u32 color = backdrop;
|
||||
u8 top = 0x20;
|
||||
|
||||
if(line2[x] < color) {
|
||||
if(line2[x] < backdrop) {
|
||||
color = line2[x];
|
||||
top = 0x04;
|
||||
}
|
||||
@ -140,19 +169,15 @@ void mode4RenderLineNoWindow()
|
||||
u32 back = backdrop;
|
||||
u8 top2 = 0x20;
|
||||
|
||||
if(line2[x] < back) {
|
||||
if(top != 0x04) {
|
||||
if((top != 0x04) && line2[x] < backdrop) {
|
||||
back = line2[x];
|
||||
top2 = 0x04;
|
||||
}
|
||||
}
|
||||
|
||||
if((u8)(lineOBJ[x]>>24) < (u8)(back >> 24)) {
|
||||
if(top != 0x10) {
|
||||
if((top != 0x10) && (u8)(lineOBJ[x]>>24) < (u8)(back >> 24)) {
|
||||
back = lineOBJ[x];
|
||||
top2 = 0x10;
|
||||
}
|
||||
}
|
||||
|
||||
if(top2 & (BLDMOD>>8))
|
||||
color = gfxAlphaBlend(color, back,
|
||||
@ -210,9 +235,20 @@ void mode4RenderLineAll()
|
||||
u16 *palette = (u16 *)paletteRAM;
|
||||
|
||||
if(DISPCNT & 0x0080) {
|
||||
for(int x = 0; x < 240; x++) {
|
||||
lineMix[x] = 0x7fff;
|
||||
}
|
||||
|
||||
int x = 232; //240 - 8
|
||||
do{
|
||||
lineMix[x ] =
|
||||
lineMix[x+1] =
|
||||
lineMix[x+2] =
|
||||
lineMix[x+3] =
|
||||
lineMix[x+4] =
|
||||
lineMix[x+5] =
|
||||
lineMix[x+6] =
|
||||
lineMix[x+7] = 0x7fff;
|
||||
x-=8;
|
||||
}while(x>=0);
|
||||
|
||||
gfxLastVCOUNT = VCOUNT;
|
||||
return;
|
||||
}
|
||||
@ -265,7 +301,7 @@ void mode4RenderLineAll()
|
||||
u8 inWin1Mask = WININ >> 8;
|
||||
u8 outMask = WINOUT & 0xFF;
|
||||
|
||||
for(int x = 0; x < 240; x++) {
|
||||
for(int x = 0; x < 240; ++x) {
|
||||
u32 color = backdrop;
|
||||
u8 top = 0x20;
|
||||
u8 mask = outMask;
|
||||
@ -285,7 +321,7 @@ void mode4RenderLineAll()
|
||||
}
|
||||
}
|
||||
|
||||
if((mask & 4) && (line2[x] < color)) {
|
||||
if((mask & 4) && (line2[x] < backdrop)) {
|
||||
color = line2[x];
|
||||
top = 0x04;
|
||||
}
|
||||
@ -331,25 +367,20 @@ void mode4RenderLineAll()
|
||||
u32 back = backdrop;
|
||||
u8 top2 = 0x20;
|
||||
|
||||
if((mask & 4) && line2[x] < back) {
|
||||
if(top != 0x04) {
|
||||
if((mask & 4) && (top != 0x04) && (line2[x] < backdrop)) {
|
||||
back = line2[x];
|
||||
top2 = 0x04;
|
||||
}
|
||||
}
|
||||
|
||||
if((mask & 16) && (u8)(lineOBJ[x]>>24) < (u8)(back >> 24)) {
|
||||
if(top != 0x10) {
|
||||
if((mask & 16) && (top != 0x10) && (u8)(lineOBJ[x]>>24) < (u8)(back >> 24)) {
|
||||
back = lineOBJ[x];
|
||||
top2 = 0x10;
|
||||
}
|
||||
}
|
||||
|
||||
if(top2 & (BLDMOD>>8))
|
||||
color = gfxAlphaBlend(color, back,
|
||||
coeff[COLEV & 0x1F],
|
||||
coeff[(COLEV >> 8) & 0x1F]);
|
||||
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -1,3 +1,11 @@
|
||||
/*
|
||||
Mode 5 is a low resolution (160x128) 15-bit colour bitmap graphics mode
|
||||
with 2 swappable pages!
|
||||
It has a single layer, background layer 2, lower resolution than the screen.
|
||||
It doesn't support scrolling, flipping, rotation or tiles.
|
||||
|
||||
These routines only render a single line at a time, because of the way the GBA does events.
|
||||
*/
|
||||
#include "GBA.h"
|
||||
#include "Globals.h"
|
||||
#include "GBAGfx.h"
|
||||
@ -5,9 +13,20 @@
|
||||
void mode5RenderLine()
|
||||
{
|
||||
if(DISPCNT & 0x0080) {
|
||||
for(int x = 0; x < 240; x++) {
|
||||
lineMix[x] = 0x7fff;
|
||||
}
|
||||
|
||||
int x = 232; //240 - 8
|
||||
do{
|
||||
lineMix[x ] =
|
||||
lineMix[x+1] =
|
||||
lineMix[x+2] =
|
||||
lineMix[x+3] =
|
||||
lineMix[x+4] =
|
||||
lineMix[x+5] =
|
||||
lineMix[x+6] =
|
||||
lineMix[x+7] = 0x7fff;
|
||||
x-=8;
|
||||
}while(x>=0);
|
||||
|
||||
gfxLastVCOUNT = VCOUNT;
|
||||
return;
|
||||
}
|
||||
@ -36,11 +55,11 @@ void mode5RenderLine()
|
||||
background = ((customBackdropColor & 0x7FFF) | 0x30000000);
|
||||
}
|
||||
|
||||
for(int x = 0; x < 240; x++) {
|
||||
for(int x = 0; x < 240; ++x) {
|
||||
u32 color = background;
|
||||
u8 top = 0x20;
|
||||
|
||||
if(line2[x] < color) {
|
||||
if(line2[x] < background) {
|
||||
color = line2[x];
|
||||
top = 0x04;
|
||||
}
|
||||
@ -87,9 +106,20 @@ void mode5RenderLine()
|
||||
void mode5RenderLineNoWindow()
|
||||
{
|
||||
if(DISPCNT & 0x0080) {
|
||||
for(int x = 0; x < 240; x++) {
|
||||
lineMix[x] = 0x7fff;
|
||||
}
|
||||
|
||||
int x = 232; //240 - 8
|
||||
do{
|
||||
lineMix[x ] =
|
||||
lineMix[x+1] =
|
||||
lineMix[x+2] =
|
||||
lineMix[x+3] =
|
||||
lineMix[x+4] =
|
||||
lineMix[x+5] =
|
||||
lineMix[x+6] =
|
||||
lineMix[x+7] = 0x7fff;
|
||||
x-=8;
|
||||
}while(x>=0);
|
||||
|
||||
gfxLastVCOUNT = VCOUNT;
|
||||
return;
|
||||
}
|
||||
@ -118,11 +148,11 @@ void mode5RenderLineNoWindow()
|
||||
background = ((customBackdropColor & 0x7FFF) | 0x30000000);
|
||||
}
|
||||
|
||||
for(int x = 0; x < 240; x++) {
|
||||
for(int x = 0; x < 240; ++x) {
|
||||
u32 color = background;
|
||||
u8 top = 0x20;
|
||||
|
||||
if(line2[x] < color) {
|
||||
if(line2[x] < background) {
|
||||
color = line2[x];
|
||||
top = 0x04;
|
||||
}
|
||||
@ -142,19 +172,15 @@ void mode5RenderLineNoWindow()
|
||||
u32 back = background;
|
||||
u8 top2 = 0x20;
|
||||
|
||||
if(line2[x] < back) {
|
||||
if(top != 0x04) {
|
||||
if((top != 0x04) && line2[x] < background) {
|
||||
back = line2[x];
|
||||
top2 = 0x04;
|
||||
}
|
||||
}
|
||||
|
||||
if((u8)(lineOBJ[x]>>24) < (u8)(back >> 24)) {
|
||||
if(top != 0x10) {
|
||||
if((top != 0x10) && (u8)(lineOBJ[x]>>24) < (u8)(back >> 24)) {
|
||||
back = lineOBJ[x];
|
||||
top2 = 0x10;
|
||||
}
|
||||
}
|
||||
|
||||
if(top2 & (BLDMOD>>8))
|
||||
color = gfxAlphaBlend(color, back,
|
||||
@ -210,9 +236,19 @@ void mode5RenderLineNoWindow()
|
||||
void mode5RenderLineAll()
|
||||
{
|
||||
if(DISPCNT & 0x0080) {
|
||||
for(int x = 0; x < 240; x++) {
|
||||
lineMix[x] = 0x7fff;
|
||||
}
|
||||
|
||||
int x = 232; //240 - 8
|
||||
do{
|
||||
lineMix[x ] =
|
||||
lineMix[x+1] =
|
||||
lineMix[x+2] =
|
||||
lineMix[x+3] =
|
||||
lineMix[x+4] =
|
||||
lineMix[x+5] =
|
||||
lineMix[x+6] =
|
||||
lineMix[x+7] = 0x7fff;
|
||||
x-=8;
|
||||
}while(x>=0);
|
||||
gfxLastVCOUNT = VCOUNT;
|
||||
return;
|
||||
}
|
||||
@ -268,7 +304,7 @@ void mode5RenderLineAll()
|
||||
background = ((customBackdropColor & 0x7FFF) | 0x30000000);
|
||||
}
|
||||
|
||||
for(int x = 0; x < 240; x++) {
|
||||
for(int x = 0; x < 240; ++x) {
|
||||
u32 color = background;
|
||||
u8 top = 0x20;
|
||||
u8 mask = outMask;
|
||||
@ -288,7 +324,7 @@ void mode5RenderLineAll()
|
||||
}
|
||||
}
|
||||
|
||||
if((mask & 4) && (line2[x] < color)) {
|
||||
if((mask & 4) && (line2[x] < background)) {
|
||||
color = line2[x];
|
||||
top = 0x04;
|
||||
}
|
||||
@ -334,19 +370,15 @@ void mode5RenderLineAll()
|
||||
u32 back = background;
|
||||
u8 top2 = 0x20;
|
||||
|
||||
if((mask & 4) && line2[x] < back) {
|
||||
if(top != 0x04) {
|
||||
if((mask & 4) && (top != 0x04) && (line2[x] < background)) {
|
||||
back = line2[x];
|
||||
top2 = 0x04;
|
||||
}
|
||||
}
|
||||
|
||||
if((mask & 16) && (u8)(lineOBJ[x]>>24) < (u8)(back >> 24)) {
|
||||
if(top != 0x10) {
|
||||
if((mask & 16) && (top != 0x10) && (u8)(lineOBJ[x]>>24) < (u8)(back >> 24)) {
|
||||
back = lineOBJ[x];
|
||||
top2 = 0x10;
|
||||
}
|
||||
}
|
||||
|
||||
if(top2 & (BLDMOD>>8))
|
||||
color = gfxAlphaBlend(color, back,
|
||||
|
@ -9,9 +9,6 @@
|
||||
#include <time.h>
|
||||
#include <string.h>
|
||||
|
||||
// Defined in VGA-GX input.cpp
|
||||
void systemCartridgeRumble(bool);
|
||||
|
||||
enum RTCSTATE
|
||||
{
|
||||
IDLE = 0,
|
||||
|
@ -50,8 +50,8 @@ int soundTicks = SOUND_CLOCK_TICKS_;
|
||||
|
||||
static float soundVolume = 1.0f;
|
||||
static int soundEnableFlag = 0x3ff; // emulator channels enabled
|
||||
static float soundFiltering_ = -1;
|
||||
static float soundVolume_ = -1;
|
||||
static float soundFiltering_ = -1.0f;
|
||||
static float soundVolume_ = -1.0f;
|
||||
|
||||
void interp_rate() { /* empty for now */ }
|
||||
|
||||
@ -82,8 +82,8 @@ public:
|
||||
int readIndex;
|
||||
int count;
|
||||
int writeIndex;
|
||||
u8 fifo [32];
|
||||
int dac;
|
||||
u8 fifo [32];
|
||||
private:
|
||||
|
||||
int timer;
|
||||
@ -115,7 +115,7 @@ void Gba_Pcm::apply_control( int idx )
|
||||
|
||||
int ch = 0;
|
||||
if ( (soundEnableFlag >> idx & 0x100) && (ioMem [NR52] & 0x80) )
|
||||
ch = ioMem [SGCNT0_H+1] >> (idx * 4) & 3;
|
||||
ch = ioMem [SGCNT0_H+1] >> (idx <<2) & 3;
|
||||
|
||||
Blip_Buffer* out = 0;
|
||||
switch ( ch )
|
||||
@ -162,11 +162,10 @@ void Gba_Pcm::update( int dac )
|
||||
int filter = 0;
|
||||
if ( soundInterpolation )
|
||||
{
|
||||
// base filtering on how long since last sample was output
|
||||
int period = time - last_time;
|
||||
unsigned period = unsigned(time - last_time);
|
||||
unsigned idx = period >> 9;
|
||||
|
||||
int idx = (unsigned) period / 512;
|
||||
if ( idx >= 3 )
|
||||
if ( idx > 3 )
|
||||
idx = 3;
|
||||
|
||||
static int const filters [4] = { 0, 0, 1, 2 };
|
||||
@ -204,7 +203,7 @@ void Gba_Pcm_Fifo::timer_overflowed( int which_timer )
|
||||
}
|
||||
|
||||
// Read next sample from FIFO
|
||||
count--;
|
||||
--count;
|
||||
dac = fifo [readIndex];
|
||||
readIndex = (readIndex + 1) & 31;
|
||||
pcm.update( dac );
|
||||
@ -284,14 +283,17 @@ static void apply_volume( bool apu_only = false )
|
||||
|
||||
if ( gb_apu )
|
||||
{
|
||||
static float const apu_vols [4] = { 0.25, 0.5, 1, 0.25 };
|
||||
static float const apu_vols [4] = { 0.25f, 0.5f, 1.0f, 0.25f };
|
||||
gb_apu->volume( soundVolume_ * apu_vols [ioMem [SGCNT0_H] & 3] );
|
||||
}
|
||||
|
||||
if ( !apu_only )
|
||||
{
|
||||
for ( int i = 0; i < 3; i++ )
|
||||
pcm_synth [i].volume( 0.66 / 256 * soundVolume_ );
|
||||
double tmpVol = 0.002578125 * soundVolume_; // 0.66 / 256 * soundVolume_
|
||||
|
||||
pcm_synth[0].volume( tmpVol );
|
||||
pcm_synth[1].volume( tmpVol );
|
||||
pcm_synth[2].volume( tmpVol );
|
||||
}
|
||||
}
|
||||
|
||||
@ -352,19 +354,14 @@ static void end_frame( blip_time_t time )
|
||||
|
||||
void flush_samples(Multi_Buffer * buffer)
|
||||
{
|
||||
#ifdef __LIBRETRO__
|
||||
int numSamples = buffer->read_samples( (blip_sample_t*) soundFinalWave, buffer->samples_avail() );
|
||||
soundDriver->write(soundFinalWave, numSamples);
|
||||
systemOnWriteDataToSoundBuffer(soundFinalWave, numSamples);
|
||||
#else
|
||||
// We want to write the data frame by frame to support legacy audio drivers
|
||||
// that don't use the length parameter of the write method.
|
||||
// TODO: Update the Win32 audio drivers (DS, OAL, XA2), and flush all the
|
||||
// samples at once to help reducing the audio delay on all platforms.
|
||||
int soundBufferLen = ( soundSampleRate / 60 ) * 4;
|
||||
int soundBufferLen = ( soundSampleRate / 60 ) << 2;
|
||||
|
||||
// soundBufferLen should have a whole number of sample pairs
|
||||
assert( soundBufferLen % (2 * sizeof *soundFinalWave) == 0 );
|
||||
assert( soundBufferLen % ((sizeof *soundFinalWave)<<1) == 0 );
|
||||
|
||||
// number of samples in output buffer
|
||||
int const out_buf_size = soundBufferLen / sizeof *soundFinalWave;
|
||||
@ -379,15 +376,16 @@ void flush_samples(Multi_Buffer * buffer)
|
||||
soundDriver->write(soundFinalWave, soundBufferLen);
|
||||
systemOnWriteDataToSoundBuffer(soundFinalWave, soundBufferLen);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static void apply_filtering()
|
||||
{
|
||||
soundFiltering_ = soundFiltering;
|
||||
|
||||
int const base_freq = (int) (32768 - soundFiltering_ * 16384);
|
||||
int const nyquist = stereo_buffer->sample_rate() / 2;
|
||||
// Yes, I changed soundFiltering_ to soundFiltering, the reason is
|
||||
// to eliminate a write-read dependency
|
||||
int const base_freq = 32768 - (int) (soundFiltering * 16384.0f);
|
||||
int const nyquist = stereo_buffer->sample_rate() >> 1;
|
||||
|
||||
for ( int i = 0; i < 3; i++ )
|
||||
{
|
||||
@ -456,13 +454,6 @@ static void remake_stereo_buffer()
|
||||
pcm [0].pcm.init();
|
||||
pcm [1].pcm.init();
|
||||
|
||||
// APU
|
||||
if ( !gb_apu )
|
||||
{
|
||||
gb_apu = new Gb_Apu; // TODO: handle out of memory
|
||||
reset_apu();
|
||||
}
|
||||
|
||||
// Stereo_Buffer
|
||||
delete stereo_buffer;
|
||||
stereo_buffer = 0;
|
||||
@ -476,7 +467,13 @@ static void remake_stereo_buffer()
|
||||
pcm [1].which = 1;
|
||||
apply_filtering();
|
||||
|
||||
// Volume Level
|
||||
// APU
|
||||
if ( !gb_apu )
|
||||
{
|
||||
gb_apu = new Gb_Apu; // TODO: handle out of memory
|
||||
reset_apu();
|
||||
}
|
||||
|
||||
apply_muting();
|
||||
apply_volume();
|
||||
}
|
||||
@ -595,8 +592,8 @@ static struct {
|
||||
gb_apu_state_t apu;
|
||||
|
||||
// old state
|
||||
u8 soundDSAValue;
|
||||
int soundDSBValue;
|
||||
u8 soundDSAValue;
|
||||
} state;
|
||||
|
||||
// Old GBA sound state format
|
||||
@ -754,25 +751,16 @@ static void skip_read( gzFile in, int count )
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef __LIBRETRO__
|
||||
void soundSaveGame( u8 *&out )
|
||||
#else
|
||||
void soundSaveGame( gzFile out )
|
||||
#endif
|
||||
{
|
||||
gb_apu->save_state( &state.apu );
|
||||
|
||||
// Be sure areas for expansion get written as zero
|
||||
memset( dummy_state, 0, sizeof dummy_state );
|
||||
|
||||
#ifdef __LIBRETRO__
|
||||
utilWriteDataMem( out, gba_state );
|
||||
#else
|
||||
utilWriteData( out, gba_state );
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifndef __LIBRETRO__
|
||||
static void soundReadGameOld( gzFile in, int version )
|
||||
{
|
||||
// Read main data
|
||||
@ -807,28 +795,19 @@ static void soundReadGameOld( gzFile in, int version )
|
||||
|
||||
(void) utilReadInt( in ); // ignore quality
|
||||
}
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#ifdef __LIBRETRO__
|
||||
void soundReadGame(const u8*& in, int version )
|
||||
#else
|
||||
void soundReadGame( gzFile in, int version )
|
||||
#endif
|
||||
{
|
||||
// Prepare APU and default state
|
||||
reset_apu();
|
||||
gb_apu->save_state( &state.apu );
|
||||
|
||||
if ( version > SAVE_GAME_VERSION_9 )
|
||||
#ifdef __LIBRETRO__
|
||||
utilReadDataMem( in, gba_state );
|
||||
#else
|
||||
utilReadData( in, gba_state );
|
||||
else
|
||||
soundReadGameOld( in, version );
|
||||
#endif
|
||||
|
||||
gb_apu->load_state( state.apu );
|
||||
write_SGCNT0_H( READ16LE( &ioMem [SGCNT0_H] ) & 0x770F );
|
||||
|
@ -1,227 +0,0 @@
|
||||
#include "gbafilter.h"
|
||||
|
||||
#include <math.h>
|
||||
|
||||
extern int systemColorDepth;
|
||||
extern int systemRedShift;
|
||||
extern int systemGreenShift;
|
||||
extern int systemBlueShift;
|
||||
|
||||
extern u16 systemColorMap16[0x10000];
|
||||
extern u32 systemColorMap32[0x10000];
|
||||
|
||||
static const unsigned char curve[32] = { 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0e, 0x10, 0x12,
|
||||
0x14, 0x16, 0x18, 0x1c, 0x20, 0x28, 0x30, 0x38,
|
||||
0x40, 0x48, 0x50, 0x58, 0x60, 0x68, 0x70, 0x80,
|
||||
0x88, 0x90, 0xa0, 0xb0, 0xc0, 0xd0, 0xe0, 0xf0};
|
||||
|
||||
// output R G B
|
||||
static const unsigned char influence[3 * 3] = { 16, 4, 4, // red
|
||||
8, 16, 8, // green
|
||||
0, 8, 16};// blue
|
||||
|
||||
inline void swap(short & a, short & b)
|
||||
{
|
||||
short temp = a;
|
||||
a = b;
|
||||
b = temp;
|
||||
}
|
||||
|
||||
void gbafilter_pal(u16 * buf, int count)
|
||||
{
|
||||
short temp[3 * 3], s;
|
||||
unsigned pix;
|
||||
u8 red, green, blue;
|
||||
|
||||
while (count--)
|
||||
{
|
||||
pix = *buf;
|
||||
|
||||
s = curve[(pix >> systemGreenShift) & 0x1f];
|
||||
temp[3] = s * influence[3];
|
||||
temp[4] = s * influence[4];
|
||||
temp[5] = s * influence[5];
|
||||
|
||||
s = curve[(pix >> systemRedShift) & 0x1f];
|
||||
temp[0] = s * influence[0];
|
||||
temp[1] = s * influence[1];
|
||||
temp[2] = s * influence[2];
|
||||
|
||||
s = curve[(pix >> systemBlueShift) & 0x1f];
|
||||
temp[6] = s * influence[6];
|
||||
temp[7] = s * influence[7];
|
||||
temp[8] = s * influence[8];
|
||||
|
||||
if (temp[0] < temp[3]) swap(temp[0], temp[3]);
|
||||
if (temp[0] < temp[6]) swap(temp[0], temp[6]);
|
||||
if (temp[3] < temp[6]) swap(temp[3], temp[6]);
|
||||
temp[3] <<= 1;
|
||||
temp[0] <<= 2;
|
||||
temp[0] += temp[3] + temp[6];
|
||||
|
||||
red = ((int(temp[0]) * 160) >> 17) + 4;
|
||||
if (red > 31) red = 31;
|
||||
|
||||
if (temp[2] < temp[5]) swap(temp[2], temp[5]);
|
||||
if (temp[2] < temp[8]) swap(temp[2], temp[8]);
|
||||
if (temp[5] < temp[8]) swap(temp[5], temp[8]);
|
||||
temp[5] <<= 1;
|
||||
temp[2] <<= 2;
|
||||
temp[2] += temp[5] + temp[8];
|
||||
|
||||
blue = ((int(temp[2]) * 160) >> 17) + 4;
|
||||
if (blue > 31) blue = 31;
|
||||
|
||||
if (temp[1] < temp[4]) swap(temp[1], temp[4]);
|
||||
if (temp[1] < temp[7]) swap(temp[1], temp[7]);
|
||||
if (temp[4] < temp[7]) swap(temp[4], temp[7]);
|
||||
temp[4] <<= 1;
|
||||
temp[1] <<= 2;
|
||||
temp[1] += temp[4] + temp[7];
|
||||
|
||||
green = ((int(temp[1]) * 160) >> 17) + 4;
|
||||
if (green > 31) green = 31;
|
||||
|
||||
pix = red << systemRedShift;
|
||||
pix += green << systemGreenShift;
|
||||
pix += blue << systemBlueShift;
|
||||
|
||||
*buf++ = pix;
|
||||
}
|
||||
}
|
||||
|
||||
void gbafilter_pal32(u32 * buf, int count)
|
||||
{
|
||||
short temp[3 * 3], s;
|
||||
unsigned pix;
|
||||
u8 red, green, blue;
|
||||
|
||||
while (count--)
|
||||
{
|
||||
pix = *buf;
|
||||
|
||||
s = curve[(pix >> systemGreenShift) & 0x1f];
|
||||
temp[3] = s * influence[3];
|
||||
temp[4] = s * influence[4];
|
||||
temp[5] = s * influence[5];
|
||||
|
||||
s = curve[(pix >> systemRedShift) & 0x1f];
|
||||
temp[0] = s * influence[0];
|
||||
temp[1] = s * influence[1];
|
||||
temp[2] = s * influence[2];
|
||||
|
||||
s = curve[(pix >> systemBlueShift) & 0x1f];
|
||||
temp[6] = s * influence[6];
|
||||
temp[7] = s * influence[7];
|
||||
temp[8] = s * influence[8];
|
||||
|
||||
if (temp[0] < temp[3]) swap(temp[0], temp[3]);
|
||||
if (temp[0] < temp[6]) swap(temp[0], temp[6]);
|
||||
if (temp[3] < temp[6]) swap(temp[3], temp[6]);
|
||||
temp[3] <<= 1;
|
||||
temp[0] <<= 2;
|
||||
temp[0] += temp[3] + temp[6];
|
||||
|
||||
//red = ((int(temp[0]) * 160) >> 17) + 4;
|
||||
red = ((int(temp[0]) * 160) >> 14) + 32;
|
||||
|
||||
if (temp[2] < temp[5]) swap(temp[2], temp[5]);
|
||||
if (temp[2] < temp[8]) swap(temp[2], temp[8]);
|
||||
if (temp[5] < temp[8]) swap(temp[5], temp[8]);
|
||||
temp[5] <<= 1;
|
||||
temp[2] <<= 2;
|
||||
temp[2] += temp[5] + temp[8];
|
||||
|
||||
//blue = ((int(temp[2]) * 160) >> 17) + 4;
|
||||
blue = ((int(temp[2]) * 160) >> 14) + 32;
|
||||
|
||||
if (temp[1] < temp[4]) swap(temp[1], temp[4]);
|
||||
if (temp[1] < temp[7]) swap(temp[1], temp[7]);
|
||||
if (temp[4] < temp[7]) swap(temp[4], temp[7]);
|
||||
temp[4] <<= 1;
|
||||
temp[1] <<= 2;
|
||||
temp[1] += temp[4] + temp[7];
|
||||
|
||||
//green = ((int(temp[1]) * 160) >> 17) + 4;
|
||||
green = ((int(temp[1]) * 160) >> 14) + 32;
|
||||
|
||||
//pix = red << redshift;
|
||||
//pix += green << greenshift;
|
||||
//pix += blue << blueshift;
|
||||
|
||||
pix = red << (systemRedShift - 3);
|
||||
pix += green << (systemGreenShift - 3);
|
||||
pix += blue << (systemBlueShift - 3);
|
||||
|
||||
*buf++ = pix;
|
||||
}
|
||||
}
|
||||
|
||||
// for palette mode to work with the three spoony filters in 32bpp depth
|
||||
|
||||
void gbafilter_pad(u8 * buf, int count)
|
||||
{
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
u8 r;
|
||||
u8 g;
|
||||
u8 b;
|
||||
u8 a;
|
||||
} part;
|
||||
unsigned whole;
|
||||
}
|
||||
mask;
|
||||
|
||||
mask.whole = 0x1f << systemRedShift;
|
||||
mask.whole += 0x1f << systemGreenShift;
|
||||
mask.whole += 0x1f << systemBlueShift;
|
||||
|
||||
switch (systemColorDepth)
|
||||
{
|
||||
case 24:
|
||||
while (count--)
|
||||
{
|
||||
*buf++ &= mask.part.r;
|
||||
*buf++ &= mask.part.g;
|
||||
*buf++ &= mask.part.b;
|
||||
}
|
||||
break;
|
||||
case 32:
|
||||
while (count--)
|
||||
{
|
||||
*((u32*)buf) &= mask.whole;
|
||||
buf += 4;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
void UpdateSystemColorMaps(int lcd)
|
||||
{
|
||||
switch(systemColorDepth) {
|
||||
case 16:
|
||||
{
|
||||
for(int i = 0; i < 0x10000; i++) {
|
||||
systemColorMap16[i] = ((i & 0x1f) << systemRedShift) |
|
||||
(((i & 0x3e0) >> 5) << systemGreenShift) |
|
||||
(((i & 0x7c00) >> 10) << systemBlueShift);
|
||||
}
|
||||
if (lcd == 1) gbafilter_pal(systemColorMap16, 0x10000);
|
||||
}
|
||||
break;
|
||||
case 24:
|
||||
case 32:
|
||||
{
|
||||
for(int i = 0; i < 0x10000; i++) {
|
||||
systemColorMap32[i] = ((i & 0x1f) << systemRedShift) |
|
||||
(((i & 0x3e0) >> 5) << systemGreenShift) |
|
||||
(((i & 0x7c00) >> 10) << systemBlueShift);
|
||||
}
|
||||
if (lcd == 1) gbafilter_pal32(systemColorMap32, 0x10000);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
*/
|
@ -1,5 +0,0 @@
|
||||
#include "../System.h"
|
||||
|
||||
void gbafilter_pal(u16 * buf, int count);
|
||||
void gbafilter_pal32(u32 * buf, int count);
|
||||
void gbafilter_pad(u8 * buf, int count);
|
@ -77,7 +77,7 @@ int systemGreenShift = 0;
|
||||
int systemColorDepth = 0;
|
||||
u16 systemGbPalette[24];
|
||||
u16 systemColorMap16[0x10000];
|
||||
u32 systemColorMap32[0x10000];
|
||||
u32 *systemColorMap32 = NULL;
|
||||
|
||||
void gbSetPalette(u32 RRGGBB[]);
|
||||
bool StartColorizing();
|
||||
|
Loading…
Reference in New Issue
Block a user