1 #include "driver.h"
2 #include "vidhrdw/generic.h"
3 #include "vidhrdw/konamiic.h"
4
5
6 static int AVAC_bits[4], AVAC_occupancy[4];
7 static int layer_colorbase[4], layer_pri[4];
8 static int AVAC_vrc, sprite_colorbase;
9
gijoe_sprite_callback(int * code,int * color,int * priority_mask)10 static void gijoe_sprite_callback(int *code, int *color, int *priority_mask)
11 {
12 int pri, c = *color;
13
14 pri = (c & 0x03e0) >> 4;
15
16 if (pri <= layer_pri[3]) *priority_mask = 0; else
17 if (pri > layer_pri[3] && pri <= layer_pri[2]) *priority_mask = 0xff00; else
18 if (pri > layer_pri[2] && pri <= layer_pri[1]) *priority_mask = 0xff00|0xf0f0; else
19 if (pri > layer_pri[1] && pri <= layer_pri[0]) *priority_mask = 0xff00|0xf0f0|0xcccc; else
20 *priority_mask = 0xff00|0xf0f0|0xcccc|0xaaaa;
21
22 *color = sprite_colorbase | (c & 0x001f);
23 }
24
gijoe_tile_callback(int layer,int * code,int * color)25 static void gijoe_tile_callback(int layer, int *code, int *color)
26 {
27 int tile = *code;
28
29 if (tile >= 0xf000 && tile <= 0xf4ff)
30 {
31 tile &= 0x0fff;
32 if (tile < 0x0310) { AVAC_occupancy[layer] |= 0x0f00; tile |= AVAC_bits[0]; } else
33 if (tile < 0x0470) { AVAC_occupancy[layer] |= 0xf000; tile |= AVAC_bits[1]; } else
34 { AVAC_occupancy[layer] |= 0x00f0; tile |= AVAC_bits[2]; }
35 *code = tile;
36 }
37
38 *color = (*color>>2 & 0x0f) | layer_colorbase[layer];
39 }
40
VIDEO_START(gijoe)41 VIDEO_START( gijoe )
42 {
43 int i;
44
45 K053251_vh_start();
46
47 if (K056832_vh_start(REGION_GFX1, K056832_BPP_4, 1, NULL, gijoe_tile_callback, 0)) return 1;
48
49 K056832_linemap_enable(1);
50
51 if (K053247_vh_start(REGION_GFX2, -37, 20, NORMAL_PLANE_ORDER, gijoe_sprite_callback)) return 1;
52
53 for (i=0; i<4; i++) AVAC_occupancy[i] = 0;
54 AVAC_vrc = 0xffff;
55
56 return 0;
57 }
58
59 /* useful function to sort the four tile layers by priority order */
sortlayers(int * layer,int * pri)60 static void sortlayers(int *layer, int *pri)
61 {
62 #define SWAP(a,b) \
63 if (pri[a] <= pri[b]) \
64 { \
65 int t; \
66 t = pri[a]; pri[a] = pri[b]; pri[b] = t; \
67 t = layer[a]; layer[a] = layer[b]; layer[b] = t; \
68 }
69
70 SWAP(0, 1)
71 SWAP(0, 2)
72 SWAP(0, 3)
73 SWAP(1, 2)
74 SWAP(1, 3)
75 SWAP(2, 3)
76 }
77
VIDEO_UPDATE(gijoe)78 VIDEO_UPDATE( gijoe )
79 {
80 const int K053251_CI[4] = { K053251_CI1, K053251_CI2, K053251_CI3, K053251_CI4 };
81 int layer[4];
82 int vrc_mode, vrc_new, colorbase_new, primode, dirty, i;
83 int mask = 0;
84
85 /* update tile offsets*/
86 K056832_read_AVAC(&vrc_mode, &vrc_new);
87
88 if (vrc_mode)
89 {
90 for (dirty=0xf000; dirty; dirty>>=4) if ((AVAC_vrc & dirty) != (vrc_new & dirty)) mask |= dirty;
91
92 AVAC_vrc = vrc_new;
93 AVAC_bits[0] = vrc_new<<4 & 0xf000;
94 AVAC_bits[1] = vrc_new & 0xf000;
95 AVAC_bits[2] = vrc_new<<8 & 0xf000;
96 AVAC_bits[3] = vrc_new<<12 & 0xf000;
97 }
98 else
99 AVAC_bits[3] = AVAC_bits[2] = AVAC_bits[1] = AVAC_bits[0] = 0xf000;
100
101 /* update color info and refresh tilemaps*/
102 sprite_colorbase = K053251_get_palette_index(K053251_CI0);
103
104 for (i=0; i<4; i++)
105 {
106 dirty = 0;
107
108 colorbase_new = K053251_get_palette_index(K053251_CI[i]);
109 if (layer_colorbase[i] != colorbase_new) { layer_colorbase[i] = colorbase_new; dirty = 1; }
110 if (AVAC_occupancy[i] & mask) dirty = 1;
111
112 if (dirty) { AVAC_occupancy[i] = 0; K056832_mark_plane_dirty(i); }
113 }
114
115 /*
116 Layer A is supposed to be a non-scrolling status display with static X-offset.
117 The weird thing is tilemap alignment only follows the 832 standard when 2 is
118 written to the layer's X-scroll register otherwise the chip expects totally
119 different alignment values.
120 */
121 if (K056832_read_register(0x14) == 2)
122 {
123 K056832_set_LayerOffset(0, 2, 0);
124 K056832_set_LayerOffset(1, 4, 0);
125 K056832_set_LayerOffset(2, 6, 0); /* 7?*/
126 K056832_set_LayerOffset(3, 8, 0);
127 }
128 else
129 {
130 K056832_set_LayerOffset(0, 0, 0);
131 K056832_set_LayerOffset(1, 8, 0);
132 K056832_set_LayerOffset(2, 14, 0);
133 K056832_set_LayerOffset(3, 16, 0); /* smaller?*/
134 }
135
136 /* seems to switch the K053251 between different priority modes, detail unknown*/
137 primode = K053251_get_priority(K053251_CI1);
138
139 layer[0] = 0;
140 layer_pri[0] = 0; /* not sure*/
141 layer[1] = 1;
142 layer_pri[1] = K053251_get_priority(K053251_CI2);
143 layer[2] = 2;
144 layer_pri[2] = K053251_get_priority(K053251_CI3);
145 layer[3] = 3;
146 layer_pri[3] = K053251_get_priority(K053251_CI4);
147
148 sortlayers(layer, layer_pri);
149
150 fillbitmap(bitmap, get_black_pen(), cliprect);
151 fillbitmap(priority_bitmap, 0, cliprect);
152
153 K056832_tilemap_draw(bitmap,cliprect, layer[0], 0, 1);
154 K056832_tilemap_draw(bitmap,cliprect, layer[1], 0, 2);
155 K056832_tilemap_draw(bitmap,cliprect, layer[2], 0, 4);
156 K056832_tilemap_draw(bitmap,cliprect, layer[3], 0, 8);
157
158 K053247_sprites_draw(bitmap, cliprect);
159 }
160