Skip to content

Commit

Permalink
Add minimal emscripten support
Browse files Browse the repository at this point in the history
  • Loading branch information
zturtleman committed Jun 7, 2024
1 parent f869bff commit f41bd37
Show file tree
Hide file tree
Showing 4 changed files with 100 additions and 3 deletions.
62 changes: 60 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -1042,6 +1042,38 @@ ifeq ($(PLATFORM),sunos)

else # ifeq sunos

#############################################################################
# SETUP AND BUILD -- emscripten
#############################################################################

ifeq ($(PLATFORM),emscripten)

# 1. Create "baseq3" directory in the same directory as this Makefile.
# 2. Copy pak[0-8].pk3 into the created "baseq3" directory.
# 3. Run `/path/to/emsdk.sh`
# 4. Run `make PLATFORM=emscripten`
# 5. Serve the build/release-emscripten-wasm32/ioquake3_opengl2.{html,js,wasm,data} from a web server.
# 6. Load ioquake3_opengl2.html in a web browser.

CC=emcc
ARCH=wasm32

# LDFLAGS+=-s MAIN_MODULE is needed for dlopen() in client/server but it causes compile errors
USE_RENDERER_DLOPEN=0

BASE_CFLAGS=-fPIC -s USE_SDL=2
LDFLAGS=-s TOTAL_MEMORY=256mb -s MAX_WEBGL_VERSION=2 --preload-file baseq3
OPTIMIZEVM = -O3
OPTIMIZE = $(OPTIMIZEVM)

FULLBINEXT=.html

SHLIBEXT=wasm
SHLIBCFLAGS=-fPIC
SHLIBLDFLAGS=-s SIDE_MODULE

else # ifeq emscripten

#############################################################################
# SETUP AND BUILD -- GENERIC
#############################################################################
Expand All @@ -1060,6 +1092,7 @@ endif #OpenBSD
endif #NetBSD
endif #IRIX
endif #SunOS
endif #emscripten

ifndef CC
CC=gcc
Expand All @@ -1085,18 +1118,37 @@ endif

ifneq ($(BUILD_SERVER),0)
TARGETS += $(B)/$(SERVERBIN)$(FULLBINEXT)

ifeq ($(PLATFORM),emscripten)
EMSCRIPTENOBJ += $(B)/$(SERVERBIN).js \
$(B)/$(SERVERBIN).wasm \
$(B)/$(SERVERBIN).data
endif
endif

ifneq ($(BUILD_CLIENT),0)
TARGETS += $(B)/$(CLIENTBIN)$(FULLBINEXT)

ifeq ($(PLATFORM),emscripten)
EMSCRIPTENOBJ += $(B)/$(CLIENTBIN).js \
$(B)/$(CLIENTBIN).wasm \
$(B)/$(CLIENTBIN).data
endif

ifneq ($(USE_RENDERER_DLOPEN),0)
TARGETS += $(B)/$(CLIENTBIN)$(FULLBINEXT) $(B)/renderer_opengl1_$(SHLIBNAME)
TARGETS += $(B)/renderer_opengl1_$(SHLIBNAME)
ifneq ($(BUILD_RENDERER_OPENGL2),0)
TARGETS += $(B)/renderer_opengl2_$(SHLIBNAME)
endif
else
TARGETS += $(B)/$(CLIENTBIN)$(FULLBINEXT)
ifneq ($(BUILD_RENDERER_OPENGL2),0)
TARGETS += $(B)/$(CLIENTBIN)_opengl2$(FULLBINEXT)

ifeq ($(PLATFORM),emscripten)
EMSCRIPTENOBJ += $(B)/$(CLIENTBIN)_opengl2.js \
$(B)/$(CLIENTBIN)_opengl2.wasm \
$(B)/$(CLIENTBIN)_opengl2.data
endif
endif
endif
endif
Expand Down Expand Up @@ -1870,10 +1922,15 @@ Q3OBJ = \
ifdef MINGW
Q3OBJ += \
$(B)/client/con_passive.o
else
ifeq ($(PLATFORM),emscripten)
Q3OBJ += \
$(B)/client/con_passive.o
else
Q3OBJ += \
$(B)/client/con_tty.o
endif
endif

Q3R2OBJ = \
$(B)/renderergl2/tr_animation.o \
Expand Down Expand Up @@ -3044,6 +3101,7 @@ clean2:
@rm -f $(OBJ)
@rm -f $(OBJ_D_FILES)
@rm -f $(STRINGOBJ)
@rm -f $(EMSCRIPTENOBJ)
@rm -f $(TARGETS)

toolsclean: toolsclean-debug toolsclean-release
Expand Down
16 changes: 16 additions & 0 deletions code/qcommon/q_platform.h
Original file line number Diff line number Diff line change
Expand Up @@ -290,6 +290,22 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA

#endif

//================================================================== EMSCRIPTEN ===

#ifdef __EMSCRIPTEN__

#define OS_STRING "emscripten"
#define ID_INLINE inline
#define PATH_SEP '/'

#define ARCH_STRING "wasm32"

#define Q3_LITTLE_ENDIAN

#define DLL_EXT ".wasm"

#endif

//================================================================== Q3VM ===

#ifdef Q3_VM
Expand Down
17 changes: 16 additions & 1 deletion code/sdl/sdl_glimp.c
Original file line number Diff line number Diff line change
Expand Up @@ -398,7 +398,7 @@ static int GLimp_SetMode(int mode, qboolean fullscreen, qboolean noborder, qbool
int profileMask;
int majorVersion;
int minorVersion;
} contexts[3];
} contexts[4];
int numContexts, type;
const char *glstring;
int perChannelColorBits;
Expand Down Expand Up @@ -543,6 +543,14 @@ static int GLimp_SetMode(int mode, qboolean fullscreen, qboolean noborder, qbool
( r_preferOpenGLES->integer == -1 && profileMask == SDL_GL_CONTEXT_PROFILE_ES ) );

if ( preferOpenGLES ) {
#ifdef __EMSCRIPTEN__
// WebGL 2.0 isn't fully backward compatible so you have to ask for it specifically
contexts[numContexts].profileMask = SDL_GL_CONTEXT_PROFILE_ES;
contexts[numContexts].majorVersion = 3;
contexts[numContexts].minorVersion = 0;
numContexts++;
#endif

contexts[numContexts].profileMask = SDL_GL_CONTEXT_PROFILE_ES;
contexts[numContexts].majorVersion = 2;
contexts[numContexts].minorVersion = 0;
Expand All @@ -560,6 +568,13 @@ static int GLimp_SetMode(int mode, qboolean fullscreen, qboolean noborder, qbool
numContexts++;

if ( !preferOpenGLES ) {
#ifdef __EMSCRIPTEN__
contexts[numContexts].profileMask = SDL_GL_CONTEXT_PROFILE_ES;
contexts[numContexts].majorVersion = 3;
contexts[numContexts].minorVersion = 0;
numContexts++;
#endif

contexts[numContexts].profileMask = SDL_GL_CONTEXT_PROFILE_ES;
contexts[numContexts].majorVersion = 2;
contexts[numContexts].minorVersion = 0;
Expand Down
8 changes: 8 additions & 0 deletions code/sys/sys_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,10 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#include <ctype.h>
#include <errno.h>

#ifdef __EMSCRIPTEN__
#include <emscripten/emscripten.h>
#endif

#ifndef DEDICATED
#ifdef USE_LOCAL_HEADERS
# include "SDL.h"
Expand Down Expand Up @@ -863,10 +867,14 @@ int main( int argc, char **argv )
signal( SIGTERM, Sys_SigHandler );
signal( SIGINT, Sys_SigHandler );

#ifdef __EMSCRIPTEN__
emscripten_set_main_loop( Com_Frame, 0, 1 );
#else
while( 1 )
{
Com_Frame( );
}
#endif

return 0;
}
Expand Down

0 comments on commit f41bd37

Please sign in to comment.