Skip to content

Commit

Permalink
Implements RawFileClass::Error and CCFileClass::Error to assist in fi…
Browse files Browse the repository at this point in the history
…le read/write issues.
  • Loading branch information
CCHyper committed Mar 28, 2022
1 parent 60c13de commit e92b5e8
Show file tree
Hide file tree
Showing 7 changed files with 197 additions and 0 deletions.
94 changes: 94 additions & 0 deletions src/extensions/ccfile/ccfileext_hooks.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
/*******************************************************************************
/* O P E N S O U R C E -- V I N I F E R A **
/*******************************************************************************
*
* @project Vinifera
*
* @file CCFILEEXT_HOOKS.CPP
*
* @author CCHyper
*
* @brief Contains the hooks for the extended CCFileClass.
*
* @license Vinifera is free software: you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation, either version
* 3 of the License, or (at your option) any later version.
*
* Vinifera is distributed in the hope that it will be
* useful, but WITHOUT ANY WARRANTY; without even the implied
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this program.
* If not, see <http://www.gnu.org/licenses/>.
*
******************************************************************************/
#include "ccfileext_hooks.h"
#include "ccfile.h"
#include "cd.h"
#include "fatal.h"
#include "debughandler.h"
#include "asserthandler.h"

#include "hooker.h"
#include "hooker_macros.h"


/**
* A fake class for implementing new member functions which allow
* access to the "this" pointer of the intended class.
*
* @note: This must not contain a constructor or destructor!
* @note: All functions must be prefixed with "_" to prevent accidental virtualization.
*/
class CCFileClassFake final : public CCFileClass
{
public:
void _Error(FileErrorType error, bool can_retry = false, const char *filename = nullptr);
};


/**
* Handles displaying a file error message.
*
* @author: 10/17/1994 JLB - Red Alert source code.
* CCHyper - Adjustments for Tiberian Sun, minor bug fix.
*/
void CCFileClassFake::_Error(FileErrorType error, bool can_retry, const char *filename)
{
/**
* File system is failled as local, no need to check if required cd is available.
*/
if (CD::IsFilesLocal) {
CDFileClass::Error(error, can_retry, filename);

} else {

/**
* If the file was not found, its possible we have the wrong disk inserted
* so prompt the user to insert the correct disk.
*/
if (!CD().Is_Available(CD::RequiredCD)) {

DEV_DEBUG_ERROR("File - Error, CD '%d' not found!", CD::RequiredCD);

/**
* If still not available, now let the low level file interface report the error.
*/
CDFileClass::Error(error, can_retry, filename);
}

}
}



/**
* Main function for patching the hooks.
*/
void CCFileClassExtension_Hooks()
{
Patch_Jump(0x00449820, &CCFileClassFake::_Error);
}
31 changes: 31 additions & 0 deletions src/extensions/ccfile/ccfileext_hooks.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/*******************************************************************************
/* O P E N S O U R C E -- V I N I F E R A **
/*******************************************************************************
*
* @project Vinifera
*
* @file CCFILEEXT_HOOKS.H
*
* @author CCHyper
*
* @brief Contains the hooks for the extended CCFileClass.
*
* @license Vinifera is free software: you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation, either version
* 3 of the License, or (at your option) any later version.
*
* Vinifera is distributed in the hope that it will be
* useful, but WITHOUT ANY WARRANTY; without even the implied
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this program.
* If not, see <http://www.gnu.org/licenses/>.
*
******************************************************************************/
#pragma once


void CCFileClassExtension_Hooks();
2 changes: 2 additions & 0 deletions src/extensions/ext_hooks.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@

#include "cciniext_hooks.h"
#include "rawfileext_hooks.h"
#include "ccfileext_hooks.h"

#include "fetchres_hooks.h"

Expand Down Expand Up @@ -217,6 +218,7 @@ void Extension_Hooks()

CCINIClassExtension_Hooks();
RawFileClassExtension_Hooks();
CCFileClassExtension_Hooks();

FetchRes_Hooks();

Expand Down
44 changes: 44 additions & 0 deletions src/extensions/rawfile/rawfileext_hooks.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
*
******************************************************************************/
#include "rawfileext_hooks.h"
#include "vinifera_globals.h"
#include "rawfile.h"
#include "fatal.h"
#include "debughandler.h"
Expand All @@ -46,6 +47,7 @@ class RawFileClassFake final : public RawFileClass
{
public:
long _Read(void *buffer, int length);
void _Error(FileErrorType error, bool can_retry = false, const char *filename = nullptr);
};


Expand Down Expand Up @@ -125,10 +127,52 @@ long RawFileClassFake::_Read(void *buffer, int length)
}


/**
* Handles displaying a file error message.
*
* @author: 10/17/1994 JLB - Red Alert source code.
* CCHyper - Adjustments for Tiberian Sun, minor bug fix.
*/
void RawFileClassFake::_Error(FileErrorType error, bool can_retry, const char *filename)
{
static char buffer[2048];

bool handled = false;

std::snprintf(buffer, sizeof(buffer),
"File - error:(%d) \"%s\" can_retry:%s filename:%s.\n",
error, File_Error_To_String(error),
can_retry ? "true" : "false",
filename != nullptr ? filename : Filename);

/**
* Output error to the debug system.
*/
if (Vinifera_PrintFileErrors) {
DEV_DEBUG_ERROR(buffer);
}

/**
* If flagged, force exit the game.
*/
if (!can_retry && Vinifera_FatalFileErrors) {
Emergency_Exit(EXIT_FAILURE);
}

/**
* If flagged, trigger a fatal assert to the user.
*/
if (Vinifera_AssertFileErrors) {
ASSERT_FATAL_PRINT(can_retry, buffer);
}
}


/**
* Main function for patching the hooks.
*/
void RawFileClassExtension_Hooks()
{
Patch_Jump(0x005BE560, &RawFileClassFake::_Read);
Patch_Jump(0x005BE300, &RawFileClassFake::_Error);
}
18 changes: 18 additions & 0 deletions src/vinifera/vinifera_functions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,24 @@ bool Vinifera_Parse_Command_Line(int argc, char *argv[])
continue;
}

/**
* Are file io errors fatal?
*/
if (stricmp(string, "-FILE_ERROR_FATAL") == 0) {
DEBUG_INFO(" - File read/write errors are fatal.\n");
Vinifera_FatalFileErrors = true;
continue;
}

/**
* Trigger an assertion on file io errors?
*/
if (stricmp(string, "-FILE_ERROR_ASSERT") == 0) {
DEBUG_INFO(" - Assertions on file read/write error.\n");
Vinifera_AssertFileErrors = true;
continue;
}

}

if (argc > 1) {
Expand Down
4 changes: 4 additions & 0 deletions src/vinifera/vinifera_globals.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,10 @@

bool Vinifera_DeveloperMode = false;

bool Vinifera_PrintFileErrors = true;
bool Vinifera_FatalFileErrors = false;
bool Vinifera_AssertFileErrors = false;

char Vinifera_DebugDirectory[PATH_MAX] = { "Debug" };
char Vinifera_ScreenshotDirectory[PATH_MAX] = { "Screenshots" };

Expand Down
4 changes: 4 additions & 0 deletions src/vinifera/vinifera_globals.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,10 @@ class EBoltClass;

extern bool Vinifera_DeveloperMode;

extern bool Vinifera_PrintFileErrors;
extern bool Vinifera_FatalFileErrors;
extern bool Vinifera_AssertFileErrors;

extern char Vinifera_DebugDirectory[PATH_MAX];
extern char Vinifera_ScreenshotDirectory[PATH_MAX];

Expand Down

0 comments on commit e92b5e8

Please sign in to comment.