summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/Constants.h6
-rw-r--r--src/GameInitDispose.cpp58
-rw-r--r--src/Skeleton.cpp176
-rw-r--r--src/Skeleton.h11
-rw-r--r--src/misc.h34
-rw-r--r--src/misc.zig64
6 files changed, 129 insertions, 220 deletions
diff --git a/src/Constants.h b/src/Constants.h
index 1998e47..4528498 100644
--- a/src/Constants.h
+++ b/src/Constants.h
@@ -1,9 +1,9 @@
 #ifndef _CONSTANTS_H_
 #define _CONSTANTS_H_
 
-#define max_joints 50
-#define max_frames 50
-#define max_muscles 100
+#define max_joints 20
+#define max_frames 16
+#define max_muscles 29
 #define gravity -25
 
 #define bullethole 0
diff --git a/src/GameInitDispose.cpp b/src/GameInitDispose.cpp
index 873aaa0..ba27374 100644
--- a/src/GameInitDispose.cpp
+++ b/src/GameInitDispose.cpp
@@ -1374,35 +1374,35 @@ void initGame(Game* game)
 
 		costume[bodyguardcostume].footcolor[2]=footcolor[2];
 
-		//Load animations
-		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");
+	// Load animations
+	testskeleton.reload();
+	animation[idleanim].load("Breathe");
+	animation[joganim].load("Run");
+	animation[pistolaimanim].load("PistolAim");
+	animation[walkanim].load("Walk");
+	animation[rifleholdanim].load("Riflehold");
+	animation[rifleaimanim].load("Rifleaim");
+	animation[assaultrifleaimanim].load("AssaultRifleaim");
+	animation[crouchanim].load("Crouch");
+	animation[headpainanim].load("Headshot");
+	animation[chestpainanim].load("Chestshot");
+	animation[stomachpainanim].load("Stomachshot");
+	animation[rightarmpainanim].load("Rightarmshot");
+	animation[leftarmpainanim].load("Leftarmshot");
+	animation[rightlegpainanim].load("Rightlegshot");
+	animation[leftlegpainanim].load("Leftlegshot");
+	animation[riflehitanim].load("Riflehit");
+	animation[grenadeaimanim].load("grenadeaim");
+	animation[grenadechargeanim].load("grenadecharge");
+	animation[grenadethrowanim].load("grenadethrow");
+	animation[zombieeatanim].load("Zombiemunch");
+	animation[zombiejoganim].load("ZombieRun");
+	animation[zombiewalkanim].load("Zombiewalk");
+	animation[getupfrontanim].load("Getupfromfront");
+	animation[getupbackanim].load("Getupfromback");
+	animation[diveanim].load("Dive");
+	animation[throwanim].load("Aikidothrow");
+	animation[thrownanim].load("Aikidothrown");
 
 	// Setup people
 	for (int i = 0; i < max_people; ++i) {
diff --git a/src/Skeleton.cpp b/src/Skeleton.cpp
index 2624efd..7315fac 100644
--- a/src/Skeleton.cpp
+++ b/src/Skeleton.cpp
@@ -458,175 +458,19 @@ void Skeleton::FindRotationMuscle(int which)
 
 extern Skeleton testskeleton;
 
-void Animation::Load(char *fileName)
+void Animation::load(const char* name)
 {
-	files.OpenFile(fileName);
-	if(files.sFile){
-		ReadInt(files.sFile, 1, &numframes);
-		for(int i=0;i<numframes;i++){
-			for(int j=0;j<max_joints;j++){
-				ReadXYZ(files.sFile, 1, &position[j][i]);
-			}
-			for(int j=0;j<max_joints;j++){
-				ReadFloat(files.sFile, 1, &twist[j][i]);
-			}
-			for(int j=0;j<max_joints;j++){
-				ReadBool(files.sFile, 1, &onground[j][i]);
-			}
-			ReadFloat(files.sFile, 1, &speed[i]);
-			ReadFloat(files.sFile, 1, &gunrotation[i]);
-		}
-		for(int i=0;i<numframes;i++){
-			for(int j=0;j<max_joints;j++){
-				ReadFloat(files.sFile, 1, &twist2[j][i]);
-			}
-		}
-	}
-
-	files.EndLoad();
-
-	for(int j=0;j<numframes;j++){
-		for(int i=0;i<testskeleton.num_joints;i++){
-			testskeleton.joints[i].position=position[i][j];
-		}
-		//Find forward vectors
-		CrossProduct(testskeleton.joints[testskeleton.forwardjoints[1]].position-testskeleton.joints[testskeleton.forwardjoints[0]].position,testskeleton.joints[testskeleton.forwardjoints[2]].position-testskeleton.joints[testskeleton.forwardjoints[0]].position,&testskeleton.forward);
-		Normalise(&testskeleton.forward);
-
-		CrossProduct(testskeleton.joints[testskeleton.lowforwardjoints[1]].position-testskeleton.joints[testskeleton.lowforwardjoints[0]].position,testskeleton.joints[testskeleton.lowforwardjoints[2]].position-testskeleton.joints[testskeleton.lowforwardjoints[0]].position,&testskeleton.lowforward);
-		Normalise(&testskeleton.lowforward);
-
-		//Special forwards
-		testskeleton.specialforward[0]=testskeleton.forward;
-
-		testskeleton.specialforward[1]=testskeleton.joints[testskeleton.jointlabels[rightshoulder]].position+testskeleton.joints[testskeleton.jointlabels[rightwrist]].position;
-		testskeleton.specialforward[1]=testskeleton.joints[testskeleton.jointlabels[rightelbow]].position-testskeleton.specialforward[1]/2;
-		testskeleton.specialforward[1]+=testskeleton.forward*.2;
-		Normalise(&testskeleton.specialforward[1]);
-		testskeleton.specialforward[2]=testskeleton.joints[testskeleton.jointlabels[leftshoulder]].position+testskeleton.joints[testskeleton.jointlabels[leftwrist]].position;
-		testskeleton.specialforward[2]=testskeleton.joints[testskeleton.jointlabels[leftelbow]].position-testskeleton.specialforward[2]/2;
-		testskeleton.specialforward[2]+=testskeleton.forward*.2;
-		Normalise(&testskeleton.specialforward[2]);
-
-		testskeleton.specialforward[3]=testskeleton.joints[testskeleton.jointlabels[righthip]].position+testskeleton.joints[testskeleton.jointlabels[rightankle]].position;
-		testskeleton.specialforward[3]=testskeleton.specialforward[3]/2-testskeleton.joints[testskeleton.jointlabels[rightknee]].position;
-		testskeleton.specialforward[3]+=testskeleton.lowforward*.2;
-		Normalise(&testskeleton.specialforward[3]);
-		testskeleton.specialforward[4]=testskeleton.joints[testskeleton.jointlabels[lefthip]].position+testskeleton.joints[testskeleton.jointlabels[leftankle]].position;
-		testskeleton.specialforward[4]=testskeleton.specialforward[4]/2-testskeleton.joints[testskeleton.jointlabels[leftknee]].position;
-		testskeleton.specialforward[4]+=testskeleton.lowforward*.2;
-		Normalise(&testskeleton.specialforward[4]);
-
-		//Find joint rotations
-		for(int i=0;i<testskeleton.num_joints;i++){
-			if(testskeleton.joints[i].hasparent&&testskeleton.joints[i].visible)
-			{
-				testskeleton.FindRotationJoint(i);
-			}
-		}
-		for(int i=0;i<testskeleton.num_muscles;i++){
-			if(testskeleton.muscles[i].visible)
-			{
-				testskeleton.FindRotationMuscle(i);
-			}
-		}
-		for(int i=0;i<testskeleton.num_muscles;i++){
-			if(testskeleton.muscles[i].visible)
-			{
-				mrotate1[i][j]=testskeleton.muscles[i].rotate1;
-				mrotate2[i][j]=testskeleton.muscles[i].rotate2;
-				mrotate3[i][j]=testskeleton.muscles[i].rotate3;
-				if(j!=0&&mrotate3[i][j]>mrotate3[i][j-1]+180)mrotate3[i][j]-=360;
-				if(j!=0&&mrotate3[i][j]<mrotate3[i][j-1]-180)mrotate3[i][j]+=360;
-				if(j!=0&&mrotate2[i][j]>mrotate2[i][j-1]+180)mrotate2[i][j]-=360;
-				if(j!=0&&mrotate2[i][j]<mrotate2[i][j-1]-180)mrotate2[i][j]+=360;
-				if(j!=0&&mrotate1[i][j]>mrotate1[i][j-1]+180)mrotate1[i][j]-=360;
-				if(j!=0&&mrotate1[i][j]<mrotate1[i][j-1]-180)mrotate1[i][j]+=360;
-			}
-		}
-		for(int i=0;i<testskeleton.num_joints;i++){
-			if(testskeleton.joints[i].hasparent&&testskeleton.joints[i].visible)
-			{
-				rotate1[i][j]=testskeleton.joints[i].rotate1;
-				rotate2[i][j]=testskeleton.joints[i].rotate2;
-				rotate3[i][j]=testskeleton.joints[i].rotate3;
-				if(j!=0&&rotate3[i][j]>rotate3[i][j-1]+180)rotate3[i][j]-=360;
-				if(j!=0&&rotate3[i][j]<rotate3[i][j-1]-180)rotate3[i][j]+=360;
-				if(j!=0&&rotate2[i][j]>rotate2[i][j-1]+180)rotate2[i][j]-=360;
-				if(j!=0&&rotate2[i][j]<rotate2[i][j-1]-180)rotate2[i][j]+=360;
-				if(j!=0&&rotate1[i][j]>rotate1[i][j-1]+180)rotate1[i][j]-=360;
-				if(j!=0&&rotate1[i][j]<rotate1[i][j-1]-180)rotate1[i][j]+=360;
-			}
-		}
-	}
-
-	for(int k=0;k<2;k++)
-	for(int j=0;j<numframes;j++){
-		for(int i=0;i<testskeleton.num_muscles;i++){
-			if(testskeleton.muscles[i].visible)
-			{
-				if(j!=0&&mrotate3[i][j]>mrotate3[i][j-1]+180)mrotate3[i][j]-=360;
-				if(j!=0&&mrotate3[i][j]<mrotate3[i][j-1]-180)mrotate3[i][j]+=360;
-				if(j!=0&&mrotate2[i][j]>mrotate2[i][j-1]+180)mrotate2[i][j]-=360;
-				if(j!=0&&mrotate2[i][j]<mrotate2[i][j-1]-180)mrotate2[i][j]+=360;
-				if(j!=0&&mrotate1[i][j]>mrotate1[i][j-1]+180)mrotate1[i][j]-=360;
-				if(j!=0&&mrotate1[i][j]<mrotate1[i][j-1]-180)mrotate1[i][j]+=360;
-
-				if(j==0&&mrotate3[i][j]>mrotate3[i][numframes-1]+180)mrotate3[i][j]-=360;
-				if(j==0&&mrotate3[i][j]<mrotate3[i][numframes-1]-180)mrotate3[i][j]+=360;
-				if(j==0&&mrotate2[i][j]>mrotate2[i][numframes-1]+180)mrotate2[i][j]-=360;
-				if(j==0&&mrotate2[i][j]<mrotate2[i][numframes-1]-180)mrotate2[i][j]+=360;
-				if(j==0&&mrotate1[i][j]>mrotate1[i][numframes-1]+180)mrotate1[i][j]-=360;
-				if(j==0&&mrotate1[i][j]<mrotate1[i][numframes-1]-180)mrotate1[i][j]+=360;
-			}
-		}
-		for(int i=0;i<testskeleton.num_joints;i++){
-			if(testskeleton.joints[i].hasparent&&testskeleton.joints[i].visible)
-			{
-				if(j!=0&&rotate3[i][j]>rotate3[i][j-1]+180)rotate3[i][j]-=360;
-				if(j!=0&&rotate3[i][j]<rotate3[i][j-1]-180)rotate3[i][j]+=360;
-				if(j!=0&&rotate2[i][j]>rotate2[i][j-1]+180)rotate2[i][j]-=360;
-				if(j!=0&&rotate2[i][j]<rotate2[i][j-1]-180)rotate2[i][j]+=360;
-				if(j!=0&&rotate1[i][j]>rotate1[i][j-1]+180)rotate1[i][j]-=360;
-				if(j!=0&&rotate1[i][j]<rotate1[i][j-1]-180)rotate1[i][j]+=360;
-
-				if(j==0&&rotate3[i][j]>rotate3[i][numframes-1]+180)rotate3[i][j]-=360;
-				if(j==0&&rotate3[i][j]<rotate3[i][numframes-1]-180)rotate3[i][j]+=360;
-				if(j==0&&rotate2[i][j]>rotate2[i][numframes-1]+180)rotate2[i][j]-=360;
-				if(j==0&&rotate2[i][j]<rotate2[i][numframes-1]-180)rotate2[i][j]+=360;
-				if(j==0&&rotate1[i][j]>rotate1[i][numframes-1]+180)rotate1[i][j]-=360;
-				if(j==0&&rotate1[i][j]<rotate1[i][numframes-1]-180)rotate1[i][j]+=360;
-			}
-		}
-	}
-}
-
-void Animation::Load(char *fileName, float rotate)
-{
-	files.OpenFile(fileName);
-	if(files.sFile){
-		ReadInt(files.sFile, 1, &numframes);
-		for(int i=0;i<numframes;i++){
-			for(int j=0;j<max_joints;j++){
-				ReadXYZ(files.sFile, 1, &position[j][i]);
-				position[j][i]=DoRotation(position[j][i],0,rotate,0);
-			}
-			for(int j=0;j<max_joints;j++){
-				ReadFloat(files.sFile, 1, &twist[j][i]);
-			}
-			for(int j=0;j<max_joints;j++){
-				ReadBool(files.sFile, 1, &onground[j][i]);
-			}
-			ReadFloat(files.sFile, 1, &speed[i]);
-			ReadFloat(files.sFile, 1, &gunrotation[i]);
-		}
-		for(int i=0;i<numframes;i++){
-			for(int j=0;j<max_joints;j++){
-				ReadFloat(files.sFile, 1, &twist2[j][i]);
-			}
+	auto data = loadAnimation(name);
+	numframes = data.len;
+	for (size_t i = 0; i < numframes; ++i) {
+		for (size_t j = 0; j < max_joints; ++j) {
+			position[j][i].x = data.ptr[i].joints[j].x;
+			position[j][i].y = data.ptr[i].joints[j].y;
+			position[j][i].z = data.ptr[i].joints[j].z;
 		}
+		speed[i] = data.ptr[i].speed;
 	}
-	files.EndLoad();
+	free(data.ptr);
 
 	for(int j=0;j<numframes;j++){
 		for(int i=0;i<testskeleton.num_joints;i++){
diff --git a/src/Skeleton.h b/src/Skeleton.h
index d28494d..35bdb43 100644
--- a/src/Skeleton.h
+++ b/src/Skeleton.h
@@ -85,20 +85,15 @@ class Animation
 {
 	public:
 		Files files;
-		int numframes;
+		size_t numframes;
 		bool canbeoverridden;
 		bool ismodified[max_joints][max_frames];
-		XYZ  position[max_joints][max_frames];
-		float twist[max_joints][max_frames];
-		float twist2[max_joints][max_frames];
+		XYZ position[max_joints][max_frames];
 		float speed[max_frames];
-		float gunrotation[max_frames];
-		bool onground[max_joints][max_frames];
 		XYZ forward[max_frames];
 		float rotate1[max_joints][max_frames],rotate2[max_joints][max_frames],rotate3[max_joints][max_frames];
 		float mrotate1[max_joints][max_frames],mrotate2[max_joints][max_frames],mrotate3[max_joints][max_frames];
-		void Load(char *fileName);
-		void Load(char *fileName,float rotate);
+		void load(const char* name);
 };
 
 class Skeleton
diff --git a/src/misc.h b/src/misc.h
index efe575a..96b2307 100644
--- a/src/misc.h
+++ b/src/misc.h
@@ -2,31 +2,41 @@
 #define BLACKSHADES_MISC_H
 
 #include <stdbool.h>
+#include <stddef.h>
 
 #include <AL/al.h>
 #include <GL/gl.h>
 
+struct AnimationData {
+	struct {
+		struct { float x, y, z; } joints[20];
+		float speed;
+	} *ptr;
+	size_t len;
+};
+
 struct JointData {
-    signed char label;
-    float x, y, z;
-    float length;
-    unsigned char model;
-    bool visible;
-    bool lower;
-    signed char parent;
+	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;
+	float length, initlen, minlen, maxlen;
+	bool flag;
+	bool visible;
+	signed char parent1;
+	signed char parent2;
 };
 
 #ifdef __cplusplus
 extern "C" {
 #endif // __cplusplus
+	AnimationData loadAnimation(const char*);
 	void loadJoints(JointData*);
 	void loadMuscles(MuscleData*);
 	ALuint loadSound(const char*);
diff --git a/src/misc.zig b/src/misc.zig
index f9e0628..caa0319 100644
--- a/src/misc.zig
+++ b/src/misc.zig
@@ -23,8 +23,11 @@ usingnamespace @cImport({
     @cInclude("lodepng.h");
 });
 
+const Dir = std.fs.Dir;
 const al = @import("zeal");
+const allocPrint = std.fmt.allocPrint;
 const allocator = std.heap.c_allocator;
+const count = std.mem.count;
 const cwd = std.fs.cwd;
 const data_dir = @import("build_options").data_dir ++ [_]u8{ sep };
 const eql = std.mem.eql;
@@ -38,6 +41,64 @@ const span = std.mem.span;
 const std = @import("std");
 const tokenize = std.mem.tokenize;
 
+// Don't judge me, take care of me!
+const max_size = maxInt(usize);
+
+/// Read given file to heap, allocated by C allocator.
+fn readFile(dir: Dir, comptime fmt: []const u8, args: anytype) ![]const u8 {
+    const filename = try allocPrint(allocator, fmt, args);
+    defer allocator.free(filename);
+    return dir.readFileAlloc(allocator, filename, max_size);
+}
+
+const Frame = extern struct {
+    joints: [20]extern struct {
+        x: f32,
+        y: f32,
+        z: f32,
+    },
+    speed: f32,
+};
+
+export fn loadAnimation(name: [*:0]const u8) extern struct {
+    ptr: [*]Frame,
+    len: usize,
+} {
+    var dir = cwd().openDir(data_dir ++ "animations", .{}) catch unreachable;
+    defer dir.close();
+    const anim_file = readFile(dir, "{s}.tsv", .{ name }) catch unreachable;
+    defer allocator.free(anim_file);
+    const length = count(u8, anim_file, "\t") - 1;
+    const frames = allocator.alloc(Frame, length) catch unreachable;
+
+    var anim = tokenize(anim_file, "\n");
+    _ = anim.next().?; // ignore field names
+    var i = @as(usize, 0);
+    while (i < length) : (i += 1) {
+        var values = tokenize(anim.next().?, "\t");
+        const frame_file = readFile(dir, "frames{c}{s}{c}{s}.tsv", .{
+            sep, name, sep, values.next().?, // frames/$animation/$frame.tsv
+        }) catch unreachable;
+        defer allocator.free(frame_file);
+
+        var frame = tokenize(frame_file, "\n");
+        _ = frame.next().?; // ignore field names
+        var j = @as(usize, 0);
+        while (frame.next()) |position| {
+            var coordinates = tokenize(position, "\t");
+            frames[i].joints[j].x = parseFloat(f32, coordinates.next().?)
+                catch unreachable;
+            frames[i].joints[j].y = parseFloat(f32, coordinates.next().?)
+                catch unreachable;
+            frames[i].joints[j].z = parseFloat(f32, coordinates.next().?)
+                catch unreachable;
+            j += 1;
+        }
+        frames[i].speed = parseFloat(f32, values.next().?) catch unreachable;
+    }
+    return .{ .ptr = frames.ptr, .len = frames.len };
+}
+
 /// Parse boolean values.
 pub fn parseBool(s: []const u8) !bool {
     if (eql(u8, s, "false"))
@@ -138,8 +199,7 @@ fn check(errorString: fn (c_uint) callconv(.C) [*c]const u8,
 export fn loadTexture(filename: [*:0]const u8) GLuint {
     var dir = cwd().openDir(data_dir ++ "textures", .{}) catch unreachable;
     defer dir.close();
-    // Don't judge me, take care of me!
-    var file = dir.readFileAlloc(allocator, span(filename), maxInt(usize))
+    const file = dir.readFileAlloc(allocator, span(filename), max_size)
         catch unreachable;
     defer allocator.free(file);