summaryrefslogtreecommitdiffstatshomepage
path: root/src/mess/video/gbamode1.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/mess/video/gbamode1.c')
-rw-r--r--src/mess/video/gbamode1.c525
1 files changed, 525 insertions, 0 deletions
diff --git a/src/mess/video/gbamode1.c b/src/mess/video/gbamode1.c
new file mode 100644
index 00000000000..1aa4db4afb3
--- /dev/null
+++ b/src/mess/video/gbamode1.c
@@ -0,0 +1,525 @@
+ /***************************************************************************
+
+ gbamode1.c
+
+ Handles GBA mode 1 screen rendering
+
+ By R. Belmont & Harmony
+
+***************************************************************************/
+
+static void draw_mode1_scanline(running_machine &machine, gba_state *state, int y, UINT32* line0, UINT32* line1, UINT32* line2, UINT32* line3, UINT32* lineOBJ, UINT32* lineOBJWin, UINT32* lineMix, int bpp)
+{
+ int x = 0;
+ UINT32 backdrop = ((UINT16*)state->m_gba_pram.target())[0] | 0x30000000;
+
+ draw_bg_scanline(state, line0, y, DISPCNT_BG0_EN, state->m_BG0CNT, state->m_BG0HOFS, state->m_BG0VOFS);
+ draw_bg_scanline(state, line1, y, DISPCNT_BG1_EN, state->m_BG1CNT, state->m_BG1HOFS, state->m_BG1VOFS);
+ draw_roz_scanline(state, line2, y, DISPCNT_BG2_EN, state->m_BG2CNT, state->m_BG2X, state->m_BG2Y, state->m_BG2PA, state->m_BG2PB, state->m_BG2PC, state->m_BG2PD, &state->m_gfxBG2X, &state->m_gfxBG2Y, state->m_gfxBG2Changed);
+ draw_gba_oam(state, machine, lineOBJ, y);
+
+ for(x = 0; x < 240; x++)
+ {
+ UINT32 color = backdrop;
+ UINT8 top = 0x20;
+
+ if(line0[x] < color)
+ {
+ color = line0[x];
+ top = 0x01;
+ }
+
+ if((UINT8)(line1[x] >> 24) < (UINT8)(color >> 24))
+ {
+ color = line1[x];
+ top = 0x02;
+ }
+
+ if((UINT8)(line2[x] >> 24) < (UINT8)(color >> 24))
+ {
+ color = line2[x];
+ top = 0x04;
+ }
+
+ if((UINT8)(lineOBJ[x] >> 24) < (UINT8)(color >> 24))
+ {
+ color = lineOBJ[x];
+ top = 0x10;
+ }
+
+ if(top == 0x10 && (color & 0x00010000) != 0)
+ {
+ UINT32 back = backdrop;
+ UINT8 top2 = 0x20;
+
+ if((UINT8)(line0[x] >> 24) < (UINT8)(back >> 24))
+ {
+ back = line0[x];
+ top2 = 0x01;
+ }
+
+ if((UINT8)(line1[x] >> 24) < (UINT8)(back >> 24))
+ {
+ back = line1[x];
+ top2 = 0x02;
+ }
+
+ if((UINT8)(line2[x] >> 24) < (UINT8)(back >> 24))
+ {
+ back = line2[x];
+ top2 = 0x04;
+ }
+
+ if(top2 & (state->m_BLDCNT >> BLDCNT_TP2_SHIFT))
+ {
+ color = alpha_blend_pixel(color, back, coeff[state->m_BLDALPHA & 0x1f], coeff[(state->m_BLDALPHA >> 8) & 0x1f]);
+ }
+ else
+ {
+ switch(state->m_BLDCNT & BLDCNT_SFX)
+ {
+ case BLDCNT_SFX_LIGHTEN:
+ if(top & state->m_BLDCNT)
+ {
+ color = increase_brightness(color, coeff[state->m_BLDY & 0x1f]);
+ }
+ break;
+ case BLDCNT_SFX_DARKEN:
+ if(top & state->m_BLDCNT)
+ {
+ color = decrease_brightness(color, coeff[state->m_BLDY & 0x1f]);
+ }
+ break;
+ }
+ }
+ }
+
+ lineMix[x] = color;
+ }
+ state->m_gfxBG2Changed = 0;
+}
+
+static void draw_mode1_scanline_nowindow(running_machine &machine, gba_state *state, int y, UINT32* line0, UINT32* line1, UINT32* line2, UINT32* line3, UINT32* lineOBJ, UINT32* lineOBJWin, UINT32* lineMix, int bpp)
+{
+ int x = 0;
+ UINT32 backdrop = ((UINT16*)state->m_gba_pram.target())[0] | 0x30000000;
+ int effect = state->m_BLDCNT & BLDCNT_SFX;
+
+ draw_bg_scanline(state, line0, y, DISPCNT_BG0_EN, state->m_BG0CNT, state->m_BG0HOFS, state->m_BG0VOFS);
+ draw_bg_scanline(state, line1, y, DISPCNT_BG1_EN, state->m_BG1CNT, state->m_BG1HOFS, state->m_BG1VOFS);
+ draw_roz_scanline(state, line2, y, DISPCNT_BG2_EN, state->m_BG2CNT, state->m_BG2X, state->m_BG2Y, state->m_BG2PA, state->m_BG2PB, state->m_BG2PC, state->m_BG2PD, &state->m_gfxBG2X, &state->m_gfxBG2Y, state->m_gfxBG2Changed);
+ draw_gba_oam(state, machine, lineOBJ, y);
+
+ for(x = 0; x < 240; x++)
+ {
+ UINT32 color = backdrop;
+ UINT8 top = 0x20;
+
+ if(line0[x] < color)
+ {
+ color = line0[x];
+ top = 0x01;
+ }
+
+ if(line1[x] < (color & 0xff000000))
+ {
+ color = line1[x];
+ top = 0x02;
+ }
+
+ if(line2[x] < (color & 0xff000000))
+ {
+ color = line2[x];
+ top = 0x04;
+ }
+
+ if(lineOBJ[x] < (color & 0xff000000))
+ {
+ color = lineOBJ[x];
+ top = 0x10;
+ }
+
+ if((color & 0x00010000) == 0)
+ {
+ switch(effect)
+ {
+ case BLDCNT_SFX_NONE:
+ break;
+ case BLDCNT_SFX_ALPHA:
+ if(state->m_BLDCNT & top)
+ {
+ UINT32 back = backdrop;
+ UINT8 top2 = 0x20;
+
+ if((UINT8)(line0[x] >> 24) < (UINT8)(back >> 24))
+ {
+ if(top != 0x01)
+ {
+ back = line0[x];
+ top2 = 0x01;
+ }
+ }
+
+ if((UINT8)(line1[x] >> 24) < (UINT8)(back >> 24))
+ {
+ if(top != 0x02)
+ {
+ back = line1[x];
+ top2 = 0x02;
+ }
+ }
+
+ if((UINT8)(line2[x] >> 24) < (UINT8)(back >> 24))
+ {
+ if(top != 0x04)
+ {
+ back = line2[x];
+ top2 = 0x04;
+ }
+ }
+
+ if((UINT8)(lineOBJ[x] >> 24) < (UINT8)(back >> 24))
+ {
+ if(top != 0x10)
+ {
+ back = lineOBJ[x];
+ top2 = 0x10;
+ }
+ }
+
+ if(top2 & (state->m_BLDCNT >> BLDCNT_TP2_SHIFT))
+ {
+ color = alpha_blend_pixel(color, back, coeff[state->m_BLDALPHA & 0x1f], coeff[(state->m_BLDALPHA >> 8) & 0x1f]);
+ }
+ }
+ break;
+ case BLDCNT_SFX_LIGHTEN:
+ if(top & state->m_BLDCNT)
+ {
+ color = increase_brightness(color, coeff[state->m_BLDY & 0x1f]);
+ }
+ break;
+ case BLDCNT_SFX_DARKEN:
+ if(top & state->m_BLDCNT)
+ {
+ color = decrease_brightness(color, coeff[state->m_BLDY & 0x1f]);
+ }
+ break;
+ }
+ }
+ else
+ {
+ UINT32 back = backdrop;
+ UINT8 top2 = 0x20;
+
+ if((UINT8)(line0[x] >> 24) < (UINT8)(back >> 24))
+ {
+ back = line0[x];
+ top2 = 0x01;
+ }
+
+ if((UINT8)(line1[x] >> 24) < (UINT8)(back >> 24))
+ {
+ back = line1[x];
+ top2 = 0x02;
+ }
+
+ if((UINT8)(line2[x] >> 24) < (UINT8)(back >> 24))
+ {
+ back = line2[x];
+ top2 = 0x04;
+ }
+
+ if(top2 & (state->m_BLDCNT >> BLDCNT_TP2_SHIFT))
+ {
+ color = alpha_blend_pixel(color, back, coeff[state->m_BLDALPHA & 0x1f], coeff[(state->m_BLDALPHA >> 8) & 0x1f]);
+ }
+ else
+ {
+ switch(state->m_BLDCNT & BLDCNT_SFX)
+ {
+ case BLDCNT_SFX_LIGHTEN:
+ if(top & state->m_BLDCNT)
+ {
+ color = increase_brightness(color, coeff[state->m_BLDY & 0x1f]);
+ }
+ break;
+ case BLDCNT_SFX_DARKEN:
+ if(top & state->m_BLDCNT)
+ {
+ color = decrease_brightness(color, coeff[state->m_BLDY & 0x1f]);
+ }
+ break;
+ }
+ }
+ }
+ lineMix[x] = color;
+ }
+ state->m_gfxBG2Changed = 0;
+}
+
+static void draw_mode1_scanline_all(running_machine &machine, gba_state *state, int y, UINT32* line0, UINT32* line1, UINT32* line2, UINT32* line3, UINT32* lineOBJ, UINT32* lineOBJWin, UINT32* lineMix, int bpp)
+{
+ int x = 0;
+ UINT32 backdrop = ((UINT16*)state->m_gba_pram.target())[0] | 0x30000000;
+ int inWindow0 = 0;
+ int inWindow1 = 0;
+ UINT8 inWin0Mask = state->m_WININ & 0x00ff;
+ UINT8 inWin1Mask = state->m_WININ >> 8;
+ UINT8 outMask = state->m_WINOUT & 0x00ff;
+
+ if(state->m_DISPCNT & DISPCNT_WIN0_EN)
+ {
+ UINT8 v0 = state->m_WIN0V >> 8;
+ UINT8 v1 = state->m_WIN0V & 0x00ff;
+ inWindow0 = ((v0 == v1) && (v0 >= 0xe8)) ? 1 : 0;
+ if(v1 >= v0)
+ {
+ inWindow0 |= (y >= v0 && y < v1) ? 1 : 0;
+ }
+ else
+ {
+ inWindow0 |= (y >= v0 || y < v1) ? 1 : 0;
+ }
+ }
+
+ if(state->m_DISPCNT & DISPCNT_WIN1_EN)
+ {
+ UINT8 v0 = state->m_WIN1V >> 8;
+ UINT8 v1 = state->m_WIN1V & 0x00ff;
+ inWindow1 = ((v0 == v1) && (v0 >= 0xe8)) ? 1 : 0;
+ if(v1 >= v0)
+ {
+ inWindow1 |= (y >= v0 && y < v1) ? 1 : 0;
+ }
+ else
+ {
+ inWindow1 |= (y >= v0 || y < v1) ? 1 : 0;
+ }
+ }
+
+ draw_bg_scanline(state, line0, y, DISPCNT_BG0_EN, state->m_BG0CNT, state->m_BG0HOFS, state->m_BG0VOFS);
+ draw_bg_scanline(state, line1, y, DISPCNT_BG1_EN, state->m_BG1CNT, state->m_BG1HOFS, state->m_BG1VOFS);
+ draw_roz_scanline(state, line2, y, DISPCNT_BG2_EN, state->m_BG2CNT, state->m_BG2X, state->m_BG2Y, state->m_BG2PA, state->m_BG2PB, state->m_BG2PC, state->m_BG2PD, &state->m_gfxBG2X, &state->m_gfxBG2Y, state->m_gfxBG2Changed);
+ draw_gba_oam(state, machine, lineOBJ, y);
+ draw_gba_oam_window(state, machine, lineOBJWin, y);
+
+ for(x = 0; x < 240; x++)
+ {
+ UINT32 color = backdrop;
+ UINT8 top = 0x20;
+ UINT8 mask = outMask;
+
+ if((lineOBJWin[x] & 0x80000000) == 0)
+ {
+ mask = state->m_WINOUT >> 8;
+ }
+
+ if(inWindow1)
+ {
+ if(is_in_window(state, x, 1))
+ {
+ mask = inWin1Mask;
+ }
+ }
+
+ if(inWindow0)
+ {
+ if(is_in_window(state, x, 0))
+ {
+ mask = inWin0Mask;
+ }
+ }
+
+ if((mask & 0x01) != 0 && (line0[x] < color))
+ {
+ color = line0[x];
+ top = 0x01;
+ }
+
+ if((mask & 0x02) != 0 && ((UINT8)(line1[x] >> 24) < (UINT8)(color >> 24)))
+ {
+ color = line1[x];
+ top = 0x02;
+ }
+
+ if((mask & 0x04) != 0 && ((UINT8)(line2[x] >> 24) < (UINT8)(color >> 24)))
+ {
+ color = line2[x];
+ top = 0x04;
+ }
+
+ if((mask & 0x10) != 0 && ((UINT8)(lineOBJ[x] >> 24) < (UINT8)(color >> 24)))
+ {
+ color = lineOBJ[x];
+ top = 0x10;
+ }
+
+ if((mask & 0x20) != 0)
+ {
+ if((color & 0x00010000) == 0)
+ {
+ switch(state->m_BLDCNT & BLDCNT_SFX)
+ {
+ case BLDCNT_SFX_NONE:
+ break;
+ case BLDCNT_SFX_ALPHA:
+ {
+ if(top & state->m_BLDCNT)
+ {
+ UINT32 back = backdrop;
+ UINT8 top2 = 0x20;
+ if((mask & 0x01) != 0 && ((UINT8)(line0[x] >> 24) < (UINT8)(back >> 24)))
+ {
+ if(top != 0x01)
+ {
+ back = line0[x];
+ top2 = 0x01;
+ }
+ }
+
+ if((mask & 0x02) != 0 && ((UINT8)(line1[x] >> 24) < (UINT8)(back >> 24)))
+ {
+ if(top != 0x02)
+ {
+ back = line1[x];
+ top2 = 0x02;
+ }
+ }
+
+ if((mask & 0x04) != 0 && ((UINT8)(line2[x] >> 24) < (UINT8)(back >> 24)))
+ {
+ if(top != 0x04)
+ {
+ back = line2[x];
+ top2 = 0x04;
+ }
+ }
+
+ if((mask & 0x10) != 0 && ((UINT8)(lineOBJ[x] >> 24) < (UINT8)(back >> 24)))
+ {
+ if(top != 0x10)
+ {
+ back = lineOBJ[x];
+ top2 = 0x10;
+ }
+ }
+
+ if(top2 & (state->m_BLDCNT >> BLDCNT_TP2_SHIFT))
+ {
+ color = alpha_blend_pixel(color, back, coeff[state->m_BLDALPHA & 0x1f], coeff[(state->m_BLDALPHA >> 8) & 0x1f]);
+ }
+ }
+ break;
+ }
+ case BLDCNT_SFX_LIGHTEN:
+ if(top & state->m_BLDCNT)
+ {
+ color = increase_brightness(color, coeff[state->m_BLDY & 0x1f]);
+ }
+ break;
+ case BLDCNT_SFX_DARKEN:
+ if(top & state->m_BLDCNT)
+ {
+ color = decrease_brightness(color, coeff[state->m_BLDY & 0x1f]);
+ }
+ break;
+ }
+ }
+ else
+ {
+ UINT32 back = backdrop;
+ UINT8 top2 = 0x20;
+
+ if((mask & 0x01) != 0 && ((UINT8)(line0[x] >> 24) < (UINT8)(back >> 24)))
+ {
+ back = line0[x];
+ top2 = 0x01;
+ }
+
+ if((mask & 0x02) != 0 && ((UINT8)(line1[x] >> 24) < (UINT8)(back >> 24)))
+ {
+ back = line1[x];
+ top2 = 0x02;
+ }
+
+ if((mask & 0x04) != 0 && ((UINT8)(line2[x] >> 24) < (UINT8)(back >> 24)))
+ {
+ back = line2[x];
+ top2 = 0x04;
+ }
+
+ if(top2 & (state->m_BLDCNT >> BLDCNT_TP2_SHIFT))
+ {
+ color = alpha_blend_pixel(color, back, coeff[state->m_BLDALPHA & 0x1f], coeff[(state->m_BLDALPHA >> 8) & 0x1f]);
+ }
+ else
+ {
+ switch(state->m_BLDCNT & BLDCNT_SFX)
+ {
+ case BLDCNT_SFX_LIGHTEN:
+ if(top & state->m_BLDCNT)
+ {
+ color = increase_brightness(color, coeff[state->m_BLDY & 0x1f]);
+ }
+ break;
+ case BLDCNT_SFX_DARKEN:
+ if(top & state->m_BLDCNT)
+ {
+ color = decrease_brightness(color, coeff[state->m_BLDY & 0x1f]);
+ }
+ break;
+ }
+ }
+ }
+ }
+ else if(color & 0x00010000)
+ {
+ UINT32 back = backdrop;
+ UINT8 top2 = 0x20;
+
+ if((mask & 0x01) != 0 && ((UINT8)(line0[x] >> 24) < (UINT8)(back >> 24)))
+ {
+ back = line0[x];
+ top2 = 0x01;
+ }
+
+ if((mask & 0x02) != 0 && ((UINT8)(line1[x] >> 24) < (UINT8)(back >> 24)))
+ {
+ back = line1[x];
+ top2 = 0x02;
+ }
+
+ if((mask & 0x04) != 0 && ((UINT8)(line2[x] >> 24) < (UINT8)(back >> 24)))
+ {
+ back = line2[x];
+ top2 = 0x04;
+ }
+
+ if(top2 & (state->m_BLDCNT >> BLDCNT_TP2_SHIFT))
+ {
+ color = alpha_blend_pixel(color, back, coeff[state->m_BLDALPHA & 0x1f], coeff[(state->m_BLDALPHA >> 8) & 0x1f]);
+ }
+ else
+ {
+ switch(state->m_BLDCNT & BLDCNT_SFX)
+ {
+ case BLDCNT_SFX_LIGHTEN:
+ if(top & state->m_BLDCNT)
+ {
+ color = increase_brightness(color, coeff[state->m_BLDY & 0x1f]);
+ }
+ break;
+ case BLDCNT_SFX_DARKEN:
+ if(top & state->m_BLDCNT)
+ {
+ color = decrease_brightness(color, coeff[state->m_BLDY & 0x1f]);
+ }
+ break;
+ }
+ }
+ }
+ lineMix[x] = color;
+ }
+ state->m_gfxBG2Changed = 0;
+}