Exemple #1
0
 public Crypto1(ulong key)
 {
     for (int i = 47; i > 0; i -= 2)
     {
         _state.Odd  = _state.Odd << 1 | key.Bit((i - 1) ^ 7);
         _state.Even = _state.Even << 1 | key.Bit(i ^ 7);
     }
 }
Exemple #2
0
            public void AddEdges(ulong bits)
            {
                for (int j = 0; j < n; j++)
                {
                    if (!bits.Bit(j))
                    {
                        continue;
                    }

                    for (int k = j + 1; k < n; k++)
                    {
                        if (bits.Bit(k))
                        {
                            AddEdge(j, k);
                        }
                    }
                }
            }
Exemple #3
0
 public override string ToString()
 {
     return(new string(Enumerable.Range(0, 64).Select(i => MaskChar(one.Bit(i), zero.Bit(i))).Reverse().ToArray()));
 }
Exemple #4
0
        public static RDPState ExecuteCommands(UVTXFile uvtx, out StringBuilder cmdsString)
        {
            RDPState rdpState = new RDPState();

            cmdsString = new StringBuilder();
            foreach (byte[] commandBytes in uvtx.displayListCommands)
            {
                byte[] bytes = commandBytes;

                string operationDesc;
                switch ((Fast3DEX2Opcode)bytes[0])
                {
                case Fast3DEX2Opcode.G_TEXTURE:
                {
                    ulong word          = bytes.ReadUInt64(0);
                    byte  mipMap        = (byte)(word.Bits(43, 3) + 1);
                    byte  tileDescIndex = (byte)word.Bits(40, 3);

                    bool  on           = word.Bit(33);
                    float scaleFactorS = bytes.ReadUInt16(4) / (float)0x10000;
                    float scaleFactorT = bytes.ReadUInt16(6) / (float)0x10000;

                    rdpState.tileToUseWhenTexturing = tileDescIndex;
                    rdpState.maxMipMapLevels        = mipMap;
                    rdpState.texturingEnabled       = on;
                    rdpState.textureScaleS          = scaleFactorS;
                    rdpState.textureScaleT          = scaleFactorT;

                    operationDesc  = "G_TEXTURE        (Set RSP texture state)";
                    operationDesc += $": tile {tileDescIndex} scale=<{scaleFactorS}, {scaleFactorT}>; mm={mipMap} on={on}";
                    break;
                }

                case Fast3DEX2Opcode.G_SetOtherMode_H:
                {
                    // TODO: actually implement this?
                    operationDesc = "G_SetOtherMode_H (Set Other Modes Hi)";

                    int length = bytes[3] + 1;
                    int shift  = 32 - length - bytes[2];

                    string str = otherModeHShiftToStr[shift];
                    byte   val = (byte)bytes.ReadUInt64(0).Bits(shift, length);

                    // TODO?: https://wiki.cloudmodding.com/oot/F3DZEX#RDP_Other_Modes.2C_Higher_Half
                    string valStr = Convert.ToString(val, 2).PadLeft(length, '0');

                    operationDesc += $": {str} = {valStr}";
                    break;
                }

                case Fast3DEX2Opcode.G_SETTILESIZE:
                {
                    ulong word = bytes.ReadUInt64(0);


                    ushort sLoRaw        = (ushort)word.Bits(44, 12);
                    ushort tLoRaw        = (ushort)word.Bits(32, 12);
                    byte   tileDescIndex = (byte)word.Bits(24, 3);
                    ushort sHiRaw        = (ushort)word.Bits(12, 12);
                    ushort tHiRaw        = (ushort)word.Bits(0, 12);

                    TileDescriptor t = rdpState.tileDescriptors[tileDescIndex];
                    t.sLo = sLoRaw / 4.0f;
                    t.tLo = tLoRaw / 4.0f;
                    t.sHi = sHiRaw / 4.0f;
                    t.tHi = tHiRaw / 4.0f;

                    float visWidth  = (t.sHi - t.sLo) + 1;
                    float visHeight = (t.tHi - t.tLo) + 1;

                    operationDesc  = "G_SETTILESIZE    (Set texture coords and size)";
                    operationDesc += $": tile {tileDescIndex} lo=({t.sLo}, {t.tLo}) hi=({t.sHi}, {t.tHi}) [[{visWidth}, {visHeight}]]";
                    break;
                }

                case Fast3DEX2Opcode.G_LOADBLOCK:
                {
                    ulong word = bytes.ReadUInt64(0);

                    ushort sLo           = (ushort)word.Bits(44, 12);
                    ushort tLo           = (ushort)word.Bits(32, 12);
                    byte   tileDescIndex = (byte)word.Bits(24, 3);
                    ushort sHi           = (ushort)word.Bits(12, 12);
                    ushort dxt           = (ushort)word.Bits(0, 12);

                    if (dxt != 0)
                    {
                        throw new Exception();
                    }

                    if (sLo != 0 || tLo != 0)
                    {
                        throw new Exception();
                    }

                    if (rdpState.nextDRAMAddrForLoad == null || rdpState.bitSizeOfNextDataForLoad == null)
                    {
                        throw new Exception();
                    }

                    rdpState.tileDescriptors[tileDescIndex].sLo = sLo;
                    rdpState.tileDescriptors[tileDescIndex].tLo = tLo;
                    rdpState.tileDescriptors[tileDescIndex].sHi = sHi;
                    rdpState.tileDescriptors[tileDescIndex].tHi = dxt;         // Not 100% sure this is the correct behavior


                    int dataStart       = (int)rdpState.nextDRAMAddrForLoad;
                    int dataLengthBytes = (sHi + 1) * Texels.BitSizeToNumBytes((BitSize)rdpState.bitSizeOfNextDataForLoad);
                    int destPtr         = rdpState.tileDescriptors[tileDescIndex].tmemAddressInWords * 8;

                    // I'm assuming this is the correct behavior because if I don't do this a lot of textures have a notch at the top right
                    // (Also it would make sense given that interleaving and addresses are all done on 64-bit words
                    dataLengthBytes = (int)Math.Ceiling(dataLengthBytes / 8f) * 8;

                    // Note: technically this inaccurate, we shouldn't clamp. But the instructions read beyond the file and IDK why,
                    // it doesn't seem to serve any purpose so I assume it's a bug (or I don't understand something about how the RSP works)
                    Array.Copy(uvtx.texelData, dataStart, rdpState.tmem, destPtr, Math.Min(uvtx.texelData.Length - dataStart, dataLengthBytes));

                    operationDesc  = "G_LOADBLOCK      (Load data into TMEM (uses params set in SETTIMG))";
                    operationDesc += $": tile {tileDescIndex} sLo={sLo} tLo={tLo} sHi={sHi} dxt={dxt}";
                    break;
                }

                case Fast3DEX2Opcode.G_SETTILE:
                {
                    ulong          word = bytes.ReadUInt64(0);
                    TileDescriptor t    = new TileDescriptor
                    {
                        format             = (ColorFormat)word.Bits(53, 3),
                        bitSize            = (BitSize)word.Bits(51, 2),
                        wordsPerLine       = (ushort)word.Bits(41, 9),
                        tmemAddressInWords = (ushort)word.Bits(32, 9),
                        palette            = (byte)word.Bits(20, 4),
                        clampEnableT       = word.Bit(19),
                        mirrorEnableT      = word.Bit(18),
                        maskT         = (byte)word.Bits(14, 4),
                        shiftT        = (byte)word.Bits(10, 4),
                        clampEnableS  = word.Bit(9),
                        mirrorEnableS = word.Bit(8),
                        maskS         = (byte)word.Bits(4, 4),
                        shiftS        = (byte)word.Bits(0, 4),
                    };
                    byte tileDescIndex = (byte)word.Bits(24, 3);
                    rdpState.tileDescriptors[tileDescIndex] = t;

                    operationDesc  = "G_SETTILE        (Set texture properties)";
                    operationDesc += $": tile {tileDescIndex} fmt={t.bitSize}-bit {t.format} wordsPerLine={t.wordsPerLine} addrWords={t.tmemAddressInWords} palette={t.palette}"
                                     + $" s(clmp={t.clampEnableS} mirr={t.mirrorEnableS} mask={t.maskS} shift={t.shiftS}) t(clmp={t.clampEnableT} mirr={t.mirrorEnableT} mask={t.maskT} shift={t.shiftT})";

                    break;
                }

                case Fast3DEX2Opcode.G_SETPRIMCOLOR:
                {
                    float minLODLevel = bytes[2] / 0x100f;
                    float LODfrac     = bytes[3] / 0x100f;
                    byte  r           = bytes[4];
                    byte  g           = bytes[5];
                    byte  b           = bytes[6];
                    byte  a           = bytes[7];

                    rdpState.colorCombinerSettings.primR       = r;
                    rdpState.colorCombinerSettings.primG       = g;
                    rdpState.colorCombinerSettings.primB       = b;
                    rdpState.colorCombinerSettings.primA       = a;
                    rdpState.colorCombinerSettings.minLODLevel = minLODLevel;
                    rdpState.colorCombinerSettings.LODfrac     = LODfrac;

                    operationDesc  = "G_SETPRIMCOLOR   (Set color combiner primitive color + LOD)";
                    operationDesc += $": rgba({r}, {g}, {b}, {a}) minLOD={minLODLevel} LODfrac={LODfrac}";
                    break;
                }

                case Fast3DEX2Opcode.G_SETENVCOLOR:
                {
                    byte r = bytes[4];
                    byte g = bytes[5];
                    byte b = bytes[6];
                    byte a = bytes[7];

                    rdpState.colorCombinerSettings.envR = r;
                    rdpState.colorCombinerSettings.envG = g;
                    rdpState.colorCombinerSettings.envB = b;
                    rdpState.colorCombinerSettings.envA = a;

                    operationDesc  = "G_SETENVCOLOR    (Set color combiner environment color)";
                    operationDesc += $": rgba({r}, {g}, {b}, {a})";
                    break;
                }

                case Fast3DEX2Opcode.G_SETCOMBINE:
                    operationDesc = "G_SETCOMBINE     (Set color combiner algorithm)";
                    break;

                case Fast3DEX2Opcode.G_SETTIMG:
                {
                    ulong word = bytes.ReadUInt64(0);

                    ColorFormat format      = (ColorFormat)word.Bits(53, 3);
                    BitSize     bitSize     = (BitSize)word.Bits(51, 2);
                    uint        dramAddress = (uint)word.Bits(0, 25);

                    rdpState.nextDRAMAddrForLoad      = dramAddress;
                    rdpState.bitSizeOfNextDataForLoad = bitSize;

                    operationDesc  = "G_SETTIMG        (Set pointer to data to load + size of data)";
                    operationDesc += $": DRAM 0x{dramAddress:X8}; fmt={bitSize}-bit {format}";

                    break;
                }

                case Fast3DEX2Opcode.G_RDPLOADSYNC:
                    operationDesc = "G_RDPLOADSYNC    (Wait for texture load)";
                    break;

                case Fast3DEX2Opcode.G_RDPTILESYNC:
                    operationDesc = "G_RDPTILESYNC    (Wait for rendering + update tile descriptor attributes)";
                    break;

                case Fast3DEX2Opcode.G_ENDDL:
                    operationDesc = "G_ENDDL          (End display list)";
                    break;

                default:
                    throw new InvalidOperationException();
                }

                string bytesStr = String.Join(" ", bytes.Select(b => b.ToString("X2")));
                cmdsString.AppendLine(bytesStr + " | " + operationDesc);
            }

            return(rdpState);
        }
Exemple #5
0
        protected UInt64[] GenerateValuesAllInMask()
        {
            List <UInt64> keys = new List <ulong>();
            List <int>    bits = new List <int>();

            for (int i = 0; i < 64; ++i)
            {
                bits.Add(i);
            }



            Random rnd = new Random(1234567890);

            for (int set = 0; set < 16; ++set)
            {
                int[] bitInds = new int[4];
                for (int i = 0; i < 4; ++i)
                {
                    int num = rnd.Next(bits.Count);
                    bitInds[i] = bits[num];
                    bits.RemoveAt(num);
                }

                ulong   src       = rnd.Next() % 2 == 0 ? 0 : ulong.MaxValue;
                ulong[] setvalues = new ulong[16];
                for (int i = 0; i < 16; ++i)
                {
                    setvalues[i] = src;
                }


                for (ulong i = 0; i < 16; ++i)
                {
                    for (int j = 0; j < 4; ++j)
                    {
                        var bitInd   = bitInds[j];
                        var bitValue = i.Bit(j);
                        if (bitValue)
                        {
                            setvalues[i].SetBit(bitInd);
                        }
                        else
                        {
                            setvalues[i].UnsetBit(bitInd);
                        }
                    }
                }
                keys.AddRange(setvalues);
            }


            HashSet <ulong> resultKeys = new HashSet <ulong>();

            foreach (var k in keys)
            {
                if (!resultKeys.Contains(k))
                {
                    resultKeys.Add(k);
                }
            }
            while (resultKeys.Count < 256)
            {
                var k = rnd.NextUInt64();
                if (!resultKeys.Contains(k))
                {
                    resultKeys.Add(k);
                }
            }
            return(resultKeys.ToArray());
        }