davidjoffe / dave_gnukem

Dave Gnukem is a cross-platform 2D scrolling platform shooter inspired by Duke Nukem 1
GNU General Public License v2.0
76 stars 23 forks source link

Dynamic DATA_DIR and Makefile DATA_DIR #176

Open davidjoffe opened 1 year ago

davidjoffe commented 1 year ago

Something small I've been wanting to do a while is just a small refactoring of the DATA_DIR stuff so that at the application startup, it copies DATA_DIR initially into a simple string variable somewhere in a datadir 'backend' ... then we could have small helpers like "djDataDir()" or something (not access the string directly as the implementation may change or be port-dependent maybe even) that abstract away and just return the value wherever we currently use DATA_DIR instead (plus maybe a few 'path append' helpers to make it simpler to use, and add some safety stuff like 'trailing /' sanity checks) ..

(Edit I forgot we already have some helpers for path appending .. maybe needs a little cleanup/refactoring)

That would allow us to do something like, check if DATA_DIR exists but then potentially switch to a fallback directory (e.g. say it looks in "/usr/share/..." but doesn't find it, it could then immediately look underneath say the current folder you're running it from - if you're developing, say) ... might also help to give porters slightly more flexibility, as they could also maybe patch the code to set their own custom datadir for arbitrary console platforms etc. maybe or something.

(Note I'm not necessarily suggesting here a change in the Makefile itself, though regarding the Makefile it would be useful if we could pass the desired DATA_DIR into the new Makefile in some way, but I'm not sure if that is easily do-able in a platform-neutral way and also not sure if it is do-able

Some convenience helpers in one place could also allow e.g. 'tedious' malloc/new code for file path appending to be done in one place with helper functions perhaps (thus safety-checking in one proper place, and also, at the same time could start trying to reduce or get rid (or make more reasonable) the path file limits in order to support extremely long filenames (I recently updated some horrible ancient limits in the code but ideally it should allow arbitrarily long (or perhaps almost arbitrary to some reasonable degree) paths .. and also at some point we should also make sure Unicode filenames work (I don't know if they already will on some platforms))

E.g. something like:

pLevel->m_szBackground = djStrDeepCopy(DATA_DIR "levels/bg1.tga");

could become:

pLevel->m_szBackground = djPathAppend(djDataDir(), "levels/bg1.tga");

or something along those lines.

This change could also make it a bit easier to create different new derivative games potentially from the source as a different game just point to e.g. some entirely different data folder, e.g. if one created say a Captain Cosmo or Manic Miner style retro parody from the same codebase or whatever (or new modern game even)

I'm slightly torn between using std::string for such a getdatadir helper and const char* ... maybe that's a bit pedantic or old-fashioned but std::string does make for both convenience and easier appending of arbitrary lengths, using more and more template stuff may bloat the code and slow compiles (though this game compiles relatively quickly I'd like to ideally keep it that way). Possibly optional std::string alternatives could live in a different .h/cpp but that may be overkill

davidjoffe commented 1 year ago

FYI There's now a new "-datadir DIR" commandline option that can be used to override the compiled in DATA_DIR (plus I've implemented the above), so from one's development folder one can e.g.

$ git clone https://github.com/davidjoffe/dave_gnukem
$ cd dave_gnukem
$ git clone https://github.com/davidjoffe/gnukem_data data
$ make
$ ./davegnukem -datadir data

OR

$ git clone https://github.com/davidjoffe/gnukem_data mydatafolder
$ ./davegnukem -datadir mydatafolder

OR

$ git clone https://github.com/davidjoffe/gnukem_data 
$ ./davegnukem -datadir gnukem_data

etc.

This allows you to have multiple data folders easily - e.g. say one stable, or one if you want to e.g. add or edit your own levels or something (in theory, potentially)

Also it means if DATA_DIR is compiled as it is now by default with the Makefile with something like /usr/... you can easily still just override it during testing with your local data folder. Or even if you've done a "make install" you can pass the installed versino a local data folder

(If some platform porters want to disable the ability of players to pass a commandline option it can be disable with a -D / config.h preprocessor option. Or if for some hardware console port you want to pass a special datadir.)

Currently it first checks your "-datadir" path exists and if not found, it then tries the usual "DATA_DIR"