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