1 // 054338
2
3 // license:BSD-3-Clause
4 // copyright-holders:David Haywood
5
6 #include "tiles_generic.h"
7 #include "konamiic.h"
8
9 static UINT16 k54338_regs[32];
10 INT32 m_shd_rgb[12];
11
12 static INT32 k054338_alphainverted;
13 static INT32 alpha_cache; // for moomesa
14
reset_shadows()15 static void reset_shadows()
16 {
17 m_shd_rgb[0] = m_shd_rgb[1] = m_shd_rgb[2] = -80; // shadow bank 0
18 m_shd_rgb[3] = m_shd_rgb[4] = m_shd_rgb[5] = -80; // shadow bank 1
19 m_shd_rgb[6] = m_shd_rgb[7] = m_shd_rgb[8] = -80; // shadow bank 2
20 m_shd_rgb[9] = m_shd_rgb[10] = m_shd_rgb[11] = -80; // shadow bank 3 (static)
21 }
22
K054338Reset()23 void K054338Reset()
24 {
25 memset(k54338_regs, 0, sizeof(k54338_regs));
26 memset(m_shd_rgb, 0, sizeof(m_shd_rgb));
27
28 reset_shadows();
29 alpha_cache = 0;
30 }
31
K054338Exit()32 void K054338Exit()
33 {
34
35 }
36
K054338Scan(INT32 nAction)37 void K054338Scan(INT32 nAction)
38 {
39 struct BurnArea ba;
40
41 if (nAction & ACB_MEMORY_RAM) {
42 memset(&ba, 0, sizeof(ba));
43 ba.Data = (UINT8*)k54338_regs;
44 ba.nLen = sizeof(k54338_regs);
45 ba.szName = "K054338 Regs";
46 BurnAcb(&ba);
47
48 SCAN_VAR(alpha_cache);
49 }
50 }
51
K054338Init()52 void K054338Init()
53 {
54 KonamiIC_K054338InUse = 1;
55 KonamiAllocateBitmaps();
56
57 K054338Reset();
58 k054338_alphainverted = 1;
59 }
60
K054338WriteWord(INT32 offset,UINT16 data)61 void K054338WriteWord(INT32 offset, UINT16 data)
62 {
63 k54338_regs[(offset & 0x1e)/2] = data;
64 }
65
K054338WriteByte(INT32 offset,UINT8 data)66 void K054338WriteByte(INT32 offset, UINT8 data)
67 {
68 UINT8 *regs = (UINT8*)&k54338_regs;
69
70 regs[(offset & 0x1f)^1] = data;
71 }
72
73 // returns a 16-bit '338 register
K054338_read_register(INT32 reg)74 INT32 K054338_read_register(INT32 reg)
75 {
76 return k54338_regs[reg];
77 }
78
K054338_update_all_shadows(INT32 rushingheroes_hack)79 void K054338_update_all_shadows(INT32 rushingheroes_hack)
80 {
81 INT32 i, d;
82
83 for (i = 0; i < 9; i++)
84 {
85 d = k54338_regs[K338_REG_SHAD1R + i] & 0x1ff;
86 if (d >= 0x100)
87 d -= 0x200;
88 m_shd_rgb[i] = d;
89 }
90
91 if (rushingheroes_hack) {
92 reset_shadows();
93 }
94 }
95
K054338_export_config(INT32 ** shd_rgb)96 void K054338_export_config(INT32 **shd_rgb)
97 {
98 *shd_rgb = m_shd_rgb;
99 }
100
101 // k054338 BG color fill
K054338_fill_solid_bg()102 void K054338_fill_solid_bg()
103 {
104 UINT32 bgcolor;
105 UINT32 *pLine;
106 INT32 x, y;
107
108 bgcolor = (K054338_read_register(K338_REG_BGC_R)&0xff)<<16;
109 bgcolor |= K054338_read_register(K338_REG_BGC_GB);
110
111 /* and fill the screen with it */
112 for (y = 0; y < nScreenHeight; y++)
113 {
114 pLine = konami_bitmap32;
115 pLine += (nScreenWidth*y);
116 for (x = 0; x < nScreenWidth; x++)
117 *pLine++ = bgcolor;
118 }
119 }
120
121 // Unified k054338/K055555 BG color fill
K054338_fill_backcolor(INT32 palette_offset,INT32 mode)122 void K054338_fill_backcolor(INT32 palette_offset, INT32 mode) // (see p.67)
123 {
124 INT32 clipx, clipy, clipw, cliph, i, dst_pitch;
125 INT32 BGC_CBLK, BGC_SET;
126 UINT32 *dst_ptr, *pal_ptr;
127 INT32 bgcolor;
128
129 clipx = 0 & ~3;
130 clipy = 0;
131 clipw = ((nScreenWidth - 1) + 4) & ~3;
132 cliph = (nScreenHeight-1) + 1;
133
134 dst_ptr = konami_bitmap32 + palette_offset;
135 dst_pitch = nScreenWidth;
136 dst_ptr += 0;
137
138 BGC_SET = 0;
139 pal_ptr = konami_palette32;
140
141 if (!mode)
142 {
143 // single color output from CLTC
144 bgcolor = (int)(k54338_regs[K338_REG_BGC_R]&0xff)<<16 | (int)k54338_regs[K338_REG_BGC_GB];
145 }
146 else
147 {
148 BGC_CBLK = K055555ReadRegister(0);
149 BGC_SET = K055555ReadRegister(1);
150 pal_ptr += BGC_CBLK << 9;
151
152 // single color output from PCU2
153 if (!(BGC_SET & 2)) { bgcolor = *pal_ptr; mode = 0; } else bgcolor = 0;
154 }
155
156 if (!mode)
157 {
158 // single color fill
159 dst_ptr += clipw;
160 i = clipw = -clipw;
161 do
162 {
163 do { dst_ptr[i] = dst_ptr[i+1] = dst_ptr[i+2] = dst_ptr[i+3] = bgcolor; } while (i += 4);
164 dst_ptr += dst_pitch;
165 i = clipw;
166 }
167 while (--cliph);
168 }
169 else
170 {
171 if (!(BGC_SET & 1))
172 {
173 // vertical gradient fill
174 pal_ptr += clipy;
175 dst_ptr += clipw;
176 bgcolor = *pal_ptr++;
177 i = clipw = -clipw;
178 do
179 {
180 do { dst_ptr[i] = dst_ptr[i+1] = dst_ptr[i+2] = dst_ptr[i+3] = bgcolor; } while (i += 4);
181 dst_ptr += dst_pitch;
182 bgcolor = *pal_ptr++;
183 i = clipw;
184 }
185 while (--cliph);
186 }
187 else
188 {
189 // horizontal gradient fill
190 pal_ptr += clipx;
191 clipw <<= 2;
192 do
193 {
194 memcpy(dst_ptr, pal_ptr, clipw);
195 dst_ptr += dst_pitch;
196 }
197 while (--cliph);
198 }
199 }
200 }
201
202 // addition blending unimplemented (requires major changes to drawgfx and tilemap.c)
K054338_set_alpha_level(INT32 pblend)203 INT32 K054338_set_alpha_level(INT32 pblend)
204 {
205 UINT16 *regs;
206 INT32 ctrl, mixpri, mixset, mixlv;
207
208 if (pblend <= 0 || pblend > 3)
209 {
210 // alpha_set_level(255);
211 return(255);
212 }
213
214 regs = k54338_regs;
215 ctrl = k54338_regs[K338_REG_CONTROL];
216 mixpri = ctrl & K338_CTL_MIXPRI;
217 mixset = regs[K338_REG_PBLEND + (pblend>>1 & 1)] >> (~pblend<<3 & 8);
218 mixlv = mixset & 0x1f;
219
220 if (k054338_alphainverted) mixlv = 0x1f - mixlv;
221
222 if (!(mixset & 0x20))
223 {
224 mixlv = mixlv<<3 | mixlv>>2;
225 // alpha_set_level(mixlv); // source x alpha/255 + target x (255-alpha)/255
226 }
227 else
228 {
229 if (!mixpri)
230 {
231 // source x alpha + target (clipped at 255)
232 }
233 else
234 {
235 // source + target x alpha (clipped at 255)
236 }
237
238 // DUMMY
239 if (mixlv && mixlv<0x1f) mixlv = 0x10;
240 mixlv = mixlv<<3 | mixlv>>2;
241 // alpha_set_level(mixlv);
242 }
243
244 return(mixlv);
245 }
246
247 //#define DEBUGMOO
248
K054338_alpha_level_moo(INT32 pblend)249 INT32 K054338_alpha_level_moo(INT32 pblend)
250 {
251 UINT16 *regs;
252 INT32 ctrl, mixpri, mixset, mixlv;
253
254 if (pblend <= 0 || pblend > 3)
255 {
256 // alpha_set_level(255);
257 return(255);
258 }
259
260 regs = k54338_regs;
261 ctrl = k54338_regs[K338_REG_CONTROL];
262 mixpri = ctrl & K338_CTL_MIXPRI;
263 mixset = regs[K338_REG_PBLEND + (pblend>>1 & 1)] >> (~pblend<<3 & 8);
264 mixlv = mixset & 0x1f;
265
266 #ifdef DEBUGMOO
267 bprintf(0, _T("%X - %X"), mixlv, mixpri);
268 #endif
269 if (mixlv == 0 && alpha_cache == 0x1f) {
270 mixlv = 0x1f;
271 #ifdef DEBUGMOO
272 bprintf(0, _T(" (cached) -> 0x1f"));
273 #endif
274 } // 0x1f -> 0x00 transition cache [dink]
275 #ifdef DEBUGMOO
276 bprintf(0, _T("\n"));
277 #endif
278 alpha_cache = mixlv;
279
280 if (k054338_alphainverted) mixlv = 0x1f - mixlv;
281
282 if (!(mixset & 0x20))
283 {
284 mixlv = mixlv<<3 | mixlv>>2;
285 // alpha_set_level(mixlv); // source x alpha/255 + target x (255-alpha)/255
286 }
287 else
288 {
289 if (!mixpri)
290 {
291 // source x alpha + target (clipped at 255)
292 }
293 else
294 {
295 // source + target x alpha (clipped at 255)
296 }
297
298 // DUMMY
299 if (mixlv && mixlv<0x1f) mixlv = 0x10;
300 mixlv = mixlv<<3 | mixlv>>2;
301 // alpha_set_level(mixlv);
302 }
303
304 return(mixlv);
305 }
306
K054338_invert_alpha(INT32 invert)307 void K054338_invert_alpha(INT32 invert)
308 {
309 k054338_alphainverted = invert;
310 }
311