summaryrefslogtreecommitdiffstatshomepage
path: root/src/mame/video/gijoe.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/mame/video/gijoe.c')
-rw-r--r--src/mame/video/gijoe.c156
1 files changed, 156 insertions, 0 deletions
diff --git a/src/mame/video/gijoe.c b/src/mame/video/gijoe.c
new file mode 100644
index 00000000000..8f3fbeefc78
--- /dev/null
+++ b/src/mame/video/gijoe.c
@@ -0,0 +1,156 @@
+#include "driver.h"
+#include "video/konamiic.h"
+
+
+static int AVAC_bits[4], AVAC_occupancy[4];
+static int layer_colorbase[4], layer_pri[4];
+static int AVAC_vrc, sprite_colorbase;
+
+static void gijoe_sprite_callback(int *code, int *color, int *priority_mask)
+{
+ int pri, c = *color;
+
+ pri = (c & 0x03e0) >> 4;
+
+ if (pri <= layer_pri[3]) *priority_mask = 0; else
+ if (pri > layer_pri[3] && pri <= layer_pri[2]) *priority_mask = 0xff00; else
+ if (pri > layer_pri[2] && pri <= layer_pri[1]) *priority_mask = 0xff00|0xf0f0; else
+ if (pri > layer_pri[1] && pri <= layer_pri[0]) *priority_mask = 0xff00|0xf0f0|0xcccc; else
+ *priority_mask = 0xff00|0xf0f0|0xcccc|0xaaaa;
+
+ *color = sprite_colorbase | (c & 0x001f);
+}
+
+static void gijoe_tile_callback(int layer, int *code, int *color, int *flags)
+{
+ int tile = *code;
+
+ if (tile >= 0xf000 && tile <= 0xf4ff)
+ {
+ tile &= 0x0fff;
+ if (tile < 0x0310) { AVAC_occupancy[layer] |= 0x0f00; tile |= AVAC_bits[0]; } else
+ if (tile < 0x0470) { AVAC_occupancy[layer] |= 0xf000; tile |= AVAC_bits[1]; } else
+ { AVAC_occupancy[layer] |= 0x00f0; tile |= AVAC_bits[2]; }
+ *code = tile;
+ }
+
+ *color = (*color>>2 & 0x0f) | layer_colorbase[layer];
+}
+
+VIDEO_START( gijoe )
+{
+ int i;
+
+ K053251_vh_start();
+ K056832_vh_start(machine, REGION_GFX1, K056832_BPP_4, 1, NULL, gijoe_tile_callback, 0);
+
+ K056832_linemap_enable(1);
+
+ K053247_vh_start(machine, REGION_GFX2, -37, 20, NORMAL_PLANE_ORDER, gijoe_sprite_callback);
+
+ for (i=0; i<4; i++) AVAC_occupancy[i] = 0;
+ AVAC_vrc = 0xffff;
+}
+
+/* useful function to sort the four tile layers by priority order */
+static void sortlayers(int *layer, int *pri)
+{
+#define SWAP(a,b) \
+ if (pri[a] <= pri[b]) \
+ { \
+ int t; \
+ t = pri[a]; pri[a] = pri[b]; pri[b] = t; \
+ t = layer[a]; layer[a] = layer[b]; layer[b] = t; \
+ }
+
+ SWAP(0, 1)
+ SWAP(0, 2)
+ SWAP(0, 3)
+ SWAP(1, 2)
+ SWAP(1, 3)
+ SWAP(2, 3)
+}
+
+VIDEO_UPDATE( gijoe )
+{
+ static const int K053251_CI[4] = { K053251_CI1, K053251_CI2, K053251_CI3, K053251_CI4 };
+ int layer[4];
+ int vrc_mode, vrc_new, colorbase_new, primode, dirty, i;
+ int mask = 0;
+
+ // update tile offsets
+ K056832_read_AVAC(&vrc_mode, &vrc_new);
+
+ if (vrc_mode)
+ {
+ for (dirty=0xf000; dirty; dirty>>=4) if ((AVAC_vrc & dirty) != (vrc_new & dirty)) mask |= dirty;
+
+ AVAC_vrc = vrc_new;
+ AVAC_bits[0] = vrc_new<<4 & 0xf000;
+ AVAC_bits[1] = vrc_new & 0xf000;
+ AVAC_bits[2] = vrc_new<<8 & 0xf000;
+ AVAC_bits[3] = vrc_new<<12 & 0xf000;
+ }
+ else
+ AVAC_bits[3] = AVAC_bits[2] = AVAC_bits[1] = AVAC_bits[0] = 0xf000;
+
+ // update color info and refresh tilemaps
+ sprite_colorbase = K053251_get_palette_index(K053251_CI0);
+
+ for (i=0; i<4; i++)
+ {
+ dirty = 0;
+
+ colorbase_new = K053251_get_palette_index(K053251_CI[i]);
+ if (layer_colorbase[i] != colorbase_new) { layer_colorbase[i] = colorbase_new; dirty = 1; }
+ if (AVAC_occupancy[i] & mask) dirty = 1;
+
+ if (dirty) { AVAC_occupancy[i] = 0; K056832_mark_plane_dirty(i); }
+ }
+
+ /*
+ Layer A is supposed to be a non-scrolling status display with static X-offset.
+ The weird thing is tilemap alignment only follows the 832 standard when 2 is
+ written to the layer's X-scroll register otherwise the chip expects totally
+ different alignment values.
+ */
+ if (K056832_read_register(0x14) == 2)
+ {
+ K056832_set_LayerOffset(0, 2, 0);
+ K056832_set_LayerOffset(1, 4, 0);
+ K056832_set_LayerOffset(2, 6, 0); // 7?
+ K056832_set_LayerOffset(3, 8, 0);
+ }
+ else
+ {
+ K056832_set_LayerOffset(0, 0, 0);
+ K056832_set_LayerOffset(1, 8, 0);
+ K056832_set_LayerOffset(2, 14, 0);
+ K056832_set_LayerOffset(3, 16, 0); // smaller?
+ }
+
+ // seems to switch the K053251 between different priority modes, detail unknown
+ primode = K053251_get_priority(K053251_CI1);
+
+ layer[0] = 0;
+ layer_pri[0] = 0; // not sure
+ layer[1] = 1;
+ layer_pri[1] = K053251_get_priority(K053251_CI2);
+ layer[2] = 2;
+ layer_pri[2] = K053251_get_priority(K053251_CI3);
+ layer[3] = 3;
+ layer_pri[3] = K053251_get_priority(K053251_CI4);
+
+ sortlayers(layer, layer_pri);
+
+ fillbitmap(bitmap, get_black_pen(machine), cliprect);
+ fillbitmap(priority_bitmap, 0, cliprect);
+
+ K056832_tilemap_draw(machine, bitmap,cliprect, layer[0], 0, 1);
+ K056832_tilemap_draw(machine, bitmap,cliprect, layer[1], 0, 2);
+ K056832_tilemap_draw(machine, bitmap,cliprect, layer[2], 0, 4);
+ K056832_tilemap_draw(machine, bitmap,cliprect, layer[3], 0, 8);
+
+ K053247_sprites_draw(machine, bitmap, cliprect);
+ return 0;
+}