Path: blob/master/libmupen64plus/mupen64plus-video-z64/src/rdp.cpp
2 views
/*1* z642*3* Copyright (C) 2007 ziggy4*5* This program is free software; you can redistribute it and/or modify6* it under the terms of the GNU General Public License as published by7* the Free Software Foundation; either version 2 of the License, or8* (at your option) any later version.9*10* This program is distributed in the hope that it will be useful,11* but WITHOUT ANY WARRANTY; without even the implied warranty of12* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the13* GNU General Public License for more details.14*15* You should have received a copy of the GNU General Public License along16* with this program; if not, write to the Free Software Foundation, Inc.,17* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.18*19**/2021#include "rdp.h"22#include "rgl.h"2324#include <string.h>2526const char *rdpImageFormats[] =27{ "RGBA", "YUV", "CI", "IA", "I", "???", "???", "???" };2829rdpState_t rdpState;30uint32_t rdpChanged;31//rdpColor_t rdpTlut[1024];32uint8_t rdpTmem[4*0x1000];33int rdpFbFormat;34int rdpFbSize;35int rdpFbWidth;36uint32_t rdpFbAddress;37uint32_t rdpZbAddress;38int rdpTiFormat;39int rdpTiSize;40int rdpTiWidth;41uint32_t rdpTiAddress;42rdpTile_t rdpTiles[8];43int rdpTileSet;4445struct area_t {46int start, stop;47uint32_t from;48int fromLine, fromFormat, fromSize;49};5051#define MAX_TMEM_AREAS 1652static area_t tmemAreas[MAX_TMEM_AREAS];53static int nbTmemAreas;5455#ifdef RDP_DEBUG56int rdp_dump;57#endif5859#define MAXCMD 0x10000060static uint32_t rdp_cmd_data[MAXCMD+44];61static volatile int rdp_cmd_ptr = 0;62static volatile int rdp_cmd_cur = 0;63static int rdp_cmd_left = 0;6465#ifdef RDP_DEBUG66uint32_t rdpTraceBuf[0x100000];67int rdpTracePos;68#endif697071static void MarkTmemArea(int start, int stop, uint32_t from, uint32_t fromLine,72int fromFormat, int fromSize)73{74int i;7576// remove areas that intersect77for (i=0; i<nbTmemAreas; i++)78while (i<nbTmemAreas &&79tmemAreas[i].start<stop && tmemAreas[i].stop>start) {80memmove(tmemAreas+i, tmemAreas+i+1, nbTmemAreas-i-1);81nbTmemAreas--;82}8384DUMP("marking tmem %x --> %x rdram %x\n", start, stop, from);8586// add new area87//rglAssert(nbTmemAreas < MAX_TMEM_AREAS);88if (nbTmemAreas == MAX_TMEM_AREAS) {89LOG("tmem areas buffer full, clearing\n");90nbTmemAreas = 0;91}92tmemAreas[nbTmemAreas].start = start;93tmemAreas[nbTmemAreas].stop = stop;94tmemAreas[nbTmemAreas].from = from;95tmemAreas[nbTmemAreas].fromLine = fromLine;96tmemAreas[nbTmemAreas].fromFormat = fromFormat;97tmemAreas[nbTmemAreas].fromSize = fromSize;98nbTmemAreas++;99}100101uint32_t rdpGetTmemOrigin(int tmem, int * line, int * stop, int * format, int * size)102{103int i;104for (i=0; i<nbTmemAreas; i++)105if (tmemAreas[i].start == tmem) {106*line = tmemAreas[i].fromLine;107*stop = tmemAreas[i].stop;108*format = tmemAreas[i].fromFormat;109*size = tmemAreas[i].fromSize;110return tmemAreas[i].from;111}112113return ~0;114}115116inline uint32_t READ_RDP_DATA(uint32_t address)117{118if (dp_status & 0x1) // XBUS_DMEM_DMA enabled119{120return rsp_dmem[(address & 0xfff) / 4];121}122else123{124return rdram[(address / 4)];125}126}127128static const int rdp_command_length[64] =129{1308, // 0x00, No Op1318, // 0x01, ???1328, // 0x02, ???1338, // 0x03, ???1348, // 0x04, ???1358, // 0x05, ???1368, // 0x06, ???1378, // 0x07, ???13832, // 0x08, Non-Shaded Triangle13932+16, // 0x09, Non-Shaded, Z-Buffered Triangle14032+64, // 0x0a, Textured Triangle14132+64+16, // 0x0b, Textured, Z-Buffered Triangle14232+64, // 0x0c, Shaded Triangle14332+64+16, // 0x0d, Shaded, Z-Buffered Triangle14432+64+64, // 0x0e, Shaded+Textured Triangle14532+64+64+16,// 0x0f, Shaded+Textured, Z-Buffered Triangle1468, // 0x10, ???1478, // 0x11, ???1488, // 0x12, ???1498, // 0x13, ???1508, // 0x14, ???1518, // 0x15, ???1528, // 0x16, ???1538, // 0x17, ???1548, // 0x18, ???1558, // 0x19, ???1568, // 0x1a, ???1578, // 0x1b, ???1588, // 0x1c, ???1598, // 0x1d, ???1608, // 0x1e, ???1618, // 0x1f, ???1628, // 0x20, ???1638, // 0x21, ???1648, // 0x22, ???1658, // 0x23, ???16616, // 0x24, Texture_Rectangle16716, // 0x25, Texture_Rectangle_Flip1688, // 0x26, Sync_Load1698, // 0x27, Sync_Pipe1708, // 0x28, Sync_Tile1718, // 0x29, Sync_Full1728, // 0x2a, Set_Key_GB1738, // 0x2b, Set_Key_R1748, // 0x2c, Set_Convert1758, // 0x2d, Set_Scissor1768, // 0x2e, Set_Prim_Depth1778, // 0x2f, Set_Other_Modes1788, // 0x30, Load_TLUT1798, // 0x31, ???1808, // 0x32, Set_Tile_Size1818, // 0x33, Load_Block1828, // 0x34, Load_Tile1838, // 0x35, Set_Tile1848, // 0x36, Fill_Rectangle1858, // 0x37, Set_Fill_Color1868, // 0x38, Set_Fog_Color1878, // 0x39, Set_Blend_Color1888, // 0x3a, Set_Prim_Color1898, // 0x3b, Set_Env_Color1908, // 0x3c, Set_Combine1918, // 0x3d, Set_Texture_Image1928, // 0x3e, Set_Mask_Image1938 // 0x3f, Set_Color_Image194};195196/*****************************************************************************/197198////////////////////////199// RDP COMMANDS200////////////////////////201202static void rdp_invalid(uint32_t w1, uint32_t w2)203{204LOGERROR("RDP: invalid command %d, %08X %08X\n", (w1 >> 24) & 0x3f, w1, w2);205}206207static void rdp_noop(uint32_t w1, uint32_t w2)208{209210}211212static void triangle(uint32_t w1, uint32_t w2, int shade, int texture, int zbuffer)213{214rglTriangle(w1, w2, shade, texture, zbuffer, rdp_cmd_data + rdp_cmd_cur);215}216217static void rdp_tri_noshade(uint32_t w1, uint32_t w2)218{219triangle(w1, w2, 0, 0, 0);220}221222static void rdp_tri_noshade_z(uint32_t w1, uint32_t w2)223{224triangle(w1, w2, 0, 0, 1);225}226227static void rdp_tri_tex(uint32_t w1, uint32_t w2)228{229triangle(w1, w2, 0, 1, 0);230}231232static void rdp_tri_tex_z(uint32_t w1, uint32_t w2)233{234triangle(w1, w2, 0, 1, 1);235}236237static void rdp_tri_shade(uint32_t w1, uint32_t w2)238{239triangle(w1, w2, 1, 0, 0);240}241242static void rdp_tri_shade_z(uint32_t w1, uint32_t w2)243{244triangle(w1, w2, 1, 0, 1);245}246247static void rdp_tri_texshade(uint32_t w1, uint32_t w2)248{249triangle(w1, w2, 1, 1, 0);250}251252static void rdp_tri_texshade_z(uint32_t w1, uint32_t w2)253{254triangle(w1, w2, 1, 1, 1);255}256257static void rdp_tex_rect(uint32_t w1, uint32_t w2)258{259uint32_t w3, w4;260rdpTexRect_t rect;261262w3 = rdp_cmd_data[rdp_cmd_cur+2];263w4 = rdp_cmd_data[rdp_cmd_cur+3];264265rect.tilenum = (w2 >> 24) & 0x7;266rect.xl = (w1 >> 12) & 0xfff;267rect.yl = (w1 >> 0) & 0xfff;268rect.xh = (w2 >> 12) & 0xfff;269rect.yh = (w2 >> 0) & 0xfff;270rect.s = (w3 >> 16) & 0xffff;271rect.t = (w3 >> 0) & 0xffff;272rect.dsdx = (w4 >> 16) & 0xffff;273rect.dtdy = (w4 >> 0) & 0xffff;274275rglTextureRectangle(&rect, 0);276}277278static void rdp_tex_rect_flip(uint32_t w1, uint32_t w2)279{280uint32_t w3, w4;281rdpTexRect_t rect;282283w3 = rdp_cmd_data[rdp_cmd_cur+2];284w4 = rdp_cmd_data[rdp_cmd_cur+3];285286rect.tilenum = (w2 >> 24) & 0x7;287rect.xl = (w1 >> 12) & 0xfff;288rect.yl = (w1 >> 0) & 0xfff;289rect.xh = (w2 >> 12) & 0xfff;290rect.yh = (w2 >> 0) & 0xfff;291rect.t = (w3 >> 16) & 0xffff;292rect.s = (w3 >> 0) & 0xffff;293rect.dtdy = (w4 >> 16) & 0xffff;294rect.dsdx = (w4 >> 0) & 0xffff;295296rglTextureRectangle(&rect, 1);297}298299static void rdp_sync_load(uint32_t w1, uint32_t w2)300{301// Nothing to do?302}303304static void rdp_sync_pipe(uint32_t w1, uint32_t w2)305{306// Nothing to do?307}308309static void rdp_sync_tile(uint32_t w1, uint32_t w2)310{311// Nothing to do?312}313314void rdpSignalFullSync();315void rdpWaitFullSync();316#ifdef RDP_DEBUG317int nbFullSync;318#endif319static void rdp_sync_full(uint32_t w1, uint32_t w2)320{321//printf("full sync\n");322rglFullSync();323rglUpdate();324325if (rglSettings.async)326rdpSignalFullSync();327else {328*gfx.MI_INTR_REG |= 0x20;329gfx.CheckInterrupts();330}331#ifdef RDP_DEBUG332nbFullSync++;333#endif334}335336static void rdp_set_key_gb(uint32_t w1, uint32_t w2)337{338//osd_die("RDP: unhandled command set_key_gb, %08X %08X\n", w1, w2);339}340341static void rdp_set_key_r(uint32_t w1, uint32_t w2)342{343//osd_die("RDP: unhandled command set_key_r, %08X %08X\n", w1, w2);344}345346static void rdp_set_convert(uint32_t w1, uint32_t w2)347{348rdpState.k5 = w2&0xff;349//osd_die("RDP: unhandled command set_convert, %08X %08X\n", w1, w2);350}351352static void rdp_set_scissor(uint32_t w1, uint32_t w2)353{354rdpChanged |= RDP_BITS_CLIP;355rdpState.clipMode = (w2 >> 24) & 3;356rdpState.clip.xh = (w1 >> 12) & 0xfff;357rdpState.clip.yh = (w1 >> 0) & 0xfff;358rdpState.clip.xl = (w2 >> 12) & 0xfff;359rdpState.clip.yl = (w2 >> 0) & 0xfff;360// TODO: handle f & o?361}362363static void rdp_set_prim_depth(uint32_t w1, uint32_t w2)364{365rdpChanged |= RDP_BITS_MISC;366rdpState.primitiveZ = (uint16_t)(w2 >> 16);367rdpState.primitiveDeltaZ = (uint16_t)(w1);368}369370static void rdp_set_other_modes(uint32_t w1, uint32_t w2)371{372rdpChanged |= RDP_BITS_OTHER_MODES;373rdpState.otherModes.w1 = w1;374rdpState.otherModes.w2 = w2;375}376377static void rdp_load_tlut(uint32_t w1, uint32_t w2)378{379int tilenum = (w2 >> 24) & 0x7;380381rdpChanged |= RDP_BITS_TILE_SETTINGS;382383#define tile rdpTiles[tilenum]384//rdpTile_t tile;385tile.sl = (w1 >> 12) & 0xfff;386tile.tl = (w1 >> 0) & 0xfff;387tile.sh = (w2 >> 12) & 0xfff;388tile.th = (w2 >> 0) & 0xfff;389390int i;391392rdpChanged |= RDP_BITS_TLUT;393394int count = ((tile.sh - tile.sl + 4) >>2) * ((tile.th - tile.tl + 4) >>2);395396switch (rdpTiSize)397{398case RDP_PIXEL_SIZE_16BIT:399{400uint16_t *src = (uint16_t *)&rdram[(rdpTiAddress + (tile.tl >>2) * rdpTiWidth * 2 + ((tile.sl >>2) << rdpTiSize >> 1))/4];401uint16_t *dst = (uint16_t *)(rdpTmem + rdpTiles[tilenum].tmem);402403// printf("loading TLUT from %x --> %x\n",404// tile.th * rdpTiWidth / 2 + (tile.sh << rdpTiSize >> 1)/4405406for (i=0; i < count; i++)407{408dst[i*4] = src[i^1];409}410break;411}412default: LOGERROR("RDP: load_tlut: size = %d\n", rdpTiSize);413}414#undef tile415}416417static void rdp_set_tile_size(uint32_t w1, uint32_t w2)418{419int tilenum = (w2 >> 24) & 0x7;420421rdpChanged |= RDP_BITS_TILE_SETTINGS;422423#define tile rdpTiles[tilenum]424tile.sl = (w1 >> 12) & 0xfff;425tile.tl = (w1 >> 0) & 0xfff;426tile.sh = (w2 >> 12) & 0xfff;427tile.th = (w2 >> 0) & 0xfff;428#undef tile429}430431static void rdp_load_block(uint32_t w1, uint32_t w2)432{433int i, width;434uint16_t sl, sh, tl, dxt;435int tilenum = (w2 >> 24) & 0x7;436uint32_t *src, *tc;437int tb;438439rdpChanged |= RDP_BITS_TMEM;440441sl = ((w1 >> 12) & 0xfff);442tl = ((w1 >> 0) & 0xfff) << 11;443sh = ((w2 >> 12) & 0xfff);444dxt = ((w2 >> 0) & 0xfff);445446width = (sh - sl + 1) << rdpTiSize >> 1;447448src = (uint32_t*)&rdram[0];449tc = (uint32_t*)rdpTmem;450tb = rdpTiles[tilenum].tmem/4;451452//printf("Load block to %x width %x\n", rdpTiles[tilenum].tmem, width);453454MarkTmemArea(rdpTiles[tilenum].tmem, rdpTiles[tilenum].tmem + width,455tl * rdpTiWidth*4 + rdpTiAddress + sl*4, 0, ~0, ~0);456457if (tb+width/4 > 0x1000/4) {458LOG("load_block : fixup too large width\n");459width = 0x1000-tb*4;460}461462if (dxt != 0)463{464int j=0;465466//rglAssert(tb+width/4 <= 0x1000/4);467468int swap = rdpTiles[tilenum].size == 3? 2 : 1;469470for (i=0; i < width / 4; i+=2)471{472int t = j >> 11;473474tc[(((tb+i) + 0) ^ ((t & 1) ? swap : 0))&0x3ff] =475src[rdpTiAddress / 4 + ((tl * rdpTiWidth) / 4) + sl + i + 0];476tc[(((tb+i) + 1) ^ ((t & 1) ? swap : 0))&0x3ff] =477src[rdpTiAddress / 4 + ((tl * rdpTiWidth) / 4) + sl + i + 1];478479j += dxt;480}481}482else483{484//rglAssert(tb+width/4 <= 0x1000/4);485for (i=0; i < width / 4; i++)486{487tc[(tb+i)&0x3ff] = src[((tl * rdpTiWidth) / 4) + rdpTiAddress / 4 + sl + i];488}489}490}491492static void rdp_load_tile(uint32_t w1, uint32_t w2)493{494int i, j;495uint16_t sl, sh, tl, th;496int width, height;497int tilenum = (w2 >> 24) & 0x7;498int line;499500rdpChanged |= RDP_BITS_TMEM;501502sl = ((w1 >> 12) & 0xfff) / 4;503tl = ((w1 >> 0) & 0xfff) / 4;504sh = ((w2 >> 12) & 0xfff) / 4;505th = ((w2 >> 0) & 0xfff) / 4;506507width = (sh - sl) + 1;508height = (th - tl) + 1;509510// printf("Load tile to %x line %x height %d\n",511// rdpTiles[tilenum].tmem,512// rdpTiles[tilenum].line,513// height);514515rdpTiles[tilenum].size = rdpTiSize; // CHECK THIS516line = rdpTiles[tilenum].line;517switch (rdpTiles[tilenum].size /*rdpTiSize*/)518{519case RDP_PIXEL_SIZE_8BIT:520{521uint8_t *src = (uint8_t*)&rdram[0];522uint8_t *tc = (uint8_t*)rdpTmem;523int tb = rdpTiles[tilenum].tmem;524525MarkTmemArea(tb, tb + height*line, rdpTiAddress + tl * rdpTiWidth + sl,526rdpTiWidth, rdpTiFormat, rdpTiSize);527528if (tb + (line * (height-1) + width) > 4096)529{530LOGERROR("rdp_load_tile 8-bit: tmem %04X, width %d, height %d = %d\n", rdpTiles[tilenum].tmem, width, height, width*height);531height = (4096-tb)/line;532}533534for (j=0; j < height; j++)535{536int tline = tb + (rdpTiles[tilenum].line * j);537int s = ((j + tl) * rdpTiWidth) + sl;538539for (i=0; i < width; i++)540{541tc[(((tline+i) ^ BYTE_ADDR_XOR) ^ ((j & 1) ? 4 : 0))&0xfff] = src[(rdpTiAddress + s++) ^ BYTE_ADDR_XOR];542}543}544break;545}546case RDP_PIXEL_SIZE_16BIT:547{548uint16_t *src = (uint16_t*)&rdram[0];549uint16_t *tc = (uint16_t*)rdpTmem;550int tb = (rdpTiles[tilenum].tmem / 2);551552if (tb + (line/2 * (height-1) + width) > 2048)553{554LOGERROR("rdp_load_tile 16-bit: tmem %04X, width %d, height %d = %d\n", rdpTiles[tilenum].tmem, width, height, width*height);555height = (2048 - tb) / (line/2);556}557558MarkTmemArea(tb*2, tb*2 + height*line,559rdpTiAddress + (tl * rdpTiWidth + sl)*2,560rdpTiWidth*2, rdpTiFormat, rdpTiSize);561562for (j=0; j < height; j++)563{564int tline = tb + ((rdpTiles[tilenum].line / 2) * j);565int s = ((j + tl) * rdpTiWidth) + sl;566567for (i=0; i < width; i++)568{569tc[(((tline+i) ^ WORD_ADDR_XOR) ^ ((j & 1) ? 2 : 0))&0x7ff] = src[(rdpTiAddress / 2 + s++) ^ WORD_ADDR_XOR];570}571}572break;573}574case RDP_PIXEL_SIZE_32BIT:575{576uint32_t *src = (uint32_t*)&rdram[0];577uint32_t *tc = (uint32_t*)rdpTmem;578int tb = (rdpTiles[tilenum].tmem / 4);579580MarkTmemArea(tb*4, tb*4 + height*line*2,581rdpTiAddress + (tl * rdpTiWidth + sl)*4,582rdpTiWidth*4, rdpTiFormat, rdpTiSize);583584if (tb + (line/2 * (height-1) + width) > 1024)585{586rdp_log(M64MSG_ERROR, "rdp_load_tile 32-bit: tmem %04X, width %d, height %d = %d\n", rdpTiles[tilenum].tmem, width, height, width*height);587}588589for (j=0; j < height; j++)590{591int tline = tb + ((rdpTiles[tilenum].line / 2) * j);592int s = ((j + tl) * rdpTiWidth) + sl;593594for (i=0; i < width; i++)595{596tc[((tline+i) ^ ((j & 1) ? 2 : 0))&0x3ff] = src[(rdpTiAddress / 4 + s++)];597}598}599break;600}601602default:603rdp_log(M64MSG_ERROR, "RDP: load_tile: size = %d\n", rdpTiSize);604}605}606607static void rdp_set_tile(uint32_t w1, uint32_t w2)608{609int tilenum = (w2 >> 24) & 0x7;610//int i;611612rdpChanged |= RDP_BITS_TILE_SETTINGS;613rdpTileSet |= 1<<tilenum;614615#define tile rdpTiles[tilenum]616tile.format = (w1 >> 21) & 0x7;617tile.size = (w1 >> 19) & 0x3;618tile.line = ((w1 >> 9) & 0x1ff) * 8;619tile.tmem = ((w1 >> 0) & 0x1ff) * 8;620tile.palette= (w2 >> 20) & 0xf;621tile.ct = (w2 >> 19) & 0x1;622tile.mt = (w2 >> 18) & 0x1;623tile.mask_t = (w2 >> 14) & 0xf;624tile.shift_t= (w2 >> 10) & 0xf;625if (tile.shift_t >= 12) tile.shift_t -= 16;626tile.cs = (w2 >> 9) & 0x1;627tile.ms = (w2 >> 8) & 0x1;628tile.mask_s = (w2 >> 4) & 0xf;629tile.shift_s= (w2 >> 0) & 0xf;630if (tile.shift_s >= 12) tile.shift_s -= 16;631#undef tile632}633634static void rdp_fill_rect(uint32_t w1, uint32_t w2)635{636rdpRect_t rect;637rect.xl = (w1 >> 12) & 0xfff;638rect.yl = (w1 >> 0) & 0xfff;639rect.xh = (w2 >> 12) & 0xfff;640rect.yh = (w2 >> 0) & 0xfff;641642rglFillRectangle(&rect);643}644645static void rdp_set_fill_color(uint32_t w1, uint32_t w2)646{647rdpChanged |= RDP_BITS_FILL_COLOR;648rdpState.fillColor = w2;649}650651static void rdp_set_fog_color(uint32_t w1, uint32_t w2)652{653rdpChanged |= RDP_BITS_FOG_COLOR;654rdpState.fogColor = w2;655}656657static void rdp_set_blend_color(uint32_t w1, uint32_t w2)658{659rdpChanged |= RDP_BITS_BLEND_COLOR;660rdpState.blendColor = w2;661}662663static void rdp_set_prim_color(uint32_t w1, uint32_t w2)664{665rdpChanged |= RDP_BITS_PRIM_COLOR;666// TODO: prim min level, prim_level667rdpState.primColor = w2;668}669670static void rdp_set_env_color(uint32_t w1, uint32_t w2)671{672rdpChanged |= RDP_BITS_ENV_COLOR;673rdpState.envColor = w2;674}675676static void rdp_set_combine(uint32_t w1, uint32_t w2)677{678rdpChanged |= RDP_BITS_COMBINE_MODES;679680rdpState.combineModes.w1 = w1;681rdpState.combineModes.w2 = w2;682}683684static void rdp_set_texture_image(uint32_t w1, uint32_t w2)685{686rdpChanged |= RDP_BITS_TI_SETTINGS;687688rdpTiFormat = (w1 >> 21) & 0x7;689rdpTiSize = (w1 >> 19) & 0x3;690rdpTiWidth = (w1 & 0x3ff) + 1;691rdpTiAddress = w2 & 0x01ffffff;692}693694static void rdp_set_mask_image(uint32_t w1, uint32_t w2)695{696rdpChanged |= RDP_BITS_ZB_SETTINGS;697rdpZbAddress = w2 & 0x01ffffff;698}699700static void rdp_set_color_image(uint32_t w1, uint32_t w2)701{702rdpChanged |= RDP_BITS_FB_SETTINGS;703rdpFbFormat = (w1 >> 21) & 0x7;704rdpFbSize = (w1 >> 19) & 0x3;705rdpFbWidth = (w1 & 0x3ff) + 1;706rdpFbAddress = w2 & 0x01ffffff;707}708709/*****************************************************************************/710711static void (* rdp_command_table[64])(uint32_t w1, uint32_t w2) =712{713/* 0x00 */714rdp_noop, rdp_invalid, rdp_invalid, rdp_invalid,715rdp_invalid, rdp_invalid, rdp_invalid, rdp_invalid,716rdp_tri_noshade, rdp_tri_noshade_z, rdp_tri_tex, rdp_tri_tex_z,717rdp_tri_shade, rdp_tri_shade_z, rdp_tri_texshade, rdp_tri_texshade_z,718/* 0x10 */719rdp_invalid, rdp_invalid, rdp_invalid, rdp_invalid,720rdp_invalid, rdp_invalid, rdp_invalid, rdp_invalid,721rdp_invalid, rdp_invalid, rdp_invalid, rdp_invalid,722rdp_invalid, rdp_invalid, rdp_invalid, rdp_invalid,723/* 0x20 */724rdp_invalid, rdp_invalid, rdp_invalid, rdp_invalid,725rdp_tex_rect, rdp_tex_rect_flip, rdp_sync_load, rdp_sync_pipe,726rdp_sync_tile, rdp_sync_full, rdp_set_key_gb, rdp_set_key_r,727rdp_set_convert, rdp_set_scissor, rdp_set_prim_depth, rdp_set_other_modes,728/* 0x30 */729rdp_load_tlut, rdp_invalid, rdp_set_tile_size, rdp_load_block,730rdp_load_tile, rdp_set_tile, rdp_fill_rect, rdp_set_fill_color,731rdp_set_fog_color, rdp_set_blend_color, rdp_set_prim_color, rdp_set_env_color,732rdp_set_combine, rdp_set_texture_image, rdp_set_mask_image, rdp_set_color_image733};734735void rdp_process_list(void)736{737//int i;738uint32_t cmd;//, length, cmd_length;739740rglUpdateStatus();741if (!rglSettings.threaded)742rdp_store_list();743744if (rglStatus == RGL_STATUS_CLOSED)745return;746747// this causes problem with depth writeback in zelda mm748// but is necessary for in fisherman749rglUpdate();750751while (rdp_cmd_cur != rdp_cmd_ptr)752{753cmd = (rdp_cmd_data[rdp_cmd_cur] >> 24) & 0x3f;754// if (((rdp_cmd_data[rdp_cmd_cur] >> 24) & 0xc0) != 0xc0)755// {756// LOGERROR("rdp_process_list: invalid rdp command %08X at %08X\n", rdp_cmd_data[rdp_cmd_cur], dp_start+(rdp_cmd_cur * 4));757// }758759if ((((rdp_cmd_ptr-rdp_cmd_cur)&(MAXCMD-1)) * 4) < rdp_command_length[cmd])760{761// LOGERROR("rdp_process_list: not enough rdp command data: cur = %d, ptr = %d, expected = %d\n", rdp_cmd_cur, rdp_cmd_ptr, rdp_command_length[cmd]);762// return;763break;764}765766#ifdef RDP_DEBUG767if (rdp_dump)768{769char string[4000];770int rdp_dasm(uint32_t * rdp_cmd_data, int rdp_cmd_cur, int length, char *buffer);771rdp_dasm(rdp_cmd_data, rdp_cmd_cur, rdp_command_length[cmd], string);772773fprintf(stderr, "%08X: %08X %08X %s\n", dp_start+(rdp_cmd_cur * 4), rdp_cmd_data[rdp_cmd_cur+0], rdp_cmd_data[rdp_cmd_cur+1], string);774}775#endif776777#ifdef RDP_DEBUG778memcpy(rdpTraceBuf+rdpTracePos, rdp_cmd_data+rdp_cmd_cur, rdp_command_length[cmd]);779#endif780781if (rdp_cmd_cur + rdp_command_length[cmd]/4 > MAXCMD)782memcpy(rdp_cmd_data + MAXCMD, rdp_cmd_data, rdp_command_length[cmd] - (MAXCMD - rdp_cmd_cur)*4);783784// execute the command785rdp_command_table[cmd](rdp_cmd_data[rdp_cmd_cur+0], rdp_cmd_data[rdp_cmd_cur+1]);786787#ifdef RDP_DEBUG788rdpTracePos += rdp_command_length[cmd] / 4;789rglAssert(rdpTracePos < sizeof(rdpTraceBuf)/sizeof(rdpTraceBuf[0]));790#endif791792rdp_cmd_cur = (rdp_cmd_cur + rdp_command_length[cmd] / 4) & (MAXCMD-1);793}794795// dp_current = dp_end;796// dp_start = dp_end;797dp_start = dp_current;798799dp_status &= ~0x0002;800}801802int rdp_store_list(void)803{804uint32_t i;805uint32_t data, cmd, length;806int sync = 0;807808// while (dp_current < dp_end) {809810// }811// dp_status &= ~0x0002;812813length = dp_end - dp_current;814815// LOG("rdp start %x cur %x end %x length %d dp_status %x\n",816// dp_start, dp_current, dp_end,817// length, dp_status);818819if (dp_end <= dp_current) {820return 0;821}822823// load command data824for (i=0; i < length; i += 4)825{826data = READ_RDP_DATA(dp_current + i);827if (rglSettings.async) {828if (rdp_cmd_left) {829rdp_cmd_left--;830} else {831cmd = (data >> 24) & 0x3f;832rdp_cmd_left = rdp_command_length[cmd]/4-1;833if (cmd == 0x29) // full_sync834sync = 1;835}836}837rdp_cmd_data[rdp_cmd_ptr] = data;838rdp_cmd_ptr = (rdp_cmd_ptr + 1) & (MAXCMD-1);839}840841dp_current += length;842843return sync;844}845846847int rdp_init()848{849rdp_cmd_cur = rdp_cmd_ptr = 0;850rdp_cmd_left = 0;851#ifdef RDP_DEBUG852rdpTracePos = 0;853#endif854nbTmemAreas = 0;855return rglInit();856}857858859860