1 #include "driver.h"
2 #include "vidhrdw/generic.h"
3 #include "vidhrdw/taitoic.h"
4 
5 #define TC0480SCP_GFX_NUM 1
6 
7 struct tempsprite
8 {
9 	int gfx;
10 	int code,color;
11 	int flipx,flipy;
12 	int x,y;
13 	int zoomx,zoomy;
14 	int primask;
15 };
16 static struct tempsprite *spritelist;
17 
VIDEO_START(superchs)18 VIDEO_START( superchs )
19 {
20 	spritelist = auto_malloc(0x4000 * sizeof(*spritelist));
21 	if (!spritelist)
22 		return 1;
23 
24 	if (TC0480SCP_vh_start(TC0480SCP_GFX_NUM,0,0x20,0x08,-1,0,0,0,0))
25 		return 1;
26 
27 	return 0;
28 }
29 
30 /************************************************************
31 			SPRITE DRAW ROUTINES
32 
33 We draw a series of small tiles ("chunks") together to
34 create each big sprite. The spritemap rom provides the lookup
35 table for this. The game hardware looks up 16x16 sprite chunks
36 from the spritemap rom, creating a 64x64 sprite like this:
37 
38 	 0  1  2  3
39 	 4  5  6  7
40 	 8  9 10 11
41 	12 13 14 15
42 
43 (where the number is the word offset into the spritemap rom).
44 It can also create 32x32 sprites.
45 
46 NB: unused portions of the spritemap rom contain hex FF's.
47 It is a useful coding check to warn in the log if these
48 are being accessed. [They can be inadvertently while
49 spriteram is being tested, take no notice of that.]
50 
51 Heavy use is made of sprite zooming.
52 
53 		***
54 
55 	Sprite table layout (4 long words per entry)
56 
57 	------------------------------------------
58 	 0 | ........ x....... ........ ........ | Flip X
59 	 0 | ........ .xxxxxxx ........ ........ | ZoomX
60 	 0 | ........ ........ .xxxxxxx xxxxxxxx | Sprite Tile
61 	   |                                     |
62 	 2 | ........ ....xx.. ........ ........ | Sprite/tile priority [*]
63 	 2 | ........ ......xx xxxxxx.. ........ | Palette bank
64 	 2 | ........ ........ ......xx xxxxxxxx | X position
65 	   |                                     |
66 	 3 | ........ .....x.. ........ ........ | Sprite size (0=32x32, 1=64x64)
67 	 3 | ........ ......x. ........ ........ | Flip Y
68 	 3 | ........ .......x xxxxxx.. ........ | ZoomY
69 	 3 | ........ ........ ......xx xxxxxxxx | Y position
70 	------------------------------------------
71 
72 	[* 00=over BG1; 01=BG2; 10=BG3; 11=over text]
73 
74 ********************************************************/
75 
superchs_draw_sprites_16x16(struct mame_bitmap * bitmap,const struct rectangle * cliprect,int * primasks,int x_offs,int y_offs)76 static void superchs_draw_sprites_16x16(struct mame_bitmap *bitmap,const struct rectangle *cliprect,int *primasks,int x_offs,int y_offs)
77 {
78 	data16_t *spritemap = (data16_t *)memory_region(REGION_USER1);
79 	int offs, data, tilenum, color, flipx, flipy;
80 	int x, y, priority, dblsize, curx, cury;
81 	int sprites_flipscreen = 0;
82 	int zoomx, zoomy, zx, zy;
83 	int sprite_chunk,map_offset,code,j,k,px,py;
84 	int dimension,total_chunks,bad_chunks;
85 
86 	/* pdrawgfx() needs us to draw sprites front to back, so we have to build a list
87 	   while processing sprite ram and then draw them all at the end */
88 	struct tempsprite *sprite_ptr = spritelist;
89 
90 	for (offs = (spriteram_size/4-4);offs >= 0;offs -= 4)
91 	{
92 		data = spriteram32[offs+0];
93 		flipx =    (data & 0x00800000) >> 23;
94 		zoomx =    (data & 0x007f0000) >> 16;
95 		tilenum =  (data & 0x00007fff);
96 
97 		data = spriteram32[offs+2];
98 		priority = (data & 0x000c0000) >> 18;
99 		color =    (data & 0x0003fc00) >> 10;
100 		x =        (data & 0x000003ff);
101 
102 		data = spriteram32[offs+3];
103 		dblsize =  (data & 0x00040000) >> 18;
104 		flipy =    (data & 0x00020000) >> 17;
105 		zoomy =    (data & 0x0001fc00) >> 10;
106 		y =        (data & 0x000003ff);
107 
108 		color |= 0x100;
109 
110 		if (!tilenum) continue;
111 
112 		flipy = !flipy;
113 		zoomx += 1;
114 		zoomy += 1;
115 
116 		y += y_offs;
117 
118 		/* treat coords as signed */
119 		if (x>0x340) x -= 0x400;
120 		if (y>0x340) y -= 0x400;
121 
122 		x -= x_offs;
123 
124 		bad_chunks = 0;
125 		dimension = ((dblsize*2) + 2);	/* 2 or 4*/
126 		total_chunks = ((dblsize*3) + 1) << 2;	/* 4 or 16*/
127 		map_offset = tilenum << 2;
128 
129 		{
130 			for (sprite_chunk=0;sprite_chunk<total_chunks;sprite_chunk++)
131 			{
132 				j = sprite_chunk / dimension;   /* rows */
133 				k = sprite_chunk % dimension;   /* chunks per row */
134 
135 				px = k;
136 				py = j;
137 				/* pick tiles back to front for x and y flips */
138 				if (flipx)  px = dimension-1-k;
139 				if (flipy)  py = dimension-1-j;
140 
141 				code = spritemap[map_offset + px + (py<<(dblsize+1))];
142 
143 				if (code==0xffff)
144 				{
145 					bad_chunks += 1;
146 					continue;
147 				}
148 
149 				curx = x + ((k*zoomx)/dimension);
150 				cury = y + ((j*zoomy)/dimension);
151 
152 				zx= x + (((k+1)*zoomx)/dimension) - curx;
153 				zy= y + (((j+1)*zoomy)/dimension) - cury;
154 
155 				if (sprites_flipscreen)
156 				{
157 					/* -zx/y is there to fix zoomed sprite coords in screenflip.
158 					   drawgfxzoom does not know to draw from flip-side of sprites when
159 					   screen is flipped; so we must correct the coords ourselves. */
160 
161 					curx = 320 - curx - zx;
162 					cury = 256 - cury - zy;
163 					flipx = !flipx;
164 					flipy = !flipy;
165 				}
166 
167 				sprite_ptr->gfx = 0;
168 				sprite_ptr->code = code;
169 				sprite_ptr->color = color;
170 				sprite_ptr->flipx = !flipx;
171 				sprite_ptr->flipy = flipy;
172 				sprite_ptr->x = curx;
173 				sprite_ptr->y = cury;
174 				sprite_ptr->zoomx = zx << 12;
175 				sprite_ptr->zoomy = zy << 12;
176 
177 				if (primasks)
178 				{
179 					sprite_ptr->primask = primasks[priority];
180 
181 					sprite_ptr++;
182 				}
183 				else
184 				{
185 					drawgfxzoom(bitmap,Machine->gfx[sprite_ptr->gfx],
186 							sprite_ptr->code,
187 							sprite_ptr->color,
188 							sprite_ptr->flipx,sprite_ptr->flipy,
189 							sprite_ptr->x,sprite_ptr->y,
190 							cliprect,TRANSPARENCY_PEN,0,
191 							sprite_ptr->zoomx,sprite_ptr->zoomy);
192 				}
193 			}
194 		}
195 
196 		if (bad_chunks)
197 log_cb(RETRO_LOG_DEBUG, LOGPRE "Sprite number %04x had %02x invalid chunks\n",tilenum,bad_chunks);
198 	}
199 
200 	/* this happens only if primsks != NULL */
201 	while (sprite_ptr != spritelist)
202 	{
203 		sprite_ptr--;
204 
205 		pdrawgfxzoom(bitmap,Machine->gfx[sprite_ptr->gfx],
206 				sprite_ptr->code,
207 				sprite_ptr->color,
208 				sprite_ptr->flipx,sprite_ptr->flipy,
209 				sprite_ptr->x,sprite_ptr->y,
210 				cliprect,TRANSPARENCY_PEN,0,
211 				sprite_ptr->zoomx,sprite_ptr->zoomy,
212 				sprite_ptr->primask);
213 	}
214 }
215 
216 
217 /**************************************************************
218 				SCREEN REFRESH
219 **************************************************************/
220 
VIDEO_UPDATE(superchs)221 VIDEO_UPDATE( superchs )
222 {
223 	UINT8 layer[5];
224 	UINT16 priority;
225 	int primasks[4] = {0xfffc, 0xfff0, 0xff00, 0x0};
226 
227 	TC0480SCP_tilemap_update();
228 
229 	priority = TC0480SCP_get_bg_priority();
230 	layer[0] = (priority &0xf000) >> 12;	/* tells us which bg layer is bottom */
231 	layer[1] = (priority &0x0f00) >>  8;
232 	layer[2] = (priority &0x00f0) >>  4;
233 	layer[3] = (priority &0x000f) >>  0;	/* tells us which is top */
234 	layer[4] = 4;   /* text layer always over bg layers */
235 
236 	fillbitmap(priority_bitmap,0,cliprect);
237 
238 	/* We have to assume 2nd to bottom layer is always underneath
239 	   sprites as pdrawgfx cannot yet cope with more than 4 layers */
240 
241 #ifdef MAME_DEBUG
242 	if (!keyboard_pressed (KEYCODE_Z)) TC0480SCP_tilemap_draw(bitmap,cliprect,layer[0],TILEMAP_IGNORE_TRANSPARENCY,0);
243 	if (!keyboard_pressed (KEYCODE_X)) TC0480SCP_tilemap_draw(bitmap,cliprect,layer[1],0,1);
244 	if (!keyboard_pressed (KEYCODE_C)) TC0480SCP_tilemap_draw(bitmap,cliprect,layer[2],0,2);
245 	if (!keyboard_pressed (KEYCODE_V)) TC0480SCP_tilemap_draw(bitmap,cliprect,layer[3],0,4);
246 	if (!keyboard_pressed (KEYCODE_B)) TC0480SCP_tilemap_draw(bitmap,cliprect,layer[4],0,8);
247 	if (!keyboard_pressed (KEYCODE_N)) superchs_draw_sprites_16x16(bitmap,cliprect,primasks,48,-116);
248 #else
249 	TC0480SCP_tilemap_draw(bitmap,cliprect,layer[0],TILEMAP_IGNORE_TRANSPARENCY,0);
250 	TC0480SCP_tilemap_draw(bitmap,cliprect,layer[1],0,1);
251 	TC0480SCP_tilemap_draw(bitmap,cliprect,layer[2],0,2);
252 	TC0480SCP_tilemap_draw(bitmap,cliprect,layer[3],0,4);
253 	TC0480SCP_tilemap_draw(bitmap,cliprect,layer[4],0,8);	/* text layer */
254 	superchs_draw_sprites_16x16(bitmap,cliprect,primasks,48,-116);
255 #endif
256 }
257