diff --git a/CODEmp/Splines/Splines.dsp b/CODE-mp/Splines/Splines.dsp similarity index 100% rename from CODEmp/Splines/Splines.dsp rename to CODE-mp/Splines/Splines.dsp diff --git a/CODEmp/Splines/math_angles.cpp b/CODE-mp/Splines/math_angles.cpp similarity index 100% rename from CODEmp/Splines/math_angles.cpp rename to CODE-mp/Splines/math_angles.cpp diff --git a/CODEmp/Splines/math_angles.h b/CODE-mp/Splines/math_angles.h similarity index 100% rename from CODEmp/Splines/math_angles.h rename to CODE-mp/Splines/math_angles.h diff --git a/CODEmp/Splines/math_matrix.cpp b/CODE-mp/Splines/math_matrix.cpp similarity index 100% rename from CODEmp/Splines/math_matrix.cpp rename to CODE-mp/Splines/math_matrix.cpp diff --git a/CODEmp/Splines/math_matrix.h b/CODE-mp/Splines/math_matrix.h similarity index 100% rename from CODEmp/Splines/math_matrix.h rename to CODE-mp/Splines/math_matrix.h diff --git a/CODEmp/Splines/math_quaternion.cpp b/CODE-mp/Splines/math_quaternion.cpp similarity index 100% rename from CODEmp/Splines/math_quaternion.cpp rename to CODE-mp/Splines/math_quaternion.cpp diff --git a/CODEmp/Splines/math_quaternion.h b/CODE-mp/Splines/math_quaternion.h similarity index 100% rename from CODEmp/Splines/math_quaternion.h rename to CODE-mp/Splines/math_quaternion.h diff --git a/CODEmp/Splines/math_vector.cpp b/CODE-mp/Splines/math_vector.cpp similarity index 100% rename from CODEmp/Splines/math_vector.cpp rename to CODE-mp/Splines/math_vector.cpp diff --git a/CODEmp/Splines/math_vector.h b/CODE-mp/Splines/math_vector.h similarity index 100% rename from CODEmp/Splines/math_vector.h rename to CODE-mp/Splines/math_vector.h diff --git a/CODE-mp/Splines/mssccprj.scc b/CODE-mp/Splines/mssccprj.scc new file mode 100644 index 0000000..a2ee319 --- /dev/null +++ b/CODE-mp/Splines/mssccprj.scc @@ -0,0 +1,5 @@ +SCC = This is a Source Code Control file + +[Splines.dsp] +SCC_Aux_Path = "\\ravend\vss_projects\jk2sof2MP" +SCC_Project_Name = "$/General/code/Splines", GAAAAAAA diff --git a/CODEmp/Splines/q_parse.cpp b/CODE-mp/Splines/q_parse.cpp similarity index 100% rename from CODEmp/Splines/q_parse.cpp rename to CODE-mp/Splines/q_parse.cpp diff --git a/CODEmp/Splines/q_shared.cpp b/CODE-mp/Splines/q_shared.cpp similarity index 100% rename from CODEmp/Splines/q_shared.cpp rename to CODE-mp/Splines/q_shared.cpp diff --git a/CODEmp/Splines/q_shared.h b/CODE-mp/Splines/q_shared.h similarity index 100% rename from CODEmp/Splines/q_shared.h rename to CODE-mp/Splines/q_shared.h diff --git a/CODEmp/Splines/splines.cpp b/CODE-mp/Splines/splines.cpp similarity index 100% rename from CODEmp/Splines/splines.cpp rename to CODE-mp/Splines/splines.cpp diff --git a/CODEmp/Splines/splines.h b/CODE-mp/Splines/splines.h similarity index 100% rename from CODEmp/Splines/splines.h rename to CODE-mp/Splines/splines.h diff --git a/CODEmp/Splines/util_list.h b/CODE-mp/Splines/util_list.h similarity index 100% rename from CODEmp/Splines/util_list.h rename to CODE-mp/Splines/util_list.h diff --git a/CODEmp/Splines/util_str.cpp b/CODE-mp/Splines/util_str.cpp similarity index 100% rename from CODEmp/Splines/util_str.cpp rename to CODE-mp/Splines/util_str.cpp diff --git a/CODEmp/Splines/util_str.h b/CODE-mp/Splines/util_str.h similarity index 100% rename from CODEmp/Splines/util_str.h rename to CODE-mp/Splines/util_str.h diff --git a/CODE-mp/Splines/vssver.scc b/CODE-mp/Splines/vssver.scc new file mode 100644 index 0000000..f4e973b Binary files /dev/null and b/CODE-mp/Splines/vssver.scc differ diff --git a/CODEmp/botlib/aasfile.h b/CODE-mp/botlib/aasfile.h similarity index 100% rename from CODEmp/botlib/aasfile.h rename to CODE-mp/botlib/aasfile.h diff --git a/CODEmp/botlib/be_aas_bsp.h b/CODE-mp/botlib/be_aas_bsp.h similarity index 100% rename from CODEmp/botlib/be_aas_bsp.h rename to CODE-mp/botlib/be_aas_bsp.h diff --git a/CODEmp/botlib/be_aas_bspq3.cpp b/CODE-mp/botlib/be_aas_bspq3.cpp similarity index 100% rename from CODEmp/botlib/be_aas_bspq3.cpp rename to CODE-mp/botlib/be_aas_bspq3.cpp diff --git a/CODEmp/botlib/be_aas_cluster.cpp b/CODE-mp/botlib/be_aas_cluster.cpp similarity index 100% rename from CODEmp/botlib/be_aas_cluster.cpp rename to CODE-mp/botlib/be_aas_cluster.cpp diff --git a/CODEmp/botlib/be_aas_cluster.h b/CODE-mp/botlib/be_aas_cluster.h similarity index 100% rename from CODEmp/botlib/be_aas_cluster.h rename to CODE-mp/botlib/be_aas_cluster.h diff --git a/CODEmp/botlib/be_aas_debug.cpp b/CODE-mp/botlib/be_aas_debug.cpp similarity index 100% rename from CODEmp/botlib/be_aas_debug.cpp rename to CODE-mp/botlib/be_aas_debug.cpp diff --git a/CODEmp/botlib/be_aas_debug.h b/CODE-mp/botlib/be_aas_debug.h similarity index 100% rename from CODEmp/botlib/be_aas_debug.h rename to CODE-mp/botlib/be_aas_debug.h diff --git a/CODEmp/botlib/be_aas_def.h b/CODE-mp/botlib/be_aas_def.h similarity index 100% rename from CODEmp/botlib/be_aas_def.h rename to CODE-mp/botlib/be_aas_def.h diff --git a/CODEmp/botlib/be_aas_entity.cpp b/CODE-mp/botlib/be_aas_entity.cpp similarity index 100% rename from CODEmp/botlib/be_aas_entity.cpp rename to CODE-mp/botlib/be_aas_entity.cpp diff --git a/CODEmp/botlib/be_aas_entity.h b/CODE-mp/botlib/be_aas_entity.h similarity index 100% rename from CODEmp/botlib/be_aas_entity.h rename to CODE-mp/botlib/be_aas_entity.h diff --git a/CODEmp/botlib/be_aas_file.cpp b/CODE-mp/botlib/be_aas_file.cpp similarity index 100% rename from CODEmp/botlib/be_aas_file.cpp rename to CODE-mp/botlib/be_aas_file.cpp diff --git a/CODEmp/botlib/be_aas_file.h b/CODE-mp/botlib/be_aas_file.h similarity index 100% rename from CODEmp/botlib/be_aas_file.h rename to CODE-mp/botlib/be_aas_file.h diff --git a/CODEmp/botlib/be_aas_funcs.h b/CODE-mp/botlib/be_aas_funcs.h similarity index 100% rename from CODEmp/botlib/be_aas_funcs.h rename to CODE-mp/botlib/be_aas_funcs.h diff --git a/CODEmp/botlib/be_aas_main.cpp b/CODE-mp/botlib/be_aas_main.cpp similarity index 100% rename from CODEmp/botlib/be_aas_main.cpp rename to CODE-mp/botlib/be_aas_main.cpp diff --git a/CODEmp/botlib/be_aas_main.h b/CODE-mp/botlib/be_aas_main.h similarity index 100% rename from CODEmp/botlib/be_aas_main.h rename to CODE-mp/botlib/be_aas_main.h diff --git a/CODEmp/botlib/be_aas_move.cpp b/CODE-mp/botlib/be_aas_move.cpp similarity index 100% rename from CODEmp/botlib/be_aas_move.cpp rename to CODE-mp/botlib/be_aas_move.cpp diff --git a/CODEmp/botlib/be_aas_move.h b/CODE-mp/botlib/be_aas_move.h similarity index 100% rename from CODEmp/botlib/be_aas_move.h rename to CODE-mp/botlib/be_aas_move.h diff --git a/CODEmp/botlib/be_aas_optimize.cpp b/CODE-mp/botlib/be_aas_optimize.cpp similarity index 100% rename from CODEmp/botlib/be_aas_optimize.cpp rename to CODE-mp/botlib/be_aas_optimize.cpp diff --git a/CODEmp/botlib/be_aas_optimize.h b/CODE-mp/botlib/be_aas_optimize.h similarity index 100% rename from CODEmp/botlib/be_aas_optimize.h rename to CODE-mp/botlib/be_aas_optimize.h diff --git a/CODEmp/botlib/be_aas_reach.cpp b/CODE-mp/botlib/be_aas_reach.cpp similarity index 100% rename from CODEmp/botlib/be_aas_reach.cpp rename to CODE-mp/botlib/be_aas_reach.cpp diff --git a/CODEmp/botlib/be_aas_reach.h b/CODE-mp/botlib/be_aas_reach.h similarity index 100% rename from CODEmp/botlib/be_aas_reach.h rename to CODE-mp/botlib/be_aas_reach.h diff --git a/CODEmp/botlib/be_aas_route.cpp b/CODE-mp/botlib/be_aas_route.cpp similarity index 100% rename from CODEmp/botlib/be_aas_route.cpp rename to CODE-mp/botlib/be_aas_route.cpp diff --git a/CODEmp/botlib/be_aas_route.h b/CODE-mp/botlib/be_aas_route.h similarity index 100% rename from CODEmp/botlib/be_aas_route.h rename to CODE-mp/botlib/be_aas_route.h diff --git a/CODEmp/botlib/be_aas_routealt.cpp b/CODE-mp/botlib/be_aas_routealt.cpp similarity index 100% rename from CODEmp/botlib/be_aas_routealt.cpp rename to CODE-mp/botlib/be_aas_routealt.cpp diff --git a/CODEmp/botlib/be_aas_routealt.h b/CODE-mp/botlib/be_aas_routealt.h similarity index 100% rename from CODEmp/botlib/be_aas_routealt.h rename to CODE-mp/botlib/be_aas_routealt.h diff --git a/CODEmp/botlib/be_aas_sample.cpp b/CODE-mp/botlib/be_aas_sample.cpp similarity index 100% rename from CODEmp/botlib/be_aas_sample.cpp rename to CODE-mp/botlib/be_aas_sample.cpp diff --git a/CODEmp/botlib/be_aas_sample.h b/CODE-mp/botlib/be_aas_sample.h similarity index 100% rename from CODEmp/botlib/be_aas_sample.h rename to CODE-mp/botlib/be_aas_sample.h diff --git a/CODEmp/botlib/be_ai_char.cpp b/CODE-mp/botlib/be_ai_char.cpp similarity index 100% rename from CODEmp/botlib/be_ai_char.cpp rename to CODE-mp/botlib/be_ai_char.cpp diff --git a/CODEmp/botlib/be_ai_chat.cpp b/CODE-mp/botlib/be_ai_chat.cpp similarity index 100% rename from CODEmp/botlib/be_ai_chat.cpp rename to CODE-mp/botlib/be_ai_chat.cpp diff --git a/CODEmp/botlib/be_ai_gen.cpp b/CODE-mp/botlib/be_ai_gen.cpp similarity index 100% rename from CODEmp/botlib/be_ai_gen.cpp rename to CODE-mp/botlib/be_ai_gen.cpp diff --git a/CODEmp/botlib/be_ai_goal.cpp b/CODE-mp/botlib/be_ai_goal.cpp similarity index 100% rename from CODEmp/botlib/be_ai_goal.cpp rename to CODE-mp/botlib/be_ai_goal.cpp diff --git a/CODEmp/botlib/be_ai_move.cpp b/CODE-mp/botlib/be_ai_move.cpp similarity index 100% rename from CODEmp/botlib/be_ai_move.cpp rename to CODE-mp/botlib/be_ai_move.cpp diff --git a/CODEmp/botlib/be_ai_weap.cpp b/CODE-mp/botlib/be_ai_weap.cpp similarity index 100% rename from CODEmp/botlib/be_ai_weap.cpp rename to CODE-mp/botlib/be_ai_weap.cpp diff --git a/CODEmp/botlib/be_ai_weight.cpp b/CODE-mp/botlib/be_ai_weight.cpp similarity index 100% rename from CODEmp/botlib/be_ai_weight.cpp rename to CODE-mp/botlib/be_ai_weight.cpp diff --git a/CODEmp/botlib/be_ai_weight.h b/CODE-mp/botlib/be_ai_weight.h similarity index 100% rename from CODEmp/botlib/be_ai_weight.h rename to CODE-mp/botlib/be_ai_weight.h diff --git a/CODEmp/botlib/be_ea.cpp b/CODE-mp/botlib/be_ea.cpp similarity index 100% rename from CODEmp/botlib/be_ea.cpp rename to CODE-mp/botlib/be_ea.cpp diff --git a/CODEmp/botlib/be_interface.cpp b/CODE-mp/botlib/be_interface.cpp similarity index 96% rename from CODEmp/botlib/be_interface.cpp rename to CODE-mp/botlib/be_interface.cpp index 022bb48..274beee 100644 --- a/CODEmp/botlib/be_interface.cpp +++ b/CODE-mp/botlib/be_interface.cpp @@ -857,6 +857,8 @@ botlib_export_t *GetBotLibAPI(int apiVersion, botlib_import_t *import) { be_botlib_export.PC_FreeSourceHandle = PC_FreeSourceHandle; be_botlib_export.PC_ReadTokenHandle = PC_ReadTokenHandle; be_botlib_export.PC_SourceFileAndLine = PC_SourceFileAndLine; + be_botlib_export.PC_LoadGlobalDefines = PC_LoadGlobalDefines; + be_botlib_export.PC_RemoveAllGlobalDefines = PC_RemoveAllGlobalDefines; be_botlib_export.BotLibStartFrame = Export_BotLibStartFrame; be_botlib_export.BotLibLoadMap = Export_BotLibLoadMap; diff --git a/CODEmp/botlib/be_interface.h b/CODE-mp/botlib/be_interface.h similarity index 100% rename from CODEmp/botlib/be_interface.h rename to CODE-mp/botlib/be_interface.h diff --git a/CODEmp/botlib/botlib.dsp b/CODE-mp/botlib/botlib.dsp similarity index 100% rename from CODEmp/botlib/botlib.dsp rename to CODE-mp/botlib/botlib.dsp diff --git a/CODEmp/botlib/l_crc.cpp b/CODE-mp/botlib/l_crc.cpp similarity index 100% rename from CODEmp/botlib/l_crc.cpp rename to CODE-mp/botlib/l_crc.cpp diff --git a/CODEmp/botlib/l_crc.h b/CODE-mp/botlib/l_crc.h similarity index 100% rename from CODEmp/botlib/l_crc.h rename to CODE-mp/botlib/l_crc.h diff --git a/CODEmp/botlib/l_libvar.cpp b/CODE-mp/botlib/l_libvar.cpp similarity index 100% rename from CODEmp/botlib/l_libvar.cpp rename to CODE-mp/botlib/l_libvar.cpp diff --git a/CODEmp/botlib/l_libvar.h b/CODE-mp/botlib/l_libvar.h similarity index 100% rename from CODEmp/botlib/l_libvar.h rename to CODE-mp/botlib/l_libvar.h diff --git a/CODEmp/botlib/l_log.cpp b/CODE-mp/botlib/l_log.cpp similarity index 100% rename from CODEmp/botlib/l_log.cpp rename to CODE-mp/botlib/l_log.cpp diff --git a/CODEmp/botlib/l_log.h b/CODE-mp/botlib/l_log.h similarity index 100% rename from CODEmp/botlib/l_log.h rename to CODE-mp/botlib/l_log.h diff --git a/CODEmp/botlib/l_memory.cpp b/CODE-mp/botlib/l_memory.cpp similarity index 100% rename from CODEmp/botlib/l_memory.cpp rename to CODE-mp/botlib/l_memory.cpp diff --git a/CODEmp/botlib/l_memory.h b/CODE-mp/botlib/l_memory.h similarity index 100% rename from CODEmp/botlib/l_memory.h rename to CODE-mp/botlib/l_memory.h diff --git a/CODEmp/botlib/l_precomp.cpp b/CODE-mp/botlib/l_precomp.cpp similarity index 94% rename from CODEmp/botlib/l_precomp.cpp rename to CODE-mp/botlib/l_precomp.cpp index 2f7ac34..68efed7 100644 --- a/CODEmp/botlib/l_precomp.cpp +++ b/CODE-mp/botlib/l_precomp.cpp @@ -101,7 +101,12 @@ token_t *freetokens; //free tokens from the heap */ //list with global defines added to every source loaded -define_t *globaldefines; +#if DEFINEHASHING +define_t **globaldefines = NULL; +#else +define_t *globaldefines = NULL; +#endif +qboolean addGlobalDefine = qfalse; //============================================================================ // @@ -555,9 +560,21 @@ void PC_AddDefineToHash(define_t *define, define_t **definehash) { int hash; + + if ( addGlobalDefine ) + { + definehash = globaldefines; + define->flags |= DEFINE_GLOBAL; + } + hash = PC_NameHash(define->name); define->hashnext = definehash[hash]; definehash[hash] = define; + + if ( addGlobalDefine ) + { + define->globalnext = define->hashnext; + } } //end of the function PC_AddDefineToHash //============================================================================ // @@ -1117,12 +1134,16 @@ int PC_Directive_undef(source_t *source) if (define->flags & DEFINE_FIXED) { SourceWarning(source, "can't undef %s", token.string); - } //end if + } //end if else { if (lastdefine) lastdefine->hashnext = define->hashnext; else source->definehash[hash] = define->hashnext; - PC_FreeDefine(define); + + if ( !(define->flags & DEFINE_GLOBAL ) ) + { + PC_FreeDefine(define); + } } //end else break; } //end if @@ -1361,6 +1382,11 @@ int PC_AddDefine(source_t *source, char *string) { define_t *define; + if ( addGlobalDefine ) + { + return PC_AddGlobalDefine ( string ); + } + define = PC_DefineFromString(string); if (!define) return qfalse; #if DEFINEHASHING @@ -1380,12 +1406,14 @@ int PC_AddDefine(source_t *source, char *string) //============================================================================ int PC_AddGlobalDefine(char *string) { +#if !DEFINEHASHING define_t *define; define = PC_DefineFromString(string); if (!define) return qfalse; define->next = globaldefines; globaldefines = define; +#endif return qtrue; } //end of the function PC_AddGlobalDefine //============================================================================ @@ -1397,6 +1425,7 @@ int PC_AddGlobalDefine(char *string) //============================================================================ int PC_RemoveGlobalDefine(char *name) { +#if !DEFINEHASHING define_t *define; define = PC_FindDefine(globaldefines, name); @@ -1405,6 +1434,7 @@ int PC_RemoveGlobalDefine(char *name) PC_FreeDefine(define); return qtrue; } //end if +#endif return qfalse; } //end of the function PC_RemoveGlobalDefine //============================================================================ @@ -1418,11 +1448,27 @@ void PC_RemoveAllGlobalDefines(void) { define_t *define; +#if DEFINEHASHING + int i; + if ( globaldefines ) + { + for (i = 0; i < DEFINEHASHSIZE; i++) + { + while(globaldefines[i]) + { + define = globaldefines[i]; + globaldefines[i] = globaldefines[i]->globalnext; + PC_FreeDefine(define); + } + } + } +#else //DEFINEHASHING for (define = globaldefines; define; define = globaldefines) { globaldefines = globaldefines->next; PC_FreeDefine(define); } //end for +#endif } //end of the function PC_RemoveAllGlobalDefines //============================================================================ // @@ -1475,18 +1521,33 @@ define_t *PC_CopyDefine(source_t *source, define_t *define) //============================================================================ void PC_AddGlobalDefinesToSource(source_t *source) { - define_t *define, *newdefine; + define_t *define; +#if DEFINEHASHING + int i; + for (i = 0; i < DEFINEHASHSIZE; i++) + { + define = globaldefines[i]; + while(define) + { + define->hashnext = NULL; + PC_AddDefineToHash(define, source->definehash); + + define = define->globalnext; + } + } +#else //DEFINEHASHING + define_t* newdefine; for (define = globaldefines; define; define = define->next) { newdefine = PC_CopyDefine(source, define); -#if DEFINEHASHING - PC_AddDefineToHash(newdefine, source->definehash); -#else //DEFINEHASHING + + + newdefine->next = source->defines; source->defines = newdefine; -#endif //DEFINEHASHING - } //end for + } +#endif } //end of the function PC_AddGlobalDefinesToSource //============================================================================ // @@ -2982,6 +3043,13 @@ source_t *LoadSourceFile(const char *filename) PC_InitTokenHeap(); +#if DEFINEHASHING + if ( !globaldefines ) + { + globaldefines = (struct define_s **)GetClearedMemory(DEFINEHASHSIZE * sizeof(define_t *)); + } +#endif + script = LoadScriptFile(filename); if (!script) return NULL; @@ -3048,6 +3116,7 @@ void FreeSource(source_t *source) token_t *token; define_t *define; indent_t *indent; + define_t *nextdefine; int i; //PC_PrintDefineHashTable(source->definehash); @@ -3068,12 +3137,20 @@ void FreeSource(source_t *source) #if DEFINEHASHING for (i = 0; i < DEFINEHASHSIZE; i++) { - while(source->definehash[i]) + define = source->definehash[i]; + while(define) { - define = source->definehash[i]; - source->definehash[i] = source->definehash[i]->hashnext; - PC_FreeDefine(define); + nextdefine = define->hashnext; + + if ( !(define->flags & DEFINE_GLOBAL) ) + { + PC_FreeDefine(define); + } + + define = nextdefine; } //end while + + source->definehash[i] = NULL; } //end for #else //DEFINEHASHING //free all defines @@ -3145,6 +3222,28 @@ int PC_FreeSourceHandle(int handle) sourceFiles[handle] = NULL; return qtrue; } //end of the function PC_FreeSourceHandle + +int PC_LoadGlobalDefines ( const char* filename ) +{ + int handle; + token_t token; + + handle = PC_LoadSourceHandle ( filename ); + if ( handle < 1 ) + return qfalse; + + addGlobalDefine = qtrue; + + // Read all the token files which will add the defines globally + while ( PC_ReadToken(sourceFiles[handle], &token) ); + + addGlobalDefine = qfalse; + + PC_FreeSourceHandle ( handle ); + + return qtrue; +} + //============================================================================ // // Parameter: - diff --git a/CODEmp/botlib/l_precomp.h b/CODE-mp/botlib/l_precomp.h similarity index 93% rename from CODEmp/botlib/l_precomp.h rename to CODE-mp/botlib/l_precomp.h index 862f322..34a0aed 100644 --- a/CODEmp/botlib/l_precomp.h +++ b/CODE-mp/botlib/l_precomp.h @@ -37,6 +37,7 @@ #define DEFINE_FIXED 0x0001 +#define DEFINE_GLOBAL 0x0002 #define BUILTIN_LINE 1 #define BUILTIN_FILE 2 @@ -61,6 +62,7 @@ typedef struct define_s token_t *tokens; //macro tokens (possibly containing parm tokens) struct define_s *next; //next defined macro in a list struct define_s *hashnext; //next define in the hash chain + struct define_s *globalnext; //used to link up the globald defines } define_t; //indents @@ -161,3 +163,6 @@ int PC_FreeSourceHandle(int handle); int PC_ReadTokenHandle(int handle, pc_token_t *pc_token); int PC_SourceFileAndLine(int handle, char *filename, int *line); void PC_CheckOpenSourceHandles(void); +int PC_LoadGlobalDefines ( const char* filename ); +void PC_RemoveAllGlobalDefines ( void ); + diff --git a/CODEmp/botlib/l_script.cpp b/CODE-mp/botlib/l_script.cpp similarity index 100% rename from CODEmp/botlib/l_script.cpp rename to CODE-mp/botlib/l_script.cpp diff --git a/CODEmp/botlib/l_script.h b/CODE-mp/botlib/l_script.h similarity index 100% rename from CODEmp/botlib/l_script.h rename to CODE-mp/botlib/l_script.h diff --git a/CODEmp/botlib/l_struct.cpp b/CODE-mp/botlib/l_struct.cpp similarity index 100% rename from CODEmp/botlib/l_struct.cpp rename to CODE-mp/botlib/l_struct.cpp diff --git a/CODEmp/botlib/l_struct.h b/CODE-mp/botlib/l_struct.h similarity index 100% rename from CODEmp/botlib/l_struct.h rename to CODE-mp/botlib/l_struct.h diff --git a/CODEmp/botlib/l_utils.h b/CODE-mp/botlib/l_utils.h similarity index 100% rename from CODEmp/botlib/l_utils.h rename to CODE-mp/botlib/l_utils.h diff --git a/CODE-mp/botlib/mssccprj.scc b/CODE-mp/botlib/mssccprj.scc new file mode 100644 index 0000000..122048b --- /dev/null +++ b/CODE-mp/botlib/mssccprj.scc @@ -0,0 +1,5 @@ +SCC = This is a Source Code Control file + +[botlib.dsp] +SCC_Aux_Path = "\\ravend\vss_projects\jk2sof2MP" +SCC_Project_Name = "$/General/code/botlib", ACAAAAAA diff --git a/CODE-mp/botlib/vssver.scc b/CODE-mp/botlib/vssver.scc new file mode 100644 index 0000000..8ecae85 Binary files /dev/null and b/CODE-mp/botlib/vssver.scc differ diff --git a/CODE-mp/buildvms.bat b/CODE-mp/buildvms.bat new file mode 100644 index 0000000..00d402b --- /dev/null +++ b/CODE-mp/buildvms.bat @@ -0,0 +1,8 @@ +set include= +cd game +call game +cd ..\cgame +call cgame +cd ..\ui +call ui +cd .. diff --git a/CODEmp/cgame/JK2_cgame.def b/CODE-mp/cgame/JK2_cgame.def similarity index 100% rename from CODEmp/cgame/JK2_cgame.def rename to CODE-mp/cgame/JK2_cgame.def diff --git a/CODEmp/cgame/JK2_cgame.dsp b/CODE-mp/cgame/JK2_cgame.dsp similarity index 94% rename from CODEmp/cgame/JK2_cgame.dsp rename to CODE-mp/cgame/JK2_cgame.dsp index 798511b..74605a9 100644 --- a/CODEmp/cgame/JK2_cgame.dsp +++ b/CODE-mp/cgame/JK2_cgame.dsp @@ -354,6 +354,11 @@ SOURCE=..\ghoul2\G2.h # End Source File # Begin Source File +SOURCE=.\JK2_cgame.def +# PROP Exclude_From_Build 1 +# End Source File +# Begin Source File + SOURCE=..\ui\keycodes.h # End Source File # Begin Source File @@ -387,12 +392,12 @@ SOURCE=..\ui\ui_shared.h # End Group # Begin Source File -SOURCE=.\cg_syscalls.asm +SOURCE=.\cgame.bat # PROP Exclude_From_Build 1 # End Source File # Begin Source File -SOURCE=.\JK2_cgame.def +SOURCE=.\cgame.q3asm # PROP Exclude_From_Build 1 # End Source File # End Target diff --git a/CODEmp/cgame/animtable.h b/CODE-mp/cgame/animtable.h similarity index 90% rename from CODEmp/cgame/animtable.h rename to CODE-mp/cgame/animtable.h index 31a9964..f0b7a9d 100644 --- a/CODEmp/cgame/animtable.h +++ b/CODE-mp/cgame/animtable.h @@ -140,6 +140,8 @@ stringID_table_t animTable [MAX_ANIMATIONS+1] = ENUM2STRING(BOTH_MELEE4), //# Fourth melee attack ENUM2STRING(BOTH_MELEE5), //# Fifth melee attack ENUM2STRING(BOTH_MELEE6), //# Sixth melee attack + ENUM2STRING(BOTH_THERMAL_READY), //# pull back with thermal + ENUM2STRING(BOTH_THERMAL_THROW), //# throw thermal //* #sep ENUM2STRING(BOTH_ SABER ANIMS //Saber attack anims - power level 2 ENUM2STRING(BOTH_A1_T__B_), //# Fast weak vertical attack top to bottom @@ -637,7 +639,7 @@ stringID_table_t animTable [MAX_ANIMATIONS+1] = ENUM2STRING(BOTH_STAND1TOSTAND5), //# Transition from stand1 to stand5 ENUM2STRING(BOTH_STAND5TOSTAND1), //# Transition from stand5 to stand1 ENUM2STRING(BOTH_STAND5TOSTAND8), //# Transition from stand5 to stand8 - ENUM2STRING(BOTH_STAND8TOSTAND5), //# Transition from stand5 to stand8 + ENUM2STRING(BOTH_STAND8TOSTAND5), //# Transition from stand8 to stand5 ENUM2STRING(BOTH_CONSOLE1START), //# typing at a console ENUM2STRING(BOTH_CONSOLE1), //# typing at a console @@ -652,48 +654,6 @@ stringID_table_t animTable [MAX_ANIMATIONS+1] = ENUM2STRING(BOTH_GESTURE1), //# Generic gesture), non-specific ENUM2STRING(BOTH_GESTURE2), //# Generic gesture), non-specific ENUM2STRING(BOTH_GESTURE3), //# Generic gesture), non-specific - ENUM2STRING(BOTH_TALK1), //# Generic talk anim - ENUM2STRING(BOTH_TALKCOMM1START), //# Start talking into a comm link - ENUM2STRING(BOTH_TALKCOMM1), //# Talking into a comm link - ENUM2STRING(BOTH_TALKCOMM1STOP), //# Stop talking into a comm link - ENUM2STRING(BOTH_TALKGESTURE1), //# Generic talk anim - ENUM2STRING(BOTH_TALKGESTURE2), //# Generic talk anim - ENUM2STRING(BOTH_TALKGESTURE3), //# Generic talk anim - - ENUM2STRING(BOTH_TALKGESTURE4START), //# Beginning talk anim 4 - ENUM2STRING(BOTH_TALKGESTURE4), //# Talk gesture 4 - ENUM2STRING(BOTH_TALKGESTURE4STOP), //# Ending talk anim 4 - ENUM2STRING(BOTH_TALKGESTURE5START), //# Start hand on chin - ENUM2STRING(BOTH_TALKGESTURE5), //# Hand on chin - ENUM2STRING(BOTH_TALKGESTURE5STOP), //# Stop hand on chin - ENUM2STRING(BOTH_TALKGESTURE6START), //# Starting Motions to self - ENUM2STRING(BOTH_TALKGESTURE6), //# Pointing at self - ENUM2STRING(BOTH_TALKGESTURE6STOP), //# Ending Motions to self - ENUM2STRING(BOTH_TALKGESTURE7START), //# Start touches Kyle on shoulder - ENUM2STRING(BOTH_TALKGESTURE7), //# Hold touches Kyle on shoulder - ENUM2STRING(BOTH_TALKGESTURE7STOP), //# Ending touches Kyle on shoulder - ENUM2STRING(BOTH_TALKGESTURE8START), //# Lando's chin hold - ENUM2STRING(BOTH_TALKGESTURE8), //# Lando's chin hold - ENUM2STRING(BOTH_TALKGESTURE8STOP), //# Lando's chin hold - ENUM2STRING(BOTH_TALKGESTURE9), //# Same as gesture 2 but with the right hand - ENUM2STRING(BOTH_TALKGESTURE10), //# Shoulder shrug - ENUM2STRING(BOTH_TALKGESTURE11START), //# Arms folded across chest - ENUM2STRING(BOTH_TALKGESTURE11STOP), //# Arms folded across chest - ENUM2STRING(BOTH_TALKGESTURE12), //# Tavion taunting Kyle - ENUM2STRING(BOTH_TALKGESTURE13START), //# Luke warning Kyle - ENUM2STRING(BOTH_TALKGESTURE13), //# Luke warning Kyle - ENUM2STRING(BOTH_TALKGESTURE13STOP), //# Luke warning Kyle - ENUM2STRING(BOTH_TALKGESTURE14), //# Luke gesturing to Kyle - - ENUM2STRING(BOTH_TALKGESTURE15START), //# Desann taunting Kyle - ENUM2STRING(BOTH_TALKGESTURE15), //# Desann taunting Kyle - ENUM2STRING(BOTH_TALKGESTURE15STOP), //# Desann taunting Kyle - ENUM2STRING(BOTH_TALKGESTURE16), //# Bartender gesture cin #15 - ENUM2STRING(BOTH_TALKGESTURE17), //# Bartender gesture cin #15 - ENUM2STRING(BOTH_TALKGESTURE18), //# Bartender gesture cin #15 - ENUM2STRING(BOTH_TALKGESTURE19START), //# Desann lifting his arm "Join me" (cin #34) - ENUM2STRING(BOTH_TALKGESTURE19STOP), //# Desann lifting his arm "Join me" (cin #34) - ENUM2STRING(BOTH_TALKGESTURE20START), //# Kyle lifting his arm "Join us" (cin #34) ENUM2STRING(BOTH_PAUSE1START), //# Luke pauses to warn Kyle (cin #24) start ENUM2STRING(BOTH_PAUSE1STOP), //# Luke pauses to warn Kyle (cin #24) stop @@ -748,10 +708,14 @@ stringID_table_t animTable [MAX_ANIMATIONS+1] = ENUM2STRING(BOTH_SILENCEGESTURE1), //# Luke silencing Kyle with a raised hand (cin #37) ENUM2STRING(BOTH_REACHFORSABER1), //# Luke holding hand out for Kyle's saber (cin #37) ENUM2STRING(BOTH_PUNCHER1), //# Jan punching Kyle in the shoulder (cin #37) + ENUM2STRING(BOTH_CONSTRAINER1HOLD), //# Static pose of starting Tavion constraining Jan (cin #9) + ENUM2STRING(BOTH_CONSTRAINEE1HOLD), //# Static pose of starting Jan being constrained by Tavion (cin #9) ENUM2STRING(BOTH_CONSTRAINER1STAND), //# Tavion constraining Jan in a stand pose (cin #9) ENUM2STRING(BOTH_CONSTRAINEE1STAND), //# Jan being constrained in a stand pose (cin #9) - ENUM2STRING(BOTH_CONSTRAINER1WALK), //# Tavion constraining Jan in a walking loop (cin #9) - ENUM2STRING(BOTH_CONSTRAINEE1WALK), //# Jan being constrained in a walking loop (cin #9) + ENUM2STRING(BOTH_CONSTRAINER1WALK), //# Tavion shoving jan forward (cin #9) + ENUM2STRING(BOTH_CONSTRAINEE1WALK), //# Jan being shoved forward by Tavion (cin #9) + ENUM2STRING(BOTH_CONSTRAINER1LOOP), //# Tavion walking with Jan in a loop (cin #9) + ENUM2STRING(BOTH_CONSTRAINEE1LOOP), //# Jan walking with Tavion in a loop (cin #9) ENUM2STRING(BOTH_SABERKILLER1), //# Tavion about to strike Jan with saber (cin #9) ENUM2STRING(BOTH_SABERKILLEE1), //# Jan about to be struck by Tavion with saber (cin #9) ENUM2STRING(BOTH_HANDSHAKER1START), //# Luke shaking Kyle's hand (cin #37) @@ -762,26 +726,6 @@ stringID_table_t animTable [MAX_ANIMATIONS+1] = ENUM2STRING(BOTH_LAUGH1STOP), //# Reelo laughing (cin #18) ENUM2STRING(BOTH_ESCAPEPOD_LEAVE1), //# Kyle leaving escape pod (cin #33) ENUM2STRING(BOTH_ESCAPEPOD_LEAVE2), //# Jan leaving escape pod (cin #33) - ENUM2STRING(BOTH_HUGGER1), //# Kyle hugging Jan (cin #29) - ENUM2STRING(BOTH_HUGGERSTOP1), //# Kyle stop hugging Jan but don't let her go (cin #29) - ENUM2STRING(BOTH_HUGGERSTOP2), //# Kyle let go of Jan and step back (cin #29) - ENUM2STRING(BOTH_HUGGEE1), //# Jan being hugged (cin #29) - ENUM2STRING(BOTH_HUGGEESTOP1), //# Jan stop being hugged but don't let go (cin #29) - ENUM2STRING(BOTH_HUGGEESTOP2), //# Jan released from hug (cin #29) - ENUM2STRING(BOTH_KISSER1), //# Temp until the Kiss anim gets split up - ENUM2STRING(BOTH_KISSER1START1), //# Kyle start kissing Jan - ENUM2STRING(BOTH_KISSER1START2), //# Kyle start kissing Jan - ENUM2STRING(BOTH_KISSER1LOOP), //# Kyle loop kissing Jan - ENUM2STRING(BOTH_KISSER1STOP), //# Temp until the Kiss anim gets split up - ENUM2STRING(BOTH_KISSER1STOP1), //# Kyle stop kissing but don't let go - ENUM2STRING(BOTH_KISSER1STOP2), //# Kyle step back from Jan - ENUM2STRING(BOTH_KISSEE1), //# Temp until the Kiss anim gets split up - ENUM2STRING(BOTH_KISSEE1START1), //# Jan start being kissed - ENUM2STRING(BOTH_KISSEE1START2), //# Jan start2 being kissed - ENUM2STRING(BOTH_KISSEE1LOOP), //# Jan loop being kissed - ENUM2STRING(BOTH_KISSEE1STOP), //# Temp until the Kiss anim gets split up - ENUM2STRING(BOTH_KISSEE1STOP1), //# Jan stop being kissed but don't let go - ENUM2STRING(BOTH_KISSEE1STOP2), //# Jan wait for Kyle to step back ENUM2STRING(BOTH_BARTENDER_IDLE1), //# Bartender idle in cin #15 ENUM2STRING(BOTH_BARTENDER_THROW1), //# Bartender throws glass in cin #15 ENUM2STRING(BOTH_BARTENDER_COWERSTART), //# Start of Bartender raising both hands up in surrender (cin #16) @@ -867,6 +811,7 @@ stringID_table_t animTable [MAX_ANIMATIONS+1] = ENUM2STRING(BOTH_WALK4), //# Walk cycle goes to a stand4 ENUM2STRING(BOTH_WALK5), //# Tavion taunting Kyle (cin 22) ENUM2STRING(BOTH_WALK6), //# Slow walk for Luke (cin 12) + ENUM2STRING(BOTH_WALK7), //# Fast walk ENUM2STRING(BOTH_WALKTORUN1), //# transition from walk to run ENUM2STRING(BOTH_RUN1), //# Full run ENUM2STRING(BOTH_RUN1START), //# Start into full run1 @@ -953,15 +898,21 @@ stringID_table_t animTable [MAX_ANIMATIONS+1] = ENUM2STRING(BOTH_DIVE1), //# Dive! + ENUM2STRING(BOTH_SABERFAST_STANCE), + ENUM2STRING(BOTH_SABERSLOW_STANCE), + ENUM2STRING(BOTH_ENGAGETAUNT), ENUM2STRING(BOTH_A2_STABBACK1), //# Stab saber backward ENUM2STRING(BOTH_ATTACK_BACK), //# Swing around backwards and attack - ENUM2STRING(BOTH_FJSS_TR_BL), //# jump spin slash tr to bl - ENUM2STRING(BOTH_FJSS_TL_BR), //# jump spin slash bl to tr + ENUM2STRING(BOTH_JUMPFLIPSLASHDOWN1),//# + ENUM2STRING(BOTH_JUMPFLIPSTABDOWN),//# + ENUM2STRING(BOTH_FORCELEAP2_T__B_),//# + ENUM2STRING(BOTH_LUNGE2_B__T_),//# + ENUM2STRING(BOTH_CROUCHATTACKBACK1),//# ENUM2STRING(BOTH_ARIAL_LEFT), //# ENUM2STRING(BOTH_ARIAL_RIGHT), //# ENUM2STRING(BOTH_CARTWHEEL_LEFT), //# ENUM2STRING(BOTH_CARTWHEEL_RIGHT), //# - ENUM2STRING(BOTH_FLIP_LEFT), //# + ENUM2STRING(BOTH_FLIP_LEFT), //# ENUM2STRING(BOTH_FLIP_BACK1), //# ENUM2STRING(BOTH_FLIP_BACK2), //# ENUM2STRING(BOTH_FLIP_BACK3), //# @@ -970,17 +921,17 @@ stringID_table_t animTable [MAX_ANIMATIONS+1] = ENUM2STRING(BOTH_WALL_RUN_RIGHT), //# ENUM2STRING(BOTH_WALL_RUN_RIGHT_FLIP),//# ENUM2STRING(BOTH_WALL_RUN_RIGHT_STOP),//# - ENUM2STRING(BOTH_WALL_RUN_LEFT), //# + ENUM2STRING(BOTH_WALL_RUN_LEFT), //# ENUM2STRING(BOTH_WALL_RUN_LEFT_FLIP),//# ENUM2STRING(BOTH_WALL_RUN_LEFT_STOP),//# ENUM2STRING(BOTH_WALL_FLIP_RIGHT), //# ENUM2STRING(BOTH_WALL_FLIP_LEFT), //# - ENUM2STRING(BOTH_WALL_FLIP_FWD), //# - ENUM2STRING(BOTH_KNOCKDOWN1), //# - ENUM2STRING(BOTH_KNOCKDOWN2), //# - ENUM2STRING(BOTH_KNOCKDOWN3), //# - ENUM2STRING(BOTH_KNOCKDOWN4), //# - ENUM2STRING(BOTH_KNOCKDOWN5), //# + ENUM2STRING(BOTH_WALL_FLIP_FWD), //# + ENUM2STRING(BOTH_KNOCKDOWN1), //# knocked backwards + ENUM2STRING(BOTH_KNOCKDOWN2), //# knocked backwards hard + ENUM2STRING(BOTH_KNOCKDOWN3), //# knocked forwards + ENUM2STRING(BOTH_KNOCKDOWN4), //# knocked backwards from crouch + ENUM2STRING(BOTH_KNOCKDOWN5), //# dupe of 3 - will be removed ENUM2STRING(BOTH_GETUP1), //# ENUM2STRING(BOTH_GETUP2), //# ENUM2STRING(BOTH_GETUP3), //# @@ -998,21 +949,24 @@ stringID_table_t animTable [MAX_ANIMATIONS+1] = ENUM2STRING(BOTH_FORCE_GETUP_B6), //# ENUM2STRING(BOTH_WALL_FLIP_BACK1), //# ENUM2STRING(BOTH_WALL_FLIP_BACK2), //# - ENUM2STRING(BOTH_SPIN1), //# + ENUM2STRING(BOTH_SPIN1), //# + ENUM2STRING(BOTH_CEILING_CLING), //# clinging to ceiling + ENUM2STRING(BOTH_CEILING_DROP), //# dropping from ceiling cling //TESTING + ENUM2STRING(BOTH_FJSS_TR_BL), //# jump spin slash tr to bl + ENUM2STRING(BOTH_FJSS_TL_BR), //# jump spin slash bl to tr ENUM2STRING(BOTH_DEATHFROMBACKSLASH),//# - ENUM2STRING(BOTH_DEFLECTSLASH__R__L_FIN),//# ENUM2STRING(BOTH_RIGHTHANDCHOPPEDOFF),//# - ENUM2STRING(BOTH_JUMPFLIPSLASHDOWN1),//# - ENUM2STRING(BOTH_JUMPFLIPSTABDOWN),//# - ENUM2STRING(BOTH_FORCELEAP2_T__B_),//# - ENUM2STRING(BOTH_LUNGE2_B__T_),//# + ENUM2STRING(BOTH_DEFLECTSLASH__R__L_FIN),//# ENUM2STRING(BOTH_BASHED1),//# ENUM2STRING(BOTH_ARIAL_F1),//# ENUM2STRING(BOTH_BUTTERFLY_FR1),//# ENUM2STRING(BOTH_BUTTERFLY_FL1),//# - ENUM2STRING(BOTH_CROUCHATTACKBACK1),//# + ENUM2STRING(BOTH_POSE1),//# + ENUM2STRING(BOTH_POSE2),//# + ENUM2STRING(BOTH_POSE3),//# + ENUM2STRING(BOTH_POSE4),//# //# #sep BOTH_ MISC MOVEMENT ENUM2STRING(BOTH_HIT1), //# Kyle hit by crate in cin #9 @@ -1073,28 +1027,9 @@ stringID_table_t animTable [MAX_ANIMATIONS+1] = ENUM2STRING(BOTH_INJURED6POINT), //# Chang points to door while in injured state ENUM2STRING(BOTH_INJUREDTOSTAND1), //# Runinjured to stand1 + ENUM2STRING(BOTH_PROPUP1), //# Kyle getting up from having been knocked down (cin #9 end) ENUM2STRING(BOTH_CRAWLBACK1), //# Lying on back), crawling backwards with elbows ENUM2STRING(BOTH_SITWALL1), //# Sitting against a wall - ENUM2STRING(BOTH_SLEEP1), //# laying on back-rknee up-rhand on torso - ENUM2STRING(BOTH_SLEEP2), //# on floor-back against wall-arms crossed - ENUM2STRING(BOTH_SLEEP3), //# Sleeping in a chair - ENUM2STRING(BOTH_SLEEP4), //# Sleeping slumped over table - ENUM2STRING(BOTH_SLEEP5), //# Laying on side sleeping on flat sufrace - ENUM2STRING(BOTH_SLEEP6START), //# Kyle leaning back to sleep (cin 20) - ENUM2STRING(BOTH_SLEEP6STOP), //# Kyle waking up and shaking his head (cin 21) - ENUM2STRING(BOTH_SLEEP1GETUP), //# alarmed and getting up out of sleep1 pose to stand - ENUM2STRING(BOTH_SLEEP1GETUP2), //# - ENUM2STRING(BOTH_SLEEP2GETUP), //# alarmed and getting up out of sleep2 pose to stand - ENUM2STRING(BOTH_SLEEP3GETUP), //# alarmed and getting up out of sleep3 pose to stand - ENUM2STRING(BOTH_SLEEP3DEATH), //# death in chair), from sleep3 idle - ENUM2STRING(BOTH_SLEEP3DEAD), //# death in chair), from sleep3 idle - - ENUM2STRING(BOTH_SLEEP_IDLE1), //# rub face and nose while asleep from sleep pose 1 - ENUM2STRING(BOTH_SLEEP_IDLE2), //# shift position while asleep - stays in sleep2 - ENUM2STRING(BOTH_SLEEP_IDLE3), //# Idle anim from sleep pose 3 - ENUM2STRING(BOTH_SLEEP_IDLE4), //# Idle anim from sleep pose 4 - ENUM2STRING(BOTH_SLEEP1_NOSE), //# Scratch nose from SLEEP1 pose - ENUM2STRING(BOTH_SLEEP2_SHIFT), //# Shift in sleep from SLEEP2 pose ENUM2STRING(BOTH_RESTRAINED1), //# Telsia tied to medical table ENUM2STRING(BOTH_RESTRAINED1POINT), //# Telsia tied to medical table pointing at Munro ENUM2STRING(BOTH_LIFTED1), //# Fits with ENUM2STRING(BOTH_LIFT1), lifted on shoulder @@ -1115,6 +1050,8 @@ stringID_table_t animTable [MAX_ANIMATIONS+1] = ENUM2STRING(BOTH_TURNOFF), //# Protocol Droid shuts off ENUM2STRING(BOTH_BUTTON1), //# Single button push with right hand ENUM2STRING(BOTH_BUTTON2), //# Single button push with left finger + ENUM2STRING(BOTH_BUTTON_HOLD), //# Single button hold with left hand + ENUM2STRING(BOTH_BUTTON_RELEASE), //# Single button release with left hand //# JEDI-SPECIFIC ENUM2STRING(BOTH_RESISTPUSH), //# plant yourself to resist force push/pulls. @@ -1123,11 +1060,17 @@ stringID_table_t animTable [MAX_ANIMATIONS+1] = ENUM2STRING(BOTH_MINDTRICK1), //# Use off-hand to do mind trick ENUM2STRING(BOTH_MINDTRICK2), //# Use off-hand to do distraction ENUM2STRING(BOTH_FORCELIGHTNING), //# Use off-hand to do lightning + ENUM2STRING(BOTH_FORCELIGHTNING_HOLD), //# Use off-hand to do lightning - hold + ENUM2STRING(BOTH_FORCELIGHTNING_RELEASE),//# Use off-hand to do lightning - release ENUM2STRING(BOTH_FORCEHEAL_START), //# Healing meditation pose start ENUM2STRING(BOTH_FORCEHEAL_STOP), //# Healing meditation pose end ENUM2STRING(BOTH_FORCEHEAL_QUICK), //# Healing meditation gesture ENUM2STRING(BOTH_SABERPULL), //# Use off-hand to do force power. - ENUM2STRING(BOTH_FORCEGRIP3), //# force-gripping + ENUM2STRING(BOTH_FORCEGRIP1), //# force-gripping (no anim?) + ENUM2STRING(BOTH_FORCEGRIP2), //# force-gripping (?) + ENUM2STRING(BOTH_FORCEGRIP3), //# force-gripping (right-hand) + ENUM2STRING(BOTH_FORCEGRIP_HOLD), //# Use off-hand to do grip - hold + ENUM2STRING(BOTH_FORCEGRIP_RELEASE),//# Use off-hand to do grip - release ENUM2STRING(BOTH_TOSS1), //# throwing to left after force gripping ENUM2STRING(BOTH_TOSS2), //# throwing to right after force gripping @@ -1205,8 +1148,6 @@ stringID_table_t animTable [MAX_ANIMATIONS+1] = ENUM2STRING(TORSO_SURRENDER_START), //# arms up ENUM2STRING(TORSO_SURRENDER_STOP), //# arms back down - ENUM2STRING(TORSO_FORCEGRIP1), //# force-gripping - ENUM2STRING(TORSO_FORCEGRIP2), //# force-gripping ENUM2STRING(TORSO_CHOKING1), //# TEMP @@ -1237,6 +1178,46 @@ stringID_table_t animTable [MAX_ANIMATIONS+1] = ENUM2STRING(LEGS_RIGHTUP3), //# On a slope with RIGHT foot 12 higher than left ENUM2STRING(LEGS_RIGHTUP4), //# On a slope with RIGHT foot 16 higher than left ENUM2STRING(LEGS_RIGHTUP5), //# On a slope with RIGHT foot 20 higher than left + ENUM2STRING(LEGS_S1_LUP1), + ENUM2STRING(LEGS_S1_LUP2), + ENUM2STRING(LEGS_S1_LUP3), + ENUM2STRING(LEGS_S1_LUP4), + ENUM2STRING(LEGS_S1_LUP5), + ENUM2STRING(LEGS_S1_RUP1), + ENUM2STRING(LEGS_S1_RUP2), + ENUM2STRING(LEGS_S1_RUP3), + ENUM2STRING(LEGS_S1_RUP4), + ENUM2STRING(LEGS_S1_RUP5), + ENUM2STRING(LEGS_S3_LUP1), + ENUM2STRING(LEGS_S3_LUP2), + ENUM2STRING(LEGS_S3_LUP3), + ENUM2STRING(LEGS_S3_LUP4), + ENUM2STRING(LEGS_S3_LUP5), + ENUM2STRING(LEGS_S3_RUP1), + ENUM2STRING(LEGS_S3_RUP2), + ENUM2STRING(LEGS_S3_RUP3), + ENUM2STRING(LEGS_S3_RUP4), + ENUM2STRING(LEGS_S3_RUP5), + ENUM2STRING(LEGS_S4_LUP1), + ENUM2STRING(LEGS_S4_LUP2), + ENUM2STRING(LEGS_S4_LUP3), + ENUM2STRING(LEGS_S4_LUP4), + ENUM2STRING(LEGS_S4_LUP5), + ENUM2STRING(LEGS_S4_RUP1), + ENUM2STRING(LEGS_S4_RUP2), + ENUM2STRING(LEGS_S4_RUP3), + ENUM2STRING(LEGS_S4_RUP4), + ENUM2STRING(LEGS_S4_RUP5), + ENUM2STRING(LEGS_S5_LUP1), + ENUM2STRING(LEGS_S5_LUP2), + ENUM2STRING(LEGS_S5_LUP3), + ENUM2STRING(LEGS_S5_LUP4), + ENUM2STRING(LEGS_S5_LUP5), + ENUM2STRING(LEGS_S5_RUP1), + ENUM2STRING(LEGS_S5_RUP2), + ENUM2STRING(LEGS_S5_RUP3), + ENUM2STRING(LEGS_S5_RUP4), + ENUM2STRING(LEGS_S5_RUP5), //================================================= //HEAD ANIMS diff --git a/CODEmp/cgame/cg_consolecmds.c b/CODE-mp/cgame/cg_consolecmds.c similarity index 93% rename from CODEmp/cgame/cg_consolecmds.c rename to CODE-mp/cgame/cg_consolecmds.c index 3841035..eaaae63 100644 --- a/CODEmp/cgame/cg_consolecmds.c +++ b/CODE-mp/cgame/cg_consolecmds.c @@ -94,25 +94,6 @@ static void CG_ScoresUp_f( void ) { extern menuDef_t *menuScoreboard; void Menu_Reset(); // FIXME: add to right include file -static void CG_LoadHud_f( void) { - char buff[1024]; - const char *hudSet; - memset(buff, 0, sizeof(buff)); - - String_Init(); - Menu_Reset(); - - trap_Cvar_VariableStringBuffer("cg_hudFiles", buff, sizeof(buff)); - hudSet = buff; - if (hudSet[0] == '\0') { - hudSet = "ui/hud.txt"; - } - - CG_LoadMenus(hudSet); - menuScoreboard = NULL; -} - - static void CG_scrollScoresDown_f( void) { if (menuScoreboard && cg.scoreBoardShowing) { Menu_ScrollFeeder(menuScoreboard, FEEDER_SCOREBOARD, qtrue); @@ -430,6 +411,7 @@ static consoleCommand_t commands[] = { { "nextskin", CG_TestModelNextSkin_f }, { "prevskin", CG_TestModelPrevSkin_f }, { "viewpos", CG_Viewpos_f }, + { "datapad", CG_ScoresDown_f }, //SP compatibility for default.cfg { "+scores", CG_ScoresDown_f }, { "-scores", CG_ScoresUp_f }, // { "+zoom", CG_ZoomDown_f }, @@ -444,7 +426,6 @@ static consoleCommand_t commands[] = { { "vtell_target", CG_VoiceTellTarget_f }, { "vtell_attacker", CG_VoiceTellAttacker_f }, { "tcmd", CG_TargetCommand_f }, - { "loadhud", CG_LoadHud_f }, { "nextTeamMember", CG_NextTeamMember_f }, { "prevTeamMember", CG_PrevTeamMember_f }, { "nextOrder", CG_NextOrder_f }, diff --git a/CODEmp/cgame/cg_draw.c b/CODE-mp/cgame/cg_draw.c similarity index 94% rename from CODEmp/cgame/cg_draw.c rename to CODE-mp/cgame/cg_draw.c index ae09967..361b4dc 100644 --- a/CODEmp/cgame/cg_draw.c +++ b/CODE-mp/cgame/cg_draw.c @@ -1429,14 +1429,9 @@ void CG_DrawInvenSelect( void ) if (bg_itemlist[BG_GetItemIndexByTag(cg.itemSelect, IT_HOLDABLE)].pickup_name) { - // FIXME :this has to use the bg_itemlist pickup name -// tag = FindInventoryItemTag(cg.inventorySelect); + vec4_t textColor = { .312f, .75f, .621f, 1.0f }; -// if (tag) -// { - UI_DrawProportionalString(320, y+48, bg_itemlist[BG_GetItemIndexByTag(cg.itemSelect, IT_HOLDABLE)].pickup_name, UI_CENTER | UI_SMALLFONT, colorTable[CT_ICON_BLUE]); -// CG_DrawProportionalString(320, y + 53, bg_itemlist[i].pickup_name, CG_CENTER | CG_SMALLFONT, colorTable[CT_ICON_BLUE]); -// } + UI_DrawProportionalString(320, y+48, bg_itemlist[BG_GetItemIndexByTag(cg.itemSelect, IT_HOLDABLE)].pickup_name, UI_CENTER | UI_SMALLFONT, textColor); } } @@ -2614,6 +2609,12 @@ static void CG_DrawActivePowers(void) i++; } + + //additionally, draw an icon force force rage recovery + if (cg.snap->ps.fd.forceRageRecoveryTime > cg.time) + { + CG_DrawPic( startx, starty, endx, endy, cgs.media.rageRecShader); + } } //-------------------------------------------------------------- @@ -3799,15 +3800,6 @@ static void CG_Draw2D( void ) { CG_DrawRocketLocking( cg.snap->ps.rocketLockIndex, cg.snap->ps.rocketLockTime ); } - if (cg.snap->ps.holocronBits) - { - CG_DrawHolocronIcons(); - } - if (cg.snap->ps.fd.forcePowersActive) - { - CG_DrawActivePowers(); - } - if (BG_HasYsalimari(cgs.gametype, &cg.snap->ps)) { if (!cgYsalTime) @@ -3886,7 +3878,7 @@ static void CG_Draw2D( void ) { { CG_DrawHolocronIcons(); } - if (cg.snap->ps.fd.forcePowersActive) + if (cg.snap->ps.fd.forcePowersActive || cg.snap->ps.fd.forceRageRecoveryTime > cg.time) { CG_DrawActivePowers(); } diff --git a/CODEmp/cgame/cg_drawtools.c b/CODE-mp/cgame/cg_drawtools.c similarity index 100% rename from CODEmp/cgame/cg_drawtools.c rename to CODE-mp/cgame/cg_drawtools.c diff --git a/CODEmp/cgame/cg_effects.c b/CODE-mp/cgame/cg_effects.c similarity index 100% rename from CODEmp/cgame/cg_effects.c rename to CODE-mp/cgame/cg_effects.c diff --git a/CODEmp/cgame/cg_ents.c b/CODE-mp/cgame/cg_ents.c similarity index 93% rename from CODEmp/cgame/cg_ents.c rename to CODE-mp/cgame/cg_ents.c index 86506ff..abc61e7 100644 --- a/CODEmp/cgame/cg_ents.c +++ b/CODE-mp/cgame/cg_ents.c @@ -1085,7 +1085,7 @@ Ghoul2 Insert End //refEntity_t sRef; //memcpy( &sRef, &ent, sizeof( sRef ) ); - ent.customShader = trap_R_RegisterShader( "gfx/effects/solidWhite_cull" ); + ent.customShader = cgs.media.solidWhite; ent.renderfx = RF_RGB_TINT; wv = sin( cg.time * 0.003f ) * 0.08f + 0.1f; ent.shaderRGBA[0] = wv * 255; @@ -1107,7 +1107,7 @@ Ghoul2 Insert End fxSArgs.rotation = 0.0f; fxSArgs.bounce = 0.0f; fxSArgs.life = 1.0f; - fxSArgs.shader = cgs.media.yellowSaberGlowShader; + fxSArgs.shader = cgs.media.yellowDroppedSaberShader; fxSArgs.flags = 0x08000000; //trap_FX_AddSprite( org, NULL, NULL, 5.5f, 5.5f, wv, wv, 0.0f, 0.0f, 1.0f, cgs.media.yellowSaberGlowShader, 0x08000000 ); @@ -1122,27 +1122,27 @@ Ghoul2 Insert End //refEntity_t sRef; //memcpy( &sRef, &ent, sizeof( sRef ) ); - ent.customShader = trap_R_RegisterShader( "gfx/effects/solidWhite_cull" ); + ent.customShader = cgs.media.solidWhite; ent.renderfx = RF_RGB_TINT; wv = sin( cg.time * 0.005f ) * 0.08f + 0.1f; //* 0.08f + 0.1f; if (cent->currentState.trickedentindex3 == 1) { //dark - ent.shaderRGBA[0] = wv * 255; - ent.shaderRGBA[1] = wv * 0; - ent.shaderRGBA[2] = wv * 0; + ent.shaderRGBA[0] = wv*255; + ent.shaderRGBA[1] = 0; + ent.shaderRGBA[2] = 0; } else if (cent->currentState.trickedentindex3 == 2) { //light - ent.shaderRGBA[0] = wv * 255; - ent.shaderRGBA[1] = wv * 255; - ent.shaderRGBA[2] = wv * 255; + ent.shaderRGBA[0] = wv*255; + ent.shaderRGBA[1] = wv*255; + ent.shaderRGBA[2] = wv*255; } else { //neutral - ent.shaderRGBA[0] = wv * 0; - ent.shaderRGBA[1] = wv * 255; - ent.shaderRGBA[2] = wv * 255; + ent.shaderRGBA[0] = 0; + ent.shaderRGBA[1] = wv*255; + ent.shaderRGBA[2] = wv*255; } ent.modelScale[0] = 1.1; @@ -1153,7 +1153,6 @@ Ghoul2 Insert End ScaleModelAxis(&ent); trap_R_AddRefEntityToScene (&ent); - VectorMA( ent.origin, 1, ent.axis[2], org ); @@ -1208,7 +1207,7 @@ Ghoul2 Insert End int i = 0; VectorMA( ent.origin, 6.6f, ent.axis[0], beamOrg );// forward - beamID = trap_FX_RegisterEffect("tripMine/laserMP.efx"); + beamID = cgs.effects.tripmineLaserFX; if (cg.snap->ps.fd.forcePowersActive & (1 << FP_SEE)) { @@ -1324,7 +1323,8 @@ Ghoul2 Insert Start item = &bg_itemlist[ es->modelindex ]; if ((item->giType == IT_WEAPON || item->giType == IT_POWERUP) && - !(cent->currentState.eFlags & EF_DROPPEDWEAPON)) + !(cent->currentState.eFlags & EF_DROPPEDWEAPON) && + !cg_simpleItems.integer) { vec3_t uNorm; qboolean doGrey; @@ -1379,16 +1379,46 @@ Ghoul2 Insert End ent.shaderRGBA[1] = 255; ent.shaderRGBA[2] = 255; - if ( es->eFlags & EF_ITEMPLACEHOLDER ) + ent.origin[2] += 16; + + if (item->giType != IT_POWERUP || item->giTag != PW_FORCE_BOON) { ent.renderfx |= RF_FORCE_ENT_ALPHA; - ent.shaderRGBA[3] = 50 + sin(cg.time*0.01)*30; + } + + if ( es->eFlags & EF_ITEMPLACEHOLDER ) + { + if (item->giType == IT_POWERUP && item->giTag == PW_FORCE_BOON) + { + return; + } + ent.shaderRGBA[0] = 200; + ent.shaderRGBA[1] = 200; + ent.shaderRGBA[2] = 200; + ent.shaderRGBA[3] = 150 + sin(cg.time*0.01)*30; } else { ent.shaderRGBA[3] = 255; } + if (CG_GreyItem(item->giType, item->giTag, cg.snap->ps.fd.forceSide)) + { + ent.shaderRGBA[0] = 100; + ent.shaderRGBA[1] = 100; + ent.shaderRGBA[2] = 100; + + ent.shaderRGBA[3] = 200; + + if (item->giTag == PW_FORCE_ENLIGHTENED_LIGHT) + { + ent.customShader = trap_R_RegisterShader("gfx/misc/mp_light_enlight_disable"); + } + else + { + ent.customShader = trap_R_RegisterShader("gfx/misc/mp_dark_enlight_disable"); + } + } trap_R_AddRefEntityToScene(&ent); return; } @@ -1648,6 +1678,14 @@ Ghoul2 Insert End } else { // add to refresh list -- normal item + if (item->giType == IT_TEAM && + (item->giTag == PW_REDFLAG || item->giTag == PW_BLUEFLAG)) + { + ent.modelScale[0] = 0.7; + ent.modelScale[1] = 0.7; + ent.modelScale[2] = 0.7; + ScaleModelAxis(&ent); + } trap_R_AddRefEntityToScene(&ent); } @@ -1884,7 +1922,7 @@ Ghoul2 Insert End //refEntity_t sRef; //memcpy( &sRef, &ent, sizeof( sRef ) ); - ent.customShader = trap_R_RegisterShader( "gfx/effects/solidWhite_cull" ); + ent.customShader = cgs.media.solidWhite; ent.renderfx = RF_RGB_TINT; wv = sin( cg.time * 0.003f ) * 0.08f + 0.1f; ent.shaderRGBA[0] = wv * 255; @@ -1906,12 +1944,24 @@ Ghoul2 Insert End fxSArgs.rotation = 0.0f; fxSArgs.bounce = 0.0f; fxSArgs.life = 1.0f; - fxSArgs.shader = cgs.media.yellowSaberGlowShader; + fxSArgs.shader = cgs.media.yellowDroppedSaberShader; fxSArgs.flags = 0x08000000; //trap_FX_AddSprite( org, NULL, NULL, 5.5f, 5.5f, wv, wv, 0.0f, 0.0f, 1.0f, cgs.media.yellowSaberGlowShader, 0x08000000 ); trap_FX_AddSprite(&fxSArgs); } + + if (cgs.gametype == GT_JEDIMASTER) + { + ent.shaderRGBA[0] = 255; + ent.shaderRGBA[1] = 255; + ent.shaderRGBA[2] = 0; + + ent.renderfx |= RF_DEPTHHACK; + ent.customShader = cgs.media.forceSightBubble; + + trap_R_AddRefEntityToScene( &ent ); + } } if ( s1->eFlags & EF_FIRING ) diff --git a/CODEmp/cgame/cg_event.c b/CODE-mp/cgame/cg_event.c similarity index 91% rename from CODEmp/cgame/cg_event.c rename to CODE-mp/cgame/cg_event.c index 91ea87d..059b5cc 100644 --- a/CODEmp/cgame/cg_event.c +++ b/CODE-mp/cgame/cg_event.c @@ -204,9 +204,26 @@ clientkilled: char *s; if ( cgs.gametype < GT_TEAM ) { - s = va("%s %s\n%s place with %i", (char *)CG_GetStripEdString("INGAMETEXT", "KILLED_MESSAGE"), targetName, - CG_PlaceString( cg.snap->ps.persistant[PERS_RANK] + 1 ), - cg.snap->ps.persistant[PERS_SCORE] ); + if (cgs.gametype == GT_JEDIMASTER && + attacker < MAX_CLIENTS && + !ent->isJediMaster && + !cg.snap->ps.isJediMaster) + { + char part1[512]; + char part2[512]; + const char *kmsg1 = CG_GetStripEdString("INGAMETEXT", "KILLED_MESSAGE"); + strcpy(part1, kmsg1); + kmsg1 = CG_GetStripEdString("INGAMETEXT", "JMKILLED_NOTJM"); + strcpy(part2, kmsg1); + + s = va("%s %s %s\n", part1, targetName, part2); + } + else + { + s = va("%s %s.\n%s place with %i.", (char *)CG_GetStripEdString("INGAMETEXT", "KILLED_MESSAGE"), targetName, + CG_PlaceString( cg.snap->ps.persistant[PERS_RANK] + 1 ), + cg.snap->ps.persistant[PERS_SCORE] ); + } } else { s = va("%s %s", (char *)CG_GetStripEdString("INGAMETEXT", "KILLED_MESSAGE"), targetName ); } @@ -1041,7 +1058,7 @@ void CG_EntityEvent( centity_t *cent, vec3_t position ) { } else { - trap_S_StartBackgroundTrack( "music/prototype/Duel.mp3", "music/prototype/Duel.mp3", qfalse ); + trap_S_StartBackgroundTrack( "music/mp/duel.mp3", "music/mp/duel.mp3", qfalse ); } } else @@ -1128,13 +1145,14 @@ void CG_EntityEvent( centity_t *cent, vec3_t position ) { if (index < 1) { //a holocron most likely index = cg_entities[es->eventParm].currentState.trickedentindex4; - trap_S_StartSound (NULL, es->number, CHAN_AUTO, trap_S_RegisterSound( "sound/player/holocron.wav" ) ); + trap_S_StartSound (NULL, es->number, CHAN_AUTO, cgs.media.holocronPickup ); if (es->number == cg.snap->ps.clientNum && showPowersName[index]) { const char *strText = CG_GetStripEdString("INGAMETEXT", "PICKUPLINE"); - Com_Printf("%s %s\n", strText, showPowersName[index]); + //Com_Printf("%s %s\n", strText, showPowersName[index]); + CG_CenterPrint( va("%s %s\n", strText, showPowersName[index]), SCREEN_HEIGHT * 0.30, BIGCHAR_WIDTH ); } //Show the player their force selection bar in case picking the holocron up changed the current selection @@ -1336,13 +1354,25 @@ void CG_EntityEvent( centity_t *cent, vec3_t position ) { DEBUGNAME("EV_SABER_HIT"); if (es->eventParm) { //hit a person + vec3_t fxDir; + VectorCopy(es->angles, fxDir); + if (!fxDir[0] && !fxDir[1] && !fxDir[2]) + { + fxDir[1] = 1; + } trap_S_StartSound(es->origin, es->number, CHAN_AUTO, trap_S_RegisterSound("sound/weapons/saber/saberhit.wav")); - trap_FX_PlayEffectID( trap_FX_RegisterEffect("saber/blood_sparks.efx"), es->origin, es->angles ); + trap_FX_PlayEffectID( trap_FX_RegisterEffect("saber/blood_sparks.efx"), es->origin, fxDir ); } else { //hit something else + vec3_t fxDir; + VectorCopy(es->angles, fxDir); + if (!fxDir[0] && !fxDir[1] && !fxDir[2]) + { + fxDir[1] = 1; + } trap_S_StartSound(es->origin, es->number, CHAN_AUTO, trap_S_RegisterSound("sound/weapons/saber/saberhit.wav")); - trap_FX_PlayEffectID( trap_FX_RegisterEffect("saber/spark.efx"), es->origin, es->angles ); + trap_FX_PlayEffectID( trap_FX_RegisterEffect("saber/spark.efx"), es->origin, fxDir ); } break; @@ -1351,15 +1381,27 @@ void CG_EntityEvent( centity_t *cent, vec3_t position ) { if (es->eventParm) { //saber block + vec3_t fxDir; + VectorCopy(es->angles, fxDir); + if (!fxDir[0] && !fxDir[1] && !fxDir[2]) + { + fxDir[1] = 1; + } trap_S_StartSound(es->origin, es->number, CHAN_AUTO, trap_S_RegisterSound(va( "sound/weapons/saber/saberblock%d.wav", Q_irand(1, 9) ))); - trap_FX_PlayEffectID( trap_FX_RegisterEffect("saber/saber_block.efx"), es->origin, es->angles ); + trap_FX_PlayEffectID( trap_FX_RegisterEffect("saber/saber_block.efx"), es->origin, fxDir ); g_saberFlashTime = cg.time-50; VectorCopy( es->origin, g_saberFlashPos ); } else { //projectile block - trap_FX_PlayEffectID(trap_FX_RegisterEffect("blaster/deflect.efx"), es->origin, es->angles); + vec3_t fxDir; + VectorCopy(es->angles, fxDir); + if (!fxDir[0] && !fxDir[1] && !fxDir[2]) + { + fxDir[1] = 1; + } + trap_FX_PlayEffectID(trap_FX_RegisterEffect("blaster/deflect.efx"), es->origin, fxDir); } break; @@ -1389,9 +1431,14 @@ void CG_EntityEvent( centity_t *cent, vec3_t position ) { { break; } - trap_FX_PlayEffectID(trap_FX_RegisterEffect("mp/spawn.efx"), pos, ang); + trap_FX_PlayEffectID(trap_FX_RegisterEffect("mp/jedispawn.efx"), pos, ang); trap_S_StartSound (NULL, es->number, CHAN_AUTO, trap_S_RegisterSound( "sound/weapons/saber/saberon.wav" ) ); + + if (cg.snap->ps.clientNum == es->number) + { + trap_S_StartLocalSound(cgs.media.happyMusic, CHAN_LOCAL); + } } break; @@ -1814,19 +1861,47 @@ void CG_EntityEvent( centity_t *cent, vec3_t position ) { //CG_AddBufferedSound( cgs.media.blueScoredSound ); break; case GTS_RED_RETURN: // CTF: blue flag returned, 1FCTF: never used - CG_AddBufferedSound( cgs.media.blueFlagReturnedSound ); + if (cgs.gametype == GT_CTY) + { + CG_AddBufferedSound( cgs.media.blueYsalReturnedSound ); + } + else + { + CG_AddBufferedSound( cgs.media.blueFlagReturnedSound ); + } break; case GTS_BLUE_RETURN: // CTF red flag returned, 1FCTF: neutral flag returned - CG_AddBufferedSound( cgs.media.redFlagReturnedSound ); + if (cgs.gametype == GT_CTY) + { + CG_AddBufferedSound( cgs.media.redYsalReturnedSound ); + } + else + { + CG_AddBufferedSound( cgs.media.redFlagReturnedSound ); + } break; case GTS_RED_TAKEN: // CTF: red team took blue flag, 1FCTF: blue team took the neutral flag // if this player picked up the flag then a sound is played in CG_CheckLocalSounds - CG_AddBufferedSound( cgs.media.redTookFlagSound ); + if (cgs.gametype == GT_CTY) + { + CG_AddBufferedSound( cgs.media.redTookYsalSound ); + } + else + { + CG_AddBufferedSound( cgs.media.redTookFlagSound ); + } break; case GTS_BLUE_TAKEN: // CTF: blue team took the red flag, 1FCTF red team took the neutral flag // if this player picked up the flag then a sound is played in CG_CheckLocalSounds - CG_AddBufferedSound( cgs.media.blueTookFlagSound ); + if (cgs.gametype == GT_CTY) + { + CG_AddBufferedSound( cgs.media.blueTookYsalSound ); + } + else + { + CG_AddBufferedSound( cgs.media.blueTookFlagSound ); + } break; case GTS_REDTEAM_SCORED: CG_AddBufferedSound(cgs.media.redScoredSound); @@ -1921,6 +1996,10 @@ void CG_EntityEvent( centity_t *cent, vec3_t position ) { DEBUGNAME("EV_DEATHx"); trap_S_StartSound( NULL, es->number, CHAN_VOICE, CG_CustomSound( es->number, va("*death%i.wav", event - EV_DEATH1 + 1) ) ); + if (es->eventParm && es->number == cg.snap->ps.clientNum) + { + trap_S_StartLocalSound(cgs.media.dramaticFailure, CHAN_LOCAL); + } break; diff --git a/CODEmp/cgame/cg_info.c b/CODE-mp/cgame/cg_info.c similarity index 100% rename from CODEmp/cgame/cg_info.c rename to CODE-mp/cgame/cg_info.c diff --git a/CODEmp/cgame/cg_light.c b/CODE-mp/cgame/cg_light.c similarity index 100% rename from CODEmp/cgame/cg_light.c rename to CODE-mp/cgame/cg_light.c diff --git a/CODEmp/cgame/cg_lights.h b/CODE-mp/cgame/cg_lights.h similarity index 100% rename from CODEmp/cgame/cg_lights.h rename to CODE-mp/cgame/cg_lights.h diff --git a/CODEmp/cgame/cg_local.h b/CODE-mp/cgame/cg_local.h similarity index 95% rename from CODEmp/cgame/cg_local.h rename to CODE-mp/cgame/cg_local.h index 5825b52..f1b6cba 100644 --- a/CODEmp/cgame/cg_local.h +++ b/CODE-mp/cgame/cg_local.h @@ -230,6 +230,8 @@ typedef struct centity_s { int frame_hold_time; int frame_hold_refreshed; + refEntity_t grip_arm; + int trickAlpha; int trickAlphaTime; } centity_t; @@ -873,6 +875,9 @@ typedef struct cgscreffects_s float shake_intensity; int shake_duration; int shake_start; + + float music_volume_mulitplier; + int music_volume_time; } cgscreffects_t; extern cgscreffects_t cgScreenEffects; @@ -934,6 +939,8 @@ typedef struct { qhandle_t purpleSaberCoreShader; qhandle_t saberBlurShader; + qhandle_t yellowDroppedSaberShader; + qhandle_t rivetMarkShader; qhandle_t teamRedShader; @@ -1019,6 +1026,8 @@ typedef struct { qhandle_t disruptorShader; + qhandle_t solidWhite; + qhandle_t heartShader; #ifdef JK2AWARDS @@ -1038,6 +1047,7 @@ typedef struct { sfxHandle_t winnerSound; sfxHandle_t loserSound; + sfxHandle_t crackleSound; sfxHandle_t grenadeBounce1; sfxHandle_t grenadeBounce2; @@ -1091,6 +1101,15 @@ typedef struct { sfxHandle_t redTookFlagSound; sfxHandle_t blueTookFlagSound; + sfxHandle_t redYsalReturnedSound; + sfxHandle_t blueYsalReturnedSound; + sfxHandle_t redTookYsalSound; + sfxHandle_t blueTookYsalSound; + + //music blips + sfxHandle_t happyMusic; + sfxHandle_t dramaticFailure; + // tournament sounds sfxHandle_t count3Sound; sfxHandle_t count2Sound; @@ -1128,6 +1147,8 @@ typedef struct { //force power icons qhandle_t forcePowerIcons[NUM_FORCE_POWERS]; + qhandle_t rageRecShader; + //other HUD parts qhandle_t HUDLeftFrame; qhandle_t HUDArmor1; @@ -1152,6 +1173,8 @@ typedef struct { qhandle_t HUDInnerLeft; + sfxHandle_t holocronPickup; + // Zoom sfxHandle_t zoomStart; sfxHandle_t zoomLoop; @@ -1218,6 +1241,9 @@ typedef struct fxHandle_t thermalExplosionEffect; fxHandle_t thermalShockwaveEffect; + // TRIPMINE + fxHandle_t tripmineLaserFX; + //FORCE fxHandle_t forceLightning; fxHandle_t forceLightningWide; diff --git a/CODEmp/cgame/cg_localents.c b/CODE-mp/cgame/cg_localents.c similarity index 100% rename from CODEmp/cgame/cg_localents.c rename to CODE-mp/cgame/cg_localents.c diff --git a/CODEmp/cgame/cg_main.c b/CODE-mp/cgame/cg_main.c similarity index 94% rename from CODEmp/cgame/cg_main.c rename to CODE-mp/cgame/cg_main.c index 504d34a..26c4798 100644 --- a/CODEmp/cgame/cg_main.c +++ b/CODE-mp/cgame/cg_main.c @@ -563,7 +563,7 @@ static cvarTable_t cvarTable[] = { // bk001129 { &cg_teamChatHeight, "cg_teamChatHeight", "0", CVAR_ARCHIVE }, { &cg_forceModel, "cg_forceModel", "0", CVAR_ARCHIVE }, { &cg_predictItems, "cg_predictItems", "1", CVAR_ARCHIVE }, - { &cg_deferPlayers, "cg_deferPlayers", "0", CVAR_ARCHIVE }, + { &cg_deferPlayers, "cg_deferPlayers", "1", CVAR_ARCHIVE }, { &cg_drawTeamOverlay, "cg_drawTeamOverlay", "0", CVAR_ARCHIVE }, { &cg_teamOverlayUserinfo, "teamoverlay", "0", CVAR_ROM | CVAR_USERINFO }, { &cg_stats, "cg_stats", "0", 0 }, @@ -588,7 +588,6 @@ static cvarTable_t cvarTable[] = { // bk001129 { &cg_singlePlayerActive, "ui_singlePlayerActive", "0", CVAR_USERINFO}, { &cg_recordSPDemo, "ui_recordSPDemo", "0", CVAR_ARCHIVE}, { &cg_recordSPDemoName, "ui_recordSPDemoName", "", CVAR_ARCHIVE}, - { &cg_hudFiles, "cg_hudFiles", "ui/hud.txt", CVAR_ARCHIVE}, { &cg_cameraOrbit, "cg_cameraOrbit", "0", CVAR_CHEAT}, { &cg_cameraOrbitDelay, "cg_cameraOrbitDelay", "50", CVAR_ARCHIVE}, @@ -644,6 +643,18 @@ void CG_RegisterCvars( void ) { trap_Cvar_Register(NULL, "team_model", DEFAULT_TEAM_MODEL, CVAR_USERINFO | CVAR_ARCHIVE ); trap_Cvar_Register(NULL, "team_headmodel", DEFAULT_TEAM_HEAD, CVAR_USERINFO | CVAR_ARCHIVE ); trap_Cvar_Register(NULL, "forcepowers", DEFAULT_FORCEPOWERS, CVAR_USERINFO | CVAR_ARCHIVE ); + + // Cvars uses for transferring data between client and server + trap_Cvar_Register(NULL, "ui_about_gametype", "0", CVAR_ROM|CVAR_INTERNAL ); + trap_Cvar_Register(NULL, "ui_about_fraglimit", "0", CVAR_ROM|CVAR_INTERNAL ); + trap_Cvar_Register(NULL, "ui_about_capturelimit", "0", CVAR_ROM|CVAR_INTERNAL ); + trap_Cvar_Register(NULL, "ui_about_timelimit", "0", CVAR_ROM|CVAR_INTERNAL ); + trap_Cvar_Register(NULL, "ui_about_maxclients", "0", CVAR_ROM|CVAR_INTERNAL ); + trap_Cvar_Register(NULL, "ui_about_dmflags", "0", CVAR_ROM|CVAR_INTERNAL ); + trap_Cvar_Register(NULL, "ui_about_mapname", "0", CVAR_ROM|CVAR_INTERNAL ); + trap_Cvar_Register(NULL, "ui_about_hostname", "0", CVAR_ROM|CVAR_INTERNAL ); + trap_Cvar_Register(NULL, "ui_about_needpass", "0", CVAR_ROM|CVAR_INTERNAL ); + trap_Cvar_Register(NULL, "ui_about_botminplayers", "0", CVAR_ROM|CVAR_INTERNAL ); } /* @@ -879,6 +890,8 @@ static void CG_RegisterSounds( void ) { cgs.media.purpleSaberCoreShader = trap_R_RegisterShader( "gfx/effects/sabers/purple_line" ); cgs.media.saberBlurShader = trap_R_RegisterShader( "gfx/effects/sabers/saberBlur" ); + cgs.media.yellowDroppedSaberShader = trap_R_RegisterShader("gfx/effects/yellow_glow"); + cgs.media.rivetMarkShader = trap_R_RegisterShader( "gfx/damage/rivetmark" ); trap_R_RegisterShader( "gfx/effects/saberFlare" ); @@ -984,9 +997,23 @@ static void CG_RegisterSounds( void ) { cgs.media.blueFlagReturnedSound = trap_S_RegisterSound( "sound/chars/mothma/misc/40MOM041" ); cgs.media.redTookFlagSound = trap_S_RegisterSound( "sound/chars/mothma/misc/40MOM040" ); cgs.media.blueTookFlagSound = trap_S_RegisterSound( "sound/chars/mothma/misc/40MOM039" ); + + cgs.media.redYsalReturnedSound = trap_S_RegisterSound( "sound/chars/mothma/misc/40MOM050" ); + cgs.media.blueYsalReturnedSound = trap_S_RegisterSound( "sound/chars/mothma/misc/40MOM049" ); + cgs.media.redTookYsalSound = trap_S_RegisterSound( "sound/chars/mothma/misc/40MOM048" ); + cgs.media.blueTookYsalSound = trap_S_RegisterSound( "sound/chars/mothma/misc/40MOM047" ); } } + cgs.media.happyMusic = trap_S_RegisterSound("music/goodsmall.mp3"); + cgs.media.dramaticFailure = trap_S_RegisterSound("music/badsmall.mp3"); + + //PRECACHE ALL MUSIC HERE (don't need to precache normally because it's streamed off the disk) + if (cg_buildScript.integer) + { + trap_S_StartBackgroundTrack( "music/mp/duel.mp3", "music/mp/duel.mp3", qfalse ); + } + cg.loadLCARSStage = 1; cgs.media.selectSound = trap_S_RegisterSound( "sound/weapons/change.wav" ); @@ -1001,6 +1028,7 @@ static void CG_RegisterSounds( void ) { cgs.media.landSound = trap_S_RegisterSound( "sound/player/land1.wav"); cgs.media.fallSound = trap_S_RegisterSound( "sound/player/fallsplat.wav"); + cgs.media.crackleSound = trap_S_RegisterSound( "sound/effects/energy_crackle.wav" ); #ifdef JK2AWARDS cgs.media.impressiveSound = trap_S_RegisterSound( "sound/chars/mothma/misc/40MOM025" ); cgs.media.excellentSound = trap_S_RegisterSound( "sound/chars/mothma/misc/40MOM053" ); @@ -1026,16 +1054,19 @@ static void CG_RegisterSounds( void ) { if (cg_buildScript.integer) { - trap_R_RegisterShader( "gfx/effects/solidWhite_cull" ); trap_R_RegisterShader( "gfx/effects/turretflashdie" ); - - trap_R_RegisterShader("gfx/misc/mp_light_enlight_disable"); - trap_R_RegisterShader("gfx/misc/mp_dark_enlight_disable"); } + cgs.media.solidWhite = trap_R_RegisterShader( "gfx/effects/solidWhite_cull" ); + + trap_R_RegisterShader("gfx/misc/mp_light_enlight_disable"); + trap_R_RegisterShader("gfx/misc/mp_dark_enlight_disable"); + trap_R_RegisterModel ( "models/map_objects/mp/sphere.md3" ); trap_R_RegisterModel("models/items/remote.md3"); + cgs.media.holocronPickup = trap_S_RegisterSound( "sound/player/holocron.wav" ); + // Zoom cgs.media.zoomStart = trap_S_RegisterSound( "sound/interface/zoomstart.wav" ); cgs.media.zoomLoop = trap_S_RegisterSound( "sound/interface/zoomloop.wav" ); @@ -1221,6 +1252,7 @@ static void CG_RegisterGraphics( void ) { trap_FX_RegisterEffect("effects/blaster/deflect.efx"); trap_FX_RegisterEffect("emplaced/dead_smoke.efx"); + trap_FX_RegisterEffect("emplaced/explode.efx"); if (cg_buildScript.integer) { @@ -1231,6 +1263,7 @@ static void CG_RegisterGraphics( void ) { trap_FX_RegisterEffect("effects/turret/muzzle_flash.efx"); trap_FX_RegisterEffect("saber/spark.efx"); trap_FX_RegisterEffect("mp/spawn.efx"); + trap_FX_RegisterEffect("mp/jedispawn.efx"); trap_FX_RegisterEffect("mp/itemcone.efx"); trap_FX_RegisterEffect("blaster/deflect.efx"); trap_FX_RegisterEffect("saber/saber_block.efx"); @@ -1834,77 +1867,6 @@ qboolean CG_Load_Menu(char **p) { } - -void CG_LoadMenus(const char *menuFile) { - char *token; - char *p; - int len, start; - fileHandle_t f; - static char buf[MAX_MENUDEFFILE]; - - start = trap_Milliseconds(); - - len = trap_FS_FOpenFile( menuFile, &f, FS_READ ); - if ( !f ) { - // do NOT do this, or it doesn't get a chance to look at the default menu below -ste - //trap_Error( va( S_COLOR_YELLOW "menu file not found: %s, using default\n", menuFile ) ); - len = trap_FS_FOpenFile( "ui/hud.txt", &f, FS_READ ); - if (!f) { - trap_Error( va( S_COLOR_RED "default menu file not found: ui/hud.txt, unable to continue!\n", menuFile ) ); - } - } - - if ( len >= MAX_MENUDEFFILE ) { - trap_Error( va( S_COLOR_RED "menu file too large: %s is %i, max allowed is %i", menuFile, len, MAX_MENUDEFFILE ) ); - trap_FS_FCloseFile( f ); - return; - } - - trap_FS_Read( buf, len, f ); - buf[len] = 0; - trap_FS_FCloseFile( f ); - - COM_Compress(buf); - - Menu_Reset(); - - p = buf; - - while ( 1 ) { - token = COM_ParseExt( (const char **)&p, qtrue ); - if( !token || token[0] == 0 || token[0] == '}') { - break; - } - - //if ( Q_stricmp( token, "{" ) ) { - // Com_Printf( "Missing { in menu file\n" ); - // break; - //} - - //if ( menuCount == MAX_MENUS ) { - // Com_Printf( "Too many menus!\n" ); - // break; - //} - - if ( Q_stricmp( token, "}" ) == 0 ) { - break; - } - - if (Q_stricmp(token, "loadmenu") == 0) { - if (CG_Load_Menu(&p)) { - continue; - } else { - break; - } - } - } - - Com_Printf("UI menu load time = %d milli seconds\n", trap_Milliseconds() - start); - -} - - - static qboolean CG_OwnerDrawHandleKey(int ownerDraw, int flags, float *special, int key) { return qfalse; } @@ -2149,10 +2111,8 @@ CG_LoadHudMenu(); ================= */ -void CG_LoadHudMenu() { - char buff[1024]; - const char *hudSet; - +void CG_LoadHudMenu() +{ cgDC.registerShaderNoMip = &trap_R_RegisterShaderNoMip; cgDC.setColor = &trap_R_SetColor; cgDC.drawHandlePic = &CG_DrawPic; @@ -2211,14 +2171,6 @@ void CG_LoadHudMenu() { Init_Display(&cgDC); Menu_Reset(); - - trap_Cvar_VariableStringBuffer("cg_hudFiles", buff, sizeof(buff)); - hudSet = buff; - if (hudSet[0] == '\0') { - hudSet = "ui/hud.txt"; - } - - CG_LoadMenus(hudSet); } void CG_AssetCache() { @@ -2451,6 +2403,7 @@ Ghoul2 Insert End i++; } + cgs.media.rageRecShader = trap_R_RegisterShaderNoMip("gfx/mp/f_icon_ragerec"); //rww - precache other HUD graphics cgs.media.HUDLeftFrame = trap_R_RegisterShaderNoMip( "gfx/hud/static_test" ); diff --git a/CODEmp/cgame/cg_marks.c b/CODE-mp/cgame/cg_marks.c similarity index 100% rename from CODEmp/cgame/cg_marks.c rename to CODE-mp/cgame/cg_marks.c diff --git a/CODEmp/cgame/cg_media.h b/CODE-mp/cgame/cg_media.h similarity index 100% rename from CODEmp/cgame/cg_media.h rename to CODE-mp/cgame/cg_media.h diff --git a/CODEmp/cgame/cg_newDraw.c b/CODE-mp/cgame/cg_newDraw.c similarity index 96% rename from CODEmp/cgame/cg_newDraw.c rename to CODE-mp/cgame/cg_newDraw.c index dbe9550..7543b4c 100644 --- a/CODEmp/cgame/cg_newDraw.c +++ b/CODE-mp/cgame/cg_newDraw.c @@ -1013,7 +1013,7 @@ static void CG_DrawAreaChat(rectDef_t *rect, float scale, vec4_t color, qhandle_ const char *CG_GetKillerText(void) { const char *s = ""; if ( cg.killerName[0] ) { - s = va("Fragged by %s", cg.killerName ); + s = va("%s %s", CG_GetStripEdString("INGAMETEXT", "KILLEDBY"), cg.killerName ); } return s; } diff --git a/CODEmp/cgame/cg_playeranimate.c b/CODE-mp/cgame/cg_playeranimate.c similarity index 100% rename from CODEmp/cgame/cg_playeranimate.c rename to CODE-mp/cgame/cg_playeranimate.c diff --git a/CODEmp/cgame/cg_players.c b/CODE-mp/cgame/cg_players.c similarity index 88% rename from CODEmp/cgame/cg_players.c rename to CODE-mp/cgame/cg_players.c index 2fec1e8..eb70991 100644 --- a/CODEmp/cgame/cg_players.c +++ b/CODE-mp/cgame/cg_players.c @@ -427,7 +427,7 @@ retryModel: { // Didn't find any slashes, this is a raw filename right in base (whish isn't a good thing) return qfalse; } - +/* // Try to load the animation.cfg for this model then. if ( !BG_ParseAnimationFile( afilename, ci->animations ) ) { // The GLA's animations failed @@ -437,6 +437,19 @@ retryModel: return qfalse; } } +*/ +//rww - For now, we'll just ignore what animation file it wants. In theory all multiplayer-supported models +//should want _humanoid/animation.cfg, so if it doesn't want that then throw it away + if (Q_stricmp(afilename, "models/players/_humanoid/animation.cfg")) + { + Com_Printf( "Model does not use supported animation config.\n"); + return qfalse; + } + else if (!BG_ParseAnimationFile("models/players/_humanoid/animation.cfg", ci->animations)) + { + Com_Printf( "Failed to load animation file models/players/_humanoid/animation.cfg\n" ); + return qfalse; + } else if (!retriedAlready) { int i; @@ -549,11 +562,13 @@ retryModel: } } + /* if (cg_entities[clientNum].ghoul2 && trap_G2_HaveWeGhoul2Models(cg_entities[clientNum].ghoul2)) { trap_G2API_CleanGhoul2Models(&(cg_entities[clientNum].ghoul2)); } trap_G2API_DuplicateGhoul2Instance(ci->ghoul2Model, &cg_entities[clientNum].ghoul2); + */ cg_entities[clientNum].ghoul2weapon = NULL; } @@ -613,6 +628,35 @@ void CG_LoadClientInfo( clientInfo_t *ci ) { qboolean isFemale = qfalse; fileHandle_t f; + clientNum = ci - cgs.clientinfo; + + if (clientNum < 0 || clientNum >= MAX_CLIENTS) + { + clientNum = -1; + } + + ci->deferred = qfalse; + + if (ci->team == TEAM_SPECTATOR) + { + // reset any existing players and bodies, because they might be in bad + // frames for this new model + clientNum = ci - cgs.clientinfo; + for ( i = 0 ; i < MAX_GENTITIES ; i++ ) { + if ( cg_entities[i].currentState.clientNum == clientNum + && cg_entities[i].currentState.eType == ET_PLAYER ) { + CG_ResetPlayerEntity( &cg_entities[i] ); + } + } + + if (ci->ghoul2Model && trap_G2_HaveWeGhoul2Models(ci->ghoul2Model)) + { + trap_G2API_CleanGhoul2Models(&ci->ghoul2Model); + } + + return; + } + teamname[0] = 0; if( cgs.gametype >= GT_TEAM) { if( ci->team == TEAM_BLUE ) { @@ -625,8 +669,8 @@ void CG_LoadClientInfo( clientInfo_t *ci ) { strcat( teamname, "/" ); } modelloaded = qtrue; - if ( !CG_RegisterClientModelname( ci, ci->modelName, ci->skinName, ci->headModelName, ci->headSkinName, teamname, -1 ) ) { - if ( cg_buildScript.integer ) { + if ( !CG_RegisterClientModelname( ci, ci->modelName, ci->skinName, ci->headModelName, ci->headSkinName, teamname, clientNum ) ) { + if ( cg_buildScript.integer && ci->team != TEAM_SPECTATOR ) { CG_Error( "CG_RegisterClientModelname( %s, %s, %s, %s %s ) failed", ci->modelName, ci->skinName, ci->headModelName, ci->headSkinName, teamname ); } @@ -649,6 +693,15 @@ void CG_LoadClientInfo( clientInfo_t *ci ) { modelloaded = qfalse; } + if (clientNum != -1 && ci->ghoul2Model && trap_G2_HaveWeGhoul2Models(ci->ghoul2Model)) + { + if (cg_entities[clientNum].ghoul2 && trap_G2_HaveWeGhoul2Models(cg_entities[clientNum].ghoul2)) + { + trap_G2API_CleanGhoul2Models(&cg_entities[clientNum].ghoul2); + } + trap_G2API_DuplicateGhoul2Instance(ci->ghoul2Model, &cg_entities[clientNum].ghoul2); + } + ci->newAnims = qfalse; if ( ci->torsoModel ) { orientation_t tag; @@ -689,6 +742,15 @@ void CG_LoadClientInfo( clientInfo_t *ci ) { trap_FS_FCloseFile(f); } + if (isFemale) + { + ci->gender = GENDER_FEMALE; + } + else + { + ci->gender = GENDER_MALE; + } + for ( i = 0 ; i < MAX_CUSTOM_SOUNDS ; i++ ) { s = cg_customSoundNames[i]; if ( !s ) { @@ -703,15 +765,7 @@ void CG_LoadClientInfo( clientInfo_t *ci ) { // if the model didn't load use the sounds of the default model if (soundpath[0]) { - if (CG_FileExists(va("sound/%s/%s.wav", soundpath, soundName)) || - CG_FileExists(va("sound/%s/%s.mp3", soundpath, soundName))) - { - ci->sounds[i] = trap_S_RegisterSound( va("sound/%s/%s", soundpath, soundName) ); - } - else - { - ci->sounds[i] = 0; - } + ci->sounds[i] = trap_S_RegisterSound( va("sound/%s/%s", soundpath, soundName) ); if (!ci->sounds[i]) { @@ -729,15 +783,7 @@ void CG_LoadClientInfo( clientInfo_t *ci ) { { if (modelloaded) { - if (CG_FileExists(va("sound/chars/%s/misc/%s.wav", dir, soundName)) || - CG_FileExists(va("sound/chars/%s/misc/%s.mp3", dir, soundName))) - { - ci->sounds[i] = trap_S_RegisterSound( va("sound/chars/%s/misc/%s", dir, soundName) ); - } - else - { - ci->sounds[i] = 0; - } + ci->sounds[i] = trap_S_RegisterSound( va("sound/chars/%s/misc/%s", dir, soundName) ); } if ( !ci->sounds[i] ) @@ -783,8 +829,16 @@ static void CG_CopyClientInfoModel( clientInfo_t *from, clientInfo_t *to ) { to->newAnims = from->newAnims; - // rww - was duplicating instance, now just reassigning pointer to same memory - to->ghoul2Model = from->ghoul2Model; + //to->ghoul2Model = from->ghoul2Model; + //rww - Trying to use the same ghoul2 pointer for two seperate clients == DISASTER + if (to->ghoul2Model && trap_G2_HaveWeGhoul2Models(to->ghoul2Model)) + { + trap_G2API_CleanGhoul2Models(&to->ghoul2Model); + } + if (from->ghoul2Model && trap_G2_HaveWeGhoul2Models(from->ghoul2Model)) + { + trap_G2API_DuplicateGhoul2Instance(from->ghoul2Model, &to->ghoul2Model); + } to->bolt_head = from->bolt_head; to->bolt_lhand = from->bolt_lhand; @@ -1086,6 +1140,20 @@ void CG_NewClientInfo( int clientNum, qboolean entitiesInitialized ) { newInfo.ATST = wasATST; + if (cgs.gametype >= GT_TEAM) + { + if (newInfo.team == TEAM_RED) + { + strcpy(newInfo.skinName, "red"); + strcpy(newInfo.headSkinName, "red"); + } + if (newInfo.team == TEAM_BLUE) + { + strcpy(newInfo.skinName, "blue"); + strcpy(newInfo.headSkinName, "blue"); + } + } + // scan for an existing clientinfo that matches this modelname // so we can avoid loading checks if possible if ( !CG_ScanForExistingClientInfo( &newInfo ) ) { @@ -1123,11 +1191,7 @@ void CG_NewClientInfo( int clientNum, qboolean entitiesInitialized ) { { // Copy the new ghoul2 model to the centity. animation_t *anim; // First check if we have a ghoul2 model on the client entity. - if (cg_entities[clientNum].ghoul2 && trap_G2_HaveWeGhoul2Models(cg_entities[clientNum].ghoul2)) - { - trap_G2API_CleanGhoul2Models(&cg_entities[clientNum].ghoul2); - } - + anim = &ci->animations[ (cg_entities[clientNum].currentState.legsAnim & ~ANIM_TOGGLEBIT) ]; if (anim) @@ -1166,35 +1230,42 @@ void CG_NewClientInfo( int clientNum, qboolean entitiesInitialized ) { cg_entities[clientNum].currentState.torsoAnim = 0; } - trap_G2API_DuplicateGhoul2Instance(ci->ghoul2Model, &cg_entities[clientNum].ghoul2); - //rww - FIXME: Perhaps I'm missing something, but if we're duplicating the instance from ci instead of pointing the cent g2 instance to it, can't we clean one up? (no reason to have - // the same instance duplicated in memory) I'm not touching this at the moment because I don't want to unknowingly break something horribly if I'm wrong - - if (cg_entities[clientNum].weapon > WP_NONE) + if (cg_entities[clientNum].ghoul2 && trap_G2_HaveWeGhoul2Models(cg_entities[clientNum].ghoul2)) { - CG_CopyG2WeaponInstance(cg_entities[clientNum].weapon, cg_entities[clientNum].ghoul2); + trap_G2API_CleanGhoul2Models(&cg_entities[clientNum].ghoul2); } + trap_G2API_DuplicateGhoul2Instance(ci->ghoul2Model, &cg_entities[clientNum].ghoul2); + + /* + if (cg_entities[clientNum].currentState.weapon > WP_NONE) + { + CG_CopyG2WeaponInstance(cg_entities[clientNum].currentState.weapon, cg_entities[clientNum].ghoul2); + } + */ + //It should catch this next update anyway. We just set all ghoul2weapon's to NULL above. } else if (ci->team == TEAM_SPECTATOR && cg_entities[clientNum].ghoul2 && trap_G2_HaveWeGhoul2Models(cg_entities[clientNum].ghoul2)) - { //rww - not doing this seems to allow .ghoul2 to become an invalid pointer. And as we all know, invalid pointers make baby Carmack cry. + { //this shouldn't actually happen now because we are not trying to register models for spectators. But just in case. trap_G2API_CleanGhoul2Models(&cg_entities[clientNum].ghoul2); - trap_G2API_DuplicateGhoul2Instance(ci->ghoul2Model, &cg_entities[clientNum].ghoul2); + if (ci->ghoul2Model && trap_G2_HaveWeGhoul2Models(ci->ghoul2Model)) + { + trap_G2API_DuplicateGhoul2Instance(ci->ghoul2Model, &cg_entities[clientNum].ghoul2); + } } } - +qboolean cgQueueLoad = qfalse; /* ====================== -CG_LoadDeferredPlayers +CG_ActualLoadDeferredPlayers -Called each frame when a player is dead -and the scoreboard is up -so deferred players can be loaded +Called at the beginning of CG_Player if cgQueueLoad is set. ====================== */ -void CG_LoadDeferredPlayers( void ) { +void CG_ActualLoadDeferredPlayers( void ) +{ int i; clientInfo_t *ci; @@ -1213,6 +1284,19 @@ void CG_LoadDeferredPlayers( void ) { } } +/* +====================== +CG_LoadDeferredPlayers + +Called each frame when a player is dead +and the scoreboard is up +so deferred players can be loaded +====================== +*/ +void CG_LoadDeferredPlayers( void ) { + cgQueueLoad = qtrue; +} + /* ============================================================================= @@ -1223,37 +1307,6 @@ PLAYER ANIMATION static qboolean CG_FirstAnimFrame(clientInfo_t *ci, lerpFrame_t *lf, qboolean torsoOnly, float speedScale); -qboolean CG_DeathAnim( int anim ) -{ - switch((anim&~ANIM_TOGGLEBIT)) - { - case BOTH_DIVE1: - case BOTH_DEATHBACKWARD1: - case BOTH_DEATHBACKWARD2: - case BOTH_DEATHFORWARD1: - case BOTH_DEATHFORWARD2: - case BOTH_DEATH1: - case BOTH_DEATH2: - case BOTH_DEATH3: - case BOTH_DEATH4: - case BOTH_DEATH5: - case BOTH_DEATH6: - case BOTH_DEATH7: - - case BOTH_DEATH1IDLE: - case BOTH_LYINGDEATH1: - case BOTH_STUMBLEDEATH1: - case BOTH_FALLDEATH1: - case BOTH_FALLDEATH1INAIR: - case BOTH_FALLDEATH1LAND: - return qtrue; - break; - default: - return qfalse; - break; - } -} - qboolean CG_InRoll( centity_t *cent ) { switch ( (cent->currentState.legsAnim&~ANIM_TOGGLEBIT) ) @@ -1271,9 +1324,6 @@ qboolean CG_InRoll( centity_t *cent ) return qfalse; } -qboolean PM_SaberInSpecial( int move ); -qboolean PM_SaberInSpecialAttack( int anim ); - /* =============== CG_SetLerpFrameAnimation @@ -1486,12 +1536,12 @@ static void CG_SetLerpFrameAnimation( centity_t *cent, clientInfo_t *ci, lerpFra if (!cent->isATST) { - if (BG_FlippingAnim(newAnimation) || CG_DeathAnim(newAnimation)) + if (BG_FlippingAnim(newAnimation) || BG_InDeathAnim(newAnimation)) { flags &= ~BONE_ANIM_BLEND; } else if ( oldAnim != -1 && - (BG_FlippingAnim(oldAnim) || CG_DeathAnim(oldAnim)) ) + (BG_FlippingAnim(oldAnim) || BG_InDeathAnim(oldAnim)) ) { flags &= ~BONE_ANIM_BLEND; } @@ -1538,12 +1588,12 @@ static void CG_SetLerpFrameAnimation( centity_t *cent, clientInfo_t *ci, lerpFra !BG_SpinningSaberAnim( cent->currentState.torsoAnim ) && !BG_InSpecialJump( cent->currentState.legsAnim ) && !BG_InSpecialJump( cent->currentState.torsoAnim ) && - !CG_DeathAnim(cent->currentState.legsAnim) && - !CG_DeathAnim(cent->currentState.torsoAnim) && + !BG_InDeathAnim(cent->currentState.legsAnim) && + !BG_InDeathAnim(cent->currentState.torsoAnim) && !CG_InRoll(cent) && - !PM_SaberInSpecial(cent->currentState.saberMove) && - !PM_SaberInSpecialAttack(cent->currentState.torsoAnim) && - !PM_SaberInSpecialAttack(cent->currentState.legsAnim) ) + !BG_SaberInSpecial(cent->currentState.saberMove) && + !BG_SaberInSpecialAttack(cent->currentState.torsoAnim) && + !BG_SaberInSpecialAttack(cent->currentState.legsAnim) ) { trap_G2API_SetBoneAnim(cent->ghoul2, 0, "Motion", anim->firstFrame, anim->firstFrame + anim->numFrames, flags, animSpeed, lf->frameTime, -1, 150); } @@ -2316,19 +2366,19 @@ void CG_G2ClientSpineAngles( centity_t *cent, vec3_t viewAngles, const vec3_t an !BG_SpinningSaberAnim( cent->currentState.torsoAnim ) && !BG_InSpecialJump( cent->currentState.legsAnim ) && !BG_InSpecialJump( cent->currentState.torsoAnim ) && - !CG_DeathAnim(cent->currentState.legsAnim) && - !CG_DeathAnim(cent->currentState.torsoAnim) && + !BG_InDeathAnim(cent->currentState.legsAnim) && + !BG_InDeathAnim(cent->currentState.torsoAnim) && !CG_InRoll(cent) && - !PM_SaberInSpecial(cent->currentState.saberMove) && - !PM_SaberInSpecialAttack(cent->currentState.torsoAnim) && - !PM_SaberInSpecialAttack(cent->currentState.legsAnim) && + !BG_SaberInSpecial(cent->currentState.saberMove) && + !BG_SaberInSpecialAttack(cent->currentState.torsoAnim) && + !BG_SaberInSpecialAttack(cent->currentState.legsAnim) && /* !BG_FlippingAnim( cent->rootBone ) && !BG_SpinningSaberAnim( cent->rootBone ) && !BG_InSpecialJump( cent->rootBone ) && - !CG_DeathAnim(cent->rootBone) && - !PM_SaberInSpecialAttack(cent->rootBone) && + !BG_InDeathAnim(cent->rootBone) && + !BG_SaberInSpecialAttack(cent->rootBone) && */ !(cent->currentState.eFlags & EF_DEAD) ) @@ -2911,118 +2961,63 @@ static void CG_TrailItem( centity_t *cent, qhandle_t hModel ) { CG_PlayerFlag =============== */ -static void CG_PlayerFlag( centity_t *cent, qhandle_t hSkin, refEntity_t *torso ) { -#if 0 - clientInfo_t *ci; - refEntity_t pole; - refEntity_t flag; - vec3_t angles, dir; - int legsAnim, /*flagAnim,*/ updateangles; - float angle, d; +static void CG_PlayerFlag( centity_t *cent, qhandle_t hModel ) { + refEntity_t ent; + vec3_t angles; + vec3_t axis[3]; + vec3_t boltOrg, tAng, getAng, right; + mdxaBone_t boltMatrix; - // show the flag pole model - memset( &pole, 0, sizeof(pole) ); - pole.hModel = cgs.media.flagPoleModel; - VectorCopy( torso->lightingOrigin, pole.lightingOrigin ); - pole.shadowPlane = torso->shadowPlane; - pole.renderfx = torso->renderfx; - CG_PositionEntityOnTag( &pole, torso, torso->hModel, "tag_flag" ); - trap_R_AddRefEntityToScene( &pole ); - - // show the flag model - memset( &flag, 0, sizeof(flag) ); - flag.hModel = cgs.media.flagFlapModel; - flag.customSkin = hSkin; - VectorCopy( torso->lightingOrigin, flag.lightingOrigin ); - flag.shadowPlane = torso->shadowPlane; - flag.renderfx = torso->renderfx; - - VectorClear(angles); - - updateangles = qfalse; - legsAnim = cent->currentState.legsAnim & ~ANIM_TOGGLEBIT; -/* - if( legsAnim == TORSO_WEAPONREADY3 || legsAnim == BOTH_CROUCH1IDLE ) { - flagAnim = FLAG_STAND; - } else if ( legsAnim == BOTH_WALK1 || legsAnim == BOTH_CROUCH1WALK ) { - flagAnim = FLAG_STAND; - updateangles = qtrue; - } else { - flagAnim = FLAG_RUN; - updateangles = qtrue; - } -*/ - if ( updateangles ) { - - VectorCopy( cent->currentState.pos.trDelta, dir ); - // add gravity - dir[2] += 100; - VectorNormalize( dir ); - d = DotProduct(pole.axis[2], dir); - // if there is anough movement orthogonal to the flag pole - if (fabs(d) < 0.9) { - // - d = DotProduct(pole.axis[0], dir); - if (d > 1.0f) { - d = 1.0f; - } - else if (d < -1.0f) { - d = -1.0f; - } - angle = acos(d); - - d = DotProduct(pole.axis[1], dir); - if (d < 0) { - angles[YAW] = 360 - angle * 180 / M_PI; - } - else { - angles[YAW] = angle * 180 / M_PI; - } - if (angles[YAW] < 0) - angles[YAW] += 360; - if (angles[YAW] > 360) - angles[YAW] -= 360; - - //vectoangles( cent->currentState.pos.trDelta, tmpangles ); - //angles[YAW] = tmpangles[YAW] + 45 - cent->pe.torso.yawAngle; - // change the yaw angle - CG_SwingAngles( angles[YAW], 25, 90, 0.15f, ¢->pe.flag.yawAngle, ¢->pe.flag.yawing ); - } - - /* - d = DotProduct(pole.axis[2], dir); - angle = Q_acos(d); - - d = DotProduct(pole.axis[1], dir); - if (d < 0) { - angle = 360 - angle * 180 / M_PI; - } - else { - angle = angle * 180 / M_PI; - } - if (angle > 340 && angle < 20) { - flagAnim = FLAG_RUNUP; - } - if (angle > 160 && angle < 200) { - flagAnim = FLAG_RUNDOWN; - } - */ + if (!cent->ghoul2) + { + return; } - // set the yaw angle - angles[YAW] = cent->pe.flag.yawAngle; - // lerp the flag animation frames - ci = &cgs.clientinfo[ cent->currentState.clientNum ]; -// CG_RunLerpFrame( ci, ¢->pe.flag, flagAnim, 1 ); - flag.oldframe = cent->pe.flag.oldFrame; - flag.frame = cent->pe.flag.frame; - flag.backlerp = cent->pe.flag.backlerp; + VectorSet( tAng, cent->turAngles[PITCH], cent->turAngles[YAW], cent->turAngles[ROLL] ); - AnglesToAxis( angles, flag.axis ); - CG_PositionRotatedEntityOnTag( &flag, &pole, pole.hModel, "tag_flag" ); + trap_G2API_GetBoltMatrix(cent->ghoul2, 0, cgs.clientinfo[cent->currentState.number].bolt_llumbar, &boltMatrix, tAng, cent->lerpOrigin, cg.time, cgs.gameModels, cent->modelScale); + trap_G2API_GiveMeVectorFromMatrix(&boltMatrix, ORIGIN, boltOrg); - trap_R_AddRefEntityToScene( &flag ); -#endif + trap_G2API_GiveMeVectorFromMatrix(&boltMatrix, POSITIVE_X, tAng); + vectoangles(tAng, tAng); + + VectorCopy(cent->lerpAngles, angles); + + boltOrg[2] -= 12; + VectorSet(getAng, 0, cent->lerpAngles[1], 0); + AngleVectors(getAng, 0, right, 0); + boltOrg[0] += right[0]*8; + boltOrg[1] += right[1]*8; + boltOrg[2] += right[2]*8; + + angles[PITCH] = -cent->lerpAngles[PITCH]/2-30; + angles[YAW] = tAng[YAW]+270; + + AnglesToAxis(angles, axis); + + memset( &ent, 0, sizeof( ent ) ); + VectorMA( boltOrg, 24, axis[0], ent.origin ); + + angles[ROLL] += 20; + AnglesToAxis( angles, ent.axis ); + + ent.hModel = hModel; + + ent.modelScale[0] = 0.5; + ent.modelScale[1] = 0.5; + ent.modelScale[2] = 0.5; + ScaleModelAxis(&ent); + + /* + if (cent->currentState.number == cg.snap->ps.clientNum) + { //If we're the current client (in third person), render the flag on our back transparently + ent.renderfx |= RF_FORCE_ENT_ALPHA; + ent.shaderRGBA[3] = 100; + } + */ + //FIXME: Not doing this at the moment because sorting totally messes up + + trap_R_AddRefEntityToScene( &ent ); } @@ -3048,34 +3043,18 @@ static void CG_PlayerPowerups( centity_t *cent, refEntity_t *torso ) { ci = &cgs.clientinfo[ cent->currentState.clientNum ]; // redflag if ( powerups & ( 1 << PW_REDFLAG ) ) { - if (ci->newAnims) { - CG_PlayerFlag( cent, cgs.media.redFlagFlapSkin, torso ); - } - else { - CG_TrailItem( cent, cgs.media.redFlagModel ); - } + CG_PlayerFlag( cent, cgs.media.redFlagModel ); trap_R_AddLightToScene( cent->lerpOrigin, 200 + (rand()&31), 1.0, 0.2f, 0.2f ); } // blueflag if ( powerups & ( 1 << PW_BLUEFLAG ) ) { - if (ci->newAnims){ - CG_PlayerFlag( cent, cgs.media.blueFlagFlapSkin, torso ); - } - else { - CG_TrailItem( cent, cgs.media.blueFlagModel ); - } + CG_PlayerFlag( cent, cgs.media.blueFlagModel ); trap_R_AddLightToScene( cent->lerpOrigin, 200 + (rand()&31), 0.2f, 0.2f, 1.0 ); } // neutralflag if ( powerups & ( 1 << PW_NEUTRALFLAG ) ) { - if (ci->newAnims) { - CG_PlayerFlag( cent, cgs.media.neutralFlagFlapSkin, torso ); - } - else { - CG_TrailItem( cent, cgs.media.neutralFlagModel ); - } trap_R_AddLightToScene( cent->lerpOrigin, 200 + (rand()&31), 1.0, 1.0, 1.0 ); } @@ -3407,6 +3386,56 @@ void CG_ForcePushBlur( vec3_t org ) ex->refEntity.customShader = trap_R_RegisterShader( "gfx/effects/forcePush" ); } +void CG_ForceGripEffect( vec3_t org ) +{ + localEntity_t *ex; + float wv = sin( cg.time * 0.004f ) * 0.08f + 0.1f; + + ex = CG_AllocLocalEntity(); + ex->leType = LE_PUFF; + ex->refEntity.reType = RT_SPRITE; + ex->radius = 2.0f; + ex->startTime = cg.time; + ex->endTime = ex->startTime + 120; + VectorCopy( org, ex->pos.trBase ); + ex->pos.trTime = cg.time; + ex->pos.trType = TR_LINEAR; + VectorScale( cg.refdef.viewaxis[1], 55, ex->pos.trDelta ); + + ex->color[0] = 200+((wv*255)); + if (ex->color[0] > 255) + { + ex->color[0] = 255; + } + ex->color[1] = 0; + ex->color[2] = 0; + ex->refEntity.customShader = trap_R_RegisterShader( "gfx/effects/forcePush" ); + + ex = CG_AllocLocalEntity(); + ex->leType = LE_PUFF; + ex->refEntity.reType = RT_SPRITE; + ex->refEntity.rotation = 180.0f; + ex->radius = 2.0f; + ex->startTime = cg.time; + ex->endTime = ex->startTime + 120; + VectorCopy( org, ex->pos.trBase ); + ex->pos.trTime = cg.time; + ex->pos.trType = TR_LINEAR; + VectorScale( cg.refdef.viewaxis[1], -55, ex->pos.trDelta ); + + /* + ex->color[0] = 200+((wv*255)); + if (ex->color[0] > 255) + { + ex->color[0] = 255; + } + */ + ex->color[0] = 255; + ex->color[1] = 255; + ex->color[2] = 255; + ex->refEntity.customShader = cgs.media.redSaberGlowShader;//trap_R_RegisterShader( "gfx/effects/forcePush" ); +} + static void CG_ForcePushBodyBlur( centity_t *cent, vec3_t origin, vec3_t tempAngles ) { vec3_t eyePos; @@ -3966,7 +3995,13 @@ Ghoul2 Insert Start if ( trace.fraction < 1.0f ) { - trap_FX_PlayEffectID( trap_FX_RegisterEffect("saber/spark.efx"), trace.endpos, trace.plane.normal ); + vec3_t trDir; + VectorCopy(trace.plane.normal, trDir); + if (!trDir[0] && !trDir[1] && !trDir[2]) + { + trDir[1] = 1; + } + trap_FX_PlayEffectID( trap_FX_RegisterEffect("saber/spark.efx"), trace.endpos, trDir ); //Stop saber? (it wouldn't look right if it was stuck through a thin wall and unable to hurt players on the other side) VectorSubtract(org_, trace.endpos, v); @@ -4036,7 +4071,14 @@ Ghoul2 Insert Start if ( trace.fraction < 1.0f ) { - trap_FX_PlayEffectID( trap_FX_RegisterEffect("saber/spark.efx"), trace.endpos, trace.plane.normal ); + vec3_t trDir; + VectorCopy(trace.plane.normal, trDir); + if (!trDir[0] && !trDir[1] && !trDir[2]) + { + trDir[1] = 1; + } + + trap_FX_PlayEffectID( trap_FX_RegisterEffect("saber/spark.efx"), trace.endpos, trDir ); //Stop saber? (it wouldn't look right if it was stuck through a thin wall and unable to hurt players on the other side) VectorSubtract(otherPos, trace.endpos, v); @@ -4601,6 +4643,8 @@ void CG_AddRandomLightning(vec3_t start, vec3_t end) CG_AddLightningBeam(inOrg, outOrg); } +extern char *forceHolocronModels[]; + /* =============== CG_Player @@ -4632,6 +4676,12 @@ void CG_Player( centity_t *cent ) { int effectTimeLayer = 0; qboolean gotLHandMatrix = qfalse; + if (cgQueueLoad) + { + CG_ActualLoadDeferredPlayers(); + cgQueueLoad = qfalse; + } + // the client number is stored in clientNum. It can't be derived // from the entity number, because a single client may have // multiple corpses on the level using the same clientinfo @@ -4647,6 +4697,8 @@ void CG_Player( centity_t *cent ) { return; } + cent->ghoul2 = cg_entities[cent->currentState.number].ghoul2; + if (!cent->ghoul2) { //not ready yet? return; @@ -4893,6 +4945,15 @@ void CG_Player( centity_t *cent ) { CG_DrawYsalimariSphere(cent, cent->lerpOrigin, efColors); } + if (cent->currentState.eFlags & EF_INVULNERABLE) + { + vec3_t efColors; + efColors[0] = 0; + efColors[1] = 255; + efColors[2] = 0; + CG_DrawYsalimariSphere(cent, cent->lerpOrigin, efColors); + } + // add the shadow shadow = CG_PlayerShadow( cent, &shadowPlane ); @@ -4965,6 +5026,139 @@ void CG_Player( centity_t *cent ) { trap_R_AddRefEntityToScene( &seeker ); } + if (cgs.gametype == GT_HOLOCRON && cent->currentState.time2 && (cg.renderingThirdPerson || cg.snap->ps.clientNum != cent->currentState.number)) + { + int i = 0; + int renderedHolos = 0; + refEntity_t holoRef; + + while (i < NUM_FORCE_POWERS && renderedHolos < 3) + { + if (cent->currentState.time2 & (1 << i)) + { + memset( &holoRef, 0, sizeof(holoRef) ); + + VectorCopy(cent->lerpOrigin, elevated); + elevated[2] += 8; + + VectorCopy( elevated, holoRef.lightingOrigin ); + holoRef.shadowPlane = shadowPlane; + holoRef.renderfx = 0;//RF_THIRD_PERSON; + + if (renderedHolos == 0) + { + angle = ((cg.time / 8) & 255) * (M_PI * 2) / 255; + dir[0] = cos(angle) * 20; + dir[1] = sin(angle) * 20; + dir[2] = cos(angle) * 20; + VectorAdd(elevated, dir, holoRef.origin); + + angles[0] = sin(angle) * 30; + angles[1] = (angle * 180 / M_PI) + 90; + if (angles[1] > 360) + angles[1] -= 360; + angles[2] = 0; + AnglesToAxis( angles, holoRef.axis ); + } + else if (renderedHolos == 1) + { + angle = ((cg.time / 8) & 255) * (M_PI * 2) / 255 + M_PI; + if (angle > M_PI * 2) + angle -= (float)M_PI * 2; + dir[0] = sin(angle) * 20; + dir[1] = cos(angle) * 20; + dir[2] = cos(angle) * 20; + VectorAdd(elevated, dir, holoRef.origin); + + angles[0] = cos(angle - 0.5 * M_PI) * 30; + angles[1] = 360 - (angle * 180 / M_PI); + if (angles[1] > 360) + angles[1] -= 360; + angles[2] = 0; + AnglesToAxis( angles, holoRef.axis ); + } + else + { + angle = ((cg.time / 6) & 255) * (M_PI * 2) / 255 + 0.5 * M_PI; + if (angle > M_PI * 2) + angle -= (float)M_PI * 2; + dir[0] = sin(angle) * 20; + dir[1] = cos(angle) * 20; + dir[2] = 0; + VectorAdd(elevated, dir, holoRef.origin); + + VectorCopy(dir, holoRef.axis[1]); + VectorNormalize(holoRef.axis[1]); + VectorSet(holoRef.axis[2], 0, 0, 1); + CrossProduct(holoRef.axis[1], holoRef.axis[2], holoRef.axis[0]); + } + + holoRef.modelScale[0] = 0.5; + holoRef.modelScale[1] = 0.5; + holoRef.modelScale[2] = 0.5; + ScaleModelAxis(&holoRef); + + { + float wv; + addspriteArgStruct_t fxSArgs; + vec3_t holoCenter; + + holoCenter[0] = holoRef.origin[0] + holoRef.axis[2][0]*18; + holoCenter[1] = holoRef.origin[1] + holoRef.axis[2][1]*18; + holoCenter[2] = holoRef.origin[2] + holoRef.axis[2][2]*18; + + wv = sin( cg.time * 0.004f ) * 0.08f + 0.1f; + + VectorCopy(holoCenter, fxSArgs.origin); + VectorClear(fxSArgs.vel); + VectorClear(fxSArgs.accel); + fxSArgs.scale = wv*60; + fxSArgs.dscale = wv*60; + fxSArgs.sAlpha = wv*12; + fxSArgs.eAlpha = wv*12; + fxSArgs.rotation = 0.0f; + fxSArgs.bounce = 0.0f; + fxSArgs.life = 1.0f; + + fxSArgs.flags = 0x08000000|0x00000001; + + if (forcePowerDarkLight[i] == FORCE_DARKSIDE) + { //dark + fxSArgs.sAlpha *= 2; + fxSArgs.eAlpha *= 2; + fxSArgs.shader = cgs.media.redSaberGlowShader; + trap_FX_AddSprite(&fxSArgs); + } + else if (forcePowerDarkLight[i] == FORCE_LIGHTSIDE) + { //light + fxSArgs.sAlpha *= 1.5; + fxSArgs.eAlpha *= 1.5; + fxSArgs.shader = cgs.media.redSaberGlowShader; + trap_FX_AddSprite(&fxSArgs); + fxSArgs.shader = cgs.media.greenSaberGlowShader; + trap_FX_AddSprite(&fxSArgs); + fxSArgs.shader = cgs.media.blueSaberGlowShader; + trap_FX_AddSprite(&fxSArgs); + } + else + { //neutral + fxSArgs.sAlpha *= 0.5; + fxSArgs.eAlpha *= 0.5; + fxSArgs.shader = cgs.media.greenSaberGlowShader; + trap_FX_AddSprite(&fxSArgs); + fxSArgs.shader = cgs.media.blueSaberGlowShader; + trap_FX_AddSprite(&fxSArgs); + } + } + + holoRef.hModel = trap_R_RegisterModel(forceHolocronModels[i]); + trap_R_AddRefEntityToScene( &holoRef ); + + renderedHolos++; + } + i++; + } + } doEssentialOne: // add a water splash if partially in and out of water CG_PlayerSplash( cent ); @@ -5279,7 +5473,87 @@ doEssentialTwo: efOrg[1] = lHandMatrix.matrix[1][3]; efOrg[2] = lHandMatrix.matrix[2][3]; - CG_ForcePushBlur( efOrg ); + if ( (cent->currentState.forcePowersActive & (1 << FP_GRIP)) && + (cg.renderingThirdPerson || cent->currentState.number != cg.snap->ps.clientNum) ) + { + vec3_t boltDir; + vec3_t origBolt; + VectorCopy(efOrg, origBolt); + trap_G2API_GiveMeVectorFromMatrix( &lHandMatrix, NEGATIVE_Y, boltDir ); + + CG_ForceGripEffect( efOrg ); + CG_ForceGripEffect( efOrg ); + + //Render a scaled version of the model's hand with a n337 looking shader + { + const char *rotateBone; + char *limbName; + char *limbCapName; + vec3_t armAng; + float wv = sin( cg.time * 0.003f ) * 0.08f + 0.1f; + + rotateBone = "lradius"; + limbName = "l_arm"; + limbCapName = "l_arm_cap_torso_off"; + + if (cent->grip_arm.ghoul2 && trap_G2_HaveWeGhoul2Models(cent->grip_arm.ghoul2)) + { + trap_G2API_CleanGhoul2Models(&(cent->grip_arm.ghoul2)); + } + + memset( ¢->grip_arm, 0, sizeof(cent->grip_arm) ); + + VectorCopy(origBolt, efOrg); + trap_G2API_GiveMeVectorFromMatrix( &lHandMatrix, NEGATIVE_Y, boltDir ); + efOrg[0] += boltDir[0]*8; + efOrg[1] += boltDir[1]*8; + efOrg[2] += boltDir[2]*8; + trap_G2API_GiveMeVectorFromMatrix( &lHandMatrix, NEGATIVE_X, boltDir ); + efOrg[0] -= boltDir[0]*4; + efOrg[1] -= boltDir[1]*4; + efOrg[2] -= boltDir[2]*4; + + VectorCopy(efOrg, cent->grip_arm.origin); + VectorCopy(cent->grip_arm.origin, cent->grip_arm.lightingOrigin); + + VectorCopy(cent->lerpAngles, armAng); + armAng[ROLL] = -90; + AnglesToAxis(armAng, cent->grip_arm.axis); + + trap_G2API_DuplicateGhoul2Instance(cent->ghoul2, ¢->grip_arm.ghoul2); + + trap_G2API_SetRootSurface(cent->grip_arm.ghoul2, 0, limbName); + trap_G2API_SetNewOrigin(cent->grip_arm.ghoul2, trap_G2API_AddBolt(cent->grip_arm.ghoul2, 0, rotateBone)); + trap_G2API_SetSurfaceOnOff(cent->grip_arm.ghoul2, limbCapName, 0); + + cent->grip_arm.modelScale[0] = 1;//+(wv*6); + cent->grip_arm.modelScale[1] = 1;//+(wv*6); + cent->grip_arm.modelScale[2] = 1;//+(wv*6); + ScaleModelAxis(¢->grip_arm); + + cent->grip_arm.radius = 64; + + cent->grip_arm.customShader = trap_R_RegisterShader( "gfx/misc/red_portashield" ); + + cent->grip_arm.renderfx |= RF_RGB_TINT; + cent->grip_arm.shaderRGBA[0] = 255 - (wv*900); + if (cent->grip_arm.shaderRGBA[0] < 30) + { + cent->grip_arm.shaderRGBA[0] = 30; + } + if (cent->grip_arm.shaderRGBA[0] > 255) + { + cent->grip_arm.shaderRGBA[0] = 255; + } + cent->grip_arm.shaderRGBA[1] = cent->grip_arm.shaderRGBA[2] = cent->grip_arm.shaderRGBA[0]; + + trap_R_AddRefEntityToScene( ¢->grip_arm ); + } + } + else if (!(cent->currentState.forcePowersActive & (1 << FP_GRIP))) + { + CG_ForcePushBlur( efOrg ); + } } if (cent->currentState.weapon == WP_STUN_BATON && (cent->currentState.eFlags & EF_FIRING)) @@ -5483,7 +5757,7 @@ stillDoSaber: fxSArgs.rotation = 0.0f; fxSArgs.bounce = 0.0f; fxSArgs.life = 1.0f; - fxSArgs.shader = cgs.media.yellowSaberGlowShader; + fxSArgs.shader = cgs.media.yellowDroppedSaberShader; fxSArgs.flags = 0x08000000; trap_FX_AddSprite(&fxSArgs); } @@ -5787,12 +6061,12 @@ doEssentialThree: legs.renderfx &= ~RF_RGB_TINT; legs.renderfx &= ~RF_FORCE_ENT_ALPHA; - legs.renderfx |= RF_DEPTHHACK; + legs.renderfx |= RF_NODEPTH; legs.customShader = cgs.media.forceSightBubble; trap_R_AddRefEntityToScene( &legs ); - legs.renderfx &= ~RF_DEPTHHACK; + legs.renderfx &= ~RF_NODEPTH; } if ((cg.snap->ps.fd.forcePowersActive & (1 << FP_SEE)) && cg.snap->ps.clientNum != cent->currentState.number && cg_auraShell.integer) @@ -5832,11 +6106,11 @@ doEssentialThree: } else */ { // See through walls. - legs.renderfx |= RF_MINLIGHT | RF_DEPTHHACK; + legs.renderfx |= RF_MINLIGHT | RF_NODEPTH; if (cg.snap->ps.fd.forcePowerLevel[FP_SEE] < FORCE_LEVEL_2) { //only level 2+ can see players through walls - legs.renderfx &= ~RF_DEPTHHACK; + legs.renderfx &= ~RF_NODEPTH; } } @@ -5882,7 +6156,7 @@ doEssentialThree: trap_R_AddRefEntityToScene( &legs ); if ( random() > 0.9f ) - trap_S_StartSound ( NULL, cent->currentState.number, CHAN_AUTO, trap_S_RegisterSound( "sound/effects/energy_crackle.wav" ) ); + trap_S_StartSound ( NULL, cent->currentState.number, CHAN_AUTO, cgs.media.crackleSound ); } } diff --git a/CODEmp/cgame/cg_playerstate.c b/CODE-mp/cgame/cg_playerstate.c similarity index 93% rename from CODEmp/cgame/cg_playerstate.c rename to CODE-mp/cgame/cg_playerstate.c index da612c5..88db5ad 100644 --- a/CODEmp/cgame/cg_playerstate.c +++ b/CODE-mp/cgame/cg_playerstate.c @@ -283,6 +283,8 @@ static void pushReward(sfxHandle_t sfx, qhandle_t shader, int rewardCount) { } } +int cgAnnouncerTime = 0; //to prevent announce sounds from playing on top of each other + /* ================== CG_CheckLocalSounds @@ -392,7 +394,7 @@ void CG_CheckLocalSounds( playerState_t *ps, playerState_t *ops ) { reward = qfalse; #endif // lead changes - if (!reward) { + if (!reward && cgAnnouncerTime < cg.time) { // if ( !cg.warmup ) { // never play lead changes during warmup @@ -400,10 +402,12 @@ void CG_CheckLocalSounds( playerState_t *ps, playerState_t *ops ) { if ( cgs.gametype < GT_TEAM) { if ( ps->persistant[PERS_RANK] == 0 ) { CG_AddBufferedSound(cgs.media.takenLeadSound); + cgAnnouncerTime = cg.time + 3000; } else if ( ps->persistant[PERS_RANK] == RANK_TIED_FLAG ) { //CG_AddBufferedSound(cgs.media.tiedLeadSound); } else if ( ( ops->persistant[PERS_RANK] & ~RANK_TIED_FLAG ) == 0 ) { CG_AddBufferedSound(cgs.media.lostLeadSound); + cgAnnouncerTime = cg.time + 3000; } } } @@ -411,7 +415,7 @@ void CG_CheckLocalSounds( playerState_t *ps, playerState_t *ops ) { } // timelimit warnings - if ( cgs.timelimit > 0 ) { + if ( cgs.timelimit > 0 && cgAnnouncerTime < cg.time ) { int msec; msec = cg.time - cgs.levelStartTime; @@ -422,27 +426,32 @@ void CG_CheckLocalSounds( playerState_t *ps, playerState_t *ops ) { else if ( !( cg.timelimitWarnings & 2 ) && msec > (cgs.timelimit - 1) * 60 * 1000 ) { cg.timelimitWarnings |= 1 | 2; trap_S_StartLocalSound( cgs.media.oneMinuteSound, CHAN_ANNOUNCER ); + cgAnnouncerTime = cg.time + 3000; } else if ( cgs.timelimit > 5 && !( cg.timelimitWarnings & 1 ) && msec > (cgs.timelimit - 5) * 60 * 1000 ) { cg.timelimitWarnings |= 1; trap_S_StartLocalSound( cgs.media.fiveMinuteSound, CHAN_ANNOUNCER ); + cgAnnouncerTime = cg.time + 3000; } } // fraglimit warnings - if ( cgs.fraglimit > 0 && cgs.gametype < GT_CTF && cgs.gametype != GT_TOURNAMENT) { + if ( cgs.fraglimit > 0 && cgs.gametype < GT_CTF && cgs.gametype != GT_TOURNAMENT && cgAnnouncerTime < cg.time) { highScore = cgs.scores1; if ( !( cg.fraglimitWarnings & 4 ) && highScore == (cgs.fraglimit - 1) ) { cg.fraglimitWarnings |= 1 | 2 | 4; CG_AddBufferedSound(cgs.media.oneFragSound); + cgAnnouncerTime = cg.time + 3000; } else if ( cgs.fraglimit > 2 && !( cg.fraglimitWarnings & 2 ) && highScore == (cgs.fraglimit - 2) ) { cg.fraglimitWarnings |= 1 | 2; CG_AddBufferedSound(cgs.media.twoFragSound); + cgAnnouncerTime = cg.time + 3000; } else if ( cgs.fraglimit > 3 && !( cg.fraglimitWarnings & 1 ) && highScore == (cgs.fraglimit - 3) ) { cg.fraglimitWarnings |= 1; CG_AddBufferedSound(cgs.media.threeFragSound); + cgAnnouncerTime = cg.time + 3000; } } } diff --git a/CODEmp/cgame/cg_predict.c b/CODE-mp/cgame/cg_predict.c similarity index 100% rename from CODEmp/cgame/cg_predict.c rename to CODE-mp/cgame/cg_predict.c diff --git a/CODEmp/cgame/cg_public.h b/CODE-mp/cgame/cg_public.h similarity index 95% rename from CODEmp/cgame/cg_public.h rename to CODE-mp/cgame/cg_public.h index 968b085..4831038 100644 --- a/CODEmp/cgame/cg_public.h +++ b/CODE-mp/cgame/cg_public.h @@ -165,6 +165,8 @@ typedef enum { CG_PC_FREE_SOURCE, CG_PC_READ_TOKEN, CG_PC_SOURCE_FILE_AND_LINE, + CG_PC_LOAD_GLOBAL_DEFINES, + CG_PC_REMOVE_ALL_GLOBAL_DEFINES, CG_S_STOPBACKGROUNDTRACK, CG_REAL_TIME, diff --git a/CODEmp/cgame/cg_saga.c b/CODE-mp/cgame/cg_saga.c similarity index 100% rename from CODEmp/cgame/cg_saga.c rename to CODE-mp/cgame/cg_saga.c diff --git a/CODEmp/cgame/cg_scoreboard.c b/CODE-mp/cgame/cg_scoreboard.c similarity index 96% rename from CODEmp/cgame/cg_scoreboard.c rename to CODE-mp/cgame/cg_scoreboard.c index 7c7d2e7..25bce0b 100644 --- a/CODEmp/cgame/cg_scoreboard.c +++ b/CODE-mp/cgame/cg_scoreboard.c @@ -269,7 +269,7 @@ qboolean CG_DrawOldScoreboard( void ) { // fragged by ... line if ( cg.killerName[0] ) { - s = va("Fragged by %s", cg.killerName ); + s = va("%s %s", CG_GetStripEdString("INGAMETEXT", "KILLEDBY"), cg.killerName ); w = CG_DrawStrlen( s ) * BIGCHAR_WIDTH; x = ( SCREEN_WIDTH - w ) / 2; y = 40; diff --git a/CODEmp/cgame/cg_servercmds.c b/CODE-mp/cgame/cg_servercmds.c similarity index 94% rename from CODEmp/cgame/cg_servercmds.c rename to CODE-mp/cgame/cg_servercmds.c index f474d39..2eb0f84 100644 --- a/CODEmp/cgame/cg_servercmds.c +++ b/CODE-mp/cgame/cg_servercmds.c @@ -138,6 +138,17 @@ void CG_ParseServerinfo( void ) { trap_Cvar_Set("g_redTeam", cgs.redTeam); Q_strncpyz( cgs.blueTeam, Info_ValueForKey( info, "g_blueTeam" ), sizeof(cgs.blueTeam) ); trap_Cvar_Set("g_blueTeam", cgs.blueTeam); + + trap_Cvar_Set ( "ui_about_gametype", va("%i", cgs.gametype ) ); + trap_Cvar_Set ( "ui_about_fraglimit", va("%i", cgs.fraglimit ) ); + trap_Cvar_Set ( "ui_about_capturelimit", va("%i", cgs.capturelimit ) ); + trap_Cvar_Set ( "ui_about_timelimit", va("%i", cgs.timelimit ) ); + trap_Cvar_Set ( "ui_about_maxclients", va("%i", cgs.maxclients ) ); + trap_Cvar_Set ( "ui_about_dmflags", va("%i", cgs.dmflags ) ); + trap_Cvar_Set ( "ui_about_mapname", mapname ); + trap_Cvar_Set ( "ui_about_hostname", Info_ValueForKey( info, "sv_hostname" ) ); + trap_Cvar_Set ( "ui_about_needpass", Info_ValueForKey( info, "g_needpass" ) ); + trap_Cvar_Set ( "ui_about_botminplayers", Info_ValueForKey ( info, "bot_minplayers" ) ); } /* diff --git a/CODEmp/cgame/cg_snapshot.c b/CODE-mp/cgame/cg_snapshot.c similarity index 100% rename from CODEmp/cgame/cg_snapshot.c rename to CODE-mp/cgame/cg_snapshot.c diff --git a/CODEmp/cgame/cg_syscalls.c b/CODE-mp/cgame/cg_syscalls.c similarity index 95% rename from CODEmp/cgame/cg_syscalls.c rename to CODE-mp/cgame/cg_syscalls.c index 651c5cd..f9ae526 100644 --- a/CODEmp/cgame/cg_syscalls.c +++ b/CODE-mp/cgame/cg_syscalls.c @@ -437,6 +437,16 @@ int trap_PC_SourceFileAndLine( int handle, char *filename, int *line ) { return syscall( CG_PC_SOURCE_FILE_AND_LINE, handle, filename, line ); } +int trap_PC_LoadGlobalDefines ( const char* filename ) +{ + return syscall ( CG_PC_LOAD_GLOBAL_DEFINES, filename ); +} + +void trap_PC_RemoveAllGlobalDefines ( void ) +{ + syscall ( CG_PC_REMOVE_ALL_GLOBAL_DEFINES ); +} + void trap_S_StopBackgroundTrack( void ) { syscall( CG_S_STOPBACKGROUNDTRACK ); } diff --git a/CODEmp/cgame/cg_turret.c b/CODE-mp/cgame/cg_turret.c similarity index 100% rename from CODEmp/cgame/cg_turret.c rename to CODE-mp/cgame/cg_turret.c diff --git a/CODEmp/cgame/cg_view.c b/CODE-mp/cgame/cg_view.c similarity index 100% rename from CODEmp/cgame/cg_view.c rename to CODE-mp/cgame/cg_view.c diff --git a/CODEmp/cgame/cg_weaponinit.c b/CODE-mp/cgame/cg_weaponinit.c similarity index 97% rename from CODEmp/cgame/cg_weaponinit.c rename to CODE-mp/cgame/cg_weaponinit.c index 3310b70..5dc4ce2 100644 --- a/CODEmp/cgame/cg_weaponinit.c +++ b/CODE-mp/cgame/cg_weaponinit.c @@ -465,8 +465,9 @@ void CG_RegisterWeapon( int weaponNum) { weaponInfo->altMissileHitSound = NULL_SOUND; weaponInfo->altMissileTrailFunc = 0; + cgs.effects.tripmineLaserFX = trap_FX_RegisterEffect("tripMine/laserMP.efx"); + trap_FX_RegisterEffect( "tripMine/explosion" ); - trap_FX_RegisterEffect( "tripMine/laser" ); // NOTENOTE temp stuff trap_S_RegisterSound( "sound/weapons/laser_trap/stick.wav" ); trap_S_RegisterSound( "sound/weapons/laser_trap/warning.wav" ); diff --git a/CODEmp/cgame/cg_weapons.c b/CODE-mp/cgame/cg_weapons.c similarity index 94% rename from CODEmp/cgame/cg_weapons.c rename to CODE-mp/cgame/cg_weapons.c index 858742b..bd943da 100644 --- a/CODEmp/cgame/cg_weapons.c +++ b/CODE-mp/cgame/cg_weapons.c @@ -155,7 +155,7 @@ static int CG_MapTorsoToWeaponFrame( clientInfo_t *ci, int frame, int animNum ) break; } - return 0; + return -1; } @@ -746,6 +746,19 @@ void CG_AddViewWeapon( playerState_t *ps ) { hand.frame = CG_MapTorsoToWeaponFrame( ci, cent->pe.torso.frame, cent->currentState.torsoAnim & ~ANIM_TOGGLEBIT ); hand.oldframe = CG_MapTorsoToWeaponFrame( ci, cent->pe.torso.oldFrame, cent->currentState.torsoAnim & ~ANIM_TOGGLEBIT ); hand.backlerp = cent->pe.torso.backlerp; + + // Handle the fringe situation where oldframe is invalid + if ( hand.frame == -1 ) + { + hand.frame = 0; + hand.oldframe = 0; + hand.backlerp = 0; + } + else if ( hand.oldframe == -1 ) + { + hand.oldframe = hand.frame; + hand.backlerp = 0; + } } hand.hModel = weapon->handsModel; @@ -927,6 +940,12 @@ static qboolean CG_WeaponSelectable( int i ) { return qfalse; } + if (i == WP_DET_PACK && cg.predictedPlayerState.ammo[weaponData[i].ammoIndex] < 1 && + !cg.predictedPlayerState.hasDetPackPlanted) + { + return qfalse; + } + if ( ! (cg.predictedPlayerState.stats[ STAT_WEAPONS ] & ( 1 << i ) ) ) { return qfalse; } @@ -1158,10 +1177,11 @@ void CG_DrawWeaponSelect( void ) { name = cg_weapons[ cg.weaponSelect ].item->pickup_name; if ( name ) { + vec4_t textColor = { .875f, .718f, .121f, 1.0f }; // Just doing this for now...... //#ifdef _DEBUG //CG_DrawProportionalString(320, y + 48, name, CG_CENTER | CG_SMALLFONT, colorTable[CT_ICON_BLUE]); - UI_DrawProportionalString(320, y+48, name, UI_CENTER|UI_SMALLFONT, colorTable[CT_ICON_BLUE]); + UI_DrawProportionalString(320, y+48, name, UI_CENTER|UI_SMALLFONT, textColor); //#endif } } diff --git a/CODE-mp/cgame/cgame.bat b/CODE-mp/cgame/cgame.bat new file mode 100644 index 0000000..7fda2fd --- /dev/null +++ b/CODE-mp/cgame/cgame.bat @@ -0,0 +1,102 @@ +del /q vm +mkdir vm +cd vm +set cc=lcc -DQ3_VM -DMISSIONPACK -DCGAME -S -Wf-target=bytecode -Wf-g -I..\..\cgame -I..\..\game -I..\..\ui %1 + +%cc% ../../game/bg_misc.c +@if errorlevel 1 goto quit +%cc% ../../game/bg_weapons.c +@if errorlevel 1 goto quit +%cc% ../../game/bg_panimate.c +@if errorlevel 1 goto quit +%cc% ../../game/bg_pmove.c +@if errorlevel 1 goto quit +%cc% ../../game/bg_slidemove.c +@if errorlevel 1 goto quit +%cc% ../../game/bg_lib.c +@if errorlevel 1 goto quit +%cc% ../../game/bg_saber.c +@if errorlevel 1 goto quit +%cc% ../../game/q_math.c +@if errorlevel 1 goto quit +%cc% ../../game/q_shared.c +@if errorlevel 1 goto quit +%cc% ../cg_consolecmds.c +@if errorlevel 1 goto quit +%cc% ../cg_draw.c +@if errorlevel 1 goto quit +%cc% ../cg_drawtools.c +@if errorlevel 1 goto quit +%cc% ../cg_effects.c +@if errorlevel 1 goto quit +%cc% ../cg_ents.c +@if errorlevel 1 goto quit +%cc% ../cg_event.c +@if errorlevel 1 goto quit +%cc% ../cg_info.c +@if errorlevel 1 goto quit +%cc% ../cg_light.c +@if errorlevel 1 goto quit +%cc% ../cg_localents.c +@if errorlevel 1 goto quit +%cc% ../cg_main.c +@if errorlevel 1 goto quit +%cc% ../cg_marks.c +@if errorlevel 1 goto quit +%cc% ../cg_players.c +@if errorlevel 1 goto quit +%cc% ../cg_playerstate.c +@if errorlevel 1 goto quit +%cc% ../cg_predict.c +@if errorlevel 1 goto quit +%cc% ../cg_saga.c +@if errorlevel 1 goto quit +%cc% ../cg_scoreboard.c +@if errorlevel 1 goto quit +%cc% ../cg_servercmds.c +@if errorlevel 1 goto quit +%cc% ../cg_snapshot.c +@if errorlevel 1 goto quit +%cc% ../cg_turret.c +@if errorlevel 1 goto quit +%cc% ../cg_view.c +@if errorlevel 1 goto quit +%cc% ../cg_weaponinit.c +@if errorlevel 1 goto quit +%cc% ../cg_weapons.c +@if errorlevel 1 goto quit +%cc% ../fx_blaster.c +@if errorlevel 1 goto quit +%cc% ../fx_bowcaster.c +@if errorlevel 1 goto quit +%cc% ../fx_bryarpistol.c +@if errorlevel 1 goto quit +%cc% ../fx_demp2.c +@if errorlevel 1 goto quit +%cc% ../fx_disruptor.c +@if errorlevel 1 goto quit +%cc% ../fx_flechette.c +@if errorlevel 1 goto quit +%cc% ../fx_heavyrepeater.c +@if errorlevel 1 goto quit +%cc% ../fx_rocketlauncher.c +@if errorlevel 1 goto quit +%cc% ../fx_force.c +@if errorlevel 1 goto quit +%cc% ../../ui/ui_shared.c +@if errorlevel 1 goto quit +%cc% ../cg_newDraw.c +@if errorlevel 1 goto quit + +sysmaker ../cg_public.h ../cg_syscalls.c ../cg_syscalls.asm +@if errorlevel 1 goto quit + +q3asm -f ../cgame +@if errorlevel 1 goto quit + +mkdir "..\..\base\vm" +copy *.map "..\..\base\vm" +copy *.qvm "..\..\base\vm" + +:quit +cd .. diff --git a/CODE-mp/cgame/cgame.q3asm b/CODE-mp/cgame/cgame.q3asm new file mode 100644 index 0000000..a88d978 --- /dev/null +++ b/CODE-mp/cgame/cgame.q3asm @@ -0,0 +1,44 @@ +-o "cgame" +cg_main +..\cg_syscalls +cg_consolecmds +cg_draw +cg_drawtools +cg_effects +cg_ents +cg_event +cg_info +cg_light +cg_localents +cg_marks +cg_players +cg_playerstate +cg_predict +cg_saga +cg_scoreboard +cg_servercmds +cg_snapshot +cg_turret +cg_view +cg_weaponinit +cg_weapons +fx_blaster +fx_bowcaster +fx_bryarpistol +fx_demp2 +fx_disruptor +fx_flechette +fx_heavyrepeater +fx_rocketlauncher +fx_force +bg_slidemove +bg_weapons +bg_panimate +bg_pmove +bg_lib +bg_misc +bg_saber +q_math +q_shared +ui_shared +cg_newDraw diff --git a/CODEmp/cgame/fx_blaster.c b/CODE-mp/cgame/fx_blaster.c similarity index 100% rename from CODEmp/cgame/fx_blaster.c rename to CODE-mp/cgame/fx_blaster.c diff --git a/CODEmp/cgame/fx_bowcaster.c b/CODE-mp/cgame/fx_bowcaster.c similarity index 100% rename from CODEmp/cgame/fx_bowcaster.c rename to CODE-mp/cgame/fx_bowcaster.c diff --git a/CODEmp/cgame/fx_bryarpistol.c b/CODE-mp/cgame/fx_bryarpistol.c similarity index 100% rename from CODEmp/cgame/fx_bryarpistol.c rename to CODE-mp/cgame/fx_bryarpistol.c diff --git a/CODEmp/cgame/fx_demp2.c b/CODE-mp/cgame/fx_demp2.c similarity index 100% rename from CODEmp/cgame/fx_demp2.c rename to CODE-mp/cgame/fx_demp2.c diff --git a/CODEmp/cgame/fx_disruptor.c b/CODE-mp/cgame/fx_disruptor.c similarity index 100% rename from CODEmp/cgame/fx_disruptor.c rename to CODE-mp/cgame/fx_disruptor.c diff --git a/CODEmp/cgame/fx_flechette.c b/CODE-mp/cgame/fx_flechette.c similarity index 100% rename from CODEmp/cgame/fx_flechette.c rename to CODE-mp/cgame/fx_flechette.c diff --git a/CODEmp/cgame/fx_force.c b/CODE-mp/cgame/fx_force.c similarity index 100% rename from CODEmp/cgame/fx_force.c rename to CODE-mp/cgame/fx_force.c diff --git a/CODEmp/cgame/fx_heavyrepeater.c b/CODE-mp/cgame/fx_heavyrepeater.c similarity index 100% rename from CODEmp/cgame/fx_heavyrepeater.c rename to CODE-mp/cgame/fx_heavyrepeater.c diff --git a/CODEmp/cgame/fx_local.h b/CODE-mp/cgame/fx_local.h similarity index 100% rename from CODEmp/cgame/fx_local.h rename to CODE-mp/cgame/fx_local.h diff --git a/CODEmp/cgame/fx_rocketlauncher.c b/CODE-mp/cgame/fx_rocketlauncher.c similarity index 100% rename from CODEmp/cgame/fx_rocketlauncher.c rename to CODE-mp/cgame/fx_rocketlauncher.c diff --git a/CODE-mp/cgame/mssccprj.scc b/CODE-mp/cgame/mssccprj.scc new file mode 100644 index 0000000..eede0df --- /dev/null +++ b/CODE-mp/cgame/mssccprj.scc @@ -0,0 +1,5 @@ +SCC = This is a Source Code Control file + +[JK2_cgame.dsp] +SCC_Aux_Path = "\\ravend\vss_projects\jk2sof2MP" +SCC_Project_Name = "$/General/code/cgame", UPCAAAAA diff --git a/CODEmp/cgame/tr_types.h b/CODE-mp/cgame/tr_types.h similarity index 88% rename from CODEmp/cgame/tr_types.h rename to CODE-mp/cgame/tr_types.h index 0c1436e..67283eb 100644 --- a/CODEmp/cgame/tr_types.h +++ b/CODE-mp/cgame/tr_types.h @@ -13,6 +13,7 @@ #define RF_THIRD_PERSON 0x00002 // don't draw through eyes, only mirrors (player bodies, chat sprites) #define RF_FIRST_PERSON 0x00004 // only draw through eyes (view weapon, damage blood blob) #define RF_DEPTHHACK 0x00008 // for view weapon Z crunching +#define RF_NODEPTH 0x00010 // No depth at all (seeing through walls) #define RF_VOLUMETRIC 0x00020 // fake volumetric shading @@ -37,6 +38,7 @@ #define RF_DISINTEGRATE2 0x40000 // does a procedural hole-ripping thing with scaling at the ripping point + // refdef flags #define RDF_NOWORLDMODEL 1 // used for player configuration screen #define RDF_HYPERSPACE 4 // teleportation effect @@ -262,25 +264,31 @@ typedef enum { ** being run right now. These are constant once the OpenGL ** subsystem is initialized. */ -typedef enum { - TC_NONE, - TC_S3TC, - TC_S3TC_DXT -} textureCompression_t; - typedef struct { - const char *renderer_string; - const char *vendor_string; - const char *version_string; - const char *extensions_string; + char renderer_string[MAX_STRING_CHARS]; + char vendor_string[MAX_STRING_CHARS]; + char version_string[MAX_STRING_CHARS]; + char extensions_string[BIG_INFO_STRING]; int maxTextureSize; // queried from GL int maxActiveTextures; // multitexture ability + int tfSolidCompressed; + float tfSolidCompressedBPT; + int tfAlphaCompressed; + float tfAlphaCompressedBPT; + int tfSolidUncompressed; + float tfSolidUncompressedBPT; + int tfAlphaUncompressed; + float tfAlphaUncompressedBPT; + int tfLightmap; + float tfLightmapBPT; + int tfCinematic; // Specially for the Voodoo4 - glTexImage2D can only handle 16 bit + float tfCinematicBPT; + int colorBits, depthBits, stencilBits; qboolean deviceSupportsGamma; - textureCompression_t textureCompression; qboolean textureEnvAddAvailable; qboolean textureFilterAnisotropicAvailable; qboolean clampToEdgeAvailable; diff --git a/CODE-mp/cgame/vssver.scc b/CODE-mp/cgame/vssver.scc new file mode 100644 index 0000000..38a1a6f Binary files /dev/null and b/CODE-mp/cgame/vssver.scc differ diff --git a/CODEmp/client/fxexport.cpp b/CODE-mp/client/FXExport.cpp similarity index 100% rename from CODEmp/client/fxexport.cpp rename to CODE-mp/client/FXExport.cpp diff --git a/CODEmp/client/fxexport.h b/CODE-mp/client/FXExport.h similarity index 100% rename from CODEmp/client/fxexport.h rename to CODE-mp/client/FXExport.h diff --git a/CODEmp/client/fxprimitives.cpp b/CODE-mp/client/FxPrimitives.cpp similarity index 100% rename from CODEmp/client/fxprimitives.cpp rename to CODE-mp/client/FxPrimitives.cpp diff --git a/CODEmp/client/fxprimitives.h b/CODE-mp/client/FxPrimitives.h similarity index 100% rename from CODEmp/client/fxprimitives.h rename to CODE-mp/client/FxPrimitives.h diff --git a/CODEmp/client/fxscheduler.cpp b/CODE-mp/client/FxScheduler.cpp similarity index 96% rename from CODEmp/client/fxscheduler.cpp rename to CODE-mp/client/FxScheduler.cpp index e8aba32..1577e4b 100644 --- a/CODEmp/client/fxscheduler.cpp +++ b/CODE-mp/client/FxScheduler.cpp @@ -966,6 +966,13 @@ void CFxScheduler::PlayEffect( int id, vec3_t origin, vec3_t forward ) { vec3_t axis[3]; + // Cannot have a empty forward vector + if ( !forward[0] && !forward[1] && !forward[2] ) + { + assert ( qfalse ); + return; + } + // Take the forward vector and create two arbitrary but perpendicular vectors VectorCopy( forward, axis[0] ); MakeNormalVectors( forward, axis[1], axis[2] ); diff --git a/CODEmp/client/fxscheduler.h b/CODE-mp/client/FxScheduler.h similarity index 100% rename from CODEmp/client/fxscheduler.h rename to CODE-mp/client/FxScheduler.h diff --git a/CODEmp/client/fxsystem.cpp b/CODE-mp/client/FxSystem.cpp similarity index 100% rename from CODEmp/client/fxsystem.cpp rename to CODE-mp/client/FxSystem.cpp diff --git a/CODEmp/client/fxsystem.h b/CODE-mp/client/FxSystem.h similarity index 100% rename from CODEmp/client/fxsystem.h rename to CODE-mp/client/FxSystem.h diff --git a/CODEmp/client/fxtemplate.cpp b/CODE-mp/client/FxTemplate.cpp similarity index 100% rename from CODEmp/client/fxtemplate.cpp rename to CODE-mp/client/FxTemplate.cpp diff --git a/CODEmp/client/fxutil.cpp b/CODE-mp/client/FxUtil.cpp similarity index 100% rename from CODEmp/client/fxutil.cpp rename to CODE-mp/client/FxUtil.cpp diff --git a/CODEmp/client/fxutil.h b/CODE-mp/client/FxUtil.h similarity index 100% rename from CODEmp/client/fxutil.h rename to CODE-mp/client/FxUtil.h diff --git a/CODEmp/client/cl_cgame.cpp b/CODE-mp/client/cl_cgame.cpp similarity index 96% rename from CODEmp/client/cl_cgame.cpp rename to CODE-mp/client/cl_cgame.cpp index 555f3ab..c01446c 100644 --- a/CODEmp/client/cl_cgame.cpp +++ b/CODE-mp/client/cl_cgame.cpp @@ -699,6 +699,11 @@ int CL_CgameSystemCalls( int *args ) { return botlib_export->PC_ReadTokenHandle( args[1], (struct pc_token_s *)VMA(2) ); case CG_PC_SOURCE_FILE_AND_LINE: return botlib_export->PC_SourceFileAndLine( args[1], (char *)VMA(2), (int *)VMA(3) ); + case CG_PC_LOAD_GLOBAL_DEFINES: + return botlib_export->PC_LoadGlobalDefines ( (char *)VMA(1) ); + case CG_PC_REMOVE_ALL_GLOBAL_DEFINES: + botlib_export->PC_RemoveAllGlobalDefines ( ); + return 0; case CG_S_STOPBACKGROUNDTRACK: S_StopBackgroundTrack(); diff --git a/CODEmp/client/cl_cin.cpp b/CODE-mp/client/cl_cin.cpp similarity index 100% rename from CODEmp/client/cl_cin.cpp rename to CODE-mp/client/cl_cin.cpp diff --git a/CODEmp/client/cl_console.cpp b/CODE-mp/client/cl_console.cpp similarity index 100% rename from CODEmp/client/cl_console.cpp rename to CODE-mp/client/cl_console.cpp diff --git a/CODEmp/client/cl_input.cpp b/CODE-mp/client/cl_input.cpp similarity index 95% rename from CODEmp/client/cl_input.cpp rename to CODE-mp/client/cl_input.cpp index 41603d3..1ef68a3 100644 --- a/CODEmp/client/cl_input.cpp +++ b/CODE-mp/client/cl_input.cpp @@ -914,8 +914,8 @@ void CL_InitInput( void ) { Cmd_AddCommand ("-speed", IN_SpeedUp); Cmd_AddCommand ("+attack", IN_Button0Down); Cmd_AddCommand ("-attack", IN_Button0Up); - Cmd_AddCommand ("+force_jump", IN_Button1Down);//force jump - Cmd_AddCommand ("-force_jump", IN_Button1Up); + //Cmd_AddCommand ("+force_jump", IN_Button1Down);//force jump + //Cmd_AddCommand ("-force_jump", IN_Button1Up); Cmd_AddCommand ("+use", IN_Button5Down); Cmd_AddCommand ("-use", IN_Button5Up); Cmd_AddCommand ("+force_grip", IN_Button6Down);//force grip diff --git a/CODEmp/client/cl_keys.cpp b/CODE-mp/client/cl_keys.cpp similarity index 95% rename from CODEmp/client/cl_keys.cpp rename to CODE-mp/client/cl_keys.cpp index d2acf05..5d72486 100644 --- a/CODEmp/client/cl_keys.cpp +++ b/CODE-mp/client/cl_keys.cpp @@ -546,7 +546,8 @@ CompleteCommand Tab expansion =============== */ -static void CompleteCommand( void ) { +void CompleteCommand( void ) +{ field_t *edit; field_t temp; diff --git a/CODEmp/client/cl_main.cpp b/CODE-mp/client/cl_main.cpp similarity index 95% rename from CODEmp/client/cl_main.cpp rename to CODE-mp/client/cl_main.cpp index e989c01..1363c41 100644 --- a/CODEmp/client/cl_main.cpp +++ b/CODE-mp/client/cl_main.cpp @@ -53,6 +53,7 @@ cvar_t *cl_inGameVideo; cvar_t *cl_serverStatusResendTime; cvar_t *cl_trn; +cvar_t *cl_framerate; vec3_t cl_windVec; @@ -1957,6 +1958,8 @@ CL_Frame ================== */ +static unsigned int frameCount; +static float avgFrametime=0.0; void CL_Frame ( int msec ) { if ( !com_cl_running->integer ) { @@ -1990,6 +1993,19 @@ void CL_Frame ( int msec ) { // decide the simulation time cls.frametime = msec; + if(cl_framerate->integer) + { + avgFrametime+=msec; + char mess[256]; + if(!(frameCount&0x1f)) + { + sprintf(mess,"Frame rate=%f\n\n",1000.0f*(1.0/(avgFrametime/32.0f))); + // OutputDebugString(mess); + Com_Printf(mess); + avgFrametime=0.0f; + } + frameCount++; + } cls.realtime += cls.frametime; @@ -2298,7 +2314,7 @@ void CL_Init( void ) { cl_freelook = Cvar_Get( "cl_freelook", "1", CVAR_ARCHIVE ); cl_showMouseRate = Cvar_Get ("cl_showmouserate", "0", 0); - + cl_framerate = Cvar_Get ("cl_framerate", "0", CVAR_TEMP); cl_allowDownload = Cvar_Get ("cl_allowDownload", "0", CVAR_ARCHIVE); cl_conXOffset = Cvar_Get ("cl_conXOffset", "0", 0); diff --git a/CODEmp/client/cl_net_chan.cpp b/CODE-mp/client/cl_net_chan.cpp similarity index 100% rename from CODEmp/client/cl_net_chan.cpp rename to CODE-mp/client/cl_net_chan.cpp diff --git a/CODEmp/client/cl_parse.cpp b/CODE-mp/client/cl_parse.cpp similarity index 100% rename from CODEmp/client/cl_parse.cpp rename to CODE-mp/client/cl_parse.cpp diff --git a/CODEmp/client/cl_scrn.cpp b/CODE-mp/client/cl_scrn.cpp similarity index 100% rename from CODEmp/client/cl_scrn.cpp rename to CODE-mp/client/cl_scrn.cpp diff --git a/CODEmp/client/cl_ui.cpp b/CODE-mp/client/cl_ui.cpp similarity index 95% rename from CODEmp/client/cl_ui.cpp rename to CODE-mp/client/cl_ui.cpp index 901d9f6..3f7578f 100644 --- a/CODEmp/client/cl_ui.cpp +++ b/CODE-mp/client/cl_ui.cpp @@ -1087,6 +1087,11 @@ int CL_UISystemCalls( int *args ) { return botlib_export->PC_ReadTokenHandle( args[1], (struct pc_token_s *)VMA(2) ); case UI_PC_SOURCE_FILE_AND_LINE: return botlib_export->PC_SourceFileAndLine( args[1], (char *)VMA(2), (int *)VMA(3) ); + case UI_PC_LOAD_GLOBAL_DEFINES: + return botlib_export->PC_LoadGlobalDefines ( (char *)VMA(1) ); + case UI_PC_REMOVE_ALL_GLOBAL_DEFINES: + botlib_export->PC_RemoveAllGlobalDefines ( ); + return 0; case UI_S_STOPBACKGROUNDTRACK: S_StopBackgroundTrack(); diff --git a/CODEmp/client/client.h b/CODE-mp/client/client.h similarity index 100% rename from CODEmp/client/client.h rename to CODE-mp/client/client.h diff --git a/CODEmp/client/keys.h b/CODE-mp/client/keys.h similarity index 100% rename from CODEmp/client/keys.h rename to CODE-mp/client/keys.h diff --git a/CODEmp/client/snd_dma.cpp b/CODE-mp/client/snd_dma.cpp similarity index 95% rename from CODEmp/client/snd_dma.cpp rename to CODE-mp/client/snd_dma.cpp index 329a364..2938f69 100644 --- a/CODEmp/client/snd_dma.cpp +++ b/CODE-mp/client/snd_dma.cpp @@ -146,6 +146,25 @@ int s_rawend; portable_samplepair_t s_rawsamples[MAX_RAW_SAMPLES]; + +// instead of clearing a whole channel_t struct, we're going to skip the MP3SlidingDecodeBuffer[] buffer in the middle... +// +#ifndef offsetof +#include +#endif +static inline void Channel_Clear(channel_t *ch) +{ + // memset (ch, 0, sizeof(*ch)); + + memset(ch,0,offsetof(channel_t,MP3SlidingDecodeBuffer)); + + byte *const p = (byte *)ch + offsetof(channel_t,MP3SlidingDecodeBuffer) + sizeof(ch->MP3SlidingDecodeBuffer); + + memset(p,0,(sizeof(*ch) - offsetof(channel_t,MP3SlidingDecodeBuffer)) - sizeof(ch->MP3SlidingDecodeBuffer)); +} + + + // ==================================================================== // User-setable variables // ==================================================================== @@ -520,7 +539,9 @@ sfxHandle_t S_RegisterSound( const char *name) if ( sfx->bDefaultSound ) { // Suppress error for inline sounds if(Q_stricmp(sfx->sSoundName, DEFAULT_SOUND_NAME)){ +#ifdef _DEBUG Com_Printf( S_COLOR_YELLOW "WARNING: could not find %s - using default\n", sfx->sSoundName ); +#endif } return 0; } @@ -688,7 +709,7 @@ channel_t *S_PickChannel(int entnum, int entchannel) Com_Printf( S_COLOR_RED"***kicking %s\n", ch_firstToDie->thesfx->sSoundName ); } - memset (ch_firstToDie, 0, sizeof(*ch_firstToDie)); + Channel_Clear(ch_firstToDie); // memset (ch_firstToDie, 0, sizeof(*ch_firstToDie)); return ch_firstToDie; } @@ -2301,7 +2322,7 @@ int SND_FreeOldestSound() { sfx = &s_knownSfx[i]; - if (sfx->bInMemory && sfx->iLastTimeUsed < iOldest) + if (!sfx->bDefaultSound && sfx->bInMemory && sfx->iLastTimeUsed < iOldest) { if (sfx->pSoundData) { diff --git a/CODEmp/client/snd_local.h b/CODE-mp/client/snd_local.h similarity index 100% rename from CODEmp/client/snd_local.h rename to CODE-mp/client/snd_local.h diff --git a/CODEmp/client/snd_mem.cpp b/CODE-mp/client/snd_mem.cpp similarity index 95% rename from CODEmp/client/snd_mem.cpp rename to CODE-mp/client/snd_mem.cpp index b14d858..03dd2ca 100644 --- a/CODEmp/client/snd_mem.cpp +++ b/CODE-mp/client/snd_mem.cpp @@ -333,7 +333,7 @@ static qboolean S_LoadSound_Actual( sfx_t *sfx ) FS_FreeFile (data); return qfalse; } - +#ifdef _DEBUG if ( info.width == 1 ) { Com_Printf(S_COLOR_YELLOW "WARNING: %s is an 8 bit wav file\n", sfx->sSoundName); } @@ -341,6 +341,7 @@ static qboolean S_LoadSound_Actual( sfx_t *sfx ) if ( info.rate != 22050 ) { Com_Printf(S_COLOR_YELLOW "WARNING: %s is not a 22kHz wav file\n", sfx->sSoundName); } +#endif samples = (short *)Z_Malloc(info.samples * sizeof(short) * 2, TAG_TEMP_WORKSPACE); diff --git a/CODEmp/client/snd_mix.cpp b/CODE-mp/client/snd_mix.cpp similarity index 100% rename from CODEmp/client/snd_mix.cpp rename to CODE-mp/client/snd_mix.cpp diff --git a/CODEmp/client/snd_mp3.cpp b/CODE-mp/client/snd_mp3.cpp similarity index 100% rename from CODEmp/client/snd_mp3.cpp rename to CODE-mp/client/snd_mp3.cpp diff --git a/CODEmp/client/snd_mp3.h b/CODE-mp/client/snd_mp3.h similarity index 100% rename from CODEmp/client/snd_mp3.h rename to CODE-mp/client/snd_mp3.h diff --git a/CODEmp/client/snd_public.h b/CODE-mp/client/snd_public.h similarity index 100% rename from CODEmp/client/snd_public.h rename to CODE-mp/client/snd_public.h diff --git a/CODE-mp/client/vssver.scc b/CODE-mp/client/vssver.scc new file mode 100644 index 0000000..fa80f3b Binary files /dev/null and b/CODE-mp/client/vssver.scc differ diff --git a/CODEmp/encryption/buffer.cpp b/CODE-mp/encryption/buffer.cpp similarity index 100% rename from CODEmp/encryption/buffer.cpp rename to CODE-mp/encryption/buffer.cpp diff --git a/CODEmp/encryption/buffer.h b/CODE-mp/encryption/buffer.h similarity index 100% rename from CODEmp/encryption/buffer.h rename to CODE-mp/encryption/buffer.h diff --git a/CODEmp/encryption/cpp_interface.cpp b/CODE-mp/encryption/cpp_interface.cpp similarity index 100% rename from CODEmp/encryption/cpp_interface.cpp rename to CODE-mp/encryption/cpp_interface.cpp diff --git a/CODEmp/encryption/cpp_interface.h b/CODE-mp/encryption/cpp_interface.h similarity index 100% rename from CODEmp/encryption/cpp_interface.h rename to CODE-mp/encryption/cpp_interface.h diff --git a/CODEmp/encryption/encryption.h b/CODE-mp/encryption/encryption.h similarity index 100% rename from CODEmp/encryption/encryption.h rename to CODE-mp/encryption/encryption.h diff --git a/CODEmp/encryption/sockets.cpp b/CODE-mp/encryption/sockets.cpp similarity index 100% rename from CODEmp/encryption/sockets.cpp rename to CODE-mp/encryption/sockets.cpp diff --git a/CODEmp/encryption/sockets.h b/CODE-mp/encryption/sockets.h similarity index 100% rename from CODEmp/encryption/sockets.h rename to CODE-mp/encryption/sockets.h diff --git a/CODE-mp/encryption/vssver.scc b/CODE-mp/encryption/vssver.scc new file mode 100644 index 0000000..362953c Binary files /dev/null and b/CODE-mp/encryption/vssver.scc differ diff --git a/CODEmp/game/JK2_game.def b/CODE-mp/game/JK2_game.def similarity index 100% rename from CODEmp/game/JK2_game.def rename to CODE-mp/game/JK2_game.def diff --git a/CODEmp/game/JK2_game.dsp b/CODE-mp/game/JK2_game.dsp similarity index 94% rename from CODEmp/game/JK2_game.dsp rename to CODE-mp/game/JK2_game.dsp index 0e89786..99bea4e 100644 --- a/CODEmp/game/JK2_game.dsp +++ b/CODE-mp/game/JK2_game.dsp @@ -389,6 +389,26 @@ SOURCE=.\inv.h # End Source File # Begin Source File +SOURCE=.\JK2_game.def + +!IF "$(CFG)" == "JK2game - Win32 Release JK2" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "JK2game - Win32 Debug JK2" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "JK2game - Win32 Final JK2" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + SOURCE=.\match.h # End Source File # Begin Source File @@ -422,28 +442,13 @@ SOURCE=.\w_saber.h # End Group # Begin Source File -SOURCE=.\g_syscalls.asm +SOURCE=.\game.bat # PROP Exclude_From_Build 1 # End Source File # Begin Source File -SOURCE=.\JK2_game.def - -!IF "$(CFG)" == "JK2game - Win32 Release JK2" - +SOURCE=.\game.q3asm # PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "JK2game - Win32 Debug JK2" - -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "JK2game - Win32 Final JK2" - -# PROP BASE Exclude_From_Build 1 -# PROP Exclude_From_Build 1 - -!ENDIF - # End Source File # End Target # End Project diff --git a/CODEmp/game/ai_main.c b/CODE-mp/game/ai_main.c similarity index 94% rename from CODEmp/game/ai_main.c rename to CODE-mp/game/ai_main.c index b39a73e..41fce2c 100644 --- a/CODEmp/game/ai_main.c +++ b/CODE-mp/game/ai_main.c @@ -1659,6 +1659,12 @@ int PassStandardEnemyChecks(bot_state_t *bs, gentity_t *en) return 0; } + if (bs->doingFallback && + (gLevelFlags & LEVELFLAG_IGNOREINFALLBACK)) + { + return 0; + } + if (en->client) { if (en->client->ps.pm_type == PM_INTERMISSION || @@ -5505,7 +5511,7 @@ void StandardBotAI(bot_state_t *bs, float thinktime) int wp, enemy; int desiredIndex; int goalWPIndex; - int doingFallback; + int doingFallback = 0; int fjHalt; vec3_t a, ang, headlevel, eorg, noz_x, noz_y, dif, a_fo; float reaction; @@ -6185,6 +6191,15 @@ void StandardBotAI(bot_state_t *bs, float thinktime) doingFallback = BotFallbackNavigation(bs); } + if (doingFallback) + { + bs->doingFallback = qtrue; + } + else + { + bs->doingFallback = qfalse; + } + if (bs->timeToReact < level.time && bs->currentEnemy && bs->enemySeenTime > level.time + (ENEMY_FORGET_MS - (ENEMY_FORGET_MS*0.2))) { if (bs->frame_Enemy_Vis) @@ -6287,19 +6302,26 @@ void StandardBotAI(bot_state_t *bs, float thinktime) bs->saberPowerTime = level.time + Q_irand(3000, 15000); } - if (bs->currentEnemy->health > 75 && bs->cur_ps.fd.forcePowerLevel[FP_SABERATTACK] > 2 && - bs->cur_ps.fd.saberAnimLevel != FORCE_LEVEL_3 && bs->saberPower) - { //if we are up against someone with a lot of health and we have a strong attack available, then h4q them - Cmd_SaberAttackCycle_f(&g_entities[bs->client]); + if (bs->currentEnemy->health > 75 && g_entities[bs->client].client->ps.fd.forcePowerLevel[FP_SABERATTACK] > 2) + { + if (g_entities[bs->client].client->ps.fd.saberAnimLevel != FORCE_LEVEL_3 && bs->saberPower) + { //if we are up against someone with a lot of health and we have a strong attack available, then h4q them + Cmd_SaberAttackCycle_f(&g_entities[bs->client]); + } } - else if (bs->currentEnemy->health > 40 && bs->cur_ps.fd.forcePowerLevel[FP_SABERATTACK] > 1 && - bs->cur_ps.fd.saberAnimLevel != FORCE_LEVEL_2) - { //they're down on health a little, use level 2 if we can - Cmd_SaberAttackCycle_f(&g_entities[bs->client]); + else if (bs->currentEnemy->health > 40 && g_entities[bs->client].client->ps.fd.forcePowerLevel[FP_SABERATTACK] > 1) + { + if (g_entities[bs->client].client->ps.fd.saberAnimLevel != FORCE_LEVEL_2) + { //they're down on health a little, use level 2 if we can + Cmd_SaberAttackCycle_f(&g_entities[bs->client]); + } } - else if (bs->cur_ps.fd.saberAnimLevel != FORCE_LEVEL_1) - { //they've gone below 40 health, go at them with quick attacks - Cmd_SaberAttackCycle_f(&g_entities[bs->client]); + else + { + if (g_entities[bs->client].client->ps.fd.saberAnimLevel != FORCE_LEVEL_1) + { //they've gone below 40 health, go at them with quick attacks + Cmd_SaberAttackCycle_f(&g_entities[bs->client]); + } } if (bs->frame_Enemy_Len <= SABER_ATTACK_RANGE) diff --git a/CODEmp/game/ai_main.h b/CODE-mp/game/ai_main.h similarity index 94% rename from CODEmp/game/ai_main.h rename to CODE-mp/game/ai_main.h index fdb0046..2804371 100644 --- a/CODEmp/game/ai_main.h +++ b/CODE-mp/game/ai_main.h @@ -4,7 +4,7 @@ //#define FORCEJUMP_INSTANTMETHOD 1 -#define MAX_CHAT_BUFFER_SIZE 65536 +#define MAX_CHAT_BUFFER_SIZE 8192 #define MAX_CHAT_LINE_SIZE 128 #define MAX_WPARRAY_SIZE 4096 @@ -37,6 +37,7 @@ #define WPFLAG_NOMOVEFUNC 0x00200000 //don't move over if a func is under #define LEVELFLAG_NOPOINTPREDICTION 1 //don't take waypoint beyond current into account when adjusting path view angles +#define LEVELFLAG_IGNOREINFALLBACK 2 //ignore enemies when in a fallback navigation routine #define WP_KEEP_FLAG_DIST 128 @@ -340,6 +341,7 @@ typedef struct bot_state_s int doForcePush; int noUseTime; + qboolean doingFallback; //end rww } bot_state_t; diff --git a/CODEmp/game/ai_util.c b/CODE-mp/game/ai_util.c similarity index 93% rename from CODEmp/game/ai_util.c rename to CODE-mp/game/ai_util.c index 81711fd..5f312c7 100644 --- a/CODEmp/game/ai_util.c +++ b/CODE-mp/game/ai_util.c @@ -10,9 +10,6 @@ void *BAllocList[MAX_BALLOC]; #endif char gBotChatBuffer[MAX_CLIENTS][MAX_CHAT_BUFFER_SIZE]; -//A total of 4194304 bytes. Not very nice at all, but we really -//want to have at least 65k for the total chat buffer just in -//case and we have no method of dynamic allocation here. void *B_TempAlloc(int size) { diff --git a/CODEmp/game/ai_wpnav.c b/CODE-mp/game/ai_wpnav.c similarity index 91% rename from CODEmp/game/ai_wpnav.c rename to CODE-mp/game/ai_wpnav.c index b5ff70f..2686ac6 100644 --- a/CODEmp/game/ai_wpnav.c +++ b/CODE-mp/game/ai_wpnav.c @@ -2179,6 +2179,82 @@ void LoadPath_ThisLevel(void) } } +gentity_t *GetClosestSpawn(gentity_t *ent) +{ + gentity_t *spawn; + gentity_t *closestSpawn = NULL; + float closestDist = -1; + int i = MAX_CLIENTS; + + spawn = NULL; + + while (i < MAX_GENTITIES) + { + spawn = &g_entities[i]; + + if (spawn && spawn->inuse && (!Q_stricmp(spawn->classname, "info_player_start") || !Q_stricmp(spawn->classname, "info_player_deathmatch")) ) + { + float checkDist; + vec3_t vSub; + + VectorSubtract(ent->client->ps.origin, spawn->r.currentOrigin, vSub); + checkDist = VectorLength(vSub); + + if (closestDist == -1 || checkDist < closestDist) + { + closestSpawn = spawn; + closestDist = checkDist; + } + } + + i++; + } + + return closestSpawn; +} + +gentity_t *GetNextSpawnInIndex(gentity_t *currentSpawn) +{ + gentity_t *spawn; + gentity_t *nextSpawn = NULL; + int i = currentSpawn->s.number+1; + + spawn = NULL; + + while (i < MAX_GENTITIES) + { + spawn = &g_entities[i]; + + if (spawn && spawn->inuse && (!Q_stricmp(spawn->classname, "info_player_start") || !Q_stricmp(spawn->classname, "info_player_deathmatch")) ) + { + nextSpawn = spawn; + break; + } + + i++; + } + + if (!nextSpawn) + { //loop back around to 0 + i = MAX_CLIENTS; + + while (i < MAX_GENTITIES) + { + spawn = &g_entities[i]; + + if (spawn && spawn->inuse && (!Q_stricmp(spawn->classname, "info_player_start") || !Q_stricmp(spawn->classname, "info_player_deathmatch")) ) + { + nextSpawn = spawn; + break; + } + + i++; + } + } + + return nextSpawn; +} + int AcceptBotCommand(char *cmd, gentity_t *pl) { int OptionalArgument, i; @@ -2284,6 +2360,24 @@ int AcceptBotCommand(char *cmd, gentity_t *pl) return 1; } + if (Q_stricmp (cmd, "bot_wp_spawntele") == 0) + { + gentity_t *closestSpawn = GetClosestSpawn(pl); + + if (!closestSpawn) + { //There should always be a spawn point.. + return 1; + } + + closestSpawn = GetNextSpawnInIndex(closestSpawn); + + if (closestSpawn) + { + VectorCopy(closestSpawn->r.currentOrigin, pl->client->ps.origin); + } + return 1; + } + if (Q_stricmp (cmd, "bot_wp_addflagged") == 0) { gDeactivated = 1; diff --git a/CODEmp/game/anims.h b/CODE-mp/game/anims.h similarity index 90% rename from CODEmp/game/anims.h rename to CODE-mp/game/anims.h index 8e8f2ca..a8b695b 100644 --- a/CODEmp/game/anims.h +++ b/CODE-mp/game/anims.h @@ -140,6 +140,8 @@ typedef enum //# animNumber_e BOTH_MELEE4, //# Fourth melee attack BOTH_MELEE5, //# Fifth melee attack BOTH_MELEE6, //# Sixth melee attack + BOTH_THERMAL_READY, //# pull back with thermal + BOTH_THERMAL_THROW, //# throw thermal //* #sep BOTH_ SABER ANIMS //Saber attack anims - power level 2 BOTH_A1_T__B_, //# Fast weak vertical attack top to bottom @@ -638,7 +640,7 @@ typedef enum //# animNumber_e BOTH_STAND1TOSTAND5, //# Transition from stand1 to stand5 BOTH_STAND5TOSTAND1, //# Transition from stand5 to stand1 BOTH_STAND5TOSTAND8, //# Transition from stand5 to stand8 - BOTH_STAND8TOSTAND5, //# Transition from stand5 to stand8 + BOTH_STAND8TOSTAND5, //# Transition from stand8 to stand5 BOTH_CONSOLE1START, //# typing at a console BOTH_CONSOLE1, //# typing at a console @@ -653,46 +655,6 @@ typedef enum //# animNumber_e BOTH_GESTURE1, //# Generic gesture, non-specific BOTH_GESTURE2, //# Generic gesture, non-specific BOTH_GESTURE3, //# Generic gesture, non-specific - BOTH_TALK1, //# Generic talk anim - BOTH_TALKCOMM1START, //# Start talking into a comm link - BOTH_TALKCOMM1, //# Talking into a comm link - BOTH_TALKCOMM1STOP, //# Stop talking into a comm link - BOTH_TALKGESTURE1, //# Generic talk anim - BOTH_TALKGESTURE2, //# Generic talk anim - BOTH_TALKGESTURE3, //# Generic talk anim - BOTH_TALKGESTURE4START, //# Beginning talk anim 4 - BOTH_TALKGESTURE4, //# Talk gesture 4 - BOTH_TALKGESTURE4STOP, //# Ending talk anim 4 - BOTH_TALKGESTURE5START, //# Start hand on chin - BOTH_TALKGESTURE5, //# Hand on chin - BOTH_TALKGESTURE5STOP, //# Stop hand on chin - BOTH_TALKGESTURE6START, //# Starting Motions to self - BOTH_TALKGESTURE6, //# Pointing at self - BOTH_TALKGESTURE6STOP, //# Ending Motions to self - BOTH_TALKGESTURE7START, //# Start touches Kyle on shoulder - BOTH_TALKGESTURE7, //# Hold touches Kyle on shoulder - BOTH_TALKGESTURE7STOP, //# Ending touches Kyle on shoulder - BOTH_TALKGESTURE8START, //# Lando's chin hold - BOTH_TALKGESTURE8, //# Lando's chin hold - BOTH_TALKGESTURE8STOP, //# Lando's chin hold - BOTH_TALKGESTURE9, //# Same as gesture 2 but with the right hand - BOTH_TALKGESTURE10, //# Shoulder shrug - BOTH_TALKGESTURE11START, //# Arms folded across chest - BOTH_TALKGESTURE11STOP, //# Arms folded across chest - BOTH_TALKGESTURE12, //# Tavion taunting Kyle - BOTH_TALKGESTURE13START, //# Luke warning Kyle - BOTH_TALKGESTURE13, //# Luke warning Kyle - BOTH_TALKGESTURE13STOP, //# Luke warning Kyle - BOTH_TALKGESTURE14, //# Luke gesturing to Kyle - BOTH_TALKGESTURE15START, //# Desann taunting Kyle - BOTH_TALKGESTURE15, //# Desann taunting Kyle - BOTH_TALKGESTURE15STOP, //# Desann taunting Kyle - BOTH_TALKGESTURE16, //# Bartender gesture cin #15 - BOTH_TALKGESTURE17, //# Bartender gesture cin #15 - BOTH_TALKGESTURE18, //# Bartender gesture cin #15 - BOTH_TALKGESTURE19START, //# Desann lifting his arm "Join me" (cin #34) - BOTH_TALKGESTURE19STOP, //# Desann lifting his arm "Join me" (cin #34) - BOTH_TALKGESTURE20START, //# Kyle lifting his arm "Join us" (cin #34) BOTH_PAUSE1START, //# Luke pauses to warn Kyle (cin #24) start BOTH_PAUSE1STOP, //# Luke pauses to warn Kyle (cin #24) stop @@ -747,10 +709,14 @@ typedef enum //# animNumber_e BOTH_SILENCEGESTURE1, //# Luke silencing Kyle with a raised hand (cin #37) BOTH_REACHFORSABER1, //# Luke holding hand out for Kyle's saber (cin #37) BOTH_PUNCHER1, //# Jan punching Kyle in the shoulder (cin #37) - BOTH_CONSTRAINER1STAND, //# Tavion constraining Jan in a stand pose (cin #9) - BOTH_CONSTRAINEE1STAND, //# Jan being constrained in a stand pose (cin #9) - BOTH_CONSTRAINER1WALK, //# Tavion constraining Jan in a walking loop (cin #9) - BOTH_CONSTRAINEE1WALK, //# Jan being constrained in a walking loop (cin #9) + BOTH_CONSTRAINER1HOLD, //# Static pose of starting Tavion constraining Jan (cin #9) + BOTH_CONSTRAINEE1HOLD, //# Static pose of starting Jan being constrained by Tavion (cin #9) + BOTH_CONSTRAINER1STAND, //# Tavion constraining Jan in a stand pose (cin #9) + BOTH_CONSTRAINEE1STAND, //# Jan being constrained in a stand pose (cin #9) + BOTH_CONSTRAINER1WALK, //# Tavion shoving jan forward (cin #9) + BOTH_CONSTRAINEE1WALK, //# Jan being shoved forward by Tavion (cin #9) + BOTH_CONSTRAINER1LOOP, //# Tavion walking with Jan in a loop (cin #9) + BOTH_CONSTRAINEE1LOOP, //# Jan walking with Tavion in a loop (cin #9) BOTH_SABERKILLER1, //# Tavion about to strike Jan with saber (cin #9) BOTH_SABERKILLEE1, //# Jan about to be struck by Tavion with saber (cin #9) BOTH_HANDSHAKER1START, //# Luke shaking Kyle's hand (cin #37) @@ -761,26 +727,6 @@ typedef enum //# animNumber_e BOTH_LAUGH1STOP, //# Reelo laughing (cin #18) BOTH_ESCAPEPOD_LEAVE1, //# Kyle leaving escape pod (cin #33) BOTH_ESCAPEPOD_LEAVE2, //# Jan leaving escape pod (cin #33) - BOTH_HUGGER1, //# Kyle hugging Jan (cin #29) - BOTH_HUGGERSTOP1, //# Kyle stop hugging Jan but don't let her go (cin #29) - BOTH_HUGGERSTOP2, //# Kyle let go of Jan and step back (cin #29) - BOTH_HUGGEE1, //# Jan being hugged (cin #29) - BOTH_HUGGEESTOP1, //# Jan stop being hugged but don't let go (cin #29) - BOTH_HUGGEESTOP2, //# Jan released from hug (cin #29) - BOTH_KISSER1, //# Temp until the Kiss anim gets split up - BOTH_KISSER1START1, //# Kyle start kissing Jan - BOTH_KISSER1START2, //# Kyle start kissing Jan - BOTH_KISSER1LOOP, //# Kyle loop kissing Jan - BOTH_KISSER1STOP, //# Temp until the Kiss anim gets split up - BOTH_KISSER1STOP1, //# Kyle stop kissing but don't let go - BOTH_KISSER1STOP2, //# Kyle step back from Jan - BOTH_KISSEE1, //# Temp until the Kiss anim gets split up - BOTH_KISSEE1START1, //# Jan start being kissed - BOTH_KISSEE1START2, //# Jan start being kissed - BOTH_KISSEE1LOOP, //# Jan loop being kissed - BOTH_KISSEE1STOP, //# Temp until the Kiss anim gets split up - BOTH_KISSEE1STOP1, //# Jan stop being kissed but don't let go - BOTH_KISSEE1STOP2, //# Jan wait for Kyle to step back BOTH_BARTENDER_IDLE1, //# Bartender idle in cin #15 BOTH_BARTENDER_THROW1, //# Bartender throws glass in cin #15 BOTH_BARTENDER_COWERSTART, //# Start of Bartender raising both hands up in surrender (cin #16) @@ -864,6 +810,7 @@ typedef enum //# animNumber_e BOTH_WALK4, //# Walk cycle goes to a stand4 BOTH_WALK5, //# Tavion taunting Kyle (cin 22) BOTH_WALK6, //# Slow walk for Luke (cin 12) + BOTH_WALK7, //# Fast walk BOTH_WALKTORUN1, //# transition from walk to run BOTH_RUN1, //# Full run BOTH_RUN1START, //# Start into full run1 @@ -950,10 +897,16 @@ typedef enum //# animNumber_e BOTH_DIVE1, //# Dive! + BOTH_SABERFAST_STANCE, + BOTH_SABERSLOW_STANCE, + BOTH_ENGAGETAUNT, BOTH_A2_STABBACK1, //# Stab saber backward BOTH_ATTACK_BACK, //# Swing around backwards and attack - BOTH_FJSS_TR_BL, //# jump spin slash tr to bl - BOTH_FJSS_TL_BR, //# jump spin slash bl to tr + BOTH_JUMPFLIPSLASHDOWN1,//# + BOTH_JUMPFLIPSTABDOWN,//# + BOTH_FORCELEAP2_T__B_,//# + BOTH_LUNGE2_B__T_,//# + BOTH_CROUCHATTACKBACK1,//# BOTH_ARIAL_LEFT, //# BOTH_ARIAL_RIGHT, //# BOTH_CARTWHEEL_LEFT, //# @@ -996,20 +949,23 @@ typedef enum //# animNumber_e BOTH_WALL_FLIP_BACK1, //# BOTH_WALL_FLIP_BACK2, //# BOTH_SPIN1, //# + BOTH_CEILING_CLING, //# clinging to ceiling + BOTH_CEILING_DROP, //# dropping from ceiling cling //TESTING + BOTH_FJSS_TR_BL, //# jump spin slash tr to bl + BOTH_FJSS_TL_BR, //# jump spin slash bl to tr BOTH_DEATHFROMBACKSLASH,//# - BOTH_DEFLECTSLASH__R__L_FIN,//# BOTH_RIGHTHANDCHOPPEDOFF,//# - BOTH_JUMPFLIPSLASHDOWN1,//# - BOTH_JUMPFLIPSTABDOWN,//# - BOTH_FORCELEAP2_T__B_,//# - BOTH_LUNGE2_B__T_,//# + BOTH_DEFLECTSLASH__R__L_FIN,//# BOTH_BASHED1,//# BOTH_ARIAL_F1,//# BOTH_BUTTERFLY_FR1,//# BOTH_BUTTERFLY_FL1,//# - BOTH_CROUCHATTACKBACK1,//# + BOTH_POSE1,//# + BOTH_POSE2,//# + BOTH_POSE3,//# + BOTH_POSE4,//# //# #sep BOTH_ MISC MOVEMENT BOTH_HIT1, //# Kyle hit by crate in cin #9 @@ -1070,28 +1026,9 @@ typedef enum //# animNumber_e BOTH_INJURED6POINT, //# Chang points to door while in injured state BOTH_INJUREDTOSTAND1, //# Runinjured to stand1 + BOTH_PROPUP1, //# Kyle getting up from having been knocked down (cin #9 end) BOTH_CRAWLBACK1, //# Lying on back, crawling backwards with elbows BOTH_SITWALL1, //# Sitting against a wall - BOTH_SLEEP1, //# laying on back-rknee up-rhand on torso - BOTH_SLEEP2, //# on floor-back against wall-arms crossed - BOTH_SLEEP3, //# Sleeping in a chair - BOTH_SLEEP4, //# Sleeping slumped over table - BOTH_SLEEP5, //# Laying on side sleeping on flat sufrace - BOTH_SLEEP6START, //# Kyle leaning back to sleep (cin 20) - BOTH_SLEEP6STOP, //# Kyle waking up and shaking his head (cin 21) - BOTH_SLEEP1GETUP, //# alarmed and getting up out of sleep1 pose to stand - BOTH_SLEEP1GETUP2, //# - BOTH_SLEEP2GETUP, //# alarmed and getting up out of sleep2 pose to stand - BOTH_SLEEP3GETUP, //# alarmed and getting up out of sleep3 pose to stand - BOTH_SLEEP3DEATH, //# death in chair, from sleep3 idle - BOTH_SLEEP3DEAD, //# death in chair, from sleep3 idle - - BOTH_SLEEP_IDLE1, //# rub face and nose while asleep from sleep pose 1 - BOTH_SLEEP_IDLE2, //# shift position while asleep - stays in sleep2 - BOTH_SLEEP_IDLE3, //# Idle anim from sleep pose 3 - BOTH_SLEEP_IDLE4, //# Idle anim from sleep pose 4 - BOTH_SLEEP1_NOSE, //# Scratch nose from SLEEP1 pose - BOTH_SLEEP2_SHIFT, //# Shift in sleep from SLEEP2 pose BOTH_RESTRAINED1, //# Telsia tied to medical table BOTH_RESTRAINED1POINT, //# Telsia tied to medical table pointing at Munro BOTH_LIFTED1, //# Fits with BOTH_LIFT1, lifted on shoulder @@ -1113,6 +1050,8 @@ typedef enum //# animNumber_e BOTH_BUTTON1, //# Single button push with right hand BOTH_BUTTON2, //# Single button push with left finger + BOTH_BUTTON_HOLD, //# Single button hold with left hand + BOTH_BUTTON_RELEASE, //# Single button release with left hand //# JEDI-SPECIFIC BOTH_RESISTPUSH, //# plant yourself to resist force push/pulls. @@ -1121,11 +1060,17 @@ typedef enum //# animNumber_e BOTH_MINDTRICK1, //# Use off-hand to do mind trick BOTH_MINDTRICK2, //# Use off-hand to do distraction BOTH_FORCELIGHTNING, //# Use off-hand to do lightning + BOTH_FORCELIGHTNING_HOLD, //# Use off-hand to do lightning - hold + BOTH_FORCELIGHTNING_RELEASE,//# Use off-hand to do lightning - release BOTH_FORCEHEAL_START, //# Healing meditation pose start BOTH_FORCEHEAL_STOP, //# Healing meditation pose end BOTH_FORCEHEAL_QUICK, //# Healing meditation gesture BOTH_SABERPULL, //# Use off-hand to do force power. - BOTH_FORCEGRIP3, //# force-gripping + BOTH_FORCEGRIP1, //# force-gripping (no anim?) + BOTH_FORCEGRIP2, //# force-gripping (?) + BOTH_FORCEGRIP3, //# force-gripping (right hand) + BOTH_FORCEGRIP_HOLD, //# Use off-hand to do grip - hold + BOTH_FORCEGRIP_RELEASE,//# Use off-hand to do grip - release BOTH_TOSS1, //# throwing to left after force gripping BOTH_TOSS2, //# throwing to right after force gripping @@ -1204,8 +1149,6 @@ typedef enum //# animNumber_e TORSO_SURRENDER_START, //# arms up TORSO_SURRENDER_STOP, //# arms back down - TORSO_FORCEGRIP1, //# force-gripping - TORSO_FORCEGRIP2, //# force-gripping TORSO_CHOKING1, //# TEMP @@ -1236,7 +1179,46 @@ typedef enum //# animNumber_e LEGS_RIGHTUP3, //# On a slope with RIGHT foot 12 higher than left LEGS_RIGHTUP4, //# On a slope with RIGHT foot 16 higher than left LEGS_RIGHTUP5, //# On a slope with RIGHT foot 20 higher than left - + LEGS_S1_LUP1, + LEGS_S1_LUP2, + LEGS_S1_LUP3, + LEGS_S1_LUP4, + LEGS_S1_LUP5, + LEGS_S1_RUP1, + LEGS_S1_RUP2, + LEGS_S1_RUP3, + LEGS_S1_RUP4, + LEGS_S1_RUP5, + LEGS_S3_LUP1, + LEGS_S3_LUP2, + LEGS_S3_LUP3, + LEGS_S3_LUP4, + LEGS_S3_LUP5, + LEGS_S3_RUP1, + LEGS_S3_RUP2, + LEGS_S3_RUP3, + LEGS_S3_RUP4, + LEGS_S3_RUP5, + LEGS_S4_LUP1, + LEGS_S4_LUP2, + LEGS_S4_LUP3, + LEGS_S4_LUP4, + LEGS_S4_LUP5, + LEGS_S4_RUP1, + LEGS_S4_RUP2, + LEGS_S4_RUP3, + LEGS_S4_RUP4, + LEGS_S4_RUP5, + LEGS_S5_LUP1, + LEGS_S5_LUP2, + LEGS_S5_LUP3, + LEGS_S5_LUP4, + LEGS_S5_LUP5, + LEGS_S5_RUP1, + LEGS_S5_RUP2, + LEGS_S5_RUP3, + LEGS_S5_RUP4, + LEGS_S5_RUP5, //================================================= //HEAD ANIMS //================================================= diff --git a/CODEmp/game/be_aas.h b/CODE-mp/game/be_aas.h similarity index 100% rename from CODEmp/game/be_aas.h rename to CODE-mp/game/be_aas.h diff --git a/CODEmp/game/be_ai_char.h b/CODE-mp/game/be_ai_char.h similarity index 100% rename from CODEmp/game/be_ai_char.h rename to CODE-mp/game/be_ai_char.h diff --git a/CODEmp/game/be_ai_chat.h b/CODE-mp/game/be_ai_chat.h similarity index 100% rename from CODEmp/game/be_ai_chat.h rename to CODE-mp/game/be_ai_chat.h diff --git a/CODEmp/game/be_ai_gen.h b/CODE-mp/game/be_ai_gen.h similarity index 100% rename from CODEmp/game/be_ai_gen.h rename to CODE-mp/game/be_ai_gen.h diff --git a/CODEmp/game/be_ai_goal.h b/CODE-mp/game/be_ai_goal.h similarity index 100% rename from CODEmp/game/be_ai_goal.h rename to CODE-mp/game/be_ai_goal.h diff --git a/CODEmp/game/be_ai_move.h b/CODE-mp/game/be_ai_move.h similarity index 100% rename from CODEmp/game/be_ai_move.h rename to CODE-mp/game/be_ai_move.h diff --git a/CODEmp/game/be_ai_weap.h b/CODE-mp/game/be_ai_weap.h similarity index 100% rename from CODEmp/game/be_ai_weap.h rename to CODE-mp/game/be_ai_weap.h diff --git a/CODEmp/game/be_ea.h b/CODE-mp/game/be_ea.h similarity index 100% rename from CODEmp/game/be_ea.h rename to CODE-mp/game/be_ea.h diff --git a/CODEmp/game/bg_lib.c b/CODE-mp/game/bg_lib.c similarity index 100% rename from CODEmp/game/bg_lib.c rename to CODE-mp/game/bg_lib.c diff --git a/CODEmp/game/bg_lib.h b/CODE-mp/game/bg_lib.h similarity index 100% rename from CODEmp/game/bg_lib.h rename to CODE-mp/game/bg_lib.h diff --git a/CODEmp/game/bg_local.h b/CODE-mp/game/bg_local.h similarity index 71% rename from CODEmp/game/bg_local.h rename to CODE-mp/game/bg_local.h index 1fb829e..54cf071 100644 --- a/CODEmp/game/bg_local.h +++ b/CODE-mp/game/bg_local.h @@ -6,8 +6,6 @@ #define STEPSIZE 18 -#define JUMP_VELOCITY 225//270 - #define TIMER_LAND 130 #define TIMER_GESTURE (34*66+50) @@ -61,6 +59,26 @@ void trap_FS_Read( void *buffer, int len, fileHandle_t f ); void trap_FS_Write( const void *buffer, int len, fileHandle_t f ); void trap_FS_FCloseFile( fileHandle_t f ); +//PM anim utility functions: +qboolean PM_SaberInParry( int move ); +qboolean PM_SaberInReflect( int move ); +qboolean PM_SaberInStart( int move ); +qboolean PM_InSaberAnim( int anim ); +qboolean PM_InKnockDown( playerState_t *ps ); +qboolean PM_PainAnim( int anim ); +qboolean PM_JumpingAnim( int anim ); +qboolean PM_LandingAnim( int anim ); +qboolean PM_SpinningAnim( int anim ); +qboolean PM_InOnGroundAnim ( int anim ); +qboolean PM_InRollComplete( playerState_t *ps, int anim ); +int PM_AnimLength( int index, animNumber_t anim ); + +int PM_GetSaberStance(void); +float PM_GroundDistance(void); +qboolean PM_SomeoneInFront(trace_t *tr); +saberMoveName_t PM_SaberFlipOverAttackMove(trace_t *tr); +saberMoveName_t PM_SaberJumpAttackMove( void ); + void PM_ClipVelocity( vec3_t in, vec3_t normal, vec3_t out, float overbounce ); void PM_AddTouchEnt( int entityNum ); void PM_AddEvent( int newEvent ); @@ -73,7 +91,6 @@ void BG_CycleInven(playerState_t *ps, int direction); void PM_StartTorsoAnim( int anim ); void PM_ContinueLegsAnim( int anim ); void PM_ForceLegsAnim( int anim ); -void PM_TorsoAnimation( void ); void PM_BeginWeaponChange( int weapon ); void PM_FinishWeaponChange( void ); diff --git a/CODEmp/game/bg_misc.c b/CODE-mp/game/bg_misc.c similarity index 93% rename from CODEmp/game/bg_misc.c rename to CODE-mp/game/bg_misc.c index 7cdb6f6..0b98442 100644 --- a/CODEmp/game/bg_misc.c +++ b/CODE-mp/game/bg_misc.c @@ -182,11 +182,11 @@ Instant shield pickup, restores 25 { "models/map_objects/mp/psd_sm.md3", 0, 0, 0}, /* view */ NULL, -/* icon */ "icons/w_icon_blaster", +/* icon */ "gfx/hud/w_icon_blaster", /* pickup */ "Shield Small", 25, IT_ARMOR, - 0, + 1, //special for shield - max on pickup is maxhealth*tag, thus small shield goes up to 100 shield /* precache */ "", /* sounds */ "" }, @@ -200,11 +200,11 @@ Instant shield pickup, restores 100 { "models/map_objects/mp/psd.md3", 0, 0, 0}, /* view */ NULL, -/* icon */ "icons/w_icon_blaster", +/* icon */ "gfx/hud/w_icon_blaster", /* pickup */ "Shield Large", 100, IT_ARMOR, - 0, + 2, //special for shield - max on pickup is maxhealth*tag, thus large shield goes up to 200 shield /* precache */ "", /* sounds */ "" }, @@ -218,7 +218,7 @@ Instant medpack pickup, heals 25 { "models/map_objects/mp/medpac.md3", 0, 0, 0 }, /* view */ NULL, -/* icon */ "icons/w_icon_blaster", +/* icon */ "gfx/hud/i_icon_medkit", /* pickup */ "Medpack", 25, IT_HEALTH, @@ -461,7 +461,7 @@ Don't place this { "models/weapons2/briar_pistol/briar_pistol_w.glm", 0, 0, 0}, /* view */ "models/weapons2/briar_pistol/briar_pistol.md3", -/* icon */ "icons/w_icon_rifle", +/* icon */ "gfx/hud/w_icon_rifle", /* pickup */ "Bryar Pistol", 50, IT_WEAPON, @@ -478,7 +478,7 @@ Don't place this { "models/weapons2/blaster_r/blaster_w.glm", 0, 0, 0}, /* view */ "models/weapons2/blaster_r/blaster.md3", -/* icon */ "icons/w_icon_blaster", +/* icon */ "gfx/hud/w_icon_blaster", /* pickup */ "E11 Blaster Rifle", 50, IT_WEAPON, @@ -495,7 +495,7 @@ Don't place this { "models/weapons2/disruptor/disruptor_w.glm", 0, 0, 0}, /* view */ "models/weapons2/disruptor/disruptor.md3", -/* icon */ "icons/w_icon_disruptor", +/* icon */ "gfx/hud/w_icon_disruptor", /* pickup */ "Tenloss Disruptor Rifle", 50, IT_WEAPON, @@ -512,7 +512,7 @@ Don't place this { "models/weapons2/bowcaster/bowcaster_w.glm", 0, 0, 0}, /* view */ "models/weapons2/bowcaster/bowcaster.md3", -/* icon */ "icons/w_icon_bowcaster", +/* icon */ "gfx/hud/w_icon_bowcaster", /* pickup */ "Wookiee Bowcaster", 50, IT_WEAPON, @@ -529,7 +529,7 @@ Don't place this { "models/weapons2/heavy_repeater/heavy_repeater_w.glm", 0, 0, 0}, /* view */ "models/weapons2/heavy_repeater/heavy_repeater.md3", -/* icon */ "icons/w_icon_repeater", +/* icon */ "gfx/hud/w_icon_repeater", /* pickup */ "Imperial Heavy Repeater", 50, IT_WEAPON, @@ -547,7 +547,7 @@ NOTENOTE This weapon is not yet complete. Don't place it. { "models/weapons2/demp2/demp2_w.glm", 0, 0, 0}, /* view */ "models/weapons2/demp2/demp2.md3", -/* icon */ "icons/w_icon_demp2", +/* icon */ "gfx/hud/w_icon_demp2", /* pickup */ "DEMP2", 50, IT_WEAPON, @@ -564,7 +564,7 @@ NOTENOTE This weapon is not yet complete. Don't place it. { "models/weapons2/golan_arms/golan_arms_w.glm", 0, 0, 0}, /* view */ "models/weapons2/golan_arms/golan_arms.md3", -/* icon */ "icons/w_icon_flechette", +/* icon */ "gfx/hud/w_icon_flechette", /* pickup */ "Golan Arms Flechette", 50, IT_WEAPON, @@ -581,7 +581,7 @@ NOTENOTE This weapon is not yet complete. Don't place it. { "models/weapons2/merr_sonn/merr_sonn_w.glm", 0, 0, 0}, /* view */ "models/weapons2/merr_sonn/merr_sonn.md3", -/* icon */ "icons/w_icon_launcher", +/* icon */ "gfx/hud/w_icon_merrsonn", /* pickup */ "Merr-Sonn Missile System", 50, IT_WEAPON, @@ -598,7 +598,7 @@ NOTENOTE This weapon is not yet complete. Don't place it. { "models/weapons2/thermal/thermal_w.glm", 0, 0, 0}, /* view */ "models/weapons2/thermal/thermal.md3", -/* icon */ "icons/w_icon_thermal", +/* icon */ "gfx/hud/w_icon_thermal", /* pickup */ "Thermal Detonator", 1, IT_WEAPON, @@ -615,7 +615,7 @@ NOTENOTE This weapon is not yet complete. Don't place it. { "models/weapons2/laser_trap/laser_trap_w.glm", 0, 0, 0}, /* view */ "models/weapons2/laser_trap/laser_trap.md3", -/* icon */ "icons/w_icon_trip_mine", +/* icon */ "gfx/hud/w_icon_tripmine", /* pickup */ "Trip Mine", 1, IT_WEAPON, @@ -629,10 +629,9 @@ NOTENOTE This weapon is not yet complete. Don't place it. { "weapon_det_pack", "sound/weapons/w_pkup.wav", - { "models/weapons2/detpack/det_pack_w.glm", - 0, 0, 0}, + { "models/weapons2/detpack/det_pack_proj.glm", "models/weapons2/detpack/det_pack_w.glm", 0, 0}, /* view */ "models/weapons2/detpack/det_pack.md3", -/* icon */ "icons/w_icon_det_pack", +/* icon */ "gfx/hud/w_icon_detpack", /* pickup */ "Det Pack", 1, IT_WEAPON, @@ -649,7 +648,7 @@ NOTENOTE This weapon is not yet complete. Don't place it. { "models/weapons2/blaster_r/blaster_w.glm", 0, 0, 0}, /* view */ "models/weapons2/blaster_r/blaster.md3", -/* icon */ "icons/w_icon_blaster", +/* icon */ "gfx/hud/w_icon_blaster", /* pickup */ "Emplaced Gun", 50, IT_WEAPON, @@ -666,7 +665,7 @@ NOTENOTE This weapon is not yet complete. Don't place it. { "models/weapons2/blaster_r/blaster_w.glm", 0, 0, 0}, /* view */ "models/weapons2/blaster_r/blaster.md3", -/* icon */ "icons/w_icon_blaster", +/* icon */ "gfx/hud/w_icon_blaster", /* pickup */ "Turret Gun", 50, IT_WEAPON, @@ -688,7 +687,7 @@ Don't place this { "models/items/energy_cell.md3", 0, 0, 0}, /* view */ NULL, -/* icon */ "icons/w_icon_blaster", +/* icon */ "gfx/hud/w_icon_blaster", /* pickup */ "Force??", 100, IT_AMMO, @@ -706,7 +705,7 @@ Ammo for the Bryar and Blaster pistols. { "models/items/energy_cell.md3", 0, 0, 0}, /* view */ NULL, -/* icon */ "icons/w_icon_blaster", +/* icon */ "gfx/hud/i_icon_battery", /* pickup */ "Blaster Pack", 100, IT_AMMO, @@ -724,7 +723,7 @@ Ammo for Tenloss Disruptor, Wookie Bowcaster, and the Destructive Electro Magnet { "models/items/power_cell.md3", 0, 0, 0}, /* view */ NULL, -/* icon */ "icons/w_icon_blaster", +/* icon */ "gfx/hud/w_icon_blaster", /* pickup */ "Power Cell", 100, IT_AMMO, @@ -742,7 +741,7 @@ Ammo for Imperial Heavy Repeater and the Golan Arms Flechette { "models/items/metallic_bolts.md3", 0, 0, 0}, /* view */ NULL, -/* icon */ "icons/w_icon_blaster", +/* icon */ "gfx/hud/w_icon_blaster", /* pickup */ "Metallic Bolts", 100, IT_AMMO, @@ -760,7 +759,7 @@ Ammo for Merr-Sonn portable missile launcher { "models/items/rockets.md3", 0, 0, 0}, /* view */ NULL, -/* icon */ "icons/w_icon_blaster", +/* icon */ "gfx/hud/w_icon_blaster", /* pickup */ "Rockets", 100, IT_AMMO, @@ -910,6 +909,11 @@ qboolean BG_CanUseFPNow(int gametype, playerState_t *ps, int time, forcePowers_t } } + if (ps->fallingToDeath) + { + return qfalse; + } + return qtrue; } @@ -1215,7 +1219,7 @@ qboolean BG_CanItemBeGrabbed( int gametype, const entityState_t *ent, const play return qtrue; case IT_ARMOR: - if ( ps->stats[STAT_ARMOR] >= ps->stats[STAT_MAX_HEALTH]/* * 2*/ ) { + if ( ps->stats[STAT_ARMOR] >= ps->stats[STAT_MAX_HEALTH] * item->giTag ) { return qfalse; } return qtrue; @@ -1699,6 +1703,8 @@ void BG_PlayerStateToEntityState( playerState_t *ps, entityState_t *s, qboolean VectorCopy(ps->lastHitLoc, s->origin2); s->isJediMaster = ps->isJediMaster; + + s->time2 = ps->holocronBits; } /* @@ -1835,6 +1841,8 @@ void BG_PlayerStateToEntityStateExtraPolate( playerState_t *ps, entityState_t *s VectorCopy(ps->lastHitLoc, s->origin2); s->isJediMaster = ps->isJediMaster; + + s->time2 = ps->holocronBits; } /* diff --git a/CODE-mp/game/bg_panimate.c b/CODE-mp/game/bg_panimate.c new file mode 100644 index 0000000..a2ee725 --- /dev/null +++ b/CODE-mp/game/bg_panimate.c @@ -0,0 +1,1012 @@ +// BG_PAnimate.c + +#include "q_shared.h" +#include "bg_public.h" +#include "bg_local.h" +#include "anims.h" +#include "../cgame/animtable.h" + +/* +============================================================================== +BEGIN: Animation utility functions (sequence checking) +============================================================================== +*/ +//Called regardless of pm validity: +qboolean BG_InSpecialJump( int anim ) +{ + switch ( (anim&~ANIM_TOGGLEBIT) ) + { + case BOTH_WALL_RUN_RIGHT: + case BOTH_WALL_RUN_RIGHT_FLIP: + case BOTH_WALL_RUN_LEFT: + case BOTH_WALL_RUN_LEFT_FLIP: + case BOTH_WALL_FLIP_RIGHT: + case BOTH_WALL_FLIP_LEFT: + case BOTH_FLIP_BACK1: + case BOTH_FLIP_BACK2: + case BOTH_FLIP_BACK3: + case BOTH_WALL_FLIP_BACK1: + case BOTH_BUTTERFLY_LEFT: + case BOTH_BUTTERFLY_RIGHT: + return qtrue; + } + return qfalse; +} + +qboolean BG_InSaberStandAnim( int anim ) +{ + switch ( (anim&~ANIM_TOGGLEBIT) ) + { + case BOTH_SABERFAST_STANCE: + case BOTH_STAND2: + case BOTH_SABERSLOW_STANCE: + return qtrue; + default: + return qfalse; + } +} + +qboolean BG_DirectFlippingAnim( int anim ) +{ + switch ( (anim&~ANIM_TOGGLEBIT) ) + { + case BOTH_FLIP_F: //# Flip forward + case BOTH_FLIP_B: //# Flip backwards + case BOTH_FLIP_L: //# Flip left + case BOTH_FLIP_R: //# Flip right + return qtrue; + break; + } + + return qfalse; +} + +qboolean BG_SaberInAttack( int move ) +{ + if ( move >= LS_A_TL2BR && move <= LS_A_T2B ) + { + return qtrue; + } + switch ( move ) + { + case LS_A_BACK: + case LS_A_BACK_CR: + case LS_A_BACKSTAB: + case LS_A_LUNGE: + case LS_A_JUMP_T__B_: + case LS_A_FLIP_STAB: + case LS_A_FLIP_SLASH: + return qtrue; + break; + } + return qfalse; +} + +qboolean BG_SaberInSpecial( int move ) +{ + switch( move ) + { + case LS_A_BACK: + case LS_A_BACK_CR: + case LS_A_BACKSTAB: + case LS_A_LUNGE: + case LS_A_JUMP_T__B_: + case LS_A_FLIP_STAB: + case LS_A_FLIP_SLASH: + return qtrue; + } + return qfalse; +} + +qboolean BG_SaberInIdle( int move ) +{ + switch ( move ) + { + case LS_NONE: + case LS_READY: + case LS_DRAW: + case LS_PUTAWAY: + return qtrue; + break; + } + return qfalse; +} + +qboolean BG_FlippingAnim( int anim ) +{ + switch ( anim ) + { + case BOTH_FLIP_F: //# Flip forward + case BOTH_FLIP_B: //# Flip backwards + case BOTH_FLIP_L: //# Flip left + case BOTH_FLIP_R: //# Flip right + case BOTH_WALL_RUN_RIGHT_FLIP: + case BOTH_WALL_RUN_LEFT_FLIP: + case BOTH_WALL_FLIP_RIGHT: + case BOTH_WALL_FLIP_LEFT: + case BOTH_FLIP_BACK1: + case BOTH_FLIP_BACK2: + case BOTH_FLIP_BACK3: + case BOTH_WALL_FLIP_BACK1: + //Not really flips, but... + case BOTH_WALL_RUN_RIGHT: + case BOTH_WALL_RUN_LEFT: + case BOTH_WALL_RUN_RIGHT_STOP: + case BOTH_WALL_RUN_LEFT_STOP: + case BOTH_BUTTERFLY_LEFT: + case BOTH_BUTTERFLY_RIGHT: + // + case BOTH_ARIAL_LEFT: + case BOTH_ARIAL_RIGHT: + case BOTH_ARIAL_F1: + case BOTH_CARTWHEEL_LEFT: + case BOTH_CARTWHEEL_RIGHT: + case BOTH_JUMPFLIPSLASHDOWN1: + case BOTH_JUMPFLIPSTABDOWN: + return qtrue; + break; + } + return qfalse; +} + +qboolean BG_SpinningSaberAnim( int anim ) +{ + switch ( anim ) + { + //level 1 - FIXME: level 1 will have *no* spins + case BOTH_T1_BR_BL: + case BOTH_T1__R__L: + case BOTH_T1__R_BL: + case BOTH_T1_TR_BL: + case BOTH_T1_BR_TL: + case BOTH_T1_BR__L: + case BOTH_T1_TL_BR: + case BOTH_T1__L_BR: + case BOTH_T1__L__R: + case BOTH_T1_BL_BR: + case BOTH_T1_BL__R: + case BOTH_T1_BL_TR: + //level 2 + case BOTH_T2_BR__L: + case BOTH_T2_BR_BL: + case BOTH_T2__R_BL: + case BOTH_T2__L_BR: + case BOTH_T2_BL_BR: + case BOTH_T2_BL__R: + //level 3 + case BOTH_T3_BR__L: + case BOTH_T3_BR_BL: + case BOTH_T3__R_BL: + case BOTH_T3__L_BR: + case BOTH_T3_BL_BR: + case BOTH_T3_BL__R: + //level 4 + case BOTH_T4_BR__L: + case BOTH_T4_BR_BL: + case BOTH_T4__R_BL: + case BOTH_T4__L_BR: + case BOTH_T4_BL_BR: + case BOTH_T4_BL__R: + //level 5 + case BOTH_T5_BR_BL: + case BOTH_T5__R__L: + case BOTH_T5__R_BL: + case BOTH_T5_TR_BL: + case BOTH_T5_BR_TL: + case BOTH_T5_BR__L: + case BOTH_T5_TL_BR: + case BOTH_T5__L_BR: + case BOTH_T5__L__R: + case BOTH_T5_BL_BR: + case BOTH_T5_BL__R: + case BOTH_T5_BL_TR: + //special + //case BOTH_A2_STABBACK1: + case BOTH_ATTACK_BACK: + case BOTH_CROUCHATTACKBACK1: + case BOTH_BUTTERFLY_LEFT: + case BOTH_BUTTERFLY_RIGHT: + case BOTH_FJSS_TR_BL: + case BOTH_FJSS_TL_BR: + case BOTH_JUMPFLIPSLASHDOWN1: + case BOTH_JUMPFLIPSTABDOWN: + return qtrue; + break; + } + return qfalse; +} + +qboolean BG_SaberInSpecialAttack( int anim ) +{ + switch ( anim&~ANIM_TOGGLEBIT ) + { + case BOTH_A2_STABBACK1: + case BOTH_ATTACK_BACK: + case BOTH_CROUCHATTACKBACK1: + case BOTH_BUTTERFLY_LEFT: + case BOTH_BUTTERFLY_RIGHT: + case BOTH_FJSS_TR_BL: + case BOTH_FJSS_TL_BR: + case BOTH_LUNGE2_B__T_: + case BOTH_FORCELEAP2_T__B_: + case BOTH_JUMPFLIPSLASHDOWN1://# + case BOTH_JUMPFLIPSTABDOWN://# + return qtrue; + } + return qfalse; +} + +qboolean BG_InRoll( playerState_t *ps, int anim ) +{ + switch ( (anim&~ANIM_TOGGLEBIT) ) + { + case BOTH_ROLL_F: + case BOTH_ROLL_B: + case BOTH_ROLL_R: + case BOTH_ROLL_L: + if ( ps->legsTimer > 0 ) + { + return qtrue; + } + break; + } + return qfalse; +} + +qboolean BG_InDeathAnim( int anim ) +{ + switch((anim&~ANIM_TOGGLEBIT)) + { + case BOTH_DIVE1: + case BOTH_DEATHBACKWARD1: + case BOTH_DEATHBACKWARD2: + case BOTH_DEATHFORWARD1: + case BOTH_DEATHFORWARD2: + case BOTH_DEATH1: + case BOTH_DEATH2: + case BOTH_DEATH3: + case BOTH_DEATH4: + case BOTH_DEATH5: + case BOTH_DEATH6: + case BOTH_DEATH7: + + case BOTH_DEATH1IDLE: + case BOTH_LYINGDEATH1: + case BOTH_STUMBLEDEATH1: + case BOTH_FALLDEATH1: + case BOTH_FALLDEATH1INAIR: + case BOTH_FALLDEATH1LAND: + return qtrue; + break; + default: + return qfalse; + break; + } +} + +//Called only where pm is valid (not all require pm, but some do): +qboolean PM_SaberInParry( int move ) +{ + if ( move >= LS_PARRY_UP && move <= LS_PARRY_LL ) + { + return qtrue; + } + return qfalse; +} + +qboolean PM_SaberInReflect( int move ) +{ + if ( move >= LS_REFLECT_UP && move <= LS_REFLECT_LL ) + { + return qtrue; + } + return qfalse; +} + +qboolean PM_SaberInStart( int move ) +{ + if ( move >= LS_S_TL2BR && move <= LS_S_T2B ) + { + return qtrue; + } + return qfalse; +} + +qboolean PM_InSaberAnim( int anim ) +{ + if ( (anim&~ANIM_TOGGLEBIT) >= BOTH_A1_T__B_ && (anim&~ANIM_TOGGLEBIT) <= BOTH_H1_S1_BR ) + { + return qtrue; + } + return qfalse; +} + +qboolean PM_InKnockDown( playerState_t *ps ) +{ + switch ( (ps->legsAnim&~ANIM_TOGGLEBIT) ) + { + case BOTH_KNOCKDOWN1: + case BOTH_KNOCKDOWN2: + case BOTH_KNOCKDOWN3: + case BOTH_KNOCKDOWN4: + case BOTH_KNOCKDOWN5: + return qtrue; + break; + case BOTH_GETUP1: + case BOTH_GETUP2: + case BOTH_GETUP3: + case BOTH_GETUP4: + case BOTH_GETUP5: + case BOTH_FORCE_GETUP_F1: + case BOTH_FORCE_GETUP_F2: + case BOTH_FORCE_GETUP_B1: + case BOTH_FORCE_GETUP_B2: + case BOTH_FORCE_GETUP_B3: + case BOTH_FORCE_GETUP_B4: + case BOTH_FORCE_GETUP_B5: + if ( ps->legsTimer ) + { + return qtrue; + } + break; + } + return qfalse; +} + +qboolean PM_PainAnim( int anim ) +{ + switch ( (anim&~ANIM_TOGGLEBIT) ) + { + case BOTH_PAIN1: //# First take pain anim + case BOTH_PAIN2: //# Second take pain anim + case BOTH_PAIN3: //# Third take pain anim + case BOTH_PAIN4: //# Fourth take pain anim + case BOTH_PAIN5: //# Fifth take pain anim - from behind + case BOTH_PAIN6: //# Sixth take pain anim - from behind + case BOTH_PAIN7: //# Seventh take pain anim - from behind + case BOTH_PAIN8: //# Eigth take pain anim - from behind + case BOTH_PAIN9: //# + case BOTH_PAIN10: //# + case BOTH_PAIN11: //# + case BOTH_PAIN12: //# + case BOTH_PAIN13: //# + case BOTH_PAIN14: //# + case BOTH_PAIN15: //# + case BOTH_PAIN16: //# + case BOTH_PAIN17: //# + case BOTH_PAIN18: //# + case BOTH_PAIN19: //# + return qtrue; + break; + } + return qfalse; +} + +qboolean PM_JumpingAnim( int anim ) +{ + switch ( (anim&~ANIM_TOGGLEBIT) ) + { + case BOTH_JUMP1: //# Jump - wind-up and leave ground + case BOTH_INAIR1: //# In air loop (from jump) + case BOTH_LAND1: //# Landing (from in air loop) + case BOTH_LAND2: //# Landing Hard (from a great height) + case BOTH_JUMPBACK1: //# Jump backwards - wind-up and leave ground + case BOTH_INAIRBACK1: //# In air loop (from jump back) + case BOTH_LANDBACK1: //# Landing backwards(from in air loop) + case BOTH_JUMPLEFT1: //# Jump left - wind-up and leave ground + case BOTH_INAIRLEFT1: //# In air loop (from jump left) + case BOTH_LANDLEFT1: //# Landing left(from in air loop) + case BOTH_JUMPRIGHT1: //# Jump right - wind-up and leave ground + case BOTH_INAIRRIGHT1: //# In air loop (from jump right) + case BOTH_LANDRIGHT1: //# Landing right(from in air loop) + case BOTH_FORCEJUMP1: //# Jump - wind-up and leave ground + case BOTH_FORCEINAIR1: //# In air loop (from jump) + case BOTH_FORCELAND1: //# Landing (from in air loop) + case BOTH_FORCEJUMPBACK1: //# Jump backwards - wind-up and leave ground + case BOTH_FORCEINAIRBACK1: //# In air loop (from jump back) + case BOTH_FORCELANDBACK1: //# Landing backwards(from in air loop) + case BOTH_FORCEJUMPLEFT1: //# Jump left - wind-up and leave ground + case BOTH_FORCEINAIRLEFT1: //# In air loop (from jump left) + case BOTH_FORCELANDLEFT1: //# Landing left(from in air loop) + case BOTH_FORCEJUMPRIGHT1: //# Jump right - wind-up and leave ground + case BOTH_FORCEINAIRRIGHT1: //# In air loop (from jump right) + case BOTH_FORCELANDRIGHT1: //# Landing right(from in air loop) + return qtrue; + break; + } + return qfalse; +} + +qboolean PM_LandingAnim( int anim ) +{ + switch ( (anim&~ANIM_TOGGLEBIT) ) + { + case BOTH_LAND1: //# Landing (from in air loop) + case BOTH_LAND2: //# Landing Hard (from a great height) + case BOTH_LANDBACK1: //# Landing backwards(from in air loop) + case BOTH_LANDLEFT1: //# Landing left(from in air loop) + case BOTH_LANDRIGHT1: //# Landing right(from in air loop) + case BOTH_FORCELAND1: //# Landing (from in air loop) + case BOTH_FORCELANDBACK1: //# Landing backwards(from in air loop) + case BOTH_FORCELANDLEFT1: //# Landing left(from in air loop) + case BOTH_FORCELANDRIGHT1: //# Landing right(from in air loop) + return qtrue; + break; + } + return qfalse; +} + +qboolean PM_SpinningAnim( int anim ) +{ + /* + switch ( anim ) + { + //FIXME: list any other spinning anims + default: + break; + } + */ + return BG_SpinningSaberAnim( anim ); +} + +qboolean PM_InOnGroundAnim ( int anim ) +{ + switch( anim&~ANIM_TOGGLEBIT ) + { + case BOTH_DEAD1: + case BOTH_DEAD2: + case BOTH_DEAD3: + case BOTH_DEAD4: + case BOTH_DEAD5: + case BOTH_DEADFORWARD1: + case BOTH_DEADBACKWARD1: + case BOTH_DEADFORWARD2: + case BOTH_DEADBACKWARD2: + case BOTH_LYINGDEATH1: + case BOTH_LYINGDEAD1: + case BOTH_PAIN2WRITHE1: //# Transition from upright position to writhing on ground anim + case BOTH_WRITHING1: //# Lying on ground writhing in pain + case BOTH_WRITHING1RLEG: //# Lying on ground writhing in pain: holding right leg + case BOTH_WRITHING1LLEG: //# Lying on ground writhing in pain: holding left leg + case BOTH_WRITHING2: //# Lying on stomache writhing in pain + case BOTH_INJURED1: //# Lying down: against wall - can also be sleeping + case BOTH_CRAWLBACK1: //# Lying on back: crawling backwards with elbows + case BOTH_INJURED2: //# Injured pose 2 + case BOTH_INJURED3: //# Injured pose 3 + case BOTH_INJURED6: //# Injured pose 6 + case BOTH_INJURED6ATTACKSTART: //# Start attack while in injured 6 pose + case BOTH_INJURED6ATTACKSTOP: //# End attack while in injured 6 pose + case BOTH_INJURED6COMBADGE: //# Hit combadge while in injured 6 pose + case BOTH_INJURED6POINT: //# Chang points to door while in injured state + case BOTH_KNOCKDOWN1: //# + case BOTH_KNOCKDOWN2: //# + return qtrue; + break; + } + + return qfalse; +} + +qboolean PM_InRollComplete( playerState_t *ps, int anim ) +{ + switch ( (anim&~ANIM_TOGGLEBIT) ) + { + case BOTH_ROLL_F: + case BOTH_ROLL_B: + case BOTH_ROLL_R: + case BOTH_ROLL_L: + if ( ps->legsTimer < 1 ) + { + return qtrue; + } + break; + } + return qfalse; +} + +int PM_AnimLength( int index, animNumber_t anim ) +{ + if (anim >= MAX_ANIMATIONS) + { + return -1; + } + return pm->animations[anim].numFrames * fabs(pm->animations[anim].frameLerp); +} + +void PM_DebugLegsAnim(int anim) +{ + int oldAnim = (pm->ps->legsAnim & ~ANIM_TOGGLEBIT); + int newAnim = (anim & ~ANIM_TOGGLEBIT); + + if (oldAnim < MAX_TOTALANIMATIONS && oldAnim >= BOTH_DEATH1 && + newAnim < MAX_TOTALANIMATIONS && newAnim >= BOTH_DEATH1) + { + Com_Printf("OLD: %s\n", animTable[oldAnim]); + Com_Printf("NEW: %s\n", animTable[newAnim]); + } +} +/* +============================================================================== +END: Animation utility functions (sequence checking) +============================================================================== +*/ + +/* +====================== +BG_ParseAnimationFile + +Read a configuration file containing animation coutns and rates +models/players/visor/animation.cfg, etc + +====================== +*/ +char BGPAFtext[40000]; +qboolean BGPAFtextLoaded = qfalse; +animation_t bgGlobalAnimations[MAX_TOTALANIMATIONS]; + +qboolean BG_ParseAnimationFile( const char *filename, animation_t *animations) +{ + char *text_p; + int len; + int i; + char *token; + float fps; + int skip; + + fileHandle_t f; + int animNum; + + + // load the file + if (!BGPAFtextLoaded) + { //rww - We are always using the same animation config now. So only load it once. + len = trap_FS_FOpenFile( filename, &f, FS_READ ); + if ( len <= 0 ) + { + return qfalse; + } + if ( len >= sizeof( BGPAFtext ) - 1 ) + { + // gi.Printf( "File %s too long\n", filename ); + return qfalse; + } + + trap_FS_Read( BGPAFtext, len, f ); + BGPAFtext[len] = 0; + trap_FS_FCloseFile( f ); + } + else + { + for(i = 0; i < MAX_ANIMATIONS; i++) + { + animations[i].firstFrame = bgGlobalAnimations[i].firstFrame; + animations[i].flipflop = bgGlobalAnimations[i].flipflop; + animations[i].frameLerp = bgGlobalAnimations[i].frameLerp; + animations[i].initialLerp = bgGlobalAnimations[i].initialLerp; + animations[i].loopFrames = bgGlobalAnimations[i].loopFrames; + animations[i].numFrames = bgGlobalAnimations[i].numFrames; + animations[i].reversed = bgGlobalAnimations[i].reversed; + } + + return qtrue; + } + + // parse the text + text_p = BGPAFtext; + skip = 0; // quiet the compiler warning + + //FIXME: have some way of playing anims backwards... negative numFrames? + + //initialize anim array so that from 0 to MAX_ANIMATIONS, set default values of 0 1 0 100 + for(i = 0; i < MAX_ANIMATIONS; i++) + { + animations[i].firstFrame = 0; + animations[i].numFrames = 0; + animations[i].loopFrames = -1; + animations[i].frameLerp = 100; + animations[i].initialLerp = 100; + } + + // read information for each frame + while(1) + { + token = COM_Parse( (const char **)(&text_p) ); + + if ( !token || !token[0]) + { + break; + } + + animNum = GetIDForString(animTable, token); + if(animNum == -1) + { +//#ifndef FINAL_BUILD +#ifdef _DEBUG + Com_Printf(S_COLOR_RED"WARNING: Unknown token %s in %s\n", token, filename); +#endif + continue; + } + + token = COM_Parse( (const char **)(&text_p) ); + if ( !token ) + { + break; + } + animations[animNum].firstFrame = atoi( token ); + + token = COM_Parse( (const char **)(&text_p) ); + if ( !token ) + { + break; + } + animations[animNum].numFrames = atoi( token ); + + token = COM_Parse( (const char **)(&text_p) ); + if ( !token ) + { + break; + } + animations[animNum].loopFrames = atoi( token ); + + token = COM_Parse( (const char **)(&text_p) ); + if ( !token ) + { + break; + } + fps = atof( token ); + if ( fps == 0 ) + { + fps = 1;//Don't allow divide by zero error + } + if ( fps < 0 ) + {//backwards + animations[animNum].frameLerp = floor(1000.0f / fps); + } + else + { + animations[animNum].frameLerp = ceil(1000.0f / fps); + } + + animations[animNum].initialLerp = ceil(1000.0f / fabs(fps)); + } + + for(i = 0; i < MAX_ANIMATIONS; i++) + { + bgGlobalAnimations[i].firstFrame = animations[i].firstFrame; + bgGlobalAnimations[i].flipflop = animations[i].flipflop; + bgGlobalAnimations[i].frameLerp = animations[i].frameLerp; + bgGlobalAnimations[i].initialLerp = animations[i].initialLerp; + bgGlobalAnimations[i].loopFrames = animations[i].loopFrames; + bgGlobalAnimations[i].numFrames = animations[i].numFrames; + bgGlobalAnimations[i].reversed = animations[i].reversed; + } + + BGPAFtextLoaded = qtrue; + return qtrue; +} + + + +/* +=================== +LEGS Animations +Base animation for overall body +=================== +*/ +static void PM_StartLegsAnim( int anim ) { + if ( pm->ps->pm_type >= PM_DEAD ) { + return; + } + if ( pm->ps->legsTimer > 0 ) { + return; // a high priority animation is running + } + + if (pm->ps->usingATST) + { //animation is handled mostly client-side with only a few exceptions + return; + } + + if (BG_InSaberStandAnim(anim) && pm->ps->weapon == WP_SABER && pm->ps->dualBlade) + { //a bit of a hack, but dualblade is cheat-only anyway + anim = BOTH_STAND1; + } + + pm->ps->legsAnim = ( ( pm->ps->legsAnim & ANIM_TOGGLEBIT ) ^ ANIM_TOGGLEBIT ) + | anim; + + if ( pm->debugLevel ) { + Com_Printf("%d: StartLegsAnim %d, on client#%d\n", pm->cmd.serverTime, anim, pm->ps->clientNum); + } +} + +void PM_ContinueLegsAnim( int anim ) { + if ( ( pm->ps->legsAnim & ~ANIM_TOGGLEBIT ) == anim ) { + return; + } + if ( pm->ps->legsTimer > 0 ) { + return; // a high priority animation is running + } + + PM_StartLegsAnim( anim ); +} + +void PM_ForceLegsAnim( int anim) { + if (BG_InSpecialJump(pm->ps->legsAnim) && + pm->ps->legsTimer > 0 && + !BG_InSpecialJump(anim)) + { + return; + } + + if (BG_InRoll(pm->ps, pm->ps->legsAnim) && + pm->ps->legsTimer > 0 && + !BG_InRoll(pm->ps, anim)) + { + return; + } + + pm->ps->legsTimer = 0; + PM_StartLegsAnim( anim ); +} + + + +/* +=================== +TORSO Animations +Override animations for upper body +=================== +*/ +void PM_StartTorsoAnim( int anim ) { + if ( pm->ps->pm_type >= PM_DEAD ) { + return; + } + + if (pm->ps->usingATST) + { //animation is handled mostly client-side with only a few exceptions + return; + } + + if (BG_InSaberStandAnim(anim) && pm->ps->weapon == WP_SABER && pm->ps->dualBlade) + { //a bit of a hack, but dualblade is cheat-only anyway + anim = BOTH_STAND1; + } + + pm->ps->torsoAnim = ( ( pm->ps->torsoAnim & ANIM_TOGGLEBIT ) ^ ANIM_TOGGLEBIT ) + | anim; +} + +static void PM_ContinueTorsoAnim( int anim ) { + if ( ( pm->ps->torsoAnim & ~ANIM_TOGGLEBIT ) == anim ) { + return; + } + if ( pm->ps->torsoTimer > 0 ) { + return; // a high priority animation is running + } + PM_StartTorsoAnim( anim); +} + + +/* +------------------------- +PM_SetLegsAnimTimer +------------------------- +*/ + +void PM_SetLegsAnimTimer(int time ) +{ + pm->ps->legsTimer = time; + + if (pm->ps->legsTimer < 0 && time != -1 ) + {//Cap timer to 0 if was counting down, but let it be -1 if that was intentional. NOTENOTE Yeah this seems dumb, but it mirrors SP. + pm->ps->legsTimer = 0; + } +} + +/* +------------------------- +PM_SetTorsoAnimTimer +------------------------- +*/ + +void PM_SetTorsoAnimTimer(int time ) +{ + pm->ps->torsoTimer = time; + + if (pm->ps->torsoTimer < 0 && time != -1 ) + {//Cap timer to 0 if was counting down, but let it be -1 if that was intentional. NOTENOTE Yeah this seems dumb, but it mirrors SP. + pm->ps->torsoTimer = 0; + } +} + +void BG_SaberStartTransAnim( int saberAnimLevel, int anim, float *animSpeed ) +{ + if ( ( (anim&~ANIM_TOGGLEBIT) >= BOTH_T1_BR__R && + (anim&~ANIM_TOGGLEBIT) <= BOTH_T1_BL_TL ) || + ( (anim&~ANIM_TOGGLEBIT) >= BOTH_T2_BR__R && + (anim&~ANIM_TOGGLEBIT) <= BOTH_T2_BL_TL ) || + ( (anim&~ANIM_TOGGLEBIT) >= BOTH_T3_BR__R && + (anim&~ANIM_TOGGLEBIT) <= BOTH_T3_BL_TL ) ) + { + if ( saberAnimLevel == FORCE_LEVEL_1 ) + { + *animSpeed *= 1.5; + } + else if ( saberAnimLevel == FORCE_LEVEL_3 ) + { + *animSpeed *= 0.75; + } + } +} + +/* +------------------------- +PM_SetAnimFinal +------------------------- +*/ +void PM_SetAnimFinal(int setAnimParts,int anim,int setAnimFlags, + int blendTime) // default blendTime=350 +{ + animation_t *animations = pm->animations; + + float editAnimSpeed = 0; + + if (!animations) + { + return; + } + + //NOTE: Setting blendTime here breaks actual blending.. + blendTime = 0; + + BG_SaberStartTransAnim(pm->ps->fd.saberAnimLevel, anim, &editAnimSpeed); + + // Set torso anim + if (setAnimParts & SETANIM_TORSO) + { + // Don't reset if it's already running the anim + if( !(setAnimFlags & SETANIM_FLAG_RESTART) && (pm->ps->torsoAnim & ~ANIM_TOGGLEBIT ) == anim ) + { + goto setAnimLegs; + } + // or if a more important anim is running + if( !(setAnimFlags & SETANIM_FLAG_OVERRIDE) && ((pm->ps->torsoTimer > 0)||(pm->ps->torsoTimer == -1)) ) + { + goto setAnimLegs; + } + + PM_StartTorsoAnim( anim ); + + if (setAnimFlags & SETANIM_FLAG_HOLD) + {//FIXME: allow to set a specific time? + if (setAnimFlags & SETANIM_FLAG_HOLDLESS) + { // Make sure to only wait in full 1/20 sec server frame intervals. + int dur; + + dur = (animations[anim].numFrames ) * fabs(animations[anim].frameLerp); + //dur = ((int)(dur/50.0)) * 50 / timeScaleMod; + dur -= blendTime+fabs(animations[anim].frameLerp)*2; + if (dur > 1) + { + pm->ps->torsoTimer = dur-1; + } + else + { + pm->ps->torsoTimer = fabs(animations[anim].frameLerp); + } + } + else + { + pm->ps->torsoTimer = ((animations[anim].numFrames ) * fabs(animations[anim].frameLerp)); + } + + if (pm->ps->fd.forcePowersActive & (1 << FP_RAGE)) + { + pm->ps->torsoTimer /= 1.7; + } + + if (editAnimSpeed) + { + pm->ps->torsoTimer /= editAnimSpeed; + } + } + } + +setAnimLegs: + // Set legs anim + if (setAnimParts & SETANIM_LEGS) + { + // Don't reset if it's already running the anim + if( !(setAnimFlags & SETANIM_FLAG_RESTART) && (pm->ps->legsAnim & ~ANIM_TOGGLEBIT ) == anim ) + { + goto setAnimDone; + } + // or if a more important anim is running + if( !(setAnimFlags & SETANIM_FLAG_OVERRIDE) && ((pm->ps->legsTimer > 0)||(pm->ps->legsTimer == -1)) ) + { + goto setAnimDone; + } + + PM_StartLegsAnim(anim); + + if (setAnimFlags & SETANIM_FLAG_HOLD) + {//FIXME: allow to set a specific time? + if (setAnimFlags & SETANIM_FLAG_HOLDLESS) + { // Make sure to only wait in full 1/20 sec server frame intervals. + int dur; + + dur = (animations[anim].numFrames -1) * fabs(animations[anim].frameLerp); + //dur = ((int)(dur/50.0)) * 50 / timeScaleMod; + dur -= blendTime+fabs(animations[anim].frameLerp)*2; + if (dur > 1) + { + pm->ps->legsTimer = dur-1; + } + else + { + pm->ps->legsTimer = fabs(animations[anim].frameLerp); + } + } + else + { + pm->ps->legsTimer = ((animations[anim].numFrames ) * fabs(animations[anim].frameLerp)); + } + + /* + PM_DebugLegsAnim(anim); + Com_Printf("%i\n", pm->ps->legsTimer); + */ + + if (pm->ps->fd.forcePowersActive & (1 << FP_RAGE)) + { + pm->ps->legsTimer /= 1.3; + } + else if (pm->ps->fd.forcePowersActive & (1 << FP_SPEED)) + { + pm->ps->legsTimer /= 1.7; + } + } + } + +setAnimDone: + return; +} + + + +// Imported from single-player, this function is mainly intended to make porting from SP easier. +void PM_SetAnim(int setAnimParts,int anim,int setAnimFlags, int blendTime) +{ + if (BG_InSpecialJump(anim)) + { + setAnimFlags |= SETANIM_FLAG_RESTART; + } + + if (BG_InRoll(pm->ps, pm->ps->legsAnim)) + { + //setAnimFlags |= SETANIM_FLAG_RESTART; + return; + } + + if (setAnimFlags&SETANIM_FLAG_OVERRIDE) + { + if (setAnimParts & SETANIM_TORSO) + { + if( (setAnimFlags & SETANIM_FLAG_RESTART) || (pm->ps->torsoAnim & ~ANIM_TOGGLEBIT ) != anim ) + { + PM_SetTorsoAnimTimer(0); + } + } + if (setAnimParts & SETANIM_LEGS) + { + if( (setAnimFlags & SETANIM_FLAG_RESTART) || (pm->ps->legsAnim & ~ANIM_TOGGLEBIT ) != anim ) + { + PM_SetLegsAnimTimer(0); + } + } + } + + PM_SetAnimFinal(setAnimParts, anim, setAnimFlags, blendTime); +} + + diff --git a/CODEmp/game/bg_pmove.c b/CODE-mp/game/bg_pmove.c similarity index 82% rename from CODEmp/game/bg_pmove.c rename to CODE-mp/game/bg_pmove.c index 1ffc47e..2299bb5 100644 --- a/CODEmp/game/bg_pmove.c +++ b/CODE-mp/game/bg_pmove.c @@ -142,6 +142,21 @@ float forceJumpStrength[NUM_FORCE_POWER_LEVELS] = 840 }; +int PM_GetSaberStance(void) +{ + if (pm->ps->fd.saberAnimLevel == FORCE_LEVEL_2) + { //medium + return BOTH_STAND2; + } + if (pm->ps->fd.saberAnimLevel == FORCE_LEVEL_3) + { //strong + return BOTH_SABERSLOW_STANCE; + } + + //fast + return BOTH_SABERFAST_STANCE; +} + /* =============== PM_AddEvent @@ -407,9 +422,6 @@ static void PM_SetMovementDir( void ) { #define METROID_JUMP 1 -qboolean PM_SaberInSpecialAttack( int anim ); -qboolean PM_SaberInSpecial( int move ); - qboolean PM_ForceJumpingUp(void) { if ( !(pm->ps->fd.forcePowersActive&(1<ps->fd.forceJumpCharge ) @@ -422,12 +434,12 @@ qboolean PM_ForceJumpingUp(void) return qfalse; } - if (PM_SaberInSpecial(pm->ps->saberMove)) + if (BG_SaberInSpecial(pm->ps->saberMove)) { return qfalse; } - if (PM_SaberInSpecialAttack(pm->ps->legsAnim)) + if (BG_SaberInSpecialAttack(pm->ps->legsAnim)) { return qfalse; } @@ -452,187 +464,6 @@ qboolean PM_ForceJumpingUp(void) return qfalse; } - -qboolean PM_InSaberAnim( int anim ) -{ - if ( (anim&~ANIM_TOGGLEBIT) >= BOTH_A1_T__B_ && (anim&~ANIM_TOGGLEBIT) <= BOTH_H1_S1_BR ) - { - return qtrue; - } - return qfalse; -} - -qboolean PM_InKnockDown( playerState_t *ps ) -{ - switch ( (ps->legsAnim&~ANIM_TOGGLEBIT) ) - { - case BOTH_KNOCKDOWN1: - case BOTH_KNOCKDOWN2: - case BOTH_KNOCKDOWN3: - case BOTH_KNOCKDOWN4: - case BOTH_KNOCKDOWN5: - return qtrue; - break; - case BOTH_GETUP1: - case BOTH_GETUP2: - case BOTH_GETUP3: - case BOTH_GETUP4: - case BOTH_GETUP5: - case BOTH_FORCE_GETUP_F1: - case BOTH_FORCE_GETUP_F2: - case BOTH_FORCE_GETUP_B1: - case BOTH_FORCE_GETUP_B2: - case BOTH_FORCE_GETUP_B3: - case BOTH_FORCE_GETUP_B4: - case BOTH_FORCE_GETUP_B5: - if ( ps->legsTimer ) - { - return qtrue; - } - break; - } - return qfalse; -} - -qboolean PM_InRoll( playerState_t *ps, int anim ) -{ - switch ( (anim&~ANIM_TOGGLEBIT) ) - { - case BOTH_ROLL_F: - case BOTH_ROLL_B: - case BOTH_ROLL_R: - case BOTH_ROLL_L: - if ( ps->legsTimer > 0 ) - { - return qtrue; - } - break; - } - return qfalse; -} - -qboolean PM_PainAnim( int anim ) -{ - switch ( (anim&~ANIM_TOGGLEBIT) ) - { - case BOTH_PAIN1: //# First take pain anim - case BOTH_PAIN2: //# Second take pain anim - case BOTH_PAIN3: //# Third take pain anim - case BOTH_PAIN4: //# Fourth take pain anim - case BOTH_PAIN5: //# Fifth take pain anim - from behind - case BOTH_PAIN6: //# Sixth take pain anim - from behind - case BOTH_PAIN7: //# Seventh take pain anim - from behind - case BOTH_PAIN8: //# Eigth take pain anim - from behind - case BOTH_PAIN9: //# - case BOTH_PAIN10: //# - case BOTH_PAIN11: //# - case BOTH_PAIN12: //# - case BOTH_PAIN13: //# - case BOTH_PAIN14: //# - case BOTH_PAIN15: //# - case BOTH_PAIN16: //# - case BOTH_PAIN17: //# - case BOTH_PAIN18: //# - case BOTH_PAIN19: //# - return qtrue; - break; - } - return qfalse; -} -qboolean PM_JumpingAnim( int anim ) -{ - switch ( (anim&~ANIM_TOGGLEBIT) ) - { - case BOTH_JUMP1: //# Jump - wind-up and leave ground - case BOTH_INAIR1: //# In air loop (from jump) - case BOTH_LAND1: //# Landing (from in air loop) - case BOTH_LAND2: //# Landing Hard (from a great height) - case BOTH_JUMPBACK1: //# Jump backwards - wind-up and leave ground - case BOTH_INAIRBACK1: //# In air loop (from jump back) - case BOTH_LANDBACK1: //# Landing backwards(from in air loop) - case BOTH_JUMPLEFT1: //# Jump left - wind-up and leave ground - case BOTH_INAIRLEFT1: //# In air loop (from jump left) - case BOTH_LANDLEFT1: //# Landing left(from in air loop) - case BOTH_JUMPRIGHT1: //# Jump right - wind-up and leave ground - case BOTH_INAIRRIGHT1: //# In air loop (from jump right) - case BOTH_LANDRIGHT1: //# Landing right(from in air loop) - case BOTH_FORCEJUMP1: //# Jump - wind-up and leave ground - case BOTH_FORCEINAIR1: //# In air loop (from jump) - case BOTH_FORCELAND1: //# Landing (from in air loop) - case BOTH_FORCEJUMPBACK1: //# Jump backwards - wind-up and leave ground - case BOTH_FORCEINAIRBACK1: //# In air loop (from jump back) - case BOTH_FORCELANDBACK1: //# Landing backwards(from in air loop) - case BOTH_FORCEJUMPLEFT1: //# Jump left - wind-up and leave ground - case BOTH_FORCEINAIRLEFT1: //# In air loop (from jump left) - case BOTH_FORCELANDLEFT1: //# Landing left(from in air loop) - case BOTH_FORCEJUMPRIGHT1: //# Jump right - wind-up and leave ground - case BOTH_FORCEINAIRRIGHT1: //# In air loop (from jump right) - case BOTH_FORCELANDRIGHT1: //# Landing right(from in air loop) - return qtrue; - break; - } - return qfalse; -} - -qboolean PM_LandingAnim( int anim ) -{ - switch ( (anim&~ANIM_TOGGLEBIT) ) - { - case BOTH_LAND1: //# Landing (from in air loop) - case BOTH_LAND2: //# Landing Hard (from a great height) - case BOTH_LANDBACK1: //# Landing backwards(from in air loop) - case BOTH_LANDLEFT1: //# Landing left(from in air loop) - case BOTH_LANDRIGHT1: //# Landing right(from in air loop) - case BOTH_FORCELAND1: //# Landing (from in air loop) - case BOTH_FORCELANDBACK1: //# Landing backwards(from in air loop) - case BOTH_FORCELANDLEFT1: //# Landing left(from in air loop) - case BOTH_FORCELANDRIGHT1: //# Landing right(from in air loop) - return qtrue; - break; - } - return qfalse; -} - -int PM_AnimLength( int index, animNumber_t anim ) -{ - if (anim >= MAX_ANIMATIONS) - { - return -1; - } - return pm->animations[anim].numFrames * fabs(pm->animations[anim].frameLerp); -} - -qboolean PM_InDeathAnim( int anim ) -{ - switch((anim&~ANIM_TOGGLEBIT)) - { - case BOTH_DIVE1: - case BOTH_DEATHBACKWARD1: - case BOTH_DEATHBACKWARD2: - case BOTH_DEATHFORWARD1: - case BOTH_DEATHFORWARD2: - case BOTH_DEATH1: - case BOTH_DEATH2: - case BOTH_DEATH3: - case BOTH_DEATH4: - case BOTH_DEATH5: - case BOTH_DEATH6: - case BOTH_DEATH7: - - case BOTH_DEATH1IDLE: - case BOTH_LYINGDEATH1: - case BOTH_STUMBLEDEATH1: - case BOTH_FALLDEATH1: - case BOTH_FALLDEATH1INAIR: - case BOTH_FALLDEATH1LAND: - return qtrue; - break; - default: - return qfalse; - break; - } -} - static void PM_JumpForDir( void ) { int anim = BOTH_JUMP1; @@ -661,135 +492,12 @@ static void PM_JumpForDir( void ) anim = BOTH_JUMP1; pm->ps->pm_flags &= ~PMF_BACKWARDS_JUMP; } - if(!PM_InDeathAnim(pm->ps->legsAnim)) + if(!BG_InDeathAnim(pm->ps->legsAnim)) { PM_SetAnim(SETANIM_LEGS,anim,SETANIM_FLAG_OVERRIDE, 100); // Only blend over 100ms } } -qboolean PM_FlippingAnim( int anim ) -{ - switch ( anim ) - { - case BOTH_FLIP_F: //# Flip forward - case BOTH_FLIP_B: //# Flip backwards - case BOTH_FLIP_L: //# Flip left - case BOTH_FLIP_R: //# Flip right - case BOTH_WALL_RUN_RIGHT_FLIP: - case BOTH_WALL_RUN_LEFT_FLIP: - case BOTH_WALL_FLIP_RIGHT: - case BOTH_WALL_FLIP_LEFT: - case BOTH_FLIP_BACK1: - case BOTH_FLIP_BACK2: - case BOTH_FLIP_BACK3: - case BOTH_WALL_FLIP_BACK1: - //Not really flips, but... - case BOTH_WALL_RUN_RIGHT: - case BOTH_WALL_RUN_LEFT: - case BOTH_WALL_RUN_RIGHT_STOP: - case BOTH_WALL_RUN_LEFT_STOP: - case BOTH_BUTTERFLY_LEFT: - case BOTH_BUTTERFLY_RIGHT: - // - case BOTH_ARIAL_LEFT: - case BOTH_ARIAL_RIGHT: - case BOTH_ARIAL_F1: - case BOTH_CARTWHEEL_LEFT: - case BOTH_CARTWHEEL_RIGHT: - case BOTH_JUMPFLIPSLASHDOWN1: - case BOTH_JUMPFLIPSTABDOWN: - return qtrue; - break; - } - return qfalse; -} - -qboolean PM_SpinningSaberAnim( int anim ) -{ - switch ( anim ) - { - //level 1 - FIXME: level 1 will have *no* spins - case BOTH_T1_BR_BL: - case BOTH_T1__R__L: - case BOTH_T1__R_BL: - case BOTH_T1_TR_BL: - case BOTH_T1_BR_TL: - case BOTH_T1_BR__L: - case BOTH_T1_TL_BR: - case BOTH_T1__L_BR: - case BOTH_T1__L__R: - case BOTH_T1_BL_BR: - case BOTH_T1_BL__R: - case BOTH_T1_BL_TR: - //level 2 - case BOTH_T2_BR__L: - case BOTH_T2_BR_BL: - case BOTH_T2__R_BL: - case BOTH_T2__L_BR: - case BOTH_T2_BL_BR: - case BOTH_T2_BL__R: - //level 3 - case BOTH_T3_BR__L: - case BOTH_T3_BR_BL: - case BOTH_T3__R_BL: - case BOTH_T3__L_BR: - case BOTH_T3_BL_BR: - case BOTH_T3_BL__R: - //level 4 - case BOTH_T4_BR__L: - case BOTH_T4_BR_BL: - case BOTH_T4__R_BL: - case BOTH_T4__L_BR: - case BOTH_T4_BL_BR: - case BOTH_T4_BL__R: - //level 5 - case BOTH_T5_BR_BL: - case BOTH_T5__R__L: - case BOTH_T5__R_BL: - case BOTH_T5_TR_BL: - case BOTH_T5_BR_TL: - case BOTH_T5_BR__L: - case BOTH_T5_TL_BR: - case BOTH_T5__L_BR: - case BOTH_T5__L__R: - case BOTH_T5_BL_BR: - case BOTH_T5_BL__R: - case BOTH_T5_BL_TR: - //special - //case BOTH_A2_STABBACK1: - case BOTH_ATTACK_BACK: - case BOTH_CROUCHATTACKBACK1: - case BOTH_BUTTERFLY_LEFT: - case BOTH_BUTTERFLY_RIGHT: - case BOTH_FJSS_TR_BL: - case BOTH_FJSS_TL_BR: - case BOTH_JUMPFLIPSLASHDOWN1: - case BOTH_JUMPFLIPSTABDOWN: - return qtrue; - break; - } - return qfalse; -} - -qboolean PM_SpinningAnim( int anim ) -{ - /* - switch ( anim ) - { - //FIXME: list any other spinning anims - default: - break; - } - */ - return PM_SpinningSaberAnim( anim ); -} - -qboolean PM_SomeoneInFront(trace_t *tr); -qboolean PM_SaberInAttack( int move ); -float PM_GroundDistance(void); -saberMoveName_t PM_SaberFlipOverAttackMove(trace_t *tr); -saberMoveName_t PM_SaberJumpAttackMove( void ); - /* ============= PM_CheckJump @@ -813,7 +521,7 @@ static qboolean PM_CheckJump( void ) return qfalse; } - if ( PM_InKnockDown( pm->ps ) || PM_InRoll( pm->ps, pm->ps->legsAnim ) ) + if ( PM_InKnockDown( pm->ps ) || BG_InRoll( pm->ps, pm->ps->legsAnim ) ) {//in knockdown return qfalse; } @@ -1353,13 +1061,13 @@ static qboolean PM_CheckJump( void ) && pm->ps->weapon == WP_SABER && (pm->ps->weaponTime > 0||pm->cmd.buttons&BUTTON_ATTACK) ) {//okay, we just jumped and we're in an attack - if ( !PM_InRoll( pm->ps, pm->ps->legsAnim ) + if ( !BG_InRoll( pm->ps, pm->ps->legsAnim ) && !PM_InKnockDown( pm->ps ) - && !PM_InDeathAnim(pm->ps->legsAnim) - && !PM_FlippingAnim( pm->ps->legsAnim ) //SAFASFASF - && !PM_SpinningAnim( pm->ps->legsAnim ) //SDGSDGGDSG - && !PM_SaberInSpecialAttack( pm->ps->torsoAnim ) - && ( PM_SaberInAttack( pm->ps->saberMove ) ) + && !BG_InDeathAnim(pm->ps->legsAnim) + && !BG_FlippingAnim( pm->ps->legsAnim ) + && !PM_SpinningAnim( pm->ps->legsAnim ) + && !BG_SaberInSpecialAttack( pm->ps->torsoAnim ) + && ( BG_SaberInAttack( pm->ps->saberMove ) ) /*&& PM_InAnimForSaberMove( pm->ps->torsoAnim, pm->ps->saberMove )*/ ) {//not in an anim we shouldn't interrupt //see if it's not too late to start a special jump-attack @@ -1958,44 +1666,13 @@ static int PM_FootstepForSurface( void ) { return EV_FOOTSTEP; } -qboolean PM_SaberInSpecialAttack( int anim ) -{ - switch ( anim&~ANIM_TOGGLEBIT ) - { - case BOTH_A2_STABBACK1: - case BOTH_ATTACK_BACK: - case BOTH_CROUCHATTACKBACK1: - case BOTH_BUTTERFLY_LEFT: - case BOTH_BUTTERFLY_RIGHT: - case BOTH_FJSS_TR_BL: - case BOTH_FJSS_TL_BR: - case BOTH_LUNGE2_B__T_: - case BOTH_FORCELEAP2_T__B_: - case BOTH_JUMPFLIPSLASHDOWN1://# - case BOTH_JUMPFLIPSTABDOWN://# - return qtrue; - } - return qfalse; -} - -qboolean PM_SaberInStart( int move ) -{ - if ( move >= LS_S_TL2BR && move <= LS_S_T2B ) - { - return qtrue; - } - return qfalse; -} - -qboolean PM_SaberInAttack( int move ); - static int PM_TryRoll( void ) { trace_t trace; int anim = -1; vec3_t fwd, right, traceto, mins, maxs, fwdAngles; - if ( PM_SaberInAttack( pm->ps->saberMove ) || PM_SaberInSpecialAttack( pm->ps->torsoAnim ) + if ( BG_SaberInAttack( pm->ps->saberMove ) || BG_SaberInSpecialAttack( pm->ps->torsoAnim ) || BG_SpinningSaberAnim( pm->ps->legsAnim ) || (!pm->ps->clientNum&&PM_SaberInStart( pm->ps->saberMove )) ) {//attacking or spinning (or, if player, starting an attack) @@ -2058,68 +1735,6 @@ static int PM_TryRoll( void ) return 0; } -qboolean PM_InOnGroundAnim ( int anim ) -{ - switch( anim&~ANIM_TOGGLEBIT ) - { - case BOTH_DEAD1: - case BOTH_DEAD2: - case BOTH_DEAD3: - case BOTH_DEAD4: - case BOTH_DEAD5: - case BOTH_DEADFORWARD1: - case BOTH_DEADBACKWARD1: - case BOTH_DEADFORWARD2: - case BOTH_DEADBACKWARD2: - case BOTH_LYINGDEATH1: - case BOTH_LYINGDEAD1: - case BOTH_PAIN2WRITHE1: //# Transition from upright position to writhing on ground anim - case BOTH_WRITHING1: //# Lying on ground writhing in pain - case BOTH_WRITHING1RLEG: //# Lying on ground writhing in pain: holding right leg - case BOTH_WRITHING1LLEG: //# Lying on ground writhing in pain: holding left leg - case BOTH_WRITHING2: //# Lying on stomache writhing in pain - case BOTH_INJURED1: //# Lying down: against wall - can also be sleeping - case BOTH_CRAWLBACK1: //# Lying on back: crawling backwards with elbows - case BOTH_INJURED2: //# Injured pose 2 - case BOTH_INJURED3: //# Injured pose 3 - case BOTH_INJURED6: //# Injured pose 6 - case BOTH_INJURED6ATTACKSTART: //# Start attack while in injured 6 pose - case BOTH_INJURED6ATTACKSTOP: //# End attack while in injured 6 pose - case BOTH_INJURED6COMBADGE: //# Hit combadge while in injured 6 pose - case BOTH_INJURED6POINT: //# Chang points to door while in injured state - case BOTH_SLEEP1: //# laying on back-rknee up-rhand on torso - case BOTH_SLEEP2: //# on floor-back against wall-arms crossed - case BOTH_SLEEP5: //# Laying on side sleeping on flat sufrace - case BOTH_SLEEP_IDLE1: //# rub face and nose while asleep from sleep pose 1 - case BOTH_SLEEP_IDLE2: //# shift position while asleep - stays in sleep2 - case BOTH_SLEEP1_NOSE: //# Scratch nose from SLEEP1 pose - case BOTH_SLEEP2_SHIFT: //# Shift in sleep from SLEEP2 pose - case BOTH_KNOCKDOWN1: //# - case BOTH_KNOCKDOWN2: //# - return qtrue; - break; - } - - return qfalse; -} - -qboolean PM_InRollComplete( playerState_t *ps, int anim ) -{ - switch ( (anim&~ANIM_TOGGLEBIT) ) - { - case BOTH_ROLL_F: - case BOTH_ROLL_B: - case BOTH_ROLL_R: - case BOTH_ROLL_L: - if ( ps->legsTimer < 1 ) - { - return qtrue; - } - break; - } - return qfalse; -} - /* ================= PM_CrashLand @@ -2160,9 +1775,9 @@ static void PM_CrashLand( void ) { } // decide which landing animation to use - if (!PM_InRoll(pm->ps, pm->ps->legsAnim) && pm->ps->inAirAnim) + if (!BG_InRoll(pm->ps, pm->ps->legsAnim) && pm->ps->inAirAnim) { //only play a land animation if we transitioned into an in-air animation while off the ground - if (!PM_SaberInSpecial(pm->ps->saberMove)) + if (!BG_SaberInSpecial(pm->ps->saberMove)) { if ( pm->ps->pm_flags & PMF_BACKWARDS_JUMP ) { PM_ForceLegsAnim( BOTH_LANDBACK1 ); @@ -2183,9 +1798,9 @@ static void PM_CrashLand( void ) { (pm->ps->legsAnim&~ANIM_TOGGLEBIT) == BOTH_WALL_RUN_LEFT || (pm->ps->legsAnim&~ANIM_TOGGLEBIT) == BOTH_WALL_RUN_RIGHT) { - if (!PM_InRoll(pm->ps, pm->ps->legsAnim) && pm->ps->inAirAnim) + if (!BG_InRoll(pm->ps, pm->ps->legsAnim) && pm->ps->inAirAnim) { - if (!PM_SaberInSpecial(pm->ps->saberMove) || pm->ps->weapon != WP_SABER) + if (!BG_SaberInSpecial(pm->ps->saberMove) || pm->ps->weapon != WP_SABER) { pm->ps->legsTimer = TIMER_LAND; } @@ -2213,7 +1828,7 @@ static void PM_CrashLand( void ) { if ( pm->ps->pm_flags & PMF_DUCKED ) { - if( delta >= 2 && !PM_InOnGroundAnim( pm->ps->legsAnim ) && !PM_InKnockDown( pm->ps ) && !PM_InRoll(pm->ps, pm->ps->legsAnim) ) + if( delta >= 2 && !PM_InOnGroundAnim( pm->ps->legsAnim ) && !PM_InKnockDown( pm->ps ) && !BG_InRoll(pm->ps, pm->ps->legsAnim) ) {//roll! int anim = PM_TryRoll(); @@ -2625,7 +2240,7 @@ static void PM_CheckDuck (void) } } - if (PM_InRoll(pm->ps, pm->ps->legsAnim)) + if (BG_InRoll(pm->ps, pm->ps->legsAnim)) { pm->maxs[2] = CROUCH_MAXS_2; pm->ps->viewheight = DEFAULT_VIEWHEIGHT; @@ -2797,7 +2412,7 @@ static void PM_Footsteps( void ) { bobmove = 0.5; // ducked characters bob much faster - if ( PM_RunningAnim( pm->ps->legsAnim ) && !PM_InRoll(pm->ps, pm->ps->legsAnim) ) + if ( PM_RunningAnim( pm->ps->legsAnim ) && !BG_InRoll(pm->ps, pm->ps->legsAnim) ) {//roll! rolled = PM_TryRoll(); } @@ -2877,7 +2492,6 @@ static void PM_Footsteps( void ) { PM_AddEvent( EV_SWIM ); } else if ( pm->waterlevel == 3 ) { // no sound when completely underwater - } } } @@ -3131,7 +2745,6 @@ static qboolean PM_DoChargedWeapons( void ) #ifdef _DEBUG Com_Printf("Starting charge\n"); #endif -// G_SoundOnEnt( pm->gent, CHAN_WEAPON, weaponData[pm->ps->weapon].altChargeSnd ); assert(pm->ps->weapon > WP_NONE); BG_AddPredictableEventToPlayerstate(EV_WEAPON_CHARGE_ALT, pm->ps->weapon, pm->ps); } @@ -3163,8 +2776,6 @@ static qboolean PM_DoChargedWeapons( void ) #ifdef _DEBUG Com_Printf("Starting charge\n"); #endif - -// G_SoundOnEnt( pm->gent, CHAN_WEAPON, weaponData[pm->ps->weapon].chargeSnd ); BG_AddPredictableEventToPlayerstate(EV_WEAPON_CHARGE, pm->ps->weapon, pm->ps); } @@ -3219,101 +2830,6 @@ rest: #define BOWCASTER_CHARGE_UNIT 200.0f // bowcaster charging gives us one more unit every 200ms--if you change this, you'll have to do the same in g_weapon #define BRYAR_CHARGE_UNIT 200.0f // bryar charging gives us one more unit every 200ms--if you change this, you'll have to do the same in g_weapon -// Specific weapons can opt to modify the ammo usage based on charges, otherwise if no special case code -// is handled below, regular ammo usage will happen -//--------------------------------------- -static void PM_DoChargingAmmoUsage( int *amount ) -//--------------------------------------- -{ -// NOTENOTE No charging weapons yet. -/* - int count; - - if ( pm->ps->weapon == WP_BOWCASTER && pm->cmd.buttons & BUTTON_ALT_ATTACK ) - { - // this code is duplicated ( I know, I know ) in G_weapon.cpp for the bowcaster alt-fire - count = ( pm->cmd.serverTime - pm->ps->weaponChargeTime ) / BOWCASTER_CHARGE_UNIT; - - if ( count < 1 ) - { - count = 1; - } - else if ( count > 5 ) - { - count = 5; - } - - if ( !(count & 1 )) - { - // if we aren't odd, knock us down a level - count--; - } - - // Only bother with these checks if we don't have infinite ammo - if ( pm->ps->ammo[ weaponData[pm->ps->weapon].ammoIndex ] != -1 ) - { - int dif = pm->ps->ammo[weaponData[pm->ps->weapon].ammoIndex] - *amount * count; - - // If we have enough ammo to do the full charged shot, we are ok - if ( dif < 0 ) - { - // we are not ok, so hack our chargetime and ammo usage, note that DIF is going to be negative - count += floor(dif / (float)*amount); - - if ( count < 1 ) - { - count = 1; - } - - // now get a real chargeTime so the duplicated code in g_weapon doesn't get freaked - pm->ps->weaponChargeTime = pm->cmd.serverTime - ( count * BOWCASTER_CHARGE_UNIT ); - } - } - - // now that count is cool, get the real ammo usage - *amount *= count; - } - else if ( pm->ps->weapon == WP_BRYAR_PISTOL && pm->cmd.buttons & BUTTON_ALT_ATTACK ) - { - // this code is duplicated ( I know, I know ) in G_weapon.cpp for the bryar alt-fire - count = ( pm->cmd.serverTime - pm->ps->weaponChargeTime ) / BRYAR_CHARGE_UNIT; - - if ( count < 1 ) - { - count = 1; - } - else if ( count > 5 ) - { - count = 5; - } - - // Only bother with these checks if we don't have infinite ammo - if ( pm->ps->ammo[ weaponData[pm->ps->weapon].ammoIndex ] != -1 ) - { - int dif = pm->ps->ammo[weaponData[pm->ps->weapon].ammoIndex] - *amount * count; - - // If we have enough ammo to do the full charged shot, we are ok - if ( dif < 0 ) - { - // we are not ok, so hack our chargetime and ammo usage, note that DIF is going to be negative - count += floor(dif / (float)*amount); - - if ( count < 1 ) - { - count = 1; - } - - // now get a real chargeTime so the duplicated code in g_weapon doesn't get freaked - pm->ps->weaponChargeTime = pm->cmd.serverTime - ( count * BRYAR_CHARGE_UNIT ); - } - } - - // now that count is cool, get the real ammo usage - *amount *= count; - } - */ -} - int PM_ItemUsable(playerState_t *ps, int forcedUse) { vec3_t fwd, fwdorg, dest, pos; @@ -3344,6 +2860,11 @@ int PM_ItemUsable(playerState_t *ps, int forcedUse) { return 0; } + if (ps->stats[STAT_HEALTH] <= 0 || + (ps->eFlags & EF_DEAD)) + { + return 0; + } return 1; case HI_SEEKER: @@ -3513,7 +3034,7 @@ static void PM_Weapon( void ) { desiredAnim = BOTH_FORCEPULL; break; case HANDEXTEND_FORCEGRIP: - desiredAnim = TORSO_FORCEGRIP1; + desiredAnim = BOTH_FORCEGRIP_HOLD; break; case HANDEXTEND_SABERPULL: desiredAnim = BOTH_SABERPULL; @@ -3531,6 +3052,10 @@ static void PM_Weapon( void ) { { desiredAnim = BOTH_FORCE_GETUP_B1; } + else if (pm->ps->forceDodgeAnim == 3) + { + desiredAnim = BOTH_FORCE_GETUP_B3; + } else { desiredAnim = BOTH_GETUP1; @@ -3542,7 +3067,7 @@ static void PM_Weapon( void ) { } break; case HANDEXTEND_DUELCHALLENGE: - desiredAnim = BOTH_FORCEGRIP3; + desiredAnim = BOTH_ENGAGETAUNT; break; case HANDEXTEND_TAUNT: desiredAnim = pm->ps->forceDodgeAnim; @@ -3566,7 +3091,7 @@ static void PM_Weapon( void ) { } if (BG_InSpecialJump(pm->ps->legsAnim) || - PM_InRoll(pm->ps, pm->ps->legsAnim) || + BG_InRoll(pm->ps, pm->ps->legsAnim) || PM_InRollComplete(pm->ps, pm->ps->legsAnim)) { pm->cmd.weapon = WP_SABER; @@ -3591,8 +3116,8 @@ static void PM_Weapon( void ) { pm->cmd.weapon = WP_SABER; //don't allow switching out mid-attack } - if (pm->ps->weapon == WP_SABER /* && !cg.zoomMode */) // WP_LIGHTSABER - { // Separate logic for lightsaber, but not when zoomed + if (pm->ps->weapon == WP_SABER) + { //rww - we still need the item stuff, so we won't return immediately PM_WeaponLightsaber(); killAfterItem = 1; @@ -3627,9 +3152,6 @@ static void PM_Weapon( void ) { return; } -//if(0) // if ( bg_itemlist[pm->ps->stats[STAT_HOLDABLE_ITEM]].giTag == HI_MEDKIT -//{ // && pm->ps->stats[STAT_HEALTH] >= (pm->ps->stats[STAT_MAX_HEALTH] + 25) ) { - // don't use medkit if at max health if (!PM_ItemUsable(pm->ps, 0)) { pm->ps->pm_flags |= PMF_USE_ITEM_HELD; @@ -3731,6 +3253,17 @@ static void PM_Weapon( void ) { } return; } + + if (pm->ps->weapon == WP_DET_PACK && !pm->ps->hasDetPackPlanted && pm->ps->ammo[weaponData[pm->ps->weapon].ammoIndex] < 1) + { + PM_AddEventWithParm( EV_NOAMMO, WP_NUM_WEAPONS+pm->ps->weapon ); + + if (pm->ps->weaponTime < 500) + { + pm->ps->weaponTime += 500; + } + return; + } } } @@ -3756,7 +3289,7 @@ static void PM_Weapon( void ) { if ( pm->ps->weaponstate == WEAPON_RAISING ) { pm->ps->weaponstate = WEAPON_READY; if ( pm->ps->weapon == WP_SABER ) { - PM_StartTorsoAnim( BOTH_STAND2 ); + PM_StartTorsoAnim( PM_GetSaberStance() ); } else { if (pm->ps->weapon == WP_DISRUPTOR && pm->ps->zoomMode == 1) { @@ -3934,9 +3467,9 @@ static void PM_Animate( void ) { pm->ps->forceHandExtend = HANDEXTEND_TAUNT; //FIXME: random taunt anims? - pm->ps->forceDodgeAnim = BOTH_TALKGESTURE3; + pm->ps->forceDodgeAnim = BOTH_ENGAGETAUNT; - pm->ps->forceHandExtendTime = pm->cmd.serverTime + 2000; + pm->ps->forceHandExtendTime = pm->cmd.serverTime + 1000; PM_AddEvent( EV_TAUNT ); } @@ -4065,16 +3598,6 @@ void PM_AdjustAttackStates( pmove_t *pm ) amount = pm->ps->ammo[weaponData[ pm->ps->weapon ].ammoIndex] - weaponData[pm->ps->weapon].energyPerShot; } - /*if ( pm->ps->weapon == WP_SABER && !pm->ps->zoomMode) - { - //saber alt-attack does a normal swing, too - pm->cmd.buttons &= ~BUTTON_ALT_ATTACK; - if ( pm->ps->saberInFlight ) - {//saber not in hand, can't swing it - pm->cmd.buttons &= ~BUTTON_ATTACK; - } - }*/ - // disruptor alt-fire should toggle the zoom mode, but only bother doing this for the player? if ( pm->ps->weapon == WP_DISRUPTOR) { @@ -4121,6 +3644,12 @@ void PM_AdjustAttackStates( pmove_t *pm ) pm->ps->zoomLocked = qtrue; } } + else if (!(pm->ps->eFlags & EF_ALT_FIRING) && (pm->cmd.buttons & BUTTON_ALT_ATTACK) && + (pm->cmd.upmove > 0 || pm->cmd.forwardmove || pm->cmd.rightmove)) + { //if you try to zoom while moving, just convert it into a primary attack + pm->cmd.buttons &= ~BUTTON_ALT_ATTACK; + pm->cmd.buttons |= BUTTON_ATTACK; + } if (pm->cmd.upmove > 0 || pm->cmd.forwardmove || pm->cmd.rightmove) { @@ -4135,10 +3664,6 @@ void PM_AdjustAttackStates( pmove_t *pm ) if ( pm->cmd.buttons & BUTTON_ATTACK ) { - if ( pm->ps->weapon == WP_DISRUPTOR && pm->ps->zoomTime+1500 > pm->cmd.serverTime) - { //make it so we can't fire in zoomed mode until we've been zoomed for a moment - pm->cmd.buttons &= ~BUTTON_ATTACK; - } // If we are zoomed, we should switch the ammo usage to the alt-fire, otherwise, we'll // just use whatever ammo was selected from above if ( pm->ps->zoomMode ) @@ -4303,7 +3828,8 @@ void BG_AdjustClientSpeed(playerState_t *ps, usercmd_t *cmd, int svTime) else if ((svTime - ps->holdMoveTime) < 1700) { ps->speed *= 0.7; - } else if ((svTime - ps->holdMoveTime) < 1900) + } + else if ((svTime - ps->holdMoveTime) < 1900) { ps->speed *= 0.8; } @@ -4318,7 +3844,6 @@ void BG_AdjustClientSpeed(playerState_t *ps, usercmd_t *cmd, int svTime) { ps->torsoAnim = ( ( ps->torsoAnim & ANIM_TOGGLEBIT ) ^ ANIM_TOGGLEBIT ) | BOTH_RUN1; - //ps->speed *= 0.8; } } @@ -4361,7 +3886,7 @@ void BG_AdjustClientSpeed(playerState_t *ps, usercmd_t *cmd, int svTime) } } - if ( PM_SaberInAttack( ps->saberMove ) && cmd->forwardmove < 0 ) + if ( BG_SaberInAttack( ps->saberMove ) && cmd->forwardmove < 0 ) {//if running backwards while attacking, don't run as fast. switch( ps->fd.saberAnimLevel ) { @@ -4382,7 +3907,7 @@ void BG_AdjustClientSpeed(playerState_t *ps, usercmd_t *cmd, int svTime) { ps->speed *= 0.5f; } - else if ( ps->weapon == WP_SABER && PM_SaberInAttack( ps->saberMove ) ) + else if ( ps->weapon == WP_SABER && BG_SaberInAttack( ps->saberMove ) ) {//if attacking with saber while running, drop your speed switch( ps->fd.saberAnimLevel ) { @@ -4398,7 +3923,7 @@ void BG_AdjustClientSpeed(playerState_t *ps, usercmd_t *cmd, int svTime) } - if ( PM_InRoll( ps, ps->legsAnim ) && ps->speed > 200 ) + if ( BG_InRoll( ps, ps->legsAnim ) && ps->speed > 200 ) { //can't roll unless you're able to move normally BG_CmdForRoll( ps->legsAnim, cmd ); ps->speed = ps->legsTimer/1.5;//450; @@ -4524,13 +4049,6 @@ void PmoveSingle (pmove_t *pmove) { pm->cmd.buttons &= ~BUTTON_WALKING; } - // set the talk balloon flag -// if ( pm->cmd.buttons & BUTTON_TALK ) { -// pm->ps->eFlags |= EF_TALK; -// } else { -// pm->ps->eFlags &= ~EF_TALK; -// } - // In certain situations, we may want to control which attack buttons are pressed and what kind of functionality // is attached to them PM_AdjustAttackStates( pm ); @@ -4541,18 +4059,6 @@ void PmoveSingle (pmove_t *pmove) { pm->ps->pm_flags &= ~PMF_RESPAWNED; } - // if talk button is down, dissallow all other input - // this is to prevent any possible intercept proxy from - // adding fake talk balloons -// if ( pmove->cmd.buttons & BUTTON_TALK ) { - // keep the talk button set tho for when the cmd.serverTime > 66 msec - // and the same cmd is used multiple times in Pmove -// pmove->cmd.buttons = BUTTON_TALK; -// pmove->cmd.forwardmove = 0; -// pmove->cmd.rightmove = 0; -// pmove->cmd.upmove = 0; -// } - // clear all pmove local vars memset (&pml, 0, sizeof(pml)); @@ -4583,12 +4089,6 @@ void PmoveSingle (pmove_t *pmove) { pm->ps->pm_flags &= ~PMF_JUMP_HELD; } -// if (pm->ps->groundEntityNum == ENTITYNUM_NONE || pml.groundTrace.fraction == 1) -// { //No holding jump in air to jump upon land -// pm->cmd.upmove = 0; -// pm->ps->pm_flags |= PMF_JUMP_HELD; -// } - // decide if backpedaling animations should be used if ( pm->cmd.forwardmove < 0 ) { pm->ps->pm_flags |= PMF_BACKWARDS_RUN; @@ -4696,10 +4196,6 @@ void PmoveSingle (pmove_t *pmove) { // PM_UpdateGhoul2AnimFromState(); } - // torso animation -// rww - This didn't seem to do anything at all.. -// PM_TorsoAnimation(); - // footstep events / legs animations PM_Footsteps(); diff --git a/CODEmp/game/bg_public.h b/CODE-mp/game/bg_public.h similarity index 94% rename from CODEmp/game/bg_public.h rename to CODE-mp/game/bg_public.h index 3eba615..5e84952 100644 --- a/CODEmp/game/bg_public.h +++ b/CODE-mp/game/bg_public.h @@ -18,6 +18,8 @@ #define ARMOR_PROTECTION 0.50 // Shields only stop 50% of armor-piercing dmg #define ARMOR_REDUCTION_FACTOR 0.50 // Certain damage doesn't take off armor as efficiently +#define JUMP_VELOCITY 225//270 + #define MAX_ITEMS 256 #define RANK_TIED_FLAG 0x4000 @@ -352,6 +354,7 @@ typedef enum { #define EF_SOUNDTRACKER 0x00800000 // sound position needs to be updated in relation to another entity #define EF_DROPPEDWEAPON 0x01000000 // it's a dropped weapon #define EF_DISINTEGRATION 0x02000000 // being disintegrated by the disruptor +#define EF_INVULNERABLE 0x04000000 // just spawned in or whatever, so is protected @@ -955,9 +958,20 @@ typedef struct extern saberMoveData_t saberMoveData[LS_MOVE_MAX]; +//BG anim utility functions: qboolean BG_InSpecialJump( int anim ); +qboolean BG_InSaberStandAnim( int anim ); +qboolean BG_DirectFlippingAnim( int anim ); +qboolean BG_SaberInAttack( int move ); +qboolean BG_SaberInSpecial( int move ); +qboolean BG_SaberInIdle( int move ); qboolean BG_FlippingAnim( int anim ); qboolean BG_SpinningSaberAnim( int anim ); +qboolean BG_SaberInSpecialAttack( int anim ); +qboolean BG_InRoll( playerState_t *ps, int anim ); +qboolean BG_InDeathAnim( int anim ); + +void BG_SaberStartTransAnim( int saberAnimLevel, int anim, float *animSpeed ); void BG_EvaluateTrajectory( const trajectory_t *tr, int atTime, vec3_t result ); void BG_EvaluateTrajectoryDelta( const trajectory_t *tr, int atTime, vec3_t result ); diff --git a/CODEmp/game/bg_saber.c b/CODE-mp/game/bg_saber.c similarity index 84% rename from CODEmp/game/bg_saber.c rename to CODE-mp/game/bg_saber.c index 01b60cb..ec258db 100644 --- a/CODEmp/game/bg_saber.c +++ b/CODE-mp/game/bg_saber.c @@ -278,7 +278,7 @@ saberMoveName_t PM_AttackMoveForQuad( int quad ) int PM_SaberAnimTransitionAnim( int curmove, int newmove ) { - //FIXME: take FP_SABER_OFFENSE into account here somehow? + //FIXME: take FP_SABERATTACK into account here somehow? int retmove = newmove; if ( curmove == LS_READY ) {//just standing there @@ -620,11 +620,6 @@ void PM_SaberLockBreak( playerState_t *genemy, qboolean victory ) { BG_AddPredictableEventToPlayerstate(EV_JUMP, PM_irand_timesync( 0, 75 ), genemy); } - else - { - //G_AddVoiceEvent( genemy, Q_irand( EV_PUSHED1, EV_PUSHED3 ), 500 ); - } - //FIXME: possibly knock saber out of hand? } } @@ -743,13 +738,6 @@ void PM_SaberLocked( void ) } } } - else - {//FIXME: other ways out of a saberlock? - //force-push? (requires more force power?) - //kick? (requires anim ... hit jump key?) - //roll? - //backflip? - } } else {//something broke us out of it @@ -863,7 +851,6 @@ saberMoveName_t PM_SaberFlipOverAttackMove(trace_t *tr) } pm->ps->fd.forceJumpZStart = pm->ps->origin[2];//so we don't take damage if we land at same height - //pm->ps->pm_flags |= PMF_JUMPING; PM_AddEvent( EV_JUMP ); pm->ps->fd.forceJumpSound = 1; @@ -1077,7 +1064,6 @@ void PM_WeaponLightsaber(void) { int addTime,amount; qboolean delayed_fire = qfalse; -// weaponInfo_t *weapon; int anim=-1, curmove, newmove=LS_NONE; qboolean saberInAir = qtrue; @@ -1138,7 +1124,7 @@ void PM_WeaponLightsaber(void) PM_SetAnim(SETANIM_TORSO,(pm->ps->legsAnim & ~ANIM_TOGGLEBIT),SETANIM_FLAG_OVERRIDE, 100); } - if ((pm->ps->torsoAnim & ~ANIM_TOGGLEBIT) == BOTH_STAND2) + if (BG_InSaberStandAnim(pm->ps->torsoAnim)) { PM_SetAnim(SETANIM_TORSO,BOTH_STAND1,SETANIM_FLAG_OVERRIDE, 100); } @@ -1185,20 +1171,6 @@ void PM_WeaponLightsaber(void) return; } - // NOTENOTE Still have to ferret out the difference between this and the weaponTime - /* - if(pm->gent && pm->gent->client && pm->gent->client->fireDelay > 0) - {//FIXME: this is going to fire off one frame before you expect, actually - pm->gent->client->fireDelay -= pml.msec; - if(pm->gent->client->fireDelay <= 0) - {//just finished delay timer - pm->gent->client->fireDelay = 0; - delayed_fire = qtrue; - } - } - */ - - // don't allow attack until all buttons are up if ( pm->ps->pm_flags & PMF_RESPAWNED ) { return; @@ -1206,15 +1178,6 @@ void PM_WeaponLightsaber(void) // check for dead player if ( pm->ps->stats[STAT_HEALTH] <= 0 ) { -// pm->ps->weapon = WP_NONE; - - // NOTENOTE Loopsound must be controlled, but not this way. - /* - if ( pm->gent ) - { - pm->gent->s.loopSound = 0; - } - */ return; } @@ -1245,10 +1208,6 @@ void PM_WeaponLightsaber(void) PM_SetAnim(SETANIM_TORSO,saberMoveData[pm->ps->saberMove].animToUse,saberMoveData[pm->ps->saberMove].animSetFlags|SETANIM_FLAG_HOLD, saberMoveData[pm->ps->saberMove].blendTime); return; } - else if (pm->ps->saberBlocked) - { - //return; - } } else { @@ -1260,21 +1219,11 @@ void PM_WeaponLightsaber(void) { int firstSet = 0; - /* - if ( pm->ps->saberMove > LS_PUTAWAY && pm->ps->saberMove <= LS_A_BL2TR && - (pm->ps->saberBlocked < BLOCKED_UPPER_RIGHT_PROJ || pm->ps->saberBlocked > BLOCKED_TOP_PROJ))//&& Q_irand( 0, 2 ) - {//we parried another lightsaber while attacking, so treat it as a bounce - pm->ps->saberBlocked = BLOCKED_ATK_BOUNCE; - } - */ - if (!pm->ps->weaponTime) { firstSet = 1; } - // pm->ps->weaponTime = 0;//SABER_BLOCK_DUR; - switch ( pm->ps->saberBlocked ) { case BLOCKED_PARRY_BROKEN: @@ -1303,14 +1252,6 @@ void PM_WeaponLightsaber(void) case BLOCKED_ATK_BOUNCE: // If there is absolutely no blocked move in the chart, don't even mess with the animation. // OR if we are already in a block or parry. - -/* - if ( !pm->ps->clientNum ) - { - G_DynaMixEvent( DM_BOUNCE ); - } -*/ - if (pm->ps->saberMove >= LS_T1_BR__R/*LS_BOUNCE_TOP*/ )//|| saberMoveData[pm->ps->saberMove].bounceMove == LS_NONE ) {//an actual bounce? Other bounces before this are actually transitions? pm->ps->saberBlocked = BLOCKED_NONE; @@ -1395,8 +1336,6 @@ void PM_WeaponLightsaber(void) if (firstSet) { - // PM_SetAnim(SETANIM_TORSO,saberMoveData[pm->ps->saberMove].animToUse,saberMoveData[pm->ps->saberMove].animSetFlags|SETANIM_FLAG_HOLD, saberMoveData[pm->ps->saberMove].blendTime); - // pm->ps->torsoAnim = saberMoveData[pm->ps->saberMove].animToUse; return; } @@ -1452,7 +1391,7 @@ weapChecks: } else { - PM_SetAnim(SETANIM_TORSO,BOTH_STAND2,SETANIM_FLAG_NORMAL, 100); + PM_SetAnim(SETANIM_TORSO,PM_GetSaberStance(),SETANIM_FLAG_NORMAL, 100); } if (pm->ps->weaponstate == WEAPON_RAISING) @@ -1472,7 +1411,6 @@ weapChecks: // ********************************************************* // NOTENOTE This is simply a client-side struct. Anything that is needed client and server should be moved to bg_weapon. -// weapon = &cg_weapons[pm->ps->weapon]; if(!delayed_fire) { @@ -1488,12 +1426,6 @@ weapChecks: // check for fire if ( !(pm->cmd.buttons & (BUTTON_ATTACK/*|BUTTON_ALT_ATTACK*/)) ) { - // pm->ps->weaponTime = 0; - - // NOTENOTE There is no fireDelay maintained as of yet. - /* - if ( pm->gent && pm->gent->client && pm->gent->client->fireDelay > 0 ) - */ if (pm->ps->weaponTime != 0) {//Still firing pm->ps->weaponstate = WEAPON_FIRING; @@ -1503,11 +1435,7 @@ weapChecks: pm->ps->weaponstate = WEAPON_IDLE; } //Check for finishing an anim if necc. - /*if (!pm->ps->weaponTime) - { - return; - } - else */if ( curmove >= LS_S_TL2BR && curmove <= LS_S_T2B ) + if ( curmove >= LS_S_TL2BR && curmove <= LS_S_T2B ) {//started a swing, must continue from here newmove = LS_A_TL2BR + (curmove-LS_S_TL2BR); } @@ -1515,12 +1443,6 @@ weapChecks: {//finished an attack, must continue from here newmove = LS_R_TL2BR + (curmove-LS_A_TL2BR); } - /* - else if ( curmove >= LS_T1_BR__R && curmove <= LS_T1_BL__L ) - {//in a transition, must play sequential attack - newmove = saberMoveData[curmove].chain_attack; - } - */ else if ( PM_SaberInTransition( curmove ) ) {//in a transition, must play sequential attack newmove = saberMoveData[curmove].chain_attack; @@ -1541,26 +1463,6 @@ weapChecks: saberInAir = qtrue; - // NOTENOTE Currently there is no support for sabers in flight. - /* - if ( pm->ps->saberInFlight ) - {//guiding saber - if ( pm->ps->saberEntityNum < ENTITYNUM_NONE && pm->ps->saberEntityNum > 0 )//player is 0 - {// - if ( &g_entities[pm->ps->saberEntityNum] != NULL && g_entities[pm->ps->saberEntityNum].s.pos.trType == TR_STATIONARY ) - {//fell to the ground and we're not trying to pull it back - saberInAir = qfalse; - } - } - } - - if ( pm->ps->weapon == WP_SABER && pm->ps->saberInFlight && saberInAir ) - {//guiding saber - PM_SetAnim(SETANIM_TORSO,BOTH_SABERPULL,SETANIM_FLAG_OVERRIDE|SETANIM_FLAG_HOLD, 100); - } - else - */ - if ( pm->ps->weaponTime > 0 ) { // Last attack is not yet complete. pm->ps->weaponstate = WEAPON_FIRING; @@ -1595,15 +1497,7 @@ weapChecks: if ( newmove != LS_NONE ) {//have a valid, final LS_ move picked, so skip findingt he transition move and just get the anim - - // NOTENOTE Had to remove this concept since there is no gent in pmove. - /* - if (PM_HasAnimation( pm->gent, saberMoveData[newmove].animToUse)) - */ - if (1) - { - anim = saberMoveData[newmove].animToUse; - } + anim = saberMoveData[newmove].animToUse; } //FIXME: diagonal dirs use the figure-eight attacks from ready pose? @@ -1659,21 +1553,9 @@ weapChecks: {//not side-stepping, pick neutral anim // Add randomness for prototype? newmove = saberMoveData[curmove].chain_attack; - // NOTENOTE Had to remove this concept since there is no gent in pmove. - /* - if (PM_HasAnimation( pm->gent, saberMoveData[newmove].animToUse)) - */ - if (1) - { - anim= saberMoveData[newmove].animToUse; - } -/* - anim = PM_PickAnim( pm->gent, BOTH_MELEE3, BOTH_MELEE4 ); - if ( anim == -1 ) - { - anim = PM_PickAnim( pm->gent, BOTH_MELEE1, BOTH_MELEE2 ); - } -*/ + + anim= saberMoveData[newmove].animToUse; + if ( !pm->cmd.forwardmove && !pm->cmd.rightmove && pm->cmd.upmove >= 0 && pm->ps->groundEntityNum != ENTITYNUM_NONE ) {//not moving at all, so set the anim on entire body both = qtrue; @@ -1697,8 +1579,7 @@ weapChecks: } else { - //FIXME: play both_stand2_random1 when you've been idle for a while - anim = BOTH_STAND2; + anim = PM_GetSaberStance(); } newmove = LS_READY; } @@ -1715,25 +1596,8 @@ weapChecks: PM_SetAnim(SETANIM_LEGS,anim,SETANIM_FLAG_OVERRIDE|SETANIM_FLAG_HOLD, 100); } - // NOTENOTE Had to remove this concept since there is no gent in pmove. - /* - if ( pm->gent && pm->gent->client ) - { -// pm->gent->client->saberTrail.inAction = qtrue; -// pm->gent->client->saberTrail.duration = 75; // saber trail lasts for 75ms...feel free to change this if you want it longer or shorter - } - */ - //don't fire again until anim is done pm->ps->weaponTime = pm->ps->torsoTimer; - - /* - //FIXME: this may be making it so sometimes you can't swing again right away... - if ( newmove == LS_READY ) - { - pm->ps->weaponTime = 500; - } - */ } } @@ -1743,116 +1607,18 @@ weapChecks: pm->ps->weaponstate = WEAPON_FIRING; -// if ( pm->cmd.buttons & BUTTON_ALT_ATTACK ) -// amount = weaponData[pm->ps->weapon].altEnergyPerShot; -// else - amount = weaponData[pm->ps->weapon].energyPerShot; - - // NOTENOTE Silly usage of gents everywhere!!! Must... deal... with... them... - /* - if ( pm->gent && pm->gent->client && pm->gent->client->fireDelay > 0 ) - */ - if (0) - {//FIXME: this is going to fire off one frame before you expect, actually - // Clear these out since we're not actually firing yet - pm->ps->eFlags &= ~EF_FIRING; - pm->ps->eFlags &= ~EF_ALT_FIRING; - return; - } + amount = weaponData[pm->ps->weapon].energyPerShot; addTime = pm->ps->weaponTime; - /* - if ( pm->cmd.buttons & BUTTON_ALT_ATTACK ) { - pm->ps->saberAttackSequence = pm->ps->torsoAnim; - if ( !addTime ) - { - addTime = weaponData[pm->ps->weapon].altFireTime; - } + pm->ps->saberAttackSequence = pm->ps->torsoAnim; + if ( !addTime ) + { + addTime = weaponData[pm->ps->weapon].fireTime; } - else {*/ - pm->ps->saberAttackSequence = pm->ps->torsoAnim; - if ( !addTime ) - { - addTime = weaponData[pm->ps->weapon].fireTime; - } - //} - - //pm->ps->weaponTime += addTime; pm->ps->weaponTime = addTime; } -qboolean PM_SaberInAttack( int move ) -{ - if ( move >= LS_A_TL2BR && move <= LS_A_T2B ) - { - return qtrue; - } - switch ( move ) - { - case LS_A_BACK: - case LS_A_BACK_CR: - case LS_A_BACKSTAB: - case LS_A_LUNGE: - case LS_A_JUMP_T__B_: - case LS_A_FLIP_STAB: - case LS_A_FLIP_SLASH: - return qtrue; - break; - } - return qfalse; -} - -qboolean PM_SaberInSpecial( int move ) -{ - switch( move ) - { - case LS_A_BACK: - case LS_A_BACK_CR: - case LS_A_BACKSTAB: - case LS_A_LUNGE: - case LS_A_JUMP_T__B_: - case LS_A_FLIP_STAB: - case LS_A_FLIP_SLASH: - return qtrue; - } - return qfalse; -} - -qboolean PM_SaberInIdle( int move ) -{ - switch ( move ) - { - case LS_NONE: - case LS_READY: - case LS_DRAW: - case LS_PUTAWAY: - return qtrue; - break; - } - return qfalse; -} - -qboolean PM_SaberInParry( int move ) -{ - if ( move >= LS_PARRY_UP && move <= LS_PARRY_LL ) - { - return qtrue; - } - return qfalse; -} - -qboolean PM_SaberInReflect( int move ) -{ - if ( move >= LS_REFLECT_UP && move <= LS_REFLECT_LL ) - { - return qtrue; - } - return qfalse; -} - -qboolean PM_SaberInSpecialAttack( int anim ); - void PM_SetSaberMove(short newMove) { unsigned int setflags = saberMoveData[newMove].animSetFlags; @@ -1863,13 +1629,13 @@ void PM_SetSaberMove(short newMove) {//finished with a kata, reset attack counter pm->ps->saberAttackChainCount = 0; } - else if ( PM_SaberInAttack( newMove ) ) + else if ( BG_SaberInAttack( newMove ) ) {//continuing with a kata, increment attack counter pm->ps->saberAttackChainCount++; } if ( pm->ps->fd.saberAnimLevel > FORCE_LEVEL_1 && - !PM_SaberInIdle( newMove ) && !PM_SaberInParry( newMove ) && !PM_SaberInReflect( newMove ) && !PM_SaberInSpecial(newMove)) + !BG_SaberInIdle( newMove ) && !PM_SaberInParry( newMove ) && !PM_SaberInReflect( newMove ) && !BG_SaberInSpecial(newMove)) {//readies, parries and reflections have only 1 level //increment the anim to the next level of saber anims if ( !PM_SaberInTransition( newMove ) ) @@ -1887,49 +1653,24 @@ void PM_SetSaberMove(short newMove) //saber torso anims should always be highest priority setflags |= SETANIM_FLAG_OVERRIDE; - // NOTENOTE Had to remove this concept since there is no gent in pmove. - /* - if ( cg_debugAnim.integer > 0 && pm->gent ) + if ( BG_InSaberStandAnim(anim) || anim == BOTH_STAND1 ) { - if ( !PM_HasAnimation( pm->gent, anim ) ) - { - Com_Printf( S_COLOR_RED"ERROR: No saber anim %s!\n", animTable[anim].name ); - } - } - */ - - if ( anim == BOTH_STAND2 || anim == BOTH_STAND1 ) - { - //FIXME: play both_stand2_random1 when you've been idle for a while - /*if((pm->ps->legsAnim & ~ANIM_TOGGLEBIT) == BOTH_WALK1 ) - { - anim = BOTH_WALK1; - } - else if((pm->ps->legsAnim & ~ANIM_TOGGLEBIT) == BOTH_RUN1 ) - { - anim = BOTH_RUN1; - } - else if((pm->ps->legsAnim & ~ANIM_TOGGLEBIT) == BOTH_WALK2 ) - { - anim = BOTH_WALK2; - }*/ - anim = (pm->ps->legsAnim & ~ANIM_TOGGLEBIT); if ((anim >= BOTH_STAND1 && anim <= BOTH_STAND4TOATTACK2) || (anim >= TORSO_DROPWEAP1 && anim <= TORSO_WEAPONIDLE12)) { //If standing then use the special saber stand anim - anim = BOTH_STAND2; + anim = PM_GetSaberStance(); } if (pm->ps->pm_flags & PMF_DUCKED) { //Playing torso walk anims while crouched makes you look like a monkey - anim = BOTH_STAND2; + anim = PM_GetSaberStance(); } if (anim == BOTH_WALKBACK1 || anim == BOTH_WALKBACK2) { //normal stance when walking backward so saber doesn't look like it's cutting through leg - anim = BOTH_STAND2; + anim = PM_GetSaberStance(); } parts = SETANIM_TORSO; @@ -1955,7 +1696,7 @@ void PM_SetSaberMove(short newMove) {//successfully changed anims //special check for *starting* a saber swing //playing at attack - if ( PM_SaberInAttack( newMove ) || PM_SaberInSpecialAttack( anim ) ) + if ( BG_SaberInAttack( newMove ) || BG_SaberInSpecialAttack( anim ) ) { if ( pm->ps->saberMove != newMove ) {//wasn't playing that attack before @@ -1968,28 +1709,10 @@ void PM_SetSaberMove(short newMove) pm->ps->torsoAnim = anim;//saberMoveData[newMove].animToUse; - // NOTENOTE All clients are players, so clientnum=0 should mean always in MP -// if ( pm->ps->saberBlocked <= BLOCKED_ATK_BOUNCE || pm->ps->clientNum == 0 || !pm->ps->saberActive || (newMove < LS_PARRY_UR || newMove > LS_DEFLECT_LL) ) if (pm->ps->weaponTime <= 0) - {//NPCs only clear blocked if not blocking? + { pm->ps->saberBlocked = BLOCKED_NONE; } - - // NOTENOTE Had to remove this concept since there is no gent in pmove. - /* - if ( pm->gent && pm->gent->client ) - { - if ( saberMoveData[newMove].trailLength > 0 ) - { - pm->gent->client->saberTrail.inAction = qtrue; - pm->gent->client->saberTrail.duration = saberMoveData[newMove].trailLength; // saber trail lasts for 75ms...feel free to change this if you want it longer or shorter - } - else - { - pm->gent->client->saberTrail.inAction = qfalse; - } - } - */ } } diff --git a/CODEmp/game/bg_saga.h b/CODE-mp/game/bg_saga.h similarity index 100% rename from CODEmp/game/bg_saga.h rename to CODE-mp/game/bg_saga.h diff --git a/CODEmp/game/bg_slidemove.c b/CODE-mp/game/bg_slidemove.c similarity index 100% rename from CODEmp/game/bg_slidemove.c rename to CODE-mp/game/bg_slidemove.c diff --git a/CODEmp/game/bg_weapons.c b/CODE-mp/game/bg_weapons.c similarity index 100% rename from CODEmp/game/bg_weapons.c rename to CODE-mp/game/bg_weapons.c diff --git a/CODEmp/game/bg_weapons.h b/CODE-mp/game/bg_weapons.h similarity index 100% rename from CODEmp/game/bg_weapons.h rename to CODE-mp/game/bg_weapons.h diff --git a/CODEmp/game/botlib.h b/CODE-mp/game/botlib.h similarity index 97% rename from CODEmp/game/botlib.h rename to CODE-mp/game/botlib.h index 281a6f4..0d77769 100644 --- a/CODEmp/game/botlib.h +++ b/CODE-mp/game/botlib.h @@ -408,6 +408,8 @@ typedef struct botlib_export_s int (*PC_FreeSourceHandle)(int handle); int (*PC_ReadTokenHandle)(int handle, pc_token_t *pc_token); int (*PC_SourceFileAndLine)(int handle, char *filename, int *line); + int (*PC_LoadGlobalDefines)(const char* filename ); + void (*PC_RemoveAllGlobalDefines) ( void ); //start a frame in the bot library int (*BotLibStartFrame)(float time); diff --git a/CODEmp/game/chars.h b/CODE-mp/game/chars.h similarity index 100% rename from CODEmp/game/chars.h rename to CODE-mp/game/chars.h diff --git a/CODEmp/game/g_active.c b/CODE-mp/game/g_active.c similarity index 86% rename from CODEmp/game/g_active.c rename to CODE-mp/game/g_active.c index 8e24980..4473d7b 100644 --- a/CODEmp/game/g_active.c +++ b/CODE-mp/game/g_active.c @@ -762,15 +762,21 @@ void ClientEvents( gentity_t *ent, int oldEventSequence ) { case EV_FIRE_WEAPON: FireWeapon( ent, qfalse ); ent->client->dangerTime = level.time; + ent->client->ps.eFlags &= ~EF_INVULNERABLE; + ent->client->invulnerableTimer = 0; break; case EV_ALT_FIRE: FireWeapon( ent, qtrue ); ent->client->dangerTime = level.time; + ent->client->ps.eFlags &= ~EF_INVULNERABLE; + ent->client->invulnerableTimer = 0; break; case EV_SABER_ATTACK: ent->client->dangerTime = level.time; + ent->client->ps.eFlags &= ~EF_INVULNERABLE; + ent->client->invulnerableTimer = 0; break; //rww - Note that these must be in the same order (ITEM#-wise) as they are in holdable_t @@ -881,6 +887,128 @@ void SendPendingPredictableEvents( playerState_t *ps ) { extern int saberOffSound; extern int saberOnSound; +/* +================== +G_UpdateClientBroadcasts + +Determines whether this client should be broadcast to any other clients. +A client is broadcast when another client is using force sight or is +================== +*/ +#define MAX_JEDIMASTER_DISTANCE 2500 +#define MAX_JEDIMASTER_FOV 100 + +#define MAX_SIGHT_DISTANCE 1500 +#define MAX_SIGHT_FOV 100 + +static void G_UpdateForceSightBroadcasts ( gentity_t *self ) +{ + int i; + + // Any clients with force sight on should see this client + for ( i = 0; i < level.numConnectedClients; i ++ ) + { + gentity_t *ent = &g_entities[level.sortedClients[i]]; + float dist; + vec3_t angles; + + if ( ent == self ) + { + continue; + } + + // Not using force sight so we shouldnt broadcast to this one + if ( !(ent->client->ps.fd.forcePowersActive & (1<client->ps.origin, ent->client->ps.origin, angles ); + dist = VectorLengthSquared ( angles ); + vectoangles ( angles, angles ); + + // Too far away then just forget it + if ( dist > MAX_SIGHT_DISTANCE * MAX_SIGHT_DISTANCE ) + { + continue; + } + + // If not within the field of view then forget it + if ( !InFieldOfVision ( ent->client->ps.viewangles, MAX_SIGHT_FOV, angles ) ) + { + break; + } + + // Turn on the broadcast bit for the master and since there is only one + // master we are done + self->r.broadcastClients[ent->s.clientNum/32] |= (1 << (ent->s.clientNum%32)); + + break; + } +} + +static void G_UpdateJediMasterBroadcasts ( gentity_t *self ) +{ + int i; + + // Not jedi master mode then nothing to do + if ( g_gametype.integer != GT_JEDIMASTER ) + { + return; + } + + // This client isnt the jedi master so it shouldnt broadcast + if ( !self->client->ps.isJediMaster ) + { + return; + } + + // Broadcast ourself to all clients within range + for ( i = 0; i < level.numConnectedClients; i ++ ) + { + gentity_t *ent = &g_entities[level.sortedClients[i]]; + float dist; + vec3_t angles; + + if ( ent == self ) + { + continue; + } + + VectorSubtract( self->client->ps.origin, ent->client->ps.origin, angles ); + dist = VectorLengthSquared ( angles ); + vectoangles ( angles, angles ); + + // Too far away then just forget it + if ( dist > MAX_JEDIMASTER_DISTANCE * MAX_JEDIMASTER_DISTANCE ) + { + continue; + } + + // If not within the field of view then forget it + if ( !InFieldOfVision ( ent->client->ps.viewangles, MAX_JEDIMASTER_FOV, angles ) ) + { + continue; + } + + // Turn on the broadcast bit for the master and since there is only one + // master we are done + self->r.broadcastClients[ent->s.clientNum/32] |= (1 << (ent->s.clientNum%32)); + } +} + +void G_UpdateClientBroadcasts ( gentity_t *self ) +{ + // Clear all the broadcast bits for this client + memset ( self->r.broadcastClients, 0, sizeof ( self->r.broadcastClients ) ); + + // The jedi master is broadcast to everyone in range + G_UpdateJediMasterBroadcasts ( self ); + + // Anyone with force sight on should see this client + G_UpdateForceSightBroadcasts ( self ); +} + /* ============== ClientThink @@ -959,6 +1087,14 @@ void ClientThink_real( gentity_t *ent ) { return; } + if (ent && ent->client && (ent->client->ps.eFlags & EF_INVULNERABLE)) + { + if (ent->client->invulnerableTimer <= level.time) + { + ent->client->ps.eFlags &= ~EF_INVULNERABLE; + } + } + // check for inactivity timer, but never drop the local client of a non-dedicated server if ( !ClientInactivityTimer( client ) ) { return; @@ -1065,7 +1201,16 @@ void ClientThink_real( gentity_t *ent ) { //Winner gets full health.. providing he's still alive if (ent->health > 0 && ent->client->ps.stats[STAT_HEALTH] > 0) { - ent->client->ps.stats[STAT_HEALTH] = ent->health = ent->client->ps.stats[STAT_MAX_HEALTH]; + if (ent->health < ent->client->ps.stats[STAT_MAX_HEALTH]) + { + ent->client->ps.stats[STAT_HEALTH] = ent->health = ent->client->ps.stats[STAT_MAX_HEALTH]; + } + + if (g_spawnInvulnerability.integer) + { + ent->client->ps.eFlags |= EF_INVULNERABLE; + ent->client->invulnerableTimer = level.time + g_spawnInvulnerability.integer; + } } /* @@ -1075,7 +1220,7 @@ void ClientThink_real( gentity_t *ent ) { //Private duel announcements are now made globally because we only want one duel at a time. if (ent->health > 0 && ent->client->ps.stats[STAT_HEALTH] > 0) { - trap_SendServerCommand( -1, va("cp \"%s %s\n\"", ent->client->pers.netname, G_GetStripEdString("SVINGAME", "PLDUELWINNER")) ); + trap_SendServerCommand( -1, va("cp \"%s %s %s!\n\"", ent->client->pers.netname, G_GetStripEdString("SVINGAME", "PLDUELWINNER"), duelAgainst->client->pers.netname) ); } else { //it was a draw, because we both managed to die in the same frame @@ -1375,6 +1520,37 @@ void ClientThink_real( gentity_t *ent ) { // perform once-a-second actions ClientTimerActions( ent, msec ); + + G_UpdateClientBroadcasts ( ent ); +} + +/* +================== +G_CheckClientTimeouts + +Checks whether a client has exceded any timeouts and act accordingly +================== +*/ +void G_CheckClientTimeouts ( gentity_t *ent ) +{ + // Only timeout supported right now is the timeout to spectator mode + if ( !g_timeouttospec.integer ) + { + return; + } + + // Already a spectator, no need to boot them to spectator + if ( ent->client->sess.sessionTeam == TEAM_SPECTATOR ) + { + return; + } + + // See how long its been since a command was received by the client and if its + // longer than the timeout to spectator then force this client into spectator mode + if ( level.time - ent->client->pers.cmd.serverTime > g_timeouttospec.integer * 1000 ) + { + SetTeam ( ent, "spectator" ); + } } /* diff --git a/CODEmp/game/g_arenas.c b/CODE-mp/game/g_arenas.c similarity index 100% rename from CODEmp/game/g_arenas.c rename to CODE-mp/game/g_arenas.c diff --git a/CODEmp/game/g_bot.c b/CODE-mp/game/g_bot.c similarity index 100% rename from CODEmp/game/g_bot.c rename to CODE-mp/game/g_bot.c diff --git a/CODEmp/game/g_client.c b/CODE-mp/game/g_client.c similarity index 94% rename from CODEmp/game/g_client.c rename to CODE-mp/game/g_client.c index 40948b3..f54bc57 100644 --- a/CODEmp/game/g_client.c +++ b/CODE-mp/game/g_client.c @@ -67,7 +67,7 @@ void SP_info_player_intermission( gentity_t *ent ) { } -#define JMSABER_RESPAWN_TIME 60000 //in case it gets stuck somewhere no one can reach +#define JMSABER_RESPAWN_TIME 20000 //in case it gets stuck somewhere no one can reach void ThrowSaberToAttacker(gentity_t *self, gentity_t *attacker) @@ -211,14 +211,25 @@ void JMSaberTouch(gentity_t *self, gentity_t *other, trace_t *trace) other->s.weapon = WP_SABER; G_AddEvent(other, EV_BECOME_JEDIMASTER, 0); + if (g_spawnInvulnerability.integer) + { + other->client->ps.eFlags |= EF_INVULNERABLE; + other->client->invulnerableTimer = level.time + g_spawnInvulnerability.integer; + } + trap_SendServerCommand( -1, va("cp \"%s %s\n\"", other->client->pers.netname, G_GetStripEdString("SVINGAME", "BECOMEJM")) ); other->client->ps.isJediMaster = qtrue; other->client->ps.saberIndex = self->s.number; - if (other->health < 100) + if (other->health < 200 && other->health > 0) { //full health when you become the Jedi Master - other->client->ps.stats[STAT_HEALTH] = other->health = 100; + other->client->ps.stats[STAT_HEALTH] = other->health = 200; + } + + if (other->client->ps.fd.forcePower < 100) + { + other->client->ps.fd.forcePower = 100; } while (i < NUM_FORCE_POWERS) @@ -277,6 +288,8 @@ void SP_info_jedimaster_start(gentity_t *ent) ent->bounceCount = -5; + ent->physicsObject = qtrue; + VectorCopy(ent->s.pos.trBase, ent->s.origin2); //remember the spawn spot ent->touch = JMSaberTouch; @@ -1238,7 +1251,6 @@ char *ClientConnect( int clientNum, qboolean firstTime, qboolean isBot ) { char userinfo[MAX_INFO_STRING]; gentity_t *ent; gentity_t *te; - const char *selFP = NULL; ent = &g_entities[ clientNum ]; @@ -1250,7 +1262,7 @@ char *ClientConnect( int clientNum, qboolean firstTime, qboolean isBot ) { return "Banned."; } - if ( !( ent->r.svFlags & SVF_BOT ) ) { + if ( !( ent->r.svFlags & SVF_BOT ) && !isBot && g_needpass.integer ) { // check for a password value = Info_ValueForKey (userinfo, "password"); if ( g_password.string[0] && Q_stricmp( g_password.string, "none" ) && @@ -1269,17 +1281,6 @@ char *ClientConnect( int clientNum, qboolean firstTime, qboolean isBot ) { client->pers.connected = CON_CONNECTING; - selFP = Info_ValueForKey (userinfo, "sfp"); // "sfp" == "selected force power" - if (selFP && selFP[0]) - { - client->sess.selectedFP = atoi(selFP)+1; - } - selFP = Info_ValueForKey (userinfo, "sal"); // "sal" == "saber attack level" - if (selFP && selFP[0]) - { - client->sess.saberLevel = atoi(selFP)+1; - } - // read or initialize the session data if ( firstTime || level.newSession ) { G_InitSessionData( client, userinfo, isBot ); @@ -1640,15 +1641,32 @@ void ClientSpawn(gentity_t *ent) { client->ps.stats[STAT_WEAPONS] |= ( 1 << WP_BRYAR_PISTOL ); } - if (g_gametype.integer == GT_JEDIMASTER) { client->ps.stats[STAT_WEAPONS] &= ~(1 << WP_SABER); client->ps.stats[STAT_WEAPONS] |= (1 << WP_STUN_BATON); } + if (client->ps.stats[STAT_WEAPONS] & (1 << WP_BRYAR_PISTOL)) + { + client->ps.weapon = WP_BRYAR_PISTOL; + } + else if (client->ps.stats[STAT_WEAPONS] & (1 << WP_SABER)) + { + client->ps.weapon = WP_SABER; + } + else + { + client->ps.weapon = WP_STUN_BATON; + } + + /* client->ps.stats[STAT_HOLDABLE_ITEMS] |= ( 1 << HI_BINOCULARS ); client->ps.stats[STAT_HOLDABLE_ITEM] = BG_GetItemIndexByTag(HI_BINOCULARS, IT_HOLDABLE); + */ + + client->ps.stats[STAT_HOLDABLE_ITEMS] = 0; + client->ps.stats[STAT_HOLDABLE_ITEM] = 0; if ( client->sess.sessionTeam == TEAM_SPECTATOR ) { @@ -1760,6 +1778,12 @@ void ClientSpawn(gentity_t *ent) { trap_LinkEntity( ent ); } + if (g_spawnInvulnerability.integer) + { + ent->client->ps.eFlags |= EF_INVULNERABLE; + ent->client->invulnerableTimer = level.time + g_spawnInvulnerability.integer; + } + // run the presend to set anything else ClientEndFrame( ent ); diff --git a/CODEmp/game/g_cmds.c b/CODE-mp/game/g_cmds.c similarity index 95% rename from CODEmp/game/g_cmds.c rename to CODE-mp/game/g_cmds.c index 5547a1c..2ee03df 100644 --- a/CODEmp/game/g_cmds.c +++ b/CODE-mp/game/g_cmds.c @@ -556,6 +556,11 @@ void BroadcastTeamChange( gclient_t *client, int oldTeam ) client->pers.netname, G_GetStripEdString("SVINGAME", "JOINEDTHEBATTLE"))); } } + + G_LogPrintf ( "setteam: %i %s %s\n", + client - &level.clients[0], + TeamName ( oldTeam ), + TeamName ( client->sess.sessionTeam ) ); } /* diff --git a/CODEmp/game/g_combat.c b/CODE-mp/game/g_combat.c similarity index 94% rename from CODEmp/game/g_combat.c rename to CODE-mp/game/g_combat.c index d503dc2..91d0edc 100644 --- a/CODEmp/game/g_combat.c +++ b/CODE-mp/game/g_combat.c @@ -1180,6 +1180,7 @@ void player_die( gentity_t *self, gentity_t *inflictor, gentity_t *attacker, int int killer; int i; char *killerName, *obit; + qboolean wasJediMaster = qfalse; if ( self->client->ps.pm_type == PM_DEAD ) { return; @@ -1196,6 +1197,11 @@ void player_die( gentity_t *self, gentity_t *inflictor, gentity_t *attacker, int attacker = inflictor->activator; } + if (self->client && self->client->ps.isJediMaster) + { + wasJediMaster = qtrue; + } + //if he was charging or anything else, kill the sound G_MuteSound(self->s.number, CHAN_WEAPON); @@ -1255,6 +1261,7 @@ void player_die( gentity_t *self, gentity_t *inflictor, gentity_t *attacker, int ent->s.otherEntityNum = self->s.number; ent->s.otherEntityNum2 = killer; ent->r.svFlags = SVF_BROADCAST; // send to everyone + ent->s.isJediMaster = wasJediMaster; self->enemy = attacker; @@ -1474,7 +1481,15 @@ void player_die( gentity_t *self, gentity_t *inflictor, gentity_t *attacker, int //rww - do this on respawn, not death //CopyToBodyQue (self); - G_AddEvent( self, EV_DEATH1 + i, killer ); + //G_AddEvent( self, EV_DEATH1 + i, killer ); + if (wasJediMaster) + { + G_AddEvent( self, EV_DEATH1 + i, 1 ); + } + else + { + G_AddEvent( self, EV_DEATH1 + i, 0 ); + } // the body can still be gibbed self->die = body_die; @@ -2154,10 +2169,37 @@ void G_Damage( gentity_t *targ, gentity_t *inflictor, gentity_t *attacker, } } + if (targ->client && targ->s.shouldtarget && targ->s.teamowner && + attacker && attacker->inuse && attacker->client && targ->s.owner >= 0 && targ->s.owner < MAX_CLIENTS) + { + gentity_t *targown = &g_entities[targ->s.owner]; + + if (targown && targown->inuse && targown->client && OnSameTeam(targown, attacker)) + { + if (!g_friendlyFire.integer) + { + return; + } + } + } + // check for godmode if ( targ->flags & FL_GODMODE ) { return; } + + if (targ && targ->client && (targ->client->ps.eFlags & EF_INVULNERABLE) && + attacker && attacker->client && targ != attacker) + { + if (targ->client->invulnerableTimer <= level.time) + { + targ->client->ps.eFlags &= ~EF_INVULNERABLE; + } + else + { + return; + } + } } if (attacker && attacker->client) @@ -2370,7 +2412,7 @@ void G_Damage( gentity_t *targ, gentity_t *inflictor, gentity_t *attacker, if (take) { if (targ->client && (targ->client->ps.fd.forcePowersActive & (1 << FP_RAGE)) && (inflictor->client || attacker->client)) { - take /= (targ->client->ps.fd.forcePowerLevel[FP_RAGE]*2); + take /= (targ->client->ps.fd.forcePowerLevel[FP_RAGE]); } targ->health = targ->health - take; if ( targ->client ) { diff --git a/CODEmp/game/g_items.c b/CODE-mp/game/g_items.c similarity index 89% rename from CODEmp/game/g_items.c rename to CODE-mp/game/g_items.c index a44acfa..9c28744 100644 --- a/CODEmp/game/g_items.c +++ b/CODE-mp/game/g_items.c @@ -16,11 +16,12 @@ */ -#define RESPAWN_ARMOR 25 -#define RESPAWN_HEALTH 35 +#define RESPAWN_ARMOR 20 +#define RESPAWN_TEAM_WEAPON 30 +#define RESPAWN_HEALTH 30 #define RESPAWN_AMMO 40 #define RESPAWN_HOLDABLE 60 -#define RESPAWN_MEGAHEALTH 35//120 +#define RESPAWN_MEGAHEALTH 120 #define RESPAWN_POWERUP 120 extern gentity_t *droppedRedFlag; @@ -30,6 +31,39 @@ extern gentity_t *droppedBlueFlag; #define MAX_MEDPACK_HEAL_AMOUNT 100 #define MAX_SENTRY_DISTANCE 256 +// For more than four players, adjust the respawn times, up to 1/4. +int adjustRespawnTime(float respawnTime) +{ + if (!g_adaptRespawn.integer) + { + return((int)respawnTime); + } + + if (level.numPlayingClients > 4) + { // Start scaling the respawn times. + if (level.numPlayingClients > 32) + { // 1/4 time minimum. + respawnTime *= 0.25; + } + else if (level.numPlayingClients > 12) + { // From 12-32, scale from 0.5 to 0.25; + respawnTime *= 20.0 / (float)(level.numPlayingClients + 8); + } + else + { // From 4-12, scale from 1.0 to 0.5; + respawnTime *= 8.0 / (float)(level.numPlayingClients + 4); + } + } + + if (respawnTime < 1.0) + { // No matter what, don't go lower than 1 second, or the pickups become very noisy! + respawnTime = 1.0; + } + + return ((int)respawnTime); +} + + #define SHIELD_HEALTH 250 #define SHIELD_HEALTH_DEC 10 // 25 seconds #define MAX_SHIELD_HEIGHT 254 @@ -37,7 +71,7 @@ extern gentity_t *droppedBlueFlag; #define SHIELD_HALFTHICKNESS 4 #define SHIELD_PLACEDIST 64 - +static qhandle_t shieldLoopSound=0; static qhandle_t shieldAttachSound=0; static qhandle_t shieldActivateSound=0; static qhandle_t shieldDeactivateSound=0; @@ -49,8 +83,9 @@ void ShieldRemove(gentity_t *self) self->think = G_FreeEntity; self->nextthink = level.time + 100; - // Play raising sound... - G_AddEvent(self, EV_GENERAL_SOUND, shieldActivateSound); + // Play kill sound... + G_AddEvent(self, EV_GENERAL_SOUND, shieldDeactivateSound); + self->s.loopSound = 0; return; } @@ -129,6 +164,7 @@ void ShieldGoSolid(gentity_t *self) // Play raising sound... G_AddEvent(self, EV_GENERAL_SOUND, shieldActivateSound); + self->s.loopSound = shieldLoopSound; } return; @@ -147,8 +183,9 @@ void ShieldGoNotSolid(gentity_t *self) self->takedamage = qfalse; trap_LinkEntity(self); - // Play raising sound... + // Play kill sound... G_AddEvent(self, EV_GENERAL_SOUND, shieldDeactivateSound); + self->s.loopSound = 0; } @@ -289,6 +326,7 @@ void CreateShield(gentity_t *ent) // Play raising sound... G_AddEvent(ent, EV_GENERAL_SOUND, shieldActivateSound); + ent->s.loopSound = shieldLoopSound; } ShieldGoSolid(ent); @@ -305,6 +343,7 @@ qboolean PlaceShield(gentity_t *playerent) if (shieldAttachSound==0) { + shieldLoopSound = G_SoundIndex("sound/movers/doors/forcefield_lp.wav"); shieldAttachSound = G_SoundIndex("sound/weapons/detpack/stick.wav"); shieldActivateSound = G_SoundIndex("sound/movers/doors/forcefield_on.wav"); shieldDeactivateSound = G_SoundIndex("sound/movers/doors/forcefield_off.wav"); @@ -613,6 +652,7 @@ void pas_adjust_enemy( gentity_t *ent ) } #define TURRET_DEATH_DELAY 2000 +#define TURRET_LIFETIME 60000 void turret_die(gentity_t *self, gentity_t *inflictor, gentity_t *attacker, int damage, int mod); @@ -648,6 +688,17 @@ void pas_think( gentity_t *ent ) return; } + if ((ent->bolt_LLeg+TURRET_LIFETIME) < level.time) + { + G_Sound( ent, CHAN_BODY, G_SoundIndex( "sound/chars/turret/shutdown.wav" )); + ent->s.bolt2 = ENTITYNUM_NONE; + ent->s.fireflag = 2; + + ent->think = sentryExpire; + ent->nextthink = level.time + TURRET_DEATH_DELAY; + return; + } + ent->nextthink = level.time + FRAMETIME; if ( ent->enemy ) @@ -922,6 +973,8 @@ void ItemUse_Sentry( gentity_t *ent ) sentry->bolt_Head = 1000; + sentry->bolt_LLeg = level.time; + sentry->noDamageTeam = ent->client->sess.sessionTeam; ent->client->ps.fd.sentryDeployed = qtrue; @@ -958,6 +1011,13 @@ void ItemUse_MedPack(gentity_t *ent) return; } + if (ent->health <= 0 || + ent->client->ps.stats[STAT_HEALTH] <= 0 || + (ent->client->ps.eFlags & EF_DEAD)) + { + return; + } + if (ent->health >= ent->client->ps.stats[STAT_MAX_HEALTH]) { return; @@ -1052,7 +1112,7 @@ int Pickup_Holdable( gentity_t *ent, gentity_t *other ) { G_LogWeaponItem(other->s.number, ent->item->giTag); - return RESPAWN_HOLDABLE; + return adjustRespawnTime(RESPAWN_HOLDABLE); } @@ -1078,7 +1138,7 @@ int Pickup_Ammo (gentity_t *ent, gentity_t *other) Add_Ammo (other, ent->item->giTag, quantity); - return RESPAWN_AMMO; + return adjustRespawnTime(RESPAWN_AMMO); } //====================================================================== @@ -1099,28 +1159,43 @@ int Pickup_Weapon (gentity_t *ent, gentity_t *other) { // dropped items and teamplay weapons always have full ammo if ( ! (ent->flags & FL_DROPPED_ITEM) && g_gametype.integer != GT_TEAM ) { // respawning rules + + // New method: If the player has less than half the minimum, give them the minimum, else add 1/2 the min. + // drop the quantity if the already have over the minimum - if ( other->client->ps.ammo[weaponData[ ent->item->giTag ].ammoIndex] < quantity ) { - quantity = quantity - other->client->ps.ammo[weaponData[ ent->item->giTag ].ammoIndex]; + if ( other->client->ps.ammo[ ent->item->giTag ] < quantity*0.5 ) { + quantity = quantity - other->client->ps.ammo[ ent->item->giTag ]; + } else { + quantity = quantity*0.5; // only add half the value. + } + + // Old method: If the player has less than the minimum, give them the minimum, else just add 1. +/* + // drop the quantity if the already have over the minimum + if ( other->client->ps.ammo[ ent->item->giTag ] < quantity ) { + quantity = quantity - other->client->ps.ammo[ ent->item->giTag ]; } else { quantity = 1; // only add a single shot } + */ } } // add the weapon other->client->ps.stats[STAT_WEAPONS] |= ( 1 << ent->item->giTag ); + //Add_Ammo( other, ent->item->giTag, quantity ); Add_Ammo( other, weaponData[ent->item->giTag].ammoIndex, quantity ); G_LogWeaponPickup(other->s.number, ent->item->giTag); - + // team deathmatch has slow weapon respawns - if ( g_gametype.integer == GT_TEAM ) { - return g_weaponTeamRespawn.integer; + if ( g_gametype.integer == GT_TEAM ) + { + return adjustRespawnTime(RESPAWN_TEAM_WEAPON); } - return g_weaponRespawn.integer; + return adjustRespawnTime(g_weaponRespawn.integer); } @@ -1154,7 +1229,7 @@ int Pickup_Health (gentity_t *ent, gentity_t *other) { return RESPAWN_MEGAHEALTH; } - return RESPAWN_HEALTH; + return adjustRespawnTime(RESPAWN_HEALTH); } //====================================================================== @@ -1162,12 +1237,12 @@ int Pickup_Health (gentity_t *ent, gentity_t *other) { int Pickup_Armor( gentity_t *ent, gentity_t *other ) { other->client->ps.stats[STAT_ARMOR] += ent->item->quantity; - if ( other->client->ps.stats[STAT_ARMOR] > other->client->ps.stats[STAT_MAX_HEALTH]/* * 2*/ ) + if ( other->client->ps.stats[STAT_ARMOR] > other->client->ps.stats[STAT_MAX_HEALTH] * ent->item->giTag ) { - other->client->ps.stats[STAT_ARMOR] = other->client->ps.stats[STAT_MAX_HEALTH]/* * 2*/; + other->client->ps.stats[STAT_ARMOR] = other->client->ps.stats[STAT_MAX_HEALTH] * ent->item->giTag; } - return RESPAWN_ARMOR; + return adjustRespawnTime(RESPAWN_ARMOR); } //====================================================================== @@ -1586,6 +1661,25 @@ void FinishSpawningItem( gentity_t *ent ) { } } } + else + { //no powerups in jedi master + if (ent->item->giType == IT_POWERUP) + { + G_FreeEntity(ent); + return; + } + } + + if (g_gametype.integer == GT_TOURNAMENT) + { + if ( ent->item->giType == IT_ARMOR || + ent->item->giType == IT_HEALTH || + (ent->item->giType == IT_HOLDABLE && ent->item->giTag == HI_MEDPAC) ) + { + G_FreeEntity(ent); + return; + } + } if (g_gametype.integer != GT_CTF && g_gametype.integer != GT_CTY && @@ -1726,6 +1820,7 @@ void ClearRegisteredItems( void ) { // players always start with the base weapon RegisterItem( BG_FindItemForWeapon( WP_BRYAR_PISTOL ) ); RegisterItem( BG_FindItemForWeapon( WP_STUN_BATON ) ); + RegisterItem( BG_FindItemForWeapon( WP_SABER ) ); } /* diff --git a/CODEmp/game/g_local.h b/CODE-mp/game/g_local.h similarity index 96% rename from CODEmp/game/g_local.h rename to CODE-mp/game/g_local.h index 1527e23..60d7e18 100644 --- a/CODEmp/game/g_local.h +++ b/CODE-mp/game/g_local.h @@ -334,6 +334,8 @@ struct gclient_s { clientPersistant_t pers; clientSession_t sess; + int invulnerableTimer; + int saberCycleQueue; qboolean readyToExit; // wishes to leave the intermission @@ -781,9 +783,10 @@ void ClientCommand( int clientNum ); // // g_active.c // -void ClientThink( int clientNum ); -void ClientEndFrame( gentity_t *ent ); -void G_RunClient( gentity_t *ent ); +void G_CheckClientTimeouts ( gentity_t *ent ); +void ClientThink ( int clientNum ); +void ClientEndFrame ( gentity_t *ent ); +void G_RunClient ( gentity_t *ent ); // // g_team.c @@ -871,8 +874,10 @@ void InitSagaMode(void); // ai_main.c #define MAX_FILEPATH 144 -int OrgVisible(vec3_t org1, vec3_t org2, int ignore); -void BotOrder(gentity_t *ent, int clientnum, int ordernum); + +int OrgVisible ( vec3_t org1, vec3_t org2, int ignore); +void BotOrder ( gentity_t *ent, int clientnum, int ordernum); +int InFieldOfVision ( vec3_t viewangles, float fov, vec3_t angles); // ai_util.c void B_InitAlloc(void); @@ -913,7 +918,9 @@ extern vmCvar_t g_dmflags; extern vmCvar_t g_maxForceRank; extern vmCvar_t g_forceBasedTeams; extern vmCvar_t g_privateDuel; +extern vmCvar_t g_saberLocking; extern vmCvar_t g_forceRegenTime; +extern vmCvar_t g_spawnInvulnerability; extern vmCvar_t g_forcePowerDisable; extern vmCvar_t g_weaponDisable; extern vmCvar_t g_fraglimit; @@ -936,6 +943,7 @@ extern vmCvar_t g_debugAlloc; extern vmCvar_t g_debugDamage; extern vmCvar_t g_weaponRespawn; extern vmCvar_t g_weaponTeamRespawn; +extern vmCvar_t g_adaptRespawn; extern vmCvar_t g_synchronousClients; extern vmCvar_t g_motd; extern vmCvar_t g_warmup; @@ -960,6 +968,7 @@ extern vmCvar_t g_enableBreath; extern vmCvar_t g_singlePlayer; extern vmCvar_t g_dismember; extern vmCvar_t g_forceDodge; +extern vmCvar_t g_timeouttospec; void trap_Printf( const char *fmt ); void trap_Error( const char *fmt ); diff --git a/CODEmp/game/g_log.c b/CODE-mp/game/g_log.c similarity index 100% rename from CODEmp/game/g_log.c rename to CODE-mp/game/g_log.c diff --git a/CODEmp/game/g_main.c b/CODE-mp/game/g_main.c similarity index 93% rename from CODEmp/game/g_main.c rename to CODE-mp/game/g_main.c index f8ba7ba..78f9030 100644 --- a/CODEmp/game/g_main.c +++ b/CODE-mp/game/g_main.c @@ -26,7 +26,9 @@ vmCvar_t g_dmflags; vmCvar_t g_maxForceRank; vmCvar_t g_forceBasedTeams; vmCvar_t g_privateDuel; +vmCvar_t g_saberLocking; vmCvar_t g_forceRegenTime; +vmCvar_t g_spawnInvulnerability; vmCvar_t g_forcePowerDisable; vmCvar_t g_weaponDisable; vmCvar_t g_fraglimit; @@ -53,6 +55,7 @@ vmCvar_t g_debugDamage; vmCvar_t g_debugAlloc; vmCvar_t g_weaponRespawn; vmCvar_t g_weaponTeamRespawn; +vmCvar_t g_adaptRespawn; vmCvar_t g_motd; vmCvar_t g_synchronousClients; vmCvar_t g_warmup; @@ -85,6 +88,7 @@ vmCvar_t g_enableDust; vmCvar_t g_enableBreath; vmCvar_t g_dismember; vmCvar_t g_forceDodge; +vmCvar_t g_timeouttospec; // bk001129 - made static to avoid aliasing static cvarTable_t gameCvarTable[] = { @@ -99,7 +103,7 @@ static cvarTable_t gameCvarTable[] = { // latched vars { &g_gametype, "g_gametype", "0", CVAR_SERVERINFO | CVAR_USERINFO | CVAR_LATCH, 0, qfalse }, - { &g_MaxHolocronCarry, "g_MaxHolocronCarry", "5", CVAR_SERVERINFO | CVAR_USERINFO | CVAR_LATCH, 0, qfalse }, + { &g_MaxHolocronCarry, "g_MaxHolocronCarry", "3", CVAR_SERVERINFO | CVAR_USERINFO | CVAR_LATCH, 0, qfalse }, { &g_maxclients, "sv_maxclients", "8", CVAR_SERVERINFO | CVAR_LATCH | CVAR_ARCHIVE, 0, qfalse }, { &g_maxGameClients, "g_maxGameClients", "0", CVAR_SERVERINFO | CVAR_LATCH | CVAR_ARCHIVE, 0, qfalse }, @@ -113,7 +117,10 @@ static cvarTable_t gameCvarTable[] = { { &g_maxForceRank, "g_maxForceRank", "0", CVAR_SERVERINFO | CVAR_USERINFO | CVAR_LATCH, 0, qfalse }, { &g_forceBasedTeams, "g_forceBasedTeams", "0", CVAR_SERVERINFO | CVAR_USERINFO | CVAR_LATCH, 0, qfalse }, { &g_privateDuel, "g_privateDuel", "0", CVAR_SERVERINFO | CVAR_ARCHIVE, 0, qtrue }, - { &g_forceRegenTime, "g_forceRegenTime", "500", CVAR_ARCHIVE, 0, qtrue }, + { &g_saberLocking, "g_saberLocking", "1", CVAR_SERVERINFO | CVAR_ARCHIVE, 0, qtrue }, + { &g_forceRegenTime, "g_forceRegenTime", "200", CVAR_ARCHIVE, 0, qtrue }, + + { &g_spawnInvulnerability, "g_spawnInvulnerability", "3000", CVAR_ARCHIVE, 0, qtrue }, { &g_forcePowerDisable, "g_forcePowerDisable", "0", CVAR_SERVERINFO | CVAR_ARCHIVE, 0, qtrue }, { &g_weaponDisable, "g_weaponDisable", "0", CVAR_SERVERINFO | CVAR_ARCHIVE, 0, qtrue }, @@ -154,8 +161,9 @@ static cvarTable_t gameCvarTable[] = { { &g_gravity, "g_gravity", "800", 0, 0, qtrue }, { &g_knockback, "g_knockback", "1000", 0, 0, qtrue }, { &g_quadfactor, "g_quadfactor", "3", 0, 0, qtrue }, - { &g_weaponRespawn, "g_weaponrespawn", "30", 0, 0, qtrue }, - { &g_weaponTeamRespawn, "g_weaponTeamRespawn", "30", 0, 0, qtrue }, + { &g_weaponRespawn, "g_weaponrespawn", "5", 0, 0, qtrue }, + { &g_weaponTeamRespawn, "g_weaponTeamRespawn", "5", 0, 0, qtrue }, + { &g_adaptRespawn, "g_adaptrespawn", "1", 0, 0, qtrue }, // Make weapons respawn faster with a lot of players. { &g_forcerespawn, "g_forcerespawn", "20", 0, 0, qtrue }, { &g_inactivity, "g_inactivity", "0", 0, 0, qtrue }, { &g_debugMove, "g_debugMove", "0", 0, 0, qfalse }, @@ -189,18 +197,20 @@ static cvarTable_t gameCvarTable[] = { { &g_rankings, "g_rankings", "0", 0, 0, qfalse}, { &g_dismember, "g_dismember", "0", 0, 0, qtrue }, - { &g_forceDodge, "g_forceDodge", "1", 0, 0, qtrue } + { &g_forceDodge, "g_forceDodge", "1", 0, 0, qtrue }, + + { &g_timeouttospec, "g_timeouttospec", "15", CVAR_ARCHIVE, 0, qfalse }, }; // bk001129 - made static to avoid aliasing static int gameCvarTableSize = sizeof( gameCvarTable ) / sizeof( gameCvarTable[0] ); -void G_InitGame( int levelTime, int randomSeed, int restart ); -void G_RunFrame( int levelTime ); -void G_ShutdownGame( int restart ); -void CheckExitRules( void ); -void G_ROFF_NotetrackCallback( gentity_t *cent, const char *notetrack); +void G_InitGame ( int levelTime, int randomSeed, int restart ); +void G_RunFrame ( int levelTime ); +void G_ShutdownGame ( int restart ); +void CheckExitRules ( void ); +void G_ROFF_NotetrackCallback ( gentity_t *cent, const char *notetrack); /* @@ -1117,6 +1127,9 @@ void ExitLevel (void) { } //this means we hit the duel limit so reset the wins/losses + //but still push the loser to the back of the line, and retain the order for + //the map change + RemoveTournamentLoser(); DuelResetWinsLosses(); } @@ -1421,7 +1434,7 @@ void CheckExitRules( void ) { continue; } - if ( g_gametype.integer == GT_TOURNAMENT && g_duel_fraglimit.integer && cl->sess.wins >= g_duel_fraglimit.integer-1 ) + if ( g_gametype.integer == GT_TOURNAMENT && g_duel_fraglimit.integer && cl->sess.wins >= g_duel_fraglimit.integer ) { LogExit( "Duel limit hit." ); trap_SendServerCommand( -1, va("print \"%s" S_COLOR_WHITE " hit the win limit.\n\"", @@ -1891,7 +1904,10 @@ int start, end; continue; } - if ( i < MAX_CLIENTS ) { + if ( i < MAX_CLIENTS ) + { + G_CheckClientTimeouts ( ent ); + G_RunClient( ent ); continue; } diff --git a/CODEmp/game/g_mem.c b/CODE-mp/game/g_mem.c similarity index 100% rename from CODEmp/game/g_mem.c rename to CODE-mp/game/g_mem.c diff --git a/CODEmp/game/g_misc.c b/CODE-mp/game/g_misc.c similarity index 93% rename from CODEmp/game/g_misc.c rename to CODE-mp/game/g_misc.c index 467a5bf..8a742a0 100644 --- a/CODEmp/game/g_misc.c +++ b/CODE-mp/game/g_misc.c @@ -323,6 +323,11 @@ void HolocronTouch(gentity_t *self, gentity_t *other, trace_t *trace) int hasall = 1; int forceReselect = WP_NONE; + if (trace) + { + self->s.groundEntityNum = trace->entityNum; + } + if (!other || !other->client || other->health < 1) { return; @@ -470,6 +475,28 @@ void HolocronThink(gentity_t *ent) goto justthink; } + + if (!ent->enemy->inuse || (ent->enemy->client && ent->enemy->client->ps.fallingToDeath)) + { + if (ent->enemy->inuse && ent->enemy->client) + { + ent->enemy->client->ps.holocronBits &= ~(1 << ent->count); + ent->enemy->client->ps.holocronsCarried[ent->count] = 0; + } + ent->enemy = NULL; + HolocronRespawn(ent); + VectorCopy(ent->s.origin2, ent->s.pos.trBase); + VectorCopy(ent->s.origin2, ent->s.origin); + VectorCopy(ent->s.origin2, ent->r.currentOrigin); + + ent->s.pos.trTime = level.time; + + ent->pos2[0] = 0; + + trap_LinkEntity(ent); + + goto justthink; + } } if (ent->pos2[0] && ent->pos2[1] < level.time) @@ -580,6 +607,8 @@ void SP_misc_holocron(gentity_t *ent) ent->s.trickedentindex3 = 3; } + ent->physicsObject = qtrue; + VectorCopy(ent->s.pos.trBase, ent->s.origin2); //remember the spawn spot ent->touch = HolocronTouch; diff --git a/CODEmp/game/g_missile.c b/CODE-mp/game/g_missile.c similarity index 91% rename from CODEmp/game/g_missile.c rename to CODE-mp/game/g_missile.c index 6764be4..90a5f8b 100644 --- a/CODEmp/game/g_missile.c +++ b/CODE-mp/game/g_missile.c @@ -361,18 +361,30 @@ void G_MissileImpact( gentity_t *ent, trace_t *trace ) { { //only block one projectile per 200ms (to prevent giant swarms of projectiles being blocked) vec3_t fwd; gentity_t *te; + int otherDefLevel = other->client->ps.fd.forcePowerLevel[FP_SABERDEFEND]; te = G_TempEntity( ent->r.currentOrigin, EV_SABER_BLOCK ); VectorCopy(ent->r.currentOrigin, te->s.origin); VectorCopy(trace->plane.normal, te->s.angles); te->s.eventParm = 0; + if (other->client->ps.velocity[2] > 0 || + other->client->pers.cmd.forwardmove || + other->client->pers.cmd.rightmove) + { + otherDefLevel -= 1; + if (otherDefLevel < 0) + { + otherDefLevel = 0; + } + } + AngleVectors(other->client->ps.viewangles, fwd, NULL, NULL); - if (other->client->ps.fd.forcePowerLevel[FP_SABERDEFEND] == FORCE_LEVEL_1) + if (otherDefLevel == FORCE_LEVEL_1) { //if def is only level 1, instead of deflecting the shot it should just die here } - else if (other->client->ps.fd.forcePowerLevel[FP_SABERDEFEND] == FORCE_LEVEL_2) + else if (otherDefLevel == FORCE_LEVEL_2) { G_DeflectMissile(other, ent, fwd); } @@ -380,14 +392,14 @@ void G_MissileImpact( gentity_t *ent, trace_t *trace ) { { G_ReflectMissile(other, ent, fwd); } - other->client->ps.saberBlockTime = level.time + (350 - (other->client->ps.fd.forcePowerLevel[FP_SABERDEFEND]*100)); //200; + other->client->ps.saberBlockTime = level.time + (350 - (otherDefLevel*100)); //200; - if (other->client->ps.fd.forcePowerLevel[FP_SABERDEFEND] == FORCE_LEVEL_3) + if (otherDefLevel == FORCE_LEVEL_3) { other->client->ps.saberBlockTime = 0; //^_^ } - if (other->client->ps.fd.forcePowerLevel[FP_SABERDEFEND] == FORCE_LEVEL_1) + if (otherDefLevel == FORCE_LEVEL_1) { goto killProj; } @@ -409,6 +421,7 @@ void G_MissileImpact( gentity_t *ent, trace_t *trace ) { { //for now still deflect even if saberBlockTime >= level.time because it hit the actual saber vec3_t fwd; gentity_t *te; + int otherDefLevel = otherOwner->client->ps.fd.forcePowerLevel[FP_SABERDEFEND]; //in this case, deflect it even if we can't actually block it because it hit our saber WP_SaberCanBlock(otherOwner, ent->r.currentOrigin, 0, 0, qtrue, 0); @@ -418,13 +431,24 @@ void G_MissileImpact( gentity_t *ent, trace_t *trace ) { VectorCopy(trace->plane.normal, te->s.angles); te->s.eventParm = 0; + if (otherOwner->client->ps.velocity[2] > 0 || + otherOwner->client->pers.cmd.forwardmove || + otherOwner->client->pers.cmd.rightmove) + { + otherDefLevel -= 1; + if (otherDefLevel < 0) + { + otherDefLevel = 0; + } + } + AngleVectors(otherOwner->client->ps.viewangles, fwd, NULL, NULL); - if (otherOwner->client->ps.fd.forcePowerLevel[FP_SABERDEFEND] == FORCE_LEVEL_1) + if (otherDefLevel == FORCE_LEVEL_1) { //if def is only level 1, instead of deflecting the shot it should just die here } - else if (otherOwner->client->ps.fd.forcePowerLevel[FP_SABERDEFEND] == FORCE_LEVEL_2) + else if (otherDefLevel == FORCE_LEVEL_2) { G_DeflectMissile(otherOwner, ent, fwd); } @@ -432,14 +456,14 @@ void G_MissileImpact( gentity_t *ent, trace_t *trace ) { { G_ReflectMissile(otherOwner, ent, fwd); } - otherOwner->client->ps.saberBlockTime = level.time + (350 - (otherOwner->client->ps.fd.forcePowerLevel[FP_SABERDEFEND]*100));//200; + otherOwner->client->ps.saberBlockTime = level.time + (350 - (otherDefLevel*100));//200; - if (otherOwner->client->ps.fd.forcePowerLevel[FP_SABERDEFEND] == FORCE_LEVEL_3) + if (otherDefLevel == FORCE_LEVEL_3) { otherOwner->client->ps.saberBlockTime = 0; //^_^ } - if (otherOwner->client->ps.fd.forcePowerLevel[FP_SABERDEFEND] == FORCE_LEVEL_1) + if (otherDefLevel == FORCE_LEVEL_1) { goto killProj; } diff --git a/CODEmp/game/g_mover.c b/CODE-mp/game/g_mover.c similarity index 100% rename from CODEmp/game/g_mover.c rename to CODE-mp/game/g_mover.c diff --git a/CODEmp/game/g_object.c b/CODE-mp/game/g_object.c similarity index 100% rename from CODEmp/game/g_object.c rename to CODE-mp/game/g_object.c diff --git a/CODEmp/game/g_public.h b/CODE-mp/game/g_public.h similarity index 95% rename from CODEmp/game/g_public.h rename to CODE-mp/game/g_public.h index cd8d6de..3823028 100644 --- a/CODEmp/game/g_public.h +++ b/CODE-mp/game/g_public.h @@ -61,6 +61,12 @@ typedef struct { // ent->s.ownerNum = passEntityNum (don't interact with your own missiles) // entity[ent->s.ownerNum].ownerNum = passEntityNum (don't interact with other missiles from owner) int ownerNum; + + // mask of clients that this entity should be broadcast too. The first 32 clients + // are represented by the first array index and the latter 32 clients are represented + // by the second array index. + int broadcastClients[2]; + } entityShared_t; diff --git a/CODEmp/game/g_saga.c b/CODE-mp/game/g_saga.c similarity index 100% rename from CODEmp/game/g_saga.c rename to CODE-mp/game/g_saga.c diff --git a/CODEmp/game/g_session.c b/CODE-mp/game/g_session.c similarity index 86% rename from CODEmp/game/g_session.c rename to CODE-mp/game/g_session.c index 5f1da0d..aaa32b9 100644 --- a/CODEmp/game/g_session.c +++ b/CODE-mp/game/g_session.c @@ -24,14 +24,17 @@ void G_WriteClientSessionData( gclient_t *client ) { const char *s; const char *var; - s = va("%i %i %i %i %i %i %i", + s = va("%i %i %i %i %i %i %i %i %i %i", client->sess.sessionTeam, client->sess.spectatorTime, client->sess.spectatorState, client->sess.spectatorClient, client->sess.wins, client->sess.losses, - client->sess.teamLeader + client->sess.teamLeader, + client->sess.setForce, + client->sess.saberLevel, + client->sess.selectedFP ); var = va( "session%i", client - level.clients ); @@ -58,20 +61,26 @@ void G_ReadSessionData( gclient_t *client ) { var = va( "session%i", client - level.clients ); trap_Cvar_VariableStringBuffer( var, s, sizeof(s) ); - sscanf( s, "%i %i %i %i %i %i %i", + sscanf( s, "%i %i %i %i %i %i %i %i %i %i", &sessionTeam, // bk010221 - format &client->sess.spectatorTime, &spectatorState, // bk010221 - format &client->sess.spectatorClient, &client->sess.wins, &client->sess.losses, - &teamLeader // bk010221 - format + &teamLeader, // bk010221 - format + &client->sess.setForce, + &client->sess.saberLevel, + &client->sess.selectedFP ); // bk001205 - format issues client->sess.sessionTeam = (team_t)sessionTeam; client->sess.spectatorState = (spectatorState_t)spectatorState; client->sess.teamLeader = (qboolean)teamLeader; + + client->ps.fd.saberAnimLevel = client->sess.saberLevel; + client->ps.fd.forcePowerSelected = client->sess.selectedFP; } diff --git a/CODEmp/game/g_spawn.c b/CODE-mp/game/g_spawn.c similarity index 100% rename from CODEmp/game/g_spawn.c rename to CODE-mp/game/g_spawn.c diff --git a/CODEmp/game/g_svcmds.c b/CODE-mp/game/g_svcmds.c similarity index 100% rename from CODEmp/game/g_svcmds.c rename to CODE-mp/game/g_svcmds.c diff --git a/CODEmp/game/g_syscalls.c b/CODE-mp/game/g_syscalls.c similarity index 100% rename from CODEmp/game/g_syscalls.c rename to CODE-mp/game/g_syscalls.c diff --git a/CODEmp/game/g_target.c b/CODE-mp/game/g_target.c similarity index 100% rename from CODEmp/game/g_target.c rename to CODE-mp/game/g_target.c diff --git a/CODEmp/game/g_team.c b/CODE-mp/game/g_team.c similarity index 100% rename from CODEmp/game/g_team.c rename to CODE-mp/game/g_team.c diff --git a/CODEmp/game/g_team.h b/CODE-mp/game/g_team.h similarity index 100% rename from CODEmp/game/g_team.h rename to CODE-mp/game/g_team.h diff --git a/CODEmp/game/g_trigger.c b/CODE-mp/game/g_trigger.c similarity index 100% rename from CODEmp/game/g_trigger.c rename to CODE-mp/game/g_trigger.c diff --git a/CODEmp/game/g_utils.c b/CODE-mp/game/g_utils.c similarity index 100% rename from CODEmp/game/g_utils.c rename to CODE-mp/game/g_utils.c diff --git a/CODEmp/game/g_weapon.c b/CODE-mp/game/g_weapon.c similarity index 94% rename from CODEmp/game/g_weapon.c rename to CODE-mp/game/g_weapon.c index e2dacc9..0b38841 100644 --- a/CODEmp/game/g_weapon.c +++ b/CODE-mp/game/g_weapon.c @@ -72,7 +72,7 @@ static vec3_t muzzle; //--------- #define FLECHETTE_SHOTS 6 #define FLECHETTE_SPREAD 4.0f -#define FLECHETTE_DAMAGE 15 +#define FLECHETTE_DAMAGE 10//15 #define FLECHETTE_VEL 3500 #define FLECHETTE_SIZE 1 #define FLECHETTE_MINE_RADIUS_CHECK 256 @@ -549,9 +549,9 @@ void WP_DisruptorAltFire( gentity_t *ent ) { count = 1; } - else if ( count >= 30 ) + else if ( count >= 60 ) { - count = 30; + count = 60; fullCharge = qtrue; } @@ -644,7 +644,7 @@ void WP_DisruptorAltFire( gentity_t *ent ) if ( traceEnt->takedamage ) { G_Damage( traceEnt, ent, ent, forward, tr.endpos, damage, - DAMAGE_NO_KNOCKBACK|DAMAGE_HALF_ARMOR_REDUCTION, MOD_DISRUPTOR_SNIPER ); + DAMAGE_NO_KNOCKBACK/*|DAMAGE_HALF_ARMOR_REDUCTION*/, MOD_DISRUPTOR_SNIPER ); tent = G_TempEntity( tr.endpos, EV_DISRUPTOR_HIT ); tent->s.eventParm = DirToByte( tr.plane.normal ); @@ -958,10 +958,24 @@ void DEMP2_AltRadiusDamage( gentity_t *ent ) gentity_t *gent; int iEntityList[MAX_GENTITIES]; gentity_t *entityList[MAX_GENTITIES]; + gentity_t *myOwner = NULL; int numListedEntities, i, e; vec3_t mins, maxs; vec3_t v, dir; + if (ent->r.ownerNum >= 0 && + ent->r.ownerNum < MAX_CLIENTS) + { + myOwner = &g_entities[ent->r.ownerNum]; + } + + if (!myOwner || !myOwner->inuse || !myOwner->client) + { + ent->think = G_FreeEntity; + ent->nextthink = level.time; + return; + } + frac *= frac * frac; // yes, this is completely ridiculous...but it causes the shell to grow slowly then "explode" at the end radius = frac * 200.0f; // 200 is max radius...the model is aprox. 100 units tall...the fx draw code mults. this by 2. @@ -1040,7 +1054,7 @@ void DEMP2_AltRadiusDamage( gentity_t *ent ) // push the center of mass higher than the origin so players get knocked into the air more dir[2] += 12; - G_Damage( gent, NULL, ent, dir, ent->r.currentOrigin, ent->damage, DAMAGE_DEATH_KNOCKBACK, ent->splashMethodOfDeath ); + G_Damage( gent, myOwner, myOwner, dir, ent->r.currentOrigin, ent->damage, DAMAGE_DEATH_KNOCKBACK, ent->splashMethodOfDeath ); } // store the last fraction so that next time around we can test against those things that fall between that last point and where the current shockwave edge is @@ -1065,6 +1079,10 @@ void DEMP2_AltDetonate( gentity_t *ent ) gentity_t *efEnt; G_SetOrigin( ent, ent->r.currentOrigin ); + if (!ent->pos1[0] && !ent->pos1[1] && !ent->pos1[2]) + { //don't play effect with a 0'd out directional vector + ent->pos1[1] = 1; + } //Let's just save ourself some bandwidth and play both the effect and sphere spawn in 1 event efEnt = G_PlayEffect( EFFECT_EXPLOSION_DEMP2ALT, ent->r.currentOrigin, ent->pos1 ); @@ -1145,6 +1163,8 @@ static void WP_DEMP2_AltFire( gentity_t *ent ) missile->splashMethodOfDeath = missile->methodOfDeath = MOD_DEMP2; missile->splashRadius = DEMP2_ALT_SPLASHRADIUS; + missile->r.ownerNum = ent->s.number; + missile->dflags = DAMAGE_DEATH_KNOCKBACK; missile->clipmask = MASK_SHOT | CONTENTS_LIGHTSABER; @@ -2104,6 +2124,8 @@ void VectorNPos(vec3_t in, vec3_t out) if (in[2] < 0) { out[2] = -in[2]; } else { out[2] = in[2]; } } +void DetPackBlow(gentity_t *self); + void charge_stick (gentity_t *self, gentity_t *other, trace_t *trace) { gentity_t *tent; @@ -2150,8 +2172,8 @@ void charge_stick (gentity_t *self, gentity_t *other, trace_t *trace) //FIXME: once on ground, shouldn't explode if touched by someone? //FIXME: if owner touches it again, pick it up? Or if he "uses" it? self->touch = 0; - self->think = 0; - self->nextthink = 0; + self->think = DetPackBlow; + self->nextthink = level.time + 30000; VectorClear(self->s.apos.trDelta); self->s.apos.trType = TR_STATIONARY; @@ -2195,7 +2217,7 @@ void DetPackBlow(gentity_t *self) G_RadiusDamage( self->r.currentOrigin, self->parent, self->splashDamage, self->splashRadius, self, MOD_UNKNOWN ); v[0] = 0; v[1] = 0; - v[2] = 0; + v[2] = 1; if (self->count == -1) { @@ -2210,12 +2232,16 @@ void DetPackBlow(gentity_t *self) void DetPackPain(gentity_t *self, gentity_t *attacker, int damage) { - DetPackBlow(self); + self->think = DetPackBlow; + self->nextthink = level.time + Q_irand(50, 100); + self->takedamage = qfalse; } void DetPackDie(gentity_t *self, gentity_t *inflictor, gentity_t *attacker, int damage, int mod) { - DetPackBlow(self); + self->think = DetPackBlow; + self->nextthink = level.time + Q_irand(50, 100); + self->takedamage = qfalse; } void drop_charge (gentity_t *self, vec3_t start, vec3_t dir) @@ -2306,6 +2332,15 @@ void BlowDetpacks(gentity_t *ent) } } +qboolean CheatsOn(void) +{ + if ( !g_cheats.integer ) + { + return qfalse; + } + return qtrue; +} + void WP_DropDetPack( gentity_t *ent, qboolean alt_fire ) { gentity_t *found = NULL; @@ -2360,7 +2395,10 @@ void WP_DropDetPack( gentity_t *ent, qboolean alt_fire ) } else { - G_FreeEntity( &g_entities[foundDetPacks[removeMe]] ); + if (!CheatsOn()) + { //Let them have unlimited if cheats are enabled + G_FreeEntity( &g_entities[foundDetPacks[removeMe]] ); + } } foundDetPacks[removeMe] = ENTITYNUM_NONE; trapcount--; diff --git a/CODE-mp/game/game.bat b/CODE-mp/game/game.bat new file mode 100644 index 0000000..8036ef4 --- /dev/null +++ b/CODE-mp/game/game.bat @@ -0,0 +1,99 @@ +del /q vm +mkdir vm +cd vm +set cc=lcc -A -DQ3_VM -DMISSIONPACK -S -Wf-target=bytecode -Wf-g -I..\..\cgame -I..\..\game -I..\..\ui %1 + +%cc% ../g_main.c +@if errorlevel 1 goto quit + +%cc% ../g_syscalls.c +@if errorlevel 1 goto quit + +%cc% ../bg_misc.c +@if errorlevel 1 goto quit +%cc% ../bg_lib.c +@if errorlevel 1 goto quit +%cc% ../bg_pmove.c +@if errorlevel 1 goto quit +%cc% ../bg_saber.c +@if errorlevel 1 goto quit +%cc% ../bg_slidemove.c +@if errorlevel 1 goto quit +%cc% ../bg_panimate.c +@if errorlevel 1 goto quit +%cc% ../bg_weapons.c +@if errorlevel 1 goto quit +%cc% ../q_math.c +@if errorlevel 1 goto quit +%cc% ../q_shared.c +@if errorlevel 1 goto quit + +%cc% ../ai_main.c +@if errorlevel 1 goto quit +%cc% ../ai_util.c +@if errorlevel 1 goto quit +%cc% ../ai_wpnav.c +@if errorlevel 1 goto quit + +%cc% ../g_active.c +@if errorlevel 1 goto quit + +%cc% ../g_arenas.c +@if errorlevel 1 goto quit +%cc% ../g_bot.c +@if errorlevel 1 goto quit +%cc% ../g_client.c +@if errorlevel 1 goto quit +%cc% ../g_cmds.c +@if errorlevel 1 goto quit +%cc% ../g_combat.c +@if errorlevel 1 goto quit +%cc% ../g_items.c +@if errorlevel 1 goto quit +%cc% ../g_log.c +@if errorlevel 1 goto quit +%cc% ../g_mem.c +@if errorlevel 1 goto quit +%cc% ../g_misc.c +@if errorlevel 1 goto quit +%cc% ../g_missile.c +@if errorlevel 1 goto quit +%cc% ../g_mover.c +@if errorlevel 1 goto quit +%cc% ../g_object.c +@if errorlevel 1 goto quit +%cc% ../g_saga.c +@if errorlevel 1 goto quit +%cc% ../g_session.c +@if errorlevel 1 goto quit +%cc% ../g_spawn.c +@if errorlevel 1 goto quit +%cc% ../g_svcmds.c +@if errorlevel 1 goto quit +%cc% ../g_target.c +@if errorlevel 1 goto quit +%cc% ../g_team.c +@if errorlevel 1 goto quit +%cc% ../g_trigger.c +@if errorlevel 1 goto quit +%cc% ../g_utils.c +@if errorlevel 1 goto quit +%cc% ../g_weapon.c +@if errorlevel 1 goto quit +%cc% ../w_force.c +@if errorlevel 1 goto quit +%cc% ../w_saber.c +@if errorlevel 1 goto quit + +sysmaker ../g_public.h ../g_syscalls.c ../g_syscalls.asm +@if errorlevel 1 goto quit + +q3asm -f ../game +@if errorlevel 1 goto quit + +mkdir "..\..\base\vm" +copy *.map "..\..\base\vm" +copy *.qvm "..\..\base\vm" + +:quit +cd .. diff --git a/CODE-mp/game/game.q3asm b/CODE-mp/game/game.q3asm new file mode 100644 index 0000000..a60a599 --- /dev/null +++ b/CODE-mp/game/game.q3asm @@ -0,0 +1,40 @@ +-o "jk2mpgame" + +g_main +ai_main +ai_util +ai_wpnav +bg_lib +bg_misc +bg_pmove +bg_panimate +bg_slidemove +bg_weapons +bg_saber +g_active +g_arenas +g_bot +g_client +g_cmds +g_combat +g_items +g_log +g_mem +g_misc +g_missile +g_mover +g_object +g_saga +g_session +g_spawn +g_svcmds +..\g_syscalls +g_target +g_team +g_trigger +g_utils +g_weapon +w_force +w_saber +q_math +q_shared diff --git a/CODEmp/game/inv.h b/CODE-mp/game/inv.h similarity index 100% rename from CODEmp/game/inv.h rename to CODE-mp/game/inv.h diff --git a/CODEmp/game/match.h b/CODE-mp/game/match.h similarity index 100% rename from CODEmp/game/match.h rename to CODE-mp/game/match.h diff --git a/CODE-mp/game/mssccprj.scc b/CODE-mp/game/mssccprj.scc new file mode 100644 index 0000000..5d4910b --- /dev/null +++ b/CODE-mp/game/mssccprj.scc @@ -0,0 +1,5 @@ +SCC = This is a Source Code Control file + +[JK2_game.dsp] +SCC_Aux_Path = "\\ravend\vss_projects\jk2sof2MP" +SCC_Project_Name = "$/General/code/game", VPCAAAAA diff --git a/CODEmp/game/q_math.c b/CODE-mp/game/q_math.c similarity index 100% rename from CODEmp/game/q_math.c rename to CODE-mp/game/q_math.c diff --git a/CODEmp/game/q_shared.c b/CODE-mp/game/q_shared.c similarity index 100% rename from CODEmp/game/q_shared.c rename to CODE-mp/game/q_shared.c diff --git a/CODEmp/game/q_shared.h b/CODE-mp/game/q_shared.h similarity index 93% rename from CODEmp/game/q_shared.h rename to CODE-mp/game/q_shared.h index b7c62e0..76c7b0b 100644 --- a/CODEmp/game/q_shared.h +++ b/CODE-mp/game/q_shared.h @@ -6,7 +6,7 @@ // q_shared.h -- included first by ALL program modules. // A user mod should never modify this file -#define Q3_VERSION "JK2MP: v0.54" +#define Q3_VERSION "JK2MP: v0.55" #define MAX_TEAMNAME 32 @@ -413,7 +413,8 @@ typedef enum SABER_YELLOW, SABER_GREEN, SABER_BLUE, - SABER_PURPLE + SABER_PURPLE, + NUM_SABER_COLORS } saber_colors_t; @@ -1098,24 +1099,26 @@ default values. ========================================================== */ -#define CVAR_ARCHIVE 1 // set to cause it to be saved to vars.rc - // used for system variables, not for player - // specific configurations -#define CVAR_USERINFO 2 // sent to server on connect or change -#define CVAR_SERVERINFO 4 // sent in response to front end requests -#define CVAR_SYSTEMINFO 8 // these cvars will be duplicated on all clients -#define CVAR_INIT 16 // don't allow change from console at all, - // but can be set from the command line -#define CVAR_LATCH 32 // will only change when C code next does - // a Cvar_Get(), so it can't be changed - // without proper initialization. modified - // will be set, even though the value hasn't - // changed yet -#define CVAR_ROM 64 // display only, cannot be set by user at all -#define CVAR_USER_CREATED 128 // created by a set command -#define CVAR_TEMP 256 // can be set even when cheats are disabled, but is not archived -#define CVAR_CHEAT 512 // can not be changed if cheats are disabled -#define CVAR_NORESTART 1024 // do not clear when a cvar_restart is issued +#define CVAR_ARCHIVE 0x00000001 // set to cause it to be saved to vars.rc + // used for system variables, not for player + // specific configurations +#define CVAR_USERINFO 0x00000002 // sent to server on connect or change +#define CVAR_SERVERINFO 0x00000004 // sent in response to front end requests +#define CVAR_SYSTEMINFO 0x00000008 // these cvars will be duplicated on all clients +#define CVAR_INIT 0x00000010 // don't allow change from console at all, + // but can be set from the command line +#define CVAR_LATCH 0x00000020 // will only change when C code next does + // a Cvar_Get(), so it can't be changed + // without proper initialization. modified + // will be set, even though the value hasn't + // changed yet +#define CVAR_ROM 0x00000040 // display only, cannot be set by user at all (can be set by code) +#define CVAR_USER_CREATED 0x00000080 // created by a set command +#define CVAR_TEMP 0x00000100 // can be set even when cheats are disabled, but is not archived +#define CVAR_CHEAT 0x00000200 // can not be changed if cheats are disabled +#define CVAR_NORESTART 0x00000400 // do not clear when a cvar_restart is issued +#define CVAR_INTERNAL 0x00000800 // cvar won't be displayed, ever (for passwords and such) +#define CVAR_PARENTAL 0x00001000 // lets cvar system know that parental stuff needs to be updated // nothing outside the Cvar_*() functions should modify these fields! typedef struct cvar_s { @@ -1582,7 +1585,10 @@ typedef struct playerState_s { int forceHandExtend; int forceHandExtendTime; + int forceRageDrainTime; + int forceDodgeAnim; + qboolean quickerGetup; int groundTime; // time when first left ground @@ -1638,7 +1644,7 @@ typedef struct playerState_s { // #define BUTTON_ATTACK 1 //#define BUTTON_TALK 2 // displays talk balloon and disables actions -#define BUTTON_FORCEJUMP 2 //rww - might be better to just reassign this from button1 on the client.. +//#define BUTTON_FORCEJUMP 2 //rww - might be better to just reassign this from button1 on the client.. #define BUTTON_USE_HOLDABLE 4 #define BUTTON_GESTURE 8 #define BUTTON_WALKING 16 // walking can't just be infered from MOVE_RUN diff --git a/CODEmp/game/surfaceflags.h b/CODE-mp/game/surfaceflags.h similarity index 100% rename from CODEmp/game/surfaceflags.h rename to CODE-mp/game/surfaceflags.h diff --git a/CODEmp/game/syn.h b/CODE-mp/game/syn.h similarity index 100% rename from CODEmp/game/syn.h rename to CODE-mp/game/syn.h diff --git a/CODE-mp/game/vssver.scc b/CODE-mp/game/vssver.scc new file mode 100644 index 0000000..aa97145 Binary files /dev/null and b/CODE-mp/game/vssver.scc differ diff --git a/CODEmp/game/w_force.c b/CODE-mp/game/w_force.c similarity index 91% rename from CODEmp/game/w_force.c rename to CODE-mp/game/w_force.c index e0fb9a4..8b24949 100644 --- a/CODEmp/game/w_force.c +++ b/CODE-mp/game/w_force.c @@ -1,5 +1,4 @@ #include "g_local.h" -#include "bg_local.h" #include "w_saber.h" #include "ai_main.h" #include "..\ghoul2\g2.h" @@ -145,7 +144,7 @@ void WP_InitForcePowers( gentity_t *ent ) char userinfo[MAX_INFO_STRING]; char forcePowers[MAX_QPATH]; char readBuf[256]; - const char *selFP = NULL; + int lastFPKnown = -1; if (!maxRank) { //if server has no max rank, default to max (50) @@ -157,7 +156,13 @@ void WP_InitForcePowers( gentity_t *ent ) return; } - ent->client->ps.fd.saberAnimLevel = FORCE_LEVEL_1; + ent->client->ps.fd.saberAnimLevel = ent->client->sess.saberLevel; + + if (ent->client->ps.fd.saberAnimLevel < FORCE_LEVEL_1 || + ent->client->ps.fd.saberAnimLevel > FORCE_LEVEL_3) + { + ent->client->ps.fd.saberAnimLevel = FORCE_LEVEL_1; + } if (!speedLoopSound) { //so that the client configstring is already modified with this when we need it @@ -484,7 +489,7 @@ validitycheck: if (warnClient || !ent->client->sess.setForce) { //the client's rank is too high for the server and has been autocapped, so tell them - if (g_gametype.integer != GT_HOLOCRON) + if (g_gametype.integer != GT_HOLOCRON && g_gametype.integer != GT_JEDIMASTER) { gentity_t *te = G_TempEntity( vec3_origin, EV_GIVE_NEW_RANK ); @@ -518,40 +523,33 @@ validitycheck: { //err.. ent->client->ps.fd.forcePowersKnown &= ~(1 << i); } + else + { + if (i != FP_LEVITATION && i != FP_SABERATTACK && i != FP_SABERDEFEND && i != FP_SABERTHROW) + { + lastFPKnown = i; + } + } i++; } - selFP = Info_ValueForKey (userinfo, "sfp"); // "sfp" == "selected force power" - - if (selFP && selFP[0]) + if (ent->client->ps.fd.forcePowersKnown & ent->client->sess.selectedFP) { - int iFP = atoi(selFP); + ent->client->ps.fd.forcePowerSelected = ent->client->sess.selectedFP; + } - if (ent->client->ps.fd.forcePowersKnown & (1 << iFP)) + if (!(ent->client->ps.fd.forcePowersKnown & (1 << ent->client->ps.fd.forcePowerSelected))) + { + if (lastFPKnown != -1) { - ent->client->ps.fd.forcePowerSelected = iFP; + ent->client->ps.fd.forcePowerSelected = lastFPKnown; + } + else + { + ent->client->ps.fd.forcePowerSelected = 0; } } - ent->client->sess.selectedFP = ent->client->ps.fd.forcePowerSelected+1; - - selFP = Info_ValueForKey (userinfo, "sal"); // "sal" == "saber attack level" - - if (selFP && selFP[0]) - { - int iFP = atoi(selFP); - - if (iFP <= ent->client->ps.fd.forcePowerLevel[FP_SABERATTACK]) - { - ent->client->ps.fd.saberAnimLevel = iFP; - - if (ent->client->ps.fd.saberAnimLevel < FORCE_LEVEL_1) - { - ent->client->ps.fd.saberAnimLevel = FORCE_LEVEL_1; - } - } - } - ent->client->sess.saberLevel = ent->client->ps.fd.saberAnimLevel+1; } void WP_SpawnInitForcePowers( gentity_t *ent ) @@ -731,6 +729,12 @@ qboolean WP_ForcePowerUsable( gentity_t *self, forcePowers_t forcePower ) return qfalse; } + if (self->health <= 0 || self->client->ps.stats[STAT_HEALTH] <= 0 || + (self->client->ps.eFlags & EF_DEAD)) + { + return qfalse; + } + if (self->client->ps.pm_flags & PMF_FOLLOW) { //specs can't use powers through people return qfalse; @@ -1002,6 +1006,7 @@ void WP_ForcePowerStart( gentity_t *self, forcePowers_t forcePower, int override hearDist = 256; //duration = 1000; self->client->ps.fd.forcePowersActive |= ( 1 << forcePower ); + self->client->ps.powerups[PW_DISINT_4] = level.time + 60000; break; case FP_LIGHTNING: hearable = qtrue; @@ -1196,7 +1201,7 @@ void ForceTeamHeal( gentity_t *self ) { ent = &g_entities[i]; - if (ent && ent->client && self != ent && OnSameTeam(self, ent) && ent->client->ps.stats[STAT_HEALTH] < ent->client->ps.stats[STAT_MAX_HEALTH] && ForcePowerUsableOn(self, ent, FP_TEAM_HEAL)) + if (ent && ent->client && self != ent && OnSameTeam(self, ent) && ent->client->ps.stats[STAT_HEALTH] < ent->client->ps.stats[STAT_MAX_HEALTH] && ent->client->ps.stats[STAT_HEALTH] > 0 && ForcePowerUsableOn(self, ent, FP_TEAM_HEAL)) { VectorSubtract(self->client->ps.origin, ent->client->ps.origin, a); @@ -1234,16 +1239,19 @@ void ForceTeamHeal( gentity_t *self ) while (i < numpl) { - g_entities[pl[i]].client->ps.stats[STAT_HEALTH] += healthadd; - if (g_entities[pl[i]].client->ps.stats[STAT_HEALTH] > g_entities[pl[i]].client->ps.stats[STAT_MAX_HEALTH]) + if (g_entities[pl[i]].client->ps.stats[STAT_HEALTH] > 0 && + g_entities[pl[i]].health > 0) { - g_entities[pl[i]].client->ps.stats[STAT_HEALTH] = g_entities[pl[i]].client->ps.stats[STAT_MAX_HEALTH]; + g_entities[pl[i]].client->ps.stats[STAT_HEALTH] += healthadd; + if (g_entities[pl[i]].client->ps.stats[STAT_HEALTH] > g_entities[pl[i]].client->ps.stats[STAT_MAX_HEALTH]) + { + g_entities[pl[i]].client->ps.stats[STAT_HEALTH] = g_entities[pl[i]].client->ps.stats[STAT_MAX_HEALTH]; + } + + g_entities[pl[i]].health = g_entities[pl[i]].client->ps.stats[STAT_HEALTH]; + + G_Sound( &g_entities[pl[i]], CHAN_ITEM, G_SoundIndex("sound/weapons/force/teamheal.wav") ); } - - g_entities[pl[i]].health = g_entities[pl[i]].client->ps.stats[STAT_HEALTH]; - - G_Sound( &g_entities[pl[i]], CHAN_ITEM, G_SoundIndex("sound/weapons/force/teamheal.wav") ); - i++; } } @@ -1609,6 +1617,9 @@ void ForceLightning( gentity_t *self ) void ForceLightningDamage( gentity_t *self, gentity_t *traceEnt, vec3_t dir, vec3_t impactPoint ) { self->client->dangerTime = level.time; + self->client->ps.eFlags &= ~EF_INVULNERABLE; + self->client->invulnerableTimer = 0; + if ( traceEnt && traceEnt->takedamage ) { if ( traceEnt->client ) @@ -1826,6 +1837,8 @@ void ForceDrainDamage( gentity_t *self, gentity_t *traceEnt, vec3_t dir, vec3_t gentity_t *tent; self->client->dangerTime = level.time; + self->client->ps.eFlags &= ~EF_INVULNERABLE; + self->client->invulnerableTimer = 0; if ( traceEnt && traceEnt->takedamage ) { @@ -1880,7 +1893,8 @@ void ForceDrainDamage( gentity_t *self, gentity_t *traceEnt, vec3_t dir, vec3_t traceEnt->client->ps.fd.forcePower = 0; } - if (self->client->ps.stats[STAT_HEALTH] < self->client->ps.stats[STAT_MAX_HEALTH]) + if (self->client->ps.stats[STAT_HEALTH] < self->client->ps.stats[STAT_MAX_HEALTH] && + self->health > 0 && self->client->ps.stats[STAT_HEALTH] > 0) { self->health += dmg; if (self->health > self->client->ps.stats[STAT_MAX_HEALTH]) @@ -2067,7 +2081,7 @@ int ForceShootDrain( gentity_t *self ) } else*/ { - WP_ForcePowerDrain( self, FP_DRAIN, forcePowerNeeded[self->client->ps.fd.forcePowerLevel[FP_DRAIN]][FP_DRAIN]/5 ); + WP_ForcePowerDrain( self, FP_DRAIN, 1 ); } self->client->ps.fd.forcePowerRegenDebounceTime = level.time + 500; @@ -2187,7 +2201,7 @@ int WP_GetVelocityForForceJump( gentity_t *self, vec3_t jumpVel, usercmd_t *ucmd if (self->client->ps.fd.forceJumpCharge < JUMP_VELOCITY+40) { //give him at least a tiny boost from just a tap - self->client->ps.fd.forceJumpCharge = JUMP_VELOCITY+40; + self->client->ps.fd.forceJumpCharge = JUMP_VELOCITY+400; } if (self->client->ps.velocity[2] < -30) @@ -2412,7 +2426,10 @@ void ForceTelepathy(gentity_t *self) if (tr.fraction != 1.0 && tr.entityNum != ENTITYNUM_NONE && - g_entities[tr.entityNum].client) + g_entities[tr.entityNum].inuse && + g_entities[tr.entityNum].client && + g_entities[tr.entityNum].client->pers.connected && + g_entities[tr.entityNum].client->sess.sessionTeam != TEAM_SPECTATOR) { WP_AddAsMindtricked(&self->client->ps.fd, tr.entityNum); //self->client->ps.fd.forceMindtrickTargetIndex |= (1 << tr.entityNum); @@ -2465,6 +2482,16 @@ void ForceTelepathy(gentity_t *self) continue; } + if (!ent->client->pers.connected) + { + continue; + } + + if (ent->client->sess.sessionTeam == TEAM_SPECTATOR) + { + continue; + } + WP_AddAsMindtricked(&self->client->ps.fd, ent->s.number); gotAtLeastOne = qtrue; } @@ -3080,6 +3107,7 @@ void ForceThrow( gentity_t *self, qboolean pull ) push_list[x]->client->ps.forceHandExtend = HANDEXTEND_KNOCKDOWN; push_list[x]->client->ps.forceHandExtendTime = level.time + 1100; push_list[x]->client->ps.forceDodgeAnim = 0; //this toggles between 1 and 0, when it's 1 we should play the get up anim + push_list[x]->client->ps.quickerGetup = qtrue; } } } @@ -3207,6 +3235,8 @@ void ForceThrow( gentity_t *self, qboolean pull ) //attempt to break any leftover grips //if we're still in a current grip that wasn't broken by the push, it will still remain self->client->dangerTime = level.time; + self->client->ps.eFlags &= ~EF_INVULNERABLE; + self->client->invulnerableTimer = 0; if (self->client->ps.fd.forceGripBeingGripped > level.time) { @@ -3282,6 +3312,8 @@ void WP_ForcePowerStop( gentity_t *self, forcePowers_t forcePower ) } self->client->ps.fd.forceGripEntityNum = ENTITYNUM_NONE; + + self->client->ps.powerups[PW_DISINT_4] = 0; break; case FP_LIGHTNING: if ( self->client->ps.fd.forcePowerLevel[FP_LIGHTNING] < FORCE_LEVEL_2 ) @@ -3348,6 +3380,8 @@ void DoGripAction(gentity_t *self, forcePowers_t forcePower) vec3_t fwd, fwd_o, start_o, nvel; self->client->dangerTime = level.time; + self->client->ps.eFlags &= ~EF_INVULNERABLE; + self->client->invulnerableTimer = 0; gripEnt = &g_entities[self->client->ps.fd.forceGripEntityNum]; @@ -3365,25 +3399,8 @@ void DoGripAction(gentity_t *self, forcePowers_t forcePower) VectorSubtract(gripEnt->client->ps.origin, self->client->ps.origin, a); - if (VectorLength(a) > MAX_GRIP_DISTANCE || !InFront( gripEnt->client->ps.origin, self->client->ps.origin, self->client->ps.viewangles, 0.9f )) - { - WP_ForcePowerStop(self, forcePower); - self->client->ps.fd.forceGripEntityNum = ENTITYNUM_NONE; - gripEnt->client->ps.forceGripChangeMovetype = PM_NORMAL; - return; - } - trap_Trace(&tr, self->client->ps.origin, NULL, NULL, gripEnt->client->ps.origin, self->s.number, MASK_PLAYERSOLID); - if (tr.fraction != 1 && - tr.entityNum != gripEnt->s.number) - { - WP_ForcePowerStop(self, forcePower); - self->client->ps.fd.forceGripEntityNum = ENTITYNUM_NONE; - gripEnt->client->ps.forceGripChangeMovetype = PM_NORMAL; - return; - } - gripLevel = WP_AbsorbConversion(gripEnt, gripEnt->client->ps.fd.forcePowerLevel[FP_ABSORB], self, FP_GRIP, self->client->ps.fd.forcePowerLevel[FP_GRIP], forcePowerNeeded[self->client->ps.fd.forcePowerLevel[FP_GRIP]][FP_GRIP]); if (gripLevel == -1) @@ -3397,6 +3414,27 @@ void DoGripAction(gentity_t *self, forcePowers_t forcePower) return; } + if (VectorLength(a) > MAX_GRIP_DISTANCE) + { + WP_ForcePowerStop(self, forcePower); + return; + } + + if ( !InFront( gripEnt->client->ps.origin, self->client->ps.origin, self->client->ps.viewangles, 0.9f ) && + gripLevel < FORCE_LEVEL_3) + { + WP_ForcePowerStop(self, forcePower); + return; + } + + if (tr.fraction != 1 && + tr.entityNum != gripEnt->s.number && + gripLevel < FORCE_LEVEL_3) + { + WP_ForcePowerStop(self, forcePower); + return; + } + if (gripLevel == FORCE_LEVEL_1) { gripEnt->client->ps.fd.forceGripBeingGripped = level.time + 1000; @@ -3459,6 +3497,8 @@ void DoGripAction(gentity_t *self, forcePowers_t forcePower) if (gripEnt->client->ps.forceGripMoveInterval < level.time) { + float nvLen = 0; + VectorCopy(gripEnt->client->ps.origin, start_o); AngleVectors(self->client->ps.viewangles, fwd, NULL, NULL); fwd_o[0] = self->client->ps.origin[0] + fwd[0]*128; @@ -3466,19 +3506,43 @@ void DoGripAction(gentity_t *self, forcePowers_t forcePower) fwd_o[2] = self->client->ps.origin[2] + fwd[2]*128; fwd_o[2] += 16; VectorSubtract(fwd_o, start_o, nvel); - if (VectorLength(nvel) < 16) + + nvLen = VectorLength(nvel); + + if (nvLen < 16) { //within x units of desired spot VectorNormalize(nvel); gripEnt->client->ps.velocity[0] = nvel[0]*8; gripEnt->client->ps.velocity[1] = nvel[1]*8; gripEnt->client->ps.velocity[2] = nvel[2]*8; } + else if (nvLen < 64) + { + VectorNormalize(nvel); + gripEnt->client->ps.velocity[0] = nvel[0]*128; + gripEnt->client->ps.velocity[1] = nvel[1]*128; + gripEnt->client->ps.velocity[2] = nvel[2]*128; + } + else if (nvLen < 128) + { + VectorNormalize(nvel); + gripEnt->client->ps.velocity[0] = nvel[0]*256; + gripEnt->client->ps.velocity[1] = nvel[1]*256; + gripEnt->client->ps.velocity[2] = nvel[2]*256; + } + else if (nvLen < 200) + { + VectorNormalize(nvel); + gripEnt->client->ps.velocity[0] = nvel[0]*512; + gripEnt->client->ps.velocity[1] = nvel[1]*512; + gripEnt->client->ps.velocity[2] = nvel[2]*512; + } else { VectorNormalize(nvel); - gripEnt->client->ps.velocity[0] = nvel[0]*64; - gripEnt->client->ps.velocity[1] = nvel[1]*64; - gripEnt->client->ps.velocity[2] = nvel[2]*64; + gripEnt->client->ps.velocity[0] = nvel[0]*700; + gripEnt->client->ps.velocity[1] = nvel[1]*700; + gripEnt->client->ps.velocity[2] = nvel[2]*700; } gripEnt->client->ps.forceGripMoveInterval = level.time + 300; //only update velocity every 300ms, so as to avoid heavy bandwidth usage @@ -3638,6 +3702,12 @@ static void WP_ForcePowerRun( gentity_t *self, forcePowers_t forcePower, usercmd } } + if (self->health < 1 || self->client->ps.stats[STAT_HEALTH] < 1) + { + WP_ForcePowerStop( self, forcePower ); + break; + } + if (self->client->ps.fd.forceHealTime > level.time) { break; @@ -3696,11 +3766,16 @@ static void WP_ForcePowerRun( gentity_t *self, forcePowers_t forcePower, usercmd } break; case FP_RAGE: - if (self->client->ps.fd.forceRageRecoveryTime < level.time) + if (self->health < 1) + { + WP_ForcePowerStop(self, forcePower); + break; + } + if (self->client->ps.forceRageDrainTime < level.time) { int addTime = 400; - self->health -= 1; + self->health -= 2; if (self->client->ps.fd.forcePowerLevel[FP_RAGE] == FORCE_LEVEL_1) { @@ -3714,7 +3789,7 @@ static void WP_ForcePowerRun( gentity_t *self, forcePowers_t forcePower, usercmd { addTime = 400; } - self->client->ps.fd.forceRageRecoveryTime = level.time + addTime; + self->client->ps.forceRageDrainTime = level.time + addTime; } if (self->health < 1) @@ -4266,6 +4341,12 @@ void JediMasterUpdate(gentity_t *self) { self->client->ps.fd.forcePowersKnown |= (1 << i); self->client->ps.fd.forcePowerLevel[i] = FORCE_LEVEL_3; + + if (i == FP_TEAM_HEAL || i == FP_TEAM_FORCE) + { + self->client->ps.fd.forcePowersKnown &= ~(1 << i); + self->client->ps.fd.forcePowerLevel[i] = 0; + } } else { @@ -4319,6 +4400,11 @@ void WP_ForcePowersUpdate( gentity_t *self, usercmd_t *ucmd ) return; } + if (self->client->ps.fd.saberAnimLevel > self->client->ps.fd.forcePowerLevel[FP_SABERATTACK]) + { + self->client->ps.fd.saberAnimLevel = self->client->ps.fd.forcePowerLevel[FP_SABERATTACK]; + } + if (!(self->client->ps.fd.forcePowersKnown & (1 << FP_LEVITATION))) { self->client->ps.fd.forcePowersKnown |= (1 << FP_LEVITATION); @@ -4334,26 +4420,16 @@ void WP_ForcePowersUpdate( gentity_t *self, usercmd_t *ucmd ) self->client->ps.fd.forcePowerSelected = 0; } - if ( ((self->client->sess.selectedFP && self->client->sess.selectedFP != self->client->ps.fd.forcePowerSelected+1) || - (self->client->sess.saberLevel && self->client->sess.saberLevel != self->client->ps.fd.saberAnimLevel+1)) && + if ( ((self->client->sess.selectedFP != self->client->ps.fd.forcePowerSelected) || + (self->client->sess.saberLevel != self->client->ps.fd.saberAnimLevel)) && !(self->r.svFlags & SVF_BOT) ) { if (self->client->sess.updateUITime < level.time) { //a bit hackish, but we don't want the client to flood with userinfo updates if they rapidly cycle //through their force powers or saber attack levels - char userinfo[MAX_INFO_STRING]; - self->client->sess.selectedFP = self->client->ps.fd.forcePowerSelected+1; - self->client->sess.saberLevel = self->client->ps.fd.saberAnimLevel+1; - - trap_GetUserinfo( self->s.number, userinfo, sizeof( userinfo ) ); - Info_SetValueForKey(userinfo, "sfp", va("%i", self->client->ps.fd.forcePowerSelected)); - Info_SetValueForKey(userinfo, "sal", va("%i", self->client->ps.fd.saberAnimLevel)); - trap_SetUserinfo( self->s.number, userinfo ); - - //old method: - //ClientUserinfoChanged(self->s.number); - //self->client->sess.updateUITime = level.time + 500; + self->client->sess.selectedFP = self->client->ps.fd.forcePowerSelected; + self->client->sess.saberLevel = self->client->ps.fd.saberAnimLevel; } } @@ -4385,6 +4461,14 @@ void WP_ForcePowersUpdate( gentity_t *self, usercmd_t *ucmd ) self->client->ps.velocity[2] = 300; } + else if (self->client->ps.quickerGetup) + { + self->client->ps.quickerGetup = qfalse; + G_EntitySound( self, CHAN_VOICE, G_SoundIndex("*jump1.wav") ); + self->client->ps.forceDodgeAnim = 3; + self->client->ps.forceHandExtendTime = level.time + 600; + self->client->ps.velocity[2] = 200; + } else { self->client->ps.forceDodgeAnim = 1; @@ -4591,18 +4675,20 @@ void WP_ForcePowersUpdate( gentity_t *self, usercmd_t *ucmd ) if (self->client->ps.fd.forceJumpCharge && self->client->ps.groundEntityNum == ENTITYNUM_NONE && self->client->fjDidJump) { - if (ucmd->upmove < 10 && !(ucmd->buttons & BUTTON_FORCEJUMP) && (!(ucmd->buttons & BUTTON_FORCEPOWER) || self->client->ps.fd.forcePowerSelected != FP_LEVITATION)) + if (ucmd->upmove < 10 && /*!(ucmd->buttons & BUTTON_FORCEJUMP) &&*/ (!(ucmd->buttons & BUTTON_FORCEPOWER) || self->client->ps.fd.forcePowerSelected != FP_LEVITATION)) { G_MuteSound(self->client->ps.fd.killSoundEntIndex[TRACK_CHANNEL_1-50], CHAN_VOICE); self->client->ps.fd.forceJumpCharge = 0; } } - if ( /*!self->client->fjDidJump &&*/ (ucmd->buttons & BUTTON_FORCEJUMP) && !BG_HasYsalimari(g_gametype.integer, &self->client->ps) && BG_CanUseFPNow(g_gametype.integer, &self->client->ps, level.time, FP_LEVITATION) ) + /* + if ( (ucmd->buttons & BUTTON_FORCEJUMP) && !BG_HasYsalimari(g_gametype.integer, &self->client->ps) && BG_CanUseFPNow(g_gametype.integer, &self->client->ps, level.time, FP_LEVITATION) ) {//just charging up ForceJumpCharge( self, ucmd ); usingForce = qtrue; } + */ #ifndef METROID_JUMP else if ( /*!self->client->fjDidJump &&*/ (ucmd->upmove > 10) && (self->client->ps.pm_flags & PMF_JUMP_HELD) && self->client->ps.groundTime && (level.time - self->client->ps.groundTime) > 150 && !BG_HasYsalimari(g_gametype.integer, &self->client->ps) && BG_CanUseFPNow(g_gametype.integer, &self->client->ps, level.time, FP_LEVITATION)/*&& !self->client->ps.fd.forceJumpZStart*/ ) {//just charging up @@ -4615,7 +4701,7 @@ void WP_ForcePowersUpdate( gentity_t *self, usercmd_t *ucmd ) } #endif - if (!(ucmd->buttons & BUTTON_FORCEJUMP) && !(self->client->ps.pm_flags & PMF_JUMP_HELD) && self->client->ps.fd.forceJumpCharge) + if (/*!(ucmd->buttons & BUTTON_FORCEJUMP) &&*/ !(self->client->ps.pm_flags & PMF_JUMP_HELD) && self->client->ps.fd.forceJumpCharge) { if (!(ucmd->buttons & BUTTON_FORCEPOWER) || self->client->ps.fd.forcePowerSelected != FP_LEVITATION) @@ -4740,7 +4826,14 @@ void WP_ForcePowersUpdate( gentity_t *self, usercmd_t *ucmd ) { if (g_gametype.integer != GT_HOLOCRON || g_MaxHolocronCarry.value) { - WP_ForcePowerRegenerate( self, 0 ); + if (self->client->ps.isJediMaster && g_gametype.integer == GT_JEDIMASTER) + { + WP_ForcePowerRegenerate( self, 4 ); //jedi master regenerates 4 times as fast + } + else + { + WP_ForcePowerRegenerate( self, 0 ); + } } else { //regenerate based on the number of holocrons carried diff --git a/CODEmp/game/w_saber.c b/CODE-mp/game/w_saber.c similarity index 91% rename from CODEmp/game/w_saber.c rename to CODE-mp/game/w_saber.c index b1b29f3..bd4d8f4 100644 --- a/CODEmp/game/w_saber.c +++ b/CODE-mp/game/w_saber.c @@ -1,5 +1,5 @@ #include "g_local.h" -#include "bg_local.h" +#include "bg_local.h" //Only because we use PM_SetAnim here once. #include "w_saber.h" #include "ai_main.h" #include "..\ghoul2\g2.h" @@ -169,26 +169,6 @@ static void G_SwingAngles( float destination, float swingTolerance, float clampT } } -qboolean G_InRoll( gentity_t *ent ) -{ - switch ( (ent->client->ps.legsAnim&~ANIM_TOGGLEBIT) ) - { - case BOTH_ROLL_F: - case BOTH_ROLL_B: - case BOTH_ROLL_R: - case BOTH_ROLL_L: - if ( ent->client->ps.legsTimer > 0 ) - { - return qtrue; - } - break; - } - return qfalse; -} - -qboolean PM_SaberInSpecial( int move ); -qboolean PM_SaberInSpecialAttack( int anim ); - //NOTE: If C` is modified this function should be modified as well (and vice versa) void G_G2ClientSpineAngles( gentity_t *ent, vec3_t viewAngles, const vec3_t angles, vec3_t thoracicAngles, vec3_t ulAngles, vec3_t llAngles ) { @@ -204,10 +184,10 @@ void G_G2ClientSpineAngles( gentity_t *ent, vec3_t viewAngles, const vec3_t angl !BG_SpinningSaberAnim( ent->client->ps.torsoAnim ) && !BG_InSpecialJump( ent->client->ps.legsAnim ) && !BG_InSpecialJump( ent->client->ps.torsoAnim ) && - !G_InRoll(ent) && - !PM_SaberInSpecial(ent->client->ps.saberMove) && - !PM_SaberInSpecialAttack(ent->client->ps.torsoAnim) && - !PM_SaberInSpecialAttack(ent->client->ps.legsAnim) ) + !BG_InRoll(&ent->client->ps, ent->client->ps.legsAnim) && + !BG_SaberInSpecial(ent->client->ps.saberMove) && + !BG_SaberInSpecialAttack(ent->client->ps.torsoAnim) && + !BG_SaberInSpecialAttack(ent->client->ps.legsAnim) ) { //adjust for motion offset mdxaBone_t boltMatrix; @@ -462,8 +442,6 @@ void G_G2PlayerAngles( gentity_t *ent, vec3_t legs[3], vec3_t legsAngles){ //trap_G2API_SetBoneAngles(ent->client->ghoul2, 0, "cranium", headAngles, BONE_ANGLES_POSTMULT, POSITIVE_Z, NEGATIVE_Y, POSITIVE_X, NULL, 0, level.time); } -qboolean PM_SaberInAttack( int move ); - qboolean SaberAttacking(gentity_t *self) { /* @@ -472,7 +450,7 @@ qboolean SaberAttacking(gentity_t *self) return qtrue; } */ - if (PM_SaberInAttack(self->client->ps.saberMove)) + if (BG_SaberInAttack(self->client->ps.saberMove)) { return qtrue; } @@ -565,8 +543,6 @@ qboolean WP_SabersCheckLock2( gentity_t *attacker, gentity_t *defender, sabersLo return qfalse; break; } -// NPC_SetAnim( attacker, SETANIM_BOTH, attAnim, SETANIM_FLAG_OVERRIDE|SETANIM_FLAG_HOLD ); -// NPC_SetAnim( defender, SETANIM_BOTH, defAnim, SETANIM_FLAG_OVERRIDE|SETANIM_FLAG_HOLD ); memset (&pmv, 0, sizeof(pmv)); pmv.ps = &attacker->client->ps; @@ -576,6 +552,7 @@ qboolean WP_SabersCheckLock2( gentity_t *attacker, gentity_t *defender, sabersLo pmv.pointcontents = trap_PointContents; pmv.gametype = g_gametype.integer; + //This is a rare exception, you should never really call PM_ utility functions from game or cgame (despite the fact that it's technically possible) pm = &pmv; PM_SetAnim(SETANIM_BOTH, attAnim, SETANIM_FLAG_OVERRIDE|SETANIM_FLAG_HOLD, 0); attacker->client->ps.saberLockFrame = attacker->client->animations[attAnim].firstFrame+(attacker->client->animations[attAnim].numFrames*0.5); @@ -594,68 +571,13 @@ qboolean WP_SabersCheckLock2( gentity_t *attacker, gentity_t *defender, sabersLo attacker->client->ps.saberLockAdvance = qfalse; defender->client->ps.saberLockAdvance = qfalse; -// if( ValidAnimFileIndex( attacker->client->clientInfo.animFileIndex ) ) - { -// anim = &level.knownAnimFileSets[attacker->client->clientInfo.animFileIndex].animations[attAnim]; -// advance = floor( anim->numFrames*attStart ); -// PM_SetAnimFrame( attacker, anim->firstFrame + advance, qtrue, qtrue ); - /* - if ( d_saberCombat->integer ) - { - Com_Printf( "%s starting saber lock, anim = %s, %d frames to go!\n", attacker->NPC_type, animTable[attAnim].name, anim->numFrames-advance ); - } - */ - } -// if( ValidAnimFileIndex( defender->client->clientInfo.animFileIndex ) ) - { -// anim = &level.knownAnimFileSets[defender->client->clientInfo.animFileIndex].animations[defAnim]; -// PM_SetAnimFrame( defender, anim->firstFrame + advance, qtrue, qtrue );//was anim->firstFrame + anim->numFrames - advance, but that's wrong since they are matched anims - /* - if ( d_saberCombat->integer ) - { - Com_Printf( "%s starting saber lock, anim = %s, %d frames to go!\n", defender->NPC_type, animTable[defAnim].name, advance ); - } - */ - } VectorClear( attacker->client->ps.velocity ); VectorClear( defender->client->ps.velocity ); attacker->client->ps.saberLockTime = defender->client->ps.saberLockTime = level.time + 10000; attacker->client->ps.saberLockEnemy = defender->s.number; defender->client->ps.saberLockEnemy = attacker->s.number; attacker->client->ps.weaponTime = defender->client->ps.weaponTime = Q_irand( 1000, 3000 );//delay 1 to 3 seconds before pushing - //MATCH ANGLES - /* - if ( attacker->NPC && defender->NPC ) - {//if 2 NPCs, just set pitch to 0 - attacker->client->ps.viewangles[PITCH] = 0; - } - else - {//if a player is involved, clamp player's pitch and match NPC's to player - if ( !attacker->s.number ) - { - if ( attacker->client->ps.viewangles[PITCH] > 50 ) - { - attacker->client->ps.viewangles[PITCH] = 50; - } - else if ( attacker->client->ps.viewangles[PITCH] < -50 ) - { - attacker->client->ps.viewangles[PITCH] = -50; - } - } - else if ( !defender->s.number ) - { - if ( defender->client->ps.viewangles[PITCH] > 50 ) - { - defender->client->ps.viewangles[PITCH] = 50; - } - else if ( defender->client->ps.viewangles[PITCH] < -50 ) - { - defender->client->ps.viewangles[PITCH] = -50; - } - attacker->client->ps.viewangles[PITCH] = defender->client->ps.viewangles[PITCH]*-1; - } - } - */ + VectorSubtract( defender->r.currentOrigin, attacker->r.currentOrigin, defDir ); VectorCopy( attacker->client->ps.viewangles, attAngles ); attAngles[YAW] = vectoyaw( defDir ); @@ -689,19 +611,20 @@ qboolean WP_SabersCheckLock2( gentity_t *attacker, gentity_t *defender, sabersLo } //DONE! - return qtrue; } -//This can only be called here because it does not reference pm -qboolean PM_InRoll( playerState_t *ps, int anim ); - qboolean WP_SabersCheckLock( gentity_t *ent1, gentity_t *ent2 ) { float dist; qboolean ent1BlockingPlayer = qfalse; qboolean ent2BlockingPlayer = qfalse; + if (!g_saberLocking.integer) + { + return qfalse; + } + if (!ent1->client || !ent2->client) { return qfalse; @@ -742,11 +665,11 @@ qboolean WP_SabersCheckLock( gentity_t *ent1, gentity_t *ent2 ) return qfalse; } - if (PM_InRoll(&ent1->client->ps, ent1->client->ps.legsAnim)) + if (BG_InRoll(&ent1->client->ps, ent1->client->ps.legsAnim)) { return qfalse; } - if (PM_InRoll(&ent2->client->ps, ent2->client->ps.legsAnim)) + if (BG_InRoll(&ent2->client->ps, ent2->client->ps.legsAnim)) { return qfalse; } @@ -1155,6 +1078,11 @@ qboolean CheckSaberDamage(gentity_t *self, vec3_t saberStart, vec3_t saberEnd, q return qfalse; } + if (dmg > 5 && self->client->ps.isJediMaster) + { //give the Jedi Master more saber attack power + dmg *= 2; + } + VectorSubtract(saberEnd, saberStart, dir); VectorNormalize(dir); @@ -1376,8 +1304,8 @@ qboolean CheckSaberDamage(gentity_t *self, vec3_t saberStart, vec3_t saberEnd, q #define MIN_SABER_SLICE_RETURN_DISTANCE 30 -#define SABER_THROWN_HIT_DAMAGE 20 -#define SABER_THROWN_RETURN_HIT_DAMAGE 15 +#define SABER_THROWN_HIT_DAMAGE 60 +#define SABER_THROWN_RETURN_HIT_DAMAGE 20 void thrownSaberTouch (gentity_t *saberent, gentity_t *other, trace_t *trace); @@ -1429,7 +1357,7 @@ void saberCheckRadiusDamage(gentity_t *saberent, int returning) if (tr.fraction == 1 || tr.entityNum == ent->s.number) { //Slice them - if (WP_SaberCanBlock(ent, tr.endpos, 0, MOD_SABER, qfalse, 0)) + if (!saberOwner->client->ps.isJediMaster && WP_SaberCanBlock(ent, tr.endpos, 0, MOD_SABER, qfalse, 0)) { te = G_TempEntity( tr.endpos, EV_SABER_BLOCK ); VectorCopy(tr.endpos, te->s.origin); @@ -1453,7 +1381,14 @@ void saberCheckRadiusDamage(gentity_t *saberent, int returning) VectorSubtract(tr.endpos, saberent->r.currentOrigin, dir); VectorNormalize(dir); - G_Damage(ent, saberOwner, saberOwner, dir, tr.endpos, saberent->damage, 0, MOD_SABER); + if (saberOwner->client->ps.isJediMaster) + { //2x damage for the Jedi Master + G_Damage(ent, saberOwner, saberOwner, dir, tr.endpos, saberent->damage*2, 0, MOD_SABER); + } + else + { + G_Damage(ent, saberOwner, saberOwner, dir, tr.endpos, saberent->damage, 0, MOD_SABER); + } te = G_TempEntity( tr.endpos, EV_SABER_HIT ); VectorCopy(tr.endpos, te->s.origin); @@ -1883,8 +1818,6 @@ runMin: G_RunObject(saberent); } -void PM_SaberStartTransAnim( int saberAnimLevel, int anim, float *animSpeed ); - void WP_SaberPositionUpdate( gentity_t *self, usercmd_t *ucmd ) { //rww - keep the saber position as updated as possible on the server so that we can try to do realistic-looking contact stuff mdxaBone_t boltMatrix; @@ -2100,6 +2033,8 @@ void WP_SaberPositionUpdate( gentity_t *self, usercmd_t *ucmd ) self->client->ps.saberDidThrowTime = level.time; self->client->dangerTime = level.time; + self->client->ps.eFlags &= ~EF_INVULNERABLE; + self->client->invulnerableTimer = 0; trap_LinkEntity(saberent); } @@ -2110,7 +2045,7 @@ void WP_SaberPositionUpdate( gentity_t *self, usercmd_t *ucmd ) } } } - else + else if (!self->client->ps.saberHolstered) { gentity_t *saberent = &g_entities[self->client->ps.saberEntityNum]; @@ -2135,7 +2070,7 @@ void WP_SaberPositionUpdate( gentity_t *self, usercmd_t *ucmd ) VectorCopy(dir, te->s.angles); te->s.eventParm = 1; - self->client->ps.saberIdleWound = level.time + 300; + self->client->ps.saberIdleWound = level.time + Q_irand(400, 600); } VectorCopy(boltOrigin, self->client->lastSaberBase); @@ -2203,9 +2138,9 @@ finalUpdate: if (!BG_FlippingAnim( self->client->ps.legsAnim ) && !BG_SpinningSaberAnim( self->client->ps.legsAnim ) && !BG_InSpecialJump( self->client->ps.legsAnim ) && - !G_InRoll(self) && - !PM_SaberInSpecial(self->client->ps.saberMove) && - !PM_SaberInSpecialAttack(self->client->ps.legsAnim) ) + !BG_InRoll(&self->client->ps, self->client->ps.legsAnim) && + !BG_SaberInSpecial(self->client->ps.saberMove) && + !BG_SaberInSpecialAttack(self->client->ps.legsAnim) ) { trap_G2API_SetBoneAnim(self->client->ghoul2, 0, "Motion", self->client->animations[legsAnim].firstFrame, self->client->animations[legsAnim].firstFrame+self->client->animations[legsAnim].numFrames, BONE_ANIM_OVERRIDE_FREEZE|BONE_ANIM_BLEND, animSpeedScale, level.time, -1, 150); } @@ -2228,7 +2163,7 @@ finalUpdate: initialFrame += 2; } - PM_SaberStartTransAnim(self->client->ps.fd.saberAnimLevel, f, &animSpeedScale); + BG_SaberStartTransAnim(self->client->ps.fd.saberAnimLevel, f, &animSpeedScale); trap_G2API_SetBoneAnim(self->client->ghoul2, 0, "upper_lumbar", initialFrame, self->client->animations[f].firstFrame+self->client->animations[f].numFrames, BONE_ANIM_OVERRIDE_FREEZE|BONE_ANIM_BLEND, animSpeedScale, level.time, initialFrame, 150); @@ -2239,9 +2174,9 @@ finalUpdate: if (!BG_FlippingAnim( self->client->ps.torsoAnim ) && !BG_SpinningSaberAnim( self->client->ps.torsoAnim ) && !BG_InSpecialJump( self->client->ps.torsoAnim ) && - !G_InRoll(self) && - !PM_SaberInSpecial(self->client->ps.saberMove) && - !PM_SaberInSpecialAttack(self->client->ps.torsoAnim) ) + !BG_InRoll(&self->client->ps, self->client->ps.legsAnim) && + !BG_SaberInSpecial(self->client->ps.saberMove) && + !BG_SaberInSpecialAttack(self->client->ps.torsoAnim) ) { trap_G2API_SetBoneAnim(self->client->ghoul2, 0, "Motion", self->client->animations[f].firstFrame, self->client->animations[f].firstFrame+self->client->animations[f].numFrames, BONE_ANIM_OVERRIDE_FREEZE|BONE_ANIM_BLEND, animSpeedScale, level.time, initialFrame, 150); } diff --git a/CODEmp/game/w_saber.h b/CODE-mp/game/w_saber.h similarity index 85% rename from CODEmp/game/w_saber.h rename to CODE-mp/game/w_saber.h index 1259b1d..d0b581b 100644 --- a/CODEmp/game/w_saber.h +++ b/CODE-mp/game/w_saber.h @@ -20,4 +20,3 @@ extern int forcePowerNeeded[NUM_FORCE_POWER_LEVELS][NUM_FORCE_POWERS]; extern float forceJumpHeight[NUM_FORCE_POWER_LEVELS]; extern float forceJumpStrength[NUM_FORCE_POWER_LEVELS]; -int InFieldOfVision(vec3_t viewangles, float fov, vec3_t angles); diff --git a/CODEmp/ghoul2/g2.h b/CODE-mp/ghoul2/G2.h similarity index 100% rename from CODEmp/ghoul2/g2.h rename to CODE-mp/ghoul2/G2.h diff --git a/CODEmp/ghoul2/g2_api.cpp b/CODE-mp/ghoul2/G2_API.cpp similarity index 100% rename from CODEmp/ghoul2/g2_api.cpp rename to CODE-mp/ghoul2/G2_API.cpp diff --git a/CODEmp/ghoul2/g2_bolts.cpp b/CODE-mp/ghoul2/G2_bolts.cpp similarity index 100% rename from CODEmp/ghoul2/g2_bolts.cpp rename to CODE-mp/ghoul2/G2_bolts.cpp diff --git a/CODEmp/ghoul2/g2_bones.cpp b/CODE-mp/ghoul2/G2_bones.cpp similarity index 100% rename from CODEmp/ghoul2/g2_bones.cpp rename to CODE-mp/ghoul2/G2_bones.cpp diff --git a/CODEmp/ghoul2/g2_gore.h b/CODE-mp/ghoul2/G2_gore.h similarity index 100% rename from CODEmp/ghoul2/g2_gore.h rename to CODE-mp/ghoul2/G2_gore.h diff --git a/CODEmp/ghoul2/g2_local.h b/CODE-mp/ghoul2/G2_local.h similarity index 100% rename from CODEmp/ghoul2/g2_local.h rename to CODE-mp/ghoul2/G2_local.h diff --git a/CODEmp/ghoul2/g2_misc.cpp b/CODE-mp/ghoul2/G2_misc.cpp similarity index 100% rename from CODEmp/ghoul2/g2_misc.cpp rename to CODE-mp/ghoul2/G2_misc.cpp diff --git a/CODEmp/ghoul2/g2_surfaces.cpp b/CODE-mp/ghoul2/G2_surfaces.cpp similarity index 100% rename from CODEmp/ghoul2/g2_surfaces.cpp rename to CODE-mp/ghoul2/G2_surfaces.cpp diff --git a/CODEmp/ghoul2/ghoul2_shared.h b/CODE-mp/ghoul2/ghoul2_shared.h similarity index 100% rename from CODEmp/ghoul2/ghoul2_shared.h rename to CODE-mp/ghoul2/ghoul2_shared.h diff --git a/CODE-mp/ghoul2/vssver.scc b/CODE-mp/ghoul2/vssver.scc new file mode 100644 index 0000000..7a1b52f Binary files /dev/null and b/CODE-mp/ghoul2/vssver.scc differ diff --git a/CODE-mp/installvms.bat b/CODE-mp/installvms.bat new file mode 100644 index 0000000..43c7700 --- /dev/null +++ b/CODE-mp/installvms.bat @@ -0,0 +1,4 @@ +xcopy/d/y release\jk2mp.exe w:\game +xcopy/d/y base\vm\cgame.* w:\game\base\vm +xcopy/d/y base\vm\jk2mpgame.* w:\game\base\vm +xcopy/d/y base\vm\ui.* w:\game\base\vm diff --git a/CODEmp/jk2mp.dsp b/CODE-mp/jk2mp.dsp similarity index 94% rename from CODEmp/jk2mp.dsp rename to CODE-mp/jk2mp.dsp index 2149e62..0366e7b 100644 --- a/CODEmp/jk2mp.dsp +++ b/CODE-mp/jk2mp.dsp @@ -1125,6 +1125,10 @@ SOURCE=.\renderer\tr_surface.cpp # End Source File # Begin Source File +SOURCE=.\renderer\tr_surfacesprites.cpp +# End Source File +# Begin Source File + SOURCE=.\cgame\tr_types.h # End Source File # Begin Source File diff --git a/CODEmp/jk2mp.dsw b/CODE-mp/jk2mp.dsw similarity index 100% rename from CODEmp/jk2mp.dsw rename to CODE-mp/jk2mp.dsw diff --git a/CODEmp/jpeg-6/jcapimin.cpp b/CODE-mp/jpeg-6/jcapimin.cpp similarity index 100% rename from CODEmp/jpeg-6/jcapimin.cpp rename to CODE-mp/jpeg-6/jcapimin.cpp diff --git a/CODEmp/jpeg-6/jccoefct.cpp b/CODE-mp/jpeg-6/jccoefct.cpp similarity index 100% rename from CODEmp/jpeg-6/jccoefct.cpp rename to CODE-mp/jpeg-6/jccoefct.cpp diff --git a/CODEmp/jpeg-6/jccolor.cpp b/CODE-mp/jpeg-6/jccolor.cpp similarity index 100% rename from CODEmp/jpeg-6/jccolor.cpp rename to CODE-mp/jpeg-6/jccolor.cpp diff --git a/CODEmp/jpeg-6/jcdctmgr.cpp b/CODE-mp/jpeg-6/jcdctmgr.cpp similarity index 100% rename from CODEmp/jpeg-6/jcdctmgr.cpp rename to CODE-mp/jpeg-6/jcdctmgr.cpp diff --git a/CODEmp/jpeg-6/jchuff.cpp b/CODE-mp/jpeg-6/jchuff.cpp similarity index 100% rename from CODEmp/jpeg-6/jchuff.cpp rename to CODE-mp/jpeg-6/jchuff.cpp diff --git a/CODEmp/jpeg-6/jchuff.h b/CODE-mp/jpeg-6/jchuff.h similarity index 100% rename from CODEmp/jpeg-6/jchuff.h rename to CODE-mp/jpeg-6/jchuff.h diff --git a/CODEmp/jpeg-6/jcinit.cpp b/CODE-mp/jpeg-6/jcinit.cpp similarity index 100% rename from CODEmp/jpeg-6/jcinit.cpp rename to CODE-mp/jpeg-6/jcinit.cpp diff --git a/CODEmp/jpeg-6/jcmainct.cpp b/CODE-mp/jpeg-6/jcmainct.cpp similarity index 100% rename from CODEmp/jpeg-6/jcmainct.cpp rename to CODE-mp/jpeg-6/jcmainct.cpp diff --git a/CODEmp/jpeg-6/jcmarker.cpp b/CODE-mp/jpeg-6/jcmarker.cpp similarity index 100% rename from CODEmp/jpeg-6/jcmarker.cpp rename to CODE-mp/jpeg-6/jcmarker.cpp diff --git a/CODEmp/jpeg-6/jcmaster.cpp b/CODE-mp/jpeg-6/jcmaster.cpp similarity index 100% rename from CODEmp/jpeg-6/jcmaster.cpp rename to CODE-mp/jpeg-6/jcmaster.cpp diff --git a/CODEmp/jpeg-6/jcomapi.cpp b/CODE-mp/jpeg-6/jcomapi.cpp similarity index 100% rename from CODEmp/jpeg-6/jcomapi.cpp rename to CODE-mp/jpeg-6/jcomapi.cpp diff --git a/CODEmp/jpeg-6/jconfig.h b/CODE-mp/jpeg-6/jconfig.h similarity index 100% rename from CODEmp/jpeg-6/jconfig.h rename to CODE-mp/jpeg-6/jconfig.h diff --git a/CODEmp/jpeg-6/jcparam.cpp b/CODE-mp/jpeg-6/jcparam.cpp similarity index 100% rename from CODEmp/jpeg-6/jcparam.cpp rename to CODE-mp/jpeg-6/jcparam.cpp diff --git a/CODEmp/jpeg-6/jcphuff.cpp b/CODE-mp/jpeg-6/jcphuff.cpp similarity index 100% rename from CODEmp/jpeg-6/jcphuff.cpp rename to CODE-mp/jpeg-6/jcphuff.cpp diff --git a/CODEmp/jpeg-6/jcprepct.cpp b/CODE-mp/jpeg-6/jcprepct.cpp similarity index 100% rename from CODEmp/jpeg-6/jcprepct.cpp rename to CODE-mp/jpeg-6/jcprepct.cpp diff --git a/CODEmp/jpeg-6/jcsample.cpp b/CODE-mp/jpeg-6/jcsample.cpp similarity index 100% rename from CODEmp/jpeg-6/jcsample.cpp rename to CODE-mp/jpeg-6/jcsample.cpp diff --git a/CODEmp/jpeg-6/jctrans.cpp b/CODE-mp/jpeg-6/jctrans.cpp similarity index 100% rename from CODEmp/jpeg-6/jctrans.cpp rename to CODE-mp/jpeg-6/jctrans.cpp diff --git a/CODEmp/jpeg-6/jdapimin.cpp b/CODE-mp/jpeg-6/jdapimin.cpp similarity index 100% rename from CODEmp/jpeg-6/jdapimin.cpp rename to CODE-mp/jpeg-6/jdapimin.cpp diff --git a/CODEmp/jpeg-6/jdapistd.cpp b/CODE-mp/jpeg-6/jdapistd.cpp similarity index 100% rename from CODEmp/jpeg-6/jdapistd.cpp rename to CODE-mp/jpeg-6/jdapistd.cpp diff --git a/CODEmp/jpeg-6/jdatadst.cpp b/CODE-mp/jpeg-6/jdatadst.cpp similarity index 100% rename from CODEmp/jpeg-6/jdatadst.cpp rename to CODE-mp/jpeg-6/jdatadst.cpp diff --git a/CODEmp/jpeg-6/jdatasrc.cpp b/CODE-mp/jpeg-6/jdatasrc.cpp similarity index 100% rename from CODEmp/jpeg-6/jdatasrc.cpp rename to CODE-mp/jpeg-6/jdatasrc.cpp diff --git a/CODEmp/jpeg-6/jdcoefct.cpp b/CODE-mp/jpeg-6/jdcoefct.cpp similarity index 100% rename from CODEmp/jpeg-6/jdcoefct.cpp rename to CODE-mp/jpeg-6/jdcoefct.cpp diff --git a/CODEmp/jpeg-6/jdcolor.cpp b/CODE-mp/jpeg-6/jdcolor.cpp similarity index 100% rename from CODEmp/jpeg-6/jdcolor.cpp rename to CODE-mp/jpeg-6/jdcolor.cpp diff --git a/CODEmp/jpeg-6/jdct.h b/CODE-mp/jpeg-6/jdct.h similarity index 100% rename from CODEmp/jpeg-6/jdct.h rename to CODE-mp/jpeg-6/jdct.h diff --git a/CODEmp/jpeg-6/jddctmgr.cpp b/CODE-mp/jpeg-6/jddctmgr.cpp similarity index 100% rename from CODEmp/jpeg-6/jddctmgr.cpp rename to CODE-mp/jpeg-6/jddctmgr.cpp diff --git a/CODEmp/jpeg-6/jdhuff.cpp b/CODE-mp/jpeg-6/jdhuff.cpp similarity index 100% rename from CODEmp/jpeg-6/jdhuff.cpp rename to CODE-mp/jpeg-6/jdhuff.cpp diff --git a/CODEmp/jpeg-6/jdhuff.h b/CODE-mp/jpeg-6/jdhuff.h similarity index 100% rename from CODEmp/jpeg-6/jdhuff.h rename to CODE-mp/jpeg-6/jdhuff.h diff --git a/CODEmp/jpeg-6/jdinput.cpp b/CODE-mp/jpeg-6/jdinput.cpp similarity index 100% rename from CODEmp/jpeg-6/jdinput.cpp rename to CODE-mp/jpeg-6/jdinput.cpp diff --git a/CODEmp/jpeg-6/jdmainct.cpp b/CODE-mp/jpeg-6/jdmainct.cpp similarity index 100% rename from CODEmp/jpeg-6/jdmainct.cpp rename to CODE-mp/jpeg-6/jdmainct.cpp diff --git a/CODEmp/jpeg-6/jdmarker.cpp b/CODE-mp/jpeg-6/jdmarker.cpp similarity index 100% rename from CODEmp/jpeg-6/jdmarker.cpp rename to CODE-mp/jpeg-6/jdmarker.cpp diff --git a/CODEmp/jpeg-6/jdmaster.cpp b/CODE-mp/jpeg-6/jdmaster.cpp similarity index 100% rename from CODEmp/jpeg-6/jdmaster.cpp rename to CODE-mp/jpeg-6/jdmaster.cpp diff --git a/CODEmp/jpeg-6/jdpostct.cpp b/CODE-mp/jpeg-6/jdpostct.cpp similarity index 100% rename from CODEmp/jpeg-6/jdpostct.cpp rename to CODE-mp/jpeg-6/jdpostct.cpp diff --git a/CODEmp/jpeg-6/jdsample.cpp b/CODE-mp/jpeg-6/jdsample.cpp similarity index 100% rename from CODEmp/jpeg-6/jdsample.cpp rename to CODE-mp/jpeg-6/jdsample.cpp diff --git a/CODEmp/jpeg-6/jdtrans.cpp b/CODE-mp/jpeg-6/jdtrans.cpp similarity index 100% rename from CODEmp/jpeg-6/jdtrans.cpp rename to CODE-mp/jpeg-6/jdtrans.cpp diff --git a/CODEmp/jpeg-6/jerror.cpp b/CODE-mp/jpeg-6/jerror.cpp similarity index 100% rename from CODEmp/jpeg-6/jerror.cpp rename to CODE-mp/jpeg-6/jerror.cpp diff --git a/CODEmp/jpeg-6/jerror.h b/CODE-mp/jpeg-6/jerror.h similarity index 100% rename from CODEmp/jpeg-6/jerror.h rename to CODE-mp/jpeg-6/jerror.h diff --git a/CODEmp/jpeg-6/jfdctflt.cpp b/CODE-mp/jpeg-6/jfdctflt.cpp similarity index 100% rename from CODEmp/jpeg-6/jfdctflt.cpp rename to CODE-mp/jpeg-6/jfdctflt.cpp diff --git a/CODEmp/jpeg-6/jidctflt.cpp b/CODE-mp/jpeg-6/jidctflt.cpp similarity index 100% rename from CODEmp/jpeg-6/jidctflt.cpp rename to CODE-mp/jpeg-6/jidctflt.cpp diff --git a/CODEmp/jpeg-6/jinclude.h b/CODE-mp/jpeg-6/jinclude.h similarity index 100% rename from CODEmp/jpeg-6/jinclude.h rename to CODE-mp/jpeg-6/jinclude.h diff --git a/CODEmp/jpeg-6/jmemmgr.cpp b/CODE-mp/jpeg-6/jmemmgr.cpp similarity index 100% rename from CODEmp/jpeg-6/jmemmgr.cpp rename to CODE-mp/jpeg-6/jmemmgr.cpp diff --git a/CODEmp/jpeg-6/jmemnobs.cpp b/CODE-mp/jpeg-6/jmemnobs.cpp similarity index 100% rename from CODEmp/jpeg-6/jmemnobs.cpp rename to CODE-mp/jpeg-6/jmemnobs.cpp diff --git a/CODEmp/jpeg-6/jmemsys.h b/CODE-mp/jpeg-6/jmemsys.h similarity index 100% rename from CODEmp/jpeg-6/jmemsys.h rename to CODE-mp/jpeg-6/jmemsys.h diff --git a/CODEmp/jpeg-6/jmorecfg.h b/CODE-mp/jpeg-6/jmorecfg.h similarity index 100% rename from CODEmp/jpeg-6/jmorecfg.h rename to CODE-mp/jpeg-6/jmorecfg.h diff --git a/CODEmp/jpeg-6/jpegint.h b/CODE-mp/jpeg-6/jpegint.h similarity index 100% rename from CODEmp/jpeg-6/jpegint.h rename to CODE-mp/jpeg-6/jpegint.h diff --git a/CODEmp/jpeg-6/jpeglib.h b/CODE-mp/jpeg-6/jpeglib.h similarity index 100% rename from CODEmp/jpeg-6/jpeglib.h rename to CODE-mp/jpeg-6/jpeglib.h diff --git a/CODEmp/jpeg-6/jutils.cpp b/CODE-mp/jpeg-6/jutils.cpp similarity index 100% rename from CODEmp/jpeg-6/jutils.cpp rename to CODE-mp/jpeg-6/jutils.cpp diff --git a/CODEmp/jpeg-6/jversion.h b/CODE-mp/jpeg-6/jversion.h similarity index 100% rename from CODEmp/jpeg-6/jversion.h rename to CODE-mp/jpeg-6/jversion.h diff --git a/CODE-mp/jpeg-6/vssver.scc b/CODE-mp/jpeg-6/vssver.scc new file mode 100644 index 0000000..0f669ce Binary files /dev/null and b/CODE-mp/jpeg-6/vssver.scc differ diff --git a/CODEmp/mp3code/cdct.c b/CODE-mp/mp3code/cdct.c similarity index 100% rename from CODEmp/mp3code/cdct.c rename to CODE-mp/mp3code/cdct.c diff --git a/CODEmp/mp3code/config.h b/CODE-mp/mp3code/config.h similarity index 100% rename from CODEmp/mp3code/config.h rename to CODE-mp/mp3code/config.h diff --git a/CODEmp/mp3code/copyright.h b/CODE-mp/mp3code/copyright.h similarity index 100% rename from CODEmp/mp3code/copyright.h rename to CODE-mp/mp3code/copyright.h diff --git a/CODEmp/mp3code/csbt.c b/CODE-mp/mp3code/csbt.c similarity index 100% rename from CODEmp/mp3code/csbt.c rename to CODE-mp/mp3code/csbt.c diff --git a/CODEmp/mp3code/csbtb.c b/CODE-mp/mp3code/csbtb.c similarity index 100% rename from CODEmp/mp3code/csbtb.c rename to CODE-mp/mp3code/csbtb.c diff --git a/CODEmp/mp3code/csbtl3.c b/CODE-mp/mp3code/csbtl3.c similarity index 100% rename from CODEmp/mp3code/csbtl3.c rename to CODE-mp/mp3code/csbtl3.c diff --git a/CODEmp/mp3code/cup.c b/CODE-mp/mp3code/cup.c similarity index 100% rename from CODEmp/mp3code/cup.c rename to CODE-mp/mp3code/cup.c diff --git a/CODEmp/mp3code/cupini.c b/CODE-mp/mp3code/cupini.c similarity index 100% rename from CODEmp/mp3code/cupini.c rename to CODE-mp/mp3code/cupini.c diff --git a/CODEmp/mp3code/cupl1.c b/CODE-mp/mp3code/cupl1.c similarity index 100% rename from CODEmp/mp3code/cupl1.c rename to CODE-mp/mp3code/cupl1.c diff --git a/CODEmp/mp3code/cupl3.c b/CODE-mp/mp3code/cupl3.c similarity index 100% rename from CODEmp/mp3code/cupl3.c rename to CODE-mp/mp3code/cupl3.c diff --git a/CODEmp/mp3code/cwin.c b/CODE-mp/mp3code/cwin.c similarity index 100% rename from CODEmp/mp3code/cwin.c rename to CODE-mp/mp3code/cwin.c diff --git a/CODEmp/mp3code/cwinb.c b/CODE-mp/mp3code/cwinb.c similarity index 100% rename from CODEmp/mp3code/cwinb.c rename to CODE-mp/mp3code/cwinb.c diff --git a/CODEmp/mp3code/cwinm.c b/CODE-mp/mp3code/cwinm.c similarity index 100% rename from CODEmp/mp3code/cwinm.c rename to CODE-mp/mp3code/cwinm.c diff --git a/CODEmp/mp3code/htable.h b/CODE-mp/mp3code/htable.h similarity index 100% rename from CODEmp/mp3code/htable.h rename to CODE-mp/mp3code/htable.h diff --git a/CODEmp/mp3code/hwin.c b/CODE-mp/mp3code/hwin.c similarity index 100% rename from CODEmp/mp3code/hwin.c rename to CODE-mp/mp3code/hwin.c diff --git a/CODEmp/mp3code/jdw.h b/CODE-mp/mp3code/jdw.h similarity index 100% rename from CODEmp/mp3code/jdw.h rename to CODE-mp/mp3code/jdw.h diff --git a/CODEmp/mp3code/l3.h b/CODE-mp/mp3code/l3.h similarity index 100% rename from CODEmp/mp3code/l3.h rename to CODE-mp/mp3code/l3.h diff --git a/CODEmp/mp3code/l3dq.c b/CODE-mp/mp3code/l3dq.c similarity index 100% rename from CODEmp/mp3code/l3dq.c rename to CODE-mp/mp3code/l3dq.c diff --git a/CODEmp/mp3code/l3init.c b/CODE-mp/mp3code/l3init.c similarity index 100% rename from CODEmp/mp3code/l3init.c rename to CODE-mp/mp3code/l3init.c diff --git a/CODEmp/mp3code/mdct.c b/CODE-mp/mp3code/mdct.c similarity index 100% rename from CODEmp/mp3code/mdct.c rename to CODE-mp/mp3code/mdct.c diff --git a/CODEmp/mp3code/mhead.c b/CODE-mp/mp3code/mhead.c similarity index 100% rename from CODEmp/mp3code/mhead.c rename to CODE-mp/mp3code/mhead.c diff --git a/CODEmp/mp3code/mhead.h b/CODE-mp/mp3code/mhead.h similarity index 100% rename from CODEmp/mp3code/mhead.h rename to CODE-mp/mp3code/mhead.h diff --git a/CODEmp/mp3code/mp3struct.h b/CODE-mp/mp3code/mp3struct.h similarity index 100% rename from CODEmp/mp3code/mp3struct.h rename to CODE-mp/mp3code/mp3struct.h diff --git a/CODEmp/mp3code/msis.c b/CODE-mp/mp3code/msis.c similarity index 100% rename from CODEmp/mp3code/msis.c rename to CODE-mp/mp3code/msis.c diff --git a/CODEmp/mp3code/port.h b/CODE-mp/mp3code/port.h similarity index 100% rename from CODEmp/mp3code/port.h rename to CODE-mp/mp3code/port.h diff --git a/CODEmp/mp3code/small_header.h b/CODE-mp/mp3code/small_header.h similarity index 100% rename from CODEmp/mp3code/small_header.h rename to CODE-mp/mp3code/small_header.h diff --git a/CODEmp/mp3code/tableawd.h b/CODE-mp/mp3code/tableawd.h similarity index 100% rename from CODEmp/mp3code/tableawd.h rename to CODE-mp/mp3code/tableawd.h diff --git a/CODEmp/mp3code/towave.c b/CODE-mp/mp3code/towave.c similarity index 100% rename from CODEmp/mp3code/towave.c rename to CODE-mp/mp3code/towave.c diff --git a/CODEmp/mp3code/uph.c b/CODE-mp/mp3code/uph.c similarity index 100% rename from CODEmp/mp3code/uph.c rename to CODE-mp/mp3code/uph.c diff --git a/CODEmp/mp3code/upsf.c b/CODE-mp/mp3code/upsf.c similarity index 100% rename from CODEmp/mp3code/upsf.c rename to CODE-mp/mp3code/upsf.c diff --git a/CODE-mp/mp3code/vssver.scc b/CODE-mp/mp3code/vssver.scc new file mode 100644 index 0000000..92aab9a Binary files /dev/null and b/CODE-mp/mp3code/vssver.scc differ diff --git a/CODEmp/mp3code/wavep.c b/CODE-mp/mp3code/wavep.c similarity index 100% rename from CODEmp/mp3code/wavep.c rename to CODE-mp/mp3code/wavep.c diff --git a/CODE-mp/mssccprj.scc b/CODE-mp/mssccprj.scc new file mode 100644 index 0000000..3ec70d1 --- /dev/null +++ b/CODE-mp/mssccprj.scc @@ -0,0 +1,5 @@ +SCC = This is a Source Code Control file + +[jk2mp.dsp] +SCC_Aux_Path = "\\ravend\vss_projects\jk2sof2MP" +SCC_Project_Name = "$/General/code", EAAAAAAA diff --git a/CODEmp/png/png.cpp b/CODE-mp/png/png.cpp similarity index 100% rename from CODEmp/png/png.cpp rename to CODE-mp/png/png.cpp diff --git a/CODEmp/png/png.h b/CODE-mp/png/png.h similarity index 100% rename from CODEmp/png/png.h rename to CODE-mp/png/png.h diff --git a/CODE-mp/png/vssver.scc b/CODE-mp/png/vssver.scc new file mode 100644 index 0000000..9f270ba Binary files /dev/null and b/CODE-mp/png/vssver.scc differ diff --git a/CODE-mp/put.bat b/CODE-mp/put.bat new file mode 100644 index 0000000..ae62aae --- /dev/null +++ b/CODE-mp/put.bat @@ -0,0 +1,2 @@ +xcopy /d /y release\*.dll w:\game +xcopy /d /y release\jk2mp.exe w:\game\ diff --git a/CODEmp/qcommon/genericparser2.cpp b/CODE-mp/qcommon/GenericParser2.cpp similarity index 100% rename from CODEmp/qcommon/genericparser2.cpp rename to CODE-mp/qcommon/GenericParser2.cpp diff --git a/CODEmp/qcommon/genericparser2.h b/CODE-mp/qcommon/GenericParser2.h similarity index 100% rename from CODEmp/qcommon/genericparser2.h rename to CODE-mp/qcommon/GenericParser2.h diff --git a/CODEmp/qcommon/miniheap.h b/CODE-mp/qcommon/MiniHeap.h similarity index 100% rename from CODEmp/qcommon/miniheap.h rename to CODE-mp/qcommon/MiniHeap.h diff --git a/CODEmp/qcommon/roffsystem.cpp b/CODE-mp/qcommon/RoffSystem.cpp similarity index 100% rename from CODEmp/qcommon/roffsystem.cpp rename to CODE-mp/qcommon/RoffSystem.cpp diff --git a/CODEmp/qcommon/roffsystem.h b/CODE-mp/qcommon/RoffSystem.h similarity index 100% rename from CODEmp/qcommon/roffsystem.h rename to CODE-mp/qcommon/RoffSystem.h diff --git a/CODEmp/qcommon/chash.h b/CODE-mp/qcommon/chash.h similarity index 100% rename from CODEmp/qcommon/chash.h rename to CODE-mp/qcommon/chash.h diff --git a/CODEmp/qcommon/cm_load.cpp b/CODE-mp/qcommon/cm_load.cpp similarity index 100% rename from CODEmp/qcommon/cm_load.cpp rename to CODE-mp/qcommon/cm_load.cpp diff --git a/CODEmp/qcommon/cm_local.h b/CODE-mp/qcommon/cm_local.h similarity index 100% rename from CODEmp/qcommon/cm_local.h rename to CODE-mp/qcommon/cm_local.h diff --git a/CODEmp/qcommon/cm_patch.cpp b/CODE-mp/qcommon/cm_patch.cpp similarity index 100% rename from CODEmp/qcommon/cm_patch.cpp rename to CODE-mp/qcommon/cm_patch.cpp diff --git a/CODEmp/qcommon/cm_patch.h b/CODE-mp/qcommon/cm_patch.h similarity index 100% rename from CODEmp/qcommon/cm_patch.h rename to CODE-mp/qcommon/cm_patch.h diff --git a/CODEmp/qcommon/cm_polylib.cpp b/CODE-mp/qcommon/cm_polylib.cpp similarity index 100% rename from CODEmp/qcommon/cm_polylib.cpp rename to CODE-mp/qcommon/cm_polylib.cpp diff --git a/CODEmp/qcommon/cm_polylib.h b/CODE-mp/qcommon/cm_polylib.h similarity index 100% rename from CODEmp/qcommon/cm_polylib.h rename to CODE-mp/qcommon/cm_polylib.h diff --git a/CODEmp/qcommon/cm_public.h b/CODE-mp/qcommon/cm_public.h similarity index 100% rename from CODEmp/qcommon/cm_public.h rename to CODE-mp/qcommon/cm_public.h diff --git a/CODEmp/qcommon/cm_shader.cpp b/CODE-mp/qcommon/cm_shader.cpp similarity index 100% rename from CODEmp/qcommon/cm_shader.cpp rename to CODE-mp/qcommon/cm_shader.cpp diff --git a/CODEmp/qcommon/cm_test.cpp b/CODE-mp/qcommon/cm_test.cpp similarity index 100% rename from CODEmp/qcommon/cm_test.cpp rename to CODE-mp/qcommon/cm_test.cpp diff --git a/CODEmp/qcommon/cm_trace.cpp b/CODE-mp/qcommon/cm_trace.cpp similarity index 100% rename from CODEmp/qcommon/cm_trace.cpp rename to CODE-mp/qcommon/cm_trace.cpp diff --git a/CODEmp/qcommon/cmd.cpp b/CODE-mp/qcommon/cmd.cpp similarity index 100% rename from CODEmp/qcommon/cmd.cpp rename to CODE-mp/qcommon/cmd.cpp diff --git a/CODEmp/qcommon/common.cpp b/CODE-mp/qcommon/common.cpp similarity index 94% rename from CODEmp/qcommon/common.cpp rename to CODE-mp/qcommon/common.cpp index 5f46841..08f95e1 100644 --- a/CODEmp/qcommon/common.cpp +++ b/CODE-mp/qcommon/common.cpp @@ -173,6 +173,14 @@ void QDECL Com_Printf( const char *fmt, ... ) { FS_Write(msg, strlen(msg), logfile); } } + +#if defined(_WIN32) && defined(_DEBUG) + if ( *msg ) + { + OutputDebugString ( Q_CleanStr(msg) ); + OutputDebugString ("\n"); + } +#endif } @@ -870,6 +878,16 @@ void *Z_Malloc(int iSize, memtag_t eTag, qboolean bZeroit /* = qfalse */) } + // ditch any image_t's (and associated GL memory) not used on this level... + // + extern qboolean RE_RegisterImages_LevelLoadEnd(void); + if (RE_RegisterImages_LevelLoadEnd()) + { + gbMemFreeupOccured = qtrue; + continue; // we've dropped at least one image, so try again with the malloc + } + + // ditch the model-binaries cache... (must be getting desperate here!) // extern qboolean RE_RegisterModels_LevelLoadEnd(qboolean bDeleteEverythingNotUsedThisLevel); @@ -1502,8 +1520,9 @@ void Hunk_Log( void) { FS_Write(buf, strlen(buf), logfile); for (block = hunkblocks ; block; block = block->next) { #ifdef HUNK_DEBUG - Com_sprintf(buf, sizeof(buf), "size = %8d: %s, line: %d (%s)\r\n", block->size, block->file, block->line, block->label); + Com_sprintf(buf, sizeof(buf), "size\t%8d\t%s\tline\t%d\t(%s)\r\n", block->size, block->file, block->line, block->label); FS_Write(buf, strlen(buf), logfile); +// OutputDebugString(buf); #endif size += block->size; numBlocks++; @@ -2186,7 +2205,14 @@ int Com_EventLoop( void ) { CL_JoystickEvent( ev.evValue, ev.evValue2, ev.evTime ); break; case SE_CONSOLE: - Cbuf_AddText( (char *)ev.evPtr ); + if ( ((char *)ev.evPtr)[0] == '\\' || ((char *)ev.evPtr)[0] == '/' ) + { + Cbuf_AddText( (char *)ev.evPtr+1 ); + } + else + { + Cbuf_AddText( (char *)ev.evPtr ); + } Cbuf_AddText( "\n" ); break; case SE_PACKET: diff --git a/CODEmp/qcommon/cvar.cpp b/CODE-mp/qcommon/cvar.cpp similarity index 93% rename from CODEmp/qcommon/cvar.cpp rename to CODE-mp/qcommon/cvar.cpp index 6f51766..c7adddc 100644 --- a/CODEmp/qcommon/cvar.cpp +++ b/CODE-mp/qcommon/cvar.cpp @@ -265,8 +265,6 @@ Cvar_Set2 cvar_t *Cvar_Set2( const char *var_name, const char *value, qboolean force ) { cvar_t *var; - Com_DPrintf( "Cvar_Set2: %s %s\n", var_name, value ); - if ( !Cvar_ValidateString( var_name ) ) { Com_Printf("invalid cvar name string: %s\n", var_name ); var_name = "BADNAME"; @@ -292,6 +290,12 @@ cvar_t *Cvar_Set2( const char *var_name, const char *value, qboolean force ) { } } + // Dont display the update when its internal + if ( !(var->flags & CVAR_INTERNAL) ) + { + Com_DPrintf( "Cvar_Set2: %s %s\n", var_name, value ); + } + if (!value ) { value = var->resetString; } @@ -450,7 +454,13 @@ qboolean Cvar_Command( void ) { } // perform a variable print or set - if ( Cmd_Argc() == 1 ) { + if ( Cmd_Argc() == 1 ) + { + if (v->flags & CVAR_INTERNAL) // don't display + { + return qtrue; + } + Com_Printf ("\"%s\" is:\"%s" S_COLOR_WHITE "\" default:\"%s" S_COLOR_WHITE "\"\n", v->name, v->string, v->resetString ); if ( v->latchedString ) { Com_Printf( "latched: \"%s\"\n", v->latchedString ); diff --git a/CODEmp/qcommon/disablewarnings.h b/CODE-mp/qcommon/disablewarnings.h similarity index 100% rename from CODEmp/qcommon/disablewarnings.h rename to CODE-mp/qcommon/disablewarnings.h diff --git a/CODEmp/qcommon/files.cpp b/CODE-mp/qcommon/files.cpp similarity index 96% rename from CODEmp/qcommon/files.cpp rename to CODE-mp/qcommon/files.cpp index 622bf2b..a9e1e6b 100644 --- a/CODEmp/qcommon/files.cpp +++ b/CODE-mp/qcommon/files.cpp @@ -1061,9 +1061,9 @@ int FS_FOpenFileRead( const char *filename, fileHandle_t *file, qboolean uniqueF } } - // qagame.qvm - 13 - // dTZT`X!di` - if (!(pak->referenced & FS_QAGAME_REF) && FS_ShiftedStrStr(filename, "dTZT`X!di`", 13)) { + // jk2mpgame.qvm - 13 + // ]^%`cZT`X!di` + if (!(pak->referenced & FS_QAGAME_REF) && FS_ShiftedStrStr(filename, "]^%`cZT`X!di`", 13)) { pak->referenced |= FS_QAGAME_REF; } // cgame.qvm - 7 diff --git a/CODEmp/qcommon/huffman.cpp b/CODE-mp/qcommon/huffman.cpp similarity index 100% rename from CODEmp/qcommon/huffman.cpp rename to CODE-mp/qcommon/huffman.cpp diff --git a/CODEmp/qcommon/md4.cpp b/CODE-mp/qcommon/md4.cpp similarity index 100% rename from CODEmp/qcommon/md4.cpp rename to CODE-mp/qcommon/md4.cpp diff --git a/CODEmp/qcommon/msg.cpp b/CODE-mp/qcommon/msg.cpp similarity index 100% rename from CODEmp/qcommon/msg.cpp rename to CODE-mp/qcommon/msg.cpp diff --git a/CODEmp/qcommon/net_chan.cpp b/CODE-mp/qcommon/net_chan.cpp similarity index 100% rename from CODEmp/qcommon/net_chan.cpp rename to CODE-mp/qcommon/net_chan.cpp diff --git a/CODEmp/qcommon/q_math.cpp b/CODE-mp/qcommon/q_math.cpp similarity index 100% rename from CODEmp/qcommon/q_math.cpp rename to CODE-mp/qcommon/q_math.cpp diff --git a/CODEmp/qcommon/q_shared.cpp b/CODE-mp/qcommon/q_shared.cpp similarity index 100% rename from CODEmp/qcommon/q_shared.cpp rename to CODE-mp/qcommon/q_shared.cpp diff --git a/CODEmp/qcommon/qcommon.h b/CODE-mp/qcommon/qcommon.h similarity index 100% rename from CODEmp/qcommon/qcommon.h rename to CODE-mp/qcommon/qcommon.h diff --git a/CODEmp/qcommon/qfiles.h b/CODE-mp/qcommon/qfiles.h similarity index 95% rename from CODEmp/qcommon/qfiles.h rename to CODE-mp/qcommon/qfiles.h index 2c82b02..263abc9 100644 --- a/CODEmp/qcommon/qfiles.h +++ b/CODE-mp/qcommon/qfiles.h @@ -98,7 +98,7 @@ typedef struct _TargaHeader { #define MD3_MAX_VERTS 4096 // per surface #define MD3_MAX_SHADERS 256 // per surface #define MD3_MAX_FRAMES 1024 // per model -#define MD3_MAX_SURFACES 32 // per model +#define MD3_MAX_SURFACES 48 // per model #define MD3_MAX_TAGS 16 // per frame // vertex scales diff --git a/CODEmp/qcommon/sstring.h b/CODE-mp/qcommon/sstring.h similarity index 100% rename from CODEmp/qcommon/sstring.h rename to CODE-mp/qcommon/sstring.h diff --git a/CODEmp/qcommon/strip.cpp b/CODE-mp/qcommon/strip.cpp similarity index 100% rename from CODEmp/qcommon/strip.cpp rename to CODE-mp/qcommon/strip.cpp diff --git a/CODEmp/qcommon/strip.h b/CODE-mp/qcommon/strip.h similarity index 100% rename from CODEmp/qcommon/strip.h rename to CODE-mp/qcommon/strip.h diff --git a/CODEmp/qcommon/tags.h b/CODE-mp/qcommon/tags.h similarity index 100% rename from CODEmp/qcommon/tags.h rename to CODE-mp/qcommon/tags.h diff --git a/CODEmp/qcommon/unzip.cpp b/CODE-mp/qcommon/unzip.cpp similarity index 100% rename from CODEmp/qcommon/unzip.cpp rename to CODE-mp/qcommon/unzip.cpp diff --git a/CODEmp/qcommon/unzip.h b/CODE-mp/qcommon/unzip.h similarity index 100% rename from CODEmp/qcommon/unzip.h rename to CODE-mp/qcommon/unzip.h diff --git a/CODEmp/qcommon/vm.cpp b/CODE-mp/qcommon/vm.cpp similarity index 100% rename from CODEmp/qcommon/vm.cpp rename to CODE-mp/qcommon/vm.cpp diff --git a/CODEmp/qcommon/vm_interpreted.cpp b/CODE-mp/qcommon/vm_interpreted.cpp similarity index 100% rename from CODEmp/qcommon/vm_interpreted.cpp rename to CODE-mp/qcommon/vm_interpreted.cpp diff --git a/CODEmp/qcommon/vm_local.h b/CODE-mp/qcommon/vm_local.h similarity index 100% rename from CODEmp/qcommon/vm_local.h rename to CODE-mp/qcommon/vm_local.h diff --git a/CODEmp/qcommon/vm_ppc.cpp b/CODE-mp/qcommon/vm_ppc.cpp similarity index 100% rename from CODEmp/qcommon/vm_ppc.cpp rename to CODE-mp/qcommon/vm_ppc.cpp diff --git a/CODEmp/qcommon/vm_x86.cpp b/CODE-mp/qcommon/vm_x86.cpp similarity index 96% rename from CODEmp/qcommon/vm_x86.cpp rename to CODE-mp/qcommon/vm_x86.cpp index dba5e4b..78722ea 100644 --- a/CODEmp/qcommon/vm_x86.cpp +++ b/CODE-mp/qcommon/vm_x86.cpp @@ -31,13 +31,13 @@ static int pc = 0; static int *instructionPointers = NULL; //#undef FTOL_PTR // bk001213 -//#define FTOL_PTR +#define FTOL_PTR #ifdef _WIN32 #if defined( FTOL_PTR ) -int __ftol( float ); -static int ftolPtr = (int)__ftol; +extern "C" int _ftol(float); +static int ftolPtr = (int)_ftol; #endif void AsmCall( void ); diff --git a/CODE-mp/qcommon/vssver.scc b/CODE-mp/qcommon/vssver.scc new file mode 100644 index 0000000..68b468e Binary files /dev/null and b/CODE-mp/qcommon/vssver.scc differ diff --git a/CODEmp/renderer/glext.h b/CODE-mp/renderer/glext.h similarity index 100% rename from CODEmp/renderer/glext.h rename to CODE-mp/renderer/glext.h diff --git a/CODEmp/renderer/matcomp.c b/CODE-mp/renderer/matcomp.c similarity index 100% rename from CODEmp/renderer/matcomp.c rename to CODE-mp/renderer/matcomp.c diff --git a/CODEmp/renderer/matcomp.h b/CODE-mp/renderer/matcomp.h similarity index 100% rename from CODEmp/renderer/matcomp.h rename to CODE-mp/renderer/matcomp.h diff --git a/CODEmp/renderer/mdx_format.h b/CODE-mp/renderer/mdx_format.h similarity index 100% rename from CODEmp/renderer/mdx_format.h rename to CODE-mp/renderer/mdx_format.h diff --git a/CODE-mp/renderer/mssccprj.scc b/CODE-mp/renderer/mssccprj.scc new file mode 100644 index 0000000..ff8df37 --- /dev/null +++ b/CODE-mp/renderer/mssccprj.scc @@ -0,0 +1,5 @@ +SCC = This is a Source Code Control file + +[renderer.dsp] +SCC_Aux_Path = "\\ravend\vss_projects\jk2sof2MP" +SCC_Project_Name = "$/General/code/renderer", YAAAAAAA diff --git a/CODEmp/renderer/qgl.h b/CODE-mp/renderer/qgl.h similarity index 100% rename from CODEmp/renderer/qgl.h rename to CODE-mp/renderer/qgl.h diff --git a/CODEmp/renderer/ref_trin.def b/CODE-mp/renderer/ref_trin.def similarity index 100% rename from CODEmp/renderer/ref_trin.def rename to CODE-mp/renderer/ref_trin.def diff --git a/CODEmp/renderer/renderer.dsp b/CODE-mp/renderer/renderer.dsp similarity index 100% rename from CODEmp/renderer/renderer.dsp rename to CODE-mp/renderer/renderer.dsp diff --git a/CODEmp/renderer/tr_worldeffects.cpp b/CODE-mp/renderer/tr_WorldEffects.cpp similarity index 93% rename from CODEmp/renderer/tr_worldeffects.cpp rename to CODE-mp/renderer/tr_WorldEffects.cpp index fa26e5e..37a19bd 100644 --- a/CODEmp/renderer/tr_worldeffects.cpp +++ b/CODE-mp/renderer/tr_WorldEffects.cpp @@ -310,11 +310,13 @@ private: SParticle *mRainList; float mFadeAlpha; + bool mIsRaining; public: enum { RAINSYSTEM_WIND_DIRECTION, + RAINSYSTEM_WIND_SPEED, }; public: @@ -323,6 +325,7 @@ public: virtual int GetIntVariable(int which); virtual SParticle *GetParticleVariable(int which); + virtual float GetFloatVariable(int which); virtual float *GetVecVariable(int which); virtual bool Command(const char *command); @@ -331,6 +334,8 @@ public: virtual void Render(void); void Init(void); + + bool IsRaining() { return mIsRaining; } }; @@ -1205,6 +1210,7 @@ private: int mUpdateCount; int mOverallContents; + bool mIsSnowing; const float mVelocityStabilize; const int mUpdateMax; @@ -1223,6 +1229,8 @@ public: virtual void Render(void); void Init(void); + + bool IsSnowing() { return mIsSnowing; } }; CSnowSystem::CSnowSystem(int maxSnowflakes) : @@ -1241,7 +1249,8 @@ CSnowSystem::CSnowSystem(int maxSnowflakes) : mOverallContents(0), mVelocityStabilize(18), - mUpdateMax(10) + mUpdateMax(10), + mIsSnowing(false) { mMinSpread[0] = -600; mMinSpread[1] = -600; @@ -1559,9 +1568,12 @@ void CSnowSystem::Update(float elapseTime) if (!(mOverallContents & CONTENTS_OUTSIDE)) { + mIsSnowing = false; return; } + mIsSnowing = true; + mUpdateCount = (mUpdateCount + 1) % mUpdateMax; x = y = z = 0; @@ -1733,7 +1745,8 @@ CRainSystem::CRainSystem(int maxRain) : mAlpha(0.1), mWindAngle(1.0), - mFadeAlpha(0.0) + mFadeAlpha(0.0f), + mIsRaining(false) { mSpread[0] = M_PI*2.0; // angle spread @@ -1811,6 +1824,17 @@ SParticle *CRainSystem::GetParticleVariable(int which) return CWorldEffectsSystem::GetParticleVariable(which); } +float CRainSystem::GetFloatVariable(int which) +{ + switch(which) + { + case CRainSystem::RAINSYSTEM_WIND_SPEED: + return mWindAngle * 75.0; // pat scaled + } + + return 0.0; +} + float *CRainSystem::GetVecVariable(int which) { switch(which) @@ -1906,6 +1930,7 @@ void CRainSystem::Update(float elapseTime) if (originContents & CONTENTS_OUTSIDE && !(originContents & CONTENTS_WATER)) { + mIsRaining = true; if (mFadeAlpha < 1.0) { mFadeAlpha += elapseTime / 2.0; @@ -1917,6 +1942,7 @@ void CRainSystem::Update(float elapseTime) } else { + mIsRaining = false; if (mFadeAlpha > 0.0) { mFadeAlpha -= elapseTime / 2.0; @@ -2240,5 +2266,41 @@ bool R_GetWindVector(vec3_t windVector) return true; } + if (snowSystem) + { + VectorCopy(snowSystem->GetVecVariable(CRainSystem::RAINSYSTEM_WIND_DIRECTION), windVector); + return true; + } + + + return false; +} + +bool R_GetWindSpeed(float &windSpeed) +{ + if (rainSystem) + { + windSpeed = rainSystem->GetFloatVariable(CRainSystem::RAINSYSTEM_WIND_SPEED); + return true; + } + + return false; +} + +bool R_IsRaining() +{ + if (rainSystem) + { + return rainSystem->IsRaining(); + } + return false; +} + +bool R_IsSnowing() +{ + if (snowSystem) + { + return snowSystem->IsSnowing(); + } return false; } diff --git a/CODEmp/renderer/tr_worldeffects.h b/CODE-mp/renderer/tr_WorldEffects.h similarity index 90% rename from CODEmp/renderer/tr_worldeffects.h rename to CODE-mp/renderer/tr_WorldEffects.h index 35450da..5320830 100644 --- a/CODEmp/renderer/tr_worldeffects.h +++ b/CODE-mp/renderer/tr_WorldEffects.h @@ -77,6 +77,7 @@ public: virtual int GetIntVariable(int which) { return 0; } virtual SParticle *GetParticleVariable(int which) { return 0; } + virtual float GetFloatVariable(int which) { return 0.0; } virtual float *GetVecVariable(int which) { return 0; } virtual bool Command(const char *command); @@ -95,5 +96,9 @@ void R_WorldEffectCommand(const char *command); void R_WorldEffect_f(void); bool R_GetWindVector(vec3_t windVector); +bool R_GetWindSpeed(float &windSpeed); + +bool R_IsRaining(); +bool R_IsSnowing(); #endif // __TR_WORLDEFFECTS_H diff --git a/CODEmp/renderer/tr_animation.cpp b/CODE-mp/renderer/tr_animation.cpp similarity index 100% rename from CODEmp/renderer/tr_animation.cpp rename to CODE-mp/renderer/tr_animation.cpp diff --git a/CODEmp/renderer/tr_backend.cpp b/CODE-mp/renderer/tr_backend.cpp similarity index 90% rename from CODEmp/renderer/tr_backend.cpp rename to CODE-mp/renderer/tr_backend.cpp index 7763a48..836d188 100644 --- a/CODEmp/renderer/tr_backend.cpp +++ b/CODE-mp/renderer/tr_backend.cpp @@ -510,7 +510,7 @@ void RB_RenderDrawSurfList( drawSurf_t *drawSurfs, int numDrawSurfs ) { int fogNum, oldFogNum; int entityNum, oldEntityNum; int dlighted, oldDlighted; - qboolean depthRange, oldDepthRange; + int depthRange, oldDepthRange; int i; drawSurf_t *drawSurf; int oldSort; @@ -581,7 +581,7 @@ void RB_RenderDrawSurfList( drawSurf_t *drawSurfs, int numDrawSurfs ) { // change the modelview matrix if needed // if ( entityNum != oldEntityNum ) { - depthRange = qfalse; + depthRange = 0; if ( entityNum != ENTITYNUM_WORLD ) { backEnd.currentEntity = &backEnd.refdef.entities[entityNum]; @@ -598,9 +598,13 @@ void RB_RenderDrawSurfList( drawSurf_t *drawSurfs, int numDrawSurfs ) { R_TransformDlights( backEnd.refdef.num_dlights, backEnd.refdef.dlights, &backEnd.or ); } - if ( backEnd.currentEntity->e.renderfx & RF_DEPTHHACK ) { + if ( backEnd.currentEntity->e.renderfx & RF_NODEPTH ) { + // No depth at all, very rare but some things for seeing through walls + depthRange = 2; + } + else if ( backEnd.currentEntity->e.renderfx & RF_DEPTHHACK ) { // hack the depth range to prevent view model from poking into walls - depthRange = qtrue; + depthRange = 1; } } else { backEnd.currentEntity = &tr.worldEntity; @@ -618,11 +622,21 @@ void RB_RenderDrawSurfList( drawSurf_t *drawSurfs, int numDrawSurfs ) { // change depthrange if needed // if ( oldDepthRange != depthRange ) { - if ( depthRange ) { - qglDepthRange (0, 0.3); - } else { - qglDepthRange (0, 1); + switch ( depthRange ) { + default: + case 0: + qglDepthRange (0, 1); + break; + + case 1: + qglDepthRange (0, .3); + break; + + case 2: + qglDepthRange (0, 0); + break; } + oldDepthRange = depthRange; } @@ -951,44 +965,48 @@ const void *RB_RotatePic2 ( const void *data ) cmd = (const rotatePicCommand_t *)data; shader = cmd->shader; - image = shader->stages[0]->bundle[0].image[0]; - if ( image ) { - if ( !backEnd.projection2D ) { - RB_SetGL2D(); + if ( shader->stages[0] ) + { + image = shader->stages[0]->bundle[0].image[0]; + + if ( image ) { + if ( !backEnd.projection2D ) { + RB_SetGL2D(); + } + + // Get our current blend mode, etc. + GL_State( shader->stages[0]->stateBits ); + + qglColor4ubv( backEnd.color2D ); + qglPushMatrix(); + + // rotation point is going to be around the center of the passed in coordinates + qglTranslatef( cmd->x, cmd->y, 0 ); + qglRotatef( cmd->a, 0.0, 0.0, 1.0 ); + + GL_Bind( image ); + qglBegin( GL_QUADS ); + qglTexCoord2f( cmd->s1, cmd->t1); + qglVertex2f( -cmd->w * 0.5f, -cmd->h * 0.5f ); + + qglTexCoord2f( cmd->s2, cmd->t1 ); + qglVertex2f( cmd->w * 0.5f, -cmd->h * 0.5f ); + + qglTexCoord2f( cmd->s2, cmd->t2 ); + qglVertex2f( cmd->w * 0.5f, cmd->h * 0.5f ); + + qglTexCoord2f( cmd->s1, cmd->t2 ); + qglVertex2f( -cmd->w * 0.5f, cmd->h * 0.5f ); + qglEnd(); + + qglPopMatrix(); + + // Hmmm, this is not too cool + GL_State( GLS_DEPTHTEST_DISABLE | + GLS_SRCBLEND_SRC_ALPHA | + GLS_DSTBLEND_ONE_MINUS_SRC_ALPHA ); } - - // Get our current blend mode, etc. - GL_State( shader->stages[0]->stateBits ); - - qglColor4ubv( backEnd.color2D ); - qglPushMatrix(); - - // rotation point is going to be around the center of the passed in coordinates - qglTranslatef( cmd->x, cmd->y, 0 ); - qglRotatef( cmd->a, 0.0, 0.0, 1.0 ); - - GL_Bind( image ); - qglBegin( GL_QUADS ); - qglTexCoord2f( cmd->s1, cmd->t1); - qglVertex2f( -cmd->w * 0.5f, -cmd->h * 0.5f ); - - qglTexCoord2f( cmd->s2, cmd->t1 ); - qglVertex2f( cmd->w * 0.5f, -cmd->h * 0.5f ); - - qglTexCoord2f( cmd->s2, cmd->t2 ); - qglVertex2f( cmd->w * 0.5f, cmd->h * 0.5f ); - - qglTexCoord2f( cmd->s1, cmd->t2 ); - qglVertex2f( -cmd->w * 0.5f, cmd->h * 0.5f ); - qglEnd(); - - qglPopMatrix(); - - // Hmmm, this is not too cool - GL_State( GLS_DEPTHTEST_DISABLE | - GLS_SRCBLEND_SRC_ALPHA | - GLS_DSTBLEND_ONE_MINUS_SRC_ALPHA ); } return (const void *)(cmd + 1); diff --git a/CODEmp/renderer/tr_bsp.cpp b/CODE-mp/renderer/tr_bsp.cpp similarity index 100% rename from CODEmp/renderer/tr_bsp.cpp rename to CODE-mp/renderer/tr_bsp.cpp diff --git a/CODEmp/renderer/tr_cmds.cpp b/CODE-mp/renderer/tr_cmds.cpp similarity index 100% rename from CODEmp/renderer/tr_cmds.cpp rename to CODE-mp/renderer/tr_cmds.cpp diff --git a/CODEmp/renderer/tr_curve.cpp b/CODE-mp/renderer/tr_curve.cpp similarity index 100% rename from CODEmp/renderer/tr_curve.cpp rename to CODE-mp/renderer/tr_curve.cpp diff --git a/CODEmp/renderer/tr_flares.cpp b/CODE-mp/renderer/tr_flares.cpp similarity index 100% rename from CODEmp/renderer/tr_flares.cpp rename to CODE-mp/renderer/tr_flares.cpp diff --git a/CODEmp/renderer/tr_font.cpp b/CODE-mp/renderer/tr_font.cpp similarity index 100% rename from CODEmp/renderer/tr_font.cpp rename to CODE-mp/renderer/tr_font.cpp diff --git a/CODEmp/renderer/tr_font.h b/CODE-mp/renderer/tr_font.h similarity index 100% rename from CODEmp/renderer/tr_font.h rename to CODE-mp/renderer/tr_font.h diff --git a/CODEmp/renderer/tr_ghoul2.cpp b/CODE-mp/renderer/tr_ghoul2.cpp similarity index 100% rename from CODEmp/renderer/tr_ghoul2.cpp rename to CODE-mp/renderer/tr_ghoul2.cpp diff --git a/CODEmp/renderer/tr_image.cpp b/CODE-mp/renderer/tr_image.cpp similarity index 90% rename from CODEmp/renderer/tr_image.cpp rename to CODE-mp/renderer/tr_image.cpp index b2bce14..10f0cc7 100644 --- a/CODEmp/renderer/tr_image.cpp +++ b/CODE-mp/renderer/tr_image.cpp @@ -1,6 +1,7 @@ // tr_image.c #include "tr_local.h" #include "glext.h" +#include "../win32/glw_win.h" #pragma warning (push, 3) //go back down to 3 for the stl include @@ -59,6 +60,128 @@ textureMode_t modes[] = { {"GL_LINEAR_MIPMAP_LINEAR", GL_LINEAR_MIPMAP_LINEAR, GL_LINEAR} }; +typedef struct textureFormat_s +{ + char *name; + GLenum type; + float bytesPerTexel; + char *primaryExtension; + char *secondaryExtension; +} textureFormat_t; + +static textureFormat_t textureFormats[] = +{ + // Fallback safe formats + { "GL_SOLID_FORMAT", GL_SOLID_FORMAT, 2.0f, NULL, NULL }, + { "GL_ALPHA_FORMAT", GL_ALPHA_FORMAT, 2.0f, NULL, NULL }, + + // OpenGL1.1 formats - all should be valid + { "GL_RGB", GL_RGB, 2.0f, NULL, NULL }, + { "GL_RGB5", GL_RGB5, 2.0f, NULL, NULL }, + { "GL_RGB8", GL_RGB8, 4.0f, NULL, NULL }, + { "GL_RGB16", GL_RGB16, 8.0f, NULL, NULL }, + + { "GL_RGBA", GL_RGBA, 2.0f, NULL, NULL }, + { "GL_RGBA4", GL_RGBA4, 2.0f, NULL, NULL }, + { "GL_RGBA8", GL_RGBA8, 4.0f, NULL, NULL }, + { "GL_RGBA16", GL_RGBA16, 8.0f, NULL, NULL }, + + { "GL_LUMINANCE8", GL_LUMINANCE8, 1.0f, NULL, NULL }, + { "GL_INTENSITY8", GL_INTENSITY8, 1.0f, NULL, NULL }, + { "GL_ALPHA8", GL_ALPHA8, 1.0f, NULL, NULL }, + + // Extended formats + { "GL_RGB4_S3TC", GL_RGB4_S3TC, 0.33333f, "GL_S3_s3tc", NULL }, + + { "GL_COMPRESSED_RGB_DXT1", GL_COMPRESSED_RGB_S3TC_DXT1_EXT, 0.33333f, "ARB_texture_compression", "EXT_texture_compression_s3tc" }, + { "GL_COMPRESSED_RGBA_DXT5", GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, 1.0f, "ARB_texture_compression", "EXT_texture_compression_s3tc" }, + + { "GL_COMPRESSED_RGB_FXT1", GL_COMPRESSED_RGB_FXT1_3DFX, 1.0f, "ARB_texture_compression", "3DFX_texture_compression_FXT1" }, +}; + +/* +=============== +GL_SetTextureFormat +=============== +*/ + +// fallback is either 0 or 1 for the simple 1.0 textures + +int GL_SetTextureFormat( const char *format, int fallback ) +{ + int i, count; + char *primary; + char *secondary; + + count = sizeof(textureFormats) / sizeof(textureFormat_t); + for ( i = 0 ; i < count ; i++ ) + { + if ( !Q_stricmp( textureFormats[i].name, format ) ) + { + break; + } + } + if(i == count) + { + ri.Printf(PRINT_ALL, S_COLOR_RED "TextureFormat: Unknown texture format %s\n", format); + return(fallback); + } + // If no extension required, just return the enum + if(!textureFormats[i].primaryExtension && !textureFormats[i].secondaryExtension) + { + return(i); + } + + // Check for extensions + primary = textureFormats[i].primaryExtension; + secondary = textureFormats[i].secondaryExtension; + if(GL_CheckForExtension(primary) && !secondary) + { + return(i); + } + if(GL_CheckForExtension(primary) && GL_CheckForExtension(secondary)) + { + return(i); + } + ri.Printf(PRINT_ALL, S_COLOR_RED "TextureFormat: Unsupported extended texture format %s\n", format); + return(fallback); +} + +void GL_InitTextureFormats( void ) +{ + int idx; + + idx = GL_SetTextureFormat( r_tf_solid_compressed->string, 0 ); + glConfig.tfSolidCompressed = textureFormats[idx].type; + glConfig.tfSolidCompressedBPT = textureFormats[idx].bytesPerTexel; + ri.Cvar_Set("r_tf_solid_compressed", textureFormats[idx].name); + + idx = GL_SetTextureFormat( r_tf_alpha_compressed->string, 1 ); + glConfig.tfAlphaCompressed = textureFormats[idx].type; + glConfig.tfAlphaCompressedBPT = textureFormats[idx].bytesPerTexel; + ri.Cvar_Set("r_tf_alpha_compressed", textureFormats[idx].name); + + idx = GL_SetTextureFormat( r_tf_solid_uncompressed->string, 0 ); + glConfig.tfSolidUncompressed = textureFormats[idx].type; + glConfig.tfSolidUncompressedBPT = textureFormats[idx].bytesPerTexel; + ri.Cvar_Set("r_tf_solid_uncompressed", textureFormats[idx].name); + + idx = GL_SetTextureFormat( r_tf_alpha_uncompressed->string, 1 ); + glConfig.tfAlphaUncompressed = textureFormats[idx].type; + glConfig.tfAlphaUncompressedBPT = textureFormats[idx].bytesPerTexel; + ri.Cvar_Set("r_tf_alpha_uncompressed", textureFormats[idx].name); + + idx = GL_SetTextureFormat( r_tf_lightmap->string, 0 ); + glConfig.tfLightmap = textureFormats[idx].type; + glConfig.tfLightmapBPT = textureFormats[idx].bytesPerTexel; + ri.Cvar_Set("r_tf_lightmap", textureFormats[idx].name); + + idx = GL_SetTextureFormat( r_tf_cinematic->string, 0 ); + glConfig.tfCinematic = textureFormats[idx].type; + glConfig.tfCinematicBPT = textureFormats[idx].bytesPerTexel; + ri.Cvar_Set("r_tf_cinematic", textureFormats[idx].name); +} + // makeup a nice clean, consistant name to query for and file under, for map<> usage... // @@ -635,6 +758,15 @@ static void Upload32( unsigned *data, GLenum internalFormat = GL_RGB; float rMax = 0, gMax = 0, bMax = 0; + if (r_force_compressed_textures->integer) + { + allowTC = qtrue; + } + if (!r_ext_compressed_textures->integer) + { + allowTC = qfalse; + } + // // convert to exact power of 2 sizes // @@ -693,7 +825,8 @@ static void Upload32( unsigned *data, c = width*height; scan = ((byte *)data); samples = 3; - if (!lightMap) { + if (!lightMap) + { for ( i = 0; i < c; i++ ) { if ( scan[i*4+0] > rMax ) @@ -717,65 +850,30 @@ static void Upload32( unsigned *data, // select proper internal format if ( samples == 3 ) { - if ( glConfig.textureCompression == TC_S3TC && allowTC) + if ( allowTC) { - internalFormat = GL_RGB4_S3TC; + internalFormat = glConfig.tfSolidCompressed; } - else if ( glConfig.textureCompression == TC_S3TC_DXT && allowTC ) - { // Compress purely color - no alpha - if ( r_texturebits->integer == 16 ) { - internalFormat = GL_COMPRESSED_RGB_S3TC_DXT1_EXT; //this format cuts to 16 bit - } - else {//if we aren't using 16 bit then, use 32 bit compression - internalFormat = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT; - } - } - else if ( lightMap && r_texturebitslm->integer > 0 ) + else { - // Allow different bit depth when we are a lightmap - if ( r_texturebitslm->integer == 16 ) - { - internalFormat = GL_RGB5; - } - else if ( r_texturebitslm->integer == 32 ) - { - internalFormat = GL_RGB8; - } - } - else if ( r_texturebits->integer == 16 ) - { - internalFormat = GL_RGB5; - } - else if ( r_texturebits->integer == 32 ) - { - internalFormat = GL_RGB8; - } - else - { - internalFormat = 3; + internalFormat = glConfig.tfSolidUncompressed; } } else if ( samples == 4 ) { - if ( glConfig.textureCompression == TC_S3TC_DXT && allowTC) + if ( allowTC) { // Compress both alpha and color - internalFormat = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT; - } - else if ( r_texturebits->integer == 16 ) - { - internalFormat = GL_RGBA4; - } - else if ( r_texturebits->integer == 32 ) - { - internalFormat = GL_RGBA8; + internalFormat = glConfig.tfAlphaCompressed; } else { - internalFormat = 4; + internalFormat = glConfig.tfAlphaUncompressed; } } - } else { - internalFormat = 3; + } + else + { + internalFormat = glConfig.tfLightmap; } // copy or resample data as appropriate for first MIP level if ( ( scaled_width == width ) && @@ -973,7 +1071,7 @@ void RE_RegisterImages_Info_f( void ) // currently, this just goes through all the images and dumps any not referenced on this level... // -void RE_RegisterImages_LevelLoadEnd(void) +qboolean RE_RegisterImages_LevelLoadEnd(void) { ri.Printf( PRINT_DEVELOPER, "RE_RegisterImages_LevelLoadEnd():\n"); @@ -1017,6 +1115,8 @@ void RE_RegisterImages_LevelLoadEnd(void) ri.Printf( PRINT_DEVELOPER, "RE_RegisterImages_LevelLoadEnd(): Ok\n"); GL_ResetBinds(); + + return bEraseOccured; } @@ -2777,6 +2877,8 @@ R_InitImages void R_InitImages( void ) { //memset(hashTable, 0, sizeof(hashTable)); // DO NOT DO THIS NOW (because of image cacheing) -ste. + GL_InitTextureFormats(); + // build brightness translation tables R_SetColorMappings(); @@ -3000,6 +3102,8 @@ qhandle_t RE_RegisterSkin( const char *name ) { // parse the shader name token = CommaParse( &text_p ); + assert ( skin->numSurfaces < MD3_MAX_SURFACES ); + surf = skin->surfaces[ skin->numSurfaces ] = (skinSurface_t *)ri.Hunk_Alloc( sizeof( *skin->surfaces[0] ), h_low ); Q_strncpyz( surf->name, surfName, sizeof( surf->name ) ); surf->shader = R_FindShader( token, lightmapsNone, stylesDefault, qtrue ); diff --git a/CODEmp/renderer/tr_init.cpp b/CODE-mp/renderer/tr_init.cpp similarity index 93% rename from CODEmp/renderer/tr_init.cpp rename to CODE-mp/renderer/tr_init.cpp index 81b4a80..78441e3 100644 --- a/CODEmp/renderer/tr_init.cpp +++ b/CODE-mp/renderer/tr_init.cpp @@ -73,6 +73,13 @@ cvar_t *r_windPointY; cvar_t *r_allowExtensions; +cvar_t *r_tf_solid_compressed; +cvar_t *r_tf_alpha_compressed; +cvar_t *r_tf_solid_uncompressed; +cvar_t *r_tf_alpha_uncompressed; +cvar_t *r_tf_lightmap; +cvar_t *r_tf_cinematic; +cvar_t *r_force_compressed_textures; cvar_t *r_ext_compressed_textures; cvar_t *r_ext_gamma_control; @@ -773,7 +780,6 @@ void GfxInfo_f( void ) ri.Printf( PRINT_ALL, "multitexture: %s\n", enablestrings[qglActiveTextureARB != 0] ); ri.Printf( PRINT_ALL, "compiled vertex arrays: %s\n", enablestrings[qglLockArraysEXT != 0 ] ); ri.Printf( PRINT_ALL, "texenv add: %s\n", enablestrings[glConfig.textureEnvAddAvailable != 0] ); - ri.Printf( PRINT_ALL, "compressed textures: %s\n", enablestrings[glConfig.textureCompression!=TC_NONE] ); ri.Printf( PRINT_ALL, "anisotropic filtering: %s\n", enablestrings[(r_ext_texture_filter_anisotropic->integer != 0) && glConfig.textureFilterAnisotropicAvailable] ); if ( glConfig.smpActive ) { @@ -795,6 +801,14 @@ void R_Register( void ) // latched and archived variables // r_allowExtensions = ri.Cvar_Get( "r_allowExtensions", "1", CVAR_ARCHIVE | CVAR_LATCH ); + r_tf_solid_compressed = ri.Cvar_Get( "r_tf_solid_compressed", "GL_COMPRESSED_RGBA_DXT5", CVAR_ARCHIVE | CVAR_LATCH ); + r_tf_alpha_compressed = ri.Cvar_Get( "r_tf_alpha_compressed", "GL_COMPRESSED_RGBA_DXT5", CVAR_ARCHIVE | CVAR_LATCH ); + r_tf_solid_uncompressed = ri.Cvar_Get( "r_tf_solid_uncompressed", "GL_RGB8", CVAR_ARCHIVE | CVAR_LATCH ); + r_tf_alpha_uncompressed = ri.Cvar_Get( "r_tf_alpha_uncompressed", "GL_RGBA8", CVAR_ARCHIVE | CVAR_LATCH ); + r_tf_lightmap = ri.Cvar_Get( "r_tf_lightmap", "GL_RGB8", CVAR_ARCHIVE | CVAR_LATCH ); + r_tf_cinematic = ri.Cvar_Get( "r_tf_cinematic", "GL_RGB8", CVAR_ARCHIVE | CVAR_LATCH ); + r_force_compressed_textures = ri.Cvar_Get( "r_force_compressed_textures", "1", CVAR_ARCHIVE | CVAR_LATCH ); + r_ext_compressed_textures = ri.Cvar_Get( "r_ext_compressed_textures", "1", CVAR_ARCHIVE | CVAR_LATCH ); r_ext_gamma_control = ri.Cvar_Get( "r_ext_gamma_control", "1", CVAR_ARCHIVE | CVAR_LATCH ); r_ext_multitexture = ri.Cvar_Get( "r_ext_multitexture", "1", CVAR_ARCHIVE | CVAR_LATCH ); @@ -890,8 +904,8 @@ void R_Register( void ) r_printShaders = ri.Cvar_Get( "r_printShaders", "0", 0 ); r_saveFontData = ri.Cvar_Get( "r_saveFontData", "0", 0 ); - r_surfaceSprites = ri.Cvar_Get ("r_surfaceSprites", "1", CVAR_ARCHIVE); - r_surfaceWeather = ri.Cvar_Get ("r_surfaceWeather", "1", CVAR_ARCHIVE); + r_surfaceSprites = ri.Cvar_Get ("r_surfaceSprites", "1", CVAR_CHEAT); + r_surfaceWeather = ri.Cvar_Get ("r_surfaceWeather", "0", 0); r_windSpeed = ri.Cvar_Get ("r_windSpeed", "0", 0); r_windAngle = ri.Cvar_Get ("r_windAngle", "0", 0); diff --git a/CODEmp/renderer/tr_light.cpp b/CODE-mp/renderer/tr_light.cpp similarity index 100% rename from CODEmp/renderer/tr_light.cpp rename to CODE-mp/renderer/tr_light.cpp diff --git a/CODEmp/renderer/tr_local.h b/CODE-mp/renderer/tr_local.h similarity index 95% rename from CODEmp/renderer/tr_local.h rename to CODE-mp/renderer/tr_local.h index 87d007f..3de082a 100644 --- a/CODEmp/renderer/tr_local.h +++ b/CODE-mp/renderer/tr_local.h @@ -33,6 +33,10 @@ long myftol( float f ); // can't be increased without changing bit packing for drawsurfs +// Default texture format constants +#define GL_SOLID_FORMAT 3 +#define GL_ALPHA_FORMAT 4 + typedef struct dlight_s { vec3_t origin; @@ -1143,6 +1147,14 @@ extern cvar_t *r_displayRefresh; // optional display refresh option extern cvar_t *r_ignorehwgamma; // overrides hardware gamma capabilities extern cvar_t *r_allowExtensions; // global enable/disable of OpenGL extensions +extern cvar_t *r_tf_solid_compressed; +extern cvar_t *r_tf_alpha_compressed; +extern cvar_t *r_tf_solid_uncompressed; +extern cvar_t *r_tf_alpha_uncompressed; +extern cvar_t *r_tf_lightmap; +extern cvar_t *r_tf_cinematic; +extern cvar_t *r_force_compressed_textures; // these control use of specific extensions + extern cvar_t *r_ext_compressed_textures; // these control use of specific extensions extern cvar_t *r_ext_gamma_control; extern cvar_t *r_ext_texenv_op; @@ -1238,6 +1250,7 @@ void R_AddDrawSurf( surfaceType_t *surface, shader_t *shader, int fogIndex, int #define CULL_OUT 2 // completely outside the clipping planes void R_LocalNormalToWorld (vec3_t local, vec3_t world); void R_LocalPointToWorld (vec3_t local, vec3_t world); +void R_WorldNormalToEntity (vec3_t localVec, vec3_t world); int R_CullLocalBox (vec3_t bounds[2]); int R_CullPointAndRadius( vec3_t origin, float radius ); int R_CullLocalPointAndRadius( vec3_t origin, float radius ); @@ -1316,7 +1329,7 @@ void RE_RegisterModels_StoreShaderRequest(const char *psModelFileName, const ch void RE_RegisterModels_Info_f(void); // //void RE_RegisterImages_LevelLoadBegin(const char *psMapName); -void RE_RegisterImages_LevelLoadEnd(void); +qboolean RE_RegisterImages_LevelLoadEnd(void); void RE_RegisterImages_Info_f(void); @@ -1805,4 +1818,7 @@ void RE_InsertModelIntoHash(const char *name, model_t *mod); Ghoul2 Insert End */ +// tr_surfacesprites +void RB_DrawSurfaceSprites( shaderStage_t *stage, shaderCommands_t *input); + #endif //TR_LOCAL_H diff --git a/CODEmp/renderer/tr_main.cpp b/CODE-mp/renderer/tr_main.cpp similarity index 92% rename from CODEmp/renderer/tr_main.cpp rename to CODE-mp/renderer/tr_main.cpp index 1400c88..98d2f90 100644 --- a/CODEmp/renderer/tr_main.cpp +++ b/CODE-mp/renderer/tr_main.cpp @@ -172,6 +172,35 @@ void R_LocalPointToWorld (vec3_t local, vec3_t world) { world[2] = local[0] * tr.or.axis[0][2] + local[1] * tr.or.axis[1][2] + local[2] * tr.or.axis[2][2] + tr.or.origin[2]; } +float preTransEntMatrix[16]; + +/* +================= +R_WorldNormalToEntity + +================= +*/ +void R_WorldNormalToEntity (vec3_t worldvec, vec3_t entvec) +{ + entvec[0] = -worldvec[0] * preTransEntMatrix[0] - worldvec[1] * preTransEntMatrix[4] + worldvec[2] * preTransEntMatrix[8]; + entvec[1] = -worldvec[0] * preTransEntMatrix[1] - worldvec[1] * preTransEntMatrix[5] + worldvec[2] * preTransEntMatrix[9]; + entvec[2] = -worldvec[0] * preTransEntMatrix[2] - worldvec[1] * preTransEntMatrix[6] + worldvec[2] * preTransEntMatrix[10]; +} + +/* +================= +R_WorldPointToEntity + +================= +*/ +/*void R_WorldPointToEntity (vec3_t worldvec, vec3_t entvec) +{ + entvec[0] = worldvec[0] * preTransEntMatrix[0] + worldvec[1] * preTransEntMatrix[4] + worldvec[2] * preTransEntMatrix[8]+preTransEntMatrix[12]; + entvec[1] = worldvec[0] * preTransEntMatrix[1] + worldvec[1] * preTransEntMatrix[5] + worldvec[2] * preTransEntMatrix[9]+preTransEntMatrix[13]; + entvec[2] = worldvec[0] * preTransEntMatrix[2] + worldvec[1] * preTransEntMatrix[6] + worldvec[2] * preTransEntMatrix[10]+preTransEntMatrix[14]; +} +*/ + /* ================= R_WorldToLocal @@ -262,7 +291,7 @@ Called by both the front end and the back end */ void R_RotateForEntity( const trRefEntity_t *ent, const viewParms_t *viewParms, orientationr_t *or ) { - float glMatrix[16]; +// float glMatrix[16]; vec3_t delta; float axisLength; @@ -277,27 +306,27 @@ void R_RotateForEntity( const trRefEntity_t *ent, const viewParms_t *viewParms, VectorCopy( ent->e.axis[1], or->axis[1] ); VectorCopy( ent->e.axis[2], or->axis[2] ); - glMatrix[0] = or->axis[0][0]; - glMatrix[4] = or->axis[1][0]; - glMatrix[8] = or->axis[2][0]; - glMatrix[12] = or->origin[0]; + preTransEntMatrix[0] = or->axis[0][0]; + preTransEntMatrix[4] = or->axis[1][0]; + preTransEntMatrix[8] = or->axis[2][0]; + preTransEntMatrix[12] = or->origin[0]; - glMatrix[1] = or->axis[0][1]; - glMatrix[5] = or->axis[1][1]; - glMatrix[9] = or->axis[2][1]; - glMatrix[13] = or->origin[1]; + preTransEntMatrix[1] = or->axis[0][1]; + preTransEntMatrix[5] = or->axis[1][1]; + preTransEntMatrix[9] = or->axis[2][1]; + preTransEntMatrix[13] = or->origin[1]; - glMatrix[2] = or->axis[0][2]; - glMatrix[6] = or->axis[1][2]; - glMatrix[10] = or->axis[2][2]; - glMatrix[14] = or->origin[2]; + preTransEntMatrix[2] = or->axis[0][2]; + preTransEntMatrix[6] = or->axis[1][2]; + preTransEntMatrix[10] = or->axis[2][2]; + preTransEntMatrix[14] = or->origin[2]; - glMatrix[3] = 0; - glMatrix[7] = 0; - glMatrix[11] = 0; - glMatrix[15] = 1; + preTransEntMatrix[3] = 0; + preTransEntMatrix[7] = 0; + preTransEntMatrix[11] = 0; + preTransEntMatrix[15] = 1; - myGlMultMatrix( glMatrix, viewParms->world.modelMatrix, or->modelMatrix ); + myGlMultMatrix( preTransEntMatrix, viewParms->world.modelMatrix, or->modelMatrix ); // calculate the viewer origin in the model's space // needed for fog, specular, and environment mapping diff --git a/CODEmp/renderer/tr_marks.cpp b/CODE-mp/renderer/tr_marks.cpp similarity index 100% rename from CODEmp/renderer/tr_marks.cpp rename to CODE-mp/renderer/tr_marks.cpp diff --git a/CODEmp/renderer/tr_mesh.cpp b/CODE-mp/renderer/tr_mesh.cpp similarity index 100% rename from CODEmp/renderer/tr_mesh.cpp rename to CODE-mp/renderer/tr_mesh.cpp diff --git a/CODEmp/renderer/tr_model.cpp b/CODE-mp/renderer/tr_model.cpp similarity index 100% rename from CODEmp/renderer/tr_model.cpp rename to CODE-mp/renderer/tr_model.cpp diff --git a/CODEmp/renderer/tr_noise.cpp b/CODE-mp/renderer/tr_noise.cpp similarity index 100% rename from CODEmp/renderer/tr_noise.cpp rename to CODE-mp/renderer/tr_noise.cpp diff --git a/CODEmp/renderer/tr_public.h b/CODE-mp/renderer/tr_public.h similarity index 100% rename from CODEmp/renderer/tr_public.h rename to CODE-mp/renderer/tr_public.h diff --git a/CODEmp/renderer/tr_quicksprite.cpp b/CODE-mp/renderer/tr_quicksprite.cpp similarity index 100% rename from CODEmp/renderer/tr_quicksprite.cpp rename to CODE-mp/renderer/tr_quicksprite.cpp diff --git a/CODEmp/renderer/tr_quicksprite.h b/CODE-mp/renderer/tr_quicksprite.h similarity index 100% rename from CODEmp/renderer/tr_quicksprite.h rename to CODE-mp/renderer/tr_quicksprite.h diff --git a/CODEmp/renderer/tr_scene.cpp b/CODE-mp/renderer/tr_scene.cpp similarity index 100% rename from CODEmp/renderer/tr_scene.cpp rename to CODE-mp/renderer/tr_scene.cpp diff --git a/CODE-mp/renderer/tr_shade.cpp b/CODE-mp/renderer/tr_shade.cpp new file mode 100644 index 0000000..4076635 --- /dev/null +++ b/CODE-mp/renderer/tr_shade.cpp @@ -0,0 +1,1483 @@ +// tr_shade.c + +#include "tr_local.h" + +#include "tr_quicksprite.h" + +/* + + THIS ENTIRE FILE IS BACK END + + This file deals with applying shaders to surface data in the tess struct. +*/ + +color4ub_t styleColors[MAX_LIGHT_STYLES]; + +/* +================ +R_ArrayElementDiscrete + +This is just for OpenGL conformance testing, it should never be the fastest +================ +*/ +static void APIENTRY R_ArrayElementDiscrete( GLint index ) { + qglColor4ubv( tess.svars.colors[ index ] ); + if ( glState.currenttmu ) { + qglMultiTexCoord2fARB( 0, tess.svars.texcoords[ 0 ][ index ][0], tess.svars.texcoords[ 0 ][ index ][1] ); + qglMultiTexCoord2fARB( 1, tess.svars.texcoords[ 1 ][ index ][0], tess.svars.texcoords[ 1 ][ index ][1] ); + } else { + qglTexCoord2fv( tess.svars.texcoords[ 0 ][ index ] ); + } + qglVertex3fv( tess.xyz[ index ] ); +} + +/* +=================== +R_DrawStripElements + +=================== +*/ +static int c_vertexes; // for seeing how long our average strips are +static int c_begins; +static void R_DrawStripElements( int numIndexes, const glIndex_t *indexes, void ( APIENTRY *element )(GLint) ) { + int i; + int last[3] = { -1, -1, -1 }; + qboolean even; + + c_begins++; + + if ( numIndexes <= 0 ) { + return; + } + + qglBegin( GL_TRIANGLE_STRIP ); + + // prime the strip + element( indexes[0] ); + element( indexes[1] ); + element( indexes[2] ); + c_vertexes += 3; + + last[0] = indexes[0]; + last[1] = indexes[1]; + last[2] = indexes[2]; + + even = qfalse; + + for ( i = 3; i < numIndexes; i += 3 ) + { + // odd numbered triangle in potential strip + if ( !even ) + { + // check previous triangle to see if we're continuing a strip + if ( ( indexes[i+0] == last[2] ) && ( indexes[i+1] == last[1] ) ) + { + element( indexes[i+2] ); + c_vertexes++; + assert( indexes[i+2] < tess.numVertexes ); + even = qtrue; + } + // otherwise we're done with this strip so finish it and start + // a new one + else + { + qglEnd(); + + qglBegin( GL_TRIANGLE_STRIP ); + c_begins++; + + element( indexes[i+0] ); + element( indexes[i+1] ); + element( indexes[i+2] ); + + c_vertexes += 3; + + even = qfalse; + } + } + else + { + // check previous triangle to see if we're continuing a strip + if ( ( last[2] == indexes[i+1] ) && ( last[0] == indexes[i+0] ) ) + { + element( indexes[i+2] ); + c_vertexes++; + + even = qfalse; + } + // otherwise we're done with this strip so finish it and start + // a new one + else + { + qglEnd(); + + qglBegin( GL_TRIANGLE_STRIP ); + c_begins++; + + element( indexes[i+0] ); + element( indexes[i+1] ); + element( indexes[i+2] ); + c_vertexes += 3; + + even = qfalse; + } + } + + // cache the last three vertices + last[0] = indexes[i+0]; + last[1] = indexes[i+1]; + last[2] = indexes[i+2]; + } + + qglEnd(); +} + + + +/* +================== +R_DrawElements + +Optionally performs our own glDrawElements that looks for strip conditions +instead of using the single glDrawElements call that may be inefficient +without compiled vertex arrays. +================== +*/ +static void R_DrawElements( int numIndexes, const glIndex_t *indexes ) { + int primitives; + + primitives = r_primitives->integer; + + // default is to use triangles if compiled vertex arrays are present + if ( primitives == 0 ) { + if ( qglLockArraysEXT ) { + primitives = 2; + } else { + primitives = 1; + } + } + + + if ( primitives == 2 ) { + qglDrawElements( GL_TRIANGLES, + numIndexes, + GL_INDEX_TYPE, + indexes ); + return; + } + + if ( primitives == 1 ) { + R_DrawStripElements( numIndexes, indexes, qglArrayElement ); + return; + } + + if ( primitives == 3 ) { + R_DrawStripElements( numIndexes, indexes, R_ArrayElementDiscrete ); + return; + } + + // anything else will cause no drawing +} + + + + +/* +============================================================= + +SURFACE SHADERS + +============================================================= +*/ + +shaderCommands_t tess; +static qboolean setArraysOnce; + +/* +================= +R_BindAnimatedImage + +================= +*/ +// de-static'd because tr_quicksprite wants it +void R_BindAnimatedImage( textureBundle_t *bundle ) { + int index; + + if ( bundle->isVideoMap ) { + ri.CIN_RunCinematic(bundle->videoMapHandle); + ri.CIN_UploadCinematic(bundle->videoMapHandle); + return; + } + + if ((r_fullbright->value /*|| tr.refdef.doFullbright */) && bundle->isLightmap) + { + GL_Bind( tr.whiteImage ); + return; + } + + if ( bundle->numImageAnimations <= 1 ) { + GL_Bind( bundle->image[0] ); + return; + } + + // it is necessary to do this messy calc to make sure animations line up + // exactly with waveforms of the same frequency + index = myftol( tess.shaderTime * bundle->imageAnimationSpeed * FUNCTABLE_SIZE ); + index >>= FUNCTABLE_SIZE2; + + if ( index < 0 ) { + index = 0; // may happen with shader time offsets + } + if ( bundle->oneShotAnimMap ) + { + if ( index >= bundle->numImageAnimations ) + { + // stick on last frame + index = bundle->numImageAnimations - 1; + } + } + else + { + // loop + index %= bundle->numImageAnimations; + } + + GL_Bind( bundle->image[ index ] ); +} + +/* +================ +DrawTris + +Draws triangle outlines for debugging +================ +*/ +static void DrawTris (shaderCommands_t *input) { + GL_Bind( tr.whiteImage ); + qglColor3f (1,1,1); + + GL_State( GLS_POLYMODE_LINE | GLS_DEPTHMASK_TRUE ); + qglDepthRange( 0, 0 ); + + qglDisableClientState (GL_COLOR_ARRAY); + qglDisableClientState (GL_TEXTURE_COORD_ARRAY); + + qglVertexPointer (3, GL_FLOAT, 16, input->xyz); // padded for SIMD + + if (qglLockArraysEXT) { + qglLockArraysEXT(0, input->numVertexes); + GLimp_LogComment( "glLockArraysEXT\n" ); + } + + R_DrawElements( input->numIndexes, input->indexes ); + + if (qglUnlockArraysEXT) { + qglUnlockArraysEXT(); + GLimp_LogComment( "glUnlockArraysEXT\n" ); + } + qglDepthRange( 0, 1 ); +} + + +/* +================ +DrawNormals + +Draws vertex normals for debugging +================ +*/ +static void DrawNormals (shaderCommands_t *input) { + int i; + vec3_t temp; + + GL_Bind( tr.whiteImage ); + qglColor3f (1,1,1); + qglDepthRange( 0, 0 ); // never occluded + GL_State( GLS_POLYMODE_LINE | GLS_DEPTHMASK_TRUE ); + + qglBegin (GL_LINES); + for (i = 0 ; i < input->numVertexes ; i++) { + qglVertex3fv (input->xyz[i]); + VectorMA (input->xyz[i], 2, input->normal[i], temp); + qglVertex3fv (temp); + } + qglEnd (); + + qglDepthRange( 0, 1 ); +} + +/* +============== +RB_BeginSurface + +We must set some things up before beginning any tesselation, +because a surface may be forced to perform a RB_End due +to overflow. +============== +*/ +void RB_BeginSurface( shader_t *shader, int fogNum ) { + + shader_t *state = (shader->remappedShader) ? shader->remappedShader : shader; + + tess.numIndexes = 0; + tess.numVertexes = 0; + tess.shader = state; + tess.fogNum = fogNum; + tess.dlightBits = 0; // will be OR'd in by surface functions + tess.xstages = state->stages; + tess.numPasses = state->numUnfoggedPasses; + tess.currentStageIteratorFunc = state->optimalStageIteratorFunc; + + tess.shaderTime = backEnd.refdef.floatTime - tess.shader->timeOffset; + if (tess.shader->clampTime && tess.shaderTime >= tess.shader->clampTime) { + tess.shaderTime = tess.shader->clampTime; + } + + +} + +/* +=================== +DrawMultitextured + +output = t0 * t1 or t0 + t1 + +t0 = most upstream according to spec +t1 = most downstream according to spec +=================== +*/ +static void DrawMultitextured( shaderCommands_t *input, int stage ) { + shaderStage_t *pStage; + + pStage = tess.xstages[stage]; + + GL_State( pStage->stateBits ); + + // this is an ugly hack to work around a GeForce driver + // bug with multitexture and clip planes + if ( backEnd.viewParms.isPortal ) { + qglPolygonMode( GL_FRONT_AND_BACK, GL_FILL ); + } + + // + // base + // + GL_SelectTexture( 0 ); + qglTexCoordPointer( 2, GL_FLOAT, 0, input->svars.texcoords[0] ); + R_BindAnimatedImage( &pStage->bundle[0] ); + + // + // lightmap/secondary pass + // + GL_SelectTexture( 1 ); + qglEnable( GL_TEXTURE_2D ); + qglEnableClientState( GL_TEXTURE_COORD_ARRAY ); + + if ( r_lightmap->integer ) { + GL_TexEnv( GL_REPLACE ); + } else { + GL_TexEnv( tess.shader->multitextureEnv ); + } + + qglTexCoordPointer( 2, GL_FLOAT, 0, input->svars.texcoords[1] ); + + R_BindAnimatedImage( &pStage->bundle[1] ); + + R_DrawElements( input->numIndexes, input->indexes ); + + // + // disable texturing on TEXTURE1, then select TEXTURE0 + // + //qglDisableClientState( GL_TEXTURE_COORD_ARRAY ); + qglDisable( GL_TEXTURE_2D ); + + GL_SelectTexture( 0 ); +} + + + +/* +=================== +ProjectDlightTexture + +Perform dynamic lighting with another rendering pass +=================== +*/ +static void ProjectDlightTexture( void ) { + int i, l; + vec3_t origin; + float *texCoords; + byte *colors; + byte clipBits[SHADER_MAX_VERTEXES]; + MAC_STATIC float texCoordsArray[SHADER_MAX_VERTEXES][2]; + byte colorArray[SHADER_MAX_VERTEXES][4]; + unsigned hitIndexes[SHADER_MAX_INDEXES]; + int numIndexes; + float scale; + float radius; + vec3_t floatColor; + + if ( !backEnd.refdef.num_dlights ) { + return; + } + + for ( l = 0 ; l < backEnd.refdef.num_dlights ; l++ ) { + dlight_t *dl; + + if ( !( tess.dlightBits & ( 1 << l ) ) ) { + continue; // this surface definately doesn't have any of this light + } + texCoords = texCoordsArray[0]; + colors = colorArray[0]; + + dl = &backEnd.refdef.dlights[l]; + VectorCopy( dl->transformed, origin ); + radius = dl->radius; + scale = 1.0f / radius; + floatColor[0] = dl->color[0] * 255.0f; + floatColor[1] = dl->color[1] * 255.0f; + floatColor[2] = dl->color[2] * 255.0f; + + for ( i = 0 ; i < tess.numVertexes ; i++, texCoords += 2, colors += 4 ) { + vec3_t dist; + int clip; + float modulate; + + backEnd.pc.c_dlightVertexes++; + + VectorSubtract( origin, tess.xyz[i], dist ); + texCoords[0] = 0.5f + dist[0] * scale; + texCoords[1] = 0.5f + dist[1] * scale; + + clip = 0; + if ( texCoords[0] < 0.0f ) { + clip |= 1; + } else if ( texCoords[0] > 1.0f ) { + clip |= 2; + } + if ( texCoords[1] < 0.0f ) { + clip |= 4; + } else if ( texCoords[1] > 1.0f ) { + clip |= 8; + } + // modulate the strength based on the height and color + if ( dist[2] > radius ) { + clip |= 16; + modulate = 0.0f; + } else if ( dist[2] < -radius ) { + clip |= 32; + modulate = 0.0f; + } else { + dist[2] = Q_fabs(dist[2]); + if ( dist[2] < radius * 0.5f ) { + modulate = 1.0f; + } else { + modulate = 2.0f * (radius - dist[2]) * scale; + } + } + clipBits[i] = clip; + + colors[0] = myftol(floatColor[0] * modulate); + colors[1] = myftol(floatColor[1] * modulate); + colors[2] = myftol(floatColor[2] * modulate); + colors[3] = 255; + } + + // build a list of triangles that need light + numIndexes = 0; + for ( i = 0 ; i < tess.numIndexes ; i += 3 ) { + int a, b, c; + + a = tess.indexes[i]; + b = tess.indexes[i+1]; + c = tess.indexes[i+2]; + if ( clipBits[a] & clipBits[b] & clipBits[c] ) { + continue; // not lighted + } + hitIndexes[numIndexes] = a; + hitIndexes[numIndexes+1] = b; + hitIndexes[numIndexes+2] = c; + numIndexes += 3; + } + + if ( !numIndexes ) { + continue; + } + + qglEnableClientState( GL_TEXTURE_COORD_ARRAY ); + qglTexCoordPointer( 2, GL_FLOAT, 0, texCoordsArray[0] ); + + qglEnableClientState( GL_COLOR_ARRAY ); + qglColorPointer( 4, GL_UNSIGNED_BYTE, 0, colorArray ); + + GL_Bind( tr.dlightImage ); + // include GLS_DEPTHFUNC_EQUAL so alpha tested surfaces don't add light + // where they aren't rendered + if ( dl->additive ) { + GL_State( GLS_SRCBLEND_ONE | GLS_DSTBLEND_ONE | GLS_DEPTHFUNC_EQUAL ); + } + else { + GL_State( GLS_SRCBLEND_DST_COLOR | GLS_DSTBLEND_ONE | GLS_DEPTHFUNC_EQUAL ); + } + R_DrawElements( numIndexes, hitIndexes ); + backEnd.pc.c_totalIndexes += numIndexes; + backEnd.pc.c_dlightIndexes += numIndexes; + } +} + + +/* +=================== +RB_FogPass + +Blends a fog texture on top of everything else +=================== +*/ +static void RB_FogPass( void ) { + fog_t *fog; + int i; + + qglEnableClientState( GL_COLOR_ARRAY ); + qglColorPointer( 4, GL_UNSIGNED_BYTE, 0, tess.svars.colors ); + + qglEnableClientState( GL_TEXTURE_COORD_ARRAY); + qglTexCoordPointer( 2, GL_FLOAT, 0, tess.svars.texcoords[0] ); + + fog = tr.world->fogs + tess.fogNum; + + for ( i = 0; i < tess.numVertexes; i++ ) { + * ( int * )&tess.svars.colors[i] = fog->colorInt; + } + + RB_CalcFogTexCoords( ( float * ) tess.svars.texcoords[0] ); + + GL_Bind( tr.fogImage ); + + if ( tess.shader->fogPass == FP_EQUAL ) { + GL_State( GLS_SRCBLEND_SRC_ALPHA | GLS_DSTBLEND_ONE_MINUS_SRC_ALPHA | GLS_DEPTHFUNC_EQUAL ); + } else { + GL_State( GLS_SRCBLEND_SRC_ALPHA | GLS_DSTBLEND_ONE_MINUS_SRC_ALPHA ); + } + + R_DrawElements( tess.numIndexes, tess.indexes ); +} + +/* +=============== +ComputeColors +=============== +*/ +static void ComputeColors( shaderStage_t *pStage, int forceRGBGen ) +{ + int i; + color4ub_t *colors = tess.svars.colors; + qboolean killGen = qfalse; + + if ( tess.shader != tr.projectionShadowShader && tess.shader != tr.shadowShader && + ( backEnd.currentEntity->e.renderfx & (RF_DISINTEGRATE1|RF_DISINTEGRATE2))) + { + RB_CalcDisintegrateColors( (unsigned char *)tess.svars.colors ); + RB_CalcDisintegrateVertDeform(); + + // We've done some custom alpha and color stuff, so we can skip the rest. Let it do fog though + killGen = qtrue; + } + + // + // rgbGen + // + if ( !forceRGBGen ) + { + forceRGBGen = pStage->rgbGen; + } + + if ( backEnd.currentEntity->e.renderfx & RF_VOLUMETRIC ) // does not work for rotated models, technically, this should also be a CGEN type, but that would entail adding new shader commands....which is too much work for one thing + { + int i; + float *normal, dot; + unsigned char *color; + int numVertexes; + + normal = tess.normal[0]; + color = tess.svars.colors[0]; + + numVertexes = tess.numVertexes; + + for ( i = 0 ; i < numVertexes ; i++, normal += 4, color += 4) + { + dot = DotProduct( normal, backEnd.refdef.viewaxis[0] ); + + dot *= dot * dot * dot; + + if ( dot < 0.2f ) // so low, so just clamp it + { + dot = 0.0f; + } + + color[0] = color[1] = color[2] = color[3] = myftol( backEnd.currentEntity->e.shaderRGBA[0] * (1-dot) ); + + } + + killGen = qtrue; + } + + if (killGen) + { + goto avoidGen; + } + + // + // rgbGen + // + switch ( forceRGBGen ) + { + case CGEN_IDENTITY: + Com_Memset( tess.svars.colors, 0xff, tess.numVertexes * 4 ); + break; + default: + case CGEN_IDENTITY_LIGHTING: + Com_Memset( tess.svars.colors, tr.identityLightByte, tess.numVertexes * 4 ); + break; + case CGEN_LIGHTING_DIFFUSE: + RB_CalcDiffuseColor( ( unsigned char * ) tess.svars.colors ); + break; + case CGEN_EXACT_VERTEX: + Com_Memcpy( tess.svars.colors, tess.vertexColors, tess.numVertexes * sizeof( tess.vertexColors[0] ) ); + break; + case CGEN_CONST: + for ( i = 0; i < tess.numVertexes; i++ ) { + *(int *)tess.svars.colors[i] = *(int *)pStage->constantColor; + } + break; + case CGEN_VERTEX: + if ( tr.identityLight == 1 ) + { + Com_Memcpy( tess.svars.colors, tess.vertexColors, tess.numVertexes * sizeof( tess.vertexColors[0] ) ); + } + else + { + for ( i = 0; i < tess.numVertexes; i++ ) + { + tess.svars.colors[i][0] = tess.vertexColors[i][0] * tr.identityLight; + tess.svars.colors[i][1] = tess.vertexColors[i][1] * tr.identityLight; + tess.svars.colors[i][2] = tess.vertexColors[i][2] * tr.identityLight; + tess.svars.colors[i][3] = tess.vertexColors[i][3]; + } + } + break; + case CGEN_ONE_MINUS_VERTEX: + if ( tr.identityLight == 1 ) + { + for ( i = 0; i < tess.numVertexes; i++ ) + { + tess.svars.colors[i][0] = 255 - tess.vertexColors[i][0]; + tess.svars.colors[i][1] = 255 - tess.vertexColors[i][1]; + tess.svars.colors[i][2] = 255 - tess.vertexColors[i][2]; + } + } + else + { + for ( i = 0; i < tess.numVertexes; i++ ) + { + tess.svars.colors[i][0] = ( 255 - tess.vertexColors[i][0] ) * tr.identityLight; + tess.svars.colors[i][1] = ( 255 - tess.vertexColors[i][1] ) * tr.identityLight; + tess.svars.colors[i][2] = ( 255 - tess.vertexColors[i][2] ) * tr.identityLight; + } + } + break; + case CGEN_FOG: + { + fog_t *fog; + + fog = tr.world->fogs + tess.fogNum; + + for ( i = 0; i < tess.numVertexes; i++ ) { + * ( int * )&tess.svars.colors[i] = fog->colorInt; + } + } + break; + case CGEN_WAVEFORM: + RB_CalcWaveColor( &pStage->rgbWave, ( unsigned char * ) tess.svars.colors ); + break; + case CGEN_ENTITY: + RB_CalcColorFromEntity( ( unsigned char * ) tess.svars.colors ); + break; + case CGEN_ONE_MINUS_ENTITY: + RB_CalcColorFromOneMinusEntity( ( unsigned char * ) tess.svars.colors ); + break; + case CGEN_LIGHTMAP0: + memset( colors, 0xff, tess.numVertexes * 4 ); + break; + case CGEN_LIGHTMAP1: + for ( i = 0; i < tess.numVertexes; i++ ) + { + *(unsigned *)&colors[i] = *(unsigned *)styleColors[pStage->lightmapStyle]; + } + break; + case CGEN_LIGHTMAP2: + for ( i = 0; i < tess.numVertexes; i++ ) + { + *(unsigned *)&colors[i] = *(unsigned *)styleColors[pStage->lightmapStyle]; + } + break; + case CGEN_LIGHTMAP3: + for ( i = 0; i < tess.numVertexes; i++ ) + { + *(unsigned *)&colors[i] = *(unsigned *)styleColors[pStage->lightmapStyle]; + } + break; + + } + + // + // alphaGen + // + switch ( pStage->alphaGen ) + { + case AGEN_SKIP: + break; + case AGEN_IDENTITY: + if ( forceRGBGen != CGEN_IDENTITY ) { + if ( ( forceRGBGen == CGEN_VERTEX && tr.identityLight != 1 ) || + forceRGBGen != CGEN_VERTEX ) { + for ( i = 0; i < tess.numVertexes; i++ ) { + tess.svars.colors[i][3] = 0xff; + } + } + } + break; + case AGEN_CONST: + if ( forceRGBGen != CGEN_CONST ) { + for ( i = 0; i < tess.numVertexes; i++ ) { + tess.svars.colors[i][3] = pStage->constantColor[3]; + } + } + break; + case AGEN_WAVEFORM: + RB_CalcWaveAlpha( &pStage->alphaWave, ( unsigned char * ) tess.svars.colors ); + break; + case AGEN_LIGHTING_SPECULAR: + RB_CalcSpecularAlpha( ( unsigned char * ) tess.svars.colors ); + break; + case AGEN_ENTITY: + RB_CalcAlphaFromEntity( ( unsigned char * ) tess.svars.colors ); + break; + case AGEN_ONE_MINUS_ENTITY: + RB_CalcAlphaFromOneMinusEntity( ( unsigned char * ) tess.svars.colors ); + break; + case AGEN_VERTEX: + if ( forceRGBGen != CGEN_VERTEX ) { + for ( i = 0; i < tess.numVertexes; i++ ) { + tess.svars.colors[i][3] = tess.vertexColors[i][3]; + } + } + break; + case AGEN_ONE_MINUS_VERTEX: + for ( i = 0; i < tess.numVertexes; i++ ) + { + tess.svars.colors[i][3] = 255 - tess.vertexColors[i][3]; + } + break; + case AGEN_PORTAL: + { + unsigned char alpha; + + for ( i = 0; i < tess.numVertexes; i++ ) + { + float len; + vec3_t v; + + VectorSubtract( tess.xyz[i], backEnd.viewParms.or.origin, v ); + len = VectorLength( v ); + + len /= tess.shader->portalRange; + + if ( len < 0 ) + { + alpha = 0; + } + else if ( len > 1 ) + { + alpha = 0xff; + } + else + { + alpha = len * 0xff; + } + + tess.svars.colors[i][3] = alpha; + } + } + break; + case AGEN_BLEND: + if ( forceRGBGen != CGEN_VERTEX ) + { + for ( i = 0; i < tess.numVertexes; i++ ) + { + //colors[i][3] = tess.vertexAlphas[i][pStage->index]; // only used on SOF2, needs implementing if you want it + } + } + break; + } +avoidGen: + // + // fog adjustment for colors to fade out as fog increases + // + if ( tess.fogNum ) + { + switch ( pStage->adjustColorsForFog ) + { + case ACFF_MODULATE_RGB: + RB_CalcModulateColorsByFog( ( unsigned char * ) tess.svars.colors ); + break; + case ACFF_MODULATE_ALPHA: + RB_CalcModulateAlphasByFog( ( unsigned char * ) tess.svars.colors ); + break; + case ACFF_MODULATE_RGBA: + RB_CalcModulateRGBAsByFog( ( unsigned char * ) tess.svars.colors ); + break; + case ACFF_NONE: + break; + } + } +} + +/* +=============== +ComputeTexCoords +=============== +*/ +static void ComputeTexCoords( shaderStage_t *pStage ) { + int i; + int b; + float *texcoords; + + for ( b = 0; b < NUM_TEXTURE_BUNDLES; b++ ) { + int tm; + + texcoords = (float *)tess.svars.texcoords[b]; + // + // generate the texture coordinates + // + switch ( pStage->bundle[b].tcGen ) + { + case TCGEN_IDENTITY: + Com_Memset( tess.svars.texcoords[b], 0, sizeof( float ) * 2 * tess.numVertexes ); + break; + case TCGEN_TEXTURE: + for ( i = 0 ; i < tess.numVertexes ; i++ ) { + tess.svars.texcoords[b][i][0] = tess.texCoords[i][0][0]; + tess.svars.texcoords[b][i][1] = tess.texCoords[i][0][1]; + } + break; + case TCGEN_LIGHTMAP: + for ( i = 0 ; i < tess.numVertexes ; i++,texcoords+=2 ) { + texcoords[0] = tess.texCoords[i][1][0]; + texcoords[1] = tess.texCoords[i][1][1]; + } + break; + case TCGEN_LIGHTMAP1: + for ( i = 0 ; i < tess.numVertexes ; i++,texcoords+=2 ) { + texcoords[0] = tess.texCoords[i][2][0]; + texcoords[1] = tess.texCoords[i][2][1]; + } + break; + case TCGEN_LIGHTMAP2: + for ( i = 0 ; i < tess.numVertexes ; i++,texcoords+=2 ) { + texcoords[0] = tess.texCoords[i][3][0]; + texcoords[1] = tess.texCoords[i][3][1]; + } + break; + case TCGEN_LIGHTMAP3: + for ( i = 0 ; i < tess.numVertexes ; i++,texcoords+=2 ) { + texcoords[0] = tess.texCoords[i][4][0]; + texcoords[1] = tess.texCoords[i][4][1]; + } + break; + case TCGEN_VECTOR: + for ( i = 0 ; i < tess.numVertexes ; i++ ) { + tess.svars.texcoords[b][i][0] = DotProduct( tess.xyz[i], pStage->bundle[b].tcGenVectors[0] ); + tess.svars.texcoords[b][i][1] = DotProduct( tess.xyz[i], pStage->bundle[b].tcGenVectors[1] ); + } + break; + case TCGEN_FOG: + RB_CalcFogTexCoords( ( float * ) tess.svars.texcoords[b] ); + break; + case TCGEN_ENVIRONMENT_MAPPED: + RB_CalcEnvironmentTexCoords( ( float * ) tess.svars.texcoords[b] ); + break; + case TCGEN_BAD: + return; + } + + // + // alter texture coordinates + // + for ( tm = 0; tm < pStage->bundle[b].numTexMods ; tm++ ) { + switch ( pStage->bundle[b].texMods[tm].type ) + { + case TMOD_NONE: + tm = TR_MAX_TEXMODS; // break out of for loop + break; + + case TMOD_TURBULENT: + RB_CalcTurbulentTexCoords( &pStage->bundle[b].texMods[tm].wave, + ( float * ) tess.svars.texcoords[b] ); + break; + + case TMOD_ENTITY_TRANSLATE: + RB_CalcScrollTexCoords( backEnd.currentEntity->e.shaderTexCoord, + ( float * ) tess.svars.texcoords[b] ); + break; + + case TMOD_SCROLL: + RB_CalcScrollTexCoords( pStage->bundle[b].texMods[tm].scroll, + ( float * ) tess.svars.texcoords[b] ); + break; + + case TMOD_SCALE: + RB_CalcScaleTexCoords( pStage->bundle[b].texMods[tm].scale, + ( float * ) tess.svars.texcoords[b] ); + break; + + case TMOD_STRETCH: + RB_CalcStretchTexCoords( &pStage->bundle[b].texMods[tm].wave, + ( float * ) tess.svars.texcoords[b] ); + break; + + case TMOD_TRANSFORM: + RB_CalcTransformTexCoords( &pStage->bundle[b].texMods[tm], + ( float * ) tess.svars.texcoords[b] ); + break; + + case TMOD_ROTATE: + RB_CalcRotateTexCoords( pStage->bundle[b].texMods[tm].rotateSpeed, + ( float * ) tess.svars.texcoords[b] ); + break; + + default: + ri.Error( ERR_DROP, "ERROR: unknown texmod '%d' in shader '%s'\n", pStage->bundle[b].texMods[tm].type, tess.shader->name ); + break; + } + } + } +} + +void ForceAlpha(unsigned char *dstColors, int TR_ForceEntAlpha) +{ + int i; + + dstColors += 3; + + for ( i = 0; i < tess.numVertexes; i++, dstColors += 4 ) + { + *dstColors = TR_ForceEntAlpha; + } +} + +/* +** RB_IterateStagesGeneric +*/ +static void RB_IterateStagesGeneric( shaderCommands_t *input ) +{ + int stage; + + for ( stage = 0; stage < MAX_SHADER_STAGES; stage++ ) + { + shaderStage_t *pStage = tess.xstages[stage]; + int forceRGBGen = 0; + int stateBits = 0; + + if ( !pStage ) + { + break; + } + + if ( stage && r_lightmap->integer && !( pStage->bundle[0].isLightmap || pStage->bundle[1].isLightmap || pStage->bundle[0].vertexLightmap ) ) + { + break; + } + + stateBits = pStage->stateBits; + + if ( backEnd.currentEntity ) + { + if ( backEnd.currentEntity->e.renderfx & RF_DISINTEGRATE1 ) + { + // we want to be able to rip a hole in the thing being disintegrated, and by doing the depth-testing it avoids some kinds of artefacts, but will probably introduce others? + stateBits = GLS_SRCBLEND_SRC_ALPHA | GLS_DSTBLEND_ONE_MINUS_SRC_ALPHA | GLS_DEPTHMASK_TRUE | GLS_DEPTHTEST_DISABLE; + } + + if ( backEnd.currentEntity->e.renderfx & RF_RGB_TINT ) + {//want to use RGBGen from ent + forceRGBGen = CGEN_ENTITY; + } + } + + if (pStage->ss.surfaceSpriteType) + { + // We check for surfacesprites AFTER drawing everything else + continue; + } + + ComputeColors( pStage, forceRGBGen ); + ComputeTexCoords( pStage ); + + if ( !setArraysOnce ) + { + qglEnableClientState( GL_COLOR_ARRAY ); + qglColorPointer( 4, GL_UNSIGNED_BYTE, 0, input->svars.colors ); + } + + // + // do multitexture + // + if ( pStage->bundle[1].image[0] != 0 ) + { + DrawMultitextured( input, stage ); + } + else + { + if ( !setArraysOnce ) + { + qglTexCoordPointer( 2, GL_FLOAT, 0, input->svars.texcoords[0] ); + } + + // + // set state + // + if ( pStage->bundle[0].vertexLightmap && ( r_vertexLight->integer && !r_uiFullScreen->integer ) && r_lightmap->integer ) + { + GL_Bind( tr.whiteImage ); + } + else + R_BindAnimatedImage( &pStage->bundle[0] ); + + if (backEnd.currentEntity && (backEnd.currentEntity->e.renderfx & RF_FORCE_ENT_ALPHA)) + { + ForceAlpha((unsigned char *) tess.svars.colors, backEnd.currentEntity->e.shaderRGBA[3]); + GL_State(GLS_SRCBLEND_SRC_ALPHA | GLS_DSTBLEND_ONE_MINUS_SRC_ALPHA); + } + else + { + GL_State( stateBits ); + } + + // + // draw + // + R_DrawElements( input->numIndexes, input->indexes ); + } + } +} + + +/* +** RB_StageIteratorGeneric +*/ +void RB_StageIteratorGeneric( void ) +{ + shaderCommands_t *input; + int stage; + + input = &tess; + + RB_DeformTessGeometry(); + + // + // log this call + // + if ( r_logFile->integer ) + { + // don't just call LogComment, or we will get + // a call to va() every frame! + GLimp_LogComment( va("--- RB_StageIteratorGeneric( %s ) ---\n", tess.shader->name) ); + } + + // + // set face culling appropriately + // + GL_Cull( input->shader->cullType ); + + // set polygon offset if necessary + if ( input->shader->polygonOffset ) + { + qglEnable( GL_POLYGON_OFFSET_FILL ); + qglPolygonOffset( r_offsetFactor->value, r_offsetUnits->value ); + } + + // + // if there is only a single pass then we can enable color + // and texture arrays before we compile, otherwise we need + // to avoid compiling those arrays since they will change + // during multipass rendering + // + if ( tess.numPasses > 1 || input->shader->multitextureEnv ) + { + setArraysOnce = qfalse; + qglDisableClientState (GL_COLOR_ARRAY); + qglDisableClientState (GL_TEXTURE_COORD_ARRAY); + } + else + { + setArraysOnce = qtrue; + + qglEnableClientState( GL_COLOR_ARRAY); + qglColorPointer( 4, GL_UNSIGNED_BYTE, 0, tess.svars.colors ); + + qglEnableClientState( GL_TEXTURE_COORD_ARRAY); + qglTexCoordPointer( 2, GL_FLOAT, 0, tess.svars.texcoords[0] ); + } + + // + // lock XYZ + // + qglVertexPointer (3, GL_FLOAT, 16, input->xyz); // padded for SIMD + if (qglLockArraysEXT) + { + qglLockArraysEXT(0, input->numVertexes); + GLimp_LogComment( "glLockArraysEXT\n" ); + } + + // + // enable color and texcoord arrays after the lock if necessary + // + if ( !setArraysOnce ) + { + qglEnableClientState( GL_TEXTURE_COORD_ARRAY ); + qglEnableClientState( GL_COLOR_ARRAY ); + } + + // + // call shader function + // + RB_IterateStagesGeneric( input ); + + // + // now do any dynamic lighting needed + // + if ( tess.dlightBits && tess.shader->sort <= SS_OPAQUE + && !(tess.shader->surfaceFlags & (SURF_NODLIGHT | SURF_SKY) ) ) { + ProjectDlightTexture(); + } + + // + // now do fog + // + if ( tess.fogNum && tess.shader->fogPass ) { + RB_FogPass(); + } + + // + // unlock arrays + // + if (qglUnlockArraysEXT) + { + qglUnlockArraysEXT(); + GLimp_LogComment( "glUnlockArraysEXT\n" ); + } + + // + // reset polygon offset + // + if ( input->shader->polygonOffset ) + { + qglDisable( GL_POLYGON_OFFSET_FILL ); + } + + // Now check for surfacesprites. + if (r_surfaceSprites->integer) + { + for ( stage = 1; stage < MAX_SHADER_STAGES; stage++ ) + { + if (!tess.xstages[stage]) + { + break; + } + if (tess.xstages[stage]->ss.surfaceSpriteType) + { // Draw the surfacesprite + RB_DrawSurfaceSprites(tess.xstages[stage], input); + } + } + } +} + + +/* +** RB_StageIteratorVertexLitTexture +*/ +void RB_StageIteratorVertexLitTexture( void ) +{ + shaderCommands_t *input; + shader_t *shader; + int stage; + + input = &tess; + + shader = input->shader; + + // + // compute colors + // + RB_CalcDiffuseColor( ( unsigned char * ) tess.svars.colors ); + + // + // log this call + // + if ( r_logFile->integer ) + { + // don't just call LogComment, or we will get + // a call to va() every frame! + GLimp_LogComment( va("--- RB_StageIteratorVertexLitTexturedUnfogged( %s ) ---\n", tess.shader->name) ); + } + + // + // set face culling appropriately + // + GL_Cull( input->shader->cullType ); + + // + // set arrays and lock + // + qglEnableClientState( GL_COLOR_ARRAY); + qglEnableClientState( GL_TEXTURE_COORD_ARRAY); + + qglColorPointer( 4, GL_UNSIGNED_BYTE, 0, tess.svars.colors ); + qglTexCoordPointer( 2, GL_FLOAT, 16, tess.texCoords[0][0] ); + qglVertexPointer (3, GL_FLOAT, 16, input->xyz); + + if ( qglLockArraysEXT ) + { + qglLockArraysEXT(0, input->numVertexes); + GLimp_LogComment( "glLockArraysEXT\n" ); + } + + // + // call special shade routine + // + R_BindAnimatedImage( &tess.xstages[0]->bundle[0] ); + GL_State( tess.xstages[0]->stateBits ); + R_DrawElements( input->numIndexes, input->indexes ); + + // + // now do any dynamic lighting needed + // + if ( tess.dlightBits && tess.shader->sort <= SS_OPAQUE ) { + ProjectDlightTexture(); + } + + // + // now do fog + // + if ( tess.fogNum && tess.shader->fogPass ) { + RB_FogPass(); + } + + // + // unlock arrays + // + if (qglUnlockArraysEXT) + { + qglUnlockArraysEXT(); + GLimp_LogComment( "glUnlockArraysEXT\n" ); + } + + // Now check for surfacesprites. + if (r_surfaceSprites->integer) + { + for ( stage = 1; stage < MAX_SHADER_STAGES; stage++ ) + { + if (!tess.xstages[stage]) + { + break; + } + if (tess.xstages[stage]->ss.surfaceSpriteType) + { // Draw the surfacesprite + RB_DrawSurfaceSprites(tess.xstages[stage], input); + } + } + } +} + +//define REPLACE_MODE + +void RB_StageIteratorLightmappedMultitexture( void ) { + shaderCommands_t *input; + int stage; + + input = &tess; + + // + // log this call + // + if ( r_logFile->integer ) { + // don't just call LogComment, or we will get + // a call to va() every frame! + GLimp_LogComment( va("--- RB_StageIteratorLightmappedMultitexture( %s ) ---\n", tess.shader->name) ); + } + + // + // set face culling appropriately + // + GL_Cull( input->shader->cullType ); + + // + // set color, pointers, and lock + // + GL_State( GLS_DEFAULT ); + qglVertexPointer( 3, GL_FLOAT, 16, input->xyz ); + +#ifdef REPLACE_MODE + qglDisableClientState( GL_COLOR_ARRAY ); + qglColor3f( 1, 1, 1 ); + qglShadeModel( GL_FLAT ); +#else + qglEnableClientState( GL_COLOR_ARRAY ); + qglColorPointer( 4, GL_UNSIGNED_BYTE, 0, tess.constantColor255 ); +#endif + + // + // select base stage + // + GL_SelectTexture( 0 ); + + qglEnableClientState( GL_TEXTURE_COORD_ARRAY ); + R_BindAnimatedImage( &tess.xstages[0]->bundle[0] ); + qglTexCoordPointer( 2, GL_FLOAT, 16, tess.texCoords[0][0] ); + + // + // configure second stage + // + GL_SelectTexture( 1 ); + qglEnable( GL_TEXTURE_2D ); + if ( r_lightmap->integer ) { + GL_TexEnv( GL_REPLACE ); + } else { + GL_TexEnv( GL_MODULATE ); + } + R_BindAnimatedImage( &tess.xstages[0]->bundle[1] ); + qglEnableClientState( GL_TEXTURE_COORD_ARRAY ); + qglTexCoordPointer( 2, GL_FLOAT, 16, tess.texCoords[0][1] ); + + // + // lock arrays + // + if ( qglLockArraysEXT ) { + qglLockArraysEXT(0, input->numVertexes); + GLimp_LogComment( "glLockArraysEXT\n" ); + } + + R_DrawElements( input->numIndexes, input->indexes ); + + // + // disable texturing on TEXTURE1, then select TEXTURE0 + // + qglDisable( GL_TEXTURE_2D ); + qglDisableClientState( GL_TEXTURE_COORD_ARRAY ); + + GL_SelectTexture( 0 ); +#ifdef REPLACE_MODE + GL_TexEnv( GL_MODULATE ); + qglShadeModel( GL_SMOOTH ); +#endif + + // + // now do any dynamic lighting needed + // + if ( tess.dlightBits && tess.shader->sort <= SS_OPAQUE ) { + ProjectDlightTexture(); + } + + // + // now do fog + // + if ( tess.fogNum && tess.shader->fogPass ) { + RB_FogPass(); + } + + // + // unlock arrays + // + if ( qglUnlockArraysEXT ) { + qglUnlockArraysEXT(); + GLimp_LogComment( "glUnlockArraysEXT\n" ); + } + + // Now check for surfacesprites. + if (r_surfaceSprites->integer) + { + for ( stage = 1; stage < MAX_SHADER_STAGES; stage++ ) + { + if (!tess.xstages[stage]) + { + break; + } + if (tess.xstages[stage]->ss.surfaceSpriteType) + { // Draw the surfacesprite + RB_DrawSurfaceSprites(tess.xstages[stage], input); + } + } + } +} + +/* +** RB_EndSurface +*/ +void RB_EndSurface( void ) { + shaderCommands_t *input; + + input = &tess; + + if (input->numIndexes == 0) { + return; + } + + if (input->indexes[SHADER_MAX_INDEXES-1] != 0) { + ri.Error (ERR_DROP, "RB_EndSurface() - SHADER_MAX_INDEXES hit"); + } + if (input->xyz[SHADER_MAX_VERTEXES-1][0] != 0) { + ri.Error (ERR_DROP, "RB_EndSurface() - SHADER_MAX_VERTEXES hit"); + } + + if ( tess.shader == tr.shadowShader ) { + RB_ShadowTessEnd(); + return; + } + + // for debugging of sort order issues, stop rendering after a given sort value + if ( r_debugSort->integer && r_debugSort->integer < tess.shader->sort ) { + return; + } + + // + // update performance counters + // + backEnd.pc.c_shaders++; + backEnd.pc.c_vertexes += tess.numVertexes; + backEnd.pc.c_indexes += tess.numIndexes; + backEnd.pc.c_totalIndexes += tess.numIndexes * tess.numPasses; + if (tess.fogNum && tess.shader->fogPass > FP_NONE && tess.shader->fogPass < FP_GLFOG)// && r_drawfog->value) + { + backEnd.pc.c_totalIndexes += tess.numIndexes; + } + + // + // call off to shader specific tess end function + // + tess.currentStageIteratorFunc(); + + // + // draw debugging stuff + // + if ( r_showtris->integer && com_developer->integer ) { + DrawTris (input); + } + if ( r_shownormals->integer && com_developer->integer ) { + DrawNormals (input); + } + // clear shader so we can tell we don't have any unclosed surfaces + tess.numIndexes = 0; + + GLimp_LogComment( "----------\n" ); +} + diff --git a/CODEmp/renderer/tr_shade_calc.cpp b/CODE-mp/renderer/tr_shade_calc.cpp similarity index 100% rename from CODEmp/renderer/tr_shade_calc.cpp rename to CODE-mp/renderer/tr_shade_calc.cpp diff --git a/CODEmp/renderer/tr_shader.cpp b/CODE-mp/renderer/tr_shader.cpp similarity index 96% rename from CODEmp/renderer/tr_shader.cpp rename to CODE-mp/renderer/tr_shader.cpp index 3eb564d..c861ba9 100644 --- a/CODEmp/renderer/tr_shader.cpp +++ b/CODE-mp/renderer/tr_shader.cpp @@ -635,6 +635,7 @@ static void ParseTexMod( const char *_text, shaderStage_t *stage ) /* +/////===== Part of the VERTIGON system =====///// =================== ParseSurfaceSprites =================== @@ -768,12 +769,15 @@ static void ParseSurfaceSprites( const char *_text, shaderStage_t *stage ) stage->ss.fxGrow[1] = 0.0; stage->ss.fxAlphaStart = 1.0; stage->ss.fxAlphaEnd = 0.0; + + shader.needsNormal = qtrue; } /* +/////===== Part of the VERTIGON system =====///// =========================== ParseSurfaceSpritesOptional =========================== @@ -1095,7 +1099,6 @@ static void ParseSurfaceSpritesOptional( const char *param, const char *_text, s } - /* =================== ParseStage diff --git a/CODEmp/renderer/tr_shadows.cpp b/CODE-mp/renderer/tr_shadows.cpp similarity index 100% rename from CODEmp/renderer/tr_shadows.cpp rename to CODE-mp/renderer/tr_shadows.cpp diff --git a/CODEmp/renderer/tr_sky.cpp b/CODE-mp/renderer/tr_sky.cpp similarity index 100% rename from CODEmp/renderer/tr_sky.cpp rename to CODE-mp/renderer/tr_sky.cpp diff --git a/CODEmp/renderer/tr_surface.cpp b/CODE-mp/renderer/tr_surface.cpp similarity index 100% rename from CODEmp/renderer/tr_surface.cpp rename to CODE-mp/renderer/tr_surface.cpp diff --git a/CODE-mp/renderer/tr_surfacesprites.cpp b/CODE-mp/renderer/tr_surfacesprites.cpp new file mode 100644 index 0000000..e27d010 --- /dev/null +++ b/CODE-mp/renderer/tr_surfacesprites.cpp @@ -0,0 +1,1462 @@ +// tr_shade.c + +#include "tr_local.h" + +#include "tr_quicksprite.h" +#include "tr_worldeffects.h" + + +/////===== Part of the VERTIGON system =====///// +// The surfacesprites are a simple system. When a polygon with this shader stage on it is drawn, +// there are randomly distributed images (defined by the shader stage) placed on the surface. +// these are capable of doing effects, grass, or simple oriented sprites. +// They usually stick vertically off the surface, hence the term vertigons. + +// The vertigons are applied as part of the renderer backend. That is, they access OpenGL calls directly. + + +unsigned char randomindex, randominterval; +const float randomchart[256] = { + 0.6554f, 0.6909f, 0.4806f, 0.6218f, 0.5717f, 0.3896f, 0.0677f, 0.7356f, + 0.8333f, 0.1105f, 0.4445f, 0.8161f, 0.4689f, 0.0433f, 0.7152f, 0.0336f, + 0.0186f, 0.9140f, 0.1626f, 0.6553f, 0.8340f, 0.7094f, 0.2020f, 0.8087f, + 0.9119f, 0.8009f, 0.1339f, 0.8492f, 0.9173f, 0.5003f, 0.6012f, 0.6117f, + 0.5525f, 0.5787f, 0.1586f, 0.3293f, 0.9273f, 0.7791f, 0.8589f, 0.4985f, + 0.0883f, 0.8545f, 0.2634f, 0.4727f, 0.3624f, 0.1631f, 0.7825f, 0.0662f, + 0.6704f, 0.3510f, 0.7525f, 0.9486f, 0.4685f, 0.1535f, 0.1545f, 0.1121f, + 0.4724f, 0.8483f, 0.3833f, 0.1917f, 0.8207f, 0.3885f, 0.9702f, 0.9200f, + 0.8348f, 0.7501f, 0.6675f, 0.4994f, 0.0301f, 0.5225f, 0.8011f, 0.1696f, + 0.5351f, 0.2752f, 0.2962f, 0.7550f, 0.5762f, 0.7303f, 0.2835f, 0.4717f, + 0.1818f, 0.2739f, 0.6914f, 0.7748f, 0.7640f, 0.8355f, 0.7314f, 0.5288f, + 0.7340f, 0.6692f, 0.6813f, 0.2810f, 0.8057f, 0.0648f, 0.8749f, 0.9199f, + 0.1462f, 0.5237f, 0.3014f, 0.4994f, 0.0278f, 0.4268f, 0.7238f, 0.5107f, + 0.1378f, 0.7303f, 0.7200f, 0.3819f, 0.2034f, 0.7157f, 0.5552f, 0.4887f, + 0.0871f, 0.3293f, 0.2892f, 0.4545f, 0.0088f, 0.1404f, 0.0275f, 0.0238f, + 0.0515f, 0.4494f, 0.7206f, 0.2893f, 0.6060f, 0.5785f, 0.4182f, 0.5528f, + 0.9118f, 0.8742f, 0.3859f, 0.6030f, 0.3495f, 0.4550f, 0.9875f, 0.6900f, + 0.6416f, 0.2337f, 0.7431f, 0.9788f, 0.6181f, 0.2464f, 0.4661f, 0.7621f, + 0.7020f, 0.8203f, 0.8869f, 0.2145f, 0.7724f, 0.6093f, 0.6692f, 0.9686f, + 0.5609f, 0.0310f, 0.2248f, 0.2950f, 0.2365f, 0.1347f, 0.2342f, 0.1668f, + 0.3378f, 0.4330f, 0.2775f, 0.9901f, 0.7053f, 0.7266f, 0.4840f, 0.2820f, + 0.5733f, 0.4555f, 0.6049f, 0.0770f, 0.4760f, 0.6060f, 0.4159f, 0.3427f, + 0.1234f, 0.7062f, 0.8569f, 0.1878f, 0.9057f, 0.9399f, 0.8139f, 0.1407f, + 0.1794f, 0.9123f, 0.9493f, 0.2827f, 0.9934f, 0.0952f, 0.4879f, 0.5160f, + 0.4118f, 0.4873f, 0.3642f, 0.7470f, 0.0866f, 0.5172f, 0.6365f, 0.2676f, + 0.2407f, 0.7223f, 0.5761f, 0.1143f, 0.7137f, 0.2342f, 0.3353f, 0.6880f, + 0.2296f, 0.6023f, 0.6027f, 0.4138f, 0.5408f, 0.9859f, 0.1503f, 0.7238f, + 0.6054f, 0.2477f, 0.6804f, 0.1432f, 0.4540f, 0.9776f, 0.8762f, 0.7607f, + 0.9025f, 0.9807f, 0.0652f, 0.8661f, 0.7663f, 0.2586f, 0.3994f, 0.0335f, + 0.7328f, 0.0166f, 0.9589f, 0.4348f, 0.5493f, 0.7269f, 0.6867f, 0.6614f, + 0.6800f, 0.7804f, 0.5591f, 0.8381f, 0.0910f, 0.7573f, 0.8985f, 0.3083f, + 0.3188f, 0.8481f, 0.2356f, 0.6736f, 0.4770f, 0.4560f, 0.6266f, 0.4677f +}; + +#define WIND_DAMP_INTERVAL 50 +#define WIND_GUST_TIME 2500.0 +#define WIND_GUST_DECAY (1.0 / WIND_GUST_TIME) + +int lastSSUpdateTime = 0; +float curWindSpeed=0; +float curWindGust=5; +float curWeatherAmount=1; +vec3_t curWindBlowVect={0,0,0}, targetWindBlowVect={0,0,0}; +vec3_t curWindGrassDir={0,0,0}, targetWindGrassDir={0,0,0}; +int totalsurfsprites=0, sssurfaces=0; + +qboolean curWindPointActive=qfalse; +float curWindPointForce = 0; +vec3_t curWindPoint; +int nextGustTime=0; +float gustLeft=0; + +qboolean standardfovinitialized=qfalse; +float standardfovx = 90, standardscalex = 1.0; +float rangescalefactor=1.0; + +vec3_t ssrightvectors[4]; +vec3_t ssfwdvector; +int rightvectorcount; + +trRefEntity_t *ssLastEntityDrawn=NULL; +vec3_t ssViewOrigin, ssViewRight, ssViewUp; + + +static void R_SurfaceSpriteFrameUpdate(void) +{ + float dtime, dampfactor; // Time since last update and damping time for wind changes + float ratio; + vec3_t ang, diff, retwindvec; + float targetspeed; + vec3_t up={0,0,1}; + + if (backEnd.refdef.time == lastSSUpdateTime) + return; + + if (backEnd.refdef.time < lastSSUpdateTime) + { // Time is BEFORE the last update time, so reset everything. + curWindGust = 5; + curWindSpeed = r_windSpeed->value; + nextGustTime = 0; + gustLeft = 0; + } + + // Reset the last entity drawn, since this is a new frame. + ssLastEntityDrawn = NULL; + + // Adjust for an FOV. If things look twice as wide on the screen, pretend the shaders have twice the range. + // ASSUMPTION HERE IS THAT "standard" fov is the first one rendered. + + if (!standardfovinitialized) + { // This isn't initialized yet. + if (backEnd.refdef.fov_x > 50 && backEnd.refdef.fov_x < 135) // I don't consider anything below 50 or above 135 to be "normal". + { + standardfovx = backEnd.refdef.fov_x; + standardscalex = tan(standardfovx * 0.5 * (M_PI/180.0f)); + standardfovinitialized = qtrue; + } + else + { + standardfovx = 90; + standardscalex = tan(standardfovx * 0.5 * (M_PI/180.0f)); + } + rangescalefactor = 1.0; // Don't multiply the shader range by anything. + } + else if (standardfovx == backEnd.refdef.fov_x) + { // This is the standard FOV (or higher), don't multiply the shader range. + rangescalefactor = 1.0; + } + else + { // We are using a non-standard FOV. We need to multiply the range of the shader by a scale factor. + if (backEnd.refdef.fov_x > 135) + { + rangescalefactor = standardscalex / tan(135.0f * 0.5f * (M_PI/180.0f)); + } + else + { + rangescalefactor = standardscalex / tan(backEnd.refdef.fov_x * 0.5 * (M_PI/180.0f)); + } + } + + // Create a set of four right vectors so that vertical sprites aren't always facing the same way. + // First generate a HORIZONTAL forward vector (important). + CrossProduct(ssViewRight, up, ssfwdvector); + + // Right Zero has a nudge forward (10 degrees). + VectorScale(ssViewRight, 0.985f, ssrightvectors[0]); + VectorMA(ssrightvectors[0], 0.174f, ssfwdvector, ssrightvectors[0]); + + // Right One has a big nudge back (30 degrees). + VectorScale(ssViewRight, 0.866f, ssrightvectors[1]); + VectorMA(ssrightvectors[1], -0.5f, ssfwdvector, ssrightvectors[1]); + + + // Right two has a big nudge forward (30 degrees). + VectorScale(ssViewRight, 0.866f, ssrightvectors[2]); + VectorMA(ssrightvectors[2], 0.5f, ssfwdvector, ssrightvectors[2]); + + + // Right three has a nudge back (10 degrees). + VectorScale(ssViewRight, 0.985f, ssrightvectors[3]); + VectorMA(ssrightvectors[3], -0.174f, ssfwdvector, ssrightvectors[3]); + + + // Update the wind. + // If it is raining, get the windspeed from the rain system rather than the cvar + if (R_IsRaining() || R_IsSnowing()) + { + curWeatherAmount = 1.0; + } + else + { + curWeatherAmount = r_surfaceWeather->value; + } + + if (R_GetWindSpeed(targetspeed)) + { // We successfully got a speed from the rain system. + // Set the windgust to 5, since that looks pretty good. + targetspeed *= 0.3f; + if (targetspeed >= 1.0) + { + curWindGust = 300/targetspeed; + } + else + { + curWindGust = 0; + } + } + else + { // Use the cvar. + targetspeed = r_windSpeed->value; // Minimum gust delay, in seconds. + curWindGust = r_windGust->value; + } + + if (targetspeed > 0 && curWindGust) + { + if (gustLeft > 0) + { // We are gusting + // Add an amount to the target wind speed + targetspeed *= 1.0 + gustLeft; + + gustLeft -= (float)(backEnd.refdef.time - lastSSUpdateTime)*WIND_GUST_DECAY; + if (gustLeft <= 0) + { + nextGustTime = backEnd.refdef.time + (curWindGust*1000)*flrand(1.0f,4.0f); + } + } + else if (backEnd.refdef.time >= nextGustTime) + { // See if there is another right now + // Gust next time, mano + gustLeft = flrand(0.75f,1.5f); + } + } + + // See if there is a weather system that will tell us a windspeed. + if (R_GetWindVector(retwindvec)) + { + retwindvec[2]=0; + VectorScale(retwindvec, -1.0f, retwindvec); + vectoangles(retwindvec, ang); + } + else + { // Calculate the target wind vector based off cvars + ang[YAW] = r_windAngle->value; + } + + ang[PITCH] = -90.0 + targetspeed; + if (ang[PITCH]>-45.0) + { + ang[PITCH] = -45.0; + } + ang[ROLL] = 0; + + if (targetspeed>0) + { +// ang[YAW] += cos(tr.refdef.time*0.01+flrand(-1.0,1.0))*targetspeed*0.5; +// ang[PITCH] += sin(tr.refdef.time*0.01+flrand(-1.0,1.0))*targetspeed*0.5; + } + + // Get the grass wind vector first + AngleVectors(ang, targetWindGrassDir, NULL, NULL); + targetWindGrassDir[2]-=1.0; +// VectorScale(targetWindGrassDir, targetspeed, targetWindGrassDir); + + // Now get the general wind vector (no pitch) + ang[PITCH]=0; + AngleVectors(ang, targetWindBlowVect, NULL, NULL); + + // Start calculating a smoothing factor so wind doesn't change abruptly between speeds. + dampfactor = 1.0-r_windDampFactor->value; // We must exponent the amount LEFT rather than the amount bled off + dtime = (float)(backEnd.refdef.time - lastSSUpdateTime) * (1.0/(float)WIND_DAMP_INTERVAL); // Our dampfactor is geared towards a time interval equal to "1". + + // Note that since there are a finite number of "practical" delta millisecond values possible, + // the ratio should be initialized into a chart ultimately. + ratio = pow(dampfactor, dtime); + + // Apply this ratio to the windspeed... + curWindSpeed = targetspeed - (ratio * (targetspeed-curWindSpeed)); + + // Use the curWindSpeed to calculate the final target wind vector (with speed) + VectorScale(targetWindBlowVect, curWindSpeed, targetWindBlowVect); + VectorSubtract(targetWindBlowVect, curWindBlowVect, diff); + VectorMA(targetWindBlowVect, -ratio, diff, curWindBlowVect); + + // Update the grass vector now + VectorSubtract(targetWindGrassDir, curWindGrassDir, diff); + VectorMA(targetWindGrassDir, -ratio, diff, curWindGrassDir); + + lastSSUpdateTime = backEnd.refdef.time; + + curWindPointForce = r_windPointForce->value - (ratio * (r_windPointForce->value - curWindPointForce)); + if (curWindPointForce < 0.01) + { + curWindPointActive = qfalse; + } + else + { + curWindPointActive = qtrue; + curWindPoint[0] = r_windPointX->value; + curWindPoint[1] = r_windPointY->value; + curWindPoint[2] = 0; + } + + if (r_surfaceSprites->integer >= 2) + { + Com_Printf("Surfacesprites Drawn: %d, on %d surfaces\n", totalsurfsprites, sssurfaces); + } + + totalsurfsprites=0; + sssurfaces=0; +} + + + +///////////////////////////////////////////// +// Surface sprite calculation and drawing. +///////////////////////////////////////////// + +#define FADE_RANGE 250.0 +#define WINDPOINT_RADIUS 750.0 + +float SSVertAlpha[SHADER_MAX_VERTEXES]; +float SSVertWindForce[SHADER_MAX_VERTEXES]; +vec2_t SSVertWindDir[SHADER_MAX_VERTEXES]; + +qboolean SSAdditiveTransparency=qfalse; +qboolean SSUsingFog=qfalse; + + +///////////////////////////////////////////// +// Vertical surface sprites + +static void RB_VerticalSurfaceSprite(vec3_t loc, float width, float height, byte light, + byte alpha, float wind, float windidle, vec2_t fog, int hangdown, vec2_t skew) +{ + vec3_t loc2, right; + float angle; + float windsway; + float points[16]; + color4ub_t color; + + angle = ((loc[0]+loc[1])*0.02+(tr.refdef.time*0.0015)); + + if (windidle>0.0) + { + windsway = (height*windidle*0.075); + loc2[0] = loc[0]+skew[0]+cos(angle)*windsway; + loc2[1] = loc[1]+skew[1]+sin(angle)*windsway; + + if (hangdown) + { + loc2[2] = loc[2]-height; + } + else + { + loc2[2] = loc[2]+height; + } + } + else + { + loc2[0] = loc[0]+skew[0]; + loc2[1] = loc[1]+skew[1]; + if (hangdown) + { + loc2[2] = loc[2]-height; + } + else + { + loc2[2] = loc[2]+height; + } + } + + if (wind>0.0 && curWindSpeed > 0.001) + { + windsway = (height*wind*0.075); + + // Add the angle + VectorMA(loc2, height*wind, curWindGrassDir, loc2); + // Bob up and down + if (curWindSpeed < 40.0) + { + windsway *= curWindSpeed*(1.0/100.0); + } + else + { + windsway *= 0.4f; + } + loc2[2] += sin(angle*2.5)*windsway; + } + + VectorScale(ssrightvectors[rightvectorcount], width*0.5, right); + + color[0]=light; + color[1]=light; + color[2]=light; + color[3]=alpha; + + // Bottom right +// VectorAdd(loc, right, point); + points[0] = loc[0] + right[0]; + points[1] = loc[1] + right[1]; + points[2] = loc[2] + right[2]; + points[3] = 0; + + // Top right +// VectorAdd(loc2, right, point); + points[4] = loc2[0] + right[0]; + points[5] = loc2[1] + right[1]; + points[6] = loc2[2] + right[2]; + points[7] = 0; + + // Top left +// VectorSubtract(loc2, right, point); + points[8] = loc2[0] - right[0] + ssfwdvector[0] * width * 0.2; + points[9] = loc2[1] - right[1] + ssfwdvector[1] * width * 0.2; + points[10] = loc2[2] - right[2]; + points[11] = 0; + + // Bottom left +// VectorSubtract(loc, right, point); + points[12] = loc[0] - right[0]; + points[13] = loc[1] - right[1]; + points[14] = loc[2] - right[2]; + points[15] = 0; + + // Add the sprite to the render list. + SQuickSprite.Add(points, color, fog); +} + +static void RB_VerticalSurfaceSpriteWindPoint(vec3_t loc, float width, float height, byte light, + byte alpha, float wind, float windidle, vec2_t fog, + int hangdown, vec2_t skew, vec2_t winddiff, float windforce) +{ + vec3_t loc2, right; + float angle; + float windsway; + float points[16]; + color4ub_t color; + + if (windforce > 1) + windforce = 1; + +// wind += 1.0-windforce; + + angle = (loc[0]+loc[1])*0.02+(tr.refdef.time*0.0015); + + if (curWindSpeed <80.0) + { + windsway = (height*windidle*0.1)*(1.0+windforce); + loc2[0] = loc[0]+skew[0]+cos(angle)*windsway; + loc2[1] = loc[1]+skew[1]+sin(angle)*windsway; + } + else + { + loc2[0] = loc[0]+skew[0]; + loc2[1] = loc[1]+skew[1]; + } + if (hangdown) + { + loc2[2] = loc[2]-height; + } + else + { + loc2[2] = loc[2]+height; + } + + if (curWindSpeed > 0.001) + { + // Add the angle + VectorMA(loc2, height*wind, curWindGrassDir, loc2); + } + + loc2[0] += height*winddiff[0]*windforce; + loc2[1] += height*winddiff[1]*windforce; + loc2[2] -= height*windforce*(0.75 + 0.15*sin((tr.refdef.time + 500*windforce)*0.01)); + + VectorScale(ssrightvectors[rightvectorcount], width*0.5, right); + + color[0]=light; + color[1]=light; + color[2]=light; + color[3]=alpha; + + // Bottom right +// VectorAdd(loc, right, point); + points[0] = loc[0] + right[0]; + points[1] = loc[1] + right[1]; + points[2] = loc[2] + right[2]; + points[3] = 0; + + // Top right +// VectorAdd(loc2, right, point); + points[4] = loc2[0] + right[0]; + points[5] = loc2[1] + right[1]; + points[6] = loc2[2] + right[2]; + points[7] = 0; + + // Top left +// VectorSubtract(loc2, right, point); + points[8] = loc2[0] - right[0] + ssfwdvector[0] * width * 0.15; + points[9] = loc2[1] - right[1] + ssfwdvector[1] * width * 0.15; + points[10] = loc2[2] - right[2]; + points[11] = 0; + + // Bottom left +// VectorSubtract(loc, right, point); + points[12] = loc[0] - right[0]; + points[13] = loc[1] - right[1]; + points[14] = loc[2] - right[2]; + points[15] = 0; + + // Add the sprite to the render list. + SQuickSprite.Add(points, color, fog); +} + +static void RB_DrawVerticalSurfaceSprites( shaderStage_t *stage, shaderCommands_t *input) +{ + int curindex, curvert; + vec3_t dist; + float triarea; + vec2_t vec1to2, vec1to3; + + vec3_t v1,v2,v3; + float a1,a2,a3; + float l1,l2,l3; + vec2_t fog1, fog2, fog3; + vec2_t winddiff1, winddiff2, winddiff3; + float windforce1, windforce2, windforce3; + + float posi, posj; + float step; + float fa,fb,fc; + + vec3_t curpoint; + float width, height; + float alpha, alphapos, thisspritesfadestart, light; + + byte randomindex2; + + vec2_t skew={0,0}; + vec2_t fogv; + vec2_t winddiffv; + float windforce=0; + qboolean usewindpoint = (qboolean) !! (curWindPointActive && stage->ss.wind > 0); + + float cutdist=stage->ss.fadeMax*rangescalefactor, cutdist2=cutdist*cutdist; + float fadedist=stage->ss.fadeDist*rangescalefactor, fadedist2=fadedist*fadedist; + + assert(cutdist2 != fadedist2); + float inv_fadediff = 1.0/(cutdist2-fadedist2); + + // The faderange is the fraction amount it takes for these sprites to fade out, assuming an ideal fade range of 250 + float faderange = FADE_RANGE/(cutdist-fadedist); + + if (faderange > 1.0) + { // Don't want to force a new fade_rand + faderange = 1.0; + } + + // Quickly calc all the alphas and windstuff for each vertex + for (curvert=0; curvertnumVertexes; curvert++) + { + VectorSubtract(ssViewOrigin, input->xyz[curvert], dist); + SSVertAlpha[curvert] = 1.0 - (VectorLengthSquared(dist) - fadedist2) * inv_fadediff; + } + + // Wind only needs initialization once per tess. + if (usewindpoint && !tess.SSInitializedWind) + { + for (curvert=0; curvertnumVertexes;curvert++) + { // Calc wind at each point + dist[0]=input->xyz[curvert][0] - curWindPoint[0]; + dist[1]=input->xyz[curvert][1] - curWindPoint[1]; + step = (dist[0]*dist[0] + dist[1]*dist[1]); // dist squared + + if (step >= (float)(WINDPOINT_RADIUS*WINDPOINT_RADIUS)) + { // No wind + SSVertWindDir[curvert][0] = 0; + SSVertWindDir[curvert][1] = 0; + SSVertWindForce[curvert]=0; // Should be < 1 + } + else + { + if (step<1) + { // Don't want to divide by zero + SSVertWindDir[curvert][0] = 0; + SSVertWindDir[curvert][1] = 0; + SSVertWindForce[curvert] = curWindPointForce * stage->ss.wind; + } + else + { + step = Q_rsqrt(step); // Equals 1 over the distance. + SSVertWindDir[curvert][0] = dist[0] * step; + SSVertWindDir[curvert][1] = dist[1] * step; + step = 1.0 - (1.0 / (step * WINDPOINT_RADIUS)); // 1- (dist/maxradius) = a scale from 0 to 1 linearly dropping off + SSVertWindForce[curvert] = curWindPointForce * stage->ss.wind * step; // *step means divide by the distance. + } + } + } + tess.SSInitializedWind = qtrue; + } + + for (curindex=0; curindexnumIndexes-2; curindex+=3) + { + curvert = input->indexes[curindex]; + VectorCopy(input->xyz[curvert], v1); + if (stage->ss.facing) + { // Hang down + if (input->normal[curvert][2] > -0.5) + { + continue; + } + } + else + { // Point up + if (input->normal[curvert][2] < 0.5) + { + continue; + } + } + l1 = input->vertexColors[curvert][2]; + a1 = SSVertAlpha[curvert]; + fog1[0] = *((float *)(tess.svars.texcoords[0])+(curvert<<1)); + fog1[1] = *((float *)(tess.svars.texcoords[0])+(curvert<<1)+1); + winddiff1[0] = SSVertWindDir[curvert][0]; + winddiff1[1] = SSVertWindDir[curvert][1]; + windforce1 = SSVertWindForce[curvert]; + + curvert = input->indexes[curindex+1]; + VectorCopy(input->xyz[curvert], v2); + if (stage->ss.facing) + { // Hang down + if (input->normal[curvert][2] > -0.5) + { + continue; + } + } + else + { // Point up + if (input->normal[curvert][2] < 0.5) + { + continue; + } + } + l2 = input->vertexColors[curvert][2]; + a2 = SSVertAlpha[curvert]; + fog2[0] = *((float *)(tess.svars.texcoords[0])+(curvert<<1)); + fog2[1] = *((float *)(tess.svars.texcoords[0])+(curvert<<1)+1); + winddiff2[0] = SSVertWindDir[curvert][0]; + winddiff2[1] = SSVertWindDir[curvert][1]; + windforce2 = SSVertWindForce[curvert]; + + curvert = input->indexes[curindex+2]; + VectorCopy(input->xyz[curvert], v3); + if (stage->ss.facing) + { // Hang down + if (input->normal[curvert][2] > -0.5) + { + continue; + } + } + else + { // Point up + if (input->normal[curvert][2] < 0.5) + { + continue; + } + } + l3 = input->vertexColors[curvert][2]; + a3 = SSVertAlpha[curvert]; + fog3[0] = *((float *)(tess.svars.texcoords[0])+(curvert<<1)); + fog3[1] = *((float *)(tess.svars.texcoords[0])+(curvert<<1)+1); + winddiff3[0] = SSVertWindDir[curvert][0]; + winddiff3[1] = SSVertWindDir[curvert][1]; + windforce3 = SSVertWindForce[curvert]; + + if (a1 <= 0.0 && a2 <= 0.0 && a3 <= 0.0) + { + continue; + } + + // Find the area in order to calculate the stepsize + vec1to2[0] = v2[0] - v1[0]; + vec1to2[1] = v2[1] - v1[1]; + vec1to3[0] = v3[0] - v1[0]; + vec1to3[1] = v3[1] - v1[1]; + + // Now get the cross product of this sum. + triarea = vec1to3[0]*vec1to2[1] - vec1to3[1]*vec1to2[0]; + triarea=fabs(triarea); + if (triarea <= 1.0) + { // Insanely small abhorrent triangle. + continue; + } + step = stage->ss.density * Q_rsqrt(triarea); + + randomindex = (byte)(v1[0]+v1[1]+v2[0]+v2[1]+v3[0]+v3[1]); + randominterval = (byte)(v1[0]+v2[1]+v3[2])|0x03; // Make sure the interval is at least 3, and always odd + rightvectorcount = 0; + + for (posi=0; posi<1.0; posi+=step) + { + for (posj=0; posj<(1.0-posi); posj+=step) + { + fa=posi+randomchart[randomindex]*step; + randomindex += randominterval; + + fb=posj+randomchart[randomindex]*step; + randomindex += randominterval; + + rightvectorcount=(rightvectorcount+1)&3; + + if (fa>1.0) + continue; + + if (fb>(1.0-fa)) + continue; + + fc = 1.0-fa-fb; + + // total alpha, minus random factor so some things fade out sooner. + alphapos = a1*fa + a2*fb + a3*fc; + + // Note that the alpha at this point is a value from 1.0 to 0.0, but represents when to START fading + thisspritesfadestart = faderange + (1.0-faderange) * randomchart[randomindex]; + randomindex += randominterval; + + // Find where the alpha is relative to the fadestart, and calc the real alpha to draw at. + alpha = 1.0 - ((thisspritesfadestart-alphapos)/faderange); + if (alpha > 0.0) + { + if (alpha > 1.0) + alpha=1.0; + + if (SSUsingFog) + { + fogv[0] = fog1[0]*fa + fog2[0]*fb + fog3[0]*fc; + fogv[1] = fog1[1]*fa + fog2[1]*fb + fog3[1]*fc; + } + + if (usewindpoint) + { + winddiffv[0] = winddiff1[0]*fa + winddiff2[0]*fb + winddiff3[0]*fc; + winddiffv[1] = winddiff1[1]*fa + winddiff2[1]*fb + winddiff3[1]*fc; + windforce = windforce1*fa + windforce2*fb + windforce3*fc; + } + + VectorScale(v1, fa, curpoint); + VectorMA(curpoint, fb, v2, curpoint); + VectorMA(curpoint, fc, v3, curpoint); + + light = l1*fa + l2*fb + l3*fc; + if (SSAdditiveTransparency) + { // Additive transparency, scale light value +// light *= alpha; + light = (128 + (light*0.5))*alpha; + alpha = 1.0; + } + + randomindex2 = randomindex; + width = stage->ss.width*(1.0 + (stage->ss.variance[0]*randomchart[randomindex2])); + height = stage->ss.height*(1.0 + (stage->ss.variance[1]*randomchart[randomindex2++])); + if (randomchart[randomindex2++]>0.5) + { + width = -width; + } + if (stage->ss.fadeScale!=0 && alphapos < 1.0) + { + width *= 1.0 + (stage->ss.fadeScale*(1.0-alphapos)); + } + + if (stage->ss.vertSkew != 0) + { // flrand(-vertskew, vertskew) + skew[0] = height * ((stage->ss.vertSkew*2.0f*randomchart[randomindex2++])-stage->ss.vertSkew); + skew[1] = height * ((stage->ss.vertSkew*2.0f*randomchart[randomindex2++])-stage->ss.vertSkew); + } + + if (usewindpoint && windforce > 0 && stage->ss.wind > 0.0) + { + if (SSUsingFog) + { + RB_VerticalSurfaceSpriteWindPoint(curpoint, width, height, (byte)light, (byte)(alpha*255.0), + stage->ss.wind, stage->ss.windIdle, fogv, stage->ss.facing, skew, + winddiffv, windforce); + } + else + { + RB_VerticalSurfaceSpriteWindPoint(curpoint, width, height, (byte)light, (byte)(alpha*255.0), + stage->ss.wind, stage->ss.windIdle, NULL, stage->ss.facing, skew, + winddiffv, windforce); + } + } + else + { + if (SSUsingFog) + { + RB_VerticalSurfaceSprite(curpoint, width, height, (byte)light, (byte)(alpha*255.0), + stage->ss.wind, stage->ss.windIdle, fogv, stage->ss.facing, skew); + } + else + { + RB_VerticalSurfaceSprite(curpoint, width, height, (byte)light, (byte)(alpha*255.0), + stage->ss.wind, stage->ss.windIdle, NULL, stage->ss.facing, skew); + } + } + + totalsurfsprites++; + } + } + } + } +} + + +///////////////////////////////////////////// +// Oriented surface sprites + +static void RB_OrientedSurfaceSprite(vec3_t loc, float width, float height, byte light, byte alpha, vec2_t fog, int faceup) +{ + vec3_t loc2, right; + float points[16]; + color4ub_t color; + + color[0]=light; + color[1]=light; + color[2]=light; + color[3]=alpha; + + if (faceup) + { + width *= 0.5; + height *= 0.5; + + // Bottom right + // VectorAdd(loc, right, point); + points[0] = loc[0] + width; + points[1] = loc[1] - width; + points[2] = loc[2] + 1.0; + points[3] = 0; + + // Top right + // VectorAdd(loc, right, point); + points[4] = loc[0] + width; + points[5] = loc[1] + width; + points[6] = loc[2] + 1.0; + points[7] = 0; + + // Top left + // VectorSubtract(loc, right, point); + points[8] = loc[0] - width; + points[9] = loc[1] + width; + points[10] = loc[2] + 1.0; + points[11] = 0; + + // Bottom left + // VectorSubtract(loc, right, point); + points[12] = loc[0] - width; + points[13] = loc[1] - width; + points[14] = loc[2] + 1.0; + points[15] = 0; + } + else + { + VectorMA(loc, height, ssViewUp, loc2); + VectorScale(ssViewRight, width*0.5, right); + + // Bottom right + // VectorAdd(loc, right, point); + points[0] = loc[0] + right[0]; + points[1] = loc[1] + right[1]; + points[2] = loc[2] + right[2]; + points[3] = 0; + + // Top right + // VectorAdd(loc2, right, point); + points[4] = loc2[0] + right[0]; + points[5] = loc2[1] + right[1]; + points[6] = loc2[2] + right[2]; + points[7] = 0; + + // Top left + // VectorSubtract(loc2, right, point); + points[8] = loc2[0] - right[0]; + points[9] = loc2[1] - right[1]; + points[10] = loc2[2] - right[2]; + points[11] = 0; + + // Bottom left + // VectorSubtract(loc, right, point); + points[12] = loc[0] - right[0]; + points[13] = loc[1] - right[1]; + points[14] = loc[2] - right[2]; + points[15] = 0; + } + + // Add the sprite to the render list. + SQuickSprite.Add(points, color, fog); +} + +static void RB_DrawOrientedSurfaceSprites( shaderStage_t *stage, shaderCommands_t *input) +{ + int curindex, curvert; + vec3_t dist; + float triarea, minnormal; + vec2_t vec1to2, vec1to3; + + vec3_t v1,v2,v3; + float a1,a2,a3; + float l1,l2,l3; + vec2_t fog1, fog2, fog3; + + float posi, posj; + float step; + float fa,fb,fc; + + vec3_t curpoint; + float width, height; + float alpha, alphapos, thisspritesfadestart, light; + byte randomindex2; + vec2_t fogv; + + float cutdist=stage->ss.fadeMax*rangescalefactor, cutdist2=cutdist*cutdist; + float fadedist=stage->ss.fadeDist*rangescalefactor, fadedist2=fadedist*fadedist; + + assert(cutdist2 != fadedist2); + float inv_fadediff = 1.0/(cutdist2-fadedist2); + + // The faderange is the fraction amount it takes for these sprites to fade out, assuming an ideal fade range of 250 + float faderange = FADE_RANGE/(cutdist-fadedist); + + if (faderange > 1.0) + { // Don't want to force a new fade_rand + faderange = 1.0; + } + + if (stage->ss.facing) + { // Faceup sprite. + minnormal = 0.99f; + } + else + { // Normal oriented sprite + minnormal = 0.5f; + } + + // Quickly calc all the alphas for each vertex + for (curvert=0; curvertnumVertexes; curvert++) + { + // Calc alpha at each point + VectorSubtract(ssViewOrigin, input->xyz[curvert], dist); + SSVertAlpha[curvert] = 1.0 - (VectorLengthSquared(dist) - fadedist2) * inv_fadediff; + } + + for (curindex=0; curindexnumIndexes-2; curindex+=3) + { + curvert = input->indexes[curindex]; + VectorCopy(input->xyz[curvert], v1); + if (input->normal[curvert][2] < minnormal) + { + continue; + } + l1 = input->vertexColors[curvert][2]; + a1 = SSVertAlpha[curvert]; + fog1[0] = *((float *)(tess.svars.texcoords[0])+(curvert<<1)); + fog1[1] = *((float *)(tess.svars.texcoords[0])+(curvert<<1)+1); + + curvert = input->indexes[curindex+1]; + VectorCopy(input->xyz[curvert], v2); + if (input->normal[curvert][2] < minnormal) + { + continue; + } + l2 = input->vertexColors[curvert][2]; + a2 = SSVertAlpha[curvert]; + fog2[0] = *((float *)(tess.svars.texcoords[0])+(curvert<<1)); + fog2[1] = *((float *)(tess.svars.texcoords[0])+(curvert<<1)+1); + + curvert = input->indexes[curindex+2]; + VectorCopy(input->xyz[curvert], v3); + if (input->normal[curvert][2] < minnormal) + { + continue; + } + l3 = input->vertexColors[curvert][2]; + a3 = SSVertAlpha[curvert]; + fog3[0] = *((float *)(tess.svars.texcoords[0])+(curvert<<1)); + fog3[1] = *((float *)(tess.svars.texcoords[0])+(curvert<<1)+1); + + if (a1 <= 0.0 && a2 <= 0.0 && a3 <= 0.0) + { + continue; + } + + // Find the area in order to calculate the stepsize + vec1to2[0] = v2[0] - v1[0]; + vec1to2[1] = v2[1] - v1[1]; + vec1to3[0] = v3[0] - v1[0]; + vec1to3[1] = v3[1] - v1[1]; + + // Now get the cross product of this sum. + triarea = vec1to3[0]*vec1to2[1] - vec1to3[1]*vec1to2[0]; + triarea=fabs(triarea); + if (triarea <= 1.0) + { // Insanely small abhorrent triangle. + continue; + } + step = stage->ss.density * Q_rsqrt(triarea); + + randomindex = (byte)(v1[0]+v1[1]+v2[0]+v2[1]+v3[0]+v3[1]); + randominterval = (byte)(v1[0]+v2[1]+v3[2])|0x03; // Make sure the interval is at least 3, and always odd + + for (posi=0; posi<1.0; posi+=step) + { + for (posj=0; posj<(1.0-posi); posj+=step) + { + fa=posi+randomchart[randomindex]*step; + randomindex += randominterval; + if (fa>1.0) + continue; + + fb=posj+randomchart[randomindex]*step; + randomindex += randominterval; + if (fb>(1.0-fa)) + continue; + + fc = 1.0-fa-fb; + + // total alpha, minus random factor so some things fade out sooner. + alphapos = a1*fa + a2*fb + a3*fc; + + // Note that the alpha at this point is a value from 1.0 to 0.0, but represents when to START fading + thisspritesfadestart = faderange + (1.0-faderange) * randomchart[randomindex]; + randomindex += randominterval; + + // Find where the alpha is relative to the fadestart, and calc the real alpha to draw at. + alpha = 1.0 - ((thisspritesfadestart-alphapos)/faderange); + + randomindex += randominterval; + if (alpha > 0.0) + { + if (alpha > 1.0) + alpha=1.0; + + if (SSUsingFog) + { + fogv[0] = fog1[0]*fa + fog2[0]*fb + fog3[0]*fc; + fogv[1] = fog1[1]*fa + fog2[1]*fb + fog3[1]*fc; + } + + VectorScale(v1, fa, curpoint); + VectorMA(curpoint, fb, v2, curpoint); + VectorMA(curpoint, fc, v3, curpoint); + + light = l1*fa + l2*fb + l3*fc; + if (SSAdditiveTransparency) + { // Additive transparency, scale light value +// light *= alpha; + light = (128 + (light*0.5))*alpha; + alpha = 1.0; + } + + randomindex2 = randomindex; + width = stage->ss.width*(1.0 + (stage->ss.variance[0]*randomchart[randomindex2])); + height = stage->ss.height*(1.0 + (stage->ss.variance[1]*randomchart[randomindex2++])); + if (randomchart[randomindex2++]>0.5) + { + width = -width; + } + if (stage->ss.fadeScale!=0 && alphapos < 1.0) + { + width *= 1.0 + (stage->ss.fadeScale*(1.0-alphapos)); + } + + if (SSUsingFog) + { + RB_OrientedSurfaceSprite(curpoint, width, height, (byte)light, (byte)(alpha*255.0), fogv, stage->ss.facing); + } + else + { + RB_OrientedSurfaceSprite(curpoint, width, height, (byte)light, (byte)(alpha*255.0), NULL, stage->ss.facing); + } + + totalsurfsprites++; + } + } + } + } +} + + +///////////////////////////////////////////// +// Effect surface sprites + +static void RB_EffectSurfaceSprite(vec3_t loc, float width, float height, byte light, byte alpha, float life, int faceup) +{ + vec3_t loc2, right; + float points[16]; + color4ub_t color; + + color[0]=light; //light; + color[1]=light; //light; + color[2]=light; //light; + color[3]=alpha; //alpha; + + if (faceup) + { + width *= 0.5; + height *= 0.5; + + // Bottom right + // VectorAdd(loc, right, point); + points[0] = loc[0] + width; + points[1] = loc[1] - width; + points[2] = loc[2] + 1.0; + points[3] = 0; + + // Top right + // VectorAdd(loc, right, point); + points[4] = loc[0] + width; + points[5] = loc[1] + width; + points[6] = loc[2] + 1.0; + points[7] = 0; + + // Top left + // VectorSubtract(loc, right, point); + points[8] = loc[0] - width; + points[9] = loc[1] + width; + points[10] = loc[2] + 1.0; + points[11] = 0; + + // Bottom left + // VectorSubtract(loc, right, point); + points[12] = loc[0] - width; + points[13] = loc[1] - width; + points[14] = loc[2] + 1.0; + points[15] = 0; + } + else + { + VectorMA(loc, height, ssViewUp, loc2); + VectorScale(ssViewRight, width*0.5, right); + + // Bottom right + // VectorAdd(loc, right, point); + points[0] = loc[0] + right[0]; + points[1] = loc[1] + right[1]; + points[2] = loc[2] + right[2]; + points[3] = 0; + + // Top right + // VectorAdd(loc2, right, point); + points[4] = loc2[0] + right[0]; + points[5] = loc2[1] + right[1]; + points[6] = loc2[2] + right[2]; + points[7] = 0; + + // Top left + // VectorSubtract(loc2, right, point); + points[8] = loc2[0] - right[0]; + points[9] = loc2[1] - right[1]; + points[10] = loc2[2] - right[2]; + points[11] = 0; + + // Bottom left + // VectorSubtract(loc, right, point); + points[12] = loc[0] - right[0]; + points[13] = loc[1] - right[1]; + points[14] = loc[2] - right[2]; + points[15] = 0; + } + + // Add the sprite to the render list. + SQuickSprite.Add(points, color, NULL); +} + +static void RB_DrawEffectSurfaceSprites( shaderStage_t *stage, shaderCommands_t *input) +{ + int curindex, curvert; + vec3_t dist; + float triarea, minnormal; + vec2_t vec1to2, vec1to3; + + vec3_t v1,v2,v3; + float a1,a2,a3; + float l1,l2,l3; + + float posi, posj; + float step; + float fa,fb,fc; + float effecttime, effectpos; + float density; + + vec3_t curpoint; + float width, height; + float alpha, alphapos, thisspritesfadestart, light; + byte randomindex2; + + float cutdist=stage->ss.fadeMax*rangescalefactor, cutdist2=cutdist*cutdist; + float fadedist=stage->ss.fadeDist*rangescalefactor, fadedist2=fadedist*fadedist; + + float fxalpha = stage->ss.fxAlphaEnd - stage->ss.fxAlphaStart; + qboolean fadeinout=qfalse; + + assert(cutdist2 != fadedist2); + float inv_fadediff = 1.0/(cutdist2-fadedist2); + + // The faderange is the fraction amount it takes for these sprites to fade out, assuming an ideal fade range of 250 + float faderange = FADE_RANGE/(cutdist-fadedist); + if (faderange > 1.0f) + { // Don't want to force a new fade_rand + faderange = 1.0f; + } + + if (stage->ss.facing) + { // Faceup sprite. + minnormal = 0.99f; + } + else + { // Normal oriented sprite + minnormal = 0.5f; + } + + // Make the object fade in. + if (stage->ss.fxAlphaEnd < 0.05 && stage->ss.height >= 0.1 && stage->ss.width >= 0.1) + { // The sprite fades out, and it doesn't start at a pinpoint. Let's fade it in. + fadeinout=qtrue; + } + + if (stage->ss.surfaceSpriteType == SURFSPRITE_WEATHERFX) + { // This effect is affected by weather settings. + if (curWeatherAmount < 0.01) + { // Don't show these effects + return; + } + else + { + density = stage->ss.density / curWeatherAmount; + } + } + else + { + density = stage->ss.density; + } + + // Quickly calc all the alphas for each vertex + for (curvert=0; curvertnumVertexes; curvert++) + { + // Calc alpha at each point + VectorSubtract(ssViewOrigin, input->xyz[curvert], dist); + SSVertAlpha[curvert] = 1.0f - (VectorLengthSquared(dist) - fadedist2) * inv_fadediff; + + // Note this is the proper equation, but isn't used right now because it would be just a tad slower. + // Formula for alpha is 1.0f - ((len-fade)/(cut-fade)) + // Which is equal to (1.0+fade/(cut-fade)) - (len/(cut-fade)) + // So mult=1/(cut-fade), and base=(1+fade*mult). + // SSVertAlpha[curvert] = fadebase - (VectorLength(dist) * fademult); + + } + + for (curindex=0; curindexnumIndexes-2; curindex+=3) + { + curvert = input->indexes[curindex]; + VectorCopy(input->xyz[curvert], v1); + if (input->normal[curvert][2] < minnormal) + { + continue; + } + l1 = input->vertexColors[curvert][2]; + a1 = SSVertAlpha[curvert]; + + curvert = input->indexes[curindex+1]; + VectorCopy(input->xyz[curvert], v2); + if (input->normal[curvert][2] < minnormal) + { + continue; + } + l2 = input->vertexColors[curvert][2]; + a2 = SSVertAlpha[curvert]; + + curvert = input->indexes[curindex+2]; + VectorCopy(input->xyz[curvert], v3); + if (input->normal[curvert][2] < minnormal) + { + continue; + } + l3 = input->vertexColors[curvert][2]; + a3 = SSVertAlpha[curvert]; + + if (a1 <= 0.0f && a2 <= 0.0f && a3 <= 0.0f) + { + continue; + } + + // Find the area in order to calculate the stepsize + vec1to2[0] = v2[0] - v1[0]; + vec1to2[1] = v2[1] - v1[1]; + vec1to3[0] = v3[0] - v1[0]; + vec1to3[1] = v3[1] - v1[1]; + + // Now get the cross product of this sum. + triarea = vec1to3[0]*vec1to2[1] - vec1to3[1]*vec1to2[0]; + triarea=fabs(triarea); + if (triarea <= 1.0f) + { // Insanely small abhorrent triangle. + continue; + } + step = density * Q_rsqrt(triarea); + + randomindex = (byte)(v1[0]+v1[1]+v2[0]+v2[1]+v3[0]+v3[1]); + randominterval = (byte)(v1[0]+v2[1]+v3[2])|0x03; // Make sure the interval is at least 3, and always odd + + for (posi=0; posi<1.0f; posi+=step) + { + for (posj=0; posj<(1.0-posi); posj+=step) + { + effecttime = (tr.refdef.time+10000.0*randomchart[randomindex])/stage->ss.fxDuration; + effectpos = (float)effecttime - (int)effecttime; + + randomindex2 = randomindex+effecttime; + randomindex += randominterval; + fa=posi+randomchart[randomindex2++]*step; + if (fa>1.0f) + continue; + + fb=posj+randomchart[randomindex2++]*step; + if (fb>(1.0-fa)) + continue; + + fc = 1.0-fa-fb; + + // total alpha, minus random factor so some things fade out sooner. + alphapos = a1*fa + a2*fb + a3*fc; + + // Note that the alpha at this point is a value from 1.0f to 0.0, but represents when to START fading + thisspritesfadestart = faderange + (1.0-faderange) * randomchart[randomindex2]; + randomindex2 += randominterval; + + // Find where the alpha is relative to the fadestart, and calc the real alpha to draw at. + alpha = 1.0f - ((thisspritesfadestart-alphapos)/faderange); + if (alpha > 0.0f) + { + if (alpha > 1.0f) + alpha=1.0f; + + VectorScale(v1, fa, curpoint); + VectorMA(curpoint, fb, v2, curpoint); + VectorMA(curpoint, fc, v3, curpoint); + + light = l1*fa + l2*fb + l3*fc; + randomindex2 = randomindex; + width = stage->ss.width*(1.0f + (stage->ss.variance[0]*randomchart[randomindex2])); + height = stage->ss.height*(1.0f + (stage->ss.variance[1]*randomchart[randomindex2++])); + + width = width + (effectpos*stage->ss.fxGrow[0]*width); + height = height + (effectpos*stage->ss.fxGrow[1]*height); + + // If we want to fade in and out, that's different than a straight fade. + if (fadeinout) + { + if (effectpos > 0.5) + { // Fade out + alpha = alpha*(stage->ss.fxAlphaStart+(fxalpha*(effectpos-0.5)*2.0)); + } + else + { // Fade in + alpha = alpha*(stage->ss.fxAlphaStart+(fxalpha*(0.5-effectpos)*2.0)); + } + } + else + { // Normal fade + alpha = alpha*(stage->ss.fxAlphaStart+(fxalpha*effectpos)); + } + + if (SSAdditiveTransparency) + { // Additive transparency, scale light value +// light *= alpha; + light = (128 + (light*0.5))*alpha; + alpha = 1.0; + } + + if (randomchart[randomindex2]>0.5f) + { + width = -width; + } + if (stage->ss.fadeScale!=0 && alphapos < 1.0f) + { + width *= 1.0f + (stage->ss.fadeScale*(1.0-alphapos)); + } + + if (stage->ss.wind>0.0f && curWindSpeed > 0.001) + { + vec3_t drawpoint; + + VectorMA(curpoint, effectpos*stage->ss.wind, curWindBlowVect, drawpoint); + RB_EffectSurfaceSprite(drawpoint, width, height, (byte)light, (byte)(alpha*255.0f), stage->ss.fxDuration, stage->ss.facing); + } + else + { + RB_EffectSurfaceSprite(curpoint, width, height, (byte)light, (byte)(alpha*255.0f), stage->ss.fxDuration, stage->ss.facing); + } + + totalsurfsprites++; + } + } + } + } +} + +extern void R_WorldToLocal (vec3_t world, vec3_t localVec) ; +extern float preTransEntMatrix[16], invEntMatrix[16]; +extern void R_InvertMatrix(float *sourcemat, float *destmat); + +void RB_DrawSurfaceSprites( shaderStage_t *stage, shaderCommands_t *input) +{ + fog_t *fog; + unsigned long glbits=stage->stateBits; + + R_SurfaceSpriteFrameUpdate(); + + // + // Check fog + // + if ( tess.fogNum && tess.shader->fogPass) // && r_drawfog->value) + { + fog = tr.world->fogs + tess.fogNum; + SSUsingFog = qtrue; + SQuickSprite.StartGroup(&stage->bundle[0], glbits, fog->colorInt); + } + else + { + SSUsingFog = qfalse; + SQuickSprite.StartGroup(&stage->bundle[0], glbits); + } + + // Special provision in case the transparency is additive. + if ((glbits & (GLS_SRCBLEND_BITS|GLS_DSTBLEND_BITS)) == (GLS_SRCBLEND_ONE|GLS_DSTBLEND_ONE)) + { // Additive transparency, scale light value + SSAdditiveTransparency=qtrue; + } + else + { + SSAdditiveTransparency=qfalse; + } + + + //Check if this is a new entity transformation (incl. world entity), and update the appropriate vectors if so. + if (backEnd.currentEntity != ssLastEntityDrawn) + { + if (backEnd.currentEntity == &tr.worldEntity) + { // Drawing the world, so our job is dead-easy, in the viewparms + VectorCopy(backEnd.viewParms.or.origin, ssViewOrigin); + VectorCopy(backEnd.viewParms.or.axis[1], ssViewRight); + VectorCopy(backEnd.viewParms.or.axis[2], ssViewUp); + } + else + { // Drawing an entity, so we need to transform the viewparms to the model's coordinate system +// R_WorldPointToEntity (backEnd.viewParms.or.origin, ssViewOrigin); + R_WorldNormalToEntity (backEnd.viewParms.or.axis[1], ssViewRight); + R_WorldNormalToEntity (backEnd.viewParms.or.axis[2], ssViewUp); + VectorCopy(backEnd.or.viewOrigin, ssViewOrigin); +// R_WorldToLocal(backEnd.viewParms.or.axis[1], ssViewRight); +// R_WorldToLocal(backEnd.viewParms.or.axis[2], ssViewUp); + } + ssLastEntityDrawn = backEnd.currentEntity; + } + + switch(stage->ss.surfaceSpriteType) + { + case SURFSPRITE_VERTICAL: + RB_DrawVerticalSurfaceSprites(stage, input); + break; + case SURFSPRITE_ORIENTED: + RB_DrawOrientedSurfaceSprites(stage, input); + break; + case SURFSPRITE_EFFECT: + case SURFSPRITE_WEATHERFX: + RB_DrawEffectSurfaceSprites(stage, input); + break; + } + + SQuickSprite.EndGroup(); + + sssurfaces++; +} + diff --git a/CODEmp/renderer/tr_world.cpp b/CODE-mp/renderer/tr_world.cpp similarity index 100% rename from CODEmp/renderer/tr_world.cpp rename to CODE-mp/renderer/tr_world.cpp diff --git a/CODE-mp/renderer/vssver.scc b/CODE-mp/renderer/vssver.scc new file mode 100644 index 0000000..479bcdb Binary files /dev/null and b/CODE-mp/renderer/vssver.scc differ diff --git a/CODEmp/server/server.h b/CODE-mp/server/server.h similarity index 100% rename from CODEmp/server/server.h rename to CODE-mp/server/server.h diff --git a/CODEmp/server/sv_bot.cpp b/CODE-mp/server/sv_bot.cpp similarity index 100% rename from CODEmp/server/sv_bot.cpp rename to CODE-mp/server/sv_bot.cpp diff --git a/CODEmp/server/sv_ccmds.cpp b/CODE-mp/server/sv_ccmds.cpp similarity index 100% rename from CODEmp/server/sv_ccmds.cpp rename to CODE-mp/server/sv_ccmds.cpp diff --git a/CODEmp/server/sv_client.cpp b/CODE-mp/server/sv_client.cpp similarity index 100% rename from CODEmp/server/sv_client.cpp rename to CODE-mp/server/sv_client.cpp diff --git a/CODEmp/server/sv_game.cpp b/CODE-mp/server/sv_game.cpp similarity index 100% rename from CODEmp/server/sv_game.cpp rename to CODE-mp/server/sv_game.cpp diff --git a/CODEmp/server/sv_init.cpp b/CODE-mp/server/sv_init.cpp similarity index 100% rename from CODEmp/server/sv_init.cpp rename to CODE-mp/server/sv_init.cpp diff --git a/CODEmp/server/sv_main.cpp b/CODE-mp/server/sv_main.cpp similarity index 100% rename from CODEmp/server/sv_main.cpp rename to CODE-mp/server/sv_main.cpp diff --git a/CODEmp/server/sv_net_chan.cpp b/CODE-mp/server/sv_net_chan.cpp similarity index 100% rename from CODEmp/server/sv_net_chan.cpp rename to CODE-mp/server/sv_net_chan.cpp diff --git a/CODEmp/server/sv_rankings.cpp b/CODE-mp/server/sv_rankings.cpp similarity index 100% rename from CODEmp/server/sv_rankings.cpp rename to CODE-mp/server/sv_rankings.cpp diff --git a/CODEmp/server/sv_snapshot.cpp b/CODE-mp/server/sv_snapshot.cpp similarity index 95% rename from CODEmp/server/sv_snapshot.cpp rename to CODE-mp/server/sv_snapshot.cpp index 2b7c184..7210554 100644 --- a/CODEmp/server/sv_snapshot.cpp +++ b/CODE-mp/server/sv_snapshot.cpp @@ -328,7 +328,8 @@ static void SV_AddEntitiesVisibleFromPoint( vec3_t origin, clientSnapshot_t *fra } // broadcast entities are always sent, and so is the main player so we don't see noclip weirdness - if ( ent->r.svFlags & SVF_BROADCAST || (e == frame->ps.clientNum)) { + if ( ent->r.svFlags & SVF_BROADCAST || (e == frame->ps.clientNum) || (ent->r.broadcastClients[frame->ps.clientNum/32] & (1<<(frame->ps.clientNum%32)))) + { SV_AddEntToSnapshot( svEnt, ent, eNums ); continue; } diff --git a/CODEmp/server/sv_world.cpp b/CODE-mp/server/sv_world.cpp similarity index 100% rename from CODEmp/server/sv_world.cpp rename to CODE-mp/server/sv_world.cpp diff --git a/CODE-mp/server/vssver.scc b/CODE-mp/server/vssver.scc new file mode 100644 index 0000000..40f384d Binary files /dev/null and b/CODE-mp/server/vssver.scc differ diff --git a/CODEmp/strings/con_text.h b/CODE-mp/strings/con_text.h similarity index 100% rename from CODEmp/strings/con_text.h rename to CODE-mp/strings/con_text.h diff --git a/CODEmp/strings/str_server.h b/CODE-mp/strings/str_server.h similarity index 100% rename from CODEmp/strings/str_server.h rename to CODE-mp/strings/str_server.h diff --git a/CODE-mp/strings/vssver.scc b/CODE-mp/strings/vssver.scc new file mode 100644 index 0000000..6836433 Binary files /dev/null and b/CODE-mp/strings/vssver.scc differ diff --git a/CODE-mp/tosend.bat b/CODE-mp/tosend.bat new file mode 100644 index 0000000..ddd325a --- /dev/null +++ b/CODE-mp/tosend.bat @@ -0,0 +1,5 @@ +xcopy/y final\*.exe c:\send\game +xcopy/y final\*.dll c:\send\game +xcopy/y base\vm\cgame.* w:\game\base\vm +xcopy/y base\vm\jk2mpgame.* w:\game\base\vm +xcopy/y base\vm\ui.* w:\game\base\vm diff --git a/CODEmp/ui/keycodes.h b/CODE-mp/ui/keycodes.h similarity index 100% rename from CODEmp/ui/keycodes.h rename to CODE-mp/ui/keycodes.h diff --git a/CODE-mp/ui/mssccprj.scc b/CODE-mp/ui/mssccprj.scc new file mode 100644 index 0000000..3ad6dae --- /dev/null +++ b/CODE-mp/ui/mssccprj.scc @@ -0,0 +1,5 @@ +SCC = This is a Source Code Control file + +[ui.dsp] +SCC_Aux_Path = "\\ravend\vss_projects\jk2sof2MP" +SCC_Project_Name = "$/General/code/ui", ZAAAAAAA diff --git a/CODE-mp/ui/ui.bat b/CODE-mp/ui/ui.bat new file mode 100644 index 0000000..cb45913 --- /dev/null +++ b/CODE-mp/ui/ui.bat @@ -0,0 +1,43 @@ +del /q vm +mkdir vm +cd vm + +set cc=lcc -DQ3_VM -S -Wf-target=bytecode -Wf-g -I..\..\cgame -I..\..\game -I..\..\ui %1 + +%cc% ../ui_main.c +@if errorlevel 1 goto quit +%cc% ../../game/bg_misc.c +@if errorlevel 1 goto quit +%cc% ../../game/bg_weapons.c +@if errorlevel 1 goto quit +%cc% ../../game/bg_lib.c +@if errorlevel 1 goto quit +%cc% ../../game/q_math.c +@if errorlevel 1 goto quit +%cc% ../../game/q_shared.c +@if errorlevel 1 goto quit +%cc% ../ui_atoms.c +@if errorlevel 1 goto quit +%cc% ../ui_force.c +@if errorlevel 1 goto quit +%cc% ../ui_players.c +@if errorlevel 1 goto quit +%cc% ../ui_util.c +@if errorlevel 1 goto quit +%cc% ../ui_shared.c +@if errorlevel 1 goto quit +%cc% ../ui_gameinfo.c +@if errorlevel 1 goto quit + +sysmaker ../ui_public.h ../ui_syscalls.c ../ui_syscalls.asm +@if errorlevel 1 goto quit + +q3asm -f ../ui +@if errorlevel 1 goto quit + +mkdir "..\..\base\vm" +copy *.map "..\..\base\vm" +copy *.qvm "..\..\base\vm" + +:quit +cd .. diff --git a/CODEmp/ui/ui.def b/CODE-mp/ui/ui.def similarity index 100% rename from CODEmp/ui/ui.def rename to CODE-mp/ui/ui.def diff --git a/CODEmp/ui/ui.dsp b/CODE-mp/ui/ui.dsp similarity index 94% rename from CODEmp/ui/ui.dsp rename to CODE-mp/ui/ui.dsp index f67fdbb..8411ab2 100644 --- a/CODEmp/ui/ui.dsp +++ b/CODE-mp/ui/ui.dsp @@ -150,10 +150,6 @@ SOURCE=..\game\q_shared.c # End Source File # Begin Source File -SOURCE=.\ui.def -# End Source File -# Begin Source File - SOURCE=.\ui_atoms.c # End Source File # Begin Source File @@ -238,6 +234,10 @@ SOURCE=..\cgame\tr_types.h # End Source File # Begin Source File +SOURCE=.\ui.def +# End Source File +# Begin Source File + SOURCE=.\ui_force.h # End Source File # Begin Source File @@ -253,9 +253,15 @@ SOURCE=.\ui_public.h SOURCE=.\ui_shared.h # End Source File # End Group -# Begin Group "Resource Files" +# Begin Source File -# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" -# End Group +SOURCE=.\ui.bat +# PROP Exclude_From_Build 1 +# End Source File +# Begin Source File + +SOURCE=.\ui.q3asm +# PROP Exclude_From_Build 1 +# End Source File # End Target # End Project diff --git a/CODE-mp/ui/ui.q3asm b/CODE-mp/ui/ui.q3asm new file mode 100644 index 0000000..81ffc5f --- /dev/null +++ b/CODE-mp/ui/ui.q3asm @@ -0,0 +1,14 @@ +-o "ui" +ui_main +..\ui_syscalls +ui_atoms +ui_force +ui_players +ui_util +ui_shared +ui_gameinfo +bg_misc +bg_weapons +bg_lib +q_math +q_shared diff --git a/CODEmp/ui/ui_atoms.c b/CODE-mp/ui/ui_atoms.c similarity index 100% rename from CODEmp/ui/ui_atoms.c rename to CODE-mp/ui/ui_atoms.c diff --git a/CODEmp/ui/ui_force.c b/CODE-mp/ui/ui_force.c similarity index 85% rename from CODEmp/ui/ui_force.c rename to CODE-mp/ui/ui_force.c index 282da13..75fb52d 100644 --- a/CODEmp/ui/ui_force.c +++ b/CODE-mp/ui/ui_force.c @@ -91,29 +91,35 @@ int uiForcePowerCost[NUM_FORCE_POWERS][NUM_FORCE_POWER_LEVELS] = //0 == neutral }; -int UI_ForceStarShaders[NUM_FORCE_STAR_IMAGES][2]; - - -void UI_InitForceStarShaders(void) +int uiForceStarShaders[NUM_FORCE_STAR_IMAGES][2]; +int uiSaberColorShaders[NUM_SABER_COLORS]; +void UI_InitForceShaders(void) { - UI_ForceStarShaders[0][0] = trap_R_RegisterShaderNoMip("forcestar0"); - UI_ForceStarShaders[0][1] = trap_R_RegisterShaderNoMip("forcestar0"); - UI_ForceStarShaders[1][0] = trap_R_RegisterShaderNoMip("forcecircle1"); - UI_ForceStarShaders[1][1] = trap_R_RegisterShaderNoMip("forcestar1"); - UI_ForceStarShaders[2][0] = trap_R_RegisterShaderNoMip("forcecircle2"); - UI_ForceStarShaders[2][1] = trap_R_RegisterShaderNoMip("forcestar2"); - UI_ForceStarShaders[3][0] = trap_R_RegisterShaderNoMip("forcecircle3"); - UI_ForceStarShaders[3][1] = trap_R_RegisterShaderNoMip("forcestar3"); - UI_ForceStarShaders[4][0] = trap_R_RegisterShaderNoMip("forcecircle4"); - UI_ForceStarShaders[4][1] = trap_R_RegisterShaderNoMip("forcestar4"); - UI_ForceStarShaders[5][0] = trap_R_RegisterShaderNoMip("forcecircle5"); - UI_ForceStarShaders[5][1] = trap_R_RegisterShaderNoMip("forcestar5"); - UI_ForceStarShaders[6][0] = trap_R_RegisterShaderNoMip("forcecircle6"); - UI_ForceStarShaders[6][1] = trap_R_RegisterShaderNoMip("forcestar6"); - UI_ForceStarShaders[7][0] = trap_R_RegisterShaderNoMip("forcecircle7"); - UI_ForceStarShaders[7][1] = trap_R_RegisterShaderNoMip("forcestar7"); - UI_ForceStarShaders[8][0] = trap_R_RegisterShaderNoMip("forcecircle8"); - UI_ForceStarShaders[8][1] = trap_R_RegisterShaderNoMip("forcestar8"); + uiForceStarShaders[0][0] = trap_R_RegisterShaderNoMip("forcestar0"); + uiForceStarShaders[0][1] = trap_R_RegisterShaderNoMip("forcestar0"); + uiForceStarShaders[1][0] = trap_R_RegisterShaderNoMip("forcecircle1"); + uiForceStarShaders[1][1] = trap_R_RegisterShaderNoMip("forcestar1"); + uiForceStarShaders[2][0] = trap_R_RegisterShaderNoMip("forcecircle2"); + uiForceStarShaders[2][1] = trap_R_RegisterShaderNoMip("forcestar2"); + uiForceStarShaders[3][0] = trap_R_RegisterShaderNoMip("forcecircle3"); + uiForceStarShaders[3][1] = trap_R_RegisterShaderNoMip("forcestar3"); + uiForceStarShaders[4][0] = trap_R_RegisterShaderNoMip("forcecircle4"); + uiForceStarShaders[4][1] = trap_R_RegisterShaderNoMip("forcestar4"); + uiForceStarShaders[5][0] = trap_R_RegisterShaderNoMip("forcecircle5"); + uiForceStarShaders[5][1] = trap_R_RegisterShaderNoMip("forcestar5"); + uiForceStarShaders[6][0] = trap_R_RegisterShaderNoMip("forcecircle6"); + uiForceStarShaders[6][1] = trap_R_RegisterShaderNoMip("forcestar6"); + uiForceStarShaders[7][0] = trap_R_RegisterShaderNoMip("forcecircle7"); + uiForceStarShaders[7][1] = trap_R_RegisterShaderNoMip("forcestar7"); + uiForceStarShaders[8][0] = trap_R_RegisterShaderNoMip("forcecircle8"); + uiForceStarShaders[8][1] = trap_R_RegisterShaderNoMip("forcestar8"); + + uiSaberColorShaders[SABER_RED] = trap_R_RegisterShaderNoMip("menu/art/saber_red"); + uiSaberColorShaders[SABER_ORANGE] = trap_R_RegisterShaderNoMip("menu/art/saber_orange"); + uiSaberColorShaders[SABER_YELLOW] = trap_R_RegisterShaderNoMip("menu/art/saber_yellow"); + uiSaberColorShaders[SABER_GREEN] = trap_R_RegisterShaderNoMip("menu/art/saber_green"); + uiSaberColorShaders[SABER_BLUE] = trap_R_RegisterShaderNoMip("menu/art/saber_blue"); + uiSaberColorShaders[SABER_PURPLE] = trap_R_RegisterShaderNoMip("menu/art/saber_purple"); } @@ -139,11 +145,11 @@ void UI_DrawForceStars(rectDef_t *rect, float scale, vec4_t color, int textStyle if (val >= i) { // Draw a star. - UI_DrawHandlePic( xPos, rect->y+6, width, width, UI_ForceStarShaders[starcolor][1] ); + UI_DrawHandlePic( xPos, rect->y+6, width, width, uiForceStarShaders[starcolor][1] ); } else { // Draw a circle. - UI_DrawHandlePic( xPos, rect->y+6, width, width, UI_ForceStarShaders[starcolor][0] ); + UI_DrawHandlePic( xPos, rect->y+6, width, width, uiForceStarShaders[starcolor][0] ); } xPos += width + pad; } @@ -189,7 +195,7 @@ void UpdateForceUsed() uiForcePowersRank[FP_LEVITATION]=1; } - menu = Menus_FindByName("ingame_player"); + menu = Menus_FindByName("ingame_playerforce"); // Set the cost of the saberattack according to whether its free. if (ui_freeSaber.integer) { // Make saber free diff --git a/CODEmp/ui/ui_force.h b/CODE-mp/ui/ui_force.h similarity index 92% rename from CODEmp/ui/ui_force.h rename to CODE-mp/ui/ui_force.h index dd8c62f..c4d933e 100644 --- a/CODEmp/ui/ui_force.h +++ b/CODE-mp/ui/ui_force.h @@ -11,10 +11,11 @@ extern qboolean gTouchedForce; extern int uiForcePowersRank[NUM_FORCE_POWERS]; extern int uiForcePowerDarkLight[NUM_FORCE_POWERS]; extern int uiForcePowerCost[NUM_FORCE_POWERS][NUM_FORCE_POWER_LEVELS]; +extern int uiSaberColorShaders[NUM_SABER_COLORS]; // Dots above or equal to a given rank carry a certain color. extern vmCvar_t ui_freeSaber; -void UI_InitForceStarShaders(void); +void UI_InitForceShaders(void); void UI_DrawTotalForceStars(rectDef_t *rect, float scale, vec4_t color, int textStyle); void UI_DrawForceStars(rectDef_t *rect, float scale, vec4_t color, int textStyle, int findex, int val, int min, int max) ; void UI_UpdateClientForcePowers(); diff --git a/CODEmp/ui/ui_gameinfo.c b/CODE-mp/ui/ui_gameinfo.c similarity index 100% rename from CODEmp/ui/ui_gameinfo.c rename to CODE-mp/ui/ui_gameinfo.c diff --git a/CODEmp/ui/ui_local.h b/CODE-mp/ui/ui_local.h similarity index 100% rename from CODEmp/ui/ui_local.h rename to CODE-mp/ui/ui_local.h diff --git a/CODEmp/ui/ui_main.c b/CODE-mp/ui/ui_main.c similarity index 95% rename from CODEmp/ui/ui_main.c rename to CODE-mp/ui/ui_main.c index 80af020..6e2a3ed 100644 --- a/CODEmp/ui/ui_main.c +++ b/CODE-mp/ui/ui_main.c @@ -79,32 +79,8 @@ static const char *teamArenaGameTypes[] = { static int const numTeamArenaGameTypes = sizeof(teamArenaGameTypes) / sizeof(const char*); -static const char *teamArenaGameNames[] = { - "Free For All", - "Holocron FFA", - "Jedi Master", - "Duel", - "Single Player", - "Team FFA", - "Saga", - "Capture the Flag", - "Capture the Ysalimari", - "Team Tournament", -}; - -static int const numTeamArenaGameNames = sizeof(teamArenaGameNames) / sizeof(const char*); - - static const int numServerFilters = sizeof(serverFilters) / sizeof(serverFilter_t); -static const char *sortKeys[] = { - "Server Name", - "Map Name", - "Open Player Spots", - "Game Type", - "Ping Time" -}; -static const int numSortKeys = sizeof(sortKeys) / sizeof(const char*); static char* netnames[] = { "???", @@ -326,7 +302,7 @@ void Text_PaintWithCursor(float x, float y, float scale, vec4_t color, const cha // { char sTemp[1024]; - int iCopyCount = min(strlen(text), limit); + int iCopyCount = limit ? min(strlen(text), limit) : strlen(text); iCopyCount = min(iCopyCount,cursorPos); iCopyCount = min(iCopyCount,sizeof(sTemp)); @@ -871,6 +847,8 @@ void UI_LoadMenus(const char *menuFile, qboolean reset) { start = trap_Milliseconds(); + trap_PC_LoadGlobalDefines ( "ui/jk2mp/menudef.h" ); + handle = trap_PC_LoadSource( menuFile ); if (!handle) { trap_Error( va( S_COLOR_YELLOW "menu file not found: %s, using default\n", menuFile ) ); @@ -910,6 +888,7 @@ void UI_LoadMenus(const char *menuFile, qboolean reset) { trap_PC_FreeSource( handle ); + trap_PC_RemoveAllGlobalDefines ( ); } void UI_Load() { @@ -1184,7 +1163,7 @@ static void UI_DrawForceSide(rectDef_t *rect, float scale, vec4_t color, int tex Menu_ShowItemByName(menu, "lightpowers_team", qtrue);//(ui_gameType.integer >= GT_TEAM)); } - menu = Menus_FindByName("ingame_player"); + menu = Menus_FindByName("ingame_playerforce"); if (menu) { Menu_ShowItemByName(menu, "lightpowers", qtrue); @@ -1207,7 +1186,7 @@ static void UI_DrawForceSide(rectDef_t *rect, float scale, vec4_t color, int tex Menu_ShowItemByName(menu, "darkpowers_team", qtrue);//(ui_gameType.integer >= GT_TEAM)); } - menu = Menus_FindByName("ingame_player"); + menu = Menus_FindByName("ingame_playerforce"); if (menu) { Menu_ShowItemByName(menu, "lightpowers", qfalse); @@ -1237,10 +1216,40 @@ static void UI_DrawTeamMember(rectDef_t *rect, float scale, vec4_t color, qboole // 2..NumCharacters - Bot int value = trap_Cvar_VariableValue(va(blue ? "ui_blueteam%i" : "ui_redteam%i", num)); const char *text; - if (value <= 0) { - text = "Closed"; - } else if (value == 1) { - text = "Human"; + int maxcl = trap_Cvar_VariableValue( "sv_maxClients" ); + vec4_t finalColor; + int numval = num; + + numval *= 2; + + if (blue) + { + numval -= 1; + } + + finalColor[0] = color[0]; + finalColor[1] = color[1]; + finalColor[2] = color[2]; + finalColor[3] = color[3]; + + if (numval > maxcl) + { + finalColor[0] *= 0.2; + finalColor[1] *= 0.2; + finalColor[2] *= 0.2; + + value = -1; + } + + if (value <= 1) { + if (value == -1) + { + text = "Closed"; + } + else + { + text = "Human"; + } } else { value -= 2; @@ -1251,17 +1260,18 @@ static void UI_DrawTeamMember(rectDef_t *rect, float scale, vec4_t color, qboole text = uiInfo.characterList[value].name; } else {*/ if (value >= UI_GetNumBots()) { - value = 0; + value = 1; } text = UI_GetBotNameByNumber(value); //} } - Text_Paint(rect->x, rect->y, scale, color, text, 0, 0, textStyle, iMenuFont); + + Text_Paint(rect->x, rect->y, scale, finalColor, text, 0, 0, textStyle, iMenuFont); } -static void UI_DrawEffects(rectDef_t *rect, float scale, vec4_t color) { - UI_DrawHandlePic( rect->x, rect->y - 14, 128, 8, uiInfo.uiDC.Assets.fxBasePic ); - UI_DrawHandlePic( rect->x + uiInfo.effectsColor /* * 16*/*20 + 8, rect->y - 16, 16, 12, uiInfo.uiDC.Assets.fxPic[uiInfo.effectsColor] ); +static void UI_DrawEffects(rectDef_t *rect, float scale, vec4_t color) +{ + UI_DrawHandlePic( rect->x, rect->y, rect->w, rect->h, uiSaberColorShaders[uiInfo.effectsColor]); } static void UI_DrawMapPreview(rectDef_t *rect, float scale, vec4_t color, qboolean net) { @@ -1779,14 +1789,12 @@ static int UI_OwnerDrawWidth(int ownerDraw, float scale) { } value = trap_Cvar_VariableValue(va("ui_blueteam%i", iUse)); - if (value <= 0) { - text = "Closed"; - } else if (value == 1) { + if (value <= 1) { text = "Human"; } else { value -= 2; if (value >= uiInfo.aliasCount) { - value = 0; + value = 1; } text = uiInfo.aliasList[value].name; } @@ -1810,14 +1818,12 @@ static int UI_OwnerDrawWidth(int ownerDraw, float scale) { } value = trap_Cvar_VariableValue(va("ui_redteam%i", iUse)); - if (value <= 0) { - text = "Closed"; - } else if (value == 1) { + if (value <= 1) { text = "Human"; } else { value -= 2; if (value >= uiInfo.aliasCount) { - value = 0; + value = 1; } text = uiInfo.aliasList[value].name; } @@ -2762,6 +2768,25 @@ static qboolean UI_TeamMember_HandleKey(int flags, float *special, int key, qboo // 2..NumCharacters - Bot char *cvar = va(blue ? "ui_blueteam%i" : "ui_redteam%i", num); int value = trap_Cvar_VariableValue(cvar); + int maxcl = trap_Cvar_VariableValue( "sv_maxClients" ); + int numval = num; + + numval *= 2; + + if (blue) + { + numval -= 1; + } + + if (numval > maxcl) + { + return qfalse; + } + + if (value < 1) + { + value = 1; + } if (key == K_MOUSE2) { value--; @@ -2777,8 +2802,8 @@ static qboolean UI_TeamMember_HandleKey(int flags, float *special, int key, qboo } } else {*/ if (value >= UI_GetNumBots() + 2) { - value = 0; - } else if (value < 0) { + value = 1; + } else if (value < 1) { value = UI_GetNumBots() + 2 - 1; } //} @@ -3530,7 +3555,7 @@ static void UI_RunMenuScript(char **args) { if (String_Parse(args, &name)) { if (Q_stricmp(name, "StartServer") == 0) { - int i, clients, oldclients; + int i, added = 0; float skill; trap_Cvar_Set("cg_thirdPerson", "0"); trap_Cvar_Set("cg_cameraOrbit", "0"); @@ -3541,47 +3566,50 @@ static void UI_RunMenuScript(char **args) { trap_Cvar_Set("g_blueTeam", UI_Cvar_VariableString("ui_opponentName")); trap_Cmd_ExecuteText( EXEC_APPEND, va( "wait ; wait ; map %s\n", uiInfo.mapList[ui_currentNetMap.integer].mapLoadName ) ); skill = trap_Cvar_VariableValue( "g_spSkill" ); - // set max clients based on spots - oldclients = trap_Cvar_VariableValue( "sv_maxClients" ); - clients = 0; - for (i = 0; i < PLAYERS_PER_TEAM; i++) { - int bot = trap_Cvar_VariableValue( va("ui_blueteam%i", i+1)); - if (bot >= 0) { - clients++; - } - bot = trap_Cvar_VariableValue( va("ui_redteam%i", i+1)); - if (bot >= 0) { - clients++; - } - } - if (clients == 0) { - clients = 8; - } - - if (oldclients > clients) { - clients = oldclients; - } - - trap_Cvar_Set("sv_maxClients", va("%d",clients)); for (i = 0; i < PLAYERS_PER_TEAM; i++) { int bot = trap_Cvar_VariableValue( va("ui_blueteam%i", i+1)); + int maxcl = trap_Cvar_VariableValue( "sv_maxClients" ); + if (bot > 1) { - if (ui_actualNetGameType.integer >= GT_TEAM) { - Com_sprintf( buff, sizeof(buff), "addbot %s %f %s\n", UI_GetBotNameByNumber(bot-2), skill, "Blue"); - } else { - Com_sprintf( buff, sizeof(buff), "addbot %s %f \n", UI_GetBotNameByNumber(bot-2), skill); + int numval = i+1; + + numval *= 2; + + numval -= 1; + + if (numval <= maxcl) + { + if (ui_actualNetGameType.integer >= GT_TEAM) { + Com_sprintf( buff, sizeof(buff), "addbot %s %f %s\n", UI_GetBotNameByNumber(bot-2), skill, "Blue"); + } else { + Com_sprintf( buff, sizeof(buff), "addbot %s %f \n", UI_GetBotNameByNumber(bot-2), skill); + } + trap_Cmd_ExecuteText( EXEC_APPEND, buff ); + added++; } - trap_Cmd_ExecuteText( EXEC_APPEND, buff ); } bot = trap_Cvar_VariableValue( va("ui_redteam%i", i+1)); if (bot > 1) { - if (ui_actualNetGameType.integer >= GT_TEAM) { - Com_sprintf( buff, sizeof(buff), "addbot %s %f %s\n", UI_GetBotNameByNumber(bot-2), skill, "Red"); - } else { - Com_sprintf( buff, sizeof(buff), "addbot %s %f \n", UI_GetBotNameByNumber(bot-2), skill); + int numval = i+1; + + numval *= 2; + + if (numval <= maxcl) + { + if (ui_actualNetGameType.integer >= GT_TEAM) { + Com_sprintf( buff, sizeof(buff), "addbot %s %f %s\n", UI_GetBotNameByNumber(bot-2), skill, "Red"); + } else { + Com_sprintf( buff, sizeof(buff), "addbot %s %f \n", UI_GetBotNameByNumber(bot-2), skill); + } + trap_Cmd_ExecuteText( EXEC_APPEND, buff ); + added++; } - trap_Cmd_ExecuteText( EXEC_APPEND, buff ); + } + if (added >= maxcl) + { //this means the client filled up all their slots in the UI with bots. So stretch out an extra slot for them, and then stop adding bots. + trap_Cvar_Set("sv_maxClients", va("%i", added+1)); + break; } } } else if (Q_stricmp(name, "updateSPMenu") == 0) { @@ -3675,7 +3703,7 @@ static void UI_RunMenuScript(char **args) { trap_Cvar_Set( "fs_game", uiInfo.modList[uiInfo.modIndex].modName); trap_Cmd_ExecuteText( EXEC_APPEND, "vid_restart;" ); } else if (Q_stricmp(name, "RunDemo") == 0) { - trap_Cmd_ExecuteText( EXEC_APPEND, va("demo %s\n", uiInfo.demoList[uiInfo.demoIndex])); + trap_Cmd_ExecuteText( EXEC_APPEND, va("demo \"%s\"\n", uiInfo.demoList[uiInfo.demoIndex])); } else if (Q_stricmp(name, "Quake3") == 0) { trap_Cvar_Set( "fs_game", ""); trap_Cmd_ExecuteText( EXEC_APPEND, "vid_restart;" ); @@ -5586,14 +5614,17 @@ static void UI_BuildQ3Model_List( void ) fileptr = filelist; for (j=0; j= 0 && skinname[k] && skinname[k] != '_') + skinLen = strlen(skinname); + k = 0; + while (k < skinLen && skinname[k] && skinname[k] != '_') { - k--; + k++; } if (skinname[k] == '_') { @@ -5798,7 +5829,7 @@ void _UI_Init( qboolean inGameLoad ) { UI_LoadForceConfig_List(); - UI_InitForceStarShaders(); + UI_InitForceShaders(); // sets defaults for ui temp cvars uiInfo.effectsColor = /*gamecodetoui[*/(int)trap_Cvar_VariableValue("color1");//-1]; @@ -5901,24 +5932,48 @@ void _UI_SetActiveMenu( uiMenuCommand_t menu ) { return; case UIMENU_MAIN: + { + qboolean active = qfalse; + //trap_Cvar_Set( "sv_killserver", "1" ); trap_Key_SetCatcher( KEYCATCH_UI ); //trap_S_StartLocalSound( trap_S_RegisterSound("sound/misc/menu_background.wav", qfalse) , CHAN_LOCAL_SOUND ); //trap_S_StartBackgroundTrack("sound/misc/menu_background.wav", NULL); - if (uiInfo.inGameLoad) { + if (uiInfo.inGameLoad) + { UI_LoadNonIngame(); } + Menus_CloseAll(); Menus_ActivateByName("main"); trap_Cvar_VariableStringBuffer("com_errorMessage", buf, sizeof(buf)); - if (strlen(buf)) { - if (!ui_singlePlayerActive.integer) { + + if (strlen(buf)) + { + if (!ui_singlePlayerActive.integer) + { Menus_ActivateByName("error_popmenu"); - } else { + active = qtrue; + } + else + { trap_Cvar_Set("com_errorMessage", ""); } } - return; + + if ( !active && (int)trap_Cvar_VariableValue ( "com_othertasks" ) ) + { + trap_Cvar_Set("com_othertasks", "0"); + if ( !(int)trap_Cvar_VariableValue ( "com_ignoreothertasks" ) ) + { + Menus_ActivateByName("backgroundtask_popmenu"); + active = qtrue; + } + } + + return; + } + case UIMENU_TEAM: trap_Key_SetCatcher( KEYCATCH_UI ); Menus_ActivateByName("team"); @@ -5948,6 +6003,14 @@ void _UI_SetActiveMenu( uiMenuCommand_t menu ) { Menus_ActivateByName("ingame_player"); UpdateForceUsed(); return; + case UIMENU_PLAYERFORCE: + // trap_Cvar_Set( "cl_paused", "1" ); + trap_Key_SetCatcher( KEYCATCH_UI ); + UI_BuildPlayerList(); + Menus_CloseAll(); + Menus_ActivateByName("ingame_playerforce"); + UpdateForceUsed(); + return; } } } @@ -6299,7 +6362,6 @@ vmCvar_t ui_realCaptureLimit; vmCvar_t ui_realWarmUp; vmCvar_t ui_serverStatusTimeOut; - // bk001129 - made static to avoid aliasing static cvarTable_t cvarTable[] = { { &ui_ffa_fraglimit, "ui_ffa_fraglimit", "20", CVAR_ARCHIVE }, @@ -6421,7 +6483,6 @@ static cvarTable_t cvarTable[] = { { &ui_bigFont, "ui_bigFont", "0.4", CVAR_ARCHIVE}, { &ui_findPlayer, "ui_findPlayer", "Kyle", CVAR_ARCHIVE}, { &ui_Q3Model, "ui_q3model", "0", CVAR_ARCHIVE}, - { &ui_hudFiles, "cg_hudFiles", "ui/hud.txt", CVAR_ARCHIVE}, { &ui_recordSPDemo, "ui_recordSPDemo", "0", CVAR_ARCHIVE}, { &ui_teamArenaFirstRun, "ui_teamArenaFirstRun", "0", CVAR_ARCHIVE}, { &ui_realWarmUp, "g_warmup", "20", CVAR_ARCHIVE}, diff --git a/CODEmp/ui/ui_players.c b/CODE-mp/ui/ui_players.c similarity index 100% rename from CODEmp/ui/ui_players.c rename to CODE-mp/ui/ui_players.c diff --git a/CODEmp/ui/ui_public.h b/CODE-mp/ui/ui_public.h similarity index 92% rename from CODEmp/ui/ui_public.h rename to CODE-mp/ui/ui_public.h index 87ec1df..6a73df3 100644 --- a/CODEmp/ui/ui_public.h +++ b/CODE-mp/ui/ui_public.h @@ -83,6 +83,9 @@ typedef enum { UI_PC_FREE_SOURCE, UI_PC_READ_TOKEN, UI_PC_SOURCE_FILE_AND_LINE, + UI_PC_LOAD_GLOBAL_DEFINES, + UI_PC_REMOVE_ALL_GLOBAL_DEFINES, + UI_S_STOPBACKGROUNDTRACK, UI_S_STARTBACKGROUNDTRACK, UI_REAL_TIME, @@ -144,7 +147,8 @@ typedef enum { UIMENU_INGAME, UIMENU_PLAYERCONFIG, UIMENU_TEAM, - UIMENU_POSTGAME + UIMENU_POSTGAME, + UIMENU_PLAYERFORCE } uiMenuCommand_t; #define SORT_HOST 0 diff --git a/CODEmp/ui/ui_shared.c b/CODE-mp/ui/ui_shared.c similarity index 95% rename from CODEmp/ui/ui_shared.c rename to CODE-mp/ui/ui_shared.c index e55239b..26a2fcb 100644 --- a/CODEmp/ui/ui_shared.c +++ b/CODE-mp/ui/ui_shared.c @@ -3316,7 +3316,7 @@ static bind_t g_bindings[] = {"+attack", K_CTRL, -1, -1, -1}, {"+altattack", -1, -1, -1, -1}, {"+use", -1, -1, -1, -1}, - {"engage_duel", -1, -1, -1, -1}, + {"engage_duel", 'h', -1, -1, -1}, {"weapprev", '[', -1, -1, -1}, {"weapnext", ']', -1, -1, -1}, {"+button3", K_MOUSE3, -1, -1, -1}, @@ -3334,34 +3334,35 @@ static bind_t g_bindings[] = {"taskEscort", 'e', -1, -1, -1}, {"taskOwnFlag", 'i', -1, -1, -1}, {"taskSuicide", 'k', -1, -1, -1}, - {"tauntKillInsult", K_F1, -1, -1, -1}, - {"tauntPraise", K_F2, -1, -1, -1}, - {"tauntTaunt", K_F3, -1, -1, -1}, - {"tauntDeathInsult",K_F4, -1, -1, -1}, - {"tauntGauntlet", K_F5, -1, -1, -1}, + {"tauntKillInsult", -1, -1, -1, -1}, + {"tauntPraise", -1, -1, -1, -1}, + {"tauntTaunt", -1, -1, -1, -1}, + {"tauntDeathInsult",-1, -1, -1, -1}, + {"tauntGauntlet", -1, -1, -1, -1}, {"scoresUp", K_KP_PGUP, -1, -1, -1}, {"scoresDown", K_KP_PGDN, -1, -1, -1}, - // bk001205 - this one below was: '-1' {"messagemode", -1, -1, -1, -1}, {"messagemode2", -1, -1, -1, -1}, {"messagemode3", -1, -1, -1, -1}, {"messagemode4", -1, -1, -1, -1}, {"+use", -1, -1, -1, -1}, {"+force_jump", -1, -1, -1, -1}, - {"+force_grip", -1, -1, -1, -1}, - {"+force_lightning",-1, -1, -1, -1}, + {"force_throw", K_F1, -1, -1, -1}, + {"force_pull", K_F2, -1, -1, -1}, + {"force_speed", K_F3, -1, -1, -1}, + {"force_distract", K_F4, -1, -1, -1}, + {"force_heal", K_F5, -1, -1, -1}, + {"+force_grip", K_F6, -1, -1, -1}, + {"+force_lightning",K_F7, -1, -1, -1}, +//mp only {"+force_drain", -1, -1, -1, -1}, - {"force_heal", -1, -1, -1, -1}, - {"force_speed", -1, -1, -1, -1}, - {"force_throw", -1, -1, -1, -1}, - {"force_pull", -1, -1, -1, -1}, - {"force_distract", -1, -1, -1, -1}, {"force_rage", -1, -1, -1, -1}, {"force_protect", -1, -1, -1, -1}, {"force_absorb", -1, -1, -1, -1}, {"force_healother", -1, -1, -1, -1}, {"force_forcepowerother", -1, -1, -1, -1}, {"force_seeing", -1, -1, -1, -1}, + {"+useforce", -1, -1, -1, -1}, {"forcenext", -1, -1, -1, -1}, {"forceprev", -1, -1, -1, -1}, @@ -3372,6 +3373,7 @@ static bind_t g_bindings[] = {"use_bacta", -1, -1, -1, -1}, {"use_electrobinoculars", -1, -1, -1, -1}, {"use_sentry", -1, -1, -1, -1}, + {"cg_thirdperson !",-1, -1, -1, -1}, }; @@ -4824,7 +4826,7 @@ qboolean ItemParse_flag( itemDef_t *item, int handle) if (itemFlags[i].string == NULL) { - Com_Printf(S_COLOR_YELLOW,va("Unknown item style value '%s'",tempStr)); + Com_Printf(va( S_COLOR_YELLOW "Unknown item style value '%s'",tempStr)); } return qtrue; @@ -5032,13 +5034,12 @@ qboolean ItemParse_textalign( itemDef_t *item, int handle ) { if (!PC_Int_Parse(handle, &item->textalignment)) { + Com_Printf(S_COLOR_YELLOW "Unknown text alignment value"); + return qfalse; } - Com_Printf(S_COLOR_YELLOW,"Unknown text alignment value"); - return qtrue; - } qboolean ItemParse_textalignx( itemDef_t *item, int handle ) { @@ -5198,6 +5199,23 @@ qboolean ItemParse_action( itemDef_t *item, int handle ) { return qtrue; } +qboolean ItemParse_stripedFile( itemDef_t *item, int handle ) { + + char *tempStr; + + if (!PC_String_Parse(handle, (const char **)&tempStr)) { + return qfalse; + } + + Q_strncpyz( (char *) DC->Assets.stripedFile, tempStr, sizeof(DC->Assets.stripedFile) ); + + trap_SP_Register(DC->Assets.stripedFile); + + Menu_currentStipEdFile(DC->Assets.stripedFile); + + return qtrue; +} + qboolean ItemParse_special( itemDef_t *item, int handle ) { if (!PC_Float_Parse(handle, &item->special)) { return qfalse; @@ -5513,6 +5531,7 @@ keywordHash_t itemParseKeywords[] = { {"rect", ItemParse_rect, NULL }, {"showCvar", ItemParse_showCvar, NULL }, {"special", ItemParse_special, NULL }, + {"stripedFile", ItemParse_stripedFile, NULL }, {"style", ItemParse_style, NULL }, {"text", ItemParse_text, NULL }, {"textalign", ItemParse_textalign, NULL }, @@ -5656,30 +5675,14 @@ MenuParse_style */ qboolean MenuParse_style( itemDef_t *item, int handle) { - int i; - char *tempStr; menuDef_t *menu = (menuDef_t*)item; - if (!PC_String_Parse(handle, (const char **)&tempStr)) + if (!PC_Int_Parse(handle, &menu->window.style)) { + Com_Printf(S_COLOR_YELLOW "Unknown menu style value"); return qfalse; } - i=0; - while (styles[i]) - { - if (Q_stricmp(tempStr,styles[i])==0) - { - menu->window.style = i; - break; - } - i++; - } - - if (styles[i] == NULL) - { - Com_Printf(S_COLOR_YELLOW,va("Unknown menu style value '%s'",tempStr)); - } return qtrue; } @@ -5763,11 +5766,10 @@ qboolean MenuParse_descAlignment( itemDef_t *item, int handle ) if (!PC_Int_Parse(handle, &menu->descAlignment)) { + Com_Printf(S_COLOR_YELLOW "Unknown desc alignment value"); return qfalse; } - Com_Printf(S_COLOR_YELLOW,"Unknown desc alignment value"); - return qtrue; } diff --git a/CODEmp/ui/ui_shared.h b/CODE-mp/ui/ui_shared.h similarity index 95% rename from CODEmp/ui/ui_shared.h rename to CODE-mp/ui/ui_shared.h index 02a5a87..28e357d 100644 --- a/CODEmp/ui/ui_shared.h +++ b/CODE-mp/ui/ui_shared.h @@ -447,11 +447,14 @@ void Controls_GetConfig( void ); void Controls_SetConfig(qboolean restart); void Controls_SetDefaults( void ); -int trap_PC_AddGlobalDefine( char *define ); -int trap_PC_LoadSource( const char *filename ); -int trap_PC_FreeSource( int handle ); -int trap_PC_ReadToken( int handle, pc_token_t *pc_token ); -int trap_PC_SourceFileAndLine( int handle, char *filename, int *line ); +int trap_PC_AddGlobalDefine ( char *define ); +int trap_PC_LoadSource ( const char *filename ); +int trap_PC_FreeSource ( int handle ); +int trap_PC_ReadToken ( int handle, pc_token_t *pc_token ); +int trap_PC_SourceFileAndLine ( int handle, char *filename, int *line ); +int trap_PC_LoadGlobalDefines ( const char* filename ); +void trap_PC_RemoveAllGlobalDefines ( void ); + void trap_SP_RegisterServer( const char *package ); void trap_SP_Register(char *file ); void Menu_currentStipEdFile(char *stripEdFile); diff --git a/CODEmp/ui/ui_syscalls.c b/CODE-mp/ui/ui_syscalls.c similarity index 94% rename from CODEmp/ui/ui_syscalls.c rename to CODE-mp/ui/ui_syscalls.c index 233e3da..1815354 100644 --- a/CODEmp/ui/ui_syscalls.c +++ b/CODE-mp/ui/ui_syscalls.c @@ -353,6 +353,16 @@ int trap_PC_SourceFileAndLine( int handle, char *filename, int *line ) { return syscall( UI_PC_SOURCE_FILE_AND_LINE, handle, filename, line ); } +int trap_PC_LoadGlobalDefines ( const char* filename ) +{ + return syscall ( UI_PC_LOAD_GLOBAL_DEFINES, filename ); +} + +void trap_PC_RemoveAllGlobalDefines ( void ) +{ + syscall ( UI_PC_REMOVE_ALL_GLOBAL_DEFINES ); +} + void trap_S_StopBackgroundTrack( void ) { syscall( UI_S_STOPBACKGROUNDTRACK ); } diff --git a/CODEmp/ui/ui_util.c b/CODE-mp/ui/ui_util.c similarity index 100% rename from CODEmp/ui/ui_util.c rename to CODE-mp/ui/ui_util.c diff --git a/CODE-mp/ui/vssver.scc b/CODE-mp/ui/vssver.scc new file mode 100644 index 0000000..69aab8a Binary files /dev/null and b/CODE-mp/ui/vssver.scc differ diff --git a/CODE-mp/vssver.scc b/CODE-mp/vssver.scc new file mode 100644 index 0000000..3728913 Binary files /dev/null and b/CODE-mp/vssver.scc differ diff --git a/CODEmp/win32/glw_win.h b/CODE-mp/win32/glw_win.h similarity index 87% rename from CODEmp/win32/glw_win.h rename to CODE-mp/win32/glw_win.h index cb08641..bbdeba0 100644 --- a/CODEmp/win32/glw_win.h +++ b/CODE-mp/win32/glw_win.h @@ -27,4 +27,6 @@ typedef struct extern glwstate_t glw_state; +bool GL_CheckForExtension(const char *ext); + #endif diff --git a/CODEmp/win32/qe3.ico b/CODE-mp/win32/qe3.ico similarity index 100% rename from CODEmp/win32/qe3.ico rename to CODE-mp/win32/qe3.ico diff --git a/CODEmp/win32/resource.h b/CODE-mp/win32/resource.h similarity index 100% rename from CODEmp/win32/resource.h rename to CODE-mp/win32/resource.h diff --git a/CODE-mp/win32/vssver.scc b/CODE-mp/win32/vssver.scc new file mode 100644 index 0000000..5ce0ab8 Binary files /dev/null and b/CODE-mp/win32/vssver.scc differ diff --git a/CODEmp/win32/win_gamma.cpp b/CODE-mp/win32/win_gamma.cpp similarity index 100% rename from CODEmp/win32/win_gamma.cpp rename to CODE-mp/win32/win_gamma.cpp diff --git a/CODEmp/win32/win_glimp.cpp b/CODE-mp/win32/win_glimp.cpp similarity index 93% rename from CODEmp/win32/win_glimp.cpp rename to CODE-mp/win32/win_glimp.cpp index 0ac9ed7..64eb0dd 100644 --- a/CODEmp/win32/win_glimp.cpp +++ b/CODE-mp/win32/win_glimp.cpp @@ -901,6 +901,31 @@ static rserr_t GLW_SetMode( int mode, return RSERR_OK; } +/* +** GLW_CheckForExtension + + Cannot use strstr directly to differentiate between (for eg) reg_combiners and reg_combiners2 +*/ + +bool GL_CheckForExtension(const char *ext) +{ + char *temp; + char term; + + temp = strstr(glConfig.extensions_string, ext); + if(!temp) + { + return(false); + } + // String exists but it may not be terminated + term = temp[strlen(ext)]; + if((term == ' ') || !term) + { + return(true); + } + return(false); +} + /* ** GLW_InitExtensions */ @@ -914,26 +939,6 @@ static void GLW_InitExtensions( void ) ri.Printf( PRINT_ALL, "Initializing OpenGL extensions\n" ); - // GL_S3_s3tc - glConfig.textureCompression = TC_NONE; - if ( strstr( glConfig.extensions_string, "GL_S3_s3tc" ) ) - { - if ( r_ext_compressed_textures->integer ) - { - glConfig.textureCompression = TC_S3TC; - ri.Printf( PRINT_ALL, "...using GL_S3_s3tc\n" ); - } - else - { - glConfig.textureCompression = TC_NONE; - ri.Printf( PRINT_ALL, "...ignoring GL_S3_s3tc\n" ); - } - } - else - { - ri.Printf( PRINT_ALL, "...GL_S3_s3tc not found\n" ); - } - // GL_EXT_texture_env_add glConfig.textureEnvAddAvailable = qfalse; if ( strstr( glConfig.extensions_string, "EXT_texture_env_add" ) ) @@ -1252,15 +1257,10 @@ void GLimp_Init( void ) GLW_StartOpenGL(); // get our config strings - glConfig.vendor_string = (const char *) qglGetString (GL_VENDOR); - glConfig.renderer_string = (const char *) qglGetString (GL_RENDERER); - glConfig.version_string = (const char *) qglGetString (GL_VERSION); - glConfig.extensions_string = (const char *) qglGetString (GL_EXTENSIONS); - - if (!glConfig.vendor_string || !glConfig.renderer_string || !glConfig.version_string || !glConfig.extensions_string) - { - ri.Error( ERR_FATAL, "GLimp_Init() - Invalid GL Driver\n" ); - } + Q_strncpyz( glConfig.vendor_string, (const char *)qglGetString (GL_VENDOR), sizeof( glConfig.vendor_string ) ); + Q_strncpyz( glConfig.renderer_string, (const char *)qglGetString (GL_RENDERER), sizeof( glConfig.renderer_string ) ); + Q_strncpyz( glConfig.version_string, (const char *)qglGetString (GL_VERSION), sizeof( glConfig.version_string ) ); + Q_strncpyz( glConfig.extensions_string, (const char *)qglGetString (GL_EXTENSIONS), sizeof( glConfig.extensions_string ) ); // // chipset specific configuration diff --git a/CODEmp/win32/win_input.cpp b/CODE-mp/win32/win_input.cpp similarity index 100% rename from CODEmp/win32/win_input.cpp rename to CODE-mp/win32/win_input.cpp diff --git a/CODEmp/win32/win_local.h b/CODE-mp/win32/win_local.h similarity index 100% rename from CODEmp/win32/win_local.h rename to CODE-mp/win32/win_local.h diff --git a/CODEmp/win32/win_main.cpp b/CODE-mp/win32/win_main.cpp similarity index 91% rename from CODEmp/win32/win_main.cpp rename to CODE-mp/win32/win_main.cpp index 2de0766..3742310 100644 --- a/CODEmp/win32/win_main.cpp +++ b/CODE-mp/win32/win_main.cpp @@ -26,6 +26,72 @@ static char sys_cmdline[MAX_STRING_CHARS]; static int sys_monkeySpank; static int sys_checksum; + +static unsigned busyCount = 0; +static bool otherTasksRunning = false; +unsigned otherTaskTime = 0; + +#pragma optimize("", off) + +void busyFunction(void) +{ + float a = MEM_THRESHOLD; + float b = 9343; + short c = 4; + + while((int)b > (float)(b-1)) + { + a = a + b / c; + busyCount++; + } +} + +void CheckProcessTime(void) +{ + HANDLE threadHandle; + int threadId; + FILETIME creationTime; // thread creation time + FILETIME exitTime; // thread exit time + FILETIME kernelTime; // thread kernel-mode time + FILETIME userTime; // thread user-mode time +// char temp[1024]; + + busyCount = 0; + threadHandle = CreateThread( + NULL, // LPSECURITY_ATTRIBUTES lpsa, + 0, // DWORD cbStack, + (LPTHREAD_START_ROUTINE)busyFunction, // LPTHREAD_START_ROUTINE lpStartAddr, + 0, // LPVOID lpvThreadParm, + CREATE_SUSPENDED, // DWORD fdwCreate, + (unsigned long *)&threadId ); + + SetThreadPriority(threadHandle, THREAD_PRIORITY_IDLE); + ResumeThread(threadHandle); + while(busyCount < 10) + { + Sleep(100); + } + Sleep(1000); + + TerminateThread(threadHandle, 0); + GetThreadTimes(threadHandle, &creationTime, &exitTime, &kernelTime, &userTime); + CloseHandle(threadHandle); + +// sprintf(temp, "Time = %u\n", userTime.dwLowDateTime); +// OutputDebugString(temp); + + otherTaskTime = userTime.dwLowDateTime; + if (userTime.dwLowDateTime < 9000000) + { + otherTasksRunning = true; +// OutputDebugString("WARNING: possibly running on a system with another task\n"); + } +} + +#pragma optimize("", on) + + + /* ================== Sys_LowPhysicalMemory() @@ -650,7 +716,7 @@ static qboolean Sys_ScanForCD( void ) { Result = GetVolumeInformation(drive,VolumeName,sizeof(VolumeName),&VolumeSerialNumber, &MaximumComponentLength,&FileSystemFlags,FileSystemName,sizeof(FileSystemName)); - if (Result && (strcmpi(VolumeName,"JEDI_OUTCAST") == 0 ) ) + if (Result && (strcmpi(VolumeName,"JEDIOUTCAST") == 0 ) ) { sprintf (test, "%s%s\\%s",drive, CD_BASEDIR, CD_EXE); f = fopen( test, "r" ); @@ -1469,9 +1535,13 @@ int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLin Sys_InitStreamThread(); - Com_Init( sys_cmdline ); - NET_Init(); + CheckProcessTime(); + Com_Init( sys_cmdline ); + Cvar_Set( "com_othertasks", ( otherTasksRunning ? "1" : "0" ) ); + Cvar_Set( "com_othertaskstime", va("%u", otherTaskTime) ); + + NET_Init(); _getcwd (cwd, sizeof(cwd)); Com_Printf("Working directory: %s\n", cwd); diff --git a/CODEmp/win32/win_net.cpp b/CODE-mp/win32/win_net.cpp similarity index 100% rename from CODEmp/win32/win_net.cpp rename to CODE-mp/win32/win_net.cpp diff --git a/CODEmp/win32/win_qgl.cpp b/CODE-mp/win32/win_qgl.cpp similarity index 100% rename from CODEmp/win32/win_qgl.cpp rename to CODE-mp/win32/win_qgl.cpp diff --git a/CODEmp/win32/win_shared.cpp b/CODE-mp/win32/win_shared.cpp similarity index 100% rename from CODEmp/win32/win_shared.cpp rename to CODE-mp/win32/win_shared.cpp diff --git a/CODEmp/win32/win_snd.cpp b/CODE-mp/win32/win_snd.cpp similarity index 100% rename from CODEmp/win32/win_snd.cpp rename to CODE-mp/win32/win_snd.cpp diff --git a/CODEmp/win32/win_syscon.cpp b/CODE-mp/win32/win_syscon.cpp similarity index 71% rename from CODEmp/win32/win_syscon.cpp rename to CODE-mp/win32/win_syscon.cpp index b6a5516..bde2720 100644 --- a/CODEmp/win32/win_syscon.cpp +++ b/CODE-mp/win32/win_syscon.cpp @@ -1,6 +1,11 @@ // win_syscon.h +// this include must remain at the top of every CPP file #include "../client/client.h" #include "win_local.h" + + + + #include "resource.h" #include #include @@ -58,7 +63,7 @@ static WinConData s_wcd; static LONG WINAPI ConWndProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { - char *cmdString; + const char *cmdString; static qboolean s_timePolarity; switch (uMsg) @@ -93,7 +98,7 @@ static LONG WINAPI ConWndProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lPara if ( ( com_dedicated && com_dedicated->integer ) ) { cmdString = CopyString( "quit" ); - Sys_QueEvent( 0, SE_CONSOLE, 0, 0, strlen( cmdString ) + 1, cmdString ); + Sys_QueEvent( 0, SE_CONSOLE, 0, 0, strlen( cmdString ) + 1, (void *)cmdString ); } else if ( s_wcd.quitOnClose ) { @@ -110,19 +115,6 @@ static LONG WINAPI ConWndProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lPara { SetBkColor( ( HDC ) wParam, RGB( 0x00, 0x00, 0xB0 ) ); SetTextColor( ( HDC ) wParam, RGB( 0xff, 0xff, 0x00 ) ); - -#if 0 // this draws a background in the edit box, but there are issues with this - if ( ( hdcScaled = CreateCompatibleDC( ( HDC ) wParam ) ) != 0 ) - { - if ( SelectObject( ( HDC ) hdcScaled, s_wcd.hbmLogo ) ) - { - StretchBlt( ( HDC ) wParam, 0, 0, 512, 384, - hdcScaled, 0, 0, 512, 384, - SRCCOPY ); - } - DeleteDC( hdcScaled ); - } -#endif return ( long ) s_wcd.hbrEditBackground; } else if ( ( HWND ) lParam == s_wcd.hwndErrorBox ) @@ -156,7 +148,7 @@ static LONG WINAPI ConWndProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lPara else { cmdString = CopyString( "quit" ); - Sys_QueEvent( 0, SE_CONSOLE, 0, 0, strlen( cmdString ) + 1, cmdString ); + Sys_QueEvent( 0, SE_CONSOLE, 0, 0, strlen( cmdString ) + 1, (void *)cmdString ); } } else if ( wParam == CLEAR_ID ) @@ -167,59 +159,11 @@ static LONG WINAPI ConWndProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lPara } break; case WM_CREATE: -// s_wcd.hbmLogo = LoadBitmap( g_wv.hInstance, MAKEINTRESOURCE( IDB_BITMAP1 ) ); -// s_wcd.hbmClearBitmap = LoadBitmap( g_wv.hInstance, MAKEINTRESOURCE( IDB_BITMAP2 ) ); s_wcd.hbrEditBackground = CreateSolidBrush( RGB( 0x00, 0x00, 0xB0 ) ); s_wcd.hbrErrorBackground = CreateSolidBrush( RGB( 0x80, 0x80, 0x80 ) ); SetTimer( hWnd, 1, 1000, NULL ); break; case WM_ERASEBKGND: -#if 0 - HDC hdcScaled; - HGDIOBJ oldObject; - -#if 1 // a single, large image - hdcScaled = CreateCompatibleDC( ( HDC ) wParam ); - assert( hdcScaled != 0 ); - - if ( hdcScaled ) - { - oldObject = SelectObject( ( HDC ) hdcScaled, s_wcd.hbmLogo ); - assert( oldObject != 0 ); - if ( oldObject ) - { - StretchBlt( ( HDC ) wParam, 0, 0, s_wcd.windowWidth, s_wcd.windowHeight, - hdcScaled, 0, 0, 512, 384, - SRCCOPY ); - } - DeleteDC( hdcScaled ); - hdcScaled = 0; - } -#else // a repeating brush - { - HBRUSH hbrClearBrush; - RECT r; - - GetWindowRect( hWnd, &r ); - - r.bottom = r.bottom - r.top + 1; - r.right = r.right - r.left + 1; - r.top = 0; - r.left = 0; - - hbrClearBrush = CreatePatternBrush( s_wcd.hbmClearBitmap ); - - assert( hbrClearBrush != 0 ); - - if ( hbrClearBrush ) - { - FillRect( ( HDC ) wParam, &r, hbrClearBrush ); - DeleteObject( hbrClearBrush ); - } - } -#endif - return 1; -#endif return DefWindowProc( hWnd, uMsg, wParam, lParam ); case WM_TIMER: if ( wParam == 1 ) @@ -236,33 +180,76 @@ static LONG WINAPI ConWndProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lPara return DefWindowProc( hWnd, uMsg, wParam, lParam ); } +extern void CompleteCommand( void ) ; +extern int nextHistoryLine; // the last line in the history buffer, not masked +extern int historyLine; // the line being displayed from history buffer + LONG WINAPI InputLineWndProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { char inputBuffer[1024]; switch ( uMsg ) { - case WM_KILLFOCUS: - if ( ( HWND ) wParam == s_wcd.hWnd || - ( HWND ) wParam == s_wcd.hwndErrorBox ) - { - SetFocus( hWnd ); - return 0; - } - break; + case WM_KILLFOCUS: + if ( ( HWND ) wParam == s_wcd.hWnd || + ( HWND ) wParam == s_wcd.hwndErrorBox ) + { + SetFocus( hWnd ); + return 0; + } + break; - case WM_CHAR: - if ( wParam == 13 ) - { - GetWindowText( s_wcd.hwndInputLine, inputBuffer, sizeof( inputBuffer ) ); - strncat( s_wcd.consoleText, inputBuffer, sizeof( s_wcd.consoleText ) - strlen( s_wcd.consoleText ) - 5 ); - strcat( s_wcd.consoleText, "\n" ); - SetWindowText( s_wcd.hwndInputLine, "" ); + case WM_CHAR: + if ( wParam == 13 ) + { + GetWindowText( s_wcd.hwndInputLine, inputBuffer, sizeof( inputBuffer ) ); + strncat( s_wcd.consoleText, inputBuffer, sizeof( s_wcd.consoleText ) - strlen( s_wcd.consoleText ) - 5 ); + strcat( s_wcd.consoleText, "\n" ); + SetWindowText( s_wcd.hwndInputLine, "" ); - Sys_Print( va( "]%s\n", inputBuffer ) ); + Sys_Print( va( "]%s\n", inputBuffer ) ); - return 0; - } + strcpy(g_consoleField.buffer, inputBuffer); + historyEditLines[nextHistoryLine % COMMAND_HISTORY] = g_consoleField; + nextHistoryLine++; + historyLine = nextHistoryLine; + + return 0; + } + else if (wParam == 9 ) + { + GetWindowText( s_wcd.hwndInputLine, inputBuffer, sizeof( inputBuffer ) ); + strcpy(g_consoleField.buffer, inputBuffer); + CompleteCommand(); + SetWindowText( s_wcd.hwndInputLine, g_consoleField.buffer); + SendMessage(s_wcd.hwndInputLine, EM_SETSEL, strlen(g_consoleField.buffer) , MAKELONG(0xffff, 0xffff) ); + } + + case WM_KEYDOWN: + if (wParam == VK_UP) + { + if ( nextHistoryLine - historyLine < COMMAND_HISTORY && historyLine > 0 ) + { + historyLine--; + } + g_consoleField = historyEditLines[ historyLine % COMMAND_HISTORY ]; + SetWindowText( s_wcd.hwndInputLine, g_consoleField.buffer); + SendMessage(s_wcd.hwndInputLine, EM_SETSEL, strlen(g_consoleField.buffer) , MAKELONG(0xffff, 0xffff) ); + return 0; + } + else if (wParam == VK_DOWN) + { + if (historyLine == nextHistoryLine) + { + return 0; + } + historyLine++; + g_consoleField = historyEditLines[ historyLine % COMMAND_HISTORY ]; + SetWindowText( s_wcd.hwndInputLine, g_consoleField.buffer); + SendMessage(s_wcd.hwndInputLine, EM_SETSEL, strlen(g_consoleField.buffer) , MAKELONG(0xffff, 0xffff) ); + return 0; + } + break; } return CallWindowProc( s_wcd.SysInputLineWndProc, hWnd, uMsg, wParam, lParam ); @@ -276,7 +263,7 @@ void Sys_CreateConsole( void ) HDC hDC; WNDCLASS wc; RECT rect; - const char *DEDCLASS = "Q3 WinConsole"; + const char *DEDCLASS = "JK2MP WinConsole"; int nHeight; int swidth, sheight; int DEDSTYLE = WS_POPUPWINDOW | WS_CAPTION | WS_MINIMIZEBOX; @@ -295,10 +282,12 @@ void Sys_CreateConsole( void ) wc.lpszClassName = DEDCLASS; if ( !RegisterClass (&wc) ) + { return; + } rect.left = 0; - rect.right = 540; + rect.right = 538; rect.top = 0; rect.bottom = 450; AdjustWindowRect( &rect, DEDSTYLE, FALSE ); @@ -313,7 +302,7 @@ void Sys_CreateConsole( void ) s_wcd.hWnd = CreateWindowEx( 0, DEDCLASS, - "Console", + "Jedi Knight 2: Jedi Outcast MP Console", DEDSTYLE, ( swidth - 600 ) / 2, ( sheight - 450 ) / 2 , rect.right - rect.left + 1, rect.bottom - rect.top + 1, NULL, @@ -353,7 +342,7 @@ void Sys_CreateConsole( void ) // create the input line // s_wcd.hwndInputLine = CreateWindow( "edit", NULL, WS_CHILD | WS_VISIBLE | WS_BORDER | - ES_LEFT | ES_AUTOHSCROLL, + ES_LEFT | ES_AUTOHSCROLL | WS_TABSTOP, 6, 400, 528, 20, s_wcd.hWnd, ( HMENU ) INPUT_ID, // child window ID @@ -362,33 +351,33 @@ void Sys_CreateConsole( void ) // // create the buttons // - s_wcd.hwndButtonCopy = CreateWindow( "button", NULL, BS_PUSHBUTTON | WS_VISIBLE | WS_CHILD | BS_DEFPUSHBUTTON, + s_wcd.hwndButtonCopy = CreateWindow( "button", NULL, BS_PUSHBUTTON | WS_VISIBLE | WS_CHILD | BS_DEFPUSHBUTTON | WS_TABSTOP, 5, 425, 72, 24, s_wcd.hWnd, ( HMENU ) COPY_ID, // child window ID g_wv.hInstance, NULL ); - SendMessage( s_wcd.hwndButtonCopy, WM_SETTEXT, 0, ( LPARAM ) "copy" ); + SendMessage( s_wcd.hwndButtonCopy, WM_SETTEXT, 0, ( LPARAM ) "Copy" ); - s_wcd.hwndButtonClear = CreateWindow( "button", NULL, BS_PUSHBUTTON | WS_VISIBLE | WS_CHILD | BS_DEFPUSHBUTTON, + s_wcd.hwndButtonClear = CreateWindow( "button", NULL, BS_PUSHBUTTON | WS_VISIBLE | WS_CHILD | BS_DEFPUSHBUTTON | WS_TABSTOP, 82, 425, 72, 24, s_wcd.hWnd, ( HMENU ) CLEAR_ID, // child window ID g_wv.hInstance, NULL ); - SendMessage( s_wcd.hwndButtonClear, WM_SETTEXT, 0, ( LPARAM ) "clear" ); + SendMessage( s_wcd.hwndButtonClear, WM_SETTEXT, 0, ( LPARAM ) "Clear" ); - s_wcd.hwndButtonQuit = CreateWindow( "button", NULL, BS_PUSHBUTTON | WS_VISIBLE | WS_CHILD | BS_DEFPUSHBUTTON, + s_wcd.hwndButtonQuit = CreateWindow( "button", NULL, BS_PUSHBUTTON | WS_VISIBLE | WS_CHILD | BS_DEFPUSHBUTTON | WS_TABSTOP, 462, 425, 72, 24, s_wcd.hWnd, ( HMENU ) QUIT_ID, // child window ID g_wv.hInstance, NULL ); - SendMessage( s_wcd.hwndButtonQuit, WM_SETTEXT, 0, ( LPARAM ) "quit" ); + SendMessage( s_wcd.hwndButtonQuit, WM_SETTEXT, 0, ( LPARAM ) "Quit" ); // // create the scrollbuffer // s_wcd.hwndBuffer = CreateWindow( "edit", NULL, WS_CHILD | WS_VISIBLE | WS_VSCROLL | WS_BORDER | - ES_LEFT | ES_MULTILINE | ES_AUTOVSCROLL | ES_READONLY, + ES_LEFT | ES_MULTILINE | ES_AUTOVSCROLL | ES_READONLY | WS_TABSTOP, 6, 40, 526, 354, s_wcd.hWnd, ( HMENU ) EDIT_ID, // child window ID @@ -397,6 +386,7 @@ void Sys_CreateConsole( void ) s_wcd.SysInputLineWndProc = ( WNDPROC ) SetWindowLong( s_wcd.hwndInputLine, GWL_WNDPROC, ( long ) InputLineWndProc ); SendMessage( s_wcd.hwndInputLine, WM_SETFONT, ( WPARAM ) s_wcd.hfBufferFont, 0 ); + SendMessage( s_wcd.hwndBuffer, EM_LIMITTEXT, ( WPARAM ) 0x7fff, 0 ); ShowWindow( s_wcd.hWnd, SW_SHOWDEFAULT); UpdateWindow( s_wcd.hWnd ); @@ -409,8 +399,14 @@ void Sys_CreateConsole( void ) /* ** Sys_DestroyConsole */ -void Sys_DestroyConsole( void ) { - if ( s_wcd.hWnd ) { +void Sys_DestroyConsole( void ) +{ + if ( s_wcd.hWnd ) + { + DeleteObject(s_wcd.hbrEditBackground); + DeleteObject(s_wcd.hbrErrorBackground); + DeleteObject(s_wcd.hfBufferFont); + ShowWindow( s_wcd.hWnd, SW_HIDE ); CloseWindow( s_wcd.hWnd ); DestroyWindow( s_wcd.hWnd ); @@ -433,7 +429,9 @@ void Sys_ShowConsole( int visLevel, qboolean quitOnClose ) s_wcd.visLevel = visLevel; if ( !s_wcd.hWnd ) + { return; + } switch ( visLevel ) { @@ -540,22 +538,20 @@ void Conbuf_AppendText( const char *pMsg ) // if ( s_totalChars > 0x7fff ) { - if (s_wcd.hWnd) - { - SendMessage( s_wcd.hwndBuffer, EM_SETSEL, 0, -1 ); - } +/* SendMessage( s_wcd.hwndBuffer, EM_SETSEL, 0, s_totalChars - 0x7fff ); + SendMessage( s_wcd.hwndBuffer, EM_REPLACESEL, 0, (LPARAM) "" ); + s_totalChars = 0x7fff; + SendMessage( s_wcd.hwndBuffer, EM_SETSEL, s_totalChars, s_totalChars );*/ + SendMessage( s_wcd.hwndBuffer, EM_SETSEL, 0, -1 ); s_totalChars = bufLen; } // // put this text into the windows console // - if (s_wcd.hWnd) - { - SendMessage( s_wcd.hwndBuffer, EM_LINESCROLL, 0, 0xffff ); - SendMessage( s_wcd.hwndBuffer, EM_SCROLLCARET, 0, 0 ); - SendMessage( s_wcd.hwndBuffer, EM_REPLACESEL, 0, (LPARAM) buffer ); - } + SendMessage( s_wcd.hwndBuffer, EM_LINESCROLL, 0, 0xffff ); + SendMessage( s_wcd.hwndBuffer, EM_SCROLLCARET, 0, 0 ); + SendMessage( s_wcd.hwndBuffer, EM_REPLACESEL, 0, (LPARAM) buffer ); } /* diff --git a/CODEmp/win32/win_wndproc.cpp b/CODE-mp/win32/win_wndproc.cpp similarity index 100% rename from CODEmp/win32/win_wndproc.cpp rename to CODE-mp/win32/win_wndproc.cpp diff --git a/CODEmp/win32/winquake.rc b/CODE-mp/win32/winquake.rc similarity index 100% rename from CODEmp/win32/winquake.rc rename to CODE-mp/win32/winquake.rc diff --git a/CODEmp/zlib/adler32.c b/CODE-mp/zlib/adler32.c similarity index 100% rename from CODEmp/zlib/adler32.c rename to CODE-mp/zlib/adler32.c diff --git a/CODEmp/zlib/crc32.cpp b/CODE-mp/zlib/crc32.cpp similarity index 100% rename from CODEmp/zlib/crc32.cpp rename to CODE-mp/zlib/crc32.cpp diff --git a/CODEmp/zlib/deflate.c b/CODE-mp/zlib/deflate.c similarity index 100% rename from CODEmp/zlib/deflate.c rename to CODE-mp/zlib/deflate.c diff --git a/CODEmp/zlib/deflate.h b/CODE-mp/zlib/deflate.h similarity index 100% rename from CODEmp/zlib/deflate.h rename to CODE-mp/zlib/deflate.h diff --git a/CODEmp/zlib/infblock.c b/CODE-mp/zlib/infblock.c similarity index 100% rename from CODEmp/zlib/infblock.c rename to CODE-mp/zlib/infblock.c diff --git a/CODEmp/zlib/infblock.h b/CODE-mp/zlib/infblock.h similarity index 100% rename from CODEmp/zlib/infblock.h rename to CODE-mp/zlib/infblock.h diff --git a/CODEmp/zlib/infcodes.c b/CODE-mp/zlib/infcodes.c similarity index 100% rename from CODEmp/zlib/infcodes.c rename to CODE-mp/zlib/infcodes.c diff --git a/CODEmp/zlib/infcodes.h b/CODE-mp/zlib/infcodes.h similarity index 100% rename from CODEmp/zlib/infcodes.h rename to CODE-mp/zlib/infcodes.h diff --git a/CODEmp/zlib/inffast.c b/CODE-mp/zlib/inffast.c similarity index 100% rename from CODEmp/zlib/inffast.c rename to CODE-mp/zlib/inffast.c diff --git a/CODEmp/zlib/inffast.h b/CODE-mp/zlib/inffast.h similarity index 100% rename from CODEmp/zlib/inffast.h rename to CODE-mp/zlib/inffast.h diff --git a/CODEmp/zlib/inffixed.h b/CODE-mp/zlib/inffixed.h similarity index 100% rename from CODEmp/zlib/inffixed.h rename to CODE-mp/zlib/inffixed.h diff --git a/CODEmp/zlib/inflate.c b/CODE-mp/zlib/inflate.c similarity index 100% rename from CODEmp/zlib/inflate.c rename to CODE-mp/zlib/inflate.c diff --git a/CODEmp/zlib/inftrees.c b/CODE-mp/zlib/inftrees.c similarity index 100% rename from CODEmp/zlib/inftrees.c rename to CODE-mp/zlib/inftrees.c diff --git a/CODEmp/zlib/inftrees.h b/CODE-mp/zlib/inftrees.h similarity index 100% rename from CODEmp/zlib/inftrees.h rename to CODE-mp/zlib/inftrees.h diff --git a/CODEmp/zlib/infutil.c b/CODE-mp/zlib/infutil.c similarity index 100% rename from CODEmp/zlib/infutil.c rename to CODE-mp/zlib/infutil.c diff --git a/CODEmp/zlib/infutil.h b/CODE-mp/zlib/infutil.h similarity index 100% rename from CODEmp/zlib/infutil.h rename to CODE-mp/zlib/infutil.h diff --git a/CODEmp/zlib/trees.c b/CODE-mp/zlib/trees.c similarity index 100% rename from CODEmp/zlib/trees.c rename to CODE-mp/zlib/trees.c diff --git a/CODEmp/zlib/trees.h b/CODE-mp/zlib/trees.h similarity index 100% rename from CODEmp/zlib/trees.h rename to CODE-mp/zlib/trees.h diff --git a/CODE-mp/zlib/vssver.scc b/CODE-mp/zlib/vssver.scc new file mode 100644 index 0000000..e6f9f26 Binary files /dev/null and b/CODE-mp/zlib/vssver.scc differ diff --git a/CODEmp/zlib/zconf.h b/CODE-mp/zlib/zconf.h similarity index 100% rename from CODEmp/zlib/zconf.h rename to CODE-mp/zlib/zconf.h diff --git a/CODEmp/zlib/zlib.h b/CODE-mp/zlib/zlib.h similarity index 100% rename from CODEmp/zlib/zlib.h rename to CODE-mp/zlib/zlib.h diff --git a/CODEmp/zlib/zutil.c b/CODE-mp/zlib/zutil.c similarity index 100% rename from CODEmp/zlib/zutil.c rename to CODE-mp/zlib/zutil.c diff --git a/CODEmp/zlib/zutil.h b/CODE-mp/zlib/zutil.h similarity index 100% rename from CODEmp/zlib/zutil.h rename to CODE-mp/zlib/zutil.h diff --git a/CODEmp/Debug/botlib.lib b/CODEmp/Debug/botlib.lib deleted file mode 100644 index 383ebde..0000000 Binary files a/CODEmp/Debug/botlib.lib and /dev/null differ diff --git a/CODEmp/Debug/cgamex86.lib b/CODEmp/Debug/cgamex86.lib deleted file mode 100644 index 795e32a..0000000 Binary files a/CODEmp/Debug/cgamex86.lib and /dev/null differ diff --git a/CODEmp/Debug/jk2mpgamex86.lib b/CODEmp/Debug/jk2mpgamex86.lib deleted file mode 100644 index 408943a..0000000 Binary files a/CODEmp/Debug/jk2mpgamex86.lib and /dev/null differ diff --git a/CODEmp/Debug/uix86.lib b/CODEmp/Debug/uix86.lib deleted file mode 100644 index a8c817c..0000000 Binary files a/CODEmp/Debug/uix86.lib and /dev/null differ diff --git a/CODEmp/Final/botlib.lib b/CODEmp/Final/botlib.lib deleted file mode 100644 index 4876e75..0000000 Binary files a/CODEmp/Final/botlib.lib and /dev/null differ diff --git a/CODEmp/Final/cgamex86.lib b/CODEmp/Final/cgamex86.lib deleted file mode 100644 index bf2ad13..0000000 Binary files a/CODEmp/Final/cgamex86.lib and /dev/null differ diff --git a/CODEmp/Final/jk2mpgamex86.lib b/CODEmp/Final/jk2mpgamex86.lib deleted file mode 100644 index a745d1a..0000000 Binary files a/CODEmp/Final/jk2mpgamex86.lib and /dev/null differ diff --git a/CODEmp/Final/uix86.lib b/CODEmp/Final/uix86.lib deleted file mode 100644 index 8043c35..0000000 Binary files a/CODEmp/Final/uix86.lib and /dev/null differ diff --git a/CODEmp/Release/botlib.lib b/CODEmp/Release/botlib.lib deleted file mode 100644 index f833099..0000000 Binary files a/CODEmp/Release/botlib.lib and /dev/null differ diff --git a/CODEmp/Release/cgamex86.lib b/CODEmp/Release/cgamex86.lib deleted file mode 100644 index c9d3a39..0000000 Binary files a/CODEmp/Release/cgamex86.lib and /dev/null differ diff --git a/CODEmp/Release/jk2mpgamex86.lib b/CODEmp/Release/jk2mpgamex86.lib deleted file mode 100644 index 270c44e..0000000 Binary files a/CODEmp/Release/jk2mpgamex86.lib and /dev/null differ diff --git a/CODEmp/Release/uix86.lib b/CODEmp/Release/uix86.lib deleted file mode 100644 index ca3df83..0000000 Binary files a/CODEmp/Release/uix86.lib and /dev/null differ diff --git a/CODEmp/game/bg_panimate.c b/CODEmp/game/bg_panimate.c deleted file mode 100644 index 9f62f3f..0000000 --- a/CODEmp/game/bg_panimate.c +++ /dev/null @@ -1,545 +0,0 @@ -// BG_PAnimate.c - -#include "q_shared.h" -#include "bg_public.h" -#include "bg_local.h" -#include "anims.h" -#include "../cgame/animtable.h" - -qboolean BG_InSpecialJump( int anim ) -{ - switch ( (anim&~ANIM_TOGGLEBIT) ) - { - case BOTH_WALL_RUN_RIGHT: - case BOTH_WALL_RUN_RIGHT_FLIP: - case BOTH_WALL_RUN_LEFT: - case BOTH_WALL_RUN_LEFT_FLIP: - case BOTH_WALL_FLIP_RIGHT: - case BOTH_WALL_FLIP_LEFT: - case BOTH_FLIP_BACK1: - case BOTH_FLIP_BACK2: - case BOTH_FLIP_BACK3: - case BOTH_WALL_FLIP_BACK1: - case BOTH_BUTTERFLY_LEFT: - case BOTH_BUTTERFLY_RIGHT: - return qtrue; - } - return qfalse; -} - -qboolean BG_FlippingAnim( int anim ) -{ - switch ( (anim&~ANIM_TOGGLEBIT) ) - { - case BOTH_FLIP_F: //# Flip forward - case BOTH_FLIP_B: //# Flip backwards - case BOTH_FLIP_L: //# Flip left - case BOTH_FLIP_R: //# Flip right - return qtrue; - break; - } - - return qfalse; -} - -qboolean BG_SpinningSaberAnim( int anim ) -{ - switch ( (anim&~ANIM_TOGGLEBIT) ) - { - case BOTH_T1_BR_BL: - case BOTH_T1__R__L: - case BOTH_T1__R_BL: - case BOTH_T1_TR_BL: - case BOTH_T1_BR_TL: - case BOTH_T1_BR__L: - case BOTH_T1_TL_BR: - case BOTH_T1__L_BR: - case BOTH_T1__L__R: - case BOTH_T1_BL_BR: - case BOTH_T1_BL__R: - case BOTH_T1_BL_TR: - return qtrue; - break; - } - return qfalse; -} - -void PM_DebugLegsAnim(int anim) -{ - int oldAnim = (pm->ps->legsAnim & ~ANIM_TOGGLEBIT); - int newAnim = (anim & ~ANIM_TOGGLEBIT); - - if (oldAnim < MAX_TOTALANIMATIONS && oldAnim >= BOTH_DEATH1 && - newAnim < MAX_TOTALANIMATIONS && newAnim >= BOTH_DEATH1) - { - Com_Printf("OLD: %s\n", animTable[oldAnim]); - Com_Printf("NEW: %s\n", animTable[newAnim]); - } -} - -qboolean PM_InRoll( playerState_t *ps, int anim ); - -/* -====================== -BG_ParseAnimationFile - -Read a configuration file containing animation coutns and rates -models/players/visor/animation.cfg, etc - -====================== -*/ -char BGPAFtext[40000]; -qboolean BG_ParseAnimationFile( const char *filename, animation_t *animations) -{ - char *text_p; - int len; - int i; - char *token; - float fps; - int skip; - - fileHandle_t f; - int animNum; - - - // load the file - len = trap_FS_FOpenFile( filename, &f, FS_READ ); - if ( len <= 0 ) - { - return qfalse; - } - if ( len >= sizeof( BGPAFtext ) - 1 ) - { -// gi.Printf( "File %s too long\n", filename ); - return qfalse; - } - - trap_FS_Read( BGPAFtext, len, f ); - BGPAFtext[len] = 0; - trap_FS_FCloseFile( f ); - - // parse the text - text_p = BGPAFtext; - skip = 0; // quiet the compiler warning - - //FIXME: have some way of playing anims backwards... negative numFrames? - - //initialize anim array so that from 0 to MAX_ANIMATIONS, set default values of 0 1 0 100 - for(i = 0; i < MAX_ANIMATIONS; i++) - { - animations[i].firstFrame = 0; - animations[i].numFrames = 0; - animations[i].loopFrames = -1; - animations[i].frameLerp = 100; - animations[i].initialLerp = 100; - } - - // read information for each frame - while(1) - { - token = COM_Parse( (const char **)(&text_p) ); - - if ( !token || !token[0]) - { - break; - } - - animNum = GetIDForString(animTable, token); - if(animNum == -1) - { -//#ifndef FINAL_BUILD -#ifdef _DEBUG - Com_Printf(S_COLOR_RED"WARNING: Unknown token %s in %s\n", token, filename); -#endif - continue; - } - - token = COM_Parse( (const char **)(&text_p) ); - if ( !token ) - { - break; - } - animations[animNum].firstFrame = atoi( token ); - - token = COM_Parse( (const char **)(&text_p) ); - if ( !token ) - { - break; - } - animations[animNum].numFrames = atoi( token ); - - token = COM_Parse( (const char **)(&text_p) ); - if ( !token ) - { - break; - } - animations[animNum].loopFrames = atoi( token ); - - token = COM_Parse( (const char **)(&text_p) ); - if ( !token ) - { - break; - } - fps = atof( token ); - if ( fps == 0 ) - { - fps = 1;//Don't allow divide by zero error - } - if ( fps < 0 ) - {//backwards - animations[animNum].frameLerp = floor(1000.0f / fps); - } - else - { - animations[animNum].frameLerp = ceil(1000.0f / fps); - } - - animations[animNum].initialLerp = ceil(1000.0f / fabs(fps)); - } - - return qtrue; -} - - - -/* -=================== -LEGS Animations -Base animation for overall body -=================== -*/ -static void PM_StartLegsAnim( int anim ) { - if ( pm->ps->pm_type >= PM_DEAD ) { - return; - } - if ( pm->ps->legsTimer > 0 ) { - return; // a high priority animation is running - } - - if (pm->ps->usingATST) - { //animation is handled mostly client-side with only a few exceptions - return; - } - - if (anim == BOTH_STAND2 && pm->ps->weapon == WP_SABER && pm->ps->dualBlade) - { //a bit of a hack, but dualblade is cheat-only anyway - anim = BOTH_STAND1; - } - - pm->ps->legsAnim = ( ( pm->ps->legsAnim & ANIM_TOGGLEBIT ) ^ ANIM_TOGGLEBIT ) - | anim; - - if ( pm->debugLevel ) { - Com_Printf("%d: StartLegsAnim %d, on client#%d\n", pm->cmd.serverTime, anim, pm->ps->clientNum); - } -} - -void PM_ContinueLegsAnim( int anim ) { - if ( ( pm->ps->legsAnim & ~ANIM_TOGGLEBIT ) == anim ) { - return; - } - if ( pm->ps->legsTimer > 0 ) { - return; // a high priority animation is running - } - - PM_StartLegsAnim( anim ); -} - -void PM_ForceLegsAnim( int anim) { - if (BG_InSpecialJump(pm->ps->legsAnim) && - pm->ps->legsTimer > 0 && - !BG_InSpecialJump(anim)) - { - return; - } - - if (PM_InRoll(pm->ps, pm->ps->legsAnim) && - pm->ps->legsTimer > 0 && - !PM_InRoll(pm->ps, anim)) - { - return; - } - - pm->ps->legsTimer = 0; - PM_StartLegsAnim( anim ); -} - - - -/* -=================== -TORSO Animations -Override animations for upper body -=================== -*/ -void PM_StartTorsoAnim( int anim ) { - if ( pm->ps->pm_type >= PM_DEAD ) { - return; - } - - if (pm->ps->usingATST) - { //animation is handled mostly client-side with only a few exceptions - return; - } - - if (anim == BOTH_STAND2 && pm->ps->weapon == WP_SABER && pm->ps->dualBlade) - { //a bit of a hack, but dualblade is cheat-only anyway - anim = BOTH_STAND1; - } - - pm->ps->torsoAnim = ( ( pm->ps->torsoAnim & ANIM_TOGGLEBIT ) ^ ANIM_TOGGLEBIT ) - | anim; -} - -static void PM_ContinueTorsoAnim( int anim ) { - if ( ( pm->ps->torsoAnim & ~ANIM_TOGGLEBIT ) == anim ) { - return; - } - if ( pm->ps->torsoTimer > 0 ) { - return; // a high priority animation is running - } - PM_StartTorsoAnim( anim); -} - - -/* -============== -PM_TorsoAnimation - -============== -*/ -void PM_TorsoAnimation( void ) { - if ( pm->ps->weaponstate == WEAPON_READY ) { - if ( pm->ps->weapon == WP_SABER ) { - PM_ContinueTorsoAnim( BOTH_STAND2 ); - } else { - PM_ContinueTorsoAnim( WeaponReadyAnim[pm->ps->weapon] ); - } - return; - } -} - - -/* -------------------------- -PM_SetLegsAnimTimer -------------------------- -*/ - -void PM_SetLegsAnimTimer(int time ) -{ - pm->ps->legsTimer = time; - - if (pm->ps->legsTimer < 0 && time != -1 ) - {//Cap timer to 0 if was counting down, but let it be -1 if that was intentional. NOTENOTE Yeah this seems dumb, but it mirrors SP. - pm->ps->legsTimer = 0; - } -} - -/* -------------------------- -PM_SetTorsoAnimTimer -------------------------- -*/ - -void PM_SetTorsoAnimTimer(int time ) -{ - pm->ps->torsoTimer = time; - - if (pm->ps->torsoTimer < 0 && time != -1 ) - {//Cap timer to 0 if was counting down, but let it be -1 if that was intentional. NOTENOTE Yeah this seems dumb, but it mirrors SP. - pm->ps->torsoTimer = 0; - } -} - -void PM_SaberStartTransAnim( int saberAnimLevel, int anim, float *animSpeed ) -{ - if ( ( (anim&~ANIM_TOGGLEBIT) >= BOTH_T1_BR__R && - (anim&~ANIM_TOGGLEBIT) <= BOTH_T1_BL_TL ) || - ( (anim&~ANIM_TOGGLEBIT) >= BOTH_T2_BR__R && - (anim&~ANIM_TOGGLEBIT) <= BOTH_T2_BL_TL ) || - ( (anim&~ANIM_TOGGLEBIT) >= BOTH_T3_BR__R && - (anim&~ANIM_TOGGLEBIT) <= BOTH_T3_BL_TL ) ) - { - if ( saberAnimLevel == FORCE_LEVEL_1 ) - { - *animSpeed *= 1.5; - } - else if ( saberAnimLevel == FORCE_LEVEL_3 ) - { - *animSpeed *= 0.75; - } - } -} - -/* -------------------------- -PM_SetAnimFinal -------------------------- -*/ -void PM_SetAnimFinal(int setAnimParts,int anim,int setAnimFlags, - int blendTime) // default blendTime=350 -{ - animation_t *animations = pm->animations; - - float editAnimSpeed = 0; - - if (!animations) - { - return; - } - - //NOTE: Setting blendTime here breaks actual blending.. - blendTime = 0; - - PM_SaberStartTransAnim(pm->ps->fd.saberAnimLevel, anim, &editAnimSpeed); - - // Set torso anim - if (setAnimParts & SETANIM_TORSO) - { - // Don't reset if it's already running the anim - if( !(setAnimFlags & SETANIM_FLAG_RESTART) && (pm->ps->torsoAnim & ~ANIM_TOGGLEBIT ) == anim ) - { - goto setAnimLegs; - } - // or if a more important anim is running - if( !(setAnimFlags & SETANIM_FLAG_OVERRIDE) && ((pm->ps->torsoTimer > 0)||(pm->ps->torsoTimer == -1)) ) - { - goto setAnimLegs; - } - - PM_StartTorsoAnim( anim ); - - if (setAnimFlags & SETANIM_FLAG_HOLD) - {//FIXME: allow to set a specific time? - if (setAnimFlags & SETANIM_FLAG_HOLDLESS) - { // Make sure to only wait in full 1/20 sec server frame intervals. - int dur; - - dur = (animations[anim].numFrames ) * fabs(animations[anim].frameLerp); - //dur = ((int)(dur/50.0)) * 50 / timeScaleMod; - dur -= blendTime+fabs(animations[anim].frameLerp)*2; - if (dur > 1) - { - pm->ps->torsoTimer = dur-1; - } - else - { - pm->ps->torsoTimer = fabs(animations[anim].frameLerp); - } - } - else - { - pm->ps->torsoTimer = ((animations[anim].numFrames ) * fabs(animations[anim].frameLerp)); - } - - if (pm->ps->fd.forcePowersActive & (1 << FP_RAGE)) - { - pm->ps->torsoTimer /= 1.7; - } - - if (editAnimSpeed) - { - pm->ps->torsoTimer /= editAnimSpeed; - } - } - } - -setAnimLegs: - // Set legs anim - if (setAnimParts & SETANIM_LEGS) - { - // Don't reset if it's already running the anim - if( !(setAnimFlags & SETANIM_FLAG_RESTART) && (pm->ps->legsAnim & ~ANIM_TOGGLEBIT ) == anim ) - { - goto setAnimDone; - } - // or if a more important anim is running - if( !(setAnimFlags & SETANIM_FLAG_OVERRIDE) && ((pm->ps->legsTimer > 0)||(pm->ps->legsTimer == -1)) ) - { - goto setAnimDone; - } - - PM_StartLegsAnim(anim); - - if (setAnimFlags & SETANIM_FLAG_HOLD) - {//FIXME: allow to set a specific time? - if (setAnimFlags & SETANIM_FLAG_HOLDLESS) - { // Make sure to only wait in full 1/20 sec server frame intervals. - int dur; - - dur = (animations[anim].numFrames -1) * fabs(animations[anim].frameLerp); - //dur = ((int)(dur/50.0)) * 50 / timeScaleMod; - dur -= blendTime+fabs(animations[anim].frameLerp)*2; - if (dur > 1) - { - pm->ps->legsTimer = dur-1; - } - else - { - pm->ps->legsTimer = fabs(animations[anim].frameLerp); - } - } - else - { - pm->ps->legsTimer = ((animations[anim].numFrames ) * fabs(animations[anim].frameLerp)); - } - - /* - PM_DebugLegsAnim(anim); - Com_Printf("%i\n", pm->ps->legsTimer); - */ - - if (pm->ps->fd.forcePowersActive & (1 << FP_RAGE)) - { - pm->ps->legsTimer /= 1.3; - } - else if (pm->ps->fd.forcePowersActive & (1 << FP_SPEED)) - { - pm->ps->legsTimer /= 1.7; - } - } - } - -setAnimDone: - return; -} - - - -// Imported from single-player, this function is mainly intended to make porting from SP easier. -void PM_SetAnim(int setAnimParts,int anim,int setAnimFlags, int blendTime) -{ - if (BG_InSpecialJump(anim)) - { - setAnimFlags |= SETANIM_FLAG_RESTART; - } - - if (PM_InRoll(pm->ps, pm->ps->legsAnim)) - { - //setAnimFlags |= SETANIM_FLAG_RESTART; - return; - } - - if (setAnimFlags&SETANIM_FLAG_OVERRIDE) - { - if (setAnimParts & SETANIM_TORSO) - { - if( (setAnimFlags & SETANIM_FLAG_RESTART) || (pm->ps->torsoAnim & ~ANIM_TOGGLEBIT ) != anim ) - { - PM_SetTorsoAnimTimer(0); - } - } - if (setAnimParts & SETANIM_LEGS) - { - if( (setAnimFlags & SETANIM_FLAG_RESTART) || (pm->ps->legsAnim & ~ANIM_TOGGLEBIT ) != anim ) - { - PM_SetLegsAnimTimer(0); - } - } - } - - PM_SetAnimFinal(setAnimParts, anim, setAnimFlags, blendTime); -} - - diff --git a/CODEmp/renderer/tr_shade.cpp b/CODEmp/renderer/tr_shade.cpp deleted file mode 100644 index 41e38b6..0000000 --- a/CODEmp/renderer/tr_shade.cpp +++ /dev/null @@ -1,2771 +0,0 @@ -// tr_shade.c - -#include "tr_local.h" - -#include "tr_quicksprite.h" - -/* - - THIS ENTIRE FILE IS BACK END - - This file deals with applying shaders to surface data in the tess struct. -*/ - -color4ub_t styleColors[MAX_LIGHT_STYLES]; - -/* -================ -R_ArrayElementDiscrete - -This is just for OpenGL conformance testing, it should never be the fastest -================ -*/ -static void APIENTRY R_ArrayElementDiscrete( GLint index ) { - qglColor4ubv( tess.svars.colors[ index ] ); - if ( glState.currenttmu ) { - qglMultiTexCoord2fARB( 0, tess.svars.texcoords[ 0 ][ index ][0], tess.svars.texcoords[ 0 ][ index ][1] ); - qglMultiTexCoord2fARB( 1, tess.svars.texcoords[ 1 ][ index ][0], tess.svars.texcoords[ 1 ][ index ][1] ); - } else { - qglTexCoord2fv( tess.svars.texcoords[ 0 ][ index ] ); - } - qglVertex3fv( tess.xyz[ index ] ); -} - -/* -=================== -R_DrawStripElements - -=================== -*/ -static int c_vertexes; // for seeing how long our average strips are -static int c_begins; -static void R_DrawStripElements( int numIndexes, const glIndex_t *indexes, void ( APIENTRY *element )(GLint) ) { - int i; - int last[3] = { -1, -1, -1 }; - qboolean even; - - c_begins++; - - if ( numIndexes <= 0 ) { - return; - } - - qglBegin( GL_TRIANGLE_STRIP ); - - // prime the strip - element( indexes[0] ); - element( indexes[1] ); - element( indexes[2] ); - c_vertexes += 3; - - last[0] = indexes[0]; - last[1] = indexes[1]; - last[2] = indexes[2]; - - even = qfalse; - - for ( i = 3; i < numIndexes; i += 3 ) - { - // odd numbered triangle in potential strip - if ( !even ) - { - // check previous triangle to see if we're continuing a strip - if ( ( indexes[i+0] == last[2] ) && ( indexes[i+1] == last[1] ) ) - { - element( indexes[i+2] ); - c_vertexes++; - assert( indexes[i+2] < tess.numVertexes ); - even = qtrue; - } - // otherwise we're done with this strip so finish it and start - // a new one - else - { - qglEnd(); - - qglBegin( GL_TRIANGLE_STRIP ); - c_begins++; - - element( indexes[i+0] ); - element( indexes[i+1] ); - element( indexes[i+2] ); - - c_vertexes += 3; - - even = qfalse; - } - } - else - { - // check previous triangle to see if we're continuing a strip - if ( ( last[2] == indexes[i+1] ) && ( last[0] == indexes[i+0] ) ) - { - element( indexes[i+2] ); - c_vertexes++; - - even = qfalse; - } - // otherwise we're done with this strip so finish it and start - // a new one - else - { - qglEnd(); - - qglBegin( GL_TRIANGLE_STRIP ); - c_begins++; - - element( indexes[i+0] ); - element( indexes[i+1] ); - element( indexes[i+2] ); - c_vertexes += 3; - - even = qfalse; - } - } - - // cache the last three vertices - last[0] = indexes[i+0]; - last[1] = indexes[i+1]; - last[2] = indexes[i+2]; - } - - qglEnd(); -} - - - -/* -================== -R_DrawElements - -Optionally performs our own glDrawElements that looks for strip conditions -instead of using the single glDrawElements call that may be inefficient -without compiled vertex arrays. -================== -*/ -static void R_DrawElements( int numIndexes, const glIndex_t *indexes ) { - int primitives; - - primitives = r_primitives->integer; - - // default is to use triangles if compiled vertex arrays are present - if ( primitives == 0 ) { - if ( qglLockArraysEXT ) { - primitives = 2; - } else { - primitives = 1; - } - } - - - if ( primitives == 2 ) { - qglDrawElements( GL_TRIANGLES, - numIndexes, - GL_INDEX_TYPE, - indexes ); - return; - } - - if ( primitives == 1 ) { - R_DrawStripElements( numIndexes, indexes, qglArrayElement ); - return; - } - - if ( primitives == 3 ) { - R_DrawStripElements( numIndexes, indexes, R_ArrayElementDiscrete ); - return; - } - - // anything else will cause no drawing -} - - -unsigned char randomindex, randominterval; -float randomchart[256] = { - 0.6554, 0.6909, 0.4806, 0.6218, 0.5717, 0.3896, 0.0677, 0.7356, - 0.8333, 0.1105, 0.4445, 0.8161, 0.4689, 0.0433, 0.7152, 0.0336, - 0.0186, 0.9140, 0.1626, 0.6553, 0.8340, 0.7094, 0.2020, 0.8087, - 0.9119, 0.8009, 0.1339, 0.8492, 0.9173, 0.5003, 0.6012, 0.6117, - 0.5525, 0.5787, 0.1586, 0.3293, 0.9273, 0.7791, 0.8589, 0.4985, - 0.0883, 0.8545, 0.2634, 0.4727, 0.3624, 0.1631, 0.7825, 0.0662, - 0.6704, 0.3510, 0.7525, 0.9486, 0.4685, 0.1535, 0.1545, 0.1121, - 0.4724, 0.8483, 0.3833, 0.1917, 0.8207, 0.3885, 0.9702, 0.9200, - 0.8348, 0.7501, 0.6675, 0.4994, 0.0301, 0.5225, 0.8011, 0.1696, - 0.5351, 0.2752, 0.2962, 0.7550, 0.5762, 0.7303, 0.2835, 0.4717, - 0.1818, 0.2739, 0.6914, 0.7748, 0.7640, 0.8355, 0.7314, 0.5288, - 0.7340, 0.6692, 0.6813, 0.2810, 0.8057, 0.0648, 0.8749, 0.9199, - 0.1462, 0.5237, 0.3014, 0.4994, 0.0278, 0.4268, 0.7238, 0.5107, - 0.1378, 0.7303, 0.7200, 0.3819, 0.2034, 0.7157, 0.5552, 0.4887, - 0.0871, 0.3293, 0.2892, 0.4545, 0.0088, 0.1404, 0.0275, 0.0238, - 0.0515, 0.4494, 0.7206, 0.2893, 0.6060, 0.5785, 0.4182, 0.5528, - 0.9118, 0.8742, 0.3859, 0.6030, 0.3495, 0.4550, 0.9875, 0.6900, - 0.6416, 0.2337, 0.7431, 0.9788, 0.6181, 0.2464, 0.4661, 0.7621, - 0.7020, 0.8203, 0.8869, 0.2145, 0.7724, 0.6093, 0.6692, 0.9686, - 0.5609, 0.0310, 0.2248, 0.2950, 0.2365, 0.1347, 0.2342, 0.1668, - 0.3378, 0.4330, 0.2775, 0.9901, 0.7053, 0.7266, 0.4840, 0.2820, - 0.5733, 0.4555, 0.6049, 0.0770, 0.4760, 0.6060, 0.4159, 0.3427, - 0.1234, 0.7062, 0.8569, 0.1878, 0.9057, 0.9399, 0.8139, 0.1407, - 0.1794, 0.9123, 0.9493, 0.2827, 0.9934, 0.0952, 0.4879, 0.5160, - 0.4118, 0.4873, 0.3642, 0.7470, 0.0866, 0.5172, 0.6365, 0.2676, - 0.2407, 0.7223, 0.5761, 0.1143, 0.7137, 0.2342, 0.3353, 0.6880, - 0.2296, 0.6023, 0.6027, 0.4138, 0.5408, 0.9859, 0.1503, 0.7238, - 0.6054, 0.2477, 0.6804, 0.1432, 0.4540, 0.9776, 0.8762, 0.7607, - 0.9025, 0.9807, 0.0652, 0.8661, 0.7663, 0.2586, 0.3994, 0.0335, - 0.7328, 0.0166, 0.9589, 0.4348, 0.5493, 0.7269, 0.6867, 0.6614, - 0.6800, 0.7804, 0.5591, 0.8381, 0.0910, 0.7573, 0.8985, 0.3083, - 0.3188, 0.8481, 0.2356, 0.6736, 0.4770, 0.4560, 0.6266, 0.4677 -}; - -#define WIND_DAMP_INTERVAL 50 -#define WIND_GUST_TIME 2500.0 -#define WIND_GUST_DECAY (1.0 / WIND_GUST_TIME) -extern bool R_GetWindVector(vec3_t windVector); - -int lastWindTime = 0; -float curWindSpeed=0; -vec3_t curWindBlowVect={0,0,0}, targetWindBlowVect={0,0,0}; -vec3_t curWindGrassDir={0,0,0}, targetWindGrassDir={0,0,0}; -int totalsurfsprites=0, sssurfaces=0; - -qboolean curWindPointActive=qfalse; -float curWindPointForce = 0; -vec3_t curWindPoint; -int nextGustTime=0; -float gustLeft=0; - -static void R_UpdateWind(void) -{ - float dtime, dampfactor; // Time since last update and damping time for wind changes - float ratio; - vec3_t ang, diff, retwindvec; - float targetspeed; - - if (backEnd.refdef.time == lastWindTime) - return; - - if (backEnd.refdef.time < lastWindTime) - { - curWindSpeed = r_windSpeed->value; - nextGustTime = 0; - gustLeft = 0; - } - - targetspeed = r_windSpeed->value; // Minimum gust delay, in seconds. - - if (targetspeed > 0 && r_windGust->value) - { - if (gustLeft > 0) - { // We are gusting - // Add an amount to the target wind speed - targetspeed *= 1.0 + gustLeft; - - gustLeft -= (float)(backEnd.refdef.time - lastWindTime)*WIND_GUST_DECAY; - if (gustLeft <= 0) - { - nextGustTime = backEnd.refdef.time + (r_windGust->value*1000)*flrand(1.0,4.0); - } - } - else if (backEnd.refdef.time >= nextGustTime) - { // See if there is another right now - // Gust next time, mano - gustLeft = flrand(0.75,1.5); - } - } - - // See if there is a weather system that will tell us a windspeed. - if (R_GetWindVector(retwindvec)) - { - retwindvec[2]=0; - VectorScale(retwindvec, -1.0, retwindvec); - vectoangles(retwindvec, ang); - } - else - { // Calculate the target wind vector based off cvars - ang[YAW] = r_windAngle->value; - } - - ang[PITCH] = -90.0 + targetspeed; - if (ang[PITCH]>-45.0) - { - ang[PITCH] = -45.0; - } - ang[ROLL] = 0; - - if (targetspeed>0) - { -// ang[YAW] += cos(tr.refdef.time*0.01+flrand(-1.0,1.0))*targetspeed*0.5; -// ang[PITCH] += sin(tr.refdef.time*0.01+flrand(-1.0,1.0))*targetspeed*0.5; - } - - // Get the grass wind vector first - AngleVectors(ang, targetWindGrassDir, NULL, NULL); - targetWindGrassDir[2]-=1.0; -// VectorScale(targetWindGrassDir, targetspeed, targetWindGrassDir); - - // Now get the general wind vector (no pitch) - ang[PITCH]=0; - AngleVectors(ang, targetWindBlowVect, NULL, NULL); - - // Start calculating a smoothing factor so wind doesn't change abruptly between speeds. - dampfactor = 1.0-r_windDampFactor->value; // We must exponent the amount LEFT rather than the amount bled off - dtime = (float)(backEnd.refdef.time - lastWindTime) * (1.0/(float)WIND_DAMP_INTERVAL); // Our dampfactor is geared towards a time interval equal to "1". - - // Note that since there are a finite number of "practical" delta millisecond values possible, - // the ratio should be initialized into a chart ultimately. - ratio = pow(dampfactor, dtime); - - // Apply this ratio to the windspeed... - curWindSpeed = targetspeed - (ratio * (targetspeed-curWindSpeed)); - - // Use the curWindSpeed to calculate the final target wind vector (with speed) - VectorScale(targetWindBlowVect, curWindSpeed, targetWindBlowVect); - VectorSubtract(targetWindBlowVect, curWindBlowVect, diff); - VectorMA(targetWindBlowVect, -ratio, diff, curWindBlowVect); - - // Update the grass vector now - VectorSubtract(targetWindGrassDir, curWindGrassDir, diff); - VectorMA(targetWindGrassDir, -ratio, diff, curWindGrassDir); - - lastWindTime = backEnd.refdef.time; - - curWindPointForce = r_windPointForce->value - (ratio * (r_windPointForce->value - curWindPointForce)); - if (curWindPointForce < 0.01) - { - curWindPointActive = qfalse; - } - else - { - curWindPointActive = qtrue; - curWindPoint[0] = r_windPointX->value; - curWindPoint[1] = r_windPointY->value; - curWindPoint[2] = 0; - } - - if (r_surfaceSprites->integer >= 2) - { - ri.Printf( PRINT_DEVELOPER, "Surfacesprites Drawn: %d, on %d surfaces\n", totalsurfsprites, sssurfaces); - } - - totalsurfsprites=0; - sssurfaces=0; -} - - - -///////////////////////////////////////////// -// Surface sprite calculation and drawing. -///////////////////////////////////////////// - -#define FADE_RANGE 250.0 -#define WINDPOINT_RADIUS 750.0 - -float SSVertAlpha[SHADER_MAX_VERTEXES]; -float SSVertWindForce[SHADER_MAX_VERTEXES]; -vec2_t SSVertWindDir[SHADER_MAX_VERTEXES]; - -qboolean SSAdditiveTransparency=qfalse; -qboolean SSUsingFog=qfalse; - - -///////////////////////////////////////////// -// Vertical surface sprites - -static void RB_VerticalSurfaceSprite(vec3_t loc, float width, float height, byte light, - byte alpha, float wind, float windidle, vec2_t fog, int hangdown, vec2_t skew) -{ - vec3_t loc2, right; - float angle; - float windsway; - float points[16]; - color4ub_t color; - - angle = ((loc[0]+loc[1])*0.02+(tr.refdef.time*0.0015)); - - if (windidle>0.0) - { - windsway = (height*windidle*0.075); - loc2[0] = loc[0]+skew[0]+cos(angle)*windsway; - loc2[1] = loc[1]+skew[1]+sin(angle)*windsway; - - if (hangdown) - { - loc2[2] = loc[2]-height; - } - else - { - loc2[2] = loc[2]+height; - } - } - else - { - loc2[0] = loc[0]+skew[0]; - loc2[1] = loc[1]+skew[1]; - if (hangdown) - { - loc2[2] = loc[2]-height; - } - else - { - loc2[2] = loc[2]+height; - } - } - - if (wind>0.0 && curWindSpeed > 0.001) - { - windsway = (height*wind*0.075); - - // Add the angle - VectorMA(loc2, height*wind, curWindGrassDir, loc2); - // Bob up and down - if (curWindSpeed < 40.0) - { - windsway *= curWindSpeed*(1.0/100.0); - } - else - { - windsway *= 0.4; - } - loc2[2] += sin(angle*2.5)*windsway; - } - - VectorScale(backEnd.viewParms.or.axis[1], width*0.5, right); - - color[0]=light; - color[1]=light; - color[2]=light; - color[3]=alpha; - - // Bottom right -// VectorAdd(loc, right, point); - points[0] = loc[0] + right[0]; - points[1] = loc[1] + right[1]; - points[2] = loc[2] + right[2]; - points[3] = 0; - - // Top right -// VectorAdd(loc2, right, point); - points[4] = loc2[0] + right[0]; - points[5] = loc2[1] + right[1]; - points[6] = loc2[2] + right[2]; - points[7] = 0; - - // Top left -// VectorSubtract(loc2, right, point); - points[8] = loc2[0] - right[0]; - points[9] = loc2[1] - right[1]; - points[10] = loc2[2] - right[2]; - points[11] = 0; - - // Bottom left -// VectorSubtract(loc, right, point); - points[12] = loc[0] - right[0]; - points[13] = loc[1] - right[1]; - points[14] = loc[2] - right[2]; - points[15] = 0; - - // Add the sprite to the render list. - SQuickSprite.Add(points, color, fog); -} - -static void RB_VerticalSurfaceSpriteWindPoint(vec3_t loc, float width, float height, byte light, - byte alpha, float wind, float windidle, vec2_t fog, - int hangdown, vec2_t skew, vec2_t winddiff, float windforce) -{ - vec3_t loc2, right; - float angle; - float windsway; - float points[16]; - color4ub_t color; - - if (windforce > 1) - windforce = 1; - -// wind += 1.0-windforce; - - angle = (loc[0]+loc[1])*0.02+(tr.refdef.time*0.0015); - - if (curWindSpeed <80.0) - { - windsway = (height*windidle*0.1)*(1.0+windforce); - loc2[0] = loc[0]+skew[0]+cos(angle)*windsway; - loc2[1] = loc[1]+skew[1]+sin(angle)*windsway; - } - else - { - loc2[0] = loc[0]+skew[0]; - loc2[1] = loc[1]+skew[1]; - } - if (hangdown) - { - loc2[2] = loc[2]-height; - } - else - { - loc2[2] = loc[2]+height; - } - - if (curWindSpeed > 0.001) - { - // Add the angle - VectorMA(loc2, height*wind, curWindGrassDir, loc2); - } - - loc2[0] += height*winddiff[0]*windforce; - loc2[1] += height*winddiff[1]*windforce; - loc2[2] -= height*windforce*(0.75 + 0.15*sin((tr.refdef.time + 500*windforce)*0.01)); - - VectorScale(backEnd.viewParms.or.axis[1], width*0.5, right); - - color[0]=light; - color[1]=light; - color[2]=light; - color[3]=alpha; - - // Bottom right -// VectorAdd(loc, right, point); - points[0] = loc[0] + right[0]; - points[1] = loc[1] + right[1]; - points[2] = loc[2] + right[2]; - points[3] = 0; - - // Top right -// VectorAdd(loc2, right, point); - points[4] = loc2[0] + right[0]; - points[5] = loc2[1] + right[1]; - points[6] = loc2[2] + right[2]; - points[7] = 0; - - // Top left -// VectorSubtract(loc2, right, point); - points[8] = loc2[0] - right[0]; - points[9] = loc2[1] - right[1]; - points[10] = loc2[2] - right[2]; - points[11] = 0; - - // Bottom left -// VectorSubtract(loc, right, point); - points[12] = loc[0] - right[0]; - points[13] = loc[1] - right[1]; - points[14] = loc[2] - right[2]; - points[15] = 0; - - // Add the sprite to the render list. - SQuickSprite.Add(points, color, fog); -} - -static void RB_DrawVerticalSurfaceSprites( shaderStage_t *stage, shaderCommands_t *input) -{ - int curindex, curvert; - vec3_t dist; - float triarea; - vec2_t vec1to2, vec1to3; - - vec3_t v1,v2,v3; - float a1,a2,a3; - float l1,l2,l3; - vec2_t fog1, fog2, fog3; - vec2_t winddiff1, winddiff2, winddiff3; - float windforce1, windforce2, windforce3; - - float posi, posj; - float step; - float fa,fb,fc; - - vec3_t curpoint; - float width, height; - float alpha, alphapos, thisspritesfadestart, light; - - byte randomindex2; - - vec2_t skew={0,0}; - vec2_t fogv; - vec2_t winddiffv; - float windforce=0; - qboolean usewindpoint = (qboolean) !!(curWindPointActive && stage->ss.wind > 0); - - float cutdist=stage->ss.fadeMax, cutdist2=cutdist*cutdist; - float fadedist=stage->ss.fadeDist, fadedist2=fadedist*fadedist; - - assert(cutdist2 != fadedist2); - float inv_fadediff = 1.0/(cutdist2-fadedist2); - - // The faderange is the fraction amount it takes for these sprites to fade out, assuming an ideal fade range of 250 - float faderange = FADE_RANGE/(cutdist-fadedist); - - if (faderange > 1.0) - { // Don't want to force a new fade_rand - faderange = 1.0; - } - - // Quickly calc all the alphas and windstuff for each vertex - for (curvert=0; curvertnumVertexes; curvert++) - { - // Calc alpha at each point - VectorSubtract(backEnd.viewParms.or.origin, input->xyz[curvert], dist); - SSVertAlpha[curvert] = 1.0 - (VectorLengthSquared(dist) - fadedist2) * inv_fadediff; - } - - // Wind only needs initialization once per tess. - if (usewindpoint && !tess.SSInitializedWind) - { - for (curvert=0; curvertnumVertexes;curvert++) - { // Calc wind at each point - dist[0]=input->xyz[curvert][0] - curWindPoint[0]; - dist[1]=input->xyz[curvert][1] - curWindPoint[1]; - step = (dist[0]*dist[0] + dist[1]*dist[1]); // dist squared - - if (step >= (float)(WINDPOINT_RADIUS*WINDPOINT_RADIUS)) - { // No wind - SSVertWindDir[curvert][0] = 0; - SSVertWindDir[curvert][1] = 0; - SSVertWindForce[curvert]=0; // Should be < 1 - } - else - { - if (step<1) - { // Don't want to divide by zero - SSVertWindDir[curvert][0] = 0; - SSVertWindDir[curvert][1] = 0; - SSVertWindForce[curvert] = curWindPointForce * stage->ss.wind; - } - else - { - step = Q_rsqrt(step); // Equals 1 over the distance. - SSVertWindDir[curvert][0] = dist[0] * step; - SSVertWindDir[curvert][1] = dist[1] * step; - step = 1.0 - (1.0 / (step * WINDPOINT_RADIUS)); // 1- (dist/maxradius) = a scale from 0 to 1 linearly dropping off - SSVertWindForce[curvert] = curWindPointForce * stage->ss.wind * step; // *step means divide by the distance. - } - } - } - tess.SSInitializedWind = qtrue; - } - - for (curindex=0; curindexnumIndexes-2; curindex+=3) - { - curvert = input->indexes[curindex]; - VectorCopy(input->xyz[curvert], v1); - if (stage->ss.facing) - { // Hang down - if (input->normal[curvert][2] > -0.5) - { - continue; - } - } - else - { // Point up - if (input->normal[curvert][2] < 0.5) - { - continue; - } - } - l1 = input->vertexColors[curvert][2]; - a1 = SSVertAlpha[curvert]; - fog1[0] = *((float *)(tess.svars.texcoords[0])+(curvert<<1)); - fog1[1] = *((float *)(tess.svars.texcoords[0])+(curvert<<1)+1); - winddiff1[0] = SSVertWindDir[curvert][0]; - winddiff1[1] = SSVertWindDir[curvert][1]; - windforce1 = SSVertWindForce[curvert]; - - curvert = input->indexes[curindex+1]; - VectorCopy(input->xyz[curvert], v2); - if (stage->ss.facing) - { // Hang down - if (input->normal[curvert][2] > -0.5) - { - continue; - } - } - else - { // Point up - if (input->normal[curvert][2] < 0.5) - { - continue; - } - } - l2 = input->vertexColors[curvert][2]; - a2 = SSVertAlpha[curvert]; - fog2[0] = *((float *)(tess.svars.texcoords[0])+(curvert<<1)); - fog2[1] = *((float *)(tess.svars.texcoords[0])+(curvert<<1)+1); - winddiff2[0] = SSVertWindDir[curvert][0]; - winddiff2[1] = SSVertWindDir[curvert][1]; - windforce2 = SSVertWindForce[curvert]; - - curvert = input->indexes[curindex+2]; - VectorCopy(input->xyz[curvert], v3); - if (stage->ss.facing) - { // Hang down - if (input->normal[curvert][2] > -0.5) - { - continue; - } - } - else - { // Point up - if (input->normal[curvert][2] < 0.5) - { - continue; - } - } - l3 = input->vertexColors[curvert][2]; - a3 = SSVertAlpha[curvert]; - fog3[0] = *((float *)(tess.svars.texcoords[0])+(curvert<<1)); - fog3[1] = *((float *)(tess.svars.texcoords[0])+(curvert<<1)+1); - winddiff3[0] = SSVertWindDir[curvert][0]; - winddiff3[1] = SSVertWindDir[curvert][1]; - windforce3 = SSVertWindForce[curvert]; - - if (a1 <= 0.0 && a2 <= 0.0 && a3 <= 0.0) - { - continue; - } - - // Find the area in order to calculate the stepsize - vec1to2[0] = v2[0] - v1[0]; - vec1to2[1] = v2[1] - v1[1]; - vec1to3[0] = v3[0] - v1[0]; - vec1to3[1] = v3[1] - v1[1]; - - // Now get the cross product of this sum. - triarea = vec1to3[0]*vec1to2[1] - vec1to3[1]*vec1to2[0]; - triarea=fabs(triarea); - if (triarea <= 1.0) - { // Insanely small abhorrent triangle. - continue; - } - step = stage->ss.density * Q_rsqrt(triarea); - - randomindex = (byte)(v1[0]+v1[1]+v2[0]+v2[1]+v3[0]+v3[1]); - randominterval = (byte)(v1[0]+v2[1]+v3[2])|0x03; // Make sure the interval is at least 3, and always odd - - for (posi=0; posi<1.0; posi+=step) - { - for (posj=0; posj<(1.0-posi); posj+=step) - { - fa=posi+randomchart[randomindex]*step; - randomindex += randominterval; - - fb=posj+randomchart[randomindex]*step; - randomindex += randominterval; - - if (fa>1.0) - continue; - - if (fb>(1.0-fa)) - continue; - - fc = 1.0-fa-fb; - - // total alpha, minus random factor so some things fade out sooner. - alphapos = a1*fa + a2*fb + a3*fc; - - // Note that the alpha at this point is a value from 1.0 to 0.0, but represents when to START fading - thisspritesfadestart = faderange + (1.0-faderange) * randomchart[randomindex]; - randomindex += randominterval; - - // Find where the alpha is relative to the fadestart, and calc the real alpha to draw at. - alpha = 1.0 - ((thisspritesfadestart-alphapos)/faderange); - if (alpha > 0.0) - { - if (alpha > 1.0) - alpha=1.0; - - if (SSUsingFog) - { - fogv[0] = fog1[0]*fa + fog2[0]*fb + fog3[0]*fc; - fogv[1] = fog1[1]*fa + fog2[1]*fb + fog3[1]*fc; - } - - if (usewindpoint) - { - winddiffv[0] = winddiff1[0]*fa + winddiff2[0]*fb + winddiff3[0]*fc; - winddiffv[1] = winddiff1[1]*fa + winddiff2[1]*fb + winddiff3[1]*fc; - windforce = windforce1*fa + windforce2*fb + windforce3*fc; - } - - VectorScale(v1, fa, curpoint); - VectorMA(curpoint, fb, v2, curpoint); - VectorMA(curpoint, fc, v3, curpoint); - - light = l1*fa + l2*fb + l3*fc; - if (SSAdditiveTransparency) - { // Additive transparency, scale light value - light *= alpha; - } - - randomindex2 = randomindex; - width = stage->ss.width*(1.0 + (stage->ss.variance[0]*randomchart[randomindex2])); - height = stage->ss.height*(1.0 + (stage->ss.variance[1]*randomchart[randomindex2++])); - if (randomchart[randomindex2++]>0.5) - { - width = -width; - } - if (stage->ss.fadeScale!=0 && alphapos < 1.0) - { - width *= 1.0 + (stage->ss.fadeScale*(1.0-alphapos)); - } - - if (stage->ss.vertSkew != 0) - { // flrand(-vertskew, vertskew) - skew[0] = height * ((stage->ss.vertSkew*2.0f*randomchart[randomindex2++])-stage->ss.vertSkew); - skew[1] = height * ((stage->ss.vertSkew*2.0f*randomchart[randomindex2++])-stage->ss.vertSkew); - } - - if (usewindpoint && windforce > 0 && stage->ss.wind > 0.0) - { - if (SSUsingFog) - { - RB_VerticalSurfaceSpriteWindPoint(curpoint, width, height, (byte)light, (byte)(alpha*255.0), - stage->ss.wind, stage->ss.windIdle, fogv, stage->ss.facing, skew, - winddiffv, windforce); - } - else - { - RB_VerticalSurfaceSpriteWindPoint(curpoint, width, height, (byte)light, (byte)(alpha*255.0), - stage->ss.wind, stage->ss.windIdle, NULL, stage->ss.facing, skew, - winddiffv, windforce); - } - } - else - { - if (SSUsingFog) - { - RB_VerticalSurfaceSprite(curpoint, width, height, (byte)light, (byte)(alpha*255.0), - stage->ss.wind, stage->ss.windIdle, fogv, stage->ss.facing, skew); - } - else - { - RB_VerticalSurfaceSprite(curpoint, width, height, (byte)light, (byte)(alpha*255.0), - stage->ss.wind, stage->ss.windIdle, NULL, stage->ss.facing, skew); - } - } - - totalsurfsprites++; - } - } - } - } -} - - -///////////////////////////////////////////// -// Oriented surface sprites - -static void RB_OrientedSurfaceSprite(vec3_t loc, float width, float height, byte light, byte alpha, vec2_t fog, int faceup) -{ - vec3_t loc2, right; - float points[16]; - color4ub_t color; - - color[0]=light; - color[1]=light; - color[2]=light; - color[3]=alpha; - - if (faceup) - { - width *= 0.5; - height *= 0.5; - - // Bottom right - // VectorAdd(loc, right, point); - points[0] = loc[0] + width; - points[1] = loc[1] - width; - points[2] = loc[2] + 1.0; - points[3] = 0; - - // Top right - // VectorAdd(loc, right, point); - points[4] = loc[0] + width; - points[5] = loc[1] + width; - points[6] = loc[2] + 1.0; - points[7] = 0; - - // Top left - // VectorSubtract(loc, right, point); - points[8] = loc[0] - width; - points[9] = loc[1] + width; - points[10] = loc[2] + 1.0; - points[11] = 0; - - // Bottom left - // VectorSubtract(loc, right, point); - points[12] = loc[0] - width; - points[13] = loc[1] - width; - points[14] = loc[2] + 1.0; - points[15] = 0; - } - else - { - VectorMA(loc, height, backEnd.viewParms.or.axis[2], loc2); - VectorScale(backEnd.viewParms.or.axis[1], width*0.5, right); - - // Bottom right - // VectorAdd(loc, right, point); - points[0] = loc[0] + right[0]; - points[1] = loc[1] + right[1]; - points[2] = loc[2] + right[2]; - points[3] = 0; - - // Top right - // VectorAdd(loc2, right, point); - points[4] = loc2[0] + right[0]; - points[5] = loc2[1] + right[1]; - points[6] = loc2[2] + right[2]; - points[7] = 0; - - // Top left - // VectorSubtract(loc2, right, point); - points[8] = loc2[0] - right[0]; - points[9] = loc2[1] - right[1]; - points[10] = loc2[2] - right[2]; - points[11] = 0; - - // Bottom left - // VectorSubtract(loc, right, point); - points[12] = loc[0] - right[0]; - points[13] = loc[1] - right[1]; - points[14] = loc[2] - right[2]; - points[15] = 0; - } - - // Add the sprite to the render list. - SQuickSprite.Add(points, color, fog); -} - -static void RB_DrawOrientedSurfaceSprites( shaderStage_t *stage, shaderCommands_t *input) -{ - int curindex, curvert; - vec3_t dist; - float triarea, minnormal; - vec2_t vec1to2, vec1to3; - - vec3_t v1,v2,v3; - float a1,a2,a3; - float l1,l2,l3; - vec2_t fog1, fog2, fog3; - - float posi, posj; - float step; - float fa,fb,fc; - - vec3_t curpoint; - float width, height; - float alpha, alphapos, thisspritesfadestart, light; - byte randomindex2; - vec2_t fogv; - - float cutdist=stage->ss.fadeMax, cutdist2=cutdist*cutdist; - float fadedist=stage->ss.fadeDist, fadedist2=fadedist*fadedist; - - assert(cutdist2 != fadedist2); - float inv_fadediff = 1.0/(cutdist2-fadedist2); - - // The faderange is the fraction amount it takes for these sprites to fade out, assuming an ideal fade range of 250 - float faderange = FADE_RANGE/(cutdist-fadedist); - - if (faderange > 1.0) - { // Don't want to force a new fade_rand - faderange = 1.0; - } - - if (stage->ss.facing) - { // Faceup sprite. - minnormal = 0.99; - } - else - { // Normal oriented sprite - minnormal = 0.5; - } - - // Quickly calc all the alphas for each vertex - for (curvert=0; curvertnumVertexes; curvert++) - { - // Calc alpha at each point - VectorSubtract(backEnd.viewParms.or.origin, input->xyz[curvert], dist); - SSVertAlpha[curvert] = 1.0 - (VectorLengthSquared(dist) - fadedist2) * inv_fadediff; - } - - for (curindex=0; curindexnumIndexes-2; curindex+=3) - { - curvert = input->indexes[curindex]; - VectorCopy(input->xyz[curvert], v1); - if (input->normal[curvert][2] < minnormal) - { - continue; - } - l1 = input->vertexColors[curvert][2]; - a1 = SSVertAlpha[curvert]; - fog1[0] = *((float *)(tess.svars.texcoords[0])+(curvert<<1)); - fog1[1] = *((float *)(tess.svars.texcoords[0])+(curvert<<1)+1); - - curvert = input->indexes[curindex+1]; - VectorCopy(input->xyz[curvert], v2); - if (input->normal[curvert][2] < minnormal) - { - continue; - } - l2 = input->vertexColors[curvert][2]; - a2 = SSVertAlpha[curvert]; - fog2[0] = *((float *)(tess.svars.texcoords[0])+(curvert<<1)); - fog2[1] = *((float *)(tess.svars.texcoords[0])+(curvert<<1)+1); - - curvert = input->indexes[curindex+2]; - VectorCopy(input->xyz[curvert], v3); - if (input->normal[curvert][2] < minnormal) - { - continue; - } - l3 = input->vertexColors[curvert][2]; - a3 = SSVertAlpha[curvert]; - fog3[0] = *((float *)(tess.svars.texcoords[0])+(curvert<<1)); - fog3[1] = *((float *)(tess.svars.texcoords[0])+(curvert<<1)+1); - - if (a1 <= 0.0 && a2 <= 0.0 && a3 <= 0.0) - { - continue; - } - - // Find the area in order to calculate the stepsize - vec1to2[0] = v2[0] - v1[0]; - vec1to2[1] = v2[1] - v1[1]; - vec1to3[0] = v3[0] - v1[0]; - vec1to3[1] = v3[1] - v1[1]; - - // Now get the cross product of this sum. - triarea = vec1to3[0]*vec1to2[1] - vec1to3[1]*vec1to2[0]; - triarea=fabs(triarea); - if (triarea <= 1.0) - { // Insanely small abhorrent triangle. - continue; - } - step = stage->ss.density * Q_rsqrt(triarea); - - randomindex = (byte)(v1[0]+v1[1]+v2[0]+v2[1]+v3[0]+v3[1]); - randominterval = (byte)(v1[0]+v2[1]+v3[2])|0x03; // Make sure the interval is at least 3, and always odd - - for (posi=0; posi<1.0; posi+=step) - { - for (posj=0; posj<(1.0-posi); posj+=step) - { - fa=posi+randomchart[randomindex]*step; - randomindex += randominterval; - if (fa>1.0) - continue; - - fb=posj+randomchart[randomindex]*step; - randomindex += randominterval; - if (fb>(1.0-fa)) - continue; - - fc = 1.0-fa-fb; - - // total alpha, minus random factor so some things fade out sooner. - alphapos = a1*fa + a2*fb + a3*fc; - - // Note that the alpha at this point is a value from 1.0 to 0.0, but represents when to START fading - thisspritesfadestart = faderange + (1.0-faderange) * randomchart[randomindex]; - randomindex += randominterval; - - // Find where the alpha is relative to the fadestart, and calc the real alpha to draw at. - alpha = 1.0 - ((thisspritesfadestart-alphapos)/faderange); - - randomindex += randominterval; - if (alpha > 0.0) - { - if (alpha > 1.0) - alpha=1.0; - - if (SSUsingFog) - { - fogv[0] = fog1[0]*fa + fog2[0]*fb + fog3[0]*fc; - fogv[1] = fog1[1]*fa + fog2[1]*fb + fog3[1]*fc; - } - - VectorScale(v1, fa, curpoint); - VectorMA(curpoint, fb, v2, curpoint); - VectorMA(curpoint, fc, v3, curpoint); - - light = l1*fa + l2*fb + l3*fc; - if (SSAdditiveTransparency) - { // Additive transparency, scale light value - light *= alpha; - } - - randomindex2 = randomindex; - width = stage->ss.width*(1.0 + (stage->ss.variance[0]*randomchart[randomindex2])); - height = stage->ss.height*(1.0 + (stage->ss.variance[1]*randomchart[randomindex2++])); - if (randomchart[randomindex2++]>0.5) - { - width = -width; - } - if (stage->ss.fadeScale!=0 && alphapos < 1.0) - { - width *= 1.0 + (stage->ss.fadeScale*(1.0-alphapos)); - } - - if (SSUsingFog) - { - RB_OrientedSurfaceSprite(curpoint, width, height, (byte)light, (byte)(alpha*255.0), fogv, stage->ss.facing); - } - else - { - RB_OrientedSurfaceSprite(curpoint, width, height, (byte)light, (byte)(alpha*255.0), NULL, stage->ss.facing); - } - - totalsurfsprites++; - } - } - } - } -} - - -///////////////////////////////////////////// -// Effect surface sprites - -static void RB_EffectSurfaceSprite(vec3_t loc, float width, float height, byte light, byte alpha, float life, int faceup) -{ - vec3_t loc2, right; - float points[16]; - color4ub_t color; - - color[0]=light; - color[1]=light; - color[2]=light; - color[3]=alpha; - - if (faceup) - { - width *= 0.5; - height *= 0.5; - - // Bottom right - // VectorAdd(loc, right, point); - points[0] = loc[0] + width; - points[1] = loc[1] - width; - points[2] = loc[2] + 1.0; - points[3] = 0; - - // Top right - // VectorAdd(loc, right, point); - points[4] = loc[0] + width; - points[5] = loc[1] + width; - points[6] = loc[2] + 1.0; - points[7] = 0; - - // Top left - // VectorSubtract(loc, right, point); - points[8] = loc[0] - width; - points[9] = loc[1] + width; - points[10] = loc[2] + 1.0; - points[11] = 0; - - // Bottom left - // VectorSubtract(loc, right, point); - points[12] = loc[0] - width; - points[13] = loc[1] - width; - points[14] = loc[2] + 1.0; - points[15] = 0; - } - else - { - VectorMA(loc, height, backEnd.viewParms.or.axis[2], loc2); - VectorScale(backEnd.viewParms.or.axis[1], width*0.5, right); - - // Bottom right - // VectorAdd(loc, right, point); - points[0] = loc[0] + right[0]; - points[1] = loc[1] + right[1]; - points[2] = loc[2] + right[2]; - points[3] = 0; - - // Top right - // VectorAdd(loc2, right, point); - points[4] = loc2[0] + right[0]; - points[5] = loc2[1] + right[1]; - points[6] = loc2[2] + right[2]; - points[7] = 0; - - // Top left - // VectorSubtract(loc2, right, point); - points[8] = loc2[0] - right[0]; - points[9] = loc2[1] - right[1]; - points[10] = loc2[2] - right[2]; - points[11] = 0; - - // Bottom left - // VectorSubtract(loc, right, point); - points[12] = loc[0] - right[0]; - points[13] = loc[1] - right[1]; - points[14] = loc[2] - right[2]; - points[15] = 0; - } - - // Add the sprite to the render list. - SQuickSprite.Add(points, color, NULL); -} - -static void RB_DrawEffectSurfaceSprites( shaderStage_t *stage, shaderCommands_t *input) -{ - int curindex, curvert; - vec3_t dist; - float triarea, minnormal; - vec2_t vec1to2, vec1to3; - - vec3_t v1,v2,v3; - float a1,a2,a3; - float l1,l2,l3; - - float posi, posj; - float step; - float fa,fb,fc; - float effecttime, effectpos; - float density; - - vec3_t curpoint; - float width, height; - float alpha, alphapos, thisspritesfadestart, light; - byte randomindex2; - - float cutdist=stage->ss.fadeMax, cutdist2=cutdist*cutdist; - float fadedist=stage->ss.fadeDist, fadedist2=fadedist*fadedist; - - float fxalpha = stage->ss.fxAlphaEnd - stage->ss.fxAlphaStart; - - assert(cutdist2 != fadedist2); - float inv_fadediff = 1.0/(cutdist2-fadedist2); - - // The faderange is the fraction amount it takes for these sprites to fade out, assuming an ideal fade range of 250 - float faderange = FADE_RANGE/(cutdist-fadedist); - if (faderange > 1.0) - { // Don't want to force a new fade_rand - faderange = 1.0; - } - - if (stage->ss.facing) - { // Faceup sprite. - minnormal = 0.99; - } - else - { // Normal oriented sprite - minnormal = 0.5; - } - - if (stage->ss.surfaceSpriteType == SURFSPRITE_WEATHERFX) - { // This effect is affected by weather settings. - if (r_surfaceWeather->value < 0.01) - { // Don't show these effects - return; - } - else - { - density = stage->ss.density / r_surfaceWeather->value; - } - } - else - { - density = stage->ss.density; - } - - // Quickly calc all the alphas for each vertex - for (curvert=0; curvertnumVertexes; curvert++) - { - // Calc alpha at each point - VectorSubtract(backEnd.viewParms.or.origin, input->xyz[curvert], dist); - SSVertAlpha[curvert] = 1.0 - (VectorLengthSquared(dist) - fadedist2) * inv_fadediff; - - // Note this is the proper equation, but isn't used right now because it would be just a tad slower. - // Formula for alpha is 1.0 - ((len-fade)/(cut-fade)) - // Which is equal to (1.0+fade/(cut-fade)) - (len/(cut-fade)) - // So mult=1/(cut-fade), and base=(1+fade*mult). - // SSVertAlpha[curvert] = fadebase - (VectorLength(dist) * fademult); - - } - - for (curindex=0; curindexnumIndexes-2; curindex+=3) - { - curvert = input->indexes[curindex]; - VectorCopy(input->xyz[curvert], v1); - if (input->normal[curvert][2] < minnormal) - { - continue; - } - l1 = input->vertexColors[curvert][2]; - a1 = SSVertAlpha[curvert]; - - curvert = input->indexes[curindex+1]; - VectorCopy(input->xyz[curvert], v2); - if (input->normal[curvert][2] < minnormal) - { - continue; - } - l2 = input->vertexColors[curvert][2]; - a2 = SSVertAlpha[curvert]; - - curvert = input->indexes[curindex+2]; - VectorCopy(input->xyz[curvert], v3); - if (input->normal[curvert][2] < minnormal) - { - continue; - } - l3 = input->vertexColors[curvert][2]; - a3 = SSVertAlpha[curvert]; - - if (a1 <= 0.0 && a2 <= 0.0 && a3 <= 0.0) - { - continue; - } - - // Find the area in order to calculate the stepsize - vec1to2[0] = v2[0] - v1[0]; - vec1to2[1] = v2[1] - v1[1]; - vec1to3[0] = v3[0] - v1[0]; - vec1to3[1] = v3[1] - v1[1]; - - // Now get the cross product of this sum. - triarea = vec1to3[0]*vec1to2[1] - vec1to3[1]*vec1to2[0]; - triarea=fabs(triarea); - if (triarea <= 1.0) - { // Insanely small abhorrent triangle. - continue; - } - step = density * Q_rsqrt(triarea); - - randomindex = (byte)(v1[0]+v1[1]+v2[0]+v2[1]+v3[0]+v3[1]); - randominterval = (byte)(v1[0]+v2[1]+v3[2])|0x03; // Make sure the interval is at least 3, and always odd - - for (posi=0; posi<1.0; posi+=step) - { - for (posj=0; posj<(1.0-posi); posj+=step) - { - effecttime = (tr.refdef.time+10000.0*randomchart[randomindex])/stage->ss.fxDuration; - effectpos = (float)effecttime - (int)effecttime; - - randomindex2 = randomindex+effecttime; - randomindex += randominterval; - fa=posi+randomchart[randomindex2++]*step; - if (fa>1.0) - continue; - - fb=posj+randomchart[randomindex2++]*step; - if (fb>(1.0-fa)) - continue; - - fc = 1.0-fa-fb; - - // total alpha, minus random factor so some things fade out sooner. - alphapos = a1*fa + a2*fb + a3*fc; - - // Note that the alpha at this point is a value from 1.0 to 0.0, but represents when to START fading - thisspritesfadestart = faderange + (1.0-faderange) * randomchart[randomindex2]; - randomindex2 += randominterval; - - // Find where the alpha is relative to the fadestart, and calc the real alpha to draw at. - alpha = 1.0 - ((thisspritesfadestart-alphapos)/faderange); - if (alpha > 0.0) - { - if (alpha > 1.0) - alpha=1.0; - - VectorScale(v1, fa, curpoint); - VectorMA(curpoint, fb, v2, curpoint); - VectorMA(curpoint, fc, v3, curpoint); - - light = l1*fa + l2*fb + l3*fc; - randomindex2 = randomindex; - width = stage->ss.width*(1.0 + (stage->ss.variance[0]*randomchart[randomindex2])); - height = stage->ss.height*(1.0 + (stage->ss.variance[1]*randomchart[randomindex2++])); - - width = width + (effectpos*stage->ss.fxGrow[0]*width); - height = height + (effectpos*stage->ss.fxGrow[1]*height); - alpha = alpha*(stage->ss.fxAlphaStart+(fxalpha*effectpos)); - - if (SSAdditiveTransparency) - { // Additive transparency, scale light value - light *= alpha; - } - - if (randomchart[randomindex2]>0.5) - { - width = -width; - } - if (stage->ss.fadeScale!=0 && alphapos < 1.0) - { - width *= 1.0 + (stage->ss.fadeScale*(1.0-alphapos)); - } - - if (stage->ss.wind>0.0 && curWindSpeed > 0.001) - { - vec3_t drawpoint; - - VectorMA(curpoint, effectpos*stage->ss.wind, curWindBlowVect, drawpoint); - RB_EffectSurfaceSprite(drawpoint, width, height, (byte)light, (byte)(alpha*255.0), stage->ss.fxDuration, stage->ss.facing); - } - else - { - RB_EffectSurfaceSprite(curpoint, width, height, (byte)light, (byte)(alpha*255.0), stage->ss.fxDuration, stage->ss.facing); - } - - totalsurfsprites++; - } - } - } - } -} - - -static void RB_DrawSurfaceSprites( shaderStage_t *stage, shaderCommands_t *input) -{ - fog_t *fog; - unsigned long glbits=stage->stateBits; - - R_UpdateWind(); - - // - // Check fog - // - if ( tess.fogNum && tess.shader->fogPass)// && r_drawfog->value) - { - fog = tr.world->fogs + tess.fogNum; - SSUsingFog = qtrue; - SQuickSprite.StartGroup(&stage->bundle[0], glbits, fog->colorInt); - } - else - { - SSUsingFog = qfalse; - SQuickSprite.StartGroup(&stage->bundle[0], glbits); - } - - // Special provision in case the transparency is additive. - if (glbits & GLS_SRCBLEND_ONE) - { // Additive transparency, scale light value - SSAdditiveTransparency=qtrue; - } - else - { - SSAdditiveTransparency=qfalse; - } - - switch(stage->ss.surfaceSpriteType) - { - case SURFSPRITE_VERTICAL: - RB_DrawVerticalSurfaceSprites(stage, input); - break; - case SURFSPRITE_ORIENTED: - RB_DrawOrientedSurfaceSprites(stage, input); - break; - case SURFSPRITE_EFFECT: - case SURFSPRITE_WEATHERFX: - RB_DrawEffectSurfaceSprites(stage, input); - break; - } - - SQuickSprite.EndGroup(); - - sssurfaces++; -} - - - - - -/* -============================================================= - -SURFACE SHADERS - -============================================================= -*/ - -shaderCommands_t tess; -static qboolean setArraysOnce; - -/* -================= -R_BindAnimatedImage - -================= -*/ -// de-static'd because tr_quicksprite wants it -void R_BindAnimatedImage( textureBundle_t *bundle ) { - int index; - - if ( bundle->isVideoMap ) { - ri.CIN_RunCinematic(bundle->videoMapHandle); - ri.CIN_UploadCinematic(bundle->videoMapHandle); - return; - } - - if ((r_fullbright->value /*|| tr.refdef.doFullbright */) && bundle->isLightmap) - { - GL_Bind( tr.whiteImage ); - return; - } - - if ( bundle->numImageAnimations <= 1 ) { - GL_Bind( bundle->image[0] ); - return; - } - - // it is necessary to do this messy calc to make sure animations line up - // exactly with waveforms of the same frequency - index = myftol( tess.shaderTime * bundle->imageAnimationSpeed * FUNCTABLE_SIZE ); - index >>= FUNCTABLE_SIZE2; - - if ( index < 0 ) { - index = 0; // may happen with shader time offsets - } - if ( bundle->oneShotAnimMap ) - { - if ( index >= bundle->numImageAnimations ) - { - // stick on last frame - index = bundle->numImageAnimations - 1; - } - } - else - { - // loop - index %= bundle->numImageAnimations; - } - - GL_Bind( bundle->image[ index ] ); -} - -/* -================ -DrawTris - -Draws triangle outlines for debugging -================ -*/ -static void DrawTris (shaderCommands_t *input) { - GL_Bind( tr.whiteImage ); - qglColor3f (1,1,1); - - GL_State( GLS_POLYMODE_LINE | GLS_DEPTHMASK_TRUE ); - qglDepthRange( 0, 0 ); - - qglDisableClientState (GL_COLOR_ARRAY); - qglDisableClientState (GL_TEXTURE_COORD_ARRAY); - - qglVertexPointer (3, GL_FLOAT, 16, input->xyz); // padded for SIMD - - if (qglLockArraysEXT) { - qglLockArraysEXT(0, input->numVertexes); - GLimp_LogComment( "glLockArraysEXT\n" ); - } - - R_DrawElements( input->numIndexes, input->indexes ); - - if (qglUnlockArraysEXT) { - qglUnlockArraysEXT(); - GLimp_LogComment( "glUnlockArraysEXT\n" ); - } - qglDepthRange( 0, 1 ); -} - - -/* -================ -DrawNormals - -Draws vertex normals for debugging -================ -*/ -static void DrawNormals (shaderCommands_t *input) { - int i; - vec3_t temp; - - GL_Bind( tr.whiteImage ); - qglColor3f (1,1,1); - qglDepthRange( 0, 0 ); // never occluded - GL_State( GLS_POLYMODE_LINE | GLS_DEPTHMASK_TRUE ); - - qglBegin (GL_LINES); - for (i = 0 ; i < input->numVertexes ; i++) { - qglVertex3fv (input->xyz[i]); - VectorMA (input->xyz[i], 2, input->normal[i], temp); - qglVertex3fv (temp); - } - qglEnd (); - - qglDepthRange( 0, 1 ); -} - -/* -============== -RB_BeginSurface - -We must set some things up before beginning any tesselation, -because a surface may be forced to perform a RB_End due -to overflow. -============== -*/ -void RB_BeginSurface( shader_t *shader, int fogNum ) { - - shader_t *state = (shader->remappedShader) ? shader->remappedShader : shader; - - tess.numIndexes = 0; - tess.numVertexes = 0; - tess.shader = state; - tess.fogNum = fogNum; - tess.dlightBits = 0; // will be OR'd in by surface functions - tess.xstages = state->stages; - tess.numPasses = state->numUnfoggedPasses; - tess.currentStageIteratorFunc = state->optimalStageIteratorFunc; - - tess.shaderTime = backEnd.refdef.floatTime - tess.shader->timeOffset; - if (tess.shader->clampTime && tess.shaderTime >= tess.shader->clampTime) { - tess.shaderTime = tess.shader->clampTime; - } - - -} - -/* -=================== -DrawMultitextured - -output = t0 * t1 or t0 + t1 - -t0 = most upstream according to spec -t1 = most downstream according to spec -=================== -*/ -static void DrawMultitextured( shaderCommands_t *input, int stage ) { - shaderStage_t *pStage; - - pStage = tess.xstages[stage]; - - GL_State( pStage->stateBits ); - - // this is an ugly hack to work around a GeForce driver - // bug with multitexture and clip planes - if ( backEnd.viewParms.isPortal ) { - qglPolygonMode( GL_FRONT_AND_BACK, GL_FILL ); - } - - // - // base - // - GL_SelectTexture( 0 ); - qglTexCoordPointer( 2, GL_FLOAT, 0, input->svars.texcoords[0] ); - R_BindAnimatedImage( &pStage->bundle[0] ); - - // - // lightmap/secondary pass - // - GL_SelectTexture( 1 ); - qglEnable( GL_TEXTURE_2D ); - qglEnableClientState( GL_TEXTURE_COORD_ARRAY ); - - if ( r_lightmap->integer ) { - GL_TexEnv( GL_REPLACE ); - } else { - GL_TexEnv( tess.shader->multitextureEnv ); - } - - qglTexCoordPointer( 2, GL_FLOAT, 0, input->svars.texcoords[1] ); - - R_BindAnimatedImage( &pStage->bundle[1] ); - - R_DrawElements( input->numIndexes, input->indexes ); - - // - // disable texturing on TEXTURE1, then select TEXTURE0 - // - //qglDisableClientState( GL_TEXTURE_COORD_ARRAY ); - qglDisable( GL_TEXTURE_2D ); - - GL_SelectTexture( 0 ); -} - - - -/* -=================== -ProjectDlightTexture - -Perform dynamic lighting with another rendering pass -=================== -*/ -static void ProjectDlightTexture( void ) { - int i, l; - vec3_t origin; - float *texCoords; - byte *colors; - byte clipBits[SHADER_MAX_VERTEXES]; - MAC_STATIC float texCoordsArray[SHADER_MAX_VERTEXES][2]; - byte colorArray[SHADER_MAX_VERTEXES][4]; - unsigned hitIndexes[SHADER_MAX_INDEXES]; - int numIndexes; - float scale; - float radius; - vec3_t floatColor; - - if ( !backEnd.refdef.num_dlights ) { - return; - } - - for ( l = 0 ; l < backEnd.refdef.num_dlights ; l++ ) { - dlight_t *dl; - - if ( !( tess.dlightBits & ( 1 << l ) ) ) { - continue; // this surface definately doesn't have any of this light - } - texCoords = texCoordsArray[0]; - colors = colorArray[0]; - - dl = &backEnd.refdef.dlights[l]; - VectorCopy( dl->transformed, origin ); - radius = dl->radius; - scale = 1.0f / radius; - floatColor[0] = dl->color[0] * 255.0f; - floatColor[1] = dl->color[1] * 255.0f; - floatColor[2] = dl->color[2] * 255.0f; - - for ( i = 0 ; i < tess.numVertexes ; i++, texCoords += 2, colors += 4 ) { - vec3_t dist; - int clip; - float modulate; - - backEnd.pc.c_dlightVertexes++; - - VectorSubtract( origin, tess.xyz[i], dist ); - texCoords[0] = 0.5f + dist[0] * scale; - texCoords[1] = 0.5f + dist[1] * scale; - - clip = 0; - if ( texCoords[0] < 0.0f ) { - clip |= 1; - } else if ( texCoords[0] > 1.0f ) { - clip |= 2; - } - if ( texCoords[1] < 0.0f ) { - clip |= 4; - } else if ( texCoords[1] > 1.0f ) { - clip |= 8; - } - // modulate the strength based on the height and color - if ( dist[2] > radius ) { - clip |= 16; - modulate = 0.0f; - } else if ( dist[2] < -radius ) { - clip |= 32; - modulate = 0.0f; - } else { - dist[2] = Q_fabs(dist[2]); - if ( dist[2] < radius * 0.5f ) { - modulate = 1.0f; - } else { - modulate = 2.0f * (radius - dist[2]) * scale; - } - } - clipBits[i] = clip; - - colors[0] = myftol(floatColor[0] * modulate); - colors[1] = myftol(floatColor[1] * modulate); - colors[2] = myftol(floatColor[2] * modulate); - colors[3] = 255; - } - - // build a list of triangles that need light - numIndexes = 0; - for ( i = 0 ; i < tess.numIndexes ; i += 3 ) { - int a, b, c; - - a = tess.indexes[i]; - b = tess.indexes[i+1]; - c = tess.indexes[i+2]; - if ( clipBits[a] & clipBits[b] & clipBits[c] ) { - continue; // not lighted - } - hitIndexes[numIndexes] = a; - hitIndexes[numIndexes+1] = b; - hitIndexes[numIndexes+2] = c; - numIndexes += 3; - } - - if ( !numIndexes ) { - continue; - } - - qglEnableClientState( GL_TEXTURE_COORD_ARRAY ); - qglTexCoordPointer( 2, GL_FLOAT, 0, texCoordsArray[0] ); - - qglEnableClientState( GL_COLOR_ARRAY ); - qglColorPointer( 4, GL_UNSIGNED_BYTE, 0, colorArray ); - - GL_Bind( tr.dlightImage ); - // include GLS_DEPTHFUNC_EQUAL so alpha tested surfaces don't add light - // where they aren't rendered - if ( dl->additive ) { - GL_State( GLS_SRCBLEND_ONE | GLS_DSTBLEND_ONE | GLS_DEPTHFUNC_EQUAL ); - } - else { - GL_State( GLS_SRCBLEND_DST_COLOR | GLS_DSTBLEND_ONE | GLS_DEPTHFUNC_EQUAL ); - } - R_DrawElements( numIndexes, hitIndexes ); - backEnd.pc.c_totalIndexes += numIndexes; - backEnd.pc.c_dlightIndexes += numIndexes; - } -} - - -/* -=================== -RB_FogPass - -Blends a fog texture on top of everything else -=================== -*/ -static void RB_FogPass( void ) { - fog_t *fog; - int i; - - qglEnableClientState( GL_COLOR_ARRAY ); - qglColorPointer( 4, GL_UNSIGNED_BYTE, 0, tess.svars.colors ); - - qglEnableClientState( GL_TEXTURE_COORD_ARRAY); - qglTexCoordPointer( 2, GL_FLOAT, 0, tess.svars.texcoords[0] ); - - fog = tr.world->fogs + tess.fogNum; - - for ( i = 0; i < tess.numVertexes; i++ ) { - * ( int * )&tess.svars.colors[i] = fog->colorInt; - } - - RB_CalcFogTexCoords( ( float * ) tess.svars.texcoords[0] ); - - GL_Bind( tr.fogImage ); - - if ( tess.shader->fogPass == FP_EQUAL ) { - GL_State( GLS_SRCBLEND_SRC_ALPHA | GLS_DSTBLEND_ONE_MINUS_SRC_ALPHA | GLS_DEPTHFUNC_EQUAL ); - } else { - GL_State( GLS_SRCBLEND_SRC_ALPHA | GLS_DSTBLEND_ONE_MINUS_SRC_ALPHA ); - } - - R_DrawElements( tess.numIndexes, tess.indexes ); -} - -/* -=============== -ComputeColors -=============== -*/ -static void ComputeColors( shaderStage_t *pStage, int forceRGBGen ) -{ - int i; - color4ub_t *colors = tess.svars.colors; - qboolean killGen = qfalse; - - if ( tess.shader != tr.projectionShadowShader && tess.shader != tr.shadowShader && - ( backEnd.currentEntity->e.renderfx & (RF_DISINTEGRATE1|RF_DISINTEGRATE2))) - { - RB_CalcDisintegrateColors( (unsigned char *)tess.svars.colors ); - RB_CalcDisintegrateVertDeform(); - - // We've done some custom alpha and color stuff, so we can skip the rest. Let it do fog though - killGen = qtrue; - } - - // - // rgbGen - // - if ( !forceRGBGen ) - { - forceRGBGen = pStage->rgbGen; - } - - if ( backEnd.currentEntity->e.renderfx & RF_VOLUMETRIC ) // does not work for rotated models, technically, this should also be a CGEN type, but that would entail adding new shader commands....which is too much work for one thing - { - int i; - float *normal, dot; - unsigned char *color; - int numVertexes; - - normal = tess.normal[0]; - color = tess.svars.colors[0]; - - numVertexes = tess.numVertexes; - - for ( i = 0 ; i < numVertexes ; i++, normal += 4, color += 4) - { - dot = DotProduct( normal, backEnd.refdef.viewaxis[0] ); - - dot *= dot * dot * dot; - - if ( dot < 0.2f ) // so low, so just clamp it - { - dot = 0.0f; - } - - color[0] = color[1] = color[2] = color[3] = myftol( backEnd.currentEntity->e.shaderRGBA[0] * (1-dot) ); - - } - - killGen = qtrue; - } - - if (killGen) - { - goto avoidGen; - } - - // - // rgbGen - // - switch ( forceRGBGen ) - { - case CGEN_IDENTITY: - Com_Memset( tess.svars.colors, 0xff, tess.numVertexes * 4 ); - break; - default: - case CGEN_IDENTITY_LIGHTING: - Com_Memset( tess.svars.colors, tr.identityLightByte, tess.numVertexes * 4 ); - break; - case CGEN_LIGHTING_DIFFUSE: - RB_CalcDiffuseColor( ( unsigned char * ) tess.svars.colors ); - break; - case CGEN_EXACT_VERTEX: - Com_Memcpy( tess.svars.colors, tess.vertexColors, tess.numVertexes * sizeof( tess.vertexColors[0] ) ); - break; - case CGEN_CONST: - for ( i = 0; i < tess.numVertexes; i++ ) { - *(int *)tess.svars.colors[i] = *(int *)pStage->constantColor; - } - break; - case CGEN_VERTEX: - if ( tr.identityLight == 1 ) - { - Com_Memcpy( tess.svars.colors, tess.vertexColors, tess.numVertexes * sizeof( tess.vertexColors[0] ) ); - } - else - { - for ( i = 0; i < tess.numVertexes; i++ ) - { - tess.svars.colors[i][0] = tess.vertexColors[i][0] * tr.identityLight; - tess.svars.colors[i][1] = tess.vertexColors[i][1] * tr.identityLight; - tess.svars.colors[i][2] = tess.vertexColors[i][2] * tr.identityLight; - tess.svars.colors[i][3] = tess.vertexColors[i][3]; - } - } - break; - case CGEN_ONE_MINUS_VERTEX: - if ( tr.identityLight == 1 ) - { - for ( i = 0; i < tess.numVertexes; i++ ) - { - tess.svars.colors[i][0] = 255 - tess.vertexColors[i][0]; - tess.svars.colors[i][1] = 255 - tess.vertexColors[i][1]; - tess.svars.colors[i][2] = 255 - tess.vertexColors[i][2]; - } - } - else - { - for ( i = 0; i < tess.numVertexes; i++ ) - { - tess.svars.colors[i][0] = ( 255 - tess.vertexColors[i][0] ) * tr.identityLight; - tess.svars.colors[i][1] = ( 255 - tess.vertexColors[i][1] ) * tr.identityLight; - tess.svars.colors[i][2] = ( 255 - tess.vertexColors[i][2] ) * tr.identityLight; - } - } - break; - case CGEN_FOG: - { - fog_t *fog; - - fog = tr.world->fogs + tess.fogNum; - - for ( i = 0; i < tess.numVertexes; i++ ) { - * ( int * )&tess.svars.colors[i] = fog->colorInt; - } - } - break; - case CGEN_WAVEFORM: - RB_CalcWaveColor( &pStage->rgbWave, ( unsigned char * ) tess.svars.colors ); - break; - case CGEN_ENTITY: - RB_CalcColorFromEntity( ( unsigned char * ) tess.svars.colors ); - break; - case CGEN_ONE_MINUS_ENTITY: - RB_CalcColorFromOneMinusEntity( ( unsigned char * ) tess.svars.colors ); - break; - case CGEN_LIGHTMAP0: - memset( colors, 0xff, tess.numVertexes * 4 ); - break; - case CGEN_LIGHTMAP1: - for ( i = 0; i < tess.numVertexes; i++ ) - { - *(unsigned *)&colors[i] = *(unsigned *)styleColors[pStage->lightmapStyle]; - } - break; - case CGEN_LIGHTMAP2: - for ( i = 0; i < tess.numVertexes; i++ ) - { - *(unsigned *)&colors[i] = *(unsigned *)styleColors[pStage->lightmapStyle]; - } - break; - case CGEN_LIGHTMAP3: - for ( i = 0; i < tess.numVertexes; i++ ) - { - *(unsigned *)&colors[i] = *(unsigned *)styleColors[pStage->lightmapStyle]; - } - break; - - } - - // - // alphaGen - // - switch ( pStage->alphaGen ) - { - case AGEN_SKIP: - break; - case AGEN_IDENTITY: - if ( forceRGBGen != CGEN_IDENTITY ) { - if ( ( forceRGBGen == CGEN_VERTEX && tr.identityLight != 1 ) || - forceRGBGen != CGEN_VERTEX ) { - for ( i = 0; i < tess.numVertexes; i++ ) { - tess.svars.colors[i][3] = 0xff; - } - } - } - break; - case AGEN_CONST: - if ( forceRGBGen != CGEN_CONST ) { - for ( i = 0; i < tess.numVertexes; i++ ) { - tess.svars.colors[i][3] = pStage->constantColor[3]; - } - } - break; - case AGEN_WAVEFORM: - RB_CalcWaveAlpha( &pStage->alphaWave, ( unsigned char * ) tess.svars.colors ); - break; - case AGEN_LIGHTING_SPECULAR: - RB_CalcSpecularAlpha( ( unsigned char * ) tess.svars.colors ); - break; - case AGEN_ENTITY: - RB_CalcAlphaFromEntity( ( unsigned char * ) tess.svars.colors ); - break; - case AGEN_ONE_MINUS_ENTITY: - RB_CalcAlphaFromOneMinusEntity( ( unsigned char * ) tess.svars.colors ); - break; - case AGEN_VERTEX: - if ( forceRGBGen != CGEN_VERTEX ) { - for ( i = 0; i < tess.numVertexes; i++ ) { - tess.svars.colors[i][3] = tess.vertexColors[i][3]; - } - } - break; - case AGEN_ONE_MINUS_VERTEX: - for ( i = 0; i < tess.numVertexes; i++ ) - { - tess.svars.colors[i][3] = 255 - tess.vertexColors[i][3]; - } - break; - case AGEN_PORTAL: - { - unsigned char alpha; - - for ( i = 0; i < tess.numVertexes; i++ ) - { - float len; - vec3_t v; - - VectorSubtract( tess.xyz[i], backEnd.viewParms.or.origin, v ); - len = VectorLength( v ); - - len /= tess.shader->portalRange; - - if ( len < 0 ) - { - alpha = 0; - } - else if ( len > 1 ) - { - alpha = 0xff; - } - else - { - alpha = len * 0xff; - } - - tess.svars.colors[i][3] = alpha; - } - } - break; - case AGEN_BLEND: - if ( forceRGBGen != CGEN_VERTEX ) - { - for ( i = 0; i < tess.numVertexes; i++ ) - { - //colors[i][3] = tess.vertexAlphas[i][pStage->index]; // only used on SOF2, needs implementing if you want it - } - } - break; - } -avoidGen: - // - // fog adjustment for colors to fade out as fog increases - // - if ( tess.fogNum ) - { - switch ( pStage->adjustColorsForFog ) - { - case ACFF_MODULATE_RGB: - RB_CalcModulateColorsByFog( ( unsigned char * ) tess.svars.colors ); - break; - case ACFF_MODULATE_ALPHA: - RB_CalcModulateAlphasByFog( ( unsigned char * ) tess.svars.colors ); - break; - case ACFF_MODULATE_RGBA: - RB_CalcModulateRGBAsByFog( ( unsigned char * ) tess.svars.colors ); - break; - case ACFF_NONE: - break; - } - } -} - -/* -=============== -ComputeTexCoords -=============== -*/ -static void ComputeTexCoords( shaderStage_t *pStage ) { - int i; - int b; - float *texcoords; - - for ( b = 0; b < NUM_TEXTURE_BUNDLES; b++ ) { - int tm; - - texcoords = (float *)tess.svars.texcoords[b]; - // - // generate the texture coordinates - // - switch ( pStage->bundle[b].tcGen ) - { - case TCGEN_IDENTITY: - Com_Memset( tess.svars.texcoords[b], 0, sizeof( float ) * 2 * tess.numVertexes ); - break; - case TCGEN_TEXTURE: - for ( i = 0 ; i < tess.numVertexes ; i++ ) { - tess.svars.texcoords[b][i][0] = tess.texCoords[i][0][0]; - tess.svars.texcoords[b][i][1] = tess.texCoords[i][0][1]; - } - break; - case TCGEN_LIGHTMAP: - for ( i = 0 ; i < tess.numVertexes ; i++,texcoords+=2 ) { - texcoords[0] = tess.texCoords[i][1][0]; - texcoords[1] = tess.texCoords[i][1][1]; - } - break; - case TCGEN_LIGHTMAP1: - for ( i = 0 ; i < tess.numVertexes ; i++,texcoords+=2 ) { - texcoords[0] = tess.texCoords[i][2][0]; - texcoords[1] = tess.texCoords[i][2][1]; - } - break; - case TCGEN_LIGHTMAP2: - for ( i = 0 ; i < tess.numVertexes ; i++,texcoords+=2 ) { - texcoords[0] = tess.texCoords[i][3][0]; - texcoords[1] = tess.texCoords[i][3][1]; - } - break; - case TCGEN_LIGHTMAP3: - for ( i = 0 ; i < tess.numVertexes ; i++,texcoords+=2 ) { - texcoords[0] = tess.texCoords[i][4][0]; - texcoords[1] = tess.texCoords[i][4][1]; - } - break; - case TCGEN_VECTOR: - for ( i = 0 ; i < tess.numVertexes ; i++ ) { - tess.svars.texcoords[b][i][0] = DotProduct( tess.xyz[i], pStage->bundle[b].tcGenVectors[0] ); - tess.svars.texcoords[b][i][1] = DotProduct( tess.xyz[i], pStage->bundle[b].tcGenVectors[1] ); - } - break; - case TCGEN_FOG: - RB_CalcFogTexCoords( ( float * ) tess.svars.texcoords[b] ); - break; - case TCGEN_ENVIRONMENT_MAPPED: - RB_CalcEnvironmentTexCoords( ( float * ) tess.svars.texcoords[b] ); - break; - case TCGEN_BAD: - return; - } - - // - // alter texture coordinates - // - for ( tm = 0; tm < pStage->bundle[b].numTexMods ; tm++ ) { - switch ( pStage->bundle[b].texMods[tm].type ) - { - case TMOD_NONE: - tm = TR_MAX_TEXMODS; // break out of for loop - break; - - case TMOD_TURBULENT: - RB_CalcTurbulentTexCoords( &pStage->bundle[b].texMods[tm].wave, - ( float * ) tess.svars.texcoords[b] ); - break; - - case TMOD_ENTITY_TRANSLATE: - RB_CalcScrollTexCoords( backEnd.currentEntity->e.shaderTexCoord, - ( float * ) tess.svars.texcoords[b] ); - break; - - case TMOD_SCROLL: - RB_CalcScrollTexCoords( pStage->bundle[b].texMods[tm].scroll, - ( float * ) tess.svars.texcoords[b] ); - break; - - case TMOD_SCALE: - RB_CalcScaleTexCoords( pStage->bundle[b].texMods[tm].scale, - ( float * ) tess.svars.texcoords[b] ); - break; - - case TMOD_STRETCH: - RB_CalcStretchTexCoords( &pStage->bundle[b].texMods[tm].wave, - ( float * ) tess.svars.texcoords[b] ); - break; - - case TMOD_TRANSFORM: - RB_CalcTransformTexCoords( &pStage->bundle[b].texMods[tm], - ( float * ) tess.svars.texcoords[b] ); - break; - - case TMOD_ROTATE: - RB_CalcRotateTexCoords( pStage->bundle[b].texMods[tm].rotateSpeed, - ( float * ) tess.svars.texcoords[b] ); - break; - - default: - ri.Error( ERR_DROP, "ERROR: unknown texmod '%d' in shader '%s'\n", pStage->bundle[b].texMods[tm].type, tess.shader->name ); - break; - } - } - } -} - -void ForceAlpha(unsigned char *dstColors, int TR_ForceEntAlpha) -{ - int i; - - dstColors += 3; - - for ( i = 0; i < tess.numVertexes; i++, dstColors += 4 ) - { - *dstColors = TR_ForceEntAlpha; - } -} - -/* -** RB_IterateStagesGeneric -*/ -static void RB_IterateStagesGeneric( shaderCommands_t *input ) -{ - int stage; - - for ( stage = 0; stage < MAX_SHADER_STAGES; stage++ ) - { - shaderStage_t *pStage = tess.xstages[stage]; - int forceRGBGen = 0; - int stateBits = 0; - - if ( !pStage ) - { - break; - } - - if ( stage && r_lightmap->integer && !( pStage->bundle[0].isLightmap || pStage->bundle[1].isLightmap || pStage->bundle[0].vertexLightmap ) ) - { - break; - } - - stateBits = pStage->stateBits; - - if ( backEnd.currentEntity ) - { - if ( backEnd.currentEntity->e.renderfx & RF_DISINTEGRATE1 ) - { - // we want to be able to rip a hole in the thing being disintegrated, and by doing the depth-testing it avoids some kinds of artefacts, but will probably introduce others? - stateBits = GLS_SRCBLEND_SRC_ALPHA | GLS_DSTBLEND_ONE_MINUS_SRC_ALPHA | GLS_DEPTHMASK_TRUE | GLS_DEPTHTEST_DISABLE; - } - - if ( backEnd.currentEntity->e.renderfx & RF_RGB_TINT ) - {//want to use RGBGen from ent - forceRGBGen = CGEN_ENTITY; - } - } - - if (pStage->ss.surfaceSpriteType) - { - // We check for surfacesprites AFTER drawing everything else - continue; - } - - ComputeColors( pStage, forceRGBGen ); - ComputeTexCoords( pStage ); - - if ( !setArraysOnce ) - { - qglEnableClientState( GL_COLOR_ARRAY ); - qglColorPointer( 4, GL_UNSIGNED_BYTE, 0, input->svars.colors ); - } - - // - // do multitexture - // - if ( pStage->bundle[1].image[0] != 0 ) - { - DrawMultitextured( input, stage ); - } - else - { - if ( !setArraysOnce ) - { - qglTexCoordPointer( 2, GL_FLOAT, 0, input->svars.texcoords[0] ); - } - - // - // set state - // - if ( pStage->bundle[0].vertexLightmap && ( r_vertexLight->integer && !r_uiFullScreen->integer ) && r_lightmap->integer ) - { - GL_Bind( tr.whiteImage ); - } - else - R_BindAnimatedImage( &pStage->bundle[0] ); - - if (backEnd.currentEntity && (backEnd.currentEntity->e.renderfx & RF_FORCE_ENT_ALPHA)) - { - ForceAlpha((unsigned char *) tess.svars.colors, backEnd.currentEntity->e.shaderRGBA[3]); - GL_State(GLS_SRCBLEND_SRC_ALPHA | GLS_DSTBLEND_ONE_MINUS_SRC_ALPHA); - } - else - { - GL_State( stateBits ); - } - - // - // draw - // - R_DrawElements( input->numIndexes, input->indexes ); - } - } -} - - -/* -** RB_StageIteratorGeneric -*/ -void RB_StageIteratorGeneric( void ) -{ - shaderCommands_t *input; - int stage; - - input = &tess; - - RB_DeformTessGeometry(); - - // - // log this call - // - if ( r_logFile->integer ) - { - // don't just call LogComment, or we will get - // a call to va() every frame! - GLimp_LogComment( va("--- RB_StageIteratorGeneric( %s ) ---\n", tess.shader->name) ); - } - - // - // set face culling appropriately - // - GL_Cull( input->shader->cullType ); - - // set polygon offset if necessary - if ( input->shader->polygonOffset ) - { - qglEnable( GL_POLYGON_OFFSET_FILL ); - qglPolygonOffset( r_offsetFactor->value, r_offsetUnits->value ); - } - - // - // if there is only a single pass then we can enable color - // and texture arrays before we compile, otherwise we need - // to avoid compiling those arrays since they will change - // during multipass rendering - // - if ( tess.numPasses > 1 || input->shader->multitextureEnv ) - { - setArraysOnce = qfalse; - qglDisableClientState (GL_COLOR_ARRAY); - qglDisableClientState (GL_TEXTURE_COORD_ARRAY); - } - else - { - setArraysOnce = qtrue; - - qglEnableClientState( GL_COLOR_ARRAY); - qglColorPointer( 4, GL_UNSIGNED_BYTE, 0, tess.svars.colors ); - - qglEnableClientState( GL_TEXTURE_COORD_ARRAY); - qglTexCoordPointer( 2, GL_FLOAT, 0, tess.svars.texcoords[0] ); - } - - // - // lock XYZ - // - qglVertexPointer (3, GL_FLOAT, 16, input->xyz); // padded for SIMD - if (qglLockArraysEXT) - { - qglLockArraysEXT(0, input->numVertexes); - GLimp_LogComment( "glLockArraysEXT\n" ); - } - - // - // enable color and texcoord arrays after the lock if necessary - // - if ( !setArraysOnce ) - { - qglEnableClientState( GL_TEXTURE_COORD_ARRAY ); - qglEnableClientState( GL_COLOR_ARRAY ); - } - - // - // call shader function - // - RB_IterateStagesGeneric( input ); - - // - // now do any dynamic lighting needed - // - if ( tess.dlightBits && tess.shader->sort <= SS_OPAQUE - && !(tess.shader->surfaceFlags & (SURF_NODLIGHT | SURF_SKY) ) ) { - ProjectDlightTexture(); - } - - // - // now do fog - // - if ( tess.fogNum && tess.shader->fogPass ) { - RB_FogPass(); - } - - // - // unlock arrays - // - if (qglUnlockArraysEXT) - { - qglUnlockArraysEXT(); - GLimp_LogComment( "glUnlockArraysEXT\n" ); - } - - // - // reset polygon offset - // - if ( input->shader->polygonOffset ) - { - qglDisable( GL_POLYGON_OFFSET_FILL ); - } - - // Now check for surfacesprites. - if (r_surfaceSprites->integer) - { - for ( stage = 1; stage < MAX_SHADER_STAGES; stage++ ) - { - if (!tess.xstages[stage]) - { - break; - } - if (tess.xstages[stage]->ss.surfaceSpriteType) - { // Draw the surfacesprite - RB_DrawSurfaceSprites(tess.xstages[stage], input); - } - } - } -} - - -/* -** RB_StageIteratorVertexLitTexture -*/ -void RB_StageIteratorVertexLitTexture( void ) -{ - shaderCommands_t *input; - shader_t *shader; - int stage; - - input = &tess; - - shader = input->shader; - - // - // compute colors - // - RB_CalcDiffuseColor( ( unsigned char * ) tess.svars.colors ); - - // - // log this call - // - if ( r_logFile->integer ) - { - // don't just call LogComment, or we will get - // a call to va() every frame! - GLimp_LogComment( va("--- RB_StageIteratorVertexLitTexturedUnfogged( %s ) ---\n", tess.shader->name) ); - } - - // - // set face culling appropriately - // - GL_Cull( input->shader->cullType ); - - // - // set arrays and lock - // - qglEnableClientState( GL_COLOR_ARRAY); - qglEnableClientState( GL_TEXTURE_COORD_ARRAY); - - qglColorPointer( 4, GL_UNSIGNED_BYTE, 0, tess.svars.colors ); - qglTexCoordPointer( 2, GL_FLOAT, 16, tess.texCoords[0][0] ); - qglVertexPointer (3, GL_FLOAT, 16, input->xyz); - - if ( qglLockArraysEXT ) - { - qglLockArraysEXT(0, input->numVertexes); - GLimp_LogComment( "glLockArraysEXT\n" ); - } - - // - // call special shade routine - // - R_BindAnimatedImage( &tess.xstages[0]->bundle[0] ); - GL_State( tess.xstages[0]->stateBits ); - R_DrawElements( input->numIndexes, input->indexes ); - - // - // now do any dynamic lighting needed - // - if ( tess.dlightBits && tess.shader->sort <= SS_OPAQUE ) { - ProjectDlightTexture(); - } - - // - // now do fog - // - if ( tess.fogNum && tess.shader->fogPass ) { - RB_FogPass(); - } - - // - // unlock arrays - // - if (qglUnlockArraysEXT) - { - qglUnlockArraysEXT(); - GLimp_LogComment( "glUnlockArraysEXT\n" ); - } - - // Now check for surfacesprites. - if (r_surfaceSprites->integer) - { - for ( stage = 1; stage < MAX_SHADER_STAGES; stage++ ) - { - if (!tess.xstages[stage]) - { - break; - } - if (tess.xstages[stage]->ss.surfaceSpriteType) - { // Draw the surfacesprite - RB_DrawSurfaceSprites(tess.xstages[stage], input); - } - } - } -} - -//define REPLACE_MODE - -void RB_StageIteratorLightmappedMultitexture( void ) { - shaderCommands_t *input; - int stage; - - input = &tess; - - // - // log this call - // - if ( r_logFile->integer ) { - // don't just call LogComment, or we will get - // a call to va() every frame! - GLimp_LogComment( va("--- RB_StageIteratorLightmappedMultitexture( %s ) ---\n", tess.shader->name) ); - } - - // - // set face culling appropriately - // - GL_Cull( input->shader->cullType ); - - // - // set color, pointers, and lock - // - GL_State( GLS_DEFAULT ); - qglVertexPointer( 3, GL_FLOAT, 16, input->xyz ); - -#ifdef REPLACE_MODE - qglDisableClientState( GL_COLOR_ARRAY ); - qglColor3f( 1, 1, 1 ); - qglShadeModel( GL_FLAT ); -#else - qglEnableClientState( GL_COLOR_ARRAY ); - qglColorPointer( 4, GL_UNSIGNED_BYTE, 0, tess.constantColor255 ); -#endif - - // - // select base stage - // - GL_SelectTexture( 0 ); - - qglEnableClientState( GL_TEXTURE_COORD_ARRAY ); - R_BindAnimatedImage( &tess.xstages[0]->bundle[0] ); - qglTexCoordPointer( 2, GL_FLOAT, 16, tess.texCoords[0][0] ); - - // - // configure second stage - // - GL_SelectTexture( 1 ); - qglEnable( GL_TEXTURE_2D ); - if ( r_lightmap->integer ) { - GL_TexEnv( GL_REPLACE ); - } else { - GL_TexEnv( GL_MODULATE ); - } - R_BindAnimatedImage( &tess.xstages[0]->bundle[1] ); - qglEnableClientState( GL_TEXTURE_COORD_ARRAY ); - qglTexCoordPointer( 2, GL_FLOAT, 16, tess.texCoords[0][1] ); - - // - // lock arrays - // - if ( qglLockArraysEXT ) { - qglLockArraysEXT(0, input->numVertexes); - GLimp_LogComment( "glLockArraysEXT\n" ); - } - - R_DrawElements( input->numIndexes, input->indexes ); - - // - // disable texturing on TEXTURE1, then select TEXTURE0 - // - qglDisable( GL_TEXTURE_2D ); - qglDisableClientState( GL_TEXTURE_COORD_ARRAY ); - - GL_SelectTexture( 0 ); -#ifdef REPLACE_MODE - GL_TexEnv( GL_MODULATE ); - qglShadeModel( GL_SMOOTH ); -#endif - - // - // now do any dynamic lighting needed - // - if ( tess.dlightBits && tess.shader->sort <= SS_OPAQUE ) { - ProjectDlightTexture(); - } - - // - // now do fog - // - if ( tess.fogNum && tess.shader->fogPass ) { - RB_FogPass(); - } - - // - // unlock arrays - // - if ( qglUnlockArraysEXT ) { - qglUnlockArraysEXT(); - GLimp_LogComment( "glUnlockArraysEXT\n" ); - } - - // Now check for surfacesprites. - if (r_surfaceSprites->integer) - { - for ( stage = 1; stage < MAX_SHADER_STAGES; stage++ ) - { - if (!tess.xstages[stage]) - { - break; - } - if (tess.xstages[stage]->ss.surfaceSpriteType) - { // Draw the surfacesprite - RB_DrawSurfaceSprites(tess.xstages[stage], input); - } - } - } -} - -/* -** RB_EndSurface -*/ -void RB_EndSurface( void ) { - shaderCommands_t *input; - - input = &tess; - - if (input->numIndexes == 0) { - return; - } - - if (input->indexes[SHADER_MAX_INDEXES-1] != 0) { - ri.Error (ERR_DROP, "RB_EndSurface() - SHADER_MAX_INDEXES hit"); - } - if (input->xyz[SHADER_MAX_VERTEXES-1][0] != 0) { - ri.Error (ERR_DROP, "RB_EndSurface() - SHADER_MAX_VERTEXES hit"); - } - - if ( tess.shader == tr.shadowShader ) { - RB_ShadowTessEnd(); - return; - } - - // for debugging of sort order issues, stop rendering after a given sort value - if ( r_debugSort->integer && r_debugSort->integer < tess.shader->sort ) { - return; - } - - // - // update performance counters - // - backEnd.pc.c_shaders++; - backEnd.pc.c_vertexes += tess.numVertexes; - backEnd.pc.c_indexes += tess.numIndexes; - backEnd.pc.c_totalIndexes += tess.numIndexes * tess.numPasses; - if (tess.fogNum && tess.shader->fogPass > FP_NONE && tess.shader->fogPass < FP_GLFOG)// && r_drawfog->value) - { - backEnd.pc.c_totalIndexes += tess.numIndexes; - } - - // - // call off to shader specific tess end function - // - tess.currentStageIteratorFunc(); - - // - // draw debugging stuff - // - if ( r_showtris->integer && com_developer->integer ) { - DrawTris (input); - } - if ( r_shownormals->integer && com_developer->integer ) { - DrawNormals (input); - } - // clear shader so we can tell we don't have any unclosed surfaces - tess.numIndexes = 0; - - GLimp_LogComment( "----------\n" ); -} - diff --git a/code/0_compiled_first/0_SH_Leak.cpp b/code/0_compiled_first/0_SH_Leak.cpp index ce1d4ab..adfd5a5 100644 --- a/code/0_compiled_first/0_SH_Leak.cpp +++ b/code/0_compiled_first/0_SH_Leak.cpp @@ -418,6 +418,7 @@ public: MemPoolSetSmallBlockAllocator(MyPool,MEM_SMALL_BLOCK_SH3); #if MEM_DEBUG dbgMemSetGuardSize(2); + EnableChecking(100000); #endif } diff --git a/code/0_compiled_first/vssver.scc b/code/0_compiled_first/vssver.scc new file mode 100644 index 0000000..f854df8 Binary files /dev/null and b/code/0_compiled_first/vssver.scc differ diff --git a/code/Debug/jk2gamex86.lib b/code/Debug/jk2gamex86.lib deleted file mode 100644 index a66216f..0000000 Binary files a/code/Debug/jk2gamex86.lib and /dev/null differ diff --git a/code/EaxMan.dll b/code/EaxMan.dll new file mode 100644 index 0000000..0a41c53 Binary files /dev/null and b/code/EaxMan.dll differ diff --git a/code/FFC10.dll b/code/FFC10.dll new file mode 100644 index 0000000..0536f23 Binary files /dev/null and b/code/FFC10.dll differ diff --git a/code/FFC10d.dll b/code/FFC10d.dll new file mode 100644 index 0000000..1f546c2 Binary files /dev/null and b/code/FFC10d.dll differ diff --git a/code/FinalBuild/jk2gamex86.lib b/code/FinalBuild/jk2gamex86.lib deleted file mode 100644 index f5190e2..0000000 Binary files a/code/FinalBuild/jk2gamex86.lib and /dev/null differ diff --git a/code/OpenAL32.dll b/code/OpenAL32.dll new file mode 100644 index 0000000..4a8dfde Binary files /dev/null and b/code/OpenAL32.dll differ diff --git a/code/Release/jk2gamex86.lib b/code/Release/jk2gamex86.lib deleted file mode 100644 index 57e7644..0000000 Binary files a/code/Release/jk2gamex86.lib and /dev/null differ diff --git a/code/SHDebug/HA312W32.DLL b/code/SHDebug/HA312W32.DLL new file mode 100644 index 0000000..2b1ea82 Binary files /dev/null and b/code/SHDebug/HA312W32.DLL differ diff --git a/code/SHDebug/SHW32.DLL b/code/SHDebug/SHW32.DLL new file mode 100644 index 0000000..42b2f67 Binary files /dev/null and b/code/SHDebug/SHW32.DLL differ diff --git a/code/SHDebug/jk2gamex86.lib b/code/SHDebug/jk2gamex86.lib deleted file mode 100644 index 3926c11..0000000 Binary files a/code/SHDebug/jk2gamex86.lib and /dev/null differ diff --git a/code/SHDebug/vssver.scc b/code/SHDebug/vssver.scc new file mode 100644 index 0000000..964c420 Binary files /dev/null and b/code/SHDebug/vssver.scc differ diff --git a/code/base/ext_data/NPCs.cfg b/code/base/ext_data/NPCs.cfg new file mode 100644 index 0000000..6ede82a --- /dev/null +++ b/code/base/ext_data/NPCs.cfg @@ -0,0 +1,2082 @@ +//Star Wars +/* +defaults and explanations of fields: + aggression 3 How likely they are to attack (from 1 (least) to 5 (most)) + aim 3 How good their aim is (from 1 (worst) to 5 (best)) + earshot 1024 How far in map units they can hear, in map units + evasion 3 How likely they are to take cover or defensive maneuvers (from 1 (least) to 5 (most)) + hfov 45 Horizontal field of view, in angles + intelligence 3 How smart they are, in general (from 1 (least) to 5 (most)) + move 3 How complex their moves are when evading or in combat (from 1 (least) to 5 (most)) + reactions 3 How quickly they react (from 1 (worst) to 5 (best)) + shootDistance 0 Overrides current weapon's max range + vfov 34 Vertical field of view, in angles + vigilance 0.1 How likely they are to notice something (from 0 (never) to 1 (always)) + visrange 2048 How far away they can see something, in map units + race none human, borg, parasite, klingon, malon, hirogen, stasis, species8472, dreadnought, harvester, reaver, avatar, vulcan + playerTeam none player, enemy, neutral + enemyTeam none player, enemy, neutral + + health 100 Health of entity (if not supplied by designer) + + moveType "runjump" Which movetype they can be (other choices are "static", "walk" and "flyswim" + yawSpeed 50 How quickly they can turn + walkSpeed 150 How fast they walk + runSpeed 300 How fast they run + acceleration 15 Acceleration (accel x 20fps = speed up per second, so accel of 15 means they can go from 0 to 300 in one second) + Accel of 0 means don't accel/decel - just start/stop (good if you're a slow mover anyway and/or robotic - like a Borg) + + scaleX 100 X (horiz) scale, 100 is normal 100% scale + scaleY 100 Y (horiz) scale, 100 is normal 100% scale + scaleZ 100 Z (vert) scale, 100 is normal 100% scale + scale 100 Sets all above 3 to what you specify + headModel "hazard" model directory/skin name + torsoModel "hazard" model directory/skin name + legsModel "hazard" model directory/skin name + headYawRangeLeft 70 How far left you can turn your head (angles) + headYawRangeRight 70 How far right you can turn your head (angles) + headPitchRangeUp 60 How far up you can tilt your head (angles) + headPitchRangeDown 60 How far down you can tilt your head (angles) + torsoYawRangeLeft 60 How far left you can turn your torso (angles) + torsoYawRangeRight 60 How far right you can turn your torso (angles) + torsoPitchRangeUp 30 How far up you can tilt your torso (angles) + torsoPitchRangeDown 70 How far down you can tilt your torso (angles) + + snd "munro" subdirectory of sound/player from which to get custom sounds (pain, death, jump, etc.) + dismemberProbHead 0 probability of head being dismembered ( from 0 (never) to 100 (always) ) + dismemberProbArms 0 probability of arms being dismembered ( from 0 (never) to 100 (always) ) + dismemberProbLegs 0 probability of legs being dismembered ( from 0 (never) to 100 (always) ) + dismemberProbWaist 0 probability of waist being dismembered ( from 0 (never) to 100 (always) ) +*/ + +//Characters +munro +{ + fullName "Katarn, Kyle" + playerModel kyle + saberColor blue + reactions 4 + aim 5 + move 3 + aggression 5 + evasion 5 + intelligence 5 + playerTeam player +// race human + class kyle + snd munro +} + +Kyle +{ + fullName "Katarn, Kyle" + playerModel kyle + saberColor blue + reactions 4 + aim 5 + move 3 + aggression 5 + evasion 5 + intelligence 5 + playerTeam player +// race human + class kyle + snd kyle + sndcombat kyle + sndjedi kyle + dismemberProbHead 50 + dismemberProbArms 50 + dismemberProbLegs 50 + dismemberProbWaist 50 +} + +Tavion +{ + playerModel tavion + rank commander + saberColor red + reactions 3 + aim 3 + move 5 + aggression 3 + evasion 4 + intelligence 5 + hfov 160 + vfov 160 + playerTeam enemy + enemyTeam player +// race human + class tavion + snd tavion + sndcombat tavion + sndjedi tavion + yawSpeed 120 + walkSpeed 55 + runSpeed 200 + health 200 + dismemberProbHead 50 + dismemberProbArms 50 + dismemberProbLegs 50 + dismemberProbWaist 50 +} + +Lando +{ + fullName "Calrissian, Lando" + playerModel lando + snd lando + reactions 3 + aim 1 + move 3 + aggression 3 + evasion 1 + intelligence 5 + rank crewman + playerTeam player + enemyTeam enemy +// race human + class lando + snd lando + sndcombat lando + walkSpeed 55 + runSpeed 200 + yawspeed 90 + dismemberProbHead 50 + dismemberProbArms 50 + dismemberProbLegs 50 + dismemberProbWaist 50 +} + +Reelo +{ + fullName "Baruk, Reelo" + playerModel reelo + snd reelo + reactions 3 + aim 1 + move 3 + aggression 3 + evasion 1 + intelligence 5 + rank crewman + playerTeam enemy + enemyTeam player +// race klingon + class reelo + snd reelo + sndcombat reelo + yawspeed 90 + walkSpeed 55 + runSpeed 200 + dismemberProbHead 50 + dismemberProbArms 50 + dismemberProbLegs 50 + dismemberProbWaist 50 +} + +Jan +{ + fullName "Ors, Jan" + playerModel jan + rank lt + reactions 3 + aim 5 + move 3 + aggression 3 + evasion 3 + intelligence 3 + playerTeam player + enemyTeam enemy + class jan + snd jan + sndcombat jan + yawSpeed 140 + walkSpeed 55 + runSpeed 200 +// race human + snd jan + dismemberProbHead 50 + dismemberProbArms 50 + dismemberProbLegs 50 + dismemberProbWaist 50 +} + +Galak +{ + fullName "Fyyar, Galak" + playerModel galak + snd galak + reactions 3 + aim 1 + move 3 + aggression 3 + evasion 1 + intelligence 5 + rank captain + playerTeam enemy + enemyTeam player +// race klingon + class imperial + yawspeed 90 + walkSpeed 55 + runSpeed 200 + dismemberProbHead 50 + dismemberProbArms 50 + dismemberProbLegs 50 + dismemberProbWaist 50 +} + +Galak_Mech +{ + fullName "Fyyar, Galak" + playerModel galak_mech + health 1000 + width 20 + height 88 + crouchheight 88 + snd galak_mech + reactions 3 + aim 5 + move 3 + aggression 3 + evasion 1 + intelligence 5 + rank crewman + playerTeam enemy + enemyTeam player +// race klingon + class galak_mech + snd galak + sndcombat galak + yawSpeed 50 + walkSpeed 45 + runSpeed 150 + dismemberProbHead 0 + dismemberProbArms 50 + dismemberProbLegs 0 + dismemberProbWaist 10 +} + + +Desann +{ + fullName "Desann" + playerModel desann + saberColor red + rank captain + reactions 3 + aim 3 + move 5 + aggression 3 + evasion 5 + intelligence 5 + hfov 160 + vfov 160 + scale 135 + height 78 + crouchheight 42 + width 18 + playerTeam enemy + enemyTeam player +// race human + class desann + yawSpeed 120 + walkSpeed 55 + runSpeed 200 + snd desann + sndcombat desann + sndjedi desann + health 500 + dismemberProbHead 50 + dismemberProbArms 50 + dismemberProbLegs 50 + dismemberProbWaist 50 +} + +Luke +{ + fullName "Skywalker, Luke" + playerModel luke + saberColor green + rank captain + reactions 3 + aim 3 + move 3 + aggression 3 + evasion 5 + intelligence 3 + playerTeam player + enemyTeam enemy + class luke + yawSpeed 140 + walkSpeed 55 + runSpeed 200 +// race human + snd luke + sndcombat luke + sndjedi luke + health 200 + dismemberProbHead 50 + dismemberProbArms 50 + dismemberProbLegs 50 + dismemberProbWaist 50 +} + +MonMothma +{ + fullName "Mon Mothma" + playerModel monmothma + snd monmothma + reactions 3 + aim 1 + move 3 + aggression 3 + evasion 1 + intelligence 5 + rank crewman + playerTeam player + enemyTeam enemy +// race human + class monmotha + walkSpeed 55 + runSpeed 200 + yawspeed 90 + dismemberProbHead 50 + dismemberProbArms 50 + dismemberProbLegs 50 + dismemberProbWaist 50 +} + +Bartender +{ + fullName "Bartender" + playerModel chiss + snd bartender + reactions 3 + aim 1 + move 3 + aggression 3 + evasion 1 + intelligence 5 + rank crewman + playerTeam neutral + enemyTeam neutral +// race human + class bartender + walkSpeed 55 + runSpeed 200 + yawspeed 90 + dismemberProbHead 50 + dismemberProbArms 50 + dismemberProbLegs 50 + dismemberProbWaist 50 +} + +MorganKatarn +{ + fullName "MorganKatarn" + playerModel morgan + snd morgan + reactions 3 + aim 1 + move 3 + aggression 3 + evasion 1 + intelligence 5 + rank crewman + playerTeam neutral + enemyTeam neutral +// race human + class morgan + walkSpeed 55 + runSpeed 200 + yawspeed 90 + dismemberProbHead 50 + dismemberProbArms 50 + dismemberProbLegs 50 + dismemberProbWaist 50 +} + +Prisoner +{ + playerModel prisoner + snd prisoner + reactions 3 + aim 1 + move 3 + aggression 3 + evasion 1 + intelligence 5 + rank crewman + playerTeam player + enemyTeam enemy + class prisoner + snd prisoner + sndcombat prisoner + walkSpeed 55 + runSpeed 200 + yawspeed 90 + dismemberProbHead 50 + dismemberProbArms 50 + dismemberProbLegs 50 + dismemberProbWaist 50 +} + +Prisoner2 +{ + playerModel prisoner + snd prisoner + surfOff "head head_face" + surfOn "head_off head_face_off" + reactions 3 + aim 1 + move 3 + aggression 3 + evasion 1 + intelligence 5 + rank crewman + playerTeam player + enemyTeam enemy + class prisoner + snd prisoner + sndcombat prisoner + walkSpeed 55 + runSpeed 200 + yawspeed 90 + dismemberProbHead 50 + dismemberProbArms 50 + dismemberProbLegs 50 + dismemberProbWaist 50 +} + +//NPC Humanoids +Jedi +{ + playerModel jedi + saberColor random + rank lt + reactions 3 + aim 3 + move 3 + aggression 3 + evasion 2 + intelligence 3 + playerTeam player + enemyTeam enemy + class jedi + yawSpeed 140 + walkSpeed 55 + runSpeed 200 + snd jedi1 + sndcombat jedi1 + sndjedi jedi1 + health 200 + dismemberProbHead 50 + dismemberProbArms 50 + dismemberProbLegs 50 + dismemberProbWaist 50 +} + +Jedi2 +{ + playerModel jedi + saberColor random + rank lt + customSkin j2 + surfOff "head head_face" + surfOn "head_off head_face_off" + reactions 3 + aim 3 + move 3 + aggression 3 + evasion 2 + intelligence 3 + playerTeam player + enemyTeam enemy + class jedi + yawSpeed 140 + walkSpeed 55 + runSpeed 200 + snd jedi2 + sndcombat jedi2 + sndjedi jedi2 + health 200 + dismemberProbHead 50 + dismemberProbArms 50 + dismemberProbLegs 50 + dismemberProbWaist 50 +} + +JediF +{ + playerModel jan + surfOff "torso_vest hips_chaps torso_computer head_goggles torso_comp hips_belt" + surfOn "torso_augment_off hips_augment_off hips_torso_off" + saberColor random + rank lt + reactions 3 + aim 3 + move 3 + aggression 3 + evasion 2 + intelligence 3 + playerTeam player + enemyTeam enemy + class jedi + yawSpeed 140 + walkSpeed 55 + runSpeed 200 + snd jan + sndcombat jan + sndjedi jan + health 200 + dismemberProbHead 50 + dismemberProbArms 50 + dismemberProbLegs 50 + dismemberProbWaist 50 +} + +JediTrainer +{ + playerModel jeditrainer + saberColor random + rank commander + reactions 5 + aim 5 + move 5 + aggression 5 + evasion 5 + intelligence 5 + playerTeam player + enemyTeam enemy + class jedi + yawSpeed 140 + walkSpeed 55 + runSpeed 200 + snd jeditrainer + sndcombat jeditrainer + sndjedi jeditrainer + health 400 + dismemberProbHead 50 + dismemberProbArms 50 + dismemberProbLegs 50 + dismemberProbWaist 50 +} + +Rebel +{ + playerModel rebel + reactions 3 + aim 1 + move 3 + aggression 3 + evasion 1 + intelligence 5 + rank crewman + playerTeam player + enemyTeam enemy +// race human + class rebel + snd rebel + sndcombat rebel + yawspeed 90 + walkSpeed 55 + runSpeed 200 + dismemberProbHead 50 + dismemberProbArms 50 + dismemberProbLegs 50 + dismemberProbWaist 50 +} + +BespinCop +{ + playerModel bespin_cop + health 40 + reactions 3 + aim 1 + move 3 + aggression 3 + evasion 1 + intelligence 5 + rank crewman + playerTeam player + enemyTeam enemy + walkSpeed 55 + runSpeed 200 + yawspeed 90 + dismemberProbHead 50 + dismemberProbArms 50 + dismemberProbLegs 50 + dismemberProbWaist 50 +// race bespincop + class bespin_cop + snd bespincop1 + sndcombat bespincop1 +} + +Ugnaught +{ + playerModel ugnaught + scale 75 + health 10 + snd ugnaught + reactions 3 + aim 1 + move 3 + aggression 3 + evasion 1 + intelligence 5 + rank crewman + playerTeam neutral + enemyTeam player +// race klingon + class ugnaught + yawspeed 90 + walkSpeed 55 + runSpeed 200 + dismemberProbHead 50 + dismemberProbArms 50 + dismemberProbLegs 50 + dismemberProbWaist 50 +} + +Gran +{ + playerModel gran + snd gran + sndcombat gran + reactions 3 + aim 1 + move 3 + aggression 3 + evasion 1 + intelligence 5 + rank crewman + health 30 + playerTeam enemy + enemyTeam player +// race klingon + class gran + snd gran1 + sndcombat gran1 + yawspeed 90 + walkSpeed 55 + runSpeed 200 + dismemberProbHead 50 + dismemberProbArms 50 + dismemberProbLegs 50 + dismemberProbWaist 50 +} + +GranShooter +{ + playerModel gran + surfOff "l_leg_kneeguard" + snd gran + sndcombat gran + reactions 3 + aim 5 + move 3 + aggression 3 + evasion 1 + intelligence 5 + health 40 + rank crewman + playerTeam enemy + enemyTeam player +// race klingon + class gran + snd gran2 + sndcombat gran2 + yawspeed 90 + walkSpeed 55 + runSpeed 200 + dismemberProbHead 50 + dismemberProbArms 50 + dismemberProbLegs 50 + dismemberProbWaist 50 +} + +GranBoxer +{ + playerModel gran + surfOff "l_leg_kneeguard r_leg_kneeguard" + snd gran + sndcombat gran + reactions 3 + aim 1 + move 3 + aggression 3 + evasion 1 + intelligence 5 + health 50 + rank crewman + playerTeam enemy + enemyTeam player +// race klingon + class gran + snd gran2 + sndcombat gran2 + yawspeed 90 + walkSpeed 55 + runSpeed 200 + dismemberProbHead 50 + dismemberProbArms 50 + dismemberProbLegs 50 + dismemberProbWaist 50 +} + +Rodian +{ + playerModel rodian + snd rodian + sndcombat rodian + reactions 3 + aim 1 + move 3 + aggression 3 + evasion 1 + intelligence 5 + health 25 + rank crewman + playerTeam enemy + enemyTeam player +// race klingon + class rodian + snd rodian1 + sndcombat rodian1 + yawspeed 90 + walkSpeed 55 + runSpeed 200 + visrange 8192 + dismemberProbHead 50 + dismemberProbArms 50 + dismemberProbLegs 50 + dismemberProbWaist 50 +} + +Rodian2 +{ + playerModel rodian + surfOff "hips_belt torso_vest" + surfOn "torso_augment_off" + snd rodian + sndcombat rodian + reactions 3 + aim 1 + move 3 + aggression 3 + evasion 1 + intelligence 5 + health 20 + rank crewman + playerTeam enemy + enemyTeam player +// race klingon + class rodian + snd rodian2 + sndcombat rodian2 + yawspeed 90 + walkSpeed 55 + runSpeed 200 + dismemberProbHead 50 + dismemberProbArms 50 + dismemberProbLegs 50 + dismemberProbWaist 50 +} + +Weequay +{ + playerModel weequay +//FIXME: randomize these somehow, also belt... + surfOff "hair_l_hairshoulder hair_r_hairshoulder head_l_hairback" + snd weequay + reactions 3 + aim 1 + move 3 + aggression 3 + evasion 1 + intelligence 5 + health 30 + rank crewman + playerTeam enemy + enemyTeam player +// race klingon + class weequay + snd weequay + sndcombat weequay + yawspeed 90 + walkSpeed 55 + runSpeed 200 + dismemberProbHead 50 + dismemberProbArms 50 + dismemberProbLegs 50 + dismemberProbWaist 50 +} + +Trandoshan +{ + playerModel trandoshan + snd trandoshan + reactions 3 + aim 1 + move 3 + aggression 3 + evasion 1 + intelligence 5 + health 40 + rank crewman + playerTeam enemy + enemyTeam player +// race klingon + class trandoshan + snd trandoshan1 + sndcombat trandoshan1 + yawspeed 90 + walkSpeed 55 + runSpeed 200 + dismemberProbHead 50 + dismemberProbArms 50 + dismemberProbLegs 50 + dismemberProbWaist 50 +} + +StormTrooper +{ + playerModel stormtrooper + surfOff torso_pauldron_off + surfOn "torso_armor_neck_augment torso_body_neck_augment" + health 30 + headPitchRangeUp 30 + headPitchRangeDown 30 + reactions 3 + aim 1 + move 3 + aggression 3 + evasion 1 + intelligence 5 + rank crewman + playerTeam enemy + enemyTeam player +// race klingon + class stormtrooper + height 64 + crouchheight 48 + walkSpeed 51 + runSpeed 200 + snd st1 + sndcombat st1 + sndextra st1 + yawspeed 70 + walkSpeed 55 + runSpeed 200 + dismemberProbHead 50 + dismemberProbArms 50 + dismemberProbLegs 50 + dismemberProbWaist 50 +} + +StormTrooper2 +{ + playerModel stormtrooper + surfOff torso_pauldron_off + surfOn "torso_armor_neck_augment torso_body_neck_augment" + health 30 + headPitchRangeUp 30 + headPitchRangeDown 30 + reactions 3 + aim 1 + move 3 + aggression 3 + evasion 1 + intelligence 5 + rank crewman + playerTeam enemy + enemyTeam player +// race klingon + class stormtrooper + height 64 + crouchheight 48 + walkSpeed 51 + runSpeed 200 + snd st2 + sndcombat st2 + sndextra st2 + yawspeed 70 + walkSpeed 55 + runSpeed 200 + dismemberProbHead 50 + dismemberProbArms 50 + dismemberProbLegs 50 + dismemberProbWaist 50 +} + +STOfficer +{ + playerModel stormtrooper + surfOn torso_pauldron_off + surfOff "torso_armor_neck_augment torso_body_neck_augment" + health 60 + headPitchRangeUp 30 + headPitchRangeDown 30 + reactions 5 + aim 5 + move 5 + aggression 5 + evasion 5 + intelligence 5 + rank ensign + scale 110 + playerTeam enemy + enemyTeam player +// race klingon + class stormtrooper + height 68 + crouchheight 52 + walkSpeed 51 + runSpeed 200 + snd stofficer1 + sndcombat stofficer1 + sndextra stofficer1 + yawspeed 90 + walkSpeed 55 + runSpeed 200 + dismemberProbHead 50 + dismemberProbArms 50 + dismemberProbLegs 50 + dismemberProbWaist 50 +} + +StormPilot +{ + playerModel stormpilot + health 30 + headPitchRangeUp 30 + headPitchRangeDown 30 + reactions 3 + aim 5 + move 3 + aggression 3 + evasion 1 + intelligence 5 + rank crewman + playerTeam enemy + enemyTeam player + class stormtrooper + height 64 + crouchheight 48 + walkSpeed 51 + runSpeed 200 + snd st3 + sndcombat st3 + sndextra st3 + yawspeed 80 + walkSpeed 55 + runSpeed 200 + dismemberProbHead 50 + dismemberProbArms 50 + dismemberProbLegs 50 + dismemberProbWaist 50 +} + +STOfficerAlt +{ + playerModel stormtrooper + surfOn torso_pauldron_off + surfOff "torso_armor_neck_augment torso_body_neck_augment" + health 60 + headPitchRangeUp 30 + headPitchRangeDown 30 + reactions 5 + aim 5 + move 5 + aggression 5 + evasion 5 + intelligence 5 + rank ensign + scale 110 + playerTeam enemy + enemyTeam player +// race klingon + class stormtrooper + height 68 + crouchheight 52 + walkSpeed 51 + runSpeed 200 + snd stofficer2 + sndcombat stofficer2 + sndextra stofficer2 + yawspeed 90 + walkSpeed 55 + runSpeed 200 + dismemberProbHead 50 + dismemberProbArms 50 + dismemberProbLegs 50 + dismemberProbWaist 50 +} + +STCommander +{ + playerModel stormtrooper + surfOn torso_pauldron_off + surfOff "torso_armor_neck_augment torso_body_neck_augment" + health 60 + headPitchRangeUp 30 + headPitchRangeDown 30 + reactions 5 + aim 5 + move 5 + aggression 5 + evasion 5 + intelligence 5 + rank ensign + scale 110 + playerTeam enemy + enemyTeam player +// race klingon + class stormtrooper + height 68 + crouchheight 52 + walkSpeed 51 + runSpeed 200 + snd stofficer2 + sndcombat stofficer2 + sndextra stofficer2 + yawspeed 110 + walkSpeed 55 + runSpeed 200 + dismemberProbHead 50 + dismemberProbArms 50 + dismemberProbLegs 50 + dismemberProbWaist 50 +} + +SwampTrooper +{ + playerModel swamptrooper + headPitchRangeUp 30 + headPitchRangeDown 30 + health 40 + reactions 3 + aim 3 + move 3 + aggression 3 + evasion 3 + intelligence 3 + scale 110 + playerTeam enemy + enemyTeam player +// race klingon + class swamptrooper + height 68 + crouchheight 52 + snd swamp1 + sndcombat swamp1 + sndextra swamp1 + yawspeed 100 + walkSpeed 55 + runSpeed 200 + dismemberProbHead 50 + dismemberProbArms 50 + dismemberProbLegs 50 + dismemberProbWaist 50 +} + +SwampTrooper2 +{ + playerModel swamptrooper + headPitchRangeUp 30 + headPitchRangeDown 30 + health 40 + reactions 3 + aim 3 + move 3 + aggression 3 + evasion 3 + intelligence 3 + scale 110 + playerTeam enemy + enemyTeam player +// race klingon + class swamptrooper + height 68 + crouchheight 52 + snd swamp2 + sndcombat swamp2 + sndextra swamp2 + yawspeed 100 + walkSpeed 55 + runSpeed 200 + dismemberProbHead 50 + dismemberProbArms 50 + dismemberProbLegs 50 + dismemberProbWaist 50 +} + +RocketTrooper +{ + playerModel stormtrooper + surfOn torso_pauldron_off + surfOff "torso_armor_neck_augment torso_body_neck_augment" + health 60 + headPitchRangeUp 30 + headPitchRangeDown 30 + reactions 5 + aim 5 + move 5 + aggression 5 + evasion 5 + intelligence 5 + rank ensign + scale 110 + playerTeam enemy + enemyTeam player +// race klingon + class stormtrooper + height 68 + crouchheight 52 + walkSpeed 51 + runSpeed 200 + snd st3 + sndcombat st3 + sndextra st3 + yawspeed 100 + walkSpeed 55 + runSpeed 200 + dismemberProbHead 50 + dismemberProbArms 50 + dismemberProbLegs 50 + dismemberProbWaist 50 +} + +Imperial +{ + playerModel imperial + surfOff "l_arm_pocket l_arm_key" + health 20 + reactions 2 + aim 2 + move 2 + aggression 2 + evasion 2 + intelligence 2 + rank lt + playerTeam enemy + enemyTeam player +// race klingon + class imperial + snd io2 + sndcombat io2 + sndextra io2 + yawspeed 110 + walkSpeed 55 + runSpeed 200 + dismemberProbHead 50 + dismemberProbArms 50 + dismemberProbLegs 50 + dismemberProbWaist 50 +} + +ImpOfficer +{ + playerModel imperial + surfOff "l_arm_pocket l_arm_key" + customSkin officer + health 40 + reactions 3 + aim 3 + move 3 + aggression 3 + evasion 3 + intelligence 3 + rank ltcomm + playerTeam enemy + enemyTeam player +// race klingon + class imperial + snd io1 + sndcombat io1 + sndextra io1 + yawspeed 110 + walkSpeed 55 + runSpeed 200 + dismemberProbHead 50 + dismemberProbArms 50 + dismemberProbLegs 50 + dismemberProbWaist 50 +} + +ImpCommander +{ + playerModel imperial + surfOff l_arm_key + customSkin commander + health 80 + reactions 4 + aim 4 + move 4 + aggression 4 + evasion 4 + intelligence 4 + rank commander + playerTeam enemy + enemyTeam player +// race klingon + class imperial +// snd io3 +// sndcombat io3 +// sndextra io3 + snd io1 + sndcombat io1 + sndextra io1 + yawspeed 110 + walkSpeed 55 + runSpeed 200 + dismemberProbHead 50 + dismemberProbArms 50 + dismemberProbLegs 50 + dismemberProbWaist 50 +} + +ImpWorker +{ + playerModel imperial_worker + headPitchRangeUp 30 + headPitchRangeDown 30 + health 30 + reactions 3 + aim 1 + move 3 + aggression 3 + evasion 1 + intelligence 5 + rank crewman + playerTeam enemy + enemyTeam player +// race imperial + class impworker + height 64 + crouchheight 48 + walkSpeed 51 + runSpeed 200 + snd worker1 + sndcombat worker1 + sndextra worker1 + yawspeed 90 + walkSpeed 55 + runSpeed 200 + dismemberProbHead 50 + dismemberProbArms 50 + dismemberProbLegs 50 + dismemberProbWaist 50 +} + +RebornAcrobat +{ + playerModel reborn + customSkin acrobat + saberColor red + rank crewman + reactions 3 + aim 3 + move 5 + aggression 3 + evasion 3 + intelligence 5 + hfov 160 + vfov 160 + scale 96 + playerTeam enemy + enemyTeam player +// race human + class reborn + snd reborn1 + sndcombat reborn1 + sndjedi reborn1 + yawSpeed 140 + walkSpeed 55 + runSpeed 200 + health 100 + dismemberProbHead 50 + dismemberProbArms 50 + dismemberProbLegs 50 + dismemberProbWaist 50 +} + +Reborn +{ + playerModel reborn + saberColor red + reactions 1 + aim 1 + move 1 + aggression 1 + evasion 1 + intelligence 1 + hfov 120 + vfov 120 + scale 94 + playerTeam enemy + enemyTeam player +// race human + class reborn + snd reborn1 + sndcombat reborn1 + sndjedi reborn1 + yawSpeed 60 + walkSpeed 45 + runSpeed 180 + health 40 + dismemberProbHead 50 + dismemberProbArms 50 + dismemberProbLegs 50 + dismemberProbWaist 50 +} + +RebornForceUser +{ + playerModel reborn + customSkin forceuser + saberColor red + rank ensign + reactions 3 + aim 3 + move 5 + aggression 2 + evasion 2 + intelligence 5 + hfov 160 + vfov 160 + scale 96 + playerTeam enemy + enemyTeam player +// race human + class reborn + snd reborn2 + sndcombat reborn2 + sndjedi reborn2 + yawSpeed 80 + walkSpeed 55 + runSpeed 200 + health 100 + dismemberProbHead 50 + dismemberProbArms 50 + dismemberProbLegs 50 + dismemberProbWaist 50 +} + +RebornFencer +{ + playerModel reborn + customSkin fencer + saberColor red + rank ltjg + reactions 3 + aim 3 + move 5 + aggression 4 + evasion 2 + intelligence 5 + hfov 160 + vfov 160 + scale 96 + playerTeam enemy + enemyTeam player +// race human + class reborn + snd reborn2 + sndcombat reborn2 + sndjedi reborn2 + yawSpeed 140 + walkSpeed 55 + runSpeed 200 + health 100 + dismemberProbHead 50 + dismemberProbArms 50 + dismemberProbLegs 50 + dismemberProbWaist 50 +} + +RebornBoss +{ + playerModel reborn + customSkin boss + saberColor red + rank lt + reactions 3 + aim 3 + move 5 + aggression 4 + evasion 3 + intelligence 5 + hfov 160 + vfov 160 + playerTeam enemy + enemyTeam player +// race human + class reborn + snd reborn3 + sndcombat reborn3 + sndjedi reborn3 + yawSpeed 140 + walkSpeed 55 + runSpeed 200 + health 150 + dismemberProbHead 50 + dismemberProbArms 50 + dismemberProbLegs 50 + dismemberProbWaist 50 +} + +ShadowTrooper +{ + playerModel shadowtrooper + saberColor red + rank ltcomm + reactions 5 + aim 5 + move 5 + aggression 5 + evasion 4 + intelligence 5 + hfov 160 + vfov 160 + playerTeam enemy + enemyTeam player +// race human + class shadowtrooper + snd shadow1 + sndcombat shadow1 + yawSpeed 140 + walkSpeed 55 + runSpeed 200 + health 100 + dismemberProbHead 50 + dismemberProbArms 50 + dismemberProbLegs 50 + dismemberProbWaist 50 +} + +ShadowTrooper2 +{ + playerModel shadowtrooper + saberColor red + rank lt + reactions 5 + aim 5 + move 5 + aggression 5 + evasion 4 + intelligence 5 + hfov 160 + vfov 160 + playerTeam enemy + enemyTeam player +// race human + class shadowtrooper + snd shadow2 + sndcombat shadow2 + yawSpeed 140 + walkSpeed 55 + runSpeed 200 + health 100 + dismemberProbHead 50 + dismemberProbArms 50 + dismemberProbLegs 50 + dismemberProbWaist 50 +} +//NPC Monsters +Howler +{ + playerModel howler + reactions 3 + aim 1 + move 3 + aggression 3 + evasion 1 + intelligence 5 + playerTeam enemy + enemyTeam player + class howler + yawSpeed 60 + runSpeed 150 + walkSpeed 50 + hFOV 120 + vfov 45 + snd howler + health 60 + dismemberProbHead 50 + dismemberProbArms 50 + dismemberProbLegs 50 + dismemberProbWaist 50 +} + +Minemonster +{ + playerModel minemonster + reactions 3 + aim 1 + move 3 + aggression 3 + evasion 1 + intelligence 5 + playerTeam enemy + enemyTeam player + class minemonster + snd mine + yawSpeed 60 + runSpeed 150 + walkSpeed 50 + hFOV 120 + vfov 45 + height 30 + width 9 + snd mine + health 40 + dismemberProbHead 50 + dismemberProbArms 50 + dismemberProbLegs 50 + dismemberProbWaist 50 +} + + +Glider +{ + playerModel glider + reactions 3 + aim 1 + move 3 + aggression 3 + evasion 1 + intelligence 5 + playerTeam neutral + enemyTeam neutral +// race harvester + class glider + yawSpeed 60 + runSpeed 150 + walkSpeed 50 + hFOV 120 + vfov 45 + snd glider + dismemberProbHead 50 + dismemberProbArms 50 + dismemberProbLegs 50 + dismemberProbWaist 50 +} + + +//NPC Droids +protocol +{ + playerModel protocol + reactions 3 + aim 1 + move 3 + aggression 3 + evasion 1 + intelligence 5 + playerTeam neutral + enemyTeam neutral +// race bot + class protocol + snd protocol + yawSpeed 60 + runSpeed 150 + walkSpeed 50 + height 48 + width 12 + hFOV 120 + vfov 45 + snd protocol + dismemberProbHead 50 + dismemberProbArms 50 + dismemberProbLegs 50 + dismemberProbWaist 50 +} + +protocol_imp +{ + playerModel protocol + surfOn head_off + surfOff head + customSkin imp + reactions 3 + aim 1 + move 3 + aggression 3 + evasion 1 + intelligence 5 + playerTeam neutral + enemyTeam neutral +// race bot + class protocol + snd protocol + yawSpeed 60 + runSpeed 150 + walkSpeed 50 + height 48 + width 12 + hFOV 120 + vfov 45 + snd protocol + dismemberProbHead 50 + dismemberProbArms 50 + dismemberProbLegs 50 + dismemberProbWaist 50 +} + +r2d2 +{ + playermodel r2d2 + headYawRangeLeft 180 + headYawRangeRight 180 + headPitchRangeUp 0 + headPitchRangeDown 0 + torsoYawRangeLeft 0 + torsoYawRangeRight 0 + torsoPitchRangeUp 10 + torsoPitchRangeDown 10 + reactions 3 + aim 1 + move 3 + aggression 3 + evasion 1 + intelligence 5 + playerTeam neutral + enemyTeam neutral +// race bot + class r2d2 + yawSpeed 120 + runSpeed 150 + walkSpeed 50 + height 40 + width 12 + hFOV 120 + vfov 45 + snd r2d2 + dismemberProbHead 50 + dismemberProbArms 50 + dismemberProbLegs 50 + dismemberProbWaist 50 +} + +r2d2_imp +{ + playermodel r2d2 + customSkin imp + headYawRangeLeft 180 + headYawRangeRight 180 + headPitchRangeUp 0 + headPitchRangeDown 0 + torsoYawRangeLeft 0 + torsoYawRangeRight 0 + torsoPitchRangeUp 10 + torsoPitchRangeDown 10 + reactions 3 + aim 1 + move 3 + aggression 3 + evasion 1 + intelligence 5 + playerTeam neutral + enemyTeam neutral +// race bot + class r2d2 + yawSpeed 120 + runSpeed 150 + walkSpeed 50 + height 40 + width 12 + hFOV 120 + vfov 45 + snd r2d2 + dismemberProbHead 50 + dismemberProbArms 50 + dismemberProbLegs 50 + dismemberProbWaist 50 +} + +r5d2 +{ + playerModel r5d2 + headYawRangeLeft 180 + headYawRangeRight 180 + headPitchRangeUp 0 + headPitchRangeDown 0 + torsoYawRangeLeft 0 + torsoYawRangeRight 0 + torsoPitchRangeUp 10 + torsoPitchRangeDown 10 + reactions 3 + aim 1 + move 3 + aggression 3 + evasion 1 + intelligence 5 + playerTeam neutral + enemyTeam neutral +// race bot + class r5d2 + yawSpeed 60 + runSpeed 150 + walkSpeed 50 + height 40 + width 12 + hFOV 120 + vfov 45 + snd r5d2 + dismemberProbHead 50 + dismemberProbArms 50 + dismemberProbLegs 50 + dismemberProbWaist 50 +} + +r5d2_imp +{ + playerModel r5d2 + customSkin imp + headYawRangeLeft 180 + headYawRangeRight 180 + headPitchRangeUp 0 + headPitchRangeDown 0 + torsoYawRangeLeft 0 + torsoYawRangeRight 0 + torsoPitchRangeUp 10 + torsoPitchRangeDown 10 + reactions 3 + aim 1 + move 3 + aggression 3 + evasion 1 + intelligence 5 + playerTeam neutral + enemyTeam neutral +// race bot + class r5d2 + yawSpeed 60 + runSpeed 150 + walkSpeed 50 + height 40 + width 12 + hFOV 120 + vfov 45 + snd r5d2 + dismemberProbHead 50 + dismemberProbArms 50 + dismemberProbLegs 50 + dismemberProbWaist 50 +} + +gonk +{ + playerModel gonk + reactions 3 + aim 1 + move 3 + aggression 3 + evasion 1 + intelligence 5 + playerTeam neutral + enemyTeam neutral +// race bot + class gonk + yawSpeed 60 + runSpeed 40 + walkSpeed 30 + height 32 + width 12 + hFOV 120 + vfov 45 + snd gonk + dismemberProbHead 50 + dismemberProbArms 50 + dismemberProbLegs 50 + dismemberProbWaist 50 +} + + +mouse +{ + headmodel none + torsomodel none + legsmodel mouse + reactions 3 + aim 1 + move 3 + aggression 3 + evasion 1 + intelligence 5 + playerTeam neutral + enemyTeam neutral +// race bot + class mouse + yawSpeed 120 + runSpeed 500 + walkSpeed 150 + height 16 + width 8 + hFOV 120 + vfov 45 + snd mouse + dismemberProbHead 50 + dismemberProbArms 50 + dismemberProbLegs 50 + dismemberProbWaist 50 +} + + +seeker +{ + headmodel none + torsomodel none + legsmodel remote + reactions 3 + aim 1 + move 3 + aggression 3 + evasion 3 + intelligence 5 + playerTeam player + enemyTeam enemy +// race bot + class seeker + yawSpeed 120 + runSpeed 500 + walkSpeed 150 + height 32 + width 8 + hFOV 160 + vfov 45 + snd remote + moveType "flyswim" + dismemberProbHead 0 + dismemberProbArms 0 + dismemberProbLegs 0 + dismemberProbWaist 0 +} + +remote +{ + headmodel none + torsomodel none + legsmodel remote + reactions 3 + aim 1 + move 3 + aggression 3 + evasion 3 + intelligence 5 + playerTeam enemy + enemyTeam player +// race bot + class remote + yawSpeed 120 + runSpeed 500 + walkSpeed 150 + height 32 + width 8 + hFOV 160 + vfov 45 + snd remote + moveType "flyswim" + dismemberProbHead 0 + dismemberProbArms 0 + dismemberProbLegs 0 + dismemberProbWaist 0 +} + +sentry +{ + playermodel sentry + health 100 + reactions 3 + aim 3 + move 3 + aggression 3 + evasion 1 + intelligence 5 + playerTeam enemy + enemyTeam player +// race bot + class sentry + health 150 + yawSpeed 120 + runSpeed 400 + walkSpeed 250 + height 48 + width 24 + hFOV 120 + vfov 160 + snd sentry + dismemberProbHead 0 + dismemberProbArms 0 + dismemberProbLegs 0 + dismemberProbWaist 0 +} + +interrogator +{ + playermodel interrogator + health 100 + reactions 3 + aim 1 + move 3 + aggression 3 + evasion 1 + intelligence 5 + playerTeam enemy + enemyTeam player +// race bot + class interrogator + yawSpeed 120 + runSpeed 150 + walkSpeed 50 + height 24 + width 12 + hFOV 120 + vfov 45 + snd interrogator + dismemberProbHead 0 + dismemberProbArms 0 + dismemberProbLegs 0 + dismemberProbWaist 0 +} + + +probe +{ + playerModel probe + health 200 + headYawRangeLeft 180 + headYawRangeRight 180 + headPitchRangeUp 0 + headPitchRangeDown 0 + torsoYawRangeLeft 0 + torsoYawRangeRight 0 + torsoPitchRangeUp 10 + torsoPitchRangeDown 10 + reactions 3 + aim 1 + move 3 + aggression 3 + evasion 1 + intelligence 5 + playerTeam enemy + enemyTeam player +// race bot + class probe + yawSpeed 60 + runSpeed 150 + walkSpeed 50 + height 110 + width 24 + hFOV 120 + vfov 45 + snd probe + moveType "flyswim" + dismemberProbHead 50 + dismemberProbArms 50 + dismemberProbLegs 50 + dismemberProbWaist 50 +} + +mark1 +{ + playerModel mark1 + reactions 3 + aim 1 + move 3 + aggression 3 + evasion 1 + intelligence 5 + height 120 + width 36 + playerTeam enemy + enemyTeam player + health 300 +// race bot + class mark1 + yawSpeed 60 + runSpeed 150 + walkSpeed 70 + hFOV 120 + vfov 45 + snd mark1 + dismemberProbHead 50 + dismemberProbArms 50 + dismemberProbLegs 50 + dismemberProbWaist 50 +} + +mark2 +{ + playerModel mark2 + reactions 3 + aim 1 + move 3 + aggression 3 + evasion 1 + intelligence 5 + playerTeam enemy + enemyTeam player +// race bot + class mark2 + yawSpeed 60 + runSpeed 150 + walkSpeed 75 + hFOV 120 + vfov 45 + snd mark2 + dismemberProbHead 50 + dismemberProbArms 50 + dismemberProbLegs 50 + dismemberProbWaist 50 +} + +atst +{ + playerModel atst +// headModel atst + //torsoModel atst + //legsModel atst + headYawRangeLeft 80 + headYawRangeRight 80 + headPitchRangeUp 30 + headPitchRangeDown 30 + torsoYawRangeLeft 0 + torsoYawRangeRight 0 + torsoPitchRangeUp 0 + torsoPitchRangeDown 0 + health 200 + reactions 3 + aim 1 + move 3 + aggression 3 + evasion 1 + intelligence 5 + playerTeam enemy + enemyTeam player + height 272 + width 80 +// race bot + class atst + yawSpeed 60 + runSpeed 150 + walkSpeed 150 + hFOV 120 + vfov 45 + snd atst + dismemberProbHead 50 + dismemberProbArms 50 + dismemberProbLegs 50 + dismemberProbWaist 50 +} + +test +{ + playerModel test + playerTeam player + enemyTeam neutral + class kyle +} diff --git a/code/base/ext_data/dms.dat b/code/base/ext_data/dms.dat new file mode 100644 index 0000000..039ab50 --- /dev/null +++ b/code/base/ext_data/dms.dat @@ -0,0 +1,1233 @@ +musicfiles +{ + kejimbase_explore + { + entry + { + marker0 0.000 + marker1 22.070 + marker2 53.723 + marker3 90.926 + } + exit + { + nextfile kejimbase_etr00 + time00 3.337 + time01 5.668 + time02 22.040 + time03 29.889 + time04 50.124 + time05 37.168 + time06 53.473 + time07 65.923 + time08 90.478 + time09 143.233 + time10 156.166 + time11 176.608 + time12 193.505 + } + exit + { + nextfile kejimbase_etr01 + time00 45.555 + time01 81.525 + time02 106.406 + time03 128.648 + time04 185.168 + time05 209.309 + } + } + kejimbase_action + { + entry + { + marker0 0.00 + marker1 42.585 + marker2 87.664 + } + exit + { + nextfile kejimbase_atr00 + nextmark marker0 + time00 69.347 + time01 72.142 + time02 80.444 + time03 87.608 + time04 90.185 + } + exit + { + nextfile kejimbase_atr01 + nextmark marker1 + time00 2.434 + time01 5.667 + time02 20.281 + } + exit + { + nextfile kejimbase_atr02 + nextmark marker2 + time00 62.894 + } + exit + { + nextfile kejimbase_atr03 + nextmark marker3 + time00 12.397 + time01 28.679 + time02 35.492 + time03 45.328 + } + } + ImpBaseB_Explore + { + entry + { + marker0 0 + marker1 37 + marker2 69.81 + marker3 119.97 + } + exit + { + nextfile ImpBaseB_Etr00 + time0 37 + time1 54.0 + time2 62.35 + time3 69.81 + time4 79.85 + time5 119.97 + time6 132.75 + time7 146.88 + } + exit + { + nextfile ImpBaseB_Etr01 + time0 13.67 + time1 26.96 + time2 89.42 + time3 96.92 + time4 107.77 + } + + } + ImpBaseB_Action + { + entry + { + marker0 0 + marker1 30.23 + marker2 45.45 + marker3 104.48 + } + exit + { + nextfile ImpBaseB_Atr00 + nextmark marker3 + time0 38.22 + time1 50.31 + time2 59.23 + time3 64.47 + time4 80.41 + time5 87.69 + time6 92.01 + time7 98.07 + time8 104.48 + } + exit + { + nextfile ImpBaseB_Atr01 + nextmark marker2 + time0 8.91 + time1 20.89 + } + exit + { + nextfile ImpBaseB_Atr02 + nextmark marker1 + time0 25.45 + time1 30.23 + } + exit + { + nextfile ImpBaseB_Atr03 + nextmark marker0 + time0 4.97 + time1 11.33 + time2 16.11 + time3 45.45 + time4 70.61 + time5 74.66 + } + } + ImpBaseC_explore + { + entry + { + marker0 0.000 + marker1 55.831 + marker2 11.160 + marker3 11.160 + + } + exit + { + nextfile ImpBaseC_etr00 + time00 42.904 + time01 71.172 + time02 127.721 + time03 150.290 + time04 171.618 + + } + exit + { + nextfile ImpBaseC_etr01 + time00 19.096 + time01 26.412 + time02 88.211 + time03 101.169 + + } + } + ImpBaseC_action + { + entry + { + marker0 0.00 + marker1 19.468 + marker2 33.480 + } + exit + { + nextfile ImpBaseC_atr00 + nextmark marker0 + time00 2.542 + time01 5.440 + time02 9.470 + time03 19.366 + } + exit + { + nextfile ImpBaseC_atr01 + nextmark marker1 + time00 25.544 + time01 29.140 + } + exit + { + nextfile ImpBaseC_atr02 + nextmark marker2 + time00 44.888 + } + exit + { + nextfile ImpBaseC_atr03 + nextmark marker3 + time00 34.272 + time01 65.224 + } + } + BespinA_Explore + { + entry + { + marker0 6.74 + marker1 17.51 + marker2 95.95 + marker3 149.87 + } + exit + { + nextfile BespinA_Etr00 + time00 42.01 + } + exit + { + nextfile BespinA_Etr01 + time00 165.65 + } + exit + { + nextfile BespinA_Etr02 + time00 17.51 + time01 29.50 + time02 54.80 + time03 70.21 + time04 90.25 + time05 106.40 + time06 120.53 + time07 149.87 + time08 178.36 + } + } + BespinA_Action + { + entry + { + marker0 0.00 + marker1 42.585 + marker2 87.664 + } + exit + { + nextfile BespinA_Atr00 + nextmark marker0 + time00 3.08 + time01 6.19 + time02 35.26 + } + exit + { + nextfile BespinA_Atr01 + nextmark marker1 + time00 8.98 + time01 14.76 + time02 20.65 + time03 44.34 + time04 47.28 + } + exit + { + nextfile BespinA_Atr02 + nextmark marker2 + time00 51.82 + time01 58.00 + } + exit + { + nextfile BespinA_Atr03 + nextmark marker3 + time00 28.90 + time01 64.78 + } + } + + besplat_explore + { + entry + { + marker0 46.78 + marker1 69.05 + marker2 85.85 + } + exit + { + nextfile besplat_etr00 + time0 6.89 + time1 21.26 + time3 55.52 + time4 69.75 + time5 85.87 + time6 98.12 + time7 119.44 + time8 131.95 + time9 157.58 + } + exit + { + nextfile besplat_etr01 + time0 34.15 + time1 141.84 + time2 174.72 + time3 183.05 + } + } + + besplat_action + { + entry + { + marker0 0 + marker1 16.56 + marker2 24.86 + marker3 62.37 + } + exit + { + nextfile besplat_atr00 + nextmark marker1 + time0 2.82 + time1 68.46 + } + exit + { + nextfile besplat_atr01 + nextmark marker2 + time0 41.23 + time1 54.20 + time2 59.31 + time3 76.51 + } + exit + { + nextfile besplat_atr02 + nextmark marker0 + time0 13.47 + time1 21.19 + time2 24.65 + time3 28.82 + time4 83.53 + } + } + + besplat_boss + { + } + + yavtrial_explore + { + entry + { + marker0 124.126 + marker1 102.326 + marker2 24.853 + marker3 0.00 + } + exit + { + nextfile yavtrial_etr00 + time00 3.095 + time01 23.931 + time02 24.937 + time03 46.905 + time04 61.268 + time05 79.042 + time06 101.750 + time07 118.136 + time08 147.951 + } + exit + { + nextfile yavtrial_etr01 + time00 161.783 + } + } + yavtrial_action + { + entry + { + marker0 0.00 + marker1 60.145 + marker2 85.922 + } + exit + { + nextfile yavtrial_atr00 + nextmark marker0 + time00 3.553 + time01 6.118 + time02 8.718 + time03 41.152 + time04 103.559 + } + exit + { + nextfile yavtrial_atr01 + nextmark marker1 + time00 9.307 + time01 12.310 + time02 16.719 + time03 20.045 + time04 26.229 + time05 35.160 + } + exit + { + nextfile yavtrial_atr02 + nextmark marker2 + time00 59.302 + time01 65.837 + time02 74.429 + } + exit + { + nextfile yavtrial_atr03 + nextmark marker3 + time00 38.325 + time01 49.857 + } + } + alienha_explore + { + entry + { + marker0 0 + marker1 65.84 + marker2 93.63 + } + exit + { + nextfile alienha_etr00 + time0 5.80 + time1 33.04 + time3 67.61 + } + exit + { + nextfile alienha_etr01 + time0 94.47 + time1 103.06 + time2 115.75 + time3 127.32 + time4 138.36 + time5 152.10 + time6 166.11 + time7 180.29 + } + } + alienha_action + { + entry + { + marker0 0 + marker1 40.96 + marker2 63.33 + } + exit + { + nextfile alienha_atr00 + nextmark marker2 + time0 3.35 + time1 6.85 + time3 15.70 + time4 22.61 + } + exit + { + nextfile alienha_atr01 + nextmark marker0 + time0 31.85 + time1 41.42 + time2 47.06 + } + exit + { + nextfile alienha_atr03 + nextmark marker1 + time0 53.01 + time1 58.57 + time2 62.87 + time3 72.03 + time4 89.64 + time5 96.94 + } + } + tunnels_explore + { + entry + { + marker0 0 + marker1 64.20 + marker2 96.47 + } + exit + { + nextfile tunnels_etr00 + time0 6.06 + time1 18.26 + time3 35.01 + time4 42.98 + time5 69.73 + time6 84.16 + } + exit + { + nextfile tunnels_etr01 + time0 94.81 + time1 111.25 + time2 121.77 + time3 134.68 + } + } + tunnels_action + { + entry + { + marker0 0 + marker1 22.39 + } + exit + { + nextfile tunnels_atr00 + nextmark marker0 + time0 0.29 + } + exit + { + nextfile tunnels_atr01 + nextmark marker2 + time0 15.62 + time1 22.94 + } + exit + { + nextfile tunnels_atr02 + nextmark marker2 + time0 29.14 + time1 35.63 + time2 45.33 + time3 51.78 + time4 58.67 + } + exit + { + nextfile tunnels_atr03 + nextmark marker1 + time0 64.81 + time1 68.53 + time2 72.28 + time3 75.89 + } + } + IMPBaseD_explore + { + entry + { + marker0 0.000 + marker1 66.790 + marker2 102.874 + marker3 150.554 + } + exit + { + nextfile IMPBaseD_etr00 + time00 7.997 + time01 16.678 + time02 44.664 + time03 70.836 + + } + exit + { + nextfile IMPBaseD_etr01 + time00 89.986 + time01 111.971 + time02 130.629 + time03 166.389 + time04 172.530 + } + } + IMPBaseD_action + { + entry + { + marker0 6.607 + marker1 60.118 + marker2 140.053 + } + exit + { + nextfile IMPBaseD_atr00 + nextmark marker0 + time00 6.457 + time01 13.265 + time02 18.757 + time03 25.194 + time04 152.772 + } + exit + { + nextfile IMPBaseD_atr01 + nextmark marker1 + time00 30.336 + time01 37.883 + time02 46.802 + time03 61.122 + } + exit + { + nextfile IMPBaseD_atr02 + nextmark marker2 + time00 78.257 + time01 85.312 + time02 92.170 + time03 140.866 + time04 149.597 + } + exit + { + nextfile IMPBaseD_atr03 + nextmark marker3 + time00 105.982 + time01 115.569 + time02 128.476 + } + } + swamp_explore + { + entry + { + marker0 0.000 + marker1 16.916 + marker2 80.714 + marker3 31.761 + + } + exit + { + nextfile swamp_etr00 + time00 11.185 + time01 20.989 + time02 51.408 + time03 63.196 + time04 71.293 + + } + exit + { + nextfile swamp_etr01 + time00 42.044 + time01 78.362 + time02 95.485 + time03 113.023 + + } + } + swamp_action + { + entry + { + marker0 0.00 + marker1 36.318 + marker2 45.982 + } + exit + { + nextfile swamp_atr00 + nextmark marker0 + time00 1.035 + } + exit + { + nextfile swamp_atr01 + nextmark marker1 + time00 6.835 + time01 11.323 + time02 18.592 + time03 36.230 + time04 59.793 + } + exit + { + nextfile swamp_atr02 + nextmark marker2 + time00 34.108 + time01 79.955 + time02 89.847 + time03 126.994 + + } + exit + { + nextfile swamp_atr03 + nextmark marker3 + time00 102.414 + time01 115.382 + time02 120.039 + } + } + yavtemp2_explore + { + entry + { + marker0 88.28 + marker1 48.10 + marker2 117.47 + marker3 0 + } + exit + { + nextfile yavtemp2_etr00 + time0 46.23 + time1 53.44 + time2 62.08 + time3 69.09 + time4 77.08 + time5 87.03 + time6 96.49 + } + exit + { + nextfile yavtemp2_etr01 + time0 15.24 + time1 31.79 + time2 42.78 + time3 114.18 + time4 134.25 + time5 144.89 + time6 160.03 + time7 168.03 + } + } + yavtemp2_action + { + entry + { + marker0 0 + marker1 17.35 + marker2 43.31 + marker3 60.39 + } + exit + { + nextfile yavtemp2_atr00 + nextmark marker0 + time0 0 + time1 8.78 + time2 13.47 + } + exit + { + nextfile yavtemp2_atr01 + nextmark marker1 + time0 23.89 + time1 28.62 + time2 41.11 + time3 46.73 + } + exit + { + nextfile yavtemp2_atr02 + nextmark marker2 + time0 48.95 + time1 60.59 + time2 69.13 + time3 97.63 + } + exit + { + nextfile yavtemp2_atr03 + nextmark marker3 + time0 91.11 + } + } + ImpBaseE_explore + { + entry + { + marker0 0.000 + marker1 13.805 + marker2 29.265 + marker3 137.915 + + } + exit + { + nextfile ImpBaseE_etr00 + time00 13.712 + time01 37.872 + time02 52.541 + time03 131.875 + time04 232.256 + + } + exit + { + nextfile ImpBaseE_etr01 + time00 120.057 + time01 157.080 + time02 176.388 + + } + } + ImpBaseE_action + { + entry + { + marker0 0.00 + marker1 18.336 + marker2 52.491 + } + exit + { + nextfile ImpBaseE_atr00 + nextmark marker0 + time00 22.012 + time01 32.861 + time02 73.853 + time03 77.808 + } + exit + { + nextfile ImpBaseE_atr01 + nextmark marker1 + time00 5.824 + time01 18.457 + time02 81.088 + time03 114.805 + } + exit + { + nextfile ImpBaseE_atr02 + nextmark marker2 + time00 1.923 + time01 26.892 + time02 30.703 + time03 59.294 + time04 65.331 + time05 88.803 + time06 91.876 + + } + exit + { + nextfile ImpBaseE_atr03 + nextmark marker3 + time00 11.958 + time01 43.027 + time02 48.014 + time04 96.757 + time05 107.858 + time06 130.437 + } + } + alienhb_explore + { + entry + { + marker0 127.71 + marker1 36.56 + marker2 89.94 + } + exit + { + nextfile alienhb_etr00 + time0 13.60 + time1 22.58 + time3 31.69 + time4 41.08 + time5 53.08 + time6 67.91 + time7 89.29 + time8 181.41 + } + exit + { + nextfile alienhb_etr01 + time0 109.08 + time1 123.18 + time2 134.76 + time3 149.54 + time4 160.53 + time5 174.10 + } + } + alienhb_action + { + entry + { + marker0 0 + marker1 6.85 + marker2 31.84 + marker3 66.77 + } + exit + { + nextfile alienhb_atr00 + nextmark marker0 + time0 5.29 + time1 21.54 + time3 26.21 + time4 120.30 + } + exit + { + nextfile alienhb_atr01 + nextmark marker1 + time0 10.35 + time1 17.03 + } + exit + { + nextfile alienhb_atr02 + nextmark marker2 + time0 60.27 + time1 70.21 + time2 80.36 + time3 93.55 + time4 100.47 + time5 111.75 + } + } + yavfinal_explore + { + entry + { + marker0 0.000 + marker1 18.664 + marker2 53.390 + marker3 97.161 + + } + exit + { + nextfile yavfinal_etr00 + time00 53.434 + time01 83.935 + + } + exit + { + nextfile yavfinal_etr01 + time00 9.852 + time01 94.171 + time02 104.106 + + } + } + yavfinal_action + { + entry + { + marker0 0.00 + marker1 43.094 + marker2 73.785 + } + exit + { + nextfile yavfinal_atr00 + nextmark marker0 + time00 53.502 + time01 61.386 + } + exit + { + nextfile yavfinal_atr01 + nextmark marker1 + time00 3.623 + time01 96.341 + } + exit + { + nextfile yavfinal_atr02 + nextmark marker2 + time00 9.019 + time01 11.707 + time02 15.535 + time03 29.107 + time04 35.847 + time05 75.327 + time06 101.992 + + } + exit + { + nextfile yavfinal_atr03 + nextmark marker3 + time00 21.257 + time01 25.167 + time02 43.800 + time03 106.249 + time04 113.638 + + } + } + yavfinal_boss + { + } + narshaada_explore + { + entry + { + marker0 123.18 + marker1 0 + marker2 43.30 + marker3 12.27 + } + exit + { + nextfile narshaada_etr00 + time0 55.86 + time1 70.17 + time2 78.63 + time3 88.61 + time4 106.57 + + } + exit + { + nextfile narshaada_etr01 + time0 13.75 + time1 31.29 + time2 43.84 + time4 123.91 + time5 134.92 + time6 149.29 + time7 168.16 + time8 184.19 + } + } + narshaada_action + { + entry + { + marker0 0 + marker1 15.65 + marker2 47.07 + } + exit + { + nextfile narshaada_atr00 + nextmark marker0 + time0 2.72 + time1 59.84 + time2 63.90 + time3 74.16 + time4 82.37 + } + exit + { + nextfile narshaada_atr01 + nextmark marker1 + time0 10.89 + time1 20.59 + time2 28.15 + time3 39.65 + time4 46.35 + } + exit + { + nextfile narshaada_atr02 + nextmark marker2 + time0 48.98 + time1 69.05 + } + exit + { + nextfile narshaada_atr03 + nextmark marker3 + time0 86.14 + time1 90.73 + time2 96.40 + time3 101.09 + } + } + +} +levelmusic +{ + kejim_post + { + explore ImpBaseB_Explore + action ImpBaseB_Action + } + kejim_base + { + explore kejimbase_explore + action kejimbase_action + } + artus_mine + { + explore tunnels_explore + action tunnels_action + } + artus_detention + { + explore ImpBaseC_explore + action ImpBaseC_action + useboss bespin_platform + } + artus_topside + { + explore ImpBaseD_explore + action ImpBaseD_action + } + ns_streets + { + explore narshaada_explore + action narshaada_action + } + ns_hideout + { + explore alienha_explore + action alienha_action + } + ns_starpad + { + explore alienhb_explore + action alienhb_action + } + bespin_undercity + { + uses artus_mine + } + bespin_streets + { + explore BespinA_Explore + action BespinA_Action + } + bespin_platform + { + explore besplat_explore + action besplat_action + boss besplat_boss + } + cairn_bay + { + explore ImpBaseE_explore + action ImpBaseE_action + } + cairn_dock1 + { + uses kejim_base + } + cairn_assembly + { + uses kejim_post + } + cairn_stockpile + { + uses artus_detention + } + cairn_reactor + { + uses artus_topside + } + cairn_dock2 + { + uses cairn_bay + } + doom_comm + { + uses kejim_base + } + doom_detention + { + uses kejim_post + } + doom_shields + { + uses artus_detention + } + yavin_swamp + { + explore swamp_explore + action swamp_action + } + yavin_canyon + { + uses ns_hideout + } + yavin_courtyard + { + explore yavtemp2_explore + action yavtemp2_action + } + yavin_final + { + explore yavfinal_explore + action yavfinal_action + boss yavfinal_boss + } + yavin_temple + { + explore placeholder + action placeholder + } + yavin_trial + { + explore yavtrial_explore + action yavtrial_action + } +} diff --git a/code/base/ext_data/items.dat b/code/base/ext_data/items.dat new file mode 100644 index 0000000..69d1ab1 --- /dev/null +++ b/code/base/ext_data/items.dat @@ -0,0 +1,742 @@ +// EXTERNAL ITEM DATA +// + +//Fields +//pickupsound STRING; DEFAULT = sound/weapons/w_pkup.wav +//itemname STRING; +//classname STRING; +//count INT; ammount of ammo or health given with item +//icon STRING; +//min VECTOR; item bounds min, DEFAULT = -16 -16 -2 +//max VECTOR; item bounds max, DEFAULT = 16 16 16 +//pickupname STRING; name to show in inventory +//tag ENUM; WP_, or AMMO_ +//type ENUM; IT_WEAPON, IT_AMMO, IT_ARMOR, IT_HEALTH +//worldmodel STRING; model to show on ground or in hand + +{ +itemname ITM_SABER_PICKUP + +classname weapon_saber +worldmodel models/weapons2/saber/saber_w.md3 +icon icons/w_icon_saber +// Amount of ammo given with weapon +count 50 +pickupname "Saber" +type IT_WEAPON +tag WP_SABER +min -16 -16 -8 +max 16 16 16 +} + + +{ +itemname ITM_BRYAR_PISTOL_PICKUP + +classname weapon_bryar_pistol +worldmodel models/weapons2/briar_pistol/briar_pistol_w.glm +icon icons/w_icon_rifle +// Amount of ammo given with weapon +count 50 +pickupname "Bryar Pistol" +type IT_WEAPON +tag WP_BRYAR_PISTOL +} + + +{ +itemname ITM_BLASTER_PICKUP + +classname weapon_blaster +worldmodel models/weapons2/blaster_r/blaster_w.glm +icon icons/w_icon_blaster +// Amount of ammo given with weapon +count 50 +pickupname "E11 Blaster Rifle" +type IT_WEAPON +tag WP_BLASTER +} + +{ +itemname ITM_DISRUPTOR_PICKUP + +classname weapon_disruptor +worldmodel models/weapons2/disruptor/disruptor_w.glm +icon icons/w_icon_disruptor +// Amount of ammo given with weapon +count 50 +pickupname "Tenloss Disruptor Rifle" +type IT_WEAPON +tag WP_DISRUPTOR +} + +{ +itemname ITM_BOWCASTER_PICKUP + +classname weapon_bowcaster +worldmodel models/weapons2/bowcaster/bowcaster_w.glm +icon icons/w_icon_bowcaster +// Amount of ammo given with weapon +count 50 +pickupname "Wookiee Bowcaster" +type IT_WEAPON +tag WP_BOWCASTER +} + +{ +itemname ITM_REPEATER_PICKUP + +classname weapon_repeater +worldmodel models/weapons2/heavy_repeater/heavy_repeater_w.glm +icon icons/w_icon_repeater +// Amount of ammo given with weapon +count 50 +pickupname "Imperial Heavy Repeater" +type IT_WEAPON +tag WP_REPEATER +} + +{ +itemname ITM_DEMP2_PICKUP + +classname weapon_demp2 +worldmodel models/weapons2/demp2/demp2_w.glm +icon icons/w_icon_demp2 +// Amount of ammo given with weapon +count 50 +pickupname "DEMP2" +type IT_WEAPON +tag WP_DEMP2 +} + + +{ +itemname ITM_FLECHETTE_PICKUP + +classname weapon_flechette +worldmodel models/weapons2/golan_arms/golan_arms_w.glm +icon icons/w_icon_flechette +// Amount of ammo given with weapon +count 50 +pickupname "Golan Arms Flechette" +type IT_WEAPON +tag WP_FLECHETTE +} + + +{ +itemname ITM_ROCKET_LAUNCHER_PICKUP + +classname weapon_rocket_launcher +worldmodel models/weapons2/merr_sonn/merr_sonn_w.glm +icon icons/w_icon_launcher +// Amount of ammo given with weapon +count 50 +pickupname "Merr-Sonn Missile System" +type IT_WEAPON +tag WP_ROCKET_LAUNCHER +} + + +{ +itemname ITM_THERMAL_DET_PICKUP + +classname weapon_thermal +worldmodel models/weapons2/thermal/thermal_w.glm +icon icons/w_icon_thermal +// Amount of ammo given with weapon +count 50 +pickupname "Thermal Detonator" +type IT_WEAPON +tag WP_THERMAL +} + +{ +itemname ITM_TRIP_MINE_PICKUP + +classname weapon_trip_mine +worldmodel models/weapons2/laser_trap/laser_trap_w.glm +icon icons/w_icon_trip_mine +// Amount of ammo given with weapon +count 50 +pickupname "Trip Mine" +type IT_WEAPON +tag WP_TRIP_MINE +} + +{ +itemname ITM_DET_PACK_PICKUP + +classname weapon_det_pack +worldmodel models/weapons2/detpack/det_pack_w.glm +icon icons/w_icon_det_pack +// Amount of ammo given with weapon +count 50 +pickupname "Det Pack" +type IT_WEAPON +tag WP_DET_PACK +} + +{ +itemname ITM_STUN_BATON_PICKUP + +classname weapon_stun_baton +worldmodel models/weapons2/stun_baton/stunbaton_w.glm +icon icons/w_icon_stun_baton +// Amount of ammo given with weapon +count 50 +pickupname "Stun Baton" +type IT_WEAPON +tag WP_STUN_BATON +} + + +{ +itemname ITM_BOT_LASER_PICKUP + +classname weapon_botwelder +worldmodel models/weapons2/noweap/noweap.md3 +icon icons/w_icon_phaser +// Amount of ammo given with weapon +count 400 +pickupname "Bot Laster" +type IT_WEAPON +tag WP_BOT_LASER +} + +{ +itemname ITM_MELEE + +classname weapon_melee +worldmodel models/weapons2/noweap/noweap.md3 +icon icons/w_icon_phaser +// Amount of ammo given with weapon +count 400 +pickupname "Melee" +type IT_WEAPON +tag WP_MELEE +min -16 -16 -2 +max 16 16 16 +} + +{ +itemname ITM_EMPLACED_GUN_PICKUP + +classname weapon_emplaced_gun +worldmodel models/weapons2/noweap/noweap.md3 +icon icons/w_icon_emp_gun +// Amount of ammo given with weapon +count 800 +pickupname "Emplaced Gun" +type IT_WEAPON +tag WP_EMPLACED_GUN +} + +{ +itemname ITM_TURRET_PICKUP + +classname weapon_turret +worldmodel models/weapons2/noweap/noweap.md3 +icon icons/w_icon_stasis +// Amount of ammo given with weapon +count 400 +pickupname "Turret Weapon" +type IT_WEAPON +tag WP_TURRET +} + +{ +itemname ITM_ATST_MAIN_PICKUP + +classname weapon_atst_main +worldmodel models/weapons2/noweap/noweap.md3 +icon icons/w_icon_atst +// Amount of ammo given with weapon +count 400 +pickupname "ATST Main" +type IT_WEAPON +tag WP_ATST_MAIN +} + +{ +itemname ITM_ATST_SIDE_PICKUP + +classname weapon_atst_side +worldmodel models/weapons2/noweap/noweap.md3 +icon icons/w_icon_atst +// Amount of ammo given with weapon +count 400 +pickupname "ATST Side" +type IT_WEAPON +tag WP_ATST_SIDE +} + +{ +itemname ITM_TIE_FIGHTER_PICKUP + +classname weapon_tie_fighter +worldmodel models/weapons2/noweap/noweap.md3 +icon icons/w_icon_tie +// Amount of ammo given with weapon +count 400 +pickupname "Tie Fighter" +type IT_WEAPON +tag WP_TIE_FIGHTER +} + +{ +itemname ITM_RAPID_FIRE_CONC_PICKUP + +classname weapon_rapid_concussion +worldmodel models/weapons2/noweap/noweap.md3 +icon icons/w_icon_rapid +// Amount of ammo given with weapon +count 400 +pickupname "Rapid Fire Concussion" +type IT_WEAPON +tag WP_RAPID_FIRE_CONC +} + +{ +itemname ITM_BLASTER_PISTOL_PICKUP + +classname weapon_blaster_pistol +worldmodel models/weapons2/imp_pistol/pistol_w.md3 +icon icons/w_icon_rifle +// Amount of ammo given with weapon +count 400 +pickupname "Blaster Pistol" +type IT_WEAPON +tag WP_BLASTER_PISTOL +} + +// +//Items +// + +// AMMO Items +//------------- +{ +itemname ITM_AMMO_FORCE_PICKUP + +classname ammo_force +worldmodel models/items/forcegem.md3 +icon icons/w_icon_blaster +count 100 +pickupname "Force??" +type IT_AMMO +tag AMMO_FORCE +max 8 8 16 +min -8 -8 -0 +} + +{ +itemname ITM_AMMO_BLASTER_PICKUP + +classname ammo_blaster +worldmodel models/items/energy_cell.md3 +icon icons/w_icon_blaster +count 100 +pickupname "Blaster Pack" +type IT_AMMO +tag AMMO_BLASTER +max 8 8 16 +min -8 -8 -0 +} + +{ +itemname ITM_AMMO_POWERCELL_PICKUP + +classname ammo_powercell +worldmodel models/items/power_cell.md3 +icon icons/w_icon_blaster +count 100 +pickupname "Power Cell" +type IT_AMMO +tag AMMO_POWERCELL +max 8 8 16 +min -8 -8 -0 +} + + +{ +itemname ITM_AMMO_METAL_BOLTS_PICKUP + +classname ammo_metallic_bolts +worldmodel models/items/metallic_bolts.md3 +icon icons/w_icon_blaster +count 100 +pickupname "Metallic Bolts" +type IT_AMMO +tag AMMO_METAL_BOLTS +max 8 8 16 +min -8 -8 -0 +} + +{ +itemname ITM_AMMO_ROCKETS_PICKUP + +classname ammo_rockets +worldmodel models/items/rockets.md3 +icon icons/w_icon_blaster +count 100 +pickupname "Rockets" +type IT_AMMO +tag AMMO_ROCKETS +max 8 8 16 +min -8 -8 -0 +} + +{ +itemname ITM_AMMO_EMPLACED_PICKUP + +classname ammo_emplaced +worldmodel models/mapobjects/scavenger/alien_ammo.md3 +icon icons/w_icon_blaster +count 100 +pickupname "Emplaced ammo" +type IT_AMMO +tag AMMO_EMPLACED +max 8 8 16 +min -8 -8 -0 +} + +{ +itemname ITM_AMMO_THERMAL_PICKUP + +classname ammo_thermal +worldmodel models/weapons2/thermal/thermal_pu.md3 +icon icons/w_icon_thermal +count 100 +pickupname "Thermal Detonator" +type IT_AMMO +tag AMMO_THERMAL +max 8 8 16 +min -8 -8 -0 +} + +{ +itemname ITM_AMMO_TRIPMINE_PICKUP + +classname ammo_tripmine +worldmodel models/weapons2/laser_trap/laser_trap_pu.md3 +icon icons/w_icon_lasertrap +count 100 +pickupname "Trip Mine" +type IT_AMMO +tag AMMO_TRIPMINE +max 8 8 16 +min -8 -8 -0 +} + +{ +itemname ITM_AMMO_DETPACK_PICKUP + +classname ammo_detpack +worldmodel models/weapons2/detpack/detpack_pu.md3 +icon icons/w_icon_detpack +count 100 +pickupname "Det Pack" +type IT_AMMO +tag AMMO_DETPACK +max 8 8 16 +min -8 -8 -0 +} + + + +{ +itemname ITM_BATTERY_PICKUP + +classname item_battery +worldmodel models/items/battery.md3 +icon icons/w_icon_blaster +count 1000 +pickupname "Batteries" +type IT_BATTERY +tag ITM_BATTERY_PICKUP +max 8 8 16 +min -8 -8 -0 +} + +{ +itemname ITM_SEEKER_PICKUP +classname item_seeker +worldmodel models/items/remote.md3 +icon gfx/hud/i_icon_seeker +count 120 +pickupname "Seeker Drone" +type IT_HOLDABLE +tag INV_SEEKER +max 8 8 16 +min -8 -8 -4 +} + +{ +itemname ITM_SHIELD_PICKUP +classname item_enviro +worldmodel models/items/shield.md3 +icon gfx/interface/inv_shield +count 100 +pickupname "Personal Shield" +type IT_HOLDABLE +tag ITM_SHIELD_PICKUP +max 8 8 16 +min -8 -8 -0 +} + +{ +itemname ITM_BACTA_PICKUP +classname item_bacta +worldmodel models/items/bacta.md3 +icon gfx/hud/i_icon_bacta +count 25 +pickupname "Medpac" +type IT_HOLDABLE +tag INV_BACTA_CANISTER +max 8 8 16 +min -8 -8 -0 +} + +{ +itemname ITM_DATAPAD_PICKUP +classname item_datapad +worldmodel models/items/datapad.md3 +icon icons/envirosuit +count 1 +pickupname "Datapad" +type IT_HOLDABLE +tag ITM_DATAPAD_PICKUP +max 8 8 16 +min -8 -8 -0 +} + +{ +itemname ITM_BINOCULARS_PICKUP +classname item_binoculars +worldmodel models/items/binoculars.md3 +icon gfx/hud/i_icon_zoom +count 1 +pickupname "Binoculars" +type IT_HOLDABLE +tag INV_ELECTROBINOCULARS +max 8 8 16 +min -8 -8 -0 +} + +{ +itemname ITM_SENTRY_GUN_PICKUP +classname item_sentry_gun +worldmodel models/items/psgun.glm +icon gfx/hud/i_icon_sentrygun +count 120 +pickupname "Sentry Gun" +type IT_HOLDABLE +tag INV_SENTRY +max 8 8 16 +min -8 -8 -0 +} + +{ +itemname ITM_LA_GOGGLES_PICKUP +classname item_la_goggles +worldmodel models/items/binoculars.md3 +icon gfx/hud/i_icon_goggles +count 30 +pickupname "LA Goggles" +type IT_HOLDABLE +tag INV_LIGHTAMP_GOGGLES +max 8 8 16 +min -8 -8 -0 +} + +{ +itemname ITM_MEDPAK_PICKUP +classname item_medpak_instant +worldmodel models/items/medpac.md3 +icon icons/w_icon_blaster +count 20 +pickupname "Medpack" +type IT_HEALTH +tag ITM_MEDPAK_PICKUP +max 8 8 16 +min -8 -8 -4 +} + +{ +itemname ITM_SHIELD_SM_PICKUP +classname item_shield_sm_instant +worldmodel models/items/psd_sm.md3 +icon icons/w_icon_blaster +count 25 +pickupname "Shield Small" +type IT_ARMOR +tag ITM_SHIELD_SM_PICKUP +max 8 8 16 +min -8 -8 -4 +} + +{ +itemname ITM_SHIELD_LRG_PICKUP +classname item_shield_lrg_instant +worldmodel models/items/psd.md3 +icon icons/w_icon_blaster +count 50 +pickupname "Shield Large" +type IT_ARMOR +tag ITM_SHIELD_LRG_PICKUP +max 8 8 16 +min -8 -8 -4 +} + + +{ +itemname ITM_GOODIE_KEY_PICKUP +classname item_goodie_key +worldmodel models/items/key.md3 +icon gfx/hud/i_icon_goodie_key +pickupname "Key" +type IT_HOLDABLE +tag INV_GOODIE_KEY +max 8 8 16 +min -8 -8 -0 +} + + +{ +itemname ITM_SECURITY_KEY_PICKUP +classname item_security_key +worldmodel models/items/key.md3 +icon gfx/hud/i_icon_security_key +pickupname "Security Key" +type IT_HOLDABLE +tag INV_SECURITY_KEY +max 8 8 16 +min -8 -8 -0 +} + +{ +itemname ITM_FORCE_HEAL_PICKUP + +classname holocron_force_heal +worldmodel models/map_objects/force_holocrons/heal.md3 +icon icons/f_icon_heal +count 1 +pickupname "Force Heal" +type IT_HOLOCRON +tag FP_HEAL +max 8 8 16 +min -8 -8 -0 +} + +{ +itemname ITM_FORCE_LEVITATION_PICKUP + +classname holocron_force_levitation +worldmodel models/map_objects/force_holocrons/jump.md3 +icon icons/f_icon_levitation +count 1 +pickupname "Force Levitation" +type IT_HOLOCRON +tag FP_LEVITATION +max 8 8 16 +min -8 -8 -0 +} + +{ +itemname ITM_FORCE_SPEED_PICKUP + +classname holocron_force_speed +worldmodel models/map_objects/force_holocrons/speed.md3 +icon icons/f_icon_speed +count 1 +pickupname "Force SPEED" +type IT_HOLOCRON +tag FP_SPEED +max 8 8 16 +min -8 -8 -0 +} + +{ +itemname ITM_FORCE_PUSH_PICKUP + +classname holocron_force_push +worldmodel models/map_objects/force_holocrons/push.md3 +icon icons/f_icon_push +count 1 +pickupname "Force Push" +type IT_HOLOCRON +tag FP_PUSH +max 8 8 16 +min -8 -8 -0 +} + +{ +itemname ITM_FORCE_PULL_PICKUP + +classname holocron_force_pull +worldmodel models/map_objects/force_holocrons/pull.md3 +icon icons/f_icon_pull +count 1 +pickupname "Force Pull" +type IT_HOLOCRON +tag FP_PULL +max 8 8 16 +min -8 -8 -0 +} + +{ +itemname ITM_FORCE_TELEPATHY_PICKUP + +classname holocron_force_telepathy +worldmodel models/map_objects/force_holocrons/telepathy.md3 +icon icons/f_icon_telepathy +count 1 +pickupname "Force Telepathy" +type IT_HOLOCRON +tag FP_TELEPATHY +max 8 8 16 +min -8 -8 -0 +} + +{ +itemname ITM_FORCE_GRIP_PICKUP + +classname holocron_force_grip +worldmodel models/map_objects/force_holocrons/grip.md3 +icon icons/f_icon_grip +count 1 +pickupname "Force Grip" +type IT_HOLOCRON +tag FP_GRIP +max 8 8 16 +min -8 -8 -0 +} + +{ +itemname ITM_FORCE_LIGHTNING_PICKUP + +classname holocron_force_lightning +worldmodel models/map_objects/force_holocrons/lightning.md3 +icon icons/f_icon_lightning +count 1 +pickupname "Force Lightning" +type IT_HOLOCRON +tag FP_LIGHTNING +max 8 8 16 +min -8 -8 -0 +} + +{ +itemname ITM_FORCE_SABERTHROW_PICKUP + +classname holocron_force_saberthrow +worldmodel models/map_objects/force_holocrons/saberthrow.md3 +icon icons/f_icon_saberthrow +count 1 +pickupname "Force SaberThrow" +type IT_HOLOCRON +tag FP_SABERTHROW +max 8 8 16 +min -8 -8 -0 +} diff --git a/code/base/ext_data/vssver.scc b/code/base/ext_data/vssver.scc new file mode 100644 index 0000000..1e832b6 Binary files /dev/null and b/code/base/ext_data/vssver.scc differ diff --git a/code/base/ext_data/weapons.dat b/code/base/ext_data/weapons.dat new file mode 100644 index 0000000..fdd0f3c --- /dev/null +++ b/code/base/ext_data/weapons.dat @@ -0,0 +1,609 @@ +// EXTERNAL WEAPON & AMMO DATA +// +// NOTE!!!!!!!!! Weapontype must start the block of weapon data. +// NOTE!!!!!!!!! Ammo must start the block of ammo data. +// +// Weapontype - weapon data is associated with which weapon (must be first) +// WP_NONE +// WP_PHASER +// WP_COMPRESSION_RIFLE +// WP_IMOD +// WP_SCAVENGER_RIFLE +// WP_STASIS +// WP_GRENADE_LAUNCHER, +// WP_TETRION_DISRUPTOR, +// WP_DREADNOUGHT, +// WP_QUANTUM_BURST, +// WP_BORG_WEAPON +// WP_BORG_TASER +// WP_BORG_ASSIMILATOR +// WP_BORG_DRILL +// WP_TRICORDER +// +// Weaponclass - weapon name +// Weaponmodel - weapon model used in game +// weaponicon - interface image +// Ammotype - type of power weapon needs to fire +// 0 - No power +// 1 - Star Fleet power +// 2 - Alien Crystal power +// 3 - Phaser power +// Ammolowcount - amount when "Low ammo" warning appears on screen +// Flashcolor - color generate by weapon flash (R,G,B) +// Firingsound - sound file used when firing +// altfiringsound - sound file used when alt-firing +// flashsound - sound file used by flash +// altflashsound - sound file used by an alt-fire flash +// stopsound - sound file used when a firing sound stops +// Firetime - amount of time between firings +// altfireTime - for alt fire +// Range - range of weapon +// energyPerShot - amount of energy used per shot +// altenergypershot- for alt fire +// barrelcount - number of barrels the model has (weaponname_b?.md3) +// missileModel - missile .md3 +// altmissileModel - alternate missile .md3 +// missileSound - played while flying +// altmissileSound - alternate missile launch sound +// missileLight - intensity of lightsource for missile - if 0.0 then none (float) +// altmissileLight - alternate missile light +// missileLightColor - color in three float style R, G, B (0.0 to 1.0) - NOTE - if you have a light, you MUST HAVE THESE +// altmissileLightColor - alternate color in three float style R, G, B (0.0 to 1.0) +// missileHitSound - played on impact +// altmissileHitSound - for alt fire +// missileFuncName - missile fly function +// altmissileFuncName - for alt fire +// +// FUNCTION NAMES +// borgfunc +// scavengerfunc +// altscavengerfunc +// stasisfunc +// grenadefunc +// altgrenadefunc +// tetrionfunc +// dreadnoughtfunc +// quantumfunc +// quantumaltfunc +// botrocketfunc +// forgeprojfunc +// forgeprojfunc2 +// forgepsychfunc +// parasiteacidfunc +// stasisattackfunc +// loaderlaserfunc +// botprojfunc + +// +// For AMMO Types +// ammoicon - STRING +// ammomax - INT + + +// WP_NULL +{ +WEAPONTYPE WP_NONE +} + +// WP_STUN_BATON +{ +weapontype WP_STUN_BATON +weaponclass weapon_stun_baton +weaponmodel models/weapons2/stun_baton/baton.md3 +weaponIcon gfx/hud/w_icon_stunbaton +firingsound sound/weapons/baton/fire.wav +barrelcount 3 +ammotype 1 +ammolowcount 5 +energypershot 0 +firetime 400 +range 8192 +altenergypershot 0 +altfiretime 800 +altrange 8192 +} + +// WP_SABER +{ +weapontype WP_SABER +weaponclass weapon_saber +weaponmodel models/weapons2/saber/saber_w.md3 +weaponIcon gfx/hud/w_icon_lightsaber +firingsound sound/weapons/saber/saberhum1.wav +ammotype 1 +ammolowcount 5 +energypershot 1 +firetime 100 +range 8192 +altenergypershot 3 +altfiretime 100 +altrange 8192 +missilemodel models/weapons2/saber/saber_w.md3 +} + + +// WP_BRYAR_PISTOL +{ +weapontype WP_BRYAR_PISTOL +weaponclass weapon_bryar_pistol +weaponmodel models/weapons2/briar_pistol/briar_pistol.md3 +weaponIcon gfx/hud/w_icon_briar +missileFuncName bryar_func +altmissileFuncName bryar_alt_func +ammotype 2 +ammolowcount 15 +energypershot 1 +firetime 400 +range 8192 +altenergypershot 1 +altfiretime 400 +altrange 8192 +muzzleEffect bryar/muzzle_flash +altmuzzleEffect bryar/altmuzzle_flash +altchargesound sound/weapons/bryar/altcharge.wav +selectSound sound/weapons/bryar/select.wav +} + +// WP_BLASTER +{ +weapontype WP_BLASTER +weaponclass weapon_blaster +weaponmodel models/weapons2/blaster_r/blaster.md3 +weaponIcon gfx/hud/w_icon_blaster +ammotype 2 +ammolowcount 5 +energypershot 1 +firetime 350 +range 8192 +altenergypershot 2 +altfiretime 150 +altrange 8192 +missileFuncName blaster_func +altmissileFuncName blaster_alt_func +muzzleEffect blaster/muzzle_flash +altmuzzleEffect blaster/altmuzzle_flash +selectSound sound/weapons/blaster/select.wav +} + +// WP_DISRUPTOR +{ +weapontype WP_DISRUPTOR +weaponclass weapon_disruptor +weaponmodel models/weapons2/disruptor/disruptor.md3 +weaponIcon gfx/hud/w_icon_disruptor +ammotype 3 +ammolowcount 5 +energypershot 4 +barrelcount 1 +firetime 600 +range 8192 +altenergypershot 1 +altfiretime 1300 +altrange 8192 +muzzleEffect disruptor/muzzle_flash +altmuzzleEffect disruptor/altmuzzle_flash +selectSound sound/weapons/disruptor/select.wav +altchargesound sound/weapons/disruptor/altCharge.wav +} + +// WP_BOWCASTER +{ +weapontype WP_BOWCASTER +weaponclass weapon_bowcaster +weaponmodel models/weapons2/bowcaster/bowcaster.md3 +weaponIcon gfx/hud/w_icon_bowcaster +altchargesound sound/weapons/bowcaster/altcharge.wav +ammotype 3 +ammolowcount 5 +energypershot 5 +firetime 750 +range 8192 +altenergypershot 5 +altfiretime 400 +altrange 8192 +missileFuncName bowcaster_func +altmissileFuncName bowcaster_func +muzzleEffect bowcaster/muzzle_flash +altmuzzleEffect bowcaster/altmuzzle_flash +selectSound sound/weapons/bowcaster/select.wav +chargesound sound/weapons/bowcaster/altcharge.wav +} + +// WP_REPEATER +{ +weapontype WP_REPEATER +weaponclass weapon_repeater +weaponmodel models/weapons2/heavy_repeater/heavy_repeater.md3 +weaponIcon gfx/hud/w_icon_repeater +ammotype 4 +ammolowcount 5 +energypershot 1 +firetime 50 +range 8192 +altenergypershot 8 +altfiretime 800 +altrange 8192 +barrelcount 1 +missileFuncName repeater_func +altmissileFuncName repeater_alt_func +muzzleEffect repeater/muzzle_flash +altmuzzleEffect repeater/altmuzzle_flash +selectSound sound/weapons/repeater/select.wav +} + +// WP_DEMP2 +{ +weapontype WP_DEMP2 +weaponclass weapon_demp2 +weaponmodel models/weapons2/demp2/demp2.md3 +weaponIcon gfx/hud/w_icon_demp2 +ammotype 3 +ammolowcount 5 +energypershot 8 +firetime 450 +range 8192 +altenergypershot 10 +altfiretime 1200 +altrange 8192 +missileFuncName demp2_func +muzzleEffect demp2/muzzle_flash +altmissileFuncName demp2_alt_func +altmuzzleEffect demp2/altmuzzle_flash +selectSound sound/weapons/demp2/select.wav +altchargesound sound/weapons/demp2/altCharge.wav +} + + +// WP_FLECHETTE +{ +weapontype WP_FLECHETTE +weaponclass weapon_flechette +weaponmodel models/weapons2/golan_arms/golan_arms.md3 +barrelcount 1 +ammotype 4 +ammolowcount 5 +firetime 550 +energypershot 8 +range 8192 +weaponIcon gfx/hud/w_icon_flechette +altenergypershot 8 +altfiretime 400 +altrange 8192 +missileFuncName flechette_func +altmissileFuncName flechette_alt_func +muzzleEffect flechette/muzzle_flash +altmuzzleEffect flechette/altmuzzle_flash +altmissileModel models/weapons2/golan_arms/projectile.md3 +selectSound sound/weapons/flechette/select.wav +} + +// WP_ROCKET_LAUNCHER +{ +weapontype WP_ROCKET_LAUNCHER +weaponclass weapon_rocket_launcher +weaponmodel models/weapons2/merr_sonn/merr_sonn.md3 +ammotype 5 +ammolowcount 5 +firetime 600 +energypershot 1 +range 8192 +weaponIcon gfx/hud/w_icon_merrsonn +barrelcount 1 +altenergypershot 1 +altfiretime 1000 +altrange 8192 +missileLight 125 +missileLightColor 1.0 1.0 0.5 +altmissileLight 125 +altmissileLightColor 1.0 1.0 0.5 +missileFuncName rocket_func +altmissileFuncName rocket_alt_func +muzzleEffect rocket/muzzle_flash2 +altmuzzleEffect rocket/altmuzzle_flash +missileModel models/weapons2/merr_sonn/projectile.md3 +altmissileModel models/weapons2/merr_sonn/projectile.md3 +missilesound sound/weapons/rocket/missileloop.wav +altmissilesound sound/weapons/rocket/missileloop.wav +selectSound sound/weapons/rocket/select.wav +} + + +// WP_THERMAL +{ +weapontype WP_THERMAL +weaponclass weapon_thermal +weaponmodel models/weapons2/thermal/thermal.md3 +weaponIcon gfx/hud/w_icon_thermal +ammotype 7 +ammolowcount 5 +energypershot 1 +firetime 800 +range 8192 +altenergypershot 1 +altfiretime 400 +altrange 8192 +missileModel models/weapons2/thermal/thermal_proj.md3 +altmissileModel models/weapons2/thermal/thermal_proj.md3 +barrelcount 0 +chargesound sound/weapons/thermal/charge.wav +altchargesound sound/weapons/thermal/charge.wav +selectSound sound/weapons/thermal/select.wav +muzzleEffect thermal/muzzle_flash +} + +// WP_TRIP_MINE +{ +weapontype WP_TRIP_MINE +weaponclass weapon_trip_mine +weaponmodel models/weapons2/laser_trap/laser_trap.md3 +weaponIcon gfx/hud/w_icon_tripmine +ammotype 8 +ammolowcount 5 +energypershot 1 +firetime 800 +range 8192 +altenergypershot 1 +altfiretime 400 +altrange 8192 +missileModel models/weapons2/laser_trap/laser_trap_w.glm +altmissileModel models/weapons2/laser_trap/laser_trap_w.glm +selectSound sound/weapons/tripmine/select.wav +muzzleEffect tripmine/muzzle_flash + +} + +// WP_DET_PACK +{ +weapontype WP_DET_PACK +weaponclass weapon_det_pack +weaponmodel models/weapons2/detpack/det_pack.md3 +weaponIcon gfx/hud/w_icon_detpack +ammotype 9 +ammolowcount 5 +energypershot 1 +firetime 800 +range 8192 +altenergypershot 0 +altfiretime 400 +altrange 8192 +missileModel models/weapons2/detpack/det_pack_proj.glm +selectSound sound/weapons/detpack/select.wav +muzzleEffect detpack/muzzle_flash +} + +// WP_EMPLACED_GUN +{ +weapontype WP_EMPLACED_GUN +weaponclass weapon_emplaced_gun +weaponmodel models/weapons2/noweap/noweap.md3 + +altenergypershot 1 +altrange 8192 +missileFuncName emplaced_func +altmissileFuncName emplaced_func +ammotype 6 +ammolowcount 15 +energypershot 1 +firetime 150 +altfiretime 150 +range 8192 +muzzleEffect emplaced/muzzle_flash +} + +// WP_BOT_LASER +{ +weapontype WP_BOT_LASER +weaponclass weapon_bryar_pistol +weaponmodel models/weapons2/noweap/noweap.md3 + +//flashsound sound/weapons/probe/fire.wav +//altflashsound sound/weapons/probe/alt_fire.wav +altenergypershot 0 +altrange 8192 +missileFuncName bryar_func +ammotype 1 +ammolowcount 15 +energypershot 2 +firetime 1600 +range 8192 +} + +// WP_MELEE +{ +weapontype WP_MELEE +weaponclass weapon_melee +weaponmodel models/weapons2/noweap/noweap.md3 + +ammotype 3 +ammolowcount 5 +energypershot 0 +firetime 1000 +range 1024 +} + +// WP_ATST_MAIN +{ +weapontype WP_ATST_MAIN +weaponclass weapon_atst_main +weaponmodel models/weapons2/noweap/noweap.md3 +weaponIcon gfx/hud/w_icon_atst +//flashsound sound/weapons/atst/ATSTfire1.wav +//altflashsound sound/weapons/atst/ATSTfire2.wav +altenergypershot 1 +altrange 8192 +missileFuncName atstmain_func +altmissileFuncName atstmain_func +ammotype 6 +ammolowcount 15 +energypershot 1 +firetime 400 +altfiretime 400 +range 8192 +muzzleEffect emplaced/muzzle_flash +} + +// WP_ATST_SIDE +{ +weapontype WP_ATST_SIDE +weaponclass weapon_atst_side +weaponmodel models/weapons2/noweap/noweap.md3 +weaponIcon gfx/hud/w_icon_atstside +//flashsound sound/weapons/atst/ATSTfire3.wav +//altflashsound sound/weapons/atst/ATSTfire4.wav +altenergypershot 1 +altrange 8192 + +altmissileModel models/weapons2/merr_sonn/projectile.md3 + +missileFuncName atst_side_main_func +altmissileFuncName atst_side_alt_func +muzzleEffect emplaced/muzzle_flash +altmuzzleEffect emplaced/muzzle_flash + +ammotype 6 +ammolowcount 15 +energypershot 1 +firetime 400 +altfiretime 1000 +range 8192 +} + +// WP_TIE_FIGHTER +{ +weapontype WP_TIE_FIGHTER +weaponclass weapon_tie_fighter +weaponmodel models/weapons2/noweap/noweap.md3 +weaponIcon icons/w_icon_tie +//flashsound sound/weapons/tie_fighter/tie_fire.wav +//altflashsound sound/weapons/tie_fighter/tie_fire2.wav +altenergypershot 1 +altrange 8192 +missileFuncName emplaced_func +altmissileFuncName emplaced_func +ammotype 6 +ammolowcount 15 +energypershot 1 +firetime 400 +altfiretime 400 +range 8192 +muzzleEffect emplaced/muzzle_flash +} + +// WP_RAPID_FIRE_CONC +{ +weapontype WP_RAPID_FIRE_CONC +weaponclass weapon_radid_concussion +weaponmodel models/weapons2/noweap/noweap.md3 +weaponIcon icons/w_icon_tie +//flashsound sound/weapons/rapid_conc/fire.wav +//altflashsound sound/weapons/rapid_conc/alt_fire.wav +altenergypershot 1 +altrange 8192 +missileFuncName emplaced_func +altmissileFuncName repeater_alt_func +ammotype 6 +ammolowcount 15 +energypershot 1 +firetime 400 +altfiretime 1000 +range 8192 +muzzleEffect emplaced/muzzle_flash +} + +// WP_BLASTER_PISTOL +{ +weapontype WP_BLASTER_PISTOL +weaponclass weapon_blaster_pistol +weaponmodel models/weapons2/imp_pistol/pistol.md3 + +//flashsound sound/weapons/npc_blaster/fire.wav +//altflashsound sound/weapons/npc_blaster/alt_fire.wav +missileFuncName bryar_func +altmissileFuncName bryar_alt_func +ammotype 2 +ammolowcount 15 +energypershot 2 +firetime 400 +range 8192 +altenergypershot 2 +altfiretime 400 +altrange 8192 +muzzleEffect bryar/muzzle_flash +} + +// WP_TURRET +{ +weapontype WP_TURRET +weaponclass weapon_turret +weaponmodel models/weapons2/noweap/noweap.md3 +weaponIcon icons/w_icon_turret +altenergypershot 1 +altrange 8192 +missileFuncName turret_func +ammotype 6 +ammolowcount 15 +energypershot 1 +firetime 400 +altfiretime 400 +range 8192 +muzzleEffect turret/muzzle_flash +} + +// AMMO_NONE +{ +AMMOTYPE AMMO_NONE +} + +// AMMO_FORCE +{ +AMMO AMMO_FORCE +AMMOMAX 100 +} + +// AMMO_BLASTER +{ +AMMO AMMO_BLASTER +AMMOMAX 300 +} + +// AMMO_POWERCELL +{ +AMMO AMMO_POWERCELL +AMMOMAX 300 +} + +// AMMO_METAL_BOLTS +{ +AMMO AMMO_METAL_BOLTS +AMMOMAX 400 +} + +// AMMO_ROCKETS +{ +AMMO AMMO_ROCKETS +AMMOMAX 10 +} + +// AMMO_EMPLACED +{ +AMMO AMMO_EMPLACED +AMMOMAX 800 +} + +// AMMO_THERMAL +{ +AMMO AMMO_THERMAL +AMMOMAX 10 +} + +// AMMO_TRIPMINE +{ +AMMO AMMO_TRIPMINE +AMMOMAX 5 +} + +// AMMO_DETPACK +{ +AMMO AMMO_DETPACK +AMMOMAX 5 +} \ No newline at end of file diff --git a/code/cgame/FxPrimitives.cpp b/code/cgame/FxPrimitives.cpp index 0ffaabc..fde9fbd 100644 --- a/code/cgame/FxPrimitives.cpp +++ b/code/cgame/FxPrimitives.cpp @@ -251,7 +251,7 @@ bool CParticle::UpdateOrigin() else { // if this returns solid, we need to do a trace - solid = !!(CG_PointContents( new_origin, ENTITYNUM_WORLD ) & MASK_SHOT); + solid = !!(CG_PointContents( new_origin, ENTITYNUM_WORLD ) & ( MASK_SHOT | CONTENTS_WATER )); } if ( solid ) @@ -261,11 +261,11 @@ bool CParticle::UpdateOrigin() if ( mFlags & FX_USE_BBOX ) { - theFxHelper.Trace( &trace, mOrigin1, mMin, mMax, new_origin, -1, MASK_SHOT ); + theFxHelper.Trace( &trace, mOrigin1, mMin, mMax, new_origin, -1, ( MASK_SHOT | CONTENTS_WATER ) ); } else { - theFxHelper.Trace( &trace, mOrigin1, NULL, NULL, new_origin, -1, MASK_SHOT ); + theFxHelper.Trace( &trace, mOrigin1, NULL, NULL, new_origin, -1, ( MASK_SHOT | CONTENTS_WATER ) ); } // Hit something @@ -1204,7 +1204,7 @@ void CEmitter::Draw() } // Hit something - if ( trace.fraction < 1.0f )//|| trace.startsolid || trace.allsolid ) + if ( trace.fraction < 1.0f || trace.startsolid || trace.allsolid ) { return; } diff --git a/code/cgame/FxScheduler.cpp b/code/cgame/FxScheduler.cpp index 1c9f538..b45b9be 100644 --- a/code/cgame/FxScheduler.cpp +++ b/code/cgame/FxScheduler.cpp @@ -1387,7 +1387,7 @@ void CFxScheduler::CreateEffect( CPrimitiveTemplate *fx, vec3_t origin, vec3_t a } } - theFxHelper.Trace( &tr, org, NULL, NULL, temp, -1, MASK_SHOT ); + theFxHelper.Trace( &tr, org, NULL, NULL, temp, -1, CONTENTS_SOLID | CONTENTS_SHOTCLIP );//MASK_SHOT ); if ( tr.startsolid || tr.allsolid ) { diff --git a/code/cgame/animtable.h b/code/cgame/animtable.h index ed2463c..9c85ec7 100644 --- a/code/cgame/animtable.h +++ b/code/cgame/animtable.h @@ -639,7 +639,7 @@ stringID_table_t animTable [MAX_ANIMATIONS+1] = ENUM2STRING(BOTH_STAND1TOSTAND5), //# Transition from stand1 to stand5 ENUM2STRING(BOTH_STAND5TOSTAND1), //# Transition from stand5 to stand1 ENUM2STRING(BOTH_STAND5TOSTAND8), //# Transition from stand5 to stand8 - ENUM2STRING(BOTH_STAND8TOSTAND5), //# Transition from stand5 to stand8 + ENUM2STRING(BOTH_STAND8TOSTAND5), //# Transition from stand8 to stand5 ENUM2STRING(BOTH_CONSOLE1START), //# typing at a console ENUM2STRING(BOTH_CONSOLE1), //# typing at a console @@ -750,10 +750,14 @@ stringID_table_t animTable [MAX_ANIMATIONS+1] = ENUM2STRING(BOTH_SILENCEGESTURE1), //# Luke silencing Kyle with a raised hand (cin #37) ENUM2STRING(BOTH_REACHFORSABER1), //# Luke holding hand out for Kyle's saber (cin #37) ENUM2STRING(BOTH_PUNCHER1), //# Jan punching Kyle in the shoulder (cin #37) + ENUM2STRING(BOTH_CONSTRAINER1HOLD), //# Static pose of starting Tavion constraining Jan (cin #9) + ENUM2STRING(BOTH_CONSTRAINEE1HOLD), //# Static pose of starting Jan being constrained by Tavion (cin #9) ENUM2STRING(BOTH_CONSTRAINER1STAND), //# Tavion constraining Jan in a stand pose (cin #9) ENUM2STRING(BOTH_CONSTRAINEE1STAND), //# Jan being constrained in a stand pose (cin #9) - ENUM2STRING(BOTH_CONSTRAINER1WALK), //# Tavion constraining Jan in a walking loop (cin #9) - ENUM2STRING(BOTH_CONSTRAINEE1WALK), //# Jan being constrained in a walking loop (cin #9) + ENUM2STRING(BOTH_CONSTRAINER1WALK), //# Tavion shoving jan forward (cin #9) + ENUM2STRING(BOTH_CONSTRAINEE1WALK), //# Jan being shoved forward by Tavion (cin #9) + ENUM2STRING(BOTH_CONSTRAINER1LOOP), //# Tavion walking with Jan in a loop (cin #9) + ENUM2STRING(BOTH_CONSTRAINEE1LOOP), //# Jan walking with Tavion in a loop (cin #9) ENUM2STRING(BOTH_SABERKILLER1), //# Tavion about to strike Jan with saber (cin #9) ENUM2STRING(BOTH_SABERKILLEE1), //# Jan about to be struck by Tavion with saber (cin #9) ENUM2STRING(BOTH_HANDSHAKER1START), //# Luke shaking Kyle's hand (cin #37) @@ -956,15 +960,21 @@ stringID_table_t animTable [MAX_ANIMATIONS+1] = ENUM2STRING(BOTH_DIVE1), //# Dive! + ENUM2STRING(BOTH_SABERFAST_STANCE), + ENUM2STRING(BOTH_SABERSLOW_STANCE), + ENUM2STRING(BOTH_ENGAGETAUNT), ENUM2STRING(BOTH_A2_STABBACK1), //# Stab saber backward ENUM2STRING(BOTH_ATTACK_BACK), //# Swing around backwards and attack - ENUM2STRING(BOTH_FJSS_TR_BL), //# jump spin slash tr to bl - ENUM2STRING(BOTH_FJSS_TL_BR), //# jump spin slash bl to tr + ENUM2STRING(BOTH_JUMPFLIPSLASHDOWN1),//# + ENUM2STRING(BOTH_JUMPFLIPSTABDOWN),//# + ENUM2STRING(BOTH_FORCELEAP2_T__B_),//# + ENUM2STRING(BOTH_LUNGE2_B__T_),//# + ENUM2STRING(BOTH_CROUCHATTACKBACK1),//# ENUM2STRING(BOTH_ARIAL_LEFT), //# ENUM2STRING(BOTH_ARIAL_RIGHT), //# ENUM2STRING(BOTH_CARTWHEEL_LEFT), //# ENUM2STRING(BOTH_CARTWHEEL_RIGHT), //# - ENUM2STRING(BOTH_FLIP_LEFT), //# + ENUM2STRING(BOTH_FLIP_LEFT), //# ENUM2STRING(BOTH_FLIP_BACK1), //# ENUM2STRING(BOTH_FLIP_BACK2), //# ENUM2STRING(BOTH_FLIP_BACK3), //# @@ -973,17 +983,17 @@ stringID_table_t animTable [MAX_ANIMATIONS+1] = ENUM2STRING(BOTH_WALL_RUN_RIGHT), //# ENUM2STRING(BOTH_WALL_RUN_RIGHT_FLIP),//# ENUM2STRING(BOTH_WALL_RUN_RIGHT_STOP),//# - ENUM2STRING(BOTH_WALL_RUN_LEFT), //# + ENUM2STRING(BOTH_WALL_RUN_LEFT), //# ENUM2STRING(BOTH_WALL_RUN_LEFT_FLIP),//# ENUM2STRING(BOTH_WALL_RUN_LEFT_STOP),//# ENUM2STRING(BOTH_WALL_FLIP_RIGHT), //# ENUM2STRING(BOTH_WALL_FLIP_LEFT), //# - ENUM2STRING(BOTH_WALL_FLIP_FWD), //# - ENUM2STRING(BOTH_KNOCKDOWN1), //# - ENUM2STRING(BOTH_KNOCKDOWN2), //# - ENUM2STRING(BOTH_KNOCKDOWN3), //# - ENUM2STRING(BOTH_KNOCKDOWN4), //# - ENUM2STRING(BOTH_KNOCKDOWN5), //# + ENUM2STRING(BOTH_WALL_FLIP_FWD), //# + ENUM2STRING(BOTH_KNOCKDOWN1), //# knocked backwards + ENUM2STRING(BOTH_KNOCKDOWN2), //# knocked backwards hard + ENUM2STRING(BOTH_KNOCKDOWN3), //# knocked forwards + ENUM2STRING(BOTH_KNOCKDOWN4), //# knocked backwards from crouch + ENUM2STRING(BOTH_KNOCKDOWN5), //# dupe of 3 - will be removed ENUM2STRING(BOTH_GETUP1), //# ENUM2STRING(BOTH_GETUP2), //# ENUM2STRING(BOTH_GETUP3), //# @@ -1001,23 +1011,24 @@ stringID_table_t animTable [MAX_ANIMATIONS+1] = ENUM2STRING(BOTH_FORCE_GETUP_B6), //# ENUM2STRING(BOTH_WALL_FLIP_BACK1), //# ENUM2STRING(BOTH_WALL_FLIP_BACK2), //# - ENUM2STRING(BOTH_SPIN1), //# - ENUM2STRING(BOTH_CEILING_CLING), //# clinging to ceiling + ENUM2STRING(BOTH_SPIN1), //# + ENUM2STRING(BOTH_CEILING_CLING), //# clinging to ceiling ENUM2STRING(BOTH_CEILING_DROP), //# dropping from ceiling cling //TESTING + ENUM2STRING(BOTH_FJSS_TR_BL), //# jump spin slash tr to bl + ENUM2STRING(BOTH_FJSS_TL_BR), //# jump spin slash bl to tr ENUM2STRING(BOTH_DEATHFROMBACKSLASH),//# - ENUM2STRING(BOTH_DEFLECTSLASH__R__L_FIN),//# ENUM2STRING(BOTH_RIGHTHANDCHOPPEDOFF),//# - ENUM2STRING(BOTH_JUMPFLIPSLASHDOWN1),//# - ENUM2STRING(BOTH_JUMPFLIPSTABDOWN),//# - ENUM2STRING(BOTH_FORCELEAP2_T__B_),//# - ENUM2STRING(BOTH_LUNGE2_B__T_),//# + ENUM2STRING(BOTH_DEFLECTSLASH__R__L_FIN),//# ENUM2STRING(BOTH_BASHED1),//# ENUM2STRING(BOTH_ARIAL_F1),//# ENUM2STRING(BOTH_BUTTERFLY_FR1),//# ENUM2STRING(BOTH_BUTTERFLY_FL1),//# - ENUM2STRING(BOTH_CROUCHATTACKBACK1),//# + ENUM2STRING(BOTH_POSE1),//# + ENUM2STRING(BOTH_POSE2),//# + ENUM2STRING(BOTH_POSE3),//# + ENUM2STRING(BOTH_POSE4),//# //# #sep BOTH_ MISC MOVEMENT ENUM2STRING(BOTH_HIT1), //# Kyle hit by crate in cin #9 @@ -1078,6 +1089,7 @@ stringID_table_t animTable [MAX_ANIMATIONS+1] = ENUM2STRING(BOTH_INJURED6POINT), //# Chang points to door while in injured state ENUM2STRING(BOTH_INJUREDTOSTAND1), //# Runinjured to stand1 + ENUM2STRING(BOTH_PROPUP1), //# Kyle getting up from having been knocked down (cin #9 end) ENUM2STRING(BOTH_CRAWLBACK1), //# Lying on back), crawling backwards with elbows ENUM2STRING(BOTH_SITWALL1), //# Sitting against a wall ENUM2STRING(BOTH_SLEEP1), //# laying on back-rknee up-rhand on torso @@ -1248,6 +1260,46 @@ stringID_table_t animTable [MAX_ANIMATIONS+1] = ENUM2STRING(LEGS_RIGHTUP3), //# On a slope with RIGHT foot 12 higher than left ENUM2STRING(LEGS_RIGHTUP4), //# On a slope with RIGHT foot 16 higher than left ENUM2STRING(LEGS_RIGHTUP5), //# On a slope with RIGHT foot 20 higher than left + ENUM2STRING(LEGS_S1_LUP1), + ENUM2STRING(LEGS_S1_LUP2), + ENUM2STRING(LEGS_S1_LUP3), + ENUM2STRING(LEGS_S1_LUP4), + ENUM2STRING(LEGS_S1_LUP5), + ENUM2STRING(LEGS_S1_RUP1), + ENUM2STRING(LEGS_S1_RUP2), + ENUM2STRING(LEGS_S1_RUP3), + ENUM2STRING(LEGS_S1_RUP4), + ENUM2STRING(LEGS_S1_RUP5), + ENUM2STRING(LEGS_S3_LUP1), + ENUM2STRING(LEGS_S3_LUP2), + ENUM2STRING(LEGS_S3_LUP3), + ENUM2STRING(LEGS_S3_LUP4), + ENUM2STRING(LEGS_S3_LUP5), + ENUM2STRING(LEGS_S3_RUP1), + ENUM2STRING(LEGS_S3_RUP2), + ENUM2STRING(LEGS_S3_RUP3), + ENUM2STRING(LEGS_S3_RUP4), + ENUM2STRING(LEGS_S3_RUP5), + ENUM2STRING(LEGS_S4_LUP1), + ENUM2STRING(LEGS_S4_LUP2), + ENUM2STRING(LEGS_S4_LUP3), + ENUM2STRING(LEGS_S4_LUP4), + ENUM2STRING(LEGS_S4_LUP5), + ENUM2STRING(LEGS_S4_RUP1), + ENUM2STRING(LEGS_S4_RUP2), + ENUM2STRING(LEGS_S4_RUP3), + ENUM2STRING(LEGS_S4_RUP4), + ENUM2STRING(LEGS_S4_RUP5), + ENUM2STRING(LEGS_S5_LUP1), + ENUM2STRING(LEGS_S5_LUP2), + ENUM2STRING(LEGS_S5_LUP3), + ENUM2STRING(LEGS_S5_LUP4), + ENUM2STRING(LEGS_S5_LUP5), + ENUM2STRING(LEGS_S5_RUP1), + ENUM2STRING(LEGS_S5_RUP2), + ENUM2STRING(LEGS_S5_RUP3), + ENUM2STRING(LEGS_S5_RUP4), + ENUM2STRING(LEGS_S5_RUP5), //================================================= //HEAD ANIMS diff --git a/code/cgame/cg_consolecmds.cpp b/code/cgame/cg_consolecmds.cpp index 42cefe1..c8d6034 100644 --- a/code/cgame/cg_consolecmds.cpp +++ b/code/cgame/cg_consolecmds.cpp @@ -16,7 +16,6 @@ void CG_UseInventory_f( void ); void CG_NextForcePower_f( void ); void CG_PrevForcePower_f( void ); void CG_LoadHud_f( void ); -void CG_ToggleThirdPersonView_f( void ); /* @@ -88,7 +87,7 @@ void CG_ToggleBinoculars( void ) // when you have batteries, you can actually zoom in cg_zoomFov = 40.0f; } - else if ( cg.overrides.fov ) + else if ( cg.overrides.active & CG_OVERRIDE_FOV ) { cg_zoomFov = cg.overrides.fov; } @@ -130,7 +129,7 @@ void CG_ToggleLAGoggles( void ) cg.zoomMode = 3; cg.zoomLocked = qfalse; - if ( cg.overrides.fov ) + if ( cg.overrides.active & CG_OVERRIDE_FOV ) { cg_zoomFov = cg.overrides.fov; } @@ -201,7 +200,6 @@ Ghoul2 Insert End { "forcenext", CG_NextForcePower_f }, { "forceprev", CG_PrevForcePower_f }, { "loadhud", CG_LoadHud_f }, - { "thirdperson", CG_ToggleThirdPersonView_f }, { "dpweapnext", CG_DPNextWeapon_f }, { "dpweapprev", CG_DPPrevWeapon_f }, { "dpinvnext", CG_DPNextInventory_f }, diff --git a/code/cgame/cg_draw.cpp b/code/cgame/cg_draw.cpp index 90a8991..f74b6f0 100644 --- a/code/cgame/cg_draw.cpp +++ b/code/cgame/cg_draw.cpp @@ -326,7 +326,19 @@ static void CG_DrawAmmo(centity_t *cent,int x,int y) if ( cent->currentState.weapon == WP_SABER && cent->gent ) { -// value = cent->gent->client->ps.forcePower; + // don't need to draw ammo, but we will draw the current saber style in this window + switch ( cg.saberAnimLevelPending ) + { + case 1://FORCE_LEVEL_1: + CG_DrawPic( x, y, 80, 40, cgs.media.HUDSaberStyle1 ); + break; + case 2://FORCE_LEVEL_2: + CG_DrawPic( x, y, 80, 40, cgs.media.HUDSaberStyle2 ); + break; + case 3://FORCE_LEVEL_3: + CG_DrawPic( x, y, 80, 40, cgs.media.HUDSaberStyle3 ); + break; + } return; } else @@ -518,7 +530,7 @@ static void CG_DrawArmor(int x,int y) calcColor[2] *= armorPercent; cgi_R_SetColor( calcColor); CG_DrawPic( x, y, 80, 80, cgs.media.HUDArmor2 ); // Inner Armor circular - +/* if (ps->stats[STAT_ARMOR]) // Is there armor? Draw the HUD Armor TIC { // Make tic flash if inner armor is at 50% (25% of full armor) @@ -552,7 +564,7 @@ static void CG_DrawArmor(int x,int y) cgi_R_SetColor( colorTable[CT_HUD_GREEN] ); CG_DrawPic( x, y, 80, 80, cgs.media.HUDArmorTic ); } - +*/ cgi_R_SetColor( colorTable[CT_HUD_GREEN] ); CG_DrawNumField (x + 16 + 14, y + 40 + 14, 3, ps->stats[STAT_ARMOR], 6, 12, NUM_FONT_SMALL,qfalse); @@ -743,7 +755,6 @@ void CG_DrawDataPadHUD( centity_t *cent ) CG_DrawHUDLeftFrame1(x,y); CG_DrawArmor(x,y); CG_DrawHealth(x,y); - CG_DrawHUDLeftFrame2(x,y); x = 526; @@ -751,7 +762,9 @@ void CG_DrawDataPadHUD( centity_t *cent ) CG_DrawForcePower(cent,x,y); CG_DrawAmmo(cent,x,y); CG_DrawMessageLit(cent,x,y); - CG_DrawHUDRightFrame2(x,y); + + cgi_R_SetColor( colorTable[CT_WHITE]); + CG_DrawPic( 0, 0, 640, 480, cgs.media.dataPadFrame ); } @@ -1227,12 +1240,22 @@ static void CG_DrawCrosshair( vec3_t worldPoint ) { ecolor[0] = ecolor[1] = ecolor[2] = 1.0f; } - else if ( cg_forceCrosshair ) + else if ( cg_forceCrosshair && cg_crosshairForceHint.integer ) { - //force-affectable targets are blue - ecolor[0] = 0.2f; - ecolor[1] = 0.5f; - ecolor[2] = 1.0f; + if ( cg_crosshairForceHint.integer == 1 ) + { + // force-affectable targets are blue..do subtle for level 1 hint + ecolor[0] = 0.55f; + ecolor[1] = 0.8f; + ecolor[2] = 1.0f; + } + else + { + // level 2 hint or higher, make it more obvious blue + ecolor[0] = 0.2f; + ecolor[1] = 0.5f; + ecolor[2] = 1.0f; + } corona = qtrue; } else @@ -1309,6 +1332,7 @@ static void CG_DrawCrosshair( vec3_t worldPoint ) } ecolor[3] = 1.0; + cgi_R_SetColor( ecolor ); if ( cg.forceCrosshairStartTime ) { @@ -1339,8 +1363,6 @@ static void CG_DrawCrosshair( vec3_t worldPoint ) } } - cgi_R_SetColor( ecolor ); - if ( corona ) // we are pointing at a crosshair item { if ( !cg.forceCrosshairStartTime ) @@ -1413,16 +1435,16 @@ static void CG_DrawCrosshair( vec3_t worldPoint ) w, h, 0, 0, 1, 1, hShader ); } - if ( cg.forceCrosshairStartTime ) + if ( cg.forceCrosshairStartTime && cg_crosshairForceHint.integer > 1 ) // drawing extra bits { ecolor[0] = ecolor[1] = ecolor[2] = 1.0f; - ecolor[3] = 1 - ecolor[3]; + ecolor[3] = (1 - ecolor[3]) * 0.25f; float sc = 1.0f + sin( cg.time * 0.0005f ) * 0.4f; cgi_R_SetColor( ecolor ); - cgi_R_DrawStretchPic( x + cg.refdef.x + 0.5 * (640 - w * 3 * (sc+1)), - y + cg.refdef.y + 0.5 * (480 - h * 3), w * 3 * (sc+1), h * 3, 0, 0, 1, 1, cgs.media.forceCoronaShader ); + cgi_R_DrawStretchPic( x + cg.refdef.x + 0.5 * (640 - w * 2.5f * (sc+1)), + y + cg.refdef.y + 0.5 * (480 - h * 2), w * 2.5f * (sc+1), h * 2, 0, 0, 1, 1, cgs.media.forceCoronaShader ); } } @@ -1570,7 +1592,7 @@ static void CG_ScanForCrosshairEntity( qboolean scanAll ) //FIXME: debounce this to about 10fps? cg_forceCrosshair = qfalse; - if ( cg_crosshairForceHint.integer && cg_entities[0].gent && cg_entities[0].gent->client ) + if ( cg_entities[0].gent && cg_entities[0].gent->client ) // <-Mike said it should always do this //if (cg_crosshairForceHint.integer && {//try to check for force-affectable stuff first vec3_t d_f, d_rt, d_up; @@ -1842,7 +1864,7 @@ static void CG_DrawRocketLocking( int lockEntNum, int lockTime ) if ( cg.zoomMode > 0 ) { - if ( cg.overrides.fov ) + if ( cg.overrides.active & CG_OVERRIDE_FOV ) { sz -= ( cg.overrides.fov - cg_zoomFov ) / 80.0f; } diff --git a/code/cgame/cg_ents.cpp b/code/cgame/cg_ents.cpp index f2864bb..d7e6ca3 100644 --- a/code/cgame/cg_ents.cpp +++ b/code/cgame/cg_ents.cpp @@ -509,12 +509,9 @@ const weaponData_t *wData = NULL; if ( !( cc->currentState.eFlags & EF_FIRING ) && !( cc->currentState.eFlags & EF_ALT_FIRING )) { - // not animating - gi.G2API_PauseBoneAnim( ¢->gent->ghoul2[cent->gent->playerModel], "model_root", cg.time ); - /* + // not animating..pausing was leaving the barrels in a bad state gi.G2API_SetBoneAnimIndex( ¢->gent->ghoul2[cent->gent->playerModel], cent->gent->rootBone, - 0, 0, BONE_ANIM_OVERRIDE_LOOP, 1, cg.time, -1, 0 ); - */ + 0, 0, BONE_ANIM_OVERRIDE, 1.0f, cg.time ); } // get alternating muzzle end bolts @@ -559,7 +556,7 @@ const weaponData_t *wData = NULL; if ( cc->currentState.eFlags & EF_FIRING || cc->currentState.eFlags & EF_ALT_FIRING ) { gi.G2API_SetBoneAnimIndex( ¢->gent->ghoul2[cent->gent->playerModel], cent->gent->rootBone, - 0, 2, BONE_ANIM_OVERRIDE_LOOP, 1.0f, cg.time, -1, 0 ); + 0, 3, BONE_ANIM_OVERRIDE_FREEZE, 0.6f, cg.time ); if ( effect ) { @@ -636,7 +633,7 @@ const weaponData_t *wData = NULL; if ( cent->gent->owner->health ) { //make sure we can always be seen - ent.renderfx |= RF_MINLIGHT | RF_PULSATE; + ent.renderfx |= RF_PULSATE; } } } @@ -671,7 +668,7 @@ const weaponData_t *wData = NULL; if ( cent->gent->owner->health ) { //make sure we can always be seen - ent.renderfx |= RF_MINLIGHT | RF_PULSATE; + ent.renderfx |= RF_PULSATE; } } } @@ -956,11 +953,11 @@ Ghoul2 Insert End // items without glow textures need to keep a minimum light value // so they are always visible - if (( item->giType == IT_WEAPON ) || ( item->giType == IT_ARMOR )) +/* if (( item->giType == IT_WEAPON ) || ( item->giType == IT_ARMOR )) { ent.renderfx |= RF_MINLIGHT; } - +*/ // increase the size of the weapons when they are presented as items // if ( item->giType == IT_WEAPON ) { // VectorScale( ent.axis[0], 1.5f, ent.axis[0] ); @@ -1617,7 +1614,7 @@ Ghoul2 Insert End cent->lerpOrigin[2] = current[2] + f * ( next[2] - current[2] ); /* - if(cent->gent && cent->currentState.eFlags & EF_NPC && !VectorCompare(current, next)) + if ( cent->gent && cent->currentState.eFlags & EF_NPC ) { Com_Printf("%s last/next/lerp pos %s/%s/%s, f = %4.2f\n", cent->gent->script_targetname, vtos(current), vtos(next), vtos(cent->lerpOrigin), f); } @@ -1625,6 +1622,24 @@ Ghoul2 Insert End return;//FIXME: should this be outside this if? } } + else + { + if ( cent->currentState.apos.trType == TR_INTERPOLATE ) + { + EvaluateTrajectory( ¢->currentState.apos, cg.snap->serverTime, cent->lerpAngles ); + } + if ( cent->currentState.pos.trType == TR_INTERPOLATE ) + { + EvaluateTrajectory( ¢->currentState.pos, cg.snap->serverTime, cent->lerpOrigin ); + /* + if(cent->gent && cent->currentState.eFlags & EF_NPC ) + { + Com_Printf("%s last/next/lerp pos %s, f = 1.0\n", cent->gent->script_targetname, vtos(cent->lerpOrigin) ); + } + */ + return; + } + } // FIXME: if it's blocked, it wigs out, draws it in a predicted spot, but never // makes it there - we need to predict it in the right place if this is happens... @@ -1818,9 +1833,11 @@ void CG_MatrixEffect ( centity_t *cent ) float totalElapsedTime = (float)(cg.time - cent->currentState.time); float elapsedTime = totalElapsedTime; if ( totalElapsedTime > cent->currentState.eventParm //MATRIX_EFFECT_TIME - || (cent->currentState.weapon&&g_entities[cent->currentState.otherEntityNum].client&&g_entities[cent->currentState.otherEntityNum].client->ps.groundEntityNum!=ENTITYNUM_NONE) ) - {//time is up or this is a falling spin and they hit the ground - cg.overrides.thirdPersonEntity = 0; + || (cent->currentState.weapon&&g_entities[cent->currentState.otherEntityNum].client&&g_entities[cent->currentState.otherEntityNum].client->ps.groundEntityNum!=ENTITYNUM_NONE) + || cg.missionStatusShow ) + {//time is up or this is a falling spin and they hit the ground or mission end screen is up + cg.overrides.active &= ~(/*CG_OVERRIDE_3RD_PERSON_ENT|*/CG_OVERRIDE_3RD_PERSON_RNG|CG_OVERRIDE_3RD_PERSON_ANG|CG_OVERRIDE_3RD_PERSON_POF); + //cg.overrides.thirdPersonEntity = 0; cg.overrides.thirdPersonAngle = 0; cg.overrides.thirdPersonPitchOffset = 0; cg.overrides.thirdPersonRange = 0; @@ -1840,9 +1857,11 @@ void CG_MatrixEffect ( centity_t *cent ) MatrixMode = qtrue; //FIXME: move the position towards them and back? + //cg.overrides.active |= CG_OVERRIDE_3RD_PERSON_ENT; //cg.overrides.thirdPersonEntity = cent->currentState.otherEntityNum; //rotate + cg.overrides.active |= CG_OVERRIDE_3RD_PERSON_ANG; cg.overrides.thirdPersonAngle = 360.0f*elapsedTime/MATRIX_EFFECT_TIME; if ( !cent->currentState.weapon ) @@ -1857,6 +1876,7 @@ void CG_MatrixEffect ( centity_t *cent ) //pitch //dip - FIXME: use pitchOffet? + cg.overrides.active |= CG_OVERRIDE_3RD_PERSON_POF; cg.overrides.thirdPersonPitchOffset = cg_thirdPersonPitchOffset.value; if ( elapsedTime < MATRIX_EFFECT_TIME*0.33f ) { @@ -1872,6 +1892,7 @@ void CG_MatrixEffect ( centity_t *cent ) } //pull back + cg.overrides.active |= CG_OVERRIDE_3RD_PERSON_RNG; cg.overrides.thirdPersonRange = cg_thirdPersonRange.value; if ( elapsedTime < MATRIX_EFFECT_TIME*0.33 ) { @@ -1886,7 +1907,11 @@ void CG_MatrixEffect ( centity_t *cent ) cg.overrides.thirdPersonRange += 80.0f; } } - //else FIXME: if they're on the ground, stop spinning... + else + {//FIXME: if they're on the ground, stop spinning and stop timescale + //FIXME: if they go to the menu, restore timescale + cgi_Cvar_Set( "timescale", "0.25f" ); + } } static void CG_Think ( centity_t *cent ) @@ -2037,18 +2062,27 @@ void CG_AddPacketEntities( void ) { playerState_t *ps; // set cg.frameInterpolation - if ( cg.nextSnap ) { + if ( cg.nextSnap ) + { int delta; delta = (cg.nextSnap->serverTime - cg.snap->serverTime); - if ( delta == 0 ) { + if ( delta == 0 ) + { cg.frameInterpolation = 0; - } else { +// Com_Printf("identical frames\n"); + } + else + { cg.frameInterpolation = (float)( cg.time - cg.snap->serverTime ) / delta; +// Com_Printf("interp %6.4f\n",cg.frameInterpolation); } - } else { + } + else + { cg.frameInterpolation = 0; // actually, it should never be used, because // no entities should be marked as interpolating +// Com_Printf("no next snap!\n"); } // the auto-rotating items will all have the same axis diff --git a/code/cgame/cg_event.cpp b/code/cgame/cg_event.cpp index ae93f02..1332cea 100644 --- a/code/cgame/cg_event.cpp +++ b/code/cgame/cg_event.cpp @@ -760,8 +760,8 @@ void CG_EntityEvent( centity_t *cent, vec3_t position ) { } else { - VectorCopy( es->angles, axis[0] ); - VectorCopy( es->angles2, axis[1] ); + VectorCopy( cent->gent->pos3, axis[0] ); + VectorCopy( cent->gent->pos4, axis[1] ); CrossProduct( axis[0], axis[1], axis[2] ); // the entNum the effect may be attached to diff --git a/code/cgame/cg_local.h b/code/cgame/cg_local.h index dfecd41..130da4f 100644 --- a/code/cgame/cg_local.h +++ b/code/cgame/cg_local.h @@ -250,13 +250,23 @@ typedef struct { } powerupInfo_t; +#define CG_OVERRIDE_3RD_PERSON_ENT 0x00000001 +#define CG_OVERRIDE_3RD_PERSON_RNG 0x00000002 +#define CG_OVERRIDE_3RD_PERSON_ANG 0x00000004 +#define CG_OVERRIDE_3RD_PERSON_VOF 0x00000008 +#define CG_OVERRIDE_3RD_PERSON_POF 0x00000010 +#define CG_OVERRIDE_3RD_PERSON_CDP 0x00000020 +#define CG_OVERRIDE_FOV 0x00000040 + typedef struct { //NOTE: these probably get cleared in save/load!!! + int active; //bit-flag field of which overrides are active int thirdPersonEntity; //who to center on float thirdPersonRange; //how far to be from them float thirdPersonAngle; //what angle to look at them from float thirdPersonVertOffset; //how high to be above them float thirdPersonPitchOffset; //what offset pitch to apply the the camera view + float thirdPersonCameraDamp; //how tightly to move the camera pos behind the player float fov; //what fov to use //NOTE: could put Alpha and HorzOffset and the target & camera damps, but no-one is trying to override those, so... } overrides_t; @@ -1099,7 +1109,7 @@ void CG_CreateBBRefEnts(entityState_t *s1, vec3_t origin ); /* Ghoul2 Insert End */ - +void trap_Com_SetOrgAngles(vec3_t org,vec3_t angles); void trap_R_GetLightStyle(int style, color4ub_t color); void trap_R_SetLightStyle(int style, int color); diff --git a/code/cgame/cg_localents.cpp b/code/cgame/cg_localents.cpp index 5ad66d9..19aea17 100644 --- a/code/cgame/cg_localents.cpp +++ b/code/cgame/cg_localents.cpp @@ -206,6 +206,9 @@ void CG_AddFragment( localEntity_t *le ) // calculate new position EvaluateTrajectory( &le->pos, cg.time, newOrigin ); + le->refEntity.renderfx |= RF_LIGHTING_ORIGIN; + VectorCopy( newOrigin, le->refEntity.lightingOrigin ); + // trace a line from previous position to new position CG_Trace( &trace, le->refEntity.origin, NULL, NULL, newOrigin, le->ownerGentNum, CONTENTS_SOLID ); if ( trace.fraction == 1.0 ) { diff --git a/code/cgame/cg_main.cpp b/code/cgame/cg_main.cpp index 0981c89..990fe6f 100644 --- a/code/cgame/cg_main.cpp +++ b/code/cgame/cg_main.cpp @@ -54,7 +54,15 @@ char *inv_names[] = "LIGHT AMP GOGGLES", "ASSAULT SENTRY", "GOODIE KEY", -"SECURITY KEY" +"GOODIE KEY", +"GOODIE KEY", +"GOODIE KEY", +"GOODIE KEY", +"SECURITY KEY", +"SECURITY KEY", +"SECURITY KEY", +"SECURITY KEY", +"SECURITY KEY", }; int force_icons[NUM_FORCE_POWERS]; @@ -272,6 +280,8 @@ vmCvar_t cg_debugBB; Ghoul2 Insert End */ +vmCvar_t cg_VariantSoundCap; // 0 = no capping, else cap to (n) max (typically just 1, but allows more) + typedef struct { vmCvar_t *vmCvar; char *cvarName; @@ -361,7 +371,7 @@ Ghoul2 Insert Start /* Ghoul2 Insert End */ - + { &cg_VariantSoundCap, "cg_VariantSoundCap", "0" }, }; int cvarTableSize = sizeof( cvarTable ) / sizeof( cvarTable[0] ); @@ -1165,6 +1175,7 @@ static void CG_RegisterGraphics( void ) { cgs.media.forceIconBackground = cgi_R_RegisterShaderNoMip( "gfx/hud/background_f"); cgs.media.inventoryIconBackground= cgi_R_RegisterShaderNoMip( "gfx/hud/background_i"); cgs.media.inventoryProngsOn = cgi_R_RegisterShaderNoMip( "gfx/hud/prong_on_i"); + cgs.media.dataPadFrame = cgi_R_RegisterShaderNoMip( "gfx/hud/datapad2"); cg.loadLCARSStage = 5; CG_LoadingString( "game media models" ); @@ -1204,7 +1215,7 @@ static void CG_RegisterGraphics( void ) { cgs.media.HUDArmor2= cgi_R_RegisterShaderNoMip( "gfx/hud/armor2" ); cgs.media.HUDHealth= cgi_R_RegisterShaderNoMip( "gfx/hud/health" ); cgs.media.HUDHealthTic= cgi_R_RegisterShaderNoMip( "gfx/hud/health_tic" ); - cgs.media.HUDArmorTic= cgi_R_RegisterShaderNoMip( "gfx/hud/armor_tic" ); +// cgs.media.HUDArmorTic= cgi_R_RegisterShaderNoMip( "gfx/hud/armor_tic" ); cgs.media.HUDRightFrame= cgi_R_RegisterShaderNoMip( "gfx/hud/hudrightframe" ); cgs.media.HUDInnerRight = cgi_R_RegisterShaderNoMip( "gfx/hud/hudright_innerframe" ); @@ -1847,6 +1858,13 @@ void CG_DrawEdge( vec3_t start, vec3_t end, int type ) FX_AddLine( start, end, 8.0f, 4.0f, 0.0f, 0.5f, 0.5f, color, color, 51, cgi_R_RegisterShader( "gfx/misc/nav_line" ), 0 ); } break; + case EDGE_MOVEDIR: + { + vec3_t color = { 0, 255, 0 }; + + FX_AddLine( start, end, 8.0f, 4.0f, 0.0f, 0.5f, 0.5f, color, color, 51, cgi_R_RegisterShader( "gfx/misc/nav_line" ), 0 ); + } + break; default: break; } @@ -2695,8 +2713,9 @@ void CG_DrawInventorySelect( void ) int count; int holdX,x,y,pad; int height; - int tag; +// int tag; float addX; + vec4_t textColor = { .312f, .75f, .621f, 1.0f }; // don't display if dead if ( cg.predicted_player_state.stats[STAT_HEALTH] <= 0 ) @@ -2818,11 +2837,15 @@ void CG_DrawInventorySelect( void ) if (inv_names[cg.inventorySelect]) { // FIXME :this has to use the bg_itemlist pickup name - tag = FindInventoryItemTag(cg.inventorySelect); +// tag = FindInventoryItemTag(cg.inventorySelect); + + int w = cgi_R_Font_StrLenPixels(inv_names[cg.inventorySelect], cgs.media.qhFontSmall, 1.0f); + int x = ( SCREEN_WIDTH - w ) / 2; + cgi_R_Font_DrawString(x, (SCREEN_HEIGHT - 24), inv_names[cg.inventorySelect], textColor, cgs.media.qhFontSmall, -1, 1.0f); // if (tag) // { - CG_DrawProportionalString(320, y + 53, inv_names[cg.inventorySelect], CG_CENTER | CG_SMALLFONT, colorTable[CT_ICON_BLUE]); +// CG_DrawProportionalString(320, y + 53, inv_names[cg.inventorySelect], CG_CENTER | CG_SMALLFONT, colorTable[CT_ICON_BLUE]); // CG_DrawProportionalString(320, y + 53, bg_itemlist[i].pickup_name, CG_CENTER | CG_SMALLFONT, colorTable[CT_ICON_BLUE]); // } } @@ -2871,23 +2894,24 @@ int cgi_UI_GetItemText(char *menuFile,char *itemName, char *text); char *inventoryDesc[15] = { -"Neuro-Saav Model TD2.3 Electrobinoculars\nElectrobinoculars operate in low-light and normal light conditions to magnify distant objects and provide a heads-up display that features detailed information on the area viewed. The heads-up display measures distances and offers various telemetry readouts on the object or area in view. Powered by normal battery cells that drain power at a minimal rate, Electrobinoculars also feature an optional, infrared mode.", -"BioTech Bacta Canister\nBacta canisters are portable, disposable packs of bacta ointments and emergency care tools. Designed for use in the field, bacta canisters can be used to heal wounds and restore vitality during medical recovery. No field medic should be without them.", -"Arakyd Mark VII Inquisitor \nAn attack drone similar to the training drones used by Jedi to practice their lightsaber skills, the Inquisitor hovers around its user and attacks any enemy the user fires upon. The drone operates automatically for a limited time and then self-destructs when its power is depleted.", -"Light Amplification Goggles\nAlso known as infra-goggles, this helpful creates a balance of light levels that allows the user to see well in most situations. The resulting effect enhances the overall brightness but casts everything in a greenish hue. The goggles require batteries to function, draining them at roughly the same rate as Electrobinoculars. Light Amplification Goggles can be worn during combat, but will not function without an available power source.", -"Portable Assault Sentry \nThis deadly weapon is roughly the size of a large backpack, but don't let its size fool you. Once activated, the weapon unfurls and is set to auto-target any enemy threat. The Sentry drains battery life at an accelerated rate and, once it's deployed, can't be restored to its original portable condition. ", -"Security Key", -"Security Key", -"Security Key", -"Security Key", -"Security Key", -"Security Key", -"Security Key", -"Security Key", -"Security Key", -"Security Key", +"NEURO_SAAV_DESC", +"BACTA_DESC", +"INQUISITOR_DESC", +"LA_GOGGLES_DESC", +"PORTABLE_SENTRY_DESC", +"SECURITY_KEY_DESC", +"SECURITY_KEY_DESC", +"SECURITY_KEY_DESC", +"SECURITY_KEY_DESC", +"SECURITY_KEY_DESC", +"SECURITY_KEY_DESC", +"SECURITY_KEY_DESC", +"SECURITY_KEY_DESC", +"SECURITY_KEY_DESC", +"SECURITY_KEY_DESC", }; + /* =================== CG_DrawDataPadInventorySelect @@ -2903,6 +2927,7 @@ void CG_DrawDataPadInventorySelect( void ) int holdX,x,y,pad; int height; float addX; + char text[1024]={0}; // count the number of items owned @@ -2918,7 +2943,8 @@ void CG_DrawDataPadInventorySelect( void ) if (!count) { - CG_DrawProportionalString(320, 300 + 22, "EMPTY INVENTORY", CG_CENTER | CG_SMALLFONT, colorTable[CT_ICON_BLUE]); + cgi_SP_GetStringTextString("INGAME_EMPTY_INV",text, sizeof(text) ); + CG_DrawProportionalString(320, 300 + 22, text, CG_CENTER | CG_SMALLFONT, colorTable[CT_ICON_BLUE]); return; } @@ -3060,11 +3086,16 @@ void CG_DrawDataPadInventorySelect( void ) if ((cg.DataPadInventorySelect>=0) && (cg.DataPadInventorySelect<13)) { - CG_DisplayBoxedText(70,50,500,300,inventoryDesc[cg.DataPadInventorySelect], - cgs.media.qhFontSmall, - 0.7f, - colorTable[CT_WHITE] - ); + cgi_SP_GetStringTextString( va("INGAME_%s",inventoryDesc[cg.DataPadInventorySelect]), text, sizeof(text) ); + + if (text) + { + CG_DisplayBoxedText(70,50,500,300,text, + cgs.media.qhFontSmall, + 0.7f, + colorTable[CT_WHITE] + ); + } } } @@ -3145,16 +3176,16 @@ void CG_NextForcePower_f( void ) return; } + SetForcePowerTime(); + if ((cg.forcepowerSelectTime + WEAPON_SELECT_TIME) < cg.time) { - SetForcePowerTime(); return; } - SetForcePowerTime(); const int original = cg.forcepowerSelect; - for ( i = 0 ;showPowers[i]!=NUM_FORCE_POWERS ; i++ ) + for ( i = 0; i < MAX_SHOWPOWERS; i++ ) { cg.forcepowerSelect++; @@ -3163,7 +3194,7 @@ void CG_NextForcePower_f( void ) cg.forcepowerSelect = 0; } - if (ForcePower_Valid(i)) // Does he have the force power? + if (ForcePower_Valid(cg.forcepowerSelect)) // Does he have the force power? { return; } @@ -3186,16 +3217,16 @@ void CG_PrevForcePower_f( void ) return; } + SetForcePowerTime(); + if ((cg.forcepowerSelectTime + WEAPON_SELECT_TIME) < cg.time) { - SetForcePowerTime(); return; } - SetForcePowerTime(); const int original = cg.forcepowerSelect; - for ( i = 0 ;showPowers[i]!=NUM_FORCE_POWERS ; i++ ) + for ( i = 0; i < MAX_SHOWPOWERS; i++ ) { cg.forcepowerSelect--; @@ -3204,7 +3235,7 @@ void CG_PrevForcePower_f( void ) cg.forcepowerSelect = MAX_SHOWPOWERS; } - if (ForcePower_Valid(i)) // Does he have the force power? + if (ForcePower_Valid(cg.forcepowerSelect)) // Does he have the force power? { return; } @@ -3367,7 +3398,9 @@ void CG_DrawForceSelect( void ) if ( showPowersName[cg.forcepowerSelect] ) { - CG_DrawProportionalString(320, y + 38, showPowersName[cg.forcepowerSelect], CG_CENTER | CG_SMALLFONT, colorTable[CT_ICON_BLUE]); + int w = cgi_R_Font_StrLenPixels(showPowersName[cg.forcepowerSelect], cgs.media.qhFontSmall, 1.0f); + int x = ( SCREEN_WIDTH - w ) / 2; + cgi_R_Font_DrawString(x, (SCREEN_HEIGHT - 24), showPowersName[cg.forcepowerSelect], colorTable[CT_ICON_BLUE], cgs.media.qhFontSmall, -1, 1.0f); } } @@ -3444,21 +3477,20 @@ void CG_DPPrevForcePower_f( void ) char *forcepowerDesc[NUM_FORCE_POWERS] = { -"Force Heal\nDuration: Instantaneous effect\nArea Of Effect: Jedi only\nEffect: The Jedi has the ability to heal himself after injury.\n· Rank 1 - Jedi goes into a meditative stance for a short time and must remain stationary. Any movement or attack will prevent healing.\n· Rank 2 - Jedi no longer needs to be stationary. The Jedi will heal over a short period of time.\n· Rank 3 - Jedi heals instantly.", -"Force Jump\nDuration: Immediate\nArea Of Effect: Jedi only\nEffect: Allows Jedi to make a tremendous vertical leap. \n· Rank 1 - Jedi can leap up to twice his normal jump height. \n· Rank 2 - Jedi can leap up to four times his normal jump height.\n· Rank 3 - Jedi can leap up to eight times his normal jump height.", -"Force Speed\nDuration: 5 seconds\nArea of Effect: Jedi and surroundings\nEffect: Jedi speeds up and slows the world around him.\n· Rank 1 - Jedi moves 25% faster than normal\n· Rank 2 - Jedi moves 50% faster than normal\n· Rank 3 - Jedi moves 100% faster than normal", -"Force Push\nDuration: Instantaneous effect\nArea Of Effect: Objects or Persons\nEffect: Allows Jedi to push objects away from himself and defend himself from missile and Force Grip attacks.\n· Rank 1 - Jedi uses the Force to push a specific enemy or object focused on.\n· Rank 2 - Jedi uses the Force to push back multiple enemies or objects in a limited arc.\n· Rank 3 - Jedi can push back multiple enemies with enough force to do damage by pushing the enemies into solid surfaces or off ledges.", -"Force Pull\nDuration: Instantaneous effect\nArea Of Effect: Objects only\nEffect: Allows Jedi to pull different objects to him\n· Rank 1 - Jedi can pull weapons and items to him from the ground in front of him from a distance\n· Rank 2 - Jedi can pull projectile weapons from enemies in an arc from a distance\n· Rank 3 - Jedi can pull and alter specific architecture, levers or objects in an arc from a distance ", -"Mind Trick\nDuration: 3 seconds\nArea Of Effect: Humanoids\nEffect: Allows Jedi to confuse and/or misdirect attention \n· Rank 1 - Jedi can distract and confuse a single enemy for 5 seconds\n· Rank 2 - Jedi can distract and confuse multiple enemies for 10 seconds.\n· Rank 3 - Jedi can distract and confuse multiple enemies for 15 seconds or befriend one enemy. \nNote: Aggressive action or loud noises made by the Jedi will alert the enemy and cancel the effect. Mind tricks don't work on some, more powerful enemies like Dark Jedi or Reborn.", -"Force Grip\nDuration: Instantaneous\nArea Of Effect: Living persons only\nEffect: Allows Jedi to choke or constrict the organs of a living being\n· Rank 1 - Affected enemy is gripped and held undamaged, but immobile for 5 seconds. Jedi must remain stationary.\n· Rank 2 - Enemy is affected similarly to rank 1, but the grip can damage and lift enemies with prolonged focus of the grip. Jedi must remain stationary.\n· Rank 3- Enemy is affected similarly to rank 2, but the Jedi can move freely and smash the enemy into walls and other obstacles around him or use the enemy as a shield while still doing choke damage.", -"Force Lightning\nDuration: Variable\nAOE: Living persons only\nEffect: Allows Jedi to hurl a devastating electrical attack against enemies.\n· Rank 1 - Jedi launches a single bolt that fires forward, doing instant damage.\n· Rank 2 - Jedi can maintain the Force Lightning for a sustained forward attack.\n· Rank 3 - Jedi emanates a sustained fan of electricity in a large forward arc, damaging anything in front of him.", -"Lightsaber Defense\nDuration: Always on\nArea Of Effect: N/A\nEffect: Jedi can block damage with his lightsaber \n· Rank 1 - Jedi can deflect projectiles and melee attacks in a small arc directly in front of him.\n· Rank 2 - Jedi can deflect projectiles and melee attacks in a larger arc directly in front of him. Increased deflection speed.\n· Rank 3 - Jedi has a larger defense area and can deflect attacks back at the attacker. Increased deflection speed.", -"Lightsaber Offense\nDuration: Always on\nArea Of Effect: N/A\nEffect: As Jedi gains combat experience his lighsaber attack effectiveness increases. \nJedi Sense\nDuration: Always on\nArea Of Effect: N/A\nEffect: Jedi can sense enemies, concealed areas, hidden items and enemies around him.", -"Lightsaber Throw\nDuration: Instant\nArea Of Effect: Player arc\nEffect: Jedi can throw his lightsaber and use it as a missile weapon.\n· Rank 1 - Lightsaber flies straight from the player and returns.\n· Rank 2 - Jedi can exert minimal control over the flying lightsaber as it arcs out, but the lightsaber still returns directly to the player. \n· Rank 3 - Jedi can exert great control over the lightsaber in the air." +"FORCE_HEAL_DESC", +"FORCE_JUMP_DESC", +"FORCE_SPEED_DESC", +"FORCE_PUSH_DESC", +"FORCE_PULL_DESC", +"FORCE_MIND_TRICK", +"FORCE_GRIP_DESC", +"FORCE_LIGHTNING_DESC", +"FORCE_SABER_DEFENSE_DESC", +"FORCE_SABER_OFFENSE_DESC", +"FORCE_SABER_THROW_DESC", }; - /* =================== CG_DrawDataPadForceSelect @@ -3472,6 +3504,7 @@ void CG_DrawDataPadForceSelect( void ) int holdX,x,y,pad,length; int sideLeftIconCnt,sideRightIconCnt; int sideMax,holdCount,iconCnt; + char text[1024]={0}; // count the number of powers owned count = 0; @@ -3589,31 +3622,19 @@ void CG_DrawDataPadForceSelect( void ) } } - CG_DisplayBoxedText(70,50,500,300,forcepowerDesc[cg.DataPadforcepowerSelect], - cgs.media.qhFontSmall, - 0.7f, - colorTable[CT_WHITE] - ); + cgi_SP_GetStringTextString( va("INGAME_%s",forcepowerDesc[cg.DataPadforcepowerSelect]), text, sizeof(text) ); + + if (text) + { + + CG_DisplayBoxedText(70,50,500,300,text, + cgs.media.qhFontSmall, + 0.7f, + colorTable[CT_WHITE] + ); + } } -/* -=============== -CG_ToggleThirdPersonView_f -=============== -*/ -void CG_ToggleThirdPersonView_f( void ) -{ - - if ( !cg.renderingThirdPerson ) - { - cgi_Cvar_Set( "cg_thirdperson", "1" ); - } - else - { - cgi_Cvar_Set( "cg_thirdperson", "0" ); - } - -} // actually, these are pretty pointless so far in CHC, since in TA codebase they were used only so init some HUD // function ptrs to allow cinematics in onscreen displays. So far, we don't use those, but here they are anyway... // diff --git a/code/cgame/cg_media.h b/code/cgame/cg_media.h index 8a7ec97..a54d922 100644 --- a/code/cgame/cg_media.h +++ b/code/cgame/cg_media.h @@ -177,9 +177,15 @@ typedef struct { qhandle_t HUDArmorTic; qhandle_t HUDInnerLeft; + qhandle_t HUDSaberStyle1; + qhandle_t HUDSaberStyle2; + qhandle_t HUDSaberStyle3; + qhandle_t HUDRightFrame; qhandle_t HUDInnerRight; + qhandle_t dataPadFrame; + qhandle_t talkingtop; qhandle_t talkingbot; @@ -287,6 +293,7 @@ typedef struct // loaded or calculated from the gamestate. It will NOT // be cleared when a tournement restart is done, allowing // all clients to begin playing instantly +#define STRIPED_LEVELNAME_VARIATIONS 3 // sigh, to cope with levels that use text from >1 SP file typedef struct { gameState_t gameState; // gamestate from server glconfig_t glconfig; // rendering configuration @@ -299,7 +306,7 @@ typedef struct { int timelimit; int maxclients; char mapname[MAX_QPATH]; - char stripLevelName[MAX_QPATH]; + char stripLevelName[STRIPED_LEVELNAME_VARIATIONS][MAX_QPATH]; // // locally derived information from gamestate diff --git a/code/cgame/cg_players.cpp b/code/cgame/cg_players.cpp index c8138d3..ff86ffb 100644 --- a/code/cgame/cg_players.cpp +++ b/code/cgame/cg_players.cpp @@ -35,6 +35,7 @@ extern int PM_AnimLength( int index, animNumber_t anim ); extern qboolean PM_InRoll( playerState_t *ps ); //Basic set of custom sounds that everyone needs +// (keep numbers in ascending order in order for variant-capping to work) const char *cg_customBasicSoundNames[MAX_CUSTOM_BASIC_SOUNDS] = { "*death1.wav", @@ -54,6 +55,7 @@ const char *cg_customBasicSoundNames[MAX_CUSTOM_BASIC_SOUNDS] = }; //Used as a supplement to the basic set for enemies and hazard team +// (keep numbers in ascending order in order for variant-capping to work) const char *cg_customCombatSoundNames[MAX_CUSTOM_COMBAT_SOUNDS] = { "*anger1.wav", //Say when acquire an enemy when didn't have one before @@ -74,6 +76,7 @@ const char *cg_customCombatSoundNames[MAX_CUSTOM_COMBAT_SOUNDS] = }; //Used as a supplement to the basic set for stormtroopers +// (keep numbers in ascending order in order for variant-capping to work) const char *cg_customExtraSoundNames[MAX_CUSTOM_EXTRA_SOUNDS] = { "*chase1.wav", @@ -115,6 +118,7 @@ const char *cg_customExtraSoundNames[MAX_CUSTOM_EXTRA_SOUNDS] = }; //Used as a supplement to the basic set for jedi +// (keep numbers in ascending order in order for variant-capping to work) const char *cg_customJediSoundNames[MAX_CUSTOM_JEDI_SOUNDS] = { "*combat1.wav", @@ -141,6 +145,70 @@ const char *cg_customJediSoundNames[MAX_CUSTOM_JEDI_SOUNDS] = "*pushfail.wav", }; + +// done at registration time only... +// +// cuts down on sound-variant registration for low end machines, +// eg *gloat1.wav (plus...2,...3) can be capped to all be just *gloat1.wav +// +static const char *GetCustomSound_VariantCapped(const char *ppsTable[], int iEntryNum) +{ + extern vmCvar_t cg_VariantSoundCap; + +// const int iVariantCap = 2; // test + const int &iVariantCap = cg_VariantSoundCap.integer; + + if (iVariantCap) + { + char *p = strchr(ppsTable[iEntryNum],'.'); + if (p && p-2 > ppsTable[iEntryNum] && isdigit(p[-1]) && !isdigit(p[-2])) + { + int iThisVariant = p[-1]-'0'; + + if (iThisVariant > iVariantCap) + { + // ok, let's not load this variant, so pick a random one below the cap value... + // + for (int i=0; i<2; i++) // 1st pass, choose random, 2nd pass (if random not in list), choose xxx1, else fall through... + { + char sName[MAX_QPATH]; + + Q_strncpyz(sName, ppsTable[iEntryNum], sizeof(sName)); + p = strchr(sName,'.'); + if (p) + { + *p = '\0'; + sName[strlen(sName)-1] = '\0'; // strip the digit + + int iRandom = !i ? Q_irand(1,iVariantCap) : 1; + + strcat(sName,va("%d.wav",iRandom)); + + // does this exist in the entries before the original one?... + // + for (int iScanNum=0; iScanNumgent->ghoul2, cent->gent->playerModel, cent->gent->motionBolt, &boltMatrix, vec3_origin, cent->lerpOrigin, cg.time, cgs.model_draw, cent->currentState.modelScale ); gi.G2API_GiveMeVectorFromMatrix( boltMatrix, NEGATIVE_Y, motionFwd ); + gi.G2API_GiveMeVectorFromMatrix( boltMatrix, NEGATIVE_X, motionRt ); vectoangles( motionFwd, motionAngles ); + vectoangles( motionRt, tempAng ); + motionAngles[ROLL] = -tempAng[PITCH]; + for ( int ang = 0; ang < 3; ang++ ) { viewAngles[ang] = AngleNormalize180( viewAngles[ang] - AngleNormalize180( motionAngles[ang] ) ); @@ -1957,6 +2029,9 @@ void CG_G2PlayerAngles( centity_t *cent, vec3_t legs[3], vec3_t angles ) } else { + //FIXME: we need to override the hips bone with a turn anim when turning + // and clear it when we're not... does beld from and to parent actually work? + //FIXME: this needs to properly set the legs.yawing field so we don't erroneously play the turning anim, but we do play it when turning in place if ( angles[YAW] == cent->pe.legs.yawAngle ) { @@ -4700,6 +4775,10 @@ void CG_Player( centity_t *cent ) { ent.renderfx |= RF_SHADOW_PLANE; } ent.renderfx |= RF_LIGHTING_ORIGIN; // use the same origin for all + if ( cent->gent->NPC->scriptFlags & SCF_MORELIGHT ) + { + ent.renderfx |= RF_MORELIGHT; //bigger than normal min light + } VectorCopy( cent->lerpOrigin, ent.origin ); VectorCopy( cent->lerpOrigin, ent.oldorigin ); @@ -4844,8 +4923,11 @@ Ghoul2 Insert Start { ent.renderfx |= RF_SHADOW_PLANE; } - ent.renderfx |= RF_LIGHTING_ORIGIN; // use the same origin for all + if ( cent->gent->NPC && cent->gent->NPC->scriptFlags & SCF_MORELIGHT ) + { + ent.renderfx |= RF_MORELIGHT; //bigger than normal min light + } CG_RegisterWeapon( cent->currentState.weapon ); @@ -5408,6 +5490,10 @@ Ghoul2 Insert End renderfx |= RF_SHADOW_PLANE; } renderfx |= RF_LIGHTING_ORIGIN; // use the same origin for all + if ( cent->gent->NPC->scriptFlags & SCF_MORELIGHT ) + { + renderfx |= RF_MORELIGHT; //bigger than normal min light + } if ( cg.snap->ps.viewEntity > 0 && cg.snap->ps.viewEntity < ENTITYNUM_WORLD && cg.snap->ps.viewEntity == cent->currentState.clientNum ) {//player is in an entity camera view, ME diff --git a/code/cgame/cg_players.dsp b/code/cgame/cg_players.dsp deleted file mode 100644 index f47f86f..0000000 --- a/code/cgame/cg_players.dsp +++ /dev/null @@ -1,88 +0,0 @@ -# Microsoft Developer Studio Project File - Name="cg_players" - Package Owner=<4> -# Microsoft Developer Studio Generated Build File, Format Version 6.00 -# ** DO NOT EDIT ** - -# TARGTYPE "Win32 (x86) Console Application" 0x0103 - -CFG=cg_players - Win32 Debug -!MESSAGE This is not a valid makefile. To build this project using NMAKE, -!MESSAGE use the Export Makefile command and run -!MESSAGE -!MESSAGE NMAKE /f "cg_players.mak". -!MESSAGE -!MESSAGE You can specify a configuration when running NMAKE -!MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE -!MESSAGE NMAKE /f "cg_players.mak" CFG="cg_players - Win32 Debug" -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "cg_players - Win32 Release" (based on "Win32 (x86) Console Application") -!MESSAGE "cg_players - Win32 Debug" (based on "Win32 (x86) Console Application") -!MESSAGE - -# Begin Project -# PROP AllowPerConfigDependencies 0 -# PROP Scc_ProjName "" -# PROP Scc_LocalPath "" -CPP=cl.exe -RSC=rc.exe - -!IF "$(CFG)" == "cg_players - Win32 Release" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir "Release" -# PROP BASE Intermediate_Dir "Release" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 0 -# PROP Output_Dir "Release" -# PROP Intermediate_Dir "Release" -# PROP Target_Dir "" -# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c -# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c -# ADD BASE RSC /l 0x409 /d "NDEBUG" -# ADD RSC /l 0x409 /d "NDEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 -# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 - -!ELSEIF "$(CFG)" == "cg_players - Win32 Debug" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir "Debug" -# PROP BASE Intermediate_Dir "Debug" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir "Debug" -# PROP Intermediate_Dir "Debug" -# PROP Target_Dir "" -# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c -# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c -# ADD BASE RSC /l 0x409 /d "_DEBUG" -# ADD RSC /l 0x409 /d "_DEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept -# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept - -!ENDIF - -# Begin Target - -# Name "cg_players - Win32 Release" -# Name "cg_players - Win32 Debug" -# Begin Source File - -SOURCE=.\cg_players.cpp -# End Source File -# End Target -# End Project diff --git a/code/cgame/cg_predict.cpp b/code/cgame/cg_predict.cpp index 70a9995..c84d9e1 100644 --- a/code/cgame/cg_predict.cpp +++ b/code/cgame/cg_predict.cpp @@ -212,6 +212,72 @@ void CG_SetClientViewAngles( vec3_t angles ) } cgi_SetUserCmdAngles( angles[PITCH], angles[YAW], angles[ROLL] ); } + +extern qboolean PM_AdjustAnglesToGripper( gentity_t *gent, usercmd_t *cmd ); +extern qboolean PM_AdjustAngleForWallRun( gentity_t *ent, usercmd_t *ucmd, qboolean doMove ); +extern qboolean PM_AdjustAnglesForSpinningFlip( gentity_t *ent, usercmd_t *ucmd, qboolean anglesOnly ); +extern qboolean PM_AdjustAnglesForBackAttack( gentity_t *ent, usercmd_t *ucmd ); +extern qboolean PM_AdjustAnglesForSaberLock( gentity_t *ent, usercmd_t *ucmd ); +extern qboolean PM_AdjustAnglesForKnockdown( gentity_t *ent, usercmd_t *ucmd, qboolean angleClampOnly ); +extern qboolean G_CheckClampUcmd( gentity_t *ent, usercmd_t *ucmd ); +qboolean CG_CheckModifyUCmd( usercmd_t *cmd, vec3_t viewangles ) +{ + qboolean overridAngles = qfalse; + if ( cg.snap->ps.viewEntity > 0 && cg.snap->ps.viewEntity < ENTITYNUM_WORLD ) + {//controlling something else + memset( cmd, 0, sizeof( usercmd_t ) ); + //to keep pointing in same dir, need to set cmd.angles + cmd->angles[PITCH] = cmd->angles[ROLL] = 0; + cmd->angles[YAW] = ANGLE2SHORT( cg.snap->ps.viewangles[YAW] ) - cg.snap->ps.delta_angles[YAW]; + //CG_SetClientViewAngles( cg.snap->ps.viewangles ); + } + else if ( cg.snap->ps.vehicleModel != 0 ) + {//in vehicle flight mode + float speed = VectorLength( cg.snap->ps.velocity ); + if ( !speed || cg.snap->ps.groundEntityNum != ENTITYNUM_NONE ) + { + cmd->rightmove = 0; + cmd->angles[PITCH] = 0; + cmd->angles[YAW] = ANGLE2SHORT( cg.snap->ps.viewangles[YAW] ) - cg.snap->ps.delta_angles[YAW]; + CG_SetClientViewAngles( cg.snap->ps.viewangles ); + } + } + + if ( &g_entities[0] && g_entities[0].client ) + { + if ( !PM_AdjustAnglesToGripper( &g_entities[0], cmd ) ) + { + if ( PM_AdjustAnglesForSpinningFlip( &g_entities[0], cmd, qtrue ) ) + { + CG_SetClientViewAngles( g_entities[0].client->ps.viewangles ); + if ( viewangles ) + { + VectorCopy( g_entities[0].client->ps.viewangles, viewangles ); + overridAngles = qtrue; + } + } + } + else + { + CG_SetClientViewAngles( g_entities[0].client->ps.viewangles ); + if ( viewangles ) + { + VectorCopy( g_entities[0].client->ps.viewangles, viewangles ); + overridAngles = qtrue; + } + } + if ( G_CheckClampUcmd( &g_entities[0], cmd ) ) + { + CG_SetClientViewAngles( g_entities[0].client->ps.viewangles ); + if ( viewangles ) + { + VectorCopy( g_entities[0].client->ps.viewangles, viewangles ); + overridAngles = qtrue; + } + } + } + return overridAngles; +} /* ======================== CG_InterpolatePlayerState @@ -220,17 +286,12 @@ Generates cg.predicted_player_state by interpolating between cg.snap->player_state and cg.nextFrame->player_state ======================== */ -extern qboolean PM_AdjustAnglesToGripper( gentity_t *gent, usercmd_t *cmd ); -extern qboolean PM_AdjustAngleForWallRun( gentity_t *ent, usercmd_t *ucmd, qboolean doMove ); -extern qboolean PM_AdjustAnglesForSpinningFlip( gentity_t *ent, usercmd_t *ucmd, qboolean anglesOnly ); -extern qboolean PM_AdjustAnglesForBackAttack( gentity_t *ent, usercmd_t *ucmd ); -extern qboolean PM_AdjustAnglesForSaberLock( gentity_t *ent, usercmd_t *ucmd ); -extern qboolean PM_AdjustAnglesForKnockdown( gentity_t *ent, usercmd_t *ucmd, qboolean angleClampOnly ); void CG_InterpolatePlayerState( qboolean grabAngles ) { float f; int i; playerState_t *out; snapshot_t *prev, *next; + qboolean skip = qfalse; out = &cg.predicted_player_state; prev = cg.snap; @@ -246,71 +307,13 @@ void CG_InterpolatePlayerState( qboolean grabAngles ) { cmdNum = cgi_GetCurrentCmdNumber(); cgi_GetUserCmd( cmdNum, &cmd ); - if ( cg.snap->ps.viewEntity > 0 && cg.snap->ps.viewEntity < ENTITYNUM_WORLD ) - {//controlling something else - memset( &cmd, 0, sizeof( usercmd_t ) ); - //to keep pointing in same dir, need to set cmd.angles - cmd.angles[PITCH] = cmd.angles[ROLL] = 0; - cmd.angles[YAW] = ANGLE2SHORT( cg.snap->ps.viewangles[YAW] ) - cg.snap->ps.delta_angles[YAW]; - //CG_SetClientViewAngles( cg.snap->ps.viewangles ); - } - else if ( cg.snap->ps.vehicleModel != 0 ) - {//in vehicle flight mode - float speed = VectorLength( cg.snap->ps.velocity ); - if ( !speed || cg.snap->ps.groundEntityNum != ENTITYNUM_NONE ) - { - cmd.rightmove = 0; - cmd.angles[PITCH] = 0; - cmd.angles[YAW] = ANGLE2SHORT( cg.snap->ps.viewangles[YAW] ) - cg.snap->ps.delta_angles[YAW]; - CG_SetClientViewAngles( cg.snap->ps.viewangles ); - } - } + skip = CG_CheckModifyUCmd( &cmd, out->viewangles ); - if ( &g_entities[0] && g_entities[0].client ) + if ( !skip ) { - if ( !PM_AdjustAnglesToGripper( &g_entities[0], &cmd ) ) - { - if ( !PM_AdjustAnglesForSaberLock( &g_entities[0], &cmd ) ) - { - if ( !PM_AdjustAnglesForSpinningFlip( &g_entities[0], &cmd, qtrue ) ) - { - if ( !PM_AdjustAnglesForBackAttack( &g_entities[0], &cmd ) ) - { - if ( !PM_AdjustAngleForWallRun( &g_entities[0], &cmd, qfalse ) ) - { - if ( PM_AdjustAnglesForKnockdown( &g_entities[0], &cmd, qtrue ) ) - { - CG_SetClientViewAngles( g_entities[0].client->ps.viewangles ); - } - } - else - { - CG_SetClientViewAngles( g_entities[0].client->ps.viewangles ); - } - } - else - { - CG_SetClientViewAngles( g_entities[0].client->ps.viewangles ); - } - } - else - { - CG_SetClientViewAngles( g_entities[0].client->ps.viewangles ); - } - } - else - { - CG_SetClientViewAngles( g_entities[0].client->ps.viewangles ); - } - } - else - { - CG_SetClientViewAngles( g_entities[0].client->ps.viewangles ); - } + //NULL so that it doesn't execute a block of code that must be run from game + PM_UpdateViewAngles( out, &cmd, NULL ); } - - //NULL so that it doesn't execute a block of code that must be run from game - PM_UpdateViewAngles( out, &cmd, NULL ); } // if the next frame is a teleport, we can't lerp to it @@ -599,6 +602,7 @@ void CG_PredictPlayerState( void ) { cg_pmove.cmd.buttons = 0; cg_pmove.cmd.upmove = 0; } + CG_CheckModifyUCmd( &cg_pmove.cmd, NULL ); //FIXME: prediction on clients in timescale results in jerky positional translation Pmove( &cg_pmove ); diff --git a/code/cgame/cg_public.h b/code/cgame/cg_public.h index 7367db3..fcf933b 100644 --- a/code/cgame/cg_public.h +++ b/code/cgame/cg_public.h @@ -135,6 +135,7 @@ typedef enum { CG_AS_ADDENTRY, CG_AS_GETBMODELSOUND, CG_S_GETSAMPLELENGTH, + COM_SETORGANGLES, /* Ghoul2 Insert Start */ diff --git a/code/cgame/cg_servercmds.cpp b/code/cgame/cg_servercmds.cpp index beb448c..3251f38 100644 --- a/code/cgame/cg_servercmds.cpp +++ b/code/cgame/cg_servercmds.cpp @@ -28,9 +28,88 @@ void CG_ParseServerinfo( void ) { cgs.maxclients = 1; mapname = Info_ValueForKey( info, "mapname" ); Com_sprintf( cgs.mapname, sizeof( cgs.mapname ), "maps/%s.bsp", mapname ); - strcpy( cgs.stripLevelName, mapname ); - strupr( cgs.stripLevelName ); - cgi_SP_Register(cgs.stripLevelName, qfalse); //do not keep around after level + strcpy( cgs.stripLevelName[0], mapname ); + strupr( cgs.stripLevelName[0] ); + for (int i=1; ips.viewEntity > 0 && cg.snap->ps.viewEntity < ENTITYNUM_WORLD && !cg.renderingThirdPerson ) { + else if ( cg.snap && cg.snap->ps.viewEntity > 0 && cg.snap->ps.viewEntity < ENTITYNUM_WORLD && !cg.renderingThirdPerson ) + { // if in entity camera view, use a special FOV if ( &g_entities[cg.snap->ps.viewEntity] && g_entities[cg.snap->ps.viewEntity].NPC ) @@ -1168,7 +1192,7 @@ static qboolean CG_CalcFov( void ) { } else { - if ( cg.overrides.fov ) // allow overriding the fov with a viewent + if ( cg.overrides.active & CG_OVERRIDE_FOV ) { fov_x = cg.overrides.fov; } @@ -1197,7 +1221,7 @@ static qboolean CG_CalcFov( void ) { } } else { // user selectable - if ( cg.overrides.fov ) + if ( cg.overrides.active & CG_OVERRIDE_FOV ) { fov_x = cg.overrides.fov; } @@ -1228,7 +1252,7 @@ static qboolean CG_CalcFov( void ) { } // Clamp zoomFov - float actualFOV = cg.overrides.fov ? cg.overrides.fov : cg_fov.value; + float actualFOV = (cg.overrides.active&CG_OVERRIDE_FOV) ? cg.overrides.fov : cg_fov.value; if ( cg_zoomFov < MAX_ZOOM_FOV ) { cg_zoomFov = MAX_ZOOM_FOV; @@ -1396,6 +1420,10 @@ static qboolean CG_CalcViewValues( void ) { ps = &cg.predicted_player_state; +#if _DEBUG + trap_Com_SetOrgAngles(ps->origin,ps->viewangles); +#endif + // intermission view if ( ps->pm_type == PM_INTERMISSION ) { VectorCopy( ps->origin, cg.refdef.vieworg ); @@ -1412,14 +1440,21 @@ static qboolean CG_CalcViewValues( void ) { if ( cg.snap->ps.viewEntity > 0 && cg.snap->ps.viewEntity < ENTITYNUM_WORLD ) {//in an entity camera view - VectorCopy( cg_entities[cg.snap->ps.viewEntity].lerpOrigin, cg.refdef.vieworg ); + if ( g_entities[cg.snap->ps.viewEntity].client && cg.renderingThirdPerson ) + { + VectorCopy( g_entities[cg.snap->ps.viewEntity].client->renderInfo.eyePoint, cg.refdef.vieworg ); + } + else + { + VectorCopy( cg_entities[cg.snap->ps.viewEntity].lerpOrigin, cg.refdef.vieworg ); + } VectorCopy( cg_entities[cg.snap->ps.viewEntity].lerpAngles, cg.refdefViewAngles ); if ( !Q_stricmp( "misc_camera", g_entities[cg.snap->ps.viewEntity].classname )) { viewEntIsCam = qtrue; } } - else if ( cg.renderingThirdPerson && !cg.zoomMode && cg.overrides.thirdPersonEntity ) + else if ( cg.renderingThirdPerson && !cg.zoomMode && (cg.overrides.active&CG_OVERRIDE_3RD_PERSON_ENT) ) {//different center, same angle VectorCopy( cg_entities[cg.overrides.thirdPersonEntity].lerpOrigin, cg.refdef.vieworg ); VectorCopy( ps->viewangles, cg.refdefViewAngles ); @@ -1680,6 +1715,31 @@ void CG_DrawActiveFrame( int serverTime, stereoFrame_t stereoView ) { inwater = CG_CalcViewValues(); } + //check for opaque water + if ( 1 ) + { + vec3_t camTest; + VectorCopy( cg.refdef.vieworg, camTest ); + camTest[2] += 6; + if ( !(CG_PointContents( camTest, ENTITYNUM_NONE )&CONTENTS_SOLID) && !gi.inPVS( cg.refdef.vieworg, camTest ) ) + {//crossed visible line into another room + cg.refdef.vieworg[2] -= 6; + } + else + { + VectorCopy( cg.refdef.vieworg, camTest ); + camTest[2] -= 6; + if ( !(CG_PointContents( camTest, ENTITYNUM_NONE )&CONTENTS_SOLID) && !gi.inPVS( cg.refdef.vieworg, camTest ) ) + { + cg.refdef.vieworg[2] += 6; + } + } + /* + if ( (trace.contents&(CONTENTS_WATER|CONTENTS_OPAQUE)) ) + {//opaque water + } + */ + } //This is done from the vieworg to get origin for non-attenuated sounds cgi_S_UpdateAmbientSet( CG_ConfigString( CS_AMBIENT_SET ), cg.refdef.vieworg ); diff --git a/code/cgame/cg_weapons.cpp b/code/cgame/cg_weapons.cpp index 246c02e..cefea2c 100644 --- a/code/cgame/cg_weapons.cpp +++ b/code/cgame/cg_weapons.cpp @@ -206,6 +206,10 @@ void CG_RegisterWeapon( int weaponNum ) { cgs.effects.forceLightning = theFxScheduler.RegisterEffect( "force/lightning" ); cgs.effects.forceLightningWide = theFxScheduler.RegisterEffect( "force/lightningwide" ); + cgs.media.HUDSaberStyle1 = cgi_R_RegisterShader( "gfx/hud/saber_styles1" ); + cgs.media.HUDSaberStyle2 = cgi_R_RegisterShader( "gfx/hud/saber_styles2" ); + cgs.media.HUDSaberStyle3 = cgi_R_RegisterShader( "gfx/hud/saber_styles3" ); + //saber sounds cgi_S_RegisterSound( "sound/weapons/saber/saberon.wav" ); cgi_S_RegisterSound( "sound/weapons/saber/enemy_saber_on.wav" ); @@ -287,7 +291,7 @@ void CG_RegisterWeapon( int weaponNum ) { cgs.media.purpleSaberGlowShader = cgi_R_RegisterShader( "gfx/effects/sabers/purple_glow" ); cgs.media.purpleSaberCoreShader = cgi_R_RegisterShader( "gfx/effects/sabers/purple_line" ); - cgs.media.forceCoronaShader = cgi_R_RegisterShader( "gfx/2d/corona" ); + cgs.media.forceCoronaShader = cgi_R_RegisterShaderNoMip( "gfx/2d/corona" ); break; case WP_BRYAR_PISTOL: @@ -855,7 +859,7 @@ void CG_AddViewWeapon( playerState_t *ps ) } // drop gun lower at higher fov - float actualFOV = cg.overrides.fov ? cg.overrides.fov : cg_fov.value; + float actualFOV = (cg.overrides.active&CG_OVERRIDE_FOV) ? cg.overrides.fov : cg_fov.value; if ( actualFOV > 80 ) { fovOffset = -0.1 * ( actualFOV - 80 ); @@ -914,7 +918,7 @@ void CG_AddViewWeapon( playerState_t *ps ) AnglesToAxis( angles, gun.axis ); CG_PositionEntityOnTag( &gun, &hand, weapon->handsModel, "tag_weapon"); - gun.renderfx = RF_MINLIGHT | RF_DEPTHHACK | RF_FIRST_PERSON; + gun.renderfx = RF_DEPTHHACK | RF_FIRST_PERSON; //--------- // OK, we are making an assumption here that if we have the phaser that it is always on.... @@ -1246,22 +1250,21 @@ void CG_DrawIconBackground(void) int cgi_UI_GetItemText(char *menuFile,char *itemName, char *text); - char *weaponDesc[13] = { -"Lightsaber -\nAn elegant weapon for a more civilized age, the lightsaber is the preferred weapon of the Jedi Knight. The lightsaber is an energy blade of great power that can be used by the wielder for both attack and defense.\nPrimary Fire - Slashing and swinging attacks\nSecondary Fire - Force powered saber throw\nDefensive Ability - Deflects blaster and energy weapon fire, parries enemy lightsaber attacks\nAmmo Type - N/A", -"Bryar Blaster Pistol \nKyle Katarn's weapon of choice, the Bryar Blaster Pistol is a common hand-held energy weapon with a slow rate of fire and incredible accuracy.\nPrimary Fire - Slow, single shot with great accuracy and damage.\nSecondary Fire - Charged energy buildup for increased damage blast attack.\nAmmo Type - Blaster Pack", -"E-11 Blaster Rifle \nThe primary weapon of the Imperial forces, the E-11 is a sturdy and deadly blaster rifle capable of inflicting great damage despite its small size. The E-11's compact design makes it easy to carry and conceal.\nPrimary Fire - Slow, single shot with moderate accuracy and great damage.\nSecondary Fire - Rapid, burst fire with low accuracy and expanded firing area.\nAmmo Type - Blaster Pack", -"Tenloss DXR-6 Disruptor rifle \nThis nefarious weapon affects matter at the molecular level, ripping apart living material with ease. Because of the weapon's inhumane nature, the DXR-6 is outlawed throughout the galaxy and is generally only used by scattered droid and Remnant forces.\nPrimary Fire - Single shot with slow fire rate, fast projectile and small radius damage.\nSecondary Fire - Scoped mode: Single shot with slow fire rate, increased damage and high weapon energy consumption\nAmmo Type - Power cell", -"Wookiee Bowcaster\nThis archaic-looking weapon fires powerful bolts of metal enveloped in pockets of energy. Capable of inflicting incredible damage, the bowcaster requires tremendous physical strength to fire. Most bowcasters sold outside the Wookiee home world come equipped with self-cocking actions that allow physically weaker creatures to fire them.\nPrimary Fire - Extremely accurate and powerful single shot with radius damage\nSecondary Fire - Charged energy buildup for multiple shots with radius damage \nAmmo Type - Power cell", -"Imperial Heavy Repeater with Concussion Launcher\nThis destructive projectile weapon is extremely deadly, firing rapid streams of metal bullets. Imperial forces use the Heavy Repeater's deadly suppressive fire and concussion launcher for crowd control and to spread heavy fire over large areas.\nPrimary Fire - Fully automatic projectile fire \nSecondary Fire - Single shot, concussion explosive round.\nAmmo type - Metallic bolts", -"Destructive Electro-Magnetic Pulse 2 Gun\nCommonly referred to as the DEMP 2, this pulse rifle is primarily used against droids and electrical devices. The DEMP 2 fires high-powered ion bursts that disrupt electrical systems. Unlike previous incarnations of the weapon, the DEMP 2's ion charges are capable of damaging living material.\nPrimary Fire - Single shot, stuns humans, damages droids\nSecondary Fire - Chain lightning arcs from the weapon and moves from target to target and is deadly to both droids and humanoid enemies. \nAmmo Type - Power cell", -"Golan Arms FC1 Flechette Weapon \nWidely used by the Corporate Sector Authority's police squads, the FC1 fires shards of metal in a widespread pattern. The weapon is designed to hit multiple targets in close proximity, but great care must be taken to avoid ricochet damage.\nPrimary Fire - Single shot, spread fire\nSecondary Fire -Launches a self-adhesive, explosive proximity mine\nAmmo Type - Metallic Bolts", -"Merr-Sonn PLX-2M Portable Missile System \nThe PLX-2M is an extremely powerful weapon that fires Arakyd 3T3 missiles. The sheer explosive power of the PLL-2M makes it dangerous to fire blindly in close quarters, but is extremely effective when used as a 'smart' tracking weapon.\nPrimary Fire - Fires a single, forward-firing explosive missile\nSecondary Fire - Fires a single 'smart' missile that tracks acquired and locked targets.\nAmmo Type - Rockets", -"Thermal Detonator \nThe thermal detonator is a radius-damage grenade that releases a barrage of thermal energy capable of disintegrating all matter around it.\nPrimary Fire - Long distance throw, grenade explodes on contact\nSecondary Fire - Short distance roll, grenade bounces and explodes", -"Trip Mines \nTrip mines consist of a beam projector affixed to a shaped explosive casing. The laser activates when the mine is placed and extends a beam from the charge to the nearest surface that intersects its path. If the beam is broken or the charge is fired upon, the mine detonates and causes radius damage to anything in range.\nPrimary Fire - Once placed, acts as proximity mine with attached laser.\nSecondary Fire - Once placed, explodes after two seconds. No laser.", -"Detonation Packs \nA detonation pack is essentially a small explosive device with a remote detonation trigger. The pack is placed or thrown and can be detonated at will by the user. Detonation packs are commonly used to ambush enemies or open sealed doors.\nPrimary Fire - Sets charge at the user's feet\nSecondary Fire - Explodes all set charges", -"Stun Baton \nCommonly used to subdue unruly prisoners, the stun baton was designed for use in melee combat where killing your opponent is not necessarily the desired outcome.\nPrimary Fire - Slashing and swinging attacks.\nSecondary Fire - Special slashing and swinging attacks.", +"SABER_DESC", +"BLASTER_PISTOL_DESC", +"BLASTER_RIFLE_DESC", +"DISRUPTOR_RIFLE_DESC", +"BOWCASTER_DESC", +"HEAVYREPEATER_DESC", +"DEMP2_DESC", +"FLECHETTE_DESC", +"MERR_SONN_DESC", +"THERMAL_DETONATOR_DESC", +"TRIP_MINE_DESC", +"DET_PACK_DESC", +"STUN_BATON_DESC", }; @@ -1281,6 +1284,7 @@ void CG_DrawDataPadWeaponSelect( void ) int sideMax,holdCount,iconCnt; int height; vec4_t calcColor; + char text[1024]={0}; // showing weapon select clears pickup item display, but not the blend blob cg.itemPickupTime = 0; @@ -1452,11 +1456,23 @@ void CG_DrawDataPadWeaponSelect( void ) x= 40; y= 70; - CG_DisplayBoxedText(70,50,500,300,weaponDesc[cg.DataPadWeaponSelect-1], + cgi_SP_GetStringTextString( va("INGAME_%s",weaponDesc[cg.DataPadWeaponSelect-1]), text, sizeof(text) ); + + if (text) + { + CG_DisplayBoxedText(70,50,500,300,text, cgs.media.qhFontSmall, 0.7f, colorTable[CT_WHITE] ); + } + +/* CG_DisplayBoxedText(70,50,500,300,weaponDesc[cg.DataPadWeaponSelect-1], + cgs.media.qhFontSmall, + 0.7f, + colorTable[CT_WHITE] + ); +*/ cgi_R_SetColor( NULL ); } @@ -1618,6 +1634,7 @@ void CG_DrawWeaponSelect( void ) int sideMax,holdCount,iconCnt; int height; vec4_t calcColor; + vec4_t textColor = { .875f, .718f, .121f, 1.0f }; if (!cgi_UI_GetMenuInfo("weaponselecthud",&x2,&y2)) { @@ -1808,7 +1825,7 @@ void CG_DrawWeaponSelect( void ) //#ifdef _DEBUG int w = cgi_R_Font_StrLenPixels(name, cgs.media.qhFontSmall, 1.0f); int x = ( SCREEN_WIDTH - w ) / 2; - cgi_R_Font_DrawString(x, y + 48, name, colorTable[CT_ICON_BLUE], cgs.media.qhFontSmall, -1, 1.0f); + cgi_R_Font_DrawString(x, (SCREEN_HEIGHT - 24), name, textColor, cgs.media.qhFontSmall, -1, 1.0f); //#endif } } diff --git a/code/cgame/vssver.scc b/code/cgame/vssver.scc new file mode 100644 index 0000000..fef8e04 Binary files /dev/null and b/code/cgame/vssver.scc differ diff --git a/code/client/OpenAL/vssver.scc b/code/client/OpenAL/vssver.scc new file mode 100644 index 0000000..652b934 Binary files /dev/null and b/code/client/OpenAL/vssver.scc differ diff --git a/code/client/cl_cgame.cpp b/code/client/cl_cgame.cpp index b2a6136..d9d71fb 100644 --- a/code/client/cl_cgame.cpp +++ b/code/client/cl_cgame.cpp @@ -604,6 +604,9 @@ int CL_CgameSystemCalls( int *args ) { case CG_SETUSERCMDANGLES: CL_SetUserCmdAngles( VMF(1), VMF(2), VMF(3) ); return 0; + case COM_SETORGANGLES: + Com_SetOrgAngles((float *)VMA(1),(float *)VMA(2)); + return 0; /* Ghoul2 Insert Start */ @@ -753,9 +756,7 @@ Ghoul2 Insert End return result; case CG_SP_REGISTER: - SP_Register( (const char *) VMA(1), args[2]?(SP_REGISTER_MENU|SP_REGISTER_REQUIRED):SP_REGISTER_CLIENT ); - return 0; - break; + return SP_Register( (const char *) VMA(1), args[2]?(SP_REGISTER_MENU|SP_REGISTER_REQUIRED):SP_REGISTER_CLIENT ); case CG_SP_GETSTRINGTEXTSTRING: case CG_SP_GETSTRINGTEXT: @@ -875,6 +876,7 @@ void CL_CGameRendering( stereoFrame_t stereo ) { } } #endif + G2API_SetTime(cl.serverTime,G2T_CG_TIME); VM_Call( CG_DRAW_ACTIVE_FRAME, cl.serverTime, stereo, qfalse ); // VM_Debug( 0 ); } diff --git a/code/client/cl_cin.cpp b/code/client/cl_cin.cpp index 9a679a8..b40ec4a 100644 --- a/code/client/cl_cin.cpp +++ b/code/client/cl_cin.cpp @@ -285,13 +285,58 @@ long RllDecodeStereoToStereo(unsigned char *from,unsigned int size,char signedOu extern cvar_t *s_volume; int iVolume = 1/*bMixedWithCurrentAudio*/ ? ((int) (256.0f * (s_volume?s_volume->value:1.0f))) : 256; - for (z=0;z>1); //*sizeof(short)); diff --git a/code/client/cl_main.cpp b/code/client/cl_main.cpp index 584ac26..12b2329 100644 --- a/code/client/cl_main.cpp +++ b/code/client/cl_main.cpp @@ -23,6 +23,7 @@ cvar_t *cl_maxpackets; cvar_t *cl_packetdup; cvar_t *cl_timeNudge; cvar_t *cl_showTimeDelta; +cvar_t *cl_newClock=0; cvar_t *cl_shownet; cvar_t *cl_avidemo; @@ -39,6 +40,7 @@ cvar_t *cl_showMouseRate; cvar_t *cl_VideoQuality; cvar_t *cl_VidFadeUp; // deliberately kept as "Vid" rather than "Video" so tab-matching matches only VideoQuality cvar_t *cl_VidFadeDown; +cvar_t *cl_framerate; cvar_t *m_pitch; cvar_t *m_pitchOverride; @@ -427,9 +429,6 @@ void CL_Snd_Restart_f( void ) { S_Init(); - S_FreeAllSFXMem(); - S_UnCacheDynamicMusic(); - // CL_Vid_Restart_f(); extern qboolean s_soundMuted; @@ -758,7 +757,10 @@ CL_Frame ================== */ -void CL_Frame ( int msec ) { +extern cvar_t *cl_newClock; +static unsigned int frameCount; +float avgFrametime=0.0; +void CL_Frame ( int msec,float fractionMsec ) { if ( !com_cl_running->integer ) { return; } @@ -798,7 +800,30 @@ void CL_Frame ( int msec ) { // decide the simulation time cls.frametime = msec; + if(cl_framerate->integer) + { + avgFrametime+=msec; + char mess[256]; + if(!(frameCount&0x1f)) + { + sprintf(mess,"Frame rate=%f\n\n",1000.0f*(1.0/(avgFrametime/32.0f))); + // OutputDebugString(mess); + Com_Printf(mess); + avgFrametime=0.0f; + } + frameCount++; + } + cls.frametimeFraction=fractionMsec; cls.realtime += msec; + cls.realtimeFraction+=fractionMsec; + if (cls.realtimeFraction>=1.0f) + { + if (cl_newClock&&cl_newClock->integer) + { + cls.realtime++; + } + cls.realtimeFraction-=1.0f; + } if ( cl_timegraph->integer ) { SCR_DebugGraph ( cls.realFrametime * 0.25, 0 ); } @@ -1044,6 +1069,7 @@ void CL_Init( void ) { cls.state = CA_DISCONNECTED; // no longer CA_UNINITIALIZED cls.keyCatchers = KEYCATCH_CONSOLE; cls.realtime = 0; + cls.realtimeFraction=0.0f; // fraction of a msec accumulated CL_InitInput (); @@ -1057,6 +1083,7 @@ void CL_Init( void ) { cl_timeNudge = Cvar_Get ("cl_timeNudge", "0", CVAR_TEMP ); cl_shownet = Cvar_Get ("cl_shownet", "0", CVAR_TEMP ); cl_showTimeDelta = Cvar_Get ("cl_showTimeDelta", "0", CVAR_TEMP ); + cl_newClock = Cvar_Get ("cl_newClock", "1", 0); cl_activeAction = Cvar_Get( "activeAction", "", CVAR_TEMP ); cl_avidemo = Cvar_Get ("cl_avidemo", "0", 0); @@ -1082,6 +1109,7 @@ void CL_Init( void ) { cl_VideoQuality = Cvar_Get ("cl_VideoQuality", "0", CVAR_ARCHIVE); cl_VidFadeUp = Cvar_Get ("cl_VidFadeUp", "1", CVAR_TEMP); cl_VidFadeDown = Cvar_Get ("cl_VidFadeDown", "1", CVAR_TEMP); + cl_framerate = Cvar_Get ("cl_framerate", "0", CVAR_TEMP); // init autoswitch so the ui will have it correctly even // if the cgame hasn't been started @@ -1116,7 +1144,7 @@ void CL_Init( void ) { Cmd_AddCommand ("cinematic", CL_PlayCinematic_f); Cmd_AddCommand ("ingamecinematic", CL_PlayInGameCinematic_f); Cmd_AddCommand ("setenv", CL_Setenv_f ); - Cmd_AddCommand ("genericmenu", CL_GenericMenu_f); + Cmd_AddCommand ("uimenu", CL_GenericMenu_f); Cmd_AddCommand ("datapad", CL_DataPad_f); Cmd_AddCommand ("endscreendissolve", CL_EndScreenDissolve_f); diff --git a/code/client/cl_mp3.org b/code/client/cl_mp3.org new file mode 100644 index 0000000..1db5f52 --- /dev/null +++ b/code/client/cl_mp3.org @@ -0,0 +1,419 @@ +// Filename:- cl_mp3.cpp +// +// (The interface module between all the MP3 stuff and Trek) +// +#include "client.h" +#include "cl_mp3.h" //(only included directly from snd_mem.cpp, so not in client.h) +#include "../mp3code/mp3struct.h" // keep this rather awful file secret from the rest of the program + +// call the real worker code in the messy C stuff... +// +#ifdef __cplusplus +extern "C" +{ +#endif + +char* C_MP3_IsValid (void *pvData, int iDataLen); +char* C_MP3_GetUnpackedSize (void *pvData, int iDataLen, int *piUnpackedSize); +char* C_MP3_UnpackRawPCM (void *pvData, int iDataLen, int *piUnpackedSize, void *pbUnpackBuffer); +char* C_MP3_GetHeaderData (void *pvData, int iDataLen, int *piRate, int *piWidth, int *piChannels); +char* C_MP3Stream_DecodeInit (LP_MP3STREAM pSFX_MP3Stream, void *pvSourceData, int iSourceBytesRemaining, + int iGameAudioSampleRate, int iGameAudioSampleBits ); +unsigned int C_MP3Stream_Decode (LP_MP3STREAM pSFX_MP3Stream); +char* C_MP3Stream_Rewind (LP_MP3STREAM pSFX_MP3Stream); + + +// these two are temp and will eventually be deleted... honest... +// +char* C_TEST_MP3_GetUnpackedSize( const char *_FILENAME1, const char *_FILENAME2, const char *_FILENAME3, + void *data1,void *data2,void *data3, + int size1,int size2,int size3, + int *iUnpackedSize1,int *iUnpackedSize2,int *iUnpackedSize3 + ); +char * C_TEST_MP3_UnpackRawPCM(const char *_FILENAME1, const char *_FILENAME2, const char *_FILENAME3, + void *data1,void *data2,void *data3, + int iSourceBytesRemaining1,int iSourceBytesRemaining2,int iSourceBytesRemaining3, + int *piUnpackedSize1,int *piUnpackedSize2,int *piUnpackedSize3, + void *pbUnpackBuffer1,void *pbUnpackBuffer2,void *pbUnpackBuffer3 + ); + + +#ifdef __cplusplus +} +#endif + + + +// expects data already loaded, filename arg is for error printing only +// +// returns success/fail +// +qboolean MP3_IsValid( const char *psLocalFilename, void *pvData, int iDataLen ) +{ + char *psError = C_MP3_IsValid(pvData, iDataLen); + + if (psError) + { + Com_Printf(va(S_COLOR_RED"%s\n(File: %s)\n",psError, psLocalFilename)); + } + + return !psError; +} + + + +// expects data already loaded, filename arg is for error printing only +// +// returns unpacked length, or 0 for errors (which will be printed internally) +// +int MP3_GetUnpackedSize( const char *psLocalFilename, void *pvData, int iDataLen, qboolean qbIgnoreID3Tag /* = qfalse */) +{ + int iUnpackedSize = 0; + + if (qbIgnoreID3Tag || !MP3_ReadSpecialTagInfo((byte *)pvData, iDataLen, NULL, &iUnpackedSize)) + { + char *psError = C_MP3_GetUnpackedSize( pvData, iDataLen, &iUnpackedSize); + + if (psError) + { + Com_Printf(va(S_COLOR_RED"%s\n(File: %s)\n",psError, psLocalFilename)); + return 0; + } + } + + return iUnpackedSize; +} + + + +// expects data already loaded, filename arg is for error printing only +// +// returns byte count of unpacked data (effectively a success/fail bool) +// +int MP3_UnpackRawPCM( const char *psLocalFilename, void *pvData, int iDataLen, byte *pbUnpackBuffer ) +{ + int iUnpackedSize; + char *psError = C_MP3_UnpackRawPCM( pvData, iDataLen, &iUnpackedSize, pbUnpackBuffer); + + if (psError) + { + Com_Printf(va(S_COLOR_RED"%s\n(File: %s)\n",psError, psLocalFilename)); + return 0; + } + + return iUnpackedSize; +} + + + +// expects data already loaded, filename arg is for error printing only +// +qboolean MP3_FakeUpWAVInfo( const char *psLocalFilename, void *pvData, int iDataLen, int iUnpackedDataLength, int &format, int &rate, int &width, int &channels, int &samples, int &dataofs) +{ + // some things can be done instantly... + // + format = 1; // 1 for MS format + dataofs= 0; // will be 0 for me (since there's no header in the unpacked data) + + // some things need to be read... + // + char *psError = C_MP3_GetHeaderData(pvData, iDataLen, &rate, &width, &channels); + if (psError) + { + Com_Printf(va(S_COLOR_RED"%s\n(File: %s)\n",psError, psLocalFilename)); + } + + // and some stuff needs calculating... + // + samples = iUnpackedDataLength / width; + + + return !psError; + +} + + + +const char sKEY_MAXVOL[]="#MAXVOL"; // formerly #defines +const char sKEY_UNCOMP[]="#UNCOMP"; // " " + +// returns qtrue for success... +// +qboolean MP3_ReadSpecialTagInfo(byte *pbLoadedFile, int iLoadedFileLen, // (in) + id3v1_1** ppTAG, // (out), can be NULL + int *piUncompressedSize, float *pfMaxVol // (out), can be NULL + ) +{ + qboolean qbError = qfalse; + + id3v1_1* pTAG = (id3v1_1*) ((pbLoadedFile+iLoadedFileLen)-sizeof(id3v1_1)); // sizeof = 128 + + if (!strncmp(pTAG->id, "TAG", 3)) + { + // TAG found... + // + + // read MAXVOL key... + // + if (strncmp(pTAG->comment, sKEY_MAXVOL, strlen(sKEY_MAXVOL))) + { + qbError = qtrue; + } + else + { + if ( pfMaxVol) + { + *pfMaxVol = atof(pTAG->comment + strlen(sKEY_MAXVOL)); + } + } + + // + // read UNCOMP key... + // + if (strncmp(pTAG->album, sKEY_UNCOMP, strlen(sKEY_UNCOMP))) + { + qbError = qtrue; + } + else + { + if ( piUncompressedSize) + { + *piUncompressedSize = atoi(pTAG->album + strlen(sKEY_UNCOMP)); + } + } + } + else + { + pTAG = NULL; + } + + if (ppTAG) + { + *ppTAG = pTAG; + } + + return (pTAG && !qbError); +} + + + +qboolean TEST_MP3_GetUnpackedSize(const char *_FILENAME1, const char *_FILENAME2, const char *_FILENAME3, + void *data1,void *data2,void *data3, + int size1,int size2,int size3, + int *iUnpackedSize1,int *iUnpackedSize2,int *iUnpackedSize3 + ) +{ + char *psError = C_TEST_MP3_GetUnpackedSize(_FILENAME1, _FILENAME2, _FILENAME3, + data1,data2,data3, + size1,size2,size3, + iUnpackedSize1,iUnpackedSize2,iUnpackedSize3 + ); + + if (psError) + { + Com_Printf(va(S_COLOR_RED"%s\n",psError)); + return qfalse; + } + + return qtrue; +} + + +// expects data already loaded, filename arg is for error printing only +// +// returns byte count of unpacked data (effectively a success/fail bool) +// +qboolean TEST_MP3_UnpackRawPCM( const char *_FILENAME1, const char *_FILENAME2, const char *_FILENAME3, + void *data1,void *data2,void *data3, + int iSourceBytesRemaining1,int iSourceBytesRemaining2,int iSourceBytesRemaining3, + int *piUnpackedSize1,int *piUnpackedSize2,int *piUnpackedSize3, + void *pbUnpackBuffer1,void *pbUnpackBuffer2,void *pbUnpackBuffer3 + ) +{ + char *psError = C_TEST_MP3_UnpackRawPCM(_FILENAME1, _FILENAME2, _FILENAME3, + data1,data2,data3, + iSourceBytesRemaining1,iSourceBytesRemaining2,iSourceBytesRemaining3, + piUnpackedSize1,piUnpackedSize2,piUnpackedSize3, + pbUnpackBuffer1,pbUnpackBuffer2,pbUnpackBuffer3 + ); + if (psError) + { + Com_Printf(va(S_COLOR_RED"%s\n",psError)); + return qfalse; + } + + return qtrue; +} + + + + + +// a file has been loaded in memory, see if we want to keep it as MP3, else as normal WAV... +// +// return = qtrue if keeping as MP3 +// +// (note: the reason I pass in the unpacked size rather than working it out here is simply because I already have it) +// +qboolean MP3Stream_InitFromFile( sfx_t* sfx, byte *pbSrcData, int iSrcDatalen, const char *psSrcDataFilename, int iMP3UnPackedSize ) +{ + // first, make a decision based on size here as to whether or not it's worth it because of MP3 buffer space + // making small files much bigger (and therefore best left as WAV)... + // +#define FUZZY_AMOUNT (5*1024) // so it has to be significantly over, not just break even, because of + // the xtra CPU time versus memory saving + + if (iSrcDatalen + sizeof(MP3STREAM) + FUZZY_AMOUNT < iMP3UnPackedSize) + { + // ok, let's keep it as MP3 then... + // + + float fMaxVol = 128; // seems to be a reasonable typical default for maxvol (for lip synch). Naturally there's no #define I can use instead... + + MP3_ReadSpecialTagInfo(pbSrcData, iSrcDatalen, NULL, NULL, &fMaxVol ); // try and read a read maxvol from MP3 header + + // fill in some sfx_t fields... + // + sfx->eCompressionType = ct_MP3; + sfx->data = (byte*) Hunk_Alloc( iSrcDatalen ); // will err_drop if fails + memcpy ( sfx->data, pbSrcData, iSrcDatalen ); // ... so the -> data field is MP3, not PCM + sfx->width = 2;//(s_compression->value == 1)?1:2; + sfx->length = (iMP3UnPackedSize / sfx->width) / (44100 / dma.speed); + sfx->vol_range = fMaxVol; + + // now init the low-level MP3 stuff... + // + MP3STREAM SFX_MP3Stream = {0}; + char *psError = C_MP3Stream_DecodeInit( &SFX_MP3Stream, sfx->data, iSrcDatalen, + dma.speed,//(s_khz->value == 44)?44100:(s_khz->value == 22)?22050:11025, + sfx->width * 8 + ); + if (psError) + { + // This should never happen, since any errors or problems with the MP3 file would have stopped us getting + // to this whole function, but just in case... + // + Com_Printf(va(S_COLOR_YELLOW"File \"%s\": %s\n",psSrcDataFilename,psError)); + + // This will leave iSrcDatalen bytes on the hunk stack (since you can't dealloc that), but MP3 files are + // usually small, and like I say, it should never happen. + // + // Strictly speaking, I should do a Z_Malloc above, then I could do a Z_Free if failed, else do a Hunk_Alloc + // to copy the Z_Malloc data into, then Z_Free, but for something that shouldn't happen it seemed bad to + // penalise the rest of the game with extra malloc demands. + // + return qfalse; + } + + // success ( ...on a plate). + // + // make a copy of the filled-in stream struct and attach to the sfx_t struct... + // + sfx->pMP3StreamHeader = (MP3STREAM *) Hunk_Alloc( sizeof(MP3STREAM) ); + memcpy( sfx->pMP3StreamHeader, &SFX_MP3Stream, sizeof(MP3STREAM) ); + // + return qtrue; + } + + return qfalse; +} + + +// return is decoded byte count, else 0 for finished +// +int MP3Stream_Decode( LP_MP3STREAM lpMP3Stream ) +{ + lpMP3Stream->iCopyOffset = 0; + return C_MP3Stream_Decode( lpMP3Stream ); +} + +// returns qtrue for all ok +// +// (this can be optimised by copying the whole header from the sfx struct sometime) +// +qboolean MP3Stream_Rewind( channel_t *ch ) +{ +/* char *psError = C_MP3Stream_Rewind( lpMP3Stream ); + + if (psError) + { + Com_Printf(S_COLOR_YELLOW"%s\n",psError); + return qfalse; + } + + return qtrue; +*/ + memcpy(&ch->MP3StreamHeader, ch->sfx->pMP3StreamHeader, sizeof(ch->MP3StreamHeader)); + return qtrue; +} + +void MP3Stream_GetSamples( channel_t *ch, int startingSampleNum, int count, short *buf ) +{ + static const int iQuarterOfSlidingBuffer = sizeof(ch->MP3SlidingDecodeBuffer)/4; + static const int iThreeQuartersOfSlidingBuffer = (sizeof(ch->MP3SlidingDecodeBuffer)*3)/4; + +// Com_Printf("startingSampleNum %d\n",startingSampleNum); + + count *= ch->sfx->width; // count arg was for words, so double it for bytes; + + startingSampleNum *= ch->sfx->width; + + if ( startingSampleNum < ch->iMP3SlidingDecodeWindowPos) + { + // what?!?!?! Fucking time travel needed or something?, forget it + memset(buf,0,count); + return; + } + +// OutputDebugString(va("\nRequest: startingSampleNum %d, count %d\n",startingSampleNum,count)); +// OutputDebugString(va("WindowPos %d, WindowWritePos %d\n",ch->iMP3SlidingDecodeWindowPos,ch->iMP3SlidingDecodeWritePos)); + + while (! + ( + (startingSampleNum >= ch->iMP3SlidingDecodeWindowPos) + && + (startingSampleNum + count < ch->iMP3SlidingDecodeWindowPos + ch->iMP3SlidingDecodeWritePos) + ) + ) + { +// OutputDebugString("Scrolling..."); + + int _iBytesDecoded = MP3Stream_Decode( (LP_MP3STREAM) &ch->MP3StreamHeader ); +// OutputDebugString(va("%d bytes decoded\n",_iBytesDecoded)); + if (_iBytesDecoded == 0) + { + // no more source data left so clear the remainder of the buffer... + // + memset(ch->MP3SlidingDecodeBuffer + ch->iMP3SlidingDecodeWritePos, 0, sizeof(ch->MP3SlidingDecodeBuffer)-ch->iMP3SlidingDecodeWritePos); + //MP3Stream_Rewind(ch); // should I do this??? +// OutputDebugString("Finished\n"); + break; + } + else + { + memcpy(ch->MP3SlidingDecodeBuffer + ch->iMP3SlidingDecodeWritePos,ch->MP3StreamHeader.bDecodeBuffer,_iBytesDecoded); + + ch->iMP3SlidingDecodeWritePos += _iBytesDecoded; + + // if reached 3/4 of buffer pos, backscroll the decode window by one quarter... + // + if (ch->iMP3SlidingDecodeWritePos > (sizeof(ch->MP3SlidingDecodeBuffer)*3)/4) + { + memmove(ch->MP3SlidingDecodeBuffer, ((byte *)ch->MP3SlidingDecodeBuffer + (sizeof(ch->MP3SlidingDecodeBuffer)/4)), (sizeof(ch->MP3SlidingDecodeBuffer)*3)/4); + ch->iMP3SlidingDecodeWritePos -= sizeof(ch->MP3SlidingDecodeBuffer)/4; + ch->iMP3SlidingDecodeWindowPos+= sizeof(ch->MP3SlidingDecodeBuffer)/4; + } + } +// OutputDebugString(va("WindowPos %d, WindowWritePos %d\n",ch->iMP3SlidingDecodeWindowPos,ch->iMP3SlidingDecodeWritePos)); + } + + assert(startingSampleNum >= ch->iMP3SlidingDecodeWindowPos); + memcpy( buf, ch->MP3SlidingDecodeBuffer + (startingSampleNum-ch->iMP3SlidingDecodeWindowPos), count); + + +// OutputDebugString("OK\n"); +} + + +///////////// eof ///////////// + diff --git a/code/client/cl_ui.cpp b/code/client/cl_ui.cpp index c22b460..9ff0758 100644 --- a/code/client/cl_ui.cpp +++ b/code/client/cl_ui.cpp @@ -297,7 +297,7 @@ void CL_GenericMenu_f(void) { char *arg = Cmd_Argv( 1 ); - UI_SetActiveMenu("genericmenu",arg); + UI_SetActiveMenu("ingame",arg); } diff --git a/code/client/client.h b/code/client/client.h index 6945b7a..c3dc515 100644 --- a/code/client/client.h +++ b/code/client/client.h @@ -195,8 +195,10 @@ typedef struct { int framecount; int frametime; // msec since last frame + float frametimeFraction; // fraction of a msec since last frame int realtime; // ignores pause + float realtimeFraction; // fraction of a msec accumulated int realFrametime; // ignoring pause, so console always works // update server info diff --git a/code/client/eax/eax-util.cpp b/code/client/eax/eax-util.cpp deleted file mode 100644 index 769064c..0000000 --- a/code/client/eax/eax-util.cpp +++ /dev/null @@ -1,706 +0,0 @@ -/***********************************************************************************************\ -* * -* EAX-UTIL.CPP - utilities for EAX 3.0 * -* Function declaration for EAX Morphing * -* String names of the all the presets defined in eax-util.h * -* Arrays grouping together all the EAX presets in a scenario * -* * -************************************************************************************************/ - -#include "eax-util.h" -#include - -// Function prototypes used by EAX3ListenerInterpolate -void Clamp(EAXVECTOR *eaxVector); -bool CheckEAX3LP(LPEAXLISTENERPROPERTIES lpEAX3LP); - - -/***********************************************************************************************\ -* -* Definition of the EAXMorph function - EAX3ListenerInterpolate -* -\***********************************************************************************************/ - -/* - EAX3ListenerInterpolate - lpStart - Initial EAX 3 Listener parameters - lpFinish - Final EAX 3 Listener parameters - flRatio - Ratio Destination : Source (0.0 == Source, 1.0 == Destination) - lpResult - Interpolated EAX 3 Listener parameters - bCheckValues - Check EAX 3.0 parameters are in range, default = false (no checking) -*/ -bool EAX3ListenerInterpolate(LPEAXLISTENERPROPERTIES lpStart, LPEAXLISTENERPROPERTIES lpFinish, - float flRatio, LPEAXLISTENERPROPERTIES lpResult, bool bCheckValues) -{ - EAXVECTOR StartVector, FinalVector; - - float flInvRatio; - - if (bCheckValues) - { - if (!CheckEAX3LP(lpStart)) - return false; - - if (!CheckEAX3LP(lpFinish)) - return false; - } - - if (flRatio >= 1.0f) - { - memcpy(lpResult, lpFinish, sizeof(EAXLISTENERPROPERTIES)); - return true; - } - else if (flRatio <= 0.0f) - { - memcpy(lpResult, lpStart, sizeof(EAXLISTENERPROPERTIES)); - return true; - } - - flInvRatio = (1.0f - flRatio); - - // Environment - lpResult->ulEnvironment = 26; // (UNDEFINED environment) - - // Environment Size - if (lpStart->flEnvironmentSize == lpFinish->flEnvironmentSize) - lpResult->flEnvironmentSize = lpStart->flEnvironmentSize; - else - lpResult->flEnvironmentSize = (float)exp( (log(lpStart->flEnvironmentSize) * flInvRatio) + (log(lpFinish->flEnvironmentSize) * flRatio) ); - - // Environment Diffusion - if (lpStart->flEnvironmentDiffusion == lpFinish->flEnvironmentDiffusion) - lpResult->flEnvironmentDiffusion = lpStart->flEnvironmentDiffusion; - else - lpResult->flEnvironmentDiffusion = (lpStart->flEnvironmentDiffusion * flInvRatio) + (lpFinish->flEnvironmentDiffusion * flRatio); - - // Room - if (lpStart->lRoom == lpFinish->lRoom) - lpResult->lRoom = lpStart->lRoom; - else - lpResult->lRoom = (int)( ((float)lpStart->lRoom * flInvRatio) + ((float)lpFinish->lRoom * flRatio) ); - - // Room HF - if (lpStart->lRoomHF == lpFinish->lRoomHF) - lpResult->lRoomHF = lpStart->lRoomHF; - else - lpResult->lRoomHF = (int)( ((float)lpStart->lRoomHF * flInvRatio) + ((float)lpFinish->lRoomHF * flRatio) ); - - // Room LF - if (lpStart->lRoomLF == lpFinish->lRoomLF) - lpResult->lRoomLF = lpStart->lRoomLF; - else - lpResult->lRoomLF = (int)( ((float)lpStart->lRoomLF * flInvRatio) + ((float)lpFinish->lRoomLF * flRatio) ); - - // Decay Time - if (lpStart->flDecayTime == lpFinish->flDecayTime) - lpResult->flDecayTime = lpStart->flDecayTime; - else - lpResult->flDecayTime = (float)exp( (log(lpStart->flDecayTime) * flInvRatio) + (log(lpFinish->flDecayTime) * flRatio) ); - - // Decay HF Ratio - if (lpStart->flDecayHFRatio == lpFinish->flDecayHFRatio) - lpResult->flDecayHFRatio = lpStart->flDecayHFRatio; - else - lpResult->flDecayHFRatio = (float)exp( (log(lpStart->flDecayHFRatio) * flInvRatio) + (log(lpFinish->flDecayHFRatio) * flRatio) ); - - // Decay LF Ratio - if (lpStart->flDecayLFRatio == lpFinish->flDecayLFRatio) - lpResult->flDecayLFRatio = lpStart->flDecayLFRatio; - else - lpResult->flDecayLFRatio = (float)exp( (log(lpStart->flDecayLFRatio) * flInvRatio) + (log(lpFinish->flDecayLFRatio) * flRatio) ); - - // Reflections - if (lpStart->lReflections == lpFinish->lReflections) - lpResult->lReflections = lpStart->lReflections; - else - lpResult->lReflections = (int)( ((float)lpStart->lReflections * flInvRatio) + ((float)lpFinish->lReflections * flRatio) ); - - // Reflections Delay - if (lpStart->flReflectionsDelay == lpFinish->flReflectionsDelay) - lpResult->flReflectionsDelay = lpStart->flReflectionsDelay; - else - lpResult->flReflectionsDelay = (float)exp( (log(lpStart->flReflectionsDelay+0.0001) * flInvRatio) + (log(lpFinish->flReflectionsDelay+0.0001) * flRatio) ); - - // Reflections Pan - - // To interpolate the vector correctly we need to ensure that both the initial and final vectors vectors are clamped to a length of 1.0f - StartVector = lpStart->vReflectionsPan; - FinalVector = lpFinish->vReflectionsPan; - - Clamp(&StartVector); - Clamp(&FinalVector); - - if (lpStart->vReflectionsPan.x == lpFinish->vReflectionsPan.x) - lpResult->vReflectionsPan.x = lpStart->vReflectionsPan.x; - else - lpResult->vReflectionsPan.x = FinalVector.x + (flInvRatio * (StartVector.x - FinalVector.x)); - - if (lpStart->vReflectionsPan.y == lpFinish->vReflectionsPan.y) - lpResult->vReflectionsPan.y = lpStart->vReflectionsPan.y; - else - lpResult->vReflectionsPan.y = FinalVector.y + (flInvRatio * (StartVector.y - FinalVector.y)); - - if (lpStart->vReflectionsPan.z == lpFinish->vReflectionsPan.z) - lpResult->vReflectionsPan.z = lpStart->vReflectionsPan.z; - else - lpResult->vReflectionsPan.z = FinalVector.z + (flInvRatio * (StartVector.z - FinalVector.z)); - - // Reverb - if (lpStart->lReverb == lpFinish->lReverb) - lpResult->lReverb = lpStart->lReverb; - else - lpResult->lReverb = (int)( ((float)lpStart->lReverb * flInvRatio) + ((float)lpFinish->lReverb * flRatio) ); - - // Reverb Delay - if (lpStart->flReverbDelay == lpFinish->flReverbDelay) - lpResult->flReverbDelay = lpStart->flReverbDelay; - else - lpResult->flReverbDelay = (float)exp( (log(lpStart->flReverbDelay+0.0001) * flInvRatio) + (log(lpFinish->flReverbDelay+0.0001) * flRatio) ); - - // Reverb Pan - - // To interpolate the vector correctly we need to ensure that both the initial and final vectors are clamped to a length of 1.0f - StartVector = lpStart->vReverbPan; - FinalVector = lpFinish->vReverbPan; - - Clamp(&StartVector); - Clamp(&FinalVector); - - if (lpStart->vReverbPan.x == lpFinish->vReverbPan.x) - lpResult->vReverbPan.x = lpStart->vReverbPan.x; - else - lpResult->vReverbPan.x = FinalVector.x + (flInvRatio * (StartVector.x - FinalVector.x)); - - if (lpStart->vReverbPan.y == lpFinish->vReverbPan.y) - lpResult->vReverbPan.y = lpStart->vReverbPan.y; - else - lpResult->vReverbPan.y = FinalVector.y + (flInvRatio * (StartVector.y - FinalVector.y)); - - if (lpStart->vReverbPan.z == lpFinish->vReverbPan.z) - lpResult->vReverbPan.z = lpStart->vReverbPan.z; - else - lpResult->vReverbPan.z = FinalVector.z + (flInvRatio * (StartVector.z - FinalVector.z)); - - // Echo Time - if (lpStart->flEchoTime == lpFinish->flEchoTime) - lpResult->flEchoTime = lpStart->flEchoTime; - else - lpResult->flEchoTime = (float)exp( (log(lpStart->flEchoTime) * flInvRatio) + (log(lpFinish->flEchoTime) * flRatio) ); - - // Echo Depth - if (lpStart->flEchoDepth == lpFinish->flEchoDepth) - lpResult->flEchoDepth = lpStart->flEchoDepth; - else - lpResult->flEchoDepth = (lpStart->flEchoDepth * flInvRatio) + (lpFinish->flEchoDepth * flRatio); - - // Modulation Time - if (lpStart->flModulationTime == lpFinish->flModulationTime) - lpResult->flModulationTime = lpStart->flModulationTime; - else - lpResult->flModulationTime = (float)exp( (log(lpStart->flModulationTime) * flInvRatio) + (log(lpFinish->flModulationTime) * flRatio) ); - - // Modulation Depth - if (lpStart->flModulationDepth == lpFinish->flModulationDepth) - lpResult->flModulationDepth = lpStart->flModulationDepth; - else - lpResult->flModulationDepth = (lpStart->flModulationDepth * flInvRatio) + (lpFinish->flModulationDepth * flRatio); - - // Air Absorption HF - if (lpStart->flAirAbsorptionHF == lpFinish->flAirAbsorptionHF) - lpResult->flAirAbsorptionHF = lpStart->flAirAbsorptionHF; - else - lpResult->flAirAbsorptionHF = (lpStart->flAirAbsorptionHF * flInvRatio) + (lpFinish->flAirAbsorptionHF * flRatio); - - // HF Reference - if (lpStart->flHFReference == lpFinish->flHFReference) - lpResult->flHFReference = lpStart->flHFReference; - else - lpResult->flHFReference = (float)exp( (log(lpStart->flHFReference) * flInvRatio) + (log(lpFinish->flHFReference) * flRatio) ); - - // LF Reference - if (lpStart->flLFReference == lpFinish->flLFReference) - lpResult->flLFReference = lpStart->flLFReference; - else - lpResult->flLFReference = (float)exp( (log(lpStart->flLFReference) * flInvRatio) + (log(lpFinish->flLFReference) * flRatio) ); - - // Room Rolloff Factor - if (lpStart->flRoomRolloffFactor == lpFinish->flRoomRolloffFactor) - lpResult->flRoomRolloffFactor = lpStart->flRoomRolloffFactor; - else - lpResult->flRoomRolloffFactor = (lpStart->flRoomRolloffFactor * flInvRatio) + (lpFinish->flRoomRolloffFactor * flRatio); - - // Flags - lpResult->ulFlags = (lpStart->ulFlags & lpFinish->ulFlags); - - // Clamp Delays - if (lpResult->flReflectionsDelay > EAXLISTENER_MAXREFLECTIONSDELAY) - lpResult->flReflectionsDelay = EAXLISTENER_MAXREFLECTIONSDELAY; - - if (lpResult->flReverbDelay > EAXLISTENER_MAXREVERBDELAY) - lpResult->flReverbDelay = EAXLISTENER_MAXREVERBDELAY; - - return true; -} - - -/* - CheckEAX3LP - Checks that the parameters in the EAX 3 Listener Properties structure are in-range -*/ -bool CheckEAX3LP(LPEAXLISTENERPROPERTIES lpEAX3LP) -{ - if ( (lpEAX3LP->lRoom < EAXLISTENER_MINROOM) || (lpEAX3LP->lRoom > EAXLISTENER_MAXROOM) ) - return false; - - if ( (lpEAX3LP->lRoomHF < EAXLISTENER_MINROOMHF) || (lpEAX3LP->lRoomHF > EAXLISTENER_MAXROOMHF) ) - return false; - - if ( (lpEAX3LP->lRoomLF < EAXLISTENER_MINROOMLF) || (lpEAX3LP->lRoomLF > EAXLISTENER_MAXROOMLF) ) - return false; - - if ( (lpEAX3LP->ulEnvironment < EAXLISTENER_MINENVIRONMENT) || (lpEAX3LP->ulEnvironment > EAXLISTENER_MAXENVIRONMENT) ) - return false; - - if ( (lpEAX3LP->flEnvironmentSize < EAXLISTENER_MINENVIRONMENTSIZE) || (lpEAX3LP->flEnvironmentSize > EAXLISTENER_MAXENVIRONMENTSIZE) ) - return false; - - if ( (lpEAX3LP->flEnvironmentDiffusion < EAXLISTENER_MINENVIRONMENTDIFFUSION) || (lpEAX3LP->flEnvironmentDiffusion > EAXLISTENER_MAXENVIRONMENTDIFFUSION) ) - return false; - - if ( (lpEAX3LP->flDecayTime < EAXLISTENER_MINDECAYTIME) || (lpEAX3LP->flDecayTime > EAXLISTENER_MAXDECAYTIME) ) - return false; - - if ( (lpEAX3LP->flDecayHFRatio < EAXLISTENER_MINDECAYHFRATIO) || (lpEAX3LP->flDecayHFRatio > EAXLISTENER_MAXDECAYHFRATIO) ) - return false; - - if ( (lpEAX3LP->flDecayLFRatio < EAXLISTENER_MINDECAYLFRATIO) || (lpEAX3LP->flDecayLFRatio > EAXLISTENER_MAXDECAYLFRATIO) ) - return false; - - if ( (lpEAX3LP->lReflections < EAXLISTENER_MINREFLECTIONS) || (lpEAX3LP->lReflections > EAXLISTENER_MAXREFLECTIONS) ) - return false; - - if ( (lpEAX3LP->flReflectionsDelay < EAXLISTENER_MINREFLECTIONSDELAY) || (lpEAX3LP->flReflectionsDelay > EAXLISTENER_MAXREFLECTIONSDELAY) ) - return false; - - if ( (lpEAX3LP->lReverb < EAXLISTENER_MINREVERB) || (lpEAX3LP->lReverb > EAXLISTENER_MAXREVERB) ) - return false; - - if ( (lpEAX3LP->flReverbDelay < EAXLISTENER_MINREVERBDELAY) || (lpEAX3LP->flReverbDelay > EAXLISTENER_MAXREVERBDELAY) ) - return false; - - if ( (lpEAX3LP->flEchoTime < EAXLISTENER_MINECHOTIME) || (lpEAX3LP->flEchoTime > EAXLISTENER_MAXECHOTIME) ) - return false; - - if ( (lpEAX3LP->flEchoDepth < EAXLISTENER_MINECHODEPTH) || (lpEAX3LP->flEchoDepth > EAXLISTENER_MAXECHODEPTH) ) - return false; - - if ( (lpEAX3LP->flModulationTime < EAXLISTENER_MINMODULATIONTIME) || (lpEAX3LP->flModulationTime > EAXLISTENER_MAXMODULATIONTIME) ) - return false; - - if ( (lpEAX3LP->flModulationDepth < EAXLISTENER_MINMODULATIONDEPTH) || (lpEAX3LP->flModulationDepth > EAXLISTENER_MAXMODULATIONDEPTH) ) - return false; - - if ( (lpEAX3LP->flAirAbsorptionHF < EAXLISTENER_MINAIRABSORPTIONHF) || (lpEAX3LP->flAirAbsorptionHF > EAXLISTENER_MAXAIRABSORPTIONHF) ) - return false; - - if ( (lpEAX3LP->flHFReference < EAXLISTENER_MINHFREFERENCE) || (lpEAX3LP->flHFReference > EAXLISTENER_MAXHFREFERENCE) ) - return false; - - if ( (lpEAX3LP->flLFReference < EAXLISTENER_MINLFREFERENCE) || (lpEAX3LP->flLFReference > EAXLISTENER_MAXLFREFERENCE) ) - return false; - - if ( (lpEAX3LP->flRoomRolloffFactor < EAXLISTENER_MINROOMROLLOFFFACTOR) || (lpEAX3LP->flRoomRolloffFactor > EAXLISTENER_MAXROOMROLLOFFFACTOR) ) - return false; - - if (lpEAX3LP->ulFlags & EAXLISTENERFLAGS_RESERVED) - return false; - - return true; -} - -/* - Clamp - Clamps the length of the vector to 1.0f -*/ -void Clamp(EAXVECTOR *eaxVector) -{ - float flMagnitude; - float flInvMagnitude; - - flMagnitude = (float)sqrt((eaxVector->x*eaxVector->x) + (eaxVector->y*eaxVector->y) + (eaxVector->z*eaxVector->z)); - - if (flMagnitude <= 1.0f) - return; - - flInvMagnitude = 1.0f / flMagnitude; - - eaxVector->x *= flInvMagnitude; - eaxVector->y *= flInvMagnitude; - eaxVector->z *= flInvMagnitude; -} - - -/***********************************************************************************************\ -* -* To assist those developers wishing to add EAX effects to their level editors, each of the - -* List of string names of the various EAX 3.0 presets defined in eax-util.h -* Arrays to group together presets of the same scenario -* -\***********************************************************************************************/ - - -////////////////////////////////////////////////////// -// Array of scenario names // -////////////////////////////////////////////////////// - -char* EAX30_SCENARIO_NAMES[] = -{ - "Castle", - "Factory", - "IcePalace", - "SpaceStation", - "WoodenShip", - "Sports", - "Prefab", - "Domes and Pipes", - "Outdoors", - "Mood", - "Driving", - "City", - "Miscellaneous", - "Original" -}; - -////////////////////////////////////////////////////// -// Array of standardised location names // -////////////////////////////////////////////////////// - -char* EAX30_LOCATION_NAMES[] = -{ - "Hall", - "Large Room", - "Medium Room", - "Small Room", - "Cupboard", - "Alcove", - "Long Passage", - "Short Passage", - "Courtyard" -}; - -////////////////////////////////////////////////////// -// Standardised Location effects can be accessed // -// from a matrix // -////////////////////////////////////////////////////// - -EAXLISTENERPROPERTIES EAX30_STANDARD_PRESETS[EAX30_NUM_STANDARD_SCENARIOS][EAX30_NUM_LOCATIONS]= -{ - {EAX30_PRESET_CASTLE_HALL, EAX30_PRESET_CASTLE_LARGEROOM, EAX30_PRESET_CASTLE_MEDIUMROOM, EAX30_PRESET_CASTLE_SMALLROOM, EAX30_PRESET_CASTLE_CUPBOARD, EAX30_PRESET_CASTLE_ALCOVE, EAX30_PRESET_CASTLE_LONGPASSAGE, EAX30_PRESET_CASTLE_SHORTPASSAGE, EAX30_PRESET_CASTLE_COURTYARD}, - {EAX30_PRESET_FACTORY_HALL, EAX30_PRESET_FACTORY_LARGEROOM, EAX30_PRESET_FACTORY_MEDIUMROOM, EAX30_PRESET_FACTORY_SMALLROOM, EAX30_PRESET_FACTORY_CUPBOARD, EAX30_PRESET_FACTORY_ALCOVE, EAX30_PRESET_FACTORY_LONGPASSAGE, EAX30_PRESET_FACTORY_SHORTPASSAGE, EAX30_PRESET_FACTORY_COURTYARD}, - {EAX30_PRESET_ICEPALACE_HALL, EAX30_PRESET_ICEPALACE_LARGEROOM, EAX30_PRESET_ICEPALACE_MEDIUMROOM, EAX30_PRESET_ICEPALACE_SMALLROOM, EAX30_PRESET_ICEPALACE_CUPBOARD, EAX30_PRESET_ICEPALACE_ALCOVE, EAX30_PRESET_ICEPALACE_LONGPASSAGE, EAX30_PRESET_ICEPALACE_SHORTPASSAGE, EAX30_PRESET_ICEPALACE_COURTYARD}, - {EAX30_PRESET_SPACESTATION_HALL,EAX30_PRESET_SPACESTATION_LARGEROOM,EAX30_PRESET_SPACESTATION_MEDIUMROOM, EAX30_PRESET_SPACESTATION_SMALLROOM,EAX30_PRESET_SPACESTATION_CUPBOARD, EAX30_PRESET_SPACESTATION_ALCOVE, EAX30_PRESET_SPACESTATION_LONGPASSAGE, EAX30_PRESET_SPACESTATION_SHORTPASSAGE, EAX30_PRESET_SPACESTATION_HALL}, - {EAX30_PRESET_WOODEN_HALL, EAX30_PRESET_WOODEN_LARGEROOM, EAX30_PRESET_WOODEN_MEDIUMROOM, EAX30_PRESET_WOODEN_SMALLROOM, EAX30_PRESET_WOODEN_CUPBOARD, EAX30_PRESET_WOODEN_ALCOVE, EAX30_PRESET_WOODEN_LONGPASSAGE, EAX30_PRESET_WOODEN_SHORTPASSAGE, EAX30_PRESET_WOODEN_COURTYARD}, -}; - - -/********************************************************************************************************/ - -////////////////////////////////////////////////////// -// Array of original environment names // -////////////////////////////////////////////////////// - -char* EAX30_ORIGINAL_PRESET_NAMES[] = -{ - "Generic", - "Padded Cell", - "Room", - "Bathroom", - "Living Room", - "Stone Room", - "Auditorium", - "Concert Hall", - "Cave", - "Arena", - "Hangar", - "Carpetted Hallway", - "Hallway", - "Stone Corridor", - "Alley", - "Forest", - "City", - "Mountains", - "Quarry", - "Plain", - "Parking Lot", - "Sewer Pipe", - "Underwater", - "Drugged", - "Dizzy", - "Psychotic" -}; - -////////////////////////////////////////////////////// -// Sports effects matrix // -////////////////////////////////////////////////////// - -EAXLISTENERPROPERTIES EAX30_ORIGINAL_PRESETS[] = -{ - EAX30_PRESET_GENERIC, - EAX30_PRESET_PADDEDCELL, - EAX30_PRESET_ROOM, - EAX30_PRESET_BATHROOM, - EAX30_PRESET_LIVINGROOM, - EAX30_PRESET_STONEROOM, - EAX30_PRESET_AUDITORIUM, - EAX30_PRESET_CONCERTHALL, - EAX30_PRESET_CAVE, - EAX30_PRESET_ARENA, - EAX30_PRESET_HANGAR, - EAX30_PRESET_CARPETTEDHALLWAY, - EAX30_PRESET_HALLWAY, - EAX30_PRESET_STONECORRIDOR, - EAX30_PRESET_ALLEY, - EAX30_PRESET_FOREST, - EAX30_PRESET_CITY, - EAX30_PRESET_MOUNTAINS, - EAX30_PRESET_QUARRY, - EAX30_PRESET_PLAIN, - EAX30_PRESET_PARKINGLOT, - EAX30_PRESET_SEWERPIPE, - EAX30_PRESET_UNDERWATER, - EAX30_PRESET_DRUGGED, - EAX30_PRESET_DIZZY, - EAX30_PRESET_PSYCHOTIC -}; - -/********************************************************************************************************/ - -////////////////////////////////////////////////////// -// Array of sport environment names // -////////////////////////////////////////////////////// - -char* EAX30_SPORTS_PRESET_NAMES[] = -{ - "Empty Stadium", - "Full Stadium", - "Stadium Tannoy", - "Squash Court", - "Small Swimming Pool", - "Large Swimming Pool", - "Gymnasium" -}; - -////////////////////////////////////////////////////// -// Sports effects matrix // -////////////////////////////////////////////////////// - -EAXLISTENERPROPERTIES EAX30_SPORTS_PRESETS[] = -{ - EAX30_PRESET_SPORT_EMPTYSTADIUM, - EAX30_PRESET_SPORT_FULLSTADIUM, - EAX30_PRESET_SPORT_STADIUMTANNOY, - EAX30_PRESET_SPORT_SQUASHCOURT, - EAX30_PRESET_SPORT_SMALLSWIMMINGPOOL, - EAX30_PRESET_SPORT_LARGESWIMMINGPOOL, - EAX30_PRESET_SPORT_GYMNASIUM -}; - -/********************************************************************************************************/ - -////////////////////////////////////////////////////// -// Array of prefab environment names // -////////////////////////////////////////////////////// - -char* EAX30_PREFAB_PRESET_NAMES[] = -{ - "Workshop", - "School Room", - "Practise Room", - "Outhouse", - "Caravan" -}; - -////////////////////////////////////////////////////// -// Prefab effects matrix // -////////////////////////////////////////////////////// - -EAXLISTENERPROPERTIES EAX30_PREFAB_PRESETS[] = -{ - EAX30_PRESET_PREFAB_WORKSHOP, - EAX30_PRESET_PREFAB_SCHOOLROOM, - EAX30_PRESET_PREFAB_PRACTISEROOM, - EAX30_PRESET_PREFAB_OUTHOUSE, - EAX30_PRESET_PREFAB_CARAVAN -}; - -/********************************************************************************************************/ - -////////////////////////////////////////////////////// -// Array of Domes & Pipes environment names // -////////////////////////////////////////////////////// - -char* EAX30_DOMESNPIPES_PRESET_NAMES[] = -{ - "Domed Tomb", - "Saint Paul's Dome", - "Small Pipe", - "Long Thin Pipe", - "Large Pipe", - "Resonant Pipe" -}; - -////////////////////////////////////////////////////// -// Domes & Pipes effects matrix // -////////////////////////////////////////////////////// - -EAXLISTENERPROPERTIES EAX30_DOMESNPIPES_PRESETS[] = -{ - EAX30_PRESET_DOME_TOMB, - EAX30_PRESET_DOME_SAINTPAULS, - EAX30_PRESET_PIPE_SMALL, - EAX30_PRESET_PIPE_LONGTHIN, - EAX30_PRESET_PIPE_LARGE, - EAX30_PRESET_PIPE_RESONANT -}; - -/********************************************************************************************************/ - -////////////////////////////////////////////////////// -// Array of Outdoors environment names // -////////////////////////////////////////////////////// - -char* EAX30_OUTDOORS_PRESET_NAMES[] = -{ - "Backyard", - "Rolling Plains", - "Deep Canyon", - "Creek", - "Valley" -}; - -////////////////////////////////////////////////////// -// Outdoors effects matrix // -////////////////////////////////////////////////////// - -EAXLISTENERPROPERTIES EAX30_OUTDOORS_PRESETS[] = -{ - EAX30_PRESET_OUTDOORS_BACKYARD, - EAX30_PRESET_OUTDOORS_ROLLINGPLAINS, - EAX30_PRESET_OUTDOORS_DEEPCANYON, - EAX30_PRESET_OUTDOORS_CREEK, - EAX30_PRESET_OUTDOORS_VALLEY -}; - -/********************************************************************************************************/ - -////////////////////////////////////////////////////// -// Array of Mood environment names // -////////////////////////////////////////////////////// - -char* EAX30_MOOD_PRESET_NAMES[] = -{ - "Heaven", - "Hell", - "Memory" -}; - -////////////////////////////////////////////////////// -// Mood effects matrix // -////////////////////////////////////////////////////// - -EAXLISTENERPROPERTIES EAX30_MOOD_PRESETS[] = -{ - EAX30_PRESET_MOOD_HEAVEN, - EAX30_PRESET_MOOD_HELL, - EAX30_PRESET_MOOD_MEMORY -}; - -/********************************************************************************************************/ - -////////////////////////////////////////////////////// -// Array of driving environment names // -////////////////////////////////////////////////////// - -char* EAX30_DRIVING_PRESET_NAMES[] = -{ - "Race Commentator", - "Pit Garage", - "In-car (Stripped out racer)", - "In-car (Sportscar)", - "In-car (Luxury)", - "Full Grandstand", - "Empty Grandstand", - "Tunnel" -}; - -////////////////////////////////////////////////////// -// Driving effects matrix // -////////////////////////////////////////////////////// - -EAXLISTENERPROPERTIES EAX30_DRIVING_PRESETS[] = -{ - EAX30_PRESET_DRIVING_COMMENTATOR, - EAX30_PRESET_DRIVING_PITGARAGE, - EAX30_PRESET_DRIVING_INCAR_RACER, - EAX30_PRESET_DRIVING_INCAR_SPORTS, - EAX30_PRESET_DRIVING_INCAR_LUXURY, - EAX30_PRESET_DRIVING_FULLGRANDSTAND, - EAX30_PRESET_DRIVING_EMPTYGRANDSTAND, - EAX30_PRESET_DRIVING_TUNNEL -}; - -/********************************************************************************************************/ - -////////////////////////////////////////////////////// -// Array of City environment names // -////////////////////////////////////////////////////// - -char* EAX30_CITY_PRESET_NAMES[] = -{ - "City Streets", - "Subway", - "Museum", - "Library", - "Underpass", - "Abandoned City" -}; - -////////////////////////////////////////////////////// -// City effects matrix // -////////////////////////////////////////////////////// - -EAXLISTENERPROPERTIES EAX30_CITY_PRESETS[] = -{ - EAX30_PRESET_CITY_STREETS, - EAX30_PRESET_CITY_SUBWAY, - EAX30_PRESET_CITY_MUSEUM, - EAX30_PRESET_CITY_LIBRARY, - EAX30_PRESET_CITY_UNDERPASS, - EAX30_PRESET_CITY_ABANDONED -}; - -/********************************************************************************************************/ - -////////////////////////////////////////////////////// -// Array of Misc environment names // -////////////////////////////////////////////////////// - -char* EAX30_MISC_PRESET_NAMES[] = -{ - "Dusty Box Room", - "Chapel", - "Small Water Room" -}; - -////////////////////////////////////////////////////// -// Misc effects matrix // -////////////////////////////////////////////////////// - -EAXLISTENERPROPERTIES EAX30_MISC_PRESETS[] = -{ - EAX30_PRESET_DUSTYROOM, - EAX30_PRESET_CHAPEL, - EAX30_PRESET_SMALLWATERROOM -}; - diff --git a/code/client/eax/eax-util.h b/code/client/eax/eax-util.h deleted file mode 100644 index ef917d5..0000000 --- a/code/client/eax/eax-util.h +++ /dev/null @@ -1,765 +0,0 @@ -/*******************************************************************\ -* * -* EAX-UTIL.H - utilities for Environmental Audio Extensions v. 3.0 * -* Definitions of the Original 26 EAX Presets * -* Definitions for some new EAX Presets * -* Definitions of some Material Presets * -* Function declaration for EAX Morphing * -* * -\*******************************************************************/ - -#ifndef EAXUTIL_INCLUDED -#define EAXUTIL_INCLUDED - -#include "eax.h" - -/*********************************************************************************************** -* Function : EAX3ListenerInterpolate -* Params : lpStart - Initial EAX 3 Listener parameters -* : lpFinish - Final EAX 3 Listener parameters -* : flRatio - Ratio Destination : Source (0.0 == Source, 1.0 == Destination) -* : lpResult - Interpolated EAX 3 Listener parameters -* : bCheckValues - Check EAX 3.0 parameters are in range, - - default == false (no checking) -************************************************************************************************/ -bool EAX3ListenerInterpolate(EAXLISTENERPROPERTIES *lpStartEAX3LP, EAXLISTENERPROPERTIES *lpFinishEAX3LP, - float flRatio, EAXLISTENERPROPERTIES *lpResultEAX3LP, bool bCheckValues = false); - - -/***********************************************************************************************\ -* -* Legacy environment presets for use with DSPROPERTY_EAXLISTENER_ALLPARAMETERS. -* Each array conforms to the DSPROPSETID_EAX30_ListenerProperties structure defined in EAX.H. -* -************************************************************************************************/ - -// Env Size Diffus Room RoomHF RoomLF DecTm DcHF DcLF Refl RefDel Ref Pan Revb RevDel Rev Pan EchTm EchDp ModTm ModDp AirAbs HFRef LFRef RRlOff FLAGS -#define EAX30_PRESET_GENERIC \ - {0, 7.5f, 1.000f, -1000, -100, 0, 1.49f, 0.83f, 1.00f, -2602, 0.007f, 0.00f,0.00f,0.00f, 200, 0.011f, 0.00f,0.00f,0.00f, 0.250f, 0.000f, 0.250f, 0.000f, -5.0f, 5000.0f, 250.0f, 0.00f, 0x3f } -#define EAX30_PRESET_PADDEDCELL \ - {1, 1.4f, 1.000f, -1000, -6000, 0, 0.17f, 0.10f, 1.00f, -1204, 0.001f, 0.00f,0.00f,0.00f, 207, 0.002f, 0.00f,0.00f,0.00f, 0.250f, 0.000f, 0.250f, 0.000f, -5.0f, 5000.0f, 250.0f, 0.00f, 0x3f } -#define EAX30_PRESET_ROOM \ - {2, 1.9f, 1.000f, -1000, -454, 0, 0.40f, 0.83f, 1.00f, -1646, 0.002f, 0.00f,0.00f,0.00f, 53, 0.003f, 0.00f,0.00f,0.00f, 0.250f, 0.000f, 0.250f, 0.000f, -5.0f, 5000.0f, 250.0f, 0.00f, 0x3f } -#define EAX30_PRESET_BATHROOM \ - {3, 1.4f, 1.000f, -1000, -1200, 0, 1.49f, 0.54f, 1.00f, -370, 0.007f, 0.00f,0.00f,0.00f, 1030, 0.011f, 0.00f,0.00f,0.00f, 0.250f, 0.000f, 0.250f, 0.000f, -5.0f, 5000.0f, 250.0f, 0.00f, 0x3f } -#define EAX30_PRESET_LIVINGROOM \ - {4, 2.5f, 1.000f, -1000, -6000, 0, 0.50f, 0.10f, 1.00f, -1376, 0.003f, 0.00f,0.00f,0.00f, -1104, 0.004f, 0.00f,0.00f,0.00f, 0.250f, 0.000f, 0.250f, 0.000f, -5.0f, 5000.0f, 250.0f, 0.00f, 0x3f } -#define EAX30_PRESET_STONEROOM \ - {5, 11.6f, 1.000f, -1000, -300, 0, 2.31f, 0.64f, 1.00f, -711, 0.012f, 0.00f,0.00f,0.00f, 83, 0.017f, 0.00f,0.00f,0.00f, 0.250f, 0.000f, 0.250f, 0.000f, -5.0f, 5000.0f, 250.0f, 0.00f, 0x3f } -#define EAX30_PRESET_AUDITORIUM \ - {6, 21.6f, 1.000f, -1000, -476, 0, 4.32f, 0.59f, 1.00f, -789, 0.020f, 0.00f,0.00f,0.00f, -289, 0.030f, 0.00f,0.00f,0.00f, 0.250f, 0.000f, 0.250f, 0.000f, -5.0f, 5000.0f, 250.0f, 0.00f, 0x3f } -#define EAX30_PRESET_CONCERTHALL \ - {7, 19.6f, 1.000f, -1000, -500, 0, 3.92f, 0.70f, 1.00f, -1230, 0.020f, 0.00f,0.00f,0.00f, -02, 0.029f, 0.00f,0.00f,0.00f, 0.250f, 0.000f, 0.250f, 0.000f, -5.0f, 5000.0f, 250.0f, 0.00f, 0x3f } -#define EAX30_PRESET_CAVE \ - {8, 14.6f, 1.000f, -1000, 0, 0, 2.91f, 1.30f, 1.00f, -602, 0.015f, 0.00f,0.00f,0.00f, -302, 0.022f, 0.00f,0.00f,0.00f, 0.250f, 0.000f, 0.250f, 0.000f, -5.0f, 5000.0f, 250.0f, 0.00f, 0x1f } -#define EAX30_PRESET_ARENA \ - {9, 36.2f, 1.000f, -1000, -698, 0, 7.24f, 0.33f, 1.00f, -1166, 0.020f, 0.00f,0.00f,0.00f, 16, 0.030f, 0.00f,0.00f,0.00f, 0.250f, 0.000f, 0.250f, 0.000f, -5.0f, 5000.0f, 250.0f, 0.00f, 0x3f } -#define EAX30_PRESET_HANGAR \ - {10, 50.3f, 1.000f, -1000, -1000, 0, 10.05f, 0.23f, 1.00f, -602, 0.020f, 0.00f,0.00f,0.00f, 198, 0.030f, 0.00f,0.00f,0.00f, 0.250f, 0.000f, 0.250f, 0.000f, -5.0f, 5000.0f, 250.0f, 0.00f, 0x3f } -#define EAX30_PRESET_CARPETTEDHALLWAY \ - {11, 1.9f, 1.000f, -1000, -4000, 0, 0.30f, 0.10f, 1.00f, -1831, 0.002f, 0.00f,0.00f,0.00f, -1630, 0.030f, 0.00f,0.00f,0.00f, 0.250f, 0.000f, 0.250f, 0.000f, -5.0f, 5000.0f, 250.0f, 0.00f, 0x3f } -#define EAX30_PRESET_HALLWAY \ - {12, 1.8f, 1.000f, -1000, -300, 0, 1.49f, 0.59f, 1.00f, -1219, 0.007f, 0.00f,0.00f,0.00f, 441, 0.011f, 0.00f,0.00f,0.00f, 0.250f, 0.000f, 0.250f, 0.000f, -5.0f, 5000.0f, 250.0f, 0.00f, 0x3f } -#define EAX30_PRESET_STONECORRIDOR \ - {13, 13.5f, 1.000f, -1000, -237, 0, 2.70f, 0.79f, 1.00f, -1214, 0.013f, 0.00f,0.00f,0.00f, 395, 0.020f, 0.00f,0.00f,0.00f, 0.250f, 0.000f, 0.250f, 0.000f, -5.0f, 5000.0f, 250.0f, 0.00f, 0x3f } -#define EAX30_PRESET_ALLEY \ - {14, 7.5f, 0.300f, -1000, -270, 0, 1.49f, 0.86f, 1.00f, -1204, 0.007f, 0.00f,0.00f,0.00f, -4, 0.011f, 0.00f,0.00f,0.00f, 0.125f, 0.950f, 0.250f, 0.000f, -5.0f, 5000.0f, 250.0f, 0.00f, 0x3f } -#define EAX30_PRESET_FOREST \ - {15, 38.0f, 0.300f, -1000, -3300, 0, 1.49f, 0.54f, 1.00f, -2560, 0.162f, 0.00f,0.00f,0.00f, -229, 0.088f, 0.00f,0.00f,0.00f, 0.125f, 1.000f, 0.250f, 0.000f, -5.0f, 5000.0f, 250.0f, 0.00f, 0x3f } -#define EAX30_PRESET_CITY \ - {16, 7.5f, 0.500f, -1000, -800, 0, 1.49f, 0.67f, 1.00f, -2273, 0.007f, 0.00f,0.00f,0.00f, -1691, 0.011f, 0.00f,0.00f,0.00f, 0.250f, 0.000f, 0.250f, 0.000f, -5.0f, 5000.0f, 250.0f, 0.00f, 0x3f } -#define EAX30_PRESET_MOUNTAINS \ - {17, 100.0f, 0.270f, -1000, -2500, 0, 1.49f, 0.21f, 1.00f, -2780, 0.300f, 0.00f,0.00f,0.00f, -1434, 0.100f, 0.00f,0.00f,0.00f, 0.250f, 1.000f, 0.250f, 0.000f, -5.0f, 5000.0f, 250.0f, 0.00f, 0x1f } -#define EAX30_PRESET_QUARRY \ - {18, 17.5f, 1.000f, -1000, -1000, 0, 1.49f, 0.83f, 1.00f, -10000, 0.061f, 0.00f,0.00f,0.00f, 500, 0.025f, 0.00f,0.00f,0.00f, 0.125f, 0.700f, 0.250f, 0.000f, -5.0f, 5000.0f, 250.0f, 0.00f, 0x3f } -#define EAX30_PRESET_PLAIN \ - {19, 42.5f, 0.210f, -1000, -2000, 0, 1.49f, 0.50f, 1.00f, -2466, 0.179f, 0.00f,0.00f,0.00f, -1926, 0.100f, 0.00f,0.00f,0.00f, 0.250f, 1.000f, 0.250f, 0.000f, -5.0f, 5000.0f, 250.0f, 0.00f, 0x3f } -#define EAX30_PRESET_PARKINGLOT \ - {20, 8.3f, 1.000f, -1000, 0, 0, 1.65f, 1.50f, 1.00f, -1363, 0.008f, 0.00f,0.00f,0.00f, -1153, 0.012f, 0.00f,0.00f,0.00f, 0.250f, 0.000f, 0.250f, 0.000f, -5.0f, 5000.0f, 250.0f, 0.00f, 0x1f } -#define EAX30_PRESET_SEWERPIPE \ - {21, 1.7f, 0.800f, -1000, -1000, 0, 2.81f, 0.14f, 1.00f, 429, 0.014f, 0.00f,0.00f,0.00f, 1023, 0.021f, 0.00f,0.00f,0.00f, 0.250f, 0.000f, 0.250f, 0.000f, -5.0f, 5000.0f, 250.0f, 0.00f, 0x3f } -#define EAX30_PRESET_UNDERWATER \ - {22, 1.8f, 1.000f, -1000, -4000, 0, 1.49f, 0.10f, 1.00f, -449, 0.007f, 0.00f,0.00f,0.00f, 1700, 0.011f, 0.00f,0.00f,0.00f, 0.250f, 0.000f, 1.180f, 0.348f, -5.0f, 5000.0f, 250.0f, 0.00f, 0x3f } -#define EAX30_PRESET_DRUGGED \ - {23, 1.9f, 0.500f, -1000, 0, 0, 8.39f, 1.39f, 1.00f, -115, 0.002f, 0.00f,0.00f,0.00f, 985, 0.030f, 0.00f,0.00f,0.00f, 0.250f, 0.000f, 0.250f, 1.000f, -5.0f, 5000.0f, 250.0f, 0.00f, 0x1f } -#define EAX30_PRESET_DIZZY \ - {24, 1.8f, 0.600f, -1000, -400, 0, 17.23f, 0.56f, 1.00f, -1713, 0.020f, 0.00f,0.00f,0.00f, -613, 0.030f, 0.00f,0.00f,0.00f, 0.250f, 1.000f, 0.810f, 0.310f, -5.0f, 5000.0f, 250.0f, 0.00f, 0x1f } -#define EAX30_PRESET_PSYCHOTIC \ - {25, 1.0f, 0.500f, -1000, -151, 0, 7.56f, 0.91f, 1.00f, -626, 0.020f, 0.00f,0.00f,0.00f, 774, 0.030f, 0.00f,0.00f,0.00f, 0.250f, 0.000f, 4.000f, 1.000f, -5.0f, 5000.0f, 250.0f, 0.00f, 0x1f } - - -/***********************************************************************************************\ -* -* New environment presets for use with DSPROPERTY_EAXLISTENER_ALLPARAMETERS. -* Each array conforms to the DSPROPSETID_EAX30_ListenerProperties structure defined in EAX.H. -* -************************************************************************************************/ - -// STANDARDISED-LOCATION SCENARIOS - -// CASTLE PRESETS - -// Env Size Diffus Room RoomHF RoomLF DecTm DcHF DcLF Refl RefDel Ref Pan Revb RevDel Rev Pan EchTm EchDp ModTm ModDp AirAbs HFRef LFRef RRlOff FLAGS -#define EAX30_PRESET_CASTLE_SMALLROOM \ - { 26, 8.3f, 0.890f, -1100, -800, -2000, 1.22f, 0.83f, 0.31f, -100, 0.022f, 0.00f,0.00f,0.00f, 0, 0.011f, 0.00f,0.00f,0.00f, 0.138f, 0.080f, 0.250f, 0.000f, -5.0f, 5168.6f, 139.5f, 0.00f, 0x20 } -#define EAX30_PRESET_CASTLE_SHORTPASSAGE \ - { 26, 8.3f, 0.890f, -1000, -1000, -2000, 2.32f, 0.83f, 0.31f, -100, 0.007f, 0.00f,0.00f,0.00f, -500, 0.023f, 0.00f,0.00f,0.00f, 0.138f, 0.080f, 0.250f, 0.000f, -5.0f, 5168.6f, 139.5f, 0.00f, 0x20 } -#define EAX30_PRESET_CASTLE_MEDIUMROOM \ - { 26, 8.3f, 0.930f, -1000, -1100, -2000, 2.04f, 0.83f, 0.46f, -300, 0.022f, 0.00f,0.00f,0.00f, -200, 0.011f, 0.00f,0.00f,0.00f, 0.155f, 0.030f, 0.250f, 0.000f, -5.0f, 5168.6f, 139.5f, 0.00f, 0x20 } -#define EAX30_PRESET_CASTLE_LONGPASSAGE \ - { 26, 8.3f, 0.890f, -1000, -800, -2000, 3.42f, 0.83f, 0.31f, -200, 0.007f, 0.00f,0.00f,0.00f, -600, 0.023f, 0.00f,0.00f,0.00f, 0.138f, 0.080f, 0.250f, 0.000f, -5.0f, 5168.6f, 139.5f, 0.00f, 0x20 } -#define EAX30_PRESET_CASTLE_LARGEROOM \ - { 26, 8.3f, 0.820f, -1000, -1100, -1800, 2.53f, 0.83f, 0.50f, -900, 0.034f, 0.00f,0.00f,0.00f, -400, 0.016f, 0.00f,0.00f,0.00f, 0.185f, 0.070f, 0.250f, 0.000f, -5.0f, 5168.6f, 139.5f, 0.00f, 0x20 } -#define EAX30_PRESET_CASTLE_HALL \ - { 26, 8.3f, 0.810f, -1000, -1100, -1500, 3.14f, 0.79f, 0.62f, -1300, 0.056f, 0.00f,0.00f,0.00f, -500, 0.024f, 0.00f,0.00f,0.00f, 0.250f, 0.000f, 0.250f, 0.000f, -5.0f, 5168.6f, 139.5f, 0.00f, 0x20 } -#define EAX30_PRESET_CASTLE_CUPBOARD \ - { 26, 8.3f, 0.890f, -1000, -1100, -2000, 0.67f, 0.87f, 0.31f, 300, 0.010f, 0.00f,0.00f,0.00f, 300, 0.007f, 0.00f,0.00f,0.00f, 0.138f, 0.080f, 0.250f, 0.000f, -5.0f, 5168.6f, 139.5f, 0.00f, 0x20 } -#define EAX30_PRESET_CASTLE_COURTYARD \ - { 26, 8.3f, 0.420f, -1100, -700, -900, 2.13f, 0.61f, 0.23f, -2300, 0.112f, 0.00f,0.00f,0.00f, -1500, 0.036f, 0.00f,0.00f,0.00f, 0.250f, 0.370f, 0.250f, 0.000f, -0.0f, 5000.0f, 250.0f, 0.00f, 0x1f } -#define EAX30_PRESET_CASTLE_ALCOVE \ - { 26, 8.3f, 0.890f, -1000, -600, -2000, 1.64f, 0.87f, 0.31f, -100, 0.007f, 0.00f,0.00f,0.00f, -500, 0.034f, 0.00f,0.00f,0.00f, 0.138f, 0.080f, 0.250f, 0.000f, -5.0f, 5168.6f, 139.5f, 0.00f, 0x20 } - - -// FACTORY PRESETS - -// Env Size Diffus Room RoomHF RoomLF DecTm DcHF DcLF Refl RefDel Ref Pan Revb RevDel Rev Pan EchTm EchDp ModTm ModDp AirAbs HFRef LFRef RRlOff FLAGS -#define EAX30_PRESET_FACTORY_ALCOVE \ - { 26, 1.8f, 0.590f, -1200, -200, -600, 3.14f, 0.65f, 1.31f, 300, 0.010f, 0.00f,0.00f,0.00f, -1200, 0.038f, 0.00f,0.00f,0.00f, 0.114f, 0.100f, 0.250f, 0.000f, -0.0f, 3762.6f, 362.5f, 0.00f, 0x20 } -#define EAX30_PRESET_FACTORY_SHORTPASSAGE \ - { 26, 1.8f, 0.640f, -1200, -200, -600, 2.53f, 0.65f, 1.31f, 0, 0.010f, 0.00f,0.00f,0.00f, -600, 0.038f, 0.00f,0.00f,0.00f, 0.135f, 0.230f, 0.250f, 0.000f, -0.0f, 3762.6f, 362.5f, 0.00f, 0x20 } -#define EAX30_PRESET_FACTORY_MEDIUMROOM \ - { 26, 1.9f, 0.820f, -1200, -200, -600, 2.76f, 0.65f, 1.31f, -1100, 0.022f, 0.00f,0.00f,0.00f, -400, 0.023f, 0.00f,0.00f,0.00f, 0.174f, 0.070f, 0.250f, 0.000f, -0.0f, 3762.6f, 362.5f, 0.00f, 0x20 } -#define EAX30_PRESET_FACTORY_LONGPASSAGE \ - { 26, 1.8f, 0.640f, -1200, -200, -600, 4.06f, 0.65f, 1.31f, 0, 0.020f, 0.00f,0.00f,0.00f, -900, 0.037f, 0.00f,0.00f,0.00f, 0.135f, 0.230f, 0.250f, 0.000f, -0.0f, 3762.6f, 362.5f, 0.00f, 0x20 } -#define EAX30_PRESET_FACTORY_LARGEROOM \ - { 26, 1.9f, 0.750f, -1200, -300, -400, 4.24f, 0.51f, 1.31f, -1500, 0.039f, 0.00f,0.00f,0.00f, -600, 0.023f, 0.00f,0.00f,0.00f, 0.231f, 0.070f, 0.250f, 0.000f, -0.0f, 3762.6f, 362.5f, 0.00f, 0x20 } -#define EAX30_PRESET_FACTORY_HALL \ - { 26, 1.9f, 0.750f, -1000, -300, -400, 7.43f, 0.51f, 1.31f, -2400, 0.073f, 0.00f,0.00f,0.00f, -500, 0.027f, 0.00f,0.00f,0.00f, 0.250f, 0.070f, 0.250f, 0.000f, -0.0f, 3762.6f, 362.5f, 0.00f, 0x20 } -#define EAX30_PRESET_FACTORY_CUPBOARD \ - { 26, 1.7f, 0.630f, -1200, -200, -600, 0.49f, 0.65f, 1.31f, 200, 0.010f, 0.00f,0.00f,0.00f, 200, 0.032f, 0.00f,0.00f,0.00f, 0.107f, 0.070f, 0.250f, 0.000f, -0.0f, 3762.6f, 362.5f, 0.00f, 0x20 } -#define EAX30_PRESET_FACTORY_COURTYARD \ - { 26, 1.7f, 0.570f, -1000, -1000, -400, 2.32f, 0.29f, 0.56f, -2400, 0.090f, 0.00f,0.00f,0.00f, -2000, 0.039f, 0.00f,0.00f,0.00f, 0.250f, 0.290f, 0.250f, 0.000f, -0.0f, 3762.6f, 362.5f, 0.00f, 0x20 } -#define EAX30_PRESET_FACTORY_SMALLROOM \ - { 26, 1.8f, 0.820f, -1200, -200, -600, 1.72f, 0.65f, 1.31f, -300, 0.010f, 0.00f,0.00f,0.00f, -200, 0.024f, 0.00f,0.00f,0.00f, 0.119f, 0.070f, 0.250f, 0.000f, -0.0f, 3762.6f, 362.5f, 0.00f, 0x20 } - -// ICE PALACE PRESETS - -// Env Size Diffus Room RoomHF RoomLF DecTm DcHF DcLF Refl RefDel Ref Pan Revb RevDel Rev Pan EchTm EchDp ModTm ModDp AirAbs HFRef LFRef RRlOff FLAGS -#define EAX30_PRESET_ICEPALACE_ALCOVE \ - { 26, 2.7f, 0.840f, -1000, -500, -1100, 2.76f, 1.46f, 0.28f, 100, 0.010f, 0.00f,0.00f,0.00f, -1200, 0.030f, 0.00f,0.00f,0.00f, 0.161f, 0.090f, 0.250f, 0.000f, -0.0f, 12428.5f, 99.6f, 0.00f, 0x20 } -#define EAX30_PRESET_ICEPALACE_SHORTPASSAGE \ - { 26, 2.7f, 0.750f, -1000, -500, -1100, 1.79f, 1.46f, 0.28f, -600, 0.010f, 0.00f,0.00f,0.00f, -700, 0.019f, 0.00f,0.00f,0.00f, 0.177f, 0.090f, 0.250f, 0.000f, -0.0f, 12428.5f, 99.6f, 0.00f, 0x20 } -#define EAX30_PRESET_ICEPALACE_MEDIUMROOM \ - { 26, 2.7f, 0.870f, -1000, -500, -700, 2.22f, 1.53f, 0.32f, -800, 0.039f, 0.00f,0.00f,0.00f, -1200, 0.027f, 0.00f,0.00f,0.00f, 0.186f, 0.120f, 0.250f, 0.000f, -0.0f, 12428.5f, 99.6f, 0.00f, 0x20 } -#define EAX30_PRESET_ICEPALACE_LONGPASSAGE \ - { 26, 2.7f, 0.770f, -1000, -500, -800, 3.01f, 1.46f, 0.28f, -200, 0.012f, 0.00f,0.00f,0.00f, -800, 0.025f, 0.00f,0.00f,0.00f, 0.186f, 0.040f, 0.250f, 0.000f, -0.0f, 12428.5f, 99.6f, 0.00f, 0x20 } -#define EAX30_PRESET_ICEPALACE_LARGEROOM \ - { 26, 2.9f, 0.810f, -1000, -500, -700, 3.14f, 1.53f, 0.32f, -1200, 0.039f, 0.00f,0.00f,0.00f, -1300, 0.027f, 0.00f,0.00f,0.00f, 0.214f, 0.110f, 0.250f, 0.000f, -0.0f, 12428.5f, 99.6f, 0.00f, 0x20 } -#define EAX30_PRESET_ICEPALACE_HALL \ - { 26, 2.9f, 0.760f, -1000, -700, -500, 5.49f, 1.53f, 0.38f, -1900, 0.054f, 0.00f,0.00f,0.00f, -1400, 0.052f, 0.00f,0.00f,0.00f, 0.226f, 0.110f, 0.250f, 0.000f, -0.0f, 12428.5f, 99.6f, 0.00f, 0x20 } -#define EAX30_PRESET_ICEPALACE_CUPBOARD \ - { 26, 2.7f, 0.830f, -1000, -600, -1300, 0.76f, 1.53f, 0.26f, 100, 0.012f, 0.00f,0.00f,0.00f, 100, 0.016f, 0.00f,0.00f,0.00f, 0.143f, 0.080f, 0.250f, 0.000f, -0.0f, 12428.5f, 99.6f, 0.00f, 0x20 } -#define EAX30_PRESET_ICEPALACE_COURTYARD \ - { 26, 2.9f, 0.590f, -1000, -1100, -1000, 2.04f, 1.20f, 0.38f, -2000, 0.073f, 0.00f,0.00f,0.00f, -2200, 0.043f, 0.00f,0.00f,0.00f, 0.235f, 0.480f, 0.250f, 0.000f, -0.0f, 12428.5f, 99.6f, 0.00f, 0x20 } -#define EAX30_PRESET_ICEPALACE_SMALLROOM \ - { 26, 2.7f, 0.840f, -1000, -500, -1100, 1.51f, 1.53f, 0.27f, -100, 0.010f, 0.00f,0.00f,0.00f, -900, 0.011f, 0.00f,0.00f,0.00f, 0.164f, 0.140f, 0.250f, 0.000f, -0.0f, 12428.5f, 99.6f, 0.00f, 0x20 } - -// SPACE STATION PRESETS - -// Env Size Diffus Room RoomHF RoomLF DecTm DcHF DcLF Refl RefDel Ref Pan Revb RevDel Rev Pan EchTm EchDp ModTm ModDp AirAbs HFRef LFRef RRlOff FLAGS -#define EAX30_PRESET_SPACESTATION_ALCOVE \ - { 26, 1.5f, 0.780f, -1100, -300, -100, 1.16f, 0.81f, 0.55f, 300, 0.007f, 0.00f,0.00f,0.00f, -500, 0.018f, 0.00f,0.00f,0.00f, 0.192f, 0.210f, 0.250f, 0.000f, -5.0f, 3316.1f, 458.2f, 0.00f, 0x20 } -#define EAX30_PRESET_SPACESTATION_MEDIUMROOM \ - { 26, 1.5f, 0.750f, -1000, -400, -100, 3.01f, 0.50f, 0.55f, -1000, 0.034f, 0.00f,0.00f,0.00f, -700, 0.035f, 0.00f,0.00f,0.00f, 0.209f, 0.310f, 0.250f, 0.000f, -5.0f, 3316.1f, 458.2f, 0.00f, 0x20 } -#define EAX30_PRESET_SPACESTATION_SHORTPASSAGE \ - { 26, 1.5f, 0.870f, -1000, -400, -100, 3.57f, 0.50f, 0.55f, 0, 0.012f, 0.00f,0.00f,0.00f, -600, 0.016f, 0.00f,0.00f,0.00f, 0.172f, 0.200f, 0.250f, 0.000f, -5.0f, 3316.1f, 458.2f, 0.00f, 0x20 } -#define EAX30_PRESET_SPACESTATION_LONGPASSAGE \ - { 26, 1.9f, 0.820f, -1000, -400, -100, 4.62f, 0.62f, 0.55f, 0, 0.012f, 0.00f,0.00f,0.00f, -800, 0.031f, 0.00f,0.00f,0.00f, 0.250f, 0.230f, 0.250f, 0.000f, -5.0f, 3316.1f, 458.2f, 0.00f, 0x20 } -#define EAX30_PRESET_SPACESTATION_LARGEROOM \ - { 26, 1.8f, 0.810f, -1000, -400, -100, 3.89f, 0.38f, 0.61f, -1200, 0.056f, 0.00f,0.00f,0.00f, -800, 0.035f, 0.00f,0.00f,0.00f, 0.233f, 0.280f, 0.250f, 0.000f, -5.0f, 3316.1f, 458.2f, 0.00f, 0x20 } -#define EAX30_PRESET_SPACESTATION_HALL \ - { 26, 1.9f, 0.870f, -1000, -400, -100, 7.11f, 0.38f, 0.61f, -1500, 0.100f, 0.00f,0.00f,0.00f, -1000, 0.047f, 0.00f,0.00f,0.00f, 0.250f, 0.250f, 0.250f, 0.000f, -5.0f, 3316.1f, 458.2f, 0.00f, 0x20 } -#define EAX30_PRESET_SPACESTATION_CUPBOARD \ - { 26, 1.4f, 0.560f, -1000, -300, -100, 0.79f, 0.81f, 0.55f, 200, 0.007f, 0.00f,0.00f,0.00f, 400, 0.018f, 0.00f,0.00f,0.00f, 0.181f, 0.310f, 0.250f, 0.000f, -5.0f, 3316.1f, 458.2f, 0.00f, 0x20 } -#define EAX30_PRESET_SPACESTATION_SMALLROOM \ - { 26, 1.5f, 0.700f, -1000, -300, -100, 1.72f, 0.82f, 0.55f, -400, 0.007f, 0.00f,0.00f,0.00f, -500, 0.013f, 0.00f,0.00f,0.00f, 0.188f, 0.260f, 0.250f, 0.000f, -5.0f, 3316.1f, 458.2f, 0.00f, 0x20 } - -// WOODEN GALLEON PRESETS - -// Env Size Diffus Room RoomHF RoomLF DecTm DcHF DcLF Refl RefDel Ref Pan Revb RevDel Rev Pan EchTm EchDp ModTm ModDp AirAbs HFRef LFRef RRlOff FLAGS -#define EAX30_PRESET_WOODEN_ALCOVE \ - { 26, 7.5f, 1.000f, -1100, -1800, -1000, 1.22f, 0.62f, 0.91f, -100, 0.012f, 0.00f,0.00f,0.00f, -600, 0.024f, 0.00f,0.00f,0.00f, 0.250f, 0.000f, 0.250f, 0.000f, -5.0f, 4705.0f, 99.6f, 0.00f, 0x3f } -#define EAX30_PRESET_WOODEN_SHORTPASSAGE \ - { 26, 7.5f, 1.000f, -1100, -1800, -1000, 1.45f, 0.50f, 0.87f, -300, 0.012f, 0.00f,0.00f,0.00f, -700, 0.024f, 0.00f,0.00f,0.00f, 0.250f, 0.000f, 0.250f, 0.000f, -5.0f, 4705.0f, 99.6f, 0.00f, 0x3f } -#define EAX30_PRESET_WOODEN_MEDIUMROOM \ - { 26, 7.5f, 1.000f, -1200, -2000, -1100, 1.07f, 0.42f, 0.82f, -300, 0.039f, 0.00f,0.00f,0.00f, -400, 0.029f, 0.00f,0.00f,0.00f, 0.250f, 0.000f, 0.250f, 0.000f, -5.0f, 4705.0f, 99.6f, 0.00f, 0x3f } -#define EAX30_PRESET_WOODEN_LONGPASSAGE \ - { 26, 7.5f, 1.000f, -1100, -2000, -1000, 1.79f, 0.40f, 0.79f, -200, 0.020f, 0.00f,0.00f,0.00f, -1000, 0.036f, 0.00f,0.00f,0.00f, 0.250f, 0.000f, 0.250f, 0.000f, -5.0f, 4705.0f, 99.6f, 0.00f, 0x3f } -#define EAX30_PRESET_WOODEN_LARGEROOM \ - { 26, 7.5f, 1.000f, -1200, -2100, -1100, 1.45f, 0.33f, 0.82f, -300, 0.056f, 0.00f,0.00f,0.00f, -500, 0.049f, 0.00f,0.00f,0.00f, 0.250f, 0.000f, 0.250f, 0.000f, -5.0f, 4705.0f, 99.6f, 0.00f, 0x3f } -#define EAX30_PRESET_WOODEN_HALL \ - { 26, 7.5f, 1.000f, -1200, -2200, -1100, 1.95f, 0.30f, 0.82f, -300, 0.068f, 0.00f,0.00f,0.00f, -500, 0.063f, 0.00f,0.00f,0.00f, 0.250f, 0.000f, 0.250f, 0.000f, -5.0f, 4705.0f, 99.6f, 0.00f, 0x3f } -#define EAX30_PRESET_WOODEN_CUPBOARD \ - { 26, 7.5f, 1.000f, -1000, -1700, -1000, 0.56f, 0.46f, 0.91f, -100, 0.012f, 0.00f,0.00f,0.00f, -100, 0.028f, 0.00f,0.00f,0.00f, 0.250f, 0.000f, 0.250f, 0.000f, -5.0f, 4705.0f, 99.6f, 0.00f, 0x3f } -#define EAX30_PRESET_WOODEN_SMALLROOM \ - { 26, 7.5f, 1.000f, -1200, -1900, -1000, 0.79f, 0.32f, 0.87f, -200, 0.032f, 0.00f,0.00f,0.00f, -300, 0.029f, 0.00f,0.00f,0.00f, 0.250f, 0.000f, 0.250f, 0.000f, -5.0f, 4705.0f, 99.6f, 0.00f, 0x3f } -#define EAX30_PRESET_WOODEN_COURTYARD \ - { 26, 7.5f, 0.650f, -1700, -2200, -1000, 1.79f, 0.35f, 0.79f, -700, 0.063f, 0.00f,0.00f,0.00f, -2300, 0.032f, 0.00f,0.00f,0.00f, 0.250f, 0.000f, 0.250f, 0.000f, -5.0f, 4705.0f, 99.6f, 0.00f, 0x3f } - - -// OTHER SCENARIOS - -// SPORTS PRESETS - -// Env Size Diffus Room RoomHF RoomLF DecTm DcHF DcLF Refl RefDel Ref Pan Revb RevDel Rev Pan EchTm EchDp ModTm ModDp AirAbs HFRef LFRef RRlOff FLAGS -#define EAX30_PRESET_SPORT_EMPTYSTADIUM \ - { 26, 7.2f, 1.000f, -1300, -700, -200, 6.26f, 0.51f, 1.10f, -2400, 0.183f, 0.00f,0.00f,0.00f, -1100, 0.038f, 0.00f,0.00f,0.00f, 0.250f, 0.000f, 0.250f, 0.000f, -5.0f, 5000.0f, 250.0f, 0.00f, 0x20 } -#define EAX30_PRESET_SPORT_SQUASHCOURT \ - { 26, 7.5f, 0.750f, -1100, -1000, -200, 2.22f, 0.91f, 1.16f, -700, 0.007f, 0.00f,0.00f,0.00f, -300, 0.011f, 0.00f,0.00f,0.00f, 0.126f, 0.190f, 0.250f, 0.000f, -0.0f, 7176.9f, 211.2f, 0.00f, 0x20 } -#define EAX30_PRESET_SPORT_SMALLSWIMMINGPOOL \ - { 26, 36.2f, 0.700f, -1400, -200, -100, 2.76f, 1.25f, 1.14f, -400, 0.020f, 0.00f,0.00f,0.00f, -300, 0.030f, 0.00f,0.00f,0.00f, 0.179f, 0.150f, 0.895f, 0.190f, -5.0f, 5000.0f, 250.0f, 0.00f, 0x0 } -#define EAX30_PRESET_SPORT_LARGESWIMMINGPOOL\ - { 26, 36.2f, 0.820f, -1200, -200, 0, 5.49f, 1.31f, 1.14f, -700, 0.039f, 0.00f,0.00f,0.00f, -800, 0.049f, 0.00f,0.00f,0.00f, 0.222f, 0.550f, 1.159f, 0.210f, -5.0f, 5000.0f, 250.0f, 0.00f, 0x0 } -#define EAX30_PRESET_SPORT_GYMNASIUM \ - { 26, 7.5f, 0.810f, -1200, -700, -100, 3.14f, 1.06f, 1.35f, -800, 0.029f, 0.00f,0.00f,0.00f, -700, 0.045f, 0.00f,0.00f,0.00f, 0.146f, 0.140f, 0.250f, 0.000f, -0.0f, 7176.9f, 211.2f, 0.00f, 0x20 } -#define EAX30_PRESET_SPORT_FULLSTADIUM \ - { 26, 7.2f, 1.000f, -1300, -2300, -200, 5.25f, 0.17f, 0.80f, -2000, 0.188f, 0.00f,0.00f,0.00f, -1300, 0.038f, 0.00f,0.00f,0.00f, 0.250f, 0.000f, 0.250f, 0.000f, -5.0f, 5000.0f, 250.0f, 0.00f, 0x20 } -#define EAX30_PRESET_SPORT_STADIUMTANNOY \ - { 26, 3.0f, 0.780f, -900, -500, -600, 2.53f, 0.88f, 0.68f, -1100, 0.230f, 0.00f,0.00f,0.00f, -600, 0.063f, 0.00f,0.00f,0.00f, 0.250f, 0.200f, 0.250f, 0.000f, -0.0f, 5000.0f, 250.0f, 0.00f, 0x20 } - -// PREFAB PRESETS - -// Env Size Diffus Room RoomHF RoomLF DecTm DcHF DcLF Refl RefDel Ref Pan Revb RevDel Rev Pan EchTm EchDp ModTm ModDp AirAbs HFRef LFRef RRlOff FLAGS -#define EAX30_PRESET_PREFAB_WORKSHOP \ - { 26, 1.9f, 1.000f, -1000, -1700, -800, 0.76f, 1.00f, 1.00f, 0, 0.012f, 0.00f,0.00f,0.00f, -200, 0.012f, 0.00f,0.00f,0.00f, 0.250f, 0.000f, 0.250f, 0.000f, -5.0f, 5000.0f, 250.0f, 0.00f, 0x0 } -#define EAX30_PRESET_PREFAB_SCHOOLROOM \ - { 26, 1.86f, 0.690f, -1100, -400, -600, 0.98f, 0.45f, 0.18f, 300, 0.017f, 0.00f,0.00f,0.00f, 0, 0.015f, 0.00f,0.00f,0.00f, 0.095f, 0.140f, 0.250f, 0.000f, -0.0f, 7176.9f, 211.2f, 0.00f, 0x20 } -#define EAX30_PRESET_PREFAB_PRACTISEROOM \ - { 26, 1.86f, 0.870f, -1000, -800, -600, 1.12f, 0.56f, 0.18f, 200, 0.010f, 0.00f,0.00f,0.00f, -200, 0.011f, 0.00f,0.00f,0.00f, 0.095f, 0.140f, 0.250f, 0.000f, -0.0f, 7176.9f, 211.2f, 0.00f, 0x20 } -#define EAX30_PRESET_PREFAB_OUTHOUSE \ - { 26, 80.3f, 0.820f, -1100, -1900, -1600, 1.38f, 0.38f, 0.35f, -100, 0.024f, 0.00f,0.00f,-0.00f, -800, 0.044f, 0.00f,0.00f,0.00f, 0.121f, 0.170f, 0.250f, 0.000f, -0.0f, 2854.4f, 107.5f, 0.00f, 0x0 } -#define EAX30_PRESET_PREFAB_CARAVAN \ - { 26, 8.3f, 1.000f, -1000, -2100, -1800, 0.43f, 1.50f, 1.00f, 0, 0.012f, 0.00f,0.00f,0.00f, 400, 0.012f, 0.00f,0.00f,0.00f, 0.250f, 0.000f, 0.250f, 0.000f, -5.0f, 5000.0f, 250.0f, 0.00f, 0x1f } - // for US developers, a caravan is the same as a trailer =o) - - -// DOME AND PIPE PRESETS - -// Env Size Diffus Room RoomHF RoomLF DecTm DcHF DcLF Refl RefDel Ref Pan Revb RevDel Rev Pan EchTm EchDp ModTm ModDp AirAbs HFRef LFRef RRlOff FLAGS -#define EAX30_PRESET_DOME_TOMB \ - { 26, 51.8f, 0.790f, -1000, -900, -1300, 4.18f, 0.21f, 0.10f, -825, 0.030f, 0.00f,0.00f,0.00f, -125, 0.022f, 0.00f,0.00f,0.00f, 0.177f, 0.190f, 0.250f, 0.000f, -5.0f, 2854.4f, 20.0f, 0.00f, 0x0 } -#define EAX30_PRESET_PIPE_SMALL \ - { 26, 50.3f, 1.000f, -1000, -900, -1300, 5.04f, 0.10f, 0.10f, -600, 0.032f, 0.00f,0.00f,0.00f, 400, 0.015f, 0.00f,0.00f,0.00f, 0.250f, 0.000f, 0.250f, 0.000f, -5.0f, 2854.4f, 20.0f, 0.00f, 0x3f } -#define EAX30_PRESET_DOME_SAINTPAULS \ - { 26, 50.3f, 0.870f, -1000, -900, -1300, 10.48f, 0.19f, 0.10f, -1500, 0.090f, 0.00f,0.00f,0.00f, -500, 0.042f, 0.00f,0.00f,0.00f, 0.250f, 0.120f, 0.250f, 0.000f, -5.0f, 2854.4f, 20.0f, 0.00f, 0x3f } -#define EAX30_PRESET_PIPE_LONGTHIN \ - { 26, 1.6f, 0.910f, -1200, -700, -1100, 9.21f, 0.18f, 0.10f, -300, 0.010f, 0.00f,0.00f,0.00f, -1000, 0.022f, 0.00f,0.00f,0.00f, 0.250f, 0.000f, 0.250f, 0.000f, -5.0f, 2854.4f, 20.0f, 0.00f, 0x0 } -#define EAX30_PRESET_PIPE_LARGE \ - { 26, 50.3f, 1.000f, -1000, -900, -1300, 8.45f, 0.10f, 0.10f, -800, 0.046f, 0.00f,0.00f,0.00f, 0, 0.032f, 0.00f,0.00f,0.00f, 0.250f, 0.000f, 0.250f, 0.000f, -5.0f, 2854.4f, 20.0f, 0.00f, 0x3f } -#define EAX30_PRESET_PIPE_RESONANT \ - { 26, 1.3f, 0.910f, -1200, -700, -1100, 6.81f, 0.18f, 0.10f, -300, 0.010f, 0.00f,0.00f,0.00f, -700, 0.022f, 0.00f,0.00f,0.00f, 0.250f, 0.000f, 0.250f, 0.000f, -5.0f, 2854.4f, 20.0f, 0.00f, 0x0 } - -// OUTDOORS PRESETS - -// Env Size Diffus Room RoomHF RoomLF DecTm DcHF DcLF Refl RefDel Ref Pan Revb RevDel Rev Pan EchTm EchDp ModTm ModDp AirAbs HFRef LFRef RRlOff FLAGS -#define EAX30_PRESET_OUTDOORS_BACKYARD \ - { 26, 80.3f, 0.450f, -1100, -1200, -600, 1.12f, 0.34f, 0.46f, -1100, 0.049f, 0.00f,0.00f,-0.00f, -1300, 0.023f, 0.00f,0.00f,0.00f, 0.218f, 0.340f, 0.250f, 0.000f, -5.0f, 4399.1f, 242.9f, 0.00f, 0x0 } -#define EAX30_PRESET_OUTDOORS_ROLLINGPLAINS \ - { 26, 80.3f, 0.000f, -1100, -3900, -400, 2.13f, 0.21f, 0.46f, -2000, 0.300f, 0.00f,0.00f,-0.00f, -1500, 0.019f, 0.00f,0.00f,0.00f, 0.250f, 1.000f, 0.250f, 0.000f, -5.0f, 4399.1f, 242.9f, 0.00f, 0x0 } -#define EAX30_PRESET_OUTDOORS_DEEPCANYON \ - { 26, 80.3f, 0.740f, -1100, -1500, -400, 3.89f, 0.21f, 0.46f, -2000, 0.193f, 0.00f,0.00f,-0.00f, -1100, 0.019f, 0.00f,0.00f,0.00f, 0.250f, 1.000f, 0.250f, 0.000f, -5.0f, 4399.1f, 242.9f, 0.00f, 0x0 } -#define EAX30_PRESET_OUTDOORS_CREEK \ - { 26, 80.3f, 0.350f, -1100, -1500, -600, 2.13f, 0.21f, 0.46f, -1700, 0.115f, 0.00f,0.00f,-0.00f, -1100, 0.031f, 0.00f,0.00f,0.00f, 0.218f, 0.340f, 0.250f, 0.000f, -5.0f, 4399.1f, 242.9f, 0.00f, 0x0 } -#define EAX30_PRESET_OUTDOORS_VALLEY \ - { 26, 80.3f, 0.280f, -1100, -3100, -1600, 2.88f, 0.26f, 0.35f, -3200, 0.163f, 0.00f,0.00f,-0.00f, -1000, 0.100f, 0.00f,0.00f,0.00f, 0.250f, 0.340f, 0.250f, 0.000f, -0.0f, 2854.4f, 107.5f, 0.00f, 0x0 } - - -// MOOD PRESETS - -// Env Size Diffus Room RoomHF RoomLF DecTm DcHF DcLF Refl RefDel Ref Pan Revb RevDel Rev Pan EchTm EchDp ModTm ModDp AirAbs HFRef LFRef RRlOff FLAGS -#define EAX30_PRESET_MOOD_HEAVEN \ - { 26, 19.6f, 0.940f, -1000, -200, -700, 5.04f, 1.12f, 0.56f, -1230, 0.020f, 0.00f,0.00f,0.00f, -200, 0.029f, 0.00f,0.00f,0.00f, 0.250f, 0.080f, 2.742f, 0.050f, -2.0f, 5000.0f, 250.0f, 0.00f, 0x3f } -#define EAX30_PRESET_MOOD_HELL \ - { 26, 100.0f, 0.570f, -1000, -900, -700, 3.57f, 0.49f, 2.00f, -10000, 0.020f, 0.00f,0.00f,0.00f, 100, 0.030f, 0.00f,0.00f,0.00f, 0.110f, 0.040f, 2.109f, 0.520f, -5.0f, 5000.0f, 139.5f, 0.00f, 0x40 } -#define EAX30_PRESET_MOOD_MEMORY \ - { 26, 8.0f, 0.850f, -1000, -400, -900, 4.06f, 0.82f, 0.56f, -2800, 0.000f, 0.00f,0.00f,0.00f, -500, 0.000f, 0.00f,0.00f,0.00f, 0.250f, 0.000f, 0.474f, 0.450f, -2.0f, 5000.0f, 250.0f, 0.00f, 0x0 } - -// DRIVING SIMULATION PRESETS - -// Env Size Diffus Room RoomHF RoomLF DecTm DcHF DcLF Refl RefDel Ref Pan Revb RevDel Rev Pan EchTm EchDp ModTm ModDp AirAbs HFRef LFRef RRlOff FLAGS -#define EAX30_PRESET_DRIVING_COMMENTATOR \ - { 26, 3.0f, 0.000f, -900, -500, -600, 2.42f, 0.88f, 0.68f, -1400, 0.093f, 0.00f,0.00f,0.00f, -1200, 0.017f, 0.00f,0.00f,0.00f, 0.250f, 1.000f, 0.250f, 0.000f, -0.0f, 5000.0f, 250.0f, 0.00f, 0x20 } -#define EAX30_PRESET_DRIVING_PITGARAGE \ - { 26, 1.9f, 0.590f, -1400, -300, -500, 1.72f, 0.93f, 0.87f, -500, 0.000f, 0.00f,0.00f,0.00f, 0, 0.016f, 0.00f,0.00f,0.00f, 0.250f, 0.110f, 0.250f, 0.000f, -5.0f, 5000.0f, 250.0f, 0.00f, 0x0 } -#define EAX30_PRESET_DRIVING_INCAR_RACER \ - { 26, 1.1f, 0.800f, -700, 0, -200, 0.17f, 2.00f, 0.41f, 500, 0.007f, 0.00f,0.00f,0.00f, -500, 0.015f, 0.00f,0.00f,0.00f, 0.250f, 0.000f, 0.250f, 0.000f, -0.0f, 10268.2f, 251.0f, 0.00f, 0x20 } -#define EAX30_PRESET_DRIVING_INCAR_SPORTS \ - { 26, 1.1f, 0.800f, -900, -400, 0, 0.17f, 0.75f, 0.41f, 0, 0.010f, 0.00f,0.00f,0.00f, -600, 0.000f, 0.00f,0.00f,0.00f, 0.250f, 0.000f, 0.250f, 0.000f, -0.0f, 10268.2f, 251.0f, 0.00f, 0x20 } -#define EAX30_PRESET_DRIVING_INCAR_LUXURY \ - { 26, 1.6f, 1.000f, -800, -2000, -600, 0.13f, 0.41f, 0.46f, -200, 0.010f, 0.00f,0.00f,0.00f, 300, 0.010f, 0.00f,0.00f,0.00f, 0.250f, 0.000f, 0.250f, 0.000f, -0.0f, 10268.2f, 251.0f, 0.00f, 0x20 } -#define EAX30_PRESET_DRIVING_FULLGRANDSTAND \ - { 26, 8.3f, 1.000f, -1100, -1100, -400, 3.01f, 1.37f, 1.28f, -900, 0.090f, 0.00f,0.00f,0.00f, -1700, 0.049f, 0.00f,0.00f,0.00f, 0.250f, 0.000f, 0.250f, 0.000f, -5.0f, 10420.2f, 250.0f, 0.00f, 0x1f } -#define EAX30_PRESET_DRIVING_EMPTYGRANDSTAND \ - { 26, 8.3f, 1.000f, -700, 0, -200, 4.62f, 1.75f, 1.40f, -1363, 0.090f, 0.00f,0.00f,0.00f, -1900, 0.049f, 0.00f,0.00f,0.00f, 0.250f, 0.000f, 0.250f, 0.000f, -5.0f, 10420.2f, 250.0f, 0.00f, 0x1f } -#define EAX30_PRESET_DRIVING_TUNNEL \ - { 26, 3.1f, 0.810f, -900, -800, -100, 3.42f, 0.94f, 1.31f, -300, 0.051f, 0.00f,0.00f,0.00f, -500, 0.047f, 0.00f,0.00f,0.00f, 0.214f, 0.050f, 0.250f, 0.000f, -0.0f, 5000.0f, 155.3f, 0.00f, 0x20 } - -// CITY PRESETS - -// Env Size Diffus Room RoomHF RoomLF DecTm DcHF DcLF Refl RefDel Ref Pan Revb RevDel Rev Pan EchTm EchDp ModTm ModDp AirAbs HFRef LFRef RRlOff FLAGS -#define EAX30_PRESET_CITY_STREETS \ - { 26, 3.0f, 0.780f, -1100, -300, -100, 1.79f, 1.12f, 0.91f, -1700, 0.046f, 0.00f,0.00f,0.00f, -2800, 0.028f, 0.00f,0.00f,0.00f, 0.250f, 0.200f, 0.250f, 0.000f, -0.0f, 5000.0f, 250.0f, 0.00f, 0x20 } -#define EAX30_PRESET_CITY_SUBWAY \ - { 26, 3.0f, 0.740f, -1100, -300, -100, 3.01f, 1.23f, 0.91f, -700, 0.046f, 0.00f,0.00f,0.00f, -1000, 0.028f, 0.00f,0.00f,0.00f, 0.125f, 0.210f, 0.250f, 0.000f, -0.0f, 5000.0f, 250.0f, 0.00f, 0x20 } -#define EAX30_PRESET_CITY_MUSEUM \ - { 26, 80.3f, 0.820f, -1100, -1500, -1500, 3.28f, 1.40f, 0.57f, -1600, 0.039f, 0.00f,0.00f,-0.00f, -600, 0.034f, 0.00f,0.00f,0.00f, 0.130f, 0.170f, 0.250f, 0.000f, -0.0f, 2854.4f, 107.5f, 0.00f, 0x0 } -#define EAX30_PRESET_CITY_LIBRARY \ - { 26, 80.3f, 0.820f, -1100, -1100, -2100, 2.76f, 0.89f, 0.41f, -1100, 0.029f, 0.00f,0.00f,-0.00f, -500, 0.020f, 0.00f,0.00f,0.00f, 0.130f, 0.170f, 0.250f, 0.000f, -0.0f, 2854.4f, 107.5f, 0.00f, 0x0 } -#define EAX30_PRESET_CITY_UNDERPASS \ - { 26, 3.0f, 0.820f, -1500, -700, -100, 3.57f, 1.12f, 0.91f, -1500, 0.059f, 0.00f,0.00f,0.00f, -1100, 0.037f, 0.00f,0.00f,0.00f, 0.250f, 0.140f, 0.250f, 0.000f, -0.0f, 5000.0f, 250.0f, 0.00f, 0x20 } -#define EAX30_PRESET_CITY_ABANDONED \ - { 26, 3.0f, 0.690f, -1100, -200, -100, 3.28f, 1.17f, 0.91f, -1400, 0.044f, 0.00f,0.00f,0.00f, -2400, 0.024f, 0.00f,0.00f,0.00f, 0.250f, 0.200f, 0.250f, 0.000f, -0.0f, 5000.0f, 250.0f, 0.00f, 0x20 } - -// MISC ROOMS - -// Env Size Diffus Room RoomHF RoomLF DecTm DcHF DcLF Refl RefDel Ref Pan Revb RevDel Rev Pan EchTm EchDp ModTm ModDp AirAbs HFRef LFRef RRlOff FLAGS -#define EAX30_PRESET_DUSTYROOM \ - { 26, 1.8f, 0.560f, -1100, -200, -300, 1.79f, 0.38f, 0.21f, -600, 0.002f, 0.00f,0.00f,0.00f, 200, 0.006f, 0.00f,0.00f,0.00f, 0.202f, 0.050f, 0.250f, 0.000f, -3.0f, 13046.0f, 163.3f, 0.00f, 0x20 } -#define EAX30_PRESET_CHAPEL \ - { 26, 19.6f, 0.840f, -1000, -500, 0, 4.62f, 0.64f, 1.23f, -700, 0.032f, 0.00f,0.00f,0.00f, -800, 0.049f, 0.00f,0.00f,0.00f, 0.250f, 0.000f, 0.250f, 0.110f, -5.0f, 5000.0f, 250.0f, 0.00f, 0x3f } -#define EAX30_PRESET_SMALLWATERROOM \ - { 26, 36.2f, 0.700f, -1200, -698, 0, 1.51f, 1.25f, 1.14f, -100, 0.020f, 0.00f,0.00f,0.00f, 200, 0.030f, 0.00f,0.00f,0.00f, 0.179f, 0.150f, 0.895f, 0.190f, -5.0f, 5000.0f, 250.0f, 0.00f, 0x0 } - -/********************************************************************************************************/ - -////////////////////////////////////////////////////// -// Effect Scenarios enumerated // -////////////////////////////////////////////////////// - -typedef enum -{ - EAX30_SCENARIO_CASTLE = 0, - EAX30_SCENARIO_FACTORY, - EAX30_SCENARIO_ICEPALACE, - EAX30_SCENARIO_SPACESTATION, - EAX30_SCENARIO_WOODGALLEON, - EAX30_SCENARIO_SPORTS, - EAX30_SCENARIO_PREFAB, - EAX30_SCENARIO_DOMESNPIPES, - EAX30_SCENARIO_OUTDOORS, - EAX30_SCENARIO_MOOD, - EAX30_SCENARIO_DRIVING, - EAX30_SCENARIO_CITY, - EAX30_SCENARIO_MISC, - EAX30_SCENARIO_ORIGINAL -} -EAX30_SCENARIO; - -////////////////////////////////////////////////////// -// Number of Effect Scenarios // -////////////////////////////////////////////////////// - -#define EAX30_NUM_SCENARIOS 14 - -////////////////////////////////////////////////////// -// Number of Effect Scenarios with standardised // -// locations // -////////////////////////////////////////////////////// - -#define EAX30_NUM_STANDARD_SCENARIOS 5 - -////////////////////////////////////////////////////// -// Array of scenario names // -////////////////////////////////////////////////////// - -extern char* EAX30_SCENARIO_NAMES[]; - -////////////////////////////////////////////////////// -// Standardised Locations enumerated // -////////////////////////////////////////////////////// - -typedef enum -{ - EAX30_LOCATION_HALL = 0, - EAX30_LOCATION_LARGEROOM, - EAX30_LOCATION_MEDIUMROOM, - EAX30_LOCATION_SMALLROOM, - EAX30_LOCATION_CUPBOARD, - EAX30_LOCATION_ALCOVE, - EAX30_LOCATION_LONGPASSAGE, - EAX30_LOCATION_SHORTPASSAGE, - EAX30_LOCATION_COURTYARD -} -EAX30_LOCATION; - -////////////////////////////////////////////////////// -// Number of Standardised Locations // -////////////////////////////////////////////////////// - -#define EAX30_NUM_LOCATIONS 9 - -////////////////////////////////////////////////////// -// Array of standardised location names // -////////////////////////////////////////////////////// - -extern char* EAX30_LOCATION_NAMES[]; - -////////////////////////////////////////////////////// -// Number of effects in each scenario // -////////////////////////////////////////////////////// - -#define EAX30_NUM_ORIGINAL_PRESETS 26 -#define EAX30_NUM_CASTLE_PRESETS EAX30_NUM_LOCATIONS -#define EAX30_NUM_FACTORY_PRESETS EAX30_NUM_LOCATIONS -#define EAX30_NUM_ICEPALACE_PRESETS EAX30_NUM_LOCATIONS -#define EAX30_NUM_SPACESTATION_PRESETS EAX30_NUM_LOCATIONS -#define EAX30_NUM_WOODGALLEON_PRESETS EAX30_NUM_LOCATIONS -#define EAX30_NUM_SPORTS_PRESETS 7 -#define EAX30_NUM_PREFAB_PRESETS 5 -#define EAX30_NUM_DOMESNPIPES_PRESETS 6 -#define EAX30_NUM_OUTDOORS_PRESETS 5 -#define EAX30_NUM_MOOD_PRESETS 3 -#define EAX30_NUM_DRIVING_PRESETS 8 -#define EAX30_NUM_CITY_PRESETS 6 -#define EAX30_NUM_MISC_PRESETS 3 - -////////////////////////////////////////////////////// -// Standardised Location effects can be accessed // -// from a matrix // -////////////////////////////////////////////////////// - -extern EAXLISTENERPROPERTIES EAX30_STANDARD_PRESETS[EAX30_NUM_STANDARD_SCENARIOS][EAX30_NUM_LOCATIONS]; - -/********************************************************************************************************/ - -////////////////////////////////////////////////////// -// Original Preset effects enumerated // -////////////////////////////////////////////////////// - -typedef enum -{ - ORIGINAL_GENERIC = 0, - ORIGINAL_PADDEDCELL, - ORIGINAL_ROOM, - ORIGINAL_BATHROOM, - ORIGINAL_LIVINGROOM, - ORIGINAL_STONEROOM, - ORIGINAL_AUDITORIUM, - ORIGINAL_CONCERTHALL, - ORIGINAL_CAVE, - ORIGINAL_ARENA, - ORIGINAL_HANGAR, - ORIGINAL_CARPETTEDHALLWAY, - ORIGINAL_HALLWAY, - ORIGINAL_STONECORRIDOR, - ORIGINAL_ALLEY, - ORIGINAL_FOREST, - ORIGINAL_CITY, - ORIGINAL_MOUNTAINS, - ORIGINAL_QUARRY, - ORIGINAL_PLAIN, - ORIGINAL_PARKINGLOT, - ORIGINAL_SEWERPIPE, - ORIGINAL_UNDERWATER, - ORIGINAL_DRUGGED, - ORIGINAL_DIZZY, - ORIGINAL_PSYCHOTIC -} -EAX30_ORIGINAL_PRESET_ENUMS; - -////////////////////////////////////////////////////// -// Array of original environment names // -////////////////////////////////////////////////////// - -extern char* EAX30_ORIGINAL_PRESET_NAMES[]; - -////////////////////////////////////////////////////// -// Original effects matrix // -////////////////////////////////////////////////////// - -extern EAXLISTENERPROPERTIES EAX30_ORIGINAL_PRESETS[]; - -/********************************************************************************************************/ - -////////////////////////////////////////////////////// -// Sports scenario effects enumerated // -////////////////////////////////////////////////////// - -typedef enum -{ - SPORT_EMPTYSTADIUM=0, - SPORT_FULLSTADIUM, - SPORT_STADIUMTANNOY, - SPORT_SQUASHCOURT, - SPORT_SMALLSWIMMINGPOOL, - SPORT_LARGESWIMMINGPOOL, - SPORT_GYMNASIUM -} -EAX30_SPORTS_PRESET_ENUMS; - -////////////////////////////////////////////////////// -// Array of sport environment names // -////////////////////////////////////////////////////// - -extern char* EAX30_SPORTS_PRESET_NAMES[]; - -////////////////////////////////////////////////////// -// Sports effects matrix // -////////////////////////////////////////////////////// - -extern EAXLISTENERPROPERTIES EAX30_SPORTS_PRESETS[]; - -/********************************************************************************************************/ - -////////////////////////////////////////////////////// -// Prefab scenario effects enumerated // -////////////////////////////////////////////////////// - -typedef enum -{ - PREFAB_WORKSHOP, - PREFAB_SCHOOLROOM, - PREFAB_PRACTISEROOM, - PREFAB_OUTHOUSE, - PREFAB_CARAVAN -} -EAX30_PREFAB_PRESET_ENUMS; - -////////////////////////////////////////////////////// -// Array of prefab environment names // -////////////////////////////////////////////////////// - -char* EAX30_PREFAB_PRESET_NAMES[]; - -////////////////////////////////////////////////////// -// Prefab effects matrix // -////////////////////////////////////////////////////// - -extern EAXLISTENERPROPERTIES EAX30_PREFAB_PRESETS[]; - -/********************************************************************************************************/ - -////////////////////////////////////////////////////// -// Domes & Pipes effects enumerated // -////////////////////////////////////////////////////// - -typedef enum -{ - DOME_TOMB, - DOME_SAINTPAULS, - PIPE_SMALL, - PIPE_LONGTHIN, - PIPE_LARGE, - PIPE_RESONANT -} -EAX30_DOMESNPIPES_PRESET_ENUMS; - -////////////////////////////////////////////////////// -// Array of Domes & Pipes environment names // -////////////////////////////////////////////////////// - -extern char* EAX30_DOMESNPIPES_PRESET_NAMES[]; - -////////////////////////////////////////////////////// -// Domes & Pipes effects matrix // -////////////////////////////////////////////////////// - -extern EAXLISTENERPROPERTIES EAX30_DOMESNPIPES_PRESETS[]; - -/********************************************************************************************************/ - -////////////////////////////////////////////////////// -// Outdoors scenario effects enumerated // -////////////////////////////////////////////////////// - -typedef enum -{ - OUTDOORS_BACKYARD, - OUTDOORS_ROLLINGPLAINS, - OUTDOORS_DEEPCANYON, - OUTDOORS_CREEK, - OUTDOORS_VALLEY -} -EAX30_OUTDOORS_PRESET_ENUMS; - -////////////////////////////////////////////////////// -// Array of Outdoors environment names // -////////////////////////////////////////////////////// - -extern char* EAX30_OUTDOORS_PRESET_NAMES[]; - -////////////////////////////////////////////////////// -// Outdoors effects matrix // -////////////////////////////////////////////////////// - -extern EAXLISTENERPROPERTIES EAX30_OUTDOORS_PRESETS[]; - -/********************************************************************************************************/ - -////////////////////////////////////////////////////// -// Mood scenario effects enumerated // -////////////////////////////////////////////////////// - -typedef enum -{ - MOOD_HEAVEN, - MOOD_HELL, - MOOD_MEMORY -} -EAX30_MOOD_PRESET_ENUMS; - -////////////////////////////////////////////////////// -// Array of Mood environment names // -////////////////////////////////////////////////////// - -extern char* EAX30_MOOD_PRESET_NAMES[]; - -////////////////////////////////////////////////////// -// Mood effects matrix // -////////////////////////////////////////////////////// - -extern EAXLISTENERPROPERTIES EAX30_MOOD_PRESETS[]; - -/********************************************************************************************************/ - -////////////////////////////////////////////////////// -// Driving scenario effects enumerated // -////////////////////////////////////////////////////// - -typedef enum -{ - DRIVING_COMMENTATOR, - DRIVING_PITGARAGE, - DRIVING_INCAR_RACER, - DRIVING_INCAR_SPORTS, - DRIVING_INCAR_LUXURY, - DRIVING_FULLGRANDSTAND, - DRIVING_EMPTYGRANDSTAND, - DRIVING_TUNNEL -} -EAX30_DRIVING_PRESET_ENUMS; - -////////////////////////////////////////////////////// -// Array of driving environment names // -////////////////////////////////////////////////////// - -extern char* EAX30_DRIVING_PRESET_NAMES[]; - -////////////////////////////////////////////////////// -// Driving effects matrix // -////////////////////////////////////////////////////// - -extern EAXLISTENERPROPERTIES EAX30_DRIVING_PRESETS[]; - -/********************************************************************************************************/ - -////////////////////////////////////////////////////// -// City scenario effects enumerated // -////////////////////////////////////////////////////// - -typedef enum -{ - CITY_STREETS, - CITY_SUBWAY, - CITY_MUSEUM, - CITY_LIBRARY, - CITY_UNDERPASS, - CITY_ABANDONED -} -EAX30_CITY_PRESET_ENUMS; - -////////////////////////////////////////////////////// -// Array of City environment names // -////////////////////////////////////////////////////// - -extern char* EAX30_CITY_PRESET_NAMES[]; - -////////////////////////////////////////////////////// -// City effects matrix // -////////////////////////////////////////////////////// - -extern EAXLISTENERPROPERTIES EAX30_CITY_PRESETS[]; - -/********************************************************************************************************/ - -////////////////////////////////////////////////////// -// Misc scenario effects enumerated // -////////////////////////////////////////////////////// - -typedef enum -{ - DUSTYROOM, - CHAPEL, - SMALLWATERROOM -} -EAX30_MISC_PRESET_ENUMS; - - -////////////////////////////////////////////////////// -// Array of Misc environment names // -////////////////////////////////////////////////////// - -extern char* EAX30_MISC_PRESET_NAMES[]; - -////////////////////////////////////////////////////// -// Misc effects matrix // -////////////////////////////////////////////////////// - -extern EAXLISTENERPROPERTIES EAX30_MISC_PRESETS[]; - - -/***********************************************************************************************\ -* -* Material transmission presets -* -* Three values in this order :- -* -* 1. Occlusion (or Obstruction) -* 2. Occlusion LF Ratio (or Obstruction LF Ratio) -* 3. Occlusion Room Ratio -* -************************************************************************************************/ - - -// Single window material preset -#define EAX_MATERIAL_SINGLEWINDOW (-2800) -#define EAX_MATERIAL_SINGLEWINDOWLF 0.71f -#define EAX_MATERIAL_SINGLEWINDOWROOMRATIO 0.43f - -// Double window material preset -#define EAX_MATERIAL_DOUBLEWINDOW (-5000) -#define EAX_MATERIAL_DOUBLEWINDOWLF 0.40f -#define EAX_MATERIAL_DOUBLEWINDOWROOMRATIO 0.24f - -// Thin door material preset -#define EAX_MATERIAL_THINDOOR (-1800) -#define EAX_MATERIAL_THINDOORLF 0.66f -#define EAX_MATERIAL_THINDOORROOMRATIO 0.66f - -// Thick door material preset -#define EAX_MATERIAL_THICKDOOR (-4400) -#define EAX_MATERIAL_THICKDOORLF 0.64f -#define EAX_MATERIAL_THICKDOORROOMRATIO 0.27f - -// Wood wall material preset -#define EAX_MATERIAL_WOODWALL (-4000) -#define EAX_MATERIAL_WOODWALLLF 0.50f -#define EAX_MATERIAL_WOODWALLROOMRATIO 0.30f - -// Brick wall material preset -#define EAX_MATERIAL_BRICKWALL (-5000) -#define EAX_MATERIAL_BRICKWALLLF 0.60f -#define EAX_MATERIAL_BRICKWALLROOMRATIO 0.24f - -// Stone wall material preset -#define EAX_MATERIAL_STONEWALL (-6000) -#define EAX_MATERIAL_STONEWALLLF 0.68f -#define EAX_MATERIAL_STONEWALLROOMRATIO 0.20f - -// Curtain material preset -#define EAX_MATERIAL_CURTAIN (-1200) -#define EAX_MATERIAL_CURTAINLF 0.15f -#define EAX_MATERIAL_CURTAINROOMRATIO 1.00f - - -#endif // EAXUTIL_INCLUDED diff --git a/code/client/eax/vssver.scc b/code/client/eax/vssver.scc new file mode 100644 index 0000000..c3eaf05 Binary files /dev/null and b/code/client/eax/vssver.scc differ diff --git a/code/client/snd_dma.cpp b/code/client/snd_dma.cpp index 7aadc92..25ee294 100644 --- a/code/client/snd_dma.cpp +++ b/code/client/snd_dma.cpp @@ -42,7 +42,6 @@ typedef struct sfx_t sfxMP3_Bgrnd; MP3STREAM streamMP3_Bgrnd; // this one is pointed at by the sfx_t's ptr, and is NOT the one the decoder uses every cycle channel_t chMP3_Bgrnd; // ... but the one in this struct IS. - MP3STREAM* pFrozenMP3; // // MP3 disk streamer stuff... (if music is non-dynamic) // @@ -234,6 +233,12 @@ void UpdateEAXListener(bool bUseDefault, bool bUseMorphing); void UpdateEAXBuffer(channel_t *ch); void EALFileInit(char *level); void EAXMorph(); +void Clamp(EAXVECTOR *eaxVector); +bool CheckEAX3LP(LPEAXLISTENERPROPERTIES lpEAX3LP); +bool EAX3ListenerInterpolate(EAXLISTENERPROPERTIES *lpStartEAX3LP, EAXLISTENERPROPERTIES *lpFinishEAX3LP, + float flRatio, EAXLISTENERPROPERTIES *lpResultEAX3LP, bool bCheckValues = false); + + // EAX 3.0 GUIDS ... confidential information ... @@ -249,6 +254,18 @@ const GUID DSPROPSETID_EAX30_BufferProperties * \**************************************************************************************************/ +// instead of clearing a whole channel_t struct, we're going to skip the MP3SlidingDecodeBuffer[] buffer in the middle... +// +static inline void Channel_Clear(channel_t *ch) +{ + // memset (ch, 0, sizeof(*ch)); + + memset(ch,0,offsetof(channel_t,MP3SlidingDecodeBuffer)); + + byte *const p = (byte *)ch + offsetof(channel_t,MP3SlidingDecodeBuffer) + sizeof(ch->MP3SlidingDecodeBuffer); + + memset(p,0,(sizeof(*ch) - offsetof(channel_t,MP3SlidingDecodeBuffer)) - sizeof(ch->MP3SlidingDecodeBuffer)); +} // ==================================================================== // User-setable variables @@ -459,15 +476,23 @@ void S_Init( void ) { // clear out the lip synching override array memset(s_entityWavVol, 0, sizeof(s_entityWavVol)); - +/* if (s_khz->integer == 44) dma.speed = 44100; else if (s_khz->integer == 22) dma.speed = 22050; else dma.speed = 11025; +*/ + // Always at 22KHz for OpenAL + dma.speed = 22050; - return; + // These aren't really relevant for Open AL, but for completeness ... + dma.channels = 2; + dma.samplebits = 16; + dma.samples = 0; + dma.submission_chunk = 0; + dma.buffer = NULL; } else { @@ -510,6 +535,9 @@ void S_Shutdown( void ) return; } + S_FreeAllSFXMem(); + S_UnCacheDynamicMusic(); + if (s_UseOpenAL) { // Release all the AL Sources (including Music channel (Source 0)) @@ -518,9 +546,6 @@ void S_Shutdown( void ) alDeleteSources(1, &(s_channels[i].alSource)); } -// // Release all the AL Buffers here or not ? -// S_FreeAllSFXMem(); - // Release Streaming AL Buffers ch = s_channels + 1; for (i = 1; i < s_numChannels; i++, ch++) @@ -570,6 +595,32 @@ void S_Shutdown( void ) } + +/* + Mutes / Unmutes all OpenAL sound +*/ +void S_AL_MuteAllSounds(qboolean bMute) +{ + if (!s_soundStarted) + return; + + if (!s_UseOpenAL) + return; + + if (bMute) + { + alListenerf(AL_GAIN, 0.0f); + } + else + { + alListenerf(AL_GAIN, 1.0f); + } +} + + + + + // ======================================================================= // Load a sound // ======================================================================= @@ -950,7 +1001,7 @@ channel_t *S_PickChannel(int entnum, int entchannel) Com_Printf( S_COLOR_RED"***kicking %s\n", firstToDie->thesfx->sSoundName ); } - memset(firstToDie, 0, sizeof(*firstToDie)); + Channel_Clear(firstToDie); // memset(firstToDie, 0, sizeof(*firstToDie)); return firstToDie; } @@ -1096,7 +1147,7 @@ void S_SpatializeOrigin (const vec3_t origin, float master_vol, int *left_vol, i dist = VectorNormalize(source_vec); if ( channel == CHAN_VOICE ) { - dist -= SOUND_FULLVOLUME * 4.0f; + dist -= SOUND_FULLVOLUME * 3.0f; } else if ( channel == CHAN_VOICE_ATTEN ) { @@ -1371,15 +1422,18 @@ void S_ClearSoundBuffer( void ) { #endif s_rawend = 0; - if (dma.samplebits == 8) - clear = 0x80; - else - clear = 0; + if (!s_UseOpenAL) + { + if (dma.samplebits == 8) + clear = 0x80; + else + clear = 0; - SNDDMA_BeginPainting (); - if (dma.buffer) - memset(dma.buffer, clear, dma.samples * dma.samplebits/8); - SNDDMA_Submit (); + SNDDMA_BeginPainting (); + if (dma.buffer) + memset(dma.buffer, clear, dma.samples * dma.samplebits/8); + SNDDMA_Submit (); + } } @@ -1904,10 +1958,8 @@ void S_UpdateEntityPosition( int entityNum, const vec3_t origin ) } } } - else - { - VectorCopy( origin, s_entityPosition[entityNum] ); - } + + VectorCopy( origin, s_entityPosition[entityNum] ); } @@ -2143,7 +2195,7 @@ void S_Respatialize( int entityNum, const vec3_t head, vec3_t axis[3], qboolean continue; } if ( ch->loopSound ) { // loopSounds are regenerated fresh each frame - memset (ch, 0, sizeof(*ch)); + Channel_Clear(ch); // memset (ch, 0, sizeof(*ch)); continue; } @@ -2164,7 +2216,7 @@ void S_Respatialize( int entityNum, const vec3_t head, vec3_t axis[3], qboolean //NOTE: Made it so that voice sounds keep playing, even out of range // so that tasks waiting for sound completion keep proper timing if ( !( ch->entchannel == CHAN_VOICE || ch->entchannel == CHAN_VOICE_ATTEN || ch->entchannel == CHAN_VOICE_GLOBAL ) && !ch->leftvol && !ch->rightvol ) { - memset (ch, 0, sizeof(*ch)); + Channel_Clear(ch); // memset (ch, 0, sizeof(*ch)); continue; } } @@ -2372,8 +2424,8 @@ void S_Update_(void) { ch = s_channels; for ( i = 0; i < MAX_CHANNELS ; i++, ch++ ) - { - if ( !ch->thesfx || (ch->leftvol<0.25 && ch->rightvol<0.25 ) || (ch->bPlaying)) + { + if ( !ch->thesfx || (ch->bPlaying)) continue; // if ( ch->entchannel == CHAN_VOICE || ch->entchannel == CHAN_VOICE_ATTEN || ch->entchannel == CHAN_VOICE_GLOBAL ) @@ -2837,12 +2889,6 @@ void UpdateLoopingSounds() ch->master_vol = loop->volume; alSourcef(s_channels[i].alSource, AL_GAIN, (float)(ch->master_vol) / 255.f); -//#ifdef _DEBUG -// char szString[256]; -// sprintf(szString, "Updating position of Looping %s on channel %d to %.3f, %.3f, %.3f\n", ch->thesfx->sSoundName, i, pos[0], pos[1], pos[2]); -// OutputDebugString(szString); -//#endif - if (s_bEALFileLoaded) UpdateEAXBuffer(ch); @@ -2869,12 +2915,6 @@ void UpdateLoopingSounds() OutputDebugString(szString); } -//#ifdef _DEBUG -// char szString[256]; -// sprintf(szString, "Stopped looping %s on channel %d\n", ch->thesfx->sSoundName, i); -// OutputDebugString(szString); -//#endif - ch->thesfx = NULL; ch->bPlaying = false; } @@ -2934,12 +2974,6 @@ void UpdateLoopingSounds() alSourcePlay(s_channels[source].alSource); if (alGetError() == AL_NO_ERROR) s_channels[source].bPlaying = true; - -//#ifdef _DEBUG -// char szString[256]; -// sprintf(szString, "Looping %s on channel %d at %.3f, %.3f, %.3f\n", ch->thesfx->sSoundName, source, pos[0], pos[1], pos[2]); -// OutputDebugString(szString); -//#endif } } } @@ -3039,9 +3073,24 @@ void UpdateRawSamples() alGetSourcei(s_channels[0].alSource, AL_SOURCE_STATE, &state); if (state != AL_PLAYING) { -//#ifdef _DEBUG -// OutputDebugString("Restarting / Starting playback of Raw Samples\n"); -//#endif + // Stopped playing ... due to buffer underrun + // Unqueue any buffers still on the Source (they will be PROCESSED), and restart playback + alGetSourcei(s_channels[0].alSource, AL_BUFFERS_PROCESSED, &processed); + while (processed) + { + alSourceUnqueueBuffers(s_channels[0].alSource, 1, &buffer); + processed--; + alGetBufferi(buffer, AL_SIZE, &size); + alDeleteBuffers(1, &buffer); + + // Update sg.soundtime (+= number of samples played (number of bytes / 4)) + s_soundtime += (size >> 2); + } + +#ifdef _DEBUG + OutputDebugString("Restarting / Starting playback of Raw Samples\n"); +#endif + alSourcePlay(s_channels[0].alSource); } } @@ -3291,9 +3340,15 @@ void S_SoundList_f( void ) { int iTotalBytes = 0; qboolean bWavOnly = qfalse; + qboolean bShouldBeMP3 = qfalse; if ( Cmd_Argc() == 2 ) { + if (!stricmp(Cmd_Argv(1), "shouldbeMP3")) + { + bShouldBeMP3 = qtrue; + } + else if (!stricmp(Cmd_Argv(1), "wavonly")) { bWavOnly = qtrue; @@ -3318,7 +3373,7 @@ void S_SoundList_f( void ) { } else { - Com_Printf("( additional option available: 'wavonly', or '1'/'2'/'3' for %%d-variant capping )\n" ); + Com_Printf("( additional (mutually exclusive) options available:\n'wavonly', 'ShouldBeMP3', '1'/'2'/'3' for %%d-variant capping )\n" ); } @@ -3336,7 +3391,10 @@ void S_SoundList_f( void ) { for (sfx=s_knownSfx, i=0 ; ieSoundCompressionMethod == ct_16) + extern cvar_t *cv_MP3overhead; + qboolean bMP3DumpOverride = bShouldBeMP3 && cv_MP3overhead && !sfx->bDefaultSound && !sfx->pMP3StreamHeader && sfx->pSoundData && (Z_Size(sfx->pSoundData) > cv_MP3overhead->integer); + + if (bMP3DumpOverride || (!bShouldBeMP3 && (!bWavOnly || sfx->eSoundCompressionMethod == ct_16))) { qboolean bDumpThisOne = qtrue; if (iVariantCap >= 1 && iVariantCap <= 3) @@ -3538,7 +3596,7 @@ static void FreeMusic( MusicInfo_t *pMusicInfo ) } } -// called only by snd_restart +// called only by snd_shutdown (from snd_restart or app exit) // void S_UnCacheDynamicMusic( void ) { @@ -3548,7 +3606,7 @@ void S_UnCacheDynamicMusic( void ) } } -static void S_StartBackgroundTrack_Actual( MusicInfo_t *pMusicInfo, qboolean qbDynamic, const char *intro, const char *loop ) +static qboolean S_StartBackgroundTrack_Actual( MusicInfo_t *pMusicInfo, qboolean qbDynamic, const char *intro, const char *loop ) { int len; char dump[16]; @@ -3569,7 +3627,7 @@ static void S_StartBackgroundTrack_Actual( MusicInfo_t *pMusicInfo, qboolean qbD pMusicInfo->bIsMP3 = qfalse; if ( !intro[0] ) { - return; + return qfalse; } // new bit, if file requested is not same any loaded one (if prev was in-mem), ditch it... @@ -3593,7 +3651,7 @@ static void S_StartBackgroundTrack_Actual( MusicInfo_t *pMusicInfo, qboolean qbD if (!pMusicInfo->s_backgroundFile) { Com_Printf( S_COLOR_RED"Couldn't open music file %s\n", name ); - return; + return qfalse; } MP3MusicStream_Reset( pMusicInfo ); @@ -3602,7 +3660,7 @@ static void S_StartBackgroundTrack_Actual( MusicInfo_t *pMusicInfo, qboolean qbD int iInitialMP3ReadSize = 8192; // fairly arbitrary, whatever size this is then the decoder is allowed to // scan up to halfway of it to find floating headers, so don't make it // too small. 8k works fine. - + qboolean bMusicSucceeded = qfalse; if (qbDynamic) { if (!pMusicInfo->pLoadedData) @@ -3672,6 +3730,7 @@ static void S_StartBackgroundTrack_Actual( MusicInfo_t *pMusicInfo, qboolean qbD } pMusicInfo->bIsMP3 = qtrue; + bMusicSucceeded = qtrue; } else { @@ -3694,7 +3753,7 @@ static void S_StartBackgroundTrack_Actual( MusicInfo_t *pMusicInfo, qboolean qbD pMusicInfo->s_backgroundFile = 0; } - return; + return bMusicSucceeded; } else // not an mp3 file { @@ -3704,7 +3763,7 @@ static void S_StartBackgroundTrack_Actual( MusicInfo_t *pMusicInfo, qboolean qbD FS_FOpenFileRead( name, &pMusicInfo->s_backgroundFile, qtrue ); if ( !pMusicInfo->s_backgroundFile ) { Com_Printf( S_COLOR_YELLOW "WARNING: couldn't open music file %s\n", name ); - return; + return qfalse; } // skip the riff wav header @@ -3715,7 +3774,7 @@ static void S_StartBackgroundTrack_Actual( MusicInfo_t *pMusicInfo, qboolean qbD Com_Printf( S_COLOR_YELLOW "WARNING: No fmt chunk in %s\n", name ); FS_FCloseFile( pMusicInfo->s_backgroundFile ); pMusicInfo->s_backgroundFile = 0; - return; + return qfalse; } // save name for soundinfo @@ -3730,7 +3789,7 @@ static void S_StartBackgroundTrack_Actual( MusicInfo_t *pMusicInfo, qboolean qbD FS_FCloseFile( pMusicInfo->s_backgroundFile ); pMusicInfo->s_backgroundFile = 0; Com_Printf(S_COLOR_YELLOW "WARNING: Not a microsoft PCM format wav: %s\n", name); - return; + return qfalse; } if ( pMusicInfo->s_backgroundInfo.channels != 2 || pMusicInfo->s_backgroundInfo.rate != 22050 ) { @@ -3741,7 +3800,7 @@ static void S_StartBackgroundTrack_Actual( MusicInfo_t *pMusicInfo, qboolean qbD FS_FCloseFile( pMusicInfo->s_backgroundFile ); pMusicInfo->s_backgroundFile = 0; Com_Printf(S_COLOR_YELLOW "WARNING: No data chunk in %s\n", name); - return; + return qfalse; } pMusicInfo->s_backgroundInfo.samples = len / (pMusicInfo->s_backgroundInfo.width * pMusicInfo->s_backgroundInfo.channels); @@ -3753,6 +3812,8 @@ static void S_StartBackgroundTrack_Actual( MusicInfo_t *pMusicInfo, qboolean qbD // Sys_BeginStreamedFile( pMusicInfo->s_backgroundFile, 0x10000 ); } + + return qtrue; } @@ -4001,9 +4062,6 @@ void S_StartBackgroundTrack( const char *intro, const char *loop, qboolean bCall char sName[MAX_QPATH]; Q_strncpyz(sName,intro,sizeof(sName)); - if (!sName[0]) - return; // no music specified - COM_DefaultExtension( sName, sizeof( sName ), ".mp3" ); // if low physical memory, then just stream the explore music instead of playing dynamic... @@ -4017,7 +4075,6 @@ void S_StartBackgroundTrack( const char *intro, const char *loop, qboolean bCall } } - // conceptually we always play the 'intro'[/sName] track, intro-to-loop transition is handled in UpdateBackGroundTrack(). // if ( (strstr(sName,"/") && S_FileExists( sName )) ) // strstr() check avoids extra file-exists check at runtime if reverting from streamed music to dynamic since literal files all need at least one slash in their name (eg "music/blah") @@ -4031,15 +4088,18 @@ void S_StartBackgroundTrack( const char *intro, const char *loop, qboolean bCall { for (int i = eBGRNDTRACK_DATABEGIN; i != eBGRNDTRACK_DATAEND; i++) { + qboolean bOk = qfalse; LPCSTR psMusicName = Music_GetFileNameForState( (MusicState_e) i); if (psMusicName && (!Q_stricmp(tMusic_Info[i].sLoadedDataName, psMusicName) || S_FileExists( psMusicName )) ) { - S_StartBackgroundTrack_Actual( &tMusic_Info[i], qtrue, psMusicName, loop ); - tMusic_Info[i].bExists = qtrue; + bOk = S_StartBackgroundTrack_Actual( &tMusic_Info[i], qtrue, psMusicName, loop ); } - else + + tMusic_Info[i].bExists = bOk; + + if (!tMusic_Info[i].bExists) { - tMusic_Info[i].bExists = qfalse; + FreeMusic( &tMusic_Info[i] ); } } @@ -4049,7 +4109,6 @@ void S_StartBackgroundTrack( const char *intro, const char *loop, qboolean bCall for (i=0; ibInMemory && sfx->iLastTimeUsed < iOldest) + if (!sfx->bDefaultSound && sfx->bInMemory && sfx->iLastTimeUsed < iOldest) { // new bit, we can't throw away any sfx_t struct in use by a channel, else the paint code will crash... // @@ -4957,8 +5014,8 @@ void UpdateEAXBuffer(channel_t *ch) if (ch->fixed_origin) { EMSourcePoint.fX = ch->origin[0]; - EMSourcePoint.fY = ch->origin[1]; - EMSourcePoint.fZ = -ch->origin[2]; + EMSourcePoint.fY = ch->origin[2]; + EMSourcePoint.fZ = ch->origin[1]; } else { @@ -4967,15 +5024,16 @@ void UpdateEAXBuffer(channel_t *ch) // Source at same position as listener // Probably won't be any Occlusion / Obstruction effect -- unless the listener is underwater EMSourcePoint.fX = listener_pos[0]; - EMSourcePoint.fY = listener_pos[1]; - EMSourcePoint.fZ = -listener_pos[2]; + EMSourcePoint.fY = listener_pos[2]; + EMSourcePoint.fZ = listener_pos[1]; } else { // Get position of Entity EMSourcePoint.fX = loopSounds[ ch->entnum ].origin[0]; - EMSourcePoint.fY = loopSounds[ ch->entnum ].origin[1]; - EMSourcePoint.fZ = -loopSounds[ ch->entnum ].origin[2]; + EMSourcePoint.fY = loopSounds[ ch->entnum ].origin[2]; + EMSourcePoint.fZ = loopSounds[ ch->entnum ].origin[1]; + } } @@ -5036,3 +5094,328 @@ void EAXMorph() } } + +/***********************************************************************************************\ +* +* Definition of the EAXMorph function - EAX3ListenerInterpolate +* +\***********************************************************************************************/ + +/* + EAX3ListenerInterpolate + lpStart - Initial EAX 3 Listener parameters + lpFinish - Final EAX 3 Listener parameters + flRatio - Ratio Destination : Source (0.0 == Source, 1.0 == Destination) + lpResult - Interpolated EAX 3 Listener parameters + bCheckValues - Check EAX 3.0 parameters are in range, default = false (no checking) +*/ +bool EAX3ListenerInterpolate(LPEAXLISTENERPROPERTIES lpStart, LPEAXLISTENERPROPERTIES lpFinish, + float flRatio, LPEAXLISTENERPROPERTIES lpResult, bool bCheckValues) +{ + EAXVECTOR StartVector, FinalVector; + + float flInvRatio; + + if (bCheckValues) + { + if (!CheckEAX3LP(lpStart)) + return false; + + if (!CheckEAX3LP(lpFinish)) + return false; + } + + if (flRatio >= 1.0f) + { + memcpy(lpResult, lpFinish, sizeof(EAXLISTENERPROPERTIES)); + return true; + } + else if (flRatio <= 0.0f) + { + memcpy(lpResult, lpStart, sizeof(EAXLISTENERPROPERTIES)); + return true; + } + + flInvRatio = (1.0f - flRatio); + + // Environment + lpResult->ulEnvironment = 26; // (UNDEFINED environment) + + // Environment Size + if (lpStart->flEnvironmentSize == lpFinish->flEnvironmentSize) + lpResult->flEnvironmentSize = lpStart->flEnvironmentSize; + else + lpResult->flEnvironmentSize = (float)exp( (log(lpStart->flEnvironmentSize) * flInvRatio) + (log(lpFinish->flEnvironmentSize) * flRatio) ); + + // Environment Diffusion + if (lpStart->flEnvironmentDiffusion == lpFinish->flEnvironmentDiffusion) + lpResult->flEnvironmentDiffusion = lpStart->flEnvironmentDiffusion; + else + lpResult->flEnvironmentDiffusion = (lpStart->flEnvironmentDiffusion * flInvRatio) + (lpFinish->flEnvironmentDiffusion * flRatio); + + // Room + if (lpStart->lRoom == lpFinish->lRoom) + lpResult->lRoom = lpStart->lRoom; + else + lpResult->lRoom = (int)( ((float)lpStart->lRoom * flInvRatio) + ((float)lpFinish->lRoom * flRatio) ); + + // Room HF + if (lpStart->lRoomHF == lpFinish->lRoomHF) + lpResult->lRoomHF = lpStart->lRoomHF; + else + lpResult->lRoomHF = (int)( ((float)lpStart->lRoomHF * flInvRatio) + ((float)lpFinish->lRoomHF * flRatio) ); + + // Room LF + if (lpStart->lRoomLF == lpFinish->lRoomLF) + lpResult->lRoomLF = lpStart->lRoomLF; + else + lpResult->lRoomLF = (int)( ((float)lpStart->lRoomLF * flInvRatio) + ((float)lpFinish->lRoomLF * flRatio) ); + + // Decay Time + if (lpStart->flDecayTime == lpFinish->flDecayTime) + lpResult->flDecayTime = lpStart->flDecayTime; + else + lpResult->flDecayTime = (float)exp( (log(lpStart->flDecayTime) * flInvRatio) + (log(lpFinish->flDecayTime) * flRatio) ); + + // Decay HF Ratio + if (lpStart->flDecayHFRatio == lpFinish->flDecayHFRatio) + lpResult->flDecayHFRatio = lpStart->flDecayHFRatio; + else + lpResult->flDecayHFRatio = (float)exp( (log(lpStart->flDecayHFRatio) * flInvRatio) + (log(lpFinish->flDecayHFRatio) * flRatio) ); + + // Decay LF Ratio + if (lpStart->flDecayLFRatio == lpFinish->flDecayLFRatio) + lpResult->flDecayLFRatio = lpStart->flDecayLFRatio; + else + lpResult->flDecayLFRatio = (float)exp( (log(lpStart->flDecayLFRatio) * flInvRatio) + (log(lpFinish->flDecayLFRatio) * flRatio) ); + + // Reflections + if (lpStart->lReflections == lpFinish->lReflections) + lpResult->lReflections = lpStart->lReflections; + else + lpResult->lReflections = (int)( ((float)lpStart->lReflections * flInvRatio) + ((float)lpFinish->lReflections * flRatio) ); + + // Reflections Delay + if (lpStart->flReflectionsDelay == lpFinish->flReflectionsDelay) + lpResult->flReflectionsDelay = lpStart->flReflectionsDelay; + else + lpResult->flReflectionsDelay = (float)exp( (log(lpStart->flReflectionsDelay+0.0001) * flInvRatio) + (log(lpFinish->flReflectionsDelay+0.0001) * flRatio) ); + + // Reflections Pan + + // To interpolate the vector correctly we need to ensure that both the initial and final vectors vectors are clamped to a length of 1.0f + StartVector = lpStart->vReflectionsPan; + FinalVector = lpFinish->vReflectionsPan; + + Clamp(&StartVector); + Clamp(&FinalVector); + + if (lpStart->vReflectionsPan.x == lpFinish->vReflectionsPan.x) + lpResult->vReflectionsPan.x = lpStart->vReflectionsPan.x; + else + lpResult->vReflectionsPan.x = FinalVector.x + (flInvRatio * (StartVector.x - FinalVector.x)); + + if (lpStart->vReflectionsPan.y == lpFinish->vReflectionsPan.y) + lpResult->vReflectionsPan.y = lpStart->vReflectionsPan.y; + else + lpResult->vReflectionsPan.y = FinalVector.y + (flInvRatio * (StartVector.y - FinalVector.y)); + + if (lpStart->vReflectionsPan.z == lpFinish->vReflectionsPan.z) + lpResult->vReflectionsPan.z = lpStart->vReflectionsPan.z; + else + lpResult->vReflectionsPan.z = FinalVector.z + (flInvRatio * (StartVector.z - FinalVector.z)); + + // Reverb + if (lpStart->lReverb == lpFinish->lReverb) + lpResult->lReverb = lpStart->lReverb; + else + lpResult->lReverb = (int)( ((float)lpStart->lReverb * flInvRatio) + ((float)lpFinish->lReverb * flRatio) ); + + // Reverb Delay + if (lpStart->flReverbDelay == lpFinish->flReverbDelay) + lpResult->flReverbDelay = lpStart->flReverbDelay; + else + lpResult->flReverbDelay = (float)exp( (log(lpStart->flReverbDelay+0.0001) * flInvRatio) + (log(lpFinish->flReverbDelay+0.0001) * flRatio) ); + + // Reverb Pan + + // To interpolate the vector correctly we need to ensure that both the initial and final vectors are clamped to a length of 1.0f + StartVector = lpStart->vReverbPan; + FinalVector = lpFinish->vReverbPan; + + Clamp(&StartVector); + Clamp(&FinalVector); + + if (lpStart->vReverbPan.x == lpFinish->vReverbPan.x) + lpResult->vReverbPan.x = lpStart->vReverbPan.x; + else + lpResult->vReverbPan.x = FinalVector.x + (flInvRatio * (StartVector.x - FinalVector.x)); + + if (lpStart->vReverbPan.y == lpFinish->vReverbPan.y) + lpResult->vReverbPan.y = lpStart->vReverbPan.y; + else + lpResult->vReverbPan.y = FinalVector.y + (flInvRatio * (StartVector.y - FinalVector.y)); + + if (lpStart->vReverbPan.z == lpFinish->vReverbPan.z) + lpResult->vReverbPan.z = lpStart->vReverbPan.z; + else + lpResult->vReverbPan.z = FinalVector.z + (flInvRatio * (StartVector.z - FinalVector.z)); + + // Echo Time + if (lpStart->flEchoTime == lpFinish->flEchoTime) + lpResult->flEchoTime = lpStart->flEchoTime; + else + lpResult->flEchoTime = (float)exp( (log(lpStart->flEchoTime) * flInvRatio) + (log(lpFinish->flEchoTime) * flRatio) ); + + // Echo Depth + if (lpStart->flEchoDepth == lpFinish->flEchoDepth) + lpResult->flEchoDepth = lpStart->flEchoDepth; + else + lpResult->flEchoDepth = (lpStart->flEchoDepth * flInvRatio) + (lpFinish->flEchoDepth * flRatio); + + // Modulation Time + if (lpStart->flModulationTime == lpFinish->flModulationTime) + lpResult->flModulationTime = lpStart->flModulationTime; + else + lpResult->flModulationTime = (float)exp( (log(lpStart->flModulationTime) * flInvRatio) + (log(lpFinish->flModulationTime) * flRatio) ); + + // Modulation Depth + if (lpStart->flModulationDepth == lpFinish->flModulationDepth) + lpResult->flModulationDepth = lpStart->flModulationDepth; + else + lpResult->flModulationDepth = (lpStart->flModulationDepth * flInvRatio) + (lpFinish->flModulationDepth * flRatio); + + // Air Absorption HF + if (lpStart->flAirAbsorptionHF == lpFinish->flAirAbsorptionHF) + lpResult->flAirAbsorptionHF = lpStart->flAirAbsorptionHF; + else + lpResult->flAirAbsorptionHF = (lpStart->flAirAbsorptionHF * flInvRatio) + (lpFinish->flAirAbsorptionHF * flRatio); + + // HF Reference + if (lpStart->flHFReference == lpFinish->flHFReference) + lpResult->flHFReference = lpStart->flHFReference; + else + lpResult->flHFReference = (float)exp( (log(lpStart->flHFReference) * flInvRatio) + (log(lpFinish->flHFReference) * flRatio) ); + + // LF Reference + if (lpStart->flLFReference == lpFinish->flLFReference) + lpResult->flLFReference = lpStart->flLFReference; + else + lpResult->flLFReference = (float)exp( (log(lpStart->flLFReference) * flInvRatio) + (log(lpFinish->flLFReference) * flRatio) ); + + // Room Rolloff Factor + if (lpStart->flRoomRolloffFactor == lpFinish->flRoomRolloffFactor) + lpResult->flRoomRolloffFactor = lpStart->flRoomRolloffFactor; + else + lpResult->flRoomRolloffFactor = (lpStart->flRoomRolloffFactor * flInvRatio) + (lpFinish->flRoomRolloffFactor * flRatio); + + // Flags + lpResult->ulFlags = (lpStart->ulFlags & lpFinish->ulFlags); + + // Clamp Delays + if (lpResult->flReflectionsDelay > EAXLISTENER_MAXREFLECTIONSDELAY) + lpResult->flReflectionsDelay = EAXLISTENER_MAXREFLECTIONSDELAY; + + if (lpResult->flReverbDelay > EAXLISTENER_MAXREVERBDELAY) + lpResult->flReverbDelay = EAXLISTENER_MAXREVERBDELAY; + + return true; +} + + +/* + CheckEAX3LP + Checks that the parameters in the EAX 3 Listener Properties structure are in-range +*/ +bool CheckEAX3LP(LPEAXLISTENERPROPERTIES lpEAX3LP) +{ + if ( (lpEAX3LP->lRoom < EAXLISTENER_MINROOM) || (lpEAX3LP->lRoom > EAXLISTENER_MAXROOM) ) + return false; + + if ( (lpEAX3LP->lRoomHF < EAXLISTENER_MINROOMHF) || (lpEAX3LP->lRoomHF > EAXLISTENER_MAXROOMHF) ) + return false; + + if ( (lpEAX3LP->lRoomLF < EAXLISTENER_MINROOMLF) || (lpEAX3LP->lRoomLF > EAXLISTENER_MAXROOMLF) ) + return false; + + if ( (lpEAX3LP->ulEnvironment < EAXLISTENER_MINENVIRONMENT) || (lpEAX3LP->ulEnvironment > EAXLISTENER_MAXENVIRONMENT) ) + return false; + + if ( (lpEAX3LP->flEnvironmentSize < EAXLISTENER_MINENVIRONMENTSIZE) || (lpEAX3LP->flEnvironmentSize > EAXLISTENER_MAXENVIRONMENTSIZE) ) + return false; + + if ( (lpEAX3LP->flEnvironmentDiffusion < EAXLISTENER_MINENVIRONMENTDIFFUSION) || (lpEAX3LP->flEnvironmentDiffusion > EAXLISTENER_MAXENVIRONMENTDIFFUSION) ) + return false; + + if ( (lpEAX3LP->flDecayTime < EAXLISTENER_MINDECAYTIME) || (lpEAX3LP->flDecayTime > EAXLISTENER_MAXDECAYTIME) ) + return false; + + if ( (lpEAX3LP->flDecayHFRatio < EAXLISTENER_MINDECAYHFRATIO) || (lpEAX3LP->flDecayHFRatio > EAXLISTENER_MAXDECAYHFRATIO) ) + return false; + + if ( (lpEAX3LP->flDecayLFRatio < EAXLISTENER_MINDECAYLFRATIO) || (lpEAX3LP->flDecayLFRatio > EAXLISTENER_MAXDECAYLFRATIO) ) + return false; + + if ( (lpEAX3LP->lReflections < EAXLISTENER_MINREFLECTIONS) || (lpEAX3LP->lReflections > EAXLISTENER_MAXREFLECTIONS) ) + return false; + + if ( (lpEAX3LP->flReflectionsDelay < EAXLISTENER_MINREFLECTIONSDELAY) || (lpEAX3LP->flReflectionsDelay > EAXLISTENER_MAXREFLECTIONSDELAY) ) + return false; + + if ( (lpEAX3LP->lReverb < EAXLISTENER_MINREVERB) || (lpEAX3LP->lReverb > EAXLISTENER_MAXREVERB) ) + return false; + + if ( (lpEAX3LP->flReverbDelay < EAXLISTENER_MINREVERBDELAY) || (lpEAX3LP->flReverbDelay > EAXLISTENER_MAXREVERBDELAY) ) + return false; + + if ( (lpEAX3LP->flEchoTime < EAXLISTENER_MINECHOTIME) || (lpEAX3LP->flEchoTime > EAXLISTENER_MAXECHOTIME) ) + return false; + + if ( (lpEAX3LP->flEchoDepth < EAXLISTENER_MINECHODEPTH) || (lpEAX3LP->flEchoDepth > EAXLISTENER_MAXECHODEPTH) ) + return false; + + if ( (lpEAX3LP->flModulationTime < EAXLISTENER_MINMODULATIONTIME) || (lpEAX3LP->flModulationTime > EAXLISTENER_MAXMODULATIONTIME) ) + return false; + + if ( (lpEAX3LP->flModulationDepth < EAXLISTENER_MINMODULATIONDEPTH) || (lpEAX3LP->flModulationDepth > EAXLISTENER_MAXMODULATIONDEPTH) ) + return false; + + if ( (lpEAX3LP->flAirAbsorptionHF < EAXLISTENER_MINAIRABSORPTIONHF) || (lpEAX3LP->flAirAbsorptionHF > EAXLISTENER_MAXAIRABSORPTIONHF) ) + return false; + + if ( (lpEAX3LP->flHFReference < EAXLISTENER_MINHFREFERENCE) || (lpEAX3LP->flHFReference > EAXLISTENER_MAXHFREFERENCE) ) + return false; + + if ( (lpEAX3LP->flLFReference < EAXLISTENER_MINLFREFERENCE) || (lpEAX3LP->flLFReference > EAXLISTENER_MAXLFREFERENCE) ) + return false; + + if ( (lpEAX3LP->flRoomRolloffFactor < EAXLISTENER_MINROOMROLLOFFFACTOR) || (lpEAX3LP->flRoomRolloffFactor > EAXLISTENER_MAXROOMROLLOFFFACTOR) ) + return false; + + if (lpEAX3LP->ulFlags & EAXLISTENERFLAGS_RESERVED) + return false; + + return true; +} + +/* + Clamp + Clamps the length of the vector to 1.0f +*/ +void Clamp(EAXVECTOR *eaxVector) +{ + float flMagnitude; + float flInvMagnitude; + + flMagnitude = (float)sqrt((eaxVector->x*eaxVector->x) + (eaxVector->y*eaxVector->y) + (eaxVector->z*eaxVector->z)); + + if (flMagnitude <= 1.0f) + return; + + flInvMagnitude = 1.0f / flMagnitude; + + eaxVector->x *= flInvMagnitude; + eaxVector->y *= flInvMagnitude; + eaxVector->z *= flInvMagnitude; +} + diff --git a/code/client/snd_local.h b/code/client/snd_local.h index c041f05..bab7ee3 100644 --- a/code/client/snd_local.h +++ b/code/client/snd_local.h @@ -13,7 +13,10 @@ #include "openal\alc.h" #include "eax\eax.h" #include "eax\eaxman.h" -#include "eax\eax-util.h" + +// Added for Open AL to know when to mute all sounds (e.g when app. loses focus) +void S_AL_MuteAllSounds(qboolean bMute); + //from SND_AMBIENT extern void AS_Init( void ); diff --git a/code/client/snd_mem.cpp b/code/client/snd_mem.cpp index 2c7fc54..2a9f3ff 100644 --- a/code/client/snd_mem.cpp +++ b/code/client/snd_mem.cpp @@ -10,7 +10,7 @@ // Open AL void S_PreProcessLipSync(sfx_t *sfx); - +extern int s_UseOpenAL; /* =============================================================================== @@ -748,7 +748,7 @@ static qboolean S_LoadSound_Actual( sfx_t *sfx ) { // Com_DPrintf("(Keeping file \"%s\" as MP3)\n",sLoadName); - if (extern s_UseOpenAL) + if (s_UseOpenAL) { // Create space for lipsync data (4 lip sync values per streaming AL buffer) if (strstr(sfx->sSoundName, "chars")) @@ -790,7 +790,7 @@ static qboolean S_LoadSound_Actual( sfx_t *sfx ) S_LoadSound_Finalize(&info,sfx,pbUnpackBuffer); // Open AL - if (extern s_UseOpenAL) + if (s_UseOpenAL) { if (strstr(sfx->sSoundName, "chars")) { @@ -860,7 +860,7 @@ static qboolean S_LoadSound_Actual( sfx_t *sfx ) ResampleSfx( sfx, info.rate, info.width, data + info.dataofs ); // Open AL - if (extern s_UseOpenAL) + if (s_UseOpenAL) { if (strstr(sfx->sSoundName, "char")) { diff --git a/code/client/snd_public.h b/code/client/snd_public.h index d42df55..15a2756 100644 --- a/code/client/snd_public.h +++ b/code/client/snd_public.h @@ -18,9 +18,7 @@ float S_GetSampleLengthInMilliSeconds( sfxHandle_t sfxHandle); // cinematics and voice-over-network will send raw samples // 1.0 volume will be direct output of source samples -void S_RawSamples (int samples, int rate, int width, int channels, - const byte *data, float volume); - +void S_RawSamples( int samples, int rate, int width, int s_channels, const byte *data, float volume, qboolean bFirstOrOnlyUpdateThisFrame ); // stop all sounds void S_StopSounds(void); // from snd_dma.cpp // stop all sounds and the background track diff --git a/code/client/vssver.scc b/code/client/vssver.scc new file mode 100644 index 0000000..568b4bf Binary files /dev/null and b/code/client/vssver.scc differ diff --git a/code/encryption/vssver.scc b/code/encryption/vssver.scc new file mode 100644 index 0000000..255a848 Binary files /dev/null and b/code/encryption/vssver.scc differ diff --git a/code/ghoul2/g2.h b/code/ghoul2/g2.h index c63536a..25284a0 100644 --- a/code/ghoul2/g2.h +++ b/code/ghoul2/g2.h @@ -171,7 +171,9 @@ char *G2API_GetAnimFileNameIndex(qhandle_t modelIndex); int G2API_GetSurfaceRenderStatus(CGhoul2Info *ghlInfo, const char *surfaceName); // From tr_ghoul2.cpp -void G2_ConstructGhoulSkeleton( CGhoul2Info_v &ghoul2, const int frameNum, qhandle_t *modelList, bool checkForNewOrigin, const vec3_t position, const vec3_t scale, bool modelSet); +void G2_ConstructGhoulSkeleton( CGhoul2Info_v &ghoul2,const int frameNum,bool checkForNewOrigin,const vec3_t scale); +void G2_GetBoltMatrixLow(CGhoul2Info &ghoul2,int boltNum,const vec3_t scale,mdxaBone_t &retMatrix); +void G2_TimingModel(boneInfo_t &bone,int time,int numFramesInFile,int ¤tFrame,int &newFrame,float &lerp); #endif // G2_H_INC \ No newline at end of file diff --git a/code/ghoul2/g2_api.cpp b/code/ghoul2/g2_api.cpp index 1a34b4e..64a08bc 100644 --- a/code/ghoul2/g2_api.cpp +++ b/code/ghoul2/g2_api.cpp @@ -2,7 +2,14 @@ // #include "../server/exe_headers.h" +#pragma warning( disable : 4786) +#pragma warning( disable : 4100) +#pragma warning( disable : 4511) + +#pragma warning (push, 3) //go back down to 3 for the stl include #include +#include +#pragma warning (pop) #ifndef __Q_SHARED_H #include "../game/q_shared.h" @@ -20,15 +27,190 @@ #include "..\qcommon\MiniHeap.h" #endif + +using namespace std; + extern mdxaBone_t worldMatrix; extern mdxaBone_t worldMatrixInv; +extern cvar_t *r_Ghoul2TimeBase; + +#define G2_DEBUG_TIME (0) + +static int G2TimeBases[NUM_G2T_TIME]; + + +#if _DEBUG +#define MAX_ERROR_PRINTS (25) +class ErrorReporter +{ + string mName; + map mErrors; +public: + ErrorReporter(const string &name) : + mName(name) + { + } + ~ErrorReporter() + { + char mess[1000]; + int total=0; + sprintf(mess,"****** %s Error Report Begin******\n",mName.c_str()); + OutputDebugString(mess); + + map::iterator i; + for (i=mErrors.begin();i!=mErrors.end();i++) + { + total+=(*i).second; + sprintf(mess,"%s (hits %d)\n",(*i).first.c_str(),(*i).second); + OutputDebugString(mess); + } + + sprintf(mess,"****** %s Error Report End %d errors of %d kinds******\n",mName.c_str(),total,mErrors.size()); + OutputDebugString(mess); + } + int Error(const char *m,int kind,const char *, int line) + { + char mess[1000]; + assert(m); + string full=mName; + if (kind==2) + { + full+=":NOTE: "; + } + else if (kind==1) + { + full+=":WARNING: "; + } + else + { + full+=":ERROR : "; + } + full+=m; + sprintf(mess," [line %d]",line); + full+=mess; + + // assert(0); + int ret=0; //place a breakpoint here + map::iterator f=mErrors.find(full); + if (f==mErrors.end()) + { + ret++; // or a breakpoint here for the first occurance + mErrors.insert(pair(full,0)); + f=mErrors.find(full); + } + assert(f!=mErrors.end()); + (*f).second++; + if ((*f).second==1000) + { + ret*=-1; // breakpoint to find a specific occurance of an error + } + if ((*f).second<=MAX_ERROR_PRINTS&&kind<2) + { + Com_Printf("%s (hit # %d)\n",full.c_str(),(*f).second); + if (1) + { + sprintf(mess,"%s (hit # %d)\n",full.c_str(),(*f).second); + OutputDebugString(mess); + } + } + return ret; + } +}; + +#include "assert.h" +ErrorReporter &G2APIError() +{ + static ErrorReporter singleton("G2API"); + return singleton; +} + +#define G2ERROR(exp,m) (void)( (exp) || (G2APIError().Error(m,0,__FILE__,__LINE__), 0) ) +#define G2WARNING(exp,m) (void)( (exp) || (G2APIError().Error(m,1,__FILE__,__LINE__), 0) ) +#define G2NOTE(exp,m) (void)( (exp) || (G2APIError().Error(m,2,__FILE__,__LINE__), 0) ) +#else + +#define G2ERROR(exp,m) ((void)0) +#define G2WARNING(exp,m) ((void)0) +#define G2NOTE(exp,m) ((void)0) + +#endif + +#ifdef _DEBUG +void G2_Bone_Not_Found(const char *boneName,const char *modName) +{ + G2ERROR(boneName,"NULL Bone Name"); + G2ERROR(boneName[0],"Empty Bone Name"); + if (boneName) + { + G2WARNING(0,va("Bone Not Found (%s:%s)",boneName,modName)); + } +} + +void G2_Bolt_Not_Found(const char *boneName,const char *modName) +{ + G2ERROR(boneName,"NULL Bolt/Bone Name"); + G2ERROR(boneName[0],"Empty Bolt/Bone Name"); + if (boneName) + { + G2WARNING(0,va("Bolt/Bone Not Found (%s:%s)",boneName,modName)); + } +} +#endif + +void G2API_SetTime(int currentTime,int clock) +{ + assert(clock>=0&&clockinteger>0&&r_Ghoul2TimeBase->integer<=NUM_G2T_TIME) + { + timeBase=r_Ghoul2TimeBase->integer; + ret=G2TimeBases[r_Ghoul2TimeBase->integer-1]; + } +#if _DEBUG + if (LastTimeBase!=timeBase) + { + LastTimeBase=timeBase; + if (timeBase==0) + { + Com_Printf("Ghoul2: Using argument time\n"); + } + if (timeBase==1) + { + Com_Printf("Ghoul2: Using server time\n"); + } + if (timeBase==2) + { + Com_Printf("Ghoul2: Using client time\n"); + } + } +#endif +#if G2_DEBUG_TIME + Com_Printf("Ghoul2: Get Time: in%6d c%6d s%6d returning %6d\n",argTime,G2TimeBases[1],G2TimeBases[0],ret); +#endif + return ret; +} + + // must be a power of two #define MAX_G2_MODELS (512) #define G2_MODEL_BITS (9) #define G2_INDEX_MASK (MAX_G2_MODELS-1) - +void RemoveBoneCache(CBoneCache *boneCache); class Ghoul2InfoArray : public IGhoul2InfoArray { @@ -37,7 +219,16 @@ class Ghoul2InfoArray : public IGhoul2InfoArray list mFreeIndecies; void DeleteLow(int idx) { + { + int model; + for (model=0; model< mInfos[idx].size(); model++) + { + RemoveBoneCache(mInfos[idx][model].mBoneCache); + mInfos[idx][model].mBoneCache=0; + } + } mInfos[idx].clear(); + if ((mIds[idx]>>G2_MODEL_BITS)>(1<<(31-G2_MODEL_BITS))) { mIds[idx]=MAX_G2_MODELS+idx; //rollover reset id to minimum value @@ -201,8 +392,9 @@ int G2API_InitGhoul2Model(CGhoul2Info_v &ghoul2, const char *fileName, int model int model = -1; CGhoul2Info newModel; + G2ERROR(fileName&&fileName[0],"NULL filename"); - if (!(fileName[0])) + if (!fileName||!fileName[0]) { assert(fileName[0]); return -1; @@ -218,6 +410,7 @@ int G2API_InitGhoul2Model(CGhoul2Info_v &ghoul2, const char *fileName, int model // on the game side this is valid. On the client side it is valid only after it has been filled in by trap_G2_SetGhoul2ModelIndexes ghoul2[model].mModel = RE_RegisterModel((char *)fileName); model_t *mod_m = R_GetModelByHandle(ghoul2[model].mModel); + G2ERROR(mod_m->type != MOD_BAD,va("Bad Model Type (%s)",fileName)); if (mod_m->type == MOD_BAD) { return -1; @@ -229,7 +422,6 @@ int G2API_InitGhoul2Model(CGhoul2Info_v &ghoul2, const char *fileName, int model ghoul2[model].mCustomShader = customShader; ghoul2[model].mCustomSkin = customSkin; strcpy(ghoul2[model].mFileName, fileName); - ghoul2[model].mCreationID = modelFlags; ghoul2[model].mLodBias = lodBias; ghoul2[model].mAnimFrameDefault = 0; ghoul2[model].mFlags = 0; @@ -245,6 +437,7 @@ int G2API_InitGhoul2Model(CGhoul2Info_v &ghoul2, const char *fileName, int model // on the game side this is valid. On the client side it is valid only after it has been filled in by trap_G2_SetGhoul2ModelIndexes newModel.mModel = RE_RegisterModel((char *)fileName); model_t *mod_m = R_GetModelByHandle(newModel.mModel); + G2ERROR(mod_m->type != MOD_BAD,va("Bad Model Type (%s)",fileName)); if (mod_m->type == MOD_BAD) { return -1; @@ -256,7 +449,6 @@ int G2API_InitGhoul2Model(CGhoul2Info_v &ghoul2, const char *fileName, int model newModel.mCustomShader = customShader; newModel.mCustomSkin = customSkin; strcpy(newModel.mFileName, fileName); - newModel.mCreationID = modelFlags; newModel.mLodBias = lodBias; newModel.mAnimFrameDefault = 0; newModel.mFlags = 0; @@ -273,6 +465,7 @@ int G2API_InitGhoul2Model(CGhoul2Info_v &ghoul2, const char *fileName, int model qboolean G2API_SetLodBias(CGhoul2Info *ghlInfo, int lodBias) { + G2ERROR(ghlInfo,"NULL ghlInfo"); if (ghlInfo) { ghlInfo->mLodBias = lodBias; @@ -283,6 +476,7 @@ qboolean G2API_SetLodBias(CGhoul2Info *ghlInfo, int lodBias) qboolean G2API_SetSkin(CGhoul2Info *ghlInfo, qhandle_t customSkin) { + G2ERROR(ghlInfo,"NULL ghlInfo"); if (ghlInfo) { ghlInfo->mCustomSkin = customSkin; @@ -293,6 +487,7 @@ qboolean G2API_SetSkin(CGhoul2Info *ghlInfo, qhandle_t customSkin) qboolean G2API_SetShader(CGhoul2Info *ghlInfo, qhandle_t customShader) { + G2ERROR(ghlInfo,"NULL ghlInfo"); if (ghlInfo) { ghlInfo->mCustomShader = customShader; @@ -303,6 +498,7 @@ qboolean G2API_SetShader(CGhoul2Info *ghlInfo, qhandle_t customShader) qboolean G2API_SetSurfaceOnOff(CGhoul2Info *ghlInfo, const char *surfaceName, const int flags) { + G2ERROR(ghlInfo,"NULL ghlInfo"); if (ghlInfo) { // ensure we flush the cache @@ -314,6 +510,7 @@ qboolean G2API_SetSurfaceOnOff(CGhoul2Info *ghlInfo, const char *surfaceName, co int G2API_GetSurfaceOnOff(CGhoul2Info *ghlInfo, const char *surfaceName) { + G2ERROR(ghlInfo,"NULL ghlInfo"); if (ghlInfo) { return G2_IsSurfaceOff(ghlInfo->mFileName, ghlInfo->mSlist, surfaceName); @@ -323,11 +520,22 @@ int G2API_GetSurfaceOnOff(CGhoul2Info *ghlInfo, const char *surfaceName) qboolean G2API_SetRootSurface(CGhoul2Info_v &ghlInfo, const int modelIndex, const char *surfaceName) { - return G2_SetRootSurface(ghlInfo, modelIndex, ghlInfo[modelIndex].mFileName, surfaceName); + G2ERROR(ghlInfo.IsValid(),"Invalid ghlInfo"); + G2ERROR(surfaceName,"Invalid surfaceName"); + if (ghlInfo.IsValid()) + { + G2ERROR(modelIndex>=0&&modelIndex=0&&modelIndexmFileName, index); @@ -360,6 +570,8 @@ int G2API_GetParentSurface(CGhoul2Info *ghlInfo, const int index) int G2API_GetSurfaceRenderStatus(CGhoul2Info *ghlInfo, const char *surfaceName) { + G2ERROR(ghlInfo,"NULL ghlInfo"); + G2ERROR(surfaceName,"Invalid surfaceName"); if (ghlInfo) { return G2_IsSurfaceRendered(ghlInfo->mFileName, surfaceName, ghlInfo->mSlist); @@ -370,10 +582,11 @@ int G2API_GetSurfaceRenderStatus(CGhoul2Info *ghlInfo, const char *surfaceName) qboolean G2API_RemoveGhoul2Model(CGhoul2Info_v &ghlInfo, const int modelIndex) { // sanity check - if (!ghlInfo.size() || (ghlInfo.size() <= modelIndex) || (ghlInfo[modelIndex].mModelindex == -1)) + if (!ghlInfo.size() || (ghlInfo.size() <= modelIndex) || (ghlInfo[modelIndex].mModelindex <0)) { // if we hit this assert then we are trying to delete a ghoul2 model on a ghoul2 instance that // one way or another is already gone. + G2ERROR(0,"Remove Nonexistant Model"); assert(0 && "remove non existing model"); return qfalse; } @@ -383,6 +596,8 @@ qboolean G2API_RemoveGhoul2Model(CGhoul2Info_v &ghlInfo, const int modelIndex) ghlInfo[modelIndex].mBltlist.clear(); ghlInfo[modelIndex].mSlist.clear(); + RemoveBoneCache(ghlInfo[modelIndex].mBoneCache); + ghlInfo[modelIndex].mBoneCache=0; // set us to be the 'not active' state ghlInfo[modelIndex].mModelindex = -1; @@ -412,43 +627,148 @@ qboolean G2API_RemoveGhoul2Model(CGhoul2Info_v &ghlInfo, const int modelIndex) qboolean G2API_SetBoneAnimIndex(CGhoul2Info *ghlInfo, const int index, const int startFrame, const int endFrame, const int flags, const float animSpeed, const int currentTime, const float setFrame, const int blendTime) { + qboolean ret=qfalse; + G2ERROR(ghlInfo,"NULL ghlInfo"); if (ghlInfo) { - // ensure we flush the cache - ghlInfo->mSkelFrameNum = 0; - return G2_Set_Bone_Anim_Index(ghlInfo->mBlist, index, startFrame, endFrame, flags, animSpeed, currentTime, setFrame, blendTime); +#if _DEBUG + ghlInfo->mModel = RE_RegisterModel(ghlInfo->mFileName); + const model_t *currentModel = R_GetModelByHandle(ghlInfo->mModel); + G2ERROR(currentModel&¤tModel->mdxm,va("Bad Model (glm) %s",ghlInfo->mFileName)); + if (currentModel&¤tModel->mdxm) + { + const model_t *animModel = R_GetModelByHandle(currentModel->mdxm->animIndex); + G2ERROR(animModel,va("Bad Model (gla) %s",ghlInfo->mFileName)); + if (animModel) + { + const mdxaHeader_t *aHeader = animModel->mdxa; + G2ERROR(aHeader,va("Bad Model (gla) %s",ghlInfo->mFileName)); + if (aHeader) + { + G2ERROR(startFrame>=0,"startframe<0"); + G2ERROR(startFramenumFrames,"startframe>=numframes"); + G2ERROR(endFrame>0,"endframe<=0"); + G2ERROR(endFrame<=aHeader->numFrames,"endframe>numframes"); + G2ERROR(setFramenumFrames,"setframe>=numframes"); + G2ERROR(setFrame==-1.0f||setFrame>=0.0f,"setframe<0 but not -1"); + +#else + { + { + { +#endif + if (startFrame<0)//||startFrame>=aHeader->numFrames) + { + *(int *)&startFrame=0; // cast away const + } + if (endFrame<=0)//||endFrame>aHeader->numFrames) + { + *(int *)&endFrame=1; + } + if (setFrame!=-1.0f&&(setFrame<0.0f/*||setFrame>=(float)aHeader->numFrames*/)) + { + *(float *)&setFrame=0.0f; + } + ghlInfo->mSkelFrameNum = 0; + G2ERROR(index>=0&&indexmBlist.size(),"Bad Bone Index"); + if (index>=0&&indexmBlist.size()) + { + G2ERROR(ghlInfo->mBlist[index].boneNumber>=0,"Bad Bone Index"); + ret=G2_Set_Bone_Anim_Index(ghlInfo->mBlist, index, startFrame, endFrame, flags, animSpeed, currentTime, setFrame, blendTime); + } + } + } + } } - return qfalse; + G2WARNING(ret,"G2API_SetBoneAnimIndex Failed"); + return ret; } qboolean G2API_SetBoneAnim(CGhoul2Info *ghlInfo, const char *boneName, const int startFrame, const int endFrame, const int flags, const float animSpeed, const int currentTime, const float setFrame, const int blendTime) { - if (ghlInfo) + qboolean ret=qfalse; + G2ERROR(ghlInfo,"NULL ghlInfo"); + G2ERROR(boneName,"NULL boneName"); + if (ghlInfo&&boneName) { - // ensure we flush the cache - ghlInfo->mSkelFrameNum = 0; - return G2_Set_Bone_Anim(ghlInfo->mFileName, ghlInfo->mBlist, boneName, startFrame, endFrame, flags, animSpeed, currentTime, setFrame, blendTime); +#if _DEBUG + ghlInfo->mModel = RE_RegisterModel(ghlInfo->mFileName); + const model_t *currentModel = R_GetModelByHandle(ghlInfo->mModel); + G2ERROR(currentModel&¤tModel->mdxm,va("Bad Model (glm) %s",ghlInfo->mFileName)); + if (currentModel&¤tModel->mdxm) + { + const model_t *animModel = R_GetModelByHandle(currentModel->mdxm->animIndex); + G2ERROR(animModel,va("Bad Model (gla) %s",ghlInfo->mFileName)); + if (animModel) + { + const mdxaHeader_t *aHeader = animModel->mdxa; + G2ERROR(aHeader,va("Bad Model (gla) %s",ghlInfo->mFileName)); + if (aHeader) + { + G2ERROR(startFrame>=0,"startframe<0"); + G2ERROR(startFramenumFrames,"startframe>=numframes"); + G2ERROR(endFrame>0,"endframe<=0"); + G2ERROR(endFrame<=aHeader->numFrames,"endframe>numframes"); + G2ERROR(setFramenumFrames,"setframe>=numframes"); + G2ERROR(setFrame==-1.0f||setFrame>=0.0f,"setframe<0 but not -1"); + +#else + { + { + { +#endif + if (startFrame<0)//||startFrame>=aHeader->numFrames) + { + *(int *)&startFrame=0; // cast away const + } + if (endFrame<=0)//||endFrame>aHeader->numFrames) + { + *(int *)&endFrame=1; + } + if (setFrame!=-1.0f&&(setFrame<0.0f/*||setFrame>=(float)aHeader->numFrames*/)) + { + *(float *)&setFrame=0.0f; + } + // ensure we flush the cache + ghlInfo->mSkelFrameNum = 0; + ret=G2_Set_Bone_Anim(ghlInfo->mFileName, ghlInfo->mBlist, boneName, startFrame, endFrame, flags, animSpeed, currentTime, setFrame, blendTime); + } + } + } } - return qfalse; + G2WARNING(ret,"G2API_SetBoneAnim Failed"); + return ret; } -qboolean G2API_GetBoneAnim(CGhoul2Info *ghlInfo, const char *boneName, const int currentTime, float *currentFrame, +qboolean G2API_GetBoneAnim(CGhoul2Info *ghlInfo, const char *boneName, const int AcurrentTime, float *currentFrame, int *startFrame, int *endFrame, int *flags, float *animSpeed, int *modelList) { - if (ghlInfo) + qboolean ret=qfalse; + G2ERROR(ghlInfo,"NULL ghlInfo"); + G2ERROR(boneName,"NULL boneName"); + int currentTime=G2API_GetTime(AcurrentTime); + if (ghlInfo&&boneName) { - return G2_Get_Bone_Anim(ghlInfo->mFileName, ghlInfo->mBlist, boneName, currentTime, currentFrame, + ret=G2_Get_Bone_Anim(ghlInfo->mFileName, ghlInfo->mBlist, boneName, currentTime, currentFrame, startFrame, endFrame, flags, animSpeed, modelList, ghlInfo->mModelindex); } - return qfalse; + G2WARNING(ret,"G2API_GetBoneAnim Failed"); + return ret; } -qboolean G2API_GetBoneAnimIndex(CGhoul2Info *ghlInfo, const int iBoneIndex, const int currentTime, float *currentFrame, +qboolean G2API_GetBoneAnimIndex(CGhoul2Info *ghlInfo, const int iBoneIndex, const int AcurrentTime, float *currentFrame, int *startFrame, int *endFrame, int *flags, float *animSpeed, int *modelList) { + qboolean ret=qfalse; + G2ERROR(ghlInfo,"NULL ghlInfo"); + int currentTime=G2API_GetTime(AcurrentTime); if (ghlInfo) { - return G2_Get_Bone_Anim_Index( ghlInfo->mBlist,// boneInfo_v &blist, + G2ERROR(iBoneIndex>=0&&iBoneIndexmBlist.size(),"Bad Bone Index"); + G2WARNING(ghlInfo->mBlist[iBoneIndex].flags & (BONE_ANIM_OVERRIDE_LOOP | BONE_ANIM_OVERRIDE),"GetBoneAnim on non-animating bone."); + if (iBoneIndex>=0&&iBoneIndexmBlist.size()&&(ghlInfo->mBlist[iBoneIndex].flags & (BONE_ANIM_OVERRIDE_LOOP | BONE_ANIM_OVERRIDE))) + { + ret=G2_Get_Bone_Anim_Index( ghlInfo->mBlist,// boneInfo_v &blist, iBoneIndex, // const int index, currentTime, // const int currentTime, currentFrame, // float *currentFrame, @@ -459,159 +779,240 @@ qboolean G2API_GetBoneAnimIndex(CGhoul2Info *ghlInfo, const int iBoneIndex, cons modelList, // qhandle_t *modelList, ghlInfo->mModelindex // int modelIndex ); + } } - return qfalse; + G2NOTE(ret,"G2API_GetBoneAnimIndex Failed"); + return ret; } qboolean G2API_GetAnimRange(CGhoul2Info *ghlInfo, const char *boneName, int *startFrame, int *endFrame) { - if (ghlInfo) + qboolean ret=qfalse; + G2ERROR(ghlInfo,"NULL ghlInfo"); + G2ERROR(boneName,"NULL boneName"); + if (ghlInfo&&boneName) { - return G2_Get_Bone_Anim_Range(ghlInfo->mFileName, ghlInfo->mBlist, boneName, startFrame, endFrame); + ret=G2_Get_Bone_Anim_Range(ghlInfo->mFileName, ghlInfo->mBlist, boneName, startFrame, endFrame); } - return qfalse; +// looks like the game checks the return value +// G2WARNING(ret,"G2API_GetAnimRange Failed"); + return ret; } qboolean G2API_GetAnimRangeIndex(CGhoul2Info *ghlInfo, const int boneIndex, int *startFrame, int *endFrame) { + qboolean ret=qfalse; + G2ERROR(ghlInfo,"NULL ghlInfo"); if (ghlInfo) { - return G2_Get_Bone_Anim_Range_Index(ghlInfo->mBlist, boneIndex, startFrame, endFrame); + G2ERROR(boneIndex>=0&&boneIndexmBlist.size(),"Bad Bone Index"); + if (boneIndex>=0&&boneIndexmBlist.size()) + { + ret=G2_Get_Bone_Anim_Range_Index(ghlInfo->mBlist, boneIndex, startFrame, endFrame); + } } - return qfalse; +// looks like the game checks the return value +// G2WARNING(ret,"G2API_GetAnimRangeIndex Failed"); + return ret; } -qboolean G2API_PauseBoneAnim(CGhoul2Info *ghlInfo, const char *boneName, const int currentTime) +qboolean G2API_PauseBoneAnim(CGhoul2Info *ghlInfo, const char *boneName, const int AcurrentTime) { - if (ghlInfo) + qboolean ret=qfalse; + G2ERROR(ghlInfo,"NULL ghlInfo"); + G2ERROR(boneName,"NULL boneName"); + int currentTime=G2API_GetTime(AcurrentTime); + if (ghlInfo&&boneName) { - return G2_Pause_Bone_Anim(ghlInfo->mFileName, ghlInfo->mBlist, boneName, currentTime); + ret=G2_Pause_Bone_Anim(ghlInfo->mFileName, ghlInfo->mBlist, boneName, currentTime); } - return qfalse; + G2WARNING(ret,"G2API_PauseBoneAnim Failed"); + return ret; } -qboolean G2API_PauseBoneAnimIndex(CGhoul2Info *ghlInfo, const int boneIndex, const int currentTime) +qboolean G2API_PauseBoneAnimIndex(CGhoul2Info *ghlInfo, const int boneIndex, const int AcurrentTime) { + qboolean ret=qfalse; + G2ERROR(ghlInfo,"NULL ghlInfo"); + int currentTime=G2API_GetTime(AcurrentTime); if (ghlInfo) { - return G2_Pause_Bone_Anim_Index(ghlInfo->mBlist, boneIndex, currentTime); + G2ERROR(boneIndex>=0&&boneIndexmBlist.size(),"Bad Bone Index"); + if (boneIndex>=0&&boneIndexmBlist.size()) + { + ret=G2_Pause_Bone_Anim_Index(ghlInfo->mBlist, boneIndex, currentTime); + } } - return qfalse; + G2WARNING(ret,"G2API_PauseBoneAnimIndex Failed"); + return ret; } qboolean G2API_IsPaused(CGhoul2Info *ghlInfo, const char *boneName) { - if (ghlInfo) + qboolean ret=qfalse; + G2ERROR(ghlInfo,"NULL ghlInfo"); + G2ERROR(boneName,"NULL boneName"); + if (ghlInfo&&boneName) { - return G2_IsPaused(ghlInfo->mFileName, ghlInfo->mBlist, boneName); + ret=G2_IsPaused(ghlInfo->mFileName, ghlInfo->mBlist, boneName); } - return qfalse; + G2WARNING(ret,"G2API_IsPaused Failed"); + return ret; } qboolean G2API_StopBoneAnimIndex(CGhoul2Info *ghlInfo, const int index) { + qboolean ret=qfalse; + G2ERROR(ghlInfo,"NULL ghlInfo"); if (ghlInfo) { - return G2_Stop_Bone_Anim_Index(ghlInfo->mBlist, index); + G2ERROR(index>=0&&indexmBlist.size(),"Bad Bone Index"); + if (index>=0&&indexmBlist.size()) + { + ret=G2_Stop_Bone_Anim_Index(ghlInfo->mBlist, index); + } } - return qfalse; + G2WARNING(ret,"G2API_StopBoneAnimIndex Failed"); + return ret; } qboolean G2API_StopBoneAnim(CGhoul2Info *ghlInfo, const char *boneName) { - if (ghlInfo) + qboolean ret=qfalse; + G2ERROR(ghlInfo,"NULL ghlInfo"); + G2ERROR(boneName,"NULL boneName"); + if (ghlInfo&&boneName) { - return G2_Stop_Bone_Anim(ghlInfo->mFileName, ghlInfo->mBlist, boneName); + ret=G2_Stop_Bone_Anim(ghlInfo->mFileName, ghlInfo->mBlist, boneName); } - return qfalse; + G2WARNING(ret,"G2API_StopBoneAnim Failed"); + return ret; } qboolean G2API_SetBoneAnglesIndex(CGhoul2Info *ghlInfo, const int index, const vec3_t angles, const int flags, const Eorientations yaw, const Eorientations pitch, const Eorientations roll, - qhandle_t *modelList, int blendTime, int currentTime) + qhandle_t *modelList, int blendTime, int AcurrentTime) { + qboolean ret=qfalse; + G2ERROR(ghlInfo,"NULL ghlInfo"); + int currentTime=G2API_GetTime(AcurrentTime); if (ghlInfo) { // ensure we flush the cache ghlInfo->mSkelFrameNum = 0; - return G2_Set_Bone_Angles_Index(ghlInfo->mFileName, ghlInfo->mBlist, index, angles, flags, yaw, pitch, roll, modelList, ghlInfo->mModelindex, blendTime, currentTime); + ret=G2_Set_Bone_Angles_Index(ghlInfo->mFileName, ghlInfo->mBlist, index, angles, flags, yaw, pitch, roll, modelList, ghlInfo->mModelindex, blendTime, currentTime); } - return qfalse; + G2WARNING(ret,"G2API_SetBoneAnglesIndex Failed"); + return ret; } qboolean G2API_SetBoneAngles(CGhoul2Info *ghlInfo, const char *boneName, const vec3_t angles, const int flags, const Eorientations up, const Eorientations left, const Eorientations forward, - qhandle_t *modelList, int blendTime, int currentTime ) + qhandle_t *modelList, int blendTime, int AcurrentTime ) { - if (ghlInfo) + qboolean ret=qfalse; + G2ERROR(ghlInfo,"NULL ghlInfo"); + int currentTime=G2API_GetTime(AcurrentTime); + G2ERROR(boneName,"NULL boneName"); + if (ghlInfo&&boneName) { // ensure we flush the cache ghlInfo->mSkelFrameNum = 0; - return G2_Set_Bone_Angles(ghlInfo->mFileName, ghlInfo->mBlist, boneName, angles, flags, up, left, forward, modelList, ghlInfo->mModelindex, blendTime, currentTime); + ret=G2_Set_Bone_Angles(ghlInfo->mFileName, ghlInfo->mBlist, boneName, angles, flags, up, left, forward, modelList, ghlInfo->mModelindex, blendTime, currentTime); } - return qfalse; + G2WARNING(ret,"G2API_SetBoneAngles Failed"); + return ret; } qboolean G2API_SetBoneAnglesMatrixIndex(CGhoul2Info *ghlInfo, const int index, const mdxaBone_t &matrix, - const int flags, qhandle_t *modelList, int blendTime, int currentTime) + const int flags, qhandle_t *modelList, int blendTime, int AcurrentTime) { + qboolean ret=qfalse; + G2ERROR(ghlInfo,"NULL ghlInfo"); + int currentTime=G2API_GetTime(AcurrentTime); if (ghlInfo) { // ensure we flush the cache ghlInfo->mSkelFrameNum = 0; - return G2_Set_Bone_Angles_Matrix_Index(ghlInfo->mBlist, index, matrix, flags, modelList, ghlInfo->mModelindex, blendTime, currentTime); + G2ERROR(index>=0&&indexmBlist.size(),"Bad Bone Index"); + if (index>=0&&indexmBlist.size()) + { + ret=G2_Set_Bone_Angles_Matrix_Index(ghlInfo->mBlist, index, matrix, flags, modelList, ghlInfo->mModelindex, blendTime, currentTime); + } } - return qfalse; + G2WARNING(ret,"G2API_SetBoneAnglesMatrixIndex Failed"); + return ret; } qboolean G2API_SetBoneAnglesMatrix(CGhoul2Info *ghlInfo, const char *boneName, const mdxaBone_t &matrix, - const int flags, qhandle_t *modelList, int blendTime, int currentTime) + const int flags, qhandle_t *modelList, int blendTime, int AcurrentTime) { - if (ghlInfo) + qboolean ret=qfalse; + G2ERROR(ghlInfo,"NULL ghlInfo"); + int currentTime=G2API_GetTime(AcurrentTime); + G2ERROR(boneName,"NULL boneName"); + if (ghlInfo&&boneName) { // ensure we flush the cache ghlInfo->mSkelFrameNum = 0; - return G2_Set_Bone_Angles_Matrix(ghlInfo->mFileName, ghlInfo->mBlist, boneName, matrix, flags, modelList, ghlInfo->mModelindex, blendTime, currentTime); + ret=G2_Set_Bone_Angles_Matrix(ghlInfo->mFileName, ghlInfo->mBlist, boneName, matrix, flags, modelList, ghlInfo->mModelindex, blendTime, currentTime); } - return qfalse; + G2WARNING(ret,"G2API_SetBoneAnglesMatrix Failed"); + return ret; } qboolean G2API_StopBoneAnglesIndex(CGhoul2Info *ghlInfo, const int index) { + qboolean ret=qfalse; + G2ERROR(ghlInfo,"NULL ghlInfo"); if (ghlInfo) { // ensure we flush the cache ghlInfo->mSkelFrameNum = 0; - return G2_Stop_Bone_Angles_Index(ghlInfo->mBlist, index); + G2ERROR(index>=0&&indexmBlist.size(),"Bad Bone Index"); + if (index>=0&&indexmBlist.size()) + { + ret=G2_Stop_Bone_Angles_Index(ghlInfo->mBlist, index); + } } - return qfalse; + G2WARNING(ret,"G2API_StopBoneAnglesIndex Failed"); + return ret; } qboolean G2API_StopBoneAngles(CGhoul2Info *ghlInfo, const char *boneName) { - if (ghlInfo) + qboolean ret=qfalse; + G2ERROR(ghlInfo,"NULL ghlInfo"); + G2ERROR(boneName,"NULL boneName"); + if (ghlInfo&&boneName) { // ensure we flush the cache ghlInfo->mSkelFrameNum = 0; - return G2_Stop_Bone_Angles(ghlInfo->mFileName, ghlInfo->mBlist, boneName); + ret=G2_Stop_Bone_Angles(ghlInfo->mFileName, ghlInfo->mBlist, boneName); } - return qfalse; + G2WARNING(ret,"G2API_StopBoneAngles Failed"); + return ret; } qboolean G2API_RemoveBone(CGhoul2Info *ghlInfo, const char *boneName) { - if (ghlInfo) + qboolean ret=qfalse; + G2ERROR(ghlInfo,"NULL ghlInfo"); + G2ERROR(boneName,"NULL boneName"); + if (ghlInfo&&boneName) { // ensure we flush the cache ghlInfo->mSkelFrameNum = 0; - return G2_Remove_Bone(ghlInfo->mFileName, ghlInfo->mBlist, boneName); + ret=G2_Remove_Bone(ghlInfo->mFileName, ghlInfo->mBlist, boneName); } - return qfalse; + G2WARNING(ret,"G2API_RemoveBone Failed"); + return ret; } void G2API_AnimateG2Models(CGhoul2Info_v &ghoul2, float speedVar) { int model; + G2ERROR(ghoul2.IsValid(),"Invalid ghlInfo"); // Walk the list and find all models that are active for (model=0; model< ghoul2.size(); model++) @@ -625,54 +1026,70 @@ void G2API_AnimateG2Models(CGhoul2Info_v &ghoul2, float speedVar) qboolean G2API_RemoveBolt(CGhoul2Info *ghlInfo, const int index) { + qboolean ret=qfalse; + G2ERROR(ghlInfo,"NULL ghlInfo"); if (ghlInfo) { - return G2_Remove_Bolt( ghlInfo->mBltlist, index); + ret=G2_Remove_Bolt( ghlInfo->mBltlist, index); } - return qfalse; + G2WARNING(ret,"G2API_RemoveBolt Failed"); + return ret; } int G2API_AddBolt(CGhoul2Info *ghlInfo, const char *boneName) { - if (ghlInfo) + int ret=-1; + G2ERROR(ghlInfo,"NULL ghlInfo"); + G2ERROR(boneName,"NULL boneName"); + if (ghlInfo&&boneName) { - return G2_Add_Bolt(ghlInfo->mFileName, ghlInfo->mBltlist, ghlInfo->mSlist, boneName); + ret=G2_Add_Bolt(ghlInfo->mFileName, ghlInfo->mBltlist, ghlInfo->mSlist, boneName); } - return -1; + G2WARNING(ret>=0,"G2API_AddBolt Failed"); + return ret; } int G2API_AddBoltSurfNum(CGhoul2Info *ghlInfo, const int surfIndex) { + int ret=-1; + G2ERROR(ghlInfo,"NULL ghlInfo"); if (ghlInfo) { - return G2_Add_Bolt_Surf_Num(ghlInfo->mFileName, ghlInfo->mBltlist, ghlInfo->mSlist, surfIndex); + ret=G2_Add_Bolt_Surf_Num(ghlInfo->mFileName, ghlInfo->mBltlist, ghlInfo->mSlist, surfIndex); } - return -1; + G2WARNING(ret>=0,"G2API_AddBoltSurfNum Failed"); + return ret; } qboolean G2API_AttachG2Model(CGhoul2Info *ghlInfo, CGhoul2Info *ghlInfoTo, int toBoltIndex, int toModel) { + qboolean ret=qfalse; + G2ERROR(ghlInfo,"NULL ghlInfo"); + G2ERROR(ghlInfoTo,"NULL ghlInfo"); + G2ERROR(ghlInfo,"NULL ghlInfo"); + G2ERROR(toBoltIndex>=0&&toBoltIndexmBltlist.size(),"Invalid Bolt Index"); assert( toBoltIndex >= 0 ); - if ( toBoltIndex < 0 ) + if ( toBoltIndex >= 0 ) { - return qfalse; + // make sure we have a model to attach, a model to attach to, and a bolt on that model + if ((ghlInfo) && (ghlInfoTo) && ((ghlInfoTo->mBltlist[toBoltIndex].boneNumber != -1) || (ghlInfoTo->mBltlist[toBoltIndex].surfaceNumber != -1))) + { + // encode the bolt address into the model bolt link + toModel &= MODEL_AND; + toBoltIndex &= BOLT_AND; + ghlInfo->mModelBoltLink = (toModel << MODEL_SHIFT) | (toBoltIndex << BOLT_SHIFT); + ret=qtrue; + } } - // make sure we have a model to attach, a model to attach to, and a bolt on that model - if ((ghlInfo) && (ghlInfoTo) && ((ghlInfoTo->mBltlist[toBoltIndex].boneNumber != -1) || (ghlInfoTo->mBltlist[toBoltIndex].surfaceNumber != -1))) - { - // encode the bolt address into the model bolt link - toModel &= MODEL_AND; - toBoltIndex &= BOLT_AND; - ghlInfo->mModelBoltLink = (toModel << MODEL_SHIFT) | (toBoltIndex << BOLT_SHIFT); - return qtrue; - } - return qfalse; + G2WARNING(ret,"G2API_AttachG2Model Failed"); + return ret; } qboolean G2API_DetachG2Model(CGhoul2Info *ghlInfo) { + G2ERROR(ghlInfo,"NULL ghlInfo"); if (ghlInfo) { ghlInfo->mModelBoltLink = -1; @@ -683,6 +1100,9 @@ qboolean G2API_DetachG2Model(CGhoul2Info *ghlInfo) qboolean G2API_AttachEnt(int *boltInfo, CGhoul2Info *ghlInfoTo, int toBoltIndex, int entNum, int toModelNum) { + qboolean ret=qfalse; + G2ERROR(boltInfo,"NULL boltInfo"); + G2ERROR(ghlInfoTo,"NULL ghlInfo"); // make sure we have a model to attach, a model to attach to, and a bolt on that model if ((ghlInfoTo) && ((ghlInfoTo->mBltlist[toBoltIndex].boneNumber != -1) || (ghlInfoTo->mBltlist[toBoltIndex].surfaceNumber != -1))) { @@ -691,59 +1111,115 @@ qboolean G2API_AttachEnt(int *boltInfo, CGhoul2Info *ghlInfoTo, int toBoltIndex, toBoltIndex &= BOLT_AND; entNum &= ENTITY_AND; *boltInfo = (toBoltIndex << BOLT_SHIFT) | (toModelNum << MODEL_SHIFT) | (entNum << ENTITY_SHIFT); - return qtrue; + ret=qtrue; } - return qfalse; - + G2WARNING(ret,"G2API_AttachEnt Failed"); + return ret; } void G2API_DetachEnt(int *boltInfo) { - *boltInfo = 0; + G2ERROR(boltInfo,"NULL boltInfo"); + if (boltInfo) + { + *boltInfo = 0; + } } +#if _DEBUG +class GBM_Test +{ +public: + int Hits; + int Misses; + GBM_Test() + { + Hits=0; + Misses=0; + } + ~GBM_Test() + { + char mess[1000]; + sprintf(mess,"GBM stats: %d hits, %d misses\n",Hits,Misses); + OutputDebugString(mess); + } +}; + +static GBM_Test TheGBM_Test; +#endif + +bool G2_NeedsRecalc(CGhoul2Info *ghlInfo,int frameNum); qboolean G2API_GetBoltMatrix(CGhoul2Info_v &ghoul2, const int modelIndex, const int boltIndex, mdxaBone_t *matrix, const vec3_t angles, - const vec3_t position, const int frameNum, qhandle_t *modelList, const vec3_t scale ) + const vec3_t position, const int AframeNum, qhandle_t *modelList, const vec3_t scale ) { - CGhoul2Info *ghlInfo = &ghoul2[modelIndex]; + G2ERROR(ghoul2.IsValid(),"Invalid ghlInfo"); + G2ERROR(matrix,"NULL matrix"); + G2ERROR(modelIndex>=0&&modelIndexmBltlist.size()); - - if (boltIndex >= 0 && ghlInfo && (boltIndex < ghlInfo->mBltlist.size()) ) + int frameNum=G2API_GetTime(AframeNum); + const static mdxaBone_t identityMatrix = + { + 0.0f, -1.0f, 0.0f, 0.0f, + 1.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 1.0f, 0.0f + }; + if (modelIndex>=0&&modelIndex= 0 && (boltIndex < ghlInfo->mBltlist.size()),"Invalid Bolt Index"); - // scale the bolt position by the scale factor for this model since at this point its still in model space - if (scale[0]) - { - ghlInfo->mBltlist[boltIndex].position.matrix[0][3] *= scale[0]; - } - if (scale[1]) - { - ghlInfo->mBltlist[boltIndex].position.matrix[1][3] *= scale[1]; - } - if (scale[2]) - { - ghlInfo->mBltlist[boltIndex].position.matrix[2][3] *= scale[2]; - } - - // pre generate the world matrix G2_GenerateWorldMatrix(angles, position); + if (boltIndex >= 0 && ghlInfo && (boltIndex < ghlInfo->mBltlist.size()) ) + { + mdxaBone_t bolt; - // make the model space matrix we have for this bolt into a world matrix - Multiply_3x4Matrix(matrix, &worldMatrix, &ghlInfo->mBltlist[boltIndex].position ); - - return qtrue; - + if (G2_NeedsRecalc(ghlInfo,frameNum)) + { + G2_ConstructGhoulSkeleton(ghoul2,frameNum,true,scale); +#if _DEBUG + TheGBM_Test.Hits++; +#endif + } +#if _DEBUG + else + { + TheGBM_Test.Misses++; + } +#endif + vec3_t newScale; + + VectorClear(newScale); + + G2_GetBoltMatrixLow(*ghlInfo,boltIndex,scale,bolt); + // scale the bolt position by the scale factor for this model since at this point its still in model space + if (scale[0]) + { + bolt.matrix[0][3] *= scale[0]; + } + if (scale[1]) + { + bolt.matrix[1][3] *= scale[1]; + } + if (scale[2]) + { + bolt.matrix[2][3] *= scale[2]; + } + VectorNormalize((float*)&bolt.matrix[0]); + VectorNormalize((float*)&bolt.matrix[1]); + VectorNormalize((float*)&bolt.matrix[2]); + + Multiply_3x4Matrix(matrix, &worldMatrix, &bolt); + return qtrue; + } } - + Multiply_3x4Matrix(matrix, &worldMatrix, &identityMatrix); return qfalse; } void G2API_ListSurfaces(CGhoul2Info *ghlInfo) { + G2ERROR(ghlInfo,"NULL ghlInfo"); if (ghlInfo) { G2_List_Model_Surfaces(ghlInfo->mFileName); @@ -752,6 +1228,7 @@ void G2API_ListSurfaces(CGhoul2Info *ghlInfo) void G2API_ListBones(CGhoul2Info *ghlInfo, int frame) { + G2ERROR(ghlInfo,"NULL ghlInfo"); if (ghlInfo) { G2_List_Model_Bones(ghlInfo->mFileName, frame); @@ -767,6 +1244,7 @@ qboolean G2API_HaveWeGhoul2Models(CGhoul2Info_v &ghoul2) // run through the Ghoul2 models and set each of the mModel values to the correct one from the cgs.gameModel offset lsit void G2API_SetGhoul2ModelIndexes(CGhoul2Info_v &ghoul2, qhandle_t *modelList, qhandle_t *skinList) { + G2ERROR(ghoul2.IsValid(),"Invalid ghlInfo"); int i; for (i=0; imdxm->animName; + G2ERROR(mod_m&&mod_m->mdxm,"Bad Model"); + if (mod_m&&mod_m->mdxm) + { + return mod_m->mdxm->animName; + } + return ""; } /************************************************************************************************ @@ -806,11 +1289,14 @@ char *G2API_GetAnimFileNameIndex(qhandle_t modelIndex) ************************************************************************************************/ qboolean G2API_GetAnimFileName(CGhoul2Info *ghlInfo, char **filename) { + qboolean ret=qfalse; + G2ERROR(ghlInfo,"NULL ghlInfo"); if (ghlInfo) { - return G2_GetAnimFileName(ghlInfo->mFileName, filename); + ret=G2_GetAnimFileName(ghlInfo->mFileName, filename); } - return qfalse; + G2WARNING(ret,"G2API_GetAnimFileName Failed"); + return ret; } /* @@ -830,17 +1316,17 @@ static int QDECL QsortDistance( const void *a, const void *b ) { void G2API_CollisionDetect(CCollisionRecord *collRecMap, CGhoul2Info_v &ghoul2, const vec3_t angles, const vec3_t position, - int frameNumber, int entNum, vec3_t rayStart, vec3_t rayEnd, vec3_t scale, CMiniHeap *, + int AframeNumber, int entNum, vec3_t rayStart, vec3_t rayEnd, vec3_t scale, CMiniHeap *, EG2_Collision eG2TraceType, int useLod, float fRadius) { + G2ERROR(ghoul2.IsValid(),"Invalid ghlInfo"); + G2ERROR(collRecMap,"NULL Collision Rec"); + int frameNumber=G2API_GetTime(AframeNumber); vec3_t transRayStart, transRayEnd; - //let's keep our timer use consistent - frameNumber = tr.refdef.time; - // make sure we have transformed the whole skeletons for each model - G2_ConstructGhoulSkeleton(ghoul2, frameNumber, NULL, true, position, scale, false); + G2_ConstructGhoulSkeleton(ghoul2, frameNumber,true, scale); // pre generate the world matrix - used to transform the incoming ray G2_GenerateWorldMatrix(angles, position); @@ -868,6 +1354,7 @@ void G2API_CollisionDetect(CCollisionRecord *collRecMap, CGhoul2Info_v &ghoul2, qboolean G2API_SetGhoul2ModelFlags(CGhoul2Info *ghlInfo, const int flags) { + G2ERROR(ghlInfo,"NULL ghlInfo"); if (ghlInfo) { ghlInfo->mFlags &= GHOUL2_NEWORIGIN; @@ -879,6 +1366,7 @@ qboolean G2API_SetGhoul2ModelFlags(CGhoul2Info *ghlInfo, const int flags) int G2API_GetGhoul2ModelFlags(CGhoul2Info *ghlInfo) { + G2ERROR(ghlInfo,"NULL ghlInfo"); if (ghlInfo) { return (ghlInfo->mFlags & ~GHOUL2_NEWORIGIN); @@ -933,40 +1421,19 @@ void G2API_GiveMeVectorFromMatrix(mdxaBone_t &boltMatrix, Eorientations flags, v // NOTE if modelIndex = -1 then copy all the models void G2API_CopyGhoul2Instance(CGhoul2Info_v &ghoul2From, CGhoul2Info_v &ghoul2To, int modelIndex) { - int i, model; - int from = 0; - int to = ghoul2From.size(); - - // determing if we are only copying one model or not - if (modelIndex != -1) + assert(modelIndex==-1); // copy individual bolted parts is not used in jk2 and I didn't want to deal with it + // if ya want it, we will add it back correctly + + G2ERROR(ghoul2From.IsValid(),"Invalid ghlInfo"); + if (ghoul2From.IsValid()) { - from = modelIndex; - to = modelIndex + 1; + ghoul2To.DeepCopy(ghoul2From); } - - // now copy the models - for (i=from; imFileName)); mdxmSurface_t *surf = 0; @@ -979,32 +1446,51 @@ char *G2API_GetSurfaceName(CGhoul2Info *ghlInfo, int surfNumber) surfInfo = (mdxmSurfHierarchy_t *)((byte *)surfIndexes + surfIndexes->offsets[surf->thisSurfaceIndex]); return surfInfo->name; } - + G2WARNING(0,"Surface Not Found"); return noSurface; } int G2API_GetSurfaceIndex(CGhoul2Info *ghlInfo, const char *surfaceName) { + int ret=-1; + G2ERROR(ghlInfo,"NULL ghlInfo"); + G2ERROR(surfaceName,"NULL surfaceName"); if (ghlInfo) { - return G2_GetSurfaceIndex(ghlInfo->mFileName, surfaceName); + ret=G2_GetSurfaceIndex(ghlInfo->mFileName, surfaceName); } - return -1; + G2WARNING(ret>=0,"G2API_GetSurfaceIndex Failed"); + return ret; } char *G2API_GetGLAName(CGhoul2Info *ghlInfo) { - model_t *mod = R_GetModelByHandle(RE_RegisterModel(ghlInfo->mFileName)); - return mod->mdxm->animName; + G2ERROR(ghlInfo,"NULL ghlInfo"); + if (ghlInfo) + { + model_t *mod = R_GetModelByHandle(RE_RegisterModel(ghlInfo->mFileName)); + G2ERROR(mod&&mod->mdxm,"Bad Model"); + if (mod&&mod->mdxm) + { + return mod->mdxm->animName; + } + } + return 0; } qboolean G2API_SetNewOrigin(CGhoul2Info *ghlInfo, const int boltIndex) { + G2ERROR(ghlInfo,"NULL ghlInfo"); if (ghlInfo) { - ghlInfo->mNewOrigin = boltIndex; - ghlInfo->mFlags |= GHOUL2_NEWORIGIN; + G2ERROR(boltIndex>=0&&boltIndexmBltlist.size(),"NULL ghlInfo"); + + if (boltIndex>=0&&boltIndexmBltlist.size()) + { + ghlInfo->mNewOrigin = boltIndex; + ghlInfo->mFlags |= GHOUL2_NEWORIGIN; + } return qtrue; } return qfalse; @@ -1012,21 +1498,27 @@ qboolean G2API_SetNewOrigin(CGhoul2Info *ghlInfo, const int boltIndex) int G2API_GetBoneIndex(CGhoul2Info *ghlInfo, const char *boneName, qboolean bAddIfNotFound) { - if (ghlInfo) + int ret=-1; + G2ERROR(ghlInfo,"NULL ghlInfo"); + G2ERROR(boneName,"NULL boneName"); + if (ghlInfo&&boneName) { - return G2_Get_Bone_Index(ghlInfo, boneName, bAddIfNotFound); + ret=G2_Get_Bone_Index(ghlInfo, boneName, bAddIfNotFound); } - return -1; + G2WARNING(ret>=0,"G2API_GetBoneIndex Failed"); + return ret; } qboolean G2API_SaveGhoul2Models(CGhoul2Info_v &ghoul2, char **buffer, int *size) { + G2ERROR(ghoul2.IsValid(),"Invalid ghlInfo"); return G2_SaveGhoul2Models(ghoul2, buffer, size); } void G2API_LoadGhoul2Models(CGhoul2Info_v &ghoul2, char *buffer) { G2_LoadGhoul2Model(ghoul2, buffer); + G2ERROR(ghoul2.IsValid(),"Invalid ghlInfo after load"); } void G2API_FreeSaveBuffer(char *buffer) diff --git a/code/ghoul2/g2_bolts.cpp b/code/ghoul2/g2_bolts.cpp index 4673518..02993a5 100644 --- a/code/ghoul2/g2_bolts.cpp +++ b/code/ghoul2/g2_bolts.cpp @@ -118,6 +118,7 @@ int G2_Add_Bolt_Surf_Num(const char *fileName, boltInfo_v &bltlist, surfaceInfo_ } +void G2_Bolt_Not_Found(const char *boneName,const char *modName); int G2_Add_Bolt(const char *fileName, boltInfo_v &bltlist, surfaceInfo_v &slist, const char *boneName) { model_t *mod_m = R_GetModelByHandle(RE_RegisterModel(fileName)); @@ -191,6 +192,9 @@ int G2_Add_Bolt(const char *fileName, boltInfo_v &bltlist, surfaceInfo_v &slist, { // didn't find it? Error //assert(0&&x == mod_a->mdxa->numBones); +#if _DEBUG + G2_Bolt_Not_Found(boneName,fileName); +#endif return -1; } @@ -283,6 +287,7 @@ void G2_Init_Bolt_List(boltInfo_v &bltlist) // remove any bolts that reference original surfaces, generated surfaces, or bones that aren't active anymore void G2_RemoveRedundantBolts(boltInfo_v &bltlist, surfaceInfo_v &slist, int *activeSurfaces, int *activeBones) { + G2_FindOverrideSurface(-1, slist); //reset the quick surface override lookup; // walk the bolt list for (int i=0; iname); +#endif // didn't find it return -1; } @@ -577,10 +581,10 @@ qboolean G2_Set_Bone_Anim_Index(boneInfo_v &blist, const int index, const int st //assert(startFrame < 1000);//do we really need this??? //assert((animSpeed > 0.01) && (animSpeed < 20.0)); - if ((index >= blist.size()) || (blist[index].boneNumber == -1)) + if (index<0||index >= blist.size()||blist[index].boneNumber<0) { // we are attempting to set a bone override that doesn't exist - assert(0); +// assert(0); return qfalse; } @@ -591,104 +595,105 @@ qboolean G2_Set_Bone_Anim_Index(boneInfo_v &blist, const int index, const int st } - // since we already existed, we can check to see if we want to start some blending - if (flags & (BONE_ANIM_BLEND|BONE_ANIM_BLEND_TO_PARENT)) + // since we already existed, we can check to see if we want to start some blending + if (flags & (BONE_ANIM_BLEND|BONE_ANIM_BLEND_TO_PARENT)) + { + float currentFrame, animSpeed; + int startFrame, endFrame, flags; + // figure out where we are now + if (G2_Get_Bone_Anim_Index(blist, index, currentTime, ¤tFrame, &startFrame, &endFrame, &flags, &animSpeed, NULL, 0)) { - float currentFrame, animSpeed; - int startFrame, endFrame, flags; - // figure out where we are now - if (G2_Get_Bone_Anim_Index(blist, index, currentTime, ¤tFrame, &startFrame, &endFrame, &flags, &animSpeed, NULL, 0)) + if (blist[index].blendStart == currentTime) //we're replacing a blend in progress which hasn't started { - if (blist[index].blendStart == currentTime) //we're replacing a blend in progress which hasn't started - { - // set the amount of time it's going to take to blend this anim with the last frame of the last one - blist[index].blendTime = blendTime; - } - else - { - blist[index].blendFrame = currentFrame; - blist[index].blendLerpFrame = currentFrame+1; - - // cope with if the lerp frame is actually off the end of the anim - if (blist[index].blendFrame >= blist[index].endFrame ) - { - // we only want to lerp with the first frame of the anim if we are looping - if (blist[index].flags & BONE_ANIM_OVERRIDE_LOOP) - { - blist[index].blendFrame = blist[index].startFrame; - } - // if we intend to end this anim or freeze after this, then just keep on the last frame - else - { - blist[index].blendFrame = blist[index].endFrame -1; - } - } - - // cope with if the lerp frame is actually off the end of the anim - if (blist[index].blendLerpFrame >= blist[index].endFrame ) - { - // we only want to lerp with the first frame of the anim if we are looping - if (blist[index].flags & BONE_ANIM_OVERRIDE_LOOP) - { - blist[index].blendLerpFrame = blist[index].startFrame; - } - // if we intend to end this anim or freeze after this, then just keep on the last frame - else - { - blist[index].blendLerpFrame = blist[index].endFrame - 1; - } - } - // set the amount of time it's going to take to blend this anim with the last frame of the last one - blist[index].blendTime = blendTime; - blist[index].blendStart = currentTime; - } + // set the amount of time it's going to take to blend this anim with the last frame of the last one + blist[index].blendTime = blendTime; } - // hmm, we weren't animating on this bone. In which case disable the blend else { - blist[index].blendFrame = blist[index].blendLerpFrame = 0; - blist[index].blendTime = 0; - // we aren't blending, so remove the option to do so - modFlags &= ~(BONE_ANIM_BLEND|BONE_ANIM_BLEND_TO_PARENT); + blist[index].blendFrame = currentFrame; + blist[index].blendLerpFrame = currentFrame+1; + + // cope with if the lerp frame is actually off the end of the anim + if (blist[index].blendFrame >= blist[index].endFrame ) + { + // we only want to lerp with the first frame of the anim if we are looping + if (blist[index].flags & BONE_ANIM_OVERRIDE_LOOP) + { + blist[index].blendFrame = blist[index].startFrame; + } + // if we intend to end this anim or freeze after this, then just keep on the last frame + else + { + blist[index].blendFrame = blist[index].endFrame -1; + } + } + + // cope with if the lerp frame is actually off the end of the anim + if (blist[index].blendLerpFrame >= blist[index].endFrame ) + { + // we only want to lerp with the first frame of the anim if we are looping + if (blist[index].flags & BONE_ANIM_OVERRIDE_LOOP) + { + blist[index].blendLerpFrame = blist[index].startFrame; + } + // if we intend to end this anim or freeze after this, then just keep on the last frame + else + { + blist[index].blendLerpFrame = blist[index].endFrame - 1; + } + } + // set the amount of time it's going to take to blend this anim with the last frame of the last one + blist[index].blendTime = blendTime; + blist[index].blendStart = currentTime; } } - else - // if we are doing it from parent, then we only care about blendtime and blend start, since the rest gets constructed in the renderer - if (flags & BONE_ANIM_BLEND_FROM_PARENT) - { - // if we hit this, someone put a BLEND_FROM_PARENT on a root bone - that's a no no - assert(blist[index].boneNumber); - // set the amount of time it's going to take to blend this anim with the last frame of the last one - blist[index].blendTime = blendTime; - blist[index].blendStart = currentTime; - } + // hmm, we weren't animating on this bone. In which case disable the blend else { blist[index].blendFrame = blist[index].blendLerpFrame = 0; - blist[index].blendTime = blist[index].blendStart = 0; - // we aren't blending, so remove the option to do so - modFlags &= ~(BONE_ANIM_BLEND|BONE_ANIM_BLEND_TO_PARENT); + blist[index].blendTime = 0; + // we aren't blending, so remove the option to do so + modFlags &= ~(BONE_ANIM_BLEND|BONE_ANIM_BLEND_TO_PARENT); + return qfalse; } + } + else + // if we are doing it from parent, then we only care about blendtime and blend start, since the rest gets constructed in the renderer + if (flags & BONE_ANIM_BLEND_FROM_PARENT) + { + // if we hit this, someone put a BLEND_FROM_PARENT on a root bone - that's a no no + assert(blist[index].boneNumber); + // set the amount of time it's going to take to blend this anim with the last frame of the last one + blist[index].blendTime = blendTime; + blist[index].blendStart = currentTime; + } + else + { + blist[index].blendFrame = blist[index].blendLerpFrame = 0; + blist[index].blendTime = blist[index].blendStart = 0; + // we aren't blending, so remove the option to do so + modFlags &= ~(BONE_ANIM_BLEND|BONE_ANIM_BLEND_TO_PARENT); + } - // yes, so set the anim data and flags correctly - blist[index].endFrame = endFrame; - blist[index].startFrame = startFrame; - blist[index].animSpeed = animSpeed; - blist[index].pauseTime = 0; - // start up the animation:) - if (setFrame != -1) - { - blist[index].lastTime = blist[index].startTime = (currentTime - (((setFrame - (float)startFrame) * 50.0)/ animSpeed)); - } - else - { - blist[index].lastTime = blist[index].startTime = currentTime; - } - blist[index].flags &= ~(BONE_ANIM_TOTAL); - blist[index].flags |= modFlags; + // yes, so set the anim data and flags correctly + blist[index].endFrame = endFrame; + blist[index].startFrame = startFrame; + blist[index].animSpeed = animSpeed; + blist[index].pauseTime = 0; + // start up the animation:) + if (setFrame != -1) + { + blist[index].lastTime = blist[index].startTime = (currentTime - (((setFrame - (float)startFrame) * 50.0)/ animSpeed)); + } + else + { + blist[index].lastTime = blist[index].startTime = currentTime; + } + blist[index].flags &= ~(BONE_ANIM_TOTAL); + blist[index].flags |= modFlags; // assert(blist[index].startTime <= currentTime); - return qtrue; + return qtrue; } @@ -789,93 +794,30 @@ qboolean G2_Get_Bone_Anim_Range(const char *fileName, boneInfo_v &blist, const c // given a model, bonelist and bonename, return the current frame, startframe and endframe of the current animation // NOTE if we aren't running an animation, then qfalse is returned qboolean G2_Get_Bone_Anim_Index( boneInfo_v &blist, const int index, const int currentTime, - float *currentFrame, int *startFrame, int *endFrame, int *flags, float *retAnimSpeed, qhandle_t *modelList, int modelIndex) + float *retcurrentFrame, int *startFrame, int *endFrame, int *flags, float *retAnimSpeed, qhandle_t *modelList, int modelIndex) { // did we find it? if ((index != -1) && !((index >= blist.size()) || (blist[index].boneNumber == -1))) { + // are we an animating bone? if (blist[index].flags & (BONE_ANIM_OVERRIDE_LOOP | BONE_ANIM_OVERRIDE)) { - // yes - add in animation speed to current frame - float animSpeed = blist[index].animSpeed; - float time = (currentTime - blist[index].startTime) / 50.0f; - float mendFrame = (float)blist[index].endFrame ; - - // are we a paused anim? - if (blist[index].pauseTime) - { - time = (blist[index].pauseTime - blist[index].startTime) / 50.0f; - } - - float newFrame_g = blist[index].startFrame + (time * animSpeed); - *currentFrame = newFrame_g; - - int animSize = blist[index].endFrame - blist[index].startFrame; - // we are supposed to be animating right? - if (animSize) - { - // did we run off the end? - if (((animSpeed > 0.0f) && (newFrame_g > mendFrame)) || - ((animSpeed < 0.0f) && (newFrame_g < mendFrame))) - { - // yep - decide what to do - if (blist[index].flags & BONE_ANIM_OVERRIDE_LOOP) - { - - // get our new animation frame back within the bounds of the animation set - if (animSpeed < 0.0f) - { - while (newFrame_g <= mendFrame) - { - newFrame_g -= animSize; - } - } - else - { - while (newFrame_g >= mendFrame) - { - newFrame_g -= animSize; - } - } - - *currentFrame = newFrame_g; - } - else - { - // nope, we ran off the end of the current anim - if (blist[index].flags & BONE_ANIM_OVERRIDE_FREEZE) - { - if (animSpeed > 0.0f) - { - *currentFrame = blist[index].endFrame -1; - } - else - { - *currentFrame = blist[index].endFrame +1; - } - } - else - { - *currentFrame = -1; - } - } - } - } - else - { - *currentFrame = blist[index].startFrame; - } + int currentFrame,newFrame,numFrames; + numFrames=30000; // I don't have this number, but it will eventually assert if the start and end frame are invalid + float lerp; + G2_TimingModel(blist[index],currentTime,numFrames,currentFrame,newFrame,lerp); + *retcurrentFrame =float(currentFrame)+lerp; *startFrame = blist[index].startFrame; *endFrame = blist[index].endFrame; *flags = blist[index].flags; - *retAnimSpeed = animSpeed; + *retAnimSpeed = blist[index].animSpeed; return qtrue; } } - *startFrame = *endFrame = *currentFrame = -1; + *startFrame = *endFrame = *retcurrentFrame = -1; *flags = 0;/*-1;*/ //cheesees fudging cripes i hate -1 return qfalse; } @@ -906,7 +848,7 @@ qboolean G2_Get_Bone_Anim(const char *fileName, boneInfo_v &blist, const char *b // given a model, bonelist and bonename, lets pause an anim if it's playing. qboolean G2_Pause_Bone_Anim_Index( boneInfo_v &blist, const int boneIndex, const int currentTime) { - if (boneIndex != -1) + if (boneIndex>=0&&boneIndexmMap.lower_bound(adjustedLastTime); - CWInstBoneMap::TBoneMapIter itStop = blist[i].boneMap->mMap.upper_bound(adjustedCurrentTime); - vector callbacksToFire; - - boneInfo_t *bone = &blist[i]; - - // walk through the map list of call backs we should hit this frame - while (itCur != itStop) - { - - int calltime = (*itCur).first; - - // push it into the list ready to fire off later. - callbacksToFire.push_back((*itCur).second); - - // did we hit an exact match? - if ((*itCur).first == adjustedCurrentTime) - { - // adjust the next time by the anim speed, so if we are running fast we won't lose this jumping of one millisecond - int adjuster = 1; - if (blist[i].animSpeed > 1) - { - adjuster = blist[i].animSpeed + 1; - } - callbackCurrentTime += adjuster; - } - // select next call back to check against - itCur++; - - // have we run off the end of the map? - if (itCur == blist[i].boneMap->mMap.end()) - { - // does the map loop back to the beginning? - if (itCur != itStop) - { - itCur = blist[i].boneMap->mMap.begin(); - } - } - } - - // fire off all the call backs we have selected for this bone. - for (int cllbks = 0; cllbks < callbacksToFire.size(); cllbks++) - { - TheGhoul2Wraith()->FireCallback(ghoul2, index, callbacksToFire[cllbks], callbackCurrentTime); - } - callbacksToFire.clear(); - - // assuming the bone is still here, set the last time to current time - if (blist[i].boneNumber != -1) - { - blist[i].lastTime = callbackCurrentTime; - } - } - } - } - } -#endif - // look through entire list for(i=0; i 0.0f) && (newFrame_g > endFrame )) || - ((animSpeed < 0.0f) && (newFrame_g < endFrame ))) + if (((animSpeed > 0.0f) && (newFrame_g > endFrame - 1)) || + ((animSpeed < 0.0f) && (newFrame_g < endFrame + 1))) { // yep - decide what to do if (blist[i].flags & BONE_ANIM_OVERRIDE_LOOP) @@ -1161,27 +1030,34 @@ void G2_Animate_Bone_List(CGhoul2Info_v &ghoul2, const int currentTime, const in // get our new animation frame back within the bounds of the animation set if (animSpeed < 0.0f) { - while (newFrame_g <= endFrame) + if (newFrame_g <= endFrame) { - newFrame_g -= animSize; + newFrame_g=endFrame+fmod(newFrame_g-endFrame,animSize)-animSize; } + // figure out new start time + float frameTime = newFrame_g - blist[i].startFrame ; + blist[i].startTime = currentTime - (int)((frameTime / animSpeed) * 50.0f); + assert(blist[i].startTime <= currentTime); + blist[i].lastTime = blist[i].startTime; } else { - while (newFrame_g >= endFrame) + if (newFrame_g >= endFrame) { - newFrame_g -= animSize; + newFrame_g=endFrame+fmod(newFrame_g-endFrame,animSize)-animSize; } + // figure out new start time + float frameTime = newFrame_g - blist[i].startFrame ; + blist[i].startTime = currentTime - (int)((frameTime / animSpeed) * 50.0f); + assert(blist[i].startTime <= currentTime); + blist[i].lastTime = blist[i].startTime; } - // figure out new start time - float frameTime = newFrame_g - blist[i].startFrame ; - blist[i].startTime = currentTime - (int)((frameTime / animSpeed) * 50.0f); - assert(blist[i].startTime <= currentTime); - blist[i].lastTime = blist[i].startTime; } else { if ((blist[i].flags & (BONE_ANIM_OVERRIDE_FREEZE)) != (BONE_ANIM_OVERRIDE_FREEZE)) +// if (((blist[i].flags & (BONE_ANIM_OVERRIDE_DEFAULT)) == (BONE_ANIM_OVERRIDE_DEFAULT))|| +// ((blist[i].flags & (BONE_ANIM_OVERRIDE_FREEZE)) == (BONE_ANIM_OVERRIDE_FREEZE))) { // if we are supposed to reset the default anim, then do so if (blist[i].flags & (BONE_ANIM_OVERRIDE_DEFAULT)) diff --git a/code/ghoul2/g2_misc.cpp b/code/ghoul2/g2_misc.cpp index d2a2d43..f729e3e 100644 --- a/code/ghoul2/g2_misc.cpp +++ b/code/ghoul2/g2_misc.cpp @@ -27,6 +27,8 @@ extern mdxaBone_t worldMatrix; extern mdxaBone_t worldMatrixInv; +const mdxaBone_t &EvalBoneCache(int index,CBoneCache *boneCache); + #pragma warning(disable : 4512) //assignment op could not be genereated class CTraceSurface { @@ -203,7 +205,8 @@ int G2_DecideTraceLod(CGhoul2Info &ghoul2, int useLod, const model_t *mod) return returnLod; } -void R_TransformEachSurface( const mdxmSurface_t *surface, vec3_t scale, CMiniHeap *G2VertSpace, int *TransformedVertsArray, mdxaBone_v &bonePtr) { +void R_TransformEachSurface( const mdxmSurface_t *surface, vec3_t scale, CMiniHeap *G2VertSpace, int *TransformedVertsArray,CBoneCache *boneCache) +{ int j, k; mdxmVertex_t *v; float *TransformedVerts; @@ -211,6 +214,7 @@ void R_TransformEachSurface( const mdxmSurface_t *surface, vec3_t scale, CMiniHe // // deform the vertexes by the lerped bones // + int *piBoneReferences = (int*) ((byte*)surface + surface->ofsBoneReferences); // alloc some space for the transformed verts to get put in TransformedVerts = (float *)G2VertSpace->MiniHeapAlloc(surface->numVerts * 5 * 4); @@ -221,7 +225,6 @@ void R_TransformEachSurface( const mdxmSurface_t *surface, vec3_t scale, CMiniHe } // whip through and actually transform each vertex - const int *piBoneRefs = (int*) ((byte*)surface + surface->ofsBoneReferences); const int numVerts = surface->numVerts; v = (mdxmVertex_t *) ((byte *)surface + surface->ofsVerts); // optimisation issue @@ -237,15 +240,15 @@ void R_TransformEachSurface( const mdxmSurface_t *surface, vec3_t scale, CMiniHe w = v->weights; for ( k = 0 ; k < v->numWeights ; k++, w++ ) { - //bone = bonePtr + piBoneRefs[w->boneIndex]; + const mdxaBone_t &bone=EvalBoneCache(piBoneReferences[w->boneIndex],boneCache); - tempVert[0] += w->boneWeight * ( DotProduct( bonePtr[piBoneRefs[w->boneIndex]].matrix[0], v->vertCoords ) + bonePtr[piBoneRefs[w->boneIndex]].matrix[0][3] ); - tempVert[1] += w->boneWeight * ( DotProduct( bonePtr[piBoneRefs[w->boneIndex]].matrix[1], v->vertCoords ) + bonePtr[piBoneRefs[w->boneIndex]].matrix[1][3] ); - tempVert[2] += w->boneWeight * ( DotProduct( bonePtr[piBoneRefs[w->boneIndex]].matrix[2], v->vertCoords ) + bonePtr[piBoneRefs[w->boneIndex]].matrix[2][3] ); + tempVert[0] += w->boneWeight * ( DotProduct( bone.matrix[0], v->vertCoords ) + bone.matrix[0][3] ); + tempVert[1] += w->boneWeight * ( DotProduct( bone.matrix[1], v->vertCoords ) + bone.matrix[1][3] ); + tempVert[2] += w->boneWeight * ( DotProduct( bone.matrix[2], v->vertCoords ) + bone.matrix[2][3] ); - tempNormal[0] += w->boneWeight * DotProduct( bonePtr[piBoneRefs[w->boneIndex]].matrix[0], v->normal ); - tempNormal[1] += w->boneWeight * DotProduct( bonePtr[piBoneRefs[w->boneIndex]].matrix[1], v->normal ); - tempNormal[2] += w->boneWeight * DotProduct( bonePtr[piBoneRefs[w->boneIndex]].matrix[2], v->normal ); + tempNormal[0] += w->boneWeight * DotProduct( bone.matrix[0], v->normal ); + tempNormal[1] += w->boneWeight * DotProduct( bone.matrix[1], v->normal ); + tempNormal[2] += w->boneWeight * DotProduct( bone.matrix[2], v->normal ); } int pos = j * 5; @@ -273,15 +276,15 @@ void R_TransformEachSurface( const mdxmSurface_t *surface, vec3_t scale, CMiniHe w = v->weights; for ( k = 0 ; k < v->numWeights ; k++, w++ ) { - //bone = bonePtr + piBoneRefs[w->boneIndex]; + const mdxaBone_t &bone=EvalBoneCache(piBoneReferences[w->boneIndex],boneCache); - tempVert[0] += w->boneWeight * ( DotProduct( bonePtr[piBoneRefs[w->boneIndex]].matrix[0], v->vertCoords ) + bonePtr[piBoneRefs[w->boneIndex]].matrix[0][3] ); - tempVert[1] += w->boneWeight * ( DotProduct( bonePtr[piBoneRefs[w->boneIndex]].matrix[1], v->vertCoords ) + bonePtr[piBoneRefs[w->boneIndex]].matrix[1][3] ); - tempVert[2] += w->boneWeight * ( DotProduct( bonePtr[piBoneRefs[w->boneIndex]].matrix[2], v->vertCoords ) + bonePtr[piBoneRefs[w->boneIndex]].matrix[2][3] ); + tempVert[0] += w->boneWeight * ( DotProduct( bone.matrix[0], v->vertCoords ) + bone.matrix[0][3] ); + tempVert[1] += w->boneWeight * ( DotProduct( bone.matrix[1], v->vertCoords ) + bone.matrix[1][3] ); + tempVert[2] += w->boneWeight * ( DotProduct( bone.matrix[2], v->vertCoords ) + bone.matrix[2][3] ); - tempNormal[0] += w->boneWeight * DotProduct( bonePtr[piBoneRefs[w->boneIndex]].matrix[0], v->normal ); - tempNormal[1] += w->boneWeight * DotProduct( bonePtr[piBoneRefs[w->boneIndex]].matrix[1], v->normal ); - tempNormal[2] += w->boneWeight * DotProduct( bonePtr[piBoneRefs[w->boneIndex]].matrix[2], v->normal ); + tempNormal[0] += w->boneWeight * DotProduct( bone.matrix[0], v->normal ); + tempNormal[1] += w->boneWeight * DotProduct( bone.matrix[1], v->normal ); + tempNormal[2] += w->boneWeight * DotProduct( bone.matrix[2], v->normal ); } // copy tranformed verts into temp space @@ -298,7 +301,7 @@ void R_TransformEachSurface( const mdxmSurface_t *surface, vec3_t scale, CMiniHe } void G2_TransformSurfaces(int surfaceNum, surfaceInfo_v &rootSList, - mdxaBone_v &bonePtr, const model_t *currentModel, int lod, vec3_t scale, CMiniHeap *G2VertSpace, int *TransformedVertArray, bool secondTimeAround) + CBoneCache *boneCache, const model_t *currentModel, int lod, vec3_t scale, CMiniHeap *G2VertSpace, int *TransformedVertArray, bool secondTimeAround) { int i; // back track and get the surfinfo struct for this surface @@ -320,7 +323,7 @@ void G2_TransformSurfaces(int surfaceNum, surfaceInfo_v &rootSList, if (!offFlags) { - R_TransformEachSurface(surface, scale, G2VertSpace, TransformedVertArray, bonePtr); + R_TransformEachSurface(surface, scale, G2VertSpace, TransformedVertArray, boneCache); } // if we are turning off all descendants, then stop this recursion now @@ -332,7 +335,7 @@ void G2_TransformSurfaces(int surfaceNum, surfaceInfo_v &rootSList, // now recursively call for the children for (i=0; i< surfInfo->numChildren; i++) { - G2_TransformSurfaces(surfInfo->childIndexes[i], rootSList, bonePtr, currentModel, lod, scale, G2VertSpace, TransformedVertArray, secondTimeAround); + G2_TransformSurfaces(surfInfo->childIndexes[i], rootSList, boneCache, currentModel, lod, scale, G2VertSpace, TransformedVertArray, secondTimeAround); } } @@ -388,8 +391,9 @@ void G2_TransformModel(CGhoul2Info_v &ghoul2, const int frameNum, vec3_t scale, // did we get enough space? assert(ghoul2[i].mTransformedVertsArray); + G2_FindOverrideSurface(-1,ghoul2[i].mSlist); //reset the quick surface override lookup; // recursively call the model surface transform - G2_TransformSurfaces(ghoul2[i].mSurfaceRoot, ghoul2[i].mSlist, ghoul2[i].mTempBoneList, currentModel, lod, correctScale, G2VertSpace, ghoul2[i].mTransformedVertsArray, false); + G2_TransformSurfaces(ghoul2[i].mSurfaceRoot, ghoul2[i].mSlist, ghoul2[i].mBoneCache, currentModel, lod, correctScale, G2VertSpace, ghoul2[i].mTransformedVertsArray, false); } } @@ -964,6 +968,9 @@ void G2_TraceModels(CGhoul2Info_v &ghoul2, vec3_t rayStart, vec3_t rayEnd, CColl lod = G2_DecideTraceLod(ghoul2[i],useLod, currentModel); + //reset the quick surface override lookup + G2_FindOverrideSurface(-1, ghoul2[i].mSlist); + CTraceSurface TS(ghoul2[i].mSurfaceRoot, ghoul2[i].mSlist, currentModel, lod, rayStart, rayEnd, collRecMap, entNum, i, skin, cust_shader, ghoul2[i].mTransformedVertsArray, eG2TraceType, fRadius); // start the surface recursion loop G2_TraceSurfaces(TS); @@ -1062,6 +1069,7 @@ void *G2_FindSurface(const void *mod_t, int index, int lod) int i; //walk the lods + assert(lod>=0&&lodmdxm->numLODs); for (i=0; i=0&&indexmdxm->numSurfaces); current += indexes->offsets[index]; return (void *)current; } #define SURFACE_SAVE_BLOCK_SIZE sizeof(surfaceInfo_t) -#define BOLT_SAVE_BLOCK_SIZE (sizeof(boltInfo_t) - sizeof(mdxaBone_t)) +#define BOLT_SAVE_BLOCK_SIZE sizeof(boltInfo_t) #define BONE_SAVE_BLOCK_SIZE sizeof(boneInfo_t) qboolean G2_SaveGhoul2Models(CGhoul2Info_v &ghoul2, char **buffer, int *size) @@ -1263,5 +1272,6 @@ void G2_LoadGhoul2Model(CGhoul2Info_v &ghoul2, char *buffer) memcpy(&ghoul2[i].mBltlist[x], buffer, BOLT_SAVE_BLOCK_SIZE); buffer += BOLT_SAVE_BLOCK_SIZE; } + ghoul2[i].mSkelFrameNum = 0; } } \ No newline at end of file diff --git a/code/ghoul2/g2_surfaces.cpp b/code/ghoul2/g2_surfaces.cpp index 8197e7b..d114674 100644 --- a/code/ghoul2/g2_surfaces.cpp +++ b/code/ghoul2/g2_surfaces.cpp @@ -18,52 +18,104 @@ #pragma warning(disable : 4512) //assignment op could not be genereated -class CConstructBoneList +class CQuickOverride { + int mOverride[512]; + int mAt[512]; + int mCurrentTouch; public: - int surfaceNum; - int *boneUsedList; - const surfaceInfo_v &rootSList; - const model_t *currentModel; - const boneInfo_v &boneList; - - CConstructBoneList( - int initsurfaceNum, - int *initboneUsedList, - const surfaceInfo_v &initrootSList, - const model_t *initcurrentModel, - const boneInfo_v &initboneList): - - surfaceNum(initsurfaceNum), - boneUsedList(initboneUsedList), - rootSList(initrootSList), - currentModel(initcurrentModel), - boneList(initboneList) { } -}; - -extern void G2_ConstructUsedBoneList(CConstructBoneList &CBL); - - -//===================================================================================================================== -// Surface List handling routines - so entities can determine what surfaces attached to a model are operational or not. - -// find a particular surface in the surface override list -const surfaceInfo_t *G2_FindOverrideSurface(int surfaceNum, const surfaceInfo_v &surfaceList) -{ - int i; - - // look through entire list - for(i=0; i=0&&index<512); + mOverride[index]=mCurrentTouch; + mAt[index]=pos; + } + int Test(int index) + { + assert(index>=0&&index<512); + if (mOverride[index]!=mCurrentTouch) + { + return -1; + } + else + { + return mAt[index]; + } + } +}; + +static CQuickOverride QuickOverride; + + +// find a particular surface in the surface override list +const surfaceInfo_t *G2_FindOverrideSurface(int surfaceNum,const surfaceInfo_v &surfaceList) +{ + + if (surfaceNum<0) + { + // starting a new lookup + QuickOverride.Invalidate(); + int i; + for(i=0; i=0) + { + QuickOverride.Set(surfaceList[i].surface,i); + } + } + return NULL; + } + int idx=QuickOverride.Test(surfaceNum); + if (idx<0) + { + int i; + if (surfaceNum==10000) + { + for(i=0; i=0&&idxmdxm->animIndex); + model_t *mod_m = R_GetModelByHandle(RE_RegisterModel(fileName)); int surf; int flags; - int *activeSurfaces, *activeBones; + int *activeSurfaces; // did we find a ghoul 2 model or not? if (!mod_m->mdxm) @@ -331,53 +382,18 @@ qboolean G2_SetRootSurface( CGhoul2Info_v &ghoul2, const int modelIndex, const c // firstly, generate a list of active / on surfaces below the root point // gimme some space to put this list into - activeSurfaces = (int *)Z_Malloc(mod_m->mdxm->numSurfaces * 4, TAG_GHOUL2, qfalse); + activeSurfaces = (int *)Z_Malloc(mod_m->mdxm->numSurfaces * 4, TAG_GHOUL2,qfalse); memset(activeSurfaces, 0, (mod_m->mdxm->numSurfaces * 4)); - activeBones = (int *)Z_Malloc(mod_a->mdxa->numBones * 4, TAG_GHOUL2, qfalse); - memset(activeBones, 0, (mod_a->mdxa->numBones * 4)); + + G2_FindOverrideSurface(-1,ghoul2[modelIndex].mSlist); //reset the quick surface override lookup; G2_FindRecursiveSurface(mod_m, surf, ghoul2[modelIndex].mSlist, activeSurfaces); - // now generate the used bone list - CConstructBoneList CBL(ghoul2[modelIndex].mSurfaceRoot, - activeBones, - ghoul2[modelIndex].mSlist, - mod_m, - ghoul2[modelIndex].mBlist); - - G2_ConstructUsedBoneList(CBL); - // now remove all procedural or override surfaces that refer to surfaces that arent on this list G2_RemoveRedundantGeneratedSurfaces(ghoul2[modelIndex].mSlist, activeSurfaces); - // now remove all bones that are pointing at bones that aren't active - G2_RemoveRedundantBoneOverrides(ghoul2[modelIndex].mBlist, activeBones); - - // then remove all bolts that point at surfaces or bones that *arent* active. - G2_RemoveRedundantBolts(ghoul2[modelIndex].mBltlist, ghoul2[modelIndex].mSlist, activeSurfaces, activeBones); - - // then remove all models on this ghoul2 instance that use those bolts that are being removed. - for (int i=0; i> MODEL_SHIFT) & MODEL_AND; - int boltNum = (ghoul2[i].mModelBoltLink >> BOLT_SHIFT) & BOLT_AND; - // if either the bolt list is too small, or the bolt we are pointing at references nothing, remove this model - if ((ghoul2[boltMod].mBltlist.size() <= boltNum) || - ((ghoul2[boltMod].mBltlist[boltNum].boneNumber == -1) && - (ghoul2[boltMod].mBltlist[boltNum].surfaceNumber == -1))) - { - G2API_RemoveGhoul2Model(ghoul2, i); - } - } - } - // remember to free what we used Z_Free(activeSurfaces); - Z_Free(activeBones); - return (qtrue); } assert(0); diff --git a/code/ghoul2/vssver.scc b/code/ghoul2/vssver.scc new file mode 100644 index 0000000..343426b Binary files /dev/null and b/code/ghoul2/vssver.scc differ diff --git a/code/icarus/vssver.scc b/code/icarus/vssver.scc new file mode 100644 index 0000000..e5f0782 Binary files /dev/null and b/code/icarus/vssver.scc differ diff --git a/code/jpeg-6/vssver.scc b/code/jpeg-6/vssver.scc new file mode 100644 index 0000000..88b5c60 Binary files /dev/null and b/code/jpeg-6/vssver.scc differ diff --git a/code/mac/MacQuake3 b/code/mac/MacQuake3 new file mode 100644 index 0000000..f6d71f8 Binary files /dev/null and b/code/mac/MacQuake3 differ diff --git a/code/mac/q3.rsrc b/code/mac/q3.rsrc new file mode 100644 index 0000000..e69de29 diff --git a/code/mac/vssver.scc b/code/mac/vssver.scc new file mode 100644 index 0000000..370282c Binary files /dev/null and b/code/mac/vssver.scc differ diff --git a/code/mp3code/vssver.scc b/code/mp3code/vssver.scc new file mode 100644 index 0000000..8e24b4f Binary files /dev/null and b/code/mp3code/vssver.scc differ diff --git a/code/mssccprj.scc b/code/mssccprj.scc new file mode 100644 index 0000000..db1c382 --- /dev/null +++ b/code/mssccprj.scc @@ -0,0 +1,9 @@ +SCC = This is a Source Code Control file + +[game.dsp] +SCC_Aux_Path = "\\ravend\vss_projects\StarWars" +SCC_Project_Name = "$/code", JVOAAAAA + +[starwars.dsp] +SCC_Aux_Path = "\\ravend\vss_projects\StarWars" +SCC_Project_Name = "$/code", JVOAAAAA diff --git a/code/null/vssver.scc b/code/null/vssver.scc new file mode 100644 index 0000000..8ae9dab Binary files /dev/null and b/code/null/vssver.scc differ diff --git a/code/qcommon/cm_load.cpp b/code/qcommon/cm_load.cpp index 4c797ca..c9efc74 100644 --- a/code/qcommon/cm_load.cpp +++ b/code/qcommon/cm_load.cpp @@ -233,6 +233,11 @@ void CMod_LoadBrushes( lump_t *l ) { Com_Error( ERR_DROP, "CMod_LoadBrushes: bad shaderNum: %i", out->shaderNum ); } out->contents = cm.shaders[out->shaderNum].contentFlags; + //TEMP HACK: for water that cuts vis but is not solid!!! + if ( cm.shaders[out->shaderNum].surfaceFlags & SURF_SLICK ) + { + out->contents &= ~CONTENTS_SOLID; + } CM_BoundBrush( out ); } @@ -740,6 +745,7 @@ static void CM_LoadMap_Actual( const char *name, qboolean clientload, int *check Q_strncpyz( cm.name, name, sizeof( cm.name ) ); Q_strncpyz( gsCachedMapDiskImage, name, sizeof(gsCachedMapDiskImage) ); // so the renderer can check it } + CM_CleanLeafCache(); } // need a wrapper function around this because of multiple returns, need to ensure bool is correct... diff --git a/code/qcommon/cm_local.h b/code/qcommon/cm_local.h index aae2675..2255b2e 100644 --- a/code/qcommon/cm_local.h +++ b/code/qcommon/cm_local.h @@ -162,6 +162,7 @@ void CM_StoreBrushes( leafList_t *ll, int nodenum ); void CM_BoxLeafnums_r( leafList_t *ll, int nodenum ); cmodel_t *CM_ClipHandleToModel( clipHandle_t handle ); +void CM_CleanLeafCache(void); // cm_patch.c diff --git a/code/qcommon/cm_test.cpp b/code/qcommon/cm_test.cpp index 5b505ce..f43ad06 100644 --- a/code/qcommon/cm_test.cpp +++ b/code/qcommon/cm_test.cpp @@ -1,5 +1,46 @@ #include "cm_local.h" +#pragma warning (push, 3) //go back down to 3 for the stl include +#include "hstring.h" +#pragma warning (pop) +using namespace std; +class CPoint +{ +public: + float x,y,z; + CPoint(float _x,float _y,float _z): + x(_x), + y(_y), + z(_z) + { + } + bool operator== (const CPoint& _P) const {return((x==_P.x)&&(y==_P.y)&&(z==_P.z));} +}; +/* +class CPointComparator +{ +public: + bool operator()(const CPoint& _A,const CPoint& _B) const {return((_A.x==_B.x)&&(_A.y==_B.y)&&(_A.z==_B.z));} +}; +*/ +//static map pointToLeaf; +static hlist > pointToLeaf; +//static hlist > pointToContents; + +void CM_CleanLeafCache(void) +{ + hlist >::iterator l; + for(l=pointToLeaf.begin();l!=pointToLeaf.end();l++) + { + pointToLeaf.erase(l); + } +/* + for(l=pointToContents.begin();l!=pointToContents.end();l++) + { + pointToContents.erase(l); + } +*/ +} /* ================== @@ -148,7 +189,7 @@ void CM_BoxLeafnums_r( leafList_t *ll, int nodenum ) { CM_BoxLeafnums ================== */ -int CM_BoxLeafnums( const vec3_t mins, const vec3_t maxs, int *list, int listsize, int *lastLeaf) { +int CM_BoxLeafnums( const vec3_t mins, const vec3_t maxs, int *List, int listsize, int *lastLeaf) { leafList_t ll; cm.checkcount++; @@ -157,7 +198,7 @@ int CM_BoxLeafnums( const vec3_t mins, const vec3_t maxs, int *list, int listsiz VectorCopy( maxs, ll.bounds[1] ); ll.count = 0; ll.maxcount = listsize; - ll.list = list; + ll.list = List; ll.storeLeafs = CM_StoreLeafs; ll.lastLeaf = 0; ll.overflowed = qfalse; @@ -173,7 +214,7 @@ int CM_BoxLeafnums( const vec3_t mins, const vec3_t maxs, int *list, int listsiz CM_BoxBrushes ================== */ -int CM_BoxBrushes( const vec3_t mins, const vec3_t maxs, cbrush_t **list, int listsize ) { +int CM_BoxBrushes( const vec3_t mins, const vec3_t maxs, cbrush_t **List, int listsize ) { leafList_t ll; cm.checkcount++; @@ -182,7 +223,7 @@ int CM_BoxBrushes( const vec3_t mins, const vec3_t maxs, cbrush_t **list, int li VectorCopy( maxs, ll.bounds[1] ); ll.count = 0; ll.maxcount = listsize; - ll.list = (int *)list; + ll.list = (int *)List; ll.storeLeafs = CM_StoreBrushes; ll.lastLeaf = 0; ll.overflowed = qfalse; @@ -202,8 +243,11 @@ CM_PointContents ================== */ + +#if 1 + int CM_PointContents( const vec3_t p, clipHandle_t model ) { - int leafnum; + int leafnum=0; int i, k; int brushnum; cLeaf_t *leaf; @@ -219,8 +263,44 @@ int CM_PointContents( const vec3_t p, clipHandle_t model ) { if ( model ) { clipm = CM_ClipHandleToModel( model ); leaf = &clipm->leaf; - } else { - leafnum = CM_PointLeafnum_r (p, 0); + } + else + { + CPoint pt(p[0],p[1],p[2]); +/* map::iterator l=pointToLeaf.find(pt); + if(l!=pointToLeaf.end()) + { + leafnum=(*l).second; + } + else + { + if(pointToLeaf.size()>=64) + { + pointToLeaf.clear(); + Com_Printf("Cleared cache\n"); + } + leafnum=CM_PointLeafnum_r(p, 0); + pointToLeaf[pt]=leafnum; + }*/ + hlist >::iterator l; + for(l=pointToLeaf.begin();l!=pointToLeaf.end();l++) + { + if((*l).first==pt) + { + leafnum=(*l).second; + break; + } + } + if(l==pointToLeaf.end()) + { + if(pointToLeaf.size()>=64) + { + pointToLeaf.pop_back(); + } + leafnum=CM_PointLeafnum_r(p, 0); + pointToLeaf.push_front(pair(pt,leafnum)); + } + leaf = &cm.leafs[leafnum]; } @@ -247,6 +327,82 @@ int CM_PointContents( const vec3_t p, clipHandle_t model ) { return contents; } +#else + +int CM_PointContents( const vec3_t p, clipHandle_t model ) { + int leafnum=0; + int i, k; + int brushnum; + cLeaf_t *leaf; + cbrush_t *b; + int contents; + float d; + cmodel_t *clipm; + + if (!cm.numNodes) { // map not loaded + return 0; + } + + CPoint pt(p[0],p[1],p[2]); + if ( model ) + { + clipm = CM_ClipHandleToModel( model ); + leaf = &clipm->leaf; + } + else + { + hlist >::iterator l; + for(l=pointToContents.begin();l!=pointToContents.end();l++) + { + if((*l).first==pt) + { + // Breakout early. + return((*l).second); + } + } + + leafnum=CM_PointLeafnum_r(p, 0); + leaf = &cm.leafs[leafnum]; + } + + contents = 0; + for (k=0 ; knumLeafBrushes ; k++) + { + brushnum = cm.leafbrushes[leaf->firstLeafBrush+k]; + b = &cm.brushes[brushnum]; + + // see if the point is in the brush + for ( i = 0 ; i < b->numsides ; i++ ) + { + d = DotProduct( p, b->sides[i].plane->normal ); + // FIXME test for Cash +// if ( d >= b->sides[i].plane->dist ) { + if ( d > b->sides[i].plane->dist ) + { + break; + } + } + + if ( i == b->numsides ) + { + contents |= b->contents; + } + } + + // Cache the result for next time. + if(!model) + { + if(pointToContents.size()>=64) + { + pointToContents.pop_back(); + } + pointToContents.push_front(pair(pt,contents)); + } + + return contents; +} + +#endif /* ================== CM_TransformedPointContents diff --git a/code/qcommon/common.cpp b/code/qcommon/common.cpp index e1319ad..771e601 100644 --- a/code/qcommon/common.cpp +++ b/code/qcommon/common.cpp @@ -33,6 +33,7 @@ int com_argc; char *com_argv[MAX_NUM_ARGVS+1]; static fileHandle_t logfile; +static fileHandle_t speedslog; static fileHandle_t camerafile; fileHandle_t com_journalFile; fileHandle_t com_journalDataFile; // config files are written here @@ -54,6 +55,7 @@ cvar_t *com_FirstTime; cvar_t *cl_paused; cvar_t *sv_paused; cvar_t *com_skippingcin; +cvar_t *com_speedslog; // 1 = buffer log, 2 = flush after each print // com_speeds times int time_game; @@ -761,6 +763,16 @@ void *Z_Malloc(int iSize, memtag_t eTag, qboolean bZeroit) } + // ditch any image_t's (and associated GL texture mem) not used on this level... + // + extern qboolean RE_RegisterImages_LevelLoadEnd(void); + if (RE_RegisterImages_LevelLoadEnd()) + { + gbMemFreeupOccured = qtrue; + continue; // we've dropped at least one image, so try again with the malloc + } + + // ditch the model-binaries cache... (must be getting desperate here!) // extern qboolean RE_RegisterModels_LevelLoadEnd(qboolean bDeleteEverythingNotUsedThisLevel); @@ -1836,6 +1848,7 @@ void Com_Init( char *commandLine ) { com_developer = Cvar_Get ("developer", "0", CVAR_TEMP ); com_logfile = Cvar_Get ("logfile", "0", CVAR_TEMP ); + com_speedslog = Cvar_Get ("speedslog", "0", CVAR_TEMP ); com_timescale = Cvar_Get ("timescale", "1", CVAR_CHEAT ); com_fixedtime = Cvar_Get ("fixedtime", "0", CVAR_CHEAT); @@ -1981,21 +1994,34 @@ void Com_WriteConfig_f( void ) { Com_ModifyMsec ================ */ -int Com_ModifyMsec( int msec ) { + + +int Com_ModifyMsec( int msec, float &fraction ) +{ int clampTime; + fraction=0.0f; + // // modify time for debugging values // - if ( com_fixedtime->integer ) { + if ( com_fixedtime->integer ) + { msec = com_fixedtime->integer; - } else if ( com_timescale->value ) { - msec *= com_timescale->value; + } + else if ( com_timescale->value ) + { + fraction=(float)msec; + fraction*=com_timescale->value; + msec=(int)floor(fraction); + fraction-=(float)msec; } // don't let it scale below 1 msec - if ( msec < 1 ) { + if ( msec < 1 ) + { msec = 1; + fraction=0.0f; } if ( com_skippingcin->integer ) { @@ -2010,6 +2036,7 @@ int Com_ModifyMsec( int msec ) { if ( msec > clampTime ) { msec = clampTime; + fraction=0.0f; } return msec; @@ -2020,6 +2047,15 @@ int Com_ModifyMsec( int msec ) { Com_Frame ================= */ +static vec3_t corg; +static vec3_t cangles; +static bool bComma; +void Com_SetOrgAngles(vec3_t org,vec3_t angles) +{ + VectorCopy(org,corg); + VectorCopy(angles,cangles); +} + #pragma warning (disable: 4701) //local may have been used without init (timing info vars) void Com_Frame( void ) { try @@ -2027,6 +2063,7 @@ try int timeBeforeFirstEvents, timeBeforeServer, timeBeforeEvents, timeBeforeClient, timeAfter; int msec, minMsec; static int lastTime; + char msg[MAXPRINTMSG]; // write config file if anything changed Com_WriteConfiguration(); @@ -2063,7 +2100,8 @@ try // mess with msec if needed com_frameMsec = msec; - msec = Com_ModifyMsec( msec ); + float fractionMsec=0.0f; + msec = Com_ModifyMsec( msec, fractionMsec); // // server side @@ -2072,7 +2110,7 @@ try timeBeforeServer = Sys_Milliseconds (); } - SV_Frame (msec); + SV_Frame (msec, fractionMsec); // @@ -2098,7 +2136,7 @@ try timeBeforeClient = Sys_Milliseconds (); } - CL_Frame (msec); + CL_Frame (msec, fractionMsec); if ( com_speeds->integer ) { timeAfter = Sys_Milliseconds (); @@ -2119,8 +2157,42 @@ try sv -= time_game; cl -= time_frontend + time_backend; - Com_Printf ("fr:%i all:%3i sv:%3i ev:%3i cl:%3i gm:%3i tr:%3i pvs:%3i rf:%3i bk:%3i\n", - com_frameNumber, all, sv, ev, cl, time_game, timeInTrace, timeInPVSCheck, time_frontend, time_backend ); + Com_Printf("fr:%i all:%3i sv:%3i ev:%3i cl:%3i gm:%3i tr:%3i pvs:%3i rf:%3i bk:%3i\n", + com_frameNumber, all, sv, ev, cl, time_game, timeInTrace, timeInPVSCheck, time_frontend, time_backend); + + // speedslog + if ( com_speedslog && com_speedslog->integer ) + { + if(!speedslog) + { + speedslog = FS_FOpenFileWrite("speeds.log"); + FS_Write("data={\n", strlen("data={\n"), speedslog); + bComma=false; + if ( com_speedslog->integer > 1 ) + { + // force it to not buffer so we get valid + // data even if we are crashing + FS_ForceFlush(logfile); + } + } + if (speedslog) + { + if(bComma) + { + FS_Write(",\n", strlen(",\n"), speedslog); + bComma=false; + } + FS_Write("{", strlen("{"), speedslog); + Com_sprintf(msg,sizeof(msg), + "%8.4f,%8.4f,%8.4f,%8.4f,%8.4f,%8.4f,",corg[0],corg[1],corg[2],cangles[0],cangles[1],cangles[2]); + FS_Write(msg, strlen(msg), speedslog); + Com_sprintf(msg,sizeof(msg), + "%i,%3i,%3i,%3i,%3i,%3i,%3i,%3i,%3i,%3i}", + com_frameNumber, all, sv, ev, cl, time_game, timeInTrace, timeInPVSCheck, time_frontend, time_backend); + FS_Write(msg, strlen(msg), speedslog); + bComma=true; + } + } timeInTrace = timeInPVSCheck = 0; } @@ -2166,6 +2238,12 @@ void Com_Shutdown (void) { logfile = 0; } + if (speedslog) { + FS_Write("\n};", strlen("\n};"), speedslog); + FS_FCloseFile (speedslog); + speedslog = 0; + } + if (camerafile) { FS_FCloseFile (camerafile); camerafile = 0; diff --git a/code/qcommon/hstring.cpp b/code/qcommon/hstring.cpp new file mode 100644 index 0000000..c4dddbf --- /dev/null +++ b/code/qcommon/hstring.cpp @@ -0,0 +1,493 @@ +#include "cm_local.h" +#include "hstring.h" + +// mapPoolBlockCount is defined differently in the executable (sv_main.cpp) and the game dll (g_main.cpp) cuz +//we likely don't need as many blocks in the executable as we do in the game +extern int mapPoolBlockCount; + +// Used to fool optimizer during compilation of mem touch routines. +int HaHaOptimizer2=0; + +CMapPoolLow &GetMapPool() +{ + // this may need to be ifdefed to be different for different modules + static CMapPoolLow thePool; + return thePool; +} + +#define MAPBLOCK_SIZE_NODES (1024) +#define MAPNODE_FREE (0xa1) +#define MAPNODE_INUSE (0x94) + +struct SMapNode +{ + unsigned char mData[MAP_NODE_SIZE-2]; + unsigned char mMapBlockNum; + unsigned char mTag; +}; + +class CMapBlock +{ + int mId; + char mRaw[(MAPBLOCK_SIZE_NODES+1)*MAP_NODE_SIZE]; + SMapNode *mNodes; + int mLastNode; + +public: + CMapBlock(int id,vector &freeList) : + mLastNode(0) + { + // Alloc node storage for MAPBLOCK_SIZE_NODES worth of nodes. + mNodes=(SMapNode *)((((unsigned long)mRaw)+MAP_NODE_SIZE)&~(unsigned long)0x1f); + // Set all nodes to initially be free. + int i; + for(i=0;i=&mNodes[0])&&(((SMapNode *)node)<&mNodes[MAPBLOCK_SIZE_NODES])); + } +}; + +CMapPoolLow::CMapPoolLow() +{ + mLastBlockNum=-1; +} + +CMapPoolLow::~CMapPoolLow() +{ +#if _DEBUG +#if _GAME + if(mFreeList.size()mTag==MAPNODE_FREE); + assert((((SMapNode *)node)->mMapBlockNum)>=0); + assert((((SMapNode *)node)->mMapBlockNum)<256); + assert((((SMapNode *)node)->mMapBlockNum)<=mLastBlockNum); + assert(mMapBlocks[((SMapNode *)node)->mMapBlockNum]->bOwnsNode(node)); + + // Ok, mark the node as in use. + ((SMapNode *)node)->mTag=MAPNODE_INUSE; + + return(node); +} + +void CMapPoolLow::Free(void *p) +{ + // Validate that someone isn't trying to double free this node and also + // that the end marker is intact. + assert(((SMapNode *)p)->mTag==MAPNODE_INUSE); + assert((((SMapNode *)p)->mMapBlockNum)>=0); + assert((((SMapNode *)p)->mMapBlockNum)<256); + assert((((SMapNode *)p)->mMapBlockNum)<=mLastBlockNum); + assert(mMapBlocks[((SMapNode *)p)->mMapBlockNum]->bOwnsNode(p)); + + // Ok, mark the the node as free. + ((SMapNode *)p)->mTag=MAPNODE_FREE; + + // Add a new freelist entry to point at this node. + mFreeList.push_back(p); +} + +void CMapPoolLow::TouchMem() +{ + int i,j; + unsigned char *memory; + int totSize=0; + for(i=0;i=0&&hash=0&&mFindPtr(BLOCK_SIZE-mBytesUsed)) + { + return(0); + } + + // Return the pointer to the start of allocated space. + char *ret=&mRaw[mBytesUsed]; + mBytesUsed+=sizeBytes; + return ret; + } + + bool operator== (const CHSBlock &block) const + { + if(!memcmp(mRaw,block.mRaw,BLOCK_SIZE)) + { + return(true); + } + return(false); + } +}; + +class CPool +{ + vector mBlockVec; + +public: + int mNextStringId; + int mLastBlockNum; + + CPool(void) : + mNextStringId(1), + mLastBlockNum(-1) + { + memset(gCharPtrs,0,MAX_HSTRINGS*4); + } + + ~CPool(void) + { + int i; + for (i=0;i=0) + { + // Get the pointer to the start of allocated space in the current block. + raw=mBlockVec[mLastBlockNum]->Alloc(sizeBytes); + } + if(!raw) + { + // Ok, make a new empty block and append it. + CHSBlock *block=new(CHSBlock); + mBlockVec.push_back(block); + mLastBlockNum++; + raw=mBlockVec[mLastBlockNum]->Alloc(sizeBytes); + } + // Should never really happen!! + assert(raw); + + id=mNextStringId; + gCharPtrs[mNextStringId]=raw; + mNextStringId++; + + return(raw); + } + + bool operator== (const CPool &pool) const + { + int i; + for(i=0;i0&&id0&&mId0&&mId +#include +#include +#include +#pragma warning (pop) + +using namespace std; + +class hstring +{ + int mId; + + void Init(const char *str); + +public: + hstring() + { + mId=0; + } + hstring(const char *str) + { + Init(str); + } + hstring(const string &str) + { + Init(str.c_str()); + } + hstring(const hstring &str) + { + mId=str.mId; + } + + operator string () const + { + return str(); + } + + const char *c_str(void) const; + string str(void) const; + + hstring& operator= (const char *str) + { + Init(str); + return *this; + } + hstring& operator= (const string &str) + { + Init(str.c_str()); + return *this; + } + hstring& operator= (const hstring &str) + { + mId=str.mId; + return *this; + } + + bool operator== (const hstring &str) const + { + return((mId==str.mId)?true:false); + } + + int compare(const hstring &str) const + { + return strcmp(c_str(),str.c_str()); + } + + bool operator< (const hstring &str) const + { + return((mId mMapBlocks; + vector mFreeList; + int mLastBlockNum; + +public: + CMapPoolLow(); + ~CMapPoolLow(); + void *Alloc(); + void Free(void *p); + void TouchMem(); +}; + +CMapPoolLow &GetMapPool(); + +template +class CMapPool +{ + CMapPoolLow &mPool; +public: + CMapPool() : mPool(GetMapPool()) + { + + } + template + CMapPool(const U&) : mPool(GetMapPool()) + { + } + ~CMapPool() + { + } + + typedef T value_type; + typedef T* pointer; + typedef const T* const_pointer; + typedef T& reference; + typedef const T& const_reference; + typedef size_t size_type; + typedef ptrdiff_t difference_type; + + template + struct rebind + { + typedef CMapPool other; + }; + + // return address of values + pointer address (reference value) const + { + return &value; + } + const_pointer address (const_reference value) const + { + return &value; + } + + // return maximum number of elements that can be allocated + size_type max_size () const + { + return mMaxSize; + } + + // allocate but don't initialize num elements of type T + pointer allocate (size_type num, const void* = 0) + { + assert(sizeof(T)<=(MAP_NODE_SIZE-2)); // to big for this pool + assert(num==1); //allocator not design for this + return (T*)mPool.Alloc(); + } + void *_Charalloc(size_type size) + { + assert(size<=(MAP_NODE_SIZE-2)); // to big for this pool + return mPool.Alloc(); + } + + // initialize elements of allocated storage p with value value + void construct (pointer p, const T& value) + { + // initialize memory with placement new + new((void*)p)T(value); + } + + // destroy elements of initialized storage p + void destroy (pointer p) + { + // destroy objects by calling their destructor + p->~T(); + } + + // deallocate storage p of deleted elements + template + void deallocate (U *p, size_type num) + { + assert(num==1); //allocator not design for this + mPool.Free(p); + } +}; + +template +bool operator== (const CMapPool&, + const CMapPool&) +{ + return false; +} +template +bool operator!= (const CMapPool&, + const CMapPool&) +{ + return true; +} + +template > +class hmap : public map >{}; + +template > +class hmultimap : public multimap >{}; + +template > +class hset : public set >{}; + +template > +class hmultiset : public multiset >{}; + +template +class hlist : public list >{}; + +#endif // hString_H \ No newline at end of file diff --git a/code/qcommon/qcommon.h b/code/qcommon/qcommon.h index bd160d6..5d449a3 100644 --- a/code/qcommon/qcommon.h +++ b/code/qcommon/qcommon.h @@ -617,6 +617,7 @@ inline void *Hunk_Alloc( int size, qboolean bZeroIt = qtrue) void Com_TouchMemory( void ); // commandLine should not include the executable name (argv[0]) +void Com_SetOrgAngles(vec3_t org,vec3_t angles); void Com_Init( char *commandLine ); void Com_Frame( void ); void Com_Shutdown( void ); @@ -641,7 +642,7 @@ void CL_InitKeyCommands( void ); void CL_Init( void ); void CL_Disconnect( void ); void CL_Shutdown( void ); -void CL_Frame( int msec ); +void CL_Frame( int msec,float fractionMsec ); qboolean CL_GameCommand( void ); void CL_KeyEvent (int key, qboolean down, unsigned time); @@ -686,7 +687,7 @@ void SCR_DebugGraph (float value, int color); // FIXME: move logging to common? // void SV_Init( void ); void SV_Shutdown( char *finalmsg ); -void SV_Frame( int msec ); +void SV_Frame( int msec,float fractionMsec); void SV_PacketEvent( netadr_t from, msg_t *msg ); qboolean SV_GameCommand( void ); diff --git a/code/qcommon/strip.cpp b/code/qcommon/strip.cpp index 1b999c0..5acb6d1 100644 --- a/code/qcommon/strip.cpp +++ b/code/qcommon/strip.cpp @@ -108,7 +108,7 @@ sFlagPair LanguagePairs[] = { TK_TEXT_LANGUAGE6, SP_LANGUAGE_TAIWANESE }, { TK_TEXT_LANGUAGE7, SP_LANGUAGE_ITALIAN }, { TK_TEXT_LANGUAGE8, SP_LANGUAGE_SPANISH }, - { TK_TEXT_LANGUAGE9, SP_LANGUAGE_9 }, + { TK_TEXT_LANGUAGE9, SP_LANGUAGE_JAPANESE }, { TK_TEXT_LANGUAGE10, SP_LANGUAGE_10}, { TK_INVALID, 0 } }; @@ -738,10 +738,10 @@ map SP_ListByID; * Registration flag * * Return: - * pointer to desired String Package + * success/fail * ************************************************************************************************/ -void SP_Register(const char *inPackage, unsigned char Registration) +qboolean SP_Register(const char *inPackage, unsigned char Registration) { char *buffer; char Package[MAX_QPATH]; @@ -770,7 +770,7 @@ void SP_Register(const char *inPackage, unsigned char Registration) { Com_Error(ERR_FATAL, "Could not open string package '%s'", Package); } - return; + return qfalse; } // Create the new string package @@ -796,6 +796,7 @@ void SP_Register(const char *inPackage, unsigned char Registration) new_sp->Register(Registration); // return new_sp; + return qtrue; } @@ -947,7 +948,7 @@ void SP_Init(void) sp_language = Cvar_Get("sp_language", va("%d", SP_LANGUAGE_ENGLISH), CVAR_ARCHIVE | CVAR_NORESTART); sp_show_strip = Cvar_Get ("sv_show_strip", "0", 0); -// Cvar_Set("sp_language", va("%d", SP_LANGUAGE_KOREAN)); // stetest, do NOT leave in +// Cvar_Set("sp_language", va("%d", SP_LANGUAGE_JAPANESE)); // stetest, do NOT leave in SP_UpdateLanguage(); sp_language->modified = false; diff --git a/code/qcommon/strippublic.h b/code/qcommon/strippublic.h index 0356dbd..74a5f6c 100644 --- a/code/qcommon/strippublic.h +++ b/code/qcommon/strippublic.h @@ -8,16 +8,6 @@ #define MAX_STRINGS 256 #define MAX_ID 255 -/* -ENGLISH -FRENCH -GERMAN -BRITISH -KOREAN -TAIWANESE -ITALIAN -SPANISH -*/ enum { SP_LANGUAGE_ENGLISH = 0, @@ -28,7 +18,7 @@ enum SP_LANGUAGE_TAIWANESE, SP_LANGUAGE_ITALIAN, SP_LANGUAGE_SPANISH, - SP_LANGUAGE_9, + SP_LANGUAGE_JAPANESE, SP_LANGUAGE_10, SP_LANGUGAGE_MAX, SP_LANGUAGE_ALL = 255 @@ -60,7 +50,7 @@ enum // Registration -void SP_Register(const char *Package, unsigned char Registration); +qboolean SP_Register(const char *Package, unsigned char Registration); void SP_Unload(unsigned char Registration); // Direct string functions @@ -89,6 +79,11 @@ inline qboolean Language_IsTaiwanese(void) return (sp_language && sp_language->integer == SP_LANGUAGE_TAIWANESE); } +inline qboolean Language_IsJapanese(void) +{ + return (sp_language && sp_language->integer == SP_LANGUAGE_JAPANESE); +} + inline int Language_GetIntegerValue(void) { if (sp_language) diff --git a/code/qcommon/stv_version.h b/code/qcommon/stv_version.h index 3fd0670..9e5924d 100644 --- a/code/qcommon/stv_version.h +++ b/code/qcommon/stv_version.h @@ -1,6 +1,6 @@ // Current version of the single player game -#define Q3_VERSION "JK2: v0.54" +#define Q3_VERSION "JK2: v0.55" // end diff --git a/code/qcommon/vssver.scc b/code/qcommon/vssver.scc new file mode 100644 index 0000000..8337976 Binary files /dev/null and b/code/qcommon/vssver.scc differ diff --git a/code/renderer/mssccprj.scc b/code/renderer/mssccprj.scc new file mode 100644 index 0000000..df82911 --- /dev/null +++ b/code/renderer/mssccprj.scc @@ -0,0 +1,5 @@ +SCC = This is a Source Code Control file + +[renderer.dsp] +SCC_Aux_Path = "\\ravend\vss_projects\StarWars" +SCC_Project_Name = "$/code/renderer", VVOAAAAA diff --git a/code/renderer/tr_font.cpp b/code/renderer/tr_font.cpp index fbbe74f..06e6e11 100644 --- a/code/renderer/tr_font.cpp +++ b/code/renderer/tr_font.cpp @@ -58,6 +58,13 @@ static int Korean_CollapseKSC5601HangulCode(unsigned int uiCode) return 0; } +static int Korean_InitFields(int &iGlyphTPs, LPCSTR &psLang) +{ + psLang = "kor"; + iGlyphTPs = GLYPH_MAX_KOREAN_SHADERS; + return 32; // m_iAsianGlyphsAcross +} + // ======================== some taiwanese stuff ============================== // (all ranges inclusive for Big5)... @@ -76,8 +83,9 @@ extern qboolean Language_IsTaiwanese( void ); static bool Taiwanese_ValidBig5Code( unsigned int uiCode ) { - if ( (uiCode >= ((BIG5_HIBYTE_START0<<8)|BIG5_LOBYTE_LOBOUND0) && uiCode <= ((BIG5_HIBYTE_STOP0<<8)|BIG5_LOBYTE_HIBOUND0)) - || (uiCode >= ((BIG5_HIBYTE_START1<<8)|BIG5_LOBYTE_LOBOUND0) && uiCode <= ((BIG5_HIBYTE_STOP1<<8)|0xD5)) // no meaningful equate for this, it's just end-of-glyphs for highest row + const byte _iHi = (uiCode >> 8)&0xFF; + if ( (_iHi >= BIG5_HIBYTE_START0 && _iHi <= BIG5_HIBYTE_STOP0) + || (_iHi >= BIG5_HIBYTE_START1 && _iHi <= BIG5_HIBYTE_STOP1) ) { const byte _iLo = uiCode & 0xFF; @@ -98,10 +106,10 @@ static bool Taiwanese_ValidBig5Code( unsigned int uiCode ) // static bool Taiwanese_IsTrailingPunctuation( unsigned int uiCode ) { - // so far I'm just counting the first 20 chars, those seem to be all the basic punctuation... + // so far I'm just counting the first 21 chars, those seem to be all the basic punctuation... // if ( uiCode >= ((BIG5_HIBYTE_START0<<8)|BIG5_LOBYTE_LOBOUND0) && - uiCode <= ((BIG5_HIBYTE_START0<<8)|BIG5_LOBYTE_LOBOUND0+20) + uiCode < ((BIG5_HIBYTE_START0<<8)|BIG5_LOBYTE_LOBOUND0+20) ) { return true; @@ -131,10 +139,113 @@ static int Taiwanese_CollapseBig5Code( unsigned int uiCode ) return 0; } +static int Taiwanese_InitFields(int &iGlyphTPs, LPCSTR &psLang) +{ + psLang = "tai"; + iGlyphTPs = GLYPH_MAX_TAIWANESE_SHADERS; + return 64; // m_iAsianGlyphsAcross +} + +// ======================== some Japanese stuff ============================== + + +// ( all ranges inclusive for Shift-JIS ) +// +#define SHIFTJIS_HIBYTE_START0 0x81 +#define SHIFTJIS_HIBYTE_STOP0 0x9F +#define SHIFTJIS_HIBYTE_START1 0xE0 +#define SHIFTJIS_HIBYTE_STOP1 0xEF +// +#define SHIFTJIS_LOBYTE_START0 0x40 +#define SHIFTJIS_LOBYTE_STOP0 0x7E +#define SHIFTJIS_LOBYTE_START1 0x80 +#define SHIFTJIS_LOBYTE_STOP1 0xFC +#define SHIFTJIS_CODES_PER_ROW (((SHIFTJIS_LOBYTE_STOP0-SHIFTJIS_LOBYTE_START0)+1)+((SHIFTJIS_LOBYTE_STOP1-SHIFTJIS_LOBYTE_START1)+1)) + + +extern qboolean Language_IsJapanese( void ); + +static bool Japanese_ValidShiftJISCode( byte _iHi, byte _iLo ) +{ + if ( (_iHi >= SHIFTJIS_HIBYTE_START0 && _iHi <= SHIFTJIS_HIBYTE_STOP0) + || (_iHi >= SHIFTJIS_HIBYTE_START1 && _iHi <= SHIFTJIS_HIBYTE_STOP1) + ) + { + if ( (_iLo >= SHIFTJIS_LOBYTE_START0 && _iLo <= SHIFTJIS_LOBYTE_STOP0) || + (_iLo >= SHIFTJIS_LOBYTE_START1 && _iLo <= SHIFTJIS_LOBYTE_STOP1) + ) + { + return true; + } + } + + return false; +} + +static inline bool Japanese_ValidShiftJISCode( unsigned int uiCode ) +{ + return Japanese_ValidShiftJISCode( uiCode >> 8, uiCode & 0xFF ); +} + + +// only call this when Japanese_ValidShiftJISCode() has already returned true... +// +static bool Japanese_IsTrailingPunctuation( unsigned int uiCode ) +{ + // so far I'm just counting the first 18 chars, those seem to be all the basic punctuation... + // + if ( uiCode >= ((SHIFTJIS_HIBYTE_START0<<8)|SHIFTJIS_LOBYTE_START0) && + uiCode < ((SHIFTJIS_HIBYTE_START0<<8)|SHIFTJIS_LOBYTE_START0+18) + ) + { + return true; + } + + return false; +} + + +// takes a ShiftJIS double-byte code and collapse down to a 0..n glyph index... +// +// (invalid codes will return 0) +// +static int Japanese_CollapseShiftJISCode( unsigned int uiCode ) +{ + if (Japanese_ValidShiftJISCode( uiCode )) + { + uiCode -= ((SHIFTJIS_HIBYTE_START0<<8)|SHIFTJIS_LOBYTE_START0); // sneaky maths on both bytes, reduce to 0x0000 onwards + + if ( (uiCode & 0xFF) >= (SHIFTJIS_LOBYTE_START1)-SHIFTJIS_LOBYTE_START0) + { + uiCode -= ((SHIFTJIS_LOBYTE_START1)-SHIFTJIS_LOBYTE_STOP0)-1; + } + + if ( ((uiCode>>8)&0xFF) >= (SHIFTJIS_HIBYTE_START1)-SHIFTJIS_HIBYTE_START0) + { + uiCode -= ((SHIFTJIS_HIBYTE_START1)-SHIFTJIS_HIBYTE_STOP0)-1; + } + + uiCode = ((uiCode >> 8) * SHIFTJIS_CODES_PER_ROW) + (uiCode & 0xFF); + + return uiCode; + } + return 0; +} + + +static int Japanese_InitFields(int &iGlyphTPs, LPCSTR &psLang) +{ + psLang = "jap"; + iGlyphTPs = GLYPH_MAX_JAPANESE_SHADERS; + return 64; // m_iAsianGlyphsAcross +} // ============================================================================ + + + // takes char *, returns integer char at that point, and advances char * on by enough bytes to move // past the letter (either western 1 byte or Asian multi-byte)... // @@ -181,6 +292,24 @@ unsigned int AnyLanguage_ReadCharFromString( const char **ppsText, qboolean *pbI return uiLetter; } } + else + if ( Language_IsJapanese() ) + { + if ( Japanese_ValidShiftJISCode( psString[0], psString[1] )) + { + uiLetter = (psString[0] * 256) + psString[1]; + *ppsText += 2; + + // need to ask if this is a trailing (ie like a comma or full-stop) punctuation?... + // + if ( pbIsTrailingPunctuation) + { + *pbIsTrailingPunctuation = Japanese_IsTrailingPunctuation( uiLetter ); + } + + return uiLetter; + } + } // ... must not have been an MBCS code... // @@ -206,7 +335,7 @@ unsigned int AnyLanguage_ReadCharFromString( const char **ppsText, qboolean *pbI // qboolean Language_IsAsian(void) { - return (Language_IsKorean() || Language_IsTaiwanese()); + return (Language_IsKorean() || Language_IsTaiwanese() || Language_IsJapanese()); } @@ -253,6 +382,44 @@ CFontInfo::CFontInfo(const char *fontName) // finished... fontArray.resize(fontIndex + 1); fontArray[fontIndex++] = this; + + + extern cvar_t *com_buildScript; + if (com_buildScript->integer) + { + static qboolean bDone = qfalse; // Do this once only (for speed)... + if (!bDone) + { + bDone = qtrue; + + char sTemp[MAX_QPATH]; + int iGlyphTPs = 0; + const char *psLang = NULL; + int iAsianGlyphsAcross; + + for (int iLang=0; iLang<3; iLang++) + { + switch (iLang) + { + case 0: iAsianGlyphsAcross = Korean_InitFields (iGlyphTPs, psLang); break; + case 1: iAsianGlyphsAcross = Taiwanese_InitFields (iGlyphTPs, psLang); break; + case 2: iAsianGlyphsAcross = Japanese_InitFields (iGlyphTPs, psLang); break; + } + + for (int i=0; i=0&&index=0&&mFinalBones[index].parent=0) + { + EvalLow(mFinalBones[index].parent); // make sure parent is evaluated + SBoneCalc &par=mBones[mFinalBones[index].parent]; + mBones[index].newFrame=par.newFrame; + mBones[index].currentFrame=par.currentFrame; + mBones[index].backlerp=par.backlerp; + mBones[index].blendFrame=par.blendFrame; + mBones[index].blendOldFrame=par.blendOldFrame; + mBones[index].blendMode=par.blendMode; + mBones[index].blendLerp=par.blendLerp; + } + G2_TransformBone(index,*this); + mFinalBones[index].touch=mCurrentTouch; + } + } +public: + int frameSize; + const mdxaHeader_t *header; + void *mod; + + // these are split for better cpu cache behavior + vector mBones; + vector mFinalBones; + + vector mSmoothBones; // for render smoothing + vector mSkels; + + boneInfo_v *rootBoneList; + mdxaBone_t rootMatrix; + int incomingTime; + + int mCurrentTouch; + + // for render smoothing + int mLastTouch; + int mLastLastTouch; + bool mSmoothingActive; + bool mUnsquash; + float mSmoothFactor; + int mLastTime; + int mWraithID; // this is just used for debug prints, can use it for any int of interest in JK2 + + CBoneCache(void *amod,const mdxaHeader_t *aheader) : + mod(amod), + header(aheader) + { + assert(amod); + assert(aheader); + mSmoothingActive=false; + mUnsquash=false; + mSmoothFactor=0.0f; + + int numBones=header->numBones; + mBones.resize(numBones); + mFinalBones.resize(numBones); + mSmoothBones.resize(numBones); + mSkels.resize(numBones); + mdxaSkelOffsets_t *offsets; + mdxaSkel_t *skel; + offsets = (mdxaSkelOffsets_t *)((byte *)header + sizeof(mdxaHeader_t)); + + int i; + for (i=0;ioffsets[i]); + mSkels[i]=skel; + mFinalBones[i].parent=skel->parent; + } + mCurrentTouch=3; + mLastTouch=2; + mLastLastTouch=1; + mLastTime=0; + } + SBoneCalc &Root() + { + assert(mBones.size()); + return mBones[0]; + } + const mdxaBone_t &Eval(int index) + { + EvalLow(index); + return mFinalBones[index].boneMatrix; + } + const mdxaBone_t &EvalRender(int index) + { + EvalLow(index); + if (mSmoothingActive) + { + if (mSmoothBones[index].touch!=mCurrentTouch) + { + if (mSmoothBones[index].touch==mLastTouch) + { + int i; + float *oldM=&mSmoothBones[index].boneMatrix.matrix[0][0]; + float *newM=&mFinalBones[index].boneMatrix.matrix[0][0]; + for (i=0;i<12;i++,oldM++,newM++) + { + *oldM=mSmoothFactor*(*oldM-*newM)+*newM; + } + } + else + { + memcpy(&mSmoothBones[index].boneMatrix,&mFinalBones[index].boneMatrix,sizeof(mdxaBone_t)); + } + if (mUnsquash) + { + mdxaBone_t tempMatrix; + Multiply_3x4Matrix(&tempMatrix,&mSmoothBones[index].boneMatrix, &mSkels[index]->BasePoseMat); + float maxl; + maxl=VectorLength(&mSkels[index]->BasePoseMat.matrix[0][0]); + VectorNormalize(&tempMatrix.matrix[0][0]); + VectorNormalize(&tempMatrix.matrix[1][0]); + VectorNormalize(&tempMatrix.matrix[2][0]); + + VectorScale(&tempMatrix.matrix[0][0],maxl,&tempMatrix.matrix[0][0]); + VectorScale(&tempMatrix.matrix[1][0],maxl,&tempMatrix.matrix[1][0]); + VectorScale(&tempMatrix.matrix[2][0],maxl,&tempMatrix.matrix[2][0]); + Multiply_3x4Matrix(&mSmoothBones[index].boneMatrix,&tempMatrix,&mSkels[index]->BasePoseMatInv); + } + mSmoothBones[index].touch=mCurrentTouch; + } + return mSmoothBones[index].boneMatrix; + } + return mFinalBones[index].boneMatrix; } }; +void RemoveBoneCache(CBoneCache *boneCache) +{ + delete boneCache; +} + +const mdxaBone_t &EvalBoneCache(int index,CBoneCache *boneCache) +{ + return boneCache->Eval(index); +} + + class CRenderSurface { public: @@ -131,7 +225,7 @@ public: const shader_t *cust_shader; int fogNum; qboolean personalModel; - mdxaBone_v &bonePtr; + CBoneCache *boneCache; int renderfx; const skin_t *skin; const model_t *currentModel; @@ -144,7 +238,7 @@ public: const shader_t *initcust_shader, int initfogNum, qboolean initpersonalModel, - mdxaBone_v &initbonePtr, + CBoneCache *initboneCache, int initrenderfx, const skin_t *initskin, const model_t *initcurrentModel, @@ -156,7 +250,7 @@ public: cust_shader(initcust_shader), fogNum(initfogNum), personalModel(initpersonalModel), - bonePtr(initbonePtr), + boneCache(initboneCache), renderfx(initrenderfx), skin(initskin), currentModel(initcurrentModel), @@ -350,92 +444,8 @@ static int G2_ComputeLOD( trRefEntity_t *ent, const model_t *currentModel, int l return lod; } -//====================================================================== -// -// Bone Manipulation code - -void G2_CreateQuaterion(mdxaBone_t *mat, vec4_t quat) -{ - // this is revised for the 3x4 matrix we use in G2. - float t = 1 + mat->matrix[0][0] + mat->matrix[1][1] + mat->matrix[2][2]; - float s; - - //If the trace of the matrix is greater than zero, then - //perform an "instant" calculation. - //Important note wrt. rouning errors: - //Test if ( T > 0.00000001 ) to avoid large distortions! - if (t > 0.00000001) - { - s = sqrt(t) * 2; - quat[0] = ( mat->matrix[1][2] - mat->matrix[2][1] ) / s; - quat[1] = ( mat->matrix[2][0] - mat->matrix[0][2] ) / s; - quat[2] = ( mat->matrix[0][1] - mat->matrix[1][0] ) / s; - quat[3] = 0.25 * s; - } - else - { - //If the trace of the matrix is equal to zero then identify - //which major diagonal element has the greatest value. - - //Depending on this, calculate the following: - - if ( mat->matrix[0][0] > mat->matrix[1][1] && mat->matrix[0][0] > mat->matrix[2][2] ) { // Column 0: - s = sqrt( 1.0 + mat->matrix[0][0] - mat->matrix[1][1] - mat->matrix[2][2])* 2; - quat[0] = 0.25 * s; - quat[1] = (mat->matrix[0][1] + mat->matrix[1][0] ) / s; - quat[2] = (mat->matrix[2][0] + mat->matrix[0][2] ) / s; - quat[3] = (mat->matrix[1][2] - mat->matrix[2][1] ) / s; - - } else if ( mat->matrix[1][1] > mat->matrix[2][2] ) { // Column 1: - s = sqrt( 1.0 + mat->matrix[1][1] - mat->matrix[0][0] - mat->matrix[2][2] ) * 2; - quat[0] = (mat->matrix[0][1] + mat->matrix[1][0] ) / s; - quat[1] = 0.25 * s; - quat[2] = (mat->matrix[1][2] + mat->matrix[2][1] ) / s; - quat[3] = (mat->matrix[2][0] - mat->matrix[0][2] ) / s; - - } else { // Column 2: - s = sqrt( 1.0 + mat->matrix[2][2] - mat->matrix[0][0] - mat->matrix[1][1] ) * 2; - quat[0] = (mat->matrix[2][0]+ mat->matrix[0][2] ) / s; - quat[1] = (mat->matrix[1][2] + mat->matrix[2][1] ) / s; - quat[2] = 0.25 * s; - quat[3] = (mat->matrix[0][1] - mat->matrix[1][0] ) / s; - } - } -} - -void G2_CreateMatrixFromQuaterion(mdxaBone_t *mat, vec4_t quat) -{ - - float xx = quat[0] * quat[0]; - float xy = quat[0] * quat[1]; - float xz = quat[0] * quat[2]; - float xw = quat[0] * quat[3]; - - float yy = quat[1] * quat[1]; - float yz = quat[1] * quat[2]; - float yw = quat[1] * quat[3]; - - float zz = quat[2] * quat[2]; - float zw = quat[2] * quat[3]; - - mat->matrix[0][0] = 1 - 2 * ( yy + zz ); - mat->matrix[1][0] = 2 * ( xy - zw ); - mat->matrix[2][0] = 2 * ( xz + yw ); - - mat->matrix[0][1] = 2 * ( xy + zw ); - mat->matrix[1][1] = 1 - 2 * ( xx + zz ); - mat->matrix[2][1] = 2 * ( yz - xw ); - - mat->matrix[0][2] = 2 * ( xz - yw ); - mat->matrix[1][2] = 2 * ( yz + xw ); - mat->matrix[2][2] = 1 - 2 * ( xx + yy ); - - mat->matrix[0][3] = mat->matrix[1][3] = mat->matrix[2][3] = 0; -} - -// nasty little matrix multiply going on here.. -void Multiply_3x4Matrix(mdxaBone_t *out, mdxaBone_t *in2, mdxaBone_t *in) +void Multiply_3x4Matrix(mdxaBone_t *out,const mdxaBone_t *in2,const mdxaBone_t *in) { // first row of out out->matrix[0][0] = (in2->matrix[0][0] * in->matrix[0][0]) + (in2->matrix[0][1] * in->matrix[1][0]) + (in2->matrix[0][2] * in->matrix[2][0]); @@ -471,39 +481,256 @@ static inline void UnCompressBone(float mat[3][4], int iBonePoolIndex, const mdx } -#define G2_DEBUG_TIMING (0) +#define DEBUG_G2_TIMING (0) + +void G2_TimingModel(boneInfo_t &bone,int currentTime,int numFramesInFile,int ¤tFrame,int &newFrame,float &lerp) +{ + assert(bone.startFrame>=0); + assert(bone.startFrame<=numFramesInFile); + assert(bone.endFrame>=0); + assert(bone.endFrame<=numFramesInFile); + + // yes - add in animation speed to current frame + float animSpeed = bone.animSpeed; + float time; + if (bone.pauseTime) + { + time = (bone.pauseTime - bone.startTime) / 50.0f; + } + else + { + time = (currentTime - bone.startTime) / 50.0f; + } + if (time<0.0f) + { + time=0.0f; + } + float newFrame_g = bone.startFrame + (time * animSpeed); + + int animSize = bone.endFrame - bone.startFrame; + float endFrame = (float)bone.endFrame; + // we are supposed to be animating right? + if (animSize) + { + // did we run off the end? + if (((animSpeed > 0.0f) && (newFrame_g > endFrame - 1)) || + ((animSpeed < 0.0f) && (newFrame_g < endFrame + 1))) + { + // yep - decide what to do + if (bone.flags & BONE_ANIM_OVERRIDE_LOOP) + { + // get our new animation frame back within the bounds of the animation set + if (animSpeed < 0.0f) + { + // we don't use this case, or so I am told + // if we do, let me know, I need to insure the mod works + + // should we be creating a virtual frame? + if ((newFrame_g < endFrame + 1) && (newFrame_g > endFrame)) + { + // now figure out what we are lerping between + // delta is the fraction between this frame and the next, since the new anim is always at a .0f; + lerp = (newFrame_g - (int)newFrame_g); + // frames are easy to calculate + currentFrame = (int)newFrame_g; + assert(currentFrame>=0&¤tFrame=0&&newFrame=0&¤tFrame=0&&newFrame=0&&newFrame endFrame - 1) && (newFrame_g < endFrame)) + { + // now figure out what we are lerping between + // delta is the fraction between this frame and the next, since the new anim is always at a .0f; + lerp = (newFrame_g - (int)newFrame_g); + // frames are easy to calculate + currentFrame = (int)newFrame_g; + assert(currentFrame>=0&¤tFrame=0&&newFrame= endFrame) + { + newFrame_g=endFrame+fmod(newFrame_g-endFrame,animSize)-animSize; + } + // now figure out what we are lerping between + // delta is the fraction between this frame and the next, since the new anim is always at a .0f; + lerp = (newFrame_g - (int)newFrame_g); + // frames are easy to calculate + currentFrame = (int)newFrame_g; + assert(currentFrame>=0&¤tFrame= endFrame - 1) + { + newFrame = bone.startFrame; + assert(newFrame>=0&&newFrame=0&&newFrame= bone.startFrame) || (animSize < 10)); + } + else + { + if (((bone.flags & (BONE_ANIM_OVERRIDE_DEFAULT)) == (BONE_ANIM_OVERRIDE_DEFAULT))|| + ((bone.flags & (BONE_ANIM_OVERRIDE_FREEZE)) == (BONE_ANIM_OVERRIDE_FREEZE))) + { + // if we are supposed to reset the default anim, then do so + if (animSpeed > 0.0f) + { + currentFrame = bone.endFrame - 1; + assert(currentFrame>=0&¤tFrame=0&¤tFrame=0&&newFrame=0&¤tFrame 0.0) + { + newFrame = currentFrame + 1; + + // are we now on the end frame? + assert((int)endFrame<=numFramesInFile); + if (newFrame >= (int)endFrame) + { + // we only want to lerp with the first frame of the anim if we are looping + if (bone.flags & BONE_ANIM_OVERRIDE_LOOP) + { + newFrame = bone.startFrame; + assert(newFrame>=0&&newFrame=0&&newFrame=0&&newFrame=0&¤tFrame=0&&newFrame=0&&newFrame=0&&newFrame=0&¤tFrame=0&&newFrame=0&¤tFrame=0&&newFrame=0.0f&&lerp<=1.0f); +} + // transform each individual bone's information - making sure to use any override information provided, both for angles and for animations, as // well as multiplying each bone's matrix by it's parents matrix -void G2_TransformBone (CTransformBone &TB) +void G2_TransformBone (int child,CBoneCache &BC) { + SBoneCalc &TB=BC.mBones[child]; mdxaBone_t tbone[6]; + mdxaFrame_t *aFrame=0; + mdxaFrame_t *bFrame=0; + mdxaFrame_t *aoldFrame=0; + mdxaFrame_t *boldFrame=0; mdxaSkel_t *skel; mdxaSkelOffsets_t *offsets; - boneInfo_v &boneList = TB.rootBoneList; - int i, j, boneListIndex; + boneInfo_v &boneList = *BC.rootBoneList; + int j, boneListIndex; int angleOverride = 0; -#if G2_DEBUG_TIMING - bool doTiming=false; - float DanimS; - float Dtime; - int DstartFrame; - float DnewFrame; - int DstartTime; +#if DEBUG_G2_TIMING + bool printTiming=false; #endif - - // decide here if we should go down this path? - is this bone used? -If not, return from this function. Due the hierarchial nature of the bones - // any bone below this one in the tree shouldn't be used either. - if (!TB.usedBoneList[TB.child]) - { - return; - } - // should this bone be overridden by a bone in the bone list? - boneListIndex = G2_Find_Bone_In_List(boneList, TB.child); + boneListIndex = G2_Find_Bone_In_List(boneList, child); if (boneListIndex != -1) { - float animSpeed = boneList[boneListIndex].animSpeed; // we found a bone in the list - we need to override something here. // do we override the rotational angles? @@ -515,11 +742,11 @@ void G2_TransformBone (CTransformBone &TB) // set blending stuff if we need to if (boneList[boneListIndex].flags & (BONE_ANIM_BLEND | BONE_ANIM_BLEND_TO_PARENT)) { - float blendTime = (TB.incomingTime - boneList[boneListIndex].blendStart); + float blendTime = BC.incomingTime - boneList[boneListIndex].blendStart; // only set up the blend anim if we actually have some blend time left on this bone anim - otherwise we might corrupt some blend higher up the hiearchy if (blendTime>0.0f&&blendTime < boneList[boneListIndex].blendTime) { - TB.blendFrame = boneList[boneListIndex].blendFrame; + TB.blendFrame = boneList[boneListIndex].blendFrame; TB.blendOldFrame = boneList[boneListIndex].blendLerpFrame; TB.blendLerp = (blendTime / boneList[boneListIndex].blendTime); TB.blendMode = true; @@ -533,7 +760,7 @@ void G2_TransformBone (CTransformBone &TB) // are blending *from* the parent? If so, grab what the parent is set to, and stick it in the blendFrame info if (boneList[boneListIndex].flags & BONE_ANIM_BLEND_FROM_PARENT) { - float blendTime = (TB.incomingTime - boneList[boneListIndex].blendStart); + float blendTime = BC.incomingTime - boneList[boneListIndex].blendStart; // only set up the blend anim if we actually have some blend time left on this bone anim - otherwise we might corrupt some blend higher up the hiearchy if (blendTime>0.0f&&blendTime < boneList[boneListIndex].blendTime) { @@ -548,7 +775,8 @@ void G2_TransformBone (CTransformBone &TB) } } else - if ((boneList[boneListIndex].flags) & (BONE_ANIM_OVERRIDE_LOOP | BONE_ANIM_OVERRIDE)) + // turn off blending if we are just doing a straing animation override + if (r_Ghoul2NoBlend->integer||((boneList[boneListIndex].flags) & (BONE_ANIM_OVERRIDE_LOOP | BONE_ANIM_OVERRIDE))) { TB.blendMode = false; } @@ -556,241 +784,79 @@ void G2_TransformBone (CTransformBone &TB) // should this animation be overridden by an animation in the bone list? if ((boneList[boneListIndex].flags) & (BONE_ANIM_OVERRIDE_LOOP | BONE_ANIM_OVERRIDE)) { - // yes - add in animation speed to current frame - float time; - if (boneList[boneListIndex].pauseTime) - { - time = (boneList[boneListIndex].pauseTime - boneList[boneListIndex].startTime) / 50.0f; - } - else - { - time = (TB.incomingTime - boneList[boneListIndex].startTime) / 50.0f; - } - if (time<0.0f) - { - time=0.0f; - } - float newFrame_g = boneList[boneListIndex].startFrame + (time * animSpeed); -#if G2_DEBUG_TIMING - DanimS=animSpeed; - Dtime=time; - DstartFrame=boneList[boneListIndex].startFrame; - DnewFrame=newFrame_g; - DstartTime=boneList[boneListIndex].startTime; + G2_TimingModel(boneList[boneListIndex],BC.incomingTime,BC.header->numFrames,TB.currentFrame,TB.newFrame,TB.backlerp); + } +#if DEBUG_G2_TIMING + printTiming=true; #endif - float endFrame = (float)boneList[boneListIndex].endFrame ; - - int animSize = endFrame - boneList[boneListIndex].startFrame; - // we are supposed to be animating right? - if (animSize) - { - // did we run off the end? - if (((animSpeed > 0.0f) && (newFrame_g > endFrame - 1)) || - ((animSpeed < 0.0f) && (newFrame_g < endFrame + 1))) - { - // yep - decide what to do - if (boneList[boneListIndex].flags & BONE_ANIM_OVERRIDE_LOOP) - { - // get our new animation frame back within the bounds of the animation set - if (animSpeed < 0.0f) - { - // should we be creating a virtual frame? - if ((newFrame_g < endFrame + 1) && (newFrame_g > endFrame)) - { - // now figure out what we are lerping between - // delta is the fraction between this frame and the next, since the new anim is always at a .0f; - TB.backlerp = (newFrame_g - (int)newFrame_g); - // frames are easy to calculate - TB.currentFrame = (int)newFrame_g; - TB.newFrame = boneList[boneListIndex].startFrame; - } - else - { - // fixme: tempcode: this is to try and stop a lockup caused by bad logic. Need to know when this triggers!!!! - if (animSize>=0) - { - assert(animSize<0); - animSize = -animSize; - } - - while (newFrame_g <= endFrame) - { - newFrame_g -= animSize; - } - // now figure out what we are lerping between - // delta is the fraction between this frame and the next, since the new anim is always at a .0f; - TB.backlerp = (newFrame_g - (int)newFrame_g); - // frames are easy to calculate - TB.currentFrame = (int)newFrame_g; - // should we be creating a virtual frame? - if (newFrame_g <= endFrame + 1) - { - - TB.newFrame = boneList[boneListIndex].startFrame; - } - else - { - TB.newFrame = TB.currentFrame - 1; - } - } - } - else - { - // should we be creating a virtual frame? - if ((newFrame_g > endFrame - 1) && (newFrame_g < endFrame)) - { - // now figure out what we are lerping between - // delta is the fraction between this frame and the next, since the new anim is always at a .0f; - TB.backlerp = (newFrame_g - (int)newFrame_g); - // frames are easy to calculate - TB.currentFrame = (int)newFrame_g; - TB.newFrame = boneList[boneListIndex].startFrame; - } - else - { - // fixme: tempcode: this is to try and stop a lockup caused by bad logic. Need to know when this triggers!!!! - if (animSize<=0) - { - assert(animSize>0); - animSize = -animSize; - } - - while (newFrame_g >= endFrame) - { - newFrame_g -= animSize; - } - // now figure out what we are lerping between - // delta is the fraction between this frame and the next, since the new anim is always at a .0f; - TB.backlerp = (newFrame_g - (int)newFrame_g); - // frames are easy to calculate - TB.currentFrame = (int)newFrame_g; - // should we be creating a virtual frame? - if (newFrame_g >= endFrame - 1) - { - TB.newFrame = boneList[boneListIndex].startFrame; - } - else - { - TB.newFrame = TB.currentFrame + 1; - } - } - } - // sanity check - assert ((TB.newFrame < endFrame) && (TB.newFrame >= boneList[boneListIndex].startFrame) || (animSize < 10)); - } - else - { - if (((boneList[boneListIndex].flags & (BONE_ANIM_OVERRIDE_DEFAULT)) == (BONE_ANIM_OVERRIDE_DEFAULT))|| - ((boneList[boneListIndex].flags & (BONE_ANIM_OVERRIDE_FREEZE)) == (BONE_ANIM_OVERRIDE_FREEZE))) - { - // if we are supposed to reset the default anim, then do so - if (animSpeed > 0.0f) - { - TB.currentFrame = boneList[boneListIndex].endFrame - 1; - } - else - { - TB.currentFrame = boneList[boneListIndex].endFrame + 1; - } - - TB.newFrame = TB.currentFrame; - TB.backlerp = 0; - } - - // nope, just stop processing this bone. And do nothing - let the bone take the parents anim info - } - } - else - { - // figure out the difference between the two frames - we have to decide what frame and what percentage of that - // frame we want to display - TB.backlerp = (newFrame_g - (int)newFrame_g); - - // frames are easy to calculate - TB.currentFrame = (int)newFrame_g; - - if (animSpeed> 0.0) - { - TB.newFrame = TB.currentFrame + 1; - - // are we now on the end frame? - if (TB.newFrame > endFrame) - { - // we only want to lerp with the first frame of the anim if we are looping - if (boneList[boneListIndex].flags & BONE_ANIM_OVERRIDE_LOOP) - { - TB.newFrame = boneList[boneListIndex].startFrame; - } - // if we intend to end this anim or freeze after this, then just keep on the last frame - else - { - TB.newFrame = boneList[boneListIndex].endFrame; - } - } - } - else - { - TB.currentFrame++; - TB.newFrame = TB.currentFrame - 1; - - TB.backlerp = 1-TB.backlerp; - // are we now on the end frame? - if (TB.newFrame < endFrame) - { - // we only want to lerp with the first frame of the anim if we are looping - if (boneList[boneListIndex].flags & BONE_ANIM_OVERRIDE_LOOP) - { - TB.newFrame = boneList[boneListIndex].startFrame; - } - // if we intend to end this anim or freeze after this, then just keep on the last frame - else - { - TB.newFrame = boneList[boneListIndex].endFrame; - } - } - } - - // sanity check - //assert ((newFrame_g < endFrame) && (newFrame_g >= boneList[boneListIndex].startFrame)); - } - } - else - { - TB.currentFrame = boneList[boneListIndex].endFrame; - TB.newFrame = TB.currentFrame; - TB.backlerp = 0; - - } -#if G2_DEBUG_TIMING - doTiming=true; -#endif - } + if ((r_Ghoul2NoLerp->integer)||((boneList[boneListIndex].flags) & (BONE_ANIM_NO_LERP))) + { + TB.backlerp = 0.0f; + } } - -// const mdxaCompBone_t *compBonePointer = (mdxaCompBone_t *)((byte *)TB.header + TB.header->ofsCompBonePool); + // figure out where the location of the bone animation data is + assert(TB.newFrame>=0&&TB.newFramenumFrames); + if (!(TB.newFrame>=0&&TB.newFramenumFrames)) + { + TB.newFrame=0; + } + aFrame = (mdxaFrame_t *)((byte *)BC.header + BC.header->ofsFrames + TB.newFrame * BC.frameSize ); + assert(TB.currentFrame>=0&&TB.currentFramenumFrames); + if (!(TB.currentFrame>=0&&TB.currentFramenumFrames)) + { + TB.currentFrame=0; + } + aoldFrame = (mdxaFrame_t *)((byte *)BC.header + BC.header->ofsFrames + TB.currentFrame * BC.frameSize ); + + // figure out where the location of the blended animation data is + assert(!(TB.blendFrame < 0.0 || TB.blendFrame >= (BC.header->numFrames+1))); + if (TB.blendFrame < 0.0 || TB.blendFrame >= (BC.header->numFrames+1) ) + { + TB.blendFrame=0.0; + } + bFrame = (mdxaFrame_t *)((byte *)BC.header + BC.header->ofsFrames + (int)TB.blendFrame * BC.frameSize ); + assert(TB.blendOldFrame>=0&&TB.blendOldFramenumFrames); + if (!(TB.blendOldFrame>=0&&TB.blendOldFramenumFrames)) + { + TB.blendOldFrame=0; + } +#if DEBUG_G2_TIMING + if (printTiming) + { + char mess[1000]; + if (TB.blendMode) + { + sprintf(mess,"b %2d %5d %4d %4d %4d %4d %f %f\n",BC.mWraithID,BC.incomingTime,(int)TB.newFrame,(int)TB.currentFrame,(int)TB.blendFrame,(int)TB.blendOldFrame,TB.backlerp,TB.blendLerp); + } + else + { + sprintf(mess,"a %2d %5d %4d %4d %f\n",BC.mWraithID,BC.incomingTime,TB.newFrame,TB.currentFrame,TB.backlerp); + } + OutputDebugString(mess); + } +#endif + boldFrame = (mdxaFrame_t *)((byte *)BC.header + BC.header->ofsFrames + TB.blendOldFrame * BC.frameSize ); + +// mdxaCompBone_t *compBonePointer = (mdxaCompBone_t *)((byte *)BC.header + BC.header->ofsCompBonePool); + + assert(child>=0&&childnumBones); + assert(bFrame->boneIndexes[child]>=0); + assert(boldFrame->boneIndexes[child]>=0); + assert(aFrame->boneIndexes[child]>=0); + assert(aoldFrame->boneIndexes[child]>=0); + + // decide where the transformed bone is going // are we blending with another frame of anim? if (TB.blendMode) { - if ((int)TB.blendFrame >= TB.header->numFrames || (int)TB.blendFrame < 0 ) - { - assert (TB.header->numFrames > (int)TB.blendFrame);//validate the frame we're about to grab - return; - } - - if (TB.blendOldFrame >= TB.header->numFrames || TB.blendOldFrame < 0) - { - assert (TB.header->numFrames > TB.blendOldFrame);//validate the frame we're about to grab - return; - } - const mdxaFrame_t *bFrame = (mdxaFrame_t *)((byte *)TB.header + TB.header->ofsFrames + (int)TB.blendFrame * TB.frameSize ); - const mdxaFrame_t *boldFrame =(mdxaFrame_t *)((byte *)TB.header + TB.header->ofsFrames + TB.blendOldFrame * TB.frameSize ); - - UnCompressBone(tbone[3].matrix,bFrame->boneIndexes[TB.child], TB.header); - UnCompressBone(tbone[4].matrix,boldFrame->boneIndexes[TB.child], TB.header); - - const float backlerp = TB.blendFrame - (int)TB.blendFrame; - const float frontlerp = 1.0 - backlerp; + float backlerp = TB.blendFrame - (int)TB.blendFrame; + float frontlerp = 1.0 - backlerp; + +// MC_UnCompress(tbone[3].matrix,compBonePointer[bFrame->boneIndexes[child]].Comp); +// MC_UnCompress(tbone[4].matrix,compBonePointer[boldFrame->boneIndexes[child]].Comp); + UnCompressBone(tbone[3].matrix,bFrame->boneIndexes[child], BC.header); + UnCompressBone(tbone[4].matrix,boldFrame->boneIndexes[child], BC.header); for ( j = 0 ; j < 12 ; j++ ) { @@ -798,41 +864,14 @@ void G2_TransformBone (CTransformBone &TB) + (frontlerp * ((float *)&tbone[4])[j]); } } -#if G2_DEBUG_TIMING - if (doTiming) - { - Com_Printf("rfTime=%7d TBtime=%7d\n",tr.refdef.time,TB.incomingTime); - Com_Printf("speed=%4.2f time=%4.2f sframe=%5d newFrame=%7.2f stTime=%7d\n", - DanimS,Dtime,DstartFrame,DnewFrame,DstartTime); - if (TB.blendMode) - { - Com_Printf("blend %d %5d %5d %5d %5d %3.2f %3.2f %3.2f\n",tr.refdef.time,TB.currentFrame,TB.newFrame,(int)TB.blendFrame,TB.blendOldFrame,TB.backlerp,float(TB.blendFrame - (int)TB.blendFrame),TB.blendLerp); - } - else - { - Com_Printf("norm %d %5d %5d %3.2f\n",tr.refdef.time,TB.currentFrame,TB.newFrame,TB.backlerp); - } - } -#endif - - // figure out where the location of the bone animation data is - if (TB.currentFrame >= TB.header->numFrames ) - { - assert (TB.header->numFrames > TB.currentFrame);//validate the frame we're about to grab - return; - } - const mdxaFrame_t *aoldFrame = (mdxaFrame_t *)((byte *)TB.header + TB.header->ofsFrames + TB.currentFrame * TB.frameSize ); - - // figure out where the bone hirearchy info is - offsets = (mdxaSkelOffsets_t *)((byte *)TB.header + sizeof(mdxaHeader_t)); - skel = (mdxaSkel_t *)((byte *)TB.header + sizeof(mdxaHeader_t) + offsets->offsets[TB.child]); + // // lerp this bone - use the temp space on the ref entity to put the bone transforms into // if (!TB.backlerp) { -// MC_UnCompress(tbone[2].matrix,compBonePointer[aoldFrame->boneIndexes[TB.child]].Comp); - UnCompressBone(tbone[2].matrix,aoldFrame->boneIndexes[TB.child], TB.header); +// MC_UnCompress(tbone[2].matrix,compBonePointer[aoldFrame->boneIndexes[child]].Comp); + UnCompressBone(tbone[2].matrix,aoldFrame->boneIndexes[child], BC.header); // blend in the other frame if we need to if (TB.blendMode) @@ -845,28 +884,20 @@ void G2_TransformBone (CTransformBone &TB) } } - if (TB.rootBone) + if (!child) { // now multiply by the root matrix, so we can offset this model should we need to - Multiply_3x4Matrix(&TB.bonePtr[TB.child], &TB.rootMatrix, &tbone[2]); + Multiply_3x4Matrix(&BC.mFinalBones[child].boneMatrix, &BC.rootMatrix, &tbone[2]); } } else { - if (TB.newFrame >= TB.header->numFrames ) - { - assert (TB.header->numFrames > TB.newFrame);//validate the frame we're about to grab - return; - } - // figure out where the location of the bone animation data is - const mdxaFrame_t *aFrame = (mdxaFrame_t *)((byte *)TB.header + TB.header->ofsFrames + TB.newFrame * TB.frameSize ); + float frontlerp = 1.0 - TB.backlerp; +// MC_UnCompress(tbone[0].matrix,compBonePointer[aFrame->boneIndexes[child]].Comp); +// MC_UnCompress(tbone[1].matrix,compBonePointer[aoldFrame->boneIndexes[child]].Comp); + UnCompressBone(tbone[0].matrix,aFrame->boneIndexes[child], BC.header); + UnCompressBone(tbone[1].matrix,aoldFrame->boneIndexes[child], BC.header); -// MC_UnCompress(tbone[0].matrix,compBonePointer[aFrame->boneIndexes[TB.child]].Comp); -// MC_UnCompress(tbone[1].matrix,compBonePointer[aoldFrame->boneIndexes[TB.child]].Comp); - UnCompressBone(tbone[0].matrix,aFrame->boneIndexes[TB.child], TB.header); - UnCompressBone(tbone[1].matrix,aoldFrame->boneIndexes[TB.child], TB.header); - - const float frontlerp = 1.0 - TB.backlerp; for ( j = 0 ; j < 12 ; j++ ) { ((float *)&tbone[2])[j] = (TB.backlerp * ((float *)&tbone[0])[j]) @@ -876,77 +907,41 @@ void G2_TransformBone (CTransformBone &TB) // blend in the other frame if we need to if (TB.blendMode) { -#if 0 - vec4_t quat; - mdxaBone_t inverseStart; - mdxaBone_t rotation, scaledRotation; - mdxaBone_t startMatrix, endMatrix; - - // tbone[5] contains the start from where we are blending from - put this in model space - Multiply_3x4Matrix(&startMatrix, &tbone[5], &skel->BasePoseMat); - - // tbone[2] contains the current animation, where are blending to - put this in model space - Multiply_3x4Matrix(&endMatrix, &tbone[2], &skel->BasePoseMat); - - // create inverse of start matrix - Inverse_Matrix(&startMatrix, &inverseStart); - - // generate rotation matrix from start to finish - Multiply_3x4Matrix(&rotation, &endMatrix, &inverseStart); - - // create a quaterion out of this matrix - G2_CreateQuaterion(&rotation, quat); - - // scale it appropriately by lerp - quat[3] *= TB.blendLerp; - - // go back and create a new rotation matrix from this scaled quaterion - G2_CreateMatrixFromQuaterion(&scaledRotation, quat); - - scaledRotation.matrix[0][3] = rotation.matrix[0][3]; - scaledRotation.matrix[1][3] = rotation.matrix[1][3]; - scaledRotation.matrix[2][3] = rotation.matrix[2][3]; - - // we should have a rotation matrix now in model space, put it back into bone space - Multiply_3x4Matrix(&endMatrix, &scaledRotation, &skel->BasePoseMatInv ); - - // multiply that by the original start to get result. - Multiply_3x4Matrix(&tbone[2], &endMatrix, &tbone[5]); - -#else - const float blendFrontlerp = 1.0 - TB.blendLerp; + float blendFrontlerp = 1.0 - TB.blendLerp; for ( j = 0 ; j < 12 ; j++ ) { - ((float *)&tbone[2])[j] = (TB.blendLerp * ((float *)&tbone[2])[j]) + ((float *)&tbone[2])[j] = (TB.blendLerp * ((float *)&tbone[2])[j]) + (blendFrontlerp * ((float *)&tbone[5])[j]); } -#endif } - if (TB.rootBone) + if (!child) { // now multiply by the root matrix, so we can offset this model should we need to - Multiply_3x4Matrix(&TB.bonePtr[TB.child], &TB.rootMatrix, &tbone[2]); + Multiply_3x4Matrix(&BC.mFinalBones[child].boneMatrix, &BC.rootMatrix, &tbone[2]); } } -#if 1 - boneInfo_t &boneOverride = boneList[boneListIndex]; - mdxaBone_t *newMatrix =&boneOverride.newMatrix; - mdxaBone_t tempNewMatrix; + // figure out where the bone hirearchy info is + offsets = (mdxaSkelOffsets_t *)((byte *)BC.header + sizeof(mdxaHeader_t)); + skel = (mdxaSkel_t *)((byte *)BC.header + sizeof(mdxaHeader_t) + offsets->offsets[child]); + int parent=BC.mFinalBones[child].parent; + assert((parent==-1&&child==0)||(parent>=0&&parentBasePoseMat); - const float matrixScale = VectorLength((float*)&temp); - - newMatrix=&tempNewMatrix; - for (int i=0; i<3;i++) - { - for(int x=0;x<3; x++) - { - tempNewMatrix.matrix[i][x]=boneOverride.newMatrix.matrix[i][x] * matrixScale; - } - } + float matrixScale = VectorLength((float*)&temp); - tempNewMatrix.matrix[0][3] = temp.matrix[0][3]; - tempNewMatrix.matrix[1][3] = temp.matrix[1][3]; - tempNewMatrix.matrix[2][3] = temp.matrix[2][3]; + mdxaBone_t newMatrixTemp; + + if (HackadelicOnClient) + { + for (int i=0; i<3;i++) + { + for(int x=0;x<3; x++) + { + newMatrixTemp.matrix[i][x] = boneOverride.newMatrix.matrix[i][x]*matrixScale; + } + } + + newMatrixTemp.matrix[0][3] = temp.matrix[0][3]; + newMatrixTemp.matrix[1][3] = temp.matrix[1][3]; + newMatrixTemp.matrix[2][3] = temp.matrix[2][3]; + } + else + { + for (int i=0; i<3;i++) + { + for(int x=0;x<3; x++) + { + newMatrixTemp.matrix[i][x] = boneOverride.matrix.matrix[i][x]*matrixScale; + } + } + + newMatrixTemp.matrix[0][3] = temp.matrix[0][3]; + newMatrixTemp.matrix[1][3] = temp.matrix[1][3]; + newMatrixTemp.matrix[2][3] = temp.matrix[2][3]; + } - Multiply_3x4Matrix(&temp, &tempNewMatrix,&skel->BasePoseMatInv); + Multiply_3x4Matrix(&temp, &newMatrixTemp,&skel->BasePoseMatInv); // now do the blend into the destination - const float blendFrontlerp = 1.0 - blendLerp; + float blendFrontlerp = 1.0 - blendLerp; for ( j = 0 ; j < 12 ; j++ ) { ((float *)&bone)[j] = (blendLerp * ((float *)&temp)[j]) @@ -997,59 +1010,95 @@ void G2_TransformBone (CTransformBone &TB) else { - Multiply_3x4Matrix(&temp, &firstPass, &skel->BasePoseMat); - const float matrixScale = VectorLength((float*)&temp); - - newMatrix=&tempNewMatrix; - for (int i=0; i<3;i++) - { - for(int x=0;x<3; x++) - { - tempNewMatrix.matrix[i][x]=boneOverride.newMatrix.matrix[i][x] * matrixScale; - } - } + Multiply_3x4Matrix(&temp,&firstPass, &skel->BasePoseMat); + float matrixScale = VectorLength((float*)&temp); - tempNewMatrix.matrix[0][3] = temp.matrix[0][3]; - tempNewMatrix.matrix[1][3] = temp.matrix[1][3]; - tempNewMatrix.matrix[2][3] = temp.matrix[2][3]; + mdxaBone_t newMatrixTemp; + + if (HackadelicOnClient) + { + for (int i=0; i<3;i++) + { + for(int x=0;x<3; x++) + { + newMatrixTemp.matrix[i][x] = boneOverride.newMatrix.matrix[i][x]*matrixScale; + } + } + + newMatrixTemp.matrix[0][3] = temp.matrix[0][3]; + newMatrixTemp.matrix[1][3] = temp.matrix[1][3]; + newMatrixTemp.matrix[2][3] = temp.matrix[2][3]; + } + else + { + for (int i=0; i<3;i++) + { + for(int x=0;x<3; x++) + { + newMatrixTemp.matrix[i][x] = boneOverride.matrix.matrix[i][x]*matrixScale; + } + } + + newMatrixTemp.matrix[0][3] = temp.matrix[0][3]; + newMatrixTemp.matrix[1][3] = temp.matrix[1][3]; + newMatrixTemp.matrix[2][3] = temp.matrix[2][3]; + } - Multiply_3x4Matrix(&temp, &tempNewMatrix,&skel->BasePoseMatInv); + Multiply_3x4Matrix(&bone, &newMatrixTemp,&skel->BasePoseMatInv); } } - else - if (angleOverride & BONE_ANGLES_PREMULT) + else if (angleOverride & BONE_ANGLES_PREMULT) { - if (TB.rootBone) + if (!child) { // use the in coming root matrix as our basis - Multiply_3x4Matrix(&TB.bonePtr[TB.child], &TB.rootMatrix,newMatrix); + if (HackadelicOnClient) + { + Multiply_3x4Matrix(&BC.mFinalBones[child].boneMatrix, &BC.rootMatrix, &boneList[boneListIndex].newMatrix); + } + else + { + Multiply_3x4Matrix(&BC.mFinalBones[child].boneMatrix, &BC.rootMatrix, &boneList[boneListIndex].matrix); + } } else { // convert from 3x4 matrix to a 4x4 matrix - Multiply_3x4Matrix(&TB.bonePtr[TB.child], &TB.bonePtr[TB.parent],newMatrix); + if (HackadelicOnClient) + { + Multiply_3x4Matrix(&BC.mFinalBones[child].boneMatrix, &BC.mFinalBones[parent].boneMatrix, &boneList[boneListIndex].newMatrix); + } + else + { + Multiply_3x4Matrix(&BC.mFinalBones[child].boneMatrix, &BC.mFinalBones[parent].boneMatrix, &boneList[boneListIndex].matrix); + } } } else -#endif - // now transform the matrix by it's TB.parent, asumming we have a TB.parent, and we aren't overriding the angles absolutely - if (!TB.rootBone) + // now transform the matrix by it's parent, asumming we have a parent, and we aren't overriding the angles absolutely + if (child) { - Multiply_3x4Matrix(&TB.bonePtr[TB.child], &TB.bonePtr[TB.parent], &tbone[2]); + Multiply_3x4Matrix(&BC.mFinalBones[child].boneMatrix, &BC.mFinalBones[parent].boneMatrix, &tbone[2]); } -#if 1 + // now multiply our resulting bone by an override matrix should we need to if (angleOverride & BONE_ANGLES_POSTMULT) { mdxaBone_t tempMatrix; - memcpy (&tempMatrix, &TB.bonePtr[TB.child], sizeof(mdxaBone_t)); - Multiply_3x4Matrix(&TB.bonePtr[TB.child], &tempMatrix,newMatrix); + memcpy (&tempMatrix,&BC.mFinalBones[child].boneMatrix, sizeof(mdxaBone_t)); + if (HackadelicOnClient) + { + Multiply_3x4Matrix(&BC.mFinalBones[child].boneMatrix, &tempMatrix, &boneList[boneListIndex].newMatrix); + } + else + { + Multiply_3x4Matrix(&BC.mFinalBones[child].boneMatrix, &tempMatrix, &boneList[boneListIndex].matrix); + } } - if (r_Ghoul2UnSqash->integer) { mdxaBone_t tempMatrix; - Multiply_3x4Matrix(&tempMatrix, &TB.bonePtr[TB.child], &skel->BasePoseMat); + Multiply_3x4Matrix(&tempMatrix,&BC.mFinalBones[child].boneMatrix, &skel->BasePoseMat); float maxl; maxl=VectorLength(&skel->BasePoseMat.matrix[0][0]); VectorNormalize(&tempMatrix.matrix[0][0]); @@ -1059,94 +1108,78 @@ void G2_TransformBone (CTransformBone &TB) VectorScale(&tempMatrix.matrix[0][0],maxl,&tempMatrix.matrix[0][0]); VectorScale(&tempMatrix.matrix[1][0],maxl,&tempMatrix.matrix[1][0]); VectorScale(&tempMatrix.matrix[2][0],maxl,&tempMatrix.matrix[2][0]); - Multiply_3x4Matrix(&TB.bonePtr[TB.child],&tempMatrix,&skel->BasePoseMatInv); - } -#endif - - // are the bone that we are resetting to the origin? - if (TB.child == TB.boltNum) - { - //create a world matrix for the new origin - mdxaBone_t tempMatrix; - Multiply_3x4Matrix(&tempMatrix, &TB.bonePtr[TB.child], &skel->BasePoseMat); - TB.newModelOrigin[0] = tempMatrix.matrix[0][3]; - TB.newModelOrigin[1] = tempMatrix.matrix[1][3]; - TB.newModelOrigin[2] = tempMatrix.matrix[2][3]; + Multiply_3x4Matrix(&BC.mFinalBones[child].boneMatrix,&tempMatrix,&skel->BasePoseMatInv); } - TB.rootBone = false; - const int parent = TB.child; - const int newFrame = TB.newFrame; - const int currentFrame = TB.currentFrame; - const float backLerp = TB.backlerp; - const bool blendMode = TB.blendMode; - const float blendFrame = TB.blendFrame; - const int blendOldFrame = TB.blendOldFrame; - const float blendLerp = TB.blendLerp; - // now work out what children we have to call this recursively for - for (i=0; i< skel->numChildren; i++) - { - TB.newFrame = newFrame; - TB.currentFrame = currentFrame; - TB.backlerp = backLerp; - TB.parent = parent; - TB.child = skel->children[i]; - TB.blendFrame = blendFrame; - TB.blendOldFrame = blendOldFrame; - TB.blendMode = blendMode; - TB.blendLerp = blendLerp; - G2_TransformBone(TB); - } } -void G2_SetUpBolts( const mdxaHeader_t *header, CGhoul2Info &ghoul2, mdxaBone_v &bonePtr, boltInfo_v &boltList, int *usedBoneList) -{ - mdxaSkel_t *skel; - mdxaSkelOffsets_t *offsets; - offsets = (mdxaSkelOffsets_t *)((byte *)header + sizeof(mdxaHeader_t)); - - for (int i=0; ioffsets[boltList[i].boneNumber]); - Multiply_3x4Matrix(&boltList[i].position, &bonePtr[boltList[i].boneNumber], &skel->BasePoseMat); - } - } - } -} // start the recursive hirearchial bone transform and lerp process for this model -static void G2_TransformGhoulBones( const mdxaHeader_t *header, int *usedBoneList, - mdxaBone_t &rootMatrix, CGhoul2Info &ghoul2, int time, int boneCount) +void G2_TransformGhoulBones(void *mod,const mdxaHeader_t *header, boneInfo_v &rootBoneList, + mdxaBone_t &rootMatrix, CGhoul2Info &ghoul2, int time) { - int frameSize, i; - int rootBoneIndex = 0; - - frameSize = (int)( &((mdxaFrame_t *)0)->boneIndexes[ header->numBones ] ); - - // figure out where our rootbone is - for (i=0; inumBones) { - if (usedBoneList[i]) + assert(0); // this would be strange + return; + } + if (!ghoul2.mBoneCache) + { + ghoul2.mBoneCache=new CBoneCache(mod,header); + } + ghoul2.mBoneCache->mod=mod; + assert(ghoul2.mBoneCache->mBones.size()==header->numBones); + + ghoul2.mBoneCache->mSmoothingActive=false; + ghoul2.mBoneCache->mUnsquash=false; + if (HackadelicOnClient) + { + ghoul2.mBoneCache->mLastTouch=ghoul2.mBoneCache->mLastLastTouch; + + // master smoothing control + float val=r_Ghoul2AnimSmooth->value; + if (val>0.0f&&val<1.0f) { - rootBoneIndex = i; - break; + float dif=float(time)-float(ghoul2.mBoneCache->mLastTime); + if (dif<16.6f) // 60 fps + { + dif=16.6f; + } + if (dif>100.0f) // 10 fps + { + dif=100.0f; + } + ghoul2.mBoneCache->mSmoothFactor=1.0f-pow(1.0f-val,50.0f/dif); + ghoul2.mBoneCache->mSmoothingActive=true; + if (r_Ghoul2UnSqashAfterSmooth->integer) + { + ghoul2.mBoneCache->mUnsquash=true; + } } } + ghoul2.mBoneCache->mCurrentTouch++; + if (HackadelicOnClient) + { + ghoul2.mBoneCache->mLastLastTouch=ghoul2.mBoneCache->mCurrentTouch; + } + assert(ghoul2.mBoneCache->header==header); + assert(ghoul2.mBoneCache->mod==mod); + ghoul2.mBoneCache->mWraithID=0; + ghoul2.mBoneCache->frameSize = (int)( &((mdxaFrame_t *)0)->boneIndexes[ header->numBones ] ); - time-=r_Ghoul2Test->integer; - // now recursively call the bone transform routines using the bone hirearchy - CTransformBone TB(ghoul2.mAnimFrameDefault, ghoul2.mAnimFrameDefault, 0, rootBoneIndex, frameSize, header, 0.0f, usedBoneList, - ghoul2.mBlist, ghoul2.mTempBoneList, ghoul2.mBltlist, rootMatrix, true, time, 0, 0, false, 0, ghoul2.mNewOrigin); + ghoul2.mBoneCache->rootBoneList=&rootBoneList; + ghoul2.mBoneCache->rootMatrix=rootMatrix; + ghoul2.mBoneCache->incomingTime=time; - G2_TransformBone (TB); - // now set up the bolt positions for those bolts required. - G2_SetUpBolts(header, ghoul2, ghoul2.mTempBoneList, ghoul2.mBltlist, usedBoneList); + SBoneCalc &TB=ghoul2.mBoneCache->Root(); + TB.newFrame=ghoul2.mAnimFrameDefault; + TB.currentFrame=ghoul2.mAnimFrameDefault; + TB.backlerp=0.0f; + TB.blendFrame=0; + TB.blendOldFrame=0; + TB.blendMode=false; + TB.blendLerp=0; } @@ -1159,7 +1192,7 @@ static void G2_TransformGhoulBones( const mdxaHeader_t *header, int *usedBoneLis // We've come across a surface that's designated as a bolt surface, process it and put it in the appropriate bolt place -void G2_ProcessSurfaceBolt(const mdxaBone_v &bonePtr, const mdxmSurface_t *surface, int boltNum, boltInfo_v &boltList, const surfaceInfo_t *surfInfo, const model_t *mod) +void G2_ProcessSurfaceBolt2(CBoneCache &boneCache, const mdxmSurface_t *surface, int boltNum, boltInfo_v &boltList, const surfaceInfo_t *surfInfo, const model_t *mod,mdxaBone_t &retMatrix) { mdxmVertex_t *v, *vert0, *vert1, *vert2; vec3_t axes[3], sides[3]; @@ -1202,32 +1235,35 @@ void G2_ProcessSurfaceBolt(const mdxaBone_v &bonePtr, const mdxmSurface_t *surfa VectorClear( pTri[0] ); VectorClear( pTri[1] ); VectorClear( pTri[2] ); + int *piBoneReferences = (int*) ((byte*)originalSurf + originalSurf->ofsBoneReferences); mdxmWeight_t *w; - int *piBoneRefs = (int*) ((byte*)originalSurf + originalSurf->ofsBoneReferences); // now go and transform just the points we need from the surface that was hit originally w = vert0->weights; for ( k = 0 ; k < vert0->numWeights ; k++, w++ ) { - pTri[0][0] += w->boneWeight * ( DotProduct( bonePtr[piBoneRefs[w->boneIndex]].matrix[0], vert0->vertCoords ) + bonePtr[piBoneRefs[w->boneIndex]].matrix[0][3] ); - pTri[0][1] += w->boneWeight * ( DotProduct( bonePtr[piBoneRefs[w->boneIndex]].matrix[1], vert0->vertCoords ) + bonePtr[piBoneRefs[w->boneIndex]].matrix[1][3] ); - pTri[0][2] += w->boneWeight * ( DotProduct( bonePtr[piBoneRefs[w->boneIndex]].matrix[2], vert0->vertCoords ) + bonePtr[piBoneRefs[w->boneIndex]].matrix[2][3] ); + const mdxaBone_t &bone=boneCache.Eval(piBoneReferences[w->boneIndex]); + pTri[0][0] += w->boneWeight * ( DotProduct( bone.matrix[0], vert0->vertCoords ) + bone.matrix[0][3] ); + pTri[0][1] += w->boneWeight * ( DotProduct( bone.matrix[1], vert0->vertCoords ) + bone.matrix[1][3] ); + pTri[0][2] += w->boneWeight * ( DotProduct( bone.matrix[2], vert0->vertCoords ) + bone.matrix[2][3] ); } w = vert1->weights; for ( k = 0 ; k < vert1->numWeights ; k++, w++ ) { - pTri[1][0] += w->boneWeight * ( DotProduct( bonePtr[piBoneRefs[w->boneIndex]].matrix[0], vert1->vertCoords ) + bonePtr[piBoneRefs[w->boneIndex]].matrix[0][3] ); - pTri[1][1] += w->boneWeight * ( DotProduct( bonePtr[piBoneRefs[w->boneIndex]].matrix[1], vert1->vertCoords ) + bonePtr[piBoneRefs[w->boneIndex]].matrix[1][3] ); - pTri[1][2] += w->boneWeight * ( DotProduct( bonePtr[piBoneRefs[w->boneIndex]].matrix[2], vert1->vertCoords ) + bonePtr[piBoneRefs[w->boneIndex]].matrix[2][3] ); + const mdxaBone_t &bone=boneCache.Eval(piBoneReferences[w->boneIndex]); + pTri[1][0] += w->boneWeight * ( DotProduct( bone.matrix[0], vert1->vertCoords ) + bone.matrix[0][3] ); + pTri[1][1] += w->boneWeight * ( DotProduct( bone.matrix[1], vert1->vertCoords ) + bone.matrix[1][3] ); + pTri[1][2] += w->boneWeight * ( DotProduct( bone.matrix[2], vert1->vertCoords ) + bone.matrix[2][3] ); } w = vert2->weights; for ( k = 0 ; k < vert2->numWeights ; k++, w++ ) { - pTri[2][0] += w->boneWeight * ( DotProduct( bonePtr[piBoneRefs[w->boneIndex]].matrix[0], vert2->vertCoords ) + bonePtr[piBoneRefs[w->boneIndex]].matrix[0][3] ); - pTri[2][1] += w->boneWeight * ( DotProduct( bonePtr[piBoneRefs[w->boneIndex]].matrix[1], vert2->vertCoords ) + bonePtr[piBoneRefs[w->boneIndex]].matrix[1][3] ); - pTri[2][2] += w->boneWeight * ( DotProduct( bonePtr[piBoneRefs[w->boneIndex]].matrix[2], vert2->vertCoords ) + bonePtr[piBoneRefs[w->boneIndex]].matrix[2][3] ); + const mdxaBone_t &bone=boneCache.Eval(piBoneReferences[w->boneIndex]); + pTri[2][0] += w->boneWeight * ( DotProduct( bone.matrix[0], vert2->vertCoords ) + bone.matrix[0][3] ); + pTri[2][1] += w->boneWeight * ( DotProduct( bone.matrix[1], vert2->vertCoords ) + bone.matrix[1][3] ); + pTri[2][2] += w->boneWeight * ( DotProduct( bone.matrix[2], vert2->vertCoords ) + bone.matrix[2][3] ); } vec3_t normal; @@ -1238,9 +1274,9 @@ void G2_ProcessSurfaceBolt(const mdxaBone_v &bonePtr, const mdxmSurface_t *surfa float baryCentricK = 1.0 - (surfInfo->genBarycentricI + surfInfo->genBarycentricJ); // now we have the model transformed into model space, now generate an origin. - boltList[boltNum].position.matrix[0][3] = (pTri[0][0] * surfInfo->genBarycentricI) + (pTri[1][0] * surfInfo->genBarycentricJ) + (pTri[2][0] * baryCentricK); - boltList[boltNum].position.matrix[1][3] = (pTri[0][1] * surfInfo->genBarycentricI) + (pTri[1][1] * surfInfo->genBarycentricJ) + (pTri[2][1] * baryCentricK); - boltList[boltNum].position.matrix[2][3] = (pTri[0][2] * surfInfo->genBarycentricI) + (pTri[1][2] * surfInfo->genBarycentricJ) + (pTri[2][2] * baryCentricK); + retMatrix.matrix[0][3] = (pTri[0][0] * surfInfo->genBarycentricI) + (pTri[1][0] * surfInfo->genBarycentricJ) + (pTri[2][0] * baryCentricK); + retMatrix.matrix[1][3] = (pTri[0][1] * surfInfo->genBarycentricI) + (pTri[1][1] * surfInfo->genBarycentricJ) + (pTri[2][1] * baryCentricK); + retMatrix.matrix[2][3] = (pTri[0][2] * surfInfo->genBarycentricI) + (pTri[1][2] * surfInfo->genBarycentricJ) + (pTri[2][2] * baryCentricK); // generate a normal to this new triangle VectorSubtract(pTri[0], pTri[1], vec0); @@ -1250,41 +1286,40 @@ void G2_ProcessSurfaceBolt(const mdxaBone_v &bonePtr, const mdxmSurface_t *surfa VectorNormalize(normal); // forward vector - boltList[boltNum].position.matrix[0][0] = normal[0]; - boltList[boltNum].position.matrix[1][0] = normal[1]; - boltList[boltNum].position.matrix[2][0] = normal[2]; + retMatrix.matrix[0][0] = normal[0]; + retMatrix.matrix[1][0] = normal[1]; + retMatrix.matrix[2][0] = normal[2]; // up will be towards point 0 of the original triangle. // so lets work it out. Vector is hit point - point 0 - up[0] = boltList[boltNum].position.matrix[0][3] - pTri[0][0]; - up[1] = boltList[boltNum].position.matrix[1][3] - pTri[0][1]; - up[2] = boltList[boltNum].position.matrix[2][3] - pTri[0][2]; + up[0] = retMatrix.matrix[0][3] - pTri[0][0]; + up[1] = retMatrix.matrix[1][3] - pTri[0][1]; + up[2] = retMatrix.matrix[2][3] - pTri[0][2]; // normalise it VectorNormalize(up); // that's the up vector - boltList[boltNum].position.matrix[0][1] = up[0]; - boltList[boltNum].position.matrix[1][1] = up[1]; - boltList[boltNum].position.matrix[2][1] = up[2]; + retMatrix.matrix[0][1] = up[0]; + retMatrix.matrix[1][1] = up[1]; + retMatrix.matrix[2][1] = up[2]; // right is always straight CrossProduct( normal, up, right ); // that's the up vector - boltList[boltNum].position.matrix[0][2] = right[0]; - boltList[boltNum].position.matrix[1][2] = right[1]; - boltList[boltNum].position.matrix[2][2] = right[2]; + retMatrix.matrix[0][2] = right[0]; + retMatrix.matrix[1][2] = right[1]; + retMatrix.matrix[2][2] = right[2]; } // no, we are looking at a normal model tag else { - int *piBoneRefs = (int*) ((byte*)surface + surface->ofsBoneReferences); - // whip through and actually transform each vertex v = (mdxmVertex_t *) ((byte *)surface + surface->ofsVerts); + int *piBoneReferences = (int*) ((byte*)surface + surface->ofsBoneReferences); for ( j = 0; j < 3; j++ ) { mdxmWeight_t *w; @@ -1293,11 +1328,11 @@ void G2_ProcessSurfaceBolt(const mdxaBone_v &bonePtr, const mdxmSurface_t *surfa w = v->weights; for ( k = 0 ; k < v->numWeights ; k++, w++ ) { - //bone = bonePtr + piBoneRefs[w->boneIndex]; + const mdxaBone_t &bone=boneCache.Eval(piBoneReferences[w->boneIndex]); - pTri[j][0] += w->boneWeight * ( DotProduct( bonePtr[piBoneRefs[w->boneIndex]].matrix[0], v->vertCoords ) + bonePtr[piBoneRefs[w->boneIndex]].matrix[0][3] ); - pTri[j][1] += w->boneWeight * ( DotProduct( bonePtr[piBoneRefs[w->boneIndex]].matrix[1], v->vertCoords ) + bonePtr[piBoneRefs[w->boneIndex]].matrix[1][3] ); - pTri[j][2] += w->boneWeight * ( DotProduct( bonePtr[piBoneRefs[w->boneIndex]].matrix[2], v->vertCoords ) + bonePtr[piBoneRefs[w->boneIndex]].matrix[2][3] ); + pTri[j][0] += w->boneWeight * ( DotProduct( bone.matrix[0], v->vertCoords ) + bone.matrix[0][3] ); + pTri[j][1] += w->boneWeight * ( DotProduct( bone.matrix[1], v->vertCoords ) + bone.matrix[1][3] ); + pTri[j][2] += w->boneWeight * ( DotProduct( bone.matrix[2], v->vertCoords ) + bone.matrix[2][3] ); } v = (mdxmVertex_t *)&v->weights[/*v->numWeights*/surface->maxVertBoneWeights]; @@ -1328,47 +1363,98 @@ void G2_ProcessSurfaceBolt(const mdxaBone_v &bonePtr, const mdxmSurface_t *surfa VectorNormalize2( axes[2], axes[2] ); // set up location in world space of the origin point in out going matrix - boltList[boltNum].position.matrix[0][3] = pTri[MDX_TAG_ORIGIN][0]; - boltList[boltNum].position.matrix[1][3] = pTri[MDX_TAG_ORIGIN][1]; - boltList[boltNum].position.matrix[2][3] = pTri[MDX_TAG_ORIGIN][2]; + retMatrix.matrix[0][3] = pTri[MDX_TAG_ORIGIN][0]; + retMatrix.matrix[1][3] = pTri[MDX_TAG_ORIGIN][1]; + retMatrix.matrix[2][3] = pTri[MDX_TAG_ORIGIN][2]; // copy axis to matrix - do some magic to orient minus Y to positive X and so on so bolt on stuff is oriented correctly - boltList[boltNum].position.matrix[0][0] = axes[1][0]; - boltList[boltNum].position.matrix[0][1] = axes[0][0]; - boltList[boltNum].position.matrix[0][2] = -axes[2][0]; + retMatrix.matrix[0][0] = axes[1][0]; + retMatrix.matrix[0][1] = axes[0][0]; + retMatrix.matrix[0][2] = -axes[2][0]; - boltList[boltNum].position.matrix[1][0] = axes[1][1]; - boltList[boltNum].position.matrix[1][1] = axes[0][1]; - boltList[boltNum].position.matrix[1][2] = -axes[2][1]; + retMatrix.matrix[1][0] = axes[1][1]; + retMatrix.matrix[1][1] = axes[0][1]; + retMatrix.matrix[1][2] = -axes[2][1]; - boltList[boltNum].position.matrix[2][0] = axes[1][2]; - boltList[boltNum].position.matrix[2][1] = axes[0][2]; - boltList[boltNum].position.matrix[2][2] = -axes[2][2]; + retMatrix.matrix[2][0] = axes[1][2]; + retMatrix.matrix[2][1] = axes[0][2]; + retMatrix.matrix[2][2] = -axes[2][2]; } } - -// now go through all the generated surfaces that aren't included in the model surface hierarchy and create the correct bolt info for them -void G2_ProcessGeneratedSurfaceBolts(CGhoul2Info &ghoul2, mdxaBone_v &bonePtr, const model_t *mod_t) + +void G2_GetBoltMatrixLow(CGhoul2Info &ghoul2,int boltNum,const vec3_t scale,mdxaBone_t &retMatrix) { - // look through the surfaces off the end of the pre-defined model surfaces - for (int i=0; i< ghoul2.mSlist.size(); i++) + if (!ghoul2.mBoneCache) { - // only look for bolts if we are actually a generated surface, and not just an overriden one - if (ghoul2.mSlist[i].offFlags & G2SURFACEFLAG_GENERATED) + retMatrix=identityMatrix; + return; + } + assert(ghoul2.mBoneCache); + CBoneCache &boneCache=*ghoul2.mBoneCache; + assert(boneCache.mod); + boltInfo_v &boltList=ghoul2.mBltlist; + assert(boltNum>=0&&boltNum=0) + { + mdxaSkel_t *skel; + mdxaSkelOffsets_t *offsets; + offsets = (mdxaSkelOffsets_t *)((byte *)boneCache.header + sizeof(mdxaHeader_t)); + skel = (mdxaSkel_t *)((byte *)boneCache.header + sizeof(mdxaHeader_t) + offsets->offsets[boltList[boltNum].boneNumber]); + Multiply_3x4Matrix(&retMatrix, &boneCache.Eval(boltList[boltNum].boneNumber), &skel->BasePoseMat); + } + else if (boltList[boltNum].surfaceNumber>=0) + { + const surfaceInfo_t *surfInfo=0; { - // well alrighty then. Lets see if there is a bolt that is attempting to use it - int boltNum = G2_Find_Bolt_Surface_Num(ghoul2.mBltlist, i, G2SURFACEFLAG_GENERATED); - // yes - ok, processing time. - if (boltNum != -1) + int i; + for (i=0;isurface<10000) + { + surface = (mdxmSurface_t *)G2_FindSurface(boneCache.mod,surfInfo->surface, 0); + } + G2_ProcessSurfaceBolt2(boneCache,surface,boltNum,boltList,surfInfo,(model_t *)boneCache.mod,retMatrix); } + else + { + // we have a bolt without a bone or surface, not a huge problem but we ought to at least clear the bolt matrix + retMatrix=identityMatrix; + } +/* + // scale the bolt position by the scale factor for this model since at this point its still in model space + if (scale[0]) + { + retMatrix.matrix[0][3] *= scale[0]; + } + if (scale[1]) + { + retMatrix.matrix[1][3] *= scale[1]; + } + if (scale[2]) + { + retMatrix.matrix[2][3] *= scale[2]; + } + VectorNormalize((float*)&retMatrix.matrix[0]); + VectorNormalize((float*)&retMatrix.matrix[1]); + VectorNormalize((float*)&retMatrix.matrix[2]); +*/ } + // set up each surface ready for rendering in the back end void RenderSurfaces(CRenderSurface &RS) { @@ -1432,7 +1518,7 @@ void RenderSurfaces(CRenderSurface &RS) { // set the surface info to point at the where the transformed bone list is going to be for when the surface gets rendered out CRenderableSurface *newSurf = new CRenderableSurface; newSurf->surfaceData = surface; - newSurf->boneList = &RS.bonePtr; + newSurf->boneCache = RS.boneCache; #ifdef _NPATCH R_AddDrawSurf( (surfaceType_t *)newSurf, tr.shadowShader, 0, qfalse, (RS.currentModel->npatchable ? 1 : 0) ); #else @@ -1448,7 +1534,7 @@ void RenderSurfaces(CRenderSurface &RS) { // set the surface info to point at the where the transformed bone list is going to be for when the surface gets rendered out CRenderableSurface *newSurf = new CRenderableSurface; newSurf->surfaceData = surface; - newSurf->boneList = &RS.bonePtr; + newSurf->boneCache = RS.boneCache; #ifdef _NPATCH R_AddDrawSurf( (surfaceType_t *)newSurf, tr.projectionShadowShader, 0, qfalse, (RS.currentModel->npatchable ? 1 : 0) ); #else @@ -1461,7 +1547,7 @@ void RenderSurfaces(CRenderSurface &RS) { // set the surface info to point at the where the transformed bone list is going to be for when the surface gets rendered out CRenderableSurface *newSurf = new CRenderableSurface; newSurf->surfaceData = surface; - newSurf->boneList = &RS.bonePtr; + newSurf->boneCache = RS.boneCache; #ifdef _NPATCH R_AddDrawSurf( (surfaceType_t *)newSurf, shader, RS.fogNum, qfalse, (RS.currentModel->npatchable ? 1 : 0) ); #else @@ -1470,18 +1556,6 @@ void RenderSurfaces(CRenderSurface &RS) } } - // is this surface considered a bolt surface? - if (offFlags & G2SURFACEFLAG_ISBOLT) - { - // well alrighty then. Lets see if there is a bolt that is attempting to use it - int boltNum = G2_Find_Bolt_Surface_Num(RS.boltList, RS.surfaceNum, 0); - // yes - ok, processing time. - if (boltNum != -1) - { - G2_ProcessSurfaceBolt(RS.bonePtr, surface, boltNum, RS.boltList, surfOverride, RS.currentModel); - } - } - // if we are turning off all descendants, then stop this recursion now if (offFlags & G2SURFACEFLAG_NODESCENDANTS) { @@ -1496,151 +1570,6 @@ void RenderSurfaces(CRenderSurface &RS) } } -// Go through the model and deal with just the surfaces that are tagged as bolt on points - this is for the server side skeleton construction -void ProcessModelBoltSurfaces(int surfaceNum, surfaceInfo_v &rootSList, - mdxaBone_v &bonePtr, const model_t *currentModel, int lod, boltInfo_v &boltList) -{ - int i; - int offFlags = 0; - - // back track and get the surfinfo struct for this surface - mdxmSurface_t *surface = (mdxmSurface_t *)G2_FindSurface((void *)currentModel, surfaceNum, 0); - mdxmHierarchyOffsets_t *surfIndexes = (mdxmHierarchyOffsets_t *)((byte *)currentModel->mdxm + sizeof(mdxmHeader_t)); - mdxmSurfHierarchy_t *surfInfo = (mdxmSurfHierarchy_t *)((byte *)surfIndexes + surfIndexes->offsets[surface->thisSurfaceIndex]); - - // see if we have an override surface in the surface list - const surfaceInfo_t *surfOverride = G2_FindOverrideSurface(surfaceNum, rootSList); - - // really, we should use the default flags for this surface unless it's been overriden - offFlags = surfInfo->flags; - - // set the off flags if we have some - if (surfOverride) - { - offFlags = surfOverride->offFlags; - } - - // is this surface considered a bolt surface? - if (surfInfo->flags & G2SURFACEFLAG_ISBOLT) - { - // well alrighty then. Lets see if there is a bolt that is attempting to use it - int boltNum = G2_Find_Bolt_Surface_Num(boltList, surfaceNum, 0); - // yes - ok, processing time. - if (boltNum != -1) - { - G2_ProcessSurfaceBolt(bonePtr, surface, boltNum, boltList, surfOverride, currentModel); - } - } - - // if we are turning off all descendants, then stop this recursion now - if (offFlags & G2SURFACEFLAG_NODESCENDANTS) - { - return; - } - - // now recursively call for the children - for (i=0; i< surfInfo->numChildren; i++) - { - ProcessModelBoltSurfaces(surfInfo->childIndexes[i], rootSList, bonePtr, currentModel, lod, boltList); - } -} - - -// build the used bone list so when doing bone transforms we can determine if we need to do it or not -void G2_ConstructUsedBoneList(CConstructBoneList &CBL) -{ - int i, j; - int offFlags = 0; - - // back track and get the surfinfo struct for this surface - const mdxmSurface_t *surface = (mdxmSurface_t *)G2_FindSurface((void *)CBL.currentModel, CBL.surfaceNum, 0); - const mdxmHierarchyOffsets_t *surfIndexes = (mdxmHierarchyOffsets_t *)((byte *)CBL.currentModel->mdxm + sizeof(mdxmHeader_t)); - const mdxmSurfHierarchy_t *surfInfo = (mdxmSurfHierarchy_t *)((byte *)surfIndexes + surfIndexes->offsets[surface->thisSurfaceIndex]); - const model_t *mod_a = R_GetModelByHandle(CBL.currentModel->mdxm->animIndex); - const mdxaSkelOffsets_t *offsets = (mdxaSkelOffsets_t *)((byte *)mod_a->mdxa + sizeof(mdxaHeader_t)); - const mdxaSkel_t *skel, *childSkel; - - // see if we have an override surface in the surface list - const surfaceInfo_t *surfOverride = G2_FindOverrideSurface(CBL.surfaceNum, CBL.rootSList); - - // really, we should use the default flags for this surface unless it's been overriden - offFlags = surfInfo->flags; - - // set the off flags if we have some - if (surfOverride) - { - offFlags = surfOverride->offFlags; - } - - // if this surface is not off, add it to the shader render list - if (!(offFlags & G2SURFACEFLAG_OFF)) - { - int *bonesReferenced = (int *)((byte*)surface + surface->ofsBoneReferences); - // now whip through the bones this surface uses - for (i=0; inumBoneReferences;i++) - { - int iBoneIndex = bonesReferenced[i]; - CBL.boneUsedList[iBoneIndex] = 1; - - // now go and check all the descendant bones attached to this bone and see if any have the always flag on them. If so, activate them - skel = (mdxaSkel_t *)((byte *)mod_a->mdxa + sizeof(mdxaHeader_t) + offsets->offsets[iBoneIndex]); - - // for every child bone... - for (j=0; j< skel->numChildren; j++) - { - // get the skel data struct for each child bone of the referenced bone - childSkel = (mdxaSkel_t *)((byte *)mod_a->mdxa + sizeof(mdxaHeader_t) + offsets->offsets[skel->children[j]]); - - // does it have the always on flag on? - if (childSkel->flags & G2BONEFLAG_ALWAYSXFORM) - { - // yes, make sure it's in the list of bones to be transformed. - CBL.boneUsedList[skel->children[j]] = 1; - } - } - - // now we need to ensure that the parents of this bone are actually active... - // - int iParentBone = skel->parent; - while (iParentBone != -1) - { - if (CBL.boneUsedList[iParentBone]) // no need to go higher - break; - CBL.boneUsedList[iParentBone] = 1; - skel = (mdxaSkel_t *)((byte *)mod_a->mdxa + sizeof(mdxaHeader_t) + offsets->offsets[iParentBone]); - iParentBone = skel->parent; - } - } - } - else - // if we are turning off all descendants, then stop this recursion now - if (offFlags & G2SURFACEFLAG_NODESCENDANTS) - { - return; - } - - // now recursively call for the children - for (i=0; i< surfInfo->numChildren; i++) - { - CBL.surfaceNum = surfInfo->childIndexes[i]; - G2_ConstructUsedBoneList(CBL); - } -} - -// count to the last bone used in the used bone list so we can resize the bone repository array struct for this ent -static int G2_CountBonesUsed(const int * const boneUsedList, int boneCount) -{ - int found = -1; - for (int i=0; ie.ghoul2); + CGhoul2Info_v &ghoul2 = *ent->e.ghoul2; + + if ( !ghoul2.IsValid() ) + { + return; + } + + int currentTime=G2API_GetTime(tr.refdef.time); // if we don't want server ghoul2 models and this is one, or we just don't want ghoul2 models at all, then return - if ((r_noServerGhoul2->integer && !(ghoul2[0].mCreationID & WF_CLIENTONLY)) || (r_noGhoul2->integer)) + if (r_noGhoul2->integer) { return; } @@ -1745,48 +1696,16 @@ void R_AddGhoulSurfaces( trRefEntity_t *ent ) { { return; } - + HackadelicOnClient=true; // are any of these models setting a new origin? - for (i=0; ie.origin, ent->e.modelScale, true); - - // scale the bolt position by the scale factor for this model since at this point its still in model space - if (ent->e.modelScale[0]) - { - ghoul2[i].mBltlist[ghoul2[i].mNewOrigin].position.matrix[0][3] *= ent->e.modelScale[0]; - } - if (ent->e.modelScale[1]) - { - ghoul2[i].mBltlist[ghoul2[i].mNewOrigin].position.matrix[1][3] *= ent->e.modelScale[1]; - } - if (ent->e.modelScale[2]) - { - ghoul2[i].mBltlist[ghoul2[i].mNewOrigin].position.matrix[2][3] *= ent->e.modelScale[2]; - } - - VectorNormalize((float*)&ghoul2[i].mBltlist[ghoul2[i].mNewOrigin].position.matrix[0]); - VectorNormalize((float*)&ghoul2[i].mBltlist[ghoul2[i].mNewOrigin].position.matrix[1]); - VectorNormalize((float*)&ghoul2[i].mBltlist[ghoul2[i].mNewOrigin].position.matrix[2]); - mdxaBone_t tempMatrix; - Inverse_Matrix(&ghoul2[i].mBltlist[ghoul2[i].mNewOrigin].position, &tempMatrix); - Multiply_3x4Matrix(&rootMatrix, &tempMatrix, (mdxaBone_t*)&identityMatrix); - - setNewOrigin = true; - } - } - } + RootMatrix(ghoul2,currentTime, ent->e.modelScale,rootMatrix); // don't add third_person objects if not in a portal personalModel = (qboolean)((ent->e.renderfx & RF_THIRD_PERSON) && !tr.viewParms.isPortal); - modelList = (int*)Z_Malloc(ghoul2.size() * 4, TAG_GHOUL2, qfalse); + int modelList[256]; + assert(ghoul2.size()<=255); + modelList[255]=548; // set up lighting now that we know we aren't culled if ( !personalModel || r_shadows->integer > 1 ) @@ -1800,6 +1719,7 @@ void R_AddGhoulSurfaces( trRefEntity_t *ent ) { // order sort the ghoul 2 models so bolt ons get bolted to the right model G2_Sort_Models(ghoul2, modelList, &modelCount); + assert(modelList[255]==548); // construct a world matrix for this entity G2_GenerateWorldMatrix(ent->e.angles, ent->e.origin); @@ -1811,13 +1731,24 @@ void R_AddGhoulSurfaces( trRefEntity_t *ent ) { i = modelList[j]; // do we really really want to deal with this model? - if (!(ghoul2[i].mFlags & GHOUL2_NOMODEL)) + // do we really want to read jakes inane comments? + if (!(ghoul2[i].mFlags & GHOUL2_NOMODEL)&&!(ghoul2[i].mFlags & GHOUL2_NORENDER)) { + // I really hate this code, really hate this code -gil +#if 1 + ghoul2[i].mModel = RE_RegisterModel(ghoul2[i].mFileName); + const model_t *currentModel = R_GetModelByHandle(ghoul2[i].mModel); +#else if (!ghoul2[i].mModel) {// probably cleared by G2API_SetGhoul2ModelIndexes ghoul2[i].mModel = RE_RegisterModel(ghoul2[i].mFileName); } const model_t *currentModel = R_GetModelByHandle(ghoul2[i].mModel); +#endif + if (!currentModel||!currentModel->mdxm) + { + continue; + } const model_t *animModel = R_GetModelByHandle(currentModel->mdxm->animIndex); const mdxaHeader_t *aHeader = animModel->mdxa; @@ -1843,264 +1774,116 @@ void R_AddGhoulSurfaces( trRefEntity_t *ent ) { } } - - if (ghoul2[i].mSkelFrameNum != tr.refdef.time) + if (j&&ghoul2[i].mModelBoltLink != -1) { - int *boneUsedList; - - ghoul2[i].mSkelFrameNum = tr.refdef.time; - - // construct a list of all bones used by this model - this makes the bone transform go a bit faster since it will dump out bones - // that aren't being used. - NOTE this will screw up any models that have surfaces turned off where the lower surfaces aren't. - boneUsedList = (int *)Z_Malloc(animModel->mdxa->numBones * 4, TAG_GHOUL2, qfalse); - memset(boneUsedList, 0, (animModel->mdxa->numBones * 4)); - - CConstructBoneList CBL(ghoul2[i].mSurfaceRoot, - boneUsedList, - ghoul2[i].mSlist, - currentModel, - ghoul2[i].mBlist - ); - - G2_ConstructUsedBoneList(CBL); - - if (!ghoul2[i].mSurfaceRoot) - { - // make sure the root bone is marked as being referenced - boneUsedList[0] =1; - } - - // now we know how many bones are going to be transformed, we can set up the temp transformed bone data repository for this ghoul model -// if (ghoul2[i].mCreationID & WF_CLIENTONLY) -// { - // this is a client side created ghoul model, which means the entity state that the refent points at is in the .exe, and I can resize this - // directly - ghoul2[i].mTempBoneList.resize(G2_CountBonesUsed(boneUsedList, animModel->mdxa->numBones)+1); -// } -// else -// { - // have to do this in the CGAME DLL since the original data was created there. -// VM_Call (CG_RESIZE_G2_TEMPBONE, &ghoul2[i].mTempBoneList,G2_CountBonesUsed(boneUsedList, animModel->mdxa->numBones)+1); -// } - - // if this is the root model, and we have a new root matrix because the model has a new origin, use that - if (!setNewOrigin || j) - { - // decide what to do about the root matrix - if (ghoul2[i].mModelBoltLink == -1) - { - // we aren't bolted to anything - rootMatrix = identityMatrix; - } - // yes we are bolted to another model, better use the bolt as the root matrix then, so our model is offset correctly for the bone bolt - else - { - int boltMod = (ghoul2[i].mModelBoltLink >> MODEL_SHIFT) & MODEL_AND; - int boltNum = (ghoul2[i].mModelBoltLink >> BOLT_SHIFT) & BOLT_AND; - rootMatrix = ghoul2[boltMod].mBltlist[boltNum].position; - } - } - - // pre-transform all the bones of this model - int timeoffset; - timeoffset=0; - G2_TransformGhoulBones( aHeader, boneUsedList, rootMatrix, ghoul2[i], tr.refdef.time+timeoffset, animModel->mdxa->numBones); - - Z_Free(boneUsedList); - } - // - // compute LOD - // - whichLod = G2_ComputeLOD( ent, currentModel, ghoul2[i].mLodBias ); - - // do we really want to render this? - if ( ghoul2[i].mFlags & GHOUL2_NORENDER /*( ghoul2[i].mModelBoltLink == -1 && ent->e.renderfx & RF_ALPHA_FADE) */) // cheesy first person lightsaber hack - { - // if we didn't render it, then we should still go sort out all the bolt surfaces in the model - ProcessModelBoltSurfaces(ghoul2[i].mSurfaceRoot, ghoul2[i].mSlist, ghoul2[i].mTempBoneList, currentModel, whichLod, ghoul2[i].mBltlist); + int boltMod = (ghoul2[i].mModelBoltLink >> MODEL_SHIFT) & MODEL_AND; + int boltNum = (ghoul2[i].mModelBoltLink >> BOLT_SHIFT) & BOLT_AND; + mdxaBone_t bolt; + G2_GetBoltMatrixLow(ghoul2[boltMod],boltNum,ent->e.modelScale,bolt); + G2_TransformGhoulBones((void *)currentModel, aHeader, ghoul2[i].mBlist,bolt, ghoul2[i],currentTime); } else - { // start the walk of the surface hierarchy - CRenderSurface RS(ghoul2[i].mSurfaceRoot, ghoul2[i].mSlist, cust_shader, fogNum, personalModel, ghoul2[i].mTempBoneList, ent->e.renderfx, skin, currentModel, whichLod, ghoul2[i].mBltlist); - RenderSurfaces(RS); + { + G2_TransformGhoulBones((void *)currentModel, aHeader, ghoul2[i].mBlist, rootMatrix, ghoul2[i],currentTime); } - - // go through all the generated surfaces and create their bolt info if we need it. - G2_ProcessGeneratedSurfaceBolts(ghoul2[i], ghoul2[i].mTempBoneList, currentModel); - + whichLod = G2_ComputeLOD( ent, currentModel, ghoul2[i].mLodBias ); + G2_FindOverrideSurface(-1,ghoul2[i].mSlist); //reset the quick surface override lookup; + CRenderSurface RS(ghoul2[i].mSurfaceRoot, ghoul2[i].mSlist, cust_shader, fogNum, personalModel, ghoul2[i].mBoneCache, ent->e.renderfx, skin, currentModel, whichLod, ghoul2[i].mBltlist); + RenderSurfaces(RS); } } - Z_Free(modelList); + HackadelicOnClient=false; } +bool G2_NeedsRecalc(CGhoul2Info *ghlInfo,int frameNum) +{ + ghlInfo->mModel = RE_RegisterModel(ghlInfo->mFileName); + void *currentModel = R_GetModelByHandle(ghlInfo->mModel); + if (ghlInfo->mSkelFrameNum!=frameNum|| + !ghlInfo->mBoneCache|| + ghlInfo->mBoneCache->mod!=currentModel) + { + ghlInfo->mSkelFrameNum=frameNum; + return true; + } + return false; +} + /* ============== G2_ConstructGhoulSkeleton - builds a complete skeleton for all ghoul models in a CGhoul2Info_v class - using LOD 0 ============== */ -void G2_ConstructGhoulSkeleton( CGhoul2Info_v &ghoul2, const int frameNum, qhandle_t *modelPointerList, bool checkForNewOrigin, const vec3_t position, const vec3_t scale, bool modelSet) { +void G2_ConstructGhoulSkeleton( CGhoul2Info_v &ghoul2,const int frameNum,bool checkForNewOrigin,const vec3_t scale) +{ mdxaHeader_t *aHeader; int i, j; - int *boneUsedList; - const model_t *currentModel; const model_t *animModel; int modelCount; - int *modelList; - bool setNewOrigin = false; mdxaBone_t rootMatrix; - // if we don't want server ghoul2 models and this is one, or we just don't want ghoul2 models at all, then return - if ((r_noServerGhoul2->integer && !(ghoul2[0].mCreationID & WF_CLIENTONLY)) || (r_noGhoul2->integer)) - { - return; - } + int modelList[256]; + assert(ghoul2.size()<=255); + modelList[255]=548; - // have we already transformed this group of ghoul2 skeletons this frame? - if (ghoul2[0].mSkelFrameNum == frameNum) - { - //Com_Printf( "%7d construct skel request using cached data\n", frameNum ); - return; - } - //Com_Printf( "%7d != %d construct skel\n", frameNum, ghoul2[0].mSkelFrameNum ); - - // should we be looking to see if any of these models are setting a new origin? if (checkForNewOrigin) { - // are any of these models setting a new origin? - for (int i=0; imdxm) { - currentModel = R_GetModelByHandle( modelPointerList[ghoul2[i].mModelindex] ); + ghoul2[i].mModel = RE_RegisterModel(ghoul2[i].mFileName); + currentModel = R_GetModelByHandle(ghoul2[i].mModel); } - else +#endif + if (!currentModel->mdxm) { - currentModel = R_GetModelByHandle( RE_RegisterModel(ghoul2[i].mFileName) ); + continue; } assert(currentModel->mdxm);//something very bad happened here, it has no glm! animModel = R_GetModelByHandle(currentModel->mdxm->animIndex); aHeader = animModel->mdxa; - ghoul2[i].mSkelFrameNum = frameNum; - - // construct a list of all bones used by this model - this makes the bone transform go a bit faster since it will dump out bones - // that aren't being used. - NOTE this will screw up any models that have surfaces turned off where the lower surfaces aren't. - boneUsedList = (int *)Z_Malloc(animModel->mdxa->numBones * 4, TAG_GHOUL2, qfalse); - memset(boneUsedList, 0, (animModel->mdxa->numBones * 4)); - - CConstructBoneList CBL( - ghoul2[i].mSurfaceRoot, - boneUsedList, - ghoul2[i].mSlist, - currentModel, - ghoul2[i].mBlist - ); - - G2_ConstructUsedBoneList(CBL); - - if (!ghoul2[i].mSurfaceRoot) + if (j&&ghoul2[i].mModelBoltLink != -1) { - // make sure the root bone is marked as being referenced - boneUsedList[0] =1; - } + int boltMod = (ghoul2[i].mModelBoltLink >> MODEL_SHIFT) & MODEL_AND; + int boltNum = (ghoul2[i].mModelBoltLink >> BOLT_SHIFT) & BOLT_AND; - if (ghoul2[i].mFileName[0]) - { - // this is a client side created ghoul model, which means the entity state that the refent points at is in the .exe, and I can resize this - // directly - ghoul2[i].mTempBoneList.resize(G2_CountBonesUsed(boneUsedList, animModel->mdxa->numBones)+1); + mdxaBone_t bolt; + G2_GetBoltMatrixLow(ghoul2[boltMod],boltNum,scale,bolt); + G2_TransformGhoulBones((void *)currentModel,aHeader,ghoul2[i].mBlist,bolt,ghoul2[i],frameNum); } else { - // have to do this in the CGAME DLL since the original data was created there. - VM_Call (CG_RESIZE_G2_TEMPBONE, &ghoul2[i].mTempBoneList,G2_CountBonesUsed(boneUsedList, animModel->mdxa->numBones)+1); + G2_TransformGhoulBones((void *)currentModel,aHeader,ghoul2[i].mBlist,rootMatrix,ghoul2[i],frameNum); } - - // decide what to do about the root matrix - - // if this is the root model, and we have a new root matrix because the model has a new origin, use that - if (!setNewOrigin || j) - { - if (ghoul2[i].mModelBoltLink == -1) - { - // we aren't bolted to anything - rootMatrix = identityMatrix; - } - // yes we are bolted to another model, better use the bolt as the root matrix then, so our model is offset correctly for the bone bolt - else - { - int boltMod = (ghoul2[i].mModelBoltLink >> MODEL_SHIFT) & MODEL_AND; - int boltNum = (ghoul2[i].mModelBoltLink >> BOLT_SHIFT) & BOLT_AND; - rootMatrix = ghoul2[boltMod].mBltlist[boltNum].position; - } - } - - // pre-transform all the bones of this model - G2_TransformGhoulBones( aHeader, boneUsedList, rootMatrix, ghoul2[i], frameNum, animModel->mdxa->numBones); - - Z_Free(boneUsedList); - - // call function that will go through the main model and generate all the bolts required - ProcessModelBoltSurfaces(ghoul2[i].mSurfaceRoot, ghoul2[i].mSlist, ghoul2[i].mTempBoneList, currentModel, 0, ghoul2[i].mBltlist); - - // go through all the generated surfaces and create their bolt info if we need it. - G2_ProcessGeneratedSurfaceBolts(ghoul2[i], ghoul2[i].mTempBoneList, currentModel); - } } - Z_Free(modelList); - return; } @@ -2116,7 +1899,7 @@ void RB_SurfaceGhoul( CRenderableSurface *surf ) { mdxmSurface_t *surface = (mdxmSurface_t *)surf->surfaceData; // point us at the bone structure that should have been pre-computed - mdxaBone_v &bonePtr = *((mdxaBone_v *)surf->boneList); + CBoneCache *bones = surf->boneCache; delete surf; // @@ -2150,7 +1933,7 @@ void RB_SurfaceGhoul( CRenderableSurface *surf ) { // whip through and actually transform each vertex - const int *piBoneRefs = (int*) ((byte*)surface + surface->ofsBoneReferences); + int *piBoneReferences = (int*) ((byte*)surface + surface->ofsBoneReferences); const int numVerts = surface->numVerts; const mdxmVertex_t *v = (mdxmVertex_t *) ((byte *)surface + surface->ofsVerts); @@ -2158,21 +1941,41 @@ void RB_SurfaceGhoul( CRenderableSurface *surf ) { for ( j = 0; j < numVerts; j++, baseVert++ ) { const int numWeights = v->numWeights; + assert(numWeights); // if this fires, comment it out please. + // if nobody comments it out, I will remove the below if for performance const mdxmWeight_t *w = v->weights; - VectorClear( tess.xyz[baseVert]); - VectorClear( tess.normal[baseVert]); + const mdxaBone_t *bone; - for ( k = 0 ; k < numWeights ; k++, w++ ) + if (numWeights) { - mdxaBone_t &bone = bonePtr[piBoneRefs[w->boneIndex]]; + bone = &bones->EvalRender(piBoneReferences[w->boneIndex]); - tess.xyz[baseVert][0] += w->boneWeight * ( DotProduct( bone.matrix[0], v->vertCoords ) + bone.matrix[0][3] ); - tess.xyz[baseVert][1] += w->boneWeight * ( DotProduct( bone.matrix[1], v->vertCoords ) + bone.matrix[1][3] ); - tess.xyz[baseVert][2] += w->boneWeight * ( DotProduct( bone.matrix[2], v->vertCoords ) + bone.matrix[2][3] ); + tess.xyz[baseVert][0] = w->boneWeight * ( DotProduct( bone->matrix[0], v->vertCoords ) + bone->matrix[0][3] ); + tess.xyz[baseVert][1] = w->boneWeight * ( DotProduct( bone->matrix[1], v->vertCoords ) + bone->matrix[1][3] ); + tess.xyz[baseVert][2] = w->boneWeight * ( DotProduct( bone->matrix[2], v->vertCoords ) + bone->matrix[2][3] ); - tess.normal[baseVert][0] += w->boneWeight * DotProduct( bone.matrix[0], v->normal ); - tess.normal[baseVert][1] += w->boneWeight * DotProduct( bone.matrix[1], v->normal ); - tess.normal[baseVert][2] += w->boneWeight * DotProduct( bone.matrix[2], v->normal ); + tess.normal[baseVert][0] = w->boneWeight * DotProduct( bone->matrix[0], v->normal ); + tess.normal[baseVert][1] = w->boneWeight * DotProduct( bone->matrix[1], v->normal ); + tess.normal[baseVert][2] = w->boneWeight * DotProduct( bone->matrix[2], v->normal ); + + for (w++, k = 1 ; k < numWeights ; k++, w++ ) + { + bone = &bones->EvalRender(piBoneReferences[w->boneIndex]); + + tess.xyz[baseVert][0] += w->boneWeight * ( DotProduct( bone->matrix[0], v->vertCoords ) + bone->matrix[0][3] ); + tess.xyz[baseVert][1] += w->boneWeight * ( DotProduct( bone->matrix[1], v->vertCoords ) + bone->matrix[1][3] ); + tess.xyz[baseVert][2] += w->boneWeight * ( DotProduct( bone->matrix[2], v->vertCoords ) + bone->matrix[2][3] ); + + tess.normal[baseVert][0] += w->boneWeight * DotProduct( bone->matrix[0], v->normal ); + tess.normal[baseVert][1] += w->boneWeight * DotProduct( bone->matrix[1], v->normal ); + tess.normal[baseVert][2] += w->boneWeight * DotProduct( bone->matrix[2], v->normal ); + } + + } + else + { + VectorClear( tess.xyz[baseVert]); + VectorClear( tess.normal[baseVert]); } tess.texCoords[baseVert][0][0] = v->texCoords[0]; diff --git a/code/renderer/tr_image.cpp b/code/renderer/tr_image.cpp index cdd9ba3..66e6bf6 100644 --- a/code/renderer/tr_image.cpp +++ b/code/renderer/tr_image.cpp @@ -858,7 +858,7 @@ void RE_RegisterImages_Info_f( void ) // currently, this just goes through all the images and dumps any not referenced on this level... // -void RE_RegisterImages_LevelLoadEnd(void) +qboolean RE_RegisterImages_LevelLoadEnd(void) { ri.Printf( PRINT_DEVELOPER, "RE_RegisterImages_LevelLoadEnd():\n"); @@ -902,6 +902,8 @@ void RE_RegisterImages_LevelLoadEnd(void) ri.Printf( PRINT_DEVELOPER, "RE_RegisterImages_LevelLoadEnd(): Ok\n"); GL_ResetBinds(); + + return bEraseOccured; } diff --git a/code/renderer/tr_init.cpp b/code/renderer/tr_init.cpp index 32b0379..5834776 100644 --- a/code/renderer/tr_init.cpp +++ b/code/renderer/tr_init.cpp @@ -155,7 +155,13 @@ Ghoul2 Insert Start cvar_t *r_noServerGhoul2; cvar_t *r_noGhoul2; cvar_t *r_Ghoul2Test; +cvar_t *r_Ghoul2AnimSmooth; cvar_t *r_Ghoul2UnSqash; +cvar_t *r_Ghoul2TimeBase=0; +cvar_t *r_Ghoul2NoLerp; +cvar_t *r_Ghoul2NoBlend; +cvar_t *r_Ghoul2UnSqashAfterSmooth; + /* Ghoul2 Insert End @@ -1034,8 +1040,8 @@ void R_Register( void ) #endif r_facePlaneCull = ri.Cvar_Get ("r_facePlaneCull", "1", CVAR_ARCHIVE ); - r_surfaceSprites = ri.Cvar_Get ("r_surfaceSprites", "1", CVAR_ARCHIVE); - r_surfaceWeather = ri.Cvar_Get ("r_surfaceWeather", "1", CVAR_ARCHIVE); + r_surfaceSprites = ri.Cvar_Get ("r_surfaceSprites", "1", CVAR_CHEAT); + r_surfaceWeather = ri.Cvar_Get ("r_surfaceWeather", "0", 0); r_windSpeed = ri.Cvar_Get ("r_windSpeed", "0", 0); r_windAngle = ri.Cvar_Get ("r_windAngle", "0", 0); @@ -1103,7 +1109,13 @@ Ghoul2 Insert Start r_noServerGhoul2 = ri.Cvar_Get( "r_noserverghoul2", "0", 0); r_noGhoul2 = ri.Cvar_Get( "r_noghoul2", "0", 0); r_Ghoul2Test = ri.Cvar_Get( "r_ghoul2test", "0", 0); + r_Ghoul2AnimSmooth = ri.Cvar_Get( "r_ghoul2animsmooth", "0", 0); r_Ghoul2UnSqash = ri.Cvar_Get( "r_ghoul2unsquash", "1", 0); + r_Ghoul2TimeBase = ri.Cvar_Get( "r_ghoul2timebase", "2", 0); + r_Ghoul2NoLerp = ri.Cvar_Get( "r_ghoul2nolerp", "0", 0); + r_Ghoul2NoBlend = ri.Cvar_Get( "r_ghoul2noblend", "0", 0); + r_Ghoul2UnSqashAfterSmooth = ri.Cvar_Get( "r_ghoul2unsquashaftersmooth", "1", 0); + /* Ghoul2 Insert End */ diff --git a/code/renderer/tr_light.cpp b/code/renderer/tr_light.cpp index 0d87d5c..94d0f9a 100644 --- a/code/renderer/tr_light.cpp +++ b/code/renderer/tr_light.cpp @@ -390,7 +390,12 @@ void R_SetupEntityLighting( const trRefdef_t *refdef, trRefEntity_t *ent ) { } // bonus items and view weapons have a fixed minimum add - if ( 1 /* ent->e.renderfx & RF_MINLIGHT */ ) { + if ( ent->e.renderfx & RF_MORELIGHT ) { + ent->ambientLight[0] += tr.identityLight * 96; + ent->ambientLight[1] += tr.identityLight * 96; + ent->ambientLight[2] += tr.identityLight * 96; + } + else { // give everything a minimum light add ent->ambientLight[0] += tr.identityLight * 32; ent->ambientLight[1] += tr.identityLight * 32; diff --git a/code/renderer/tr_local.h b/code/renderer/tr_local.h index 6ae1223..9516686 100644 --- a/code/renderer/tr_local.h +++ b/code/renderer/tr_local.h @@ -1010,6 +1010,7 @@ typedef struct { int numShaders; shader_t *shaders[MAX_SHADERS]; shader_t *sortedShaders[MAX_SHADERS]; + int iNumDeniedShaders; // used for error-messages only int numSkins; skin_t *skins[MAX_SKINS]; @@ -1289,9 +1290,8 @@ qboolean RE_RegisterModels_LevelLoadEnd(qboolean bDeleteEverythingNotUsedThisLev void* RE_RegisterModels_Malloc(int iSize, const char *psModelFileName, qboolean *pqbAlreadyFound, memtag_t eTag); void RE_RegisterModels_StoreShaderRequest(const char *psModelFileName, const char *psShaderName, const int *piShaderIndexPoke); void RE_RegisterModels_Info_f(void); -// //void RE_RegisterImages_LevelLoadBegin(const char *psMapName); -void RE_RegisterImages_LevelLoadEnd(void); +qboolean RE_RegisterImages_LevelLoadEnd(void); void RE_RegisterImages_Info_f(void); @@ -1571,16 +1571,18 @@ void RB_SurfaceAnim( md4Surface_t *surfType ); Ghoul2 Insert Start */ #pragma warning (disable: 4512) //default assignment operator could not be gened +class CBoneCache; + class CRenderableSurface { public: const int ident; // ident of this surface - required so the materials renderer knows what sort of surface this refers to - void *boneList; // pointer to transformed bone list for this surface - required client side for rendering DONOT USE IN GAME SIDE + CBoneCache *boneCache; // pointer to transformed bone list for this surf mdxmSurface_t *surfaceData; // pointer to surface data loaded into file - only used by client renderer DO NOT USE IN GAME SIDE - if there is a vid restart this will be out of wack on the game CRenderableSurface(): ident(SF_MDX), - boneList(0), + boneCache(0), surfaceData(0) {} }; @@ -1786,7 +1788,7 @@ Ghoul2 Insert Start // tr_ghoul2.cpp void Create_Matrix(const float *angle, mdxaBone_t *matrix); -void Multiply_3x4Matrix(mdxaBone_t *out, mdxaBone_t *in2, mdxaBone_t *in); +void Multiply_3x4Matrix(mdxaBone_t *out,const mdxaBone_t *in2,const mdxaBone_t *in); extern qboolean R_LoadMDXM (model_t *mod, void *buffer, const char *name, qboolean bAlreadyCached ); extern qboolean R_LoadMDXA (model_t *mod, void *buffer, const char *name, qboolean bAlreadyCached ); bool LoadTGAPalletteImage ( const char *name, byte **pic, int *width, int *height); diff --git a/code/renderer/tr_quicksprite.cpp b/code/renderer/tr_quicksprite.cpp index e13ed38..45a5850 100644 --- a/code/renderer/tr_quicksprite.cpp +++ b/code/renderer/tr_quicksprite.cpp @@ -60,8 +60,8 @@ void CQuickSpriteSystem::Flush(void) // // set arrays and lock // - qglTexCoordPointer( 2, GL_FLOAT, 0, mTextureCoords ); qglEnableClientState( GL_TEXTURE_COORD_ARRAY); + qglTexCoordPointer( 2, GL_FLOAT, 0, mTextureCoords ); qglEnableClientState( GL_COLOR_ARRAY); qglColorPointer( 4, GL_UNSIGNED_BYTE, 0, mColors ); diff --git a/code/renderer/tr_shader.cpp b/code/renderer/tr_shader.cpp index 0296757..40fab1b 100644 --- a/code/renderer/tr_shader.cpp +++ b/code/renderer/tr_shader.cpp @@ -581,6 +581,7 @@ static void ParseTexMod( const char *_text, shaderStage_t *stage ) /* +/////===== Part of the VERTIGON system =====///// =================== ParseSurfaceSprites =================== @@ -722,6 +723,7 @@ static void ParseSurfaceSprites(const char *_text, shaderStage_t *stage ) /* +/////===== Part of the VERTIGON system =====///// =========================== ParseSurfaceSpritesOptional =========================== @@ -743,7 +745,7 @@ ParseSurfaceSpritesOptional // // Optional parameters that will override the defaults set in the surfacesprites command above. // -void ParseSurfaceSpritesOptional( const char *param, const char *_text, shaderStage_t *stage ) +static void ParseSurfaceSpritesOptional( const char *param, const char *_text, shaderStage_t *stage ) { const char *token; const char **text = &_text; @@ -2552,7 +2554,8 @@ static shader_t *GeneratePermanentShader( void ) { int size, hash; if ( tr.numShaders == MAX_SHADERS ) { - ri.Printf( PRINT_WARNING, "WARNING: GeneratePermanentShader - MAX_SHADERS hit\n"); + tr.iNumDeniedShaders++; + ri.Printf( PRINT_WARNING, "WARNING: GeneratePermanentShader - MAX_SHADERS (%d) hit (overflowed by %d)\n", MAX_SHADERS, tr.iNumDeniedShaders); return tr.defaultShader; } @@ -3473,6 +3476,7 @@ CreateInternalShaders */ static void CreateInternalShaders( void ) { tr.numShaders = 0; + tr.iNumDeniedShaders = 0; // init the default shader memset( &shader, 0, sizeof( shader ) ); diff --git a/code/renderer/tr_surfacesprites.cpp b/code/renderer/tr_surfacesprites.cpp index a03835e..4c44845 100644 --- a/code/renderer/tr_surfacesprites.cpp +++ b/code/renderer/tr_surfacesprites.cpp @@ -6,6 +6,7 @@ #include "tr_QuickSprite.h" +#include "tr_worldeffects.h" /////===== Part of the VERTIGON system =====///// @@ -56,10 +57,11 @@ const float randomchart[256] = { #define WIND_DAMP_INTERVAL 50 #define WIND_GUST_TIME 2500.0 #define WIND_GUST_DECAY (1.0 / WIND_GUST_TIME) -extern bool R_GetWindVector(vec3_t windVector); int lastSSUpdateTime = 0; float curWindSpeed=0; +float curWindGust=5; +float curWeatherAmount=1; vec3_t curWindBlowVect={0,0,0}, targetWindBlowVect={0,0,0}; vec3_t curWindGrassDir={0,0,0}, targetWindGrassDir={0,0,0}; int totalsurfsprites=0, sssurfaces=0; @@ -70,7 +72,8 @@ vec3_t curWindPoint; int nextGustTime=0; float gustLeft=0; -float standardfovx = -1, standardscalex = 1.0; +qboolean standardfovinitialized=qfalse; +float standardfovx = 90, standardscalex = 1.0; float rangescalefactor=1.0; vec3_t ssrightvectors[4]; @@ -93,7 +96,8 @@ static void R_SurfaceSpriteFrameUpdate(void) return; if (backEnd.refdef.time < lastSSUpdateTime) - { + { // Time is BEFORE the last update time, so reset everything. + curWindGust = 5; curWindSpeed = r_windSpeed->value; nextGustTime = 0; gustLeft = 0; @@ -105,22 +109,35 @@ static void R_SurfaceSpriteFrameUpdate(void) // Adjust for an FOV. If things look twice as wide on the screen, pretend the shaders have twice the range. // ASSUMPTION HERE IS THAT "standard" fov is the first one rendered. - if (standardfovx < 0) + if (!standardfovinitialized) { // This isn't initialized yet. - if (backEnd.refdef.fov_x > 0.01) + if (backEnd.refdef.fov_x > 50 && backEnd.refdef.fov_x < 135) // I don't consider anything below 50 or above 135 to be "normal". { standardfovx = backEnd.refdef.fov_x; - standardscalex = tan(standardfovx * (M_PI/180.0f)); + standardscalex = tan(standardfovx * 0.5 * (M_PI/180.0f)); + standardfovinitialized = qtrue; + } + else + { + standardfovx = 90; + standardscalex = tan(standardfovx * 0.5 * (M_PI/180.0f)); } rangescalefactor = 1.0; // Don't multiply the shader range by anything. } else if (standardfovx == backEnd.refdef.fov_x) - { // This is the standard FOV, don't multiply the shader range. + { // This is the standard FOV (or higher), don't multiply the shader range. rangescalefactor = 1.0; } else { // We are using a non-standard FOV. We need to multiply the range of the shader by a scale factor. - rangescalefactor = standardscalex / tan(backEnd.refdef.fov_x * (M_PI/180.0f)); + if (backEnd.refdef.fov_x > 135) + { + rangescalefactor = standardscalex / tan(135.0f * 0.5f * (M_PI/180.0f)); + } + else + { + rangescalefactor = standardscalex / tan(backEnd.refdef.fov_x * 0.5 * (M_PI/180.0f)); + } } // Create a set of four right vectors so that vertical sprites aren't always facing the same way. @@ -147,9 +164,36 @@ static void R_SurfaceSpriteFrameUpdate(void) // Update the wind. - targetspeed = r_windSpeed->value; // Minimum gust delay, in seconds. + // If it is raining, get the windspeed from the rain system rather than the cvar + if (R_IsRaining() || R_IsSnowing()) + { + curWeatherAmount = 1.0; + } + else + { + curWeatherAmount = r_surfaceWeather->value; + } + + if (R_GetWindSpeed(targetspeed)) + { // We successfully got a speed from the rain system. + // Set the windgust to 5, since that looks pretty good. + targetspeed *= 0.3f; + if (targetspeed >= 1.0) + { + curWindGust = 300/targetspeed; + } + else + { + curWindGust = 0; + } + } + else + { // Use the cvar. + targetspeed = r_windSpeed->value; // Minimum gust delay, in seconds. + curWindGust = r_windGust->value; + } - if (targetspeed > 0 && r_windGust->value) + if (targetspeed > 0 && curWindGust) { if (gustLeft > 0) { // We are gusting @@ -159,7 +203,7 @@ static void R_SurfaceSpriteFrameUpdate(void) gustLeft -= (float)(backEnd.refdef.time - lastSSUpdateTime)*WIND_GUST_DECAY; if (gustLeft <= 0) { - nextGustTime = backEnd.refdef.time + (r_windGust->value*1000)*ri.flrand(1.0f,4.0f); + nextGustTime = backEnd.refdef.time + (curWindGust*1000)*ri.flrand(1.0f,4.0f); } } else if (backEnd.refdef.time >= nextGustTime) @@ -1131,16 +1175,15 @@ static void RB_DrawEffectSurfaceSprites( shaderStage_t *stage, shaderCommands_t float alpha, alphapos, thisspritesfadestart, light; byte randomindex2; - float cutdist=stage->ss.fadeMax, cutdist2=cutdist*cutdist; - float fadedist=stage->ss.fadeDist, fadedist2=fadedist*fadedist; + float cutdist=stage->ss.fadeMax*rangescalefactor, cutdist2=cutdist*cutdist; + float fadedist=stage->ss.fadeDist*rangescalefactor, fadedist2=fadedist*fadedist; float fxalpha = stage->ss.fxAlphaEnd - stage->ss.fxAlphaStart; + qboolean fadeinout=qfalse; assert(cutdist2 != fadedist2); float inv_fadediff = 1.0/(cutdist2-fadedist2); - qboolean fadeinout=qfalse; - // The faderange is the fraction amount it takes for these sprites to fade out, assuming an ideal fade range of 250 float faderange = FADE_RANGE/(cutdist-fadedist); if (faderange > 1.0f) @@ -1165,13 +1208,13 @@ static void RB_DrawEffectSurfaceSprites( shaderStage_t *stage, shaderCommands_t if (stage->ss.surfaceSpriteType == SURFSPRITE_WEATHERFX) { // This effect is affected by weather settings. - if (r_surfaceWeather->value < 0.01) + if (curWeatherAmount < 0.01) { // Don't show these effects return; } else { - density = stage->ss.density / r_surfaceWeather->value; + density = stage->ss.density / curWeatherAmount; } } else @@ -1183,7 +1226,7 @@ static void RB_DrawEffectSurfaceSprites( shaderStage_t *stage, shaderCommands_t for (curvert=0; curvertnumVertexes; curvert++) { // Calc alpha at each point - VectorSubtract(backEnd.viewParms.or.origin, input->xyz[curvert], dist); + VectorSubtract(ssViewOrigin, input->xyz[curvert], dist); SSVertAlpha[curvert] = 1.0f - (VectorLengthSquared(dist) - fadedist2) * inv_fadediff; // Note this is the proper equation, but isn't used right now because it would be just a tad slower. @@ -1357,7 +1400,7 @@ void RB_DrawSurfaceSprites( shaderStage_t *stage, shaderCommands_t *input) // // Check fog // - if ( tess.fogNum && tess.shader->fogPass)// && r_drawfog->value) + if ( tess.fogNum && tess.shader->fogPass && r_drawfog->value) { fog = tr.world->fogs + tess.fogNum; SSUsingFog = qtrue; diff --git a/code/renderer/tr_types.h b/code/renderer/tr_types.h index 42ce542..6d4f4cc 100644 --- a/code/renderer/tr_types.h +++ b/code/renderer/tr_types.h @@ -7,7 +7,7 @@ #define MAX_ENTITIES 1023 // can't be increased without changing drawsurf bit packing // renderfx flags -#define RF_MINLIGHT 0x00001 // allways have some light (viewmodel, some items) +#define RF_MORELIGHT 0x00001 // allways have some light (viewmodel, some items) #define RF_THIRD_PERSON 0x00002 // don't draw through eyes, only mirrors (player bodies, chat sprites) #define RF_FIRST_PERSON 0x00004 // only draw through eyes (view weapon, damage blood blob) #define RF_DEPTHHACK 0x00008 // for view weapon Z crunching diff --git a/code/renderer/tr_worldeffects.cpp b/code/renderer/tr_worldeffects.cpp index 08a3124..79d0ebd 100644 --- a/code/renderer/tr_worldeffects.cpp +++ b/code/renderer/tr_worldeffects.cpp @@ -347,11 +347,13 @@ private: SParticle *mRainList; float mFadeAlpha; + bool mIsRaining; public: enum { RAINSYSTEM_WIND_DIRECTION, + RAINSYSTEM_WIND_SPEED, }; public: @@ -360,6 +362,7 @@ public: virtual int GetIntVariable(int which); virtual SParticle *GetParticleVariable(int which); + virtual float GetFloatVariable(int which); virtual float *GetVecVariable(int which); virtual bool Command(const char *command); @@ -368,6 +371,8 @@ public: virtual void Render(void); void Init(void); + + bool IsRaining() { return mIsRaining; } }; @@ -1256,6 +1261,7 @@ private: int mUpdateCount; int mOverallContents; + bool mIsSnowing; const float mVelocityStabilize; const int mUpdateMax; @@ -1274,6 +1280,8 @@ public: virtual void Render(void); void Init(void); + + bool IsSnowing() { return mIsSnowing; } }; CSnowSystem::CSnowSystem(int maxSnowflakes) : @@ -1292,7 +1300,8 @@ CSnowSystem::CSnowSystem(int maxSnowflakes) : mOverallContents(0), mVelocityStabilize(18), - mUpdateMax(10) + mUpdateMax(10), + mIsSnowing(false) { mMinSpread[0] = -600; mMinSpread[1] = -600; @@ -1610,9 +1619,12 @@ void CSnowSystem::Update(float elapseTime) if (!(mOverallContents & CONTENTS_OUTSIDE)) { + mIsSnowing = false; return; } + mIsSnowing = true; + mUpdateCount = (mUpdateCount + 1) % mUpdateMax; x = y = z = 0; @@ -1783,7 +1795,8 @@ CRainSystem::CRainSystem(int maxRain) : mAlpha(0.1f), mWindAngle(1.0f), - mFadeAlpha(0.0f) + mFadeAlpha(0.0f), + mIsRaining(false) { char name[256]; @@ -1883,6 +1896,17 @@ SParticle *CRainSystem::GetParticleVariable(int which) return CWorldEffectsSystem::GetParticleVariable(which); } +float CRainSystem::GetFloatVariable(int which) +{ + switch(which) + { + case CRainSystem::RAINSYSTEM_WIND_SPEED: + return mWindAngle * 75.0; // pat scaled + } + + return 0.0; +} + float *CRainSystem::GetVecVariable(int which) { switch(which) @@ -1977,6 +2001,7 @@ void CRainSystem::Update(float elapseTime) if (originContents & CONTENTS_OUTSIDE && !(originContents & CONTENTS_WATER)) { + mIsRaining = true; if (mFadeAlpha < 1.0) { mFadeAlpha += elapseTime / 2.0; @@ -1988,6 +2013,7 @@ void CRainSystem::Update(float elapseTime) } else { + mIsRaining = false; if (mFadeAlpha > 0.0) { mFadeAlpha -= elapseTime / 2.0; @@ -2304,5 +2330,41 @@ bool R_GetWindVector(vec3_t windVector) return true; } + if (snowSystem) + { + VectorCopy(snowSystem->GetVecVariable(CRainSystem::RAINSYSTEM_WIND_DIRECTION), windVector); + return true; + } + + + return false; +} + +bool R_GetWindSpeed(float &windSpeed) +{ + if (rainSystem) + { + windSpeed = rainSystem->GetFloatVariable(CRainSystem::RAINSYSTEM_WIND_SPEED); + return true; + } + + return false; +} + +bool R_IsRaining() +{ + if (rainSystem) + { + return rainSystem->IsRaining(); + } + return false; +} + +bool R_IsSnowing() +{ + if (snowSystem) + { + return snowSystem->IsSnowing(); + } return false; } diff --git a/code/renderer/tr_worldeffects.h b/code/renderer/tr_worldeffects.h index 59dcf51..9ad6f5f 100644 --- a/code/renderer/tr_worldeffects.h +++ b/code/renderer/tr_worldeffects.h @@ -77,6 +77,7 @@ public: virtual int GetIntVariable(int which) { return 0; } virtual SParticle *GetParticleVariable(int which) { return 0; } + virtual float GetFloatVariable(int which) { return 0.0; } virtual float *GetVecVariable(int which) { return 0; } virtual bool Command(const char *command); @@ -95,5 +96,9 @@ void R_WorldEffectCommand(const char *command); void R_WorldEffect_f(void); bool R_GetWindVector(vec3_t windVector); +bool R_GetWindSpeed(float &windSpeed); + +bool R_IsRaining(); +bool R_IsSnowing(); #endif // __TR_WORLDEFFECTS_H diff --git a/code/renderer/vssver.scc b/code/renderer/vssver.scc new file mode 100644 index 0000000..d795f3c Binary files /dev/null and b/code/renderer/vssver.scc differ diff --git a/code/server/server.h b/code/server/server.h index a62fb16..f9a3b48 100644 --- a/code/server/server.h +++ b/code/server/server.h @@ -39,6 +39,7 @@ typedef struct { int snapshotCounter; // incremented for each snapshot built int time; // all entities are correct for this time // These 2 saved out int timeResidual; // <= 1000 / sv_frame->value // during savegame. + float timeResidualFraction; // fraction of a msec accumulated int nextFrameTime; // when time > nextFrameTime, process world // this doesn't get used anywhere! -Ste struct cmodel_s *models[MAX_MODELS]; char *configstrings[MAX_CONFIGSTRINGS]; diff --git a/code/server/sv_init.cpp b/code/server/sv_init.cpp index ade378f..5194f5b 100644 --- a/code/server/sv_init.cpp +++ b/code/server/sv_init.cpp @@ -17,6 +17,7 @@ Ghoul2 Insert Start #include "../qcommon/miniheap.h" #endif +void CM_CleanLeafCache(void); CMiniHeap *G2VertSpaceServer = NULL; /* @@ -249,6 +250,8 @@ void SV_SpawnServer( char *server, ForceReload_e eForceReload, qboolean bAllowSc } sv.time = 1000; + G2API_SetTime(sv.time,G2T_SV_TIME); + CM_LoadMap( va("maps/%s.bsp", server), qfalse, &checksum ); // set serverinfo visible name @@ -275,6 +278,7 @@ void SV_SpawnServer( char *server, ForceReload_e eForceReload, qboolean bAllowSc for ( i = 0 ;i < 3 ; i++ ) { ge->RunFrame( sv.time ); sv.time += 100; + G2API_SetTime(sv.time,G2T_SV_TIME); } // create a baseline for more efficient communications @@ -307,6 +311,7 @@ void SV_SpawnServer( char *server, ForceReload_e eForceReload, qboolean bAllowSc // run another frame to allow things to look at all connected clients ge->RunFrame( sv.time ); sv.time += 100; + G2API_SetTime(sv.time,G2T_SV_TIME); // save systeminfo and serverinfo strings @@ -434,6 +439,9 @@ void SV_Shutdown( char *finalmsg ) { } memset( &svs, 0, sizeof( svs ) ); + // Ensure we free any memory used by the leaf cache. + CM_CleanLeafCache(); + Cvar_Set( "sv_running", "0" ); Com_Printf( "---------------------------\n" ); diff --git a/code/server/sv_main.cpp b/code/server/sv_main.cpp index 2583a08..d9e5ecc 100644 --- a/code/server/sv_main.cpp +++ b/code/server/sv_main.cpp @@ -447,7 +447,8 @@ Player movement occurs as a result of packet events, which happen before SV_Frame is called ================== */ -void SV_Frame( int msec ) { +extern cvar_t *cl_newClock; +void SV_Frame( int msec,float fractionMsec ) { int frameMsec; int startTime=0; @@ -483,6 +484,15 @@ void SV_Frame( int msec ) { frameMsec = 1000 / sv_fps->integer ; sv.timeResidual += msec; + sv.timeResidualFraction+=fractionMsec; + if (sv.timeResidualFraction>=1.0f) + { + sv.timeResidualFraction-=1.0f; + if (cl_newClock&&cl_newClock->integer) + { + sv.timeResidual++; + } + } if ( sv.timeResidual < frameMsec ) { return; } @@ -517,6 +527,7 @@ void SV_Frame( int msec ) { while ( sv.timeResidual >= frameMsec ) { sv.timeResidual -= frameMsec; sv.time += frameMsec; + G2API_SetTime(sv.time,G2T_SV_TIME); // let everything in the world think and move ge->RunFrame( sv.time ); diff --git a/code/server/sv_world.cpp b/code/server/sv_world.cpp index 06ac95d..95aa6d5 100644 --- a/code/server/sv_world.cpp +++ b/code/server/sv_world.cpp @@ -71,34 +71,12 @@ typedef struct worldSector_s { svEntity_t *entities; } worldSector_t; -#define AREA_DEPTH 4 -#define AREA_NODES 64 +#define AREA_DEPTH 8 +#define AREA_NODES 1024 worldSector_t sv_worldSectors[AREA_NODES]; int sv_numworldSectors; - -/* -=============== -SV_SectorList_f -=============== -*/ -void SV_SectorList_f( void ) { - int i, c; - worldSector_t *sec; - svEntity_t *ent; - - for ( i = 0 ; i < AREA_NODES ; i++ ) { - sec = &sv_worldSectors[i]; - - c = 0; - for ( ent = sec->entities ; ent ; ent = ent->nextEntityInWorldSector ) { - c++; - } - Com_Printf( "sector %i: %i entities\n", i, c ); - } -} - /* =============== SV_CreateworldSector @@ -461,7 +439,116 @@ int SV_AreaEntities( const vec3_t mins, const vec3_t maxs, gentity_t **list, int return ap.count; } +/* +=============== +SV_SectorList_f +=============== +*/ +#if 1 +void SV_SectorList_f( void ) { + int i, c; + worldSector_t *sec; + svEntity_t *ent; + + for ( i = 0 ; i < AREA_NODES ; i++ ) { + sec = &sv_worldSectors[i]; + + c = 0; + for ( ent = sec->entities ; ent ; ent = ent->nextEntityInWorldSector ) { + c++; + } + Com_Printf( "sector %i: %i entities\n", i, c ); + } +} + +#else + +#pragma warning (push, 3) //go back down to 3 for the stl include +#include +#include +#pragma warning (pop) +using namespace std; + +class CBBox +{ +public: + float mMins[3]; + float mMaxs[3]; + + CBBox(vec3_t mins,vec3_t maxs) + { + VectorCopy(mins,mMins); + VectorCopy(maxs,mMaxs); + } +}; + +static multimap > > entStats; + +void SV_AreaEntitiesTree( worldSector_t *node, areaParms_t *ap, int level ) +{ + svEntity_t *check, *next; + gentity_t *gcheck; + int count; + list bblist; + + count = 0; + + for ( check = node->entities ; check ; check = next ) + { + next = check->nextEntityInWorldSector; + + gcheck = SV_GEntityForSvEntity( check ); + + CBBox bBox(gcheck->absmin,gcheck->absmax); + bblist.push_back(bBox); + count++; + } + + entStats.insert(pair > >(level,pair >(count,bblist))); + if (node->axis == -1) + { + return; // terminal node + } + + // recurse down both sides + SV_AreaEntitiesTree ( node->children[0], ap, level+1 ); + SV_AreaEntitiesTree ( node->children[1], ap, level+1 ); +} + +void SV_SectorList_f( void ) +{ + areaParms_t ap; + +// ap.mins = mins; +// ap.maxs = maxs; +// ap.list = list; +// ap.count = 0; +// ap.maxcount = maxcount; + + entStats.clear(); + SV_AreaEntitiesTree(sv_worldSectors,&ap,0); + char mess[1000]; + multimap > >::iterator j; + for(j=entStats.begin();j!=entStats.end();j++) + { + sprintf(mess,"**************************************************\n"); + Sleep(5); + OutputDebugString(mess); + sprintf(mess,"level=%i, count=%i\n",(*j).first,(*j).second.first); + Sleep(5); + OutputDebugString(mess); + list::iterator k; + for(k=(*j).second.second.begin();k!=(*j).second.second.end();k++) + { + sprintf(mess,"mins=%f %f %f, maxs=%f %f %f\n", + (*k).mMins[0],(*k).mMins[1],(*k).mMins[2],(*k).mMaxs[0],(*k).mMaxs[1],(*k).mMaxs[2]); + OutputDebugString(mess); + } + } + +} +#endif //=========================================================================== diff --git a/code/server/vssver.scc b/code/server/vssver.scc new file mode 100644 index 0000000..06cdccb Binary files /dev/null and b/code/server/vssver.scc differ diff --git a/code/smartheap/HA312W32.DLL b/code/smartheap/HA312W32.DLL new file mode 100644 index 0000000..2b1ea82 Binary files /dev/null and b/code/smartheap/HA312W32.DLL differ diff --git a/code/smartheap/SHW32.DLL b/code/smartheap/SHW32.DLL new file mode 100644 index 0000000..42b2f67 Binary files /dev/null and b/code/smartheap/SHW32.DLL differ diff --git a/code/smartheap/smrtheap.hpp b/code/smartheap/smrtheap.hpp new file mode 100644 index 0000000..dfc8435 --- /dev/null +++ b/code/smartheap/smrtheap.hpp @@ -0,0 +1,197 @@ +// smrtheap.hpp -- SmartHeap public C++ header file +// Professional Memory Management Library +// +// Copyright (C) 1991-1999 Compuware Corporation. +// All Rights Reserved. +// +// No part of this source code may be copied, modified or reproduced +// in any form without retaining the above copyright notice. +// This source code, or source code derived from it, may not be redistributed +// without express written permission of the copyright owner. +// +// COMMENTS: +// - Include this header file to call the SmartHeap-specific versions of +// operators new (i.e. with placement syntax), to: +// o allocate from a specific memory pool; +// o specify allocation flags, such as zero-initialization; +// o resize an allocation. +// +// - If you include this header file, you must compile and link shnew.cpp, or +// link with one of the SmartHeap static operator new libraries: +// sh[l|d]XXXX.lib +// +// - Can be used in both EXEs and DLLs. +// +// - For 16-bit x86 platforms, use only in large or compact memory model. +// +// - If you do not want to use SmartHeap's global operator new but you do +// want to use SmartHeap's other facilities in a C++ application, then +// include the smrtheap.h header file but do not include this header file, +// and do not link with shnew.cpp. The two ".Xpp" files are present +// ONLY for the purpose of defining operator new and operator delete. +// +// - Use the MemDefaultPool global variable to refer to a memory pool to pass +// to SmartHeap functions that accept a pool as a parameter, +// e.g. MemPoolCount, MemPoolSize, MemPoolWalk, etc. +// + +#if !defined(_SMARTHEAP_HPP) +#define _SMARTHEAP_HPP + +#if defined(_MSC_VER) \ + && (defined(M_I86LM) || defined(M_I86CM) || defined(M_I86HM)) \ + && !defined(MEM_HUGE) +#define MEM_HUGE 0x8000u +#endif + +#ifndef __BORLANDC__ +/* Borland C++ does not treat extern "C++" correctly */ +extern "C++" +{ +#endif /* __BORLANDC__ */ + +#if defined(_MSC_VER) && _MSC_VER >= 900 +#pragma warning(disable : 4507) +#endif + +#if defined(new) +#if defined(MEM_DEBUG) +#undef new +#endif +#endif + +#include + +#include "smrtheap.h" + +#if defined(new) +#if defined(MEM_DEBUG) +#undef new +#endif +#endif + +#if ((defined(__BORLANDC__) && (__BORLANDC__ >= 0x450)) \ + || (defined(__WATCOMC__) && __WATCOMC__ >= 1000) \ + || (defined(__IBMCPP__) && __IBMCPP__ >= 250) \ + || defined(__hpux) \ + || defined(__osf__) \ + || (defined(__SUNPRO_CC) && __SUNPRO_CC >= 0x500) \ + || defined(_AIX43)) +#define SHI_ARRAY_NEW 1 +#define SHI_ARRAY_DELETE 1 +#endif + +#if !(defined(__SUNPRO_CC) && __SUNPRO_CC >= 0x500) +#define SHI_NEWDEFARGS 1 +#endif + +void MEM_FAR * MEM_ENTRY_ANSI shi_New(unsigned long sz, unsigned flags=0, MEM_POOL pool=0); + +// operator new variants: + + +// version of new that passes memory allocation flags +// (e.g. MEM_ZEROINIT to zero-initialize memory) +// call with syntax 'ptr = new (flags) ' +inline void MEM_FAR *operator new(size_t sz, unsigned flags) + { return shi_New(sz, flags); } +#if defined(_MSC_VER) && _MSC_VER >= 1200 +inline void MEM_FAR operator delete(void *p, unsigned) + { ::operator delete(p); } +#endif // _MSC_VER + +// version of new that allocates from a specified memory pool with alloc flags +// call with the syntax 'ptr = new (pool, [flags=0]) ' +inline void MEM_FAR *operator new(size_t sz, MEM_POOL pool, unsigned flags +#ifdef SHI_NEWDEFARGS + =0 +#endif + ) + { return shi_New(sz, flags, pool); } +#if defined(_MSC_VER) && _MSC_VER >= 1200 +inline void MEM_FAR operator delete(void *p, MEM_POOL, unsigned) + { ::operator delete(p); } +#endif // _MSC_VER + +#ifdef SHI_ARRAY_NEW +inline void MEM_FAR *operator new[](size_t sz, MEM_POOL pool, unsigned flags +#ifdef SHI_NEWDEFARGS + =0 +#endif + ) + { return shi_New(sz, flags, pool); } +#endif + +// version of new that changes the size of a memory block previously allocated +// from an SmartHeap memory pool +// call with the syntax 'ptr = new (ptr, flags) ' +#if !defined(__BORLANDC__) && !defined(__HIGHC__) +/* bug in BC++, MetaWare High C++ parsers confuse this with new(file,line) */ +inline void MEM_FAR *operator new(size_t new_sz, void MEM_FAR *lpMem, + unsigned flags) + { return MemReAllocPtr(lpMem, new_sz, flags); } +#if defined(_MSC_VER) && _MSC_VER >= 1200 +inline void MEM_FAR operator delete(void *p, void MEM_FAR *, unsigned) + { ::operator delete(p); } +#endif // _MSC_VER + +#ifdef SHI_ARRAY_NEW +inline void MEM_FAR *operator new[](size_t new_sz, void MEM_FAR *lpMem, + unsigned flags) + { return MemReAllocPtr(lpMem, new_sz, flags); } +#endif // SHI_ARRAY_NEW +#endif + + +// new_handler prototypes: note that MSC/C++ prototype differs from the +// protosed ANSI standard prototype for set_new_handler +#if defined(__MWERKS__) \ + || defined(__hpux) \ + || (defined(__SUNPRO_CC) && __SUNPRO_CC >= 0x500) + +#define MEM_CPP_THROW throw() +#define MEM_CPP_THROW1(x) throw(x) +//#elif defined(_MSC_VER) && _MSC_VER >= 1100 && defined(_CPPUNWIND) +//#define MEM_CPP_THROW throw() +#else +#define MEM_CPP_THROW +#define MEM_CPP_THROW1(x) +#endif // __MWERKS__ +#ifndef _CRTIMP +#define _CRTIMP +#endif // _CRTIMP +#ifdef _MSC_VER +_CRTIMP _PNH MEM_ENTRY_ANSI _set_new_handler(_PNH); +#if UINT_MAX == 0xFFFFu +_PNH MEM_ENTRY_ANSI _set_fnew_handler(_PNH); +_PNHH MEM_ENTRY_ANSI _set_hnew_handler(_PNHH); +#endif // UINT_MAX +#endif // _MSC_VER +typedef void (MEM_ENTRY_ANSI * pnh)(); +_CRTIMP pnh MEM_ENTRY_ANSI set_new_handler(pnh) MEM_CPP_THROW; + +#ifndef DBG_FORMAL +#define DBG_FORMAL +#define DBG_ACTUAL +#ifndef DEBUG_NEW +#define DEBUG_NEW new +#endif // DEBUG_NEW +#define DEBUG_NEW1(x_) new(x_) +#define DEBUG_NEW2(x_, y_) new(x_, y_) +#define DEBUG_NEW3(x_, y_, z_) new(x_, y_, z_) +#define DEBUG_DELETE delete +#endif + +#ifdef DEFINE_NEW_MACRO +#define new DEBUG_NEW +#endif + +#if defined(_MSC_VER) && _MSC_VER >= 900 +#pragma warning(default : 4507) +#endif + +#ifndef __BORLANDC__ +} +#endif /* __BORLANDC__ */ + +#endif /* !defined(_SMARTHEAP_HPP) */ diff --git a/code/smartheap/vssver.scc b/code/smartheap/vssver.scc new file mode 100644 index 0000000..ce22e57 Binary files /dev/null and b/code/smartheap/vssver.scc differ diff --git a/code/starwars.dsp b/code/starwars.dsp index 463ffbf..ed040b3 100644 --- a/code/starwars.dsp +++ b/code/starwars.dsp @@ -186,15 +186,6 @@ SOURCE=.\0_compiled_first\0_SH_Leak.cpp # PROP Default_Filter "" # Begin Source File -SOURCE=".\client\eax\eax-util.cpp" -# SUBTRACT CPP /YX -# End Source File -# Begin Source File - -SOURCE=".\client\eax\eax-util.h" -# End Source File -# Begin Source File - SOURCE=.\client\eax\eax.h # End Source File # Begin Source File @@ -490,6 +481,11 @@ SOURCE=.\game\genericparser2.cpp # End Source File # Begin Source File +SOURCE=.\qcommon\hstring.cpp +# SUBTRACT CPP /YX +# End Source File +# Begin Source File + SOURCE=.\qcommon\md4.cpp # SUBTRACT CPP /YX # End Source File @@ -730,6 +726,10 @@ SOURCE=.\game\genericparser2.h # End Source File # Begin Source File +SOURCE=.\qcommon\hstring.h +# End Source File +# Begin Source File + SOURCE=.\Icarus\ICARUS.h # End Source File # Begin Source File diff --git a/code/tonet.bat b/code/tonet.bat new file mode 100644 index 0000000..d004639 --- /dev/null +++ b/code/tonet.bat @@ -0,0 +1,2 @@ +xcopy/d/y release\jk2sp.exe w:\game +xcopy/d/y release\jk2gamex86.dll w:\game diff --git a/code/tosend.bat b/code/tosend.bat new file mode 100644 index 0000000..31ea74d --- /dev/null +++ b/code/tosend.bat @@ -0,0 +1,4 @@ +xcopy/y finalbuild\jk2sp.exe c:\send\game +xcopy/y finalbuild\jk2gamex86.dll c:\send\game +del/s/q c:\send\game\base\saves +rd c:\send\game\base\saves diff --git a/code/ui/mssccprj.scc b/code/ui/mssccprj.scc new file mode 100644 index 0000000..b702cff --- /dev/null +++ b/code/ui/mssccprj.scc @@ -0,0 +1,5 @@ +SCC = This is a Source Code Control file + +[ui.dsp] +SCC_Aux_Path = "\\ravend\vss_projects\StarWars" +SCC_Project_Name = "$/code/ui", XVOAAAAA diff --git a/code/ui/ui_atoms.cpp b/code/ui/ui_atoms.cpp index 929d984..9ab2ef8 100644 --- a/code/ui/ui_atoms.cpp +++ b/code/ui/ui_atoms.cpp @@ -57,6 +57,9 @@ void UI_SetActiveMenu( const char* menuname,const char *menuID ) return; } + //make sure force-speed and slowmodeath doesn't slow down menus - NOTE: they should reset the timescale when the game un-pauses + Cvar_SetValue( "timescale", 1.0f ); + UI_Cursor_Show(qtrue); // enusure minumum menu data is cached diff --git a/code/ui/ui_main.cpp b/code/ui/ui_main.cpp index 6914e9b..9ff2148 100644 --- a/code/ui/ui_main.cpp +++ b/code/ui/ui_main.cpp @@ -225,8 +225,8 @@ void Text_Paint(float x, float y, float scale, vec4_t color, const char *text, i int iStyleOR = 0; switch (style) { - case ITEM_TEXTSTYLE_NORMAL: iStyleOR = 0;break; // JK2 normal text - case ITEM_TEXTSTYLE_BLINK: iStyleOR = STYLE_BLINK;break; // JK2 fast blinking +// case ITEM_TEXTSTYLE_NORMAL: iStyleOR = 0;break; // JK2 normal text +// case ITEM_TEXTSTYLE_BLINK: iStyleOR = STYLE_BLINK;break; // JK2 fast blinking case ITEM_TEXTSTYLE_PULSE: iStyleOR = STYLE_BLINK;break; // JK2 slow pulsing case ITEM_TEXTSTYLE_SHADOWED: iStyleOR = STYLE_DROPSHADOW;break; // JK2 drop shadow ( need a color for this ) case ITEM_TEXTSTYLE_OUTLINED: iStyleOR = STYLE_DROPSHADOW;break; // JK2 drop shadow ( need a color for this ) @@ -435,11 +435,8 @@ static void UI_RunMenuScript(const char **args) } else if (Q_stricmp(name, "loadAuto") == 0) { - if (s_savedata[s_savegame.currentLine].currentSaveFileName)// && (*s_file_desc_field.field.buffer)) - { - Menus_CloseAll(); - ui.Cmd_ExecuteText( EXEC_APPEND, "load auto\n"); - } + Menus_CloseAll(); + ui.Cmd_ExecuteText( EXEC_APPEND, "load auto\n"); } else if (Q_stricmp(name, "loadgame") == 0) { @@ -828,7 +825,12 @@ void _UI_Init( qboolean inGameLoad ) Menus_CloseAll(); // sets defaults for ui temp cvars - uiInfo.effectsColor = gamecodetoui[(int)trap_Cvar_VariableValue("color")-1]; + uiInfo.effectsColor = (int)trap_Cvar_VariableValue("color")-1; + if (uiInfo.effectsColor < 0) + { + uiInfo.effectsColor = 0; + } + uiInfo.effectsColor = gamecodetoui[uiInfo.effectsColor]; uiInfo.currentCrosshair = (int)trap_Cvar_VariableValue("cg_drawCrosshair"); Cvar_Set("ui_mousePitch", (trap_Cvar_VariableValue("m_pitch") >= 0) ? "0" : "1"); @@ -1198,7 +1200,11 @@ qboolean Asset_Parse(char **buffer) Q_strncpyz( uiInfo.uiDC.Assets.stripedFile, tempStr, sizeof(uiInfo.uiDC.Assets.stripedFile) ); - ui.SP_Register(uiInfo.uiDC.Assets.stripedFile, SP_REGISTER_REQUIRED|SP_REGISTER_MENU); + if (!ui.SP_Register(uiInfo.uiDC.Assets.stripedFile, SP_REGISTER_REQUIRED|SP_REGISTER_MENU)) + { + PC_ParseWarning(va("(.SP file \"%s\" not found)",uiInfo.uiDC.Assets.stripedFile)); + //return qfalse; // hmmm... dunno about this, don't want to break scripts for just missing subtitles + } continue; } @@ -1352,7 +1358,14 @@ static void UI_Update(const char *name) { int val = trap_Cvar_VariableValue(name); - if (Q_stricmp(name, "ui_SetName") == 0) + + if (Q_stricmp(name, "s_khz") == 0) + { + ui.Cmd_ExecuteText( EXEC_APPEND, "snd_restart\n" ); + return; + } + + if (Q_stricmp(name, "ui_SetName") == 0) { Cvar_Set( "name", UI_Cvar_VariableString("ui_Name")); } @@ -1603,11 +1616,11 @@ static void UI_DrawKeyBindStatus(rectDef_t *rect, float scale, vec4_t color, int { if (Display_KeyBindPending()) { - Text_Paint(rect->x, rect->y, scale, color, ui.SP_GetStringTextString(va("%s_WAITINGFORKEY",uiInfo.uiDC.Assets.stripedFile)), 0, textStyle, iFontIndex); + Text_Paint(rect->x, rect->y, scale, color, ui.SP_GetStringTextString("MENUS_WAITINGFORKEY"), 0, textStyle, iFontIndex); } else { - Text_Paint(rect->x, rect->y, scale, color, ui.SP_GetStringTextString(va("%s_ENTERTOCHANGE",uiInfo.uiDC.Assets.stripedFile)), 0, textStyle, iFontIndex); + Text_Paint(rect->x, rect->y, scale, color, ui.SP_GetStringTextString("MENUS_ENTERTOCHANGE"), 0, textStyle, iFontIndex); } } @@ -1726,23 +1739,23 @@ static void UI_OwnerDraw(float x, float y, float w, float h, float text_x, float break; case UI_DATAPAD_MISSION: - ui.Draw_DataPad(DP_OBJECTIVES); ui.Draw_DataPad(DP_HUD); + ui.Draw_DataPad(DP_OBJECTIVES); break; case UI_DATAPAD_WEAPONS: - ui.Draw_DataPad(DP_WEAPONS); ui.Draw_DataPad(DP_HUD); + ui.Draw_DataPad(DP_WEAPONS); break; case UI_DATAPAD_INVENTORY: - ui.Draw_DataPad(DP_INVENTORY); ui.Draw_DataPad(DP_HUD); + ui.Draw_DataPad(DP_INVENTORY); break; case UI_DATAPAD_FORCEPOWERS: - ui.Draw_DataPad(DP_FORCEPOWERS); ui.Draw_DataPad(DP_HUD); + ui.Draw_DataPad(DP_FORCEPOWERS); break; case UI_ALLMAPS_SELECTION://saved game thumbnail @@ -1989,11 +2002,11 @@ int UI_OwnerDrawWidth(int ownerDraw, float scale) case UI_KEYBINDSTATUS: if (Display_KeyBindPending()) { - s = ui.SP_GetStringTextString(va("%s_WAITINGFORKEY",uiInfo.uiDC.Assets.stripedFile)); + s = ui.SP_GetStringTextString("MENUS_WAITINGFORKEY"); } else { - s = ui.SP_GetStringTextString(va("%s_ENTERTOCHANGE",uiInfo.uiDC.Assets.stripedFile)); + s = ui.SP_GetStringTextString("MENUS_ENTERTOCHANGE"); } break; @@ -2154,13 +2167,20 @@ void UI_DataPadMenu(void) UI_InGameMenu ================= */ -void UI_InGameMenu(const char*holoFlag) +void UI_InGameMenu(const char*menuID) { ui.PrecacheScreenshot(); Menus_CloseByName("mainhud"); - Menus_ActivateByName("ingameMainMenu"); + if (menuID) + { + Menus_ActivateByName(menuID); + } + else + { + Menus_ActivateByName("ingameMainMenu"); + } ui.Key_SetCatcher( KEYCATCH_UI ); } @@ -2266,7 +2286,7 @@ void UI_GetVid1Data(void) gl_extensions->value = ui.Cvar_VariableValue("r_allowExtensions"); // Video mode info - video_mode->value = ui.Cvar_VariableValue( "r_mode" ) - 2; + video_mode->value = ui.Cvar_VariableValue( "r_mode" ) - 3; if ( video_mode->value < 0 ) { video_mode->value = 1; @@ -2398,9 +2418,9 @@ void UI_SetVid1Data(const char *menuName) // GL Extensions ui.Cvar_SetValue( "r_allowExtensions", gl_extensions->value ); - // Adding 2 because we don't show 320x200 and MNT_400X300 + // Adding 3 because we don't show 320x200 , 400X300, or 512x384 // Video Resolution Setting - ui.Cvar_SetValue( "r_mode", (video_mode->value + 2) ); + ui.Cvar_SetValue( "r_mode", (video_mode->value + 3) ); // Color Depth switch ( color_depth->value ) @@ -2661,24 +2681,23 @@ void ReadSaveDirectory (void) if (Q_stricmp("auto",holdChar)==0) { Cvar_Set("ui_ResumeOK", "1" ); - continue; } - - s_savedata[s_savegame.saveFileCnt].currentSaveFileName = holdChar; - - // Is this a valid file??? & Get comment of file - result = ui.SG_GetSaveGameComment(s_savedata[s_savegame.saveFileCnt].currentSaveFileName, s_savedata[s_savegame.saveFileCnt].currentSaveFileComments, s_savedata[s_savegame.saveFileCnt].currentSaveFileMap); - if (result != 0) // ignore Bad save game - { - s_savedata[s_savegame.saveFileCnt].currentSaveFileDateTime = result; - - struct tm *localTime; - localTime = localtime( &result ); - strcpy(s_savedata[s_savegame.saveFileCnt].currentSaveFileDateTimeString,asctime( localTime ) ); - s_savegame.saveFileCnt++; - if (s_savegame.saveFileCnt == MAX_SAVELOADFILES) + else + { // Is this a valid file??? & Get comment of file + result = ui.SG_GetSaveGameComment(holdChar, s_savedata[s_savegame.saveFileCnt].currentSaveFileComments, s_savedata[s_savegame.saveFileCnt].currentSaveFileMap); + if (result != 0) // ignore Bad save game { - break; + s_savedata[s_savegame.saveFileCnt].currentSaveFileName = holdChar; + s_savedata[s_savegame.saveFileCnt].currentSaveFileDateTime = result; + + struct tm *localTime; + localTime = localtime( &result ); + strcpy(s_savedata[s_savegame.saveFileCnt].currentSaveFileDateTimeString,asctime( localTime ) ); + s_savegame.saveFileCnt++; + if (s_savegame.saveFileCnt == MAX_SAVELOADFILES) + { + break; + } } } } diff --git a/code/ui/ui_public.h b/code/ui/ui_public.h index 7d278eb..0a39d8d 100644 --- a/code/ui/ui_public.h +++ b/code/ui/ui_public.h @@ -107,7 +107,7 @@ typedef struct { int (*Key_GetCatcher)( void ); void (*Key_SetCatcher)( int catcher ); - void (*SP_Register)( const char *Package, unsigned char Registration ); + qboolean (*SP_Register)( const char *Package, unsigned char Registration ); const char *(*SP_GetStringText)(unsigned short ID); const char *(*SP_GetStringTextString)(const char *Reference); diff --git a/code/ui/ui_shared.cpp b/code/ui/ui_shared.cpp index 17ab8ed..3508c2c 100644 --- a/code/ui/ui_shared.cpp +++ b/code/ui/ui_shared.cpp @@ -3139,9 +3139,7 @@ qboolean ItemParse_stripedFile( itemDef_t *item) Q_strncpyz( uiInfo.uiDC.Assets.stripedFile, tempStr, sizeof(uiInfo.uiDC.Assets.stripedFile) ); - ui.SP_Register(uiInfo.uiDC.Assets.stripedFile, SP_REGISTER_REQUIRED|SP_REGISTER_MENU); - - return qtrue; + return ui.SP_Register(uiInfo.uiDC.Assets.stripedFile, SP_REGISTER_REQUIRED|SP_REGISTER_MENU); } /* @@ -3909,32 +3907,31 @@ typedef struct { static bind_t g_bindings[] = { - {"+scores", K_TAB, -1, -1, -1}, - {"+button1", K_F1, -1, -1, -1}, {"invuse", K_ENTER, -1, -1, -1}, {"force_throw", K_F1, -1, -1, -1}, {"force_pull", K_F2, -1, -1, -1}, - {"force_speed", K_F5, -1, -1, -1}, - {"force_heal", K_F3, -1, -1, -1}, - {"+force_grip", K_F5, -1, -1, -1}, + {"force_speed", K_F3, -1, -1, -1}, {"force_distract", K_F4, -1, -1, -1}, - {"+force_lightning",K_F6, -1, -1, -1}, + {"force_heal", K_F5, -1, -1, -1}, + {"+force_grip", K_F6, -1, -1, -1}, + {"+force_lightning",K_F7, -1, -1, -1}, + {"+useforce", 'f', -1, -1, -1}, + {"forceprev", 'z', -1, -1, -1}, + {"forcenext", 'x', -1, -1, -1}, {"use_bacta", -1, -1, -1, -1}, - {"use_electrobinoculars",-1, -1, -1, -1}, - {"use_inquisitor", -1, -1, -1, -1}, - {"use_lightamp_goggles",-1, -1, -1, -1}, + {"use_seeker", -1, -1, -1, -1}, {"use_sentry", -1, -1, -1, -1}, + {"use_lightamp_goggles",-1, -1, -1, -1}, + {"use_electrobinoculars",-1, -1, -1, -1}, {"invnext", -1, -1, -1, -1}, {"invprev", -1, -1, -1, -1}, {"invuse", -1, -1, -1, -1}, - {"forcenext", K_F6, -1, -1, -1}, - {"forceprev", K_F6, -1, -1, -1}, {"+speed", K_SHIFT, -1, -1, -1}, {"+forward", K_UPARROW, -1, -1, -1}, {"+back", K_DOWNARROW, -1, -1, -1}, {"+moveleft", ',', -1, -1, -1}, {"+moveright", '.', -1, -1, -1}, - {"+moveup", K_SPACE, -1, -1, -1}, + {"+moveup", 'v', -1, -1, -1}, {"+movedown", 'c', -1, -1, -1}, {"+left", K_LEFTARROW, -1, -1, -1}, {"+right", K_RIGHTARROW, -1, -1, -1}, @@ -3944,6 +3941,7 @@ static bind_t g_bindings[] = {"+mlook", '/', -1, -1, -1}, {"centerview", K_END, -1, -1, -1}, {"zoom", -1, -1, -1, -1}, + {"weapon 0", -1, -1, -1, -1}, {"weapon 1", '1', -1, -1, -1}, {"weapon 2", '2', -1, -1, -1}, {"weapon 3", '3', -1, -1, -1}, @@ -3961,38 +3959,17 @@ static bind_t g_bindings[] = {"+altattack", -1, -1, -1, -1}, {"weapprev", '[', -1, -1, -1}, {"weapnext", ']', -1, -1, -1}, - {"+button3", K_MOUSE3, -1, -1, -1}, - {"prevTeamMember", 'w', -1, -1, -1}, - {"nextTeamMember", 'r', -1, -1, -1}, - {"nextOrder", 't', -1, -1, -1}, - {"confirmOrder", 'y', -1, -1, -1}, - {"denyOrder", 'n', -1, -1, -1}, - {"taskOffense", 'o', -1, -1, -1}, - {"taskDefense", 'd', -1, -1, -1}, - {"taskPatrol", 'p', -1, -1, -1}, - {"taskCamp", 'c', -1, -1, -1}, - {"taskFollow", 'f', -1, -1, -1}, - {"taskRetrieve", 'v', -1, -1, -1}, - {"taskEscort", 'e', -1, -1, -1}, - {"taskOwnFlag", 'i', -1, -1, -1}, - {"taskSuicide", 'k', -1, -1, -1}, - {"tauntKillInsult", K_F1, -1, -1, -1}, - {"tauntPraise", K_F2, -1, -1, -1}, - {"tauntTaunt", K_F3, -1, -1, -1}, - {"tauntDeathInsult", K_F4, -1, -1, -1}, - {"tauntGauntlet", K_F5, -1, -1, -1}, - {"scoresUp", K_KP_PGUP, -1, -1, -1}, - {"scoresDown", K_KP_PGDN, -1, -1, -1}, - {"messagemode", '-1', -1, -1, -1}, - {"messagemode2", -1, -1, -1, -1}, - {"messagemode3", -1, -1, -1, -1}, - {"messagemode4", -1, -1, -1, -1}, - {"+use", -1, -1, -1, -1}, - {"+useforce", -1, -1, -1, -1}, - {"datapad", -1, -1, -1, -1}, + {"+block", -1, -1, -1, -1}, + {"+use", K_SPACE, -1, -1, -1}, + {"datapad", K_TAB, -1, -1, -1}, {"save quik*", -1, -1, -1, -1}, - {"thirdperson", -1, -1, -1, -1}, - {"exitview", -1, -1, -1, -1} + {"load quik", -1, -1, -1, -1}, + {"load auto", -1, -1, -1, -1}, + {"cg_thirdperson !",-1, -1, -1, -1}, + {"exitview", -1, -1, -1, -1}, + {"uimenu loadmenu", -1, -1, -1, -1}, + {"uimenu savemenu", -1, -1, -1, -1}, + {"saberAttackCycle",-1, -1, -1, -1}, }; @@ -5151,7 +5128,7 @@ void BindingFromName(const char *cvar) DC->keynumToStringBuf( b2, g_nameBind2, 32 ); Q_strupr(g_nameBind2); - strcat( g_nameBind1, va(" %s ",ui.SP_GetStringTextString(va("%s_OR",uiInfo.uiDC.Assets.stripedFile))) ); + strcat( g_nameBind1, va(" %s ",ui.SP_GetStringTextString("MENUS_OR")) ); strcat( g_nameBind1, g_nameBind2 ); } return; @@ -5209,11 +5186,11 @@ void Item_Bind_Paint(itemDef_t *item) { Item_Text_Paint(item); BindingFromName(item->cvar); - DC->drawText(item->textRect.x + item->textRect.w + 8, item->textRect.y, item->textscale, newColor, g_nameBind1, /*maxChars*/item->textRect.w, item->textStyle, item->font); + DC->drawText(item->textRect.x + item->textRect.w + 8, item->textRect.y, item->textscale, newColor, g_nameBind1, maxChars/*item->textRect.w*/, item->textStyle, item->font); } else { - DC->drawText(item->textRect.x, item->textRect.y, item->textscale, newColor, (value != 0) ? "FIXME 1" : "FIXME 0", /*maxChars*/item->textRect.w, item->textStyle, item->font); + DC->drawText(item->textRect.x, item->textRect.y, item->textscale, newColor, (value != 0) ? "FIXME 1" : "FIXME 0", maxChars/*item->textRect.w*/, item->textStyle, item->font); } } @@ -6889,6 +6866,10 @@ qboolean Item_Bind_HandleKey(itemDef_t *item, int key, qboolean down) } } + else if (down && (key == K_ESCAPE)) + { + return qfalse; + } return qtrue; } else @@ -8118,7 +8099,7 @@ qboolean Item_Slider_HandleKey(itemDef_t *item, int key, qboolean down) } } } - DC->Print("slider handle key exit\n"); + //DC->Print("slider handle key exit\n"); return qfalse; } diff --git a/code/ui/vssver.scc b/code/ui/vssver.scc new file mode 100644 index 0000000..93927ab Binary files /dev/null and b/code/ui/vssver.scc differ diff --git a/code/unix/Makefile b/code/unix/Makefile new file mode 100644 index 0000000..5c8dda8 --- /dev/null +++ b/code/unix/Makefile @@ -0,0 +1,988 @@ +# +# Quake3 Unix Makefile +# +# Currently build for the following: +# Linux i386 (full client) +# Linux Alpha (dedicated server only) +# SGI IRIX (full client) +# +# Nov '98 by Zoid +# +# GNU Make required +# + +PLATFORM=$(shell uname|tr '[:upper:]' '[:lower:]') +PLATFORM_RELEASE=$(shell uname -r) + +### +### These paths are where you probably want to change things +### + +# Where we are building to, libMesaVoodooGL.so.3.1 should be here, etc. +# the demo pk3 file should be here in demoq3/pak0.pk3 or baseq3/pak0.pk3 +BUILD_DIR=/home/zoid/Quake3 + +# Where we are building from (where the source code should be!) +MOUNT_DIR=/devel/Quake3/q3code + +############################################################################# +## +## You shouldn't have to touch anything below here +## +############################################################################# + +DEMO_PAK=$(BUILD_DIR)/demoq3/pak0.pk3 + +BUILD_DEBUG_DIR=debug$(ARCH)$(GLIBC) +BUILD_RELEASE_DIR=release$(ARCH)$(GLIBC) +CLIENT_DIR=$(MOUNT_DIR)/client +SERVER_DIR=$(MOUNT_DIR)/server +REF_DIR=$(MOUNT_DIR)/renderer +COMMON_DIR=$(MOUNT_DIR)/qcommon +UNIX_DIR=$(MOUNT_DIR)/unix +GAME_DIR=$(MOUNT_DIR)/game +CGAME_DIR=$(MOUNT_DIR)/cgame +NULL_DIR=$(MOUNT_DIR)/null + +#used for linux i386 builds +MESA_DIR=/usr/local/src/Mesa-3.0 + +VERSION=1.05 + +VERSION_FN=$(VERSION)$(GLIBC) +RPM_RELEASE=9 + +############################################################################# +# SETUP AND BUILD +############################################################################# + +ifeq ($(PLATFORM),irix) + +ARCH=mips #default to MIPS +VENDOR=sgi +GLIBC= #libc is irrelevant + +CC=cc +BASE_CFLAGS=-Dstricmp=strcasecmp -Xcpluscomm -woff 1185 -mips3 \ + -nostdinc -I. -I$(ROOT)/usr/include +RELEASE_CFLAGS=$(BASE_CFLAGS) -O3 +DEBUG_CFLAGS=$(BASE_CFLAGS) -g + +SHLIBEXT=so +SHLIBCFLAGS= +SHLIBLDFLAGS=-shared + +LDFLAGS=-ldl -lm +GLLDFLAGS=-L/usr/X11/lib -lGL -lX11 -lXext -lm + +TARGETS=$(BUILDDIR)/sgiquake3 \ + $(BUILDDIR)/qagame$(ARCH).$(SHLIBEXT) \ + $(BUILDDIR)/cgame$(ARCH).$(SHLIBEXT) + +else +ifeq ($(PLATFORM),linux) + +ifneq (,$(findstring libc6,$(shell if [ -e /lib/libc.so.6* ];then echo libc6;fi))) +GLIBC=-glibc +else +GLIBC= +endif #libc6 test + + +ifneq (,$(findstring alpha,$(shell uname -m))) +ARCH=axp +RPMARCH=alpha +VENDOR=dec +else #default to i386 +ARCH=i386 +RPMARCH=i386 +VENDOR=unknown +endif #alpha test + +BASE_CFLAGS=-Dstricmp=strcasecmp -I$(MESA_DIR)/include -I/usr/include/glide \ + -DREF_HARD_LINKED -pipe + +DEBUG_CFLAGS=$(BASE_CFLAGS) -g +ifeq ($(ARCH),axp) +RELEASE_CFLAGS=$(BASE_CFLAGS) -DNDEBUG -O6 -ffast-math -funroll-loops -fomit-frame-pointer -fexpensive-optimizations +else +RELEASE_CFLAGS=$(BASE_CFLAGS) -DNDEBUG -O3 -m486 -fomit-frame-pointer -pipe -ffast-math -fexpensive-optimizations -malign-loops=2 -malign-jumps=2 -malign-functions=2 +endif + +CC=gcc + +SHLIBEXT=so +SHLIBCFLAGS=-fPIC +SHLIBLDFLAGS=-shared + +LDFLAGS=-ldl -lm +GLLDFLAGS=-L/usr/X11R6/lib -L$(MESA_DIR)/lib -lX11 -lXext -lXxf86dga -lXxf86vm +GL_SVGA_LDFLAGS=-L/usr/X11R6/lib -L$(MESA_DIR)/lib -lX11 -lXext -lvga + +ifeq ($(ARCH),axp) +TARGETS=$(BUILDDIR)/linuxq3ded $(BUILDDIR)/qagame$(ARCH).$(SHLIBEXT) +else +# $(BUILDDIR)/linuxquake3.vga +TARGETS=\ + $(BUILDDIR)/linuxquake3 \ + $(BUILDDIR)/qagame$(ARCH).$(SHLIBEXT) \ + $(BUILDDIR)/cgame$(ARCH).$(SHLIBEXT) +#$(BUILDDIR)/quake3 +endif + + +else #generic + +CC=cc +BASE_CFLAGS=-Dstricmp=strcasecmp +DEBUG_CFLAGS=$(BASE_CFLAGS) -g +RELEASE_CFLAGS=$(BASE_CFLAGS) -DNDEBUG -O + +SHLIBEXT=so +SHLIBCFLAGS=-fPIC +SHLIBLDFLAGS=-shared + +LDFLAGS=-ldl -lm + +TARGETS=$(BUILDDIR)/q3ded $(BUILDDIR)/qagame$(ARCH).$(SHLIBEXT) + +endif #Linux +endif #IRIX + +DO_CC=$(CC) $(CFLAGS) -o $@ -c $< +DO_DEBUG_CC=$(CC) $(DEBUG_CFLAGS) -o $@ -c $< +DO_SHLIB_CC=$(CC) $(CFLAGS) $(SHLIBCFLAGS) -o $@ -c $< +DO_SHLIB_DEBUG_CC=$(CC) $(DEBUG_CFLAGS) $(SHLIBCFLAGS) -o $@ -c $< +DO_AS=$(CC) $(CFLAGS) -DELF -x assembler-with-cpp -o $@ -c $< + +#### DEFAULT TARGET +# default: build_release + +build_debug: + $(MAKE) targets BUILDDIR=$(BUILD_DEBUG_DIR) CFLAGS="$(DEBUG_CFLAGS)" + +build_release: + $(MAKE) targets BUILDDIR=$(BUILD_RELEASE_DIR) CFLAGS="$(RELEASE_CFLAGS)" + +#Build both debug and release builds +all: build_debug build_release + +targets: makedirs $(TARGETS) + +makedirs: + @if [ ! -d $(BUILDDIR) ];then mkdir $(BUILDDIR);fi + @if [ ! -d $(BUILDDIR)/client ];then mkdir $(BUILDDIR)/client;fi + @if [ ! -d $(BUILDDIR)/ded ];then mkdir $(BUILDDIR)/ded;fi + @if [ ! -d $(BUILDDIR)/ref ];then mkdir $(BUILDDIR)/ref;fi + @if [ ! -d $(BUILDDIR)/game ];then mkdir $(BUILDDIR)/game;fi + @if [ ! -d $(BUILDDIR)/cgame ];then mkdir $(BUILDDIR)/cgame;fi + +############################################################################# +# CLIENT/SERVER +############################################################################# + +QUAKE3_OBJS = \ + $(BUILDDIR)/client/cl_cgame.o \ + $(BUILDDIR)/client/cl_cin.o \ + $(BUILDDIR)/client/cl_console.o \ + $(BUILDDIR)/client/cl_input.o \ + $(BUILDDIR)/client/cl_keys.o \ + $(BUILDDIR)/client/cl_main.o \ + $(BUILDDIR)/client/cl_parse.o \ + $(BUILDDIR)/client/cl_scrn.o \ + $(BUILDDIR)/client/snd_dma.o \ + $(BUILDDIR)/client/snd_mem.o \ + $(BUILDDIR)/client/snd_mix.o \ + $(BUILDDIR)/client/sv_bot.o \ + $(BUILDDIR)/client/sv_client.o \ + $(BUILDDIR)/client/sv_ccmds.o \ + $(BUILDDIR)/client/sv_game.o \ + $(BUILDDIR)/client/sv_init.o \ + $(BUILDDIR)/client/sv_main.o \ + $(BUILDDIR)/client/sv_snapshot.o \ + $(BUILDDIR)/client/sv_world.o \ + $(BUILDDIR)/client/ui_arena.o \ + $(BUILDDIR)/client/ui_connect.o \ + $(BUILDDIR)/client/ui_controls.o \ + $(BUILDDIR)/client/ui_demo.o \ + $(BUILDDIR)/client/ui_maps.o \ + $(BUILDDIR)/client/ui_menu.o \ + $(BUILDDIR)/client/ui_network.o \ + $(BUILDDIR)/client/ui_preferences.o \ + $(BUILDDIR)/client/ui_qmenu.o \ + $(BUILDDIR)/client/ui_servers.o \ + $(BUILDDIR)/client/ui_startserver.o \ + $(BUILDDIR)/client/ui_video.o \ + \ + $(BUILDDIR)/client/cm_load.o \ + $(BUILDDIR)/client/cm_patch.o \ + $(BUILDDIR)/client/cm_polylib.o \ + $(BUILDDIR)/client/cm_tag.o \ + $(BUILDDIR)/client/cm_test.o \ + $(BUILDDIR)/client/cm_trace.o \ + $(BUILDDIR)/client/cmd.o \ + $(BUILDDIR)/client/common.o \ + $(BUILDDIR)/client/cvar.o \ + $(BUILDDIR)/client/files.o \ + $(BUILDDIR)/client/gameinfo.o \ + $(BUILDDIR)/client/md4.o \ + $(BUILDDIR)/client/msg.o \ + $(BUILDDIR)/client/net_chan.o \ + $(BUILDDIR)/client/vm.o \ + \ + $(BUILDDIR)/client/q_shared.o \ + $(BUILDDIR)/client/q_math.o \ + \ + $(BUILDDIR)/client/tr_backend.o \ + $(BUILDDIR)/client/tr_bsp.o \ + $(BUILDDIR)/client/tr_calc.o \ + $(BUILDDIR)/client/tr_calc_3dnow.o \ + $(BUILDDIR)/client/tr_calc_c.o \ + $(BUILDDIR)/client/tr_calc_kni.o \ + $(BUILDDIR)/client/tr_cmds.o \ + $(BUILDDIR)/client/tr_curve.o \ + $(BUILDDIR)/client/tr_draw.o \ + $(BUILDDIR)/client/tr_flares.o \ + $(BUILDDIR)/client/tr_image.o \ + $(BUILDDIR)/client/tr_init.o \ + $(BUILDDIR)/client/tr_light.o \ + $(BUILDDIR)/client/tr_main.o \ + $(BUILDDIR)/client/tr_mesh.o \ + $(BUILDDIR)/client/tr_misc.o \ + $(BUILDDIR)/client/tr_model.o \ + $(BUILDDIR)/client/tr_noise.o \ + $(BUILDDIR)/client/tr_scene.o \ + $(BUILDDIR)/client/tr_shade.o \ + $(BUILDDIR)/client/tr_shader.o \ + $(BUILDDIR)/client/tr_shade_calc.o \ + $(BUILDDIR)/client/tr_shadows.o \ + $(BUILDDIR)/client/tr_smp.o \ + $(BUILDDIR)/client/tr_sky.o \ + $(BUILDDIR)/client/tr_surf.o \ + $(BUILDDIR)/client/tr_world.o \ + \ + $(BUILDDIR)/client/unix_main.o \ + $(BUILDDIR)/client/unix_net.o \ + $(BUILDDIR)/client/unix_shared.o + +#platform specific objects +ifeq ($(PLATFORM),irix) + QUAKE3_PLATOBJ=\ + $(BUILDDIR)/client/irix_qgl.o \ + $(BUILDDIR)/client/irix_glimp.o \ + $(BUILDDIR)/client/irix_snd.o +else +ifeq ($(PLATFORM),linux) +ifeq ($(ARCH),axp) + QUAKE3_PLATOBJ= +else + QUAKE3_PLATOBJ=\ + $(BUILDDIR)/client/linux_qgl.o \ + $(BUILDDIR)/client/linux_glimp.o \ + $(BUILDDIR)/client/linux_snd.o \ + $(BUILDDIR)/client/snd_mixa.o \ + $(BUILDDIR)/client/matha.o \ + $(BUILDDIR)/client/sys_dosa.o + QUAKE3_VGA=\ + $(BUILDDIR)/client/linux_qgl.o \ + $(BUILDDIR)/client/linux_glimp_vga.o \ + $(BUILDDIR)/client/linux_input_vga.o \ + $(BUILDDIR)/client/linux_snd.o \ + $(BUILDDIR)/client/snd_mixa.o \ + $(BUILDDIR)/client/matha.o \ + $(BUILDDIR)/client/sys_dosa.o + +endif +endif #Linux +endif #IRIX + + +$(BUILDDIR)/linuxquake3 : $(QUAKE3_OBJS) $(QUAKE3_PLATOBJ) + $(CC) $(CFLAGS) -o $@ $(QUAKE3_OBJS) $(QUAKE3_PLATOBJ) $(GLLDFLAGS) $(LDFLAGS) + +ifeq ($(PLATFORM),linux) +ifeq ($(ARCH),i386) +$(BUILDDIR)/linuxquake3.vga : $(QUAKE3_OBJS) $(QUAKE3_VGA) + $(CC) $(CFLAGS) -o $@ $(QUAKE3_OBJS) $(QUAKE3_VGA) $(GL_SVGA_LDFLAGS) $(LDFLAGS) +endif +endif + +$(BUILDDIR)/client/cl_cgame.o : $(CLIENT_DIR)/cl_cgame.c + $(DO_CC) + +$(BUILDDIR)/client/cl_cin.o : $(CLIENT_DIR)/cl_cin.c + $(DO_CC) + +$(BUILDDIR)/client/cl_console.o : $(CLIENT_DIR)/cl_console.c + $(DO_CC) + +$(BUILDDIR)/client/cl_input.o : $(CLIENT_DIR)/cl_input.c + $(DO_CC) + +$(BUILDDIR)/client/cl_keys.o : $(CLIENT_DIR)/cl_keys.c + $(DO_CC) + +$(BUILDDIR)/client/cl_main.o : $(CLIENT_DIR)/cl_main.c + $(DO_CC) + +$(BUILDDIR)/client/cl_parse.o : $(CLIENT_DIR)/cl_parse.c + $(DO_CC) + +$(BUILDDIR)/client/cl_scrn.o : $(CLIENT_DIR)/cl_scrn.c + $(DO_CC) + +$(BUILDDIR)/client/snd_dma.o : $(CLIENT_DIR)/snd_dma.c + $(DO_CC) + +$(BUILDDIR)/client/snd_mem.o : $(CLIENT_DIR)/snd_mem.c + $(DO_CC) + +$(BUILDDIR)/client/snd_mix.o : $(CLIENT_DIR)/snd_mix.c + $(DO_CC) + +$(BUILDDIR)/client/sv_bot.o : $(SERVER_DIR)/sv_bot.c + $(DO_CC) + +$(BUILDDIR)/client/sv_client.o : $(SERVER_DIR)/sv_client.c + $(DO_CC) + +$(BUILDDIR)/client/sv_ccmds.o : $(SERVER_DIR)/sv_ccmds.c + $(DO_CC) + +$(BUILDDIR)/client/sv_game.o : $(SERVER_DIR)/sv_game.c + $(DO_CC) + +$(BUILDDIR)/client/sv_init.o : $(SERVER_DIR)/sv_init.c + $(DO_CC) + +$(BUILDDIR)/client/sv_main.o : $(SERVER_DIR)/sv_main.c + $(DO_CC) + +$(BUILDDIR)/client/sv_snapshot.o : $(SERVER_DIR)/sv_snapshot.c + $(DO_CC) + +$(BUILDDIR)/client/sv_world.o : $(SERVER_DIR)/sv_world.c + $(DO_CC) + +$(BUILDDIR)/client/ui_arena.o : $(CLIENT_DIR)/ui_arena.c + $(DO_CC) + +$(BUILDDIR)/client/ui_connect.o : $(CLIENT_DIR)/ui_connect.c + $(DO_CC) + +$(BUILDDIR)/client/ui_controls.o : $(CLIENT_DIR)/ui_controls.c + $(DO_CC) + +$(BUILDDIR)/client/ui_demo.o : $(CLIENT_DIR)/ui_demo.c + $(DO_CC) + +$(BUILDDIR)/client/ui_maps.o : $(CLIENT_DIR)/ui_maps.c + $(DO_CC) + +$(BUILDDIR)/client/ui_menu.o : $(CLIENT_DIR)/ui_menu.c + $(DO_CC) + +$(BUILDDIR)/client/ui_network.o : $(CLIENT_DIR)/ui_network.c + $(DO_CC) + +$(BUILDDIR)/client/ui_preferences.o : $(CLIENT_DIR)/ui_preferences.c + $(DO_CC) + +$(BUILDDIR)/client/ui_qmenu.o : $(CLIENT_DIR)/ui_qmenu.c + $(DO_CC) + +$(BUILDDIR)/client/ui_servers.o : $(CLIENT_DIR)/ui_servers.c + $(DO_CC) + +$(BUILDDIR)/client/ui_startserver.o : $(CLIENT_DIR)/ui_startserver.c + $(DO_CC) + +$(BUILDDIR)/client/ui_video.o : $(UNIX_DIR)/ui_video.c + $(DO_CC) + +$(BUILDDIR)/client/cm_trace.o : $(COMMON_DIR)/cm_trace.c + $(DO_CC) + +$(BUILDDIR)/client/cm_load.o : $(COMMON_DIR)/cm_load.c + $(DO_CC) + +$(BUILDDIR)/client/cm_test.o : $(COMMON_DIR)/cm_test.c + $(DO_CC) + +$(BUILDDIR)/client/cm_patch.o : $(COMMON_DIR)/cm_patch.c + $(DO_CC) + +$(BUILDDIR)/client/cm_polylib.o : $(COMMON_DIR)/cm_polylib.c + $(DO_CC) + +$(BUILDDIR)/client/cm_tag.o : $(COMMON_DIR)/cm_tag.c + $(DO_CC) + +$(BUILDDIR)/client/cmd.o : $(COMMON_DIR)/cmd.c + $(DO_CC) + +$(BUILDDIR)/client/common.o : $(COMMON_DIR)/common.c + $(DO_CC) + +$(BUILDDIR)/client/cvar.o : $(COMMON_DIR)/cvar.c + $(DO_CC) + +$(BUILDDIR)/client/files.o : $(COMMON_DIR)/files.c + $(DO_CC) + +$(BUILDDIR)/client/gameinfo.o : $(COMMON_DIR)/gameinfo.c + $(DO_CC) + +$(BUILDDIR)/client/md4.o : $(COMMON_DIR)/md4.c + $(DO_CC) + +$(BUILDDIR)/client/msg.o : $(COMMON_DIR)/msg.c + $(DO_CC) + +$(BUILDDIR)/client/net_chan.o : $(COMMON_DIR)/net_chan.c + $(DO_CC) + +$(BUILDDIR)/client/vm.o : $(COMMON_DIR)/vm.c + $(DO_CC) + +$(BUILDDIR)/client/q_shared.o : $(GAME_DIR)/q_shared.c + $(DO_DEBUG_CC) + +$(BUILDDIR)/client/q_math.o : $(GAME_DIR)/q_math.c + $(DO_CC) + +$(BUILDDIR)/client/tr_bsp.o : $(REF_DIR)/tr_bsp.c + $(DO_CC) + +$(BUILDDIR)/client/tr_backend.o : $(REF_DIR)/tr_backend.c + $(DO_CC) + +$(BUILDDIR)/client/tr_calc.o : $(REF_DIR)/tr_calc.c + $(DO_CC) + +$(BUILDDIR)/client/tr_calc_3dnow.o : $(REF_DIR)/tr_calc_3dnow.c + $(DO_CC) + +$(BUILDDIR)/client/tr_calc_c.o : $(REF_DIR)/tr_calc_c.c + $(DO_CC) + +$(BUILDDIR)/client/tr_calc_kni.o : $(REF_DIR)/tr_calc_kni.c + $(DO_CC) + +$(BUILDDIR)/client/tr_cmds.o : $(REF_DIR)/tr_cmds.c + $(DO_CC) + +$(BUILDDIR)/client/tr_curve.o : $(REF_DIR)/tr_curve.c + $(DO_CC) + +$(BUILDDIR)/client/tr_draw.o : $(REF_DIR)/tr_draw.c + $(DO_CC) + +$(BUILDDIR)/client/tr_flares.o : $(REF_DIR)/tr_flares.c + $(DO_CC) + +$(BUILDDIR)/client/tr_image.o : $(REF_DIR)/tr_image.c + $(DO_CC) + +$(BUILDDIR)/client/tr_init.o : $(REF_DIR)/tr_init.c + $(DO_CC) + +$(BUILDDIR)/client/tr_light.o : $(REF_DIR)/tr_light.c + $(DO_CC) + +$(BUILDDIR)/client/tr_main.o : $(REF_DIR)/tr_main.c + $(DO_CC) + +$(BUILDDIR)/client/tr_mesh.o : $(REF_DIR)/tr_mesh.c + $(DO_CC) + +$(BUILDDIR)/client/tr_misc.o : $(REF_DIR)/tr_misc.c + $(DO_CC) + +$(BUILDDIR)/client/tr_model.o : $(REF_DIR)/tr_model.c + $(DO_CC) + +$(BUILDDIR)/client/tr_noise.o : $(REF_DIR)/tr_noise.c + $(DO_CC) + +$(BUILDDIR)/client/tr_scene.o : $(REF_DIR)/tr_scene.c + $(DO_CC) + +$(BUILDDIR)/client/tr_shade.o : $(REF_DIR)/tr_shade.c + $(DO_CC) + +$(BUILDDIR)/client/tr_shader.o : $(REF_DIR)/tr_shader.c + $(DO_CC) + +$(BUILDDIR)/client/tr_shade_calc.o : $(REF_DIR)/tr_shade_calc.c + $(DO_CC) + +$(BUILDDIR)/client/tr_shadows.o : $(REF_DIR)/tr_shadows.c + $(DO_CC) + +$(BUILDDIR)/client/tr_sky.o : $(REF_DIR)/tr_sky.c + $(DO_CC) + +$(BUILDDIR)/client/tr_smp.o : $(REF_DIR)/tr_smp.c + $(DO_CC) + +$(BUILDDIR)/client/tr_stripify.o : $(REF_DIR)/tr_stripify.c + $(DO_CC) + +$(BUILDDIR)/client/tr_subdivide.o : $(REF_DIR)/tr_subdivide.c + $(DO_CC) + +$(BUILDDIR)/client/tr_surf.o : $(REF_DIR)/tr_surf.c + $(DO_CC) + +$(BUILDDIR)/client/tr_world.o : $(REF_DIR)/tr_world.c + $(DO_CC) + +$(BUILDDIR)/client/unix_qgl.o : $(UNIX_DIR)/unix_qgl.c + $(DO_CC) + +$(BUILDDIR)/client/unix_dedicated.o : $(UNIX_DIR)/unix_dedicated.c + $(DO_CC) + +$(BUILDDIR)/client/unix_earlycon.o : $(UNIX_DIR)/unix_earlycon.c + $(DO_CC) + +$(BUILDDIR)/client/unix_main.o : $(UNIX_DIR)/unix_main.c + $(DO_CC) + +$(BUILDDIR)/client/unix_net.o : $(UNIX_DIR)/unix_net.c + $(DO_CC) + +$(BUILDDIR)/client/unix_shared.o : $(UNIX_DIR)/unix_shared.c + $(DO_CC) + +$(BUILDDIR)/client/irix_glimp.o : $(UNIX_DIR)/irix_glimp.c + $(DO_CC) + +$(BUILDDIR)/client/irix_snd.o : $(UNIX_DIR)/irix_snd.c + $(DO_CC) + +$(BUILDDIR)/client/irix_input.o : $(UNIX_DIR)/irix_input.c + $(DO_CC) + +$(BUILDDIR)/client/linux_glimp.o : $(UNIX_DIR)/linux_glimp.c + $(DO_CC) + +$(BUILDDIR)/client/linux_qgl.o : $(UNIX_DIR)/linux_qgl.c + $(DO_CC) + +$(BUILDDIR)/client/linux_input.o : $(UNIX_DIR)/linux_input.c + $(DO_CC) + +$(BUILDDIR)/client/linux_glimp_vga.o : $(UNIX_DIR)/linux_glimp_vga.c + $(DO_CC) + +$(BUILDDIR)/client/linux_snd.o : $(UNIX_DIR)/linux_snd.c + $(DO_CC) + +$(BUILDDIR)/client/snd_mixa.o : $(UNIX_DIR)/snd_mixa.s + $(DO_AS) + +$(BUILDDIR)/client/matha.o : $(UNIX_DIR)/matha.s + $(DO_AS) + +$(BUILDDIR)/client/sys_dosa.o : $(UNIX_DIR)/sys_dosa.s + $(DO_AS) + +$(BUILDDIR)/client/linux_input_vga.o : $(UNIX_DIR)/linux_input_vga.c + $(DO_CC) + +############################################################################# +# DEDICATED SERVER +############################################################################# + +Q3DED_OBJS = \ + $(BUILDDIR)/ded/sv_bot.o \ + $(BUILDDIR)/ded/sv_client.o \ + $(BUILDDIR)/ded/sv_ccmds.o \ + $(BUILDDIR)/ded/sv_game.o \ + $(BUILDDIR)/ded/sv_init.o \ + $(BUILDDIR)/ded/sv_main.o \ + $(BUILDDIR)/ded/sv_snapshot.o \ + $(BUILDDIR)/ded/sv_world.o \ + \ + $(BUILDDIR)/ded/cm_trace.o \ + $(BUILDDIR)/ded/cm_load.o \ + $(BUILDDIR)/ded/cm_test.o \ + $(BUILDDIR)/ded/cm_patch.o \ + $(BUILDDIR)/ded/cm_tag.o \ + $(BUILDDIR)/ded/cmd.o \ + $(BUILDDIR)/ded/common.o \ + $(BUILDDIR)/ded/cvar.o \ + $(BUILDDIR)/ded/files.o \ + $(BUILDDIR)/ded/gameinfo.o \ + $(BUILDDIR)/ded/md4.o \ + $(BUILDDIR)/ded/msg.o \ + $(BUILDDIR)/ded/net_chan.o \ + \ + $(BUILDDIR)/ded/unix_dedicated.o \ + $(BUILDDIR)/ded/unix_main.o \ + $(BUILDDIR)/ded/unix_net.o \ + $(BUILDDIR)/ded/unix_shared.o \ + \ + $(BUILDDIR)/ded/cl_null.o + +$(BUILDDIR)/linuxq3ded : $(Q3DED_OBJS) + $(CC) $(CFLAGS) -o $@ $(Q3DED_OBJS) $(LDFLAGS) + +$(BUILDDIR)/ded/sv_bot.o : $(SERVER_DIR)/sv_bot.c + $(DO_DED_CC) + +$(BUILDDIR)/ded/sv_client.o : $(SERVER_DIR)/sv_client.c + $(DO_DED_CC) + +$(BUILDDIR)/ded/sv_ccmds.o : $(SERVER_DIR)/sv_ccmds.c + $(DO_DED_CC) + +$(BUILDDIR)/ded/sv_game.o : $(SERVER_DIR)/sv_game.c + $(DO_DED_CC) + +$(BUILDDIR)/ded/sv_init.o : $(SERVER_DIR)/sv_init.c + $(DO_DED_CC) + +$(BUILDDIR)/ded/sv_main.o : $(SERVER_DIR)/sv_main.c + $(DO_DED_CC) + +$(BUILDDIR)/ded/sv_snapshot.o : $(SERVER_DIR)/sv_snapshot.c + $(DO_DED_CC) + +$(BUILDDIR)/ded/sv_world.o : $(SERVER_DIR)/sv_world.c + $(DO_DED_CC) + +$(BUILDDIR)/ded/cm_trace.o : $(COMMON_DIR)/cm_trace.c + $(DO_DED_CC) + +$(BUILDDIR)/ded/cm_load.o : $(COMMON_DIR)/cm_load.c + $(DO_DED_CC) + +$(BUILDDIR)/ded/cm_test.o : $(COMMON_DIR)/cm_test.c + $(DO_DED_CC) + +$(BUILDDIR)/ded/cm_patch.o : $(COMMON_DIR)/cm_patch.c + $(DO_DED_CC) + +$(BUILDDIR)/ded/cm_tag.o : $(COMMON_DIR)/cm_tag.c + $(DO_DED_CC) + +$(BUILDDIR)/ded/cmd.o : $(COMMON_DIR)/cmd.c + $(DO_DED_CC) + +$(BUILDDIR)/ded/common.o : $(COMMON_DIR)/common.c + $(DO_DED_CC) + +$(BUILDDIR)/ded/cvar.o : $(COMMON_DIR)/cvar.c + $(DO_DED_CC) + +$(BUILDDIR)/ded/files.o : $(COMMON_DIR)/files.c + $(DO_DED_CC) + +$(BUILDDIR)/ded/gameinfo.o : $(COMMON_DIR)/gameinfo.c + $(DO_DED_CC) + +$(BUILDDIR)/ded/md4.o : $(COMMON_DIR)/md4.c + $(DO_DED_CC) + +$(BUILDDIR)/ded/msg.o : $(COMMON_DIR)/msg.c + $(DO_DED_CC) + +$(BUILDDIR)/ded/net_chan.o : $(COMMON_DIR)/net_chan.c + $(DO_DED_CC) + +$(BUILDDIR)/ded/unix_dedicated.o : $(UNIX_DIR)/unix_dedicated.c + $(DO_DED_CC) + +$(BUILDDIR)/ded/unix_main.o : $(UNIX_DIR)/unix_main.c + $(DO_DED_CC) + +$(BUILDDIR)/ded/unix_net.o : $(UNIX_DIR)/unix_net.c + $(DO_DED_CC) + +$(BUILDDIR)/ded/unix_shared.o : $(UNIX_DIR)/unix_shared.c + $(DO_DED_CC) + +$(BUILDDIR)/ded/cl_null.o : $(NULL_DIR)/cl_null.c + $(DO_DED_CC) + +############################################################################# +# GAME +############################################################################# + +GAME_OBJS = \ + $(BUILDDIR)/game/b_ai.o \ + $(BUILDDIR)/game/b_files.o \ + $(BUILDDIR)/game/b_items.o \ + $(BUILDDIR)/game/b_main.o \ + $(BUILDDIR)/game/b_nav.o \ + $(BUILDDIR)/game/b_navgen.o \ + $(BUILDDIR)/game/bg_misc.o \ + $(BUILDDIR)/game/bg_pmove.o \ + $(BUILDDIR)/game/g_active.o \ + $(BUILDDIR)/game/g_aim.o \ + $(BUILDDIR)/game/g_client.o \ + $(BUILDDIR)/game/g_cmds.o \ + $(BUILDDIR)/game/g_combat.o \ + $(BUILDDIR)/game/g_items.o \ + $(BUILDDIR)/game/g_main.o \ + $(BUILDDIR)/game/g_mem.o \ + $(BUILDDIR)/game/g_misc.o \ + $(BUILDDIR)/game/g_missile.o \ + $(BUILDDIR)/game/g_mover.o \ + $(BUILDDIR)/game/g_spawn.o \ + $(BUILDDIR)/game/g_svcmds.o \ + $(BUILDDIR)/game/g_target.o \ + $(BUILDDIR)/game/g_team.o \ + $(BUILDDIR)/game/g_trigger.o \ + $(BUILDDIR)/game/g_utils.o \ + $(BUILDDIR)/game/g_weapon.o \ + $(BUILDDIR)/game/q_shared.o \ + $(BUILDDIR)/game/q_math.o + +$(BUILDDIR)/qagame$(ARCH).$(SHLIBEXT) : $(GAME_OBJS) + $(CC) $(CFLAGS) $(SHLIBLDFLAGS) -o $@ $(GAME_OBJS) + +$(BUILDDIR)/game/b_ai.o : $(GAME_DIR)/b_ai.c + $(DO_SHLIB_CC) + +$(BUILDDIR)/game/b_files.o : $(GAME_DIR)/b_files.c + $(DO_SHLIB_CC) + +$(BUILDDIR)/game/b_items.o : $(GAME_DIR)/b_items.c + $(DO_SHLIB_CC) + +$(BUILDDIR)/game/b_main.o : $(GAME_DIR)/b_main.c + $(DO_SHLIB_CC) + +$(BUILDDIR)/game/b_nav.o : $(GAME_DIR)/b_nav.c + $(DO_SHLIB_CC) + +$(BUILDDIR)/game/b_navgen.o : $(GAME_DIR)/b_navgen.c + $(DO_SHLIB_CC) + +$(BUILDDIR)/game/bg_misc.o : $(GAME_DIR)/bg_misc.c + $(DO_SHLIB_CC) + +$(BUILDDIR)/game/bg_pmove.o : $(GAME_DIR)/bg_pmove.c + $(DO_SHLIB_CC) + +$(BUILDDIR)/game/g_active.o : $(GAME_DIR)/g_active.c + $(DO_SHLIB_CC) + +$(BUILDDIR)/game/g_aim.o : $(GAME_DIR)/g_aim.c + $(DO_SHLIB_CC) + +$(BUILDDIR)/game/g_client.o : $(GAME_DIR)/g_client.c + $(DO_SHLIB_CC) + +$(BUILDDIR)/game/g_cmds.o : $(GAME_DIR)/g_cmds.c + $(DO_SHLIB_CC) + +$(BUILDDIR)/game/g_combat.o : $(GAME_DIR)/g_combat.c + $(DO_SHLIB_CC) + +$(BUILDDIR)/game/g_items.o : $(GAME_DIR)/g_items.c + $(DO_SHLIB_CC) + +$(BUILDDIR)/game/g_main.o : $(GAME_DIR)/g_main.c + $(DO_SHLIB_CC) + +$(BUILDDIR)/game/g_mem.o : $(GAME_DIR)/g_mem.c + $(DO_SHLIB_CC) + +$(BUILDDIR)/game/g_misc.o : $(GAME_DIR)/g_misc.c + $(DO_SHLIB_CC) + +$(BUILDDIR)/game/g_missile.o : $(GAME_DIR)/g_missile.c + $(DO_SHLIB_CC) + +$(BUILDDIR)/game/g_mover.o : $(GAME_DIR)/g_mover.c + $(DO_SHLIB_CC) + +$(BUILDDIR)/game/g_spawn.o : $(GAME_DIR)/g_spawn.c + $(DO_SHLIB_CC) + +$(BUILDDIR)/game/g_svcmds.o : $(GAME_DIR)/g_svcmds.c + $(DO_SHLIB_CC) + +$(BUILDDIR)/game/g_target.o : $(GAME_DIR)/g_target.c + $(DO_SHLIB_CC) + +$(BUILDDIR)/game/g_team.o : $(GAME_DIR)/g_team.c + $(DO_SHLIB_CC) + +$(BUILDDIR)/game/g_trigger.o : $(GAME_DIR)/g_trigger.c + $(DO_SHLIB_CC) + +$(BUILDDIR)/game/g_utils.o : $(GAME_DIR)/g_utils.c + $(DO_SHLIB_CC) + +$(BUILDDIR)/game/g_weapon.o : $(GAME_DIR)/g_weapon.c + $(DO_SHLIB_CC) + +$(BUILDDIR)/game/q_shared.o : $(GAME_DIR)/q_shared.c + $(DO_SHLIB_DEBUG_CC) + +$(BUILDDIR)/game/q_math.o : $(GAME_DIR)/q_math.c + $(DO_SHLIB_CC) + +############################################################################# +# CGAME +############################################################################# + +CGAME_OBJS = \ + $(BUILDDIR)/cgame/bg_misc.o \ + $(BUILDDIR)/cgame/bg_pmove.o \ + $(BUILDDIR)/cgame/cg_draw.o \ + $(BUILDDIR)/cgame/cg_effects.o \ + $(BUILDDIR)/cgame/cg_ents.o \ + $(BUILDDIR)/cgame/cg_event.o \ + $(BUILDDIR)/cgame/cg_info.o \ + $(BUILDDIR)/cgame/cg_localents.o \ + $(BUILDDIR)/cgame/cg_main.o \ + $(BUILDDIR)/cgame/cg_marks.o \ + $(BUILDDIR)/cgame/cg_menu.o \ + $(BUILDDIR)/cgame/cg_players.o \ + $(BUILDDIR)/cgame/cg_predict.o \ + $(BUILDDIR)/cgame/cg_scoreboard.o \ + $(BUILDDIR)/cgame/cg_snapshot.o \ + $(BUILDDIR)/cgame/cg_view.o \ + $(BUILDDIR)/cgame/cg_weapons.o \ + $(BUILDDIR)/cgame/q_shared.o \ + $(BUILDDIR)/cgame/q_math.o + +$(BUILDDIR)/cgame$(ARCH).$(SHLIBEXT) : $(CGAME_OBJS) + $(CC) $(CFLAGS) $(SHLIBLDFLAGS) -o $@ $(CGAME_OBJS) + +$(BUILDDIR)/cgame/bg_misc.o : $(GAME_DIR)/bg_misc.c + $(DO_SHLIB_CC) + +$(BUILDDIR)/cgame/bg_pmove.o : $(GAME_DIR)/bg_pmove.c + $(DO_SHLIB_CC) + +$(BUILDDIR)/cgame/cg_draw.o : $(CGAME_DIR)/cg_draw.c + $(DO_SHLIB_CC) + +$(BUILDDIR)/cgame/cg_effects.o : $(CGAME_DIR)/cg_effects.c + $(DO_SHLIB_CC) + +$(BUILDDIR)/cgame/cg_ents.o : $(CGAME_DIR)/cg_ents.c + $(DO_SHLIB_CC) + +$(BUILDDIR)/cgame/cg_event.o : $(CGAME_DIR)/cg_event.c + $(DO_SHLIB_CC) + +$(BUILDDIR)/cgame/cg_info.o : $(CGAME_DIR)/cg_info.c + $(DO_SHLIB_CC) + +$(BUILDDIR)/cgame/cg_localents.o : $(CGAME_DIR)/cg_localents.c + $(DO_SHLIB_CC) + +$(BUILDDIR)/cgame/cg_main.o : $(CGAME_DIR)/cg_main.c + $(DO_SHLIB_CC) + +$(BUILDDIR)/cgame/cg_marks.o : $(CGAME_DIR)/cg_marks.c + $(DO_SHLIB_CC) + +$(BUILDDIR)/cgame/cg_menu.o : $(CGAME_DIR)/cg_menu.c + $(DO_SHLIB_CC) + +$(BUILDDIR)/cgame/cg_players.o : $(CGAME_DIR)/cg_players.c + $(DO_SHLIB_CC) + +$(BUILDDIR)/cgame/cg_predict.o : $(CGAME_DIR)/cg_predict.c + $(DO_SHLIB_CC) + +$(BUILDDIR)/cgame/cg_scoreboard.o : $(CGAME_DIR)/cg_scoreboard.c + $(DO_SHLIB_CC) + +$(BUILDDIR)/cgame/cg_snapshot.o : $(CGAME_DIR)/cg_snapshot.c + $(DO_SHLIB_CC) + +$(BUILDDIR)/cgame/cg_view.o : $(CGAME_DIR)/cg_view.c + $(DO_SHLIB_CC) + +$(BUILDDIR)/cgame/cg_weapons.o : $(CGAME_DIR)/cg_weapons.c + $(DO_SHLIB_CC) + +$(BUILDDIR)/cgame/q_shared.o : $(GAME_DIR)/q_shared.c + $(DO_SHLIB_DEBUG_CC) + +$(BUILDDIR)/cgame/q_math.o : $(GAME_DIR)/q_math.c + $(DO_SHLIB_CC) + + +############################################################################# +# RPM +############################################################################# + +###### DISABLED + +TMPDIR=/var/tmp +TARDIR=$(TMPDIR)/q3test +TARFILE = q3test-$(VERSION_FN)-$(RPM_RELEASE).$(ARCH).tar + +tar: + if [ ! -d archives ];then mkdir archives;chmod 755 archives;fi + $(MAKE) copyfiles COPYDIR=$(TARDIR) + cd $(TARDIR)/..; tar cvf $(TARFILE) q3test && gzip -9 $(TARFILE) + mv $(TARDIR)/../$(TARFILE).gz archives/. + chmod 644 archives/$(TARFILE).gz + rm -rf $(TARDIR) + +# Make RPMs. You need to be root to make this work +RPMROOT=/usr/src/redhat +RPM = rpm +RPMFLAGS = -bb +INSTALLDIR = /usr/local/games/q3test +RPMDIR = $(TMPDIR)/q3test-$(VERSION_FN) +DESTDIR= $(RPMDIR)/$(INSTALLDIR) + +rpm: q3test.spec + touch $(RPMROOT)/SOURCES/q3test-$(VERSION_FN).tar.gz + if [ ! -d archives ];then mkdir archives;fi + $(MAKE) copyfiles COPYDIR=$(DESTDIR) + cp $(UNIX_DIR)/quake3.gif $(RPMROOT)/SOURCES/. + cp q3test.spec $(RPMROOT)/SPECS/. + cd $(RPMROOT)/SPECS; $(RPM) $(RPMFLAGS) q3test.spec + rm -rf $(RPMDIR) + mv $(RPMROOT)/RPMS/$(RPMARCH)/q3test-$(VERSION_FN)-$(RPM_RELEASE).$(RPMARCH).rpm archives/q3test-$(VERSION_FN)-$(RPM_RELEASE).$(RPMARCH).rpm + chmod 644 archives/q3test-$(VERSION_FN)-$(RPM_RELEASE).$(RPMARCH).rpm + +copyfiles: + -mkdirhier $(COPYDIR) + cp $(BUILD_RELEASE_DIR)/linuxquake3 $(COPYDIR) + strip $(COPYDIR)/linuxquake3 + chmod 755 $(COPYDIR)/linuxquake3 + cp $(BUILD_RELEASE_DIR)/qagame$(ARCH).$(SHLIBEXT) $(COPYDIR) + chmod 755 $(COPYDIR)/qagame$(ARCH).$(SHLIBEXT) + cp $(BUILD_RELEASE_DIR)/cgame$(ARCH).$(SHLIBEXT) $(COPYDIR) + chmod 755 $(COPYDIR)/cgame$(ARCH).$(SHLIBEXT) + cp $(BUILD_DIR)/libMesaVoodooGL.so.3.1 $(COPYDIR)/. + chmod 755 $(COPYDIR)/libMesaVoodooGL.so.3.1 + -mkdir $(COPYDIR)/demoq3 + chmod 1777 $(COPYDIR)/demoq3 + cp $(DEMO_PAK) $(COPYDIR)/demoq3/pak0.pk3 + cp $(UNIX_DIR)/README.EULA $(COPYDIR) + chmod 644 $(COPYDIR)/README.EULA + cp $(UNIX_DIR)/README.Q3Test $(COPYDIR) + chmod 644 $(COPYDIR)/README.Q3Test + +q3test.spec : $(UNIX_DIR)/q3test.spec.sh Makefile + sh $< $(VERSION_FN) $(RPM_RELEASE) $(ARCH) $(INSTALLDIR) > $@ + +############################################################################# +# MISC +############################################################################# + +clean: clean-debug clean-release + +clean-debug: + $(MAKE) clean2 BUILDDIR=$(BUILD_DEBUG_DIR) CFLAGS="$(DEBUG_CFLAGS)" + +clean-release: + $(MAKE) clean2 BUILDDIR=$(BUILD_RELEASE_DIR) CFLAGS="$(DEBUG_CFLAGS)" + diff --git a/code/unix/matha.s b/code/unix/matha.s new file mode 100644 index 0000000..73174ee --- /dev/null +++ b/code/unix/matha.s @@ -0,0 +1,402 @@ +// +// math.s +// x86 assembly-language math routines. + +#define GLQUAKE 1 // don't include unneeded defs +#include "qasm.h" + + +#if id386 + + .data + + .align 4 +Ljmptab: .long Lcase0, Lcase1, Lcase2, Lcase3 + .long Lcase4, Lcase5, Lcase6, Lcase7 + + .text + +// TODO: rounding needed? +// stack parameter offset +#define val 4 + +.globl C(Invert24To16) +C(Invert24To16): + + movl val(%esp),%ecx + movl $0x100,%edx // 0x10000000000 as dividend + cmpl %edx,%ecx + jle LOutOfRange + + subl %eax,%eax + divl %ecx + + ret + +LOutOfRange: + movl $0xFFFFFFFF,%eax + ret + +#if 0 + +#define in 4 +#define out 8 + + .align 2 +.globl C(TransformVector) +C(TransformVector): + movl in(%esp),%eax + movl out(%esp),%edx + + flds (%eax) // in[0] + fmuls C(vright) // in[0]*vright[0] + flds (%eax) // in[0] | in[0]*vright[0] + fmuls C(vup) // in[0]*vup[0] | in[0]*vright[0] + flds (%eax) // in[0] | in[0]*vup[0] | in[0]*vright[0] + fmuls C(vpn) // in[0]*vpn[0] | in[0]*vup[0] | in[0]*vright[0] + + flds 4(%eax) // in[1] | ... + fmuls C(vright)+4 // in[1]*vright[1] | ... + flds 4(%eax) // in[1] | in[1]*vright[1] | ... + fmuls C(vup)+4 // in[1]*vup[1] | in[1]*vright[1] | ... + flds 4(%eax) // in[1] | in[1]*vup[1] | in[1]*vright[1] | ... + fmuls C(vpn)+4 // in[1]*vpn[1] | in[1]*vup[1] | in[1]*vright[1] | ... + fxch %st(2) // in[1]*vright[1] | in[1]*vup[1] | in[1]*vpn[1] | ... + + faddp %st(0),%st(5) // in[1]*vup[1] | in[1]*vpn[1] | ... + faddp %st(0),%st(3) // in[1]*vpn[1] | ... + faddp %st(0),%st(1) // vpn_accum | vup_accum | vright_accum + + flds 8(%eax) // in[2] | ... + fmuls C(vright)+8 // in[2]*vright[2] | ... + flds 8(%eax) // in[2] | in[2]*vright[2] | ... + fmuls C(vup)+8 // in[2]*vup[2] | in[2]*vright[2] | ... + flds 8(%eax) // in[2] | in[2]*vup[2] | in[2]*vright[2] | ... + fmuls C(vpn)+8 // in[2]*vpn[2] | in[2]*vup[2] | in[2]*vright[2] | ... + fxch %st(2) // in[2]*vright[2] | in[2]*vup[2] | in[2]*vpn[2] | ... + + faddp %st(0),%st(5) // in[2]*vup[2] | in[2]*vpn[2] | ... + faddp %st(0),%st(3) // in[2]*vpn[2] | ... + faddp %st(0),%st(1) // vpn_accum | vup_accum | vright_accum + + fstps 8(%edx) // out[2] + fstps 4(%edx) // out[1] + fstps (%edx) // out[0] + + ret + +#endif + +#define EMINS 4+4 +#define EMAXS 4+8 +#define P 4+12 + + .align 2 +.globl C(BoxOnPlaneSide) +C(BoxOnPlaneSide): + pushl %ebx + + movl P(%esp),%edx + movl EMINS(%esp),%ecx + xorl %eax,%eax + movl EMAXS(%esp),%ebx + movb pl_signbits(%edx),%al + cmpb $8,%al + jge Lerror + flds pl_normal(%edx) // p->normal[0] + fld %st(0) // p->normal[0] | p->normal[0] + jmp Ljmptab(,%eax,4) + + +//dist1= p->normal[0]*emaxs[0] + p->normal[1]*emaxs[1] + p->normal[2]*emaxs[2]; +//dist2= p->normal[0]*emins[0] + p->normal[1]*emins[1] + p->normal[2]*emins[2]; +Lcase0: + fmuls (%ebx) // p->normal[0]*emaxs[0] | p->normal[0] + flds pl_normal+4(%edx) // p->normal[1] | p->normal[0]*emaxs[0] | + // p->normal[0] + fxch %st(2) // p->normal[0] | p->normal[0]*emaxs[0] | + // p->normal[1] + fmuls (%ecx) // p->normal[0]*emins[0] | + // p->normal[0]*emaxs[0] | p->normal[1] + fxch %st(2) // p->normal[1] | p->normal[0]*emaxs[0] | + // p->normal[0]*emins[0] + fld %st(0) // p->normal[1] | p->normal[1] | + // p->normal[0]*emaxs[0] | + // p->normal[0]*emins[0] + fmuls 4(%ebx) // p->normal[1]*emaxs[1] | p->normal[1] | + // p->normal[0]*emaxs[0] | + // p->normal[0]*emins[0] + flds pl_normal+8(%edx) // p->normal[2] | p->normal[1]*emaxs[1] | + // p->normal[1] | p->normal[0]*emaxs[0] | + // p->normal[0]*emins[0] + fxch %st(2) // p->normal[1] | p->normal[1]*emaxs[1] | + // p->normal[2] | p->normal[0]*emaxs[0] | + // p->normal[0]*emins[0] + fmuls 4(%ecx) // p->normal[1]*emins[1] | + // p->normal[1]*emaxs[1] | + // p->normal[2] | p->normal[0]*emaxs[0] | + // p->normal[0]*emins[0] + fxch %st(2) // p->normal[2] | p->normal[1]*emaxs[1] | + // p->normal[1]*emins[1] | + // p->normal[0]*emaxs[0] | + // p->normal[0]*emins[0] + fld %st(0) // p->normal[2] | p->normal[2] | + // p->normal[1]*emaxs[1] | + // p->normal[1]*emins[1] | + // p->normal[0]*emaxs[0] | + // p->normal[0]*emins[0] + fmuls 8(%ebx) // p->normal[2]*emaxs[2] | + // p->normal[2] | + // p->normal[1]*emaxs[1] | + // p->normal[1]*emins[1] | + // p->normal[0]*emaxs[0] | + // p->normal[0]*emins[0] + fxch %st(5) // p->normal[0]*emins[0] | + // p->normal[2] | + // p->normal[1]*emaxs[1] | + // p->normal[1]*emins[1] | + // p->normal[0]*emaxs[0] | + // p->normal[2]*emaxs[2] + faddp %st(0),%st(3) //p->normal[2] | + // p->normal[1]*emaxs[1] | + // p->normal[1]*emins[1]+p->normal[0]*emins[0]| + // p->normal[0]*emaxs[0] | + // p->normal[2]*emaxs[2] + fmuls 8(%ecx) //p->normal[2]*emins[2] | + // p->normal[1]*emaxs[1] | + // p->normal[1]*emins[1]+p->normal[0]*emins[0]| + // p->normal[0]*emaxs[0] | + // p->normal[2]*emaxs[2] + fxch %st(1) //p->normal[1]*emaxs[1] | + // p->normal[2]*emins[2] | + // p->normal[1]*emins[1]+p->normal[0]*emins[0]| + // p->normal[0]*emaxs[0] | + // p->normal[2]*emaxs[2] + faddp %st(0),%st(3) //p->normal[2]*emins[2] | + // p->normal[1]*emins[1]+p->normal[0]*emins[0]| + // p->normal[0]*emaxs[0]+p->normal[1]*emaxs[1]| + // p->normal[2]*emaxs[2] + fxch %st(3) //p->normal[2]*emaxs[2] + + // p->normal[1]*emins[1]+p->normal[0]*emins[0]| + // p->normal[0]*emaxs[0]+p->normal[1]*emaxs[1]| + // p->normal[2]*emins[2] + faddp %st(0),%st(2) //p->normal[1]*emins[1]+p->normal[0]*emins[0]| + // dist1 | p->normal[2]*emins[2] + + jmp LSetSides + +//dist1= p->normal[0]*emins[0] + p->normal[1]*emaxs[1] + p->normal[2]*emaxs[2]; +//dist2= p->normal[0]*emaxs[0] + p->normal[1]*emins[1] + p->normal[2]*emins[2]; +Lcase1: + fmuls (%ecx) // emins[0] + flds pl_normal+4(%edx) + fxch %st(2) + fmuls (%ebx) // emaxs[0] + fxch %st(2) + fld %st(0) + fmuls 4(%ebx) // emaxs[1] + flds pl_normal+8(%edx) + fxch %st(2) + fmuls 4(%ecx) // emins[1] + fxch %st(2) + fld %st(0) + fmuls 8(%ebx) // emaxs[2] + fxch %st(5) + faddp %st(0),%st(3) + fmuls 8(%ecx) // emins[2] + fxch %st(1) + faddp %st(0),%st(3) + fxch %st(3) + faddp %st(0),%st(2) + + jmp LSetSides + +//dist1= p->normal[0]*emaxs[0] + p->normal[1]*emins[1] + p->normal[2]*emaxs[2]; +//dist2= p->normal[0]*emins[0] + p->normal[1]*emaxs[1] + p->normal[2]*emins[2]; +Lcase2: + fmuls (%ebx) // emaxs[0] + flds pl_normal+4(%edx) + fxch %st(2) + fmuls (%ecx) // emins[0] + fxch %st(2) + fld %st(0) + fmuls 4(%ecx) // emins[1] + flds pl_normal+8(%edx) + fxch %st(2) + fmuls 4(%ebx) // emaxs[1] + fxch %st(2) + fld %st(0) + fmuls 8(%ebx) // emaxs[2] + fxch %st(5) + faddp %st(0),%st(3) + fmuls 8(%ecx) // emins[2] + fxch %st(1) + faddp %st(0),%st(3) + fxch %st(3) + faddp %st(0),%st(2) + + jmp LSetSides + +//dist1= p->normal[0]*emins[0] + p->normal[1]*emins[1] + p->normal[2]*emaxs[2]; +//dist2= p->normal[0]*emaxs[0] + p->normal[1]*emaxs[1] + p->normal[2]*emins[2]; +Lcase3: + fmuls (%ecx) // emins[0] + flds pl_normal+4(%edx) + fxch %st(2) + fmuls (%ebx) // emaxs[0] + fxch %st(2) + fld %st(0) + fmuls 4(%ecx) // emins[1] + flds pl_normal+8(%edx) + fxch %st(2) + fmuls 4(%ebx) // emaxs[1] + fxch %st(2) + fld %st(0) + fmuls 8(%ebx) // emaxs[2] + fxch %st(5) + faddp %st(0),%st(3) + fmuls 8(%ecx) // emins[2] + fxch %st(1) + faddp %st(0),%st(3) + fxch %st(3) + faddp %st(0),%st(2) + + jmp LSetSides + +//dist1= p->normal[0]*emaxs[0] + p->normal[1]*emaxs[1] + p->normal[2]*emins[2]; +//dist2= p->normal[0]*emins[0] + p->normal[1]*emins[1] + p->normal[2]*emaxs[2]; +Lcase4: + fmuls (%ebx) // emaxs[0] + flds pl_normal+4(%edx) + fxch %st(2) + fmuls (%ecx) // emins[0] + fxch %st(2) + fld %st(0) + fmuls 4(%ebx) // emaxs[1] + flds pl_normal+8(%edx) + fxch %st(2) + fmuls 4(%ecx) // emins[1] + fxch %st(2) + fld %st(0) + fmuls 8(%ecx) // emins[2] + fxch %st(5) + faddp %st(0),%st(3) + fmuls 8(%ebx) // emaxs[2] + fxch %st(1) + faddp %st(0),%st(3) + fxch %st(3) + faddp %st(0),%st(2) + + jmp LSetSides + +//dist1= p->normal[0]*emins[0] + p->normal[1]*emaxs[1] + p->normal[2]*emins[2]; +//dist2= p->normal[0]*emaxs[0] + p->normal[1]*emins[1] + p->normal[2]*emaxs[2]; +Lcase5: + fmuls (%ecx) // emins[0] + flds pl_normal+4(%edx) + fxch %st(2) + fmuls (%ebx) // emaxs[0] + fxch %st(2) + fld %st(0) + fmuls 4(%ebx) // emaxs[1] + flds pl_normal+8(%edx) + fxch %st(2) + fmuls 4(%ecx) // emins[1] + fxch %st(2) + fld %st(0) + fmuls 8(%ecx) // emins[2] + fxch %st(5) + faddp %st(0),%st(3) + fmuls 8(%ebx) // emaxs[2] + fxch %st(1) + faddp %st(0),%st(3) + fxch %st(3) + faddp %st(0),%st(2) + + jmp LSetSides + +//dist1= p->normal[0]*emaxs[0] + p->normal[1]*emins[1] + p->normal[2]*emins[2]; +//dist2= p->normal[0]*emins[0] + p->normal[1]*emaxs[1] + p->normal[2]*emaxs[2]; +Lcase6: + fmuls (%ebx) // emaxs[0] + flds pl_normal+4(%edx) + fxch %st(2) + fmuls (%ecx) // emins[0] + fxch %st(2) + fld %st(0) + fmuls 4(%ecx) // emins[1] + flds pl_normal+8(%edx) + fxch %st(2) + fmuls 4(%ebx) // emaxs[1] + fxch %st(2) + fld %st(0) + fmuls 8(%ecx) // emins[2] + fxch %st(5) + faddp %st(0),%st(3) + fmuls 8(%ebx) // emaxs[2] + fxch %st(1) + faddp %st(0),%st(3) + fxch %st(3) + faddp %st(0),%st(2) + + jmp LSetSides + +//dist1= p->normal[0]*emins[0] + p->normal[1]*emins[1] + p->normal[2]*emins[2]; +//dist2= p->normal[0]*emaxs[0] + p->normal[1]*emaxs[1] + p->normal[2]*emaxs[2]; +Lcase7: + fmuls (%ecx) // emins[0] + flds pl_normal+4(%edx) + fxch %st(2) + fmuls (%ebx) // emaxs[0] + fxch %st(2) + fld %st(0) + fmuls 4(%ecx) // emins[1] + flds pl_normal+8(%edx) + fxch %st(2) + fmuls 4(%ebx) // emaxs[1] + fxch %st(2) + fld %st(0) + fmuls 8(%ecx) // emins[2] + fxch %st(5) + faddp %st(0),%st(3) + fmuls 8(%ebx) // emaxs[2] + fxch %st(1) + faddp %st(0),%st(3) + fxch %st(3) + faddp %st(0),%st(2) + +LSetSides: + +// sides = 0; +// if (dist1 >= p->dist) +// sides = 1; +// if (dist2 < p->dist) +// sides |= 2; + + faddp %st(0),%st(2) // dist1 | dist2 + fcomps pl_dist(%edx) + xorl %ecx,%ecx + fnstsw %ax + fcomps pl_dist(%edx) + andb $1,%ah + xorb $1,%ah + addb %ah,%cl + + fnstsw %ax + andb $1,%ah + addb %ah,%ah + addb %ah,%cl + +// return sides; + + popl %ebx + movl %ecx,%eax // return status + + ret + + +Lerror: + movl 1, %eax + ret + +#endif // id386 diff --git a/code/unix/q3test.spec.sh b/code/unix/q3test.spec.sh new file mode 100644 index 0000000..a50e1f6 --- /dev/null +++ b/code/unix/q3test.spec.sh @@ -0,0 +1,41 @@ +#!/bin/sh +# Generate Quake3 test +# $1 is version +# $2 is release +# $3 is arch +# $4 is install dir (assumed to be in /var/tmp) +cat < +URL: http://www.idsoftware.com/ +Source: q3test-%{version}.tar.gz +Group: Games +Copyright: Restricted +Icon: quake3.gif +BuildRoot: /var/tmp/%{name}-%{version} +Summary: Q3Test for Linux + +%description + +%install + +%files + +%attr(644,root,root) $4/README.EULA +%attr(644,root,root) $4/README.Q3Test +%attr(755,root,root) $4/linuxquake3 +%attr(755,root,root) $4/cgamei386.so +%attr(755,root,root) $4/qagamei386.so +%attr(755,root,root) $4/libMesaVoodooGL.so.3.1 +%attr(644,root,root) $4/demoq3/pak0.pk3 + +EOF + diff --git a/code/unix/quake3.gif b/code/unix/quake3.gif new file mode 100644 index 0000000..0e7a01c Binary files /dev/null and b/code/unix/quake3.gif differ diff --git a/code/unix/snd_mixa.s b/code/unix/snd_mixa.s new file mode 100644 index 0000000..d6c2945 --- /dev/null +++ b/code/unix/snd_mixa.s @@ -0,0 +1,197 @@ +// +// snd_mixa.s +// x86 assembly-language sound code +// + +#include "qasm.h" + +#if id386 + + .text + +#if 0 +//---------------------------------------------------------------------- +// 8-bit sound-mixing code +//---------------------------------------------------------------------- + +#define ch 4+16 +#define sc 8+16 +#define count 12+16 + +.globl C(S_PaintChannelFrom8) +C(S_PaintChannelFrom8): + pushl %esi // preserve register variables + pushl %edi + pushl %ebx + pushl %ebp + +// int data; +// short *lscale, *rscale; +// unsigned char *sfx; +// int i; + + movl ch(%esp),%ebx + movl sc(%esp),%esi + +// if (ch->leftvol > 255) +// ch->leftvol = 255; +// if (ch->rightvol > 255) +// ch->rightvol = 255; + movl ch_leftvol(%ebx),%eax + movl ch_rightvol(%ebx),%edx + cmpl $255,%eax + jna LLeftSet + movl $255,%eax +LLeftSet: + cmpl $255,%edx + jna LRightSet + movl $255,%edx +LRightSet: + +// lscale = snd_scaletable[ch->leftvol >> 3]; +// rscale = snd_scaletable[ch->rightvol >> 3]; +// sfx = (signed char *)sc->data + ch->pos; +// ch->pos += count; + andl $0xF8,%eax + addl $20,%esi + movl (%esi),%esi + andl $0xF8,%edx + movl ch_pos(%ebx),%edi + movl count(%esp),%ecx + addl %edi,%esi + shll $7,%eax + addl %ecx,%edi + shll $7,%edx + movl %edi,ch_pos(%ebx) + addl $(C(snd_scaletable)),%eax + addl $(C(snd_scaletable)),%edx + subl %ebx,%ebx + movb -1(%esi,%ecx,1),%bl + + testl $1,%ecx + jz LMix8Loop + + movl (%eax,%ebx,4),%edi + movl (%edx,%ebx,4),%ebp + addl C(paintbuffer)+psp_left-psp_size(,%ecx,psp_size),%edi + addl C(paintbuffer)+psp_right-psp_size(,%ecx,psp_size),%ebp + movl %edi,C(paintbuffer)+psp_left-psp_size(,%ecx,psp_size) + movl %ebp,C(paintbuffer)+psp_right-psp_size(,%ecx,psp_size) + movb -2(%esi,%ecx,1),%bl + + decl %ecx + jz LDone + +// for (i=0 ; i>8; +// if (val > 0x7fff) +// snd_out[i] = 0x7fff; +// else if (val < (short)0x8000) +// snd_out[i] = (short)0x8000; +// else +// snd_out[i] = val; + movl -8(%ebx,%ecx,4),%eax + sarl $8,%eax + cmpl $0x7FFF,%eax + jg LClampHigh + cmpl $0xFFFF8000,%eax + jnl LClampDone + movl $0xFFFF8000,%eax + jmp LClampDone +LClampHigh: + movl $0x7FFF,%eax +LClampDone: + +// val = (snd_p[i+1]*snd_vol)>>8; +// if (val > 0x7fff) +// snd_out[i+1] = 0x7fff; +// else if (val < (short)0x8000) +// snd_out[i+1] = (short)0x8000; +// else +// snd_out[i+1] = val; + movl -4(%ebx,%ecx,4),%edx + sarl $8,%edx + cmpl $0x7FFF,%edx + jg LClampHigh2 + cmpl $0xFFFF8000,%edx + jnl LClampDone2 + movl $0xFFFF8000,%edx + jmp LClampDone2 +LClampHigh2: + movl $0x7FFF,%edx +LClampDone2: + shll $16,%edx + andl $0xFFFF,%eax + orl %eax,%edx + movl %edx,-4(%edi,%ecx,2) + +// } + subl $2,%ecx + jnz LWLBLoopTop + +// snd_p += snd_linear_count; + + popl %ebx + popl %edi + + ret + + +#endif // id386 + diff --git a/code/unix/sys_dosa.s b/code/unix/sys_dosa.s new file mode 100644 index 0000000..cc29312 --- /dev/null +++ b/code/unix/sys_dosa.s @@ -0,0 +1,94 @@ +// +// sys_dosa.s +// x86 assembly-language DOS-dependent routines. + +#include "qasm.h" + + + .data + + .align 4 +fpenv: + .long 0, 0, 0, 0, 0, 0, 0, 0 + + .text + +.globl C(MaskExceptions) +C(MaskExceptions): + fnstenv fpenv + orl $0x3F,fpenv + fldenv fpenv + + ret + +#if 0 +.globl C(unmaskexceptions) +C(unmaskexceptions): + fnstenv fpenv + andl $0xFFFFFFE0,fpenv + fldenv fpenv + + ret +#endif + + .data + + .align 4 +.globl ceil_cw, single_cw, full_cw, cw, pushed_cw +ceil_cw: .long 0 +single_cw: .long 0 +full_cw: .long 0 +cw: .long 0 +pushed_cw: .long 0 + + .text + +.globl C(Sys_LowFPPrecision) +C(Sys_LowFPPrecision): + fldcw single_cw + + ret + +.globl C(Sys_HighFPPrecision) +C(Sys_HighFPPrecision): + fldcw full_cw + + ret + +.globl C(Sys_PushFPCW_SetHigh) +C(Sys_PushFPCW_SetHigh): + fnstcw pushed_cw + fldcw full_cw + + ret + +.globl C(Sys_PopFPCW) +C(Sys_PopFPCW): + fldcw pushed_cw + + ret + +.globl C(Sys_SetFPCW) +C(Sys_SetFPCW): + fnstcw cw + movl cw,%eax +#if id386 + andb $0xF0,%ah + orb $0x03,%ah // round mode, 64-bit precision +#endif + movl %eax,full_cw + +#if id386 + andb $0xF0,%ah + orb $0x0C,%ah // chop mode, single precision +#endif + movl %eax,single_cw + +#if id386 + andb $0xF0,%ah + orb $0x08,%ah // ceil mode, single precision +#endif + movl %eax,ceil_cw + + ret + diff --git a/code/unix/vssver.scc b/code/unix/vssver.scc new file mode 100644 index 0000000..d8a9f55 Binary files /dev/null and b/code/unix/vssver.scc differ diff --git a/code/vssver.scc b/code/vssver.scc new file mode 100644 index 0000000..43c6185 Binary files /dev/null and b/code/vssver.scc differ diff --git a/code/win32/background.bmp b/code/win32/background.bmp new file mode 100644 index 0000000..88b3dab Binary files /dev/null and b/code/win32/background.bmp differ diff --git a/code/win32/clear.bmp b/code/win32/clear.bmp new file mode 100644 index 0000000..1451638 Binary files /dev/null and b/code/win32/clear.bmp differ diff --git a/code/win32/feelit/FFC10.dll b/code/win32/feelit/FFC10.dll new file mode 100644 index 0000000..0536f23 Binary files /dev/null and b/code/win32/feelit/FFC10.dll differ diff --git a/code/win32/feelit/FFC10d.dll b/code/win32/feelit/FFC10d.dll new file mode 100644 index 0000000..1f546c2 Binary files /dev/null and b/code/win32/feelit/FFC10d.dll differ diff --git a/code/win32/feelit/vssver.scc b/code/win32/feelit/vssver.scc new file mode 100644 index 0000000..3cf99a6 Binary files /dev/null and b/code/win32/feelit/vssver.scc differ diff --git a/code/win32/vssver.scc b/code/win32/vssver.scc new file mode 100644 index 0000000..c121f66 Binary files /dev/null and b/code/win32/vssver.scc differ diff --git a/code/win32/win_local.h b/code/win32/win_local.h index 65e3e81..7c35d3f 100644 --- a/code/win32/win_local.h +++ b/code/win32/win_local.h @@ -44,7 +44,7 @@ LONG WINAPI MainWndProc ( void Conbuf_AppendText( const char *msg ); -void SNDDMA_Activate( void ); +void SNDDMA_Activate( qboolean bAppActive ); typedef struct { diff --git a/code/win32/win_main.cpp b/code/win32/win_main.cpp index 51e70d2..d343c12 100644 --- a/code/win32/win_main.cpp +++ b/code/win32/win_main.cpp @@ -282,7 +282,7 @@ static qboolean Sys_ScanForCD( void ) { Result = GetVolumeInformation(drive,VolumeName,sizeof(VolumeName),&VolumeSerialNumber, &MaximumComponentLength,&FileSystemFlags,FileSystemName,sizeof(FileSystemName)); - if (Result && (strcmpi(VolumeName,"JEDI_OUTCAST") == 0 ) ) + if (Result && (strcmpi(VolumeName,"JEDIOUTCAST") == 0 ) ) { sprintf (test, "%s%s\\%s", drive, CD_BASEDIR, CD_EXE); f = fopen( test, "r"); diff --git a/code/win32/win_snd.cpp b/code/win32/win_snd.cpp index a59914b..9187523 100644 --- a/code/win32/win_snd.cpp +++ b/code/win32/win_snd.cpp @@ -15,6 +15,8 @@ HRESULT (WINAPI *pDirectSoundCreate)(GUID FAR *lpGUID, LPDIRECTSOUND FAR *lplpDS #define SECONDARY_BUFFER_SIZE 0x10000 +extern int s_UseOpenAL; + static qboolean dsound_init; static int sample16; static DWORD gSndBufSize; @@ -365,7 +367,13 @@ SNDDMA_Activate When we change windows we need to do this ================= */ -void SNDDMA_Activate( void ) { +void SNDDMA_Activate( qboolean bAppActive ) +{ + if (s_UseOpenAL) + { + S_AL_MuteAllSounds(!bAppActive); + } + if ( !pDS ) { return; } @@ -377,6 +385,7 @@ void SNDDMA_Activate( void ) { } + // I know this is a bit horrible, but I need to pass our LPDIRECTSOUND ptr to Bink for video playback, // and I don't want other modules to have to know about LPDIRECTSOUND handles, hence the int casting // diff --git a/code/win32/win_syscon.cpp b/code/win32/win_syscon.cpp index c9d8140..2adce86 100644 --- a/code/win32/win_syscon.cpp +++ b/code/win32/win_syscon.cpp @@ -434,8 +434,10 @@ char *Sys_ConsoleInput( void ) void Conbuf_AppendText( const char *pMsg ) { #define CONSOLE_BUFFER_SIZE 16384 - - char buffer[CONSOLE_BUFFER_SIZE*2]; + if ( !s_wcd.hWnd ) { + return; + } + char buffer[CONSOLE_BUFFER_SIZE*4]; char *b = buffer; const char *msg; int bufLen; diff --git a/code/win32/win_wndproc.cpp b/code/win32/win_wndproc.cpp index a58872b..ccf12d5 100644 --- a/code/win32/win_wndproc.cpp +++ b/code/win32/win_wndproc.cpp @@ -405,7 +405,7 @@ LONG WINAPI MainWndProc ( fMinimized = (BOOL) HIWORD(wParam); VID_AppActivate( fActive != WA_INACTIVE, fMinimized); - SNDDMA_Activate(); + SNDDMA_Activate( fActive != WA_INACTIVE && !fMinimized ); } break; diff --git a/ui/vssver.scc b/ui/vssver.scc new file mode 100644 index 0000000..c146db8 Binary files /dev/null and b/ui/vssver.scc differ