diff --git a/Makefile b/Makefile index 8e9e15371..321ebc067 100644 --- a/Makefile +++ b/Makefile @@ -92,7 +92,7 @@ endif export CROSS_COMPILING ifndef VERSION -VERSION=0.4 +VERSION=0.5 endif ifndef CLIENTBIN @@ -109,7 +109,7 @@ APPBUNDLE=Spearmint.app endif ifndef RENDERER_PREFIX -RENDERER_PREFIX=mint-renderer- +RENDERER_PREFIX=spearmint-renderer- endif ifndef BASEGAME @@ -1123,6 +1123,7 @@ endif BASE_CFLAGS += -DPRODUCT_VERSION=\\\"$(VERSION)\\\" BASE_CFLAGS += -DBASEGAME=\\\"$(BASEGAME)\\\" +BASE_CFLAGS += -DRENDERER_PREFIX=\\\"$(RENDERER_PREFIX)\\\" BASE_CFLAGS += -Wformat=2 -Wno-format-zero-length -Wformat-security -Wno-format-nonliteral BASE_CFLAGS += -Wstrict-aliasing=2 -Wmissing-format-attribute BASE_CFLAGS += -Wdisabled-optimization @@ -1406,22 +1407,6 @@ Q3OBJ = \ $(B)/client/vm.o \ $(B)/client/vm_interpreted.o \ \ - $(B)/client/be_aas_bspq3.o \ - $(B)/client/be_aas_cluster.o \ - $(B)/client/be_aas_debug.o \ - $(B)/client/be_aas_entity.o \ - $(B)/client/be_aas_file.o \ - $(B)/client/be_aas_main.o \ - $(B)/client/be_aas_move.o \ - $(B)/client/be_aas_optimize.o \ - $(B)/client/be_aas_reach.o \ - $(B)/client/be_aas_route.o \ - $(B)/client/be_aas_routealt.o \ - $(B)/client/be_aas_sample.o \ - $(B)/client/be_interface.o \ - $(B)/client/l_crc.o \ - $(B)/client/l_libvar.o \ - $(B)/client/l_log.o \ $(B)/client/l_memory.o \ $(B)/client/l_precomp.o \ $(B)/client/l_script.o \ @@ -1987,22 +1972,6 @@ Q3DOBJ = \ $(B)/ded/vm.o \ $(B)/ded/vm_interpreted.o \ \ - $(B)/ded/be_aas_bspq3.o \ - $(B)/ded/be_aas_cluster.o \ - $(B)/ded/be_aas_debug.o \ - $(B)/ded/be_aas_entity.o \ - $(B)/ded/be_aas_file.o \ - $(B)/ded/be_aas_main.o \ - $(B)/ded/be_aas_move.o \ - $(B)/ded/be_aas_optimize.o \ - $(B)/ded/be_aas_reach.o \ - $(B)/ded/be_aas_route.o \ - $(B)/ded/be_aas_routealt.o \ - $(B)/ded/be_aas_sample.o \ - $(B)/ded/be_interface.o \ - $(B)/ded/l_crc.o \ - $(B)/ded/l_libvar.o \ - $(B)/ded/l_log.o \ $(B)/ded/l_memory.o \ $(B)/ded/l_precomp.o \ $(B)/ded/l_script.o \ diff --git a/README.md b/README.md index 1e62e8325..8afe053d1 100644 --- a/README.md +++ b/README.md @@ -26,7 +26,7 @@ Pre-built packages for Windows, GNU/Linux, and Mac OS X are available at the [Sp ## Git branches -* `master` branch is compatible with Spearmint 0.4. +* `master` branch is compatible with Spearmint 0.5. * `devil` branch is for development (devil-op-mint) that is not compatible with the current release — it may be out of date compared to master. * `coverity_scan` branch is for automatically running [Coverity Scan](https://scan.coverity.com/) on [Travis CI](https://travis-ci.org). * `gh-pages` branch is the [Spearmint website](http://spearmint.pw). diff --git a/code/botlib/be_aas_bspq3.c b/code/botlib/be_aas_bspq3.c index 0f72e4e1d..3df8fb4bf 100644 --- a/code/botlib/be_aas_bspq3.c +++ b/code/botlib/be_aas_bspq3.c @@ -248,13 +248,13 @@ int AAS_ValueForBSPEpairKey(int ent, char *key, char *value, int size) int AAS_VectorForBSPEpairKey(int ent, char *key, vec3_t v) { char buf[MAX_EPAIRKEY]; - float v1, v2, v3; + double v1, v2, v3; VectorClear(v); if (!AAS_ValueForBSPEpairKey(ent, key, buf, MAX_EPAIRKEY)) return qfalse; - //scanf into floats, then assign, so it is vec_t size independent + //scanf into doubles, then assign, so it is vec_t size independent v1 = v2 = v3 = 0; - sscanf(buf, "%f %f %f", &v1, &v2, &v3); + sscanf(buf, "%lf %lf %lf", &v1, &v2, &v3); v[0] = v1; v[1] = v2; v[2] = v3; diff --git a/code/botlib/be_aas_debug.c b/code/botlib/be_aas_debug.c index 63db1b8bc..41baf87a6 100644 --- a/code/botlib/be_aas_debug.c +++ b/code/botlib/be_aas_debug.c @@ -38,7 +38,6 @@ Suite 120, Rockville, Maryland 20850 USA. *****************************************************************************/ #include "../qcommon/q_shared.h" -#include "../qcommon/surfaceflags.h" // for CONTENTS_* used by BOTMASK_SOLID #include "l_memory.h" #include "aasfile.h" #include "botlib.h" @@ -547,6 +546,43 @@ void AAS_DrawCross(vec3_t origin, float size, int color) // Returns: - // Changes Globals: - //=========================================================================== +void AAS_PrintTravelType(int traveltype) +{ + char *str; + // + switch(traveltype & TRAVELTYPE_MASK) + { + case TRAVEL_INVALID: str = "TRAVEL_INVALID"; break; + case TRAVEL_WALK: str = "TRAVEL_WALK"; break; + case TRAVEL_CROUCH: str = "TRAVEL_CROUCH"; break; + case TRAVEL_BARRIERJUMP: str = "TRAVEL_BARRIERJUMP"; break; + case TRAVEL_JUMP: str = "TRAVEL_JUMP"; break; + case TRAVEL_LADDER: str = "TRAVEL_LADDER"; break; + case TRAVEL_WALKOFFLEDGE: str = "TRAVEL_WALKOFFLEDGE"; break; + case TRAVEL_SWIM: str = "TRAVEL_SWIM"; break; + case TRAVEL_WATERJUMP: str = "TRAVEL_WATERJUMP"; break; + case TRAVEL_TELEPORT: str = "TRAVEL_TELEPORT"; break; + case TRAVEL_ELEVATOR: str = "TRAVEL_ELEVATOR"; break; + case TRAVEL_ROCKETJUMP: str = "TRAVEL_ROCKETJUMP"; break; + case TRAVEL_BFGJUMP: str = "TRAVEL_BFGJUMP"; break; + case TRAVEL_GRAPPLEHOOK: str = "TRAVEL_GRAPPLEHOOK"; break; + case TRAVEL_DOUBLEJUMP: str = "TRAVEL_DOUBLEJUMP"; break; + case TRAVEL_RAMPJUMP: str = "TRAVEL_RAMPJUMP"; break; + case TRAVEL_STRAFEJUMP: str = "TRAVEL_STRAFEJUMP"; break; + case TRAVEL_JUMPPAD: str = "TRAVEL_JUMPPAD"; break; + case TRAVEL_FUNCBOB: str = "TRAVEL_FUNCBOB"; break; + default: + botimport.Print(PRT_MESSAGE, S_COLOR_RED "UNKNOWN TRAVEL TYPE (%d)" S_COLOR_WHITE, (traveltype & TRAVELTYPE_MASK)); + return; + } //end switch + botimport.Print(PRT_MESSAGE, "%s", str); +} //end of the function AAS_PrintTravelType +//=========================================================================== +// +// Parameter: - +// Returns: - +// Changes Globals: - +//=========================================================================== void AAS_DrawArrow(vec3_t start, vec3_t end, int linecolor, int arrowcolor) { vec3_t dir, cross, p1, p2, up = {0, 0, 1}; @@ -573,12 +609,11 @@ void AAS_DrawArrow(vec3_t start, vec3_t end, int linecolor, int arrowcolor) // Returns: - // Changes Globals: - //=========================================================================== -void AAS_ShowReachability(aas_reachability_t *reach) +void AAS_ShowReachability(aas_reachability_t *reach, int contentmask) { vec3_t dir, cmdmove, velocity; float speed, zvel; aas_clientmove_t move; - int contentmask = BOTMASK_SOLID; // ZTM: FIXME: Get contentmask from Game VM! AAS_ShowAreaPolygons(reach->areanum, 5, qtrue); //AAS_ShowArea(reach->areanum, qtrue); @@ -656,8 +691,7 @@ void AAS_ShowReachability(aas_reachability_t *reach) // Returns: - // Changes Globals: - //=========================================================================== -#ifdef DEBUG -void AAS_ShowReachableAreas(int areanum) +void AAS_ShowReachableAreas(int areanum, int contentmask) { aas_areasettings_t *settings; static aas_reachability_t reach; @@ -680,13 +714,11 @@ void AAS_ShowReachableAreas(int areanum) Com_Memcpy(&reach, &aasworld.reachability[settings->firstreachablearea + index], sizeof(aas_reachability_t)); index++; lasttime = AAS_Time(); - // ZTM: FIXME: Moved AAS_PrintTravelType to game/ai_move.c as BotPrintTravelType - //AAS_PrintTravelType(reach.traveltype & TRAVELTYPE_MASK); - //botimport.Print(PRT_MESSAGE, "\n"); + AAS_PrintTravelType(reach.traveltype & TRAVELTYPE_MASK); + botimport.Print(PRT_MESSAGE, "\n"); } //end if - AAS_ShowReachability(&reach); -} //end of the function ShowReachableAreas -#endif + AAS_ShowReachability(&reach, contentmask); +} //end of the function AAS_ShowReachableAreas void AAS_FloodAreas_r(int areanum, int cluster, int *done) { diff --git a/code/botlib/be_aas_debug.h b/code/botlib/be_aas_debug.h index 96c8bdb17..9046bacae 100644 --- a/code/botlib/be_aas_debug.h +++ b/code/botlib/be_aas_debug.h @@ -59,10 +59,14 @@ void AAS_ShowArea(int areanum, int groundfacesonly); void AAS_ShowAreaPolygons(int areanum, int color, int groundfacesonly); //draw a cros void AAS_DrawCross(vec3_t origin, float size, int color); +//print the travel type +void AAS_PrintTravelType(int traveltype); //draw an arrow void AAS_DrawArrow(vec3_t start, vec3_t end, int linecolor, int arrowcolor); //visualize the given reachability -void AAS_ShowReachability(struct aas_reachability_s *reach); +void AAS_ShowReachability(struct aas_reachability_s *reach, int contentmask); //show the reachable areas from the given area -void AAS_ShowReachableAreas(int areanum); +void AAS_ShowReachableAreas(int areanum, int contentmask); +// +void AAS_FloodAreas(vec3_t origin); diff --git a/code/botlib/be_interface.c b/code/botlib/be_interface.c index 5a0ddb616..0ef94f954 100644 --- a/code/botlib/be_interface.c +++ b/code/botlib/be_interface.c @@ -40,9 +40,7 @@ Suite 120, Rockville, Maryland 20850 USA. #include "../qcommon/q_shared.h" #include "l_log.h" #include "l_libvar.h" -#include "l_script.h" -#include "l_precomp.h" -#include "l_struct.h" +#include "l_memory.h" #include "aasfile.h" #include "botlib.h" #include "be_aas.h" @@ -175,8 +173,9 @@ int Export_BotLibShutdown(void) AAS_Shutdown(); //free all libvars LibVarDeAllocAll(); - //remove all global defines from the pre compiler - PC_RemoveAllGlobalDefines(); + //clear debug polygons and release handles + AAS_ClearShownPolygons(); + AAS_ClearShownDebugLines(); //dump all allocated memory // DumpMemory(); @@ -188,8 +187,6 @@ int Export_BotLibShutdown(void) // botlibsetup = qfalse; botlibglobals.botlibsetup = qfalse; - // print any files still open - PC_CheckOpenSourceHandles(); // return BLERR_NOERROR; } //end of the function Export_BotLibShutdown @@ -283,366 +280,6 @@ void Export_AAS_TracePlayerBBox(struct aas_trace_s *trace, vec3_t start, vec3_t tr = AAS_TracePlayerBBox(start, end, presencetype, passent, contentmask); Com_Memcpy(trace, &tr, sizeof (aas_trace_t)); } //end of the function Export_AAS_TracePlayerBBox -//=========================================================================== -// -// Parameter: - -// Returns: - -// Changes Globals: - -//=========================================================================== -// ZTM: FIXME: Botlib's Test function is broken, move to game? -#ifdef DEBUG -void AAS_TestMovementPrediction(int entnum, vec3_t origin, vec3_t dir, int contentmask); -void ElevatorBottomCenter(aas_reachability_t *reach, vec3_t bottomcenter); -int BotGetReachabilityToGoal(vec3_t origin, int areanum, - int lastgoalareanum, int lastareanum, - int *avoidreach, float *avoidreachtimes, int *avoidreachtries, - bot_goal_t *goal, int travelflags, - struct bot_avoidspot_s *avoidspots, int numavoidspots, int *flags); - -int AAS_PointLight(vec3_t origin, int *red, int *green, int *blue); - -int AAS_TraceAreas(vec3_t start, vec3_t end, int *areas, vec3_t *points, int maxareas); - -int AAS_Reachability_WeaponJump(int area1num, int area2num); - -int BotFuzzyPointReachabilityArea(vec3_t origin); - -float BotGapDistance(vec3_t origin, vec3_t hordir, int entnum); - -void AAS_FloodAreas(vec3_t origin); -#endif - -int BotExportTest(int parm0, char *parm1, vec3_t parm2, vec3_t parm3) -{ - -// return AAS_PointLight(parm2, NULL, NULL, NULL); - -#ifdef DEBUG - static int area = -1; - static int line[2]; - int newarea, i, highlightarea, flood; -// int reachnum; - vec3_t forward, origin; -// vec3_t eye, right, end; -// vec3_t bottomcenter; -// aas_trace_t trace; -// aas_face_t *face; -// aas_entity_t *ent; -// bsp_trace_t bsptrace; -// aas_reachability_t reach; -// bot_goal_t goal; - - // clock_t start_time, end_time; -// vec3_t mins = {-16, -16, -24}; -// vec3_t maxs = {16, 16, 32}; - -// int areas[10], numareas; - - - //return 0; - - if (!aasworld.loaded) return 0; - - /* - if (parm0 & 1) - { - AAS_ClearShownPolygons(); - AAS_FloodAreas(parm2); - } //end if - return 0; - */ - for (i = 0; i < 2; i++) if (!line[i]) line[i] = botimport.DebugLineCreate(); - -// AAS_ClearShownDebugLines(); - - //if (AAS_AgainstLadder(parm2)) botimport.Print(PRT_MESSAGE, "against ladder\n"); - //BotOnGround(parm2, PRESENCE_NORMAL, 1, &newarea, &newarea); - //botimport.Print(PRT_MESSAGE, "%f %f %f\n", parm2[0], parm2[1], parm2[2]); - //* - highlightarea = LibVarGetValue("bot_highlightarea"); - if (highlightarea > 0) - { - newarea = highlightarea; - } //end if - else - { - VectorCopy(parm2, origin); - origin[2] += 0.5; - //newarea = AAS_PointAreaNum(origin); - newarea = BotFuzzyPointReachabilityArea(origin); - } //end else - - botimport.Print(PRT_MESSAGE, "\rtravel time to goal (%d) = %d ", botlibglobals.goalareanum, - AAS_AreaTravelTimeToGoalArea(newarea, origin, botlibglobals.goalareanum, TFL_DEFAULT)); - //newarea = BotReachabilityArea(origin, qtrue); - if (newarea != area) - { - botimport.Print(PRT_MESSAGE, "origin = %f, %f, %f\n", origin[0], origin[1], origin[2]); - area = newarea; - botimport.Print(PRT_MESSAGE, "new area %d, cluster %d, presence type %d\n", - area, AAS_AreaCluster(area), AAS_PointPresenceType(origin)); - botimport.Print(PRT_MESSAGE, "area contents: "); - if (aasworld.areasettings[area].contents & AREACONTENTS_WATER) - { - botimport.Print(PRT_MESSAGE, "water &"); - } //end if - if (aasworld.areasettings[area].contents & AREACONTENTS_LAVA) - { - botimport.Print(PRT_MESSAGE, "lava &"); - } //end if - if (aasworld.areasettings[area].contents & AREACONTENTS_SLIME) - { - botimport.Print(PRT_MESSAGE, "slime &"); - } //end if - if (aasworld.areasettings[area].contents & AREACONTENTS_JUMPPAD) - { - botimport.Print(PRT_MESSAGE, "jump pad &"); - } //end if - if (aasworld.areasettings[area].contents & AREACONTENTS_CLUSTERPORTAL) - { - botimport.Print(PRT_MESSAGE, "cluster portal &"); - } //end if - if (aasworld.areasettings[area].contents & AREACONTENTS_VIEWPORTAL) - { - botimport.Print(PRT_MESSAGE, "view portal &"); - } //end if - if (aasworld.areasettings[area].contents & AREACONTENTS_DONOTENTER) - { - botimport.Print(PRT_MESSAGE, "do not enter &"); - } //end if - if (aasworld.areasettings[area].contents & AREACONTENTS_MOVER) - { - botimport.Print(PRT_MESSAGE, "mover &"); - } //end if - if (!aasworld.areasettings[area].contents) - { - botimport.Print(PRT_MESSAGE, "empty"); - } //end if - botimport.Print(PRT_MESSAGE, "\n"); - botimport.Print(PRT_MESSAGE, "travel time to goal (%d) = %d\n", botlibglobals.goalareanum, - AAS_AreaTravelTimeToGoalArea(newarea, origin, botlibglobals.goalareanum, TFL_DEFAULT|TFL_ROCKETJUMP)); - /* - VectorCopy(origin, end); - end[2] += 5; - numareas = AAS_TraceAreas(origin, end, areas, NULL, 10); - AAS_TracePlayerBBox(origin, end, PRESENCE_CROUCH, -1, MASK_PLAYERSOLID); - botimport.Print(PRT_MESSAGE, "num areas = %d, area = %d\n", numareas, areas[0]); - */ - /* - botlibglobals.goalareanum = newarea; - VectorCopy(parm2, botlibglobals.goalorigin); - botimport.Print(PRT_MESSAGE, "new goal %2.1f %2.1f %2.1f area %d\n", - origin[0], origin[1], origin[2], newarea); - */ - } //end if - //* - flood = LibVarGetValue("bot_flood"); - if (parm0 & 1) - { - if (flood) - { - AAS_ClearShownPolygons(); - AAS_ClearShownDebugLines(); - AAS_FloodAreas(parm2); - } - else - { - botlibglobals.goalareanum = newarea; - VectorCopy(parm2, botlibglobals.goalorigin); - botimport.Print(PRT_MESSAGE, "new goal %2.1f %2.1f %2.1f area %d\n", - origin[0], origin[1], origin[2], newarea); - } - } //end if*/ - if (flood) - return 0; -// if (parm0 & BUTTON_USE) -// { -// botlibglobals.runai = !botlibglobals.runai; -// if (botlibglobals.runai) botimport.Print(PRT_MESSAGE, "started AI\n"); -// else botimport.Print(PRT_MESSAGE, "stopped AI\n"); - //* / - /* - goal.areanum = botlibglobals.goalareanum; - reachnum = BotGetReachabilityToGoal(parm2, newarea, 1, - ms.avoidreach, ms.avoidreachtimes, - &goal, TFL_DEFAULT); - if (!reachnum) - { - botimport.Print(PRT_MESSAGE, "goal not reachable\n"); - } //end if - else - { - AAS_ReachabilityFromNum(reachnum, &reach); - AAS_ClearShownDebugLines(); - AAS_ShowArea(area, qtrue); - AAS_ShowArea(reach.areanum, qtrue); - AAS_DrawCross(reach.start, 6, LINECOLOR_BLUE); - AAS_DrawCross(reach.end, 6, LINECOLOR_RED); - // - if ((reach.traveltype & TRAVELTYPE_MASK) == TRAVEL_ELEVATOR) - { - ElevatorBottomCenter(&reach, bottomcenter); - AAS_DrawCross(bottomcenter, 10, LINECOLOR_GREEN); - } //end if - } //end else*/ -// botimport.Print(PRT_MESSAGE, "travel time to goal = %d\n", -// AAS_AreaTravelTimeToGoalArea(area, origin, botlibglobals.goalareanum, TFL_DEFAULT)); -// botimport.Print(PRT_MESSAGE, "test rj from 703 to 716\n"); -// AAS_Reachability_WeaponJump(703, 716); -// } //end if*/ - -/* face = AAS_AreaGroundFace(newarea, parm2); - if (face) - { - AAS_ShowFace(face - aasworld.faces); - } //end if*/ - /* - AAS_ClearShownDebugLines(); - AAS_ShowArea(newarea, parm0 & BUTTON_USE); - AAS_ShowReachableAreas(area); - */ - AAS_ClearShownPolygons(); - AAS_ClearShownDebugLines(); - AAS_ShowAreaPolygons(newarea, 1, parm0 & 4); - if (parm0 & 2) AAS_ShowReachableAreas(area); - else - { - static int lastgoalareanum, lastareanum; - static int avoidreach[MAX_AVOIDREACH]; - static float avoidreachtimes[MAX_AVOIDREACH]; - static int avoidreachtries[MAX_AVOIDREACH]; - int reachnum, resultFlags; - bot_goal_t goal; - aas_reachability_t reach; - - /* - goal.areanum = botlibglobals.goalareanum; - VectorCopy(botlibglobals.goalorigin, goal.origin); - reachnum = BotGetReachabilityToGoal(origin, newarea, - lastgoalareanum, lastareanum, - avoidreach, avoidreachtimes, avoidreachtries, - &goal, TFL_DEFAULT|TFL_FUNCBOB|TFL_ROCKETJUMP, - NULL, 0, &resultFlags); - AAS_ReachabilityFromNum(reachnum, &reach); - AAS_ShowReachability(&reach); - */ - int curarea; - vec3_t curorigin; - - goal.areanum = botlibglobals.goalareanum; - VectorCopy(botlibglobals.goalorigin, goal.origin); - VectorCopy(origin, curorigin); - curarea = newarea; - for ( i = 0; i < 100; i++ ) { - if ( curarea == goal.areanum ) { - break; - } - reachnum = BotGetReachabilityToGoal(curorigin, curarea, - lastgoalareanum, lastareanum, - avoidreach, avoidreachtimes, avoidreachtries, - &goal, TFL_DEFAULT|TFL_FUNCBOB|TFL_ROCKETJUMP, - NULL, 0, &resultFlags); - AAS_ReachabilityFromNum(reachnum, &reach); - AAS_ShowReachability(&reach); - VectorCopy(reach.end, origin); - lastareanum = curarea; - curarea = reach.areanum; - } - } //end else - VectorClear(forward); - //BotGapDistance(origin, forward, 0); - /* - if (parm0 & BUTTON_USE) - { - botimport.Print(PRT_MESSAGE, "test rj from 703 to 716\n"); - AAS_Reachability_WeaponJump(703, 716); - } //end if*/ - -// AngleVectors(parm3, forward, right, NULL); - //get the eye 16 units to the right of the origin -// VectorMA(parm2, 8, right, eye); - //get the eye 24 units up -// eye[2] += 24; - //get the end point for the line to be traced -// VectorMA(eye, 800, forward, end); - -// AAS_TestMovementPrediction(1, parm2, forward, MASK_PLAYERSOLID); -/* - //trace the line to find the hit point - trace = AAS_TracePlayerBBox(eye, end, PRESENCE_NORMAL, 1, MASK_PLAYERSOLID); - if (!line[0]) line[0] = botimport.DebugLineCreate(); - botimport.DebugLineShow(line[0], eye, trace.endpos, LINECOLOR_BLUE); - // - AAS_ClearShownDebugLines(); - if (trace.ent) - { - ent = &aasworld.entities[trace.ent]; - AAS_ShowBoundingBox(ent->origin, ent->mins, ent->maxs); - } //end if -*/ - -/* - start_time = clock(); - for (i = 0; i < 2000; i++) - { - AAS_Trace2(eye, mins, maxs, end, 1, MASK_PLAYERSOLID); -// AAS_TracePlayerBBox(eye, end, PRESENCE_NORMAL, 1, MASK_PLAYERSOLID); - } //end for - end_time = clock(); - botimport.Print(PRT_MESSAGE, "me %lu clocks, %lu CLOCKS_PER_SEC\n", end_time - start_time, CLOCKS_PER_SEC); - start_time = clock(); - for (i = 0; i < 2000; i++) - { - AAS_Trace(eye, mins, maxs, end, 1, MASK_PLAYERSOLID); - } //end for - end_time = clock(); - botimport.Print(PRT_MESSAGE, "id %lu clocks, %lu CLOCKS_PER_SEC\n", end_time - start_time, CLOCKS_PER_SEC); -*/ - - // TTimo: nested comments are BAD for gcc -Werror, use #if 0 instead.. -#if 0 - AAS_ClearShownDebugLines(); - //bsptrace = AAS_Trace(eye, NULL, NULL, end, 1, MASK_PLAYERSOLID); - bsptrace = AAS_Trace(eye, mins, maxs, end, 1, MASK_PLAYERSOLID); - if (!line[0]) line[0] = botimport.DebugLineCreate(); - botimport.DebugLineShow(line[0], eye, bsptrace.endpos, LINECOLOR_YELLOW); - if (bsptrace.fraction < 1.0) - { - face = AAS_TraceEndFace(&trace); - if (face) - { - AAS_ShowFace(face - aasworld.faces); - } //end if - - AAS_DrawPlaneCross(bsptrace.endpos, - bsptrace.plane.normal, - bsptrace.plane.dist + bsptrace.exp_dist, - bsptrace.plane.type, LINECOLOR_GREEN); - if (trace.ent) - { - ent = &aasworld.entities[trace.ent]; - AAS_ShowBoundingBox(ent->origin, ent->mins, ent->maxs); - } //end if - } //end if - //bsptrace = AAS_Trace2(eye, NULL, NULL, end, 1, MASK_PLAYERSOLID); - bsptrace = AAS_Trace2(eye, mins, maxs, end, 1, MASK_PLAYERSOLID); - botimport.DebugLineShow(line[1], eye, bsptrace.endpos, LINECOLOR_BLUE); - if (bsptrace.fraction < 1.0) - { - AAS_DrawPlaneCross(bsptrace.endpos, - bsptrace.plane.normal, - bsptrace.plane.dist,// + bsptrace.exp_dist, - bsptrace.plane.type, LINECOLOR_RED); - if (bsptrace.ent) - { - ent = &aasworld.entities[bsptrace.ent]; - AAS_ShowBoundingBox(ent->origin, ent->mins, ent->maxs); - } //end if - } //end if -#endif -#endif - return 0; -} //end of the function BotExportTest /* @@ -659,6 +296,25 @@ static void Init_AAS_Export( aas_export_t *aas ) { aas->AAS_PresenceTypeBoundingBox = AAS_PresenceTypeBoundingBox; aas->AAS_Time = AAS_Time; //-------------------------------------------- + // be_aas_debug.c + //-------------------------------------------- + aas->AAS_ClearShownDebugLines = AAS_ClearShownDebugLines; + aas->AAS_ClearShownPolygons = AAS_ClearShownPolygons; + aas->AAS_DebugLine = AAS_DebugLine; + aas->AAS_PermanentLine = AAS_PermanentLine; + aas->AAS_DrawPermanentCross = AAS_DrawPermanentCross; + aas->AAS_DrawPlaneCross = AAS_DrawPlaneCross; + aas->AAS_ShowBoundingBox = AAS_ShowBoundingBox; + aas->AAS_ShowFace = AAS_ShowFace; + aas->AAS_ShowArea = AAS_ShowArea; + aas->AAS_ShowAreaPolygons = AAS_ShowAreaPolygons; + aas->AAS_DrawCross = AAS_DrawCross; + aas->AAS_PrintTravelType = AAS_PrintTravelType; + aas->AAS_DrawArrow = AAS_DrawArrow; + aas->AAS_ShowReachability = AAS_ShowReachability; + aas->AAS_ShowReachableAreas = AAS_ShowReachableAreas; + aas->AAS_FloodAreas = AAS_FloodAreas; + //-------------------------------------------- // be_aas_sample.c //-------------------------------------------- aas->AAS_PointAreaNum = AAS_PointAreaNum; @@ -746,18 +402,9 @@ botlib_export_t *GetBotLibAPI(int apiVersion, botlib_import_t *import) { be_botlib_export.BotLibVarSet = Export_BotLibVarSet; be_botlib_export.BotLibVarGet = Export_BotLibVarGet; - be_botlib_export.PC_AddGlobalDefine = PC_AddGlobalDefine; - be_botlib_export.PC_RemoveAllGlobalDefines = PC_RemoveAllGlobalDefines; - be_botlib_export.PC_LoadSourceHandle = PC_LoadSourceHandle; - be_botlib_export.PC_FreeSourceHandle = PC_FreeSourceHandle; - be_botlib_export.PC_ReadTokenHandle = PC_ReadTokenHandle; - be_botlib_export.PC_UnreadLastTokenHandle = PC_UnreadLastTokenHandle; - be_botlib_export.PC_SourceFileAndLine = PC_SourceFileAndLine; - be_botlib_export.BotLibStartFrame = Export_BotLibStartFrame; be_botlib_export.BotLibLoadMap = Export_BotLibLoadMap; be_botlib_export.BotLibUpdateEntity = Export_BotLibUpdateEntity; - be_botlib_export.Test = BotExportTest; return &be_botlib_export; } diff --git a/code/botlib/be_interface.h b/code/botlib/be_interface.h index 826d3d879..452992049 100644 --- a/code/botlib/be_interface.h +++ b/code/botlib/be_interface.h @@ -47,12 +47,6 @@ typedef struct botlib_globals_s int maxentities; //maximum number of entities int maxclients; //maximum number of clients float time; //the global time -#ifdef DEBUG - qboolean debug; //true if debug is on - int goalareanum; - vec3_t goalorigin; - int runai; -#endif } botlib_globals_t; diff --git a/code/botlib/botlib.h b/code/botlib/botlib.h index bbffef63f..bbe17a793 100644 --- a/code/botlib/botlib.h +++ b/code/botlib/botlib.h @@ -144,6 +144,25 @@ typedef struct aas_export_s int (*AAS_Initialized)(void); void (*AAS_PresenceTypeBoundingBox)(int presencetype, vec3_t mins, vec3_t maxs); float (*AAS_Time)(void); + //----------------------------------- + // be_aas_debug.c + //----------------------------------- + void (*AAS_ClearShownDebugLines)(void); + void (*AAS_ClearShownPolygons)(void); + void (*AAS_DebugLine)(vec3_t start, vec3_t end, int color); + void (*AAS_PermanentLine)(vec3_t start, vec3_t end, int color); + void (*AAS_DrawPermanentCross)(vec3_t origin, float size, int color); + void (*AAS_DrawPlaneCross)(vec3_t point, vec3_t normal, float dist, int type, int color); + void (*AAS_ShowBoundingBox)(vec3_t origin, vec3_t mins, vec3_t maxs); + void (*AAS_ShowFace)(int facenum); + void (*AAS_ShowArea)(int areanum, int groundfacesonly); + void (*AAS_ShowAreaPolygons)(int areanum, int color, int groundfacesonly); + void (*AAS_DrawCross)(vec3_t origin, float size, int color); + void (*AAS_PrintTravelType)(int traveltype); + void (*AAS_DrawArrow)(vec3_t start, vec3_t end, int linecolor, int arrowcolor); + void (*AAS_ShowReachability)(struct aas_reachability_s *reach, int contentmask); + void (*AAS_ShowReachableAreas)(int areanum, int contentmask); + void (*AAS_FloodAreas)(vec3_t origin); //-------------------------------------------- // be_aas_sample.c //-------------------------------------------- @@ -231,23 +250,12 @@ typedef struct botlib_export_s //gets a library variable returns BLERR_ int (*BotLibVarGet)(const char *var_name, char *value, int size); - //sets a C-like define returns BLERR_ - int (*PC_AddGlobalDefine)(char *string); - void (*PC_RemoveAllGlobalDefines)(void); - int (*PC_LoadSourceHandle)(const char *filename, const char *basepath); - int (*PC_FreeSourceHandle)(int handle); - int (*PC_ReadTokenHandle)(int handle, pc_token_t *pc_token); - void (*PC_UnreadLastTokenHandle)(int handle); - int (*PC_SourceFileAndLine)(int handle, char *filename, int *line); - //start a frame in the bot library int (*BotLibStartFrame)(float time); //load a new map in the bot library int (*BotLibLoadMap)(const char *mapname); //entity updates int (*BotLibUpdateEntity)(int ent, bot_entitystate_t *state); - //just for testing - int (*Test)(int parm0, char *parm1, vec3_t parm2, vec3_t parm3); } botlib_export_t; //linking of bot library diff --git a/code/botlib/l_memory.c b/code/botlib/l_memory.c index 77008476a..c53428eae 100644 --- a/code/botlib/l_memory.c +++ b/code/botlib/l_memory.c @@ -38,6 +38,7 @@ Suite 120, Rockville, Maryland 20850 USA. *****************************************************************************/ #include "../qcommon/q_shared.h" +#include "../qcommon/qcommon.h" #include "botlib.h" #include "l_log.h" #include "l_memory.h" @@ -53,6 +54,48 @@ int allocatedmemory; int totalmemorysize; int numblocks; +/* +================== +BotImport_GetMemory +================== +*/ +static void *BotImport_GetMemory(int size) { + void *ptr; + + ptr = Z_TagMalloc( size, TAG_BOTLIB ); + return ptr; +} + +/* +================== +BotImport_FreeMemory +================== +*/ +static void BotImport_FreeMemory(void *ptr) { + Z_Free(ptr); +} + +/* +================= +BotImport_HunkAlloc +================= +*/ +static void *BotImport_HunkAlloc( int size ) { + if( Hunk_CheckMark() ) { + Com_Error( ERR_DROP, "SV_Bot_HunkAlloc: Alloc with marks already set" ); + } + return Hunk_Alloc( size, h_high ); +} + +/* +================= +BotImport_AvailableMemory +================= +*/ +static int BotImport_AvailableMemory( void ) { + return Z_AvailableMemory(); +} + #ifdef MEMORYMANEGER typedef struct memoryblock_s @@ -109,8 +152,8 @@ void *GetMemory(unsigned long size) { void *ptr; memoryblock_t *block; - assert(botimport.GetMemory); - ptr = botimport.GetMemory(size + sizeof(memoryblock_t)); + //assert(BotImport_GetMemory); + ptr = BotImport_GetMemory(size + sizeof(memoryblock_t)); block = (memoryblock_t *) ptr; block->id = MEM_ID; block->ptr = (char *) ptr + sizeof(memoryblock_t); @@ -162,7 +205,7 @@ void *GetHunkMemory(unsigned long size) void *ptr; memoryblock_t *block; - ptr = botimport.HunkAlloc(size + sizeof(memoryblock_t)); + ptr = BotImport_HunkAlloc(size + sizeof(memoryblock_t)); block = (memoryblock_t *) ptr; block->id = HUNK_ID; block->ptr = (char *) ptr + sizeof(memoryblock_t); @@ -214,19 +257,19 @@ memoryblock_t *BlockFromPointer(void *ptr, char *str) #ifdef MEMDEBUG //char *crash = (char *) NULL; //crash[0] = 1; - botimport.Print(PRT_FATAL, "%s: NULL pointer\n", str); + BotImport_Print(PRT_FATAL, "%s: NULL pointer\n", str); #endif // MEMDEBUG return NULL; } //end if block = (memoryblock_t *) ((char *) ptr - sizeof(memoryblock_t)); if (block->id != MEM_ID && block->id != HUNK_ID) { - botimport.Print(PRT_FATAL, "%s: invalid memory block\n", str); + BotImport_Print(PRT_FATAL, "%s: invalid memory block\n", str); return NULL; } //end if if (block->ptr != ptr) { - botimport.Print(PRT_FATAL, "%s: memory block pointer invalid\n", str); + BotImport_Print(PRT_FATAL, "%s: memory block pointer invalid\n", str); return NULL; } //end if return block; @@ -250,7 +293,7 @@ void FreeMemory(void *ptr) // if (block->id == MEM_ID) { - botimport.FreeMemory(block); + BotImport_FreeMemory(block); } //end if } //end of the function FreeMemory //=========================================================================== @@ -261,7 +304,7 @@ void FreeMemory(void *ptr) //=========================================================================== int AvailableMemory(void) { - return botimport.AvailableMemory(); + return BotImport_AvailableMemory(); } //end of the function AvailableMemory //=========================================================================== // @@ -285,9 +328,9 @@ int MemoryByteSize(void *ptr) //=========================================================================== void PrintUsedMemorySize(void) { - botimport.Print(PRT_MESSAGE, "total allocated memory: %d KB\n", allocatedmemory >> 10); - botimport.Print(PRT_MESSAGE, "total botlib memory: %d KB\n", totalmemorysize >> 10); - botimport.Print(PRT_MESSAGE, "total memory blocks: %d\n", numblocks); + BotImport_Print(PRT_MESSAGE, "total allocated memory: %d KB\n", allocatedmemory >> 10); + BotImport_Print(PRT_MESSAGE, "total botlib memory: %d KB\n", totalmemorysize >> 10); + BotImport_Print(PRT_MESSAGE, "total memory blocks: %d\n", numblocks); } //end of the function PrintUsedMemorySize //=========================================================================== // @@ -354,7 +397,7 @@ void *GetMemory(unsigned long size) void *ptr; unsigned long int *memid; - ptr = botimport.GetMemory(size + sizeof(unsigned long int)); + ptr = BotImport_GetMemory(size + sizeof(unsigned long int)); if (!ptr) return NULL; memid = (unsigned long int *) ptr; *memid = MEM_ID; @@ -396,7 +439,7 @@ void *GetHunkMemory(unsigned long size) void *ptr; unsigned long int *memid; - ptr = botimport.HunkAlloc(size + sizeof(unsigned long int)); + ptr = BotImport_HunkAlloc(size + sizeof(unsigned long int)); if (!ptr) return NULL; memid = (unsigned long int *) ptr; *memid = HUNK_ID; @@ -437,7 +480,7 @@ void FreeMemory(void *ptr) if (*memid == MEM_ID) { - botimport.FreeMemory(memid); + BotImport_FreeMemory(memid); } //end if } //end of the function FreeMemory //=========================================================================== @@ -448,7 +491,7 @@ void FreeMemory(void *ptr) //=========================================================================== int AvailableMemory(void) { - return botimport.AvailableMemory(); + return BotImport_AvailableMemory(); } //end of the function AvailableMemory //=========================================================================== // diff --git a/code/botlib/l_precomp.c b/code/botlib/l_precomp.c index 21b9c558e..754dc1e16 100644 --- a/code/botlib/l_precomp.c +++ b/code/botlib/l_precomp.c @@ -59,6 +59,7 @@ typedef enum {qfalse, qtrue} qboolean; #ifdef BOTLIB #include "../qcommon/q_shared.h" +#include "../qcommon/qcommon.h" #include "botlib.h" #include "be_interface.h" #include "l_memory.h" @@ -100,7 +101,7 @@ token_t *freetokens; //free tokens from the heap */ //list with global defines added to every source loaded -define_t *globaldefines; +define_t *globaldefines_implicit; //============================================================================ // @@ -117,7 +118,7 @@ void QDECL SourceError(source_t *source, char *str, ...) Q_vsnprintf(text, sizeof(text), str, ap); va_end(ap); #ifdef BOTLIB - botimport.Print(PRT_ERROR, "file %s, line %d: %s\n", source->scriptstack->filename, source->scriptstack->line, text); + Com_Printf(S_COLOR_RED "Error: file %s, line %d: %s\n", source->scriptstack->filename, source->scriptstack->line, text); #endif //BOTLIB #ifdef BSPC Log_Print("error: file %s, line %d: %s\n", source->scriptstack->filename, source->scriptstack->line, text); @@ -138,7 +139,7 @@ void QDECL SourceWarning(source_t *source, char *str, ...) Q_vsnprintf(text, sizeof(text), str, ap); va_end(ap); #ifdef BOTLIB - botimport.Print(PRT_WARNING, "file %s, line %d: %s\n", source->scriptstack->filename, source->scriptstack->line, text); + Com_Printf(S_COLOR_YELLOW "Warning: file %s, line %d: %s\n", source->scriptstack->filename, source->scriptstack->line, text); #endif //BOTLIB #ifdef BSPC Log_Print("warning: file %s, line %d: %s\n", source->scriptstack->filename, source->scriptstack->line, text); @@ -494,6 +495,7 @@ void PC_PrintDefine(define_t *define) // struct define_s *next; //next defined macro in a list } //end of the function PC_PrintDefine*/ #if DEFINEHASHING +#if 0 //============================================================================ // // Parameter: - @@ -515,6 +517,7 @@ void PC_PrintDefineHashTable(define_t **definehash) Log_Write("\n"); } //end for } //end of the function PC_PrintDefineHashTable +#endif //============================================================================ // // Parameter: - @@ -1276,7 +1279,7 @@ int PC_Directive_define(source_t *source) // Returns: - // Changes Globals: - //============================================================================ -define_t *PC_DefineFromString(char *string) +define_t *PC_DefineFromString(const char *string) { script_t *script; source_t src; @@ -1334,7 +1337,7 @@ define_t *PC_DefineFromString(char *string) // Returns: - // Changes Globals: - //============================================================================ -int PC_AddDefine(source_t *source, char *string) +int PC_AddDefine(source_t *source, const char *string) { define_t *define; @@ -1355,14 +1358,17 @@ int PC_AddDefine(source_t *source, char *string) // Returns: - // Changes Globals: - //============================================================================ -int PC_AddGlobalDefine(char *string) +int PC_AddGlobalDefine(define_t **globaldefines, const char *string) { define_t *define; + if ( !globaldefines ) + globaldefines = &globaldefines_implicit; + define = PC_DefineFromString(string); if (!define) return qfalse; - define->next = globaldefines; - globaldefines = define; + define->next = *globaldefines; + *globaldefines = define; return qtrue; } //end of the function PC_AddGlobalDefine //============================================================================ @@ -1372,16 +1378,28 @@ int PC_AddGlobalDefine(char *string) // Returns: - // Changes Globals: - //============================================================================ -int PC_RemoveGlobalDefine(char *name) +int PC_RemoveGlobalDefine(define_t **globaldefines, const char *name) { - define_t *define; + define_t *define, *previous, *next; - define = PC_FindDefine(globaldefines, name); - if (define) + if ( !globaldefines ) + globaldefines = &globaldefines_implicit; + + previous = NULL; + for (define = *globaldefines; define; define = next) { - PC_FreeDefine(define); - return qtrue; - } //end if + next = define->next; + if (!strcmp(define->name, name)) { + if (previous) { + previous->next = next; + } else { + *globaldefines = next; + } + PC_FreeDefine(define); + return qtrue; + } + previous = define; + } //end for return qfalse; } //end of the function PC_RemoveGlobalDefine //============================================================================ @@ -1391,15 +1409,19 @@ int PC_RemoveGlobalDefine(char *name) // Returns: - // Changes Globals: - //============================================================================ -void PC_RemoveAllGlobalDefines(void) +void PC_RemoveAllGlobalDefines(define_t **globaldefines) { define_t *define; - for (define = globaldefines; define; define = globaldefines) + if ( !globaldefines ) + globaldefines = &globaldefines_implicit; + + for (define = *globaldefines; define; define = *globaldefines) { - globaldefines = globaldefines->next; + *globaldefines = (*globaldefines)->next; PC_FreeDefine(define); } //end for + *globaldefines = NULL; } //end of the function PC_RemoveAllGlobalDefines //============================================================================ // @@ -1407,7 +1429,7 @@ void PC_RemoveAllGlobalDefines(void) // Returns: - // Changes Globals: - //============================================================================ -define_t *PC_CopyDefine(source_t *source, define_t *define) +define_t *PC_CopyDefine(source_t *source, const define_t *define) { define_t *newdefine; token_t *token, *newtoken, *lasttoken; @@ -1450,9 +1472,13 @@ define_t *PC_CopyDefine(source_t *source, define_t *define) // Returns: - // Changes Globals: - //============================================================================ -void PC_AddGlobalDefinesToSource(source_t *source) +void PC_AddGlobalDefinesToSource(source_t *source, const define_t *globaldefines) { - define_t *define, *newdefine; + const define_t *define; + define_t *newdefine; + + if (!globaldefines) + globaldefines = globaldefines_implicit; for (define = globaldefines; define; define = define->next) { @@ -2894,7 +2920,7 @@ void PC_SetPunctuations(source_t *source, punctuation_t *p) // Returns: - // Changes Globals: - //============================================================================ -source_t *LoadSourceFile(const char *filename) +source_t *LoadSourceFile(const char *filename, const define_t *globaldefines) { source_t *source; script_t *script; @@ -2919,7 +2945,7 @@ source_t *LoadSourceFile(const char *filename) #if DEFINEHASHING source->definehash = GetClearedMemory(DEFINEHASHSIZE * sizeof(define_t *)); #endif //DEFINEHASHING - PC_AddGlobalDefinesToSource(source); + PC_AddGlobalDefinesToSource(source, globaldefines); return source; } //end of the function LoadSourceFile //============================================================================ @@ -2928,7 +2954,7 @@ source_t *LoadSourceFile(const char *filename) // Returns: - // Changes Globals: - //============================================================================ -source_t *LoadSourceMemory(char *ptr, int length, char *name) +source_t *LoadSourceMemory(const char *ptr, int length, const char *name, const define_t *globaldefines) { source_t *source; script_t *script; @@ -2952,7 +2978,7 @@ source_t *LoadSourceMemory(char *ptr, int length, char *name) #if DEFINEHASHING source->definehash = GetClearedMemory(DEFINEHASHSIZE * sizeof(define_t *)); #endif //DEFINEHASHING - PC_AddGlobalDefinesToSource(source); + PC_AddGlobalDefinesToSource(source, globaldefines); return source; } //end of the function LoadSourceMemory //============================================================================ @@ -3028,7 +3054,7 @@ void FreeSource(source_t *source) source_t *sourceFiles[MAX_SOURCEFILES]; -int PC_LoadSourceHandle(const char *filename, const char *basepath) +int PC_LoadSourceHandle(const char *filename, const char *basepath, const define_t *globaldefines) { source_t *source; int i; @@ -3041,7 +3067,7 @@ int PC_LoadSourceHandle(const char *filename, const char *basepath) if (i >= MAX_SOURCEFILES) return 0; PS_SetBaseFolder(basepath); - source = LoadSourceFile(filename); + source = LoadSourceFile(filename, globaldefines); if (!source) return 0; sourceFiles[i] = source; @@ -3070,6 +3096,21 @@ int PC_FreeSourceHandle(int handle) // Returns: - // Changes Globals: - //============================================================================ +int PC_AddDefineHandle(int handle, const char *define) +{ + if (handle < 1 || handle >= MAX_SOURCEFILES) + return qfalse; + if (!sourceFiles[handle]) + return qfalse; + + return PC_AddDefine(sourceFiles[handle], define); +} //end of the function PC_FreeSourceHandle +//============================================================================ +// +// Parameter: - +// Returns: - +// Changes Globals: - +//============================================================================ int PC_ReadTokenHandle(int handle, pc_token_t *pc_token) { token_t token; @@ -3153,7 +3194,7 @@ void PC_CheckOpenSourceHandles(void) if (sourceFiles[i]) { #ifdef BOTLIB - botimport.Print(PRT_ERROR, "file %s still open in precompiler\n", sourceFiles[i]->scriptstack->filename); + Com_Printf(S_COLOR_RED "Error: file %s still open in precompiler\n", sourceFiles[i]->scriptstack->filename); #endif //BOTLIB } //end if } //end for diff --git a/code/botlib/l_precomp.h b/code/botlib/l_precomp.h index da16880bd..dc1414dfb 100644 --- a/code/botlib/l_precomp.h +++ b/code/botlib/l_precomp.h @@ -134,13 +134,13 @@ int PC_ReadLine(source_t *source, token_t *token); //returns true if there was a white space in front of the token int PC_WhiteSpaceBeforeToken(token_t *token); //add a define to the source -int PC_AddDefine(source_t *source, char *string); +int PC_AddDefine(source_t *source, const char *string); //add a globals define that will be added to all opened sources -int PC_AddGlobalDefine(char *string); +int PC_AddGlobalDefine(define_t **globaldefines, const char *string); //remove the given global define -int PC_RemoveGlobalDefine(char *name); +int PC_RemoveGlobalDefine(define_t **globaldefines, const char *string); //remove all globals defines -void PC_RemoveAllGlobalDefines(void); +void PC_RemoveAllGlobalDefines(define_t **globaldefines); //add builtin defines void PC_AddBuiltinDefines(source_t *source); //set the source include path @@ -150,9 +150,9 @@ void PC_SetPunctuations(source_t *source, punctuation_t *p); //set the base folder to load files from void PC_SetBaseFolder(const char *path); //load a source file -source_t *LoadSourceFile(const char *filename); +source_t *LoadSourceFile(const char *filename, const define_t *globaldefines); //load a source from memory -source_t *LoadSourceMemory(char *ptr, int length, char *name); +source_t *LoadSourceMemory(const char *ptr, int length, const char *name, const define_t *globaldefines); //free the given source void FreeSource(source_t *source); //print a source error @@ -161,8 +161,9 @@ void QDECL SourceError(source_t *source, char *str, ...) __attribute__ ((format void QDECL SourceWarning(source_t *source, char *str, ...) __attribute__ ((format (printf, 2, 3))); // -int PC_LoadSourceHandle(const char *filename, const char *basepath); +int PC_LoadSourceHandle(const char *filename, const char *basepath, const define_t *globaldefines); int PC_FreeSourceHandle(int handle); +int PC_AddDefineHandle(int handle, const char *define); int PC_ReadTokenHandle(int handle, pc_token_t *pc_token); void PC_UnreadLastTokenHandle( int handle ); int PC_SourceFileAndLine(int handle, char *filename, int *line); diff --git a/code/botlib/l_script.c b/code/botlib/l_script.c index 10189365f..cba542664 100644 --- a/code/botlib/l_script.c +++ b/code/botlib/l_script.c @@ -57,6 +57,7 @@ typedef enum {qfalse, qtrue} qboolean; #ifdef BOTLIB //include files for usage in the bot library #include "../qcommon/q_shared.h" +#include "../qcommon/qcommon.h" #include "botlib.h" #include "be_interface.h" #include "l_script.h" @@ -230,7 +231,7 @@ void QDECL ScriptError(script_t *script, char *str, ...) Q_vsnprintf(text, sizeof(text), str, ap); va_end(ap); #ifdef BOTLIB - botimport.Print(PRT_ERROR, "file %s, line %d: %s\n", script->filename, script->line, text); + Com_Printf(S_COLOR_RED "Error: file %s, line %d: %s\n", script->filename, script->line, text); #endif //BOTLIB #ifdef BSPC Log_Print("error: file %s, line %d: %s\n", script->filename, script->line, text); @@ -253,7 +254,7 @@ void QDECL ScriptWarning(script_t *script, char *str, ...) Q_vsnprintf(text, sizeof(text), str, ap); va_end(ap); #ifdef BOTLIB - botimport.Print(PRT_WARNING, "file %s, line %d: %s\n", script->filename, script->line, text); + Com_Printf(S_COLOR_YELLOW "Warning: file %s, line %d: %s\n", script->filename, script->line, text); #endif //BOTLIB #ifdef BSPC Log_Print("warning: file %s, line %d: %s\n", script->filename, script->line, text); @@ -1325,7 +1326,7 @@ script_t *LoadScriptFile(const char *filename) Com_sprintf(pathname, sizeof(pathname), "%s/%s", basefolder, filename); else Com_sprintf(pathname, sizeof(pathname), "%s", filename); - length = botimport.FS_FOpenFile( pathname, &fp, FS_READ ); + length = FS_FOpenFileByMode( pathname, &fp, FS_READ ); if (!fp) return NULL; #else fp = fopen(filename, "rb"); @@ -1356,8 +1357,8 @@ script_t *LoadScriptFile(const char *filename) SetScriptPunctuations(script, NULL); // #ifdef BOTLIB - botimport.FS_Read(script->buffer, length, fp); - botimport.FS_FCloseFile(fp); + FS_Read(script->buffer, length, fp); + FS_FCloseFile(fp); #else if (fread(script->buffer, length, 1, fp) != 1) { @@ -1375,7 +1376,7 @@ script_t *LoadScriptFile(const char *filename) // Returns: - // Changes Globals: - //============================================================================ -script_t *LoadScriptMemory(char *ptr, int length, char *name) +script_t *LoadScriptMemory(const char *ptr, int length, const char *name) { void *buffer; script_t *script; diff --git a/code/botlib/l_script.h b/code/botlib/l_script.h index 4e78cb62c..00fea25f2 100644 --- a/code/botlib/l_script.h +++ b/code/botlib/l_script.h @@ -238,7 +238,7 @@ char *PunctuationFromNum(script_t *script, int num); //load a script from the given file at the given offset with the given length script_t *LoadScriptFile(const char *filename); //load a script from the given memory with the given length -script_t *LoadScriptMemory(char *ptr, int length, char *name); +script_t *LoadScriptMemory(const char *ptr, int length, const char *name); //free a script void FreeScript(script_t *script); //set the base folder to load files from diff --git a/code/bspc/aas_cfg.c b/code/bspc/aas_cfg.c index 3ab6c4964..8eaa5fafa 100644 --- a/code/bspc/aas_cfg.c +++ b/code/bspc/aas_cfg.c @@ -186,7 +186,7 @@ int LoadCfgFile(char *filename) token_t token; int settingsdefined; - source = LoadSourceFile(filename); + source = LoadSourceFile(filename, NULL); if (!source) { Log_Print("couldn't open cfg file %s\n", filename); diff --git a/code/bspc/be_aas_bspc.c b/code/bspc/be_aas_bspc.c index 82fce7534..65f0255eb 100644 --- a/code/bspc/be_aas_bspc.c +++ b/code/bspc/be_aas_bspc.c @@ -208,13 +208,28 @@ void Com_DPrintf(const char *fmt, ...) void AAS_InitBotImport(void) { botimport.MilliSeconds = Sys_MilliSeconds; - botimport.GetEntityToken = BotImport_GetEntityToken; - botimport.GetMemory = BotImport_GetMemory; - botimport.FreeMemory = FreeMemory; + botimport.Print = BotImport_Print; botimport.Trace = BotImport_Trace; + botimport.EntityTrace = NULL; botimport.PointContents = BotImport_PointContents; - botimport.Print = BotImport_Print; + botimport.inPVS = NULL; + botimport.GetEntityToken = BotImport_GetEntityToken; botimport.BSPModelMinsMaxsOrigin = BotImport_BSPModelMinsMaxsOrigin; + botimport.BotClientCommand = NULL; + botimport.GetMemory = BotImport_GetMemory; + botimport.FreeMemory = FreeMemory; + botimport.AvailableMemory = NULL; + botimport.HunkAlloc = NULL; + botimport.FS_FOpenFile = NULL; + botimport.FS_Read = NULL; + botimport.FS_Write = NULL; + botimport.FS_FCloseFile = NULL; + botimport.FS_Seek = NULL; + botimport.DebugLineCreate = NULL; + botimport.DebugLineDelete = NULL; + botimport.DebugLineShow = NULL; + botimport.DebugPolygonCreate = NULL; + botimport.DebugPolygonDelete = NULL; } //end of the function AAS_InitBotImport //=========================================================================== // diff --git a/code/cgame/cg_public.h b/code/cgame/cg_public.h index c16b7683a..97f6536d9 100644 --- a/code/cgame/cg_public.h +++ b/code/cgame/cg_public.h @@ -36,7 +36,7 @@ Suite 120, Rockville, Maryland 20850 USA. // major 0 means each minor is an API break. // major > 0 means each major is an API break and each minor extends API. #define CG_API_MAJOR_VERSION 0 -#define CG_API_MINOR_VERSION 37 +#define CG_API_MINOR_VERSION 38 #define CMD_BACKUP 64 @@ -221,18 +221,24 @@ typedef enum { CG_FS_DELETE, CG_FS_RENAME, - CG_PC_ADD_GLOBAL_DEFINE, - CG_PC_REMOVE_ALL_GLOBAL_DEFINES, - CG_PC_LOAD_SOURCE, - CG_PC_FREE_SOURCE, - CG_PC_READ_TOKEN, - CG_PC_UNREAD_TOKEN, - CG_PC_SOURCE_FILE_AND_LINE, + CG_PC_ADD_GLOBAL_DEFINE, // ( const char *define ); + CG_PC_REMOVE_GLOBAL_DEFINE, // ( const char *define ); + CG_PC_REMOVE_ALL_GLOBAL_DEFINES, // ( void ); + CG_PC_LOAD_SOURCE, // ( const char *filename, const char *basepath ); + CG_PC_FREE_SOURCE, // ( int handle ); + CG_PC_ADD_DEFINE, // ( int handle, const char *define ); + CG_PC_READ_TOKEN, // ( int handle, pc_token_t *pc_token ); + CG_PC_UNREAD_TOKEN, // ( int handle ); + CG_PC_SOURCE_FILE_AND_LINE, // ( int handle, char *filename, int *line ); CG_HEAP_MALLOC, // ( int size ); CG_HEAP_AVAILABLE, // ( void ); CG_HEAP_FREE, // ( void *data ); + CG_FIELD_COMPLETEFILENAME, // ( const char *dir, const char *ext, qboolean stripExt, qboolean allowNonPureFilesOnDisk ); + CG_FIELD_COMPLETECOMMAND, // ( const char *cmd, qboolean doCommands, qboolean doCvars ); + CG_FIELD_COMPLETELIST, // ( const char *list ); + //=========== client game specific functionality ============= CG_GETCLIPBOARDDATA = 100, @@ -341,6 +347,7 @@ typedef enum { CG_S_QUEUESTREAMINGSOUND, CG_S_GETSTREAMPLAYCOUNT, CG_S_SETSTREAMVOLUME, + CG_S_STOPALLSOUNDS, // note: these were not originally available in ui CG_S_STARTSOUND = 450, @@ -507,9 +514,12 @@ typedef enum { CG_CREATE_USER_CMD, // usercmd_t *CG_CreateUserCmd( int localPlayerNum, int frameTime, int frameMsec, float mx, float my, qboolean anykeydown ); - CG_UPDATE_GLCONFIG + CG_UPDATE_GLCONFIG, // void CG_UpdateGLConfig( void ); + CG_CONSOLE_COMPLETEARGUMENT, +// qboolean (*CG_ConsoleCompleteArgument)( connstate_t state, int realTime, int completeArgument ); + } cgameExport_t; #endif diff --git a/code/client/cl_cgame.c b/code/client/cl_cgame.c index 7d9bdabd4..a2040ce63 100644 --- a/code/client/cl_cgame.c +++ b/code/client/cl_cgame.c @@ -31,18 +31,22 @@ Suite 120, Rockville, Maryland 20850 USA. #include "client.h" -#include "../botlib/botlib.h" +#include "../botlib/l_script.h" +#include "../botlib/l_precomp.h" #ifdef USE_MUMBLE #include "libmumblelink.h" #endif -extern botlib_export_t *botlib_export; +define_t *cgame_globaldefines; extern qboolean loadCamera(const char *name); extern void startCamera(int time); extern qboolean getCameraInfo(int time, vec3_t *origin, vec3_t *angles); +void CL_GameCommand( void ); +void CL_GameCompleteArgument( char *args, int argNum ); + /* ==================== CL_GetGameState @@ -1136,7 +1140,6 @@ void CL_ShutdownCGame( void ) { Mouse_ClearStates(); cls.cgameStarted = qfalse; cls.printToCgame = qfalse; - cls.enteredMenu = qfalse; if ( !cgvm ) { return; } @@ -1147,6 +1150,12 @@ void CL_ShutdownCGame( void ) { Cmd_RemoveCommandsByFunc( CL_GameCommand ); + //remove all global defines from the pre compiler + PC_RemoveAllGlobalDefines( &cgame_globaldefines ); + + // print any files still open + PC_CheckOpenSourceHandles(); + BSP_Free( cls.cgameBsp ); cls.cgameBsp = NULL; } @@ -1224,7 +1233,7 @@ intptr_t CL_CgameSystemCalls( intptr_t *args ) { FS_FCloseFile( args[1] ); return 0; case CG_FS_GETFILELIST: - return FS_GetFileList( VMA(1), VMA(2), VMA(3), args[4] ); + return FS_GetFileListBuffer( VMA(1), VMA(2), VMA(3), args[4] ); case CG_FS_DELETE: return FS_Delete( VMA(1) ); case CG_FS_RENAME: @@ -1233,7 +1242,7 @@ intptr_t CL_CgameSystemCalls( intptr_t *args ) { Cbuf_ExecuteTextSafe( args[1], VMA(2) ); return 0; case CG_ADDCOMMAND: - Cmd_AddCommandSafe( VMA(1), CL_GameCommand ); + Cmd_AddCommandSafe( VMA(1), CL_GameCommand, CL_GameCompleteArgument ); return 0; case CG_REMOVECOMMAND: Cmd_RemoveCommandSafe( VMA(1), CL_GameCommand ); @@ -1244,6 +1253,15 @@ intptr_t CL_CgameSystemCalls( intptr_t *args ) { case CG_CMD_AUTOCOMPLETE: CL_Cmd_AutoComplete( VMA(1), VMA(2), args[3] ); return 0; + case CG_FIELD_COMPLETEFILENAME: + Field_CompleteFilename( VMA(1), VMA(2), args[3], args[4] ); + return 0; + case CG_FIELD_COMPLETECOMMAND: + Field_CompleteCommand( VMA(1), args[2], args[3] ); + return 0; + case CG_FIELD_COMPLETELIST: + Field_CompleteList( VMA(1) ); + return 0; case CG_SV_SHUTDOWN: SV_Shutdown( VMA(1) ); return 0; @@ -1341,6 +1359,9 @@ intptr_t CL_CgameSystemCalls( intptr_t *args ) { case CG_S_SETSTREAMVOLUME: S_SetStreamVolume( args[1], VMF(2) ); return 0; + case CG_S_STOPALLSOUNDS: + S_StopAllSounds(); + return 0; case CG_R_LOADWORLDMAP: CL_LoadWorldMap( VMA(1) ); return 0; @@ -1634,21 +1655,26 @@ intptr_t CL_CgameSystemCalls( intptr_t *args ) { case CG_PC_ADD_GLOBAL_DEFINE: - return botlib_export->PC_AddGlobalDefine( VMA(1) ); + return PC_AddGlobalDefine( &cgame_globaldefines, VMA(1) ); + case CG_PC_REMOVE_GLOBAL_DEFINE: + PC_RemoveGlobalDefine( &cgame_globaldefines, VMA(1) ); + return 0; case CG_PC_REMOVE_ALL_GLOBAL_DEFINES: - botlib_export->PC_RemoveAllGlobalDefines(); + PC_RemoveAllGlobalDefines( &cgame_globaldefines ); return 0; case CG_PC_LOAD_SOURCE: - return botlib_export->PC_LoadSourceHandle( VMA(1), VMA(2) ); + return PC_LoadSourceHandle( VMA(1), VMA(2), cgame_globaldefines ); case CG_PC_FREE_SOURCE: - return botlib_export->PC_FreeSourceHandle( args[1] ); + return PC_FreeSourceHandle( args[1] ); + case CG_PC_ADD_DEFINE: + return PC_AddDefineHandle( args[1], VMA(2) ); case CG_PC_READ_TOKEN: - return botlib_export->PC_ReadTokenHandle( args[1], VMA(2) ); + return PC_ReadTokenHandle( args[1], VMA(2) ); case CG_PC_UNREAD_TOKEN: - botlib_export->PC_UnreadLastTokenHandle( args[1] ); + PC_UnreadLastTokenHandle( args[1] ); return 0; case CG_PC_SOURCE_FILE_AND_LINE: - return botlib_export->PC_SourceFileAndLine( args[1], VMA(2), VMA(3) ); + return PC_SourceFileAndLine( args[1], VMA(2), VMA(3) ); case CG_HEAP_MALLOC: return VM_HeapMalloc( args[1] ); @@ -1869,6 +1895,21 @@ void CL_GameCommand( void ) { VM_Call( cgvm, CG_CONSOLE_COMMAND, clc.state, cls.realtime ); } +/* +==================== +CL_GameCompleteArgument + +Pass the current console command to cgame +==================== +*/ +void CL_GameCompleteArgument( char *args, int argNum ) { + if ( !cgvm ) { + return; + } + + VM_Call( cgvm, CG_CONSOLE_COMPLETEARGUMENT, clc.state, cls.realtime, argNum ); +} + /* ==================== CL_GameConsoleText @@ -1907,7 +1948,6 @@ void CL_ShowMainMenu( void ) { return; } - cls.enteredMenu = qtrue; VM_Call( cgvm, CG_SET_ACTIVE_MENU, UIMENU_NONE ); } diff --git a/code/client/cl_main.c b/code/client/cl_main.c index 16a3bcf05..f9f1dbaaf 100644 --- a/code/client/cl_main.c +++ b/code/client/cl_main.c @@ -3070,18 +3070,6 @@ void CL_Frame ( int msec ) { } #endif - if ( clc.state == CA_DISCONNECTED && !cls.enteredMenu - && !com_sv_running->integer && cgvm ) { - // if disconnected, bring up the menu - S_StopAllSounds(); - - // ZTM: Forcing main menu prevents displaying Team Arena Single Player postgame menu. - // CGame will load main menu if needed anyway. - // ZTM: TODO: Add trap_S_StopAllSounds to CGame so this block of code can be removed. - //CL_ShowMainMenu(); - cls.enteredMenu = qtrue; - } - // if recording an avi, lock to a fixed fps if ( CL_VideoRecording( ) && cl_aviFrameRate->integer && msec) { // save the current screen diff --git a/code/client/client.h b/code/client/client.h index f6c451d11..e359f2eff 100644 --- a/code/client/client.h +++ b/code/client/client.h @@ -335,7 +335,6 @@ typedef struct { qboolean soundRegistered; qboolean cgameStarted; - qboolean enteredMenu; qboolean printToCgame; // enabled after restoring console text to cgame bspFile_t *cgameBsp; @@ -591,7 +590,6 @@ void CIN_CloseAllVideos(void); // void CL_InitCGame( void ); void CL_ShutdownCGame( void ); -void CL_GameCommand( void ); void CL_CGameRendering( stereoFrame_t stereo ); void CL_ShowMainMenu( void ); void CL_UpdateGlconfig( void ); diff --git a/code/game/g_public.h b/code/game/g_public.h index 43e10730a..03489b9af 100644 --- a/code/game/g_public.h +++ b/code/game/g_public.h @@ -36,7 +36,7 @@ Suite 120, Rockville, Maryland 20850 USA. // major 0 means each minor is an API break. // major > 0 means each major is an API break and each minor extends API. #define GAME_API_MAJOR_VERSION 0 -#define GAME_API_MINOR_VERSION 14 +#define GAME_API_MINOR_VERSION 15 // entity->svFlags @@ -167,18 +167,24 @@ typedef enum { G_FS_DELETE, // ( const void *path ); G_FS_RENAME, // ( const void *from, const void *to ); - G_PC_ADD_GLOBAL_DEFINE, - G_PC_REMOVE_ALL_GLOBAL_DEFINES, - G_PC_LOAD_SOURCE, - G_PC_FREE_SOURCE, - G_PC_READ_TOKEN, - G_PC_UNREAD_TOKEN, - G_PC_SOURCE_FILE_AND_LINE, + G_PC_ADD_GLOBAL_DEFINE, // ( const char *define ); + G_PC_REMOVE_GLOBAL_DEFINE, // ( const char *define ); + G_PC_REMOVE_ALL_GLOBAL_DEFINES, // ( void ); + G_PC_LOAD_SOURCE, // ( const char *filename, const char *basepath ); + G_PC_FREE_SOURCE, // ( int handle ); + G_PC_ADD_DEFINE, // ( int handle, const char *define ); + G_PC_READ_TOKEN, // ( int handle, pc_token_t *pc_token ); + G_PC_UNREAD_TOKEN, // ( int handle ); + G_PC_SOURCE_FILE_AND_LINE, // ( int handle, char *filename, int *line ); G_HEAP_MALLOC, // ( int size ); G_HEAP_AVAILABLE, // ( void ); G_HEAP_FREE, // ( void *data ); + G_FIELD_COMPLETEFILENAME, // ( const char *dir, const char *ext, qboolean stripExt, qboolean allowNonPureFilesOnDisk ); + G_FIELD_COMPLETECOMMAND, // ( const char *cmd, qboolean doCommands, qboolean doCvars ); + G_FIELD_COMPLETELIST, // ( const char *list ); + //=========== server specific functionality ============= G_LOCATE_GAME_DATA = 100, // ( gentity_t *gEnts, int numGEntities, int sizeofGEntity_t, @@ -246,10 +252,13 @@ typedef enum { G_ENTITY_CONTACT, // ( const vec3_t mins, const vec3_t maxs, const gentity_t *ent ); // perform an exact check against inline brush models of non-square shape - // access for bots to get and free a server client (FIXME?) - G_BOT_ALLOCATE_CLIENT, // ( void ); - - G_BOT_FREE_CLIENT, // ( int playerNum ); + // access for bots to get and free a server client + G_BOT_ALLOCATE_CLIENT, // ( void ); + G_BOT_FREE_CLIENT, // ( int playerNum ); + G_BOT_GET_SNAPSHOT_ENTITY, // ( int playerNum, int ent ); + G_BOT_GET_SERVER_COMMAND, // ( int playerNum, char *command, int size ); + G_BOT_USER_COMMAND, // ( int playerNum, usercmd_t *ucmd ); + G_CLIENT_COMMAND, // ( int playerNum, const char *command ); G_GET_USERCMD, // ( int playerNum, usercmd_t *cmd ) @@ -273,83 +282,9 @@ typedef enum { // const vec3_t *torsoAxis, qhandle_t torsoFrameModel, int torsoFrame, qhandle_t oldTorsoFrameModel, int oldTorsoFrame, float torsoFrac ); G_R_MODELBOUNDS, // ( qhandle_t handle, vec3_t mins, vec3_t maxs, int startFrame, int endFrame, float frac ); - G_CLIENT_COMMAND, // ( int playerNum, const char *command ); - G_CLIPTOENTITIES, // ( trace_t *results, const vec3_t start, const vec3_t mins, const vec3_t maxs, const vec3_t end, int passEntityNum, int contentmask ); G_CLIPTOENTITIESCAPSULE, // ( trace_t *results, const vec3_t start, const vec3_t mins, const vec3_t maxs, const vec3_t end, int passEntityNum, int contentmask ); - BOTLIB_SETUP = 200, // ( void ); - BOTLIB_SHUTDOWN, // ( void ); - BOTLIB_LIBVAR_SET, - BOTLIB_LIBVAR_GET, - BOTLIB_START_FRAME, - BOTLIB_LOAD_MAP, - BOTLIB_UPDATENTITY, - BOTLIB_TEST, - - BOTLIB_GET_SNAPSHOT_ENTITY, // ( int playerNum, int ent ); - BOTLIB_GET_CONSOLE_MESSAGE, // ( int playerNum, char *message, int size ); - BOTLIB_USER_COMMAND, // ( int playerNum, usercmd_t *ucmd ); - - BOTLIB_AAS_BBOX_AREAS = 301, - BOTLIB_AAS_AREA_INFO, - BOTLIB_AAS_LOADED, - BOTLIB_AAS_INITIALIZED, - BOTLIB_AAS_PRESENCE_TYPE_BOUNDING_BOX, - BOTLIB_AAS_TIME, - - BOTLIB_AAS_POINT_AREA_NUM, - BOTLIB_AAS_TRACE_PLAYER_BBOX, - BOTLIB_AAS_TRACE_AREAS, - - BOTLIB_AAS_POINT_CONTENTS, - BOTLIB_AAS_NEXT_BSP_ENTITY, - BOTLIB_AAS_VALUE_FOR_BSP_EPAIR_KEY, - BOTLIB_AAS_VECTOR_FOR_BSP_EPAIR_KEY, - BOTLIB_AAS_FLOAT_FOR_BSP_EPAIR_KEY, - BOTLIB_AAS_INT_FOR_BSP_EPAIR_KEY, - - // aas_move - BOTLIB_AAS_PREDICT_PLAYER_MOVEMENT = 325, - BOTLIB_AAS_ON_GROUND, - BOTLIB_AAS_SWIMMING, - BOTLIB_AAS_JUMP_REACH_RUN_START, - BOTLIB_AAS_AGAINST_LADDER, - BOTLIB_AAS_HORIZONTAL_VELOCITY_FOR_JUMP, - BOTLIB_AAS_DROP_TO_FLOOR, - - // aas_reach - BOTLIB_AAS_AREA_REACHABILITY = 350, - BOTLIB_AAS_BEST_REACHABLE_AREA, - BOTLIB_AAS_BEST_REACHABLE_FROM_JUMP_PAD_AREA, - BOTLIB_AAS_NEXT_MODEL_REACHABILITY, - BOTLIB_AAS_AREA_GROUND_FACE_AREA, - BOTLIB_AAS_AREA_CROUCH, - BOTLIB_AAS_AREA_SWIM, - BOTLIB_AAS_AREA_LIQUID, - BOTLIB_AAS_AREA_LAVA, - BOTLIB_AAS_AREA_SLIME, - BOTLIB_AAS_AREA_GROUNDED, - BOTLIB_AAS_AREA_LADDER, - BOTLIB_AAS_AREA_JUMP_PAD, - BOTLIB_AAS_AREA_DO_NOT_ENTER, - - // aas_route - BOTLIB_AAS_TRAVEL_FLAG_FOR_TYPE = 400, - BOTLIB_AAS_AREA_CONTENTS_TRAVEL_FLAGS, - BOTLIB_AAS_NEXT_AREA_REACHABILITY, - BOTLIB_AAS_REACHABILITY_FROM_NUM, - BOTLIB_AAS_RANDOM_GOAL_AREA, - BOTLIB_AAS_ENABLE_ROUTING_AREA, - BOTLIB_AAS_AREA_TRAVEL_TIME, - BOTLIB_AAS_AREA_TRAVEL_TIME_TO_GOAL_AREA, - BOTLIB_AAS_PREDICT_ROUTE, - - // aas_altroute - BOTLIB_AAS_ALTERNATIVE_ROUTE_GOAL = 420, - - BOTLIB_AAS_POINT_REACHABILITY_AREA_INDEX = 500, - } gameImport_t; @@ -375,7 +310,7 @@ typedef enum { GAME_PLAYER_USERINFO_CHANGED, // ( int playerNum ); - GAME_PLAYER_DISCONNECT, // ( int playerNum ); + GAME_PLAYER_DISCONNECT, // ( int playerNum, qboolean force ); GAME_CLIENT_COMMAND, // ( int clientNum ); @@ -384,7 +319,7 @@ typedef enum { GAME_RUN_FRAME, // ( int levelTime ); GAME_CONSOLE_COMMAND, // ( void ); - // ConsoleCommand will be called when a command has been issued + // G_ConsoleCommand will be called when a command has been issued // that is not recognized as a builtin function. // The game can issue trap_argc() / trap_argv() commands to get the command // and parameters. Return qfalse if the game doesn't recognize it as a command. @@ -398,11 +333,13 @@ typedef enum { // caused by vid_restart on localhost server. // model handles are no longer valid, must re-register all models. - GAME_MAP_RESTART // ( int levelTime, int restartTime ); + GAME_MAP_RESTART, // ( int levelTime, int restartTime ); // G_MapRestart will be called when a map_restart command has been issued; // caused by user, VM code, or server after restart time is hit. // return restart time (levelTime + delay), -1 to do a full map reload, // or INT_MAX to prevent map restart. + GAME_CONSOLE_COMPLETEARGUMENT, // ( int completeArgument ); + } gameExport_t; diff --git a/code/qcommon/cmd.c b/code/qcommon/cmd.c index aec19d30e..18bc586ae 100644 --- a/code/qcommon/cmd.c +++ b/code/qcommon/cmd.c @@ -521,31 +521,6 @@ char *Cmd_Cmd(void) return cmd.cmd; } -/* - Replace command separators with space to prevent interpretation - This is a hack to protect buggy qvms - https://bugzilla.icculus.org/show_bug.cgi?id=3593 - https://bugzilla.icculus.org/show_bug.cgi?id=4769 -*/ - -void Cmd_Args_Sanitize(void) -{ - int i; - - for(i = 1; i < cmd.argc; i++) - { - char *c = cmd.argv[i]; - - if(strlen(c) > MAX_CVAR_VALUE_STRING - 1) - c[MAX_CVAR_VALUE_STRING - 1] = '\0'; - - while ((c = strpbrk(c, "\n\r;"))) { - *c = ' '; - ++c; - } - } -} - /* ============ Cmd_TokenizeString @@ -695,10 +670,10 @@ cmd_function_t *Cmd_FindCommand( const char *cmd_name ) /* ============ -Cmd_AddCommand +Cmd_AddCommandWithCompletion ============ */ -void Cmd_AddCommand( const char *cmd_name, xcommand_t function ) { +void Cmd_AddCommandWithCompletion( const char *cmd_name, xcommand_t function, completionFunc_t complete ) { cmd_function_t *cmd; // fail if the command already exists @@ -712,11 +687,20 @@ void Cmd_AddCommand( const char *cmd_name, xcommand_t function ) { cmd = S_Malloc (sizeof(cmd_function_t)); cmd->name = CopyString( cmd_name ); cmd->function = function; - cmd->complete = NULL; + cmd->complete = complete; cmd->next = cmd_functions; cmd_functions = cmd; } +/* +============ +Cmd_AddCommand +============ +*/ +void Cmd_AddCommand( const char *cmd_name, xcommand_t function ) { + Cmd_AddCommandWithCompletion( cmd_name, function, NULL ); +} + /* ============ Cmd_AddCommandSafe @@ -724,7 +708,7 @@ Cmd_AddCommandSafe Only add command if there isn't a system cvar with the same name ============ */ -void Cmd_AddCommandSafe( const char *cmd_name, xcommand_t function ) +void Cmd_AddCommandSafe( const char *cmd_name, xcommand_t function, completionFunc_t complete ) { if( !( Cvar_Flags( cmd_name ) & ( CVAR_NONEXISTENT | CVAR_VM_CREATED | CVAR_USER_CREATED ) ) ) { @@ -733,7 +717,7 @@ void Cmd_AddCommandSafe( const char *cmd_name, xcommand_t function ) return; } - Cmd_AddCommand( cmd_name, function ); + Cmd_AddCommandWithCompletion( cmd_name, function, complete ); } /* diff --git a/code/qcommon/common.c b/code/qcommon/common.c index 3f958ad71..bc482b4e2 100644 --- a/code/qcommon/common.c +++ b/code/qcommon/common.c @@ -44,7 +44,7 @@ Suite 120, Rockville, Maryland 20850 USA. // List of demo protocols that are supported for playback. // Also plays protocol com_protocol int demo_protocols[] = -{ PROTOCOL_VERSION, 5, 4, 3, 2, 0 }; +{ PROTOCOL_VERSION, 10, /* 6,7,8,9 were skipped */ 5, 4, 3, 2, 0 }; #define MAX_NUM_ARGVS 50 @@ -3206,7 +3206,7 @@ void Com_ShutdownRef( void ) { Com_InitRef ============ */ -void BotDrawDebugPolygons( void (*drawPoly)(int color, int numPoints, float *points) ); +void SV_BotDrawDebugPolygons( void (*drawPoly)(int color, int numPoints, float *points) ); void Com_InitRef( refimport_t *ri ) { refexport_t *ret; @@ -3275,7 +3275,7 @@ void Com_InitRef( refimport_t *ri ) { ri->CM_ClusterPVS = CM_ClusterPVS; ri->CM_DrawDebugSurface = CM_DrawDebugSurface; - ri->BotDrawDebugPolygons = BotDrawDebugPolygons; + ri->SV_BotDrawDebugPolygons = SV_BotDrawDebugPolygons; ri->FS_ReadFile = FS_ReadFile; ri->FS_FreeFile = FS_FreeFile; @@ -3839,13 +3839,20 @@ Field_CompleteFilename void Field_CompleteFilename( const char *dir, const char *ext, qboolean stripExt, qboolean allowNonPureFilesOnDisk ) { + char **pFiles; + int nFiles; + matchCount = 0; shortestMatch[ 0 ] = 0; - FS_FilenameCompletion( dir, ext, stripExt, FindMatches, allowNonPureFilesOnDisk ); + pFiles = FS_GetFileList( dir, ext, &nFiles, allowNonPureFilesOnDisk ); + + FS_FilenameCompletion( pFiles, nFiles, stripExt, FindMatches, allowNonPureFilesOnDisk ); if( !Field_Complete( ) ) - FS_FilenameCompletion( dir, ext, stripExt, PrintMatches, allowNonPureFilesOnDisk ); + FS_FilenameCompletion( pFiles, nFiles, stripExt, PrintMatches, allowNonPureFilesOnDisk ); + + FS_FreeFileList( pFiles ); } /* @@ -3853,11 +3860,17 @@ void Field_CompleteFilename( const char *dir, Field_CompleteCommand =============== */ -void Field_CompleteCommand( char *cmd, +void Field_CompleteCommand( const char *_cmd, qboolean doCommands, qboolean doCvars ) { + char buffer[ BIG_INFO_STRING ], *cmd; int completionArgument = 0; + // _cmd shouldn't ever be changed but it's too much work to const-ify + // every where it goes so make a local copy + Q_strncpyz( buffer, _cmd, sizeof ( buffer ) ); + cmd = buffer; + // Skip leading whitespace and quotes cmd = Com_SkipCharset( cmd, " \"" ); @@ -3940,6 +3953,50 @@ void Field_CompleteCommand( char *cmd, } } +/* +============ +Field_ListCompletion +============ +*/ +static void Field_ListCompletion( const char *list, void(*callback)(const char *s) ) { + const char *itemname; + + itemname = list; + + while ( 1 ) { + if (itemname[0] == '\0') + break; + + callback(itemname); + + itemname += strlen(itemname) + 1; + } +} + +/* +=============== +Field_CompleteList + +List items are 0-byte terminated with an additonal 0-byte at the end of the list + +Example: "hello\0world\0" +C-strings have an implicit trailing 0-byte so the memory is actually hello\0world\0\0 +=============== +*/ +void Field_CompleteList( const char *list ) +{ + matchCount = 0; + shortestMatch[ 0 ] = 0; + + if ( !list ) + return; + + Field_ListCompletion( list, FindMatches ); + + if( !Field_Complete( ) ) + Field_ListCompletion( list, PrintMatches ); +} + /* =============== Field_AutoComplete diff --git a/code/qcommon/files.c b/code/qcommon/files.c index e0c62a737..4905c52be 100644 --- a/code/qcommon/files.c +++ b/code/qcommon/files.c @@ -2693,63 +2693,38 @@ void FS_FreeFileList( char **list ) { FS_GetFileList ================ */ -int FS_GetFileList( const char *path, const char *extension, char *listbuf, int bufsize ) { - int nFiles, i, nTotal, nLen; +char **FS_GetFileList( const char *path, const char *extension, int *numfiles, qboolean allowNonPureFilesOnDisk ) { + int nFiles; char **pFiles = NULL; - if ( !path || !listbuf || bufsize < 1 ) { - return 0; + if ( !path ) { + if ( numfiles ) { + *numfiles = 0; + } + return NULL; } if ( !extension ) { extension = ""; } - *listbuf = 0; - nFiles = 0; - nTotal = 0; - - if (Q_stricmp(path, "$modlist") == 0) { - return FS_GetModList(listbuf, bufsize); - } - - if (Q_stricmp(extension, "$demos") == 0) { + if (Q_stricmp(extension, "$demos") == 0) + { char dotdemoext[MAX_QPATH]; - int extLength; - Com_sprintf( dotdemoext, sizeof ( dotdemoext ), ".%s", com_demoext->string ); - extLength = strlen(dotdemoext); - pFiles = FS_ListFiles(path, dotdemoext, &nFiles); - - // strip extension from list items - for (i =0; i < nFiles; i++) { - nLen = strlen(pFiles[i]) + 1 - extLength; - if (nTotal + nLen + 1 < bufsize) { - Q_strncpyz(listbuf, pFiles[i], nLen); - listbuf += nLen; - nTotal += nLen; - } - else { - nFiles = i; - break; - } - } - - FS_FreeFileList(pFiles); - return nFiles; + pFiles = FS_ListFilteredFiles(path, dotdemoext, NULL, &nFiles, allowNonPureFilesOnDisk); } - - if (Q_stricmp(extension, "$videos") == 0) + else if (Q_stricmp(extension, "$videos") == 0) { const char *extensions[] = { "RoQ", "roq" }; int extNamesSize = ARRAY_LEN(extensions); - pFiles = FS_ListFilesEx(path, extensions, extNamesSize, &nFiles, qfalse); + pFiles = FS_ListFilesEx(path, extensions, extNamesSize, &nFiles, allowNonPureFilesOnDisk); } else if (Q_stricmp(extension, "$images") == 0) { const char *extensions[] = { "png", "tga", "jpg", "jpeg", "ftx", "dds", "pcx", "bmp" }; int extNamesSize = ARRAY_LEN(extensions); - pFiles = FS_ListFilesEx(path, extensions, extNamesSize, &nFiles, qfalse); + pFiles = FS_ListFilesEx(path, extensions, extNamesSize, &nFiles, allowNonPureFilesOnDisk); } else if (Q_stricmp(extension, "$sounds") == 0) { @@ -2762,13 +2737,19 @@ int FS_GetFileList( const char *path, const char *extension, char *listbuf, int #endif }; int extNamesSize = ARRAY_LEN(extensions); - pFiles = FS_ListFilesEx(path, extensions, extNamesSize, &nFiles, qfalse); + pFiles = FS_ListFilesEx(path, extensions, extNamesSize, &nFiles, allowNonPureFilesOnDisk); } else if (Q_stricmp(extension, "$fonts") == 0) { const char *extensions[] = { "ttf", "otf", "ttc", "otc", "fon" }; int extNamesSize = ARRAY_LEN(extensions); - pFiles = FS_ListFilesEx(path, extensions, extNamesSize, &nFiles, qfalse); + pFiles = FS_ListFilesEx(path, extensions, extNamesSize, &nFiles, allowNonPureFilesOnDisk); + } + else if (Q_stricmp(extension, "$models") == 0) + { + const char *extensions[] = { "md3", "mdr", "mdc", "mds", "mdx", "mdm", "tan", "iqm" }; + int extNamesSize = ARRAY_LEN(extensions); + pFiles = FS_ListFilesEx(path, extensions, extNamesSize, &nFiles, allowNonPureFilesOnDisk); } // Allow extension to be a list // Example "RoQ;roq;jpg;wav" @@ -2822,14 +2803,74 @@ int FS_GetFileList( const char *path, const char *extension, char *listbuf, int } } - pFiles = FS_ListFilesEx(path, extensions, numExts, &nFiles, qfalse); + pFiles = FS_ListFilesEx(path, extensions, numExts, &nFiles, allowNonPureFilesOnDisk); #undef MAX_FILE_LIST_EXTS } else { - pFiles = FS_ListFiles(path, extension, &nFiles); + pFiles = FS_ListFilteredFiles(path, extension, NULL, &nFiles, allowNonPureFilesOnDisk); + } + + if ( numfiles ) { + *numfiles = nFiles; + } + return pFiles; +} + +/* +================ +FS_GetFileListBuffer +================ +*/ +int FS_GetFileListBuffer( const char *path, const char *extension, char *listbuf, int bufsize ) { + int nFiles, i, nTotal, nLen; + char **pFiles = NULL; + + if ( !path || !listbuf || bufsize < 1 ) { + return 0; + } + + if ( !extension ) { + extension = ""; + } + + *listbuf = 0; + nFiles = 0; + nTotal = 0; + + if (Q_stricmp(path, "$modlist") == 0) { + return FS_GetModList(listbuf, bufsize); + } + + // ZTM: TODO: merging removing extension with general block as this list code is duplicate. + if (Q_stricmp(extension, "$demos") == 0) { + char dotdemoext[MAX_QPATH]; + int extLength; + + Com_sprintf( dotdemoext, sizeof ( dotdemoext ), ".%s", com_demoext->string ); + extLength = strlen(dotdemoext); + pFiles = FS_ListFiles(path, dotdemoext, &nFiles); + + // strip extension from list items + for (i =0; i < nFiles; i++) { + nLen = strlen(pFiles[i]) + 1 - extLength; + if (nTotal + nLen + 1 < bufsize) { + Q_strncpyz(listbuf, pFiles[i], nLen); + listbuf += nLen; + nTotal += nLen; + } + else { + nFiles = i; + break; + } + } + + FS_FreeFileList(pFiles); + return nFiles; } + pFiles = FS_GetFileList( path, extension, &nFiles, qfalse ); + for (i =0; i < nFiles; i++) { nLen = strlen(pFiles[i]) + 1; if (nTotal + nLen + 1 < bufsize) { @@ -3134,7 +3175,7 @@ void FS_Dir_f( void ) { Com_Printf( "Directory of %s %s\n", path, extension ); Com_Printf( "---------------\n" ); - dirnames = FS_ListFiles( path, extension, &ndirs ); + dirnames = FS_GetFileList( path, extension, &ndirs, qfalse ); for ( i = 0; i < ndirs; i++ ) { Com_Printf( "%s\n", dirnames[i] ); @@ -5162,15 +5203,11 @@ void FS_Flush( fileHandle_t f ) { fflush(fsh[f].handleFiles.file.o); } -void FS_FilenameCompletion( const char *dir, const char *ext, +void FS_FilenameCompletion( char **filenames, int nfiles, qboolean stripExt, void(*callback)(const char *s), qboolean allowNonPureFilesOnDisk ) { - char **filenames; - int nfiles; int i; char filename[ MAX_STRING_CHARS ]; - filenames = FS_ListFilteredFiles( dir, ext, NULL, &nfiles, allowNonPureFilesOnDisk ); - for( i = 0; i < nfiles; i++ ) { FS_ConvertPath( filenames[ i ] ); Q_strncpyz( filename, filenames[ i ], MAX_STRING_CHARS ); @@ -5181,7 +5218,6 @@ void FS_FilenameCompletion( const char *dir, const char *ext, callback( filename ); } - FS_FreeFileList( filenames ); } const char *FS_GetCurrentGameDir(void) diff --git a/code/qcommon/qcommon.h b/code/qcommon/qcommon.h index e1023862c..dd52ec061 100644 --- a/code/qcommon/qcommon.h +++ b/code/qcommon/qcommon.h @@ -39,7 +39,7 @@ Suite 120, Rockville, Maryland 20850 USA. // Keep this in-sync with VERSION in Makefile. #ifndef PRODUCT_VERSION - #define PRODUCT_VERSION "0.4" + #define PRODUCT_VERSION "0.5" #endif #define Q3_VERSION PRODUCT_NAME " " PRODUCT_VERSION @@ -70,7 +70,9 @@ Suite 120, Rockville, Maryland 20850 USA. // Prefix for renderer native libraries. Example: PREFIXopengl1_x86.dll // Change this if you break renderer compatibility with Spearmint. // You'll also need to change RENDERER_PREFIX in Makefile. -#define RENDERER_PREFIX "mint-renderer-" +#ifndef RENDERER_PREFIX + #define RENDERER_PREFIX "spearmint-renderer-" +#endif // Default game to load (default fs_game value). // You can change this and it won't break network compatiblity. @@ -323,7 +325,7 @@ PROTOCOL ============================================================== */ -#define PROTOCOL_VERSION 10 +#define PROTOCOL_VERSION 11 #define PROTOCOL_LEGACY_VERSION 0 // maintain a list of compatible protocols for demo playing @@ -492,10 +494,12 @@ then searches for a command or variable that matches the first token. */ typedef void (*xcommand_t) (void); +typedef void (*completionFunc_t)( char *args, int argNum ); void Cmd_Init (void); void Cmd_AddCommand( const char *cmd_name, xcommand_t function ); +void Cmd_AddCommandWithCompletion( const char *cmd_name, xcommand_t function, completionFunc_t complete ); // called by the init functions of other parts of the program to // register commands and functions to call for them. // The cmd_name is referenced later, so it should not be in temp memory @@ -505,10 +509,8 @@ void Cmd_AddCommand( const char *cmd_name, xcommand_t function ); void Cmd_RemoveCommand( const char *cmd_name ); void Cmd_RemoveCommandsByFunc( xcommand_t function ); -typedef void (*completionFunc_t)( char *args, int argNum ); - // don't allow VMs to remove system commands -void Cmd_AddCommandSafe( const char *cmd_name, xcommand_t function ); +void Cmd_AddCommandSafe( const char *cmd_name, xcommand_t function, completionFunc_t complete ); void Cmd_RemoveCommandSafe( const char *cmd_name, xcommand_t function ); void Cmd_CommandCompletion( void(*callback)(const char *s) ); @@ -526,7 +528,6 @@ char *Cmd_ArgsFrom( int arg ); void Cmd_ArgsBuffer( char *buffer, int bufferLength ); void Cmd_LiteralArgsBuffer( char *buffer, int bufferLength ); char *Cmd_Cmd (void); -void Cmd_Args_Sanitize( void ); // The functions that execute commands get their parameters with these // functions. Cmd_Argv () will return an empty string, not a NULL // if arg > argc, so string operations are allways safe. @@ -727,7 +728,8 @@ qboolean FS_CompareZipChecksum(const char *zipfile); int FS_LoadStack( void ); -int FS_GetFileList( const char *path, const char *extension, char *listbuf, int bufsize ); +char **FS_GetFileList( const char *path, const char *extension, int *numfiles, qboolean allowNonPureFilesOnDisk ); +int FS_GetFileListBuffer( const char *path, const char *extension, char *listbuf, int bufsize ); int FS_GetModList( char *listbuf, int bufsize ); void FS_GetModDescription( const char *modDir, char *description, int descriptionLen ); @@ -825,7 +827,7 @@ qboolean FS_Rename( const char *from, const char *to ); int FS_Remove( const char *osPath ); int FS_HomeRemove( const char *homePath ); -void FS_FilenameCompletion( const char *dir, const char *ext, +void FS_FilenameCompletion( char **filenames, int nfiles, qboolean stripExt, void(*callback)(const char *s), qboolean allowNonPureFilesOnDisk ); const char *FS_GetCurrentGameDir(void); @@ -885,8 +887,9 @@ void Field_AutoComplete( field_t *edit ); void Field_CompleteKeyname( void ); void Field_CompleteFilename( const char *dir, const char *ext, qboolean stripExt, qboolean allowNonPureFilesOnDisk ); -void Field_CompleteCommand( char *cmd, +void Field_CompleteCommand( const char *cmd, qboolean doCommands, qboolean doCvars ); +void Field_CompleteList( const char *list ); /* ============================================================== diff --git a/code/renderercommon/tr_public.h b/code/renderercommon/tr_public.h index a79fe5614..8ec4e0ac7 100644 --- a/code/renderercommon/tr_public.h +++ b/code/renderercommon/tr_public.h @@ -196,7 +196,7 @@ typedef struct { // visualization for debugging collision detection void (*CM_DrawDebugSurface)( void (*drawPoly)(int color, int numPoints, float *points) ); - void (*BotDrawDebugPolygons)( void (*drawPoly)(int color, int numPoints, float *points) ); + void (*SV_BotDrawDebugPolygons)( void (*drawPoly)(int color, int numPoints, float *points) ); // a -1 return means the file does not exist // NULL can be passed for buf to just determine existance diff --git a/code/renderergl1/tr_main.c b/code/renderergl1/tr_main.c index 95574bfc9..013be4ad1 100644 --- a/code/renderergl1/tr_main.c +++ b/code/renderergl1/tr_main.c @@ -1746,9 +1746,9 @@ void R_DebugGraphics( void ) { if ( r_debugSurface->integer == 1 ) { GL_Cull( CT_FRONT_SIDED ); ri.CM_DrawDebugSurface( R_DebugPolygon ); - } else { + } else if ( r_debugSurface->integer == 2 ) { GL_Cull( CT_TWO_SIDED ); - ri.BotDrawDebugPolygons( R_DebugPolygon ); + ri.SV_BotDrawDebugPolygons( R_DebugPolygon ); } } diff --git a/code/renderergl2/tr_main.c b/code/renderergl2/tr_main.c index 726636673..868e9ea5c 100644 --- a/code/renderergl2/tr_main.c +++ b/code/renderergl2/tr_main.c @@ -2107,9 +2107,9 @@ void R_DebugGraphics( void ) { if ( r_debugSurface->integer == 1 ) { GL_Cull( CT_FRONT_SIDED ); ri.CM_DrawDebugSurface( R_DebugPolygon ); - } else { + } else if ( r_debugSurface->integer == 2 ) { GL_Cull( CT_TWO_SIDED ); - ri.BotDrawDebugPolygons( R_DebugPolygon ); + ri.SV_BotDrawDebugPolygons( R_DebugPolygon ); } } diff --git a/code/server/server.h b/code/server/server.h index 0cbfa78c5..9d18bca40 100644 --- a/code/server/server.h +++ b/code/server/server.h @@ -390,7 +390,7 @@ void SV_UserinfoChanged( player_t *cl ); void SV_SetupPlayerEntity( player_t *player ); void SV_PlayerEnterWorld( player_t *player, usercmd_t *cmd ); void SV_FreePlayer( player_t *player ); -void SV_DropPlayer( player_t *drop, const char *reason ); +void SV_DropPlayer( player_t *drop, const char *reason, qboolean force ); void SV_FreeClient( client_t *client ); void SV_DropClient( client_t *drop, const char *reason ); @@ -435,7 +435,6 @@ sharedEntity_t *SV_GEntityForSvEntity( svEntity_t *svEnt ); void SV_InitGameProgs ( void ); void SV_ShutdownGameProgs ( void ); void SV_RestartGameProgs( void ); -void SV_GameCommand( void ); qboolean SV_inPVS (const vec3_t p1, const vec3_t p2); // @@ -449,7 +448,7 @@ void SV_BotInitCvars(void); int SV_BotLibSetup( void ); int SV_BotLibShutdown( void ); int SV_BotGetSnapshotEntity( int playerNum, int ent ); -int SV_BotGetConsoleMessage( int playerNum, char *buf, int size ); +int SV_BotGetServerCommand( int playerNum, char *buf, int size ); int BotImport_DebugPolygonCreate(int color, int numPoints, vec3_t *points); void BotImport_DebugPolygonShow(int id, int color, int numPoints, vec3_t *points); diff --git a/code/server/sv_bot.c b/code/server/sv_bot.c index c6debfa1a..6021a06ef 100644 --- a/code/server/sv_bot.c +++ b/code/server/sv_bot.c @@ -30,7 +30,6 @@ Suite 120, Rockville, Maryland 20850 USA. // sv_bot.c #include "server.h" -#include "../botlib/botlib.h" typedef struct bot_debugpoly_s { @@ -41,12 +40,9 @@ typedef struct bot_debugpoly_s } bot_debugpoly_t; static bot_debugpoly_t *debugpolygons; -int bot_maxdebugpolys; +cvar_t *bot_maxdebugpolys; -extern botlib_export_t *botlib_export; -int bot_enable; - -static cvar_t *bot_developer; +cvar_t *bot_enable; /* @@ -123,40 +119,20 @@ void SV_BotFreeClient( int playerNum ) { /* ================== -BotDrawDebugPolygons +SV_BotDrawDebugPolygons Set r_debugSurface to 2 to enable ================== */ -void BotDrawDebugPolygons( void (*drawPoly)(int color, int numPoints, float *points) ) { - static cvar_t *bot_debug, *bot_groundonly, *bot_reachability, *bot_highlightarea; +void SV_BotDrawDebugPolygons( void (*drawPoly)(int color, int numPoints, float *points) ) { bot_debugpoly_t *poly; - int i, parm0; + int i; if (!debugpolygons) return; - //bot debugging - if (!bot_debug) bot_debug = Cvar_Get("bot_debug", "0", 0); - // - if (bot_enable && bot_debug->integer) { - //show reachabilities - if (!bot_reachability) bot_reachability = Cvar_Get("bot_reachability", "0", 0); - //show ground faces only - if (!bot_groundonly) bot_groundonly = Cvar_Get("bot_groundonly", "1", 0); - //get the hightlight area - if (!bot_highlightarea) bot_highlightarea = Cvar_Get("bot_highlightarea", "0", 0); - // - parm0 = 0; - // ZTM: FIXME: Moved BUTTONS_GENERATED from engine to bg_misc.h, the Test function it self should move to game VM. - //if (svs.players[0].lastUsercmd.buttons & ~BUTTONS_GENERATED) parm0 |= 1; - if (bot_reachability->integer) parm0 |= 2; - if (bot_groundonly->integer) parm0 |= 4; - botlib_export->BotLibVarSet("bot_highlightarea", bot_highlightarea->string); - botlib_export->Test(parm0, NULL, svs.players[0].gentity->r.currentOrigin, - svs.players[0].gentity->r.currentAngles); - } //end if + //draw all debug polys - for (i = 0; i < bot_maxdebugpolys; i++) { + for (i = 0; i < bot_maxdebugpolys->integer; i++) { poly = &debugpolygons[i]; if (!poly->inuse) continue; drawPoly(poly->color, poly->numPoints, (float *) poly->points); @@ -164,161 +140,6 @@ void BotDrawDebugPolygons( void (*drawPoly)(int color, int numPoints, float *poi } } -/* -================== -BotImport_Print -================== -*/ -static __attribute__ ((format (printf, 2, 3))) void QDECL BotImport_Print(int type, char *fmt, ...) -{ - char str[2048]; - va_list ap; - - va_start(ap, fmt); - Q_vsnprintf(str, sizeof(str), fmt, ap); - va_end(ap); - - switch(type) { - case PRT_DEVELOPER: { - if (bot_developer->integer) { - Com_Printf("%s", str); - } - break; - } - case PRT_MESSAGE: { - Com_Printf("%s", str); - break; - } - case PRT_WARNING: { - Com_Printf(S_COLOR_YELLOW "Warning: %s", str); - break; - } - case PRT_ERROR: { - Com_Printf(S_COLOR_RED "Error: %s", str); - break; - } - case PRT_FATAL: { - Com_Printf(S_COLOR_RED "Fatal: %s", str); - break; - } - case PRT_EXIT: { - Com_Error(ERR_DROP, S_COLOR_RED "Exit: %s", str); - break; - } - default: { - Com_Printf("unknown print type\n"); - break; - } - } -} - -/* -================== -BotImport_Trace -================== -*/ -static void BotImport_Trace(bsp_trace_t *bsptrace, vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end, int passent, int contentmask) { - SV_Trace(bsptrace, start, mins, maxs, end, passent, contentmask, TT_AABB); -} - -/* -================== -BotImport_EntityTrace -================== -*/ -static void BotImport_EntityTrace(bsp_trace_t *bsptrace, vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end, int entnum, int contentmask) { - SV_ClipToEntity(bsptrace, start, mins, maxs, end, entnum, contentmask, TT_AABB); -} - - -/* -================== -BotImport_PointContents -================== -*/ -static int BotImport_PointContents(vec3_t point) { - return SV_PointContents(point, -1); -} - -/* -================== -BotImport_inPVS -================== -*/ -static int BotImport_inPVS(vec3_t p1, vec3_t p2) { - return SV_inPVS (p1, p2); -} - -/* -================== -BotImport_GetEntityToken -================== -*/ -qboolean BotImport_GetEntityToken( int *offset, char *buffer, int size ) { - return CM_GetEntityToken( offset, buffer, size ); -} - -/* -================== -BotImport_BSPModelMinsMaxsOrigin -================== -*/ -static void BotImport_BSPModelMinsMaxsOrigin(int modelnum, vec3_t angles, vec3_t outmins, vec3_t outmaxs, vec3_t origin) { - clipHandle_t h; - vec3_t mins, maxs; - float max; - int i; - - h = CM_InlineModel(modelnum); - CM_ModelBounds(h, mins, maxs); - //if the model is rotated - if ((angles[0] || angles[1] || angles[2])) { - // expand for rotation - - max = RadiusFromBounds(mins, maxs); - for (i = 0; i < 3; i++) { - mins[i] = -max; - maxs[i] = max; - } - } - if (outmins) VectorCopy(mins, outmins); - if (outmaxs) VectorCopy(maxs, outmaxs); - if (origin) VectorClear(origin); -} - -/* -================== -BotImport_GetMemory -================== -*/ -static void *BotImport_GetMemory(int size) { - void *ptr; - - ptr = Z_TagMalloc( size, TAG_BOTLIB ); - return ptr; -} - -/* -================== -BotImport_FreeMemory -================== -*/ -static void BotImport_FreeMemory(void *ptr) { - Z_Free(ptr); -} - -/* -================= -BotImport_HunkAlloc -================= -*/ -static void *BotImport_HunkAlloc( int size ) { - if( Hunk_CheckMark() ) { - Com_Error( ERR_DROP, "SV_Bot_HunkAlloc: Alloc with marks already set" ); - } - return Hunk_Alloc( size, h_high ); -} - /* ================== BotImport_DebugPolygonCreate @@ -331,11 +152,11 @@ int BotImport_DebugPolygonCreate(int color, int numPoints, vec3_t *points) { if (!debugpolygons) return 0; - for (i = 1; i < bot_maxdebugpolys; i++) { + for (i = 1; i < bot_maxdebugpolys->integer; i++) { if (!debugpolygons[i].inuse) break; } - if (i >= bot_maxdebugpolys) + if (i >= bot_maxdebugpolys->integer) return 0; poly = &debugpolygons[i]; poly->inuse = qtrue; @@ -360,7 +181,7 @@ void BotImport_DebugPolygonShow(int id, int color, int numPoints, vec3_t *points if (!debugpolygons) return; - if (id < 0 || id >= bot_maxdebugpolys) + if (id < 0 || id >= bot_maxdebugpolys->integer) return; poly = &debugpolygons[id]; @@ -383,63 +204,12 @@ void BotImport_DebugPolygonDelete(int id) { if (!debugpolygons) return; - if (id < 0 || id >= bot_maxdebugpolys) + if (id < 0 || id >= bot_maxdebugpolys->integer) return; debugpolygons[id].inuse = qfalse; } -/* -================== -BotImport_DebugLineCreate -================== -*/ -static int BotImport_DebugLineCreate(void) { - return BotImport_DebugPolygonCreate(0, 0, NULL); -} - -/* -================== -BotImport_DebugLineDelete -================== -*/ -static void BotImport_DebugLineDelete(int line) { - BotImport_DebugPolygonDelete(line); -} - -/* -================== -BotImport_DebugLineShow -================== -*/ -static void BotImport_DebugLineShow(int line, vec3_t start, vec3_t end, int color) { - vec3_t points[4], dir, cross, up = {0, 0, 1}; - float dot; - - VectorCopy(start, points[0]); - VectorCopy(start, points[1]); - //points[1][2] -= 2; - VectorCopy(end, points[2]); - //points[2][2] -= 2; - VectorCopy(end, points[3]); - - - VectorSubtract(end, start, dir); - VectorNormalize(dir); - dot = DotProduct(dir, up); - if (dot > 0.99 || dot < -0.99) VectorSet(cross, 1, 0, 0); - else CrossProduct(dir, up, cross); - - VectorNormalize(cross); - - VectorMA(points[0], 2, cross, points[0]); - VectorMA(points[1], -2, cross, points[1]); - VectorMA(points[2], -2, cross, points[2]); - VectorMA(points[3], 2, cross, points[3]); - - BotImport_DebugPolygonShow(line, color, 4, points); -} - /* ================== SV_ClientForPlayerNum @@ -476,117 +246,38 @@ SV_BotFrame ================== */ void SV_BotFrame( int time ) { - if (!bot_enable) return; + if (!bot_enable->integer) return; //NOTE: maybe the game is already shutdown if (!gvm) return; VM_Call( gvm, BOTAI_START_FRAME, time ); } -/* -=============== -SV_BotLibSetup -=============== -*/ -int SV_BotLibSetup( void ) { - if (!bot_enable) { - return 0; - } - - if ( !botlib_export ) { - Com_Printf( S_COLOR_RED "Error: SV_BotLibSetup without SV_BotInitBotLib\n" ); - return -1; - } - - botlib_export->BotLibVarSet( "basedir", Cvar_VariableString( "fs_basepath" ) ); - botlib_export->BotLibVarSet( "homedir", Cvar_VariableString( "fs_homepath" ) ); - botlib_export->BotLibVarSet( "gamedir", Cvar_VariableString( "fs_game" ) ); - - return botlib_export->BotLibSetup(); -} - -/* -=============== -SV_ShutdownBotLib - -Called when either the entire server is being killed, or -it is changing to a different game directory. -=============== -*/ -int SV_BotLibShutdown( void ) { - - if ( !botlib_export ) { - return -1; - } - - return botlib_export->BotLibShutdown(); -} - /* ================== SV_BotInitCvars + +Called at start up and map change ================== */ void SV_BotInitCvars(void) { - - Cvar_Get("bot_enable", "1", 0); //enable the bot - bot_developer = Cvar_Get("bot_developer", "0", CVAR_CHEAT); //bot developer mode - Cvar_Get("bot_debug", "0", CVAR_CHEAT); //enable bot debugging - Cvar_Get("bot_maxdebugpolys", "2", 0); //maximum number of debug polys - Cvar_Get("bot_groundonly", "1", 0); //only show ground faces of areas - Cvar_Get("bot_reachability", "0", 0); //show all reachabilities to other areas - Cvar_Get("bot_visualizejumppads", "0", CVAR_CHEAT); //show jumppads - Cvar_Get("bot_forceclustering", "0", 0); //force cluster calculations - Cvar_Get("bot_forcereachability", "0", 0); //force reachability calculations - Cvar_Get("bot_forcewrite", "0", 0); //force writing aas file - Cvar_Get("bot_aasoptimize", "0", 0); //no aas file optimisation + bot_enable = Cvar_Get( "bot_enable", "1", CVAR_LATCH ); + bot_maxdebugpolys = Cvar_Get( "bot_maxdebugpolys", "2", CVAR_LATCH ); } /* ================== SV_BotInitBotLib + +Called at map change ================== */ void SV_BotInitBotLib(void) { - botlib_import_t botlib_import; - - if (debugpolygons) Z_Free(debugpolygons); - bot_maxdebugpolys = Cvar_VariableIntegerValue("bot_maxdebugpolys"); - debugpolygons = Z_Malloc(sizeof(bot_debugpoly_t) * bot_maxdebugpolys); - - botlib_import.MilliSeconds = Sys_Milliseconds; - botlib_import.Print = BotImport_Print; - botlib_import.Trace = BotImport_Trace; - botlib_import.EntityTrace = BotImport_EntityTrace; - botlib_import.PointContents = BotImport_PointContents; - botlib_import.inPVS = BotImport_inPVS; - botlib_import.GetEntityToken = BotImport_GetEntityToken; - botlib_import.BSPModelMinsMaxsOrigin = BotImport_BSPModelMinsMaxsOrigin; - botlib_import.BotClientCommand = SV_ForceClientCommand; - - //memory management - botlib_import.GetMemory = BotImport_GetMemory; - botlib_import.FreeMemory = BotImport_FreeMemory; - botlib_import.AvailableMemory = Z_AvailableMemory; - botlib_import.HunkAlloc = BotImport_HunkAlloc; - - // file system access - botlib_import.FS_FOpenFile = FS_FOpenFileByMode; - botlib_import.FS_Read = FS_Read; - botlib_import.FS_Write = FS_Write; - botlib_import.FS_FCloseFile = FS_FCloseFile; - botlib_import.FS_Seek = FS_Seek; - - //debug lines - botlib_import.DebugLineCreate = BotImport_DebugLineCreate; - botlib_import.DebugLineDelete = BotImport_DebugLineDelete; - botlib_import.DebugLineShow = BotImport_DebugLineShow; - - //debug polygons - botlib_import.DebugPolygonCreate = BotImport_DebugPolygonCreate; - botlib_import.DebugPolygonDelete = BotImport_DebugPolygonDelete; - - botlib_export = (botlib_export_t *)GetBotLibAPI( BOTLIB_API_VERSION, &botlib_import ); - assert(botlib_export); // somehow we end up with a zero import. + if ( !debugpolygons || bot_maxdebugpolys->modified ) { + if (debugpolygons) Z_Free(debugpolygons); + debugpolygons = Z_Malloc(sizeof(bot_debugpoly_t) * bot_maxdebugpolys->integer); + bot_maxdebugpolys->modified = qfalse; + } + Com_Memset( debugpolygons, 0, sizeof(bot_debugpoly_t) * bot_maxdebugpolys->integer ); } @@ -596,10 +287,10 @@ void SV_BotInitBotLib(void) { /* ================== -SV_BotGetConsoleMessage +SV_BotGetServerCommand ================== */ -int SV_BotGetConsoleMessage( int playerNum, char *buf, int size ) +int SV_BotGetServerCommand( int playerNum, char *buf, int size ) { client_t *cl; int index; diff --git a/code/server/sv_ccmds.c b/code/server/sv_ccmds.c index bb24ecc3e..b5b958094 100644 --- a/code/server/sv_ccmds.c +++ b/code/server/sv_ccmds.c @@ -323,7 +323,7 @@ static void SV_MapRestart_f( void ) { // this generally shouldn't happen, because the player // was connected before the level change if ( player != NULL ) { - SV_DropPlayer( player, denied ); + SV_DropPlayer( player, denied, qtrue ); } Com_Printf( "SV_MapRestart_f: dropped client %i - denied!\n", i ); continue; @@ -383,7 +383,7 @@ static void SV_Kick_f( void ) { return; } - SV_DropPlayer( player, "was kicked" ); + SV_DropPlayer( player, "was kicked", qtrue ); client->lastPacketTime = svs.time; // in case there is a funny zombie } @@ -483,7 +483,7 @@ static void SV_KickNum_f( void ) { return; } - SV_DropPlayer( player, "was kicked" ); + SV_DropPlayer( player, "was kicked", qtrue ); client->lastPacketTime = svs.time; // in case there is a funny zombie } @@ -1098,79 +1098,6 @@ static void SV_Status_f( void ) { Com_Printf ("\n"); } -/* -================== -SV_ConSay_f -================== -*/ -static void SV_ConSay_f(void) { - char *p; - char text[1024]; - - // make sure server is running - if ( !com_sv_running->integer ) { - Com_Printf( "Server is not running.\n" ); - return; - } - - if ( Cmd_Argc () < 2 ) { - return; - } - - strcpy (text, "console: "); - p = Cmd_Args(); - - if ( *p == '"' ) { - p++; - p[strlen(p)-1] = 0; - } - - strcat(text, p); - - Com_Printf("%s\n", text); - SV_SendServerCommand(NULL, -1, "chat \"%s\" -1", text); -} - -/* -================== -SV_ConTell_f -================== -*/ -static void SV_ConTell_f(void) { - char *p; - char text[1024]; - player_t *player; - - // make sure server is running - if ( !com_sv_running->integer ) { - Com_Printf( "Server is not running.\n" ); - return; - } - - if ( Cmd_Argc() < 3 ) { - Com_Printf ("Usage: tell \n"); - return; - } - - player = SV_GetPlayerByNum(); - if ( !player ) { - return; - } - - strcpy (text, "console_tell: "); - p = Cmd_ArgsFrom(2); - - if ( *p == '"' ) { - p++; - p[strlen(p)-1] = 0; - } - - strcat(text, p); - - Com_Printf("%s\n", text); - SV_SendServerCommand( player->client, SV_LocalPlayerNum( player ), "tell \"%s\" -1", text ); -} - /* ================== @@ -1305,11 +1232,7 @@ void SV_AddOperatorCommands( void ) { Cmd_AddCommand ("devmap", SV_Map_f); Cmd_SetCommandCompletionFunc( "devmap", SV_CompleteMapName ); Cmd_AddCommand ("killserver", SV_KillServer_f); - if( com_dedicated->integer ) { - Cmd_AddCommand ("say", SV_ConSay_f); - Cmd_AddCommand ("tell", SV_ConTell_f); - } - + Cmd_AddCommand("rehashbans", SV_RehashBans_f); Cmd_AddCommand("listbans", SV_ListBans_f); Cmd_AddCommand("banaddr", SV_BanAddr_f); diff --git a/code/server/sv_client.c b/code/server/sv_client.c index 4873f061a..5aab46551 100644 --- a/code/server/sv_client.c +++ b/code/server/sv_client.c @@ -691,7 +691,7 @@ or unwillingly. This is NOT called if the entire server is quiting or crashing -- SV_FinalMessage() will handle that ===================== */ -void SV_DropPlayer( player_t *drop, const char *reason ) { +void SV_DropPlayer( player_t *drop, const char *reason, qboolean force ) { int i; challenge_t *challenge; int numLocalPlayers; @@ -710,6 +710,13 @@ void SV_DropPlayer( player_t *drop, const char *reason ) { return; } + // call the game vm function for removing a player + // it will remove the body, among other things + // allow the game to reject splitscreen player disconnect + if ( !VM_Call( gvm, GAME_PLAYER_DISCONNECT, playerNum, force || numLocalPlayers == 1 ) && !( force || numLocalPlayers == 1 ) ) { + return; + } + if ( !isBot ) { // see if we already have a challenge for this ip challenge = &svs.challenges[0]; @@ -732,10 +739,6 @@ void SV_DropPlayer( player_t *drop, const char *reason ) { SV_SendServerCommand( NULL, -1, "print \"%s" S_COLOR_WHITE " %s\n\"", drop->name, reason ); } - // call the prog function for removing a client - // this will remove the body, among other things - VM_Call( gvm, GAME_PLAYER_DISCONNECT, playerNum ); - // Check if player is a extra local player if ( numLocalPlayers > 1 ) { for (i = 0; i < MAX_SPLITVIEW; i++) { @@ -797,7 +800,7 @@ void SV_DropClient( client_t *cl, const char *reason ) { continue; } - SV_DropPlayer( cl->localPlayers[i], reason ); + SV_DropPlayer( cl->localPlayers[i], reason, qtrue ); } } @@ -1394,7 +1397,7 @@ void SV_UserinfoChanged( player_t *player ) { len = strlen( ip ) + 4 + strlen( player->userinfo ); if( len >= MAX_INFO_STRING ) - SV_DropPlayer( player, "userinfo string length exceeded" ); + SV_DropPlayer( player, "userinfo string length exceeded", qtrue ); else Info_SetValueForKey( player->userinfo, "ip", ip ); @@ -1441,7 +1444,7 @@ void SV_DropOut_f( client_t *client, int localPlayerNum ) { return; } - SV_DropPlayer( player, "dropped out" ); + SV_DropPlayer( player, "dropped out", qfalse ); } /* @@ -1641,7 +1644,6 @@ void SV_ExecuteClientCommand( client_t *cl, const char *s, qboolean clientOK ) { if (clientOK) { // pass unknown strings to the game if (!u->name && sv.state == SS_GAME && (cl->state == CS_ACTIVE || cl->state == CS_PRIMED)) { - Cmd_Args_Sanitize(); VM_Call( gvm, GAME_CLIENT_COMMAND, cl - svs.clients ); } } diff --git a/code/server/sv_game.c b/code/server/sv_game.c index 305b5cf06..8d260bd78 100644 --- a/code/server/sv_game.c +++ b/code/server/sv_game.c @@ -31,9 +31,13 @@ Suite 120, Rockville, Maryland 20850 USA. #include "server.h" -#include "../botlib/botlib.h" +#include "../botlib/l_script.h" +#include "../botlib/l_precomp.h" -botlib_export_t *botlib_export; +define_t *game_globaldefines; + +void SV_GameCommand( void ); +void SV_GameCompleteArgument( char *args, int argNum ); // these functions must be used instead of pointer arithmetic, because // the game allocates gentities with private information after the server shared part @@ -113,7 +117,7 @@ void SV_GameDropPlayer( int playerNum, const char *reason ) { if ( playerNum < 0 || playerNum >= sv_maxclients->integer ) { return; } - SV_DropPlayer( svs.players + playerNum, reason ); + SV_DropPlayer( svs.players + playerNum, reason, qtrue ); } @@ -315,7 +319,7 @@ intptr_t SV_GameSystemCalls( intptr_t *args ) { return 0; case G_ADDCOMMAND: - Cmd_AddCommandSafe( VMA(1), SV_GameCommand ); + Cmd_AddCommandSafe( VMA(1), SV_GameCommand, SV_GameCompleteArgument ); return 0; case G_REMOVECOMMAND: Cmd_RemoveCommandSafe( VMA(1), SV_GameCommand ); @@ -382,28 +386,33 @@ intptr_t SV_GameSystemCalls( intptr_t *args ) { FS_FCloseFile( args[1] ); return 0; case G_FS_GETFILELIST: - return FS_GetFileList( VMA(1), VMA(2), VMA(3), args[4] ); + return FS_GetFileListBuffer( VMA(1), VMA(2), VMA(3), args[4] ); case G_FS_DELETE: return FS_Delete( VMA(1) ); case G_FS_RENAME: return FS_Rename( VMA(1), VMA(2) ); case G_PC_ADD_GLOBAL_DEFINE: - return botlib_export->PC_AddGlobalDefine( VMA(1) ); + return PC_AddGlobalDefine( &game_globaldefines, VMA(1) ); + case G_PC_REMOVE_GLOBAL_DEFINE: + PC_RemoveGlobalDefine( &game_globaldefines, VMA(1) ); + return 0; case G_PC_REMOVE_ALL_GLOBAL_DEFINES: - botlib_export->PC_RemoveAllGlobalDefines(); + PC_RemoveAllGlobalDefines( &game_globaldefines ); return 0; case G_PC_LOAD_SOURCE: - return botlib_export->PC_LoadSourceHandle( VMA(1), VMA(2) ); + return PC_LoadSourceHandle( VMA(1), VMA(2), game_globaldefines ); case G_PC_FREE_SOURCE: - return botlib_export->PC_FreeSourceHandle( args[1] ); + return PC_FreeSourceHandle( args[1] ); + case G_PC_ADD_DEFINE: + return PC_AddDefineHandle( args[1], VMA(2) ); case G_PC_READ_TOKEN: - return botlib_export->PC_ReadTokenHandle( args[1], VMA(2) ); + return PC_ReadTokenHandle( args[1], VMA(2) ); case G_PC_UNREAD_TOKEN: - botlib_export->PC_UnreadLastTokenHandle( args[1] ); + PC_UnreadLastTokenHandle( args[1] ); return 0; case G_PC_SOURCE_FILE_AND_LINE: - return botlib_export->PC_SourceFileAndLine( args[1], VMA(2), VMA(3) ); + return PC_SourceFileAndLine( args[1], VMA(2), VMA(3) ); case G_HEAP_MALLOC: return VM_HeapMalloc( args[1] ); @@ -413,6 +422,16 @@ intptr_t SV_GameSystemCalls( intptr_t *args ) { VM_HeapFree( VMA(1) ); return 0; + case G_FIELD_COMPLETEFILENAME: + Field_CompleteFilename( VMA(1), VMA(2), args[3], args[4] ); + return 0; + case G_FIELD_COMPLETECOMMAND: + Field_CompleteCommand( VMA(1), args[2], args[3] ); + return 0; + case G_FIELD_COMPLETELIST: + Field_CompleteList( VMA(1) ); + return 0; + //==================================== case G_LOCATE_GAME_DATA: @@ -521,31 +540,11 @@ intptr_t SV_GameSystemCalls( intptr_t *args ) { case G_R_MODELBOUNDS: return re.ModelBounds( args[1], VMA(2), VMA(3), args[4], args[5], VMF(6) ); - //==================================== - - case BOTLIB_SETUP: - return SV_BotLibSetup(); - case BOTLIB_SHUTDOWN: - return SV_BotLibShutdown(); - case BOTLIB_LIBVAR_SET: - return botlib_export->BotLibVarSet( VMA(1), VMA(2) ); - case BOTLIB_LIBVAR_GET: - return botlib_export->BotLibVarGet( VMA(1), VMA(2), args[3] ); - - case BOTLIB_START_FRAME: - return botlib_export->BotLibStartFrame( VMF(1) ); - case BOTLIB_LOAD_MAP: - return botlib_export->BotLibLoadMap( VMA(1) ); - case BOTLIB_UPDATENTITY: - return botlib_export->BotLibUpdateEntity( args[1], VMA(2) ); - case BOTLIB_TEST: - return botlib_export->Test( args[1], VMA(2), VMA(3), VMA(4) ); - - case BOTLIB_GET_SNAPSHOT_ENTITY: + case G_BOT_GET_SNAPSHOT_ENTITY: return SV_BotGetSnapshotEntity( args[1], args[2] ); - case BOTLIB_GET_CONSOLE_MESSAGE: - return SV_BotGetConsoleMessage( args[1], VMA(2), args[3] ); - case BOTLIB_USER_COMMAND: + case G_BOT_GET_SERVER_COMMAND: + return SV_BotGetServerCommand( args[1], VMA(2), args[3] ); + case G_BOT_USER_COMMAND: { int playerNum = args[1]; @@ -555,112 +554,6 @@ intptr_t SV_GameSystemCalls( intptr_t *args ) { } return 0; - case BOTLIB_AAS_BBOX_AREAS: - return botlib_export->aas.AAS_BBoxAreas( VMA(1), VMA(2), VMA(3), args[4] ); - case BOTLIB_AAS_AREA_INFO: - return botlib_export->aas.AAS_AreaInfo( args[1], VMA(2) ); - case BOTLIB_AAS_ALTERNATIVE_ROUTE_GOAL: - return botlib_export->aas.AAS_AlternativeRouteGoals( VMA(1), args[2], VMA(3), args[4], args[5], VMA(6), args[7], args[8] ); - - case BOTLIB_AAS_LOADED: - return botlib_export->aas.AAS_Loaded(); - case BOTLIB_AAS_INITIALIZED: - return botlib_export->aas.AAS_Initialized(); - case BOTLIB_AAS_PRESENCE_TYPE_BOUNDING_BOX: - botlib_export->aas.AAS_PresenceTypeBoundingBox( args[1], VMA(2), VMA(3) ); - return 0; - case BOTLIB_AAS_TIME: - return FloatAsInt( botlib_export->aas.AAS_Time() ); - - case BOTLIB_AAS_POINT_AREA_NUM: - return botlib_export->aas.AAS_PointAreaNum( VMA(1) ); - case BOTLIB_AAS_POINT_REACHABILITY_AREA_INDEX: - return botlib_export->aas.AAS_PointReachabilityAreaIndex( VMA(1) ); - case BOTLIB_AAS_TRACE_PLAYER_BBOX: - botlib_export->aas.AAS_TracePlayerBBox( VMA(1), VMA(2), VMA(3), args[4], args[5], args[6] ); - return 0; - case BOTLIB_AAS_TRACE_AREAS: - return botlib_export->aas.AAS_TraceAreas( VMA(1), VMA(2), VMA(3), VMA(4), args[5] ); - - case BOTLIB_AAS_POINT_CONTENTS: - return botlib_export->aas.AAS_PointContents( VMA(1) ); - case BOTLIB_AAS_NEXT_BSP_ENTITY: - return botlib_export->aas.AAS_NextBSPEntity( args[1] ); - case BOTLIB_AAS_VALUE_FOR_BSP_EPAIR_KEY: - return botlib_export->aas.AAS_ValueForBSPEpairKey( args[1], VMA(2), VMA(3), args[4] ); - case BOTLIB_AAS_VECTOR_FOR_BSP_EPAIR_KEY: - return botlib_export->aas.AAS_VectorForBSPEpairKey( args[1], VMA(2), VMA(3) ); - case BOTLIB_AAS_FLOAT_FOR_BSP_EPAIR_KEY: - return botlib_export->aas.AAS_FloatForBSPEpairKey( args[1], VMA(2), VMA(3) ); - case BOTLIB_AAS_INT_FOR_BSP_EPAIR_KEY: - return botlib_export->aas.AAS_IntForBSPEpairKey( args[1], VMA(2), VMA(3) ); - - case BOTLIB_AAS_AREA_REACHABILITY: - return botlib_export->aas.AAS_AreaReachability( args[1] ); - case BOTLIB_AAS_BEST_REACHABLE_AREA: - return botlib_export->aas.AAS_BestReachableArea( VMA(1), VMA(2), VMA(3), VMA(4) ); - case BOTLIB_AAS_BEST_REACHABLE_FROM_JUMP_PAD_AREA: - return botlib_export->aas.AAS_BestReachableFromJumpPadArea( VMA(1), VMA(2), VMA(3) ); - case BOTLIB_AAS_NEXT_MODEL_REACHABILITY: - return botlib_export->aas.AAS_NextModelReachability( args[1], args[2] ); - case BOTLIB_AAS_AREA_GROUND_FACE_AREA: - return FloatAsInt( botlib_export->aas.AAS_AreaGroundFaceArea( args[1] ) ); - case BOTLIB_AAS_AREA_CROUCH: - return botlib_export->aas.AAS_AreaCrouch( args[1] ); - case BOTLIB_AAS_AREA_SWIM: - return botlib_export->aas.AAS_AreaSwim( args[1] ); - case BOTLIB_AAS_AREA_LIQUID: - return botlib_export->aas.AAS_AreaLiquid( args[1] ); - case BOTLIB_AAS_AREA_LAVA: - return botlib_export->aas.AAS_AreaLava( args[1] ); - case BOTLIB_AAS_AREA_SLIME: - return botlib_export->aas.AAS_AreaSlime( args[1] ); - case BOTLIB_AAS_AREA_GROUNDED: - return botlib_export->aas.AAS_AreaGrounded( args[1] ); - case BOTLIB_AAS_AREA_LADDER: - return botlib_export->aas.AAS_AreaLadder( args[1] ); - case BOTLIB_AAS_AREA_JUMP_PAD: - return botlib_export->aas.AAS_AreaJumpPad( args[1] ); - case BOTLIB_AAS_AREA_DO_NOT_ENTER: - return botlib_export->aas.AAS_AreaDoNotEnter( args[1] ); - - case BOTLIB_AAS_TRAVEL_FLAG_FOR_TYPE: - return botlib_export->aas.AAS_TravelFlagForType( args[1] ); - case BOTLIB_AAS_AREA_CONTENTS_TRAVEL_FLAGS: - return botlib_export->aas.AAS_AreaContentsTravelFlags( args[1] ); - case BOTLIB_AAS_NEXT_AREA_REACHABILITY: - return botlib_export->aas.AAS_NextAreaReachability( args[1], args[2] ); - case BOTLIB_AAS_REACHABILITY_FROM_NUM: - botlib_export->aas.AAS_ReachabilityFromNum( args[1], VMA(2) ); - return 0; - case BOTLIB_AAS_RANDOM_GOAL_AREA: - return botlib_export->aas.AAS_RandomGoalArea( args[1], args[2], args[3], VMA(4), VMA(5) ); - case BOTLIB_AAS_ENABLE_ROUTING_AREA: - return botlib_export->aas.AAS_EnableRoutingArea( args[1], args[2] ); - case BOTLIB_AAS_AREA_TRAVEL_TIME: - return botlib_export->aas.AAS_AreaTravelTime( args[1], VMA(2), VMA(3) ); - case BOTLIB_AAS_AREA_TRAVEL_TIME_TO_GOAL_AREA: - return botlib_export->aas.AAS_AreaTravelTimeToGoalArea( args[1], VMA(2), args[3], args[4] ); - case BOTLIB_AAS_PREDICT_ROUTE: - return botlib_export->aas.AAS_PredictRoute( VMA(1), args[2], VMA(3), args[4], args[5], args[6], args[7], args[8], args[9], args[10], args[11] ); - - case BOTLIB_AAS_PREDICT_PLAYER_MOVEMENT: - return botlib_export->aas.AAS_PredictPlayerMovement( VMA(1), args[2], VMA(3), args[4], args[5], - VMA(6), VMA(7), args[8], args[9], VMF(10), args[11], args[12], args[13], args[14] ); - case BOTLIB_AAS_ON_GROUND: - return botlib_export->aas.AAS_OnGround( VMA(1), args[2], args[3], args[4] ); - case BOTLIB_AAS_SWIMMING: - return botlib_export->aas.AAS_Swimming( VMA(1) ); - case BOTLIB_AAS_JUMP_REACH_RUN_START: - botlib_export->aas.AAS_JumpReachRunStart( VMA(1), VMA(2), args[3] ); - return 0; - case BOTLIB_AAS_AGAINST_LADDER: - return botlib_export->aas.AAS_AgainstLadder( VMA(1) ); - case BOTLIB_AAS_HORIZONTAL_VELOCITY_FOR_JUMP: - return botlib_export->aas.AAS_HorizontalVelocityForJump( VMF(1), VMA(2), VMA(3), VMA(4) ); - case BOTLIB_AAS_DROP_TO_FLOOR: - return botlib_export->aas.AAS_DropToFloor( VMA(1), VMA(2), VMA(3), args[4], args[5] ); - default: Com_Error( ERR_DROP, "Bad game system trap: %ld", (long int) args[0] ); } @@ -694,6 +587,12 @@ void SV_ShutdownGameProgs( void ) { SV_GameInternalShutdown( qfalse ); VM_Free( gvm ); gvm = NULL; + + //remove all global defines from the pre compiler + PC_RemoveAllGlobalDefines( &game_globaldefines ); + + // print any files still open + PC_CheckOpenSourceHandles(); } /* @@ -774,18 +673,6 @@ Called on a normal map change, not on a map_restart =============== */ void SV_InitGameProgs( void ) { - cvar_t *var; - //FIXME these are temp while I make bots run in vm - extern int bot_enable; - - var = Cvar_Get( "bot_enable", "1", CVAR_LATCH ); - if ( var ) { - bot_enable = var->integer; - } - else { - bot_enable = 0; - } - // load the dll or bytecode gvm = VM_Create( VM_PREFIX "game", SV_GameSystemCalls, Cvar_VariableValue( "vm_game" ), TAG_GAME, Cvar_VariableValue( "vm_gameHeapMegs" ) * 1024 * 1024 ); @@ -813,6 +700,19 @@ void SV_GameCommand( void ) { VM_Call( gvm, GAME_CONSOLE_COMMAND ); } +/* +==================== +CL_GameCompleteArgument +==================== +*/ +void SV_GameCompleteArgument( char *args, int argNum ) { + if ( sv.state != SS_GAME ) { + return; + } + + VM_Call( gvm, GAME_CONSOLE_COMPLETEARGUMENT, argNum ); +} + /* =============== SV_GameVidRestart diff --git a/code/server/sv_init.c b/code/server/sv_init.c index c0bc9e8bf..82f755abd 100644 --- a/code/server/sv_init.c +++ b/code/server/sv_init.c @@ -580,6 +580,10 @@ void SV_SpawnServer( char *server, qboolean killBots ) { // to load during actual gameplay sv.state = SS_LOADING; + // update latched bot cvars + SV_BotInitCvars(); + SV_BotInitBotLib(); + // load and spawn all other entities SV_InitGameProgs(); @@ -633,7 +637,7 @@ void SV_SpawnServer( char *server, qboolean killBots ) { if ( denied && player != NULL ) { // this generally shouldn't happen, because the client // was connected before the level change - SV_DropPlayer( player, denied ); + SV_DropPlayer( player, denied, qtrue ); } } @@ -816,9 +820,6 @@ void SV_Init (void) // initialize bot cvars so they are listed and can be set before loading the botlib SV_BotInitCvars(); - // init the botlib here because we need the pre-compiler in the UI - SV_BotInitBotLib(); - // Load saved bans Cbuf_AddText("rehashbans\n"); } diff --git a/make-linux-portable.sh b/make-linux-portable.sh index 4d23839da..e129b3549 100755 --- a/make-linux-portable.sh +++ b/make-linux-portable.sh @@ -1,16 +1,27 @@ #!/bin/sh if [ -z "$1" ]; then - echo "Usage: $0 " + echo "Usage: $0 [make options]" echo " arch can be x86 or x86_64" exit 0 fi ARCH=$1 -SDL_PREFIX=/home/zack/Local/SDL-2.0.3/build-$ARCH +SDL_PREFIX=/home/zack/Local/SDL-2.0.4/build-$ARCH + +if [ ! -d $SDL_PREFIX ] ; then + echo "Change SDL_PREFIX in $0 to point to SDL build output" + exit 0 +fi SDL_CFLAGS="`$SDL_PREFIX/bin/sdl2-config --cflags`" SDL_LIBS="`$SDL_PREFIX/bin/sdl2-config --libs`" -make ARCH=$ARCH USE_PORTABLE_RPATH=1 BUILD_FINAL=1 SDL_CFLAGS="$SDL_CFLAGS" SDL_LIBS="$SDL_LIBS" +# Don't pass arch ($1) to make in $* +shift 1 + +make ARCH=$ARCH USE_PORTABLE_RPATH=1 SDL_CFLAGS="$SDL_CFLAGS" SDL_LIBS="$SDL_LIBS" $* +# Copy SDL lib to where spearmint will read it from +#mkdir -p build/release-linux-$ARCH/lib/$ARCH/ +#cp $SDL_PREFIX/lib/libSDL2-2.0.so.0 build/release-linux-$ARCH/lib/$ARCH/ diff --git a/misc/nsis/Makefile b/misc/nsis/Makefile index 2c933a53f..54c84e751 100644 --- a/misc/nsis/Makefile +++ b/misc/nsis/Makefile @@ -2,7 +2,7 @@ ifndef FSNAME FSNAME=spearmint endif ifndef VERSION -VERSION=1.36_SVN +VERSION=0.5 endif ifndef RELEASE RELEASE=0 diff --git a/misc/nsis/spearmint.nsi.in b/misc/nsis/spearmint.nsi.in index 30bcf0761..4ef9133d7 100644 --- a/misc/nsis/spearmint.nsi.in +++ b/misc/nsis/spearmint.nsi.in @@ -11,6 +11,7 @@ !define GAMENAME "Spearmint" !define CLIENT "spearmint_x86.exe" !define SERVER "spearmint-server_x86.exe" +!define RENDERER_PREFIX "spearmint-renderer-" !define GAMEDIR "Spearmint" !define GAMEKEY "spearmint" @@ -100,8 +101,8 @@ Section "${GAMENAME} ${VERSION}-${RELEASE} (required)" File "../../build/release-mingw32-x86/${SERVER}" File "../../build/release-mingw32-x86/${CLIENT}" !ifdef USE_RENDERER_DLOPEN - File "../../build/release-mingw32-x86/mint-renderer-opengl1_x86.dll" - File "../../build/release-mingw32-x86/mint-renderer-opengl2_x86.dll" + File "../../build/release-mingw32-x86/${RENDERER_PREFIX}opengl1_x86.dll" + File "../../build/release-mingw32-x86/${RENDERER_PREFIX}opengl2_x86.dll" !endif File "../../COPYING.txt" @@ -168,8 +169,8 @@ Section "Uninstall" Delete $INSTDIR\${CLIENT} Delete $INSTDIR\${SERVER} !ifdef USE_RENDERER_DLOPEN - Delete $INSTDIR\mint-renderer-opengl1_x86.dll - Delete $INSTDIR\mint-renderer-opengl2_x86.dll + Delete $INSTDIR\${RENDERER_PREFIX}opengl1_x86.dll + Delete $INSTDIR\${RENDERER_PREFIX}opengl2_x86.dll !endif Delete $INSTDIR\COPYING.txt