Compare commits

..

9 Commits
v6 ... master

Author SHA1 Message Date
1004f17ca7 Tweaks. 2025-03-23 18:57:40 +01:00
e78e12e658 Added jo_mp1 and sts_mixer. 2025-03-23 18:57:32 +01:00
3cb5dbdaa9 Work on the audio implementation. 2025-03-23 18:57:14 +01:00
7cfe9a22ee Fix connecting class methods to Signal. 2025-03-05 16:42:11 +01:00
703411a91e Backported commits from pandemonium:
- Now unicode error printing is disabled by default. Also can be enabled
via a macro. 2e41d4dfcda7ff2c35a1326f0de71b0714524f11
- Added to_real helper methods to String.
43b14a071c6ccf7c3062e0568e3d7bb05d8a83d2
- Fix AABB.encloses failing on shared upper bound.
8341ddc450bd160b5cb44eeb0400da2e5a151ed0
- Fix incorrect clipping in String::substr_index().
dcd00dec81a2841ad5244e043379697c68d681f7
- Backported create_reference() helper methods for InputEvents from
godot 4. 4cdb1636264d8a6cef0881a37a7fad72ac262f3f
- Backported comparison operators to Array from godot4.
7779439e284bf8a0534f606d5c7f929674764941
- Removed Vector2i(Vector2) constructor, added a Vector2i conversion
operator to Vector2 instead. This solves ambigous Variant to Vector2i
conversion errors. 27b73fa9f9984709b0c8eb77bfeea5cab8d9fee3
- Added exp2 to the Math singleton.
e17cc864bc339c1f4d1ce6acd4cabf4a6593c6cc
- Add a get_or_add method to Dictionary.
487b454506259c080306098093875ea7bda5b5ad
- Add is_zero_approx methods to Vector{2,3}
441bb29fd3bd758ff783e4122e6b2d512dc8529f
- Also add is_zero_approx() to Vector4.
ed224298e5ae951093b42a004afacbd275e54494
- Transform now uses Basis::create_looking_at.
6f53257e05d72088c28028eb568526f4da146ae0
- Backported from godot4: Add the ability to look-at in model-space.
951ae7b11db0376dd0dbdf080e2f2e3652ac33ed
- Fix split_floats behavior when spaces are used as separators
4585110a298487081f026827e3395c4feaf35f9a
- Better solution for the previous fix.
d75d3591edf13ae0dd6aa989962595aa1280ae73
- Fix the fix. 48935e93b3f5849a52b0e7fc0b6ede36a7b61123
2025-03-01 12:52:00 +01:00
a7590426eb Added Renderer::camera_3d_camera_transform_matrix_stack_clear() and Renderer::get_camera_3d_model_view_matrix_stack_clear() helper methods. 2025-02-23 10:42:58 +01:00
c382024f95 Added Renderer::camera_3d_reset(). 2025-02-23 10:39:47 +01:00
a7a73b1081 Simplifications and a small rework to the immediate renderer's 2d camera api.
- Now camera_2d_projection_set_to_* helper methods won't mess with the
model view matrices.
- Added camera_2d_reset().
- Added helper methods to clear each matrix separately.
- This also fixes a bug where the internal matrices were kept after a
reset.
2025-02-23 10:36:14 +01:00
6bb0a96196 Renamed audio.cpp so the makefile works for compiledb generation. 2025-02-23 10:31:48 +01:00
43 changed files with 1532 additions and 183 deletions

408
sfw/audio/3rd_jo_mp1.h Normal file
View File

@ -0,0 +1,408 @@
/* public domain Simple, Minimalistic MPEG Layer 1 decoder - http://jonolick.com
*
* Revision History:
* 1.00 (2014-26-1) Initial release.
*
* Basic usage:
* int hz, channels, outputSize;
* short *output;
* jo_read_mp1(input, inputSize, output, outputSize, hz, channels);
* // Do something with the data here
* free(output);
*
* */
#ifndef JO_INCLUDE_MP1_H
#define JO_INCLUDE_MP1_H
#include <stdbool.h>
#include <cstdio>
extern bool jo_read_mp1(const void *input, int inputSize, short **output, int *outputSize, int *hz, int *channels);
#endif // JO_INCLUDE_MP1_H
#ifndef JO_MP1_HEADER_FILE_ONLY
#if defined(_MSC_VER) && _MSC_VER >= 0x1400
#define _CRT_SECURE_NO_WARNINGS // suppress warnings about fopen()
#endif
#include <stdlib.h>
#include <math.h>
#include <limits.h>
static const double s_jo_multTbl[64] = {
2.000000,1.587401,1.259921,1.000000,0.793701,0.629961,0.500000,0.396850,0.314980,0.250000,0.198425,0.157490,0.125000,0.099213,0.078745,0.062500,
0.049606,0.039373,0.031250,0.024803,0.019686,0.015625,0.012402,0.009843,0.007812,0.006201,0.004922,0.003906,0.003100,0.002461,0.001953,0.001550,
0.001230,0.000977,0.000775,0.000615,0.000488,0.000388,0.000308,0.000244,0.000194,0.000154,0.000122,0.000097,0.000077,0.000061,0.000048,0.000038,
0.000031,0.000024,0.000019,0.000015,0.000012,0.000010,0.000008,0.000006,0.000005,0.000004,0.000003,0.000002,0.000002,0.000002,0.000001,1e-20
};
// l = i - 256;
// s = (i & 0x40) ? 1 : -1;
// windowTbl[(i/16)|((i%16)<<5)] = s * 20 * exp(-(l/112)*-(l/112)) * sin(l * M_PI*2 / 112) / l;
static const double s_jo_windowTbl[512] = {
-0.000000,-0.000443,0.003250,-0.007004,0.031082,-0.078629,0.100311,-0.572037,1.144989,0.572037,0.100311,0.078629,0.031082,0.007004,0.003250,0.000443,
-0.000015,-0.000473,0.003326,-0.007919,0.030518,-0.084183,0.090927,-0.600220,1.144287,0.543823,0.108856,0.073059,0.031479,0.006119,0.003174,0.000397,
-0.000015,-0.000534,0.003387,-0.008865,0.029785,-0.089706,0.080688,-0.628296,1.142212,0.515610,0.116577,0.067520,0.031738,0.005295,0.003082,0.000366,
-0.000015,-0.000580,0.003433,-0.009842,0.028885,-0.095169,0.069595,-0.656219,1.138763,0.487473,0.123474,0.061996,0.031845,0.004486,0.002991,0.000320,
-0.000015,-0.000626,0.003464,-0.010849,0.027802,-0.100540,0.057617,-0.683914,1.133926,0.459473,0.129578,0.056534,0.031815,0.003723,0.002899,0.000290,
-0.000015,-0.000687,0.003479,-0.011887,0.026535,-0.105820,0.044785,-0.711319,1.127747,0.431656,0.134888,0.051132,0.031662,0.003006,0.002792,0.000259,
-0.000015,-0.000748,0.003479,-0.012939,0.025085,-0.110947,0.031082,-0.738373,1.120224,0.404083,0.139450,0.045837,0.031387,0.002335,0.002686,0.000244,
-0.000031,-0.000809,0.003464,-0.014023,0.023422,-0.115921,0.016510,-0.765030,1.111374,0.376801,0.143265,0.040634,0.031006,0.001694,0.002579,0.000214,
-0.000031,-0.000885,0.003418,-0.015121,0.021576,-0.120697,0.001068,-0.791214,1.101212,0.349869,0.146362,0.035553,0.030533,0.001099,0.002457,0.000198,
-0.000031,-0.000961,0.003372,-0.016235,0.019531,-0.125259,-0.015228,-0.816864,1.089783,0.323318,0.148773,0.030609,0.029938,0.000549,0.002350,0.000168,
-0.000031,-0.001038,0.003281,-0.017349,0.017258,-0.129562,-0.032379,-0.841949,1.077118,0.297211,0.150497,0.025818,0.029282,0.000031,0.002243,0.000153,
-0.000046,-0.001114,0.003174,-0.018463,0.014801,-0.133591,-0.050354,-0.866364,1.063217,0.271591,0.151596,0.021179,0.028534,-0.000443,0.002121,0.000137,
-0.000046,-0.001205,0.003052,-0.019577,0.012115,-0.137299,-0.069168,-0.890091,1.048157,0.246506,0.152069,0.016708,0.027725,-0.000870,0.002014,0.000122,
-0.000061,-0.001297,0.002884,-0.020691,0.009232,-0.140671,-0.088776,-0.913055,1.031937,0.221985,0.151962,0.012421,0.026840,-0.001266,0.001907,0.000107,
-0.000061,-0.001389,0.002701,-0.021790,0.006134,-0.143677,-0.109161,-0.935196,1.014618,0.198059,0.151306,0.008316,0.025909,-0.001617,0.001785,0.000107,
-0.000076,-0.001480,0.002487,-0.022858,0.002823,-0.146255,-0.130310,-0.956482,0.996246,0.174789,0.150116,0.004395,0.024933,-0.001938,0.001694,0.000092,
-0.000076,-0.001587,0.002228,-0.023911,-0.000687,-0.148422,-0.152206,-0.976852,0.976852,0.152206,0.148422,0.000687,0.023911,-0.002228,0.001587,0.000076,
-0.000092,-0.001694,0.001938,-0.024933,-0.004395,-0.150116,-0.174789,-0.996246,0.956482,0.130310,0.146255,-0.002823,0.022858,-0.002487,0.001480,0.000076,
-0.000107,-0.001785,0.001617,-0.025909,-0.008316,-0.151306,-0.198059,-1.014618,0.935196,0.109161,0.143677,-0.006134,0.021790,-0.002701,0.001389,0.000061,
-0.000107,-0.001907,0.001266,-0.026840,-0.012421,-0.151962,-0.221985,-1.031937,0.913055,0.088776,0.140671,-0.009232,0.020691,-0.002884,0.001297,0.000061,
-0.000122,-0.002014,0.000870,-0.027725,-0.016708,-0.152069,-0.246506,-1.048157,0.890091,0.069168,0.137299,-0.012115,0.019577,-0.003052,0.001205,0.000046,
-0.000137,-0.002121,0.000443,-0.028534,-0.021179,-0.151596,-0.271591,-1.063217,0.866364,0.050354,0.133591,-0.014801,0.018463,-0.003174,0.001114,0.000046,
-0.000153,-0.002243,-0.000031,-0.029282,-0.025818,-0.150497,-0.297211,-1.077118,0.841949,0.032379,0.129562,-0.017258,0.017349,-0.003281,0.001038,0.000031,
-0.000168,-0.002350,-0.000549,-0.029938,-0.030609,-0.148773,-0.323318,-1.089783,0.816864,0.015228,0.125259,-0.019531,0.016235,-0.003372,0.000961,0.000031,
-0.000198,-0.002457,-0.001099,-0.030533,-0.035553,-0.146362,-0.349869,-1.101212,0.791214,-0.001068,0.120697,-0.021576,0.015121,-0.003418,0.000885,0.000031,
-0.000214,-0.002579,-0.001694,-0.031006,-0.040634,-0.143265,-0.376801,-1.111374,0.765030,-0.016510,0.115921,-0.023422,0.014023,-0.003464,0.000809,0.000031,
-0.000244,-0.002686,-0.002335,-0.031387,-0.045837,-0.139450,-0.404083,-1.120224,0.738373,-0.031082,0.110947,-0.025085,0.012939,-0.003479,0.000748,0.000015,
-0.000259,-0.002792,-0.003006,-0.031662,-0.051132,-0.134888,-0.431656,-1.127747,0.711319,-0.044785,0.105820,-0.026535,0.011887,-0.003479,0.000687,0.000015,
-0.000290,-0.002899,-0.003723,-0.031815,-0.056534,-0.129578,-0.459473,-1.133926,0.683914,-0.057617,0.100540,-0.027802,0.010849,-0.003464,0.000626,0.000015,
-0.000320,-0.002991,-0.004486,-0.031845,-0.061996,-0.123474,-0.487473,-1.138763,0.656219,-0.069595,0.095169,-0.028885,0.009842,-0.003433,0.000580,0.000015,
-0.000366,-0.003082,-0.005295,-0.031738,-0.067520,-0.116577,-0.515610,-1.142212,0.628296,-0.080688,0.089706,-0.029785,0.008865,-0.003387,0.000534,0.000015,
-0.000397,-0.003174,-0.006119,-0.031479,-0.073059,-0.108856,-0.543823,-1.144287,0.600220,-0.090927,0.084183,-0.030518,0.007919,-0.003326,0.000473,0.000015,
};
// filterTbl[i][j] = cos(((M_PI/64*i+M_PI/4)*(2*j+1)));
static const double s_jo_filterTbl[64][32] = {
{0.707107,-0.707107,-0.707107,0.707107,0.707107,-0.707107,-0.707107,0.707107,0.707107,-0.707107,-0.707107,0.707107,0.707107,-0.707107,-0.707107,0.707107,
0.707107,-0.707107,-0.707107,0.707107,0.707107,-0.707107,-0.707107,0.707107,0.707107,-0.707107,-0.707107,0.707107,0.707107,-0.707107,-0.707107,0.707107},
{0.671559,-0.803208,-0.514103,0.903989,0.336890,-0.970031,-0.146730,0.998795,-0.049068,-0.989177,0.242980,0.941544,-0.427555,-0.857729,0.595699,0.740951,
-0.740951,-0.595699,0.857729,0.427555,-0.941544,-0.242980,0.989177,0.049068,-0.998795,0.146730,0.970031,-0.336890,-0.903989,0.514103,0.803208,-0.671559},
{0.634393,-0.881921,-0.290285,0.995185,-0.098017,-0.956940,0.471397,0.773010,-0.773010,-0.471397,0.956940,0.098017,-0.995185,0.290285,0.881921,-0.634393,
-0.634393,0.881921,0.290285,-0.995185,0.098017,0.956940,-0.471397,-0.773010,0.773010,0.471397,-0.956940,-0.098017,0.995185,-0.290285,-0.881921,0.634393},
{0.595699,-0.941544,-0.049068,0.970031,-0.514103,-0.671559,0.903989,0.146730,-0.989177,0.427555,0.740951,-0.857729,-0.242980,0.998795,-0.336890,-0.803208,
0.803208,0.336890,-0.998795,0.242980,0.857729,-0.740951,-0.427555,0.989177,-0.146730,-0.903989,0.671559,0.514103,-0.970031,0.049068,0.941544,-0.595699},
{0.555570,-0.980785,0.195090,0.831470,-0.831470,-0.195090,0.980785,-0.555570,-0.555570,0.980785,-0.195090,-0.831470,0.831470,0.195090,-0.980785,0.555570,
0.555570,-0.980785,0.195090,0.831470,-0.831470,-0.195090,0.980785,-0.555570,-0.555570,0.980785,-0.195090,-0.831470,0.831470,0.195090,-0.980785,0.555570},
{0.514103,-0.998795,0.427555,0.595699,-0.989177,0.336890,0.671559,-0.970031,0.242980,0.740951,-0.941544,0.146730,0.803208,-0.903989,0.049068,0.857729,
-0.857729,-0.049068,0.903989,-0.803208,-0.146730,0.941544,-0.740951,-0.242980,0.970031,-0.671559,-0.336890,0.989177,-0.595699,-0.427555,0.998795,-0.514103},
{0.471397,-0.995185,0.634393,0.290285,-0.956940,0.773010,0.098017,-0.881921,0.881921,-0.098017,-0.773010,0.956940,-0.290285,-0.634393,0.995185,-0.471397,
-0.471397,0.995185,-0.634393,-0.290285,0.956940,-0.773010,-0.098017,0.881921,-0.881921,0.098017,0.773010,-0.956940,0.290285,0.634393,-0.995185,0.471397},
{0.427555,-0.970031,0.803208,-0.049068,-0.740951,0.989177,-0.514103,-0.336890,0.941544,-0.857729,0.146730,0.671559,-0.998795,0.595699,0.242980,-0.903989,
0.903989,-0.242980,-0.595699,0.998795,-0.671559,-0.146730,0.857729,-0.941544,0.336890,0.514103,-0.989177,0.740951,0.049068,-0.803208,0.970031,-0.427555},
{0.382683,-0.923880,0.923880,-0.382683,-0.382683,0.923880,-0.923880,0.382683,0.382683,-0.923880,0.923880,-0.382683,-0.382683,0.923880,-0.923880,0.382683,
0.382683,-0.923880,0.923880,-0.382683,-0.382683,0.923880,-0.923880,0.382683,0.382683,-0.923880,0.923880,-0.382683,-0.382683,0.923880,-0.923880,0.382683},
{0.336890,-0.857729,0.989177,-0.671559,0.049068,0.595699,-0.970031,0.903989,-0.427555,-0.242980,0.803208,-0.998795,0.740951,-0.146730,-0.514103,0.941544,
-0.941544,0.514103,0.146730,-0.740951,0.998795,-0.803208,0.242980,0.427555,-0.903989,0.970031,-0.595699,-0.049068,0.671559,-0.989177,0.857729,-0.336890},
{0.290285,-0.773010,0.995185,-0.881921,0.471397,0.098017,-0.634393,0.956940,-0.956940,0.634393,-0.098017,-0.471397,0.881921,-0.995185,0.773010,-0.290285,
-0.290285,0.773010,-0.995185,0.881921,-0.471397,-0.098017,0.634393,-0.956940,0.956940,-0.634393,0.098017,0.471397,-0.881921,0.995185,-0.773010,0.290285},
{0.242980,-0.671559,0.941544,-0.989177,0.803208,-0.427555,-0.049068,0.514103,-0.857729,0.998795,-0.903989,0.595699,-0.146730,-0.336890,0.740951,-0.970031,
0.970031,-0.740951,0.336890,0.146730,-0.595699,0.903989,-0.998795,0.857729,-0.514103,0.049068,0.427555,-0.803208,0.989177,-0.941544,0.671559,-0.242980},
{0.195090,-0.555570,0.831470,-0.980785,0.980785,-0.831470,0.555570,-0.195090,-0.195090,0.555570,-0.831470,0.980785,-0.980785,0.831470,-0.555570,0.195090,
0.195090,-0.555570,0.831470,-0.980785,0.980785,-0.831470,0.555570,-0.195090,-0.195090,0.555570,-0.831470,0.980785,-0.980785,0.831470,-0.555570,0.195090},
{0.146730,-0.427555,0.671559,-0.857729,0.970031,-0.998795,0.941544,-0.803208,0.595699,-0.336890,0.049068,0.242980,-0.514103,0.740951,-0.903989,0.989177,
-0.989177,0.903989,-0.740951,0.514103,-0.242980,-0.049068,0.336890,-0.595699,0.803208,-0.941544,0.998795,-0.970031,0.857729,-0.671559,0.427555,-0.146730},
{0.098017,-0.290285,0.471397,-0.634393,0.773010,-0.881921,0.956940,-0.995185,0.995185,-0.956940,0.881921,-0.773010,0.634393,-0.471397,0.290285,-0.098017,
-0.098017,0.290285,-0.471397,0.634393,-0.773010,0.881921,-0.956940,0.995185,-0.995185,0.956940,-0.881921,0.773010,-0.634393,0.471397,-0.290285,0.098017},
{0.049068,-0.146730,0.242980,-0.336890,0.427555,-0.514103,0.595699,-0.671559,0.740951,-0.803208,0.857729,-0.903989,0.941544,-0.970031,0.989177,-0.998795,
0.998795,-0.989177,0.970031,-0.941544,0.903989,-0.857729,0.803208,-0.740951,0.671559,-0.595699,0.514103,-0.427555,0.336890,-0.242980,0.146730,-0.049068},
{0.000000,-0.000000,0.000000,-0.000000,0.000000,-0.000000,-0.000000,-0.000000,-0.000000,-0.000000,-0.000000,-0.000000,-0.000000,-0.000000,-0.000000,-0.000000,
0.000000,-0.000000,0.000000,-0.000000,0.000000,-0.000000,0.000000,0.000000,0.000000,-0.000000,0.000000,0.000000,0.000000,-0.000000,0.000000,0.000000},
{-0.049068,0.146730,-0.242980,0.336890,-0.427555,0.514103,-0.595699,0.671559,-0.740951,0.803208,-0.857729,0.903989,-0.941544,0.970031,-0.989177,0.998795,
-0.998795,0.989177,-0.970031,0.941544,-0.903989,0.857729,-0.803208,0.740951,-0.671559,0.595699,-0.514103,0.427555,-0.336890,0.242980,-0.146730,0.049068},
{-0.098017,0.290285,-0.471397,0.634393,-0.773010,0.881921,-0.956940,0.995185,-0.995185,0.956940,-0.881921,0.773010,-0.634393,0.471397,-0.290285,0.098017,
0.098017,-0.290285,0.471397,-0.634393,0.773010,-0.881921,0.956940,-0.995185,0.995185,-0.956940,0.881921,-0.773010,0.634393,-0.471397,0.290285,-0.098017},
{-0.146730,0.427555,-0.671559,0.857729,-0.970031,0.998795,-0.941544,0.803208,-0.595699,0.336890,-0.049068,-0.242980,0.514103,-0.740951,0.903989,-0.989177,
0.989177,-0.903989,0.740951,-0.514103,0.242980,0.049068,-0.336890,0.595699,-0.803208,0.941544,-0.998795,0.970031,-0.857729,0.671559,-0.427555,0.146730},
{-0.195090,0.555570,-0.831470,0.980785,-0.980785,0.831470,-0.555570,0.195090,0.195090,-0.555570,0.831470,-0.980785,0.980785,-0.831470,0.555570,-0.195090,
-0.195090,0.555570,-0.831470,0.980785,-0.980785,0.831470,-0.555570,0.195090,0.195090,-0.555570,0.831470,-0.980785,0.980785,-0.831470,0.555570,-0.195090},
{-0.242980,0.671559,-0.941544,0.989177,-0.803208,0.427555,0.049068,-0.514103,0.857729,-0.998795,0.903989,-0.595699,0.146730,0.336890,-0.740951,0.970031,
-0.970031,0.740951,-0.336890,-0.146730,0.595699,-0.903989,0.998795,-0.857729,0.514103,-0.049068,-0.427555,0.803208,-0.989177,0.941544,-0.671559,0.242980},
{-0.290285,0.773010,-0.995185,0.881921,-0.471397,-0.098017,0.634393,-0.956940,0.956940,-0.634393,0.098017,0.471397,-0.881921,0.995185,-0.773010,0.290285,
0.290285,-0.773010,0.995185,-0.881921,0.471397,0.098017,-0.634393,0.956940,-0.956940,0.634393,-0.098017,-0.471397,0.881921,-0.995185,0.773010,-0.290285},
{-0.336890,0.857729,-0.989177,0.671559,-0.049068,-0.595699,0.970031,-0.903989,0.427555,0.242980,-0.803208,0.998795,-0.740951,0.146730,0.514103,-0.941544,
0.941544,-0.514103,-0.146730,0.740951,-0.998795,0.803208,-0.242980,-0.427555,0.903989,-0.970031,0.595699,0.049068,-0.671559,0.989177,-0.857729,0.336890},
{-0.382683,0.923880,-0.923880,0.382683,0.382683,-0.923880,0.923880,-0.382683,-0.382683,0.923880,-0.923880,0.382683,0.382683,-0.923880,0.923880,-0.382683,
-0.382683,0.923880,-0.923880,0.382683,0.382683,-0.923880,0.923880,-0.382683,-0.382683,0.923880,-0.923880,0.382683,0.382683,-0.923880,0.923880,-0.382683},
{-0.427555,0.970031,-0.803208,0.049068,0.740951,-0.989177,0.514103,0.336890,-0.941544,0.857729,-0.146730,-0.671559,0.998795,-0.595699,-0.242980,0.903989,
-0.903989,0.242980,0.595699,-0.998795,0.671559,0.146730,-0.857729,0.941544,-0.336890,-0.514103,0.989177,-0.740951,-0.049068,0.803208,-0.970031,0.427555},
{-0.471397,0.995185,-0.634393,-0.290285,0.956940,-0.773010,-0.098017,0.881921,-0.881921,0.098017,0.773010,-0.956940,0.290285,0.634393,-0.995185,0.471397,
0.471397,-0.995185,0.634393,0.290285,-0.956940,0.773010,0.098017,-0.881921,0.881921,-0.098017,-0.773010,0.956940,-0.290285,-0.634393,0.995185,-0.471397},
{-0.514103,0.998795,-0.427555,-0.595699,0.989177,-0.336890,-0.671559,0.970031,-0.242980,-0.740951,0.941544,-0.146730,-0.803208,0.903989,-0.049068,-0.857729,
0.857729,0.049068,-0.903989,0.803208,0.146730,-0.941544,0.740951,0.242980,-0.970031,0.671559,0.336890,-0.989177,0.595699,0.427555,-0.998795,0.514103},
{-0.555570,0.980785,-0.195090,-0.831470,0.831470,0.195090,-0.980785,0.555570,0.555570,-0.980785,0.195090,0.831470,-0.831470,-0.195090,0.980785,-0.555570,
-0.555570,0.980785,-0.195090,-0.831470,0.831470,0.195090,-0.980785,0.555570,0.555570,-0.980785,0.195090,0.831470,-0.831470,-0.195090,0.980785,-0.555570},
{-0.595699,0.941544,0.049068,-0.970031,0.514103,0.671559,-0.903989,-0.146730,0.989177,-0.427555,-0.740951,0.857729,0.242980,-0.998795,0.336890,0.803208,
-0.803208,-0.336890,0.998795,-0.242980,-0.857729,0.740951,0.427555,-0.989177,0.146730,0.903989,-0.671559,-0.514103,0.970031,-0.049068,-0.941544,0.595699},
{-0.634393,0.881921,0.290285,-0.995185,0.098017,0.956940,-0.471397,-0.773010,0.773010,0.471397,-0.956940,-0.098017,0.995185,-0.290285,-0.881921,0.634393,
0.634393,-0.881921,-0.290285,0.995185,-0.098017,-0.956940,0.471397,0.773010,-0.773010,-0.471397,0.956940,0.098017,-0.995185,0.290285,0.881921,-0.634393},
{-0.671559,0.803208,0.514103,-0.903989,-0.336890,0.970031,0.146730,-0.998795,0.049068,0.989177,-0.242980,-0.941544,0.427555,0.857729,-0.595699,-0.740951,
0.740951,0.595699,-0.857729,-0.427555,0.941544,0.242980,-0.989177,-0.049068,0.998795,-0.146730,-0.970031,0.336890,0.903989,-0.514103,-0.803208,0.671559},
{-0.707107,0.707107,0.707107,-0.707107,-0.707107,0.707107,0.707107,-0.707107,-0.707107,0.707107,0.707107,-0.707107,-0.707107,0.707107,0.707107,-0.707107,
-0.707107,0.707107,0.707107,-0.707107,-0.707107,0.707107,0.707107,-0.707107,-0.707107,0.707107,0.707107,-0.707107,-0.707107,0.707107,0.707107,-0.707107},
{-0.740951,0.595699,0.857729,-0.427555,-0.941544,0.242980,0.989177,-0.049068,-0.998795,-0.146730,0.970031,0.336890,-0.903989,-0.514103,0.803208,0.671559,
-0.671559,-0.803208,0.514103,0.903989,-0.336890,-0.970031,0.146730,0.998795,0.049068,-0.989177,-0.242980,0.941544,0.427555,-0.857729,-0.595699,0.740951},
{-0.773010,0.471397,0.956940,-0.098017,-0.995185,-0.290285,0.881921,0.634393,-0.634393,-0.881921,0.290285,0.995185,0.098017,-0.956940,-0.471397,0.773010,
0.773010,-0.471397,-0.956940,0.098017,0.995185,0.290285,-0.881921,-0.634393,0.634393,0.881921,-0.290285,-0.995185,-0.098017,0.956940,0.471397,-0.773010},
{-0.803208,0.336890,0.998795,0.242980,-0.857729,-0.740951,0.427555,0.989177,0.146730,-0.903989,-0.671559,0.514103,0.970031,0.049068,-0.941544,-0.595699,
0.595699,0.941544,-0.049068,-0.970031,-0.514103,0.671559,0.903989,-0.146730,-0.989177,-0.427555,0.740951,0.857729,-0.242980,-0.998795,-0.336890,0.803208},
{-0.831470,0.195090,0.980785,0.555570,-0.555570,-0.980785,-0.195090,0.831470,0.831470,-0.195090,-0.980785,-0.555570,0.555570,0.980785,0.195090,-0.831470,
-0.831470,0.195090,0.980785,0.555570,-0.555570,-0.980785,-0.195090,0.831470,0.831470,-0.195090,-0.980785,-0.555570,0.555570,0.980785,0.195090,-0.831470},
{-0.857729,0.049068,0.903989,0.803208,-0.146730,-0.941544,-0.740951,0.242980,0.970031,0.671559,-0.336890,-0.989177,-0.595699,0.427555,0.998795,0.514103,
-0.514103,-0.998795,-0.427555,0.595699,0.989177,0.336890,-0.671559,-0.970031,-0.242980,0.740951,0.941544,0.146730,-0.803208,-0.903989,-0.049068,0.857729},
{-0.881921,-0.098017,0.773010,0.956940,0.290285,-0.634393,-0.995185,-0.471397,0.471397,0.995185,0.634393,-0.290285,-0.956940,-0.773010,0.098017,0.881921,
0.881921,0.098017,-0.773010,-0.956940,-0.290285,0.634393,0.995185,0.471397,-0.471397,-0.995185,-0.634393,0.290285,0.956940,0.773010,-0.098017,-0.881921},
{-0.903989,-0.242980,0.595699,0.998795,0.671559,-0.146730,-0.857729,-0.941544,-0.336890,0.514103,0.989177,0.740951,-0.049068,-0.803208,-0.970031,-0.427555,
0.427555,0.970031,0.803208,0.049068,-0.740951,-0.989177,-0.514103,0.336890,0.941544,0.857729,0.146730,-0.671559,-0.998795,-0.595699,0.242980,0.903989},
{-0.923880,-0.382683,0.382683,0.923880,0.923880,0.382683,-0.382683,-0.923880,-0.923880,-0.382683,0.382683,0.923880,0.923880,0.382683,-0.382683,-0.923880,
-0.923880,-0.382683,0.382683,0.923880,0.923880,0.382683,-0.382683,-0.923880,-0.923880,-0.382683,0.382683,0.923880,0.923880,0.382683,-0.382683,-0.923880},
{-0.941544,-0.514103,0.146730,0.740951,0.998795,0.803208,0.242980,-0.427555,-0.903989,-0.970031,-0.595699,0.049068,0.671559,0.989177,0.857729,0.336890,
-0.336890,-0.857729,-0.989177,-0.671559,-0.049068,0.595699,0.970031,0.903989,0.427555,-0.242980,-0.803208,-0.998795,-0.740951,-0.146730,0.514103,0.941544},
{-0.956940,-0.634393,-0.098017,0.471397,0.881921,0.995185,0.773010,0.290285,-0.290285,-0.773010,-0.995185,-0.881921,-0.471397,0.098017,0.634393,0.956940,
0.956940,0.634393,0.098017,-0.471397,-0.881921,-0.995185,-0.773010,-0.290285,0.290285,0.773010,0.995185,0.881921,0.471397,-0.098017,-0.634393,-0.956940},
{-0.970031,-0.740951,-0.336890,0.146730,0.595699,0.903989,0.998795,0.857729,0.514103,0.049068,-0.427555,-0.803208,-0.989177,-0.941544,-0.671559,-0.242980,
0.242980,0.671559,0.941544,0.989177,0.803208,0.427555,-0.049068,-0.514103,-0.857729,-0.998795,-0.903989,-0.595699,-0.146730,0.336890,0.740951,0.970031},
{-0.980785,-0.831470,-0.555570,-0.195090,0.195090,0.555570,0.831470,0.980785,0.980785,0.831470,0.555570,0.195090,-0.195090,-0.555570,-0.831470,-0.980785,
-0.980785,-0.831470,-0.555570,-0.195090,0.195090,0.555570,0.831470,0.980785,0.980785,0.831470,0.555570,0.195090,-0.195090,-0.555570,-0.831470,-0.980785},
{-0.989177,-0.903989,-0.740951,-0.514103,-0.242980,0.049068,0.336890,0.595699,0.803208,0.941544,0.998795,0.970031,0.857729,0.671559,0.427555,0.146730,
-0.146730,-0.427555,-0.671559,-0.857729,-0.970031,-0.998795,-0.941544,-0.803208,-0.595699,-0.336890,-0.049068,0.242980,0.514103,0.740951,0.903989,0.989177},
{-0.995185,-0.956940,-0.881921,-0.773010,-0.634393,-0.471397,-0.290285,-0.098017,0.098017,0.290285,0.471397,0.634393,0.773010,0.881921,0.956940,0.995185,
0.995185,0.956940,0.881921,0.773010,0.634393,0.471397,0.290285,0.098017,-0.098017,-0.290285,-0.471397,-0.634393,-0.773010,-0.881921,-0.956940,-0.995185},
{-0.998795,-0.989177,-0.970031,-0.941544,-0.903989,-0.857729,-0.803208,-0.740951,-0.671559,-0.595699,-0.514103,-0.427555,-0.336890,-0.242980,-0.146730,-0.049068,
0.049068,0.146730,0.242980,0.336890,0.427555,0.514103,0.595699,0.671559,0.740951,0.803208,0.857729,0.903989,0.941544,0.970031,0.989177,0.998795},
{-1.000000,-1.000000,-1.000000,-1.000000,-1.000000,-1.000000,-1.000000,-1.000000,-1.000000,-1.000000,-1.000000,-1.000000,-1.000000,-1.000000,-1.000000,-1.000000,
-1.000000,-1.000000,-1.000000,-1.000000,-1.000000,-1.000000,-1.000000,-1.000000,-1.000000,-1.000000,-1.000000,-1.000000,-1.000000,-1.000000,-1.000000,-1.000000},
{-0.998795,-0.989177,-0.970031,-0.941544,-0.903989,-0.857729,-0.803208,-0.740951,-0.671559,-0.595699,-0.514103,-0.427555,-0.336890,-0.242980,-0.146730,-0.049068,
0.049068,0.146730,0.242980,0.336890,0.427555,0.514103,0.595699,0.671559,0.740951,0.803208,0.857729,0.903989,0.941544,0.970031,0.989177,0.998795},
{-0.995185,-0.956940,-0.881921,-0.773010,-0.634393,-0.471397,-0.290285,-0.098017,0.098017,0.290285,0.471397,0.634393,0.773010,0.881921,0.956940,0.995185,
0.995185,0.956940,0.881921,0.773010,0.634393,0.471397,0.290285,0.098017,-0.098017,-0.290285,-0.471397,-0.634393,-0.773010,-0.881921,-0.956940,-0.995185},
{-0.989177,-0.903989,-0.740951,-0.514103,-0.242980,0.049068,0.336890,0.595699,0.803208,0.941544,0.998795,0.970031,0.857729,0.671559,0.427555,0.146730,
-0.146730,-0.427555,-0.671559,-0.857729,-0.970031,-0.998795,-0.941544,-0.803208,-0.595699,-0.336890,-0.049068,0.242980,0.514103,0.740951,0.903989,0.989177},
{-0.980785,-0.831470,-0.555570,-0.195090,0.195090,0.555570,0.831470,0.980785,0.980785,0.831470,0.555570,0.195090,-0.195090,-0.555570,-0.831470,-0.980785,
-0.980785,-0.831470,-0.555570,-0.195090,0.195090,0.555570,0.831470,0.980785,0.980785,0.831470,0.555570,0.195090,-0.195090,-0.555570,-0.831470,-0.980785},
{-0.970031,-0.740951,-0.336890,0.146730,0.595699,0.903989,0.998795,0.857729,0.514103,0.049068,-0.427555,-0.803208,-0.989177,-0.941544,-0.671559,-0.242980,
0.242980,0.671559,0.941544,0.989177,0.803208,0.427555,-0.049068,-0.514103,-0.857729,-0.998795,-0.903989,-0.595699,-0.146730,0.336890,0.740951,0.970031},
{-0.956940,-0.634393,-0.098017,0.471397,0.881921,0.995185,0.773010,0.290285,-0.290285,-0.773010,-0.995185,-0.881921,-0.471397,0.098017,0.634393,0.956940,
0.956940,0.634393,0.098017,-0.471397,-0.881921,-0.995185,-0.773010,-0.290285,0.290285,0.773010,0.995185,0.881921,0.471397,-0.098017,-0.634393,-0.956940},
{-0.941544,-0.514103,0.146730,0.740951,0.998795,0.803208,0.242980,-0.427555,-0.903989,-0.970031,-0.595699,0.049068,0.671559,0.989177,0.857729,0.336890,
-0.336890,-0.857729,-0.989177,-0.671559,-0.049068,0.595699,0.970031,0.903989,0.427555,-0.242980,-0.803208,-0.998795,-0.740951,-0.146730,0.514103,0.941544},
{-0.923880,-0.382683,0.382683,0.923880,0.923880,0.382683,-0.382683,-0.923880,-0.923880,-0.382683,0.382683,0.923880,0.923880,0.382683,-0.382683,-0.923880,
-0.923880,-0.382683,0.382683,0.923880,0.923880,0.382683,-0.382683,-0.923880,-0.923880,-0.382683,0.382683,0.923880,0.923880,0.382683,-0.382683,-0.923880},
{-0.903989,-0.242980,0.595699,0.998795,0.671559,-0.146730,-0.857729,-0.941544,-0.336890,0.514103,0.989177,0.740951,-0.049068,-0.803208,-0.970031,-0.427555,
0.427555,0.970031,0.803208,0.049068,-0.740951,-0.989177,-0.514103,0.336890,0.941544,0.857729,0.146730,-0.671559,-0.998795,-0.595699,0.242980,0.903989},
{-0.881921,-0.098017,0.773010,0.956940,0.290285,-0.634393,-0.995185,-0.471397,0.471397,0.995185,0.634393,-0.290285,-0.956940,-0.773010,0.098017,0.881921,
0.881921,0.098017,-0.773010,-0.956940,-0.290285,0.634393,0.995185,0.471397,-0.471397,-0.995185,-0.634393,0.290285,0.956940,0.773010,-0.098017,-0.881921},
{-0.857729,0.049068,0.903989,0.803208,-0.146730,-0.941544,-0.740951,0.242980,0.970031,0.671559,-0.336890,-0.989177,-0.595699,0.427555,0.998795,0.514103,
-0.514103,-0.998795,-0.427555,0.595699,0.989177,0.336890,-0.671559,-0.970031,-0.242980,0.740951,0.941544,0.146730,-0.803208,-0.903989,-0.049068,0.857729},
{-0.831470,0.195090,0.980785,0.555570,-0.555570,-0.980785,-0.195090,0.831470,0.831470,-0.195090,-0.980785,-0.555570,0.555570,0.980785,0.195090,-0.831470,
-0.831470,0.195090,0.980785,0.555570,-0.555570,-0.980785,-0.195090,0.831470,0.831470,-0.195090,-0.980785,-0.555570,0.555570,0.980785,0.195090,-0.831470},
{-0.803208,0.336890,0.998795,0.242980,-0.857729,-0.740951,0.427555,0.989177,0.146730,-0.903989,-0.671559,0.514103,0.970031,0.049068,-0.941544,-0.595699,
0.595699,0.941544,-0.049068,-0.970031,-0.514103,0.671559,0.903989,-0.146730,-0.989177,-0.427555,0.740951,0.857729,-0.242980,-0.998795,-0.336890,0.803208},
{-0.773010,0.471397,0.956940,-0.098017,-0.995185,-0.290285,0.881921,0.634393,-0.634393,-0.881921,0.290285,0.995185,0.098017,-0.956940,-0.471397,0.773010,
0.773010,-0.471397,-0.956940,0.098017,0.995185,0.290285,-0.881921,-0.634393,0.634393,0.881921,-0.290285,-0.995185,-0.098017,0.956940,0.471397,-0.773010},
{-0.740951,0.595699,0.857729,-0.427555,-0.941544,0.242980,0.989177,-0.049068,-0.998795,-0.146730,0.970031,0.336890,-0.903989,-0.514103,0.803208,0.671559,
-0.671559,-0.803208,0.514103,0.903989,-0.336890,-0.970031,0.146730,0.998795,0.049068,-0.989177,-0.242980,0.941544,0.427555,-0.857729,-0.595699,0.740951}
};
// up to 32-bits
static unsigned jo_readBits(const unsigned char *data, int *at, int num) {
unsigned r = 0;
// read partial starting bits
int sc = (8 - (*at & 7)) & 7;
sc = sc > num ? num : sc;
if(sc) {
r = (data[*at/8] >> (8 - (*at&7) - sc)) & ((1<<sc)-1);
num -= sc;
*at += sc;
}
// read full bytes
while(num>=8) {
r <<= 8;
r |= data[*at/8];
*at += 8;
num -= 8;
}
// read partial ending bits
if(num) {
r <<= num;
r |= (data[*at/8] >> (8 - num)) & ((1<<num)-1);
*at += num;
}
return r;
}
bool jo_read_mp1(const void *input, int inputSize, short **output_, int *outputSize_, int *hz_, int *channels_) {
int outputSize = 0, hz, channels;
short *output = 0;
int outputMax = 0;
const unsigned char *data = (const unsigned char *)input;
// Buffers for the lapped transform
double buf[2][2 * 512] = { 0 };
int bufOffset[2] = { 64,64 };
int at = 0; // Where in the stream are we?
while (at < inputSize * 8) {
// Sync markers are byte aligned
at = (at + 7)&-8;
while (at < inputSize * 8 - 32) {
if (data[at / 8] == 0xFF && (data[at / 8 + 1] & 0xF0) == 0xF0) {
break;
}
else {
at += 8;
}
}
if (at >= inputSize * 8 - 32) {
break;
}
unsigned header = jo_readBits(data, &at, 32);
//printf("header: %x.%x/%x: %08x\n", (at-32)/8, (at-32)&7, inputSize, header);
// sync = 0xFFF
// ID = 1
// layer = 3 (layer 1)
if ((header & 0xFFFE0000) != 0xFFFE0000) {
return false;
}
static const int bitrateTbl[16] = { 0,32,40,48,56,64,80,96,112,128,160,192,224,256,320,-1 };
int kbps = bitrateTbl[(header >> 12) & 15];
if (kbps < 0) {
return false;
}
static const int hzTbl[4] = { 44100, 48000, 32000, 0 };
hz = hzTbl[(header >> 10) & 3];
if (!hz) {
return false;
}
// mode 0 = stereo
// mode 1 = joint stereo
// mode 2 = dual channel (no idea what this does TODO)
// mode 3 = mono
int mode = (header >> 6) & 3;
int modeExt = (header >> 4) & 3;
channels = mode == 3 ? 1 : 2;
const int bound = mode == 1 ? (modeExt + 1) * 4 : 32;
bool errorProtection = ((header >> 16) & 1) ^ 1; //< @r-lyeh extra parens
if (errorProtection) {
at += 16; // skip the CRC.
}
// Read bit allocations
int bitAlloc[32][2] = { 0 };
for (int i = 0; i < bound; ++i) {
for (int ch = 0; ch < channels; ++ch) {
bitAlloc[i][ch] = jo_readBits(data, &at, 4);
}
}
for (int i = bound; i < 32; ++i) {
bitAlloc[i][1] = bitAlloc[i][0] = jo_readBits(data, &at, 4);
}
// Read scale indexes
int scaleIdx[32][2];
for (int i = 0; i < 32; ++i) {
for (int ch = 0; ch < channels; ++ch) {
scaleIdx[i][ch] = bitAlloc[i][ch] ? jo_readBits(data, &at, 6) : 63;
}
}
// Read & compute output samples
short pcm[12][2][32];
for (int s = 0; s < 12; ++s) {
// Read normalized, quantized band samples
int samples[32][2] = { 0 };
for (int i = 0; i < bound; ++i) {
for (int ch = 0; ch < channels; ++ch) {
if (bitAlloc[i][ch]) {
samples[i][ch] = jo_readBits(data, &at, bitAlloc[i][ch] + 1);
}
}
}
for (int i = bound; i < 32; ++i) {
if (bitAlloc[i][0]) {
samples[i][1] = samples[i][0] = jo_readBits(data, &at, bitAlloc[i][0] + 1);
}
}
// Compute bands: Dequantize & Denormalize
double bandTbl[2][32] = { 0 };
for (int i = 0; i < 32; ++i) {
for (int ch = 0; ch < channels; ++ch) {
int b = bitAlloc[i][ch];
if (b++) {
int samp = samples[i][ch];
double f = ((samp >> (b - 1)) & 1) ? 0 : -1;
f += (samp & ((1 << (b - 1)) - 1)) / (double)(1 << (b - 1));
f = (f + 1.0 / (1 << (b - 1))) * (1 << b) / ((1 << b) - 1.0);
f *= s_jo_multTbl[scaleIdx[i][ch]];
bandTbl[ch][i] = f;
}
}
}
// Convert subbands to PCM
for (int ch = 0; ch < channels; ++ch) {
bufOffset[ch] = (bufOffset[ch] + 0x3C0) & 0x3ff;
double *bufOffsetPtr = buf[ch] + bufOffset[ch];
const double *f = s_jo_filterTbl[0];
for (int i = 0; i < 64; ++i) {
double sum = 0;
for (int j = 0; j < 32; ++j) {
sum += *f++ * bandTbl[ch][j];
}
bufOffsetPtr[i] = sum;
}
const double *w = s_jo_windowTbl;
for (int i = 0; i < 32; ++i) {
double sum = 0;
for (int j = 0; j < 16; ++j) {
int k = i | (j + ((j + 1) & -2)) << 5;
sum += *w++ * buf[ch][(k + bufOffset[ch]) & 0x3ff];
}
int ss = (int)(sum * 0x8000);
ss = ss > SHRT_MAX ? SHRT_MAX : ss < SHRT_MIN ? SHRT_MIN : ss;
pcm[s][ch][i] = ss;
}
}
}
if (at > inputSize * 8) {
printf("file corruption?\n");
return false;
}
if (outputMax == 0) {
// estimate total number of samples (may be totally wrong, but its better than nothing)
at = (at + 7)&-8;
outputMax = inputSize / (at / 8) * 384 * channels * sizeof(*output);
output = (short*)REALLOC(output, outputMax);
}
if (outputSize * sizeof(*output) + 384 * channels * sizeof(*output) > outputMax) {
outputMax += 384 * channels * sizeof(*output);
output = (short*)REALLOC(output, outputMax);
}
for (int i = 0; i < 12; ++i) {
for (int j = 0; j < 32; ++j) {
for (int k = 0; k < channels; ++k) {
output[outputSize++] = pcm[i][k][j];
}
}
}
}
*outputSize_ = outputSize;
*hz_ = hz;
*channels_ = channels;
*output_ = output;
return outputSize && hz && channels && output;
}
#endif // JO_MP1_HEADER_FILE_ONLY

535
sfw/audio/3rd_sts_mixer.h Normal file
View File

@ -0,0 +1,535 @@
///////////////////////////////////////////////////////////////////////////////
// sts_mixer.h - v0.02
// written 2016 by Sebastian Steinhauer
//
// LICENSE
// Public domain. See "unlicense" statement at the end of this file.
//
// ABOUT
// A simple stereo audio mixer which is capable of mixing samples and audio streams.
// Samples can be played with different gain, pitch and panning.
// Streams can be played with different gain.
// This library has no malloc/free. All structs have to be "prepared" by the user. So you can enroll your own memory management.
// You have to implement/provide a real audio-backend to hear something from the speakers.
// A good starting point would be SDL2 where you can use an audio callback to feed the audio device.
//
// USAGE
// Please note that most audio systems will run in a separate thread. So you have to take care about locking before modifying the sts_mixer_t state.
// See the example at the end of the file.
//
// VERSION HISTORY
// 0.03 (2022-12-12) add an ability to stop audio stream via callback, add a method to check if voice is already stopped
// 0.02 (2022-05-10) allow voice queueing in same channel. ie, chain another sample on same voice channel after current sample playback is done (@r-lyeh)
// 0.01 (2016-05-01) initial version
//
#ifndef __INCLUDED__STS_MIXER_H__
#define __INCLUDED__STS_MIXER_H__
// The number of concurrent voices (channels) which are used to mix the audio.
// If you need more, use a higher number by setting #define STS_MIXER_VOICE n before including this header.
#ifndef STS_MIXER_VOICES
#define STS_MIXER_VOICES 32
#endif // STS_MIXER_VOICES
// Defines the various audio formats. Note that they are all on system endianess.
enum {
STS_MIXER_SAMPLE_FORMAT_NONE, // no format
STS_MIXER_SAMPLE_FORMAT_8, // signed 8-bit
STS_MIXER_SAMPLE_FORMAT_16, // signed 16-bit
STS_MIXER_SAMPLE_FORMAT_32, // signed 32-bit
STS_MIXER_SAMPLE_FORMAT_FLOAT // floats
};
////////////////////////////////////////////////////////////////////////////////
//
// SAMPLES
//
// A sample is a *MONO* piece of audio which is loaded fully to memory.
// It can be played with various gains, pitches and pannings.
//
typedef struct {
unsigned int length; // length in samples (so 1024 samples of STS_MIXER_SAMPLE_FORMAT_16 would be 2048 bytes)
unsigned int frequency; // frequency of this sample (e.g. 44100, 22000 ...)
int audio_format; // one of STS_MIXER_SAMPLE_FORMAT_*
void* data; // pointer to the sample data, sts_mixer makes no copy, so you have to keep them in memory
void* next; // next sample in chain (if any) //< @r-lyeh
} sts_mixer_sample_t;
////////////////////////////////////////////////////////////////////////////////
//
// STREAMS
//
// A stream is *STEREO* audio which will be decoded/loaded as needed.
// It can be played with various gains. No panning or pitching.
//
// The callback which will be called when the stream needs more data.
typedef bool (*sts_mixer_stream_callback)(sts_mixer_sample_t* sample, void* userdata);
typedef struct {
void* userdata; // a userdata pointer which will passed to the callback
sts_mixer_stream_callback callback; // this callback will be called when the stream needs more data
sts_mixer_sample_t sample; // the current stream "sample" which holds the current piece of audio
} sts_mixer_stream_t;
////////////////////////////////////////////////////////////////////////////////
//
// VOICES
//
// A voice is an audio source which will be used during mixing.
// It can play nothing, a sample or a stream.
// Most of those fields are considered "private" and you should not play around with those.
//
typedef struct {
int state;
sts_mixer_sample_t* sample;
sts_mixer_stream_t* stream;
float position;
float gain;
float pitch;
float pan;
} sts_mixer_voice_t;
////////////////////////////////////////////////////////////////////////////////
//
// MIXER
//
// The mixer state.
//
typedef struct {
float gain; // the global gain (you can change it if you want to change to overall volume)
unsigned int frequency; // the frequency for the output of mixed audio data
int audio_format; // the audio format for the output of mixed audio data
sts_mixer_voice_t voices[STS_MIXER_VOICES]; // holding all audio voices for this state
} sts_mixer_t;
////////////////////////////////////////////////////////////////////////////////
//
// API
//
// "Initializes" a new sts_mixer state.
void sts_mixer_init(sts_mixer_t* mixer, unsigned int frequency, int audio_format);
// "Shutdown" the mixer state. It will simply reset all fields.
void sts_mixer_shutdown(sts_mixer_t* mixer);
// Return the number of active voices. Active voices are voices that play either a stream or a sample.
int sts_mixer_get_active_voices(sts_mixer_t* mixer);
// Play the given sample with the gain, pitch and panning.
// Panning can be something between -1.0f (fully left) ... +1.0f (fully right)
// Please note that pitch will be clamped so it cannot reach 0.0f (would be useless).
// Returns the number of the voice where this sample will be played or -1 if no voice was free.
int sts_mixer_play_sample(sts_mixer_t* mixer, sts_mixer_sample_t* sample, float gain, float pitch, float pan);
// Plays the given stream with the gain.
// Returns the number of the voice where this stream will be played or -1 if no voice was free.
int sts_mixer_play_stream(sts_mixer_t* mixer, sts_mixer_stream_t* stream, float gain);
// Stops voice with the given voice no. You can pass the returned number of sts_mixer_play_sample / sts_mixer_play_stream here.
void sts_mixer_stop_voice(sts_mixer_t* mixer, int voice);
// Returns whether the given sample has already stopped playing.
bool sts_mixer_sample_stopped(sts_mixer_t* mixer, sts_mixer_sample_t* sample);
// Returns whether the given stream has already stopped playing.
bool sts_mixer_stream_stopped(sts_mixer_t* mixer, sts_mixer_stream_t* stream);
// Stops all voices playing the given sample. Useful when you want to delete the sample and make sure it is not used anymore.
void sts_mixer_stop_sample(sts_mixer_t* mixer, sts_mixer_sample_t* sample);
// Stops all voices playing the given stream. Useful when you want to delete the stream and make sure it is not used anymore.
void sts_mixer_stop_stream(sts_mixer_t* mixer, sts_mixer_stream_t* stream);
// The mixing function. You should call the function if you need to pass more audio data to the audio device.
// Typically this function is called in a separate thread or something like that.
// It will write audio data in the specified format and frequency of the mixer state.
void sts_mixer_mix_audio(sts_mixer_t* mixer, void* output, unsigned int samples);
#endif // __INCLUDED__STS_MIXER_H__
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
////
//// IMPLEMENTATION
////
////
#ifdef STS_MIXER_IMPLEMENTATION
enum {
STS_MIXER_VOICE_STOPPED,
STS_MIXER_VOICE_PLAYING,
STS_MIXER_VOICE_STREAMING
};
static float sts_mixer__clamp(const float value, const float min, const float max) {
if (value < min) return min;
else if (value > max) return max;
else return value;
}
static float sts_mixer__clamp_sample(const float sample) {
if (sample < -1.0f) return -1.0f;
else if (sample > 1.0f) return 1.0f;
else return sample;
}
static float sts_mixer__get_sample(sts_mixer_sample_t* sample, unsigned int position) {
switch (sample->audio_format) {
case STS_MIXER_SAMPLE_FORMAT_8:
return (float)((char*)sample->data)[position] / 127.0f;
case STS_MIXER_SAMPLE_FORMAT_16:
return (float)((short*)sample->data)[position] / 32767.0f;
case STS_MIXER_SAMPLE_FORMAT_32:
return (float)((int*)sample->data)[position] / 2147483647.0f;
case STS_MIXER_SAMPLE_FORMAT_FLOAT:
return ((float*)sample->data)[position];
default:
return 0.0f;
}
}
static void sts_mixer__reset_voice(sts_mixer_t* mixer, const int i) {
sts_mixer_voice_t* voice = &mixer->voices[i];
voice->state = STS_MIXER_VOICE_STOPPED;
voice->sample = 0;
voice->stream = 0;
voice->position = voice->gain = voice->pitch = voice->pan = 0.0f;
}
static int sts_mixer__find_free_voice(sts_mixer_t* mixer) {
int i;
for (i = 0; i < STS_MIXER_VOICES; ++i) {
if (mixer->voices[i].state == STS_MIXER_VOICE_STOPPED) return i;
}
return -1;
}
void sts_mixer_init(sts_mixer_t* mixer, unsigned int frequency, int audio_format) {
int i;
for (i = 0; i < STS_MIXER_VOICES; ++i) sts_mixer__reset_voice(mixer, i);
mixer->frequency = frequency;
mixer->gain = 1.0f;
mixer->audio_format = audio_format;
}
void sts_mixer_shutdown(sts_mixer_t* mixer) {
sts_mixer_init(mixer, 0, 0);
}
int sts_mixer_get_active_voices(sts_mixer_t* mixer) {
int i, active;
for (i = 0, active = 0; i < STS_MIXER_VOICES; ++i) {
if (mixer->voices[i].state != STS_MIXER_VOICE_STOPPED) ++active;
}
return active;
}
int sts_mixer_play_sample(sts_mixer_t* mixer, sts_mixer_sample_t* sample, float gain, float pitch, float pan) {
int i;
sts_mixer_voice_t* voice;
i = sts_mixer__find_free_voice(mixer);
if (i >= 0) {
voice = &mixer->voices[i];
voice->gain = gain;
voice->pitch = sts_mixer__clamp(pitch, 0.1f, 10.0f);
voice->pan = sts_mixer__clamp(pan * 0.5f, -0.5f, 0.5f);
voice->position = 0.0f;
voice->sample = sample;
voice->stream = 0;
voice->state = STS_MIXER_VOICE_PLAYING;
}
return i;
}
int sts_mixer_play_stream(sts_mixer_t* mixer, sts_mixer_stream_t* stream, float gain) {
int i;
sts_mixer_voice_t* voice;
i = sts_mixer__find_free_voice(mixer);
if (i >= 0) {
voice = &mixer->voices[i];
voice->gain = gain;
voice->position = 0.0f;
voice->sample = 0;
voice->stream = stream;
voice->state = STS_MIXER_VOICE_STREAMING;
}
return i;
}
void sts_mixer_stop_voice(sts_mixer_t* mixer, int voice) {
if (voice >= 0 && voice < STS_MIXER_VOICES) sts_mixer__reset_voice(mixer, voice);
}
bool sts_mixer_sample_stopped(sts_mixer_t* mixer, sts_mixer_sample_t* sample) {
for (int i = 0; i < STS_MIXER_VOICES; ++i) {
if (mixer->voices[i].sample == sample && mixer->voices[i].state != STS_MIXER_VOICE_STOPPED) return false;
}
return true;
}
bool sts_mixer_stream_stopped(sts_mixer_t* mixer, sts_mixer_stream_t* stream) {
for (int i = 0; i < STS_MIXER_VOICES; ++i) {
if (mixer->voices[i].stream == stream && mixer->voices[i].state != STS_MIXER_VOICE_STOPPED) return false;
}
return true;
}
void sts_mixer_stop_sample(sts_mixer_t* mixer, sts_mixer_sample_t* sample) {
int i;
for (i = 0; i < STS_MIXER_VOICES; ++i) {
if (mixer->voices[i].sample == sample) sts_mixer__reset_voice(mixer, i);
}
}
void sts_mixer_stop_stream(sts_mixer_t* mixer, sts_mixer_stream_t* stream) {
int i;
for (i = 0; i < STS_MIXER_VOICES; ++i) {
if (mixer->voices[i].stream == stream) sts_mixer__reset_voice(mixer, i);
}
}
void sts_mixer_mix_audio(sts_mixer_t* mixer, void* output, unsigned int samples) {
sts_mixer_voice_t* voice;
unsigned int i, position;
float left, right, advance, sample;
char* out_8 = (char*)output;
short* out_16 = (short*)output;
int* out_32 = (int*)output;
float* out_float = (float*)output;
// mix all voices
advance = 1.0f / (float)mixer->frequency;
for (; samples > 0; --samples) {
left = right = 0.0f;
for (i = 0; i < STS_MIXER_VOICES; ++i) {
voice = &mixer->voices[i];
if (voice->state == STS_MIXER_VOICE_PLAYING) {
position = (int)voice->position;
if (position < voice->sample->length) {
sample = sts_mixer__clamp_sample(sts_mixer__get_sample(voice->sample, position) * voice->gain);
left += sts_mixer__clamp_sample(sample * (0.5f - voice->pan));
right += sts_mixer__clamp_sample(sample * (0.5f + voice->pan));
voice->position += (float)voice->sample->frequency * advance * voice->pitch;
} else if( voice->sample->next ) { //< @r-lyeh
*voice->sample = *(sts_mixer_sample_t*)voice->sample->next; //< @r-lyeh
voice->position = 0; //< @r-lyeh
} else sts_mixer__reset_voice(mixer, i);
} else if (voice->state == STS_MIXER_VOICE_STREAMING) {
position = ((int)voice->position) * 2;
if (position >= voice->stream->sample.length) {
// buffer empty...refill
if (voice->stream->callback(&voice->stream->sample, voice->stream->userdata)) {
voice->position = 0.0f;
position = 0;
} else {
sts_mixer__reset_voice(mixer, i);
continue;
}
}
left += sts_mixer__clamp_sample(sts_mixer__get_sample(&voice->stream->sample, position) * voice->gain);
right += sts_mixer__clamp_sample(sts_mixer__get_sample(&voice->stream->sample, position + 1) * voice->gain);
voice->position += (float)voice->stream->sample.frequency * advance;
}
}
// write to buffer.
float _g = mixer->gain; //< @r-lyeh: added master gain
float _127 = 127.0f * _g; //< @r-lyeh: added master gain
float _32767 = 32767.0f * _g; //< @r-lyeh: added master gain
float _2147483647 = 2147483647.0f * _g; //< @r-lyeh: added master gain
left = sts_mixer__clamp_sample(left);
right = sts_mixer__clamp_sample(right);
switch (mixer->audio_format) {
case STS_MIXER_SAMPLE_FORMAT_8:
*out_8++ = (char)(left * _127); //< @r-lyeh: added master gain
*out_8++ = (char)(right * _127); //< @r-lyeh: added master gain
break;
case STS_MIXER_SAMPLE_FORMAT_16:
*out_16++ = (short)(left * _32767); //< @r-lyeh: added master gain
*out_16++ = (short)(right * _32767); //< @r-lyeh: added master gain
break;
case STS_MIXER_SAMPLE_FORMAT_32:
*out_32++ = (int)(left * _2147483647); //< @r-lyeh: added master gain
*out_32++ = (int)(right * _2147483647); //< @r-lyeh: added master gain
break;
case STS_MIXER_SAMPLE_FORMAT_FLOAT:
*out_float++ = left * _g; //< @r-lyeh: added master gain
*out_float++ = right * _g; //< @r-lyeh: added master gain
break;
}
}
}
#endif // STS_MIXER_IMPLEMENTATION
////////////////////////////////////////////////////////////////////////////////
// EXAMPLE
// This is a very simple example loading a stream and a sample using
// dr_flac.h (https://github.com/mackron/dr_libs) and SDL2. You can of course also use stb_vorbis or something similar :)
// Please note how the audio thread of SDL2 will be locked when the mixer state get's modified. This is important!
// Also there's no error checking in the entire example code, so beware.
//
#if 0
#include "SDL.h"
#define DR_FLAC_IMPLEMENTATION
#include "dr_flac.h"
#define STS_MIXER_IMPLEMENTATION
#include "sts_mixer.h"
SDL_AudioDeviceID audio_device = 0;
sts_mixer_t mixer;
// encapsulate drflac and some buffer with the sts_mixer_stream_t
typedef struct {
drflac* flac; // FLAC decoder state
sts_mixer_stream_t stream; // mixer stream
int32_t data[4096*2]; // static sample buffer
} mystream_t;
// SDL2 audio callback
static void audio_callback(void* userdata, Uint8* stream, int len) {
(void)(userdata);
sts_mixer_mix_audio(&mixer, stream, len / (sizeof(int) * 2));
}
// load a sample
static void load_sample(sts_mixer_sample_t* sample, const char *filename) {
drflac* flac = drflac_open_file(filename);
sample->frequency = flac->sampleRate;
sample->audio_format = STS_MIXER_SAMPLE_FORMAT_32;
sample->length = flac->totalSampleCount;
sample->data = malloc(sample->length * sizeof(int32_t));
drflac_read_s32(flac, sample->length, (int32_t*)sample->data);
drflac_close(flac);
}
// the callback to refill the stream data
static void refill_stream(sts_mixer_sample_t* sample, void* userdata) {
mystream_t* stream = (mystream_t*)userdata;
if (drflac_read_s32(stream->flac, sample->length, stream->data) < sample->length) drflac_seek_to_sample(stream->flac, 0);
}
// load a stream
static void load_stream(mystream_t* stream, const char *filename) {
stream->flac = drflac_open_file(filename);
stream->stream.userdata = stream;
stream->stream.callback = refill_stream;
stream->stream.sample.frequency = stream->flac->sampleRate;
stream->stream.sample.audio_format = STS_MIXER_SAMPLE_FORMAT_32;
stream->stream.sample.length = 4096*2;
stream->stream.sample.data = stream->data;
refill_stream(&stream->stream.sample, stream);
}
// helper to get random [0.0f..1.0f values
static float randf() {
return (float)(rand()) / (float)RAND_MAX;
}
int main(int argc, char *argv[]) {
SDL_AudioSpec want, have;
sts_mixer_sample_t sample;
mystream_t stream;
(void)(argc); (void)(argv);
// init SDL2 + audio
want.format = AUDIO_S32SYS;
want.freq = 44100;
want.channels = 2;
want.userdata = NULL;
want.samples = 4096;
want.callback = audio_callback;
SDL_Init(SDL_INIT_AUDIO);
audio_device = SDL_OpenAudioDevice(NULL, 0, &want, &have, 0);
// init sts_mixer and load things
sts_mixer_init(&mixer, 44100, STS_MIXER_SAMPLE_FORMAT_32);
load_sample(&sample, "effect.flac");
load_stream(&stream, "music.flac");
// play the stream
sts_mixer_play_stream(&mixer, &stream.stream, 0.7f);
// start audio processing and do a loop for audio effects
SDL_PauseAudioDevice(audio_device, 0);
for (;;) {
// !!!IMPORTANT!!! lock the audio thread before modifying data in the sts_mixer !!!
SDL_LockAudioDevice(audio_device);
// play a sample with random gain, pitch and panning
sts_mixer_play_sample(&mixer, &sample, randf(), 0.5f + randf(), -1.0f + randf() * 2.0f);
// unlock audio thread again
SDL_UnlockAudioDevice(audio_device);
// wait ...
SDL_Delay(76);
}
SDL_PauseAudioDevice(audio_device, 1);
SDL_CloseAudioDevice(audio_device);
SDL_Quit();
return 0;
}
#endif // 0
/*
This is free and unencumbered software released into the public domain.
Anyone is free to copy, modify, publish, use, compile, sell, or
distribute this software, either in source code form or as a compiled
binary, for any purpose, commercial or non-commercial, and by any
means.
In jurisdictions that recognize copyright laws, the author or authors
of this software dedicate any and all copyright interest in the
software to the public domain. We make this dedication for the benefit
of the public at large and to the detriment of our heirs and
successors. We intend this dedication to be an overt act of
relinquishment in perpetuity of all present and future rights to this
software under copyright law.
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 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.
For more information, please refer to <http://unlicense.org/>
*/

View File

@ -1,3 +1,30 @@
#define MINIAUDIO_IMPLEMENTATION // miniaudio
#define MA_NO_FLAC // miniaudio
#define STS_MIXER_IMPLEMENTATION // sts_mixer
#ifdef __APPLE__
#define MA_NO_RUNTIME_LINKING // miniaudio osx
#endif
//--STRIP
#include "core/memory.h"
#include "audio.h"
#include "3rd_jo_mp1.h"
#define get_bits stb_vorbis_get_bits
#define error stb_vorbis_error
#include "3rd_stb_vorbis.h"
#undef error
#undef DEBUG
#include "3rd_miniaudio.h"
#include "3rd_sts_mixer.h"
//--STRIP
// @fixme: really shutdown audio & related threads before quitting. ma_dr_wav crashes.
// encapsulate ma_dr_wav,ma_dr_mp3,stbvorbis and some buffer with the sts_mixer_stream_t
@ -95,15 +122,21 @@ static void reset_stream(mystream_t *stream) {
// load a (stereo) stream
static bool load_stream(mystream_t *stream, const char *filename) {
int datalen;
char *data = vfs_load(filename, &datalen);
if (!data)
int datalen = 0;
//char *data = vfs_load(filename, &datalen);
char *data = NULL;
if (!data) {
return false;
}
int error;
int HZ = 44100;
//int HZ = 44100;
stream->type = UNK;
stream->loop = true;
if (stream->type == UNK && (stream->ogg = stb_vorbis_open_memory((const unsigned char *)data, datalen, &error, NULL))) {
stb_vorbis_info info = stb_vorbis_get_info(stream->ogg);
if (info.channels != 2) {
@ -114,7 +147,7 @@ static bool load_stream(mystream_t *stream, const char *filename) {
stream->stream.sample.frequency = info.sample_rate;
stream->stream.sample.audio_format = STS_MIXER_SAMPLE_FORMAT_16;
}
if (stream->type == UNK && ma_dr_wav_init_memory(&stream->wav, data, datalen, NULL)) {
if (stream->type == UNK && ma_dr_wav_init_memory(&stream->wav, data, (size_t)datalen, NULL)) {
if (stream->wav.channels != 2) {
puts("cannot stream wav file. stereo required.");
goto end;
@ -123,11 +156,15 @@ static bool load_stream(mystream_t *stream, const char *filename) {
stream->stream.sample.frequency = stream->wav.sampleRate;
stream->stream.sample.audio_format = STS_MIXER_SAMPLE_FORMAT_16;
}
ma_dr_mp3_config mp3_cfg = { 2, HZ };
if (stream->type == UNK && (ma_dr_mp3_init_memory(&stream->mp3_, data, datalen, NULL /*&mp3_cfg*/) != 0)) {
stream->type = MP3;
stream->stream.sample.frequency = stream->mp3_.sampleRate;
stream->stream.sample.audio_format = STS_MIXER_SAMPLE_FORMAT_FLOAT;
if (stream->type == UNK) {
//ma_dr_mp3_config mp3_cfg = { 2, HZ };
if ((ma_dr_mp3_init_memory(&stream->mp3_, data, (size_t)datalen, NULL /*&mp3_cfg*/) != 0)) {
stream->type = MP3;
stream->stream.sample.frequency = stream->mp3_.sampleRate;
stream->stream.sample.audio_format = STS_MIXER_SAMPLE_FORMAT_FLOAT;
}
}
if (stream->type == UNK) {
@ -147,15 +184,19 @@ end:;
// load a (mono) sample
static bool load_sample(sts_mixer_sample_t *sample, const char *filename) {
int datalen;
char *data = vfs_load(filename, &datalen);
if (!data)
//char *data = vfs_load(filename, &datalen);
char *data = NULL;
if (!data) {
return false;
}
int error;
int channels = 0;
if (!channels)
for (ma_dr_wav w = { 0 }, *wav = &w; wav && ma_dr_wav_init_memory(wav, data, datalen, NULL); wav = 0) {
for (ma_dr_wav w = { 0 }, *wav = &w; wav && ma_dr_wav_init_memory(wav, data, (size_t)datalen, NULL); wav = 0) {
channels = wav->channels;
sample->frequency = wav->sampleRate;
sample->audio_format = STS_MIXER_SAMPLE_FORMAT_16;
@ -181,13 +222,14 @@ static bool load_sample(sts_mixer_sample_t *sample, const char *filename) {
ma_dr_mp3_config mp3_cfg = { 2, 44100 };
ma_uint64 mp3_fc;
if (!channels)
for (short *fbuf = ma_dr_mp3_open_memory_and_read_pcm_frames_s16(data, datalen, &mp3_cfg, &mp3_fc, NULL); fbuf; fbuf = 0) {
for (short *fbuf = ma_dr_mp3_open_memory_and_read_pcm_frames_s16(data, (size_t)datalen, &mp3_cfg, &mp3_fc, NULL); fbuf; fbuf = 0) {
channels = mp3_cfg.channels;
sample->frequency = mp3_cfg.sampleRate;
sample->audio_format = STS_MIXER_SAMPLE_FORMAT_16;
sample->length = mp3_fc; // / sizeof(float) / mp3_cfg.channels;
sample->data = fbuf;
}
if (!channels) {
short *output = 0;
int outputSize, hz, mp1channels;
@ -287,8 +329,8 @@ int audio_init(int flags) {
#endif
};
if (ma_context_init(backends, countof(backends), NULL, &context) != MA_SUCCESS) {
PRINTF("%s\n", "Failed to initialize audio context.");
if (ma_context_init(backends, (int)(sizeof(backends) / sizeof(0 [backends])), NULL, &context) != MA_SUCCESS) {
LOG_ERR("Failed to initialize audio context.");
return false;
}
@ -297,7 +339,7 @@ int audio_init(int flags) {
config.playback.format = ma_format_s32;
config.playback.channels = 2;
config.sampleRate = 44100;
config.dataCallback = (void *)audio_callback; //< @r-lyeh add void* cast
config.dataCallback = audio_callback;
config.pUserData = NULL;
if (ma_device_init(NULL, &config, &device) != MA_SUCCESS) {
@ -320,20 +362,20 @@ typedef struct audio_handle {
};
} audio_handle;
static array(audio_handle *) audio_instances;
static Vector<audio_handle *> audio_instances;
audio_t audio_clip(const char *pathfile) {
audio_handle *a = REALLOC(0, sizeof(audio_handle));
audio_handle *a = memnew(audio_handle);
memset(a, 0, sizeof(audio_handle));
a->is_clip = load_sample(&a->clip, pathfile);
array_push(audio_instances, a);
audio_instances.push_back(a);
return a;
}
audio_t audio_stream(const char *pathfile) {
audio_handle *a = REALLOC(0, sizeof(audio_handle));
audio_handle *a = memnew(audio_handle);
memset(a, 0, sizeof(audio_handle));
a->is_stream = load_stream(&a->stream, pathfile);
array_push(audio_instances, a);
audio_instances.push_back(a);
return a;
}
@ -342,7 +384,7 @@ float audio_volume_clip(float gain) {
if (gain >= 0 && gain <= 1)
volume_clip = gain * gain;
// patch all live clips
for (int i = 0, active = 0; i < STS_MIXER_VOICES; ++i) {
for (int i = 0; i < STS_MIXER_VOICES; ++i) {
if (mixer.voices[i].state != STS_MIXER_VOICE_STOPPED) // is_active?
if (mixer.voices[i].sample) // is_sample?
mixer.voices[i].gain = volume_clip;
@ -353,7 +395,7 @@ float audio_volume_stream(float gain) {
if (gain >= 0 && gain <= 1)
volume_stream = gain * gain;
// patch all live streams
for (int i = 0, active = 0; i < STS_MIXER_VOICES; ++i) {
for (int i = 0; i < STS_MIXER_VOICES; ++i) {
if (mixer.voices[i].state != STS_MIXER_VOICE_STOPPED) // is_active?
if (mixer.voices[i].stream) // is_stream?
mixer.voices[i].gain = volume_stream;
@ -369,9 +411,11 @@ float audio_volume_master(float gain) {
}
int audio_mute(int mute) {
static bool muted = 0;
do_once muted = flag("--mute") || flag("--muted");
if (mute >= 0 && mute <= 1)
if (mute >= 0 && mute <= 1) {
muted = mute;
}
return muted;
}
int audio_muted() {
@ -479,13 +523,14 @@ static bool audio_queue_callback(sts_mixer_sample_t *sample, void *userdata) {
int sl = sample->length / 2; // 2 ch
int bytes = sl * 2 * (sample->audio_format == STS_MIXER_SAMPLE_FORMAT_16 ? 2 : 4);
char *dst = sample->data;
char *dst = (char *)sample->data;
static audio_queue_t *aq = 0;
do {
while (!aq)
while (!aq) {
aq = (audio_queue_t *)thread_queue_consume(&queue_mutex, THREAD_QUEUE_WAIT_INFINITE);
}
int len = aq->avail > bytes ? bytes : aq->avail;
memcpy(dst, (char *)aq->data + aq->cursor, len);
@ -495,7 +540,7 @@ static bool audio_queue_callback(sts_mixer_sample_t *sample, void *userdata) {
aq->avail -= len;
if (aq->avail <= 0) {
FREE(aq); // @fixme: mattias' original thread_queue_consume() implementation crashes here on tcc+win because of a double free on same pointer. using mcmp for now
memfree(aq); // @fixme: mattias' original thread_queue_consume() implementation crashes here on tcc+win because of a double free on same pointer. using mcmp for now
aq = 0;
}
} while (bytes > 0);
@ -542,7 +587,7 @@ int audio_queue(const void *samples, int num_samples, int flags) {
return 0;
}
audio_queue_t *aq = MALLOC(sizeof(audio_queue_t) + (bytes << (channels == 1))); // dupe space if going to be converted from mono to stereo
audio_queue_t *aq = (audio_queue_t *)memalloc(sizeof(audio_queue_t) + (bytes << (channels == 1))); // dupe space if going to be converted from mono to stereo
aq->cursor = 0;
aq->avail = bytes;
aq->flags = flags;

View File

@ -163,11 +163,11 @@ inline bool AABB::encloses(const AABB &p_aabb) const {
return (
(src_min.x <= dst_min.x) &&
(src_max.x > dst_max.x) &&
(src_max.x >= dst_max.x) &&
(src_min.y <= dst_min.y) &&
(src_max.y > dst_max.y) &&
(src_max.y >= dst_max.y) &&
(src_min.z <= dst_min.z) &&
(src_max.z > dst_max.z));
(src_max.z >= dst_max.z));
}
Vector3 AABB::get_support(const Vector3 &p_normal) const {

View File

@ -1160,12 +1160,16 @@ void Basis::rotate_sh(real_t *p_values) {
p_values[8] = d4 * s_scale_dst4;
}
Basis Basis::looking_at(const Vector3 &p_target, const Vector3 &p_up) {
Basis Basis::looking_at(const Vector3 &p_target, const Vector3 &p_up, bool p_use_model_front) {
#ifdef MATH_CHECKS
ERR_FAIL_COND_V_MSG(p_target.is_equal_approx(Vector3()), Basis(), "The target vector can't be zero.");
ERR_FAIL_COND_V_MSG(p_up.is_equal_approx(Vector3()), Basis(), "The up vector can't be zero.");
#endif
Vector3 v_z = -p_target.normalized();
Vector3 v_z = p_target.normalized();
if (!p_use_model_front) {
v_z = -v_z;
}
Vector3 v_x = p_up.cross(v_z);
#ifdef MATH_CHECKS
ERR_FAIL_COND_V_MSG(v_x.is_equal_approx(Vector3()), Basis(), "The target vector and up vector can't be parallel to each other.");

View File

@ -264,7 +264,7 @@ struct _NO_DISCARD_CLASS_ Basis {
// only be used in cases of single normals, or when the basis changes each time.
Vector3 xform_normal(const Vector3 &p_vector) const { return get_normal_xform_basis().xform_normal_fast(p_vector); }
static Basis looking_at(const Vector3 &p_target, const Vector3 &p_up = Vector3(0, 1, 0));
static Basis looking_at(const Vector3 &p_target, const Vector3 &p_up = Vector3(0, 1, 0), bool p_use_model_front = false);
static Basis from_scale(const Vector3 &p_scale);
operator Quaternion() const { return get_quaternion(); }

View File

@ -105,6 +105,9 @@ public:
static _ALWAYS_INLINE_ double exp(double p_x) { return ::exp(p_x); }
static _ALWAYS_INLINE_ float exp(float p_x) { return ::expf(p_x); }
static _ALWAYS_INLINE_ double exp2(double p_x) { return ::exp2(p_x); }
static _ALWAYS_INLINE_ float exp2(float p_x) { return ::exp2f(p_x); }
static _ALWAYS_INLINE_ double erf(double p_x) { return ::erf(p_x); }
static _ALWAYS_INLINE_ float erf(float p_x) { return ::erff(p_x); }

View File

@ -58,34 +58,7 @@ void Transform::rotate_basis(const Vector3 &p_axis, real_t p_phi) {
}
void Transform::set_look_at(const Vector3 &p_eye, const Vector3 &p_target, const Vector3 &p_up) {
#ifdef MATH_CHECKS
ERR_FAIL_COND(p_eye == p_target);
ERR_FAIL_COND(p_up.length() == 0);
#endif
// Reference: MESA source code
Vector3 v_x, v_y, v_z;
/* Make rotation matrix */
/* Z vector */
v_z = p_eye - p_target;
v_z.normalize();
v_y = p_up;
v_x = v_y.cross(v_z);
#ifdef MATH_CHECKS
ERR_FAIL_COND(v_x.length() == 0);
#endif
/* Recompute Y = Z cross X */
v_y = v_z.cross(v_x);
v_x.normalize();
v_y.normalize();
basis.set(v_x, v_y, v_z);
basis = Basis::looking_at(p_target - p_eye, p_up);
origin = p_eye;
}

View File

@ -24,6 +24,8 @@
#endif
//--STRIP
#define PRINT_UNICODE_ERRORS 0
#if defined(MINGW_ENABLED) || defined(_MSC_VER)
#define snprintf _snprintf_s
#endif
@ -234,7 +236,9 @@ void String::copy_from(const char *p_cstr) {
for (size_t i = 0; i <= len; i++) {
uint8_t c = p_cstr[i] >= 0 ? p_cstr[i] : uint8_t(256 + p_cstr[i]);
if (c == 0 && i < len) {
#if PRINT_UNICODE_ERRORS
print_unicode_error("NUL character", true);
#endif
dst[i] = 0x20;
} else {
dst[i] = c;
@ -267,7 +271,10 @@ void String::copy_from(const char *p_cstr, const int p_clip_to) {
for (int i = 0; i < len; i++) {
uint8_t c = p_cstr[i] >= 0 ? p_cstr[i] : uint8_t(256 + p_cstr[i]);
if (c == 0) {
#if PRINT_UNICODE_ERRORS
print_unicode_error("NUL character", true);
#endif
dst[i] = 0x20;
} else {
dst[i] = c;
@ -296,9 +303,16 @@ void String::copy_from(const wchar_t *p_cstr, const int p_clip_to) {
#endif
}
void String::copy_from(const Char16String &p_str) {
parse_utf16(p_str.ptr());
}
void String::copy_from(const CharType &p_char) {
if (p_char == 0) {
#if PRINT_UNICODE_ERRORS
print_unicode_error("NUL character", true);
#endif
return;
}
/*
@ -368,7 +382,10 @@ void String::copy_from_unchecked(const CharType *p_char, const int p_length) {
for (int i = 0; i < p_length; i++) {
if (p_char[i] == 0) {
#if PRINT_UNICODE_ERRORS
print_unicode_error("NUL character", true);
#endif
dst[i] = 0x20;
continue;
}
@ -449,7 +466,10 @@ String &String::operator+=(const String &p_str) {
String &String::operator+=(CharType p_char) {
if (p_char == 0) {
#if PRINT_UNICODE_ERRORS
print_unicode_error("NUL character", true);
#endif
return *this;
}
/*
@ -484,7 +504,10 @@ String &String::operator+=(const char *p_str) {
for (size_t i = 0; i <= rhs_len; i++) {
uint8_t c = p_str[i] >= 0 ? p_str[i] : uint8_t(256 + p_str[i]);
if (c == 0 && i < rhs_len) {
#if PRINT_UNICODE_ERRORS
print_unicode_error("NUL character", true);
#endif
dst[i] = 0x20;
} else {
dst[i] = c;
@ -889,7 +912,7 @@ String String::substr_index(const int start_index, const int end_index) const {
return "";
}
if (end_index >= s) {
if (end_index > s) {
return substr(start_index, (s - 1) - start_index);
}
@ -2385,13 +2408,16 @@ Vector<float> String::split_floats(const String &p_splitter, bool p_allow_empty)
int from = 0;
int len = length();
String buffer = *this;
while (true) {
int end = find(p_splitter, from);
if (end < 0) {
end = len;
}
if (p_allow_empty || (end > from)) {
ret.push_back(String::to_double(&get_data()[from]));
buffer[end] = 0;
ret.push_back(String::to_double(&buffer.get_data()[from]));
buffer[end] = _cowdata.get(end);
}
if (end == len) {
@ -2409,6 +2435,7 @@ Vector<float> String::split_floats_mk(const Vector<String> &p_splitters, bool p_
int from = 0;
int len = length();
String buffer = *this;
while (true) {
int idx;
int end = findmk(p_splitters, from, &idx);
@ -2420,7 +2447,9 @@ Vector<float> String::split_floats_mk(const Vector<String> &p_splitters, bool p_
}
if (p_allow_empty || (end > from)) {
ret.push_back(String::to_double(&get_data()[from]));
buffer[end] = 0;
ret.push_back(String::to_double(&buffer.get_data()[from]));
buffer[end] = _cowdata.get(end);
}
if (end == len) {
@ -4696,6 +4725,10 @@ String::String(const CharType *p_str) {
copy_from(p_str);
}
String::String(const Char16String &p_str) {
copy_from(p_str);
}
String::String(const char *p_str, int p_clip_to_len) {
copy_from(p_str, p_clip_to_len);
}

View File

@ -9,10 +9,11 @@
/*************************************************************************/
//--STRIP
#include "cowdata.h"
#include "core/vector.h"
#include "char_utils.h"
#include "core/math_defs.h"
#include "core/typedefs.h"
#include "core/vector.h"
#include "cowdata.h"
//--STRIP
/*************************************************************************/
@ -349,6 +350,13 @@ public:
int to_int() const;
bool to_bool() const;
uint32_t to_uint() const;
_FORCE_INLINE_ real_t to_real() const {
#ifdef REAL_T_IS_DOUBLE
return to_double();
#else
return to_float();
#endif
}
int hex_to_int(bool p_with_prefix = true) const;
int64_t hex_to_int64(bool p_with_prefix = true) const;
@ -367,6 +375,31 @@ public:
static double to_double(const wchar_t *p_str, const wchar_t **r_end = nullptr);
static double to_double(const CharType *p_str, const CharType **r_end = nullptr);
_FORCE_INLINE_ static real_t to_real(const char *p_str) {
#ifdef REAL_T_IS_DOUBLE
return to_double(p_str);
#else
return to_float(p_str);
#endif
}
_FORCE_INLINE_ static real_t to_real(const wchar_t *p_str, const wchar_t **r_end = nullptr) {
#ifdef REAL_T_IS_DOUBLE
return to_double(p_str, r_end);
#else
return to_float(p_str, r_end);
#endif
}
_FORCE_INLINE_ static real_t to_real(const CharType *p_str, const CharType **r_end = nullptr) {
#ifdef REAL_T_IS_DOUBLE
return to_double(p_str, r_end);
#else
return to_float(p_str, r_end);
#endif
}
static uint32_t num_characters(int64_t p_int);
String capitalize() const;
@ -508,6 +541,7 @@ public:
String(const char *p_str);
String(const wchar_t *p_str);
String(const CharType *p_str);
String(const Char16String &p_str);
String(const char *p_str, int p_clip_to_len);
String(const wchar_t *p_str, int p_clip_to_len);
String(const CharType *p_str, int p_clip_to_len);
@ -521,6 +555,7 @@ private:
void copy_from(const char *p_cstr, const int p_clip_to);
void copy_from(const wchar_t *p_cstr);
void copy_from(const wchar_t *p_cstr, const int p_clip_to);
void copy_from(const Char16String &p_str);
void copy_from(const CharType *p_cstr);
void copy_from(const CharType *p_cstr, const int p_clip_to);

View File

@ -5,6 +5,7 @@
//--STRIP
#include "core/vector2.h"
#include "core/vector2i.h"
#include "core/ustring.h"
//--STRIP
@ -147,6 +148,14 @@ bool Vector2::is_equal_approx(const Vector2 &p_v) const {
return Math::is_equal_approx(x, p_v.x) && Math::is_equal_approx(y, p_v.y);
}
bool Vector2::is_zero_approx() const {
return Math::is_zero_approx(x) && Math::is_zero_approx(y);
}
Vector2::operator String() const {
return "(" + String::num_real(x) + ", " + String::num_real(y) + ")";
}
Vector2::operator Vector2i() const {
return Vector2i(x, y);
}

View File

@ -15,6 +15,7 @@
//--STRIP
class String;
struct Vector2i;
struct _NO_DISCARD_CLASS_ Vector2 {
static const int AXIS_COUNT = 2;
@ -103,6 +104,7 @@ struct _NO_DISCARD_CLASS_ Vector2 {
Vector2 reflect(const Vector2 &p_normal) const;
bool is_equal_approx(const Vector2 &p_v) const;
bool is_zero_approx() const;
Vector2 operator+(const Vector2 &p_v) const;
void operator+=(const Vector2 &p_v);
@ -158,6 +160,7 @@ struct _NO_DISCARD_CLASS_ Vector2 {
real_t aspect() const { return width / height; }
operator String() const;
operator Vector2i() const;
_FORCE_INLINE_ Vector2(real_t p_x, real_t p_y) {
x = p_x;

View File

@ -107,10 +107,6 @@ struct _NO_DISCARD_CLASS_ Vector2i {
operator String() const;
operator Vector2() const { return Vector2(x, y); }
inline Vector2i(const Vector2 &p_vec2) {
x = (int)p_vec2.x;
y = (int)p_vec2.y;
}
inline Vector2i(int p_x, int p_y) {
x = p_x;
y = p_y;

View File

@ -82,6 +82,10 @@ bool Vector3::is_equal_approx(const Vector3 &p_v) const {
return Math::is_equal_approx(x, p_v.x) && Math::is_equal_approx(y, p_v.y) && Math::is_equal_approx(z, p_v.z);
}
bool Vector3::is_zero_approx() const {
return Math::is_zero_approx(x) && Math::is_zero_approx(y) && Math::is_zero_approx(z);
}
Vector3::operator String() const {
return "(" + String::num_real(x) + ", " + String::num_real(y) + ", " + String::num_real(z) + ")";
}

View File

@ -115,6 +115,7 @@ struct _NO_DISCARD_CLASS_ Vector3 {
bool is_equal_approx(const Vector3 &p_v) const;
inline bool is_equal_approx(const Vector3 &p_v, real_t p_tolerance) const;
inline bool is_equal_approxt(const Vector3 &p_v, real_t p_tolerance) const;
bool is_zero_approx() const;
/* Operators */

View File

@ -47,6 +47,10 @@ bool Vector4::is_equal_approx(const Vector4 &p_vec4) const {
return Math::is_equal_approx(x, p_vec4.x) && Math::is_equal_approx(y, p_vec4.y) && Math::is_equal_approx(z, p_vec4.z) && Math::is_equal_approx(w, p_vec4.w);
}
bool Vector4::is_zero_approx() const {
return Math::is_zero_approx(x) && Math::is_zero_approx(y) && Math::is_zero_approx(z) && Math::is_zero_approx(w);
}
real_t Vector4::length() const {
return Math::sqrt(length_squared());
}

View File

@ -51,6 +51,7 @@ struct _NO_DISCARD_CLASS_ Vector4 {
_FORCE_INLINE_ real_t length_squared() const;
bool is_equal_approx(const Vector4 &p_vec4) const;
bool is_zero_approx() const;
real_t length() const;
void normalize();
Vector4 normalized() const;

View File

@ -10,9 +10,9 @@
#include "render_core/app_window.h"
#include "render_core/keyboard.h"
#include "render_core/mesh_utils.h"
#include "render_immediate/renderer.h"
#include "render_gui/gui.h"
#include "render_gui/imgui.h"
#include "render_immediate/renderer.h"
//#include "render_core/font.h"
#include "core/sub_process.h"
@ -88,6 +88,15 @@ void GameScene::input_event(const Ref<InputEvent> &event) {
}
}
if (k->get_physical_scancode() == KEY_S) {
if (pressed) {
ERR_PRINT("Sending test signal");
test_signal.emit(this);
test_signal.emit(this, 12);
test_signal.emit(this, 33, "Test String");
}
}
return;
}
@ -440,7 +449,6 @@ void GameScene::render_gui_manual(bool clear_screen) {
GUI::new_frame();
ImGuiIO &io = ImGui::GetIO();
(void)io;
@ -608,6 +616,21 @@ void GameScene::socket_thread_func(void *data) {
self->_server_socket = NULL;
}
void GameScene::signal_member(Signal *emitter) {
LOG_MSG("signal_member Params:");
for (int i = 0; i < emitter->params.size(); ++i) {
LOG_MSG(String(emitter->params[i]));
}
LOG_MSG("signal_member Params End.");
}
void GameScene::signal_static(Signal *emitter) {
LOG_MSG("signal_static Params:");
for (int i = 0; i < emitter->params.size(); ++i) {
LOG_MSG(String(emitter->params[i]));
}
LOG_MSG("signal_static Params End.");
}
GameScene::GameScene() {
render_type = 0;
@ -792,6 +815,9 @@ GameScene::GameScene() {
_render_tex.instance();
_render_tex->set_frame_buffer(_frame_buffer);
test_signal.connect(this, &GameScene::signal_member);
test_signal.connect_static(&GameScene::signal_static);
}
GameScene::~GameScene() {

View File

@ -6,6 +6,7 @@
#include "render_core/color_material.h"
#include "render_core/colored_material.h"
#include "render_core/font.h"
#include "render_core/frame_buffer.h"
#include "render_core/image.h"
#include "render_core/mesh.h"
#include "render_core/texture.h"
@ -18,7 +19,8 @@
#include "render_objects/sprite.h"
#include "render_objects/text_2d.h"
#include "render_objects/tile_map.h"
#include "render_core/frame_buffer.h"
#include "object/psignal.h"
class Thread;
class Socket;
@ -46,6 +48,9 @@ public:
void toggle_socket();
static void socket_thread_func(void *d);
void signal_member(Signal *emitter);
static void signal_static(Signal *emitter);
GameScene();
~GameScene();
@ -92,6 +97,8 @@ public:
Ref<FrameBuffer> _frame_buffer;
Ref<RenderTexture> _render_tex;
Signal test_signal;
//ColoredMaterial *cmaterial;
};

View File

@ -7,10 +7,10 @@
#include "array.h"
#include "core/hashfuncs.h"
#include "core/ustring.h"
#include "core/vector.h"
#include "object/object.h"
#include "object/variant.h"
#include "core/ustring.h"
//--STRIP
class ArrayPrivate {
@ -461,6 +461,37 @@ Variant Array::max() const {
return maxval;
}
bool Array::operator<(const Array &p_array) const {
int a_len = size();
int b_len = p_array.size();
int min_cmp = MIN(a_len, b_len);
for (int i = 0; i < min_cmp; i++) {
if (operator[](i) < p_array[i]) {
return true;
} else if (p_array[i] < operator[](i)) {
return false;
}
}
return a_len < b_len;
}
bool Array::operator<=(const Array &p_array) const {
return !operator>(p_array);
}
bool Array::operator>(const Array &p_array) const {
return p_array < *this;
}
bool Array::operator>=(const Array &p_array) const {
return !operator<(p_array);
}
const void *Array::id() const {
return _p;
}

View File

@ -82,6 +82,11 @@ public:
Variant min() const;
Variant max() const;
bool operator<(const Array &p_array) const;
bool operator<=(const Array &p_array) const;
bool operator>(const Array &p_array) const;
bool operator>=(const Array &p_array) const;
const void *id() const;
String sprintf(const String &p_format, bool *error) const;

View File

@ -94,6 +94,18 @@ Variant Dictionary::get(const Variant &p_key, const Variant &p_default) const {
return *result;
}
Variant Dictionary::get_or_add(const Variant &p_key, const Variant &p_default) {
const Variant *result = getptr(p_key);
if (!result) {
operator[](p_key) = p_default;
return p_default;
}
return *result;
}
int Dictionary::size() const {
return _p->variant_map.size();
}

View File

@ -37,6 +37,7 @@ public:
Variant get_valid(const Variant &p_key) const;
Variant get(const Variant &p_key, const Variant &p_default) const;
Variant get_or_add(const Variant &p_key, const Variant &p_default);
int size() const;
bool empty() const;

View File

@ -4,11 +4,11 @@
//--STRIP
//--STRIP
#include "core/vector.h"
#include "core/ustring.h"
#include "core/vector.h"
#include "object/variant.h"
#include "object/reference.h"
#include "object/variant.h"
//--STRIP
class Signal {
@ -18,11 +18,11 @@ public:
Vector<Variant> static_data;
template <class T>
void connect(T *obj, void (*func)(T*, Signal *));
void connect(T *obj, void (T::*func)(Signal *));
template <class T>
void disconnect(T *obj, void (*func)(T*, Signal *));
void disconnect(T *obj, void (T::*func)(Signal *));
template <class T>
bool is_connected(T *obj, void (*func)(T*, Signal *));
bool is_connected(T *obj, void (T::*func)(Signal *));
void connect_static(void (*func)(Signal *));
void disconnect_static(void (*func)(Signal *));
@ -70,12 +70,11 @@ protected:
};
struct ClassSignalEntry : public SignalEntry {
virtual void* get_obj_ptr() {
virtual void *get_obj_ptr() {
return nullptr;
}
virtual void* get_func_ptr() {
virtual void *get_func_ptr() {
return nullptr;
}
@ -84,26 +83,26 @@ protected:
}
};
template<typename T>
template <typename T>
struct ClassSignalEntrySpec : public ClassSignalEntry {
union {
T* obj;
void* obj_ptr;
T *obj;
void *obj_ptr;
};
union {
void (*func)(T*, Signal *);
void* func_ptr;
void (T::*func)(Signal *);
void *func_ptr;
};
virtual void call(Signal *s) {
func(obj, s);
(obj->*func)(s);
}
void* get_obj_ptr() {
void *get_obj_ptr() {
return obj_ptr;
}
void* get_func_ptr() {
void *get_func_ptr() {
return func_ptr;
}
@ -118,7 +117,7 @@ protected:
};
template <typename T>
void Signal::connect(T *obj, void (*func)(T*, Signal *)) {
void Signal::connect(T *obj, void (T::*func)(Signal *)) {
ClassSignalEntrySpec<T> *ce = memnew(ClassSignalEntrySpec<T>());
ce->obj = obj;
ce->func = func;
@ -127,13 +126,13 @@ void Signal::connect(T *obj, void (*func)(T*, Signal *)) {
}
template <typename T>
void Signal::disconnect(T *obj, void (*func)(T*, Signal *)) {
void Signal::disconnect(T *obj, void (T::*func)(Signal *)) {
ClassSignalEntrySpec<T> t;
t.obj = obj;
t.func = func;
void* obj_ptr = t.obj_ptr;
void* func_ptr = t.func_ptr;
void *obj_ptr = t.obj_ptr;
void *func_ptr = t.func_ptr;
for (int i = 0; i < entries.size(); ++i) {
SignalEntry *e = entries[i];
@ -150,13 +149,13 @@ void Signal::disconnect(T *obj, void (*func)(T*, Signal *)) {
}
template <typename T>
bool Signal::is_connected(T *obj, void (*func)(T*, Signal *)) {
bool Signal::is_connected(T *obj, void (T::*func)(Signal *)) {
ClassSignalEntrySpec<T> t;
t.obj = obj;
t.func = func;
void* obj_ptr = t.obj_ptr;
void* func_ptr = t.func_ptr;
void *obj_ptr = t.obj_ptr;
void *func_ptr = t.func_ptr;
for (int i = 0; i < entries.size(); ++i) {
SignalEntry *e = entries[i];

View File

@ -238,6 +238,42 @@ String InputEventKey::as_text() const {
return kc;
}
Ref<InputEventKey> InputEventKey::create_reference(uint32_t p_keycode, bool p_physical) {
Ref<InputEventKey> ie;
ie.instance();
if (p_physical) {
ie->set_physical_scancode(p_keycode & KEY_CODE_MASK);
} else {
ie->set_scancode(p_keycode & KEY_CODE_MASK);
}
char32_t ch = char32_t(p_keycode & KEY_CODE_MASK);
if (ch < 0xd800 || (ch > 0xdfff && ch <= 0x10ffff)) {
ie->set_unicode(ch);
}
if ((p_keycode & KEY_MASK_SHIFT)) {
ie->set_shift(true);
}
if ((p_keycode & KEY_MASK_ALT)) {
ie->set_alt(true);
}
if ((p_keycode & KEY_MASK_CTRL)) {
ie->set_control(true);
}
if ((p_keycode & KEY_MASK_META)) {
ie->set_command(true);
}
return ie;
}
bool InputEventKey::action_match(const Ref<InputEvent> &p_event, bool p_exact_match, bool *p_pressed, float *p_strength, float *p_raw_strength, float p_deadzone) const {
Ref<InputEventKey> key = p_event;
if (key.is_null()) {

View File

@ -167,6 +167,8 @@ public:
virtual String as_text() const;
static Ref<InputEventKey> create_reference(uint32_t p_keycode_with_modifier_masks, bool p_physical = false);
InputEventKey();
};

View File

@ -5,13 +5,13 @@
#include "render_core/color_material.h"
#include "render_core/color_material_2d.h"
#include "render_core/colored_material.h"
#include "render_core/colored_texture_material_2d.h"
#include "render_core/font.h"
#include "render_core/font_material.h"
#include "render_core/material.h"
#include "render_core/mesh.h"
#include "render_core/texture.h"
#include "render_core/texture_material.h"
#include "render_core/colored_texture_material_2d.h"
#include "render_core/render_state.h"
//--STRIP
@ -373,6 +373,16 @@ void Renderer::camera_2d_bind() {
RenderState::model_view_matrix_2d = _camera_2d_model_view_matrix;
RenderState::projection_matrix_2d = _camera_2d_projection_matrix;
}
void Renderer::camera_2d_reset() {
RenderState::model_view_matrix_2d = Transform2D();
RenderState::projection_matrix_2d = Transform();
_camera_2d_model_view_matrix_stack.clear();
_camera_2d_projection_matrix_stack.clear();
_camera_2d_projection_matrix = RenderState::projection_matrix_2d;
_camera_2d_model_view_matrix = RenderState::model_view_matrix_2d;
}
Transform Renderer::camera_2d_get_current_projection_matrix() const {
return _camera_2d_projection_matrix;
@ -398,6 +408,12 @@ void Renderer::camera_2d_pop_projection_matrix() {
int Renderer::get_camera_2d_projection_matrix_stack_size() const {
return _camera_2d_projection_matrix_stack.size();
}
void Renderer::camera_2d_projection_matrix_stack_clear() {
_camera_2d_projection_matrix_stack.clear();
_camera_2d_projection_matrix = Transform();
RenderState::projection_matrix_2d = _camera_2d_projection_matrix;
}
Transform2D Renderer::camera_2d_get_current_model_view_matrix() const {
return _camera_2d_model_view_matrix;
@ -425,6 +441,12 @@ void Renderer::camera_2d_pop_model_view_matrix() {
int Renderer::get_camera_2d_model_view_matrix_stack_size() const {
return _camera_2d_model_view_matrix_stack.size();
}
void Renderer::camera_2d_model_view_matrix_stack_clear() {
_camera_2d_model_view_matrix_stack.clear();
_camera_2d_model_view_matrix = Transform2D();
RenderState::model_view_matrix_2d = _camera_2d_model_view_matrix;
}
void Renderer::camera_2d_projection_set_to_window() {
Vector2 size = get_window_size();
@ -434,10 +456,9 @@ void Renderer::camera_2d_projection_set_to_window() {
//canvas_transform.scale(Vector3(2.0f / size.x, 2.0f / size.y, 1.0f));
canvas_transform.scale(Vector3(2.0f / size.x, -2.0f / size.y, 1.0f));
RenderState::model_view_matrix_2d = Transform2D();
RenderState::projection_matrix_2d = canvas_transform;
_camera_2d_model_view_matrix_stack.clear();
_camera_2d_projection_matrix_stack.clear();
_camera_2d_projection_matrix = canvas_transform;
}
void Renderer::camera_2d_projection_set_to_size(const Size2i &p_size) {
@ -446,10 +467,9 @@ void Renderer::camera_2d_projection_set_to_size(const Size2i &p_size) {
//canvas_transform.scale(Vector3(2.0f / size.x, 2.0f / size.y, 1.0f));
canvas_transform.scale(Vector3(2.0f / p_size.x, -2.0f / p_size.y, 1.0f));
RenderState::model_view_matrix_2d = Transform2D();
RenderState::projection_matrix_2d = canvas_transform;
_camera_2d_model_view_matrix_stack.clear();
_camera_2d_projection_matrix_stack.clear();
_camera_2d_projection_matrix = canvas_transform;
}
void Renderer::camera_2d_projection_set_to_render_target() {
@ -460,10 +480,15 @@ void Renderer::camera_2d_projection_set_to_render_target() {
//canvas_transform.scale(Vector3(2.0f / size.x, 2.0f / size.y, 1.0f));
canvas_transform.scale(Vector3(2.0f / size.x, -2.0f / size.y, 1.0f));
RenderState::model_view_matrix_2d = Transform2D();
RenderState::projection_matrix_2d = canvas_transform;
_camera_2d_projection_matrix_stack.clear();
_camera_2d_projection_matrix = canvas_transform;
}
_camera_2d_model_view_matrix_stack.clear();
void Renderer::camera_2d_projection_set_to_transform(const Transform &p_transform) {
RenderState::projection_matrix_2d = p_transform;
_camera_2d_projection_matrix_stack.clear();
_camera_2d_projection_matrix = p_transform;
}
void Renderer::camera_3d_bind() {
@ -472,6 +497,19 @@ void Renderer::camera_3d_bind() {
RenderState::projection_matrix_3d = _camera_3d_projection;
}
void Renderer::camera_3d_reset() {
_camera_3d_projection = Projection();
_camera_3d_camera_transform_matrix = Transform();
_camera_3d_model_view_matrix = Transform();
_camera_3d_camera_transform_matrix_stack.clear();
_camera_3d_model_view_matrix_stack.clear();
RenderState::camera_transform_3d = _camera_3d_camera_transform_matrix;
RenderState::model_view_matrix_3d = _camera_3d_model_view_matrix;
RenderState::projection_matrix_3d = _camera_3d_projection;
}
Transform Renderer::camera_3d_get_current_camera_transform_matrix() const {
return _camera_3d_camera_transform_matrix;
}
@ -496,6 +534,11 @@ void Renderer::camera_3d_pop_camera_transform_matrix() {
int Renderer::get_camera_3d_camera_transform_matrix_stack_size() const {
return _camera_3d_camera_transform_matrix_stack.size();
}
void Renderer::camera_3d_camera_transform_matrix_stack_clear() {
_camera_3d_camera_transform_matrix_stack.clear();
_camera_3d_camera_transform_matrix = Transform();
RenderState::camera_transform_3d = _camera_3d_camera_transform_matrix;
}
Transform Renderer::camera_3d_get_current_model_view_matrix() const {
return _camera_3d_model_view_matrix;
@ -521,6 +564,12 @@ void Renderer::camera_3d_pop_model_view_matrix() {
int Renderer::get_camera_3d_model_view_matrix_stack_size() const {
return _camera_3d_model_view_matrix_stack.size();
}
void Renderer::get_camera_3d_model_view_matrix_stack_clear() {
_camera_3d_model_view_matrix_stack.clear();
_camera_3d_model_view_matrix = Transform();
RenderState::model_view_matrix_3d = _camera_3d_model_view_matrix;
}
// Aspect Ratio = w / h
void Renderer::camera_3d_projection_set_to_orthographic(float aspect_ratio, float size, float znear, float zfar, bool vaspect) {
@ -552,7 +601,7 @@ void Renderer::camera_3d_projection_set_to_perspective(float aspect_ratio, float
RenderState::projection_matrix_3d = _camera_3d_projection;
_last_camera_3d_data.type = LastCamera3DData::TYPE_PERSPECTIVE;
_last_camera_3d_data.type = LastCamera3DData::TYPE_PERSPECTIVE;
_last_camera_3d_data.size = size;
_last_camera_3d_data.aspect_ratio = aspect_ratio;
_last_camera_3d_data.znear = znear;
@ -683,7 +732,6 @@ Point2 Renderer::camera_3d_unproject_position(const Vector3 &p_pos) const {
return res;
}
Vector3 Renderer::camera_3d_project_position(const Point2 &p_point, float p_z_depth) const {
if (p_z_depth == 0) {
return _camera_3d_camera_transform_matrix.origin;
@ -711,7 +759,6 @@ Vector3 Renderer::camera_3d_project_position(const Point2 &p_point, float p_z_de
return _camera_3d_camera_transform_matrix.xform(p);
}
void Renderer::clear_screen(const Color &p_color) {
glClearColor(p_color.r, p_color.g, p_color.b, p_color.a);

View File

@ -70,34 +70,41 @@ public:
//2D Camera API
void camera_2d_bind();
void camera_2d_reset();
Transform camera_2d_get_current_projection_matrix() const;
void camera_2d_push_projection_matrix(const Transform &p_transform);
void camera_2d_pop_projection_matrix();
int get_camera_2d_projection_matrix_stack_size() const;
void camera_2d_projection_matrix_stack_clear();
Transform2D camera_2d_get_current_model_view_matrix() const;
void camera_2d_push_model_view_matrix(const Transform2D &p_transform_2d);
void camera_2d_pop_model_view_matrix();
int get_camera_2d_model_view_matrix_stack_size() const;
void camera_2d_model_view_matrix_stack_clear();
void camera_2d_projection_set_to_window();
void camera_2d_projection_set_to_size(const Size2i &p_size);
void camera_2d_projection_set_to_render_target();
void camera_2d_projection_set_to_transform(const Transform &p_transform);
//3D Camera API
void camera_3d_bind();
void camera_3d_reset();
Transform camera_3d_get_current_camera_transform_matrix() const;
void camera_3d_push_camera_transform_matrix(const Transform &p_transform);
void camera_3d_pop_camera_transform_matrix();
int get_camera_3d_camera_transform_matrix_stack_size() const;
void camera_3d_camera_transform_matrix_stack_clear();
Transform camera_3d_get_current_model_view_matrix() const;
void camera_3d_push_model_view_matrix(const Transform &p_transform);
void camera_3d_pop_model_view_matrix();
int get_camera_3d_model_view_matrix_stack_size() const;
void get_camera_3d_model_view_matrix_stack_clear();
// Aspect Ratio = w / h
void camera_3d_projection_set_to_orthographic(float aspect_ratio, float size = 1.0, float znear = 0.05, float zfar = 100, bool vaspect = false);

View File

@ -105,6 +105,9 @@ public:
static _ALWAYS_INLINE_ double exp(double p_x) { return ::exp(p_x); }
static _ALWAYS_INLINE_ float exp(float p_x) { return ::expf(p_x); }
static _ALWAYS_INLINE_ double exp2(double p_x) { return ::exp2(p_x); }
static _ALWAYS_INLINE_ float exp2(float p_x) { return ::exp2f(p_x); }
static _ALWAYS_INLINE_ double erf(double p_x) { return ::erf(p_x); }
static _ALWAYS_INLINE_ float erf(float p_x) { return ::erff(p_x); }

View File

@ -24,6 +24,8 @@
#endif
//--STRIP
#define PRINT_UNICODE_ERRORS 0
#if defined(MINGW_ENABLED) || defined(_MSC_VER)
#define snprintf _snprintf_s
#endif
@ -131,6 +133,10 @@ const char16_t *Char16String::get_data() const {
}
}
void String::copy_from(const Char16String &p_str) {
parse_utf16(p_str.ptr());
}
void Char16String::copy_from(const char16_t *p_cstr) {
if (!p_cstr) {
resize(0);
@ -234,7 +240,9 @@ void String::copy_from(const char *p_cstr) {
for (size_t i = 0; i <= len; i++) {
uint8_t c = p_cstr[i] >= 0 ? p_cstr[i] : uint8_t(256 + p_cstr[i]);
if (c == 0 && i < len) {
#if PRINT_UNICODE_ERRORS
print_unicode_error("NUL character", true);
#endif
dst[i] = 0x20;
} else {
dst[i] = c;
@ -267,7 +275,9 @@ void String::copy_from(const char *p_cstr, const int p_clip_to) {
for (int i = 0; i < len; i++) {
uint8_t c = p_cstr[i] >= 0 ? p_cstr[i] : uint8_t(256 + p_cstr[i]);
if (c == 0) {
#if PRINT_UNICODE_ERRORS
print_unicode_error("NUL character", true);
#endif
dst[i] = 0x20;
} else {
dst[i] = c;
@ -298,7 +308,9 @@ void String::copy_from(const wchar_t *p_cstr, const int p_clip_to) {
void String::copy_from(const CharType &p_char) {
if (p_char == 0) {
#if PRINT_UNICODE_ERRORS
print_unicode_error("NUL character", true);
#endif
return;
}
/*
@ -368,7 +380,9 @@ void String::copy_from_unchecked(const CharType *p_char, const int p_length) {
for (int i = 0; i < p_length; i++) {
if (p_char[i] == 0) {
#if PRINT_UNICODE_ERRORS
print_unicode_error("NUL character", true);
#endif
dst[i] = 0x20;
continue;
}
@ -449,7 +463,9 @@ String &String::operator+=(const String &p_str) {
String &String::operator+=(CharType p_char) {
if (p_char == 0) {
#if PRINT_UNICODE_ERRORS
print_unicode_error("NUL character", true);
#endif
return *this;
}
/*
@ -484,7 +500,9 @@ String &String::operator+=(const char *p_str) {
for (size_t i = 0; i <= rhs_len; i++) {
uint8_t c = p_str[i] >= 0 ? p_str[i] : uint8_t(256 + p_str[i]);
if (c == 0 && i < rhs_len) {
#if PRINT_UNICODE_ERRORS
print_unicode_error("NUL character", true);
#endif
dst[i] = 0x20;
} else {
dst[i] = c;
@ -889,7 +907,7 @@ String String::substr_index(const int start_index, const int end_index) const {
return "";
}
if (end_index >= s) {
if (end_index > s) {
return substr(start_index, (s - 1) - start_index);
}
@ -2385,13 +2403,16 @@ Vector<float> String::split_floats(const String &p_splitter, bool p_allow_empty)
int from = 0;
int len = length();
String buffer = *this;
while (true) {
int end = find(p_splitter, from);
if (end < 0) {
end = len;
}
if (p_allow_empty || (end > from)) {
ret.push_back(String::to_double(&get_data()[from]));
buffer[end] = 0;
ret.push_back(String::to_double(&buffer.get_data()[from]));
buffer[end] = _cowdata.get(end);
}
if (end == len) {
@ -2409,6 +2430,7 @@ Vector<float> String::split_floats_mk(const Vector<String> &p_splitters, bool p_
int from = 0;
int len = length();
String buffer = *this;
while (true) {
int idx;
int end = findmk(p_splitters, from, &idx);
@ -2420,7 +2442,9 @@ Vector<float> String::split_floats_mk(const Vector<String> &p_splitters, bool p_
}
if (p_allow_empty || (end > from)) {
ret.push_back(String::to_double(&get_data()[from]));
buffer[end] = 0;
ret.push_back(String::to_double(&buffer.get_data()[from]));
buffer[end] = _cowdata.get(end);
}
if (end == len) {
@ -4696,6 +4720,10 @@ String::String(const CharType *p_str) {
copy_from(p_str);
}
String::String(const Char16String &p_str) {
copy_from(p_str);
}
String::String(const char *p_str, int p_clip_to_len) {
copy_from(p_str, p_clip_to_len);
}

View File

@ -9,10 +9,11 @@
/*************************************************************************/
//--STRIP
#include "cowdata.h"
#include "core/vector.h"
#include "char_utils.h"
#include "core/math_defs.h"
#include "core/typedefs.h"
#include "core/vector.h"
#include "cowdata.h"
//--STRIP
/*************************************************************************/
@ -350,6 +351,14 @@ public:
bool to_bool() const;
uint32_t to_uint() const;
_FORCE_INLINE_ real_t to_real() const {
#ifdef REAL_T_IS_DOUBLE
return to_double();
#else
return to_float();
#endif
}
int hex_to_int(bool p_with_prefix = true) const;
int64_t hex_to_int64(bool p_with_prefix = true) const;
int64_t bin_to_int64(bool p_with_prefix = true) const;
@ -367,6 +376,31 @@ public:
static double to_double(const wchar_t *p_str, const wchar_t **r_end = nullptr);
static double to_double(const CharType *p_str, const CharType **r_end = nullptr);
_FORCE_INLINE_ static real_t to_real(const char *p_str) {
#ifdef REAL_T_IS_DOUBLE
return to_double(p_str);
#else
return to_float(p_str);
#endif
}
_FORCE_INLINE_ static real_t to_real(const wchar_t *p_str, const wchar_t **r_end = nullptr) {
#ifdef REAL_T_IS_DOUBLE
return to_double(p_str, r_end);
#else
return to_float(p_str, r_end);
#endif
}
_FORCE_INLINE_ static real_t to_real(const CharType *p_str, const CharType **r_end = nullptr) {
#ifdef REAL_T_IS_DOUBLE
return to_double(p_str, r_end);
#else
return to_float(p_str, r_end);
#endif
}
static uint32_t num_characters(int64_t p_int);
String capitalize() const;
@ -508,6 +542,7 @@ public:
String(const char *p_str);
String(const wchar_t *p_str);
String(const CharType *p_str);
String(const Char16String &p_str);
String(const char *p_str, int p_clip_to_len);
String(const wchar_t *p_str, int p_clip_to_len);
String(const CharType *p_str, int p_clip_to_len);
@ -521,6 +556,7 @@ private:
void copy_from(const char *p_cstr, const int p_clip_to);
void copy_from(const wchar_t *p_cstr);
void copy_from(const wchar_t *p_cstr, const int p_clip_to);
void copy_from(const Char16String &p_str);
void copy_from(const CharType *p_cstr);
void copy_from(const CharType *p_cstr, const int p_clip_to);

View File

@ -7,10 +7,10 @@
#include "array.h"
#include "core/hashfuncs.h"
#include "core/ustring.h"
#include "core/vector.h"
#include "object/object.h"
#include "object/variant.h"
#include "core/ustring.h"
//--STRIP
class ArrayPrivate {
@ -461,6 +461,37 @@ Variant Array::max() const {
return maxval;
}
bool Array::operator<(const Array &p_array) const {
int a_len = size();
int b_len = p_array.size();
int min_cmp = MIN(a_len, b_len);
for (int i = 0; i < min_cmp; i++) {
if (operator[](i) < p_array[i]) {
return true;
} else if (p_array[i] < operator[](i)) {
return false;
}
}
return a_len < b_len;
}
bool Array::operator<=(const Array &p_array) const {
return !operator>(p_array);
}
bool Array::operator>(const Array &p_array) const {
return p_array < *this;
}
bool Array::operator>=(const Array &p_array) const {
return !operator<(p_array);
}
const void *Array::id() const {
return _p;
}

View File

@ -82,6 +82,11 @@ public:
Variant min() const;
Variant max() const;
bool operator<(const Array &p_array) const;
bool operator<=(const Array &p_array) const;
bool operator>(const Array &p_array) const;
bool operator>=(const Array &p_array) const;
const void *id() const;
String sprintf(const String &p_format, bool *error) const;

View File

@ -94,6 +94,18 @@ Variant Dictionary::get(const Variant &p_key, const Variant &p_default) const {
return *result;
}
Variant Dictionary::get_or_add(const Variant &p_key, const Variant &p_default) {
const Variant *result = getptr(p_key);
if (!result) {
operator[](p_key) = p_default;
return p_default;
}
return *result;
}
int Dictionary::size() const {
return _p->variant_map.size();
}

View File

@ -37,6 +37,7 @@ public:
Variant get_valid(const Variant &p_key) const;
Variant get(const Variant &p_key, const Variant &p_default) const;
Variant get_or_add(const Variant &p_key, const Variant &p_default);
int size() const;
bool empty() const;

View File

@ -4,11 +4,11 @@
//--STRIP
//--STRIP
#include "core/vector.h"
#include "core/ustring.h"
#include "core/vector.h"
#include "object/variant.h"
#include "object/reference.h"
#include "object/variant.h"
//--STRIP
class Signal {
@ -18,11 +18,11 @@ public:
Vector<Variant> static_data;
template <class T>
void connect(T *obj, void (*func)(T*, Signal *));
void connect(T *obj, void (T::*func)(Signal *));
template <class T>
void disconnect(T *obj, void (*func)(T*, Signal *));
void disconnect(T *obj, void (T::*func)(Signal *));
template <class T>
bool is_connected(T *obj, void (*func)(T*, Signal *));
bool is_connected(T *obj, void (T::*func)(Signal *));
void connect_static(void (*func)(Signal *));
void disconnect_static(void (*func)(Signal *));
@ -70,12 +70,11 @@ protected:
};
struct ClassSignalEntry : public SignalEntry {
virtual void* get_obj_ptr() {
virtual void *get_obj_ptr() {
return nullptr;
}
virtual void* get_func_ptr() {
virtual void *get_func_ptr() {
return nullptr;
}
@ -84,26 +83,26 @@ protected:
}
};
template<typename T>
template <typename T>
struct ClassSignalEntrySpec : public ClassSignalEntry {
union {
T* obj;
void* obj_ptr;
T *obj;
void *obj_ptr;
};
union {
void (*func)(T*, Signal *);
void* func_ptr;
void (T::*func)(Signal *);
void *func_ptr;
};
virtual void call(Signal *s) {
func(obj, s);
(obj->*func)(s);
}
void* get_obj_ptr() {
void *get_obj_ptr() {
return obj_ptr;
}
void* get_func_ptr() {
void *get_func_ptr() {
return func_ptr;
}
@ -118,7 +117,7 @@ protected:
};
template <typename T>
void Signal::connect(T *obj, void (*func)(T*, Signal *)) {
void Signal::connect(T *obj, void (T::*func)(Signal *)) {
ClassSignalEntrySpec<T> *ce = memnew(ClassSignalEntrySpec<T>());
ce->obj = obj;
ce->func = func;
@ -127,13 +126,13 @@ void Signal::connect(T *obj, void (*func)(T*, Signal *)) {
}
template <typename T>
void Signal::disconnect(T *obj, void (*func)(T*, Signal *)) {
void Signal::disconnect(T *obj, void (T::*func)(Signal *)) {
ClassSignalEntrySpec<T> t;
t.obj = obj;
t.func = func;
void* obj_ptr = t.obj_ptr;
void* func_ptr = t.func_ptr;
void *obj_ptr = t.obj_ptr;
void *func_ptr = t.func_ptr;
for (int i = 0; i < entries.size(); ++i) {
SignalEntry *e = entries[i];
@ -150,13 +149,13 @@ void Signal::disconnect(T *obj, void (*func)(T*, Signal *)) {
}
template <typename T>
bool Signal::is_connected(T *obj, void (*func)(T*, Signal *)) {
bool Signal::is_connected(T *obj, void (T::*func)(Signal *)) {
ClassSignalEntrySpec<T> t;
t.obj = obj;
t.func = func;
void* obj_ptr = t.obj_ptr;
void* func_ptr = t.func_ptr;
void *obj_ptr = t.obj_ptr;
void *func_ptr = t.func_ptr;
for (int i = 0; i < entries.size(); ++i) {
SignalEntry *e = entries[i];

View File

@ -133,7 +133,13 @@
//--STRIP
{{FILE:sfw/core/pcg.cpp}}
//--STRIP
//#include "core/vector2i.h"
//#include "core/ustring.h"
//--STRIP
{{FILE:sfw/core/vector2i.cpp}}
//--STRIP
//#include "core/vector2.h"
//#include "core/vector2i.h"
//#include "core/ustring.h"
//--STRIP
{{FILE:sfw/core/vector2.cpp}}
@ -173,11 +179,6 @@
//--STRIP
{{FILE:sfw/core/plane.cpp}}
//--STRIP
//#include "core/vector2i.h"
//#include "core/ustring.h"
//--STRIP
{{FILE:sfw/core/vector2i.cpp}}
//--STRIP
//#include "core/transform_2d.h" // Includes rect2.h but Rect2 needs Transform2D
//#include "core/rect2i.h"
//--STRIP

View File

@ -339,7 +339,13 @@
//--STRIP
{{FILE:sfw/core/pcg.cpp}}
//--STRIP
//#include "core/vector2i.h"
//#include "core/ustring.h"
//--STRIP
{{FILE:sfw/core/vector2i.cpp}}
//--STRIP
//#include "core/vector2.h"
//#include "core/vector2i.h"
//#include "core/ustring.h"
//--STRIP
{{FILE:sfw/core/vector2.cpp}}
@ -379,11 +385,6 @@
//--STRIP
{{FILE:sfw/core/plane.cpp}}
//--STRIP
//#include "core/vector2i.h"
//#include "core/ustring.h"
//--STRIP
{{FILE:sfw/core/vector2i.cpp}}
//--STRIP
//#include "core/transform_2d.h" // Includes rect2.h but Rect2 needs Transform2D
//#include "core/rect2i.h"
//--STRIP

View File

@ -340,7 +340,13 @@
//--STRIP
{{FILE:sfw/core/pcg.cpp}}
//--STRIP
//#include "core/vector2i.h"
//#include "core/ustring.h"
//--STRIP
{{FILE:sfw/core/vector2i.cpp}}
//--STRIP
//#include "core/vector2.h"
//#include "core/vector2i.h"
//#include "core/ustring.h"
//--STRIP
{{FILE:sfw/core/vector2.cpp}}
@ -380,11 +386,6 @@
//--STRIP
{{FILE:sfw/core/plane.cpp}}
//--STRIP
//#include "core/vector2i.h"
//#include "core/ustring.h"
//--STRIP
{{FILE:sfw/core/vector2i.cpp}}
//--STRIP
//#include "core/transform_2d.h" // Includes rect2.h but Rect2 needs Transform2D
//#include "core/rect2i.h"
//--STRIP

View File

@ -141,7 +141,13 @@
//--STRIP
{{FILE:sfw/core/pcg.cpp}}
//--STRIP
//#include "core/vector2i.h"
//#include "core/ustring.h"
//--STRIP
{{FILE:sfw/core/vector2i.cpp}}
//--STRIP
//#include "core/vector2.h"
//#include "core/vector2i.h"
//#include "core/ustring.h"
//--STRIP
{{FILE:sfw/core/vector2.cpp}}
@ -181,11 +187,6 @@
//--STRIP
{{FILE:sfw/core/plane.cpp}}
//--STRIP
//#include "core/vector2i.h"
//#include "core/ustring.h"
//--STRIP
{{FILE:sfw/core/vector2i.cpp}}
//--STRIP
//#include "core/transform_2d.h" // Includes rect2.h but Rect2 needs Transform2D
//#include "core/rect2i.h"
//--STRIP

View File

@ -339,7 +339,13 @@
//--STRIP
{{FILE:sfw/core/pcg.cpp}}
//--STRIP
//#include "core/vector2i.h"
//#include "core/ustring.h"
//--STRIP
{{FILE:sfw/core/vector2i.cpp}}
//--STRIP
//#include "core/vector2.h"
//#include "core/vector2i.h"
//#include "core/ustring.h"
//--STRIP
{{FILE:sfw/core/vector2.cpp}}
@ -379,11 +385,6 @@
//--STRIP
{{FILE:sfw/core/plane.cpp}}
//--STRIP
//#include "core/vector2i.h"
//#include "core/ustring.h"
//--STRIP
{{FILE:sfw/core/vector2i.cpp}}
//--STRIP
//#include "core/transform_2d.h" // Includes rect2.h but Rect2 needs Transform2D
//#include "core/rect2i.h"
//--STRIP

View File

@ -339,7 +339,13 @@
//--STRIP
{{FILE:sfw/core/pcg.cpp}}
//--STRIP
//#include "core/vector2i.h"
//#include "core/ustring.h"
//--STRIP
{{FILE:sfw/core/vector2i.cpp}}
//--STRIP
//#include "core/vector2.h"
//#include "core/vector2i.h"
//#include "core/ustring.h"
//--STRIP
{{FILE:sfw/core/vector2.cpp}}
@ -379,11 +385,6 @@
//--STRIP
{{FILE:sfw/core/plane.cpp}}
//--STRIP
//#include "core/vector2i.h"
//#include "core/ustring.h"
//--STRIP
{{FILE:sfw/core/vector2i.cpp}}
//--STRIP
//#include "core/transform_2d.h" // Includes rect2.h but Rect2 needs Transform2D
//#include "core/rect2i.h"
//--STRIP

View File

@ -339,7 +339,13 @@
//--STRIP
{{FILE:sfw/core/pcg.cpp}}
//--STRIP
//#include "core/vector2i.h"
//#include "core/ustring.h"
//--STRIP
{{FILE:sfw/core/vector2i.cpp}}
//--STRIP
//#include "core/vector2.h"
//#include "core/vector2i.h"
//#include "core/ustring.h"
//--STRIP
{{FILE:sfw/core/vector2.cpp}}
@ -379,11 +385,6 @@
//--STRIP
{{FILE:sfw/core/plane.cpp}}
//--STRIP
//#include "core/vector2i.h"
//#include "core/ustring.h"
//--STRIP
{{FILE:sfw/core/vector2i.cpp}}
//--STRIP
//#include "core/transform_2d.h" // Includes rect2.h but Rect2 needs Transform2D
//#include "core/rect2i.h"
//--STRIP