1 /***************************************************************************
2
3 Video Hardware for Blood Brothers
4
5 ***************************************************************************/
6
7 #include "vidhrdw/generic.h"
8
9 #define NUM_SPRITES 128
10
11 unsigned char *textlayoutram;
12 static unsigned char *dirtybuffer2;
13 static struct osd_bitmap *tmpbitmap2;
14 extern unsigned char *dirtybuffer2;
15 unsigned char *bloodbro_videoram2;
16 unsigned char *bloodbro_scroll;
17 static struct sprite_list *sprite_list;
18
19
READ_HANDLER(bloodbro_background_r)20 READ_HANDLER( bloodbro_background_r ){
21 return READ_WORD (&videoram[offset]);
22 }
23
WRITE_HANDLER(bloodbro_background_w)24 WRITE_HANDLER( bloodbro_background_w ){
25 int oldword = READ_WORD(&videoram[offset]);
26 int newword = COMBINE_WORD(oldword,data);
27 if( oldword != newword ){
28 WRITE_WORD(&videoram[offset],newword);
29 dirtybuffer[offset/2] = 1;
30 }
31 }
32
READ_HANDLER(bloodbro_foreground_r)33 READ_HANDLER( bloodbro_foreground_r ){
34 return READ_WORD (&bloodbro_videoram2[offset]);
35 }
36
WRITE_HANDLER(bloodbro_foreground_w)37 WRITE_HANDLER( bloodbro_foreground_w ){
38 int oldword = READ_WORD(&bloodbro_videoram2[offset]);
39 int newword = COMBINE_WORD(oldword,data);
40 if( oldword != newword ){
41 WRITE_WORD(&bloodbro_videoram2[offset],newword);
42 dirtybuffer2[offset/2] = 1;
43 }
44 }
45
46 /**************************************************************************/
47
bloodbro_vh_stop(void)48 void bloodbro_vh_stop(void) {
49 if( tmpbitmap ) bitmap_free( tmpbitmap );
50 if( tmpbitmap2 ) bitmap_free( tmpbitmap2 );
51 free( dirtybuffer2 );
52 free( dirtybuffer );
53 }
54
bloodbro_vh_start(void)55 int bloodbro_vh_start(void) {
56 tmpbitmap = bitmap_alloc(512,256);
57 dirtybuffer = (unsigned char*)malloc(32*16);
58 tmpbitmap2 = bitmap_alloc(512,256);
59 dirtybuffer2 = (unsigned char*)malloc(32*16);
60 sprite_list = sprite_list_create( NUM_SPRITES, SPRITE_LIST_FRONT_TO_BACK );
61
62 if( tmpbitmap && tmpbitmap2 && dirtybuffer && dirtybuffer2 ){
63 memset( dirtybuffer, 1, 32*16 );
64 memset( dirtybuffer2, 1, 32*16 );
65 sprite_list->transparent_pen = 0xf;
66 sprite_list->max_priority = 1;
67 sprite_list->sprite_type = SPRITE_TYPE_STACK;
68 return 0;
69 }
70 bloodbro_vh_stop();
71 return 1;
72 }
73
74 /**************************************************************************/
75
draw_text(struct osd_bitmap * bitmap)76 static void draw_text( struct osd_bitmap *bitmap ){
77 const struct rectangle *clip = &Machine->visible_area;
78 const UINT16 *source = (const UINT16 *)textlayoutram;
79 int sx, sy;
80 for( sy=0; sy<32; sy++ ){
81 for( sx=0; sx<32; sx++ ){
82 UINT16 data = *source++;
83
84 drawgfx(bitmap,Machine->gfx[0],
85 data&0xfff, /* tile number */
86 data>>12, /* color */
87 0,0, /* no flip */
88 8*sx,8*sy,
89 clip,TRANSPARENCY_PEN,0xf);
90 }
91 }
92 }
93
draw_background(struct osd_bitmap * bitmap)94 static void draw_background( struct osd_bitmap *bitmap ) {
95 const struct GfxElement *gfx = Machine->gfx[1];
96 const UINT16 *source = (UINT16 *)videoram;
97 int offs;
98 for( offs=0; offs<32*16; offs++ ){
99 if( dirtybuffer[offs] ){
100 int sx = 16*(offs%32);
101 int sy = 16*(offs/32);
102 UINT16 data = source[offs];
103 dirtybuffer[offs] = 0;
104
105 drawgfx(tmpbitmap,gfx,
106 data&0xfff, /* tile number */
107 (data&0xf000)>>12, /* color */
108 0,0, /* no flip */
109 sx,sy,
110 0,TRANSPARENCY_NONE,0);
111 }
112 }
113 {
114 int scrollx = -READ_WORD( &bloodbro_scroll[0x20] ); /** ? **/
115 int scrolly = -READ_WORD( &bloodbro_scroll[0x22] ); /** ? **/
116
117 copyscrollbitmap(bitmap,tmpbitmap,
118 1,&scrollx,1,&scrolly,
119 &Machine->visible_area,
120 TRANSPARENCY_NONE,0);
121 }
122 }
123
draw_foreground(struct osd_bitmap * bitmap)124 static void draw_foreground( struct osd_bitmap *bitmap ) {
125 struct rectangle r;
126 const struct GfxElement *gfx = Machine->gfx[2];
127 const UINT16 *source = (UINT16 *)bloodbro_videoram2;
128 int offs;
129 for( offs=0; offs<32*16; offs++ ){
130 if( dirtybuffer2[offs] ){
131 int sx = 16*(offs%32);
132 int sy = 16*(offs/32);
133 UINT16 data = source[offs];
134 dirtybuffer2[offs] = 0;
135
136 /* Necessary to use TRANSPARENCY_PEN here */
137 r.min_x = sx; r.max_x = sx+15;
138 r.min_y = sy; r.max_y = sy+15;
139 fillbitmap(tmpbitmap2,0xf,&r);
140 /******************************************/
141
142 drawgfx( tmpbitmap2,gfx,
143 data&0xfff, /* tile number */
144 (data&0xf000)>>12, /* color */
145 0,0,
146 sx,sy,
147 0,TRANSPARENCY_PEN,0xf);
148 }
149 }
150 {
151 int scrollx = -READ_WORD( &bloodbro_scroll[0x24] );
152 int scrolly = -READ_WORD( &bloodbro_scroll[0x26] );
153
154 copyscrollbitmap(bitmap,tmpbitmap2,1,&scrollx,1,&scrolly,&Machine->visible_area,
155 TRANSPARENCY_PEN,0xf );
156 }
157 }
158
159 /* SPRITE INFO (8 bytes)
160
161 --F???SS SSSSCCCC
162 ---TTTTT TTTTTTTT
163 -------X XXXXXXXX
164 -------- YYYYYYYY */
get_sprite_info(void)165 static void get_sprite_info( void ){
166 const struct GfxElement *gfx = Machine->gfx[3];
167 const unsigned short *source = (const UINT16 *)spriteram;
168 struct sprite *sprite = sprite_list->sprite;
169 int count = NUM_SPRITES;
170
171 int attributes, flags, number, color, vertical_size, horizontal_size, i;
172 while( count-- ){
173 attributes = source[0];
174 flags = 0;
175 if( (attributes&0x8000)==0 ){
176 flags |= SPRITE_VISIBLE;
177 horizontal_size = 1 + ((attributes>>7)&7);
178 vertical_size = 1 + ((attributes>>4)&7);
179 sprite->priority = (attributes>>11)&1;
180 number = source[1]&0x1fff;
181 sprite->x = source[2]&0x1ff;
182 sprite->y = source[3]&0x1ff;
183
184 /* wraparound - could be handled by Sprite Manager?*/
185 if( sprite->x >= 256) sprite->x -= 512;
186 if( sprite->y >= 256) sprite->y -= 512;
187
188 sprite->total_width = 16*horizontal_size;
189 sprite->total_height = 16*vertical_size;
190
191 sprite->tile_width = 16;
192 sprite->tile_height = 16;
193 sprite->line_offset = 16;
194
195 if( attributes&0x2000 ) flags |= SPRITE_FLIPX;
196 if( attributes&0x4000 ) flags |= SPRITE_FLIPY; /* ? */
197 color = attributes&0xf;
198
199 sprite->pen_data = gfx->gfxdata + number * gfx->char_modulo;
200 sprite->pal_data = &gfx->colortable[gfx->color_granularity * color];
201
202 sprite->pen_usage = 0;
203 for( i=0; i<vertical_size*horizontal_size; i++ ){
204 sprite->pen_usage |= gfx->pen_usage[number++];
205 }
206 }
207 sprite->flags = flags;
208
209 sprite++;
210 source+=4;
211 }
212 }
213
bloodbro_mark_used_colors(void)214 static void bloodbro_mark_used_colors(void){
215 int offs,i;
216 int code, color, colmask[0x80];
217 int pal_base = Machine->drv->gfxdecodeinfo[0].color_codes_start;
218
219 /* Build the dynamic palette */
220 palette_init_used_colors();
221
222 /* Text layer */
223 pal_base = Machine->drv->gfxdecodeinfo[0].color_codes_start;
224 for (color = 0;color < 16;color++) colmask[color] = 0;
225 for (offs = 0;offs <0x800;offs += 2) {
226 code = READ_WORD(&textlayoutram[offs]);
227 color=code>>12;
228 if ((code&0xfff)==0xd) continue;
229 colmask[color] |= Machine->gfx[0]->pen_usage[code&0xfff];
230 }
231 for (color = 0;color < 16;color++)
232 {
233 for (i = 0;i < 15;i++)
234 {
235 if (colmask[color] & (1 << i))
236 palette_used_colors[pal_base + 16 * color + i] = PALETTE_COLOR_USED;
237 }
238 }
239
240 /* Tiles - bottom layer */
241 pal_base = Machine->drv->gfxdecodeinfo[1].color_codes_start;
242 for (offs=0; offs<256; offs++)
243 palette_used_colors[pal_base + offs] = PALETTE_COLOR_USED;
244
245 /* Tiles - top layer */
246 pal_base = Machine->drv->gfxdecodeinfo[2].color_codes_start;
247 for (color = 0;color < 16;color++) colmask[color] = 0;
248 for (offs = 0x0000;offs <0x400;offs += 2 )
249 {
250 code = READ_WORD(&bloodbro_videoram2[offs]);
251 color= code>>12;
252 colmask[color] |= Machine->gfx[2]->pen_usage[code&0xfff];
253 }
254
255 for (color = 0;color < 16;color++){
256 for (i = 0;i < 15;i++)
257 {
258 if (colmask[color] & (1 << i))
259 palette_used_colors[pal_base + 16 * color + i] = PALETTE_COLOR_USED;
260 }
261 /* kludge */
262 palette_used_colors[pal_base + 16 * color +15] = PALETTE_COLOR_TRANSPARENT;
263 palette_change_color(pal_base + 16 * color +15 ,0,0,0);
264 }
265 }
266
bloodbro_vh_screenrefresh(struct osd_bitmap * bitmap,int fullrefresh)267 void bloodbro_vh_screenrefresh( struct osd_bitmap *bitmap, int fullrefresh ){
268 get_sprite_info();
269
270 bloodbro_mark_used_colors();
271 sprite_update();
272
273 if (palette_recalc()) {
274 memset(dirtybuffer,1,32*16);
275 memset(dirtybuffer2,1,32*16);
276 }
277
278 draw_background( bitmap );
279 sprite_draw( sprite_list, 1 );
280 draw_foreground( bitmap );
281 sprite_draw( sprite_list, 0 );
282 draw_text( bitmap );
283 }
284
285 /* SPRITE INFO (8 bytes)
286
287 -------- YYYYYYYY
288 ---TTTTT TTTTTTTT
289 CCCC--F? -?--???? Priority??
290 -------X XXXXXXXX
291 */
292
weststry_draw_sprites(struct osd_bitmap * bitmap,int priority)293 static void weststry_draw_sprites( struct osd_bitmap *bitmap, int priority) {
294 int offs;
295 for( offs = 0x800-8; offs > 0; offs-=8 ){
296 int data = READ_WORD( &spriteram[offs+4] );
297 int data0 = READ_WORD( &spriteram[offs+0] );
298 int tile_number = READ_WORD( &spriteram[offs+2] )&0x1fff;
299 int sx = READ_WORD( &spriteram[offs+6] )&0xff;
300 int sy = 0xf0-(data0&0xff);
301 int flipx = (data&0x200)>>9;
302 int datax = (READ_WORD( &spriteram[offs+6] )&0x100);
303 int color = (data&0xf000)>>12;
304
305 /* Remap sprites */
306 switch(tile_number&0x1800) {
307 case 0x0000: break;
308 case 0x0800: tile_number = (tile_number&0x7ff) | 0x1000; break;
309 case 0x1000: tile_number = (tile_number&0x7ff) | 0x800; break;
310 case 0x1800: break;
311 }
312
313 if ((!(data0&0x8000)) && (!datax)) {
314 drawgfx(bitmap,Machine->gfx[3],
315 tile_number, color, flipx,0,
316 sx,sy,
317 &Machine->visible_area,TRANSPARENCY_PEN,0xf);
318 }
319 }
320 }
321
weststry_mark_used_colors(void)322 static void weststry_mark_used_colors(void){
323 int offs,i;
324 int colmask[0x80],code,pal_base,color;
325
326 /* Build the dynamic palette */
327 palette_init_used_colors();
328
329 /* Text layer */
330 pal_base = Machine->drv->gfxdecodeinfo[0].color_codes_start;
331 for (color = 0;color < 16;color++) colmask[color] = 0;
332 for (offs = 0;offs <0x800;offs += 2) {
333 code = READ_WORD(&textlayoutram[offs]);
334 color=code>>12;
335 if ((code&0xfff)==0xd) continue;
336 colmask[color] |= Machine->gfx[0]->pen_usage[code&0xfff];
337 }
338 for (color = 0;color < 16;color++)
339 {
340 for (i = 0;i < 15;i++)
341 {
342 if (colmask[color] & (1 << i))
343 palette_used_colors[pal_base + 16 * color + i] = PALETTE_COLOR_USED;
344 }
345 }
346
347 /* Tiles - bottom layer */
348 pal_base = Machine->drv->gfxdecodeinfo[1].color_codes_start;
349 for (offs=0; offs<256; offs++)
350 palette_used_colors[pal_base + offs] = PALETTE_COLOR_USED;
351
352 /* Tiles - top layer */
353 pal_base = Machine->drv->gfxdecodeinfo[2].color_codes_start;
354 for (color = 0;color < 16;color++) colmask[color] = 0;
355 for (offs = 0x0000;offs <0x400;offs += 2 )
356 {
357 code = READ_WORD(&bloodbro_videoram2[offs]);
358 color= code>>12;
359 colmask[color] |= Machine->gfx[2]->pen_usage[code&0xfff];
360 }
361 for (color = 0;color < 16;color++)
362 {
363 for (i = 0;i < 15;i++)
364 {
365 if (colmask[color] & (1 << i))
366 palette_used_colors[pal_base + 16 * color + i] = PALETTE_COLOR_USED;
367 }
368
369 /* kludge */
370 palette_used_colors[pal_base + 16 * color +15] = PALETTE_COLOR_TRANSPARENT;
371 palette_change_color(pal_base + 16 * color +15 ,0,0,0);
372 }
373
374 /* Sprites */
375 pal_base = Machine->drv->gfxdecodeinfo[3].color_codes_start;
376 for (color = 0;color < 16;color++) colmask[color] = 0;
377 for (offs = 0;offs <0x800;offs += 8 )
378 {
379 color = READ_WORD(&spriteram[offs+4])>>12;
380 code = READ_WORD(&spriteram[offs+2])&0x1fff;
381 /* Remap code 0x800 <-> 0x1000 */
382 code = (code&0x7ff) | ((code&0x800)<<1) | ((code&0x1000)>>1);
383
384 colmask[color] |= Machine->gfx[3]->pen_usage[code];
385 }
386 for (color = 0;color < 16;color++)
387 {
388 for (i = 0;i < 15;i++)
389 {
390 if (colmask[color] & (1 << i))
391 palette_used_colors[pal_base + 16 * color + i] = PALETTE_COLOR_USED;
392 }
393 }
394
395 if (palette_recalc()) {
396 memset(dirtybuffer,1,32*16);
397 memset(dirtybuffer2,1,32*16);
398 }
399 }
400
weststry_vh_screenrefresh(struct osd_bitmap * bitmap,int fullrefresh)401 void weststry_vh_screenrefresh( struct osd_bitmap *bitmap, int fullrefresh ){
402 weststry_mark_used_colors();
403
404 draw_background( bitmap );
405 //weststry_draw_sprites(bitmap,0);
406 draw_foreground( bitmap );
407 weststry_draw_sprites(bitmap,1);
408 draw_text( bitmap );
409 }
410
411