]> Shamusworld >> Repos - virtualjaguar/blob - src/objectp.cpp
Adding 1.0.1/2 uncompressed tarballs to tags for historical purposes.
[virtualjaguar] / src / objectp.cpp
1 //\r
2 // Object Processor\r
3 //\r
4 \r
5 #include <stdio.h>\r
6 #include <stdlib.h>\r
7 #include <string.h>\r
8 #include "jaguar.h"\r
9 \r
10 \r
11 //#define OP_DEBUG\r
12 //#define OP_DEBUG_BMP\r
13 //WTFITF???static int cnt = 0;\r
14 extern uint32 jaguar_mainRom_crc32;\r
15 \r
16 static uint8 * op_blend_y;\r
17 static uint8 * op_blend_cc;\r
18 \r
19 #define BLEND_Y(dst,src) op_blend_y[(((uint16)dst)<<8) | ((uint16)(src))]\r
20 #define BLEND_CC(dst,src) op_blend_cc[(((uint16)dst)<<8) | ((uint16)(src))]\r
21 \r
22 \r
23 static uint8 objectp_ram[0x40];\r
24 uint8 objectp_running;\r
25 \r
26 uint8 objectp_stop_reading_list;\r
27 \r
28 #define OBJECT_TYPE_BITMAP      0\r
29 #define OBJECT_TYPE_SCALE       1\r
30 #define OBJECT_TYPE_GPU         2\r
31 #define OBJECT_TYPE_BRANCH      3\r
32 #define OBJECT_TYPE_STOP        4\r
33 /*\r
34 #define OBJECT_TYPE_BITMAP      000\r
35 #define OBJECT_TYPE_SCALE       001\r
36 #define OBJECT_TYPE_GPU         010\r
37 #define OBJECT_TYPE_BRANCH      011\r
38 #define OBJECT_TYPE_STOP        100\r
39 */\r
40 \r
41 #define CONDITION_EQUAL                 0\r
42 #define CONDITION_LESS_THAN             1\r
43 #define CONDITION_GREATER_THAN  2\r
44 #define CONDITION_OP_FLAG_SET   3\r
45 #define CONDITION_SECOND_HALF_LINE      4\r
46 \r
47 #define FLAGS_RELEASE           8\r
48 #define FLAGS_TRANSPARENT       4\r
49 #define FLAGS_READMODIFY        2\r
50 #define FLAGS_HFLIP                     1\r
51 \r
52 static uint8 op_bitmap_bit_depth[8] = { 1, 2, 4, 8, 16, 24, 32, 0 };\r
53 static uint32 op_bitmap_bit_size[8] =\r
54         { (uint32)(0.125*65536), (uint32)(0.25*65536), (uint32)(0.5*65536), (uint32)(1*65536),\r
55           (uint32)(2*65536),     (uint32)(1*65536),    (uint32)(1*65536),   (uint32)(1*65536) };\r
56 static uint32 op_pointer;\r
57 //WTFITF???static int cnt_bitmap = 0;\r
58 \r
59 //\r
60 // Object Processor bitmap processing\r
61 //\r
62 \r
63 void op_process_bitmap(int16 * backbuffer, int scanline, uint64 p0, uint64 p1, int render)\r
64 {\r
65         uint8 bitdepth = (p1 >> 12) & 0x07;\r
66         int16 ypos = ((p0 >> 3) & 0x3FF) / 2;                   // ??? What if not interlaced (/2)?\r
67         int32 xpos = (((int32)((p1 << 20) & 0xFFFFFFFF)) >> 20) - tom_getHBlankWidthInPixels();\r
68         int32 iwidth = ((p1 >> 28) & 0x3FF) * 4;\r
69         int32 dwidth = ((p1 >> 18) & 0x3FF) * 4;                // ??? Should it be signed or unsigned ???\r
70         int16 height = ((p0 >> 14) & 0x3FF) - 1;\r
71         uint32 link = ((p0 >> 24) & 0x7FFFF) << 3;\r
72         uint32 ptr = ((p0 >> 43) & 0x1FFFFF) << 3;\r
73 #ifdef OP_DEBUG_BMP\r
74         uint32  firstPix = (p1 >> 49) & 0x3F;\r
75 #endif\r
76         uint8 flags = (p1 >> 45) & 0x0F;\r
77         uint8 idx = (p1 >> 38) & 0x7F;\r
78         uint32 pitch = (p1 >> 15) & 0x07;\r
79         int16 scanline_width = tom_getVideoModeWidth();\r
80         uint8 * tom_ram_8 = tom_get_ram_pointer();\r
81         uint8 * current_line_buffer = &tom_ram_8[0x1800];\r
82         uint8 * paletteRam = &tom_ram_8[0x400];\r
83         uint8 doom_hack = 0;\r
84 \r
85 //if (scanline == 200)\r
86 //      fprintf(log_get(), "OP --> Current OPPtr: %08X, next: %08X, BMPPtr: %08X\n", op_pointer, link, ptr);\r
87 \r
88         op_pointer = link;\r
89 \r
90         if (!render || (op_pointer == 0) || (height < 0) || (dwidth < 0) || (ptr == 0) || (pitch == 0))\r
91                 return;\r
92 \r
93         if (iwidth == 0)\r
94                 dwidth = iwidth = height;\r
95 \r
96         if (jaguar_mainRom_crc32 == 0x5e705756) // doom\r
97         {\r
98                 if ((iwidth==160)&&(height==179)&&(xpos==-9)&&(ypos==24))\r
99                 {\r
100                         doom_hack=1;\r
101                         xpos=0;\r
102                 }\r
103         }\r
104         // il y a un offset vertical de 20 pour un des bitmaps\r
105         // dans dinon olympics pour une raison encore inconnue\r
106         if (jaguar_mainRom_crc32==0x3c7bfda8)\r
107         {\r
108                 if ((iwidth==220)&&(height==184)&&(ypos==0))\r
109                 {\r
110                         ypos=20;\r
111                 }\r
112         }\r
113         else\r
114         if (jaguar_mainRom_crc32==0x2f032271)\r
115         {\r
116                 ypos+=8;\r
117         }\r
118         if (op_bitmap_bit_depth[bitdepth] == 24)\r
119         {\r
120                 iwidth *= 2;\r
121                 dwidth *= 2;\r
122         }\r
123         if (op_bitmap_bit_depth[bitdepth] == 8)\r
124         {\r
125                 iwidth *= 2;\r
126                 dwidth *= 2;\r
127         }\r
128         if (op_bitmap_bit_depth[bitdepth] == 4)\r
129         {\r
130                 iwidth *= 2;\r
131                 dwidth *= 2;\r
132         }\r
133         if (op_bitmap_bit_depth[bitdepth] == 2)\r
134         {\r
135                 iwidth *= 2;\r
136                 dwidth *= 2;\r
137         }\r
138         if (op_bitmap_bit_depth[bitdepth] == 1)\r
139         {\r
140                 iwidth *= 2;\r
141                 dwidth *= 2;\r
142         }\r
143         // Power Drive Rally (fixed size bitmaps have a 240 lines vertical offset)\r
144         // but could well be a modulo 240\r
145         if (jaguar_mainRom_crc32==0x0ab88d90)\r
146                 ypos %= 240;\r
147 \r
148 #ifdef OP_DEBUG_BMP\r
149         fprintf(log_get(),"bitmap %ix%i %ibpp at %i,%i firstpix=%i ptr=0x%.8x pitch %i hflipped=%s dwidth=%i (linked to 0x%.8x) Transluency=%s\n",iwidth,height,op_bitmap_bit_depth[bitdepth],xpos,ypos,firstPix,ptr,pitch,flags&FLAGS_HFLIP?"yes":"no",dwidth,op_pointer,(flags&FLAGS_READMODIFY)?"yes":"no");\r
150 #endif\r
151 \r
152         if ((scanline < ypos) || (scanline > (ypos + height)))\r
153                 return;\r
154 \r
155         // seek to the good bitmap scanline\r
156         // not sure for palettized modes\r
157         if (op_bitmap_bit_depth[bitdepth] > 8)\r
158                 ptr += ((dwidth * op_bitmap_bit_size[bitdepth]) >> 16) * (scanline - ypos);\r
159         else\r
160                 ptr += dwidth * (scanline - ypos);\r
161 \r
162         if (xpos < 0)\r
163         {\r
164                 iwidth += xpos;\r
165                 ptr += (pitch * op_bitmap_bit_size[bitdepth] * (-xpos)) >> 16;\r
166                 xpos = 0;\r
167         }\r
168 \r
169         if (iwidth <= 0)\r
170         {\r
171 #ifdef OP_DEBUG_BMP\r
172                 fprintf(log_get(), "not rendering because iwidth <= 0\n");\r
173 #endif\r
174                 return;\r
175         }\r
176         \r
177         if (flags & FLAGS_HFLIP)\r
178         {\r
179                 if ((xpos < 0) || ((xpos - iwidth) >= scanline_width))\r
180                         return;\r
181 \r
182                 if ((xpos - iwidth) < 0)\r
183                         iwidth = xpos;\r
184         }\r
185         else\r
186         {\r
187                 if (((xpos + iwidth) < 0) || (xpos >= scanline_width))\r
188                         return;\r
189 \r
190                 if ((xpos + iwidth) > scanline_width)\r
191                         iwidth = scanline_width - xpos;\r
192         }\r
193 \r
194         current_line_buffer += xpos * 2; // 2 in 16 bpp modes (need to take the mode into account)\r
195 \r
196         // doom switches the resolution from 320 to 160 to double the display width\r
197         // this is not yet supported\r
198         if (doom_hack)\r
199         {\r
200                 while (iwidth)\r
201                 {\r
202                         uint8 d0=jaguar_byte_read(ptr+0);\r
203                         uint8 d1=jaguar_byte_read(ptr+1);\r
204                         *current_line_buffer++=d0;\r
205                         *current_line_buffer++=d1;\r
206                         *current_line_buffer++=d0;\r
207                         *current_line_buffer++=d1;\r
208                         ptr+=2;\r
209                         iwidth--;\r
210                 }\r
211                 return;\r
212         }\r
213         if (op_bitmap_bit_depth[bitdepth] == 1)\r
214         {\r
215                 if (pitch == 1)\r
216                 {\r
217 #include "fbmpop1.h"\r
218                 }\r
219                 else\r
220                 {\r
221 #include "fbmpop1p.h"\r
222                 }\r
223         }\r
224         else if (op_bitmap_bit_depth[bitdepth] == 2)\r
225         {\r
226                 if (pitch == 1)\r
227                 {\r
228 #include "fbmpop2.h"\r
229                 }\r
230                 else\r
231                 {\r
232 #include "fbmpop2p.h"\r
233                 }\r
234         }\r
235         else if (op_bitmap_bit_depth[bitdepth] == 4)\r
236         {\r
237                 if (pitch == 1)\r
238                 {\r
239 #include "fbmpop4.h"\r
240                 }\r
241                 else\r
242                 {\r
243 #include "fbmpop4p.h"\r
244                 }\r
245         }\r
246         else if (op_bitmap_bit_depth[bitdepth] == 8)\r
247         {\r
248                 if (pitch == 1)\r
249                 {\r
250 #include "fbmpop8.h"\r
251                 }\r
252                 else\r
253                 {\r
254 #include "fbmpop8p.h"\r
255                 }\r
256         }\r
257         else if (op_bitmap_bit_depth[bitdepth] == 16)\r
258         {\r
259                 if (pitch == 1)\r
260                 {\r
261 #include "fbmpop16.h"\r
262                 }\r
263                 else\r
264                 {\r
265 #include "fbmpop16p.h"\r
266                 }\r
267         }\r
268         else if (op_bitmap_bit_depth[bitdepth] == 24)\r
269         {\r
270                 if (pitch == 1)\r
271                 {\r
272 #include "fbmpop24.h"\r
273                 }\r
274                 else\r
275                 {\r
276 #include "fbmpop24p.h"\r
277                 }\r
278         }\r
279 }\r
280 \r
281 //\r
282 // Object Processor scaled bitmap processing\r
283 //\r
284 \r
285 void op_process_scaled_bitmap(int16 * backbuffer, int scanline, uint64 p0, uint64 p1, uint64 p2, int render)\r
286 {\r
287 //      if ((render == 0) || (op_pointer == 0) || (height < 0) || (dwidth < 0) || (ptr == 0) || (pitch == 0))\r
288 \r
289         int32 xpos = (((int32)((p1 << 20) & 0xFFFFFFFF)) >> 20) - tom_getHBlankWidthInPixels();\r
290         int16 ypos = ((p0 & 0x3FF8) >> 3) / 2;\r
291         uint16 iwidth = ((p1 >> 28) & 0x3FF) * 4;\r
292         int16 dwidth = ((p1 >> 18) & 0x3FF) * 4;                // ??? Signed or unsigned ???\r
293         int16 height = (p0 >> 14) & 0x3FF;                              // ??? Signed or unsigned ???\r
294         uint32 link = ((p0 >> 24) & 0x7FFFF) << 3;\r
295         uint32 ptr = ((p0 >> 43) & 0x1FFFFF) << 3;\r
296 //unused        uint32 firstPix = (p1 >> 49) & 0x3F;\r
297         uint8 flags = (p1 >> 45) & 0x0F;\r
298         uint8 idx = (p1 >> 38) & 0x7F;\r
299         uint8 pitch = (p1 >> 15) & 0x07;\r
300         uint8 bitdepth = (p1 >> 12) & 0x07;\r
301         int16 scanline_width = tom_getVideoModeWidth();\r
302         uint8 * tom_ram_8 = tom_get_ram_pointer();\r
303         uint8 * current_line_buffer = &tom_ram_8[0x1800];\r
304         uint32 vscale_fixed3p5 = ((p2 >> 8) & 0xFF);\r
305         uint32 hscale_fixed3p5 = (p2 & 0xFF);\r
306         float vscale = (float)vscale_fixed3p5 / 32.0f, hscale = (float)hscale_fixed3p5 / 32.0f;\r
307 \r
308         op_pointer = link;\r
309 \r
310         if (jaguar_mainRom_crc32==0x5a5b9c68) // atari karts\r
311         {\r
312                 if (vscale == 0.0f) \r
313                         vscale = 1.0f;\r
314 \r
315                 if (ypos == 0)\r
316                         ypos = scanline;\r
317         }\r
318 #ifdef OP_DEBUG_BMP\r
319         if (xpos == -3)\r
320                 fprintf(log_get(), "[scanline %i] %ix%i scaled to %ix%i scale (%f, %f)%i bpp pitch %i at (%i,%i) @ 0x%.8x Transluency=%s\n",\r
321                         scanline, iwidth,height, (int)(iwidth*hscale), (int)(height*vscale), hscale, vscale,\r
322                         op_bitmap_bit_depth[bitdepth], pitch, xpos, ypos, ptr, (flags&FLAGS_READMODIFY) ? "yes" : "no");\r
323 #endif\r
324         if (jaguar_mainRom_crc32==0x2f032271)\r
325                 ypos += 8;\r
326 \r
327         if ((render == 0) || (op_pointer == 0) || (height < 0) || (dwidth < 0) || (ptr == 0) || (pitch == 0))\r
328                 return;\r
329 \r
330         if (op_bitmap_bit_depth[bitdepth]==8)\r
331         {\r
332                 iwidth*=2;\r
333                 dwidth*=2;\r
334         }\r
335         if (op_bitmap_bit_depth[bitdepth]==4)\r
336         {\r
337                 iwidth*=2;\r
338                 dwidth*=2;\r
339         }\r
340         if (op_bitmap_bit_depth[bitdepth]==2)\r
341         {\r
342                 iwidth*=2;\r
343                 dwidth*=2;\r
344         }\r
345         if (op_bitmap_bit_depth[bitdepth]==1)\r
346         {\r
347                 iwidth*=2;\r
348                 dwidth*=2;\r
349         }\r
350 \r
351         uint16 scaled_width = (uint16)((float)iwidth * hscale),\r
352                 scaled_height = (uint16)((float)height * vscale);\r
353 \r
354         if (op_bitmap_bit_depth[bitdepth] == 4) // why ?\r
355                 scaled_width *= 2;\r
356 \r
357         if (op_bitmap_bit_depth[bitdepth] == 2) // why ?\r
358                 scaled_width *= 4;\r
359 \r
360         if (op_bitmap_bit_depth[bitdepth] == 1) // why ?\r
361                 scaled_width *= 8;\r
362 \r
363         // seek to the good bitmap scanline\r
364         // not sure for palettized modes\r
365         if (op_bitmap_bit_depth[bitdepth] > 8)\r
366                 ptr += ((dwidth * op_bitmap_bit_size[bitdepth]) >> 16) * ((uint32)((scanline - ypos) / vscale));\r
367         else\r
368                 ptr += dwidth * ((uint32)((scanline - ypos) / vscale));\r
369 \r
370         // visible ?\r
371         if ((scanline < ypos) || (scanline > (ypos+scaled_height)) || ((xpos+scaled_width) < 0)\r
372                 || (xpos >= scanline_width))\r
373                 return;\r
374         \r
375         if (xpos < 0)\r
376         {\r
377                 scaled_width += xpos;\r
378                 ptr += (pitch * op_bitmap_bit_size[bitdepth] * ((uint32)((-xpos) / hscale))) >> 16;\r
379                 xpos = 0;\r
380         }\r
381 \r
382         if (iwidth<=0)\r
383                 return;\r
384 \r
385         if (flags&FLAGS_HFLIP)\r
386         {\r
387                 if ((xpos<0)||((xpos-scaled_width)>=scanline_width))\r
388                         return;\r
389 \r
390                 if ((xpos-scaled_width)<0)\r
391                         scaled_width=xpos;\r
392         }\r
393         else\r
394         {\r
395                 if (((xpos+scaled_width)<0)||(xpos>=scanline_width))\r
396                         return;\r
397 \r
398                 if ((xpos+scaled_width)>scanline_width)\r
399                         scaled_width=scanline_width-xpos;\r
400         }\r
401         \r
402         current_line_buffer += xpos * 2;\r
403 \r
404         int32 hscale_fixed = (int32)(65536.0f / hscale);\r
405         int32 cnt = 0;\r
406 \r
407         if (op_bitmap_bit_depth[bitdepth] == 1)\r
408         {\r
409                 if (pitch == 1)\r
410                 {\r
411 #include "zbmpop1.h"\r
412                 }\r
413                 else\r
414                 {\r
415 #include "zbmpop1p.h"\r
416                 }\r
417         }\r
418         else if (op_bitmap_bit_depth[bitdepth] == 2)\r
419         {\r
420                 if (pitch == 1)\r
421                 {\r
422 #include "zbmpop2.h"\r
423                 }\r
424                 else\r
425                 {\r
426 #include "zbmpop2p.h"\r
427                 }\r
428         }\r
429         else if (op_bitmap_bit_depth[bitdepth] == 4)\r
430         {\r
431                 if (pitch == 1)\r
432                 {\r
433 #include "zbmpop4.h"\r
434                 }\r
435                 else\r
436                 {\r
437 #include "zbmpop4p.h"\r
438                 }\r
439         }\r
440         else if (op_bitmap_bit_depth[bitdepth] == 8)\r
441         {\r
442                 if (pitch == 1)\r
443                 {\r
444 #include "zbmpop8.h"\r
445                 }\r
446                 else\r
447                 {\r
448 #include "zbmpop8p.h"\r
449                 }\r
450         }\r
451         else if (op_bitmap_bit_depth[bitdepth] == 16)\r
452         {\r
453                 if (pitch == 1)\r
454                 {\r
455 #include "zbmpop16.h"\r
456                 }\r
457                 else\r
458                 {\r
459 #include "zbmpop16p.h"\r
460                 }\r
461         }\r
462         else\r
463                 fprintf(log_get(),"(unimplemented) %i bpp scaled bitmap\n",op_bitmap_bit_depth[bitdepth]);\r
464 }\r
465 \r
466 uint64 op_load_phrase(uint32 offset)\r
467 {\r
468         offset &= ~0x07;                                                // 8 byte alignment\r
469         return ((uint64)jaguar_long_read(offset) << 32) | (uint64)jaguar_long_read(offset+4);\r
470 }\r
471 \r
472 //\r
473 // Object Processor main list processing\r
474 //\r
475 \r
476 void op_process_list(int16 * backbuffer, int scanline, int render)\r
477 {\r
478 //      char * condition_to_str[8] =\r
479 //              { "==", "<", ">", "(opflag set)", "(second half line)", "?", "?", "?" };\r
480 //WTFITF???     cnt_bitmap = 0;\r
481 \r
482         if (scanline < tom_get_vdb())\r
483                 return;\r
484 \r
485         if (scanline >= 525)//tom_getVideoModeHeight()+tom_get_vdb())\r
486                 return;\r
487 \r
488         op_pointer = op_get_list_pointer();\r
489 \r
490         objectp_stop_reading_list = 0;\r
491 //WTFITF???     cnt = 0;\r
492 \r
493 //      if (op_pointer) fprintf(log_get()," new op list at 0x%.8x scanline %i\n",op_pointer,scanline);\r
494         while (op_pointer)\r
495         {\r
496                 if (objectp_stop_reading_list)\r
497                         return;\r
498                         \r
499                 uint64 p0 = op_load_phrase(op_pointer);\r
500                 op_pointer += 8;\r
501 /*if (scanline == tom_get_vdb())\r
502 {\r
503 fprintf(log_get(), "%08X --> phrase %08X %08X", op_pointer - 8, (int)(p0>>32), (int)(p0&0xFFFFFFFF));\r
504 if ((p0 & 0x07) == OBJECT_TYPE_BITMAP)\r
505 {\r
506 fprintf(log_get(), " (BITMAP) ");\r
507 uint64 p1 = op_load_phrase(op_pointer);\r
508 fprintf(log_get(), "\n%08X --> phrase %08X %08X ", op_pointer, (int)(p1>>32), (int)(p1&0xFFFFFFFF));\r
509         uint8 bitdepth = (p1 >> 12) & 0x07;\r
510         int16 ypos = ((p0 >> 3) & 0x3FF);                       // ??? What if not interlaced (/2)?\r
511 //      int32 xpos = (((int32)((p1 << 20) & 0xFFFFFFFF)) >> 20);\r
512 int32 xpos = p1 & 0xFFF;\r
513 xpos = (xpos & 0x800 ? xpos | 0xFFFFF000 : xpos);\r
514         uint32 iwidth = ((p1 >> 28) & 0x3FF);\r
515         uint32 dwidth = ((p1 >> 18) & 0x3FF);           // ??? Should it be signed or unsigned ???\r
516         int16 height = ((p0 >> 14) & 0x3FF) - 1;\r
517         uint32 link = ((p0 >> 24) & 0x7FFFF) << 3;\r
518         uint32 ptr = ((p0 >> 43) & 0x1FFFFF) << 3;\r
519         uint32 firstPix = (p1 >> 49) & 0x3F;\r
520         uint8 flags = (p1 >> 45) & 0x0F;\r
521         uint8 idx = (p1 >> 38) & 0x7F;\r
522         uint32 pitch = (p1 >> 15) & 0x07;\r
523 fprintf(log_get(), "[%u (%u) x %u @ %i, %u (%u bpp), l: %08X, p: %08X fp: %02X, fl:%02X, idx:%02X, pt:%02X]\n", iwidth, dwidth, height, xpos, ypos, op_bitmap_bit_depth[bitdepth], link, ptr, firstPix, flags, idx, pitch);\r
524 uint8 * jaguar_mainRam = GetRamPtr();\r
525 fprintf(log_get(), "[RAM] --> ");\r
526 for(int k=0; k<16; k++)\r
527         fprintf(log_get(), "%02X ", jaguar_mainRam[op_pointer-8 + k]);\r
528 fprintf(log_get(), "\n");\r
529 }\r
530 if ((p0 & 0x07) == OBJECT_TYPE_SCALE)\r
531 {\r
532 fprintf(log_get(), " (SCALED BITMAP)\n");\r
533 }\r
534 if ((p0 & 0x07) == OBJECT_TYPE_GPU)\r
535 fprintf(log_get(), " (GPU)\n");\r
536 if ((p0 & 0x07) == OBJECT_TYPE_BRANCH)\r
537 {\r
538 fprintf(log_get(), " (BRANCH)\n");\r
539 uint8 * jaguar_mainRam = GetRamPtr();\r
540 fprintf(log_get(), "[RAM] --> ");\r
541 for(int k=0; k<8; k++)\r
542         fprintf(log_get(), "%02X ", jaguar_mainRam[op_pointer-8 + k]);\r
543 fprintf(log_get(), "\n");\r
544 }\r
545 if ((p0 & 0x07) == OBJECT_TYPE_STOP)\r
546 fprintf(log_get(), "    --> List end\n");\r
547 }*/\r
548                 \r
549 //              fprintf(log_get(),"0x%.8x type %i\n",op_pointer,((uint8)p0&0x07));              \r
550                 switch ((uint8)p0 & 0x07)\r
551                 {\r
552                 case OBJECT_TYPE_BITMAP:\r
553                 {\r
554                         uint64 p1 = op_load_phrase(op_pointer);\r
555                         op_pointer += 8;\r
556                         op_process_bitmap(backbuffer, scanline, p0, p1, render);\r
557                         break;\r
558                 }\r
559                 case OBJECT_TYPE_SCALE:\r
560                 {\r
561                         uint64 p1 = op_load_phrase(op_pointer);\r
562                         op_pointer += 8;\r
563                         uint64 p2 = op_load_phrase(op_pointer);\r
564                         op_pointer += 8;\r
565                         op_process_scaled_bitmap(backbuffer, scanline, p0, p1, p2, render);\r
566                         break;\r
567                 }\r
568                 case OBJECT_TYPE_GPU:\r
569                 {\r
570 //unused                        uint64 data = p0 >> 3;\r
571                         op_set_current_object(p0);\r
572                         gpu_set_irq_line(3, 1); \r
573                         break;\r
574                 }\r
575                 case OBJECT_TYPE_BRANCH:\r
576                 {\r
577                         uint16 vcnt = (p0 >> 3) & 0x7FF;\r
578                         uint8  cc   = (p0 >> 14) & 0x03;\r
579                         uint32 link = ((p0 >> 24) & 0x1FFFFF) << 3;\r
580                         \r
581 //                      if ((vcnt!=507)&&(vcnt!=25))\r
582 //                              fprintf(log_get(),"\t%i%s%i link=0x%.8x\n",scanline,condition_to_str[cc],vcnt>>1,link);\r
583                         switch (cc)\r
584                         {\r
585                         case CONDITION_EQUAL:\r
586                                 if ((vcnt != 0x7FF) && (vcnt & 0x01))\r
587                                         vcnt ^= 0x01;\r
588                                 if (((2 * tom_get_scanline()) == vcnt) || (vcnt == 0x7FF))\r
589                                         op_pointer = link;\r
590                                 break;\r
591                         case CONDITION_LESS_THAN:\r
592                                 if ((2 * tom_get_scanline()) < vcnt)\r
593                                         op_pointer = link;\r
594                                 break;\r
595                         case CONDITION_GREATER_THAN:\r
596                                 if ((2 * tom_get_scanline()) > vcnt)\r
597                                         op_pointer = link;\r
598                                 break;\r
599                         case CONDITION_OP_FLAG_SET:\r
600                                 if (op_get_status_register() & 0x01)\r
601                                         op_pointer = link;\r
602                                 break;\r
603                         case CONDITION_SECOND_HALF_LINE:\r
604                                 fprintf(log_get(), "op: unexpected CONDITION_SECOND_HALF_LINE in BRANCH object\nop: shuting down\n");\r
605                                 fclose(log_get());\r
606                                 exit(0);\r
607                                 break;\r
608                         default:\r
609                                 fprintf(log_get(),"op: unimplemented branch condition %i\n", cc);\r
610                         }\r
611                         break;\r
612                 }\r
613                 case OBJECT_TYPE_STOP:\r
614                 {\r
615                         // unsure\r
616                         op_set_status_register(((p0>>3) & 0xFFFFFFFF));\r
617                         \r
618                         if (p0 & 0x8)\r
619                         {\r
620                                 tom_set_pending_object_int();\r
621                                 if ((tom_irq_enabled(2)) && (jaguar_interrupt_handler_is_valid(64)))\r
622                                 {\r
623 //                                      s68000interrupt(7,64);\r
624 //                                      s68000flushInterrupts();\r
625                                         m68k_set_irq(7);                                // Cause an NMI to occur...\r
626                                 }\r
627                         }\r
628 \r
629                         return;\r
630                         break;\r
631                 }\r
632                 default:\r
633                         fprintf(log_get(),"op: unknown object type %i\n", ((uint8)p0 & 0x07)); \r
634                         return;\r
635                 }\r
636         }\r
637 }\r
638 \r
639 //\r
640 // Object Processor initialization\r
641 //\r
642 \r
643 void op_init(void)\r
644 {\r
645         memory_malloc_secure((void **)&op_blend_y, 0x10000, "Jaguar Object processor Y blend lookup table");\r
646         memory_malloc_secure((void **)&op_blend_cc, 0x10000, "Jaguar Object processor C blend lookup table");\r
647 \r
648         for(int i=0; i<256*256; i++)\r
649         {\r
650                 int y = (i >> 8) & 0xFF;\r
651                 int dy = (int8)(i & 0xFF);\r
652                 y += dy;\r
653                 if (y < 0)\r
654                         y = 0;\r
655                 else if (y > 0xFF)\r
656                         y = 0xFF;\r
657                 op_blend_y[i] = y;\r
658         }\r
659 \r
660         for(int i=0; i<256*256; i++)\r
661         {\r
662                 int cl = (i >> 8) & 0xFF;\r
663                 int dcl = (int8)(i & 0xFF);\r
664                 cl += dcl;\r
665                 if (cl < 0)\r
666                         cl = 0;\r
667                 else if (cl > 0xFF)\r
668                         cl = 0xFF;\r
669                 op_blend_cc[i] = cl;\r
670         }\r
671         op_reset();\r
672 }\r
673 \r
674 //\r
675 // Object Processor reset\r
676 //\r
677 \r
678 void op_reset(void)\r
679 {\r
680         memset(objectp_ram, 0x00, 0x40);\r
681         objectp_running = 0;\r
682 }\r
683 \r
684 void op_done(void)\r
685 {\r
686 }\r
687 \r
688 void op_byte_write(uint32 offset, uint8 data)\r
689 {\r
690         offset &= 0x3F;\r
691         objectp_ram[offset] = data;\r
692 }\r
693 \r
694 void op_word_write(uint32 offset, uint16 data)\r
695 {\r
696         offset &= 0x3F;\r
697         objectp_ram[offset] = (data >> 8) & 0xFF;\r
698         objectp_ram[offset+1] = data & 0xFF;\r
699 \r
700 /*if (offset == 0x20)\r
701 fprintf(log_get(), "OP: Setting lo list pointer: %04X\n", data);\r
702 if (offset == 0x22)\r
703 fprintf(log_get(), "OP: Setting hi list pointer: %04X\n", data);//*/\r
704 }\r
705 \r
706 // Memory range: F00010 - F00027\r
707 \r
708 uint8 op_byte_read(uint32 offset)\r
709 {\r
710         offset &= 0x3F;\r
711         return objectp_ram[offset];\r
712 }\r
713 \r
714 uint16 op_word_read(uint32 offset)\r
715 {\r
716         return (objectp_ram[offset & 0x3F] << 8) | objectp_ram[(offset+1) & 0x3F];\r
717 }\r
718 \r
719 //      F00010-F00017   R     xxxxxxxx xxxxxxxx   OB - current object code from the graphics processor\r
720 //      F00020-F00023     W   xxxxxxxx xxxxxxxx   OLP - start of the object list\r
721 //      F00026            W   -------- -------x   OBF - object processor flag\r
722 \r
723 uint32 op_get_list_pointer(void)\r
724 {\r
725         // Note: This register is WORD swapped, hence the funky look of this...\r
726 /*      uint32 ptr = objectp_ram[0x22];\r
727         ptr <<= 8;\r
728         ptr |= objectp_ram[0x23];\r
729         ptr <<= 8;\r
730         ptr |= objectp_ram[0x20];\r
731         ptr <<= 8;\r
732         ptr |= objectp_ram[0x21];\r
733 fprintf(log_get(), "OP: Getting list pointer: %08X\n", (unsigned int)ptr);\r
734         ptr &= ~0x07;\r
735 \r
736         return ptr;//*/\r
737         return (objectp_ram[0x22] << 24) | (objectp_ram[0x23] << 16) | (objectp_ram[0x20] << 8) | objectp_ram[0x21];\r
738 }\r
739 \r
740 uint32 op_get_status_register(void)\r
741 {\r
742 /*      uint32 ptr = objectp_ram[0x26];\r
743         ptr <<= 8;\r
744         ptr |= objectp_ram[0x27];\r
745         ptr <<= 8;\r
746         ptr |= objectp_ram[0x28];\r
747         ptr <<= 8;\r
748         ptr |= objectp_ram[0x29];\r
749 \r
750         return ptr;//*/\r
751         return (objectp_ram[0x26] << 24) | (objectp_ram[0x27] << 16) | (objectp_ram[0x28] << 8) | objectp_ram[0x29];\r
752 }\r
753 \r
754 void op_set_status_register(uint32 data)\r
755 {\r
756         objectp_ram[0x26] = (data & 0xFF000000) >> 24;\r
757         objectp_ram[0x27] = (data & 0x00FF0000) >> 16;\r
758         objectp_ram[0x28] = (data & 0x0000FF00) >> 8;\r
759         objectp_ram[0x29] |= (data & 0xFE);\r
760 }\r
761 \r
762 void op_set_current_object(uint64 object)\r
763 {\r
764 /*\r
765  32       28        24        20       16       12        8        4        0\r
766   +--------^---------^---------^--------^--------^--------^--------^--------+\r
767 0 |                                object-data                              |\r
768   +-------------------------------------------------------------------------+\r
769 \r
770  64       60        56        52       48       44       40       36        32\r
771   +--------^---------^---------^--------^--------^--------^--------^--------+\r
772 1 |                                object-data                              |\r
773   +-------------------------------------------------------------------------+\r
774 */\r
775         // Stored as least significant 32 bits first, ms32 last in big endian\r
776         objectp_ram[0x13] = object & 0xFF; object >>= 8;\r
777         objectp_ram[0x12] = object & 0xFF; object >>= 8;\r
778         objectp_ram[0x11] = object & 0xFF; object >>= 8;\r
779         objectp_ram[0x10] = object & 0xFF; object >>= 8;\r
780 \r
781         objectp_ram[0x17] = object & 0xFF; object >>= 8;\r
782         objectp_ram[0x16] = object & 0xFF; object >>= 8;\r
783         objectp_ram[0x15] = object & 0xFF; object >>= 8;\r
784         objectp_ram[0x14] = object & 0xFF; \r
785 }\r