moving forward
This commit is contained in:
parent
cb6c5ac0c6
commit
9832374861
@ -2,6 +2,7 @@
|
||||
# define ENGINE_H
|
||||
|
||||
#include <struct.h>
|
||||
#include <render.h>
|
||||
|
||||
# ifndef ENGINE_PROTOTYPE
|
||||
# define ENGINE_PROTOTYPE
|
||||
|
||||
12536
include/extern/external/dr_flac.h
vendored
Normal file
12536
include/extern/external/dr_flac.h
vendored
Normal file
File diff suppressed because it is too large
Load Diff
4834
include/extern/external/dr_mp3.h
vendored
Normal file
4834
include/extern/external/dr_mp3.h
vendored
Normal file
File diff suppressed because it is too large
Load Diff
8803
include/extern/external/dr_wav.h
vendored
Normal file
8803
include/extern/external/dr_wav.h
vendored
Normal file
File diff suppressed because it is too large
Load Diff
1596
include/extern/external/jar_mod.h
vendored
Normal file
1596
include/extern/external/jar_mod.h
vendored
Normal file
File diff suppressed because it is too large
Load Diff
2471
include/extern/external/jar_xm.h
vendored
Normal file
2471
include/extern/external/jar_xm.h
vendored
Normal file
File diff suppressed because it is too large
Load Diff
92621
include/extern/external/miniaudio.h
vendored
Normal file
92621
include/extern/external/miniaudio.h
vendored
Normal file
File diff suppressed because it is too large
Load Diff
728
include/extern/external/qoa.h
vendored
Normal file
728
include/extern/external/qoa.h
vendored
Normal file
@ -0,0 +1,728 @@
|
||||
/*
|
||||
|
||||
Copyright (c) 2023, Dominic Szablewski - https://phoboslab.org
|
||||
SPDX-License-Identifier: MIT
|
||||
|
||||
QOA - The "Quite OK Audio" format for fast, lossy audio compression
|
||||
|
||||
|
||||
-- Data Format
|
||||
|
||||
QOA encodes pulse-code modulated (PCM) audio data with up to 255 channels,
|
||||
sample rates from 1 up to 16777215 hertz and a bit depth of 16 bits.
|
||||
|
||||
The compression method employed in QOA is lossy; it discards some information
|
||||
from the uncompressed PCM data. For many types of audio signals this compression
|
||||
is "transparent", i.e. the difference from the original file is often not
|
||||
audible.
|
||||
|
||||
QOA encodes 20 samples of 16 bit PCM data into slices of 64 bits. A single
|
||||
sample therefore requires 3.2 bits of storage space, resulting in a 5x
|
||||
compression (16 / 3.2).
|
||||
|
||||
A QOA file consists of an 8 byte file header, followed by a number of frames.
|
||||
Each frame contains an 8 byte frame header, the current 16 byte en-/decoder
|
||||
state per channel and 256 slices per channel. Each slice is 8 bytes wide and
|
||||
encodes 20 samples of audio data.
|
||||
|
||||
All values, including the slices, are big endian. The file layout is as follows:
|
||||
|
||||
struct {
|
||||
struct {
|
||||
char magic[4]; // magic bytes "qoaf"
|
||||
uint32_t samples; // samples per channel in this file
|
||||
} file_header;
|
||||
|
||||
struct {
|
||||
struct {
|
||||
uint8_t num_channels; // no. of channels
|
||||
uint24_t samplerate; // samplerate in hz
|
||||
uint16_t fsamples; // samples per channel in this frame
|
||||
uint16_t fsize; // frame size (includes this header)
|
||||
} frame_header;
|
||||
|
||||
struct {
|
||||
int16_t history[4]; // most recent last
|
||||
int16_t weights[4]; // most recent last
|
||||
} lms_state[num_channels];
|
||||
|
||||
qoa_slice_t slices[256][num_channels];
|
||||
|
||||
} frames[ceil(samples / (256 * 20))];
|
||||
} qoa_file_t;
|
||||
|
||||
Each `qoa_slice_t` contains a quantized scalefactor `sf_quant` and 20 quantized
|
||||
residuals `qrNN`:
|
||||
|
||||
.- QOA_SLICE -- 64 bits, 20 samples --------------------------/ /------------.
|
||||
| Byte[0] | Byte[1] | Byte[2] \ \ Byte[7] |
|
||||
| 7 6 5 4 3 2 1 0 | 7 6 5 4 3 2 1 0 | 7 6 5 / / 2 1 0 |
|
||||
|------------+--------+--------+--------+---------+---------+-\ \--+---------|
|
||||
| sf_quant | qr00 | qr01 | qr02 | qr03 | qr04 | / / | qr19 |
|
||||
`-------------------------------------------------------------\ \------------`
|
||||
|
||||
Each frame except the last must contain exactly 256 slices per channel. The last
|
||||
frame may contain between 1 .. 256 (inclusive) slices per channel. The last
|
||||
slice (for each channel) in the last frame may contain less than 20 samples; the
|
||||
slice still must be 8 bytes wide, with the unused samples zeroed out.
|
||||
|
||||
Channels are interleaved per slice. E.g. for 2 channel stereo:
|
||||
slice[0] = L, slice[1] = R, slice[2] = L, slice[3] = R ...
|
||||
|
||||
A valid QOA file or stream must have at least one frame. Each frame must contain
|
||||
at least one channel and one sample with a samplerate between 1 .. 16777215
|
||||
(inclusive).
|
||||
|
||||
If the total number of samples is not known by the encoder, the samples in the
|
||||
file header may be set to 0x00000000 to indicate that the encoder is
|
||||
"streaming". In a streaming context, the samplerate and number of channels may
|
||||
differ from frame to frame. For static files (those with samples set to a
|
||||
non-zero value), each frame must have the same number of channels and same
|
||||
samplerate.
|
||||
|
||||
Note that this implementation of QOA only handles files with a known total
|
||||
number of samples.
|
||||
|
||||
A decoder should support at least 8 channels. The channel layout for channel
|
||||
counts 1 .. 8 is:
|
||||
|
||||
1. Mono
|
||||
2. L, R
|
||||
3. L, R, C
|
||||
4. FL, FR, B/SL, B/SR
|
||||
5. FL, FR, C, B/SL, B/SR
|
||||
6. FL, FR, C, LFE, B/SL, B/SR
|
||||
7. FL, FR, C, LFE, B, SL, SR
|
||||
8. FL, FR, C, LFE, BL, BR, SL, SR
|
||||
|
||||
QOA predicts each audio sample based on the previously decoded ones using a
|
||||
"Sign-Sign Least Mean Squares Filter" (LMS). This prediction plus the
|
||||
dequantized residual forms the final output sample.
|
||||
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
Header - Public functions */
|
||||
|
||||
#ifndef QOA_H
|
||||
#define QOA_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define QOA_MIN_FILESIZE 16
|
||||
#define QOA_MAX_CHANNELS 8
|
||||
|
||||
#define QOA_SLICE_LEN 20
|
||||
#define QOA_SLICES_PER_FRAME 256
|
||||
#define QOA_FRAME_LEN (QOA_SLICES_PER_FRAME * QOA_SLICE_LEN)
|
||||
#define QOA_LMS_LEN 4
|
||||
#define QOA_MAGIC 0x716f6166 /* 'qoaf' */
|
||||
|
||||
#define QOA_FRAME_SIZE(channels, slices) \
|
||||
(8 + QOA_LMS_LEN * 4 * channels + 8 * slices * channels)
|
||||
|
||||
typedef struct {
|
||||
int history[QOA_LMS_LEN];
|
||||
int weights[QOA_LMS_LEN];
|
||||
} qoa_lms_t;
|
||||
|
||||
typedef struct {
|
||||
unsigned int channels;
|
||||
unsigned int samplerate;
|
||||
unsigned int samples;
|
||||
qoa_lms_t lms[QOA_MAX_CHANNELS];
|
||||
#ifdef QOA_RECORD_TOTAL_ERROR
|
||||
double error;
|
||||
#endif
|
||||
} qoa_desc;
|
||||
|
||||
unsigned int qoa_encode_header(qoa_desc *qoa, unsigned char *bytes);
|
||||
unsigned int qoa_encode_frame(const short *sample_data, qoa_desc *qoa, unsigned int frame_len, unsigned char *bytes);
|
||||
void *qoa_encode(const short *sample_data, qoa_desc *qoa, unsigned int *out_len);
|
||||
|
||||
unsigned int qoa_max_frame_size(qoa_desc *qoa);
|
||||
unsigned int qoa_decode_header(const unsigned char *bytes, int size, qoa_desc *qoa);
|
||||
unsigned int qoa_decode_frame(const unsigned char *bytes, unsigned int size, qoa_desc *qoa, short *sample_data, unsigned int *frame_len);
|
||||
short *qoa_decode(const unsigned char *bytes, int size, qoa_desc *file);
|
||||
|
||||
#ifndef QOA_NO_STDIO
|
||||
|
||||
int qoa_write(const char *filename, const short *sample_data, qoa_desc *qoa);
|
||||
void *qoa_read(const char *filename, qoa_desc *qoa);
|
||||
|
||||
#endif /* QOA_NO_STDIO */
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* QOA_H */
|
||||
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
Implementation */
|
||||
|
||||
#ifdef QOA_IMPLEMENTATION
|
||||
#include <stdlib.h>
|
||||
|
||||
#ifndef QOA_MALLOC
|
||||
#define QOA_MALLOC(sz) malloc(sz)
|
||||
#define QOA_FREE(p) free(p)
|
||||
#endif
|
||||
|
||||
typedef unsigned long long qoa_uint64_t;
|
||||
|
||||
|
||||
/* The quant_tab provides an index into the dequant_tab for residuals in the
|
||||
range of -8 .. 8. It maps this range to just 3bits and becomes less accurate at
|
||||
the higher end. Note that the residual zero is identical to the lowest positive
|
||||
value. This is mostly fine, since the qoa_div() function always rounds away
|
||||
from zero. */
|
||||
|
||||
static const int qoa_quant_tab[17] = {
|
||||
7, 7, 7, 5, 5, 3, 3, 1, /* -8..-1 */
|
||||
0, /* 0 */
|
||||
0, 2, 2, 4, 4, 6, 6, 6 /* 1.. 8 */
|
||||
};
|
||||
|
||||
|
||||
/* We have 16 different scalefactors. Like the quantized residuals these become
|
||||
less accurate at the higher end. In theory, the highest scalefactor that we
|
||||
would need to encode the highest 16bit residual is (2**16)/8 = 8192. However we
|
||||
rely on the LMS filter to predict samples accurately enough that a maximum
|
||||
residual of one quarter of the 16 bit range is sufficient. I.e. with the
|
||||
scalefactor 2048 times the quant range of 8 we can encode residuals up to 2**14.
|
||||
|
||||
The scalefactor values are computed as:
|
||||
scalefactor_tab[s] <- round(pow(s + 1, 2.75)) */
|
||||
|
||||
static const int qoa_scalefactor_tab[16] = {
|
||||
1, 7, 21, 45, 84, 138, 211, 304, 421, 562, 731, 928, 1157, 1419, 1715, 2048
|
||||
};
|
||||
|
||||
|
||||
/* The reciprocal_tab maps each of the 16 scalefactors to their rounded
|
||||
reciprocals 1/scalefactor. This allows us to calculate the scaled residuals in
|
||||
the encoder with just one multiplication instead of an expensive division. We
|
||||
do this in .16 fixed point with integers, instead of floats.
|
||||
|
||||
The reciprocal_tab is computed as:
|
||||
reciprocal_tab[s] <- ((1<<16) + scalefactor_tab[s] - 1) / scalefactor_tab[s] */
|
||||
|
||||
static const int qoa_reciprocal_tab[16] = {
|
||||
65536, 9363, 3121, 1457, 781, 475, 311, 216, 156, 117, 90, 71, 57, 47, 39, 32
|
||||
};
|
||||
|
||||
|
||||
/* The dequant_tab maps each of the scalefactors and quantized residuals to
|
||||
their unscaled & dequantized version.
|
||||
|
||||
Since qoa_div rounds away from the zero, the smallest entries are mapped to 3/4
|
||||
instead of 1. The dequant_tab assumes the following dequantized values for each
|
||||
of the quant_tab indices and is computed as:
|
||||
float dqt[8] = {0.75, -0.75, 2.5, -2.5, 4.5, -4.5, 7, -7};
|
||||
dequant_tab[s][q] <- round_ties_away_from_zero(scalefactor_tab[s] * dqt[q])
|
||||
|
||||
The rounding employed here is "to nearest, ties away from zero", i.e. positive
|
||||
and negative values are treated symmetrically.
|
||||
*/
|
||||
|
||||
static const int qoa_dequant_tab[16][8] = {
|
||||
{ 1, -1, 3, -3, 5, -5, 7, -7},
|
||||
{ 5, -5, 18, -18, 32, -32, 49, -49},
|
||||
{ 16, -16, 53, -53, 95, -95, 147, -147},
|
||||
{ 34, -34, 113, -113, 203, -203, 315, -315},
|
||||
{ 63, -63, 210, -210, 378, -378, 588, -588},
|
||||
{ 104, -104, 345, -345, 621, -621, 966, -966},
|
||||
{ 158, -158, 528, -528, 950, -950, 1477, -1477},
|
||||
{ 228, -228, 760, -760, 1368, -1368, 2128, -2128},
|
||||
{ 316, -316, 1053, -1053, 1895, -1895, 2947, -2947},
|
||||
{ 422, -422, 1405, -1405, 2529, -2529, 3934, -3934},
|
||||
{ 548, -548, 1828, -1828, 3290, -3290, 5117, -5117},
|
||||
{ 696, -696, 2320, -2320, 4176, -4176, 6496, -6496},
|
||||
{ 868, -868, 2893, -2893, 5207, -5207, 8099, -8099},
|
||||
{1064, -1064, 3548, -3548, 6386, -6386, 9933, -9933},
|
||||
{1286, -1286, 4288, -4288, 7718, -7718, 12005, -12005},
|
||||
{1536, -1536, 5120, -5120, 9216, -9216, 14336, -14336},
|
||||
};
|
||||
|
||||
|
||||
/* The Least Mean Squares Filter is the heart of QOA. It predicts the next
|
||||
sample based on the previous 4 reconstructed samples. It does so by continuously
|
||||
adjusting 4 weights based on the residual of the previous prediction.
|
||||
|
||||
The next sample is predicted as the sum of (weight[i] * history[i]).
|
||||
|
||||
The adjustment of the weights is done with a "Sign-Sign-LMS" that adds or
|
||||
subtracts the residual to each weight, based on the corresponding sample from
|
||||
the history. This, surprisingly, is sufficient to get worthwhile predictions.
|
||||
|
||||
This is all done with fixed point integers. Hence the right-shifts when updating
|
||||
the weights and calculating the prediction. */
|
||||
|
||||
static int qoa_lms_predict(qoa_lms_t *lms) {
|
||||
int prediction = 0;
|
||||
for (int i = 0; i < QOA_LMS_LEN; i++) {
|
||||
prediction += lms->weights[i] * lms->history[i];
|
||||
}
|
||||
return prediction >> 13;
|
||||
}
|
||||
|
||||
static void qoa_lms_update(qoa_lms_t *lms, int sample, int residual) {
|
||||
int delta = residual >> 4;
|
||||
for (int i = 0; i < QOA_LMS_LEN; i++) {
|
||||
lms->weights[i] += lms->history[i] < 0 ? -delta : delta;
|
||||
}
|
||||
|
||||
for (int i = 0; i < QOA_LMS_LEN-1; i++) {
|
||||
lms->history[i] = lms->history[i+1];
|
||||
}
|
||||
lms->history[QOA_LMS_LEN-1] = sample;
|
||||
}
|
||||
|
||||
|
||||
/* qoa_div() implements a rounding division, but avoids rounding to zero for
|
||||
small numbers. E.g. 0.1 will be rounded to 1. Note that 0 itself still
|
||||
returns as 0, which is handled in the qoa_quant_tab[].
|
||||
qoa_div() takes an index into the .16 fixed point qoa_reciprocal_tab as an
|
||||
argument, so it can do the division with a cheaper integer multiplication. */
|
||||
|
||||
static inline int qoa_div(int v, int scalefactor) {
|
||||
int reciprocal = qoa_reciprocal_tab[scalefactor];
|
||||
int n = (v * reciprocal + (1 << 15)) >> 16;
|
||||
n = n + ((v > 0) - (v < 0)) - ((n > 0) - (n < 0)); /* round away from 0 */
|
||||
return n;
|
||||
}
|
||||
|
||||
static inline int qoa_clamp(int v, int min, int max) {
|
||||
if (v < min) { return min; }
|
||||
if (v > max) { return max; }
|
||||
return v;
|
||||
}
|
||||
|
||||
/* This specialized clamp function for the signed 16 bit range improves decode
|
||||
performance quite a bit. The extra if() statement works nicely with the CPUs
|
||||
branch prediction as this branch is rarely taken. */
|
||||
|
||||
static inline int qoa_clamp_s16(int v) {
|
||||
if ((unsigned int)(v + 32768) > 65535) {
|
||||
if (v < -32768) { return -32768; }
|
||||
if (v > 32767) { return 32767; }
|
||||
}
|
||||
return v;
|
||||
}
|
||||
|
||||
static inline qoa_uint64_t qoa_read_u64(const unsigned char *bytes, unsigned int *p) {
|
||||
bytes += *p;
|
||||
*p += 8;
|
||||
return
|
||||
((qoa_uint64_t)(bytes[0]) << 56) | ((qoa_uint64_t)(bytes[1]) << 48) |
|
||||
((qoa_uint64_t)(bytes[2]) << 40) | ((qoa_uint64_t)(bytes[3]) << 32) |
|
||||
((qoa_uint64_t)(bytes[4]) << 24) | ((qoa_uint64_t)(bytes[5]) << 16) |
|
||||
((qoa_uint64_t)(bytes[6]) << 8) | ((qoa_uint64_t)(bytes[7]) << 0);
|
||||
}
|
||||
|
||||
static inline void qoa_write_u64(qoa_uint64_t v, unsigned char *bytes, unsigned int *p) {
|
||||
bytes += *p;
|
||||
*p += 8;
|
||||
bytes[0] = (v >> 56) & 0xff;
|
||||
bytes[1] = (v >> 48) & 0xff;
|
||||
bytes[2] = (v >> 40) & 0xff;
|
||||
bytes[3] = (v >> 32) & 0xff;
|
||||
bytes[4] = (v >> 24) & 0xff;
|
||||
bytes[5] = (v >> 16) & 0xff;
|
||||
bytes[6] = (v >> 8) & 0xff;
|
||||
bytes[7] = (v >> 0) & 0xff;
|
||||
}
|
||||
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
Encoder */
|
||||
|
||||
unsigned int qoa_encode_header(qoa_desc *qoa, unsigned char *bytes) {
|
||||
unsigned int p = 0;
|
||||
qoa_write_u64(((qoa_uint64_t)QOA_MAGIC << 32) | qoa->samples, bytes, &p);
|
||||
return p;
|
||||
}
|
||||
|
||||
unsigned int qoa_encode_frame(const short *sample_data, qoa_desc *qoa, unsigned int frame_len, unsigned char *bytes) {
|
||||
unsigned int channels = qoa->channels;
|
||||
|
||||
unsigned int p = 0;
|
||||
unsigned int slices = (frame_len + QOA_SLICE_LEN - 1) / QOA_SLICE_LEN;
|
||||
unsigned int frame_size = QOA_FRAME_SIZE(channels, slices);
|
||||
int prev_scalefactor[QOA_MAX_CHANNELS] = {0};
|
||||
|
||||
/* Write the frame header */
|
||||
qoa_write_u64((
|
||||
(qoa_uint64_t)qoa->channels << 56 |
|
||||
(qoa_uint64_t)qoa->samplerate << 32 |
|
||||
(qoa_uint64_t)frame_len << 16 |
|
||||
(qoa_uint64_t)frame_size
|
||||
), bytes, &p);
|
||||
|
||||
|
||||
for (int c = 0; c < channels; c++) {
|
||||
/* If the weights have grown too large, reset them to 0. This may happen
|
||||
with certain high-frequency sounds. This is a last resort and will
|
||||
introduce quite a bit of noise, but should at least prevent pops/clicks */
|
||||
int weights_sum =
|
||||
qoa->lms[c].weights[0] * qoa->lms[c].weights[0] +
|
||||
qoa->lms[c].weights[1] * qoa->lms[c].weights[1] +
|
||||
qoa->lms[c].weights[2] * qoa->lms[c].weights[2] +
|
||||
qoa->lms[c].weights[3] * qoa->lms[c].weights[3];
|
||||
if (weights_sum > 0x2fffffff) {
|
||||
qoa->lms[c].weights[0] = 0;
|
||||
qoa->lms[c].weights[1] = 0;
|
||||
qoa->lms[c].weights[2] = 0;
|
||||
qoa->lms[c].weights[3] = 0;
|
||||
}
|
||||
|
||||
/* Write the current LMS state */
|
||||
qoa_uint64_t weights = 0;
|
||||
qoa_uint64_t history = 0;
|
||||
for (int i = 0; i < QOA_LMS_LEN; i++) {
|
||||
history = (history << 16) | (qoa->lms[c].history[i] & 0xffff);
|
||||
weights = (weights << 16) | (qoa->lms[c].weights[i] & 0xffff);
|
||||
}
|
||||
qoa_write_u64(history, bytes, &p);
|
||||
qoa_write_u64(weights, bytes, &p);
|
||||
}
|
||||
|
||||
/* We encode all samples with the channels interleaved on a slice level.
|
||||
E.g. for stereo: (ch-0, slice 0), (ch 1, slice 0), (ch 0, slice 1), ...*/
|
||||
for (int sample_index = 0; sample_index < frame_len; sample_index += QOA_SLICE_LEN) {
|
||||
|
||||
for (int c = 0; c < channels; c++) {
|
||||
int slice_len = qoa_clamp(QOA_SLICE_LEN, 0, frame_len - sample_index);
|
||||
int slice_start = sample_index * channels + c;
|
||||
int slice_end = (sample_index + slice_len) * channels + c;
|
||||
|
||||
/* Brute for search for the best scalefactor. Just go through all
|
||||
16 scalefactors, encode all samples for the current slice and
|
||||
meassure the total squared error. */
|
||||
qoa_uint64_t best_error = -1;
|
||||
qoa_uint64_t best_slice;
|
||||
qoa_lms_t best_lms;
|
||||
int best_scalefactor;
|
||||
|
||||
for (int sfi = 0; sfi < 16; sfi++) {
|
||||
/* There is a strong correlation between the scalefactors of
|
||||
neighboring slices. As an optimization, start testing
|
||||
the best scalefactor of the previous slice first. */
|
||||
int scalefactor = (sfi + prev_scalefactor[c]) % 16;
|
||||
|
||||
/* We have to reset the LMS state to the last known good one
|
||||
before trying each scalefactor, as each pass updates the LMS
|
||||
state when encoding. */
|
||||
qoa_lms_t lms = qoa->lms[c];
|
||||
qoa_uint64_t slice = scalefactor;
|
||||
qoa_uint64_t current_error = 0;
|
||||
|
||||
for (int si = slice_start; si < slice_end; si += channels) {
|
||||
int sample = sample_data[si];
|
||||
int predicted = qoa_lms_predict(&lms);
|
||||
|
||||
int residual = sample - predicted;
|
||||
int scaled = qoa_div(residual, scalefactor);
|
||||
int clamped = qoa_clamp(scaled, -8, 8);
|
||||
int quantized = qoa_quant_tab[clamped + 8];
|
||||
int dequantized = qoa_dequant_tab[scalefactor][quantized];
|
||||
int reconstructed = qoa_clamp_s16(predicted + dequantized);
|
||||
|
||||
long long error = (sample - reconstructed);
|
||||
current_error += error * error;
|
||||
if (current_error > best_error) {
|
||||
break;
|
||||
}
|
||||
|
||||
qoa_lms_update(&lms, reconstructed, dequantized);
|
||||
slice = (slice << 3) | quantized;
|
||||
}
|
||||
|
||||
if (current_error < best_error) {
|
||||
best_error = current_error;
|
||||
best_slice = slice;
|
||||
best_lms = lms;
|
||||
best_scalefactor = scalefactor;
|
||||
}
|
||||
}
|
||||
|
||||
prev_scalefactor[c] = best_scalefactor;
|
||||
|
||||
qoa->lms[c] = best_lms;
|
||||
#ifdef QOA_RECORD_TOTAL_ERROR
|
||||
qoa->error += best_error;
|
||||
#endif
|
||||
|
||||
/* If this slice was shorter than QOA_SLICE_LEN, we have to left-
|
||||
shift all encoded data, to ensure the rightmost bits are the empty
|
||||
ones. This should only happen in the last frame of a file as all
|
||||
slices are completely filled otherwise. */
|
||||
best_slice <<= (QOA_SLICE_LEN - slice_len) * 3;
|
||||
qoa_write_u64(best_slice, bytes, &p);
|
||||
}
|
||||
}
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
void *qoa_encode(const short *sample_data, qoa_desc *qoa, unsigned int *out_len) {
|
||||
if (
|
||||
qoa->samples == 0 ||
|
||||
qoa->samplerate == 0 || qoa->samplerate > 0xffffff ||
|
||||
qoa->channels == 0 || qoa->channels > QOA_MAX_CHANNELS
|
||||
) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Calculate the encoded size and allocate */
|
||||
unsigned int num_frames = (qoa->samples + QOA_FRAME_LEN-1) / QOA_FRAME_LEN;
|
||||
unsigned int num_slices = (qoa->samples + QOA_SLICE_LEN-1) / QOA_SLICE_LEN;
|
||||
unsigned int encoded_size = 8 + /* 8 byte file header */
|
||||
num_frames * 8 + /* 8 byte frame headers */
|
||||
num_frames * QOA_LMS_LEN * 4 * qoa->channels + /* 4 * 4 bytes lms state per channel */
|
||||
num_slices * 8 * qoa->channels; /* 8 byte slices */
|
||||
|
||||
unsigned char *bytes = QOA_MALLOC(encoded_size);
|
||||
|
||||
for (int c = 0; c < qoa->channels; c++) {
|
||||
/* Set the initial LMS weights to {0, 0, -1, 2}. This helps with the
|
||||
prediction of the first few ms of a file. */
|
||||
qoa->lms[c].weights[0] = 0;
|
||||
qoa->lms[c].weights[1] = 0;
|
||||
qoa->lms[c].weights[2] = -(1<<13);
|
||||
qoa->lms[c].weights[3] = (1<<14);
|
||||
|
||||
/* Explicitly set the history samples to 0, as we might have some
|
||||
garbage in there. */
|
||||
for (int i = 0; i < QOA_LMS_LEN; i++) {
|
||||
qoa->lms[c].history[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Encode the header and go through all frames */
|
||||
unsigned int p = qoa_encode_header(qoa, bytes);
|
||||
#ifdef QOA_RECORD_TOTAL_ERROR
|
||||
qoa->error = 0;
|
||||
#endif
|
||||
|
||||
int frame_len = QOA_FRAME_LEN;
|
||||
for (int sample_index = 0; sample_index < qoa->samples; sample_index += frame_len) {
|
||||
frame_len = qoa_clamp(QOA_FRAME_LEN, 0, qoa->samples - sample_index);
|
||||
const short *frame_samples = sample_data + sample_index * qoa->channels;
|
||||
unsigned int frame_size = qoa_encode_frame(frame_samples, qoa, frame_len, bytes + p);
|
||||
p += frame_size;
|
||||
}
|
||||
|
||||
*out_len = p;
|
||||
return bytes;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
Decoder */
|
||||
|
||||
unsigned int qoa_max_frame_size(qoa_desc *qoa) {
|
||||
return QOA_FRAME_SIZE(qoa->channels, QOA_SLICES_PER_FRAME);
|
||||
}
|
||||
|
||||
unsigned int qoa_decode_header(const unsigned char *bytes, int size, qoa_desc *qoa) {
|
||||
unsigned int p = 0;
|
||||
if (size < QOA_MIN_FILESIZE) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* Read the file header, verify the magic number ('qoaf') and read the
|
||||
total number of samples. */
|
||||
qoa_uint64_t file_header = qoa_read_u64(bytes, &p);
|
||||
|
||||
if ((file_header >> 32) != QOA_MAGIC) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
qoa->samples = file_header & 0xffffffff;
|
||||
if (!qoa->samples) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Peek into the first frame header to get the number of channels and
|
||||
the samplerate. */
|
||||
qoa_uint64_t frame_header = qoa_read_u64(bytes, &p);
|
||||
qoa->channels = (frame_header >> 56) & 0x0000ff;
|
||||
qoa->samplerate = (frame_header >> 32) & 0xffffff;
|
||||
|
||||
if (qoa->channels == 0 || qoa->samples == 0 || qoa->samplerate == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 8;
|
||||
}
|
||||
|
||||
unsigned int qoa_decode_frame(const unsigned char *bytes, unsigned int size, qoa_desc *qoa, short *sample_data, unsigned int *frame_len) {
|
||||
unsigned int p = 0;
|
||||
*frame_len = 0;
|
||||
|
||||
if (size < 8 + QOA_LMS_LEN * 4 * qoa->channels) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Read and verify the frame header */
|
||||
qoa_uint64_t frame_header = qoa_read_u64(bytes, &p);
|
||||
int channels = (frame_header >> 56) & 0x0000ff;
|
||||
int samplerate = (frame_header >> 32) & 0xffffff;
|
||||
int samples = (frame_header >> 16) & 0x00ffff;
|
||||
int frame_size = (frame_header ) & 0x00ffff;
|
||||
|
||||
int data_size = frame_size - 8 - QOA_LMS_LEN * 4 * channels;
|
||||
int num_slices = data_size / 8;
|
||||
int max_total_samples = num_slices * QOA_SLICE_LEN;
|
||||
|
||||
if (
|
||||
channels != qoa->channels ||
|
||||
samplerate != qoa->samplerate ||
|
||||
frame_size > size ||
|
||||
samples * channels > max_total_samples
|
||||
) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* Read the LMS state: 4 x 2 bytes history, 4 x 2 bytes weights per channel */
|
||||
for (int c = 0; c < channels; c++) {
|
||||
qoa_uint64_t history = qoa_read_u64(bytes, &p);
|
||||
qoa_uint64_t weights = qoa_read_u64(bytes, &p);
|
||||
for (int i = 0; i < QOA_LMS_LEN; i++) {
|
||||
qoa->lms[c].history[i] = ((signed short)(history >> 48));
|
||||
history <<= 16;
|
||||
qoa->lms[c].weights[i] = ((signed short)(weights >> 48));
|
||||
weights <<= 16;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Decode all slices for all channels in this frame */
|
||||
for (int sample_index = 0; sample_index < samples; sample_index += QOA_SLICE_LEN) {
|
||||
for (int c = 0; c < channels; c++) {
|
||||
qoa_uint64_t slice = qoa_read_u64(bytes, &p);
|
||||
|
||||
int scalefactor = (slice >> 60) & 0xf;
|
||||
int slice_start = sample_index * channels + c;
|
||||
int slice_end = qoa_clamp(sample_index + QOA_SLICE_LEN, 0, samples) * channels + c;
|
||||
|
||||
for (int si = slice_start; si < slice_end; si += channels) {
|
||||
int predicted = qoa_lms_predict(&qoa->lms[c]);
|
||||
int quantized = (slice >> 57) & 0x7;
|
||||
int dequantized = qoa_dequant_tab[scalefactor][quantized];
|
||||
int reconstructed = qoa_clamp_s16(predicted + dequantized);
|
||||
|
||||
sample_data[si] = reconstructed;
|
||||
slice <<= 3;
|
||||
|
||||
qoa_lms_update(&qoa->lms[c], reconstructed, dequantized);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
*frame_len = samples;
|
||||
return p;
|
||||
}
|
||||
|
||||
short *qoa_decode(const unsigned char *bytes, int size, qoa_desc *qoa) {
|
||||
unsigned int p = qoa_decode_header(bytes, size, qoa);
|
||||
if (!p) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Calculate the required size of the sample buffer and allocate */
|
||||
int total_samples = qoa->samples * qoa->channels;
|
||||
short *sample_data = QOA_MALLOC(total_samples * sizeof(short));
|
||||
|
||||
unsigned int sample_index = 0;
|
||||
unsigned int frame_len;
|
||||
unsigned int frame_size;
|
||||
|
||||
/* Decode all frames */
|
||||
do {
|
||||
short *sample_ptr = sample_data + sample_index * qoa->channels;
|
||||
frame_size = qoa_decode_frame(bytes + p, size - p, qoa, sample_ptr, &frame_len);
|
||||
|
||||
p += frame_size;
|
||||
sample_index += frame_len;
|
||||
} while (frame_size && sample_index < qoa->samples);
|
||||
|
||||
qoa->samples = sample_index;
|
||||
return sample_data;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
File read/write convenience functions */
|
||||
|
||||
#ifndef QOA_NO_STDIO
|
||||
#include <stdio.h>
|
||||
|
||||
int qoa_write(const char *filename, const short *sample_data, qoa_desc *qoa) {
|
||||
FILE *f = fopen(filename, "wb");
|
||||
unsigned int size;
|
||||
void *encoded;
|
||||
|
||||
if (!f) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
encoded = qoa_encode(sample_data, qoa, &size);
|
||||
if (!encoded) {
|
||||
fclose(f);
|
||||
return 0;
|
||||
}
|
||||
|
||||
fwrite(encoded, 1, size, f);
|
||||
fclose(f);
|
||||
|
||||
QOA_FREE(encoded);
|
||||
return size;
|
||||
}
|
||||
|
||||
void *qoa_read(const char *filename, qoa_desc *qoa) {
|
||||
FILE *f = fopen(filename, "rb");
|
||||
int size, bytes_read;
|
||||
void *data;
|
||||
short *sample_data;
|
||||
|
||||
if (!f) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
fseek(f, 0, SEEK_END);
|
||||
size = ftell(f);
|
||||
if (size <= 0) {
|
||||
fclose(f);
|
||||
return NULL;
|
||||
}
|
||||
fseek(f, 0, SEEK_SET);
|
||||
|
||||
data = QOA_MALLOC(size);
|
||||
if (!data) {
|
||||
fclose(f);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bytes_read = fread(data, 1, size, f);
|
||||
fclose(f);
|
||||
|
||||
sample_data = qoa_decode(data, bytes_read, qoa);
|
||||
QOA_FREE(data);
|
||||
return sample_data;
|
||||
}
|
||||
|
||||
#endif /* QOA_NO_STDIO */
|
||||
#endif /* QOA_IMPLEMENTATION */
|
||||
278
include/extern/external/qoaplay.c
vendored
Normal file
278
include/extern/external/qoaplay.c
vendored
Normal file
@ -0,0 +1,278 @@
|
||||
/*******************************************************************************************
|
||||
*
|
||||
* qoaplay - QOA stream playing helper functions
|
||||
*
|
||||
* qoaplay is a tiny abstraction to read and decode a QOA file "on the fly".
|
||||
* It reads and decodes one frame at a time with minimal memory requirements.
|
||||
* qoaplay also provides some functions to seek to a specific frame.
|
||||
*
|
||||
* LICENSE: MIT License
|
||||
*
|
||||
* Copyright (c) 2023 Dominic Szablewski (@phoboslab), reviewed by Ramon Santamaria (@raysan5)
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
**********************************************************************************************/
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Types and Structures Definition
|
||||
//----------------------------------------------------------------------------------
|
||||
// QOA streaming data descriptor
|
||||
typedef struct {
|
||||
qoa_desc info; // QOA descriptor data
|
||||
|
||||
FILE *file; // QOA file to read, if NULL, using memory buffer -> file_data
|
||||
unsigned char *file_data; // QOA file data on memory
|
||||
unsigned int file_data_size; // QOA file data on memory size
|
||||
unsigned int file_data_offset; // QOA file data on memory offset for next read
|
||||
|
||||
unsigned int first_frame_pos; // First frame position (after QOA header, required for offset)
|
||||
unsigned int sample_position; // Current streaming sample position
|
||||
|
||||
unsigned char *buffer; // Buffer used to read samples from file/memory (used on decoding)
|
||||
unsigned int buffer_len; // Buffer length to read samples for streaming
|
||||
|
||||
short *sample_data; // Sample data decoded
|
||||
unsigned int sample_data_len; // Sample data decoded length
|
||||
unsigned int sample_data_pos; // Sample data decoded position
|
||||
|
||||
} qoaplay_desc;
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Module Functions Declaration
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" { // Prevents name mangling of functions
|
||||
#endif
|
||||
|
||||
qoaplay_desc *qoaplay_open(const char *path);
|
||||
qoaplay_desc *qoaplay_open_memory(const unsigned char *data, int data_size);
|
||||
void qoaplay_close(qoaplay_desc *qoa_ctx);
|
||||
|
||||
void qoaplay_rewind(qoaplay_desc *qoa_ctx);
|
||||
void qoaplay_seek_frame(qoaplay_desc *qoa_ctx, int frame);
|
||||
unsigned int qoaplay_decode(qoaplay_desc *qoa_ctx, float *sample_data, int num_samples);
|
||||
unsigned int qoaplay_decode_frame(qoaplay_desc *qoa_ctx);
|
||||
double qoaplay_get_duration(qoaplay_desc *qoa_ctx);
|
||||
double qoaplay_get_time(qoaplay_desc *qoa_ctx);
|
||||
int qoaplay_get_frame(qoaplay_desc *qoa_ctx);
|
||||
|
||||
#if defined(__cplusplus)
|
||||
} // Prevents name mangling of functions
|
||||
#endif
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Module Functions Definition
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Open QOA file, keep FILE pointer to keep reading from file
|
||||
qoaplay_desc *qoaplay_open(const char *path)
|
||||
{
|
||||
FILE *file = fopen(path, "rb");
|
||||
if (!file) return NULL;
|
||||
|
||||
// Read and decode the file header
|
||||
unsigned char header[QOA_MIN_FILESIZE];
|
||||
int read = fread(header, QOA_MIN_FILESIZE, 1, file);
|
||||
if (!read) return NULL;
|
||||
|
||||
qoa_desc qoa;
|
||||
unsigned int first_frame_pos = qoa_decode_header(header, QOA_MIN_FILESIZE, &qoa);
|
||||
if (!first_frame_pos) return NULL;
|
||||
|
||||
// Rewind the file back to beginning of the first frame
|
||||
fseek(file, first_frame_pos, SEEK_SET);
|
||||
|
||||
// Allocate one chunk of memory for the qoaplay_desc struct
|
||||
// + the sample data for one frame
|
||||
// + a buffer to hold one frame of encoded data
|
||||
unsigned int buffer_size = qoa_max_frame_size(&qoa);
|
||||
unsigned int sample_data_size = qoa.channels*QOA_FRAME_LEN*sizeof(short)*2;
|
||||
qoaplay_desc *qoa_ctx = QOA_MALLOC(sizeof(qoaplay_desc) + buffer_size + sample_data_size);
|
||||
memset(qoa_ctx, 0, sizeof(qoaplay_desc));
|
||||
|
||||
qoa_ctx->file = file;
|
||||
qoa_ctx->file_data = NULL;
|
||||
qoa_ctx->file_data_size = 0;
|
||||
qoa_ctx->file_data_offset = 0;
|
||||
qoa_ctx->first_frame_pos = first_frame_pos;
|
||||
|
||||
// Setup data pointers to previously allocated data
|
||||
qoa_ctx->buffer = ((unsigned char *)qoa_ctx) + sizeof(qoaplay_desc);
|
||||
qoa_ctx->sample_data = (short *)(((unsigned char *)qoa_ctx) + sizeof(qoaplay_desc) + buffer_size);
|
||||
|
||||
qoa_ctx->info.channels = qoa.channels;
|
||||
qoa_ctx->info.samplerate = qoa.samplerate;
|
||||
qoa_ctx->info.samples = qoa.samples;
|
||||
|
||||
return qoa_ctx;
|
||||
}
|
||||
|
||||
// Open QOA file from memory, no FILE pointer required
|
||||
qoaplay_desc *qoaplay_open_memory(const unsigned char *data, int data_size)
|
||||
{
|
||||
// Read and decode the file header
|
||||
unsigned char header[QOA_MIN_FILESIZE];
|
||||
memcpy(header, data, QOA_MIN_FILESIZE);
|
||||
|
||||
qoa_desc qoa;
|
||||
unsigned int first_frame_pos = qoa_decode_header(header, QOA_MIN_FILESIZE, &qoa);
|
||||
if (!first_frame_pos) return NULL;
|
||||
|
||||
// Allocate one chunk of memory for the qoaplay_desc struct
|
||||
// + the sample data for one frame
|
||||
// + a buffer to hold one frame of encoded data
|
||||
unsigned int buffer_size = qoa_max_frame_size(&qoa);
|
||||
unsigned int sample_data_size = qoa.channels*QOA_FRAME_LEN*sizeof(short)*2;
|
||||
qoaplay_desc *qoa_ctx = QOA_MALLOC(sizeof(qoaplay_desc) + buffer_size + sample_data_size);
|
||||
memset(qoa_ctx, 0, sizeof(qoaplay_desc));
|
||||
|
||||
qoa_ctx->file = NULL;
|
||||
|
||||
// Keep a copy of file data provided to be managed internally
|
||||
qoa_ctx->file_data = (unsigned char *)QOA_MALLOC(data_size);
|
||||
memcpy(qoa_ctx->file_data, data, data_size);
|
||||
qoa_ctx->file_data_size = data_size;
|
||||
qoa_ctx->file_data_offset = 0;
|
||||
qoa_ctx->first_frame_pos = first_frame_pos;
|
||||
|
||||
// Setup data pointers to previously allocated data
|
||||
qoa_ctx->buffer = ((unsigned char *)qoa_ctx) + sizeof(qoaplay_desc);
|
||||
qoa_ctx->sample_data = (short *)(((unsigned char *)qoa_ctx) + sizeof(qoaplay_desc) + buffer_size);
|
||||
|
||||
qoa_ctx->info.channels = qoa.channels;
|
||||
qoa_ctx->info.samplerate = qoa.samplerate;
|
||||
qoa_ctx->info.samples = qoa.samples;
|
||||
|
||||
return qoa_ctx;
|
||||
}
|
||||
|
||||
// Close QOA file (if open) and free internal memory
|
||||
void qoaplay_close(qoaplay_desc *qoa_ctx)
|
||||
{
|
||||
if (qoa_ctx->file) fclose(qoa_ctx->file);
|
||||
|
||||
if ((qoa_ctx->file_data) && (qoa_ctx->file_data_size > 0))
|
||||
{
|
||||
QOA_FREE(qoa_ctx->file_data);
|
||||
qoa_ctx->file_data_size = 0;
|
||||
}
|
||||
|
||||
QOA_FREE(qoa_ctx);
|
||||
}
|
||||
|
||||
// Decode one frame from QOA data
|
||||
unsigned int qoaplay_decode_frame(qoaplay_desc *qoa_ctx)
|
||||
{
|
||||
if (qoa_ctx->file) qoa_ctx->buffer_len = fread(qoa_ctx->buffer, 1, qoa_max_frame_size(&qoa_ctx->info), qoa_ctx->file);
|
||||
else
|
||||
{
|
||||
qoa_ctx->buffer_len = qoa_max_frame_size(&qoa_ctx->info);
|
||||
memcpy(qoa_ctx->buffer, qoa_ctx->file_data + qoa_ctx->file_data_offset, qoa_ctx->buffer_len);
|
||||
qoa_ctx->file_data_offset += qoa_ctx->buffer_len;
|
||||
}
|
||||
|
||||
unsigned int frame_len;
|
||||
qoa_decode_frame(qoa_ctx->buffer, qoa_ctx->buffer_len, &qoa_ctx->info, qoa_ctx->sample_data, &frame_len);
|
||||
qoa_ctx->sample_data_pos = 0;
|
||||
qoa_ctx->sample_data_len = frame_len;
|
||||
|
||||
return frame_len;
|
||||
}
|
||||
|
||||
// Rewind QOA file or memory pointer to beginning
|
||||
void qoaplay_rewind(qoaplay_desc *qoa_ctx)
|
||||
{
|
||||
if (qoa_ctx->file) fseek(qoa_ctx->file, qoa_ctx->first_frame_pos, SEEK_SET);
|
||||
else qoa_ctx->file_data_offset = 0;
|
||||
|
||||
qoa_ctx->sample_position = 0;
|
||||
qoa_ctx->sample_data_len = 0;
|
||||
qoa_ctx->sample_data_pos = 0;
|
||||
}
|
||||
|
||||
// Decode required QOA frames
|
||||
unsigned int qoaplay_decode(qoaplay_desc *qoa_ctx, float *sample_data, int num_samples)
|
||||
{
|
||||
int src_index = qoa_ctx->sample_data_pos*qoa_ctx->info.channels;
|
||||
int dst_index = 0;
|
||||
|
||||
for (int i = 0; i < num_samples; i++)
|
||||
{
|
||||
// Do we have to decode more samples?
|
||||
if (qoa_ctx->sample_data_len - qoa_ctx->sample_data_pos == 0)
|
||||
{
|
||||
if (!qoaplay_decode_frame(qoa_ctx))
|
||||
{
|
||||
// Loop to the beginning
|
||||
qoaplay_rewind(qoa_ctx);
|
||||
qoaplay_decode_frame(qoa_ctx);
|
||||
}
|
||||
|
||||
src_index = 0;
|
||||
}
|
||||
|
||||
// Normalize to -1..1 floats and write to dest
|
||||
for (int c = 0; c < qoa_ctx->info.channels; c++)
|
||||
{
|
||||
sample_data[dst_index++] = qoa_ctx->sample_data[src_index++]/32768.0;
|
||||
}
|
||||
|
||||
qoa_ctx->sample_data_pos++;
|
||||
qoa_ctx->sample_position++;
|
||||
}
|
||||
|
||||
return num_samples;
|
||||
}
|
||||
|
||||
// Get QOA total time duration in seconds
|
||||
double qoaplay_get_duration(qoaplay_desc *qoa_ctx)
|
||||
{
|
||||
return (double)qoa_ctx->info.samples/(double)qoa_ctx->info.samplerate;
|
||||
}
|
||||
|
||||
// Get QOA current time position in seconds
|
||||
double qoaplay_get_time(qoaplay_desc *qoa_ctx)
|
||||
{
|
||||
return (double)qoa_ctx->sample_position/(double)qoa_ctx->info.samplerate;
|
||||
}
|
||||
|
||||
// Get QOA current audio frame
|
||||
int qoaplay_get_frame(qoaplay_desc *qoa_ctx)
|
||||
{
|
||||
return qoa_ctx->sample_position/QOA_FRAME_LEN;
|
||||
}
|
||||
|
||||
// Seek QOA audio frame
|
||||
void qoaplay_seek_frame(qoaplay_desc *qoa_ctx, int frame)
|
||||
{
|
||||
if (frame < 0) frame = 0;
|
||||
|
||||
if (frame > qoa_ctx->info.samples/QOA_FRAME_LEN) frame = qoa_ctx->info.samples/QOA_FRAME_LEN;
|
||||
|
||||
qoa_ctx->sample_position = frame*QOA_FRAME_LEN;
|
||||
qoa_ctx->sample_data_len = 0;
|
||||
qoa_ctx->sample_data_pos = 0;
|
||||
|
||||
unsigned int offset = qoa_ctx->first_frame_pos + frame*qoa_max_frame_size(&qoa_ctx->info);
|
||||
|
||||
if (qoa_ctx->file) fseek(qoa_ctx->file, offset, SEEK_SET);
|
||||
else qoa_ctx->file_data_offset = offset;
|
||||
}
|
||||
5584
include/extern/external/stb_vorbis.c
vendored
Normal file
5584
include/extern/external/stb_vorbis.c
vendored
Normal file
File diff suppressed because it is too large
Load Diff
2797
include/extern/raudio.c
vendored
Normal file
2797
include/extern/raudio.c
vendored
Normal file
File diff suppressed because it is too large
Load Diff
222
include/extern/raudio.h
vendored
Normal file
222
include/extern/raudio.h
vendored
Normal file
@ -0,0 +1,222 @@
|
||||
/**********************************************************************************************
|
||||
*
|
||||
* raudio v1.1 - A simple and easy-to-use audio library based on miniaudio
|
||||
*
|
||||
* FEATURES:
|
||||
* - Manage audio device (init/close)
|
||||
* - Manage raw audio context
|
||||
* - Manage mixing channels
|
||||
* - Load and unload audio files
|
||||
* - Format wave data (sample rate, size, channels)
|
||||
* - Play/Stop/Pause/Resume loaded audio
|
||||
*
|
||||
* DEPENDENCIES:
|
||||
* miniaudio.h - Audio device management lib (https://github.com/mackron/miniaudio)
|
||||
* stb_vorbis.h - Ogg audio files loading (http://www.nothings.org/stb_vorbis/)
|
||||
* dr_wav.h - WAV audio files loading (http://github.com/mackron/dr_libs)
|
||||
* dr_mp3.h - MP3 audio file loading (https://github.com/mackron/dr_libs)
|
||||
* dr_flac.h - FLAC audio file loading (https://github.com/mackron/dr_libs)
|
||||
* jar_xm.h - XM module file loading
|
||||
* jar_mod.h - MOD audio file loading
|
||||
*
|
||||
* CONTRIBUTORS:
|
||||
* David Reid (github: @mackron) (Nov. 2017):
|
||||
* - Complete port to miniaudio library
|
||||
*
|
||||
* Joshua Reisenauer (github: @kd7tck) (2015):
|
||||
* - XM audio module support (jar_xm)
|
||||
* - MOD audio module support (jar_mod)
|
||||
* - Mixing channels support
|
||||
* - Raw audio context support
|
||||
*
|
||||
*
|
||||
* LICENSE: zlib/libpng
|
||||
*
|
||||
* Copyright (c) 2013-2025 Ramon Santamaria (@raysan5)
|
||||
*
|
||||
* This software is provided "as-is", without any express or implied warranty. In no event
|
||||
* will the authors be held liable for any damages arising from the use of this software.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose, including commercial
|
||||
* applications, and to alter it and redistribute it freely, subject to the following restrictions:
|
||||
*
|
||||
* 1. The origin of this software must not be misrepresented; you must not claim that you
|
||||
* wrote the original software. If you use this software in a product, an acknowledgment
|
||||
* in the product documentation would be appreciated but is not required.
|
||||
*
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be misrepresented
|
||||
* as being the original software.
|
||||
*
|
||||
* 3. This notice may not be removed or altered from any source distribution.
|
||||
*
|
||||
**********************************************************************************************/
|
||||
|
||||
#ifndef RAUDIO_H
|
||||
#define RAUDIO_H
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Defines and Macros
|
||||
//----------------------------------------------------------------------------------
|
||||
// In case this file is included, we are using raudio in standalone mode
|
||||
#ifndef RAUDIO_STANDALONE
|
||||
#define RAUDIO_STANDALONE
|
||||
#endif // RAUDIO_STANDALONE
|
||||
|
||||
// Allow custom memory allocators
|
||||
#ifndef RL_MALLOC
|
||||
#define RL_MALLOC(sz) malloc(sz)
|
||||
#endif
|
||||
#ifndef RL_CALLOC
|
||||
#define RL_CALLOC(n,sz) calloc(n,sz)
|
||||
#endif
|
||||
#ifndef RL_FREE
|
||||
#define RL_FREE(p) free(p)
|
||||
#endif
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Types and Structures Definition
|
||||
//----------------------------------------------------------------------------------
|
||||
#if (defined(__STDC__) && __STDC_VERSION__ >= 199901L) || (defined(_MSC_VER) && _MSC_VER >= 1800)
|
||||
#include <stdbool.h>
|
||||
#elif !defined(__cplusplus) && !defined(bool)
|
||||
typedef enum bool { false = 0, true = !false } bool;
|
||||
#define RL_BOOL_TYPE
|
||||
#endif
|
||||
|
||||
typedef void (*AudioCallback)(void *bufferData, unsigned int frames);
|
||||
|
||||
// Wave, audio wave data
|
||||
typedef struct Wave {
|
||||
unsigned int frameCount; // Total number of frames (considering channels)
|
||||
unsigned int sampleRate; // Frequency (samples per second)
|
||||
unsigned int sampleSize; // Bit depth (bits per sample): 8, 16, 32 (24 not supported)
|
||||
unsigned int channels; // Number of channels (1-mono, 2-stereo, ...)
|
||||
void *data; // Buffer data pointer
|
||||
} Wave;
|
||||
|
||||
// Opaque structs declaration
|
||||
typedef struct rAudioBuffer rAudioBuffer;
|
||||
typedef struct rAudioProcessor rAudioProcessor;
|
||||
|
||||
// AudioStream, custom audio stream
|
||||
typedef struct AudioStream {
|
||||
rAudioBuffer *buffer; // Pointer to internal data used by the audio system
|
||||
rAudioProcessor *processor; // Pointer to internal data processor, useful for audio effects
|
||||
|
||||
unsigned int sampleRate; // Frequency (samples per second)
|
||||
unsigned int sampleSize; // Bit depth (bits per sample): 8, 16, 32 (24 not supported)
|
||||
unsigned int channels; // Number of channels (1-mono, 2-stereo, ...)
|
||||
} AudioStream;
|
||||
|
||||
// Sound
|
||||
typedef struct Sound {
|
||||
AudioStream stream; // Audio stream
|
||||
unsigned int frameCount; // Total number of frames (considering channels)
|
||||
} Sound;
|
||||
|
||||
// Music, audio stream, anything longer than ~10 seconds should be streamed
|
||||
typedef struct Music {
|
||||
AudioStream stream; // Audio stream
|
||||
unsigned int frameCount; // Total number of frames (considering channels)
|
||||
bool looping; // Music looping enable
|
||||
|
||||
int ctxType; // Type of music context (audio filetype)
|
||||
void *ctxData; // Audio context data, depends on type
|
||||
} Music;
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Global Variables Definition
|
||||
//----------------------------------------------------------------------------------
|
||||
//...
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Module Functions Declaration
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" { // Prevents name mangling of functions
|
||||
#endif
|
||||
|
||||
// Audio device management functions
|
||||
void InitAudioDevice(void); // Initialize audio device and context
|
||||
void CloseAudioDevice(void); // Close the audio device and context
|
||||
bool IsAudioDeviceReady(void); // Check if audio device has been initialized successfully
|
||||
void SetMasterVolume(float volume); // Set master volume (listener)
|
||||
float GetMasterVolume(void); // Get master volume (listener)
|
||||
|
||||
// Wave/Sound loading/unloading functions
|
||||
Wave LoadWave(const char *fileName); // Load wave data from file
|
||||
Wave LoadWaveFromMemory(const char *fileType, const unsigned char *fileData, int dataSize); // Load wave from memory buffer, fileType refers to extension: i.e. ".wav"
|
||||
bool IsWaveReady(Wave wave); // Checks if wave data is ready
|
||||
Sound LoadSound(const char *fileName); // Load sound from file
|
||||
Sound LoadSoundFromWave(Wave wave); // Load sound from wave data
|
||||
Sound LoadSoundAlias(Sound source); // Create a new sound that shares the same sample data as the source sound, does not own the sound data
|
||||
bool IsSoundReady(Sound sound); // Checks if a sound is ready
|
||||
void UpdateSound(Sound sound, const void *data, int frameCount);// Update sound buffer with new data
|
||||
void UnloadWave(Wave wave); // Unload wave data
|
||||
void UnloadSound(Sound sound); // Unload sound
|
||||
void UnloadSoundAlias(Sound alias); // Unload a sound alias (does not deallocate sample data)
|
||||
bool ExportWave(Wave wave, const char *fileName); // Export wave data to file, returns true on success
|
||||
bool ExportWaveAsCode(Wave wave, const char *fileName); // Export wave sample data to code (.h), returns true on success
|
||||
|
||||
// Wave/Sound management functions
|
||||
void PlaySound(Sound sound); // Play a sound
|
||||
void StopSound(Sound sound); // Stop playing a sound
|
||||
void PauseSound(Sound sound); // Pause a sound
|
||||
void ResumeSound(Sound sound); // Resume a paused sound
|
||||
bool IsSoundPlaying(Sound sound); // Check if a sound is currently playing
|
||||
void SetSoundVolume(Sound sound, float volume); // Set volume for a sound (1.0 is max level)
|
||||
void SetSoundPitch(Sound sound, float pitch); // Set pitch for a sound (1.0 is base level)
|
||||
void SetSoundPan(Sound sound, float pan); // Set pan for a sound (0.0 to 1.0, 0.5=center)
|
||||
Wave WaveCopy(Wave wave); // Copy a wave to a new wave
|
||||
void WaveCrop(Wave *wave, int initSample, int finalSample); // Crop a wave to defined samples range
|
||||
void WaveFormat(Wave *wave, int sampleRate, int sampleSize, int channels); // Convert wave data to desired format
|
||||
float *LoadWaveSamples(Wave wave); // Load samples data from wave as a floats array
|
||||
void UnloadWaveSamples(float *samples); // Unload samples data loaded with LoadWaveSamples()
|
||||
|
||||
// Music management functions
|
||||
Music LoadMusicStream(const char *fileName); // Load music stream from file
|
||||
Music LoadMusicStreamFromMemory(const char *fileType, const unsigned char* data, int dataSize); // Load music stream from data
|
||||
bool IsMusicReady(Music music); // Checks if a music stream is ready
|
||||
void UnloadMusicStream(Music music); // Unload music stream
|
||||
void PlayMusicStream(Music music); // Start music playing
|
||||
bool IsMusicStreamPlaying(Music music); // Check if music is playing
|
||||
void UpdateMusicStream(Music music); // Updates buffers for music streaming
|
||||
void StopMusicStream(Music music); // Stop music playing
|
||||
void PauseMusicStream(Music music); // Pause music playing
|
||||
void ResumeMusicStream(Music music); // Resume playing paused music
|
||||
void SeekMusicStream(Music music, float position); // Seek music to a position (in seconds)
|
||||
void SetMusicVolume(Music music, float volume); // Set volume for music (1.0 is max level)
|
||||
void SetMusicPitch(Music music, float pitch); // Set pitch for a music (1.0 is base level)
|
||||
void SetMusicPan(Music music, float pan); // Set pan for a music (0.0 to 1.0, 0.5=center)
|
||||
float GetMusicTimeLength(Music music); // Get music time length (in seconds)
|
||||
float GetMusicTimePlayed(Music music); // Get current music time played (in seconds)
|
||||
|
||||
// AudioStream management functions
|
||||
AudioStream LoadAudioStream(unsigned int sampleRate, unsigned int sampleSize, unsigned int channels); // Load audio stream (to stream raw audio pcm data)
|
||||
bool IsAudioStreamReady(AudioStream stream); // Checks if an audio stream is ready
|
||||
void UnloadAudioStream(AudioStream stream); // Unload audio stream and free memory
|
||||
void UpdateAudioStream(AudioStream stream, const void *data, int samplesCount); // Update audio stream buffers with data
|
||||
bool IsAudioStreamProcessed(AudioStream stream); // Check if any audio stream buffers requires refill
|
||||
void PlayAudioStream(AudioStream stream); // Play audio stream
|
||||
void PauseAudioStream(AudioStream stream); // Pause audio stream
|
||||
void ResumeAudioStream(AudioStream stream); // Resume audio stream
|
||||
bool IsAudioStreamPlaying(AudioStream stream); // Check if audio stream is playing
|
||||
void StopAudioStream(AudioStream stream); // Stop audio stream
|
||||
void SetAudioStreamVolume(AudioStream stream, float volume); // Set volume for audio stream (1.0 is max level)
|
||||
void SetAudioStreamPitch(AudioStream stream, float pitch); // Set pitch for audio stream (1.0 is base level)
|
||||
void SetAudioStreamPan(AudioStream strean, float pan); // Set pan for audio stream (0.0 to 1.0, 0.5=center)
|
||||
void SetAudioStreamBufferSizeDefault(int size); // Default size for new audio streams
|
||||
void SetAudioStreamCallback(AudioStream stream, AudioCallback callback); // Audio thread callback to request new data
|
||||
|
||||
void AttachAudioStreamProcessor(AudioStream stream, AudioCallback processor); // Attach audio stream processor to stream
|
||||
void DetachAudioStreamProcessor(AudioStream stream, AudioCallback processor); // Detach audio stream processor from stream
|
||||
|
||||
void AttachAudioMixedProcessor(AudioCallback processor); // Attach audio stream processor to the entire audio pipeline
|
||||
void DetachAudioMixedProcessor(AudioCallback processor); // Detach audio stream processor from the entire audio pipeline
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // RAUDIO_H
|
||||
5521
include/extern/raygui.h
vendored
Normal file
5521
include/extern/raygui.h
vendored
Normal file
File diff suppressed because it is too large
Load Diff
1708
include/extern/raylib.h
vendored
Normal file
1708
include/extern/raylib.h
vendored
Normal file
File diff suppressed because it is too large
Load Diff
2941
include/extern/raymath.h
vendored
Normal file
2941
include/extern/raymath.h
vendored
Normal file
File diff suppressed because it is too large
Load Diff
569
include/extern/rgs/style_terminal.h
vendored
Normal file
569
include/extern/rgs/style_terminal.h
vendored
Normal file
@ -0,0 +1,569 @@
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// StyleAsCode exporter v2.0 - Style data exported as a values array //
|
||||
// //
|
||||
// USAGE: On init call: GuiLoadStyleTerminal(); //
|
||||
// //
|
||||
// more info and bugs-report: github.com/raysan5/raygui //
|
||||
// feedback and support: ray[at]raylibtech.com //
|
||||
// //
|
||||
// Copyright (c) 2020-2023 raylib technologies (@raylibtech) //
|
||||
// //
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#define TERMINAL_STYLE_PROPS_COUNT 17
|
||||
|
||||
// Custom style name: Terminal
|
||||
static const GuiStyleProp terminalStyleProps[TERMINAL_STYLE_PROPS_COUNT] = {
|
||||
{ 0, 0, 0x1c8d00ff }, // DEFAULT_BORDER_COLOR_NORMAL
|
||||
{ 0, 1, 0x161313ff }, // DEFAULT_BASE_COLOR_NORMAL
|
||||
{ 0, 2, 0x38f620ff }, // DEFAULT_TEXT_COLOR_NORMAL
|
||||
{ 0, 3, 0xc3fbc6ff }, // DEFAULT_BORDER_COLOR_FOCUSED
|
||||
{ 0, 4, 0x43bf2eff }, // DEFAULT_BASE_COLOR_FOCUSED
|
||||
{ 0, 5, 0xdcfadcff }, // DEFAULT_TEXT_COLOR_FOCUSED
|
||||
{ 0, 6, 0x1f5b19ff }, // DEFAULT_BORDER_COLOR_PRESSED
|
||||
{ 0, 7, 0x43ff28ff }, // DEFAULT_BASE_COLOR_PRESSED
|
||||
{ 0, 8, 0x1e6f15ff }, // DEFAULT_TEXT_COLOR_PRESSED
|
||||
{ 0, 9, 0x223b22ff }, // DEFAULT_BORDER_COLOR_DISABLED
|
||||
{ 0, 10, 0x182c18ff }, // DEFAULT_BASE_COLOR_DISABLED
|
||||
{ 0, 11, 0x244125ff }, // DEFAULT_TEXT_COLOR_DISABLED
|
||||
{ 0, 16, 0x00000010 }, // DEFAULT_TEXT_SIZE
|
||||
{ 0, 17, 0x00000000 }, // DEFAULT_TEXT_SPACING
|
||||
{ 0, 18, 0xe6fce3ff }, // DEFAULT_LINE_COLOR
|
||||
{ 0, 19, 0x0c1505ff }, // DEFAULT_BACKGROUND_COLOR
|
||||
{ 0, 20, 0x00000018 }, // DEFAULT_TEXT_LINE_SPACING
|
||||
};
|
||||
|
||||
// WARNING: This style uses a custom font: "Mecha.ttf" (size: 16, spacing: 0)
|
||||
|
||||
#define TERMINAL_STYLE_FONT_ATLAS_COMP_SIZE 1860
|
||||
|
||||
// Font atlas image pixels data: DEFLATE compressed
|
||||
static unsigned char terminalFontData[TERMINAL_STYLE_FONT_ATLAS_COMP_SIZE] = { 0xed,
|
||||
0xdd, 0x41, 0x92, 0xa4, 0x36, 0x10, 0x05, 0x50, 0xee, 0x7f, 0xe9, 0xf4, 0x62, 0x62, 0x16, 0x76, 0xb8, 0x1b, 0x94, 0x4a,
|
||||
0x89, 0x04, 0x9e, 0x5f, 0x78, 0xd3, 0xd5, 0x53, 0x4d, 0x01, 0xbf, 0x24, 0x84, 0x94, 0xc4, 0x01, 0x00, 0x00, 0x00, 0x7c,
|
||||
0x5e, 0xfc, 0xef, 0x4f, 0xe2, 0xc7, 0xdf, 0x8c, 0xcb, 0xef, 0xf3, 0xe7, 0xa7, 0xf1, 0xe3, 0x5f, 0xf9, 0xfb, 0xdf, 0x95,
|
||||
0x77, 0xba, 0xfe, 0x5b, 0x31, 0xb4, 0x75, 0x73, 0x5b, 0x95, 0x7b, 0x9f, 0xd1, 0xdf, 0xfe, 0x7d, 0x7b, 0xaa, 0xde, 0xad,
|
||||
0xf6, 0x95, 0xb1, 0xb3, 0x23, 0xbf, 0xe7, 0xae, 0x6e, 0x61, 0x6c, 0xdf, 0x2b, 0xc7, 0xa6, 0x7d, 0x1c, 0x0d, 0xf2, 0x7f,
|
||||
0x7e, 0xcc, 0x46, 0xf2, 0x14, 0xe9, 0xf4, 0x8e, 0x7f, 0x3b, 0xad, 0xfc, 0x0e, 0x1d, 0xdd, 0xc6, 0xdc, 0x3e, 0x89, 0x92,
|
||||
0xf7, 0x9f, 0xf9, 0x3b, 0x51, 0xb6, 0xd7, 0x72, 0xff, 0x26, 0x86, 0xdb, 0x88, 0xf9, 0x4f, 0x78, 0xbe, 0x8f, 0x63, 0xd1,
|
||||
0x71, 0xef, 0x99, 0xff, 0xfc, 0x51, 0xcb, 0x9f, 0x29, 0x57, 0xb7, 0x3c, 0xd7, 0xa6, 0xaf, 0x3a, 0x27, 0xe5, 0xff, 0xec,
|
||||
0x9b, 0xfa, 0xe7, 0x16, 0xb4, 0xa2, 0xdd, 0x90, 0xff, 0x5c, 0x06, 0x62, 0x22, 0x47, 0xbb, 0xf2, 0x5f, 0xdb, 0xd6, 0xc8,
|
||||
0xff, 0x33, 0xda, 0xff, 0xb3, 0x6d, 0xff, 0xf7, 0x79, 0x2b, 0xff, 0xd9, 0xa3, 0x90, 0x6d, 0xff, 0x63, 0x7a, 0xfb, 0x3b,
|
||||
0xe7, 0x7f, 0x74, 0xdc, 0x43, 0xfe, 0xcf, 0xaf, 0xe8, 0x73, 0xbf, 0x7d, 0xb6, 0x27, 0xe4, 0x7f, 0x5d, 0xfe, 0x7f, 0xeb,
|
||||
0xb3, 0x9d, 0xf5, 0xf4, 0x76, 0xe4, 0xff, 0xd8, 0x9e, 0xff, 0xb3, 0xeb, 0xa8, 0xeb, 0xfb, 0x62, 0xc7, 0x08, 0xd4, 0x91,
|
||||
0x1c, 0xdb, 0x89, 0xc1, 0x0c, 0xdf, 0xd3, 0x0b, 0x3b, 0xcb, 0x7f, 0x66, 0x4f, 0x66, 0xf2, 0x7f, 0x76, 0x5c, 0x8e, 0x5f,
|
||||
0x7a, 0x30, 0xab, 0xf6, 0x7e, 0x45, 0xfe, 0x67, 0x46, 0xe4, 0x9e, 0x9d, 0xff, 0x38, 0xd9, 0x57, 0x31, 0x31, 0xbe, 0xb9,
|
||||
0xb3, 0xcf, 0x30, 0xd3, 0x4f, 0xeb, 0x7b, 0x1c, 0xde, 0xd3, 0xff, 0x8f, 0xd6, 0xed, 0xbf, 0xfc, 0xcf, 0x5d, 0xff, 0xbf,
|
||||
0x2d, 0xff, 0xb1, 0xfd, 0x58, 0xc5, 0x85, 0x33, 0x56, 0xfe, 0xe7, 0xf6, 0xf0, 0x79, 0x8f, 0x23, 0x16, 0x5d, 0xbf, 0x74,
|
||||
0xcd, 0x7f, 0xee, 0xd3, 0x7d, 0xb1, 0xfd, 0x8f, 0x1b, 0x8f, 0x8f, 0xfc, 0xaf, 0xd8, 0x9b, 0x23, 0x77, 0xd8, 0x66, 0xe7,
|
||||
0x2f, 0xc8, 0xbf, 0xfc, 0xcb, 0x7f, 0xef, 0xfe, 0x7f, 0x0c, 0x8e, 0xdc, 0xc6, 0xe3, 0xc7, 0xff, 0xe2, 0x52, 0x6f, 0x69,
|
||||
0x7e, 0xb6, 0xe0, 0x78, 0x9f, 0x2b, 0xf7, 0x6e, 0xf9, 0xd9, 0x75, 0x4f, 0xb9, 0xfe, 0xdf, 0x39, 0x93, 0xf2, 0x28, 0x99,
|
||||
0x87, 0xb2, 0x7e, 0xfe, 0xdf, 0x33, 0xe7, 0x28, 0x77, 0xcf, 0x3f, 0xb0, 0x7a, 0x95, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0x65, 0x0d, 0x4d, 0x94, 0xad, 0x7b, 0x8c, 0x16, 0x95, 0xe7, 0xf7, 0xd4, 0x58,
|
||||
0xbf, 0xb6, 0x87, 0xaa, 0xde, 0x71, 0xec, 0x59, 0x02, 0x63, 0xeb, 0x30, 0x73, 0x2b, 0xff, 0x56, 0xaf, 0x6e, 0x9b, 0x59,
|
||||
0xdd, 0x58, 0xb3, 0x65, 0x15, 0xb5, 0x2d, 0xee, 0x49, 0xc7, 0xca, 0x75, 0xe2, 0x71, 0x69, 0x75, 0x70, 0x6d, 0x92, 0x56,
|
||||
0xaf, 0xd8, 0xce, 0xac, 0x7d, 0xdf, 0x99, 0xff, 0xb1, 0x33, 0x70, 0xfc, 0x73, 0x46, 0x62, 0x35, 0x55, 0x6d, 0x0d, 0x98,
|
||||
0x63, 0xe9, 0xb9, 0x19, 0x8b, 0xd6, 0x90, 0x8d, 0xef, 0x83, 0x3d, 0xe9, 0x90, 0xff, 0x2f, 0xe7, 0x3f, 0x57, 0x23, 0x7b,
|
||||
0xc7, 0xb3, 0x50, 0xe4, 0x5f, 0xfe, 0xe5, 0xff, 0xad, 0xf9, 0x8f, 0xe2, 0xfe, 0x77, 0xbe, 0x5a, 0x47, 0xcd, 0x95, 0x55,
|
||||
0x6d, 0x4a, 0xe4, 0x5f, 0xfe, 0x7f, 0xef, 0x6d, 0xc7, 0xc5, 0x56, 0x6c, 0xa4, 0xc5, 0xdb, 0x59, 0xb3, 0x64, 0x5f, 0x15,
|
||||
0xad, 0xd1, 0x6f, 0x93, 0x28, 0x4c, 0xf0, 0x57, 0xf2, 0x9f, 0xaf, 0x7b, 0xbe, 0x67, 0xdc, 0x2b, 0xb3, 0xe5, 0x99, 0xda,
|
||||
0x57, 0xf5, 0xf9, 0x3f, 0x7b, 0x1e, 0x42, 0xe6, 0xfb, 0xe9, 0x5b, 0xf9, 0x1f, 0xfd, 0x6c, 0xf2, 0x7f, 0x6c, 0x7e, 0xb6,
|
||||
0xcc, 0xfd, 0x35, 0x16, 0x23, 0xd9, 0xd2, 0x57, 0x6d, 0x75, 0xa4, 0x46, 0xdb, 0xaa, 0x7e, 0x9e, 0xab, 0xd2, 0xf8, 0xde,
|
||||
0xfc, 0x47, 0xc1, 0x7d, 0xae, 0xb9, 0x56, 0x52, 0xfe, 0xe5, 0xff, 0x98, 0xac, 0xc0, 0xdb, 0x3d, 0xff, 0x2b, 0xae, 0xbf,
|
||||
0x2b, 0x9f, 0xe6, 0xfa, 0xcc, 0xf6, 0xff, 0x59, 0xf7, 0xff, 0xbe, 0x92, 0xff, 0xb3, 0x63, 0x79, 0x77, 0xfe, 0x3b, 0xd5,
|
||||
0x4c, 0xcd, 0x8c, 0x30, 0xce, 0xfc, 0x9b, 0x8e, 0xf9, 0xdf, 0x35, 0x9f, 0x47, 0xfe, 0x77, 0xe5, 0xff, 0xe7, 0xa7, 0x8d,
|
||||
0xcb, 0x7f, 0xaf, 0xfc, 0xaf, 0xeb, 0xff, 0x3f, 0x3b, 0xff, 0xeb, 0x7a, 0x5f, 0xab, 0xfb, 0x73, 0xb5, 0x5b, 0x9e, 0x99,
|
||||
0x01, 0xf7, 0xdb, 0xfc, 0xbb, 0x48, 0x57, 0x6d, 0xaf, 0x98, 0x87, 0x37, 0x33, 0x3b, 0x68, 0xf7, 0x95, 0x41, 0xf5, 0xbf,
|
||||
0xa9, 0x1f, 0xb3, 0xe8, 0x9b, 0x7f, 0x78, 0x46, 0xfe, 0xbf, 0xb0, 0xaf, 0x71, 0x3c, 0xee, 0x69, 0x59, 0x57, 0xfe, 0x3e,
|
||||
0xce, 0x37, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0xd3, 0x2a, 0xac, 0xaa, 0xba, 0x8d, 0x3b,
|
||||
0xab, 0x65, 0xe4, 0xd6, 0xf9, 0xc5, 0xe5, 0xba, 0x2e, 0x99, 0x55, 0xe4, 0x23, 0x6b, 0xf9, 0x6a, 0xd6, 0x34, 0xe6, 0xcf,
|
||||
0x81, 0x48, 0xad, 0x96, 0x3b, 0x3f, 0x53, 0x32, 0x35, 0xec, 0xd7, 0xcd, 0xb6, 0xff, 0xbd, 0x7e, 0x43, 0xbe, 0x92, 0xc8,
|
||||
0xaa, 0xf5, 0x05, 0x75, 0xf5, 0x9f, 0x8e, 0x82, 0xd5, 0x8a, 0xd9, 0x35, 0xf4, 0xf7, 0xe6, 0x7f, 0x74, 0xf5, 0xdb, 0xf5,
|
||||
0x9f, 0x55, 0xd4, 0x5b, 0x89, 0xc4, 0xca, 0xbc, 0xca, 0xfc, 0x57, 0x9c, 0xe3, 0x51, 0xf6, 0xbe, 0xb1, 0xb8, 0x4e, 0xc1,
|
||||
0x95, 0x56, 0xe2, 0xd9, 0x6b, 0xa2, 0xe2, 0xd5, 0xf9, 0xaf, 0xad, 0x96, 0x5b, 0xff, 0x9d, 0x90, 0xaf, 0x4f, 0x70, 0x5f,
|
||||
0xfe, 0xff, 0x6e, 0x57, 0x75, 0xfe, 0x33, 0xef, 0x5b, 0x53, 0xd9, 0x6a, 0x2e, 0xff, 0x3d, 0x56, 0xf6, 0xc5, 0xf2, 0x9e,
|
||||
0x47, 0x26, 0xff, 0x63, 0xfd, 0xb6, 0x15, 0xf9, 0xcf, 0x57, 0xe6, 0x39, 0x36, 0x65, 0xfd, 0x28, 0x4e, 0xf9, 0xfa, 0xfc,
|
||||
0xd7, 0x9f, 0x69, 0xf1, 0x9f, 0xff, 0xbb, 0xac, 0xb6, 0x7d, 0x4b, 0xfe, 0x73, 0xd5, 0x69, 0x66, 0xf3, 0x9f, 0xbd, 0xe2,
|
||||
0xbd, 0xbb, 0xfd, 0x5f, 0x73, 0x4d, 0xb0, 0x3e, 0xff, 0x91, 0xaa, 0x0c, 0xde, 0x27, 0xff, 0xb1, 0x20, 0xb9, 0xf2, 0x9f,
|
||||
0x6d, 0x03, 0xdf, 0x90, 0xff, 0xea, 0xe7, 0x7c, 0x74, 0xc8, 0x7f, 0x6e, 0xc4, 0x2b, 0x4a, 0x73, 0x1a, 0xed, 0xdb, 0xff,
|
||||
0x63, 0xdb, 0xf8, 0x5f, 0xff, 0xfc, 0x47, 0x49, 0xbf, 0xf0, 0xce, 0xfc, 0xd7, 0x57, 0xcb, 0xcd, 0x56, 0x0d, 0xbc, 0x3e,
|
||||
0xd6, 0xd7, 0xa7, 0xfd, 0xaf, 0xbf, 0x1e, 0x5e, 0xd1, 0xfe, 0x1f, 0x0b, 0xee, 0x52, 0xac, 0xbf, 0xaa, 0xee, 0x9f, 0xff,
|
||||
0xaa, 0xeb, 0xc2, 0xcc, 0x73, 0x93, 0x46, 0xef, 0xff, 0xc5, 0xe9, 0x59, 0x3c, 0x7a, 0xe7, 0x68, 0x3c, 0x4f, 0x31, 0xf8,
|
||||
0xf4, 0xa2, 0xfe, 0xd7, 0xff, 0x95, 0xed, 0xff, 0x9a, 0x51, 0xef, 0xae, 0xa3, 0xe9, 0xd7, 0x9e, 0x2f, 0xde, 0x63, 0x8b,
|
||||
0xf3, 0x4f, 0xdc, 0x8a, 0xed, 0x57, 0x56, 0x7d, 0x8e, 0xf1, 0xfc, 0x67, 0x5f, 0x93, 0xff, 0x8a, 0x8a, 0xd3, 0xf5, 0xed,
|
||||
0xe1, 0xf7, 0xe6, 0xbc, 0xcc, 0xdc, 0x75, 0xef, 0xb1, 0xb5, 0xd5, 0xe7, 0xc5, 0x3b, 0xf2, 0x5f, 0xf7, 0xd9, 0x63, 0xc9,
|
||||
0xb7, 0x4a, 0xa6, 0x96, 0x77, 0x2c, 0x9f, 0x0f, 0x23, 0xff, 0xcf, 0xcd, 0x7f, 0xdc, 0x70, 0xcf, 0xf0, 0x58, 0x3c, 0x1e,
|
||||
0xdd, 0x61, 0x0f, 0xef, 0xcd, 0x3f, 0xfd, 0xce, 0x88, 0xee, 0xf9, 0x5f, 0x3f, 0x2f, 0xf4, 0xcb, 0xed, 0x81, 0x2a, 0xf9,
|
||||
0x3c, 0xf1, 0x5a, 0x56, 0xfe, 0x73, 0xfd, 0x96, 0xd9, 0xf9, 0xff, 0x20, 0xff, 0xdf, 0xdd, 0xeb, 0xd0, 0x7f, 0x76, 0x03,
|
||||
0xf2, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xfb, 0x67, 0xbb, 0x45, 0x6a, 0x7d, 0x5b, 0x0c, 0x56,
|
||||
0x32, 0x88, 0x74, 0xa5, 0xf8, 0x6c, 0x7d, 0x8c, 0x18, 0x5c, 0xf7, 0x35, 0x5f, 0x37, 0xf8, 0xfa, 0xf3, 0x15, 0x66, 0xd6,
|
||||
0x0f, 0xae, 0x3f, 0x8e, 0x75, 0x15, 0xd6, 0xeb, 0x8f, 0x52, 0xe6, 0xef, 0x47, 0x79, 0xed, 0xb5, 0xfe, 0x99, 0x99, 0xdf,
|
||||
0xcf, 0x99, 0x95, 0xbe, 0xb5, 0x67, 0xd4, 0xb5, 0x63, 0x5b, 0xb7, 0xba, 0x33, 0x26, 0x92, 0x3e, 0x3e, 0x4f, 0xfb, 0xf7,
|
||||
0xaa, 0x9f, 0x5d, 0x8f, 0x63, 0x2e, 0x4b, 0x51, 0xba, 0x06, 0x37, 0xf7, 0xd7, 0x9f, 0xb6, 0xaf, 0xaf, 0x57, 0x01, 0xd8,
|
||||
0xdd, 0x5f, 0xc8, 0x3f, 0x35, 0x28, 0x6e, 0x9f, 0x8b, 0xbf, 0xae, 0xa2, 0x4e, 0x5d, 0xad, 0xe2, 0xbb, 0x8f, 0xe3, 0x71,
|
||||
0xfa, 0x0c, 0x93, 0x68, 0xb8, 0xbe, 0xe5, 0xac, 0xff, 0x18, 0x2d, 0xf7, 0x75, 0x5c, 0xee, 0x23, 0xe6, 0xf3, 0x9f, 0x7f,
|
||||
0x3e, 0x53, 0x14, 0x57, 0xe6, 0xcd, 0x57, 0xc7, 0xac, 0xde, 0xfa, 0x7c, 0xfb, 0x9f, 0xb9, 0x52, 0x88, 0xe5, 0x9f, 0xaa,
|
||||
0xf6, 0x3b, 0x39, 0x4e, 0x6a, 0xb9, 0xae, 0x3e, 0x2b, 0x56, 0xbc, 0x12, 0x1b, 0xce, 0xad, 0xdc, 0xf5, 0xde, 0xb5, 0x33,
|
||||
0x64, 0x26, 0xff, 0x7d, 0x8f, 0xcd, 0xd1, 0xe6, 0x95, 0xdd, 0xf9, 0x7f, 0xee, 0x2b, 0xef, 0xc9, 0x7f, 0x9f, 0xb3, 0xef,
|
||||
0xb7, 0xcf, 0x33, 0xfb, 0xac, 0xc2, 0x0e, 0x47, 0xe0, 0xac, 0x4e, 0xec, 0x5b, 0xf3, 0x1f, 0x3f, 0x8e, 0x0c, 0xf6, 0xff,
|
||||
0x4e, 0xfe, 0xb9, 0x5f, 0xf0, 0xb4, 0xfc, 0x57, 0xb6, 0xcb, 0x15, 0x6d, 0xf9, 0xde, 0x6b, 0x66, 0xed, 0xbf, 0xf6, 0xff,
|
||||
0xdb, 0xf9, 0xbf, 0xff, 0x2a, 0x6c, 0x6f, 0x66, 0xfa, 0xed, 0xb3, 0x3e, 0xf9, 0x1f, 0x19, 0xf3, 0x92, 0xff, 0xb7, 0xe7,
|
||||
0xff, 0x09, 0xdf, 0x4d, 0xb3, 0xf7, 0xff, 0xde, 0x31, 0xfe, 0x57, 0xf5, 0x8a, 0xf6, 0x7f, 0x6e, 0x8c, 0xfd, 0xee, 0x6d,
|
||||
0xcb, 0x1f, 0xf3, 0xb7, 0x1c, 0x85, 0xd1, 0x3e, 0x80, 0xfe, 0xbf, 0xfc, 0xbf, 0x27, 0xff, 0x47, 0x7a, 0xf6, 0xc1, 0xb3,
|
||||
0xae, 0x33, 0x46, 0x8e, 0xc7, 0x73, 0xf2, 0x5f, 0x79, 0xc7, 0xee, 0x29, 0xe3, 0x7f, 0x4f, 0xfb, 0x66, 0x78, 0x63, 0xfe,
|
||||
0xef, 0xbd, 0xd7, 0xda, 0x63, 0xe6, 0xef, 0x33, 0xfb, 0x32, 0x4f, 0xce, 0xff, 0xb3, 0xfb, 0x64, 0xc7, 0x6d, 0x57, 0x85,
|
||||
0x51, 0xb8, 0xa7, 0x79, 0x46, 0xfe, 0x63, 0x53, 0xfe, 0x47, 0xc6, 0x06, 0xde, 0x9d, 0xff, 0xf1, 0xd6, 0x2a, 0x6e, 0x1f,
|
||||
0x63, 0x96, 0xff, 0xbb, 0xf3, 0xbf, 0x7f, 0xeb, 0x77, 0xf5, 0xc4, 0x62, 0x49, 0xd2, 0xc7, 0x8f, 0xc9, 0x13, 0xfb, 0xa4,
|
||||
0x3b, 0xb7, 0x4d, 0xfe, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xef, 0xcc, 0x00, 0x1e, 0x7b, 0xb5,
|
||||
0x43, 0x05, 0xfd, 0x23, 0x5d, 0x6d, 0xbd, 0xee, 0xf3, 0x1e, 0x89, 0xaa, 0xee, 0x99, 0x6d, 0xe8, 0x5c, 0x41, 0xdf, 0xac,
|
||||
0xdb, 0xb7, 0x7e, 0x03, 0xf4, 0xae, 0xa0, 0x7f, 0x5e, 0xe5, 0x63, 0xfd, 0xe7, 0xad, 0x9c, 0x3f, 0xdf, 0xbb, 0x82, 0x7e,
|
||||
0xbf, 0xb5, 0xab, 0xf4, 0xfb, 0x26, 0xd9, 0x59, 0x41, 0x7f, 0xbc, 0xbf, 0x71, 0x6c, 0xdc, 0xae, 0x6c, 0x35, 0x83, 0xae,
|
||||
0x15, 0xf4, 0xbb, 0xaf, 0x05, 0xe3, 0xfe, 0xb5, 0x59, 0x63, 0xcf, 0xb4, 0xa8, 0xaa, 0xa0, 0xf1, 0xb4, 0x0a, 0xfa, 0x67,
|
||||
0x19, 0x7b, 0x52, 0x9d, 0x6c, 0xf9, 0xb7, 0xfe, 0xf7, 0xbe, 0xfc, 0xf7, 0xad, 0x93, 0x91, 0xad, 0x52, 0xd3, 0xbb, 0x82,
|
||||
0xa6, 0xfc, 0xcb, 0xbf, 0xfc, 0xaf, 0xaa, 0x91, 0x20, 0xff, 0x3c, 0x3d, 0xff, 0x3b, 0x2b, 0xe8, 0xa8, 0xa0, 0xb9, 0xbb,
|
||||
0x22, 0xd0, 0x21, 0xff, 0xae, 0xff, 0x1f, 0xf1, 0x04, 0x3d, 0xf9, 0x5f, 0xf3, 0x8a, 0xfc, 0x7f, 0xfd, 0xde, 0x9f, 0x0a,
|
||||
0xda, 0x2b, 0xf3, 0x1f, 0x4d, 0xc7, 0xff, 0xf6, 0xdf, 0xf1, 0xe1, 0x89, 0xf9, 0xd7, 0xff, 0xcf, 0xe7, 0xe2, 0xfe, 0x0a,
|
||||
0x9a, 0xf9, 0x34, 0xcb, 0xbf, 0xfe, 0x7f, 0xc5, 0xfc, 0x9f, 0x9a, 0xb6, 0x47, 0x05, 0xcd, 0xb9, 0x6d, 0x93, 0x7f, 0xd0,
|
||||
0x2b, 0xd4, 0xff, 0x07, 0xbd, 0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf6, 0xf9, 0xf3, 0x9f, 0xfd, 0x00, 0xf2, 0x0f, 0x7c, 0x2e, 0xff, 0xff, 0x00 };
|
||||
|
||||
// Font glyphs rectangles data (on atlas)
|
||||
static const Rectangle terminalFontRecs[189] = {
|
||||
{ 4, 4, 4 , 16 },
|
||||
{ 16, 4, 1 , 11 },
|
||||
{ 25, 4, 3 , 3 },
|
||||
{ 36, 4, 6 , 11 },
|
||||
{ 50, 4, 5 , 11 },
|
||||
{ 63, 4, 5 , 11 },
|
||||
{ 76, 4, 5 , 11 },
|
||||
{ 89, 4, 1 , 2 },
|
||||
{ 98, 4, 2 , 13 },
|
||||
{ 108, 4, 2 , 13 },
|
||||
{ 118, 4, 3 , 3 },
|
||||
{ 129, 4, 5 , 5 },
|
||||
{ 142, 4, 1 , 3 },
|
||||
{ 151, 4, 5 , 1 },
|
||||
{ 164, 4, 1 , 1 },
|
||||
{ 173, 4, 6 , 12 },
|
||||
{ 187, 4, 5 , 11 },
|
||||
{ 200, 4, 2 , 11 },
|
||||
{ 210, 4, 5 , 11 },
|
||||
{ 223, 4, 5 , 11 },
|
||||
{ 236, 4, 5 , 11 },
|
||||
{ 249, 4, 5 , 11 },
|
||||
{ 262, 4, 5 , 11 },
|
||||
{ 275, 4, 5 , 11 },
|
||||
{ 288, 4, 5 , 11 },
|
||||
{ 301, 4, 5 , 11 },
|
||||
{ 314, 4, 1 , 8 },
|
||||
{ 323, 4, 1 , 10 },
|
||||
{ 332, 4, 4 , 5 },
|
||||
{ 344, 4, 5 , 3 },
|
||||
{ 357, 4, 4 , 5 },
|
||||
{ 369, 4, 5 , 11 },
|
||||
{ 382, 4, 11 , 11 },
|
||||
{ 401, 4, 5 , 11 },
|
||||
{ 414, 4, 5 , 11 },
|
||||
{ 427, 4, 5 , 11 },
|
||||
{ 440, 4, 5 , 11 },
|
||||
{ 453, 4, 5 , 11 },
|
||||
{ 466, 4, 5 , 11 },
|
||||
{ 479, 4, 5 , 11 },
|
||||
{ 492, 4, 5 , 11 },
|
||||
{ 4, 28, 1 , 11 },
|
||||
{ 13, 28, 5 , 11 },
|
||||
{ 26, 28, 5 , 11 },
|
||||
{ 39, 28, 5 , 11 },
|
||||
{ 52, 28, 7 , 11 },
|
||||
{ 67, 28, 5 , 11 },
|
||||
{ 80, 28, 5 , 11 },
|
||||
{ 93, 28, 5 , 11 },
|
||||
{ 106, 28, 5 , 13 },
|
||||
{ 119, 28, 5 , 11 },
|
||||
{ 132, 28, 5 , 11 },
|
||||
{ 145, 28, 5 , 11 },
|
||||
{ 158, 28, 5 , 11 },
|
||||
{ 171, 28, 5 , 11 },
|
||||
{ 184, 28, 7 , 11 },
|
||||
{ 199, 28, 5 , 11 },
|
||||
{ 212, 28, 5 , 11 },
|
||||
{ 225, 28, 5 , 11 },
|
||||
{ 238, 28, 2 , 13 },
|
||||
{ 248, 28, 6 , 12 },
|
||||
{ 262, 28, 2 , 13 },
|
||||
{ 272, 28, 5 , 4 },
|
||||
{ 285, 28, 5 , 1 },
|
||||
{ 298, 28, 2 , 2 },
|
||||
{ 308, 28, 5 , 8 },
|
||||
{ 321, 28, 5 , 11 },
|
||||
{ 334, 28, 5 , 8 },
|
||||
{ 347, 28, 5 , 11 },
|
||||
{ 360, 28, 5 , 8 },
|
||||
{ 373, 28, 4 , 11 },
|
||||
{ 385, 28, 5 , 10 },
|
||||
{ 398, 28, 5 , 11 },
|
||||
{ 411, 28, 1 , 11 },
|
||||
{ 420, 28, 1 , 13 },
|
||||
{ 429, 28, 5 , 11 },
|
||||
{ 442, 28, 1 , 11 },
|
||||
{ 451, 28, 7 , 8 },
|
||||
{ 466, 28, 5 , 8 },
|
||||
{ 479, 28, 5 , 8 },
|
||||
{ 492, 28, 5 , 10 },
|
||||
{ 4, 52, 5 , 10 },
|
||||
{ 17, 52, 4 , 8 },
|
||||
{ 29, 52, 5 , 8 },
|
||||
{ 42, 52, 3 , 11 },
|
||||
{ 53, 52, 5 , 8 },
|
||||
{ 66, 52, 5 , 8 },
|
||||
{ 79, 52, 7 , 8 },
|
||||
{ 94, 52, 5 , 8 },
|
||||
{ 107, 52, 5 , 10 },
|
||||
{ 120, 52, 5 , 8 },
|
||||
{ 133, 52, 3 , 13 },
|
||||
{ 144, 52, 1 , 15 },
|
||||
{ 153, 52, 3 , 13 },
|
||||
{ 164, 52, 5 , 3 },
|
||||
{ 177, 52, 1 , 11 },
|
||||
{ 186, 52, 5 , 11 },
|
||||
{ 199, 52, 5 , 10 },
|
||||
{ 212, 52, 5 , 10 },
|
||||
{ 225, 52, 5 , 10 },
|
||||
{ 238, 52, 0 , 0 },
|
||||
{ 246, 52, 0 , 0 },
|
||||
{ 254, 52, 0 , 0 },
|
||||
{ 262, 52, 7 , 8 },
|
||||
{ 277, 52, 0 , 0 },
|
||||
{ 285, 52, 0 , 0 },
|
||||
{ 293, 52, 5 , 3 },
|
||||
{ 306, 52, 7 , 8 },
|
||||
{ 321, 52, 5 , 1 },
|
||||
{ 334, 52, 3 , 3 },
|
||||
{ 345, 52, 5 , 7 },
|
||||
{ 358, 52, 0 , 0 },
|
||||
{ 366, 52, 0 , 0 },
|
||||
{ 374, 52, 0 , 0 },
|
||||
{ 382, 52, 5 , 10 },
|
||||
{ 395, 52, 7 , 11 },
|
||||
{ 410, 52, 1 , 1 },
|
||||
{ 419, 52, 0 , 0 },
|
||||
{ 427, 52, 0 , 0 },
|
||||
{ 435, 52, 0 , 0 },
|
||||
{ 443, 52, 0 , 0 },
|
||||
{ 451, 52, 0 , 0 },
|
||||
{ 459, 52, 0 , 0 },
|
||||
{ 467, 52, 5 , 13 },
|
||||
{ 480, 52, 5 , 11 },
|
||||
{ 493, 52, 5 , 14 },
|
||||
{ 4, 76, 5 , 14 },
|
||||
{ 17, 76, 5 , 14 },
|
||||
{ 30, 76, 5 , 14 },
|
||||
{ 43, 76, 5 , 13 },
|
||||
{ 56, 76, 5 , 13 },
|
||||
{ 69, 76, 9 , 11 },
|
||||
{ 86, 76, 5 , 13 },
|
||||
{ 99, 76, 5 , 14 },
|
||||
{ 112, 76, 5 , 14 },
|
||||
{ 125, 76, 5 , 14 },
|
||||
{ 138, 76, 5 , 13 },
|
||||
{ 151, 76, 2 , 14 },
|
||||
{ 161, 76, 2 , 14 },
|
||||
{ 171, 76, 3 , 14 },
|
||||
{ 182, 76, 3 , 13 },
|
||||
{ 193, 76, 5 , 11 },
|
||||
{ 206, 76, 5 , 14 },
|
||||
{ 219, 76, 5 , 14 },
|
||||
{ 232, 76, 5 , 14 },
|
||||
{ 245, 76, 5 , 14 },
|
||||
{ 258, 76, 5 , 14 },
|
||||
{ 271, 76, 5 , 13 },
|
||||
{ 284, 76, 5 , 5 },
|
||||
{ 297, 76, 5 , 13 },
|
||||
{ 310, 76, 5 , 14 },
|
||||
{ 323, 76, 5 , 14 },
|
||||
{ 336, 76, 5 , 14 },
|
||||
{ 349, 76, 5 , 13 },
|
||||
{ 362, 76, 5 , 14 },
|
||||
{ 375, 76, 5 , 11 },
|
||||
{ 388, 76, 5 , 11 },
|
||||
{ 401, 76, 5 , 11 },
|
||||
{ 414, 76, 5 , 11 },
|
||||
{ 427, 76, 5 , 11 },
|
||||
{ 440, 76, 5 , 11 },
|
||||
{ 453, 76, 5 , 10 },
|
||||
{ 466, 76, 5 , 10 },
|
||||
{ 479, 76, 9 , 8 },
|
||||
{ 496, 76, 5 , 10 },
|
||||
{ 4, 100, 5 , 11 },
|
||||
{ 17, 100, 5 , 11 },
|
||||
{ 30, 100, 5 , 11 },
|
||||
{ 43, 100, 5 , 10 },
|
||||
{ 56, 100, 2 , 11 },
|
||||
{ 66, 100, 2 , 11 },
|
||||
{ 76, 100, 3 , 11 },
|
||||
{ 87, 100, 3 , 10 },
|
||||
{ 98, 100, 5 , 11 },
|
||||
{ 111, 100, 5 , 11 },
|
||||
{ 124, 100, 5 , 11 },
|
||||
{ 137, 100, 5 , 11 },
|
||||
{ 150, 100, 5 , 11 },
|
||||
{ 163, 100, 5 , 11 },
|
||||
{ 176, 100, 5 , 10 },
|
||||
{ 189, 100, 5 , 5 },
|
||||
{ 202, 100, 5 , 10 },
|
||||
{ 215, 100, 5 , 11 },
|
||||
{ 228, 100, 5 , 11 },
|
||||
{ 241, 100, 5 , 11 },
|
||||
{ 254, 100, 5 , 10 },
|
||||
{ 267, 100, 5 , 13 },
|
||||
{ 280, 100, 4 , 8 },
|
||||
{ 292, 100, 5 , 12 },
|
||||
};
|
||||
|
||||
// Font glyphs info data
|
||||
// NOTE: No glyphs.image data provided
|
||||
static const GlyphInfo terminalFontGlyphs[189] = {
|
||||
{ 32, 0, 14, 4, { 0 }},
|
||||
{ 33, 1, 3, 3, { 0 }},
|
||||
{ 34, 1, 3, 5, { 0 }},
|
||||
{ 35, 1, 3, 8, { 0 }},
|
||||
{ 36, 1, 3, 7, { 0 }},
|
||||
{ 37, 1, 3, 7, { 0 }},
|
||||
{ 38, 1, 3, 7, { 0 }},
|
||||
{ 39, 1, 3, 3, { 0 }},
|
||||
{ 40, 1, 2, 4, { 0 }},
|
||||
{ 41, 1, 2, 4, { 0 }},
|
||||
{ 42, 1, 3, 5, { 0 }},
|
||||
{ 43, 1, 7, 7, { 0 }},
|
||||
{ 44, 1, 13, 3, { 0 }},
|
||||
{ 45, 1, 9, 7, { 0 }},
|
||||
{ 46, 1, 13, 3, { 0 }},
|
||||
{ 47, 1, 2, 8, { 0 }},
|
||||
{ 48, 1, 3, 7, { 0 }},
|
||||
{ 49, 1, 3, 4, { 0 }},
|
||||
{ 50, 1, 3, 7, { 0 }},
|
||||
{ 51, 1, 3, 7, { 0 }},
|
||||
{ 52, 1, 3, 7, { 0 }},
|
||||
{ 53, 1, 3, 7, { 0 }},
|
||||
{ 54, 1, 3, 7, { 0 }},
|
||||
{ 55, 1, 3, 7, { 0 }},
|
||||
{ 56, 1, 3, 7, { 0 }},
|
||||
{ 57, 1, 3, 7, { 0 }},
|
||||
{ 58, 1, 6, 3, { 0 }},
|
||||
{ 59, 1, 6, 3, { 0 }},
|
||||
{ 60, 1, 7, 6, { 0 }},
|
||||
{ 61, 1, 8, 7, { 0 }},
|
||||
{ 62, 1, 7, 6, { 0 }},
|
||||
{ 63, 1, 3, 7, { 0 }},
|
||||
{ 64, 2, 3, 15, { 0 }},
|
||||
{ 65, 1, 3, 7, { 0 }},
|
||||
{ 66, 1, 3, 7, { 0 }},
|
||||
{ 67, 1, 3, 7, { 0 }},
|
||||
{ 68, 1, 3, 7, { 0 }},
|
||||
{ 69, 1, 3, 7, { 0 }},
|
||||
{ 70, 1, 3, 7, { 0 }},
|
||||
{ 71, 1, 3, 7, { 0 }},
|
||||
{ 72, 1, 3, 7, { 0 }},
|
||||
{ 73, 1, 3, 3, { 0 }},
|
||||
{ 74, 1, 3, 7, { 0 }},
|
||||
{ 75, 1, 3, 7, { 0 }},
|
||||
{ 76, 1, 3, 7, { 0 }},
|
||||
{ 77, 1, 3, 9, { 0 }},
|
||||
{ 78, 1, 3, 7, { 0 }},
|
||||
{ 79, 1, 3, 7, { 0 }},
|
||||
{ 80, 1, 3, 7, { 0 }},
|
||||
{ 81, 1, 3, 7, { 0 }},
|
||||
{ 82, 1, 3, 7, { 0 }},
|
||||
{ 83, 1, 3, 7, { 0 }},
|
||||
{ 84, 1, 3, 7, { 0 }},
|
||||
{ 85, 1, 3, 7, { 0 }},
|
||||
{ 86, 1, 3, 7, { 0 }},
|
||||
{ 87, 1, 3, 9, { 0 }},
|
||||
{ 88, 1, 3, 7, { 0 }},
|
||||
{ 89, 1, 3, 7, { 0 }},
|
||||
{ 90, 1, 3, 7, { 0 }},
|
||||
{ 91, 1, 2, 4, { 0 }},
|
||||
{ 92, 1, 2, 8, { 0 }},
|
||||
{ 93, 1, 2, 4, { 0 }},
|
||||
{ 94, 1, 3, 7, { 0 }},
|
||||
{ 95, 1, 15, 7, { 0 }},
|
||||
{ 96, 1, 0, 4, { 0 }},
|
||||
{ 97, 1, 6, 7, { 0 }},
|
||||
{ 98, 1, 3, 7, { 0 }},
|
||||
{ 99, 1, 6, 7, { 0 }},
|
||||
{ 100, 1, 3, 7, { 0 }},
|
||||
{ 101, 1, 6, 7, { 0 }},
|
||||
{ 102, 1, 3, 6, { 0 }},
|
||||
{ 103, 1, 6, 7, { 0 }},
|
||||
{ 104, 1, 3, 7, { 0 }},
|
||||
{ 105, 1, 3, 3, { 0 }},
|
||||
{ 106, 1, 3, 3, { 0 }},
|
||||
{ 107, 1, 3, 7, { 0 }},
|
||||
{ 108, 1, 3, 3, { 0 }},
|
||||
{ 109, 1, 6, 9, { 0 }},
|
||||
{ 110, 1, 6, 7, { 0 }},
|
||||
{ 111, 1, 6, 7, { 0 }},
|
||||
{ 112, 1, 6, 7, { 0 }},
|
||||
{ 113, 1, 6, 7, { 0 }},
|
||||
{ 114, 1, 6, 6, { 0 }},
|
||||
{ 115, 1, 6, 7, { 0 }},
|
||||
{ 116, 1, 3, 5, { 0 }},
|
||||
{ 117, 1, 6, 7, { 0 }},
|
||||
{ 118, 1, 6, 7, { 0 }},
|
||||
{ 119, 1, 6, 9, { 0 }},
|
||||
{ 120, 1, 6, 7, { 0 }},
|
||||
{ 121, 1, 6, 7, { 0 }},
|
||||
{ 122, 1, 6, 7, { 0 }},
|
||||
{ 123, 1, 2, 5, { 0 }},
|
||||
{ 124, 1, 1, 3, { 0 }},
|
||||
{ 125, 1, 2, 5, { 0 }},
|
||||
{ 126, 1, 8, 7, { 0 }},
|
||||
{ 161, 1, 3, 3, { 0 }},
|
||||
{ 162, 1, 3, 7, { 0 }},
|
||||
{ 163, 1, 3, 7, { 0 }},
|
||||
{ 8364, 1, 3, 7, { 0 }},
|
||||
{ 165, 1, 3, 7, { 0 }},
|
||||
{ 352, 0, 14, 4, { 0 }},
|
||||
{ 167, 0, 14, 4, { 0 }},
|
||||
{ 353, 0, 14, 4, { 0 }},
|
||||
{ 169, 1, 3, 9, { 0 }},
|
||||
{ 170, 0, 14, 4, { 0 }},
|
||||
{ 171, 0, 14, 4, { 0 }},
|
||||
{ 172, 1, 8, 7, { 0 }},
|
||||
{ 174, 1, 3, 9, { 0 }},
|
||||
{ 175, 1, 1, 7, { 0 }},
|
||||
{ 176, 1, 0, 5, { 0 }},
|
||||
{ 177, 1, 7, 7, { 0 }},
|
||||
{ 178, 0, 14, 4, { 0 }},
|
||||
{ 179, 0, 14, 4, { 0 }},
|
||||
{ 381, 0, 14, 4, { 0 }},
|
||||
{ 181, 1, 6, 7, { 0 }},
|
||||
{ 182, 1, 3, 9, { 0 }},
|
||||
{ 183, 1, 8, 3, { 0 }},
|
||||
{ 382, 0, 14, 4, { 0 }},
|
||||
{ 185, 0, 14, 4, { 0 }},
|
||||
{ 186, 0, 14, 4, { 0 }},
|
||||
{ 187, 0, 14, 4, { 0 }},
|
||||
{ 338, 0, 14, 4, { 0 }},
|
||||
{ 339, 0, 14, 4, { 0 }},
|
||||
{ 376, 1, 1, 7, { 0 }},
|
||||
{ 191, 1, 3, 7, { 0 }},
|
||||
{ 192, 1, 0, 7, { 0 }},
|
||||
{ 193, 1, 0, 7, { 0 }},
|
||||
{ 194, 1, 0, 7, { 0 }},
|
||||
{ 195, 1, 0, 7, { 0 }},
|
||||
{ 196, 1, 1, 7, { 0 }},
|
||||
{ 197, 1, 1, 7, { 0 }},
|
||||
{ 198, 1, 3, 11, { 0 }},
|
||||
{ 199, 1, 3, 7, { 0 }},
|
||||
{ 200, 1, 0, 7, { 0 }},
|
||||
{ 201, 1, 0, 7, { 0 }},
|
||||
{ 202, 1, 0, 7, { 0 }},
|
||||
{ 203, 1, 1, 7, { 0 }},
|
||||
{ 204, 0, 0, 3, { 0 }},
|
||||
{ 205, 1, 0, 3, { 0 }},
|
||||
{ 206, 0, 0, 3, { 0 }},
|
||||
{ 207, 0, 1, 3, { 0 }},
|
||||
{ 208, 1, 3, 7, { 0 }},
|
||||
{ 209, 1, 0, 7, { 0 }},
|
||||
{ 210, 1, 0, 7, { 0 }},
|
||||
{ 211, 1, 0, 7, { 0 }},
|
||||
{ 212, 1, 0, 7, { 0 }},
|
||||
{ 213, 1, 0, 7, { 0 }},
|
||||
{ 214, 1, 1, 7, { 0 }},
|
||||
{ 215, 1, 7, 7, { 0 }},
|
||||
{ 216, 1, 2, 7, { 0 }},
|
||||
{ 217, 1, 0, 7, { 0 }},
|
||||
{ 218, 1, 0, 7, { 0 }},
|
||||
{ 219, 1, 0, 7, { 0 }},
|
||||
{ 220, 1, 1, 7, { 0 }},
|
||||
{ 221, 1, 0, 7, { 0 }},
|
||||
{ 222, 1, 3, 7, { 0 }},
|
||||
{ 223, 1, 3, 7, { 0 }},
|
||||
{ 224, 1, 3, 7, { 0 }},
|
||||
{ 225, 1, 3, 7, { 0 }},
|
||||
{ 226, 1, 3, 7, { 0 }},
|
||||
{ 227, 1, 3, 7, { 0 }},
|
||||
{ 228, 1, 4, 7, { 0 }},
|
||||
{ 229, 1, 4, 7, { 0 }},
|
||||
{ 230, 1, 6, 11, { 0 }},
|
||||
{ 231, 1, 6, 7, { 0 }},
|
||||
{ 232, 1, 3, 7, { 0 }},
|
||||
{ 233, 1, 3, 7, { 0 }},
|
||||
{ 234, 1, 3, 7, { 0 }},
|
||||
{ 235, 1, 4, 7, { 0 }},
|
||||
{ 236, 0, 3, 3, { 0 }},
|
||||
{ 237, 1, 3, 3, { 0 }},
|
||||
{ 238, 0, 3, 3, { 0 }},
|
||||
{ 239, 0, 4, 3, { 0 }},
|
||||
{ 240, 1, 3, 7, { 0 }},
|
||||
{ 241, 1, 3, 7, { 0 }},
|
||||
{ 242, 1, 3, 7, { 0 }},
|
||||
{ 243, 1, 3, 7, { 0 }},
|
||||
{ 244, 1, 3, 7, { 0 }},
|
||||
{ 245, 1, 3, 7, { 0 }},
|
||||
{ 246, 1, 4, 7, { 0 }},
|
||||
{ 247, 1, 7, 7, { 0 }},
|
||||
{ 248, 1, 5, 7, { 0 }},
|
||||
{ 249, 1, 3, 7, { 0 }},
|
||||
{ 250, 1, 3, 7, { 0 }},
|
||||
{ 251, 1, 3, 7, { 0 }},
|
||||
{ 252, 1, 4, 7, { 0 }},
|
||||
{ 253, 1, 3, 7, { 0 }},
|
||||
{ 254, 1, 6, 6, { 0 }},
|
||||
{ 255, 1, 4, 7, { 0 }},
|
||||
};
|
||||
|
||||
// Style loading function: Terminal
|
||||
static void GuiLoadStyleTerminal(void)
|
||||
{
|
||||
// Load style properties provided
|
||||
// NOTE: Default properties are propagated
|
||||
for (int i = 0; i < TERMINAL_STYLE_PROPS_COUNT; i++)
|
||||
{
|
||||
GuiSetStyle(terminalStyleProps[i].controlId, terminalStyleProps[i].propertyId, terminalStyleProps[i].propertyValue);
|
||||
}
|
||||
|
||||
// Custom font loading
|
||||
// NOTE: Compressed font image data (DEFLATE), it requires DecompressData() function
|
||||
int terminalFontDataSize = 0;
|
||||
unsigned char *data = DecompressData(terminalFontData, TERMINAL_STYLE_FONT_ATLAS_COMP_SIZE, &terminalFontDataSize);
|
||||
Image imFont = { data, 512, 256, 1, 2 };
|
||||
|
||||
Font font = { 0 };
|
||||
font.baseSize = 16;
|
||||
font.glyphCount = 189;
|
||||
|
||||
// Load texture from image
|
||||
font.texture = LoadTextureFromImage(imFont);
|
||||
UnloadImage(imFont); // Uncompressed image data can be unloaded from memory
|
||||
|
||||
// Copy char recs data from global fontRecs
|
||||
// NOTE: Required to avoid issues if trying to free font
|
||||
font.recs = (Rectangle *)RAYGUI_MALLOC(font.glyphCount*sizeof(Rectangle));
|
||||
memcpy(font.recs, terminalFontRecs, font.glyphCount*sizeof(Rectangle));
|
||||
|
||||
// Copy font char info data from global fontChars
|
||||
// NOTE: Required to avoid issues if trying to free font
|
||||
font.glyphs = (GlyphInfo *)RAYGUI_MALLOC(font.glyphCount*sizeof(GlyphInfo));
|
||||
memcpy(font.glyphs, terminalFontGlyphs, font.glyphCount*sizeof(GlyphInfo));
|
||||
|
||||
GuiSetFont(font);
|
||||
|
||||
// Setup a white rectangle on the font to be used on shapes drawing,
|
||||
// it makes possible to draw shapes and text (full UI) in a single draw call
|
||||
Rectangle fontWhiteRec = { 510, 254, 1, 1 };
|
||||
SetShapesTexture(font.texture, fontWhiteRec);
|
||||
|
||||
//-----------------------------------------------------------------
|
||||
|
||||
// TODO: Custom user style setup: Set specific properties here (if required)
|
||||
// i.e. Controls specific BORDER_WIDTH, TEXT_PADDING, TEXT_ALIGNMENT
|
||||
}
|
||||
5262
include/extern/rlgl.h
vendored
Normal file
5262
include/extern/rlgl.h
vendored
Normal file
File diff suppressed because it is too large
Load Diff
80
include/render.h
Normal file
80
include/render.h
Normal file
@ -0,0 +1,80 @@
|
||||
#ifndef RENDER_H
|
||||
#define RENDER_H
|
||||
|
||||
#include <core.h>
|
||||
|
||||
typedef enum {
|
||||
R_ENTITY_STATIC,
|
||||
R_ENTITY_ANIMATED,
|
||||
R_ENTITY_INSTANCED // Particles, foliage, etc.
|
||||
} REntityType_e;
|
||||
|
||||
typedef struct {
|
||||
REntityType_e type;
|
||||
uint32_t modelId;
|
||||
Matrix transform;
|
||||
|
||||
union {
|
||||
struct {
|
||||
int activeAnim;
|
||||
float time;
|
||||
} anim;
|
||||
struct {
|
||||
Matrix *transforms;
|
||||
int instanceCount;
|
||||
} instancing;
|
||||
} data;
|
||||
} RenderEntity;
|
||||
|
||||
typedef struct {
|
||||
RenderEntity *entities;
|
||||
int count;
|
||||
int capacity;//may use frame allocator instead to not have dynamic capacity
|
||||
} Scene;
|
||||
|
||||
typedef struct {
|
||||
Model *models;
|
||||
int count;
|
||||
} ModelRegistry;
|
||||
|
||||
typedef struct {
|
||||
ModelAnimation *animations;
|
||||
int count;
|
||||
} AnimationRegistry;
|
||||
|
||||
typedef struct {
|
||||
Texture *tex;
|
||||
int count;
|
||||
} TextureRegistry;
|
||||
|
||||
typedef struct {
|
||||
Font *font;
|
||||
int count;
|
||||
} FontRegistry;
|
||||
|
||||
typedef struct {
|
||||
Shader gbuffer;
|
||||
Shader deferred;
|
||||
Shader filter;
|
||||
} ShaderRD;
|
||||
|
||||
typedef struct {
|
||||
unsigned int framebufferId;
|
||||
unsigned int normal_tex_id;
|
||||
unsigned int albedoSpec_tex_id;
|
||||
unsigned int depth_tex_id;
|
||||
} GBuffer;
|
||||
|
||||
typedef struct {
|
||||
uint16_t height;
|
||||
uint16_t width;
|
||||
void* window;
|
||||
//RenderTexture rendtex;
|
||||
GBuffer gbuffer;
|
||||
Camera3D camera3d;
|
||||
Camera2D camera2d;
|
||||
ShaderRD shader;
|
||||
bool hud_on, debug_on;
|
||||
} RenderCtx;
|
||||
|
||||
#endif
|
||||
@ -11,34 +11,6 @@ typedef struct {
|
||||
Sound sound;
|
||||
} Assets;
|
||||
|
||||
// Render
|
||||
|
||||
typedef struct {
|
||||
Shader gbuffer;
|
||||
Shader deferred;
|
||||
Shader filter;
|
||||
} ShaderRD;
|
||||
|
||||
typedef struct {
|
||||
unsigned int framebufferId;
|
||||
unsigned int normal_tex_id;
|
||||
unsigned int albedoSpec_tex_id;
|
||||
unsigned int depth_tex_id;
|
||||
|
||||
} GBuffer;
|
||||
|
||||
typedef struct {
|
||||
uint16_t height;
|
||||
uint16_t width;
|
||||
void* window;
|
||||
//RenderTexture rendtex;
|
||||
GBuffer gbuffer;
|
||||
Camera3D camera3d;
|
||||
Camera2D camera2d;
|
||||
ShaderRD shader;
|
||||
bool hud_on, debug_on;
|
||||
} RenderCtx;
|
||||
|
||||
// Event
|
||||
typedef struct {
|
||||
EVENT_TYPE type;
|
||||
|
||||
BIN
lib/libraylib.a
Normal file
BIN
lib/libraylib.a
Normal file
Binary file not shown.
@ -1,4 +1,4 @@
|
||||
#include <engine.h>
|
||||
#include <render.h>
|
||||
|
||||
RenderCtx r_ctx;
|
||||
|
||||
@ -70,7 +70,7 @@ void LoadCameraMode(int mode) {
|
||||
}
|
||||
|
||||
//need to work on a way to structurize my data for the scene to be rendered
|
||||
void RenderingDeferred3D() {
|
||||
void RenderingDeferred3D(Scene* scene, ModelRegistry *models, AnimationRegistry *animation) {
|
||||
BeginDrawing();
|
||||
ClearBackground(BLACK);
|
||||
rlEnableDepthMask();
|
||||
@ -78,6 +78,28 @@ void RenderingDeferred3D() {
|
||||
rlEnableShader(r_ctx.shader.gbuffer.id);
|
||||
BeginMode3D(r_ctx.camera3d);
|
||||
//MainGeamoetry;
|
||||
for (int i = 0; i < scene->count; i++) {
|
||||
RenderEntity *e = &scene->entities[i];
|
||||
Model m = models->models[e->modelId];
|
||||
|
||||
switch (e->type) {
|
||||
case R_ENTITY_STATIC:
|
||||
DrawModel(m, (Vector3){0}, 1.0f, WHITE);
|
||||
break;
|
||||
|
||||
case R_ENTITY_ANIMATED:
|
||||
UpdateModelAnimation(m, animation->animations[e->data.anim.activeAnim], e->data.anim.time);
|
||||
DrawModel(m, (Vector3){0}, 1.0f, WHITE);
|
||||
break;
|
||||
|
||||
case R_ENTITY_INSTANCED:
|
||||
// Note: Raylib's DrawMeshInstanced handles the instancing buffer
|
||||
for (int j = 0; j < m.meshCount; j++) {
|
||||
DrawMeshInstanced(m.meshes[j], m.materials[0], e->data.instancing.transforms, e->data.instancing.instanceCount);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
EndMode3D();
|
||||
rlDisableShader();
|
||||
rlDisableFramebuffer();
|
||||
@ -86,7 +108,7 @@ void RenderingDeferred3D() {
|
||||
|
||||
//Light Pass and forward pass;
|
||||
//I should build a shader that take every light in the scene and make a 3D heightmap of lighting then compute it once for all static light allowing to cheat computing everylight
|
||||
//light is computed into a scalar field
|
||||
//light could be computed into a scalar field
|
||||
|
||||
//Light Pass
|
||||
|
||||
|
||||
25
source/core_registry.c
Normal file
25
source/core_registry.c
Normal file
@ -0,0 +1,25 @@
|
||||
#include <engine.h>
|
||||
|
||||
void RegistryAdd() {
|
||||
|
||||
}
|
||||
|
||||
void RegistryRemove() {
|
||||
|
||||
}
|
||||
|
||||
void RegistryCreate() {
|
||||
|
||||
}
|
||||
|
||||
void RegistryDestroy() {
|
||||
|
||||
}
|
||||
|
||||
void RegistrySort() {
|
||||
|
||||
}
|
||||
|
||||
void RegistrySearch() {
|
||||
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user