mirror of
https://github.com/1dot13/source.git
synced 2026-07-29 13:52:17 +02:00
ja2export is not vendored, we own that + fix errors
stop lying about it by keeping it in ext/ fix three errors in clang-cl
This commit is contained in:
committed by
majcosta
parent
fc1c1dfe77
commit
fd47a422b5
@@ -0,0 +1,29 @@
|
||||
option(BUILD_JA2EXPORT "Build the Ja2Export tool." ON)
|
||||
|
||||
if(BUILD_JA2EXPORT)
|
||||
message(STATUS "Configuring Ja2Export")
|
||||
|
||||
add_executable(Ja2Export
|
||||
init_vfs.cpp
|
||||
main.cpp
|
||||
progress_bar.cpp
|
||||
ja2/himage.cpp
|
||||
ja2/XMLWriter.cpp
|
||||
export/jsd/export_jsd.cpp
|
||||
export/jsd/structure.cpp
|
||||
export/slf/export_slf.cpp
|
||||
export/sti/export_sti.cpp
|
||||
export/sti/Image.cpp
|
||||
export/sti/stci_image_utils.cpp
|
||||
export/sti/STCI_lib.cpp
|
||||
)
|
||||
target_include_directories(Ja2Export PUBLIC
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}"
|
||||
)
|
||||
target_link_libraries(Ja2Export PUBLIC bfVFS libpng)
|
||||
set_target_properties(Ja2Export PROPERTIES
|
||||
RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}
|
||||
)
|
||||
else()
|
||||
message(STATUS "BUILD_JA2EXPORT set to \"OFF\", not configuring Ja2Export")
|
||||
endif()
|
||||
@@ -0,0 +1,96 @@
|
||||
|
||||
#include <export/jsd/export_jsd.h>
|
||||
|
||||
#include <init_vfs.h>
|
||||
#include <progress_bar.h>
|
||||
|
||||
#include <vfs/Core/vfs.h>
|
||||
#include <vfs/Core/vfs_file_raii.h>
|
||||
#include <vfs/Core/File/vfs_buffer_file.h>
|
||||
#include <vfs/Ext/slf/vfs_slf_library.h>
|
||||
#include <vfs/Ext/7z/vfs_create_7z_library.h>
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include <export/jsd/structure.h>
|
||||
|
||||
bool ja2xp::convertJSDtoXML(vfs::Path const& sSrc, vfs::Path const& sDst)
|
||||
{
|
||||
vfs::CVirtualFileSystem::Iterator it = getVFS()->begin(sSrc);
|
||||
int file_counter = 0;
|
||||
for(; !it.end(); it.next())
|
||||
{
|
||||
file_counter++;
|
||||
vfs::String::str_t fname = it.value()->getPath().c_wcs();
|
||||
if( !vfs::StrCmp::Equal( fname.substr(fname.length()-4,4), L".jsd") )
|
||||
{
|
||||
std::wcout << L"\"" << fname << L"\" " << L"is not an .jsd file" << std::endl;
|
||||
continue;
|
||||
}
|
||||
if(!it.value()->openRead())
|
||||
{
|
||||
std::wcout << L"Could not open file \"" << sSrc() << L"\"" << std::endl;
|
||||
continue;
|
||||
}
|
||||
vfs::String::str_t new_fname = fname.substr(0,fname.length()-4) + L".jsd.xml";
|
||||
vfs::Path out_name;
|
||||
if(vfs::StrCmp::Equal(sDst(), L"."))
|
||||
{
|
||||
out_name = vfs::Path(new_fname);
|
||||
}
|
||||
else
|
||||
{
|
||||
out_name = sDst;
|
||||
}
|
||||
|
||||
std::wcout << L"Converting file \"" << it.value()->getPath().c_wcs() << L"\"" << std::endl;
|
||||
|
||||
vfs::COpenWriteFile wfile(out_name,true,true);
|
||||
if(!ConvertStructure(it.value(), &wfile.file()))
|
||||
{
|
||||
printf("Error converting file : %s", vfs::String::as_utf8(it.value()->getPath()()).c_str());
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if(file_counter == 0)
|
||||
{
|
||||
std::wcout << L"Nothing to convert!" << std::endl;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**********************************************************************************************/
|
||||
|
||||
const wchar_t* ja2xp::CExportJSD::commandString = L"jsd";
|
||||
|
||||
void ja2xp::CExportJSD::handleCommand(param_list_t const& params)
|
||||
{
|
||||
//param_list_t::const_iterator cit = params.begin();
|
||||
//for(; cit != params.end(); ++cit)
|
||||
//{
|
||||
//}
|
||||
|
||||
ja2xp::InitVFS& vfs = ja2xp::InitVFS::instance();
|
||||
vfs.checkParameters(params);
|
||||
if(!vfs.init())
|
||||
{
|
||||
return;
|
||||
}
|
||||
try
|
||||
{
|
||||
convertJSDtoXML(vfs.srcPattern(), vfs.dstPattern());
|
||||
}
|
||||
catch(vfs::Exception& msg)
|
||||
{
|
||||
std::wcout << msg.getLastEntryString().c_str() << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
void ja2xp::CExportJSD::printHelp()
|
||||
{
|
||||
std::wcout
|
||||
<< L" convert JSD to XML file(s)" << std::endl
|
||||
<< L" * if \"destination\" is a directory, then the filename's extension will be" << std::endl
|
||||
<< L" replaced with \".jsd.xml\"" << std::endl
|
||||
<< std::endl;
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
#ifndef _EXPORT_JSD_H_
|
||||
#define _EXPORT_SLF_H_
|
||||
|
||||
#include <vfs/Core/vfs_path.h>
|
||||
#include <vfs/Core/Interface/vfs_file_interface.h>
|
||||
|
||||
#include <exporter_base.h>
|
||||
|
||||
namespace ja2xp
|
||||
{
|
||||
class CExportJSD : public IExporterBase
|
||||
{
|
||||
public:
|
||||
typedef IExporterBase::param_list_t param_list_t;
|
||||
|
||||
static const wchar_t* commandString;// = L"jsd";
|
||||
|
||||
virtual void handleCommand(param_list_t const& params);
|
||||
virtual void printHelp();
|
||||
};
|
||||
|
||||
bool convertJSDtoXML(vfs::Path const& sSrc, vfs::Path const& sDst);
|
||||
};
|
||||
|
||||
#endif // _EXPORT_SLF_H_
|
||||
@@ -0,0 +1,293 @@
|
||||
#include <export/jsd/structure.h>
|
||||
#include <vfs/Core/vfs_file_raii.h>
|
||||
#include <vfs/Tools/vfs_tools.h>
|
||||
|
||||
#include <types.h>
|
||||
#include <XMLWriter.h>
|
||||
#include <sgp_auto_memory.h>
|
||||
#include <Structure Internals.h>
|
||||
|
||||
bool ja2xp::ConvertStructure(vfs::tReadableFile* pStructureFile, vfs::tWritableFile* pOutputFile)
|
||||
{
|
||||
vfs::tReadableFile *pFile = pStructureFile;
|
||||
if(!pFile)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
vfs::COpenReadFile rfile(pFile);
|
||||
|
||||
XMLWriter xmlw;
|
||||
xmlw.addAttributeToNextValue( "filename", vfs::String::as_utf8( rfile->getPath()() ) );
|
||||
xmlw.openNode("STRUCTURE_FILE");
|
||||
|
||||
// Read Header
|
||||
STRUCTURE_FILE_HEADER Header;
|
||||
rfile->read((vfs::Byte*)&Header, sizeof( STRUCTURE_FILE_HEADER ));
|
||||
|
||||
// Write Header data
|
||||
xmlw.openNode("HEADER");
|
||||
xmlw.addValue("szId", std::string(Header.szId,0,4));
|
||||
xmlw.addValue("usNumberOfStructures", Header.usNumberOfStructures);
|
||||
xmlw.addValue("usNumberOfImages", Header.usNumberOfImages);
|
||||
|
||||
xmlw.addValue("usNumberOfStructuresStored", Header.usNumberOfStructuresStored);
|
||||
xmlw.addValue("usNumberOfImageTileLocsStored", Header.usNumberOfImageTileLocsStored);
|
||||
xmlw.addValue("usStructureDataSize", Header.usStructureDataSize);
|
||||
if(Header.fFlags > 0)
|
||||
{
|
||||
xmlw.addAttributeToNextValue("uint",(void*)((UINT32)Header.fFlags));
|
||||
xmlw.openNode("flags");
|
||||
xmlw.addFlag(Header.fFlags, STRUCTURE_FILE_CONTAINS_AUXIMAGEDATA, "STRUCTURE_FILE_CONTAINS_AUXIMAGEDATA");
|
||||
xmlw.addFlag(Header.fFlags, STRUCTURE_FILE_CONTAINS_STRUCTUREDATA, "STRUCTURE_FILE_CONTAINS_STRUCTUREDATA");
|
||||
xmlw.closeNode();
|
||||
}
|
||||
else
|
||||
{
|
||||
xmlw.addValue("flags");
|
||||
}
|
||||
xmlw.closeNode();
|
||||
|
||||
if (Header.fFlags & STRUCTURE_FILE_CONTAINS_AUXIMAGEDATA)
|
||||
{
|
||||
UINT32 uiDataSize = sizeof( AuxObjectData ) * Header.usNumberOfImages;
|
||||
sgp::AutoArray<AuxObjectData> pAuxData(uiDataSize);
|
||||
VFS_THROW_IFF( pAuxData(), L"" );
|
||||
|
||||
// Read AuxImage data
|
||||
VFS_THROW_IFF( uiDataSize == rfile->read( (vfs::Byte*)pAuxData(), uiDataSize ), L"" );
|
||||
|
||||
// Write AuxImage data
|
||||
xmlw.addAttributeToNextValue("number_of", Header.usNumberOfImages);
|
||||
xmlw.openNode("AUXIMAGE_DATA");
|
||||
for(int i = 0; i < Header.usNumberOfImages; ++i)
|
||||
{
|
||||
xmlw.addAttributeToNextValue("index",i);
|
||||
xmlw.openNode("auximage");
|
||||
AuxObjectData& auximage = pAuxData[i];
|
||||
xmlw.addValue("tile_loc_index", (int)auximage.usTileLocIndex);
|
||||
xmlw.addValue("wall_orientation", (int)auximage.ubWallOrientation);
|
||||
xmlw.addValue("number_of_tiles", (int)auximage.ubNumberOfTiles);
|
||||
xmlw.addValue("current_frame", (int)auximage.ubCurrentFrame);
|
||||
xmlw.addValue("number_of_frames", (int)auximage.ubNumberOfFrames);
|
||||
if(auximage.fFlags > 0)
|
||||
{
|
||||
xmlw.addAttributeToNextValue("uint", (void*)((UINT32)auximage.fFlags));
|
||||
xmlw.openNode("flags");
|
||||
xmlw.addFlag(auximage.fFlags, AUX_FULL_TILE, "AUX_FULL_TILE");
|
||||
xmlw.addFlag(auximage.fFlags, AUX_ANIMATED_TILE, "AUX_ANIMATED_TILE");
|
||||
xmlw.addFlag(auximage.fFlags, AUX_DYNAMIC_TILE, "AUX_DYNAMIC_TILE");
|
||||
xmlw.addFlag(auximage.fFlags, AUX_INTERACTIVE_TILE, "AUX_INTERACTIVE_TILE");
|
||||
xmlw.addFlag(auximage.fFlags, AUX_IGNORES_HEIGHT, "AUX_IGNORES_HEIGHT");
|
||||
xmlw.addFlag(auximage.fFlags, AUX_USES_LAND_Z, "AUX_USES_LAND_Z");
|
||||
xmlw.closeNode();
|
||||
}
|
||||
else
|
||||
{
|
||||
xmlw.addValue("flags");
|
||||
}
|
||||
xmlw.closeNode();
|
||||
}
|
||||
xmlw.closeNode(); // auximage_data
|
||||
|
||||
xmlw.addAttributeToNextValue("number_of", Header.usNumberOfImageTileLocsStored);
|
||||
xmlw.openNode("TILE_OFFSETS");
|
||||
if (Header.usNumberOfImageTileLocsStored > 0)
|
||||
{
|
||||
uiDataSize = sizeof( RelTileLoc ) * Header.usNumberOfImageTileLocsStored;
|
||||
sgp::AutoArray<RelTileLoc> pTileLocData(Header.usNumberOfImageTileLocsStored);
|
||||
VFS_THROW_IFF( pTileLocData(), L"" );
|
||||
|
||||
VFS_THROW_IFF( uiDataSize == rfile->read((vfs::Byte*)pTileLocData(), uiDataSize), L"" );
|
||||
|
||||
for(int i = 0; i < Header.usNumberOfImageTileLocsStored; ++i)
|
||||
{
|
||||
RelTileLoc& off = pTileLocData[i];
|
||||
xmlw.addAttributeToNextValue("index",i);
|
||||
xmlw.addAttributeToNextValue("x",(int)off.bTileOffsetX);
|
||||
xmlw.addAttributeToNextValue("y",(int)off.bTileOffsetY);
|
||||
xmlw.addValue("offset");
|
||||
}
|
||||
}
|
||||
xmlw.closeNode();
|
||||
}
|
||||
else
|
||||
{
|
||||
xmlw.addAttributeToNextValue("number_of", 0);
|
||||
xmlw.addValue("AUXIMAGE_DATA");
|
||||
xmlw.addAttributeToNextValue("number_of", Header.usNumberOfImageTileLocsStored);
|
||||
xmlw.addValue("TILE_OFFSETS");
|
||||
}
|
||||
|
||||
if (Header.fFlags & STRUCTURE_FILE_CONTAINS_STRUCTUREDATA)
|
||||
{
|
||||
UINT32 usNumberOfStructuresStored = Header.usNumberOfStructuresStored;
|
||||
UINT32 uiDataSize = Header.usStructureDataSize;
|
||||
// Determine the size of the data, from the header just read,
|
||||
// allocate enough memory and read it in
|
||||
sgp::AutoArray<UINT8> pubStructureData( uiDataSize );
|
||||
VFS_THROW_IFF(pubStructureData(), L"");
|
||||
|
||||
VFS_THROW_IFF( uiDataSize == rfile->read((vfs::Byte*)pubStructureData(), uiDataSize), L"" );
|
||||
|
||||
xmlw.addAttributeToNextValue("number_of", Header.usNumberOfStructures);
|
||||
if(Header.usNumberOfStructures != Header.usNumberOfStructuresStored)
|
||||
{
|
||||
xmlw.addAttributeToNextValue("stored", Header.usNumberOfStructuresStored);
|
||||
}
|
||||
xmlw.openNode("STRUCTURE_DATA");
|
||||
|
||||
UINT8* p_current = pubStructureData();
|
||||
UINT8* p_end = pubStructureData() + uiDataSize;
|
||||
for(unsigned int i = 0; i < usNumberOfStructuresStored; ++i)
|
||||
{
|
||||
if (p_current + sizeof( DB_STRUCTURE ) > p_end)
|
||||
{
|
||||
// gone past end of file block?!
|
||||
// freeing of memory will occur outside of the function
|
||||
break;
|
||||
}
|
||||
|
||||
DB_STRUCTURE* structure = ((DB_STRUCTURE*)p_current);
|
||||
p_current += sizeof( DB_STRUCTURE );
|
||||
|
||||
//xmlw.addAttributeToNextValue("index", i);
|
||||
xmlw.addAttributeToNextValue("index", (int)structure->usStructureNumber);
|
||||
xmlw.openNode("STRUCTURE");
|
||||
|
||||
//xmlw.addValue("usStructureNumber", (int)structure->usStructureNumber);
|
||||
xmlw.addValue("ubArmour", (int)structure->ubArmour);
|
||||
xmlw.addValue("ubHitPoints", (int)structure->ubHitPoints);
|
||||
xmlw.addValue("ubDensity", (int)structure->ubDensity);
|
||||
xmlw.addValue("ubWallOrientation", (int)structure->ubWallOrientation);
|
||||
xmlw.addValue("bDestructionPartner",(int)structure->bDestructionPartner);
|
||||
xmlw.addValue("bPartnerDelta", (int)structure->bPartnerDelta);
|
||||
xmlw.addValue("bZTileOffsetX", (int)structure->bZTileOffsetX);
|
||||
xmlw.addValue("bZTileOffsetY", (int)structure->bZTileOffsetY);
|
||||
if(structure->fFlags > 0)
|
||||
{
|
||||
xmlw.addAttributeToNextValue("uint",(void*)((UINT32)structure->fFlags));
|
||||
xmlw.openNode("flags");
|
||||
|
||||
xmlw.addFlag(structure->fFlags, STRUCTURE_BASE_TILE, "STRUCTURE_BASE_TILE");
|
||||
xmlw.addFlag(structure->fFlags, STRUCTURE_OPEN, "STRUCTURE_OPEN");
|
||||
xmlw.addFlag(structure->fFlags, STRUCTURE_OPENABLE, "STRUCTURE_OPENABLE");
|
||||
// synonyms for STRUCTURE_OPENABLE
|
||||
xmlw.addFlag(structure->fFlags, STRUCTURE_CLOSEABLE, "STRUCTURE_CLOSEABLE");
|
||||
xmlw.addFlag(structure->fFlags, STRUCTURE_SEARCHABLE, "STRUCTURE_SEARCHABLE");
|
||||
xmlw.addFlag(structure->fFlags, STRUCTURE_HIDDEN, "STRUCTURE_HIDDEN");
|
||||
|
||||
xmlw.addFlag(structure->fFlags, STRUCTURE_MOBILE, "STRUCTURE_MOBILE");
|
||||
// STRUCTURE_PASSABLE is set for each structure instance where
|
||||
// the tile flag TILE_PASSABLE is set
|
||||
xmlw.addFlag(structure->fFlags, STRUCTURE_PASSABLE, "STRUCTURE_PASSABLE");
|
||||
xmlw.addFlag(structure->fFlags, STRUCTURE_EXPLOSIVE, "STRUCTURE_EXPLOSIVE");
|
||||
xmlw.addFlag(structure->fFlags, STRUCTURE_TRANSPARENT, "STRUCTURE_TRANSPARENT");
|
||||
|
||||
xmlw.addFlag(structure->fFlags, STRUCTURE_GENERIC, "STRUCTURE_GENERIC");
|
||||
xmlw.addFlag(structure->fFlags, STRUCTURE_TREE, "STRUCTURE_TREE");
|
||||
xmlw.addFlag(structure->fFlags, STRUCTURE_FENCE, "STRUCTURE_FENCE");
|
||||
xmlw.addFlag(structure->fFlags, STRUCTURE_WIREFENCE, "STRUCTURE_WIREFENCE");
|
||||
|
||||
xmlw.addFlag(structure->fFlags, STRUCTURE_HASITEMONTOP, "STRUCTURE_HASITEMONTOP");
|
||||
xmlw.addFlag(structure->fFlags, STRUCTURE_SPECIAL, "STRUCTURE_SPECIAL");
|
||||
xmlw.addFlag(structure->fFlags, STRUCTURE_LIGHTSOURCE, "STRUCTURE_LIGHTSOURCE");
|
||||
xmlw.addFlag(structure->fFlags, STRUCTURE_VEHICLE, "STRUCTURE_VEHICLE");
|
||||
|
||||
xmlw.addFlag(structure->fFlags, STRUCTURE_WALL, "STRUCTURE_WALL");
|
||||
xmlw.addFlag(structure->fFlags, STRUCTURE_WALLNWINDOW, "STRUCTURE_WALLNWINDOW");
|
||||
xmlw.addFlag(structure->fFlags, STRUCTURE_SLIDINGDOOR, "STRUCTURE_SLIDINGDOOR");
|
||||
xmlw.addFlag(structure->fFlags, STRUCTURE_DOOR, "STRUCTURE_DOOR");
|
||||
|
||||
// a "multi" structure (as opposed to multitiled) is composed of multiple graphics & structures
|
||||
xmlw.addFlag(structure->fFlags, STRUCTURE_MULTI, "STRUCTURE_MULTI");
|
||||
xmlw.addFlag(structure->fFlags, STRUCTURE_CAVEWALL, "STRUCTURE_CAVEWALL");
|
||||
xmlw.addFlag(structure->fFlags, STRUCTURE_DDOOR_LEFT, "STRUCTURE_DDOOR_LEFT");
|
||||
xmlw.addFlag(structure->fFlags, STRUCTURE_DDOOR_RIGHT, "STRUCTURE_DDOOR_RIGHT");
|
||||
|
||||
xmlw.addFlag(structure->fFlags, STRUCTURE_NORMAL_ROOF, "STRUCTURE_NORMAL_ROOF");
|
||||
xmlw.addFlag(structure->fFlags, STRUCTURE_SLANTED_ROOF, "STRUCTURE_SLANTED_ROOF");
|
||||
xmlw.addFlag(structure->fFlags, STRUCTURE_TALL_ROOF, "STRUCTURE_TALL_ROOF");
|
||||
xmlw.addFlag(structure->fFlags, STRUCTURE_SWITCH, "STRUCTURE_SWITCH");
|
||||
|
||||
xmlw.addFlag(structure->fFlags, STRUCTURE_ON_LEFT_WALL, "STRUCTURE_ON_LEFT_WALL");
|
||||
xmlw.addFlag(structure->fFlags, STRUCTURE_ON_RIGHT_WALL, "STRUCTURE_ON_RIGHT_WALL");
|
||||
xmlw.addFlag(structure->fFlags, STRUCTURE_CORPSE, "STRUCTURE_CORPSE");
|
||||
xmlw.addFlag(structure->fFlags, STRUCTURE_PERSON, "STRUCTURE_PERSON");
|
||||
|
||||
// COMBINATION FLAGS
|
||||
xmlw.addFlag(structure->fFlags, STRUCTURE_ANYFENCE, "STRUCTURE_ANYFENCE");
|
||||
xmlw.addFlag(structure->fFlags, STRUCTURE_ANYDOOR, "STRUCTURE_ANYDOOR");
|
||||
xmlw.addFlag(structure->fFlags, STRUCTURE_OBSTACLE, "STRUCTURE_OBSTACLE");
|
||||
xmlw.addFlag(structure->fFlags, STRUCTURE_WALLSTUFF, "STRUCTURE_WALLSTUFF");
|
||||
xmlw.addFlag(structure->fFlags, STRUCTURE_BLOCKSMOVES, "STRUCTURE_BLOCKSMOVES");
|
||||
xmlw.addFlag(structure->fFlags, STRUCTURE_TYPE_DEFINED, "STRUCTURE_TYPE_DEFINED");
|
||||
xmlw.addFlag(structure->fFlags, STRUCTURE_ROOF, "STRUCTURE_ROOF");
|
||||
|
||||
xmlw.closeNode();
|
||||
}
|
||||
else
|
||||
{
|
||||
xmlw.addValue("flags");
|
||||
}
|
||||
xmlw.addValue("ubNumberOfTiles", (int)structure->ubNumberOfTiles);
|
||||
xmlw.addAttributeToNextValue("number_of", (int)structure->ubNumberOfTiles);
|
||||
xmlw.openNode("TILES");
|
||||
for(int i = 0; i < structure->ubNumberOfTiles; ++i)
|
||||
{
|
||||
if (p_current + sizeof( DB_STRUCTURE_TILE ) > p_end)
|
||||
{
|
||||
// gone past end of file block?!
|
||||
// freeing of memory will occur outside of the function
|
||||
break;
|
||||
}
|
||||
DB_STRUCTURE_TILE* structTile = ((DB_STRUCTURE_TILE*)p_current);
|
||||
p_current += sizeof( DB_STRUCTURE_TILE );
|
||||
|
||||
xmlw.addAttributeToNextValue("index", i);
|
||||
xmlw.openNode("STRUCTURE_TILE");
|
||||
xmlw.addValue("bXPosRelToBase", (int)structTile->bXPosRelToBase);
|
||||
xmlw.addValue("bYPosRelToBase", (int)structTile->bYPosRelToBase);
|
||||
xmlw.addValue("sPosRelToBase", (int)structTile->sPosRelToBase);
|
||||
xmlw.addValue("ubVehicleHitLocation", (int)structTile->ubVehicleHitLocation);
|
||||
if(structTile->fFlags > 0)
|
||||
{
|
||||
xmlw.addAttributeToNextValue("uint", (void*)((UINT32)structTile->fFlags));
|
||||
xmlw.openNode("flags");
|
||||
xmlw.addFlag(structTile->fFlags, TILE_ON_ROOF, "TILE_ON_ROOF");
|
||||
xmlw.addFlag(structTile->fFlags, TILE_PASSABLE, "TILE_PASSABLE");
|
||||
xmlw.closeNode();
|
||||
}
|
||||
else
|
||||
{
|
||||
xmlw.addValue("flags");
|
||||
}
|
||||
xmlw.openNode("profile");
|
||||
for(int y=PROFILE_Y_SIZE-1; y >= 0; y--)
|
||||
{
|
||||
std::stringstream ss;
|
||||
for(int x = 0; x < PROFILE_X_SIZE - 1; ++x)
|
||||
{
|
||||
ss << (int)structTile->Shape[y][x] << ",";
|
||||
}
|
||||
ss << (int)structTile->Shape[y][PROFILE_X_SIZE-1];
|
||||
xmlw.addValue("y"+vfs::toString<char>(y), ss.str());
|
||||
}
|
||||
xmlw.closeNode();
|
||||
xmlw.closeNode();
|
||||
}
|
||||
xmlw.closeNode();
|
||||
|
||||
xmlw.closeNode();
|
||||
}
|
||||
xmlw.closeNode();
|
||||
}
|
||||
else
|
||||
{
|
||||
xmlw.addAttributeToNextValue("number_of", Header.usNumberOfStructuresStored);
|
||||
xmlw.addValue("STRUCTURE_DATA");
|
||||
}
|
||||
xmlw.closeNode(); // root
|
||||
xmlw.writeToFile(pOutputFile);
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
#ifndef _STRUCTURE_H_
|
||||
#define _STRUCTURE_H_
|
||||
|
||||
#include <vfs/Core/Interface/vfs_file_interface.h>
|
||||
|
||||
namespace ja2xp
|
||||
{
|
||||
bool ConvertStructure(vfs::tReadableFile* pStructureFile, vfs::tWritableFile* pOutputFile);
|
||||
};
|
||||
|
||||
#endif // _STRUCTURE_H_
|
||||
@@ -0,0 +1,182 @@
|
||||
|
||||
#include <export/slf/export_slf.h>
|
||||
#include <export/sti/export_sti.h>
|
||||
|
||||
#include <init_vfs.h>
|
||||
#include <progress_bar.h>
|
||||
|
||||
#include <vfs/Core/vfs.h>
|
||||
#include <vfs/Core/vfs_file_raii.h>
|
||||
#include <vfs/Core/File/vfs_buffer_file.h>
|
||||
#include <vfs/Ext/slf/vfs_slf_library.h>
|
||||
#include <vfs/Ext/7z/vfs_create_7z_library.h>
|
||||
|
||||
#include <iostream>
|
||||
|
||||
bool ja2xp::convertSLFto7z(vfs::tReadableFile* pInFile, vfs::tWritableFile *pOutFile, bool bConvertSTIs, bool bPngOffsets)
|
||||
{
|
||||
vfs::CSLFLibrary src_lib(pInFile,"");
|
||||
if(!src_lib.init())
|
||||
{
|
||||
std::wcout << L"Could not init SLF Library \"" << pInFile->getPath().c_wcs() << L"\"" << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
vfs::CCreateUncompressed7zLibrary create7zLib;
|
||||
|
||||
vfs::CSLFLibrary::Iterator it = src_lib.begin();
|
||||
int count = 0;
|
||||
while(!it.end())
|
||||
{
|
||||
count++;
|
||||
it.next();
|
||||
}
|
||||
ProgressBar pbar(54,count);
|
||||
it = src_lib.begin();
|
||||
for(; !it.end(); it.next())
|
||||
{
|
||||
count++;
|
||||
vfs::CBufferFile* temp_file = NULL;
|
||||
vfs::tReadableFile *file = vfs::tReadableFile::cast(it.value());
|
||||
if(bConvertSTIs)
|
||||
{
|
||||
vfs::Path filename = it.value()->getPath();
|
||||
if(vfs::StrCmp::Equal(filename().substr(filename().length()-4,4), L".sti"))
|
||||
{
|
||||
vfs::Path path = vfs::String(filename().substr(0,filename.length()-4) + L".jpc.7z");
|
||||
temp_file = new vfs::CBufferFile(path);
|
||||
if(convertSTItoJPC(vfs::tReadableFile::cast(it.value()), vfs::tWritableFile::cast(temp_file), bPngOffsets, false))
|
||||
{
|
||||
file = vfs::tReadableFile::cast( temp_file );
|
||||
}
|
||||
}
|
||||
}
|
||||
if(create7zLib.addFile(file))
|
||||
{
|
||||
pbar.Next(it.value()->getPath()());
|
||||
}
|
||||
else
|
||||
{
|
||||
std::wcout << L"Adding file '" << it.value()->getPath().c_wcs() << L"' failed!" << std::endl;
|
||||
}
|
||||
if(temp_file)
|
||||
{
|
||||
delete temp_file;
|
||||
}
|
||||
}
|
||||
std::wstringstream wss;
|
||||
wss << L"Writing file \"" << pOutFile->getPath().c_wcs() << L"\"";
|
||||
pbar.Next(wss.str());
|
||||
if(!create7zLib.writeLibrary(pOutFile))
|
||||
{
|
||||
wss.str(L"");
|
||||
wss << L"Could not write file \"" << pOutFile->getPath().c_wcs() << L"\"";
|
||||
pbar.Next(wss.str());
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ja2xp::convertSLFto7z(vfs::Path const& sSrc, vfs::Path const& sDst, bool bConvertSTIs, bool bPngOffsets)
|
||||
{
|
||||
vfs::CVirtualFileSystem::Iterator it = getVFS()->begin(sSrc);
|
||||
int file_counter = 0;
|
||||
for(; !it.end(); it.next())
|
||||
{
|
||||
file_counter++;
|
||||
vfs::String::str_t fname = it.value()->getPath().c_wcs();
|
||||
if( !vfs::StrCmp::Equal( fname.substr(fname.length()-4,4), L".slf") )
|
||||
{
|
||||
std::wcout << L"\"" << fname << L"\" " << L"is not an .slf file" << std::endl;
|
||||
continue;
|
||||
}
|
||||
if(!it.value()->openRead())
|
||||
{
|
||||
std::wcout << L"Could not open file \"" << sSrc() << L"\"" << std::endl;
|
||||
continue;
|
||||
}
|
||||
vfs::String::str_t new_fname = fname.substr(0,fname.length()-4) + L".jdc.7z";
|
||||
vfs::Path out_name;
|
||||
if(vfs::StrCmp::Equal(sDst(), L"."))
|
||||
{
|
||||
out_name = vfs::Path(new_fname);
|
||||
}
|
||||
else
|
||||
{
|
||||
out_name = sDst;
|
||||
}
|
||||
|
||||
std::wcout << L"Converting file \"" << it.value()->getPath().c_wcs() << L"\"" << std::endl;
|
||||
|
||||
vfs::COpenWriteFile wfile(out_name,true,true);
|
||||
if(!convertSLFto7z(it.value(), &wfile.file(), bConvertSTIs, bPngOffsets))
|
||||
{
|
||||
printf("\n");
|
||||
continue;
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
if(file_counter == 0)
|
||||
{
|
||||
std::wcout << L"Nothing to convert!" << std::endl;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**********************************************************************************************/
|
||||
|
||||
const wchar_t* ja2xp::CExportSLF::commandString = L"slf";
|
||||
|
||||
void ja2xp::CExportSLF::handleCommand(param_list_t const& params)
|
||||
{
|
||||
bool opt_Sti2Png = false, opt_PngOffsets = false;
|
||||
|
||||
param_list_t vfs_params;
|
||||
param_list_t::const_iterator cit = params.begin();
|
||||
for(; cit != params.end(); ++cit)
|
||||
{
|
||||
if( vfs::StrCmp::Equal(*cit, L"-sti2png") )
|
||||
{
|
||||
opt_Sti2Png = true;
|
||||
continue;
|
||||
}
|
||||
else if( vfs::StrCmp::Equal(*cit, L"-png_offsets") )
|
||||
{
|
||||
opt_PngOffsets = true;
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
vfs_params.push_back(*cit);
|
||||
}
|
||||
}
|
||||
|
||||
ja2xp::InitVFS& vfs = ja2xp::InitVFS::instance();
|
||||
vfs.checkParameters(vfs_params);
|
||||
if(!vfs.init())
|
||||
{
|
||||
return;
|
||||
}
|
||||
try
|
||||
{
|
||||
convertSLFto7z(vfs.srcPattern(), vfs.dstPattern(), opt_Sti2Png, opt_PngOffsets);
|
||||
}
|
||||
catch(vfs::Exception& msg)
|
||||
{
|
||||
std::wcout << msg.getLastEntryString().c_str() << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
void ja2xp::CExportSLF::printHelp()
|
||||
{
|
||||
std::wcout
|
||||
<< L" convert SLF archive(s) to uncompressed 7z archive(s)" << std::endl
|
||||
<< L" * if \"destination\" is a directory, then the filename's extension will be" << std::endl
|
||||
<< L" replaced with \".jdc.7z\"" << std::endl
|
||||
<< std::endl
|
||||
<< L" options :" << std::endl
|
||||
<< L" -sti2png : all sti files in the archive will be converted to" << std::endl
|
||||
<< L" \".jpc.7z\" files" << std::endl
|
||||
<< L" -png_offsets : if option \"sti2png\" is enabled, offsets of the png" << std::endl
|
||||
<< L" subimages will be written int the \"appdata.xml\" file" << std::endl;
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
#ifndef _EXPORT_SLF_H_
|
||||
#define _EXPORT_SLF_H_
|
||||
|
||||
#include <vfs/Core/vfs_path.h>
|
||||
#include <vfs/Core/Interface/vfs_file_interface.h>
|
||||
|
||||
#include <exporter_base.h>
|
||||
|
||||
namespace ja2xp
|
||||
{
|
||||
class CExportSLF : public IExporterBase
|
||||
{
|
||||
public:
|
||||
typedef IExporterBase::param_list_t param_list_t;
|
||||
|
||||
static const wchar_t* commandString;// = L"slf";
|
||||
|
||||
virtual void handleCommand(param_list_t const& params);
|
||||
virtual void printHelp();
|
||||
};
|
||||
|
||||
bool convertSLFto7z(vfs::tReadableFile* pInFile, vfs::tWritableFile *pOutFile, bool bConvertSTIs=false, bool bPngOffsets=false);
|
||||
bool convertSLFto7z(vfs::Path const& sSrc, vfs::Path const& sDst, bool bConvertSTIs=false, bool bPngOffsets=false);
|
||||
};
|
||||
|
||||
#endif // _EXPORT_SLF_H_
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,68 @@
|
||||
#ifndef _IMAGE_H_
|
||||
#define _IMAGE_H_
|
||||
|
||||
#include "types.h"
|
||||
#include "himage.h"
|
||||
|
||||
#include <vfs/Core/vfs_types.h>
|
||||
#include <vfs/Core/File/vfs_file.h>
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace ja2xp
|
||||
{
|
||||
class CImage
|
||||
{
|
||||
public:
|
||||
enum EImageType
|
||||
{
|
||||
IT_NONE,
|
||||
IT_BITMAP,
|
||||
IT_COMPRESSED,
|
||||
};
|
||||
public:
|
||||
|
||||
CImage(vfs::Path const& sFileName);
|
||||
CImage(vfs::tReadableFile *pFile);
|
||||
~CImage();
|
||||
|
||||
EImageType GetImageType();
|
||||
|
||||
bool GetSize(UINT32 uiSubImage, UINT32 &uiWidth, UINT32 &uiHeight);
|
||||
bool GetPosition(UINT32 uiSubImage, INT32 &uiX, INT32 &uiY);
|
||||
|
||||
SGPPaletteEntry* GetPalette();
|
||||
|
||||
// use when image type is 'BITMAP'
|
||||
void* GetDataPointer(UINT32 &uiSize);
|
||||
|
||||
bool GetRawDataOfSubImage(UINT32 uiSubImage, void* pData, UINT32 uiMaxSize, UINT32 &uiFilledSize);
|
||||
// use when image type is 'COMPRESSED' unless you know how to 'decompress'
|
||||
UINT32 FillData(UINT32 uiSubImage, UINT8* pData, UINT32 uiMaxSize, bool rgba = false);
|
||||
bool Unpack16BppImageToRGBBuffer(UINT16* pSrc, UINT8* pDst, UINT32 uiWidth, UINT32 uiHeight);
|
||||
|
||||
UINT32 GetNumberOfSubImages();
|
||||
|
||||
bool LoadData();
|
||||
bool DeleteData();
|
||||
|
||||
void LoadBMP();
|
||||
//bool WriteAsBMPs(vfs_string sOutPathName);
|
||||
bool WriteAsPNGs(vfs::tWritableFile* outFile, bool bWriteOffsets=false, bool rgba=false );
|
||||
bool WriteAsPNGs(vfs::Path outpath, bool bWriteOffsets=false, bool rgba=false);
|
||||
bool WriteFirstPNG(vfs::tWritableFile* outFile, bool rgba=false);
|
||||
//bool WriteAsSTIs(vfs_string sOutPathName);
|
||||
|
||||
protected:
|
||||
bool writeSubImageToPNGFile(int i, vfs::tWritableFile* file, bool rgba = false);
|
||||
bool writeImageToPNGFile(vfs::tWritableFile* file, bool rgba = false);
|
||||
bool writeSTIAppData(std::vector<bool> const& write_image, bool bWriteOffsets, vfs::tWritableFile* file);
|
||||
private:
|
||||
vfs::tReadableFile* m_pImageFile;
|
||||
EImageType m_eImageType;
|
||||
image_type* m_pRawImage;
|
||||
bool m_bImageLoaded;
|
||||
};
|
||||
};
|
||||
|
||||
#endif // _IMAGE_H_
|
||||
@@ -0,0 +1,426 @@
|
||||
#include <vfs/Core/vfs_types.h>
|
||||
|
||||
#include "STCI_lib.h"
|
||||
|
||||
#include "imgfmt.h"
|
||||
#include "himage.h"
|
||||
#include "types.h"
|
||||
#include <vfs/Core/vfs_file_raii.h>
|
||||
#include <vfs/Core/vfs_debug.h>
|
||||
#include <string>
|
||||
|
||||
#include <cassert>
|
||||
#include <iostream>
|
||||
|
||||
namespace ja2xp
|
||||
{
|
||||
BOOLEAN STCILoadRGB(vfs::tReadableFile *pFile, HIMAGE hImage, UINT16 fContents, STCIHeader * pHeader );
|
||||
BOOLEAN STCILoadIndexed(vfs::tReadableFile *pFile, HIMAGE hImage, UINT16 fContents, STCIHeader * pHeader );
|
||||
BOOLEAN STCISetPalette(vfs::tReadableFile *pFile, PTR pSTCIPalette, HIMAGE hImage );
|
||||
};
|
||||
|
||||
BOOLEAN ja2xp::LoadSTCIFileToImage(vfs::tReadableFile *pFile, HIMAGE hImage, UINT16 fContents )
|
||||
{
|
||||
STCIHeader Header;
|
||||
image_type TempImage;
|
||||
|
||||
// Check that hImage is valid, and that the file in question exists
|
||||
assert( hImage != NULL );
|
||||
|
||||
TempImage = *hImage;
|
||||
|
||||
if(pFile == NULL)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// Open the file and read the header
|
||||
|
||||
vfs::COpenReadFile file(pFile);
|
||||
VFS_THROW_IFF( STCI_HEADER_SIZE == pFile->read((vfs::Byte*)&Header,STCI_HEADER_SIZE), L"" );
|
||||
VFS_THROW_IFF( memcmp( Header.cID, STCI_ID_STRING, STCI_ID_LEN ) == 0, L"" );
|
||||
|
||||
// Determine from the header the data stored in the file. and run the appropriate loader
|
||||
if (Header.fFlags & STCI_RGB)
|
||||
{
|
||||
if( !STCILoadRGB(pFile, &TempImage, fContents, &Header ) )
|
||||
{
|
||||
pFile->close();
|
||||
std::cout << ".. loading bitmap image failed .." << std::endl;
|
||||
return( FALSE );
|
||||
}
|
||||
}
|
||||
else if (Header.fFlags & STCI_INDEXED)
|
||||
{
|
||||
if( !STCILoadIndexed(pFile, &TempImage, fContents, &Header ) )
|
||||
{
|
||||
pFile->close();
|
||||
std::cout << ".. loading compressed image failed .." << std::endl;
|
||||
return( FALSE );
|
||||
}
|
||||
}
|
||||
else
|
||||
{ // unsupported type of data, or the right flags weren't set!
|
||||
pFile->close();
|
||||
return( FALSE );
|
||||
}
|
||||
|
||||
// Requested data loaded successfully.
|
||||
pFile->close();
|
||||
|
||||
// Set some more flags in the temporary image structure, copy it so that hImage points
|
||||
// to it, and return.
|
||||
if (Header.fFlags & STCI_ZLIB_COMPRESSED)
|
||||
{
|
||||
TempImage.fFlags |= IMAGE_COMPRESSED;
|
||||
}
|
||||
TempImage.usWidth = Header.usWidth;
|
||||
TempImage.usHeight = Header.usHeight;
|
||||
TempImage.ubBitDepth = Header.ubDepth;
|
||||
*hImage = TempImage;
|
||||
|
||||
return( TRUE );
|
||||
}
|
||||
|
||||
BOOLEAN ja2xp::STCILoadRGB(vfs::tReadableFile *pFile, HIMAGE hImage, UINT16 fContents, STCIHeader * pHeader )
|
||||
{
|
||||
if (fContents & IMAGE_PALETTE && !(fContents & IMAGE_ALLIMAGEDATA))
|
||||
{
|
||||
// RGB doesn't have a palette!
|
||||
std::cout << "RGB doesn't have a palette!" << std::endl;
|
||||
return( FALSE );
|
||||
}
|
||||
|
||||
if (fContents & IMAGE_BITMAPDATA)
|
||||
{
|
||||
// Allocate memory for the image data and read it in
|
||||
hImage->pImageData = new char[ pHeader->uiStoredSize ];
|
||||
if (hImage->pImageData == NULL)
|
||||
{
|
||||
return( FALSE );
|
||||
}
|
||||
try
|
||||
{
|
||||
vfs::size_t size = pHeader->uiStoredSize;
|
||||
VFS_THROW_IFF( size == pFile->read( (vfs::Byte*)hImage->pImageData, size ), L"" );
|
||||
}
|
||||
catch(vfs::Exception& ex)
|
||||
{
|
||||
delete[] hImage->pImageData;
|
||||
return( FALSE );
|
||||
}
|
||||
|
||||
hImage->fFlags |= IMAGE_BITMAPDATA;
|
||||
|
||||
if( pHeader->ubDepth == 16)
|
||||
{
|
||||
// ASSUMPTION: file data is 565 R,G,B
|
||||
|
||||
if (gusRedMask != (UINT16) pHeader->RGB.uiRedMask || gusGreenMask != (UINT16) pHeader->RGB.uiGreenMask || gusBlueMask != (UINT16) pHeader->RGB.uiBlueMask )
|
||||
{
|
||||
// colour distribution of the file is different from hardware! We have to change it!
|
||||
// Convert the image to the current hardware's specifications
|
||||
if (gusRedMask > gusGreenMask && gusGreenMask > gusBlueMask)
|
||||
{
|
||||
// hardware wants RGB!
|
||||
if (gusRedMask == 0x7C00 && gusGreenMask == 0x03E0 && gusBlueMask == 0x001F)
|
||||
{ // hardware is 555
|
||||
ConvertRGBDistribution565To555( hImage->p16BPPData, pHeader->usWidth * pHeader->usHeight );
|
||||
return( TRUE );
|
||||
}
|
||||
else if (gusRedMask == 0xFC00 && gusGreenMask == 0x03E0 && gusBlueMask == 0x001F)
|
||||
{
|
||||
ConvertRGBDistribution565To655( hImage->p16BPPData, pHeader->usWidth * pHeader->usHeight );
|
||||
return( TRUE );
|
||||
}
|
||||
else if (gusRedMask == 0xF800 && gusGreenMask == 0x07C0 && gusBlueMask == 0x003F)
|
||||
{
|
||||
ConvertRGBDistribution565To556( hImage->p16BPPData, pHeader->usWidth * pHeader->usHeight );
|
||||
return( TRUE );
|
||||
}
|
||||
else
|
||||
{
|
||||
// take the long route
|
||||
ConvertRGBDistribution565ToAny( hImage->p16BPPData, pHeader->usWidth * pHeader->usHeight );
|
||||
return( TRUE );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// hardware distribution is not R-G-B so we have to take the long route!
|
||||
ConvertRGBDistribution565ToAny( hImage->p16BPPData, pHeader->usWidth * pHeader->usHeight );
|
||||
return( TRUE );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return( TRUE );
|
||||
}
|
||||
|
||||
|
||||
BOOLEAN ja2xp::STCILoadIndexed(vfs::tReadableFile *pFile, HIMAGE hImage, UINT16 fContents, STCIHeader * pHeader )
|
||||
{
|
||||
UINT32 uiFileSectionSize;
|
||||
PTR pSTCIPalette;
|
||||
|
||||
if (fContents & IMAGE_PALETTE)
|
||||
{
|
||||
// Allocate memory for reading in the palette
|
||||
if (pHeader->Indexed.uiNumberOfColours != 256)
|
||||
{
|
||||
return( FALSE );
|
||||
}
|
||||
uiFileSectionSize = pHeader->Indexed.uiNumberOfColours * STCI_PALETTE_ELEMENT_SIZE;
|
||||
pSTCIPalette = new char[uiFileSectionSize];
|
||||
if (pSTCIPalette == NULL)
|
||||
{
|
||||
pFile->close();
|
||||
return( FALSE );
|
||||
}
|
||||
|
||||
memset( pSTCIPalette, 0, uiFileSectionSize );
|
||||
|
||||
// Read in the palette
|
||||
try
|
||||
{
|
||||
VFS_THROW_IFF( uiFileSectionSize == pFile->read( (vfs::Byte*)pSTCIPalette, uiFileSectionSize ), L"" );
|
||||
}
|
||||
catch(vfs::Exception& ex)
|
||||
{
|
||||
pFile->close();
|
||||
delete[] pSTCIPalette;
|
||||
return( FALSE );
|
||||
}
|
||||
if (!STCISetPalette(pFile, pSTCIPalette, hImage ))
|
||||
{
|
||||
pFile->close();
|
||||
delete[] pSTCIPalette;
|
||||
return( FALSE );
|
||||
}
|
||||
hImage->fFlags |= IMAGE_PALETTE;
|
||||
// Free the temporary buffer
|
||||
delete[] pSTCIPalette;
|
||||
}
|
||||
else if (fContents & (IMAGE_BITMAPDATA | IMAGE_APPDATA))
|
||||
{ // seek past the palette
|
||||
uiFileSectionSize = pHeader->Indexed.uiNumberOfColours * STCI_PALETTE_ELEMENT_SIZE;
|
||||
try
|
||||
{
|
||||
pFile->setReadPosition( uiFileSectionSize, vfs::IBaseFile::SD_CURRENT);
|
||||
}
|
||||
catch(vfs::Exception& ex)
|
||||
{
|
||||
pFile->close();
|
||||
return( FALSE );
|
||||
}
|
||||
}
|
||||
if (fContents & IMAGE_BITMAPDATA)
|
||||
{
|
||||
if (pHeader->fFlags & STCI_ETRLE_COMPRESSED)
|
||||
{
|
||||
// load data for the subimage (object) structures
|
||||
assert( sizeof( ETRLEObject ) == STCI_SUBIMAGE_SIZE );
|
||||
hImage->usNumberOfObjects = pHeader->Indexed.usNumberOfSubImages;
|
||||
uiFileSectionSize = hImage->usNumberOfObjects * STCI_SUBIMAGE_SIZE;
|
||||
hImage->pETRLEObject = (ETRLEObject *) new char[uiFileSectionSize];
|
||||
if (hImage->pETRLEObject == NULL)
|
||||
{
|
||||
pFile->close();
|
||||
if (fContents & IMAGE_PALETTE)
|
||||
{
|
||||
delete[] hImage->pPalette;
|
||||
}
|
||||
return( FALSE );
|
||||
}
|
||||
try
|
||||
{
|
||||
VFS_THROW_IFF(uiFileSectionSize == pFile->read((vfs::Byte*)hImage->pETRLEObject, uiFileSectionSize), L"")
|
||||
}
|
||||
catch(vfs::Exception& ex)
|
||||
{
|
||||
//FileClose( hFile );
|
||||
pFile->close();
|
||||
if (fContents & IMAGE_PALETTE)
|
||||
{
|
||||
delete[] hImage->pPalette;
|
||||
}
|
||||
delete[] hImage->pETRLEObject;
|
||||
return( FALSE );
|
||||
}
|
||||
hImage->uiSizePixData = pHeader->uiStoredSize;
|
||||
hImage->fFlags |= IMAGE_TRLECOMPRESSED;
|
||||
}
|
||||
// allocate memory for and read in the image data
|
||||
hImage->pImageData = new char[pHeader->uiStoredSize];
|
||||
if (hImage->pImageData == NULL)
|
||||
{
|
||||
pFile->close();
|
||||
if (fContents & IMAGE_PALETTE)
|
||||
{
|
||||
delete[] hImage->pPalette;
|
||||
}
|
||||
if (hImage->usNumberOfObjects > 0)
|
||||
{
|
||||
delete[] hImage->pETRLEObject;
|
||||
}
|
||||
return( FALSE );
|
||||
}
|
||||
try
|
||||
{
|
||||
VFS_THROW_IFF(pHeader->uiStoredSize == pFile->read( (vfs::Byte*)hImage->pImageData, pHeader->uiStoredSize), L"");
|
||||
}
|
||||
catch(vfs::Exception& ex)
|
||||
{ // Problem reading in the image data!
|
||||
pFile->close();
|
||||
delete[] hImage->pImageData;
|
||||
if (fContents & IMAGE_PALETTE)
|
||||
{
|
||||
delete[] hImage->pPalette;
|
||||
}
|
||||
if (hImage->usNumberOfObjects > 0)
|
||||
{
|
||||
delete[] hImage->pETRLEObject;
|
||||
}
|
||||
return( FALSE );
|
||||
}
|
||||
hImage->fFlags |= IMAGE_BITMAPDATA;
|
||||
}
|
||||
else if (fContents & IMAGE_APPDATA) // then there's a point in seeking ahead
|
||||
{
|
||||
try
|
||||
{
|
||||
pFile->setReadPosition( pHeader->uiStoredSize, vfs::IBaseFile::SD_CURRENT);
|
||||
}
|
||||
catch(vfs::Exception& ex)
|
||||
{
|
||||
//FileClose( hFile );
|
||||
pFile->close();
|
||||
return( FALSE );
|
||||
}
|
||||
}
|
||||
|
||||
if (/*fContents & IMAGE_APPDATA &&*/ pHeader->uiAppDataSize > 0)
|
||||
{
|
||||
// load application-specific data
|
||||
hImage->pAppData = new UINT8[pHeader->uiAppDataSize];
|
||||
if (hImage->pAppData == NULL)
|
||||
{
|
||||
pFile->close();
|
||||
delete[] hImage->pAppData;
|
||||
if (fContents & IMAGE_PALETTE)
|
||||
{
|
||||
delete[] hImage->pPalette;
|
||||
}
|
||||
if (fContents & IMAGE_BITMAPDATA)
|
||||
{
|
||||
delete[] hImage->pImageData;
|
||||
}
|
||||
if (hImage->usNumberOfObjects > 0)
|
||||
{
|
||||
delete[] hImage->pETRLEObject;
|
||||
}
|
||||
return( FALSE );
|
||||
}
|
||||
try
|
||||
{
|
||||
VFS_THROW_IFF(pHeader->uiAppDataSize == pFile->read( (vfs::Byte*)hImage->pAppData, pHeader->uiAppDataSize), L"");
|
||||
}
|
||||
catch(vfs::Exception& ex)
|
||||
{
|
||||
pFile->close();
|
||||
delete[] hImage->pAppData;
|
||||
if (fContents & IMAGE_PALETTE)
|
||||
{
|
||||
delete[] hImage->pPalette;
|
||||
}
|
||||
if (fContents & IMAGE_BITMAPDATA)
|
||||
{
|
||||
delete[] hImage->pImageData;
|
||||
}
|
||||
if (hImage->usNumberOfObjects > 0)
|
||||
{
|
||||
delete[] hImage->pETRLEObject;
|
||||
}
|
||||
return( FALSE );
|
||||
}
|
||||
hImage->uiAppDataSize = pHeader->uiAppDataSize;
|
||||
for(int i=0; i<pHeader->Indexed.usNumberOfSubImages; ++i)
|
||||
{
|
||||
AuxObjectData *pAOD = (AuxObjectData*)(&(hImage->pAppData[i*16]));
|
||||
pAOD->ubUnused[0] = pAOD->ubUnused[0];
|
||||
}
|
||||
hImage->fFlags |= IMAGE_APPDATA;
|
||||
}
|
||||
else
|
||||
{
|
||||
hImage->pAppData = NULL;
|
||||
hImage->uiAppDataSize = 0;
|
||||
}
|
||||
return( TRUE );
|
||||
}
|
||||
|
||||
|
||||
BOOLEAN ja2xp::STCISetPalette(vfs::tReadableFile *pFile, PTR pSTCIPalette, HIMAGE hImage )
|
||||
{
|
||||
UINT16 usIndex;
|
||||
STCIPaletteElement * pubPalette;
|
||||
|
||||
pubPalette = (STCIPaletteElement *) pSTCIPalette;
|
||||
|
||||
// Allocate memory for palette
|
||||
hImage->pPalette = (SGPPaletteEntry *) new char[ sizeof( SGPPaletteEntry ) * 256];
|
||||
memset( hImage->pPalette, 0, ( sizeof( SGPPaletteEntry ) * 256 ) );
|
||||
|
||||
if ( hImage->pPalette == NULL )
|
||||
{
|
||||
return( FALSE );
|
||||
}
|
||||
|
||||
// Initialize the proper palette entries
|
||||
for (usIndex = 0; usIndex < 256; usIndex++)
|
||||
{
|
||||
hImage->pPalette[ usIndex ].peRed = pubPalette->ubRed;
|
||||
hImage->pPalette[ usIndex ].peGreen = pubPalette->ubGreen;
|
||||
hImage->pPalette[ usIndex ].peBlue = pubPalette->ubBlue;
|
||||
hImage->pPalette[ usIndex ].peFlags = 0;
|
||||
pubPalette ++;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
BOOLEAN ja2xp::IsSTCIETRLEFile(vfs::tReadableFile *pFile, CHAR8 * ImageFile )
|
||||
{
|
||||
// HWFILE hFile;
|
||||
STCIHeader Header;
|
||||
|
||||
if(pFile == NULL)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
//CHECKF( FileExists( ImageFile ) );
|
||||
vfs::Path filename(ImageFile);
|
||||
|
||||
try
|
||||
{
|
||||
VFS_THROW_IFF(STCI_HEADER_SIZE == pFile->read( (vfs::Byte*)&Header, STCI_HEADER_SIZE), L"");
|
||||
VFS_THROW_IFF( memcmp( Header.cID, STCI_ID_STRING, STCI_ID_LEN ) == 0, L"" );
|
||||
}
|
||||
catch(vfs::Exception& ex)
|
||||
{
|
||||
pFile->close();
|
||||
return( FALSE );
|
||||
}
|
||||
pFile->close();
|
||||
if (Header.fFlags & STCI_ETRLE_COMPRESSED)
|
||||
{
|
||||
return( TRUE );
|
||||
}
|
||||
else
|
||||
{
|
||||
return( FALSE );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
#include "types.h"
|
||||
#include "himage.h"
|
||||
|
||||
#include <vfs/Core/File/vfs_file.h>
|
||||
|
||||
namespace ja2xp
|
||||
{
|
||||
BOOLEAN LoadSTCIFileToImage(vfs::tReadableFile *pFile, HIMAGE hImage, UINT16 fContents );
|
||||
|
||||
BOOLEAN IsSTCIETRLEFile(vfs::tReadableFile *pFile, CHAR8 * ImageFile );
|
||||
};
|
||||
@@ -0,0 +1,207 @@
|
||||
|
||||
#include "export_sti.h"
|
||||
|
||||
#include "Image.h"
|
||||
#include <init_vfs.h>
|
||||
|
||||
#include <vfs/Core/vfs.h>
|
||||
#include <vfs/Core/vfs_file_raii.h>
|
||||
|
||||
#include <iostream>
|
||||
|
||||
bool ja2xp::convertSTItoJPC(vfs::tReadableFile *pFile, vfs::tWritableFile *pOutFile, bool bOffsets, bool rgba)
|
||||
{
|
||||
if(!pFile)
|
||||
{
|
||||
std::wcout << L"file to read from is NULL" << std::endl;
|
||||
}
|
||||
if(!pOutFile)
|
||||
{
|
||||
std::wcout << L"file to write to is NULL" << std::endl;
|
||||
}
|
||||
CImage image(pFile);
|
||||
if(image.LoadData())
|
||||
{
|
||||
return image.WriteAsPNGs(pOutFile, bOffsets, rgba);
|
||||
}
|
||||
std::wcout << L"could not load data from STI file" << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ja2xp::convertSTItoJPC(vfs::tReadableFile *pFile, vfs::Path const base_out_path, bool bOffsets, bool rgba)
|
||||
{
|
||||
if(!pFile)
|
||||
{
|
||||
std::wcout << L"file to read from is NULL" << std::endl;
|
||||
}
|
||||
CImage image(pFile);
|
||||
if(image.LoadData())
|
||||
{
|
||||
return image.WriteAsPNGs(base_out_path, bOffsets, rgba);
|
||||
}
|
||||
std::wcout << L"could not load data from STI file" << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ja2xp::convertSTItoPNG(vfs::tReadableFile *pFile, vfs::tWritableFile *pOutFile, bool rgba)
|
||||
{
|
||||
if(!pFile)
|
||||
{
|
||||
std::wcout << L"file to read from is NULL" << std::endl;
|
||||
}
|
||||
CImage image(pFile);
|
||||
if(image.LoadData())
|
||||
{
|
||||
return image.WriteFirstPNG(pOutFile, rgba);
|
||||
}
|
||||
std::wcout << L"could not load data from STI file" << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ja2xp::convertSTItoJPC(vfs::Path const& sSrc, vfs::Path const& sDst, bool bPacked, bool bOffsets, bool bOnePng, bool rgba)
|
||||
{
|
||||
vfs::CVirtualFileSystem::Iterator it = getVFS()->begin(sSrc);
|
||||
int file_counter = 0;
|
||||
for(; !it.end(); it.next())
|
||||
{
|
||||
file_counter++;
|
||||
vfs::String::str_t fname = it.value()->getPath().c_wcs();
|
||||
if( !vfs::StrCmp::Equal( fname.substr(fname.length()-4,4), L".sti") )
|
||||
{
|
||||
std::wcout << L"\"" << fname << L"\" is not an .sti file" << std::endl;
|
||||
continue;
|
||||
}
|
||||
if(!it.value()->openRead())
|
||||
{
|
||||
std::wcout << L"Could not open file \"" << sSrc() << L"\"" << std::endl;
|
||||
continue;
|
||||
}
|
||||
vfs::String::str_t fname_base = fname.substr(0,fname.length()-4);
|
||||
|
||||
std::wcout << L"Converting file \"" << fname << L"\"" << std::endl;
|
||||
|
||||
if(bOnePng)
|
||||
{
|
||||
vfs::Path out_name;
|
||||
if(vfs::StrCmp::Equal(sDst(), L"."))
|
||||
{
|
||||
out_name = vfs::Path(fname_base + L".png");
|
||||
}
|
||||
else
|
||||
{
|
||||
out_name = sDst;
|
||||
}
|
||||
vfs::COpenWriteFile wfile(out_name,true,true);
|
||||
|
||||
if( !convertSTItoPNG( it.value(), &(wfile.file()), rgba ) )
|
||||
{
|
||||
std::wcout << L"error : could not convert sti image" << std::endl;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else if(bPacked)
|
||||
{
|
||||
vfs::Path out_name;
|
||||
if(vfs::StrCmp::Equal(sDst(), L"."))
|
||||
{
|
||||
out_name = vfs::Path(fname_base + L".jpc.7z");
|
||||
}
|
||||
else
|
||||
{
|
||||
out_name = sDst;
|
||||
}
|
||||
vfs::COpenWriteFile wfile(out_name,true,true);
|
||||
|
||||
if( !convertSTItoJPC( it.value(), &(wfile.file()), bOffsets, rgba ) )
|
||||
{
|
||||
std::wcout << L"error : could not convert sti image" << std::endl;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if( !convertSTItoJPC( it.value(), vfs::Path(fname_base), bOffsets, rgba ) )
|
||||
{
|
||||
std::wcout << L"error : could not convert sti image" << std::endl;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(file_counter == 0)
|
||||
{
|
||||
std::wcout << L"Nothing to convert!" << std::endl;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**********************************************************************************************/
|
||||
|
||||
const wchar_t* ja2xp::CExportSTI::commandString = L"sti";
|
||||
|
||||
void ja2xp::CExportSTI::handleCommand(CExportSTI::param_list_t const& params)
|
||||
{
|
||||
bool opt_Packed = true,
|
||||
opt_ExportOffsets = false,
|
||||
opt_OnePng = false,
|
||||
opt_Rgba = false;
|
||||
|
||||
param_list_t vfs_params;
|
||||
param_list_t::const_iterator cit = params.begin();
|
||||
for(; cit != params.end(); ++cit)
|
||||
{
|
||||
if( vfs::StrCmp::Equal(*cit, L"-unpack") )
|
||||
{
|
||||
opt_Packed = false;
|
||||
}
|
||||
else if( vfs::StrCmp::Equal(*cit, L"-offsets") )
|
||||
{
|
||||
opt_ExportOffsets = true;
|
||||
}
|
||||
else if( vfs::StrCmp::Equal(*cit, L"-onepng") )
|
||||
{
|
||||
opt_OnePng = true;
|
||||
}
|
||||
else if( vfs::StrCmp::Equal(*cit, L"-rgba") )
|
||||
{
|
||||
opt_Rgba = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
vfs_params.push_back(*cit);
|
||||
}
|
||||
}
|
||||
|
||||
ja2xp::InitVFS& vfs = ja2xp::InitVFS::instance();
|
||||
vfs.checkParameters(vfs_params);
|
||||
if(!vfs.init())
|
||||
{
|
||||
return;
|
||||
}
|
||||
try
|
||||
{
|
||||
convertSTItoJPC(vfs.srcPattern(), vfs.dstPattern(), opt_Packed, opt_ExportOffsets, opt_OnePng, opt_Rgba);
|
||||
}
|
||||
catch(vfs::Exception& msg)
|
||||
{
|
||||
std::wcout << msg.getLastEntryString().c_wcs() << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
void ja2xp::CExportSTI::printHelp()
|
||||
{
|
||||
std::wcout
|
||||
<< L" convert STI image file(s) to a series of png images (as 7z archive)" << std::endl
|
||||
<< L" * if \"destination\" is a directory, then the filename's extension will be" << std::endl
|
||||
<< L" replaced with \".jpc.7z\"" << std::endl
|
||||
<< std::endl
|
||||
<< L" options :" << std::endl
|
||||
<< L" -unpack : if set, no 7z archive will be created. Instead," << std::endl
|
||||
<< L" for an image 'path/image.sti',subimages will be" << std::endl
|
||||
<< L" written into the directory \"path/image/.\"" << std::endl
|
||||
<< L" -offsets : offsets of all subimages will we written in the" << std::endl
|
||||
<< L" \"appdata.xml\" file" << std::endl
|
||||
<< L" -onepng : creates one png image instead of a jpc.7z archive." << std::endl
|
||||
<< L" If there are multiple subimages, only the first one" << std::endl
|
||||
<< L" will be converted." << std::endl;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
#ifndef _EXPORT_STI_H_
|
||||
#define _EXPORT_STI_H_
|
||||
|
||||
#include <vfs/Core/vfs_path.h>
|
||||
#include <vfs/Core/Interface/vfs_file_interface.h>
|
||||
|
||||
#include <exporter_base.h>
|
||||
|
||||
namespace ja2xp
|
||||
{
|
||||
class CExportSTI : public IExporterBase
|
||||
{
|
||||
public:
|
||||
typedef IExporterBase::param_list_t param_list_t;
|
||||
|
||||
static const wchar_t* commandString;// = L"sti";
|
||||
|
||||
virtual void handleCommand(param_list_t const& params);
|
||||
virtual void printHelp();
|
||||
};
|
||||
|
||||
bool convertSTItoJPC(vfs::tReadableFile *pFile, vfs::tWritableFile *pOutFile, bool bOffsets, bool rgba);
|
||||
bool convertSTItoJPC(vfs::tReadableFile *pFile, vfs::Path const base_out_path, bool bOffsets, bool rgba);
|
||||
bool convertSTItoPNG(vfs::tReadableFile *pFile, vfs::tWritableFile *pOutFile, bool rgba);
|
||||
|
||||
bool convertSTItoJPC(vfs::Path const& sSrc, vfs::Path const& sDst,
|
||||
bool bPacked=true, bool bOffsets=false, bool bOnePng=false, bool rgba=false);
|
||||
};
|
||||
|
||||
#endif // _EXPORT_STI_H_
|
||||
@@ -0,0 +1,554 @@
|
||||
#include "stci_image_utils.h"
|
||||
#include "himage.h"
|
||||
|
||||
#include <cassert>
|
||||
|
||||
const int iCOMPRESS_TRANSPARENT = 0x80;
|
||||
const int iCOMPRESS_RUN_MASK = 0x7F;
|
||||
|
||||
|
||||
UINT32 ja2xp::UnpackETRLEImageToBuffer(UINT8 *pBuffer, image_type *pImage, UINT16 usETRLEIndex)
|
||||
{
|
||||
if(!pImage || !pBuffer)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
ETRLEObject *pETRLEObject = &(pImage->pETRLEObject[usETRLEIndex]);
|
||||
if(!pETRLEObject)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
UINT8 *pCurrent;
|
||||
pCurrent = &((UINT8 *)pImage->pPixData8)[pETRLEObject->uiDataOffset];
|
||||
unsigned int uiImageSize = pETRLEObject->usHeight * pETRLEObject->usWidth;
|
||||
|
||||
unsigned int uiBufferPos = 0;
|
||||
unsigned char ubCount;
|
||||
while(uiBufferPos < uiImageSize)
|
||||
{
|
||||
ubCount = *pCurrent & iCOMPRESS_RUN_MASK;
|
||||
if(*pCurrent & iCOMPRESS_TRANSPARENT)
|
||||
{
|
||||
pCurrent++;
|
||||
uiBufferPos += ubCount;
|
||||
}
|
||||
else
|
||||
{
|
||||
pCurrent++;
|
||||
memcpy(&pBuffer[uiBufferPos], pCurrent, ubCount);
|
||||
pCurrent += ubCount;
|
||||
uiBufferPos += ubCount;
|
||||
}
|
||||
}
|
||||
return uiBufferPos;
|
||||
}
|
||||
|
||||
UINT32 ja2xp::UnpackETRLEImageToRGBABuffer(UINT8 *pBuffer, image_type *pImage, UINT16 usETRLEIndex)
|
||||
{
|
||||
if(!pImage || !pBuffer)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
ETRLEObject *pETRLEObject = &(pImage->pETRLEObject[usETRLEIndex]);
|
||||
if(!pETRLEObject)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
SGPPaletteEntry* palette = pImage->pPalette;
|
||||
if(!palette)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
UINT8 *pCurrent;
|
||||
pCurrent = &((UINT8 *)pImage->pPixData8)[pETRLEObject->uiDataOffset];
|
||||
unsigned int uiImageSize = pETRLEObject->usHeight * pETRLEObject->usWidth;
|
||||
|
||||
unsigned int uiBufferPos = 0;
|
||||
unsigned char ubCount;
|
||||
while(uiBufferPos < (4*uiImageSize))
|
||||
{
|
||||
ubCount = *pCurrent & iCOMPRESS_RUN_MASK;
|
||||
if(*pCurrent & iCOMPRESS_TRANSPARENT)
|
||||
{
|
||||
pCurrent++;
|
||||
uiBufferPos += 4 * (int)ubCount;
|
||||
pBuffer += 4 * (int)ubCount;
|
||||
}
|
||||
else
|
||||
{
|
||||
pCurrent++;
|
||||
int count = ubCount;
|
||||
while(count--)
|
||||
{
|
||||
UINT8 cur = *pCurrent++;
|
||||
*pBuffer++ = palette[cur].peRed;
|
||||
*pBuffer++ = palette[cur].peGreen;
|
||||
*pBuffer++ = palette[cur].peBlue;
|
||||
*pBuffer++ = 255; // alpha
|
||||
}
|
||||
uiBufferPos += 4 * (int)ubCount;
|
||||
}
|
||||
}
|
||||
return uiBufferPos;
|
||||
}
|
||||
|
||||
|
||||
ja2xp::CIndexedSTIImage::CIndexedSTIImage()
|
||||
{
|
||||
memset(&_header, 0, sizeof(STCIHeader));
|
||||
}
|
||||
|
||||
ja2xp::CIndexedSTIImage::~CIndexedSTIImage()
|
||||
{
|
||||
if(_palette)
|
||||
{
|
||||
delete[] _palette;
|
||||
}
|
||||
for(unsigned int i=0; i < _compressed_images.size(); ++i)
|
||||
{
|
||||
delete[] _compressed_images[i];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
bool ja2xp::CIndexedSTIImage::SetPalette(SGPPaletteEntry *pPal, int iSize)
|
||||
{
|
||||
if(iSize < 0 ||iSize > 1024)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
_pal_size = iSize;
|
||||
_palette = new STCIPaletteElement[iSize];
|
||||
for(int i=0; i<iSize;++i)
|
||||
{
|
||||
_palette[i].ubBlue = pPal[i].peBlue;
|
||||
_palette[i].ubGreen = pPal[i].peGreen;
|
||||
_palette[i].ubRed = pPal[i].peRed;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ja2xp::CIndexedSTIImage::AddCompressedImage(UINT8 *data, UINT32 data_size, UINT32 image_width, UINT32 image_height, INT32 image_offset_x, INT32 image_offset_y)
|
||||
{
|
||||
if(!data || (data_size < 0) )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
STCISubImage subimage;
|
||||
subimage.sOffsetX = image_offset_x;
|
||||
subimage.sOffsetY = image_offset_y;
|
||||
subimage.usWidth = image_width;
|
||||
subimage.usHeight = image_height;
|
||||
|
||||
UINT8 *compressed = new UINT8[data_size];
|
||||
memcpy(compressed,data,data_size);
|
||||
|
||||
subimage.uiDataLength = data_size;
|
||||
_header.uiStoredSize += data_size;
|
||||
_images.push_back(subimage);
|
||||
_compressed_images.push_back(compressed);
|
||||
_header.uiOriginalSize += image_width * image_height;
|
||||
_header.Indexed.usNumberOfSubImages += 1;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool ja2xp::CIndexedSTIImage::AddImage(UINT8 *data, UINT32 data_size, UINT32 image_width, UINT32 image_height, INT32 image_offset_x, INT32 image_offset_y, UINT8 *original_compressed, UINT32 iriginal_compressed_size)
|
||||
{
|
||||
if(!data || (data_size != image_width*image_height) )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
STCISubImage subimage;
|
||||
subimage.sOffsetX = image_offset_x;
|
||||
subimage.sOffsetY = image_offset_y;
|
||||
subimage.usWidth = image_width;
|
||||
subimage.usHeight = image_height;
|
||||
|
||||
UINT8 *compressed = new UINT8[2*data_size];
|
||||
UINT8 *compressed_start = compressed;
|
||||
memset(compressed,0,data_size);
|
||||
UINT32 compressed_size = 0;
|
||||
|
||||
unsigned int uiBufferPos = 0;
|
||||
|
||||
bool bZeroRun = false;
|
||||
UINT8 uiRunLength = 0;
|
||||
UINT8 *uiRunStartPosition = data;
|
||||
if(*data == 0)
|
||||
{
|
||||
bZeroRun = true;
|
||||
}
|
||||
bool done = false;
|
||||
UINT32 scanline = 0;
|
||||
while(!done)
|
||||
{
|
||||
if(bZeroRun)
|
||||
{
|
||||
while((*data == 0) && (uiRunLength < 128) && (uiBufferPos < data_size) && (scanline < image_width))
|
||||
{
|
||||
data++;
|
||||
uiRunLength++;
|
||||
uiBufferPos++;
|
||||
scanline++;
|
||||
}
|
||||
uiRunStartPosition = compressed;
|
||||
*compressed++ = uiRunLength | iCOMPRESS_TRANSPARENT;
|
||||
compressed_size += 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
uiRunStartPosition = compressed++;
|
||||
while((*data != 0) && (uiRunLength < 128) && (uiBufferPos < data_size) && (scanline < image_width))
|
||||
{
|
||||
*compressed++ = *data++;
|
||||
uiRunLength++;
|
||||
uiBufferPos++;
|
||||
scanline++;
|
||||
}
|
||||
*uiRunStartPosition = uiRunLength;
|
||||
compressed_size += uiRunLength+1;
|
||||
}
|
||||
// prepare next run
|
||||
uiRunLength = 0;
|
||||
bZeroRun = (*data != 0) ? false : true;
|
||||
if(scanline == image_width)
|
||||
{
|
||||
scanline = 0;
|
||||
// "close" scanline with a zero
|
||||
*compressed++ = 0;
|
||||
compressed_size += 1;
|
||||
}
|
||||
if(uiBufferPos >= data_size)
|
||||
{
|
||||
done = true;
|
||||
}
|
||||
}
|
||||
|
||||
subimage.uiDataLength = compressed_size;
|
||||
_header.uiStoredSize += compressed_size;
|
||||
_images.push_back(subimage);
|
||||
_compressed_images.push_back(compressed_start);
|
||||
_header.uiOriginalSize += data_size;
|
||||
_header.Indexed.usNumberOfSubImages += 1;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ja2xp::CIndexedSTIImage::WriteImage(vfs::tWritableFile* pFile)
|
||||
{
|
||||
if(!pFile || !pFile->openWrite())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
strncpy((char*)&(_header.cID[0]),"STCI",4);
|
||||
|
||||
_header.uiOriginalSize = _compressed_images.size() * 640 * 480;
|
||||
//_header.uiStoredSize += 64 + 768 + _header.Indexed.usNumberOfSubImages*16; // equal to uiOriginalSize if data uncompressed
|
||||
_header.uiTransparentValue = 0;
|
||||
_header.fFlags = STCI_ETRLE_COMPRESSED | STCI_INDEXED | STCI_TRANSPARENT;
|
||||
_header.usHeight = 480;
|
||||
_header.usWidth = 640;
|
||||
|
||||
_header.ubDepth = 8;
|
||||
_header.uiAppDataSize = _compressed_images.size() * 16;
|
||||
|
||||
_header.Indexed.ubRedDepth = 8;
|
||||
_header.Indexed.ubGreenDepth = 8;
|
||||
_header.Indexed.ubBlueDepth = 8;
|
||||
_header.Indexed.uiNumberOfColours = 256;
|
||||
_header.Indexed.usNumberOfSubImages = _compressed_images.size();
|
||||
|
||||
pFile->write((vfs::Byte*)&_header,STCI_HEADER_SIZE);
|
||||
|
||||
pFile->write((vfs::Byte*)_palette,_pal_size*sizeof(STCIPaletteElement));
|
||||
|
||||
UINT32 offset=0;
|
||||
// write sub-image headers
|
||||
for(unsigned int i=0; i<_images.size(); ++i)
|
||||
{
|
||||
_images[i].uiDataOffset = offset;
|
||||
pFile->write((vfs::Byte*)&_images[i],STCI_SUBIMAGE_SIZE);
|
||||
offset += _images[i].uiDataLength;
|
||||
}
|
||||
// write sub-images
|
||||
for(unsigned int i=0; i<_compressed_images.size(); ++i)
|
||||
{
|
||||
pFile->write((vfs::Byte*)_compressed_images[i],_images[i].uiDataLength);
|
||||
}
|
||||
// write application data
|
||||
int frames = _compressed_images.size()/8; // 8 = number of directions
|
||||
for(unsigned int i=0; i<_compressed_images.size(); ++i)
|
||||
{
|
||||
AuxObjectData aod;
|
||||
memset(&aod,0,sizeof(AuxObjectData));
|
||||
if((frames+1) % (i+1) == 0)
|
||||
{
|
||||
aod.ubNumberOfFrames = frames;
|
||||
aod.fFlags = AUX_ANIMATED_TILE;
|
||||
}
|
||||
pFile->write((vfs::Byte*)&aod,sizeof(AuxObjectData));
|
||||
}
|
||||
pFile->close();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ja2xp::CIndexedSTIImage::WriteToHIMAGE(HIMAGE pImage)
|
||||
{
|
||||
if(!pImage)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
pImage->usNumberOfObjects = _compressed_images.size();
|
||||
pImage->usWidth = 640;
|
||||
pImage->usHeight = 480;
|
||||
pImage->ubBitDepth = 8;
|
||||
pImage->fFlags = STCI_ETRLE_COMPRESSED | STCI_INDEXED | STCI_TRANSPARENT;;
|
||||
strncat(pImage->ImageFile,"test",4);
|
||||
pImage->iFileLoader = -1;
|
||||
pImage->pui16BPPPalette = NULL;
|
||||
|
||||
|
||||
pImage->pPalette = new SGPPaletteEntry[256];
|
||||
for(int j=0; j<256; ++j)
|
||||
{
|
||||
pImage->pPalette[j].peRed = _palette[j].ubRed;
|
||||
pImage->pPalette[j].peGreen = _palette[j].ubGreen;
|
||||
pImage->pPalette[j].peBlue = _palette[j].ubBlue;
|
||||
pImage->pPalette[j].peFlags = 0;
|
||||
}
|
||||
|
||||
pImage->pETRLEObject = new ETRLEObject[pImage->usNumberOfObjects];
|
||||
UINT32 offset=0; // == size
|
||||
for(unsigned int i=0; i<_images.size(); ++i)
|
||||
{
|
||||
pImage->pETRLEObject[i].sOffsetX = _images[i].sOffsetX;
|
||||
pImage->pETRLEObject[i].sOffsetY = _images[i].sOffsetY;
|
||||
pImage->pETRLEObject[i].usHeight = _images[i].usHeight;
|
||||
pImage->pETRLEObject[i].usWidth = _images[i].usWidth;
|
||||
pImage->pETRLEObject[i].uiDataOffset = offset;
|
||||
pImage->pETRLEObject[i].uiDataLength = _images[i].uiDataLength;
|
||||
offset += _images[i].uiDataLength;
|
||||
}
|
||||
|
||||
pImage->uiSizePixData = offset;
|
||||
pImage->pPixData8 = new UINT8[offset];
|
||||
// write sub-images
|
||||
for(unsigned int i=0; i<_compressed_images.size(); ++i)
|
||||
{
|
||||
memcpy(
|
||||
&pImage->pPixData8[pImage->pETRLEObject[i].uiDataOffset],
|
||||
_compressed_images[i],
|
||||
pImage->pETRLEObject[i].uiDataLength);
|
||||
}
|
||||
|
||||
pImage->uiAppDataSize = pImage->usNumberOfObjects * sizeof(AuxObjectData);
|
||||
pImage->pAppData = (UINT8*)(new AuxObjectData[pImage->usNumberOfObjects]);
|
||||
memset(pImage->pAppData,0,pImage->uiAppDataSize);
|
||||
|
||||
// write application data
|
||||
int frames = _compressed_images.size()/8; // 8 = number of directions
|
||||
for(unsigned int i=0; i<pImage->usNumberOfObjects; ++i)
|
||||
{
|
||||
if(i % frames == 0)
|
||||
{
|
||||
AuxObjectData &aod = *((AuxObjectData*)(&pImage->pAppData[i*sizeof(AuxObjectData)]));
|
||||
aod.ubNumberOfFrames = frames;
|
||||
aod.fFlags = AUX_ANIMATED_TILE;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//BOOLEAN GetETRLEPixelValue( UINT8 * pDest, HVOBJECT hVObject, UINT16 usETRLEIndex, UINT16 usX, UINT16 usY )
|
||||
BOOLEAN ja2xp::GetETRLEPixelValue( UINT8 * pDest, image_type *hImage, UINT16 usETRLEIndex, UINT16 usX, UINT16 usY )
|
||||
{
|
||||
UINT8 * pCurrent;
|
||||
UINT16 usLoopX = 0;
|
||||
UINT16 usLoopY = 0;
|
||||
UINT16 ubRunLength;
|
||||
ETRLEObject * pETRLEObject;
|
||||
|
||||
// Do a bunch of checks
|
||||
assert( hImage != NULL );
|
||||
assert( usETRLEIndex < hImage->usNumberOfObjects );
|
||||
|
||||
pETRLEObject = &(hImage->pETRLEObject[usETRLEIndex]);
|
||||
|
||||
assert( usX < pETRLEObject->usWidth );
|
||||
assert( usY < pETRLEObject->usHeight );
|
||||
|
||||
// Assuming everything's okay, go ahead and look...
|
||||
pCurrent = &((UINT8 *)hImage->pPixData8)[pETRLEObject->uiDataOffset];
|
||||
|
||||
// Skip past all uninteresting scanlines
|
||||
while( usLoopY < usY )
|
||||
{
|
||||
while( *pCurrent != 0 )
|
||||
{
|
||||
if (*pCurrent & iCOMPRESS_TRANSPARENT)
|
||||
{
|
||||
pCurrent++;
|
||||
}
|
||||
else
|
||||
{
|
||||
pCurrent += *pCurrent & iCOMPRESS_RUN_MASK;
|
||||
}
|
||||
}
|
||||
usLoopY++;
|
||||
}
|
||||
|
||||
// Now look in this scanline for the appropriate byte
|
||||
do
|
||||
{
|
||||
ubRunLength = *pCurrent & iCOMPRESS_RUN_MASK;
|
||||
|
||||
if (*pCurrent & iCOMPRESS_TRANSPARENT)
|
||||
{
|
||||
if (usLoopX + ubRunLength >= usX)
|
||||
{
|
||||
*pDest = 0;
|
||||
return( TRUE );
|
||||
}
|
||||
else
|
||||
{
|
||||
pCurrent++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (usLoopX + ubRunLength >= usX)
|
||||
{
|
||||
// skip to the correct byte; skip at least 1 to get past the byte defining the run
|
||||
pCurrent += (usX - usLoopX) + 1;
|
||||
*pDest = *pCurrent;
|
||||
return( TRUE );
|
||||
}
|
||||
else
|
||||
{
|
||||
pCurrent += ubRunLength + 1;
|
||||
}
|
||||
}
|
||||
usLoopX += ubRunLength;
|
||||
}
|
||||
while( usLoopX < usX );
|
||||
// huh???
|
||||
return( FALSE );
|
||||
}
|
||||
|
||||
/*
|
||||
BOOLEAN Blt8BPPDataTo8BPPBuffer( UINT8 *pBuffer, UINT32 uiDestPitchBYTES, image_type *hSrcVObject, INT32 iX, INT32 iY, UINT16 usIndex )
|
||||
{
|
||||
static UINT32 uiOffset;
|
||||
static UINT32 usHeight, usWidth;
|
||||
static UINT8 *SrcPtr, *DestPtr;
|
||||
static UINT32 LineSkip;
|
||||
static ETRLEObject *pTrav;
|
||||
static INT32 iTempX, iTempY;
|
||||
|
||||
|
||||
// Assertions
|
||||
Assert( hSrcVObject != NULL );
|
||||
Assert( pBuffer != NULL );
|
||||
|
||||
// Get Offsets from Index into structure
|
||||
pTrav = &(hSrcVObject->pETRLEObject[ usIndex ] );
|
||||
usHeight = (UINT32)pTrav->usHeight;
|
||||
usWidth = (UINT32)pTrav->usWidth;
|
||||
uiOffset = pTrav->uiDataOffset;
|
||||
|
||||
// Add to start position of dest buffer
|
||||
iTempX = iX + pTrav->sOffsetX;
|
||||
iTempY = iY + pTrav->sOffsetY;
|
||||
|
||||
// Validations
|
||||
CHECKF( iTempX >= 0 );
|
||||
CHECKF( iTempY >= 0 );
|
||||
|
||||
|
||||
SrcPtr= (UINT8 *)hSrcVObject->pPixData8 + uiOffset;
|
||||
DestPtr = (UINT8 *)pBuffer + (uiDestPitchBYTES*iTempY) + (iTempX);
|
||||
LineSkip=(uiDestPitchBYTES-(usWidth));
|
||||
|
||||
__asm {
|
||||
|
||||
mov esi, SrcPtr
|
||||
mov edi, DestPtr
|
||||
xor eax, eax
|
||||
xor ebx, ebx
|
||||
xor ecx, ecx
|
||||
|
||||
BlitDispatch:
|
||||
|
||||
mov cl, [esi]
|
||||
inc esi
|
||||
or cl, cl
|
||||
js BlitTransparent
|
||||
jz BlitDoneLine
|
||||
|
||||
//BlitNonTransLoop:
|
||||
|
||||
clc
|
||||
rcr cl, 1
|
||||
jnc BlitNTL2
|
||||
|
||||
movsb
|
||||
|
||||
BlitNTL2:
|
||||
clc
|
||||
rcr cl, 1
|
||||
jnc BlitNTL3
|
||||
|
||||
movsw
|
||||
|
||||
BlitNTL3:
|
||||
|
||||
or cl, cl
|
||||
jz BlitDispatch
|
||||
|
||||
xor ebx, ebx
|
||||
|
||||
//BlitNTL4:
|
||||
|
||||
rep movsd
|
||||
|
||||
jmp BlitDispatch
|
||||
|
||||
BlitTransparent:
|
||||
|
||||
and ecx, 07fH
|
||||
xor al, al
|
||||
rep stosb
|
||||
|
||||
jmp BlitDispatch
|
||||
|
||||
|
||||
BlitDoneLine:
|
||||
|
||||
dec usHeight
|
||||
jz BlitDone
|
||||
add edi, LineSkip
|
||||
jmp BlitDispatch
|
||||
|
||||
|
||||
BlitDone:
|
||||
}
|
||||
|
||||
return(TRUE);
|
||||
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
#ifndef _STCI_IMAGE_UTILS_H_
|
||||
#define _STCI_IMAGE_UTILS_H_
|
||||
|
||||
#include "types.h"
|
||||
#include "himage.h"
|
||||
#include <vfs/Core/vfs_types.h>
|
||||
#include <vfs/Core/File/vfs_file.h>
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace ja2xp
|
||||
{
|
||||
class CIndexedSTIImage
|
||||
{
|
||||
public:
|
||||
CIndexedSTIImage();
|
||||
~CIndexedSTIImage();
|
||||
|
||||
bool SetPalette(SGPPaletteEntry *pPal, int iSize);
|
||||
bool AddImage(UINT8 *data, UINT32 data_size, UINT32 image_width, UINT32 image_height, INT32 image_offset_x, INT32 image_offset_y, UINT8 *original_compressed=NULL, UINT32 iriginal_compressed_size=0);
|
||||
|
||||
bool AddCompressedImage(UINT8 *data, UINT32 data_size, UINT32 image_width, UINT32 image_height, INT32 image_offset_x, INT32 image_offset_y);
|
||||
|
||||
bool WriteImage(vfs::tWritableFile* pFile);
|
||||
bool WriteToHIMAGE(HIMAGE pImage);
|
||||
private:
|
||||
STCIHeader _header;
|
||||
STCIPaletteElement *_palette;
|
||||
int _pal_size;
|
||||
std::vector<STCISubImage> _images;
|
||||
std::vector<UINT8*> _compressed_images;
|
||||
};
|
||||
|
||||
|
||||
void SplitSTIImage(vfs::String const&, vfs::String &file, vfs::String &ext);
|
||||
|
||||
/**
|
||||
* BUG: this function gives wrong results
|
||||
*/
|
||||
BOOLEAN GetETRLEPixelValue( UINT8 * pDest, image_type *hImage, UINT16 usETRLEIndex, UINT16 usX, UINT16 usY );
|
||||
|
||||
UINT32 UnpackETRLEImageToBuffer(UINT8 *pBuffer, image_type *pImage, UINT16 ueETRLEIndex);
|
||||
UINT32 UnpackETRLEImageToRGBABuffer(UINT8 *pBuffer, image_type *pImage, UINT16 ueETRLEIndex);
|
||||
|
||||
};
|
||||
#endif // _STCI_IMAGE_UTILS_H_
|
||||
@@ -0,0 +1,19 @@
|
||||
#ifndef _EXPORTER_BASE_H_
|
||||
#define _EXPORTER_BASE_H_
|
||||
|
||||
#include <list>
|
||||
#include <string>
|
||||
|
||||
namespace ja2xp
|
||||
{
|
||||
class IExporterBase
|
||||
{
|
||||
public:
|
||||
typedef std::list<std::wstring> param_list_t;
|
||||
|
||||
virtual void handleCommand(std::list<std::wstring> const& params) = 0;
|
||||
virtual void printHelp() = 0;
|
||||
};
|
||||
};
|
||||
|
||||
#endif // _EXPORTER_BASE_H_
|
||||
@@ -0,0 +1,211 @@
|
||||
#include <init_vfs.h>
|
||||
|
||||
#include <vfs/Core/vfs_os_functions.h>
|
||||
#include <vfs/Core/vfs_init.h>
|
||||
#include <vfs/Tools/vfs_property_container.h>
|
||||
|
||||
#include <stack>
|
||||
#include <iostream>
|
||||
|
||||
ja2xp::InitVFS::InitVFS()
|
||||
{
|
||||
}
|
||||
|
||||
ja2xp::InitVFS& ja2xp::InitVFS::instance()
|
||||
{
|
||||
static ja2xp::InitVFS singleton;
|
||||
return singleton;
|
||||
}
|
||||
|
||||
void ja2xp::InitVFS::checkParameters(ja2xp::IExporterBase::param_list_t const& params)
|
||||
{
|
||||
ja2xp::IExporterBase::param_list_t::const_iterator cit = params.begin();
|
||||
for(; cit != params.end(); ++cit)
|
||||
{
|
||||
if( vfs::StrCmp::Equal(*cit, L"-lib") )
|
||||
{
|
||||
this->src_lib = true;
|
||||
cit++;
|
||||
if(cit != params.end())
|
||||
{
|
||||
// get library path
|
||||
this->src_path = vfs::Path(*cit);
|
||||
this->has_src = true;
|
||||
|
||||
cit++;
|
||||
if(cit != params.end())
|
||||
{
|
||||
this->src_pattern = vfs::Path(*cit);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
std::wcout << L"error " << std::endl;
|
||||
}
|
||||
else if( vfs::StrCmp::Equal(*cit, L"-create_dst") )
|
||||
{
|
||||
this->dst_create = true;
|
||||
continue;
|
||||
}
|
||||
else if(!cit->empty() && cit->at(0) == L'-')
|
||||
{
|
||||
//ignore unknown options
|
||||
continue;
|
||||
}
|
||||
|
||||
if(!this->has_src)
|
||||
{
|
||||
this->src_path = vfs::Path(*cit);
|
||||
this->has_src = true;
|
||||
}
|
||||
else if(this->has_src && !this->has_dst)
|
||||
{
|
||||
this->dst_path = vfs::Path(*cit);
|
||||
this->has_dst = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void SplitPath(vfs::Path const& path, vfs::Path& root, vfs::Path& pattern)
|
||||
{
|
||||
vfs::String::str_t sSrc = path();
|
||||
if(sSrc.empty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
// remove enclosing ""
|
||||
if(sSrc.at(0) == L'\"' && sSrc.at(sSrc.length()-1) == L'\"')
|
||||
{
|
||||
sSrc = sSrc.substr(1,sSrc.length()-2);
|
||||
}
|
||||
// has * in path
|
||||
size_t pos = sSrc.find_first_of(L"*");
|
||||
if(pos != std::wstring::npos)
|
||||
{
|
||||
vfs::Path temp_root, temp_pattern;
|
||||
// get directory
|
||||
vfs::Path temp(sSrc.substr(0,pos+1));
|
||||
temp.splitLast(temp_root, temp_pattern);
|
||||
// correct pattern
|
||||
temp_pattern = vfs::Path(temp_pattern.c_wcs() + sSrc.substr(pos+1,sSrc.length()-pos-1));
|
||||
|
||||
root = vfs::Path(temp_root);
|
||||
pattern = vfs::Path(temp_pattern);
|
||||
}
|
||||
else
|
||||
{
|
||||
path.splitLast(root,pattern);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//bool InitVFS(vfs::Path const& sSrcPath, vfs::Path const& sDstPath,
|
||||
// vfs::Path& src_pattern, vfs::Path& dst_pattern,
|
||||
// bool bSourceAsLib, bool bCreateDstDirectory)
|
||||
bool ja2xp::InitVFS::init()
|
||||
{
|
||||
if( !this->has_src || !this->has_dst )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
vfs::Path src_root, dst_root;
|
||||
|
||||
if( this->src_pattern.empty() && !this->src_lib )
|
||||
{
|
||||
SplitPath(this->src_path, src_root, this->src_pattern);
|
||||
if(src_root.empty()) src_root = L".";
|
||||
}
|
||||
else
|
||||
{
|
||||
src_root = this->src_path;
|
||||
}
|
||||
|
||||
SplitPath(this->dst_path, dst_root, this->dst_pattern);
|
||||
if(dst_root.empty()) dst_root = L".";
|
||||
|
||||
vfs::String ext_test;
|
||||
if(!this->dst_pattern.extension(ext_test))
|
||||
{
|
||||
// output pattern has no extension and is probably not a directory name
|
||||
dst_root += this->dst_pattern;
|
||||
this->dst_pattern = L".";
|
||||
}
|
||||
|
||||
if(!this->src_lib && !vfs::OS::checkRealDirectory(src_root))
|
||||
{
|
||||
std::wcout << L"Source directory \"" << src_root() << L"\" does not exist" << std::endl;
|
||||
return false;
|
||||
}
|
||||
if(!vfs::OS::checkRealDirectory(dst_root))
|
||||
{
|
||||
if(!this->dst_create)
|
||||
{
|
||||
std::wcout << L"Destination directory \"" << dst_root() << L"\" does not exist" << std::endl;
|
||||
return false;
|
||||
}
|
||||
std::stack<vfs::Path> dirs;
|
||||
vfs::Path left = dst_root, right, temp;
|
||||
while(!left.empty() && !vfs::OS::checkRealDirectory(left))
|
||||
{
|
||||
dirs.push(left);
|
||||
left.splitLast(temp,right);
|
||||
left = temp;
|
||||
}
|
||||
while(!dirs.empty())
|
||||
{
|
||||
if(!vfs::OS::createRealDirectory(dirs.top()))
|
||||
{
|
||||
std::wcout << L"Could not create directory \"" << dirs.top().c_wcs() << std::endl;
|
||||
return false;
|
||||
}
|
||||
dirs.pop();
|
||||
}
|
||||
}
|
||||
|
||||
vfs_init::Location src_loc;
|
||||
if(this->src_lib)
|
||||
{
|
||||
src_loc.m_type = L"library";
|
||||
}
|
||||
else
|
||||
{
|
||||
src_loc.m_type = L"directory";
|
||||
}
|
||||
src_loc.m_path = src_root;
|
||||
|
||||
vfs_init::Profile src_prof;
|
||||
src_prof.m_name = L"Source";
|
||||
src_prof.addLocation(&src_loc);
|
||||
|
||||
vfs_init::Location dst_loc;
|
||||
dst_loc.m_type = L"directory";
|
||||
dst_loc.m_path = dst_root;
|
||||
|
||||
vfs_init::Profile dst_prof;
|
||||
dst_prof.m_name = L"Destination";
|
||||
dst_prof.addLocation(&dst_loc);
|
||||
dst_prof.m_writable = true;
|
||||
|
||||
vfs_init::VfsConfig conf;
|
||||
conf.addProfile(&src_prof);
|
||||
conf.addProfile(&dst_prof);
|
||||
|
||||
try
|
||||
{
|
||||
vfs_init::initVirtualFileSystem(conf);
|
||||
}
|
||||
catch(vfs::Exception& ex)
|
||||
{
|
||||
std::wcout << ex.m_CallStack.front().message.c_wcs() << std::endl;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
vfs::Path const& ja2xp::InitVFS::srcPattern()
|
||||
{
|
||||
return this->src_pattern;
|
||||
}
|
||||
vfs::Path const& ja2xp::InitVFS::dstPattern()
|
||||
{
|
||||
return this->dst_pattern;
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
#ifndef _INIT_VFS_H_
|
||||
#define _INIT_VFS_H_
|
||||
|
||||
#include <vfs/Core/vfs_path.h>
|
||||
#include <exporter_base.h>
|
||||
|
||||
namespace ja2xp
|
||||
{
|
||||
class InitVFS
|
||||
{
|
||||
public:
|
||||
static InitVFS& instance();
|
||||
|
||||
void checkParameters(IExporterBase::param_list_t const& params);
|
||||
bool init();
|
||||
|
||||
vfs::Path const& srcPattern();
|
||||
vfs::Path const& dstPattern();
|
||||
private:
|
||||
InitVFS();
|
||||
|
||||
bool has_src, has_dst;
|
||||
bool src_lib, dst_create;
|
||||
vfs::Path src_path, dst_path;
|
||||
vfs::Path src_pattern, dst_pattern;
|
||||
};
|
||||
}
|
||||
|
||||
//bool InitVFS(vfs::Path const& sSrcPath, vfs::Path const& sDstPath,
|
||||
// vfs::Path& src_pattern, vfs::Path& dst_pattern,
|
||||
// bool bSourceAsLib, bool bCreateDstDirectory);
|
||||
|
||||
#endif // _INIT_VFS_H_
|
||||
@@ -0,0 +1,243 @@
|
||||
#ifndef __STRUCTURE_INTERNAL_H
|
||||
#define __STRUCTURE_INTERNAL_H
|
||||
|
||||
//
|
||||
// If you wish to use the structure database functions, include
|
||||
// structure_extern.h, not structure.h!
|
||||
//
|
||||
|
||||
#include "types.h"
|
||||
#include "himage.h"
|
||||
|
||||
// A few words about the overall structure scheme:
|
||||
//
|
||||
// Large structures are split into multiple sections,
|
||||
// one for each tile.
|
||||
//
|
||||
// Each section is treated as a separate object,
|
||||
// except that it does NOT record information about
|
||||
// hit points, but instead stores a pointer to the
|
||||
// base object (section).
|
||||
//
|
||||
// Each section has a line of sight profile. These
|
||||
// profiles are split into 5 in each horizontal direction
|
||||
// and 4 vertically, forming 100 "cubes". In real
|
||||
// world terms, each section represents a volume
|
||||
// with a height of 8 feet (and width and length
|
||||
// of what?)
|
||||
//
|
||||
// It is important to note that the vertical
|
||||
// position of each section is measured in individual
|
||||
// cubes (rather than, as it were, groups of 4 vertical
|
||||
// cubes)
|
||||
|
||||
#define PROFILE_X_SIZE 5
|
||||
#define PROFILE_Y_SIZE 5
|
||||
#define PROFILE_Z_SIZE 4
|
||||
|
||||
// these values should be compared for less than rather than less
|
||||
// than or equal to
|
||||
#define STRUCTURE_ON_GROUND 0
|
||||
#define STRUCTURE_ON_ROOF PROFILE_Z_SIZE
|
||||
#define STRUCTURE_ON_GROUND_MAX PROFILE_Z_SIZE
|
||||
#define STRUCTURE_ON_ROOF_MAX PROFILE_Z_SIZE * 2
|
||||
|
||||
typedef UINT8 PROFILE[PROFILE_X_SIZE][PROFILE_Y_SIZE];
|
||||
|
||||
extern UINT8 AtHeight[PROFILE_Z_SIZE];
|
||||
|
||||
// MAP_ELEMENT may get later:
|
||||
// PROFILE * CombinedLOSProfile;
|
||||
// PROFILE * CombinedProtectionProfile;
|
||||
//
|
||||
// LEVELNODE gets a pointer to a STRUCTURE or
|
||||
// a union between its soldier pointer and a
|
||||
// STRUCTURE pointer
|
||||
|
||||
// if (fFlags & STRUCTURE_BASE_TILE)
|
||||
// then the structure is the "base" of the object
|
||||
// and its hitpoint value is the one for the object
|
||||
//
|
||||
// vv generic flags for all structures
|
||||
// vvv type flags
|
||||
//
|
||||
|
||||
// how to handle explodable structures
|
||||
|
||||
// NOT used in DB structures!
|
||||
#define STRUCTURE_BASE_TILE 0x00000001
|
||||
#define STRUCTURE_OPEN 0x00000002
|
||||
#define STRUCTURE_OPENABLE 0x00000004
|
||||
// synonyms for STRUCTURE_OPENABLE
|
||||
#define STRUCTURE_CLOSEABLE 0x00000004
|
||||
#define STRUCTURE_SEARCHABLE 0x00000004
|
||||
#define STRUCTURE_HIDDEN 0x00000008
|
||||
|
||||
#define STRUCTURE_MOBILE 0x00000010
|
||||
// STRUCTURE_PASSABLE is set for each structure instance where
|
||||
// the tile flag TILE_PASSABLE is set
|
||||
#define STRUCTURE_PASSABLE 0x00000020
|
||||
#define STRUCTURE_EXPLOSIVE 0x00000040
|
||||
#define STRUCTURE_TRANSPARENT 0x00000080
|
||||
|
||||
#define STRUCTURE_GENERIC 0x00000100
|
||||
#define STRUCTURE_TREE 0x00000200
|
||||
#define STRUCTURE_FENCE 0x00000400
|
||||
#define STRUCTURE_WIREFENCE 0x00000800
|
||||
|
||||
#define STRUCTURE_HASITEMONTOP 0x00001000 // ATE: HASITEM: struct has item on top of it
|
||||
#define STRUCTURE_SPECIAL 0x00002000
|
||||
#define STRUCTURE_LIGHTSOURCE 0x00004000
|
||||
#define STRUCTURE_VEHICLE 0x00008000
|
||||
|
||||
#define STRUCTURE_WALL 0x00010000
|
||||
#define STRUCTURE_WALLNWINDOW 0x00020000
|
||||
#define STRUCTURE_SLIDINGDOOR 0x00040000
|
||||
#define STRUCTURE_DOOR 0x00080000
|
||||
|
||||
// a "multi" structure (as opposed to multitiled) is composed of multiple graphics & structures
|
||||
#define STRUCTURE_MULTI 0x00100000
|
||||
#define STRUCTURE_CAVEWALL 0x00200000
|
||||
#define STRUCTURE_DDOOR_LEFT 0x00400000
|
||||
#define STRUCTURE_DDOOR_RIGHT 0x00800000
|
||||
|
||||
#define STRUCTURE_NORMAL_ROOF 0x01000000
|
||||
#define STRUCTURE_SLANTED_ROOF 0x02000000
|
||||
#define STRUCTURE_TALL_ROOF 0x04000000
|
||||
#define STRUCTURE_SWITCH 0x08000000
|
||||
|
||||
#define STRUCTURE_ON_LEFT_WALL 0x10000000
|
||||
#define STRUCTURE_ON_RIGHT_WALL 0x20000000
|
||||
#define STRUCTURE_CORPSE 0x40000000
|
||||
#define STRUCTURE_PERSON 0x80000000
|
||||
|
||||
// COMBINATION FLAGS
|
||||
#define STRUCTURE_ANYFENCE 0x00000C00
|
||||
#define STRUCTURE_ANYDOOR 0x00CC0000
|
||||
#define STRUCTURE_OBSTACLE 0x00008F00
|
||||
#define STRUCTURE_WALLSTUFF 0x00CF0000
|
||||
#define STRUCTURE_BLOCKSMOVES 0x00208F00
|
||||
#define STRUCTURE_TYPE_DEFINED 0x8FEF8F00
|
||||
#define STRUCTURE_ROOF 0x07000000
|
||||
|
||||
#define TILE_ON_ROOF 0x01
|
||||
#define TILE_PASSABLE 0x02
|
||||
|
||||
typedef struct TAG_STRUCTURE_TILE
|
||||
{
|
||||
INT16 sPosRelToBase; // "single-axis"
|
||||
INT8 bXPosRelToBase;
|
||||
INT8 bYPosRelToBase;
|
||||
PROFILE Shape; // 25 bytes
|
||||
UINT8 fFlags;
|
||||
UINT8 ubVehicleHitLocation;
|
||||
BYTE bUnused[1];
|
||||
} DB_STRUCTURE_TILE; // 32 bytes
|
||||
|
||||
#define BASE_TILE 0
|
||||
|
||||
#define NO_PARTNER_STRUCTURE 0
|
||||
|
||||
typedef struct TAG_DB_STRUCTURE
|
||||
{
|
||||
UINT8 ubArmour;
|
||||
UINT8 ubHitPoints;
|
||||
UINT8 ubDensity;
|
||||
UINT8 ubNumberOfTiles;
|
||||
UINT32 fFlags;
|
||||
UINT16 usStructureNumber;
|
||||
UINT8 ubWallOrientation;
|
||||
INT8 bDestructionPartner; // >0 = debris number (bDP - 1), <0 = partner graphic
|
||||
INT8 bPartnerDelta; // opened/closed version, etc... 0 for unused
|
||||
INT8 bZTileOffsetX;
|
||||
INT8 bZTileOffsetY;
|
||||
BYTE bUnused[1];
|
||||
} DB_STRUCTURE; // 16 bytes
|
||||
|
||||
typedef struct TAG_DB_STRUCTURE_REF
|
||||
{
|
||||
DB_STRUCTURE * pDBStructure;
|
||||
DB_STRUCTURE_TILE ** ppTile; // dynamic array
|
||||
} DB_STRUCTURE_REF; // 8 bytes
|
||||
|
||||
//dnl ch46 031009
|
||||
typedef struct TAG_STRUCTURE
|
||||
{
|
||||
struct TAG_STRUCTURE* pPrev;
|
||||
struct TAG_STRUCTURE* pNext;
|
||||
DB_STRUCTURE_REF* pDBStructureRef;
|
||||
PROFILE* pShape;
|
||||
UINT32 fFlags;// need to have something to indicate base tile/not
|
||||
INT32 sGridNo;
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
UINT8 ubHitPoints;
|
||||
UINT8 ubLockStrength;
|
||||
};
|
||||
INT32 sBaseGridNo;
|
||||
};
|
||||
UINT16 usStructureID;
|
||||
INT16 sCubeOffset;// height of bottom of object in profile "cubes"
|
||||
UINT8 ubWallOrientation;
|
||||
UINT8 ubVehicleHitLocation;
|
||||
UINT8 ubStructureHeight;// if 0, then unset; otherwise stores height of structure when last calculated
|
||||
UINT8 ubUnused;
|
||||
}STRUCTURE;// 36 bytes
|
||||
|
||||
typedef struct TAG_STRUCTURE_FILE_REF
|
||||
{
|
||||
struct TAG_STRUCTURE_FILE_REF * pPrev;
|
||||
struct TAG_STRUCTURE_FILE_REF * pNext;
|
||||
AuxObjectData * pAuxData;
|
||||
RelTileLoc * pTileLocData;
|
||||
UINT8 * pubStructureData;
|
||||
DB_STRUCTURE_REF * pDBStructureRef; // dynamic array
|
||||
UINT16 usNumberOfStructures;
|
||||
UINT16 usNumberOfStructuresStored;
|
||||
} STRUCTURE_FILE_REF; // 24 bytes
|
||||
|
||||
// IMPORTANT THING TO REMEMBER
|
||||
//
|
||||
// Although the number of structures and images about which information
|
||||
// may be stored in a file, the two are stored very differently.
|
||||
//
|
||||
// The structure data stored amounts to a sparse array, with no data
|
||||
// saved for any structures that are not defined.
|
||||
//
|
||||
// For image information, however, an array is stored with every entry
|
||||
// filled regardless of whether there is non-zero data defined for
|
||||
// that graphic!
|
||||
typedef struct TAG_STRUCTURE_FILE_HEADER
|
||||
{
|
||||
CHAR8 szId[4];
|
||||
union
|
||||
{
|
||||
//struct
|
||||
//{
|
||||
UINT16 usNumberOfStructures;
|
||||
//};
|
||||
//struct
|
||||
//{
|
||||
UINT16 usNumberOfImages;
|
||||
//};
|
||||
};
|
||||
UINT16 usNumberOfStructuresStored;
|
||||
UINT16 usStructureDataSize;
|
||||
UINT8 fFlags;
|
||||
UINT8 bUnused[3];
|
||||
UINT16 usNumberOfImageTileLocsStored;
|
||||
} STRUCTURE_FILE_HEADER; // 16 bytes
|
||||
|
||||
// "J2SD" = Jagged 2 Structure Data
|
||||
#define STRUCTURE_FILE_ID "J2SD"
|
||||
#define STRUCTURE_FILE_ID_LEN 4
|
||||
|
||||
#define STRUCTURE_SCRIPT_FILE_EXTENSION "JSS"
|
||||
#define STRUCTURE_FILE_EXTENSION "JSD"
|
||||
|
||||
#define STRUCTURE_FILE_CONTAINS_AUXIMAGEDATA 0x01
|
||||
#define STRUCTURE_FILE_CONTAINS_STRUCTUREDATA 0x02
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,175 @@
|
||||
#include "XMLWriter.h"
|
||||
|
||||
#include <vfs/Core/vfs_file_raii.h>
|
||||
#include <vfs/Core/File/vfs_file.h>
|
||||
|
||||
#include <iostream>
|
||||
|
||||
void XMLWriter::addValue(vfs::String const& key)
|
||||
{
|
||||
m_ssBuffer << indent() << "<" << key.utf8();
|
||||
insertAttributesIntoBuffer();
|
||||
m_ssBuffer << " />\n";
|
||||
}
|
||||
|
||||
void XMLWriter::addComment(vfs::String const& comment)
|
||||
{
|
||||
m_ssBuffer << indent() << "<!-- " << comment.utf8() << " -->\n";
|
||||
}
|
||||
|
||||
void XMLWriter::addFlag(UINT32 const& flags, UINT32 const& flag, vfs::String strFlag)
|
||||
{
|
||||
if( ( flags & flag) == flag )
|
||||
{
|
||||
this->addValue(strFlag);
|
||||
}
|
||||
}
|
||||
|
||||
void XMLWriter::openNode(vfs::String const& key)
|
||||
{
|
||||
std::string utf8key = key.utf8();
|
||||
m_ssBuffer << indent() << "<" << utf8key;
|
||||
insertAttributesIntoBuffer();
|
||||
m_ssBuffer << ">\n";
|
||||
m_iIndentLevel += 1;
|
||||
m_stOpenNodes.push(utf8key);
|
||||
}
|
||||
|
||||
bool XMLWriter::closeNode()
|
||||
{
|
||||
if(m_iIndentLevel < 1)
|
||||
{
|
||||
// there is nothing to close
|
||||
return false;
|
||||
}
|
||||
if(m_stOpenNodes.empty())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
m_iIndentLevel -= 1;
|
||||
m_ssBuffer << indent() << "</" << m_stOpenNodes.top() << ">\n";
|
||||
m_stOpenNodes.pop();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool XMLWriter::writeToFile(vfs::Path const& sFileName)
|
||||
{
|
||||
try
|
||||
{
|
||||
vfs::COpenWriteFile file(sFileName,true,true);
|
||||
return writeToFile( &file.file() );
|
||||
}
|
||||
catch(vfs::Exception& ex)
|
||||
{
|
||||
std::wcout << ex.getExceptionString() << std::endl;
|
||||
vfs::CFile file(sFileName);
|
||||
if(file.openWrite(true,true))
|
||||
{
|
||||
return writeToFile(vfs::tWritableFile::cast(&file));
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool XMLWriter::writeToFile(vfs::tWritableFile* pFile)
|
||||
{
|
||||
try
|
||||
{
|
||||
vfs::COpenWriteFile file(pFile);
|
||||
const std::string str = m_ssBuffer.str();
|
||||
pFile->write(str.c_str(), str.length() * sizeof(std::string::value_type));
|
||||
return true;
|
||||
}
|
||||
catch(vfs::Exception& ex)
|
||||
{
|
||||
std::wcout << ex.getLastEntryString() << std::endl;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
std::string XMLWriter::indent()
|
||||
{
|
||||
std::string indent_string;
|
||||
for(int i=0; i < m_iIndentLevel; ++i)
|
||||
{
|
||||
indent_string += "\t";
|
||||
}
|
||||
return indent_string;
|
||||
}
|
||||
|
||||
void XMLWriter::insertAttributesIntoBuffer()
|
||||
{
|
||||
if(!m_stNextValAttributes.empty())
|
||||
{
|
||||
std::vector<attribute_type>::iterator it = m_stNextValAttributes.begin();
|
||||
for(; it != m_stNextValAttributes.end(); ++it)
|
||||
{
|
||||
m_ssBuffer << " " << it->first << "=\"" << it->second << "\"";
|
||||
}
|
||||
}
|
||||
m_stNextValAttributes.clear();
|
||||
}
|
||||
|
||||
std::string XMLWriter::handleSpecialCharacters(std::string const& str)
|
||||
{
|
||||
std::stringstream ss;
|
||||
unsigned int current = 0, old = 0;
|
||||
while( current < str.length() )
|
||||
{
|
||||
char const& c = str.at(current);
|
||||
if( c == '&' )
|
||||
{
|
||||
ss << str.substr(old, current-old) << "&";
|
||||
old = current + 1;
|
||||
}
|
||||
else if( c == '<' )
|
||||
{
|
||||
ss << str.substr(old, current-old) << "<";
|
||||
old = current + 1;
|
||||
}
|
||||
else if( c == '>' )
|
||||
{
|
||||
ss << str.substr(old, current-old) << ">";
|
||||
old = current + 1;
|
||||
}
|
||||
else if( c == '\"' )
|
||||
{
|
||||
ss << str.substr(old, current-old) << """;
|
||||
old = current + 1;
|
||||
}
|
||||
else if( c == '\'' )
|
||||
{
|
||||
ss << str.substr(old, current-old) << "'";
|
||||
old = current + 1;
|
||||
}
|
||||
current++;
|
||||
}
|
||||
if(old)
|
||||
{
|
||||
ss << str.substr(old, current-old);
|
||||
return ss.str();
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
void testMXLWriter()
|
||||
{
|
||||
//XMLWriter<char> xmlw;
|
||||
XMLWriter xmlw;
|
||||
//xmlw.openNode(L"root");
|
||||
xmlw.openNode("root");
|
||||
xmlw.addAttributeToNextValue("attr1",10);
|
||||
xmlw.addAttributeToNextValue("attr2","string");
|
||||
//xmlw.AddValue(L"val1",10);
|
||||
xmlw.addValue("val1",10);
|
||||
|
||||
xmlw.addAttributeToNextValue("node_attr",17);
|
||||
xmlw.addComment("bbb -->\n <a> comment</a> <!-- aaa");
|
||||
xmlw.openNode("test");
|
||||
//xmlw.addValue(L"val2",10.5);
|
||||
xmlw.addValue("val2",10.5);
|
||||
xmlw.closeNode();
|
||||
xmlw.closeNode();
|
||||
//xmlw.WriteToFile(WideString("xml_output/test.xml")());
|
||||
xmlw.writeToFile("xml_output/test.xml");
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
#ifndef _XMLWRITER_H_
|
||||
#define _XMLWRITER_H_
|
||||
|
||||
#include <vfs/Core/Interface/vfs_file_interface.h>
|
||||
#include <vfs/Core/vfs_string.h>
|
||||
|
||||
#include <stack>
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
#include <vector>
|
||||
|
||||
class XMLWriter
|
||||
{
|
||||
public:
|
||||
typedef std::pair<std::string, std::string> attribute_type;
|
||||
public:
|
||||
XMLWriter() : m_iIndentLevel(0)
|
||||
{
|
||||
m_ssBuffer << "<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n" ;
|
||||
};
|
||||
~XMLWriter()
|
||||
{};
|
||||
|
||||
template<typename ValueType>
|
||||
void addAttributeToNextValue(vfs::String const& attribute, ValueType const& value)
|
||||
{
|
||||
std::stringstream temp_buffer;
|
||||
temp_buffer << value;
|
||||
m_stNextValAttributes.push_back( attribute_type(attribute.utf8(),temp_buffer.str()) );
|
||||
}
|
||||
|
||||
template<typename ValueType>
|
||||
void addValue(vfs::String const& key, ValueType const& value)
|
||||
{
|
||||
std::string utf8key = key.utf8();
|
||||
m_ssBuffer << indent() << "<" << utf8key;
|
||||
insertAttributesIntoBuffer();
|
||||
m_ssBuffer << ">" << value << "</" << utf8key << ">\n";
|
||||
}
|
||||
|
||||
template<>
|
||||
void addValue<std::string>(vfs::String const& key, std::string const& value)
|
||||
{
|
||||
std::string utf8key = key.utf8();
|
||||
m_ssBuffer << indent() << "<" << utf8key;
|
||||
insertAttributesIntoBuffer();
|
||||
m_ssBuffer << ">" << handleSpecialCharacters(value) << "</" << utf8key << ">\n";
|
||||
}
|
||||
|
||||
void addValue(vfs::String const& key);
|
||||
void addComment(vfs::String const& comment);
|
||||
void addFlag(vfs::UInt32 const& flags, vfs::UInt32 const& flag, vfs::String strFlag);
|
||||
|
||||
void openNode(vfs::String const& key);
|
||||
bool closeNode();
|
||||
|
||||
bool writeToFile(vfs::Path const& sFileName);
|
||||
bool writeToFile(vfs::tWritableFile* pFile);
|
||||
|
||||
private:
|
||||
std::string indent();
|
||||
std::string handleSpecialCharacters(std::string const& str);
|
||||
void insertAttributesIntoBuffer();
|
||||
private:
|
||||
std::stringstream m_ssBuffer;
|
||||
std::stack<std::string> m_stOpenNodes;
|
||||
std::vector<attribute_type> m_stNextValAttributes;
|
||||
int m_iIndentLevel;
|
||||
};
|
||||
|
||||
|
||||
void testMXLWriter();
|
||||
|
||||
#endif // _XMLWRITER_H_
|
||||
|
||||
@@ -0,0 +1,217 @@
|
||||
|
||||
#include <cmath>
|
||||
#include <cstdlib>
|
||||
#include "types.h"
|
||||
#include "string.h"
|
||||
#include "himage.h"
|
||||
|
||||
|
||||
// This is the color substituted to keep a 24bpp->16bpp color
|
||||
// from going transparent (0x0000) -- DB
|
||||
|
||||
#define BLACK_SUBSTITUTE 0x0001
|
||||
|
||||
|
||||
//UINT16 gusAlphaMask = 0;
|
||||
//UINT16 gusRedMask = 0;
|
||||
//UINT16 gusGreenMask = 0;
|
||||
//UINT16 gusBlueMask = 0;
|
||||
//INT16 gusRedShift = 0;
|
||||
//INT16 gusBlueShift = 0;
|
||||
//INT16 gusGreenShift = 0;
|
||||
UINT16 gusAlphaMask = 0;
|
||||
UINT16 gusRedMask = 0xF800;
|
||||
UINT16 gusGreenMask = 0x07E0;
|
||||
UINT16 gusBlueMask = 0x001F;
|
||||
INT16 gusRedShift = 8;
|
||||
INT16 gusBlueShift = -3;
|
||||
INT16 gusGreenShift = 3;
|
||||
|
||||
|
||||
// this funky union is used for fast 16-bit pixel format conversions
|
||||
union SplitUINT32
|
||||
{
|
||||
struct
|
||||
{
|
||||
UINT16 usLower;
|
||||
UINT16 usHigher;
|
||||
};
|
||||
UINT32 uiValue;
|
||||
};
|
||||
|
||||
// Convert from RGB to 16 bit value
|
||||
UINT16 Get16BPPColor( UINT32 RGBValue )
|
||||
{
|
||||
UINT16 r16, g16, b16, usColor = 0;
|
||||
UINT8 r,g,b;
|
||||
|
||||
r = SGPGetRValue( RGBValue );
|
||||
g = SGPGetGValue( RGBValue );
|
||||
b = SGPGetBValue( RGBValue );
|
||||
|
||||
if(gusRedShift < 0)
|
||||
r16=((UINT16)r>>abs(gusRedShift));
|
||||
else
|
||||
r16=((UINT16)r<<gusRedShift);
|
||||
|
||||
if(gusGreenShift < 0)
|
||||
g16=((UINT16)g>>abs(gusGreenShift));
|
||||
else
|
||||
g16=((UINT16)g<<gusGreenShift);
|
||||
|
||||
|
||||
if(gusBlueShift < 0)
|
||||
b16=((UINT16)b>>abs(gusBlueShift));
|
||||
else
|
||||
b16=((UINT16)b<<gusBlueShift);
|
||||
|
||||
usColor=(r16&gusRedMask)|(g16&gusGreenMask)|(b16&gusBlueMask);
|
||||
|
||||
// if our color worked out to absolute black, and the original wasn't
|
||||
// absolute black, convert it to a VERY dark grey to avoid transparency
|
||||
// problems
|
||||
|
||||
if(usColor==0)
|
||||
{
|
||||
if(RGBValue!=0)
|
||||
usColor=BLACK_SUBSTITUTE | gusAlphaMask;
|
||||
}
|
||||
else
|
||||
usColor |= gusAlphaMask;
|
||||
|
||||
return(usColor);
|
||||
}
|
||||
|
||||
// Convert from 16 BPP to RGBvalue
|
||||
UINT32 GetRGBColor( UINT16 Value16BPP )
|
||||
{
|
||||
UINT16 r16, g16, b16;
|
||||
UINT32 r,g,b,val;
|
||||
|
||||
r16 = Value16BPP & gusRedMask;
|
||||
g16 = Value16BPP & gusGreenMask;
|
||||
b16 = Value16BPP & gusBlueMask;
|
||||
|
||||
if(gusRedShift < 0)
|
||||
r=((UINT32)r16<<abs(gusRedShift));
|
||||
else
|
||||
r=((UINT32)r16>>gusRedShift);
|
||||
|
||||
if(gusGreenShift < 0)
|
||||
g=((UINT32)g16<<abs(gusGreenShift));
|
||||
else
|
||||
g=((UINT32)g16>>gusGreenShift);
|
||||
|
||||
if(gusBlueShift < 0)
|
||||
b=((UINT32)b16<<abs(gusBlueShift));
|
||||
else
|
||||
b=((UINT32)b16>>gusBlueShift);
|
||||
|
||||
r &= 0x000000ff;
|
||||
g &= 0x000000ff;
|
||||
b &= 0x000000ff;
|
||||
|
||||
val = FROMRGB(r,g,b);
|
||||
|
||||
return(val);
|
||||
}
|
||||
|
||||
void ConvertRGBDistribution565To555( UINT16 * p16BPPData, UINT32 uiNumberOfPixels )
|
||||
{
|
||||
UINT16 * pPixel;
|
||||
UINT32 uiLoop;
|
||||
|
||||
SplitUINT32 Pixel;
|
||||
|
||||
pPixel = p16BPPData;
|
||||
for (uiLoop = 0; uiLoop < uiNumberOfPixels; uiLoop++)
|
||||
{
|
||||
// If the pixel is completely black, don't bother converting it -- DB
|
||||
if(*pPixel!=0)
|
||||
{
|
||||
// we put the 16 pixel bits in the UPPER word of uiPixel, so that we can
|
||||
// right shift the blue value (at the bottom) into the LOWER word to protect it
|
||||
Pixel.usHigher = *pPixel;
|
||||
Pixel.uiValue >>= 5;
|
||||
// get rid of the least significant bit of green
|
||||
Pixel.usHigher >>= 1;
|
||||
// now shift back into the upper word
|
||||
Pixel.uiValue <<= 5;
|
||||
// and copy back
|
||||
*pPixel = Pixel.usHigher | gusAlphaMask;
|
||||
}
|
||||
pPixel++;
|
||||
}
|
||||
}
|
||||
|
||||
void ConvertRGBDistribution565To655( UINT16 * p16BPPData, UINT32 uiNumberOfPixels )
|
||||
{
|
||||
UINT16 * pPixel;
|
||||
UINT32 uiLoop;
|
||||
|
||||
SplitUINT32 Pixel;
|
||||
|
||||
pPixel = p16BPPData;
|
||||
for (uiLoop = 0; uiLoop < uiNumberOfPixels; uiLoop++)
|
||||
{
|
||||
// we put the 16 pixel bits in the UPPER word of uiPixel, so that we can
|
||||
// right shift the blue value (at the bottom) into the LOWER word to protect it
|
||||
Pixel.usHigher = *pPixel;
|
||||
Pixel.uiValue >>= 5;
|
||||
// get rid of the least significant bit of green
|
||||
Pixel.usHigher >>= 1;
|
||||
// shift to the right some more...
|
||||
Pixel.uiValue >>= 5;
|
||||
// so we can left-shift the red value alone to give it an extra bit
|
||||
Pixel.usHigher <<= 1;
|
||||
// now shift back and copy
|
||||
Pixel.uiValue <<= 10;
|
||||
*pPixel = Pixel.usHigher;
|
||||
pPixel++;
|
||||
}
|
||||
}
|
||||
|
||||
void ConvertRGBDistribution565To556( UINT16 * p16BPPData, UINT32 uiNumberOfPixels )
|
||||
{
|
||||
UINT16 * pPixel;
|
||||
UINT32 uiLoop;
|
||||
|
||||
SplitUINT32 Pixel;
|
||||
|
||||
pPixel = p16BPPData;
|
||||
for (uiLoop = 0; uiLoop < uiNumberOfPixels; uiLoop++)
|
||||
{
|
||||
// we put the 16 pixel bits in the UPPER word of uiPixel, so that we can
|
||||
// right shift the blue value (at the bottom) into the LOWER word to protect it
|
||||
Pixel.usHigher = *pPixel;
|
||||
Pixel.uiValue >>= 5;
|
||||
// get rid of the least significant bit of green
|
||||
Pixel.usHigher >>= 1;
|
||||
// shift back into the upper word
|
||||
Pixel.uiValue <<= 5;
|
||||
// give blue an extra bit (blank in the least significant spot)
|
||||
Pixel.usHigher <<= 1;
|
||||
// copy back
|
||||
*pPixel = Pixel.usHigher;
|
||||
pPixel++;
|
||||
}
|
||||
}
|
||||
|
||||
void ConvertRGBDistribution565ToAny( UINT16 * p16BPPData, UINT32 uiNumberOfPixels )
|
||||
{
|
||||
UINT16 * pPixel;
|
||||
UINT32 uiRed, uiGreen, uiBlue, uiTemp, uiLoop;
|
||||
|
||||
pPixel = p16BPPData;
|
||||
for (uiLoop = 0; uiLoop < uiNumberOfPixels; uiLoop++)
|
||||
{
|
||||
// put the 565 RGB 16-bit value into a 32-bit RGB value
|
||||
uiRed = (*pPixel) >> 11;
|
||||
uiGreen = (*pPixel & 0x07E0) >> 5;
|
||||
uiBlue = (*pPixel & 0x001F);
|
||||
uiTemp = FROMRGB(uiRed,uiGreen,uiBlue);
|
||||
// then convert the 32-bit RGB value to whatever 16 bit format is used
|
||||
*pPixel = Get16BPPColor( uiTemp );
|
||||
pPixel++;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,206 @@
|
||||
#ifndef __IMAGE_H
|
||||
#define __IMAGE_H
|
||||
|
||||
|
||||
#include "imgfmt.h"
|
||||
|
||||
|
||||
#define FROMRGB(r, g ,b) ((UINT32) (((UINT8) (r) | ((UINT16) (g) << 8)) | (((UINT32) (UINT8) (b)) << 16)))
|
||||
|
||||
|
||||
// The HIMAGE module provides a common interface for managing image data. This module
|
||||
// includes:
|
||||
// - A set of data structures representing image data. Data can be 8 or 16 bpp and/or
|
||||
// compressed
|
||||
// - A set of file loaders which load specific file formats into the internal data format
|
||||
// - A set of blitters which blt the data to memory
|
||||
// - A comprehensive automatic blitter which blits the appropriate type based on the
|
||||
// image header.
|
||||
|
||||
|
||||
// Defines for type of file readers
|
||||
#define PCX_FILE_READER 0x1
|
||||
#define TGA_FILE_READER 0x2
|
||||
#define STCI_FILE_READER 0x4
|
||||
#define TRLE_FILE_READER 0x8
|
||||
#define UNKNOWN_FILE_READER 0x200
|
||||
|
||||
// Defines for buffer bit depth
|
||||
#define BUFFER_8BPP 0x1
|
||||
#define BUFFER_16BPP 0x2
|
||||
|
||||
// Defines for image charactoristics
|
||||
#define IMAGE_COMPRESSED 0x0001
|
||||
#define IMAGE_TRLECOMPRESSED 0x0002
|
||||
#define IMAGE_PALETTE 0x0004
|
||||
#define IMAGE_BITMAPDATA 0x0008
|
||||
#define IMAGE_APPDATA 0x0010
|
||||
#define IMAGE_ALLIMAGEDATA 0x000C
|
||||
#define IMAGE_ALLDATA 0x001C
|
||||
|
||||
// Palette structure, mimics that of Win32
|
||||
typedef struct tagSGPPaletteEntry
|
||||
{
|
||||
UINT8 peRed;
|
||||
UINT8 peGreen;
|
||||
UINT8 peBlue;
|
||||
UINT8 peFlags;
|
||||
|
||||
} SGPPaletteEntry;
|
||||
|
||||
#define AUX_FULL_TILE 0x01
|
||||
#define AUX_ANIMATED_TILE 0x02
|
||||
#define AUX_DYNAMIC_TILE 0x04
|
||||
#define AUX_INTERACTIVE_TILE 0x08
|
||||
#define AUX_IGNORES_HEIGHT 0x10
|
||||
#define AUX_USES_LAND_Z 0x20
|
||||
|
||||
typedef struct
|
||||
{
|
||||
UINT8 ubWallOrientation;
|
||||
UINT8 ubNumberOfTiles;
|
||||
UINT16 usTileLocIndex;
|
||||
UINT8 ubUnused1[3];
|
||||
UINT8 ubCurrentFrame;
|
||||
UINT8 ubNumberOfFrames;
|
||||
UINT8 fFlags;
|
||||
UINT8 ubUnused[6];
|
||||
} AuxObjectData;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
INT8 bTileOffsetX;
|
||||
INT8 bTileOffsetY;
|
||||
} RelTileLoc; // relative tile location
|
||||
|
||||
// TRLE subimage structure, mirroring that of ST(C)I
|
||||
typedef struct tagETRLEObject
|
||||
{
|
||||
UINT32 uiDataOffset;
|
||||
UINT32 uiDataLength;
|
||||
INT16 sOffsetX;
|
||||
INT16 sOffsetY;
|
||||
UINT16 usHeight;
|
||||
UINT16 usWidth;
|
||||
} ETRLEObject;
|
||||
|
||||
typedef struct tagETRLEData
|
||||
{
|
||||
PTR pPixData;
|
||||
UINT32 uiSizePixData;
|
||||
ETRLEObject * pETRLEObject;
|
||||
UINT16 usNumberOfObjects;
|
||||
} ETRLEData;
|
||||
|
||||
// Image header structure
|
||||
typedef struct
|
||||
{
|
||||
UINT16 usWidth;
|
||||
UINT16 usHeight;
|
||||
UINT8 ubBitDepth;
|
||||
UINT16 fFlags;
|
||||
SGPFILENAME ImageFile;
|
||||
UINT32 iFileLoader;
|
||||
SGPPaletteEntry * pPalette;
|
||||
UINT16 * pui16BPPPalette;
|
||||
UINT8 * pAppData;
|
||||
UINT32 uiAppDataSize;
|
||||
// This union is used to describe each data type and is flexible to include the
|
||||
// data strucutre of the compresssed format, once developed.
|
||||
union
|
||||
{
|
||||
PTR pImageData;
|
||||
PTR pCompressedImageData;
|
||||
UINT8* p8BPPData;
|
||||
UINT16* p16BPPData;
|
||||
struct
|
||||
{
|
||||
UINT8* pPixData8;
|
||||
UINT32 uiSizePixData;
|
||||
ETRLEObject* pETRLEObject;
|
||||
UINT16 usNumberOfObjects;
|
||||
};
|
||||
};
|
||||
|
||||
} image_type, *HIMAGE;
|
||||
|
||||
|
||||
#define SGPGetRValue(rgb) ((BYTE) (rgb))
|
||||
#define SGPGetBValue(rgb) ((BYTE) ((rgb) >> 16))
|
||||
#define SGPGetGValue(rgb) ((BYTE) (((UINT16) (rgb)) >> 8))
|
||||
|
||||
// *****************************************************************************
|
||||
//
|
||||
// Function prototypes
|
||||
//
|
||||
// *****************************************************************************
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// This function will return NULL if it fails, and call SetLastError() to set
|
||||
// error information
|
||||
HIMAGE CreateImage( SGPFILENAME ImageFile, UINT16 fContents );
|
||||
|
||||
// This function destroys the HIMAGE structure as well as its contents
|
||||
BOOLEAN DestroyImage( HIMAGE hImage );
|
||||
|
||||
// This function releases data allocated to various parts of the image based
|
||||
// on the contents flags passed as a parameter. If a contents flag is given
|
||||
// and the image does not contain that data, no error is raised
|
||||
BOOLEAN ReleaseImageData( HIMAGE hImage, UINT16 fContents );
|
||||
|
||||
// This function will attept to Load data from an existing image object's filename
|
||||
// In this way, dynamic loading of image data can be done
|
||||
BOOLEAN LoadImageData( HIMAGE hImage, UINT16 fContents );
|
||||
|
||||
// This function will run the appropriate copy function based on the type of HIMAGE object
|
||||
BOOLEAN CopyImageToBuffer( HIMAGE hImage, UINT32 fBufferType, BYTE *pDestBuf, UINT16 usDestWidth, UINT16 usDestHeight, UINT16 usX, UINT16 usY, SGPRect *srcRect );
|
||||
|
||||
// The following blitters are used by the function above as well as clients
|
||||
#ifndef NO_ZLIB_COMPRESSION
|
||||
BOOLEAN Copy8BPPCompressedImageTo8BPPBuffer( HIMAGE hImage, BYTE *pDestBuf, UINT16 usDestWidth, UINT16 usDestHeight, UINT16 usX, UINT16 usY, SGPRect *srcRect );
|
||||
BOOLEAN Copy8BPPCompressedImageTo16BPPBuffer( HIMAGE hImage, BYTE *pDestBuf, UINT16 usDestWidth, UINT16 usDestHeight, UINT16 usX, UINT16 usY, SGPRect *srcRect );
|
||||
BOOLEAN Copy16BPPCompressedImageTo16BPPBuffer( HIMAGE hImage, BYTE *pDestBuf, UINT16 usDestWidth, UINT16 usDestHeight, UINT16 usX, UINT16 usY, SGPRect *srcRect );
|
||||
// This function will extract a compressed image into a non-compressed buffer
|
||||
BOOLEAN Extract8BPPCompressedImageToBuffer( HIMAGE hImage, BYTE *pDestBuf );
|
||||
BOOLEAN Extract16BPPCompressedImageToBuffer( HIMAGE hImage, BYTE *pDestBuf );
|
||||
#endif
|
||||
|
||||
BOOLEAN Copy8BPPImageTo8BPPBuffer( HIMAGE hImage, BYTE *pDestBuf, UINT16 usDestWidth, UINT16 usDestHeight, UINT16 usX, UINT16 usY, SGPRect *srcRect );
|
||||
BOOLEAN Copy8BPPImageTo16BPPBuffer( HIMAGE hImage, BYTE *pDestBuf, UINT16 usDestWidth, UINT16 usDestHeight, UINT16 usX, UINT16 usY, SGPRect *srcRect );
|
||||
BOOLEAN Copy16BPPImageTo16BPPBuffer( HIMAGE hImage, BYTE *pDestBuf, UINT16 usDestWidth, UINT16 usDestHeight, UINT16 usX, UINT16 usY, SGPRect *srcRect );
|
||||
|
||||
|
||||
// This function will create a buffer in memory of ETRLE data, excluding palette
|
||||
BOOLEAN GetETRLEImageData( HIMAGE hImage, ETRLEData *pBuffer );
|
||||
|
||||
// UTILITY FUNCTIONS
|
||||
|
||||
// Used to create a 16BPP Palette from an 8 bit palette, found in himage.c
|
||||
UINT16 *Create16BPPPaletteShaded( SGPPaletteEntry *pPalette, UINT32 rscale, UINT32 gscale, UINT32 bscale, BOOLEAN mono);
|
||||
UINT16 *Create16BPPPalette( SGPPaletteEntry *pPalette );
|
||||
UINT16 Get16BPPColor( UINT32 RGBValue );
|
||||
UINT32 GetRGBColor( UINT16 Value16BPP );
|
||||
SGPPaletteEntry *ConvertRGBToPaletteEntry(UINT8 sbStart, UINT8 sbEnd, UINT8 *pOldPalette);
|
||||
|
||||
extern UINT16 gusAlphaMask;
|
||||
extern UINT16 gusRedMask;
|
||||
extern UINT16 gusGreenMask;
|
||||
extern UINT16 gusBlueMask;
|
||||
extern INT16 gusRedShift;
|
||||
extern INT16 gusBlueShift;
|
||||
extern INT16 gusGreenShift;
|
||||
|
||||
// used to convert 565 RGB data into different bit-formats
|
||||
void ConvertRGBDistribution565To555( UINT16 * p16BPPData, UINT32 uiNumberOfPixels );
|
||||
void ConvertRGBDistribution565To655( UINT16 * p16BPPData, UINT32 uiNumberOfPixels );
|
||||
void ConvertRGBDistribution565To556( UINT16 * p16BPPData, UINT32 uiNumberOfPixels );
|
||||
void ConvertRGBDistribution565ToAny( UINT16 * p16BPPData, UINT32 uiNumberOfPixels );
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,92 @@
|
||||
#if !defined( STCI_H )
|
||||
|
||||
#define STCI_H
|
||||
|
||||
// Sir-Tech's Crazy Image (STCI) file format specifications. Each file is composed of:
|
||||
// 1 ImageFileHeader, uncompressed
|
||||
// * Palette (STCI_INDEXED, size = uiNumberOfColours * PALETTE_ELEMENT_SIZE), uncompressed
|
||||
// * SubRectInfo's (usNumberOfRects > 0, size = usNumberOfSubRects * sizeof(SubRectInfo) ), uncompressed
|
||||
// * Bytes of image data, possibly compressed
|
||||
|
||||
#include "types.h"
|
||||
|
||||
#define STCI_ID_STRING "STCI"
|
||||
#define STCI_ID_LEN 4
|
||||
|
||||
#define STCI_ETRLE_COMPRESSED 0x0020
|
||||
#define STCI_ZLIB_COMPRESSED 0x0010
|
||||
#define STCI_INDEXED 0x0008
|
||||
#define STCI_RGB 0x0004
|
||||
#define STCI_ALPHA 0x0002
|
||||
#define STCI_TRANSPARENT 0x0001
|
||||
|
||||
// ETRLE defines
|
||||
#define COMPRESS_TRANSPARENT 0x80
|
||||
#define COMPRESS_NON_TRANSPARENT 0x00
|
||||
#define COMPRESS_RUN_LIMIT 0x7F
|
||||
|
||||
// NB if you're going to change the header definition:
|
||||
// - make sure that everything in this header is nicely aligned
|
||||
// - don't exceed the 64-byte maximum
|
||||
typedef struct
|
||||
{
|
||||
UINT8 cID[STCI_ID_LEN];
|
||||
UINT32 uiOriginalSize;
|
||||
UINT32 uiStoredSize; // equal to uiOriginalSize if data uncompressed
|
||||
UINT32 uiTransparentValue;
|
||||
UINT32 fFlags;
|
||||
UINT16 usHeight;
|
||||
UINT16 usWidth;
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
UINT32 uiRedMask;
|
||||
UINT32 uiGreenMask;
|
||||
UINT32 uiBlueMask;
|
||||
UINT32 uiAlphaMask;
|
||||
UINT8 ubRedDepth;
|
||||
UINT8 ubGreenDepth;
|
||||
UINT8 ubBlueDepth;
|
||||
UINT8 ubAlphaDepth;
|
||||
} RGB;
|
||||
struct
|
||||
{ // For indexed files, the palette will contain 3 separate bytes for red, green, and blue
|
||||
UINT32 uiNumberOfColours;
|
||||
UINT16 usNumberOfSubImages;
|
||||
UINT8 ubRedDepth;
|
||||
UINT8 ubGreenDepth;
|
||||
UINT8 ubBlueDepth;
|
||||
UINT8 cIndexedUnused[11];
|
||||
} Indexed;
|
||||
};
|
||||
UINT8 ubDepth; // size in bits of one pixel as stored in the file
|
||||
UINT32 uiAppDataSize;
|
||||
UINT8 cUnused[15];
|
||||
} STCIHeader;
|
||||
|
||||
#define STCI_HEADER_SIZE 64
|
||||
|
||||
typedef struct
|
||||
{
|
||||
UINT32 uiDataOffset;
|
||||
UINT32 uiDataLength;
|
||||
INT16 sOffsetX;
|
||||
INT16 sOffsetY;
|
||||
UINT16 usHeight;
|
||||
UINT16 usWidth;
|
||||
} STCISubImage;
|
||||
|
||||
#define STCI_SUBIMAGE_SIZE 16
|
||||
|
||||
typedef struct
|
||||
{
|
||||
UINT8 ubRed;
|
||||
UINT8 ubGreen;
|
||||
UINT8 ubBlue;
|
||||
} STCIPaletteElement;
|
||||
|
||||
#define STCI_PALETTE_ELEMENT_SIZE 3
|
||||
#define STCI_8BIT_PALETTE_SIZE 768
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,83 @@
|
||||
#ifndef _SGP_AUTO_MEMORY_H_
|
||||
#define _SGP_AUTO_MEMORY_H_
|
||||
|
||||
namespace sgp
|
||||
{
|
||||
/************************************************************/
|
||||
|
||||
template<typename T>
|
||||
class TAutoArray
|
||||
{
|
||||
public:
|
||||
T& operator[](unsigned int index)
|
||||
{
|
||||
return _array[index];
|
||||
}
|
||||
|
||||
T* operator()()
|
||||
{
|
||||
return _array;
|
||||
}
|
||||
T& operator*()
|
||||
{
|
||||
return *_array;
|
||||
}
|
||||
bool operator!()
|
||||
{
|
||||
// NULL == _array
|
||||
return !_array;
|
||||
}
|
||||
|
||||
T* release()
|
||||
{
|
||||
T* tmp = _array;
|
||||
_array = NULL;
|
||||
return tmp;
|
||||
}
|
||||
protected:
|
||||
T* _array;
|
||||
};
|
||||
|
||||
/************************************************************/
|
||||
|
||||
template<typename T>
|
||||
class AutoArray : public TAutoArray<T>
|
||||
{
|
||||
public:
|
||||
AutoArray(unsigned int size)
|
||||
{
|
||||
_array = new T[size];
|
||||
}
|
||||
~AutoArray()
|
||||
{
|
||||
if(_array)
|
||||
{
|
||||
delete[] _array;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/************************************************************/
|
||||
|
||||
template<typename T, typename void*(*Alloc)(size_t) = malloc, typename void(*Dealloc)(void*) = free>
|
||||
class AutoCArray : public TAutoArray<T>
|
||||
{
|
||||
public:
|
||||
AutoCArray(unsigned int size = 1)
|
||||
{
|
||||
_array = (T*)Alloc( size * sizeof(T) );
|
||||
}
|
||||
~AutoCArray()
|
||||
{
|
||||
if(_array)
|
||||
{
|
||||
Dealloc(_array);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/************************************************************/
|
||||
|
||||
} // namespace sgp
|
||||
|
||||
#endif // _SGP_AUTO_MEMORY_H_
|
||||
@@ -0,0 +1,103 @@
|
||||
#ifndef __TYPES_
|
||||
#define __TYPES_
|
||||
|
||||
#include <wchar.h> // for wide-character strings
|
||||
|
||||
// *** SIR-TECH TYPE DEFINITIONS ***
|
||||
|
||||
// These two types are defined by VC6 and were causing redefinition
|
||||
// problems, but JA2 is compiled with VC5
|
||||
|
||||
// HEY WIZARDRY DUDES, JA2 ISN'T THE ONLY PROGRAM WE COMPILE! :-)
|
||||
|
||||
typedef unsigned int UINT32;
|
||||
typedef signed int INT32;
|
||||
|
||||
// integers
|
||||
typedef unsigned char UINT8;
|
||||
typedef signed char INT8;
|
||||
typedef unsigned short UINT16;
|
||||
typedef signed short INT16;
|
||||
// floats
|
||||
typedef float FLOAT;
|
||||
typedef double DOUBLE;
|
||||
// strings
|
||||
typedef char CHAR8;
|
||||
typedef wchar_t CHAR16;
|
||||
typedef CHAR8 * STR;
|
||||
typedef CHAR8 * STR8;
|
||||
typedef CHAR16 * STR16;
|
||||
// flags (individual bits used)
|
||||
typedef unsigned char FLAGS8;
|
||||
typedef unsigned short FLAGS16;
|
||||
typedef unsigned long FLAGS32;
|
||||
// other
|
||||
typedef unsigned char BOOLEAN;
|
||||
typedef void * PTR;
|
||||
typedef unsigned short HNDL;
|
||||
typedef UINT8 BYTE;
|
||||
typedef CHAR8 STRING512[512];
|
||||
typedef UINT32 HWFILE;
|
||||
|
||||
#define SGPFILENAME_LEN 100
|
||||
typedef CHAR8 SGPFILENAME[SGPFILENAME_LEN];
|
||||
|
||||
#ifndef TRUE
|
||||
#define TRUE 1
|
||||
#endif
|
||||
|
||||
#ifndef FALSE
|
||||
#define FALSE 0
|
||||
#endif
|
||||
|
||||
#define BAD_INDEX -1
|
||||
|
||||
#define NULL_HANDLE 65535
|
||||
|
||||
#define PI 3.1415926
|
||||
|
||||
|
||||
#ifndef NULL
|
||||
#define NULL 0
|
||||
#endif
|
||||
|
||||
typedef struct
|
||||
{
|
||||
INT32 iLeft;
|
||||
INT32 iTop;
|
||||
INT32 iRight;
|
||||
INT32 iBottom;
|
||||
|
||||
} SGPRect;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
INT32 iX;
|
||||
INT32 iY;
|
||||
|
||||
} SGPPoint;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
INT32 Min;
|
||||
INT32 Max;
|
||||
|
||||
} SGPRange;
|
||||
|
||||
|
||||
typedef FLOAT VECTOR2[2]; // 2d vector (2x1 matrix)
|
||||
typedef FLOAT VECTOR3[3]; // 3d vector (3x1 matrix)
|
||||
typedef FLOAT VECTOR4[4]; // 4d vector (4x1 matrix)
|
||||
|
||||
typedef INT32 IVECTOR2[2]; // 2d vector (2x1 matrix)
|
||||
typedef INT32 IVECTOR3[3]; // 3d vector (3x1 matrix)
|
||||
typedef INT32 IVECTOR4[4]; // 4d vector (4x1 matrix)
|
||||
|
||||
typedef VECTOR3 MATRIX3[3]; // 3x3 matrix
|
||||
typedef VECTOR4 MATRIX4[4]; // 4x4 matrix
|
||||
|
||||
//typedef VECTOR3 ANGLE; // angle return array //lal removed
|
||||
typedef VECTOR4 COLOR; // rgba color array
|
||||
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,115 @@
|
||||
#include <iostream>
|
||||
#include <map>
|
||||
|
||||
#include <export/sti/export_sti.h>
|
||||
#include <export/slf/export_slf.h>
|
||||
#include <export/jsd/export_jsd.h>
|
||||
|
||||
#include <exporter_base.h>
|
||||
|
||||
static const char* VERSION_STRING = "1.1.1";
|
||||
|
||||
typedef std::map<vfs::String, ja2xp::IExporterBase*, vfs::String::Less> CommandMap_t;
|
||||
CommandMap_t g_command_map;
|
||||
|
||||
class HelpCommand : public ja2xp::IExporterBase
|
||||
{
|
||||
public:
|
||||
typedef ja2xp::IExporterBase::param_list_t param_list_t;
|
||||
|
||||
static const wchar_t* commandString;// = L"help";
|
||||
|
||||
virtual void handleCommand(param_list_t const& params)
|
||||
{
|
||||
param_list_t::const_iterator cit = params.begin();
|
||||
for(; cit != params.end(); ++cit)
|
||||
{
|
||||
CommandMap_t::const_iterator comm_it = g_command_map.find(*cit);
|
||||
if(comm_it != g_command_map.end())
|
||||
{
|
||||
this->printBasicUsage();
|
||||
comm_it->second->printHelp();
|
||||
return;
|
||||
}
|
||||
}
|
||||
this->printBasicUsage();
|
||||
this->printHelp();
|
||||
}
|
||||
|
||||
void printBasicUsage()
|
||||
{
|
||||
std::wcout
|
||||
<< L"*** ja2export : version " << VERSION_STRING << " ***" << std::endl
|
||||
<< std::endl
|
||||
<< L"Usage : ja2export command [OPTIONS] source destination" << std::endl
|
||||
<< std::endl
|
||||
<< L" converts file(s) specified by \"source\" and outputs according to filename" << std::endl
|
||||
<< L" specified by \"destination\"" << std::endl
|
||||
<< std::endl;
|
||||
}
|
||||
virtual void printHelp()
|
||||
{
|
||||
std::wcout
|
||||
<< L" * if \"source\" is a file pattern with the wildcard *, then all files that" << std::endl
|
||||
<< L" match this pattern will be converted" << std::endl
|
||||
<< L" * if \"destination\" is a file name, the converted file will take exactly " << std::endl
|
||||
<< L" this name" << std::endl
|
||||
<< L" * if \"destination\" is a directory name, then the converted file will be" << std::endl
|
||||
<< L" written in this directory and its extension will be modified according" << std::endl
|
||||
<< L" to the command specification" << std::endl
|
||||
<< std::endl
|
||||
<< L" commands :" << std::endl
|
||||
<< L" help : print this message, use help [command] to print specific help message" << std::endl
|
||||
<< L" sti : convert STI image file(s) to a series of png images in a 7z archive" << std::endl
|
||||
<< L" slf : convert SLF archive(s) to uncompressed 7z archive(s)" << std::endl
|
||||
<< L" jsd : convert JSD file(s) to XML file(s)" << std::endl
|
||||
<< std::endl
|
||||
<< L" options :" << std::endl
|
||||
<< L" -create_dst : creates destination directory if it doesn't exist" << std::endl
|
||||
<< L" -lib : when set, the next two paramers are treated as" << std::endl
|
||||
<< L" 'source path' and 'source file pattern'" << std::endl;
|
||||
}
|
||||
};
|
||||
const wchar_t* HelpCommand::commandString = L"help";
|
||||
|
||||
int wmain(int argc, wchar_t **argv)
|
||||
{
|
||||
std::list<std::wstring> param_list;
|
||||
argv++;
|
||||
while(*argv)
|
||||
{
|
||||
param_list.push_back(*argv++);
|
||||
};
|
||||
|
||||
auto cmd_help{ std::make_unique<HelpCommand>() };
|
||||
g_command_map[HelpCommand::commandString] = cmd_help.get();
|
||||
|
||||
auto cmd_sti{ std::make_unique<ja2xp::CExportSTI>() };
|
||||
g_command_map[ja2xp::CExportSTI::commandString] = cmd_sti.get();
|
||||
|
||||
auto cmd_slf{ std::make_unique<ja2xp::CExportSLF>() };
|
||||
g_command_map[ja2xp::CExportSLF::commandString] = cmd_slf.get();
|
||||
|
||||
auto cmd_jsd{ std::make_unique<ja2xp::CExportJSD>() };
|
||||
g_command_map[ja2xp::CExportJSD::commandString] = cmd_jsd.get();
|
||||
|
||||
if(!param_list.empty())
|
||||
{
|
||||
ja2xp::IExporterBase* command = g_command_map[param_list.front()];
|
||||
if(command)
|
||||
{
|
||||
std::list<std::wstring> command_params(++param_list.begin(), param_list.end());
|
||||
command->handleCommand(command_params);
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::wcout << L"Unknown command \"" << param_list.front() << "\"";
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
cmd_help->printBasicUsage();
|
||||
cmd_help->printHelp();
|
||||
|
||||
return 1;
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
#include <progress_bar.h>
|
||||
|
||||
|
||||
ja2xp::ProgressBar::ProgressBar(int size, int numElements)
|
||||
: iSIZE(size), num_elements(numElements), count(0)
|
||||
{
|
||||
empty_str.resize(iSIZE);
|
||||
for(int i=0; i<iSIZE; ++i)
|
||||
{
|
||||
empty_str[i] = L' ';
|
||||
}
|
||||
};
|
||||
|
||||
void ja2xp::ProgressBar::Next(vfs::String const& message)
|
||||
{
|
||||
count++;
|
||||
float percent = (float)count/float(num_elements);
|
||||
wchar_t bar[21] = L" ";
|
||||
int bar_end = (int)(20*percent);
|
||||
bar_end = std::min<int>(20,bar_end);
|
||||
for(int i=0; i < bar_end; ++i)
|
||||
{
|
||||
bar[i] = L'=';
|
||||
}
|
||||
std::vector<wchar_t> infoZ(iSIZE+1);
|
||||
std::wstring str = message.c_wcs();
|
||||
int start = std::min<int>(iSIZE,(int)str.length());
|
||||
wcsncpy(&infoZ[0],str.c_str(),start);
|
||||
memcpy(&infoZ[start],&empty_str[0],(iSIZE-start)*sizeof(wchar_t));
|
||||
infoZ[iSIZE] = 0;
|
||||
wprintf(L"\r[%.20s] - %.54s", bar, &infoZ[0]);
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
#ifndef _PROGRESSBAR_H_
|
||||
#define _PROGRESSBAR_H_
|
||||
|
||||
#include <vector>
|
||||
#include <vfs/Core/vfs_string.h>
|
||||
|
||||
namespace ja2xp
|
||||
{
|
||||
class ProgressBar
|
||||
{
|
||||
public:
|
||||
ProgressBar(int size, int numElements);
|
||||
|
||||
void Next(vfs::String const& message);
|
||||
private:
|
||||
const int iSIZE;
|
||||
const int num_elements;
|
||||
int count;
|
||||
std::vector<wchar_t> empty_str;
|
||||
};
|
||||
};
|
||||
|
||||
#endif // _PROGRESSBAR_H_
|
||||
Reference in New Issue
Block a user