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