Add support for GPA patching, remove some unusable video options

This commit is contained in:
elasota
2020-03-14 03:21:20 -04:00
parent 505e73e842
commit d90ea24405
6 changed files with 284 additions and 80 deletions

View File

@@ -0,0 +1,101 @@
{
"items" :
[
{
"name" : "Okay",
"itemType" : "Button",
"pos" : [ 267, 211 ],
"size" : [ 58, 20 ],
"id" : 0,
"enabled" : true
},
{
"name" : "Cancel",
"itemType" : "Button",
"pos" : [ 201, 211 ],
"size" : [ 58, 20 ],
"id" : 0,
"enabled" : true
},
{
"name" : "",
"itemType" : "Icon",
"pos" : [ 209, 40 ],
"size" : [ 32, 32 ],
"id" : 1020,
"enabled" : true
},
{
"name" : "",
"itemType" : "Icon",
"pos" : [ 249, 40 ],
"size" : [ 32, 32 ],
"id" : 1021,
"enabled" : true
},
{
"name" : "",
"itemType" : "Icon",
"pos" : [ 289, 40 ],
"size" : [ 32, 32 ],
"id" : 1022,
"enabled" : true
},
{
"name" : "Number of Rooms to Display:\r(the less rooms, the faster)",
"itemType" : "Label",
"pos" : [ 8, 40 ],
"size" : [ 195, 32 ],
"id" : 0,
"enabled" : false
},
{
"name" : "",
"itemType" : "Image",
"pos" : [ 0, 0 ],
"size" : [ 333, 32 ],
"id" : 1006,
"enabled" : false
},
{
"name" : "",
"itemType" : "UserItem",
"pos" : [ 8, 80 ],
"size" : [ 317, 1 ],
"id" : 0,
"enabled" : false
},
{
"name" : "Beautiful opening color fade",
"itemType" : "CheckBox",
"pos" : [ 8, 142 ],
"size" : [ 256, 18 ],
"id" : 0,
"enabled" : true
},
{
"name" : "",
"itemType" : "UserItem",
"pos" : [ 8, 137 ],
"size" : [ 317, 1 ],
"id" : 0,
"enabled" : false
},
{
"name" : "",
"itemType" : "UserItem",
"pos" : [ 8, 200 ],
"size" : [ 317, 1 ],
"id" : 0,
"enabled" : false
},
{
"name" : "Defaults",
"itemType" : "Button",
"pos" : [ 8, 211 ],
"size" : [ 64, 20 ],
"id" : 0,
"enabled" : true
}
]
}

View File

@@ -0,0 +1,9 @@
{
"add" :
{
"DITL/1017.json" : "ApplicationResourcePatches/DITL/1017.json"
},
"delete" :
[
]
}

View File

@@ -4,7 +4,7 @@ mkdir Packaged\WinCursors
x64\Release\MiniRez.exe "GliderProData\Glider PRO.r" Packaged\ApplicationResources.gpr
x64\Release\gpr2gpa.exe "Packaged\ApplicationResources.gpr" "DefaultTimestamp.timestamp" "Packaged\ApplicationResources.gpa"
x64\Release\gpr2gpa.exe "Packaged\ApplicationResources.gpr" "DefaultTimestamp.timestamp" "Packaged\ApplicationResources.gpa" "ApplicationResourcePatches\manifest.json"
x64\Release\ConvertColorCursors.exe

View File

@@ -31,13 +31,16 @@
#define kDisplay1Item 3
#define kDisplay3Item 4
#define kDisplay9Item 5
#define kBorder1Item 8
#define kDoColorFadeItem 9
#define kCurrentDepth 10
#define k256Depth 11
#define k16Depth 12
#define kDispDefault 15
#define kUseQDItem 16
#define kUseScreen2Item 17
//#define kCurrentDepth 10
//#define k256Depth 11
//#define k16Depth 12
#define kBorder2Item 10
#define kBorder3Item 11
#define kDispDefault 12
//#define kUseQDItem 13
//#define kUseScreen2Item 14
#define kSofterItem 4
#define kLouderItem 5
#define kVolNumberItem 7
@@ -894,17 +897,13 @@ void DisplayUpdate (Dialog *theDialog)
DrawDefaultButton(theDialog);
SetDialogItemValue(theDialog, kDoColorFadeItem, (short)wasFade);
SelectFromRadioGroup(theDialog, kCurrentDepth + wasDepthPref,
kCurrentDepth, k16Depth);
// SetDialogItemValue(theDialog, kUseQDItem, (short)wasQD);
SetDialogItemValue(theDialog, kUseScreen2Item, (short)wasScreen2);
ForeColor(redColor);
FrameDisplayIcon(theDialog, StdColors::Red());
ForeColor(blackColor);
FrameDialogItemC(theDialog, 8, kRedOrangeColor8);
FrameDialogItemC(theDialog, 13, kRedOrangeColor8);
FrameDialogItemC(theDialog, 14, kRedOrangeColor8);
FrameDialogItemC(theDialog, kBorder1Item, kRedOrangeColor8);
FrameDialogItemC(theDialog, kBorder2Item, kRedOrangeColor8);
FrameDialogItemC(theDialog, kBorder3Item, kRedOrangeColor8);
}
//-------------------------------------------------------------- DisplayFilter
@@ -961,37 +960,6 @@ int16_t DisplayFilter(Dialog *dial, const TimeTaggedVOSEvent *evt)
}
break;
case PL_KEY_SPECIAL(kUpArrow):
switch (wasDepthPref)
{
case kSwitchIfNeeded:
return k16Depth;
case kSwitchTo256Colors:
return kCurrentDepth;
case kSwitchTo16Grays:
return k256Depth;
default:
return -1;
}
break;
case PL_KEY_SPECIAL(kDownArrow):
switch (wasDepthPref)
{
case kSwitchIfNeeded:
return k256Depth;
case kSwitchTo256Colors:
return k16Depth;
case kSwitchTo16Grays:
return kCurrentDepth;
}
break;
case PL_KEY_ASCII('1'):
return kDisplay1Item;
@@ -1008,15 +976,6 @@ int16_t DisplayFilter(Dialog *dial, const TimeTaggedVOSEvent *evt)
FlashDialogButton(dial, kDispDefault);
return kDispDefault;
case PL_KEY_ASCII('R'):
PL_NotYetImplemented_TODO("FixMe"); // GP: This looks like a bug
FlashDialogButton(dial, kUseQDItem);
return kUseScreen2Item;
case PL_KEY_ASCII('U'):
return kUseQDItem;
default:
return -1;
}
@@ -1036,14 +995,8 @@ void DoDisplayPrefs (void)
BringUpDialog(&prefDlg, kDisplayPrefsDialID, nullptr);
if (!thisMac.can8Bit)
{
MyDisableControl(prefDlg, kDoColorFadeItem);
MyDisableControl(prefDlg, k256Depth);
}
if (!thisMac.can4Bit)
MyDisableControl(prefDlg, k16Depth);
if (thisMac.numScreens < 2)
MyDisableControl(prefDlg, kUseScreen2Item);
wasNeighbors = numNeighbors;
wasFade = isDoColorFade;
wasDepthPref = isDepthPref;
@@ -1100,29 +1053,12 @@ void DoDisplayPrefs (void)
SetDialogItemValue(prefDlg, kDoColorFadeItem, (short)wasFade);
break;
case kCurrentDepth:
case k256Depth:
case k16Depth:
wasDepthPref = itemHit - kCurrentDepth;
SelectFromRadioGroup(prefDlg, itemHit, kCurrentDepth, k16Depth);
break;
case kDispDefault:
FrameDisplayIcon(prefDlg, StdColors::White());
ForeColor(blackColor);
DisplayDefaults();
DisplayUpdate(prefDlg);
break;
case kUseQDItem:
// wasQD = !wasQD;
// SetDialogItemValue(prefDlg, kUseQDItem, (short)wasQD);
break;
case kUseScreen2Item:
wasScreen2 = !wasScreen2;
SetDialogItemValue(prefDlg, kUseScreen2Item, (short)wasScreen2);
break;
}
}

View File

@@ -1,3 +1,5 @@
#define _CRT_SECURE_NO_WARNINGS
#include "BMPFormat.h"
#include "CFileStream.h"
#include "CombinedTimestamp.h"
@@ -17,8 +19,12 @@
#include "zlib.h"
#include "rapidjson/rapidjson.h"
#include "rapidjson/document.h"
#include <stdio.h>
#include <vector>
#include <algorithm>
#include <Windows.h>
struct PlannedEntry
@@ -33,6 +39,11 @@ struct PlannedEntry
}
};
bool EntryAlphaSortPredicate(const PlannedEntry &a, const PlannedEntry &b)
{
return a.m_name < b.m_name;
}
void AppendStr(std::vector<uint8_t> &array, const char *str)
{
size_t appendSize = strlen(str);
@@ -998,11 +1009,129 @@ bool ImportDialogItemTemplate(std::vector<uint8_t> &outTXT, const void *inData,
return true;
}
void ReadFileToVector(FILE *f, std::vector<uint8_t> &vec)
{
fseek(f, 0, SEEK_END);
long fsize = ftell(f);
vec.resize(fsize);
if (fsize > 0)
{
fseek(f, 0, SEEK_SET);
fread(&vec[0], 1, fsize, f);
}
}
bool ApplyPatch(const std::vector<uint8_t> &patchFileContents, std::vector<PlannedEntry> &archive)
{
rapidjson::Document document;
document.Parse(reinterpret_cast<const char*>(&patchFileContents[0]), patchFileContents.size());
if (document.HasParseError())
{
fprintf(stderr, "Error occurred parsing patch data");
fprintf(stderr, "Error code %i Location %i", static_cast<int>(document.GetParseError()), static_cast<int>(document.GetErrorOffset()));
return false;
}
if (!document.IsObject())
{
fprintf(stderr, "Patch document is not an object");
return false;
}
if (document.HasMember("add"))
{
const rapidjson::Value &addValue = document["add"];
if (!addValue.IsObject())
{
fprintf(stderr, "Patch add list is not an object");
return false;
}
for (rapidjson::Value::ConstMemberIterator it = addValue.MemberBegin(), itEnd = addValue.MemberEnd(); it != itEnd; ++it)
{
const rapidjson::Value &itemName = it->name;
if (!itemName.IsString())
{
fprintf(stderr, "Patch add list item key is not a string");
return false;
}
const rapidjson::Value &itemValue = it->value;
if (!itemValue.IsString())
{
fprintf(stderr, "Patch add list item value is not a string");
return false;
}
PlannedEntry *entry = nullptr;
for (std::vector<PlannedEntry>::iterator it = archive.begin(), itEnd = archive.end(); it != itEnd; ++it)
{
if (it->m_name == itemName.GetString())
{
entry = &(*it);
break;
}
}
if (!entry)
{
archive.push_back(PlannedEntry());
entry = &archive.back();
}
FILE *f = fopen(itemValue.GetString(), "rb");
if (!f)
{
fprintf(stderr, "Could not find source file %s for patch", static_cast<const char*>(itemValue.GetString()));
return false;
}
entry->m_isDirectory = false;
entry->m_contents.clear();
ReadFileToVector(f, entry->m_contents);
fclose(f);
}
}
if (document.HasMember("delete"))
{
const rapidjson::Value &deleteValue = document["delete"];
if (!deleteValue.IsArray())
{
fprintf(stderr, "Patch add list is not an object");
return false;
}
for (const rapidjson::Value *it = deleteValue.Begin(), *itEnd = deleteValue.End(); it != itEnd; ++it)
{
const rapidjson::Value &item = *it;
if (!item.IsString())
{
fprintf(stderr, "Patch delete list item key is not a string");
return false;
}
PlannedEntry *entry = nullptr;
for (std::vector<PlannedEntry>::iterator it = archive.begin(), itEnd = archive.end(); it != itEnd; ++it)
{
if (it->m_name == item.GetString())
{
archive.erase(it);
break;
}
}
}
}
return true;
}
int main(int argc, const char **argv)
{
if (argc != 4)
if (argc != 4 && argc != 5)
{
fprintf(stderr, "Usage: gpr2gpa <input.gpr> <input.ts> <output.gpa>");
fprintf(stderr, "Usage: gpr2gpa <input.gpr> <input.ts> <output.gpa> [patch.json]");
return -1;
}
@@ -1029,6 +1158,23 @@ int main(int argc, const char **argv)
return -1;
}
bool havePatchFile = false;
std::vector<uint8_t> patchFileContents;
FILE *patchF = nullptr;
if (argc == 5 && fopen_s(&patchF, argv[4], "rb"))
{
fprintf(stderr, "Error reading patch file");
return -1;
}
if (patchF)
{
havePatchFile = true;
ReadFileToVector(patchF, patchFileContents);
fclose(patchF);
}
PortabilityLayer::CFileStream cfs(inF);
PortabilityLayer::ResourceFile *resFile = PortabilityLayer::ResourceFile::Create();
@@ -1133,6 +1279,14 @@ int main(int argc, const char **argv)
}
}
if (havePatchFile)
{
if (!ApplyPatch(patchFileContents, contents))
return -1;
}
std::sort(contents.begin(), contents.end(), EntryAlphaSortPredicate);
ExportZipFile(argv[3], contents, ts);
resFile->Destroy();

View File

@@ -63,6 +63,7 @@
<Import Project="..\Common.props" />
<Import Project="..\GpCommon.props" />
<Import Project="..\MacRomanConversion.props" />
<Import Project="..\RapidJSON.props" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
@@ -71,6 +72,7 @@
<Import Project="..\Common.props" />
<Import Project="..\GpCommon.props" />
<Import Project="..\MacRomanConversion.props" />
<Import Project="..\RapidJSON.props" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
@@ -79,6 +81,7 @@
<Import Project="..\Common.props" />
<Import Project="..\GpCommon.props" />
<Import Project="..\MacRomanConversion.props" />
<Import Project="..\RapidJSON.props" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
@@ -87,6 +90,7 @@
<Import Project="..\Common.props" />
<Import Project="..\GpCommon.props" />
<Import Project="..\MacRomanConversion.props" />
<Import Project="..\RapidJSON.props" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup />