port from perforce
This commit is contained in:
120
hgplus/nordlicht2014-intro/3rdparty/modified-rocket/base.h
vendored
Normal file
120
hgplus/nordlicht2014-intro/3rdparty/modified-rocket/base.h
vendored
Normal file
@@ -0,0 +1,120 @@
|
||||
/* Copyright (C) 2007-2010 Erik Faye-Lund and Egbert Teeselink
|
||||
* For conditions of distribution and use, see copyright notice in COPYING
|
||||
*/
|
||||
|
||||
#ifndef SYNC_BASE_H
|
||||
#define SYNC_BASE_H
|
||||
|
||||
/* configure inline keyword */
|
||||
#if (!defined(__STDC_VERSION__) || (__STDC_VERSION__ < 199901L)) && !defined(__cplusplus)
|
||||
#if defined(_MSC_VER) || defined(__GNUC__) || defined(__SASC)
|
||||
#define inline __inline
|
||||
#else
|
||||
/* compiler does not support inline, make function static instead */
|
||||
#define inline static
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* configure lacking CRT features */
|
||||
#ifdef _MSC_VER
|
||||
/* int is 32-bit for both x86 and x64 */
|
||||
typedef unsigned int uint32_t;
|
||||
#define UINT32_MAX UINT_MAX
|
||||
#elif defined(__GNUC__)
|
||||
#include <stdint.h>
|
||||
#elif defined(M68000)
|
||||
typedef unsigned int uint32_t;
|
||||
#endif
|
||||
|
||||
/* configure socket-stack */
|
||||
#ifdef _WIN32
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#define NOMINMAX
|
||||
#include <winsock2.h>
|
||||
#include <windows.h>
|
||||
#include <limits.h>
|
||||
#elif defined(USE_AMITCP)
|
||||
#include <sys/socket.h>
|
||||
#include <proto/exec.h>
|
||||
#include <proto/socket.h>
|
||||
#include <netdb.h>
|
||||
#define SOCKET int
|
||||
#define INVALID_SOCKET -1
|
||||
#define select(n,r,w,e,t) WaitSelect(n,r,w,e,t,0)
|
||||
#define closesocket(x) CloseSocket(x)
|
||||
#else
|
||||
#include <sys/socket.h>
|
||||
#include <sys/time.h>
|
||||
#include <netinet/in.h>
|
||||
#include <netdb.h>
|
||||
#include <unistd.h>
|
||||
#define SOCKET int
|
||||
#define INVALID_SOCKET -1
|
||||
#define closesocket(x) close(x)
|
||||
#endif
|
||||
|
||||
#define CLIENT_GREET "hello, synctracker!"
|
||||
#define SERVER_GREET "hello, demo!"
|
||||
|
||||
enum {
|
||||
SET_KEY = 0,
|
||||
DELETE_KEY = 1,
|
||||
GET_TRACK = 2,
|
||||
SET_ROW = 3,
|
||||
PAUSE = 4,
|
||||
SAVE_TRACKS = 5
|
||||
};
|
||||
|
||||
static inline int socket_poll(SOCKET socket)
|
||||
{
|
||||
struct timeval to = { 0, 0 };
|
||||
fd_set fds;
|
||||
|
||||
FD_ZERO(&fds);
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable: 4127)
|
||||
#endif
|
||||
FD_SET(socket, &fds);
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
return select((int)socket + 1, &fds, NULL, NULL, &to) > 0;
|
||||
}
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
static inline int xsend(SOCKET s, const void *buf, size_t len, int flags)
|
||||
{
|
||||
#ifdef WIN32
|
||||
assert(len <= INT_MAX);
|
||||
return send(s, (const char *)buf, (int)len, flags) != (int)len;
|
||||
#else
|
||||
return send(s, (const char *)buf, len, flags) != len;
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline int xrecv(SOCKET s, void *buf, size_t len, int flags)
|
||||
{
|
||||
#ifdef WIN32
|
||||
assert(len <= INT_MAX);
|
||||
return recv(s, (char *)buf, (int)len, flags) != (int)len;
|
||||
#else
|
||||
return recv(s, (char *)buf, len, flags) != len;
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef NEED_STRDUP
|
||||
static inline char *rocket_strdup(const char *str)
|
||||
{
|
||||
char *ret = malloc(strlen(str) + 1);
|
||||
if (ret)
|
||||
strcpy(ret, str);
|
||||
return ret;
|
||||
}
|
||||
#define strdup rocket_strdup
|
||||
#endif
|
||||
|
||||
#endif /* SYNC_BASE_H */
|
||||
33
hgplus/nordlicht2014-intro/3rdparty/modified-rocket/data.c
vendored
Normal file
33
hgplus/nordlicht2014-intro/3rdparty/modified-rocket/data.c
vendored
Normal file
@@ -0,0 +1,33 @@
|
||||
/* Copyright (C) 2007-2008 Erik Faye-Lund and Egbert Teeselink
|
||||
* For conditions of distribution and use, see copyright notice in COPYING
|
||||
*/
|
||||
|
||||
#include "data.h"
|
||||
|
||||
void sync_data_deinit(struct sync_data *d)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < (int)d->num_tracks; ++i) {
|
||||
free(d->tracks[i]->name);
|
||||
free(d->tracks[i]->keys);
|
||||
free(d->tracks[i]);
|
||||
}
|
||||
free(d->tracks);
|
||||
}
|
||||
|
||||
int sync_create_track(struct sync_data *d, const char *name)
|
||||
{
|
||||
struct sync_track *t;
|
||||
assert(sync_find_track(d, name) < 0);
|
||||
|
||||
t = malloc(sizeof(*t));
|
||||
t->name = strdup(name);
|
||||
t->keys = NULL;
|
||||
t->num_keys = 0;
|
||||
|
||||
d->num_tracks++;
|
||||
d->tracks = realloc(d->tracks, sizeof(d->tracks[0]) * d->num_tracks);
|
||||
d->tracks[d->num_tracks - 1] = t;
|
||||
|
||||
return (int)d->num_tracks - 1;
|
||||
}
|
||||
28
hgplus/nordlicht2014-intro/3rdparty/modified-rocket/data.h
vendored
Normal file
28
hgplus/nordlicht2014-intro/3rdparty/modified-rocket/data.h
vendored
Normal file
@@ -0,0 +1,28 @@
|
||||
/* Copyright (C) 2007-2010 Erik Faye-Lund and Egbert Teeselink
|
||||
* For conditions of distribution and use, see copyright notice in COPYING
|
||||
*/
|
||||
|
||||
#ifndef SYNC_DATA_H
|
||||
#define SYNC_DATA_H
|
||||
|
||||
#include "track.h"
|
||||
|
||||
struct sync_data {
|
||||
struct sync_track **tracks;
|
||||
size_t num_tracks;
|
||||
};
|
||||
|
||||
static inline int sync_find_track(const struct sync_data *data,
|
||||
const char *name)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < (int)data->num_tracks; ++i)
|
||||
if (!strcmp(name, data->tracks[i]->name))
|
||||
return i;
|
||||
return -1; /* not found */
|
||||
}
|
||||
|
||||
void sync_data_deinit(struct sync_data *);
|
||||
int sync_create_track(struct sync_data *, const char *);
|
||||
|
||||
#endif /* SYNC_DATA_H */
|
||||
359
hgplus/nordlicht2014-intro/3rdparty/modified-rocket/device.c
vendored
Normal file
359
hgplus/nordlicht2014-intro/3rdparty/modified-rocket/device.c
vendored
Normal file
@@ -0,0 +1,359 @@
|
||||
/* Copyright (C) 2007-2008 Erik Faye-Lund and Egbert Teeselink
|
||||
* For conditions of distribution and use, see copyright notice in COPYING
|
||||
*/
|
||||
|
||||
#include "device.h"
|
||||
#include "sync.h"
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
|
||||
static const char *sync_track_path(const char *base, const char *name)
|
||||
{
|
||||
static char temp[FILENAME_MAX];
|
||||
strncpy(temp, base, sizeof(temp) - 1);
|
||||
temp[sizeof(temp) - 1] = '\0';
|
||||
strncat(temp, "_", sizeof(temp) - 1);
|
||||
strncat(temp, name, sizeof(temp) - 1);
|
||||
strncat(temp, ".track", sizeof(temp) - 1);
|
||||
return temp;
|
||||
}
|
||||
|
||||
#ifndef SYNC_PLAYER
|
||||
|
||||
#ifdef USE_AMITCP
|
||||
static struct Library *socket_base = NULL;
|
||||
#endif
|
||||
|
||||
static SOCKET server_connect(const char *host, unsigned short nport)
|
||||
{
|
||||
struct hostent *he;
|
||||
struct sockaddr_in sa;
|
||||
char greet[128], **ap;
|
||||
SOCKET sock = INVALID_SOCKET;
|
||||
|
||||
#ifdef WIN32
|
||||
static int need_init = 1;
|
||||
if (need_init) {
|
||||
WSADATA wsa;
|
||||
if (WSAStartup(MAKEWORD(2, 0), &wsa))
|
||||
return INVALID_SOCKET;
|
||||
need_init = 0;
|
||||
}
|
||||
#elif defined(USE_AMITCP)
|
||||
if (!socket_base) {
|
||||
socket_base = OpenLibrary("bsdsocket.library", 4);
|
||||
if (!socket_base)
|
||||
return INVALID_SOCKET;
|
||||
}
|
||||
#endif
|
||||
|
||||
he = gethostbyname(host);
|
||||
if (!he)
|
||||
return INVALID_SOCKET;
|
||||
|
||||
for (ap = he->h_addr_list; *ap; ++ap) {
|
||||
sa.sin_family = he->h_addrtype;
|
||||
sa.sin_port = htons(nport);
|
||||
memcpy(&sa.sin_addr, *ap, he->h_length);
|
||||
|
||||
sock = socket(he->h_addrtype, SOCK_STREAM, 0);
|
||||
if (sock == INVALID_SOCKET)
|
||||
continue;
|
||||
|
||||
if (connect(sock, (struct sockaddr *)&sa, sizeof(sa)) >= 0)
|
||||
break;
|
||||
|
||||
closesocket(sock);
|
||||
sock = INVALID_SOCKET;
|
||||
}
|
||||
|
||||
if (sock == INVALID_SOCKET)
|
||||
return INVALID_SOCKET;
|
||||
|
||||
if (xsend(sock, CLIENT_GREET, strlen(CLIENT_GREET), 0) ||
|
||||
xrecv(sock, greet, strlen(SERVER_GREET), 0))
|
||||
return INVALID_SOCKET;
|
||||
|
||||
if (!strncmp(SERVER_GREET, greet, strlen(SERVER_GREET)))
|
||||
return sock;
|
||||
|
||||
closesocket(sock);
|
||||
return INVALID_SOCKET;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
void sync_set_io_cb(struct sync_device *d, struct sync_io_cb *cb)
|
||||
{
|
||||
d->io_cb.open = cb->open;
|
||||
d->io_cb.read = cb->read;
|
||||
d->io_cb.close = cb->close;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
struct sync_device *sync_create_device(const char *base)
|
||||
{
|
||||
struct sync_device *d = malloc(sizeof(*d));
|
||||
if (!d)
|
||||
return NULL;
|
||||
|
||||
d->base = strdup(base);
|
||||
if (!d->base) {
|
||||
free(d);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
d->data.tracks = NULL;
|
||||
d->data.num_tracks = 0;
|
||||
|
||||
#ifndef SYNC_PLAYER
|
||||
d->row = -1;
|
||||
d->sock = INVALID_SOCKET;
|
||||
#else
|
||||
d->io_cb.open = fopen;
|
||||
d->io_cb.read = fread;
|
||||
d->io_cb.close = fclose;
|
||||
#endif
|
||||
|
||||
return d;
|
||||
}
|
||||
|
||||
void sync_destroy_device(struct sync_device *d)
|
||||
{
|
||||
free(d->base);
|
||||
sync_data_deinit(&d->data);
|
||||
free(d);
|
||||
|
||||
#if defined(USE_AMITCP) && !defined(SYNC_PLAYER)
|
||||
if (socket_base) {
|
||||
CloseLibrary(socket_base);
|
||||
socket_base = NULL;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef SYNC_PLAYER
|
||||
|
||||
static int get_track_data(struct sync_device *d, struct sync_track *t)
|
||||
{
|
||||
int i;
|
||||
void *fp = d->io_cb.open(sync_track_path(d->base, t->name), "rb");
|
||||
if (!fp)
|
||||
return -1;
|
||||
|
||||
d->io_cb.read(&t->num_keys, sizeof(size_t), 1, fp);
|
||||
t->keys = malloc(sizeof(struct track_key) * t->num_keys);
|
||||
if (!t->keys)
|
||||
return -1;
|
||||
|
||||
for (i = 0; i < (int)t->num_keys; ++i) {
|
||||
struct track_key *key = t->keys + i;
|
||||
char type;
|
||||
d->io_cb.read(&key->row, sizeof(int), 1, fp);
|
||||
d->io_cb.read(&key->value, sizeof(float), 1, fp);
|
||||
d->io_cb.read(&type, sizeof(char), 1, fp);
|
||||
key->type = (enum key_type)type;
|
||||
}
|
||||
|
||||
d->io_cb.close(fp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
static int save_track(const struct sync_track *t, const char *path)
|
||||
{
|
||||
int i;
|
||||
FILE *fp = fopen(path, "wb");
|
||||
if (!fp)
|
||||
return -1;
|
||||
|
||||
fwrite(&t->num_keys, sizeof(size_t), 1, fp);
|
||||
for (i = 0; i < (int)t->num_keys; ++i) {
|
||||
char type = (char)t->keys[i].type;
|
||||
fwrite(&t->keys[i].row, sizeof(int), 1, fp);
|
||||
fwrite(&t->keys[i].value, sizeof(float), 1, fp);
|
||||
fwrite(&type, sizeof(char), 1, fp);
|
||||
}
|
||||
|
||||
fclose(fp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void sync_save_tracks(const struct sync_device *d)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < (int)d->data.num_tracks; ++i) {
|
||||
const struct sync_track *t = d->data.tracks[i];
|
||||
save_track(t, sync_track_path(d->base, t->name));
|
||||
}
|
||||
}
|
||||
|
||||
static int get_track_data(struct sync_device *d, struct sync_track *t)
|
||||
{
|
||||
unsigned char cmd = GET_TRACK;
|
||||
uint32_t name_len;
|
||||
|
||||
assert(strlen(t->name) <= UINT32_MAX);
|
||||
name_len = htonl((uint32_t)strlen(t->name));
|
||||
|
||||
/* send request data */
|
||||
if (xsend(d->sock, (char *)&cmd, 1, 0) ||
|
||||
xsend(d->sock, (char *)&name_len, sizeof(name_len), 0) ||
|
||||
xsend(d->sock, t->name, (int)strlen(t->name), 0))
|
||||
{
|
||||
closesocket(d->sock);
|
||||
d->sock = INVALID_SOCKET;
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int handle_set_key_cmd(SOCKET sock, struct sync_data *data)
|
||||
{
|
||||
uint32_t track, row;
|
||||
union {
|
||||
float f;
|
||||
uint32_t i;
|
||||
} v;
|
||||
struct track_key key;
|
||||
unsigned char type;
|
||||
|
||||
if (xrecv(sock, (char *)&track, sizeof(track), 0) ||
|
||||
xrecv(sock, (char *)&row, sizeof(row), 0) ||
|
||||
xrecv(sock, (char *)&v.i, sizeof(v.i), 0) ||
|
||||
xrecv(sock, (char *)&type, 1, 0))
|
||||
return -1;
|
||||
|
||||
track = ntohl(track);
|
||||
v.i = ntohl(v.i);
|
||||
|
||||
key.row = ntohl(row);
|
||||
key.value = v.f;
|
||||
|
||||
assert(type < KEY_TYPE_COUNT);
|
||||
assert(track < data->num_tracks);
|
||||
key.type = (enum key_type)type;
|
||||
return sync_set_key(data->tracks[track], &key);
|
||||
}
|
||||
|
||||
static int handle_del_key_cmd(SOCKET sock, struct sync_data *data)
|
||||
{
|
||||
uint32_t track, row;
|
||||
|
||||
if (xrecv(sock, (char *)&track, sizeof(track), 0) ||
|
||||
xrecv(sock, (char *)&row, sizeof(row), 0))
|
||||
return -1;
|
||||
|
||||
track = ntohl(track);
|
||||
row = ntohl(row);
|
||||
|
||||
assert(track < data->num_tracks);
|
||||
return sync_del_key(data->tracks[track], row);
|
||||
}
|
||||
|
||||
int sync_connect(struct sync_device *d, const char *host, unsigned short port)
|
||||
{
|
||||
int i;
|
||||
if (d->sock != INVALID_SOCKET)
|
||||
closesocket(d->sock);
|
||||
|
||||
d->sock = server_connect(host, port);
|
||||
if (d->sock == INVALID_SOCKET)
|
||||
return -1;
|
||||
|
||||
for (i = 0; i < (int)d->data.num_tracks; ++i) {
|
||||
free(d->data.tracks[i]->keys);
|
||||
d->data.tracks[i]->keys = NULL;
|
||||
d->data.tracks[i]->num_keys = 0;
|
||||
}
|
||||
|
||||
for (i = 0; i < (int)d->data.num_tracks; ++i) {
|
||||
if (get_track_data(d, d->data.tracks[i])) {
|
||||
closesocket(d->sock);
|
||||
d->sock = INVALID_SOCKET;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sync_update(struct sync_device *d, int row, struct sync_cb *cb,
|
||||
void *cb_param)
|
||||
{
|
||||
if (d->sock == INVALID_SOCKET)
|
||||
return -1;
|
||||
|
||||
/* look for new commands */
|
||||
while (socket_poll(d->sock)) {
|
||||
unsigned char cmd = 0, flag;
|
||||
uint32_t row;
|
||||
if (xrecv(d->sock, (char *)&cmd, 1, 0))
|
||||
goto sockerr;
|
||||
|
||||
switch (cmd) {
|
||||
case SET_KEY:
|
||||
if (handle_set_key_cmd(d->sock, &d->data))
|
||||
goto sockerr;
|
||||
break;
|
||||
case DELETE_KEY:
|
||||
if (handle_del_key_cmd(d->sock, &d->data))
|
||||
goto sockerr;
|
||||
break;
|
||||
case SET_ROW:
|
||||
if (xrecv(d->sock, (char *)&row, sizeof(row), 0))
|
||||
goto sockerr;
|
||||
if (cb && cb->set_row)
|
||||
cb->set_row(cb_param, ntohl(row));
|
||||
break;
|
||||
case PAUSE:
|
||||
if (xrecv(d->sock, (char *)&flag, 1, 0))
|
||||
goto sockerr;
|
||||
if (cb && cb->pause)
|
||||
cb->pause(cb_param, flag);
|
||||
break;
|
||||
case SAVE_TRACKS:
|
||||
sync_save_tracks(d);
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "unknown cmd: %02x\n", cmd);
|
||||
goto sockerr;
|
||||
}
|
||||
}
|
||||
|
||||
if (cb && cb->is_playing && cb->is_playing(cb_param)) {
|
||||
if (d->row != row && d->sock != INVALID_SOCKET) {
|
||||
unsigned char cmd = SET_ROW;
|
||||
uint32_t nrow = htonl(row);
|
||||
if (xsend(d->sock, (char*)&cmd, 1, 0) ||
|
||||
xsend(d->sock, (char*)&nrow, sizeof(nrow), 0))
|
||||
goto sockerr;
|
||||
d->row = row;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
|
||||
sockerr:
|
||||
closesocket(d->sock);
|
||||
d->sock = INVALID_SOCKET;
|
||||
return -1;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
const struct sync_track *sync_get_track(struct sync_device *d,
|
||||
const char *name)
|
||||
{
|
||||
struct sync_track *t;
|
||||
int idx = sync_find_track(&d->data, name);
|
||||
if (idx >= 0)
|
||||
return d->data.tracks[idx];
|
||||
|
||||
idx = sync_create_track(&d->data, name);
|
||||
t = d->data.tracks[idx];
|
||||
|
||||
get_track_data(d, t);
|
||||
return t;
|
||||
}
|
||||
23
hgplus/nordlicht2014-intro/3rdparty/modified-rocket/device.h
vendored
Normal file
23
hgplus/nordlicht2014-intro/3rdparty/modified-rocket/device.h
vendored
Normal file
@@ -0,0 +1,23 @@
|
||||
/* Copyright (C) 2007-2008 Erik Faye-Lund and Egbert Teeselink
|
||||
* For conditions of distribution and use, see copyright notice in COPYING
|
||||
*/
|
||||
|
||||
#ifndef SYNC_DEVICE_H
|
||||
#define SYNC_DEVICE_H
|
||||
|
||||
#include "data.h"
|
||||
#include "sync.h"
|
||||
|
||||
struct sync_device {
|
||||
char *base;
|
||||
struct sync_data data;
|
||||
|
||||
#ifndef SYNC_PLAYER
|
||||
int row;
|
||||
SOCKET sock;
|
||||
#else
|
||||
struct sync_io_cb io_cb;
|
||||
#endif
|
||||
};
|
||||
|
||||
#endif /* SYNC_DEVICE_H */
|
||||
44
hgplus/nordlicht2014-intro/3rdparty/modified-rocket/sync.h
vendored
Normal file
44
hgplus/nordlicht2014-intro/3rdparty/modified-rocket/sync.h
vendored
Normal file
@@ -0,0 +1,44 @@
|
||||
/* Copyright (C) 2010 Erik Faye-Lund and Egbert Teeselink
|
||||
* For conditions of distribution and use, see copyright notice in COPYING
|
||||
*/
|
||||
|
||||
#ifndef SYNC_H
|
||||
#define SYNC_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct sync_device;
|
||||
struct sync_track;
|
||||
|
||||
struct sync_device *sync_create_device(const char *);
|
||||
void sync_destroy_device(struct sync_device *);
|
||||
|
||||
#ifndef SYNC_PLAYER
|
||||
struct sync_cb {
|
||||
void (*pause)(void *, int);
|
||||
void (*set_row)(void *, int);
|
||||
int (*is_playing)(void *);
|
||||
};
|
||||
#define SYNC_DEFAULT_PORT 1338
|
||||
int sync_connect(struct sync_device *, const char *, unsigned short);
|
||||
int sync_update(struct sync_device *, int, struct sync_cb *, void *);
|
||||
void sync_save_tracks(const struct sync_device *);
|
||||
#else /* defined(SYNC_PLAYER) */
|
||||
struct sync_io_cb {
|
||||
void *(*open)(const char *filename, const char *mode);
|
||||
size_t (*read)(void *ptr, size_t size, size_t nitems, void *stream);
|
||||
int (*close)(void *stream);
|
||||
};
|
||||
void sync_set_io_cb(struct sync_device *d, struct sync_io_cb *cb);
|
||||
#endif /* defined(SYNC_PLAYER) */
|
||||
|
||||
const struct sync_track *sync_get_track(struct sync_device *, const char *);
|
||||
double sync_get_val(const struct sync_track *, double);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* !defined(SYNC_H) */
|
||||
128
hgplus/nordlicht2014-intro/3rdparty/modified-rocket/track.c
vendored
Normal file
128
hgplus/nordlicht2014-intro/3rdparty/modified-rocket/track.c
vendored
Normal file
@@ -0,0 +1,128 @@
|
||||
/* Copyright (C) 2010 Erik Faye-Lund and Egbert Teeselink
|
||||
* For conditions of distribution and use, see copyright notice in COPYING
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
#include <math.h>
|
||||
#ifndef M_PI
|
||||
#define M_PI 3.141926
|
||||
#endif
|
||||
|
||||
#include "sync.h"
|
||||
#include "track.h"
|
||||
#include "base.h"
|
||||
|
||||
static double key_linear(const struct track_key k[2], double row)
|
||||
{
|
||||
double t = (row - k[0].row) / (k[1].row - k[0].row);
|
||||
return k[0].value + (k[1].value - k[0].value) * t;
|
||||
}
|
||||
|
||||
static double key_smooth(const struct track_key k[2], double row)
|
||||
{
|
||||
double t = (row - k[0].row) / (k[1].row - k[0].row);
|
||||
t = t * t * (3 - 2 * t);
|
||||
return k[0].value + (k[1].value - k[0].value) * t;
|
||||
}
|
||||
|
||||
static double key_ramp(const struct track_key k[2], double row)
|
||||
{
|
||||
double t = (row - k[0].row) / (k[1].row - k[0].row);
|
||||
t = pow(t, 2.0);
|
||||
return k[0].value + (k[1].value - k[0].value) * t;
|
||||
}
|
||||
|
||||
double sync_get_val(const struct sync_track *t, double row)
|
||||
{
|
||||
int idx, irow;
|
||||
|
||||
/* If we have no keys at all, return a constant 0 */
|
||||
if (!t->num_keys)
|
||||
return 0.0f;
|
||||
|
||||
irow = (int)floor(row);
|
||||
idx = key_idx_floor(t, irow);
|
||||
|
||||
/* at the edges, return the first/last value */
|
||||
if (idx < 0)
|
||||
return t->keys[0].value;
|
||||
if (idx > (int)t->num_keys - 2)
|
||||
return t->keys[t->num_keys - 1].value;
|
||||
|
||||
/* interpolate according to key-type */
|
||||
switch (t->keys[idx].type) {
|
||||
case KEY_STEP:
|
||||
return t->keys[idx].value;
|
||||
case KEY_LINEAR:
|
||||
return key_linear(t->keys + idx, row);
|
||||
case KEY_SMOOTH:
|
||||
return key_smooth(t->keys + idx, row);
|
||||
case KEY_RAMP:
|
||||
return key_ramp(t->keys + idx, row);
|
||||
default:
|
||||
assert(0);
|
||||
return 0.0f;
|
||||
}
|
||||
}
|
||||
|
||||
int sync_find_key(const struct sync_track *t, int row)
|
||||
{
|
||||
int lo = 0, hi = t->num_keys;
|
||||
|
||||
/* binary search, t->keys is sorted by row */
|
||||
while (lo < hi) {
|
||||
int mi = (lo + hi) / 2;
|
||||
assert(mi != hi);
|
||||
|
||||
if (t->keys[mi].row < row)
|
||||
lo = mi + 1;
|
||||
else if (t->keys[mi].row > row)
|
||||
hi = mi;
|
||||
else
|
||||
return mi; /* exact hit */
|
||||
}
|
||||
assert(lo == hi);
|
||||
|
||||
/* return first key after row, negated and biased (to allow -0) */
|
||||
return -lo - 1;
|
||||
}
|
||||
|
||||
#ifndef SYNC_PLAYER
|
||||
int sync_set_key(struct sync_track *t, const struct track_key *k)
|
||||
{
|
||||
int idx = sync_find_key(t, k->row);
|
||||
if (idx < 0) {
|
||||
/* no exact hit, we need to allocate a new key */
|
||||
void *tmp;
|
||||
idx = -idx - 1;
|
||||
tmp = realloc(t->keys, sizeof(struct track_key) *
|
||||
(t->num_keys + 1));
|
||||
if (!tmp)
|
||||
return -1;
|
||||
t->num_keys++;
|
||||
t->keys = tmp;
|
||||
memmove(t->keys + idx + 1, t->keys + idx,
|
||||
sizeof(struct track_key) * (t->num_keys - idx - 1));
|
||||
}
|
||||
t->keys[idx] = *k;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sync_del_key(struct sync_track *t, int pos)
|
||||
{
|
||||
void *tmp;
|
||||
int idx = sync_find_key(t, pos);
|
||||
assert(idx >= 0);
|
||||
memmove(t->keys + idx, t->keys + idx + 1,
|
||||
sizeof(struct track_key) * (t->num_keys - idx - 1));
|
||||
assert(t->keys);
|
||||
tmp = realloc(t->keys, sizeof(struct track_key) *
|
||||
(t->num_keys - 1));
|
||||
if (t->num_keys != 1 && !tmp)
|
||||
return -1;
|
||||
t->num_keys--;
|
||||
t->keys = tmp;
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
51
hgplus/nordlicht2014-intro/3rdparty/modified-rocket/track.h
vendored
Normal file
51
hgplus/nordlicht2014-intro/3rdparty/modified-rocket/track.h
vendored
Normal file
@@ -0,0 +1,51 @@
|
||||
/* Copyright (C) 2007-2010 Erik Faye-Lund and Egbert Teeselink
|
||||
* For conditions of distribution and use, see copyright notice in COPYING
|
||||
*/
|
||||
|
||||
#ifndef SYNC_TRACK_H
|
||||
#define SYNC_TRACK_H
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include "base.h"
|
||||
|
||||
enum key_type {
|
||||
KEY_STEP, /* stay constant */
|
||||
KEY_LINEAR, /* lerp to the next value */
|
||||
KEY_SMOOTH, /* smooth curve to the next value */
|
||||
KEY_RAMP,
|
||||
KEY_TYPE_COUNT
|
||||
};
|
||||
|
||||
struct track_key {
|
||||
int row;
|
||||
float value;
|
||||
enum key_type type;
|
||||
};
|
||||
|
||||
struct sync_track {
|
||||
char *name;
|
||||
struct track_key *keys;
|
||||
int num_keys;
|
||||
};
|
||||
|
||||
int sync_find_key(const struct sync_track *, int);
|
||||
static inline int key_idx_floor(const struct sync_track *t, int row)
|
||||
{
|
||||
int idx = sync_find_key(t, row);
|
||||
if (idx < 0)
|
||||
idx = -idx - 2;
|
||||
return idx;
|
||||
}
|
||||
|
||||
#ifndef SYNC_PLAYER
|
||||
int sync_set_key(struct sync_track *, const struct track_key *);
|
||||
int sync_del_key(struct sync_track *, int);
|
||||
static inline int is_key_frame(const struct sync_track *t, int row)
|
||||
{
|
||||
return sync_find_key(t, row) >= 0;
|
||||
}
|
||||
|
||||
#endif /* !defined(SYNC_PLAYER) */
|
||||
|
||||
#endif /* SYNC_TRACK_H */
|
||||
Reference in New Issue
Block a user