summaryrefslogtreecommitdiffstatshomepage
path: root/src/mame/video/gradius3.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/mame/video/gradius3.c')
-rw-r--r--src/mame/video/gradius3.c190
1 files changed, 190 insertions, 0 deletions
diff --git a/src/mame/video/gradius3.c b/src/mame/video/gradius3.c
new file mode 100644
index 00000000000..3321068698c
--- /dev/null
+++ b/src/mame/video/gradius3.c
@@ -0,0 +1,190 @@
+#include "driver.h"
+#include "video/konamiic.h"
+
+
+#define TOTAL_CHARS 0x1000
+#define TOTAL_SPRITES 0x4000
+
+UINT16 *gradius3_gfxram;
+int gradius3_priority;
+static int layer_colorbase[3],sprite_colorbase;
+static int dirtygfx;
+static UINT8 *dirtychar;
+
+
+
+/***************************************************************************
+
+ Callbacks for the K052109
+
+***************************************************************************/
+
+static void gradius3_tile_callback(int layer,int bank,int *code,int *color,int *flags,int *priority)
+{
+ /* (color & 0x02) is flip y handled internally by the 052109 */
+ *code |= ((*color & 0x01) << 8) | ((*color & 0x1c) << 7);
+ *color = layer_colorbase[layer] + ((*color & 0xe0) >> 5);
+}
+
+
+
+/***************************************************************************
+
+ Callbacks for the K051960
+
+***************************************************************************/
+
+static void gradius3_sprite_callback(int *code,int *color,int *priority_mask,int *shadow)
+{
+ #define L0 0xaa
+ #define L1 0xcc
+ #define L2 0xf0
+ static int primask[2][4] =
+ {
+ { L0|L2, L0, L0|L2, L0|L1|L2 },
+ { L1|L2, L2, 0, L0|L1|L2 }
+ };
+ int pri = ((*color & 0x60) >> 5);
+ if (gradius3_priority == 0) *priority_mask = primask[0][pri];
+ else *priority_mask = primask[1][pri];
+
+ *code |= (*color & 0x01) << 13;
+ *color = sprite_colorbase + ((*color & 0x1e) >> 1);
+}
+
+
+
+/***************************************************************************
+
+ Start the video hardware emulation.
+
+***************************************************************************/
+
+VIDEO_START( gradius3 )
+{
+ int i;
+ static const gfx_layout spritelayout =
+ {
+ 16,16,
+ TOTAL_SPRITES,
+ 4,
+ { 0, 1, 2, 3 },
+ { 2*4, 3*4, 0*4, 1*4, 6*4, 7*4, 4*4, 5*4,
+ 32*8+2*4, 32*8+3*4, 32*8+0*4, 32*8+1*4, 32*8+6*4, 32*8+7*4, 32*8+4*4, 32*8+5*4 },
+ { 0*32, 1*32, 2*32, 3*32, 4*32, 5*32, 6*32, 7*32,
+ 64*8+0*32, 64*8+1*32, 64*8+2*32, 64*8+3*32, 64*8+4*32, 64*8+5*32, 64*8+6*32, 64*8+7*32 },
+ 128*8
+ };
+
+
+ layer_colorbase[0] = 0;
+ layer_colorbase[1] = 32;
+ layer_colorbase[2] = 48;
+ sprite_colorbase = 16;
+ K052109_vh_start(machine,REGION_GFX1,NORMAL_PLANE_ORDER,gradius3_tile_callback);
+ K051960_vh_start(machine,REGION_GFX2,REVERSE_PLANE_ORDER,gradius3_sprite_callback);
+
+ K052109_set_layer_offsets(2, -2, 0);
+ K051960_set_sprite_offsets(2, 0);
+
+ /* re-decode the sprites because the ROMs are connected to the custom IC differently
+ from how they are connected to the CPU. */
+ for (i = 0;i < TOTAL_SPRITES;i++)
+ decodechar(machine->gfx[1],i,memory_region(REGION_GFX2),&spritelayout);
+
+ dirtychar = auto_malloc(TOTAL_CHARS);
+ memset(dirtychar,1,TOTAL_CHARS);
+}
+
+
+
+/***************************************************************************
+
+ Memory handlers
+
+***************************************************************************/
+
+READ16_HANDLER( gradius3_gfxrom_r )
+{
+ UINT8 *gfxdata = memory_region(REGION_GFX2);
+
+ return (gfxdata[2*offset+1] << 8) | gfxdata[2*offset];
+}
+
+WRITE16_HANDLER( gradius3_gfxram_w )
+{
+ int oldword = gradius3_gfxram[offset];
+ COMBINE_DATA(&gradius3_gfxram[offset]);
+ if (oldword != gradius3_gfxram[offset])
+ {
+ dirtygfx = 1;
+ dirtychar[offset / 16] = 1;
+ }
+}
+
+
+
+/***************************************************************************
+
+ Display refresh
+
+***************************************************************************/
+
+VIDEO_UPDATE( gradius3 )
+{
+ static const gfx_layout charlayout =
+ {
+ 8,8,
+ TOTAL_CHARS,
+ 4,
+ { 0, 1, 2, 3 },
+#ifdef LSB_FIRST
+ { 2*4, 3*4, 0*4, 1*4, 6*4, 7*4, 4*4, 5*4 },
+#else
+ { 0*4, 1*4, 2*4, 3*4, 4*4, 5*4, 6*4, 7*4 },
+#endif
+ { 0*32, 1*32, 2*32, 3*32, 4*32, 5*32, 6*32, 7*32 },
+ 32*8
+ };
+
+ /* TODO: this kludge enforces the char banks. For some reason, they don't work otherwise. */
+ K052109_w(0x1d80,0x10);
+ K052109_w(0x1f00,0x32);
+
+ if (dirtygfx)
+ {
+ int i;
+
+ dirtygfx = 0;
+
+ for (i = 0;i < TOTAL_CHARS;i++)
+ {
+ if (dirtychar[i])
+ {
+ dirtychar[i] = 0;
+ decodechar(machine->gfx[0],i,(UINT8 *)gradius3_gfxram,&charlayout);
+ }
+ }
+
+ tilemap_mark_all_tiles_dirty(ALL_TILEMAPS);
+ }
+
+ K052109_tilemap_update();
+
+ fillbitmap(priority_bitmap,0,cliprect);
+ if (gradius3_priority == 0)
+ {
+ tilemap_draw(bitmap,cliprect,K052109_tilemap[1],TILEMAP_DRAW_OPAQUE,2);
+ tilemap_draw(bitmap,cliprect,K052109_tilemap[2],0,4);
+ tilemap_draw(bitmap,cliprect,K052109_tilemap[0],0,1);
+ }
+ else
+ {
+ tilemap_draw(bitmap,cliprect,K052109_tilemap[0],TILEMAP_DRAW_OPAQUE,1);
+ tilemap_draw(bitmap,cliprect,K052109_tilemap[1],0,2);
+ tilemap_draw(bitmap,cliprect,K052109_tilemap[2],0,4);
+ }
+
+ K051960_sprites_draw(bitmap,cliprect,-1,-1);
+ return 0;
+}