first and last commit
2
.gitignore
vendored
Normal file
|
@ -0,0 +1,2 @@
|
|||
/skcblitz
|
||||
/skc.cfg
|
207
alsasnd.h
Normal file
|
@ -0,0 +1,207 @@
|
|||
|
||||
#define SND_MSGUNDER
|
||||
|
||||
typedef struct {
|
||||
snd_pcm_t *handle;
|
||||
void *buffer;
|
||||
int *conv;
|
||||
uint samplerate;
|
||||
uint blocksize;
|
||||
uint channels;
|
||||
uint width;
|
||||
uint smppos;
|
||||
uint devbufsize;
|
||||
#ifdef SND_MSGUNDER
|
||||
uint underruns;
|
||||
uint lastunder;
|
||||
uint pushed;
|
||||
uint pad;
|
||||
#else
|
||||
uint pad[4];
|
||||
#endif
|
||||
} aud_handle;
|
||||
|
||||
void aud_prepare(aud_handle *dev) {
|
||||
if(dev->handle == NULL) {
|
||||
return;
|
||||
}
|
||||
memset(dev->buffer, 0, dev->blocksize * dev->width * dev->channels);
|
||||
dev->smppos = 0;
|
||||
int rc = 0;
|
||||
uint tries = 0;
|
||||
while(rc != dev->blocksize) {
|
||||
if(tries++ >= 256) {
|
||||
snd_logw(STR_AUD_PREPERR);
|
||||
return;
|
||||
}
|
||||
rc = snd_pcm_writei(dev->handle, dev->buffer, dev->blocksize);
|
||||
if(rc == -EAGAIN || (rc >= 0 && (uint)rc < dev->blocksize)) {
|
||||
snd_pcm_wait(dev->handle, 100);
|
||||
}
|
||||
else if(rc == -EPIPE) {
|
||||
snd_pcm_prepare(dev->handle);
|
||||
}
|
||||
}
|
||||
snd_pcm_nonblock(dev->handle, 1);
|
||||
for(int z = 0; z < 16; z++) {
|
||||
rc = snd_pcm_writei(dev->handle, dev->buffer, dev->blocksize);
|
||||
if(rc == -EAGAIN || (rc >= 0 && (uint)rc < dev->blocksize)) {
|
||||
snd_pcm_wait(dev->handle, 100);
|
||||
}
|
||||
else if(rc == -EPIPE) {
|
||||
snd_pcm_prepare(dev->handle);
|
||||
}
|
||||
}
|
||||
snd_pcm_nonblock(dev->handle, 0);
|
||||
}
|
||||
|
||||
void aud_write(aud_handle *dev, void *data, uint samples) {
|
||||
int rc;
|
||||
uint blocksize = dev->blocksize;
|
||||
while(samples > 0) {
|
||||
blocksize = samples < blocksize ? samples : blocksize;
|
||||
if(dev->handle) {
|
||||
rc = snd_pcm_writei(dev->handle, data, blocksize);
|
||||
}
|
||||
data += blocksize * dev->channels;
|
||||
samples -= blocksize;
|
||||
if(dev->handle) {
|
||||
if(rc == -EAGAIN || (rc >= 0 && (uint)rc < blocksize)) {
|
||||
snd_pcm_wait(dev->handle, 100);
|
||||
}
|
||||
else if(rc == -EPIPE) {
|
||||
#ifdef SND_MSGUNDER
|
||||
if(dev->underruns == 0) {
|
||||
dev->lastunder = dev->pushed;
|
||||
}
|
||||
dev->underruns += 1;
|
||||
#endif
|
||||
snd_pcm_prepare(dev->handle);
|
||||
}
|
||||
else if(rc < 0) {
|
||||
snd_loge(STR_AUD_WRITERR, snd_strerror(rc), rc);
|
||||
}
|
||||
#ifdef SND_MSGUNDER
|
||||
else {
|
||||
dev->pushed += 1;
|
||||
}
|
||||
if((dev->underruns > 0) && ((dev->pushed - dev->lastunder) >= (dev->samplerate / dev->blocksize))) {
|
||||
snd_logw(STR_AUD_UNDERR, dev->underruns);
|
||||
dev->underruns = 0;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uint aud_open_dev(aud_handle *dev, const char *devname, uint samplerate, byte channels, byte width, uint frames, uint bufsize) {
|
||||
dev->channels = (uint)channels;
|
||||
dev->samplerate = samplerate;
|
||||
dev->width = (uint)width;
|
||||
dev->smppos = 0;
|
||||
#ifdef SND_MSGUNDER
|
||||
dev->underruns = 0;
|
||||
dev->lastunder = 0;
|
||||
dev->pushed = 0;
|
||||
#endif
|
||||
dev->handle = NULL;
|
||||
dev->buffer = NULL;
|
||||
dev->conv = NULL;
|
||||
int rc;
|
||||
int subdir = 0;
|
||||
snd_pcm_hw_params_t *params = NULL;
|
||||
rc = snd_pcm_open(&dev->handle, devname, SND_PCM_STREAM_PLAYBACK, 0);
|
||||
if(rc < 0) {
|
||||
snd_loge(STR_AUD_OPNERR, devname, snd_strerror(rc), rc);
|
||||
return 0;
|
||||
}
|
||||
snd_pcm_hw_params_alloca(¶ms);
|
||||
snd_pcm_hw_params_any(dev->handle, params);
|
||||
snd_pcm_hw_params_set_access(dev->handle, params, SND_PCM_ACCESS_RW_INTERLEAVED);
|
||||
if(snd_pcm_hw_params_set_format(dev->handle, params, (dev->width == 4) ? SND_PCM_FORMAT_S32_LE : SND_PCM_FORMAT_S16_LE) != 0) {
|
||||
dev->width = (width == 4) ? 2 : 4;
|
||||
if(snd_pcm_hw_params_set_format(dev->handle, params, (dev->width == 4) ? SND_PCM_FORMAT_S32_LE : SND_PCM_FORMAT_S16_LE) != 0) {
|
||||
snd_loge(STR_AUD_FMTERR, devname);
|
||||
snd_pcm_close(dev->handle);
|
||||
return 0;
|
||||
}
|
||||
else {
|
||||
snd_logw(STR_AUD_FMTCH, devname, width * 8, dev->width * 8);
|
||||
}
|
||||
}
|
||||
snd_pcm_hw_params_set_channels(dev->handle, params, dev->channels);
|
||||
snd_pcm_hw_params_set_rate_near(dev->handle, params, &dev->samplerate, &subdir);
|
||||
snd_pcm_uframes_t framesize = frames;
|
||||
snd_pcm_hw_params_set_period_size_near(dev->handle, params, &framesize, &subdir);
|
||||
snd_pcm_uframes_t buffersize = bufsize;
|
||||
if(bufsize > 0) {
|
||||
snd_pcm_hw_params_set_buffer_size_near(dev->handle, params, &buffersize);
|
||||
}
|
||||
rc = snd_pcm_hw_params(dev->handle, params);
|
||||
if(rc < 0) {
|
||||
snd_loge(STR_AUD_HWERR, devname, snd_strerror(rc), rc);
|
||||
snd_pcm_close(dev->handle);
|
||||
return 0;
|
||||
}
|
||||
snd_pcm_hw_params_get_period_size(params, &framesize, &subdir);
|
||||
snd_pcm_hw_params_get_buffer_size(params, &buffersize);
|
||||
snd_pcm_sw_params_t *swparams;
|
||||
snd_pcm_sw_params_alloca(&swparams);
|
||||
snd_pcm_sw_params_current(dev->handle, swparams);
|
||||
// snd_pcm_sw_params_set_avail_min(dev->handle, swparams, framesize);
|
||||
// snd_pcm_sw_params_set_start_threshold(dev->handle, swparams, 0);
|
||||
// snd_pcm_sw_params_set_stop_threshold(dev->handle, swparams, buffersize);
|
||||
rc = snd_pcm_sw_params(dev->handle, swparams);
|
||||
if(rc < 0) {
|
||||
snd_loge(STR_AUD_SWERR, devname, snd_strerror(rc), rc);
|
||||
snd_pcm_close(dev->handle);
|
||||
return 0;
|
||||
}
|
||||
|
||||
dev->blocksize = framesize;
|
||||
dev->devbufsize = buffersize;
|
||||
dev->buffer = malloc(dev->blocksize * dev->width * dev->channels);
|
||||
if(dev->width == 4)
|
||||
dev->conv = malloc(sizeof(int) * dev->channels);
|
||||
snd_pcm_wait(dev->handle, -1);
|
||||
aud_prepare(dev);
|
||||
return dev->samplerate;
|
||||
}
|
||||
|
||||
void aud_push_raw(aud_handle *dev, void *data) {
|
||||
memcpy(&((byte*)(dev->buffer))[dev->smppos*dev->channels*dev->width], data, dev->width * dev->channels);
|
||||
dev->smppos++;
|
||||
if(dev->smppos == dev->blocksize) {
|
||||
aud_write(dev, dev->buffer, dev->blocksize);
|
||||
dev->smppos = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void aud_push(aud_handle *dev, short *data) {
|
||||
if(dev->width == 4) {
|
||||
for(int h = 0; h < dev->channels; h++) {
|
||||
dev->conv[h] = ((int)data[h]) << 16;
|
||||
}
|
||||
aud_push_raw(dev, dev->conv);
|
||||
}
|
||||
else {
|
||||
aud_push_raw(dev, data);
|
||||
}
|
||||
}
|
||||
|
||||
void aud_flush(aud_handle *dev) {
|
||||
if(dev->smppos != 0) {
|
||||
aud_write(dev, dev->buffer, dev->smppos);
|
||||
dev->smppos = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void aud_close(aud_handle *dev) {
|
||||
if(dev->handle) {
|
||||
snd_pcm_drain(dev->handle);
|
||||
snd_pcm_close(dev->handle);
|
||||
}
|
||||
free(dev->buffer);
|
||||
if(dev->conv)
|
||||
free(dev->conv);
|
||||
}
|
208
argparse.h
Normal file
|
@ -0,0 +1,208 @@
|
|||
|
||||
void arg_help(argp_t *argspec, char *prog) {
|
||||
arg_t *arg_vec = argspec->arg_vec;
|
||||
fprintf(stderr, STR_ARG_USAGE": %s\n [-? ("STR_ARG_HELP")]\n", prog);
|
||||
for(int h = 0; h < argspec->arg_count; h++) {
|
||||
arg_t *arg = &arg_vec[h];
|
||||
if(arg->spec) {
|
||||
if(arg->arg) {
|
||||
if((arg->min == 0) && (arg->max == 0)) {
|
||||
fprintf(stderr, " [-%c <%s>]\n", arg->spec, arg->name);
|
||||
}
|
||||
else {
|
||||
fprintf(stderr, " [-%c <%s (%d-%d)>]\n", arg->spec, arg->name, arg->min, arg->max);
|
||||
}
|
||||
}
|
||||
else {
|
||||
fprintf(stderr, " [-%c (%s)]\n", arg->spec, arg->name);
|
||||
}
|
||||
}
|
||||
}
|
||||
for(int h = 0; h < argspec->arg_max; h++) {
|
||||
arg_t *arg = &arg_vec[h];
|
||||
char nb = (h < argspec->arg_min) ? '<' : '[';
|
||||
char eb = (h < argspec->arg_min) ? '>' : ']';
|
||||
if((arg->min == 0) && (arg->max == 0)) {
|
||||
fprintf(stderr, " %c%s%s%c\n", nb, arg->name, (arg->value == NULL) ? "" : ", ...", eb);
|
||||
}
|
||||
else {
|
||||
fprintf(stderr, " %c%s (%d-%d)%c\n", nb, arg->name, arg->min, arg->max, eb);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
char arg_process(arg_t *arg_vec, char *arg, int off) {
|
||||
if((arg_vec[off].min == 0) && (arg_vec[off].max == 0)) {
|
||||
if(arg_vec[off].value != NULL) {
|
||||
arg_vec[off].str[*(arg_vec[off].value)] = arg;
|
||||
*(arg_vec[off].value) += 1;
|
||||
}
|
||||
else {
|
||||
*(arg_vec[off].str) = arg;
|
||||
}
|
||||
}
|
||||
else {
|
||||
errno = 0;
|
||||
char *endptr;
|
||||
*(arg_vec[off].value) = strtol(arg, &endptr, 10);
|
||||
if((errno != 0) || (endptr[0] != 0)) {
|
||||
if(arg_vec[off].spec) {
|
||||
fprintf(stderr, STR_ARG_EINT_V"\n", arg_vec[off].name, arg_vec[off].spec);
|
||||
}
|
||||
else {
|
||||
fprintf(stderr, STR_ARG_EINT_P"\n", arg_vec[off].name, off + 1);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
if((*(arg_vec[off].value) < arg_vec[off].min) || (*(arg_vec[off].value) > arg_vec[off].max)) {
|
||||
if(arg_vec[off].spec) {
|
||||
fprintf(stderr, STR_ARG_ERANGE_V"\n", arg_vec[off].name, arg_vec[off].spec, arg_vec[off].min, arg_vec[off].max);
|
||||
}
|
||||
else {
|
||||
fprintf(stderr, STR_ARG_ERANGE_P"\n", arg_vec[off].name, off + 1, arg_vec[off].min, arg_vec[off].max);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
char arg_parse(argp_t *argspec, int argc, char **argv) {
|
||||
uint arg_min = argspec->arg_min;
|
||||
uint arg_max = argspec->arg_max;
|
||||
uint arg_count = argspec->arg_count;
|
||||
arg_t *arg_vec = argspec->arg_vec;
|
||||
uint idx = 0;
|
||||
uint sp = 0;
|
||||
char sa = 0;
|
||||
for(int h = 1; h < argc; h++) {
|
||||
char *arg = argv[h];
|
||||
if((sa == 0) && (arg[0] == '-') && (arg[1] != 0)) {
|
||||
arg += 1;
|
||||
if(arg[0] == '?') {
|
||||
arg_help(argspec, argv[0]);
|
||||
free(argspec);
|
||||
return 0;
|
||||
}
|
||||
while((arg[0] != 0) && (sa == 0)) {
|
||||
int f = 0;
|
||||
for(int h = 0; h < arg_count; h++) {
|
||||
if((arg_vec[h].arg ^ 1) && (arg[0] == arg_vec[h].spec)) {
|
||||
*(arg_vec[h].value) = 1;
|
||||
arg += 1;
|
||||
f++;
|
||||
break;
|
||||
}
|
||||
else if(arg[0] == arg_vec[h].spec) {
|
||||
sa = arg[0];
|
||||
sp = h;
|
||||
arg += 1;
|
||||
f++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(f == 0) {
|
||||
fprintf(stderr, STR_ARG_UNKNOWN"\n", arg[0]);
|
||||
free(argspec);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
if(arg[0] == 0) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else if(sa == 0) {
|
||||
if((arg[0] == '\\') && (arg[1] == '-')) {
|
||||
arg += 1;
|
||||
}
|
||||
if((idx < arg_max) || ((arg_max > 0) && (arg_vec[arg_max-1].min == 0) && (arg_vec[arg_max-1].max == 0) && (arg_vec[arg_max-1].value != NULL))) {
|
||||
if(!arg_process(arg_vec, arg, (idx >= arg_max) ? (arg_max-1) : idx)) {
|
||||
free(argspec);
|
||||
return 0;
|
||||
}
|
||||
idx += 1;
|
||||
continue;
|
||||
}
|
||||
else {
|
||||
fprintf(stderr, STR_ARG_EMORE"\n", arg_max);
|
||||
free(argspec);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
if(!arg_process(arg_vec, arg, sp)) {
|
||||
free(argspec);
|
||||
return 0;
|
||||
}
|
||||
sa = 0;
|
||||
}
|
||||
if(sa != 0) {
|
||||
fprintf(stderr, STR_ARG_EREQARG"\n", arg_vec[sp].name, sa);
|
||||
free(argspec);
|
||||
return 0;
|
||||
}
|
||||
if(idx < arg_min) {
|
||||
fprintf(stderr, STR_ARG_ELESS"\n", arg_min);
|
||||
free(argspec);
|
||||
return 0;
|
||||
}
|
||||
free(argspec);
|
||||
return 1;
|
||||
}
|
||||
|
||||
void arg_add_gen(argp_t *argspec, char spec, const char *name, int min, int max, char argreq, int *value, char **str) {
|
||||
arg_t *arg = &argspec->arg_vec[(argspec->arg_count)++];
|
||||
arg->spec = spec;
|
||||
arg->arg = argreq;
|
||||
arg->min = min;
|
||||
arg->max = max;
|
||||
arg->value = value;
|
||||
arg->str = str;
|
||||
arg->name = name;
|
||||
}
|
||||
|
||||
void arg_add_int(argp_t *argspec, char spec, const char *name, int min, int max, int *value) {
|
||||
arg_add_gen(argspec, spec, name, min, max, 1, value, NULL);
|
||||
}
|
||||
|
||||
void arg_add_str(argp_t *argspec, char spec, const char *name, char **value) {
|
||||
arg_add_gen(argspec, spec, name, 0, 0, 1, NULL, value);
|
||||
}
|
||||
|
||||
void arg_add_bool(argp_t *argspec, char spec, const char *name, int *value) {
|
||||
arg_add_gen(argspec, spec, name, 0, 0, 0, value, NULL);
|
||||
}
|
||||
|
||||
void arg_add_nint(argp_t *argspec, const char *name, char req, int min, int max, int *value) {
|
||||
arg_add_gen(argspec, 0, name, min, max, 0, value, NULL);
|
||||
argspec->arg_max += 1;
|
||||
argspec->arg_min += req ? 1 : 0;
|
||||
}
|
||||
|
||||
void arg_add_nstr(argp_t *argspec, const char *name, char req, char **value) {
|
||||
arg_add_gen(argspec, 0, name, 0, 0, 0, NULL, value);
|
||||
argspec->arg_max += 1;
|
||||
argspec->arg_min += req ? 1 : 0;
|
||||
}
|
||||
|
||||
void arg_add_nbool(argp_t *argspec, const char *name, char req, int *value) {
|
||||
arg_add_gen(argspec, 0, name, 0, 1, 0, value, NULL);
|
||||
argspec->arg_max += 1;
|
||||
argspec->arg_min += req ? 1 : 0;
|
||||
}
|
||||
|
||||
void arg_add_vstr(argp_t *argspec, const char *name, char req, char **svalue, int *ivalue) {
|
||||
arg_add_gen(argspec, 0, name, 0, 0, 0, ivalue, svalue);
|
||||
argspec->arg_max = 1;
|
||||
argspec->arg_min += req ? 1 : 0;
|
||||
}
|
||||
|
||||
argp_t *arg_alloc(uint count) {
|
||||
char *data = malloc(sizeof(argp_t) + (count * sizeof(arg_t)));
|
||||
argp_t *argspec = (argp_t*)data;
|
||||
data += sizeof(argp_t);
|
||||
argspec->arg_vec = (arg_t*)data;
|
||||
argspec->arg_count = 0;
|
||||
argspec->arg_min = 0;
|
||||
argspec->arg_max = 0;
|
||||
return argspec;
|
||||
}
|
404
bank.h
Normal file
|
@ -0,0 +1,404 @@
|
|||
|
||||
void bank_reset(opl3_chip *chip, bank_handle *bank) {
|
||||
ushort voices = chip->n_voices;
|
||||
byte flags = bank->flags;
|
||||
char velo_func = bank->velo_func;
|
||||
bank_instr *instr = bank->bdata;
|
||||
byte *bankdata = (byte*)bank;
|
||||
bankdata += sizeof(bank_handle);
|
||||
memset(bank, 0, sizeof(bank_handle));
|
||||
bank->voices = (bank_voice*)bankdata;
|
||||
bank->v_avail = voices;
|
||||
bank->flags = flags;
|
||||
bank->velo_func = velo_func;
|
||||
bank->bdata = instr;
|
||||
for(int h = 0; h < 16; h++) {
|
||||
bank_channel *channel = &bank->channel[h];
|
||||
channel->bank = bank;
|
||||
memset(channel->notes, 0xff, 128);
|
||||
channel->volume = 127;
|
||||
channel->pbank = (h == 9) ? 128 : 0;
|
||||
channel->instr = &bank->bdata[(h == 9) ? 128 : 0];
|
||||
channel->ch_num = h;
|
||||
}
|
||||
for(int h = 0; h < voices; h++) {
|
||||
bank_voice *voice = &bank->voices[h];
|
||||
voice->channel = NULL;
|
||||
voice->opl = &chip->channel[h];
|
||||
voice->note = 0xff;
|
||||
voice->op = b_op2;
|
||||
voice->detune = 0;
|
||||
voice->pair = &bank->voices[h+(((h & 1) == 0) ? 1 : -1)];
|
||||
}
|
||||
}
|
||||
|
||||
bank_handle *bank_alloc(opl3_chip *chip, bank_instr *instr, byte keep, byte useunkn, char velofunc) {
|
||||
byte *bankdata = malloc(sizeof(bank_handle) + (sizeof(bank_voice) * chip->n_voices));
|
||||
bank_handle *bank = (bank_handle*)bankdata;
|
||||
bank->flags = (keep ? BANK_KEEP : 0) | (useunkn ? BANK_UNKN : 0);
|
||||
bank->velo_func = velofunc;
|
||||
bank->bdata = instr;
|
||||
bank_reset(chip, bank);
|
||||
return bank;
|
||||
}
|
||||
|
||||
byte bank_getnote(bank_channel *ch, byte key, byte id, byte drum, bank_instr *instr) {
|
||||
short note = (short)key;
|
||||
if(instr->fixed /* || drum */) {
|
||||
note = ((short)instr->percnum) + instr->channels[id].offset;
|
||||
}
|
||||
else {
|
||||
note += instr->channels[id].offset;
|
||||
}
|
||||
note = note < 0 ? 0 : note;
|
||||
note = note > 127 ? 127 : note;
|
||||
return (byte)note;
|
||||
}
|
||||
|
||||
void OPL3_ChannelFreqHz(opl3_channel *channel, uint freq) {
|
||||
uint block = 0;
|
||||
while(opl3_maxfreq[block] < freq) {
|
||||
block++;
|
||||
if(block == 8) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(block == 8) {
|
||||
OPL3_ChannelFreq(channel, 7, 1023);
|
||||
return;
|
||||
}
|
||||
double f_num = ((double)freq) / 1000.0 * pow(2.0, (20.0-((double)block))) / 49716.0;
|
||||
OPL3_ChannelFreq(channel, block, (uint)f_num);
|
||||
}
|
||||
|
||||
uint bank_getfreq(byte key, short pitch, short detune) {
|
||||
double pfrq = pow(2.0, ((((double)pitch) / 8191.0 * BANK_PBRANGE) + (((double)detune) / 100.0)) / 12.0);
|
||||
double freq = ((double)bank_notes[key]) * pfrq;
|
||||
return (uint)freq;
|
||||
}
|
||||
|
||||
void OPL3_ChannelNote(opl3_channel *channel, byte key, short pitch, short detune) {
|
||||
OPL3_ChannelFreqHz(channel, bank_getfreq(key, pitch, detune));
|
||||
}
|
||||
|
||||
uint bank_getlevel(char function, byte velocity, byte volume, char pan) {
|
||||
double lvl = ((function == -128) ? 1.0 :
|
||||
(function ? BANK_VELOFUNC(((double)velocity)/127.0, function < 0 ? (0.1+(1.0-((((double)(-function))-1.0)/126.0))*9.9) : (1.0+((((double)function)-1.0)/126.0)*9.0)) :
|
||||
(((double)velocity)/127.0))) * (((double)volume)/127.0) * (1.0-(0.9*((double)pan)/63.0));
|
||||
// fprintf(stderr, "%d===%d-->%.2f\n", function, velocity, lvl);
|
||||
lvl *= 65536.0;
|
||||
return (uint)lvl;
|
||||
}
|
||||
|
||||
void OPL3_ChannelLevelPan(opl3_channel *channel, char function, byte velocity, byte volume, char pan) {
|
||||
OPL3_ChannelOutput(channel, 0, bank_getlevel(function, velocity, volume, pan));
|
||||
OPL3_ChannelOutput(channel, 1, bank_getlevel(function, velocity, volume, -pan));
|
||||
}
|
||||
|
||||
void bank_release_voice(bank_handle *bank, bank_channel *ch, bank_voice *voice) {
|
||||
if(voice->note == 0xff) {
|
||||
return;
|
||||
}
|
||||
OPL3_ChannelKeyOff(voice->opl);
|
||||
voice->note = 0xff;
|
||||
if(voice->op == b_op22) {
|
||||
voice->pair->note = 0xff;
|
||||
OPL3_ChannelKeyOff(voice->pair->opl);
|
||||
bank->v_used -= 2;
|
||||
}
|
||||
else if(voice->op == b_op4) {
|
||||
voice->pair->note = 0xff;
|
||||
bank->v_used -= 2;
|
||||
}
|
||||
else {
|
||||
bank->v_used -= 1;
|
||||
}
|
||||
}
|
||||
|
||||
bank_voice *bank_release_key(bank_channel *ch, byte note) {
|
||||
if(ch->active == 0) {
|
||||
return NULL;
|
||||
}
|
||||
if(ch->notes[note] == 0xff) {
|
||||
return NULL;
|
||||
}
|
||||
bank_key *key = &ch->keys[ch->notes[note]];
|
||||
ch->notes[note] = 0xff;
|
||||
ch->active -= 1;
|
||||
if(key->voice) {
|
||||
bank_release_voice(ch->bank, ch, key->voice);
|
||||
}
|
||||
key->velocity = 0;
|
||||
return key->voice;
|
||||
}
|
||||
|
||||
void bank_init_voice(opl3_channel *channel, bank_instr *instr, byte id) {
|
||||
OPL3_Channel4Op(channel, instr->op == b_op4);
|
||||
for(int o = 0; o < ((instr->op == b_op4) ? 4 : 2); o++) {
|
||||
bank_pair *pair = &instr->channels[(instr->op == b_op4) ? (o >> 1) : id];
|
||||
bank_operator *op = &pair->ops[o & 1];
|
||||
opl3_slot *slot = (o >= 2) ? (channel->pair->slots[o & 1]) : (channel->slots[o & 1]);
|
||||
OPL3_SlotFlags(slot, op->tremolo, op->vibrato, op->sustaining, op->ksr);
|
||||
OPL3_SlotMult(slot, op->mult);
|
||||
OPL3_SlotKSL(slot, op->ksl);
|
||||
OPL3_SlotLevel(slot, op->level);
|
||||
OPL3_SlotADSR(slot, op->attack, op->decay, op->sustain, op->release);
|
||||
OPL3_SlotWaveform(slot, op->waveform);
|
||||
if((o & 1) == 1) {
|
||||
opl3_channel *chn = (o >= 2) ? channel->pair : channel;
|
||||
OPL3_ChannelFeedback(chn, pair->feedback);
|
||||
OPL3_ChannelAM(chn, pair->am);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bank_voice *bank_get_voice(bank_handle *bank, bank_channel *ch, byte note, byte velocity) {
|
||||
bank_instr *instr = ch->instr;
|
||||
if(ch->pbank == 128) {
|
||||
instr += note;
|
||||
}
|
||||
else if((ch->pbank != 0) && (!(bank->flags & BANK_UNKN))) {
|
||||
return NULL;
|
||||
}
|
||||
if(instr->op == b_op0) {
|
||||
return NULL;
|
||||
}
|
||||
if(bank->v_used == bank->v_avail) {
|
||||
if(bank->flags & BANK_KEEP) {
|
||||
return NULL;
|
||||
}
|
||||
if((instr->op != b_op2) && ((bank->voiceindex & 1) != 0)) {
|
||||
bank->voiceindex += 1;
|
||||
if(bank->voiceindex >= bank->v_avail) {
|
||||
bank->voiceindex = 0;
|
||||
}
|
||||
}
|
||||
bank_release_key(bank->voices[bank->voiceindex].channel, bank->voices[bank->voiceindex].note);
|
||||
}
|
||||
else if((instr->op != b_op2) && ((bank->voiceindex & 1) != 0)) {
|
||||
bank->voiceindex += 1;
|
||||
if(bank->voiceindex >= bank->v_avail) {
|
||||
bank->voiceindex = 0;
|
||||
}
|
||||
}
|
||||
byte vi = bank->voiceindex;
|
||||
while((bank->voices[bank->voiceindex].note != 0xff) || ((instr->op != b_op2) && (bank->voices[bank->voiceindex+1].note != 0xff))) {
|
||||
bank->voiceindex += (instr->op != b_op2) ? 2 : 1;
|
||||
if(bank->voiceindex >= bank->v_avail) {
|
||||
bank->voiceindex = 0;
|
||||
}
|
||||
if(vi == bank->voiceindex) {
|
||||
if(bank->flags & BANK_KEEP) {
|
||||
return NULL;
|
||||
}
|
||||
bank_release_key(bank->voices[bank->voiceindex].channel, bank->voices[bank->voiceindex].note);
|
||||
if((instr->op != b_op2) && (bank->voices[bank->voiceindex+1].note != 0xff)) {
|
||||
bank_release_key(bank->voices[bank->voiceindex+1].channel, bank->voices[bank->voiceindex+1].note);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
bank_voice *voice = &bank->voices[bank->voiceindex];
|
||||
if((instr->op == b_op2) && (voice->op == b_op4)) {
|
||||
short offset = ((short)bank->voiceindex) + (((bank->voiceindex & 1) == 0) ? 1 : -1);
|
||||
bank_voice *voice2 = &bank->voices[offset];
|
||||
if(voice2->note == 0xff) {
|
||||
OPL3_ChannelOutput(voice2->opl, 0, 0);
|
||||
OPL3_ChannelOutput(voice2->opl, 1, 0);
|
||||
}
|
||||
}
|
||||
bank->voiceindex += (instr->op != b_op2) ? 2 : 1;
|
||||
if(bank->voiceindex >= bank->v_avail) {
|
||||
bank->voiceindex = 0;
|
||||
}
|
||||
voice->channel = ch;
|
||||
voice->note = note;
|
||||
voice->op = instr->op;
|
||||
voice->detune = instr->channels[0].detune;
|
||||
bank_init_voice(voice->opl, instr, 0);
|
||||
if(voice->op == b_op22) {
|
||||
voice->pair->channel = ch;
|
||||
voice->pair->note = note;
|
||||
voice->pair->op = b_op22;
|
||||
voice->pair->detune = instr->channels[1].detune;
|
||||
bank_init_voice(voice->pair->opl, instr, 1);
|
||||
OPL3_ChannelNote(voice->opl, bank_getnote(ch, note, 0, ch->pbank == 128, instr), ch->pitch, voice->detune);
|
||||
OPL3_ChannelNote(voice->pair->opl, bank_getnote(ch, note, 1, ch->pbank == 128, instr), ch->pitch, voice->pair->detune);
|
||||
OPL3_ChannelLevelPan(voice->opl, bank->velo_func, velocity, ch->volume, ch->pan);
|
||||
OPL3_ChannelLevelPan(voice->pair->opl, bank->velo_func, velocity, ch->volume, ch->pan);
|
||||
OPL3_ChannelKeyOn(voice->opl);
|
||||
OPL3_ChannelKeyOn(voice->pair->opl);
|
||||
bank->v_used += 2;
|
||||
}
|
||||
else if(voice->op == b_op4) {
|
||||
voice->pair->channel = ch;
|
||||
voice->pair->note = note;
|
||||
voice->pair->op = b_op4;
|
||||
OPL3_ChannelNote(voice->opl, bank_getnote(ch, note, 0, ch->pbank == 128, instr), ch->pitch, voice->detune);
|
||||
OPL3_ChannelLevelPan(voice->opl, bank->velo_func, velocity, ch->volume, ch->pan);
|
||||
OPL3_ChannelKeyOn(voice->opl);
|
||||
bank->v_used += 2;
|
||||
}
|
||||
else {
|
||||
OPL3_ChannelNote(voice->opl, bank_getnote(ch, note, 0, ch->pbank == 128, instr), ch->pitch, voice->detune);
|
||||
OPL3_ChannelLevelPan(voice->opl, bank->velo_func, velocity, ch->volume, ch->pan);
|
||||
OPL3_ChannelKeyOn(voice->opl);
|
||||
bank->v_used += 1;
|
||||
}
|
||||
return voice;
|
||||
}
|
||||
|
||||
bank_voice *bank_press_key(bank_channel *ch, byte note, byte velocity) {
|
||||
if(ch->notes[note] != 0xff) {
|
||||
bank_release_key(ch, note);
|
||||
}
|
||||
if(ch->active == BANK_MAX) {
|
||||
return NULL;
|
||||
}
|
||||
byte ki = ch->keyindex;
|
||||
while(ch->keys[ch->keyindex].velocity != 0) {
|
||||
ch->keyindex += 1;
|
||||
if(ch->keyindex == BANK_MAX) {
|
||||
ch->keyindex = 0;
|
||||
}
|
||||
if(ki == ch->keyindex) {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
bank_voice *voice = bank_get_voice(ch->bank, ch, note, velocity);
|
||||
ch->notes[note] = ch->keyindex;
|
||||
ch->active += 1;
|
||||
bank_key *key = &ch->keys[ch->keyindex];
|
||||
key->note = note;
|
||||
key->velocity = velocity;
|
||||
key->voice = voice;
|
||||
return voice;
|
||||
}
|
||||
|
||||
void bank_notesoff(bank_channel *ch) {
|
||||
for(int h = 0; (h < BANK_MAX) && (ch->active > 0); h++) {
|
||||
bank_release_key(ch, h);
|
||||
}
|
||||
}
|
||||
|
||||
void bank_progupdate(bank_channel *ch, opl3_chip *chip) {
|
||||
bank_notesoff(ch);
|
||||
ushort id = ch->program;
|
||||
if(ch->pbank == 128) {
|
||||
id = 128;
|
||||
}
|
||||
else if((ch->pbank != 0) && (!(ch->bank->flags & BANK_UNKN))) {
|
||||
id = 0;
|
||||
}
|
||||
ch->instr = (ch->bank->bdata)+id;
|
||||
}
|
||||
|
||||
void bank_levelupdate(bank_channel *ch, opl3_chip *chip) {
|
||||
byte done = 0;
|
||||
for(int h = 0; (h < BANK_MAX) && (done < ch->active); h++) {
|
||||
bank_key *key = (ch->keys)+h;
|
||||
if((key->velocity == 0) || (key->voice == NULL)) {
|
||||
continue;
|
||||
}
|
||||
OPL3_ChannelLevelPan(key->voice->opl, ch->bank->velo_func, key->velocity, ch->volume, ch->pan);
|
||||
if(key->voice->op == b_op22) {
|
||||
OPL3_ChannelLevelPan(key->voice->pair->opl, ch->bank->velo_func, key->velocity, ch->volume, ch->pan);
|
||||
}
|
||||
done++;
|
||||
}
|
||||
}
|
||||
|
||||
void bank_frequpdate(bank_channel *ch, opl3_chip *chip) {
|
||||
byte done = 0;
|
||||
for(int h = 0; (h < BANK_MAX) && (done < ch->active); h++) {
|
||||
bank_key *key = (ch->keys)+h;
|
||||
if((key->velocity == 0) || (key->voice == NULL)) {
|
||||
continue;
|
||||
}
|
||||
OPL3_ChannelNote(key->voice->opl, bank_getnote(ch, key->note, 0, ch->pbank == 128, ch->instr), ch->pitch, key->voice->detune);
|
||||
if(key->voice->op == b_op22) {
|
||||
OPL3_ChannelNote(key->voice->pair->opl, bank_getnote(ch, key->note, 1, ch->pbank == 128, ch->instr), ch->pitch, key->voice->pair->detune);
|
||||
}
|
||||
done++;
|
||||
}
|
||||
}
|
||||
|
||||
void bank_noteon(bank_handle *bank, opl3_chip *chip, byte channel, byte key, byte velocity) {
|
||||
bank_channel *ch = &bank->channel[channel];
|
||||
// if((ch->pbank == 128) && ((key < 35) || (key > 81))) {
|
||||
// return;
|
||||
// }
|
||||
bank_press_key(ch, key, velocity);
|
||||
}
|
||||
|
||||
void bank_noteoff(bank_handle *bank, opl3_chip *chip, byte channel, byte key, byte velocity) {
|
||||
bank_channel *ch = &bank->channel[channel];
|
||||
// if((ch->pbank == 128) && ((key < 35) || (key > 81))) {
|
||||
// return;
|
||||
// }
|
||||
bank_release_key(ch, key);
|
||||
}
|
||||
|
||||
void bank_progchange(bank_handle *bank, opl3_chip *chip, byte channel, byte program) {
|
||||
bank_channel *ch = &bank->channel[channel];
|
||||
ch->program = program;
|
||||
bank_progupdate(ch, chip);
|
||||
}
|
||||
|
||||
void bank_pitchbend(bank_handle *bank, opl3_chip *chip, byte channel, short pitch) {
|
||||
bank_channel *ch = &bank->channel[channel];
|
||||
ch->pitch = pitch;
|
||||
bank_frequpdate(ch, chip);
|
||||
}
|
||||
|
||||
void bank_control(bank_handle *bank, opl3_chip *chip, byte channel, byte control, byte value) {
|
||||
bank_channel *ch = &bank->channel[channel];
|
||||
switch(control) {
|
||||
case 0x00: // bank MSB
|
||||
// if((channel == 9) && (value == 0)) {
|
||||
// ch->pbank = 128;
|
||||
// }
|
||||
// else {
|
||||
if(channel != 9) {
|
||||
ch->pbank &= 0x007f;
|
||||
ch->pbank |= (((ushort)value) << 7) & 0x3f80;
|
||||
}
|
||||
bank_progupdate(ch, chip);
|
||||
break;
|
||||
case 0x20: // bank LSB
|
||||
// if((channel == 9) && (value == 0)) {
|
||||
// ch->pbank = 128;
|
||||
// }
|
||||
// else {
|
||||
if(channel != 9) {
|
||||
ch->pbank &= 0x3f80;
|
||||
ch->pbank |= ((ushort)value) & 0x007f;
|
||||
}
|
||||
bank_progupdate(ch, chip);
|
||||
break;
|
||||
case 0x07: // volume MSB
|
||||
ch->volume = value;
|
||||
bank_levelupdate(ch, chip);
|
||||
break;
|
||||
case 0x0a: // pan MSB
|
||||
ch->pan = ((char)value) - 64;
|
||||
bank_levelupdate(ch, chip);
|
||||
break;
|
||||
case 0x79: // reset
|
||||
ch->pbank = (channel == 9) ? 128 : 0;
|
||||
ch->volume = 127;
|
||||
ch->pan = 0;
|
||||
bank_progupdate(ch, chip);
|
||||
bank_levelupdate(ch, chip);
|
||||
break;
|
||||
case 0x7b: // all off
|
||||
bank_notesoff(ch);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void bank_alloff(bank_handle *bank) {
|
||||
for(int h = 0; h < 16; h++) {
|
||||
bank_notesoff(&bank->channel[h]);
|
||||
}
|
||||
}
|
BIN
banks/bank49.opl
Normal file
BIN
banks/bank53.opl
Normal file
BIN
banks/cyberpuck.tmb
Normal file
BIN
banks/d3dtimbr.tmb
Normal file
BIN
banks/d3dtimbr_mod.tmb
Normal file
BIN
banks/dmx_dmx.op2
Normal file
BIN
banks/dmx_doom1.op2
Normal file
BIN
banks/dmx_doom2.op2
Normal file
BIN
banks/dmx_raptor.op2
Normal file
BIN
banks/dmx_strife.op2
Normal file
BIN
banks/drumopl.tmb
Normal file
BIN
banks/earthsieg.ad
Normal file
BIN
banks/fat2.op3
Normal file
BIN
banks/fat4.op3
Normal file
BIN
banks/gmoconel.tmb
Normal file
BIN
banks/gmopl.ibk
Normal file
BIN
banks/gmopl_mod.tmb
Normal file
BIN
banks/hmi_144.skb
Normal file
BIN
banks/insmaker_std.bnk
Normal file
BIN
banks/jv_2op.op3
Normal file
BIN
banks/mt32.ibk
Normal file
BIN
banks/nemesis.opl
Normal file
BIN
banks/op2x2.op3
Normal file
BIN
banks/std_o3.skb
Normal file
BIN
banks/std_sb.skb
Normal file
BIN
banks/swtimbr.tmb
Normal file
BIN
banks/tmb_default.tmb
Normal file
BIN
banks/wallace.op3
Normal file
BIN
banks/wallence.tmb
Normal file
BIN
banks/warcraft.ad
Normal file
BIN
banks/wolfinstein.op2
Normal file
192
bbox.h
Normal file
|
@ -0,0 +1,192 @@
|
|||
|
||||
bbox_t *box_offset_to(bbox_t *aa, bbox_t *bb, double x, double y, double z) {
|
||||
bb->x1 = aa->x1 + x;
|
||||
bb->x2 = aa->x2 + x;
|
||||
bb->y1 = aa->y1 + y;
|
||||
bb->y2 = aa->y2 + y;
|
||||
bb->z1 = aa->z1 + z;
|
||||
bb->z2 = aa->z2 + z;
|
||||
return bb;
|
||||
}
|
||||
|
||||
bbox_t *box_add_coord(bbox_t *aa, bbox_t *bb, double x, double y, double z) {
|
||||
if(aa)
|
||||
AABB_PCOPY(aa, bb);
|
||||
if(x < 0.0D)
|
||||
bb->x1 += x;
|
||||
else if(x > 0.0D)
|
||||
bb->x2 += x;
|
||||
if(y < 0.0D)
|
||||
bb->y1 += y;
|
||||
else if(y > 0.0D)
|
||||
bb->y2 += y;
|
||||
if(z < 0.0D)
|
||||
bb->z1 += z;
|
||||
else if(z > 0.0D)
|
||||
bb->z2 += z;
|
||||
return bb;
|
||||
}
|
||||
|
||||
bbox_t *box_union(bbox_t *aa, bbox_t *bb, double x, double y, double z) {
|
||||
if(aa)
|
||||
AABB_PCOPY(aa, bb);
|
||||
bb->x1 = MIN_VALUE(bb->x1, x);
|
||||
bb->y1 = MIN_VALUE(bb->y1, y);
|
||||
bb->z1 = MIN_VALUE(bb->z1, z);
|
||||
bb->x2 = MAX_VALUE(bb->x2, x);
|
||||
bb->y2 = MAX_VALUE(bb->y2, y);
|
||||
bb->z2 = MAX_VALUE(bb->z2, z);
|
||||
return bb;
|
||||
}
|
||||
|
||||
#define BOX_OFFSET_FUNC(cc, cd, ce) \
|
||||
double box_calc_ ## cc ## off(bbox_t *aa, bbox_t *bb, double offset) { \
|
||||
if(bb->cd ## 2 > aa->cd ## 1 && bb->cd ## 1 < aa->cd ## 2 && bb->ce ## 2 > aa->ce ## 1 && bb->ce ## 1 < aa->ce ## 2) { \
|
||||
if(offset > 0.0 && bb->cc ## 2 <= aa->cc ## 1) { \
|
||||
double pdelta = aa->cc ## 1 - bb->cc ## 2; \
|
||||
if(pdelta < offset) \
|
||||
offset = pdelta; \
|
||||
} \
|
||||
else if(offset < 0.0 && bb->cc ## 1 >= aa->cc ## 2) { \
|
||||
double ndelta = aa->cc ## 2 - bb->cc ## 1; \
|
||||
if(ndelta > offset) \
|
||||
offset = ndelta; \
|
||||
} \
|
||||
return offset; \
|
||||
} \
|
||||
else { \
|
||||
return offset; \
|
||||
} \
|
||||
}
|
||||
|
||||
BOX_OFFSET_FUNC(x, y, z)
|
||||
BOX_OFFSET_FUNC(y, x, z)
|
||||
BOX_OFFSET_FUNC(z, x, y)
|
||||
|
||||
byte box_intersects(bbox_t *aa, bbox_t *bb) {
|
||||
return bb->x2 > aa->x1 && bb->x1 < aa->x2 && bb->y2 > aa->y1 && bb->y1 < aa->y2 && bb->z2 > aa->z1 && bb->z1 < aa->z2;
|
||||
}
|
||||
|
||||
chunk_t *chunk_get(world_t *world, int x, int y, int z, byte load);
|
||||
|
||||
int box_get_colliding(world_t *world, bbox_t **listptr, bbox_t *box) {
|
||||
bbox_t *list = sys.collision_list;
|
||||
int x1 = ((int)(double)(box->x1 + (box->x2 - box->x1) / 2.0)) / CHUNK_SIZE;
|
||||
int y1 = ((int)(double)(box->y1 + (box->y2 - box->y1) / 2.0)) / CHUNK_SIZE;
|
||||
int z1 = ((int)(double)(box->z1 + (box->z2 - box->z1) / 2.0)) / CHUNK_SIZE;
|
||||
int x2 = x1 + 2;
|
||||
int y2 = y1 + 2;
|
||||
int z2 = z1 + 2;
|
||||
x1 -= 2;
|
||||
y1 -= 2;
|
||||
z1 -= 2;
|
||||
// x1 = CHUNK_CLAMP(world, x1, x);
|
||||
// y1 = CHUNK_CLAMP(world, y1, y);
|
||||
// z1 = CHUNK_CLAMP(world, z1, z);
|
||||
// x2 = CHUNK_CLAMP(world, x2, x);
|
||||
// y2 = CHUNK_CLAMP(world, y2, y);
|
||||
// z2 = CHUNK_CLAMP(world, z2, z);
|
||||
int boxes = 0;
|
||||
ulong pos = 0;
|
||||
chunk_t *chunk; // = &world->global;
|
||||
geometry_t **gptr;
|
||||
geometry_t *geom;
|
||||
if(listptr)
|
||||
*listptr = list;
|
||||
while(gptr = tbl_iter(&world->global_geom, &pos)) {
|
||||
geom = *gptr;
|
||||
if(box_intersects(&geom->collision, box)) {
|
||||
list[boxes++] = geom->collision;
|
||||
if(boxes == COLL_MAX)
|
||||
return boxes;
|
||||
}
|
||||
}
|
||||
for(int cx = x1; cx <= x2; cx++) {
|
||||
for(int cz = z1; cz <= z2; cz++) {
|
||||
for(int cy = y1; cy <= y2; cy++) {
|
||||
if(!(chunk = chunk_get(world, cx, cy, cz, 0)))
|
||||
continue;
|
||||
pos = 0;
|
||||
while(geom = tbl_iter(&chunk->obj_table, &pos)) {
|
||||
if(!geom->global && box_intersects(&geom->collision, box)) {
|
||||
list[boxes++] = geom->collision;
|
||||
if(boxes == COLL_MAX)
|
||||
return boxes;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return boxes;
|
||||
}
|
||||
|
||||
byte box_check_intersect(vec3 origin, vec3 dir, chunk_t *chunk, polygon_t *poly, float *dist) {
|
||||
vec3 vects[3];
|
||||
for(int n = 0; n < 3; n++) {
|
||||
VEC3_SET(vects[n], poly->vertices[n].pos X + (float)chunk->box.x1, poly->vertices[n].pos Y + (float)chunk->box.y1,
|
||||
poly->vertices[n].pos Z + (float)chunk->box.z1);
|
||||
}
|
||||
return glm_ray_triangle(origin, dir, vects[0], vects[1], vects[2], dist);
|
||||
}
|
||||
|
||||
ulong box_get_pointed(world_t *world, camera_t *cam, vec3 pos) {
|
||||
vec3 origin;
|
||||
ulong iter = 0;
|
||||
ulong id = 0;
|
||||
float dist;
|
||||
float mdist = 1000000.0f;
|
||||
chunk_t *chunk;
|
||||
geometry_t **gptr;
|
||||
geometry_t *geom;
|
||||
polygon_t *poly;
|
||||
int x = (int)NEG_OFFSET(cam->pos_x, CHUNK_SIZE);
|
||||
int y = (int)NEG_OFFSET(cam->pos_y, CHUNK_SIZE);
|
||||
int z = (int)NEG_OFFSET(cam->pos_z, CHUNK_SIZE);
|
||||
VEC3_SET(origin, (float)cam->pos_x, (float)cam->pos_y, (float)cam->pos_z);
|
||||
|
||||
while(gptr = tbl_iter(&world->global_geom, &iter)) {
|
||||
geom = *gptr;
|
||||
if(!(chunk = chunk_get(world, geom->chunk_x, geom->chunk_y, geom->chunk_z, 0)))
|
||||
continue;
|
||||
poly = &chunk->poly_pool[geom->polys];
|
||||
while(poly) {
|
||||
if(box_check_intersect(origin, cam->front, chunk, poly, &dist) && (dist < mdist)) {
|
||||
mdist = dist;
|
||||
id = geom->id;
|
||||
if(pos) {
|
||||
glm_vec3_scale(cam->front, dist, pos);
|
||||
glm_vec3_add(origin, pos, pos);
|
||||
}
|
||||
}
|
||||
poly = (poly->next == 0xffffffff) ? NULL : &chunk->poly_pool[poly->next];
|
||||
}
|
||||
}
|
||||
|
||||
for(int cx = -1; cx <= 1; cx++) {
|
||||
for(int cz = -1; cz <= 1; cz++) {
|
||||
for(int cy = -1; cy <= 1; cy++) {
|
||||
if(!(chunk = chunk_get(world, x + cx, y + cy, z + cz, 0)))
|
||||
continue;
|
||||
iter = 0;
|
||||
while(geom = tbl_iter(&chunk->obj_table, &iter)) {
|
||||
if(!geom->global) {
|
||||
poly = &chunk->poly_pool[geom->polys];
|
||||
while(poly) {
|
||||
if(box_check_intersect(origin, cam->front, chunk, poly, &dist) && (dist < mdist)) {
|
||||
mdist = dist;
|
||||
id = geom->id;
|
||||
if(pos) {
|
||||
glm_vec3_scale(cam->front, dist, pos);
|
||||
glm_vec3_add(origin, pos, pos);
|
||||
}
|
||||
}
|
||||
poly = (poly->next == 0xffffffff) ? NULL : &chunk->poly_pool[poly->next];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return id;
|
||||
}
|
101
buffer.h
Normal file
|
@ -0,0 +1,101 @@
|
|||
|
||||
int buf_init_int(byte dynamic, uint *vbo, uint *vao, const float *verts, uint size, int stride, va_list ap) {
|
||||
int elems;
|
||||
int pos;
|
||||
int idx = 0;
|
||||
glGenVertexArrays(1, vao);
|
||||
glGenBuffers(1, vbo);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, *vbo);
|
||||
glBufferData(GL_ARRAY_BUFFER, size, verts, dynamic ? GL_DYNAMIC_DRAW : GL_STATIC_DRAW);
|
||||
gdr.buf_mem += size;
|
||||
gdr.buf_peak = gdr.buf_mem > gdr.buf_peak ? gdr.buf_mem : gdr.buf_peak;
|
||||
glBindVertexArray(*vao);
|
||||
for(pos = 0; pos < stride; pos += elems) {
|
||||
elems = va_arg(ap, int);
|
||||
glVertexAttribPointer(idx, elems, GL_FLOAT, GL_FALSE, stride * sizeof(float), (void*)(pos * sizeof(float)));
|
||||
glEnableVertexAttribArray(idx++);
|
||||
}
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
return idx;
|
||||
}
|
||||
|
||||
void buf_init_sys(uint *vbo, uint *vao, const float *verts, uint size, int stride, ...) {
|
||||
va_list ap;
|
||||
va_start(ap, stride);
|
||||
buf_init_int(0, vbo, vao, verts, size, stride, ap);
|
||||
logd(LOG_GFX, STR_BUF_ILOADED, size, stride, *vbo, *vao);
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
buf_t *buf_init(byte dynamic, uint *vbo, uint *vao, const float *verts, uint size, int stride, ...) {
|
||||
va_list ap;
|
||||
va_start(ap, stride);
|
||||
int idx;
|
||||
buf_t *bind;
|
||||
sys_assert(bind = (buf_t*)tbl_push(&gdr.buffers));
|
||||
idx = buf_init_int(dynamic, vbo, vao, verts, size, stride, ap);
|
||||
bind->vao = vao;
|
||||
bind->vbo = vbo;
|
||||
bind->size = size;
|
||||
bind->stride = stride;
|
||||
bind->groups = idx;
|
||||
bind->dynamic = dynamic;
|
||||
gdr.buf_loaded += 1;
|
||||
logt(LOG_GFX, STR_BUF_LOADED, size, stride, *vbo, *vao);
|
||||
va_end(ap);
|
||||
return bind;
|
||||
}
|
||||
|
||||
void buf_data(buf_t *buf, const float *verts, uint size) {
|
||||
size *= ((uint)buf->stride) * sizeof(float);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, *(buf->vbo));
|
||||
glBufferData(GL_ARRAY_BUFFER, size, verts, buf->dynamic ? GL_DYNAMIC_DRAW : GL_STATIC_DRAW);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
if(buf->size != size) {
|
||||
logt(LOG_GFX, STR_BUF_RESIZED, *(buf->vbo), *(buf->vao), buf->size, size, buf->stride);
|
||||
gdr.buf_mem -= buf->size;
|
||||
gdr.buf_mem += buf->size = size;
|
||||
gdr.buf_peak = gdr.buf_mem > gdr.buf_peak ? gdr.buf_mem : gdr.buf_peak;
|
||||
}
|
||||
}
|
||||
|
||||
void buf_delete(uint *vbo, uint *vao) {
|
||||
if(*vbo) {
|
||||
glDeleteBuffers(1, vbo);
|
||||
glDeleteVertexArrays(1, vao);
|
||||
logd(LOG_GFX, STR_BUF_IUNLOADED, *vbo, *vao);
|
||||
*vbo = 0;
|
||||
*vao = 0;
|
||||
}
|
||||
}
|
||||
|
||||
byte buf_unload(buf_t *buf) {
|
||||
if(!(*(buf->vbo))) {
|
||||
return 0;
|
||||
}
|
||||
glDeleteBuffers(1, buf->vbo);
|
||||
glDeleteVertexArrays(1, buf->vao);
|
||||
gdr.buf_mem -= buf->size;
|
||||
logt(LOG_GFX, STR_BUF_UNLOADED, buf->size, buf->stride, *(buf->vbo), *(buf->vao));
|
||||
*(buf->vbo) = 0;
|
||||
*(buf->vao) = 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
void buf_remove(buf_t *buf) {
|
||||
if(buf_unload(buf)) {
|
||||
// tbl_pop(&gdr.buffers, buf);
|
||||
gdr.buf_loaded -= 1;
|
||||
}
|
||||
}
|
||||
|
||||
void buf_destroy(buf_t *buf) {
|
||||
if(buf_unload(buf)) {
|
||||
tbl_pop(&gdr.buffers, buf);
|
||||
gdr.buf_loaded -= 1;
|
||||
}
|
||||
}
|
||||
|
||||
int buf_clear() {
|
||||
return tbl_clear_func(&gdr.buffers, (clear_func*)buf_remove);
|
||||
}
|
1
build.txt
Normal file
|
@ -0,0 +1 @@
|
|||
3295
|
92
camera.h
Normal file
|
@ -0,0 +1,92 @@
|
|||
|
||||
void cam_calc_vec(camera_t *cam) {
|
||||
VEC3_SET(cam->front, cos(glm_rad(cam->yaw)) * cos(glm_rad(cam->pitch)), sin(glm_rad(cam->pitch)), sin(glm_rad(cam->yaw)) * cos(glm_rad(cam->pitch)))
|
||||
glm_vec3_normalize(cam->front);
|
||||
glm_vec3_cross(cam->front, cam->world_up, cam->right);
|
||||
glm_vec3_normalize(cam->right);
|
||||
glm_vec3_cross(cam->right, cam->front, cam->up);
|
||||
glm_vec3_normalize(cam->up);
|
||||
}
|
||||
|
||||
void cam_angle(camera_t *cam, float yaw, float pitch) {
|
||||
cam->yaw = yaw;
|
||||
cam->pitch = pitch;
|
||||
cam_calc_vec(cam);
|
||||
}
|
||||
|
||||
void cam_angle_ent(camera_t *cam, entity_t *ent) {
|
||||
cam->yaw = ent->yaw;
|
||||
cam->pitch = ent->pitch;
|
||||
cam_calc_vec(cam);
|
||||
}
|
||||
|
||||
void cam_pos(camera_t *cam, double x, double y, double z) {
|
||||
cam->pos_x = x;
|
||||
cam->pos_y = y;
|
||||
cam->pos_z = z;
|
||||
}
|
||||
|
||||
void cam_pos_ent(camera_t *cam, entity_t *ent, double fraction) {
|
||||
cam->pos_x = ent->last_x + (ent->pos_x - ent->last_x) * fraction;
|
||||
cam->pos_y = (ent->last_y + (ent->pos_y - ent->last_y) * fraction) + ent->eye;
|
||||
cam->pos_z = ent->last_z + (ent->pos_z - ent->last_z) * fraction;
|
||||
}
|
||||
|
||||
void cam_init(camera_t *cam, double x, double y, double z, float yaw, float pitch) {
|
||||
VEC3_SET(cam->world_up, 0.0f, 1.0f, 0.0f)
|
||||
cam_angle(cam, yaw, pitch);
|
||||
cam_pos(cam, x, y, z);
|
||||
}
|
||||
|
||||
void cam_swing(camera_t *cam, float x, float y) {
|
||||
// if(gdr.cam_fixed)
|
||||
// return;
|
||||
cam->yaw += x * sys.sensitivity * 0.1f;
|
||||
cam->pitch += y * sys.sensitivity * 0.1f;
|
||||
cam->yaw = fmodf(cam->yaw + 180.0f, 360.0f);
|
||||
cam->yaw = ((cam->yaw < 0.0f) ? (cam->yaw + 360.0f) : cam->yaw) - 180.0f;
|
||||
cam->pitch = CLAMP_VALUE(cam->pitch, -89.0f, 89.0f);
|
||||
cam_calc_vec(cam);
|
||||
}
|
||||
|
||||
void cam_zoom(camera_t *cam, float zoom) {
|
||||
// if(gdr.zoom_fixed)
|
||||
// return;
|
||||
cam->zoom += zoom;
|
||||
cam->zoom = CLAMP_VALUE(cam->zoom, 0.0f, 1.0f);
|
||||
}
|
||||
|
||||
void cam_rzoom(camera_t *cam) {
|
||||
cam->zoom = 0.0f;
|
||||
}
|
||||
|
||||
void cam_move_noclip(camera_t *cam, float delta, float speed, byte dir) {
|
||||
// if(gdr.pos_fixed)
|
||||
// return;
|
||||
float velo = speed * delta;
|
||||
vec3 pos;
|
||||
VEC3_SET(pos, cam->pos_x, cam->pos_y, cam->pos_z)
|
||||
switch(dir) {
|
||||
case DIR_LEFT:
|
||||
glm_vec3_muladds(cam->right, -velo, pos);
|
||||
break;
|
||||
case DIR_RIGHT:
|
||||
glm_vec3_muladds(cam->right, velo, pos);
|
||||
break;
|
||||
case DIR_DOWN:
|
||||
glm_vec3_muladds(cam->world_up, -velo, pos);
|
||||
break;
|
||||
case DIR_UP:
|
||||
glm_vec3_muladds(cam->world_up, velo, pos);
|
||||
break;
|
||||
case DIR_BACKWARD:
|
||||
glm_vec3_muladds(cam->front, -velo, pos);
|
||||
break;
|
||||
case DIR_FORWARD:
|
||||
glm_vec3_muladds(cam->front, velo, pos);
|
||||
break;
|
||||
}
|
||||
cam->pos_x = pos[0];
|
||||
cam->pos_y = pos[1];
|
||||
cam->pos_z = pos[2];
|
||||
}
|
24
compile.sh
Executable file
|
@ -0,0 +1,24 @@
|
|||
#!/bin/bash
|
||||
|
||||
BUILD_ID=1
|
||||
if [ -e build.txt ]; then
|
||||
BUILD_ID=$(cat build.txt)
|
||||
let BUILD_ID=BUILD_ID+1
|
||||
fi
|
||||
MODIFIED=0
|
||||
if [ -e skcblitz ]; then
|
||||
MODIFIED=$(date -r skcblitz +%s)
|
||||
fi
|
||||
for header in *.h *.c; do
|
||||
if [ $(date -r "$header" +%s) -gt $MODIFIED ]; then
|
||||
if gcc -rdynamic -g -DBUILD_DATE="\"$(date)\"" -DBUILD_SYS="\"$(uname -snrm)\"" -DBUILD_ID=$BUILD_ID -DBUILD_COMP="\"$(gcc --version | head -n 1)\"" -o skcblitz program.c -lm -lX11 -ldl -lasound -pthread; then
|
||||
echo -n $BUILD_ID > build.txt
|
||||
echo "Build $BUILD_ID"
|
||||
break;
|
||||
else
|
||||
exit 1;
|
||||
fi
|
||||
fi
|
||||
done
|
||||
set -x
|
||||
$@
|
453
console.h
Normal file
|
@ -0,0 +1,453 @@
|
|||
|
||||
#define logcu(fmt, args ...) logu(LOG_CON, fmt, args)
|
||||
#define logci(fmt, args ...) logi(LOG_CON, fmt, args)
|
||||
#define logcw(fmt, args ...) logw(LOG_CON, fmt, args)
|
||||
#define logce(fmt, args ...) loge(LOG_CON, fmt, args)
|
||||
|
||||
int str_tokenize(char *arg, char **args, const char *str) {
|
||||
// if(str[0] == 0) {
|
||||
// return 0;
|
||||
// }
|
||||
int pos = 0;
|
||||
int apos = 0;
|
||||
int argc = 0;
|
||||
int last = 0;
|
||||
byte space = 1;
|
||||
byte quote = 0;
|
||||
byte escape = 0;
|
||||
char c;
|
||||
while(c = str[pos++]) {
|
||||
if(escape) {
|
||||
escape = 0;
|
||||
switch(c) {
|
||||
case '\\':
|
||||
case ' ':
|
||||
case '"':
|
||||
arg[apos++] = c;
|
||||
break;
|
||||
default:
|
||||
logce(STR_PARSER_ESC_UNKNOWN, pos, c);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else if(c == '\\') {
|
||||
space = 0;
|
||||
escape = 1;
|
||||
}
|
||||
else if(c == '"') {
|
||||
space = 0;
|
||||
quote = !quote;
|
||||
last = pos;
|
||||
}
|
||||
else if(c == ' ' && !quote) {
|
||||
if(!space) {
|
||||
args[argc++] = arg;
|
||||
arg[apos++] = 0;
|
||||
arg += apos;
|
||||
apos = 0;
|
||||
}
|
||||
space = 1;
|
||||
}
|
||||
else {
|
||||
space = 0;
|
||||
arg[apos++] = c;
|
||||
}
|
||||
}
|
||||
if(escape) {
|
||||
logce(STR_PARSER_ESC_SHORT, pos);
|
||||
return 0;
|
||||
}
|
||||
if(quote) {
|
||||
logce(STR_PARSER_NO_QUOTE, last);
|
||||
return 0;
|
||||
}
|
||||
if(!space) {
|
||||
args[argc++] = arg;
|
||||
arg[apos] = 0;
|
||||
}
|
||||
return argc;
|
||||
}
|
||||
|
||||
ccmd_t *con_get(const char *key) {
|
||||
return (ccmd_t*)smap_get(&sys.ccmd_map, key);
|
||||
}
|
||||
|
||||
void con_exec(const char *line) {
|
||||
char str[64];
|
||||
int argc;
|
||||
char **argv;
|
||||
cvar_t *cv;
|
||||
ccmd_t *cmd;
|
||||
if(!(argc = str_tokenize(sys.con_tok, sys.con_arg, line)))
|
||||
return;
|
||||
argv = sys.con_arg;
|
||||
cv = cvar_get(argv[0]);
|
||||
if(cv && argc == 1) {
|
||||
cvar_format(cv, str);
|
||||
logcu("%s = %s", cv->name, str);
|
||||
return;
|
||||
}
|
||||
else if(cv && argc == 2) {
|
||||
if(cv->readonly) {
|
||||
logce(STR_CVAR_READONLY, cv->name);
|
||||
}
|
||||
else if(cvar_set(cv, argv[1], 0)) {
|
||||
cvar_format(cv, str);
|
||||
logcu("%s = %s", cv->name, str);
|
||||
}
|
||||
else {
|
||||
logce(STR_CVAR_INVALID, cv->name, argv[1]);
|
||||
}
|
||||
return;
|
||||
}
|
||||
else if(cv) {
|
||||
logce(STR_CVAR_MOREARGS, argc);
|
||||
return;
|
||||
}
|
||||
cmd = con_get(argv[0]);
|
||||
if(!cmd) {
|
||||
logce(STR_CVAR_CCMD_UNKNOWN, argv[0]);
|
||||
return;
|
||||
}
|
||||
if(--argc < cmd->min) {
|
||||
logce(STR_CCMD_LESSARGS, argv[0], cmd->min, argc);
|
||||
return;
|
||||
}
|
||||
else if(argc > cmd->max) {
|
||||
logce(STR_CCMD_MOREARGS, argv[0], cmd->max, argc);
|
||||
return;
|
||||
}
|
||||
logcu("# %s", line);
|
||||
cmd->func(cmd, (const char **)&argv[1], argc);
|
||||
}
|
||||
|
||||
void con_reset() {
|
||||
sys.log_len = sprintf(sys.con_buf, COL_NEON "*** " SYS_PROGRAM_FULL " ***");
|
||||
// for(int z = 0; z < sys.con_size; z++) {
|
||||
// sys.con_msgs[z].message = NULL;
|
||||
// }
|
||||
// sys.con_pos = 0;
|
||||
}
|
||||
|
||||
ccmd_t *con_add(const char *name, const char *args, ccmd_func *func, ushort min, ushort max) {
|
||||
ccmd_t *cmd = &sys.ccmds[sys.n_ccmds];
|
||||
cmd->func = func;
|
||||
cmd->args = args;
|
||||
cmd->min = min;
|
||||
cmd->max = max;
|
||||
cmd->id = sys.n_ccmds;
|
||||
cmd->name = name;
|
||||
sys.n_ccmds += 1;
|
||||
return cmd;
|
||||
}
|
||||
|
||||
void con_fmt_cvar(cvar_t *cv, char *str) {
|
||||
int pos;
|
||||
if(cv->type == CVAR_ENUM) {
|
||||
pos = sprintf(str, "%s "COL_DGRAY"["COL_GRAY"D "COL_CRIMSON"%s"COL_DGRAY"] ["COL_LGRAY, ((const char**)cv->aux_data)[cv->value], ((const char**)cv->aux_data)[cv->def]);
|
||||
for(int z = 0; z < cv->max; z++) {
|
||||
pos += sprintf(str+pos, z ? ", %s" : "%s", ((const char**)cv->aux_data)[z]);
|
||||
}
|
||||
pos += sprintf(str+pos, COL_DGRAY"]");
|
||||
}
|
||||
else {
|
||||
cvar_fmt[cv->type](str, cv->value);
|
||||
pos = strlen(str);
|
||||
pos += sprintf(str+pos, " "COL_DGRAY"["COL_GRAY"D "COL_CRIMSON);
|
||||
cvar_fmt[cv->type](str+pos, cv->def);
|
||||
pos += strlen(str+pos);
|
||||
pos += sprintf(str+pos, COL_DGRAY"]");
|
||||
if(cv->type == CVAR_INT)
|
||||
pos += sprintf(str+pos, " ["COL_LGRAY"%d .. %d"COL_DGRAY"]", cv->min, cv->max);
|
||||
else if(cv->type == CVAR_FLOAT)
|
||||
pos += sprintf(str+pos, " ["COL_LGRAY"%.3f .. %.3f"COL_DGRAY"]", cvar_itf(cv->min), cvar_itf(cv->max));
|
||||
}
|
||||
logcu("%s "COL_NEON"%s "COL_DGRAY"[%s"COL_DGRAY"]"COL_GRAY" = "COL_WHITE"%s%s", cvar_types[cv->type], cv->name, cvar_categories[cv->category], str, cv->readonly ? " "COL_DGRAY"["COL_RED"RO"COL_DGRAY"]" : "");
|
||||
}
|
||||
|
||||
void con_cmd_cvar(ccmd_t *cmd, const char **argv, int argc) {
|
||||
cvar_t *cv;
|
||||
char fmt[512];
|
||||
if(argc) {
|
||||
for(int z = 0; z < argc; z++) {
|
||||
cv = cvar_get(argv[z]);
|
||||
if(!cv) {
|
||||
logce(STR_CVAR_UNKNOWN, argv[z]);
|
||||
continue;
|
||||
}
|
||||
con_fmt_cvar(cv, fmt);
|
||||
}
|
||||
}
|
||||
else {
|
||||
int ro = 0;
|
||||
for(int z = 0; z < sys.n_cvars; z++) {
|
||||
cv = &sys.cvars[z];
|
||||
con_fmt_cvar(cv, fmt);
|
||||
ro += cv->readonly ? 1 : 0;
|
||||
}
|
||||
logcu(STR_CMD_CVARLIST, sys.n_cvars, ro);
|
||||
}
|
||||
}
|
||||
|
||||
void con_fmt_ccmd(ccmd_t *cmd, char *str) {
|
||||
logcu("%s "COL_NEON"%s "COL_DGRAY"["COL_LGRAY"%d .. %d"COL_DGRAY"]", cmd->name, cmd->args, cmd->min, cmd->max);
|
||||
}
|
||||
|
||||
void con_cmd_ccmd(ccmd_t *cmd, const char **argv, int argc) {
|
||||
ccmd_t *ccmd;
|
||||
char fmt[128];
|
||||
if(argc) {
|
||||
for(int z = 0; z < argc; z++) {
|
||||
ccmd = con_get(argv[z]);
|
||||
if(!ccmd) {
|
||||
logce(STR_CCMD_UNKNOWN, argv[z]);
|
||||
continue;
|
||||
}
|
||||
con_fmt_ccmd(ccmd, fmt);
|
||||
}
|
||||
}
|
||||
else {
|
||||
for(int z = 0; z < sys.n_ccmds; z++) {
|
||||
ccmd = &sys.ccmds[z];
|
||||
con_fmt_ccmd(ccmd, fmt);
|
||||
}
|
||||
logcu(STR_CMD_CCMDLIST, sys.n_ccmds);
|
||||
}
|
||||
}
|
||||
|
||||
void con_cmd_memdump(ccmd_t *cmd, const char **argv, int argc) {
|
||||
logcu("base : %12.3f MB (%5.2f %%), 1 block (%5.2f %%)", ((float)SYS_BASE) / 1024.0f / 1024.0f, ((float)SYS_BASE) / ((float)sys.mem_alloc) * 100.0f, 100.0f / ((float)sys.mem_blocks));
|
||||
for(int z = 0; z < MEM_CATS; z++) {
|
||||
logcu("%-10s: %12.3f MB (%5.2f %%), %6lld block%c (%5.2f %%)", mem_types[z], ((float)sys.mem_pool_sizes[z]) / 1024.0f / 1024.0f, ((float)sys.mem_pool_sizes[z]) / ((float)sys.mem_alloc) * 100.0f,
|
||||
sys.mem_pool_blocks[z], sys.mem_pool_blocks[z] == 1 ? ' ' : 's', ((float)sys.mem_pool_blocks[z]) / ((float)sys.mem_blocks) * 100.0f);
|
||||
}
|
||||
logcu("total : %12.3f MB (peak: %.3f MB), %lld blocks", ((float)sys.mem_alloc) / 1024.0f / 1024.0f, ((float)sys.mem_peak) / 1024.0f / 1024.0f, sys.mem_blocks);
|
||||
}
|
||||
|
||||
byte plr_queue(const char *dmxname, const char *drumname, const char **files, int count);
|
||||
void plr_end();
|
||||
|
||||
void con_cmd_play(ccmd_t *cmd, const char **argv, int argc) {
|
||||
const char *bank = NULL;
|
||||
const char *drum = NULL;
|
||||
int id = snd.mid_bank;
|
||||
if(argc) {
|
||||
if(!strcmp(argv[0], "-b")) {
|
||||
if(argc < 2) {
|
||||
logce(STR_CMD_ARGREQ, "-b");
|
||||
for(int z = 0; z < 32; z++) {
|
||||
logce("#%02d -- %s", z, z < 31 ? snd_banknames[z] : "[custom]");
|
||||
}
|
||||
return;
|
||||
}
|
||||
if(!str_parse_enum(argv[1], snd_banknames, 31, &id)) {
|
||||
bank = argv[1];
|
||||
}
|
||||
argv += 2;
|
||||
argc -= 2;
|
||||
}
|
||||
else if(!strcmp(argv[0], "-B")) {
|
||||
if(argc < 3) {
|
||||
logce(STR_CMD_ARGREQS, "-B", 2);
|
||||
return;
|
||||
}
|
||||
bank = argv[1];
|
||||
drum = argv[2];
|
||||
argv += 3;
|
||||
argc -= 3;
|
||||
}
|
||||
if(!argc) {
|
||||
logcu(STR_CMD_PLAY_BANKID, bank ? 31 : id);
|
||||
return;
|
||||
}
|
||||
if(plr_queue(bank ? bank : snd_bankfiles[id], drum, argv, argc))
|
||||
logcu(STR_CMD_PLAY_QUEUED, argc);
|
||||
}
|
||||
else {
|
||||
if(snd.mid_queued) {
|
||||
logcu(STR_CMD_PLAY_PLAYING, snd.mid_queued);
|
||||
for(int z = 0; z < snd.mid_queued; z++) {
|
||||
if(z != (snd.mid_queued - 1))
|
||||
snd.mid_queue[z+1][-1] = 0;
|
||||
logcu("%d. -- %s", z + 1, &(snd.mid_queue[z])[6]);
|
||||
if(z != (snd.mid_queued - 1))
|
||||
snd.mid_queue[z+1][-1] = '\n';
|
||||
}
|
||||
}
|
||||
else {
|
||||
logcu(STR_CMD_PLAY_STOPPED, NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void con_cmd_stop(ccmd_t *cmd, const char **argv, int argc) {
|
||||
if(snd.mid_queued)
|
||||
logcu(STR_CMD_PLAY_ENDED, NULL);
|
||||
else
|
||||
logcu(STR_CMD_PLAY_STOPPED, NULL);
|
||||
plr_end();
|
||||
}
|
||||
|
||||
#define theme_add(str) \
|
||||
style = (style_t*)tbl_push(&sys.themes);\
|
||||
style->name = str;
|
||||
|
||||
#define theme_window(bdrtop, bdrbtm, top, btm, text) \
|
||||
style->wbrdr_top = bdrtop;\
|
||||
style->wbrdr_btm = bdrbtm;\
|
||||
style->win_top = top;\
|
||||
style->win_btm = btm;\
|
||||
style->text_win = text;
|
||||
|
||||
#define theme_border(top, btm, size) \
|
||||
style->brdr_top = top;\
|
||||
style->brdr_btm = btm;\
|
||||
style->border = size;
|
||||
|
||||
#define theme_background(top, btm) \
|
||||
style->bg_top = top;\
|
||||
style->bg_btm = btm;
|
||||
|
||||
#define theme_base(top, btm, text, label) \
|
||||
style->fill_top = top;\
|
||||
style->fill_btm = btm;\
|
||||
style->text_base = text;\
|
||||
style->text_label = label;
|
||||
|
||||
#define theme_field(top, btm, text) \
|
||||
style->field_top = top;\
|
||||
style->field_btm = btm;\
|
||||
style->text_field = text;
|
||||
|
||||
#define theme_slider(handle) \
|
||||
style->slider_width = handle;
|
||||
|
||||
#define theme_select(presstop, pressbtm, hovertop, hoverbtm, sel, cur) \
|
||||
style->press_top = presstop;\
|
||||
style->press_btm = pressbtm;\
|
||||
style->hover_top = hovertop;\
|
||||
style->hover_btm = hoverbtm;\
|
||||
style->select = sel;\
|
||||
style->cursor = cur;
|
||||
|
||||
void con_cmd_themedump(ccmd_t *cmd, const char **argv, int argc) {
|
||||
logcu("theme_add(STR_THEME_%s);", argc ? argv[0] : "");
|
||||
logcu("theme_window(0x%06x, 0x%06x, 0x%06x, 0x%06x, 0x%06x);", sys.style.wbrdr_top & 0xffffff, sys.style.wbrdr_btm & 0xffffff, sys.style.win_top & 0xffffff, sys.style.win_btm & 0xffffff, sys.style.text_win & 0xffffff);
|
||||
logcu("theme_border(0x%06x, 0x%06x, %d);", sys.style.brdr_top & 0xffffff, sys.style.brdr_btm & 0xffffff, sys.style.border);
|
||||
logcu("theme_background(0x%06x, 0x%06x);", sys.style.bg_top & 0xffffff, sys.style.bg_btm & 0xffffff);
|
||||
logcu("theme_base(0x%06x, 0x%06x, 0x%06x, 0x%06x);", sys.style.fill_top & 0xffffff, sys.style.fill_btm & 0xffffff, sys.style.text_base & 0xffffff, sys.style.text_label & 0xffffff);
|
||||
logcu("theme_field(0x%06x, 0x%06x, 0x%06x);", sys.style.field_top & 0xffffff, sys.style.field_btm & 0xffffff, sys.style.text_field & 0xffffff);
|
||||
logcu("theme_slider(%d);", sys.style.slider_width);
|
||||
logcu("theme_select(0x%08x, 0x%08x, 0x%08x, 0x%08x, 0x%08x, 0x%08x);", sys.style.press_top, sys.style.press_btm, sys.style.hover_top, sys.style.hover_btm, sys.style.select, sys.style.cursor);
|
||||
}
|
||||
|
||||
void con_reg() {
|
||||
con_add("cvar", "[cvar ...]", con_cmd_cvar, 0, CCMD_UNLIMITED);
|
||||
con_add("ccmd", "[ccmd ...]", con_cmd_ccmd, 0, CCMD_UNLIMITED);
|
||||
con_add("memdump", "", con_cmd_memdump, 0, 0);
|
||||
con_add("play", "[-b <bank|id> | -B <bank> <drum>] [midi ...]", con_cmd_play, 0, CCMD_UNLIMITED);
|
||||
con_add("stop", "", con_cmd_stop, 0, 0);
|
||||
con_add("themedump", "[id]", con_cmd_themedump, 0, 1);
|
||||
}
|
||||
|
||||
void con_init() {
|
||||
ccmd_t *cmd;
|
||||
con_reg();
|
||||
smap_init(&sys.ccmd_map, 1, MEM_SYSTEM);
|
||||
for(int z = 0; z < sys.n_ccmds; z++) {
|
||||
cmd = &sys.ccmds[z];
|
||||
smap_put(&sys.ccmd_map, cmd->name, cmd);
|
||||
}
|
||||
}
|
||||
|
||||
void con_end() {
|
||||
smap_clear(&sys.ccmd_map);
|
||||
}
|
||||
|
||||
void con_resize(int size) {
|
||||
for(int z = sys.hud_size; z < size; z++) {
|
||||
sys.hud_msgs[z].message = NULL;
|
||||
}
|
||||
sys.hud_size = size;
|
||||
if(sys.hud_pos >= sys.hud_size)
|
||||
sys.hud_pos = 0;
|
||||
}
|
||||
|
||||
gui_t *gui_get(window_t *win, int id);
|
||||
void gui_update_text(gui_t *elem);
|
||||
void gui_text_update_cur(gui_t *elem, int offset, byte shift);
|
||||
|
||||
void log_sys(const char *msg, int length, int offset) {
|
||||
char c;
|
||||
if(sys.con_timestamps ^ 1) {
|
||||
length -= offset;
|
||||
msg += offset;
|
||||
offset = 0;
|
||||
}
|
||||
if((sys.log_len + length + 2) > CON_BUF) {
|
||||
offset = (length + 2) > 1024 ? (length + 2) : 1024;
|
||||
while(c = sys.con_buf[offset++]) {
|
||||
if(c == '\n')
|
||||
break;
|
||||
}
|
||||
offset -= c ? 0 : 1;
|
||||
sys.log_len -= offset;
|
||||
memmove(sys.con_buf, &sys.con_buf[offset], sys.log_len);
|
||||
}
|
||||
sys.con_buf[sys.log_len] = '\n';
|
||||
sys.log_len += 1;
|
||||
memcpy(&sys.con_buf[sys.log_len], msg, length);
|
||||
sys.log_len += length;
|
||||
sys.con_buf[sys.log_len] = 0;
|
||||
if(sys.console && sys.console->open) {
|
||||
gui_t *elem = gui_get(sys.console, 5);
|
||||
if(sys.con_autoscroll)
|
||||
elem->sel_start = elem->sel_end = elem->sel_drag = sys.log_len;
|
||||
gui_update_text(elem);
|
||||
if(elem->sel_start >= 0)
|
||||
gui_text_update_cur(elem, elem->sel_start, 1);
|
||||
}
|
||||
}
|
||||
|
||||
void log_hud(window_t *win, const char *fmt, ...) {
|
||||
conmsg_t *con;
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
int length = vsnprintf(sys.log_buf, LOG_BUF, fmt, ap);
|
||||
if((sys.hud_len + length + 2) > HUD_BUF) {
|
||||
char c;
|
||||
int offset = (length + 2) > 1024 ? (length + 2) : 1024;
|
||||
while(c = sys.hud_buf[offset++]) {
|
||||
if(c == '\n')
|
||||
break;
|
||||
}
|
||||
offset -= c ? 0 : 1;
|
||||
sys.hud_len -= offset;
|
||||
memmove(sys.hud_buf, &sys.hud_buf[offset], sys.hud_len);
|
||||
for(int z = 0; z < sys.hud_size; z++) {
|
||||
con = &sys.hud_msgs[z];
|
||||
if(con->message) {
|
||||
if((con->offset -= offset) < 0)
|
||||
con->message = NULL;
|
||||
else
|
||||
con->message -= offset;
|
||||
}
|
||||
}
|
||||
}
|
||||
sys.hud_buf[sys.hud_len] = '\n';
|
||||
sys.hud_len += 1;
|
||||
memcpy(&sys.hud_buf[sys.hud_len], sys.log_buf, length);
|
||||
if(sys.hud_size) {
|
||||
con = &sys.hud_msgs[sys.hud_pos];
|
||||
con->message = &sys.hud_buf[sys.hud_len];
|
||||
con->offset = sys.hud_len;
|
||||
con->length = length;
|
||||
con->time = sys.tmr_current;
|
||||
con->window = win;
|
||||
if(++(sys.hud_pos) >= sys.hud_size)
|
||||
sys.hud_pos = 0;
|
||||
}
|
||||
sys.hud_len += length;
|
||||
sys.hud_buf[sys.hud_len] = 0;
|
||||
va_end(ap);
|
||||
}
|
681
cvar.h
Normal file
|
@ -0,0 +1,681 @@
|
|||
|
||||
int cvar_fti(float f) {
|
||||
return *((int*)&f);
|
||||
}
|
||||
|
||||
float cvar_itf(int i) {
|
||||
return *((float*)&i);
|
||||
}
|
||||
|
||||
void cvar_fnc_void(cvar_t *cv, int value) {
|
||||
;
|
||||
}
|
||||
|
||||
void cvar_fnc_bool(cvar_t *cv, int value) {
|
||||
*((byte*)cv->data) = (byte)value;
|
||||
}
|
||||
|
||||
void cvar_fnc_int(cvar_t *cv, int value) {
|
||||
*((int*)cv->data) = value;
|
||||
}
|
||||
|
||||
void cvar_fnc_float(cvar_t *cv, int value) {
|
||||
*((float*)cv->data) = cvar_itf(value);
|
||||
}
|
||||
|
||||
void cvar_fnc_double(cvar_t *cv, int value) {
|
||||
*((double*)cv->data) = (double)cvar_itf(value);
|
||||
}
|
||||
|
||||
void cvar_fnc_color(cvar_t *cv, int value) {
|
||||
*((uint*)cv->data) = (uint)value;
|
||||
}
|
||||
|
||||
void cvar_fnc_fcolor(cvar_t *cv, int value) {
|
||||
((float*)cv->data)[0] = ((float)((uint)((value >> 16) & 0xff))) * 255.0f;
|
||||
((float*)cv->data)[1] = ((float)((uint)((value >> 8) & 0xff))) * 255.0f;
|
||||
((float*)cv->data)[2] = ((float)((uint)(value & 0xff))) * 255.0f;
|
||||
}
|
||||
|
||||
void cvar_fnc_scolor(cvar_t *cv, int value) {
|
||||
*((uint*)cv->data) = ((uint)value) | 0xff000000;
|
||||
}
|
||||
|
||||
void cvar_fnc_ccolor(cvar_t *cv, int value) {
|
||||
*((uint*)cv->data) = ((uint)value) | ((*((uint*)cv->data)) & 0xff000000);
|
||||
}
|
||||
|
||||
void cvar_fnc_acolor(cvar_t *cv, int value) {
|
||||
*((uint*)cv->data) = ((uint)(float)(cvar_itf(value) * 255.0f)) | ((*((uint*)cv->data)) & 0x00ffffff);
|
||||
}
|
||||
|
||||
void cvar_fnc_bind(cvar_t *cv, int value) {
|
||||
((bind_t*)cv->data)->key = value;
|
||||
}
|
||||
|
||||
cvar_t *cvar_add(const char *name, cvar_func *func, void *data, void *aux_data, int def, int min, int max, byte type, byte category, byte readonly, byte startup) {
|
||||
cvar_t *cv = &sys.cvars[sys.n_cvars];
|
||||
cv->func = func;
|
||||
cv->data = data;
|
||||
cv->aux_data = aux_data;
|
||||
cv->value = cv->def = def;
|
||||
cv->min = min;
|
||||
cv->max = max;
|
||||
cv->id = sys.n_cvars;
|
||||
cv->readonly = readonly;
|
||||
cv->startup = startup;
|
||||
cv->type = type;
|
||||
cv->category = category;
|
||||
cv->name = name;
|
||||
sys.n_cvars += 1;
|
||||
return cv;
|
||||
}
|
||||
|
||||
cvar_t *cvar_add_bool(const char *name, byte category, byte *data, byte def) {
|
||||
cvar_t *cv = cvar_add(name, cvar_fnc_bool, data, NULL, (int)def, 0, 0, CVAR_BOOL, category, 0, 1);
|
||||
if(data)
|
||||
*data = def;
|
||||
return cv;
|
||||
}
|
||||
|
||||
cvar_t *cvar_add_sbool(const char *name, byte category, cvar_func *func, byte *data, byte def, byte startup) {
|
||||
cvar_t *cv = cvar_add(name, func, data, NULL, (int)def, 0, 0, CVAR_BOOL, category, 0, startup);
|
||||
if(data)
|
||||
*data = def;
|
||||
return cv;
|
||||
}
|
||||
|
||||
cvar_t *cvar_add_wbool(const char *name, byte category, cvar_func *func, byte def) {
|
||||
return cvar_add(name, func, NULL, NULL, (int)def, 0, 0, CVAR_BOOL, category, 0, 0);
|
||||
}
|
||||
|
||||
cvar_t *cvar_add_int(const char *name, byte category, int *data, int def, int min, int max) {
|
||||
cvar_t *cv = cvar_add(name, cvar_fnc_int, data, NULL, def, min, max, CVAR_INT, category, 0, 1);
|
||||
if(data)
|
||||
*data = def;
|
||||
return cv;
|
||||
}
|
||||
|
||||
cvar_t *cvar_add_sint(const char *name, byte category, cvar_func *func, int *data, int def, int min, int max, byte startup) {
|
||||
cvar_t *cv = cvar_add(name, func, data, NULL, def, min, max, CVAR_INT, category, 0, startup);
|
||||
if(data)
|
||||
*data = def;
|
||||
return cv;
|
||||
}
|
||||
|
||||
cvar_t *cvar_add_byte(const char *name, byte category, byte *data, byte def, byte min, byte max) {
|
||||
cvar_t *cv = cvar_add(name, cvar_fnc_bool, data, NULL, (int)def, (int)min, (int)max, CVAR_INT, category, 0, 1);
|
||||
if(data)
|
||||
*data = def;
|
||||
return cv;
|
||||
}
|
||||
|
||||
cvar_t *cvar_add_rint(const char *name, byte category, int def, int min, int max) {
|
||||
return cvar_add(name, cvar_fnc_void, NULL, NULL, def, min, max, CVAR_INT, category, 1, 0);
|
||||
}
|
||||
|
||||
cvar_t *cvar_add_wint(const char *name, byte category, cvar_func *func, int def, int min, int max) {
|
||||
return cvar_add(name, func, NULL, NULL, def, min, max, CVAR_INT, category, 0, 0);
|
||||
}
|
||||
|
||||
cvar_t *cvar_add_float(const char *name, byte category, float *data, float def, float min, float max) {
|
||||
cvar_t *cv = cvar_add(name, cvar_fnc_float, data, NULL, cvar_fti(def), cvar_fti(min), cvar_fti(max), CVAR_FLOAT, category, 0, 1);
|
||||
if(data)
|
||||
*data = def;
|
||||
return cv;
|
||||
}
|
||||
|
||||
cvar_t *cvar_add_sfloat(const char *name, byte category, cvar_func *func, float *data, float def, float min, float max, byte startup) {
|
||||
cvar_t *cv = cvar_add(name, func, data, NULL, cvar_fti(def), cvar_fti(min), cvar_fti(max), CVAR_FLOAT, category, 0, startup);
|
||||
if(data)
|
||||
*data = def;
|
||||
return cv;
|
||||
}
|
||||
|
||||
cvar_t *cvar_add_double(const char *name, byte category, double *data, float def, float min, float max) {
|
||||
cvar_t *cv = cvar_add(name, cvar_fnc_double, data, NULL, cvar_fti(def), cvar_fti(min), cvar_fti(max), CVAR_FLOAT, category, 0, 1);
|
||||
if(data)
|
||||
*data = (double)def;
|
||||
return cv;
|
||||
}
|
||||
|
||||
cvar_t *cvar_add_benum(const char *name, byte category, byte *data, const char **names, byte def, int states) {
|
||||
cvar_t *cv = cvar_add(name, cvar_fnc_bool, data, names, (int)def, 0, states, CVAR_ENUM, category, 0, 1);
|
||||
if(data)
|
||||
*data = def;
|
||||
return cv;
|
||||
}
|
||||
|
||||
cvar_t *cvar_add_sbenum(const char *name, byte category, cvar_func *func, byte *data, const char **names, byte def, int states, byte startup) {
|
||||
cvar_t *cv = cvar_add(name, func, data, names, (int)def, 0, states, CVAR_ENUM, category, 0, startup);
|
||||
if(data)
|
||||
*data = def;
|
||||
return cv;
|
||||
}
|
||||
|
||||
cvar_t *cvar_add_ienum(const char *name, byte category, int *data, const char **names, int def, int states) {
|
||||
cvar_t *cv = cvar_add(name, cvar_fnc_int, data, names, def, 0, states, CVAR_ENUM, category, 0, 1);
|
||||
if(data)
|
||||
*data = def;
|
||||
return cv;
|
||||
}
|
||||
|
||||
cvar_t *cvar_add_color(const char *name, byte category, uint *data, uint def) {
|
||||
cvar_t *cv = cvar_add(name, cvar_fnc_scolor, data, NULL, (int)def, 0, 0, CVAR_COLOR, category, 0, 1);
|
||||
if(data)
|
||||
*data = def | 0xff000000;
|
||||
return cv;
|
||||
}
|
||||
|
||||
cvar_t *cvar_add_scolor(const char *name, byte category, cvar_func *func, uint *data, uint def, byte startup) {
|
||||
cvar_t *cv = cvar_add(name, func, data, NULL, (int)def, 0, 0, CVAR_COLOR, category, 0, startup);
|
||||
if(data)
|
||||
*data = def | 0xff000000;
|
||||
return cv;
|
||||
}
|
||||
|
||||
cvar_t *cvar_add_acolor(const char *name, byte category, uint *data, uint def) {
|
||||
cvar_t *cv = cvar_add(name, cvar_fnc_color, data, NULL, (int)def, 0, 0, CVAR_COLOR_ALPHA, category, 0, 1);
|
||||
if(data)
|
||||
*data = def;
|
||||
return cv;
|
||||
}
|
||||
|
||||
cvar_t *cvar_add_key(const char *name, byte bind, int def) {
|
||||
cvar_t *cv = cvar_add(name, cvar_fnc_bind, &sys.binds[bind], NULL, def, 0, 0, CVAR_KEY, CVAR_BIND, 0, 1);
|
||||
sys.binds[bind].key = def;
|
||||
return cv;
|
||||
}
|
||||
|
||||
void cvar_fmt_bool(char *str, int value) {
|
||||
sprintf(str, value ? "true" : "false");
|
||||
}
|
||||
|
||||
void cvar_fmt_int(char *str, int value) {
|
||||
sprintf(str, "%d", value);
|
||||
}
|
||||
|
||||
void cvar_fmt_float(char *str, int value) {
|
||||
sprintf(str, "%.3f", cvar_itf(value));
|
||||
}
|
||||
|
||||
void cvar_fmt_color(char *str, int value) {
|
||||
sprintf(str, "%06x", (uint)value);
|
||||
}
|
||||
|
||||
void cvar_fmt_acolor(char *str, int value) {
|
||||
sprintf(str, "%08x", (uint)value);
|
||||
}
|
||||
|
||||
void cvar_fmt_key(char *str, int value) {
|
||||
if(value == 0) {
|
||||
sprintf(str, "none");
|
||||
}
|
||||
else if(value >= -SCROLL_RIGHT && value <= -MOUSE_LEFT) {
|
||||
sprintf(str, key_names[KEY_MOUSE_OFFSET - (value + MOUSE_LEFT)]);
|
||||
}
|
||||
else if(value >= KEYSYM_0 && value <= KEYSYM_9) {
|
||||
sprintf(str, "%d", value - KEYSYM_0);
|
||||
}
|
||||
else if(value >= KEYSYM_A && value <= KEYSYM_Z) {
|
||||
sprintf(str, "%c", 'a' + (char)(value - KEYSYM_A));
|
||||
}
|
||||
else if(value >= KEYSYM_F1 && value <= KEYSYM_F12) {
|
||||
sprintf(str, "f%d", 1 + value - KEYSYM_F1);
|
||||
}
|
||||
else if(value >= KEYSYM_KP_0 && value <= KEYSYM_KP_9) {
|
||||
sprintf(str, "kp%d", value - KEYSYM_KP_0);
|
||||
}
|
||||
else if(value >= KEYSYM_FIRST && value <= KEYSYM_LAST) {
|
||||
sprintf(str, key_names[value - KEYSYM_FIRST]);
|
||||
}
|
||||
else {
|
||||
sprintf(str, "#%d", value);
|
||||
}
|
||||
}
|
||||
|
||||
static const cvar_fmt_func cvar_fmt[] = {cvar_fmt_bool, cvar_fmt_int, cvar_fmt_float, NULL, cvar_fmt_color, cvar_fmt_acolor, cvar_fmt_key};
|
||||
|
||||
byte cvar_parse_bool(const char *str, int *value) {
|
||||
if(str_eq_lower("1", str) || str_eq_lower("true", str) || str_eq_lower("on", str) || str_eq_lower("yes", str) || str_eq_lower("y", str)) {
|
||||
*value = 1;
|
||||
return 1;
|
||||
}
|
||||
else if(str_eq_lower("0", str) || str_eq_lower("false", str) || str_eq_lower("off", str) || str_eq_lower("no", str) || str_eq_lower("n", str)) {
|
||||
*value = 0;
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
byte cvar_parse_int(const char *str, int *value) {
|
||||
return str_parse_int(str, value, 0);
|
||||
}
|
||||
|
||||
byte cvar_parse_float(const char *str, int *value) {
|
||||
errno = 0;
|
||||
float f = strtof(str, NULL);
|
||||
if(errno)
|
||||
return 0;
|
||||
*value = cvar_fti(f);
|
||||
return 1;
|
||||
}
|
||||
|
||||
byte cvar_parse_color(const char *str, int *value) {
|
||||
int c;
|
||||
if((!str_parse_int(str, &c, -16)) || (c & 0xff000000))
|
||||
return 0;
|
||||
*value = c;
|
||||
return 1;
|
||||
}
|
||||
|
||||
byte cvar_parse_acolor(const char *str, int *value) {
|
||||
return str_parse_int(str, value, -16);
|
||||
}
|
||||
|
||||
byte cvar_parse_key(const char *str, int *value) {
|
||||
int comp;
|
||||
int max = 0;
|
||||
int best = 0;
|
||||
if(str[0] >= '0' && str[0] <= '9' && !(str[1])) {
|
||||
*value = (str[0] - '0') + KEYSYM_0;
|
||||
return 1;
|
||||
}
|
||||
else if(str[0] >= 'a' && str[0] <= 'z' && !(str[1])) {
|
||||
*value = (str[0] - 'a') + KEYSYM_A;
|
||||
return 1;
|
||||
}
|
||||
else if(str[0] >= 'A' && str[0] <= 'Z' && !(str[1])) {
|
||||
*value = (str[0] - 'A') + KEYSYM_A;
|
||||
return 1;
|
||||
}
|
||||
else if((str[0] == '#') && str[1] && str_parse_int(str+1, value, 10)) {
|
||||
return 1;
|
||||
}
|
||||
else if((str_lower(str[0]) == 'f') && str[1] && str_parse_int(str+1, &comp, 10) && (comp >= 1) && (comp <= 25)) {
|
||||
*value = (comp - 1) + KEYSYM_F1;
|
||||
return 1;
|
||||
}
|
||||
else if((str_lower(str[0]) == 'k') && (str_lower(str[1]) == 'p') && (str[2] >= '0') && (str[2] <= '9') && !(str[3])) {
|
||||
*value = (str[2] - '0') + KEYSYM_KP_0;
|
||||
return 1;
|
||||
}
|
||||
else if(str_eq_lower("none", str)) {
|
||||
*value = 0;
|
||||
return 1;
|
||||
}
|
||||
for(int z = 0; z < KEY_MOUSE_OFFSET + SCROLL_RIGHT; z++) {
|
||||
if((comp = str_cmp_lower(key_names[z], str)) > best) {
|
||||
max = comp;
|
||||
best = z;
|
||||
}
|
||||
}
|
||||
if(max) {
|
||||
*value = (best >= KEY_MOUSE_OFFSET) ? -(MOUSE_LEFT + best - KEY_MOUSE_OFFSET) : (KEYSYM_FIRST + best);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const cvar_parse_func cvar_parse[] = {cvar_parse_bool, cvar_parse_int, cvar_parse_float, NULL, cvar_parse_color, cvar_parse_acolor, cvar_parse_key};
|
||||
|
||||
cvar_t *cvar_get(const char *key) {
|
||||
return (cvar_t*)smap_get(&sys.cvar_map, key);
|
||||
}
|
||||
|
||||
byte cvar_set(cvar_t *cv, const char *str, byte startup) {
|
||||
if((cv->type == CVAR_ENUM) ? str_parse_enum(str, (const char**)cv->aux_data, cv->max, &cv->value) : cvar_parse[cv->type](str, &cv->value)) {
|
||||
if(cv->type == CVAR_INT)
|
||||
cv->value = CLAMP_VALUE(cv->value, cv->min, cv->max);
|
||||
else if(cv->type == CVAR_FLOAT)
|
||||
cv->value = cvar_fti(CLAMP_VALUE(cvar_itf(cv->value), cvar_itf(cv->min), cvar_itf(cv->max)));
|
||||
if((!startup) || cv->startup)
|
||||
cv->func(cv, cv->value);
|
||||
sys.cfg_dirty |= startup ^ 1;
|
||||
return 1;
|
||||
}
|
||||
else {
|
||||
sys.cfg_dirty |= startup;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
void cvar_format(cvar_t *cv, char *str) {
|
||||
if(cv->type == CVAR_ENUM) {
|
||||
sprintf(str, "%s", ((const char**)cv->aux_data)[cv->value]);
|
||||
}
|
||||
else {
|
||||
cvar_fmt[cv->type](str, cv->value);
|
||||
}
|
||||
}
|
||||
|
||||
byte cvar_byte(const char *name) {
|
||||
return (byte)cvar_get(name)->value;
|
||||
}
|
||||
|
||||
int cvar_int(const char *name) {
|
||||
return cvar_get(name)->value;
|
||||
}
|
||||
|
||||
float cvar_float(const char *name) {
|
||||
return cvar_itf(cvar_get(name)->value);
|
||||
}
|
||||
|
||||
uint cvar_color(const char *name) {
|
||||
return (uint)cvar_get(name)->value;
|
||||
}
|
||||
|
||||
int cvar_key(byte bind) {
|
||||
return sys.cvars[bind].value;
|
||||
}
|
||||
|
||||
int cvar_defkey(byte bind) {
|
||||
return sys.cvars[bind].def;
|
||||
}
|
||||
|
||||
void cvar_sdef(cvar_t *cv) {
|
||||
cv->value = cv->def;
|
||||
cv->func(cv, cv->value);
|
||||
sys.cfg_dirty = 1;
|
||||
}
|
||||
|
||||
void cvar_setdef(const char *name) {
|
||||
cvar_sdef(cvar_get(name));
|
||||
}
|
||||
|
||||
void cvar_str(const char *name, char *str) {
|
||||
cvar_format(cvar_get(name), str);
|
||||
}
|
||||
|
||||
void cvar_sbool(cvar_t *cv, byte value) {
|
||||
cv->value = (int)value;
|
||||
cv->func(cv, cv->value);
|
||||
sys.cfg_dirty = 1;
|
||||
}
|
||||
|
||||
void cvar_setbool(const char *name, byte value) {
|
||||
cvar_sbool(cvar_get(name), value);
|
||||
}
|
||||
|
||||
void cvar_toggle(const char *name) {
|
||||
cvar_t *cv = cvar_get(name);
|
||||
cv->value ^= 1;
|
||||
cv->func(cv, cv->value);
|
||||
sys.cfg_dirty = 1;
|
||||
}
|
||||
|
||||
void cvar_sint(cvar_t *cv, int value) {
|
||||
cv->value = value;
|
||||
cv->func(cv, cv->value);
|
||||
sys.cfg_dirty = 1;
|
||||
}
|
||||
|
||||
void cvar_setint(const char *name, int value) {
|
||||
cvar_sint(cvar_get(name), value);
|
||||
}
|
||||
|
||||
void cvar_sfloat(cvar_t *cv, float value) {
|
||||
cv->value = cvar_fti(value);
|
||||
cv->func(cv, cv->value);
|
||||
sys.cfg_dirty = 1;
|
||||
}
|
||||
|
||||
void cvar_setfloat(const char *name, float value) {
|
||||
cvar_sfloat(cvar_get(name), value);
|
||||
}
|
||||
|
||||
void cvar_scolor(cvar_t *cv, uint value) {
|
||||
cv->value = (int)value;
|
||||
cv->func(cv, cv->value);
|
||||
sys.cfg_dirty = 1;
|
||||
}
|
||||
|
||||
void cvar_skey(byte bind, int value) {
|
||||
cvar_t *cv = &sys.cvars[bind];
|
||||
cv->value = (int)value;
|
||||
cv->func(cv, cv->value);
|
||||
sys.cfg_dirty = 1;
|
||||
}
|
||||
|
||||
byte cvar_sstr(cvar_t *cv, const char *value) {
|
||||
return cvar_set(cv, value, 0);
|
||||
}
|
||||
|
||||
// void win_full(byte full);
|
||||
|
||||
// void cvar_fnc_full(cvar_t *cv, int value) {
|
||||
// win_full(value);
|
||||
// }
|
||||
|
||||
void win_sync(int sync);
|
||||
|
||||
void cvar_fnc_sync(cvar_t *cv, int value) {
|
||||
win_sync(value);
|
||||
}
|
||||
|
||||
void cvar_fnc_dlight(cvar_t *cv, int value) {
|
||||
light_setup(value);
|
||||
}
|
||||
|
||||
void tick_target(float tps);
|
||||
|
||||
void cvar_fnc_ticktarget(cvar_t *cv, int value) {
|
||||
tick_target(cvar_itf(value));
|
||||
}
|
||||
|
||||
void cvar_fnc_tex(cvar_t *cv, int value) {
|
||||
cvar_fnc_bool(cv, value);
|
||||
tex_config();
|
||||
}
|
||||
|
||||
void cvar_fnc_ftex(cvar_t *cv, int value) {
|
||||
cvar_fnc_float(cv, value);
|
||||
tex_config();
|
||||
}
|
||||
|
||||
void con_resize(int size);
|
||||
|
||||
void cvar_fnc_consize(cvar_t *cv, int value) {
|
||||
con_resize(value);
|
||||
}
|
||||
|
||||
void plr_debug(byte debug);
|
||||
void plr_volume(byte channel, ushort volume);
|
||||
|
||||
void cvar_fnc_middebug(cvar_t *cv, int value) {
|
||||
plr_debug((byte)value);
|
||||
}
|
||||
|
||||
void cvar_fnc_volume(cvar_t *cv, int value) {
|
||||
plr_volume((byte)(int)(cv->id - cvar_get(snd_cvar_volume[0])->id), (ushort)(cvar_itf(value) * 32767.0f));
|
||||
}
|
||||
|
||||
void cvar_fnc_sound(cvar_t *cv, int value) {
|
||||
}
|
||||
|
||||
void gfx_back_color(uint color);
|
||||
|
||||
void cvar_fnc_clight(cvar_t *cv, int value) {
|
||||
gfx_back_color(0xff000000 | (uint)value);
|
||||
}
|
||||
|
||||
void cvar_reg() {
|
||||
#include "vars.h"
|
||||
}
|
||||
|
||||
void theme_reg() {
|
||||
style_t *style;
|
||||
|
||||
#define theme_add(str) \
|
||||
style = (style_t*)tbl_push(&sys.themes);\
|
||||
style->name = str;
|
||||
|
||||
#define theme_window(bdrtop, bdrbtm, top, btm, text) \
|
||||
style->wbrdr_top = bdrtop;\
|
||||
style->wbrdr_btm = bdrbtm;\
|
||||
style->win_top = top;\
|
||||
style->win_btm = btm;\
|
||||
style->text_win = text;
|
||||
|
||||
#define theme_border(top, btm, size) \
|
||||
style->brdr_top = top;\
|
||||
style->brdr_btm = btm;\
|
||||
style->border = size;
|
||||
|
||||
#define theme_background(top, btm) \
|
||||
style->bg_top = top;\
|
||||
style->bg_btm = btm;
|
||||
|
||||
#define theme_base(top, btm, text, label) \
|
||||
style->fill_top = top;\
|
||||
style->fill_btm = btm;\
|
||||
style->text_base = text;\
|
||||
style->text_label = label;
|
||||
|
||||
#define theme_field(top, btm, text) \
|
||||
style->field_top = top;\
|
||||
style->field_btm = btm;\
|
||||
style->text_field = text;
|
||||
|
||||
#define theme_slider(handle) \
|
||||
style->slider_width = handle;
|
||||
|
||||
#define theme_select(presstop, pressbtm, hovertop, hoverbtm, sel, cur) \
|
||||
style->press_top = presstop;\
|
||||
style->press_btm = pressbtm;\
|
||||
style->hover_top = hovertop;\
|
||||
style->hover_btm = hoverbtm;\
|
||||
style->select = sel;\
|
||||
style->cursor = cur;
|
||||
|
||||
#include "themes.h"
|
||||
|
||||
#undef theme_add
|
||||
#undef theme_window
|
||||
#undef theme_border
|
||||
#undef theme_background
|
||||
#undef theme_base
|
||||
#undef theme_field
|
||||
#undef theme_slider
|
||||
#undef theme_select
|
||||
|
||||
sys.style_def = style;
|
||||
}
|
||||
|
||||
byte cvar_load() {
|
||||
char str[64];
|
||||
char *lines;
|
||||
char *line = NULL;
|
||||
cvar_t *cv;
|
||||
int pos;
|
||||
if(!file_sread(&lines, sys.cfg_file)) {
|
||||
return 0;
|
||||
}
|
||||
while(line = strtok(line ? NULL : lines, "\n")) {
|
||||
for(pos = 0; line[pos]; pos++) {
|
||||
if(line[pos] == '=')
|
||||
break;
|
||||
}
|
||||
if(line[pos]) {
|
||||
line[pos++] = 0;
|
||||
if(!(cv = cvar_get(line))) {
|
||||
loge(LOG_SYS, STR_CVAR_UNKNOWN, line);
|
||||
continue;
|
||||
}
|
||||
if(sys.log_set != 0xff && cv->data == &sys.log_level) {
|
||||
if(str_parse_enum(line+pos, (const char**)cv->aux_data, cv->max, &cv->value))
|
||||
sys.log_set = (byte)cv->value;
|
||||
else
|
||||
loge(LOG_SYS, STR_CVAR_INVALID, cv->name, line+pos);
|
||||
cv->value = (int)sys.log_level;
|
||||
continue;
|
||||
}
|
||||
if(cvar_set(cv, line+pos, 1)) {
|
||||
cvar_format(cv, str);
|
||||
logt(LOG_SYS, "%s = %s", cv->name, str);
|
||||
}
|
||||
else {
|
||||
loge(LOG_SYS, STR_CVAR_INVALID, cv->name, line+pos);
|
||||
}
|
||||
}
|
||||
}
|
||||
mem_free(lines);
|
||||
return 1;
|
||||
}
|
||||
|
||||
byte cvar_save() {
|
||||
char str[64];
|
||||
cvar_t *cv;
|
||||
FILE *fd;
|
||||
int err;
|
||||
if(!(fd = fopen(sys.cfg_file, "wb"))) {
|
||||
err = errno;
|
||||
loge(LOG_IO, STR_CVAR_EWOPEN, sys.cfg_file, strerror(err), err);
|
||||
return 0;
|
||||
}
|
||||
for(int z = 0; z < sys.n_cvars; z++) {
|
||||
cv = &sys.cvars[z];
|
||||
if(sys.log_set != 0xff && cv->data == &sys.log_level)
|
||||
sprintf(str, "%s", ((const char**)cv->aux_data)[sys.log_set]);
|
||||
else
|
||||
cvar_format(cv, str);
|
||||
fprintf(fd, "%s=%s\n", cv->name, str);
|
||||
}
|
||||
fclose(fd);
|
||||
return 1;
|
||||
}
|
||||
|
||||
void cvar_init() {
|
||||
cvar_t *cv;
|
||||
tbl_init(&sys.themes, 32, 1, sizeof(style_t), MEM_SYSTEM);
|
||||
theme_reg();
|
||||
cvar_reg();
|
||||
smap_init(&sys.cvar_map, 1, MEM_SYSTEM);
|
||||
for(int z = 0; z < sys.n_cvars; z++) {
|
||||
cv = &sys.cvars[z];
|
||||
smap_put(&sys.cvar_map, cv->name, cv);
|
||||
}
|
||||
cvar_load();
|
||||
}
|
||||
|
||||
void cvar_end() {
|
||||
cvar_save();
|
||||
smap_clear(&sys.cvar_map);
|
||||
tbl_clear(&sys.themes);
|
||||
}
|
||||
|
||||
const char *cvar_getbind(byte bind) {
|
||||
return STR_BIND_QUIT + (LOCALE_ELEM * bind);
|
||||
}
|
||||
|
||||
const char *cvar_getkey(int key, char *buf) {
|
||||
if(key == 0) {
|
||||
return "---";
|
||||
}
|
||||
else if(key >= -SCROLL_RIGHT && key <= -MOUSE_LEFT) {
|
||||
return STR_KEY_MOUSE_LEFT + (LOCALE_ELEM * -(key + MOUSE_LEFT));
|
||||
}
|
||||
else if(key >= KEYSYM_0 && key <= KEYSYM_9) {
|
||||
sprintf(buf, "<%d>", key - KEYSYM_0);
|
||||
return buf;
|
||||
}
|
||||
else if(key >= KEYSYM_A && key <= KEYSYM_Z) {
|
||||
sprintf(buf, "<%c>", 'A' + (char)(key - KEYSYM_A));
|
||||
return buf;
|
||||
}
|
||||
else if(key >= KEYSYM_F1 && key <= KEYSYM_F12) {
|
||||
sprintf(buf, "F%d", 1 + key - KEYSYM_F1);
|
||||
return buf;
|
||||
}
|
||||
else if(key >= KEYSYM_KP_0 && key <= KEYSYM_KP_9) {
|
||||
sprintf(buf, "#%d", key - KEYSYM_KP_0);
|
||||
return buf;
|
||||
}
|
||||
else if(key >= KEYSYM_FIRST && key <= KEYSYM_LAST) {
|
||||
return STR_KEY_SPACE + (LOCALE_ELEM * (key - KEYSYM_FIRST));
|
||||
}
|
||||
else {
|
||||
sprintf(buf, "[%d]", key);
|
||||
return buf;
|
||||
}
|
||||
}
|
900
dmx.h
Normal file
|
@ -0,0 +1,900 @@
|
|||
|
||||
// #ifndef DMX_STDMEM
|
||||
#define DMX_MALLOC(s) mem_alloc(s, MEM_FILE)
|
||||
#define DMX_FREE(p) mem_free(p)
|
||||
// #else
|
||||
// #define DMX_MALLOC(s) malloc(s)
|
||||
// #define DMX_FREE(p) free(p)
|
||||
// #endif
|
||||
// #ifndef DMX_LOG
|
||||
#define DMX_LOG(s, a...) loge(LOG_IO, s, a)
|
||||
// #endif
|
||||
|
||||
uint bnk_read_mhbank(byte **data, bank_instr **instr, const char *filename, uint minsize, uint maxsize, const char *hdr, uint hdrsize) {
|
||||
int err;
|
||||
FILE *fd = fopen(filename, "rb");
|
||||
if(fd == NULL) {
|
||||
err = errno;
|
||||
DMX_LOG(STR_BNK_OPNERR, filename, strerror(err), err);
|
||||
return 0;
|
||||
}
|
||||
if(fseek(fd, 0L, SEEK_END)) {
|
||||
err = errno;
|
||||
DMX_LOG(STR_BNK_EGEN, filename, strerror(err), err);
|
||||
fclose(fd);
|
||||
return 0;
|
||||
}
|
||||
long size = ftell(fd);
|
||||
if(size < 0L) {
|
||||
err = errno;
|
||||
DMX_LOG(STR_BNK_EGEN, filename, strerror(err), err);
|
||||
fclose(fd);
|
||||
return 0;
|
||||
}
|
||||
if(fseek(fd, 0L, SEEK_SET)) {
|
||||
err = errno;
|
||||
DMX_LOG(STR_BNK_EGEN, filename, strerror(err), err);
|
||||
fclose(fd);
|
||||
return 0;
|
||||
}
|
||||
if(size < (hdrsize+minsize)) {
|
||||
DMX_LOG(STR_BNK_ESHORT, filename);
|
||||
fclose(fd);
|
||||
return 0;
|
||||
}
|
||||
if(hdrsize > 0) {
|
||||
byte header[hdrsize];
|
||||
if(fread(header, 1, hdrsize, fd) != hdrsize) {
|
||||
err = feof(fd);
|
||||
DMX_LOG(err == 0 ? STR_BNK_EIO : STR_BNK_EEOF, filename);
|
||||
fclose(fd);
|
||||
return 0;
|
||||
}
|
||||
if(memcmp(header, hdr, hdrsize) != 0) {
|
||||
DMX_LOG(STR_BNK_EMFHDR, filename);
|
||||
fclose(fd);
|
||||
return 0;
|
||||
}
|
||||
size -= hdrsize;
|
||||
}
|
||||
size = ((maxsize > 0) && (size > maxsize)) ? maxsize : size;
|
||||
*data = DMX_MALLOC(size);
|
||||
if(fread(*data, 1, size, fd) != size) {
|
||||
err = feof(fd);
|
||||
DMX_LOG(err == 0 ? STR_BNK_EIO : STR_BNK_EEOF, filename);
|
||||
fclose(fd);
|
||||
DMX_FREE(*data);
|
||||
return 0;
|
||||
}
|
||||
fclose(fd);
|
||||
*instr = DMX_MALLOC(sizeof(bank_instr)*256);
|
||||
return size;
|
||||
}
|
||||
|
||||
uint bnk_read_mbank(byte **data, bank_instr **instr, const char *filename, uint minsize, uint maxsize) {
|
||||
return bnk_read_mhbank(data, instr, filename, minsize, maxsize, NULL, 0);
|
||||
}
|
||||
|
||||
uint bnk_read_hbank(byte **data, bank_instr **instr, const char *filename, uint size, const char *hdr, uint hdrsize) {
|
||||
return bnk_read_mhbank(data, instr, filename, size, size, hdr, hdrsize);
|
||||
}
|
||||
|
||||
uint bnk_read_sbank(byte **data, bank_instr **instr, const char *filename, uint size) {
|
||||
return bnk_read_mhbank(data, instr, filename, size, size, NULL, 0);
|
||||
}
|
||||
|
||||
ushort dmx_read_uint16(byte *data) {
|
||||
ushort value = 0;
|
||||
for(int h = 0; h < 2; h++) {
|
||||
value |= ((ushort)data[1-h]);
|
||||
value <<= h < 1 ? 8 : 0;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
ushort dmx_read_uint16be(byte *data) {
|
||||
ushort value = 0;
|
||||
for(int h = 0; h < 2; h++) {
|
||||
value |= ((ushort)data[h]);
|
||||
value <<= h < 1 ? 8 : 0;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
void dmx_read_instr(bank_instr *instr, byte *data, byte drum) {
|
||||
instr->fixed = ((data[0] & 0x01) > 0) | drum;
|
||||
instr->op = ((data[0] & 0x04) > 0) ? b_op22 : b_op2;
|
||||
instr->channels[0].detune = 0;
|
||||
instr->channels[1].detune = ((short)data[2]) - 128;
|
||||
instr->percnum = data[3] & 0x7f;
|
||||
data += 4;
|
||||
for(int ch = 0; ch < 2; ch++) {
|
||||
for(int op = 0; op < 2; op++) {
|
||||
instr->channels[ch].ops[op].tremolo = (data[op*7+0] & 0x80) > 0;
|
||||
instr->channels[ch].ops[op].vibrato = (data[op*7+0] & 0x40) > 0;
|
||||
instr->channels[ch].ops[op].sustaining = (data[op*7+0] & 0x20) > 0;
|
||||
instr->channels[ch].ops[op].ksr = (data[op*7+0] & 0x10) > 0;
|
||||
instr->channels[ch].ops[op].mult = data[op*7+0] & 0x0f;
|
||||
instr->channels[ch].ops[op].attack = (data[op*7+1] >> 4) & 0x0f;
|
||||
instr->channels[ch].ops[op].decay = data[op*7+1] & 0x0f;
|
||||
instr->channels[ch].ops[op].sustain = (data[op*7+2] >> 4) & 0x0f;
|
||||
instr->channels[ch].ops[op].release = data[op*7+2] & 0x0f;
|
||||
instr->channels[ch].ops[op].waveform = data[op*7+3] & 0x07;
|
||||
instr->channels[ch].ops[op].ksl = (data[op*7+4] >> 6) & 0x03;
|
||||
instr->channels[ch].ops[op].level = data[op*7+5] & 0x3f;
|
||||
}
|
||||
instr->channels[ch].feedback = (data[6] >> 1) & 0x07;
|
||||
instr->channels[ch].am = data[6] & 0x01;
|
||||
instr->channels[ch].offset = ((short)dmx_read_uint16(data+14)) + 12;
|
||||
data += 16;
|
||||
}
|
||||
}
|
||||
|
||||
bank_instr *dmx_read_bank(const char *filename) {
|
||||
byte *data;
|
||||
bank_instr *instr;
|
||||
uint size = bnk_read_hbank(&data, &instr, filename, 175*68, "#OPL_II#", 8);
|
||||
if(size == 0) {
|
||||
return NULL;
|
||||
}
|
||||
byte *odata = data;
|
||||
for(int i = 0; i < 256; i++) {
|
||||
instr[i].op = b_op0;
|
||||
instr[i].name[0] = 0;
|
||||
}
|
||||
for(int i = 0; i < 175; i++) {
|
||||
dmx_read_instr(&instr[(i < 128) ? i : (i + 35)], data, i >= 128);
|
||||
data += 36;
|
||||
}
|
||||
for(int i = 0; i < 175; i++) {
|
||||
bank_instr *ins = &instr[(i < 128) ? i : (i + 35)];
|
||||
memcpy(ins->name, data, 32);
|
||||
ins->name[31] = 0;
|
||||
data += 32;
|
||||
}
|
||||
DMX_FREE(odata);
|
||||
return instr;
|
||||
}
|
||||
|
||||
void tmb_read_instr(bank_instr *instr, byte *data, byte drum) {
|
||||
instr->name[0] = 0;
|
||||
instr->fixed = drum;
|
||||
instr->op = b_op2;
|
||||
for(int op = 0; op < 2; op++) {
|
||||
instr->channels[0].ops[op].tremolo = (data[op+0] & 0x80) > 0;
|
||||
instr->channels[0].ops[op].vibrato = (data[op+0] & 0x40) > 0;
|
||||
instr->channels[0].ops[op].sustaining = (data[op+0] & 0x20) > 0;
|
||||
instr->channels[0].ops[op].ksr = (data[op+0] & 0x10) > 0;
|
||||
instr->channels[0].ops[op].mult = data[op+0] & 0x0f;
|
||||
instr->channels[0].ops[op].attack = (data[op+4] >> 4) & 0x0f;
|
||||
instr->channels[0].ops[op].decay = data[op+4] & 0x0f;
|
||||
instr->channels[0].ops[op].sustain = (data[op+6] >> 4) & 0x0f;
|
||||
instr->channels[0].ops[op].release = data[op+6] & 0x0f;
|
||||
instr->channels[0].ops[op].waveform = data[op+8] & 0x07;
|
||||
instr->channels[0].ops[op].ksl = (data[op+2] >> 6) & 0x03;
|
||||
instr->channels[0].ops[op].level = data[op+2] & 0x3f;
|
||||
}
|
||||
instr->channels[0].feedback = (data[10] >> 1) & 0x07;
|
||||
instr->channels[0].am = data[10] & 0x01;
|
||||
instr->percnum = drum ? (data[11] & 0x7f) : 0;
|
||||
instr->channels[0].offset = drum ? 0 : ((char)data[11]);
|
||||
instr->channels[0].detune = 0;
|
||||
}
|
||||
|
||||
bank_instr *tmb_read_bank(const char *filename) {
|
||||
byte *data;
|
||||
bank_instr *instr;
|
||||
uint size = bnk_read_sbank(&data, &instr, filename, 256*13);
|
||||
if(size == 0) {
|
||||
return NULL;
|
||||
}
|
||||
byte *odata = data;
|
||||
for(int i = 0; i < 256; i++) {
|
||||
tmb_read_instr(&instr[i], data, i >= 128);
|
||||
data += 13;
|
||||
}
|
||||
DMX_FREE(odata);
|
||||
return instr;
|
||||
}
|
||||
|
||||
void ibk_read_instr(bank_instr *instr, byte *data, byte drum) {
|
||||
instr->fixed = drum;
|
||||
instr->op = b_op2;
|
||||
for(int op = 0; op < 2; op++) {
|
||||
instr->channels[0].ops[op].tremolo = (data[op+0] & 0x80) > 0;
|
||||
instr->channels[0].ops[op].vibrato = (data[op+0] & 0x40) > 0;
|
||||
instr->channels[0].ops[op].sustaining = (data[op+0] & 0x20) > 0;
|
||||
instr->channels[0].ops[op].ksr = (data[op+0] & 0x10) > 0;
|
||||
instr->channels[0].ops[op].mult = data[op+0] & 0x0f;
|
||||
instr->channels[0].ops[op].attack = (data[op+4] >> 4) & 0x0f;
|
||||
instr->channels[0].ops[op].decay = data[op+4] & 0x0f;
|
||||
instr->channels[0].ops[op].sustain = (data[op+6] >> 4) & 0x0f;
|
||||
instr->channels[0].ops[op].release = data[op+6] & 0x0f;
|
||||
instr->channels[0].ops[op].waveform = data[op+8] & 0x07;
|
||||
instr->channels[0].ops[op].ksl = (data[op+2] >> 6) & 0x03;
|
||||
instr->channels[0].ops[op].level = data[op+2] & 0x3f;
|
||||
}
|
||||
instr->channels[0].feedback = (data[10] >> 1) & 0x07;
|
||||
instr->channels[0].am = data[10] & 0x01;
|
||||
instr->percnum = drum ? (data[13] & 0x7f) : 0;
|
||||
instr->channels[0].offset = drum ? 0 : ((char)data[13]);
|
||||
instr->channels[0].detune = 0;
|
||||
}
|
||||
|
||||
bank_instr *ibk_read_bank(const char *filename, byte drum) {
|
||||
byte *data;
|
||||
bank_instr *instr;
|
||||
uint size = bnk_read_hbank(&data, &instr, filename, 128*25, "IBK\x1a", 4);
|
||||
if(size == 0) {
|
||||
return NULL;
|
||||
}
|
||||
byte *odata = data;
|
||||
for(int i = 0; i < 128; i++) {
|
||||
instr[i + (drum ? 0 : 128)].op = b_op0;
|
||||
instr[i + (drum ? 0 : 128)].name[0] = 0;
|
||||
}
|
||||
for(int i = 0; i < 128; i++) {
|
||||
ibk_read_instr(&instr[i + (drum ? 128 : 0)], data, drum);
|
||||
data += 16;
|
||||
}
|
||||
for(int i = 0; i < 128; i++) {
|
||||
bank_instr *ins = &instr[i + (drum ? 128 : 0)];
|
||||
memcpy(ins->name, data, 8);
|
||||
ins->name[8] = 0;
|
||||
data += 9;
|
||||
}
|
||||
DMX_FREE(odata);
|
||||
return instr;
|
||||
}
|
||||
|
||||
void sb_read_instr(bank_instr *instr, byte *data, byte drum) {
|
||||
for(int h = 0; h < 28; h++) {
|
||||
instr->name[h] = (data[h] == 0x1a) ? ' ' : data[h];
|
||||
}
|
||||
instr->name[28] = 0;
|
||||
instr->percnum = data[35] & 0x7f;
|
||||
instr->fixed = drum;
|
||||
instr->op = b_op2;
|
||||
data += 36;
|
||||
for(int op = 0; op < 2; op++) {
|
||||
instr->channels[0].ops[op].tremolo = (data[op+0] & 0x80) > 0;
|
||||
instr->channels[0].ops[op].vibrato = (data[op+0] & 0x40) > 0;
|
||||
instr->channels[0].ops[op].sustaining = (data[op+0] & 0x20) > 0;
|
||||
instr->channels[0].ops[op].ksr = (data[op+0] & 0x10) > 0;
|
||||
instr->channels[0].ops[op].mult = data[op+0] & 0x0f;
|
||||
instr->channels[0].ops[op].attack = (data[op+4] >> 4) & 0x0f;
|
||||
instr->channels[0].ops[op].decay = data[op+4] & 0x0f;
|
||||
instr->channels[0].ops[op].sustain = (data[op+6] >> 4) & 0x0f;
|
||||
instr->channels[0].ops[op].release = data[op+6] & 0x0f;
|
||||
instr->channels[0].ops[op].waveform = data[op+8] & 0x07;
|
||||
instr->channels[0].ops[op].ksl = (data[op+2] >> 6) & 0x03;
|
||||
instr->channels[0].ops[op].level = data[op+2] & 0x3f;
|
||||
}
|
||||
instr->channels[0].feedback = (data[10] >> 1) & 0x07;
|
||||
instr->channels[0].am = data[10] & 0x01;
|
||||
instr->channels[0].offset = 0;
|
||||
instr->channels[0].detune = 0;
|
||||
}
|
||||
|
||||
bank_instr *sb_read_bank(const char *filename, byte drum) {
|
||||
byte *data;
|
||||
bank_instr *instr;
|
||||
uint size = bnk_read_sbank(&data, &instr, filename, 128*52);
|
||||
if(size == 0) {
|
||||
return NULL;
|
||||
}
|
||||
byte *odata = data;
|
||||
for(int i = 0; i < 128; i++) {
|
||||
instr[i + (drum ? 0 : 128)].op = b_op0;
|
||||
instr[i + (drum ? 0 : 128)].name[0] = 0;
|
||||
}
|
||||
for(int i = 0; i < 128; i++) {
|
||||
sb_read_instr(&instr[i + (drum ? 128 : 0)], data, drum);
|
||||
data += 52;
|
||||
}
|
||||
DMX_FREE(odata);
|
||||
return instr;
|
||||
}
|
||||
|
||||
void sb3_read_instr(bank_instr *instr, byte *data, byte drum) {
|
||||
for(int h = 0; h < 28; h++) {
|
||||
instr->name[h] = (data[h] == 0x1a) ? ' ' : data[h];
|
||||
}
|
||||
instr->name[28] = 0;
|
||||
instr->percnum = data[35] & 0x7f;
|
||||
instr->fixed = drum;
|
||||
instr->op = (data[0] == '4') ? b_op4 : b_op2;
|
||||
data += 36;
|
||||
for(int ch = 0; ch < 2; ch++) {
|
||||
for(int op = 0; op < 2; op++) {
|
||||
instr->channels[ch].ops[op].tremolo = (data[op+0] & 0x80) > 0;
|
||||
instr->channels[ch].ops[op].vibrato = (data[op+0] & 0x40) > 0;
|
||||
instr->channels[ch].ops[op].sustaining = (data[op+0] & 0x20) > 0;
|
||||
instr->channels[ch].ops[op].ksr = (data[op+0] & 0x10) > 0;
|
||||
instr->channels[ch].ops[op].mult = data[op+0] & 0x0f;
|
||||
instr->channels[ch].ops[op].attack = (data[op+4] >> 4) & 0x0f;
|
||||
instr->channels[ch].ops[op].decay = data[op+4] & 0x0f;
|
||||
instr->channels[ch].ops[op].sustain = (data[op+6] >> 4) & 0x0f;
|
||||
instr->channels[ch].ops[op].release = data[op+6] & 0x0f;
|
||||
instr->channels[ch].ops[op].waveform = data[op+8] & 0x07;
|
||||
instr->channels[ch].ops[op].ksl = (data[op+2] >> 6) & 0x03;
|
||||
instr->channels[ch].ops[op].level = data[op+2] & 0x3f;
|
||||
}
|
||||
instr->channels[ch].feedback = (data[10] >> 1) & 0x07;
|
||||
instr->channels[ch].am = data[10] & 0x01;
|
||||
instr->channels[ch].offset = 0;
|
||||
instr->channels[ch].detune = 0;
|
||||
data += 11;
|
||||
}
|
||||
}
|
||||
|
||||
bank_instr *sb3_read_bank(const char *filename, byte drum) {
|
||||
byte *data;
|
||||
bank_instr *instr;
|
||||
uint size = bnk_read_sbank(&data, &instr, filename, 128*60);
|
||||
if(size == 0) {
|
||||
return NULL;
|
||||
}
|
||||
byte *odata = data;
|
||||
for(int i = 0; i < 128; i++) {
|
||||
instr[i + (drum ? 0 : 128)].op = b_op0;
|
||||
instr[i + (drum ? 0 : 128)].name[0] = 0;
|
||||
}
|
||||
for(int i = 0; i < 128; i++) {
|
||||
sb3_read_instr(&instr[i + (drum ? 128 : 0)], data, drum);
|
||||
data += 60;
|
||||
}
|
||||
DMX_FREE(odata);
|
||||
return instr;
|
||||
}
|
||||
|
||||
void op3_read_instr(bank_instr *instr, byte *data, byte drum) {
|
||||
instr->percnum = data[1] & 0x7f;
|
||||
instr->fixed = drum;
|
||||
instr->op = ((data[0] & 0x01) > 0) ? b_op4 : b_op2;
|
||||
data += 2;
|
||||
for(int ch = 0; ch < 2; ch++) {
|
||||
for(int op = 0; op < 2; op++) {
|
||||
instr->channels[ch].ops[op].tremolo = (data[op*6+0] & 0x80) > 0;
|
||||
instr->channels[ch].ops[op].vibrato = (data[op*6+0] & 0x40) > 0;
|
||||
instr->channels[ch].ops[op].sustaining = (data[op*6+0] & 0x20) > 0;
|
||||
instr->channels[ch].ops[op].ksr = (data[op*6+0] & 0x10) > 0;
|
||||
instr->channels[ch].ops[op].mult = data[op*6+0] & 0x0f;
|
||||
instr->channels[ch].ops[op].attack = (data[op*6+2] >> 4) & 0x0f;
|
||||
instr->channels[ch].ops[op].decay = data[op*6+2] & 0x0f;
|
||||
instr->channels[ch].ops[op].sustain = (data[op*6+3] >> 4) & 0x0f;
|
||||
instr->channels[ch].ops[op].release = data[op*6+3] & 0x0f;
|
||||
instr->channels[ch].ops[op].waveform = data[op*6+4] & 0x07;
|
||||
instr->channels[ch].ops[op].ksl = (data[op*6+1] >> 6) & 0x03;
|
||||
instr->channels[ch].ops[op].level = data[op*6+1] & 0x3f;
|
||||
}
|
||||
instr->channels[ch].feedback = (data[5] >> 1) & 0x07;
|
||||
instr->channels[ch].am = data[5] & 0x01;
|
||||
instr->channels[ch].offset = 0;
|
||||
instr->channels[ch].detune = 0;
|
||||
data += 11;
|
||||
}
|
||||
}
|
||||
|
||||
bank_instr *op3_read_bank(const char *filename) {
|
||||
byte *data;
|
||||
bank_instr *instr;
|
||||
uint size = bnk_read_mhbank(&data, &instr, filename, 16, 256*24+16, "Junglevision Patch File\x1a", 24);
|
||||
if(size == 0) {
|
||||
return NULL;
|
||||
}
|
||||
byte *odata = data;
|
||||
for(int i = 0; i < 256; i++) {
|
||||
instr[i].op = b_op0;
|
||||
instr[i].name[0] = 0;
|
||||
}
|
||||
data += 8;
|
||||
ushort nmelo = dmx_read_uint16(&data[0]);
|
||||
ushort ndrum = dmx_read_uint16(&data[2]);
|
||||
ushort omelo = dmx_read_uint16(&data[4]);
|
||||
ushort odrum = dmx_read_uint16(&data[6]);
|
||||
data += 8;
|
||||
if((((nmelo+ndrum)*24+16) > size) || ((omelo+nmelo) > 128) || ((odrum+ndrum) > 128)) {
|
||||
DMX_LOG(STR_BNK_EEOD, filename);
|
||||
DMX_FREE(odata);
|
||||
DMX_FREE(instr);
|
||||
return NULL;
|
||||
}
|
||||
for(int i = 0; i < nmelo; i++) {
|
||||
op3_read_instr(&instr[i + omelo], data, 0);
|
||||
data += 24;
|
||||
}
|
||||
for(int i = 0; i < ndrum; i++) {
|
||||
op3_read_instr(&instr[i + odrum + 128], data, 1);
|
||||
data += 24;
|
||||
}
|
||||
DMX_FREE(odata);
|
||||
return instr;
|
||||
}
|
||||
|
||||
void ad_read_instr(bank_instr *instr, byte *data, byte drum, ushort isize) {
|
||||
if(isize < 12) {
|
||||
return;
|
||||
}
|
||||
instr->percnum = data[0] & 0x7f;
|
||||
instr->fixed = drum;
|
||||
instr->op = (isize >= 23) ? b_op4 : b_op2;
|
||||
data += 1;
|
||||
instr->channels[0].feedback = instr->channels[1].feedback = (data[5] >> 1) & 0x07;
|
||||
instr->channels[0].am = data[5] & 0x01;
|
||||
instr->channels[1].am = (data[5] & 0x80) > 0;
|
||||
for(int ch = 0; ch < ((isize >= 23) ? 2 : 1); ch++) {
|
||||
for(int op = 0; op < 2; op++) {
|
||||
instr->channels[ch].ops[op].tremolo = (data[op*6+0] & 0x80) > 0;
|
||||
instr->channels[ch].ops[op].vibrato = (data[op*6+0] & 0x40) > 0;
|
||||
instr->channels[ch].ops[op].sustaining = (data[op*6+0] & 0x20) > 0;
|
||||
instr->channels[ch].ops[op].ksr = (data[op*6+0] & 0x10) > 0;
|
||||
instr->channels[ch].ops[op].mult = data[op*6+0] & 0x0f;
|
||||
instr->channels[ch].ops[op].attack = (data[op*6+2] >> 4) & 0x0f;
|
||||
instr->channels[ch].ops[op].decay = data[op*6+2] & 0x0f;
|
||||
instr->channels[ch].ops[op].sustain = (data[op*6+3] >> 4) & 0x0f;
|
||||
instr->channels[ch].ops[op].release = data[op*6+3] & 0x0f;
|
||||
instr->channels[ch].ops[op].waveform = data[op*6+4] & 0x07;
|
||||
instr->channels[ch].ops[op].ksl = (data[op*6+1] >> 6) & 0x03;
|
||||
instr->channels[ch].ops[op].level = data[op*6+1] & 0x3f;
|
||||
}
|
||||
instr->channels[ch].offset = 0;
|
||||
instr->channels[ch].detune = 0;
|
||||
data += 11;
|
||||
}
|
||||
}
|
||||
|
||||
bank_instr *ad_read_bank(const char *filename) {
|
||||
byte *data;
|
||||
bank_instr *instr;
|
||||
uint size = bnk_read_mbank(&data, &instr, filename, 2, 256*20+2);
|
||||
if(size == 0) {
|
||||
return NULL;
|
||||
}
|
||||
byte *odata = data;
|
||||
for(int i = 0; i < 256; i++) {
|
||||
instr[i].op = b_op0;
|
||||
instr[i].name[0] = 0;
|
||||
}
|
||||
for(int i = 0;; i++, data += 6) {
|
||||
if((i*6) >= size) {
|
||||
DMX_LOG(STR_BNK_EEOD, filename);
|
||||
DMX_FREE(odata);
|
||||
DMX_FREE(instr);
|
||||
return NULL;
|
||||
}
|
||||
byte prog = data[0];
|
||||
if(prog == 0xff) {
|
||||
break;
|
||||
}
|
||||
if(prog >= 128) {
|
||||
continue;
|
||||
}
|
||||
byte bank = data[1];
|
||||
if((bank != 0) && (bank != 127)) {
|
||||
continue;
|
||||
}
|
||||
ushort offs = dmx_read_uint16(data+2);
|
||||
ushort isize;
|
||||
if(((offs+2) > size) || ((offs+(isize = dmx_read_uint16(odata+offs))) > size) || (isize < 2)) {
|
||||
DMX_LOG(STR_BNK_EEOD, filename);
|
||||
DMX_FREE(odata);
|
||||
DMX_FREE(instr);
|
||||
return NULL;
|
||||
}
|
||||
ad_read_instr(&instr[prog + ((bank == 127) ? 128 : 0)], odata+(offs+2), bank == 127, isize-2);
|
||||
}
|
||||
DMX_FREE(odata);
|
||||
return instr;
|
||||
}
|
||||
|
||||
void bk_read_instr(bank_instr *instr, byte *data, byte drum) {
|
||||
instr->fixed = drum;
|
||||
instr->op = b_op2;
|
||||
for(int op = 0; op < 2; op++) {
|
||||
instr->channels[0].ops[op].tremolo = data[op*13+9] & 0x01;
|
||||
instr->channels[0].ops[op].vibrato = data[op*13+10] & 0x01;
|
||||
instr->channels[0].ops[op].sustaining = data[op*13+5] & 0x01;
|
||||
instr->channels[0].ops[op].ksr = data[op*13+11] & 0x01;
|
||||
instr->channels[0].ops[op].mult = data[op*13+1] & 0x0f;
|
||||
instr->channels[0].ops[op].attack = data[op*13+3] & 0x0f;
|
||||
instr->channels[0].ops[op].decay = data[op*13+6] & 0x0f;
|
||||
instr->channels[0].ops[op].sustain = data[op*13+4] & 0x0f;
|
||||
instr->channels[0].ops[op].release = data[op*13+7] & 0x0f;
|
||||
instr->channels[0].ops[op].waveform = data[26+op] & 0x07;
|
||||
instr->channels[0].ops[op].ksl = data[op*13+0] & 0x03;
|
||||
instr->channels[0].ops[op].level = data[op*13+8] & 0x3f;
|
||||
}
|
||||
instr->channels[0].feedback = data[2] & 0x07;
|
||||
instr->channels[0].am = (data[25] & 0x01) ^ 1;
|
||||
instr->channels[0].offset = 0;
|
||||
instr->channels[0].detune = 0;
|
||||
}
|
||||
|
||||
bank_instr *bk_read_bank(const char *filename, byte drum) {
|
||||
byte *data;
|
||||
bank_instr *instr;
|
||||
uint size = bnk_read_mbank(&data, &instr, filename, 28, 256*42+28);
|
||||
if(size == 0) {
|
||||
return NULL;
|
||||
}
|
||||
byte *odata = data;
|
||||
if(memcmp(data+2, "ADLIB-", 6) != 0) {
|
||||
DMX_LOG(STR_BNK_EMFHDR, filename);
|
||||
DMX_FREE(odata);
|
||||
DMX_FREE(instr);
|
||||
return NULL;
|
||||
}
|
||||
data += 8;
|
||||
for(int i = 0; i < 256; i++) {
|
||||
instr[i].op = b_op0;
|
||||
instr[i].name[0] = 0;
|
||||
}
|
||||
// ushort nnorm = data[0];
|
||||
uint ninst = dmx_read_uint16(&data[2]);
|
||||
data += 20;
|
||||
if((ninst*42+28) > size) {
|
||||
DMX_LOG(STR_BNK_EEOD, filename);
|
||||
DMX_FREE(odata);
|
||||
DMX_FREE(instr);
|
||||
return NULL;
|
||||
}
|
||||
data += ninst*12;
|
||||
int pos = 0;
|
||||
for(int i = 0; i < ninst; i++, data += 30) {
|
||||
if(data[0] != 0) {
|
||||
continue;
|
||||
}
|
||||
bk_read_instr(&instr[pos + (drum ? 128 : 0)], data+2, drum);
|
||||
byte *ndata = odata+(i*12+28);
|
||||
instr[pos + (drum ? 128 : 0)].percnum = ndata[2] & 0x7f;
|
||||
memcpy(instr[pos + (drum ? 128 : 0)].name, ndata+3, 8);
|
||||
instr[pos + (drum ? 128 : 0)].name[8] = 0;
|
||||
if(++pos == 128) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
DMX_FREE(odata);
|
||||
return instr;
|
||||
}
|
||||
|
||||
void tim_read_instr(bank_instr *instr, byte *data) {
|
||||
instr->percnum = 0;
|
||||
instr->fixed = 0;
|
||||
instr->op = b_op2;
|
||||
for(int op = 0; op < 2; op++) {
|
||||
instr->channels[0].ops[op].tremolo = dmx_read_uint16(&data[op*26+18]) & 0x01;
|
||||
instr->channels[0].ops[op].vibrato = dmx_read_uint16(&data[op*26+20]) & 0x01;
|
||||
instr->channels[0].ops[op].sustaining = dmx_read_uint16(&data[op*26+10]) & 0x01;
|
||||
instr->channels[0].ops[op].ksr = dmx_read_uint16(&data[op*26+22]) & 0x01;
|
||||
instr->channels[0].ops[op].mult = dmx_read_uint16(&data[op*26+2]) & 0x0f;
|
||||
instr->channels[0].ops[op].attack = dmx_read_uint16(&data[op*26+6]) & 0x0f;
|
||||
instr->channels[0].ops[op].decay = dmx_read_uint16(&data[op*26+12]) & 0x0f;
|
||||
instr->channels[0].ops[op].sustain = dmx_read_uint16(&data[op*26+8]) & 0x0f;
|
||||
instr->channels[0].ops[op].release = dmx_read_uint16(&data[op*26+14]) & 0x0f;
|
||||
instr->channels[0].ops[op].waveform = dmx_read_uint16(&data[52+op*2]) & 0x07;
|
||||
instr->channels[0].ops[op].ksl = dmx_read_uint16(&data[op*26+0]) & 0x03;
|
||||
instr->channels[0].ops[op].level = dmx_read_uint16(&data[op*26+16]) & 0x3f;
|
||||
}
|
||||
instr->channels[0].feedback = dmx_read_uint16(&data[4]) & 0x07;
|
||||
instr->channels[0].am = (dmx_read_uint16(&data[50]) & 0x01) ^ 1;
|
||||
instr->channels[0].offset = 0;
|
||||
instr->channels[0].detune = 0;
|
||||
}
|
||||
|
||||
bank_instr *tim_read_bank(const char *filename, byte drum) {
|
||||
byte *data;
|
||||
bank_instr *instr;
|
||||
uint size = bnk_read_mbank(&data, &instr, filename, 6, 256*65+6);
|
||||
if(size == 0) {
|
||||
return NULL;
|
||||
}
|
||||
byte *odata = data;
|
||||
for(int i = 0; i < 256; i++) {
|
||||
instr[i].op = b_op0;
|
||||
instr[i].name[0] = 0;
|
||||
}
|
||||
uint ninst = dmx_read_uint16(&data[2]);
|
||||
data += 6;
|
||||
if((ninst*65+6) > size) {
|
||||
DMX_LOG(STR_BNK_EEOD, filename);
|
||||
DMX_FREE(odata);
|
||||
DMX_FREE(instr);
|
||||
return NULL;
|
||||
}
|
||||
data += ninst*9;
|
||||
for(int i = 0; (i < ninst) && (i < 128); i++, data += 56) {
|
||||
tim_read_instr(&instr[i + (drum ? 128 : 0)], data);
|
||||
byte *ndata = odata+(i*9+6);
|
||||
memcpy(instr[i + (drum ? 128 : 0)].name, ndata, 8);
|
||||
instr[i + (drum ? 128 : 0)].name[8] = 0;
|
||||
}
|
||||
DMX_FREE(odata);
|
||||
return instr;
|
||||
}
|
||||
|
||||
/*
|
||||
void wopl_read_instr(bank_instr *instr, byte *data, byte drum) {
|
||||
memcpy(instr->name, data, 32);
|
||||
instr->name[31] = 0;
|
||||
data += 32;
|
||||
instr->percnum = data[6] & 0x7f;
|
||||
instr->fixed = drum;
|
||||
instr->op = (data[7] & 0x01) ? (((data[7] & 0x02) > 0) ? b_op22 : b_op4) : b_op2;
|
||||
instr->channels[0].offset = (short)dmx_read_uint16be(&data[0]);
|
||||
instr->channels[0].detune = 0;
|
||||
if(instr->op != b_op2) {
|
||||
instr->channels[1].offset = (short)dmx_read_uint16be(&data[2]);
|
||||
instr->channels[0].detune = (char)data[5];
|
||||
}
|
||||
instr->channels[0].am = data[8] & 0x01;
|
||||
instr->channels[0].feedback = (data[8] >> 1) & 0x07;
|
||||
if(instr->op != b_op2) {
|
||||
instr->channels[1].am = data[9] & 0x01;
|
||||
instr->channels[1].feedback = (data[9] >> 1) & 0x07;
|
||||
}
|
||||
data += 10;
|
||||
for(int ch = 0; ch < ((instr->op != b_op2) ? 2 : 1); ch++) {
|
||||
for(int op = 0; op < 2; op++) {
|
||||
instr->channels[ch].ops[1-op].tremolo = (data[op*5+0] & 0x80) > 0;
|
||||
instr->channels[ch].ops[1-op].vibrato = (data[op*5+0] & 0x40) > 0;
|
||||
instr->channels[ch].ops[1-op].sustaining = (data[op*5+0] & 0x20) > 0;
|
||||
instr->channels[ch].ops[1-op].ksr = (data[op*5+0] & 0x10) > 0;
|
||||
instr->channels[ch].ops[1-op].mult = data[op*5+0] & 0x0f;
|
||||
instr->channels[ch].ops[1-op].attack = (data[op*5+2] >> 4) & 0x0f;
|
||||
instr->channels[ch].ops[1-op].decay = data[op*5+2] & 0x0f;
|
||||
instr->channels[ch].ops[1-op].sustain = (data[op*5+3] >> 4) & 0x0f;
|
||||
instr->channels[ch].ops[1-op].release = data[op*5+3] & 0x0f;
|
||||
instr->channels[ch].ops[1-op].waveform = data[op*5+4] & 0x07;
|
||||
instr->channels[ch].ops[1-op].ksl = (data[op*5+1] >> 6) & 0x03;
|
||||
instr->channels[ch].ops[1-op].level = data[op*5+1] & 0x3f;
|
||||
}
|
||||
data += 10;
|
||||
}
|
||||
}
|
||||
|
||||
bank_instr *wopl_read_bank(const char *filename) {
|
||||
byte *data;
|
||||
bank_instr *instr;
|
||||
uint size = bnk_read_mhbank(&data, &instr, filename, 256*62+9, 512*66+77, "WOPL3-BANK", 10);
|
||||
if(size == 0) {
|
||||
return NULL;
|
||||
}
|
||||
byte *odata = data;
|
||||
int stride = (data[7] != 0) ? 66 : 62;
|
||||
int off = (data[7] != 0) ? 77 : 9 + ((data[4] == 2) ? 102 : 0);
|
||||
int off2 = (data[4] == 2) ? (128*stride) : 0;
|
||||
if((256*stride+off+off2) > size) {
|
||||
DMX_LOG(STR_BNK_EEOD, filename);
|
||||
DMX_FREE(odata);
|
||||
DMX_FREE(instr);
|
||||
return NULL;
|
||||
}
|
||||
data += off;
|
||||
for(int i = 0; i < 128; i++) {
|
||||
wopl_read_instr(&instr[i], data, 0);
|
||||
data += stride;
|
||||
}
|
||||
data += off2;
|
||||
for(int i = 0; i < 128; i++) {
|
||||
wopl_read_instr(&instr[i + 128], data, 1);
|
||||
data += stride;
|
||||
}
|
||||
DMX_FREE(odata);
|
||||
return instr;
|
||||
}
|
||||
*/
|
||||
|
||||
// SKB!
|
||||
// OO-NNNNN NAME[N] FPPPPPPP AFFFAFFF
|
||||
// DDDDDDDD OOOOOOOO TVSKMMMM KKLLLLLL AAAADDDD SSSSRRRR TVSKMMMM KKLLLLLL AAAADDDD SSSSRRRR -WWW-WWW
|
||||
|
||||
uint skb_read_instr(bank_instr *instr, byte *data, uint pos, uint size) {
|
||||
if((pos + 1) > size) {
|
||||
return 0;
|
||||
}
|
||||
data += pos;
|
||||
instr->op = (data[0] >> 6) & 0x03;
|
||||
byte nlen = data[0] & 0x1f;
|
||||
if((pos + 1 + nlen) > size) {
|
||||
return 0;
|
||||
}
|
||||
memcpy(instr->name, data+1, nlen);
|
||||
instr->name[nlen] = 0;
|
||||
pos += 1 + nlen;
|
||||
if(instr->op == b_op0) {
|
||||
return pos;
|
||||
}
|
||||
int numch = (instr->op == b_op2) ? 1 : 2;
|
||||
if((pos + 1 + (12 * numch)) > size) {
|
||||
return 0;
|
||||
}
|
||||
data += 1 + nlen;
|
||||
instr->fixed = (data[0] & 0x80) > 0;
|
||||
instr->percnum = data[0] & 0x7f;
|
||||
instr->channels[0].am = (data[1] & 0x08) > 0;
|
||||
instr->channels[0].feedback = data[1] & 0x07;
|
||||
if(numch == 2) {
|
||||
instr->channels[1].am = (data[1] & 0x80) > 0;
|
||||
instr->channels[1].feedback = (data[1] >> 4) & 0x07;
|
||||
}
|
||||
data += 2;
|
||||
for(int ch = 0; ch < numch; ch++) {
|
||||
instr->channels[ch].detune = ((short)data[0]) - 128;
|
||||
instr->channels[ch].offset = ((short)data[1]) - 128;
|
||||
data += 2;
|
||||
for(int op = 0; op < 2; op++) {
|
||||
instr->channels[ch].ops[op].tremolo = (data[0] & 0x80) > 0;
|
||||
instr->channels[ch].ops[op].vibrato = (data[0] & 0x40) > 0;
|
||||
instr->channels[ch].ops[op].sustaining = (data[0] & 0x20) > 0;
|
||||
instr->channels[ch].ops[op].ksr = (data[0] & 0x10) > 0;
|
||||
instr->channels[ch].ops[op].mult = data[0] & 0x0f;
|
||||
instr->channels[ch].ops[op].ksl = (data[1] >> 6) & 0x03;
|
||||
instr->channels[ch].ops[op].level = data[1] & 0x3f;
|
||||
instr->channels[ch].ops[op].attack = (data[2] >> 4) & 0x0f;
|
||||
instr->channels[ch].ops[op].decay = data[2] & 0x0f;
|
||||
instr->channels[ch].ops[op].sustain = (data[3] >> 4) & 0x0f;
|
||||
instr->channels[ch].ops[op].release = data[3] & 0x0f;
|
||||
data += 4;
|
||||
}
|
||||
instr->channels[ch].ops[0].waveform = (data[0] >> 4) & 0x07;
|
||||
instr->channels[ch].ops[1].waveform = data[0] & 0x07;
|
||||
data += 1;
|
||||
}
|
||||
return pos + 2 + (11 * numch);
|
||||
}
|
||||
|
||||
bank_instr *skb_read_bank(const char *filename) {
|
||||
byte *data;
|
||||
bank_instr *instr;
|
||||
uint size = bnk_read_mhbank(&data, &instr, filename, 256, 256*56, "SKB!", 4);
|
||||
if(size == 0) {
|
||||
return NULL;
|
||||
}
|
||||
uint pos = 0;
|
||||
for(int i = 0; i < 256; i++) {
|
||||
pos = skb_read_instr(&instr[i], data, pos, size);
|
||||
if(pos == 0) {
|
||||
DMX_LOG(STR_BNK_EEOD, filename);
|
||||
DMX_FREE(data);
|
||||
DMX_FREE(instr);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
DMX_FREE(data);
|
||||
return instr;
|
||||
}
|
||||
|
||||
bank_instr *bnk_read_bank(const char *filename, byte drum) {
|
||||
int len = 0;
|
||||
int dp = 0;
|
||||
char ch;
|
||||
while(ch = filename[len++]) {
|
||||
if(ch == '.') {
|
||||
dp = len;
|
||||
}
|
||||
}
|
||||
if(dp == 0) {
|
||||
DMX_LOG(STR_BNK_UNKN, filename);
|
||||
return NULL;
|
||||
}
|
||||
char ext[len -= dp];
|
||||
for(int c = 0; c < len; c++) {
|
||||
ext[c] = filename[dp+c];
|
||||
if((ext[c] >= 'A') && (ext[c] <= 'Z')) {
|
||||
ext[c] = ext[c] - 'A' + 'a';
|
||||
}
|
||||
}
|
||||
if(strcmp(ext, "skb") == 0) {
|
||||
return skb_read_bank(filename);
|
||||
}
|
||||
else if((strcmp(ext, "dmx") == 0) || (strcmp(ext, "op2") == 0) || (strcmp(ext, "lmp") == 0)) {
|
||||
return dmx_read_bank(filename);
|
||||
}
|
||||
else if(strcmp(ext, "tmb") == 0) {
|
||||
return tmb_read_bank(filename);
|
||||
}
|
||||
else if(strcmp(ext, "ibk") == 0) {
|
||||
return ibk_read_bank(filename, drum);
|
||||
}
|
||||
else if(strcmp(ext, "sb") == 0) {
|
||||
return sb_read_bank(filename, drum);
|
||||
}
|
||||
else if(strcmp(ext, "o3") == 0) {
|
||||
return sb3_read_bank(filename, drum);
|
||||
}
|
||||
else if(strcmp(ext, "op3") == 0) {
|
||||
return op3_read_bank(filename);
|
||||
}
|
||||
else if((strcmp(ext, "ad") == 0) || (strcmp(ext, "opl") == 0)) {
|
||||
return ad_read_bank(filename);
|
||||
}
|
||||
else if(strcmp(ext, "bnk") == 0) {
|
||||
return bk_read_bank(filename, drum);
|
||||
}
|
||||
else if((strcmp(ext, "tim") == 0) || (strcmp(ext, "snd") == 0)) {
|
||||
return tim_read_bank(filename, drum);
|
||||
}
|
||||
// else if(strcmp(ext, "wopl") == 0) {
|
||||
// return wopl_read_bank(filename);
|
||||
// }
|
||||
DMX_LOG(STR_BNK_UNKN, filename);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bank_instr *bnk_read_banks(const char *filename, const char *drumname, byte usedrum) {
|
||||
bank_instr *ins1 = bnk_read_bank(filename, usedrum);
|
||||
if((ins1 != NULL) && (drumname != NULL)) {
|
||||
bank_instr *ins2 = bnk_read_bank(drumname, usedrum ^ 1);
|
||||
if(ins2 != NULL) {
|
||||
memcpy(ins1+128, ins2+128, sizeof(bank_instr)*128);
|
||||
DMX_FREE(ins2);
|
||||
}
|
||||
else {
|
||||
DMX_FREE(ins1);
|
||||
ins1 = NULL;
|
||||
}
|
||||
}
|
||||
return ins1;
|
||||
}
|
||||
|
||||
uint skb_write_instr(bank_instr *instr, byte *data, uint pos) {
|
||||
data += pos;
|
||||
byte nlen = strlen(instr->name);
|
||||
data[0] = (instr->op << 6) | nlen;
|
||||
memcpy(data+1, instr->name, nlen);
|
||||
pos += 1 + nlen;
|
||||
if(instr->op == b_op0) {
|
||||
return pos;
|
||||
}
|
||||
int numch = (instr->op == b_op2) ? 1 : 2;
|
||||
data += 1 + nlen;
|
||||
data[0] = (instr->fixed << 7) | instr->percnum;
|
||||
data[1] = ((numch == 2) ? ((instr->channels[1].am << 7) | (instr->channels[1].feedback << 4)) : 0) | (instr->channels[0].am << 3) | instr->channels[0].feedback;
|
||||
data += 2;
|
||||
for(int ch = 0; ch < numch; ch++) {
|
||||
data[0] = (byte)((short)(instr->channels[ch].detune + 128));
|
||||
data[1] = (byte)((short)(instr->channels[ch].offset + 128));
|
||||
data += 2;
|
||||
for(int op = 0; op < 2; op++) {
|
||||
data[0] = (instr->channels[ch].ops[op].tremolo << 7) | (instr->channels[ch].ops[op].vibrato << 6) | (instr->channels[ch].ops[op].sustaining << 5) |
|
||||
(instr->channels[ch].ops[op].ksr << 4) | instr->channels[ch].ops[op].mult;
|
||||
data[1] = (instr->channels[ch].ops[op].ksl << 6) | instr->channels[ch].ops[op].level;
|
||||
data[2] = (instr->channels[ch].ops[op].attack << 4) | instr->channels[ch].ops[op].decay;
|
||||
data[3] = (instr->channels[ch].ops[op].sustain << 4) | instr->channels[ch].ops[op].release;
|
||||
data += 4;
|
||||
}
|
||||
data[0] = (instr->channels[ch].ops[0].waveform << 4) | instr->channels[ch].ops[1].waveform;
|
||||
data += 1;
|
||||
}
|
||||
return pos + 2 + (11 * numch);
|
||||
}
|
||||
|
||||
byte skb_write_bank(bank_instr *instr, const char *filename) {
|
||||
int err;
|
||||
FILE *fd = fopen(filename, "wb");
|
||||
if(fd == NULL) {
|
||||
err = errno;
|
||||
DMX_LOG(STR_BNK_OPNERR, filename, strerror(err), err);
|
||||
return 0;
|
||||
}
|
||||
if(fwrite("SKB!", 1, 4, fd) != 4) {
|
||||
DMX_LOG(STR_BNK_EWIO, filename);
|
||||
fclose(fd);
|
||||
return 0;
|
||||
}
|
||||
byte *data = DMX_MALLOC(256*56);
|
||||
uint size = 0;
|
||||
for(int i = 0; i < 256; i++) {
|
||||
size = skb_write_instr(&instr[i], data, size);
|
||||
}
|
||||
if(fwrite(data, 1, size, fd) != size) {
|
||||
DMX_LOG(STR_BNK_EWIO, filename);
|
||||
fclose(fd);
|
||||
DMX_FREE(data);
|
||||
return 0;
|
||||
}
|
||||
fclose(fd);
|
||||
DMX_FREE(data);
|
||||
return 1;
|
||||
}
|
142
drawlist.h
Normal file
|
@ -0,0 +1,142 @@
|
|||
|
||||
void draw_set_material(world_t *world, material_t *mat) {
|
||||
shd_sel(mat->shader ? mat->shader : gdr.shd_world, world);
|
||||
shd_scolor("specular", mat->spec_color);
|
||||
shd_float("shine", mat->shine);
|
||||
shd_float("density", mat->density);
|
||||
if(mat->texture)
|
||||
glBindTexture(GL_TEXTURE_2D, mat->texture);
|
||||
}
|
||||
|
||||
int draw_dispatch(world_t *world, drawlist_t *list) {
|
||||
int drawn = 0;
|
||||
draw_t *draw;
|
||||
mat4 mat;
|
||||
glm_mat4_identity(mat);
|
||||
glm_translate(mat, list->position);
|
||||
glBindVertexArray(list->vao);
|
||||
for(int z = 0; z < list->size; z++) {
|
||||
draw = &list->draws[z];
|
||||
draw_set_material(world, draw->material);
|
||||
shd_mat4("model", mat);
|
||||
glDrawArrays(GL_TRIANGLES, draw->offset, draw->size);
|
||||
drawn += draw->size;
|
||||
}
|
||||
return drawn;
|
||||
}
|
||||
|
||||
void draw_world(world_t *world) {
|
||||
int x1 = ((int)world->camera.pos_x) / CHUNK_SIZE;
|
||||
int y1 = ((int)world->camera.pos_y) / CHUNK_SIZE;
|
||||
int z1 = ((int)world->camera.pos_z) / CHUNK_SIZE;
|
||||
int x2 = x1 + gdr.ldist_chunk_xz;
|
||||
int y2 = y1 + gdr.ldist_chunk_y;
|
||||
int z2 = z1 + gdr.ldist_chunk_xz;
|
||||
int lists = 0;
|
||||
int drawn = 0;
|
||||
chunk_t *chunk; // = &world->global;
|
||||
x1 -= gdr.ldist_chunk_xz;
|
||||
y1 -= gdr.ldist_chunk_y;
|
||||
z1 -= gdr.ldist_chunk_xz;
|
||||
// x1 = CHUNK_CLAMP(world, x1, x);
|
||||
// y1 = CHUNK_CLAMP(world, y1, y);
|
||||
// z1 = CHUNK_CLAMP(world, z1, z);
|
||||
// x2 = CHUNK_CLAMP(world, x2, x);
|
||||
// y2 = CHUNK_CLAMP(world, y2, y);
|
||||
// z2 = CHUNK_CLAMP(world, z2, z);
|
||||
// if(chunk->drawlist) {
|
||||
// drawn += draw_dispatch(chunk->drawlist);
|
||||
// lists++;
|
||||
// }
|
||||
for(int cx = x1; cx <= x2; cx++) {
|
||||
for(int cz = z1; cz <= z2; cz++) {
|
||||
for(int cy = y1; cy <= y2; cy++) {
|
||||
if(!(chunk = chunk_get(world, cx, cy, cz, 0)))
|
||||
continue;
|
||||
if(chunk->drawlist) {
|
||||
drawn += draw_dispatch(world, chunk->drawlist);
|
||||
lists++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
gdr.lists_drawn += lists;
|
||||
gdr.tris_drawn += drawn / 3;
|
||||
}
|
||||
|
||||
/*
|
||||
void draw_floor(world_t *world) {
|
||||
if(!(world->flat_tex))
|
||||
return;
|
||||
mat4 mat;
|
||||
glm_mat4_identity(mat);
|
||||
glm_scale(mat, world->flat_scale);
|
||||
glm_translate(mat, world->flat_offset);
|
||||
shd_mat4("model", mat);
|
||||
glBindVertexArray(gdr.vao_box);
|
||||
glBindTexture(GL_TEXTURE_2D, world->flat_tex);
|
||||
draw_set_material(world->flat_mat);
|
||||
glDrawArrays(GL_TRIANGLES, 30, 6);
|
||||
}
|
||||
*/
|
||||
|
||||
void draw_destroy(drawlist_t *list) {
|
||||
if(list->bind)
|
||||
buf_destroy(list->bind);
|
||||
if(list->draws)
|
||||
mem_free(list->draws);
|
||||
list->size = 0;
|
||||
list->draws = NULL;
|
||||
list->bind = NULL;
|
||||
}
|
||||
|
||||
void draw_build(chunk_t *chunk, drawlist_t *list) {
|
||||
int pos;
|
||||
int done;
|
||||
int verts;
|
||||
uint id;
|
||||
material_t *material;
|
||||
polygon_t *poly;
|
||||
float *vert;
|
||||
draw_t *draw;
|
||||
float *vertices = mem_alloc(chunk->poly_list.stored * 3 * sizeof(vertex_t), MEM_POLY);
|
||||
list->size = 0;
|
||||
list->draws = NULL;
|
||||
for(done = 0; done < chunk->poly_list.stored; list->size += 1) {
|
||||
list->draws = mem_realloc(list->draws, sizeof(draw_t) * (list->size + 1), MEM_POLY);
|
||||
draw = &list->draws[list->size];
|
||||
verts = 0;
|
||||
material = NULL;
|
||||
pos = 0;
|
||||
draw->offset = done * 3;
|
||||
while((id = lst_iter(&chunk->poly_list, &pos)) != 0xffffffff) {
|
||||
poly = &chunk->poly_pool[id];
|
||||
if(!material) {
|
||||
material = poly->material;
|
||||
for(int z = 0; z < list->size; z++) {
|
||||
if(material == list->draws[z].material) {
|
||||
material = NULL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(!material)
|
||||
continue;
|
||||
}
|
||||
else if(material != poly->material) {
|
||||
// logd("nnt", "C %d %d %d %d %.3f %.3f", texture, poly->texture, material, poly->material, density, poly->density);
|
||||
continue;
|
||||
}
|
||||
sys_assert(done < chunk->poly_list.stored)
|
||||
memcpy(&vertices[24 * done], poly->vertices, 3 * sizeof(vertex_t));
|
||||
done++;
|
||||
verts++;
|
||||
}
|
||||
draw->size = verts * 3;
|
||||
draw->material = material;
|
||||
// logd("nnt", "L %d %d %d %.3f", draw->size, draw->texture, draw->material, draw->density);
|
||||
}
|
||||
list->bind = buf_init(0, &list->vbo, &list->vao, vertices, done * 3 * sizeof(vertex_t), 8, 3, 3, 2);
|
||||
mem_free(vertices);
|
||||
VEC3_SET(list->position, chunk->box.x1, chunk->box.y1, chunk->box.z1);
|
||||
// logd("nnt", "= %d @ %.3f %.3f %.3f", list->size, list->position[0], list->position[1], list->position[2]);
|
||||
}
|
333
entity.h
Normal file
|
@ -0,0 +1,333 @@
|
|||
|
||||
void ent_position(entity_t *ent, double x, double y, double z) {
|
||||
ent->last_x = ent->pos_x = x;
|
||||
ent->last_y = ent->pos_y = y;
|
||||
ent->last_z = ent->pos_z = z;
|
||||
AABB_SET(ent->box, x - (ent->width / 2.0), y, z - (ent->width / 2.0), x + (ent->width / 2.0), y + ent->height, z + (ent->width / 2.0));
|
||||
}
|
||||
|
||||
void ent_angle(entity_t *ent, float yaw, float pitch) {
|
||||
ent->yaw = yaw;
|
||||
ent->pitch = pitch;
|
||||
ent->rot_yaw = ((double)yaw) - 90.0;
|
||||
}
|
||||
|
||||
void ent_pos(entity_t *ent, double x, double y, double z, float yaw, float pitch) {
|
||||
ent_position(ent, x, y, z);
|
||||
ent_angle(ent, yaw, pitch);
|
||||
}
|
||||
|
||||
void ent_init(entity_t *ent, world_t *world, double x, double y, double z, float yaw, float pitch) {
|
||||
memset(ent, 0, sizeof(entity_t));
|
||||
ent->world = world;
|
||||
ent->speed = 1.0;
|
||||
ent->eye = 1.8;
|
||||
ent->width = 0.6;
|
||||
ent->height = 2.0;
|
||||
ent->step_height = 0.6;
|
||||
ent->jump_motion = 0.42;
|
||||
ent->fly_base_speed = 0.05;
|
||||
ent->walk_base_speed = 0.1;
|
||||
ent->air_base_speed = 0.02;
|
||||
ent->first_tick = 1;
|
||||
ent_pos(ent, x, y, z, yaw, pitch);
|
||||
}
|
||||
|
||||
void ent_position_vec(entity_t *ent, vec3 pos) {
|
||||
ent_position(ent, pos[0], pos[1], pos[2]);
|
||||
}
|
||||
|
||||
void ent_position_eye(entity_t *ent, vec3 pos) {
|
||||
ent_position(ent, pos[0], pos[1] - ent->eye, pos[2]);
|
||||
}
|
||||
|
||||
void ent_getpos(entity_t *ent, vec3 pos) {
|
||||
VEC3_SET(pos, ent->pos_x, ent->pos_y, ent->pos_z);
|
||||
}
|
||||
|
||||
void ent_geteye(entity_t *ent, vec3 pos) {
|
||||
VEC3_SET(pos, ent->pos_x, ent->pos_y + ent->eye, ent->pos_z);
|
||||
}
|
||||
|
||||
void ent_angle_cam(entity_t *ent, camera_t *cam) {
|
||||
ent_angle(ent, cam->yaw, cam->pitch);
|
||||
}
|
||||
|
||||
void ent_tick(entity_t *ent) {
|
||||
float strafe, forward;
|
||||
byte jumping, noclip;
|
||||
double last_mot_y, velo, friction, mot;
|
||||
double x, y, z;
|
||||
// double cx, cy, cz;
|
||||
noclip = (ent == ent->world->entity) && ent->world->noclip && !(ent->world->camonly);
|
||||
if(noclip)
|
||||
ent->ground = 0;
|
||||
ent->last_x = ent->pos_x;
|
||||
ent->last_y = ent->pos_y;
|
||||
ent->last_z = ent->pos_z;
|
||||
ent->first_tick = 0;
|
||||
if(!(ent->sprinting) && !(ent->sneak) && (ent->forward > 0.0) && /* wld.can_sprint && */ !(ent->use) && ent->sprint)
|
||||
ent->sprinting = 1;
|
||||
if(ent->sprinting && (ent->sneak || (ent->forward <= 0.0) || ent->use || ent->collided_h /* || !(wld.can_sprint) */))
|
||||
ent->sprinting = 0;
|
||||
// if(wld.can_fly) {
|
||||
if(noclip) {
|
||||
if(!(ent->flying))
|
||||
ent->flying = 1;
|
||||
}
|
||||
else if(!(ent->last_jump) && ent->jump) {
|
||||
if(ent->fly_timer == 0) {
|
||||
ent->fly_timer = 7;
|
||||
}
|
||||
else {
|
||||
ent->flying ^= 1;
|
||||
ent->fly_timer = 0;
|
||||
}
|
||||
}
|
||||
// }
|
||||
ent->last_jump = ent->jump;
|
||||
if(ent->flying && (ent == ent->world->entity)) {
|
||||
if(ent->sneak)
|
||||
ent->motion_y -= ent->fly_speed * 3.0 * (ent->sprint ? 2.0 : 1.0);
|
||||
if(ent->jump)
|
||||
ent->motion_y += ent->fly_speed * 3.0 * (ent->sprint ? 2.0 : 1.0);
|
||||
}
|
||||
if (ent->fly_timer > 0)
|
||||
ent->fly_timer -= 1;
|
||||
if (ent->jump_ticks > 0)
|
||||
ent->jump_ticks -= 1;
|
||||
if(fabs(ent->motion_x) < 0.005)
|
||||
ent->motion_x = 0.0;
|
||||
if(fabs(ent->motion_y) < 0.005)
|
||||
ent->motion_y = 0.0;
|
||||
if(fabs(ent->motion_z) < 0.005)
|
||||
ent->motion_z = 0.0;
|
||||
if(ent->blocked) {
|
||||
jumping = 0;
|
||||
strafe = 0.0;
|
||||
forward = 0.0;
|
||||
}
|
||||
else if(ent == ent->world->entity) {
|
||||
strafe = ent->strafe * (ent->sneak ? 0.3 : 1.0) * (ent->use ? 0.2 : 1.0);
|
||||
forward = ent->forward * (ent->sneak ? 0.3 : 1.0) * (ent->use ? 0.2 : 1.0);
|
||||
jumping = ent->jump;
|
||||
}
|
||||
if(jumping) {
|
||||
if(ent->ground && ent->jump_ticks == 0) {
|
||||
ent->motion_y = ent->jump_motion;
|
||||
if(ent->sprinting) {
|
||||
double bmot = ent->rot_yaw * M_PI / 180.0;
|
||||
ent->motion_x -= sin(bmot) * 0.2;
|
||||
ent->motion_z += cos(bmot) * 0.2;
|
||||
}
|
||||
ent->jump_ticks = 10;
|
||||
}
|
||||
}
|
||||
else {
|
||||
ent->jump_ticks = 0;
|
||||
}
|
||||
strafe *= 0.98;
|
||||
forward *= 0.98;
|
||||
if(ent->flying) {
|
||||
last_mot_y = ent->motion_y;
|
||||
ent->air_speed = ent->fly_speed * (ent->sprinting ? 2.0 : 1.0);
|
||||
}
|
||||
velo = 0.91;
|
||||
if(ent->ground) {
|
||||
velo *= (1.0 - ent->world->friction) * 0.5 + 0.5;
|
||||
friction = ent->walk_speed * 0.16277136 / (velo * velo * velo);
|
||||
}
|
||||
else {
|
||||
friction = ent->air_speed;
|
||||
}
|
||||
mot = strafe * strafe + forward * forward;
|
||||
if(mot >= 1.0E-4) {
|
||||
mot = sqrt(mot);
|
||||
if(mot < 1.0)
|
||||
mot = 1.0;
|
||||
mot = friction / mot;
|
||||
strafe = strafe * mot;
|
||||
forward = forward * mot;
|
||||
double smot = sin(ent->rot_yaw * M_PI / 180.0);
|
||||
double cmot = cos(ent->rot_yaw * M_PI / 180.0);
|
||||
ent->motion_x += strafe * cmot - forward * smot;
|
||||
ent->motion_z += forward * cmot + strafe * smot;
|
||||
}
|
||||
velo = 0.91;
|
||||
if(ent->ground)
|
||||
velo *= (1.0 - ent->world->friction) * 0.5 + 0.5;
|
||||
x = ent->motion_x;
|
||||
y = ent->motion_y;
|
||||
z = ent->motion_z;
|
||||
if(noclip) {
|
||||
AABB_OFFSET(ent->box, x, y, z)
|
||||
ent->pos_x = (ent->box.x1 + ent->box.x2) / 2.0;
|
||||
ent->pos_y = ent->box.y1;
|
||||
ent->pos_z = (ent->box.z1 + ent->box.z2) / 2.0;
|
||||
}
|
||||
else {
|
||||
double last_x, last_y, last_z;
|
||||
bbox_t box;
|
||||
bbox_t *list;
|
||||
int len;
|
||||
byte step;
|
||||
if(ent->braked) {
|
||||
ent->braked = 0;
|
||||
x *= 0.25;
|
||||
y *= 0.05000000074505806;
|
||||
z *= 0.25;
|
||||
ent->motion_x = ent->motion_y = ent->motion_z = 0.0;
|
||||
}
|
||||
last_x = x;
|
||||
last_y = y;
|
||||
last_z = z;
|
||||
if(ent->ground && ent->sneak) {
|
||||
double shift;
|
||||
for(shift = 0.05; x != 0.0 && box_get_colliding(ent->world, NULL, box_offset_to(&ent->box, &box, x, -1.0, 0.0)) == 0; last_x = x) {
|
||||
if(x < shift && x >= -shift)
|
||||
x = 0.0;
|
||||
else if(x > 0.0)
|
||||
x -= shift;
|
||||
else
|
||||
x += shift;
|
||||
}
|
||||
for(; z != 0.0 && box_get_colliding(ent->world, NULL, box_offset_to(&ent->box, &box, 0.0, -1.0, z)) == 0; last_z = z) {
|
||||
if(z < shift && z >= -shift)
|
||||
z = 0.0;
|
||||
else if(z > 0.0)
|
||||
z -= shift;
|
||||
else
|
||||
z += shift;
|
||||
}
|
||||
for(; x != 0.0 && z != 0.0 && box_get_colliding(ent->world, NULL, box_offset_to(&ent->box, &box, x, -1.0, z)) == 0; last_z = z) {
|
||||
if(x < shift && x >= -shift)
|
||||
x = 0.0;
|
||||
else if(x > 0.0)
|
||||
x -= shift;
|
||||
else
|
||||
x += shift;
|
||||
last_x = x;
|
||||
if(z < shift && z >= -shift)
|
||||
z = 0.0;
|
||||
else if(z > 0.0)
|
||||
z -= shift;
|
||||
else
|
||||
z += shift;
|
||||
}
|
||||
}
|
||||
len = box_get_colliding(ent->world, &list, box_add_coord(&ent->box, &box, x, y, z));
|
||||
AABB_COPY(ent->box, box);
|
||||
for(int n = 0; n < len; n++)
|
||||
y = box_calc_yoff(&list[n], &ent->box, y);
|
||||
AABB_OFFSET(ent->box, 0.0, y, 0.0);
|
||||
step = ent->ground || last_y != y && last_y < 0.0;
|
||||
for(int n = 0; n < len; n++)
|
||||
x = box_calc_xoff(&list[n], &ent->box, x);
|
||||
AABB_OFFSET(ent->box, x, 0.0, 0.0);
|
||||
for(int n = 0; n < len; n++)
|
||||
z = box_calc_zoff(&list[n], &ent->box, z);
|
||||
AABB_OFFSET(ent->box, 0.0, 0.0, z);
|
||||
if(ent->step_height > 0.0 && step && (last_x != x || last_z != z)) {
|
||||
double step_x = x;
|
||||
double step_y = y;
|
||||
double step_z = z;
|
||||
bbox_t box_prev, box_shift, box_sshift;
|
||||
double shift_x, shift_y, shift_z;
|
||||
double shift_sx, shift_sy, shift_sz;
|
||||
AABB_COPY(ent->box, box_prev);
|
||||
AABB_COPY(box, ent->box);
|
||||
y = ent->step_height;
|
||||
len = box_get_colliding(ent->world, &list, box_add_coord(&ent->box, &box, last_x, y, last_z));
|
||||
AABB_COPY(ent->box, box_shift);
|
||||
box_add_coord(&box_shift, &box, last_x, 0.0, last_z);
|
||||
shift_y = y;
|
||||
for(int n = 0; n < len; n++)
|
||||
shift_y = box_calc_yoff(&list[n], &box, shift_y);
|
||||
AABB_OFFSET(box_shift, 0.0, shift_y, 0.0);
|
||||
shift_x = last_x;
|
||||
for(int n = 0; n < len; n++)
|
||||
shift_x = box_calc_xoff(&list[n], &box_shift, shift_x);
|
||||
AABB_OFFSET(box_shift, shift_x, 0.0, 0.0);
|
||||
shift_z = last_z;
|
||||
for(int n = 0; n < len; n++)
|
||||
shift_z = box_calc_zoff(&list[n], &box_shift, shift_z);
|
||||
AABB_OFFSET(box_shift, 0.0, 0.0, shift_z);
|
||||
AABB_COPY(ent->box, box_sshift);
|
||||
shift_sy = y;
|
||||
for(int n = 0; n < len; n++)
|
||||
shift_sy = box_calc_yoff(&list[n], &box_sshift, shift_sy);
|
||||
AABB_OFFSET(box_sshift, 0.0, shift_sy, 0.0);
|
||||
shift_sx = last_x;
|
||||
for(int n = 0; n < len; n++)
|
||||
shift_sx = box_calc_xoff(&list[n], &box_sshift, shift_sx);
|
||||
AABB_OFFSET(box_sshift, shift_sx, 0.0, 0.0);
|
||||
shift_sz = last_z;
|
||||
for(int n = 0; n < len; n++)
|
||||
shift_sz = box_calc_zoff(&list[n], &box_sshift, shift_sz);
|
||||
AABB_OFFSET(box_sshift, 0.0, 0.0, shift_sz);
|
||||
if((shift_x * shift_x + shift_z * shift_z) > (shift_sx * shift_sx + shift_sz * shift_sz)) {
|
||||
x = shift_x;
|
||||
z = shift_z;
|
||||
y = -shift_y;
|
||||
AABB_COPY(box_shift, ent->box);
|
||||
}
|
||||
else {
|
||||
x = shift_sx;
|
||||
z = shift_sz;
|
||||
y = -shift_sy;
|
||||
AABB_COPY(box_sshift, ent->box);
|
||||
}
|
||||
for(int n = 0; n < len; n++)
|
||||
y = box_calc_yoff(&list[n], &ent->box, y);
|
||||
AABB_OFFSET(ent->box, 0.0, y, 0.0);
|
||||
if(step_x * step_x + step_z * step_z >= x * x + z * z) {
|
||||
x = step_x;
|
||||
y = step_y;
|
||||
z = step_z;
|
||||
AABB_COPY(box_prev, ent->box);
|
||||
}
|
||||
}
|
||||
ent->pos_x = (ent->box.x1 + ent->box.x2) / 2.0;
|
||||
ent->pos_y = ent->box.y1;
|
||||
ent->pos_z = (ent->box.z1 + ent->box.z2) / 2.0;
|
||||
ent->collided_h = last_x != x || last_z != z;
|
||||
ent->collided_v = last_y != y;
|
||||
ent->ground = ent->collided_v && last_y < 0.0;
|
||||
ent->collided = ent->collided_h || ent->collided_v;
|
||||
if(ent->ground) {
|
||||
if(ent->fall_distance > 0.0) {
|
||||
// fall_distance ...
|
||||
ent->fall_distance = 0.0;
|
||||
}
|
||||
}
|
||||
else if(y < 0.0) {
|
||||
ent->fall_distance = ent->fall_distance - y;
|
||||
}
|
||||
if(last_x != x)
|
||||
ent->motion_x = 0.0;
|
||||
if(last_z != z)
|
||||
ent->motion_z = 0.0;
|
||||
if(last_y != y)
|
||||
ent->motion_y = 0.0;
|
||||
}
|
||||
ent->motion_y -= ent->world->gravity * 0.1;
|
||||
ent->motion_y *= 0.9800000190734863;
|
||||
ent->motion_x *= velo;
|
||||
ent->motion_z *= velo;
|
||||
if(ent->flying)
|
||||
ent->motion_y = last_mot_y * 0.6;
|
||||
ent->walk_speed = ent->walk_base_speed * ent->speed;
|
||||
ent->air_speed = ent->air_base_speed * ent->speed;
|
||||
ent->fly_speed = ent->fly_base_speed * ent->speed;
|
||||
if(ent->sprinting) {
|
||||
ent->air_speed *= 1.3;
|
||||
ent->walk_speed *= 1.3;
|
||||
}
|
||||
if(ent->ground && ent->flying && !noclip)
|
||||
ent->flying = 0;
|
||||
// cx = ent->world->clamp_xz ? CLAMP_VALUE(ent->pos_x, ent->world->global.box.x1, ent->world->global.box.x2) : ent->pos_x;
|
||||
// cy = ent->world->clamp_y ? CLAMP_VALUE(ent->pos_y, ent->world->global.box.y1, ent->world->global.box.y2) : ent->pos_y;
|
||||
// cz = ent->world->clamp_xz ? CLAMP_VALUE(ent->pos_z, ent->world->global.box.z1, ent->world->global.box.z2) : ent->pos_z;
|
||||
// if(cx != ent->pos_x || cy != ent->pos_y || cz != ent->pos_z)
|
||||
// ent_position(ent, cx, cy, cz);
|
||||
}
|
162
files.h
Normal file
|
@ -0,0 +1,162 @@
|
|||
|
||||
uint file_read_hdr(byte **data, const char *filename, const char *hdr, uint hdrsize, byte flags) {
|
||||
int err;
|
||||
FILE *fd = fopen(filename, "rb");
|
||||
if(fd == NULL) {
|
||||
err = errno;
|
||||
if(err != ENOENT || !(flags & FILE_FLAG_IGNMISS))
|
||||
loge(LOG_IO, STR_FILE_OPENERR, filename, strerror(err), err);
|
||||
return 0;
|
||||
}
|
||||
if(fseek(fd, 0L, SEEK_END)) {
|
||||
err = errno;
|
||||
loge(LOG_IO, STR_FILE_EGEN, filename, strerror(err), err);
|
||||
fclose(fd);
|
||||
return 0;
|
||||
}
|
||||
long size = ftell(fd);
|
||||
if(size < 0L) {
|
||||
err = errno;
|
||||
loge(LOG_IO, STR_FILE_EGEN, filename, strerror(err), err);
|
||||
fclose(fd);
|
||||
return 0;
|
||||
}
|
||||
if(fseek(fd, 0L, SEEK_SET)) {
|
||||
err = errno;
|
||||
loge(LOG_IO, STR_FILE_EGEN, filename, strerror(err), err);
|
||||
fclose(fd);
|
||||
return 0;
|
||||
}
|
||||
if(!size) {
|
||||
if(!(flags & FILE_FLAG_IGNEMPTY))
|
||||
loge(LOG_IO, STR_FILE_EEMPTY, filename);
|
||||
fclose(fd);
|
||||
if((flags & FILE_FLAG_IGNEMPTY) && (flags & FILE_FLAG_STRING)) {
|
||||
*data = mem_alloc(1, MEM_FILE);
|
||||
(*data)[0] = 0;
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
if(size < hdrsize) {
|
||||
loge(LOG_IO, STR_FILE_ESHORT, filename);
|
||||
fclose(fd);
|
||||
return 0;
|
||||
}
|
||||
*data = mem_alloc(size + ((flags & FILE_FLAG_STRING) ? 1 : 0), MEM_FILE);
|
||||
if(hdrsize > 0) {
|
||||
if(fread(*data, 1, hdrsize, fd) != hdrsize) {
|
||||
err = feof(fd);
|
||||
loge(LOG_IO, err == 0 ? STR_FILE_EIO : STR_FILE_EEOF, filename);
|
||||
fclose(fd);
|
||||
mem_free(*data);
|
||||
return 0;
|
||||
}
|
||||
if(memcmp(*data, hdr, hdrsize) != 0) {
|
||||
loge(LOG_IO, STR_FILE_EMFHDR, filename);
|
||||
fclose(fd);
|
||||
mem_free(*data);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
if(fread(&((*data)[hdrsize]), 1, size-hdrsize, fd) != size) {
|
||||
err = feof(fd);
|
||||
loge(LOG_IO, err == 0 ? STR_FILE_EIO : STR_FILE_EEOF, filename);
|
||||
fclose(fd);
|
||||
mem_free(*data);
|
||||
return 0;
|
||||
}
|
||||
fclose(fd);
|
||||
if(flags & FILE_FLAG_STRING)
|
||||
(*data)[size] = 0;
|
||||
return size;
|
||||
}
|
||||
|
||||
byte file_has_ext(const char *file, const char **exts, int n_exts) {
|
||||
int len = strlen(file);
|
||||
int extlen;
|
||||
for(int extidx = 0; extidx < n_exts; extidx++) {
|
||||
extlen = strlen(exts[extidx]);
|
||||
if(len < extlen + 2)
|
||||
continue;
|
||||
if((file[len - (extlen + 1)] == '.') && str_eq_lower(exts[extidx], &file[len - extlen]))
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
const char **file_list_dir(int *count, const char *path, const char **exts, int n_exts) {
|
||||
DIR *dir;
|
||||
struct dirent *ent;
|
||||
int found = 0;
|
||||
// int extlen;
|
||||
// int extidx;
|
||||
int pos = 0;
|
||||
int plen = strlen(path);
|
||||
char *buf = NULL;
|
||||
uint *idx = NULL;
|
||||
const char *sep = "/";
|
||||
if(path[plen - 1] == '/')
|
||||
sep = "";
|
||||
else
|
||||
plen += 1;
|
||||
dir = opendir(path);
|
||||
if(dir) {
|
||||
while(ent = readdir(dir)) {
|
||||
if(ent->d_type == DT_REG) {
|
||||
if(exts && !file_has_ext(ent->d_name, exts, n_exts)) {
|
||||
/*
|
||||
len = strlen(ent->d_name);
|
||||
for(extidx = 0; extidx < n_exts; extidx++) {
|
||||
extlen = strlen(exts[extidx]);
|
||||
if(len < extlen + 2)
|
||||
continue;
|
||||
if((ent->d_name[len - (extlen + 1)] == '.') && str_eq_lower(exts[extidx], &ent->d_name[len - extlen]))
|
||||
break;
|
||||
}
|
||||
if(extidx == n_exts)
|
||||
*/
|
||||
continue;
|
||||
}
|
||||
idx = mem_realloc(idx, (sizeof(uint) * (found + 1)), MEM_FILE);
|
||||
buf = mem_realloc(buf, pos + plen + strlen(ent->d_name) + 1, MEM_FILE);
|
||||
idx[found] = pos;
|
||||
pos += sprintf(&buf[pos], "%s%s%s", path, sep, ent->d_name) + 1;
|
||||
found += 1;
|
||||
}
|
||||
}
|
||||
closedir(dir);
|
||||
}
|
||||
*count = found;
|
||||
if(buf) {
|
||||
char **list = mem_alloc((sizeof(char *) * found) + pos, MEM_FILE);
|
||||
memcpy(&list[found], buf, pos);
|
||||
for(int z = 0; z < found; z++) {
|
||||
list[z] = &((char *)&list[found])[idx[z]];
|
||||
}
|
||||
mem_free(buf);
|
||||
mem_free(idx);
|
||||
// logd("TMP", "%d ...", found);
|
||||
// for(int z = 0; z < found; z++) {
|
||||
// logd("TMP", "%d -> %s", z, list[z]);
|
||||
// }
|
||||
return (const char **)list;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const char **file_list(int *count, const char *path, const char **exts, int n_exts) {
|
||||
struct stat node;
|
||||
*count = 0;
|
||||
if(stat(path, &node))
|
||||
return NULL;
|
||||
if(((node.st_mode & S_IFMT) == S_IFREG) && file_has_ext(path, exts, n_exts)) {
|
||||
int len = strlen(path) + 1;
|
||||
char **file = mem_alloc(sizeof(char *) + len, MEM_FILE);
|
||||
file[0] = (char *)&file[1];
|
||||
memcpy(&file[1], path, len);
|
||||
*count = 1;
|
||||
return (const char**)file;
|
||||
}
|
||||
return ((node.st_mode & S_IFMT) == S_IFDIR) ? file_list_dir(count, path, exts, n_exts) : NULL;
|
||||
}
|
BIN
fonts/font.xcf
Normal file
BIN
fonts/font_0000.png
Normal file
After Width: | Height: | Size: 3.3 KiB |
BIN
fonts/font_0020.png
Normal file
After Width: | Height: | Size: 1.7 KiB |
BIN
fonts/font_0030.png
Normal file
After Width: | Height: | Size: 1.5 KiB |
BIN
fonts/font_01f0.png
Normal file
After Width: | Height: | Size: 1.6 KiB |
BIN
fonts/font_01f1.png
Normal file
After Width: | Height: | Size: 1.6 KiB |
BIN
fonts/font_01f2.png
Normal file
After Width: | Height: | Size: 1.6 KiB |
BIN
fonts/font_01f3.png
Normal file
After Width: | Height: | Size: 1.6 KiB |
BIN
fonts/font_01f4.png
Normal file
After Width: | Height: | Size: 12 KiB |
BIN
fonts/font_01f5.png
Normal file
After Width: | Height: | Size: 12 KiB |
BIN
fonts/font_01f6.png
Normal file
After Width: | Height: | Size: 12 KiB |
BIN
fonts/font_01f7.png
Normal file
After Width: | Height: | Size: 1.6 KiB |
BIN
fonts/font_01f8.png
Normal file
After Width: | Height: | Size: 1.6 KiB |
BIN
fonts/font_01f9.png
Normal file
After Width: | Height: | Size: 12 KiB |
BIN
fonts/font_01fa.png
Normal file
After Width: | Height: | Size: 1.6 KiB |
BIN
fonts/font_01fb.png
Normal file
After Width: | Height: | Size: 1.6 KiB |
BIN
fonts/font_01fc.png
Normal file
After Width: | Height: | Size: 1.6 KiB |
BIN
fonts/font_01fd.png
Normal file
After Width: | Height: | Size: 1.6 KiB |
BIN
fonts/font_01fe.png
Normal file
After Width: | Height: | Size: 1.6 KiB |
BIN
fonts/font_01ff.png
Normal file
After Width: | Height: | Size: 1.6 KiB |
BIN
fonts/font_1000.png
Normal file
After Width: | Height: | Size: 8.3 KiB |
154
framebuf.h
Normal file
|
@ -0,0 +1,154 @@
|
|||
|
||||
byte fb_init_int(uint *fbo, uint *fbtex, uint *rbo, byte linear) {
|
||||
uint status;
|
||||
glGenFramebuffers(1, fbo);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, *fbo);
|
||||
glGenTextures(1, fbtex);
|
||||
glBindTexture(GL_TEXTURE_2D, *fbtex);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, linear ? GL_LINEAR : GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, linear ? GL_LINEAR : GL_NEAREST);
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, *fbtex, 0);
|
||||
if(rbo) {
|
||||
glGenRenderbuffers(1, rbo);
|
||||
glBindRenderbuffer(GL_RENDERBUFFER, *rbo);
|
||||
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, 16, 16);
|
||||
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, *rbo);
|
||||
}
|
||||
if((status = glCheckFramebufferStatus(GL_FRAMEBUFFER)) != GL_FRAMEBUFFER_COMPLETE) {
|
||||
loge(LOG_GFX, STR_FBO_INCOMPLETE, *fbo, status);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
glDeleteTextures(1, fbtex);
|
||||
glDeleteFramebuffers(1, fbo);
|
||||
if(rbo) {
|
||||
glDeleteRenderbuffers(1, rbo);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
gdr.fb_mem += 16 * 16 * 4;
|
||||
gdr.fb_peak = gdr.fb_mem > gdr.fb_peak ? gdr.fb_mem : gdr.fb_peak;
|
||||
return 1;
|
||||
}
|
||||
|
||||
byte fb_init_sys(uint *fbo, uint *fbtex) {
|
||||
if(fb_init_int(fbo, fbtex, NULL, 0)) {
|
||||
logd(LOG_GFX, STR_FBO_ADDED, *fbo, *fbtex);
|
||||
gdr.fb_loaded += 1;
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
fbo_t *fb_init(uint *fbo, uint *fbtex, uint *rbo, window_t *resize, byte linear) {
|
||||
fbo_t *bind;
|
||||
if(!fb_init_int(fbo, fbtex, rbo, linear))
|
||||
return NULL;
|
||||
sys_assert(bind = (fbo_t*)tbl_push(&gdr.framebufs));
|
||||
bind->fbo = fbo;
|
||||
bind->tex = fbtex;
|
||||
bind->rbo = rbo;
|
||||
bind->resize = resize;
|
||||
bind->linear = linear;
|
||||
bind->xsize = 0;
|
||||
bind->ysize = 0;
|
||||
gdr.fb_loaded += 1;
|
||||
if(rbo)
|
||||
logd(LOG_GFX, STR_FBO_ADDED_RBO, *fbo, *fbtex, *rbo);
|
||||
else
|
||||
logd(LOG_GFX, STR_FBO_ADDED, *fbo, *fbtex);
|
||||
return bind;
|
||||
}
|
||||
|
||||
void fb_resize_int(uint fbtex, int px, int py, int x, int y) {
|
||||
gdr.fb_mem -= px * py * 4;
|
||||
glBindTexture(GL_TEXTURE_2D, fbtex);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, x, y, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
|
||||
gdr.fb_mem += x * y * 4;
|
||||
gdr.fb_peak = gdr.fb_mem > gdr.fb_peak ? gdr.fb_mem : gdr.fb_peak;
|
||||
}
|
||||
|
||||
byte fb_resize(fbo_t *buf, window_t *resize) {
|
||||
if(!(buf->resize) || (buf->resize != resize))
|
||||
return 0;
|
||||
glBindTexture(GL_TEXTURE_2D, *(buf->tex));
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, resize->fb_x, resize->fb_y, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
|
||||
if(buf->rbo) {
|
||||
glBindRenderbuffer(GL_RENDERBUFFER, *(buf->rbo));
|
||||
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, resize->fb_x, resize->fb_y);
|
||||
}
|
||||
gdr.fb_mem -= buf->xsize * buf->ysize * 4;
|
||||
gdr.fb_mem += (buf->xsize = resize->fb_x) * (buf->ysize = resize->fb_y) * 4;
|
||||
gdr.fb_peak = gdr.fb_mem > gdr.fb_peak ? gdr.fb_mem : gdr.fb_peak;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int fb_reconfig(window_t *resize) {
|
||||
int done = 0;
|
||||
ulong iter = 0;
|
||||
fbo_t *buf;
|
||||
while(buf = tbl_iter(&gdr.framebufs, &iter)) {
|
||||
done += (int)fb_resize(buf, resize);
|
||||
}
|
||||
// logd(LOG_GFX, STR_FBO_RESIZE, done);
|
||||
return done;
|
||||
}
|
||||
|
||||
void fb_size_int(uint tex, uint rbo, int x, int y) {
|
||||
glBindTexture(GL_TEXTURE_2D, tex);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, x, y, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
|
||||
if(rbo) {
|
||||
glBindRenderbuffer(GL_RENDERBUFFER, rbo);
|
||||
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, x, y);
|
||||
}
|
||||
}
|
||||
|
||||
byte fb_size(fbo_t *buf, int x, int y) {
|
||||
fb_size_int(*(buf->tex), buf->rbo ? *(buf->rbo) : 0, x, y);
|
||||
gdr.fb_mem -= buf->xsize * buf->ysize * 4;
|
||||
gdr.fb_mem += (buf->xsize = x) * (buf->ysize = y) * 4;
|
||||
gdr.fb_peak = gdr.fb_mem > gdr.fb_peak ? gdr.fb_mem : gdr.fb_peak;
|
||||
}
|
||||
|
||||
void fb_delete(uint *fbo, uint *fbtex) {
|
||||
if(*fbo) {
|
||||
glDeleteTextures(1, fbtex);
|
||||
glDeleteFramebuffers(1, fbo);
|
||||
logd(LOG_GFX, STR_FBO_DELETED, *fbo, *fbtex);
|
||||
*fbo = 0;
|
||||
*fbtex = 0;
|
||||
gdr.fb_loaded -= 1;
|
||||
}
|
||||
}
|
||||
|
||||
byte fb_unload(fbo_t *buf) {
|
||||
if(!(*(buf->fbo))) {
|
||||
return 0;
|
||||
}
|
||||
glDeleteTextures(1, buf->tex);
|
||||
glDeleteFramebuffers(1, buf->fbo);
|
||||
if(buf->rbo) {
|
||||
glDeleteRenderbuffers(1, buf->rbo);
|
||||
logd(LOG_GFX, STR_FBO_DELETED_RBO, *(buf->fbo), *(buf->tex), *(buf->rbo));
|
||||
*(buf->rbo) = 0;
|
||||
}
|
||||
else {
|
||||
logd(LOG_GFX, STR_FBO_DELETED, *(buf->fbo), *(buf->tex));
|
||||
}
|
||||
*(buf->fbo) = 0;
|
||||
*(buf->tex) = 0;
|
||||
gdr.fb_loaded -= 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
void fb_remove(fbo_t *buf) {
|
||||
if(fb_unload(buf)) {
|
||||
tbl_pop(&gdr.framebufs, buf);
|
||||
}
|
||||
}
|
||||
|
||||
int fb_clear() {
|
||||
return tbl_clear_func(&gdr.framebufs, (clear_func*)fb_unload);
|
||||
}
|
1381
gl_constants.h
Normal file
718
gl_functions.h
Normal file
|
@ -0,0 +1,718 @@
|
|||
// GL_API_1_0
|
||||
OGL_DEF1(glCullFace, uint)
|
||||
OGL_DEF1(glFrontFace, uint)
|
||||
OGL_DEF2(glHint, uint, uint)
|
||||
OGL_DEF1(glLineWidth, float)
|
||||
OGL_DEF1(glPointSize, float)
|
||||
OGL_DEF2(glPolygonMode, uint, uint)
|
||||
OGL_DEF4(glScissor, int, int, int, int)
|
||||
OGL_DEF3(glTexParameterf, uint, uint, float)
|
||||
OGL_DEF3(glTexParameterfv, uint, uint, const float *)
|
||||
OGL_DEF3(glTexParameteri, uint, uint, int)
|
||||
OGL_DEF3(glTexParameteriv, uint, uint, const int *)
|
||||
OGL_DEF8(glTexImage1D, uint, int, int, int, int, uint, uint, const void *)
|
||||
OGL_DEF9(glTexImage2D, uint, int, int, int, int, int, uint, uint, const void *)
|
||||
OGL_DEF1(glDrawBuffer, uint)
|
||||
OGL_DEF1(glClear, uint)
|
||||
OGL_DEF4(glClearColor, float, float, float, float)
|
||||
OGL_DEF1(glClearStencil, int)
|
||||
OGL_DEF1(glClearDepth, double)
|
||||
OGL_DEF1(glStencilMask, uint)
|
||||
OGL_DEF4(glColorMask, byte, byte, byte, byte)
|
||||
OGL_DEF1(glDepthMask, byte)
|
||||
OGL_DEF1(glDisable, uint)
|
||||
OGL_DEF1(glEnable, uint)
|
||||
OGL_DEF(glFinish)
|
||||
OGL_DEF(glFlush)
|
||||
OGL_DEF2(glBlendFunc, uint, uint)
|
||||
OGL_DEF1(glLogicOp, uint)
|
||||
OGL_DEF3(glStencilFunc, uint, int, uint)
|
||||
OGL_DEF3(glStencilOp, uint, uint, uint)
|
||||
OGL_DEF1(glDepthFunc, uint)
|
||||
OGL_DEF2(glPixelStoref, uint, float)
|
||||
OGL_DEF2(glPixelStorei, uint, int)
|
||||
OGL_DEF1(glReadBuffer, uint)
|
||||
OGL_DEF7(glReadPixels, int, int, int, int, uint, uint, void *)
|
||||
OGL_DEF2(glGetBooleanv, uint, byte *)
|
||||
OGL_DEF2(glGetDoublev, uint, double *)
|
||||
OGL_DEFR(uint, glGetError)
|
||||
OGL_DEF2(glGetFloatv, uint, float *)
|
||||
OGL_DEF2(glGetIntegerv, uint, int *)
|
||||
OGL_DEFR1(const byte *, glGetString, uint)
|
||||
OGL_DEF5(glGetTexImage, uint, int, uint, uint, void *)
|
||||
OGL_DEF3(glGetTexParameterfv, uint, uint, float *)
|
||||
OGL_DEF3(glGetTexParameteriv, uint, uint, int *)
|
||||
OGL_DEF4(glGetTexLevelParameterfv, uint, int, uint, float *)
|
||||
OGL_DEF4(glGetTexLevelParameteriv, uint, int, uint, int *)
|
||||
OGL_DEFR1(byte, glIsEnabled, uint)
|
||||
OGL_DEF2(glDepthRange, double, double)
|
||||
OGL_DEF4(glViewport, int, int, int, int)
|
||||
// GL_API_1_1
|
||||
OGL_DEF3(glDrawArrays, uint, int, int)
|
||||
OGL_DEF4(glDrawElements, uint, int, uint, const void *)
|
||||
OGL_DEF2(glPolygonOffset, float, float)
|
||||
OGL_DEF7(glCopyTexImage1D, uint, int, uint, int, int, int, int)
|
||||
OGL_DEF8(glCopyTexImage2D, uint, int, uint, int, int, int, int, int)
|
||||
OGL_DEF6(glCopyTexSubImage1D, uint, int, int, int, int, int)
|
||||
OGL_DEF8(glCopyTexSubImage2D, uint, int, int, int, int, int, int, int)
|
||||
OGL_DEF7(glTexSubImage1D, uint, int, int, int, uint, uint, const void *)
|
||||
OGL_DEF9(glTexSubImage2D, uint, int, int, int, int, int, uint, uint, const void *)
|
||||
OGL_DEF2(glBindTexture, uint, uint)
|
||||
OGL_DEF2(glDeleteTextures, int, const uint *)
|
||||
OGL_DEF2(glGenTextures, int, uint *)
|
||||
OGL_DEFR1(byte, glIsTexture, uint)
|
||||
// GL_API_1_2
|
||||
OGL_DEF6(glDrawRangeElements, uint, uint, uint, int, uint, const void *)
|
||||
OGL_DEF10(glTexImage3D, uint, int, int, int, int, int, int, uint, uint, const void *)
|
||||
OGL_DEF11(glTexSubImage3D, uint, int, int, int, int, int, int, int, uint, uint, const void *)
|
||||
OGL_DEF9(glCopyTexSubImage3D, uint, int, int, int, int, int, int, int, int)
|
||||
// GL_API_1_3
|
||||
OGL_DEF1(glActiveTexture, uint)
|
||||
OGL_DEF2(glSampleCoverage, float, byte)
|
||||
OGL_DEF9(glCompressedTexImage3D, uint, int, uint, int, int, int, int, int, const void *)
|
||||
OGL_DEF8(glCompressedTexImage2D, uint, int, uint, int, int, int, int, const void *)
|
||||
OGL_DEF7(glCompressedTexImage1D, uint, int, uint, int, int, int, const void *)
|
||||
OGL_DEF11(glCompressedTexSubImage3D, uint, int, int, int, int, int, int, int, uint, int, const void *)
|
||||
OGL_DEF9(glCompressedTexSubImage2D, uint, int, int, int, int, int, uint, int, const void *)
|
||||
OGL_DEF7(glCompressedTexSubImage1D, uint, int, int, int, uint, int, const void *)
|
||||
OGL_DEF3(glGetCompressedTexImage, uint, int, void *)
|
||||
// GL_API_1_4
|
||||
OGL_DEF4(glBlendFuncSeparate, uint, uint, uint, uint)
|
||||
OGL_DEF4(glMultiDrawArrays, uint, const int *, const int *, int)
|
||||
OGL_DEF5(glMultiDrawElements, uint, const int *, uint, const void *const*, int)
|
||||
OGL_DEF2(glPointParameterf, uint, float)
|
||||
OGL_DEF2(glPointParameterfv, uint, const float *)
|
||||
OGL_DEF2(glPointParameteri, uint, int)
|
||||
OGL_DEF2(glPointParameteriv, uint, const int *)
|
||||
OGL_DEF4(glBlendColor, float, float, float, float)
|
||||
OGL_DEF1(glBlendEquation, uint)
|
||||
// GL_API_1_5
|
||||
OGL_DEF2(glGenQueries, int, uint *)
|
||||
OGL_DEF2(glDeleteQueries, int, const uint *)
|
||||
OGL_DEFR1(byte, glIsQuery, uint)
|
||||
OGL_DEF2(glBeginQuery, uint, uint)
|
||||
OGL_DEF1(glEndQuery, uint)
|
||||
OGL_DEF3(glGetQueryiv, uint, uint, int *)
|
||||
OGL_DEF3(glGetQueryObjectiv, uint, uint, int *)
|
||||
OGL_DEF3(glGetQueryObjectuiv, uint, uint, uint *)
|
||||
OGL_DEF2(glBindBuffer, uint, uint)
|
||||
OGL_DEF2(glDeleteBuffers, int, const uint *)
|
||||
OGL_DEF2(glGenBuffers, int, uint *)
|
||||
OGL_DEFR1(byte, glIsBuffer, uint)
|
||||
OGL_DEF4(glBufferData, uint, ssize, const void *, uint)
|
||||
OGL_DEF4(glBufferSubData, uint, iptr, ssize, const void *)
|
||||
OGL_DEF4(glGetBufferSubData, uint, iptr, ssize, void *)
|
||||
OGL_DEFR2(void *, glMapBuffer, uint, uint)
|
||||
OGL_DEFR1(byte, glUnmapBuffer, uint)
|
||||
OGL_DEF3(glGetBufferParameteriv, uint, uint, int *)
|
||||
OGL_DEF3(glGetBufferPointerv, uint, uint, void **)
|
||||
// GL_API_2_0
|
||||
OGL_DEF2(glBlendEquationSeparate, uint, uint)
|
||||
OGL_DEF2(glDrawBuffers, int, const uint *)
|
||||
OGL_DEF4(glStencilOpSeparate, uint, uint, uint, uint)
|
||||
OGL_DEF4(glStencilFuncSeparate, uint, uint, int, uint)
|
||||
OGL_DEF2(glStencilMaskSeparate, uint, uint)
|
||||
OGL_DEF2(glAttachShader, uint, uint)
|
||||
OGL_DEF3(glBindAttribLocation, uint, uint, const char *)
|
||||
OGL_DEF1(glCompileShader, uint)
|
||||
OGL_DEFR(uint, glCreateProgram)
|
||||
OGL_DEFR1(uint, glCreateShader, uint)
|
||||
OGL_DEF1(glDeleteProgram, uint)
|
||||
OGL_DEF1(glDeleteShader, uint)
|
||||
OGL_DEF2(glDetachShader, uint, uint)
|
||||
OGL_DEF1(glDisableVertexAttribArray, uint)
|
||||
OGL_DEF1(glEnableVertexAttribArray, uint)
|
||||
OGL_DEF7(glGetActiveAttrib, uint, uint, int, int *, int *, uint *, char *)
|
||||
OGL_DEF7(glGetActiveUniform, uint, uint, int, int *, int *, uint *, char *)
|
||||
OGL_DEF4(glGetAttachedShaders, uint, int, int *, uint *)
|
||||
OGL_DEFR2(int, glGetAttribLocation, uint, const char *)
|
||||
OGL_DEF3(glGetProgramiv, uint, uint, int *)
|
||||
OGL_DEF4(glGetProgramInfoLog, uint, int, int *, char *)
|
||||
OGL_DEF3(glGetShaderiv, uint, uint, int *)
|
||||
OGL_DEF4(glGetShaderInfoLog, uint, int, int *, char *)
|
||||
OGL_DEF4(glGetShaderSource, uint, int, int *, char *)
|
||||
OGL_DEFR2(int, glGetUniformLocation, uint, const char *)
|
||||
OGL_DEF3(glGetUniformfv, uint, int, float *)
|
||||
OGL_DEF3(glGetUniformiv, uint, int, int *)
|
||||
OGL_DEF3(glGetVertexAttribdv, uint, uint, double *)
|
||||
OGL_DEF3(glGetVertexAttribfv, uint, uint, float *)
|
||||
OGL_DEF3(glGetVertexAttribiv, uint, uint, int *)
|
||||
OGL_DEF3(glGetVertexAttribPointerv, uint, uint, void **)
|
||||
OGL_DEFR1(byte, glIsProgram, uint)
|
||||
OGL_DEFR1(byte, glIsShader, uint)
|
||||
OGL_DEF1(glLinkProgram, uint)
|
||||
OGL_DEF4(glShaderSource, uint, int, const char *const*, const int *)
|
||||
OGL_DEF1(glUseProgram, uint)
|
||||
OGL_DEF2(glUniform1f, int, float)
|
||||
OGL_DEF3(glUniform2f, int, float, float)
|
||||
OGL_DEF4(glUniform3f, int, float, float, float)
|
||||
OGL_DEF5(glUniform4f, int, float, float, float, float)
|
||||
OGL_DEF2(glUniform1i, int, int)
|
||||
OGL_DEF3(glUniform2i, int, int, int)
|
||||
OGL_DEF4(glUniform3i, int, int, int, int)
|
||||
OGL_DEF5(glUniform4i, int, int, int, int, int)
|
||||
OGL_DEF3(glUniform1fv, int, int, const float *)
|
||||
OGL_DEF3(glUniform2fv, int, int, const float *)
|
||||
OGL_DEF3(glUniform3fv, int, int, const float *)
|
||||
OGL_DEF3(glUniform4fv, int, int, const float *)
|
||||
OGL_DEF3(glUniform1iv, int, int, const int *)
|
||||
OGL_DEF3(glUniform2iv, int, int, const int *)
|
||||
OGL_DEF3(glUniform3iv, int, int, const int *)
|
||||
OGL_DEF3(glUniform4iv, int, int, const int *)
|
||||
OGL_DEF4(glUniformMatrix2fv, int, int, byte, const float *)
|
||||
OGL_DEF4(glUniformMatrix3fv, int, int, byte, const float *)
|
||||
OGL_DEF4(glUniformMatrix4fv, int, int, byte, const float *)
|
||||
OGL_DEF1(glValidateProgram, uint)
|
||||
OGL_DEF2(glVertexAttrib1d, uint, double)
|
||||
OGL_DEF2(glVertexAttrib1dv, uint, const double *)
|
||||
OGL_DEF2(glVertexAttrib1f, uint, float)
|
||||
OGL_DEF2(glVertexAttrib1fv, uint, const float *)
|
||||
OGL_DEF2(glVertexAttrib1s, uint, short)
|
||||
OGL_DEF2(glVertexAttrib1sv, uint, const short *)
|
||||
OGL_DEF3(glVertexAttrib2d, uint, double, double)
|
||||
OGL_DEF2(glVertexAttrib2dv, uint, const double *)
|
||||
OGL_DEF3(glVertexAttrib2f, uint, float, float)
|
||||
OGL_DEF2(glVertexAttrib2fv, uint, const float *)
|
||||
OGL_DEF3(glVertexAttrib2s, uint, short, short)
|
||||
OGL_DEF2(glVertexAttrib2sv, uint, const short *)
|
||||
OGL_DEF4(glVertexAttrib3d, uint, double, double, double)
|
||||
OGL_DEF2(glVertexAttrib3dv, uint, const double *)
|
||||
OGL_DEF4(glVertexAttrib3f, uint, float, float, float)
|
||||
OGL_DEF2(glVertexAttrib3fv, uint, const float *)
|
||||
OGL_DEF4(glVertexAttrib3s, uint, short, short, short)
|
||||
OGL_DEF2(glVertexAttrib3sv, uint, const short *)
|
||||
OGL_DEF2(glVertexAttrib4Nbv, uint, const char *)
|
||||
OGL_DEF2(glVertexAttrib4Niv, uint, const int *)
|
||||
OGL_DEF2(glVertexAttrib4Nsv, uint, const short *)
|
||||
OGL_DEF5(glVertexAttrib4Nub, uint, byte, byte, byte, byte)
|
||||
OGL_DEF2(glVertexAttrib4Nubv, uint, const byte *)
|
||||
OGL_DEF2(glVertexAttrib4Nuiv, uint, const uint *)
|
||||
OGL_DEF2(glVertexAttrib4Nusv, uint, const ushort *)
|
||||
OGL_DEF2(glVertexAttrib4bv, uint, const char *)
|
||||
OGL_DEF5(glVertexAttrib4d, uint, double, double, double, double)
|
||||
OGL_DEF2(glVertexAttrib4dv, uint, const double *)
|
||||
OGL_DEF5(glVertexAttrib4f, uint, float, float, float, float)
|
||||
OGL_DEF2(glVertexAttrib4fv, uint, const float *)
|
||||
OGL_DEF2(glVertexAttrib4iv, uint, const int *)
|
||||
OGL_DEF5(glVertexAttrib4s, uint, short, short, short, short)
|
||||
OGL_DEF2(glVertexAttrib4sv, uint, const short *)
|
||||
OGL_DEF2(glVertexAttrib4ubv, uint, const byte *)
|
||||
OGL_DEF2(glVertexAttrib4uiv, uint, const uint *)
|
||||
OGL_DEF2(glVertexAttrib4usv, uint, const ushort *)
|
||||
OGL_DEF6(glVertexAttribPointer, uint, int, uint, byte, int, const void *)
|
||||
// GL_API_2_1
|
||||
OGL_DEF4(glUniformMatrix2x3fv, int, int, byte, const float *)
|
||||
OGL_DEF4(glUniformMatrix3x2fv, int, int, byte, const float *)
|
||||
OGL_DEF4(glUniformMatrix2x4fv, int, int, byte, const float *)
|
||||
OGL_DEF4(glUniformMatrix4x2fv, int, int, byte, const float *)
|
||||
OGL_DEF4(glUniformMatrix3x4fv, int, int, byte, const float *)
|
||||
OGL_DEF4(glUniformMatrix4x3fv, int, int, byte, const float *)
|
||||
// GL_API_3_0
|
||||
OGL_DEF5(glColorMaski, uint, byte, byte, byte, byte)
|
||||
OGL_DEF3(glGetBooleani_v, uint, uint, byte *)
|
||||
OGL_DEF3(glGetIntegeri_v, uint, uint, int *)
|
||||
OGL_DEF2(glEnablei, uint, uint)
|
||||
OGL_DEF2(glDisablei, uint, uint)
|
||||
OGL_DEFR2(byte, glIsEnabledi, uint, uint)
|
||||
OGL_DEF1(glBeginTransformFeedback, uint)
|
||||
OGL_DEF(glEndTransformFeedback)
|
||||
OGL_DEF5(glBindBufferRange, uint, uint, uint, iptr, ssize)
|
||||
OGL_DEF3(glBindBufferBase, uint, uint, uint)
|
||||
OGL_DEF4(glTransformFeedbackVaryings, uint, int, const char *const*, uint)
|
||||
OGL_DEF7(glGetTransformFeedbackVarying, uint, uint, int, int *, int *, uint *, char *)
|
||||
OGL_DEF2(glClampColor, uint, uint)
|
||||
OGL_DEF2(glBeginConditionalRender, uint, uint)
|
||||
OGL_DEF(glEndConditionalRender)
|
||||
OGL_DEF5(glVertexAttribIPointer, uint, int, uint, int, const void *)
|
||||
OGL_DEF3(glGetVertexAttribIiv, uint, uint, int *)
|
||||
OGL_DEF3(glGetVertexAttribIuiv, uint, uint, uint *)
|
||||
OGL_DEF2(glVertexAttribI1i, uint, int)
|
||||
OGL_DEF3(glVertexAttribI2i, uint, int, int)
|
||||
OGL_DEF4(glVertexAttribI3i, uint, int, int, int)
|
||||
OGL_DEF5(glVertexAttribI4i, uint, int, int, int, int)
|
||||
OGL_DEF2(glVertexAttribI1ui, uint, uint)
|
||||
OGL_DEF3(glVertexAttribI2ui, uint, uint, uint)
|
||||
OGL_DEF4(glVertexAttribI3ui, uint, uint, uint, uint)
|
||||
OGL_DEF5(glVertexAttribI4ui, uint, uint, uint, uint, uint)
|
||||
OGL_DEF2(glVertexAttribI1iv, uint, const int *)
|
||||
OGL_DEF2(glVertexAttribI2iv, uint, const int *)
|
||||
OGL_DEF2(glVertexAttribI3iv, uint, const int *)
|
||||
OGL_DEF2(glVertexAttribI4iv, uint, const int *)
|
||||
OGL_DEF2(glVertexAttribI1uiv, uint, const uint *)
|
||||
OGL_DEF2(glVertexAttribI2uiv, uint, const uint *)
|
||||
OGL_DEF2(glVertexAttribI3uiv, uint, const uint *)
|
||||
OGL_DEF2(glVertexAttribI4uiv, uint, const uint *)
|
||||
OGL_DEF2(glVertexAttribI4bv, uint, const char *)
|
||||
OGL_DEF2(glVertexAttribI4sv, uint, const short *)
|
||||
OGL_DEF2(glVertexAttribI4ubv, uint, const byte *)
|
||||
OGL_DEF2(glVertexAttribI4usv, uint, const ushort *)
|
||||
OGL_DEF3(glGetUniformuiv, uint, int, uint *)
|
||||
OGL_DEF3(glBindFragDataLocation, uint, uint, const char *)
|
||||
OGL_DEFR2(int, glGetFragDataLocation, uint, const char *)
|
||||
OGL_DEF2(glUniform1ui, int, uint)
|
||||
OGL_DEF3(glUniform2ui, int, uint, uint)
|
||||
OGL_DEF4(glUniform3ui, int, uint, uint, uint)
|
||||
OGL_DEF5(glUniform4ui, int, uint, uint, uint, uint)
|
||||
OGL_DEF3(glUniform1uiv, int, int, const uint *)
|
||||
OGL_DEF3(glUniform2uiv, int, int, const uint *)
|
||||
OGL_DEF3(glUniform3uiv, int, int, const uint *)
|
||||
OGL_DEF3(glUniform4uiv, int, int, const uint *)
|
||||
OGL_DEF3(glTexParameterIiv, uint, uint, const int *)
|
||||
OGL_DEF3(glTexParameterIuiv, uint, uint, const uint *)
|
||||
OGL_DEF3(glGetTexParameterIiv, uint, uint, int *)
|
||||
OGL_DEF3(glGetTexParameterIuiv, uint, uint, uint *)
|
||||
OGL_DEF3(glClearBufferiv, uint, int, const int *)
|
||||
OGL_DEF3(glClearBufferuiv, uint, int, const uint *)
|
||||
OGL_DEF3(glClearBufferfv, uint, int, const float *)
|
||||
OGL_DEF4(glClearBufferfi, uint, int, float, int)
|
||||
OGL_DEFR2(const byte *, glGetStringi, uint, uint)
|
||||
OGL_DEFR1(byte, glIsRenderbuffer, uint)
|
||||
OGL_DEF2(glBindRenderbuffer, uint, uint)
|
||||
OGL_DEF2(glDeleteRenderbuffers, int, const uint *)
|
||||
OGL_DEF2(glGenRenderbuffers, int, uint *)
|
||||
OGL_DEF4(glRenderbufferStorage, uint, uint, int, int)
|
||||
OGL_DEF3(glGetRenderbufferParameteriv, uint, uint, int *)
|
||||
OGL_DEFR1(byte, glIsFramebuffer, uint)
|
||||
OGL_DEF2(glBindFramebuffer, uint, uint)
|
||||
OGL_DEF2(glDeleteFramebuffers, int, const uint *)
|
||||
OGL_DEF2(glGenFramebuffers, int, uint *)
|
||||
OGL_DEFR1(uint, glCheckFramebufferStatus, uint)
|
||||
OGL_DEF5(glFramebufferTexture1D, uint, uint, uint, uint, int)
|
||||
OGL_DEF5(glFramebufferTexture2D, uint, uint, uint, uint, int)
|
||||
OGL_DEF6(glFramebufferTexture3D, uint, uint, uint, uint, int, int)
|
||||
OGL_DEF4(glFramebufferRenderbuffer, uint, uint, uint, uint)
|
||||
OGL_DEF4(glGetFramebufferAttachmentParameteriv, uint, uint, uint, int *)
|
||||
OGL_DEF1(glGenerateMipmap, uint)
|
||||
OGL_DEF10(glBlitFramebuffer, int, int, int, int, int, int, int, int, uint, uint)
|
||||
OGL_DEF5(glRenderbufferStorageMultisample, uint, int, uint, int, int)
|
||||
OGL_DEF5(glFramebufferTextureLayer, uint, uint, uint, int, int)
|
||||
OGL_DEFR4(void *, glMapBufferRange, uint, iptr, ssize, uint)
|
||||
OGL_DEF3(glFlushMappedBufferRange, uint, iptr, ssize)
|
||||
OGL_DEF1(glBindVertexArray, uint)
|
||||
OGL_DEF2(glDeleteVertexArrays, int, const uint *)
|
||||
OGL_DEF2(glGenVertexArrays, int, uint *)
|
||||
OGL_DEFR1(byte, glIsVertexArray, uint)
|
||||
// GL_API_3_1
|
||||
OGL_DEF4(glDrawArraysInstanced, uint, int, int, int)
|
||||
OGL_DEF5(glDrawElementsInstanced, uint, int, uint, const void *, int)
|
||||
OGL_DEF3(glTexBuffer, uint, uint, uint)
|
||||
OGL_DEF1(glPrimitiveRestartIndex, uint)
|
||||
OGL_DEF5(glCopyBufferSubData, uint, uint, iptr, iptr, ssize)
|
||||
OGL_DEF4(glGetUniformIndices, uint, int, const char *const*, uint *)
|
||||
OGL_DEF5(glGetActiveUniformsiv, uint, int, const uint *, uint, int *)
|
||||
OGL_DEF5(glGetActiveUniformName, uint, uint, int, int *, char *)
|
||||
OGL_DEFR2(uint, glGetUniformBlockIndex, uint, const char *)
|
||||
OGL_DEF4(glGetActiveUniformBlockiv, uint, uint, uint, int *)
|
||||
OGL_DEF5(glGetActiveUniformBlockName, uint, uint, int, int *, char *)
|
||||
OGL_DEF3(glUniformBlockBinding, uint, uint, uint)
|
||||
// GL_API_3_2
|
||||
OGL_DEF5(glDrawElementsBaseVertex, uint, int, uint, const void *, int)
|
||||
OGL_DEF7(glDrawRangeElementsBaseVertex, uint, uint, uint, int, uint, const void *, int)
|
||||
OGL_DEF6(glDrawElementsInstancedBaseVertex, uint, int, uint, const void *, int, int)
|
||||
OGL_DEF6(glMultiDrawElementsBaseVertex, uint, const int *, uint, const void *const*, int, const int *)
|
||||
OGL_DEF1(glProvokingVertex, uint)
|
||||
OGL_DEFR2(sync_t, glFenceSync, uint, uint)
|
||||
OGL_DEFR1(byte, glIsSync, sync_t)
|
||||
OGL_DEF1(glDeleteSync, sync_t)
|
||||
OGL_DEFR3(uint, glClientWaitSync, sync_t, uint, ulong)
|
||||
OGL_DEF3(glWaitSync, sync_t, uint, ulong)
|
||||
OGL_DEF2(glGetInteger64v, uint, long *)
|
||||
OGL_DEF5(glGetSynciv, sync_t, uint, int, int *, int *)
|
||||
OGL_DEF3(glGetInteger64i_v, uint, uint, long *)
|
||||
OGL_DEF3(glGetBufferParameteri64v, uint, uint, long *)
|
||||
OGL_DEF4(glFramebufferTexture, uint, uint, uint, int)
|
||||
OGL_DEF6(glTexImage2DMultisample, uint, int, uint, int, int, byte)
|
||||
OGL_DEF7(glTexImage3DMultisample, uint, int, uint, int, int, int, byte)
|
||||
OGL_DEF3(glGetMultisamplefv, uint, uint, float *)
|
||||
OGL_DEF2(glSampleMaski, uint, uint)
|
||||
// GL_API_3_3
|
||||
OGL_DEF4(glBindFragDataLocationIndexed, uint, uint, uint, const char *)
|
||||
OGL_DEFR2(int, glGetFragDataIndex, uint, const char *)
|
||||
OGL_DEF2(glGenSamplers, int, uint *)
|
||||
OGL_DEF2(glDeleteSamplers, int, const uint *)
|
||||
OGL_DEFR1(byte, glIsSampler, uint)
|
||||
OGL_DEF2(glBindSampler, uint, uint)
|
||||
OGL_DEF3(glSamplerParameteri, uint, uint, int)
|
||||
OGL_DEF3(glSamplerParameteriv, uint, uint, const int *)
|
||||
OGL_DEF3(glSamplerParameterf, uint, uint, float)
|
||||
OGL_DEF3(glSamplerParameterfv, uint, uint, const float *)
|
||||
OGL_DEF3(glSamplerParameterIiv, uint, uint, const int *)
|
||||
OGL_DEF3(glSamplerParameterIuiv, uint, uint, const uint *)
|
||||
OGL_DEF3(glGetSamplerParameteriv, uint, uint, int *)
|
||||
OGL_DEF3(glGetSamplerParameterIiv, uint, uint, int *)
|
||||
OGL_DEF3(glGetSamplerParameterfv, uint, uint, float *)
|
||||
OGL_DEF3(glGetSamplerParameterIuiv, uint, uint, uint *)
|
||||
OGL_DEF2(glQueryCounter, uint, uint)
|
||||
OGL_DEF3(glGetQueryObjecti64v, uint, uint, long *)
|
||||
OGL_DEF3(glGetQueryObjectui64v, uint, uint, ulong *)
|
||||
OGL_DEF2(glVertexAttribDivisor, uint, uint)
|
||||
OGL_DEF4(glVertexAttribP1ui, uint, uint, byte, uint)
|
||||
OGL_DEF4(glVertexAttribP1uiv, uint, uint, byte, const uint *)
|
||||
OGL_DEF4(glVertexAttribP2ui, uint, uint, byte, uint)
|
||||
OGL_DEF4(glVertexAttribP2uiv, uint, uint, byte, const uint *)
|
||||
OGL_DEF4(glVertexAttribP3ui, uint, uint, byte, uint)
|
||||
OGL_DEF4(glVertexAttribP3uiv, uint, uint, byte, const uint *)
|
||||
OGL_DEF4(glVertexAttribP4ui, uint, uint, byte, uint)
|
||||
OGL_DEF4(glVertexAttribP4uiv, uint, uint, byte, const uint *)
|
||||
OGL_DEF2(glVertexP2ui, uint, uint)
|
||||
OGL_DEF2(glVertexP2uiv, uint, const uint *)
|
||||
OGL_DEF2(glVertexP3ui, uint, uint)
|
||||
OGL_DEF2(glVertexP3uiv, uint, const uint *)
|
||||
OGL_DEF2(glVertexP4ui, uint, uint)
|
||||
OGL_DEF2(glVertexP4uiv, uint, const uint *)
|
||||
OGL_DEF2(glTexCoordP1ui, uint, uint)
|
||||
OGL_DEF2(glTexCoordP1uiv, uint, const uint *)
|
||||
OGL_DEF2(glTexCoordP2ui, uint, uint)
|
||||
OGL_DEF2(glTexCoordP2uiv, uint, const uint *)
|
||||
OGL_DEF2(glTexCoordP3ui, uint, uint)
|
||||
OGL_DEF2(glTexCoordP3uiv, uint, const uint *)
|
||||
OGL_DEF2(glTexCoordP4ui, uint, uint)
|
||||
OGL_DEF2(glTexCoordP4uiv, uint, const uint *)
|
||||
OGL_DEF3(glMultiTexCoordP1ui, uint, uint, uint)
|
||||
OGL_DEF3(glMultiTexCoordP1uiv, uint, uint, const uint *)
|
||||
OGL_DEF3(glMultiTexCoordP2ui, uint, uint, uint)
|
||||
OGL_DEF3(glMultiTexCoordP2uiv, uint, uint, const uint *)
|
||||
OGL_DEF3(glMultiTexCoordP3ui, uint, uint, uint)
|
||||
OGL_DEF3(glMultiTexCoordP3uiv, uint, uint, const uint *)
|
||||
OGL_DEF3(glMultiTexCoordP4ui, uint, uint, uint)
|
||||
OGL_DEF3(glMultiTexCoordP4uiv, uint, uint, const uint *)
|
||||
OGL_DEF2(glNormalP3ui, uint, uint)
|
||||
OGL_DEF2(glNormalP3uiv, uint, const uint *)
|
||||
OGL_DEF2(glColorP3ui, uint, uint)
|
||||
OGL_DEF2(glColorP3uiv, uint, const uint *)
|
||||
OGL_DEF2(glColorP4ui, uint, uint)
|
||||
OGL_DEF2(glColorP4uiv, uint, const uint *)
|
||||
OGL_DEF2(glSecondaryColorP3ui, uint, uint)
|
||||
OGL_DEF2(glSecondaryColorP3uiv, uint, const uint *)
|
||||
// GL_API_4_0
|
||||
OGL_DEF1(glMinSampleShading, float)
|
||||
OGL_DEF2(glBlendEquationi, uint, uint)
|
||||
OGL_DEF3(glBlendEquationSeparatei, uint, uint, uint)
|
||||
OGL_DEF3(glBlendFunci, uint, uint, uint)
|
||||
OGL_DEF5(glBlendFuncSeparatei, uint, uint, uint, uint, uint)
|
||||
OGL_DEF2(glDrawArraysIndirect, uint, const void *)
|
||||
OGL_DEF3(glDrawElementsIndirect, uint, uint, const void *)
|
||||
OGL_DEF2(glUniform1d, int, double)
|
||||
OGL_DEF3(glUniform2d, int, double, double)
|
||||
OGL_DEF4(glUniform3d, int, double, double, double)
|
||||
OGL_DEF5(glUniform4d, int, double, double, double, double)
|
||||
OGL_DEF3(glUniform1dv, int, int, const double *)
|
||||
OGL_DEF3(glUniform2dv, int, int, const double *)
|
||||
OGL_DEF3(glUniform3dv, int, int, const double *)
|
||||
OGL_DEF3(glUniform4dv, int, int, const double *)
|
||||
OGL_DEF4(glUniformMatrix2dv, int, int, byte, const double *)
|
||||
OGL_DEF4(glUniformMatrix3dv, int, int, byte, const double *)
|
||||
OGL_DEF4(glUniformMatrix4dv, int, int, byte, const double *)
|
||||
OGL_DEF4(glUniformMatrix2x3dv, int, int, byte, const double *)
|
||||
OGL_DEF4(glUniformMatrix2x4dv, int, int, byte, const double *)
|
||||
OGL_DEF4(glUniformMatrix3x2dv, int, int, byte, const double *)
|
||||
OGL_DEF4(glUniformMatrix3x4dv, int, int, byte, const double *)
|
||||
OGL_DEF4(glUniformMatrix4x2dv, int, int, byte, const double *)
|
||||
OGL_DEF4(glUniformMatrix4x3dv, int, int, byte, const double *)
|
||||
OGL_DEF3(glGetUniformdv, uint, int, double *)
|
||||
OGL_DEFR3(int, glGetSubroutineUniformLocation, uint, uint, const char *)
|
||||
OGL_DEFR3(uint, glGetSubroutineIndex, uint, uint, const char *)
|
||||
OGL_DEF5(glGetActiveSubroutineUniformiv, uint, uint, uint, uint, int *)
|
||||
OGL_DEF6(glGetActiveSubroutineUniformName, uint, uint, uint, int, int *, char *)
|
||||
OGL_DEF6(glGetActiveSubroutineName, uint, uint, uint, int, int *, char *)
|
||||
OGL_DEF3(glUniformSubroutinesuiv, uint, int, const uint *)
|
||||
OGL_DEF3(glGetUniformSubroutineuiv, uint, int, uint *)
|
||||
OGL_DEF4(glGetProgramStageiv, uint, uint, uint, int *)
|
||||
OGL_DEF2(glPatchParameteri, uint, int)
|
||||
OGL_DEF2(glPatchParameterfv, uint, const float *)
|
||||
OGL_DEF2(glBindTransformFeedback, uint, uint)
|
||||
OGL_DEF2(glDeleteTransformFeedbacks, int, const uint *)
|
||||
OGL_DEF2(glGenTransformFeedbacks, int, uint *)
|
||||
OGL_DEFR1(byte, glIsTransformFeedback, uint)
|
||||
OGL_DEF(glPauseTransformFeedback)
|
||||
OGL_DEF(glResumeTransformFeedback)
|
||||
OGL_DEF2(glDrawTransformFeedback, uint, uint)
|
||||
OGL_DEF3(glDrawTransformFeedbackStream, uint, uint, uint)
|
||||
OGL_DEF3(glBeginQueryIndexed, uint, uint, uint)
|
||||
OGL_DEF2(glEndQueryIndexed, uint, uint)
|
||||
OGL_DEF4(glGetQueryIndexediv, uint, uint, uint, int *)
|
||||
// GL_API_4_1
|
||||
OGL_DEF(glReleaseShaderCompiler)
|
||||
OGL_DEF5(glShaderBinary, int, const uint *, uint, const void *, int)
|
||||
OGL_DEF4(glGetShaderPrecisionFormat, uint, uint, int *, int *)
|
||||
OGL_DEF2(glDepthRangef, float, float)
|
||||
OGL_DEF1(glClearDepthf, float)
|
||||
OGL_DEF5(glGetProgramBinary, uint, int, int *, uint *, void *)
|
||||
OGL_DEF4(glProgramBinary, uint, uint, const void *, int)
|
||||
OGL_DEF3(glProgramParameteri, uint, uint, int)
|
||||
OGL_DEF3(glUseProgramStages, uint, uint, uint)
|
||||
OGL_DEF2(glActiveShaderProgram, uint, uint)
|
||||
OGL_DEFR3(uint, glCreateShaderProgramv, uint, int, const char *const*)
|
||||
OGL_DEF1(glBindProgramPipeline, uint)
|
||||
OGL_DEF2(glDeleteProgramPipelines, int, const uint *)
|
||||
OGL_DEF2(glGenProgramPipelines, int, uint *)
|
||||
OGL_DEFR1(byte, glIsProgramPipeline, uint)
|
||||
OGL_DEF3(glGetProgramPipelineiv, uint, uint, int *)
|
||||
OGL_DEF3(glProgramUniform1i, uint, int, int)
|
||||
OGL_DEF4(glProgramUniform1iv, uint, int, int, const int *)
|
||||
OGL_DEF3(glProgramUniform1f, uint, int, float)
|
||||
OGL_DEF4(glProgramUniform1fv, uint, int, int, const float *)
|
||||
OGL_DEF3(glProgramUniform1d, uint, int, double)
|
||||
OGL_DEF4(glProgramUniform1dv, uint, int, int, const double *)
|
||||
OGL_DEF3(glProgramUniform1ui, uint, int, uint)
|
||||
OGL_DEF4(glProgramUniform1uiv, uint, int, int, const uint *)
|
||||
OGL_DEF4(glProgramUniform2i, uint, int, int, int)
|
||||
OGL_DEF4(glProgramUniform2iv, uint, int, int, const int *)
|
||||
OGL_DEF4(glProgramUniform2f, uint, int, float, float)
|
||||
OGL_DEF4(glProgramUniform2fv, uint, int, int, const float *)
|
||||
OGL_DEF4(glProgramUniform2d, uint, int, double, double)
|
||||
OGL_DEF4(glProgramUniform2dv, uint, int, int, const double *)
|
||||
OGL_DEF4(glProgramUniform2ui, uint, int, uint, uint)
|
||||
OGL_DEF4(glProgramUniform2uiv, uint, int, int, const uint *)
|
||||
OGL_DEF5(glProgramUniform3i, uint, int, int, int, int)
|
||||
OGL_DEF4(glProgramUniform3iv, uint, int, int, const int *)
|
||||
OGL_DEF5(glProgramUniform3f, uint, int, float, float, float)
|
||||
OGL_DEF4(glProgramUniform3fv, uint, int, int, const float *)
|
||||
OGL_DEF5(glProgramUniform3d, uint, int, double, double, double)
|
||||
OGL_DEF4(glProgramUniform3dv, uint, int, int, const double *)
|
||||
OGL_DEF5(glProgramUniform3ui, uint, int, uint, uint, uint)
|
||||
OGL_DEF4(glProgramUniform3uiv, uint, int, int, const uint *)
|
||||
OGL_DEF6(glProgramUniform4i, uint, int, int, int, int, int)
|
||||
OGL_DEF4(glProgramUniform4iv, uint, int, int, const int *)
|
||||
OGL_DEF6(glProgramUniform4f, uint, int, float, float, float, float)
|
||||
OGL_DEF4(glProgramUniform4fv, uint, int, int, const float *)
|
||||
OGL_DEF6(glProgramUniform4d, uint, int, double, double, double, double)
|
||||
OGL_DEF4(glProgramUniform4dv, uint, int, int, const double *)
|
||||
OGL_DEF6(glProgramUniform4ui, uint, int, uint, uint, uint, uint)
|
||||
OGL_DEF4(glProgramUniform4uiv, uint, int, int, const uint *)
|
||||
OGL_DEF5(glProgramUniformMatrix2fv, uint, int, int, byte, const float *)
|
||||
OGL_DEF5(glProgramUniformMatrix3fv, uint, int, int, byte, const float *)
|
||||
OGL_DEF5(glProgramUniformMatrix4fv, uint, int, int, byte, const float *)
|
||||
OGL_DEF5(glProgramUniformMatrix2dv, uint, int, int, byte, const double *)
|
||||
OGL_DEF5(glProgramUniformMatrix3dv, uint, int, int, byte, const double *)
|
||||
OGL_DEF5(glProgramUniformMatrix4dv, uint, int, int, byte, const double *)
|
||||
OGL_DEF5(glProgramUniformMatrix2x3fv, uint, int, int, byte, const float *)
|
||||
OGL_DEF5(glProgramUniformMatrix3x2fv, uint, int, int, byte, const float *)
|
||||
OGL_DEF5(glProgramUniformMatrix2x4fv, uint, int, int, byte, const float *)
|
||||
OGL_DEF5(glProgramUniformMatrix4x2fv, uint, int, int, byte, const float *)
|
||||
OGL_DEF5(glProgramUniformMatrix3x4fv, uint, int, int, byte, const float *)
|
||||
OGL_DEF5(glProgramUniformMatrix4x3fv, uint, int, int, byte, const float *)
|
||||
OGL_DEF5(glProgramUniformMatrix2x3dv, uint, int, int, byte, const double *)
|
||||
OGL_DEF5(glProgramUniformMatrix3x2dv, uint, int, int, byte, const double *)
|
||||
OGL_DEF5(glProgramUniformMatrix2x4dv, uint, int, int, byte, const double *)
|
||||
OGL_DEF5(glProgramUniformMatrix4x2dv, uint, int, int, byte, const double *)
|
||||
OGL_DEF5(glProgramUniformMatrix3x4dv, uint, int, int, byte, const double *)
|
||||
OGL_DEF5(glProgramUniformMatrix4x3dv, uint, int, int, byte, const double *)
|
||||
OGL_DEF1(glValidateProgramPipeline, uint)
|
||||
OGL_DEF4(glGetProgramPipelineInfoLog, uint, int, int *, char *)
|
||||
OGL_DEF2(glVertexAttribL1d, uint, double)
|
||||
OGL_DEF3(glVertexAttribL2d, uint, double, double)
|
||||
OGL_DEF4(glVertexAttribL3d, uint, double, double, double)
|
||||
OGL_DEF5(glVertexAttribL4d, uint, double, double, double, double)
|
||||
OGL_DEF2(glVertexAttribL1dv, uint, const double *)
|
||||
OGL_DEF2(glVertexAttribL2dv, uint, const double *)
|
||||
OGL_DEF2(glVertexAttribL3dv, uint, const double *)
|
||||
OGL_DEF2(glVertexAttribL4dv, uint, const double *)
|
||||
OGL_DEF5(glVertexAttribLPointer, uint, int, uint, int, const void *)
|
||||
OGL_DEF3(glGetVertexAttribLdv, uint, uint, double *)
|
||||
OGL_DEF3(glViewportArrayv, uint, int, const float *)
|
||||
OGL_DEF5(glViewportIndexedf, uint, float, float, float, float)
|
||||
OGL_DEF2(glViewportIndexedfv, uint, const float *)
|
||||
OGL_DEF3(glScissorArrayv, uint, int, const int *)
|
||||
OGL_DEF5(glScissorIndexed, uint, int, int, int, int)
|
||||
OGL_DEF2(glScissorIndexedv, uint, const int *)
|
||||
OGL_DEF3(glDepthRangeArrayv, uint, int, const double *)
|
||||
OGL_DEF3(glDepthRangeIndexed, uint, double, double)
|
||||
OGL_DEF3(glGetFloati_v, uint, uint, float *)
|
||||
OGL_DEF3(glGetDoublei_v, uint, uint, double *)
|
||||
// GL_API_4_2
|
||||
OGL_DEF5(glDrawArraysInstancedBaseInstance, uint, int, int, int, uint)
|
||||
OGL_DEF6(glDrawElementsInstancedBaseInstance, uint, int, uint, const void *, int, uint)
|
||||
OGL_DEF7(glDrawElementsInstancedBaseVertexBaseInstance, uint, int, uint, const void *, int, int, uint)
|
||||
OGL_DEF5(glGetInternalformativ, uint, uint, uint, int, int *)
|
||||
OGL_DEF4(glGetActiveAtomicCounterBufferiv, uint, uint, uint, int *)
|
||||
OGL_DEF7(glBindImageTexture, uint, uint, int, byte, int, uint, uint)
|
||||
OGL_DEF1(glMemoryBarrier, uint)
|
||||
OGL_DEF4(glTexStorage1D, uint, int, uint, int)
|
||||
OGL_DEF5(glTexStorage2D, uint, int, uint, int, int)
|
||||
OGL_DEF6(glTexStorage3D, uint, int, uint, int, int, int)
|
||||
OGL_DEF3(glDrawTransformFeedbackInstanced, uint, uint, int)
|
||||
OGL_DEF4(glDrawTransformFeedbackStreamInstanced, uint, uint, uint, int)
|
||||
// GL_API_4_3
|
||||
OGL_DEF5(glClearBufferData, uint, uint, uint, uint, const void *)
|
||||
OGL_DEF7(glClearBufferSubData, uint, uint, iptr, ssize, uint, uint, const void *)
|
||||
OGL_DEF3(glDispatchCompute, uint, uint, uint)
|
||||
OGL_DEF1(glDispatchComputeIndirect, iptr)
|
||||
OGL_DEF15(glCopyImageSubData, uint, uint, int, int, int, int, uint, uint, int, int, int, int, int, int, int)
|
||||
OGL_DEF3(glFramebufferParameteri, uint, uint, int)
|
||||
OGL_DEF3(glGetFramebufferParameteriv, uint, uint, int *)
|
||||
OGL_DEF5(glGetInternalformati64v, uint, uint, uint, int, long *)
|
||||
OGL_DEF8(glInvalidateTexSubImage, uint, int, int, int, int, int, int, int)
|
||||
OGL_DEF2(glInvalidateTexImage, uint, int)
|
||||
OGL_DEF3(glInvalidateBufferSubData, uint, iptr, ssize)
|
||||
OGL_DEF1(glInvalidateBufferData, uint)
|
||||
OGL_DEF3(glInvalidateFramebuffer, uint, int, const uint *)
|
||||
OGL_DEF7(glInvalidateSubFramebuffer, uint, int, const uint *, int, int, int, int)
|
||||
OGL_DEF4(glMultiDrawArraysIndirect, uint, const void *, int, int)
|
||||
OGL_DEF5(glMultiDrawElementsIndirect, uint, uint, const void *, int, int)
|
||||
OGL_DEF4(glGetProgramInterfaceiv, uint, uint, uint, int *)
|
||||
OGL_DEFR3(uint, glGetProgramResourceIndex, uint, uint, const char *)
|
||||
OGL_DEF6(glGetProgramResourceName, uint, uint, uint, int, int *, char *)
|
||||
OGL_DEF8(glGetProgramResourceiv, uint, uint, uint, int, const uint *, int, int *, int *)
|
||||
OGL_DEFR3(int, glGetProgramResourceLocation, uint, uint, const char *)
|
||||
OGL_DEFR3(int, glGetProgramResourceLocationIndex, uint, uint, const char *)
|
||||
OGL_DEF3(glShaderStorageBlockBinding, uint, uint, uint)
|
||||
OGL_DEF5(glTexBufferRange, uint, uint, uint, iptr, ssize)
|
||||
OGL_DEF6(glTexStorage2DMultisample, uint, int, uint, int, int, byte)
|
||||
OGL_DEF7(glTexStorage3DMultisample, uint, int, uint, int, int, int, byte)
|
||||
OGL_DEF8(glTextureView, uint, uint, uint, uint, uint, uint, uint, uint)
|
||||
OGL_DEF4(glBindVertexBuffer, uint, uint, iptr, int)
|
||||
OGL_DEF5(glVertexAttribFormat, uint, int, uint, byte, uint)
|
||||
OGL_DEF4(glVertexAttribIFormat, uint, int, uint, uint)
|
||||
OGL_DEF4(glVertexAttribLFormat, uint, int, uint, uint)
|
||||
OGL_DEF2(glVertexAttribBinding, uint, uint)
|
||||
OGL_DEF2(glVertexBindingDivisor, uint, uint)
|
||||
OGL_DEF6(glDebugMessageControl, uint, uint, uint, int, const uint *, byte)
|
||||
OGL_DEF6(glDebugMessageInsert, uint, uint, uint, uint, int, const char *)
|
||||
OGL_DEF2(glDebugMessageCallback, gldebug_t, const void *)
|
||||
OGL_DEFR8(uint, glGetDebugMessageLog, uint, int, uint *, uint *, uint *, uint *, int *, char *)
|
||||
OGL_DEF4(glPushDebugGroup, uint, uint, int, const char *)
|
||||
OGL_DEF(glPopDebugGroup)
|
||||
OGL_DEF4(glObjectLabel, uint, uint, int, const char *)
|
||||
OGL_DEF5(glGetObjectLabel, uint, uint, int, int *, char *)
|
||||
OGL_DEF3(glObjectPtrLabel, const void *, int, const char *)
|
||||
OGL_DEF4(glGetObjectPtrLabel, const void *, int, int *, char *)
|
||||
OGL_DEF2(glGetPointerv, uint, void **)
|
||||
// GL_API_4_4
|
||||
OGL_DEF4(glBufferStorage, uint, ssize, const void *, uint)
|
||||
OGL_DEF5(glClearTexImage, uint, int, uint, uint, const void *)
|
||||
OGL_DEF11(glClearTexSubImage, uint, int, int, int, int, int, int, int, uint, uint, const void *)
|
||||
OGL_DEF4(glBindBuffersBase, uint, uint, int, const uint *)
|
||||
OGL_DEF6(glBindBuffersRange, uint, uint, int, const uint *, const iptr *, const ssize *)
|
||||
OGL_DEF3(glBindTextures, uint, int, const uint *)
|
||||
OGL_DEF3(glBindSamplers, uint, int, const uint *)
|
||||
OGL_DEF3(glBindImageTextures, uint, int, const uint *)
|
||||
OGL_DEF5(glBindVertexBuffers, uint, int, const uint *, const iptr *, const int *)
|
||||
// GL_API_4_5
|
||||
OGL_DEF2(glClipControl, uint, uint)
|
||||
OGL_DEF2(glCreateTransformFeedbacks, int, uint *)
|
||||
OGL_DEF3(glTransformFeedbackBufferBase, uint, uint, uint)
|
||||
OGL_DEF5(glTransformFeedbackBufferRange, uint, uint, uint, iptr, ssize)
|
||||
OGL_DEF3(glGetTransformFeedbackiv, uint, uint, int *)
|
||||
OGL_DEF4(glGetTransformFeedbacki_v, uint, uint, uint, int *)
|
||||
OGL_DEF4(glGetTransformFeedbacki64_v, uint, uint, uint, long *)
|
||||
OGL_DEF2(glCreateBuffers, int, uint *)
|
||||
OGL_DEF4(glNamedBufferStorage, uint, ssize, const void *, uint)
|
||||
OGL_DEF4(glNamedBufferData, uint, ssize, const void *, uint)
|
||||
OGL_DEF4(glNamedBufferSubData, uint, iptr, ssize, const void *)
|
||||
OGL_DEF5(glCopyNamedBufferSubData, uint, uint, iptr, iptr, ssize)
|
||||
OGL_DEF5(glClearNamedBufferData, uint, uint, uint, uint, const void *)
|
||||
OGL_DEF7(glClearNamedBufferSubData, uint, uint, iptr, ssize, uint, uint, const void *)
|
||||
OGL_DEFR2(void *, glMapNamedBuffer, uint, uint)
|
||||
OGL_DEFR4(void *, glMapNamedBufferRange, uint, iptr, ssize, uint)
|
||||
OGL_DEFR1(byte, glUnmapNamedBuffer, uint)
|
||||
OGL_DEF3(glFlushMappedNamedBufferRange, uint, iptr, ssize)
|
||||
OGL_DEF3(glGetNamedBufferParameteriv, uint, uint, int *)
|
||||
OGL_DEF3(glGetNamedBufferParameteri64v, uint, uint, long *)
|
||||
OGL_DEF3(glGetNamedBufferPointerv, uint, uint, void **)
|
||||
OGL_DEF4(glGetNamedBufferSubData, uint, iptr, ssize, void *)
|
||||
OGL_DEF2(glCreateFramebuffers, int, uint *)
|
||||
OGL_DEF4(glNamedFramebufferRenderbuffer, uint, uint, uint, uint)
|
||||
OGL_DEF3(glNamedFramebufferParameteri, uint, uint, int)
|
||||
OGL_DEF4(glNamedFramebufferTexture, uint, uint, uint, int)
|
||||
OGL_DEF5(glNamedFramebufferTextureLayer, uint, uint, uint, int, int)
|
||||
OGL_DEF2(glNamedFramebufferDrawBuffer, uint, uint)
|
||||
OGL_DEF3(glNamedFramebufferDrawBuffers, uint, int, const uint *)
|
||||
OGL_DEF2(glNamedFramebufferReadBuffer, uint, uint)
|
||||
OGL_DEF3(glInvalidateNamedFramebufferData, uint, int, const uint *)
|
||||
OGL_DEF7(glInvalidateNamedFramebufferSubData, uint, int, const uint *, int, int, int, int)
|
||||
OGL_DEF4(glClearNamedFramebufferiv, uint, uint, int, const int *)
|
||||
OGL_DEF4(glClearNamedFramebufferuiv, uint, uint, int, const uint *)
|
||||
OGL_DEF4(glClearNamedFramebufferfv, uint, uint, int, const float *)
|
||||
OGL_DEF5(glClearNamedFramebufferfi, uint, uint, int, float, int)
|
||||
OGL_DEF12(glBlitNamedFramebuffer, uint, uint, int, int, int, int, int, int, int, int, uint, uint)
|
||||
OGL_DEFR2(uint, glCheckNamedFramebufferStatus, uint, uint)
|
||||
OGL_DEF3(glGetNamedFramebufferParameteriv, uint, uint, int *)
|
||||
OGL_DEF4(glGetNamedFramebufferAttachmentParameteriv, uint, uint, uint, int *)
|
||||
OGL_DEF2(glCreateRenderbuffers, int, uint *)
|
||||
OGL_DEF4(glNamedRenderbufferStorage, uint, uint, int, int)
|
||||
OGL_DEF5(glNamedRenderbufferStorageMultisample, uint, int, uint, int, int)
|
||||
OGL_DEF3(glGetNamedRenderbufferParameteriv, uint, uint, int *)
|
||||
OGL_DEF3(glCreateTextures, uint, int, uint *)
|
||||
OGL_DEF3(glTextureBuffer, uint, uint, uint)
|
||||
OGL_DEF5(glTextureBufferRange, uint, uint, uint, iptr, ssize)
|
||||
OGL_DEF4(glTextureStorage1D, uint, int, uint, int)
|
||||
OGL_DEF5(glTextureStorage2D, uint, int, uint, int, int)
|
||||
OGL_DEF6(glTextureStorage3D, uint, int, uint, int, int, int)
|
||||
OGL_DEF6(glTextureStorage2DMultisample, uint, int, uint, int, int, byte)
|
||||
OGL_DEF7(glTextureStorage3DMultisample, uint, int, uint, int, int, int, byte)
|
||||
OGL_DEF7(glTextureSubImage1D, uint, int, int, int, uint, uint, const void *)
|
||||
OGL_DEF9(glTextureSubImage2D, uint, int, int, int, int, int, uint, uint, const void *)
|
||||
OGL_DEF11(glTextureSubImage3D, uint, int, int, int, int, int, int, int, uint, uint, const void *)
|
||||
OGL_DEF7(glCompressedTextureSubImage1D, uint, int, int, int, uint, int, const void *)
|
||||
OGL_DEF9(glCompressedTextureSubImage2D, uint, int, int, int, int, int, uint, int, const void *)
|
||||
OGL_DEF11(glCompressedTextureSubImage3D, uint, int, int, int, int, int, int, int, uint, int, const void *)
|
||||
OGL_DEF6(glCopyTextureSubImage1D, uint, int, int, int, int, int)
|
||||
OGL_DEF8(glCopyTextureSubImage2D, uint, int, int, int, int, int, int, int)
|
||||
OGL_DEF9(glCopyTextureSubImage3D, uint, int, int, int, int, int, int, int, int)
|
||||
OGL_DEF3(glTextureParameterf, uint, uint, float)
|
||||
OGL_DEF3(glTextureParameterfv, uint, uint, const float *)
|
||||
OGL_DEF3(glTextureParameteri, uint, uint, int)
|
||||
OGL_DEF3(glTextureParameterIiv, uint, uint, const int *)
|
||||
OGL_DEF3(glTextureParameterIuiv, uint, uint, const uint *)
|
||||
OGL_DEF3(glTextureParameteriv, uint, uint, const int *)
|
||||
OGL_DEF1(glGenerateTextureMipmap, uint)
|
||||
OGL_DEF2(glBindTextureUnit, uint, uint)
|
||||
OGL_DEF6(glGetTextureImage, uint, int, uint, uint, int, void *)
|
||||
OGL_DEF4(glGetCompressedTextureImage, uint, int, int, void *)
|
||||
OGL_DEF4(glGetTextureLevelParameterfv, uint, int, uint, float *)
|
||||
OGL_DEF4(glGetTextureLevelParameteriv, uint, int, uint, int *)
|
||||
OGL_DEF3(glGetTextureParameterfv, uint, uint, float *)
|
||||
OGL_DEF3(glGetTextureParameterIiv, uint, uint, int *)
|
||||
OGL_DEF3(glGetTextureParameterIuiv, uint, uint, uint *)
|
||||
OGL_DEF3(glGetTextureParameteriv, uint, uint, int *)
|
||||
OGL_DEF2(glCreateVertexArrays, int, uint *)
|
||||
OGL_DEF2(glDisableVertexArrayAttrib, uint, uint)
|
||||
OGL_DEF2(glEnableVertexArrayAttrib, uint, uint)
|
||||
OGL_DEF2(glVertexArrayElementBuffer, uint, uint)
|
||||
OGL_DEF5(glVertexArrayVertexBuffer, uint, uint, uint, iptr, int)
|
||||
OGL_DEF6(glVertexArrayVertexBuffers, uint, uint, int, const uint *, const iptr *, const int *)
|
||||
OGL_DEF3(glVertexArrayAttribBinding, uint, uint, uint)
|
||||
OGL_DEF6(glVertexArrayAttribFormat, uint, uint, int, uint, byte, uint)
|
||||
OGL_DEF5(glVertexArrayAttribIFormat, uint, uint, int, uint, uint)
|
||||
OGL_DEF5(glVertexArrayAttribLFormat, uint, uint, int, uint, uint)
|
||||
OGL_DEF3(glVertexArrayBindingDivisor, uint, uint, uint)
|
||||
OGL_DEF3(glGetVertexArrayiv, uint, uint, int *)
|
||||
OGL_DEF4(glGetVertexArrayIndexediv, uint, uint, uint, int *)
|
||||
OGL_DEF4(glGetVertexArrayIndexed64iv, uint, uint, uint, long *)
|
||||
OGL_DEF2(glCreateSamplers, int, uint *)
|
||||
OGL_DEF2(glCreateProgramPipelines, int, uint *)
|
||||
OGL_DEF3(glCreateQueries, uint, int, uint *)
|
||||
OGL_DEF4(glGetQueryBufferObjecti64v, uint, uint, uint, iptr)
|
||||
OGL_DEF4(glGetQueryBufferObjectiv, uint, uint, uint, iptr)
|
||||
OGL_DEF4(glGetQueryBufferObjectui64v, uint, uint, uint, iptr)
|
||||
OGL_DEF4(glGetQueryBufferObjectuiv, uint, uint, uint, iptr)
|
||||
OGL_DEF1(glMemoryBarrierByRegion, uint)
|
||||
OGL_DEF12(glGetTextureSubImage, uint, int, int, int, int, int, int, int, uint, uint, int, void *)
|
||||
OGL_DEF10(glGetCompressedTextureSubImage, uint, int, int, int, int, int, int, int, int, void *)
|
||||
OGL_DEFR(uint, glGetGraphicsResetStatus)
|
||||
OGL_DEF4(glGetnCompressedTexImage, uint, int, int, void *)
|
||||
OGL_DEF6(glGetnTexImage, uint, int, uint, uint, int, void *)
|
||||
OGL_DEF4(glGetnUniformdv, uint, int, int, double *)
|
||||
OGL_DEF4(glGetnUniformfv, uint, int, int, float *)
|
||||
OGL_DEF4(glGetnUniformiv, uint, int, int, int *)
|
||||
OGL_DEF4(glGetnUniformuiv, uint, int, int, uint *)
|
||||
OGL_DEF8(glReadnPixels, int, int, int, int, uint, uint, int, void *)
|
||||
OGL_DEF4(glGetnMapdv, uint, uint, int, double *)
|
||||
OGL_DEF4(glGetnMapfv, uint, uint, int, float *)
|
||||
OGL_DEF4(glGetnMapiv, uint, uint, int, int *)
|
||||
OGL_DEF3(glGetnPixelMapfv, uint, int, float *)
|
||||
OGL_DEF3(glGetnPixelMapuiv, uint, int, uint *)
|
||||
OGL_DEF3(glGetnPixelMapusv, uint, int, ushort *)
|
||||
OGL_DEF2(glGetnPolygonStipple, int, byte *)
|
||||
OGL_DEF5(glGetnColorTable, uint, uint, uint, int, void *)
|
||||
OGL_DEF5(glGetnConvolutionFilter, uint, uint, uint, int, void *)
|
||||
OGL_DEF8(glGetnSeparableFilter, uint, uint, uint, int, void *, int, void *, void *)
|
||||
OGL_DEF6(glGetnHistogram, uint, byte, uint, uint, int, void *)
|
||||
OGL_DEF6(glGetnMinmax, uint, byte, uint, uint, int, void *)
|
||||
OGL_DEF(glTextureBarrier)
|
||||
// GL_API_4_6
|
||||
OGL_DEF5(glSpecializeShader, uint, const char *, uint, const uint *, const uint *)
|
||||
OGL_DEF5(glMultiDrawArraysIndirectCount, uint, const void *, iptr, int, int)
|
||||
OGL_DEF6(glMultiDrawElementsIndirectCount, uint, uint, const void *, iptr, int, int)
|
||||
OGL_DEF3(glPolygonOffsetClamp, float, float, float)
|
195
gl_loader.h
Normal file
|
@ -0,0 +1,195 @@
|
|||
|
||||
#ifdef GLFNC_DEBUG
|
||||
|
||||
void gl_check_error(const char *name);
|
||||
|
||||
#define OGL_NNAME(f) gl_debug_ ## f
|
||||
#define OGL_DFUNCV(f, t, u) void gl_checked_ ## f t { OGL_NNAME(f)u; gl_check_error(STRINGIZE(f)); }
|
||||
#define OGL_DFUNCR(r, f, t, u) r gl_checked_ ## f t { r ret; ret = OGL_NNAME(f)u; gl_check_error(STRINGIZE(f)); return ret; }
|
||||
#else
|
||||
|
||||
void sys_panic(const char *error, const char *fmt, ...);
|
||||
|
||||
#define OGL_DEFINE(r, f, z) r (*OGL_NNAME(f))z;
|
||||
#define OGL_CHECKPTR(f) sys_assert(OGL_NNAME(f)); logt(LOG_GFX, "%s -> $%llx", STRINGIZE(f), OGL_NNAME(f)); cnt++;
|
||||
#define OGL_ISETPTR(r, f, z) OGL_NNAME(f) = (r (*)z)(load(STRINGIZE(f))); OGL_CHECKPTR(f)
|
||||
|
||||
#define OGL_NNAME(f) f
|
||||
#define OGL_DFUNCV(f, t, u)
|
||||
#define OGL_DFUNCR(r, f, t, u)
|
||||
#endif
|
||||
|
||||
#ifdef GLFNC_DEBUG
|
||||
#define OGL_SETPTR(r, f, z) OGL_ISETPTR(r, f, z) f = gl_checked_ ## f;
|
||||
#else
|
||||
#define OGL_SETPTR(r, f, z) OGL_ISETPTR(r, f, z)
|
||||
#endif
|
||||
|
||||
#define OGL_DEF(f) OGL_DEFINE(void, f, ()) \
|
||||
OGL_DFUNCV(f, (), ())
|
||||
#define OGL_DEFR(r, f) OGL_DEFINE(r, f, ()) \
|
||||
OGL_DFUNCR(r, f, (), ())
|
||||
#define OGL_DEF1(f, p1) OGL_DEFINE(void, f, (p1)) \
|
||||
OGL_DFUNCV(f, (p1 v1), (v1))
|
||||
#define OGL_DEFR1(r, f, p1) OGL_DEFINE(r, f, (p1)) \
|
||||
OGL_DFUNCR(r, f, (p1 v1), (v1))
|
||||
#define OGL_DEF2(f, p1, p2) OGL_DEFINE(void, f, (p1, p2)) \
|
||||
OGL_DFUNCV(f, (p1 v1, p2 v2), (v1, v2))
|
||||
#define OGL_DEFR2(r, f, p1, p2) OGL_DEFINE(r, f, (p1, p2)) \
|
||||
OGL_DFUNCR(r, f, (p1 v1, p2 v2), (v1, v2))
|
||||
#define OGL_DEF3(f, p1, p2, p3) OGL_DEFINE(void, f, (p1, p2, p3)) \
|
||||
OGL_DFUNCV(f, (p1 v1, p2 v2, p3 v3), (v1, v2, v3))
|
||||
#define OGL_DEFR3(r, f, p1, p2, p3) OGL_DEFINE(r, f, (p1, p2, p3)) \
|
||||
OGL_DFUNCR(r, f, (p1 v1, p2 v2, p3 v3), (v1, v2, v3))
|
||||
#define OGL_DEF4(f, p1, p2, p3, p4) OGL_DEFINE(void, f, (p1, p2, p3, p4)) \
|
||||
OGL_DFUNCV(f, (p1 v1, p2 v2, p3 v3, p4 v4), (v1, v2, v3, v4))
|
||||
#define OGL_DEFR4(r, f, p1, p2, p3, p4) OGL_DEFINE(r, f, (p1, p2, p3, p4)) \
|
||||
OGL_DFUNCR(r, f, (p1 v1, p2 v2, p3 v3, p4 v4), (v1, v2, v3, v4))
|
||||
#define OGL_DEF5(f, p1, p2, p3, p4, p5) OGL_DEFINE(void, f, (p1, p2, p3, p4, p5)) \
|
||||
OGL_DFUNCV(f, (p1 v1, p2 v2, p3 v3, p4 v4, p5 v5), (v1, v2, v3, v4, v5))
|
||||
#define OGL_DEF6(f, p1, p2, p3, p4, p5, p6) OGL_DEFINE(void, f, (p1, p2, p3, p4, p5, p6)) \
|
||||
OGL_DFUNCV(f, (p1 v1, p2 v2, p3 v3, p4 v4, p5 v5, p6 v6), (v1, v2, v3, v4, v5, v6))
|
||||
#define OGL_DEF7(f, p1, p2, p3, p4, p5, p6, p7) OGL_DEFINE(void, f, (p1, p2, p3, p4, p5, p6, p7)) \
|
||||
OGL_DFUNCV(f, (p1 v1, p2 v2, p3 v3, p4 v4, p5 v5, p6 v6, p7 v7), (v1, v2, v3, v4, v5, v6, v7))
|
||||
#define OGL_DEF8(f, p1, p2, p3, p4, p5, p6, p7, p8) OGL_DEFINE(void, f, (p1, p2, p3, p4, p5, p6, p7, p8)) \
|
||||
OGL_DFUNCV(f, (p1 v1, p2 v2, p3 v3, p4 v4, p5 v5, p6 v6, p7 v7, p8 v8), (v1, v2, v3, v4, v5, v6, v7, v8))
|
||||
#define OGL_DEFR8(r, f, p1, p2, p3, p4, p5, p6, p7, p8) OGL_DEFINE(r, f, (p1, p2, p3, p4, p5, p6, p7, p8)) \
|
||||
OGL_DFUNCR(r, f, (p1 v1, p2 v2, p3 v3, p4 v4, p5 v5, p6 v6, p7 v7, p8 v8), (v1, v2, v3, v4, v5, v6, v7, v8))
|
||||
#define OGL_DEF9(f, p1, p2, p3, p4, p5, p6, p7, p8, p9) OGL_DEFINE(void, f, (p1, p2, p3, p4, p5, p6, p7, p8, p9)) \
|
||||
OGL_DFUNCV(f, (p1 v1, p2 v2, p3 v3, p4 v4, p5 v5, p6 v6, p7 v7, p8 v8, p9 v9), (v1, v2, v3, v4, v5, v6, v7, v8, v9))
|
||||
#define OGL_DEF10(f, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10) OGL_DEFINE(void, f, (p1, p2, p3, p4, p5, p6, p7, p8, p9, p10)) \
|
||||
OGL_DFUNCV(f, (p1 v1, p2 v2, p3 v3, p4 v4, p5 v5, p6 v6, p7 v7, p8 v8, p9 v9, p10 v10), (v1, v2, v3, v4, v5, v6, v7, v8, v9, v10))
|
||||
#define OGL_DEF11(f, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11) OGL_DEFINE(void, f, (p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11)) \
|
||||
OGL_DFUNCV(f, (p1 v1, p2 v2, p3 v3, p4 v4, p5 v5, p6 v6, p7 v7, p8 v8, p9 v9, p10 v10, p11 v11), (v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11))
|
||||
#define OGL_DEF12(f, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12) OGL_DEFINE(void, f, (p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12)) \
|
||||
OGL_DFUNCV(f, (p1 v1, p2 v2, p3 v3, p4 v4, p5 v5, p6 v6, p7 v7, p8 v8, p9 v9, p10 v10, p11 v11, p12 v12), (v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12))
|
||||
#define OGL_DEF15(f, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15) OGL_DEFINE(void, f, (p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15)) \
|
||||
OGL_DFUNCV(f, (p1 v1, p2 v2, p3 v3, p4 v4, p5 v5, p6 v6, p7 v7, p8 v8, p9 v9, p10 v10, p11 v11, p12 v12, p13 v13, p14 v14, p15 v15), (v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15))
|
||||
|
||||
#include "gl_functions.h"
|
||||
|
||||
#undef OGL_DEF
|
||||
#undef OGL_DEFR
|
||||
#undef OGL_DEF1
|
||||
#undef OGL_DEFR1
|
||||
#undef OGL_DEF2
|
||||
#undef OGL_DEFR2
|
||||
#undef OGL_DEF3
|
||||
#undef OGL_DEFR3
|
||||
#undef OGL_DEF4
|
||||
#undef OGL_DEFR4
|
||||
#undef OGL_DEF5
|
||||
#undef OGL_DEF6
|
||||
#undef OGL_DEF7
|
||||
#undef OGL_DEF8
|
||||
#undef OGL_DEFR8
|
||||
#undef OGL_DEF9
|
||||
#undef OGL_DEF10
|
||||
#undef OGL_DEF11
|
||||
#undef OGL_DEF12
|
||||
#undef OGL_DEF15
|
||||
|
||||
#ifdef GLFNC_DEBUG
|
||||
|
||||
#define OGL_TESTERROR OGL_NNAME(glGetError)
|
||||
|
||||
void gl_check_error(const char *name) {
|
||||
uint error;
|
||||
if((error = OGL_TESTERROR()) != GL_NO_ERROR) {
|
||||
loge(LOG_GFX, STR_OGL_ERR, error, name);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#define OGL_DEF(f) OGL_SETPTR(void, f, ())
|
||||
#define OGL_DEFR(r, f) OGL_SETPTR(r, f, ())
|
||||
#define OGL_DEF1(f, p1) OGL_SETPTR(void, f, (p1))
|
||||
#define OGL_DEFR1(r, f, p1) OGL_SETPTR(r, f, (p1))
|
||||
#define OGL_DEF2(f, p1, p2) OGL_SETPTR(void, f, (p1, p2))
|
||||
#define OGL_DEFR2(r, f, p1, p2) OGL_SETPTR(r, f, (p1, p2))
|
||||
#define OGL_DEF3(f, p1, p2, p3) OGL_SETPTR(void, f, (p1, p2, p3))
|
||||
#define OGL_DEFR3(r, f, p1, p2, p3) OGL_SETPTR(r, f, (p1, p2, p3))
|
||||
#define OGL_DEF4(f, p1, p2, p3, p4) OGL_SETPTR(void, f, (p1, p2, p3, p4))
|
||||
#define OGL_DEFR4(r, f, p1, p2, p3, p4) OGL_SETPTR(r, f, (p1, p2, p3, p4))
|
||||
#define OGL_DEF5(f, p1, p2, p3, p4, p5) OGL_SETPTR(void, f, (p1, p2, p3, p4, p5))
|
||||
#define OGL_DEF6(f, p1, p2, p3, p4, p5, p6) OGL_SETPTR(void, f, (p1, p2, p3, p4, p5, p6))
|
||||
#define OGL_DEF7(f, p1, p2, p3, p4, p5, p6, p7) OGL_SETPTR(void, f, (p1, p2, p3, p4, p5, p6, p7))
|
||||
#define OGL_DEF8(f, p1, p2, p3, p4, p5, p6, p7, p8) OGL_SETPTR(void, f, (p1, p2, p3, p4, p5, p6, p7, p8))
|
||||
#define OGL_DEFR8(r, f, p1, p2, p3, p4, p5, p6, p7, p8) OGL_SETPTR(r, f, (p1, p2, p3, p4, p5, p6, p7, p8))
|
||||
#define OGL_DEF9(f, p1, p2, p3, p4, p5, p6, p7, p8, p9) OGL_SETPTR(void, f, (p1, p2, p3, p4, p5, p6, p7, p8, p9))
|
||||
#define OGL_DEF10(f, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10) OGL_SETPTR(void, f, (p1, p2, p3, p4, p5, p6, p7, p8, p9, p10))
|
||||
#define OGL_DEF11(f, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11) OGL_SETPTR(void, f, (p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11))
|
||||
#define OGL_DEF12(f, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12) OGL_SETPTR(void, f, (p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12))
|
||||
#define OGL_DEF15(f, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15) OGL_SETPTR(void, f, (p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15))
|
||||
|
||||
int
|
||||
#ifdef GLFNC_DEBUG
|
||||
gl_load_dbg_funcs
|
||||
#else
|
||||
gl_load_functions
|
||||
#endif
|
||||
(void * (*load)(const char *)) {
|
||||
int cnt = 0;
|
||||
#include "gl_functions.h"
|
||||
logd(LOG_GFX, STR_OGL_LOADED, cnt);
|
||||
return cnt;
|
||||
}
|
||||
|
||||
#undef OGL_DEF
|
||||
#undef OGL_DEFR
|
||||
#undef OGL_DEF1
|
||||
#undef OGL_DEFR1
|
||||
#undef OGL_DEF2
|
||||
#undef OGL_DEFR2
|
||||
#undef OGL_DEF3
|
||||
#undef OGL_DEFR3
|
||||
#undef OGL_DEF4
|
||||
#undef OGL_DEFR4
|
||||
#undef OGL_DEF5
|
||||
#undef OGL_DEF6
|
||||
#undef OGL_DEF7
|
||||
#undef OGL_DEF8
|
||||
#undef OGL_DEFR8
|
||||
#undef OGL_DEF9
|
||||
#undef OGL_DEF10
|
||||
#undef OGL_DEF11
|
||||
#undef OGL_DEF12
|
||||
#undef OGL_DEF15
|
||||
|
||||
#ifdef GLFNC_DEBUG
|
||||
|
||||
#define OGL_TESTSTRING OGL_NNAME(glGetString)
|
||||
|
||||
byte gl_init(void * (*load)(const char *), byte debug) {
|
||||
int major, minor;
|
||||
const char* version;
|
||||
OGL_TESTSTRING = (const byte * (*)(uint))(load("glGetString"));
|
||||
if((OGL_TESTSTRING == NULL) || !(version = OGL_TESTSTRING(GL_VERSION))) {
|
||||
loge(LOG_GFX, STR_OGL_LOADER_ERR);
|
||||
return 0;
|
||||
}
|
||||
if(!strncmp(version, "OpenGL ES", 9) || (sscanf(version, "%d.%d", &major, &minor) != 2)) {
|
||||
loge(LOG_GFX, STR_OGL_COMPAT, version);
|
||||
return 0;
|
||||
}
|
||||
if(major < 4 || ((major == 4) && (minor < 6))) {
|
||||
loge(LOG_GFX, STR_OGL_OLD, major, minor);
|
||||
return 0;
|
||||
}
|
||||
if(debug)
|
||||
gl_load_dbg_funcs(load);
|
||||
else
|
||||
gl_load_functions(load);
|
||||
return 1;
|
||||
}
|
||||
|
||||
#undef GLFNC_DEBUG
|
||||
#else
|
||||
#define GLFNC_DEBUG
|
||||
#endif
|
||||
|
||||
#undef OGL_NNAME
|
||||
#undef OGL_DFUNCV
|
||||
#undef OGL_DFUNCR
|
||||
#undef OGL_SETPTR
|
9
gl_types.h
Normal file
|
@ -0,0 +1,9 @@
|
|||
|
||||
#if ((defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || defined(__GNUC__) || defined(__SCO__) || defined(__USLC__)) && defined(__SIZEOF_LONG__) && defined(__SIZEOF_POINTER__) && (__SIZEOF_POINTER__ > __SIZEOF_LONG__)
|
||||
typedef intptr_t iptr;
|
||||
#else
|
||||
typedef signed long int iptr;
|
||||
#endif
|
||||
typedef signed long int ssize;
|
||||
typedef struct __GLsync *sync_t;
|
||||
typedef void (*gldebug_t)(uint, uint, uint, uint, int, const char *, const void *);
|
58
glx_stub.h
Normal file
|
@ -0,0 +1,58 @@
|
|||
|
||||
#define GLX_RGBA_BIT 0x00000001
|
||||
#define GLX_WINDOW_BIT 0x00000001
|
||||
#define GLX_DRAWABLE_TYPE 0x8010
|
||||
#define GLX_RENDER_TYPE 0x8011
|
||||
#define GLX_RGBA_TYPE 0x8014
|
||||
#define GLX_DOUBLEBUFFER 5
|
||||
#define GLX_RED_SIZE 8
|
||||
#define GLX_GREEN_SIZE 9
|
||||
#define GLX_BLUE_SIZE 10
|
||||
#define GLX_ALPHA_SIZE 11
|
||||
#define GLX_DEPTH_SIZE 12
|
||||
#define GLX_STENCIL_SIZE 13
|
||||
#define GLX_SAMPLE_BUFFERS 0x186a0
|
||||
|
||||
#define GLX_CONTEXT_DEBUG_BIT_ARB 0x00000001
|
||||
#define GLX_CONTEXT_FLAGS_ARB 0x2094
|
||||
#define GLX_CONTEXT_OPENGL_NO_ERROR_ARB 0x31b3
|
||||
|
||||
typedef XID GLXWindow;
|
||||
typedef XID GLXDrawable;
|
||||
typedef struct __GLXFBConfig* GLXFBConfig;
|
||||
typedef struct __GLXcontext* GLXContext;
|
||||
typedef void (*__GLXextproc)(void);
|
||||
|
||||
typedef int (*PFNGLXGETFBCONFIGATTRIBPROC)(Display*,GLXFBConfig,int,int*);
|
||||
typedef const char* (*PFNGLXGETCLIENTSTRINGPROC)(Display*,int);
|
||||
typedef Bool (*PFNGLXQUERYEXTENSIONPROC)(Display*,int*,int*);
|
||||
typedef Bool (*PFNGLXQUERYVERSIONPROC)(Display*,int*,int*);
|
||||
typedef void (*PFNGLXDESTROYCONTEXTPROC)(Display*,GLXContext);
|
||||
typedef Bool (*PFNGLXMAKECURRENTPROC)(Display*,GLXDrawable,GLXContext);
|
||||
typedef void (*PFNGLXSWAPBUFFERSPROC)(Display*,GLXDrawable);
|
||||
typedef const char* (*PFNGLXQUERYEXTENSIONSSTRINGPROC)(Display*,int);
|
||||
typedef GLXFBConfig* (*PFNGLXGETFBCONFIGSPROC)(Display*,int,int*);
|
||||
typedef GLXContext (*PFNGLXCREATENEWCONTEXTPROC)(Display*,GLXFBConfig,int,GLXContext,Bool);
|
||||
typedef __GLXextproc (* PFNGLXGETPROCADDRESSPROC)(const byte *procName);
|
||||
typedef void (*PFNGLXSWAPINTERVALEXTPROC)(Display*,GLXDrawable,int);
|
||||
typedef XVisualInfo* (*PFNGLXGETVISUALFROMFBCONFIGPROC)(Display*,GLXFBConfig);
|
||||
typedef GLXWindow (*PFNGLXCREATEWINDOWPROC)(Display*,GLXFBConfig,Window,const int*);
|
||||
typedef void (*PFNGLXDESTROYWINDOWPROC)(Display*,GLXWindow);
|
||||
|
||||
typedef int (*PFNGLXSWAPINTERVALMESAPROC)(int);
|
||||
typedef int (*PFNGLXSWAPINTERVALSGIPROC)(int);
|
||||
typedef GLXContext (*PFNGLXCREATECONTEXTATTRIBSARBPROC)(Display*,GLXFBConfig,GLXContext,Bool,const int*);
|
||||
|
||||
#define glXGetFBConfigs wcf.GetFBConfigs
|
||||
#define glXGetFBConfigAttrib wcf.GetFBConfigAttrib
|
||||
#define glXGetClientString wcf.GetClientString
|
||||
#define glXQueryExtension wcf.QueryExtension
|
||||
#define glXQueryVersion wcf.QueryVersion
|
||||
#define glXDestroyContext wcf.DestroyContext
|
||||
#define glXMakeCurrent wcf.MakeCurrent
|
||||
#define glXSwapBuffers wcf.SwapBuffers
|
||||
#define glXQueryExtensionsString wcf.QueryExtensionsString
|
||||
#define glXCreateNewContext wcf.CreateNewContext
|
||||
#define glXGetVisualFromFBConfig wcf.GetVisualFromFBConfig
|
||||
#define glXCreateWindow wcf.CreateWindow
|
||||
#define glXDestroyWindow wcf.DestroyWindow
|
5
inttypes.h
Normal file
|
@ -0,0 +1,5 @@
|
|||
|
||||
typedef unsigned char byte;
|
||||
typedef unsigned short ushort;
|
||||
typedef unsigned int uint;
|
||||
typedef unsigned long ulong;
|
215
lighting.h
Normal file
|
@ -0,0 +1,215 @@
|
|||
|
||||
/*
|
||||
void light_set_shader(light_t *light, uint id) {
|
||||
int pos;
|
||||
char str[32];
|
||||
pos = sprintf(str, "lights[%d].", id);
|
||||
sprintf(str+pos, "position");
|
||||
shd_vec3(str, light->pos);
|
||||
sprintf(str+pos, "ambient");
|
||||
shd_vec3(str, light->ambient);
|
||||
sprintf(str+pos, "diffuse");
|
||||
shd_vec3(str, light->diffuse);
|
||||
sprintf(str+pos, "specular");
|
||||
shd_vec3(str, light->specular);
|
||||
sprintf(str+pos, "range");
|
||||
shd_vec3(str, light->range);
|
||||
sprintf(str+pos, "constant");
|
||||
shd_float(str, light->constant);
|
||||
sprintf(str+pos, "linear");
|
||||
shd_float(str, light->linear);
|
||||
sprintf(str+pos, "quadratic");
|
||||
shd_float(str, light->quadratic);
|
||||
sprintf(str+pos, "enabled");
|
||||
shd_bool(str, 1);
|
||||
}
|
||||
|
||||
void light_unset_shader(uint id) {
|
||||
char str[32];
|
||||
sprintf(str, "lights[%d].enabled", id);
|
||||
shd_bool(str, 0);
|
||||
}
|
||||
*/
|
||||
|
||||
void light_calc(world_t *world) {
|
||||
int x1 = ((int)world->camera.pos_x) / CHUNK_SIZE;
|
||||
int y1 = ((int)world->camera.pos_y) / CHUNK_SIZE;
|
||||
int z1 = ((int)world->camera.pos_z) / CHUNK_SIZE;
|
||||
int x2 = x1 + gdr.light_dist_chunk;
|
||||
int y2 = y1 + gdr.light_dist_chunk;
|
||||
int z2 = z1 + gdr.light_dist_chunk;
|
||||
ulong pos;
|
||||
chunk_t *chunk;
|
||||
light_t *light;
|
||||
x1 -= gdr.light_dist_chunk;
|
||||
y1 -= gdr.light_dist_chunk;
|
||||
z1 -= gdr.light_dist_chunk;
|
||||
// x1 = CHUNK_CLAMP(world, x1, x);
|
||||
// y1 = CHUNK_CLAMP(world, y1, y);
|
||||
// z1 = CHUNK_CLAMP(world, z1, z);
|
||||
// x2 = CHUNK_CLAMP(world, x2, x);
|
||||
// y2 = CHUNK_CLAMP(world, y2, y);
|
||||
// z2 = CHUNK_CLAMP(world, z2, z);
|
||||
// glBufferData(GL_UNIFORM_BUFFER, sizeof(float) * 18 * gdr.light_max, NULL, GL_DYNAMIC_DRAW);
|
||||
// memset(world->lights, 0, sizeof(light_t) * gdr.light_max);
|
||||
world->s_lights = 0;
|
||||
if(!gdr.light_max)
|
||||
return;
|
||||
glBindBuffer(GL_UNIFORM_BUFFER, world->light_buf);
|
||||
for(int cx = x1; cx <= x2; cx++) {
|
||||
for(int cz = z1; cz <= z2; cz++) {
|
||||
for(int cy = y1; cy <= y2; cy++) {
|
||||
if(!(chunk = chunk_get(world, cx, cy, cz, 0)))
|
||||
continue;
|
||||
pos = 0;
|
||||
while(light = tbl_iter(&chunk->light_table, &pos)) {
|
||||
// if(nndist) {
|
||||
// if(light_add(world, light) == 0xffffffff)
|
||||
// return;
|
||||
glBufferSubData(GL_UNIFORM_BUFFER, LIGHT_SSIZE * world->s_lights, LIGHT_SSIZE, light);
|
||||
// memcpy(&world->lights[world->s_lights], light, sizeof(shdlight_t));
|
||||
if((world->s_lights += 1) >= gdr.light_max) {
|
||||
glBindBuffer(GL_UNIFORM_BUFFER, 0);
|
||||
return;
|
||||
}
|
||||
// }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
glBindBuffer(GL_UNIFORM_BUFFER, 0);
|
||||
}
|
||||
|
||||
/*
|
||||
uint light_add(float x, float y, float z, uint color) {
|
||||
light_t *light;
|
||||
uint id;
|
||||
if(!(world->lights))
|
||||
return 0xffffffff;
|
||||
if((id = lst_push(&world->light_list)) == 0xffffffff)
|
||||
return 0xffffffff;
|
||||
light = &world->lights[id];
|
||||
light_init_def(light, x, y, z, color);
|
||||
shd_sel(gdr.shd_world, 0);
|
||||
light_set_shader(light, id);
|
||||
world->s_lights += 1;
|
||||
shd_int("n_lights", world->s_lights);
|
||||
logd("TST", "l %d @ %.3f %.3f %.3f: %06x, %.1f %.1f %.1f", id, x, y, z, color, light->diffuse[0], light->diffuse[1], light->diffuse[2]);
|
||||
return id;
|
||||
}
|
||||
*/
|
||||
|
||||
// void light_remove(world_t *world, uint id) {
|
||||
// lst_pop(&world->light_list, id);
|
||||
// shd_sel(gdr.shd_world, world);
|
||||
// glBindBuffer(GL_UNIFORM_BUFFER, world->light_buf);
|
||||
// light_unset_shader(id);
|
||||
// world->s_lights -= 1;
|
||||
// shd_int("n_lights", world->s_lights);
|
||||
// }
|
||||
|
||||
// void light_refresh() {
|
||||
// if(world->world)
|
||||
// light_calc(world->world);
|
||||
// /*
|
||||
// for(int z = 0; z < gdr.light_max; z++) {
|
||||
// light_add(((float)(rand() % 20000)) / 100.0f - 100.0f, 1.0f, ((float)(rand() % 20000)) / 100.0f - 100.0f, (rand() % 0xffffff) | 0x404040);
|
||||
// }
|
||||
// */
|
||||
// }
|
||||
|
||||
// void light_end(world_t *world) {
|
||||
// if(world->lights) {
|
||||
// mem_free(world->lights);
|
||||
// world->lights = NULL;
|
||||
// }
|
||||
// }
|
||||
|
||||
// void light_init(world_t *world) {
|
||||
// light_end(world);
|
||||
// if(gdr.light_max)
|
||||
// world->lights = mem_alloc(sizeof(light_t) * gdr.light_max, MEM_LIGHTS);
|
||||
// light_calc(world);
|
||||
// }
|
||||
|
||||
void light_setup(int max) {
|
||||
window_t *win;
|
||||
gdr.light_max = max;
|
||||
shd_refresh();
|
||||
for(win = wcf.window_list; win; win = win->next) {
|
||||
if(win->world) {
|
||||
glNamedBufferData(win->world->light_buf, LIGHT_SSIZE * gdr.light_max, NULL, GL_DYNAMIC_DRAW);
|
||||
light_calc(win->world);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
void light_map_fill(const float *polys, int n_polys, uint color, float fog) {
|
||||
buf_data(gdr.buf_lightmap, polys, n_polys * 3);
|
||||
glBindVertexArray(gdr.vao_lightmap);
|
||||
shd_sel(gdr.shd_lightmap, 1);
|
||||
shd_vec2v("size", (float)(TEMP_LM_SIZE * CHUNK_SIZE), (float)(TEMP_LM_SIZE * CHUNK_SIZE));
|
||||
shd_scolor("color", color);
|
||||
shd_float("fog", fog);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, gdr.fb_lightmap);
|
||||
glViewport(0, 0, TEMP_LM_SIZE * CHUNK_SIZE, TEMP_LM_SIZE * CHUNK_SIZE);
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
glDisable(GL_BLEND);
|
||||
glDrawArrays(GL_TRIANGLES, 0, n_polys * 3);
|
||||
glEnable(GL_BLEND);
|
||||
glViewport(0, 0, wcf.current->fb_x, wcf.current->fb_y);
|
||||
buf_data(gdr.buf_lightmap, NULL, 0);
|
||||
}
|
||||
|
||||
void light_map_rect(int x1, int z1, int x2, int z2, uint color, float fog) {
|
||||
x2 -= x1;
|
||||
z2 -= z1;
|
||||
x1 += (CHUNK_SIZE * (TEMP_LM_SIZE / 2));
|
||||
z1 += (CHUNK_SIZE * (TEMP_LM_SIZE / 2));
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, gdr.fb_lightmap);
|
||||
glClearColor(
|
||||
(float)((uint)((color >> 16) & 0xff)) / 255.0f,
|
||||
(float)((uint)((color >> 8) & 0xff)) / 255.0f,
|
||||
(float)((uint)(color & 0xff)) / 255.0f,
|
||||
fog);
|
||||
glViewport(0, 0, TEMP_LM_SIZE * CHUNK_SIZE, TEMP_LM_SIZE * CHUNK_SIZE);
|
||||
glScissor(x1, z1, x2, z2);
|
||||
// logd(LOG_SYS, "n %d %d %d %d", x1, z1, x2, z2);
|
||||
glEnable(GL_SCISSOR_TEST);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
glDisable(GL_SCISSOR_TEST);
|
||||
glViewport(0, 0, wcf.current->fb_x, wcf.current->fb_y);
|
||||
}
|
||||
|
||||
void light_map_clear() {
|
||||
fb_size(gdr.fbt_lightmap, TEMP_LM_SIZE * CHUNK_SIZE, TEMP_LM_SIZE * CHUNK_SIZE);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, gdr.fb_lightmap);
|
||||
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
}
|
||||
*/
|
||||
|
||||
void light_init_base(light_t *light, light_b *lamp) {
|
||||
float r = (float)((uint)((lamp->color >> 16) & 0xff)) / 255.0f;
|
||||
float g = (float)((uint)((lamp->color >> 8) & 0xff)) / 255.0f;
|
||||
float b = (float)((uint)(lamp->color & 0xff)) / 255.0f;
|
||||
VEC3_SET(light->ambient, r * lamp->amb_fact, g * lamp->amb_fact, b * lamp->amb_fact);
|
||||
VEC3_SET(light->diffuse, r * lamp->dif_fact, g * lamp->dif_fact, b * lamp->dif_fact);
|
||||
VEC3_SET(light->specular, r, g, b);
|
||||
VEC3_SET(light->range, lamp->range_xz, lamp->range_y, lamp->range_xz);
|
||||
light->constant = lamp->constant;
|
||||
light->linear = lamp->linear;
|
||||
light->quadratic = lamp->quadratic;
|
||||
}
|
||||
|
||||
void light_init_def(light_b *light, uint color, float brightness) {
|
||||
light->color = color;
|
||||
light->amb_fact = brightness;
|
||||
light->dif_fact = MIN_VALUE(brightness * 16.0f, 1.0f);
|
||||
light->range_xz = 1.0f;
|
||||
light->range_y = 1.0f;
|
||||
light->constant = 1.0f;
|
||||
light->linear = 0.09f;
|
||||
light->quadratic = 0.032f;
|
||||
}
|
85
list.h
Normal file
|
@ -0,0 +1,85 @@
|
|||
|
||||
uint lst_push(list_t *list) {
|
||||
list_e *elem = list->free;
|
||||
if(elem == NULL) {
|
||||
return 0xffffffff;
|
||||
}
|
||||
list->free = list->free->f_next ? list->free->f_next : list->free->f_prev;
|
||||
if(elem->f_prev) {
|
||||
elem->f_prev->f_next = elem->f_next;
|
||||
}
|
||||
if(elem->f_next) {
|
||||
elem->f_next->f_prev = elem->f_prev;
|
||||
}
|
||||
elem->f_next = elem->f_prev = NULL;
|
||||
if(list->used && list->used->u_prev) {
|
||||
list->used->u_prev->u_next = elem;
|
||||
}
|
||||
elem->u_prev = list->used ? list->used->u_prev : NULL; // unused
|
||||
elem->u_next = list->used;
|
||||
if(list->used) {
|
||||
list->used->u_prev = elem;
|
||||
}
|
||||
list->used = elem;
|
||||
|
||||
list->stored += 1;
|
||||
return elem->id;
|
||||
}
|
||||
|
||||
void lst_pop(list_t *list, uint id) {
|
||||
list_e *elem = &list->elems[id];
|
||||
if(elem == list->used) {
|
||||
list->used = list->used->u_next ? list->used->u_next : list->used->u_prev;
|
||||
}
|
||||
if(elem->u_prev) {
|
||||
elem->u_prev->u_next = elem->u_next;
|
||||
}
|
||||
if(elem->u_next) {
|
||||
elem->u_next->u_prev = elem->u_prev;
|
||||
}
|
||||
elem->u_next = elem->u_prev = NULL;
|
||||
if(list->free && list->free->f_prev) {
|
||||
list->free->f_prev->f_next = elem;
|
||||
}
|
||||
elem->f_prev = list->free ? list->free->f_prev : NULL;
|
||||
elem->f_next = list->free;
|
||||
if(list->free) {
|
||||
list->free->f_prev = elem;
|
||||
}
|
||||
list->free = elem;
|
||||
|
||||
list->stored -= 1;
|
||||
}
|
||||
|
||||
uint lst_iter(list_t *list, int *ptr) {
|
||||
list_e *elem = ((*ptr) < 0) ? NULL : (((*ptr) == 0) ? list->used : &list->elems[(*ptr)-1]);
|
||||
if(elem == NULL) {
|
||||
return 0xffffffff;
|
||||
}
|
||||
*ptr = elem->u_next ? (elem->u_next->id + 1) : -1;
|
||||
return elem->id;
|
||||
}
|
||||
|
||||
void lst_clear(list_t *list) {
|
||||
list_e *elem;
|
||||
list->stored = 0;
|
||||
list->used = NULL;
|
||||
list->free = list->elems;
|
||||
for(int z = 0; z < list->size; z++) {
|
||||
elem = &list->elems[z];
|
||||
elem->f_prev = (z == 0) ? NULL : &list->elems[z-1];
|
||||
elem->f_next = (z == (list->size - 1)) ? NULL : &list->elems[z+1];
|
||||
elem->u_prev = elem->u_next = NULL;
|
||||
elem->id = z;
|
||||
}
|
||||
}
|
||||
|
||||
void lst_init(list_t *list, uint size, byte cat) {
|
||||
list->size = size;
|
||||
list->elems = mem_alloc(list->size * sizeof(table_e), cat);
|
||||
lst_clear(list);
|
||||
}
|
||||
|
||||
void lst_free(list_t *list) {
|
||||
mem_free(list->elems);
|
||||
}
|
150
locale.h
Normal file
|
@ -0,0 +1,150 @@
|
|||
|
||||
#ifdef LOCALE_LOADER
|
||||
#define STR(v, f, d) loc_set(&sys.str_table[n*LOCALE_ELEM], STRINGIZE(v), sys.str_format[n], smap_get(map, STRINGIZE(v))); n++;
|
||||
#undef LOCALE_LOADER
|
||||
|
||||
void loc_read(smap_t *map);
|
||||
|
||||
void loc_load(const char *filename) {
|
||||
char *lines;
|
||||
char *line = NULL;
|
||||
smap_t map;
|
||||
int pos;
|
||||
if(!file_sread(&lines, filename)) {
|
||||
return;
|
||||
}
|
||||
smap_init(&map, 8, MEM_SYSTEM);
|
||||
while(line = strtok(line ? NULL : lines, "\n")) {
|
||||
for(pos = 0; line[pos]; pos++) {
|
||||
if(line[pos] == '=')
|
||||
break;
|
||||
}
|
||||
if(line[pos]) {
|
||||
line[pos++] = 0;
|
||||
smap_put(&map, line, line+pos);
|
||||
}
|
||||
}
|
||||
loc_read(&map);
|
||||
smap_clear(&map);
|
||||
mem_free(lines);
|
||||
}
|
||||
|
||||
void loc_read(smap_t *map) {
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef LOCALE_DEFAULTS
|
||||
#define STR(v, f, d) loc_set(&sys.str_table[n*LOCALE_ELEM], STRINGIZE(v), sys.str_format[n], d); n++;
|
||||
#undef LOCALE_DEFAULTS
|
||||
#define LOCALE_LOADER
|
||||
|
||||
void loc_def() {
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef LOCALE_VARS
|
||||
#define STR(v, f, d) STR_ ## v = &sys.str_table[n*LOCALE_ELEM]; sys.str_format[n++] = f;
|
||||
#undef LOCALE_VARS
|
||||
#define LOCALE_DEFAULTS
|
||||
|
||||
void loc_init() {
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef LOCALE_BASE
|
||||
#define STR(v, f, d) const char * STR_ ## v;
|
||||
|
||||
uint file_read_hdr(byte **data, const char *filename, const char *hdr, uint hdrsize, byte flags);
|
||||
|
||||
void loc_set(char *str, const char *name, const char *fmt, const char *loc) {
|
||||
byte fstr[16];
|
||||
byte pos = 0;
|
||||
byte lpos = 0;
|
||||
byte narg = 0;
|
||||
char c;
|
||||
if((!loc) || (loc[0] == 0)) {
|
||||
sprintf(str, fmt[0] ? "$%s$ [%s]" : "$%s$", name, fmt);
|
||||
return;
|
||||
}
|
||||
while(c = fmt[pos++]) {
|
||||
if(c == ' ') {
|
||||
fstr[narg++] = lpos;
|
||||
lpos = pos;
|
||||
}
|
||||
}
|
||||
if(fmt[lpos]) {
|
||||
fstr[narg++] = lpos;
|
||||
}
|
||||
pos = lpos = 0;
|
||||
while(c = *(loc++)) {
|
||||
if(pos == LOCALE_ELEM - 1)
|
||||
break;
|
||||
if(lpos) {
|
||||
if((c >= '1') && (c <= '9')) {
|
||||
lpos = 1 + c - '1';
|
||||
}
|
||||
else if((c >= 'a') && (c <= 'g')) {
|
||||
lpos = 10 + c - 'a';
|
||||
}
|
||||
else if((c >= 'A') && (c <= 'G')) {
|
||||
lpos = 10 + c - 'A';
|
||||
}
|
||||
else {
|
||||
lpos = 0;
|
||||
}
|
||||
if(lpos && (lpos <= narg)) {
|
||||
if(pos >= LOCALE_ELEM - ((lpos < 10) ? 4 : 5))
|
||||
break;
|
||||
str[pos++] = '%';
|
||||
str[pos++] = (lpos < 10) ? ('0' + lpos) : '1';
|
||||
if(lpos >= 10)
|
||||
str[pos++] = ('0' + (lpos - 10));
|
||||
str[pos++] = '$';
|
||||
for(lpos = fstr[lpos-1];; lpos++) {
|
||||
c = fmt[lpos];
|
||||
if((c == 0) || (c == ' ')) {
|
||||
break;
|
||||
}
|
||||
else if(pos == LOCALE_ELEM - 1) {
|
||||
while(str[--pos] != '%') {
|
||||
;
|
||||
}
|
||||
str[pos] = 0;
|
||||
return;
|
||||
}
|
||||
str[pos++] = c;
|
||||
}
|
||||
lpos = 0;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else if(c == '$') {
|
||||
lpos = 1;
|
||||
continue;
|
||||
}
|
||||
if(c == '%') {
|
||||
if(pos == LOCALE_ELEM - 2)
|
||||
break;
|
||||
str[pos++] = '%';
|
||||
str[pos++] = '%';
|
||||
}
|
||||
else {
|
||||
str[pos++] = c;
|
||||
}
|
||||
}
|
||||
str[pos] = 0;
|
||||
}
|
||||
|
||||
#define LOCALE_VARS
|
||||
#else
|
||||
int n = 0;
|
||||
#endif
|
||||
|
||||
#include "strings.h"
|
||||
|
||||
#ifdef LOCALE_BASE
|
||||
}
|
||||
#else
|
||||
#define LOCALE_BASE
|
||||
#endif
|
||||
#undef STR
|
118
log.h
Normal file
|
@ -0,0 +1,118 @@
|
|||
|
||||
void log_sys(const char *msg, int length, int offset);
|
||||
|
||||
ulong tmr_rtime();
|
||||
|
||||
void log_out(const char *str) {
|
||||
char c;
|
||||
int pos = 0;
|
||||
int last = 0;
|
||||
uint color;
|
||||
// fprintf(stderr, CON_DGRAY"["CON_GREEN"%s"CON_DGRAY"]["CON_LGRAY"%s"CON_DGRAY"][%s%s"CON_DGRAY"] %s",
|
||||
// tm, prefix, log_concolor[level], log_levels[level], log_concolor[level]);
|
||||
while(c = str[pos]) {
|
||||
if(((c >= CHR_COLORS1) && (c <= CHR_COLORE1)) || ((c >= CHR_COLORS2) && (c <= CHR_COLORE2))) {
|
||||
if(pos - last)
|
||||
fwrite(&str[last], 1, pos - last, stderr);
|
||||
color = (c >= CHR_COLORS2) && (c <= CHR_COLORE2) ? gdr.aux_colors[c - CHR_COLORS2] : text_colors[c - CHR_COLORS1];
|
||||
fprintf(stderr, "\x1b[38;2;%d;%d;%dm", (color >> 16) & 0xff, (color >> 8) & 0xff, color & 0xff);
|
||||
last = ++pos;
|
||||
continue;
|
||||
}
|
||||
else if(c == CHR_CRESET) {
|
||||
if(pos - last)
|
||||
fwrite(&str[last], 1, pos - last, stderr);
|
||||
fprintf(stderr, "\x1b[0m");
|
||||
last = ++pos;
|
||||
continue;
|
||||
}
|
||||
else if(c == CHR_UNK) {
|
||||
if(pos - last)
|
||||
fwrite(&str[last], 1, pos - last, stderr);
|
||||
fprintf(stderr, "?");
|
||||
last = ++pos;
|
||||
continue;
|
||||
}
|
||||
else if(c >= 0 && c < CHR_SPC && c != CHR_NLN) {
|
||||
if(pos - last)
|
||||
fwrite(&str[last], 1, pos - last, stderr);
|
||||
last = ++pos;
|
||||
continue;
|
||||
}
|
||||
pos++;
|
||||
if(!str[pos] && (pos - last))
|
||||
fwrite(&str[last], 1, pos - last, stderr);
|
||||
}
|
||||
fprintf(stderr, "\x1b[0m\n");
|
||||
}
|
||||
|
||||
void log_msg(const char *prefix, byte level, const char *fmt, va_list ap) {
|
||||
char tm[32];
|
||||
int pos = 0;
|
||||
int len;
|
||||
if(level > sys.log_level)
|
||||
return;
|
||||
str_time(tm, tmr_rtime());
|
||||
pos = sprintf(sys.log_buf, COL_DGRAY"["COL_GREEN"%s"COL_DGRAY"]["COL_LGRAY"%s"COL_DGRAY"][%s%s"COL_DGRAY"] %s",
|
||||
tm, prefix, log_colors[level], log_levels[level], log_colors[level]);
|
||||
len = pos + vsnprintf((sys.log_buf)+pos, LOG_BUF-pos, fmt, ap);
|
||||
log_sys(sys.log_buf, len, pos - 1);
|
||||
log_out(sys.log_buf);
|
||||
}
|
||||
|
||||
void log_str(const char *prefix, byte level, const char *fmt, ...) {
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
log_msg(prefix, level, fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
LOG_FUNC(logu, LOG_USER)
|
||||
LOG_FUNC(loge, LOG_ERROR)
|
||||
LOG_FUNC(logw, LOG_WARN)
|
||||
LOG_FUNC(logi, LOG_INFO)
|
||||
LOG_FUNC(logp, LOG_PERF)
|
||||
LOG_FUNC(logd, LOG_DEBUG)
|
||||
LOG_FUNC(logt, LOG_TRACE)
|
||||
|
||||
void snd_log(byte level, const char *fmt, va_list ap) {
|
||||
while(sgt.log_queue == SND_LOG) {
|
||||
;
|
||||
}
|
||||
pthread_mutex_lock(&sgt.log_lock);
|
||||
char *msg = &sgt.logs[sgt.log_push * SND_LOG_LEN];
|
||||
msg[0] = (char)level;
|
||||
vsnprintf(&msg[1], SND_LOG_LEN - 1, fmt, ap);
|
||||
if(++(sgt.log_push) == SND_LOG)
|
||||
sgt.log_push = 0;
|
||||
sgt.log_queue += 1;
|
||||
pthread_mutex_unlock(&sgt.log_lock);
|
||||
}
|
||||
|
||||
SLOG_FUNC(snd_logu, LOG_USER)
|
||||
SLOG_FUNC(snd_loge, LOG_ERROR)
|
||||
SLOG_FUNC(snd_logw, LOG_WARN)
|
||||
SLOG_FUNC(snd_logi, LOG_INFO)
|
||||
SLOG_FUNC(snd_logp, LOG_PERF)
|
||||
SLOG_FUNC(snd_logd, LOG_DEBUG)
|
||||
SLOG_FUNC(snd_logt, LOG_TRACE)
|
||||
SLOG_FUNC(snd_logx, SND_LOGX)
|
||||
|
||||
void plr_tlog(int type, const char *text);
|
||||
|
||||
void snd_log_flush() {
|
||||
if(sgt.disabled)
|
||||
return;
|
||||
pthread_mutex_lock(&sgt.log_lock);
|
||||
while(sgt.log_queue) {
|
||||
char *msg = &sgt.logs[sgt.log_pop * SND_LOG_LEN];
|
||||
if(msg[0] == SND_LOGX)
|
||||
plr_tlog(msg[1] - '0', &msg[2]);
|
||||
else
|
||||
log_str(LOG_SND, msg[0], "%s", &msg[1]);
|
||||
if(++(sgt.log_pop) == SND_LOG)
|
||||
sgt.log_pop = 0;
|
||||
sgt.log_queue -= 1;
|
||||
}
|
||||
pthread_mutex_unlock(&sgt.log_lock);
|
||||
}
|
201
map.h
Normal file
|
@ -0,0 +1,201 @@
|
|||
|
||||
#define HASHM_BUCKETS 2
|
||||
|
||||
uint map_f_inthash(void *ptr) {
|
||||
uint hash = (uint)((ulong)ptr);
|
||||
return ((hash << 8) & 0xf000) | ((hash >> 8) & 0x0fff); // (hash >> 24) | ((hash >> 8) & 0x0000ff00) | ((hash << 8) & 0x00ff0000) | (hash << 24);
|
||||
}
|
||||
|
||||
byte map_f_inteq(void *ptr1, void *ptr2) {
|
||||
return ptr1 == ptr2;
|
||||
}
|
||||
|
||||
uint map_f_strhash(void *str) {
|
||||
int pos = 0;
|
||||
uint hash = 0;
|
||||
uint c;
|
||||
while(c = (uint)(((char*)str)[pos++])) {
|
||||
hash = 31 * hash + c;
|
||||
}
|
||||
return hash;
|
||||
}
|
||||
|
||||
byte map_f_streq(void *str1, void *str2) {
|
||||
return strcmp((char*)str1, (char*)str2) == 0;
|
||||
}
|
||||
|
||||
void map_init(map_t *map, map_hashfunc *hash, map_eqfunc *eq, uint load, byte cat) {
|
||||
map->hash_func = hash;
|
||||
map->eq_func = eq;
|
||||
map->elems = NULL;
|
||||
map->load = load;
|
||||
map->cat = cat;
|
||||
map->stored = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
void **map_talloc(void ***ptr, byte offset) {
|
||||
void **list = *ptr;
|
||||
if(list == NULL) {
|
||||
*ptr = list = mem_alloc(sizeof(void **) * 256);
|
||||
memset(list, 0, sizeof(void **) * 256);
|
||||
}
|
||||
return list[offset];
|
||||
}
|
||||
*/
|
||||
|
||||
byte map_put(map_t *map, void *key, void *elem) {
|
||||
uint hash = map->hash_func(key);
|
||||
uint offset;
|
||||
uint size;
|
||||
void ***ptr = &map->elems;
|
||||
void **list = *ptr;
|
||||
void **elems;
|
||||
uint stored;
|
||||
for(int z = HASHM_BUCKETS - 1; z >= 0; z--) {
|
||||
offset = (hash >> (z << 3)) & 0xff;
|
||||
// list = *ptr;
|
||||
if(list == NULL) {
|
||||
*ptr = list = mem_alloc(sizeof(void **) * 256, map->cat);
|
||||
memset(list, 0, sizeof(void **) * 256);
|
||||
}
|
||||
ptr = (void***)&list[offset];
|
||||
list = list[offset];
|
||||
}
|
||||
if(list == NULL) {
|
||||
*ptr = list = mem_alloc(sizeof(void *) * map->load * 2 + sizeof(uint) * 2, map->cat);
|
||||
memset(list, 0, sizeof(void *) * map->load * 2 + sizeof(uint) * 2);
|
||||
((uint*)list)[0] = size = map->load;
|
||||
stored = 0;
|
||||
}
|
||||
else {
|
||||
size = ((uint*)list)[0];
|
||||
stored = ((uint*)list)[1];
|
||||
}
|
||||
elems = (void**)(((uint*)list) + 2);
|
||||
for(uint z = 0; z < size; z++) {
|
||||
if((elems[z*2] != NULL) && map->eq_func(key, elems[z*2])) {
|
||||
elems[z*2+0] = key;
|
||||
elems[z*2+1] = elem;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
if(stored == size) {
|
||||
*ptr = list = mem_realloc(list, sizeof(void *) * (size+(map->load)) * 2 + sizeof(uint) * 2, map->cat);
|
||||
elems = (void**)(((uint*)list) + 2);
|
||||
memset(&elems[size*2], 0, sizeof(void *) * map->load * 2); // + sizeof(uint) * 2);
|
||||
((uint*)list)[0] = size += map->load;
|
||||
}
|
||||
for(uint z = 0; z < size; z++) {
|
||||
if(elems[z*2] == NULL) {
|
||||
elems[z*2+0] = key;
|
||||
elems[z*2+1] = elem;
|
||||
break;
|
||||
}
|
||||
}
|
||||
((uint*)list)[1] = stored + 1;
|
||||
map->stored += 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
void *map_get(map_t *map, void *key) {
|
||||
uint hash = map->hash_func(key);
|
||||
uint offset;
|
||||
uint size;
|
||||
void **list = map->elems;
|
||||
void **elems;
|
||||
for(int z = HASHM_BUCKETS - 1; z >= 0; z--) {
|
||||
if(list == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
offset = (hash >> (z << 3)) & 0xff;
|
||||
list = list[offset];
|
||||
}
|
||||
if(list == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
size = ((uint*)list)[0];
|
||||
elems = (void**)(((uint*)list) + 2);
|
||||
for(uint z = 0; z < size; z++) {
|
||||
if((elems[z*2] != NULL) && map->eq_func(key, elems[z*2+0])) {
|
||||
return elems[z*2+1];
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void *map_remove(map_t *map, void *key) {
|
||||
uint hash = map->hash_func(key);
|
||||
uint offset;
|
||||
uint size;
|
||||
uint stored;
|
||||
void **lists[HASHM_BUCKETS];
|
||||
void **list = map->elems;
|
||||
void **elems;
|
||||
void *elem;
|
||||
int s;
|
||||
for(int z = HASHM_BUCKETS - 1; z >= 0; z--) {
|
||||
if(list == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
offset = (hash >> (z << 3)) & 0xff;
|
||||
lists[z] = list;
|
||||
list = list[offset];
|
||||
}
|
||||
size = ((uint*)list)[0];
|
||||
stored = ((uint*)list)[1];
|
||||
elems = (void**)(((uint*)list) + 2);
|
||||
for(uint z = 0; z < size; z++) {
|
||||
if((elems[z*2] != NULL) && map->eq_func(key, elems[z*2+0])) {
|
||||
elem = elems[z*2+1];
|
||||
elems[z*2+0] = elems[z*2+1] = NULL;
|
||||
((uint*)list)[1] = stored -= 1;
|
||||
// logd("t", "s %d", stored);
|
||||
if(stored == 0) {
|
||||
mem_free(list);
|
||||
for(int n = 0; n < HASHM_BUCKETS; n++) {
|
||||
// if(lists[n] == NULL) {
|
||||
// break;
|
||||
// }
|
||||
lists[n][(hash >> (n << 3)) & 0xff] = NULL;
|
||||
for(s = 0; s < 256; s++) {
|
||||
if(lists[n][s] != NULL) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(s == 256) {
|
||||
mem_free(lists[n]);
|
||||
if(n == HASHM_BUCKETS - 1) {
|
||||
map->elems = NULL;
|
||||
}
|
||||
else {
|
||||
lists[n+1][(hash >> ((n+1) << 3)) & 0xff] = NULL;
|
||||
}
|
||||
}
|
||||
else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
map->stored -= 1;
|
||||
return elem;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void map_rclear(void **list, int depth) {
|
||||
for(int z = 0; z < 256 && depth < HASHM_BUCKETS; z++) {
|
||||
if(list[z] != NULL) {
|
||||
map_rclear(list[z], depth+1);
|
||||
}
|
||||
}
|
||||
mem_free(list);
|
||||
}
|
||||
|
||||
void map_clear(map_t *map) {
|
||||
map->stored = 0;
|
||||
if(map->elems)
|
||||
map_rclear(map->elems, 0);
|
||||
map->elems = NULL;
|
||||
}
|
94
mem.h
Normal file
|
@ -0,0 +1,94 @@
|
|||
|
||||
void *mem_alloc(ulong size, byte cat) {
|
||||
byte *ptr = malloc(size + sizeof(ulong));
|
||||
if(ptr) {
|
||||
sys.mem_alloc += size;
|
||||
sys.mem_blocks += 1;
|
||||
sys.mem_peak = sys.mem_alloc > sys.mem_peak ? sys.mem_alloc : sys.mem_peak;
|
||||
sys.mem_pool_sizes[cat] += size;
|
||||
sys.mem_pool_blocks[cat] += 1;
|
||||
*((ulong*)ptr) = ((ulong)size) | (((ulong)cat) << 56);
|
||||
ptr += sizeof(ulong);
|
||||
#ifdef MEM_TRACING
|
||||
logt(LOG_MEM, STR_MEM_ALLOC, size, (ulong)ptr, sys.mem_alloc, mem_types[cat]);
|
||||
#endif
|
||||
}
|
||||
else {
|
||||
sys_panic("OUT_OF_MEMORY", "Konnte nicht %lld Bytes Speicher für %s reservieren", size, mem_types[cat]);
|
||||
}
|
||||
return (void *)ptr;
|
||||
}
|
||||
|
||||
void *mem_zeros(ulong size, byte cat) {
|
||||
byte *ptr = calloc(size + sizeof(ulong), 1);
|
||||
if(ptr) {
|
||||
sys.mem_alloc += size;
|
||||
sys.mem_blocks += 1;
|
||||
sys.mem_peak = sys.mem_alloc > sys.mem_peak ? sys.mem_alloc : sys.mem_peak;
|
||||
sys.mem_pool_sizes[cat] += size;
|
||||
sys.mem_pool_blocks[cat] += 1;
|
||||
*((ulong*)ptr) = ((ulong)size) | (((ulong)cat) << 56);
|
||||
ptr += sizeof(ulong);
|
||||
#ifdef MEM_TRACING
|
||||
logt(LOG_MEM, STR_MEM_ALLOC, size, (ulong)ptr, sys.mem_alloc, mem_types[cat]);
|
||||
#endif
|
||||
}
|
||||
else {
|
||||
sys_panic("OUT_OF_MEMORY", "Konnte nicht %lld Bytes Speicher für %s reservieren", size, mem_types[cat]);
|
||||
}
|
||||
return (void *)ptr;
|
||||
}
|
||||
|
||||
void mem_free(void *vptr) {
|
||||
byte *ptr = (byte *)vptr;
|
||||
ulong size;
|
||||
byte cat;
|
||||
if(ptr == NULL) {
|
||||
return;
|
||||
}
|
||||
ptr -= sizeof(ulong);
|
||||
size = (ulong)(((ulong)*((ulong*)ptr)) & 0x00ffffffffffffffULL);
|
||||
cat = (byte)(((ulong)*((ulong*)ptr)) >> 56);
|
||||
free(ptr);
|
||||
sys.mem_alloc -= size;
|
||||
sys.mem_blocks -= 1;
|
||||
sys.mem_pool_sizes[cat] -= size;
|
||||
sys.mem_pool_blocks[cat] -= 1;
|
||||
#ifdef MEM_TRACING
|
||||
logt(LOG_MEM, STR_MEM_FREE, size, (ulong)ptr, sys.mem_alloc, mem_types[cat]);
|
||||
#endif
|
||||
}
|
||||
|
||||
void *mem_realloc(void *vptr, ulong size, byte cat) {
|
||||
byte *ptr = (byte *)vptr;
|
||||
ulong psize;
|
||||
byte ocat;
|
||||
byte *nptr;
|
||||
if(ptr == NULL) {
|
||||
return mem_alloc(size, cat);
|
||||
}
|
||||
else if(size == 0) {
|
||||
mem_free(ptr);
|
||||
return NULL;
|
||||
}
|
||||
ptr -= sizeof(ulong);
|
||||
psize = (ulong)(((ulong)*((ulong*)ptr)) & 0x00ffffffffffffffULL);
|
||||
ocat = (byte)(((ulong)*((ulong*)ptr)) >> 56);
|
||||
nptr = realloc(ptr, size + sizeof(ulong));
|
||||
if(nptr) {
|
||||
sys.mem_alloc -= psize;
|
||||
sys.mem_alloc += size;
|
||||
sys.mem_peak = sys.mem_alloc > sys.mem_peak ? sys.mem_alloc : sys.mem_peak;
|
||||
sys.mem_pool_sizes[ocat] -= psize;
|
||||
sys.mem_pool_sizes[cat] += size;
|
||||
*((ulong*)nptr) = ((ulong)size) | (((ulong)cat) << 56);
|
||||
nptr += sizeof(ulong);
|
||||
#ifdef MEM_TRACING
|
||||
logt(LOG_MEM, STR_MEM_REALLOC, psize, size, (ulong)nptr, sys.mem_alloc, mem_types[cat]);
|
||||
#endif
|
||||
}
|
||||
else {
|
||||
sys_panic("OUT_OF_MEMORY", "Konnte nicht %lld auf %lld Bytes Speicher bei $%llx für %s neu reservieren", psize, size, (ulong)ptr, mem_types[cat]);
|
||||
}
|
||||
return (void *)nptr;
|
||||
}
|
518
midi.h
Normal file
|
@ -0,0 +1,518 @@
|
|||
|
||||
void snd_logd(const char *fmt, ...);
|
||||
void snd_loge(const char *fmt, ...);
|
||||
void snd_logx(const char *fmt, ...);
|
||||
|
||||
void mid_dlog(const char *format, ...) {
|
||||
if(sgt.log_debug)
|
||||
snd_logd(format);
|
||||
}
|
||||
|
||||
void mid_settempo(mid_handle *mid, uint tempo) {
|
||||
mid->uspb = tempo;
|
||||
mid->ticktime = mid->uspb / mid->tpqn;
|
||||
}
|
||||
|
||||
uint mid_read_uint32(byte *data) {
|
||||
uint value = 0;
|
||||
for(int h = 0; h < 4; h++) {
|
||||
value |= ((uint)data[h]);
|
||||
value <<= h < 3 ? 8 : 0;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
ushort mid_read_uint16(byte *data) {
|
||||
ushort value = 0;
|
||||
for(int h = 0; h < 2; h++) {
|
||||
value |= ((ushort)data[h]);
|
||||
value <<= h < 1 ? 8 : 0;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
uint midt_read_uint32(mid_track *trk) {
|
||||
uint value = 0;
|
||||
for(int h = 0; h < 4; h++) {
|
||||
if(trk->pos >= trk->size) {
|
||||
break;
|
||||
}
|
||||
value |= ((uint)trk->buffer[trk->pos++]);
|
||||
value <<= h < 3 ? 8 : 0;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
uint midt_read_uint24(mid_track *trk) {
|
||||
uint value = 0;
|
||||
for(int h = 0; h < 3; h++) {
|
||||
if(trk->pos >= trk->size) {
|
||||
break;
|
||||
}
|
||||
value |= ((uint)trk->buffer[trk->pos++]);
|
||||
value <<= h < 2 ? 8 : 0;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
ushort midt_read_uint16(mid_track *trk) {
|
||||
ushort value = 0;
|
||||
for(int h = 0; h < 2; h++) {
|
||||
if(trk->pos >= trk->size) {
|
||||
break;
|
||||
}
|
||||
value |= ((ushort)trk->buffer[trk->pos++]);
|
||||
value <<= h < 1 ? 8 : 0;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
byte midt_read_uint8(mid_track *trk) {
|
||||
byte value = 0;
|
||||
if(trk->pos < trk->size) {
|
||||
value = trk->buffer[trk->pos++];
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
void midt_read_var(mid_track *trk, uint len, byte *chars) {
|
||||
memset(chars, 0, len);
|
||||
for(int h = 0; h < len; h++) {
|
||||
if(trk->pos >= trk->size) {
|
||||
break;
|
||||
}
|
||||
chars[h] = trk->buffer[trk->pos++];
|
||||
}
|
||||
}
|
||||
|
||||
uint mid_read_vlen(mid_track *trk)
|
||||
{
|
||||
uint value;
|
||||
byte bt;
|
||||
|
||||
if(trk->pos >= trk->size) {
|
||||
return 0;
|
||||
}
|
||||
if((value = trk->buffer[trk->pos++]) & 0x80)
|
||||
{
|
||||
value &= 0x7f;
|
||||
do {
|
||||
if(trk->pos >= trk->size) {
|
||||
break;
|
||||
}
|
||||
value = (value << 7) + ((bt = trk->buffer[trk->pos++]) & 0x7f);
|
||||
}
|
||||
while(bt & 0x80);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
uint mid_read(mid_handle *mid, const char *filename) {
|
||||
int err;
|
||||
FILE *fd = fopen(filename, "rb");
|
||||
if(fd == NULL) {
|
||||
err = errno;
|
||||
loge(LOG_IO, STR_MID_OPNERR, filename, strerror(err), err);
|
||||
return 0;
|
||||
}
|
||||
if(fseek(fd, 0L, SEEK_END)) {
|
||||
err = errno;
|
||||
loge(LOG_IO, STR_MID_EGEN, filename, strerror(err), err);
|
||||
fclose(fd);
|
||||
return 0;
|
||||
}
|
||||
long size = ftell(fd);
|
||||
if(size < 0L) {
|
||||
err = errno;
|
||||
loge(LOG_IO, STR_MID_EGEN, filename, strerror(err), err);
|
||||
fclose(fd);
|
||||
return 0;
|
||||
}
|
||||
if(fseek(fd, 0L, SEEK_SET)) {
|
||||
err = errno;
|
||||
loge(LOG_IO, STR_MID_EGEN, filename, strerror(err), err);
|
||||
fclose(fd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(size < 14) {
|
||||
loge(LOG_IO, STR_MID_ESHORT, filename);
|
||||
fclose(fd);
|
||||
return 0;
|
||||
}
|
||||
byte header[14];
|
||||
if(fread(header, 1, 14, fd) != 14) {
|
||||
err = feof(fd);
|
||||
loge(LOG_IO, err == 0 ? STR_MID_EIO : STR_MID_EEOF, filename);
|
||||
fclose(fd);
|
||||
return 0;
|
||||
}
|
||||
if(memcmp(header, mid_hdr, 4) != 0) {
|
||||
loge(LOG_IO, STR_MID_EMFHDR, filename);
|
||||
fclose(fd);
|
||||
return 0;
|
||||
}
|
||||
if(mid_read_uint32(header+4) != 6) {
|
||||
loge(LOG_IO, STR_MID_EHSIZE, filename);
|
||||
fclose(fd);
|
||||
return 0;
|
||||
}
|
||||
byte mtrack;
|
||||
ushort type = mid_read_uint16(header+8);
|
||||
if(type == 0) {
|
||||
mtrack = 0;
|
||||
}
|
||||
else if((type == 1) || (type == 2)) {
|
||||
mtrack = 1;
|
||||
}
|
||||
else {
|
||||
loge(LOG_IO, STR_MID_ETKFMT, filename);
|
||||
fclose(fd);
|
||||
return 0;
|
||||
}
|
||||
mid->tracks = mid_read_uint16(header+10);
|
||||
if(mid->tracks == 0) {
|
||||
loge(LOG_IO, STR_MID_ENOTRK, filename);
|
||||
fclose(fd);
|
||||
return 0;
|
||||
}
|
||||
else if((mtrack ^ 1) && (mid->tracks > 1)) {
|
||||
loge(LOG_IO, STR_MID_ESMULT, filename);
|
||||
fclose(fd);
|
||||
return 0;
|
||||
}
|
||||
mid->tpqn = mid_read_uint16(header+12);
|
||||
if((mid->tpqn & 0x8000) > 0) {
|
||||
loge(LOG_IO, STR_MID_ESMPTE, filename);
|
||||
fclose(fd);
|
||||
return 0;
|
||||
}
|
||||
if(mid->tpqn == 0) {
|
||||
loge(LOG_IO, STR_MID_EDZERO, filename);
|
||||
fclose(fd);
|
||||
return 0;
|
||||
}
|
||||
uint esize = 0;
|
||||
for(ushort trk = 0; trk < mid->tracks; trk++) {
|
||||
if(fread(header, 1, 8, fd) != 8) {
|
||||
err = feof(fd);
|
||||
loge(LOG_IO, err == 0 ? STR_MID_EIO : STR_MID_EEOF, filename);
|
||||
fclose(fd);
|
||||
return 0;
|
||||
}
|
||||
if(memcmp(header, mid_trk, 4) != 0) {
|
||||
loge(LOG_IO, STR_MID_ETKHDR, filename);
|
||||
fclose(fd);
|
||||
return 0;
|
||||
}
|
||||
uint trks = mid_read_uint32(header+4);
|
||||
if((14 + esize + 8 + trks) > size) {
|
||||
loge(LOG_IO, STR_MID_EOUTOF, filename, trk+1);
|
||||
fclose(fd);
|
||||
return 0;
|
||||
}
|
||||
if(fseek(fd, trks, SEEK_CUR)) {
|
||||
err = errno;
|
||||
loge(LOG_IO, STR_MID_EGEN, filename, strerror(err), err);
|
||||
fclose(fd);
|
||||
return 0;
|
||||
}
|
||||
esize += trks + 8;
|
||||
}
|
||||
if(fseek(fd, 14L, SEEK_SET)) {
|
||||
err = errno;
|
||||
loge(LOG_IO, STR_MID_EGEN, filename, strerror(err), err);
|
||||
fclose(fd);
|
||||
return 0;
|
||||
}
|
||||
esize -= (mid->tracks * 8);
|
||||
byte *buf = mem_alloc((sizeof(mid_track) * mid->tracks) + esize, MEM_FILE);
|
||||
mid->track = (mid_track*)buf;
|
||||
buf += (sizeof(mid_track) * mid->tracks);
|
||||
for(ushort trk = 0; trk < mid->tracks; trk++) {
|
||||
memset((mid->track)+trk, 0, sizeof(mid_track));
|
||||
if(fread(header, 1, 8, fd) != 8) {
|
||||
err = feof(fd);
|
||||
loge(LOG_IO, err == 0 ? STR_MID_EIO : STR_MID_EEOF, filename);
|
||||
fclose(fd);
|
||||
mem_free(mid->track);
|
||||
return 0;
|
||||
}
|
||||
mid->track[trk].size = mid_read_uint32(header+4);
|
||||
if(fread(buf, 1, mid->track[trk].size, fd) != mid->track[trk].size) {
|
||||
err = feof(fd);
|
||||
loge(LOG_IO, err == 0 ? STR_MID_EIO : STR_MID_EEOF, filename);
|
||||
fclose(fd);
|
||||
mem_free(mid->track);
|
||||
return 0;
|
||||
}
|
||||
mid->track[trk].buffer = buf;
|
||||
mid->track[trk].pos = 0;
|
||||
mid->track[trk].wait = 0;
|
||||
mid->track[trk].trknum = trk;
|
||||
buf += mid->track[trk].size;
|
||||
}
|
||||
fclose(fd);
|
||||
mid_settempo(mid, MID_DEFTEMPO);
|
||||
return (sizeof(mid_track) * mid->tracks) + esize;
|
||||
}
|
||||
|
||||
void mid_process_meta(mid_handle *mid, mid_track *trk) {
|
||||
byte meta = midt_read_uint8(trk);
|
||||
uint size = mid_read_vlen(trk);
|
||||
switch(meta) {
|
||||
case midmt_seqnum:
|
||||
if(size == 0) {
|
||||
mid_dlog(STR_MID_SEQNUMO, trk->trknum, trk->trknum);
|
||||
return;
|
||||
}
|
||||
else if(size != 2) {
|
||||
trk->pos += size;
|
||||
snd_loge(STR_MID_METALEN, trk->trknum, meta, 2, size);
|
||||
return;
|
||||
}
|
||||
mid_dlog(STR_MID_SEQNUM, trk->trknum, midt_read_uint16(trk));
|
||||
return;
|
||||
case midmt_text:
|
||||
case midmt_copyright:
|
||||
case midmt_trackname:
|
||||
case midmt_instrname:
|
||||
case midmt_lyric:
|
||||
case midmt_marker:
|
||||
case midmt_cuepoint: {
|
||||
byte dt[size+1];
|
||||
dt[size] = 0;
|
||||
midt_read_var(trk, size, dt);
|
||||
snd_logx("%d%s", meta, dt);
|
||||
return;
|
||||
}
|
||||
case midmt_chnprefix:
|
||||
if(size != 1) {
|
||||
trk->pos += size;
|
||||
snd_loge(STR_MID_METALEN, trk->trknum, meta, 1, size);
|
||||
return;
|
||||
}
|
||||
mid_dlog(STR_MID_CHNPFX, trk->trknum, midt_read_uint8(trk));
|
||||
return;
|
||||
case midmt_endtrack:
|
||||
trk->pos += size;
|
||||
trk->ending = 1;
|
||||
mid_dlog(STR_MID_END, trk->trknum);
|
||||
return;
|
||||
case midmt_tempo:
|
||||
if(size != 3) {
|
||||
trk->pos += size;
|
||||
snd_loge(STR_MID_METALEN, trk->trknum, meta, 3, size);
|
||||
return;
|
||||
}
|
||||
mid_settempo(mid, midt_read_uint24(trk));
|
||||
mid_dlog(STR_MID_TEMPO, 60000000 / mid->uspb);
|
||||
return;
|
||||
case midmt_smpte:
|
||||
if(size != 5) {
|
||||
trk->pos += size;
|
||||
snd_loge(STR_MID_METALEN, trk->trknum, meta, 5, size);
|
||||
return;
|
||||
}
|
||||
trk->pos += 5;
|
||||
mid_dlog(STR_MID_SMPTE);
|
||||
return;
|
||||
case midmt_timesig: {
|
||||
if(size != 4) {
|
||||
trk->pos += size;
|
||||
snd_loge(STR_MID_METALEN, trk->trknum, meta, 4, size);
|
||||
return;
|
||||
}
|
||||
byte n = midt_read_uint8(trk);
|
||||
uint d = 1 << ((uint)midt_read_uint8(trk));
|
||||
byte c = midt_read_uint8(trk);
|
||||
byte b = midt_read_uint8(trk);
|
||||
mid_dlog(STR_MID_TIMESIG, n, d, c, b);
|
||||
return;
|
||||
}
|
||||
case midmt_keysig: {
|
||||
if(size != 2) {
|
||||
trk->pos += size;
|
||||
snd_loge(STR_MID_METALEN, trk->trknum, meta, 2, size);
|
||||
return;
|
||||
}
|
||||
int8_t s = midt_read_uint8(trk);
|
||||
byte m = midt_read_uint8(trk);
|
||||
mid_dlog(STR_MID_KEYSIG, s, (m == 0) ? "MAJOR" : ((m == 1) ? "MINOR" : "- ? -"));
|
||||
return;
|
||||
}
|
||||
case midmt_seqspec: {
|
||||
trk->pos += size;
|
||||
mid_dlog(STR_MID_SEQDATA, trk->trknum, size);
|
||||
return;
|
||||
}
|
||||
default:
|
||||
trk->pos += size;
|
||||
mid_dlog(STR_MID_UNKMETA, trk->trknum, meta, size);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef MID_NOEVT
|
||||
void mid_process(mid_handle *mid, mid_track *trk, bank_handle *bank, opl3_chip *chip) {
|
||||
#else
|
||||
void mid_process(mid_handle *mid, mid_track *trk) {
|
||||
#endif
|
||||
if(trk->pos >= trk->size) {
|
||||
return;
|
||||
}
|
||||
byte status = trk->buffer[trk->pos++];
|
||||
if((status & 0x80) == 0) {
|
||||
status = trk->status;
|
||||
trk->pos -= 1;
|
||||
}
|
||||
else {
|
||||
trk->status = status;
|
||||
}
|
||||
if((status & 0xf0) != 0xf0) {
|
||||
byte channel = status & 0x0f;
|
||||
status &= 0xf0;
|
||||
switch(status) {
|
||||
case midev_noteoff: {
|
||||
byte o_key = midt_read_uint8(trk);
|
||||
byte o_velocity = midt_read_uint8(trk);
|
||||
#ifndef MID_NOEVT
|
||||
bank_noteoff(bank, chip, channel, o_key, o_velocity);
|
||||
#endif
|
||||
mid_dlog(STR_MID_NOTEOFF, channel+1, o_key, o_velocity);
|
||||
break;
|
||||
}
|
||||
case midev_noteon: {
|
||||
byte key = midt_read_uint8(trk);
|
||||
byte velocity = midt_read_uint8(trk);
|
||||
#ifndef MID_NOEVT
|
||||
if(velocity == 0) {
|
||||
bank_noteoff(bank, chip, channel, key, velocity);
|
||||
}
|
||||
else {
|
||||
bank_noteon(bank, chip, channel, key, velocity);
|
||||
}
|
||||
#endif
|
||||
mid_dlog(STR_MID_NOTEON, channel+1, key, velocity);
|
||||
break;
|
||||
}
|
||||
case midev_aftertouch: {
|
||||
byte pressure = midt_read_uint8(trk);
|
||||
mid_dlog(STR_MID_PRESS, channel+1, pressure);
|
||||
break;
|
||||
}
|
||||
case midev_control: {
|
||||
byte control = midt_read_uint8(trk);
|
||||
byte value = midt_read_uint8(trk);
|
||||
#ifndef MID_NOEVT
|
||||
bank_control(bank, chip, channel, control, value);
|
||||
#endif
|
||||
mid_dlog(STR_MID_CC, channel+1, control, value);
|
||||
break;
|
||||
}
|
||||
case midev_progchg: {
|
||||
byte program = midt_read_uint8(trk);
|
||||
#ifndef MID_NOEVT
|
||||
bank_progchange(bank, chip, channel, program);
|
||||
#endif
|
||||
mid_dlog(STR_MID_PROG, channel+1, program);
|
||||
break;
|
||||
}
|
||||
case midev_chnpressure: {
|
||||
byte cpressure = midt_read_uint8(trk);
|
||||
mid_dlog(STR_MID_CPRESS, channel+1, cpressure);
|
||||
break;
|
||||
}
|
||||
case midev_pitchbend: {
|
||||
ushort pb = ((ushort)midt_read_uint8(trk)) | (((ushort)midt_read_uint8(trk)) << 7);
|
||||
short pitch = ((short)pb) - 0x2000;
|
||||
#ifndef MID_NOEVT
|
||||
bank_pitchbend(bank, chip, channel, pitch);
|
||||
#endif
|
||||
mid_dlog(STR_MID_PITCH, channel+1, pitch);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
switch(status) {
|
||||
case midev_sysex: {
|
||||
uint slen = mid_read_vlen(trk);
|
||||
trk->pos += slen;
|
||||
mid_dlog(STR_MID_SYSEX, slen);
|
||||
break;
|
||||
}
|
||||
case midev_songpos:
|
||||
mid_dlog(STR_MID_SONGPOS, ((ushort)midt_read_uint8(trk)) | (((ushort)midt_read_uint8(trk)) << 7));
|
||||
break;
|
||||
case midev_songsel:
|
||||
mid_dlog(STR_MID_SONGSEL, midt_read_uint8(trk));
|
||||
break;
|
||||
case midev_tunereq:
|
||||
mid_dlog(STR_MID_TUNE);
|
||||
break;
|
||||
case midev_endsysex: {
|
||||
uint elen = mid_read_vlen(trk);
|
||||
trk->pos += elen;
|
||||
mid_dlog(STR_MID_ESYSEX, elen);
|
||||
break;
|
||||
}
|
||||
case midev_clock:
|
||||
case midev_start:
|
||||
case midev_continue:
|
||||
case midev_stop:
|
||||
case midev_actsense:
|
||||
mid_dlog(STR_MID_GENSTAT, status);
|
||||
break;
|
||||
case midev_meta:
|
||||
mid_process_meta(mid, trk);
|
||||
break;
|
||||
default:
|
||||
snd_loge(STR_MID_UNKSTAT, status);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef MID_NOEVT
|
||||
byte mid_tick(mid_handle *mid, bank_handle *bank, opl3_chip *chip) {
|
||||
#else
|
||||
byte mid_tick(mid_handle *mid) {
|
||||
#endif
|
||||
byte end = 1;
|
||||
for(int trk = 0; trk < mid->tracks; trk++) {
|
||||
mid_track *track = (mid->track)+trk;
|
||||
if(track->ending) {
|
||||
continue;
|
||||
}
|
||||
if(track->wait > 0) {
|
||||
track->wait -= 1;
|
||||
if(track->wait > 0) {
|
||||
end = 0;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
while(1) {
|
||||
if(track->pos > 0) {
|
||||
#ifndef MID_NOEVT
|
||||
mid_process(mid, track, bank, chip);
|
||||
#else
|
||||
mid_process(mid, track);
|
||||
#endif
|
||||
if((track->ending ^ 1) && (track->pos >= track->size)) {
|
||||
snd_loge(STR_MID_EEND, track->trknum);
|
||||
track->ending = 1;
|
||||
}
|
||||
if(track->ending) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
track->wait = mid_read_vlen(track);
|
||||
if(track->wait > 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
end &= track->ending;
|
||||
}
|
||||
return end ^ 1;
|
||||
}
|
225
noise.h
Normal file
|
@ -0,0 +1,225 @@
|
|||
|
||||
static const double noise_d3x[] = { 1.0D, -1.0D, 1.0D, -1.0D, 1.0D, -1.0D, 1.0D, -1.0D, 0.0D, 0.0D, 0.0D, 0.0D, 1.0D, 0.0D, -1.0D, 0.0D };
|
||||
static const double noise_d3y[] = { 1.0D, 1.0D, -1.0D, -1.0D, 0.0D, 0.0D, 0.0D, 0.0D, 1.0D, -1.0D, 1.0D, -1.0D, 1.0D, -1.0D, 1.0D, -1.0D };
|
||||
static const double noise_d3z[] = { 0.0D, 0.0D, 0.0D, 0.0D, 1.0D, 1.0D, -1.0D, -1.0D, 1.0D, 1.0D, -1.0D, -1.0D, 0.0D, 1.0D, 0.0D, -1.0D };
|
||||
static const double noise_d2x[] = { 1.0D, -1.0D, 1.0D, -1.0D, 1.0D, -1.0D, 1.0D, -1.0D, 0.0D, 0.0D, 0.0D, 0.0D, 1.0D, 0.0D, -1.0D, 0.0D };
|
||||
static const double noise_d2z[] = { 0.0D, 0.0D, 0.0D, 0.0D, 1.0D, 1.0D, -1.0D, -1.0D, 1.0D, 1.0D, -1.0D, -1.0D, 0.0D, 1.0D, 0.0D, -1.0D };
|
||||
|
||||
typedef struct {
|
||||
int permutations[512];
|
||||
double xcoord;
|
||||
double ycoord;
|
||||
double zcoord;
|
||||
} octave_t;
|
||||
|
||||
typedef struct {
|
||||
octave_t *octaves;
|
||||
uint n_octaves;
|
||||
} noisegen_t;
|
||||
|
||||
void noise_oct_init(octave_t *oct, ulong *rand) {
|
||||
memset(oct->permutations, 0, 512 * sizeof(int));
|
||||
oct->xcoord = rng_double(rand) * 256.0D;
|
||||
oct->ycoord = rng_double(rand) * 256.0D;
|
||||
oct->zcoord = rng_double(rand) * 256.0D;
|
||||
|
||||
for(int n = 0; n < 256; oct->permutations[n] = n++) {
|
||||
;
|
||||
}
|
||||
|
||||
for(int n = 0; n < 256; ++n) {
|
||||
int pos = rng_zrange(rand, 256 - n) + n;
|
||||
int value = oct->permutations[n];
|
||||
oct->permutations[n] = oct->permutations[pos];
|
||||
oct->permutations[pos] = value;
|
||||
oct->permutations[n + 256] = oct->permutations[n];
|
||||
}
|
||||
}
|
||||
|
||||
void noise_gen_init(noisegen_t *gen, ulong *rand, int octs) {
|
||||
gen->n_octaves = octs;
|
||||
gen->octaves = mem_alloc(octs * sizeof(octave_t), MEM_MISC);
|
||||
|
||||
for(int n = 0; n < octs; ++n) {
|
||||
noise_oct_init(&gen->octaves[n], rand);
|
||||
}
|
||||
}
|
||||
|
||||
void noise_gen_free(noisegen_t *gen) {
|
||||
if(gen->octaves)
|
||||
mem_free(gen->octaves);
|
||||
gen->octaves = NULL;
|
||||
gen->n_octaves = 0;
|
||||
}
|
||||
|
||||
double noise_lerp(double d, double n, double m) {
|
||||
return n + d * (m - n);
|
||||
}
|
||||
|
||||
double noise_grad2d(int n, double xm, double zm) {
|
||||
int i = n & 15;
|
||||
return noise_d2x[i] * xm + noise_d2z[i] * zm;
|
||||
}
|
||||
|
||||
double noise_grad(int n, double xm, double ym, double zm) {
|
||||
int i = n & 15;
|
||||
return noise_d3x[i] * xm + noise_d3y[i] * ym + noise_d3z[i] * zm;
|
||||
}
|
||||
|
||||
long noise_floor_double(double value) {
|
||||
long i = (long)value;
|
||||
return value < (double)i ? i - 1L : i;
|
||||
}
|
||||
|
||||
void noise_oct_gen(octave_t *oct, double *noise, double xoff, double yoff, double zoff, int xsize, int ysize, int zsize,
|
||||
double xscale, double yscale, double zscale, double scale) {
|
||||
int *permutations = oct->permutations;
|
||||
double xcoord = oct->xcoord;
|
||||
double ycoord = oct->ycoord;
|
||||
double zcoord = oct->zcoord;
|
||||
if(ysize == 1) {
|
||||
int i5 = 0;
|
||||
int j5 = 0;
|
||||
int j = 0;
|
||||
int k5 = 0;
|
||||
double d14 = 0.0D;
|
||||
double d15 = 0.0D;
|
||||
int l5 = 0;
|
||||
double d16 = 1.0D / scale;
|
||||
|
||||
for(int j2 = 0; j2 < xsize; ++j2) {
|
||||
double d17 = xoff + (double)j2 * xscale + xcoord;
|
||||
int i6 = (int)d17;
|
||||
|
||||
if(d17 < (double)i6) {
|
||||
--i6;
|
||||
}
|
||||
|
||||
int k2 = i6 & 255;
|
||||
d17 = d17 - (double)i6;
|
||||
double d18 = d17 * d17 * d17 * (d17 * (d17 * 6.0D - 15.0D) + 10.0D);
|
||||
|
||||
for(int j6 = 0; j6 < zsize; ++j6) {
|
||||
double d19 = zoff + (double)j6 * zscale + zcoord;
|
||||
int k6 = (int)d19;
|
||||
|
||||
if(d19 < (double)k6) {
|
||||
--k6;
|
||||
}
|
||||
|
||||
int l6 = k6 & 255;
|
||||
d19 = d19 - (double)k6;
|
||||
double d20 = d19 * d19 * d19 * (d19 * (d19 * 6.0D - 15.0D) + 10.0D);
|
||||
i5 = permutations[k2] + 0;
|
||||
j5 = permutations[i5] + l6;
|
||||
j = permutations[k2 + 1] + 0;
|
||||
k5 = permutations[j] + l6;
|
||||
d14 = noise_lerp(d18, noise_grad2d(permutations[j5], d17, d19), noise_grad(permutations[k5], d17 - 1.0D, 0.0D, d19));
|
||||
d15 = noise_lerp(d18, noise_grad(permutations[j5 + 1], d17, 0.0D, d19 - 1.0D),
|
||||
noise_grad(permutations[k5 + 1], d17 - 1.0D, 0.0D, d19 - 1.0D));
|
||||
double d21 = noise_lerp(d20, d14, d15);
|
||||
int i7 = l5++;
|
||||
noise[i7] += d21 * d16;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
int i = 0;
|
||||
double d0 = 1.0D / scale;
|
||||
int k = -1;
|
||||
int l = 0;
|
||||
int i1 = 0;
|
||||
int j1 = 0;
|
||||
int k1 = 0;
|
||||
int l1 = 0;
|
||||
int i2 = 0;
|
||||
double d1 = 0.0D;
|
||||
double d2 = 0.0D;
|
||||
double d3 = 0.0D;
|
||||
double d4 = 0.0D;
|
||||
|
||||
for(int l2 = 0; l2 < xsize; ++l2) {
|
||||
double d5 = xoff + (double)l2 * xscale + xcoord;
|
||||
int i3 = (int)d5;
|
||||
|
||||
if(d5 < (double)i3) {
|
||||
--i3;
|
||||
}
|
||||
|
||||
int j3 = i3 & 255;
|
||||
d5 = d5 - (double)i3;
|
||||
double d6 = d5 * d5 * d5 * (d5 * (d5 * 6.0D - 15.0D) + 10.0D);
|
||||
|
||||
for(int k3 = 0; k3 < zsize; ++k3) {
|
||||
double d7 = zoff + (double)k3 * zscale + zcoord;
|
||||
int l3 = (int)d7;
|
||||
|
||||
if(d7 < (double)l3) {
|
||||
--l3;
|
||||
}
|
||||
|
||||
int i4 = l3 & 255;
|
||||
d7 = d7 - (double)l3;
|
||||
double d8 = d7 * d7 * d7 * (d7 * (d7 * 6.0D - 15.0D) + 10.0D);
|
||||
|
||||
for(int j4 = 0; j4 < ysize; ++j4) {
|
||||
double d9 = yoff + (double)j4 * yscale + ycoord;
|
||||
int k4 = (int)d9;
|
||||
|
||||
if(d9 < (double)k4) {
|
||||
--k4;
|
||||
}
|
||||
|
||||
int l4 = k4 & 255;
|
||||
d9 = d9 - (double)k4;
|
||||
double d10 = d9 * d9 * d9 * (d9 * (d9 * 6.0D - 15.0D) + 10.0D);
|
||||
|
||||
if(j4 == 0 || l4 != k) {
|
||||
k = l4;
|
||||
l = permutations[j3] + l4;
|
||||
i1 = permutations[l] + i4;
|
||||
j1 = permutations[l + 1] + i4;
|
||||
k1 = permutations[j3 + 1] + l4;
|
||||
l1 = permutations[k1] + i4;
|
||||
i2 = permutations[k1 + 1] + i4;
|
||||
d1 = noise_lerp(d6, noise_grad(permutations[i1], d5, d9, d7), noise_grad(permutations[l1], d5 - 1.0D, d9, d7));
|
||||
d2 = noise_lerp(d6, noise_grad(permutations[j1], d5, d9 - 1.0D, d7),
|
||||
noise_grad(permutations[i2], d5 - 1.0D, d9 - 1.0D, d7));
|
||||
d3 = noise_lerp(d6, noise_grad(permutations[i1 + 1], d5, d9, d7 - 1.0D),
|
||||
noise_grad(permutations[l1 + 1], d5 - 1.0D, d9, d7 - 1.0D));
|
||||
d4 = noise_lerp(d6, noise_grad(permutations[j1 + 1], d5, d9 - 1.0D, d7 - 1.0D),
|
||||
noise_grad(permutations[i2 + 1], d5 - 1.0D, d9 - 1.0D, d7 - 1.0D));
|
||||
}
|
||||
|
||||
double d11 = noise_lerp(d10, d1, d2);
|
||||
double d12 = noise_lerp(d10, d3, d4);
|
||||
double d13 = noise_lerp(d8, d11, d12);
|
||||
int j7 = i++;
|
||||
noise[j7] += d13 * d0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void noise_gen(noisegen_t *gen, double *noise, double xoff, double yoff, double zoff, int xsize, int ysize, int zsize,
|
||||
double xscale, double yscale, double zscale) {
|
||||
memset(noise, 0, sizeof(double) * xsize * ysize * zsize);
|
||||
uint octaves = gen->n_octaves;
|
||||
double factor = 1.0D;
|
||||
for(int n = 0; n < octaves; ++n) {
|
||||
double xo = xoff * factor * xscale;
|
||||
double yo = yoff * factor * yscale;
|
||||
double zo = zoff * factor * zscale;
|
||||
long xn = noise_floor_double(xo);
|
||||
long zn = noise_floor_double(zo);
|
||||
xo = xo - (double)xn;
|
||||
zo = zo - (double)zn;
|
||||
xn = xn % 16777216L;
|
||||
zn = zn % 16777216L;
|
||||
xo = xo + (double)xn;
|
||||
zo = zo + (double)zn;
|
||||
noise_oct_gen(&gen->octaves[n], noise, xo, yo, zo, xsize, ysize, zsize, xscale * factor, yscale * factor, zscale * factor, factor);
|
||||
factor /= 2.0D;
|
||||
}
|
||||
}
|
932
opl3.h
Normal file
|
@ -0,0 +1,932 @@
|
|||
|
||||
// Envelope generator
|
||||
|
||||
short OPL3_EnvelopeCalcExp(uint level)
|
||||
{
|
||||
if (level > 0x1fff)
|
||||
{
|
||||
level = 0x1fff;
|
||||
}
|
||||
return (exprom[level & 0xff] << 1) >> (level >> 8);
|
||||
}
|
||||
|
||||
short OPL3_EnvelopeCalcSin0(ushort phase, ushort envelope)
|
||||
{
|
||||
ushort out = 0;
|
||||
ushort neg = 0;
|
||||
phase &= 0x3ff;
|
||||
if (phase & 0x200)
|
||||
{
|
||||
neg = 0xffff;
|
||||
}
|
||||
if (phase & 0x100)
|
||||
{
|
||||
out = logsinrom[(phase & 0xff) ^ 0xff];
|
||||
}
|
||||
else
|
||||
{
|
||||
out = logsinrom[phase & 0xff];
|
||||
}
|
||||
return OPL3_EnvelopeCalcExp(out + (envelope << 3)) ^ neg;
|
||||
}
|
||||
|
||||
short OPL3_EnvelopeCalcSin1(ushort phase, ushort envelope)
|
||||
{
|
||||
ushort out = 0;
|
||||
phase &= 0x3ff;
|
||||
if (phase & 0x200)
|
||||
{
|
||||
out = 0x1000;
|
||||
}
|
||||
else if (phase & 0x100)
|
||||
{
|
||||
out = logsinrom[(phase & 0xff) ^ 0xff];
|
||||
}
|
||||
else
|
||||
{
|
||||
out = logsinrom[phase & 0xff];
|
||||
}
|
||||
return OPL3_EnvelopeCalcExp(out + (envelope << 3));
|
||||
}
|
||||
|
||||
short OPL3_EnvelopeCalcSin2(ushort phase, ushort envelope)
|
||||
{
|
||||
ushort out = 0;
|
||||
phase &= 0x3ff;
|
||||
if (phase & 0x100)
|
||||
{
|
||||
out = logsinrom[(phase & 0xff) ^ 0xff];
|
||||
}
|
||||
else
|
||||
{
|
||||
out = logsinrom[phase & 0xff];
|
||||
}
|
||||
return OPL3_EnvelopeCalcExp(out + (envelope << 3));
|
||||
}
|
||||
|
||||
short OPL3_EnvelopeCalcSin3(ushort phase, ushort envelope)
|
||||
{
|
||||
ushort out = 0;
|
||||
phase &= 0x3ff;
|
||||
if (phase & 0x100)
|
||||
{
|
||||
out = 0x1000;
|
||||
}
|
||||
else
|
||||
{
|
||||
out = logsinrom[phase & 0xff];
|
||||
}
|
||||
return OPL3_EnvelopeCalcExp(out + (envelope << 3));
|
||||
}
|
||||
|
||||
short OPL3_EnvelopeCalcSin4(ushort phase, ushort envelope)
|
||||
{
|
||||
ushort out = 0;
|
||||
ushort neg = 0;
|
||||
phase &= 0x3ff;
|
||||
if ((phase & 0x300) == 0x100)
|
||||
{
|
||||
neg = 0xffff;
|
||||
}
|
||||
if (phase & 0x200)
|
||||
{
|
||||
out = 0x1000;
|
||||
}
|
||||
else if (phase & 0x80)
|
||||
{
|
||||
out = logsinrom[((phase ^ 0xff) << 1) & 0xff];
|
||||
}
|
||||
else
|
||||
{
|
||||
out = logsinrom[(phase << 1) & 0xff];
|
||||
}
|
||||
return OPL3_EnvelopeCalcExp(out + (envelope << 3)) ^ neg;
|
||||
}
|
||||
|
||||
short OPL3_EnvelopeCalcSin5(ushort phase, ushort envelope)
|
||||
{
|
||||
ushort out = 0;
|
||||
phase &= 0x3ff;
|
||||
if (phase & 0x200)
|
||||
{
|
||||
out = 0x1000;
|
||||
}
|
||||
else if (phase & 0x80)
|
||||
{
|
||||
out = logsinrom[((phase ^ 0xff) << 1) & 0xff];
|
||||
}
|
||||
else
|
||||
{
|
||||
out = logsinrom[(phase << 1) & 0xff];
|
||||
}
|
||||
return OPL3_EnvelopeCalcExp(out + (envelope << 3));
|
||||
}
|
||||
|
||||
short OPL3_EnvelopeCalcSin6(ushort phase, ushort envelope)
|
||||
{
|
||||
ushort neg = 0;
|
||||
phase &= 0x3ff;
|
||||
if (phase & 0x200)
|
||||
{
|
||||
neg = 0xffff;
|
||||
}
|
||||
return OPL3_EnvelopeCalcExp(envelope << 3) ^ neg;
|
||||
}
|
||||
|
||||
short OPL3_EnvelopeCalcSin7(ushort phase, ushort envelope)
|
||||
{
|
||||
ushort out = 0;
|
||||
ushort neg = 0;
|
||||
phase &= 0x3ff;
|
||||
if (phase & 0x200)
|
||||
{
|
||||
neg = 0xffff;
|
||||
phase = (phase & 0x1ff) ^ 0x1ff;
|
||||
}
|
||||
out = phase << 3;
|
||||
return OPL3_EnvelopeCalcExp(out + (envelope << 3)) ^ neg;
|
||||
}
|
||||
|
||||
short OPL3_EnvelopeCalcTri(ushort phase, ushort envelope)
|
||||
{
|
||||
ushort out = 0;
|
||||
ushort neg = 0;
|
||||
phase &= 0x3ff;
|
||||
if (phase & 0x200)
|
||||
{
|
||||
neg = 0xffff;
|
||||
}
|
||||
if (phase & 0x100)
|
||||
{
|
||||
out = (phase & 0xff) << 3;
|
||||
}
|
||||
else
|
||||
{
|
||||
out = ~(phase & 0xff) << 3;
|
||||
}
|
||||
return OPL3_EnvelopeCalcExp(out + (envelope << 3)) ^ neg;
|
||||
}
|
||||
|
||||
short OPL3_EnvelopeCalcSqr25(ushort phase, ushort envelope)
|
||||
{
|
||||
ushort neg = 0;
|
||||
phase &= 0x3ff;
|
||||
if (phase & 0x300)
|
||||
{
|
||||
neg = 0xffff;
|
||||
}
|
||||
return OPL3_EnvelopeCalcExp(envelope << 3) ^ neg;
|
||||
}
|
||||
|
||||
short OPL3_EnvelopeCalcSqr12(ushort phase, ushort envelope)
|
||||
{
|
||||
ushort neg = 0;
|
||||
phase &= 0x3ff;
|
||||
if (phase & 0x380)
|
||||
{
|
||||
neg = 0xffff;
|
||||
}
|
||||
return OPL3_EnvelopeCalcExp(envelope << 3) ^ neg;
|
||||
}
|
||||
|
||||
short OPL3_EnvelopeCalcSaw(ushort phase, ushort envelope)
|
||||
{
|
||||
ushort out = 0;
|
||||
ushort neg = 0;
|
||||
phase &= 0x3ff;
|
||||
if (phase & 0x200)
|
||||
{
|
||||
neg = 0xffff;
|
||||
out = ~(phase & 0x1ff) << 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
out = (phase & 0x1ff) << 2;
|
||||
}
|
||||
return OPL3_EnvelopeCalcExp(out + (envelope << 3)) ^ neg;
|
||||
}
|
||||
|
||||
short OPL3_EnvelopeCalcNoise(ushort phase, ushort envelope)
|
||||
{
|
||||
ushort out = 0;
|
||||
ushort neg = 0;
|
||||
phase &= 0x3ff;
|
||||
if ((phase ^ rng_table[~phase & 0xff]) & 1)
|
||||
{
|
||||
neg = 0xffff;
|
||||
}
|
||||
out = rng_table[phase & 0xff] << 2;
|
||||
return OPL3_EnvelopeCalcExp(out + (envelope << 3)) ^ neg;
|
||||
}
|
||||
|
||||
static const envelope_sinfunc envelope_sin[16] = {
|
||||
OPL3_EnvelopeCalcSin0,
|
||||
OPL3_EnvelopeCalcSin1,
|
||||
OPL3_EnvelopeCalcSin2,
|
||||
OPL3_EnvelopeCalcSin3,
|
||||
OPL3_EnvelopeCalcSin4,
|
||||
OPL3_EnvelopeCalcSin5,
|
||||
OPL3_EnvelopeCalcSin6,
|
||||
OPL3_EnvelopeCalcSin7,
|
||||
OPL3_EnvelopeCalcTri,
|
||||
OPL3_EnvelopeCalcSqr25,
|
||||
OPL3_EnvelopeCalcSqr12,
|
||||
OPL3_EnvelopeCalcSaw,
|
||||
OPL3_EnvelopeCalcNoise,
|
||||
OPL3_EnvelopeCalcNoise,
|
||||
OPL3_EnvelopeCalcNoise,
|
||||
OPL3_EnvelopeCalcNoise,
|
||||
};
|
||||
|
||||
void OPL3_EnvelopeCalc(opl3_slot *slot)
|
||||
{
|
||||
byte nonzero;
|
||||
byte rate;
|
||||
byte rate_hi;
|
||||
byte rate_lo;
|
||||
byte reg_rate = 0;
|
||||
byte ks;
|
||||
byte eg_shift, shift;
|
||||
ushort eg_rout;
|
||||
short eg_inc;
|
||||
byte eg_off;
|
||||
byte reset = 0;
|
||||
if(slot->retrigger) {
|
||||
slot->eg_rout = 0x1ff;
|
||||
}
|
||||
slot->eg_out = slot->eg_rout + (slot->reg_tl << 2)
|
||||
+ (slot->eg_ksl >> kslshift[slot->reg_ksl]) + *slot->trem;
|
||||
if (slot->key && slot->eg_gen == envelope_gen_num_release)
|
||||
{
|
||||
reset = 1;
|
||||
reg_rate = slot->reg_ar;
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (slot->eg_gen)
|
||||
{
|
||||
case envelope_gen_num_attack:
|
||||
reg_rate = slot->reg_ar;
|
||||
break;
|
||||
case envelope_gen_num_decay:
|
||||
reg_rate = slot->reg_dr;
|
||||
break;
|
||||
case envelope_gen_num_sustain:
|
||||
if (!slot->reg_type)
|
||||
{
|
||||
reg_rate = slot->reg_rr;
|
||||
}
|
||||
break;
|
||||
case envelope_gen_num_release:
|
||||
reg_rate = slot->reg_rr;
|
||||
break;
|
||||
}
|
||||
}
|
||||
slot->pg_reset = reset;
|
||||
ks = slot->channel->ksv >> ((slot->reg_ksr ^ 1) << 1);
|
||||
nonzero = (reg_rate != 0);
|
||||
rate = ks + (reg_rate << 2);
|
||||
rate_hi = rate >> 2;
|
||||
rate_lo = rate & 0x03;
|
||||
if (rate_hi & 0x10)
|
||||
{
|
||||
rate_hi = 0x0f;
|
||||
}
|
||||
eg_shift = rate_hi + slot->chip->eg_add;
|
||||
shift = 0;
|
||||
if (nonzero)
|
||||
{
|
||||
if (rate_hi < 12)
|
||||
{
|
||||
if (slot->chip->eg_state)
|
||||
{
|
||||
switch (eg_shift)
|
||||
{
|
||||
case 12:
|
||||
shift = 1;
|
||||
break;
|
||||
case 13:
|
||||
shift = (rate_lo >> 1) & 0x01;
|
||||
break;
|
||||
case 14:
|
||||
shift = rate_lo & 0x01;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
shift = (rate_hi & 0x03) + eg_incstep[rate_lo][slot->chip->timer & 0x03];
|
||||
if (shift & 0x04)
|
||||
{
|
||||
shift = 0x03;
|
||||
}
|
||||
if (!shift)
|
||||
{
|
||||
shift = slot->chip->eg_state;
|
||||
}
|
||||
}
|
||||
}
|
||||
eg_rout = slot->eg_rout;
|
||||
eg_inc = 0;
|
||||
eg_off = 0;
|
||||
/* Instant attack */
|
||||
if (reset && rate_hi == 0x0f)
|
||||
{
|
||||
eg_rout = 0x00;
|
||||
}
|
||||
/* Envelope off */
|
||||
if ((slot->eg_rout & 0x1f8) == 0x1f8)
|
||||
{
|
||||
eg_off = 1;
|
||||
}
|
||||
if (slot->eg_gen != envelope_gen_num_attack && !reset && eg_off)
|
||||
{
|
||||
eg_rout = 0x1ff;
|
||||
}
|
||||
switch (slot->eg_gen)
|
||||
{
|
||||
case envelope_gen_num_attack:
|
||||
if (!(slot->eg_rout))
|
||||
{
|
||||
slot->eg_gen = envelope_gen_num_decay;
|
||||
}
|
||||
else if (slot->key && shift > 0 && rate_hi != 0x0f)
|
||||
{
|
||||
eg_inc = ~slot->eg_rout >> (4 - shift);
|
||||
}
|
||||
break;
|
||||
case envelope_gen_num_decay:
|
||||
if ((slot->eg_rout >> 4) == slot->reg_sl)
|
||||
{
|
||||
slot->eg_gen = envelope_gen_num_sustain;
|
||||
}
|
||||
else if (!eg_off && !reset && shift > 0)
|
||||
{
|
||||
eg_inc = 1 << (shift - 1);
|
||||
}
|
||||
break;
|
||||
case envelope_gen_num_sustain:
|
||||
case envelope_gen_num_release:
|
||||
if (!eg_off && !reset && shift > 0)
|
||||
{
|
||||
eg_inc = 1 << (shift - 1);
|
||||
}
|
||||
break;
|
||||
}
|
||||
slot->eg_rout = (eg_rout + eg_inc) & 0x1ff;
|
||||
/* Key off */
|
||||
if (reset)
|
||||
{
|
||||
slot->eg_gen = envelope_gen_num_attack;
|
||||
}
|
||||
if (!(slot->key))
|
||||
{
|
||||
slot->eg_gen = envelope_gen_num_release;
|
||||
}
|
||||
slot->detrigger = 0;
|
||||
slot->retrigger = 0;
|
||||
}
|
||||
|
||||
void OPL3_EnvelopeUpdateKSL(opl3_slot *slot)
|
||||
{
|
||||
short ksl = (kslrom[slot->channel->f_num >> 6] << 2)
|
||||
- ((0x08 - slot->channel->block) << 5);
|
||||
if (ksl < 0)
|
||||
{
|
||||
ksl = 0;
|
||||
}
|
||||
slot->eg_ksl = (byte)ksl;
|
||||
}
|
||||
|
||||
void OPL3_EnvelopeKeyOn(opl3_slot *slot)
|
||||
{
|
||||
slot->key = 0x01;
|
||||
if(slot->detrigger) {
|
||||
slot->eg_gen = envelope_gen_num_release;
|
||||
// slot->eg_rout = 0x1ff;
|
||||
// slot->eg_out = slot->eg_rout = 0x1ff;
|
||||
slot->detrigger = 0;
|
||||
}
|
||||
slot->retrigger = 1;
|
||||
}
|
||||
|
||||
void OPL3_EnvelopeKeyOff(opl3_slot *slot)
|
||||
{
|
||||
slot->key = 0x00;
|
||||
slot->detrigger = 1;
|
||||
slot->retrigger = 0;
|
||||
}
|
||||
|
||||
void OPL3_PhaseGenerate(opl3_slot *slot)
|
||||
{
|
||||
opl3_chip *chip;
|
||||
ushort f_num;
|
||||
uint basefreq;
|
||||
ushort phase;
|
||||
|
||||
chip = slot->chip;
|
||||
f_num = slot->channel->f_num;
|
||||
if (slot->reg_vib)
|
||||
{
|
||||
char range;
|
||||
byte vibpos;
|
||||
|
||||
range = (f_num >> 7) & 7;
|
||||
vibpos = slot->chip->vibpos;
|
||||
|
||||
if (!(vibpos & 3))
|
||||
{
|
||||
range = 0;
|
||||
}
|
||||
else if (vibpos & 1)
|
||||
{
|
||||
range >>= 1;
|
||||
}
|
||||
range >>= slot->chip->vibshift;
|
||||
|
||||
if (vibpos & 4)
|
||||
{
|
||||
range = -range;
|
||||
}
|
||||
f_num += range;
|
||||
}
|
||||
basefreq = (f_num << slot->channel->block) >> 1;
|
||||
phase = (ushort)(slot->pg_phase >> 9);
|
||||
if (slot->pg_reset)
|
||||
{
|
||||
slot->pg_phase = 0;
|
||||
}
|
||||
slot->pg_phase += (basefreq * op_mt[slot->reg_mult]) >> 1;
|
||||
slot->pg_phase_out = phase;
|
||||
}
|
||||
|
||||
void OPL3_SlotGenerate(opl3_slot *slot)
|
||||
{
|
||||
slot->out = envelope_sin[slot->reg_wf](slot->pg_phase_out + *slot->mod, slot->eg_out);
|
||||
}
|
||||
|
||||
void OPL3_SlotCalcFB(opl3_slot *slot)
|
||||
{
|
||||
if (slot->channel->fb != 0x00)
|
||||
{
|
||||
slot->fbmod = (slot->prout + slot->out) >> (0x09 - slot->channel->fb);
|
||||
}
|
||||
else
|
||||
{
|
||||
slot->fbmod = 0;
|
||||
}
|
||||
slot->prout = slot->out;
|
||||
}
|
||||
|
||||
void OPL3_ProcessSlot(opl3_slot *slot)
|
||||
{
|
||||
OPL3_SlotCalcFB(slot);
|
||||
OPL3_EnvelopeCalc(slot);
|
||||
OPL3_PhaseGenerate(slot);
|
||||
OPL3_SlotGenerate(slot);
|
||||
}
|
||||
|
||||
short OPL3_ClipSampleOld(int sample)
|
||||
{
|
||||
if (sample > 32767)
|
||||
{
|
||||
sample = 32767;
|
||||
}
|
||||
else if (sample < -32768)
|
||||
{
|
||||
sample = -32768;
|
||||
}
|
||||
return (short)sample;
|
||||
}
|
||||
|
||||
short OPL3_ClipSample(int sample)
|
||||
{
|
||||
int sign = (sample < 0) ? -1 : 1;
|
||||
sample = (sample < 0) ? -sample : sample;
|
||||
sample *= 5;
|
||||
sample /= 8;
|
||||
sample = sample > 32767 ? 32767 : sample;
|
||||
sample *= sign;
|
||||
return (short)sample;
|
||||
}
|
||||
|
||||
void OPL3_Generate(opl3_chip *chip, short *buf)
|
||||
{
|
||||
opl3_channel *channel;
|
||||
short **out;
|
||||
int mix[2];
|
||||
byte ii;
|
||||
short accm;
|
||||
byte shift = 0;
|
||||
|
||||
buf[0] = OPL3_ClipSample(chip->mixbuff[0]);
|
||||
buf[1] = OPL3_ClipSample(chip->mixbuff[1]);
|
||||
|
||||
for (ii = 0; ii < (chip->n_voices * 2); ii++)
|
||||
{
|
||||
OPL3_ProcessSlot(&chip->slot[ii]);
|
||||
}
|
||||
|
||||
mix[0] = mix[1] = 0;
|
||||
for (ii = 0; ii < chip->n_voices; ii++)
|
||||
{
|
||||
channel = &chip->channel[ii];
|
||||
out = channel->out;
|
||||
accm = *out[0] + *out[1] + *out[2] + *out[3];
|
||||
mix[0] += (short)((accm * channel->level[0]) >> 16);
|
||||
mix[1] += (short)((accm * channel->level[1]) >> 16);
|
||||
}
|
||||
chip->mixbuff[0] = mix[0];
|
||||
chip->mixbuff[1] = mix[1];
|
||||
|
||||
if ((chip->timer & 0x3f) == 0x3f)
|
||||
{
|
||||
chip->tremolopos = (chip->tremolopos + 1) % 210;
|
||||
}
|
||||
if (chip->tremolopos < 105)
|
||||
{
|
||||
chip->tremolo = chip->tremolopos >> chip->tremoloshift;
|
||||
}
|
||||
else
|
||||
{
|
||||
chip->tremolo = (210 - chip->tremolopos) >> chip->tremoloshift;
|
||||
}
|
||||
|
||||
if ((chip->timer & 0x3ff) == 0x3ff)
|
||||
{
|
||||
chip->vibpos = (chip->vibpos + 1) & 7;
|
||||
}
|
||||
|
||||
chip->timer++;
|
||||
|
||||
chip->eg_add = 0;
|
||||
if (chip->eg_timer)
|
||||
{
|
||||
while (shift < 36 && ((chip->eg_timer >> shift) & 1) == 0)
|
||||
{
|
||||
shift++;
|
||||
}
|
||||
if (shift > 12)
|
||||
{
|
||||
chip->eg_add = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
chip->eg_add = shift + 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (chip->eg_timerrem || chip->eg_state)
|
||||
{
|
||||
if (chip->eg_timer == 0xfffffffff)
|
||||
{
|
||||
chip->eg_timer = 0;
|
||||
chip->eg_timerrem = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
chip->eg_timer++;
|
||||
chip->eg_timerrem = 0;
|
||||
}
|
||||
}
|
||||
|
||||
chip->eg_state ^= 1;
|
||||
}
|
||||
|
||||
void OPL3_GenerateResampled(opl3_chip *chip, short *buf)
|
||||
{
|
||||
while (chip->samplecnt >= chip->rateratio)
|
||||
{
|
||||
chip->oldsamples[0] = chip->samples[0];
|
||||
chip->oldsamples[1] = chip->samples[1];
|
||||
OPL3_Generate(chip, chip->samples);
|
||||
chip->samplecnt -= chip->rateratio;
|
||||
}
|
||||
buf[0] = (short)((chip->oldsamples[0] * (chip->rateratio - chip->samplecnt)
|
||||
+ chip->samples[0] * chip->samplecnt) / chip->rateratio);
|
||||
buf[1] = (short)((chip->oldsamples[1] * (chip->rateratio - chip->samplecnt)
|
||||
+ chip->samples[1] * chip->samplecnt) / chip->rateratio);
|
||||
chip->samplecnt += 1 << RSM_FRAC;
|
||||
}
|
||||
|
||||
// Operator
|
||||
|
||||
void OPL3_SlotFlags(opl3_slot *slot, byte tremolo, byte vibrato, byte sustaining, byte ksr) {
|
||||
if (tremolo)
|
||||
{
|
||||
slot->trem = &slot->chip->tremolo;
|
||||
}
|
||||
else
|
||||
{
|
||||
slot->trem = (byte*)&slot->chip->zeromod;
|
||||
}
|
||||
slot->reg_vib = vibrato & 0x01;
|
||||
slot->reg_type = sustaining & 0x01;
|
||||
slot->reg_ksr = ksr & 0x01;
|
||||
}
|
||||
|
||||
void OPL3_SlotMult(opl3_slot *slot, byte mult) {
|
||||
slot->reg_mult = mult & 0x0f;
|
||||
}
|
||||
|
||||
void OPL3_SlotKSL(opl3_slot *slot, byte ksl) {
|
||||
slot->reg_ksl = ksl & 0x03;
|
||||
OPL3_EnvelopeUpdateKSL(slot);
|
||||
}
|
||||
|
||||
void OPL3_SlotLevel(opl3_slot *slot, byte level) {
|
||||
slot->reg_tl = level & 0x3f;
|
||||
}
|
||||
|
||||
void OPL3_SlotADSR(opl3_slot *slot, byte attack, byte decay, byte sustain, byte release) {
|
||||
slot->reg_ar = attack & 0x0f;
|
||||
slot->reg_dr = decay & 0x0f;
|
||||
slot->reg_sl = sustain & 0x0f;
|
||||
if (slot->reg_sl == 0x0f)
|
||||
{
|
||||
slot->reg_sl = 0x1f;
|
||||
}
|
||||
slot->reg_rr = release & 0x0f;
|
||||
if (slot->reg_rr == 0x00)
|
||||
{
|
||||
slot->reg_rr = 0x01;
|
||||
}
|
||||
}
|
||||
|
||||
void OPL3_SlotWaveform(opl3_slot *slot, byte waveform) {
|
||||
slot->reg_wf = waveform & 0x07;
|
||||
}
|
||||
|
||||
void OPL3_SlotWaveformNew(opl3_slot *slot, byte waveform) {
|
||||
slot->reg_wf = waveform & 0x0f;
|
||||
}
|
||||
|
||||
// Channel
|
||||
|
||||
void OPL3_ChannelSetupAlg(opl3_channel *channel)
|
||||
{
|
||||
if (channel->alg & 0x08)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (channel->alg & 0x04)
|
||||
{
|
||||
channel->pair->out[0] = &channel->chip->zeromod;
|
||||
channel->pair->out[1] = &channel->chip->zeromod;
|
||||
channel->pair->out[2] = &channel->chip->zeromod;
|
||||
channel->pair->out[3] = &channel->chip->zeromod;
|
||||
switch (channel->alg & 0x03)
|
||||
{
|
||||
case 0x00:
|
||||
channel->pair->slots[0]->mod = &channel->pair->slots[0]->fbmod;
|
||||
channel->pair->slots[1]->mod = &channel->pair->slots[0]->out;
|
||||
channel->slots[0]->mod = &channel->pair->slots[1]->out;
|
||||
channel->slots[1]->mod = &channel->slots[0]->out;
|
||||
channel->out[0] = &channel->slots[1]->out;
|
||||
channel->out[1] = &channel->chip->zeromod;
|
||||
channel->out[2] = &channel->chip->zeromod;
|
||||
channel->out[3] = &channel->chip->zeromod;
|
||||
break;
|
||||
case 0x01:
|
||||
channel->pair->slots[0]->mod = &channel->pair->slots[0]->fbmod;
|
||||
channel->pair->slots[1]->mod = &channel->pair->slots[0]->out;
|
||||
channel->slots[0]->mod = &channel->chip->zeromod;
|
||||
channel->slots[1]->mod = &channel->slots[0]->out;
|
||||
channel->out[0] = &channel->pair->slots[1]->out;
|
||||
channel->out[1] = &channel->slots[1]->out;
|
||||
channel->out[2] = &channel->chip->zeromod;
|
||||
channel->out[3] = &channel->chip->zeromod;
|
||||
break;
|
||||
case 0x02:
|
||||
channel->pair->slots[0]->mod = &channel->pair->slots[0]->fbmod;
|
||||
channel->pair->slots[1]->mod = &channel->chip->zeromod;
|
||||
channel->slots[0]->mod = &channel->pair->slots[1]->out;
|
||||
channel->slots[1]->mod = &channel->slots[0]->out;
|
||||
channel->out[0] = &channel->pair->slots[0]->out;
|
||||
channel->out[1] = &channel->slots[1]->out;
|
||||
channel->out[2] = &channel->chip->zeromod;
|
||||
channel->out[3] = &channel->chip->zeromod;
|
||||
break;
|
||||
case 0x03:
|
||||
channel->pair->slots[0]->mod = &channel->pair->slots[0]->fbmod;
|
||||
channel->pair->slots[1]->mod = &channel->chip->zeromod;
|
||||
channel->slots[0]->mod = &channel->pair->slots[1]->out;
|
||||
channel->slots[1]->mod = &channel->chip->zeromod;
|
||||
channel->out[0] = &channel->pair->slots[0]->out;
|
||||
channel->out[1] = &channel->slots[0]->out;
|
||||
channel->out[2] = &channel->slots[1]->out;
|
||||
channel->out[3] = &channel->chip->zeromod;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (channel->alg & 0x01)
|
||||
{
|
||||
case 0x00:
|
||||
channel->slots[0]->mod = &channel->slots[0]->fbmod;
|
||||
channel->slots[1]->mod = &channel->slots[0]->out;
|
||||
channel->out[0] = &channel->slots[1]->out;
|
||||
channel->out[1] = &channel->chip->zeromod;
|
||||
channel->out[2] = &channel->chip->zeromod;
|
||||
channel->out[3] = &channel->chip->zeromod;
|
||||
break;
|
||||
case 0x01:
|
||||
channel->slots[0]->mod = &channel->slots[0]->fbmod;
|
||||
channel->slots[1]->mod = &channel->chip->zeromod;
|
||||
channel->out[0] = &channel->slots[0]->out;
|
||||
channel->out[1] = &channel->slots[1]->out;
|
||||
channel->out[2] = &channel->chip->zeromod;
|
||||
channel->out[3] = &channel->chip->zeromod;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void OPL3_ChannelUpdateAlg(opl3_channel *channel)
|
||||
{
|
||||
channel->alg = channel->con;
|
||||
if (channel->chtype == ch_4op)
|
||||
{
|
||||
channel->pair->alg = 0x04 | (channel->con << 1) | (channel->pair->con);
|
||||
channel->alg = 0x08;
|
||||
OPL3_ChannelSetupAlg(channel->pair);
|
||||
}
|
||||
else if (channel->chtype == ch_4op2)
|
||||
{
|
||||
channel->alg = 0x04 | (channel->pair->con << 1) | (channel->con);
|
||||
channel->pair->alg = 0x08;
|
||||
OPL3_ChannelSetupAlg(channel);
|
||||
}
|
||||
else
|
||||
{
|
||||
OPL3_ChannelSetupAlg(channel);
|
||||
}
|
||||
}
|
||||
|
||||
void OPL3_ChannelFreq(opl3_channel *channel, byte block, ushort f_num) {
|
||||
if (channel->chtype == ch_4op2)
|
||||
{
|
||||
return;
|
||||
}
|
||||
channel->f_num = f_num & 0x3ff;
|
||||
channel->block = block & 0x07;
|
||||
channel->ksv = (channel->block << 1)
|
||||
| ((channel->f_num >> (0x09 - channel->chip->nts)) & 0x01);
|
||||
OPL3_EnvelopeUpdateKSL(channel->slots[0]);
|
||||
OPL3_EnvelopeUpdateKSL(channel->slots[1]);
|
||||
if (channel->chtype == ch_4op)
|
||||
{
|
||||
channel->pair->f_num = channel->f_num;
|
||||
channel->pair->block = channel->block;
|
||||
channel->pair->ksv = channel->ksv;
|
||||
OPL3_EnvelopeUpdateKSL(channel->pair->slots[0]);
|
||||
OPL3_EnvelopeUpdateKSL(channel->pair->slots[1]);
|
||||
}
|
||||
}
|
||||
|
||||
void OPL3_ChannelOutput(opl3_channel *channel, byte output, uint level) {
|
||||
channel->level[output & 1] = level;
|
||||
}
|
||||
|
||||
void OPL3_Channel4Op(opl3_channel *channel, byte op4) {
|
||||
if (op4)
|
||||
{
|
||||
channel->chtype = ch_4op;
|
||||
channel->pair->chtype = ch_4op2;
|
||||
OPL3_ChannelUpdateAlg(channel);
|
||||
}
|
||||
else
|
||||
{
|
||||
channel->chtype = ch_2op;
|
||||
channel->pair->chtype = ch_2op;
|
||||
OPL3_ChannelUpdateAlg(channel);
|
||||
OPL3_ChannelUpdateAlg(channel->pair);
|
||||
}
|
||||
}
|
||||
|
||||
void OPL3_ChannelFeedback(opl3_channel *channel, byte feedback) {
|
||||
channel->fb = feedback & 0x07;
|
||||
}
|
||||
|
||||
void OPL3_ChannelAM(opl3_channel *channel, byte am) {
|
||||
channel->con = am & 0x01;
|
||||
OPL3_ChannelUpdateAlg(channel);
|
||||
}
|
||||
|
||||
void OPL3_ChannelKeyOn(opl3_channel *channel)
|
||||
{
|
||||
if (channel->chtype == ch_4op)
|
||||
{
|
||||
OPL3_EnvelopeKeyOn(channel->slots[0]);
|
||||
OPL3_EnvelopeKeyOn(channel->slots[1]);
|
||||
OPL3_EnvelopeKeyOn(channel->pair->slots[0]);
|
||||
OPL3_EnvelopeKeyOn(channel->pair->slots[1]);
|
||||
}
|
||||
else if (channel->chtype == ch_2op)
|
||||
{
|
||||
OPL3_EnvelopeKeyOn(channel->slots[0]);
|
||||
OPL3_EnvelopeKeyOn(channel->slots[1]);
|
||||
}
|
||||
}
|
||||
|
||||
void OPL3_ChannelKeyOff(opl3_channel *channel)
|
||||
{
|
||||
if (channel->chtype == ch_4op)
|
||||
{
|
||||
OPL3_EnvelopeKeyOff(channel->slots[0]);
|
||||
OPL3_EnvelopeKeyOff(channel->slots[1]);
|
||||
OPL3_EnvelopeKeyOff(channel->pair->slots[0]);
|
||||
OPL3_EnvelopeKeyOff(channel->pair->slots[1]);
|
||||
}
|
||||
else if (channel->chtype == ch_2op)
|
||||
{
|
||||
OPL3_EnvelopeKeyOff(channel->slots[0]);
|
||||
OPL3_EnvelopeKeyOff(channel->slots[1]);
|
||||
}
|
||||
}
|
||||
|
||||
void OPL3_Reset(opl3_chip *chip)
|
||||
{
|
||||
byte slotnum;
|
||||
byte channum;
|
||||
|
||||
int rateratio = chip->rateratio;
|
||||
byte n_voices = chip->n_voices;
|
||||
opl3_slot *slot = chip->slot;
|
||||
opl3_channel *channel = chip->channel;
|
||||
|
||||
memset(chip, 0, sizeof(opl3_chip) + (n_voices * (sizeof(opl3_slot) * 2 + sizeof(opl3_channel))));
|
||||
|
||||
chip->rateratio = rateratio;
|
||||
chip->n_voices = n_voices;
|
||||
chip->slot = slot;
|
||||
chip->channel = channel;
|
||||
|
||||
for (slotnum = 0; slotnum < (chip->n_voices * 2); slotnum++)
|
||||
{
|
||||
slot = &chip->slot[slotnum];
|
||||
slot->chip = chip;
|
||||
slot->mod = &chip->zeromod;
|
||||
slot->eg_rout = 0x1ff;
|
||||
slot->eg_out = 0x1ff;
|
||||
slot->eg_gen = envelope_gen_num_release;
|
||||
slot->trem = (byte*)&chip->zeromod;
|
||||
slot->slot_num = slotnum;
|
||||
}
|
||||
for (channum = 0; channum < chip->n_voices; channum++)
|
||||
{
|
||||
channel = &chip->channel[channum];
|
||||
channel->slots[0] = &chip->slot[channum * 2];
|
||||
channel->slots[1] = &chip->slot[channum * 2 + 1];
|
||||
chip->slot[channum * 2].channel = channel;
|
||||
chip->slot[channum * 2 + 1].channel = channel;
|
||||
channel->pair = &chip->channel[(channum & 1) ? (channum - 1) : (channum + 1)];
|
||||
channel->chip = chip;
|
||||
channel->out[0] = &chip->zeromod;
|
||||
channel->out[1] = &chip->zeromod;
|
||||
channel->out[2] = &chip->zeromod;
|
||||
channel->out[3] = &chip->zeromod;
|
||||
channel->chtype = ch_2op;
|
||||
channel->level[0] = 0x10000;
|
||||
channel->level[1] = 0x10000;
|
||||
channel->ch_num = channum;
|
||||
OPL3_ChannelSetupAlg(channel);
|
||||
}
|
||||
chip->tremoloshift = 4;
|
||||
chip->vibshift = 1;
|
||||
}
|
||||
|
||||
void OPL3_Rate(opl3_chip *chip, uint samplerate) {
|
||||
chip->rateratio = (samplerate << RSM_FRAC) / 49716;
|
||||
}
|
||||
|
||||
void OPL3_ChipFlags(opl3_chip *chip, byte nts, byte vibrato, byte deeptremolo, byte deepvibrato) {
|
||||
chip->nts = nts;
|
||||
chip->tremoloshift = ((deeptremolo ^ 1) << 1) + 2;
|
||||
chip->vibshift = deepvibrato ^ 1;
|
||||
}
|
||||
|
||||
opl3_chip *OPL3_Alloc(uint samplerate, byte voices) {
|
||||
opl3_chip *chip = malloc(sizeof(opl3_chip) + (voices * (sizeof(opl3_slot) * 2 + sizeof(opl3_channel))));
|
||||
chip->channel = (opl3_channel*)(((byte*)chip) + sizeof(opl3_chip));
|
||||
chip->slot = (opl3_slot*)(((byte*)chip->channel) + (voices * sizeof(opl3_channel)));
|
||||
chip->n_voices = voices;
|
||||
OPL3_Rate(chip, samplerate);
|
||||
OPL3_Reset(chip);
|
||||
return chip;
|
||||
}
|
||||
|
||||
byte OPL3_Playing(opl3_chip *chip) {
|
||||
opl3_slot *slot;
|
||||
for(int z = 0; z < (chip->n_voices * 2); z++) {
|
||||
slot = &chip->slot[z];
|
||||
if(slot->eg_out <= 0x100) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
343
player.h
Normal file
|
@ -0,0 +1,343 @@
|
|||
|
||||
static const char **plr_descs[] = { &STR_IMID_TITLE, &STR_IMID_INFO, &STR_IMID_COPY, &STR_IMID_WARN, &STR_IMID_LANG, &STR_IMID_VER };
|
||||
|
||||
byte plr_play_file(const char *midname, byte nowait) {
|
||||
mid_handle mid;
|
||||
uint size;
|
||||
if(!(size = mid_read(&mid, midname)))
|
||||
return 0;
|
||||
logi(LOG_CON, STR_MID_PLAY, midname);
|
||||
snd_instruct(mid.track, size, SND_CMD_LOAD, 0, (uint)mid.tracks | ((uint)mid.tpqn << 16) | ((uint)nowait << 31));
|
||||
mem_free(mid.track);
|
||||
return 1;
|
||||
}
|
||||
|
||||
void plr_cmlog(byte empty);
|
||||
|
||||
byte plr_play(int pos, byte nowait) {
|
||||
plr_cmlog(0);
|
||||
if(pos != (snd.mid_queued - 1))
|
||||
snd.mid_queue[pos+1][-1] = 0;
|
||||
byte status = plr_play_file(&(snd.mid_queue[pos])[6], nowait);
|
||||
if(pos != (snd.mid_queued - 1))
|
||||
snd.mid_queue[pos+1][-1] = '\n';
|
||||
snd.mid_queue[pos][0] = COL_GREEN[0];
|
||||
if(snd.mid_prevpos >= 0)
|
||||
snd.mid_queue[snd.mid_prevpos][0] = COL_NEON[0];
|
||||
snd.mid_prevpos = pos;
|
||||
return status;
|
||||
}
|
||||
|
||||
byte plr_stopped() {
|
||||
return snd_query(SND_STAT_STOPPED, 0);
|
||||
}
|
||||
|
||||
// voices -- 2 ~ 192
|
||||
byte plr_setup(byte voices, const char *dmxname, const char *drumname, byte keep, byte useunkn, char velofunc) {
|
||||
// if(dmxname) {
|
||||
bank_instr *instr = bnk_read_banks(dmxname, drumname, 0);
|
||||
if(!instr)
|
||||
return 0;
|
||||
snd_instruct(instr, sizeof(bank_instr) * 256, SND_CMD_VOICES, 0, 0);
|
||||
mem_free(instr);
|
||||
// }
|
||||
voices = (voices & 1) ? (voices + 1) : voices;
|
||||
// snd_instruct(NULL, 0, SND_CMD_BANK, dmxname ? 31 : bank, 0);
|
||||
snd_instruct(NULL, 0, SND_CMD_MKOPL, 0, (uint)voices | ((uint)((byte)(velofunc & 0xff)) << 8) | ((uint)keep << 16) | ((uint)useunkn << 17));
|
||||
return 1;
|
||||
}
|
||||
|
||||
void plr_debug(byte debug) {
|
||||
snd_instruct(NULL, 0, SND_CMD_DEBUG, 0, debug);
|
||||
snd.mid_debug = debug;
|
||||
}
|
||||
|
||||
void plr_volume(byte channel, ushort volume) {
|
||||
snd_instruct(NULL, 0, SND_CMD_VOLUME, channel, volume);
|
||||
}
|
||||
|
||||
enum repeat_type {
|
||||
REPEAT_OFF,
|
||||
REPEAT_SINGLE,
|
||||
REPEAT_ALL,
|
||||
REPEAT_SHUFFLE
|
||||
};
|
||||
|
||||
void plr_end() {
|
||||
if(snd.mid_queue) {
|
||||
mem_free(snd.mid_queue);
|
||||
mem_free(snd.mid_list);
|
||||
}
|
||||
snd.mid_queue = NULL;
|
||||
snd.mid_list = NULL;
|
||||
snd.mid_queued = 0;
|
||||
snd_instruct(NULL, 0, SND_CMD_LOAD, 0, 0);
|
||||
snd_instruct(NULL, 0, SND_CMD_MKOPL, 0, 0);
|
||||
}
|
||||
|
||||
byte plr_queue(const char *dmxname, const char *drumname, const char **files, int count) {
|
||||
plr_end();
|
||||
if(!plr_setup(snd.mid_voices, dmxname, drumname, snd.mid_keep, snd.mid_unknown, (char)snd.mid_velo))
|
||||
return 0;
|
||||
snd.mid_queue = mem_alloc(sizeof(char *) * count, MEM_FILE);
|
||||
int size = 0;
|
||||
for(int z = 0; z < count; z++) {
|
||||
size += strlen(files[z]) + 7;
|
||||
}
|
||||
char *list = snd.mid_list = mem_alloc(size, MEM_FILE);
|
||||
for(int z = 0; z < count; z++) {
|
||||
snd.mid_queue[z] = list;
|
||||
list += snprintf(list, 1024, (z == (count - 1)) ? COL_NEON "#%03d %s" : COL_NEON "#%03d %s\n", z + 1, files[z]);
|
||||
}
|
||||
snd.mid_queued = count;
|
||||
snd.mid_playpos = -1;
|
||||
snd.mid_prevpos = -1;
|
||||
}
|
||||
|
||||
void plr_mode(byte repeat) {
|
||||
snd.mid_repeat = repeat;
|
||||
}
|
||||
|
||||
void plr_pause() {
|
||||
if(!snd.mid_queue || (snd.mid_playpos == INT_MIN))
|
||||
return;
|
||||
if(snd.mid_playpos >= -1)
|
||||
snd.mid_playpos = -(snd.mid_playpos + 3);
|
||||
else
|
||||
snd.mid_playpos = -(snd.mid_playpos) - 3;
|
||||
if(snd.mid_playpos >= 0 || snd.mid_playpos < -2)
|
||||
snd.mid_queue[(snd.mid_playpos < -1) ? (-(snd.mid_playpos) - 3) : snd.mid_playpos][0] = snd.mid_playpos < -1 ? COL_YELLOW[0] : COL_GREEN[0];
|
||||
snd_instruct(NULL, 0, SND_CMD_PAUSE, 0, snd.mid_playpos < -1);
|
||||
}
|
||||
|
||||
void plr_stop() {
|
||||
if(!snd.mid_queue)
|
||||
return;
|
||||
plr_cmlog(1);
|
||||
snd.mid_playpos = INT_MIN;
|
||||
if(snd.mid_prevpos >= 0)
|
||||
snd.mid_queue[snd.mid_prevpos][0] = COL_NEON[0];
|
||||
snd.mid_prevpos = -1;
|
||||
snd_instruct(NULL, 0, SND_CMD_LOAD, 0, 0);
|
||||
}
|
||||
|
||||
void plr_resume() {
|
||||
if(!snd.mid_queue)
|
||||
return;
|
||||
if(snd.mid_playpos == INT_MIN)
|
||||
plr_play(snd.mid_playpos = 0, snd.mid_nowait);
|
||||
else if(snd.mid_playpos < -1)
|
||||
plr_pause();
|
||||
}
|
||||
|
||||
void plr_update() {
|
||||
if(snd.mid_queue && (sys.tmr_current - snd.mid_poll) >= 250000ULL) {
|
||||
snd.mid_poll = sys.tmr_current;
|
||||
if((snd.mid_playpos >= -1) && plr_stopped()) {
|
||||
if(snd.mid_playpos >= 0) {
|
||||
switch(snd.mid_repeat) {
|
||||
case REPEAT_OFF:
|
||||
snd.mid_playpos += 1;
|
||||
break;
|
||||
case REPEAT_SINGLE:
|
||||
break;
|
||||
case REPEAT_ALL:
|
||||
if((snd.mid_playpos += 1) >= snd.mid_queued)
|
||||
snd.mid_playpos = 0;
|
||||
break;
|
||||
case REPEAT_SHUFFLE:
|
||||
snd.mid_playpos = rand() % snd.mid_queued;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else {
|
||||
snd.mid_playpos = 0;
|
||||
}
|
||||
if(snd.mid_playpos >= snd.mid_queued)
|
||||
plr_stop();
|
||||
else
|
||||
plr_play(snd.mid_playpos, snd.mid_nowait);
|
||||
if(snd.player && snd.player->open) {
|
||||
gui_update_text(gui_get(snd.player, 1));
|
||||
gui_plr_update(snd.player);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void plr_jump(int pos) {
|
||||
if(!snd.mid_queue)
|
||||
return;
|
||||
plr_resume();
|
||||
pos = CLAMP_VALUE(pos, 0, snd.mid_queued - 1);
|
||||
plr_play(snd.mid_playpos = pos, snd.mid_nowait);
|
||||
}
|
||||
|
||||
void plr_next() {
|
||||
if(!snd.mid_queue)
|
||||
return;
|
||||
plr_resume();
|
||||
if((snd.mid_playpos += 1) >= snd.mid_queued)
|
||||
snd.mid_playpos = 0;
|
||||
plr_play(snd.mid_playpos, snd.mid_nowait);
|
||||
}
|
||||
|
||||
void plr_prev() {
|
||||
if(!snd.mid_queue)
|
||||
return;
|
||||
plr_resume();
|
||||
if((snd.mid_playpos -= 1) < 0)
|
||||
snd.mid_playpos = snd.mid_queued - 1;
|
||||
plr_play(snd.mid_playpos, snd.mid_nowait);
|
||||
}
|
||||
|
||||
void plr_rand() {
|
||||
if(!snd.mid_queue)
|
||||
return;
|
||||
plr_resume();
|
||||
plr_play((snd.mid_playpos = rand() % snd.mid_queued), snd.mid_nowait);
|
||||
}
|
||||
|
||||
void plr_capture(const char *wavname) {
|
||||
snd_instruct(wavname, wavname ? (strlen(wavname) + 1) : 0, SND_CMD_WAVECAP, 0, 0);
|
||||
}
|
||||
|
||||
void plr_clog() {
|
||||
snd.mid_klog_pos = 0;
|
||||
snd.mid_klog_offs = 0;
|
||||
for(int z = 0; z < SND_KLOG; z++) {
|
||||
memset(&snd.mid_klogger[z * SND_KAR], ' ', SND_KAR - 1);
|
||||
snd.mid_klogger[z * SND_KAR + (SND_KAR - 1)] = (z == (SND_KLOG - 1)) ? 0 : '\n';
|
||||
}
|
||||
if(snd.player && snd.player->open)
|
||||
gui_update_text(gui_get(snd.player, 16));
|
||||
}
|
||||
|
||||
void plr_cmlog(byte empty) {
|
||||
snd.mid_karaoke = 0;
|
||||
for(int z = 0; z < 6; z++) {
|
||||
snd.mid_info_offs[z] = empty ? 0 : sprintf(&snd.mid_info[z * SND_INFO], "%-12s: ", *(plr_descs[z]));
|
||||
if(!empty) {
|
||||
memset(&snd.mid_info[z * SND_INFO + snd.mid_info_offs[z]], ' ', SND_INFO - 1);
|
||||
snd.mid_info[z * SND_INFO + (SND_INFO - 1)] = (z == 5) ? 0 : '\n';
|
||||
}
|
||||
}
|
||||
if(empty)
|
||||
snd.mid_info[0] = 0;
|
||||
plr_clog();
|
||||
if(snd.player && snd.player->open)
|
||||
gui_update_text(gui_get(snd.player, 15));
|
||||
}
|
||||
|
||||
void plr_kar() {
|
||||
if(snd.mid_karaoke ^ 1) {
|
||||
snd.mid_karaoke = 1;
|
||||
plr_clog();
|
||||
}
|
||||
}
|
||||
|
||||
void plr_info(int type, const char *text) {
|
||||
char *info = &snd.mid_info[type * SND_INFO];
|
||||
int offs = snd.mid_info_offs[type];
|
||||
int len = strlen(text);
|
||||
int max = (SND_INFO - 1) - 14;
|
||||
max -= (offs > 14) ? 2 : 0;
|
||||
len = (len > (max-offs)) ? (max-offs) : len;
|
||||
if(len <= 0) {
|
||||
return;
|
||||
}
|
||||
if(offs > 14) {
|
||||
info[offs++] = ';';
|
||||
info[offs++] = ' ';
|
||||
}
|
||||
// else {
|
||||
// max = sprintf(info, "%-12s: ", *(plr_descs[type]));
|
||||
// memset(info+(max + len), ' ', SND_INFO - (1 + max + len));
|
||||
// offs += max;
|
||||
// }
|
||||
memcpy(info+offs, text, len);
|
||||
offs += len;
|
||||
// info[SND_INFO - 1] = (type == 5) ? 0 : '\n';
|
||||
snd.mid_info_offs[type] = offs;
|
||||
if(snd.player && snd.player->open)
|
||||
gui_update_text(gui_get(snd.player, 15));
|
||||
}
|
||||
|
||||
void plr_tlog(int type, const char *text) {
|
||||
int slen = strlen(text);
|
||||
// for(int h = 0; h < slen; h++) {
|
||||
// text[h] = ((text[h] < 32) && (text[h] >= 0)) ? ((h == (slen-1)) ? 0 : '?') : text[h];
|
||||
// }
|
||||
if((type == 1) && (text[0] == '@')) {
|
||||
// text += 1;
|
||||
switch(text[1]) {
|
||||
case 'T':
|
||||
plr_info(0, text+2);
|
||||
return;
|
||||
case 'I':
|
||||
plr_info(1, text+2);
|
||||
return;
|
||||
case 'K':
|
||||
plr_info(2, text+2);
|
||||
return;
|
||||
case 'W':
|
||||
plr_info(3, text+2);
|
||||
return;
|
||||
case 'L':
|
||||
plr_info(4, text+2);
|
||||
return;
|
||||
case 'V':
|
||||
plr_info(5, text+2);
|
||||
return;
|
||||
}
|
||||
// text += (text[0] == 0) ? 0 : 1;
|
||||
}
|
||||
else if((type == 1) && (text[0] == '%') && (text[1] == '-')) {
|
||||
plr_kar();
|
||||
return;
|
||||
}
|
||||
else if(type == 1 /* || type == 5 */) {
|
||||
switch(text[0]) {
|
||||
case '\\':
|
||||
plr_kar();
|
||||
plr_clog();
|
||||
text += 1;
|
||||
slen -= 1;
|
||||
break;
|
||||
case '/':
|
||||
// mid_kar();
|
||||
if(snd.mid_karaoke) {
|
||||
snd.mid_klog_pos += 1;
|
||||
snd.mid_klog_offs = 0;
|
||||
if(snd.mid_klog_pos == SND_KLOG)
|
||||
plr_clog();
|
||||
text += 1;
|
||||
slen -= 1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if(snd.mid_karaoke) {
|
||||
int len;
|
||||
while(slen > 0) {
|
||||
len = (slen > ((SND_KAR - 1) - snd.mid_klog_offs)) ? ((SND_KAR - 1) - snd.mid_klog_offs) : slen;
|
||||
if(len <= 0)
|
||||
break;
|
||||
memcpy(&snd.mid_klogger[snd.mid_klog_pos * SND_KAR + snd.mid_klog_offs], text, len);
|
||||
snd.mid_klog_offs += len;
|
||||
// snd.mid_klogger[snd.mid_klog_pos * SND_KAR + snd.mid_klog_offs] = 0;
|
||||
slen -= len;
|
||||
if(slen > 0) {
|
||||
snd.mid_klog_pos += 1;
|
||||
snd.mid_klog_offs = 0;
|
||||
if(snd.mid_klog_pos == SND_KLOG)
|
||||
plr_clog();
|
||||
}
|
||||
}
|
||||
if(snd.player && snd.player->open)
|
||||
gui_update_text(gui_get(snd.player, 16));
|
||||
return;
|
||||
}
|
||||
}
|
||||
if(snd.mid_debug || (type <= 2) || (type >= 5))
|
||||
logd(LOG_CON, STR_MID_TEXT, type, text);
|
||||
}
|
214
program.c
Normal file
|
@ -0,0 +1,214 @@
|
|||
|
||||
/*
|
||||
Een net ganz funktionierndes Programm ...
|
||||
|
||||
Absolute Mindestanforderungen:
|
||||
|
||||
Prozessor : Intel Core i3 530 oder AMD Phenom 2 X2 545
|
||||
Grafikkarte : NVIDIA GeForce GTS 450 oder AMD Radeon HD 7730
|
||||
Arbeitsspeicher : Etwa 512 MB ~ 1 GB, 2 - 4 GB empfohlen
|
||||
Mainboard : Was gerade passt (auch mit Hammer)
|
||||
Kühler : Ne Klimaanlage oder ordentlich Pusten
|
||||
Festplatte : Richtet sich nach der Geduld des Nutzers
|
||||
Netzteil : Atomkraftwerk oder stabiler Energiekern
|
||||
Gehäuse : Pappkarton, Bierkasten oder auch gar keins
|
||||
Tastatur : Hlb fktonrnd odr bsr
|
||||
Maus : Aus Plastik oder mit extra Quietsch-Effekt
|
||||
Monitor : Olle Röhre oder gebrochener Flachbild (Mindestens 1280x800)
|
||||
Stuhl : Interessiert niemanden (sonst siehe Gehäuse)
|
||||
|
||||
[[oder einfach einen Toaster mit nem LCD und Maus]]
|
||||
*/
|
||||
|
||||
#if !defined(__x86_64) && !defined(__amd64) && !defined(_M_AMD64)
|
||||
#error "Programm erfordert die Prozessor-Architektur x86_64 ('AMD64' / 'Intel 64')"
|
||||
#endif
|
||||
|
||||
#if !defined(__SSE__)
|
||||
#error "Die x86_64-Erweiterung SSE ist nicht vorhanden"
|
||||
#endif
|
||||
|
||||
#if !defined(__SSE2__)
|
||||
#error "Die x86_64-Erweiterung SSE2 ist nicht vorhanden"
|
||||
#endif
|
||||
|
||||
#if !defined(__linux__) && !defined(__gnu_linux__) && !defined(__linux) && !defined(linux)
|
||||
#error "Programm unterstützt nur Linux als das System / ABI"
|
||||
#endif
|
||||
|
||||
#define SYS_PROGNAME "SKCBlitz"
|
||||
#define SYS_INFO \
|
||||
COL_GREEN SYM_BUG SYM_BUG SYM_BUG " " COL_VIOLET FMT_FADE SYS_PROGRAM_FULL FMT_RESET COL_GREEN " " SYM_BUG SYM_BUG SYM_BUG "\n"\
|
||||
"\n"\
|
||||
COL_LGRAY "Ein kleine Anwendung zur Simulation, zum Testen, für Spiele, Musik und vieles" "\n"\
|
||||
"mehr. Optimiert für Geschwindigkeit, Stabilität und" STR_UNK STR_UNK " [Speicherzugriffsfehler]" "\n"\
|
||||
"\n"\
|
||||
COL_CYAN "Geschrieben von Sen dem \"kleinen\" Dämonen " COL_CRIMSON SYM_DEMON COL_BLACK SYM_BLKHEART "\n"\
|
||||
"\n"\
|
||||
COL_YELLOW "Verwendete Programmbibliotheken:" "\n"\
|
||||
COL_LGRAY " -> " COL_NEON "axe_ork (Modifiziert: GLFW 3.3.8)" "\n"\
|
||||
COL_LGRAY " -> " COL_NEON "tcglm (Modifiziert: cglm 0.8.9)" "\n"\
|
||||
COL_LGRAY " -> " COL_NEON "stb_timage (Modifiziert: stb_image 2.28 + stb_image_write 1.16)" "\n"\
|
||||
COL_LGRAY " -> " COL_NEON "gl_loader (Modifiziert: glad 0.1.34)" "\n"\
|
||||
COL_LGRAY " -> " COL_NEON "opl3 (Modifiziert: Nuked-OPL3 f2c9873)" "\n"\
|
||||
"\n"\
|
||||
COL_YELLOW "Verwendeter Compiler: " "\n"\
|
||||
COL_LGRAY " -> " COL_NEON BUILD_COMP "\n"\
|
||||
"\n"\
|
||||
COL_YELLOW "Kompiliert auf System: " "\n"\
|
||||
COL_LGRAY " -> " COL_NEON BUILD_SYS "\n"\
|
||||
"\n"\
|
||||
"\n"\
|
||||
COL_BLACK "#0 " COL_DGRAY "#1 " COL_GRAY "#2 " COL_LGRAY "#3 " COL_WHITE "#4 " COL_RED "#5 " COL_GREEN "#6 " COL_BLUE "#7 " \
|
||||
COL_YELLOW "#8 " COL_MAGENTA "#9 " COL_CYAN "#A " COL_VIOLET "#B " COL_ORANGE "#C " COL_CRIMSON "#D " COL_MIDNIGHT "#E " COL_NEON "#F " \
|
||||
COL_LGRAY FMT_ULINE "#G" FMT_RESET " " COL_YELLOW FMT_CLINE "#H" FMT_RESET " " COL_DGRAY FMT_BLINK "#I" FMT_RESET " " COL_BLACK FMT_FADE "#J" FMT_RESET
|
||||
|
||||
#define ALSA_PCM_NEW_HW_PARAMS_API
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <time.h>
|
||||
#include <signal.h>
|
||||
#include <errno.h>
|
||||
#include <math.h>
|
||||
#include <limits.h>
|
||||
#include <float.h>
|
||||
#include <execinfo.h>
|
||||
#include <unistd.h>
|
||||
#include <dirent.h>
|
||||
#include <dlfcn.h>
|
||||
#include <locale.h>
|
||||
#include <fcntl.h>
|
||||
#include <poll.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <pthread.h>
|
||||
#include <alsa/asoundlib.h>
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/keysym.h>
|
||||
#include <X11/Xatom.h>
|
||||
#include <X11/Xcursor/Xcursor.h>
|
||||
#include <X11/extensions/Xrandr.h>
|
||||
#include <X11/XKBlib.h>
|
||||
#include <X11/extensions/Xinerama.h>
|
||||
#include <X11/extensions/XInput2.h>
|
||||
#include <X11/Xresource.h>
|
||||
#include <X11/Xmd.h>
|
||||
#include <xmmintrin.h>
|
||||
#include <emmintrin.h>
|
||||
|
||||
#include "inttypes.h"
|
||||
#include "x11_stub.h"
|
||||
#include "glx_stub.h"
|
||||
#include "system.h"
|
||||
#include "gl_types.h"
|
||||
#include "gl_constants.h"
|
||||
#include "types.h"
|
||||
#include "tcglm.h"
|
||||
#include "stb_timage.h"
|
||||
#include "argparse.h"
|
||||
#include "str.h"
|
||||
#include "list.h"
|
||||
#include "table.h"
|
||||
#include "map.h"
|
||||
#include "smap.h"
|
||||
#include "locale.h"
|
||||
#include "locale.h"
|
||||
#include "locale.h"
|
||||
#include "locale.h"
|
||||
#include "timing.h"
|
||||
#include "log.h"
|
||||
#include "gl_loader.h"
|
||||
#include "gl_loader.h"
|
||||
#include "mem.h"
|
||||
#include "files.h"
|
||||
#include "random.h"
|
||||
#include "noise.h"
|
||||
#include "texture.h"
|
||||
#include "shader.h"
|
||||
#include "buffer.h"
|
||||
#include "framebuf.h"
|
||||
#include "strdraw.h"
|
||||
#include "strdraw.h"
|
||||
#include "strdraw.h"
|
||||
#include "strdraw.h"
|
||||
#include "strdraw.h"
|
||||
#include "camera.h"
|
||||
#include "bbox.h"
|
||||
#include "entity.h"
|
||||
#include "lighting.h"
|
||||
#include "cvar.h"
|
||||
#include "console.h"
|
||||
#include "render.h"
|
||||
#include "drawlist.h"
|
||||
#include "world.h"
|
||||
#include "axe_ork.h"
|
||||
#include "gui.h"
|
||||
#include "window.h"
|
||||
#include "opl3.h"
|
||||
#include "dmx.h"
|
||||
#include "bank.h"
|
||||
#include "midi.h"
|
||||
#include "alsasnd.h"
|
||||
#include "wavfile.h"
|
||||
#include "sound.h"
|
||||
#include "player.h"
|
||||
#include "program.h"
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
SIZE_TEST(void*, 64);
|
||||
SIZE_TEST(byte, 8);
|
||||
SIZE_TEST(char, 8);
|
||||
SIZE_TEST(ushort, 16);
|
||||
SIZE_TEST(short, 16);
|
||||
SIZE_TEST(uint, 32);
|
||||
SIZE_TEST(int, 32);
|
||||
SIZE_TEST(ulong, 64);
|
||||
SIZE_TEST(long, 64);
|
||||
SIZE_TEST(float, 32);
|
||||
SIZE_TEST(double, 64);
|
||||
|
||||
SIZE_TEST(light_t, 704);
|
||||
|
||||
uint cpuid;
|
||||
asm volatile("cpuid" : "=d" (cpuid) : "0" (1));
|
||||
sys_assert((cpuid & 0x6000000) == 0x6000000);
|
||||
|
||||
int loglevel = 0xff;
|
||||
char *cfgfile = "skc.cfg";
|
||||
char *langfile = NULL;
|
||||
int gldebug = 0;
|
||||
int nosound = 0;
|
||||
int version = 0;
|
||||
int n_cmds = 0;
|
||||
char **cmds = malloc(sizeof(char*) * argc);
|
||||
|
||||
argp_t *argspec = arg_alloc(7);
|
||||
arg_add_vstr(argspec, ARGSTR_COMMANDS, 0, cmds, &n_cmds);
|
||||
arg_add_bool(argspec, 'v', ARGSTR_VERSION, &version);
|
||||
arg_add_int(argspec, 'l', ARGSTR_LOGLEVEL, LOG_SILENT, LOG_TRACE, &loglevel);
|
||||
arg_add_bool(argspec, 'g', ARGSTR_GLDEBUG, &gldebug);
|
||||
arg_add_bool(argspec, 's', ARGSTR_NOSOUND, &nosound);
|
||||
arg_add_str(argspec, 'c', ARGSTR_CONFIG, &cfgfile);
|
||||
arg_add_str(argspec, 't', ARGSTR_LANG, &langfile);
|
||||
if(!arg_parse(argspec, argc, argv)) {
|
||||
free(cmds);
|
||||
return -1;
|
||||
}
|
||||
if(version) {
|
||||
fprintf(stderr, SYS_PROGRAM_FULL "\n* " BUILD_COMP "\n* " BUILD_SYS "\n");
|
||||
free(cmds);
|
||||
return 0;
|
||||
}
|
||||
if(!init(cfgfile, langfile, loglevel, gldebug, nosound)) {
|
||||
free(cmds);
|
||||
return 1;
|
||||
}
|
||||
start(cmds, n_cmds);
|
||||
free(cmds);
|
||||
run();
|
||||
finish();
|
||||
return 0;
|
||||
}
|
743
program.h
Normal file
|
@ -0,0 +1,743 @@
|
|||
|
||||
byte win_down(byte bind) {
|
||||
return sys.binds[bind].pressed;
|
||||
}
|
||||
|
||||
byte win_pressed(byte bind) {
|
||||
return sys.binds[bind].active;
|
||||
}
|
||||
|
||||
void handle_int(int sig) {
|
||||
sys.interrupted = 1;
|
||||
fprintf(stderr, "\n");
|
||||
}
|
||||
|
||||
void input() {
|
||||
bind_t *bind;
|
||||
for(int z = 0; z < KEY_BINDS; z++) {
|
||||
bind = &sys.binds[z];
|
||||
if(sys.input ^ 1) {
|
||||
bind->pressed = 0;
|
||||
}
|
||||
else if(bind->key >= 1 && bind->key <= KEYSYM_LAST) {
|
||||
bind->pressed = wcf.active && (wcf_getkey(wcf.active, bind->key) == KEY_PRESS);
|
||||
}
|
||||
else if(bind->key >= -MOUSE_BTN_C && bind->key <= -MOUSE_LEFT) {
|
||||
bind->pressed = wcf.active && !(wcf.active->open) && ((wcf.active->mouse >> (-MOUSE_LEFT - bind->key)) & 1);
|
||||
if(!sys.mouse_bind)
|
||||
bind->last_state = bind->pressed;
|
||||
}
|
||||
else if(bind->key >= -SCROLL_RIGHT && bind->key <= -SCROLL_UP) {
|
||||
bind->pressed = wcf.active && !(wcf.active->open) && ((wcf.active->scroll >> (-SCROLL_UP - bind->key)) & 1);
|
||||
}
|
||||
else {
|
||||
bind->pressed = 0;
|
||||
}
|
||||
bind->active = bind->pressed && !(bind->last_state);
|
||||
bind->last_state = bind->pressed;
|
||||
}
|
||||
sys.mouse_bind = 1;
|
||||
if(wcf.active)
|
||||
wcf.active->scroll = 0;
|
||||
|
||||
if(win_pressed(KEY_QUIT)) {
|
||||
sys.interrupted = 1;
|
||||
}
|
||||
if(win_pressed(KEY_SYNC)) {
|
||||
cvar_setint("win_sync", sys.win_vsync ? sys.sync_limit : (sys.sync_limited ? -1 : 0));
|
||||
}
|
||||
if(win_pressed(KEY_SCREENSHOT)) {
|
||||
sys.screenshot = 1;
|
||||
}
|
||||
if(win_pressed(KEY_PLAYER)) {
|
||||
plr_rand();
|
||||
if(snd.player && snd.player->open)
|
||||
gui_update_text(gui_get(snd.player, 1));
|
||||
}
|
||||
if(wcf.active && wcf.active->world) {
|
||||
if(win_pressed(KEY_FULLSCREEN)) {
|
||||
win_full(!sys.win_full);
|
||||
}
|
||||
if(win_pressed(KEY_MENU)) {
|
||||
gui_open(wcf.active, wcf.active->open ^ 1);
|
||||
}
|
||||
if(win_pressed(KEY_SHOW)) {
|
||||
if(sys.draw_debug) {
|
||||
sys.draw_debug = sys.draw_fps = 0;
|
||||
}
|
||||
else {
|
||||
sys.draw_debug = sys.draw_fps;
|
||||
sys.draw_fps = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(wcf.active && wcf.active->world && !wcf.active->open) {
|
||||
if(wcf.active->world->pointed && win_pressed(KEY_FLY)) {
|
||||
world_remove(wcf.active->world, wcf.active->world->pointed);
|
||||
}
|
||||
if(wcf.active->world->noclip) {
|
||||
if((!(wcf.active->world->camonly) && win_pressed(KEY_NOCLIP)) || (wcf.active->world->camonly && win_pressed(KEY_CAMERA))) {
|
||||
if(wcf.active->world->camonly && wcf.active->world->entity) {
|
||||
cam_angle_ent(&wcf.active->world->camera, wcf.active->world->entity);
|
||||
cam_pos_ent(&wcf.active->world->camera, wcf.active->world->entity, 0.0);
|
||||
}
|
||||
log_hud(wcf.active, wcf.active->world->camonly ? STR_CAMERA_OFF : STR_NOCLIP_OFF);
|
||||
wcf.active->world->noclip = wcf.active->world->camonly = 0;
|
||||
}
|
||||
}
|
||||
else if(wcf.active->world->entity) {
|
||||
if(win_pressed(KEY_NOCLIP)) {
|
||||
log_hud(wcf.active, STR_NOCLIP_ON);
|
||||
wcf.active->world->noclip = 1;
|
||||
}
|
||||
else if(win_pressed(KEY_CAMERA)) {
|
||||
log_hud(wcf.active, STR_CAMERA_ON);
|
||||
wcf.active->world->noclip = wcf.active->world->camonly = 1;
|
||||
}
|
||||
}
|
||||
if(win_down(KEY_ZOOM_IN)) {
|
||||
cam_zoom(&wcf.active->world->camera, 0.05f);
|
||||
}
|
||||
if(win_down(KEY_ZOOM_OUT)) {
|
||||
cam_zoom(&wcf.active->world->camera, -0.05f);
|
||||
}
|
||||
if((wcf.active->world->noclip && wcf.active->world->camonly) || !(wcf.active->world->entity)) {
|
||||
float speed = sys.speed * (win_down(KEY_FAST) ? 20.0f : 5.0f);
|
||||
if(win_down(KEY_DOWN)) {
|
||||
cam_move_noclip(&wcf.active->world->camera, sys.fdelta, speed, DIR_DOWN);
|
||||
}
|
||||
if(win_down(KEY_UP)) {
|
||||
cam_move_noclip(&wcf.active->world->camera, sys.fdelta, speed, DIR_UP);
|
||||
}
|
||||
if(win_down(KEY_FORWARD)) {
|
||||
cam_move_noclip(&wcf.active->world->camera, sys.fdelta, speed, DIR_FORWARD);
|
||||
}
|
||||
if(win_down(KEY_BACKWARD)) {
|
||||
cam_move_noclip(&wcf.active->world->camera, sys.fdelta, speed, DIR_BACKWARD);
|
||||
}
|
||||
if(win_down(KEY_LEFT)) {
|
||||
cam_move_noclip(&wcf.active->world->camera, sys.fdelta, speed, DIR_LEFT);
|
||||
}
|
||||
if(win_down(KEY_RIGHT)) {
|
||||
cam_move_noclip(&wcf.active->world->camera, sys.fdelta, speed, DIR_RIGHT);
|
||||
}
|
||||
}
|
||||
else {
|
||||
wcf.active->world->entity->speed = /* sys.speed_fixed ? 1.0f : */ sys.speed;
|
||||
wcf.active->world->entity->sprint = win_down(KEY_FAST);
|
||||
wcf.active->world->entity->sneak = win_down(KEY_DOWN);
|
||||
wcf.active->world->entity->jump = win_down(KEY_UP);
|
||||
wcf.active->world->entity->forward = (win_down(KEY_FORWARD) ? 1.0f : 0.0f) + (win_down(KEY_BACKWARD) ? -1.0f : 0.0f);
|
||||
wcf.active->world->entity->strafe = (win_down(KEY_LEFT) ? 1.0f : 0.0f) + (win_down(KEY_RIGHT) ? -1.0f : 0.0f);
|
||||
}
|
||||
// if(wld.entity && !(wld.camonly))
|
||||
// ent_angle_cam(wld.entity, &wld.camera);
|
||||
}
|
||||
if(!(sys.keywait))
|
||||
sys.input = 1;
|
||||
}
|
||||
|
||||
void screenshot() {
|
||||
time_t t = time(0);
|
||||
struct tm *date = localtime(&t);
|
||||
struct stat statbuf;
|
||||
int stride = (((wcf.current->frame_x * 3) & 3) ? (4 + ((wcf.current->frame_x * 3) & ~3)) : (wcf.current->frame_x * 3));
|
||||
int n = 0;
|
||||
byte *data = mem_alloc(stride * wcf.current->frame_y, MEM_IMAGE);
|
||||
mkdir(DIR_SCREENSHOTS, 0777);
|
||||
do {
|
||||
sprintf(sys.work_buf, DIR_SCREENSHOTS"/screen_%02d-%02d-%d_%02d-%02d-%02d%s%.0d.png",
|
||||
date->tm_mday, date->tm_mon + 1, date->tm_year + 1900, date->tm_hour, date->tm_min, date->tm_sec, n ? "_" : "", n);
|
||||
n++;
|
||||
}
|
||||
while(!stat(sys.work_buf, &statbuf));
|
||||
glReadPixels(wcf.current->offset_x, (wcf.current->fb_y - wcf.current->frame_y) - wcf.current->offset_y,
|
||||
wcf.current->frame_x, wcf.current->frame_y, GL_RGB, GL_UNSIGNED_BYTE, data);
|
||||
if(img_save(sys.work_buf, wcf.current->frame_x, wcf.current->frame_y, 0, 1, stride, data))
|
||||
logu(LOG_SYS, STR_MSG_SCREENSHOT, sys.work_buf);
|
||||
mem_free(data);
|
||||
}
|
||||
|
||||
const char *framecode() {
|
||||
return (sys.tmr_framerate >= 59.0f) ? COL_GREEN : ((sys.tmr_framerate >= 29.0f) ? COL_YELLOW : ((sys.tmr_framerate >= 14.0f) ? COL_ORANGE : COL_RED));
|
||||
}
|
||||
|
||||
const char *tpscode() {
|
||||
return (sys.tick_tickrate >= (((float)sys.tick_target / 1000.0f) - 1.0f)) ? COL_GREEN : ((sys.tick_tickrate >= (((float)sys.tick_target / 1000.0f) / 2.0f - 1.0f)) ? COL_YELLOW :
|
||||
((sys.tick_tickrate >= (((float)sys.tick_target / 1000.0f) / 4.0f - 1.0f)) ? COL_ORANGE : COL_RED));
|
||||
}
|
||||
|
||||
ulong perf_get(byte section) {
|
||||
return sys.tmr_profile[(sys.perf_swap ? 0 : PERF_SECTIONS) + section];
|
||||
}
|
||||
|
||||
byte gl_isdebug() {
|
||||
int flags;
|
||||
glGetIntegerv(GL_CONTEXT_FLAGS, &flags);
|
||||
return (flags & GL_CONTEXT_FLAG_DEBUG_BIT) == GL_CONTEXT_FLAG_DEBUG_BIT;
|
||||
}
|
||||
|
||||
const char *gl_getsuffix() {
|
||||
int mask;
|
||||
glGetIntegerv(GL_CONTEXT_PROFILE_MASK, &mask);
|
||||
if(mask & GL_CONTEXT_COMPATIBILITY_PROFILE_BIT)
|
||||
return " compat";
|
||||
else if(mask & GL_CONTEXT_CORE_PROFILE_BIT)
|
||||
return " core";
|
||||
else
|
||||
return "";
|
||||
}
|
||||
|
||||
void print_debug(world_t *world) {
|
||||
int pos;
|
||||
pos = sprintf(sys.work_buf,
|
||||
"%s%.2f"COL_RESET" %s, @ "COL_RED"%.1f "COL_GREEN"%.1f "COL_CYAN"%.1f"COL_RESET", Y "COL_MAGENTA"%.1f"COL_RESET", P "COL_YELLOW"%.1f"COL_RESET
|
||||
", H %.1f, F %.1f, Z %.1f, M "COL_RED"%.1f "COL_GREEN"%.1f "COL_CYAN"%.1f"COL_RESET
|
||||
,
|
||||
framecode(), (sys.tmr_framerate < 1.0f) ? (1.0f / sys.tmr_framerate) : sys.tmr_framerate, sys.tmr_framerate < 1.0f ? "SPF" : "FPS",
|
||||
world->camera.pos_x, world->camera.pos_y, world->camera.pos_z, world->camera.yaw, world->camera.pitch, (world->entity && !world->camonly) ? world->entity->eye : 0.0,
|
||||
gdr.fov, world->camera.zoom * (gdr.fov - 1.0f),
|
||||
world->entity ? world->entity->motion_x : 0.0, world->entity ? world->entity->motion_y : 0.0, world->entity ? world->entity->motion_z : 0.0
|
||||
);
|
||||
if(world->pointed)
|
||||
pos = sprintf(&sys.work_buf[pos],
|
||||
", -> "COL_YELLOW"#%llu "COL_RESET"("COL_RED"%.1f "COL_GREEN"%.1f "COL_CYAN"%.1f"COL_RESET")"
|
||||
,
|
||||
world->pointed, world->look_pos X, world->look_pos Y, world->look_pos Z
|
||||
);
|
||||
}
|
||||
|
||||
void tick_start(world_t *world) {
|
||||
world->last_cx = (int)NEG_OFFSET(world->camera.pos_x, CHUNK_SIZE);
|
||||
world->last_cy = (int)NEG_OFFSET(world->camera.pos_y, CHUNK_SIZE);
|
||||
world->last_cz = (int)NEG_OFFSET(world->camera.pos_z, CHUNK_SIZE);
|
||||
if(world->entity && !(world->camonly))
|
||||
ent_angle_cam(world->entity, &world->camera);
|
||||
}
|
||||
|
||||
void tick_main(world_t *world) {
|
||||
ent_tick(&world->entity_base);
|
||||
}
|
||||
|
||||
void tick_end(world_t *world) {
|
||||
if(world->entity && !(world->camonly))
|
||||
cam_pos_ent(&world->camera, world->entity, sys.tick_fraction);
|
||||
if(world->last_cx != (int)NEG_OFFSET(world->camera.pos_x, CHUNK_SIZE) || world->last_cy != (int)NEG_OFFSET(world->camera.pos_y, CHUNK_SIZE) ||
|
||||
world->last_cz != (int)NEG_OFFSET(world->camera.pos_z, CHUNK_SIZE))
|
||||
world->light_dirty = 1;
|
||||
}
|
||||
|
||||
void tick() {
|
||||
window_t *win;
|
||||
sys.tick_stime = tmr_rtime();
|
||||
if((sys.tick_stime - sys.tick_update) >= 1000000ULL) {
|
||||
sys.tick_tickrate = ((float)sys.tick_done) * 1000000.0f / ((float)(ulong)(sys.tick_stime - sys.tick_update));
|
||||
sys.tick_done = 0;
|
||||
sys.tick_update = sys.tick_stime;
|
||||
}
|
||||
if(sys.ticked ^ 1) {
|
||||
sys.tick_time = 0ULL;
|
||||
return;
|
||||
}
|
||||
sys.tick_torun += (((ulong)sys.tick_target) * sys.tmr_delta) / 1000ULL;
|
||||
sys.tick_frame = 0;
|
||||
for(win = wcf.window_list; win; win = win->next) {
|
||||
if(win->world)
|
||||
tick_start(win->world);
|
||||
}
|
||||
while(sys.tick_torun >= 1000000ULL) {
|
||||
for(win = wcf.window_list; win; win = win->next) {
|
||||
if(win->world)
|
||||
tick_main(win->world);
|
||||
}
|
||||
sys.tick_done += 1ULL;
|
||||
sys.tick_frame += 1;
|
||||
sys.tick_total += 1ULL;
|
||||
sys.tick_torun -= 1000000ULL;
|
||||
if((sys.tick_ftime = (tmr_rtime() - sys.tick_stime)) >= (((ulong)sys.tick_timeout) * 1000ULL)) {
|
||||
logw(LOG_TIC, STR_TICK_TIMEOUT, sys.tick_ftime / 1000ULL, sys.tick_timeout, sys.tick_torun / 1000000ULL);
|
||||
sys.tick_torun = 0ULL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
sys.tick_fraction = ((double)sys.tick_torun) / 1000000.0;
|
||||
for(win = wcf.window_list; win; win = win->next) {
|
||||
if(win->world)
|
||||
tick_end(win->world);
|
||||
}
|
||||
sys.tick_ttime += sys.tick_ftime;
|
||||
sys.tick_time = sys.tick_frame ? (sys.tick_ftime / (ulong)sys.tick_frame) : 0ULL;
|
||||
}
|
||||
|
||||
void tick_target(float tps) {
|
||||
sys.tick_target = (int)(tps * 1000.0f);
|
||||
sys.tick_torun = 0ULL;
|
||||
sys.tick_done = 0ULL;
|
||||
sys.tick_update = tmr_rtime();
|
||||
sys.ticked = tps > 0.0f;
|
||||
}
|
||||
|
||||
float rfloat(float min, float max) {
|
||||
return ((float)(int)(rand() % 1000000000)) / 1000000000.0f * (max - min) + min;
|
||||
}
|
||||
|
||||
void floor_test(world_t *world, material_t *mat, int n) {
|
||||
for(int z = 0; z < n; z++) {
|
||||
world_add_floor(world, rfloat(-1800.0f, 1800.0f), rfloat(-230.0f, 230.0f), rfloat(-1800.0f, 1800.0f), rfloat(8.0f, 40.0f), rfloat(8.0f, 40.0f), mat);
|
||||
}
|
||||
}
|
||||
|
||||
void snd_apply() {
|
||||
plr_debug(cvar_byte("mid_debug_events"));
|
||||
for(int z = 0; z < SND_VOLUMES; z++) {
|
||||
plr_volume(z, (ushort)(cvar_float(snd_cvar_volume[z]) * 32767.0f));
|
||||
}
|
||||
}
|
||||
|
||||
void save_vars() {
|
||||
cvar_setint("win_pos_x", sys.console->xpos);
|
||||
cvar_setint("win_pos_y", sys.console->ypos);
|
||||
cvar_setint("win_width", sys.console->xsize);
|
||||
cvar_setint("win_height", sys.console->ysize);
|
||||
}
|
||||
|
||||
static const float lm_test[] = {20.0f, 20.0f, 40.0f, 20.0f, 20.0f, 40.0f};
|
||||
|
||||
float wg_test(void *p, float x, float z) {
|
||||
noisegen_t *gen = (noisegen_t*)p;
|
||||
// float n = (x * x + z * z) *
|
||||
// (sinf(7.57f * M_PI*2.0f*x) + 1.0f) * (sinf(16.7585f * M_PI*2.0f*z) + 1.0f) * (sinf(8.657f * M_PI*2.0f*x) + 1.0f) * (sinf(6.75485f * M_PI*2.0f*z) + 1.0f);
|
||||
// srand((int)(x * 16384.0f) ^ (int)(z * 16384.0f));
|
||||
// n += rfloat(0.0f, n / 8.0f);
|
||||
double n;
|
||||
noise_gen(gen, &n, (double)x, 0, (double)z, 1, 1, 1, 512.0, 512.0, 512.0);
|
||||
return (float)(n / 512.0);
|
||||
}
|
||||
|
||||
uint tex_test, tex_floor;
|
||||
material_t *mat_test;
|
||||
material_t *mat_floor;
|
||||
material_t *mat_grid;
|
||||
material_t *mat_vis;
|
||||
|
||||
void start(char **cmds, int n_cmds) {
|
||||
tex_load(&tex_test, "textures/test.png", TEX_FLAG_FILTER | TEX_FLAG_MIPMAP);
|
||||
tex_load(&tex_floor, "textures/floor.png", TEX_FLAG_FILTER | TEX_FLAG_MIPMAP);
|
||||
mat_test = gfx_add_material(tex_test, 512.0f, 0xffffff, 4.0f, NULL);
|
||||
mat_floor = gfx_add_material(tex_floor, 512.0f, 0xffffff, 1.0f, NULL);
|
||||
mat_grid = gfx_add_material(0, 512.0f, 0xffffff, 1.0f, gdr.shd_grid);
|
||||
mat_vis = gfx_add_material(0, 512.0f, 0xffffff, 1.0f, gdr.shd_vis);
|
||||
// plr_play("/home/sen/Musik/midi50k/Video_Games/ff/ff2cecil.mid", 0);
|
||||
for(int z = 0; z < n_cmds; z++) {
|
||||
if(strlen(cmds[z]) >= CON_LINE)
|
||||
loge(LOG_SYS, STR_CON_TOOLONG, z + 1);
|
||||
else
|
||||
con_exec(cmds[z]);
|
||||
}
|
||||
}
|
||||
|
||||
void test(window_t *win) {
|
||||
world_init(win, 0.0, 32.0, 0.0, 90.0f, 0.0f);
|
||||
noisegen_t gen;
|
||||
ulong rng = rng_rseed();
|
||||
noise_gen_init(&gen, &rng, 16);
|
||||
switch(rng_zrange(&rng, 3)) {
|
||||
case 0:
|
||||
for(int z = 0; z < 10; z++) {
|
||||
world_add_box(win->world, 10.0f + (float)z * 2.0f, 64.0f, 20.0f, 4.0f, (float)(z + 1) * 0.5f, 6.0f, mat_test);
|
||||
}
|
||||
world_add_graph(win->world, wg_test, &gen, -1536.0f, 0.0f, -1536.0f, 3072.0f, 0.125f, 3072.0f, mat_floor,
|
||||
128, 128, 0.0f, 0.0f, 512.0f, 512.0f, 1);
|
||||
light_b lamp;
|
||||
for(int z = 0; z < 256; z++) {
|
||||
light_init_def(&lamp, ((rand() & 0xff) | 0x40) << ((rand() % 3) << 3), 1.0f);
|
||||
world_add_light(win->world, &lamp, rfloat(-1250.0f, 1250.0f), rfloat(4.0f, 8.0f), rfloat(-1250.0f, 1250.0f));
|
||||
}
|
||||
break;
|
||||
|
||||
case 1:
|
||||
world_add_graph(win->world, wg_test, &gen, -1536.0f, 0.0f, -1536.0f, 3072.0f, 2.0f, 3072.0f, mat_grid,
|
||||
128, 128, 0.0f, 0.0f, 512.0f, 512.0f, 1);
|
||||
break;
|
||||
|
||||
case 2:
|
||||
world_add_graph(win->world, wg_test, &gen, -1536.0f, 0.0f, -1536.0f, 3072.0f, 1.0f, 3072.0f, mat_vis,
|
||||
256, 256, 0.0f, 0.0f, 512.0f, 512.0f, 1);
|
||||
break;
|
||||
}
|
||||
noise_gen_free(&gen);
|
||||
}
|
||||
|
||||
void run() {
|
||||
window_t *win;
|
||||
PERF_FIRST()
|
||||
while(sys.interrupted ^ 1) {
|
||||
PERF_START(PERF_TIMING)
|
||||
sys.tmr_current = tmr_rtime();
|
||||
sys.tmr_delta = sys.tmr_current - sys.tmr_last;
|
||||
sys.tmr_last = sys.tmr_current;
|
||||
sys.fdelta = ((float)sys.tmr_delta) / 1000000.0f;
|
||||
if((sys.tmr_current - sys.tmr_update) >= 1000000ULL) {
|
||||
sys.tmr_framerate = ((float)sys.tmr_frames) * 1000000.0f / ((float)(ulong)(sys.tmr_current - sys.tmr_update));
|
||||
sys.tmr_frames = 0;
|
||||
sys.tmr_update = sys.tmr_current;
|
||||
// logi(LOG_SYS, "%.3f FPS", sys.tmr_framerate);
|
||||
}
|
||||
PERF_SEC(PERF_INPUT)
|
||||
for(win = wcf.window_list; win; win = win->next) {
|
||||
gui_check(win);
|
||||
}
|
||||
input();
|
||||
if(wcf.active)
|
||||
gui_await(wcf.active);
|
||||
PERF_SEC(PERF_TICK)
|
||||
tick();
|
||||
PERF_SEC(PERF_UPDATE)
|
||||
plr_update();
|
||||
for(win = wcf.window_list; win; win = win->next) {
|
||||
if(win->world) {
|
||||
// wcf_selcontext(wcf.active);
|
||||
// glViewport(0, 0, wcf.active->fb_x, wcf.active->fb_y);
|
||||
world_update(win->world);
|
||||
win->world->pointed = box_get_pointed(win->world, &win->world->camera, win->world->look_pos);
|
||||
}
|
||||
}
|
||||
PERF_SEC(PERF_RENDER)
|
||||
gdr.lists_drawn = 0;
|
||||
gdr.tris_drawn = 0;
|
||||
for(win = wcf.window_list; win; win = win->next) {
|
||||
if(win->world) {
|
||||
wcf_selcontext(win);
|
||||
gdr.shader = 0;
|
||||
glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, gdr.post ? win->world->fb_post : 0);
|
||||
glClearColor(gdr.clear_r, gdr.clear_g, gdr.clear_b, gdr.clear_a);
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
if(gdr.wireframe)
|
||||
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
|
||||
glViewport(win->offset_x, (win->fb_y - win->frame_y) - win->offset_y,
|
||||
win->frame_x, win->frame_y);
|
||||
// gfx_pass_world();
|
||||
// glBindTexture(GL_TEXTURE_2D, gdr.tex_test);
|
||||
// glDrawArrays(GL_TRIANGLES, 0, 36);
|
||||
// draw_floor(gdr.world);
|
||||
draw_world(win->world);
|
||||
// ...
|
||||
// glViewport(0, 0, wld.window->fb_x, wld.window->fb_y);
|
||||
if(gdr.wireframe)
|
||||
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
|
||||
}
|
||||
}
|
||||
PERF_SEC(PERF_GUI)
|
||||
for(win = wcf.window_list; win; win = win->next) {
|
||||
wcf_selcontext(win);
|
||||
gdr.shader = 0;
|
||||
glViewport(0, 0, win->fb_x, win->fb_y);
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, win->fb_gui);
|
||||
glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
|
||||
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
|
||||
if(win->redraw) {
|
||||
win->redraw = 0;
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
}
|
||||
if(win->fb_x && win->fb_y)
|
||||
gfx_draw_gui(win);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
if(gdr.post && win->world)
|
||||
gfx_blit(win->world->fbtex_post);
|
||||
gfx_draw_rect(0, win->offset_y - (win->fb_x - win->frame_x) / 2, win->fb_x, win->frame_y + win->fb_x - win->frame_x, (win->fb_x - win->frame_x) / 2,
|
||||
0, 0, 0, sys.style.wbrdr_top, sys.style.wbrdr_btm);
|
||||
if(!(win->world))
|
||||
gfx_draw_rect(win->offset_x, win->offset_y, win->frame_x, win->frame_y, 0, 0, sys.style.bg_top, sys.style.bg_btm, 0, 0);
|
||||
else if(!win->open)
|
||||
gfx_draw_rect(win->offset_x + (win->frame_x / 2) - 16, win->offset_y + (win->frame_y / 2) - 16, 32, 32, 0, gdr.tex_crosshair,
|
||||
win->world->pointed ? 0xffffffff : 0xffcfcfcf, win->world->pointed ? 0xffffffff : 0xffcfcfcf, 0, 0);
|
||||
gfx_blit(win->fbtex_gui);
|
||||
if(win == wcf.active)
|
||||
gfx_draw_gui_overlay(win);
|
||||
if(win->drag_x || win->drag_y) {
|
||||
sprintf(sys.work_buf, "%d x %d", win->frame_x, win->frame_y);
|
||||
txt_draw(0, 0, 0, sys.font.yglyph, sys.font.yglyph,
|
||||
0, 0, win->fb_x, win->fb_y,
|
||||
0xffff0000, 0xff000000, &sys.font, sys.work_buf);
|
||||
}
|
||||
if(sys.hud_overlay && win->world)
|
||||
gfx_draw_con_overlay(win);
|
||||
if(sys.draw_fps && win->world) {
|
||||
// gfx_pass_text();
|
||||
if(sys.draw_debug) {
|
||||
print_debug(win->world);
|
||||
txt_draw(win->offset_x, win->offset_y + (sys.hud_bottom ? 0 : (win->frame_y - sys.font.yglyph)),
|
||||
0, sys.font.yglyph, sys.font.yglyph,
|
||||
win->offset_x, win->offset_y + (sys.hud_bottom ? 0 : (win->frame_y - sys.font.yglyph)),
|
||||
win->offset_x + win->frame_x, win->offset_y + win->frame_y,
|
||||
0xffffffff, 0x40000000, &sys.font, sys.work_buf);
|
||||
// print_profile();
|
||||
// txt_draw(win->offset_x + win->frame_x - ((sys.mono.xglyph - 1) * 28), win->offset_y, 0, sys.mono.yglyph, sys.mono.yglyph,
|
||||
// win->offset_x + win->frame_x - ((sys.mono.xglyph - 1) * 28), win->offset_y, win->offset_x + win->frame_x, win->offset_y + win->frame_y,
|
||||
// 0xffffffff, 0x40000000, &sys.mono, sys.work_buf);
|
||||
}
|
||||
else {
|
||||
sprintf(sys.work_buf, "%s%.2f", framecode(), sys.tmr_framerate);
|
||||
txt_draw(win->offset_x, win->offset_y + (sys.hud_bottom ? 0 : (win->frame_y - sys.font.yglyph)),
|
||||
0, sys.font.yglyph, sys.font.yglyph,
|
||||
win->offset_x, win->offset_y + (sys.hud_bottom ? 0 : (win->frame_y - sys.font.yglyph)),
|
||||
win->offset_x + win->frame_x, win->offset_y + win->frame_y,
|
||||
0xffffffff, 0x40000000, &sys.font, sys.work_buf);
|
||||
}
|
||||
}
|
||||
}
|
||||
PERF_SEC(PERF_REST)
|
||||
if(sys.screenshot) {
|
||||
sys.screenshot = 0;
|
||||
if(wcf.active) {
|
||||
wcf_selcontext(wcf.active);
|
||||
glViewport(0, 0, wcf.active->fb_x, wcf.active->fb_y);
|
||||
screenshot();
|
||||
}
|
||||
}
|
||||
if(sys.cfg_dirty) {
|
||||
save_vars();
|
||||
cvar_save();
|
||||
sys.cfg_dirty = 0;
|
||||
}
|
||||
PERF_SEC(PERF_SWAP)
|
||||
for(win = wcf.window_list; win; win = win->next) {
|
||||
wcf_selcontext(win);
|
||||
glViewport(0, 0, win->fb_x, win->fb_y);
|
||||
if(sys.gl_flush)
|
||||
glFlush(); // glFinish();
|
||||
wcf_swap(win);
|
||||
}
|
||||
PERF_SEC(PERF_EVENTS)
|
||||
snd_log_flush();
|
||||
wcf_poll();
|
||||
PERF_SEC(PERF_WAIT)
|
||||
while(sys.sync_limited && (tmr_rtime() - sys.tmr_current) < (1000000ULL / sys.sync_limit)) {
|
||||
;
|
||||
}
|
||||
sys.tmr_frames += 1;
|
||||
PERF_END()
|
||||
}
|
||||
PERF_LAST()
|
||||
}
|
||||
|
||||
void end() {
|
||||
wcf_end();
|
||||
// #ifdef MEM_TRACING
|
||||
// logt(LOG_MEM, STR_MEM_FREE, SYS_BASE, (ulong)(&sys), sys.mem_alloc -= SYS_BASE, "base");
|
||||
// #else
|
||||
sys.mem_alloc -= SYS_BASE;
|
||||
// #endif
|
||||
logp(LOG_MEM, STR_MEM_PEAK, sys.mem_peak);
|
||||
if(sys.mem_alloc) {
|
||||
logw(LOG_MEM, STR_MEM_LEAK, sys.mem_alloc);
|
||||
}
|
||||
logi(LOG_SYS, STR_EXIT);
|
||||
sys_remove_handlers();
|
||||
}
|
||||
|
||||
void finish() {
|
||||
logi(LOG_SYS, STR_SHUTDOWN);
|
||||
// world_delete(wld.world);
|
||||
// wld.world = NULL;
|
||||
plr_end();
|
||||
if(snd_end())
|
||||
logi(LOG_SYS, STR_SND_STOP);
|
||||
save_vars();
|
||||
win_end();
|
||||
con_end();
|
||||
cvar_end();
|
||||
gfx_end();
|
||||
end();
|
||||
}
|
||||
|
||||
void snd_start(byte disabled) {
|
||||
const char *devname = snd_edevice[cvar_int("snd_device_type")];
|
||||
if(!strcmp(devname, "hw") || !strcmp(devname, "plughw")) {
|
||||
int dev = cvar_int("snd_device_index");
|
||||
int sub = cvar_int("snd_device_sub");
|
||||
sprintf(sys.work_buf, dev < 0 ? "default" : (sub < 0 ? "%s:%d" : "%s:%d,%d"), devname, dev, sub);
|
||||
devname = sys.work_buf;
|
||||
}
|
||||
uint samplerate = snd_init(devname, cvar_int("snd_sample_rate"), cvar_byte("snd_sample_format") ? 32 : 16, cvar_int("snd_frame_size"), cvar_int("snd_buffer_size"), disabled);
|
||||
snd_log_flush();
|
||||
if(samplerate)
|
||||
logi(LOG_SYS, STR_SND_START, devname, samplerate);
|
||||
else if(!disabled && strcmp(devname, "none"))
|
||||
loge(LOG_SYS, STR_SND_STARTERR, devname);
|
||||
}
|
||||
|
||||
void snd_restart() {
|
||||
byte disabled = sgt.disabled;
|
||||
plr_end();
|
||||
if(snd_end())
|
||||
logi(LOG_SYS, STR_SND_STOP);
|
||||
memset(&sgt, 0, sizeof(isnd_t));
|
||||
memset(&snd, 0, sizeof(snd_t));
|
||||
snd_start(disabled);
|
||||
snd_apply();
|
||||
}
|
||||
|
||||
const char *gl_debug_source(uint src) {
|
||||
switch(src) {
|
||||
case GL_DEBUG_SOURCE_API:
|
||||
return "API";
|
||||
case GL_DEBUG_SOURCE_WINDOW_SYSTEM:
|
||||
return "WIN";
|
||||
case GL_DEBUG_SOURCE_SHADER_COMPILER:
|
||||
return "SHD";
|
||||
case GL_DEBUG_SOURCE_THIRD_PARTY:
|
||||
return "3RD";
|
||||
case GL_DEBUG_SOURCE_APPLICATION:
|
||||
return "PRG";
|
||||
case GL_DEBUG_SOURCE_OTHER:
|
||||
default:
|
||||
return "XXX";
|
||||
}
|
||||
}
|
||||
|
||||
const char *gl_debug_type(uint type) {
|
||||
switch(type) {
|
||||
case GL_DEBUG_TYPE_ERROR:
|
||||
return "ERR!";
|
||||
case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR:
|
||||
return "DEPR";
|
||||
case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR:
|
||||
return "NDEF";
|
||||
case GL_DEBUG_TYPE_PORTABILITY:
|
||||
return "PORT";
|
||||
case GL_DEBUG_TYPE_PERFORMANCE:
|
||||
return "PERF";
|
||||
case GL_DEBUG_TYPE_MARKER:
|
||||
return "MARK";
|
||||
case GL_DEBUG_TYPE_PUSH_GROUP:
|
||||
return "GPSH";
|
||||
case GL_DEBUG_TYPE_POP_GROUP:
|
||||
return "GPOP";
|
||||
case GL_DEBUG_TYPE_OTHER:
|
||||
default:
|
||||
return "XXXX";
|
||||
}
|
||||
}
|
||||
|
||||
byte gl_debug_severity(uint level) {
|
||||
switch(level) {
|
||||
case GL_DEBUG_SEVERITY_HIGH:
|
||||
return LOG_ERROR;
|
||||
case GL_DEBUG_SEVERITY_MEDIUM:
|
||||
return LOG_WARN;
|
||||
case GL_DEBUG_SEVERITY_LOW:
|
||||
return LOG_INFO;
|
||||
case GL_DEBUG_SEVERITY_NOTIFICATION:
|
||||
default:
|
||||
return LOG_PERF;
|
||||
}
|
||||
}
|
||||
|
||||
void gl_debug_callback(uint src, uint type, uint id, uint level, int len, const char *msg, const void *user) {
|
||||
byte lvl = gl_debug_severity(level);
|
||||
const char *color = log_colors[lvl];
|
||||
log_str(LOG_GFX, lvl, COL_DGRAY"[%sGL:%d"COL_DGRAY"][%s%s"COL_DGRAY"][%s%s"COL_DGRAY"]%s %s",
|
||||
color, id, color, gl_debug_source(src), color, gl_debug_type(type), color, msg);
|
||||
}
|
||||
|
||||
byte init(const char *cfgfile, const char *langfile, byte loglevel, byte gldebug, byte nosound) {
|
||||
clockid_t timer;
|
||||
sys_setup_handlers();
|
||||
sys_test_handlers(getenv("ERROR_HANDLER_TEST"));
|
||||
timer = tmr_gettimer();
|
||||
memset(&sys, 0, sizeof(sys_t));
|
||||
memset(&gdr, 0, sizeof(gfx_t));
|
||||
memset(&sgt, 0, sizeof(isnd_t));
|
||||
memset(&snd, 0, sizeof(snd_t));
|
||||
signal(SIGINT, handle_int);
|
||||
sys.tmr_timer = (ulong)timer;
|
||||
sys.tmr_start = tmr_time();
|
||||
sys.log_level = loglevel == 0xff ? LOG_INFO : loglevel;
|
||||
sys.log_set = loglevel;
|
||||
sys.cfg_file = cfgfile;
|
||||
sys.rng_uniq = 8682522807148012L;
|
||||
|
||||
con_reset();
|
||||
|
||||
loc_init();
|
||||
loc_def();
|
||||
if(langfile)
|
||||
loc_load(langfile);
|
||||
|
||||
logi(LOG_SYS, SYS_PROGRAM_FULL);
|
||||
logi(LOG_SYS, STR_BUILD_COMPILER, BUILD_COMP);
|
||||
logi(LOG_SYS, STR_BUILD_SYSTEM, BUILD_SYS);
|
||||
// #ifdef MEM_TRACING
|
||||
// logt(LOG_MEM, STR_MEM_ALLOC, SYS_BASE, (ulong)(&sys), sys.mem_alloc = sys.mem_peak = SYS_BASE, "base");
|
||||
// #else
|
||||
sys.mem_alloc = sys.mem_peak = SYS_BASE;
|
||||
// #endif
|
||||
|
||||
if(!wcf_init(gldebug))
|
||||
return 0;
|
||||
if(!(sys.console = wcf_create(SYS_PROGRAM, 1))) {
|
||||
loge(LOG_GFX, STR_WIN_CREATE_ERR);
|
||||
wcf_end();
|
||||
return 0;
|
||||
}
|
||||
if(gl_isdebug()) {
|
||||
glDebugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DONT_CARE, 0, NULL, 1);
|
||||
glDebugMessageCallback(gl_debug_callback, NULL);
|
||||
}
|
||||
logi(LOG_GFX, "OpenGL %s%s%s", glGetString(GL_VERSION), gl_getsuffix(), gl_isdebug() ? " debug" : "");
|
||||
logi(LOG_GFX, "GLSL %s", glGetString(GL_SHADING_LANGUAGE_VERSION));
|
||||
logi(LOG_GFX, "GL_VENDOR: %s", glGetString(GL_VENDOR));
|
||||
logi(LOG_GFX, "GL_RENDERER: %s", glGetString(GL_RENDERER));
|
||||
logi(LOG_SYS, STR_STARTUP);
|
||||
if(!gfx_init()) {
|
||||
gfx_end();
|
||||
end();
|
||||
return 0;
|
||||
}
|
||||
cvar_init();
|
||||
con_init();
|
||||
win_init();
|
||||
win_sync(cvar_int("win_sync"));
|
||||
snd_start(nosound);
|
||||
snd_apply();
|
||||
light_setup(cvar_int("gl_dynlight_max"));
|
||||
cvar_setdef("tic_target");
|
||||
tex_load(&gdr.tex_logo, "textures/logo.png", 0);
|
||||
tex_load(&gdr.tex_crosshair, "textures/crosshair.png", 0);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
txt_draw(80, 80, 0, 18, 18, 80, 80, sys.fb_x - 80, sys.fb_y - 80, 0xff1f1f1f, 0x40000000, &sys.font,
|
||||
" !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ^_`abcdefghijklmnopqrstuvwxyz{|}~"STR_UNK"§°²³´µÄÖÜßäöü€"STR_WSPC"\n"
|
||||
COL_BLACK" !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ^_`abcdefghijklmnopqrstuvwxyz{|}~"STR_UNK"§°²³´µÄÖÜßäöü€"STR_WSPC"\n"
|
||||
COL_DGRAY" !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ^_`abcdefghijklmnopqrstuvwxyz{|}~"STR_UNK"§°²³´µÄÖÜßäöü€"STR_WSPC"\n"
|
||||
COL_GRAY" !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ^_`abcdefghijklmnopqrstuvwxyz{|}~"STR_UNK"§°²³´µÄÖÜßäöü€"STR_WSPC"\n"
|
||||
COL_LGRAY" !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ^_`abcdefghijklmnopqrstuvwxyz{|}~"STR_UNK"§°²³´µÄÖÜßäöü€"STR_WSPC"\n"
|
||||
COL_WHITE" !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ^_`abcdefghijklmnopqrstuvwxyz{|}~"STR_UNK"§°²³´µÄÖÜßäöü€"STR_WSPC"\n"
|
||||
COL_RED" !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ^_`abcdefghijklmnopqrstuvwxyz{|}~"STR_UNK"§°²³´µÄÖÜßäöü€"STR_WSPC"\n"
|
||||
COL_GREEN" !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ^_`abcdefghijklmnopqrstuvwxyz{|}~"STR_UNK"§°²³´µÄÖÜßäöü€"STR_WSPC"\n"
|
||||
COL_BLUE" !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ^_`abcdefghijklmnopqrstuvwxyz{|}~"STR_UNK"§°²³´µÄÖÜßäöü€"STR_WSPC"\n"
|
||||
COL_YELLOW" !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ^_`abcdefghijklmnopqrstuvwxyz{|}~"STR_UNK"§°²³´µÄÖÜßäöü€"STR_WSPC"\n"
|
||||
COL_MAGENTA" !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ^_`abcdefghijklmnopqrstuvwxyz{|}~"STR_UNK"§°²³´µÄÖÜßäöü€"STR_WSPC"\n"
|
||||
COL_CYAN" !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ^_`abcdefghijklmnopqrstuvwxyz{|}~"STR_UNK"§°²³´µÄÖÜßäöü€"STR_WSPC"\n"
|
||||
COL_VIOLET" !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ^_`abcdefghijklmnopqrstuvwxyz{|}~"STR_UNK"§°²³´µÄÖÜßäöü€"STR_WSPC"\n"
|
||||
COL_ORANGE" !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ^_`abcdefghijklmnopqrstuvwxyz{|}~"STR_UNK"§°²³´µÄÖÜßäöü€"STR_WSPC"\n"
|
||||
COL_CRIMSON" !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ^_`abcdefghijklmnopqrstuvwxyz{|}~"STR_UNK"§°²³´µÄÖÜßäöü€"STR_WSPC"\n"
|
||||
COL_MIDNIGHT" !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ^_`abcdefghijklmnopqrstuvwxyz{|}~"STR_UNK"§°²³´µÄÖÜßäöü€"STR_WSPC"\n"
|
||||
COL_NEON" !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ^_`abcdefghijklmnopqrstuvwxyz{|}~"STR_UNK"§°²³´µÄÖÜßäöü€"STR_WSPC"\n"
|
||||
COL_AUX1" !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ^_`abcdefghijklmnopqrstuvwxyz{|}~"STR_UNK"§°²³´µÄÖÜßäöü€"STR_WSPC"\n"
|
||||
COL_AUX2" !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ^_`abcdefghijklmnopqrstuvwxyz{|}~"STR_UNK"§°²³´µÄÖÜßäöü€"STR_WSPC"\n"
|
||||
COL_AUX3" !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ^_`abcdefghijklmnopqrstuvwxyz{|}~"STR_UNK"§°²³´µÄÖÜßäöü€"STR_WSPC"\n"
|
||||
COL_AUX4" !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ^_`abcdefghijklmnopqrstuvwxyz{|}~"STR_UNK"§°²³´µÄÖÜßäöü€"STR_WSPC"\n"
|
||||
COL_AUX5" !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ^_`abcdefghijklmnopqrstuvwxyz{|}~"STR_UNK"§°²³´µÄÖÜßäöü€"STR_WSPC"\n"
|
||||
COL_AUX6" !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ^_`abcdefghijklmnopqrstuvwxyz{|}~"STR_UNK"§°²³´µÄÖÜßäöü€"STR_WSPC"\n"
|
||||
COL_AUX7" !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ^_`abcdefghijklmnopqrstuvwxyz{|}~"STR_UNK"§°²³´µÄÖÜßäöü€"STR_WSPC"\n"
|
||||
COL_AUX8" !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ^_`abcdefghijklmnopqrstuvwxyz{|}~"STR_UNK"§°²³´µÄÖÜßäöü€"STR_WSPC"\n"
|
||||
COL_RESET"END\n"
|
||||
);
|
||||
*/
|
153
random.h
Normal file
|
@ -0,0 +1,153 @@
|
|||
|
||||
#define RNG_MULT 0x5DEECE66DL
|
||||
#define RNG_ADDEND 0xBL
|
||||
#define RNG_MASK (1L << 48) - 1
|
||||
#define RNG_UNIT 0x1.0p-53 // 1.0 / (1L << 53)
|
||||
|
||||
ulong rng_rseed() {
|
||||
return (((sys.rng_uniq *= 181783497276652981L) ^ tmr_ntime()) ^ RNG_MULT) & RNG_MASK;
|
||||
}
|
||||
|
||||
ulong rng_sseed(ulong seed) {
|
||||
return (seed ^ RNG_MULT) & RNG_MASK;
|
||||
}
|
||||
|
||||
uint rng_gen(ulong *rand, int bits) {
|
||||
*rand = ((*rand) * RNG_MULT + RNG_ADDEND) & RNG_MASK;
|
||||
return (uint)((*rand) >> (48 - bits));
|
||||
}
|
||||
|
||||
uint rng_uint(ulong *rand) {
|
||||
return rng_gen(rand, 32);
|
||||
}
|
||||
|
||||
int rng_zrange(ulong *rand, int bound) {
|
||||
sys_assert(bound > 0);
|
||||
int r = rng_gen(rand, 31);
|
||||
int m = bound - 1;
|
||||
if((bound & m) == 0) // ^2
|
||||
r = (int)((bound * (long)r) >> 31);
|
||||
else
|
||||
for(int u = r; u - (r = u % bound) + m < 0; u = rng_gen(rand, 31));
|
||||
return r;
|
||||
}
|
||||
|
||||
uint rng_urange(ulong *rand, uint bound) {
|
||||
sys_assert(bound);
|
||||
uint r = rng_gen(rand, 32);
|
||||
uint m = bound - 1;
|
||||
if((bound & m) == 0) // ^2
|
||||
r = (uint)((bound * (ulong)r) >> 31);
|
||||
else
|
||||
for(uint u = r; u - (r = u % bound) + m < 0; u = rng_gen(rand, 32));
|
||||
return r;
|
||||
}
|
||||
|
||||
ulong rng_ulong(ulong *rand) {
|
||||
return ((ulong)(rng_gen(rand, 32)) << 32) | (ulong)rng_gen(rand, 32);
|
||||
}
|
||||
|
||||
byte rng_bool(ulong *rand) {
|
||||
return (byte)rng_gen(rand, 1);
|
||||
}
|
||||
|
||||
float rng_float(ulong *rand) {
|
||||
return rng_gen(rand, 24) / ((float)(1 << 24));
|
||||
}
|
||||
|
||||
double rng_double(ulong *rand) {
|
||||
return (((long)(rng_gen(rand, 26)) << 27) + rng_gen(rand, 27)) * RNG_UNIT;
|
||||
}
|
||||
|
||||
void rng_gauss(ulong *rand, double *n1, double *n2) {
|
||||
double v1, v2, s;
|
||||
do {
|
||||
v1 = 2.0 * rng_double(rand) - 1.0; // between -1 and 1
|
||||
v2 = 2.0 * rng_double(rand) - 1.0; // between -1 and 1
|
||||
s = v1 * v1 + v2 * v2;
|
||||
}
|
||||
while (s >= 1.0 || s == 0.0);
|
||||
double mul = sqrt(-2.0 * log(s)/s);
|
||||
*n1 = v1 * mul;
|
||||
*n2 = v2 * mul;
|
||||
}
|
||||
|
||||
int rng_excl(ulong *rand, int min, int max) {
|
||||
return min + rng_zrange(rand, max - min);
|
||||
}
|
||||
|
||||
int rng_ch_offset(ulong *rand) {
|
||||
return 8 + rng_gen(rand, 4);
|
||||
}
|
||||
|
||||
int rng_roll(ulong *rand, int range) {
|
||||
return 1 + rng_zrange(rand, range);
|
||||
}
|
||||
|
||||
int rng_roll_bonus(ulong *rand, int range, int bonus) {
|
||||
return 1 + rng_zrange(rand, range) + rng_zrange(rand, bonus + 1);
|
||||
}
|
||||
|
||||
int rng_range(ulong *rand, int min, int max) {
|
||||
return min + rng_zrange(rand, max + 1 - min);
|
||||
}
|
||||
|
||||
int rng_range_bonus(ulong *rand, int min, int max, int bonus) {
|
||||
return (min + rng_zrange(rand, max + 1 - min)) + rng_zrange(rand, bonus + 1);
|
||||
}
|
||||
|
||||
int rng_range_checked(ulong *rand, int min, int max) {
|
||||
return min >= max ? min : (rng_zrange(rand, max + 1 - min) + min);
|
||||
}
|
||||
|
||||
float rng_frange(ulong *rand, float min, float max) {
|
||||
return min >= max ? min : (rng_float(rand) * (max - min) + min);
|
||||
}
|
||||
|
||||
double rng_drange(ulong *rand, double min, double max) {
|
||||
return min >= max ? min : (rng_double(rand) * (max - min) + min);
|
||||
}
|
||||
|
||||
byte rng_chance(ulong *rand, int chance) {
|
||||
return !rng_zrange(rand, chance);
|
||||
}
|
||||
|
||||
byte rng_rarity(ulong *rand, int chance) {
|
||||
return rng_zrange(rand, chance) != 0;
|
||||
}
|
||||
|
||||
void *rng_select(ulong *rand, void *a, void *b, int chance) {
|
||||
return rng_zrange(rand, chance) ? a : b;
|
||||
}
|
||||
|
||||
int rng_iselect(ulong *rand, int a, int b, int chance) {
|
||||
return rng_zrange(rand, chance) ? a : b;
|
||||
}
|
||||
|
||||
byte rng_percent(ulong *rand, float chance) {
|
||||
return rng_float(rand) < chance / 100.0f;
|
||||
}
|
||||
|
||||
void *rng_pselect(ulong *rand, void *a, void *b, float chance) {
|
||||
return rng_float(rand) < chance / 100.0f ? b : a;
|
||||
}
|
||||
|
||||
void *rng_rselect(ulong *rand, void *a, void *b) {
|
||||
return rng_gen(rand, 1) != 0 ? b : a;
|
||||
}
|
||||
|
||||
void *rng_pick(ulong *rand, void **obj, uint size) {
|
||||
return obj[rng_zrange(rand, size)];
|
||||
}
|
||||
|
||||
int rng_ipick(ulong *rand, int *obj, uint size) {
|
||||
return obj[rng_zrange(rand, size)];
|
||||
}
|
||||
|
||||
void *rng_weight(ulong *rand, void *a, void *b, int ca, int cb) {
|
||||
return rng_zrange(rand, ca + cb) >= ca ? b : a;
|
||||
}
|
||||
|
||||
void *rng_fselect(ulong *rand, void *a, void *b, float chance) {
|
||||
return rng_float(rand) < chance ? b : a;
|
||||
}
|
552
render.h
Normal file
|
@ -0,0 +1,552 @@
|
|||
|
||||
/*
|
||||
void gfx_calc_mono(fchar_t *glyphs, int width, int height) {
|
||||
fchar_t *ch;
|
||||
for(int z = 0; z < 256; z++) {
|
||||
ch = &glyphs[z];
|
||||
if(ch->u) {
|
||||
ch->s = ch->t = 2;
|
||||
ch->u = width - 2;
|
||||
ch->v = height - 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
byte gfx_font_special(int width, uint ch) {
|
||||
return ((ch == CHR_UNK) || (ch == CHR_WSPC)) ? width : ((ch == CHR_SPC) ? (width / 6) : 255);
|
||||
}
|
||||
|
||||
void gfx_calc_font(byte *data, fchar_t *glyphs, int width, int height, int page) {
|
||||
int off;
|
||||
fchar_t *ch;
|
||||
for(int z = 0; z < 256; z++) {
|
||||
ch = &glyphs[z];
|
||||
if((ch->u = gfx_font_special(width, (page << 8) + z)) != 255) {
|
||||
ch->s = ch->t = 0;
|
||||
ch->v = ((int)ch->u) * height / width;
|
||||
if(((page << 8) + z) != CHR_UNK) {
|
||||
for(int x = 0; x < width; x++) {
|
||||
for(int y = 0; y < height; y++) {
|
||||
off = FONT_STRIDE(x, y, z);
|
||||
data[off+3] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
ch->s = ch->t = 255;
|
||||
ch->u = ch->v = 0;
|
||||
for(int x = 0; x < width; x++) {
|
||||
for(int y = 0; y < height; y++) {
|
||||
off = FONT_STRIDE(x, y, z);
|
||||
if(data[off+3]) {
|
||||
ch->s = x < ch->s ? x : ch->s;
|
||||
ch->t = y < ch->t ? y : ch->t;
|
||||
ch->u = x > ch->u ? x : ch->u;
|
||||
ch->v = y > ch->v ? y : ch->v;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(ch->s == 255 && ch->t == 255 && ch->u == 0 && ch->v == 0) {
|
||||
ch->s = ch->t = 0;
|
||||
}
|
||||
else {
|
||||
ch->u += 1;
|
||||
ch->v += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int gfx_load_font(font_t *font, const char *path) {
|
||||
byte *data;
|
||||
int width, height;
|
||||
int pages = 0;
|
||||
font->xglyph = 0;
|
||||
// if(mono)
|
||||
// mono->xglyph = 0;
|
||||
for(int page = 0; page < UNI_MAX_PAGES; page++) {
|
||||
sprintf(sys.work_buf, "fonts/%s_%04x.png", path, page);
|
||||
if(!(data = img_load(sys.work_buf, &width, &height, 0, 1))) {
|
||||
if(!page) {
|
||||
|
||||
return 0;
|
||||
}
|
||||
font->textures[page] = 0;
|
||||
font->sizes[page] = NULL;
|
||||
// if(mono) {
|
||||
// mono->textures[page] = 0;
|
||||
// mono->sizes[page] = NULL;
|
||||
// }
|
||||
continue;
|
||||
}
|
||||
if(page == 0) {
|
||||
if(width > 3968 || height > 3968) {
|
||||
|
||||
mem_free(data);
|
||||
return 0;
|
||||
}
|
||||
else if((width % 16) || (height % 16)) {
|
||||
|
||||
mem_free(data);
|
||||
return 0;
|
||||
}
|
||||
font->xsize = width;
|
||||
font->ysize = height;
|
||||
font->xglyph = width >> 4;
|
||||
font->yglyph = height >> 4;
|
||||
}
|
||||
else if(font->xsize != width || font->ysize != height) {
|
||||
|
||||
font->textures[page] = 0;
|
||||
font->sizes[page] = NULL;
|
||||
// if(mono) {
|
||||
// mono->textures[page] = 0;
|
||||
// mono->sizes[page] = NULL;
|
||||
// }
|
||||
mem_free(data);
|
||||
continue;
|
||||
}
|
||||
pages += 1;
|
||||
font->sizes[page] = mem_alloc(256 * sizeof(fchar_t), MEM_FONT);
|
||||
gfx_calc_font(data, font->sizes[page], font->xglyph, font->yglyph, page);
|
||||
tex_push(&font->textures[page], data, width, height);
|
||||
// if(mono) {
|
||||
// mono->sizes[page] = mem_alloc(256 * sizeof(fchar_t), MEM_FONT);
|
||||
// memcpy(mono->sizes[page], font->sizes[page], 256 * sizeof(fchar_t));
|
||||
// gfx_calc_mono(mono->sizes[page], font->xglyph, font->yglyph);
|
||||
// mono->textures[page] = font->textures[page];
|
||||
// }
|
||||
logd(LOG_GFX, STR_TEX_ILOADED, sys.work_buf, font->textures[page]);
|
||||
mem_free(data);
|
||||
}
|
||||
// if(mono) {
|
||||
// mono->xsize = font->xsize;
|
||||
// mono->ysize = font->ysize;
|
||||
// mono->xglyph = font->xglyph;
|
||||
// mono->yglyph = font->yglyph;
|
||||
// }
|
||||
return pages;
|
||||
}
|
||||
|
||||
/*
|
||||
int gfx_load_font_int(font_t *font, const byte **fdata, const byte **fsizes) {
|
||||
int pages = 0;
|
||||
byte *data = mem_alloc(12 * 16 * 18 * 16 * 4, MEM_IMAGE);
|
||||
font->xglyph = 12;
|
||||
font->yglyph = 18;
|
||||
font->xsize = 12 * 16;
|
||||
font->ysize = 18 * 16;
|
||||
for(int page = 0; page < UNI_MAX_PAGES; page++) {
|
||||
sprintf(sys.work_buf, "font_%04x", page);
|
||||
if(!fdata[page]) {
|
||||
font->textures[page] = 0;
|
||||
font->sizes[page] = NULL;
|
||||
continue;
|
||||
}
|
||||
pages += 1;
|
||||
font->sizes[page] = (fchar_t *)fsizes[page];
|
||||
tex_unpack_1bit(data, fdata[page], 12 * 16 * 18 * 16);
|
||||
tex_push(&font->textures[page], data, 12 * 16, 18 * 16);
|
||||
// mono->sizes[page] = mem_alloc(256 * sizeof(fchar_t), MEM_FONT);
|
||||
// memcpy(mono->sizes[page], fsizes[page], 256 * sizeof(fchar_t));
|
||||
// gfx_calc_mono(mono->sizes[page], font->xglyph, font->yglyph);
|
||||
// mono->textures[page] = font->textures[page];
|
||||
logd(LOG_GFX, STR_TEX_ILOADED, sys.work_buf, font->textures[page]);
|
||||
}
|
||||
mem_free(data);
|
||||
return pages;
|
||||
}
|
||||
*/
|
||||
|
||||
void gfx_free_font(font_t *font) {
|
||||
for(int page = 0; (page < UNI_MAX_PAGES) && font->xglyph; page++) {
|
||||
if(font->sizes[page]) {
|
||||
mem_free(font->sizes[page]);
|
||||
tex_delete(&font->textures[page]);
|
||||
}
|
||||
// if(mono && mono->sizes[page])
|
||||
// mem_free(mono->sizes[page]);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
void gfx_free_font_int(font_t *font) {
|
||||
for(int page = 0; page < UNI_MAX_PAGES; page++) {
|
||||
if(font->sizes[page])
|
||||
tex_delete(&font->textures[page]);
|
||||
// if(mono->sizes[page])
|
||||
// mem_free(mono->sizes[page]);
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
void gfx_aux_colors(const uint *colors) {
|
||||
memcpy(gdr.aux_colors, colors, sizeof(uint) * 8);
|
||||
}
|
||||
|
||||
void gfx_back_color(uint color) {
|
||||
gdr.clear_r = (float)((uint)((color >> 16) & 0xff)) / 255.0f;
|
||||
gdr.clear_g = (float)((uint)((color >> 8) & 0xff)) / 255.0f;
|
||||
gdr.clear_b = (float)((uint)(color & 0xff)) / 255.0f;
|
||||
gdr.clear_a = (float)((uint)((color >> 24) & 0xff)) / 255.0f;
|
||||
}
|
||||
|
||||
void shd_fnc_tex() {
|
||||
shd_int("tex", 0);
|
||||
}
|
||||
|
||||
void shd_fnc_world() {
|
||||
shd_int("tex", 0);
|
||||
glUniformBlockBinding(gdr.shader, glGetUniformBlockIndex(gdr.shader, "light_block"), 0);
|
||||
}
|
||||
|
||||
void gfx_view(camera_t *cam, mat4 mat, float x, float y, float z) {
|
||||
vec3 pos;
|
||||
vec3 center;
|
||||
VEC3_SET(pos, x, y, z);
|
||||
glm_vec3_add(pos, cam->front, center);
|
||||
glm_mat4_identity(mat);
|
||||
glm_lookat(pos, center, cam->up, mat);
|
||||
}
|
||||
|
||||
void gfx_perspective(camera_t *cam, mat4 mat) {
|
||||
glm_mat4_identity(mat);
|
||||
glm_perspective(glm_rad(gdr.fov - (cam->zoom * (gdr.fov - 1.0f))), ((float)wcf.current->frame_x) / ((float)wcf.current->frame_y), gdr.clip_near, gdr.clip_far, mat);
|
||||
}
|
||||
|
||||
void shd_pass_rect(void *u) {
|
||||
// shd_sel(gdr.shd_rect);
|
||||
shd_vec2v("screen", (float)wcf.current->fb_x, (float)wcf.current->fb_y);
|
||||
glBindVertexArray(gdr.vao_quad);
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
}
|
||||
|
||||
void shd_pass_text(void *u) {
|
||||
// shd_sel(gdr.shd_text);
|
||||
shd_vec2v("screen", (float)wcf.current->fb_x, (float)wcf.current->fb_y);
|
||||
shd_float("time", tmr_ftime());
|
||||
glBindVertexArray(gdr.vao_quad);
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
}
|
||||
|
||||
void shd_pass_blit(void *u) {
|
||||
// shd_sel(gdr.shd_blit);
|
||||
glBindVertexArray(gdr.vao_quad);
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
}
|
||||
|
||||
void shd_pass_world(world_t *world) {
|
||||
mat4 mat;
|
||||
// shd_sel(gdr.shd_world);
|
||||
shd_float("clip_near", gdr.clip_near);
|
||||
shd_float("clip_far", gdr.clip_far);
|
||||
shd_vec2v("screen", (float)wcf.current->frame_x, (float)wcf.current->frame_y);
|
||||
// shd_vec3v("world_size", (float)(TEMP_LM_SIZE * CHUNK_SIZE), (float)(TEMP_LM_SIZE * CHUNK_SIZE), (float)(TEMP_LM_SIZE * CHUNK_SIZE));
|
||||
shd_vec3v("cam_pos", world->camera.pos_x, world->camera.pos_y, world->camera.pos_z);
|
||||
gfx_view(&world->camera, mat, world->camera.pos_x, world->camera.pos_y, world->camera.pos_z);
|
||||
shd_mat4("view", mat);
|
||||
gfx_perspective(&world->camera, mat);
|
||||
shd_mat4("projection", mat);
|
||||
/*
|
||||
glm_mat4_identity(mat);
|
||||
vec3 v;
|
||||
VEC3_SET(v, 100.0f, 0.5f, 100.0f);
|
||||
glm_scale(mat, v);
|
||||
VEC3_SET(v, 0.0f, -1.0f, 0.0f);
|
||||
glm_translate(mat, v);
|
||||
shd_mat4("model", mat);
|
||||
shd_scolor("specular", 0xffffff);
|
||||
shd_float("shine", 4.0f);
|
||||
*/
|
||||
shd_vec3v("dir_direction", gdr.ambient_x, gdr.ambient_y, gdr.ambient_z);
|
||||
// shd_vec3v("dir_ambient", 0.1f, 0.1f, 0.2f);
|
||||
shd_vec3v("dir_ambient", gdr.clear_r, gdr.clear_g, gdr.clear_b);
|
||||
shd_vec3v("dir_diffuse", gdr.clear_r * 1.25f, gdr.clear_g * 1.25f, gdr.clear_b * 1.25f);
|
||||
shd_vec3v("dir_specular", gdr.clear_r * 1.5f, gdr.clear_g * 1.5f, gdr.clear_b * 1.5f);
|
||||
shd_float("light_factor", gdr.light_blend);
|
||||
shd_float("max_vert_dist", gdr.light_dist_vert);
|
||||
shd_float("max_cam_dist", gdr.light_dist_cam);
|
||||
// shd_float("time", tmr_ftime());
|
||||
// glBindVertexArray(gdr.vao_box);
|
||||
// glActiveTexture(GL_TEXTURE1);
|
||||
// glBindTexture(GL_TEXTURE_2D, gdr.fbtex_lightmap);
|
||||
shd_int("n_lights", world->s_lights);
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
|
||||
glBindBufferBase(GL_UNIFORM_BUFFER, 0, world->light_buf);
|
||||
}
|
||||
|
||||
void shd_pass_vis(world_t *world) {
|
||||
mat4 mat;
|
||||
gfx_view(&world->camera, mat, world->camera.pos_x, world->camera.pos_y, world->camera.pos_z);
|
||||
shd_mat4("view", mat);
|
||||
gfx_perspective(&world->camera, mat);
|
||||
shd_mat4("projection", mat);
|
||||
}
|
||||
|
||||
void shd_pass_grid(world_t *world) {
|
||||
mat4 mat;
|
||||
// shd_sel(gdr.shd_vis);
|
||||
shd_float("clip_near", gdr.clip_near);
|
||||
shd_float("clip_far", gdr.clip_far);
|
||||
shd_vec2v("screen", (float)wcf.current->frame_x, (float)wcf.current->frame_y);
|
||||
gfx_view(&world->camera, mat, world->camera.pos_x, world->camera.pos_y, world->camera.pos_z);
|
||||
shd_mat4("view", mat);
|
||||
gfx_perspective(&world->camera, mat);
|
||||
shd_mat4("projection", mat);
|
||||
shd_float("time", tmr_ftime());
|
||||
// glActiveTexture(GL_TEXTURE0);
|
||||
}
|
||||
|
||||
byte gfx_init() {
|
||||
gdr.aniso_max = 1.0f;
|
||||
// if(gdr.aniso_avail = (GL_API_4_6 || gl_has_ext("GL_EXT_texture_filter_anisotropic") || gl_has_ext("GL_ARB_texture_filter_anisotropic")))
|
||||
glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY, &gdr.aniso_max);
|
||||
tbl_init(&gdr.textures, 256, 64, sizeof(tex_t), MEM_DRAW);
|
||||
tbl_init(&gdr.buffers, 1024, 16, sizeof(buf_t), MEM_DRAW);
|
||||
tbl_init(&gdr.shaders, 1, 16, sizeof(shd_t), MEM_DRAW);
|
||||
tbl_init(&gdr.framebufs, 1, 16, sizeof(fbo_t), MEM_DRAW);
|
||||
tbl_init(&gdr.drawlists, 1, 16384, sizeof(drawlist_t), MEM_DRAW);
|
||||
tbl_init(&gdr.materials, 16, 32, sizeof(material_t), MEM_DRAW);
|
||||
shd_setvars();
|
||||
LOAD_SHADER(text, shd_fnc_tex, shd_pass_text);
|
||||
LOAD_SHADER(rect, shd_fnc_tex, shd_pass_rect);
|
||||
LOAD_SHADER(blit, shd_fnc_tex, shd_pass_blit);
|
||||
LOAD_SHADER(world, shd_fnc_world, shd_pass_world);
|
||||
// LOAD_SHADER(lightmap, NULL, NULL);
|
||||
LOAD_SHADER(vis, NULL, shd_pass_vis);
|
||||
LOAD_SHADER(grid, NULL, shd_pass_grid);
|
||||
sys.font_pages = gfx_load_font(&sys.font, "font");
|
||||
buf_init_sys(&gdr.vbo_quad, &gdr.vao_quad, vert_quad, sizeof(vert_quad), 2, 2);
|
||||
if(!fb_init_sys(&sys.console->fb_gui, &sys.console->fbtex_gui))
|
||||
return 0;
|
||||
tex_gen_fallback(&gdr.tex_fallback, 8);
|
||||
gfx_aux_colors(aux_colors);
|
||||
// gfx_back_color(0x000000);
|
||||
// gfx_back_color(0xff20208f);
|
||||
gfx_back_color(0xff000000);
|
||||
// gui_style_default(&sys.style);
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
// gdr.buf_lightmap = buf_init(1, &gdr.vbo_lightmap, &gdr.vao_lightmap, NULL, 0, 2, 2);
|
||||
// gdr.fbt_lightmap = fb_init(&gdr.fb_lightmap, &gdr.fbtex_lightmap, NULL, 0, 1);
|
||||
// gfx_init_world();
|
||||
return 1;
|
||||
}
|
||||
|
||||
void gfx_end() {
|
||||
tex_clear();
|
||||
buf_clear();
|
||||
shd_clear();
|
||||
fb_clear();
|
||||
gfx_free_font(&sys.font);
|
||||
tex_delete(&gdr.tex_fallback);
|
||||
buf_delete(&gdr.vbo_quad, &gdr.vao_quad);
|
||||
// shd_delete(&gdr.shd_rect);
|
||||
// shd_delete(&gdr.shd_text);
|
||||
// shd_delete(&gdr.shd_blit);
|
||||
// shd_clearall();
|
||||
// fb_delete(&sys.console->fb_gui, &sys.console->fbtex_gui);
|
||||
tbl_clear(&gdr.textures);
|
||||
tbl_clear(&gdr.buffers);
|
||||
tbl_clear(&gdr.shaders);
|
||||
tbl_clear(&gdr.framebufs);
|
||||
tbl_clear(&gdr.drawlists);
|
||||
tbl_clear(&gdr.materials);
|
||||
}
|
||||
|
||||
void gfx_blit(uint tex) {
|
||||
shd_sel(gdr.shd_blit, NULL);
|
||||
glBindTexture(GL_TEXTURE_2D, tex);
|
||||
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
||||
}
|
||||
|
||||
void gfx_draw_rect(int x, int y, int w, int h, int border, uint tex, uint top, uint bottom, uint b_top, uint b_bottom) {
|
||||
shd_sel(gdr.shd_rect, NULL);
|
||||
shd_vec2v("offset", (float)x, (float)y);
|
||||
shd_vec2v("size", (float)w, (float)h);
|
||||
shd_bool("use_tex", tex ? 1 : 0);
|
||||
shd_float("border", (float)border);
|
||||
shd_color("fill_t", top);
|
||||
shd_color("fill_b", bottom);
|
||||
shd_color("border_t", b_top);
|
||||
shd_color("border_b", b_bottom);
|
||||
if(tex) {
|
||||
glBindTexture(GL_TEXTURE_2D, tex);
|
||||
}
|
||||
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
||||
}
|
||||
|
||||
void gfx_draw_gui(window_t *win) {
|
||||
int x1, y1, x2, y2;
|
||||
gui_t *elem = win->selected;
|
||||
if(elem && elem->r_dirty && elem->type == GUI_DROPDOWN_HANDLE && !(elem->visible)) {
|
||||
glScissor(elem->pos_x, (win->fb_y - (elem->pos_y + elem->size_y)) < 0 ? 0 : (win->fb_y - (elem->pos_y + elem->size_y)), elem->size_x, elem->size_y);
|
||||
glEnable(GL_SCISSOR_TEST);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
glDisable(GL_SCISSOR_TEST);
|
||||
elem->r_dirty = elem->t_dirty = 0;
|
||||
win->selected = NULL;
|
||||
for(int z = 0; z < win->n_elems; z++) {
|
||||
if((win->elems[z].pos_y + win->elems[z].size_y) > elem->pos_y && win->elems[z].pos_y < (elem->pos_y + elem->size_y) &&
|
||||
(win->elems[z].pos_x + win->elems[z].size_x) > elem->pos_x && win->elems[z].pos_x < (elem->pos_x + elem->size_x) && win->elems[z].visible)
|
||||
win->elems[z].r_dirty = 1;
|
||||
}
|
||||
}
|
||||
for(int z = 0; z < win->n_elems; z++) {
|
||||
elem = &win->elems[z];
|
||||
if(elem->r_dirty || elem->t_dirty) {
|
||||
if(win->selected == elem && elem->type == GUI_DROPDOWN_HANDLE && elem->visible)
|
||||
continue;
|
||||
glScissor(elem->pos_x, (win->fb_y - (elem->pos_y + elem->size_y)) < 0 ? 0 : (win->fb_y - (elem->pos_y + elem->size_y)), elem->size_x, elem->size_y);
|
||||
// logd("DBG", "%d @ %d %d -> %d %d", elem->id, elem->pos_x, elem->pos_y, elem->pos_x + elem->size_x, elem->pos_y + elem->size_y);
|
||||
glEnable(GL_SCISSOR_TEST);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
if(elem->type == GUI_CUSTOM)
|
||||
elem->func(elem, 0);
|
||||
glDisable(GL_SCISSOR_TEST);
|
||||
if(elem->visible && (elem->type != GUI_CUSTOM))
|
||||
gfx_draw_rect(elem->pos_x, elem->pos_y, elem->size_x, elem->size_y, elem->border, elem->texture, elem->color_fill_t, elem->color_fill_b, elem->color_brdr_t, elem->color_brdr_b);
|
||||
if(elem->visible && (elem->type == GUI_SLIDER))
|
||||
gfx_draw_rect(elem->pos_x + elem->sel_start - (elem->sel_end / 2), elem->pos_y, elem->sel_end, elem->size_y, elem->sel_drag, elem->texture, elem->margin_x1, elem->margin_y1, elem->margin_x2, elem->margin_y2);
|
||||
elem->r_dirty = 0;
|
||||
elem->t_dirty = elem->visible;
|
||||
// logd("DBG", "@ r");
|
||||
}
|
||||
}
|
||||
// gfx_pass_text();
|
||||
for(int z = 0; z < win->n_elems; z++) {
|
||||
elem = &win->elems[z];
|
||||
if(elem->t_dirty && elem->visible) {
|
||||
if(win->selected == elem && elem->type == GUI_DROPDOWN_HANDLE)
|
||||
continue;
|
||||
x1 = elem->pos_x + ((elem->type != GUI_SLIDER) ? elem->margin_x1 : 0);
|
||||
y1 = elem->pos_y + ((elem->type != GUI_SLIDER) ? elem->margin_y1 : 0);
|
||||
x2 = elem->size_x - ((elem->type != GUI_SLIDER) ? (elem->margin_x1 + elem->margin_x2) : 0);
|
||||
y2 = elem->size_y - ((elem->type != GUI_SLIDER) ? (elem->margin_y1 + elem->margin_y2) : 0);
|
||||
// if(elem->type == GUI_FIELD) {
|
||||
glScissor(x1 < 0 ? 0 : x1, (win->fb_y - (y1 + y2)) < 0 ? 0 : (win->fb_y - (y1 + y2)), x2 < 0 ? 0 : x2, y2 < 0 ? 0 : y2);
|
||||
glEnable(GL_SCISSOR_TEST);
|
||||
// }
|
||||
if(elem->type == GUI_CUSTOM)
|
||||
elem->func(elem, 1);
|
||||
else
|
||||
elem->t_dirty = txt_draw(x1 + (elem->xbreak ? 0 : elem->text_x), y1 + elem->text_y,
|
||||
0, elem->font_size * elem->font->yglyph,
|
||||
elem->font_size * (elem->font->yglyph + elem->line_space), x1 + elem->text_x, y1 + elem->text_y,
|
||||
elem->xbreak ? (elem->pos_x + x2) : 0x7fffffff, 0x7fffffff, elem->color_text, 0x00000000, elem->font, elem->text);
|
||||
if(elem->type == GUI_FIELD && elem->sel_start >= 0 && elem->sel_end != elem->sel_start)
|
||||
txt_draw_range(elem->sel_start, elem->sel_end, x1 + (elem->xbreak ? 0 : elem->text_x), y1 + elem->text_y, 0, elem->font_size * elem->font->yglyph,
|
||||
elem->font_size * elem->font->yglyph, x1 + elem->text_x, y1 + elem->text_y,
|
||||
elem->xbreak ? (elem->pos_x + x2) : 0x7fffffff, 0x7fffffff, 0x00000000, sys.style.select, elem->font, elem->text);
|
||||
// logd("DBG", "%d @ %d %d -> %d %d", elem->id, x1, y1, elem->pos_x + x2, elem->pos_y + y2);
|
||||
// if(elem->type == GUI_FIELD) {
|
||||
glDisable(GL_SCISSOR_TEST);
|
||||
// glScissor(0, 0, sys.fb_x, sys.fb_y);
|
||||
// }
|
||||
}
|
||||
}
|
||||
elem = win->selected;
|
||||
if(elem && (elem->r_dirty || elem->t_dirty) && elem->type == GUI_DROPDOWN_HANDLE && elem->visible) {
|
||||
// gfx_pass_rect();
|
||||
glScissor(elem->pos_x, (win->fb_y - (elem->pos_y + elem->size_y)) < 0 ? 0 : (win->fb_y - (elem->pos_y + elem->size_y)), elem->size_x, elem->size_y);
|
||||
glEnable(GL_SCISSOR_TEST);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
glDisable(GL_SCISSOR_TEST);
|
||||
gfx_draw_rect(elem->pos_x, elem->pos_y, elem->size_x, elem->size_y, elem->border, elem->texture, elem->color_fill_t, elem->color_fill_b, elem->color_brdr_t, elem->color_brdr_b);
|
||||
elem->r_dirty = 0;
|
||||
// gfx_pass_text();
|
||||
x1 = elem->pos_x + elem->margin_x1;
|
||||
y1 = elem->pos_y + elem->margin_y1;
|
||||
x2 = elem->size_x - (elem->margin_x1 + elem->margin_x2);
|
||||
y2 = elem->size_y - (elem->margin_y1 + elem->margin_y2);
|
||||
glScissor(x1 < 0 ? 0 : x1, (win->fb_y - (y1 + y2)) < 0 ? 0 : (win->fb_y - (y1 + y2)), x2 < 0 ? 0 : x2, y2 < 0 ? 0 : y2);
|
||||
glEnable(GL_SCISSOR_TEST);
|
||||
elem->t_dirty = txt_draw(x1 + elem->text_x, y1 + elem->text_y,
|
||||
0, elem->font_size * elem->font->yglyph,
|
||||
elem->font_size * (elem->font->yglyph + elem->line_space), x1 + elem->text_x, y1 + elem->text_y,
|
||||
0x7fffffff, 0x7fffffff, elem->color_text, 0x00000000, elem->font, elem->text);
|
||||
glDisable(GL_SCISSOR_TEST);
|
||||
}
|
||||
}
|
||||
|
||||
byte gui_inside(gui_t *elem, int x, int y);
|
||||
gui_t *gui_clicked(window_t *win, int x, int y);
|
||||
|
||||
void gfx_draw_gui_overlay(window_t *win) {
|
||||
gui_t *elem;
|
||||
if(win->open) {
|
||||
elem = win->selected;
|
||||
if(win->mouse && elem && elem->enabled && elem->visible && (elem->type != GUI_LABEL) && (elem->type != GUI_FIELD) && (elem->type != GUI_DROPDOWN_HANDLE) && (elem->type != GUI_CUSTOM)) {
|
||||
gfx_draw_rect(elem->pos_x, elem->pos_y, elem->size_x, elem->size_y, 0, 0, sys.style.press_top, sys.style.press_btm, 0x00000000, 0x00000000);
|
||||
return;
|
||||
}
|
||||
else if(elem && elem->enabled && elem->visible && (elem->type == GUI_FIELD)) {
|
||||
if(elem->value && elem->sel_start >= 0 && elem->sel_end == elem->sel_start && fmodf(tmr_ftime(), 1.0f) < 0.5f) {
|
||||
int x1 = elem->pos_x + elem->margin_x1;
|
||||
int y1 = elem->pos_y + elem->margin_y1;
|
||||
int x2 = elem->size_x - (elem->margin_x1 + elem->margin_x2);
|
||||
int y2 = elem->size_y - (elem->margin_y1 + elem->margin_y2);
|
||||
glScissor(x1 < 0 ? 0 : x1, (win->fb_y - (y1 + y2)) < 0 ? 0 : (win->fb_y - (y1 + y2)), x2 < 0 ? 0 : x2, y2 < 0 ? 0 : y2);
|
||||
glEnable(GL_SCISSOR_TEST);
|
||||
gfx_draw_rect(elem->min, elem->max, elem->font_size, elem->font->yglyph * elem->font_size, 0, 0, sys.style.cursor, sys.style.cursor, 0x00000000, 0x00000000);
|
||||
glDisable(GL_SCISSOR_TEST);
|
||||
}
|
||||
}
|
||||
elem = gui_clicked(win, win->mouse_x, win->mouse_y);
|
||||
if(elem && elem->enabled && elem->visible && (elem->type != GUI_LABEL) && /* ( */ (elem->type != GUI_FIELD) && (elem->type != GUI_CUSTOM) /* || (elem != gui.selected)) */ ) {
|
||||
if(elem->type == GUI_DROPDOWN_HANDLE) {
|
||||
int m = ((win->mouse_y - (elem->pos_y + elem->margin_y1)) * elem->max / (elem->size_y - (elem->margin_y1 + elem->margin_y2)));
|
||||
// if((sys.mouse_y - elem->pos_y) < (elem->size_y - elem->margin_y2))
|
||||
gfx_draw_rect(elem->pos_x + elem->margin_x1, elem->pos_y + elem->margin_y1 + CLAMP_VALUE(m, 0, elem->max - 1) * ((elem->size_y - (elem->margin_y1 + elem->margin_y2)) / elem->max),
|
||||
elem->size_x - (elem->margin_x1 + elem->margin_x2),
|
||||
(elem->size_y - (elem->margin_y1 + elem->margin_y2)) / elem->max, 0, 0, sys.style.hover_top, sys.style.hover_btm, 0x00000000, 0x00000000);
|
||||
}
|
||||
else {
|
||||
gfx_draw_rect(elem->pos_x, elem->pos_y, elem->size_x, elem->size_y, 0, 0, sys.style.hover_top, sys.style.hover_btm, 0x00000000, 0x00000000);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void gfx_draw_con_overlay(window_t *win) {
|
||||
if(sys.hud_size) {
|
||||
conmsg_t *con;
|
||||
ulong fade = 1000ULL * (ulong)(sys.hud_fadeout);
|
||||
font_t *font = &sys.font;
|
||||
int y = sys.hud_bottom ? (win->frame_y - font->yglyph) : 0;
|
||||
int pos = sys.hud_pos;
|
||||
for(int z = 0; z < sys.hud_size; z++) {
|
||||
if(--pos < 0)
|
||||
pos = sys.hud_size - 1;
|
||||
con = &sys.hud_msgs[pos];
|
||||
if(con->message && (con->window == win)) {
|
||||
if((sys.tmr_current - con->time) <= fade) {
|
||||
txt_draw_range(0, con->length, win->offset_x, win->offset_y + y, 0, font->yglyph, font->yglyph,
|
||||
win->offset_x, win->offset_y + y,
|
||||
win->offset_x + win->frame_x, win->offset_y + win->frame_y,
|
||||
0xffffffff, (uint)sys.hud_opacity << 24, font, con->message);
|
||||
y += sys.hud_bottom ? -(font->yglyph) : font->yglyph;
|
||||
}
|
||||
else {
|
||||
con->message = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
material_t *gfx_add_material(uint texture, float density, uint spec_color, float shine, shd_t *shader) {
|
||||
material_t *mat = tbl_push(&gdr.materials);
|
||||
mat->texture = texture;
|
||||
mat->density = density;
|
||||
mat->spec_color = spec_color;
|
||||
mat->shine = shine;
|
||||
mat->shader = shader;
|
||||
return mat;
|
||||
}
|
||||
|
||||
void gfx_clear_materials() {
|
||||
tbl_clear(&gdr.materials);
|
||||
}
|
BIN
screenshots/screen_01-10-2023_14-24-33.png
Normal file
After Width: | Height: | Size: 35 KiB |
BIN
screenshots/screen_01-10-2023_14-58-06.png
Normal file
After Width: | Height: | Size: 38 KiB |
BIN
screenshots/screen_01-10-2023_14-58-08.png
Normal file
After Width: | Height: | Size: 38 KiB |
BIN
screenshots/screen_01-10-2023_14-58-09.png
Normal file
After Width: | Height: | Size: 38 KiB |
BIN
screenshots/screen_01-10-2023_14-58-14.png
Normal file
After Width: | Height: | Size: 76 KiB |
BIN
screenshots/screen_01-10-2023_14-58-15.png
Normal file
After Width: | Height: | Size: 76 KiB |
BIN
screenshots/screen_01-10-2023_14-58-17.png
Normal file
After Width: | Height: | Size: 76 KiB |
BIN
screenshots/screen_01-10-2023_14-58-18.png
Normal file
After Width: | Height: | Size: 76 KiB |
BIN
screenshots/screen_01-10-2023_14-58-21.png
Normal file
After Width: | Height: | Size: 76 KiB |
BIN
screenshots/screen_02-09-2024_08-36-24.png
Normal file
After Width: | Height: | Size: 2.4 MiB |