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