<- 1  -   of 75 ->
^^
vv
List results:
Search options:
Use \ before commas in usernames
The DDS header is fairly straight forward, and the data is pretty easy to work with. Heck Parax and I both directly put the pixel buffers in the DDS texture and make up a header that matches the data.
Edit history:
Antidote: 2015-02-28 01:16:55 am
After all the crap that CodeWarrior has put us through I decided that it needs a new mascot:

What do you guys think?
Yeah, a broken image represents CodeWarrior perfectly.
lol, fixed.
Edit history:
Bearborg: 2015-03-01 01:19:46 am
Found something interesting in an MREA in Corruption; fully commented Lua code for those X-Ray keypads on the Pirate Homeworld. It's pretty long, but what was particularly interesting was this bit:

"If player is not in X-Ray visor, check if they pressed the current key value needed. If so, swap the key's value with another unpressed key's value."

If, by some amazing stroke of luck, you actually guessed the key sequence right, they change your inputs to incorrect ones. Even though the codes are generated randomly every time, and there's a 1/1,680 chance of any random sequence of inputs being correct.

Thanks, Retro.
Edit history:
Aruki: 2015-03-01 01:06:16 am
Retro hates speedrunners confirmed.

edit: I went and found the script bearborg was talking about. Here is the whole thing in case anyone's interested. According to Antidote this actually comes up a lot in MP3.

Quote:
        -- this code is run when the script is loaded since its outside all functions
        -- allows you to initialize things
     
        DEBUG_LUA_PIRATEXRAYPAD = FALSE                                   
        MAX_KEYS_IN_SEQUENCE = 4
        NUMBER_OF_KEYS = 8

        -- gKeyCodeSequence has an extra buffer 0 to be read as the final Enter (5th entry) needed in a code of 4 keys
        gKeyCodeSequence = { 0, 0, 0, 0, 0 }
        -- gKeysPressedList tracks which keys have been pressed on the pad.  1 = UNPRESSED, 0 = PRESSED (its set up this way so RandomWeightedChance can be used on the list)
        gKeysPressedList = { 1, 1, 1, 1, 1, 1, 1, 1 }
        -- gKeyValuesList tracks the mapping of displayed keys to the actual key it represents. Starts out unscrambled.
        gKeyValuesList = { 1, 2, 3, 4, 5, 6, 7, 8 }

        -- which entry of the code sequence we're at
        gCurrentCodeIndex = 1
        -- true until an incorrect key is pressed
        gIsEnteredCodeCorrect = 1

        -- variable used to track what key the player pressed, so we can go outside the LUA object, test for X-Ray with PlayerProxy, then come back in from the Proxy
        -- and check the actual button pressed
        gCurrentKeyPressed = 0

        -- list of connected text fields for displaying pressed keys
        gConnectedTextFieldObjIDs = { 0, 0, 0, 0 }

        -- list of connected Key MultiModelActors, for swithcing out the look of keys during randomization
        gConnectedKeyActorObjIDs = { 0, 0, 0, 0, 0, 0, 0, 0 }

        -- list of connected text fields for displaying code needed
        gConnectedCodeFieldObjIDs = { 0, 0, 0, 0 }

        -- Message functions
        -- Message functions will be called with the matching name as the message with
        -- "On" prefixed.  As below, this object takes Start, Stop, Reset and ResetAndStart
        -- messages.
        --
        -- A message function parameter is a table containing three elements:
        --  msg.state is a string indicating the source state that sent the message
        --  msg.sender is a string identifer for the object that sent the message
        --  msg.originator is a string identify for the object that originator this
        --      chain of messages


-- ********************************************* DEBUG FUNCTIONS *********************************************************
        function printKeysPressed()
          if (DEBUG_LUA_PIRATEXRAYPAD) then
            Print("KeysPressed : 1 2 3 4 5 6 7 8 \n")
            Print("KeysPressed :")
            for i = 1, NUMBER_OF_KEYS, 1 do
              Print(" " .. gKeysPressedList[i] .."")     
            end
            Print("\n")
          end
        end

        function printKeyValues()
          if (DEBUG_LUA_PIRATEXRAYPAD) then
            Print("KeyValues : 1 2 3 4 5 6 7 8 \n")
            Print("KeyValues :")
            for i = 1, NUMBER_OF_KEYS, 1 do
              Print(" " .. gKeyValuesList[i] .."")     
            end
            Print("\n")
          end
        end
       
        function printDebugInfo()
          printKeysPressed()
          printKeyValues()
        end

-- ********************************************* MATH FUNCTIONS *********************************************************

        function round(num, idp)
          return tonumber(string.format("%." .. (idp or 0) .. "f", num))
        end


-- ********************************************* FUNCTIONS FOR HANDLING MULTIACTOROBJECT SUPPORT *********************************************************

        function convertTextFieldToConnectionName(textFieldToConvert)
          -- This function gives us the InternalState that we'll look for on connected MultiModelActors to figure out which object corresponds to which
          -- text field, in order from left to right.

          if(textFieldToConvert == 1) then
            return ("InternalState11")
          elseif(textFieldToConvert == 2) then
            return ("InternalState12")
          elseif(textFieldToConvert == 3) then
            return ("InternalState13")
          elseif(textFieldToConvert == 4) then
            return ("InternalState14")
          end
        end

        function convertKeyToMessage(keyToConvert)
          -- This function converts a Key (1-8) to the corresponding InternalMessage that must be sent to a connected MultiModelActor to tell it to display the
          -- CMDL corresponding to that number.  9 Is used for the Pressed State on the actual keys
          -- This is used both for the Display Area as well as the 8 keys you can press, when they get randomized.
     
          if(keyToConvert == 1) then
            return("InternalMessage3")
          elseif(keyToConvert == 2) then
            return("InternalMessage4")
          elseif(keyToConvert == 3) then
            return("InternalMessage5")
          elseif(keyToConvert == 4) then
            return("InternalMessage6")
          elseif(keyToConvert == 5) then
            return("InternalMessage7")
          elseif(keyToConvert == 6) then
            return("InternalMessage8")
          elseif(keyToConvert == 7) then
            return("InternalMessage9")
          elseif(keyToConvert == 8) then
            return("InternalMessage10")
          elseif(keyToConvert == 9) then
            return("InternalMessage11")
          else
            -- must be "enter/nothing"
            return("InternalMessage2")
          end
        end

        function getConnectedMultiModelActors(msg)
          -- This function populates our three ObjID lists (gConnectedTextFieldObjIDs, gConnectedCodeFieldObjIDs, and gConnectedKeyActorObjIDs)  with the connected
          -- MultiObjectActors that correspond to their members. Whenever we need to update a display field, a code field, or a key actor with a specific button image,
          -- we now have simple lists to index for the ObjID to send the appropriate message to
       
          if(DEBUG_LUA_PIRATEXRAYPAD) then           
            Print("Checking connections for Objects...\n")
          end

          local connections = GetObjectConnectionList()
          for i,connection in ipairs( connections ) do
            if(DEBUG_LUA_PIRATEXRAYPAD) then
              Print(" Connection[" .. connection.state .. "] --> [" .. connection.message .. "]\n" )
            end
            for i2,connectedObjID in ipairs( connection.objectids ) do
              if(DEBUG_LUA_PIRATEXRAYPAD) then
                Print("  ConnectedID :" .. connectedObjID .. "\n")
              end
              if(connection.state == "InternalState3") then        -- "ConnectKey1"
                gConnectedKeyActorObjIDs[1] = connectedObjID
              elseif(connection.state == "InternalState4") then    -- "ConnectKey2"
                gConnectedKeyActorObjIDs[2] = connectedObjID
              elseif(connection.state == "InternalState5") then    -- "ConnectKey3"
                gConnectedKeyActorObjIDs[3] = connectedObjID
              elseif(connection.state == "InternalState6") then    -- "ConnectKey4"
                gConnectedKeyActorObjIDs[4] = connectedObjID
              elseif(connection.state == "InternalState7") then    -- "ConnectKey5"
                gConnectedKeyActorObjIDs[5] = connectedObjID
              elseif(connection.state == "InternalState8") then    -- "ConnectKey6"
                gConnectedKeyActorObjIDs[6] = connectedObjID
              elseif(connection.state == "InternalState9") then    -- "ConnectKey7"
                gConnectedKeyActorObjIDs[7] = connectedObjID
              elseif(connection.state == "InternalState10") then    -- "ConnectKey8"
                gConnectedKeyActorObjIDs[8] = connectedObjID

              elseif(connection.state == "InternalState11") then    -- "ConnectTextField1"
                gConnectedTextFieldObjIDs[1] = connectedObjID
              elseif(connection.state == "InternalState12") then    -- "ConnectTextField2"
                gConnectedTextFieldObjIDs[2] = connectedObjID
              elseif(connection.state == "InternalState13") then    -- "ConnectTextField3"
                gConnectedTextFieldObjIDs[3] = connectedObjID
              elseif(connection.state == "InternalState14") then    -- "ConnectTextField4"
                gConnectedTextFieldObjIDs[4] = connectedObjID
              elseif(connection.state == "InternalState15") then    -- "ConnectCodeField1"
                gConnectedCodeFieldObjIDs[1] = connectedObjID 
              elseif(connection.state == "InternalState16") then    -- "ConnectCodeField2"
                gConnectedCodeFieldObjIDs[2] = connectedObjID 
              elseif(connection.state == "InternalState17") then    -- "ConnectCodeField3"
                gConnectedCodeFieldObjIDs[3] = connectedObjID 
              elseif(connection.state == "InternalState18") then    -- "ConnectCodeField4"
                gConnectedCodeFieldObjIDs[4] = connectedObjID           
              end
            end
          end   
        end

        function displayKeyPressed(keyPressed)
          -- This function receives a keyPressed (1-9, since this doesn't get sent by Enter), and converts it to a message string (messageToSend)
          -- The message string (messageToSend) is one of 10 messages that a MultiModeActor can receive.  We've connected a MultiModeActor for each
          -- Text Field corresponding to an index in the sequence. 
          -- The message string is sent to the Object ID of the corresponding Text Field for the current key index we're on.
          -- i.e. "We pressed the number 2 for our 3rd number.  Convert 2 into "InternalMessage4", the message that will switch our Text Field MultiModelActor to the
          --    "2" image.  We then look through our connected objects list and find the ObjID for the 3rd display TextField. Send that ObjID the "InternalMessage4"
          --      message so it will switch its image to the number 2.

          local messageToSend = convertKeyToMessage(keyPressed)
          local receiverObjID = gConnectedTextFieldObjIDs[gCurrentCodeIndex]

          if(receiverObjID == 0) then
            if(DEBUG_LUA_PIRATEXRAYPAD) then
              Print ("WARNING! No connected actor for TextField" .. gCurrentCodeIndex .."\n")
            end
            return
          end

          if(DEBUG_LUA_PIRATEXRAYPAD) then
            Print ("Sending message ".. messageToSend .." to receiverObjID " .. receiverObjID .." \n")
          end
          SendEventMessage("Activate", messageToSend, receiverObjID)
        end

        function setKeyActorModels(includePressedKeys)
          if(DEBUG_LUA_PIRATEXRAYPAD) then
            Print ("setKeyActorModels! includePressedKeys : " .. includePressedKeys .." \n")
          end
          -- This function runs through the gKeyValuesList to get the current value of a key (what it's been randomized to) and then sends the appropriate message to
          -- the associated KeyActor, to force the DisplayModel for that value.
         
          for i = 1, NUMBER_OF_KEYS, 1 do
            -- if we've decided not to include pressed keys, then check to see if the current key we're looking at is pressed, and return out if true.
            if((includePressedKeys == 0) and (gKeysPressedList[i] == 0)) then
              if(DEBUG_LUA_PIRATEXRAYPAD) then
                Print ("gKeysPressedList[" .. i .. "] == 0 and includePressedKeys was 0. Skipping setActorModel for this key. \n")
              end
            else
              local receiverObjID = gConnectedKeyActorObjIDs[i]     
              if(receiverObjID == 0) then
                if (DEBUG_LUA_PIRATEXRAYPAD) then
                  Print ("WARNING! No connected actor for KeyActor" .. i .."\n")
                end
                return
              end

              local keyToDisplay = gKeyValuesList[i]
              local messageToSend = convertKeyToMessage(keyToDisplay)
              if (DEBUG_LUA_PIRATEXRAYPAD) then
                Print ("key ".. i .." | ToDisplay ".. keyToDisplay .." | Sending message ".. messageToSend .." to receiverObjID " .. receiverObjID .." \n")
              end
            SendEventMessage("Activate", messageToSend, receiverObjID)
            end
          end
        end

        function setCodeDisplayModels()
          -- this function sets up the DisplayModels for each CodeDisplay multimodel actor - effectively resetting the display to the current code chosen
          for i = 1, MAX_KEYS_IN_SEQUENCE, 1 do
            local receiverObjID = gConnectedCodeFieldObjIDs[i]
            if(receiverObjID == 0) then
              if (DEBUG_LUA_PIRATEXRAYPAD) then
                  Print ("WARNING! No connected actor for CodeDisplay" .. i .."\n")
              end
              return
            end
            local keyToDisplay = gKeyCodeSequence[i]
            local messageToSend = convertKeyToMessage(keyToDisplay)
            SendEventMessage("Activate", messageToSend, receiverObjID)
          end
        end

  -- ********************************************* RANDOMIZING KEYS *********************************************************


        function randomizeKeyValues()
          if(DEBUG_LUA_PIRATEXRAYPAD) then
            Print ("Randomizing Keys! \n")
          end
          printDebugInfo()
          -- This function randomizes the keys by remapping the value for each key.  I.e. you may press key 1, but it's acting like it's key 6

          local chosenKey
         
          for i = 1, NUMBER_OF_KEYS-1, 1 do
            -- make sure we're not trying to remap a key that's already been pressed and locked
            -- Print ("Remapping Key " .. i .." : ")
            if(gKeysPressedList[i] == 1) then         
               
                -- return a random index from the list of available keys that haven't been pressed (pressed keys are set to 0, so they can't be rolled)
                -- Print ("Key Unpressed, choosing random remap \n")
                chosenKey = RandomRange(1, NUMBER_OF_KEYS)
                chosenKey = round(chosenKey, 0)
               
                local needKeyReplacement = 1             
                while needKeyReplacement do     
                  -- Print("trying chosenKey ["..chosenKey.."]\n")
                  if(gKeysPressedList[chosenKey] == 1) then
                    -- Print("gKeysPressedList["..chosenKey.."] is available, swapping with keyValue ["..i.."]\n")
                    break
                  else
                    chosenKey = chosenKey + 1
                    if(chosenKey > NUMBER_OF_KEYS) then
                      chosenKey = 1
                    end
                  end
                end

                -- swap the current key's value with the chosen key's value
                if(DEBUG_LUA_PIRATEXRAYPAD) then
                  Print ("Remapping : Key["..i.."] Value["..gKeyValuesList[i].."] to Value["..gKeyValuesList[chosenKey].."]\n")
                  Print ("Swapping  : Key["..chosenKey.."] Value["..gKeyValuesList[chosenKey].."] to Value["..gKeyValuesList[i].."]\n")
                end
                local valueToSwap = gKeyValuesList[i]
                gKeyValuesList[i] = gKeyValuesList[chosenKey]
                gKeyValuesList[chosenKey] = valueToSwap
               
            else
              if(DEBUG_LUA_PIRATEXRAYPAD) then
                Print ("gKeysPressedList["..i.."] is pressed, skipping! \n")
              end
            end
          end

          printDebugInfo()
          -- once we've randomized, set the key actors' models to match their randomized values.  Don't include pressed keys
          setKeyActorModels(0)
        end

-- ********************************************* KEY CODE CREATION / SETUP *********************************************************
           
        function generateRandomKeyCode()
          -- This function (shock!) generates a random Key Code that the player must enter into the key code interaction. 
         
          local i
       
          local availableKeys = { 1, 1, 1, 1, 1, 1, 1, 1 }

          if ( DEBUG_LUA_PIRATEXRAYPAD ) then
            Print (" Generating Key : ")
          end

          for i = 1, MAX_KEYS_IN_SEQUENCE, 1 do
            local chosenKey = RandomWeightedChoice(availableKeys)
            gKeyCodeSequence[i] = chosenKey
            availableKeys[chosenKey] = 0

            if ( DEBUG_LUA_PIRATEXRAYPAD ) then
              Print (" " .. chosenKey .. " ")
            end
          end

          if ( DEBUG_LUA_PIRATEXRAYPAD ) then
              Print (" \n")
          end

          -- set the code display up with the correct visuals for our new code
          setCodeDisplayModels()
        end

        function clearKeyCode()
          if ( DEBUG_LUA_PIRATEXRAYPAD ) then
              Print (" Clearing Key Code! \n")
          end

          gIsEnteredCodeCorrect = 1
          gCurrentCodeIndex = 1

          for i = 1, NUMBER_OF_KEYS, 1 do
            gKeysPressedList[i] = 1
          end
        end


-- ********************************************* CHECKING INPUT VS. CODE *********************************************************

        function checkKeyCodeCompletion()
          if ( gIsEnteredCodeCorrect > 0 ) then
            SendEvent( "KeyCodeSolved" )
          else
            SendEvent( "KeyCodeFailed" )
          end
        end     
--[[ **********OLD KEY CODE CHECK***********
        function checkKeyPressedAgainstCode(keyPressed)
          -- map the key pressed to its current value in the gKeyValuesList. This is the scrambled list representing what each key maps to at that moment
          local remappedKeyPressed = gKeyValuesList[keyPressed]

          -- get the current key needed in the sequence
          local currentKeyNeeded = gKeyCodeSequence[gCurrentCodeIndex]

          displayKeyPressed(remappedKeyPressed)
         
          if ( DEBUG_LUA_PIRATEXRAYPAD ) then
            Print (" CurrentKeyNeeded :  " .. currentKeyNeeded .. " / User Pressed : " .. remappedKeyPressed .. " \n")
          end

         
          if( currentKeyNeeded ~= remappedKeyPressed ) then
            gIsEnteredCodeCorrect = 0
            SendEvent( "InvalidKeyPressed" )
          end

          -- set the key pressed to the "pressed image"
          local receiverObjID = gConnectedKeyActorObjIDs[keyPressed]
          local messageToSend = convertKeyToMessage(9)
          SendEventMessage("Activate", messageToSend, receiverObjID)

          -- set the passed key as being pressed, then randomize the values of all keys
          gKeysPressedList[keyPressed] = 0

          -- increment to the next index in the key code sequence
          gCurrentCodeIndex = gCurrentCodeIndex+1
          -- check if we just entered the last number needed
          if(gCurrentCodeIndex > MAX_KEYS_IN_SEQUENCE) then
            checkKeyCodeCompletion()
          else
            SendEvent("ReadyForScramble")
          end
        end     
]]--
-- ********** NEW KEY CODE CHECK *********
        function checkKeyPressedAgainstCode(isInXRay)

          -- get the current key needed in the sequence
          local currentKeyNeeded = gKeyCodeSequence[gCurrentCodeIndex]
         
          local keyPressed = gCurrentKeyPressed

          -- set the passed key as being pressed
          gKeysPressedList[keyPressed] = 0

          -- map the key pressed to its current value in the gKeyValuesList. This is the scrambled list representing what each key maps to at that moment
          local keyPressedValue = gKeyValuesList[keyPressed]
         
          if ( DEBUG_LUA_PIRATEXRAYPAD ) then
            Print (" CurrentKeyNeeded :  " .. currentKeyNeeded .. " / User Pressed : " .. keyPressedValue .. " \n")
          end

          -- If player is not in X-Ray visor, check if they pressed the current key value needed. If so, swap the key's value with another unpressed key's value
          if(isInXRay == 0) then
            if (keyPressedValue == currentKeyNeeded) then
              if ( DEBUG_LUA_PIRATEXRAYPAD ) then
                Print("Not In X-Ray and pressed correct key. Swapping with another key value! \n")
              end
             
              local chosenKey = RandomRange(1, NUMBER_OF_KEYS)
              chosenKey = round(chosenKey, 0)

              local needKeyReplacement = 1             
              while needKeyReplacement do     
                -- Print("trying chosenKey ["..chosenKey.."]\n")
                if(gKeysPressedList[chosenKey] == 1) then
                  -- Swap the newly chosen value to our keyPressedValue, then swap the two values in the ValuesList
                  -- Print("gKeysPressedList["..chosenKey.."] is available, swapping its value with currentKeyPressed Value ["..valueToSwap.."] \n")
                  keyPressedValue = gKeyValuesList[chosenKey]
                  gKeyValuesList[chosenKey] = gKeyValuesList[keyPressed]
                  gKeyValuesList[keyPressed] = keyPressedValue
                  break
                else
                  chosenKey = chosenKey + 1
                  if(chosenKey > NUMBER_OF_KEYS) then
                    chosenKey = 1
                  end
                end
              end
            else
              if( DEBUG_LUA_PIRATEXRAYPAD ) then
                Print("Not In X-Ray but did not press correct value! Let it drop through!\n")
              end
            end
          end

          -- show the value pressed on the appropariate Display TextField
          displayKeyPressed(keyPressedValue)             

          -- if the player didn't press the key with the value needed, send the InvalidKeyPressed Event and mark that they've put in a wrong value
          if( currentKeyNeeded ~= keyPressedValue ) then
            gIsEnteredCodeCorrect = 0
            SendEvent( "InvalidKeyPressed" )
          end

          -- set the key pressed to the "pressed image"
          local receiverObjID = gConnectedKeyActorObjIDs[keyPressed]
          local messageToSend = convertKeyToMessage(9)
          SendEventMessage("Activate", messageToSend, receiverObjID)

       
          -- increment to the next index in the key code sequence
          gCurrentCodeIndex = gCurrentCodeIndex+1
          -- check if we just entered the last number needed
          if(gCurrentCodeIndex > MAX_KEYS_IN_SEQUENCE) then
            checkKeyCodeCompletion()
          else
            SendEvent("ReadyForScramble")
          end
        end

-- ********************************************* X-RAY HANDLING **********************************************************
        function OnPlayerInXRay(msg)
          checkKeyPressedAgainstCode(1)
        end

        function OnPlayerNotInXRay(msg)
          checkKeyPressedAgainstCode(0)
        end

-- ********************************************* MESSAGE AND LOAD EVENTS *********************************************************

        function OnKeyPressed1(msg)
          gCurrentKeyPressed = 1
          SendEvent("TestForXRay")
        end

        function OnKeyPressed2(msg)
          gCurrentKeyPressed = 2
          SendEvent("TestForXRay")
        end

        function OnKeyPressed3(msg)
          gCurrentKeyPressed = 3
          SendEvent("TestForXRay")
        end                         

        function OnKeyPressed4(msg)
          gCurrentKeyPressed = 4
          SendEvent("TestForXRay")
        end

        function OnKeyPressed5(msg)
          gCurrentKeyPressed = 5
          SendEvent("TestForXRay")
        end

        function OnKeyPressed6(msg)
          gCurrentKeyPressed = 6
          SendEvent("TestForXRay")
        end                         

        function OnKeyPressed7(msg)
          gCurrentKeyPressed = 7
          SendEvent("TestForXRay")
        end

        function OnKeyPressed8(msg)
          gCurrentKeyPressed = 8
          SendEvent("TestForXRay")
        end

        function OnKeyCodeCancelled(msg)
          clearKeyCode()
        end

        function OnGenerateKeyCode(msg)
          clearKeyCode()         
          generateRandomKeyCode()
          randomizeKeyValues()
        end

        function OnRandomizeKeys(msg)
          randomizeKeyValues()
        end

        function OnPrintDebugInfo(msg)
          printDebugInfo()
        end

        function OnAreaLoaded(msg)
          getConnectedMultiModelActors(msg)
        end
Yeah, Metroid Prime 3 uses LUA for a lot of things, doors, puzzles ^ case in point, drop rates, debugging, etc.
To be fair to Retro, I don't think any speedrunners would actually enjoy having to deal with a 1/1680 chance four or so times throughout the run in order to skip X-Ray.
Would've been neat for TAS runs, though.
I decided to try adding the submesh header for DKCR to my MREA code, w00t :D

First try too!
yes yes yes yes, that looks sexy. MREA is compressed in blocks right? how did you know what you need to save and what you need to overwrite?
Edit history:
Aruki: 2015-03-02 01:32:13 pm
Aruki: 2015-03-02 01:17:19 pm
Aruki: 2015-03-02 01:12:29 pm
so I'm giving up on MP3 materials for now, since I can't seem to find the data I'm interested in and it's started to feel like I'm wasting my time on it. If anyone else wants to look at it to try to figure it out, here's some info:

- Get the symbols from the .sel file loaded. It's very very incomplete but there's quite a few important functions in there, namely a bunch of GX/CGX/CGraphics functions.
- Here's some important functions (all of these are from the original NTSC retail release):
* 802E1AD4 - SwarmRenderHelpers::CSwarmDisplayList::SetMaterialCurrent(const(CModelFlags const &)) (closest function that has symbols)
* 8037C648 - CMDL/MREA material section parse function
* 8037C36C - Material parse function
* 8037C188 - PASS parse function
* 8037C0F8 - CLR parse function
* 8037C048 - INT parse function
* There's a class that seems to manage textures and tex coords. I've named it CSomeClass.
* 803506B0 - CSomeClass texture loading function
* 803507FC - CSomeClass tex map ID getter (two int params, each an array index)
* 80350904 - CSomeClass tex coord ID getter (two int params, each an array index)
* 8034F1AC - this is a very important material-related function but I'm not sure what it's doing. It seems to have something to do with both setting materials and drawing geometry. Best bet is to look here.
* 80345AEC - UV anim setup; there are separate functions for all 9 modes that appear in order immediately before this one (MP3 has a new UV anim mode)

I mean the way it's set up you can probably guess and get a pretty close approximation, or just don't do TEV emulation at all and set it up more like you would for a normal material/shader (I'm guessing that's what MetroidMenace/SarahHarp did), but I'd really like to know exactly how the game does it and find the exact settings it's using...
Edit history:
Antidote: 2015-03-02 02:25:15 pm
Antidote: 2015-03-02 02:24:29 pm
Quote from Jesse:
yes yes yes yes, that looks sexy. MREA is compressed in blocks right? how did you know what you need to save and what you need to overwrite?


Yes, the MREA is compressed into blocks (LZO for MP2/3 and zlib for DKCR), however I'm not overwriting/saving anything I'm just loading the vertices, normals, texcoords, lightmaps, and mesh/submesh definitions. I'm not really sure what you mean.
Edit history:
Aruki: 2015-03-02 02:36:49 pm
Aruki: 2015-03-02 02:34:43 pm
Jesse, get the newest version of PakTool here that I released a week and a half ago. It's capable of decompressing MREAs at unpack time and recompressing them at repack time, so it makes it much easier to examine and edit them. It's completely compatible with DKCR. (you can also leave them decompressed and use the decompressed version in the game)
Quote from Parax:
(you can also leave them decompressed and use the decompressed version in the game)

As long as you're playing from the files on Dolphin, at least. Otherwise you'll likely have issues with the game's size and load times.
Yeah, with Dolphin you'll also want to make sure you don't change the pak sizes at runtime (either by generating new paks while the game is running, or by loading a savestate that you made with different paks). That'll make the game crash. That isn't a problem if you don't change the size of any files and leave compression disabled (different data compresses to different sizes), but like Miles said that's only really a good idea if you use Dolphin.
Uh, that's not entirely accurate, decompress Metroid1.pak from MP3 to see why.
Yes, it's accurate. I was personally testing materials using a decompressed Metroid1.pak in MP3 recently.
When I tried it before it crashed, but that was a while back, I'll try again then.
Thanks for saying about that embedded compression, otherwise I would have never noticed. Thus the inside of a MREA looks pretty much like a giant cmdl with extra information.

btw I will try to generate a cmdl from a simple .obj soon. I will have to start simple with only vertex shorts and triangle attributes... Lets just say that the theory is present.
Edit history:
Antidote: 2015-03-02 05:00:22 pm
Antidote: 2015-03-02 04:57:33 pm
Well, MREA is more comparable to a PAK in that sense, it contains a group of models that make up the mesh, and a global material set those models share. The models themselves contain everything they need to build a CMDL if you were so inclined (in fact that's basically what RetroView is doing, it has a CModelData class which CModelFile inherits, and CAreaFile has a vector of). After that data is the area's BSP tree, script layers, collision octree, lights, and path (MP2 and beyond have a few other things, e.g REL/RSO references).

MP3 and DKCR troll us by moving the model headers away from the actual model data, it's now contained in a WOBJ section (usually two of them, sometimes just one). There is something to watch out for: No matter how many WOBJ sections there are, they ALWAYS point to section 0, which is the material set.

EDIT:
Oh, I nearly forgot the PVS (Probable Visibility Set) tree, which has the magic VISI. In MP3/DKCR it's held in the PVS! section.
MREA is basically the file that contains all the data for the level. So yeah, it includes terrain geometry, but it also includes a ton of other stuff like Antidote mentioned.
Does DKCR (and DKTF) contain any LUA code?  The Corruption prototype has an earlier version of the drop rates codes but nothing else it seems.  Setting DEBUG_LUA_GENERATOR=true in the prototype might actually activate the Print() statements there.

Was anyone aware that the Echoes demo had more rooms to it?
Unused Rooms Part 1
Unused Rooms Part 2
An all items AR code?  Start at a save station?  How could this work be recreated?
Are there even more rooms than shown here within the pak files?

There also is a boostball attack.  MilesSMB is mentioned but I cannot find any mention on m2k2.
Unused Boostball Attack

And the last video in the set (all by abahbob - most known for Wind Waker TAS), proof that screw attack was built on top of morphball code.
Uhhhhhhh, what?
Edit history:
Aruki: 2015-03-02 09:19:48 pm
Aruki: 2015-03-02 09:15:54 pm
I think I heard from Miles (or possibly someone else) that the reason those rooms are there is because they're used by a different demo. AFAIK there's no other extra rooms but apparently there's some unused layers in the rooms that are there (Metroid7.pak, Temple Grounds, has some pirates in it). Also there's shitloads of unused scans in the demo. Some of them are pretty interesting; there's one talking about how Dark Samus has the Wave/Ice/Plasma Beams for instance.

As far as screw attack being based on morph ball, yeah, I think that's pretty well established by now lol
Hey, looks like that Wii U loader for IDA was released! https://gbatemp.net/threads/ida-pro-wii-u-loader.382433/

Just tested it and it's successfully loaded all the symbols from Tropical Freeze straight from the RPX; no ELF conversion needed. Sweet. Unfortunately IDA doesn't seem to be able to demangle most of the names, but this is still pretty sweet!