1 /* Tao Taido Video Hardware */
2 
3 /*
4 
5 its similar to other video system games
6 
7 zooming might be wrong (only used on title logo?)
8 
9 */
10 
11 #include "driver.h"
12 
13 static data16_t taotaido_sprite_character_bank_select[8];
14 static data16_t taotaido_video_bank_select[8];
15 static struct tilemap *bg_tilemap;
16 
17 extern data16_t *taotaido_spriteram;
18 extern data16_t *taotaido_spriteram2;
19 extern data16_t *taotaido_scrollram;
20 extern data16_t *taotaido_bgram;
21 
22 static data16_t *taotaido_spriteram_old, *taotaido_spriteram_older;
23 static data16_t *taotaido_spriteram2_old, *taotaido_spriteram2_older;
24 
25 /* sprite tile codes 0x4000 - 0x7fff get remapped according to the content of these registers */
WRITE16_HANDLER(taotaido_sprite_character_bank_select_w)26 WRITE16_HANDLER( taotaido_sprite_character_bank_select_w )
27 {
28 	if(ACCESSING_MSB)
29 		taotaido_sprite_character_bank_select[offset*2] = data >> 8;
30 	if(ACCESSING_LSB)
31 		taotaido_sprite_character_bank_select[offset*2+1] = data &0xff;
32 }
33 
34 /* sprites are like the other video system / psikyo games, we can merge this with aerofgt and plenty of other
35    things eventually */
36 
taotaido_drawsprite(UINT16 spriteno,struct mame_bitmap * bitmap,const struct rectangle * cliprect)37 static void taotaido_drawsprite( UINT16 spriteno, struct mame_bitmap *bitmap, const struct rectangle *cliprect )
38 {
39 	/*- SPR RAM Format -**
40 
41 	  4 words per sprite
42 
43 	  zzzz sssp  pppp pppp (y zoom, y size, y position)
44 	  zzzz sssp  pppp pppp (x zoom, x size, x position)
45 	  yxpc cccc  ---- ---- (flipy, flipx, priority?, colour)
46 	  -nnn nnnn  nnnn nnnn (tile lookup)
47 
48 	*/
49 
50 	int x,y;
51 
52 	data16_t *source = &taotaido_spriteram_older[spriteno*4];
53 	const struct GfxElement *gfx = Machine->gfx[0];
54 
55 
56 	int yzoom = (source[0] & 0xf000) >> 12;
57 	int xzoom = (source[1] & 0xf000) >> 12;
58 
59 	int ysize = (source[0] & 0x0e00) >> 9;
60 	int xsize = (source[1] & 0x0e00) >> 9;
61 
62 	int ypos = source[0] & 0x01ff;
63 	int xpos = source[1] & 0x01ff;
64 
65 	int yflip = source[2] & 0x8000;
66 	int xflip = source[2] & 0x4000;
67 	int color = (source[2] & 0x1f00) >> 8;
68 
69 	int tile = source[3] & 0xffff;
70 
71 	xpos += (xsize*xzoom+2)/4;
72 	ypos += (ysize*yzoom+2)/4;
73 
74 	xzoom = 32 - xzoom;
75 	yzoom = 32 - yzoom;
76 
77 
78 	for (y = 0;y <= ysize;y++)
79 	{
80 		int sx,sy;
81 
82 		if (yflip) sy = ((ypos + yzoom * (ysize - y)/2 + 16) & 0x1ff) - 16;
83 			else sy = ((ypos + yzoom * y / 2 + 16) & 0x1ff) - 16;
84 
85 		for (x = 0;x <= xsize;x++)
86 		{
87 
88 			/* this indirection is a bit different to the other video system games */
89 			int realtile;
90 
91 			realtile = taotaido_spriteram2_older[tile];
92 
93 			if (realtile > 0x3fff)
94 			{
95 				int block;
96 
97 				block = (realtile & 0x3800)>>11;
98 
99 				realtile &= 0x07ff;
100 				realtile |= taotaido_sprite_character_bank_select[block] * 0x800;
101 			}
102 
103 			if (xflip) sx = ((xpos + xzoom * (xsize - x) / 2 + 16) & 0x1ff) - 16;
104 				else sx = ((xpos + xzoom * x / 2 + 16) & 0x1ff) - 16;
105 
106 
107 			drawgfxzoom(bitmap,gfx,
108 						realtile,
109 						color,
110 						xflip,yflip,
111 						sx,sy,
112 						cliprect,TRANSPARENCY_PEN,15,
113 						xzoom << 11, yzoom << 11);
114 
115 			tile++;
116 
117 		}
118 	}
119 }
120 
taotaido_drawsprites(struct mame_bitmap * bitmap,const struct rectangle * cliprect)121 static void taotaido_drawsprites( struct mame_bitmap *bitmap, const struct rectangle *cliprect )
122 {
123 	/* first part of sprite ram is the list of sprites to draw, terminated with 0x4000 */
124 	data16_t *source = taotaido_spriteram_older;
125 	data16_t *finish = taotaido_spriteram_older + 0x2000/2;
126 
127 	while( source<finish )
128 	{
129 
130 		if (source[0] == 0x4000) break;
131 
132 		taotaido_drawsprite(source[0]&0x3ff, bitmap, cliprect);
133 
134 		source++;
135 
136 	}
137 }
138 
139 
140 /* the tilemap */
141 
WRITE16_HANDLER(taotaido_tileregs_w)142 WRITE16_HANDLER( taotaido_tileregs_w )
143 {
144 	switch (offset)
145 	{
146 		case 0: // would normally be x scroll?
147 		case 1: // would normally be y scroll?
148 		case 2:
149 		case 3:
150 			logerror ("unhanded tilemap register write offset %02x data %04x \n",offset,data);
151 			break;
152 
153 		/* tile banks */
154 		case 4:
155 		case 5:
156 		case 6:
157 		case 7:
158 			if(ACCESSING_MSB)
159 				taotaido_video_bank_select[(offset-4)*2] = data >> 8;
160 			if(ACCESSING_LSB)
161 				taotaido_video_bank_select[(offset-4)*2+1] = data &0xff;
162 				tilemap_mark_all_tiles_dirty(bg_tilemap);
163 			break;
164 	}
165 }
166 
WRITE16_HANDLER(taotaido_bgvideoram_w)167 WRITE16_HANDLER( taotaido_bgvideoram_w )
168 {
169 	if (taotaido_bgram[offset] != data)
170 	{
171 		COMBINE_DATA(&taotaido_bgram[offset]);
172 		tilemap_mark_tile_dirty(bg_tilemap,offset);
173 	}
174 }
175 
taotaido_bg_tile_info(int tile_index)176 static void taotaido_bg_tile_info(int tile_index)
177 {
178 	int code = taotaido_bgram[tile_index]&0x01ff;
179 	int bank = (taotaido_bgram[tile_index]&0x0e00)>>9;
180 	int col  = (taotaido_bgram[tile_index]&0xf000)>>12;
181 
182 	code |= taotaido_video_bank_select[bank]*0x200;
183 
184 	SET_TILE_INFO(
185 			1,
186 			code,
187 			col,
188 			0)
189 }
190 
taotaido_tilemap_scan_rows(UINT32 col,UINT32 row,UINT32 num_cols,UINT32 num_rows)191 UINT32 taotaido_tilemap_scan_rows( UINT32 col, UINT32 row, UINT32 num_cols, UINT32 num_rows )
192 {
193 	/* logical (col,row) -> memory offset */
194 	return row*0x40 + (col&0x3f) + ((col&0x40)<<6);
195 }
196 
VIDEO_START(taotaido)197 VIDEO_START(taotaido)
198 {
199 	bg_tilemap = tilemap_create(taotaido_bg_tile_info,taotaido_tilemap_scan_rows,TILEMAP_OPAQUE,     16,16,128,64);
200 
201 	taotaido_spriteram_old = auto_malloc(0x2000);
202 	taotaido_spriteram_older = auto_malloc(0x2000);
203 
204 	taotaido_spriteram2_old = auto_malloc(0x10000);
205 	taotaido_spriteram2_older = auto_malloc(0x10000);
206 
207 	return 0;
208 }
209 
210 
VIDEO_UPDATE(taotaido)211 VIDEO_UPDATE(taotaido)
212 {
213 //	tilemap_set_scrollx(bg_tilemap,0,(taotaido_scrollram[0x380/2]>>4)); // the values put here end up being wrong every other frame
214 //	tilemap_set_scrolly(bg_tilemap,0,(taotaido_scrollram[0x382/2]>>4)); // the values put here end up being wrong every other frame
215 
216 	/* not amazingly efficient however it should be functional for row select and linescroll */
217 	int line;
218 	struct rectangle clip;
219 
220 	clip.min_x = Machine->visible_area.min_x;
221 	clip.max_x = Machine->visible_area.max_x;
222 	clip.min_y = Machine->visible_area.min_y;
223 	clip.max_y = Machine->visible_area.max_y;
224 
225 	for (line = 0; line < 224;line++)
226 	{
227 		clip.min_y = clip.max_y = line;
228 
229 		tilemap_set_scrollx(bg_tilemap,0,((taotaido_scrollram[(0x00+4*line)/2])>>4)+30);
230 		tilemap_set_scrolly(bg_tilemap,0,((taotaido_scrollram[(0x02+4*line)/2])>>4)-line);
231 
232 		tilemap_draw(bitmap,&clip,bg_tilemap,0,0);
233 	}
234 
235 	taotaido_drawsprites(bitmap,cliprect);
236 }
237 
VIDEO_EOF(taotaido)238 VIDEO_EOF( taotaido )
239 {
240 	/* sprites need to be delayed by 2 frames? */
241 
242 	memcpy(taotaido_spriteram2_older,taotaido_spriteram2_old,0x10000);
243 	memcpy(taotaido_spriteram2_old,taotaido_spriteram2,0x10000);
244 
245 	memcpy(taotaido_spriteram_older,taotaido_spriteram_old,0x2000);
246 	memcpy(taotaido_spriteram_old,taotaido_spriteram,0x2000);
247 }
248