TheForceEngine icon indicating copy to clipboard operation
TheForceEngine copied to clipboard

Linux Components

Open gilmorem560 opened this issue 3 years ago • 14 comments

This PR implements functionality required to satisfy #89 by providing Linux (and POSIX where possible) alternatives to Windows-specific methods as well as tweaking a few things to make the code more portable. Summary of changes:

Paths:

  • Excludes application search paths outside of Windows given the unlikelihood of local installation in C: or D:
  • Provide various system paths for Linux
  • Prevent creating a Mods folder where the binary resides outside Windows

Sizing:

  • Integrate cinttypes where format strings must print dubious stdint types
  • Ensures GOB and LFD field sizes are fixed 32-bit integers
  • Use time_t for screenshot time outside Windows (unknown if Windows must be 64-bit precision)

Reimplementation of Windows features:

  • Provide a POSIX mutex
  • Provide a POSIX sleep
  • Provide POSIX fileutils operations
  • Provide strupr outside Windows
  • Replace _s safe string operations with "n" ANSI variants outside Windows
  • Scaffold necessary threading components to build pthreads core

Build Support:

  • Remove ## from preprocessor subsitutions which prevented g++ compilation
  • Reimplement FileStream string operations as explicit methods due to lack of Std C++ support for explicit specialization
  • Added a Makefile which should build a shared binary on any Linux system with:
    • Mesa3D
    • GLEW
    • SDL 2
    • DevIL
    • Alsa (Other backends are possible, consult the Makefile and RtAudio)
    • RtAudio
    • RtMidi
  • Added some VSCode workspace files for building and debugging, perhaps someone will find them useful

There's a lot here, as you've mentioned, take your time, the code's not going anywhere. One item that I have done in my local copy but didn't push up yet is reimplement the zip component to use https://github.com/nih-at/libzip, however, didn't want to throw in a dependency change with this PR.

Some notes: Local data is stored in ~/.local/share/TheForceEngine Program data is accessed at ~/TheForceEngine The mouse cursor ungrabs from the window when you click Fullscreen doesn't quite work on Linux. Had a workaround for testing but didn't commit as it may have other implications No audio but haven't peeked at any of the code there Some areas that I simply ifdef _WIN32'd things may be candidates for consolidation, but didn't feel the need to replace what works for now.

Until this is merged, if anyone experiences issues with this specific set of changes, be sure to toss the issues over on my fork rather than adding noise to the upstream repo.

gilmorem560 avatar Dec 05 '21 08:12 gilmorem560

Until this is merged, if anyone experiences issues with this specific set of changes, be sure to toss the issues over on my fork rather than adding noise to the upstream repo.

Thanks for this! I don't see an "issues" section in your repo, it's possible you haven't enabled that feature for it.

JPLeBreton avatar Dec 05 '21 19:12 JPLeBreton

Whoops, flipped that on.

gilmorem560 avatar Dec 06 '21 00:12 gilmorem560

It is a decent number of changes but it looks fairly straightforward. I will have to test locally in the near future but assuming everything still works properly it looks good.

luciusDXL avatar Dec 06 '21 21:12 luciusDXL

One thing I would encourage if you take a swing at merging is assessing if various forks in the road controlled by _WIN32 ifdefs are really necessary, or if the non-Windows pathway would work on Windows as well.

Two such items that come to mind: Use of __time64_t vs time_t in screenshot timestamp generation in main.c. I can't reliably get __time64_t to expose on my system through the standard ctime header. It's in <time/time.h> but this is a glibc extension I think, so grabbing that doesn't bode well for re-usability on say macOS or the BSDs.

There are a few areas where the MSVC "_s" safe variants of operations on string buffers are used to prevent buffer overflows. I suspect these are fine to replace with the "n" versions from the ANSI C standard (e.g. strcpy_s -> strncpy) but put them in an ifdef-else construct for now.

There are others, but in each case, I didn't feel confident in replacing something that may have had an explicit rationale behind the choice on the Windows platform, so I just wrapped them with the ifdefs instead.

gilmorem560 avatar Dec 06 '21 21:12 gilmorem560

There hasn't been a lot of activity with this because the project has been in flux as work towards version 1.0 continues. My plan is to look at the changes here and reimplement the parts still needed after version 1.0 is out rather than merging the CL directly. Thanks for all the work on the changes. :)

luciusDXL avatar May 31 '22 17:05 luciusDXL

You betcha, I've been wholly consumed with some research projects anyhow, haven't had time to pivot back and see where things are at. Happy to help when the time comes.

gilmorem560 avatar May 31 '22 18:05 gilmorem560

When trying to build this I get the following errors at the end? Any way to resolve this? Building on ubuntu 20.04

Ui/markdown.o TheForceEngine/TFE_Ui/ui.o TheForceEngine/main.o -g -pthread -lGL -lGLEW -lSDL2 -lIL -lILU -lasound -lrtaudio -lrtmidi
/usr/bin/ld: cannot find -lIL
/usr/bin/ld: cannot find -lILU
/usr/bin/ld: cannot find -lrtaudio
/usr/bin/ld: cannot find -lrtmidi
collect2: error: ld returned 1 exit status

r3claimer avatar Jul 06 '22 14:07 r3claimer

Haven't been keeping up with this too terribly, but sounds like you don't have the dev libraries. Either install source packages for those libraries or install the "dev" versions of them from your package manager of choice. If you do have them installed, then make sure your linker is actually looking for them with a -L parameter.

gilmorem560 avatar Jul 07 '22 14:07 gilmorem560

I got it figured out, TY. Unfortunately the handheld linux OS I was trying to port it to doesn't currently support GLEW.

r3claimer avatar Jul 10 '22 21:07 r3claimer

Sure it does, you just need to build it. If it's a Linux kernel with X and Mesa it most likely supports GLEW, your package manager just might not have binaries available. GLEWs homepage should have compilation/installation instructions.

Edit: Just noticed too that your error does not include "/usr/bin/ld: cannot find -lGLEW" so that implies you have GLEW installed already.

gilmorem560 avatar Jul 11 '22 15:07 gilmorem560

Unfortunately this is for a linux hanheld gaming device based on an arm cpu with mali graphics hardware. Open Gles3.x and SDL2 is all that is supported. Currently there is no support for GLEW, GLFS, OpenGL (without GL4ES emulation), etc.

r3claimer avatar Jul 11 '22 16:07 r3claimer

Well again, when you compile, you don't get an error saying you can't find GLEW, if GLEW wasn't installed, you'd get an indication that -lGLEW failed, but it didn't. I'll take your word for it though, but your feedback does seem inconsistent with my understanding of the library and error messages.

gilmorem560 avatar Jul 11 '22 16:07 gilmorem560

We dont build on the device itself, as its read only operating system (based on core elec). I have an ubuntu based docker container that is used to build games / packages and then we package games with the necessary lib files.

r3claimer avatar Jul 11 '22 16:07 r3claimer

Ahh cross compiling...that throws all of those assumptions out the window. Well best of luck, I've never had issues with GLEW on aarch64, I don't feel like arm32 should make a difference, but you know your device.

gilmorem560 avatar Jul 11 '22 16:07 gilmorem560

Just to share my experiences and findings with linux port (based on https://github.com/z33ky/TheForceEngine/tree/linux_port_implementation and consequently on this https://github.com/gilmorem560/TheForceEngine/tree/linux_port_implementation).

  1. to have sound and midi I had to compile it with flag LINUX_PULSE which added support for Pulseaudio for Rtaudio and Rtmidi, which were dynamically linked. To actually hear midi, I need to run fluidsynth in the background in server mode. More about this here #122 . Perhaps it's just me, but I have a feeling that Music is being played slightly faster as normal, but the sound effects are ok.

  2. Initially I didn't have any cut scenes. Reason for this was that my installation of GOG version of Dark Forces, had all files in LFD folder in uppercase and those files were simply not found (however no errors were displayed about this). At the end I renamed all files in the folder to lowercase and in addition to this: a) I need to have MENU.LFD in both, upper and lower case, otherwise game would crash when going back to the main menu with ESC in the game; and I wouldn't see any text in agent menu, respectively. b) AGENTMNU.LFD should be in uppercase, otherwise it would crash when trying to display agent menu. I guess main reason for this is, that Linux is case sensitive, while Windows is not, and that those two files are hardcoded in couple of places as uppercase.

spacekomet avatar Dec 11 '22 17:12 spacekomet

If PulseAudio requires a separate MIDI emulator running for this, it may be advantageous to lock one down and make it a dependency explicitly. This would grant the flexibility to actually execute it from TFE instead of having to launch it separately. Plus, forking the process right out of TFE rather than executing it separately may simplify the integrations between pieces. Granted, this would be very POSIX-specific code, I'm not sure what the current MIDI handling looks like on Windows or if there's anything there that would benefit from making portable for both use-cases. Plus, there's the matter of ensuring this mechanism works on other POSIX platforms such as macOS. I'll be the first to admit I know little to nothing about the audio subsystem in macOS save that it's likely ObjC and Swift native and would need either a shim or bindings written for this engine if going through RtAudio on that platform doesn't work. And that's just the matter of connecting to the audio system, then there's MIDI support.

I would almost be inclined to suggest an audio library that has its own MIDI synthesizer as to avoid this entirely. Granted, I don't know enough about the landscape of audio development out there well enough to even muster a guess as to where to start, but if MIDI is the format used, MIDI should probably have first class support as succinctly as possible. I probably won't be the one working on this, so not going to wave my hand around and act like I have a perfect idea on what to do, good luck!

gilmorem560 avatar Dec 12 '22 19:12 gilmorem560

I wouldn't integrate the midi synth into the application, unless you provide an option to redirect the midi output seperately as well. There are a lot of Linux users that use external hardware synths and software synths. Fluidsynth and Timidity are pretty standard as software synths. Dosbox does this, it can render internally or pipe the music out to external synths.

DMJC avatar Dec 25 '22 22:12 DMJC

Closing this as much of this work has been brought forward by mlauss

gilmorem560 avatar Dec 31 '22 05:12 gilmorem560