From 8863db872e9f68d5cbe912c0143743fd43f7d133 Mon Sep 17 00:00:00 2001 From: Robert Beckebans Date: Tue, 9 Nov 2021 19:47:06 +0100 Subject: [PATCH] Added CMake options STANDALONE and DOOM_CLASSIC --- neo/CMakeLists.txt | 60 ++-- neo/framework/Common_mapconvert.cpp | 44 ++- neo/framework/DeclManager.cpp | 42 ++- neo/framework/Licensee.h | 2 +- neo/idlib/MapFile.cpp | 264 ++++++++++++++++++ neo/idlib/MapFile.h | 3 + neo/renderer/Image.h | 3 + neo/renderer/Image_files.cpp | 6 +- neo/swf/SWF_Image.cpp | 3 +- neo/swf/SWF_Load.cpp | 2 +- neo/swf/SWF_Main.cpp | 189 +++++++------ neo/swf/SWF_ScriptFunction.cpp | 2 +- neo/swf/SWF_Sprites.cpp | 12 +- .../addons/io_rbdoom_flash/__init__.py | 6 +- 14 files changed, 506 insertions(+), 132 deletions(-) diff --git a/neo/CMakeLists.txt b/neo/CMakeLists.txt index 98de8c0f..918e9773 100644 --- a/neo/CMakeLists.txt +++ b/neo/CMakeLists.txt @@ -9,6 +9,12 @@ if(CMAKE_MAJOR_VERSION EQUAL 3 AND CMAKE_MINOR_VERSION GREATER_EQUAL 6) set_property (DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT RBDoom3BFG) endif() +option(STANDALONE + "Skip DOOM-3-BFG base/ folder and use assets/ instead" OFF) + +option(DOOM_CLASSIC + "Build with Doom 1 & 2" OFF) + option(FORCE_COLOR_OUTPUT "Always produce ANSI-colored output (GNU/Clang only)." OFF) @@ -16,7 +22,7 @@ option(COMPILE_COMMANDS "Generate compile_commands.json" OFF) option(USE_MFC_TOOLS - "Compile the built-in MFC based tools" OFF) + "Compile the legacy MFC based tools (unsupported)" OFF) option(USE_PRECOMPILED_HEADERS "Use precompiled headers during build" ON) @@ -45,11 +51,8 @@ option(USE_MoltenVK option(ONATIVE "Optimize for the host CPU" OFF) -option(WINRT - "Build for Windows RT" OFF) - option(WINDOWS10 - "Build for Windows 10" OFF) + "Build for Windows 10+" OFF) option(USE_SYSTEM_ZLIB "Use the system zlib instead of the bundled one" OFF) @@ -285,7 +288,7 @@ elseif(MSVC) -D_MBCS -DUSE_EXCEPTIONS) - if( WINRT OR WINDOWS10 ) # Windows RT + if( WINDOWS10 ) # Windows RT add_definitions(-DUSE_WINRT) endif() @@ -308,9 +311,11 @@ if (USE_INTRINSICS_SSE) add_definitions(-DUSE_INTRINSICS_SSE) endif() -#if(STANDALONE) -# add_definitions(-DSTANDALONE) -#endif() +if(STANDALONE) + add_definitions(-DSTANDALONE) + + set(DOOM_CLASSIC OFF) +endif() if (USE_SYSTEM_ZLIB) find_package(ZLIB REQUIRED) @@ -1361,8 +1366,6 @@ set(RBDOOM3_INCLUDES ${UI_INCLUDES} ${SWF_INCLUDES} ${COMMON_INCLUDES} - ${DOOMCLASSIC_INCLUDES} - ${TIMIDITY_INCLUDES} ${COMPILER_INCLUDES} ${COMPILER_AAS_INCLUDES} ${COMPILER_AAS_SOURCES} @@ -1409,8 +1412,6 @@ set(RBDOOM3_SOURCES ${UI_SOURCES} ${SWF_SOURCES} ${COMMON_SOURCES} - ${DOOMCLASSIC_SOURCES} - ${TIMIDITY_SOURCES} ${COMPILER_AAS_SOURCES} ${COMPILER_DMAP_SOURCES} @@ -1427,7 +1428,15 @@ set(RBDOOM3_SOURCES ${GAMED3XP_SCRIPT_SOURCES} ) -add_definitions(-DUSE_DOOMCLASSIC) +if(DOOM_CLASSIC) + add_definitions(-DUSE_DOOMCLASSIC) + + list(APPEND RBDOOM3_INCLUDES ${DOOMCLASSIC_INCLUDES}) + list(APPEND RBDOOM3_INCLUDES ${TIMIDITY_INCLUDES}) + + list(APPEND RBDOOM3_SOURCES ${DOOMCLASSIC_SOURCES}) + list(APPEND RBDOOM3_SOURCES ${TIMIDITY_SOURCES}) +endif() add_definitions(-D__DOOM__ #-DBUILD_FREETYPE @@ -1494,9 +1503,10 @@ if(MSVC) endif() list(APPEND RBDOOM3_INCLUDES ${OPENAL_INCLUDES}) - list(APPEND RBDOOM3_SOURCES - ${OPENAL_SOURCES} - ${DOOMCLASSIC_OPENAL_SOURCES}) + list(APPEND RBDOOM3_SOURCES ${OPENAL_SOURCES}) + if(DOOM_CLASSIC) + list(APPEND RBDOOM3_SOURCES ${DOOMCLASSIC_OPENAL_SOURCES}) + endif() set(OpenAL_LIBRARIES OpenAL32) @@ -1509,9 +1519,11 @@ if(MSVC) endif() else() list(APPEND RBDOOM3_INCLUDES ${XAUDIO2_INCLUDES}) - list(APPEND RBDOOM3_SOURCES - ${XAUDIO2_SOURCES} - ${DOOMCLASSIC_XAUDIO2_SOURCES}) + list(APPEND RBDOOM3_SOURCES ${XAUDIO2_SOURCES}) + + if(DOOM_CLASSIC) + list(APPEND RBDOOM3_SOURCES ${DOOMCLASSIC_XAUDIO2_SOURCES}) + endif() endif() if(FFMPEG) @@ -1715,9 +1727,11 @@ else() ${DOOMCLASSIC_OPENAL_SOURCES}) else() list(APPEND RBDOOM3_INCLUDES ${STUBAUDIO_INCLUDES}) - list(APPEND RBDOOM3_SOURCES - ${STUBAUDIO_SOURCES} - ${DOOMCLASSIC_STUBAUDIO_SOURCES}) + list(APPEND RBDOOM3_SOURCES ${STUBAUDIO_SOURCES}) + + if(DOOM_CLASSIC) + list(APPEND RBDOOM3_SOURCES ${DOOMCLASSIC_STUBAUDIO_SOURCES}) + endif() endif() if(USE_VULKAN) diff --git a/neo/framework/Common_mapconvert.cpp b/neo/framework/Common_mapconvert.cpp index 15a27001..6260579f 100644 --- a/neo/framework/Common_mapconvert.cpp +++ b/neo/framework/Common_mapconvert.cpp @@ -3,7 +3,7 @@ Doom 3 BFG Edition GPL Source Code Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company. -Copyright (C) 2015 Robert Beckebans +Copyright (C) 2015-2021 Robert Beckebans This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code"). @@ -691,3 +691,45 @@ CONSOLE_COMMAND( convertMapToJSON, "Convert .map file to new .json map format wi common->SetRefreshOnPrint( false ); } + +CONSOLE_COMMAND( convertMapToValve220, "Convert .map file to the Valve 220 map format for TrenchBroom", idCmdSystem::ArgCompletion_MapNameNoJson ) +{ + common->SetRefreshOnPrint( true ); + + if( args.Argc() != 2 ) + { + common->Printf( "Usage: convertMapToValve220 \n" ); + return; + } + + idStr filename = args.Argv( 1 ); + if( !filename.Length() ) + { + return; + } + filename.StripFileExtension(); + + idStr mapName; + sprintf( mapName, "maps/%s.map", filename.c_str() ); + + idMapFile map; + if( map.Parse( mapName, true, false ) ) + { + map.ConvertToValve220Format(); + + idStrStatic< MAX_OSPATH > canonical = mapName; + canonical.ToLower(); + + idStrStatic< MAX_OSPATH > extension; + canonical.StripFileExtension(); + + idStrStatic< MAX_OSPATH > convertedFileName; + + convertedFileName = canonical; + convertedFileName += "_valve220"; + + map.Write( convertedFileName, ".map" ); + } + + common->SetRefreshOnPrint( false ); +} diff --git a/neo/framework/DeclManager.cpp b/neo/framework/DeclManager.cpp index 7072ca14..0b67f0cc 100644 --- a/neo/framework/DeclManager.cpp +++ b/neo/framework/DeclManager.cpp @@ -2141,6 +2141,7 @@ void idDeclManagerLocal::ExportDeclsToTrenchBroom_f( const idCmdArgs& args ) ignoreList.AddUnique( "ss" ); ignoreList.AddUnique( "test" ); ignoreList.AddUnique( "underground" ); + ignoreList.AddUnique( "lm_" ); // xbox ignoreList.AddUnique( "xbox" ); @@ -2152,6 +2153,20 @@ void idDeclManagerLocal::ExportDeclsToTrenchBroom_f( const idCmdArgs& args ) ignoreList.AddUnique( "npc" ); ignoreList.AddUnique( "zombie" ); + idStrList solidClassNames; + solidClassNames.AddUnique( "worldspawn" ); + solidClassNames.AddUnique( "func_aas_obstacle" ); + solidClassNames.AddUnique( "func_aas_portal" ); + solidClassNames.AddUnique( "func_clipmodel" ); + solidClassNames.AddUnique( "func_forcefield" ); + solidClassNames.AddUnique( "func_fracture" ); + solidClassNames.AddUnique( "func_liquid" ); + solidClassNames.AddUnique( "func_plat" ); + solidClassNames.AddUnique( "func_rotating" ); + solidClassNames.AddUnique( "func_splinemover" ); + solidClassNames.AddUnique( "moveable_base" ); + solidClassNames.AddUnique( "trigger_" ); + for( int f = 0; f < filenames.Num(); f++ ) { int totalEntitiesCount = 0; @@ -2253,14 +2268,26 @@ void idDeclManagerLocal::ExportDeclsToTrenchBroom_f( const idCmdArgs& args ) } } + bool solidClass = false; + for( int i = 0; i < solidClassNames.Num(); i++ ) + { + const char* solidStr = solidClassNames[ i ].c_str(); + if( idStr::Icmpn( decl->GetName(), solidStr, ( int )strlen( solidStr ) ) == 0 ) + { + solidClass = true; + break; + } + } + + if( idStr::Icmp( decl->GetName(), "trigger_relay" ) == 0 ) + { + solidClass = false; + } // // build header // - const idKeyValue* kv; - kv = decl->dict.MatchPrefix( "inherit", NULL ); - - if( idStr::Icmp( decl->GetName(), "worldspawn" ) == 0 ) + if( solidClass ) { file->Printf( "@SolidClass " ); } @@ -2273,6 +2300,9 @@ void idDeclManagerLocal::ExportDeclsToTrenchBroom_f( const idCmdArgs& args ) file->Printf( "@PointClass " ); } + const idKeyValue* kv; + kv = decl->dict.MatchPrefix( "inherit", NULL ); + if( kv ) { file->Printf( "base(%s) ", kv->GetValue().c_str() ); @@ -2538,6 +2568,10 @@ void idDeclManagerLocal::ExportDeclsToTrenchBroom_f( const idCmdArgs& args ) { file->Printf( "model({ \"path\": \"sprites/speaker.png\", \"scale\": 0.03125 }) " ); } + else if( idStr::Icmp( decl->GetName(), "env_probe" ) == 0 ) + { + file->Printf( "model({ \"path\": \"sprites/360-degree.png\", \"scale\": 0.03125 }) " ); + } else if( idStr::Icmpn( decl->GetName(), "ai_", 3 ) == 0 ) { file->Printf( "model({ \"path\": \"sprites/ai.png\", \"scale\": 0.03125 }) " ); diff --git a/neo/framework/Licensee.h b/neo/framework/Licensee.h index 58f3a158..123549cd 100644 --- a/neo/framework/Licensee.h +++ b/neo/framework/Licensee.h @@ -40,7 +40,7 @@ If you have questions concerning this license or the applicable additional terms // RB: changed home folder so we don't break the savegame of the original game #define SAVE_PATH "\\id Software\\RBDOOM 3 BFG" -#define ENGINE_VERSION "RBDOOM 3 BFG 1.3.0" // printed in console +#define ENGINE_VERSION "RBDOOM 3 BFG 1.3.1" // printed in console // RB end // jmarshall diff --git a/neo/idlib/MapFile.cpp b/neo/idlib/MapFile.cpp index 8b533361..470df8c1 100644 --- a/neo/idlib/MapFile.cpp +++ b/neo/idlib/MapFile.cpp @@ -30,6 +30,7 @@ If you have questions concerning this license or the applicable additional terms #include "precompiled.h" #pragma hdrstop +#include "../renderer/Image.h" /* =============== @@ -124,6 +125,104 @@ void idMapBrushSide::GetTextureVectors( idVec4 v[2] ) const } } +// RB begin +inline bool BrushPrimitive_Degenerate( const idVec3& bpTexMatX, const idVec3& bpTexMatY ) +{ + // 2D cross product + return ( bpTexMatX[0] * bpTexMatY[1] - bpTexMatX[1] * bpTexMatY[0] ) == 0; +} + +void idMapBrushSide::ConvertToValve220Format( const idMat4& entityTransform ) +{ + // create p1, p2, p3 + idVec3 forward = plane.Normal(); + idVec3 p1 = forward * plane.Dist(); + + // create tangents right,up similar as in Quake's MakeNormalVectors + idVec3 right = forward; + right[1] = -forward[0]; + right[2] = forward[1]; + right[0] = forward[2]; + + float d = right * forward; + right = right + ( -d * forward ); + right.Normalize(); + + idVec3 up = right.Cross( forward ); + + // offset p1 by tangents to have 3 points in a plane + idVec3 p2 = p1 + right; + idVec3 p3 = p1 + up; + + // move planepts from entity space to world space because TrenchBroom can only handle brushes in world space + planepts[0] = entityTransform * p1; + planepts[1] = entityTransform * p2; + planepts[2] = entityTransform * p3; + + idVec3 texX, texY; + + ComputeAxisBase( plane.Normal(), texX, texY ); + + texValve[0][0] = texX[0]; + texValve[0][1] = texX[1]; + texValve[0][2] = texX[2]; + + texValve[1][0] = texY[0]; + texValve[1][1] = texY[1]; + texValve[1][2] = texY[2]; + + texScale[0] = 1.0f; + texScale[1] = 1.0f; + + if( BrushPrimitive_Degenerate( texX, texY ) ) + { + //idLib::Warning( "non orthogonal texture matrix in ConvertToValve220Format" ); + } + +#if 0 + // rotate initial axes + for( int i = 0; i < 2; i++ ) + { + texValve[i][0] = texX[0] * texMat[i][0] + texY[0] * texMat[i][1]; + texValve[i][1] = texX[1] * texMat[i][0] + texY[1] * texMat[i][1]; + texValve[i][2] = texX[2] * texMat[i][0] + texY[2] * texMat[i][1]; + //texValve[i][3] = texMat[i][2] + ( origin * texValve[i].ToVec3() ); + } +#endif + + //material = "enpro/enwall16"; + + const idMaterial* material = declManager->FindMaterial( GetMaterial() ); + + idImage* image = material->GetEditorImage(); + if( image != NULL ) + { + texSize.x = image->GetUploadWidth(); + texSize.y = image->GetUploadHeight(); + } + + // compute a fake shift scale rot representation from the texture matrix + // these shift scale rot values are to be understood in the local axis base + texScale[0] = 1.0f / idMath::Sqrt( texMat[0][0] * texMat[0][0] + texMat[1][0] * texMat[1][0] ); + texScale[1] = 1.0f / idMath::Sqrt( texMat[0][1] * texMat[0][1] + texMat[1][1] * texMat[1][1] ); + + texScale[0] /= texSize.x; + texScale[1] /= texSize.y; + + if( texMat[0][0] < idMath::FLOAT_EPSILON ) + { + texScale[0] = -texScale[0]; + } + + if( texMat[1][0] < idMath::FLOAT_EPSILON ) + { + texScale[1] = -texScale[1]; + } + + texValve[0][3] = -texMat[0][2]; + texValve[1][3] = texMat[1][2]; +} + /* ================= idMapPatch::Parse @@ -647,6 +746,8 @@ idMapBrush* idMapBrush::ParseValve220( idLexer& src, const idVec3& origin ) scale[0] = src.ParseFloat(); scale[1] = src.ParseFloat(); + /* + RB: negative values seem to be valid and the q3map2 implementation in netradiant-custom is faulty if( scale[0] < idMath::FLOAT_EPSILON ) { scale[0] = 1.0f; @@ -655,6 +756,7 @@ idMapBrush* idMapBrush::ParseValve220( idLexer& src, const idVec3& origin ) { scale[1] = 1.0f; } + */ side->texScale[0] = scale[0]; side->texScale[1] = scale[1]; @@ -2656,4 +2758,166 @@ bool idMapFile::ConvertToPolygonMeshFormat() return true; } +bool idMapFile::ConvertToValve220Format() +{ + valve220Format = true; + + idDict classTypeOverview; + + int count = GetNumEntities(); + for( int j = 0; j < count; j++ ) + { + idMapEntity* ent = GetEntity( j ); + if( ent ) + { + idStr classname = ent->epairs.GetString( "classname" ); + + if( idStr::Icmp( classname, "worldspawn" ) == 0 ) + { + ent->epairs.Set( "_tb_textures", "textures/common;textures/editor;textures/decals;textures/decals2" ); + } + + if( ent->GetNumPrimitives() > 0 ) + { + // build entity transform + idVec3 origin; + origin.Zero(); + + idMat3 rot; + rot.Identity(); + + idStr name = ent->epairs.GetString( "name" ); + + origin = ent->epairs.GetVector( "origin", "0 0 0" ); + + if( !ent->epairs.GetMatrix( "rotation", "1 0 0 0 1 0 0 0 1", rot ) ) + { + idAngles angles; + + if( ent->epairs.GetAngles( "angles", "0 0 0", angles ) ) + { + if( angles.pitch != 0.0f || angles.yaw != 0.0f || angles.roll != 0.0f ) + { + rot = angles.ToMat3(); + } + else + { + rot.Identity(); + } + } + else + { + float angle = ent->epairs.GetFloat( "angle" ); + if( angle != 0.0f ) + { + rot = idAngles( 0.0f, angle, 0.0f ).ToMat3(); + } + else + { + rot.Identity(); + } + } + } + + idMat4 transform( rot, origin ); + //transform.Identity(); + +#if 1 + if( !transform.IsIdentity() && + idStr::Icmp( classname, "func_static" ) != 0 && + idStr::Icmp( classname, "light" ) != 0 ) + { + ent->epairs.Delete( "origin" ); + ent->epairs.Delete( "rotation" ); + ent->epairs.Delete( "angles" ); + ent->epairs.Delete( "angle" ); + } +#endif + + // convert brushes + for( int i = 0; i < ent->GetNumPrimitives(); i++ ) + { + idMapPrimitive* mapPrim; + + mapPrim = ent->GetPrimitive( i ); + if( mapPrim->GetType() == idMapPrimitive::TYPE_BRUSH ) + { + idMapBrush* brushPrim = static_cast( mapPrim ); + for( int s = 0; s < brushPrim->GetNumSides(); s++ ) + { + idMapBrushSide* side = brushPrim->GetSide( s ); + side->ConvertToValve220Format( transform ); + } + } + } + + const idKeyValue* kv = classTypeOverview.FindKey( classname ); + if( kv && kv->GetValue().Length() ) + { + if( idStr::Icmp( kv->GetValue().c_str(), "PointClass" ) == 0 && idStr::Icmp( kv->GetValue().c_str(), "Mixed" ) != 0 ) + { + classTypeOverview.Set( classname, "Mixed" ); + } + } + else + { + classTypeOverview.Set( classname, "BrushClass" ); + } + } + else + { + const idKeyValue* kv = classTypeOverview.FindKey( classname ); + if( kv && kv->GetValue().Length() ) + { + if( idStr::Icmp( kv->GetValue().c_str(), "BrushClass" ) == 0 && idStr::Icmp( kv->GetValue().c_str(), "Mixed" ) != 0 ) + { + classTypeOverview.Set( classname, "Mixed" ); + } + } + else + { + classTypeOverview.Set( classname, "PointClass" ); + } + } + } + } + + int n = classTypeOverview.GetNumKeyVals(); + + idLib::Printf( "BrushClasses:\n" ); + for( int i = 0; i < n; i++ ) + { + const idKeyValue* kv = classTypeOverview.GetKeyVal( i ); + + if( kv->GetValue() == "BrushClass" ) + { + idLib::Printf( "'%s'\n", kv->GetKey().c_str() ); + } + } + + idLib::Printf( "\nPointClasses:\n" ); + for( int i = 0; i < n; i++ ) + { + const idKeyValue* kv = classTypeOverview.GetKeyVal( i ); + + if( kv->GetValue() == "PointClass" ) + { + idLib::Printf( "'%s'\n", kv->GetKey().c_str() ); + } + } + + idLib::Printf( "\nMixedClasses:\n" ); + for( int i = 0; i < n; i++ ) + { + const idKeyValue* kv = classTypeOverview.GetKeyVal( i ); + + if( kv->GetValue() == "Mixed" ) + { + idLib::Printf( "'%s'\n", kv->GetKey().c_str() ); + } + } + + return true; +} + // RB end diff --git a/neo/idlib/MapFile.h b/neo/idlib/MapFile.h index bf117d6b..04549ec2 100644 --- a/neo/idlib/MapFile.h +++ b/neo/idlib/MapFile.h @@ -132,6 +132,8 @@ public: { return texSize; } + + void ConvertToValve220Format( const idMat4& entityTransform ); // RB end protected: @@ -481,6 +483,7 @@ public: // RB begin bool WriteJSON( const char* fileName, const char* ext, bool fromBasePath = true ); bool ConvertToPolygonMeshFormat(); + bool ConvertToValve220Format(); // RB end // get the number of entities in the map diff --git a/neo/renderer/Image.h b/neo/renderer/Image.h index df10abeb..ca6da870 100644 --- a/neo/renderer/Image.h +++ b/neo/renderer/Image.h @@ -494,6 +494,9 @@ private: }; // data is RGBA +void LoadPNG( const char* filename, unsigned char** pic, int* width, int* height, ID_TIME_T* timestamp ); + +void LoadTGA( const char* name, byte** pic, int* width, int* height, ID_TIME_T* timestamp ); void R_WriteTGA( const char* filename, const byte* data, int width, int height, bool flipVertical = false, const char* basePath = "fs_savepath" ); // data is in top-to-bottom raster order unless flipVertical is set diff --git a/neo/renderer/Image_files.cpp b/neo/renderer/Image_files.cpp index 23b041cd..efc05649 100644 --- a/neo/renderer/Image_files.cpp +++ b/neo/renderer/Image_files.cpp @@ -130,7 +130,7 @@ void R_WriteTGA( const char* filename, const byte* data, int width, int height, fileSystem->WriteFile( filename, buffer, bufferSize, basePath ); } -static void LoadTGA( const char* name, byte** pic, int* width, int* height, ID_TIME_T* timestamp ); +void LoadTGA( const char* name, byte** pic, int* width, int* height, ID_TIME_T* timestamp ); static void LoadJPG( const char* name, byte** pic, int* width, int* height, ID_TIME_T* timestamp ); /* @@ -164,7 +164,7 @@ TARGA LOADING LoadTGA ============= */ -static void LoadTGA( const char* name, byte** pic, int* width, int* height, ID_TIME_T* timestamp ) +void LoadTGA( const char* name, byte** pic, int* width, int* height, ID_TIME_T* timestamp ) { int columns, rows, numPixels, fileSize, numBytes; byte* pixbuf; @@ -668,7 +668,7 @@ extern "C" LoadPNG ============= */ -static void LoadPNG( const char* filename, unsigned char** pic, int* width, int* height, ID_TIME_T* timestamp ) +void LoadPNG( const char* filename, unsigned char** pic, int* width, int* height, ID_TIME_T* timestamp ) { byte* fbuffer; #if PNG_LIBPNG_VER_MAJOR > 1 || PNG_LIBPNG_VER_MINOR > 4 diff --git a/neo/swf/SWF_Image.cpp b/neo/swf/SWF_Image.cpp index 352446f7..15b445b2 100644 --- a/neo/swf/SWF_Image.cpp +++ b/neo/swf/SWF_Image.cpp @@ -339,7 +339,8 @@ void idSWF::WriteSwfImageAtlas( const char* filename ) } // the TGA is only for examination during development - R_WriteTGA( filename, swfAtlas.Ptr(), atlasWidth, atlasHeight, false, "fs_basepath" ); + //R_WriteTGA( filename, swfAtlas.Ptr(), atlasWidth, atlasHeight, false, "fs_basepath" ); + R_WritePNG( filename, swfAtlas.Ptr(), 4, atlasWidth, atlasHeight, true, "fs_basepath" ); } /* diff --git a/neo/swf/SWF_Load.cpp b/neo/swf/SWF_Load.cpp index 98d9aabc..8149a7dc 100644 --- a/neo/swf/SWF_Load.cpp +++ b/neo/swf/SWF_Load.cpp @@ -134,7 +134,7 @@ bool idSWF::LoadSWF( const char* fullpath ) // now that all images have been loaded, write out the combined image idStr atlasFileName = "generated/"; atlasFileName += fullpath; - atlasFileName.SetFileExtension( ".tga" ); + atlasFileName.SetFileExtension( ".png" ); WriteSwfImageAtlas( atlasFileName ); diff --git a/neo/swf/SWF_Main.cpp b/neo/swf/SWF_Main.cpp index 0a802091..067e0e1b 100644 --- a/neo/swf/SWF_Main.cpp +++ b/neo/swf/SWF_Main.cpp @@ -189,7 +189,7 @@ idSWF::idSWF( const char* filename_, idSoundWorld* soundWorld_ ) } idStr atlasFileName = binaryFileName; - atlasFileName.SetFileExtension( ".tga" ); + atlasFileName.SetFileExtension( ".png" ); atlasMaterial = declManager->FindMaterial( atlasFileName ); byte* atlasExportImageRGBA = NULL; @@ -198,112 +198,123 @@ idSWF::idSWF( const char* filename_, idSoundWorld* soundWorld_ ) if( /*!loadedFromJSON &&*/ ( postLoadExportFlashToJSON.GetBool() || postLoadExportFlashAtlas.GetBool() || postLoadExportFlashToSWF.GetBool() ) ) { - idStrStatic< MAX_OSPATH > generatedName = atlasFileName; - generatedName.StripFileExtension(); - idImage::GetGeneratedName( generatedName, TD_DEFAULT, CF_2D ); + // try loading the TGA first + ID_TIME_T timestamp; + //LoadTGA( atlasFileName.c_str(), &atlasExportImageRGBA, &atlasExportImageWidth, &atlasExportImageHeight, ×tamp ); + LoadPNG( atlasFileName.c_str(), &atlasExportImageRGBA, &atlasExportImageWidth, &atlasExportImageHeight, ×tamp ); - idBinaryImage im( generatedName ); - ID_TIME_T binaryFileTime = im.LoadFromGeneratedFile( FILE_NOT_FOUND_TIMESTAMP ); - - if( binaryFileTime != FILE_NOT_FOUND_TIMESTAMP ) + if( ( atlasExportImageRGBA == NULL ) || ( timestamp == FILE_NOT_FOUND_TIMESTAMP ) ) { - const bimageFile_t& imgHeader = im.GetFileHeader(); - const bimageImage_t& img = im.GetImageHeader( 0 ); + idLib::Warning( "failed to load atlas '%s'", atlasFileName.c_str() ); - const byte* data = im.GetImageData( 0 ); + idStrStatic< MAX_OSPATH > generatedName = atlasFileName; + generatedName.StripFileExtension(); + idImage::GetGeneratedName( generatedName, TD_DEFAULT, CF_2D ); - //( img.level, 0, 0, img.destZ, img.width, img.height, data ); + idBinaryImage im( generatedName ); + ID_TIME_T binaryFileTime = im.LoadFromGeneratedFile( FILE_NOT_FOUND_TIMESTAMP ); - idTempArray rgba( img.width * img.height * 4 ); - memset( rgba.Ptr(), 255, rgba.Size() ); - - if( imgHeader.format == FMT_DXT1 ) + if( binaryFileTime != FILE_NOT_FOUND_TIMESTAMP ) { - idDxtDecoder dxt; - dxt.DecompressImageDXT1( data, rgba.Ptr(), img.width, img.height ); - } - else if( imgHeader.format == FMT_DXT5 ) - { - idDxtDecoder dxt; + const bimageFile_t& imgHeader = im.GetFileHeader(); + const bimageImage_t& img = im.GetImageHeader( 0 ); - if( imgHeader.colorFormat == CFM_NORMAL_DXT5 ) + const byte* data = im.GetImageData( 0 ); + + //( img.level, 0, 0, img.destZ, img.width, img.height, data ); + + idTempArray rgba( img.width * img.height * 4 ); + memset( rgba.Ptr(), 255, rgba.Size() ); + + if( imgHeader.format == FMT_DXT1 ) { - dxt.DecompressNormalMapDXT5( data, rgba.Ptr(), img.width, img.height ); + idDxtDecoder dxt; + dxt.DecompressImageDXT1( data, rgba.Ptr(), img.width, img.height ); } - else if( imgHeader.colorFormat == CFM_YCOCG_DXT5 ) + else if( imgHeader.format == FMT_DXT5 ) { - dxt.DecompressYCoCgDXT5( data, rgba.Ptr(), img.width, img.height ); + idDxtDecoder dxt; + + if( imgHeader.colorFormat == CFM_NORMAL_DXT5 ) + { + dxt.DecompressNormalMapDXT5( data, rgba.Ptr(), img.width, img.height ); + } + else if( imgHeader.colorFormat == CFM_YCOCG_DXT5 ) + { + dxt.DecompressYCoCgDXT5( data, rgba.Ptr(), img.width, img.height ); + } + else + { + + dxt.DecompressImageDXT5( data, rgba.Ptr(), img.width, img.height ); + } + } + else if( imgHeader.format == FMT_LUM8 || imgHeader.format == FMT_INT8 ) + { + // LUM8 and INT8 just read the red channel + byte* pic = rgba.Ptr(); + for( int i = 0; i < img.dataSize; i++ ) + { + pic[ i * 4 ] = data[ i ]; + } + } + else if( imgHeader.format == FMT_ALPHA ) + { + // ALPHA reads the alpha channel + byte* pic = rgba.Ptr(); + for( int i = 0; i < img.dataSize; i++ ) + { + pic[ i * 4 + 3 ] = data[ i ]; + } + } + else if( imgHeader.format == FMT_L8A8 ) + { + // L8A8 reads the alpha and red channels + byte* pic = rgba.Ptr(); + for( int i = 0; i < img.dataSize / 2; i++ ) + { + pic[ i * 4 + 0 ] = data[ i * 2 + 0 ]; + pic[ i * 4 + 3 ] = data[ i * 2 + 1 ]; + } + } + else if( imgHeader.format == FMT_RGB565 ) + { + // FIXME + /* + byte* pic = rgba.Ptr(); + for( int i = 0; i < img.dataSize / 2; i++ ) + { + unsigned short color = ( ( pic[ i * 4 + 0 ] >> 3 ) << 11 ) | ( ( pic[ i * 4 + 1 ] >> 2 ) << 5 ) | ( pic[ i * 4 + 2 ] >> 3 ); + img.data[ i * 2 + 0 ] = ( color >> 8 ) & 0xFF; + img.data[ i * 2 + 1 ] = color & 0xFF; + } + */ } else { + byte* pic = rgba.Ptr(); + for( int i = 0; i < img.dataSize; i++ ) + { + pic[ i ] = data[ i ]; + } + } - dxt.DecompressImageDXT5( data, rgba.Ptr(), img.width, img.height ); - } - } - else if( imgHeader.format == FMT_LUM8 || imgHeader.format == FMT_INT8 ) - { - // LUM8 and INT8 just read the red channel - byte* pic = rgba.Ptr(); - for( int i = 0; i < img.dataSize; i++ ) - { - pic[ i * 4 ] = data[ i ]; - } - } - else if( imgHeader.format == FMT_ALPHA ) - { - // ALPHA reads the alpha channel - byte* pic = rgba.Ptr(); - for( int i = 0; i < img.dataSize; i++ ) - { - pic[ i * 4 + 3 ] = data[ i ]; - } - } - else if( imgHeader.format == FMT_L8A8 ) - { - // L8A8 reads the alpha and red channels - byte* pic = rgba.Ptr(); - for( int i = 0; i < img.dataSize / 2; i++ ) - { - pic[ i * 4 + 0 ] = data[ i * 2 + 0 ]; - pic[ i * 4 + 3 ] = data[ i * 2 + 1 ]; - } - } - else if( imgHeader.format == FMT_RGB565 ) - { - // FIXME - /* - byte* pic = rgba.Ptr(); - for( int i = 0; i < img.dataSize / 2; i++ ) - { - unsigned short color = ( ( pic[ i * 4 + 0 ] >> 3 ) << 11 ) | ( ( pic[ i * 4 + 1 ] >> 2 ) << 5 ) | ( pic[ i * 4 + 2 ] >> 3 ); - img.data[ i * 2 + 0 ] = ( color >> 8 ) & 0xFF; - img.data[ i * 2 + 1 ] = color & 0xFF; - } - */ - } - else - { - byte* pic = rgba.Ptr(); - for( int i = 0; i < img.dataSize; i++ ) - { - pic[ i ] = data[ i ]; - } - } + idStr atlasFileNameExport = atlasFileName; + atlasFileNameExport.Replace( "generated/", "exported/" ); + atlasFileNameExport.SetFileExtension( ".png" ); - idStr atlasFileNameExport = atlasFileName; - atlasFileNameExport.Replace( "generated/", "exported/" ); - atlasFileNameExport.SetFileExtension( ".png" ); + R_WritePNG( atlasFileNameExport, rgba.Ptr(), 4, img.width, img.height, true, "fs_basepath" ); - R_WritePNG( atlasFileNameExport, rgba.Ptr(), 4, img.width, img.height, true, "fs_basepath" ); - - if( postLoadExportFlashToSWF.GetBool() ) - { - atlasExportImageWidth = img.width; - atlasExportImageHeight = img.height; - atlasExportImageRGBA = ( byte* ) Mem_Alloc( rgba.Size(), TAG_TEMP ); - memcpy( atlasExportImageRGBA, rgba.Ptr(), rgba.Size() ); + if( postLoadExportFlashToSWF.GetBool() ) + { + atlasExportImageWidth = img.width; + atlasExportImageHeight = img.height; + atlasExportImageRGBA = ( byte* ) Mem_Alloc( rgba.Size(), TAG_TEMP ); + memcpy( atlasExportImageRGBA, rgba.Ptr(), rgba.Size() ); + } } } + } if( postLoadExportFlashToSWF.GetBool() ) diff --git a/neo/swf/SWF_ScriptFunction.cpp b/neo/swf/SWF_ScriptFunction.cpp index e5f01e32..a8c6becb 100644 --- a/neo/swf/SWF_ScriptFunction.cpp +++ b/neo/swf/SWF_ScriptFunction.cpp @@ -2997,7 +2997,7 @@ idStr idSWFScriptFunction_Script::ExportToScript( idSWFScriptObject* thisObject, finish: idStr actionScript = BuildActionCode( actionBlocks, 0 ); - idLib::Printf( "%s.Sprite%i script:\n%s\n", filename, characterID, actionScript.c_str() ); + //idLib::Printf( "%s.Sprite%i script:\n%s\n", filename, characterID, actionScript.c_str() ); return actionScript; } diff --git a/neo/swf/SWF_Sprites.cpp b/neo/swf/SWF_Sprites.cpp index dac3ac53..6f6559cf 100644 --- a/neo/swf/SWF_Sprites.cpp +++ b/neo/swf/SWF_Sprites.cpp @@ -693,7 +693,7 @@ void idSWFSprite::WriteJSON_PlaceObject3( idFile* file, idSWFBitStream& bitstrea // can't support anything after the filter list either (blend modes and clip actions) //idLib::Warning( "PlaceObject3: has filters" ); file->WriteFloatString( ",\n\t\t\t\t\t\"hasFilterList\": true" ); - return; + //return; } if( ( flags2 & PlaceFlagHasBlendMode ) != 0 ) @@ -719,12 +719,14 @@ void idSWFSprite::WriteJSON_RemoveObject2( idFile* file, idSWFBitStream& bitstre void idSWFSprite::WriteJSON_DoAction( idFile* file, idSWFBitStream& bitstream, int characterID, int commandID, const char* indentPrefix ) { +#if 1 idBase64 base64; base64.Encode( bitstream.Ptr(), bitstream.Length() ); -#if 0 - file->WriteFloatString( "%s\t\t\t\t{\t\"type\": \"Tag_DoAction\", \"streamLength\": %i, \"stream\": \"%s\" }", ( commandID != 0 ) ? ",\n" : "", bitstream.Length(), base64.c_str() ); +#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() ); #else idSWFScriptObject* scriptObject = idSWFScriptObject::Alloc(); scriptObject->SetPrototype( &spriteInstanceScriptObjectPrototype ); @@ -750,9 +752,7 @@ void idSWFSprite::WriteJSON_DoAction( idFile* file, idSWFBitStream& bitstream, i delete scriptObject; #endif - - - +#endif } diff --git a/tools/blender/blender-2.93/scripts/addons/io_rbdoom_flash/__init__.py b/tools/blender/blender-2.93/scripts/addons/io_rbdoom_flash/__init__.py index 41683738..b9fe48c9 100644 --- a/tools/blender/blender-2.93/scripts/addons/io_rbdoom_flash/__init__.py +++ b/tools/blender/blender-2.93/scripts/addons/io_rbdoom_flash/__init__.py @@ -10,8 +10,10 @@ import os from decimal import * from math import * -jsonfilename = "C:\\Projects\\RBDOOM-3-BFG\\base\\exported\\swf\\shell.json" -basepath = "C:\\Projects\\RBDOOM-3-BFG\\base\\" +#jsonfilename = "C:\\Projects\\RBDOOM-3-BFG\\base\\exported\\swf\\shell.json" +jsonfilename = "C:\\Projects\\RBDOOM-3-BFG\\mod_ragetoolkit\\exported\\swf\\hud.json" + +basepath = "C:\\Projects\\RBDOOM-3-BFG\\mod_ragetoolkit\\" start = time.time() data = json.loads( open( jsonfilename ).read() )