1 // license:BSD-3-Clause
2 // copyright-holders:Phil Stroffolino
3 /* video/namconb1.c */
4 
5 #include "emu.h"
6 #include "includes/namconb1.h"
7 
8 #include <algorithm>
9 
10 /* nth_word32 is a general-purpose utility function, which allows us to
11  * read from 32-bit aligned memory as if it were an array of 16 bit words.
12  */
13 static inline u16
nth_word32(const u32 * source,int which)14 nth_word32(const u32 *source, int which)
15 {
16 	source += which / 2;
17 	if (which & 1)
18 	{
19 		return (*source) & 0xffff;
20 	}
21 	else
22 	{
23 		return (*source) >> 16;
24 	}
25 }
26 
27 /* nth_byte32 is a general-purpose utility function, which allows us to
28  * read from 32-bit aligned memory as if it were an array of bytes.
29  */
30 static inline u8
nth_byte32(const u32 * pSource,int which)31 nth_byte32(const u32 *pSource, int which)
32 {
33 	u32 data = pSource[which / 4];
34 	switch (which & 3)
35 	{
36 	case 0: return data >> 24;
37 	case 1: return (data >> 16) & 0xff;
38 	case 2: return (data >> 8) & 0xff;
39 	default: return data & 0xff;
40 	}
41 } /* nth_byte32 */
42 
NB1TilemapCB(u16 code,int * tile,int * mask)43 void namconb1_state::NB1TilemapCB(u16 code, int *tile, int *mask)
44 {
45 	*tile = code;
46 	*mask = code;
47 } /* NB1TilemapCB */
48 
NB2TilemapCB_machbrkr(u16 code,int * tile,int * mask)49 void namconb1_state::NB2TilemapCB_machbrkr(u16 code, int *tile, int *mask)
50 {
51 	/*  00010203 04050607 00010203 04050607 (normal) */
52 	/*  00010718 191a1b07 00010708 090a0b07 (alt bank) */
53 	int bank = nth_byte32(m_tilebank32, (code >> 13) + 8);
54 	int mangle = (code & 0x1fff) | (bank << 13);
55 	*tile = mangle;
56 	*mask = mangle;
57 } /* NB2TilemapCB_machbrkr */
58 
NB2TilemapCB_outfxies(u16 code,int * tile,int * mask)59 void namconb1_state::NB2TilemapCB_outfxies(u16 code, int *tile, int *mask)
60 {
61 	/* the pixmap index is mangled, the transparency bitmask index is not */
62 	*tile = bitswap<16>(code, 15, 14, 13, 12, 11, 10, 9, 6, 7, 8, 5, 4, 3, 2, 1, 0);
63 	*mask = code;
64 } /* NB2TilemapCB_outfxies */
65 
NB2RozCB_machbrkr(u16 code,int * tile,int * mask,int which)66 void namconb1_state::NB2RozCB_machbrkr(u16 code, int *tile, int *mask, int which)
67 {
68 	int bank = nth_byte32(&m_rozbank32[which * 8 / 4], (code >> 11) & 0x7);
69 	int mangle = (code & 0x7ff) | (bank << 11);
70 	*tile = mangle;
71 	*mask = mangle;
72 } /* NB2RozCB_machbrkr */
73 
NB2RozCB_outfxies(u16 code,int * tile,int * mask,int which)74 void namconb1_state::NB2RozCB_outfxies(u16 code, int *tile, int *mask, int which)
75 {
76 	/* the pixmap index is mangled, the transparency bitmask index is not */
77 	int bank = nth_byte32(&m_rozbank32[which * 8 / 4], (code >> 11) & 0x7);
78 	int mangle = (code & 0x7ff) | (bank << 11);
79 	*mask = mangle;
80 	mangle = bitswap<19>(mangle & 0x7ffff, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 4, 5, 6, 3, 2, 1, 0);
81 	*tile = mangle;
82 } /* NB2RozCB_outfxies */
83 
video_update_common(screen_device & screen,bitmap_ind16 & bitmap,const rectangle & cliprect)84 void namconb1_state::video_update_common(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
85 {
86 	int pri;
87 
88 	if (m_c169roz)
89 	{
90 		for (pri = 0; pri < 16; pri++)
91 		{
92 			m_c169roz->draw(screen, bitmap, cliprect, pri);
93 			if ((pri & 1) == 0)
94 			{
95 				m_c123tmap->draw(screen, bitmap, cliprect, pri / 2);
96 			}
97 			m_c355spr->draw(screen, bitmap, cliprect, pri);
98 		}
99 	}
100 	else
101 	{
102 		for (pri = 0; pri < 8; pri++)
103 		{
104 			m_c123tmap->draw(screen, bitmap, cliprect, pri);
105 			m_c355spr->draw(screen, bitmap, cliprect, pri);
106 		}
107 	}
108 } /* video_update_common */
109 
WRITE_LINE_MEMBER(namconb1_state::screen_vblank)110 WRITE_LINE_MEMBER(namconb1_state::screen_vblank)
111 {
112 	m_c355spr->vblank(state);
113 	if (state)
114 	{
115 		const u32 size = m_spritebank32.bytes() / 4;
116 		std::copy_n(&m_spritebank32[0], size, &m_spritebank32_delayed[0]);
117 	}
118 }
119 
120 /************************************************************************************************/
121 
screen_update_namconb1(screen_device & screen,bitmap_ind16 & bitmap,const rectangle & cliprect)122 u32 namconb1_state::screen_update_namconb1(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
123 {
124 	/* compute window for custom screen blanking */
125 	rectangle clip;
126 	//004a 016a 0021 0101 0144 0020 (nebulas ray)
127 	clip.min_x = m_c116->get_reg(0) - 0x4a;
128 	clip.max_x = m_c116->get_reg(1) - 0x4a - 1;
129 	clip.min_y = m_c116->get_reg(2) - 0x21;
130 	clip.max_y = m_c116->get_reg(3) - 0x21 - 1;
131 	/* intersect with master clip rectangle */
132 	clip &= cliprect;
133 
134 	bitmap.fill(m_c116->black_pen(), cliprect);
135 
136 	video_update_common(screen, bitmap, clip);
137 
138 	return 0;
139 }
140 
NB1objcode2tile(int code)141 int namconb1_state::NB1objcode2tile(int code)
142 {
143 	int bank = nth_word32(m_spritebank32_delayed.get(), code >> 11);
144 	return (code & 0x7ff) | (bank << 11);
145 }
146 
video_start()147 void namconb1_state::video_start()
148 {
149 	const u32 size = m_spritebank32.bytes() / 4;
150 	m_spritebank32_delayed = make_unique_clear<u32[]>(size);
151 	save_item(NAME(m_tilemap_tile_bank));
152 	save_pointer(NAME(m_spritebank32_delayed), size);
153 } /* namconb1 */
154 
155 /****************************************************************************************************/
156 
rozbank32_w(offs_t offset,u32 data,u32 mem_mask)157 void namconb1_state::rozbank32_w(offs_t offset, u32 data, u32 mem_mask)
158 {
159 	u32 old_data = m_rozbank32[offset];
160 	COMBINE_DATA(&m_rozbank32[offset]);
161 	if (m_rozbank32[offset] != old_data)
162 		m_c169roz->mark_all_dirty();
163 }
164 
screen_update_namconb2(screen_device & screen,bitmap_ind16 & bitmap,const rectangle & cliprect)165 u32 namconb1_state::screen_update_namconb2(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
166 {
167 	/* compute window for custom screen blanking */
168 	rectangle clip;
169 	//004a016a 00210101 01440020
170 	clip.min_x = m_c116->get_reg(0) - 0x4b;
171 	clip.max_x = m_c116->get_reg(1) - 0x4b - 1;
172 	clip.min_y = m_c116->get_reg(2) - 0x21;
173 	clip.max_y = m_c116->get_reg(3) - 0x21 - 1;
174 	/* intersect with master clip rectangle */
175 	clip &= cliprect;
176 
177 	bitmap.fill(m_c116->black_pen(), cliprect);
178 
179 	if (memcmp(m_tilemap_tile_bank, m_tilebank32, sizeof(m_tilemap_tile_bank)) != 0)
180 	{
181 		m_c123tmap->mark_all_dirty();
182 		memcpy(m_tilemap_tile_bank, m_tilebank32, sizeof(m_tilemap_tile_bank));
183 	}
184 	video_update_common(screen, bitmap, clip);
185 	return 0;
186 }
187 
NB2objcode2tile_machbrkr(int code)188 int namconb1_state::NB2objcode2tile_machbrkr(int code)
189 {
190 	int bank = nth_byte32(m_spritebank32_delayed.get(), (code >> 11) & 0xf);
191 	code &= 0x7ff;
192 	code |= bitswap<6>(bank & 0x5f, 6, 4, 3, 2, 1, 0) << 11;
193 	return code;
194 } /* NB2objcode2tile_machbrkr */
195 
NB2objcode2tile_outfxies(int code)196 int namconb1_state::NB2objcode2tile_outfxies(int code)
197 {
198 	int bank = nth_byte32(m_spritebank32_delayed.get(), (code >> 11) & 0xf);
199 	code &= 0x7ff;
200 	code |= bitswap<6>(bank & 0x5f, 6, 4, 3, 1, 2, 0) << 11;
201 	return code;
202 } /* NB2objcode2tile_outfxies */
203