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