fteqw icon indicating copy to clipboard operation
fteqw copied to clipboard

Windows Visual Studio 2022 update

Open michaeleggers opened this issue 3 months ago • 3 comments

Hello everyone.

I made some changes so a minimal Visual Studio 2022 solution can be generated with CMake. The only dependency necessary is zlib: https://www.zlib.net/.

These are the steps to build it.

Get zlib and add as an dependency

1.) Clone the repo and create a new folder in the repo's root called dependencies. 2.) Copy the zlib source directory inside dependencies.

Why is this step required? I changed the CMakeLists.txt the following way:

IF (WIN32)
	
	IF(NOT DEFINED ZLIB_SOURCE_DIR)
		SET(ZLIB_SOURCE_DIR "dependencies/zlib")
	ENDIF()

	MESSAGE("Zlib source directory is set to: " ${ZLIB_SOURCE_DIR})

	IF (NOT EXISTS ${ZLIB_SOURCE_DIR})
		MESSAGE("Zlib source directory could not be found: " ${ZLIB_SOURCE_DIR})
	ENDIF()	

	ADD_SUBDIRECTORY(${ZLIB_SOURCE_DIR})
	SET(ZLIB_LIBRARIES zlib)
	SET(ZLIB_STATIC zlibstatic)
	SET(ZLIB_LIBRARY zlib)
	SET(ZLIB_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/${ZLIB_SOURCE_DIR})

	SET(FTE_LIB_DEFINES ${FTE_LIB_DEFINES};ZLIB_STATIC)
	SET(FTE_LIBS ${FTE_LIBS} ${ZLIB_LIBRARIES})
	SET(FTESV_LIBS ${FTESV_LIBS} ${ZLIB_LIBRARIES})
	SET(FTEQCC_LIBS ${FTEQCC_LIBS} ${ZLIB_LIBRARIES})
ELSE()
	FIND_PACKAGE(ZLIB)
	IF(ZLIB_FOUND)
		SET(FTE_LIB_DEFINES ${FTE_LIB_DEFINES};ZLIB_STATIC)
		SET(FTE_LIBS ${FTE_LIBS} ${ZLIB_LIBRARIES})
		SET(FTESV_LIBS ${FTESV_LIBS} ${ZLIB_LIBRARIES})
		SET(FTEQCC_LIBS ${FTEQCC_LIBS} ${ZLIB_LIBRARIES})
	ELSE()
		MESSAGE(WARNING "libz library NOT available. compressed pk3 will not be available.")
		SET(FTE_LIB_DEFINES ${FTE_LIB_DEFINES};NO_ZLIB)
	ENDIF()
ENDIF()

This means CMake does not look for an installed version of zlib on the system but rather includes the zlib sources into the final solution and zlib will be built ourselves. You can provide the relative directory path to the zlib sources via -DZLIB_SOURCE_DIR, eg. -DZLIB_SOURCE_DIR=dependencies/zlib-1.3.1.

Create a build directory

Now, create another directory called build inside this repo's root directory. It doesn't have to be called build, it is just a CMake convention. Go inside build. Open a console and type:

cmake ..

You will se a lot of (funny) messages that dependencies could not be found. This is fine but in the end no error should appear and a FTEQuake.sln should appear inside build. Open the solution and build the project fteqw. Depending on the build configuration (Debug/Release), you should now have a folder called bin. Inside the repo's root directory.

This bin directory is another change I made to the CMakeLists.txt:

# On Windows put all the built libs/exes/etc. in one directory
IF (WIN32)
	set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_SOURCE_DIR}/bin")
	set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_SOURCE_DIR}/bin")
	set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_SOURCE_DIR}/bin")
ENDIF()

This makes sure that all dll's lib's and executables land inside bin/Debug (or bin/Release). I have found it convenient (on windows) to have all the stuff combined in one folder and you don't have to manually copy DLL's or whatever around to get the fteqw.exe running.

All that is left to do is copy the game data (eg.Id1) alongside the .exe. It should run now.

Changes to source files

fs_zip.c:

I uncommented the following preprocessor code:

# ifdef _MSC_VER
#  ifdef _WIN64
#   pragma comment(lib, MSVCLIBSPATH "zlib64.lib")
#  else
#   pragma comment(lib, MSVCLIBSPATH "zlib.lib")
#  endif
# endif

because when we build zlib, the resulting library will be just called zlib.lib (even when built in 64 bit mode).

fs.c:

The ternary operator without providing a statement for the true case would not compile on msvc: So I made this change:

if (modlist[p].manifest && !strcmp(modlist[p].manifest->basedir ? modlist[p].manifest->basedir :"", man->basedir ? man->basedir :"") && !strcmp(modlist[p].manifest->mainconfig ? modlist[p].manifest->mainconfig  :"", man->mainconfig ? man->mainconfig  :"") && ((modlist[p].sourcetype!=MST_INTRINSIC&&sourcetype==MST_INTRINSIC) || !Q_strcasecmp(modlist[p].manifest->installation, man->installation)))
    return false;

This, I have to admit, is just a quick fix to get it running. While it's not wrong, it certainly is lengthy and not nice to read. I think it might be possible to set some CMake flags to let the compiler know that it is allowed.

sv_main.c:

Include stdint.h:

#if defined(WIN32)
	#include <stdint.h> 
#endif

The compile wouldn't find intmax_t without this. Again, it might be possible to set some compiler flag, so it is not necessary to include the header, I don't know.

.gitignore

I added the folders dependencies, build and bin.

Final words

  • I did not continue to add more dependencies (such as Bullet) because I wanted to get in sync first with the fte-team about the changes I made so far and listen to the feedback. get the other things included and build on Windows with cmake.
  • I only tested the OpenGL renderer.
  • I only tested Quake 1, but everything ran without any problems, I messed around with graphics settings and so on and couldn't get it to crash or behave in otherwise weird ways.
  • I used the newest available zlib library (ver 1.3.1).

Cheers, pythno

michaeleggers avatar Mar 16 '24 12:03 michaeleggers