Fixed a couple of bugs regarding Flash JSON reimport

This commit is contained in:
Robert Beckebans 2024-07-01 22:35:27 +02:00
parent b52d2eece3
commit 1639c37ca5
7 changed files with 105 additions and 27 deletions

View file

@ -662,9 +662,6 @@ convertMapQuakeToDoom `<map>` | Command: Expects a Quake 1 .map in the
makeZooMapForModels | Command: Makes a Source engine style zoo map with mapobject/models like .blwo, .base et cetera and saves it to maps/zoomaps/zoo_models.map. This helps mappers to get a good overview of the trememdous amount of custom models available in Doom 3 BFG by sorting them into categories and arranging them in 3D. It also filters models so that only modular models are picked that can be reused in new maps.
exportEntityDefsToBlender | Command: Exports all entity and model defs to base/_bl/entities.json for usage in Blender before loading a map.
exportMapToOBJ | Command: Convert .map file to .obj/.mtl
postLoadExportFlashAtlas | Cvar: Set to 1 at startup to dump the Flash images to exported/swf/
postLoadExportFlashToSWF | Cvar: Set to 1 at startup to dump the Flash .bswf files as .swf (WIP)
postLoadExportFlashToJSON | Cvar: Set to 1 at startup to dump the Flash .bswf files as .json. Can be reimported into the engine and imported into Blender for inspection
swf_show | Cvar: Draws the bounding box of instanced Flash sprites in red and their names
makeMaterials `<folder>` | Command: Make a .mtr file based on PBR naming conventions

View file

@ -811,8 +811,8 @@ void idCommonDialog::Init()
Shutdown();
dialog = new( TAG_SWF ) idSWF( "dialog" );
saveIndicator = new( TAG_SWF ) idSWF( "save_indicator" );
dialog = new( TAG_SWF ) idSWF( "dialog", NULL );
saveIndicator = new( TAG_SWF ) idSWF( "save_indicator", NULL );
#define BIND_DIALOG_CONSTANT( x ) dialog->SetGlobal( #x, x )
if( dialog != NULL )

View file

@ -86,7 +86,7 @@ This class handles loading and rendering SWF files
class idSWF
{
public:
idSWF( const char* filename, idSoundWorld* soundWorld = NULL );
idSWF( const char* filename, idSoundWorld* soundWorld, bool exportJSON = false, bool exportSWF = false );
~idSWF();
bool IsLoaded()

View file

@ -1154,7 +1154,7 @@ bool idSWF::LoadJSON( const char* filename )
for( int d = 0; d < shape->lineDraws.Num(); d++ )
{
idSWFShapeDrawLine& lineDraw = shape->lineDraws[d];
Value& jsonDraw = entry["lineDraw"][d];
Value& jsonDraw = entry["lineDraws"][d];
Value& style = jsonDraw["style"];
lineDraw.style.startWidth = style["startWidth"].GetUint();
@ -1808,4 +1808,5 @@ void idSWF::WriteJSON( const char* jsonFilename )
file->WriteFloatString( "\t]\n" );
file->WriteFloatString( "}\n" );
}
// RB end

View file

@ -34,11 +34,6 @@ If you have questions concerning this license or the applicable additional terms
#pragma warning(disable: 4355) // 'this' : used in base member initializer list
idCVar swf_loadBinary( "swf_loadBinary", "1", CVAR_INTEGER, "used to set whether to load binary swf from generated" );
// RB begin
idCVar postLoadExportFlashAtlas( "postLoadExportFlashAtlas", "0", CVAR_INTEGER, "" );
idCVar postLoadExportFlashToSWF( "postLoadExportFlashToSWF", "0", CVAR_INTEGER, "" );
idCVar postLoadExportFlashToJSON( "postLoadExportFlashToJSON", "0", CVAR_INTEGER, "" );
// RB end
int idSWF::mouseX = -1;
int idSWF::mouseY = -1;
@ -53,7 +48,7 @@ extern idCVar in_useJoystick;
idSWF::idSWF
===================
*/
idSWF::idSWF( const char* filename_, idSoundWorld* soundWorld_ )
idSWF::idSWF( const char* filename_, idSoundWorld* soundWorld_, bool exportJSON, bool exportSWF )
{
atlasMaterial = NULL;
@ -179,7 +174,7 @@ idSWF::idSWF( const char* filename_, idSoundWorld* soundWorld_ )
}
}
if( postLoadExportFlashToJSON.GetBool() )
if( exportJSON )
{
idStr jsonFileName = "exported/";
jsonFileName += filename;
@ -196,7 +191,7 @@ idSWF::idSWF( const char* filename_, idSoundWorld* soundWorld_ )
int atlasExportImageWidth = 0;
int atlasExportImageHeight = 0;
if( /*!loadedFromJSON &&*/ ( postLoadExportFlashToJSON.GetBool() || postLoadExportFlashAtlas.GetBool() || postLoadExportFlashToSWF.GetBool() ) )
if( /*!loadedFromJSON &&*/ ( exportJSON || exportSWF ) )
{
// try loading the TGA first
ID_TIME_T timestamp;
@ -205,7 +200,7 @@ idSWF::idSWF( const char* filename_, idSoundWorld* soundWorld_ )
if( ( atlasExportImageRGBA == NULL ) || ( timestamp == FILE_NOT_FOUND_TIMESTAMP ) )
{
idLib::Warning( "failed to load atlas '%s'", atlasFileName.c_str() );
//idLib::Warning( "failed to load atlas '%s'", atlasFileName.c_str() );
idStrStatic< MAX_OSPATH > generatedName = atlasFileName;
generatedName.StripFileExtension();
@ -221,15 +216,33 @@ idSWF::idSWF( const char* filename_, idSoundWorld* soundWorld_ )
const byte* data = im.GetImageData( 0 );
//( img.level, 0, 0, img.destZ, img.width, img.height, data );
// RB: Images that are were DXT compressed and aren't multiples of 4 were padded out before compressing
// however the idBinaryImageData stores the original input width and height.
// We need multiples of 4 for the decompression routines
idTempArray<byte> rgba( img.width * img.height * 4 );
int dxtWidth = img.width;
int dxtHeight = img.height;
if( imgHeader.format == FMT_DXT5 || imgHeader.format == FMT_DXT1 )
{
if( ( img.width & 3 ) || ( img.height & 3 ) )
{
dxtWidth = ( img.width + 3 ) & ~3;
dxtHeight = ( img.height + 3 ) & ~3;
}
}
idTempArray<byte> rgba( dxtWidth * dxtHeight * 4 );
memset( rgba.Ptr(), 255, rgba.Size() );
if( imgHeader.format == FMT_DXT1 )
{
idDxtDecoder dxt;
dxt.DecompressImageDXT1( data, rgba.Ptr(), img.width, img.height );
dxt.DecompressImageDXT1( data, rgba.Ptr(), dxtWidth, dxtHeight );
for( int i = 0; i < ( dxtWidth * dxtHeight ); i++ )
{
rgba[i * 4 + 3] = 255;
}
}
else if( imgHeader.format == FMT_DXT5 )
{
@ -237,16 +250,33 @@ idSWF::idSWF( const char* filename_, idSoundWorld* soundWorld_ )
if( imgHeader.colorFormat == CFM_NORMAL_DXT5 )
{
dxt.DecompressNormalMapDXT5( data, rgba.Ptr(), img.width, img.height );
dxt.DecompressNormalMapDXT5( data, rgba.Ptr(), dxtWidth, dxtHeight );
for( int i = 0; i < ( dxtWidth * dxtHeight ); i++ )
{
rgba[i * 4 + 3] = 255;
}
}
/*
else if( imgHeader.colorFormat == CFM_YCOCG_DXT5 )
{
dxt.DecompressYCoCgDXT5( data, rgba.Ptr(), img.width, img.height );
dxt.DecompressYCoCgDXT5( data, rgba.Ptr(), dxtWidth, dxtHeight );
idColorSpace::ConvertCoCg_YToRGB( rgba.Ptr(), rgba.Ptr(), dxtWidth, dxtHeight );
for( int i = 0; i < ( dxtWidth * dxtHeight ); i++ )
{
rgba[i * 4 + 3] = 255;
}
}
*/
else
{
dxt.DecompressImageDXT5( data, rgba.Ptr(), dxtWidth, dxtHeight );
dxt.DecompressImageDXT5( data, rgba.Ptr(), img.width, img.height );
for( int i = 0; i < ( dxtWidth * dxtHeight ); i++ )
{
rgba[i * 4 + 3] = 255;
}
}
}
else if( imgHeader.format == FMT_LUM8 || imgHeader.format == FMT_INT8 )
@ -303,9 +333,11 @@ idSWF::idSWF( const char* filename_, idSoundWorld* soundWorld_ )
atlasFileNameExport.Replace( "generated/", "exported/" );
atlasFileNameExport.SetFileExtension( ".png" );
idLib::Printf( "Exporting image '%s'\n", atlasFileNameExport.c_str() );
R_WritePNG( atlasFileNameExport, rgba.Ptr(), 4, img.width, img.height, "fs_basepath" );
if( postLoadExportFlashToSWF.GetBool() )
if( exportSWF )
{
atlasExportImageWidth = img.width;
atlasExportImageHeight = img.height;
@ -317,7 +349,7 @@ idSWF::idSWF( const char* filename_, idSoundWorld* soundWorld_ )
}
if( postLoadExportFlashToSWF.GetBool() )
if( exportSWF )
{
idStr swfFileName = "exported/";
swfFileName += filename;
@ -974,3 +1006,51 @@ void idSWF::idSWFScriptNativeVar_crop::Set( idSWFScriptObject* object, const idS
{
pThis->crop = value.ToBool();
}
// RB begin
CONSOLE_COMMAND_SHIP( exportFlash, "Export all .bswf files to the exported/swf/ folder", NULL )
{
bool exportSWF = false;
for( int i = 1; i < args.Argc(); i++ )
{
idStr option = args.Argv( i );
option.StripLeading( '-' );
if( option.Icmp( "swf" ) == 0 )
{
exportSWF = true;
}
}
idFileList* files = fileSystem->ListFilesTree( "generated", ".bswf", true, true );
for( int f = 0; f < files->GetList().Num(); f++ )
{
idStr bswfName = files->GetList()[ f ];
#if 0
// only export hud for testing
if( idStr::Icmp( bswfName, "generated/swf/hud.bswf" ) != 0 )
{
continue;
}
#endif
/*
idFileLocal bFile = fileSystem->OpenFileRead( bswfName );
if( bFile == NULL )
{
continue;
}
*/
bswfName.StripLeadingOnce( "generated/" );
idSWF* swf = new idSWF( bswfName, NULL, true, true ); //exportSWF );
delete swf;
}
fileSystem->FreeFileList( files );
}
// RB end

View file

@ -427,7 +427,7 @@ void idSWFSpriteInstance::RunTo( int targetFrame )
targetFrame = sprite->frameOffsets.Num() - 1;
}
// actions.Clear();
//actions.Clear();
uint32 firstActionCommand = sprite->frameOffsets[ targetFrame - 1 ];

View file

@ -725,8 +725,8 @@ void idSWFSprite::WriteJSON_DoAction( idFile* file, idSWFBitStream& bitstream, i
base64.Encode( bitstream.Ptr(), bitstream.Length() );
#if 1
//file->WriteFloatString( "%s\t\t\t\t{\t\"type\": \"Tag_DoAction\", \"streamLength\": %i, \"stream\": \"%s\" }", ( commandID != 0 ) ? ",\n" : "", bitstream.Length(), base64.c_str() );
file->WriteFloatString( "%s\t\t\t\t{\t\"type\": \"Tag_DoAction\", \"streamLength\": %i, \"stream\": \"FIXME\" }", ( commandID != 0 ) ? ",\n" : "", bitstream.Length() );
file->WriteFloatString( "%s\t\t\t\t{\t\"type\": \"Tag_DoAction\", \"streamLength\": %i, \"stream\": \"%s\" }", ( commandID != 0 ) ? ",\n" : "", bitstream.Length(), base64.c_str() );
//file->WriteFloatString( "%s\t\t\t\t{\t\"type\": \"Tag_DoAction\", \"streamLength\": %i, \"stream\": \"FIXME\" }", ( commandID != 0 ) ? ",\n" : "", bitstream.Length() );
#else
idSWFScriptObject* scriptObject = idSWFScriptObject::Alloc();
scriptObject->SetPrototype( &spriteInstanceScriptObjectPrototype );