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