trunk/src/mame/drivers/coolridr.c
| r21474 | r21475 | |
| 2 | 2 | |
| 3 | 3 | System H1 (c) 1994 Sega |
| 4 | 4 | |
| 5 | | preliminary driver by David Haywood, Angelo Salese and Tomasz Slanina |
| 5 | Driver by David Haywood, Angelo Salese and Tomasz Slanina |
| 6 | 6 | special thanks to Guru for references and HW advices |
| 7 | 7 | |
| 8 | This system is interesting in that it makes use of an RLE compression scheme, which |
| 9 | is not something common for Sega hardware, there is a patent for it ( 6,141,122 ) |
| 10 | http://www.google.com/patents/US6141122 |
| 11 | |
| 8 | 12 | TODO: |
| 9 | | - decode compressed GFX ROMs for "sprite" blitter (6,141,122 is the patent number) |
| 10 | | http://www.google.com/patents/US6141122 |
| 11 | | - DMA is still a bit of a mystery; |
| 12 | | - video emulation is pratically non-existant; |
| 13 | | - SCSP; |
| 14 | | - Many SH-1 ports needs investigations; |
| 13 | - walk the dog |
| 14 | - improve sound emulation |
| 15 | 15 | - i8237 purpose is unknown, might even not be at the right place ... |
| 16 | | - IRQ generation |
| 17 | | - Understand & remove the hacks at the bottom; |
| 18 | | - IC1/IC10 are currently unused, might contain sprite data / music data for the SCSP / chars for the |
| 19 | | text tilemap/blitter; |
| 16 | - verify zooming etc. our current algorithm is a bit ugly for text |
| 20 | 17 | |
| 18 | |
| 19 | |
| 21 | 20 | ======================================================================================================= |
| 22 | 21 | |
| 23 | 22 | Cool Riders |
| r21474 | r21475 | |
| 274 | 273 | read a 160-bit word at once. Regardless both addresses are restricted |
| 275 | 274 | to the same bank as defined through A20. |
| 276 | 275 | |
| 277 | | From looking at the ROMs there seem to be structures that may be |
| 278 | | tables. A table would be needed to associate a tile number with RLE |
| 279 | | data in ROM, so that would be a likely function of tables in the ROM. |
| 280 | | It may be that the split address design allows the chip to read table |
| 281 | | data from one 80-bit port while reading in graphics data from the |
| 282 | | other. |
| 283 | | |
| 284 | | Now this next bit is just an interpretation of what's in the patent, |
| 285 | | so you probably already know it: |
| 286 | | |
| 287 | | The primitive unit of graphics data is a 10-bit word (hence all the |
| 288 | | multiples of 10 listed above, e.g. 80 and 160-bit words) The top two |
| 289 | | bits define the type: |
| 290 | | |
| 291 | | 0,x : $000 : Type A (3-bit color code, 5-bit run length, 1 bit "cell" flag) |
| 292 | | 1,x : $800 : Type B (7-bit color code, 2-bit run length) |
| 293 | | 1,1 : $C00 : Type C (8-bit color code) |
| 294 | | |
| 295 | | Because the top two bits (which identify the type) are shared with the |
| 296 | | color code, this limits the range of colors somewhat. E.g. one of the |
| 297 | | patent diagrams shows the upper 4 bits of a Type A pixel moved into |
| 298 | | the bottom four bits of the color RAM index, but for type A the most |
| 299 | | significant bit is always zero. So that 4-bit quantity is always 0-7 |
| 300 | | which is why type A has a limit of 8 colors. |
| 301 | | |
| 302 | | This is why one of the later diagrams shows the Type B pixel ANDed |
| 303 | | with 7F and the Type C pixel ANDed with 3FF, to indicate the two |
| 304 | | indicator bits are being stripped out and the remaining value is |
| 305 | | somewhat truncated. |
| 306 | | |
| 307 | | We figured due to the colorful graphics in the game there would be a |
| 308 | | large groups of Type C pixels, but we could never find an |
| 309 | | rearrangement of data and address bits that yielded a large number of |
| 310 | | words with bits 9,8 set. Some of the data looks like it's linear, and |
| 311 | | some of it looks like bitplanes. Perhaps tables are linear and |
| 312 | | graphics are planar. |
| 313 | | |
| 314 | | We tried the usual stuff; assuming the 16-bit words from each ROM was |
| 315 | | a 160-pixel wide array of 10-bit elements (linear), or assuming each |
| 316 | | bit from each ROM was a single bit of a 10-bit word so 16 bits defined |
| 317 | | 16 10-bit words in parallel (planar), and never got useful output. |
| 318 | | |
| 319 | | There may be some weird data/address scrambling done to put data in an |
| 320 | | order easiest for the hardware to process, which would be |
| 321 | | non-intuitive. |
| 322 | | |
| 323 | | Also the two indicator bits may have different polarities, maybe 0,0 |
| 324 | | is Type C instead of 1,1. |
| 325 | | |
| 326 | | --- CORRECTION from Charles 20/02/13 |
| 327 | | |
| 328 | | I was just playing around with decoding this morning, and now I feel |
| 329 | | certain the ordering is to take the 16-bit output of each of the 10 |
| 330 | | ROMs at a given address and divide that 160-bit word into sixteen |
| 331 | | 10-bit words. |
| 332 | | |
| 333 | | When you do this, you get some kind of animation at 0x3898E0 which is |
| 334 | | eight sequential frames of an object with a solid color fill in the |
| 335 | | background. Because the size is constant it may be all Type C pixels |
| 336 | | (e.g. no run-length) so that could be a good place to start with |
| 337 | | shuffling bits/addresses to see how to get a lot of $3xx pixels. |
| 338 | | |
| 339 | | There's a similar animation at 0x73CEC0, smaller object, 32 frames. |
| 340 | | |
| 341 | | I think the 'background' data behind the object in both cases might be |
| 342 | | a pen number that continuously increases, maybe for flashing effect as |
| 343 | | you cycle through the animation. Otherwise you'd expect the background |
| 344 | | pixels to be the same in each frame. |
| 345 | | |
| 346 | | I also wonder if a pixel value of 0000 (type A with run length=0) |
| 347 | | indicates a single dot since there are a lot of 0000 words. |
| 348 | | |
| 349 | | There may be some bit/byte/address swapping needed to still get valid |
| 350 | | output. And the tables may be encoded differently, there's a large one |
| 351 | | at 0xDE60. |
| 352 | | |
| 353 | | |
| 354 | | |
| 355 | 276 | */ |
| 356 | 277 | |
| 357 | 278 | |
| r21474 | r21475 | |
| 400 | 321 | m_io_an7(*this, "AN7"), |
| 401 | 322 | m_io_config(*this, "CONFIG") |
| 402 | 323 | { |
| 403 | | m_work_queue[0] = osd_work_queue_alloc(WORK_QUEUE_FLAG_HIGH_FREQ); |
| 404 | | m_work_queue[1] = osd_work_queue_alloc(WORK_QUEUE_FLAG_HIGH_FREQ); |
| 405 | | decode[0].current_object = 0; |
| 406 | | decode[1].current_object = 0; |
| 407 | | debug_randompal = 9; |
| 324 | |
| 408 | 325 | } |
| 409 | 326 | |
| 410 | 327 | // Blitter state |
| r21474 | r21475 | |
| 450 | 367 | |
| 451 | 368 | bitmap_ind16 m_temp_bitmap_sprites; |
| 452 | 369 | bitmap_ind16 m_temp_bitmap_sprites2; |
| 453 | | bitmap_ind16 m_zbuffer_bitmap; |
| 454 | | bitmap_ind16 m_zbuffer_bitmap2; |
| 370 | //bitmap_ind16 m_zbuffer_bitmap; |
| 371 | //bitmap_ind16 m_zbuffer_bitmap2; |
| 455 | 372 | |
| 456 | 373 | bitmap_ind16 m_bg_bitmap; |
| 457 | 374 | bitmap_ind16 m_bg_bitmap2; |
| r21474 | r21475 | |
| 543 | 460 | UINT32* indirect_zoom; |
| 544 | 461 | UINT32 spriteblit[12]; |
| 545 | 462 | bitmap_ind16* drawbitmap; |
| 546 | | bitmap_ind16* zbitmap; |
| 463 | //bitmap_ind16* zbitmap; |
| 547 | 464 | UINT16 zpri; |
| 548 | 465 | UINT8 blittype; |
| 549 | 466 | coolridr_state* state; |
| r21474 | r21475 | |
| 645 | 562 | |
| 646 | 563 | machine().primary_screen->register_screen_bitmap(m_temp_bitmap_sprites); |
| 647 | 564 | machine().primary_screen->register_screen_bitmap(m_temp_bitmap_sprites2); |
| 648 | | machine().primary_screen->register_screen_bitmap(m_zbuffer_bitmap); |
| 649 | | machine().primary_screen->register_screen_bitmap(m_zbuffer_bitmap2); |
| 565 | //machine().primary_screen->register_screen_bitmap(m_zbuffer_bitmap); |
| 566 | //machine().primary_screen->register_screen_bitmap(m_zbuffer_bitmap2); |
| 650 | 567 | machine().primary_screen->register_screen_bitmap(m_bg_bitmap); |
| 651 | 568 | machine().primary_screen->register_screen_bitmap(m_bg_bitmap2); |
| 652 | 569 | |
| r21474 | r21475 | |
| 1266 | 1183 | if (drawy>clipmaxY) { break; }; \ |
| 1267 | 1184 | if (drawy<clipminY) { drawy++; continue; }; \ |
| 1268 | 1185 | line = &drawbitmap->pix16(drawy); \ |
| 1269 | | zline = &object->zbitmap->pix16(drawy); \ |
| 1186 | /* zline = &object->zbitmap->pix16(drawy); */ \ |
| 1270 | 1187 | int blockwide = pixelOffsetnextX-pixelOffsetX; \ |
| 1271 | 1188 | if (pixelOffsetX+blockwide <clipminX) { drawy++; continue; } \ |
| 1272 | 1189 | if (pixelOffsetX>clipmaxX) { drawy++; continue; } \ |
| r21474 | r21475 | |
| 1305 | 1222 | const int drawy = pixelOffsetY+y; \ |
| 1306 | 1223 | if ((drawy>clipmaxY) || (drawy<clipminY)) continue; \ |
| 1307 | 1224 | line = &drawbitmap->pix16(drawy); \ |
| 1308 | | zline = &object->zbitmap->pix16(drawy); \ |
| 1225 | /* zline = &object->zbitmap->pix16(drawy); */ \ |
| 1309 | 1226 | int drawx = pixelOffsetX; \ |
| 1310 | 1227 | for (int x = 0; x < blockwide; x++) \ |
| 1311 | 1228 | { \ |
| r21474 | r21475 | |
| 1324 | 1241 | const int drawy = pixelOffsetY+realy; \ |
| 1325 | 1242 | if ((drawy>clipmaxY) || (drawy<clipminY)) continue; \ |
| 1326 | 1243 | line = &drawbitmap->pix16(drawy); \ |
| 1327 | | zline = &object->zbitmap->pix16(drawy); \ |
| 1244 | /* zline = &object->zbitmap->pix16(drawy); */ \ |
| 1328 | 1245 | int drawx = pixelOffsetX; \ |
| 1329 | 1246 | for (int realx = 0; realx < 16; realx++) \ |
| 1330 | 1247 | { \ |
| r21474 | r21475 | |
| 1354 | 1271 | /* values < 0x8000 have no alpha effect to them */ \ |
| 1355 | 1272 | if (pix < 0x8000) \ |
| 1356 | 1273 | { \ |
| 1357 | | if (object->zpri < zline[drawx]) \ |
| 1274 | /*if (object->zpri < zline[drawx])*/ \ |
| 1358 | 1275 | { \ |
| 1359 | 1276 | { \ |
| 1360 | 1277 | line[drawx] = pix&0x7fff; \ |
| 1361 | | zline[drawx] = object->zpri; \ |
| 1278 | /*zline[drawx] = object->zpri;*/ \ |
| 1362 | 1279 | } \ |
| 1363 | 1280 | } \ |
| 1364 | 1281 | } \ |
| r21474 | r21475 | |
| 1366 | 1283 | else if (pix > 0x8000) \ |
| 1367 | 1284 | { \ |
| 1368 | 1285 | /* a blend level of 0x8 (real register value 0x7 but we added one so we can shift instead of divide in code below) seems to be the same as solid, it is set on most parts of the road and during the 'lovemachine' animation in attract when the heart should be hidden */ \ |
| 1369 | | if (object->zpri < zline[drawx]) \ |
| 1286 | /* if (object->zpri < zline[drawx]) */ \ |
| 1370 | 1287 | { \ |
| 1371 | 1288 | if (blit4blendlevelinv==0x0) \ |
| 1372 | 1289 | { \ |
| 1373 | 1290 | line[drawx] = pix&0x7fff; \ |
| 1374 | | zline[drawx] = object->zpri; \ |
| 1291 | /* zline[drawx] = object->zpri; */ \ |
| 1375 | 1292 | } \ |
| 1376 | 1293 | else \ |
| 1377 | 1294 | { \ |
| r21474 | r21475 | |
| 1383 | 1300 | int dest_g = ((pix>>5)&0x1f) * blit4blendlevel; \ |
| 1384 | 1301 | int dest_b = ((pix>>0)&0x1f) * blit4blendlevel; \ |
| 1385 | 1302 | line[drawx] = (((src_r+dest_r)>>3)<<10) | (((src_g+dest_g)>>3)<<5) | (((src_b+dest_b)>>3)<<0); \ |
| 1386 | | zline[drawx] = object->zpri; \ |
| 1303 | /* zline[drawx] = object->zpri; */ \ |
| 1387 | 1304 | } \ |
| 1388 | 1305 | } \ |
| 1389 | 1306 | } \ |
| r21474 | r21475 | |
| 2099 | 2016 | |
| 2100 | 2017 | // DEBUG: Draw 16x16 block |
| 2101 | 2018 | UINT16* line; |
| 2102 | | UINT16* zline; |
| 2019 | //UINT16* zline; |
| 2103 | 2020 | |
| 2104 | 2021 | |
| 2105 | 2022 | if (indirect_zoom_enable) |
| r21474 | r21475 | |
| 2414 | 2331 | if (m_blitterMode == 0x30 || m_blitterMode == 0x40 || m_blitterMode == 0x4f || m_blitterMode == 0x50 || m_blitterMode == 0x60) |
| 2415 | 2332 | { |
| 2416 | 2333 | testobject->drawbitmap = &m_temp_bitmap_sprites; |
| 2417 | | testobject->zbitmap = &m_zbuffer_bitmap; |
| 2334 | /* testobject->zbitmap = &m_zbuffer_bitmap; */ |
| 2418 | 2335 | // pass these from the type 1 writes |
| 2419 | 2336 | testobject->clipvals[0] = m_clipvals[0][0]; |
| 2420 | 2337 | testobject->clipvals[1] = m_clipvals[0][1]; |
| r21474 | r21475 | |
| 2427 | 2344 | else // 0x90, 0xa0, 0xaf, 0xb0, 0xc0 |
| 2428 | 2345 | { |
| 2429 | 2346 | testobject->drawbitmap = &m_temp_bitmap_sprites2; |
| 2430 | | testobject->zbitmap = &m_zbuffer_bitmap2; |
| 2347 | /* testobject->zbitmap = &m_zbuffer_bitmap2; */ |
| 2431 | 2348 | // pass these from the type 1 writes |
| 2432 | 2349 | testobject->clipvals[0] = m_clipvals[1][0]; |
| 2433 | 2350 | testobject->clipvals[1] = m_clipvals[1][1]; |
| r21474 | r21475 | |
| 2700 | 2617 | // render the tilemap to the backbuffer, ready for having sprites drawn on it |
| 2701 | 2618 | draw_bg_coolridr(m_temp_bitmap_sprites, visarea, 0); |
| 2702 | 2619 | // wipe the z-buffer ready for the sprites |
| 2703 | | m_zbuffer_bitmap.fill(0xffff, visarea); |
| 2620 | /* m_zbuffer_bitmap.fill(0xffff, visarea); */ |
| 2704 | 2621 | // almost certainly wrong |
| 2705 | 2622 | m_clipvals[0][0] = 0; |
| 2706 | 2623 | m_clipvals[0][1] = 0; |
| 2707 | 2624 | m_clipvals[0][2] = 0; |
| 2708 | 2625 | m_clipblitterMode[0] = 0xff; |
| 2709 | 2626 | |
| 2710 | | //qsort(m_cool_render_object_list1, m_listcount1, sizeof(struct cool_render_object *), comp_sprite_z); |
| 2627 | /* bubble sort, might be something better to use instead */ |
| 2628 | for (int pass = 0 ; pass < ( m_listcount1 - 1 ); pass++) |
| 2629 | { |
| 2630 | for (int elem2 = 0 ; elem2 < m_listcount1 - pass - 1; elem2++) |
| 2631 | { |
| 2632 | if (m_cool_render_object_list1[elem2]->zpri > m_cool_render_object_list1[elem2+1]->zpri) |
| 2633 | { |
| 2634 | cool_render_object* temp = m_cool_render_object_list1[elem2]; |
| 2635 | m_cool_render_object_list1[elem2] = m_cool_render_object_list1[elem2+1]; |
| 2636 | m_cool_render_object_list1[elem2+1] = temp; |
| 2637 | } |
| 2638 | } |
| 2639 | } |
| 2711 | 2640 | |
| 2712 | | for (int i=0;i<m_listcount1;i++) |
| 2641 | for (int i=m_listcount1-1;i>=0;i--) |
| 2713 | 2642 | { |
| 2714 | 2643 | if (m_usethreads) |
| 2715 | 2644 | { |
| r21474 | r21475 | |
| 2740 | 2669 | // render the tilemap to the backbuffer, ready for having sprites drawn on it |
| 2741 | 2670 | draw_bg_coolridr(m_temp_bitmap_sprites2, visarea, 1); |
| 2742 | 2671 | // wipe the z-buffer ready for the sprites |
| 2743 | | m_zbuffer_bitmap2.fill(0xffff, visarea); |
| 2672 | /* m_zbuffer_bitmap2.fill(0xffff, visarea); */ |
| 2744 | 2673 | // almost certainly wrong |
| 2745 | 2674 | m_clipvals[1][0] = 0; |
| 2746 | 2675 | m_clipvals[1][1] = 0; |
| 2747 | 2676 | m_clipvals[1][2] = 0; |
| 2748 | 2677 | m_clipblitterMode[1] = 0xff; |
| 2749 | 2678 | |
| 2750 | | //qsort(m_cool_render_object_list2, m_listcount2, sizeof(struct cool_render_object *), comp_sprite_z); |
| 2679 | /* bubble sort, might be something better to use instead */ |
| 2680 | for (int pass = 0 ; pass < ( m_listcount2 - 1 ); pass++) |
| 2681 | { |
| 2682 | for (int elem2 = 0 ; elem2 < m_listcount2 - pass - 1; elem2++) |
| 2683 | { |
| 2684 | if (m_cool_render_object_list2[elem2]->zpri > m_cool_render_object_list2[elem2+1]->zpri) |
| 2685 | { |
| 2686 | cool_render_object* temp = m_cool_render_object_list2[elem2]; |
| 2687 | m_cool_render_object_list2[elem2] = m_cool_render_object_list2[elem2+1]; |
| 2688 | m_cool_render_object_list2[elem2+1] = temp; |
| 2689 | } |
| 2690 | } |
| 2691 | } |
| 2751 | 2692 | |
| 2752 | | for (int i=0;i<m_listcount2;i++) |
| 2693 | for (int i=m_listcount2-1;i>=0;i--) |
| 2753 | 2694 | { |
| 2754 | 2695 | if (m_usethreads) |
| 2755 | 2696 | { |
| r21474 | r21475 | |
| 3633 | 3574 | m_cool_render_object_list2 = auto_alloc_array_clear(machine(), struct cool_render_object*, 1000000); |
| 3634 | 3575 | m_listcount2 = 0; |
| 3635 | 3576 | |
| 3577 | m_work_queue[0] = osd_work_queue_alloc(WORK_QUEUE_FLAG_HIGH_FREQ); |
| 3578 | m_work_queue[1] = osd_work_queue_alloc(WORK_QUEUE_FLAG_HIGH_FREQ); |
| 3579 | decode[0].current_object = 0; |
| 3580 | decode[1].current_object = 0; |
| 3581 | debug_randompal = 9; |
| 3636 | 3582 | |
| 3637 | 3583 | save_pointer(NAME(m_h1_vram), VRAM_SIZE); |
| 3638 | 3584 | save_pointer(NAME(m_h1_pcg), VRAM_SIZE); |
| r21474 | r21475 | |
| 3864 | 3810 | sh2drc_set_options(machine().device("sub"), SH2DRC_FASTEST_OPTIONS); |
| 3865 | 3811 | } |
| 3866 | 3812 | |
| 3867 | | GAME( 1995, coolridr, 0, coolridr, coolridr, coolridr_state, coolridr, ROT0, "Sega", "Cool Riders",GAME_NOT_WORKING|GAME_IMPERFECT_SOUND|GAME_IMPERFECT_GRAPHICS ) // region is set in test mode, this set is for Japan, USA and Export (all regions) |
| 3813 | GAME( 1995, coolridr, 0, coolridr, coolridr, coolridr_state, coolridr, ROT0, "Sega", "Cool Riders",GAME_IMPERFECT_SOUND) // region is set in test mode, this set is for Japan, USA and Export (all regions) |
| 3868 | 3814 | |