1 #include "quakedef.h"
2 
3 #ifdef _WIN32
4 #include "winquake.h"
5 #endif
6 
7 #include "neh.h"
8 #if 0
9 #include "fmod/fmod.h"
10 #include "fmod/fmod_errors.h"
11 #endif
12 
13 int     smoketexture, DoFullbright;
14 int     NehGameType = 0;
15 int     modplaying = 0, mp3playing = 0;
16 
17 cvar_t  r_dynamicbothsides = {"r_dynamicbothsides", "0"}; // LordHavoc: dynamic lights no longer light backfaces
18 func_t RestoreGame;
19 
20 
21 // Ender
22 // ----------------------------------------------------------------------
23 // [FOG]  Gl Cvar's
24         cvar_t       gl_fogenable = {"gl_fogenable", "0"};
25         cvar_t       gl_fogdisable = {"gl_fogdisable", "0"}; // Overrides
26         cvar_t       gl_fogdensity = {"gl_fogdensity", "0.8"};
27         cvar_t       gl_fogred = {"gl_fogred","0.3"};
28         cvar_t       gl_fogblue = {"gl_fogblue","0.3"};
29         cvar_t       gl_foggreen = {"gl_foggreen","0.3"};
30         cvar_t       gl_skyclip = {"gl_skyclip", "4608"}; // Farclip for sky in fog
31         cvar_t       gl_skyfix = {"gl_skyfix", "1"};	  // Fix to draw skybox over world (multitexture only)
32 	qboolean     gl_do_skyfix; // Combines all conditions for performing skyfix
33 
34 
35 // [INT]  Interpolation
36         cvar_t  r_interpolate_model_animation = {"r_interpolate_model_animation", "1", true};
37         cvar_t  r_interpolate_model_transform = {"r_interpolate_model_transform", "1", true};
38 
39 // [APH]  Model_Alpha
40         cvar_t       gl_notrans = {"gl_notrans", "0"};
41         float        model_alpha;
42 
43 // [DEM]  Cutscene demo usage
44         cvar_t  nehx00 = {"nehx00", "0"};cvar_t nehx01 = {"nehx01", "0"};
45         cvar_t  nehx02 = {"nehx02", "0"};cvar_t nehx03 = {"nehx03", "0"};
46         cvar_t  nehx04 = {"nehx04", "0"};cvar_t nehx05 = {"nehx05", "0"};
47         cvar_t  nehx06 = {"nehx06", "0"};cvar_t nehx07 = {"nehx07", "0"};
48         cvar_t  nehx08 = {"nehx08", "0"};cvar_t nehx09 = {"nehx09", "0"};
49         cvar_t  nehx10 = {"nehx10", "0"};cvar_t nehx11 = {"nehx11", "0"};
50         cvar_t  nehx12 = {"nehx12", "0"};cvar_t nehx13 = {"nehx13", "0"};
51         cvar_t  nehx14 = {"nehx14", "0"};cvar_t nehx15 = {"nehx15", "0"};
52         cvar_t  nehx16 = {"nehx16", "0"};cvar_t nehx17 = {"nehx17", "0"};
53         cvar_t  nehx18 = {"nehx18", "0"};cvar_t nehx19 = {"nehx19", "0"};
54         cvar_t  cutscene = {"cutscene", "1"};
55 
56 // [EVL]  Evaluation Shortcuts
57         int eval_gravity, eval_items2, eval_alpha, eval_fullbright;
58         int eval_idealpitch, eval_pitch_speed;
59 
60 // [MOD]  FMOD stuff
61         FMUSIC_MODULE *mod = NULL;
62         cvar_t        modvolume = {"modvolume", "0.5"};
63 
64 // [MSC]  Misc
65         cvar_t       gl_rsmoke = {"gl_rsmoke", "1"};
66         cvar_t       nospr32   = {"nospr32", "0"};
67         cvar_t       slowmo    = {"slowmo", "1.0"};
68         cvar_t       r_waterripple = {"r_waterripple", "3"};
69         cvar_t       tweak = {"tweak", "1"};
70 
71 // Light Flare = 3,2,1
72 // Lighting Gun = 1,1,50
73 
74         cvar_t       gl_glows = {"gl_glows", "1", true};
75 
76         int  eval_gravity, num_sfxorig;
77         void NEH_sky(void);
78         void CheckMode(void);
79 
MOD_stop(void)80 void MOD_stop (void)
81 {
82 #if 0
83 	if (modplaying)
84 		FMUSIC_FreeSong (mod);
85 
86 	modplaying = 0;
87 #endif
88 }
89 
MOD_SetVolume_f(void)90 void MOD_SetVolume_f (void)
91 {
92 #if 0
93 	if (!modplaying)
94 		return;
95 
96 	FMUSIC_SetMasterVolume (mod, modvolume.value * 128);
97 #endif
98 }
99 
MOD_play(void)100 void MOD_play (void)
101 {
102 #if 0
103 	static char modname[256];
104 	char	    modfile[256];
105 	char	    *buffer;
106 	int	    mark;
107 
108 	if (modplaying)
109 	{
110 		if (!strcmp(modname, Cmd_Argv(1)))
111 			return; // Ignore repeated play commands of the same song
112 
113 		MOD_stop ();
114 	}
115 
116 	strcpy (modname, Cmd_Argv(1));
117 
118 	if (strlen(modname) < 3)
119 	{
120 		Con_Print ("Format: PlayMod <filename.ext>\n");
121 		return;
122 	}
123 
124 	mark = Hunk_LowMark ();
125 	buffer = (char *)COM_LoadHunkFile (modname);
126 
127 	if (!buffer)
128 	{
129 		Hunk_FreeToLowMark (mark);
130 		Con_Printf ("Couldn't find: %s\n", Cmd_Argv(1));
131 		return;
132 	}
133 #ifdef _WIN32
134 	mod = FMUSIC_LoadSongMemory (buffer, com_filesize);
135 #endif
136 	Hunk_FreeToLowMark (mark);
137 
138 	if (!mod)
139 	{
140 		Con_Printf ("%s\n", FMOD_ErrorString(FSOUND_GetError()));
141 		return;
142 	}
143 
144 	modplaying = 1;
145 	MOD_SetVolume_f ();
146 	FMUSIC_PlaySong (mod);
147 #endif
148 }
149 
MOD_init(void)150 void MOD_init(void)
151 {
152 #if 0
153 	if (COM_CheckParm("-nosound"))
154 		return;
155 
156 	FSOUND_SetBufferSize(300);
157 
158 	if (!FSOUND_Init(11025, 32, 0)) // Ender: Changed init frequency
159 	{
160 		Con_Printf("%s\n", FMOD_ErrorString(FSOUND_GetError()));
161 		return;
162 	}
163 
164 	FSOUND_SetMixer(FSOUND_MIXER_AUTODETECT);
165 
166 	switch (FSOUND_GetMixer())
167 	{
168 		case FSOUND_MIXER_BLENDMODE:     Con_Printf("FSOUND_MIXER_BLENDMODE\n");     break;
169 		case FSOUND_MIXER_MMXP5:         Con_Printf("FSOUND_MIXER_MMXP5\n");         break;
170 		case FSOUND_MIXER_MMXP6:         Con_Printf("FSOUND_MIXER_MMXP6\n");         break;
171 		case FSOUND_MIXER_QUALITY_FPU:   Con_Printf("FSOUND_MIXER_QUALITY_FPU\n");   break;
172 		case FSOUND_MIXER_QUALITY_MMXP5: Con_Printf("FSOUND_MIXER_QUALITY_MMXP5\n"); break;
173 		case FSOUND_MIXER_QUALITY_MMXP6: Con_Printf("FSOUND_MIXER_QUALITY_MMXP6\n"); break;
174 	}
175 
176 	// Con_Printf("%s\n", FSOUND_GetDriverName(FSOUND_GetDriver()));
177 
178 	Cvar_RegisterVariable (&modvolume);
179 	Cmd_AddCommand ("stopmod",MOD_stop);
180 	Cmd_AddCommand ("playmod",MOD_play);
181 #endif
182 }
183 
MOD_done(void)184 void MOD_done (void)
185 {
186 #if 0
187 	FSOUND_Close ();
188 #endif
189 }
190 
pausedemo(void)191 void pausedemo (void)
192 {
193 	if (cls.demopaused)
194 		Con_Printf ("Unpaused demo\n");
195 	else
196 		Con_Printf ("Paused demo\n");
197 
198 	cls.demopaused = !cls.demopaused;
199 }
200 
fog(void)201 void fog (void)
202 {
203 	if (Cmd_Argc() < 2 || Cmd_Argc() > 5)
204 	{
205 		Con_Printf ("usage:\n");
206 		Con_Printf ("   fog <density>\n");
207 		Con_Printf ("   fog <density> <rgb>\n");
208 		Con_Printf ("   fog <red> <green> <blue>\n");
209 		Con_Printf ("   fog <density> <red> <green> <blue>\n");
210 		Con_Printf("current values:\n");
211 		Con_Printf("   fog is %sabled%s\n", gl_fogenable.value ? "en" : "dis", gl_fogenable.value && gl_fogdisable.value ? " but blocked" : "");
212 		Con_Printf("   density is %g\n", gl_fogdensity.value);
213 		Con_Printf("   red   is %g\n", gl_fogred.value);
214 		Con_Printf("   green is %g\n", gl_foggreen.value);
215 		Con_Printf("   blue  is %g\n", gl_fogblue.value);
216 		return;
217 	}
218 
219 	if (Cmd_Argc() == 2 && atof(Cmd_Argv(1)) == 0)
220 	{
221 		// Disable
222 		Cvar_SetValue ("gl_fogenable", 0);
223 		Cvar_SetValue ("gl_fogdensity", 0);
224 		return;
225 	}
226 
227 	Cvar_SetValue ("gl_fogenable", 1);
228 
229 	if (Cmd_Argc() != 4)
230 		Cvar_Set ("gl_fogdensity", Cmd_Argv(1));
231 
232 	if (Cmd_Argc() == 3)
233 	{
234 		// RGB
235 		Cvar_Set ("gl_fogred", Cmd_Argv(2));
236 		Cvar_Set ("gl_foggreen", Cmd_Argv(2));
237 		Cvar_Set ("gl_fogblue", Cmd_Argv(2));
238 	}
239 	else if (Cmd_Argc() > 3)
240 	{
241 		// Separate colours
242 		Cvar_Set ("gl_fogred", Cmd_Argv(Cmd_Argc() - 3));
243 		Cvar_Set ("gl_foggreen", Cmd_Argv(Cmd_Argc() - 2));
244 		Cvar_Set ("gl_fogblue", Cmd_Argv(Cmd_Argc() - 1));
245 	}
246 }
247 
FindFieldOffset(char * field)248 int FindFieldOffset(char *field)
249 {
250 	ddef_t *d;
251 	d = ED_FindField(field);
252 	if (!d)
253 		return 0;
254 	return d->ofs*4;
255 }
256 
FindEdictFieldOffsets()257 void FindEdictFieldOffsets() {
258         dfunction_t *f;
259 
260 	eval_gravity = FindFieldOffset("gravity");
261 	eval_alpha = FindFieldOffset("alpha");
262 	eval_fullbright = FindFieldOffset("fullbright");
263 	eval_idealpitch = FindFieldOffset("idealpitch");
264 	eval_pitch_speed = FindFieldOffset("pitch_speed");
265 
266         RestoreGame = 0;
267         if ((f = ED_FindFunction ("RestoreGame")) != NULL)
268            RestoreGame = (func_t)(f - pr_functions);
269 }
270 
DoBindings(void)271 void DoBindings(void)
272 {
273 	if (NehGameType != TYPE_DEMO)
274 		return;
275 
276 	// Never worked properly, doubtful if desired
277 
278 /*	Cbuf_InsertText ("bind F1 \"slowmo 0.4\"\n");
279 	Cbuf_InsertText ("bind F2 \"slowmo 0.6\"\n");
280 	Cbuf_InsertText ("bind F3 \"slowmo 0.8\"\n");
281 
282 	Cbuf_InsertText ("bind F4 \"slowmo 1.0\"\n");
283 	Cbuf_InsertText ("bind F5 \"slowmo 1.4\"\n");
284 	Cbuf_InsertText ("bind F6 \"slowmo 1.6\"\n");
285 	Cbuf_InsertText ("bind F7 \"slowmo 1.8\"\n");
286 
287 	Cbuf_InsertText ("bind F8 \"slowmo 2.0\"\n");
288 	Cbuf_InsertText ("bind F9 \"slowmo 2.4\"\n");
289 	Cbuf_InsertText ("bind F10 \"slowmo 2.6\"\n");
290 
291 	Cbuf_InsertText ("bind PAUSE pausedemo\n");*/
292 }
293 
Neh_Init(void)294 void Neh_Init(void)
295 {
296 	// Fog
297 	Cvar_RegisterVariable (&gl_fogenable);
298 	Cvar_RegisterVariable (&gl_fogdisable);
299 	Cvar_RegisterVariable (&gl_fogdensity);
300 	Cvar_RegisterVariable (&gl_fogred);
301 	Cvar_RegisterVariable (&gl_foggreen);
302 	Cvar_RegisterVariable (&gl_fogblue);
303 	Cvar_RegisterVariable (&gl_skyclip);
304 	Cvar_RegisterVariable (&gl_skyfix);
305 
306 
307 	Cvar_RegisterVariable (&gl_glows);
308 	Cvar_RegisterVariable (&r_interpolate_model_animation);
309 	Cvar_RegisterVariable (&r_interpolate_model_transform);
310 
311 	Cvar_RegisterVariable (&gl_rsmoke);
312 	Cvar_RegisterVariable (&r_waterripple);
313 	Cvar_RegisterVariable (&gl_notrans);
314 	Cvar_RegisterVariable (&nospr32);
315 
316 	// Nehahra uses these to pass data around cutscene demos
317 	Cvar_RegisterVariable (&nehx00);Cvar_RegisterVariable (&nehx01);
318 	Cvar_RegisterVariable (&nehx02);Cvar_RegisterVariable (&nehx03);
319 	Cvar_RegisterVariable (&nehx04);Cvar_RegisterVariable (&nehx05);
320 	Cvar_RegisterVariable (&nehx06);Cvar_RegisterVariable (&nehx07);
321 	Cvar_RegisterVariable (&nehx08);Cvar_RegisterVariable (&nehx09);
322 	Cvar_RegisterVariable (&nehx10);Cvar_RegisterVariable (&nehx11);
323 	Cvar_RegisterVariable (&nehx12);Cvar_RegisterVariable (&nehx13);
324 	Cvar_RegisterVariable (&nehx14);Cvar_RegisterVariable (&nehx15);
325 	Cvar_RegisterVariable (&nehx16);Cvar_RegisterVariable (&nehx17);
326 	Cvar_RegisterVariable (&nehx18);Cvar_RegisterVariable (&nehx19);
327 
328 	Cvar_RegisterVariable (&cutscene);
329 	Cvar_RegisterVariable (&tweak);
330 	Cvar_RegisterVariable (&slowmo);
331 	Cmd_AddCommand ("pausedemo", pausedemo);
332 	Cmd_AddCommand ("fog", fog);
333 
334 	CheckMode ();
335 	DoBindings ();
336 
337 	if (COM_CheckParm ("-matrox"))
338 		nospr32.value = 1;
339 
340 	MOD_init ();
341 	DzipInit ();
342 }
343 
Neh_BeginFrame(void)344 void Neh_BeginFrame(void) // Called from gl_rmain.c (R_RenderView)
345 {
346 	if (gl_fogenable.value && !gl_fogdisable.value)
347 	{
348 		GLfloat colors[4] = {(GLfloat) gl_fogred.value, (GLfloat) gl_foggreen.value, (GLfloat) gl_fogblue.value, (GLfloat) 1};
349 		glFogi (GL_FOG_MODE, GL_EXP2);
350 		glFogf (GL_FOG_DENSITY, (GLfloat) gl_fogdensity.value / 100);
351 		glFogfv (GL_FOG_COLOR, colors);
352 		glEnable (GL_FOG);
353 	}
354 }
355 
Neh_EndFrame(void)356 void Neh_EndFrame (void)
357 {
358 	if (gl_fogenable.value && !gl_fogdisable.value)
359 		glDisable (GL_FOG);
360 }
361 
362 #define SHOWLMP_MAXLABELS 256
363 typedef struct showlmp_s
364 {
365 	qboolean	isactive;
366 	float		x;
367 	float		y;
368 	char		label[32];
369 	char		pic[128];
370 } showlmp_t;
371 
372 showlmp_t showlmp[SHOWLMP_MAXLABELS];
373 
SHOWLMP_decodehide()374 void SHOWLMP_decodehide()
375 {
376 	int i;
377 	byte *lmplabel;
378 	lmplabel = MSG_ReadString();
379 	for (i = 0;i < SHOWLMP_MAXLABELS;i++)
380 		if (showlmp[i].isactive && strcmp(showlmp[i].label, lmplabel) == 0)
381 		{
382 			showlmp[i].isactive = false;
383 			return;
384 		}
385 }
386 
SHOWLMP_decodeshow()387 void SHOWLMP_decodeshow()
388 {
389 	int i, k;
390 	byte lmplabel[256], picname[256];
391 	float x, y;
392 	strcpy(lmplabel,MSG_ReadString());
393 	strcpy(picname, MSG_ReadString());
394 	x = MSG_ReadByte();
395 	y = MSG_ReadByte();
396 	k = -1;
397 	for (i = 0;i < SHOWLMP_MAXLABELS;i++)
398 		if (showlmp[i].isactive)
399 		{
400 			if (strcmp(showlmp[i].label, lmplabel) == 0)
401 			{
402 				k = i;
403 				break; // drop out to replace it
404 			}
405 		}
406 		else if (k < 0) // find first empty one to replace
407 			k = i;
408 	if (k < 0)
409 		return; // none found to replace
410 	// change existing one
411 	showlmp[k].isactive = true;
412 	strcpy(showlmp[k].label, lmplabel);
413 	strcpy(showlmp[k].pic, picname);
414 	showlmp[k].x = x;
415 	showlmp[k].y = y;
416 }
417 
SHOWLMP_drawall()418 void SHOWLMP_drawall()
419 {
420 	int i;
421 	for (i = 0;i < SHOWLMP_MAXLABELS;i++)
422 		if (showlmp[i].isactive)
423 			Draw_TransPic(showlmp[i].x, showlmp[i].y, Draw_CachePic(showlmp[i].pic));
424 }
425 
SHOWLMP_clear()426 void SHOWLMP_clear()
427 {
428 	int i;
429 	for (i = 0;i < SHOWLMP_MAXLABELS;i++)
430 		showlmp[i].isactive = false;
431 }
432 
433 
CheckMode(void)434 void CheckMode (void)
435 {
436 	int h = 4, h2 = 5;
437 	int movieinstalled = 0, gameinstalled = 0;
438 
439 	//  Con_SafePrintf("Beginning check..\n");
440 	// Check for movies
441 
442 	if (COM_FindOnly ("hearing.dem") == 1)
443 		movieinstalled = 1;
444 	else if (COM_FindOnly ("hearing.dz") == 1)
445 		movieinstalled = 1;
446 
447 	//  Con_SafePrintf("Done Movie..\n");
448 
449 	// Check for game
450 
451 	if (COM_FindOnly ("maps/neh1m4.bsp") == 1)
452 		gameinstalled = 1;
453 
454 	//  Con_SafePrintf("Done Game..\n");
455 
456 	Con_SafePrintf ("\x02Nehahra type: ");
457 
458 	if (gameinstalled && movieinstalled)
459 	{
460 		NehGameType = TYPE_BOTH;             // mainmenu.lmp
461 		Con_SafePrintf ("Both\n");
462 		return;
463 	}
464 
465 	if (gameinstalled)
466 	{
467 		NehGameType = TYPE_GAME;             // gamemenu.lmp
468 		Con_SafePrintf ("Game\n");
469 		return;
470 	}
471 
472 	if (movieinstalled)
473 	{
474 		NehGameType = TYPE_DEMO;             // demomenu.lmp
475 		Con_SafePrintf ("Demo\n");
476 		return;
477 	}
478 
479 	Sys_Error ("You must specify the Nehahra game directory in -game!");
480 }
481 
Neh_GameStart(void)482 void Neh_GameStart (void) // From host_cmd.c
483 {
484 	if (RestoreGame)
485 	{
486 		 Con_SafePrintf ("Loading enhanced game - RestoreGame()\n");
487 		 pr_global_struct->time = sv.time;
488 		 pr_global_struct->self = EDICT_TO_PROG(sv_player);
489 		 PR_ExecuteProgram (RestoreGame);
490 	}
491 	else
492 		Con_SafePrintf ("Loading standard game - !RestoreGame()\n");
493 }
494