1 // license:BSD-3-Clause
2 // copyright-holders:Stefan Jokisch
3 /***************************************************************************
4 
5 Atari Sky Raider video emulation
6 
7 ***************************************************************************/
8 
9 #include "emu.h"
10 #include "includes/skyraid.h"
11 
12 
video_start()13 void skyraid_state::video_start()
14 {
15 	m_helper.allocate(128, 240);
16 }
17 
18 
draw_text(bitmap_ind16 & bitmap,const rectangle & cliprect)19 void skyraid_state::draw_text(bitmap_ind16 &bitmap, const rectangle &cliprect)
20 {
21 	const uint8_t* p = m_alpha_num_ram;
22 
23 	int i;
24 
25 	for (i = 0; i < 4; i++)
26 	{
27 		int x;
28 		int y;
29 
30 		y = 136 + 16 * (i ^ 1);
31 
32 		for (x = 0; x < bitmap.width(); x += 16)
33 			m_gfxdecode->gfx(0)->transpen(bitmap,cliprect, *p++, 0, 0, 0,   x, y, 0);
34 	}
35 }
36 
37 
draw_terrain(bitmap_ind16 & bitmap,const rectangle & cliprect)38 void skyraid_state::draw_terrain(bitmap_ind16 &bitmap, const rectangle &cliprect)
39 {
40 	const uint8_t* p = memregion("user1")->base();
41 
42 	int x;
43 	int y;
44 
45 	for (y = 0; y < bitmap.height(); y++)
46 	{
47 		int offset = (16 * m_scroll + 16 * ((y + 1) / 2)) & 0x7FF;
48 
49 		x = 0;
50 
51 		while (x < bitmap.width())
52 		{
53 			uint8_t val = p[offset++];
54 
55 			int color = val / 32;
56 			int count = val % 32;
57 
58 			rectangle r(x, x + 31 - count, y, y+ 1);
59 
60 			bitmap.fill(color, r);
61 
62 			x += 32 - count;
63 		}
64 	}
65 }
66 
67 
draw_sprites(bitmap_ind16 & bitmap,const rectangle & cliprect)68 void skyraid_state::draw_sprites(bitmap_ind16 &bitmap, const rectangle &cliprect)
69 {
70 	int i;
71 
72 	for (i = 0; i < 4; i++)
73 	{
74 		int code = m_obj_ram[8 + 2 * i + 0] & 15;
75 		int flag = m_obj_ram[8 + 2 * i + 1] & 15;
76 		int vert = m_pos_ram[8 + 2 * i + 0];
77 		int horz = m_pos_ram[8 + 2 * i + 1];
78 
79 		vert -= 31;
80 
81 		if (flag & 1)
82 			m_gfxdecode->gfx(1)->transpen(bitmap,cliprect,
83 				code ^ 15, code >> 3, 0, 0,
84 				horz / 2, vert, 2);
85 	}
86 }
87 
88 
draw_missiles(bitmap_ind16 & bitmap,const rectangle & cliprect)89 void skyraid_state::draw_missiles(bitmap_ind16 &bitmap, const rectangle &cliprect)
90 {
91 	int i;
92 
93 	/* hardware is restricted to one sprite per scanline */
94 
95 	for (i = 0; i < 4; i++)
96 	{
97 		int code = m_obj_ram[2 * i + 0] & 15;
98 		int vert = m_pos_ram[2 * i + 0];
99 		int horz = m_pos_ram[2 * i + 1];
100 
101 		vert -= 15;
102 		horz -= 31;
103 
104 		m_gfxdecode->gfx(2)->transpen(bitmap,cliprect,
105 			code ^ 15, 0, 0, 0,
106 			horz / 2, vert, 0);
107 	}
108 }
109 
110 
draw_trapezoid(bitmap_ind16 & dst,bitmap_ind16 & src)111 void skyraid_state::draw_trapezoid(bitmap_ind16& dst, bitmap_ind16& src)
112 {
113 	uint8_t const *const p = memregion("user2")->base();
114 
115 	for (int y = 0; y < dst.height(); y++)
116 	{
117 		uint16_t const *const pSrc = &src.pix(y);
118 		uint16_t *const pDst = &dst.pix(y);
119 
120 		int const x1 = 0x000 + p[(y & ~1) + 0];
121 		int const x2 = 0x100 + p[(y & ~1) + 1];
122 
123 		for (int x = x1; x < x2; x++)
124 			pDst[x] = pSrc[128 * (x - x1) / (x2 - x1)];
125 	}
126 }
127 
128 
screen_update_skyraid(screen_device & screen,bitmap_ind16 & bitmap,const rectangle & cliprect)129 uint32_t skyraid_state::screen_update_skyraid(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
130 {
131 	bitmap.fill(0, cliprect);
132 
133 	rectangle helper_clip = cliprect;
134 	helper_clip &= m_helper.cliprect();
135 
136 	draw_terrain(m_helper, helper_clip);
137 	draw_sprites(m_helper, helper_clip);
138 	draw_missiles(m_helper, helper_clip);
139 	draw_trapezoid(bitmap, m_helper);
140 	draw_text(bitmap, cliprect);
141 	return 0;
142 }
143