1 // license:BSD-3-Clause
2 // copyright-holders:Luca Elia
3 /***************************************************************************************
4 
5                       -= Electronic Devices / International Games =-
6 
7                     driver by   Luca Elia (l.elia@tin.it)
8 
9     This game has sprites only:
10 
11     tiles are 16 x 16 x 6. There are 0x400 sprites, each one is allotted
12     8 bytes of memory (but only 5 are used) in spriteram (0x54000):
13 
14     Offset:     Bits:           Value:
15 
16         0                       X (low bits)
17 
18         1       7--- ----       X (high bit)
19                 -6-- ----       Y (high bit)
20                 --5- ----       Flip X
21                 ---4 ----       Flip Y
22                 ---- 32--
23                 ---- --10       Color
24 
25         2                       Code (high bits)
26 
27         3                       Code (low bits)
28 
29         4                       Y (low bits)
30 
31     Then 2 tables follow, 0x400 bytes each:
32 
33     - the first table  (0x56000) contains 1 byte per sprite: an index in the second table
34     - the second table (0x56400) is either an x,y offset or an index in spriteram_2 (0x60000):
35 
36         0                       X offset (low bits)
37 
38         1                       Y offset (low bits)
39 
40         2       7--- ----       If 1, the following bits are an index in spriteram_2 for the real X&Y & Code offsets
41                 -654 321-
42                 ---- ---0       X offset (high bit)
43 
44         3       7654 321-
45                 ---- ---0       Y offset (high bit)
46 
47 
48     Spriteram_2 contains 0x4000 X&Y & Code offsets:
49 
50         0                       Y offset (low bits)
51 
52         1       7--- ----       Flip X (xor with that in spriteram)
53                 -6-- ----       Flip Y ""
54                 --54 321-       Code offset
55                 ---- ---0       Y offset (high bit)
56 
57         2                       X offset (low bits)
58 
59         3                       X offset (high bit)
60 
61 ***************************************************************************************/
62 
63 #include "emu.h"
64 #include "includes/fantland.h"
65 
draw_sprites(bitmap_ind16 & bitmap,const rectangle & cliprect)66 void fantland_state::draw_sprites(bitmap_ind16 &bitmap,const rectangle &cliprect)
67 {
68 	uint8_t *indx_ram   =   m_spriteram + 0x2000,    // this ram contains indexes into offs_ram
69 			*offs_ram   =   m_spriteram + 0x2400,    // this ram contains x,y offsets or indexes into m_spriteram2
70 			*ram        =   m_spriteram,         // current sprite pointer in spriteram
71 			*ram2       =   indx_ram;           // current sprite pointer in indx_ram
72 
73 	// wheelrun is the only game with a smaller visible area
74 	const rectangle &visarea = m_screen->visible_area();
75 	int special = visarea.height() < 0x100;
76 
77 	for ( ; ram < indx_ram; ram += 8,ram2++)
78 	{
79 		int attr,code,color, x,y,xoffs,yoffs,flipx,flipy, idx;
80 
81 		attr    =   ram[1];
82 
83 		x       =   ram[0];
84 		code    =   ram[3] + (ram[2] << 8);
85 		y       =   ram[4];
86 
87 		color   =   (attr & 0x03);
88 		flipy   =   (attr & 0x10) ? 1 : 0;
89 		flipx   =   (attr & 0x20) ? 1 : 0;
90 
91 		y       +=  (attr & 0x40) << 2;
92 		x       +=  (attr & 0x80) << 1;
93 
94 		// Index in the table of offsets
95 
96 		idx     =   ram2[0] * 4;
97 
98 		// Fetch the offsets
99 
100 		if (offs_ram[idx + 2] & 0x80)
101 		{
102 			// x,y & code offset is in m_spriteram2, this is its index
103 
104 			idx     =   (((offs_ram[idx + 2] << 8) + offs_ram[idx + 3]) & 0x3fff) * 4;
105 
106 			yoffs   =   m_spriteram2[idx + 0] + (m_spriteram2[idx + 1] << 8);
107 			xoffs   =   m_spriteram2[idx + 2] + (m_spriteram2[idx + 3] << 8);
108 
109 			code    +=  (yoffs & 0x3e00) >> 9;
110 			flipy   ^=  (yoffs & 0x4000) ? 1 : 0;
111 			flipx   ^=  (yoffs & 0x8000) ? 1 : 0;
112 		}
113 		else
114 		{
115 			// this is an x,y offset
116 
117 			yoffs   =   ((offs_ram[idx + 3] & 0x01) << 8) + offs_ram[idx + 1];
118 			xoffs   =   ((offs_ram[idx + 2] & 0x01) << 8) + offs_ram[idx + 0];
119 		}
120 
121 		yoffs   =   (yoffs & 0xff) - (yoffs & 0x100);
122 		xoffs   =   (xoffs & 0x1ff);
123 
124 		if (xoffs >= 0x180)     xoffs -= 0x200;
125 
126 		y       +=  yoffs;
127 		x       +=  xoffs;
128 
129 		// wheelrun needs y=0xf0 & yoffs=0x50 to be rendered at screen y 0x40
130 		if (special && y > 0)
131 			y &= 0xff;
132 
133 		y       =   (y & 0xff) - (y & 0x100);
134 		x       =   (x & 0x1ff);
135 
136 		if (x >= 0x180)     x -= 0x200;
137 
138 		m_gfxdecode->gfx(0)->transpen(bitmap,cliprect, code,color, flipx,flipy, x,y,0);
139 	}
140 }
141 
screen_update(screen_device & screen,bitmap_ind16 & bitmap,const rectangle & cliprect)142 uint32_t fantland_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
143 {
144 	bitmap.fill(0, cliprect);
145 	draw_sprites(bitmap,cliprect);
146 
147 	return 0;
148 }
149