trunk/src/mame/drivers/coolridr.c
| r21453 | r21454 | |
| 401 | 401 | { |
| 402 | 402 | m_work_queue[0] = osd_work_queue_alloc(WORK_QUEUE_FLAG_HIGH_FREQ); |
| 403 | 403 | m_work_queue[1] = osd_work_queue_alloc(WORK_QUEUE_FLAG_HIGH_FREQ); |
| 404 | decode[0].current_object = 0; |
| 405 | decode[1].current_object = 0; |
| 406 | |
| 404 | 407 | } |
| 405 | 408 | |
| 406 | 409 | // Blitter state |
| r21453 | r21454 | |
| 515 | 518 | osd_work_queue * m_work_queue[2]; // work queue, one per screen |
| 516 | 519 | static void *draw_object_threaded(void *param, int threadid); |
| 517 | 520 | int m_usethreads; |
| 521 | |
| 522 | #define DECODECACHE_NUMOBJECTCACHES (128) |
| 523 | |
| 524 | #define DECODECACHE_NUMSPRITETILES (16*16) |
| 525 | |
| 526 | // decode cache |
| 527 | struct objectcache |
| 528 | { |
| 529 | // these needs to be all the elements actually going to affect the decode of an individual tile for any given object |
| 530 | UINT32 lastromoffset; |
| 531 | UINT16 lastused_flipx; |
| 532 | UINT16 lastused_flipy; |
| 533 | UINT32 lastblit_rotate; |
| 534 | UINT32 lastb1mode; |
| 535 | UINT32 lastb1colorNumber; |
| 536 | UINT32 lastb2colorNumber; |
| 537 | UINT32 lastb2altpenmask; |
| 538 | UINT16 lastused_hCellCount; |
| 539 | UINT16 lastused_vCellCount; |
| 540 | int repeatcount; |
| 541 | |
| 542 | struct dectile |
| 543 | { |
| 544 | UINT16 tempshape_multi[16*16]; |
| 545 | bool tempshape_multi_decoded; |
| 546 | bool is_blank; |
| 547 | }; |
| 548 | |
| 549 | dectile tiles[DECODECACHE_NUMSPRITETILES]; |
| 550 | |
| 551 | }; |
| 552 | |
| 553 | |
| 554 | struct objcachemanager |
| 555 | { |
| 556 | int current_object; |
| 557 | objectcache objcache[DECODECACHE_NUMOBJECTCACHES]; |
| 558 | |
| 559 | // fallback decode buffer for certain cases (indirect sprites, sprites too big for our buffer..) |
| 560 | UINT16 tempshape[16*16]; |
| 561 | }; |
| 562 | |
| 563 | objcachemanager decode[2]; |
| 564 | |
| 565 | |
| 566 | |
| 567 | |
| 518 | 568 | }; |
| 519 | 569 | |
| 520 | 570 | #define PRINT_BLIT_STUFF \ |
| r21453 | r21454 | |
| 681 | 731 | UINT8 blittype; |
| 682 | 732 | coolridr_state* state; |
| 683 | 733 | UINT32 clipvals[3]; |
| 734 | int screen; |
| 684 | 735 | }; |
| 685 | 736 | |
| 686 | 737 | #define RLE_BLOCK(writeaddrxor) \ |
| 687 | 738 | /* skip the decoding if it's the same tile as last time! */ \ |
| 688 | | if (spriteNumber != lastSpriteNumber) \ |
| 739 | if (!current_decoded) \ |
| 689 | 740 | { \ |
| 690 | | blankcount = 256;\ |
| 691 | | lastSpriteNumber = spriteNumber; \ |
| 692 | | \ |
| 693 | | int i = 1;/* skip first 10 bits for now */ \ |
| 694 | | int data_written = 0; \ |
| 695 | | \ |
| 696 | | while (data_written<256) \ |
| 741 | lastSpriteNumber = 0xffffffff; /* this optimization is currently broken, so hack it to be disabled here */ \ |
| 742 | if (spriteNumber != lastSpriteNumber) \ |
| 697 | 743 | { \ |
| 698 | | \ |
| 699 | | const UINT16 compdata = expanded_10bit_gfx[ (b3romoffset) + spriteNumber + i]; \ |
| 700 | | \ |
| 701 | | if (((compdata & 0x300) == 0x000) || ((compdata & 0x300) == 0x100)) /* 3bpp */ \ |
| 744 | blankcount = 256;\ |
| 745 | lastSpriteNumber = spriteNumber; \ |
| 746 | \ |
| 747 | int i = 1;/* skip first 10 bits for now */ \ |
| 748 | int data_written = 0; \ |
| 749 | \ |
| 750 | while (data_written<256) \ |
| 702 | 751 | { \ |
| 703 | | /* mm ccrr rrr0 */ \ |
| 704 | | int encodelength = (compdata & 0x03e)>>1; \ |
| 705 | | const UINT16 rledata = rearranged_16bit_gfx[color_offs + ((compdata & 0x1c0) >> 6)]; \ |
| 706 | | /* guess, blank tiles have the following form */ \ |
| 707 | | /* 00120 (00000024,0) | 010 03f */ \ |
| 708 | | if (compdata&1) encodelength = 255; \ |
| 709 | | \ |
| 710 | | while (data_written<256 && encodelength >=0) \ |
| 752 | \ |
| 753 | const UINT16 compdata = expanded_10bit_gfx[ (b3romoffset) + spriteNumber + i]; \ |
| 754 | \ |
| 755 | if (((compdata & 0x300) == 0x000) || ((compdata & 0x300) == 0x100)) /* 3bpp */ \ |
| 711 | 756 | { \ |
| 712 | | tempshape[data_written^writeaddrxor] = rledata; \ |
| 713 | | if (tempshape[data_written^writeaddrxor]==0x8000) blankcount--; \ |
| 714 | | encodelength--; \ |
| 715 | | data_written++; \ |
| 757 | /* mm ccrr rrr0 */ \ |
| 758 | int encodelength = (compdata & 0x03e)>>1; \ |
| 759 | const UINT16 rledata = rearranged_16bit_gfx[color_offs + ((compdata & 0x1c0) >> 6)]; \ |
| 760 | /* guess, blank tiles have the following form */ \ |
| 761 | /* 00120 (00000024,0) | 010 03f */ \ |
| 762 | if (compdata&1) encodelength = 255; \ |
| 763 | \ |
| 764 | while (data_written<256 && encodelength >=0) \ |
| 765 | { \ |
| 766 | tempshape[data_written^writeaddrxor] = rledata; \ |
| 767 | if (tempshape[data_written^writeaddrxor]==0x8000) blankcount--; \ |
| 768 | encodelength--; \ |
| 769 | data_written++; \ |
| 770 | } \ |
| 716 | 771 | } \ |
| 717 | | } \ |
| 718 | | else if ((compdata & 0x300) == 0x200) /* 6bpp */ \ |
| 719 | | { \ |
| 720 | | /* mm cccc ccrr */ \ |
| 721 | | int encodelength = (compdata & 0x003); \ |
| 722 | | const UINT16 rledata = rearranged_16bit_gfx[color_offs + ((compdata & 0x0fc) >> 2) + 8]; \ |
| 723 | | while (data_written<256 && encodelength >=0) \ |
| 772 | else if ((compdata & 0x300) == 0x200) /* 6bpp */ \ |
| 724 | 773 | { \ |
| 725 | | tempshape[data_written^writeaddrxor] = rledata; /* + 0x8 crt test, most of red, green, start of blue */ \ |
| 774 | /* mm cccc ccrr */ \ |
| 775 | int encodelength = (compdata & 0x003); \ |
| 776 | const UINT16 rledata = rearranged_16bit_gfx[color_offs + ((compdata & 0x0fc) >> 2) + 8]; \ |
| 777 | while (data_written<256 && encodelength >=0) \ |
| 778 | { \ |
| 779 | tempshape[data_written^writeaddrxor] = rledata; /* + 0x8 crt test, most of red, green, start of blue */ \ |
| 780 | if (tempshape[data_written^writeaddrxor]==0x8000) blankcount--; \ |
| 781 | encodelength--; \ |
| 782 | data_written++; \ |
| 783 | } \ |
| 784 | } \ |
| 785 | else /* 8bpp */ \ |
| 786 | { \ |
| 787 | /* mm cccc cccc */ \ |
| 788 | UINT16 rawdat = (compdata & 0x0ff); \ |
| 789 | if (b1mode && (rawdat > (b2altpenmask + 0x48))) /* does this have to be turned on by b1mode? road ends up with some bad pixels otherwise but maybe the calc is wrong... does it affect the other colour depths too? */ \ |
| 790 | tempshape[data_written^writeaddrxor] = rearranged_16bit_gfx[color_offs2 + (rawdat )+0x48]; /* bike wheels + brake light */ \ |
| 791 | else \ |
| 792 | tempshape[data_written^writeaddrxor] = rearranged_16bit_gfx[color_offs + (rawdat )+0x48]; /* +0x48 crt test end of blue, start of white */ \ |
| 726 | 793 | if (tempshape[data_written^writeaddrxor]==0x8000) blankcount--; \ |
| 727 | | encodelength--; \ |
| 728 | 794 | data_written++; \ |
| 729 | 795 | } \ |
| 796 | \ |
| 797 | i++; \ |
| 730 | 798 | } \ |
| 731 | | else /* 8bpp */ \ |
| 799 | if (!indirect_tile_enable && size < DECODECACHE_NUMSPRITETILES) \ |
| 732 | 800 | { \ |
| 733 | | /* mm cccc cccc */ \ |
| 734 | | UINT16 rawdat = (compdata & 0x0ff); \ |
| 735 | | if (b1mode && (rawdat > (b2altpenmask + 0x48))) /* does this have to be turned on by b1mode? road ends up with some bad pixels otherwise but maybe the calc is wrong... does it affect the other colour depths too? */ \ |
| 736 | | tempshape[data_written^writeaddrxor] = rearranged_16bit_gfx[color_offs2 + (rawdat )+0x48]; /* bike wheels + brake light */ \ |
| 801 | object->state->decode[screen].objcache[use_object].tiles[v*used_hCellCount + h].tempshape_multi_decoded = true; \ |
| 802 | if (blankcount==0) \ |
| 803 | object->state->decode[screen].objcache[use_object].tiles[v*used_hCellCount + h].is_blank = true; \ |
| 737 | 804 | else \ |
| 738 | | tempshape[data_written^writeaddrxor] = rearranged_16bit_gfx[color_offs + (rawdat )+0x48]; /* +0x48 crt test end of blue, start of white */ \ |
| 739 | | if (tempshape[data_written^writeaddrxor]==0x8000) blankcount--; \ |
| 740 | | data_written++; \ |
| 805 | object->state->decode[screen].objcache[use_object].tiles[v*used_hCellCount + h].is_blank = false; \ |
| 806 | /* if (object->screen==0) printf("marking offset %04x as decoded (sprite number %08x ptr %08x)\n", v*used_hCellCount + h, spriteNumber, ((UINT64)(void*)tempshape)&0xffffffff);*/ \ |
| 741 | 807 | } \ |
| 742 | | \ |
| 743 | | i++; \ |
| 744 | 808 | } \ |
| 745 | 809 | } \ |
| 746 | 810 | |
| 747 | 811 | |
| 812 | |
| 748 | 813 | #define CHECK_DECODE \ |
| 749 | 814 | if (used_flipy) \ |
| 750 | 815 | { \ |
| r21453 | r21454 | |
| 767 | 832 | RLE_BLOCK(0x00) \ |
| 768 | 833 | } \ |
| 769 | 834 | } \ |
| 770 | | if (blankcount==0) \ |
| 771 | | continue; \ |
| 835 | if (!indirect_tile_enable && size < DECODECACHE_NUMSPRITETILES) \ |
| 836 | { \ |
| 837 | if (object->state->decode[screen].objcache[use_object].tiles[v*used_hCellCount + h].is_blank == true) \ |
| 838 | continue; \ |
| 839 | } \ |
| 840 | else \ |
| 841 | if (blankcount==0) continue; \ |
| 772 | 842 | |
| 843 | |
| 844 | |
| 773 | 845 | #define GET_SPRITE_NUMBER \ |
| 774 | 846 | int lookupnum; \ |
| 775 | 847 | /* with this bit enabled the tile numbers gets looked up using 'data' (which would be blit11) (eg 03f40000 for startup text) */ \ |
| r21453 | r21454 | |
| 819 | 891 | UINT32 spriteNumber = (expanded_10bit_gfx[ (b3romoffset) + (lookupnum<<1) +0 ] << 10) | (expanded_10bit_gfx[ (b3romoffset) + (lookupnum<<1) + 1 ]); \ |
| 820 | 892 | |
| 821 | 893 | |
| 822 | | #define YXLOOP_START_1 \ |
| 823 | | for (int y = 0; y < blockhigh; y++) \ |
| 894 | #define DO_XCLIP_REAL \ |
| 895 | if (drawx>clipmaxX) { break; } \ |
| 896 | if (drawx<clipminX) { drawx++; continue; } \ |
| 897 | |
| 898 | #define DO_XCLIP_NONE \ |
| 899 | |
| 900 | |
| 901 | #define GET_CURRENT_LINESCROLLZOOM \ |
| 902 | UINT32 dword = object->indirect_zoom[v*16+realy]; \ |
| 903 | UINT16 hZoomTable = hZoom + (dword>>16); \ |
| 904 | /* bit 0x8000 does get set too, but only on some lines, might have another meaning? */ \ |
| 905 | int linescroll = dword&0x7fff; \ |
| 906 | if (linescroll & 0x4000) linescroll -= 0x8000; \ |
| 907 | int hPositionTable = linescroll + hPositionx; \ |
| 908 | /* DON'T use the table hZoom in this calc? (road..) */ \ |
| 909 | int sizex = used_hCellCount * 16 * hZoom; \ |
| 910 | hPositionTable *= 0x40; \ |
| 911 | switch (hOrigin & 3) \ |
| 824 | 912 | { \ |
| 825 | | int realy = ((y*incy)>>21); \ |
| 826 | | if (!hZoomTable[realy]) \ |
| 827 | | continue; \ |
| 828 | | const int pixelOffsetX = ((hPositionTable[realy]) + (h* 16 * hZoomTable[realy])) / 0x40; \ |
| 829 | | const int pixelOffsetnextX = ((hPositionTable[realy]) + ((h+1)* 16 * hZoomTable[realy])) / 0x40; \ |
| 830 | | const int drawy = pixelOffsetY+y; \ |
| 831 | | if ((drawy>clipmaxY) || (drawy<clipminY)) continue; \ |
| 832 | | line = &drawbitmap->pix32(drawy); \ |
| 833 | | zline = &object->zbitmap->pix16(drawy); \ |
| 834 | | int blockwide = pixelOffsetnextX-pixelOffsetX; \ |
| 835 | | if (pixelOffsetX+blockwide <clipminX) \ |
| 836 | | continue; \ |
| 837 | | if (pixelOffsetX>clipmaxX) \ |
| 838 | | continue; \ |
| 839 | | \ |
| 840 | | if (pixelOffsetX>=clipminX && pixelOffsetX+blockwide<clipmaxX) \ |
| 841 | | { \ |
| 842 | | UINT32 incx = 0x8000000 / hZoomTable[realy]; \ |
| 843 | | for (int x = 0; x < blockwide; x++) \ |
| 844 | | { \ |
| 845 | | const int drawx = pixelOffsetX+x; \ |
| 846 | | int realx = ((x*incx)>>21); \ |
| 847 | | const UINT16 &pix = tempshape[realx*16+realy]; \ |
| 848 | | DRAW_PIX \ |
| 849 | | } \ |
| 850 | | } \ |
| 851 | | else \ |
| 852 | | { \ |
| 853 | | UINT32 incx = 0x8000000 / hZoomTable[realy]; \ |
| 854 | | for (int x = 0; x < blockwide; x++) \ |
| 855 | | { \ |
| 856 | | const int drawx = pixelOffsetX+x; \ |
| 857 | | if ((drawx>clipmaxX || drawx<clipminX)) continue; \ |
| 858 | | int realx = ((x*incx)>>21); \ |
| 859 | | const UINT16 &pix = tempshape[realx*16+realy]; \ |
| 860 | | DRAW_PIX \ |
| 861 | | } \ |
| 862 | | } \ |
| 913 | case 0: \ |
| 914 | /* left */ \ |
| 915 | break; \ |
| 916 | case 1: \ |
| 917 | hPositionTable -= sizex / 2; \ |
| 918 | /* middle? */ \ |
| 919 | break; \ |
| 920 | case 2: \ |
| 921 | hPositionTable -= sizex-1; \ |
| 922 | /* right? */ \ |
| 923 | break; \ |
| 924 | case 3: \ |
| 925 | /* invalid? */ \ |
| 926 | break; \ |
| 863 | 927 | } \ |
| 864 | 928 | |
| 865 | 929 | |
| 866 | | #define YXLOOP_START_2 \ |
| 930 | |
| 931 | |
| 932 | #define YXLOOP \ |
| 933 | int drawy = pixelOffsetY; \ |
| 867 | 934 | for (int y = 0; y < blockhigh; y++) \ |
| 868 | 935 | { \ |
| 869 | 936 | int realy = ((y*incy)>>21); \ |
| 870 | | if (!hZoomTable[realy]) \ |
| 871 | | continue; \ |
| 872 | | const int pixelOffsetX = ((hPositionTable[realy]) + (h* 16 * hZoomTable[realy])) / 0x40; \ |
| 873 | | const int pixelOffsetnextX = ((hPositionTable[realy]) + ((h+1)* 16 * hZoomTable[realy])) / 0x40; \ |
| 874 | | const int drawy = pixelOffsetY+y; \ |
| 875 | | if ((drawy>clipmaxY) || (drawy<clipminY)) continue; \ |
| 937 | GET_CURRENT_LINESCROLLZOOM \ |
| 938 | UINT16 hZoomHere = hZoomTable; \ |
| 939 | if (!hZoomHere) { drawy++; continue; } \ |
| 940 | const int pixelOffsetX = ((hPositionTable) + (h* 16 * hZoomHere)) / 0x40; \ |
| 941 | const int pixelOffsetnextX = ((hPositionTable) + ((h+1)* 16 * hZoomHere)) / 0x40; \ |
| 942 | if (drawy>clipmaxY) { break; }; \ |
| 943 | if (drawy<clipminY) { drawy++; continue; }; \ |
| 876 | 944 | line = &drawbitmap->pix32(drawy); \ |
| 877 | 945 | zline = &object->zbitmap->pix16(drawy); \ |
| 878 | 946 | int blockwide = pixelOffsetnextX-pixelOffsetX; \ |
| 879 | | if (pixelOffsetX+blockwide <clipminX) \ |
| 880 | | continue; \ |
| 881 | | if (pixelOffsetX>clipmaxX) \ |
| 882 | | continue; \ |
| 947 | if (pixelOffsetX+blockwide <clipminX) { drawy++; continue; } \ |
| 948 | if (pixelOffsetX>clipmaxX) { drawy++; continue; } \ |
| 883 | 949 | if (pixelOffsetX>=clipminX && pixelOffsetX+blockwide<clipmaxX) \ |
| 884 | 950 | { \ |
| 885 | | UINT32 incx = 0x8000000 / hZoomTable[realy]; \ |
| 951 | UINT32 incx = 0x8000000 / hZoomHere; \ |
| 952 | int drawx = pixelOffsetX; \ |
| 886 | 953 | for (int x = 0; x < blockwide; x++) \ |
| 887 | 954 | { \ |
| 888 | | const int drawx = pixelOffsetX+x; \ |
| 955 | DO_XCLIP_NONE \ |
| 889 | 956 | int realx = ((x*incx)>>21); \ |
| 890 | | const UINT16 &pix = tempshape[realy*16+realx]; \ |
| 891 | | DRAW_PIX \ |
| 957 | GET_PIX; \ |
| 958 | DRAW_PIX; \ |
| 892 | 959 | } \ |
| 893 | 960 | } \ |
| 894 | 961 | else \ |
| 895 | 962 | { \ |
| 896 | | UINT32 incx = 0x8000000 / hZoomTable[realy]; \ |
| 963 | UINT32 incx = 0x8000000 / hZoomHere; \ |
| 964 | int drawx = pixelOffsetX; \ |
| 897 | 965 | for (int x = 0; x < blockwide; x++) \ |
| 898 | 966 | { \ |
| 899 | | const int drawx = pixelOffsetX+x; \ |
| 967 | DO_XCLIP_REAL \ |
| 900 | 968 | int realx = ((x*incx)>>21); \ |
| 901 | | if ((drawx>clipmaxX || drawx<clipminX)) continue; \ |
| 902 | | const UINT16 &pix = tempshape[realy*16+realx]; \ |
| 903 | | DRAW_PIX \ |
| 969 | GET_PIX; \ |
| 970 | DRAW_PIX; \ |
| 904 | 971 | } \ |
| 905 | 972 | } \ |
| 973 | drawy++; \ |
| 906 | 974 | } \ |
| 907 | 975 | |
| 908 | 976 | |
| 909 | | |
| 910 | | |
| 911 | | #define YXLOOP_END \ |
| 912 | | } \ |
| 913 | | } \ |
| 914 | | |
| 915 | | |
| 916 | | #define YXLOOP_START_NO_LINEZOOM \ |
| 977 | #define YXLOOP_NO_LINEZOOM \ |
| 917 | 978 | for (int y = 0; y < blockhigh; y++) \ |
| 918 | 979 | { \ |
| 919 | 980 | int realy = ((y*incy)>>21); \ |
| r21453 | r21454 | |
| 921 | 982 | if ((drawy>clipmaxY) || (drawy<clipminY)) continue; \ |
| 922 | 983 | line = &drawbitmap->pix32(drawy); \ |
| 923 | 984 | zline = &object->zbitmap->pix16(drawy); \ |
| 985 | int drawx = pixelOffsetX; \ |
| 924 | 986 | for (int x = 0; x < blockwide; x++) \ |
| 925 | 987 | { \ |
| 926 | | const int drawx = pixelOffsetX+x; \ |
| 927 | | if ((drawx>clipmaxX || drawx<clipminX)) continue; \ |
| 988 | DO_XCLIP \ |
| 928 | 989 | int realx = ((x*incx)>>21); \ |
| 990 | GET_PIX; \ |
| 991 | DRAW_PIX \ |
| 992 | } \ |
| 993 | } \ |
| 929 | 994 | |
| 930 | | #define YXLOOP_START_NO_LINEZOOM_NO_XCLIP \ |
| 931 | | for (int y = 0; y < blockhigh; y++) \ |
| 932 | | { \ |
| 933 | | int realy = ((y*incy)>>21); \ |
| 934 | | const int drawy = pixelOffsetY+y; \ |
| 935 | | if ((drawy>clipmaxY) || (drawy<clipminY)) continue; \ |
| 936 | | line = &drawbitmap->pix32(drawy); \ |
| 937 | | zline = &object->zbitmap->pix16(drawy); \ |
| 938 | | for (int x = 0; x < blockwide; x++) \ |
| 939 | | { \ |
| 940 | | const int drawx = pixelOffsetX+x; \ |
| 941 | | int realx = ((x*incx)>>21); \ |
| 942 | 995 | |
| 943 | 996 | |
| 944 | | #define YXLOOP_START_NO_ZOOM \ |
| 945 | | for (int y = 0; y < 16; y++) \ |
| 997 | #define YXLOOP_NO_ZOOM \ |
| 998 | for (int realy = 0; realy < 16; realy++) \ |
| 946 | 999 | { \ |
| 947 | | const int drawy = pixelOffsetY+y; \ |
| 1000 | const int drawy = pixelOffsetY+realy; \ |
| 948 | 1001 | if ((drawy>clipmaxY) || (drawy<clipminY)) continue; \ |
| 949 | 1002 | line = &drawbitmap->pix32(drawy); \ |
| 950 | 1003 | zline = &object->zbitmap->pix16(drawy); \ |
| 951 | | for (int x = 0; x < 16; x++) \ |
| 1004 | int drawx = pixelOffsetX; \ |
| 1005 | for (int realx = 0; realx < 16; realx++) \ |
| 952 | 1006 | { \ |
| 953 | | const int drawx = pixelOffsetX+x; \ |
| 954 | | if ((drawx>clipmaxX || drawx<clipminX)) continue; \ |
| 1007 | DO_XCLIP \ |
| 1008 | GET_PIX; \ |
| 1009 | DRAW_PIX \ |
| 1010 | } \ |
| 1011 | } \ |
| 955 | 1012 | |
| 956 | | #define YXLOOP_START_NO_ZOOM_NO_XCLIP \ |
| 957 | | for (int y = 0; y < 16; y++) \ |
| 958 | | { \ |
| 959 | | const int drawy = pixelOffsetY+y; \ |
| 960 | | if ((drawy>clipmaxY) || (drawy<clipminY)) continue; \ |
| 961 | | line = &drawbitmap->pix32(drawy); \ |
| 962 | | zline = &object->zbitmap->pix16(drawy); \ |
| 963 | | for (int x = 0; x < 16; x++) \ |
| 964 | | { \ |
| 965 | | const int drawx = pixelOffsetX+x; \ |
| 966 | 1013 | |
| 967 | 1014 | |
| 968 | | |
| 969 | 1015 | /* the two tables that the patent claims are located at: |
| 970 | 1016 | 0x1ec800 |
| 971 | 1017 | 0x1f0000 |
| r21453 | r21454 | |
| 994 | 1040 | /* how do we tell the difference between them? */ \ |
| 995 | 1041 | /* how would you have a black 0x0000 in an alpha sprite?? */ \ |
| 996 | 1042 | } \ |
| 1043 | drawx++; \ |
| 997 | 1044 | |
| 998 | 1045 | |
| 1046 | |
| 999 | 1047 | //object->rearranged_16bit_gfx |
| 1000 | 1048 | //object->expanded_10bit_gfx |
| 1001 | 1049 | |
| 1050 | #define GET_PIX_ROTATED \ |
| 1051 | UINT16 pix = tempshape[realx*16+realy]; \ |
| 1002 | 1052 | |
| 1053 | #define GET_PIX_NORMAL \ |
| 1054 | UINT16 pix = tempshape[realy*16+realx]; \ |
| 1003 | 1055 | |
| 1004 | 1056 | |
| 1005 | | |
| 1006 | 1057 | void *coolridr_state::draw_object_threaded(void *param, int threadid) |
| 1007 | 1058 | { |
| 1008 | 1059 | cool_render_object *object = reinterpret_cast<cool_render_object *>(param); |
| 1009 | 1060 | bitmap_rgb32* drawbitmap = object->drawbitmap; |
| 1010 | 1061 | |
| 1062 | /************* object->spriteblit[3] *************/ |
| 1063 | |
| 1064 | UINT32 blit3_unused = object->spriteblit[3] & 0xffe00000; |
| 1065 | UINT32 b3romoffset = (object->spriteblit[3] & 0x001fffff)*16; |
| 1066 | |
| 1067 | if (blit3_unused) printf("unknown bits in blit word %d - %08x\n", 3, blit3_unused); |
| 1068 | |
| 1069 | /************* object->spriteblit[5] *************/ |
| 1070 | |
| 1071 | UINT32 blit5_unused = object->spriteblit[5]&0xfffefffe; |
| 1072 | // this might enable the text indirection thing? |
| 1073 | int indirect_tile_enable = (object->spriteblit[5] & 0x00010000)>>16; |
| 1074 | int indirect_zoom_enable = (object->spriteblit[5] & 0x00000001); |
| 1075 | |
| 1076 | |
| 1077 | if (blit5_unused) printf("unknown bits in blit word %d - %08x\n", 5, blit5_unused); |
| 1078 | // 00010000 (text) |
| 1079 | // 00000001 (other) |
| 1080 | |
| 1081 | |
| 1082 | |
| 1083 | |
| 1011 | 1084 | UINT16* rearranged_16bit_gfx = object->state->m_rearranged_16bit_gfx; |
| 1012 | 1085 | UINT16* expanded_10bit_gfx = object->state->m_expanded_10bit_gfx; |
| 1013 | 1086 | |
| r21453 | r21454 | |
| 1065 | 1138 | // ?? seems to be 00 or 7f, set depending on b1mode |
| 1066 | 1139 | // uuu, at least 11 bits used, maybe 12 usually the same as blit1_unused? leftover? |
| 1067 | 1140 | |
| 1068 | | /************* object->spriteblit[3] *************/ |
| 1069 | 1141 | |
| 1070 | | UINT32 blit3_unused = object->spriteblit[3] & 0xffe00000; |
| 1071 | | UINT32 b3romoffset = (object->spriteblit[3] & 0x001fffff)*16; |
| 1072 | 1142 | |
| 1073 | | if (blit3_unused) printf("unknown bits in blit word %d - %08x\n", 3, blit3_unused); |
| 1074 | | |
| 1075 | | |
| 1076 | 1143 | /************* object->spriteblit[4] *************/ |
| 1077 | 1144 | |
| 1078 | 1145 | UINT32 blit4_unused = object->spriteblit[4] & 0xf8fefefe; |
| r21453 | r21454 | |
| 1090 | 1157 | // y = y-flip |
| 1091 | 1158 | // r = unknown, not used much, occasional object - rotate |
| 1092 | 1159 | |
| 1093 | | /************* object->spriteblit[5] *************/ |
| 1094 | 1160 | |
| 1095 | | UINT32 blit5_unused = object->spriteblit[5]&0xfffefffe; |
| 1096 | | // this might enable the text indirection thing? |
| 1097 | | int indirect_tile_enable = (object->spriteblit[5] & 0x00010000)>>16; |
| 1098 | | int indirect_zoom_enable = (object->spriteblit[5] & 0x00000001); |
| 1099 | 1161 | |
| 1100 | 1162 | |
| 1101 | | if (blit5_unused) printf("unknown bits in blit word %d - %08x\n", 5, blit5_unused); |
| 1102 | | // 00010000 (text) |
| 1103 | | // 00000001 (other) |
| 1104 | | |
| 1105 | | |
| 1106 | | |
| 1107 | | |
| 1108 | 1163 | /************* object->spriteblit[6] *************/ |
| 1109 | 1164 | |
| 1110 | 1165 | UINT16 vCellCount = (object->spriteblit[6] & 0x03ff0000) >> 16; |
| r21453 | r21454 | |
| 1152 | 1207 | /************* object->spriteblit[10] *************/ |
| 1153 | 1208 | |
| 1154 | 1209 | // pointer to per-line zoom and scroll data for sprites |
| 1155 | | UINT32 blit10 = 0; // we've cached the data here already |
| 1210 | //UINT32 blit10 = 0; // we've cached the data here already |
| 1156 | 1211 | |
| 1157 | 1212 | /************* object->spriteblit[11] *************/ |
| 1158 | 1213 | |
| r21453 | r21454 | |
| 1497 | 1552 | |
| 1498 | 1553 | |
| 1499 | 1554 | |
| 1555 | int size = used_hCellCount * used_vCellCount; |
| 1500 | 1556 | |
| 1557 | UINT16* tempshape; |
| 1558 | int screen = object->screen; |
| 1559 | int use_object = 0; |
| 1501 | 1560 | |
| 1561 | if (!indirect_tile_enable && size < DECODECACHE_NUMSPRITETILES) |
| 1562 | { |
| 1563 | int found = -1; |
| 1502 | 1564 | |
| 1565 | for (int k=0;k<DECODECACHE_NUMOBJECTCACHES;k++) |
| 1566 | { |
| 1567 | if(((object->state->decode[screen].objcache[k].lastromoffset == b3romoffset)) && |
| 1568 | ((object->state->decode[screen].objcache[k].lastused_flipx == used_flipx)) && |
| 1569 | ((object->state->decode[screen].objcache[k].lastused_flipy == used_flipy)) && |
| 1570 | ((object->state->decode[screen].objcache[k].lastblit_rotate == blit_rotate)) && |
| 1571 | ((object->state->decode[screen].objcache[k].lastb1mode == b1mode)) && |
| 1572 | ((object->state->decode[screen].objcache[k].lastb1colorNumber == b1colorNumber)) && |
| 1573 | ((object->state->decode[screen].objcache[k].lastb2colorNumber == b2colorNumber)) && |
| 1574 | ((object->state->decode[screen].objcache[k].lastused_hCellCount == used_hCellCount)) && |
| 1575 | ((object->state->decode[screen].objcache[k].lastused_vCellCount == used_vCellCount)) && |
| 1576 | ((object->state->decode[screen].objcache[k].lastb2altpenmask == b2altpenmask))) |
| 1577 | { |
| 1578 | found = k; |
| 1579 | break; |
| 1580 | } |
| 1581 | } |
| 1503 | 1582 | |
| 1583 | if (found != -1) |
| 1584 | { |
| 1585 | object->state->decode[screen].objcache[found].repeatcount++; |
| 1586 | use_object = found; |
| 1587 | } |
| 1588 | else |
| 1589 | { |
| 1590 | use_object = object->state->decode[screen].current_object; |
| 1504 | 1591 | |
| 1592 | // dirty the cache |
| 1593 | for (int i=0;i<DECODECACHE_NUMSPRITETILES;i++) |
| 1594 | object->state->decode[screen].objcache[use_object].tiles[i].tempshape_multi_decoded = false; |
| 1595 | |
| 1596 | object->state->decode[screen].objcache[use_object].lastromoffset = b3romoffset; |
| 1597 | object->state->decode[screen].objcache[use_object].lastused_flipx = used_flipx; |
| 1598 | object->state->decode[screen].objcache[use_object].lastused_flipy = used_flipy; |
| 1599 | object->state->decode[screen].objcache[use_object].lastblit_rotate = blit_rotate; |
| 1600 | object->state->decode[screen].objcache[use_object].lastb1mode = b1mode; |
| 1601 | object->state->decode[screen].objcache[use_object].lastb1colorNumber = b1colorNumber; |
| 1602 | object->state->decode[screen].objcache[use_object].lastb2colorNumber = b2colorNumber; |
| 1603 | object->state->decode[screen].objcache[use_object].lastused_hCellCount = used_hCellCount; |
| 1604 | object->state->decode[screen].objcache[use_object].lastused_vCellCount = used_vCellCount; |
| 1605 | object->state->decode[screen].objcache[use_object].lastb2altpenmask = b2altpenmask; |
| 1606 | object->state->decode[screen].objcache[use_object].repeatcount = 0; |
| 1607 | |
| 1608 | object->state->decode[screen].current_object++; |
| 1609 | if (object->state->decode[screen].current_object >= DECODECACHE_NUMOBJECTCACHES) |
| 1610 | object->state->decode[screen].current_object = 0; |
| 1611 | } |
| 1612 | } |
| 1613 | |
| 1614 | |
| 1615 | |
| 1616 | |
| 1505 | 1617 | int sizey = used_vCellCount * 16 * vZoom; |
| 1506 | 1618 | |
| 1507 | 1619 | vPosition *= 0x40; |
| r21453 | r21454 | |
| 1552 | 1664 | //if (used_flipx) |
| 1553 | 1665 | // hPositionx -= 1; |
| 1554 | 1666 | |
| 1555 | | UINT16 hZoomTable[16]; |
| 1556 | | int hPositionTable[16]; |
| 1557 | 1667 | int hPosition = 0; |
| 1558 | 1668 | |
| 1559 | | if (indirect_zoom_enable) |
| 1560 | | { |
| 1561 | | for (int idx=0;idx<16;idx++) |
| 1562 | | { |
| 1563 | | UINT32 dword = object->indirect_zoom[blit10]; |
| 1564 | 1669 | |
| 1565 | | hZoomTable[idx] = hZoom + (dword>>16); // add original value? |
| 1566 | | |
| 1567 | | // bit 0x8000 does get set too, but only on some lines, might have another meaning? |
| 1568 | | int linescroll = dword&0x7fff; |
| 1569 | | if (linescroll & 0x4000) linescroll -= 0x8000; |
| 1570 | | |
| 1571 | | hPositionTable[idx] = linescroll + hPositionx; |
| 1572 | | blit10++; |
| 1573 | | |
| 1574 | | // DON'T use the table hZoom in this calc? (road..) |
| 1575 | | int sizex = used_hCellCount * 16 * hZoom; |
| 1576 | | |
| 1577 | | hPositionTable[idx] *= 0x40; |
| 1578 | | |
| 1579 | | switch (hOrigin & 3) |
| 1580 | | { |
| 1581 | | case 0: |
| 1582 | | // left |
| 1583 | | break; |
| 1584 | | case 1: |
| 1585 | | hPositionTable[idx] -= sizex / 2; |
| 1586 | | // middle? |
| 1587 | | break; |
| 1588 | | case 2: |
| 1589 | | hPositionTable[idx] -= sizex-1; |
| 1590 | | // right? |
| 1591 | | break; |
| 1592 | | case 3: |
| 1593 | | // invalid? |
| 1594 | | break; |
| 1595 | | } |
| 1596 | | } |
| 1597 | | } |
| 1598 | | else |
| 1670 | |
| 1671 | if (!indirect_zoom_enable) |
| 1599 | 1672 | { |
| 1600 | 1673 | |
| 1601 | 1674 | int sizex = used_hCellCount * 16 * hZoom; |
| r21453 | r21454 | |
| 1622 | 1695 | } |
| 1623 | 1696 | |
| 1624 | 1697 | UINT32 lastSpriteNumber = 0xffffffff; |
| 1625 | | UINT16 tempshape[16*16]; |
| 1626 | 1698 | UINT16 blankcount = 0; |
| 1627 | 1699 | int color_offs = (0x7b20 + (b1colorNumber & 0x7ff))*0x40 * 5; /* yes, * 5 */ \ |
| 1628 | 1700 | int color_offs2 = (0x7b20 + (b2colorNumber & 0x7ff))*0x40 * 5; \ |
| r21453 | r21454 | |
| 1630 | 1702 | for (int h = 0; h < used_hCellCount; h++) |
| 1631 | 1703 | { |
| 1632 | 1704 | |
| 1705 | int current_decoded = false; |
| 1706 | |
| 1707 | if (!indirect_tile_enable && size < DECODECACHE_NUMSPRITETILES) |
| 1708 | { |
| 1709 | tempshape = object->state->decode[screen].objcache[use_object].tiles[v*used_hCellCount + h].tempshape_multi; |
| 1710 | current_decoded = object->state->decode[screen].objcache[use_object].tiles[v*used_hCellCount + h].tempshape_multi_decoded; |
| 1711 | /* |
| 1712 | if (object->screen==0) |
| 1713 | { |
| 1714 | if (current_decoded) printf("setting temp shape to %04x tile is marked as decoded %08x \n", v*used_hCellCount + h, ((UINT64)(void*)tempshape)&0xffffffff); |
| 1715 | else printf("setting temp shape to %04x tile is marked as NOT decoded %08x \n", v*used_hCellCount + h, ((UINT64)(void*)tempshape)&0xffffffff); |
| 1716 | } |
| 1717 | */ |
| 1718 | } |
| 1719 | else |
| 1720 | { |
| 1721 | //if (object->screen==0) printf("using base tempshape\n"); |
| 1722 | tempshape = object->state->decode[screen].tempshape; |
| 1723 | } |
| 1633 | 1724 | |
| 1634 | 1725 | |
| 1635 | 1726 | |
| 1636 | 1727 | |
| 1637 | | |
| 1638 | 1728 | UINT32 incy = 0x8000000 / vZoom; |
| 1639 | 1729 | |
| 1640 | 1730 | // DEBUG: Draw 16x16 block |
| r21453 | r21454 | |
| 1650 | 1740 | |
| 1651 | 1741 | if (blit_rotate) |
| 1652 | 1742 | { |
| 1653 | | YXLOOP_START_1 |
| 1654 | | |
| 1743 | #define GET_PIX GET_PIX_ROTATED |
| 1744 | YXLOOP |
| 1745 | #undef GET_PIX |
| 1655 | 1746 | } |
| 1656 | 1747 | else // no rotate |
| 1657 | 1748 | { |
| 1658 | | YXLOOP_START_2 |
| 1749 | #define GET_PIX GET_PIX_NORMAL |
| 1750 | YXLOOP |
| 1751 | #undef GET_PIX |
| 1659 | 1752 | |
| 1660 | 1753 | } |
| 1661 | 1754 | } |
| r21453 | r21454 | |
| 1684 | 1777 | { |
| 1685 | 1778 | if (blit_rotate) |
| 1686 | 1779 | { |
| 1687 | | YXLOOP_START_NO_ZOOM_NO_XCLIP |
| 1688 | | const UINT16 &pix = tempshape[x*16+y]; |
| 1689 | | DRAW_PIX |
| 1690 | | YXLOOP_END |
| 1780 | #define DO_XCLIP DO_XCLIP_NONE |
| 1781 | #define GET_PIX GET_PIX_ROTATED |
| 1782 | YXLOOP_NO_ZOOM |
| 1783 | #undef GET_PIX |
| 1784 | #undef DO_XCLIP |
| 1691 | 1785 | } |
| 1692 | 1786 | else // no rotate |
| 1693 | 1787 | { |
| 1694 | | YXLOOP_START_NO_ZOOM_NO_XCLIP |
| 1695 | | const UINT16 &pix = tempshape[y*16+x]; |
| 1696 | | DRAW_PIX |
| 1697 | | YXLOOP_END |
| 1788 | #define DO_XCLIP DO_XCLIP_NONE |
| 1789 | #define GET_PIX GET_PIX_NORMAL |
| 1790 | YXLOOP_NO_ZOOM |
| 1791 | #undef GET_PIX |
| 1792 | #undef DO_XCLIP |
| 1698 | 1793 | } |
| 1699 | 1794 | } |
| 1700 | 1795 | else |
| 1701 | 1796 | { |
| 1702 | 1797 | if (blit_rotate) |
| 1703 | 1798 | { |
| 1704 | | YXLOOP_START_NO_ZOOM |
| 1705 | | const UINT16 &pix = tempshape[x*16+y]; |
| 1706 | | DRAW_PIX |
| 1707 | | YXLOOP_END |
| 1799 | #define DO_XCLIP DO_XCLIP_REAL |
| 1800 | #define GET_PIX GET_PIX_ROTATED |
| 1801 | YXLOOP_NO_ZOOM |
| 1802 | #undef GET_PIX |
| 1803 | #undef DO_XCLIP |
| 1708 | 1804 | } |
| 1709 | 1805 | else // no rotate |
| 1710 | 1806 | { |
| 1711 | | YXLOOP_START_NO_ZOOM |
| 1712 | | const UINT16 &pix = tempshape[y*16+x]; |
| 1713 | | DRAW_PIX |
| 1714 | | YXLOOP_END |
| 1807 | #define DO_XCLIP DO_XCLIP_REAL |
| 1808 | #define GET_PIX GET_PIX_NORMAL |
| 1809 | YXLOOP_NO_ZOOM |
| 1810 | #undef GET_PIX |
| 1811 | #undef DO_XCLIP |
| 1715 | 1812 | } |
| 1716 | 1813 | } |
| 1717 | 1814 | } |
| r21453 | r21454 | |
| 1736 | 1833 | { |
| 1737 | 1834 | if (blit_rotate) |
| 1738 | 1835 | { |
| 1739 | | YXLOOP_START_NO_LINEZOOM_NO_XCLIP |
| 1740 | | const UINT16 &pix = tempshape[realx*16+realy]; |
| 1741 | | DRAW_PIX |
| 1742 | | YXLOOP_END |
| 1836 | #define DO_XCLIP DO_XCLIP_NONE |
| 1837 | #define GET_PIX GET_PIX_ROTATED |
| 1838 | YXLOOP_NO_LINEZOOM |
| 1839 | #undef GET_PIX |
| 1840 | #undef DO_XCLIP |
| 1743 | 1841 | } |
| 1744 | 1842 | else // no rotate |
| 1745 | 1843 | { |
| 1746 | | YXLOOP_START_NO_LINEZOOM_NO_XCLIP |
| 1747 | | const UINT16 &pix = tempshape[realy*16+realx]; |
| 1748 | | DRAW_PIX |
| 1749 | | YXLOOP_END |
| 1844 | #define DO_XCLIP DO_XCLIP_NONE |
| 1845 | #define GET_PIX GET_PIX_NORMAL |
| 1846 | YXLOOP_NO_LINEZOOM |
| 1847 | #undef GET_PIX |
| 1848 | #undef DO_XCLIP |
| 1750 | 1849 | } |
| 1751 | 1850 | } |
| 1752 | 1851 | else |
| 1753 | 1852 | { |
| 1754 | 1853 | if (blit_rotate) |
| 1755 | 1854 | { |
| 1756 | | YXLOOP_START_NO_LINEZOOM |
| 1757 | | const UINT16 &pix = tempshape[realx*16+realy]; |
| 1758 | | DRAW_PIX |
| 1759 | | YXLOOP_END |
| 1855 | #define DO_XCLIP DO_XCLIP_REAL |
| 1856 | #define GET_PIX GET_PIX_ROTATED |
| 1857 | YXLOOP_NO_LINEZOOM |
| 1858 | #undef GET_PIX |
| 1859 | #undef DO_XCLIP |
| 1760 | 1860 | } |
| 1761 | 1861 | else // no rotate |
| 1762 | 1862 | { |
| 1763 | | YXLOOP_START_NO_LINEZOOM |
| 1764 | | const UINT16 &pix = tempshape[realy*16+realx]; |
| 1765 | | DRAW_PIX |
| 1766 | | YXLOOP_END |
| 1863 | #define DO_XCLIP DO_XCLIP_REAL |
| 1864 | #define GET_PIX GET_PIX_NORMAL |
| 1865 | YXLOOP_NO_LINEZOOM |
| 1866 | #undef GET_PIX |
| 1867 | #undef DO_XCLIP |
| 1767 | 1868 | } |
| 1768 | 1869 | } |
| 1769 | 1870 | } // end zoomed |
| r21453 | r21454 | |
| 1946 | 2047 | testobject->clipvals[0] = m_clipvals[0][0]; |
| 1947 | 2048 | testobject->clipvals[1] = m_clipvals[0][1]; |
| 1948 | 2049 | testobject->clipvals[2] = m_clipvals[0][2]; |
| 1949 | | |
| 2050 | testobject->screen = 0; |
| 1950 | 2051 | queue = m_work_queue[0]; |
| 1951 | 2052 | } |
| 1952 | 2053 | else // 0x90, 0xa0, 0xaf, 0xb0, 0xc0 |
| r21453 | r21454 | |
| 1957 | 2058 | testobject->clipvals[0] = m_clipvals[1][0]; |
| 1958 | 2059 | testobject->clipvals[1] = m_clipvals[1][1]; |
| 1959 | 2060 | testobject->clipvals[2] = m_clipvals[1][2]; |
| 1960 | | |
| 2061 | testobject->screen = 1; |
| 1961 | 2062 | queue = m_work_queue[1]; |
| 1962 | 2063 | } |
| 1963 | 2064 | |