Add download house option

This commit is contained in:
elasota
2021-05-11 00:41:35 -04:00
parent 75923ad7b0
commit ac56badffa
14 changed files with 320 additions and 3 deletions

View File

@@ -268,6 +268,16 @@ bool GpSystemServices_Win32::HasNativeFileManager() const
return true;
}
GpOperatingSystem_t GpSystemServices_Win32::GetOperatingSystem() const
{
return GpOperatingSystems::kWindows;
}
GpOperatingSystemFlavor_t GpSystemServices_Win32::GetOperatingSystemFlavor() const
{
return GpOperatingSystemFlavors::kGeneric;
}
unsigned int GpSystemServices_Win32::GetCPUCount() const
{
SYSTEM_INFO sysInfo;

View File

@@ -35,6 +35,8 @@ public:
bool IsFullscreenPreferred() const override;
bool IsFullscreenOnStartup() const override;
bool HasNativeFileManager() const override;
GpOperatingSystem_t GetOperatingSystem() const override;
GpOperatingSystemFlavor_t GetOperatingSystemFlavor() const override;
unsigned int GetCPUCount() const override;
void SetTextInputEnabled(bool isEnabled) override;
bool IsTextInputEnabled() const override;

View File

@@ -90,6 +90,16 @@ bool GpSystemServices_Android::HasNativeFileManager() const
return false;
}
GpOperatingSystem_t GpSystemServices_Android::GetOperatingSystem() const
{
return GpOperatingSystems::kAndroid;
}
GpOperatingSystemFlavor_t GpSystemServices_Android::GetOperatingSystemFlavor() const
{
return GpOperatingSystems::kGeneric;
}
unsigned int GpSystemServices_Android::GetCPUCount() const
{
return SDL_GetCPUCount();

View File

@@ -16,6 +16,8 @@ public:
bool IsFullscreenPreferred() const override;
bool IsFullscreenOnStartup() const override;
bool HasNativeFileManager() const override;
GpOperatingSystem_t GetOperatingSystem() const override;
GpOperatingSystemFlavor_t GetOperatingSystemFlavor() const override;
unsigned int GetCPUCount() const override;
void SetTextInputEnabled(bool isEnabled) override;
bool IsTextInputEnabled() const override;

View File

@@ -171,6 +171,16 @@ bool GpSystemServices_Web::HasNativeFileManager() const
return false;
}
GpOperatingSystem_t GpSystemServices_Web::GetOperatingSystem() const
{
return GpOperatingSystems::kWeb;
}
GpOperatingSystemFlavor_t GpSystemServices_Web::GetOperatingSystemFlavor() const
{
return GpOperatingSystems::kGeneric;
}
unsigned int GpSystemServices_Web::GetCPUCount() const
{
return SDL_GetCPUCount();

View File

@@ -19,6 +19,8 @@ public:
bool IsFullscreenPreferred() const override;
bool IsFullscreenOnStartup() const override;
bool HasNativeFileManager() const override;
GpOperatingSystem_t GetOperatingSystem() const;
GpOperatingSystemFlavor_t GetOperatingSystemFlavor() const;
unsigned int GetCPUCount() const override;
void SetTextInputEnabled(bool isEnabled) override;
bool IsTextInputEnabled() const override;

View File

@@ -99,6 +99,16 @@ bool GpSystemServices_X::HasNativeFileManager() const
return true;
}
GpOperatingSystem_t GpSystemServices_X::GetOperatingSystem() const
{
return GpOperatingSystems::kLinux;
}
GpOperatingSystemFlavor_t GpSystemServices_X::GetOperatingSystemFlavor() const
{
return GpOperatingSystems::kGeneric;
}
unsigned int GpSystemServices_X::GetCPUCount() const
{
return SDL_GetCPUCount();

View File

@@ -19,6 +19,8 @@ public:
bool IsFullscreenPreferred() const override;
bool IsFullscreenOnStartup() const override;
bool HasNativeFileManager() const override;
GpOperatingSystem_t GetOperatingSystem() const override;
GpOperatingSystemFlavor_t GetOperatingSystemFlavor() const override;
unsigned int GetCPUCount() const override;
void SetTextInputEnabled(bool isEnabled) override;
bool IsTextInputEnabled() const override;

View File

@@ -76,6 +76,7 @@ namespace PortabilityLayer
#define iCoordinateWindow 21
#define iExportGliderPROHouse 1
#define iDownloadHouse 2
//-------------------------------------------------------------- Structs
/*

View File

@@ -120,12 +120,12 @@ void DoGoToDialog (void);
void ConvertHouseVer1To2 (void);
void ShiftWholeHouse (SInt16);
void ExportHouse (void);
void DownloadHouse (void);
void DoHouseInfo (void); // --- HouseInfo.c
Boolean OpenHouse (Boolean load); // --- HouseIO.c
Boolean OpenSpecificHouse (const VFileSpec &);
Boolean SaveHouseAs (void);
Boolean ReadHouse (GpIOStream *houseStream, bool untrusted);
Boolean WriteHouse (Boolean);
Boolean CloseHouse (void);

View File

@@ -25,6 +25,8 @@
#include "PLStringCompare.h"
#include "PLPasStr.h"
#include "CombinedTimestamp.h"
#include "DeflateCodec.h"
#include "MacFileInfo.h"
#include "GpIOStream.h"
#include "GpVector.h"
@@ -32,6 +34,7 @@
#include "QDPictOpcodes.h"
#include "QDPixMap.h"
#include "PLStandardColors.h"
#include "ZipFile.h"
#define kSaveChangesAlert 1002
#define kSaveChanges 1
@@ -3515,10 +3518,16 @@ ExportHouseResult_t TryExportHouseToStream(GpIOStream *stream)
ByteSwapHouse(house, houseSize, true);
if (!stream->WriteExact(house, houseType::kBinaryDataSize))
{
ByteSwapHouse(house, houseSize, false);
return ExportHouseResults::kIOError;
}
if (!stream->WriteExact(house->rooms, sizeof(roomType) * nRooms))
{
ByteSwapHouse(house, houseSize, false);
return ExportHouseResults::kIOError;
}
ByteSwapHouse(house, houseSize, false);
@@ -3610,3 +3619,218 @@ void ExportHouse(void)
break;
}
}
ExportHouseResult_t TryDownloadHouseToStream(GpIOStream *stream)
{
PortabilityLayer::MacFileProperties mfp;
mfp.m_createdTimeMacEpoch = PLDrivers::GetSystemServices()->GetTime();
memcpy(mfp.m_fileCreator, "ozm5", 4);
memcpy(mfp.m_fileType, "gliH", 4);
mfp.m_finderFlags = 0;
mfp.m_modifiedTimeMacEpoch = mfp.m_createdTimeMacEpoch;
mfp.m_protected = 0;
mfp.m_xPos = 0;
mfp.m_yPos = 0;
PortabilityLayer::MacFilePropertiesSerialized mfps;
mfps.Serialize(mfp);
unsigned int year, month, day, hour, minute, second;
PortabilityLayer::CombinedTimestamp ts;
PLDrivers::GetSystemServices()->GetLocalDateTime(year, month, day, hour, minute, second);
ts.SetLocalYear(year);
ts.m_localDay = day;
ts.m_localHour = hour;
ts.m_localMinute = minute;
ts.m_localMonth = month;
ts.m_localSecond = second;
uint16_t dosDate, dosTime;
ts.GetAsMSDOSTimestamp(dosDate, dosTime);
const uint32_t metaSize = sizeof(mfps.m_data);
const uint32_t metaCRC = PortabilityLayer::DeflateContext::CRC32(0, mfps.m_data, metaSize);
const char *metaPackagedName = PortabilityLayer::MacFilePropertiesSerialized::GetPackagedName();
GpUFilePos_t metaLHPos = 0;
PortabilityLayer::ZipFileLocalHeader metaLH;
metaLH.m_signature = PortabilityLayer::ZipFileLocalHeader::kSignature;
metaLH.m_versionRequired = PortabilityLayer::ZipConstants::kStoredRequiredVersion;
metaLH.m_flags = 0;
metaLH.m_method = PortabilityLayer::ZipConstants::kStoredMethod;
metaLH.m_modificationTime = dosTime;
metaLH.m_modificationDate = dosDate;
metaLH.m_crc = metaCRC;
metaLH.m_compressedSize = metaSize;
metaLH.m_uncompressedSize = metaSize;
metaLH.m_fileNameLength = strlen(metaPackagedName);
metaLH.m_extraFieldLength = 0;
if (!stream->WriteExact(&metaLH, sizeof(metaLH)))
return ExportHouseResults::kIOError;
if (!stream->WriteExact(metaPackagedName, strlen(metaPackagedName)))
return ExportHouseResults::kIOError;
if (!stream->WriteExact(mfps.m_data, metaSize))
return ExportHouseResults::kIOError;
houseType *house = *thisHouse;
const size_t houseSize = thisHouse.MMBlock()->m_size;
const size_t nRooms = house->nRooms;
const size_t houseDataSize = houseType::kBinaryDataSize + sizeof(roomType) * nRooms;
ByteSwapHouse(house, houseSize, true);
uint32_t houseCRC = PortabilityLayer::DeflateContext::CRC32(0, house, houseType::kBinaryDataSize);
houseCRC = PortabilityLayer::DeflateContext::CRC32(houseCRC, house->rooms, sizeof(roomType) * nRooms);
const uint32_t totalhouseSize = houseType::kBinaryDataSize + sizeof(roomType) * nRooms;
GpUFilePos_t houseLHPos = 0;
const char *dataPackagedName = "!data";
PortabilityLayer::ZipFileLocalHeader houseLH;
houseLH.m_signature = PortabilityLayer::ZipFileLocalHeader::kSignature;
houseLH.m_versionRequired = PortabilityLayer::ZipConstants::kStoredRequiredVersion;
houseLH.m_flags = 0;
houseLH.m_method = PortabilityLayer::ZipConstants::kStoredMethod;
houseLH.m_modificationTime = dosTime;
houseLH.m_modificationDate = dosDate;
houseLH.m_crc = houseCRC;
houseLH.m_compressedSize = totalhouseSize;
houseLH.m_uncompressedSize = totalhouseSize;
houseLH.m_fileNameLength = strlen(dataPackagedName);
houseLH.m_extraFieldLength = 0;
if (!stream->WriteExact(&houseLH, sizeof(houseLH)))
{
ByteSwapHouse(house, houseSize, false);
return ExportHouseResults::kIOError;
}
if (!stream->WriteExact(dataPackagedName, strlen(dataPackagedName)))
{
ByteSwapHouse(house, houseSize, false);
return ExportHouseResults::kIOError;
}
if (!stream->WriteExact(house, houseType::kBinaryDataSize))
{
ByteSwapHouse(house, houseSize, false);
return ExportHouseResults::kIOError;
}
if (!stream->WriteExact(house->rooms, sizeof(roomType) * nRooms))
{
ByteSwapHouse(house, houseSize, false);
return ExportHouseResults::kIOError;
}
ByteSwapHouse(house, houseSize, false);
GpUFilePos_t cdirStart = stream->Tell();
PortabilityLayer::ZipCentralDirectoryFileHeader metaCDir;
metaCDir.m_signature = PortabilityLayer::ZipCentralDirectoryFileHeader::kSignature;
metaCDir.m_versionCreated = PortabilityLayer::ZipConstants::kCompressedRequiredVersion;;
metaCDir.m_versionRequired = PortabilityLayer::ZipConstants::kStoredRequiredVersion;
metaCDir.m_flags = 0;
metaCDir.m_method = PortabilityLayer::ZipConstants::kStoredMethod;
metaCDir.m_modificationTime = dosTime;
metaCDir.m_modificationDate = dosDate;
metaCDir.m_crc = metaCRC;
metaCDir.m_compressedSize = metaSize;
metaCDir.m_uncompressedSize = metaSize;
metaCDir.m_fileNameLength = strlen(metaPackagedName);
metaCDir.m_extraFieldLength = 0;
metaCDir.m_commentLength = 0;
metaCDir.m_diskNumber = 0;
metaCDir.m_internalAttributes = 0;
metaCDir.m_externalAttributes = PortabilityLayer::ZipConstants::kArchivedAttributes;
metaCDir.m_localHeaderOffset = static_cast<uint32_t>(metaLHPos);
if (!stream->WriteExact(&metaCDir, sizeof(metaCDir)))
return ExportHouseResults::kIOError;
if (!stream->WriteExact(metaPackagedName, strlen(metaPackagedName)))
return ExportHouseResults::kIOError;
PortabilityLayer::ZipCentralDirectoryFileHeader dataCDir;
dataCDir.m_signature = PortabilityLayer::ZipCentralDirectoryFileHeader::kSignature;
dataCDir.m_versionCreated = PortabilityLayer::ZipConstants::kCompressedRequiredVersion;;
dataCDir.m_versionRequired = PortabilityLayer::ZipConstants::kStoredRequiredVersion;
dataCDir.m_flags = 0;
dataCDir.m_method = PortabilityLayer::ZipConstants::kStoredMethod;
dataCDir.m_modificationTime = dosTime;
dataCDir.m_modificationDate = dosDate;
dataCDir.m_crc = metaCRC;
dataCDir.m_compressedSize = houseDataSize;
dataCDir.m_uncompressedSize = houseDataSize;
dataCDir.m_fileNameLength = strlen(dataPackagedName);
dataCDir.m_extraFieldLength = 0;
dataCDir.m_commentLength = 0;
dataCDir.m_diskNumber = 0;
dataCDir.m_internalAttributes = 0;
dataCDir.m_externalAttributes = PortabilityLayer::ZipConstants::kArchivedAttributes;
dataCDir.m_localHeaderOffset = static_cast<uint32_t>(houseLHPos);
if (!stream->WriteExact(&dataCDir, sizeof(dataCDir)))
return ExportHouseResults::kIOError;
if (!stream->WriteExact(dataPackagedName, strlen(dataPackagedName)))
return ExportHouseResults::kIOError;
PortabilityLayer::ZipEndOfCentralDirectoryRecord eocd;
eocd.m_signature = PortabilityLayer::ZipEndOfCentralDirectoryRecord::kSignature;
eocd.m_thisDiskNumber = 0;
eocd.m_centralDirDisk = 0;
eocd.m_numCentralDirRecordsThisDisk = 2;
eocd.m_numCentralDirRecords = 2;
eocd.m_centralDirectorySizeBytes = static_cast<uint32_t>(stream->Tell() - cdirStart);
eocd.m_centralDirStartOffset = static_cast<uint32_t>(cdirStart);
eocd.m_commentLength = 0;
if (!stream->WriteExact(&eocd, sizeof(eocd)))
return ExportHouseResults::kIOError;
return ExportHouseResults::kOK;
}
ExportHouseResult_t TryDownloadHouse(void)
{
GpIOStream *stream = nullptr;
if (PortabilityLayer::FileManager::GetInstance()->OpenNonCompositeFile(PortabilityLayer::VirtualDirectories::kSourceExport, thisHouseName, ".gpf", PortabilityLayer::EFilePermission_Write, GpFileCreationDispositions::kCreateOrOverwrite, stream))
return ExportHouseResults::kStreamFailed;
ExportHouseResult_t result = TryDownloadHouseToStream(stream);
stream->Close();
return result;
}
void DownloadHouse(void)
{
ExportHouseResult_t result = TryDownloadHouse();
switch (result)
{
case ExportHouseResults::kOK:
break;
case ExportHouseResults::kMemError:
YellowAlert(kYellowNoMemory, 0);
break;
case ExportHouseResults::kInternalError:
YellowAlert(kYellowUnaccounted, 0);
break;
case ExportHouseResults::kIOError:
case ExportHouseResults::kStreamFailed:
YellowAlert(kYellowFailedWrite, 0);
break;
case ExportHouseResults::kResourceError:
YellowAlert(kYellowFailedResOpen, 0);
break;
}
}

View File

@@ -9,6 +9,7 @@
#include "Externs.h"
#include "Environ.h"
#include "IGpDisplayDriver.h"
#include "IGpSystemServices.h"
#include "GpApplicationName.h"
#include "Map.h"
#include "MenuManager.h"
@@ -79,8 +80,9 @@ void InitializeMenus (void)
if (houseMenu == nil)
RedAlert(kErrFailedResourceLoad);
exportMenu = mm->CreateMenu(PSTR("Export"), kExportMenuID, true, 100, 16, 0);
exportMenu = mm->CreateMenu(PSTR("Import/Export"), kExportMenuID, true, 100, 16, 0);
mm->AppendMenuItem(exportMenu, 0, 0, 0, 0, true, false, PSTR("Export Glider PRO\xaa House..."));
mm->AppendMenuItem(exportMenu, 0, 0, 0, 0, false, false, PSTR("Download House..."));
UpdateMenus(false);
}

View File

@@ -6,7 +6,7 @@
//============================================================================
//#include <Balloons.h>
#include "PLDrivers.h"
#include "PLNumberFormatting.h"
#include "PLKeyEncoding.h"
#include "PLHacks.h"
@@ -17,6 +17,7 @@
#include "Externs.h"
#include "Environ.h"
#include "House.h"
#include "IGpSystemServices.h"
#include "MenuManager.h"
#include "ObjectEdit.h"
@@ -143,9 +144,17 @@ void UpdateMenusHouseOpen (void)
}
if (houseUnlocked)
{
EnableMenuItem(exportMenu, iExportGliderPROHouse);
if (PLDrivers::GetSystemServices()->GetOperatingSystem() == GpOperatingSystems::kWeb)
EnableMenuItem(exportMenu, iDownloadHouse);
}
else
{
DisableMenuItem(exportMenu, iExportGliderPROHouse);
if (PLDrivers::GetSystemServices()->GetOperatingSystem() == GpOperatingSystems::kWeb)
DisableMenuItem(exportMenu, iDownloadHouse);
}
}
//-------------------------------------------------------------- UpdateMenusHouseClosed
@@ -486,6 +495,9 @@ void DoExportMenu(short theItem)
case iExportGliderPROHouse:
ExportHouse();
break;
case iDownloadHouse:
DownloadHouse();
break;
};
}

View File

@@ -14,6 +14,34 @@ struct IGpMutex;
struct IGpThreadEvent;
struct IGpClipboardContents;
namespace GpOperatingSystems
{
enum GpOperatingSystem
{
kUnknown,
kWindows,
kAndroid,
kWeb,
kLinux,
kMacOS,
kIOS,
};
}
typedef GpOperatingSystems::GpOperatingSystem GpOperatingSystem_t;
namespace GpOperatingSystemFlavors
{
enum GpOperatingSystemFlavor
{
kGeneric,
};
}
typedef GpOperatingSystemFlavors::GpOperatingSystemFlavor GpOperatingSystemFlavor_t;
struct IGpSystemServices
{
public:
@@ -33,6 +61,8 @@ public:
virtual bool IsFullscreenOnStartup() const = 0;
virtual bool IsTextInputObstructive() const = 0;
virtual bool HasNativeFileManager() const = 0;
virtual GpOperatingSystem_t GetOperatingSystem() const = 0;
virtual GpOperatingSystemFlavor_t GetOperatingSystemFlavor() const = 0;
virtual unsigned int GetCPUCount() const = 0;
virtual void SetTextInputEnabled(bool isEnabled) = 0;
virtual bool IsTextInputEnabled() const = 0;