1 // license:BSD-3-Clause
2 // copyright-holders:Aaron Giles
3 /***************************************************************************
4
5 Atari Jaguar object processor
6
7 ****************************************************************************/
8
9 #ifndef INCLUDE_OBJECT_PROCESSOR
10 #error jagobj.c is not directly compilable!
11 #endif
12
13
14 #define LOG_OBJECTS 0
15
16
17 /*************************************
18 *
19 * Object processor init
20 *
21 *************************************/
22
jagobj_init()23 void jaguar_state::jagobj_init()
24 {
25 int i;
26
27 /* fill tables */
28 for (i = 0; i < 256 * 256; i++)
29 {
30 int y = (i >> 8) & 0xff;
31 int dy = (int8_t)i;
32 int c1 = (i >> 8) & 0x0f;
33 int dc1 = (int8_t)(i << 4) >> 4;
34 int c2 = (i >> 12) & 0x0f;
35 int dc2 = (int8_t)(i & 0xf0) >> 4;
36
37 y += dy;
38 if (y < 0) y = 0;
39 else if (y > 0xff) y = 0xff;
40 m_blend_y[i] = y;
41
42 c1 += dc1;
43 if (c1 < 0) c1 = 0;
44 else if (c1 > 0x0f) c1 = 0x0f;
45 c2 += dc2;
46 if (c2 < 0) c2 = 0;
47 else if (c2 > 0x0f) c2 = 0x0f;
48 m_blend_cc[i] = (c2 << 4) | c1;
49 }
50 }
51
52
53
54 /*************************************
55 *
56 * Blending function
57 *
58 *************************************/
59
60 #define BLEND(dst, src) \
61 (dst) = (m_blend_cc[((dst) & 0xff00) | (((src) >> 8) & 0xff)] << 8) | m_blend_y[(((dst) & 0xff) << 8) | ((src) & 0xff)];
62
63
64
65 /*************************************
66 *
67 * 4bpp bitmap renderers
68 *
69 *************************************/
70
bitmap_4_draw(uint16_t * scanline,int32_t firstpix,int32_t iwidth,uint32_t * src,int32_t xpos,uint8_t flags,int32_t dxpos,uint16_t * clutbase)71 inline void jaguar_state::bitmap_4_draw(uint16_t *scanline, int32_t firstpix, int32_t iwidth, uint32_t *src, int32_t xpos, uint8_t flags, int32_t dxpos, uint16_t *clutbase)
72 {
73 if (firstpix & 7)
74 {
75 uint32_t pixsrc = src[firstpix >> 3];
76 while (firstpix & 7)
77 {
78 int pix = (pixsrc >> ((~firstpix & 7) << 2)) & 0x0f;
79 if ((!(flags & 4) || pix) && (uint32_t)xpos < 760)
80 {
81 if (!(flags & 2))
82 scanline[xpos] = clutbase[BYTE_XOR_BE(pix)];
83 else
84 BLEND(scanline[xpos], clutbase[BYTE_XOR_BE(pix)]);
85 }
86 xpos += dxpos;
87 firstpix++;
88 }
89 }
90
91 firstpix >>= 3;
92 iwidth >>= 3;
93 iwidth -= firstpix;
94
95 while (iwidth-- > 0)
96 {
97 uint32_t pix = src[firstpix++];
98 if (!(flags & 4) || pix)
99 {
100 if ((!(flags & 4) || (pix & 0xf0000000)) && (uint32_t)xpos < 760)
101 {
102 if (!(flags & 2))
103 scanline[xpos] = clutbase[BYTE_XOR_BE(pix >> 28)];
104 else
105 BLEND(scanline[xpos], clutbase[BYTE_XOR_BE(pix >> 28)]);
106 }
107 xpos += dxpos;
108
109 if ((!(flags & 4) || (pix & 0x0f000000)) && (uint32_t)xpos < 760)
110 {
111 if (!(flags & 2))
112 scanline[xpos] = clutbase[BYTE_XOR_BE((pix >> 24) & 0x0f)];
113 else
114 BLEND(scanline[xpos], clutbase[BYTE_XOR_BE((pix >> 24) & 0x0f)]);
115 }
116 xpos += dxpos;
117
118 if ((!(flags & 4) || (pix & 0x00f00000)) && (uint32_t)xpos < 760)
119 {
120 if (!(flags & 2))
121 scanline[xpos] = clutbase[BYTE_XOR_BE((pix >> 20) & 0x0f)];
122 else
123 BLEND(scanline[xpos], clutbase[BYTE_XOR_BE((pix >> 20) & 0x0f)]);
124 }
125 xpos += dxpos;
126
127 if ((!(flags & 4) || (pix & 0x000f0000)) && (uint32_t)xpos < 760)
128 {
129 if (!(flags & 2))
130 scanline[xpos] = clutbase[BYTE_XOR_BE((pix >> 16) & 0x0f)];
131 else
132 BLEND(scanline[xpos], clutbase[BYTE_XOR_BE((pix >> 16) & 0x0f)]);
133 }
134 xpos += dxpos;
135
136 if ((!(flags & 4) || (pix & 0x0000f000)) && (uint32_t)xpos < 760)
137 {
138 if (!(flags & 2))
139 scanline[xpos] = clutbase[BYTE_XOR_BE((pix >> 12) & 0x0f)];
140 else
141 BLEND(scanline[xpos], clutbase[BYTE_XOR_BE((pix >> 12) & 0x0f)]);
142 }
143 xpos += dxpos;
144
145 if ((!(flags & 4) || (pix & 0x00000f00)) && (uint32_t)xpos < 760)
146 {
147 if (!(flags & 2))
148 scanline[xpos] = clutbase[BYTE_XOR_BE((pix >> 8) & 0x0f)];
149 else
150 BLEND(scanline[xpos], clutbase[BYTE_XOR_BE((pix >> 8) & 0x0f)]);
151 }
152 xpos += dxpos;
153
154 if ((!(flags & 4) || (pix & 0x000000f0)) && (uint32_t)xpos < 760)
155 {
156 if (!(flags & 2))
157 scanline[xpos] = clutbase[BYTE_XOR_BE((pix >> 4) & 0x0f)];
158 else
159 BLEND(scanline[xpos], clutbase[BYTE_XOR_BE((pix >> 4) & 0x0f)]);
160 }
161 xpos += dxpos;
162
163 if ((!(flags & 4) || (pix & 0x0000000f)) && (uint32_t)xpos < 760)
164 {
165 if (!(flags & 2))
166 scanline[xpos] = clutbase[BYTE_XOR_BE(pix & 0x0f)];
167 else
168 BLEND(scanline[xpos], clutbase[BYTE_XOR_BE(pix & 0x0f)]);
169 }
170 xpos += dxpos;
171 }
172 else
173 xpos += dxpos << 3;
174 }
175 }
176
bitmap_4_0(uint16_t * scanline,int32_t firstpix,int32_t iwidth,uint32_t * src,int32_t xpos,uint16_t * clutbase)177 void jaguar_state::bitmap_4_0(uint16_t *scanline, int32_t firstpix, int32_t iwidth, uint32_t *src, int32_t xpos, uint16_t *clutbase)
178 {
179 bitmap_4_draw(scanline, firstpix, iwidth, src, xpos, 0, 1, clutbase);
180 }
181
bitmap_4_1(uint16_t * scanline,int32_t firstpix,int32_t iwidth,uint32_t * src,int32_t xpos,uint16_t * clutbase)182 void jaguar_state::bitmap_4_1(uint16_t *scanline, int32_t firstpix, int32_t iwidth, uint32_t *src, int32_t xpos, uint16_t *clutbase)
183 {
184 bitmap_4_draw(scanline, firstpix, iwidth, src, xpos, 1, -1, clutbase);
185 }
186
bitmap_4_2(uint16_t * scanline,int32_t firstpix,int32_t iwidth,uint32_t * src,int32_t xpos,uint16_t * clutbase)187 void jaguar_state::bitmap_4_2(uint16_t *scanline, int32_t firstpix, int32_t iwidth, uint32_t *src, int32_t xpos, uint16_t *clutbase)
188 {
189 bitmap_4_draw(scanline, firstpix, iwidth, src, xpos, 2, 1, clutbase);
190 }
191
bitmap_4_3(uint16_t * scanline,int32_t firstpix,int32_t iwidth,uint32_t * src,int32_t xpos,uint16_t * clutbase)192 void jaguar_state::bitmap_4_3(uint16_t *scanline, int32_t firstpix, int32_t iwidth, uint32_t *src, int32_t xpos, uint16_t *clutbase)
193 {
194 bitmap_4_draw(scanline, firstpix, iwidth, src, xpos, 3, -1, clutbase);
195 }
196
bitmap_4_4(uint16_t * scanline,int32_t firstpix,int32_t iwidth,uint32_t * src,int32_t xpos,uint16_t * clutbase)197 void jaguar_state::bitmap_4_4(uint16_t *scanline, int32_t firstpix, int32_t iwidth, uint32_t *src, int32_t xpos, uint16_t *clutbase)
198 {
199 bitmap_4_draw(scanline, firstpix, iwidth, src, xpos, 4, 1, clutbase);
200 }
201
bitmap_4_5(uint16_t * scanline,int32_t firstpix,int32_t iwidth,uint32_t * src,int32_t xpos,uint16_t * clutbase)202 void jaguar_state::bitmap_4_5(uint16_t *scanline, int32_t firstpix, int32_t iwidth, uint32_t *src, int32_t xpos, uint16_t *clutbase)
203 {
204 bitmap_4_draw(scanline, firstpix, iwidth, src, xpos, 5, -1, clutbase);
205 }
206
bitmap_4_6(uint16_t * scanline,int32_t firstpix,int32_t iwidth,uint32_t * src,int32_t xpos,uint16_t * clutbase)207 void jaguar_state::bitmap_4_6(uint16_t *scanline, int32_t firstpix, int32_t iwidth, uint32_t *src, int32_t xpos, uint16_t *clutbase)
208 {
209 bitmap_4_draw(scanline, firstpix, iwidth, src, xpos, 6, 1, clutbase);
210 }
211
bitmap_4_7(uint16_t * scanline,int32_t firstpix,int32_t iwidth,uint32_t * src,int32_t xpos,uint16_t * clutbase)212 void jaguar_state::bitmap_4_7(uint16_t *scanline, int32_t firstpix, int32_t iwidth, uint32_t *src, int32_t xpos, uint16_t *clutbase)
213 {
214 bitmap_4_draw(scanline, firstpix, iwidth, src, xpos, 7, -1, clutbase);
215 }
216
217 void (jaguar_state::*const jaguar_state::bitmap4[8])(uint16_t *, int32_t, int32_t, uint32_t *, int32_t, uint16_t *) =
218 {
219 &jaguar_state::bitmap_4_0,
220 &jaguar_state::bitmap_4_1,
221 &jaguar_state::bitmap_4_2,
222 &jaguar_state::bitmap_4_3,
223 &jaguar_state::bitmap_4_4,
224 &jaguar_state::bitmap_4_5,
225 &jaguar_state::bitmap_4_6,
226 &jaguar_state::bitmap_4_7
227 };
228
229
230
231 /*************************************
232 *
233 * 8bpp bitmap renderers
234 *
235 *************************************/
236
bitmap_8_draw(uint16_t * scanline,int32_t firstpix,int32_t iwidth,uint32_t * src,int32_t xpos,uint8_t flags,int32_t dxpos,uint16_t * clutbase)237 inline void jaguar_state::bitmap_8_draw(uint16_t *scanline, int32_t firstpix, int32_t iwidth, uint32_t *src, int32_t xpos, uint8_t flags, int32_t dxpos, uint16_t *clutbase)
238 {
239 if (firstpix & 3)
240 {
241 uint32_t pixsrc = src[firstpix >> 2];
242 while (firstpix & 3)
243 {
244 uint8_t pix = pixsrc >> ((~firstpix & 3) << 3);
245 if ((!(flags & 4) || pix) && (uint32_t)xpos < 760)
246 {
247 if (!(flags & 2))
248 scanline[xpos] = clutbase[BYTE_XOR_BE(pix)];
249 else
250 BLEND(scanline[xpos], clutbase[BYTE_XOR_BE(pix)]);
251 }
252 xpos += dxpos;
253 firstpix++;
254 }
255 }
256
257 firstpix >>= 2;
258 iwidth >>= 2;
259 iwidth -= firstpix;
260
261 while (iwidth-- > 0)
262 {
263 uint32_t pix = src[firstpix++];
264 if (!(flags & 4) || pix)
265 {
266 if ((!(flags & 4) || (pix & 0xff000000)) && (uint32_t)xpos < 760)
267 {
268 if (!(flags & 2))
269 scanline[xpos] = clutbase[BYTE_XOR_BE(pix >> 24)];
270 else
271 BLEND(scanline[xpos], clutbase[BYTE_XOR_BE(pix >> 24)]);
272 }
273 xpos += dxpos;
274
275 if ((!(flags & 4) || (pix & 0x00ff0000)) && (uint32_t)xpos < 760)
276 {
277 if (!(flags & 2))
278 scanline[xpos] = clutbase[BYTE_XOR_BE((pix >> 16) & 0xff)];
279 else
280 BLEND(scanline[xpos], clutbase[BYTE_XOR_BE((pix >> 16) & 0xff)]);
281 }
282 xpos += dxpos;
283
284 if ((!(flags & 4) || (pix & 0x0000ff00)) && (uint32_t)xpos < 760)
285 {
286 if (!(flags & 2))
287 scanline[xpos] = clutbase[BYTE_XOR_BE((pix >> 8) & 0xff)];
288 else
289 BLEND(scanline[xpos], clutbase[BYTE_XOR_BE((pix >> 8) & 0xff)]);
290 }
291 xpos += dxpos;
292
293 if ((!(flags & 4) || (pix & 0x000000ff)) && (uint32_t)xpos < 760)
294 {
295 if (!(flags & 2))
296 scanline[xpos] = clutbase[BYTE_XOR_BE(pix & 0xff)];
297 else
298 BLEND(scanline[xpos], clutbase[BYTE_XOR_BE(pix & 0xff)]);
299 }
300 xpos += dxpos;
301 }
302 else
303 xpos += dxpos << 2;
304 }
305 }
306
bitmap_8_0(uint16_t * scanline,int32_t firstpix,int32_t iwidth,uint32_t * src,int32_t xpos,uint16_t * clutbase)307 void jaguar_state::bitmap_8_0(uint16_t *scanline, int32_t firstpix, int32_t iwidth, uint32_t *src, int32_t xpos, uint16_t *clutbase)
308 {
309 bitmap_8_draw(scanline, firstpix, iwidth, src, xpos, 0, 1, clutbase);
310 }
311
bitmap_8_1(uint16_t * scanline,int32_t firstpix,int32_t iwidth,uint32_t * src,int32_t xpos,uint16_t * clutbase)312 void jaguar_state::bitmap_8_1(uint16_t *scanline, int32_t firstpix, int32_t iwidth, uint32_t *src, int32_t xpos, uint16_t *clutbase)
313 {
314 bitmap_8_draw(scanline, firstpix, iwidth, src, xpos, 1, -1, clutbase);
315 }
316
bitmap_8_2(uint16_t * scanline,int32_t firstpix,int32_t iwidth,uint32_t * src,int32_t xpos,uint16_t * clutbase)317 void jaguar_state::bitmap_8_2(uint16_t *scanline, int32_t firstpix, int32_t iwidth, uint32_t *src, int32_t xpos, uint16_t *clutbase)
318 {
319 bitmap_8_draw(scanline, firstpix, iwidth, src, xpos, 2, 1, clutbase);
320 }
321
bitmap_8_3(uint16_t * scanline,int32_t firstpix,int32_t iwidth,uint32_t * src,int32_t xpos,uint16_t * clutbase)322 void jaguar_state::bitmap_8_3(uint16_t *scanline, int32_t firstpix, int32_t iwidth, uint32_t *src, int32_t xpos, uint16_t *clutbase)
323 {
324 bitmap_8_draw(scanline, firstpix, iwidth, src, xpos, 3, -1, clutbase);
325 }
326
bitmap_8_4(uint16_t * scanline,int32_t firstpix,int32_t iwidth,uint32_t * src,int32_t xpos,uint16_t * clutbase)327 void jaguar_state::bitmap_8_4(uint16_t *scanline, int32_t firstpix, int32_t iwidth, uint32_t *src, int32_t xpos, uint16_t *clutbase)
328 {
329 bitmap_8_draw(scanline, firstpix, iwidth, src, xpos, 4, 1, clutbase);
330 }
331
bitmap_8_5(uint16_t * scanline,int32_t firstpix,int32_t iwidth,uint32_t * src,int32_t xpos,uint16_t * clutbase)332 void jaguar_state::bitmap_8_5(uint16_t *scanline, int32_t firstpix, int32_t iwidth, uint32_t *src, int32_t xpos, uint16_t *clutbase)
333 {
334 bitmap_8_draw(scanline, firstpix, iwidth, src, xpos, 5, -1, clutbase);
335 }
336
bitmap_8_6(uint16_t * scanline,int32_t firstpix,int32_t iwidth,uint32_t * src,int32_t xpos,uint16_t * clutbase)337 void jaguar_state::bitmap_8_6(uint16_t *scanline, int32_t firstpix, int32_t iwidth, uint32_t *src, int32_t xpos, uint16_t *clutbase)
338 {
339 bitmap_8_draw(scanline, firstpix, iwidth, src, xpos, 6, 1, clutbase);
340 }
341
bitmap_8_7(uint16_t * scanline,int32_t firstpix,int32_t iwidth,uint32_t * src,int32_t xpos,uint16_t * clutbase)342 void jaguar_state::bitmap_8_7(uint16_t *scanline, int32_t firstpix, int32_t iwidth, uint32_t *src, int32_t xpos, uint16_t *clutbase)
343 {
344 bitmap_8_draw(scanline, firstpix, iwidth, src, xpos, 7, -1, clutbase);
345 }
346
347 void (jaguar_state::*const jaguar_state::bitmap8[8])(uint16_t *, int32_t, int32_t, uint32_t *, int32_t, uint16_t *) =
348 {
349 &jaguar_state::bitmap_8_0,
350 &jaguar_state::bitmap_8_1,
351 &jaguar_state::bitmap_8_2,
352 &jaguar_state::bitmap_8_3,
353 &jaguar_state::bitmap_8_4,
354 &jaguar_state::bitmap_8_5,
355 &jaguar_state::bitmap_8_6,
356 &jaguar_state::bitmap_8_7
357 };
358
359
360
361 /*************************************
362 *
363 * 16bpp bitmap renderers
364 *
365 *************************************/
366
bitmap_16_draw(uint16_t * scanline,int32_t firstpix,int32_t iwidth,uint32_t * src,int32_t xpos,uint8_t flags,int32_t dxpos)367 inline void jaguar_state::bitmap_16_draw(uint16_t *scanline, int32_t firstpix, int32_t iwidth, uint32_t *src, int32_t xpos, uint8_t flags, int32_t dxpos)
368 {
369 if (firstpix & 1)
370 {
371 uint16_t pix = src[firstpix >> 1];
372 if ((!(flags & 4) || pix) && (uint32_t)xpos < 760)
373 {
374 if (!(flags & 2))
375 scanline[xpos] = pix;
376 else
377 BLEND(scanline[xpos], pix);
378 }
379 xpos += dxpos;
380 }
381
382 firstpix >>= 1;
383 iwidth >>= 1;
384 iwidth -= firstpix;
385
386 while (iwidth-- > 0)
387 {
388 uint32_t pix = src[firstpix++];
389 if (!(flags & 4) || pix)
390 {
391 if ((!(flags & 4) || (pix >> 16)) && (uint32_t)xpos < 760)
392 {
393 if (!(flags & 2))
394 scanline[xpos] = pix >> 16;
395 else
396 BLEND(scanline[xpos], pix >> 16);
397 }
398 xpos += dxpos;
399
400 if ((!(flags & 4) || (pix & 0xffff)) && (uint32_t)xpos < 760)
401 {
402 if (!(flags & 2))
403 scanline[xpos] = pix;
404 else
405 BLEND(scanline[xpos], pix);
406 }
407 xpos += dxpos;
408 }
409 else
410 xpos += dxpos << 1;
411 }
412 }
413
bitmap_16_0(uint16_t * scanline,int32_t firstpix,int32_t iwidth,uint32_t * src,int32_t xpos)414 void jaguar_state::bitmap_16_0(uint16_t *scanline, int32_t firstpix, int32_t iwidth, uint32_t *src, int32_t xpos)
415 {
416 bitmap_16_draw(scanline, firstpix, iwidth, src, xpos, 0, 1);
417 }
418
bitmap_16_1(uint16_t * scanline,int32_t firstpix,int32_t iwidth,uint32_t * src,int32_t xpos)419 void jaguar_state::bitmap_16_1(uint16_t *scanline, int32_t firstpix, int32_t iwidth, uint32_t *src, int32_t xpos)
420 {
421 bitmap_16_draw(scanline, firstpix, iwidth, src, xpos, 1, -1);
422 }
423
bitmap_16_2(uint16_t * scanline,int32_t firstpix,int32_t iwidth,uint32_t * src,int32_t xpos)424 void jaguar_state::bitmap_16_2(uint16_t *scanline, int32_t firstpix, int32_t iwidth, uint32_t *src, int32_t xpos)
425 {
426 bitmap_16_draw(scanline, firstpix, iwidth, src, xpos, 2, 1);
427 }
428
bitmap_16_3(uint16_t * scanline,int32_t firstpix,int32_t iwidth,uint32_t * src,int32_t xpos)429 void jaguar_state::bitmap_16_3(uint16_t *scanline, int32_t firstpix, int32_t iwidth, uint32_t *src, int32_t xpos)
430 {
431 bitmap_16_draw(scanline, firstpix, iwidth, src, xpos, 3, -1);
432 }
433
bitmap_16_4(uint16_t * scanline,int32_t firstpix,int32_t iwidth,uint32_t * src,int32_t xpos)434 void jaguar_state::bitmap_16_4(uint16_t *scanline, int32_t firstpix, int32_t iwidth, uint32_t *src, int32_t xpos)
435 {
436 bitmap_16_draw(scanline, firstpix, iwidth, src, xpos, 4, 1);
437 }
438
bitmap_16_5(uint16_t * scanline,int32_t firstpix,int32_t iwidth,uint32_t * src,int32_t xpos)439 void jaguar_state::bitmap_16_5(uint16_t *scanline, int32_t firstpix, int32_t iwidth, uint32_t *src, int32_t xpos)
440 {
441 bitmap_16_draw(scanline, firstpix, iwidth, src, xpos, 5, -1);
442 }
443
bitmap_16_6(uint16_t * scanline,int32_t firstpix,int32_t iwidth,uint32_t * src,int32_t xpos)444 void jaguar_state::bitmap_16_6(uint16_t *scanline, int32_t firstpix, int32_t iwidth, uint32_t *src, int32_t xpos)
445 {
446 bitmap_16_draw(scanline, firstpix, iwidth, src, xpos, 6, 1);
447 }
448
bitmap_16_7(uint16_t * scanline,int32_t firstpix,int32_t iwidth,uint32_t * src,int32_t xpos)449 void jaguar_state::bitmap_16_7(uint16_t *scanline, int32_t firstpix, int32_t iwidth, uint32_t *src, int32_t xpos)
450 {
451 bitmap_16_draw(scanline, firstpix, iwidth, src, xpos, 7, -1);
452 }
453
454 void (jaguar_state::*const jaguar_state::bitmap16[8])(uint16_t *, int32_t, int32_t, uint32_t *, int32_t) =
455 {
456 &jaguar_state::bitmap_16_0,
457 &jaguar_state::bitmap_16_1,
458 &jaguar_state::bitmap_16_2,
459 &jaguar_state::bitmap_16_3,
460 &jaguar_state::bitmap_16_4,
461 &jaguar_state::bitmap_16_5,
462 &jaguar_state::bitmap_16_6,
463 &jaguar_state::bitmap_16_7
464 };
465
466
467
468
469
470 /*************************************
471 *
472 * 32bpp bitmap renderers - needs to be verified
473 *
474 *************************************/
475
bitmap_32_draw(uint16_t * scanline,int32_t firstpix,int32_t iwidth,uint32_t * src,int32_t xpos,uint8_t flags,int32_t dxpos)476 inline void jaguar_state::bitmap_32_draw(uint16_t *scanline, int32_t firstpix, int32_t iwidth, uint32_t *src, int32_t xpos, uint8_t flags, int32_t dxpos)
477 {
478 iwidth -= firstpix;
479
480 while (iwidth-- > 0)
481 {
482 uint32_t pix = src[firstpix++];
483
484 if (xpos < 760)
485 {
486 scanline[xpos++] = (pix&0xffff0000)>>16;
487 scanline[xpos++] = pix&0xffff;
488 }
489 }
490 }
491
bitmap_32_0(uint16_t * scanline,int32_t firstpix,int32_t iwidth,uint32_t * src,int32_t xpos)492 void jaguar_state::bitmap_32_0(uint16_t *scanline, int32_t firstpix, int32_t iwidth, uint32_t *src, int32_t xpos)
493 {
494 bitmap_32_draw(scanline, firstpix, iwidth, src, xpos, 0, 1);
495 }
496
bitmap_32_1(uint16_t * scanline,int32_t firstpix,int32_t iwidth,uint32_t * src,int32_t xpos)497 void jaguar_state::bitmap_32_1(uint16_t *scanline, int32_t firstpix, int32_t iwidth, uint32_t *src, int32_t xpos)
498 {
499 bitmap_32_draw(scanline, firstpix, iwidth, src, xpos, 1, -1);
500 }
501
bitmap_32_2(uint16_t * scanline,int32_t firstpix,int32_t iwidth,uint32_t * src,int32_t xpos)502 void jaguar_state::bitmap_32_2(uint16_t *scanline, int32_t firstpix, int32_t iwidth, uint32_t *src, int32_t xpos)
503 {
504 bitmap_32_draw(scanline, firstpix, iwidth, src, xpos, 2, 1);
505 }
506
bitmap_32_3(uint16_t * scanline,int32_t firstpix,int32_t iwidth,uint32_t * src,int32_t xpos)507 void jaguar_state::bitmap_32_3(uint16_t *scanline, int32_t firstpix, int32_t iwidth, uint32_t *src, int32_t xpos)
508 {
509 bitmap_32_draw(scanline, firstpix, iwidth, src, xpos, 3, -1);
510 }
511
bitmap_32_4(uint16_t * scanline,int32_t firstpix,int32_t iwidth,uint32_t * src,int32_t xpos)512 void jaguar_state::bitmap_32_4(uint16_t *scanline, int32_t firstpix, int32_t iwidth, uint32_t *src, int32_t xpos)
513 {
514 bitmap_32_draw(scanline, firstpix, iwidth, src, xpos, 4, 1);
515 }
516
bitmap_32_5(uint16_t * scanline,int32_t firstpix,int32_t iwidth,uint32_t * src,int32_t xpos)517 void jaguar_state::bitmap_32_5(uint16_t *scanline, int32_t firstpix, int32_t iwidth, uint32_t *src, int32_t xpos)
518 {
519 bitmap_32_draw(scanline, firstpix, iwidth, src, xpos, 5, -1);
520 }
521
bitmap_32_6(uint16_t * scanline,int32_t firstpix,int32_t iwidth,uint32_t * src,int32_t xpos)522 void jaguar_state::bitmap_32_6(uint16_t *scanline, int32_t firstpix, int32_t iwidth, uint32_t *src, int32_t xpos)
523 {
524 bitmap_32_draw(scanline, firstpix, iwidth, src, xpos, 6, 1);
525 }
526
bitmap_32_7(uint16_t * scanline,int32_t firstpix,int32_t iwidth,uint32_t * src,int32_t xpos)527 void jaguar_state::bitmap_32_7(uint16_t *scanline, int32_t firstpix, int32_t iwidth, uint32_t *src, int32_t xpos)
528 {
529 bitmap_32_draw(scanline, firstpix, iwidth, src, xpos, 7, -1);
530 }
531
532 void (jaguar_state::*const jaguar_state::bitmap32[8])(uint16_t *, int32_t, int32_t, uint32_t *, int32_t) =
533 {
534 &jaguar_state::bitmap_32_0,
535 &jaguar_state::bitmap_32_1,
536 &jaguar_state::bitmap_32_2,
537 &jaguar_state::bitmap_32_3,
538 &jaguar_state::bitmap_32_4,
539 &jaguar_state::bitmap_32_5,
540 &jaguar_state::bitmap_32_6,
541 &jaguar_state::bitmap_32_7
542 };
543
544
545
lookup_pixel(const uint32_t * src,int i,int pitch,int depth)546 static inline uint8_t lookup_pixel(const uint32_t *src, int i, int pitch, int depth)
547 {
548 int ppl = 32 / depth;
549 uint32_t data = src[((i & ppl) / ppl) + ((i / (ppl<<1)) * (pitch<<1))];
550 uint8_t pix = (data >> ((~i & (ppl-1)) * depth)) & ((1 << depth) - 1);
551 return pix;
552 }
553
554
555
556 /*************************************
557 *
558 * Standard bitmap processor
559 *
560 *************************************/
561
process_bitmap(uint16_t * scanline,uint32_t * objdata,int vc,bool logit)562 uint32_t *jaguar_state::process_bitmap(uint16_t *scanline, uint32_t *objdata, int vc, bool logit)
563 {
564 /* extract minimal data */
565 uint32_t upper = objdata[0];
566 uint32_t lower = objdata[1];
567 uint32_t ypos = (lower >> 3) & 0x7ff;
568 uint32_t height = (lower >> 14) & 0x3ff;
569 uint32_t link = (lower >> 24) | ((upper & 0x7ff) << 8);
570 uint32_t data = (upper >> 11);
571 uint32_t *src = (uint32_t *)memory_base(data << 3);
572
573 if (logit)
574 {
575 /* second phrase */
576 uint32_t upper2 = objdata[2];
577 uint32_t lower2 = objdata[3];
578
579 /* extract data */
580 int32_t xpos = (int32_t)(lower2 << 20) >> 20;
581 uint8_t depth = 1 << ((lower2 >> 12) & 7);
582 uint8_t pitch = (lower2 >> 15) & 7;
583 uint32_t dwidth = (lower2 >> 18) & 0x3ff;
584 int32_t iwidth = (lower2 >> 28) | ((upper2 & 0x3f) << 4);
585 uint8_t _index = (upper2 >> 6) & 0x3f;
586 uint8_t flags = (upper2 >> 13) & 0x0f;
587 uint8_t firstpix = (upper2 >> 17) & 0x3f;
588
589 logerror(" ypos=%X height=%X link=%06X data=%06X\n", ypos, height, link << 3, data << 3);
590 logerror(" xpos=%X depth=%X pitch=%X dwidth=%X iwidth=%X index=%X flags=%X firstpix=%X\n", xpos, depth, pitch, dwidth, iwidth, _index, flags, firstpix);
591 }
592
593 /* only render if valid */
594 if (vc >= ypos && height > 0 && src)
595 {
596 /* second phrase */
597 uint32_t upper2 = objdata[2];
598 uint32_t lower2 = objdata[3];
599
600 /* extract data */
601 int32_t xpos = (int32_t)(lower2 << 20) >> 20;
602 uint8_t depthlog = (lower2 >> 12) & 7;
603 uint8_t pitch = (lower2 >> 15) & 7;
604 uint32_t dwidth = (lower2 >> 18) & 0x3ff;
605 uint32_t iwidth = ((lower2 >> 28) | ((upper2 & 0x3f) << 4)) << (6 - depthlog);
606 uint8_t _index = (upper2 >> 5) & 0xfe;
607 uint8_t flags = (upper2 >> 13) & 0x07;
608 uint8_t firstpix = ((upper2 >> 17) & 0x3f) >> depthlog;
609 int i, dxpos = (flags & 1) ? -1 : 1;
610
611 /* preadjust for firstpix */
612 xpos += firstpix * dxpos;
613
614 /* switch off the depth */
615 switch (depthlog)
616 {
617 /* 1bpp case */
618 case 0:
619 {
620 uint16_t *clut = (uint16_t *)&m_gpu_clut[0] + _index;
621
622 /* non-blending */
623 if (!(flags & 2))
624 {
625 for (i = firstpix; i < iwidth; i++)
626 {
627 uint8_t pix = lookup_pixel(src, i, pitch, 1);
628
629 if (xpos >= 0 && xpos < 760 && (pix || !(flags & 4)))
630 scanline[xpos] = clut[BYTE_XOR_BE(pix)];
631 xpos += dxpos;
632 }
633 }
634
635 /* blending */
636 else
637 {
638 for (i = firstpix; i < iwidth; i++)
639 {
640 uint8_t pix = lookup_pixel(src, i, pitch, 1);
641
642 if (xpos >= 0 && xpos < 760 && (pix || !(flags & 4)))
643 BLEND(scanline[xpos], clut[BYTE_XOR_BE(pix)]);
644 xpos += dxpos;
645 }
646 }
647 break;
648 }
649
650 /* 2bpp case */
651 case 1:
652 {
653 uint16_t *clut = (uint16_t *)&m_gpu_clut[0] + (_index & 0xfc);
654
655 /* non-blending */
656 if (!(flags & 2))
657 {
658 for (i = firstpix; i < iwidth; i++)
659 {
660 uint8_t pix = lookup_pixel(src, i, pitch, 2);
661
662 if (xpos >= 0 && xpos < 760 && (pix || !(flags & 4)))
663 scanline[xpos] = clut[BYTE_XOR_BE(pix)];
664 xpos += dxpos;
665 }
666 }
667
668 /* blending */
669 else
670 {
671 for (i = firstpix; i < iwidth; i++)
672 {
673 uint8_t pix = lookup_pixel(src, i, pitch, 2);
674
675 if (xpos >= 0 && xpos < 760 && (pix || !(flags & 4)))
676 BLEND(scanline[xpos], clut[BYTE_XOR_BE(pix)]);
677 xpos += dxpos;
678 }
679 }
680 break;
681 }
682
683 /* 4bpp case */
684 case 2:
685 /* only handle pitch=1 for now */
686 if (pitch != 1)
687 logerror("Unhandled pitch = %d\n", pitch);
688
689 (this->*bitmap4[flags])(scanline, firstpix, iwidth, src, xpos, (uint16_t *)&m_gpu_clut[0] + (_index & 0xf8));
690 break;
691
692 /* 8bpp case */
693 case 3:
694 /* only handle pitch=1 for now */
695 if (pitch != 1)
696 logerror("Unhandled pitch = %d\n", pitch);
697
698 (this->*bitmap8[flags])(scanline, firstpix, iwidth, src, xpos, (uint16_t *)&m_gpu_clut[0]);
699 break;
700
701 /* 16bpp case */
702 case 4:
703 /* only handle pitch=1 for now */
704 if (pitch != 1)
705 logerror("Unhandled pitch = %d\n", pitch);
706
707 (this->*bitmap16[flags])(scanline, firstpix, iwidth, src, xpos);
708 break;
709
710 /* 32bpp case */
711 case 5:
712 /* only handle pitch=1 for now */
713 if (pitch != 1)
714 logerror("Unhandled pitch = %d\n", pitch);
715
716 (this->*bitmap32[flags])(scanline, firstpix, iwidth, src, xpos);
717 break;
718
719 default:
720 fprintf(stderr, "Unhandled bitmap source depth = %d\n", depthlog);
721 break;
722 }
723
724 /* decrement the height and add to the source data offset */
725 objdata[0] = upper + (dwidth << 11);
726 objdata[1] = lower - (1 << 14);
727 }
728
729 return (uint32_t *)memory_base(link << 3);
730 }
731
732
733
734 /*************************************
735 *
736 * Scaled bitmap object processor
737 *
738 *************************************/
739
process_scaled_bitmap(uint16_t * scanline,uint32_t * objdata,int vc,bool logit)740 uint32_t *jaguar_state::process_scaled_bitmap(uint16_t *scanline, uint32_t *objdata, int vc, bool logit)
741 {
742 /* extract data */
743 uint32_t upper = objdata[0];
744 uint32_t lower = objdata[1];
745 uint32_t ypos = (lower >> 3) & 0x7ff;
746 uint32_t height = (lower >> 14) & 0x3ff;
747 uint32_t link = (lower >> 24) | ((upper & 0x7ff) << 8);
748 uint32_t data = (upper >> 11);
749 uint32_t *src = (uint32_t *)memory_base(data << 3);
750
751 /* third phrase */
752 uint32_t lower3 = objdata[5];
753 int32_t remainder = (lower3 >> 16) & 0xff;
754
755 if (logit)
756 {
757 /* second phrase */
758 uint32_t upper2 = objdata[2];
759 uint32_t lower2 = objdata[3];
760
761 /* extract data */
762 int32_t xpos = (int32_t)(lower2 << 20) >> 20;
763 uint8_t depth = 1 << ((lower2 >> 12) & 7);
764 uint8_t pitch = (lower2 >> 15) & 7;
765 uint32_t dwidth = (lower2 >> 18) & 0x3ff;
766 int32_t iwidth = (lower2 >> 28) | ((upper2 & 0x3f) << 4);
767 uint8_t _index = (upper2 >> 6) & 0x3f;
768 uint8_t flags = (upper2 >> 13) & 0x0f;
769 uint8_t firstpix = (upper2 >> 17) & 0x3f;
770
771 int32_t hscale = lower3 & 0xff;
772 int32_t vscale = (lower3 >> 8) & 0xff;
773
774 logerror(" ypos=%X height=%X link=%06X data=%06X\n", ypos, height, link << 3, data << 3);
775 logerror(" xpos=%X depth=%X pitch=%X dwidth=%X iwidth=%X index=%X flags=%X firstpix=%X\n", xpos, depth, pitch, dwidth, iwidth, _index, flags, firstpix);
776 logerror(" hscale=%X vscale=%X remainder=%X\n", hscale, vscale, remainder);
777 }
778
779 /* only render if valid */
780 if (vc >= ypos && (height > 0 || remainder > 0) && src)
781 {
782 /* second phrase */
783 uint32_t upper2 = objdata[2];
784 uint32_t lower2 = objdata[3];
785
786 /* extract data */
787 int32_t xpos = (int32_t)(lower2 << 20) >> 20;
788 uint8_t depthlog = (lower2 >> 12) & 7;
789 uint8_t pitch = (lower2 >> 15) & 7;
790 uint32_t dwidth = (lower2 >> 18) & 0x3ff;
791 int32_t iwidth = ((lower2 >> 28) | ((upper2 & 0x3f) << 4)) << (6 - depthlog);
792 uint8_t _index = (upper2 >> 5) & 0xfe;
793 uint8_t flags = (upper2 >> 13) & 0x07;
794 uint8_t firstpix = ((upper2 >> 17) & 0x3f) >> depthlog;
795
796 int32_t hscale = lower3 & 0xff;
797 int32_t vscale = (lower3 >> 8) & 0xff;
798 int32_t xleft = hscale;
799 int dxpos = (flags & 1) ? -1 : 1;
800 int xpix = firstpix, yinc;
801
802 /* only handle pitch=1 (sequential data) for now */
803 if (pitch != 1)
804 logerror("Unhandled pitch = %d\n", pitch);
805 if (flags & 2)
806 {
807 osd_printf_debug("Unhandled blend mode in scaled bitmap case\n");
808 logerror("Unhandled blend mode in scaled bitmap case\n");
809 }
810
811 /* preadjust for firstpix */
812 xpos += firstpix * dxpos;
813
814 /* ignore hscale = 0 */
815 if (hscale != 0)
816 {
817 /* switch off the depth */
818 switch (depthlog)
819 {
820 case 0:
821 {
822 uint16_t *clut = (uint16_t *)&m_gpu_clut[0] + _index;
823
824 /* render in phrases */
825 while (xpix < iwidth)
826 {
827 uint16_t pix = (src[xpix >> 5] >> (~xpix & 31)) & 0x01;
828
829 while (xleft > 0)
830 {
831 if (xpos >= 0 && xpos < 760 && (pix || !(flags & 4)))
832 scanline[xpos] = clut[BYTE_XOR_BE(pix)];
833 xpos += dxpos;
834 xleft -= 0x20;
835 }
836 while (xleft <= 0)
837 xleft += hscale, xpix++;
838 }
839 break;
840 }
841
842 case 1:
843 {
844 uint16_t *clut = (uint16_t *)&m_gpu_clut[0] + (_index & 0xfc);
845
846 /* render in phrases */
847 while (xpix < iwidth)
848 {
849 uint16_t pix = (src[xpix >> 4] >> ((~xpix & 15) << 1)) & 0x03;
850
851 while (xleft > 0)
852 {
853 if (xpos >= 0 && xpos < 760 && (pix || !(flags & 4)))
854 scanline[xpos] = clut[BYTE_XOR_BE(pix)];
855 xpos += dxpos;
856 xleft -= 0x20;
857 }
858 while (xleft <= 0)
859 xleft += hscale, xpix++;
860 }
861 break;
862 }
863
864 case 2:
865 {
866 uint16_t *clut = (uint16_t *)&m_gpu_clut[0] + (_index & 0xf8);
867
868 /* render in phrases */
869 while (xpix < iwidth)
870 {
871 uint16_t pix = (src[xpix >> 3] >> ((~xpix & 7) << 2)) & 0x0f;
872
873 while (xleft > 0)
874 {
875 if (xpos >= 0 && xpos < 760 && (pix || !(flags & 4)))
876 scanline[xpos] = clut[BYTE_XOR_BE(pix)];
877 xpos += dxpos;
878 xleft -= 0x20;
879 }
880 while (xleft <= 0)
881 xleft += hscale, xpix++;
882 }
883 break;
884 }
885
886 case 3:
887 {
888 uint16_t *clut = (uint16_t *)&m_gpu_clut[0];
889
890 /* render in phrases */
891 while (xpix < iwidth)
892 {
893 uint16_t pix = (src[xpix >> 2] >> ((~xpix & 3) << 3)) & 0xff;
894
895 while (xleft > 0)
896 {
897 if (xpos >= 0 && xpos < 760 && (pix || !(flags & 4)))
898 scanline[xpos] = clut[BYTE_XOR_BE(pix)];
899 xpos += dxpos;
900 xleft -= 0x20;
901 }
902 while (xleft <= 0)
903 xleft += hscale, xpix++;
904 }
905 break;
906 }
907
908 case 4:
909 while (xpix < iwidth)
910 {
911 uint16_t pix = src[xpix >> 1] >> ((~xpix & 1) << 4);
912
913 while (xleft > 0)
914 {
915 if (xpos >= 0 && xpos < 760 && (pix || !(flags & 4)))
916 scanline[xpos] = pix;
917 xpos += dxpos;
918 xleft -= 0x20;
919 }
920 while (xleft <= 0)
921 xleft += hscale, xpix++;
922 }
923 break;
924
925 default:
926 fprintf(stderr, "Unhandled scaled bitmap source depth = %d\n", depthlog);
927 break;
928 }
929 }
930
931 /* handle Y scale */
932 remainder -= 0x20;
933 yinc = 0;
934 while (remainder <= 0 && vscale != 0)
935 remainder += vscale, yinc++;
936 if (yinc > height)
937 yinc = height, remainder = 0;
938
939 /* decrement the height and add to the source data offset */
940 objdata[0] = upper + yinc * (dwidth << 11);
941 objdata[1] = lower - yinc * (1 << 14);
942 objdata[5] = (lower3 & ~0xff0000) | ((remainder & 0xff) << 16);
943 }
944
945 return (uint32_t *)memory_base(link << 3);
946 }
947
948
949
950 /*************************************
951 *
952 * Branch object processor
953 *
954 *************************************/
955
process_branch(uint32_t * objdata,int vc,bool logit)956 uint32_t *jaguar_state::process_branch(uint32_t *objdata, int vc, bool logit)
957 {
958 uint32_t upper = objdata[0];
959 uint32_t lower = objdata[1];
960 uint32_t ypos = (lower >> 3) & 0x7ff;
961 uint32_t cc = (lower >> 14) & 7;
962 uint32_t link = (lower >> 24) | ((upper & 0x7ff) << 8);
963 int taken = 0;
964
965 // if ((ypos & 1) && ypos != 0x7ff)
966 // fprintf(stderr, " branch cc=%d ypos=%X link=%06X - \n", cc, ypos, link << 3);
967
968 switch (cc)
969 {
970 /* 0: branch if ypos == vc or ypos == 0x7ff */
971 case 0:
972 if (logit) logerror(" branch if %X == vc or %X == 0x7ff to %06X\n", ypos, ypos, link << 3);
973 taken = (ypos == vc) || (ypos == 0x7ff);
974 break;
975
976 /* 1: branch if ypos > vc */
977 case 1:
978 if (logit) logerror(" branch if %X > vc to %06X\n", ypos, link << 3);
979 taken = (ypos > vc);
980 break;
981
982 /* 2: branch if ypos < vc */
983 case 2:
984 if (logit) logerror(" branch if %X < vc to %06X\n", ypos, link << 3);
985 taken = (ypos < vc);
986 break;
987
988 /* 3: branch if object processor flag is set */
989 case 3:
990 if (logit) logerror(" branch if object flag set to %06X\n", link << 3);
991 taken = m_gpu_regs[OBF] & 1;
992 break;
993
994 /* 4: branch on second half of display line */
995 case 4:
996 if (logit) logerror(" branch if second half of line to %06X\n", link << 3);
997 taken = (vc & 1);
998 break;
999
1000 default:
1001 fprintf(stderr, "Invalid branch!\n");
1002 link = 0; taken = 1;
1003 break;
1004 }
1005
1006 /* handle the branch */
1007 return taken ? (uint32_t *)memory_base(link << 3) : (objdata + 2);
1008 }
1009
1010
1011
1012 /*************************************
1013 *
1014 * Process object list
1015 *
1016 *************************************/
1017
process_object_list(int vc,uint16_t * scanline)1018 void jaguar_state::process_object_list(int vc, uint16_t *scanline)
1019 {
1020 int done = 0, count = 0;
1021 uint32_t *objdata;
1022 bool logit;
1023 int x;
1024
1025 /* erase the scanline first */
1026 for (x = 0; x < 760; x++)
1027 scanline[x] = m_gpu_regs[BG];
1028
1029 logit = LOG_OBJECTS;
1030
1031 /* fetch the object pointer */
1032 objdata = (uint32_t *)memory_base((m_gpu_regs[OLP_H] << 16) | m_gpu_regs[OLP_L]);
1033 while (!done && objdata && count++ < 100)
1034 {
1035 /* the low 3 bits determine the command */
1036 switch (objdata[1] & 7)
1037 {
1038 /* bitmap object */
1039 case 0:
1040 if (logit)
1041 logerror("bitmap = %08X-%08X %08X-%08X\n", objdata[0], objdata[1], objdata[2], objdata[3]);
1042 objdata = process_bitmap(scanline, objdata, vc, logit);
1043 break;
1044
1045 /* scaled bitmap object */
1046 case 1:
1047 if (logit)
1048 logerror("scaled = %08X-%08X %08X-%08X %08X-%08X\n", objdata[0], objdata[1], objdata[2], objdata[3], objdata[4], objdata[5]);
1049 objdata = process_scaled_bitmap(scanline, objdata, vc, logit);
1050 break;
1051
1052
1053 /* GPU interrupt */
1054 case 2:
1055 m_gpu_regs[OB_HH]=(objdata[1]&0xffff0000)>>16;
1056 m_gpu_regs[OB_HL]=objdata[1]&0xffff;
1057 m_gpu_regs[OB_LH]=(objdata[0]&0xffff0000)>>16;
1058 m_gpu_regs[OB_LL]=objdata[0]&0xffff;
1059 m_gpu->set_input_line(3, ASSERT_LINE);
1060 done=1;
1061 // mutntpng, atarikrt VPOS = 0
1062 // TODO: what the VPOS is actually for?
1063 //printf("GPU irq VPOS = %04x\n",(objdata[1] >> 3) & 0x7ff);
1064 break;
1065
1066 /* branch */
1067 case 3:
1068 if (logit)
1069 logerror("branch = %08X-%08X\n", objdata[0], objdata[1]);
1070 objdata = process_branch(objdata, vc, logit);
1071 break;
1072
1073 /* stop */
1074 case 4:
1075 {
1076 int interrupt = (objdata[1] >> 3) & 1;
1077 done = 1;
1078
1079 if (logit)
1080 logerror("stop = %08X-%08X\n", objdata[0], objdata[1]);
1081 if (interrupt)
1082 {
1083 // TODO: fball95 doesn't have a real handling for stop irq, causing the line to be always asserted, how to prevent?
1084 // fprintf(stderr, "stop int=%d\n", interrupt);
1085 trigger_host_cpu_irq(2);
1086 }
1087 break;
1088 }
1089
1090 case 6:
1091 // kasumi: F7000000 00F0311E (nop? bad align?)
1092 break;
1093
1094 default:
1095 fprintf(stderr, "%08X %08X\n", objdata[0], objdata[1]);
1096 //done = 1;
1097 break;
1098 }
1099 }
1100 }
1101