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