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;
			}
		}