|
|
(4 intermediate revisions by 3 users not shown) |
Line 1: |
Line 1: |
| Author: Leon
| | UCC is a command line utility for early Unreal engine games. Star Wars: Republic Commando ships without one, but a custom one has been made available as a result of reverse engineering. |
|
| |
|
| Used Tools: [[MS Visual Studio 2003]] | | Description: A custom UCC.exe for Republic Commando. Used for executing Unreal Commandlets. |
|
| |
|
| Description: A self written UCC for Republic Commando. Used for executing Unreal Commandlets.
| | Latest Build: [https://github.com/SWRC-Modding/CT/releases here] |
|
| |
|
| Github: [https://github.com/Leon280698/CT here]
| |
|
| |
|
| Latest Build: [http://www.moddb.com/games/star-wars-republic-commando/downloads/star-wars-republic-commando-ucc-exe here]
| | [[File:Uccshow.PNG]] |
|
| |
|
| | ===== Batchexport Commandlet ===== |
|
| |
|
| /*
| | The batchexport commandlet is made available by UCC. This commandlet can parse the game's resource archives in order to export any exportable type in bulk. Here is the syntax for converting some texture package, called "exampletexturepackage.utx" from the game into a set of tga files in ExampleOutputFolder: |
| * This is a custom UCC.exe for Star Wars Republic Commando since the game shipped without one.
| |
| * Everything compiles fine with Visual Studio .NET 2003 which is being used to achieve maximum compatibility
| |
| * since it was also used to compile RC
| |
| * The following settings are required in order to compile everything without errors:
| |
| * - Character Set = Not Set
| |
| * - Struct Member Alignment = 4 Bytes
| |
| * - Calling Convention = __fastcall
| |
| */
| |
|
| |
|
| #include "../../Core/Inc/Core.h"
| | '''<sup>./ucc.exe batchexport exampletexturepackage.utx texture tga ".\\ExampleOutputFolder"</sup>''' |
| #include "../../Core/Inc/FOutputDeviceFile.h"
| |
| #include "../../Core/Inc/FOutputDeviceWindowsError.h"
| |
| #include "../../Core/Inc/FFeedbackContextCmd.h"
| |
| #include "../../Core/Inc/FConfigCacheIni.h"
| |
|
| |
|
| void UServerCommandletMain(); // Defined in ServerCommandlet.cpp
| | In particular, UCC can extract batches of sounds from the UAX archives where Republic Commando's voice lines and sound effects are stored. The batchexport commandlet does this. See [[Extract_Game_Audio_Using_UCC|how to extract game audio using UCC]] for details. |
| | |
| void ShowBanner(FOutputDevice& Out){
| |
| Out.Log("=======================================");
| |
| Out.Log("ucc.exe for Star Wars Republic Commando");
| |
| Out.Log("made by Leon0628");
| |
| Out.Log("=======================================");
| |
| Out.Log("");
| |
| }
| |
| | |
| int __cdecl main(int argc, char** argv){
| |
| int ExitCode = EXIT_SUCCESS;
| |
| FOutputDeviceFile Log;
| |
| FOutputDeviceWindowsError Error;
| |
| FFeedbackContextCmd Warn;
| |
| | |
| GIsStarted = 1;
| |
| | |
| try{
| |
| GIsGuarded = 1;
| |
| | |
| FString CmdLine;
| |
| | |
| for(int i = 1; i < argc; ++i)
| |
| CmdLine += FString(argv[i]) + " ";
| |
| | |
| appInit("SWRepublicCommando", *CmdLine, &Log, &Error, &Warn, FConfigCacheIni::Factory, 1);
| |
| UObject::SetLanguage("int");
| |
| | |
| if(argc > 1){
| |
| // Initializing global state
| |
| GIsUCC = GIsClient = GIsServer = GIsEditor = GIsScriptable = GLazyLoad = 1;
| |
| | |
| FString ClassName = argv[1];
| |
| TArray<FRegistryObjectInfo> List;
| |
| | |
| UObject::GetRegistryObjects(List, UClass::StaticClass(), UCommandlet::StaticClass(), 0); // Loading list of commandlets declared in .int files
| |
| | |
| for(int i = 0; i < List.Num(); ++i){ // Looking Token up in list and autocompleting class name if found
| |
| FString FullName = List[i].Object;
| |
| FString ShortName = FullName;
| |
| | |
| while(ShortName.InStr(".") >= 0) // Removing package name so that only class name remains
| |
| ShortName = ShortName.Mid(ShortName.InStr(".") + 1);
| |
| | |
| if(ClassName == FullName || ClassName + "Commandlet" == FullName || // Checking against "PackageName.ClassName (+ Commandlet)"
| |
| ClassName == ShortName || ClassName + "Commandlet" == ShortName){ // Checking against "ClassName (+ Commandlet)"
| |
| ClassName = List[i].Object;
| |
| | |
| break;
| |
| }
| |
| }
| |
| | |
| DWORD LoadFlags = LOAD_NoWarn | LOAD_Quiet;
| |
| | |
| if(ClassName == "Editor.MakeCommandlet"){
| |
| // Loading default packages to avoid 'Superclass not found' errors
| |
| UObject::LoadPackage(NULL, "Core", LOAD_NoFail);
| |
| UObject::LoadPackage(NULL, "Engine", LOAD_NoFail);
| |
| LoadFlags |= LOAD_DisallowFiles;
| |
| }
| |
| | |
| UClass* Class = LoadClass<UCommandlet>(NULL, *ClassName, NULL, LoadFlags, NULL);
| |
| | |
| if(!Class) // If class failed to load appending "Commandlet" and trying again
| |
| Class = LoadClass<UCommandlet>(NULL, *(ClassName + "Commandlet"), NULL, LoadFlags, NULL);
| |
| | |
| if(Class){
| |
| UCommandlet* Commandlet = ConstructObject<UCommandlet>(Class);
| |
| UCommandlet* Default = Cast<UCommandlet>(Class->GetDefaultObject());
| |
| | |
| if(Default->ShowBanner)
| |
| ShowBanner(Warn);
| |
| | |
| Warn.Logf("Executing %s", Class->GetFullName());
| |
| Warn.Log("");
| |
| | |
| GIsClient = Default->IsClient;
| |
| GIsEditor = Default->IsEditor;
| |
| GIsServer = Default->IsServer;
| |
| GLazyLoad = Default->LazyLoad;
| |
| | |
| // Contains only the command-line options that are passed to the commandlet
| |
| FString CommandletCmdLine;
| |
| | |
| for(int i = 2; i < argc; ++i)
| |
| CommandletCmdLine += FString(argv[i]) + " ";
| |
| | |
| Commandlet->InitExecution();
| |
| Commandlet->ParseParms(*CommandletCmdLine);
| |
| | |
| if(Default->LogToStdout){ // Redirecting commandlet output to console
| |
| Warn.AuxOut = GLog;
| |
| GLog = &Warn;
| |
| }
| |
| | |
| if(ClassName == "Engine.Server" || ClassName == "Engine.ServerCommandlet")
| |
| UServerCommandletMain(); // The ServerCommandlet has a special Main function
| |
| else
| |
| ExitCode = CommandletMain(Commandlet, CommandletCmdLine);
| |
| | |
| if(Default->ShowErrorCount){
| |
| Warn.Log("");
| |
| Warn.Logf("%s - %i error(s), %i warning(s)", Warn.ErrorCount == 0 ? "Success" : "Failure", Warn.ErrorCount, Warn.WarningCount);
| |
| }
| |
| | |
| if(Default->LogToStdout){
| |
| Warn.AuxOut = NULL;
| |
| GLog = &Log;
| |
| }
| |
| }else{
| |
| ShowBanner(Warn);
| |
| Warn.Logf("Commandlet %s not found", argv[1]);
| |
| }
| |
| }else{
| |
| ShowBanner(Warn);
| |
| Warn.Log("Usage:");
| |
| Warn.Log(" ucc <command> <parameters>");
| |
| }
| |
| | |
| // This prevents an infinite loop during garbage collection when there are compile errors with ucc make
| |
| if(Warn.ErrorCount == 0)
| |
| appPreExit();
| |
| else
| |
| ExitCode = EXIT_FAILURE;
| |
| | |
| GIsGuarded = 0;
| |
| }catch(...){
| |
| GIsGuarded = 0;
| |
| GLog = &Log;
| |
| ExitCode = EXIT_FAILURE;
| |
| Error.HandleError();
| |
| }
| |
| | |
| appExit();
| |
| | |
| return ExitCode;
| |
| }
| |