1 // FBAlpha Toggable Shifter and Gear Display
2 //
3 // For how-to, search BurnShift in konami/d_chqflag.cpp :)
4 //
5
6 #include "burnint.h"
7 #include "burn_shift.h"
8
9 INT32 BurnShiftEnabled = 1; // enable/disable rendering
10 INT32 bBurnShiftStatus; // current status of shifter
11
12 static INT32 prev_shift;
13
14 static INT32 shift_alpha_level;
15 static INT32 shift_alpha_level2;
16 static INT32 shift_alpha_level_grey;
17 static INT32 shift_alpha_level2_grey;
18 static INT32 shift_color;
19 static INT32 shift_size;
20 static INT32 shift_position0;
21 static INT32 shift_position;
22 static INT32 shift_xpos;
23 static INT32 shift_ypos;
24 static INT32 shift_xadv;
25 static INT32 shift_yadv;
26
27 static INT32 nScreenWidth, nScreenHeight;
28 static INT32 screen_flipped;
29 static INT32 screen_vertical;
30 static INT32 flipscreen = -1;
31 static INT32 colortab[10] = { 0, 0, 0x42f4f4, 0xffffff, 0x0000ff, 0x9200f4, 0xf4f400, 0xf45900, 0x00d8f4, 0 };
32 static INT32 lhtimer = 0; // color-cycle effect counter
33
34 #define a 0,
35 #define b 1,
36 #define c 2,
37 #define d 3,
38 UINT8 BurnGearRender[8*8];
39 #if 0
40 // small font
41 UINT8 BurnGearL[8*8] = {
42 a a a a a a a a
43 a a a a a a a a
44 a a a b c a a a
45 a a a b c a a a
46 a a a b c c c a
47 a a a b b b c a
48 a a a c c c c a
49 a a a a a a a a };
50
51 UINT8 BurnGearH[8*8] = {
52 a a a a a a a a
53 a a a a a a a a
54 a a a b c b c a
55 a a a b b b c a
56 a a a b c b c a
57 a a a c c c c a
58 a a a a a a a a
59 a a a a a a a a };
60 #endif
61 #if 0
62 // blocky font (Gab75)
63 UINT8 BurnGearL[8*8] = {
64 b b d a a d a a
65 b b d a a d a a
66 d d d d d d d d
67 b b d a a d a a
68 b b d a a d a a
69 d d d d d d d d
70 b b d b b d b b
71 b b d b b d b b };
72
73 UINT8 BurnGearH[8*8] = {
74 b b d a a d b b
75 b b d a a d b b
76 d d d d d d d d
77 b b d b b d b b
78 b b d b b d b b
79 d d d d d d d d
80 b b d a a d b b
81 b b d a a d b b };
82 #endif
83 #if 1
84 // Shadow font (Gab75)
85 UINT8 BurnGearL[8*8] = {
86 a a a a a a a a
87 a a b b a a a a
88 a a b b c a a a
89 a a b b c a a a
90 a a b b c a a a
91 a a b b b b a a
92 a a a c c c c a
93 a a a a a a a a };
94
95 UINT8 BurnGearH[8*8] = {
96 a a a a a a a a
97 a b b a a b b a
98 a b b c a b b c
99 a b b b b b b c
100 a b b c c b b c
101 a b b c a b b c
102 a a c c a a c c
103 a a a a a a a a };
104 #endif
105 #undef b
106 #undef a
107 #undef c
108 #undef d
109
alpha_blend32(UINT32 d,UINT32 col)110 static UINT32 alpha_blend32(UINT32 d, UINT32 col)
111 {
112 if (col == 3) col = 3 /*0x1f1f1f*/; else
113 if (col == 2) col = 0; else
114 if (lhtimer == 0) col = colortab[1]; else
115 col = colortab[lhtimer/2];
116
117
118 if (col == 3) { // handle grey with a lighter transparency
119 col = 0x1f1f1f;
120 return (((((col & 0xff00ff) * shift_alpha_level_grey) + ((d & 0xff00ff) * shift_alpha_level2_grey)) & 0xff00ff00) |
121 ((((col & 0x00ff00) * shift_alpha_level_grey) + ((d & 0x00ff00) * shift_alpha_level2_grey)) & 0x00ff0000)) >> 8;
122 }
123
124 return (((((col & 0xff00ff) * shift_alpha_level) + ((d & 0xff00ff) * shift_alpha_level2)) & 0xff00ff00) |
125 ((((col & 0x00ff00) * shift_alpha_level) + ((d & 0x00ff00) * shift_alpha_level2)) & 0x00ff0000)) >> 8;
126 }
127
set_shift_draw_position()128 static void set_shift_draw_position()
129 {
130 shift_position = shift_position0;
131
132 if (screen_flipped ^ flipscreen) {
133 switch (shift_position & 3) {
134 case SHIFT_POSITION_TOP_LEFT: shift_position = SHIFT_POSITION_BOTTOM_RIGHT; break;
135 case SHIFT_POSITION_TOP_RIGHT: shift_position = SHIFT_POSITION_BOTTOM_LEFT; break;
136 case SHIFT_POSITION_BOTTOM_LEFT: shift_position = SHIFT_POSITION_TOP_RIGHT; break;
137 case SHIFT_POSITION_BOTTOM_RIGHT: shift_position = SHIFT_POSITION_TOP_LEFT; break;
138 }
139 }
140
141 if (BurnDrvGetFlags() & BDF_ORIENTATION_VERTICAL) {
142 BurnDrvGetVisibleSize(&nScreenHeight, &nScreenWidth);
143
144 screen_vertical = 1;
145
146 shift_xadv = 0;
147 shift_yadv = shift_size + 1;
148
149 switch (shift_position & 3)
150 {
151 case SHIFT_POSITION_TOP_LEFT:
152 shift_xpos = (nScreenWidth - 1) - shift_size;
153 shift_ypos = 1;
154 break;
155
156 case SHIFT_POSITION_BOTTOM_RIGHT:
157 shift_xpos = 1;
158 shift_ypos = (nScreenHeight - 1) - (shift_yadv * 1);
159 break;
160
161 case SHIFT_POSITION_BOTTOM_LEFT:
162 shift_xpos = 1;
163 shift_ypos = 1;
164 break;
165
166 case SHIFT_POSITION_TOP_RIGHT:
167 default:
168 shift_xpos = (nScreenWidth - 1) - shift_size;
169 shift_ypos = (nScreenHeight - 1) - (shift_yadv * 1);
170 break;
171 }
172 } else {
173 BurnDrvGetVisibleSize(&nScreenWidth, &nScreenHeight);
174
175 screen_vertical = 0;
176
177 shift_xadv = shift_size + 1;
178 shift_yadv = 0;
179
180 switch (shift_position & 3)
181 {
182 case SHIFT_POSITION_BOTTOM_LEFT:
183 shift_xpos = 1;
184 shift_ypos = (nScreenHeight - 1) - shift_size;
185 // shift_ypos;
186 break;
187
188 case SHIFT_POSITION_TOP_RIGHT:
189 shift_xpos = (nScreenWidth - 1) - (shift_xadv * 1);
190 shift_ypos = 1;
191 break;
192
193 case SHIFT_POSITION_TOP_LEFT:
194 shift_xpos = 1;
195 shift_ypos = 1;
196 break;
197
198 case SHIFT_POSITION_BOTTOM_RIGHT:
199 default:
200 shift_xpos = (nScreenWidth - 1) - (shift_xadv * 1);
201 shift_ypos = (nScreenHeight - 1) - shift_size;
202 break;
203 }
204 }
205 }
206
BurnShiftSetFlipscreen(INT32 flip)207 void BurnShiftSetFlipscreen(INT32 flip)
208 {
209 #if defined FBA_DEBUG
210 if (!Debug_BurnShiftInitted) bprintf(PRINT_ERROR, _T("BurnShiftSetFlipscreen called without init\n"));
211 #endif
212
213 flip = flip ? 1 : 0;
214
215 if (flipscreen != flip) {
216 flipscreen = flip;
217 set_shift_draw_position();
218 }
219 }
220
BurnShiftReset()221 void BurnShiftReset()
222 {
223 #if defined FBA_DEBUG
224 if (!Debug_BurnShiftInitted) bprintf(PRINT_ERROR, _T("BurnShiftReset called without init\n"));
225 #endif
226
227 prev_shift = 0;
228
229 BurnShiftSetStatus(0);
230
231 BurnShiftSetFlipscreen(0);
232
233 lhtimer = 0;
234 }
235
BurnShiftInit(INT32 position,INT32 color,INT32 transparency)236 void BurnShiftInit(INT32 position, INT32 color, INT32 transparency)
237 {
238 Debug_BurnShiftInitted = 1;
239
240 colortab[1] = shift_color = color;
241
242 shift_size = 8;
243 shift_position0 = position;
244
245 shift_alpha_level = (255 * transparency) / 100;
246 shift_alpha_level2 = 256 - shift_alpha_level;
247
248 shift_alpha_level_grey = (255 * 20) / 100;
249 shift_alpha_level2_grey = 256 - shift_alpha_level_grey;
250
251 screen_flipped = (BurnDrvGetFlags() & BDF_ORIENTATION_FLIPPED) ? 1 : 0;
252 screen_vertical = (BurnDrvGetFlags() & BDF_ORIENTATION_VERTICAL) ? 1 : 0;
253
254 BurnShiftReset();
255 }
256
BurnShiftInitDefault()257 void BurnShiftInitDefault()
258 {
259 BurnShiftInit(SHIFT_POSITION_BOTTOM_RIGHT, SHIFT_COLOR_GREEN, 80);
260 }
261
BurnShiftInputCheckToggle(UINT8 shiftinput)262 INT32 BurnShiftInputCheckToggle(UINT8 shiftinput)
263 {
264 if (prev_shift != shiftinput && shiftinput) {
265 bBurnShiftStatus = !bBurnShiftStatus;
266 BurnShiftSetStatus(bBurnShiftStatus);
267 }
268
269 prev_shift = shiftinput;
270
271 return bBurnShiftStatus;
272 }
273
BurnShiftSetStatus(UINT32 status)274 void BurnShiftSetStatus(UINT32 status)
275 {
276 #if defined FBA_DEBUG
277 if (!Debug_BurnShiftInitted) bprintf(PRINT_ERROR, _T("BurnShiftSetStatus called without init\n"));
278 #endif
279
280 bBurnShiftStatus = status ? 1 : 0;
281
282 UINT8 *source = (status) ? &BurnGearH[0] : &BurnGearL[0];
283
284 for (UINT8 y = 0; y < 8; y++)
285 for (UINT8 x = 0; x < 8; x++)
286 {
287 if ((screen_flipped ^ flipscreen)) {
288 if (screen_vertical)
289 { // flipped + vertical
290 BurnGearRender[(y * 8) + x] = source[(x * 8) + (7-y)];
291 }
292 else
293 { // flipped
294 BurnGearRender[(y * 8) + x] = source[(y * 8) + (7-x)];
295 }
296 } else if (screen_vertical)
297 { // vertical
298 BurnGearRender[(y * 8) + x] = source[(x * 8) + y];
299 } else
300 { // normal
301 BurnGearRender[(y * 8) + x] = source[(y * 8) + x];
302 }
303 }
304 lhtimer = (nBurnFPS < 4500) ? 10 : 19; // for color effects
305 }
306
BurnShiftExit()307 void BurnShiftExit()
308 {
309 #if defined FBA_DEBUG
310 if (!Debug_BurnShiftInitted) bprintf(PRINT_ERROR, _T("BurnShiftExit called without init\n"));
311 #endif
312
313 shift_alpha_level = 0;
314 shift_alpha_level2 = 0;
315 shift_alpha_level_grey = 0;
316 shift_alpha_level2_grey = 0;
317 shift_color = 0;
318 shift_size = 0;
319 shift_position = 0;
320 shift_position0 = 0;
321
322 shift_xpos = 0;
323 shift_ypos = 0;
324
325 screen_flipped = 0;
326 nScreenWidth = 0;
327 nScreenHeight = 0;
328 lhtimer = 0;
329
330 flipscreen = -1;
331
332 Debug_BurnShiftInitted = 0;
333 }
334
BurnShiftRender()335 void BurnShiftRender()
336 {
337 #if defined FBA_DEBUG
338 if (!Debug_BurnShiftInitted) bprintf(PRINT_ERROR, _T("BurnShiftRender called without init\n"));
339 #endif
340
341 if (!BurnShiftEnabled) return;
342
343 INT32 xpos = shift_xpos;
344 INT32 ypos = shift_ypos;
345 INT32 color = BurnHighCol((shift_color >> 16) & 0xff, (shift_color >> 8) & 0xff, (shift_color >> 0) & 0xff, 0);
346
347 {
348 if (xpos < 0 || xpos > (nScreenWidth - shift_size)) return;
349
350 {
351 for (INT32 y = 0; y < 8; y++)
352 {
353 UINT8 *ptr = pBurnDraw + (((ypos + y) * nScreenWidth) + xpos) * nBurnBpp;
354
355 for (INT32 x = 0; x < 8; x++) {
356 if (BurnGearRender[(y*8)+x])
357 {
358 if (nBurnBpp >= 4)
359 {
360 *((UINT32*)ptr) = alpha_blend32(*((UINT32*)ptr), BurnGearRender[(y*8)+x]);
361 }
362 else if (nBurnBpp == 3)
363 {
364 UINT32 t = alpha_blend32((ptr[2] << 16) | (ptr[1] << 8) | ptr[0], BurnGearRender[(y*8)+x]);
365
366 ptr[2] = t >> 16;
367 ptr[1] = t >> 8;
368 ptr[0] = t >> 0;
369 }
370 else if (nBurnBpp == 2 && BurnGearRender[(y*8)+x] == 1) // alpha blend not supported for 16-bit
371 {
372 *((UINT16*)ptr) = color;
373 }
374 }
375 ptr += nBurnBpp;
376 }
377 }
378 }
379
380 xpos += shift_xadv;
381 ypos += shift_yadv;
382 }
383 if (lhtimer > 0) lhtimer--;
384 }
385
BurnShiftRenderDoubleSize()386 void BurnShiftRenderDoubleSize()
387 {
388 #if defined FBA_DEBUG
389 if (!Debug_BurnShiftInitted) bprintf(PRINT_ERROR, _T("BurnShiftRender called without init\n"));
390 #endif
391
392 if (!BurnShiftEnabled) return;
393
394 if (shift_size == 8) { // need to re-init some things for 16x16 mode
395 shift_size = 16;
396 set_shift_draw_position();
397 }
398
399 INT32 xpos = shift_xpos;
400 INT32 ypos = shift_ypos;
401 INT32 color = BurnHighCol((shift_color >> 16) & 0xff, (shift_color >> 8) & 0xff, (shift_color >> 0) & 0xff, 0);
402
403 {
404 if (xpos < 0 || xpos > (nScreenWidth - shift_size)) return;
405
406 {
407 for (INT32 y = 0; y < 16; y++)
408 {
409 UINT8 *ptr = pBurnDraw + (((ypos + y) * nScreenWidth) + xpos) * nBurnBpp;
410
411 for (INT32 x = 0; x < 16; x++) {
412 if (BurnGearRender[((y/2)*8)+(x/2)])
413 {
414 if (nBurnBpp >= 4)
415 {
416 *((UINT32*)ptr) = alpha_blend32(*((UINT32*)ptr), BurnGearRender[((y/2)*8)+(x/2)]);
417 }
418 else if (nBurnBpp == 3)
419 {
420 UINT32 t = alpha_blend32((ptr[2] << 16) | (ptr[1] << 8) | ptr[0], BurnGearRender[((y/2)*8)+(x/2)]);
421
422 ptr[2] = t >> 16;
423 ptr[1] = t >> 8;
424 ptr[0] = t >> 0;
425 }
426 else if (nBurnBpp == 2 && BurnGearRender[((y/2)*8)+(x/2)] == 1) // alpha blend not supported for 16-bit
427 {
428 *((UINT16*)ptr) = color;
429 }
430 }
431 ptr += nBurnBpp;
432 }
433 }
434 }
435
436 xpos += shift_xadv;
437 ypos += shift_yadv;
438 }
439 if (lhtimer > 0) lhtimer--;
440 }
441
BurnShiftScan(INT32 nAction)442 INT32 BurnShiftScan(INT32 nAction)
443 {
444 #if defined FBA_DEBUG
445 if (!Debug_BurnShiftInitted) bprintf(PRINT_ERROR, _T("BurnShiftScan called without init\n"));
446 #endif
447
448 if (nAction & ACB_DRIVER_DATA) {
449 SCAN_VAR(bBurnShiftStatus);
450 }
451
452 if (nAction & ACB_WRITE) {
453 BurnShiftSetStatus(bBurnShiftStatus);
454 lhtimer = 0;
455 }
456
457 return 0;
458 }
459