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