Added CMake options STANDALONE and DOOM_CLASSIC

This commit is contained in:
Robert Beckebans 2021-11-09 19:47:06 +01:00
parent ebdea5f6c9
commit 8863db872e
14 changed files with 506 additions and 132 deletions

View file

@ -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)

View file

@ -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 <map>\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 );
}

View file

@ -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 }) " );

View file

@ -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

View file

@ -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<idMapBrush*>( 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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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" );
}
/*

View file

@ -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 );

View file

@ -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, &timestamp );
LoadPNG( atlasFileName.c_str(), &atlasExportImageRGBA, &atlasExportImageWidth, &atlasExportImageHeight, &timestamp );
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<byte> 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<byte> 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() )

View file

@ -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;
}

View file

@ -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
}

View file

@ -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() )