File system refactor, bug fixes

This commit is contained in:
elasota
2021-03-07 04:24:13 -05:00
parent 6715bcb030
commit 3917e1a370
70 changed files with 2417 additions and 1242 deletions

View File

@@ -121,10 +121,10 @@ void ShiftWholeHouse (SInt16);
void DoHouseInfo (void); // --- HouseInfo.c
Boolean OpenHouse (void); // --- HouseIO.c
Boolean OpenHouse (Boolean load); // --- HouseIO.c
Boolean OpenSpecificHouse (const VFileSpec &);
Boolean SaveHouseAs (void);
Boolean ReadHouse (void);
Boolean ReadHouse (GpIOStream *houseStream);
Boolean WriteHouse (Boolean);
Boolean CloseHouse (void);
void OpenHouseResFork (void);

View File

@@ -50,7 +50,7 @@ void GetHighScoreName (short);
void UpdateBannerDialog (Dialog *);
int16_t BannerFilter(void *context, Dialog *dialog, const TimeTaggedVOSEvent *evt);
void GetHighScoreBanner (void);
Boolean OpenHighScoresFile (const VFileSpec &spec, GpIOStream *&outStream);
Boolean OpenHighScoresFile (const VFileSpec &spec, GpIOStream *&outStream, Boolean write);
Str31 highBanner;
@@ -686,23 +686,18 @@ void GetHighScoreBanner (void)
//-------------------------------------------------------------- OpenHighScoresFile
Boolean OpenHighScoresFile (const VFileSpec &scoreSpec, GpIOStream *&scoresStream)
Boolean OpenHighScoresFile (const VFileSpec &spec, GpIOStream *&outStream, Boolean write)
{
PLError_t theErr;
PortabilityLayer::FileManager *fm = PortabilityLayer::FileManager::GetInstance();
theErr = fm->OpenFileData(scoreSpec.m_dir, scoreSpec.m_name, PortabilityLayer::EFilePermission_Any, scoresStream);
PLError_t theErr = fm->OpenNonCompositeFile(spec.m_dir, spec.m_name, ".dat", write ? PortabilityLayer::EFilePermission_Write : PortabilityLayer::EFilePermission_Read, write ? GpFileCreationDispositions::kCreateOrOverwrite : GpFileCreationDispositions::kOpenExisting, outStream);
if (theErr == PLErrors::kFileNotFound)
{
theErr = fm->CreateFileAtCurrentTime(scoreSpec.m_dir, scoreSpec.m_name, 'ozm5', 'gliS');
if (!CheckFileError(theErr, PSTR("New High Scores File")))
return (false);
theErr = fm->OpenFileData(scoreSpec.m_dir, scoreSpec.m_name, PortabilityLayer::EFilePermission_Any, scoresStream);
if (!CheckFileError(theErr, PSTR("High Score")))
return (false);
outStream = nil;
return (true);
}
else if (!CheckFileError(theErr, PSTR("High Score")))
if (!CheckFileError(theErr, PSTR("High Score")))
return (false);
return (true);
@@ -721,18 +716,11 @@ Boolean WriteScoresToDisk (void)
GpIOStream *scoresStream = nil;
scoreSpec = MakeVFileSpec(PortabilityLayer::VirtualDirectories::kHighScores, thisHouseName);
if (!OpenHighScoresFile(scoreSpec, scoresStream))
if (!OpenHighScoresFile(scoreSpec, scoresStream, true))
{
SysBeep(1);
return (false);
}
if (!scoresStream->SeekStart(0))
{
CheckFileError(PLErrors::kIOError, PSTR("High Scores File"));
scoresStream->Close();
return(false);
}
byteCount = sizeof(scoresType);
theScores = &((*thisHouse)->highScores);
@@ -744,13 +732,6 @@ Boolean WriteScoresToDisk (void)
return(false);
}
if (!scoresStream->Truncate(byteCount))
{
CheckFileError(PLErrors::kIOError, PSTR("High Scores File"));
scoresStream->Close();
return(false);
}
scoresStream->Close();
return (true);
@@ -777,15 +758,22 @@ Boolean ReadScoresFromDisk (void)
short volRefNum;
char wasState;
GpIOStream *scoresStream = nil;
VFileSpec scoreSpec = MakeVFileSpec(PortabilityLayer::VirtualDirectories::kHighScores, thisHouseName);
if (!OpenHighScoresFile(scoreSpec, scoresStream))
if (!OpenHighScoresFile(scoreSpec, scoresStream, false))
{
SysBeep(1);
return (false);
}
if (!scoresStream)
return (false);
byteCount = scoresStream->Size();
if (byteCount != sizeof(scoresType))
{
scoresStream->Close();
return (false);
}
theScores = &((*thisHouse)->highScores);

View File

@@ -16,6 +16,7 @@
#include "FileManager.h"
#include "FontFamily.h"
#include "House.h"
#include "MacFileInfo.h"
#include "PLStandardColors.h"
#include "PLTimeTaggedVOSEvent.h"
#include "RectUtils.h"
@@ -66,6 +67,13 @@ static void FBUI_FreeFileDetails(void *fileDetails)
{
}
static bool FBUI_FilterFile(PortabilityLayer::VirtualDirectory_t dirID, const PLPasStr &filename)
{
PortabilityLayer::CompositeFile *cfile = PortabilityLayer::FileManager::GetInstance()->OpenCompositeFile(dirID, filename);
return PortabilityLayer::ResTypeIDCodec::Decode(cfile->GetProperties().m_fileType) == 'gliH';
}
static PortabilityLayer::FileBrowserUI_DetailsCallbackAPI GetHouseDetailsAPI()
{
PortabilityLayer::FileBrowserUI_DetailsCallbackAPI api;
@@ -74,6 +82,7 @@ static PortabilityLayer::FileBrowserUI_DetailsCallbackAPI GetHouseDetailsAPI()
api.m_drawFileDetailsCallback = FBUI_DrawFileDetails;
api.m_loadFileDetailsCallback = FBUI_LoadFileDetails;
api.m_freeFileDetailsCallback = FBUI_FreeFileDetails;
api.m_filterFileCallback = FBUI_FilterFile;
return api;
}
@@ -98,7 +107,7 @@ Boolean CreateNewHouse (void)
char savePath[sizeof(theSpec.m_name) + 1];
size_t savePathLength = 0;
if (!fm->PromptSaveFile(theSpec.m_dir, 'gliH', savePath, savePathLength, sizeof(theSpec.m_name), PSTR("My House"), PSTR("Create House"), GetHouseDetailsAPI()))
if (!fm->PromptSaveFile(theSpec.m_dir, ".gpf", savePath, savePathLength, sizeof(theSpec.m_name), PSTR("My House"), PSTR("Create House"), true, GetHouseDetailsAPI()))
return false;
assert(savePathLength < sizeof(theSpec.m_name) - 1);
@@ -108,7 +117,7 @@ Boolean CreateNewHouse (void)
if (fm->FileExists(theSpec.m_dir, theSpec.m_name))
{
if (!fm->DeleteFile(theSpec.m_dir, theSpec.m_name))
if (!fm->DeleteCompositeFile(theSpec.m_dir, theSpec.m_name))
{
CheckFileError(PLErrors::kAccessDenied, theSpec.m_name);
return (false);
@@ -133,7 +142,7 @@ Boolean CreateNewHouse (void)
AddExtraHouse(theSpec);
BuildHouseList();
InitCursor();
if (!OpenHouse())
if (!OpenHouse(false))
return (false);
WriteOutPrefs();

View File

@@ -28,20 +28,18 @@
#define kDiscardChanges 2
void LoopMovie (void);
void OpenHouseMovie (void);
void CloseHouseMovie (void);
Boolean IsFileReadOnly (const VFileSpec &);
AnimationPlayer theMovie;
Rect movieRect;
PortabilityLayer::IResourceArchive *houseResFork;
short wasHouseVersion;
GpIOStream *houseStream;
Boolean houseOpen, fileDirty;
Boolean changeLockStateOfHouse, saveHouseLocked, houseIsReadOnly;
Boolean hasMovie, tvInRoom;
PortabilityLayer::CompositeFile *houseCFile;
extern VFileSpec *theHousesSpecs;
@@ -59,9 +57,7 @@ void OpenHouseMovie (void)
{
#ifdef COMPILEQT
VFileSpec theSpec;
VFileInfo finderInfo;
Handle spaceSaver;
PLError_t theErr;
short movieRefNum;
Boolean dataRefWasChanged;
@@ -69,19 +65,20 @@ void OpenHouseMovie (void)
{
theSpec = theHousesSpecs[thisHouseIndex];
PasStringConcat(theSpec.m_name, PSTR(".mov"));
theErr = FSpGetFInfo(theSpec, finderInfo);
if (theErr != PLErrors::kNone)
return;
AnimationPackage *anim = AnimationPackage::Create();
if (!anim)
return;
if (!anim->Load(theSpec.m_dir, theSpec.m_name))
PLError_t theErr = anim->Load(theSpec.m_dir, theSpec.m_name);
if (theErr != PLErrors::kNone)
{
anim->Destroy();
YellowAlert(kYellowQTMovieNotLoaded, theErr);
if (theErr != PLErrors::kFileNotFound)
YellowAlert(kYellowQTMovieNotLoaded, theErr);
return;
}
@@ -116,7 +113,7 @@ void CloseHouseMovie (void)
//-------------------------------------------------------------- OpenHouse
// Opens a house (whatever current selection is). Returns true if all went well.
Boolean OpenHouse (void)
Boolean OpenHouse (Boolean read)
{
PLError_t theErr;
@@ -132,12 +129,21 @@ Boolean OpenHouse (void)
if (!StrCmp::EqualCaseInsensitive(theHousesSpecs[thisHouseIndex].name, "\pDemo House"))
return (false);
#endif
houseIsReadOnly = IsFileReadOnly(theHousesSpecs[thisHouseIndex]);
theErr = PortabilityLayer::FileManager::GetInstance()->OpenFileData(theHousesSpecs[thisHouseIndex].m_dir, theHousesSpecs[thisHouseIndex].m_name, PortabilityLayer::EFilePermission_Any, houseStream);
if (!CheckFileError(theErr, thisHouseName))
houseCFile = PortabilityLayer::FileManager::GetInstance()->OpenCompositeFile(theHousesSpecs[thisHouseIndex].m_dir, theHousesSpecs[thisHouseIndex].m_name);
if (!houseCFile)
return (false);
houseIsReadOnly = houseCFile->IsDataReadOnly();
GpIOStream *houseStream = nil;
theErr = houseCFile->OpenData(PortabilityLayer::EFilePermission_Any, GpFileCreationDispositions::kCreateOrOpen, houseStream);
if (!CheckFileError(theErr, thisHouseName))
{
houseCFile->Close();
houseCFile = nil;
return (false);
}
houseOpen = true;
OpenHouseResFork();
@@ -148,6 +154,16 @@ Boolean OpenHouse (void)
tvInRoom = false;
tvWithMovieNumber = -1;
OpenHouseMovie();
if (read)
{
Boolean readOK = ReadHouse(houseStream);
houseStream->Close();
return readOK;
}
houseStream->Close();
return (true);
}
@@ -173,9 +189,7 @@ Boolean OpenSpecificHouse (const VFileSpec &specs)
{
thisHouseIndex = i;
PasStringCopy(theHousesSpecs[thisHouseIndex].m_name, thisHouseName);
if (OpenHouse())
itOpened = ReadHouse();
else
if (!OpenHouse(true))
itOpened = false;
break;
}
@@ -527,7 +541,7 @@ bool ByteSwapHouse(housePtr house, size_t sizeInBytes, bool isSwappedAfter)
return true;
}
Boolean ReadHouse (void)
Boolean ReadHouse (GpIOStream *houseStream)
{
long byteCount;
PLError_t theErr;
@@ -653,19 +667,27 @@ Boolean WriteHouse (Boolean checkIt)
UInt32 timeStamp;
long byteCount;
PLError_t theErr;
if ((housesFound < 1) || (thisHouseIndex == -1))
return(false);
if (!houseOpen)
{
YellowAlert(kYellowUnaccounted, 4);
return (false);
}
if (!houseStream->SeekStart(0))
if (!houseCFile)
{
CheckFileError(PLErrors::kIOError, thisHouseName);
return(false);
YellowAlert(kYellowUnaccounted, 4);
return (false);
}
GpIOStream *houseStream = nil;
theErr = houseCFile->OpenData(PortabilityLayer::EFilePermission_Write, GpFileCreationDispositions::kCreateOrOpen, houseStream);
if (theErr != PLErrors::kNone)
return (false);
CopyThisRoomToRoom();
if (checkIt)
@@ -699,6 +721,7 @@ Boolean WriteHouse (Boolean checkIt)
{
CheckFileError(PLErrors::kIOError, thisHouseName);
ByteSwapHouse(*thisHouse, static_cast<size_t>(byteCount), false);
houseStream->Close();
return(false);
}
@@ -706,16 +729,13 @@ Boolean WriteHouse (Boolean checkIt)
{
CheckFileError(PLErrors::kIOError, thisHouseName);
ByteSwapHouse(*thisHouse, static_cast<size_t>(byteCount), false);
houseStream->Close();
return(false);
}
ByteSwapHouse(*thisHouse, static_cast<size_t>(byteCount), false);
if (!houseStream->Truncate(byteCount))
{
CheckFileError(PLErrors::kIOError, thisHouseName);
return(false);
}
houseStream->Close();
if (changeLockStateOfHouse)
{
@@ -749,7 +769,11 @@ Boolean CloseHouse (void)
CloseHouseResFork();
CloseHouseMovie();
houseStream->Close();
if (houseCFile)
{
houseCFile->Close();
houseCFile = nil;
}
houseOpen = false;
@@ -764,7 +788,7 @@ void OpenHouseResFork (void)
PortabilityLayer::ResourceManager *rm = PortabilityLayer::ResourceManager::GetInstance();
if (houseResFork == nullptr)
{
houseResFork = rm->LoadResFile(theHousesSpecs[thisHouseIndex].m_dir, theHousesSpecs[thisHouseIndex].m_name);
houseResFork = rm->LoadResFile(houseCFile);
if (!houseResFork)
YellowAlert(kYellowFailedResOpen, PLErrors::kResourceError);
}
@@ -817,8 +841,7 @@ Boolean QuerySaveChanges (void)
if (!quitting)
{
whoCares = CloseHouse();
if (OpenHouse())
whoCares = ReadHouse();
OpenHouse(true);
}
UpdateMenus(false);
return (true);
@@ -850,17 +873,6 @@ void YellowAlert (short whichAlert, short identifier)
whoCares = PortabilityLayer::DialogManager::GetInstance()->DisplayAlert(kYellowAlert, &substitutions);
}
//-------------------------------------------------------------- IsFileReadOnly
Boolean IsFileReadOnly (const VFileSpec &spec)
{
// Kind of annoying, but itch.io doesn't preserve read-only flags and there doesn't seem to be any way around that.
if (spec.m_dir == PortabilityLayer::VirtualDirectories::kApplicationData || spec.m_dir == PortabilityLayer::VirtualDirectories::kGameData)
return true;
return PortabilityLayer::FileManager::GetInstance()->FileLocked(spec.m_dir, spec.m_name);
}
//-------------------------------------------------------------- LoadHousePicture
THandle<void> LoadHouseResource(const PortabilityLayer::ResTypeID &resTypeID, int16_t resID)

View File

@@ -8,6 +8,7 @@
#include "WindowDef.h"
#include "BitmapImage.h"
#include "FileManager.h"
#include "Externs.h"
#include "Environ.h"
#include "FontFamily.h"
@@ -70,7 +71,7 @@ extern Str15 leftName, rightName, batteryName, bandName;
extern Str15 highName;
//extern long encryptedNumber;
extern short maxFiles, numNeighbors, willMaxFiles;
extern GpIOStream *houseStream;
extern PortabilityLayer::CompositeFile *houseCFile;
extern short isEditH, isEditV, isMapH, isMapV;
extern short isToolsH, isToolsV, isCoordH, isCoordV;
extern short isLinkH, isLinkV, toolMode, mapLeftRoom, mapTopRoom;
@@ -225,12 +226,12 @@ void ReadInPrefs (void)
isEditV = 41;
isMapH = 3;
// isMapV = qd.screenBits.bounds.bottom - 100;
isMapV = 100;
isMapV = 385;
mapRoomsWide = 15;
mapRoomsHigh = 4;
// isToolsH = qd.screenBits.bounds.right - 120;
isToolsH = 100;
isToolsV = 35;
isToolsH = 525;
isToolsV = 41;
isLinkH = 50;
isLinkV = 80;
// isCoordH = qd.screenBits.bounds.right - 55;
@@ -361,8 +362,6 @@ void WriteOutPrefs (void)
SysBeep(1);
modulePrefs.Dispose();
UnivSetSoundVolume(wasVolume, thisMac.hasSM3);
}
void StepLoadScreenRing()
@@ -1167,8 +1166,7 @@ int gpAppMain()
InitSound(); SpinCursor(2);
InitMusic(); SpinCursor(2);
BuildHouseList();
if (OpenHouse())
whoCares = ReadHouse();
OpenHouse(true);
PlayPrioritySound(kBirdSound, kBirdPriority);
DelayTicks(6);
@@ -1201,7 +1199,8 @@ int gpAppMain()
if (!CloseHouse())
{
CloseHouseResFork();
houseStream->Close();
if (houseCFile)
houseCFile->Close();
houseOpen = false;
}
}

View File

@@ -426,6 +426,7 @@ void DoOptionsMenu (short theItem)
}
OpenMainWindow();
RedrawSplashScreen();
incrementModeTime = TickCount() + kIdleSplashTicks;
}
else if (theMode == kSplashMode) // switching to edit mode

View File

@@ -278,12 +278,11 @@ void DoDemoGame (void)
whoCares = CloseHouse();
thisHouseIndex = demoHouseIndex;
PasStringCopy(theHousesSpecs[thisHouseIndex].m_name, thisHouseName);
if (OpenHouse())
if (OpenHouse(true))
{
if (thisMac.isTouchscreen)
DismissMainMenuUI();
whoCares = ReadHouse();
demoGoing = true;
NewGame(kNewGameMode);
@@ -293,8 +292,7 @@ void DoDemoGame (void)
whoCares = CloseHouse();
thisHouseIndex = wasHouseIndex;
PasStringCopy(theHousesSpecs[thisHouseIndex].m_name, thisHouseName);
if (OpenHouse())
whoCares = ReadHouse();
OpenHouse(true);
incrementModeTime = TickCount() + kIdleSplashTicks;
RedrawSplashScreen();
}

View File

@@ -22,7 +22,7 @@
#define kPrefCreatorType 'ozm5'
#define kPrefFileType 'gliP'
#define kPrefFileName PSTR("Glider Prefs v2")
#define kPrefFileName PSTR("Glider Prefs")
#define kDefaultPrefFName PSTR("Preferences")
#define kPrefsStringsID 160
#define kNewPrefsAlertID 160
@@ -67,16 +67,8 @@ Boolean WritePrefs (const prefsInfo *thePrefs, short versionNow, THandle<moduleP
PasStringCopy(kPrefFileName, fileName);
VFileSpec theSpecs = MakeVFileSpec(PortabilityLayer::VirtualDirectories::kPrefs, fileName);
if (!fm->FileExists(PortabilityLayer::VirtualDirectories::kPrefs, fileName))
{
theErr = fm->CreateFileAtCurrentTime(theSpecs.m_dir, theSpecs.m_name, kPrefCreatorType, kPrefFileType);
if (theErr != PLErrors::kNone)
{
CheckFileError(theErr, PSTR("Preferences"));
return(false);
}
}
theErr = fm->OpenFileData(theSpecs.m_dir, theSpecs.m_name, PortabilityLayer::EFilePermission_Write, fileStream);
theErr = fm->OpenNonCompositeFile(theSpecs.m_dir, theSpecs.m_name, ".dat", PortabilityLayer::EFilePermission_Write, GpFileCreationDispositions::kCreateOrOverwrite, fileStream);
if (theErr != PLErrors::kNone)
{
CheckFileError(theErr, PSTR("Preferences"));
@@ -201,10 +193,10 @@ PLError_t ReadPrefs (prefsInfo *thePrefs, short versionNeed, Boolean *isOldVersi
theSpecs = MakeVFileSpec(PortabilityLayer::VirtualDirectory_t::kPrefs, fileName);
if (!PortabilityLayer::FileManager::GetInstance()->FileExists(theSpecs.m_dir, theSpecs.m_name))
return PLErrors::kFileNotFound;
theErr = fm->OpenNonCompositeFile(theSpecs.m_dir, theSpecs.m_name, ".dat", PortabilityLayer::EFilePermission_Read, GpFileCreationDispositions::kOpenExisting, fileStream);
if (theErr == PLErrors::kFileNotFound)
return theErr;
theErr = fm->OpenFileData(theSpecs.m_dir, theSpecs.m_name, PortabilityLayer::EFilePermission_Read, fileStream);
if (theErr != PLErrors::kNone)
{
CheckFileError(theErr, PSTR("Preferences"));
@@ -326,7 +318,7 @@ Boolean DeletePrefs ()
theSpecs = MakeVFileSpec(PortabilityLayer::VirtualDirectories::kPrefs, fileName);
return PortabilityLayer::FileManager::GetInstance()->DeleteFile(theSpecs.m_dir, theSpecs.m_name);
return PortabilityLayer::FileManager::GetInstance()->DeleteNonCompositeFile(theSpecs.m_dir, theSpecs.m_name, ".dat");
}
//-------------------------------------------------------------- RunFunctionOnAllPrefsHandlers

View File

@@ -73,7 +73,7 @@ static void FBUI_DrawFileDetails(DrawSurface *surface, const Point &basePoint, c
static void *FBUI_LoadFileDetails(PortabilityLayer::VirtualDirectory_t dirID, const PLPasStr &filename)
{
GpIOStream *stream = nullptr;
if (PortabilityLayer::FileManager::GetInstance()->OpenFileData(dirID, filename, PortabilityLayer::EFilePermission_Read, stream) != PLErrors::kNone)
if (PortabilityLayer::FileManager::GetInstance()->OpenNonCompositeFile(dirID, filename, ".sav", PortabilityLayer::EFilePermission_Read, GpFileCreationDispositions::kOpenExisting, stream) != PLErrors::kNone)
return nullptr;
const size_t kPrefixSize = sizeof(game2Type) - sizeof(savedRoom);
@@ -102,6 +102,11 @@ static void FBUI_FreeFileDetails(void *fileDetails)
PortabilityLayer::MemoryManager::GetInstance()->Release(fileDetails);
}
static bool FBUI_FilterFile(PortabilityLayer::VirtualDirectory_t dirID, const PLPasStr &filename)
{
return true;
}
static PortabilityLayer::FileBrowserUI_DetailsCallbackAPI GetSavedGameDetailsAPI()
{
PortabilityLayer::FileBrowserUI_DetailsCallbackAPI api;
@@ -110,6 +115,7 @@ static PortabilityLayer::FileBrowserUI_DetailsCallbackAPI GetSavedGameDetailsAPI
api.m_drawFileDetailsCallback = FBUI_DrawFileDetails;
api.m_loadFileDetailsCallback = FBUI_LoadFileDetails;
api.m_freeFileDetailsCallback = FBUI_FreeFileDetails;
api.m_filterFileCallback = FBUI_FilterFile;
return api;
}
@@ -163,7 +169,7 @@ Boolean SaveGame2 (void)
char savePath[sizeof(spec.m_name) + 1];
size_t savePathLength = 0;
if (!fm->PromptSaveFile(spec.m_dir, 'gliG', savePath, savePathLength, sizeof(spec.m_name), PLPasStr(gameNameStr), PSTR("Save Game"), GetSavedGameDetailsAPI()))
if (!fm->PromptSaveFile(spec.m_dir, ".sav", savePath, savePathLength, sizeof(spec.m_name), PLPasStr(gameNameStr), PSTR("Save Game"), false, GetSavedGameDetailsAPI()))
{
mm->Release(savedGame);
return false;
@@ -176,7 +182,7 @@ Boolean SaveGame2 (void)
if (fm->FileExists(spec.m_dir, PLPasStr(spec.m_name)))
{
if (!fm->DeleteFile(spec.m_dir, spec.m_name))
if (!fm->DeleteNonCompositeFile(spec.m_dir, spec.m_name, ".dat"))
{
CheckFileError(PLErrors::kAccessDenied, PSTR("Saved Game"));
return false;
@@ -216,20 +222,15 @@ Boolean SaveGame2 (void)
destRoom->objects[i] = srcRoom->objects[i];
}
PLError_t theErr = fm->CreateFileAtCurrentTime(spec.m_dir, spec.m_name, 'ozm5', 'gliG');
PLError_t theErr = fm->OpenNonCompositeFile(spec.m_dir, spec.m_name, ".sav", PortabilityLayer::EFilePermission_Write, GpFileCreationDispositions::kCreateOrOverwrite, gameStream);
if (CheckFileError(theErr, PSTR("Saved Game")))
{
theErr = fm->OpenFileData(spec.m_dir, spec.m_name, PortabilityLayer::EFilePermission_Write, gameStream);
if (CheckFileError(theErr, PSTR("Saved Game")))
if (gameStream->Write(savedGame, byteCount) != byteCount)
{
if (gameStream->Write(savedGame, byteCount) != byteCount)
{
CheckFileError(PLErrors::kIOError, PSTR("Saved Game"));
}
gameStream->Close();
CheckFileError(PLErrors::kIOError, PSTR("Saved Game"));
}
gameStream->Close();
}
mm->Release(savedGame);
@@ -274,7 +275,7 @@ Boolean OpenSavedGame (void)
char savePath[sizeof(spec.m_name) + 1];
size_t savePathLength = 0;
if (!fm->PromptOpenFile(spec.m_dir, 'gliG', savePath, savePathLength, sizeof(spec.m_name), PSTR("Open Saved Game"), GetSavedGameDetailsAPI()))
if (!fm->PromptOpenFile(spec.m_dir, ".sav", savePath, savePathLength, sizeof(spec.m_name), PSTR("Open Saved Game"), true, GetSavedGameDetailsAPI()))
return false;
assert(savePathLength < sizeof(spec.m_name) - 1);
@@ -282,15 +283,8 @@ Boolean OpenSavedGame (void)
spec.m_name[0] = static_cast<uint8_t>(savePathLength);
memcpy(spec.m_name + 1, savePath, savePathLength);
PortabilityLayer::MacFileProperties props;
if (!fm->ReadFileProperties(spec.m_dir, spec.m_name, props))
return false;
if (memcmp(props.m_fileType, "gliG", 4))
return false;
GpIOStream *gameStream = nullptr;
PLError_t theErr = fm->OpenFileData(spec.m_dir, spec.m_name, PortabilityLayer::EFilePermission_Read, gameStream);
PLError_t theErr = fm->OpenNonCompositeFile(spec.m_dir, spec.m_name, ".sav", PortabilityLayer::EFilePermission_Read, GpFileCreationDispositions::kOpenExisting, gameStream);
if (!CheckFileError(theErr, PSTR("Saved Game")))
return(false);

View File

@@ -101,18 +101,26 @@ void UpdateLoadDialog (Dialog *theDialog)
if (SectRect(&dialogRect, &tempRect, &dummyRect))
{
PortabilityLayer::IResourceArchive *resFile = PortabilityLayer::ResourceManager::GetInstance()->LoadResFile(theHousesSpecs[i].m_dir, theHousesSpecs[i].m_name);
if (resFile != nullptr)
PortabilityLayer::CompositeFile *cfile = PortabilityLayer::FileManager::GetInstance()->OpenCompositeFile(theHousesSpecs[i].m_dir, theHousesSpecs[i].m_name);
bool haveHouseIcon = false;
GpIOStream *resStream = nil;
if (cfile)
{
if (!LargeIconPlot(surface, resFile, -16455, tempRect))
PortabilityLayer::IResourceArchive *resFile = PortabilityLayer::ResourceManager::GetInstance()->LoadResFile(cfile);
if (resFile != nullptr)
{
LoadDialogPICT(theDialog, kLoadIconFirstItem + i - housePage,
kDefaultHousePict8);
if (LargeIconPlot(surface, resFile, -16455, tempRect))
haveHouseIcon = true;
resFile->Destroy();
}
resFile->Destroy();
cfile->Close();
}
else
if (!haveHouseIcon)
LoadDialogPICT(theDialog, kLoadIconFirstItem + i - housePage,
kDefaultHousePict8);
}
@@ -411,11 +419,8 @@ void DoLoadHouse (void)
whoCares = CloseHouse();
PasStringCopy(theHousesSpecs[thisHouseIndex].m_name,
thisHouseName);
if (OpenHouse())
{
whoCares = ReadHouse();
if (OpenHouse(true))
houseNameDirty = true;
}
}
leaving = true;
}
@@ -452,11 +457,8 @@ void DoLoadHouse (void)
whoCares = CloseHouse();
PasStringCopy(theHousesSpecs[thisHouseIndex].m_name,
thisHouseName);
if (OpenHouse())
{
whoCares = ReadHouse();
if (OpenHouse(true))
houseNameDirty = true;
}
}
leaving = true;
}
@@ -489,11 +491,8 @@ void DoLoadHouse (void)
whoCares = CloseHouse();
PasStringCopy(theHousesSpecs[thisHouseIndex].m_name,
thisHouseName);
if (OpenHouse())
{
whoCares = ReadHouse();
if (OpenHouse(true))
houseNameDirty = true;
}
}
leaving = true;
}

View File

@@ -96,41 +96,6 @@ SortableEntry SortableEntry::Create(const char *zipLocation, PortabilityLayer::V
return entry;
}
static void ConvertToMSDOSTimestamp(const PortabilityLayer::CombinedTimestamp &ts, uint16_t &msdosDate, uint16_t &msdosTime)
{
int32_t yearsSince1980 = ts.GetLocalYear() - 1980;
uint8_t month = ts.m_localMonth;
uint8_t day = ts.m_localDay;
uint8_t hour = ts.m_localHour;
uint8_t minute = ts.m_localMinute;
uint8_t second = ts.m_localSecond;
if (yearsSince1980 < 0)
{
// Time machine
yearsSince1980 = 0;
second = 0;
minute = 0;
hour = 0;
day = 1;
month = 1;
}
else if (yearsSince1980 > 127)
{
// I was promised flying cars, but it's 2107 and you're still flying paper airplanes...
yearsSince1980 = 127;
second = 59;
minute = 59;
hour = 23;
day = 31;
month = 12;
}
msdosTime = (second / 2) | (minute << 5) | (hour << 11);
msdosDate = day | (month << 5) | (yearsSince1980 << 9);
}
static void InitSourceExportWindow(SourceExportState *state)
{
static const int kLoadScreenHeight = 32;
@@ -403,7 +368,7 @@ static bool RepackDirectory(SourceExportState &state, GpIOStream *outStream, std
uint16_t dosDate = 0;
uint16_t dosTime = 0;
ConvertToMSDOSTimestamp(state.m_ts, dosDate, dosTime);
state.m_ts.GetAsMSDOSTimestamp(dosDate, dosTime);
IGpDirectoryCursor *dirCursor = PLDrivers::GetFileSystem()->ScanDirectory(virtualDir);
if (!dirCursor)
@@ -610,7 +575,7 @@ static bool AddZipDirectory(GpIOStream *stream, std::vector<PortabilityLayer::Zi
uint16_t dosDate = 0;
uint16_t dosTime = 0;
ConvertToMSDOSTimestamp(ts, dosDate, dosTime);
ts.GetAsMSDOSTimestamp(dosDate, dosTime);
GpUFilePos_t localHeaderPos = stream->Tell();