[SOLVED][FTE]Is #CLIENTONLY define really works?

Discuss programming topics for the various GPL'd game engine sources.
Post Reply
toneddu2000
Posts: 1395
Joined: Tue Feb 24, 2009 4:39 pm
Location: Italy

[SOLVED][FTE]Is #CLIENTONLY define really works?

Post by toneddu2000 »

Hi engine masters! I'm trying to build updated version of FTE (v5224) using preprocessor define #CLIENTONLY .
I put it on top of client/quakedef.h but, when I try to compile it, it gives tons of errors because it searches for server structs / functions that, obviously, it can't find.
Am i missing a step?
Could you please help? Because I'd really like to compile FTE only client as 1° step, then second step would be more ambitious, but just go step by step for now! :)
Huge thanks guys!!
Last edited by toneddu2000 on Sat Mar 10, 2018 11:32 am, edited 1 time in total.
Meadow Fun!! - my first commercial game, made with FTEQW game engine
toneddu2000
Posts: 1395
Joined: Tue Feb 24, 2009 4:39 pm
Location: Italy

Re: [FTE]Is #CLIENTONLY define really works?

Post by toneddu2000 »

UPDATE: I also tried to define #clientonly in common/bothdefs.h but also lots of errors. It seems that some files don't have the #ifndef CLIENTONLY part where server parts are used
Meadow Fun!! - my first commercial game, made with FTEQW game engine
toneddu2000
Posts: 1395
Joined: Tue Feb 24, 2009 4:39 pm
Location: Italy

Re: [FTE]Is #CLIENTONLY define really works?

Post by toneddu2000 »

ok, I made it work.

client/cl_plugin.inc line 1248

Code: Select all

#ifndef CLIENTONLY
		Terr_GetTerrainFuncs
		#endif
client/textedit.c line 1018

Code: Select all

#ifndef CLIENTONLY
				NET_Sleep(20/1000.0, false);	//any os.
			#endif
server/sv_phys.c line 2196

Code: Select all

case MOVETYPE_FLY:
		#ifndef CLIENTONLY
		if (svent)
		{	//NQ players with movetype_fly are not like non-players.
			if (!WPhys_RunThink (w, ent))
				return;
			if (ent->xv->gravitydir[2] || ent->xv->gravitydir[1] || ent->xv->gravitydir[0])
				gravitydir = ent->xv->gravitydir;
			else
				gravitydir = w->g.defaultgravitydir;
			WPhys_CheckStuck (w, ent);
			WPhys_WalkMove (w, ent, gravitydir);
			break;
		}
		//fallthrough
		#endif
common/bothdefs.c line 248

Code: Select all

#ifndef CLIENTONLY
			#if defined(_WIN32) && !defined(FTE_SDL) && !defined(WINRT)
				#define SUBSERVERS	//use subserver code.
			#elif defined(__linux__) && !defined(ANDROID) && !defined(FTE_SDL)
				#define SUBSERVERS	//use subserver code.
			#endif
		#endif
common/bothdefs.c line 271

Code: Select all

#ifndef CLIENTONLY
			#define RAGDOLL
		#endif
common/bothdefs.c line 288

Code: Select all

#ifndef CLIENTONLY
			#define SVCHAT			//serverside npc chatting. see sv_chat.c
			#define Q2SERVER		//server can run a q2 game dll and switches to q2 network and everything else.
			#define Q2CLIENT		//client can connect to q2 servers
			#define HEXEN2			//mostly server only, but also includes some hud+menu stuff, and effects
		#endif
common/bothdefs.c line 303

Code: Select all

#ifndef CLIENTONLY
			#define WEBCLIENT		//http clients.
		#endif
common/bothdefs.c line 585

Code: Select all

#ifndef CLIENTONLY
	#if defined(HAVE_WINSSPI) || defined(HAVE_GNUTLS)
		#define HAVE_SSL
	#endif
#endif
and finally, in common/bothdefs.c add, at line 24

Code: Select all

#define CLIENTONLY
yay! Next step will be to remove sv_phys and engine menu and re-do all this stuff in craFTEr! :biggrin:
Meadow Fun!! - my first commercial game, made with FTEQW game engine
Max_Salivan
Posts: 96
Joined: Thu Dec 15, 2011 1:00 pm

Re: [SOLVED][FTE]Is #CLIENTONLY define really works?

Post by Max_Salivan »

compile engine with make sv-rel CFLAGS=-DCLIENTONLY ???
Sorry for my english :)
toneddu2000
Posts: 1395
Joined: Tue Feb 24, 2009 4:39 pm
Location: Italy

Re: [SOLVED][FTE]Is #CLIENTONLY define really works?

Post by toneddu2000 »

:?:
I don't understand ,was it a question or an answer? :biggrin:
Meadow Fun!! - my first commercial game, made with FTEQW game engine
Spike
Posts: 2914
Joined: Fri Nov 05, 2004 3:12 am
Location: UK
Contact:

Re: [SOLVED][FTE]Is #CLIENTONLY define really works?

Post by Spike »

if you're trying to strip out lots of stuff, you might want to use wastes/TW as a base.
cp common/config_wastes.h common/config_myconfig.h && make m-rel FTE_CONFIG=myconfig
causes it to read a custom config header based upon eukara's wastes config with a number of config options that strip out optional/vanilla stuff that simply isn't needed in (eg) The Wastes, which disturbingly makes it smaller than the no-server 'minimal' builds... I blame 3rd-party libraries.
I ought to split the minimal and standard configs into seperate config files too, if only to make the different configs easier to diff.

There are too many options for me to really care about every single combination of options, so yeah, expect it to bug out (usually by failing to compile) unless other stuff is also disabled too. :(
I probably also ought to go through and change the NOFOOs to FOOs instead, and all sorts of other cleanups, but gah. I don't much like cleaning code, usually I just end up breaking and not having the enthusiasm to hunt all the new bugs so I tend to do it only when there's a purpose beyond the code itself.

side note: building a server using only a client is a little folly.
toneddu2000
Posts: 1395
Joined: Tue Feb 24, 2009 4:39 pm
Location: Italy

Re: [SOLVED][FTE]Is #CLIENTONLY define really works?

Post by toneddu2000 »

The Wastes you say, huh? Definately I'll try it, thanks. I'll sure post it here.

Would it be possible to add a new "game" profile with the same options of The Wastes?
Because I'd suggest to create a "General modern game" profile with just the "game" folder as game folder and a neutral icon(I'd do it for you in no time, if you need it), so, people like me could use it to make non-quake games.
I personally just use:iqm,tga,particles,dynamiclight_add,and a single .bsp hull of 6 walls as map.
Spike wrote:I probably also ought to go through and change the NOFOOs to FOOs instead, and all sorts of other cleanups, but gah.
Yeah, I noticed everywhere #ifndef CLIENTONLY...
Yesterday I really tried to understand how engine works, which parts are called at start, but it's for me very difficult because of my poor C skills.
I *guess* it starts with WinMain() that calls Host_Init(),but then Host_Init call R_SetRenderer with argument to NULL and then I lost the way home! :biggrin:
I really really would like to contribute and to make a super light build of FTE with just client( and no net protocols at all),opengl, iqm, tga and an already bsp hull created by code at startup (I did it in quakec but not in the engine) but for now it's too difficult for me
Spike wrote:side note: building a server using only a client is a little folly.
That's what Max_Salivan said. I never said I compile the server. That would be absurd, I agree.
Infact, I use make gl-rel FTE_TARGET=win32 -j 8. That's it.

PS:Since you're here, I sent you a pm some day ago to say that latest modification you made (v5221) to add dynamiclight_spawnstatic ruined dynamiclight_add func. Now dynamic lights flicker every frame.
Sorry to bother you
Meadow Fun!! - my first commercial game, made with FTEQW game engine
Spike
Posts: 2914
Joined: Fri Nov 05, 2004 3:12 am
Location: UK
Contact:

Re: [SOLVED][FTE]Is #CLIENTONLY define really works?

Post by Spike »

in terms of rendering, the basic idea is that FTE is 'just' trisoup.
the client generates batches of trisoup meshes. each batch has a single shader and a few other common properties. the backend logic of each renderer then takes those batches, walks through the shader passes, and draws the meshes accordingly.
the backends configure the shader logic via the sh_config struct, which controls the accepted aspects of the shaders (like whether glsl can be used or not, or the max number of textures per pass). the usable texture formats are configured the same way too.
so the model code is responsible for loading models, the image.c code is responsible for loading texture files and converting into formats supported by the gpu. the gl_shader.c code is responsible for parsing shaders and generating the internal representation of those. the client code handles bsp culling+pvs to add the various meshes into batches.
each renderer has a rendererinfo_t struct that tells the rest of the engine what to call in order to get any gpu work done - its pretty much all trisoup, textures, and buffers.
the renderer then has a fairly generic interface which allows FTE to support many renderers without too much extra effort, in theory.

rendering wise, GLSCR_UpdateScreen is the function that's meant to be responsible for throwing everything at the screen. So if you're trying to walk through FTE's rendering stages, start there. There shouldn't be any drawing elsewhere. Note that the other renderers have their own alternatives to this function, which sucks.
pr_csqc.c contains most of the csqc-only builtins (any externally-visible gunctions are meant to have a CSQC_ prefix, while builtins follow the PF_ prefix), with pr_cmds.c giving the ssqc-only ones, with pr_menu.qc giving the menu-only ones, supposedly. pr_bgcmd.c contains the generic builtins that might be used by any vm, while pr_clcmd.c gives builtins shared between csqc+menuqc, and pr_skelobj.c giving the skeletal object, ragdoll, and a number of model-related builtins shared between csqc+ssqc.
gl_shadow.c's rtlights are sandwiched between two shader sort values called from somewhere inside gl_backend.c or so.

but yeah, its a large project, with lots of legacy, the more you play with it, the more you'll understand it - practise makes perfect.... or something.
toneddu2000
Posts: 1395
Joined: Tue Feb 24, 2009 4:39 pm
Location: Italy

Re: [SOLVED][FTE]Is #CLIENTONLY define really works?

Post by toneddu2000 »

Spike wrote:rendering wise, GLSCR_UpdateScreen is the function that's meant to be responsible for throwing everything at the screen. So if you're trying to walk through FTE's rendering stages, start there. There shouldn't be any drawing elsewhere.
Thanks a lot Spike, that's what I was trying to do
Spike wrote:pr_csqc.c contains most of the csqc-only builtins (any externally-visible gunctions are meant to have a CSQC_ prefix, while builtins follow the PF_ prefix), with pr_cmds.c giving the ssqc-only ones, with pr_menu.qc giving the menu-only ones, supposedly. pr_bgcmd.c contains the generic builtins that might be used by any vm, while pr_clcmd.c gives builtins shared between csqc+menuqc, and pr_skelobj.c giving the skeletal object, ragdoll, and a number of model-related builtins shared between csqc+ssqc.
That's important too. Are there parts of skeletal code that are shared with ssqc? Or, if I build an only client release, do I have all the skeletal stuff up and ready?
Spike wrote:gl_shadow.c's rtlights are sandwiched between two shader sort values called from somewhere inside gl_backend.c or so.
well, I'll try to look at that too
Spike wrote:but yeah, its a large project, with lots of legacy, the more you play with it, the more you'll understand it - practise makes perfect.... or something.
LOL
Meadow Fun!! - my first commercial game, made with FTEQW game engine
toneddu2000
Posts: 1395
Joined: Tue Feb 24, 2009 4:39 pm
Location: Italy

Re: [SOLVED][FTE]Is #CLIENTONLY define really works?

Post by toneddu2000 »

After 1 year (!) I followed your suggestion to use the wastes config and it worked, thanks Spike! The exe size ranged from 7MB to 3.5MB!
This is my copied config from the wastes (I left Vera Visions copyright to avoid irritating anyone)

Code: Select all

/***
*
*   Copyright (c) 2000-2019, Vera Visions. All rights reserved.
*
****/

/* Branding Defaults */
#define DISTRIBUTION "MEH"
#define DISTRIBUTIONLONG "Meh productions"
#define FULLENGINENAME "Meh game"
#define ENGINEWEBSITE "https://www.meh-whatever.com/"
#define BRANDING_ICON "meh.ico"

/* FS rebranding */
#define GAME_SHORTNAME		"meh"
#define GAME_FULLNAME		FULLENGINENAME
#define GAME_BASEGAMES		GAME_SHORTNAME
#define GAME_PROTOCOL		"MEH-PROTOCOL"
#define GAME_DEFAULTPORT	23000
//#define GAME_IDENTIFYINGFILES	NULL	//with multiple games, this string-list gives verification that the basedir is actually valid. if null, will just be assumed correct.
//#define GAME_DOWNLOADSURL	NULL	//url for the package manger to update from
//#define GAME_DEFAULTCMDS	NULL	//a string containing the things you want to 

/* Engine-side, fast routing */
#define ENGINE_ROUTING

/* Native menu replacing menuQC, will debut eventually */
#undef MENU_NATIVECODE

#ifndef GLQUAKE
#define GLQUAKE
#endif

#ifndef VKQUAKE
#define VKQUAKE
#endif

//#define PLUGINS
#define QUAKETC
#define AVAIL_OPENAL
//#define AVAIL_ZLIB
//#define AVAIL_OGGVORBIS
//#define IMAGEFMT_PCX
#define CL_MASTER
#define CSQC_DAT
//#define MENU_DAT
#define PSET_SCRIPT
//#define VOICECHAT
#define RTLIGHTS
#define LOADERTHREAD
#define USEAREAGRID
#define USERBE
//#define IMAGEFMT_DDS
#define DECOMPRESS_ETC2
#define DECOMPRESS_RGTC
#define DECOMPRESS_S3TC
#define DECOMPRESS_BPTC			//bc6+bc7
#define NOBUILTINMENUS
#define NOLEGACY
#define AVAIL_DINPUT
//#define IMAGEFMT_BMP
#define HAVE_TCP
#define HAVE_PACKET
//#define SUPPORT_ICE

#ifndef MULTITHREAD
#define MULTITHREAD
#endif

#ifndef DEBUG
#define NOQCDESCRIPTIONS 2 //if 2, disables writing fteextensions.qc completely.
#endif

// Various package formats
#define PACKAGE_PK3
//#define PACKAGE_TEXWAD
//#define PACKAGE_Q1PAK

// Map formats
#define Q3BSPS
//#define Q1BSPS
//#define TERRAIN

// Model formats, IQM/VVM and HLMDL for legacy maps
#define INTERQUAKEMODELS
//#define HALFLIFEMODELS

// What do we NOT want to use
#undef USE_INTERNAL_BULLET
#undef USE_INTERNAL_ODE
#undef PACKAGE_DOOMWAD
#undef PACKAGE_VPK
#undef DOOMWADS
#undef MAP_PROC
#undef Q2BSPS
#undef RFBSPS
#undef SPRMODELS
#undef SP2MODELS
#undef DSPMODELS
#undef MD1MODELS
#undef MD2MODELS
#undef MD3MODELS
#undef MD5MODELS
#undef ZYMOTICMODELS
#undef DPMMODELS
#undef PSKMODELS

#undef MVD_RECORDING //server can record MVDs.
#undef D3D9QUAKE
#undef D3D11QUAKE
#undef D3D8QUAKE
#undef AVAIL_WASAPI	//windows advanced sound api
#undef AVAIL_DSOUND
#undef BOTLIB_STATIC	//q3 botlib
#undef AVAIL_XZDEC	//.xz decompression
#undef HAVE_SPEEX	//.xz decompression
#undef AVAIL_GZDEC	//.gz decompression
#undef PACKAGE_DZIP	//.dzip special-case archive support
#undef AVAIL_PNGLIB	//.png image format support (read+screenshots)
#undef AVAIL_JPEGLIB	//.jpeg image format support (read+screenshots)
#undef AVAIL_MP3_ACM	//.mp3 support (in windows).
#undef IMAGEFMT_KTX
#undef IMAGEFMT_PKM
#undef IMAGEFMT_BLP	//legacy crap
#undef IMAGEFMT_VTF	//legacy crap
#undef NETPREPARSE	//allows for running both nq+qw on the same server (if not, protocol used must match gamecode).
#undef USE_SQLITE	//sql-database-as-file support
#undef QUAKESTATS	//defines STAT_HEALTH etc. if omitted, you'll need to provide that functionality yourself.
#undef QUAKEHUD		//support for drawing the vanilla hud.
#undef QWSKINS		//disabling this means no qw .pcx skins nor enemy/team skin/colour forcing
#undef SVRANKING	//legacy server-side ranking system.
#undef RAGDOLL		//ragdoll support. requires RBE support.
#undef HUFFNETWORK	//crappy network compression. probably needs reseeding.
#undef SVCHAT		//ancient lame builtin to support NPC-style chat...
#undef VM_Q1		//q1qvm implementation, to support ktx.
#undef Q2SERVER		//q2 server+gamecode.
#undef Q2CLIENT		//q2 client. file formats enabled separately.
#undef Q3CLIENT		//q3 client stuff.
#undef Q3SERVER		//q3 server stuff.
#undef HEXEN2		//runs hexen2 gamecode, supports hexen2 file formats.
#undef NQPROT		//act as an nq client/server, with nq gamecode.
////#undef WEBSERVER	//sv_ftp + sv_http cvars.
#undef WEBCLIENT	//uri_get+any internal downloads etc
#undef RUNTIMELIGHTING	//automatic generation of .lit files
#undef R_XFLIP		//old silly thing
#undef TEXTEDITOR	//my funky text editor! its awesome!
#undef TCPCONNECT	//support for playing over tcp sockets, instead of just udp. compatible with qizmo.
#undef IRCCONNECT	//lame support for routing game packets via irc server. not a good idea.
#undef PSET_CLASSIC	//support the 'classic' particle system, for that classic quake feel.
#undef HAVE_CDPLAYER	//includes cd playback. actual cds. named/numbered tracks are supported regardless (though you need to use the 'music' command to play them without this).
////#undef QTERM
#undef SIDEVIEWS
#undef MAX_SPLITS
#undef SUBSERVERS
////#undef SV_MASTER
#undef HAVE_MIXER	//openal only
#undef VM_LUA
#undef HLCLIENT
#undef HLSERVER
#undef FTPSERVER
//#undef CLIENTONLY	//leave this up to the makefiles.
#undef HAVE_GNUTLS	//linux tls/dtls support
#undef HAVE_WINSSPI	//windows tls/dtls support
#undef HAVE_JUKEBOX	//includes built-in jukebox crap
#undef HAVE_MEDIA_DECODER	//can play cin/roq, more with plugins
#undef HAVE_MEDIA_ENCODER	//capture/capturedemo work.
#undef HAVE_SPEECHTOTEXT	//windows speech-to-text thing
//#define SAVEDGAMES			//Can save the game.
#undef PACKAGEMANAGER			//Allows the user to enable/disable/download packages and plugins.
#undef HEADLESSQUAKE
#undef WAYLANDQUAKE
#undef AVAIL_FREETYPE	// for truetype font rendering
#undef SERVER_DEMO_PLAYBACK	//outdated crap

//FIXME
//#define HAVE_OPUS
//#define HAVE_OPENSSL
//#define IMAGEFMT_HDR
//#define IMAGEFMT_PBM
//#define IMAGEFMT_PSD
//#define IPLOG
//#define AVAIL_BOTLIB
//#define AVAIL_BZLIB

#ifdef COMPILE_OPTS
//things to configure qclib, which annoyingly doesn't include this file itself
-DOMIT_QCC	//disable the built-in qcc 
-DSIMPLE_QCVM	//disable qc debugging and 32bit opcodes
#ifndef AVAIL_ZLIB
-DNO_ZLIB	//disable zlib
#endif

#ifdef USE_INTERNAL_BULLET	//makefile will respond to this by trying to link bullet into the engine itself, instead of as a plugin.
-DLINK_INTERNAL_BULLET
#endif

-DNO_SPEEX	//disable static speex
#ifndef BOTLIB_STATIC
-DNO_BOTLIB	//disable static botlib
#endif

-DLIBVORBISFILE_STATIC

//-Os //optimise for size instead of speed. less cpu cache needed means that its sometimes faster anyway.
#endif

It runs ok, but if I put code like drawfill,drawstring,etc. after renderscene in CSQC_UpdateView it shutdown csqc with error message

Code: Select all

Detected attempt to draw framebuffer where framebuffer is not valid
R2D_Flush was set outside of SCR_UpdateScreen
In my commenting rampage I definately commented something that must be not commented, but what? :biggrin:

##EDIT##I noticed that also the wastes config gives same error, so probably must be in the fact that is client only
##EDIT2##if I add a variable that is triggered by input and according to that variable I print drawstring,drawfill,etc, it works. Apparently it shutdown when level is not completely loaded and a draw call is called. There's a way to detect is level is full loaded?
Meadow Fun!! - my first commercial game, made with FTEQW game engine
Spike
Posts: 2914
Joined: Fri Nov 05, 2004 3:12 am
Location: UK
Contact:

Re: [SOLVED][FTE]Is #CLIENTONLY define really works?

Post by Spike »

You're only allowed to throw stuff at the screen during CSQC_UpdateView or CSQC_UpdateViewLoading calls. If you're trying to draw within the callstack of any other entry point then you'll get those sorts of errors.
As a special exception, drawing to render targets is permitted elsewhere (as the results may still be useful).

Violating this rule is pointless as the next call to CSQC_UpdateView will scribble over everything anyway.
And these are warnings, not errors, if its shutting down then that's being caused by something else.
toneddu2000
Posts: 1395
Joined: Tue Feb 24, 2009 4:39 pm
Location: Italy

Re: [SOLVED][FTE]Is #CLIENTONLY define really works?

Post by toneddu2000 »

You're only allowed to throw stuff at the screen during CSQC_UpdateView or CSQC_UpdateViewLoading calls. If you're trying to draw within the callstack of any other entry point then you'll get those sorts of errors.
I jush test it with my latest release of Meadow Fun!!, which it's now online since January (so I guess it's pretty stable). With normal FTE build no errors(even v5540), no warnings and of course no CSQC shutdown at all. The problem is when I use the stripped build from the wastes or the one derived from it (same shutdown).

All the draw* calls are inside CSQC_UpdateView, as always. It's just that the stripped build cannot handle it properly. No idea how, my VERY humble opinion is that, during map reload (is in that moment that CSQC shuts, between game map exit and map menu) client calls server and since there's no server in that build, it failed the R2D_Flush calls. You say, how can I be so sure about it?
Because, if I set

Code: Select all

float mytemp; //and set to FALSE in CSQC_Init()
and I trigger it to TRUE via input, any input key is valid
Then in CSQC_UpdateView I put

Code: Select all

void CSQC_UpdateView(float vwidth, float vheight, float notmenu)
{
  clearscene();
  //my update view stuff
  renderscene();
  //postupdate starts here
  if(mytemp) {
    drawstring()
    drawfill()
    etc.
  }
}
and I trigger it in any moment AFTER the level is loaded (1 second, 2 seconds, it's the same).. now it works, because it doesn't render BETWEEN level loading. At least this is what I thought
Meadow Fun!! - my first commercial game, made with FTEQW game engine
Post Reply