Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion Core/Assertions.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,9 @@
#define NOOP ((void)0)
#define ASSUME(condition, failureMessage) NOOP

#endif
#endif

#define EXPAND_AS_STRING(x) #x
#define TOSTRING(x) EXPAND_AS_STRING(x)

#define FROM_HERE __FILE__ ":" TOSTRING(__LINE__)
1 change: 1 addition & 0 deletions Core/Platforms/Linux.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
// PLACEHOLDER
1 change: 1 addition & 0 deletions Core/Platforms/MacOS.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
// PLACEHOLDER
121 changes: 120 additions & 1 deletion Core/Platforms/Win32.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,123 @@
#include <psapi.h>
#include <shlwapi.h>
#include <strsafe.h>
#include <timeapi.h>
#include <timeapi.h>

typedef struct {
DWORD accessPermissions;
DWORD creationDisposition;
DWORD sharingMode;
DWORD extraFlags;
} platform_policy_t;

typedef struct {
const char* message;
const char* source;
uint32_t code;
} platform_error_t;

typedef struct {
platform_error_t errorDetails;
// NOTE: For portability, could store void* descriptor but then need to assert that sizeof(void*) == sizeof(HANDLE)
// NOTE: Since the platform runtime will already know OS-specific types and each platform should have its own, meh
HANDLE handle;

#ifdef RAGLITE_DEBUG_ANNOTATIONS
platform_policy_t creationPolicy;
#endif
} platform_handle_t;

GLOBAL platform_error_t PLATFORM_ERROR_NONE = {
.message = "OK",
.source = FROM_HERE,
.code = ERROR_SUCCESS,
};

INTERNAL inline void PlatformSetFileError(platform_handle_t& fileHandle, const char* message, const char* sourceLocation) {
// TODO: Get platform error message via FormatErrorString (needs a new API that pushes the error string to an arena)
fileHandle.errorDetails = {
.message = message,
.source = sourceLocation,
.code = GetLastError()
};
}

INTERNAL inline const char* PlatformGetFileError(platform_handle_t& fileHandle) {
// TODO: Should support arena parameter that the error string can be pushed onto (then move to utility layer?)
// NOTE: For now, just returns the hardcoded error message so that there is at least some information - if not ideal
return fileHandle.errorDetails.message; // Cannot concatenate without string building/arenas - fix this up later
}

INTERNAL inline bool PlatformNoFileErrors(platform_handle_t& fileHandle) {
// NOTE: It's unlikely this code would change, but relying on zeroized structs to always match it still seems wrong
return fileHandle.errorDetails.code == PLATFORM_ERROR_NONE.code;
}

INTERNAL inline bool PlatformIsValidFileHandle(platform_handle_t& fileHandle) {
return fileHandle.handle != INVALID_HANDLE_VALUE && fileHandle.handle != NULL;
}

INTERNAL inline platform_policy_t PlatformPolicyReadOnly() {
platform_policy_t policy = {
.accessPermissions = GENERIC_READ,
.creationDisposition = OPEN_EXISTING,
.sharingMode = FILE_SHARE_READ,
.extraFlags = FILE_ATTRIBUTE_NORMAL,
};
return policy;
}

// NOTE: These probably aren't quite right - will have to revisit later when writing/deleting files is actually needed
INTERNAL inline platform_policy_t PlatformPolicyReadWrite() {
platform_policy_t policy = {
.accessPermissions = GENERIC_READ | GENERIC_WRITE,
.creationDisposition = OPEN_ALWAYS,
.sharingMode = FILE_SHARE_READ | FILE_SHARE_DELETE,
.extraFlags = FILE_ATTRIBUTE_NORMAL,
};
return policy;
}

INTERNAL platform_handle_t PlatformOpenFileHandle(const char* fileSystemPath, platform_policy_t modePreset) {
platform_handle_t fileHandle = {};

DWORD accessPermissions = modePreset.accessPermissions;
DWORD creationDisposition = modePreset.creationDisposition;
DWORD sharingMode = modePreset.sharingMode;
DWORD attributeFlags = modePreset.extraFlags;
HANDLE templateFile = NULL;

#ifdef RAGLITE_DEBUG_ANNOTATIONS
fileHandle.creationPolicy = modePreset;
#endif

LPSECURITY_ATTRIBUTES securityAttributes = NULL; // Don't care (for now)
// TODO: Should use CreateFileW and convert from UTF8 to UTF16, but that requires scratch space and testing -> later
fileHandle.handle = CreateFileA(fileSystemPath, accessPermissions, sharingMode, securityAttributes, creationDisposition, attributeFlags, templateFile);

if(PlatformIsValidFileHandle(fileHandle)) fileHandle.errorDetails = PLATFORM_ERROR_NONE;
else PlatformSetFileError(fileHandle, "CreateFile returned INVALID_HANDLE_VALUE", FROM_HERE);

return fileHandle;
}

INTERNAL void PlatformCloseFileHandle(platform_handle_t& fileHandle) {
if(!PlatformIsValidFileHandle(fileHandle)) return;

HANDLE handle = fileHandle.handle;
CloseHandle(handle);
fileHandle.handle = INVALID_HANDLE_VALUE;
}

INTERNAL size_t PlatformGetFileSize(platform_handle_t& fileHandle) {
if(!PlatformIsValidFileHandle(fileHandle)) return 0;

LARGE_INTEGER fileSize;
BOOL success = GetFileSizeEx(fileHandle.handle, &fileSize);
if(!success) {
PlatformSetFileError(fileHandle, "GetFileSizeEx returned FALSE", FROM_HERE);
return 0;
}

return (size_t)fileSize.QuadPart;
}
11 changes: 10 additions & 1 deletion Core/RagLite2.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
#ifdef NDEBUG
#define RAGLITE_DEFAULT_APP DummyTest
#else
#define RAGLITE_DEBUG_ANNOTATIONS
#define RAGLITE_DEBUG_ASSERTIONS
#define RAGLITE_DEFAULT_APP PatternTest
#define RAGLITE_PREDICTABLE_MEMORY
Expand Down Expand Up @@ -82,4 +83,12 @@ typedef struct gamepad_controller_state {
typedef struct volatile_simulation_state {
int32 offsetX;
int32 offsetY;
} simulation_state_t;
} simulation_state_t;

#ifdef RAGLITE_PLATFORM_WINDOWS
#include "Platforms/Win32.hpp"
#elifdef RAGLITE_PLATFORM_MACOS
#include "Platforms/MacOS.hpp"
#elifdef RAGLITE_PLATFORM_LINUX
#include "Platforms/Linux.hpp"
#endif
29 changes: 18 additions & 11 deletions Tools/RagnarokTools.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,7 @@
#define GLOBAL static
#define INTERNAL static

// TODO: Use the exported types from the platform API (unfinished/WIP)
typedef void* platform_handle_t;
#include "../Core/RagLite2.hpp"

// TODO: Compute this automatically (requires a bit of annoying boilerplate, but it's not too difficult)
GLOBAL const char* THIS_EXECUTABLE = "RagnarokTools.exe";
Expand Down Expand Up @@ -133,15 +132,15 @@ typedef struct {
} opcode_list_t;

INTERNAL void PlaceholderNotYetImplemented(roff_request_t requestDetails, platform_handle_t inputFileHandle, platform_handle_t outputFileHandle) {
printf("[DISPATCH] Using platform-specific input file handle: 0x%p\n", inputFileHandle);
printf("[DISPATCH] Using platform-specific output file handle: 0x%p\n", outputFileHandle);
printf("[DISPATCH] Using platform-specific input file handle: 0x%p\n", &inputFileHandle);
printf("[DISPATCH] Using platform-specific output file handle: 0x%p\n", &outputFileHandle);

printf("[NYI] Alas... It is with great sorrow that I must inform you: This feature has not been implemented yet\n");
printf("[NYI] Some day, the missing functionality may indeed be available - but, clearly, today is not that day\n");
printf("[NYI] In due time, the patient shall see this great work come to fruition (or implement it yourself maybe)\n");

if(!inputFileHandle) fprintf(stderr, "[DISPATCH] Request aborted: Cannot read from an invalid OS file handle\n");
if(!outputFileHandle) fprintf(stderr, "[DISPATCH] Request aborted: Cannot write to an invalid OS file handle\n");
if(!PlatformNoFileErrors(inputFileHandle)) fprintf(stderr, "[DISPATCH] Request aborted: Cannot read from an invalid OS file handle\n");
if(!PlatformNoFileErrors(outputFileHandle)) fprintf(stderr, "[DISPATCH] Request aborted: Cannot write to an invalid OS file handle\n");
}

INTERNAL void DisplayFormatInfo(roff_request_t requestDetails, platform_handle_t inputFileHandle, platform_handle_t outputFileHandle) {
Expand All @@ -157,7 +156,7 @@ INTERNAL void DisplayFormatInfo(roff_request_t requestDetails, platform_handle_t
// TODO: It would probably be better to display (only) the supported operations for this format here

// TODO: Might be useful to print some file metadata here (size, hash, maybe even the header?)
printf("[NYI] A more useful file description for OS handle 0x%p should eventually appear here\n", inputFileHandle);
printf("[NYI] A more useful file description for OS handle 0x%p should eventually appear here\n", &inputFileHandle);
}

INTERNAL opcode_list_t GetSupportedFormatOperations(roff_format_t fileFormat) {
Expand Down Expand Up @@ -325,16 +324,24 @@ int main(size_t argCount, const char** arguments) {

// TODO: Preallocate a temporary memory arena for the format-specific decoders here

// TODO: Open platform handle to input file or stream
platform_handle_t inputFileHandle = NULL;
platform_handle_t inputFileHandle = {};
if(!requestDetails.inputSource) {
printf("[NYI] Reading from STDIN isn't currently supported, but should be very soon (... famous last words?)\n");
// TODO: Open platform handle to stdin
} else {
printf("[NYI] Reading files isn't currently supported, but should be very soon (... famous last words?)\n");
inputFileHandle = PlatformOpenFileHandle(requestDetails.inputSource, PlatformPolicyReadOnly());
if(!PlatformNoFileErrors(inputFileHandle)) {
fprintf(stderr, "Failed to open %s (platform reported error: %s)\n", requestDetails.inputSource, PlatformGetFileError(inputFileHandle));
fprintf(stderr, "Make sure the file exists in the working directory and is readable by this process\n");
return 1;
}
size_t fileSize = PlatformGetFileSize(inputFileHandle);
printf("[NYI] Reading file contents from %s (%zd bytes)\n", requestDetails.inputSource, fileSize);
PlatformCloseFileHandle(inputFileHandle);
}

// TODO: Open platform handle to output file or stream
platform_handle_t outputFileHandle = NULL;
platform_handle_t outputFileHandle = {};
if(!requestDetails.outputDestination) {
printf("[NYI] Writing to STDOUT isn't currently supported, but should be very soon (... famous last words?)\n");
} else {
Expand Down
Loading