diff --git a/LibCmo/CK2/CKBitmapData.cpp b/LibCmo/CK2/CKBitmapData.cpp index c62a697..cfdc777 100644 --- a/LibCmo/CK2/CKBitmapData.cpp +++ b/LibCmo/CK2/CKBitmapData.cpp @@ -368,6 +368,10 @@ namespace LibCmo::CK2 { #pragma region Not important variable visitor + CK_BITMAPDATA_FLAGS CKBitmapData::GetBitmapFlags() const { + return m_BitmapFlags; + } + void CKBitmapData::SetCubeMap(bool is_cube) { if (is_cube) { SetSlotCount(6); diff --git a/LibCmo/CK2/CKBitmapData.hpp b/LibCmo/CK2/CKBitmapData.hpp index 9b131f5..938bdc2 100644 --- a/LibCmo/CK2/CKBitmapData.hpp +++ b/LibCmo/CK2/CKBitmapData.hpp @@ -110,6 +110,8 @@ namespace LibCmo::CK2 { #pragma region Not important funcs + CK_BITMAPDATA_FLAGS GetBitmapFlags() const; + void SetCubeMap(bool is_cube); bool IsCubeMap() const; diff --git a/LibCmo/CK2/CKContext.cpp b/LibCmo/CK2/CKContext.cpp index 274bf1d..aea1ed6 100644 --- a/LibCmo/CK2/CKContext.cpp +++ b/LibCmo/CK2/CKContext.cpp @@ -157,7 +157,7 @@ namespace LibCmo::CK2 { } CKDWORD CKContext::GetManagerCount() { - return m_ManagerList.size(); + return static_cast(m_ManagerList.size()); } MgrImpls::CKBaseManager* CKContext::GetManager(CKDWORD index) { diff --git a/LibCmo/CK2/ObjImpls/CKMesh.cpp b/LibCmo/CK2/ObjImpls/CKMesh.cpp index 862596e..dc0d189 100644 --- a/LibCmo/CK2/ObjImpls/CKMesh.cpp +++ b/LibCmo/CK2/ObjImpls/CKMesh.cpp @@ -289,7 +289,7 @@ namespace LibCmo::CK2::ObjImpls { chunk->ReadStruct(uvcount); if (uvcount != 0) { // make sure no overflow - uvcount = std::min(uvcount, chl.m_CustomUV.size()); + uvcount = std::min(uvcount, static_cast(chl.m_CustomUV.size())); CKDWORD bufsize = uvcount * CKSizeof(VxMath::VxVector2); auto locker = chunk->LockReadBufferWrapper(bufsize); diff --git a/LibCmo/CK2/ObjImpls/CKTexture.cpp b/LibCmo/CK2/ObjImpls/CKTexture.cpp index 2869f0e..4ccc616 100644 --- a/LibCmo/CK2/ObjImpls/CKTexture.cpp +++ b/LibCmo/CK2/ObjImpls/CKTexture.cpp @@ -93,34 +93,41 @@ namespace LibCmo::CK2::ObjImpls { return false; } else { CKDWORD fmtbytesize; - if (chunk->SeekIdentifierAndReturnSize(CK_STATESAVEFLAGS_TEXTURE::CK_STATESAVE_OLDTEXONLY, &fmtbytesize)) { + // MARK: there is a patch for virtools 2.1 implement. + // CK_STATESAVE_TEXONLY is noy valid in 2.1 but we add it for cpmpatibility reason. + if (chunk->SeekIdentifierAndReturnSize(CK_STATESAVEFLAGS_TEXTURE::CK_STATESAVE_OLDTEXONLY, &fmtbytesize) || + chunk->SeekIdentifierAndReturnSize(CK_STATESAVEFLAGS_TEXTURE::CK_STATESAVE_TEXONLY, &fmtbytesize)) { // for mid data: // HIGH >>> 0xFF (blank) 0xFF (save options) 0xFF (transparent + movie info + video fmt) 0xFF (mip map) <<< LOW // for mixed flags: // HIGH >>> 1(blank) 1(cubemap) 1(has video fmt) 1(is transparent) CKDWORD mixdata; chunk->ReadStruct(mixdata); + // set mipmap m_UseMipMap = (mixdata & 0xFF); - m_ImageHost.SetSaveOptions(static_cast((mixdata & 0xFF0000) >> 16)); + mixdata >>= 8; + // mix flags + CKDWORD mixflags = mixdata & 0xFF; + mixdata >>= 8; + m_ImageHost.SetTransparent(mixflags & 0x1); + bool hasVideoFmt = mixflags & 0x2; + m_ImageHost.SetCubeMap(mixflags & 0x4); + // save options + m_ImageHost.SetSaveOptions(static_cast(mixdata & 0xFF)); + mixdata >>= 8; - mixdata = mixdata & 0xFF00 >> 8; - m_ImageHost.SetTransparent(mixdata & 0x1); - bool hasVideoFmt = mixdata & 0x2; - m_ImageHost.SetCubeMap(mixdata & 0x4); - // MARK: I ignore 0x4 in there because it involve video. - // set current slot, transparent color, and video format. CKDWORD currentSlot, transColor; fmtbytesize -= CKSizeof(CKDWORD); switch (fmtbytesize) { - case (3 * sizeof(CKDWORD)): + case (3 * CKSizeof(CKDWORD)): chunk->ReadStruct(transColor); m_ImageHost.SetTransparentColor(transColor); chunk->ReadStruct(currentSlot); m_ImageHost.SetCurrentSlot(currentSlot); chunk->ReadStruct(m_VideoFormat); break; - case (2 * sizeof(CKDWORD)): + case (2 * CKSizeof(CKDWORD)): if (m_ImageHost.GetSlotCount() <= 1 || !hasVideoFmt) { chunk->ReadStruct(transColor); m_ImageHost.SetTransparentColor(transColor); @@ -133,7 +140,7 @@ namespace LibCmo::CK2::ObjImpls { chunk->ReadStruct(m_VideoFormat); } break; - case (sizeof(CKDWORD)): + case (CKSizeof(CKDWORD)): if (hasVideoFmt) { chunk->ReadStruct(m_VideoFormat); } else if (m_ImageHost.GetSlotCount() <= 1) { diff --git a/Unvirt/AccessibleValue.cpp b/Unvirt/AccessibleValue.cpp index e53e360..e1ef1d7 100644 --- a/Unvirt/AccessibleValue.cpp +++ b/Unvirt/AccessibleValue.cpp @@ -339,6 +339,15 @@ namespace Unvirt::AccessibleValue { { LibCmo::CK2::CK_TEXTURE_SAVEOPTIONS::CKTEXTURE_USEGLOBAL, {"CKTEXTURE_USEGLOBAL"} }, { LibCmo::CK2::CK_TEXTURE_SAVEOPTIONS::CKTEXTURE_INCLUDEORIGINALFILE, {"CKTEXTURE_INCLUDEORIGINALFILE"} }, }; + const GeneralReflectionArray CK_BITMAPDATA_FLAGS { + { LibCmo::CK2::CK_BITMAPDATA_FLAGS::CKBITMAPDATA_INVALID, {"CKBITMAPDATA_INVALID"} }, + { LibCmo::CK2::CK_BITMAPDATA_FLAGS::CKBITMAPDATA_TRANSPARENT, {"CKBITMAPDATA_TRANSPARENT"} }, + { LibCmo::CK2::CK_BITMAPDATA_FLAGS::CKBITMAPDATA_FORCERESTORE, {"CKBITMAPDATA_FORCERESTORE"} }, + { LibCmo::CK2::CK_BITMAPDATA_FLAGS::CKBITMAPDATA_CLAMPUPTODATE, {"CKBITMAPDATA_CLAMPUPTODATE"} }, + { LibCmo::CK2::CK_BITMAPDATA_FLAGS::CKBITMAPDATA_CUBEMAP, {"CKBITMAPDATA_CUBEMAP"} }, + { LibCmo::CK2::CK_BITMAPDATA_FLAGS::CKBITMAPDATA_FREEVIDEOMEMORY, {"CKBITMAPDATA_FREEVIDEOMEMORY"} }, + { LibCmo::CK2::CK_BITMAPDATA_FLAGS::CKBITMAPDATA_DYNAMIC, {"CKBITMAPDATA_DYNAMIC"} }, + }; const GeneralReflectionArray VX_PIXELFORMAT { { LibCmo::VxMath::VX_PIXELFORMAT::UNKNOWN_PF, {"UNKNOWN_PF"} }, diff --git a/Unvirt/AccessibleValue.hpp b/Unvirt/AccessibleValue.hpp index a03ab89..f4ad2b8 100644 --- a/Unvirt/AccessibleValue.hpp +++ b/Unvirt/AccessibleValue.hpp @@ -35,7 +35,10 @@ namespace Unvirt { for (auto& item : desc) { // if it have exacelt same entry, return directly if (item.first == val) { - strl = item.second.mName; + StringHelper::StdstringPrintf(strl, "%s (0x%08" PRIXCKDWORD ")", + item.second.mName, + static_cast(item.first) + ); return strl; } @@ -80,7 +83,8 @@ namespace Unvirt { extern const GeneralReflectionArray CK_OBJECT_FLAGS; extern const GeneralReflectionArray CK_3DENTITY_FLAGS; extern const GeneralReflectionArray CK_TEXTURE_SAVEOPTIONS; - + extern const GeneralReflectionArray CK_BITMAPDATA_FLAGS; + extern const GeneralReflectionArray VX_PIXELFORMAT; extern const GeneralReflectionArray VXTEXTURE_BLENDMODE; extern const GeneralReflectionArray VXTEXTURE_FILTERMODE; diff --git a/Unvirt/StructFormatter.cpp b/Unvirt/StructFormatter.cpp index d8d2884..959f51e 100644 --- a/Unvirt/StructFormatter.cpp +++ b/Unvirt/StructFormatter.cpp @@ -45,13 +45,16 @@ namespace Unvirt::StructFormatter { r = (argb & 0x00FF0000) >> 16, g = (argb & 0x0000FF00) >> 8, b = (argb & 0x000000FF); - fprintf(stdout, "A:%" PRIuCKDWORD " (%.4" PRIfCKFLOAT ") RGB(%" PRIuCKDWORD ", %" PRIuCKDWORD ", %" PRIuCKDWORD ") RGB#%" PRIxCKDWORD "%" PRIxCKDWORD "%" PRIxCKDWORD " RGBA#%" PRIxCKDWORD "%" PRIxCKDWORD "%" PRIxCKDWORD "%" PRIxCKDWORD, + fprintf(stdout, "A:%" PRIuCKDWORD " (%.4" PRIfCKFLOAT ") RGB(%" PRIuCKDWORD ", %" PRIuCKDWORD ", %" PRIuCKDWORD ") RGB#%02" PRIxCKDWORD "%02" PRIxCKDWORD "%02" PRIxCKDWORD " RGBA#%02" PRIxCKDWORD "%02" PRIxCKDWORD "%02" PRIxCKDWORD "%02" PRIxCKDWORD, a, col.a, r, g, b, r, g, b, r, g, b, a ); } + static void PrintColor(LibCmo::CKDWORD argb) { + PrintColor(LibCmo::VxMath::VxColor(argb)); + } template static void GeneralPrintList( @@ -87,6 +90,10 @@ namespace Unvirt::StructFormatter { fprintf(stdout, "CK ID: %" PRIuCKID "\n", obj->GetID()); // print class id fprintf(stdout, "Class ID: %" PRIiCLASSID " (%s)\n", obj->GetClassID(), AccessibleValue::GetClassIdHierarchy(obj->GetClassID()).c_str()); + // print flags + fputs("Flags:\n", stdout); + fputs(AccessibleValue::GetFlagEnumName(obj->GetObjectFlags(), AccessibleValue::EnumDesc::CK_OBJECT_FLAGS, "\n").c_str(), stdout); + fputc('\n', stdout); } static void PrintCKSceneObjectDetail(LibCmo::CK2::ObjImpls::CKSceneObject* obj) { @@ -177,7 +184,40 @@ namespace Unvirt::StructFormatter { static void PrintCKTextureDetail(LibCmo::CK2::ObjImpls::CKTexture* obj) { PrintCKBeObjectDetail(obj); fputs(UNVIRT_TERMCOL_LIGHT_YELLOW(("CKTexture\n")), stdout); - fputs(UNVIRT_TERMCOL_LIGHT_RED(("No Data\n")), stdout); + + // texture + fputs("== Texture ==\n", stdout); + + LibCmo::CK2::CKBitmapData& bd = obj->GetUnderlyingData(); + LibCmo::CKDWORD slot_count = bd.GetSlotCount(); + fprintf(stdout, "Slot Count: %" PRIuCKDWORD "\n", slot_count); + fprintf(stdout, "Current Slot: %" PRIuCKDWORD "\n", bd.GetCurrentSlot()); + + fputs("Index\tWidth\tHeight\tImage Addr\tImage Size\tFilename\n", stdout); + for (LibCmo::CKDWORD i = 0; i < slot_count; ++i) { + auto desc = bd.GetImageDesc(i); + + fprintf(stdout, "#%" PRIuCKDWORD "\t", i); + fprintf(stdout, "%" PRIuCKDWORD "\t%" PRIuCKDWORD "\t", desc->GetWidth(), desc->GetHeight()); + PrintPointer(desc->GetImage()); + fputc('\t', stdout); + fprintf(stdout, "0x%" PRIxCKDWORD " bytes\t", desc->GetImageSize()); + PrintCKSTRING(bd.GetSlotFileName(i)); + fputc('\n', stdout); + } + + // other data + fputs("== Misc ==\n", stdout); + fprintf(stdout, "Video Format: %s\n", AccessibleValue::GetEnumName(obj->GetVideoFormat(), AccessibleValue::EnumDesc::VX_PIXELFORMAT).c_str()); + fprintf(stdout, "Save Option: %s\n", AccessibleValue::GetEnumName(bd.GetSaveOptions(), AccessibleValue::EnumDesc::CK_TEXTURE_SAVEOPTIONS).c_str()); + fprintf(stdout, "Pick Threshold: %" PRIuCKDWORD "\n", bd.GetPickThreshold()); + fputs("Transparent Color: ", stdout); + PrintColor(bd.GetTransparentColor()); + fputc('\n', stdout); + + fputs("Bitmap Flags:\n", stdout); + fputs(AccessibleValue::GetFlagEnumName(bd.GetBitmapFlags(), AccessibleValue::EnumDesc::CK_BITMAPDATA_FLAGS, "\n").c_str(), stdout); + fputc('\n', stdout); } static void PrintCKMaterialDetail(LibCmo::CK2::ObjImpls::CKMaterial* obj) { @@ -204,7 +244,7 @@ namespace Unvirt::StructFormatter { // basic data fputs("== Basic ==\n", stdout); - fprintf(stdout, "Both Sided: "); + fputs("Both Sided: ", stdout); PrintBool(obj->GetTwoSidedEnabled()); fputc('\n', stdout); fprintf(stdout, "Fill Mode: %s\n", AccessibleValue::GetEnumName(obj->GetFillMode(), AccessibleValue::EnumDesc::VXFILL_MODE).c_str()); @@ -227,13 +267,13 @@ namespace Unvirt::StructFormatter { fprintf(stdout, "Filter Min: %s\n", AccessibleValue::GetEnumName(obj->GetTextureMinMode(), AccessibleValue::EnumDesc::VXTEXTURE_FILTERMODE).c_str()); fprintf(stdout, "Filter Mag: %s\n", AccessibleValue::GetEnumName(obj->GetTextureMagMode(), AccessibleValue::EnumDesc::VXTEXTURE_FILTERMODE).c_str()); fprintf(stdout, "Address Mode: %s\n", AccessibleValue::GetEnumName(obj->GetTextureAddressMode(), AccessibleValue::EnumDesc::VXTEXTURE_ADDRESSMODE).c_str()); - fprintf(stdout, "Perspective Correct: "); + fputs("Perspective Correct: ", stdout); PrintBool(obj->GetPerspectiveCorrectionEnabled()); fputc('\n', stdout); // alpha test fputs("== Alpha Test ==\n", stdout); - fprintf(stdout, "Enabled: "); + fputs("Enabled: ", stdout); PrintBool(obj->GetAlphaTestEnabled()); fputc('\n', stdout); fprintf(stdout, "Alpha Function: %s\n", AccessibleValue::GetEnumName(obj->GetAlphaFunc(), AccessibleValue::EnumDesc::VXCMPFUNC).c_str()); @@ -241,7 +281,7 @@ namespace Unvirt::StructFormatter { // alpha blend fputs("== Alpha Blend ==\n", stdout); - fprintf(stdout, "Enabled: "); + fputs("Enabled: ", stdout); PrintBool(obj->GetAlphaBlendEnabled()); fputc('\n', stdout); fprintf(stdout, "Source Blend: %s\n", AccessibleValue::GetEnumName(obj->GetSourceBlend(), AccessibleValue::EnumDesc::VXBLEND_MODE).c_str()); @@ -249,7 +289,7 @@ namespace Unvirt::StructFormatter { // z buffer fputs("== Z-Buffer Write ==\n", stdout); - fprintf(stdout, "Enabled: "); + fputs("Enabled: ", stdout); PrintBool(obj->GetZWriteEnabled()); fputc('\n', stdout); fprintf(stdout, "Z Compare Function: %s\n", AccessibleValue::GetEnumName(obj->GetZFunc(), AccessibleValue::EnumDesc::VXCMPFUNC).c_str()); diff --git a/Unvirt/TerminalHelper.cpp b/Unvirt/TerminalHelper.cpp index 4366d33..9688ad8 100644 --- a/Unvirt/TerminalHelper.cpp +++ b/Unvirt/TerminalHelper.cpp @@ -47,7 +47,7 @@ namespace Unvirt { } void GetCmdLine(std::string& u8cmd) { - fputs("Unvirt> ", stdout); + fputs(UNVIRT_TERMCOL_LIGHT_GREEN(("Unvirt> ")), stdout); #if defined(LIBCMO_OS_WIN32) std::wstring wcmd; std::getline(std::wcin, wcmd);