1 // license:BSD-3-Clause
2 // copyright-holders:Carlos A. Lozano
3 /***************************************************************************
4 
5   video.c
6 
7   Functions to emulate the video hardware of the machine.
8 
9 ***************************************************************************/
10 
11 #include "emu.h"
12 #include "includes/terracre.h"
13 
14 
TILE_GET_INFO_MEMBER(terracre_state::get_bg_tile_info)15 TILE_GET_INFO_MEMBER(terracre_state::get_bg_tile_info)
16 {
17 	/* xxxx.----.----.----
18 	 * ----.xx--.----.----
19 	 * ----.--xx.xxxx.xxxx */
20 	unsigned data = m_bg_videoram[tile_index];
21 	unsigned color = data>>11;
22 	tileinfo.set(1,data&0x3ff,color,0 );
23 }
24 
TILE_GET_INFO_MEMBER(terracre_state::get_fg_tile_info)25 TILE_GET_INFO_MEMBER(terracre_state::get_fg_tile_info)
26 {
27 	unsigned data = m_fg_videoram[tile_index];
28 	tileinfo.set(0,data&0xff,0,0 );
29 }
30 
draw_sprites(bitmap_ind16 & bitmap,const rectangle & cliprect)31 void terracre_state::draw_sprites(bitmap_ind16 &bitmap, const rectangle &cliprect )
32 {
33 	const uint8_t *spritepalettebank = memregion("user1")->base();
34 	gfx_element *pGfx = m_gfxdecode->gfx(2);
35 	const uint16_t *pSource = m_spriteram->buffer();
36 	int flip = flip_screen();
37 	int transparent_pen;
38 
39 	if( pGfx->elements() > 0x200 )
40 	{ /* HORE HORE Kid */
41 		transparent_pen = 0xf;
42 	}
43 	else
44 	{
45 		transparent_pen = 0x0;
46 	}
47 	for( int i=0; i<0x200; i+=8 )
48 	{
49 		int tile = pSource[1]&0xff;
50 		int attrs = pSource[2];
51 		int flipx = attrs&0x04;
52 		int flipy = attrs&0x08;
53 		int color = (attrs&0xf0)>>4;
54 		int sx = (pSource[3] & 0xff) - 0x80 + 256 * (attrs & 1);
55 		int sy = 240 - (pSource[0] & 0xff);
56 
57 		if( transparent_pen )
58 		{
59 			int bank;
60 
61 			if( attrs&0x02 ) tile |= 0x200;
62 			if( attrs&0x10 ) tile |= 0x100;
63 
64 			bank = (tile&0xfc)>>1;
65 			if( tile&0x200 ) bank |= 0x80;
66 			if( tile&0x100 ) bank |= 0x01;
67 
68 			color &= 0xe;
69 			color += 16*(spritepalettebank[bank]&0xf);
70 		}
71 		else
72 		{
73 			if( attrs&0x02 ) tile|= 0x100;
74 			color += 16 * (spritepalettebank[(tile>>1)&0xff] & 0x0f);
75 		}
76 
77 		if (flip)
78 		{
79 				sx=240-sx;
80 				sy=240-sy;
81 				flipx = !flipx;
82 				flipy = !flipy;
83 		}
84 
85 		pGfx->transpen(
86 			bitmap,cliprect,tile, color,flipx,flipy,sx,sy,transparent_pen );
87 
88 		pSource += 4;
89 	}
90 }
91 
terracre_palette(palette_device & palette) const92 void terracre_state::terracre_palette(palette_device &palette) const
93 {
94 	const uint8_t *color_prom = memregion("proms")->base();
95 
96 	// create a lookup table for the palette
97 	for (int i = 0; i < 0x100; i++)
98 	{
99 		int const r = pal4bit(color_prom[i + 0x000]);
100 		int const g = pal4bit(color_prom[i + 0x100]);
101 		int const b = pal4bit(color_prom[i + 0x200]);
102 
103 		palette.set_indirect_color(i, rgb_t(r, g, b));
104 	}
105 
106 	// color_prom now points to the beginning of the lookup table
107 	color_prom += 0x300;
108 
109 	// characters use colors 0-0x0f
110 	for (int i = 0; i < 0x10; i++)
111 		palette.set_pen_indirect(i, i);
112 
113 	// background tiles use colors 0xc0-0xff in four banks
114 	// the bottom two bits of the color code select the palette bank for pens 0-7;
115 	// the top two bits for pens 8-0x0f.
116 	for (int i = 0; i < 0x100; i++)
117 	{
118 		uint8_t const ctabentry = 0xc0 | (i & 0x0f) | ((i >> ((i & 0x08) ? 2 : 0)) & 0x30);
119 
120 		palette.set_pen_indirect(0x10 + i, ctabentry);
121 	}
122 
123 	// sprites use colors 128-191 in four banks
124 	// The lookup table tells which colors to pick from the selected bank
125 	// the bank is selected by another PROM and depends on the top 8 bits of the sprite code.
126 	// The PROM selects the bank *separately* for pens 0-7 and 8-15 (like for tiles).
127 	for (int i = 0; i < 0x1000; i++)
128 	{
129 		uint8_t const ctabentry = 0x80 | ((i << ((i & 0x80) ? 2 : 4)) & 0x30) | (color_prom[i >> 4] & 0x0f);
130 		int i_swapped = ((i & 0x0f) << 8) | ((i & 0xff0) >> 4);
131 
132 		palette.set_pen_indirect(0x110 + i_swapped, ctabentry);
133 	}
134 }
135 
amazon_background_w(offs_t offset,uint16_t data,uint16_t mem_mask)136 void terracre_state::amazon_background_w(offs_t offset, uint16_t data, uint16_t mem_mask)
137 {
138 	COMBINE_DATA(&m_bg_videoram[offset]);
139 	m_background->mark_tile_dirty(offset);
140 }
141 
amazon_foreground_w(offs_t offset,uint16_t data,uint16_t mem_mask)142 void terracre_state::amazon_foreground_w(offs_t offset, uint16_t data, uint16_t mem_mask)
143 {
144 	COMBINE_DATA(&m_fg_videoram[offset]);
145 	m_foreground->mark_tile_dirty(offset);
146 }
147 
amazon_flipscreen_w(offs_t offset,uint16_t data,uint16_t mem_mask)148 void terracre_state::amazon_flipscreen_w(offs_t offset, uint16_t data, uint16_t mem_mask)
149 {
150 	if( ACCESSING_BITS_0_7 )
151 	{
152 		machine().bookkeeping().coin_counter_w(0, data&0x01 );
153 		machine().bookkeeping().coin_counter_w(1, (data&0x02)>>1 );
154 		flip_screen_set(data&0x04);
155 	}
156 }
157 
amazon_scrolly_w(offs_t offset,uint16_t data,uint16_t mem_mask)158 void terracre_state::amazon_scrolly_w(offs_t offset, uint16_t data, uint16_t mem_mask)
159 {
160 	COMBINE_DATA(&m_yscroll);
161 	m_background->set_scrolly(0,m_yscroll);
162 }
163 
amazon_scrollx_w(offs_t offset,uint16_t data,uint16_t mem_mask)164 void terracre_state::amazon_scrollx_w(offs_t offset, uint16_t data, uint16_t mem_mask)
165 {
166 	COMBINE_DATA(&m_xscroll);
167 	m_background->set_scrollx(0,m_xscroll);
168 }
169 
video_start()170 void terracre_state::video_start()
171 {
172 	m_background = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(terracre_state::get_bg_tile_info)), TILEMAP_SCAN_COLS, 16,16, 64,32);
173 	m_foreground = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(terracre_state::get_fg_tile_info)), TILEMAP_SCAN_COLS,  8, 8, 64,32);
174 	m_foreground->set_transparent_pen(0xf);
175 
176 	/* register for saving */
177 	save_item(NAME(m_xscroll));
178 	save_item(NAME(m_yscroll));
179 }
180 
screen_update_amazon(screen_device & screen,bitmap_ind16 & bitmap,const rectangle & cliprect)181 uint32_t terracre_state::screen_update_amazon(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
182 {
183 	if( m_xscroll&0x2000 )
184 		bitmap.fill(m_palette->black_pen(), cliprect );
185 	else
186 		m_background->draw(screen, bitmap, cliprect, 0, 0 );
187 
188 	draw_sprites(bitmap,cliprect );
189 
190 	if ((m_xscroll & 0x1000) == 0)
191 		m_foreground->draw(screen, bitmap, cliprect, 0, 0);
192 
193 	return 0;
194 }
195