Create Your Own [Almost] Completely Original SADX Level Geometry

Discussion in 'Engineering & Reverse Engineering' started by Melody the Sylveon, Nov 21, 2009.

Thread Status:
Not open for further replies.
  1. Melody the Sylveon

    Melody the Sylveon

    You're never too old to become your true self. Oldbie
    1,985
    61
    28
    healing
    Here's what you'll need for this tutorial:
    -Sonic Adventure DX (duh)
    -A hex editor and some skill in using it - I use Hex Workshop
    -3DS Max (a version between 9 and 2008) and some skill in using it
    -<a href="http://x-hax.cultnet.net/dudetools/KrxImpExp-max2009-Jun-18-2008.7z" target="_blank">Kerrax's ASC import plugins for 3DS Max (jun 18th 2008 revision)</a>
    -<a href="http://forums.sonicretro.org/index.php?showtopic=17491" target="_blank">Dude's model tools v1.3</a>
    -OBJ2VT, available in <a href="http://x-hax.cultnet.net/modeltools.rar" target="_blank">this rar</a>
    -patience for screwing things up, as you'll do it a lot


    1) First you'll need to get the models out of the game and into 3DS Max.
    To do this, drag and drop sonic.exe onto sadxmdl2_levelASC.exe from Dude's tools. You'll get a file called out.asc.

    2) Open up out.asc in 3DS Max. You'll notice right away that the level is rotated weirdly. This is unfortunately something you'll have to deal with - don't rotate it!

    3) Find the object you want to edit. Feel free to morph the objects into things completely different - but ONLY EDIT THE VERTICES, AND KEEP IT IN THE SAME PLACE. Keep in mind that the UVs (texture definitions per poly) don't change as well, so avoid stretching faces too much and stuff like that.

    4) When you're done, create an instance copy of the object you just edited. Move it to 0,0,0 coordinates.

    5) Select only the object you moved to 0,0,0. Go to File > Export Selected and export it as a WaveFront object (.OBJ). Make sure the "Rotate Model" box is UNCHECKED. Don't close 3DS Max just yet.

    6) Drag and drop that OBJ file onto OBJ2VT. A new file will be made called out.vt. Open that up in your hex editor.

    7) MAKE A COPY OF SONIC.EXE. Do this EVERY TIME you change ANYTHING, in case you screw something up. Open up sonic.exe in your hex editor.

    Note) <a href="http://x-hax.cultnet.net/Docs/MDL_FS2.png" target="_blank">This may help you with steps 8 and 9 if you're experienced with hex stuff.</a>

    8) Hard part. In 3DS Max, get the name of the object you edited, and take the number out of it (e.g. 12643760). Take this and go to this decimal offset in sonic.exe in your hex editor. Jump 4 bytes forward. Take this unsigned long and subtract 0x400000 from that, and go to that offset. Take the unsigned long here and subtract 0x400000 from THAT, and jump to it again. You are now at the vertex data. Select all the data from out.vt and make note of how many bytes it is (in hex) and copy it. Go back to sonic.exe, and at the location we just jumped to, select a block exactly that many bytes long and paste.

    9) We're not done yet. Go back to the offset (e.g. 12643760) and jump 8 bytes forward. You are now at the position data. Go back to 3DS Max and move the model to the exact place you want it. Get the X position. Put it at this location as a float. Jump 4 bytes forward and repeat for Y, and then 4 more forward for Z. The next 3 floats are the rotation data in BAMS

    10) Save. At this point if you did everything right you should get the object in game, but it may (probably will) have glitchy collision. In 3DS Max, make a sphere that as exactly as possible covers the entire object while being as small as possible.

    11) Take the original number (12643760 again) and ADD 0x400000 to it, and search for if in sonic.exe. When you have found it you are at the Object pointer in the <a href="http://x-hax.cultnet.net/Docs/Layoutspec.txt" target="_blank">Collision struct</a>. If you don't understand that, jump back 24 bytes. This float is the X location of your sphere. 4 Bytes forward is the Y as a float, and 4 bytes later is the Z as a float. 4 bytes forward from this is the radius of the sphere.

    12) You should be done, hopefully. Go back to step 3 to do more geometry edits. Then make an object layout with <a href="http://info.sonicretro.org/SETedit" target="_blank">SETedit</a>!
     
  2. MainMemory

    MainMemory

    Kate the Wolf Tech Member
    4,551
    145
    43
    SonLVL
    Nice guide, seems simple enough.
    I would totally do this if I knew how to do 3D stuff. I'm going to have to look into that eventually.
     
  3. Dude

    Dude

    Tech Member
    3,138
    0
    16
    Southbridge, MA
    Random VR/AR trash
    I'm working on a program to do steps 4-11 for you. But I'm having issues parsing the asc file... If someone who is good with C and text parsing would be willing to help, it'd probably facilitate simplifying level editing.
     
  4. MainMemory

    MainMemory

    Kate the Wolf Tech Member
    4,551
    145
    43
    SonLVL
    <!--quoteo(post=376200:date=Nov 20 2009, 10:40 PM:name=Dude)--><div class='quotetop'>QUOTE (Dude @ Nov 20 2009, 10:40 PM) <a href="index.php?act=findpost&pid=376200">[​IMG]</a></div><div class='quotemain'><!--quotec-->text parsing<!--QuoteEnd--></div><!--QuoteEEnd-->
    I can do that!
    <!--quoteo(post=376200:date=Nov 20 2009, 10:40 PM:name=Dude)--><div class='quotetop'>QUOTE (Dude @ Nov 20 2009, 10:40 PM) <a href="index.php?act=findpost&pid=376200">[​IMG]</a></div><div class='quotemain'><!--quotec-->who is good with C<!--QuoteEnd--></div><!--QuoteEEnd-->
    Not so much that...

    Basically, if you show me code, I can probably understand it, but I can't really write code in a language I'm not familiar with.
    If I could find a good reference guide, I could probably teach myself.
     
  5. Melody the Sylveon

    Melody the Sylveon

    You're never too old to become your true self. Oldbie
    1,985
    61
    28
    healing
    Hey, I'm decent with C but I'm no good at text parsing. Maybe we could collaborate? :v:
     
  6. Dude

    Dude

    Tech Member
    3,138
    0
    16
    Southbridge, MA
    Random VR/AR trash
    Well I suppose it couldn't hurt to post the source to the program...

    Code (Text):
    1. /*
    2. ---------------------------------
    3. ASCInjector by Dude
    4. The purpose of this program is to take an ASC scenes generated with SADXMDL2_levelASC and modified in 3d studio max (or equivalent 3d package)
    5. into the sonic.exe (or sonic.exe derivative) that it originally came from.
    6. ----------------------------------
    7.  
    8. Special thanks to Ultima for telling me how to cast a sphere from a vertex array
    9. A pre-emptive special thanks to Hikaru for helping me debug my code, even though he hasn't actually done it yet. But I know he will =P
    10. */
    11. #include <stdio.h>
    12. #include <string.h>
    13. #include <errno.h>
    14. #include <stdlib.h>
    15. #include <windows.h> // there goes *nix capabilities LOL. Good thing linux sux
    16. // gerbilsoft reccomends "strtol()" from #libc in place of atoi()
    17.  
    18. //Typedefs
    19. typedef unsigned char byte;
    20. typedef unsigned short word;
    21. typedef unsigned int dword;
    22.  
    23. typedef signed char sbyte;
    24. typedef signed short sword;
    25. typedef signed int sdword;
    26.  
    27. #define KEY 0x400000&nbsp;&nbsp;//SONIC.EXE
    28. //#define KEY 0xC900000 // dreamcast stages
    29. int model_count = 0;
    30. int current_model = 0;
    31. int error = 0;
    32. dword colpointer;
    33.  
    34. /*#define KEY 0x10000000&nbsp;&nbsp;// CHRMODELS.DLL
    35.  
    36. RANGE is no longer checked for, so don't use it.
    37. --------------------
    38. #define RANGE 0x5C
    39. RANGE is 92 for STG in decimal
    40. --------------------
    41.  
    42. #define KEY 0xC900000 // dreamcast stages
    43. */
    44.  
    45. //SADXmdl structures;
    46. typedef struct COL // COL is mostly extraneous, we're only using it for it's seg pointer.
    47. {
    48. &nbsp;&nbsp;&nbsp;&nbsp;float x_pos;
    49. &nbsp;&nbsp;&nbsp;&nbsp;float y_pos;
    50. &nbsp;&nbsp;&nbsp;&nbsp;float z_pos;
    51. &nbsp;&nbsp;&nbsp;&nbsp;float radius; // could also be diameter?? we'll probably never know - this applies to ATTACH as well.
    52. &nbsp;&nbsp;&nbsp;&nbsp;dword null[2];
    53. &nbsp;&nbsp;&nbsp;&nbsp;dword seg;
    54. &nbsp;&nbsp;&nbsp;&nbsp;dword pad;
    55. &nbsp;&nbsp;&nbsp;&nbsp;dword suf_flags;
    56. } COL;
    57.  
    58. typedef struct MESH
    59. {
    60. &nbsp;&nbsp;&nbsp;&nbsp;word mat_id;
    61. &nbsp;&nbsp;&nbsp;&nbsp;word poly_total;
    62. &nbsp;&nbsp;&nbsp;&nbsp;dword poly;
    63. &nbsp;&nbsp;&nbsp;&nbsp;dword PAttr; //Dword?
    64. &nbsp;&nbsp;&nbsp;&nbsp;dword PNormal;
    65. &nbsp;&nbsp;&nbsp;&nbsp;dword VColor;
    66. &nbsp;&nbsp;&nbsp;&nbsp;dword UV;
    67. &nbsp;&nbsp;&nbsp;&nbsp;dword _null; // comment out for DC
    68. } MESH;
    69.  
    70. typedef struct VERTEX
    71. {
    72. &nbsp;&nbsp;&nbsp;&nbsp;float x;
    73. &nbsp;&nbsp;&nbsp;&nbsp;float y;
    74. &nbsp;&nbsp;&nbsp;&nbsp;float z;
    75. } VERTEX;
    76.  
    77. typedef struct ATTACH
    78. {
    79. &nbsp;&nbsp;&nbsp;&nbsp;dword vertex;
    80. &nbsp;&nbsp;&nbsp;&nbsp;dword normal;
    81. &nbsp;&nbsp;&nbsp;&nbsp;dword vertex_total;
    82. &nbsp;&nbsp;&nbsp;&nbsp;dword mesh;
    83. &nbsp;&nbsp;&nbsp;&nbsp;dword material;
    84. &nbsp;&nbsp;&nbsp;&nbsp;word mesh_total;
    85. &nbsp;&nbsp;&nbsp;&nbsp;word material_total;
    86. &nbsp;&nbsp;&nbsp;&nbsp;float center[3];
    87. &nbsp;&nbsp;&nbsp;&nbsp;float radius;
    88. &nbsp;&nbsp;&nbsp;&nbsp;dword _null;
    89. } ATTACH;
    90.  
    91. typedef struct SEG
    92. {
    93. &nbsp;&nbsp;&nbsp;&nbsp;dword type;
    94. &nbsp;&nbsp;&nbsp;&nbsp;dword attach;
    95. &nbsp;&nbsp;&nbsp;&nbsp;float pos[3];
    96. &nbsp;&nbsp;&nbsp;&nbsp;float rot[3];
    97. &nbsp;&nbsp;&nbsp;&nbsp;float scale[3];
    98. &nbsp;&nbsp;&nbsp;&nbsp;dword child;
    99. &nbsp;&nbsp;&nbsp;&nbsp;dword joint;
    100. } SEG;
    101.  
    102. int main()
    103. {
    104. &nbsp;&nbsp;&nbsp;&nbsp;// init win32 console API color
    105. &nbsp;&nbsp;&nbsp;&nbsp;HANDLE&nbsp;&nbsp;hConsole;
    106. &nbsp;&nbsp;&nbsp;&nbsp;hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
    107. &nbsp;&nbsp;&nbsp;&nbsp;
    108. &nbsp;&nbsp;&nbsp;&nbsp;//File access variables
    109. &nbsp;&nbsp;&nbsp;&nbsp;FILE *_fin;
    110. &nbsp;&nbsp;&nbsp;&nbsp;FILE *_fout;
    111. &nbsp;&nbsp;&nbsp;&nbsp;FILE *_log;
    112. &nbsp;&nbsp;&nbsp;&nbsp;char ascpath[1024]={0};
    113. &nbsp;&nbsp;&nbsp;&nbsp;char exepath[1024]={0};
    114. &nbsp;&nbsp;&nbsp;&nbsp;unsigned char ASCVersion[4]={0};
    115. &nbsp;&nbsp;&nbsp;&nbsp;char usebadver;
    116. &nbsp;&nbsp;&nbsp;&nbsp;unsigned long _fsize={0};
    117. &nbsp;&nbsp;&nbsp;&nbsp;
    118. &nbsp;&nbsp;&nbsp;&nbsp;// temp variables
    119. &nbsp;&nbsp;&nbsp;&nbsp;char geomheader[11]={0};
    120. &nbsp;&nbsp;&nbsp;&nbsp;dword count[4]; // increments
    121. &nbsp;&nbsp;&nbsp;&nbsp;dword total[4]; // totals
    122. &nbsp;&nbsp;&nbsp;&nbsp;dword offset[4]; // file offsets
    123. &nbsp;&nbsp;&nbsp;&nbsp;int match;
    124. &nbsp;&nbsp;&nbsp;&nbsp;int match2;
    125. &nbsp;&nbsp;&nbsp;&nbsp;unsigned char geombuffer[1024]={0};
    126. &nbsp;&nbsp;&nbsp;&nbsp;unsigned char varbuffer[1024]={0};
    127. &nbsp;&nbsp;&nbsp;&nbsp;float coordcpy[2];
    128. &nbsp;&nbsp;&nbsp;&nbsp;
    129. &nbsp;&nbsp;&nbsp;&nbsp;// SADX model parts
    130. &nbsp;&nbsp;&nbsp;&nbsp;SEG seg;
    131. &nbsp;&nbsp;&nbsp;&nbsp;ATTACH attach;
    132. &nbsp;&nbsp;&nbsp;&nbsp;VERTEX vertex;
    133. &nbsp;&nbsp;&nbsp;&nbsp;MESH mesh;
    134. &nbsp;&nbsp;&nbsp;&nbsp;COL col;
    135. &nbsp;&nbsp;&nbsp;&nbsp;
    136. &nbsp;&nbsp;&nbsp;&nbsp;_log = fopen("out.log", "w+");
    137. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (_log == NULL)
    138. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{
    139. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf("Error: logfile can't be opened.");
    140. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;exit (0);
    141. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}
    142. &nbsp;&nbsp;&nbsp;&nbsp;SetConsoleTextAttribute(hConsole, 2); // black on red?
    143. &nbsp;&nbsp;&nbsp;&nbsp;printf("================================================== \n");
    144. &nbsp;&nbsp;&nbsp;&nbsp;printf("| Dude's ASC injector program, use this to apply&nbsp;&nbsp;| \n");
    145. &nbsp;&nbsp;&nbsp;&nbsp;printf("| your exported ASC scene from 3dsmax into a sadx | \n");
    146. &nbsp;&nbsp;&nbsp;&nbsp;printf("| game executable.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;| \n");
    147. &nbsp;&nbsp;&nbsp;&nbsp;printf("================================================== \n \n \n");
    148. &nbsp;&nbsp;&nbsp;&nbsp;printf("Select a 3d scene to apply to a game executable: \n");
    149. &nbsp;&nbsp;&nbsp;&nbsp;scanf("%s", ascpath);
    150. &nbsp;&nbsp;&nbsp;&nbsp;printf("%s \n", ascpath);
    151. &nbsp;&nbsp;&nbsp;&nbsp;printf("Select an executable to inject the data into: \n");
    152. &nbsp;&nbsp;&nbsp;&nbsp;SetConsoleTextAttribute(hConsole, 12);
    153. &nbsp;&nbsp;&nbsp;&nbsp;printf("MAKE A BACKUP BEFORE RUNNING THIS PROGRAM! \n");
    154. &nbsp;&nbsp;&nbsp;&nbsp;SetConsoleTextAttribute(hConsole, 2);
    155. &nbsp;&nbsp;&nbsp;&nbsp;scanf("%s", exepath);
    156. &nbsp;&nbsp;&nbsp;&nbsp;
    157. &nbsp;&nbsp;&nbsp;&nbsp;// Does ASC pass validity checks?
    158. &nbsp;&nbsp;&nbsp;&nbsp;_fin = fopen(ascpath, "r");
    159. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (_fin == NULL)
    160. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{
    161. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf("Error: NULL input file\n");
    162. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;exit(0);
    163. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}
    164. &nbsp;&nbsp;&nbsp;&nbsp;fseek(_fin, 20, SEEK_SET); // seek to version number
    165. &nbsp;&nbsp;&nbsp;&nbsp;fread(ASCVersion, 3, 1, _fin); // load it into memory
    166. &nbsp;&nbsp;&nbsp;&nbsp;int v;
    167. &nbsp;&nbsp;&nbsp;&nbsp;v = atoi (ASCVersion);&nbsp;&nbsp;&nbsp;&nbsp;
    168. &nbsp;&nbsp;&nbsp;&nbsp;//printf("Converted ASCVersion is %d \n", v); // debugging output
    169. &nbsp;&nbsp;&nbsp;&nbsp;
    170. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (v != 110)
    171. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{
    172. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf("ASC Version mismatch... Continue? \n");
    173. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf("1 for yes, anything else for no\n");
    174. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;usebadver = 0;
    175. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;scanf("%d", usebadver);
    176. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (usebadver != 1)
    177. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{
    178. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf("User abort. \n");
    179. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;system("PAUSE");
    180. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;exit (0);
    181. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}
    182. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else
    183. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf("Mis-matched version numbers or extra data WILL corrupt your executable. \n");
    184. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf("If SADX crashes, check the file output for version mismatches. \n");
    185. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//break;
    186. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}
    187. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
    188. &nbsp;&nbsp;&nbsp;&nbsp;// Does EXE pass validity checks?
    189. &nbsp;&nbsp;&nbsp;&nbsp;_fout = fopen(exepath, "r+b");
    190. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (_fout == NULL)
    191. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{
    192. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf("Error: Output file doesn't exist! \n");
    193. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;system("PAUSE");
    194. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;exit (0);
    195. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}
    196. &nbsp;&nbsp;&nbsp;&nbsp;fseek(_fout, 0, SEEK_END);
    197. &nbsp;&nbsp;&nbsp;&nbsp;_fsize=ftell(_fout);&nbsp;&nbsp;&nbsp;&nbsp;
    198. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
    199. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (_fsize > 55549952)
    200. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{
    201. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf("Error: File is not a valid SONIC.EXE! (too big)\n");
    202. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;system("PAUSE");
    203. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;exit (0);
    204. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}
    205. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
    206. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (_fsize < 53000000)
    207. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{
    208. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf("Error: File is not a valid SONIC.EXE! (too small)\n");
    209. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;system("PAUSE");
    210. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;exit (0);
    211. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}
    212. &nbsp;&nbsp;&nbsp;&nbsp;printf("Valid SONIC.EXE!!! \n");
    213. &nbsp;&nbsp;&nbsp;&nbsp;// Everything passed the checks, we should be OK to proceed
    214. &nbsp;&nbsp;&nbsp;&nbsp;
    215. &nbsp;&nbsp;&nbsp;&nbsp;fseek(_fin, 0, SEEK_SET); // Go back to the beginning
    216. &nbsp;&nbsp;&nbsp;&nbsp;reset:
    217. &nbsp;&nbsp;&nbsp;&nbsp;while (!feof(_fin)) // Scanner works! Now it's time to process the data.
    218. &nbsp;&nbsp;&nbsp;&nbsp;{
    219. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fgets(geomheader, 80, _fin);
    220. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//printf("%s\n", geomheader);
    221. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;match = strncmp(geomheader, "*GEOMOBJECT", sizeof(geomheader));
    222. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (match == 0)
    223. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{
    224. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fseek(_fin, -11, SEEK_CUR); // adjust current address to match beginning of string comparison?
    225. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;offset[0]=ftell(_fin);
    226. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf("Valid GEOMOBJECT found at %d \n", offset[0]);
    227. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;
    228. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}
    229. &nbsp;&nbsp;&nbsp;&nbsp;}
    230. &nbsp;&nbsp;&nbsp;&nbsp;match=1; // set to false so we can get accurate results later
    231. &nbsp;&nbsp;&nbsp;&nbsp;//Insert GEOMOBJECT processing code here
    232. &nbsp;&nbsp;&nbsp;&nbsp;while (!feof(_fin))
    233. &nbsp;&nbsp;&nbsp;&nbsp;{
    234. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fgets(varbuffer, 19, _fin);
    235. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf("VARBUFFER IS %s \n", varbuffer);
    236. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;system("PAUSE");
    237. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;match = strncmp(varbuffer, "*NODE_NAME \"model_", 19);
    238. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fprintf(_log, "%d, \n", match);
    239. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (match ==0)
    240. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{
    241. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;offset[0] = ftell(_fin);
    242. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fgets(varbuffer, 10, _fin); // !!!!!!!!!!!!!!!!!!!!!!!!!! Come back and make sure this can be upped safely without breaking things.
    243. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;offset[1] = atoi (varbuffer);
    244. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf("%d \n", offset[1]);
    245. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;system("PAUSE");
    246. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}
    247. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;match2 = strncmp(varbuffer, "*GEOMOBJECT", sizeof(geomheader));
    248. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (match2 == 0)
    249. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{
    250. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SetConsoleTextAttribute(hConsole, 12);
    251. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf("Internal scanner has stepped over itself, cannot continue. \n");
    252. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;exit(0);
    253. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;
    254. &nbsp;&nbsp;&nbsp;&nbsp;}
    255. &nbsp;&nbsp;&nbsp;&nbsp;
    256. &nbsp;&nbsp;&nbsp;&nbsp;if (!feof(_fin))
    257. &nbsp;&nbsp;&nbsp;&nbsp;{
    258. &nbsp;&nbsp;&nbsp;&nbsp;goto reset;
    259. &nbsp;&nbsp;&nbsp;&nbsp;}
    260. &nbsp;&nbsp;&nbsp;&nbsp;printf("EOF Reached, closing...\n");
    261. &nbsp;&nbsp;&nbsp;&nbsp;fclose(_fin);
    262. &nbsp;&nbsp;&nbsp;&nbsp;fclose(_fout);
    263. &nbsp;&nbsp;&nbsp;&nbsp;system("PAUSE");
    264. &nbsp;&nbsp;&nbsp;&nbsp;return 1;
    265. };
    How it works right now is it reads the asc header and searches for its first *GEOMOBJECT. Once it finds this, it needs to find a *NODE_NAME and then take the numbers after "model_" and store those as a dword. Then take that dword and go to that offset in sonic.exe and so on and so forth. Right now the main problem I'm having is that it's not finding all of the node_name instances, its missing them for some reason I can't figure out.
     
  7. MainMemory

    MainMemory

    Kate the Wolf Tech Member
    4,551
    145
    43
    SonLVL
    Yeah, I have no idea what that means. I can tell generally what it's doing, and I can see where you're checking for it, but I have no idea how it works. :(

    Although, I've been inspired, and I am going to see if I can make Direct3D work for me, and make a model viewer. Either way, I'm probably going to make something to edit the values (incl. vertices) manually, using numbers.
     
  8. Dude

    Dude

    Tech Member
    3,138
    0
    16
    Southbridge, MA
    Random VR/AR trash
    This is sort of a plea to the community. I'd really like someone to find what's wrong with my code. An example file can be found at

    <a href="http://x-hax.cultnet.net/out.asc" target="_blank">http://x-hax.cultnet.net/out.asc</a> (it's a text file, openable in notepad)

    If someone with C skills can get the scanner to return every hit for the model names and the position data, I'd be able to handle the rest. But as it stands now, my program doesn't properly parse the file.
     
  9. Ultima

    Ultima

    Games Publisher Tech Member
    2,398
    1
    18
    London, England
    Publishing mobile games!
    <a href="http://www.gamedev.net/reference/articles/article1277.asp" target="_blank">http://www.gamedev.net/reference/articles/article1277.asp</a>

    This has some info on loading asc files, not sure if it's entirely relevant.
     
  10. Dude

    Dude

    Tech Member
    3,138
    0
    16
    Southbridge, MA
    Random VR/AR trash
    <!--quoteo(post=377205:date=Nov 24 2009, 03:43 AM:name=Ultima)--><div class='quotetop'>QUOTE (Ultima @ Nov 24 2009, 03:43 AM) <a href="index.php?act=findpost&pid=377205">[​IMG]</a></div><div class='quotemain'><!--quotec--><a href="http://www.gamedev.net/reference/articles/article1277.asp" target="_blank">http://www.gamedev.net/reference/articles/article1277.asp</a>

    This has some info on loading asc files, not sure if it's entirely relevant.<!--QuoteEnd--></div><!--QuoteEEnd-->


    Oh that's incredibly useful. Total's maxscript already serves as a decent sculpting/arranging tool, but it requires 3dsmax. Eventually, people will want a stand alone editor to work with. I'll probably just expand the asc program to include a renderer, then some basic editing and exporting functions. Not any time soon mind you, but I'm doing the research now.
     
  11. Dude

    Dude

    Tech Member
    3,138
    0
    16
    Southbridge, MA
    Random VR/AR trash
    Total's sadx exporter

    <a href="http://x-hax.cultnet.net/sadx_exporter.rar" target="_blank">http://x-hax.cultnet.net/SADX_Exporter.rar</a>

    This allows you to take a level ripped with my asc ripper, and re-arrange the elements without touching a hex editor. There are still small occasions where you'd want to use a hex edtior (model swaps and whatnot) but this script handles COL structs, seg structs, rotations and positions.

    I helped total with this and I can safely tell you this is one of the most awesome tools in a long time. It's a slow script, but it does almost all of the hex work for you.

    Currently, all you can do is re-arrange the scene and edit verts. You cannot edit meshes, or add/delete verts. Sorry, that functionality is alot more complex, but it will happen eventually. And be careful with this, its very easy to break things. Don't select an entire model at the vertex level and move it while leaving the pivot in its original position. Things will break. Think of it as the layout editor in SonEd, without art editing capabilities. You can re-arrange the tiles, but you can't edit the art (very much)

    We'll probably expand the script to export split meshes (so you can construct an entirely new mesh, and insert the split pieces into a padded space, essentially allowing you to make a 100% new level), and possibly even develop a script to edit SET files.
     
  12. Dude

    Dude

    Tech Member
    3,138
    0
    16
    Southbridge, MA
    Random VR/AR trash
    Bump, updated. This version exports ATTACH spheres, and fixes a bug with vertex output. Also, there's a checkbox to disable vertex output so you can save export time while just re-arranging things. I might make a tutorial for this but it's so damn easy I don't see why everyone isn't level editing yet.

    <a href="http://x-hax.cultnet.net/SADX_Exporter.rar" target="_blank">http://x-hax.cultnet.net/SADX_Exporter.rar</a>
     
  13. MainMemory

    MainMemory

    Kate the Wolf Tech Member
    4,551
    145
    43
    SonLVL
    <!--quoteo(post=378231:date=Nov 27 2009, 02:58 AM:name=Dude)--><div class='quotetop'>QUOTE (Dude @ Nov 27 2009, 02:58 AM) <a href="index.php?act=findpost&pid=378231">[​IMG]</a></div><div class='quotemain'><!--quotec-->I don't see why everyone isn't level editing yet.<!--QuoteEnd--></div><!--QuoteEEnd-->
    Maybe because some of us don't have 3DSMax. Like me. I'm sure I could find it if I looked.
     
  14. darkspines35

    darkspines35

    It's Easy Actually. No, seriously. Tech Member
    248
    0
    16
    .V.
    Sanik Adevnt Casters
    Thanks Dude. This will be very useful in the future. Planning on getting a release of what I've been working on out soon. Topic for it should be up later today.

    Edit: It works. Gotta be sure you make the SADX_E is capitilaized in the link.
     
  15. Dude

    Dude

    Tech Member
    3,138
    0
    16
    Southbridge, MA
    Random VR/AR trash
    Sorry about the broken link, I forgot the internets is case sensitive. I removed the old file to avoid confusion.
     
  16. Azu

    Azu

    I must be stupid. Member
    Dude, you should change your name to awesome. Can we eventually swap or add level geometry from other levels?
     
  17. Dude

    Dude

    Tech Member
    3,138
    0
    16
    Southbridge, MA
    Random VR/AR trash
    <!--quoteo(post=380530:date=Dec 3 2009, 01:17 AM:name=Azu)--><div class='quotetop'>QUOTE (Azu @ Dec 3 2009, 01:17 AM) <a href="index.php?act=findpost&pid=380530">[​IMG]</a></div><div class='quotemain'><!--quotec-->Dude, you should change your name to awesome. Can we eventually swap or add level geometry from other levels?<!--QuoteEnd--></div><!--QuoteEEnd-->

    You must be psychic, I'm working on tools right now. You'll either have to re-rip the levels or keep track of offsets yourself. Not hard to do once I make a tutorial. Don't forget the script I released earlier isn't 100% accurate at the moment. I think it's the rotation math that's wrong. 3d matricies fuck with my head.

    the 2 new tools I'll be releasing will:
    a. extract the model you choose from a sonic.exe
    b. fix ALL of the pointers so all you have to do is copy/paste the ported model into the place you told the program you would.
     
  18. Azu

    Azu

    I must be stupid. Member
    I'll wait for your tutorial.
     
  19. Dude

    Dude

    Tech Member
    3,138
    0
    16
    Southbridge, MA
    Random VR/AR trash
    Almost done with the auto porting code...
    [​IMG]
    model on the left was ported by hand, model on the right was ported using a program I'm writing...

    Yeah vertex colors are fucked up, but it doesn't crash!
     
  20. total

    total

    Member
    67
    0
    0
    Update.
    <a href="http://www.sendspace.com/file/05gux5" target="_blank">Download</a>
    There were small issues with negative rotation values, but now export is probably 100% accurate.

    PS: no custom meshes export yet, but it will be done eventually.
    PPS: "Now hurry up and make more sadx hacks damnit!" &copy; :)
     
Thread Status:
Not open for further replies.