Browse Source

fix map positions, fix #23

Ivan Avdeev 6 years ago
parent
commit
2e3ff4e987
3 changed files with 195 additions and 30 deletions
  1. 12 2
      hl2.cfg
  2. 181 26
      src/OpenSource.c
  3. 2 2
      src/bsp.h

+ 12 - 2
hl2.cfg

@@ -8,6 +8,16 @@ max_maps 99
 map d1_trainstation_01
 
 patch_landmarks {
-	map "d1_trainstation_05"
-	"landmark_trainstation_04-05" "0 0 0"
+	"d1_trainstation_05" {
+		"landmark_trainstation_04-05" "-8561.0 -4127.0 0.0"
+	}
+	"d1_canals_11" {
+		"canals_trans_0809" ""
+	}
+	"d3_c17_01" {
+		"landmark_trainstation_04-05" "-5424.0 -992.0 -439.0"
+	}
+	"d3_c17_03" {
+		"d3_c17_02-03" "-5880 -4204 135"
+	}
 }

+ 181 - 26
src/OpenSource.c

@@ -35,10 +35,18 @@ typedef struct Map {
 	char *name;
 	int loaded;
 	struct AVec3f offset;
+	struct AVec3f debug_offset;
 	struct BSPModel model;
 	struct Map *next;
 } Map;
 
+typedef struct Patch {
+	const char *map_name;
+	int delete;
+	BSPLandmark landmark;
+	struct Patch *next;
+} Patch;
+
 static struct {
 	struct Camera camera;
 	int forward, right, run;
@@ -46,6 +54,9 @@ static struct {
 	float R;
 
 	struct ICollection *collection_chain;
+
+	Patch *patches;
+
 	Map *maps_begin, *maps_end;
 	int maps_count, maps_limit;
 	Map *selected_map;
@@ -90,6 +101,29 @@ void openSourceAddMap(const char* mapname, int mapname_length) {
 	PRINTF("Added new map to the queue: %.*s", mapname_length, mapname);
 }
 
+static void mapUpdatePosition(Map *map) {
+	if (map == g.maps_begin && map->model.landmarks_count == 0)
+		return;
+
+	for (struct Map *map2 = g.maps_begin; map2; map2 = map2->next) {
+		if (map2 == map || map2->loaded != 1)
+			continue;
+
+		for (int j = 0; j < map2->model.landmarks_count; ++j) {
+			const struct BSPLandmark *m2 = map2->model.landmarks + j;
+			for (int k = 0; k < map->model.landmarks_count; ++k) {
+				const struct BSPLandmark *m1 = map->model.landmarks + k;
+				if (strcmp(m1->name, m2->name) == 0) {
+					map->offset = aVec3fAdd(aVec3fAdd(map2->offset, map2->debug_offset), aVec3fSub(m2->origin, m1->origin));
+					PRINTF("Map %s landmark %s parent map %s offset %f, %f, %f",
+						map->name, m1->name, map2->name, map->offset.x, map->offset.y, map->offset.z);
+					return;
+				} // if landmarks match
+			} // for all landmarks of map 1
+		} // for all landmarks of map 2
+	} // for all maps (2)
+}
+
 static enum BSPLoadResult loadMap(struct Map *map, struct ICollection *collection) {
 	struct BSPLoadModelContext loadctx = {
 		.collection = collection,
@@ -113,34 +147,79 @@ static enum BSPLoadResult loadMap(struct Map *map, struct ICollection *collectio
 			map->model.aabb.max.y,
 			map->model.aabb.max.z);
 
+	for (const Patch *p = g.patches; p; p = p->next) {
+		if (p->delete || strcasecmp(p->map_name, map->name) != 0)
+			continue;
+
+		int found = 0;
+		for (int i = 0; i < map->model.landmarks_count; ++i) {
+			struct BSPLandmark *lm = map->model.landmarks + i;
+			if (strcasecmp(p->landmark.name, lm->name) == 0) {
+				found = 1;
+				break;
+			}
+		}
+
+		if (found)
+			continue;
+
+		if (map->model.landmarks_count == BSP_MAX_LANDMARKS) {
+			PRINTF("Too many landmarks for map %s", map->name);
+			break;
+		}
+
+		PRINTF("Injecting landmark %s %f %f %f to map %s",
+			p->landmark.name,
+			p->landmark.origin.x,
+			p->landmark.origin.y,
+			p->landmark.origin.z,
+			map->name);
+		memmove(map->model.landmarks + 1, map->model.landmarks, sizeof(BSPLandmark) * map->model.landmarks_count);
+		map->model.landmarks[0] = p->landmark;
+		++map->model.landmarks_count;
+	}
+
 	PRINTF("Landmarks: %d", map->model.landmarks_count);
 	for (int i = 0; i < map->model.landmarks_count; ++i) {
 		struct BSPLandmark *lm = map->model.landmarks + i;
+
+		int deleted = 0;
+		for (const Patch *p = g.patches; p; p = p->next) {
+			if (strcasecmp(p->map_name, map->name) == 0 && strcasecmp(p->landmark.name, lm->name) == 0) {
+				if (p->delete) {
+					PRINTF("Deleting landmark %s", p->landmark.name);
+					--map->model.landmarks_count;
+					memmove(lm, lm + 1, sizeof(BSPLandmark) * (map->model.landmarks_count - i));
+					deleted = 1;
+				} else {
+					PRINTF("Modifying landmark %s %f %f %f -> %f %f %f of map %s",
+						p->landmark.name,
+						p->landmark.origin.x,
+						p->landmark.origin.y,
+						p->landmark.origin.z,
+						lm->origin.x,
+						lm->origin.y,
+						lm->origin.z,
+						map->name);
+					lm->origin = p->landmark.origin;
+				}
+
+				continue;
+			}
+		}
+
+		if (deleted) {
+			--i;
+			continue;
+		}
+
 		PRINTF("\t%d: %s -> (%f, %f, %f)", i + 1, lm->name,
 			lm->origin.x, lm->origin.y, lm->origin.z);
 	}
 
+	map->offset = map->debug_offset = aVec3ff(0);
 	map->loaded = 1;
-
-	if (map != g.maps_begin && map->model.landmarks_count != 0) {
-		for (struct Map *map2 = g.maps_begin; map2; map2 = map2->next) {
-			if (map2->loaded != 1)
-				continue;
-
-			for (int j = 0; j < map2->model.landmarks_count; ++j) {
-				const struct BSPLandmark *m2 = map2->model.landmarks + j;
-				for (int k = 0; k < map->model.landmarks_count; ++k) {
-					const struct BSPLandmark *m1 = map->model.landmarks + k;
-					if (strcmp(m1->name, m2->name) == 0) {
-						map->offset = aVec3fAdd(map2->offset, aVec3fSub(m2->origin, m1->origin));
-						PRINTF("Map %s offset %f, %f, %f",
-							map->name, map->offset.x, map->offset.y, map->offset.z);
-						return BSPLoadResult_Success;
-					} // if landmarks match
-				} // for all landmarks of map 1
-			} // for all landmarks of map 2
-		} // for all maps (2)
-	} // if neet to position map
+	mapUpdatePosition(map);
 
 	return BSPLoadResult_Success;
 }
@@ -204,7 +283,7 @@ static void opensrcPaint(ATimeUs timestamp, float dt) {
 
 		const RDrawParams params = {
 			.camera = &g.camera,
-			.translation = map->offset,
+			.translation = aVec3fAdd(map->offset, map->debug_offset),
 			.selected = map == g.selected_map
 		};
 
@@ -255,6 +334,8 @@ static void opensrcKeyPress(ATimeUs timestamp, AKey key, int pressed) {
 		case AK_PageDown: map_offset.z -= 1.f; moved_map = 1; break;
 		case AK_Tab:
 			g.selected_map = g.selected_map ? g.selected_map->next : g.maps_begin;
+			if (g.selected_map)
+				PRINTF("Selected map %s", g.selected_map->name);
 			break;
 		case AK_Q:
 			g.selected_map = NULL;
@@ -269,9 +350,11 @@ static void opensrcKeyPress(ATimeUs timestamp, AKey key, int pressed) {
 				map_offset.y *= 100.f;
 				map_offset.z *= 100.f;
 			}
-			PRINTF("Map offset: %f %f %f", map_offset.x, map_offset.y, map_offset.z);
-			map->offset = aVec3fAdd(map->offset, map_offset);
-			PRINTF("Map offset: %f %f %f", map->offset.x, map->offset.y, map->offset.z);
+			map->debug_offset = aVec3fAdd(map->debug_offset, map_offset);
+			PRINTF("Map %s offset: %f %f %f", map->name, map->debug_offset.x, map->debug_offset.y, map->debug_offset.z);
+
+			for (Map *m = map; m; m = m->next)
+				mapUpdatePosition(m);
 		}
 	}
 }
@@ -299,8 +382,38 @@ static struct ICollection *addToCollectionChain(struct ICollection *chain, struc
 	return next;
 }
 
+static void opensrcAddLandmarkPatch(StringView map, StringView key, StringView value) {
+	if (key.length >= BSP_LANDMARK_NAME_LENGTH) {
+		PRINTF(PRI_SV " is too long", PRI_SVV(key));
+		return;
+	}
+
+	struct AVec3f origin = aVec3ff(0);
+	// FIXME sscanf limit by value.length
+	if (value.length >= 5 && 3 != sscanf(value.str, "%f %f %f", &origin.x, &origin.y, &origin.z)) {
+		PRINTF(PRI_SV " format is wrong", PRI_SVV(value));
+		return;
+	}
+
+	Patch *new_patch = stackAlloc(mem.persistent, sizeof(Patch));
+	new_patch->next = g.patches;
+	g.patches = new_patch;
+
+	char *map_name = stackAlloc(mem.persistent, map.length + 1);
+	memcpy(map_name, map.str, map.length);
+	map_name[map.length] = '\0';
+	new_patch->map_name = map_name;
+
+	new_patch->delete = value.length < 5;
+
+	memcpy(new_patch->landmark.name, key.str, key.length);
+	new_patch->landmark.name[key.length] = '\0';
+	new_patch->landmark.origin = origin;
+}
+
 typedef struct {
 	StringView gamedir;
+	StringView current_patched_map;
 } Config;
 
 static char *buildSteamPath(const StringView *gamedir, const StringView *path) {
@@ -329,6 +442,46 @@ static char *buildSteamPath(const StringView *gamedir, const StringView *path) {
 	return value;
 }
 
+static VMFAction configPatchCallback(VMFState *state, VMFEntryType entry, const VMFKeyValue *kv);
+static VMFAction configReadCallback(VMFState *state, VMFEntryType entry, const VMFKeyValue *kv);
+
+static VMFAction configLandmarkCallback(VMFState *state, VMFEntryType entry, const VMFKeyValue *kv) {
+	Config *cfg = state->user_data;
+
+	switch (entry) {
+	case VMFEntryType_KeyValue:
+		opensrcAddLandmarkPatch(cfg->current_patched_map, kv->key, kv->value);
+		break;
+	case VMFEntryType_SectionClose:
+		cfg->current_patched_map.length = 0;
+		state->callback = configPatchCallback;
+		break;
+	default:
+		return VMFAction_SemanticError;
+	}
+
+	return VMFAction_Continue;
+}
+
+static VMFAction configPatchCallback(VMFState *state, VMFEntryType entry, const VMFKeyValue *kv) {
+	Config *cfg = state->user_data;
+
+	switch (entry) {
+	case VMFEntryType_SectionOpen:
+		if (kv->key.length < 1)
+			return VMFAction_SemanticError;
+		cfg->current_patched_map = kv->key;
+		state->callback = configLandmarkCallback;
+		break;
+	case VMFEntryType_SectionClose:
+		return VMFAction_Exit;
+	default:
+		return VMFAction_SemanticError;
+	}
+
+	return VMFAction_Continue;
+}
+
 static VMFAction configReadCallback(VMFState *state, VMFEntryType entry, const VMFKeyValue *kv) {
 	Config *cfg = state->user_data;
 
@@ -352,9 +505,10 @@ static VMFAction configReadCallback(VMFState *state, VMFEntryType entry, const V
 		} 
 		break;
 	case VMFEntryType_SectionOpen:
-		return VMFAction_Exit;
+		if (strncasecmp("patch_landmarks", kv->key.str, kv->key.length) != 0)
+			return VMFAction_SemanticError;
+		state->callback = configPatchCallback;
 		break;
-
 	default:
 		return VMFAction_SemanticError;
 	}
@@ -397,6 +551,7 @@ void attoAppInit(struct AAppProctable *proctable) {
 	profilerInit();
 	//aGLInit();
 	g.collection_chain = NULL;
+	g.patches = NULL;
 	g.maps_limit = 1;
 	g.maps_count = 0;
 	g.selected_map = NULL;

+ 2 - 2
src/bsp.h

@@ -22,10 +22,10 @@ struct BSPDraw {
 #define BSP_LANDMARK_NAME_LENGTH 64
 #define BSP_MAX_LANDMARKS 32
 
-struct BSPLandmark {
+typedef struct BSPLandmark {
 	char name[BSP_LANDMARK_NAME_LENGTH];
 	struct AVec3f origin;
-};
+} BSPLandmark;
 
 struct BSPDrawSet {
 	int draws_count;