Skip to content

EliteForce

Zack Middleton edited this page May 2, 2021 · 19 revisions

Elite Force Multiplayer Engine notes (based on Thilo Schulz' ioEF engine).

The EF MP game logic / UI code currently is only available under an EULA that cannot be used with Spearmint which is GPLv3+ (with additional terms from RTCW/ET).

Missing from Spearmint Engine

  • Quite a few new refEntity_t types (RT_*), see tr_surface.c in iostvef patch.
    • Planning to add support for putting these in cgame if possible. See issue 168.

Porting Notes

These don't require changes to the Spearmint Engine.

+#ifdef ELITEFORCE
+	cl_maxpackets = Cvar_Get ("cl_maxpackets", "43", CVAR_ARCHIVE );
+#else
 	cl_maxpackets = Cvar_Get ("cl_maxpackets", "30", CVAR_ARCHIVE );
+#endif
  • Replaced RF_FULLBRIGHT, which used fixed ambient light value of 0x7F and disabled directed light. It's used by the holodeck door at level load. Example of how to replace RF_FULLBRIGHT below:
refEntity_t doorbox;
...
// use fixed ambient light and disabled directed light
doorbox.renderfx |= ( RF_CONST_AMBIENT | RF_NO_DIRECTED_LIGHT );
// RGB ambient light values
doorbox.ambientLight[0] = 0x7F;
doorbox.ambientLight[1] = 0x7F;
doorbox.ambientLight[2] = 0x7F;
// add ent
trap_R_AddRefEntityToScene( &doorbox );
  • Q3 uses com_errorMessage cvar for this. EF CGame will need to check if com_errorMessage cvar is set and run err_dialog itself. May want to remove "Server disconnected - " from com_errorMessage.
 		// https://zerowing.idsoftware.com/bugzilla/show_bug.cgi?id=552
 		// allow server to indicate why they were disconnected
 		if ( argc >= 2 )
+		{
+			#ifdef ELITEFORCE
+			Cbuf_AddText(va("err_dialog \"%s\"", Cmd_Argv(1)));
+			#endif
 			Com_Error( ERR_SERVERDISCONNECT, "Server disconnected - %s", Cmd_Argv( 1 ) );
+		}
 		else
+		{
+			#ifdef ELITEFORCE
+			Cbuf_AddText(va("err_dialog \"%s\"", Cmd_Argv(1)));
+			#endif
 			Com_Error( ERR_SERVERDISCONNECT, "Server disconnected" );
+		}
  • Can make EF use indexes like Q3. It might be nice to get strings (i.e. UDP) from Spearmint engine, but not sure duplicate them for each server is a great idea.
+#ifdef ELITEFORCE
+			Info_SetValueForKey( cl_pinglist[i].info, "nettype", str);
+#else
+			Info_SetValueForKey( cl_pinglist[i].info, "nettype", va("%d", type));
+#endif
  • trap_R_RegisterShader3D(name) is the same as trap_R_RegisterShaderEx(name, LIGHTMAP_NONE, qtrue/*mipmap*/); in Spearmint. CG_CVAR_SET_NO_MODIFY just returns 0, so just remove or add dummy function.
+        CG_R_REGISTERSHADER3D,  //59
+        CG_CVAR_SET_NO_MODIFY,  // 60 // ZTM: just returns 0 in iostvef
...
+	case CG_R_REGISTERSHADER3D:
+		return re.RegisterShader3D( VMA(1) );
+	case CG_CVAR_SET_NO_MODIFY:
+		return qfalse;
  • Can handle start background track change in CGame VM if needed.
 	case CG_S_STARTBACKGROUNDTRACK:
-		S_StartBackgroundTrack( VMA(1), VMA(2) );
+#ifdef ELITEFORCE
+		if(!VMA(1) || !*((char *) VMA(1)))
+			S_StopBackgroundTrack();
+		else
+#endif
+			S_StartBackgroundTrack(VMA(1), VMA(2));
  • Missing DEUTSCH sound support. Possible to do in CGame VM though.
+#ifdef ELITEFORCE
+int sem = qtrue;
+#define VOXDIR "sound/voice"
+
+void *S_MangleNameEF(char *filename, snd_info_t *info)
+{
+	char localName[MAX_QPATH];
+
+	if(
+	    !Q_strncmp(filename, VOXDIR, ARRAY_LEN(VOXDIR) - 1) &&
+	    !Q_stricmp(Cvar_VariableString("s_language"), "DEUTSCH")
+	  )
+	{
+		Q_strncpyz(localName, filename, MAX_QPATH - 10);
+	
+		localName[8] = 'x';
+		localName[9] = '_';
+		localName[10] = 'd';
+	
+		return S_CodecGetSound(localName, info);
+	}
+
+	return NULL;
+}
+#endif
+
  • Add wrapper in gamecode or fix code depending on this, since the original qvms won't be run.
+#ifdef ELITEFORCE
+	// obviously Raven fucked this up. They seem to expect a SURF_NOIMPACT flag if the trace
+	// went through to the end, or the game will crash when firing the dreadnought weapon and
+	// it doesn't hit anything.
+	tw.trace.surfaceFlags = SURF_NOIMPACT;
+#endif
  • Console changes, can do in CGame VM (now that console has been moved there).
+#ifdef ELITEFORCE
+	cls.charSetShader = re.RegisterShaderNoMip( "gfx/2d/charsgrid_med" );
+#else
 	cls.charSetShader = re.RegisterShader( "gfx/2d/bigchars" );
+#endif
...
+		#ifdef ELITEFORCE
+		color[0] = 0;
+		color[1] = 0;
+		color[2] = 0;
+		color[3] = 0.85;
+		re.SetColor(color);
+		#endif
 		SCR_DrawPic( 0, 0, SCREEN_WIDTH, y, cls.consoleShader );
  • Dummy sound. Set in Spearmint's mint-game.settings.
+#ifdef ELITEFORCE
+		S_Base_RegisterSound("sound/null.wav", qfalse); // Eliteforce specific sound.
+#else
 		S_Base_RegisterSound("sound/feedback/hit.wav", qfalse);		// changed to a sound in baseq3
+#endif

+#ifdef ELITEFORCE
+	default_sfx = S_AL_BufferFind("sound/null.wav");
+#else
 	default_sfx = S_AL_BufferFind("sound/feedback/hit.wav");
+#endif
  • Game VM has old BotSetChatName code, would need to update using newer Q3 code.

iostvef Difference Notes

Changes that don't seem to be present in Elite Force and were not included in Spearmint (as is, at least).

  • The increased defines below basically allow each patch aka grid surface to be four times as big. Seems harmless, uses more memory though. Given that JA has the same values as Q3, I'm assuming EF does as well (which could be a wrong assumption). The EF maps all load with the lower Q3/JA value on Linux x86_64. Why increase them? From forum posts online for various id Tech 3 games, Mac PPC would create more patch planes than Windows x86, resulting in Mac PPC players being unable to play some maps. (I haven't tested the official EF maps on PPC to see if it's needed.) This doesn't seem like the best solution as mappers will just make bigger patches and we'll end up with the same issue, right?
    • I'm currently disinclined to increase these unless there are official proprietary maps for an id Tech 3 game that need them increased.
    • I think the real issue would be solved by having the map compiler generate and save the planes and grid info (which means needing a new map format though).
-#define	MAX_FACETS			1024
-#define	MAX_PATCH_PLANES	2048
+#define	MAX_FACETS			4096
+#define	MAX_PATCH_PLANES	8192
  • MAX_SUBMODELS was increased from 256 to 8192. A) submodels are attached to entities, it doesn't make sense to allows 8 submodels per-entities (EF MP has 1024 entities max). B) q3/ef-mp cgame doesn't range check trap_CM_NumInlineModels() in CG_RegisterGraphics leading to buffer overflow if more than 256. C) modelindex only networks 8 bits (0 to 255), so it won't work correct in cgame. To use more than 256 you'd probably need to modified game/cgame VMs. I increased MAX_SUBMODELS to 1024 (same as q3map2) and fixed cgame/network issues in Spearmint (see here).
    • All the EF SP/MP maps load with MAX_SUBMODELS as 1024 in Spearmint. I suppose user EF maps could have more, though it would probably need modified q3map and game/cgame VMs.
    • Sounds like the max submodels was 256 in EF. I'm unsure if post is about SP or MP or both. http://www.ritualistic.com/forums/showthread.php?t=10908
    • q3map2 limits to 1024 (MAX_MAP_MODELS 0x400).
+	#define	MAX_SUBMODELS			8192
+	#define	BOX_MODEL_HANDLE		MAX_SUBMODELS-1
+	#define CAPSULE_MODEL_HANDLE		BOX_MODEL_HANDLE-2
Clone this wiki locally