gba: implement mode 3, mode 5 backdrops. slightly todo, as i don't know how mosaic + affine works on hardware

This commit is contained in:
goyuken 2012-11-25 01:34:58 +00:00
parent afdc3dd670
commit 206adff851
4 changed files with 53 additions and 4 deletions

View File

@ -46,6 +46,9 @@ namespace AMeteor
void DrawLine4 (uint8_t line, uint16_t* ptr,
int32_t curX, int32_t curY,
int16_t dx, int16_t dmx, int16_t dy, int16_t dmy, bool frame1);
void DrawLine5 (uint16_t* ptr,
int32_t refX, int32_t refY,
int16_t dx, int16_t dy, bool frame1);
void FillList ();
void UpdateCnt (uint16_t cnt);

View File

@ -308,7 +308,7 @@ namespace AMeteor
{
int32_t intX, intY;
uint8_t* pChar = m_memory.GetRealAddress(0x06000000);
uint16_t* pChar = (uint16_t*) m_memory.GetRealAddress(0x06000000);
for (uint8_t x = 0; x < 240; ++x, ++ptr, curX += dx, curY += dy)
{
@ -317,6 +317,7 @@ namespace AMeteor
// if we are off layer
if (intX < 0 || intX >= 240)
/*
if (m_cnt & (0x1 << 13))
{
// NOTE : in C++, the modulus can be negative
@ -324,19 +325,20 @@ namespace AMeteor
if (intX < 0)
intX += 240;
}
else
else*/
continue;
if (intY < 0 || intY >= 160)
/*
if (m_cnt & (0x1 << 13))
{
intY %= 160;
if (intY < 0)
intY += 160;
}
else
else*/
continue;
*ptr = pChar[intY * 240 * 2 + intX * 2] | 0x8000;
*ptr = pChar[intY * 240 + intX] | 0x8000;
}
}
@ -412,6 +414,29 @@ namespace AMeteor
}
}
void BgLayer::DrawLine5 (uint16_t* ptr,
int32_t curX, int32_t curY,
int16_t dx, int16_t dy, bool frame1)
{
int32_t intX, intY;
uint16_t* pChar = (uint16_t*) m_memory.GetRealAddress(frame1 ? 0x0600A000 : 0x06000000);
for (uint8_t x = 0; x < 240; ++x, ++ptr, curX += dx, curY += dy)
{
intX = curX >> 8;
intY = curY >> 8;
// if we are off layer
if (intX < 0 || intX >= 160)
continue;
if (intY < 0 || intY >= 128)
continue;
*ptr = pChar[intY * 160 + intX] | 0x8000;
}
}
void BgLayer::UpdateCnt (uint16_t cnt)
{
if (m_cnt == cnt)

View File

@ -121,6 +121,16 @@ namespace AMeteor
// if objects are enabled draw them
if (layersOn & (0x1 << 4)) m_objs.DrawLine(line, lineObj);
break;
case 3: // bg2 only 15 bit direct color 240x160
layersOn &= 0xF4;
if (layersOn & (0x1 << 2))
m_bgLayer2.DrawLine3(lineBg+2*WIDTH,
m_refX2, m_refY2,
m_io.DRead16(Io::BG2PA),
m_io.DRead16(Io::BG2PC));
if (layersOn & (0x1 << 4))
m_objs.DrawLineHighOnly(line, lineObj);
break;
// TODO (remember, HIGH ONLY for objs, don't make shitty copy paste)
case 4: // bg2 only in mode 4 (bitmap 256)
layersOn &= 0xF4;
@ -141,6 +151,17 @@ namespace AMeteor
// all objs with the current priority
m_objs.DrawLineHighOnly(line, lineObj);
break;
case 5: // bg2 only 15 bit direct color 160x128 2 frames
layersOn &= 0xF4;
if (layersOn & (0x1 << 2))
m_bgLayer2.DrawLine5(lineBg+2*WIDTH,
m_refX2, m_refY2,
m_io.DRead16(Io::BG2PA),
m_io.DRead16(Io::BG2PC),
m_dispcnt & (0x1 << 4));
if (layersOn & (0x1 << 4))
m_objs.DrawLineHighOnly(line, lineObj);
break;
default :
met_abort("not supported : " << (m_dispcnt & 0x7));
break;