bool FifoCommandRunnable() { u32 buffer_size = (u32)(GetVideoBufferEndPtr() - g_pVideoData); if (buffer_size == 0) return false; // can't peek u8 cmd_byte = DataPeek8(0); u32 command_size = 0; switch (cmd_byte) { case GX_NOP: // Hm, this means that we scan over nop streams pretty slowly... case GX_CMD_INVL_VC: // Invalidate Vertex Cache - no parameters case GX_CMD_UNKNOWN_METRICS: // zelda 4 swords calls it and checks the metrics registers after that command_size = 1; break; case GX_LOAD_BP_REG: command_size = 5; break; case GX_LOAD_CP_REG: command_size = 6; break; case GX_LOAD_INDX_A: case GX_LOAD_INDX_B: case GX_LOAD_INDX_C: case GX_LOAD_INDX_D: command_size = 5; break; case GX_CMD_CALL_DL: command_size = 9; break; case GX_LOAD_XF_REG: { // check if we can read the header if (buffer_size >= 5) { command_size = 1 + 4; u32 Cmd2 = DataPeek32(1); int transfer_size = ((Cmd2 >> 16) & 15) + 1; command_size += transfer_size * 4; } else { return false; } }
u32 FifoCommandRunnable(u32 &command_size) { u32 cycleTime = 0; u32 buffer_size = (u32)(GetVideoBufferEndPtr() - g_pVideoData); if (buffer_size == 0) return 0; // can't peek u8 cmd_byte = DataPeek8(0); switch (cmd_byte) { case GX_NOP: // Hm, this means that we scan over nop streams pretty slowly... command_size = 1; cycleTime = 6; break; case GX_CMD_INVL_VC: // Invalidate Vertex Cache - no parameters command_size = 1; cycleTime = 6; break; case GX_CMD_UNKNOWN_METRICS: // zelda 4 swords calls it and checks the metrics registers after that command_size = 1; cycleTime = 6; break; case GX_LOAD_BP_REG: command_size = 5; cycleTime = 12; break; case GX_LOAD_CP_REG: command_size = 6; cycleTime = 12; break; case GX_LOAD_INDX_A: case GX_LOAD_INDX_B: case GX_LOAD_INDX_C: case GX_LOAD_INDX_D: command_size = 5; cycleTime = 6; // TODO break; case GX_CMD_CALL_DL: { // FIXME: Calculate the cycle time of the display list. //u32 address = DataPeek32(1); //u32 size = DataPeek32(5); //u8* old_pVideoData = g_pVideoData; //u8* startAddress = Memory::GetPointer(address); //// Avoid the crash if Memory::GetPointer failed .. //if (startAddress != 0) //{ // g_pVideoData = startAddress; // u8 *end = g_pVideoData + size; // u32 step = 0; // while (g_pVideoData < end) // { // cycleTime += FifoCommandRunnable(step); // g_pVideoData += step; // } //} //else //{ // cycleTime = 45; //} //// reset to the old pointer //g_pVideoData = old_pVideoData; command_size = 9; cycleTime = 45; // This is unverified } break; case GX_LOAD_XF_REG: { // check if we can read the header if (buffer_size >= 5) { command_size = 1 + 4; u32 Cmd2 = DataPeek32(1); int transfer_size = ((Cmd2 >> 16) & 15) + 1; command_size += transfer_size * 4; cycleTime = 18 + 6 * transfer_size; } else { return 0; } }