QJ.NET | Videos | Forums | iPhone | MMORPG | Nintendo DS | Wii | PlayStation 3 | PSP | Xbox 360 | PC | Downloads | Contact Us
Forums | Gaming News | Videos | Downloads | Today's Posts | Mark Forums Read | Chat | FAQ | Members List | Contact

QJ.net Game Discussion - PSP, Xbox, Wii, PS3, PSP Homebrew, and PSP Guides

Go Back   QJ.net Game Discussion - PSP, Xbox, Wii, PS3, PSP Homebrew, and PSP Guides > Developers Corner > PSP Development, Hacks, and Homebrew > PSP Development Forum
The above video goes away if you are a member and logged in, so log in now!

SFO File Organization

This is a discussion on SFO File Organization within the PSP Development Forum forums, part of the PSP Development, Hacks, and Homebrew category; OK guys, so I'm trying to get my SFO editor working -- only to find out that using the official ...

Reply
 
LinkBack Thread Tools
Old 10-07-2009, 03:13 PM   #1
 
 
Join Date: Apr 2009
Real First Name: Morgan
Location: Around black mesa.
Just Played: SMB
Posts: 83
Trader Feedback: 0
Default SFO File Organization

OK guys, so I'm trying to get my SFO editor working -- only to find out that using the official "System File Viewer" it works *fine* but under the actual PSP it comes up as bad. WTF? As well,

Code:
EBOOTR.SFO
Offset(h) 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F

00000000  00 50 53 46 01 01 00 00 54 00 00 00 74 00 00 00  .PSF....T...t...
00000010  04 00 00 00 00 00 04 04 04 00 00 00 04 00 00 00  ................
00000020  00 00 00 00 09 00 04 02 03 00 00 00 04 00 00 00  ................
00000030  04 00 00 00 12 00 04 04 04 00 00 00 04 00 00 00  ................
00000040  08 00 00 00 19 00 04 02 0B 00 00 00 0C 00 00 00  ................
00000050  0C 00 00 00 42 4F 4F 54 41 42 4C 45 00 43 41 54  ....BOOTABLE.CAT
00000060  45 47 4F 52 59 00 52 45 47 49 4F 4E 00 54 49 54  EGORY.REGION.TIT
00000070  4C 45 00 00 01 00 00 00 4D 47 00 00 00 80 00 00  LE......MG...€..
00000080  4D 79 20 47 61 6D 65 20 3A 29 00 00              My Game :)..

PBP_UNPACKER.SFO
Offset(h) 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F

00000000  00 50 53 46 01 01 00 00 54 00 00 00 74 00 00 00  .PSF....T...t...
00000010  04 00 00 00 00 00 04 04 04 00 00 00 04 00 00 00  ................
00000020  00 00 00 00 09 00 04 02 03 00 00 00 04 00 00 00  ................
00000030  04 00 00 00 12 00 04 04 04 00 00 00 04 00 00 00  ................
00000040  08 00 00 00 19 00 04 02 0B 00 00 00 0B 00 00 00  ................
00000050  0C 00 00 00 42 4F 4F 54 41 42 4C 45 00 43 41 54  ....BOOTABLE.CAT
00000060  45 47 4F 52 59 00 52 45 47 49 4F 4E 00 54 49 54  EGORY.REGION.TIT
00000070  4C 45 00 00 01 00 00 00 4D 47 00 00 00 80 00 00  LE......MG...€..
00000080  4D 79 20 47 61 6D 65 20 3A 29 00 00              My Game :)..
the *only* difference is the padding involved (offset 0x4C), FWIK.

Spoiler for code to get SFO bytes:

Code:
   public byte[] FormatData()
        {


            System.IO.MemoryStream keystream = new System.IO.MemoryStream();
            System.IO.MemoryStream datastream = new System.IO.MemoryStream();
            System.IO.MemoryStream tablestream = new System.IO.MemoryStream();
            int idx_key = 0;
            int idx_val = 0;
            foreach (var item in Dict) // Dict is a SortedDictionary.
            {
                // things we need to know.
                byte[] key = System.Text.Encoding.UTF8.GetBytes(item.Key);
                byte[] dwrite = item.Value.data;
                int padded_size = (int)RoundUpToMult((UInt32)dwrite.Length, (uint)4);

                if (item.Value.type == SFOEntryType.txt)
                {
                    // check if there's an appropriate NULL byte there.
                    if (Array.IndexOf(dwrite, 0x00) < 0)
                    {
                        // there needs to be a NULL there :)
                        dwrite = System.Text.Encoding.UTF8.GetBytes(item.Value.ToString() + '\0');
                        padded_size = (int)RoundUpToMult((UInt32)dwrite.Length, (uint)4);
                    }
                }


                // write our entry into the table.
                tablestream.Write(BitConverter.GetBytes((UInt16)idx_key), 0, 2); // offset of key name into the key table.
                tablestream.WriteByte(4); //unknown '4' byte.
                tablestream.WriteByte((byte)item.Value.type);



                tablestream.Write(BitConverter.GetBytes((UInt32)dwrite.Length), 0, 4);
                tablestream.Write(BitConverter.GetBytes((UInt32)padded_size), 0, 4);
                tablestream.Write(BitConverter.GetBytes((UInt32)idx_val), 0, 4);


                keystream.Write(key, 0, key.Length);
                keystream.WriteByte(0x00); // write a null byte, to be safe.
                idx_key += key.Length + 1;


                Array.Resize(ref dwrite, padded_size);

                // here's where we're messing up. We need to write a COMPLETELY FRESH buffer.

                //datastream.Write(dwrite, 0, padded_size);

                byte[] bx = new byte[padded_size];
                bx.Initialize();
                Array.Copy(dwrite, bx, dwrite.Length);
                datastream.Write(bx, 0, padded_size);

                idx_val += padded_size;
            }

            //byte[] return_array = new byte[20+info_table.Length + keystream.Length + datastream.Length];

            byte[] HEADER = { 0x00, 0x50, 0x53, 0x46, 0x01, 0x01, 0x0, 0x00 };

            //Array.Copy(HEADER, return_array, 8);
            //Array.Copy(BitConverter.GetBytes((UInt32)(20 + tablestream.Length)), 0, return_array, 8, 4);
            //Array.Copy(BitConverter.GetBytes((UInt32)(20 + tablestream.Length + keystream.Length)), 0, return_array, 12, 4);
            //Array.Copy(BitConverter.GetBytes((UInt32)Dict.Count), 0, return_array, 16, 4);
            //Array.Copy(tablestream.ToArray(), 0, return_array, 20, tablestream.Length);
            //Array.Copy(keystream.ToArray(), 0, return_array, 20 + tablestream.Length, keystream.Length);
            //Array.Copy(datastream.ToArray(), 0, return_array, 20 + tablestream.Length + keystream.Length, datastream.Length);


            System.IO.MemoryStream ms = new System.IO.MemoryStream();
            ms.Write(HEADER, 0, 8);                 /* test to see if something is just broken... */
            ms.Write(BitConverter.GetBytes((UInt32)(/*20 + */ 20 + tablestream.Length)), 0, 4);
            ms.Write(BitConverter.GetBytes((UInt32)(/*20 + */ 20 + tablestream.Length + keystream.Length + 1)), 0, 4);
            ms.Write(BitConverter.GetBytes((UInt32)Dict.Count), 0, 4);
            ms.Write(tablestream.ToArray(), 0, (int)tablestream.Length);
            ms.Write(keystream.ToArray(), 0, (int)keystream.Length);
            ms.WriteByte(0x00);
            ms.Write(datastream.ToArray(), 0, (int)datastream.Length);

            return ms.ToArray();


Any ideas?
indrora is offline  
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
Reply With Quote
Old 10-08-2009, 04:43 AM   #2
QJ's Nice-guy :)
 
Skyline34's Avatar
 
My Mood: Cheerful
Join Date: Mar 2006
Real First Name: Randy Andy
Location: UK
Just Played: Nazi Zombies
Posts: 4,191
Trader Feedback: 0
Default

You're trying to use the Official Sony SFO Editor?

In that case we can't help because it's of illegal software.
__________________
On Facebook?

JOIN MY MAFIA!
Skyline34 is offline  
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
Reply With Quote
Old 10-08-2009, 09:54 PM   #3
 
 
Join Date: Apr 2009
Real First Name: Morgan
Location: Around black mesa.
Just Played: SMB
Posts: 83
Trader Feedback: 0
Default

Found my problem: the PSP doesnt like certain combos of language.
indrora is offline  
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
Reply With Quote
Reply

Tags
file , organization , sfo , wtf

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are Off
Pingbacks are Off
Refbacks are Off



All times are GMT -8. The time now is 02:28 PM.



Use of this Web site constitutes acceptance of the TERMS & CONDITIONS and PRIVACY POLICY
Copyright © 2009, QJ.NET. All Rights Reserved.
Contact Us