summaryrefslogtreecommitdiffstatshomepage
path: root/src/mame/video/darkseal.c
blob: 525942e7d46141e9bf0b552d657b0c925abd744d (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
/***************************************************************************

   Dark Seal Video emulation - Bryan McPhail, mish@tendril.co.uk

****************************************************************************

Data East custom chip 55:  Generates two playfields, playfield 1 is underneath
playfield 2.  Dark Seal uses two of these chips.  1 playfield is _always_ off
in this game.

    16 bytes of control registers per chip.

    Word 0:
        Mask 0x0080: Flip screen
        Mask 0x007f: ?
    Word 2:
        Mask 0xffff: Playfield 2 X scroll (top playfield)
    Word 4:
        Mask 0xffff: Playfield 2 Y scroll (top playfield)
    Word 6:
        Mask 0xffff: Playfield 1 X scroll (bottom playfield)
    Word 8:
        Mask 0xffff: Playfield 1 Y scroll (bottom playfield)
    Word 0xa:
        Mask 0xc000: Playfield 1 shape??
        Mask 0x3000: Playfield 1 rowscroll style (maybe mask 0x3800??)
        Mask 0x0300: Playfield 1 colscroll style (maybe mask 0x0700??)?

        Mask 0x00c0: Playfield 2 shape??
        Mask 0x0030: Playfield 2 rowscroll style (maybe mask 0x0038??)
        Mask 0x0003: Playfield 2 colscroll style (maybe mask 0x0007??)?
    Word 0xc:
        Mask 0x8000: Playfield 1 is 8*8 tiles else 16*16
        Mask 0x4000: Playfield 1 rowscroll enabled
        Mask 0x2000: Playfield 1 colscroll enabled
        Mask 0x1f00: ?

        Mask 0x0080: Playfield 2 is 8*8 tiles else 16*16
        Mask 0x0040: Playfield 2 rowscroll enabled
        Mask 0x0020: Playfield 2 colscroll enabled
        Mask 0x001f: ?
    Word 0xe:
        ??

Locations 0 & 0xe are mostly unknown:

                             0      14
Caveman Ninja (bottom):     0053    1100 (changes to 1111 later)
Caveman Ninja (top):        0010    0081
Two Crude (bottom):         0053    0000
Two Crude (top):            0010    0041
Dark Seal (bottom):         0010    0000
Dark Seal (top):            0053    4101
Tumblepop:                  0010    0000
Super Burger Time:          0010    0000

Location 0xe looks like it could be a mirror of another byte..

**************************************************************************

Sprites - Data East custom chip 52

    8 bytes per sprite, unknowns bits seem unused.

    Word 0:
        Mask 0x8000 - ?
        Mask 0x4000 - Y flip
        Mask 0x2000 - X flip
        Mask 0x1000 - Sprite flash
        Mask 0x0800 - ?
        Mask 0x0600 - Sprite height (1x, 2x, 4x, 8x)
        Mask 0x01ff - Y coordinate

    Word 2:
        Mask 0xffff - Sprite number

    Word 4:
        Mask 0x8000 - ?
        Mask 0x4000 - Sprite is drawn beneath top 8 pens of playfield 4
        Mask 0x3e00 - Colour (32 palettes, most games only use 16)
        Mask 0x01ff - X coordinate

    Word 6:
        Always unused.

***************************************************************************/

#include "driver.h"

UINT16 *darkseal_pf12_row,*darkseal_pf34_row;
UINT16 *darkseal_pf1_data,*darkseal_pf2_data,*darkseal_pf3_data;

static UINT16 darkseal_control_0[8];
static UINT16 darkseal_control_1[8];

static tilemap *pf1_tilemap,*pf2_tilemap,*pf3_tilemap;
static int flipscreen;

/***************************************************************************/

/* Function for all 16x16 1024x1024 layers */
static TILEMAP_MAPPER( darkseal_scan )
{
	/* logical (col,row) -> memory offset */
	return (col & 0x1f) + ((row & 0x1f) << 5) + ((col & 0x20) << 5) + ((row & 0x20) << 6);
}

INLINE void get_bg_tile_info(running_machine *machine,tile_data *tileinfo,int tile_index,int gfx_bank,UINT16 *gfx_base)
{
	int tile,color;

	tile=gfx_base[tile_index];
	color=tile >> 12;
	tile=tile&0xfff;

	SET_TILE_INFO(
			gfx_bank,
			tile,
			color,
			0);
}

static TILE_GET_INFO( get_bg_tile_info2 ) { get_bg_tile_info(machine,tileinfo,tile_index,1,darkseal_pf2_data); }
static TILE_GET_INFO( get_bg_tile_info3 ) { get_bg_tile_info(machine,tileinfo,tile_index,2,darkseal_pf3_data); }

static TILE_GET_INFO( get_fg_tile_info )
{
	int tile=darkseal_pf1_data[tile_index];
	int color=tile >> 12;

	tile=tile&0xfff;
	SET_TILE_INFO(
			0,
			tile,
			color,
			0);
}

/******************************************************************************/

static void update_24bitcol(int offset)
{
	int r,g,b;

	r = (paletteram16[offset] >> 0) & 0xff;
	g = (paletteram16[offset] >> 8) & 0xff;
	b = (paletteram16_2[offset] >> 0) & 0xff;

	palette_set_color(Machine,offset,MAKE_RGB(r,g,b));
}

WRITE16_HANDLER( darkseal_palette_24bit_rg_w )
{
	COMBINE_DATA(&paletteram16[offset]);
	update_24bitcol(offset);
}

WRITE16_HANDLER( darkseal_palette_24bit_b_w )
{
	COMBINE_DATA(&paletteram16_2[offset]);
	update_24bitcol(offset);
}

/******************************************************************************/

static void draw_sprites(running_machine* machine, mame_bitmap *bitmap, const rectangle *cliprect)
{
	int offs;

	for (offs = 0;offs < 0x400;offs += 4)
	{
		int x,y,sprite,colour,multi,fx,fy,inc,flash,mult;

		sprite = buffered_spriteram16[offs+1] & 0x1fff;
		if (!sprite) continue;

		y = buffered_spriteram16[offs];
		x = buffered_spriteram16[offs+2];

		flash=y&0x1000;
		if (flash && (cpu_getcurrentframe() & 1)) continue;

		colour = (x >> 9) &0x1f;

		fx = y & 0x2000;
		fy = y & 0x4000;
		multi = (1 << ((y & 0x0600) >> 9)) - 1;	/* 1x, 2x, 4x, 8x height */

		x = x & 0x01ff;
		y = y & 0x01ff;
		if (x >= 256) x -= 512;
		if (y >= 256) y -= 512;
		x = 240 - x;
		y = 240 - y;

		if (x>256) continue; /* Speedup */

		sprite &= ~multi;
		if (fy)
			inc = -1;
		else
		{
			sprite += multi;
			inc = 1;
		}

		if (flipscreen)
		{
			y=240-y;
			x=240-x;
			if (fx) fx=0; else fx=1;
			if (fy) fy=0; else fy=1;
			mult=16;
		}
		else mult=-16;

		while (multi >= 0)
		{
			drawgfx(bitmap,machine->gfx[3],
					sprite - multi * inc,
					colour,
					fx,fy,
					x,y + mult * multi,
					cliprect,TRANSPARENCY_PEN,0);

			multi--;
		}
	}
}

/******************************************************************************/

WRITE16_HANDLER( darkseal_pf1_data_w )
{
	COMBINE_DATA(&darkseal_pf1_data[offset]);
	tilemap_mark_tile_dirty(pf1_tilemap,offset);
}

WRITE16_HANDLER( darkseal_pf2_data_w )
{
	COMBINE_DATA(&darkseal_pf2_data[offset]);
	tilemap_mark_tile_dirty(pf2_tilemap,offset);
}

WRITE16_HANDLER( darkseal_pf3_data_w )
{
	COMBINE_DATA(&darkseal_pf3_data[offset]);
	tilemap_mark_tile_dirty(pf3_tilemap,offset);
}

WRITE16_HANDLER( darkseal_pf3b_data_w ) /* Mirror */
{
	darkseal_pf3_data_w(offset+0x800,data,mem_mask);
}

WRITE16_HANDLER( darkseal_control_0_w )
{
	COMBINE_DATA(&darkseal_control_0[offset]);
}

WRITE16_HANDLER( darkseal_control_1_w )
{
	COMBINE_DATA(&darkseal_control_1[offset]);
}

/******************************************************************************/

VIDEO_START( darkseal )
{
	pf1_tilemap = tilemap_create(get_fg_tile_info, tilemap_scan_rows,TILEMAP_TYPE_PEN, 8, 8,64,64);
	pf2_tilemap = tilemap_create(get_bg_tile_info2,darkseal_scan,    TILEMAP_TYPE_PEN,16,16,64,64);
	pf3_tilemap = tilemap_create(get_bg_tile_info3,darkseal_scan,    TILEMAP_TYPE_PEN,     16,16,64,64);

	tilemap_set_transparent_pen(pf1_tilemap,0);
	tilemap_set_transparent_pen(pf2_tilemap,0);
}

/******************************************************************************/

VIDEO_UPDATE( darkseal )
{
	flipscreen=!(darkseal_control_0[0]&0x80);
	tilemap_set_flip(ALL_TILEMAPS,flipscreen ? (TILEMAP_FLIPY | TILEMAP_FLIPX) : 0);

	/* Update scroll registers */
	tilemap_set_scrollx( pf1_tilemap,0, darkseal_control_1[3] );
	tilemap_set_scrolly( pf1_tilemap,0, darkseal_control_1[4] );
	tilemap_set_scrollx( pf2_tilemap,0, darkseal_control_1[1]);
	tilemap_set_scrolly( pf2_tilemap,0, darkseal_control_1[2] );

	if (darkseal_control_0[6]&0x4000) { /* Rowscroll enable */
		int offs,scrollx=darkseal_control_0[3];

		tilemap_set_scroll_rows(pf3_tilemap,512);
		for (offs = 0;offs < 512;offs++)
			tilemap_set_scrollx( pf3_tilemap,offs, scrollx + darkseal_pf34_row[offs+0x40] );
	}
	else {
		tilemap_set_scroll_rows(pf3_tilemap,1);
		tilemap_set_scrollx( pf3_tilemap,0, darkseal_control_0[3] );
	}
	tilemap_set_scrolly( pf3_tilemap,0, darkseal_control_0[4] );

	tilemap_draw(bitmap,cliprect,pf3_tilemap,0,0);
	tilemap_draw(bitmap,cliprect,pf2_tilemap,0,0);
	draw_sprites(machine,bitmap,cliprect);
	tilemap_draw(bitmap,cliprect,pf1_tilemap,0,0);
	return 0;
}

/******************************************************************************/