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