diff --git a/linux.cmake b/linux.cmake new file mode 100644 index 0000000000..77a58dfa83 --- /dev/null +++ b/linux.cmake @@ -0,0 +1,10 @@ +# These are various overrides for dependencies built using CMake. + +set(CMAKE_SYSTEM_NAME Linux) +set(CMAKE_C_COMPILER gcc) +set(CMAKE_C_FLAGS -m32) +set(CMAKE_CXX_COMPILER g++) +set(CMAKE_CXX_FLAGS -m32) +set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) +set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) +set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) diff --git a/linux.mk b/linux.mk new file mode 100644 index 0000000000..3da07dc844 --- /dev/null +++ b/linux.mk @@ -0,0 +1,340 @@ +include version.mk + +BUILD_NUMBER ?= $(VER_BUILD) +VER_STRING := $(VER_MAJOR).$(VER_MINOR).$(VER_RELEASE).$(BUILD_NUMBER) $(PACKAGE_SUFFIX) + +ROOTDIR := $(dir $(abspath $(lastword $(MAKEFILE_LIST)))) + +RM = rm -f +MV = mv -f +CP = cp -f +MKDIR = mkdir -p +ECHO = echo +CD = cd +CMAKE := cmake -DCMAKE_TOOLCHAIN_FILE=$(ROOTDIR)/linux.cmake + +SOURCES = \ + src/actionpt.c \ + src/api.c \ + src/ariadne.c \ + src/ariadne_edge.c \ + src/ariadne_findcache.c \ + src/ariadne_naviheap.c \ + src/ariadne_navitree.c \ + src/ariadne_points.c \ + src/ariadne_regions.c \ + src/ariadne_tringls.c \ + src/ariadne_wallhug.c \ + src/bflib_base_tcp.c \ + src/bflib_basics.c \ + src/bflib_bufrw.c \ + src/bflib_coroutine.c \ + src/bflib_client_tcp.c \ + src/bflib_cpu.c \ + src/bflib_datetm.c \ + src/bflib_dernc.c \ + src/bflib_enet.c \ + src/bflib_fileio.c \ + src/bflib_filelst.c \ + src/bflib_guibtns.c \ + src/bflib_inputctrl.c \ + src/bflib_keybrd.c \ + src/bflib_main.c \ + src/bflib_math.c \ + src/bflib_memory.c \ + src/bflib_mouse.c \ + src/bflib_mshandler.c \ + src/bflib_mspointer.c \ + src/bflib_netsession.c \ + src/bflib_netsp.c \ + src/bflib_netsp_ipx.c \ + src/bflib_netsync.c \ + src/bflib_network.c \ + src/bflib_planar.c \ + src/bflib_render.c \ + src/bflib_render_gpoly.c \ + src/bflib_render_trig.c \ + src/bflib_server_tcp.c \ + src/bflib_sound.c \ + src/bflib_sprfnt.c \ + src/bflib_sprite.c \ + src/bflib_string.c \ + src/bflib_tcpsp.c \ + src/bflib_threadcond.c \ + src/bflib_video.c \ + src/bflib_vidraw.c \ + src/bflib_vidraw_spr_norm.c \ + src/bflib_vidraw_spr_onec.c \ + src/bflib_vidraw_spr_remp.c \ + src/bflib_vidsurface.c \ + src/config.c \ + src/config_campaigns.c \ + src/config_creature.c \ + src/config_crtrmodel.c \ + src/config_crtrstates.c \ + src/config_lenses.c \ + src/config_magic.c \ + src/config_objects.c \ + src/config_players.c \ + src/config_powerhands.c \ + src/config_rules.c \ + src/config_settings.c \ + src/config_slabsets.c \ + src/config_strings.c \ + src/config_terrain.c \ + src/config_cubes.c \ + src/config_textures.c \ + src/config_trapdoor.c \ + src/config_spritecolors.c \ + src/console_cmd.c \ + src/custom_sprites.c \ + src/creature_battle.c \ + src/creature_control.c \ + src/creature_graphics.c \ + src/creature_groups.c \ + src/creature_instances.c \ + src/creature_jobs.c \ + src/creature_senses.c \ + src/creature_states.c \ + src/creature_states_barck.c \ + src/creature_states_combt.c \ + src/creature_states_gardn.c \ + src/creature_states_guard.c \ + src/creature_states_hero.c \ + src/creature_states_lair.c \ + src/creature_states_mood.c \ + src/creature_states_pray.c \ + src/creature_states_prisn.c \ + src/creature_states_rsrch.c \ + src/creature_states_scavn.c \ + src/creature_states_spdig.c \ + src/creature_states_tortr.c \ + src/creature_states_train.c \ + src/creature_states_tresr.c \ + src/creature_states_wrshp.c \ + src/cursor_tag.c \ + src/dungeon_data.c \ + src/dungeon_stats.c \ + src/engine_arrays.c \ + src/engine_camera.c \ + src/engine_lenses.c \ + src/engine_redraw.c \ + src/engine_render.c \ + src/engine_render_data.c \ + src/engine_textures.c \ + src/front_credits.c \ + src/front_credits_data.c \ + src/front_easter.c \ + src/front_fmvids.c \ + src/front_highscore.c \ + src/front_input.c \ + src/front_landview.c \ + src/front_lvlstats.c \ + src/front_lvlstats_data.c \ + src/front_network.c \ + src/front_simple.c \ + src/front_torture.c \ + src/front_torture_data.c \ + src/frontend.c \ + src/frontmenu_options_data.c \ + src/frontmenu_saves_data.c \ + src/frontmenu_select.c \ + src/frontmenu_select_data.c \ + src/frontmenu_ingame_evnt.c \ + src/frontmenu_ingame_evnt_data.c \ + src/frontmenu_ingame_map.c \ + src/frontmenu_ingame_opts.c \ + src/frontmenu_ingame_opts_data.c \ + src/frontmenu_ingame_tabs.c \ + src/frontmenu_ingame_tabs_data.c \ + src/frontmenu_net.c \ + src/frontmenu_net_data.c \ + src/frontmenu_options.c \ + src/frontmenu_saves.c \ + src/frontmenu_specials.c \ + src/game_heap.c \ + src/game_legacy.c \ + src/game_loop.c \ + src/game_lghtshdw.c \ + src/game_merge.c \ + src/game_saves.c \ + src/gui_boxmenu.c \ + src/gui_draw.c \ + src/gui_frontbtns.c \ + src/gui_frontmenu.c \ + src/gui_msgs.c \ + src/gui_parchment.c \ + src/gui_soundmsgs.c \ + src/gui_tooltips.c \ + src/gui_topmsg.c \ + src/kjm_input.c \ + src/lens_api.c \ + src/config_effects.c \ + src/lens_flyeye.c \ + src/lens_mist.c \ + src/light_data.c \ + src/lvl_filesdk1.c \ + src/lvl_script.c \ + src/lvl_script_commands.c \ + src/lvl_script_commands_old.c \ + src/lvl_script_lib.c \ + src/lvl_script_conditions.c \ + src/lvl_script_value.c \ + src/magic.c \ + src/main.cpp \ + src/main_game.c \ + src/map_blocks.c \ + src/map_columns.c \ + src/map_ceiling.c \ + src/map_data.c \ + src/map_events.c \ + src/map_locations.c \ + src/map_utils.c \ + src/moonphase.c \ + src/music_player.c \ + src/net_game.c \ + src/net_sync.c \ + src/packets.c \ + src/packets_cheats.c \ + src/packets_input.c \ + src/packets_misc.c \ + src/player_compchecks.c \ + src/player_compevents.c \ + src/player_complookup.c \ + src/config_compp.c \ + src/player_compprocs.c \ + src/player_comptask.c \ + src/player_computer.c \ + src/player_computer_data.c \ + src/player_data.c \ + src/player_instances.c \ + src/player_utils.c \ + src/power_hand.c \ + src/power_process.c \ + src/power_specials.c \ + src/room_data.c \ + src/room_entrance.c \ + src/room_garden.c \ + src/room_graveyard.c \ + src/room_jobs.c \ + src/room_lair.c \ + src/room_library.c \ + src/room_list.c \ + src/room_scavenge.c \ + src/room_util.c \ + src/room_workshop.c \ + src/roomspace.c \ + src/roomspace_detection.c \ + src/scrcapt.c \ + src/slab_data.c \ + src/sounds.c \ + src/spdigger_stack.c \ + src/tasks_list.c \ + src/thing_corpses.c \ + src/thing_creature.c \ + src/thing_creature_data.c \ + src/thing_data.c \ + src/thing_doors.c \ + src/thing_effects.c \ + src/thing_factory.c \ + src/thing_list.c \ + src/thing_navigate.c \ + src/thing_objects.c \ + src/thing_physics.c \ + src/thing_shots.c \ + src/thing_stats.c \ + src/thing_traps.c \ + src/value_util.c \ + src/vidfade.c \ + src/vidmode_data.c \ + src/vidmode.c \ + src/KeeperSpeechImp.c \ + src/stubs.cpp \ + src/linux.cpp + +WIN_SOURCES = \ + src/bflib_crash.c \ + src/bflib_fmvids.c \ + src/bflib_sndlib.c \ + src/steam_api.c + +INCLUDES = \ + deps/centitoml \ + deps/centijson/src \ + deps/libspng/spng \ + deps/enet/include + +DEPS = \ + deps/astronomy/astronomy.o \ + deps/centijson/build/libjson.a \ + deps/centitoml/toml_api.o \ + deps/libspng/build/libspng_static.a \ + deps/zlib/contrib/minizip/unzip.o \ + deps/zlib/contrib/minizip/ioapi.o \ + deps/enet/build/libenet.a + +CFLAGS = -c -g -m32 --std=gnu17 -Wall -Wextra -Werror -Wno-sign-compare -Wno-unused-parameter -Wno-unknown-pragmas -Wno-format-truncation +CXXFLAGS = -c -g -m32 --std=c++23 -Wall -Wextra -Werror -Wno-sign-compare -Wno-unused-parameter -Wno-unknown-pragmas -Wno-format-truncation + +all: bin/keeperfx + +clean: + $(RM) -r obj src/ver_defs.h + +bin/keeperfx: obj/archive.a $(DEPS) | bin + $(CXX) -g -m32 -o $@ $^ -lSDL2 -lSDL2_mixer -lSDL2_net -lSDL2_image -lz -lm + +obj/%.o: src/%.c | obj src/ver_defs.h + $(CC) $(CFLAGS) -o $@ $(addprefix -I,$(INCLUDES)) $^ + +obj/%.o: src/%.cpp | obj src/ver_defs.h + $(CXX) $(CXXFLAGS) -o $@ $(addprefix -I,$(INCLUDES)) $^ + +obj/archive.a: $(patsubst src/%.c,obj/%.o,$(patsubst src/%.cpp,obj/%.o,$(SOURCES))) | obj + $(AR) r $@ $^ + +bin obj: + $(MKDIR) -p $@ + +src/ver_defs.h: version.mk + $(ECHO) \#define VER_MAJOR $(VER_MAJOR) > "$@.swp" + $(ECHO) \#define VER_MINOR $(VER_MINOR) >> "$@.swp" + $(ECHO) \#define VER_RELEASE $(VER_RELEASE) >> "$@.swp" + $(ECHO) \#define VER_BUILD $(BUILD_NUMBER) >> "$@.swp" + $(ECHO) \#define VER_STRING \"$(VER_STRING)\" >> "$@.swp" + $(ECHO) \#define PACKAGE_SUFFIX \"$(PACKAGE_SUFFIX)\" >> "$@.swp" + $(ECHO) \#define GIT_REVISION \"`git describe --always`\" >> "$@.swp" + $(MV) "$@.swp" "$@" + +deps/astronomy/astronomy.o: deps/astronomy/astronomy.c + $(CC) $(CFLAGS) -o $@ $^ + +deps/centijson/build/libjson.a: deps/centijson/build/Makefile + $(CD) deps/centijson/build && $(MAKE) + +deps/centijson/build/Makefile: + $(MKDIR) -p deps/centijson/build + $(CD) deps/centijson/build && $(CMAKE) .. + +deps/centitoml/toml_api.o: deps/centitoml/toml_api.c + $(CC) $(CFLAGS) -o $@ $^ -Ideps/centijson/src + +deps/zlib/contrib/minizip/unzip.o: deps/zlib/contrib/minizip/unzip.c + $(CC) $(CFLAGS) -o $@ $^ + +deps/zlib/contrib/minizip/ioapi.o: deps/zlib/contrib/minizip/ioapi.c + $(CC) $(CFLAGS) -o $@ $^ + +deps/libspng/build/libspng_static.a: deps/libspng/build/Makefile + $(CD) deps/libspng/build && $(MAKE) + +deps/libspng/build/Makefile: + $(MKDIR) -p deps/libspng/build + $(CD) deps/libspng/build && $(CMAKE) .. + +deps/enet/build/libenet.a: deps/enet/build/Makefile + $(CD) deps/enet/build && $(MAKE) + +deps/enet/build/Makefile: + $(MKDIR) -p deps/enet/build + $(CD) deps/enet/build && $(CMAKE) .. diff --git a/src/bflib_fileio.c b/src/bflib_fileio.c index 7af1396fb3..d3ebfd5cb9 100644 --- a/src/bflib_fileio.c +++ b/src/bflib_fileio.c @@ -26,20 +26,14 @@ #include #include #include -#include #include #include #include #include -#include #include "bflib_basics.h" #include "bflib_datetm.h" -#if defined(_WIN32)||defined(DOS)||defined(GO32) -#include -#include -#endif #include "post_inc.h" short LbFileExists(const char *fname) @@ -62,7 +56,11 @@ int create_directory_for_file(const char * fname) while (separator != NULL) { memcpy(tmp, fname, separator - fname); tmp[separator - fname] = 0; +#if defined(_WIN32) if (mkdir(tmp) != 0) { +#else + if (mkdir(tmp, 0755) != 0) { +#endif if (errno != EEXIST) { free(tmp); return 0; diff --git a/src/linux.cpp b/src/linux.cpp new file mode 100644 index 0000000000..db6c84901f --- /dev/null +++ b/src/linux.cpp @@ -0,0 +1,132 @@ + +#include "bflib_fileio.h" +#include "bflib_cpu.h" +#include "bflib_crash.h" +#include "bflib_datetm.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include + +struct TbFileFind { + std::string filespec; + std::string path; + std::string namebuf; + DIR * handle = nullptr; + bool is_pattern = false; +}; + +bool filespec_is_pattern(const char * filespec) { + return strchr(filespec, '*') != nullptr; +} + +std::string directory_from_filespec(const char * filespec) { + const auto sep = strrchr(filespec, '/'); + if (sep && sep != filespec) { + return std::string(filespec, sep - filespec); + } else { + return "."; + } +} + +bool find_file(TbFileFind * ff, TbFileEntry * fe) { + while (true) { + auto de = readdir(ff->handle); + if (!de) { + return false; + } else if (strcmp(de->d_name, ".") == 0) { + continue; + } else if (strcmp(de->d_name, "..") == 0) { + continue; + } + const std::string path = ff->path + "/" + de->d_name; + ff->namebuf = de->d_name; + fe->Filename = ff->namebuf.c_str(); + if (ff->is_pattern) { + if (fnmatch(ff->filespec.c_str(), path.c_str(), FNM_FILE_NAME | FNM_CASEFOLD) != 0) { + continue; + } + } + struct stat sb; + if (stat(path.c_str(), &sb) < 0) { + continue; + } else if (!S_ISREG(sb.st_mode)) { + continue; + } + return true; + } + return false; +} + +extern "C" TbFileFind * LbFileFindFirst(const char * filespec, TbFileEntry * fe) +{ + try { + auto ff = std::make_unique(); + ff->is_pattern = filespec_is_pattern(filespec); + ff->filespec = filespec; + if (ff->is_pattern) { + ff->path = directory_from_filespec(filespec); + ff->handle = opendir(ff->path.c_str()); + } else { + ff->path = filespec; + ff->handle = opendir(filespec); + } + if (ff->handle) { + if (find_file(ff.get(), fe)) { + return ff.release(); + } + } + } catch (...) {} + return nullptr; +} + +extern "C" int LbFileFindNext(TbFileFind * ff, TbFileEntry * fe) +{ + try { + if (find_file(ff, fe)) { + return 1; + } + } catch (...) {} + return -1; +} + +extern "C" void LbFileFindEnd(TbFileFind * ff) +{ + if (ff) { + closedir(ff->handle); + } + delete ff; +} + +extern "C" void log_system_info(const CPU_INFO *) { + // TODO +} + +extern "C" void get_cmdln_args(unsigned short &argc, char *argv[]) { + // Nothing to do here +} + +extern "C" void platform_init() { + // Nothing to do here +} + +extern "C" void LbErrorParachuteInstall() { + // Nothing to do here +} + +extern "C" void LbErrorParachuteUpdate() { + // Nothing to do here +} + +extern "C" void LbDoMultitasking() +{ + timespec ts; + ts.tv_sec = 0; + ts.tv_nsec = (LARGE_DELAY_TIME>>1) * 1000; + nanosleep(&ts, nullptr); +} diff --git a/src/stubs.cpp b/src/stubs.cpp new file mode 100644 index 0000000000..232671cb6c --- /dev/null +++ b/src/stubs.cpp @@ -0,0 +1,40 @@ +#include "bflib_sound.h" + +extern "C" int init_miles_sound_system() { return 0; } +extern "C" void unload_miles_sound_system() {} +extern "C" int FreeAudio() { return 0; } +extern "C" int SetRedbookVolume(int) { return 0; } +extern "C" int SetSoundMasterVolume(int) { return 0; } +extern "C" int SetMusicMasterVolume(int) { return 0; } +extern "C" int GetSoundInstalled(void) { return 0; } +extern "C" int PlayRedbookTrack(int) { return 0; } +extern "C" int PauseRedbookTrack(void) { return 0; } +extern "C" int ResumeRedbookTrack(void) { return 0; } +extern "C" int MonitorStreamedSoundTrack(void) { return 0; } +extern "C" int StopRedbookTrack(void) { return 0; } +extern "C" void * GetSoundDriver(void) { return nullptr; } +extern "C" int StopAllSamples(void) { return 0; } +extern "C" struct SampleInfo * GetFirstSampleInfoStructure(void) { return nullptr; } +extern "C" int InitAudio(void *) { return 0; } +extern "C" int SetupAudioOptionDefaults(void *) { return 0; } +extern "C" int IsSamplePlaying(int a1, int a2, int a3) { return 0; } +extern "C" struct SampleInfo * GetLastSampleInfoStructure(void) { return nullptr; } +extern "C" int GetCurrentSoundMasterVolume(void) { return 0; } +extern "C" int StopSample(SoundEmitterID emit_id, long smptbl_id) { return 0; } +extern "C" int SetSampleVolume(SoundEmitterID emit_id, long smptbl_id,long volume,long d) { return 0; } +extern "C" int SetSamplePan(SoundEmitterID emit_id, long smptbl_id,long pan,int d) { return 0; } +extern "C" int SetSamplePitch(SoundEmitterID emit_id, long smptbl_id,long pitch,int d) { return 0; } +extern "C" struct SampleInfo * PlaySampleFromAddress(SoundEmitterID emit_id, int smpl_idx, int a3, int a4, int a5, unsigned char a6, unsigned char a7, void * buf, int sfxid) { return 0; } + +extern "C" short play_smk_(char *fname, int smkflags, int plyflags) { return 0; } +extern "C" short play_smk_direct(char *fname, int smkflags, int plyflags) { return 0; } +extern "C" short play_smk_via_buffer(char *fname, int smkflags, int plyflags) { return 0; } + +// Exported functions - FLI related +extern "C" short anim_open(char *fname, int arg1, short arg2, int width, int height, int arg5, unsigned int flags) { return 0; } +extern "C" short anim_stop(void) { return 0; } +extern "C" short anim_record(void) { return 0; } +extern "C" TbBool anim_record_frame(unsigned char *screenbuf, unsigned char *palette) { return 0; } + +extern "C" int steam_api_init() { return 0; } +extern "C" void steam_api_shutdown() {}