<NME> main.cpp <BEF> #include <stdio.h> #include <stdlib.h> #include <fstream> #include <math.h> #include <string.h> #include "utils.h" #include "textures.h" #include "gameobjects.h" #include "tilemap.h" #include "d3darkmod.h" #include "SourceEngine.h" #include "scripting.h" #include "materials.h" #include "main.h" #include "asciimode.h" #include "gamestrings.h" #include "gamegraphics.h" #include "Conversations.h" //#include "fbxExport.h" #include "Unity.h" #include "hacking.h" using namespace std; texture *textureMasters; objectMaster *objectMasters; FILE *MAPFILE; extern int levelNo; extern int GAME; void ExtractSkills(); int graphics_file_no=-1; int graphics_mode; int BitMapSize=32; int panels = 0;//Panels.gr are a special case for extraction char Graphics_File[255]; char Graphics_Pal[255]; char path_uw0[100]; int BitMapSize = 32; short panels = 0;//Panels.gr are a special case for extraction char Graphics_File[255]; char Graphics_Pal[255]; char FileToOpen[255];//Generic use file char FileToOpen2[255];//Generic use file char TempOutFileName[255]; char auxPalPath[255]; char path_target_platform[100]; char OutFileName[255]; int critPal=0; int bytark=0; int BlocksToRepack=320;//UW2 blocks to repack FILE *f = NULL; if ((f = fopen("gamepaths.txt", "r")) == NULL) { FILE *f = NULL; /* if ((f = fopen("c:\\games\\uw2\\data\\lev.ark", "r")) == NULL) { printf("Could not open specified file\n"); return 0; } long fileSize = getFileSize(f); unsigned char *tmp_ark = new unsigned char[fileSize]; fread(tmp_ark, fileSize, 1, f); fclose(f); int datalen = 0; get_rwops_uw2dec(tmp_ark, 240, &datalen); return 0;*/ if ((f = fopen("gamepaths.txt", "r")) == NULL) { printf("Could not open specified file\n"); return 0; } fgets(path_uw0, 100, f); int ln = strlen(path_uw0) - 1; if (path_uw0[ln] == '\n') path_uw0[ln] = '\0'; fgets(path_uw1, 100, f); ln = strlen(path_uw1) - 1; if (path_uw1[ln] == '\n') path_uw1[ln] = '\0'; fgets(path_uw2, 100, f); ln = strlen(path_uw2) - 1; if (path_uw2[ln] == '\n') path_uw2[ln] = '\0'; fgets(path_shock, 100, f); ln = strlen(path_shock) - 1; if (path_shock[ln] == '\n') path_shock[ln] = '\0'; fgets(path_target_platform, 100, f); ln = strlen(path_target_platform) - 1; if (path_target_platform[ln] == '\n') path_target_platform[ln] = '\0'; const char *uw1_graphics_file[45]; const char *uw2_graphics_file[37]; uw1_graphics_file[0] = "F16.tr";// - Floor textures 16x16"); uw1_graphics_file[1] = "F32.tr";// - Floor textures 32x32\n"); uw1_graphics_file[2] = "W16.tr";// - Wall textures 16x16"); uw1_graphics_file[3] = "W64.tr";// - Wall textures 64x64\n"); uw1_graphics_file[4] = "3DWIN.GR"; uw1_graphics_file[5] = "ANIMO.GR"; uw1_graphics_file[6] = "ARMOR_F.GR"; uw1_graphics_file[7] = "ARMOR_G.GR"; uw1_graphics_file[8] = "BODIES.GR"; uw1_graphics_file[9] = "BUTTONS.GR"; uw1_graphics_file[10] = "CHAINS.GR"; uw1_graphics_file[11] = "CHARHEAD.GR"; uw1_graphics_file[12] = "CHRBTNS.GR"; uw1_graphics_file[13] = "COMPASS.GR"; uw1_graphics_file[14] = "CONVERSE.GR"; uw1_graphics_file[15] = "CURSORS.GR"; uw1_graphics_file[16] = "DOORS.GR"; uw1_graphics_file[17] = "DRAGONS.GR"; uw1_graphics_file[18] = "EYES.GR"; uw1_graphics_file[19] = "FLASKS.GR"; uw1_graphics_file[20] = "GENHEAD.GR"; uw1_graphics_file[21] = "HEADS.GR"; uw1_graphics_file[22] = "INV.GR"; uw1_graphics_file[23] = "LFTI.GR"; uw1_graphics_file[24] = "OBJECTS.GR"; uw1_graphics_file[25] = "OPTBN"; uw1_graphics_file[26] = "OPTB"; uw1_graphics_file[27] = "OPTBNS"; uw1_graphics_file[28] = "PANELS.GR"; uw1_graphics_file[29] = "POWER.GR"; uw1_graphics_file[30] = "QUEST.GR"; uw1_graphics_file[31] = "SCRLEDGE.GR"; uw1_graphics_file[32] = "SPELLS.GR"; uw1_graphics_file[33] = "TMFLAT.GR"; uw1_graphics_file[34] = "TMOBJ.GR"; uw1_graphics_file[35] = "WEAPONS.GR"; uw1_graphics_file[36] = "BLNKMAP.BYT"; uw1_graphics_file[37] = "CHARGEN.BYT"; uw1_graphics_file[38] = "CONV.BYT"; uw1_graphics_file[39] = "MAIN.BYT"; uw1_graphics_file[40] = "OPSCR.BYT"; uw1_graphics_file[41] = "PRES1.BYT"; uw1_graphics_file[42] = "PRES2.BYT"; uw1_graphics_file[43] = "WIN1.BYT"; uw1_graphics_file[44] = "WIN2.BYT"; uw2_graphics_file[0] = "T64.tr";//uw2 textures uw2_graphics_file[1] = "3DWIN.GR"; uw2_graphics_file[2] = "ANIMO.GR"; uw2_graphics_file[3] = "ARMOR_F.GR"; uw2_graphics_file[4] = "ARMOR_G.GR"; uw2_graphics_file[5] = "BODIES.GR"; uw2_graphics_file[6] = "BUTTONS.GR"; uw2_graphics_file[7] = "CHAINS.GR"; uw2_graphics_file[8] = "CHARHEAD.GR"; uw2_graphics_file[9] = "CHRBTNS.GR"; uw2_graphics_file[10] = "COMPASS.GR"; uw2_graphics_file[11] = "CONVERSE.GR"; uw2_graphics_file[12] = "CURSORS.GR"; uw2_graphics_file[13] = "DOORS.GR"; uw2_graphics_file[14] = "DRAGONS.GR"; uw2_graphics_file[15] = "EYES.GR"; uw2_graphics_file[16] = "FLASKS.GR"; uw2_graphics_file[17] = "GEMPT.GR"; uw2_graphics_file[18] = "GENHEAD.GR"; uw2_graphics_file[19] = "GHEAD.GR"; uw2_graphics_file[20] = "HEADS.GR"; uw2_graphics_file[21] = "INV.GR"; uw2_graphics_file[22] = "LFTI.GR"; uw2_graphics_file[23] = "OBJECTS.GR"; uw2_graphics_file[24] = "OPTBN"; uw2_graphics_file[25] = "OPTB"; uw2_graphics_file[26] = "OPTBNS"; uw2_graphics_file[27] = "PANELS.GR"; uw2_graphics_file[28] = "POWER.GR"; uw2_graphics_file[29] = "QUESTION.GR"; uw2_graphics_file[30] = "SCRLEDGE.GR"; uw2_graphics_file[31] = "SPELLS.GR"; uw2_graphics_file[32] = "TMFLAT.GR"; uw2_graphics_file[33] = "TMOBJ.GR"; uw2_graphics_file[34] = "VIEWS.GR"; uw2_graphics_file[35] = "WEAP.GR"; uw2_graphics_file[36] = "BYT.ARK"; //int game = SHOCK; //int game = UWDEMO; //int game = UW1; //int game = UW2; //int mode = D3_MODE; //int mode = ASCII_MODE; //int mode = STRINGS_EXTRACT_MODE; //int mode = BITMAP_EXTRACT_MODE; //int mode = SCRIPT_BUILD_MODE; //int mode = MATERIALS_BUILD_MODE; //int mode = CONVERSATION_MODE; //int mode = REPACK_MODE; //int mode= SOURCE_MODE; levelNo = -1; printf("Welcome to Underworld Exporter.\n"); printf("\nAvailable games\n"); printf("0) Ultima Underworld Demo (probably doesn't work!)\n"); printf("1) Ultima Underworld 1: The Stygian Abyss\n"); printf("2) Ultima Underworld 2: The Labyrinth of Worlds\n"); printf("3) System Shock 1\n"); printf("Please select a game.\n>"); scanf("%d",&game); if ((game < UWDEMO) || (game > SHOCK)) { printf("Invalid input. Bye."); return 0; } printf("Available Modes.\n"); printf("%d) Ascii dump.\n",ASCII_MODE); printf("%d) IDTech/DarkMod export.\n",D3_MODE); printf("%d) String Extraction\n",STRINGS_EXTRACT_MODE); printf("%d) Bitmap Extraction\n",BITMAP_EXTRACT_MODE); printf("%d) Script build(Also runs as part of IDTech export)\n",SCRIPT_BUILD_MODE); printf("%d) Support Materials Builder\n",MATERIALS_BUILD_MODE); printf("%d) Conversation code dump (unfinished!)\n",CONVERSATION_MODE); printf("%d) Repacker mode (UW2 and Shock only. Use at own risk!)\n",REPACK_MODE); printf("%d) Source Engine export\n",SOURCE_MODE); printf("%d) Critter Art Extract\n", CRITTER_EXTRACT_MODE); printf("%d) Cutscene Art Extract\n", CUTSCENE_EXTRACT_MODE); printf("Please select a mode.\n>"); scanf("%d", &mode); if ((mode < 0) || (mode > 10)) { printf("Invalid input. Bye."); return 0; } switch (mode) { case ASCII_MODE: case D3_MODE: case SOURCE_MODE: case SCRIPT_BUILD_MODE: case REPACK_MODE: { switch (game) { case UWDEMO: sprintf_s(GameFilePath, 255, "%s\\level13.st", path_uw0); break; case UW1: case UW2: printf("\nPick a level archive or save game to open\n"); for (int i = 0; i < 6; i++) { printf("%d) %s\n",i,uw_game_files[i]); } if ((game==UW2) && (mode==REPACK_MODE)) { printf("%d) %s\n",6,uw_game_files[6]); } printf(">"); scanf("%d", &gamefile); if ((gamefile < 0) || (gamefile >= 7)) { printf("Invalid input. Bye."); return 0; } if(game==UW1) { sprintf_s(GameFilePath, 255, "%s\\%s", path_uw1, uw_game_files[gamefile]); } else { sprintf_s(GameFilePath, 255, "%s\\%s", path_uw2, uw_game_files[gamefile]); } break; case SHOCK: printf("\nPick a level archive or save game to open\n"); for (int i = 0; i < 9; i++) { printf("%d) %s\n", i, shock_game_files[i]); } printf(">"); scanf("%d", &gamefile); if ((gamefile < 0) || (gamefile >= 10)) { printf("Invalid input. Bye."); return 0; } sprintf_s(GameFilePath, 255, "%s\\%s", path_shock, shock_game_files[gamefile]); break; } if (mode !=REPACK_MODE) { switch (game) { case UWDEMO: levelNo = 0; //only possible value break; case UW1://Print list of UW1 levels. printf("\nPick a level.\n"); printf("0)Entrance level.\n"); printf("1)Domain of the Mountainmen.\n"); printf("2)The Swamp and Lizardmen.\n"); printf("3)Trolls and Knights.\n"); printf("4)Catacombs and banquet halls.\n"); printf("5)The Seers.\n"); printf("6)Tybals Lair.\n"); printf("7)The Volcano.\n"); printf("8)Ethereal Void.\n"); printf(">"); scanf("%d", &levelNo); if ((levelNo < 0) || (levelNo > 9)) { printf("Invalid input. Bye."); return 0; } break; case UW2: printf("\nPick a level\n"); printf("0 - 4 Britannia\n"); printf("8 - 15 Prison Tower\n"); printf("16 - 17 Killorn Keep\n"); printf("24 - 25 Ice Cavern\n"); printf("32 - 33 Talorus\n"); printf("40 - 47 Academy\n"); printf("48 - 51 Tomb\n"); printf("56 - 58 Pits\n"); printf("64 - 72 Void (65 is stickman level)\n"); printf(">"); scanf("%d", &levelNo); if (!( ((levelNo >= 0) && (levelNo <= 4)) || ((levelNo >= 8) && (levelNo <= 15)) || ((levelNo >= 16) && (levelNo <= 17)) || ((levelNo >= 24) && (levelNo <= 25)) || ((levelNo >= 32) && (levelNo <= 33)) || ((levelNo >= 40) && (levelNo <= 47)) || ((levelNo >= 48) && (levelNo <= 51)) || ((levelNo >= 56) && (levelNo <= 58)) || ((levelNo >= 64) && (levelNo <= 72)) )) { printf("Invalid input. Bye."); return 0; } break; case SHOCK: printf("\nPick a level (need to dblchk these)\n"); printf("0)Reactor\n"); printf("1)Med SCI\n"); printf("2)Research\n"); printf("3)Maintenance\n"); printf("4)Storage\n"); printf("5)Flight Deck\n"); printf("6)Executive\n"); printf("7)System Engineering\n"); printf("8)Security\n"); printf("9)Bridge\n"); printf("10)Cyberspace 1 (Shodan)\n"); printf("11)Grove 1\n"); printf("12)Grove 1\n"); printf("13)Grove 1\n"); printf("14)Cyberspace 2\n"); printf("15)Cyberspace 3\n"); printf(">"); scanf("%d", &levelNo); if ((levelNo < 0) || (levelNo > 15)) { printf("Invalid input. Bye."); return 0; } break; } printf("Enter a filename for output (%s\\[filename].map)\n>", path_target_platform); scanf("%s", TempOutFileName); sprintf_s(OutFileName, 255, "%s\\%s", path_target_platform, TempOutFileName); } else { switch (game) { case UW2: printf("Enter a filename for repacking into (%s\\data\\[filename].ark)\n>", path_uw2); scanf("%s", TempOutFileName); sprintf_s(OutFileName, 255, "%s\\data\\%s.ark", path_uw2, TempOutFileName); break; case SHOCK: printf("Enter a filename for repacking into (%s\\[filename].data)\n>", path_shock); scanf("%s", TempOutFileName); sprintf_s(OutFileName, 255, "%s\\res\\data\\%s.ark", path_target_platform, TempOutFileName); break; default: printf("\nInvalid game for repacking. Goodbye"); return 0; } } break; } case BITMAP_EXTRACT_MODE: switch (game) { case UWDEMO: printf("\nCome back later...\n"); return 0; break; case UW1: for (int i = 0; i < 45; i++) { printf("%d) %s",i, uw1_graphics_file[i]); if (i % 2 == 0) { printf("\t"); } else { printf("\n"); } } printf("\nPick a file\n>"); scanf("%d", &graphics_file_no); if ((graphics_file_no < 0) || (graphics_file_no > 44)) { printf("Invalid input. Bye."); return 0; } sprintf_s(Graphics_File, 255, "%s\\data\\%s", path_uw1, uw1_graphics_file[graphics_file_no]); sprintf_s(Graphics_Pal, 255, "%s\\data\\pals.dat", path_uw1); sprintf_s(auxPalPath, 255, "%s\\%s", path_uw1, AUXILARY_PAL_FILE); if (graphics_file_no <= 3) { graphics_mode = UW_GRAPHICS_TEXTURES; switch (graphics_file_no) { case 0: BitMapSize=16; break; case 1: BitMapSize = 32; break; case 2: BitMapSize = 16; break; case 3: BitMapSize = 64; break; } } else if (graphics_file_no <= 35) { if (graphics_file_no == 27)//Panels { panels=1; } graphics_mode = UW_GRAPHICS_GR; } else { graphics_mode = UW_GRAPHICS_BITMAPS; } break; case UW2: for (int i = 0; i < 37; i++) { printf("%d) %s", i, uw2_graphics_file[i]); if (i % 2 == 0) { printf("\t"); } else { printf("\n"); } } printf("\nPick a file\n>"); scanf("%d", &graphics_file_no); if ((graphics_file_no < 0) || (graphics_file_no > 36)) { printf("Invalid input. Bye."); return 0; } if (graphics_file_no == 36) {//UW2 Byt ark bytark=1; } sprintf_s(Graphics_File, 255, "%s\\data\\%s", path_uw2, uw2_graphics_file[graphics_file_no]); sprintf_s(Graphics_Pal, 255, "%s\\data\\pals.dat", path_uw2); sprintf_s(auxPalPath, 255, "%s\\%s", path_uw2, AUXILARY_PAL_FILE); if (graphics_file_no <= 0) { graphics_mode = UW_GRAPHICS_TEXTURES; BitMapSize = 64; } else { graphics_mode = UW_GRAPHICS_GR; if (graphics_file_no == 28)//Panels { panels = 1;//special case due to file headers } } break; case SHOCK: printf("\nI don't have a graphics extractor for System Shock as part of this program yet. You'll have to find one yourself.\n"); return 0; } printf("\nEnter a palette number to use.(0 to 7)\n>"); scanf("%d", &critPal); printf("Enter a filename for output ([filename]_###.bmp)\n>"); scanf("%s", OutFileName); break; case STRINGS_EXTRACT_MODE: switch (game) { case UWDEMO: sprintf_s(GameFilePath, 255, "%s\\%s", path_uw0, UW1_STRINGS_FILE); break; case UW1: sprintf_s(GameFilePath, 255, "%s\\%s", path_uw1, UW1_STRINGS_FILE); break; case UW2: sprintf_s(GameFilePath, 255, "%s\\%s", path_uw2, UW2_STRINGS_FILE); break; case SHOCK: sprintf_s(GameFilePath, 255, "%s\\%s", path_shock, SHOCK_STRINGS_FILE); break; } break; case MATERIALS_BUILD_MODE: break; case CRITTER_EXTRACT_MODE: if (game == SHOCK) { printf("\nI don't have a graphics extractor for System Shock as part of this program. You'll have to find one yourself.\n"); return 0; } printf("\nType a critter filename for extraction from. gamepath\crit\\[filename]\n"); scanf("%s",TempOutFileName); switch (game) { case UWDEMO: sprintf_s(fileCrit, 255, "%s\\crit\\%s", path_uw0, TempOutFileName); sprintf_s(fileAssoc, 255, "%s\\%s", path_uw0, UW1_CRITTER_ASSOC); sprintf_s(Graphics_Pal, 255, "%s\\data\\pals.dat", path_uw0); sprintf_s(auxPalPath, 255, "%s\\%s", path_uw0, AUXILARY_PAL_FILE); break; case UW1: sprintf_s(fileCrit, 255, "%s\\crit\\%s", path_uw1, TempOutFileName); sprintf_s(fileAssoc, 255, "%s\\%s", path_uw1, UW1_CRITTER_ASSOC); sprintf_s(Graphics_Pal, 255, "%s\\data\\pals.dat", path_uw1); sprintf_s(auxPalPath, 255, "%s\\%s", path_uw1, AUXILARY_PAL_FILE); break; case UW2: sprintf_s(fileCrit, 255, "%s\\crit\\%s", path_uw2, TempOutFileName); sprintf_s(fileAssoc, 255, "%s\\%s", path_uw2, UW2_CRITTER_ASSOC); sprintf_s(Graphics_Pal, 255, "%s\\data\\pals.dat", path_uw2); sprintf_s(auxPalPath, 255, "%s\\%s", path_uw2, AUXILARY_PAL_FILE); break; } printf("\nEnter a palette number to use.(0 to 3)\n>"); scanf("%d", &critPal); printf("Enter a filename for output ([filename]_###.bmp)\n>"); scanf("%s", OutFileName); break; case CUTSCENE_EXTRACT_MODE: if (game == SHOCK) { printf("\nI don't have a graphics extractor for System Shock as part of this program. You'll have to find one yourself.\n"); return 0; } printf("\nType a cutscene filename for extraction from. gamedata\\cuts\\[filename]\n"); scanf("%s", TempOutFileName); switch (game) { case UWDEMO: sprintf_s(Graphics_File, 255, "%s\\cuts\\%s", path_uw0, TempOutFileName); break; case UW1: sprintf_s(Graphics_File, 255, "%s\\cuts\\%s", path_uw1, TempOutFileName); break; case UW2: sprintf_s(Graphics_File, 255, "%s\\cuts\\%s", path_uw2, TempOutFileName); break; } printf("Enter a filename for output ([filename]_###.bmp)\n>"); scanf("%s", OutFileName); break; case CONVERSATION_MODE: break; } GAME = game; switch (game) { const char *uw_comp_file; const char *uw_obj_prop_file; uw_comp_file = "DATA\\comobj.dat"; uw_obj_prop_file = "DATA\\Objects.dat"; case SHOCK: {BrushSizeX=120;BrushSizeY=120;BrushSizeZ=15;break;}//To ease on the steepness of some slopes that are impassible } //int NoOfLevels=80; //uw1 has 9, uw2 has 80(kind of), shock has 15, uw demo has 0. Level no 0 is the first level. LoadConfig(game,mode); levelNo = -1; if (true) { printf("Welcome to Underworld Exporter.\n"); printf("\nAvailable games\n"); printf("0) Ultima Underworld Demo (probably doesn't work!)\n"); printf("1) Ultima Underworld 1: The Stygian Abyss\n"); printf("2) Ultima Underworld 2: The Labyrinth of Worlds\n"); printf("3) System Shock 1\n"); printf("Please select a game.\n>"); scanf("%d", &game); if ((game < UWDEMO) || (game > SHOCK)) { printf("Invalid input. Bye."); return 0; } printf("Available Modes.\n"); printf("%d) Ascii dump.\n", ASCII_MODE); printf("%d) IDTech/DarkMod export.\n", D3_MODE); printf("%d) String Extraction\n", STRINGS_EXTRACT_MODE); { if (bytark!=1) { extractTextureBitmap(-1, Graphics_File, Graphics_Pal, critPal, BitMapSize, graphics_mode, OutFileName,auxPalPath); } else { extractUW2Bitmaps(Graphics_File,Graphics_Pal,critPal,OutFileName); } } else { extractPanels(-1, Graphics_File, Graphics_Pal, 0, BitMapSize, UW_GRAPHICS_GR, game,OutFileName); } break; case CRITTER_EXTRACT_MODE: extractCritters(fileAssoc, fileCrit, Graphics_Pal, critPal, 64, UW_GRAPHICS_GR,game, 0, OutFileName); break; case CUTSCENE_EXTRACT_MODE: load_cuts_anim(Graphics_File, OutFileName); break; case MATERIALS_BUILD_MODE: //BuildXDataFile(game); switch (mode) { case ASCII_MODE: case D3_MODE: case SOURCE_MODE: case SCRIPT_BUILD_MODE: case REPACK_MODE: case FBX_MODE: case UNITY_MODE: case UNITY_TILEMAP_MODE: { switch (game) { case UWDEMO: sprintf_s(GameFilePath, 255, "%s", path_uw0); break; case UW1: } else { if (game == SHOCK) { RepackShock(GameFilePath, OutFileName); } { printf("%d) %s\n", 6, uw_game_files[6]); } printf(">"); scanf("%d", &gamefile); if ((gamefile < 0) || (gamefile >= 7)) { printf("Invalid input. Bye."); return 0; } if (game == UW1) { sprintf_s(GameFilePath, 255, "%s\\%s", path_uw1, uw_game_files[gamefile]); } else { sprintf_s(GameFilePath, 255, "%s\\%s", path_uw2, uw_game_files[gamefile]); } break; case SHOCK: printf("\nPick a level archive or save game to open\n"); for (int i = 0; i < 9; i++) { printf("%d) %s\n", i, shock_game_files[i]); } printf(">"); scanf("%d", &gamefile); if ((gamefile < 0) || (gamefile >= 10)) { printf("Invalid input. Bye."); return 0; } sprintf_s(GameFilePath, 255, "%s\\%s", path_shock, shock_game_files[gamefile]); break; } if (mode != REPACK_MODE) { switch (game) { case UWDEMO: levelNo = 0; //only possible value break; case UW1://Print list of UW1 levels. printf("\nPick a level.\n"); printf("0)Entrance level.\n"); printf("1)Domain of the Mountainmen.\n"); printf("2)The Swamp and Lizardmen.\n"); printf("3)Trolls and Knights.\n"); printf("4)Catacombs and banquet halls.\n"); printf("5)The Seers.\n"); printf("6)Tybals Lair.\n"); printf("7)The Volcano.\n"); printf("8)Ethereal Void.\n"); printf(">"); scanf("%d", &levelNo); if ((levelNo < 0) || (levelNo > 9)) { printf("Invalid input. Bye."); return 0; } break; case UW2: printf("\nPick a level\n"); printf("0 - 4 Britannia\n"); printf("8 - 15 Prison Tower\n"); printf("16 - 17 Killorn Keep\n"); printf("24 - 25 Ice Cavern\n"); printf("32 - 33 Talorus\n"); printf("40 - 47 Academy\n"); printf("48 - 51 Tomb\n"); printf("56 - 58 Pits\n"); printf("64 - 72 Void (65 is stickman level, 66 scint vault)\n"); printf(">"); scanf("%d", &levelNo); if (!( ((levelNo >= 0) && (levelNo <= 4)) || ((levelNo >= 8) && (levelNo <= 15)) || ((levelNo >= 16) && (levelNo <= 17)) || ((levelNo >= 24) && (levelNo <= 25)) || ((levelNo >= 32) && (levelNo <= 33)) || ((levelNo >= 40) && (levelNo <= 47)) || ((levelNo >= 48) && (levelNo <= 51)) || ((levelNo >= 56) && (levelNo <= 58)) || ((levelNo >= 64) && (levelNo <= 72)) )) { printf("Invalid input. Bye."); return 0; } break; case SHOCK: printf("\nPick a level (need to dblchk these)\n"); printf("0)Reactor\n"); printf("1)Med SCI\n"); printf("2)Research\n"); printf("3)Maintenance\n"); printf("4)Storage\n"); printf("5)Flight Deck\n"); printf("6)Executive\n"); printf("7)System Engineering\n"); printf("8)Security\n"); printf("9)Bridge\n"); printf("10)Cyberspace 1 (Shodan)\n"); printf("11)Grove 1\n"); printf("12)Grove 1\n"); printf("13)Grove 1\n"); printf("14)Cyberspace 2\n"); printf("15)Cyberspace 3\n"); printf(">"); scanf("%d", &levelNo); if ((levelNo < 0) || (levelNo > 15)) { printf("Invalid input. Bye."); return 0; } break; } printf("Enter a filename for output (%s\\[filename].map)\n>", path_target_platform); scanf("%s", TempOutFileName); sprintf_s(OutFileName, 255, "%s\\%s", path_target_platform, TempOutFileName); } else { switch (game) { case UW2: printf("Enter a filename for repacking into (%s\\data\\[filename].ark)\n>", path_uw2); scanf("%s", TempOutFileName); sprintf_s(OutFileName, 255, "%s\\data\\%s.ark", path_uw2, TempOutFileName); break; case SHOCK: printf("Enter a filename for repacking into (%s\\[filename].data)\n>", path_shock); scanf("%s", TempOutFileName); sprintf_s(OutFileName, 255, "%s\\res\\data\\%s.ark", path_shock, TempOutFileName); break; default: printf("\nInvalid game for repacking. Goodbye"); return 0; } } break; } case BITMAP_EXTRACT_MODE: case FONT_EXTRACT_MODE: if (mode == FONT_EXTRACT_MODE){ game = SHOCK; } switch (game) { case UWDEMO: for (int i = 0; i < 44; i++) { printf("%d) %s", i, uw0_graphics_file[i]); if (i % 2 == 0) { printf("\t\t"); } else { printf("\n"); } } printf("\nPick a file\n>"); scanf("%d", &graphics_file_no); if ((graphics_file_no < 0) || (graphics_file_no > 43)) { printf("Invalid input. Bye."); return 0; } sprintf_s(Graphics_File, 255, "%s\\%s", path_uw0, uw0_graphics_file[graphics_file_no]); sprintf_s(Graphics_Pal, 255, "%s\\data\\pals.dat", path_uw0); sprintf_s(auxPalPath, 255, "%s\\%s", path_uw0, AUXILARY_PAL_FILE); if (graphics_file_no <= 3) { graphics_mode = UW_GRAPHICS_TEXTURES; switch (graphics_file_no) { case 0: BitMapSize = 16; break; case 1: BitMapSize = 32; break; case 2: BitMapSize = 16; break; case 3: BitMapSize = 64; break; } } else if (graphics_file_no <= 35) { if ((game==UW1) && (graphics_file_no == 28))//Panels { panels = 1; } if ((game == UW2) && (graphics_file_no == 27))//Panels { panels = 1; } graphics_mode = UW_GRAPHICS_GR; } else { graphics_mode = UW_GRAPHICS_BITMAPS; } break; case UW1: for (int i = 0; i < 45; i++) { printf("%d) %s", i, uw1_graphics_file[i]); if (i % 2 == 0) { printf("\t\t"); } else { printf("\n"); } } printf("\nPick a file\n>"); scanf("%d", &graphics_file_no); if ((graphics_file_no < 0) || (graphics_file_no > 44)) { printf("Invalid input. Bye."); return 0; } sprintf_s(Graphics_File, 255, "%s\\%s", path_uw1, uw1_graphics_file[graphics_file_no]); sprintf_s(Graphics_Pal, 255, "%s\\data\\pals.dat", path_uw1); sprintf_s(auxPalPath, 255, "%s\\%s", path_uw1, AUXILARY_PAL_FILE); if (graphics_file_no <= 3) { graphics_mode = UW_GRAPHICS_TEXTURES; switch (graphics_file_no) { case 0: BitMapSize = 16; break; case 1: BitMapSize = 32; break; case 2: BitMapSize = 16; break; case 3: BitMapSize = 64; break; } } else if (graphics_file_no <= 35) { if ( (game== UW1) && (graphics_file_no == 28))//Panels { panels = 1; } graphics_mode = UW_GRAPHICS_GR; } else { graphics_mode = UW_GRAPHICS_BITMAPS; } break; case UW2: for (int i = 0; i < 45; i++) { printf("%d) %s", i, uw2_graphics_file[i]); if (i % 2 == 0) { printf("\t\t"); } else { printf("\n"); } } printf("\nPick a file\n>"); scanf("%d", &graphics_file_no); if ((graphics_file_no < 0) || (graphics_file_no > 45)) { printf("Invalid input. Bye."); return 0; } if (graphics_file_no == 36) {//UW2 Byt ark bytark = 1; } sprintf_s(Graphics_File, 255, "%s\\%s", path_uw2, uw2_graphics_file[graphics_file_no]); sprintf_s(Graphics_Pal, 255, "%s\\data\\pals.dat", path_uw2); sprintf_s(auxPalPath, 255, "%s\\%s", path_uw2, AUXILARY_PAL_FILE); if (graphics_file_no <= 0) {//only on texture file in uw2 graphics_mode = UW_GRAPHICS_TEXTURES; BitMapSize = 64; } else if (graphics_file_no >= 37) {//Byt files in cuts dir graphics_mode = UW_GRAPHICS_BITMAPS; } else { graphics_mode = UW_GRAPHICS_GR; if ((game == UW1) && (graphics_file_no == 28))//Panels { panels = 1;//special case due to file headers } } break; case SHOCK: for (int i = 0; i < 18; i++) { printf("%d) %s", i, shock_graphics_file[i]); if (i % 2 == 0) { printf("\t\t"); } else { printf("\n"); } } printf("\nPick a file\n>"); scanf("%d", &graphics_file_no); if ((graphics_file_no < 0) || (graphics_file_no > 18)) { printf("Invalid input. Bye."); return 0; } sprintf_s(Graphics_File, 255, "%s\\%s", path_shock, shock_graphics_file[graphics_file_no]); for (int i = 0; i < 3; i++) { printf("%d) %s\n", i, shock_pal_file[i]); } printf("\nPick a file\n>"); scanf("%d", &graphics_file_no); if ((graphics_file_no < 0) || (graphics_file_no > 3)) { printf("Invalid input. Bye."); return 0; } sprintf_s(Graphics_Pal, 255, "%s\\%s", path_shock, shock_pal_file[graphics_file_no]); //return 0; } printf("\nEnter a palette number to use.(Typically 0 to 7)\n>"); scanf("%d", &critPal); printf("\nEnter a file format to use.\n0) BMP\n1) TGA\n>"); scanf("%d", &useTGA); if (useTGA == 1) { printf("Enter a filename for output ([filename]_###.tga)\n>"); } else { printf("Enter a filename for output ([filename]_###.bmp)\n>"); } scanf("%s", OutFileName); break; case STRINGS_EXTRACT_MODE: switch (game) { case UWDEMO: sprintf_s(GameFilePath, 255, "%s\\%s", path_uw0, UW1_STRINGS_FILE); break; case UW1: sprintf_s(GameFilePath, 255, "%s\\%s", path_uw1, UW1_STRINGS_FILE); break; case UW2: sprintf_s(GameFilePath, 255, "%s\\%s", path_uw2, UW2_STRINGS_FILE); break; case SHOCK: sprintf_s(GameFilePath, 255, "%s\\%s", path_shock, SHOCK_STRINGS_FILE); break; } break; case MATERIALS_BUILD_MODE: break; case CRITTER_EXTRACT_MODE: if (game == SHOCK) { printf("\nI don't have a graphics extractor for System Shock as part of this program. You'll have to find one yourself.\n"); return 0; } printf("\nType a critter filename for extraction from. gamepath\crit\\[filename]\n"); scanf("%s", TempOutFileName); switch (game) { case UWDEMO: sprintf_s(fileCrit, 255, "%s\\crit\\%s", path_uw0, TempOutFileName); sprintf_s(fileCrit, 255, "%s\\crit\\", path_uw0); sprintf_s(fileAssoc, 255, "%s\\%s", path_uw0, UW0_CRITTER_ASSOC); sprintf_s(Graphics_Pal, 255, "%s\\data\\pals.dat", path_uw1); sprintf_s(auxPalPath, 255, "%s\\%s", path_uw0, AUXILARY_PAL_FILE); break; case UW1: //sprintf_s(fileCrit, 255, "%s\\crit\\%s", path_uw1, TempOutFileName); sprintf_s(fileCrit, 255, "%s\\crit\\", path_uw1); sprintf_s(fileAssoc, 255, "%s\\%s", path_uw1, UW1_CRITTER_ASSOC); sprintf_s(Graphics_Pal, 255, "%s\\data\\pals.dat", path_uw1); sprintf_s(auxPalPath, 255, "%s\\%s", path_uw1, AUXILARY_PAL_FILE); break; case UW2: //sprintf_s(fileCrit, 255, "%s\\crit\\%s", path_uw2, TempOutFileName); sprintf_s(fileCrit, 255, "%s\\crit\\", path_uw2); sprintf_s(fileAssoc, 255, "%s\\%s", path_uw2, UW2_CRITTER_ASSOC); sprintf_s(Graphics_Pal, 255, "%s\\data\\pals.dat", path_uw2); sprintf_s(auxPalPath, 255, "%s\\%s", path_uw2, AUXILARY_PAL_FILE); break; } printf("\nEnter a palette number to use.(0 to 3)\n>"); scanf("%d", &critPal); printf("\nEnter a file format to use.\n0) BMP\n1) TGA\n>"); scanf("%d", &useTGA); if (useTGA == 1) { printf("Enter a filename for output ([filename]_###.tga)\n>"); } else { printf("Enter a filename for output ([filename]_###.bmp)\n>"); } scanf("%s", OutFileName); break; case CUTSCENE_EXTRACT_MODE: if (game == SHOCK) { for (int i = 0; i < 3; i++) { printf("%d) %s", i, shock_cuts_file[i]); if (i % 2 == 0) { printf("\t\t"); } else { printf("\n"); } } printf("\nPick a file\n>"); scanf("%d", &graphics_file_no); if ((graphics_file_no < 0) || (graphics_file_no > 3)) { printf("Invalid input. Bye."); return 0; } sprintf_s(Graphics_File, 255, "%s\\%s", path_shock, shock_cuts_file[graphics_file_no]); for (int i = 0; i < 3; i++) { printf("%d) %s\n", i, shock_pal_file[i]); } printf("\nPick a file\n>"); scanf("%d", &graphics_file_no); if ((graphics_file_no < 0) || (graphics_file_no > 3)) { printf("Invalid input. Bye."); return 0; } sprintf_s(Graphics_Pal, 255, "%s\\%s", path_shock, shock_pal_file[graphics_file_no]); } else { printf("\nType a cutscene filename for extraction from. gamedata\\cuts\\[filename]\n"); scanf("%s", TempOutFileName); switch (game) { case UWDEMO: sprintf_s(Graphics_File, 255, "%s\\cuts\\%s", path_uw0, TempOutFileName); break; case UW1: sprintf_s(Graphics_File, 255, "%s\\cuts\\%s", path_uw1, TempOutFileName); break; case UW2: sprintf_s(Graphics_File, 255, "%s\\cuts\\%s", path_uw2, TempOutFileName); break; } } //printf("\nEnter a file format to use.\n0) BMP\n1) TGA\n>"); //scanf("%d", &useTGA); if (useTGA == 1) { printf("Enter a filename for output ([filename]_###.tga)\n>"); } else { printf("Enter a filename for output ([filename]_###.bmp)\n>"); } scanf("%s", OutFileName); break; case CONVERSATION_MODE: break; case SKILLS_EXTRACT_MODE: break; } } else { printf("commandline args processing eventually"); } GAME = game; switch (game) { case UWDEMO: case UW1: case UW2: {BrushSizeX = 120; BrushSizeY = 120; BrushSizeZ = 15; break; } case SHOCK: {BrushSizeX = 120; BrushSizeY = 120; BrushSizeZ = 15; break; }//To ease on the steepness of some slopes that are impassible } LoadConfig(game, mode); char Logfile[255]; strcpy_s(Logfile, LOGFILENAME); //sprintf_s(Logfile, 255, "%s", LOGFILENAME); if (fopen_s(&LOGFILE, Logfile, "w") != 0) { printf("Unable to create output file for logfile"); return 0; } switch (mode) { case D3_MODE: case ASCII_MODE: case SCRIPT_BUILD_MODE: case SOURCE_MODE: case FBX_MODE: case UNITY_MODE: case UNITY_TILEMAP_MODE: printf("\n================Game %d==Level %d==Mode %d===================\n", game, levelNo, mode); exportMaps(game, mode, levelNo, OutFileName, GameFilePath); break; case STRINGS_EXTRACT_MODE: if (game == SHOCK) { unpackStringsShock(GameFilePath); } else { unpackStrings(game, GameFilePath); } break; case BITMAP_EXTRACT_MODE: if (game != SHOCK) { if (panels == 0) { if (bytark != 1) { //for (int f = 0; f < 8; f++) // { // sprintf(OutFileName, "%d",f); //extractTextureBitmap(-1, Graphics_File, Graphics_Pal, f, BitMapSize, graphics_mode, OutFileName, auxPalPath, useTGA); if ((graphics_file_no == 35) && (1))//Weapons { char WeaponAnims[255]; if (game==UW2) { sprintf_s(auxPalPath, 255, "%s\\data\\Weap.cm", path_uw2); sprintf_s(WeaponAnims, 255, "%s\\data\\Weap.dat", path_uw2);//TODO:Support other games properly! } else { sprintf_s(auxPalPath, 255, "%s\\data\\Weapons.cm", path_uw1); sprintf_s(WeaponAnims, 255, "%s\\data\\Weapons.dat", path_uw1); } ExtractWeaponAnimations(-1, Graphics_File, Graphics_Pal, critPal, BitMapSize, graphics_mode, OutFileName, auxPalPath, WeaponAnims, useTGA,game); } else { extractTextureBitmap(-1, Graphics_File, Graphics_Pal, critPal, BitMapSize, graphics_mode, OutFileName, auxPalPath, useTGA); } // } } else { extractUW2Bitmaps(Graphics_File, Graphics_Pal, critPal, OutFileName, useTGA); } } else { extractPanels(-1, Graphics_File, Graphics_Pal, 0, BitMapSize, UW_GRAPHICS_GR, game, OutFileName, useTGA); } } else { //sprintf_s(Graphics_File, 255, testfile, path_uw2); ExtractShockGraphics(Graphics_File, Graphics_Pal, critPal, OutFileName, useTGA); } break; case FONT_EXTRACT_MODE: ExtractShockFont(Graphics_File, Graphics_Pal, critPal, OutFileName, useTGA); break; case CRITTER_EXTRACT_MODE: switch (game) { case UWDEMO: case UW1:extractAllCrittersUW1(fileAssoc, fileCrit, Graphics_Pal, game, useTGA); break; case UW2:extractAllCrittersUW2(fileAssoc, fileCrit, Graphics_Pal, game, useTGA); break; } //extractCritters(fileAssoc, fileCrit, Graphics_Pal, critPal, 64, UW_GRAPHICS_GR,game, 0, OutFileName,useTGA,1); break; case CUTSCENE_EXTRACT_MODE: switch (game) { case UW1://TODO: remove this hardcoding of cutscene selection. //for (int i = 17; i < 47; i++) for (int i = 38; i < 39; i++) { char inFile[255]; sprintf(inFile, "%s\\%s",path_uw1, uw1_cuts_file[i] ,1); if (i == 17) { load_cuts_anim(inFile, uw1_cuts_out_file[i], useTGA,true,uw1_cuts_alpha[i]); } else { load_cuts_anim(inFile, uw1_cuts_out_file[i], useTGA, false, uw1_cuts_alpha[i]); } } break; case UW2: for (int i = 28; i < 57; i++) { char inFile[255]; sprintf(inFile, "%s\\%s", path_uw2, uw2_cuts_file[i], 1); //if (i == 17) // { // load_cuts_anim(inFile, uw2_cuts_out_file[i], useTGA, true, uw2_cuts_alpha[i]); // } //else // { load_cuts_anim(inFile, uw2_cuts_out_file[i], useTGA, false, uw2_cuts_alpha[i]); // } } break; case SHOCK: ExtractShockCutscenes(Graphics_File, Graphics_Pal, critPal, OutFileName, 0);//Bitmap only so far break; default: load_cuts_anim(Graphics_File, OutFileName, useTGA,false,0); break; } break; case MATERIALS_BUILD_MODE: //BuildSHOCKMtrFiles(0); //BuildXDataFile(game); //BuildSndShaderFiles(); //BuildShockMtrFiles(3); //BuildUWMtrFiles(game,2); //BuildUWXData(game, 8); //BuildGuiFiles(); //ExportModelFormat(); //BuildWORDSXData(game); //BuildParticles(game); printf("Materials builder turned off at the moment."); break; case CONVERSATION_MODE: if (game == UW2) { ExtractConversationsUW2(game); } else { ExtractConversations(game); } break; case REPACK_MODE: if (game == UW2) { RepackUW2(GameFilePath, OutFileName, BlocksToRepack); } else { if (game == SHOCK) {//C:\Games\Terra Nova\CD\Terra_Nova\MAPS RepackShock(GameFilePath, OutFileName); //RepackShock("C:\\Games\\Terra Nova\\CD\\Terra_Nova\\MAPS\\FLAT.RES", OutFileName); } } break; case COMBINATION_EXTRACT_MODE: { switch (game) { case UW1: { sprintf_s(FileToOpen, 255, "%s\\%s", path_uw1, uw_objcomb_file); DumpObjectCombinations(FileToOpen, game); break; } case UW2: { sprintf_s(FileToOpen, 255, "%s\\%s", path_uw2, uw2_objcomb_file); DumpObjectCombinations(FileToOpen, game); break; } } break; } case COMMON_PROPERTIES_EXTRACT_MODE: { switch (game) { case UW1: { //sprintf_s(FileToOpen, 255, "%s\\%s", path_uw1, uw_comp_file); //sprintf_s(FileToOpen2, 255, "%s\\%s", path_uw1, uw_obj_prop_file); UWCommonObj(game); break; } case UW2: { //sprintf_s(FileToOpen, 255, "%s\\%s", path_uw2, uw2_comp_file); //sprintf_s(FileToOpen, 255, "%s\\%s", path_uw2, uw2_obj_prop_file); UWCommonObj(game); break; } case SHOCK: { shockCommonObject(); break; } } break; } case FONT_DECODE_UW1_MODE: { DecodeUWFont(); } case SKILLS_EXTRACT_MODE: { ExtractSkills(); } } fclose(LOGFILE); } void LoadConfig(int game, int mode) { //Read in mile FILE *f = NULL; char filePathT[255]; int i = 0; int texNo = 0; char texDesc[80]; char texPath[80]; int objNo = 0; char objDesc[80]; char objPath[80]; char objCat[10]; char objSound[80]; char objParticle[80]; char objBase[80]; char invIcon[80]; char EquippedIconFemaleLowest[80]; char EquippedIconMaleLowest[80];//and default char EquippedIconFemaleLow[80]; char EquippedIconMaleLow[80]; char EquippedIconFemaleMedium[80]; char EquippedIconMaleMedium[80]; char EquippedIconFemaleBest[80]; char EquippedIconMaleBest[80]; int objType; int hasPart; int hasSound; int isSolid; //or useable int isMoveable; int isInventory; int isAnimated; int useSprite; int ShouldSave; int objClass; int objSubClass; int objSubClassIndex; //Shock object classes char line[500]; textureMasters = new texture[340]; objectMasters = new objectMaster[500]; switch (game) { case UWDEMO: case UW1: if (mode != SOURCE_MODE) { strcpy_s(filePathT, UW1_TEXTURE_CONFIG_FILE); } else { strcpy_s(filePathT, UW1_TEXTURE_CONFIG_FILE_SOURCE); } break; case UW2: if (mode != SOURCE_MODE) { strcpy_s(filePathT, UW2_TEXTURE_CONFIG_FILE); } else { strcpy_s(filePathT, UW2_TEXTURE_CONFIG_FILE_SOURCE); } break; case SHOCK: if (mode != SOURCE_MODE) { strcpy_s(filePathT, SHOCK_TEXTURE_CONFIG_FILE); } else { strcpy_s(filePathT, SHOCK_TEXTURE_CONFIG_FILE_SOURCE); } break; } //f=fopen(filePathT,"r"); if ((fopen_s(&f, filePathT, "r") == 0)) { while (fgets(line, 255, f)) { float align1_1 = 0; float align1_2 = 0; float align1_3 = 0; float align2_1 = 0; float align2_2 = 0; float align2_3 = 0; float floor_align1_1 = 0; float floor_align1_2 = 0; float floor_align1_3 = 0; float floor_align2_1 = 0; float floor_align2_2 = 0; float floor_align2_3 = 0; int water = 0; int lava = 0; sscanf(line, "%d %s %s %f %f %f %f %f %f %f %f %f %f %f %f %d %d", &texNo, &texDesc, &texPath, &align1_1, &align1_2, &align1_3, &align2_1, &align2_2, &align2_3, &floor_align1_1, &floor_align1_2, &floor_align1_3, &floor_align2_1, &floor_align2_2, &floor_align2_3, &water, &lava); textureMasters[texNo].textureNo = texNo; strcpy_s(textureMasters[texNo].desc, texDesc); strcpy_s(textureMasters[texNo].path, texPath); textureMasters[texNo].align1_1 = align1_1; textureMasters[texNo].align1_2 = align1_2; textureMasters[texNo].align1_3 = align1_3; textureMasters[texNo].align2_1 = align2_1; textureMasters[texNo].align2_2 = align2_2; textureMasters[texNo].align2_3 = align2_3; textureMasters[texNo].floor_align1_1 = floor_align1_1; textureMasters[texNo].floor_align1_2 = floor_align1_2; textureMasters[texNo].floor_align1_3 = floor_align1_3; textureMasters[texNo].floor_align2_1 = floor_align2_1; textureMasters[texNo].floor_align2_2 = floor_align2_2; textureMasters[texNo].floor_align2_3 = floor_align2_3; textureMasters[texNo].water = water; textureMasters[texNo].lava = lava; i++; } fclose(f); } char filePathO[255]; switch (game) { case UWDEMO: case UW1: strcpy_s(filePathO, UW1_OBJECT_CONFIG_FILE); break; case UW2: strcpy_s(filePathO, UW2_OBJECT_CONFIG_FILE); break; case SHOCK: strcpy_s(filePathO, SHOCK_OBJECT_CONFIG_FILE); break; } if ((fopen_s(&f, filePathO, "r") == 0)) { switch (game) { case UWDEMO: case UW1: case UW2: case SHOCK: { while (fgets(line, 500, f)) { //v sscanf(line, "%d %d %d %d %s %d %s %s %d %s %d %s %s %d %d %d %s %s %s %s %s %s %s %s %s %d %d %d", &objNo, &objClass, &objSubClass, &objSubClassIndex, &objCat, &objType, &objDesc, &objPath, &hasPart, &objParticle, &hasSound, &objSound, &objBase, &isSolid, &isMoveable, &isInventory, &invIcon, &EquippedIconFemaleLowest, &EquippedIconFemaleLow, &EquippedIconFemaleMedium, &EquippedIconFemaleBest, &EquippedIconMaleLowest, &EquippedIconMaleLow, &EquippedIconMaleMedium, &EquippedIconMaleBest, &isAnimated, &useSprite, &ShouldSave); objectMasters[objNo].index = objNo; objectMasters[objNo].isSet = 1; objectMasters[objNo].objClass = objClass; objectMasters[objNo].objSubClass = objSubClass; objectMasters[objNo].objSubClassIndex = objSubClassIndex; strcpy_s(objectMasters[objNo].desc, objDesc); strcpy_s(objectMasters[objNo].path, objPath); strcpy_s(objectMasters[objNo].particle, objParticle); strcpy_s(objectMasters[objNo].sound, objSound); strcpy_s(objectMasters[objNo].base, objBase); if (strcmp(objCat, "model") == 0) { objectMasters[objNo].isEntity = 0; } else if (strcmp(objCat, "entity") == 0) { objectMasters[objNo].isEntity = 1; } else { objectMasters[objNo].isEntity = -1; } objectMasters[objNo].type = objType; objectMasters[objNo].DeathWatch = 0; objectMasters[objNo].hasParticle = hasPart; objectMasters[objNo].hasSound = hasSound; objectMasters[objNo].isSolid = isSolid; objectMasters[objNo].isMoveable = isMoveable; objectMasters[objNo].isInventory = isInventory; if ((game == UW1) || (game == UWDEMO)) { strcpy_s(objectMasters[objNo].EquippedIconFemaleLowest, EquippedIconFemaleLowest); strcpy_s(objectMasters[objNo].EquippedIconMaleLowest, EquippedIconMaleLowest); strcpy_s(objectMasters[objNo].EquippedIconFemaleLow, EquippedIconFemaleLow); strcpy_s(objectMasters[objNo].EquippedIconMaleLow, EquippedIconMaleLow); strcpy_s(objectMasters[objNo].EquippedIconFemaleMedium, EquippedIconFemaleMedium); strcpy_s(objectMasters[objNo].EquippedIconMaleMedium, EquippedIconMaleMedium); strcpy_s(objectMasters[objNo].EquippedIconFemaleBest, EquippedIconFemaleBest); strcpy_s(objectMasters[objNo].EquippedIconMaleBest, EquippedIconMaleBest); objectMasters[objNo].isAnimated = isAnimated; objectMasters[objNo].useSprite = useSprite; strcpy_s(objectMasters[objNo].InvIcon, invIcon); objectMasters[objNo].ShouldSave = ShouldSave; } //printf("uw1_object_%03d.prt\n",objNo); i++; } fclose(f); break; } } } } void exportMaps(int game, int mode, int LevelNo, char OutFileName[255], char filePath[255]) { ObjectItem objList[1600]; //shockObjectItem shockobjList[1600]; long texture_map[256]; long texture_map_shock[272]; int roomIndex = 1; char Map_Output_File[255]; char Script_Output_File[255]; //char *filePath; if ((mode == D3_MODE)) { sprintf_s(Map_Output_File, 255, "%s.map", OutFileName); if (fopen_s(&MAPFILE, Map_Output_File, "w") != 0) { printf("Unable to create output file for map"); return; } } if ((mode == SOURCE_MODE)) { sprintf_s(Map_Output_File, 255, "%s.vmf", OutFileName); if (fopen_s(&MAPFILE, Map_Output_File, "w") != 0) { printf("Unable to create output file for map"); return; } } switch (game) { case UWDEMO: //Underworld Demo { //filePath = UW0_LEVEL_PATH ; //"C:\\Games\\Ultima\\UWDemo\\DATA\\level13.st"; BuildTileMapUW(LevelInfo, objList, texture_map, filePath, game, LevelNo); setTileNeighbourCount(LevelInfo); BuildObjectListUW(LevelInfo, objList, texture_map, filePath, game, LevelNo); setObjectTileXY(game, LevelInfo, objList); SetExitBits(LevelInfo, objList); setDoorBits(LevelInfo, objList); //setCorridors(LevelInfo, &roomIndex); setRooms(LevelInfo, &roomIndex); setPatchBits(LevelInfo, objList); setElevatorBits(LevelInfo, objList); setTerrainChangeBits(LevelInfo, objList); setKeyCount(game, LevelInfo, objList); PrintUWObjects(objList); //Since I can't get full debug info until I have TileX/Y set. MergeWaterRegions(LevelInfo); // break; } case UW1: //Underworld 1 { //filePath = UW1_LEVEL_PATH ; // "C:\\Games\\Ultima\\UW1\\DATA\\lev.ark"; char GravePath[255]; sprintf_s(GravePath, 255, "%s\\%s", path_uw1, UW1_GRAVES); UWCommonObj(game); UW1_Graves(GravePath); BuildTileMapUW(LevelInfo, objList, texture_map, filePath, game, LevelNo); setTileNeighbourCount(LevelInfo); BuildObjectListUW(LevelInfo, objList, texture_map, filePath, game, LevelNo); setObjectTileXY(game, LevelInfo, objList); SetExitBits(LevelInfo, objList); setDoorBits(LevelInfo, objList); setBridgeBits(LevelInfo, objList); //setCorridors(LevelInfo, &roomIndex); setRooms(LevelInfo, &roomIndex); setPatchBits(LevelInfo, objList); setElevatorBits(LevelInfo, objList); setTerrainChangeBits(LevelInfo, objList); SetBullFrog(LevelInfo, objList, LevelNo); setKeyCount(game, LevelInfo, objList); PrintUWObjects(objList); //Since I can't get full debug info until I have TileX/Y set. //CleanUp(LevelInfo,game); //Get rid of unneeded tiles. MergeWaterRegions(LevelInfo); MergeLavaRegions(LevelInfo); break; } case UW2: //Underworld 2 { //filePath = UW2_LEVEL_PATH; //"C:\\Games\\Ultima\\UW2\\DATA\\lev.ark"; if (BuildTileMapUW(LevelInfo, objList, texture_map, filePath, game, LevelNo) == -1) { return; }; setTileNeighbourCount(LevelInfo); BuildObjectListUW(LevelInfo, objList, texture_map, filePath, game, LevelNo); setObjectTileXY(game, LevelInfo, objList); setDoorBits(LevelInfo, objList); //setCorridors(LevelInfo, &roomIndex); setRooms(LevelInfo, &roomIndex); setPatchBits(LevelInfo, objList); setElevatorBits(LevelInfo, objList); setTerrainChangeBits(LevelInfo, objList); setKeyCount(game, LevelInfo, objList); PrintUWObjects(objList); //Since I can't get full debug info until I have TileX/Y set. //CleanUp(LevelInfo,game); //Get rid of unneeded tiles. MergeWaterRegions(LevelInfo); break; } case SHOCK: //system shock { //filePath = SHOCK_LEVEL_PATH; //"C:\\Games\\SystemShock\\Res\\DATA\\archive.dat"; BuildTileMapShock(LevelInfo, objList, texture_map_shock, filePath, game, LevelNo); BuildObjectListShock(LevelInfo, objList, texture_map_shock, filePath, game, LevelNo); SetDeathWatch(objList); setTileNeighbourCount(LevelInfo); setDoorBits(LevelInfo, objList); //setCorridors(LevelInfo, &roomIndex); setRooms(LevelInfo, &roomIndex); setKeyCount(game, LevelInfo, objList); //CleanUp(LevelInfo,game); //Get rid of unneeded tiles. break; } default: {printf("Invalid Game!"); return; } } switch (mode) { case ASCII_MODE: //ascii + other data maps { CleanUp(LevelInfo, game); DumpAscii(game, LevelInfo, objList, LevelNo, 0); //1 for maps only. 0 for extra printouts like objects, textures + heightmaps. break; } case D3_MODE: //D3/Dark Mod { RenderDarkModLevel(LevelInfo, objList, game); fclose(MAPFILE); //break; } case SOURCE_MODE: //Source engine { CleanUp(LevelInfo, game); //Get rid of unneeded tiles. RenderSourceEnginelLevel(LevelInfo, objList, game); fclose(MAPFILE); } case SCRIPT_BUILD_MODE: { sprintf_s(Script_Output_File, 255, "%s.script", OutFileName); if (game != SHOCK) { buildScriptsUW(game, LevelInfo, objList, LevelNo, Script_Output_File); } else { BuildScriptsShock(game, LevelInfo, objList, LevelNo, Script_Output_File); } break; } case FBX_MODE: CleanUp(LevelInfo, game); //Get rid of unneeded tiles. //printf("%d", LevelInfo[3][5].Render); //TODO: restore this for FBX RenderFBXLevel(LevelInfo, objList, game); break; case UNITY_MODE: RenderUnityObjectList(game, LevelNo, LevelInfo, objList); break; case UNITY_TILEMAP_MODE: PrintUnityTileMap(game, LevelNo, LevelInfo); break; } } void PrintCharClass(int classType) { switch (classType) { case 0: fprintf(LOGFILE, "FIGHTER");break; case 1: fprintf(LOGFILE, "MAGE"); break; case 2: fprintf(LOGFILE, "BARD"); break; case 3: fprintf(LOGFILE, "TINKER"); break; case 4: fprintf(LOGFILE, "DRUID"); break; case 5: fprintf(LOGFILE, "PALADIN"); break; case 6: fprintf(LOGFILE, "RANGER"); break; case 7: fprintf(LOGFILE, "SHEPARD"); break; default: fprintf(LOGFILE, "UNKNOWN!"); break; } } void PrintSkill(int SkillType) { switch (SkillType) { case 0: //Attack fprintf(LOGFILE, "%d //Attack", SkillType+31); break; case 1: //Defense fprintf(LOGFILE, "%d //Defense", SkillType+31); break; case 2: //unarmed fprintf(LOGFILE, "%d //Unarmed", SkillType+31); break; case 3: //Sword fprintf(LOGFILE, "%d //Sword", SkillType+31); break; case 4: //Axe fprintf(LOGFILE, "%d //Axe", SkillType+31); break; case 5: //Mace fprintf(LOGFILE, "%d //Mace", SkillType+31); break; case 6: //Missile fprintf(LOGFILE, "%d //Missile", SkillType+31); break; case 7: //Mana fprintf(LOGFILE, "%d //Mana", SkillType+31); break; case 8: //Lore fprintf(LOGFILE, "%d //Lore", SkillType+31); break; case 9: //Casting fprintf(LOGFILE, "%d //Casting", SkillType+31); break; case 10: //Traps fprintf(LOGFILE, "%d //Traps", SkillType+31); break; case 11: //Search fprintf(LOGFILE, "%d //Search", SkillType+31); break; case 12: //Track fprintf(LOGFILE, "%d //Track", SkillType + 31); break; case 13: //Sneak fprintf(LOGFILE, "%d //Sneak", SkillType + 31); break; case 14: //Repair fprintf(LOGFILE, "%d //Repair", SkillType + 31); break; case 15: //Charm fprintf(LOGFILE, "%d //Charm", SkillType + 31); break; case 16: //Pick Lock fprintf(LOGFILE, "%d //Picklock", SkillType + 31); break; case 17: //Acrobat fprintf(LOGFILE, "%d //Acrobat", SkillType + 31); break; case 18: //Appraise fprintf(LOGFILE, "%d //Appraise", SkillType + 31); break; case 19: //Swimming fprintf(LOGFILE, "%d //Swimming", SkillType + 31); break; default: //Unknown fprintf(LOGFILE, "%d //UNKNOWN!", SkillType); break; } } void ExtractSkills() { char filePath[255]; unsigned char *Buffer; sprintf_s(filePath, 255, "%s\\%s", path_uw1, UW1_SKILLS); FILE *file = NULL; // File pointer if (fopen_s(&file, filePath, "rb") != 0) { printf("Could not open specified file\n"); return; } else { // Get the size of the file in bytes long fileSize = getFileSize(file); // Allocate space in the buffer for the whole file Buffer = new unsigned char[fileSize]; fread(Buffer, fileSize, 1, file); fclose(file); int add_ptr=0x20; //Starts further out the file. for (int CharClass=0; CharClass<8;CharClass++)//For each character type. {//Five sets of skills fprintf(LOGFILE, "\nChar Class "); PrintCharClass(CharClass); fprintf(LOGFILE, "//(%d)\n", CharClass); fprintf(LOGFILE, "\t//Base Str %d\n", getValAtAddress(Buffer, CharClass * 4 + 0, 8)); fprintf(LOGFILE, "\t//Base Dex %d\n", getValAtAddress(Buffer, CharClass * 4 + 1, 8)); fprintf(LOGFILE, "\t//Base Int %d\n", getValAtAddress(Buffer, CharClass * 4 + 2, 8)); fprintf(LOGFILE, "\t//Unk (seed?) %d\n", getValAtAddress(Buffer, CharClass * 4 + 3, 8)); for (int SkillChoice = 0; SkillChoice<5;SkillChoice++) { fprintf(LOGFILE, "\tSkillChoices %d\n", SkillChoice); int NoOfEntries = getValAtAddress(Buffer,add_ptr++,8); for (int i = 0; i < NoOfEntries; i++) { fprintf(LOGFILE, "\t\tSkill : "); PrintSkill(getValAtAddress(Buffer, add_ptr++, 8)); fprintf(LOGFILE, "\n"); } } } } } <MSG> Graphics extractions can now output in tga format with alpha channel. <DFF> @@ -35,7 +35,7 @@ int gamefile=-1; int graphics_file_no=-1; int graphics_mode; int BitMapSize=32; -int panels = 0;//Panels.gr are a special case for extraction +short panels = 0;//Panels.gr are a special case for extraction char Graphics_File[255]; char Graphics_Pal[255]; char path_uw0[100]; @@ -52,6 +52,7 @@ char fileCrit[255]; int critPal=0; int bytark=0; int BlocksToRepack=320;//UW2 blocks to repack +int useTGA=0; FILE *f = NULL; if ((f = fopen("gamepaths.txt", "r")) == NULL) { @@ -108,494 +109,528 @@ shock_game_files[8] = "Data\\SAVGAM07.dat"; const char *uw1_graphics_file[45]; -const char *uw2_graphics_file[37]; -uw1_graphics_file[0] = "F16.tr";// - Floor textures 16x16"); -uw1_graphics_file[1] = "F32.tr";// - Floor textures 32x32\n"); -uw1_graphics_file[2] = "W16.tr";// - Wall textures 16x16"); -uw1_graphics_file[3] = "W64.tr";// - Wall textures 64x64\n"); -uw1_graphics_file[4] = "3DWIN.GR"; -uw1_graphics_file[5] = "ANIMO.GR"; -uw1_graphics_file[6] = "ARMOR_F.GR"; -uw1_graphics_file[7] = "ARMOR_G.GR"; -uw1_graphics_file[8] = "BODIES.GR"; -uw1_graphics_file[9] = "BUTTONS.GR"; -uw1_graphics_file[10] = "CHAINS.GR"; -uw1_graphics_file[11] = "CHARHEAD.GR"; -uw1_graphics_file[12] = "CHRBTNS.GR"; -uw1_graphics_file[13] = "COMPASS.GR"; -uw1_graphics_file[14] = "CONVERSE.GR"; -uw1_graphics_file[15] = "CURSORS.GR"; -uw1_graphics_file[16] = "DOORS.GR"; -uw1_graphics_file[17] = "DRAGONS.GR"; -uw1_graphics_file[18] = "EYES.GR"; -uw1_graphics_file[19] = "FLASKS.GR"; -uw1_graphics_file[20] = "GENHEAD.GR"; -uw1_graphics_file[21] = "HEADS.GR"; -uw1_graphics_file[22] = "INV.GR"; -uw1_graphics_file[23] = "LFTI.GR"; -uw1_graphics_file[24] = "OBJECTS.GR"; -uw1_graphics_file[25] = "OPTBN"; -uw1_graphics_file[26] = "OPTB"; -uw1_graphics_file[27] = "OPTBNS"; -uw1_graphics_file[28] = "PANELS.GR"; -uw1_graphics_file[29] = "POWER.GR"; -uw1_graphics_file[30] = "QUEST.GR"; -uw1_graphics_file[31] = "SCRLEDGE.GR"; -uw1_graphics_file[32] = "SPELLS.GR"; -uw1_graphics_file[33] = "TMFLAT.GR"; -uw1_graphics_file[34] = "TMOBJ.GR"; -uw1_graphics_file[35] = "WEAPONS.GR"; -uw1_graphics_file[36] = "BLNKMAP.BYT"; -uw1_graphics_file[37] = "CHARGEN.BYT"; -uw1_graphics_file[38] = "CONV.BYT"; -uw1_graphics_file[39] = "MAIN.BYT"; -uw1_graphics_file[40] = "OPSCR.BYT"; -uw1_graphics_file[41] = "PRES1.BYT"; -uw1_graphics_file[42] = "PRES2.BYT"; -uw1_graphics_file[43] = "WIN1.BYT"; -uw1_graphics_file[44] = "WIN2.BYT"; - -uw2_graphics_file[0] = "T64.tr";//uw2 textures -uw2_graphics_file[1] = "3DWIN.GR"; -uw2_graphics_file[2] = "ANIMO.GR"; -uw2_graphics_file[3] = "ARMOR_F.GR"; -uw2_graphics_file[4] = "ARMOR_G.GR"; -uw2_graphics_file[5] = "BODIES.GR"; -uw2_graphics_file[6] = "BUTTONS.GR"; -uw2_graphics_file[7] = "CHAINS.GR"; -uw2_graphics_file[8] = "CHARHEAD.GR"; -uw2_graphics_file[9] = "CHRBTNS.GR"; -uw2_graphics_file[10] = "COMPASS.GR"; -uw2_graphics_file[11] = "CONVERSE.GR"; -uw2_graphics_file[12] = "CURSORS.GR"; -uw2_graphics_file[13] = "DOORS.GR"; -uw2_graphics_file[14] = "DRAGONS.GR"; -uw2_graphics_file[15] = "EYES.GR"; -uw2_graphics_file[16] = "FLASKS.GR"; -uw2_graphics_file[17] = "GEMPT.GR"; -uw2_graphics_file[18] = "GENHEAD.GR"; -uw2_graphics_file[19] = "GHEAD.GR"; -uw2_graphics_file[20] = "HEADS.GR"; -uw2_graphics_file[21] = "INV.GR"; -uw2_graphics_file[22] = "LFTI.GR"; -uw2_graphics_file[23] = "OBJECTS.GR"; -uw2_graphics_file[24] = "OPTBN"; -uw2_graphics_file[25] = "OPTB"; -uw2_graphics_file[26] = "OPTBNS"; -uw2_graphics_file[27] = "PANELS.GR"; -uw2_graphics_file[28] = "POWER.GR"; -uw2_graphics_file[29] = "QUESTION.GR"; -uw2_graphics_file[30] = "SCRLEDGE.GR"; -uw2_graphics_file[31] = "SPELLS.GR"; -uw2_graphics_file[32] = "TMFLAT.GR"; -uw2_graphics_file[33] = "TMOBJ.GR"; -uw2_graphics_file[34] = "VIEWS.GR"; -uw2_graphics_file[35] = "WEAP.GR"; -uw2_graphics_file[36] = "BYT.ARK"; - -//int game = SHOCK; -//int game = UWDEMO; -//int game = UW1; -//int game = UW2; -//int mode = D3_MODE; -//int mode = ASCII_MODE; -//int mode = STRINGS_EXTRACT_MODE; -//int mode = BITMAP_EXTRACT_MODE; -//int mode = SCRIPT_BUILD_MODE; -//int mode = MATERIALS_BUILD_MODE; -//int mode = CONVERSATION_MODE; -//int mode = REPACK_MODE; -//int mode= SOURCE_MODE; +const char *uw2_graphics_file[45]; +uw1_graphics_file[0] = "Data\\F16.tr";// - Floor textures 16x16"); +uw1_graphics_file[1] = "Data\\F32.tr";// - Floor textures 32x32\n"); +uw1_graphics_file[2] = "Data\\W16.tr";// - Wall textures 16x16"); +uw1_graphics_file[3] = "Data\\W64.tr";// - Wall textures 64x64\n"); +uw1_graphics_file[4] = "Data\\3DWIN.GR"; +uw1_graphics_file[5] = "Data\\ANIMO.GR"; +uw1_graphics_file[6] = "Data\\ARMOR_F.GR"; +uw1_graphics_file[7] = "Data\\ARMOR_G.GR"; +uw1_graphics_file[8] = "Data\\BODIES.GR"; +uw1_graphics_file[9] = "Data\\BUTTONS.GR"; +uw1_graphics_file[10] = "Data\\CHAINS.GR"; +uw1_graphics_file[11] = "Data\\CHARHEAD.GR"; +uw1_graphics_file[12] = "Data\\CHRBTNS.GR"; +uw1_graphics_file[13] = "Data\\COMPASS.GR"; +uw1_graphics_file[14] = "Data\\CONVERSE.GR"; +uw1_graphics_file[15] = "Data\\CURSORS.GR"; +uw1_graphics_file[16] = "Data\\DOORS.GR"; +uw1_graphics_file[17] = "Data\\DRAGONS.GR"; +uw1_graphics_file[18] = "Data\\EYES.GR"; +uw1_graphics_file[19] = "Data\\FLASKS.GR"; +uw1_graphics_file[20] = "Data\\GENHEAD.GR"; +uw1_graphics_file[21] = "Data\\HEADS.GR"; +uw1_graphics_file[22] = "Data\\INV.GR"; +uw1_graphics_file[23] = "Data\\LFTI.GR"; +uw1_graphics_file[24] = "Data\\OBJECTS.GR"; +uw1_graphics_file[25] = "Data\\OPTBN"; +uw1_graphics_file[26] = "Data\\OPTB"; +uw1_graphics_file[27] = "Data\\OPTBNS"; +uw1_graphics_file[28] = "Data\\PANELS.GR"; +uw1_graphics_file[29] = "Data\\POWER.GR"; +uw1_graphics_file[30] = "Data\\QUEST.GR"; +uw1_graphics_file[31] = "Data\\SCRLEDGE.GR"; +uw1_graphics_file[32] = "Data\\SPELLS.GR"; +uw1_graphics_file[33] = "Data\\TMFLAT.GR"; +uw1_graphics_file[34] = "Data\\TMOBJ.GR"; +uw1_graphics_file[35] = "Data\\WEAPONS.GR"; +uw1_graphics_file[36] = "Data\\BLNKMAP.BYT"; +uw1_graphics_file[37] = "Data\\CHARGEN.BYT"; +uw1_graphics_file[38] = "Data\\CONV.BYT"; +uw1_graphics_file[39] = "Data\\MAIN.BYT"; +uw1_graphics_file[40] = "Data\\OPSCR.BYT"; +uw1_graphics_file[41] = "Data\\PRES1.BYT"; +uw1_graphics_file[42] = "Data\\PRES2.BYT"; +uw1_graphics_file[43] = "Data\\WIN1.BYT"; +uw1_graphics_file[44] = "Data\\WIN2.BYT"; + +uw2_graphics_file[0] = "Data\\T64.tr";//uw2 textures +uw2_graphics_file[1] = "Data\\3DWIN.GR"; +uw2_graphics_file[2] = "Data\\ANIMO.GR"; +uw2_graphics_file[3] = "Data\\ARMOR_F.GR"; +uw2_graphics_file[4] = "Data\\ARMOR_G.GR"; +uw2_graphics_file[5] = "Data\\BODIES.GR"; +uw2_graphics_file[6] = "Data\\BUTTONS.GR"; +uw2_graphics_file[7] = "Data\\CHAINS.GR"; +uw2_graphics_file[8] = "Data\\CHARHEAD.GR"; +uw2_graphics_file[9] = "Data\\CHRBTNS.GR"; +uw2_graphics_file[10] = "Data\\COMPASS.GR"; +uw2_graphics_file[11] = "Data\\CONVERSE.GR"; +uw2_graphics_file[12] = "Data\\CURSORS.GR"; +uw2_graphics_file[13] = "Data\\DOORS.GR"; +uw2_graphics_file[14] = "Data\\DRAGONS.GR"; +uw2_graphics_file[15] = "Data\\EYES.GR"; +uw2_graphics_file[16] = "Data\\FLASKS.GR"; +uw2_graphics_file[17] = "Data\\GEMPT.GR"; +uw2_graphics_file[18] = "Data\\GENHEAD.GR"; +uw2_graphics_file[19] = "Data\\GHEAD.GR"; +uw2_graphics_file[20] = "Data\\HEADS.GR"; +uw2_graphics_file[21] = "Data\\INV.GR"; +uw2_graphics_file[22] = "Data\\LFTI.GR"; +uw2_graphics_file[23] = "Data\\OBJECTS.GR"; +uw2_graphics_file[24] = "Data\\OPTBN"; +uw2_graphics_file[25] = "Data\\OPTB"; +uw2_graphics_file[26] = "Data\\OPTBNS"; +uw2_graphics_file[27] = "Data\\PANELS.GR"; +uw2_graphics_file[28] = "Data\\POWER.GR"; +uw2_graphics_file[29] = "Data\\QUESTION.GR"; +uw2_graphics_file[30] = "Data\\SCRLEDGE.GR"; +uw2_graphics_file[31] = "Data\\SPELLS.GR"; +uw2_graphics_file[32] = "Data\\TMFLAT.GR"; +uw2_graphics_file[33] = "Data\\TMOBJ.GR"; +uw2_graphics_file[34] = "Data\\VIEWS.GR"; +uw2_graphics_file[35] = "Data\\WEAP.GR"; +uw2_graphics_file[36] = "Data\\BYT.ARK"; +uw2_graphics_file[37] = "Cuts\\LBACK000.BYT"; +uw2_graphics_file[38] = "Cuts\\LBACK001.BYT"; +uw2_graphics_file[39] = "Cuts\\LBACK002.BYT"; +uw2_graphics_file[40] = "Cuts\\LBACK003.BYT"; +uw2_graphics_file[41] = "Cuts\\LBACK004.BYT"; +uw2_graphics_file[42] = "Cuts\\LBACK005.BYT"; +uw2_graphics_file[43] = "Cuts\\LBACK006.BYT"; +uw2_graphics_file[44] = "Cuts\\LBACK007.BYT"; + levelNo = -1; -printf("Welcome to Underworld Exporter.\n"); - printf("\nAvailable games\n"); - printf("0) Ultima Underworld Demo (probably doesn't work!)\n"); - printf("1) Ultima Underworld 1: The Stygian Abyss\n"); - printf("2) Ultima Underworld 2: The Labyrinth of Worlds\n"); - printf("3) System Shock 1\n"); - printf("Please select a game.\n>"); - scanf("%d",&game); - if ((game < UWDEMO) || (game > SHOCK)) - { +if (true) + { + printf("Welcome to Underworld Exporter.\n"); + printf("\nAvailable games\n"); + printf("0) Ultima Underworld Demo (probably doesn't work!)\n"); + printf("1) Ultima Underworld 1: The Stygian Abyss\n"); + printf("2) Ultima Underworld 2: The Labyrinth of Worlds\n"); + printf("3) System Shock 1\n"); + printf("Please select a game.\n>"); + scanf("%d",&game); + if ((game < UWDEMO) || (game > SHOCK)) + { + printf("Invalid input. Bye."); + return 0; + } + + printf("Available Modes.\n"); + printf("%d) Ascii dump.\n",ASCII_MODE); + printf("%d) IDTech/DarkMod export.\n",D3_MODE); + printf("%d) String Extraction\n",STRINGS_EXTRACT_MODE); + printf("%d) Bitmap Extraction\n",BITMAP_EXTRACT_MODE); + printf("%d) Script build(Also runs as part of IDTech export)\n",SCRIPT_BUILD_MODE); + printf("%d) Support Materials Builder\n",MATERIALS_BUILD_MODE); + printf("%d) Conversation code dump (unfinished!)\n",CONVERSATION_MODE); + printf("%d) Repacker mode (UW2 and Shock only. Use at own risk!)\n",REPACK_MODE); + printf("%d) Source Engine export\n",SOURCE_MODE); + printf("%d) Critter Art Extract\n", CRITTER_EXTRACT_MODE); + printf("%d) Cutscene Art Extract\n", CUTSCENE_EXTRACT_MODE); + printf("Please select a mode.\n>"); + scanf("%d", &mode); + if ((mode < 0) || (mode > 10)) + { printf("Invalid input. Bye."); return 0; - } - -printf("Available Modes.\n"); -printf("%d) Ascii dump.\n",ASCII_MODE); -printf("%d) IDTech/DarkMod export.\n",D3_MODE); -printf("%d) String Extraction\n",STRINGS_EXTRACT_MODE); -printf("%d) Bitmap Extraction\n",BITMAP_EXTRACT_MODE); -printf("%d) Script build(Also runs as part of IDTech export)\n",SCRIPT_BUILD_MODE); -printf("%d) Support Materials Builder\n",MATERIALS_BUILD_MODE); -printf("%d) Conversation code dump (unfinished!)\n",CONVERSATION_MODE); -printf("%d) Repacker mode (UW2 and Shock only. Use at own risk!)\n",REPACK_MODE); -printf("%d) Source Engine export\n",SOURCE_MODE); -printf("%d) Critter Art Extract\n", CRITTER_EXTRACT_MODE); -printf("%d) Cutscene Art Extract\n", CUTSCENE_EXTRACT_MODE); -printf("Please select a mode.\n>"); -scanf("%d", &mode); -if ((mode < 0) || (mode > 10)) -{ - printf("Invalid input. Bye."); - return 0; -} + } -switch (mode) -{ -case ASCII_MODE: -case D3_MODE: -case SOURCE_MODE: -case SCRIPT_BUILD_MODE: -case REPACK_MODE: - { - switch (game) - { - case UWDEMO: - sprintf_s(GameFilePath, 255, "%s\\level13.st", path_uw0); - break; - case UW1: - case UW2: - printf("\nPick a level archive or save game to open\n"); - for (int i = 0; i < 6; i++) - { - printf("%d) %s\n",i,uw_game_files[i]); - } - if ((game==UW2) && (mode==REPACK_MODE)) - { - printf("%d) %s\n",6,uw_game_files[6]); - } - printf(">"); - scanf("%d", &gamefile); - if ((gamefile < 0) || (gamefile >= 7)) - { - printf("Invalid input. Bye."); - return 0; - } - if(game==UW1) - { - sprintf_s(GameFilePath, 255, "%s\\%s", path_uw1, uw_game_files[gamefile]); - } - else - { - sprintf_s(GameFilePath, 255, "%s\\%s", path_uw2, uw_game_files[gamefile]); - } - break; - case SHOCK: - printf("\nPick a level archive or save game to open\n"); - for (int i = 0; i < 9; i++) - { - printf("%d) %s\n", i, shock_game_files[i]); - } - printf(">"); - scanf("%d", &gamefile); - if ((gamefile < 0) || (gamefile >= 10)) - { - printf("Invalid input. Bye."); - return 0; - } - sprintf_s(GameFilePath, 255, "%s\\%s", path_shock, shock_game_files[gamefile]); - break; - } - if (mode !=REPACK_MODE) + switch (mode) { - switch (game) + case ASCII_MODE: + case D3_MODE: + case SOURCE_MODE: + case SCRIPT_BUILD_MODE: + case REPACK_MODE: { + switch (game) + { case UWDEMO: - levelNo = 0; //only possible value + sprintf_s(GameFilePath, 255, "%s\\level13.st", path_uw0); break; - case UW1://Print list of UW1 levels. - printf("\nPick a level.\n"); - printf("0)Entrance level.\n"); - printf("1)Domain of the Mountainmen.\n"); - printf("2)The Swamp and Lizardmen.\n"); - printf("3)Trolls and Knights.\n"); - printf("4)Catacombs and banquet halls.\n"); - printf("5)The Seers.\n"); - printf("6)Tybals Lair.\n"); - printf("7)The Volcano.\n"); - printf("8)Ethereal Void.\n"); - printf(">"); - scanf("%d", &levelNo); - if ((levelNo < 0) || (levelNo > 9)) + case UW1: + case UW2: + printf("\nPick a level archive or save game to open\n"); + for (int i = 0; i < 6; i++) { - printf("Invalid input. Bye."); - return 0; + printf("%d) %s\n",i,uw_game_files[i]); } - break; - case UW2: - printf("\nPick a level\n"); - printf("0 - 4 Britannia\n"); - printf("8 - 15 Prison Tower\n"); - printf("16 - 17 Killorn Keep\n"); - printf("24 - 25 Ice Cavern\n"); - printf("32 - 33 Talorus\n"); - printf("40 - 47 Academy\n"); - printf("48 - 51 Tomb\n"); - printf("56 - 58 Pits\n"); - printf("64 - 72 Void (65 is stickman level)\n"); + if ((game==UW2) && (mode==REPACK_MODE)) + { + printf("%d) %s\n",6,uw_game_files[6]); + } printf(">"); - scanf("%d", &levelNo); - if (!( - ((levelNo >= 0) && (levelNo <= 4)) - || ((levelNo >= 8) && (levelNo <= 15)) - || ((levelNo >= 16) && (levelNo <= 17)) - || ((levelNo >= 24) && (levelNo <= 25)) - || ((levelNo >= 32) && (levelNo <= 33)) - || ((levelNo >= 40) && (levelNo <= 47)) - || ((levelNo >= 48) && (levelNo <= 51)) - || ((levelNo >= 56) && (levelNo <= 58)) - || ((levelNo >= 64) && (levelNo <= 72)) - )) + scanf("%d", &gamefile); + if ((gamefile < 0) || (gamefile >= 7)) { printf("Invalid input. Bye."); return 0; } + if(game==UW1) + { + sprintf_s(GameFilePath, 255, "%s\\%s", path_uw1, uw_game_files[gamefile]); + } + else + { + sprintf_s(GameFilePath, 255, "%s\\%s", path_uw2, uw_game_files[gamefile]); + } break; case SHOCK: - printf("\nPick a level (need to dblchk these)\n"); - printf("0)Reactor\n"); - printf("1)Med SCI\n"); - printf("2)Research\n"); - printf("3)Maintenance\n"); - printf("4)Storage\n"); - printf("5)Flight Deck\n"); - printf("6)Executive\n"); - printf("7)System Engineering\n"); - printf("8)Security\n"); - printf("9)Bridge\n"); - printf("10)Cyberspace 1 (Shodan)\n"); - printf("11)Grove 1\n"); - printf("12)Grove 1\n"); - printf("13)Grove 1\n"); - printf("14)Cyberspace 2\n"); - printf("15)Cyberspace 3\n"); + printf("\nPick a level archive or save game to open\n"); + for (int i = 0; i < 9; i++) + { + printf("%d) %s\n", i, shock_game_files[i]); + } printf(">"); - scanf("%d", &levelNo); - if ((levelNo < 0) || (levelNo > 15)) + scanf("%d", &gamefile); + if ((gamefile < 0) || (gamefile >= 10)) { printf("Invalid input. Bye."); return 0; } + sprintf_s(GameFilePath, 255, "%s\\%s", path_shock, shock_game_files[gamefile]); break; - } - printf("Enter a filename for output (%s\\[filename].map)\n>", path_target_platform); - - scanf("%s", TempOutFileName); - sprintf_s(OutFileName, 255, "%s\\%s", path_target_platform, TempOutFileName); - } - else + } + if (mode !=REPACK_MODE) { switch (game) { + case UWDEMO: + levelNo = 0; //only possible value + break; + case UW1://Print list of UW1 levels. + printf("\nPick a level.\n"); + printf("0)Entrance level.\n"); + printf("1)Domain of the Mountainmen.\n"); + printf("2)The Swamp and Lizardmen.\n"); + printf("3)Trolls and Knights.\n"); + printf("4)Catacombs and banquet halls.\n"); + printf("5)The Seers.\n"); + printf("6)Tybals Lair.\n"); + printf("7)The Volcano.\n"); + printf("8)Ethereal Void.\n"); + printf(">"); + scanf("%d", &levelNo); + if ((levelNo < 0) || (levelNo > 9)) + { + printf("Invalid input. Bye."); + return 0; + } + break; case UW2: - printf("Enter a filename for repacking into (%s\\data\\[filename].ark)\n>", path_uw2); - scanf("%s", TempOutFileName); - sprintf_s(OutFileName, 255, "%s\\data\\%s.ark", path_uw2, TempOutFileName); - break; - case SHOCK: - printf("Enter a filename for repacking into (%s\\[filename].data)\n>", path_shock); - scanf("%s", TempOutFileName); - sprintf_s(OutFileName, 255, "%s\\res\\data\\%s.ark", path_target_platform, TempOutFileName); - break; - default: - printf("\nInvalid game for repacking. Goodbye"); - return 0; + printf("\nPick a level\n"); + printf("0 - 4 Britannia\n"); + printf("8 - 15 Prison Tower\n"); + printf("16 - 17 Killorn Keep\n"); + printf("24 - 25 Ice Cavern\n"); + printf("32 - 33 Talorus\n"); + printf("40 - 47 Academy\n"); + printf("48 - 51 Tomb\n"); + printf("56 - 58 Pits\n"); + printf("64 - 72 Void (65 is stickman level)\n"); + printf(">"); + scanf("%d", &levelNo); + if (!( + ((levelNo >= 0) && (levelNo <= 4)) + || ((levelNo >= 8) && (levelNo <= 15)) + || ((levelNo >= 16) && (levelNo <= 17)) + || ((levelNo >= 24) && (levelNo <= 25)) + || ((levelNo >= 32) && (levelNo <= 33)) + || ((levelNo >= 40) && (levelNo <= 47)) + || ((levelNo >= 48) && (levelNo <= 51)) + || ((levelNo >= 56) && (levelNo <= 58)) + || ((levelNo >= 64) && (levelNo <= 72)) + )) + { + printf("Invalid input. Bye."); + return 0; + } + break; + case SHOCK: + printf("\nPick a level (need to dblchk these)\n"); + printf("0)Reactor\n"); + printf("1)Med SCI\n"); + printf("2)Research\n"); + printf("3)Maintenance\n"); + printf("4)Storage\n"); + printf("5)Flight Deck\n"); + printf("6)Executive\n"); + printf("7)System Engineering\n"); + printf("8)Security\n"); + printf("9)Bridge\n"); + printf("10)Cyberspace 1 (Shodan)\n"); + printf("11)Grove 1\n"); + printf("12)Grove 1\n"); + printf("13)Grove 1\n"); + printf("14)Cyberspace 2\n"); + printf("15)Cyberspace 3\n"); + printf(">"); + scanf("%d", &levelNo); + if ((levelNo < 0) || (levelNo > 15)) + { + printf("Invalid input. Bye."); + return 0; + } + break; + } + printf("Enter a filename for output (%s\\[filename].map)\n>", path_target_platform); + + scanf("%s", TempOutFileName); + sprintf_s(OutFileName, 255, "%s\\%s", path_target_platform, TempOutFileName); } + else + { + switch (game) + { + case UW2: + printf("Enter a filename for repacking into (%s\\data\\[filename].ark)\n>", path_uw2); + scanf("%s", TempOutFileName); + sprintf_s(OutFileName, 255, "%s\\data\\%s.ark", path_uw2, TempOutFileName); + break; + case SHOCK: + printf("Enter a filename for repacking into (%s\\[filename].data)\n>", path_shock); + scanf("%s", TempOutFileName); + sprintf_s(OutFileName, 255, "%s\\res\\data\\%s.ark", path_target_platform, TempOutFileName); + break; + default: + printf("\nInvalid game for repacking. Goodbye"); + return 0; + } + } + + break; } - - break; - } -case BITMAP_EXTRACT_MODE: - switch (game) - { - case UWDEMO: - printf("\nCome back later...\n"); - return 0; - break; - case UW1: - for (int i = 0; i < 45; i++) - { - printf("%d) %s",i, uw1_graphics_file[i]); - if (i % 2 == 0) + case BITMAP_EXTRACT_MODE: + switch (game) + { + case UWDEMO: + printf("\nCome back later...\n"); + return 0; + break; + case UW1: + for (int i = 0; i < 45; i++) { - printf("\t"); + printf("%d) %s",i, uw1_graphics_file[i]); + if (i % 2 == 0) + { + printf("\t"); + } + else + { + printf("\n"); + } } - else + printf("\nPick a file\n>"); + scanf("%d", &graphics_file_no); + if ((graphics_file_no < 0) || (graphics_file_no > 44)) { - printf("\n"); + printf("Invalid input. Bye."); + return 0; } - } - printf("\nPick a file\n>"); - scanf("%d", &graphics_file_no); - if ((graphics_file_no < 0) || (graphics_file_no > 44)) - { - printf("Invalid input. Bye."); - return 0; - } - sprintf_s(Graphics_File, 255, "%s\\data\\%s", path_uw1, uw1_graphics_file[graphics_file_no]); - sprintf_s(Graphics_Pal, 255, "%s\\data\\pals.dat", path_uw1); - sprintf_s(auxPalPath, 255, "%s\\%s", path_uw1, AUXILARY_PAL_FILE); - if (graphics_file_no <= 3) - { - graphics_mode = UW_GRAPHICS_TEXTURES; - switch (graphics_file_no) + sprintf_s(Graphics_File, 255, "%s\\%s", path_uw1, uw1_graphics_file[graphics_file_no]); + sprintf_s(Graphics_Pal, 255, "%s\\data\\pals.dat", path_uw1); + sprintf_s(auxPalPath, 255, "%s\\%s", path_uw1, AUXILARY_PAL_FILE); + if (graphics_file_no <= 3) + { + graphics_mode = UW_GRAPHICS_TEXTURES; + switch (graphics_file_no) + { + case 0: + BitMapSize=16; break; + case 1: + BitMapSize = 32; break; + case 2: + BitMapSize = 16; break; + case 3: + BitMapSize = 64; break; + } + } + else if (graphics_file_no <= 35) { - case 0: - BitMapSize=16; break; - case 1: - BitMapSize = 32; break; - case 2: - BitMapSize = 16; break; - case 3: - BitMapSize = 64; break; + if (graphics_file_no == 27)//Panels + { + panels=1; + } + graphics_mode = UW_GRAPHICS_GR; } - } - else if (graphics_file_no <= 35) - { - if (graphics_file_no == 27)//Panels + else { - panels=1; + graphics_mode = UW_GRAPHICS_BITMAPS; } - graphics_mode = UW_GRAPHICS_GR; - } - else - { - graphics_mode = UW_GRAPHICS_BITMAPS; - } - break; - case UW2: - for (int i = 0; i < 37; i++) - { - printf("%d) %s", i, uw2_graphics_file[i]); - if (i % 2 == 0) + break; + case UW2: + for (int i = 0; i < 45; i++) { - printf("\t"); + printf("%d) %s", i, uw2_graphics_file[i]); + if (i % 2 == 0) + { + printf("\t"); + } + else + { + printf("\n"); + } } - else + printf("\nPick a file\n>"); + scanf("%d", &graphics_file_no); + if ((graphics_file_no < 0) || (graphics_file_no > 45)) { - printf("\n"); + printf("Invalid input. Bye."); + return 0; } - } - printf("\nPick a file\n>"); - scanf("%d", &graphics_file_no); - if ((graphics_file_no < 0) || (graphics_file_no > 36)) - { - printf("Invalid input. Bye."); - return 0; - } - if (graphics_file_no == 36) - {//UW2 Byt ark - bytark=1; - } - sprintf_s(Graphics_File, 255, "%s\\data\\%s", path_uw2, uw2_graphics_file[graphics_file_no]); - sprintf_s(Graphics_Pal, 255, "%s\\data\\pals.dat", path_uw2); - sprintf_s(auxPalPath, 255, "%s\\%s", path_uw2, AUXILARY_PAL_FILE); + if (graphics_file_no == 36) + {//UW2 Byt ark + bytark=1; + } + sprintf_s(Graphics_File, 255, "%s\\%s", path_uw2, uw2_graphics_file[graphics_file_no]); + sprintf_s(Graphics_Pal, 255, "%s\\data\\pals.dat", path_uw2); + sprintf_s(auxPalPath, 255, "%s\\%s", path_uw2, AUXILARY_PAL_FILE); - if (graphics_file_no <= 0) - { - graphics_mode = UW_GRAPHICS_TEXTURES; - BitMapSize = 64; - } - else - { - graphics_mode = UW_GRAPHICS_GR; - if (graphics_file_no == 28)//Panels - { - panels = 1;//special case due to file headers + if (graphics_file_no <= 0) + {//only on texture file in uw2 + graphics_mode = UW_GRAPHICS_TEXTURES; + BitMapSize = 64; } - } - break; - case SHOCK: - printf("\nI don't have a graphics extractor for System Shock as part of this program yet. You'll have to find one yourself.\n"); - return 0; - } - printf("\nEnter a palette number to use.(0 to 7)\n>"); - scanf("%d", &critPal); - printf("Enter a filename for output ([filename]_###.bmp)\n>"); - scanf("%s", OutFileName); - break; - case STRINGS_EXTRACT_MODE: - switch (game) - {
Graphics extractions can now output in tga format with alpha channel.