#include <acknex.h>
var cutscene_editmode = 0;
var cutscene_playing = 0;
var cutscene_paused = 0;
var cutscene_time;
var cutscene_keyframe;
typedef struct Cue {
STRING* entname;
VECTOR* startpos;
VECTOR* endpos;
ANGLE* startang;
ANGLE* endang;
VECTOR* startscale;
VECTOR* endscale;
STRING* anim; //animation name- or NULL
var animloops;
var starttime;
var duration;
struct Cue* next; //used when the cue is in the linked list of active cues
struct Cue* prev;
} Cue;
typedef struct Keyframe {
var cuetime;
var actions_count;
Cue* actions[64];
} Keyframe;
Keyframe* scene;
Cue* active_cues[300];
var keyframe_count;
Cue* active_cues_head = NULL;
function newCue()
{
Cue* newcue = malloc(sizeof(Cue));
memset(newcue,0,sizeof(Cue));
return newcue;
}
function newKeyframe()
{
Keyframe* newkeyframe = malloc(sizeof(Keyframe));
memset(newkeyframe,0,sizeof(Keyframe));
return newkeyframe;
}
function killCue(Cue* c)
{
free(c);
}
function killKeyframe(Keyframe* k)
{
free(k);
}
function loadScene(STRING* filename)
{
str_cpy(delimit_str," ");
var filehandle = file_open_read(filename);
var flop = file_open_write("testt.txt");
var length = file_var_read(filehandle); //first number is number of keyframes to malloc
file_var_write(flop,length);
scene = malloc(length * sizeof(Keyframe));
var i;
for(i = 0; i < length; i += 1)
{
memcpy(scene[i],newKeyframe(),sizeof(Keyframe));
scene[i].cuetime = file_var_read(filehandle);
scene[i].actions_count = file_var_read(filehandle);
if(scene[i].actions_count > 0)
{
scene[i].actions = malloc(scene[i].actions_count * sizeof(Cue));
var k;
for(k = 0; i < scene[i].actions_count; i++)
{
scene[i].actions[k] = newCue();
scene[i].actions[k].entname = str_create("#20");
file_str_read(filehandle,scene[i].actions[k].entname);
scene[i].actions[k].startpos = vector(0,0,0);
scene[i].actions[k].endpos = vector(0,0,0);
scene[i].actions[k].startang = vector(0,0,0);
scene[i].actions[k].endang = vector(0,0,0);
scene[i].actions[k].startscale = vector(0,0,0);
scene[i].actions[k].endscale = vector(0,0,0);
scene[i].actions[k].startpos.x = file_var_read(filehandle);
scene[i].actions[k].startpos.y = file_var_read(filehandle);
scene[i].actions[k].startpos.z = file_var_read(filehandle);
scene[i].actions[k].endpos.x = file_var_read(filehandle);
scene[i].actions[k].endpos.y = file_var_read(filehandle);
scene[i].actions[k].endpos.z = file_var_read(filehandle);
scene[i].actions[k].startang.pan = file_var_read(filehandle);
scene[i].actions[k].startang.tilt = file_var_read(filehandle);
scene[i].actions[k].startang.roll = file_var_read(filehandle);
scene[i].actions[k].endang.pan = file_var_read(filehandle);
scene[i].actions[k].endang.tilt = file_var_read(filehandle);
scene[i].actions[k].endang.roll = file_var_read(filehandle);
scene[i].actions[k].startscale.x = file_var_read(filehandle);
scene[i].actions[k].startscale.y = file_var_read(filehandle);
scene[i].actions[k].startscale.z = file_var_read(filehandle);
scene[i].actions[k].endscale.x = file_var_read(filehandle);
scene[i].actions[k].endscale.y = file_var_read(filehandle);
scene[i].actions[k].endscale.z = file_var_read(filehandle);
file_str_read(filehandle,scene[i].actions[k].anim);
scene[i].actions[k].animloops = file_var_read(filehandle);
scene[i].actions[k].starttime = scene[i].cuetime;
scene[i].actions[k].duration = file_var_read(filehandle);
scene[i].actions[k].next = NULL;
scene[i].actions[k].prev = NULL;
}
}
}
file_close(filehandle);
file_close(flop);
}
function playScene()
{
cutscene_time = 0;
cutscene_keyframe = 0;
cutscene_playing = 1;
var flog = file_open_write("scenelog.txt");
while(cutscene_playing == 1)
{
while(cutscene_paused) wait(1);
if(scene[cutscene_keyframe].cuetime == 0)
{
cutscene_playing = 0;
}
else{
if(cutscene_time >= scene[cutscene_keyframe].cuetime)
{
Cue* reader = active_cues_head;
if(reader != NULL)
{
while(reader != NULL && reader.next != NULL)
{
reader = reader.next;
}
}
var i;
for(i = 0; i < scene[cutscene_keyframe].actions_count; i += 1)
{
Cue* thiscue = newCue();
memcpy(thiscue,scene[cutscene_keyframe].actions[i],sizeof(Cue)); //ERROR HERE
if(reader == NULL)
{
active_cues_head = thiscue;
reader = thiscue;
}
else
{
reader.next = thiscue;
reader.next.prev = reader;
reader = reader.next;
}
}
cutscene_keyframe += 1;
}
Cue* reader = active_cues_head;
while(reader != NULL)
{
if((reader.starttime + reader.duration) < cutscene_time)
{
file_var_write(flog,reader.starttime);
file_var_write(flog,reader.duration);
Cue* killme = reader;
if(reader == active_cues_head && reader.next != NULL)
{
reader.next.prev = NULL;
active_cues_head = reader.next;
reader = reader.next;
}
else if(reader == active_cues_head && reader.next == NULL)
{
active_cues_head = NULL;
reader = NULL;
}
else if(reader.next == NULL)
{
reader.prev.next = NULL;
reader = NULL;
}
else
{
reader.prev.next = reader.next;
reader.next.prev = reader.prev;
reader = reader.next;
}
free(killme);
}
else
{
if(reader.entname == NULL)
{
var factor = (cutscene_time - reader.starttime) / reader.duration;
vec_lerp(camera.x,reader.startpos,reader.endpos,factor);
vec_lerp(camera.pan,reader.startang,reader.endang,factor);
}
else
{
ENTITY* actor = ent_for_name(reader.entname);
var factor = (cutscene_time - reader.starttime) / reader.duration;
if(vec_dist(reader.startpos,reader.endpos) != 0) vec_lerp(actor.x,reader.startpos,reader.endpos,factor);
if(vec_dist(reader.startang,reader.endang) != 0) vec_lerp(actor.pan,reader.startang,reader.endang,factor);
if(vec_dist(reader.startscale,reader.endscale) != 0) vec_lerp(actor.scale_x,reader.startscale,reader.endscale,factor);
if(reader.anim != NULL) ent_animate(actor,reader.anim,(factor * 100 * reader.animloops) % 100,ANM_CYCLE);
}
reader = reader.next;
}
}
cutscene_time += time_frame;
}
wait(1);
}
file_close(flog);
}
function pauseScene()
{
cutscene_paused = 1;
}
function unpauseScene()
{
cutscene_paused = 0;
}
function freeScene()
{
free(scene);
}
action actor()
{
wait(1);
}