~ubuntu-branches/ubuntu/karmic/xmame/karmic

« back to all changes in this revision

Viewing changes to src/vidhrdw/mcr.c

  • Committer: Bazaar Package Importer
  • Author(s): Bruno Barrera C.
  • Date: 2007-02-16 10:06:54 UTC
  • mfrom: (2.1.5 edgy)
  • Revision ID: james.westby@ubuntu.com-20070216100654-iztas2cl47k5j039
Tags: 0.106-2
* Added Italian debconf templates translation. (closes: #382672)
* Added German debconf templates translation. (closes: #396610)
* Added Japanese debconf templates translation. (closes: #400011)
* Added Portuguese debconf templates translation. (closes: #409960)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/***************************************************************************
 
2
 
 
3
    Midway MCR systems
 
4
 
 
5
***************************************************************************/
 
6
 
 
7
#include "driver.h"
 
8
#include "mcr.h"
 
9
 
 
10
 
 
11
INT8 mcr12_sprite_xoffs;
 
12
INT8 mcr12_sprite_xoffs_flip;
 
13
 
 
14
static tilemap *bg_tilemap;
 
15
 
 
16
 
 
17
/*************************************
 
18
 *
 
19
 *  Tilemap callbacks
 
20
 *
 
21
 *************************************/
 
22
 
 
23
/*
 
24
    The 90009 board uses 1 byte per tile:
 
25
 
 
26
    Byte 0:
 
27
        pppppppp = picture index
 
28
 */
 
29
static void mcr_90009_get_tile_info(int tile_index)
 
30
{
 
31
        SET_TILE_INFO(0, videoram[tile_index], 0, 0);
 
32
 
 
33
        /* sprite color base is constant 0x10 */
 
34
        tile_info.priority = 1;
 
35
}
 
36
 
 
37
 
 
38
/*
 
39
    The 90010 board uses 2 adjacent bytes per tile:
 
40
 
 
41
    Byte 0:
 
42
        pppppppp = picture index (low 8 bits)
 
43
 
 
44
    Byte 1:
 
45
        ss------ = sprite palette bank
 
46
        ---cc--- = tile palette bank
 
47
        -----y-- = Y flip
 
48
        ------x- = X flip
 
49
        -------p = picture index (high 1 bit)
 
50
 */
 
51
static void mcr_90010_get_tile_info(int tile_index)
 
52
{
 
53
        int data = videoram[tile_index * 2] | (videoram[tile_index * 2 + 1] << 8);
 
54
        int code = data & 0x1ff;
 
55
        int color = (data >> 11) & 3;
 
56
        SET_TILE_INFO(0, code, color, TILE_FLIPYX((data >> 9) & 3));
 
57
 
 
58
        /* sprite color base comes from the top 2 bits */
 
59
        tile_info.priority = (data >> 14) & 3;
 
60
}
 
61
 
 
62
 
 
63
/*
 
64
    The 91490 board uses 2 adjacent bytes per tile:
 
65
 
 
66
    Byte 0:
 
67
        pppppppp = picture index (low 8 bits)
 
68
 
 
69
    Byte 1:
 
70
        ss------ = sprite palette bank (can be disabled via jumpers)
 
71
        --cc---- = tile palette bank
 
72
        ----y--- = Y flip
 
73
        -----x-- = X flip
 
74
        ------pp = picture index (high 2 bits)
 
75
 */
 
76
static void mcr_91490_get_tile_info(int tile_index)
 
77
{
 
78
        int data = videoram[tile_index * 2] | (videoram[tile_index * 2 + 1] << 8);
 
79
        int code = data & 0x3ff;
 
80
        int color = (data >> 12) & 3;
 
81
        SET_TILE_INFO(0, code, color, TILE_FLIPYX((data >> 10) & 3));
 
82
 
 
83
        /* sprite color base might come from the top 2 bits */
 
84
        tile_info.priority = (data >> 14) & 3;
 
85
}
 
86
 
 
87
 
 
88
 
 
89
/*************************************
 
90
 *
 
91
 *  Common video startup/shutdown
 
92
 *
 
93
 *************************************/
 
94
 
 
95
VIDEO_START( mcr )
 
96
{
 
97
        /* the tilemap callback is based on the CPU board */
 
98
        switch (mcr_cpu_board)
 
99
        {
 
100
                case 90009:
 
101
                        bg_tilemap = tilemap_create(mcr_90009_get_tile_info, tilemap_scan_rows, TILEMAP_OPAQUE, 16,16, 32,30);
 
102
                        break;
 
103
 
 
104
                case 90010:
 
105
                        bg_tilemap = tilemap_create(mcr_90010_get_tile_info, tilemap_scan_rows, TILEMAP_OPAQUE, 16,16, 32,30);
 
106
                        break;
 
107
 
 
108
                case 91475:
 
109
                        bg_tilemap = tilemap_create(mcr_90010_get_tile_info, tilemap_scan_rows, TILEMAP_OPAQUE, 16,16, 32,30);
 
110
                        break;
 
111
 
 
112
                case 91490:
 
113
                        bg_tilemap = tilemap_create(mcr_91490_get_tile_info, tilemap_scan_rows, TILEMAP_OPAQUE, 16,16, 32,30);
 
114
                        break;
 
115
        }
 
116
        if (!bg_tilemap)
 
117
                return 1;
 
118
        return 0;
 
119
}
 
120
 
 
121
 
 
122
 
 
123
/*************************************
 
124
 *
 
125
 *  Palette RAM writes
 
126
 *
 
127
 *************************************/
 
128
 
 
129
static void mcr_set_color(int index, int data)
 
130
{
 
131
        /* 3 bits each, RGB */
 
132
        int r = (data >> 6) & 7;
 
133
        int g = (data >> 0) & 7;
 
134
        int b = (data >> 3) & 7;
 
135
 
 
136
        /* up to 8 bits */
 
137
        r = (r << 5) | (r << 2) | (r >> 1);
 
138
        g = (g << 5) | (g << 2) | (g >> 1);
 
139
        b = (b << 5) | (b << 2) | (b >> 1);
 
140
 
 
141
        /* set the color */
 
142
        palette_set_color(index, r, g, b);
 
143
}
 
144
 
 
145
 
 
146
static void journey_set_color(int index, int data)
 
147
{
 
148
        /* 3 bits each, RGB */
 
149
        int r = (data >> 6) & 7;
 
150
        int g = (data >> 0) & 7;
 
151
        int b = (data >> 3) & 7;
 
152
 
 
153
        /* up to 8 bits */
 
154
        r = (r << 5) | (r << 1);
 
155
        g = (g << 5) | (g << 1);
 
156
        b = (b << 5) | (b << 1);
 
157
 
 
158
        /* set the BG color */
 
159
        palette_set_color(index, r, g, b);
 
160
 
 
161
        /* if this is an odd entry in the upper palette bank, the hardware */
 
162
        /* hard-codes a low 1 bit -- this is used for better grayscales */
 
163
        if ((index & 0x31) == 0x31)
 
164
        {
 
165
                r |= 0x11;
 
166
                g |= 0x11;
 
167
                b |= 0x11;
 
168
        }
 
169
 
 
170
        /* set the FG color */
 
171
        palette_set_color(index + 64, r, g, b);
 
172
}
 
173
 
 
174
 
 
175
WRITE8_HANDLER( mcr_91490_paletteram_w )
 
176
{
 
177
        paletteram[offset] = data;
 
178
        offset &= 0x7f;
 
179
        mcr_set_color((offset / 2) & 0x3f, data | ((offset & 1) << 8));
 
180
}
 
181
 
 
182
 
 
183
 
 
184
/*************************************
 
185
 *
 
186
 *  Video RAM writes
 
187
 *
 
188
 *************************************/
 
189
 
 
190
WRITE8_HANDLER( mcr_90009_videoram_w )
 
191
{
 
192
        videoram[offset] = data;
 
193
        tilemap_mark_tile_dirty(bg_tilemap, offset);
 
194
}
 
195
 
 
196
 
 
197
WRITE8_HANDLER( mcr_90010_videoram_w )
 
198
{
 
199
        videoram[offset] = data;
 
200
        tilemap_mark_tile_dirty(bg_tilemap, offset / 2);
 
201
 
 
202
        /* palette RAM is mapped into the upper 0x80 bytes here */
 
203
        if ((offset & 0x780) == 0x780)
 
204
        {
 
205
                if (mcr_cpu_board != 91475)
 
206
                        mcr_set_color((offset / 2) & 0x3f, data | ((offset & 1) << 8));
 
207
                else
 
208
                        journey_set_color((offset / 2) & 0x3f, data | ((offset & 1) << 8));
 
209
        }
 
210
}
 
211
 
 
212
 
 
213
READ8_HANDLER( twotiger_videoram_r )
 
214
{
 
215
        /* Two Tigers swizzles the address bits on videoram */
 
216
        int effoffs = ((offset << 1) & 0x7fe) | ((offset >> 10) & 1);
 
217
        return videoram[effoffs];
 
218
}
 
219
 
 
220
WRITE8_HANDLER( twotiger_videoram_w )
 
221
{
 
222
        /* Two Tigers swizzles the address bits on videoram */
 
223
        int effoffs = ((offset << 1) & 0x7fe) | ((offset >> 10) & 1);
 
224
 
 
225
        videoram[effoffs] = data;
 
226
        tilemap_mark_tile_dirty(bg_tilemap, effoffs / 2);
 
227
 
 
228
        /* palette RAM is mapped into the upper 0x80 bytes here */
 
229
        if ((effoffs & 0x780) == 0x780)
 
230
                mcr_set_color(((offset & 0x400) >> 5) | ((offset >> 1) & 0x1f), data | ((offset & 1) << 8));
 
231
}
 
232
 
 
233
 
 
234
WRITE8_HANDLER( mcr_91490_videoram_w )
 
235
{
 
236
        videoram[offset] = data;
 
237
        tilemap_mark_tile_dirty(bg_tilemap, offset / 2);
 
238
}
 
239
 
 
240
 
 
241
 
 
242
/*************************************
 
243
 *
 
244
 *  91399 Video Gen sprite renderer
 
245
 *
 
246
 *  Paired with:
 
247
 *      90009 CPU -> fixed palette @ 1
 
248
 *      90010 CPU -> palette specified by tiles
 
249
 *
 
250
 *************************************/
 
251
 
 
252
static void render_sprites_91399(mame_bitmap *bitmap, const rectangle *cliprect)
 
253
{
 
254
        const gfx_element *gfx = Machine->gfx[1];
 
255
        int offs;
 
256
 
 
257
        /* render the sprites into the bitmap, ORing together */
 
258
        for (offs = 0; offs < spriteram_size; offs += 4)
 
259
        {
 
260
                int code, x, y, sx, sy, hflip, vflip;
 
261
 
 
262
                /* extract the bits of information */
 
263
                code = spriteram[offs + 1] & 0x3f;
 
264
                hflip = (spriteram[offs + 1] & 0x40) ? 31 : 0;
 
265
                vflip = (spriteram[offs + 1] & 0x80) ? 31 : 0;
 
266
                sx = (spriteram[offs + 2] - 4) * 2;
 
267
                sy = (240 - spriteram[offs]) * 2;
 
268
 
 
269
                /* apply cocktail mode */
 
270
                if (mcr_cocktail_flip)
 
271
                {
 
272
                        hflip ^= 31;
 
273
                        vflip ^= 31;
 
274
                        sx = 466 - sx + mcr12_sprite_xoffs_flip;
 
275
                        sy = 450 - sy;
 
276
                }
 
277
                else
 
278
                        sx += mcr12_sprite_xoffs;
 
279
 
 
280
                /* clamp within 512 */
 
281
                sx &= 0x1ff;
 
282
                sy &= 0x1ff;
 
283
 
 
284
                /* loop over lines in the sprite */
 
285
                for (y = 0; y < 32; y++, sy = (sy + 1) & 0x1ff)
 
286
                        if (sy >= cliprect->min_y && sy <= cliprect->max_y)
 
287
                        {
 
288
                                UINT8 *src = gfx->gfxdata + gfx->char_modulo * code + gfx->line_modulo * (y ^ vflip);
 
289
                                UINT16 *dst = (UINT16 *)bitmap->line[sy];
 
290
                                UINT8 *pri = priority_bitmap->line[sy];
 
291
 
 
292
                                /* loop over columns */
 
293
                                for (x = 0; x < 32; x++)
 
294
                                {
 
295
                                        int tx = (sx + x) & 0x1ff;
 
296
                                        int pix = pri[tx] | src[x ^ hflip];
 
297
 
 
298
                                        /* update the effective sprite pixel */
 
299
                                        pri[tx] = pix;
 
300
 
 
301
                                        /* only draw if the low 3 bits are set */
 
302
                                        if (pix & 0x07)
 
303
                                                dst[tx] = pix;
 
304
                                }
 
305
                        }
 
306
        }
 
307
}
 
308
 
 
309
 
 
310
 
 
311
/*************************************
 
312
 *
 
313
 *  91464 Super Video Gen sprite renderer
 
314
 *
 
315
 *  Paired with:
 
316
 *      91442 CPU -> fixed palette @ 1 (upper half) or 3 (lower half)
 
317
 *      91475 CPU -> palette specified by sprite board; sprites have extra implicit colors
 
318
 *      91490 CPU -> palette specified by sprite board or by tiles (select via jumpers)
 
319
 *      91721 CPU -> palette specified by sprite board
 
320
 *
 
321
 *************************************/
 
322
 
 
323
static void render_sprites_91464(mame_bitmap *bitmap, const rectangle *cliprect, int primask, int sprmask, int colormask)
 
324
{
 
325
        const gfx_element *gfx = Machine->gfx[1];
 
326
        int offs;
 
327
 
 
328
        /* render the sprites into the bitmap, working from topmost to bottommost */
 
329
        for (offs = spriteram_size - 4; offs >= 0; offs -= 4)
 
330
        {
 
331
                int code, color, x, y, sx, sy, hflip, vflip;
 
332
 
 
333
                /* extract the bits of information */
 
334
                code = (spriteram[offs + 2] + 256 * ((spriteram[offs + 1] >> 3) & 0x01)) % gfx->total_elements;
 
335
                color = (((~spriteram[offs + 1] & 3) << 4) & sprmask) | colormask;
 
336
                hflip = (spriteram[offs + 1] & 0x10) ? 31 : 0;
 
337
                vflip = (spriteram[offs + 1] & 0x20) ? 31 : 0;
 
338
                sx = (spriteram[offs + 3] - 3) * 2;
 
339
                sy = (241 - spriteram[offs]) * 2;
 
340
 
 
341
                /* apply cocktail mode */
 
342
                if (mcr_cocktail_flip)
 
343
                {
 
344
                        hflip ^= 31;
 
345
                        vflip ^= 31;
 
346
                        sx = 480 - sx;
 
347
                        sy = 452 - sy;
 
348
                }
 
349
 
 
350
                /* clamp within 512 */
 
351
                sx &= 0x1ff;
 
352
                sy &= 0x1ff;
 
353
 
 
354
                /* loop over lines in the sprite */
 
355
                for (y = 0; y < 32; y++, sy = (sy + 1) & 0x1ff)
 
356
                        if (sy >= cliprect->min_y && sy <= cliprect->max_y)
 
357
                        {
 
358
                                UINT8 *src = gfx->gfxdata + gfx->char_modulo * code + gfx->line_modulo * (y ^ vflip);
 
359
                                UINT16 *dst = (UINT16 *)bitmap->line[sy];
 
360
                                UINT8 *pri = priority_bitmap->line[sy];
 
361
 
 
362
                                /* loop over columns */
 
363
                                for (x = 0; x < 32; x++)
 
364
                                {
 
365
                                        int tx = (sx + x) & 0x1ff;
 
366
                                        int pix = pri[tx];
 
367
                                        if (pix != 0xff)
 
368
                                        {
 
369
                                                /* compute the final value */
 
370
                                                pix = (pix & primask) | color | src[x ^ hflip];
 
371
 
 
372
                                                /* if non-zero, draw */
 
373
                                                if (pix & 0x0f)
 
374
                                                {
 
375
                                                        /* mark this pixel so we don't draw there again */
 
376
                                                        pri[tx] = 0xff;
 
377
 
 
378
                                                        /* only draw if the low 3 bits are set */
 
379
                                                        if (pix & 0x07)
 
380
                                                                dst[tx] = pix;
 
381
                                                }
 
382
                                        }
 
383
                                }
 
384
                        }
 
385
        }
 
386
}
 
387
 
 
388
 
 
389
 
 
390
/*************************************
 
391
 *
 
392
 *  Main refresh routines
 
393
 *
 
394
 *************************************/
 
395
 
 
396
VIDEO_UPDATE( mcr )
 
397
{
 
398
        /* update the flip state */
 
399
        tilemap_set_flip(bg_tilemap, mcr_cocktail_flip ? (TILEMAP_FLIPX | TILEMAP_FLIPY) : 0);
 
400
 
 
401
        /* draw the background */
 
402
        fillbitmap(priority_bitmap, 0, cliprect);
 
403
        tilemap_draw(bitmap, cliprect, bg_tilemap, 0, 0x00);
 
404
        tilemap_draw(bitmap, cliprect, bg_tilemap, 1, 0x10);
 
405
        tilemap_draw(bitmap, cliprect, bg_tilemap, 2, 0x20);
 
406
        tilemap_draw(bitmap, cliprect, bg_tilemap, 3, 0x30);
 
407
 
 
408
        /* update the sprites and render them */
 
409
        switch (mcr_sprite_board)
 
410
        {
 
411
                case 91399:
 
412
                        render_sprites_91399(bitmap, cliprect);
 
413
                        break;
 
414
 
 
415
                case 91464:
 
416
                        if (mcr_cpu_board == 91442)
 
417
                                render_sprites_91464(bitmap, cliprect, 0x00, 0x30, 0x00);
 
418
                        else if (mcr_cpu_board == 91475)
 
419
                                render_sprites_91464(bitmap, cliprect, 0x00, 0x30, 0x40);
 
420
                        else if (mcr_cpu_board == 91490)
 
421
                                render_sprites_91464(bitmap, cliprect, 0x00, 0x30, 0x00);
 
422
                        else if (mcr_cpu_board == 91721)
 
423
                                render_sprites_91464(bitmap, cliprect, 0x00, 0x30, 0x00);
 
424
                        break;
 
425
        }
 
426
}