Skip to content

Commit

Permalink
Merge branch 'feature/xdg-dirs'
Browse files Browse the repository at this point in the history
Fix #53
  • Loading branch information
carstene1ns committed Oct 26, 2023
2 parents 897fa0b + a4dd229 commit c5cbd33
Show file tree
Hide file tree
Showing 37 changed files with 463 additions and 163 deletions.
4 changes: 3 additions & 1 deletion BUILDING.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,10 @@ http://www.alister.eu/jazz/oj/build.php

## additional build options

- `DATAPATH` - use a fixed path for data files
- `DATAPATH` - add a fixed path for game data files
- `SCALE` - enable scaling of the video output (i.e. Scale2X...)
- `PORTABLE` - Do not use external directories for configuration saving, etc.
(This only affects Unix platforms, Windows version is always portable)

Some ports have their own options, see (Platforms)[PLATFORMS.md] for details.

Expand Down
28 changes: 26 additions & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -113,10 +113,24 @@ add_executable(OpenJazz
src/jj2/level/jj2levelplayerframe.cpp)
target_include_directories(OpenJazz PUBLIC src)

# portable mode

cmake_dependent_option(PORTABLE "Do not write to external directories, etc." OFF
"NOT OJ_DEFAULT_PORTABLE" ON)
if(PORTABLE)
set(PORTABLE_STATUS "Enabled")
target_compile_definitions(OpenJazz PRIVATE PORTABLE)
else()
set(PORTABLE_STATUS "Disabled")
endif()
if((PORTABLE AND OJ_DEFAULT_PORTABLE) OR (NOT PORTABLE AND NOT OJ_DEFAULT_PORTABLE))
set(PORTABLE_STATUS "${PORTABLE_STATUS} (Default)")
endif()

# path to game data

set(DATAPATH "" CACHE PATH "Fixed path where game data is searched first")
if(${DATAPATH})
set(DATAPATH "" CACHE PATH "Fixed path where game data is available")
if(DATAPATH)
target_compile_definitions(OpenJazz PRIVATE DATAPATH="${DATAPATH}")
endif()

Expand Down Expand Up @@ -192,6 +206,9 @@ if(WIN32)
# add icon
target_sources(OpenJazz PRIVATE res/windows/OpenJazz.rc)
elseif(RISCOS)
target_sources(OpenJazz PRIVATE
src/platforms/riscos.cpp
src/platforms/riscos.h)
target_link_options(OpenJazz PRIVATE "-static")
elf2aif(OpenJazz)
elseif(3DS)
Expand Down Expand Up @@ -236,6 +253,9 @@ elseif(HAIKU)
src/platforms/haiku.cpp
src/platforms/haiku.h)
elseif(UNIX)
target_sources(OpenJazz PRIVATE
src/platforms/xdg.cpp
src/platforms/xdg.h)
target_link_libraries(OpenJazz -lm)
endif()

Expand Down Expand Up @@ -340,7 +360,11 @@ if(ROMFS)
endif()
message(STATUS "Network: ${NETWORK_STATUS}")
message(STATUS "Scaling: ${SCALE_STATUS}")
if(DATAPATH)
message(STATUS "Additional/System Game Data Path: \"${DATAPATH}\"")
endif()
message(STATUS "Manual page: ${MANUAL_STATUS}")
message(STATUS "Portable Engine: ${PORTABLE_STATUS}")
message(STATUS "")
message(STATUS "In case something goes wrong, report bugs to https://github.com/AlisterT/openjazz/issues")
message(STATUS "")
3 changes: 2 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ include openjazz.mk
# Sane defaults
CXX ?= g++
CXXFLAGS ?= -g -Wall -O2
CPPFLAGS = -Isrc -DSCALE -Iext/scale2x -Iext/psmplug -Iext/miniz -Iext/argparse
DEFINES = -DSCALE -DPORTABLE
CPPFLAGS = $(DEFINES) -Isrc -Iext/scale2x -Iext/psmplug -Iext/miniz -Iext/argparse

# Network support
CXXFLAGS += -DUSE_SOCKETS
Expand Down
6 changes: 6 additions & 0 deletions builds/cmake/Platform-Helpers.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ set(PLATFORM_LIST "")
set(OJ_ALLOW_SCALE ON)
set(OJ_LIBS_NET)
set(OJ_LIBS_HOST)
set(OJ_DEFAULT_PORTABLE ON)

option(PANDORA "Build for Pandora" OFF) # arm-none-linux-gnueabi
option(CAANOO "Build for GP2X Canoo" OFF) # arm-gph-linux-gnueabi
Expand Down Expand Up @@ -113,6 +114,11 @@ endif()
if(${OJ_HOST} STREQUAL "Unknown")
set(OJ_HOST ${CMAKE_SYSTEM_NAME})
set(OJ_ALLOW_NEW_SDL TRUE)

if(UNIX)
# usually we do a system-wide installation
set(OJ_DEFAULT_PORTABLE OFF)
endif()
endif()

# choose SDL library for Linux/Windows/Mac/etc., but not homebrew platforms
Expand Down
2 changes: 1 addition & 1 deletion src/game/clientgame.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -367,7 +367,7 @@ int ClientGame::step (unsigned int ticks) {

try {

file = new File(levelFile, true);
file = new File(levelFile, PATH_TYPE_TEMP, true);

} catch (int e) {

Expand Down
2 changes: 1 addition & 1 deletion src/game/servergame.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ int ServerGame::setLevel (char* fileName) {

try {

file = new File(fileName, false);
file = new File(fileName, PATH_TYPE_GAME);

} catch (int e) {

Expand Down
100 changes: 93 additions & 7 deletions src/io/file.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
#include "io/log.h"

#include <string.h>
#include <unistd.h>
#include <miniz.h>

#if !(defined(_WIN32) || defined(WII) || defined(PSP) || defined(_3DS))
Expand All @@ -42,17 +43,26 @@
* Try opening a file from the available paths.
*
* @param name File name
* @param pathType Kind of directory
* @param write Whether or not the file can be written to
*/
File::File (const char* name, bool write) {
File::File (const char* name, int pathType, bool write) {

Path* path;

path = firstPath;
Path* path = gamePaths.paths;

while (path) {

if (open(path->path, name, write)) return;
// skip other paths
if (pathType != PATH_TYPE_ANY && (path->pathType & pathType) != pathType) {
path = path->next;
continue;
}

// only allow certain write paths
if (!write || (pathType & (PATH_TYPE_CONFIG|PATH_TYPE_TEMP)) > 0) {
if (open(path->path, name, write)) return;
} else LOG_FATAL("Not allowed to write to %s", name);

path = path->next;

}
Expand Down Expand Up @@ -615,18 +625,94 @@ void File::loadPalette (SDL_Color* palette, bool rle) {
}


PathMgr::PathMgr():
paths(NULL), has_config(false), has_temp(false) {

};

PathMgr::~PathMgr() {
delete paths;
};

bool PathMgr::add(char* newPath, int newPathType) {

// Check for CWD
if(!strlen(newPath)) {
delete[] newPath;

char cwd[1024];
if (getcwd(cwd, sizeof(cwd)) != NULL) {
newPath = createString(cwd);
} else {
LOG_WARN("Could not get current working directory!");
return false;
}
}

// Append a directory separator if necessary
if (newPath[strlen(newPath) - 1] != OJ_DIR_SEP) {
char* tmp = createString(newPath, OJ_DIR_SEP_STR);
delete[] newPath;
newPath = tmp;
}

// all paths need to be readable
if (access(newPath, R_OK) != 0) {
LOG_TRACE("Path '%s' is not readable, ignoring!", newPath);
delete[] newPath;
return false;
}

// ignore, if already present
if(has_config) newPathType &= ~PATH_TYPE_CONFIG;
if(has_temp) newPathType &= ~PATH_TYPE_TEMP;

// config and temp dir need to be writeable
if ((newPathType & (PATH_TYPE_CONFIG|PATH_TYPE_TEMP)) > 0) {
if (access(newPath, W_OK) != 0) {
LOG_WARN("Path '%s' is not writeable, disabling!", newPath);

newPathType &= ~PATH_TYPE_CONFIG;
newPathType &= ~PATH_TYPE_TEMP;
}
}

if(newPathType == PATH_TYPE_INVALID) {
delete[] newPath;
return false;
}

// we only need one directory for these
if (newPathType & PATH_TYPE_CONFIG) has_config = true;
if (newPathType & PATH_TYPE_TEMP) has_temp = true;

// Finally add
paths = new Path(paths, newPath, newPathType);

return true;
}


/**
* Create a new directory path object.
*
* @param newNext Next path
* @param newPath The new path
*/
Path::Path (Path* newNext, char* newPath) {
Path::Path (Path* newNext, char* newPath, int newPathType) {

char pathInfo[10] = {};
if(newPathType & PATH_TYPE_SYSTEM) strcat(pathInfo, "S");
if(newPathType & PATH_TYPE_CONFIG) strcat(pathInfo, "C");
if(newPathType & PATH_TYPE_GAME) strcat(pathInfo, "G");
if(newPathType & PATH_TYPE_TEMP) strcat(pathInfo, "T");
if(newPathType & PATH_TYPE_ANY) strcat(pathInfo, "A");

LOG_TRACE("Adding '%s' to the path list", newPath);
LOG_DEBUG("Adding '%s' to the path list [%s]", newPath, pathInfo);

next = newNext;
path = newPath;
pathType = newPathType;

}

Expand Down
48 changes: 43 additions & 5 deletions src/io/file.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ class File {
bool open (const char* path, const char* name, bool write);

public:
File (const char* name, bool write);
File (const char* name, int pathType, bool write = false);
~File ();

int getSize ();
Expand All @@ -66,21 +66,59 @@ class File {
};

/// Directory path

enum path_type {
PATH_TYPE_INVALID = 0, ///< Invalid directory, do not use
PATH_TYPE_SYSTEM = 1 << 0, ///< Read-only system directory
PATH_TYPE_CONFIG = 1 << 1, ///< User writable configuration directory
PATH_TYPE_GAME = 1 << 2, ///< Directory containing game data
PATH_TYPE_TEMP = 1 << 3, ///< User writable temporary directory
PATH_TYPE_ANY = 1 << 4 ///< Special case: any type
};

class Path {

public:
Path* next; ///< Next path to check
char* path; ///< Path
Path* next; ///< Next path to check
char* path; ///< Path
int pathType; ///< One or more of path_type enum

Path (Path* newNext, char* newPath);
Path (Path* newNext, char* newPath, int newPathType);
~Path ();

};


class PathMgr {

public:
PathMgr();
~PathMgr();

bool add(char* newPath, int newPathType = PATH_TYPE_ANY);

Path* paths;

bool has_config;
bool has_temp;

};


// Directory Seperator

#ifdef _WIN32
#define OJ_DIR_SEP '\\'
#define OJ_DIR_SEP_STR "\\"
#else
#define OJ_DIR_SEP '/'
#define OJ_DIR_SEP_STR "/"
#endif


// Variable

EXTERN Path* firstPath; ///< Paths to files
EXTERN PathMgr gamePaths; ///< Paths to files

#endif

4 changes: 2 additions & 2 deletions src/io/gfx/font.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ Font::Font (const char* fileName) {

try {

file = new File(fileName, false);
file = new File(fileName, PATH_TYPE_GAME);

} catch (int e) {

Expand Down Expand Up @@ -229,7 +229,7 @@ Font::Font (bool bonus) {

try {

file = new File(bonus? "BONUS.000": "FONTS.000", false);
file = new File(bonus? "BONUS.000": "FONTS.000", PATH_TYPE_GAME);

} catch (int e) {

Expand Down
4 changes: 2 additions & 2 deletions src/io/sound.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -208,7 +208,7 @@ void playMusic (const char * fileName, bool restart) {

try {

file = new File(fileName, false);
file = new File(fileName, PATH_TYPE_GAME);

} catch (int e) {

Expand Down Expand Up @@ -396,7 +396,7 @@ int loadSounds (const char *fileName) {

try {

file = new File(fileName, false);
file = new File(fileName, PATH_TYPE_GAME);

} catch (int e) {

Expand Down
6 changes: 3 additions & 3 deletions src/jj1/bonuslevel/jj1bonuslevel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ int JJ1BonusLevel::loadSprites () {

try {

file = new File("BONUS.000", false);
file = new File("BONUS.000", PATH_TYPE_GAME);

} catch (int e) {

Expand Down Expand Up @@ -135,7 +135,7 @@ int JJ1BonusLevel::loadTiles (char *fileName) {

try {

file = new File(fileName, false);
file = new File(fileName, PATH_TYPE_GAME);

} catch (int e) {

Expand Down Expand Up @@ -216,7 +216,7 @@ JJ1BonusLevel::JJ1BonusLevel (Game* owner, char * fileName, bool multi) : Level(

try {

file = new File(fileName, false);
file = new File(fileName, PATH_TYPE_GAME);

} catch (int e) {

Expand Down
Loading

0 comments on commit c5cbd33

Please sign in to comment.