1 // license:BSD-3-Clause
2 // copyright-holders:Allard van der Bas
3 /***************************************************************************
4
5 Pooyan
6
7 ***************************************************************************/
8
9 #include "emu.h"
10 #include "video/resnet.h"
11 #include "includes/pooyan.h"
12
13 /***************************************************************************
14
15 Convert the color PROMs into a more useable format.
16
17 Pooyan has one 32x8 palette PROM and two 256x4 lookup table PROMs
18 (one for characters, one for sprites).
19 The palette PROM is connected to the RGB output this way:
20
21 bit 7 -- 220 ohm resistor -- BLUE
22 -- 470 ohm resistor -- BLUE
23 -- 220 ohm resistor -- GREEN
24 -- 470 ohm resistor -- GREEN
25 -- 1 kohm resistor -- GREEN
26 -- 220 ohm resistor -- RED
27 -- 470 ohm resistor -- RED
28 bit 0 -- 1 kohm resistor -- RED
29
30 ***************************************************************************/
31
pooyan_palette(palette_device & palette) const32 void pooyan_state::pooyan_palette(palette_device &palette) const
33 {
34 const uint8_t *color_prom = memregion("proms")->base();
35 static constexpr int resistances_rg[3] = { 1000, 470, 220 };
36 static constexpr int resistances_b [2] = { 470, 220 };
37
38 // compute the color output resistor weights
39 double rweights[3], gweights[3], bweights[2];
40 compute_resistor_weights(0, 255, -1.0,
41 3, resistances_rg, rweights, 1000, 0,
42 3, resistances_rg, gweights, 1000, 0,
43 2, resistances_b, bweights, 1000, 0);
44
45 // create a lookup table for the palette
46 for (int i = 0; i < 0x20; i++)
47 {
48 int bit0, bit1, bit2;
49
50 // red component
51 bit0 = BIT(color_prom[i], 0);
52 bit1 = BIT(color_prom[i], 1);
53 bit2 = BIT(color_prom[i], 2);
54 int const r = combine_weights(rweights, bit0, bit1, bit2);
55
56 // green component
57 bit0 = BIT(color_prom[i], 3);
58 bit1 = BIT(color_prom[i], 4);
59 bit2 = BIT(color_prom[i], 5);
60 int const g = combine_weights(gweights, bit0, bit1, bit2);
61
62 // blue component
63 bit0 = BIT(color_prom[i], 6);
64 bit1 = BIT(color_prom[i], 7);
65 int const b = combine_weights(bweights, bit0, bit1);
66
67 palette.set_indirect_color(i, rgb_t(r, g, b));
68 }
69
70 // color_prom now points to the beginning of the lookup table
71 color_prom += 0x20;
72
73 // characters
74 for (int i = 0; i < 0x100; i++)
75 {
76 uint8_t const ctabentry = (color_prom[i] & 0x0f) | 0x10;
77 palette.set_pen_indirect(i, ctabentry);
78 }
79
80 // sprites
81 for (int i = 0x100; i < 0x200; i++)
82 {
83 uint8_t const ctabentry = color_prom[i] & 0x0f;
84 palette.set_pen_indirect(i, ctabentry);
85 }
86 }
87
88
89
90 /*************************************
91 *
92 * Tilemap info callback
93 *
94 *************************************/
95
TILE_GET_INFO_MEMBER(pooyan_state::get_bg_tile_info)96 TILE_GET_INFO_MEMBER(pooyan_state::get_bg_tile_info)
97 {
98 int attr = m_colorram[tile_index];
99 int code = m_videoram[tile_index];
100 int color = attr & 0x0f;
101 int flags = TILE_FLIPYX(attr >> 6);
102
103 tileinfo.set(0, code, color, flags);
104 }
105
106
107
108 /*************************************
109 *
110 * Video startup
111 *
112 *************************************/
113
video_start()114 void pooyan_state::video_start()
115 {
116 m_bg_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(pooyan_state::get_bg_tile_info)), TILEMAP_SCAN_ROWS, 8, 8, 32, 32);
117 }
118
119
120
121 /*************************************
122 *
123 * Memory write handlers
124 *
125 *************************************/
126
videoram_w(offs_t offset,uint8_t data)127 void pooyan_state::videoram_w(offs_t offset, uint8_t data)
128 {
129 m_videoram[offset] = data;
130 m_bg_tilemap->mark_tile_dirty(offset);
131 }
132
133
colorram_w(offs_t offset,uint8_t data)134 void pooyan_state::colorram_w(offs_t offset, uint8_t data)
135 {
136 m_colorram[offset] = data;
137 m_bg_tilemap->mark_tile_dirty(offset);
138 }
139
140
WRITE_LINE_MEMBER(pooyan_state::flipscreen_w)141 WRITE_LINE_MEMBER(pooyan_state::flipscreen_w)
142 {
143 flip_screen_set(!state);
144 }
145
146
147
148 /*************************************
149 *
150 * Sprite rendering
151 *
152 *************************************/
153
draw_sprites(bitmap_ind16 & bitmap,const rectangle & cliprect)154 void pooyan_state::draw_sprites( bitmap_ind16 &bitmap, const rectangle &cliprect )
155 {
156 for (int offs = 0x10; offs < 0x40; offs += 2)
157 {
158 int sx = m_spriteram[offs];
159 int sy = 240 - m_spriteram2[offs + 1];
160
161 int code = m_spriteram[offs + 1];
162 int color = m_spriteram2[offs] & 0x0f;
163 int flipx = ~m_spriteram2[offs] & 0x40;
164 int flipy = m_spriteram2[offs] & 0x80;
165
166
167 m_gfxdecode->gfx(1)->transmask(bitmap,cliprect,
168 code,
169 color,
170 flipx, flipy,
171 sx, sy,
172 m_palette->transpen_mask(*m_gfxdecode->gfx(1), color, 0));
173 }
174 }
175
176
177
178 /*************************************
179 *
180 * Video update
181 *
182 *************************************/
183
screen_update(screen_device & screen,bitmap_ind16 & bitmap,const rectangle & cliprect)184 uint32_t pooyan_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
185 {
186 m_bg_tilemap->draw(screen, bitmap, cliprect, 0, 0);
187 draw_sprites(bitmap, cliprect);
188 return 0;
189 }
190