summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--Data/Skeleton/Basic Figurebin1809 -> 0 bytes
-rw-r--r--src/GameInitDispose.cpp35
-rw-r--r--src/GameTick.cpp4
-rw-r--r--src/Skeleton.cpp101
-rw-r--r--src/Skeleton.h44
-rw-r--r--src/config.zig10
-rw-r--r--src/joints.tsv21
-rw-r--r--src/main.zig7
-rw-r--r--src/misc.h22
-rw-r--r--src/misc.zig98
-rw-r--r--src/muscles.tsv30
11 files changed, 240 insertions, 132 deletions
diff --git a/Data/Skeleton/Basic Figure b/Data/Skeleton/Basic Figure
deleted file mode 100644
index 7621984..0000000
--- a/Data/Skeleton/Basic Figure
+++ /dev/null
Binary files differdiff --git a/src/GameInitDispose.cpp b/src/GameInitDispose.cpp
index c2ef2ca..873aaa0 100644
--- a/src/GameInitDispose.cpp
+++ b/src/GameInitDispose.cpp
@@ -646,9 +646,6 @@ void initGame(Game* game)
 	vip.playerrotation2 = 0; // 20
 	vip.lastdistancevictim = 200000;
 
-	if (vip.skeleton.broken)
-		vip.skeleton.Load((char*) ":Data:Skeleton:Basic Figure");
-
 	game->citypeoplenum[vip.whichblockx][vip.whichblocky]++;
 	game->numpeople++;
 	game->spawndelay = 0.1f;
@@ -1378,60 +1375,33 @@ void initGame(Game* game)
 		costume[bodyguardcostume].footcolor[2]=footcolor[2];
 
 		//Load animations
-		testskeleton.Load((char *)":Data:Skeleton:Basic Figure");
-
+		testskeleton.reload();
 		animation[idleanim].Load((char *)":Data:Animations:Breathe");
-
 		animation[joganim].Load((char *)":Data:Animations:Run");
-
 		animation[pistolaimanim].Load((char *)":Data:Animations:PistolAim");
-
 		animation[walkanim].Load((char *)":Data:Animations:Walk");
-
 		animation[rifleholdanim].Load((char *)":Data:Animations:Riflehold");
-
 		animation[rifleaimanim].Load((char *)":Data:Animations:Rifleaim");
-
 		animation[assaultrifleaimanim].Load((char *)":Data:Animations:AssaultRifleaim");
-
 		animation[crouchanim].Load((char *)":Data:Animations:Crouch");
-
 		animation[headpainanim].Load((char *)":Data:Animations:Headshot");
-
 		animation[chestpainanim].Load((char *)":Data:Animations:Chestshot");
-
 		animation[stomachpainanim].Load((char *)":Data:Animations:Stomachshot");
-
 		animation[rightarmpainanim].Load((char *)":Data:Animations:Rightarmshot");
-
 		animation[leftarmpainanim].Load((char *)":Data:Animations:Leftarmshot");
-
 		animation[rightlegpainanim].Load((char *)":Data:Animations:Rightlegshot");
-
 		animation[leftlegpainanim].Load((char *)":Data:Animations:Leftlegshot");
-
 		animation[riflehitanim].Load((char *)":Data:Animations:Riflehit");
-
 		animation[grenadeaimanim].Load((char *)":Data:Animations:grenadeaim");
-
 		animation[grenadechargeanim].Load((char *)":Data:Animations:grenadecharge");
-
 		animation[grenadethrowanim].Load((char *)":Data:Animations:grenadethrow");
-
 		animation[zombieeatanim].Load((char *)":Data:Animations:Zombiemunch");
-
 		animation[zombiejoganim].Load((char *)":Data:Animations:ZombieRun");
-
 		animation[zombiewalkanim].Load((char *)":Data:Animations:Zombiewalk");
-
 		animation[getupfrontanim].Load((char *)":Data:Animations:Getupfromfront");
-
 		animation[getupbackanim].Load((char *)":Data:Animations:Getupfromback",180);
-
 		animation[diveanim].Load((char *)":Data:Animations:Dive");
-
 		animation[throwanim].Load((char *)":Data:Animations:Aikidothrow");
-
 		animation[thrownanim].Load((char *)":Data:Animations:Aikidothrown");
 
 	// Setup people
@@ -1451,8 +1421,7 @@ void initGame(Game* game)
 		person.velocity = 0;
 
 		// Load skeleton structure
-		if (!game->initialized)
-			person.skeleton.Load((char*) ":Data:Skeleton:Basic Figure");
+		person.skeleton.reload();
 	}
 
 	bodyguard.attackframe = -1;
diff --git a/src/GameTick.cpp b/src/GameTick.cpp
index 3088ae5..9a79086 100644
--- a/src/GameTick.cpp
+++ b/src/GameTick.cpp
@@ -829,8 +829,6 @@ void Game::Tick()
 
 		person[numpeople].lastdistancevictim=200000;
 
-		if(person[numpeople].skeleton.broken)person[numpeople].skeleton.Load((char *)":Data:Skeleton:Basic Figure");
-
 		if(numpeople==1)person[numpeople].type=viptype;
 
 		person[numpeople].killtarget=-1;
@@ -957,8 +955,6 @@ void Game::Tick()
 
 			person[cycle].playerrotation2=0;
 
-			if(person[cycle].skeleton.broken)person[cycle].skeleton.Load((char *)":Data:Skeleton:Basic Figure");
-
 			if(enemystate==1)person[cycle].killtarget=-1;
 
 			if(person[cycle].type==eviltype){person[cycle].existing=1;  person[cycle].pathsize=1.04; person[cycle].whichgun=nogun; person[cycle].aiming=1; person[cycle].killtarget=-1; person[cycle].speedmult=1+.3*difficulty;}
diff --git a/src/Skeleton.cpp b/src/Skeleton.cpp
index 7dcdaa1..2624efd 100644
--- a/src/Skeleton.cpp
+++ b/src/Skeleton.cpp
@@ -744,61 +744,56 @@ void Animation::Load(char *fileName, float rotate)
 	}
 }
 
-void Skeleton::Load(char *fileName)
+void Skeleton::reload()
 {
-	int parentID;
-	bool what;
-	files.OpenFile(fileName);
-	if(files.sFile){
-		ReadInt(files.sFile, 1, &num_joints);
-		for(int i=0;i<num_joints;i++){
-			ReadXYZ(files.sFile, 1, &joints[i].position);
-			ReadFloat(files.sFile, 1, &joints[i].length);
-			ReadFloat(files.sFile, 1, &joints[i].mass);
-			ReadBool(files.sFile, 1, &joints[i].hasparent);
-			ReadBool(files.sFile, 1, &joints[i].locked);
-			ReadInt(files.sFile, 1, &joints[i].modelnum);
-			ReadBool(files.sFile, 1, &joints[i].visible);
-			ReadBool(files.sFile, 1, &what);
-			ReadInt(files.sFile, 1, &joints[i].label);
-			ReadInt(files.sFile, 1, &joints[i].hasgun);
-			ReadBool(files.sFile, 1, &joints[i].lower);
-			ReadInt(files.sFile, 1, &parentID);
-			if(joints[i].hasparent)joints[i].parent=&joints[parentID];
-			joints[i].velocity=0;
-			joints[i].oldposition=joints[i].position;
-			joints[i].existing=1;
-		}
-
-		ReadInt(files.sFile, 1, &num_muscles);
-		for(int i=0;i<num_muscles;i++){
-			ReadFloat(files.sFile, 1, &muscles[i].length);
-			ReadFloat(files.sFile, 1, &muscles[i].targetlength);
-			ReadFloat(files.sFile, 1, &muscles[i].minlength);
-			ReadFloat(files.sFile, 1, &muscles[i].maxlength);
-			ReadFloat(files.sFile, 1, &muscles[i].strength);
-			ReadInt(files.sFile, 1, &muscles[i].type);
-			ReadBool(files.sFile, 1, &muscles[i].visible);
-			ReadInt(files.sFile, 1, &parentID);
-			muscles[i].parent1=&joints[parentID];
-			ReadInt(files.sFile, 1, &parentID);
-			muscles[i].parent2=&joints[parentID];
-		}
-
-		for(int j=0;j<3;j++){
-			ReadInt(files.sFile, 1, &forwardjoints[j]);
-		}
-		for(int j=0;j<3;j++){
-			ReadInt(files.sFile, 1, &lowforwardjoints[j]);
-		}
+	broken = 0;
+	num_joints = 20;
+	JointData joints_data[num_joints];
+	loadJoints(joints_data);
+	for (int i = 0; i < num_joints; ++i) {
+		joints[i].label = joints_data[i].label;
+		joints[i].position.x = joints_data[i].x;
+		joints[i].position.y = joints_data[i].y;
+		joints[i].position.z = joints_data[i].z;
+		joints[i].length = joints_data[i].length;
+		joints[i].modelnum = joints_data[i].model;
+		joints[i].visible = joints_data[i].visible;
+		joints[i].lower = joints_data[i].lower;
+
+		if (joints_data[i].parent < 0) {
+			joints[i].hasparent = false;
+			joints[i].parent = NULL;
+		} else {
+			joints[i].hasparent = true;
+			joints[i].parent = joints + joints_data[i].parent;
+		}
+
+		joints[i].existing = true;
+		joints[i].locked = false;
+		joints[i].velocity = 0;
+		joints[i].oldposition = joints[i].position;
+		jointlabels[joints[i].label] = i;
 	}
-	files.EndLoad();
 
-	for(int i=0;i<num_joints;i++){
-		for(int j=0;j<num_joints;j++){
-			if(joints[i].label==j)jointlabels[j]=i;
-		}
+	forwardjoints[0] = 7;
+	forwardjoints[1] = 3;
+	forwardjoints[2] = 8;
+	lowforwardjoints[0] = 17;
+	lowforwardjoints[1] = 3;
+	lowforwardjoints[2] = 19;
+
+	num_muscles = 29;
+	MuscleData muscles_data[num_muscles];
+	loadMuscles(muscles_data);
+	for (int i = 0; i < num_muscles; ++i) {
+		muscles[i].length = muscles_data[i].length;
+		muscles[i].targetlength = muscles_data[i].initlen;
+		muscles[i].minlength = muscles_data[i].minlen;
+		muscles[i].maxlength = muscles_data[i].maxlen;
+		muscles[i].type = muscles_data[i].flag;
+		muscles[i].visible = muscles_data[i].visible;
+		muscles[i].parent1 = joints + muscles_data[i].parent1;
+		muscles[i].parent2 = joints + muscles_data[i].parent2;
+		muscles[i].strength = !muscles[i].type;
 	}
-
-	broken=0;
 }
diff --git a/src/Skeleton.h b/src/Skeleton.h
index b408b3c..d28494d 100644
--- a/src/Skeleton.h
+++ b/src/Skeleton.h
@@ -20,26 +20,26 @@
 		//middle, left hip, right hip,groin
 		//left knee,left ankle, left foot, right knee, right ankle, right foort
 
-#define head 1
-#define neck 2
-#define leftshoulder 3
-#define leftelbow 4
-#define leftwrist 5
-#define lefthand 6
-#define rightshoulder 7
-#define rightelbow 8
-#define rightwrist 9
-#define righthand 10
-#define abdomen 11
-#define lefthip 12
-#define righthip 13
-#define groin 14
-#define leftknee 15
-#define leftankle 16
-#define leftfoot 17
-#define rightknee 18
-#define rightankle 19
-#define rightfoot 20
+#define head 0
+#define neck 1
+#define leftshoulder 2
+#define leftelbow 3
+#define leftwrist 4
+#define lefthand 5
+#define rightshoulder 6
+#define rightelbow 7
+#define rightwrist 8
+#define righthand 9
+#define abdomen 10
+#define lefthip 11
+#define righthip 12
+#define groin 13
+#define leftknee 14
+#define leftankle 15
+#define leftfoot 16
+#define rightknee 17
+#define rightankle 18
+#define rightfoot 19
 
 class Joint
 {
@@ -51,7 +51,6 @@ class Joint
 		XYZ offset;
 		float blurred;
 		float length;
-		float mass;
 		bool lower;
 		bool hasparent;
 		bool locked;
@@ -60,7 +59,6 @@ class Joint
 		bool existing;
 		Joint* parent;
 		int label;
-		int hasgun;
 		float rotate1,rotate2,rotate3;
 
 		void DoConstraint();
@@ -143,7 +141,7 @@ class Skeleton
 		void DeleteMuscle(int whichmuscle);
 		void FindRotationJoint(int which);
 		void FindRotationMuscle(int which);
-		void Load(char *fileName);
+		void reload();
 };
 
 #endif
diff --git a/src/config.zig b/src/config.zig
index 49c6dad..2ecb69b 100644
--- a/src/config.zig
+++ b/src/config.zig
@@ -24,6 +24,7 @@ const ini = @import("ini");
 const join = std.fs.path.join;
 const mkdir = std.os.mkdir;
 const openFile = std.fs.openFileAbsolute;
+const parseBool = @import("misc.zig").parseBool;
 const parseFloat = std.fmt.parseFloat;
 const parseInt = std.fmt.parseInt;
 const std = @import("std");
@@ -44,15 +45,6 @@ pub const Config = extern struct {
     debug: bool = false,
 };
 
-/// Parse boolean values.
-fn parseBool(s: []const u8) !bool {
-    if (eql(u8, s, "false"))
-        return false;
-    if (eql(u8, s, "true"))
-        return true;
-    return error.InvalidCharacter;
-}
-
 /// Parse config.ini in the given base directory.
 pub fn parse(allocator: *Allocator, base_dir: []const u8) !Config {
     const config_dir = try join(allocator, &.{ base_dir, "blackshades" });
diff --git a/src/joints.tsv b/src/joints.tsv
new file mode 100644
index 0000000..52f81ef
--- /dev/null
+++ b/src/joints.tsv
@@ -0,0 +1,21 @@
+label	x	y	z	length	model	visible	lower	parent
+5	-0.1378	0.2002	1.0711	0.3174	5	true	false	15
+18	-3.8366	0.2002	1.1826	0.6836	8	true	true	-1
+17	-2.5112	0.2002	0.5712	1.4597	7	true	true	1
+10	0.0644	0.2002	0.1555	1.4178	2	false	true	7
+14	-0.5556	0.2002	2.9636	1.5648	6	true	true	-1
+15	-1.0848	0.2002	4.4175	1.5473	7	true	true	4
+16	-1.2397	0.2002	4.5773	0.2226	8	true	true	5
+2	1.2820	0.2002	-0.5709	0.0000	0	false	false	-1
+6	-0.4220	0.2002	-1.1863	1.8730	0	false	false	7
+1	0.4964	0.2002	-0.8546	0.9459	1	false	false	8
+0	0.2390	0.2002	-2.2577	1.4112	0	true	false	9
+7	-1.5911	0.2002	-1.3499	1.1803	3	true	false	8
+8	-2.5230	0.2002	-1.3332	0.9321	4	true	false	11
+9	-2.8692	0.2002	-1.2356	0.3597	5	true	false	12
+3	1.0220	0.2002	0.6092	1.2048	3	true	false	7
+4	0.1480	0.2002	0.9330	0.9321	4	true	false	14
+19	-4.0869	0.2002	1.1576	0.2515	8	true	true	1
+12	-0.8438	0.2002	0.9086	1.1798	6	false	true	3
+13	-0.2474	0.2002	1.1657	0.5090	6	false	true	17
+11	0.3856	0.2002	1.4386	1.3227	6	false	true	3
diff --git a/src/main.zig b/src/main.zig
index f80d316..d7a1da1 100644
--- a/src/main.zig
+++ b/src/main.zig
@@ -25,13 +25,6 @@ const gl = @import("zgl");
 const legacy = @cImport(@cInclude("Game.h"));
 const misc = @import("misc.zig");
 
-comptime {
-    // Work around lazy compilation.
-    @export(misc.loadSound, .{ .name = "loadSound" });
-    @export(misc.loadTexture, .{ .name = "loadTexture" });
-    @export(misc.playSound, .{ .name = "playSound" });
-}
-
 var game: *legacy.Game = undefined;
 
 fn resizeWindow(window: ?*gf.Window.Impl,
diff --git a/src/misc.h b/src/misc.h
index 638255c..5fa1b56 100644
--- a/src/misc.h
+++ b/src/misc.h
@@ -1,14 +1,36 @@
 #ifndef BLACKSHADES_MISC_H
 #define BLACKSHADES_MISC_H
 
+#include <stdbool.h>
+
 #include <AL/al.h>
 #include <GL/gl.h>
 
+struct JointData {
+    signed char label;
+    float x, y, z;
+    float length;
+    unsigned char model;
+    bool visible;
+    bool lower;
+    signed char parent;
+};
+
+struct MuscleData {
+    float length, initlen, minlen, maxlen;
+    bool flag;
+    bool visible;
+    signed char parent1;
+    signed char parent2;
+};
+
 #ifdef __cplusplus
 extern "C" {
 #endif // __cplusplus
 	ALuint loadSound(const char*);
 	GLuint loadTexture(const char*);
+	void loadJoints(JointData*);
+	void loadMuscles(MuscleData*);
 	void playSound(ALuint source, ALfloat x, ALfloat y, ALfloat z);
 #ifdef __cplusplus
 } // extern "C"
diff --git a/src/misc.zig b/src/misc.zig
index 353dcac..f4021ac 100644
--- a/src/misc.zig
+++ b/src/misc.zig
@@ -27,15 +27,98 @@ const al = @import("zeal");
 const allocator = std.heap.c_allocator;
 const cwd = std.fs.cwd;
 const data_dir = @import("build_options").data_dir ++ [_]u8{ sep };
+const eql = std.mem.eql;
 const free = std.c.free;
 const join = std.fs.path.joinZ;
 const maxInt = std.math.maxInt;
+const parseFloat = std.fmt.parseFloat;
+const parseInt = std.fmt.parseInt;
 const sep = std.fs.path.sep;
 const span = std.mem.span;
 const std = @import("std");
+const tokenize = std.mem.tokenize;
+
+/// Parse boolean values.
+pub fn parseBool(s: []const u8) !bool {
+    if (eql(u8, s, "false"))
+        return false;
+    if (eql(u8, s, "true"))
+        return true;
+    return error.InvalidCharacter;
+}
+
+const Joint = extern struct {
+    label: i8,
+    x: f32,
+    y: f32,
+    z: f32,
+    length: f32,
+    model: u8,
+    visible: bool,
+    lower: bool,
+    parent: i8,
+
+    pub fn load(self: *Joint, row: []const u8) !void {
+        var values = tokenize(row, "\t");
+        self.label = try parseInt(i8, values.next().?, 10);
+        self.x = try parseFloat(f32, values.next().?);
+        self.y = try parseFloat(f32, values.next().?);
+        self.z = try parseFloat(f32, values.next().?);
+        self.length = try parseFloat(f32, values.next().?);
+        self.model = try parseInt(u8, values.next().?, 10);
+        self.visible = try parseBool(values.next().?);
+        self.lower = try parseBool(values.next().?);
+        self.parent = try parseInt(i8, values.next().?, 10);
+    }
+};
+
+/// Load joints in character's frame
+fn loadJoints(joints: [*]Joint) callconv(.C) void {
+    var tsv = tokenize(@embedFile("joints.tsv"), "\n");
+    _ = tsv.next().?; // ignore field names
+    var i = @as(u8, 0);
+    while (tsv.next()) |row| {
+        joints[i].load(row) catch unreachable;
+        i += 1;
+    }
+}
+
+const Muscle = extern struct {
+    length: f32,
+    initlen: f32,
+    minlen: f32,
+    maxlen: f32,
+    flag: bool,
+    visible: bool,
+    parent1: i8,
+    parent2: i8,
+
+    pub fn load(self: *Muscle, row: []const u8) !void {
+        var values = tokenize(row, "\t");
+        self.length = try parseFloat(f32, values.next().?);
+        self.initlen = try parseFloat(f32, values.next().?);
+        self.minlen = try parseFloat(f32, values.next().?);
+        self.maxlen = try parseFloat(f32, values.next().?);
+        self.flag = try parseBool(values.next().?);
+        self.visible = try parseBool(values.next().?);
+        self.parent1 = try parseInt(i8, values.next().?, 10);
+        self.parent2 = try parseInt(i8, values.next().?, 10);
+    }
+};
+
+/// Load muscles in character's frame
+fn loadMuscles(muscles: [*]Muscle) callconv(.C) void {
+    var tsv = tokenize(@embedFile("muscles.tsv"), "\n");
+    _ = tsv.next().?; // ignore field names
+    var i = @as(u8, 0);
+    while (tsv.next()) |row| {
+        muscles[i].load(row) catch unreachable;
+        i += 1;
+    }
+}
 
 /// Load audio file into an OpenAL buffer and return it.
-pub fn loadSound(filename: [*:0]const u8) callconv(.C) u32 {
+fn loadSound(filename: [*:0]const u8) callconv(.C) u32 {
     const path = join(allocator, &.{ data_dir ++ "sounds", span(filename) })
         catch unreachable;
     defer allocator.free(path);
@@ -52,7 +135,7 @@ fn check(errorString: fn (c_uint) callconv(.C) [*c]const u8,
 }
 
 /// Load PNG file into an OpenGL buffer and return it.
-pub fn loadTexture(filename: [*:0]const u8) callconv(.C) GLuint {
+fn loadTexture(filename: [*:0]const u8) callconv(.C) GLuint {
     var dir = cwd().openDir(data_dir ++ "textures", .{}) catch unreachable;
     defer dir.close();
     // Don't judge me, take care of me!
@@ -86,9 +169,18 @@ pub fn loadTexture(filename: [*:0]const u8) callconv(.C) GLuint {
 }
 
 /// Move sound source to given position and play it.
-pub fn playSound(source: u32, x: f32, y: f32, z: f32) callconv(.C) void {
+fn playSound(source: u32, x: f32, y: f32, z: f32) callconv(.C) void {
     const src = al.Source{ .reference = source };
     _ = alGetError(); // TODO: remove when completely migrate to zeal
     src.setPosition(.{ x / 32, y / 32, z / 32 }) catch unreachable;
     src.play() catch unreachable;
 }
+
+comptime {
+    // Work around lazy compilation.
+    @export(loadJoints, .{ .name = "loadJoints" });
+    @export(loadMuscles, .{ .name = "loadMuscles" });
+    @export(loadSound, .{ .name = "loadSound" });
+    @export(loadTexture, .{ .name = "loadTexture" });
+    @export(playSound, .{ .name = "playSound" });
+}
diff --git a/src/muscles.tsv b/src/muscles.tsv
new file mode 100644
index 0000000..795e036
--- /dev/null
+++ b/src/muscles.tsv
@@ -0,0 +1,30 @@
+length	initlen	minlen	maxlen	type	visible	parent1	parent2
+1.7697	1.7697	0.0000	16.6320	false	true	17	2
+0.8354	0.8354	0.0000	10.0000	false	false	7	9
+1.4274	1.4274	0.0000	13.6748	false	false	3	8
+0.6199	0.6199	0.0000	13.5724	false	false	18	19
+1.3388	1.3388	0.0000	15.8856	false	false	17	19
+1.7920	1.7920	0.0000	12.8109	false	true	19	4
+1.0572	1.9491	0.0000	13.2607	true	true	3	18
+1.0987	1.0143	0.0000	12.5167	true	true	9	3
+2.1370	2.3075	0.0000	2.3075	true	false	8	17
+2.2003	2.5659	0.0000	2.5659	true	false	7	19
+2.5899	2.5822	2.0812	10.0000	true	false	17	7
+2.7465	2.7494	2.2821	10.0000	true	false	19	8
+2.2376	1.0983	1.1285	10.0000	true	false	3	11
+1.0596	1.0856	1.0596	10.0000	true	false	3	14
+2.1947	2.2254	2.1947	10.0000	true	false	8	15
+3.8805	2.5318	2.5462	10.0000	true	false	7	12
+2.4195	2.0167	2.3011	10.0000	true	false	3	10
+3.0239	1.8946	1.9257	10.0000	true	false	19	2
+2.0751	2.0963	2.0751	10.0000	true	false	17	4
+4.2300	1.7806	3.5772	4.2300	true	false	19	1
+3.5171	2.9497	2.9440	4.0761	true	false	17	5
+4.1521	2.8085	3.9940	10.0000	true	false	8	4
+5.6429	3.9810	5.6429	10.0000	true	false	8	5
+3.9613	3.5795	3.5930	10.0000	true	false	7	2
+5.4106	5.0035	5.0111	10.0000	true	false	7	1
+1.7528	1.7509	1.7513	10.0000	true	false	4	6
+1.6813	1.6416	1.6507	10.0000	true	false	2	16
+1.2484	1.2301	1.2221	10.0000	true	false	14	0
+1.2833	1.1653	1.1626	10.0000	true	false	11	13