The Wiki With Hacking tools! SCHG:Sonic Generations Maybe someone will wright some tutorials or make some videos on how to use them. OLD Stuff Below now!!! -------------------------------------------------------------- NEW NEWS 7/26/2013 Added links to Animation tools and maxscripts for importing generations models into Max. NEW NEWS 5/1/2012 Kay Guys. Update: Sorry I haven't kept up with this post to make front page updates. ( been busy renovating my house) That hasn't slown down many of you from submitting stuff. I'm here to inform everybody that Generations has been cracked wider than Humpty Dumpty and custom levels are an ongoing event! (wish I could get you guys to PM me links to important recourses, tools and other miscellaneous things related to the topic. so that I can post them here on the front page for easy grabs) Also the Hacking guide. Sonic Community Hacking Guide: Sonic Generations Its a wiki page. -----------------------------------old news------------------------------------------ I'll start by sharing All of the Ripped Texture graphics recourses from the demo. (If its in the game than it will be found in these packs. Title screen, backgrounds, character skins, fonts, loading screen and level textures among other very rare finds. ( like new never before seen screen shots) DaGuAr from sonicreikai.com Assisted in setting me up with the ripping strategies. all credit goes to him for that. I just ripped and Batch converted them in photoshop. Lets see what everyone will bring to the thread, Any Recourses are welcome. Edit: Watch for lots of incoming shit for full game * * * CONVERTED FORMATS* * * -------------------------FULL GAME-------------------------------------- Download Concept Art Hinchy's fully-tagged Super High Quality V0 Music rip. FULL GAME SOUNDTRACK MP3 part 1 Credit to my main man TZ these are kind of low quality. --------------------------DEMOS----------------------------------------- 360 TEXTURE PACK .TGA version. (DEMO 2) Complete Voice Samples (All Lang) .MP3 @ 48khz 320kbps. (DEMO 2) Credit to DaGuAr Complete sound FX .MP3 @ 48khz 320kbps. (DEMO 2) Credit to DaGuAr Part of Soundtrack. (DEMO 2) Credit to Hinchy (note: Demo 1 and 2 together for full soundtrack) Full SOUNDTRACK (DEMO 1) MP3 are 48khz 320kbps Credit to DaGuAr ( Raw .aax and MP3) 360 TEXTURE PACK .TGA version. (DEMO 1) TEXTURE PACK .PNG version. (DEMO 1) * * * RAW FORMATS* * * -------------------------FULL GAME-------------------------------------- Raw .AXX Music files Ripped by evilhamwizard(Full game Release). (650MB) --------------------------DEMOS----------------------------------------- .DDS Textures, And Photoshop actions for converting to PNG with Transparencies (DEMO 2) SONIC GENERATIONS(FULL RAW PS3 Version (DEMO 2) Credit to Heran Bago SONIC GENERATIONS (FULL RAW 360 version) (DEMO 2) SONIC GENERATIONS (Complete RAW .model and .terrain format models) (DEMO 2) 360 MODELS PACK (Raw .model version. (DEMO 1) (Extracted Raw Music files in .axx format. (DEMO 1) (Raw .sfd version. (DEMO 1) (Generations Demo PS3 PKG. Don't bitch about piracy guys, it's a damn demo...) (DEMO 1) * * * HACKING TOOLS * * * Tools for converting the movie files from Generations. Tools for extracting data from the full Generations ISO Thanks TZ for the tools *ISO2god is for rebuilding the iso to get it ready for extracting. *Wx360 1.6 for extracting the files from iso *Quickbms to extract the cpk Open .DDS TEXTURE files with Photoshop 3 tools for extracting files from the Raw 360 demos 1 and 2 (The UTF Tab Suite by HCS64) Used to unpack the .CPK files ( in The Sound pack, the PS3.PKG , and upcoming 360 Rip) (.AAX, .ADX and .WAV converters) Import Model to Max Maxscript: 1:Copy past the code below to a new notepad. 2: change the extention to .MS 3: Drag and drop the maxscript to a max viewport. 4: Enjoy! Spoiler clearlistener() mdlScale = 1.0 if (heapSize < 20000000) then heapSize = 200000000 -- allow ~ 40 MB instead of just 7.5 MB. Prevents "Runtime Error: Out of scripter memory" struct weight_data ( boneids,weights ) struct VertexDeclarationEntry ( DataOffset, DataType, EntryType, SubId ) struct BoneDData ( BoneID, BoneNameOffset, BoneName, BoneParentID ) fn existFile fname = (getfiles fname).count != 0 fn PrintOffset Var = ( local Var = Var print ("This is the offset 0x" + (bit.intAsHex Var) as string) Var ) y = 180 PrintOffset y x = 200 print ("This is the number 0x" + (bit.intAsHex x) as string) fn floatSwap2 f = ( I = bit.floatAsInt f h = bit.intashex I while h.count < 8 do h = "0" + h s = (substring h 7 2) + (substring h 5 2) + (substring h 3 2) + (substring h 1 2) bit.intAsFloat (bit.hexasint s) ) fn ReadBEword fstream = ( return (bit.swapBytes (readshort fstream #unsigned) 1 2) ) fn ReadBEHalfFloat Fstream = ( local BH = readByte Fstream #unsigned local BL = readByte Fstream #unsigned local N = BH*256 + BL local S = floor((mod N 65536) / 32768) local Ef = floor((mod N 32768) / 1024) local M = mod N 1024 if (Ef==0)AND(M==0) then return ( (-1.0)^S * 0.0 ) if (Ef==0)AND(M!=0) then return ( (-1.0)^S * 2.0^-14 * (M / 2.0^10) ) if (Ef>0)AND(Ef<31) then return ( (-1.0)^S * 2.0^(Ef-15) * (1 + M/2.0^10) ) if (Ef==31)AND(M==0) then return ( (-1.0)^S * 1/0.0 ) if (Ef==31)AND(M!=0) then return 0 --hack-- should be #inf )--end fn ReadBEHalfFloat fn ReadBElong fstream = ( long = readlong fstream long = bit.swapBytes long 1 4 long = bit.swapBytes long 2 3 return long ) fn ImportTextureGenerations mm index texfilename filepath = ( matdata = fopen (filepath + texfilename + ".material") "rb" fseek matdata 0x04 #seek_set texcount = ReadBElong matdata fseek matdata 0x24 #seek_set --PrintOffset (ftell matdata) DataBegin = ReadBElong matdata fseek matdata (DataBegin + 0x18) #seek_set --PrintOffset (ftell matdata) DataBegin2 = ReadBElong matdata fseek matdata (DataBegin2 + 0x18) #seek_set --PrintOffset (ftell matdata) TexBegin = ReadBElong matdata fseek matdata (TexBegin + 0x18) #seek_set --PrintOffset (ftell matdata) --mat = standardMaterial() mat = mm.materialList[index] mat.name = texfilename mat.showinviewport = true mat.twosided = false --print("Material has " + (texcount as string) + " maps!") for I = 1 to texcount do ( ddsfile = readstring matdata ddsdata = readstring matdata --print("Map " + (I as string) + " is " + ddsdata + " map: " + (ddsfile) + ".dds") pos = ftell matdata pos = pos + 0x0C ex = mod pos 4 if(ex != 0) then ( pos = pos + (4 - ex) ) fseek matdata pos #seek_set --print ddsdata tm = Bitmaptexture filenamefilepath + ddsfile + ".dds") tm.alphasource = 2 case ddsdata of ( "diffuse": mat.diffuseMap = tm "displacement": ( mat.bumpMap = tm mat.bumpMapAmount = 40 ) "normal": ( mat.bumpMap = tm mat.bumpMapAmount = 40 ) "specular": mat.specularMap = tm "gloss": mat.specularMap = tm "reflection": mat.reflectionMap = tm default: ( ) ) ) fclose matdata --msh.material = mat ) fn ImportTexture mm index texfilename filepath = ( if(not existFile(filepath + texfilename + ".texset")) then ( ImportTextureGenerations mm index texfilename filepath return true ) texdesc = fopen (filepath + texfilename + ".texset") "rb" fseek texdesc 0x18 #seek_set texcount = ReadBElong texdesc textfiles = #() fseek texdesc (0x20 + texcount * 4) #seek_set for I = 1 to texcount do ( textfiles = readstring texdesc --print (textfiles) ) fclose texdesc mat = mm.materialList[index] mat.name = texfilename mat.showinviewport = true mat.twosided = false for I = 1 to texcount do ( mapdata = fopen (filepath + textfiles + ".texture") "rb" fseek mapdata 0x24 #seek_set ddsfile = readstring mapdata ddsdata = readstring mapdata fclose mapdata --print ddsdata tm = Bitmaptexture filenamefilepath + ddsfile + ".dds") tm.alphasource = 2 case ddsdata of ( "diffuse": mat.diffuseMap = tm "displacement": ( mat.bumpMap = tm mat.bumpMapAmount = 40 ) "normal": ( mat.bumpMap = tm mat.bumpMapAmount = 40 ) "specular": mat.specularMap = tm "gloss": mat.specularMap = tm "reflection": mat.reflectionMap = tm default: ( ) ) ) --msh.material = mat ) fn ImportTextureGenerationsMesh msh texfilename filepath = ( matdata = fopen (filepath + texfilename + ".material") "rb" fseek matdata 0x04 #seek_set texcount = ReadBElong matdata fseek matdata 0x24 #seek_set --PrintOffset (ftell matdata) DataBegin = ReadBElong matdata fseek matdata (DataBegin + 0x18) #seek_set --PrintOffset (ftell matdata) DataBegin2 = ReadBElong matdata fseek matdata (DataBegin2 + 0x18) #seek_set --PrintOffset (ftell matdata) TexBegin = ReadBElong matdata fseek matdata (TexBegin + 0x18) #seek_set --PrintOffset (ftell matdata) mat = standardMaterial() mat.showinviewport = true mat.twosided = false --print("Material has " + (texcount as string) + " maps!") for I = 1 to texcount do ( ddsfile = readstring matdata ddsdata = readstring matdata --print("Map " + (I as string) + " is " + ddsdata + " map: " + (ddsfile) + ".dds") pos = ftell matdata pos = pos + 0x0C ex = mod pos 4 if(ex != 0) then ( pos = pos + (4 - ex) ) fseek matdata pos #seek_set --print ddsdata tm = Bitmaptexture filenamefilepath + ddsfile + ".dds") tm.alphasource = 2 case ddsdata of ( "diffuse": mat.diffuseMap = tm "displacement": ( mat.bumpMap = tm mat.bumpMapAmount = 40 ) "normal": ( mat.bumpMap = tm mat.bumpMapAmount = 40 ) "specular": mat.specularMap = tm "gloss": mat.specularMap = tm "reflection": mat.reflectionMap = tm default: ( ) ) ) fclose matdata msh.material = mat ) fn ImportTextureMesh msh texfilename filepath = ( if(not existFile(filepath + texfilename + ".texset")) then ( ImportTextureGenerationsMesh msh texfilename filepath return true ) texdesc = fopen (filepath + texfilename + ".texset") "rb" fseek texdesc 0x18 #seek_set texcount = ReadBElong texdesc textfiles = #() fseek texdesc (0x20 + texcount * 4) #seek_set for I = 1 to texcount do ( textfiles = readstring texdesc --print (textfiles) ) fclose texdesc mat = StandardMaterial() mat.showinviewport = true mat.twosided = false for I = 1 to texcount do ( mapdata = fopen (filepath + textfiles + ".texture") "rb" fseek mapdata 0x24 #seek_set ddsfile = readstring mapdata ddsdata = readstring mapdata fclose mapdata --print ddsdata tm = Bitmaptexture filenamefilepath + ddsfile + ".dds") tm.alphasource = 2 case ddsdata of ( "diffuse": mat.diffuseMap = tm "displacement": ( mat.bumpMap = tm mat.bumpMapAmount = 40 ) "normal": ( mat.bumpMap = tm mat.bumpMapAmount = 40 ) "specular": mat.specularMap = tm "gloss": mat.specularMap = tm "reflection": mat.reflectionMap = tm default: ( ) ) ) msh.material = mat ) fn ReadBEfloat fstream = ( return floatSwap2(readfloat fstream) ) fname = GetOpenFileName caption:"Open Sonic Model File" types:"Sonic Model File(*.model)|*.model" if (fname!=undefined) and ((doesFileExist fname)==true) then ( f = fopen fname "rb" --open file in read only format filepath = GetFilenamePath fname fseek f 0x04 #seek_set MeshType = ReadBElong f CinematicMesh = 0 MorphTargetTable = 0 BoneCount = 0 BoneTableOffset = 0 BoneTableOffset2 = 0 BoneTableOffset3 = 0 ModelType = 0 Extra_Mesh_Area = #() VertexDataBegin = 0x68 if(MeshType == 2) Then ( print "MeshType 2" fseek f 0x30 #seek_set BoneCount = ReadBElong f BoneTableOffset = ReadBElong f + 0x18 BoneTableOffset2 = ReadBElong f + 0x18 BoneTableOffset3 = ReadBElong f + 0x18 VertexDataBegin = 0x40 fseek f 0x18 #seek_set ) else if(MeshType == 4) Then ( print "MeshType 4" fseek f 0x38 #seek_set BoneCount = ReadBElong f BoneTableOffset = ReadBElong f + 0x18 BoneTableOffset2 = ReadBElong f + 0x18 BoneTableOffset3 = ReadBElong f + 0x18 VertexDataBegin = 0x48 fseek f 0x18 #seek_set ) else if(MeshType == 5) Then ( print "MeshType 5" fseek f 0x20 #seek_set CinematicMesh = ReadBElong f MorphTargetTable = ReadBElong f + 0x18 BoneCount = ReadBElong f BoneTableOffset = ReadBElong f + 0x18 BoneTableOffset2 = ReadBElong f + 0x18 BoneTableOffset3 = ReadBElong f + 0x18 ModelType = ReadBElong f VertexDataBegin = 0x68 ) else if(MeshType == 2005) Then ( print "MeshType 2005" fseek f 0x28 #seek_set BoneCount = ReadBElong f BoneTableOffset = ReadBElong f + 0x18 BoneTableOffset2 = ReadBElong f + 0x18 BoneTableOffset3 = ReadBElong f + 0x18 ModelType = ReadBElong f VertexDataBegin = 0x68 fseek f 0x44 #seek_set ) else ( throw "Unknown format!" fclose f ) MeshDataOffset = 0 if(ModelType > 0x34) then ( MeshDataOffset = (ModelType - 0x34) MeshDataOffset = MeshDataOffset - (mod MeshDataOffset 4) ) ExtraMeshAreaCount = MeshDataOffset / 4 for I = 1 to ExtraMeshAreaCount Do ( append Extra_Mesh_Area (ReadBELong f + 0x18) ) BeforeExtra = ftell f ExtraMeshCount = 0 Extra_Meshes = #() for I = 1 to ExtraMeshAreaCount Do ( fseek f Extra_Mesh_Area #seek_set ThisAreaExtra = (ReadBELong f) ExtraMeshCount = ExtraMeshCount + ThisAreaExtra ThisAreaHead = ReadBELong f + 0x18 for j = 1 To ThisAreaExtra Do ( append Extra_Meshes (ThisAreaHead + (j-1) * 4) ) ) fseek f BeforeExtra #seek_set MeshCount = ReadBElong f UnkCount2 = ReadBElong f AddMeshCount = ReadBElong f AddMeshBegin =ReadBElong f + 0x18 ExtraMeshCount = ExtraMeshCount + AddMeshCount for I = 1 to AddMeshCount Do ( append Extra_Meshes (AddMeshBegin + (I-1) * 4) ) AlphaMeshCount = ReadBElong f AlphaMeshBegin = ReadBElong f + 0x18 ExtraMeshCount = ExtraMeshCount + AlphaMeshCount for I = 1 to AlphaMeshCount Do ( append Extra_Meshes (AlphaMeshBegin + (I-1) * 4) ) fseek f BoneTableOffset#seek_set struct BoneOffset ( BoneTOffset ) Bone_Offset_array = #() for I = 1 to BoneCount Do ( BoneTOffset = ReadBElong f + 0x18 append Bone_Offset_array (BoneOffset BoneTOffset:BoneTOffset) ) print Bone_Offset_array Bone_Data_array = #() BoneID = -1 for k in Bone_Offset_array Do ( fseek f k.BoneTOffset#seek_set BoneID += 1 BoneParentID = ReadBElong f BoneNameOffset = ReadBElong f BoneName = readstring f append Bone_Data_array ( BoneDData BoneID:BoneID BoneNameOffset:BoneNameOffset BoneName:BoneName BoneParentID:BoneParentID ) ) print Bone_Data_array fseek f BoneTableOffset2 #seek_set --if CinematicMesh == 1 Do ( --fseek f 0x1#seek_cur --) BNArr = #() enableSceneRedraw() --disableSceneRedraw() Bone_root_array = #() for I = 1 to BoneCount Do ( m11 = ReadBEfloat f; m12 = ReadBEfloat f; m13 = ReadBEfloat f; m14 = ReadBEfloat f m21 = ReadBEfloat f; m22 = ReadBEfloat f; m23 = ReadBEfloat f; m24 = ReadBEfloat f m31 = ReadBEfloat f; m32 = ReadBEfloat f; m33 = ReadBEfloat f; m34 = ReadBEfloat f m41 = ReadBEfloat f; m42 = ReadBEfloat f; m43 = ReadBEfloat f; m44 = ReadBEfloat f tfm = matrix3 [m11,m12,m13] [m21,m22,m23] [m31,m32,m33] [m41,m42,m43] newBone = bonesys.createbone \ tfm.row4 \ (tfm.row4 + 0.01 * (normalize tfm.row1)) \ (normalize tfm.row3) newBone.name = Bone_Data_array.BoneName newBone.width = 0.01 newBone.height = 0.01 newBone.transform = tfm pos = (-1) * [m14,m24,m34] pos = pos * tfm --if(newbone.name == "Brow1_L") then --newBone.pos = [0.045,0.84,0.148] --else if(newbone.name == "Brow2_L") then --newBone.pos = [0.096,0.911,0.108] --else if(newbone.name == "Brow3_L") then --newBone.pos = [0.138,0.854,0.05] --else if(newbone.name == "Brow_C") then --newBone.pos = [0.0, 0.8, 0.05] --else --( newBone.pos.x = pos.x * mdlScale newBone.pos.y = pos.z * (-1) * mdlScale newBone.pos.z = pos.y * mdlScale --) newBone.setBoneEnable false 0 newBone.pos.controller = TCB_position () newBone.rotation.controller = TCB_rotation () if (Bone_Data_array.BoneParentID != -1) then newBone.parent = BNArr[Bone_Data_array.BoneParentID+1] BNArr = newBone if I == 1 do ( append Bone_root_array newBone ) ) MorphArr = #() MorphArr2 = #() Morph_Face_array = #() Morph_Name_array = #() print "Bones done" if CinematicMesh == 1 Then ( fseek f MorphTargetTable #seek_set print "Cinematic mesh" PrintOffset (ftell f) MorphVertCountOffset = ReadBElong f + 0x18 MorphVertCount = ReadBElong f MorphTableEnd = ReadBElong f + 0x18 MorphUnkCount1 = ReadBElong f MorphCount = ReadBElong f MorphTableStart = ReadBElong f + 0x18 MorphTableNameStart = ReadBElong f + 0x18 MorphFaceSetsCount = ReadBElong f MorphFaceTableStart = ReadBElong f + 0x18 Null = readlong f MorphFaceTableEnd = ReadBElong f + 0x18 Texture = "" Bone_ids1 = #() fseek f MorphFaceTableStart#seek_set PrintOffset (ftell f) MorphFaceSets = #() MorphVertSize = 0x68 DataTable = #() for I = 1 to MorphFaceSetsCount Do ( FaceSetStart = ReadBElong f + 0x18 append MorphFaceSets FaceSetStart ) for I = 1 to MorphFaceSetsCount Do ( fseek f MorphFaceSets #seek_set PrintOffset (ftell f) TextureOffset = ReadBElong f + 0x18 MorphFaceCount = ReadBElong f MorphFaceOffset = ReadBElong f + 0x18 --ReadBElong f --MorphVertSize = ReadBElong f --MorphDataTable = ReadBElong f + 0x18 if ( I == 1) then ( BackJump = ftell f fseek f TextureOffset #seek_set Texture = readstring f fseek f BackJump #seek_set fseek f 0x10 #seek_cur boneidcount = ReadBElong f boneidstart = (ReadBElong f) + 0x18 fseek f boneidstart #seek_set for j=1 to boneidcount do ( addboneid = (ReadByte f #unsigned) append Bone_ids1 (addboneid + 1) ) ) --Read data table /* CoordinatesFound = false UVDataFound = false BoneIndicesFound = false BoneWeightsFound = false DataTableEnd = false fseek f MorphDataTable #seek_set PrintOffset(MorphDataTable) while(not DataTableEnd) do ( DataOffset = ReadBElong f DataType = ReadBElong f EntryType = ReadBEword f SubId = ReadByte f Padding = ReadByte f if(DataType != -1) then ( append DataTable (VertexDeclarationEntry DataOffset: DataOffset DataType: DataType EntryType: EntryType SubId: SubId) if(EntryType == 0) then CoordinatesFound = true if(EntryType == 1) then BoneWeightsFound = true if(EntryType == 2) then BoneIndicesFound = true if(EntryType == 5) then UVDataFound = true ) else ( DataTableEnd = true ) ) if((not CoordinatesFound) or (not BoneWeightsFound) or (not BoneIndicesFound) or (not UVDataFound)) then ( throw "NOOOOO!" )*/ fseek f MorphFaceOffset#seek_set StartDirection = 1 f1 = (ReadBEword f) + 1 f2 = (ReadBEword f) + 1 FaceDirection = StartDirection Do ( f3 = (ReadBEword f) if (f3==0xFFFF) then ( f1 = (ReadBEword f) + 1 f2 = (ReadBEword f) + 1 FaceDirection = StartDirection ) else ( f3 += 1 FaceDirection *= -1 if (f1!=f2)AND(f2!=f3)AND(f3!=f1) then ( if FaceDirection > 0 then append Morph_Face_array [f1,f2,f3] else append Morph_Face_array [f1,f3,f2] ) f1 = f2 f2 = f3 ) ) while ((ftell f) != (MorphFaceOffset + (MorphFaceCount * 2))) ) fseek f MorphTableEnd #seek_set Vert_array1 = #() --define arrays for verts, normals, UV and Faces --Normal_array1 = #() UV_array1 = #() Weight_array1 = #() for k = 1 to MorphVertCount Do ( --Ignoring data table for speed reasons! vx = ReadBEfloat f --read xyz coordinates vy = ReadBEfloat f vz = ReadBEfloat f fseek f 0x24#seek_cur tu = ReadBEFloat f --read UV float value tv = ReadBEFloat f * -1 fseek f 0x28#seek_cur bone1 = readbyte f#unsigned bone2 = readbyte f#unsigned bone3 = readbyte f#unsigned bone4 = readbyte f#unsigned weight1 = readbyte f#unsigned weight2 = readbyte f#unsigned weight3 = readbyte f#unsigned weight4 = readbyte f#unsigned w = (weight_data boneids:#() weights:#()) maxweight = 0 if(bone1 != 0xFF) then maxweight = maxweight + weight1 if(bone2 != 0xFF) then maxweight = maxweight + weight2 if(bone3 != 0xFF) then maxweight = maxweight + weight3 if(bone4 != 0xFF) then maxweight = maxweight + weight4 if(maxweight != 0) then ( mxw = 255.0 if(bone1 != 0xFF) then ( w1 = weight1 as float append w.boneids (Bone_ids1[bone1+1]) append w.weights (w1 / mxw) ) if(bone2 != 0xFF) then ( w2 = weight2 as float append w.boneids (Bone_ids1[bone2+1]) append w.weights (w2 / mxw) ) if(bone3 != 0xFF) then ( w3 = weight3 as float append w.boneids (Bone_ids1[bone3+1]) append w.weights (w3 / mxw) ) if(bone4 != 0xFF) then ( w4 = weight4 as float append w.boneids (Bone_ids1[bone4+1]) append w.weights (w4 / mxw) ) ) append Vert_array1 [vx*mdlScale,(-1)*vz*mdlScale,vy*mdlScale] append UV_array1 [tu,tv,0] --save UVs to UV_array append Weight_array1 w ) msh = mesh verticesert_array1 faces:Morph_Face_array --build mesh msh.numTVerts = UV_array1.count buildTVFaces msh ImportTextureMesh msh Texture filepath msh.name = "Mouth" for j = 1 to UV_array1.count do setTVert msh j UV_array1[j] for j = 1 to Morph_Face_array.count do setTVFace msh j Morph_Face_array[j] --for j = 1 to Normal_array1.count do setNormal msh j Normal_array1[j] select $Mouth MorphMod = morpher () addModifier $Mouth MorphMod $Mouth.morpher.Autoload_of_targets = 1 --$Mouth.parent = $Neck fseek f MorphTableStart#seek_set for I = 1 to MorphCount Do ( append MorphArr (ReadBElong f + 0x18) ) for I = 1 to MorphCount Do ( append MorphArr2 (ReadBElong f + 0x18) ) for I = 1 to MorphCount Do ( fseek f MorphArr#seek_set MorphName = readstring f fseek f MorphArr2#seek_set Morph_Vert_array = #() Morph_UV_array = #() --Morph_Normal_array = #() for k = 1 to MorphVertCount Do ( vx = ((ReadBEfloat f) ) + Vert_array1[k].x / mdlScale vy = ((ReadBEfloat f) ) + Vert_array1[k].z / mdlScale vz = ((ReadBEfloat f) ) + (-1) * Vert_array1[k].y / mdlScale append Morph_Vert_array [vx * mdlScale,-vz * mdlScale,vy * mdlScale] ) msh = mesh vertices:Morph_Vert_array faces:Morph_Face_array --build mesh msh.numTVerts = UV_array1.count buildTVFaces msh msh.name = MorphName for j = 1 to UV_array1.count do setTVert msh j UV_array1[j] for j = 1 to Morph_Face_array.count do setTVFace msh j Morph_Face_array[j] --for j = 1 to Morph_Normal_array.count do setNormal msh j Morph_Normal_array[j] append Morph_Name_array msh ) max modify mode select $mouth skinMod = skin () addModifier $mouth skinMod for I = 1 to BNArr.count do ( maxbone = getnodebyname BNArr.name if I != BNArr.count then skinOps.addBone skinMod maxbone 0 else skinOps.addBone skinMod maxbone 1 ) modPanel.setCurrentObject skinMod for I = 1 to Weight_array1.count do ( w = Weight_array1 bi = #() --bone index array wv = #() --weight value array for j = 1 to w.boneids.count do ( boneid = w.boneids[j] weight = w.weights[j] append bi boneid append wv weight ) skinOps.ReplaceVertexWeights skinMod I bi wv ) vwld = Vertex_Weld() vwld.enabledInRenders = true vwld.enabledInViews = false vwld.threshold = 0.002 addModifier $mouth vwld max create mode ) for b = 1 to Morph_Name_array.count Do ( WM3_MC_BuildFromNode $Mouth.morpher b Morph_Name_array hide Morph_Name_array ) All_Vert_array = #() All_UV_array = #() All_Mat_Face_array = #() All_Face_array = #() All_Weight_array = #() AllVertexCount = 0 MultiMat = MultiMaterial() MultiMat.numsubs = MeshCount+ExtraMeshCount if(MeshType == 5) Then fseek f (VertexDataBegin + MeshDataOffset) #seek_set else fseek f VertexDataBegin #seek_set for c = 1 to MeshCount+ExtraMeshCount Do ( CExtra = false if(c > MeshCount) then ( --Extra mesh! CExtra = true extraIndex = c - MeshCount fseek f (Extra_Meshes[extraIndex]) #seek_set print("Extra Mesh " + (extraIndex as string)) ) --print ("Mesh: " + c as string) --PrintOffset (ftell f) Vert_array = #() Normal_array = #() UV_array = #() Face_array = #() Weight_array = #() BoneID_array = #() offsetstart = (ReadBElong f) + 0x18 tablestart = ftell f fseek f offsetstart#seek_set PrintOffset (ftell f) TextureOffset = ReadBElong f + 0x18 BackJump = ftell f fseek f TextureOffset #seek_set Texture = readstring f --print (Texture) fseek f BackJump #seek_set FaceCount = ReadBElong f FaceStart = ReadBElong f + 0x18 VertCount = ReadBElong f VertSize = ReadBElong f VertStart = ReadBElong f + 0x18 DataTableStart = ReadBElong f + 0x18 SecBoneCount = ReadBElong f SecBoneIDs = (ReadBElong f) + 0x18 BackJump = ftell f fseek f SecBoneIDs #seek_set for I = 1 to SecBoneCount do ( addboneid = (ReadByte f #unsigned) append BoneID_array (addboneid + 1) ) fseek f BackJump #seek_set Count10 = ReadBElong f Count11 = ReadBElong f FaceStart = ftell f VerStart = (FaceCount * 2) + FaceStart --Read data table BackJump = ftell f CoordinatesFound = false UVDataFound = false BoneIndicesFound = false BoneWeightsFound = false DataTableEnd = false DataTable = #() fseek f DataTableStart #seek_set while(not DataTableEnd) do ( DataOffset = ReadBElong f DataType = ReadBElong f EntryType = ReadBEword f SubId = ReadByte f Padding = ReadByte f if(DataType != -1) then ( append DataTable (VertexDeclarationEntry DataOffset: DataOffset DataType: DataType EntryType: EntryType SubId: SubId) if(EntryType == 0) then CoordinatesFound = true if(EntryType == 1) then BoneWeightsFound = true if(EntryType == 2) then BoneIndicesFound = true if(EntryType == 5) then UVDataFound = true ) else ( DataTableEnd = true ) ) if((not CoordinatesFound) or (not BoneWeightsFound) or (not BoneIndicesFound) or (not UVDataFound)) then ( throw "NOOOOO!" ) fseek f BackJump #seek_set --end read data table StartDirection = 1 f1 = (ReadBEword f) + 1 f2 = (ReadBEword f) + 1 FaceDirection = StartDirection Do ( f3 = (ReadBEword f) if (f3==0xFFFF) then ( f1 = (ReadBEword f) + 1 f2 = (ReadBEword f) + 1 FaceDirection = StartDirection ) else ( f3 += 1 FaceDirection *= -1 if (f1!=f2)AND(f2!=f3)AND(f3!=f1) then ( if FaceDirection > 0 then append Face_array [f1,f2,f3] else append Face_array [f1,f3,f2] ) f1 = f2 f2 = f3 ) ) while ((ftell f) != (VerStart)) fseek f VerStart#seek_set test = readshort f if test != 0x0000 Do ( fseek f -2 #seek_cur ) fseek f VertStart#seek_set for v = 1 to VertCount Do ( vx = 0 vy = 0 vz = 0 tu = 0 tv = 0 bone1 = 0xFF bone2 = 0xFF bone3 = 0xFF bone4 = 0xFF weight1 = 0 weight2 = 0 weight3 = 0 weight4 = 0 UVSubZeroFound = false UVFound = false VertexDataStart = ftell f for x = 1 to DataTable.count Do ( Entry = DataTable[x] fseek f Entry.DataOffset #seek_cur if(Entry.EntryType == 0) Then ( vx = ReadBEfloat f vy = ReadBEfloat f vz = ReadBEfloat f ) if(Entry.EntryType == 1) Then ( weight1 = readbyte f#unsigned weight2 = readbyte f#unsigned weight3 = readbyte f#unsigned weight4 = readbyte f#unsigned ) if(Entry.EntryType == 2) Then ( bone1 = readbyte f#unsigned bone2 = readbyte f#unsigned bone3 = readbyte f#unsigned bone4 = readbyte f#unsigned ) if(Entry.EntryType == 5) Then ( SubId = Entry.SubId ReadThisUV = (not UVFound) or (not UVSubZeroFound and SubId == 0) if(ReadThisUV) then ( UVFound = true if(SubId == 0) then UVSubZeroFound = true if(Entry.DataType == 2892709) then ( tu = ReadBEfloat f tv = ReadBEfloat f ) else ( tu = ReadBEHalfFloat f tv = ReadBEHalfFloat f ) tv = tv * (-1) ) ) fseek f VertexDataStart #seek_set ) fseek f VertSize #seek_cur w = (weight_data boneids:#() weights:#()) maxweight = 0 if(bone1 != 0xFF) then maxweight = maxweight + weight1 if(bone2 != 0xFF) then maxweight = maxweight + weight2 if(bone3 != 0xFF) then maxweight = maxweight + weight3 if(bone4 != 0xFF) then maxweight = maxweight + weight4 if(maxweight != 0) then ( mxw = 255.0 if(bone1 != 0xFF) then ( w1 = weight1 as float append w.boneids (BoneID_array[bone1+1]) append w.weights (w1 / mxw) ) if(bone2 != 0xFF) then ( w2 = weight2 as float append w.boneids (BoneID_array[bone2+1]) append w.weights (w2 / mxw) ) if(bone3 != 0xFF) then ( w3 = weight3 as float append w.boneids (BoneID_array[bone3+1]) append w.weights (w3 / mxw) ) if(bone4 != 0xFF) then ( w4 = weight4 as float append w.boneids (BoneID_array[bone4+1]) append w.weights (w4 / mxw) ) ) append Vert_array [vx * mdlScale,(-1)*vz * mdlScale,vy * mdlScale] --save verts to Vert_array --append Normal_array [nx,ny,nz] --save normals to Normal_array append UV_array [tu,tv,0] --save UVs to UV_array append Weight_array w ) fseek f tablestart#seek_set for I = 1 to Face_array.count do ( vertices = Face_array append All_Face_array [vertices[1] + AllVertexCount, vertices[2] + AllVertexCount, vertices[3] + AllVertexCount] append All_Mat_Face_array c ) AllVertexCount = AllVertexCount + Vert_array.count for I = 1 to Vert_array.count do ( append All_Vert_array vert_array[I] append All_UV_array UV_array[I] append All_Weight_array Weight_array[I] ) importTexture MultiMat c Texture filepath /*msh = mesh verticesert_array faces:Face_array --build mesh msh.numTVerts = UV_array.count importTexture msh Texture filepath buildTVFaces msh for j = 1 to UV_array.count do setTVert msh j UV_array[j] for j = 1 to Face_array.count do setTVFace msh j Face_array[j] --for j = 1 to Normal_array.count do setNormal msh j Normal_array[j] max modify mode select msh skinMod = skin () addModifier msh skinMod for I = 1 to BNArr.count do ( maxbone = getnodebyname BNArr[I].name if I != BNArr.count then skinOps.addBone skinMod maxbone 0 else skinOps.addBone skinMod maxbone 1 ) modPanel.setCurrentObject skinMod for I = 1 to Weight_array.count do ( w = Weight_array[I] bi = #() --bone index array wv = #() --weight value array for j = 1 to w.boneids.count do ( boneid = w.boneids[j] weight = w.weights[j] append bi boneid append wv weight ) skinOps.ReplaceVertexWeights skinMod I bi wv ) max create mode*/ ) max create mode msh = mesh vertices:All_Vert_array faces:All_Face_array --build mesh msh.numTVerts = All_UV_array.count if (BNArr.count >= 1) then msh.name = BNArr[1].name buildTVFaces msh for j = 1 to All_UV_array.count do setTVert msh j All_UV_array[j] for j = 1 to All_Face_array.count do ( setTVFace msh j All_Face_array[j] setFaceMatID msh j All_Mat_Face_array[j] ) max modify mode select msh skinMod = skin () addModifier msh skinMod for I = 1 to BNArr.count do ( maxbone = getnodebyname BNArr[I].name if I != BNArr.count then skinOps.addBone skinMod maxbone 0 else skinOps.addBone skinMod maxbone 1 ) modPanel.setCurrentObject skinMod for I = 1 to All_Weight_array.count do ( w = All_Weight_array[I] bi = #() --bone index array wv = #() --weight value array for j = 1 to w.boneids.count do ( boneid = w.boneids[j] weight = w.weights[j] append bi boneid append wv weight ) skinOps.ReplaceVertexWeights skinMod I bi wv ) msh.material = MultiMat max modify mode --enableSceneRedraw() fclose f ) /*select Bone_root_array[1] scale $ [36.0,36.0,36.0] rotate $ (angleaxis 90 [1,0,0])*/ --actionMan.executeAction 0 "311" -- Tools: Zoom Extents All Selected [/I][/I][/I][/I][/I][/I][/I] [I][I][I][I][I][I] Direct link to maxscript just in case it gets updated: http://sonic-glvl.googlecode.com/svn/trunk/export_scripts/3dsmax/Model%20Importer-Updated%206-07-2012.ms Maxscript Credits: chrrox, kentilan, darkspinesonic35, and TZ, And a little myself early on( batch importing models)... am I forgetting anyone ? Animations tools: [url= http://niftools.sourceforge.net/wiki/3ds_Max] niftools for max 2010 and 2011[/url] [url= https://tesrenewal.com/forums/tools-and-coding/nif-importexport-plugin-for-3dsmax-2013] niftools for max 2013[/url] [url= http://hotfile.com/dl/143278880/d7bce05/Hkxcmd.rar.html] hkxcmd[/url] 1) Install Niftools plugin into 3ds max 2) Convert the .hkx files into .kf using hkxcmd. Use the following command line parameters: hkxcmd.exe exportkf FILE.skl.hkx FILE.anm.hkx FILE.kf FILE.skl.hkx -> the skeleton file of the model, like "chr_Sonic_HD.skl.hkx" FILE.anm.hkx -> the animation file you want to convert, like "sn_run_loop.anm.hkx" FILE.kf -> the output .kf file 3) Use the model importer maxscript (like "Model Importer-Updated 6-07-2012.ms") to import the .model file into 3ds max 4) Once you have the 3d model opened in 3ds Max, import the .kf file in 3ds max with the niftools plugin (you may have to import the animation a few times to get it to work perfectly.) (Animation tools explanation credit to DaGuar)[/i][/i][/i][/i][/i][/i]
I guess we could make this the Sonic Generations hacking topic. :P Check this out: Code (Text): <HomingAttack> <Param> <ActionEnableAfterHomingAttack>0.35</ActionEnableAfterHomingAttack> <HomingAttackEnableAfterFall>0.1</HomingAttackEnableAfterFall> <HomingAttackEnableVertUp>-1</HomingAttackEnableVertUp> <HomingRotateForce>10</HomingRotateForce> <XButtonHoming>false</XButtonHoming> </Param> </HomingAttack> This was found in SonicClassic.prm.xml. So if you ever wanted to use the homingattack as Classic Sonic, it's as easy as turning on a variable and repacking the game. yay I think if we activated the game's debugger, we can modify these variables in real time so it'd be a lot easier. SonicClassic.prm.xml is full of variables for the Classic Sonic physics. EDIT1: Here's one possibility to activating the debugger. In #Application.ar.00, there are two lua files called ApplicationSetting.lua and ApplicationSettingDebug.lua. By default, the demo looks at ApplicationSetting.lua, here are the settings: Code (Text): function applicationSetting() AppSetting_Integer("SignIn", 1); -- ‹N“®Žž‚ɃTƒCƒ“ƒCƒ“‚·‚é‚© AppSetting_Integer("SaveLoad", 0); -- ƒZ[ƒuƒ[ƒh‚·‚é‚© AppSetting_Integer("DeleteSaveData", 0); -- ‹N“®Žž‚ɃZ[ƒuƒf[ƒ^‚ð휂·‚é‚© AppSetting_Integer("DebugSequence", 0); AppSetting_String("Language", "English"); -- "English","Japanese","French","Italian","German","Spanish" AppSetting_String("DemoKind", "Demo"); -- Production/Demo AppSetting_String("DemoDistribution", "Trial_Ver1"); -- PressTour/E3_Front/E3_Backyard/GamesCom/TGS/Trial_Ver1/Trial_Ver2 end For comparison sake, here's the Debug equivalent: Code (Text): function applicationSetting() AppSetting_Integer("SignIn", 1); -- ‹N“®Žž‚ɃTƒCƒ“ƒCƒ“‚·‚é‚© AppSetting_Integer("SaveLoad", 1); -- ƒZ[ƒuƒ[ƒh‚·‚é‚© AppSetting_Integer("DeleteSaveData", 0); -- ‹N“®Žž‚ɃZ[ƒuƒf[ƒ^‚ð휂·‚é‚© AppSetting_Integer("DebugSequence", 1); AppSetting_String("Language", "Japanese"); -- "English","Japanese","French","Italian","German","Spanish" 擪‚P•¶Žš‚ ‚Á‚Ä‚ê‚΂n‚j AppSetting_String("DemoKind", "Production"); -- Production/Demo AppSetting_String("DemoDistribution", "Trial_Ver1"); -- PressTour/E3_Front/E3_Backyard/GamesCom/TGS/Trial_Ver1/Trial_Ver2 AppSetting_Integer("DisableOnlineTime", 1); -- Xbox360‘ÌŒ±”ł̃Iƒ“ƒ‰ƒCƒ“ŽžŠÔ”F؂𖳌ø‚ É‚·‚é‚© end (mind the text, quick notepad copy and paste) I think one thing the game might consider when loading the debug is the "DemoKind" string. The plan is to set the DemoKind string in ApplicationSetting to Production, and possibly DebugSequence to 1 (might be unnecessary since we don't know what it does). DemoDistribution should be commented out. Basically, make ApplicationSetting.lua look like ApplicationSettingDebug. I remember when messing around with Shadow and NiGHTS JoD, those games do take what the build string is into consideration. Because this is a prerelease, there should be a possibility of getting the debug to work. But of course, since it's a "release" build, maybe they left the files needed out. But it's worth a try. The only problem right now is packing things up so the game can read them. This is apparently a problem for the 360 version, but might not be a problem for the PS3 version. But I doubt it, because the keys that have been released for the PS3 probably won't help with this since this is more recent. I hope a PC demo comes out. That should make things easier.
So, Seaside Hill is Ocean Palace for the looks of it. And Spagonia has areas that resemble the hub area in Unleashed, the university stands out.
So do we have a method of extracting and injecting to CPK files yet? I have some devious ideas I'd like to perform on my files.
So I hear that the assets for Chemical Plant are in the demo somewhere - has anybody been able to find any visual evidence of it in the game?
Badnik list anyone? Code (Text): </Name> <Object> <ID>EnemyMotora2D</ID> <ObjName>???[2D]</ObjName> </Object> <Object> <ID>EnemyMotora3D</ID> <ObjName>???[3D]</ObjName> </Object> <Object> <ID>EnemyBeeton2D</ID> <ObjName>????[2D]</ObjName> </Object> <Object> <ID>EnemyBeeton3D</ID> <ObjName>????[3D]</ObjName> </Object> <Object> <ID>EnemyBatabata2D</ID> <ObjName>????[2D]</ObjName> </Object> <Object> <ID>EnemyBatabata3D</ID> <ObjName>????[3D]</ObjName> </Object> <Object> <ID>EnemyGanigani2D</ID> <ObjName>????[2D]</ObjName> </Object> <Object> <ID>EnemyGanigani3D</ID> <ObjName>????[3D]</ObjName> </Object> <Object> <ID>EnemyLander2D</ID> <ObjName>????[2D]</ObjName> </Object> <Object> <ID>EnemyLander3D</ID> <ObjName>????[3D]</ObjName> </Object> <Object> <ID>EnemyGrabber2D</ID> <ObjName>????[2D]</ObjName> </Object> <Object> <ID>EnemyGrabber3D</ID> <ObjName>????[3D]</ObjName> </Object> <Object> <ID>EnemyEggRobo2D</ID> <ObjName>?????[2D]</ObjName> </Object> <Object> <ID>EnemyEggRobo3D</ID> <ObjName>?????[3D]</ObjName> </Object> <Object> <ID>EnemySpinner2D</ID> <ObjName>???[2D]</ObjName> </Object> <Object> <ID>EnemySpinner</ID> <ObjName>???[3D]</ObjName> </Object> <Object> <ID>EnemySpanner2D</ID> <ObjName>???[2D]</ObjName> </Object> <Object> <ID>EnemySpanner</ID> <ObjName>???[3D]</ObjName> </Object> <Object> <ID>EnemyCopSpeeder2D</ID> <ObjName>????????[2D]</ObjName> </Object> <Object> <ID>EnemyCopSpeeder3D</ID> <ObjName>????????[3D]</ObjName> </Object> <Object> <ID>EnemyCopSpeeder3DCreator</ID> <ObjName>?????????????</ObjName> </Object> <Object> <ID>EnemyCopSpeederWallRun</ID> <ObjName>????????????</ObjName> </Object> <Object> <ID>EnemyPathMover</ID> <ObjName>????????????</ObjName> </Object> <Object> <ID>EnemyMonoBeetle2D</ID> <ObjName>??????2D</ObjName> </Object> <Object> <ID>EnemyMonoBeetle3D</ID> <ObjName>??????3D</ObjName> </Object> <Object> <ID>EnemyGunBeetle2D</ID> <ObjName>??????2D</ObjName> </Object> <Object> <ID>EnemyGunBeetle3D</ID> <ObjName>??????3D</ObjName> </Object> <Object> <ID>EnemyGunHunter2D</ID> <ObjName>??????2D</ObjName> </Object> <Object> <ID>EnemyGunHunter3D</ID> <ObjName>??????3D</ObjName> </Object> <Object> <ID>EnemyPawn2D</ID> <ObjName>???2D</ObjName> </Object> <Object> <ID>EnemyPawn3D</ID> <ObjName>???3D</ObjName> </Object> <Object> <ID>EnemyPawnLance2D</ID> <ObjName>???2D(?)</ObjName> </Object> <Object> <ID>EnemyPawnLance3D</ID> <ObjName>???3D(?)</ObjName> </Object> <Object> <ID>EnemyPawnGun2D</ID> <ObjName>???2D(?)</ObjName> </Object> <Object> <ID>EnemyPawnGun3D</ID> <ObjName>???3D(?)</ObjName> </Object> <Object> <ID>EnemyTaker2D</ID> <ObjName>????2D</ObjName> <DataPath>object/stage/crisiscity/spikeshot</DataPath> </Object> <Object> <ID>EnemyTaker3D</ID> <ObjName>????3D</ObjName> <DataPath>object/stage/crisiscity/spikeshot</DataPath> </Object> <Object> <ID>EnemyCrawler2D</ID> <ObjName>??????D</ObjName> <DataPath>object/stage/crisiscity/spikeshot</DataPath> </Object> <Object> <ID>EnemyCrawler3D</ID> <ObjName>??????D</ObjName> <DataPath>object/stage/crisiscity/spikeshot</DataPath> </Object> <Object> <ID>EnemyBiter2D</ID> <ObjName>?????D</ObjName> </Object> <Object> <ID>EnemyBiter3D</ID> <ObjName>?????D</ObjName> </Object> <Object> <ID>EnemyEFighter2D</ID> <ObjName>????????[2D]</ObjName> </Object> <Object> <ID>EnemyEFighter3D</ID> <ObjName>????????[3D]</ObjName> </Object> <Object> <ID>EnemyEFighterSword2D</ID> <ObjName>?????????[2D]</ObjName> </Object> <Object> <ID>EnemyEFighterSword3D</ID> <ObjName>?????????[3D]</ObjName> </Object> <Object> <ID>EnemyELauncher2D</ID> <ObjName>????????[2D]</ObjName> </Object> <Object> <ID>EnemyELauncher3D</ID> <ObjName>????????[3D]</ObjName> </Object> <Object> <ID>EnemyAeroCannon</ID> <ObjName>??????</ObjName> </Object> <Object> <ID>EnemyEChaserManager</ID> <ObjName>?????????????</ObjName> </Object> <Object> <ID>EnemyNal2D</ID> <ObjName>???2D</ObjName> </Object> <Object> <ID>EnemyNal3D</ID> <ObjName>???3D</ObjName> </Object> <Object> <ID>EnemyPawnPla3D</ID> <ObjName>???3D(?????)</ObjName> </Object> <Object> <ID>EnemyPawnPla2D</ID> <ObjName>???2D(?????)</ObjName> </Object> <Object> <ID>EnemyEChaserSV</ID> <ObjName>????????SV</ObjName> </Object> </Category>
The CRI Packed File Maker can extract and pack CPK files, and there are probably some tools for quickbms that'll work too. I tried CRI's tools on bb.cpk but even though it would list the contents of everything it wouldn't let me extract anything, so I had to use quickbms plus a cpk script. The music/sound cpks open and extract fine with CRI's tools though. I remember getting Saz to use .ar files I packed with edited lua/xml files for Unleashed about a year ago and those worked out okay for him. I forget if he was using a dev 360 or not. I remember repacking the CPK file for Sonic 4 and that was okay, so maybe it could work.
I'm hoping the model for Classic Sonic can be extracted, but I'm sure work's already under way to get to that. Also holding faint hope the weighting and skeleton can also be extracted, but that might be more of a longshot.
I see Super Sonic textures in there. I hope someone gets the models and shares them. That modern Knuckles too. Don't have a new one of him
Mind if I pester you for the QuickBMS script? Jim and I ran into the same issue earlier. Glad there's a fix for it. I assume the CRI tools can still repack bb.cpk correct?
Sure, you can use this script with QuickBMS to extract basically any CPK file. You can pack a directory into a CPK file with CRI's tools. In this case, you need to pack the entire contents of bb.cpk again to create a new one. If you need to look inside the .ar files, you can find the tools needed to pack and unpack them here. Hope this helps and good luck.
Thanks for the artools. That QuickBMS script does not seem to want to work with the PSN version's bb.cpk. I dunno what we're going to do about that. The biggest thing about getting this to work though is that Jim has a modded PS3 and can get debug mode going if we can get bb.cpk to unpack/repack.
Both Knuckles and Tails are considered Modern by their eyes if that is something to go off of, so don't expect to see a Classic Amy beyond a reference at best.
Maybe I could try, can you somehow find a way to get the .pkg for the demo my way? From the sound of it, maybe bb.cpk is encrypted?
Here's the PKG (Don't bitch about piracy guys, it's a damn demo...) Thing is, I don't think it's encrypted. We've managed to get a partial extract, but I'm certain there's more to it. Then again, I'm basing this off of what I saw through the tools. I haven't seen the 360 extract to go off of so I wouldn't know. EDIT: Just got my hands on the 360 version. I can confirm that the PSN bb.cpk is larger so there has to be something different preventing it from extracting.
A Bigger Texture pack has been uploaded on the first page, I think we may have all the textures extracted from the game at this point in time. (unless there are some in places like the Stage.pfd and Stage-Add.pfd files which I managed to get open. there is a junk load of .ar files inside that I could not extract anything from. anyone know what these are for?