Compare commits
30 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 159255adda | |||
| c7c489fde5 | |||
| 1f7f5314a3 | |||
| 1f2cbc4c31 | |||
| 183d89ceaf | |||
| 0be3d6cd77 | |||
| 4613bfd072 | |||
| 585e5e1167 | |||
| 30408393e7 | |||
| e9c8cc9aea | |||
| 03b2989130 | |||
| e9c2872187 | |||
| b9ad5293bf | |||
| e4b2df21bc | |||
| 970faad32d | |||
| 0fb517f282 | |||
| 9fefa903bd | |||
| 3f8984b69f | |||
| 9ea1305c27 | |||
| 7c7c3b37ff | |||
| 792e537f2b | |||
| 5c433111e2 | |||
| c15188d456 | |||
| a76954b6f7 | |||
| b02eb7e1d4 | |||
| ce675b1430 | |||
| 3de17a3b43 | |||
| d69368322e | |||
| 2cc6839009 | |||
| 62454960d1 |
@@ -9,13 +9,17 @@ LDFLAGS := -Llib -L/usr/lib -L/usr/local/lib
|
||||
|
||||
SRCS := $(wildcard src/*.cpp)
|
||||
OBJECTS := $(patsubst src/%.cpp,build/%.o, $(SRCS))
|
||||
DEPENDS := $(patsubst src/%.cpp,build/%.d, $(SRCS))
|
||||
|
||||
viseq: $(OBJECTS)
|
||||
$(CXX) $(OBJECTS) -o $@ $(LDFLAGS) $(LDLIBS)
|
||||
|
||||
$(OBJECTS): build/%.o : src/%.cpp
|
||||
-include $(DEPENDS)
|
||||
|
||||
#$(OBJECTS): build/%.o : src/%.cpp
|
||||
build/%.o: src/%.cpp Makefile
|
||||
@mkdir -p build
|
||||
$(CXX) -c $< -o $@ $(CXXFLAGS) $(CXXINC)
|
||||
$(CXX) -c $< -o $@ $(CXXFLAGS) $(CXXINC) -MMD -MP
|
||||
|
||||
clean:
|
||||
rm -f build/*
|
||||
|
||||
@@ -32,6 +32,7 @@ NAMESPACE_LIBREMIDI {
|
||||
}
|
||||
#endif
|
||||
|
||||
#include <init/Microsoft.Windows.Devices.Midi2.Initialization.hpp>
|
||||
// clang-format on
|
||||
|
||||
namespace midi2 = winrt::Microsoft::Windows::Devices::Midi2;
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
## style: dark
|
||||
|
||||
Classical dark style with an extra high-def colour touch! Elegant and professional, perfect for the expensive tools!
|
||||
|
||||

|
||||
|
||||
## style: provided files
|
||||
|
||||
Several options are provided to add the style to a `raygui` application, choose the one that better fits the project.
|
||||
|
||||
| file name | description |
|
||||
| :-------- | :---------- |
|
||||
| `style_dark.rgs` | Binary style file (raygui 4.0), font data compressed (recs, glyphs) |
|
||||
| `style_dark.txt.rgs` | Text style file, no font data, requires external font provided |
|
||||
| `style_dark.old.rgs` | Binary style file (raygui 3.x), font data uncompressed (recs, glyphs) |
|
||||
| `style_dark.h` | Embeddable style as code file, self-contained, includes font data |
|
||||
| `style_dark.png` | Style table image, contains `rGSf` chunk with binary `rgs` file data |
|
||||
|
||||
## screenshot
|
||||
|
||||

|
||||
|
||||
## about font
|
||||
|
||||
"Pixel Operator" font by de Jayvee Enaguas.
|
||||
|
||||
CC0 1.0 Universal, downloaded from dafont.com: [pixel-operator](https://www.dafont.com/pixel-operator.font)
|
||||
|
After Width: | Height: | Size: 47 KiB |
|
Before Width: | Height: | Size: 47 KiB After Width: | Height: | Size: 107 KiB |
@@ -7,7 +7,7 @@
|
||||
// more info and bugs-report: github.com/raysan5/raygui //
|
||||
// feedback and support: ray[at]raylibtech.com //
|
||||
// //
|
||||
// Copyright (c) 2020-2024 raylib technologies (@raylibtech) //
|
||||
// Copyright (c) 2020-2025 raylib technologies (@raylibtech) //
|
||||
// //
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -15,144 +15,144 @@
|
||||
|
||||
// Custom style name: Dark
|
||||
static const GuiStyleProp darkStyleProps[DARK_STYLE_PROPS_COUNT] = {
|
||||
{ 0, 0, (long int)0x878787ff }, // DEFAULT_BORDER_COLOR_NORMAL
|
||||
{ 0, 1, (long int)0x2c2c2cff }, // DEFAULT_BASE_COLOR_NORMAL
|
||||
{ 0, 2, (long int)0xc3c3c3ff }, // DEFAULT_TEXT_COLOR_NORMAL
|
||||
{ 0, 3, (long int)0xe1e1e1ff }, // DEFAULT_BORDER_COLOR_FOCUSED
|
||||
{ 0, 4, (long int)0x848484ff }, // DEFAULT_BASE_COLOR_FOCUSED
|
||||
{ 0, 5, (long int)0x181818ff }, // DEFAULT_TEXT_COLOR_FOCUSED
|
||||
{ 0, 6, (long int)0x000000ff }, // DEFAULT_BORDER_COLOR_PRESSED
|
||||
{ 0, 7, (long int)0xefefefff }, // DEFAULT_BASE_COLOR_PRESSED
|
||||
{ 0, 8, (long int)0x202020ff }, // DEFAULT_TEXT_COLOR_PRESSED
|
||||
{ 0, 9, (long int)0x6a6a6aff }, // DEFAULT_BORDER_COLOR_DISABLED
|
||||
{ 0, 10, (long int)0x818181ff }, // DEFAULT_BASE_COLOR_DISABLED
|
||||
{ 0, 11, (long int)0x606060ff }, // DEFAULT_TEXT_COLOR_DISABLED
|
||||
{ 0, 16, (long int)0x00000010 }, // DEFAULT_TEXT_SIZE
|
||||
{ 0, 17, (long int)0x00000000 }, // DEFAULT_TEXT_SPACING
|
||||
{ 0, 18, (long int)0x9d9d9dff }, // DEFAULT_LINE_COLOR
|
||||
{ 0, 19, (long int)0x3c3c3cff }, // DEFAULT_BACKGROUND_COLOR
|
||||
{ 0, 20, (long int)0x00000018 }, // DEFAULT_TEXT_LINE_SPACING
|
||||
{ 1, 5, (long int)0xf7f7f7ff }, // LABEL_TEXT_COLOR_FOCUSED
|
||||
{ 1, 8, (long int)0x898989ff }, // LABEL_TEXT_COLOR_PRESSED
|
||||
{ 4, 5, (long int)0xb0b0b0ff }, // SLIDER_TEXT_COLOR_FOCUSED
|
||||
{ 5, 5, (long int)0x848484ff }, // PROGRESSBAR_TEXT_COLOR_FOCUSED
|
||||
{ 9, 5, (long int)0xf5f5f5ff }, // TEXTBOX_TEXT_COLOR_FOCUSED
|
||||
{ 10, 5, (long int)0xf6f6f6ff }, // VALUEBOX_TEXT_COLOR_FOCUSED
|
||||
{ 0, 0, (int)0x878787ff }, // DEFAULT_BORDER_COLOR_NORMAL
|
||||
{ 0, 1, (int)0x2c2c2cff }, // DEFAULT_BASE_COLOR_NORMAL
|
||||
{ 0, 2, (int)0xc3c3c3ff }, // DEFAULT_TEXT_COLOR_NORMAL
|
||||
{ 0, 3, (int)0xe1e1e1ff }, // DEFAULT_BORDER_COLOR_FOCUSED
|
||||
{ 0, 4, (int)0x848484ff }, // DEFAULT_BASE_COLOR_FOCUSED
|
||||
{ 0, 5, (int)0x181818ff }, // DEFAULT_TEXT_COLOR_FOCUSED
|
||||
{ 0, 6, (int)0x000000ff }, // DEFAULT_BORDER_COLOR_PRESSED
|
||||
{ 0, 7, (int)0xefefefff }, // DEFAULT_BASE_COLOR_PRESSED
|
||||
{ 0, 8, (int)0x202020ff }, // DEFAULT_TEXT_COLOR_PRESSED
|
||||
{ 0, 9, (int)0x6a6a6aff }, // DEFAULT_BORDER_COLOR_DISABLED
|
||||
{ 0, 10, (int)0x818181ff }, // DEFAULT_BASE_COLOR_DISABLED
|
||||
{ 0, 11, (int)0x606060ff }, // DEFAULT_TEXT_COLOR_DISABLED
|
||||
{ 0, 16, (int)0x00000010 }, // DEFAULT_TEXT_SIZE
|
||||
{ 0, 17, (int)0x00000000 }, // DEFAULT_TEXT_SPACING
|
||||
{ 0, 18, (int)0x9d9d9dff }, // DEFAULT_LINE_COLOR
|
||||
{ 0, 19, (int)0x3c3c3cff }, // DEFAULT_BACKGROUND_COLOR
|
||||
{ 0, 20, (int)0x00000018 }, // DEFAULT_TEXT_LINE_SPACING
|
||||
{ 1, 5, (int)0xf7f7f7ff }, // LABEL_TEXT_COLOR_FOCUSED
|
||||
{ 1, 8, (int)0x898989ff }, // LABEL_TEXT_COLOR_PRESSED
|
||||
{ 4, 5, (int)0xb0b0b0ff }, // SLIDER_TEXT_COLOR_FOCUSED
|
||||
{ 5, 5, (int)0x848484ff }, // PROGRESSBAR_TEXT_COLOR_FOCUSED
|
||||
{ 9, 5, (int)0xf5f5f5ff }, // TEXTBOX_TEXT_COLOR_FOCUSED
|
||||
{ 10, 5, (int)0xf6f6f6ff }, // VALUEBOX_TEXT_COLOR_FOCUSED
|
||||
};
|
||||
|
||||
// WARNING: This style uses a custom font: "PixelOperator.ttf" (size: 16, spacing: 0)
|
||||
|
||||
#define DARK_STYLE_FONT_ATLAS_COMP_SIZE 2126
|
||||
#define DARK_STYLE_FONT_ATLAS_COMP_SIZE 2138
|
||||
|
||||
// Font atlas image pixels data: DEFLATE compressed
|
||||
static unsigned char darkFontData[DARK_STYLE_FONT_ATLAS_COMP_SIZE] = { 0xed,
|
||||
0xdd, 0xdb, 0x72, 0xa4, 0x3a, 0x12, 0x05, 0x50, 0xfd, 0xff, 0x4f, 0xe7, 0x3c, 0x4c, 0x4c, 0x4c, 0x74, 0x9c, 0xd3, 0x20,
|
||||
0xa5, 0x52, 0x17, 0xec, 0xd5, 0xeb, 0xcd, 0xe5, 0x76, 0x51, 0xa0, 0x94, 0x84, 0x28, 0x36, 0xd1, 0x00, 0x00, 0x00, 0x80,
|
||||
0x5f, 0x2f, 0xfe, 0xf5, 0x27, 0xf1, 0xd7, 0xdf, 0x8c, 0xee, 0xbf, 0xf3, 0xfc, 0xf3, 0xff, 0xbd, 0x1a, 0x0f, 0xef, 0xd5,
|
||||
0xb7, 0xad, 0xa3, 0xef, 0x1b, 0x03, 0x7b, 0xe2, 0xdf, 0xb7, 0x2f, 0xba, 0xff, 0xee, 0xdf, 0x3e, 0xdf, 0xf8, 0xef, 0x3f,
|
||||
0xfd, 0xa5, 0xe7, 0xad, 0x8f, 0xa1, 0xfd, 0x3e, 0xfe, 0x7f, 0xc6, 0x8e, 0x62, 0x2c, 0xd9, 0xf7, 0xef, 0x5b, 0x37, 0xbe,
|
||||
0xed, 0x95, 0xff, 0x27, 0x1e, 0x3e, 0x4f, 0xe6, 0x28, 0xf5, 0xd4, 0xd6, 0x0d, 0xf5, 0x1f, 0x5d, 0x95, 0x18, 0xa5, 0x2d,
|
||||
0xe7, 0xff, 0xef, 0x1a, 0x85, 0x3d, 0x55, 0x76, 0x4f, 0x3e, 0x55, 0xfa, 0xf8, 0xfe, 0x78, 0x6a, 0xfd, 0xe3, 0x3d, 0x60,
|
||||
0x94, 0x7c, 0x96, 0xf9, 0xd6, 0x18, 0xd3, 0xbf, 0xdd, 0xd7, 0x92, 0x6a, 0x3e, 0xd5, 0xcc, 0x2b, 0xad, 0xe4, 0x28, 0x9d,
|
||||
0xa8, 0xff, 0x48, 0xf7, 0x54, 0x31, 0x58, 0xd1, 0x15, 0x7b, 0x30, 0xd3, 0x0f, 0xb7, 0x8d, 0xf5, 0x1f, 0xa5, 0x73, 0x97,
|
||||
0x28, 0x6b, 0x73, 0x27, 0xea, 0xff, 0x79, 0xd4, 0x6e, 0x25, 0xed, 0x26, 0x5e, 0xf6, 0x51, 0x6d, 0x2d, 0xaf, 0x9d, 0xa7,
|
||||
0xae, 0xae, 0xff, 0xe7, 0xdf, 0x1c, 0x1d, 0x6f, 0x63, 0x70, 0xec, 0xae, 0xd8, 0x4f, 0xb9, 0xf1, 0xbf, 0x7e, 0x3f, 0xc6,
|
||||
0x5f, 0xc7, 0xe6, 0xec, 0x3c, 0x64, 0x64, 0x0f, 0xc7, 0xe0, 0xd9, 0xd5, 0xec, 0x08, 0x7b, 0x72, 0xfc, 0xef, 0x9b, 0x0b,
|
||||
0xaa, 0xff, 0xb5, 0xf5, 0x9f, 0xf9, 0x24, 0xd1, 0xb9, 0x05, 0x99, 0x31, 0xb1, 0x5d, 0x50, 0xff, 0xa3, 0xfd, 0xd0, 0xf3,
|
||||
0xbe, 0xaa, 0x9a, 0xcb, 0x8f, 0xae, 0x4b, 0xf4, 0x9d, 0x61, 0xef, 0x6b, 0x85, 0xe3, 0x73, 0xa3, 0xf1, 0xfa, 0x1f, 0xef,
|
||||
0x3d, 0xdf, 0xfe, 0xda, 0xe8, 0x5e, 0xfd, 0xfb, 0x99, 0xdd, 0xfc, 0x1e, 0xdf, 0x57, 0xff, 0x91, 0x18, 0x53, 0xce, 0xd7,
|
||||
0x73, 0x4d, 0xfd, 0x47, 0x62, 0xe5, 0xa2, 0x95, 0xad, 0xf2, 0xe5, 0xd6, 0x25, 0xea, 0xd6, 0x0c, 0xce, 0x1f, 0x81, 0xf7,
|
||||
0xfa, 0x7f, 0x3b, 0x1f, 0x3c, 0x3f, 0xfe, 0xc7, 0x15, 0xe3, 0x7f, 0xa4, 0xd7, 0x86, 0x5b, 0xa2, 0xf7, 0xfd, 0x5a, 0xfd,
|
||||
0x47, 0xa2, 0x66, 0xa2, 0xe4, 0xbc, 0xbc, 0x2d, 0x59, 0xcb, 0xab, 0x5d, 0x33, 0xdc, 0x73, 0xb4, 0xde, 0x46, 0xd1, 0xaa,
|
||||
0xb3, 0x9a, 0x9f, 0x55, 0xff, 0xad, 0x60, 0xfc, 0xef, 0x9b, 0x03, 0xcc, 0x7e, 0x8e, 0xf8, 0xd8, 0xe8, 0x5f, 0x59, 0xff,
|
||||
0xbb, 0x56, 0xec, 0xd7, 0xb7, 0xc6, 0xb8, 0xe2, 0xc8, 0x58, 0xff, 0xaf, 0x9c, 0xff, 0xe7, 0xd7, 0x00, 0xc6, 0xce, 0x63,
|
||||
0xe2, 0xd2, 0xea, 0xcf, 0x9c, 0x33, 0x57, 0x5d, 0xb1, 0xaf, 0xfd, 0x36, 0x41, 0x24, 0xbe, 0xab, 0x51, 0xb3, 0x8a, 0xb3,
|
||||
0xfa, 0x18, 0x8c, 0x8f, 0xff, 0xbb, 0xae, 0xff, 0xbf, 0xcf, 0xb9, 0xef, 0x18, 0xff, 0xdb, 0xeb, 0xe8, 0x7e, 0xcb, 0xf6,
|
||||
0x00, 0x7b, 0x7b, 0x80, 0x50, 0xfd, 0xe0, 0x7b, 0xc4, 0x80, 0xfa, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x0a, 0xbf, 0x9f, 0x5f, 0x9f, 0x63, 0x30, 0x9e, 0x84, 0xbd, 0x3e, 0x81, 0x7d, 0x26, 0x13, 0x38, 0xbb,
|
||||
0x87, 0xaa, 0xfe, 0xe2, 0x73, 0x76, 0xfc, 0x48, 0xd2, 0x42, 0x7f, 0xcb, 0x88, 0xe1, 0xa7, 0x1f, 0x54, 0x26, 0x0a, 0x64,
|
||||
0x32, 0x0d, 0xda, 0x60, 0x9b, 0xa8, 0xcd, 0x52, 0x1a, 0xdb, 0xfa, 0x3d, 0x2d, 0xfe, 0x0b, 0xf5, 0x7f, 0xfe, 0x95, 0x96,
|
||||
0xc8, 0xef, 0xd9, 0x59, 0xff, 0xa3, 0x6d, 0x2f, 0x97, 0x8f, 0x3b, 0x37, 0x96, 0xec, 0x4e, 0x14, 0x8b, 0xc2, 0x63, 0xb8,
|
||||
0x6f, 0x5c, 0xfd, 0x33, 0x43, 0x67, 0x47, 0xbb, 0x9e, 0xa9, 0xff, 0xd1, 0xec, 0xd3, 0x78, 0xe8, 0x85, 0xef, 0xa9, 0xff,
|
||||
0xb6, 0xa5, 0xfe, 0xe3, 0x23, 0xf5, 0x5f, 0x9d, 0x24, 0x53, 0x95, 0x42, 0x9e, 0x49, 0xbe, 0x19, 0x3f, 0x86, 0xf9, 0x84,
|
||||
0xdf, 0x6c, 0x8b, 0xfb, 0x4e, 0xfd, 0x67, 0xda, 0xd6, 0x73, 0xce, 0xaa, 0xfa, 0x7f, 0xdf, 0xb7, 0x99, 0xd1, 0x64, 0xfe,
|
||||
0xe7, 0x35, 0x95, 0xbf, 0x27, 0x47, 0xf7, 0xed, 0x39, 0x5a, 0x6b, 0xdb, 0xca, 0xec, 0x58, 0xf9, 0x95, 0xfa, 0x8f, 0xe4,
|
||||
0x5f, 0x89, 0x97, 0x1e, 0xa5, 0x36, 0x81, 0xbd, 0x26, 0xb5, 0x6d, 0x6f, 0xfd, 0x57, 0x3f, 0xf7, 0xe7, 0x8e, 0xfa, 0x3f,
|
||||
0x9f, 0xa3, 0xbb, 0xea, 0x1c, 0xae, 0x76, 0xac, 0xfc, 0xd9, 0xe3, 0xff, 0x7b, 0x2f, 0xb9, 0xa3, 0x7d, 0xcc, 0x8c, 0xf4,
|
||||
0x27, 0xc7, 0xff, 0x73, 0x3f, 0x3f, 0x5b, 0xff, 0x55, 0xad, 0x3d, 0x36, 0xce, 0x4c, 0xb2, 0x63, 0xe5, 0xce, 0x55, 0xb2,
|
||||
0xdd, 0xe7, 0xff, 0xab, 0x3e, 0x59, 0x1b, 0x9e, 0x4d, 0xc4, 0xb5, 0xf5, 0x3f, 0xb3, 0x0a, 0xb9, 0x6e, 0xbe, 0x70, 0x66,
|
||||
0xfe, 0x9f, 0x7b, 0xbe, 0x6d, 0xe6, 0xa9, 0x80, 0xb7, 0x8d, 0xff, 0xbb, 0xae, 0x92, 0xb5, 0xcd, 0x35, 0xb9, 0xf7, 0xbd,
|
||||
0x2a, 0x9f, 0x52, 0x37, 0x9e, 0xdf, 0x1f, 0xc5, 0x33, 0xbc, 0xaf, 0xd7, 0x7f, 0x7e, 0x95, 0xbf, 0x15, 0xad, 0x4a, 0x9e,
|
||||
0x9b, 0xff, 0xef, 0x7e, 0xd2, 0x49, 0xe6, 0x5d, 0x6a, 0xfa, 0xdf, 0xbe, 0xab, 0xc2, 0xb5, 0xa3, 0xc0, 0xdf, 0xaf, 0x36,
|
||||
0x44, 0xd1, 0xc8, 0x51, 0x95, 0xdf, 0xff, 0xe7, 0xb6, 0x8d, 0x3f, 0xf1, 0x6c, 0xfc, 0x4a, 0x7c, 0x0c, 0x3e, 0x4f, 0xff,
|
||||
0x44, 0xfd, 0x67, 0xde, 0x39, 0xf3, 0xbf, 0x46, 0x8f, 0x61, 0x65, 0xfd, 0x9f, 0xeb, 0x01, 0xe4, 0x6e, 0xc2, 0x8d, 0xb3,
|
||||
0x18, 0xe0, 0xe7, 0xf4, 0x00, 0x9e, 0x70, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0xec, 0xbe, 0x13, 0xfb, 0xef, 0xd9, 0x5c, 0x99, 0xd4, 0xf8, 0xf1, 0xfb, 0xa4, 0x77, 0x26, 0xe6, 0xb7, 0x97, 0x14, 0xb2,
|
||||
0xe7, 0xdf, 0xfa, 0xf3, 0x95, 0x8a, 0x3c, 0xde, 0x28, 0xbc, 0x6b, 0xfd, 0x29, 0x93, 0xe4, 0x39, 0x4b, 0x71, 0x34, 0x77,
|
||||
0xe0, 0x7d, 0x0f, 0x8f, 0x1f, 0x97, 0x99, 0xd7, 0x5a, 0x61, 0x9a, 0x42, 0x24, 0xd2, 0x5e, 0xde, 0xf6, 0x7a, 0x7f, 0x36,
|
||||
0x70, 0x94, 0x6d, 0xf1, 0x58, 0x1d, 0x55, 0x65, 0x27, 0xdf, 0x9e, 0x98, 0x3f, 0x9f, 0xbc, 0x13, 0x2f, 0xad, 0xae, 0xbf,
|
||||
0xfe, 0x7b, 0x92, 0x23, 0xd6, 0xe7, 0x18, 0xf5, 0xfc, 0x34, 0x93, 0x7a, 0x31, 0x96, 0xc1, 0x36, 0xd7, 0x06, 0x56, 0x8f,
|
||||
0x50, 0x6d, 0xb2, 0x42, 0x62, 0xaa, 0xa5, 0xcc, 0x67, 0xff, 0xbd, 0x6f, 0x69, 0x1b, 0x1c, 0xb9, 0x6e, 0x48, 0xcc, 0x8c,
|
||||
0xce, 0xfa, 0xaa, 0xfe, 0x69, 0x1b, 0xec, 0x6f, 0x32, 0x79, 0x75, 0x51, 0x9a, 0x44, 0x91, 0xff, 0x3f, 0x91, 0x48, 0x6d,
|
||||
0x6e, 0xc9, 0x2c, 0xbe, 0x7c, 0x46, 0x7c, 0x26, 0xa7, 0x2a, 0x16, 0xef, 0xd9, 0x4c, 0xfd, 0xb7, 0x43, 0xf5, 0x9f, 0x49,
|
||||
0x3d, 0x38, 0x9f, 0x98, 0x1d, 0xa9, 0xda, 0xdd, 0x5b, 0xff, 0xd1, 0xd1, 0x7f, 0x65, 0x66, 0xd7, 0x51, 0x78, 0xce, 0xf0,
|
||||
0x3e, 0xe3, 0xad, 0x1e, 0xff, 0xdb, 0xe3, 0x7e, 0x1a, 0x4f, 0x75, 0x5b, 0x3f, 0x42, 0x65, 0x7a, 0x93, 0xb1, 0xfa, 0x5f,
|
||||
0xdd, 0x63, 0xcd, 0x3c, 0x07, 0x29, 0x3e, 0x37, 0xfe, 0x9f, 0x49, 0xcc, 0x8e, 0xc4, 0xd9, 0x75, 0xe6, 0x7d, 0xeb, 0xd7,
|
||||
0x5e, 0xa2, 0xb0, 0xfe, 0x33, 0x3d, 0x40, 0xbe, 0xfe, 0x77, 0xce, 0xa6, 0xb3, 0x79, 0x93, 0x31, 0xdd, 0x86, 0xce, 0xd4,
|
||||
0x7f, 0xe5, 0xd3, 0x96, 0x56, 0x24, 0xe6, 0x8e, 0x3f, 0xd9, 0xf1, 0xd4, 0xf8, 0xdf, 0x52, 0xe3, 0x7f, 0x6e, 0x9c, 0xa8,
|
||||
0x3b, 0xf6, 0xb5, 0x73, 0xe5, 0xf7, 0xfa, 0x8f, 0x0d, 0xef, 0xb6, 0xaf, 0xfe, 0x33, 0x3d, 0x61, 0x2c, 0x9b, 0xff, 0x67,
|
||||
0xab, 0x25, 0x86, 0xe7, 0xd7, 0x3b, 0x13, 0x73, 0x33, 0xeb, 0xcc, 0xf7, 0xd7, 0x7f, 0xe5, 0x33, 0x4c, 0xda, 0x54, 0xfa,
|
||||
0x72, 0x94, 0x8e, 0xc8, 0xfb, 0xc6, 0xff, 0x15, 0xb3, 0xe9, 0x4c, 0xfa, 0xfe, 0x3d, 0xeb, 0x7f, 0xad, 0xf8, 0x88, 0xb5,
|
||||
0xe3, 0x79, 0x88, 0x2b, 0x66, 0x85, 0x27, 0xce, 0xff, 0xab, 0x12, 0xd8, 0x73, 0xe7, 0xff, 0xd5, 0x2b, 0xf2, 0x73, 0xc7,
|
||||
0xf2, 0xde, 0xf1, 0x3f, 0xd7, 0x42, 0x62, 0x68, 0x7c, 0x6e, 0x9f, 0xaa, 0xff, 0x5b, 0xbe, 0xd1, 0x50, 0xd1, 0x6f, 0x45,
|
||||
0x49, 0xef, 0x96, 0x79, 0x6e, 0x4b, 0xe5, 0x3c, 0xaa, 0x72, 0xfd, 0x6a, 0xe6, 0xfa, 0xff, 0xcc, 0xb7, 0x53, 0x56, 0xbf,
|
||||
0x5b, 0xfe, 0xfa, 0xff, 0xda, 0xfa, 0x8f, 0xe2, 0x2d, 0xe6, 0x9e, 0x5e, 0xea, 0xe6, 0xf7, 0xd3, 0x7e, 0xee, 0x38, 0x82,
|
||||
0x6a, 0x59, 0xeb, 0x39, 0x71, 0x3e, 0xc4, 0xef, 0x9a, 0x33, 0xf3, 0xd3, 0xbf, 0xe1, 0x6d, 0x3f, 0x18, 0x9b, 0x01, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xef, 0xde, 0xc3, 0x14, 0xaf, 0x77, 0x38, 0xbc, 0x65, 0x4b,
|
||||
0x64, 0x72, 0x29, 0x5b, 0x69, 0xce, 0x5d, 0x4b, 0x24, 0xf3, 0x67, 0xb7, 0xae, 0x77, 0xaf, 0xac, 0xff, 0x64, 0xb3, 0x69,
|
||||
0xe6, 0x99, 0xc4, 0xf9, 0xcc, 0x3e, 0x3e, 0x7b, 0x34, 0xdf, 0x32, 0x3c, 0x22, 0x91, 0xc6, 0x5a, 0x79, 0xbc, 0x5a, 0x6a,
|
||||
0xdf, 0x65, 0x5b, 0x59, 0x6f, 0x0f, 0xd0, 0x9f, 0x0f, 0x53, 0x7f, 0x8f, 0x69, 0xa4, 0xf6, 0x79, 0x4d, 0x32, 0xff, 0x4c,
|
||||
0x5b, 0x6a, 0xe9, 0x04, 0xe2, 0x6c, 0xab, 0xe9, 0xfd, 0x5b, 0x31, 0xfd, 0x97, 0xdf, 0xb3, 0x5a, 0xe3, 0x73, 0x47, 0x33,
|
||||
0x9b, 0x17, 0x5f, 0x7d, 0xbc, 0x6a, 0xd3, 0xdb, 0x6a, 0x7a, 0x80, 0x8a, 0xfa, 0xaf, 0xdb, 0xca, 0xfd, 0xf7, 0xc6, 0x46,
|
||||
0xf2, 0x7e, 0xfa, 0xf8, 0xfc, 0xfd, 0xa7, 0xf1, 0xd1, 0x24, 0x81, 0x5c, 0xca, 0xe4, 0xae, 0x4f, 0x95, 0xcb, 0xe5, 0xca,
|
||||
0xa7, 0xb7, 0xed, 0x1c, 0xff, 0x33, 0x49, 0x52, 0x99, 0xb4, 0xd0, 0xea, 0x57, 0xb2, 0xbd, 0x65, 0xae, 0xfe, 0x33, 0x99,
|
||||
0x4d, 0x51, 0x94, 0x67, 0x5c, 0xf7, 0xdc, 0x93, 0x48, 0xce, 0xaf, 0x4f, 0x1e, 0xcd, 0x78, 0x4d, 0x25, 0xaf, 0xca, 0xd8,
|
||||
0xdd, 0xfb, 0x4a, 0x4c, 0x26, 0x3e, 0x44, 0xd7, 0xf1, 0x8e, 0xe9, 0xb1, 0x70, 0xd7, 0xd3, 0x02, 0x33, 0xcf, 0xa4, 0x68,
|
||||
0xc9, 0xd4, 0xcc, 0x28, 0x9b, 0xe1, 0x57, 0xbf, 0xb2, 0xa2, 0xfe, 0xe3, 0xe1, 0x3c, 0xb9, 0xfa, 0x99, 0x65, 0xd5, 0x47,
|
||||
0xb3, 0xa7, 0x67, 0xf8, 0x62, 0xfd, 0xaf, 0x9d, 0xa7, 0xd5, 0x9c, 0xff, 0x47, 0xfa, 0x59, 0x3c, 0x77, 0xb6, 0x98, 0xe8,
|
||||
0x4c, 0x77, 0xfe, 0x69, 0xf5, 0xbf, 0x77, 0x1f, 0x57, 0xf7, 0xe6, 0xcf, 0x33, 0xec, 0xf6, 0xd1, 0xfa, 0x9f, 0x49, 0x8b,
|
||||
0xaf, 0x39, 0x5f, 0x79, 0x5f, 0xff, 0xaf, 0x5c, 0xd9, 0xb8, 0xa3, 0xfe, 0x6f, 0xa9, 0xf2, 0xb1, 0x7d, 0xbe, 0xb6, 0xfe,
|
||||
0xcf, 0xd7, 0xd0, 0x6c, 0xf2, 0xfb, 0xf9, 0x6d, 0x8f, 0xb2, 0xf3, 0xff, 0x9a, 0x75, 0xa1, 0xea, 0x79, 0xc4, 0x6d, 0x3d,
|
||||
0xe8, 0xaa, 0xa7, 0xab, 0xbd, 0xcd, 0x1d, 0xaa, 0xcf, 0x77, 0xef, 0x18, 0xff, 0x43, 0xfd, 0x2f, 0x58, 0x0b, 0xaf, 0x1d,
|
||||
0x25, 0xf3, 0x2b, 0xcc, 0x33, 0xfd, 0xc9, 0xf8, 0xb3, 0xec, 0x6b, 0x57, 0xc9, 0x32, 0x7d, 0x68, 0xcf, 0x2b, 0xf9, 0x27,
|
||||
0x6e, 0x7c, 0x75, 0xfe, 0xdf, 0xf3, 0x54, 0xa0, 0x6f, 0xd5, 0x7f, 0x24, 0xd7, 0xb7, 0xee, 0xa8, 0xff, 0xb5, 0x57, 0x06,
|
||||
0xd6, 0x5f, 0xcb, 0xbf, 0x79, 0xfe, 0xbf, 0xa2, 0xcf, 0xfb, 0x76, 0xfd, 0x7f, 0x61, 0x0e, 0xbd, 0xe6, 0x5b, 0x28, 0xe7,
|
||||
0xea, 0x7f, 0x6e, 0xdc, 0x56, 0xff, 0x2b, 0x56, 0x8c, 0xf3, 0x9f, 0x7a, 0xc5, 0xf9, 0x7f, 0xef, 0x4c, 0xe3, 0xe7, 0xd7,
|
||||
0x7f, 0x7d, 0xd2, 0xf9, 0x9a, 0xf3, 0xcd, 0x76, 0xe9, 0x77, 0x61, 0xee, 0xfa, 0x4e, 0xf2, 0x9e, 0x16, 0xb3, 0x66, 0xed,
|
||||
0x23, 0xf3, 0x94, 0xde, 0xda, 0xa7, 0x39, 0xc5, 0xa2, 0x4a, 0xcf, 0x5d, 0xe5, 0xdd, 0x73, 0xfd, 0x7f, 0xef, 0x37, 0x8a,
|
||||
0xaa, 0xb7, 0x50, 0xfd, 0x7f, 0xa3, 0x0f, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xdb,
|
||||
0xee, 0xd0, 0xdb, 0x9b, 0xa8, 0x5f, 0x9f, 0x82, 0x71, 0x7b, 0xa2, 0xfe, 0xdb, 0x5d, 0x33, 0xed, 0xda, 0x44, 0xfd, 0xd6,
|
||||
0x95, 0x4c, 0xf4, 0xbd, 0x44, 0xfd, 0xdf, 0x78, 0xc7, 0xc7, 0x6d, 0x89, 0xfa, 0x75, 0x77, 0x4e, 0xdf, 0x9e, 0xa8, 0xdf,
|
||||
0x5e, 0xf2, 0x87, 0x6e, 0x4e, 0xd4, 0xcf, 0xdf, 0x3b, 0x75, 0x6b, 0xa2, 0x3e, 0x6b, 0xef, 0x98, 0xec, 0xed, 0xfb, 0xe3,
|
||||
0xe0, 0x31, 0x5b, 0x75, 0x77, 0x69, 0x7c, 0xf4, 0xce, 0xcf, 0xf1, 0x8c, 0xa6, 0x15, 0x3d, 0x4a, 0xe5, 0x5d, 0x9a, 0xeb,
|
||||
0x13, 0xf5, 0x7f, 0x4a, 0xbd, 0xee, 0x4a, 0xd4, 0x7f, 0xcf, 0x19, 0x8b, 0x4d, 0xdb, 0x1f, 0x43, 0xf3, 0xc6, 0xb5, 0x89,
|
||||
0x5a, 0xcf, 0xfd, 0xe8, 0xbd, 0xcf, 0x47, 0xf8, 0x76, 0xa2, 0xf6, 0x6f, 0xab, 0xff, 0x55, 0xfb, 0x29, 0x8a, 0xaa, 0xae,
|
||||
0xf7, 0x95, 0x7d, 0x59, 0x41, 0x75, 0xf5, 0x1f, 0xe5, 0xaf, 0xed, 0x4d, 0xd4, 0xca, 0xae, 0x27, 0xa8, 0xff, 0xef, 0xac,
|
||||
0x01, 0xe4, 0xd6, 0xad, 0xe6, 0x12, 0x75, 0x4f, 0xb6, 0x80, 0x9d, 0x89, 0x5a, 0x5f, 0xaf, 0xff, 0xcc, 0xac, 0x5c, 0xfd,
|
||||
0xdf, 0x39, 0xff, 0x8f, 0xb2, 0x57, 0x32, 0xbd, 0x46, 0x7e, 0xfd, 0xff, 0xcb, 0x4f, 0xd4, 0xfa, 0x99, 0xf5, 0x7f, 0x47,
|
||||
0xa2, 0xae, 0xfa, 0x3f, 0x33, 0xff, 0x5f, 0xf7, 0x54, 0x82, 0x9d, 0x89, 0xba, 0xc6, 0xff, 0x55, 0x15, 0x71, 0x77, 0x95,
|
||||
0xdf, 0x95, 0x9b, 0xfb, 0xcd, 0xf3, 0xff, 0xdc, 0x93, 0x40, 0xb3, 0x3d, 0xc0, 0xbe, 0x84, 0xd6, 0x13, 0x89, 0xfa, 0x12,
|
||||
0x75, 0x67, 0x8e, 0xd7, 0xf3, 0xec, 0xef, 0x9b, 0xd7, 0x63, 0x6e, 0x9f, 0xff, 0xd7, 0x5e, 0xab, 0xf9, 0xe7, 0x9a, 0xd2,
|
||||
0xea, 0x15, 0xef, 0x55, 0xf3, 0xff, 0xda, 0x2b, 0x5b, 0x12, 0x75, 0xab, 0x8f, 0xda, 0x6f, 0x5f, 0xff, 0x3b, 0xdb, 0xd3,
|
||||
0xc0, 0xee, 0x79, 0xed, 0xf9, 0x9e, 0x10, 0xf8, 0xda, 0x37, 0xb9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0xdd, 0xdb, 0x92, 0xa5, 0xba, 0x0d, 0x00, 0x50, 0xff, 0xff, 0x4f, 0x2b, 0x0f, 0xa9, 0x54, 0x32, 0x95, 0xd3, 0x80, 0x64,
|
||||
0xd9, 0x98, 0x9e, 0x35, 0xeb, 0xad, 0x77, 0x4f, 0xc3, 0x36, 0x96, 0x6f, 0x80, 0x1c, 0x03, 0x00, 0x00, 0x00, 0xf8, 0xeb,
|
||||
0xc5, 0x3f, 0xfe, 0x24, 0x7e, 0xfc, 0xcd, 0x78, 0xfc, 0x77, 0xae, 0x7f, 0xfe, 0x9f, 0x4f, 0xe3, 0xe2, 0x58, 0xcf, 0xce,
|
||||
0x35, 0x7b, 0xdc, 0x48, 0x94, 0xc4, 0x3f, 0x9f, 0x5f, 0x3c, 0xfe, 0xbb, 0x3f, 0x7d, 0xbf, 0xfc, 0xef, 0x5f, 0xfd, 0xa5,
|
||||
0xeb, 0xb3, 0x8f, 0x54, 0xb9, 0xe7, 0xff, 0x4f, 0xee, 0x2a, 0xc6, 0x92, 0xb2, 0xbf, 0x3f, 0xbb, 0xfc, 0xb9, 0x77, 0xfe,
|
||||
0x9f, 0xb8, 0xf8, 0x3e, 0x95, 0xab, 0xf4, 0x24, 0xb6, 0x4e, 0x88, 0xff, 0x78, 0x14, 0x89, 0xd1, 0x5a, 0x73, 0xfe, 0x7b,
|
||||
0xd4, 0x68, 0x6c, 0xa9, 0xaa, 0x25, 0x79, 0x15, 0xe9, 0xf9, 0xf2, 0xb8, 0xaa, 0xfd, 0xf9, 0x16, 0x30, 0x5a, 0xbe, 0xcb,
|
||||
0x7c, 0x6d, 0x8c, 0xe9, 0xdf, 0x7e, 0x56, 0x93, 0x7a, 0xbe, 0xd5, 0xcc, 0x27, 0xa3, 0xe5, 0x2a, 0xbd, 0x11, 0xff, 0x51,
|
||||
0x6e, 0xa9, 0x22, 0x19, 0xd1, 0x1d, 0x25, 0x58, 0x69, 0x87, 0xc7, 0xc6, 0xf8, 0x8f, 0xd6, 0xb1, 0x4b, 0xb4, 0xd5, 0xb9,
|
||||
0x37, 0xe2, 0xff, 0xba, 0xd7, 0x1e, 0x2d, 0xf5, 0x26, 0x6e, 0xca, 0xa8, 0x37, 0x96, 0xd7, 0x8e, 0x53, 0x57, 0xc7, 0xff,
|
||||
0xf5, 0x6f, 0x66, 0xfb, 0xdb, 0x48, 0xf6, 0xdd, 0x1d, 0xe5, 0x54, 0xeb, 0xff, 0xfb, 0xcb, 0x31, 0x7e, 0xec, 0x9b, 0xab,
|
||||
0xe3, 0x90, 0x4c, 0x09, 0x47, 0x72, 0x76, 0x35, 0xdb, 0xc3, 0xbe, 0xd9, 0xff, 0x3f, 0x1b, 0x0b, 0x8a, 0xff, 0xb5, 0xf1,
|
||||
0x5f, 0xf9, 0x26, 0xf1, 0xf0, 0x0c, 0x2a, 0x7d, 0xe2, 0x38, 0x20, 0xfe, 0xb3, 0xed, 0xd0, 0x75, 0x59, 0x75, 0x8d, 0xe5,
|
||||
0xb3, 0xeb, 0x12, 0xcf, 0x66, 0xd8, 0xfb, 0x6a, 0x61, 0x7e, 0x6c, 0x94, 0x8f, 0xff, 0x7c, 0xeb, 0x79, 0xf7, 0xd7, 0xb2,
|
||||
0xa5, 0xfa, 0xf3, 0xcc, 0x6e, 0xbe, 0xc4, 0xf7, 0xc5, 0x7f, 0x14, 0xfa, 0x94, 0xf7, 0xe3, 0xb9, 0x27, 0xfe, 0xa3, 0xb0,
|
||||
0x72, 0x31, 0xda, 0x56, 0xf9, 0x6a, 0xeb, 0x12, 0x7d, 0x6b, 0x06, 0xef, 0x5f, 0x81, 0xfb, 0xf8, 0xbf, 0x9b, 0x0f, 0xbe,
|
||||
0xdf, 0xff, 0xc7, 0x11, 0xfd, 0x7f, 0x94, 0xd7, 0x86, 0x47, 0xa1, 0xf5, 0xfd, 0x5a, 0xfc, 0x47, 0x21, 0x66, 0xa2, 0x65,
|
||||
0x5e, 0x3e, 0x96, 0xac, 0xe5, 0xf5, 0xae, 0x19, 0xee, 0xb9, 0x5a, 0x77, 0xbd, 0x68, 0xd7, 0xac, 0xe6, 0x77, 0xc5, 0xff,
|
||||
0x68, 0xe8, 0xff, 0x9f, 0x8d, 0x01, 0x66, 0xbf, 0x47, 0x7c, 0xac, 0xf7, 0xef, 0x8c, 0xff, 0x5d, 0x2b, 0xf6, 0xeb, 0x6b,
|
||||
0x63, 0x1c, 0x71, 0x65, 0xac, 0xff, 0x77, 0x8e, 0xff, 0xeb, 0x6b, 0x00, 0xb9, 0x79, 0x4c, 0x1c, 0x1a, 0xfd, 0x95, 0x39,
|
||||
0x73, 0xd7, 0x1d, 0xfb, 0xde, 0xa7, 0x09, 0xa2, 0xf0, 0xac, 0x46, 0xcf, 0x2a, 0xce, 0xea, 0x6b, 0x90, 0xef, 0xff, 0x77,
|
||||
0xdd, 0xff, 0xbf, 0x1f, 0x73, 0x9f, 0xd1, 0xff, 0x8f, 0xdb, 0xde, 0xfd, 0x94, 0xf3, 0x01, 0xf6, 0xb6, 0x00, 0x21, 0xfa,
|
||||
0xc1, 0x73, 0xc4, 0x80, 0xf8, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x9f, 0xcf,
|
||||
0xef, 0xcf, 0x63, 0x90, 0xcf, 0x84, 0xbd, 0x3e, 0x03, 0xfb, 0x4c, 0x4e, 0xe0, 0x6a, 0x09, 0x75, 0xfd, 0xc5, 0xeb, 0xdc,
|
||||
0xf1, 0x99, 0x4c, 0x0b, 0xcf, 0x6b, 0x46, 0xa4, 0x77, 0x3f, 0xe8, 0xcc, 0x28, 0x50, 0xc9, 0x69, 0x30, 0x92, 0x75, 0xa2,
|
||||
0x37, 0x97, 0x52, 0xee, 0xec, 0xf7, 0xd4, 0xf8, 0x2f, 0xc4, 0xff, 0xfb, 0x9f, 0x8c, 0x42, 0xfe, 0x9e, 0x9d, 0xf1, 0x9f,
|
||||
0xad, 0x7b, 0xb5, 0xfc, 0xb8, 0x73, 0x7d, 0xc9, 0xee, 0x8c, 0x62, 0xd1, 0x78, 0x0d, 0xf7, 0xf5, 0xab, 0x7f, 0xe6, 0xd0,
|
||||
0xd9, 0x51, 0xaf, 0x67, 0xe2, 0x3f, 0x9b, 0xfb, 0x34, 0x2e, 0x5a, 0xe1, 0x73, 0xe2, 0x7f, 0x6c, 0x89, 0xff, 0xf8, 0x48,
|
||||
0xfc, 0x77, 0x67, 0x92, 0xe9, 0xca, 0x42, 0x5e, 0xc9, 0x7c, 0x93, 0xbf, 0x86, 0xf5, 0x0c, 0xbf, 0xd5, 0x1a, 0xf7, 0x9d,
|
||||
0xf8, 0xaf, 0xd4, 0xad, 0xeb, 0x3c, 0xab, 0xe2, 0xff, 0xbe, 0x6c, 0x2b, 0xbd, 0xc9, 0xfc, 0xcf, 0x7b, 0x22, 0x7f, 0x4f,
|
||||
0x1e, 0xdd, 0xbb, 0x7d, 0xb4, 0xd6, 0xd6, 0x95, 0xd9, 0xbe, 0xf2, 0x2b, 0xf1, 0x1f, 0xc5, 0xbf, 0x12, 0x37, 0x2d, 0x4a,
|
||||
0x6f, 0x06, 0xf6, 0x9e, 0xac, 0x6d, 0x7b, 0xe3, 0xbf, 0x7b, 0xdf, 0x9f, 0x33, 0xe2, 0xff, 0xfd, 0x3c, 0xba, 0xab, 0xe6,
|
||||
0x70, 0xbd, 0x7d, 0xe5, 0xef, 0xee, 0xff, 0xef, 0x5b, 0xc9, 0x1d, 0xf5, 0x63, 0xa6, 0xa7, 0x7f, 0xb3, 0xff, 0x7f, 0xef,
|
||||
0xe7, 0xef, 0xc6, 0x7f, 0x57, 0x6d, 0x8f, 0x8d, 0x23, 0x93, 0x6a, 0x5f, 0xb9, 0x73, 0x95, 0x6c, 0xf7, 0xfc, 0x7f, 0xd5,
|
||||
0x37, 0x1b, 0xe9, 0xd1, 0x44, 0x1c, 0x1b, 0xff, 0x33, 0xab, 0x90, 0xeb, 0xc6, 0x0b, 0xef, 0x8c, 0xff, 0x6b, 0xfb, 0xdb,
|
||||
0x56, 0x76, 0x05, 0x3c, 0xad, 0xff, 0xdf, 0x75, 0x97, 0x6c, 0x6c, 0x8e, 0xc9, 0xbd, 0xc7, 0xea, 0xdc, 0xa5, 0x2e, 0x9f,
|
||||
0xbf, 0x3f, 0x9a, 0x47, 0x78, 0x5f, 0x8f, 0xff, 0xfa, 0x2a, 0xff, 0x68, 0x5a, 0x95, 0x7c, 0x6f, 0xfc, 0xbf, 0x7b, 0xa7,
|
||||
0x93, 0xca, 0x51, 0x7a, 0xda, 0xdf, 0x67, 0x77, 0x85, 0x7b, 0x7b, 0x81, 0x9f, 0xef, 0x36, 0x44, 0x53, 0xcf, 0xd1, 0x95,
|
||||
0xbf, 0xff, 0xcf, 0x73, 0xcb, 0xef, 0x78, 0x96, 0xbf, 0x13, 0x1f, 0xc9, 0xfd, 0xf4, 0xdf, 0x88, 0xff, 0xca, 0x91, 0x2b,
|
||||
0xff, 0x2b, 0x7b, 0x0d, 0x3b, 0xe3, 0xff, 0xbd, 0x16, 0x40, 0xde, 0x4d, 0x38, 0x71, 0x14, 0x03, 0xfc, 0x9e, 0x16, 0xc0,
|
||||
0x0e, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xee, 0x37, 0xb1, 0x7f, 0xce,
|
||||
0xcd, 0x55, 0xc9, 0x1a, 0x9f, 0x7f, 0x4f, 0x7a, 0x67, 0xc6, 0xfc, 0x71, 0x93, 0x85, 0xec, 0xfa, 0xb7, 0xfe, 0xfc, 0xa4,
|
||||
0x23, 0x1f, 0x6f, 0x34, 0xbe, 0xb5, 0x9e, 0xc9, 0xe5, 0x1d, 0x85, 0x6c, 0x03, 0x57, 0x6f, 0xc6, 0xe6, 0xae, 0x41, 0xee,
|
||||
0x18, 0xd1, 0x9e, 0xcf, 0x2c, 0xd2, 0xd9, 0x63, 0xfe, 0xf7, 0x9c, 0x9f, 0x67, 0xfa, 0x8d, 0xf2, 0x9b, 0xc6, 0x77, 0xb9,
|
||||
0xcc, 0xf2, 0xf9, 0x11, 0x2a, 0x39, 0xf3, 0xf2, 0x79, 0x36, 0x4f, 0xcf, 0x98, 0x3f, 0x9f, 0x79, 0x27, 0x6e, 0xea, 0xe4,
|
||||
0xf3, 0x5a, 0xfa, 0x24, 0x73, 0x44, 0x4f, 0x06, 0xa1, 0xda, 0x37, 0x8e, 0xe9, 0xda, 0x5a, 0xb9, 0xde, 0x99, 0x23, 0xc4,
|
||||
0xf4, 0xfb, 0xfc, 0x95, 0xfa, 0x1e, 0x93, 0xd7, 0xbd, 0xfe, 0x8d, 0x67, 0xb2, 0x10, 0x44, 0xa9, 0xa7, 0xeb, 0x2c, 0xc1,
|
||||
0xeb, 0x4f, 0xf2, 0x19, 0x33, 0xe3, 0x61, 0x7c, 0x75, 0xff, 0x74, 0x24, 0xdb, 0x9b, 0x4a, 0xbe, 0xba, 0x99, 0x5d, 0x33,
|
||||
0xe6, 0xc6, 0x88, 0xe3, 0x22, 0xbb, 0x52, 0x3e, 0xfa, 0x7f, 0xee, 0x6f, 0x62, 0x32, 0xfe, 0xa3, 0x98, 0x59, 0xa8, 0x1e,
|
||||
0x23, 0xd9, 0xf8, 0x9f, 0xbf, 0x0a, 0xbb, 0xe2, 0xbf, 0x92, 0xf5, 0xe0, 0xfd, 0x8c, 0xd9, 0xb5, 0x9e, 0x70, 0x6f, 0xfc,
|
||||
0xc7, 0x83, 0xf6, 0x6b, 0xa4, 0xe7, 0x2f, 0xa3, 0x90, 0xe1, 0xfc, 0xf9, 0xec, 0x22, 0x5a, 0xfb, 0xff, 0x71, 0x59, 0x26,
|
||||
0xf1, 0xc2, 0xf8, 0xbf, 0xb6, 0xdf, 0x5b, 0x2e, 0xfe, 0x67, 0x5a, 0xa7, 0xfd, 0xfd, 0x7f, 0xad, 0x5f, 0x3b, 0xb9, 0xff,
|
||||
0x7f, 0x27, 0x63, 0x76, 0x14, 0xe6, 0xd9, 0x95, 0xe3, 0xc6, 0xe4, 0xc8, 0xe0, 0xd9, 0x5c, 0x30, 0x1a, 0xe6, 0xab, 0x1d,
|
||||
0xf1, 0xdf, 0x3f, 0xc2, 0xae, 0xcc, 0xad, 0x6a, 0xfd, 0x7f, 0xb4, 0xce, 0xff, 0x23, 0xdd, 0xce, 0xcf, 0xc5, 0x7f, 0xe7,
|
||||
0x6e, 0x4b, 0x2b, 0x32, 0xe6, 0xe6, 0x77, 0x76, 0x7c, 0xab, 0xff, 0x1f, 0xa5, 0xfe, 0xbf, 0xd6, 0x7b, 0xcd, 0xd4, 0xca,
|
||||
0xd8, 0x90, 0xeb, 0x2e, 0x37, 0xfe, 0x5f, 0x3d, 0xca, 0xce, 0xcf, 0x28, 0x63, 0x53, 0xfb, 0xd4, 0x3d, 0xf7, 0xab, 0x45,
|
||||
0x4b, 0xa4, 0xc7, 0xd7, 0x3b, 0x33, 0xe6, 0x56, 0xd6, 0x9e, 0xcf, 0x8f, 0xff, 0xce, 0x3d, 0x4c, 0x2a, 0x77, 0x17, 0xa2,
|
||||
0xa1, 0x6f, 0x5e, 0xdd, 0xff, 0xcf, 0xce, 0xff, 0x2b, 0xb9, 0xf4, 0xf7, 0xac, 0xff, 0x8d, 0xa5, 0x6b, 0x3f, 0xd1, 0x7a,
|
||||
0x3f, 0x71, 0x1c, 0xd0, 0x7e, 0x77, 0x66, 0x89, 0x7f, 0x63, 0xfe, 0xdf, 0x95, 0x81, 0x7d, 0x94, 0xef, 0x09, 0xd5, 0xd7,
|
||||
0xff, 0x67, 0x6b, 0x60, 0x1c, 0xd3, 0xf7, 0x8f, 0xc7, 0x7b, 0xe8, 0xc4, 0x4b, 0xd1, 0x7f, 0x5a, 0xfc, 0x9f, 0xf2, 0x44,
|
||||
0x43, 0x47, 0xbb, 0x15, 0x2d, 0xad, 0x5b, 0x65, 0xdf, 0x96, 0xce, 0x71, 0xd4, 0xfc, 0xfc, 0x7f, 0xcd, 0xba, 0xfa, 0x1b,
|
||||
0xc7, 0x98, 0xb9, 0x23, 0x3b, 0x1f, 0xff, 0xb1, 0xbc, 0xe4, 0xe4, 0x23, 0xfe, 0x4e, 0x2b, 0x75, 0xde, 0xf1, 0xfe, 0xe6,
|
||||
0xda, 0x13, 0x1b, 0x9f, 0xb5, 0x13, 0xa1, 0xc4, 0xd1, 0xf3, 0x21, 0xd7, 0x03, 0xfe, 0xe6, 0xf9, 0xd0, 0xdf, 0xfa, 0x1c,
|
||||
0xbc, 0x92, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4e, 0x7d, 0x3b, 0xa4, 0x92, 0x59,
|
||||
0x72, 0x34, 0xbf, 0x8b, 0x9e, 0xcf, 0xad, 0x5f, 0x3d, 0xbb, 0xbb, 0xf7, 0xa5, 0x6b, 0xf9, 0x79, 0x6b, 0xe5, 0x34, 0x97,
|
||||
0x8f, 0x28, 0x97, 0x53, 0xed, 0x7e, 0xff, 0x83, 0x38, 0xf2, 0x6a, 0xde, 0x65, 0x75, 0x8d, 0x42, 0x3e, 0xd5, 0xce, 0xeb,
|
||||
0x35, 0x4a, 0x65, 0xb7, 0xab, 0x96, 0x3d, 0x7f, 0x3b, 0x34, 0x36, 0xbc, 0x4f, 0x59, 0x8b, 0x85, 0x5a, 0x6e, 0xc3, 0xb9,
|
||||
0xdc, 0x61, 0xb1, 0xf8, 0x9b, 0xe5, 0xca, 0x6f, 0x7e, 0x3f, 0x89, 0xfb, 0x6c, 0xab, 0xf1, 0xb9, 0xab, 0x59, 0xcd, 0xf8,
|
||||
0xde, 0x7d, 0xbd, 0xea, 0xb5, 0xe5, 0x84, 0x5a, 0xb6, 0x7e, 0x67, 0x89, 0x37, 0xde, 0x6e, 0xad, 0x66, 0xc4, 0x8d, 0xcf,
|
||||
0xbf, 0x73, 0x1a, 0x1f, 0xcd, 0x05, 0x50, 0xcb, 0x13, 0xb9, 0xeb, 0x5b, 0x55, 0x8e, 0x14, 0xa5, 0x3d, 0x9b, 0xc6, 0xf6,
|
||||
0xec, 0x10, 0xf9, 0xec, 0xe7, 0xa3, 0x94, 0xef, 0xb3, 0xfb, 0x93, 0xca, 0x15, 0xa9, 0xc7, 0xff, 0x55, 0x39, 0x55, 0x3e,
|
||||
0x99, 0xed, 0xff, 0xc7, 0xf2, 0x7d, 0x18, 0x4e, 0xb9, 0x9a, 0x77, 0xfd, 0x7f, 0xb4, 0xed, 0x98, 0xb4, 0xf7, 0x93, 0x1d,
|
||||
0xe5, 0xda, 0x11, 0x0b, 0xbb, 0xf6, 0xfb, 0x8b, 0x74, 0xad, 0x18, 0xe9, 0x1c, 0x7b, 0xf5, 0xd9, 0xd7, 0xae, 0x4f, 0x56,
|
||||
0xc4, 0x7f, 0x5c, 0xcc, 0x93, 0xbb, 0x77, 0x1d, 0xeb, 0xbe, 0x9a, 0x4f, 0x5a, 0x86, 0x2f, 0xc6, 0xff, 0x8e, 0xf8, 0x99,
|
||||
0x9d, 0xff, 0x47, 0x79, 0x37, 0x9d, 0x33, 0x6b, 0x4c, 0x3c, 0xcc, 0xe8, 0xfc, 0xdb, 0xe2, 0x7f, 0x6f, 0x19, 0x77, 0xb7,
|
||||
0xe6, 0xd7, 0x23, 0xec, 0xf1, 0xd1, 0xf8, 0x9f, 0xdd, 0xef, 0x6d, 0x7e, 0xee, 0x7a, 0xbf, 0xfe, 0xdf, 0xb9, 0xb2, 0x71,
|
||||
0x46, 0xfc, 0x9f, 0x12, 0xe5, 0xb9, 0x32, 0x5f, 0x1b, 0xff, 0xef, 0xc7, 0x50, 0x57, 0x1f, 0xf6, 0xde, 0xb9, 0x47, 0xdb,
|
||||
0xfc, 0xff, 0x7e, 0x97, 0xe4, 0xdc, 0xdd, 0x9d, 0xbd, 0xab, 0x49, 0x3b, 0x4b, 0xbd, 0x73, 0xcf, 0xe1, 0xa7, 0x63, 0x87,
|
||||
0xee, 0xf9, 0xee, 0x19, 0xfd, 0x7f, 0x88, 0xff, 0x05, 0x6b, 0xe1, 0x27, 0xf4, 0x92, 0xab, 0xee, 0xe5, 0xe5, 0xb3, 0xd8,
|
||||
0xf7, 0x7e, 0x32, 0x5b, 0x52, 0xf9, 0xfb, 0xff, 0x5f, 0x1f, 0xff, 0x3f, 0xd9, 0xe1, 0xe7, 0x5b, 0xf1, 0x1f, 0xc5, 0x15,
|
||||
0xc5, 0x33, 0xe2, 0x3f, 0x36, 0x8e, 0x6a, 0x57, 0xdc, 0xcb, 0x3f, 0x79, 0xfc, 0xdf, 0xbf, 0x13, 0xd4, 0xd7, 0xe3, 0xff,
|
||||
0x0b, 0x63, 0xe8, 0x35, 0x4f, 0xa1, 0xbc, 0x17, 0xff, 0x73, 0x77, 0x86, 0x4f, 0x1e, 0xff, 0x9f, 0x1e, 0xff, 0xb3, 0x57,
|
||||
0x25, 0x36, 0xcd, 0xff, 0x9f, 0x8e, 0x34, 0x7e, 0x7f, 0xfc, 0x8f, 0xad, 0x7b, 0xf7, 0xd7, 0xe7, 0x9b, 0xe3, 0xd0, 0x67,
|
||||
0x61, 0xce, 0x79, 0x8a, 0xe3, 0xfd, 0x99, 0xcd, 0xfc, 0xae, 0xa8, 0xeb, 0xef, 0xff, 0x8f, 0x65, 0xfd, 0x7f, 0xef, 0x93,
|
||||
0x2d, 0xbb, 0xee, 0xff, 0xef, 0x7d, 0xa2, 0xa8, 0xfb, 0x0c, 0xc5, 0xff, 0x37, 0xda, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xe2, 0x73, 0xf2, 0x2b, 0x72, 0xeb, 0xf7, 0xe7, 0xc3, 0x38, 0x3d, 0xb7, 0xfe,
|
||||
0xdd, 0xfb, 0x33, 0xe3, 0xd8, 0xdc, 0xfa, 0xe3, 0x51, 0x8e, 0xa2, 0xef, 0xe5, 0xd6, 0xf7, 0xee, 0xc7, 0xd3, 0xb7, 0x64,
|
||||
0xd6, 0xe5, 0xd6, 0xef, 0x7b, 0x87, 0xfa, 0xf4, 0xdc, 0xfa, 0xe3, 0x26, 0x13, 0xd1, 0xc9, 0xb9, 0xf5, 0xeb, 0x6f, 0x51,
|
||||
0x9d, 0x9a, 0x5b, 0x9f, 0xb5, 0xef, 0x4e, 0x3e, 0x6d, 0xfb, 0xe3, 0xc5, 0x6b, 0xf6, 0x46, 0x36, 0x84, 0x93, 0x6b, 0x64,
|
||||
0x3e, 0x5b, 0xd3, 0x8a, 0x16, 0xa5, 0xf3, 0x7d, 0xcd, 0xb3, 0x73, 0xeb, 0x7f, 0x3d, 0xc6, 0xeb, 0xd9, 0x58, 0xa3, 0x9c,
|
||||
0xf3, 0xbe, 0xef, 0x5d, 0xed, 0x48, 0x8d, 0x1b, 0xd7, 0xe6, 0xd6, 0xba, 0x6e, 0x47, 0xcf, 0xdd, 0x29, 0xe1, 0xdb, 0xb9,
|
||||
0xb5, 0xc5, 0x7f, 0x4f, 0xab, 0x1b, 0x4d, 0x51, 0xf7, 0xf4, 0x93, 0x7d, 0x59, 0x83, 0xfa, 0xe2, 0x3f, 0xda, 0x3f, 0xdb,
|
||||
0x9b, 0x5b, 0xab, 0xba, 0x9e, 0x20, 0xfe, 0x7f, 0x57, 0x3b, 0x90, 0x99, 0xd1, 0x3e, 0x29, 0xf7, 0x37, 0x6b, 0xc0, 0xce,
|
||||
0xdc, 0x5a, 0x5f, 0x8f, 0xff, 0x4a, 0xff, 0x20, 0xfe, 0x7f, 0xcf, 0xf8, 0xbf, 0xaf, 0x2f, 0xaf, 0xaf, 0xff, 0x7f, 0x79,
|
||||
0x6f, 0xad, 0xdf, 0x19, 0xff, 0x67, 0xe4, 0xd6, 0x15, 0xff, 0xef, 0x8c, 0xff, 0x6b, 0xfb, 0x13, 0xac, 0x58, 0xcd, 0xed,
|
||||
0x9d, 0x4d, 0x88, 0xff, 0xd5, 0x75, 0xe7, 0xa4, 0x9d, 0x21, 0xc4, 0x78, 0x7d, 0xfe, 0x5f, 0xdb, 0x13, 0xb4, 0xda, 0x02,
|
||||
0xec, 0xcb, 0xd5, 0xfa, 0x46, 0x6e, 0x7d, 0xb9, 0x75, 0x67, 0xae, 0xd7, 0xf5, 0xe8, 0xef, 0x9b, 0xf7, 0x63, 0x4e, 0x1f,
|
||||
0xff, 0xf7, 0xde, 0xab, 0xf9, 0xff, 0x35, 0xa5, 0xd5, 0x2b, 0xde, 0xab, 0xc6, 0xff, 0x2b, 0xda, 0xd8, 0x37, 0x4b, 0x63,
|
||||
0xcd, 0xbd, 0xa3, 0xfe, 0x33, 0x8c, 0xa6, 0xd1, 0x1f, 0xef, 0xb4, 0x1a, 0xb0, 0x66, 0x9c, 0xf1, 0x7e, 0x4b, 0x08, 0x7c,
|
||||
0xed, 0x49, 0x2e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x56, 0xf9, 0xef, 0x3f, 0xfb, 0x01, 0xd4, 0x3f,
|
||||
0xf0, 0xeb, 0xea, 0xff, 0x3f };
|
||||
0x00, 0x00, 0x00, 0x80, 0x93, 0xfc, 0xfb, 0x9f, 0x72, 0x00, 0xf1, 0x0f, 0xfc, 0x75, 0xf1, 0xff, 0x2f };
|
||||
|
||||
// Font glyphs rectangles data (on atlas)
|
||||
static const Rectangle darkFontRecs[189] = {
|
||||
@@ -257,100 +257,100 @@ static const Rectangle darkFontRecs[189] = {
|
||||
{ 218, 52, 6 , 9 },
|
||||
{ 232, 52, 5 , 9 },
|
||||
{ 245, 52, 5 , 12 },
|
||||
{ 258, 52, 5 , 9 },
|
||||
{ 271, 52, 5 , 10 },
|
||||
{ 284, 52, 7 , 9 },
|
||||
{ 299, 52, 5 , 9 },
|
||||
{ 312, 52, 6 , 5 },
|
||||
{ 326, 52, 5 , 3 },
|
||||
{ 339, 52, 7 , 9 },
|
||||
{ 354, 52, 5 , 9 },
|
||||
{ 367, 52, 4 , 4 },
|
||||
{ 379, 52, 5 , 7 },
|
||||
{ 392, 52, 5 , 9 },
|
||||
{ 405, 52, 5 , 9 },
|
||||
{ 418, 52, 5 , 12 },
|
||||
{ 431, 52, 5 , 9 },
|
||||
{ 444, 52, 7 , 9 },
|
||||
{ 459, 52, 1 , 1 },
|
||||
{ 468, 52, 5 , 10 },
|
||||
{ 481, 52, 5 , 9 },
|
||||
{ 494, 52, 5 , 9 },
|
||||
{ 4, 76, 6 , 5 },
|
||||
{ 18, 76, 9 , 9 },
|
||||
{ 35, 76, 9 , 7 },
|
||||
{ 52, 76, 5 , 11 },
|
||||
{ 65, 76, 5 , 9 },
|
||||
{ 78, 76, 5 , 12 },
|
||||
{ 91, 76, 5 , 12 },
|
||||
{ 104, 76, 5 , 12 },
|
||||
{ 117, 76, 6 , 12 },
|
||||
{ 131, 76, 5 , 11 },
|
||||
{ 144, 76, 5 , 13 },
|
||||
{ 157, 76, 9 , 9 },
|
||||
{ 174, 76, 5 , 12 },
|
||||
{ 187, 76, 5 , 12 },
|
||||
{ 200, 76, 5 , 12 },
|
||||
{ 213, 76, 5 , 12 },
|
||||
{ 226, 76, 5 , 11 },
|
||||
{ 239, 76, 2 , 12 },
|
||||
{ 249, 76, 2 , 12 },
|
||||
{ 259, 76, 3 , 12 },
|
||||
{ 270, 76, 3 , 11 },
|
||||
{ 281, 76, 6 , 9 },
|
||||
{ 295, 76, 6 , 12 },
|
||||
{ 309, 76, 5 , 12 },
|
||||
{ 322, 76, 5 , 12 },
|
||||
{ 335, 76, 5 , 12 },
|
||||
{ 348, 76, 6 , 12 },
|
||||
{ 362, 76, 5 , 11 },
|
||||
{ 375, 76, 5 , 5 },
|
||||
{ 388, 76, 7 , 9 },
|
||||
{ 403, 76, 5 , 12 },
|
||||
{ 416, 76, 5 , 12 },
|
||||
{ 429, 76, 5 , 12 },
|
||||
{ 442, 76, 5 , 11 },
|
||||
{ 455, 76, 5 , 12 },
|
||||
{ 468, 76, 5 , 9 },
|
||||
{ 481, 76, 5 , 9 },
|
||||
{ 494, 76, 5 , 10 },
|
||||
{ 4, 100, 5 , 10 },
|
||||
{ 17, 100, 5 , 10 },
|
||||
{ 30, 100, 6 , 10 },
|
||||
{ 44, 100, 5 , 9 },
|
||||
{ 57, 100, 5 , 11 },
|
||||
{ 70, 100, 9 , 7 },
|
||||
{ 258, 52, 0 , 0 },
|
||||
{ 266, 52, 5 , 10 },
|
||||
{ 279, 52, 7 , 9 },
|
||||
{ 294, 52, 0 , 0 },
|
||||
{ 302, 52, 6 , 5 },
|
||||
{ 316, 52, 5 , 3 },
|
||||
{ 329, 52, 7 , 9 },
|
||||
{ 344, 52, 0 , 0 },
|
||||
{ 352, 52, 4 , 4 },
|
||||
{ 364, 52, 5 , 7 },
|
||||
{ 377, 52, 0 , 0 },
|
||||
{ 385, 52, 0 , 0 },
|
||||
{ 393, 52, 5 , 12 },
|
||||
{ 406, 52, 5 , 9 },
|
||||
{ 419, 52, 7 , 9 },
|
||||
{ 434, 52, 1 , 1 },
|
||||
{ 443, 52, 5 , 10 },
|
||||
{ 456, 52, 0 , 0 },
|
||||
{ 464, 52, 0 , 0 },
|
||||
{ 472, 52, 6 , 5 },
|
||||
{ 486, 52, 9 , 9 },
|
||||
{ 4, 76, 9 , 7 },
|
||||
{ 21, 76, 5 , 11 },
|
||||
{ 34, 76, 5 , 9 },
|
||||
{ 47, 76, 5 , 12 },
|
||||
{ 60, 76, 5 , 12 },
|
||||
{ 73, 76, 5 , 12 },
|
||||
{ 86, 76, 6 , 12 },
|
||||
{ 100, 76, 5 , 11 },
|
||||
{ 113, 76, 5 , 13 },
|
||||
{ 126, 76, 9 , 9 },
|
||||
{ 143, 76, 5 , 12 },
|
||||
{ 156, 76, 5 , 12 },
|
||||
{ 169, 76, 5 , 12 },
|
||||
{ 182, 76, 5 , 12 },
|
||||
{ 195, 76, 5 , 11 },
|
||||
{ 208, 76, 2 , 12 },
|
||||
{ 218, 76, 2 , 12 },
|
||||
{ 228, 76, 3 , 12 },
|
||||
{ 239, 76, 3 , 11 },
|
||||
{ 250, 76, 6 , 9 },
|
||||
{ 264, 76, 6 , 12 },
|
||||
{ 278, 76, 5 , 12 },
|
||||
{ 291, 76, 5 , 12 },
|
||||
{ 304, 76, 5 , 12 },
|
||||
{ 317, 76, 6 , 12 },
|
||||
{ 331, 76, 5 , 11 },
|
||||
{ 344, 76, 5 , 5 },
|
||||
{ 357, 76, 7 , 9 },
|
||||
{ 372, 76, 5 , 12 },
|
||||
{ 385, 76, 5 , 12 },
|
||||
{ 398, 76, 5 , 12 },
|
||||
{ 411, 76, 5 , 11 },
|
||||
{ 424, 76, 5 , 12 },
|
||||
{ 437, 76, 5 , 9 },
|
||||
{ 450, 76, 5 , 9 },
|
||||
{ 463, 76, 5 , 10 },
|
||||
{ 476, 76, 5 , 10 },
|
||||
{ 489, 76, 5 , 10 },
|
||||
{ 4, 100, 6 , 10 },
|
||||
{ 18, 100, 5 , 9 },
|
||||
{ 31, 100, 5 , 11 },
|
||||
{ 44, 100, 9 , 7 },
|
||||
{ 61, 100, 5 , 10 },
|
||||
{ 74, 100, 5 , 10 },
|
||||
{ 87, 100, 5 , 10 },
|
||||
{ 100, 100, 5 , 10 },
|
||||
{ 113, 100, 5 , 10 },
|
||||
{ 126, 100, 5 , 10 },
|
||||
{ 139, 100, 5 , 9 },
|
||||
{ 152, 100, 2 , 10 },
|
||||
{ 162, 100, 2 , 10 },
|
||||
{ 172, 100, 3 , 10 },
|
||||
{ 183, 100, 3 , 9 },
|
||||
{ 194, 100, 6 , 9 },
|
||||
{ 208, 100, 6 , 10 },
|
||||
{ 113, 100, 5 , 9 },
|
||||
{ 126, 100, 2 , 10 },
|
||||
{ 136, 100, 2 , 10 },
|
||||
{ 146, 100, 3 , 10 },
|
||||
{ 157, 100, 3 , 9 },
|
||||
{ 168, 100, 6 , 9 },
|
||||
{ 182, 100, 6 , 10 },
|
||||
{ 196, 100, 5 , 10 },
|
||||
{ 209, 100, 5 , 10 },
|
||||
{ 222, 100, 5 , 10 },
|
||||
{ 235, 100, 5 , 10 },
|
||||
{ 248, 100, 5 , 10 },
|
||||
{ 261, 100, 6 , 10 },
|
||||
{ 275, 100, 5 , 9 },
|
||||
{ 288, 100, 5 , 5 },
|
||||
{ 301, 100, 7 , 7 },
|
||||
{ 235, 100, 6 , 10 },
|
||||
{ 249, 100, 5 , 9 },
|
||||
{ 262, 100, 5 , 5 },
|
||||
{ 275, 100, 7 , 7 },
|
||||
{ 290, 100, 5 , 10 },
|
||||
{ 303, 100, 5 , 10 },
|
||||
{ 316, 100, 5 , 10 },
|
||||
{ 329, 100, 5 , 10 },
|
||||
{ 342, 100, 5 , 10 },
|
||||
{ 355, 100, 5 , 9 },
|
||||
{ 368, 100, 5 , 12 },
|
||||
{ 381, 100, 5 , 11 },
|
||||
{ 394, 100, 5 , 11 },
|
||||
{ 329, 100, 5 , 9 },
|
||||
{ 342, 100, 5 , 12 },
|
||||
{ 355, 100, 5 , 11 },
|
||||
{ 368, 100, 5 , 11 },
|
||||
};
|
||||
|
||||
// Font glyphs info data
|
||||
// NOTE: No glyphs.image data provided
|
||||
static const GlyphInfo darkFontGlyphs[189] = {
|
||||
{ 32, 0, 13, 4, { 0 }},
|
||||
{ 32, 0, 0, 4, { 0 }},
|
||||
{ 33, 2, 4, 5, { 0 }},
|
||||
{ 34, 2, 4, 7, { 0 }},
|
||||
{ 35, 1, 4, 8, { 0 }},
|
||||
@@ -451,25 +451,25 @@ static const GlyphInfo darkFontGlyphs[189] = {
|
||||
{ 8364, 1, 4, 8, { 0 }},
|
||||
{ 165, 1, 4, 7, { 0 }},
|
||||
{ 352, 1, 1, 7, { 0 }},
|
||||
{ 167, 2, 4, 9, { 0 }},
|
||||
{ 167, 0, 0, 0, { 0 }},
|
||||
{ 353, 1, 3, 7, { 0 }},
|
||||
{ 169, 1, 4, 9, { 0 }},
|
||||
{ 170, 2, 4, 9, { 0 }},
|
||||
{ 170, 0, 0, 0, { 0 }},
|
||||
{ 171, 1, 6, 8, { 0 }},
|
||||
{ 172, 1, 8, 7, { 0 }},
|
||||
{ 174, 1, 4, 9, { 0 }},
|
||||
{ 175, 2, 4, 9, { 0 }},
|
||||
{ 175, 0, 0, 0, { 0 }},
|
||||
{ 176, 1, 4, 6, { 0 }},
|
||||
{ 177, 1, 6, 7, { 0 }},
|
||||
{ 178, 2, 4, 9, { 0 }},
|
||||
{ 179, 2, 4, 9, { 0 }},
|
||||
{ 178, 0, 0, 0, { 0 }},
|
||||
{ 179, 0, 0, 0, { 0 }},
|
||||
{ 381, 1, 1, 7, { 0 }},
|
||||
{ 181, 1, 6, 7, { 0 }},
|
||||
{ 182, 1, 4, 9, { 0 }},
|
||||
{ 183, 2, 8, 5, { 0 }},
|
||||
{ 382, 1, 3, 7, { 0 }},
|
||||
{ 185, 2, 4, 9, { 0 }},
|
||||
{ 186, 2, 4, 9, { 0 }},
|
||||
{ 185, 0, 0, 0, { 0 }},
|
||||
{ 186, 0, 0, 0, { 0 }},
|
||||
{ 187, 1, 6, 8, { 0 }},
|
||||
{ 338, 1, 4, 11, { 0 }},
|
||||
{ 339, 1, 6, 11, { 0 }},
|
||||
|
||||
|
Before Width: | Height: | Size: 31 KiB After Width: | Height: | Size: 33 KiB |
@@ -1,22 +1,22 @@
|
||||
/**********************************************************************************************
|
||||
*
|
||||
* raylib v5.5-dev - A simple and easy-to-use library to enjoy videogames programming (www.raylib.com)
|
||||
* raylib v5.6-dev - A simple and easy-to-use library to enjoy videogames programming (www.raylib.com)
|
||||
*
|
||||
* FEATURES:
|
||||
* - NO external dependencies, all required libraries included with raylib
|
||||
* - Multiplatform: Windows, Linux, FreeBSD, OpenBSD, NetBSD, DragonFly,
|
||||
* MacOS, Haiku, Android, Raspberry Pi, DRM native, HTML5.
|
||||
* - Written in plain C code (C99) in PascalCase/camelCase notation
|
||||
* - Hardware accelerated with OpenGL (1.1, 2.1, 3.3, 4.3 or ES2 - choose at compile)
|
||||
* - Hardware accelerated with OpenGL (1.1, 2.1, 3.3, 4.3, ES2, ES3 - choose at compile)
|
||||
* - Unique OpenGL abstraction layer (usable as standalone module): [rlgl]
|
||||
* - Multiple Fonts formats supported (TTF, XNA fonts, AngelCode fonts)
|
||||
* - Multiple Fonts formats supported (TTF, OTF, FNT, BDF, Sprite fonts)
|
||||
* - Outstanding texture formats support, including compressed formats (DXT, ETC, ASTC)
|
||||
* - Full 3d support for 3d Shapes, Models, Billboards, Heightmaps and more!
|
||||
* - Flexible Materials system, supporting classic maps and PBR maps
|
||||
* - Animated 3D models supported (skeletal bones animation) (IQM)
|
||||
* - Animated 3D models supported (skeletal bones animation) (IQM, M3D, GLTF)
|
||||
* - Shaders support, including Model shaders and Postprocessing shaders
|
||||
* - Powerful math module for Vector, Matrix and Quaternion operations: [raymath]
|
||||
* - Audio loading and playing with streaming support (WAV, OGG, MP3, FLAC, XM, MOD)
|
||||
* - Audio loading and playing with streaming support (WAV, OGG, MP3, FLAC, QOA, XM, MOD)
|
||||
* - VR stereo rendering with configurable HMD device parameters
|
||||
* - Bindings to multiple programming languages available!
|
||||
*
|
||||
@@ -27,29 +27,35 @@
|
||||
* - One default RenderBatch is loaded on rlglInit()->rlLoadRenderBatch() [rlgl] (OpenGL 3.3 or ES2)
|
||||
*
|
||||
* DEPENDENCIES (included):
|
||||
* [rcore] rglfw (Camilla Löwy - github.com/glfw/glfw) for window/context management and input (PLATFORM_DESKTOP)
|
||||
* [rlgl] glad (David Herberth - github.com/Dav1dde/glad) for OpenGL 3.3 extensions loading (PLATFORM_DESKTOP)
|
||||
* [rcore][GLFW] rglfw (Camilla Löwy - github.com/glfw/glfw) for window/context management and input
|
||||
* [rcore][RGFW] rgfw (ColleagueRiley - github.com/ColleagueRiley/RGFW) for window/context management and input
|
||||
* [rlgl] glad/glad_gles2 (David Herberth - github.com/Dav1dde/glad) for OpenGL 3.3 extensions loading
|
||||
* [raudio] miniaudio (David Reid - github.com/mackron/miniaudio) for audio device/context management
|
||||
*
|
||||
* OPTIONAL DEPENDENCIES (included):
|
||||
* [rcore] msf_gif (Miles Fogle) for GIF recording
|
||||
* [rcore] sinfl (Micha Mettke) for DEFLATE decompression algorithm
|
||||
* [rcore] sdefl (Micha Mettke) for DEFLATE compression algorithm
|
||||
* [rcore] rprand (Ramon Snatamaria) for pseudo-random numbers generation
|
||||
* [rtextures] qoi (Dominic Szablewski - https://phoboslab.org) for QOI image manage
|
||||
* [rtextures] stb_image (Sean Barret) for images loading (BMP, TGA, PNG, JPEG, HDR...)
|
||||
* [rtextures] stb_image_write (Sean Barret) for image writing (BMP, TGA, PNG, JPG)
|
||||
* [rtextures] stb_image_resize (Sean Barret) for image resizing algorithms
|
||||
* [rtextures] stb_image_resize2 (Sean Barret) for image resizing algorithms
|
||||
* [rtextures] stb_perlin (Sean Barret) for Perlin Noise image generation
|
||||
* [rtext] stb_truetype (Sean Barret) for ttf fonts loading
|
||||
* [rtext] stb_rect_pack (Sean Barret) for rectangles packing
|
||||
* [rmodels] par_shapes (Philip Rideout) for parametric 3d shapes generation
|
||||
* [rmodels] tinyobj_loader_c (Syoyo Fujita) for models loading (OBJ, MTL)
|
||||
* [rmodels] cgltf (Johannes Kuhlmann) for models loading (glTF)
|
||||
* [rmodels] Model3D (bzt) for models loading (M3D, https://bztsrc.gitlab.io/model3d)
|
||||
* [rmodels] m3d (bzt) for models loading (M3D, https://bztsrc.gitlab.io/model3d)
|
||||
* [rmodels] vox_loader (Johann Nadalutti) for models loading (VOX)
|
||||
* [raudio] dr_wav (David Reid) for WAV audio file loading
|
||||
* [raudio] dr_flac (David Reid) for FLAC audio file loading
|
||||
* [raudio] dr_mp3 (David Reid) for MP3 audio file loading
|
||||
* [raudio] stb_vorbis (Sean Barret) for OGG audio loading
|
||||
* [raudio] jar_xm (Joshua Reisenauer) for XM audio module loading
|
||||
* [raudio] jar_mod (Joshua Reisenauer) for MOD audio module loading
|
||||
* [raudio] qoa (Dominic Szablewski - https://phoboslab.org) for QOA audio manage
|
||||
*
|
||||
*
|
||||
* LICENSE: zlib/libpng
|
||||
@@ -57,7 +63,7 @@
|
||||
* raylib is licensed under an unmodified zlib/libpng license, which is an OSI-certified,
|
||||
* BSD-like license that allows static linking with closed source software:
|
||||
*
|
||||
* Copyright (c) 2013-2024 Ramon Santamaria (@raysan5)
|
||||
* Copyright (c) 2013-2025 Ramon Santamaria (@raysan5)
|
||||
*
|
||||
* This software is provided "as-is", without any express or implied warranty. In no event
|
||||
* will the authors be held liable for any damages arising from the use of this software.
|
||||
@@ -82,9 +88,9 @@
|
||||
#include <stdarg.h> // Required for: va_list - Only used by TraceLogCallback
|
||||
|
||||
#define RAYLIB_VERSION_MAJOR 5
|
||||
#define RAYLIB_VERSION_MINOR 5
|
||||
#define RAYLIB_VERSION_MINOR 6
|
||||
#define RAYLIB_VERSION_PATCH 0
|
||||
#define RAYLIB_VERSION "5.5-dev"
|
||||
#define RAYLIB_VERSION "5.6-dev"
|
||||
|
||||
// Function specifiers in case library is build/used as a shared library
|
||||
// NOTE: Microsoft specifiers to tell compiler that symbols are imported/exported from a .dll
|
||||
@@ -737,7 +743,7 @@ typedef enum {
|
||||
GAMEPAD_BUTTON_RIGHT_THUMB // Gamepad joystick pressed button right
|
||||
} GamepadButton;
|
||||
|
||||
// Gamepad axis
|
||||
// Gamepad axes
|
||||
typedef enum {
|
||||
GAMEPAD_AXIS_LEFT_X = 0, // Gamepad left stick X axis
|
||||
GAMEPAD_AXIS_LEFT_Y = 1, // Gamepad left stick Y axis
|
||||
@@ -795,7 +801,8 @@ typedef enum {
|
||||
SHADER_LOC_MAP_BRDF, // Shader location: sampler2d texture: brdf
|
||||
SHADER_LOC_VERTEX_BONEIDS, // Shader location: vertex attribute: boneIds
|
||||
SHADER_LOC_VERTEX_BONEWEIGHTS, // Shader location: vertex attribute: boneWeights
|
||||
SHADER_LOC_BONE_MATRICES // Shader location: array of matrices uniform: boneMatrices
|
||||
SHADER_LOC_BONE_MATRICES, // Shader location: array of matrices uniform: boneMatrices
|
||||
SHADER_LOC_VERTEX_INSTANCE_TX // Shader location: vertex attribute: instanceTransform
|
||||
} ShaderLocationIndex;
|
||||
|
||||
#define SHADER_LOC_MAP_DIFFUSE SHADER_LOC_MAP_ALBEDO
|
||||
@@ -811,6 +818,10 @@ typedef enum {
|
||||
SHADER_UNIFORM_IVEC2, // Shader uniform type: ivec2 (2 int)
|
||||
SHADER_UNIFORM_IVEC3, // Shader uniform type: ivec3 (3 int)
|
||||
SHADER_UNIFORM_IVEC4, // Shader uniform type: ivec4 (4 int)
|
||||
SHADER_UNIFORM_UINT, // Shader uniform type: unsigned int
|
||||
SHADER_UNIFORM_UIVEC2, // Shader uniform type: uivec2 (2 unsigned int)
|
||||
SHADER_UNIFORM_UIVEC3, // Shader uniform type: uivec3 (3 unsigned int)
|
||||
SHADER_UNIFORM_UIVEC4, // Shader uniform type: uivec4 (4 unsigned int)
|
||||
SHADER_UNIFORM_SAMPLER2D // Shader uniform type: sampler2d
|
||||
} ShaderUniformDataType;
|
||||
|
||||
@@ -877,8 +888,7 @@ typedef enum {
|
||||
CUBEMAP_LAYOUT_LINE_VERTICAL, // Layout is defined by a vertical line with faces
|
||||
CUBEMAP_LAYOUT_LINE_HORIZONTAL, // Layout is defined by a horizontal line with faces
|
||||
CUBEMAP_LAYOUT_CROSS_THREE_BY_FOUR, // Layout is defined by a 3x4 cross with cubemap faces
|
||||
CUBEMAP_LAYOUT_CROSS_FOUR_BY_THREE, // Layout is defined by a 4x3 cross with cubemap faces
|
||||
CUBEMAP_LAYOUT_PANORAMA // Layout is defined by a panorama image (equirrectangular map)
|
||||
CUBEMAP_LAYOUT_CROSS_FOUR_BY_THREE // Layout is defined by a 4x3 cross with cubemap faces
|
||||
} CubemapLayout;
|
||||
|
||||
// Font type, defines generation method
|
||||
@@ -944,7 +954,7 @@ typedef void (*TraceLogCallback)(int logLevel, const char *text, va_list args);
|
||||
typedef unsigned char *(*LoadFileDataCallback)(const char *fileName, int *dataSize); // FileIO: Load binary data
|
||||
typedef bool (*SaveFileDataCallback)(const char *fileName, void *data, int dataSize); // FileIO: Save binary data
|
||||
typedef char *(*LoadFileTextCallback)(const char *fileName); // FileIO: Load text data
|
||||
typedef bool (*SaveFileTextCallback)(const char *fileName, char *text); // FileIO: Save text data
|
||||
typedef bool (*SaveFileTextCallback)(const char *fileName, const char *text); // FileIO: Save text data
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
// Global Variables Definition
|
||||
@@ -965,36 +975,36 @@ RLAPI void CloseWindow(void); // Close windo
|
||||
RLAPI bool WindowShouldClose(void); // Check if application should close (KEY_ESCAPE pressed or windows close icon clicked)
|
||||
RLAPI bool IsWindowReady(void); // Check if window has been initialized successfully
|
||||
RLAPI bool IsWindowFullscreen(void); // Check if window is currently fullscreen
|
||||
RLAPI bool IsWindowHidden(void); // Check if window is currently hidden (only PLATFORM_DESKTOP)
|
||||
RLAPI bool IsWindowMinimized(void); // Check if window is currently minimized (only PLATFORM_DESKTOP)
|
||||
RLAPI bool IsWindowMaximized(void); // Check if window is currently maximized (only PLATFORM_DESKTOP)
|
||||
RLAPI bool IsWindowFocused(void); // Check if window is currently focused (only PLATFORM_DESKTOP)
|
||||
RLAPI bool IsWindowHidden(void); // Check if window is currently hidden
|
||||
RLAPI bool IsWindowMinimized(void); // Check if window is currently minimized
|
||||
RLAPI bool IsWindowMaximized(void); // Check if window is currently maximized
|
||||
RLAPI bool IsWindowFocused(void); // Check if window is currently focused
|
||||
RLAPI bool IsWindowResized(void); // Check if window has been resized last frame
|
||||
RLAPI bool IsWindowState(unsigned int flag); // Check if one specific window flag is enabled
|
||||
RLAPI void SetWindowState(unsigned int flags); // Set window configuration state using flags (only PLATFORM_DESKTOP)
|
||||
RLAPI void SetWindowState(unsigned int flags); // Set window configuration state using flags
|
||||
RLAPI void ClearWindowState(unsigned int flags); // Clear window configuration state flags
|
||||
RLAPI void ToggleFullscreen(void); // Toggle window state: fullscreen/windowed [resizes monitor to match window resolution] (only PLATFORM_DESKTOP)
|
||||
RLAPI void ToggleBorderlessWindowed(void); // Toggle window state: borderless windowed [resizes window to match monitor resolution] (only PLATFORM_DESKTOP)
|
||||
RLAPI void MaximizeWindow(void); // Set window state: maximized, if resizable (only PLATFORM_DESKTOP)
|
||||
RLAPI void MinimizeWindow(void); // Set window state: minimized, if resizable (only PLATFORM_DESKTOP)
|
||||
RLAPI void RestoreWindow(void); // Set window state: not minimized/maximized (only PLATFORM_DESKTOP)
|
||||
RLAPI void SetWindowIcon(Image image); // Set icon for window (single image, RGBA 32bit, only PLATFORM_DESKTOP)
|
||||
RLAPI void SetWindowIcons(Image *images, int count); // Set icon for window (multiple images, RGBA 32bit, only PLATFORM_DESKTOP)
|
||||
RLAPI void SetWindowTitle(const char *title); // Set title for window (only PLATFORM_DESKTOP and PLATFORM_WEB)
|
||||
RLAPI void SetWindowPosition(int x, int y); // Set window position on screen (only PLATFORM_DESKTOP)
|
||||
RLAPI void ToggleFullscreen(void); // Toggle window state: fullscreen/windowed, resizes monitor to match window resolution
|
||||
RLAPI void ToggleBorderlessWindowed(void); // Toggle window state: borderless windowed, resizes window to match monitor resolution
|
||||
RLAPI void MaximizeWindow(void); // Set window state: maximized, if resizable
|
||||
RLAPI void MinimizeWindow(void); // Set window state: minimized, if resizable
|
||||
RLAPI void RestoreWindow(void); // Restore window from being minimized/maximized
|
||||
RLAPI void SetWindowIcon(Image image); // Set icon for window (single image, RGBA 32bit)
|
||||
RLAPI void SetWindowIcons(Image *images, int count); // Set icon for window (multiple images, RGBA 32bit)
|
||||
RLAPI void SetWindowTitle(const char *title); // Set title for window
|
||||
RLAPI void SetWindowPosition(int x, int y); // Set window position on screen
|
||||
RLAPI void SetWindowMonitor(int monitor); // Set monitor for the current window
|
||||
RLAPI void SetWindowMinSize(int width, int height); // Set window minimum dimensions (for FLAG_WINDOW_RESIZABLE)
|
||||
RLAPI void SetWindowMaxSize(int width, int height); // Set window maximum dimensions (for FLAG_WINDOW_RESIZABLE)
|
||||
RLAPI void SetWindowSize(int width, int height); // Set window dimensions
|
||||
RLAPI void SetWindowOpacity(float opacity); // Set window opacity [0.0f..1.0f] (only PLATFORM_DESKTOP)
|
||||
RLAPI void SetWindowFocused(void); // Set window focused (only PLATFORM_DESKTOP)
|
||||
RLAPI void SetWindowOpacity(float opacity); // Set window opacity [0.0f..1.0f]
|
||||
RLAPI void SetWindowFocused(void); // Set window focused
|
||||
RLAPI void *GetWindowHandle(void); // Get native window handle
|
||||
RLAPI int GetScreenWidth(void); // Get current screen width
|
||||
RLAPI int GetScreenHeight(void); // Get current screen height
|
||||
RLAPI int GetRenderWidth(void); // Get current render width (it considers HiDPI)
|
||||
RLAPI int GetRenderHeight(void); // Get current render height (it considers HiDPI)
|
||||
RLAPI int GetMonitorCount(void); // Get number of connected monitors
|
||||
RLAPI int GetCurrentMonitor(void); // Get current connected monitor
|
||||
RLAPI int GetCurrentMonitor(void); // Get current monitor where window is placed
|
||||
RLAPI Vector2 GetMonitorPosition(int monitor); // Get specified monitor position
|
||||
RLAPI int GetMonitorWidth(int monitor); // Get specified monitor width (current video mode used by monitor)
|
||||
RLAPI int GetMonitorHeight(int monitor); // Get specified monitor height (current video mode used by monitor)
|
||||
@@ -1006,6 +1016,7 @@ RLAPI Vector2 GetWindowScaleDPI(void); // Get window
|
||||
RLAPI const char *GetMonitorName(int monitor); // Get the human-readable, UTF-8 encoded name of the specified monitor
|
||||
RLAPI void SetClipboardText(const char *text); // Set clipboard text content
|
||||
RLAPI const char *GetClipboardText(void); // Get clipboard text content
|
||||
RLAPI Image GetClipboardImage(void); // Get clipboard image content
|
||||
RLAPI void EnableEventWaiting(void); // Enable waiting for events on EndDrawing(), no automatic event polling
|
||||
RLAPI void DisableEventWaiting(void); // Disable waiting for events on EndDrawing(), automatic events polling
|
||||
|
||||
@@ -1044,13 +1055,13 @@ RLAPI void UnloadVrStereoConfig(VrStereoConfig config); // Unload VR s
|
||||
// NOTE: Shader functionality is not available on OpenGL 1.1
|
||||
RLAPI Shader LoadShader(const char *vsFileName, const char *fsFileName); // Load shader from files and bind default locations
|
||||
RLAPI Shader LoadShaderFromMemory(const char *vsCode, const char *fsCode); // Load shader from code strings and bind default locations
|
||||
RLAPI bool IsShaderReady(Shader shader); // Check if a shader is ready
|
||||
RLAPI bool IsShaderValid(Shader shader); // Check if a shader is valid (loaded on GPU)
|
||||
RLAPI int GetShaderLocation(Shader shader, const char *uniformName); // Get shader uniform location
|
||||
RLAPI int GetShaderLocationAttrib(Shader shader, const char *attribName); // Get shader attribute location
|
||||
RLAPI void SetShaderValue(Shader shader, int locIndex, const void *value, int uniformType); // Set shader uniform value
|
||||
RLAPI void SetShaderValueV(Shader shader, int locIndex, const void *value, int uniformType, int count); // Set shader uniform value vector
|
||||
RLAPI void SetShaderValueMatrix(Shader shader, int locIndex, Matrix mat); // Set shader uniform value (matrix 4x4)
|
||||
RLAPI void SetShaderValueTexture(Shader shader, int locIndex, Texture2D texture); // Set shader uniform value for texture (sampler2d)
|
||||
RLAPI void SetShaderValueTexture(Shader shader, int locIndex, Texture2D texture); // Set shader uniform value and bind the texture (sampler2d)
|
||||
RLAPI void UnloadShader(Shader shader); // Unload shader from GPU memory (VRAM)
|
||||
|
||||
// Screen-space-related functions
|
||||
@@ -1112,7 +1123,7 @@ RLAPI bool SaveFileData(const char *fileName, void *data, int dataSize); // Save
|
||||
RLAPI bool ExportDataAsCode(const unsigned char *data, int dataSize, const char *fileName); // Export data to code (.h), returns true on success
|
||||
RLAPI char *LoadFileText(const char *fileName); // Load text data from file (read), returns a '\0' terminated string
|
||||
RLAPI void UnloadFileText(char *text); // Unload file text data allocated by LoadFileText()
|
||||
RLAPI bool SaveFileText(const char *fileName, char *text); // Save text data to file (write), string must be '\0' terminated, returns true on success
|
||||
RLAPI bool SaveFileText(const char *fileName, const char *text); // Save text data to file (write), string must be '\0' terminated, returns true on success
|
||||
//------------------------------------------------------------------
|
||||
|
||||
// File system functions
|
||||
@@ -1142,18 +1153,21 @@ RLAPI long GetFileModTime(const char *fileName); // Get file mo
|
||||
// Compression/Encoding functionality
|
||||
RLAPI unsigned char *CompressData(const unsigned char *data, int dataSize, int *compDataSize); // Compress data (DEFLATE algorithm), memory must be MemFree()
|
||||
RLAPI unsigned char *DecompressData(const unsigned char *compData, int compDataSize, int *dataSize); // Decompress data (DEFLATE algorithm), memory must be MemFree()
|
||||
RLAPI char *EncodeDataBase64(const unsigned char *data, int dataSize, int *outputSize); // Encode data to Base64 string, memory must be MemFree()
|
||||
RLAPI unsigned char *DecodeDataBase64(const unsigned char *data, int *outputSize); // Decode Base64 string data, memory must be MemFree()
|
||||
RLAPI char *EncodeDataBase64(const unsigned char *data, int dataSize, int *outputSize); // Encode data to Base64 string (includes NULL terminator), memory must be MemFree()
|
||||
RLAPI unsigned char *DecodeDataBase64(const char *text, int *outputSize); // Decode Base64 string (expected NULL terminated), memory must be MemFree()
|
||||
RLAPI unsigned int ComputeCRC32(unsigned char *data, int dataSize); // Compute CRC32 hash code
|
||||
RLAPI unsigned int *ComputeMD5(unsigned char *data, int dataSize); // Compute MD5 hash code, returns static int[4] (16 bytes)
|
||||
RLAPI unsigned int *ComputeSHA1(unsigned char *data, int dataSize); // Compute SHA1 hash code, returns static int[5] (20 bytes)
|
||||
|
||||
// Automation events functionality
|
||||
RLAPI AutomationEventList LoadAutomationEventList(const char *fileName); // Load automation events list from file, NULL for empty list, capacity = MAX_AUTOMATION_EVENTS
|
||||
RLAPI void UnloadAutomationEventList(AutomationEventList list); // Unload automation events list from file
|
||||
RLAPI bool ExportAutomationEventList(AutomationEventList list, const char *fileName); // Export automation events list as text file
|
||||
RLAPI void SetAutomationEventList(AutomationEventList *list); // Set automation event list to record to
|
||||
RLAPI void SetAutomationEventBaseFrame(int frame); // Set automation event internal base frame to start recording
|
||||
RLAPI void StartAutomationEventRecording(void); // Start recording automation events (AutomationEventList must be set)
|
||||
RLAPI void StopAutomationEventRecording(void); // Stop recording automation events
|
||||
RLAPI void PlayAutomationEvent(AutomationEvent event); // Play a recorded automation event
|
||||
RLAPI AutomationEventList LoadAutomationEventList(const char *fileName); // Load automation events list from file, NULL for empty list, capacity = MAX_AUTOMATION_EVENTS
|
||||
RLAPI void UnloadAutomationEventList(AutomationEventList list); // Unload automation events list from file
|
||||
RLAPI bool ExportAutomationEventList(AutomationEventList list, const char *fileName); // Export automation events list as text file
|
||||
RLAPI void SetAutomationEventList(AutomationEventList *list); // Set automation event list to record to
|
||||
RLAPI void SetAutomationEventBaseFrame(int frame); // Set automation event internal base frame to start recording
|
||||
RLAPI void StartAutomationEventRecording(void); // Start recording automation events (AutomationEventList must be set)
|
||||
RLAPI void StopAutomationEventRecording(void); // Stop recording automation events
|
||||
RLAPI void PlayAutomationEvent(AutomationEvent event); // Play a recorded automation event
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
// Input Handling Functions (Module: core)
|
||||
@@ -1161,26 +1175,27 @@ RLAPI void PlayAutomationEvent(AutomationEvent event);
|
||||
|
||||
// Input-related functions: keyboard
|
||||
RLAPI bool IsKeyPressed(int key); // Check if a key has been pressed once
|
||||
RLAPI bool IsKeyPressedRepeat(int key); // Check if a key has been pressed again (Only PLATFORM_DESKTOP)
|
||||
RLAPI bool IsKeyPressedRepeat(int key); // Check if a key has been pressed again
|
||||
RLAPI bool IsKeyDown(int key); // Check if a key is being pressed
|
||||
RLAPI bool IsKeyReleased(int key); // Check if a key has been released once
|
||||
RLAPI bool IsKeyUp(int key); // Check if a key is NOT being pressed
|
||||
RLAPI int GetKeyPressed(void); // Get key pressed (keycode), call it multiple times for keys queued, returns 0 when the queue is empty
|
||||
RLAPI int GetCharPressed(void); // Get char pressed (unicode), call it multiple times for chars queued, returns 0 when the queue is empty
|
||||
RLAPI const char *GetKeyName(int key); // Get name of a QWERTY key on the current keyboard layout (eg returns string 'q' for KEY_A on an AZERTY keyboard)
|
||||
RLAPI void SetExitKey(int key); // Set a custom key to exit program (default is ESC)
|
||||
|
||||
// Input-related functions: gamepads
|
||||
RLAPI bool IsGamepadAvailable(int gamepad); // Check if a gamepad is available
|
||||
RLAPI const char *GetGamepadName(int gamepad); // Get gamepad internal name id
|
||||
RLAPI bool IsGamepadButtonPressed(int gamepad, int button); // Check if a gamepad button has been pressed once
|
||||
RLAPI bool IsGamepadButtonDown(int gamepad, int button); // Check if a gamepad button is being pressed
|
||||
RLAPI bool IsGamepadButtonReleased(int gamepad, int button); // Check if a gamepad button has been released once
|
||||
RLAPI bool IsGamepadButtonUp(int gamepad, int button); // Check if a gamepad button is NOT being pressed
|
||||
RLAPI int GetGamepadButtonPressed(void); // Get the last gamepad button pressed
|
||||
RLAPI int GetGamepadAxisCount(int gamepad); // Get gamepad axis count for a gamepad
|
||||
RLAPI float GetGamepadAxisMovement(int gamepad, int axis); // Get axis movement value for a gamepad axis
|
||||
RLAPI int SetGamepadMappings(const char *mappings); // Set internal gamepad mappings (SDL_GameControllerDB)
|
||||
RLAPI void SetGamepadVibration(int gamepad, float leftMotor, float rightMotor); // Set gamepad vibration for both motors
|
||||
RLAPI bool IsGamepadAvailable(int gamepad); // Check if a gamepad is available
|
||||
RLAPI const char *GetGamepadName(int gamepad); // Get gamepad internal name id
|
||||
RLAPI bool IsGamepadButtonPressed(int gamepad, int button); // Check if a gamepad button has been pressed once
|
||||
RLAPI bool IsGamepadButtonDown(int gamepad, int button); // Check if a gamepad button is being pressed
|
||||
RLAPI bool IsGamepadButtonReleased(int gamepad, int button); // Check if a gamepad button has been released once
|
||||
RLAPI bool IsGamepadButtonUp(int gamepad, int button); // Check if a gamepad button is NOT being pressed
|
||||
RLAPI int GetGamepadButtonPressed(void); // Get the last gamepad button pressed
|
||||
RLAPI int GetGamepadAxisCount(int gamepad); // Get axis count for a gamepad
|
||||
RLAPI float GetGamepadAxisMovement(int gamepad, int axis); // Get movement value for a gamepad axis
|
||||
RLAPI int SetGamepadMappings(const char *mappings); // Set internal gamepad mappings (SDL_GameControllerDB)
|
||||
RLAPI void SetGamepadVibration(int gamepad, float leftMotor, float rightMotor, float duration); // Set gamepad vibration for both motors (duration in seconds)
|
||||
|
||||
// Input-related functions: mouse
|
||||
RLAPI bool IsMouseButtonPressed(int button); // Check if a mouse button has been pressed once
|
||||
@@ -1208,19 +1223,19 @@ RLAPI int GetTouchPointCount(void); // Get number of t
|
||||
//------------------------------------------------------------------------------------
|
||||
// Gestures and Touch Handling Functions (Module: rgestures)
|
||||
//------------------------------------------------------------------------------------
|
||||
RLAPI void SetGesturesEnabled(unsigned int flags); // Enable a set of gestures using flags
|
||||
RLAPI bool IsGestureDetected(unsigned int gesture); // Check if a gesture have been detected
|
||||
RLAPI int GetGestureDetected(void); // Get latest detected gesture
|
||||
RLAPI float GetGestureHoldDuration(void); // Get gesture hold time in milliseconds
|
||||
RLAPI Vector2 GetGestureDragVector(void); // Get gesture drag vector
|
||||
RLAPI float GetGestureDragAngle(void); // Get gesture drag angle
|
||||
RLAPI Vector2 GetGesturePinchVector(void); // Get gesture pinch delta
|
||||
RLAPI float GetGesturePinchAngle(void); // Get gesture pinch angle
|
||||
RLAPI void SetGesturesEnabled(unsigned int flags); // Enable a set of gestures using flags
|
||||
RLAPI bool IsGestureDetected(unsigned int gesture); // Check if a gesture have been detected
|
||||
RLAPI int GetGestureDetected(void); // Get latest detected gesture
|
||||
RLAPI float GetGestureHoldDuration(void); // Get gesture hold time in seconds
|
||||
RLAPI Vector2 GetGestureDragVector(void); // Get gesture drag vector
|
||||
RLAPI float GetGestureDragAngle(void); // Get gesture drag angle
|
||||
RLAPI Vector2 GetGesturePinchVector(void); // Get gesture pinch delta
|
||||
RLAPI float GetGesturePinchAngle(void); // Get gesture pinch angle
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
// Camera System Functions (Module: rcamera)
|
||||
//------------------------------------------------------------------------------------
|
||||
RLAPI void UpdateCamera(Camera *camera, int mode); // Update camera position for selected mode
|
||||
RLAPI void UpdateCamera(Camera *camera, int mode); // Update camera position for selected mode
|
||||
RLAPI void UpdateCameraPro(Camera *camera, Vector3 movement, Vector3 rotation, float zoom); // Update camera movement/rotation
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
@@ -1229,9 +1244,9 @@ RLAPI void UpdateCameraPro(Camera *camera, Vector3 movement, Vector3 rotation, f
|
||||
// Set texture and rectangle to be used on shapes drawing
|
||||
// NOTE: It can be useful when using basic shapes and one single font,
|
||||
// defining a font char white rectangle would allow drawing everything in a single draw call
|
||||
RLAPI void SetShapesTexture(Texture2D texture, Rectangle source); // Set texture and rectangle to be used on shapes drawing
|
||||
RLAPI Texture2D GetShapesTexture(void); // Get texture that is used for shapes drawing
|
||||
RLAPI Rectangle GetShapesTextureRectangle(void); // Get texture source rectangle that is used for shapes drawing
|
||||
RLAPI void SetShapesTexture(Texture2D texture, Rectangle source); // Set texture and rectangle to be used on shapes drawing
|
||||
RLAPI Texture2D GetShapesTexture(void); // Get texture that is used for shapes drawing
|
||||
RLAPI Rectangle GetShapesTextureRectangle(void); // Get texture source rectangle that is used for shapes drawing
|
||||
|
||||
// Basic shapes drawing functions
|
||||
RLAPI void DrawPixel(int posX, int posY, Color color); // Draw a pixel using geometry [Can be slow, use with care]
|
||||
@@ -1249,7 +1264,9 @@ RLAPI void DrawCircleV(Vector2 center, float radius, Color color);
|
||||
RLAPI void DrawCircleLines(int centerX, int centerY, float radius, Color color); // Draw circle outline
|
||||
RLAPI void DrawCircleLinesV(Vector2 center, float radius, Color color); // Draw circle outline (Vector version)
|
||||
RLAPI void DrawEllipse(int centerX, int centerY, float radiusH, float radiusV, Color color); // Draw ellipse
|
||||
RLAPI void DrawEllipseV(Vector2 center, float radiusH, float radiusV, Color color); // Draw ellipse (Vector version)
|
||||
RLAPI void DrawEllipseLines(int centerX, int centerY, float radiusH, float radiusV, Color color); // Draw ellipse outline
|
||||
RLAPI void DrawEllipseLinesV(Vector2 center, float radiusH, float radiusV, Color color); // Draw ellipse outline (Vector version)
|
||||
RLAPI void DrawRing(Vector2 center, float innerRadius, float outerRadius, float startAngle, float endAngle, int segments, Color color); // Draw ring
|
||||
RLAPI void DrawRingLines(Vector2 center, float innerRadius, float outerRadius, float startAngle, float endAngle, int segments, Color color); // Draw ring outline
|
||||
RLAPI void DrawRectangle(int posX, int posY, int width, int height, Color color); // Draw a color-filled rectangle
|
||||
@@ -1258,7 +1275,7 @@ RLAPI void DrawRectangleRec(Rectangle rec, Color color);
|
||||
RLAPI void DrawRectanglePro(Rectangle rec, Vector2 origin, float rotation, Color color); // Draw a color-filled rectangle with pro parameters
|
||||
RLAPI void DrawRectangleGradientV(int posX, int posY, int width, int height, Color top, Color bottom); // Draw a vertical-gradient-filled rectangle
|
||||
RLAPI void DrawRectangleGradientH(int posX, int posY, int width, int height, Color left, Color right); // Draw a horizontal-gradient-filled rectangle
|
||||
RLAPI void DrawRectangleGradientEx(Rectangle rec, Color topLeft, Color bottomLeft, Color topRight, Color bottomRight); // Draw a gradient-filled rectangle with custom vertex colors
|
||||
RLAPI void DrawRectangleGradientEx(Rectangle rec, Color topLeft, Color bottomLeft, Color bottomRight, Color topRight); // Draw a gradient-filled rectangle with custom vertex colors
|
||||
RLAPI void DrawRectangleLines(int posX, int posY, int width, int height, Color color); // Draw rectangle outline
|
||||
RLAPI void DrawRectangleLinesEx(Rectangle rec, float lineThick, Color color); // Draw rectangle outline with extended parameters
|
||||
RLAPI void DrawRectangleRounded(Rectangle rec, float roundness, int segments, Color color); // Draw rectangle with rounded edges
|
||||
@@ -1273,11 +1290,11 @@ RLAPI void DrawPolyLines(Vector2 center, int sides, float radius, float rotation
|
||||
RLAPI void DrawPolyLinesEx(Vector2 center, int sides, float radius, float rotation, float lineThick, Color color); // Draw a polygon outline of n sides with extended parameters
|
||||
|
||||
// Splines drawing functions
|
||||
RLAPI void DrawSplineLinear(const Vector2 *points, int pointCount, float thick, Color color); // Draw spline: Linear, minimum 2 points
|
||||
RLAPI void DrawSplineBasis(const Vector2 *points, int pointCount, float thick, Color color); // Draw spline: B-Spline, minimum 4 points
|
||||
RLAPI void DrawSplineCatmullRom(const Vector2 *points, int pointCount, float thick, Color color); // Draw spline: Catmull-Rom, minimum 4 points
|
||||
RLAPI void DrawSplineBezierQuadratic(const Vector2 *points, int pointCount, float thick, Color color); // Draw spline: Quadratic Bezier, minimum 3 points (1 control point): [p1, c2, p3, c4...]
|
||||
RLAPI void DrawSplineBezierCubic(const Vector2 *points, int pointCount, float thick, Color color); // Draw spline: Cubic Bezier, minimum 4 points (2 control points): [p1, c2, c3, p4, c5, c6...]
|
||||
RLAPI void DrawSplineLinear(const Vector2 *points, int pointCount, float thick, Color color); // Draw spline: Linear, minimum 2 points
|
||||
RLAPI void DrawSplineBasis(const Vector2 *points, int pointCount, float thick, Color color); // Draw spline: B-Spline, minimum 4 points
|
||||
RLAPI void DrawSplineCatmullRom(const Vector2 *points, int pointCount, float thick, Color color); // Draw spline: Catmull-Rom, minimum 4 points
|
||||
RLAPI void DrawSplineBezierQuadratic(const Vector2 *points, int pointCount, float thick, Color color); // Draw spline: Quadratic Bezier, minimum 3 points (1 control point): [p1, c2, p3, c4...]
|
||||
RLAPI void DrawSplineBezierCubic(const Vector2 *points, int pointCount, float thick, Color color); // Draw spline: Cubic Bezier, minimum 4 points (2 control points): [p1, c2, c3, p4, c5, c6...]
|
||||
RLAPI void DrawSplineSegmentLinear(Vector2 p1, Vector2 p2, float thick, Color color); // Draw spline segment: Linear, 2 points
|
||||
RLAPI void DrawSplineSegmentBasis(Vector2 p1, Vector2 p2, Vector2 p3, Vector2 p4, float thick, Color color); // Draw spline segment: B-Spline, 4 points
|
||||
RLAPI void DrawSplineSegmentCatmullRom(Vector2 p1, Vector2 p2, Vector2 p3, Vector2 p4, float thick, Color color); // Draw spline segment: Catmull-Rom, 4 points
|
||||
@@ -1295,13 +1312,13 @@ RLAPI Vector2 GetSplinePointBezierCubic(Vector2 p1, Vector2 c2, Vector2 c3, Vect
|
||||
RLAPI bool CheckCollisionRecs(Rectangle rec1, Rectangle rec2); // Check collision between two rectangles
|
||||
RLAPI bool CheckCollisionCircles(Vector2 center1, float radius1, Vector2 center2, float radius2); // Check collision between two circles
|
||||
RLAPI bool CheckCollisionCircleRec(Vector2 center, float radius, Rectangle rec); // Check collision between circle and rectangle
|
||||
RLAPI bool CheckCollisionCircleLine(Vector2 center, float radius, Vector2 p1, Vector2 p2); // Check if circle collides with a line created betweeen two points [p1] and [p2]
|
||||
RLAPI bool CheckCollisionPointRec(Vector2 point, Rectangle rec); // Check if point is inside rectangle
|
||||
RLAPI bool CheckCollisionPointCircle(Vector2 point, Vector2 center, float radius); // Check if point is inside circle
|
||||
RLAPI bool CheckCollisionPointTriangle(Vector2 point, Vector2 p1, Vector2 p2, Vector2 p3); // Check if point is inside a triangle
|
||||
RLAPI bool CheckCollisionPointLine(Vector2 point, Vector2 p1, Vector2 p2, int threshold); // Check if point belongs to line created between two points [p1] and [p2] with defined margin in pixels [threshold]
|
||||
RLAPI bool CheckCollisionPointPoly(Vector2 point, const Vector2 *points, int pointCount); // Check if point is within a polygon described by array of vertices
|
||||
RLAPI bool CheckCollisionLines(Vector2 startPos1, Vector2 endPos1, Vector2 startPos2, Vector2 endPos2, Vector2 *collisionPoint); // Check the collision between two lines defined by two points each, returns collision point by reference
|
||||
RLAPI bool CheckCollisionPointLine(Vector2 point, Vector2 p1, Vector2 p2, int threshold); // Check if point belongs to line created between two points [p1] and [p2] with defined margin in pixels [threshold]
|
||||
RLAPI bool CheckCollisionCircleLine(Vector2 center, float radius, Vector2 p1, Vector2 p2); // Check if circle collides with a line created betweeen two points [p1] and [p2]
|
||||
RLAPI Rectangle GetCollisionRec(Rectangle rec1, Rectangle rec2); // Get collision rectangle for two rectangles collision
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
@@ -1317,7 +1334,7 @@ RLAPI Image LoadImageAnimFromMemory(const char *fileType, const unsigned char *f
|
||||
RLAPI Image LoadImageFromMemory(const char *fileType, const unsigned char *fileData, int dataSize); // Load image from memory buffer, fileType refers to extension: i.e. '.png'
|
||||
RLAPI Image LoadImageFromTexture(Texture2D texture); // Load image from GPU texture data
|
||||
RLAPI Image LoadImageFromScreen(void); // Load image from screen buffer and (screenshot)
|
||||
RLAPI bool IsImageReady(Image image); // Check if an image is ready
|
||||
RLAPI bool IsImageValid(Image image); // Check if an image is valid (data and parameters)
|
||||
RLAPI void UnloadImage(Image image); // Unload image from CPU memory (RAM)
|
||||
RLAPI bool ExportImage(Image image, const char *fileName); // Export image data to file, returns true on success
|
||||
RLAPI unsigned char *ExportImageToMemory(Image image, const char *fileType, int *fileSize); // Export image to memory buffer
|
||||
@@ -1350,7 +1367,7 @@ RLAPI void ImageAlphaPremultiply(Image *image);
|
||||
RLAPI void ImageBlurGaussian(Image *image, int blurSize); // Apply Gaussian blur using a box blur approximation
|
||||
RLAPI void ImageKernelConvolution(Image *image, const float *kernel, int kernelSize); // Apply custom square convolution kernel to image
|
||||
RLAPI void ImageResize(Image *image, int newWidth, int newHeight); // Resize image (Bicubic scaling algorithm)
|
||||
RLAPI void ImageResizeNN(Image *image, int newWidth,int newHeight); // Resize image (Nearest-Neighbor scaling algorithm)
|
||||
RLAPI void ImageResizeNN(Image *image, int newWidth, int newHeight); // Resize image (Nearest-Neighbor scaling algorithm)
|
||||
RLAPI void ImageResizeCanvas(Image *image, int newWidth, int newHeight, int offsetX, int offsetY, Color fill); // Resize canvas and fill with color
|
||||
RLAPI void ImageMipmaps(Image *image); // Compute all mipmap levels for a provided image
|
||||
RLAPI void ImageDither(Image *image, int rBpp, int gBpp, int bBpp, int aBpp); // Dither image data to 16bpp or lower (Floyd-Steinberg dithering)
|
||||
@@ -1391,8 +1408,8 @@ RLAPI void ImageDrawRectangleLines(Image *dst, Rectangle rec, int thick, Color c
|
||||
RLAPI void ImageDrawTriangle(Image *dst, Vector2 v1, Vector2 v2, Vector2 v3, Color color); // Draw triangle within an image
|
||||
RLAPI void ImageDrawTriangleEx(Image *dst, Vector2 v1, Vector2 v2, Vector2 v3, Color c1, Color c2, Color c3); // Draw triangle with interpolated colors within an image
|
||||
RLAPI void ImageDrawTriangleLines(Image *dst, Vector2 v1, Vector2 v2, Vector2 v3, Color color); // Draw triangle outline within an image
|
||||
RLAPI void ImageDrawTriangleFan(Image *dst, Vector2 *points, int pointCount, Color color); // Draw a triangle fan defined by points within an image (first vertex is the center)
|
||||
RLAPI void ImageDrawTriangleStrip(Image *dst, Vector2 *points, int pointCount, Color color); // Draw a triangle strip defined by points within an image
|
||||
RLAPI void ImageDrawTriangleFan(Image *dst, const Vector2 *points, int pointCount, Color color); // Draw a triangle fan defined by points within an image (first vertex is the center)
|
||||
RLAPI void ImageDrawTriangleStrip(Image *dst, const Vector2 *points, int pointCount, Color color); // Draw a triangle strip defined by points within an image
|
||||
RLAPI void ImageDraw(Image *dst, Image src, Rectangle srcRec, Rectangle dstRec, Color tint); // Draw a source image within a destination image (tint applied to source)
|
||||
RLAPI void ImageDrawText(Image *dst, const char *text, int posX, int posY, int fontSize, Color color); // Draw text (using default font) within an image (destination)
|
||||
RLAPI void ImageDrawTextEx(Image *dst, Font font, const char *text, Vector2 position, float fontSize, float spacing, Color tint); // Draw text (custom sprite font) within an image (destination)
|
||||
@@ -1403,9 +1420,9 @@ RLAPI Texture2D LoadTexture(const char *fileName);
|
||||
RLAPI Texture2D LoadTextureFromImage(Image image); // Load texture from image data
|
||||
RLAPI TextureCubemap LoadTextureCubemap(Image image, int layout); // Load cubemap from image, multiple image cubemap layouts supported
|
||||
RLAPI RenderTexture2D LoadRenderTexture(int width, int height); // Load texture for rendering (framebuffer)
|
||||
RLAPI bool IsTextureReady(Texture2D texture); // Check if a texture is ready
|
||||
RLAPI bool IsTextureValid(Texture2D texture); // Check if a texture is valid (loaded in GPU)
|
||||
RLAPI void UnloadTexture(Texture2D texture); // Unload texture from GPU memory (VRAM)
|
||||
RLAPI bool IsRenderTextureReady(RenderTexture2D target); // Check if a render texture is ready
|
||||
RLAPI bool IsRenderTextureValid(RenderTexture2D target); // Check if a render texture is valid (loaded in GPU)
|
||||
RLAPI void UnloadRenderTexture(RenderTexture2D target); // Unload render texture from GPU memory (VRAM)
|
||||
RLAPI void UpdateTexture(Texture2D texture, const void *pixels); // Update GPU texture with new data
|
||||
RLAPI void UpdateTextureRec(Texture2D texture, Rectangle rec, const void *pixels); // Update GPU texture rectangle with new data
|
||||
@@ -1452,7 +1469,7 @@ RLAPI Font LoadFont(const char *fileName);
|
||||
RLAPI Font LoadFontEx(const char *fileName, int fontSize, int *codepoints, int codepointCount); // Load font from file with extended parameters, use NULL for codepoints and 0 for codepointCount to load the default character set, font size is provided in pixels height
|
||||
RLAPI Font LoadFontFromImage(Image image, Color key, int firstChar); // Load font from Image (XNA style)
|
||||
RLAPI Font LoadFontFromMemory(const char *fileType, const unsigned char *fileData, int dataSize, int fontSize, int *codepoints, int codepointCount); // Load font from memory buffer, fileType refers to extension: i.e. '.ttf'
|
||||
RLAPI bool IsFontReady(Font font); // Check if a font is ready
|
||||
RLAPI bool IsFontValid(Font font); // Check if a font is valid (font data loaded, WARNING: GPU texture not checked)
|
||||
RLAPI GlyphInfo *LoadFontData(const unsigned char *fileData, int dataSize, int fontSize, int *codepoints, int codepointCount, int type); // Load font data for further use
|
||||
RLAPI Image GenImageFontAtlas(const GlyphInfo *glyphs, Rectangle **glyphRecs, int glyphCount, int fontSize, int padding, int packMethod); // Generate image font atlas using chars info
|
||||
RLAPI void UnloadFontData(GlyphInfo *glyphs, int glyphCount); // Unload font chars info data (RAM)
|
||||
@@ -1476,18 +1493,19 @@ RLAPI GlyphInfo GetGlyphInfo(Font font, int codepoint);
|
||||
RLAPI Rectangle GetGlyphAtlasRec(Font font, int codepoint); // Get glyph rectangle in font atlas for a codepoint (unicode character), fallback to '?' if not found
|
||||
|
||||
// Text codepoints management functions (unicode characters)
|
||||
RLAPI char *LoadUTF8(const int *codepoints, int length); // Load UTF-8 text encoded from codepoints array
|
||||
RLAPI void UnloadUTF8(char *text); // Unload UTF-8 text encoded from codepoints array
|
||||
RLAPI int *LoadCodepoints(const char *text, int *count); // Load all codepoints from a UTF-8 text string, codepoints count returned by parameter
|
||||
RLAPI void UnloadCodepoints(int *codepoints); // Unload codepoints data from memory
|
||||
RLAPI int GetCodepointCount(const char *text); // Get total number of codepoints in a UTF-8 encoded string
|
||||
RLAPI int GetCodepoint(const char *text, int *codepointSize); // Get next codepoint in a UTF-8 encoded string, 0x3f('?') is returned on failure
|
||||
RLAPI int GetCodepointNext(const char *text, int *codepointSize); // Get next codepoint in a UTF-8 encoded string, 0x3f('?') is returned on failure
|
||||
RLAPI int GetCodepointPrevious(const char *text, int *codepointSize); // Get previous codepoint in a UTF-8 encoded string, 0x3f('?') is returned on failure
|
||||
RLAPI const char *CodepointToUTF8(int codepoint, int *utf8Size); // Encode one codepoint into UTF-8 byte array (array length returned as parameter)
|
||||
RLAPI char *LoadUTF8(const int *codepoints, int length); // Load UTF-8 text encoded from codepoints array
|
||||
RLAPI void UnloadUTF8(char *text); // Unload UTF-8 text encoded from codepoints array
|
||||
RLAPI int *LoadCodepoints(const char *text, int *count); // Load all codepoints from a UTF-8 text string, codepoints count returned by parameter
|
||||
RLAPI void UnloadCodepoints(int *codepoints); // Unload codepoints data from memory
|
||||
RLAPI int GetCodepointCount(const char *text); // Get total number of codepoints in a UTF-8 encoded string
|
||||
RLAPI int GetCodepoint(const char *text, int *codepointSize); // Get next codepoint in a UTF-8 encoded string, 0x3f('?') is returned on failure
|
||||
RLAPI int GetCodepointNext(const char *text, int *codepointSize); // Get next codepoint in a UTF-8 encoded string, 0x3f('?') is returned on failure
|
||||
RLAPI int GetCodepointPrevious(const char *text, int *codepointSize); // Get previous codepoint in a UTF-8 encoded string, 0x3f('?') is returned on failure
|
||||
RLAPI const char *CodepointToUTF8(int codepoint, int *utf8Size); // Encode one codepoint into UTF-8 byte array (array length returned as parameter)
|
||||
|
||||
// Text strings management functions (no UTF-8 strings, only byte chars)
|
||||
// NOTE: Some strings allocate memory internally for returned strings, just be careful!
|
||||
// WARNING 1: Most of these functions use internal static buffers, it's recommended to store returned data on user-side for re-use
|
||||
// WARNING 2: Some strings allocate memory internally for the returned strings, those strings must be free by user using MemFree()
|
||||
RLAPI int TextCopy(char *dst, const char *src); // Copy one string to another, returns bytes copied
|
||||
RLAPI bool TextIsEqual(const char *text1, const char *text2); // Check if two text string are equal
|
||||
RLAPI unsigned int TextLength(const char *text); // Get text length, checks for '\0' ending
|
||||
@@ -1495,18 +1513,18 @@ RLAPI const char *TextFormat(const char *text, ...);
|
||||
RLAPI const char *TextSubtext(const char *text, int position, int length); // Get a piece of a text string
|
||||
RLAPI char *TextReplace(const char *text, const char *replace, const char *by); // Replace text string (WARNING: memory must be freed!)
|
||||
RLAPI char *TextInsert(const char *text, const char *insert, int position); // Insert text in a position (WARNING: memory must be freed!)
|
||||
RLAPI const char *TextJoin(const char **textList, int count, const char *delimiter); // Join text strings with delimiter
|
||||
RLAPI const char **TextSplit(const char *text, char delimiter, int *count); // Split text into multiple strings
|
||||
RLAPI char *TextJoin(char **textList, int count, const char *delimiter); // Join text strings with delimiter
|
||||
RLAPI char **TextSplit(const char *text, char delimiter, int *count); // Split text into multiple strings
|
||||
RLAPI void TextAppend(char *text, const char *append, int *position); // Append text at specific position and move cursor!
|
||||
RLAPI int TextFindIndex(const char *text, const char *find); // Find first text occurrence within a string
|
||||
RLAPI const char *TextToUpper(const char *text); // Get upper case version of provided string
|
||||
RLAPI const char *TextToLower(const char *text); // Get lower case version of provided string
|
||||
RLAPI const char *TextToPascal(const char *text); // Get Pascal case notation version of provided string
|
||||
RLAPI const char *TextToSnake(const char *text); // Get Snake case notation version of provided string
|
||||
RLAPI const char *TextToCamel(const char *text); // Get Camel case notation version of provided string
|
||||
RLAPI char *TextToUpper(const char *text); // Get upper case version of provided string
|
||||
RLAPI char *TextToLower(const char *text); // Get lower case version of provided string
|
||||
RLAPI char *TextToPascal(const char *text); // Get Pascal case notation version of provided string
|
||||
RLAPI char *TextToSnake(const char *text); // Get Snake case notation version of provided string
|
||||
RLAPI char *TextToCamel(const char *text); // Get Camel case notation version of provided string
|
||||
|
||||
RLAPI int TextToInteger(const char *text); // Get integer value from text (negative values not supported)
|
||||
RLAPI float TextToFloat(const char *text); // Get float value from text (negative values not supported)
|
||||
RLAPI int TextToInteger(const char *text); // Get integer value from text
|
||||
RLAPI float TextToFloat(const char *text); // Get float value from text
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
// Basic 3d Shapes Drawing Functions (Module: models)
|
||||
@@ -1542,7 +1560,7 @@ RLAPI void DrawGrid(int slices, float spacing);
|
||||
// Model management functions
|
||||
RLAPI Model LoadModel(const char *fileName); // Load model from files (meshes and materials)
|
||||
RLAPI Model LoadModelFromMesh(Mesh mesh); // Load model from generated mesh (default material)
|
||||
RLAPI bool IsModelReady(Model model); // Check if a model is ready
|
||||
RLAPI bool IsModelValid(Model model); // Check if a model is valid (loaded in GPU, VAO/VBOs)
|
||||
RLAPI void UnloadModel(Model model); // Unload model (including meshes) from memory (RAM and/or VRAM)
|
||||
RLAPI BoundingBox GetModelBoundingBox(Model model); // Compute model bounding box limits (considers all meshes)
|
||||
|
||||
@@ -1585,28 +1603,28 @@ RLAPI Mesh GenMeshCubicmap(Image cubicmap, Vector3 cubeSize);
|
||||
// Material loading/unloading functions
|
||||
RLAPI Material *LoadMaterials(const char *fileName, int *materialCount); // Load materials from model file
|
||||
RLAPI Material LoadMaterialDefault(void); // Load default material (Supports: DIFFUSE, SPECULAR, NORMAL maps)
|
||||
RLAPI bool IsMaterialReady(Material material); // Check if a material is ready
|
||||
RLAPI bool IsMaterialValid(Material material); // Check if a material is valid (shader assigned, map textures loaded in GPU)
|
||||
RLAPI void UnloadMaterial(Material material); // Unload material from GPU memory (VRAM)
|
||||
RLAPI void SetMaterialTexture(Material *material, int mapType, Texture2D texture); // Set texture for a material map type (MATERIAL_MAP_DIFFUSE, MATERIAL_MAP_SPECULAR...)
|
||||
RLAPI void SetModelMeshMaterial(Model *model, int meshId, int materialId); // Set material for a mesh
|
||||
|
||||
// Model animations loading/unloading functions
|
||||
RLAPI ModelAnimation *LoadModelAnimations(const char *fileName, int *animCount); // Load model animations from file
|
||||
RLAPI void UpdateModelAnimation(Model model, ModelAnimation anim, int frame); // Update model animation pose
|
||||
RLAPI void UpdateModelAnimation(Model model, ModelAnimation anim, int frame); // Update model animation pose (CPU)
|
||||
RLAPI void UpdateModelAnimationBones(Model model, ModelAnimation anim, int frame); // Update model animation mesh bone matrices (GPU skinning)
|
||||
RLAPI void UnloadModelAnimation(ModelAnimation anim); // Unload animation data
|
||||
RLAPI void UnloadModelAnimations(ModelAnimation *animations, int animCount); // Unload animation array data
|
||||
RLAPI bool IsModelAnimationValid(Model model, ModelAnimation anim); // Check model animation skeleton match
|
||||
RLAPI void UpdateModelAnimationBoneMatrices(Model model, ModelAnimation anim, int frame); // Update model animation mesh bone matrices (Note GPU skinning does not work on Mac)
|
||||
|
||||
// Collision detection functions
|
||||
RLAPI bool CheckCollisionSpheres(Vector3 center1, float radius1, Vector3 center2, float radius2); // Check collision between two spheres
|
||||
RLAPI bool CheckCollisionBoxes(BoundingBox box1, BoundingBox box2); // Check collision between two bounding boxes
|
||||
RLAPI bool CheckCollisionBoxSphere(BoundingBox box, Vector3 center, float radius); // Check collision between box and sphere
|
||||
RLAPI RayCollision GetRayCollisionSphere(Ray ray, Vector3 center, float radius); // Get collision info between ray and sphere
|
||||
RLAPI RayCollision GetRayCollisionBox(Ray ray, BoundingBox box); // Get collision info between ray and box
|
||||
RLAPI RayCollision GetRayCollisionMesh(Ray ray, Mesh mesh, Matrix transform); // Get collision info between ray and mesh
|
||||
RLAPI RayCollision GetRayCollisionTriangle(Ray ray, Vector3 p1, Vector3 p2, Vector3 p3); // Get collision info between ray and triangle
|
||||
RLAPI RayCollision GetRayCollisionQuad(Ray ray, Vector3 p1, Vector3 p2, Vector3 p3, Vector3 p4); // Get collision info between ray and quad
|
||||
RLAPI bool CheckCollisionSpheres(Vector3 center1, float radius1, Vector3 center2, float radius2); // Check collision between two spheres
|
||||
RLAPI bool CheckCollisionBoxes(BoundingBox box1, BoundingBox box2); // Check collision between two bounding boxes
|
||||
RLAPI bool CheckCollisionBoxSphere(BoundingBox box, Vector3 center, float radius); // Check collision between box and sphere
|
||||
RLAPI RayCollision GetRayCollisionSphere(Ray ray, Vector3 center, float radius); // Get collision info between ray and sphere
|
||||
RLAPI RayCollision GetRayCollisionBox(Ray ray, BoundingBox box); // Get collision info between ray and box
|
||||
RLAPI RayCollision GetRayCollisionMesh(Ray ray, Mesh mesh, Matrix transform); // Get collision info between ray and mesh
|
||||
RLAPI RayCollision GetRayCollisionTriangle(Ray ray, Vector3 p1, Vector3 p2, Vector3 p3); // Get collision info between ray and triangle
|
||||
RLAPI RayCollision GetRayCollisionQuad(Ray ray, Vector3 p1, Vector3 p2, Vector3 p3, Vector3 p4); // Get collision info between ray and quad
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
// Audio Loading and Playing Functions (Module: audio)
|
||||
@@ -1623,11 +1641,11 @@ RLAPI float GetMasterVolume(void); // Get mas
|
||||
// Wave/Sound loading/unloading functions
|
||||
RLAPI Wave LoadWave(const char *fileName); // Load wave data from file
|
||||
RLAPI Wave LoadWaveFromMemory(const char *fileType, const unsigned char *fileData, int dataSize); // Load wave from memory buffer, fileType refers to extension: i.e. '.wav'
|
||||
RLAPI bool IsWaveReady(Wave wave); // Checks if wave data is ready
|
||||
RLAPI bool IsWaveValid(Wave wave); // Checks if wave data is valid (data loaded and parameters)
|
||||
RLAPI Sound LoadSound(const char *fileName); // Load sound from file
|
||||
RLAPI Sound LoadSoundFromWave(Wave wave); // Load sound from wave data
|
||||
RLAPI Sound LoadSoundAlias(Sound source); // Create a new sound that shares the same sample data as the source sound, does not own the sound data
|
||||
RLAPI bool IsSoundReady(Sound sound); // Checks if a sound is ready
|
||||
RLAPI bool IsSoundValid(Sound sound); // Checks if a sound is valid (data loaded and buffers initialized)
|
||||
RLAPI void UpdateSound(Sound sound, const void *data, int sampleCount); // Update sound buffer with new data
|
||||
RLAPI void UnloadWave(Wave wave); // Unload wave data
|
||||
RLAPI void UnloadSound(Sound sound); // Unload sound
|
||||
@@ -1653,7 +1671,7 @@ RLAPI void UnloadWaveSamples(float *samples); // Unload
|
||||
// Music management functions
|
||||
RLAPI Music LoadMusicStream(const char *fileName); // Load music stream from file
|
||||
RLAPI Music LoadMusicStreamFromMemory(const char *fileType, const unsigned char *data, int dataSize); // Load music stream from data
|
||||
RLAPI bool IsMusicReady(Music music); // Checks if a music stream is ready
|
||||
RLAPI bool IsMusicValid(Music music); // Checks if a music stream is valid (context and buffers initialized)
|
||||
RLAPI void UnloadMusicStream(Music music); // Unload music stream
|
||||
RLAPI void PlayMusicStream(Music music); // Start music playing
|
||||
RLAPI bool IsMusicStreamPlaying(Music music); // Check if music is playing
|
||||
@@ -1670,7 +1688,7 @@ RLAPI float GetMusicTimePlayed(Music music); // Get cur
|
||||
|
||||
// AudioStream management functions
|
||||
RLAPI AudioStream LoadAudioStream(unsigned int sampleRate, unsigned int sampleSize, unsigned int channels); // Load audio stream (to stream raw audio pcm data)
|
||||
RLAPI bool IsAudioStreamReady(AudioStream stream); // Checks if an audio stream is ready
|
||||
RLAPI bool IsAudioStreamValid(AudioStream stream); // Checks if an audio stream is valid (buffers initialized)
|
||||
RLAPI void UnloadAudioStream(AudioStream stream); // Unload audio stream and free memory
|
||||
RLAPI void UpdateAudioStream(AudioStream stream, const void *data, int frameCount); // Update audio stream buffers with data
|
||||
RLAPI bool IsAudioStreamProcessed(AudioStream stream); // Check if any audio stream buffers requires refill
|
||||
@@ -1685,10 +1703,10 @@ RLAPI void SetAudioStreamPan(AudioStream stream, float pan); // Set pan
|
||||
RLAPI void SetAudioStreamBufferSizeDefault(int size); // Default size for new audio streams
|
||||
RLAPI void SetAudioStreamCallback(AudioStream stream, AudioCallback callback); // Audio thread callback to request new data
|
||||
|
||||
RLAPI void AttachAudioStreamProcessor(AudioStream stream, AudioCallback processor); // Attach audio stream processor to stream, receives the samples as 'float'
|
||||
RLAPI void AttachAudioStreamProcessor(AudioStream stream, AudioCallback processor); // Attach audio stream processor to stream, receives frames x 2 samples as 'float' (stereo)
|
||||
RLAPI void DetachAudioStreamProcessor(AudioStream stream, AudioCallback processor); // Detach audio stream processor from stream
|
||||
|
||||
RLAPI void AttachAudioMixedProcessor(AudioCallback processor); // Attach audio stream processor to the entire audio pipeline, receives the samples as 'float'
|
||||
RLAPI void AttachAudioMixedProcessor(AudioCallback processor); // Attach audio stream processor to the entire audio pipeline, receives frames x 2 samples as 'float' (stereo)
|
||||
RLAPI void DetachAudioMixedProcessor(AudioCallback processor); // Detach audio stream processor from the entire audio pipeline
|
||||
|
||||
#if defined(__cplusplus)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/**********************************************************************************************
|
||||
*
|
||||
* raymath v1.5 - Math functions to work with Vector2, Vector3, Matrix and Quaternions
|
||||
* raymath v2.0 - Math functions to work with Vector2, Vector3, Matrix and Quaternions
|
||||
*
|
||||
* CONVENTIONS:
|
||||
* - Matrix structure is defined as row-major (memory layout) but parameters naming AND all
|
||||
@@ -12,7 +12,7 @@
|
||||
* - Functions are always self-contained, no function use another raymath function inside,
|
||||
* required code is directly re-implemented inside
|
||||
* - Functions input parameters are always received by value (2 unavoidable exceptions)
|
||||
* - Functions use always a "result" variable for return
|
||||
* - Functions use always a "result" variable for return (except C++ operators)
|
||||
* - Functions are always defined inline
|
||||
* - Angles are always in radians (DEG2RAD/RAD2DEG macros provided for convenience)
|
||||
* - No compound literals used to make sure libray is compatible with C++
|
||||
@@ -27,10 +27,12 @@
|
||||
* Define static inline functions code, so #include header suffices for use.
|
||||
* This may use up lots of memory.
|
||||
*
|
||||
* #define RAYMATH_DISABLE_CPP_OPERATORS
|
||||
* Disables C++ operator overloads for raymath types.
|
||||
*
|
||||
* LICENSE: zlib/libpng
|
||||
*
|
||||
* Copyright (c) 2015-2024 Ramon Santamaria (@raysan5)
|
||||
* Copyright (c) 2015-2025 Ramon Santamaria (@raysan5)
|
||||
*
|
||||
* This software is provided "as-is", without any express or implied warranty. In no event
|
||||
* will the authors be held liable for any damages arising from the use of this software.
|
||||
@@ -302,6 +304,14 @@ RMAPI float Vector2DotProduct(Vector2 v1, Vector2 v2)
|
||||
return result;
|
||||
}
|
||||
|
||||
// Calculate two vectors cross product
|
||||
RMAPI float Vector2CrossProduct(Vector2 v1, Vector2 v2)
|
||||
{
|
||||
float result = (v1.x*v2.y - v1.y*v2.x);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// Calculate distance between two vectors
|
||||
RMAPI float Vector2Distance(Vector2 v1, Vector2 v2)
|
||||
{
|
||||
@@ -318,8 +328,9 @@ RMAPI float Vector2DistanceSqr(Vector2 v1, Vector2 v2)
|
||||
return result;
|
||||
}
|
||||
|
||||
// Calculate angle between two vectors
|
||||
// NOTE: Angle is calculated from origin point (0, 0)
|
||||
// Calculate the signed angle from v1 to v2, relative to the origin (0, 0)
|
||||
// NOTE: Coordinate system convention: positive X right, positive Y down,
|
||||
// positive angles appear clockwise, and negative angles appear counterclockwise
|
||||
RMAPI float Vector2Angle(Vector2 v1, Vector2 v2)
|
||||
{
|
||||
float result = 0.0f;
|
||||
@@ -1457,19 +1468,35 @@ RMAPI int Vector4Equals(Vector4 p, Vector4 q)
|
||||
RMAPI float MatrixDeterminant(Matrix mat)
|
||||
{
|
||||
float result = 0.0f;
|
||||
|
||||
/*
|
||||
// Cache the matrix values (speed optimization)
|
||||
float a00 = mat.m0, a01 = mat.m1, a02 = mat.m2, a03 = mat.m3;
|
||||
float a10 = mat.m4, a11 = mat.m5, a12 = mat.m6, a13 = mat.m7;
|
||||
float a20 = mat.m8, a21 = mat.m9, a22 = mat.m10, a23 = mat.m11;
|
||||
float a30 = mat.m12, a31 = mat.m13, a32 = mat.m14, a33 = mat.m15;
|
||||
|
||||
// NOTE: It takes 72 multiplication to calculate 4x4 matrix determinant
|
||||
result = a30*a21*a12*a03 - a20*a31*a12*a03 - a30*a11*a22*a03 + a10*a31*a22*a03 +
|
||||
a20*a11*a32*a03 - a10*a21*a32*a03 - a30*a21*a02*a13 + a20*a31*a02*a13 +
|
||||
a30*a01*a22*a13 - a00*a31*a22*a13 - a20*a01*a32*a13 + a00*a21*a32*a13 +
|
||||
a30*a11*a02*a23 - a10*a31*a02*a23 - a30*a01*a12*a23 + a00*a31*a12*a23 +
|
||||
a10*a01*a32*a23 - a00*a11*a32*a23 - a20*a11*a02*a33 + a10*a21*a02*a33 +
|
||||
a20*a01*a12*a33 - a00*a21*a12*a33 - a10*a01*a22*a33 + a00*a11*a22*a33;
|
||||
*/
|
||||
// Using Laplace expansion (https://en.wikipedia.org/wiki/Laplace_expansion),
|
||||
// previous operation can be simplified to 40 multiplications, decreasing matrix
|
||||
// size from 4x4 to 2x2 using minors
|
||||
|
||||
// Cache the matrix values (speed optimization)
|
||||
float m0 = mat.m0, m1 = mat.m1, m2 = mat.m2, m3 = mat.m3;
|
||||
float m4 = mat.m4, m5 = mat.m5, m6 = mat.m6, m7 = mat.m7;
|
||||
float m8 = mat.m8, m9 = mat.m9, m10 = mat.m10, m11 = mat.m11;
|
||||
float m12 = mat.m12, m13 = mat.m13, m14 = mat.m14, m15 = mat.m15;
|
||||
|
||||
result = (m0*((m5*(m10*m15 - m11*m14) - m9*(m6*m15 - m7*m14) + m13*(m6*m11 - m7*m10))) -
|
||||
m4*((m1*(m10*m15 - m11*m14) - m9*(m2*m15 - m3*m14) + m13*(m2*m11 - m3*m10))) +
|
||||
m8*((m1*(m6*m15 - m7*m14) - m5*(m2*m15 - m3*m14) + m13*(m2*m7 - m3*m6))) -
|
||||
m12*((m1*(m6*m11 - m7*m10) - m5*(m2*m11 - m3*m10) + m9*(m2*m7 - m3*m6))));
|
||||
|
||||
return result;
|
||||
}
|
||||
@@ -2567,7 +2594,13 @@ RMAPI void MatrixDecompose(Matrix mat, Vector3 *translation, Quaternion *rotatio
|
||||
if (!FloatEquals(det, 0))
|
||||
{
|
||||
clone.m0 /= s.x;
|
||||
clone.m4 /= s.x;
|
||||
clone.m8 /= s.x;
|
||||
clone.m1 /= s.y;
|
||||
clone.m5 /= s.y;
|
||||
clone.m9 /= s.y;
|
||||
clone.m2 /= s.z;
|
||||
clone.m6 /= s.z;
|
||||
clone.m10 /= s.z;
|
||||
|
||||
// Extract rotation
|
||||
@@ -2580,4 +2613,354 @@ RMAPI void MatrixDecompose(Matrix mat, Vector3 *translation, Quaternion *rotatio
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(__cplusplus) && !defined(RAYMATH_DISABLE_CPP_OPERATORS)
|
||||
|
||||
// Optional C++ math operators
|
||||
//-------------------------------------------------------------------------------
|
||||
|
||||
// Vector2 operators
|
||||
static constexpr Vector2 Vector2Zeros = { 0, 0 };
|
||||
static constexpr Vector2 Vector2Ones = { 1, 1 };
|
||||
static constexpr Vector2 Vector2UnitX = { 1, 0 };
|
||||
static constexpr Vector2 Vector2UnitY = { 0, 1 };
|
||||
|
||||
inline Vector2 operator + (const Vector2& lhs, const Vector2& rhs)
|
||||
{
|
||||
return Vector2Add(lhs, rhs);
|
||||
}
|
||||
|
||||
inline const Vector2& operator += (Vector2& lhs, const Vector2& rhs)
|
||||
{
|
||||
lhs = Vector2Add(lhs, rhs);
|
||||
return lhs;
|
||||
}
|
||||
|
||||
inline Vector2 operator - (const Vector2& lhs, const Vector2& rhs)
|
||||
{
|
||||
return Vector2Subtract(lhs, rhs);
|
||||
}
|
||||
|
||||
inline const Vector2& operator -= (Vector2& lhs, const Vector2& rhs)
|
||||
{
|
||||
lhs = Vector2Subtract(lhs, rhs);
|
||||
return lhs;
|
||||
}
|
||||
|
||||
inline Vector2 operator * (const Vector2& lhs, const float& rhs)
|
||||
{
|
||||
return Vector2Scale(lhs, rhs);
|
||||
}
|
||||
|
||||
inline const Vector2& operator *= (Vector2& lhs, const float& rhs)
|
||||
{
|
||||
lhs = Vector2Scale(lhs, rhs);
|
||||
return lhs;
|
||||
}
|
||||
|
||||
inline Vector2 operator * (const Vector2& lhs, const Vector2& rhs)
|
||||
{
|
||||
return Vector2Multiply(lhs, rhs);
|
||||
}
|
||||
|
||||
inline const Vector2& operator *= (Vector2& lhs, const Vector2& rhs)
|
||||
{
|
||||
lhs = Vector2Multiply(lhs, rhs);
|
||||
return lhs;
|
||||
}
|
||||
|
||||
inline Vector2 operator * (const Vector2& lhs, const Matrix& rhs)
|
||||
{
|
||||
return Vector2Transform(lhs, rhs);
|
||||
}
|
||||
|
||||
inline const Vector2& operator *= (Vector2& lhs, const Matrix& rhs)
|
||||
{
|
||||
lhs = Vector2Transform(lhs, rhs);
|
||||
return lhs;
|
||||
}
|
||||
|
||||
inline Vector2 operator / (const Vector2& lhs, const float& rhs)
|
||||
{
|
||||
return Vector2Scale(lhs, 1.0f/rhs);
|
||||
}
|
||||
|
||||
inline const Vector2& operator /= (Vector2& lhs, const float& rhs)
|
||||
{
|
||||
lhs = Vector2Scale(lhs, 1.0f/rhs);
|
||||
return lhs;
|
||||
}
|
||||
|
||||
inline Vector2 operator / (const Vector2& lhs, const Vector2& rhs)
|
||||
{
|
||||
return Vector2Divide(lhs, rhs);
|
||||
}
|
||||
|
||||
inline const Vector2& operator /= (Vector2& lhs, const Vector2& rhs)
|
||||
{
|
||||
lhs = Vector2Divide(lhs, rhs);
|
||||
return lhs;
|
||||
}
|
||||
|
||||
inline bool operator == (const Vector2& lhs, const Vector2& rhs)
|
||||
{
|
||||
return FloatEquals(lhs.x, rhs.x) && FloatEquals(lhs.y, rhs.y);
|
||||
}
|
||||
|
||||
inline bool operator != (const Vector2& lhs, const Vector2& rhs)
|
||||
{
|
||||
return !FloatEquals(lhs.x, rhs.x) || !FloatEquals(lhs.y, rhs.y);
|
||||
}
|
||||
|
||||
// Vector3 operators
|
||||
static constexpr Vector3 Vector3Zeros = { 0, 0, 0 };
|
||||
static constexpr Vector3 Vector3Ones = { 1, 1, 1 };
|
||||
static constexpr Vector3 Vector3UnitX = { 1, 0, 0 };
|
||||
static constexpr Vector3 Vector3UnitY = { 0, 1, 0 };
|
||||
static constexpr Vector3 Vector3UnitZ = { 0, 0, 1 };
|
||||
|
||||
inline Vector3 operator + (const Vector3& lhs, const Vector3& rhs)
|
||||
{
|
||||
return Vector3Add(lhs, rhs);
|
||||
}
|
||||
|
||||
inline const Vector3& operator += (Vector3& lhs, const Vector3& rhs)
|
||||
{
|
||||
lhs = Vector3Add(lhs, rhs);
|
||||
return lhs;
|
||||
}
|
||||
|
||||
inline Vector3 operator - (const Vector3& lhs, const Vector3& rhs)
|
||||
{
|
||||
return Vector3Subtract(lhs, rhs);
|
||||
}
|
||||
|
||||
inline const Vector3& operator -= (Vector3& lhs, const Vector3& rhs)
|
||||
{
|
||||
lhs = Vector3Subtract(lhs, rhs);
|
||||
return lhs;
|
||||
}
|
||||
|
||||
inline Vector3 operator * (const Vector3& lhs, const float& rhs)
|
||||
{
|
||||
return Vector3Scale(lhs, rhs);
|
||||
}
|
||||
|
||||
inline const Vector3& operator *= (Vector3& lhs, const float& rhs)
|
||||
{
|
||||
lhs = Vector3Scale(lhs, rhs);
|
||||
return lhs;
|
||||
}
|
||||
|
||||
inline Vector3 operator * (const Vector3& lhs, const Vector3& rhs)
|
||||
{
|
||||
return Vector3Multiply(lhs, rhs);
|
||||
}
|
||||
|
||||
inline const Vector3& operator *= (Vector3& lhs, const Vector3& rhs)
|
||||
{
|
||||
lhs = Vector3Multiply(lhs, rhs);
|
||||
return lhs;
|
||||
}
|
||||
|
||||
inline Vector3 operator * (const Vector3& lhs, const Matrix& rhs)
|
||||
{
|
||||
return Vector3Transform(lhs, rhs);
|
||||
}
|
||||
|
||||
inline const Vector3& operator *= (Vector3& lhs, const Matrix& rhs)
|
||||
{
|
||||
lhs = Vector3Transform(lhs, rhs);
|
||||
return lhs;
|
||||
}
|
||||
|
||||
inline Vector3 operator / (const Vector3& lhs, const float& rhs)
|
||||
{
|
||||
return Vector3Scale(lhs, 1.0f/rhs);
|
||||
}
|
||||
|
||||
inline const Vector3& operator /= (Vector3& lhs, const float& rhs)
|
||||
{
|
||||
lhs = Vector3Scale(lhs, 1.0f/rhs);
|
||||
return lhs;
|
||||
}
|
||||
|
||||
inline Vector3 operator / (const Vector3& lhs, const Vector3& rhs)
|
||||
{
|
||||
return Vector3Divide(lhs, rhs);
|
||||
}
|
||||
|
||||
inline const Vector3& operator /= (Vector3& lhs, const Vector3& rhs)
|
||||
{
|
||||
lhs = Vector3Divide(lhs, rhs);
|
||||
return lhs;
|
||||
}
|
||||
|
||||
inline bool operator == (const Vector3& lhs, const Vector3& rhs)
|
||||
{
|
||||
return FloatEquals(lhs.x, rhs.x) && FloatEquals(lhs.y, rhs.y) && FloatEquals(lhs.z, rhs.z);
|
||||
}
|
||||
|
||||
inline bool operator != (const Vector3& lhs, const Vector3& rhs)
|
||||
{
|
||||
return !FloatEquals(lhs.x, rhs.x) || !FloatEquals(lhs.y, rhs.y) || !FloatEquals(lhs.z, rhs.z);
|
||||
}
|
||||
|
||||
// Vector4 operators
|
||||
static constexpr Vector4 Vector4Zeros = { 0, 0, 0, 0 };
|
||||
static constexpr Vector4 Vector4Ones = { 1, 1, 1, 1 };
|
||||
static constexpr Vector4 Vector4UnitX = { 1, 0, 0, 0 };
|
||||
static constexpr Vector4 Vector4UnitY = { 0, 1, 0, 0 };
|
||||
static constexpr Vector4 Vector4UnitZ = { 0, 0, 1, 0 };
|
||||
static constexpr Vector4 Vector4UnitW = { 0, 0, 0, 1 };
|
||||
|
||||
inline Vector4 operator + (const Vector4& lhs, const Vector4& rhs)
|
||||
{
|
||||
return Vector4Add(lhs, rhs);
|
||||
}
|
||||
|
||||
inline const Vector4& operator += (Vector4& lhs, const Vector4& rhs)
|
||||
{
|
||||
lhs = Vector4Add(lhs, rhs);
|
||||
return lhs;
|
||||
}
|
||||
|
||||
inline Vector4 operator - (const Vector4& lhs, const Vector4& rhs)
|
||||
{
|
||||
return Vector4Subtract(lhs, rhs);
|
||||
}
|
||||
|
||||
inline const Vector4& operator -= (Vector4& lhs, const Vector4& rhs)
|
||||
{
|
||||
lhs = Vector4Subtract(lhs, rhs);
|
||||
return lhs;
|
||||
}
|
||||
|
||||
inline Vector4 operator * (const Vector4& lhs, const float& rhs)
|
||||
{
|
||||
return Vector4Scale(lhs, rhs);
|
||||
}
|
||||
|
||||
inline const Vector4& operator *= (Vector4& lhs, const float& rhs)
|
||||
{
|
||||
lhs = Vector4Scale(lhs, rhs);
|
||||
return lhs;
|
||||
}
|
||||
|
||||
inline Vector4 operator * (const Vector4& lhs, const Vector4& rhs)
|
||||
{
|
||||
return Vector4Multiply(lhs, rhs);
|
||||
}
|
||||
|
||||
inline const Vector4& operator *= (Vector4& lhs, const Vector4& rhs)
|
||||
{
|
||||
lhs = Vector4Multiply(lhs, rhs);
|
||||
return lhs;
|
||||
}
|
||||
|
||||
inline Vector4 operator / (const Vector4& lhs, const float& rhs)
|
||||
{
|
||||
return Vector4Scale(lhs, 1.0f/rhs);
|
||||
}
|
||||
|
||||
inline const Vector4& operator /= (Vector4& lhs, const float& rhs)
|
||||
{
|
||||
lhs = Vector4Scale(lhs, 1.0f/rhs);
|
||||
return lhs;
|
||||
}
|
||||
|
||||
inline Vector4 operator / (const Vector4& lhs, const Vector4& rhs)
|
||||
{
|
||||
return Vector4Divide(lhs, rhs);
|
||||
}
|
||||
|
||||
inline const Vector4& operator /= (Vector4& lhs, const Vector4& rhs)
|
||||
{
|
||||
lhs = Vector4Divide(lhs, rhs);
|
||||
return lhs;
|
||||
}
|
||||
|
||||
inline bool operator == (const Vector4& lhs, const Vector4& rhs)
|
||||
{
|
||||
return FloatEquals(lhs.x, rhs.x) && FloatEquals(lhs.y, rhs.y) && FloatEquals(lhs.z, rhs.z) && FloatEquals(lhs.w, rhs.w);
|
||||
}
|
||||
|
||||
inline bool operator != (const Vector4& lhs, const Vector4& rhs)
|
||||
{
|
||||
return !FloatEquals(lhs.x, rhs.x) || !FloatEquals(lhs.y, rhs.y) || !FloatEquals(lhs.z, rhs.z) || !FloatEquals(lhs.w, rhs.w);
|
||||
}
|
||||
|
||||
// Quaternion operators
|
||||
static constexpr Quaternion QuaternionZeros = { 0, 0, 0, 0 };
|
||||
static constexpr Quaternion QuaternionOnes = { 1, 1, 1, 1 };
|
||||
static constexpr Quaternion QuaternionUnitX = { 0, 0, 0, 1 };
|
||||
|
||||
inline Quaternion operator + (const Quaternion& lhs, const float& rhs)
|
||||
{
|
||||
return QuaternionAddValue(lhs, rhs);
|
||||
}
|
||||
|
||||
inline const Quaternion& operator += (Quaternion& lhs, const float& rhs)
|
||||
{
|
||||
lhs = QuaternionAddValue(lhs, rhs);
|
||||
return lhs;
|
||||
}
|
||||
|
||||
inline Quaternion operator - (const Quaternion& lhs, const float& rhs)
|
||||
{
|
||||
return QuaternionSubtractValue(lhs, rhs);
|
||||
}
|
||||
|
||||
inline const Quaternion& operator -= (Quaternion& lhs, const float& rhs)
|
||||
{
|
||||
lhs = QuaternionSubtractValue(lhs, rhs);
|
||||
return lhs;
|
||||
}
|
||||
|
||||
inline Quaternion operator * (const Quaternion& lhs, const Matrix& rhs)
|
||||
{
|
||||
return QuaternionTransform(lhs, rhs);
|
||||
}
|
||||
|
||||
inline const Quaternion& operator *= (Quaternion& lhs, const Matrix& rhs)
|
||||
{
|
||||
lhs = QuaternionTransform(lhs, rhs);
|
||||
return lhs;
|
||||
}
|
||||
|
||||
// Matrix operators
|
||||
inline Matrix operator + (const Matrix& lhs, const Matrix& rhs)
|
||||
{
|
||||
return MatrixAdd(lhs, rhs);
|
||||
}
|
||||
|
||||
inline const Matrix& operator += (Matrix& lhs, const Matrix& rhs)
|
||||
{
|
||||
lhs = MatrixAdd(lhs, rhs);
|
||||
return lhs;
|
||||
}
|
||||
|
||||
inline Matrix operator - (const Matrix& lhs, const Matrix& rhs)
|
||||
{
|
||||
return MatrixSubtract(lhs, rhs);
|
||||
}
|
||||
|
||||
inline const Matrix& operator -= (Matrix& lhs, const Matrix& rhs)
|
||||
{
|
||||
lhs = MatrixSubtract(lhs, rhs);
|
||||
return lhs;
|
||||
}
|
||||
|
||||
inline Matrix operator * (const Matrix& lhs, const Matrix& rhs)
|
||||
{
|
||||
return MatrixMultiply(lhs, rhs);
|
||||
}
|
||||
|
||||
inline const Matrix& operator *= (Matrix& lhs, const Matrix& rhs)
|
||||
{
|
||||
lhs = MatrixMultiply(lhs, rhs);
|
||||
return lhs;
|
||||
}
|
||||
//-------------------------------------------------------------------------------
|
||||
#endif // C++ operators
|
||||
|
||||
#endif // RAYMATH_H
|
||||
|
||||
@@ -0,0 +1,122 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
width="512"
|
||||
height="512"
|
||||
viewBox="0 0 512 512"
|
||||
version="1.1"
|
||||
id="svg1"
|
||||
inkscape:export-filename="blocker_closed.png"
|
||||
inkscape:export-xdpi="24"
|
||||
inkscape:export-ydpi="24"
|
||||
inkscape:version="1.4.4 (dcaf3e7d9e, 2026-05-05)"
|
||||
sodipodi:docname="block.svg"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg">
|
||||
<sodipodi:namedview
|
||||
id="namedview1"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#000000"
|
||||
borderopacity="0.25"
|
||||
inkscape:showpageshadow="2"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pagecheckerboard="0"
|
||||
inkscape:deskcolor="#d1d1d1"
|
||||
inkscape:document-units="px"
|
||||
showguides="true"
|
||||
inkscape:zoom="1.1398148"
|
||||
inkscape:cx="87.294883"
|
||||
inkscape:cy="268.026"
|
||||
inkscape:window-width="2560"
|
||||
inkscape:window-height="1414"
|
||||
inkscape:window-x="2560"
|
||||
inkscape:window-y="1106"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="g5">
|
||||
<sodipodi:guide
|
||||
position="0,256"
|
||||
orientation="0,1"
|
||||
id="guide1"
|
||||
inkscape:locked="false"
|
||||
inkscape:label=""
|
||||
inkscape:color="rgb(0,134,229)" />
|
||||
<sodipodi:guide
|
||||
position="256,256"
|
||||
orientation="1,0"
|
||||
id="guide2"
|
||||
inkscape:locked="false" />
|
||||
</sodipodi:namedview>
|
||||
<defs
|
||||
id="defs1" />
|
||||
<g
|
||||
inkscape:label="Blocker Open"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1"
|
||||
style="display:none">
|
||||
<rect
|
||||
style="fill:#b4d273;fill-opacity:1;fill-rule:evenodd;stroke-width:0.742756"
|
||||
id="rect1"
|
||||
width="282.46313"
|
||||
height="512"
|
||||
x="114.76843"
|
||||
y="0"
|
||||
ry="141.23157" />
|
||||
<rect
|
||||
style="fill:#d6d6d6;fill-opacity:1;fill-rule:evenodd;stroke-width:0.950718"
|
||||
id="rect2"
|
||||
width="379.43814"
|
||||
height="45.092152"
|
||||
x="-445.71906"
|
||||
y="233.45392"
|
||||
transform="rotate(-90)" />
|
||||
<circle
|
||||
style="fill:#d6d6d6;fill-opacity:1"
|
||||
id="path1"
|
||||
cx="255.99994"
|
||||
cy="106.15759"
|
||||
r="56.149471" />
|
||||
<circle
|
||||
style="fill:#d6d6d6;fill-opacity:1"
|
||||
id="path1-0"
|
||||
cx="256"
|
||||
cy="407.41348"
|
||||
r="56.149471" />
|
||||
</g>
|
||||
<g
|
||||
inkscape:label="Blocker Closed"
|
||||
inkscape:groupmode="layer"
|
||||
id="g5"
|
||||
transform="rotate(-90,256,256)">
|
||||
<rect
|
||||
style="fill:#c35355;fill-opacity:1;fill-rule:evenodd;stroke-width:0.742756"
|
||||
id="rect3"
|
||||
width="282.46313"
|
||||
height="512"
|
||||
x="114.76843"
|
||||
y="0"
|
||||
ry="141.23157" />
|
||||
<rect
|
||||
style="fill:#d6d6d6;fill-opacity:1;fill-rule:evenodd;stroke-width:0.950718"
|
||||
id="rect4"
|
||||
width="379.43814"
|
||||
height="45.092152"
|
||||
x="-445.71906"
|
||||
y="233.45392"
|
||||
transform="rotate(-90)" />
|
||||
<circle
|
||||
style="fill:#d6d6d6;fill-opacity:1"
|
||||
id="circle4"
|
||||
cx="255.99994"
|
||||
cy="106.15759"
|
||||
r="56.149471" />
|
||||
<circle
|
||||
style="fill:#d6d6d6;fill-opacity:1"
|
||||
id="circle5"
|
||||
cx="256"
|
||||
cy="407.41348"
|
||||
r="56.149471" />
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 3.2 KiB |
@@ -0,0 +1,81 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
width="512"
|
||||
height="512"
|
||||
viewBox="0 0 512 512"
|
||||
version="1.1"
|
||||
id="svg1"
|
||||
inkscape:export-filename="round-delete.png"
|
||||
inkscape:export-xdpi="24"
|
||||
inkscape:export-ydpi="24"
|
||||
inkscape:version="1.4.4 (dcaf3e7d9e, 2026-05-05)"
|
||||
sodipodi:docname="textures.svg"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg">
|
||||
<sodipodi:namedview
|
||||
id="namedview1"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#000000"
|
||||
borderopacity="0.25"
|
||||
inkscape:showpageshadow="2"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pagecheckerboard="0"
|
||||
inkscape:deskcolor="#d1d1d1"
|
||||
inkscape:document-units="px"
|
||||
showguides="true"
|
||||
inkscape:zoom="1.1398148"
|
||||
inkscape:cx="87.73355"
|
||||
inkscape:cy="268.026"
|
||||
inkscape:window-width="2560"
|
||||
inkscape:window-height="1414"
|
||||
inkscape:window-x="2560"
|
||||
inkscape:window-y="1106"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="layer1">
|
||||
<sodipodi:guide
|
||||
position="0,256"
|
||||
orientation="0,1"
|
||||
id="guide1"
|
||||
inkscape:locked="false"
|
||||
inkscape:label=""
|
||||
inkscape:color="rgb(0,134,229)" />
|
||||
<sodipodi:guide
|
||||
position="256,256"
|
||||
orientation="1,0"
|
||||
id="guide2"
|
||||
inkscape:locked="false" />
|
||||
</sodipodi:namedview>
|
||||
<defs
|
||||
id="defs1" />
|
||||
<g
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1">
|
||||
<circle
|
||||
style="fill:#c35355;fill-opacity:1"
|
||||
id="path2"
|
||||
cx="256"
|
||||
cy="256"
|
||||
r="256" />
|
||||
<rect
|
||||
style="fill:#d6d6d6;fill-opacity:1;fill-rule:evenodd"
|
||||
id="rect2"
|
||||
width="419.79556"
|
||||
height="45.092152"
|
||||
x="-571.93646"
|
||||
y="-22.546076"
|
||||
transform="rotate(-135)" />
|
||||
<rect
|
||||
style="fill:#d6d6d6;fill-opacity:1;fill-rule:evenodd"
|
||||
id="rect2-0"
|
||||
width="419.79556"
|
||||
height="45.092152"
|
||||
x="-209.89778"
|
||||
y="339.49261"
|
||||
transform="rotate(-45)" />
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.2 KiB |
@@ -0,0 +1,96 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
width="512"
|
||||
height="512"
|
||||
viewBox="0 0 512 512"
|
||||
version="1.1"
|
||||
id="svg1"
|
||||
inkscape:export-filename="textures/split.png"
|
||||
inkscape:export-xdpi="24"
|
||||
inkscape:export-ydpi="24"
|
||||
inkscape:version="1.4.4 (dcaf3e7d9e, 2026-05-05)"
|
||||
sodipodi:docname="split.svg"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg">
|
||||
<sodipodi:namedview
|
||||
id="namedview1"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#000000"
|
||||
borderopacity="0.25"
|
||||
inkscape:showpageshadow="2"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pagecheckerboard="0"
|
||||
inkscape:deskcolor="#d1d1d1"
|
||||
inkscape:document-units="px"
|
||||
showguides="true"
|
||||
inkscape:zoom="0.80597077"
|
||||
inkscape:cx="-42.805522"
|
||||
inkscape:cy="129.65731"
|
||||
inkscape:window-width="2560"
|
||||
inkscape:window-height="1414"
|
||||
inkscape:window-x="2560"
|
||||
inkscape:window-y="1106"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="layer1">
|
||||
<sodipodi:guide
|
||||
position="0,256"
|
||||
orientation="0,1"
|
||||
id="guide1"
|
||||
inkscape:locked="false"
|
||||
inkscape:label=""
|
||||
inkscape:color="rgb(0,134,229)" />
|
||||
<sodipodi:guide
|
||||
position="256,256"
|
||||
orientation="1,0"
|
||||
id="guide2"
|
||||
inkscape:locked="false" />
|
||||
</sodipodi:namedview>
|
||||
<defs
|
||||
id="defs1" />
|
||||
<g
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1">
|
||||
<rect
|
||||
style="fill:#b4d273;fill-opacity:1;fill-rule:evenodd;stroke-width:0.742756"
|
||||
id="rect1"
|
||||
width="282.46313"
|
||||
height="512"
|
||||
x="-1027.9529"
|
||||
y="0"
|
||||
ry="141.23157" />
|
||||
<circle
|
||||
style="fill:#b4d273;fill-opacity:1"
|
||||
id="path2"
|
||||
cx="256"
|
||||
cy="256"
|
||||
r="256" />
|
||||
<circle
|
||||
style="fill:#d6d6d6;fill-opacity:1;stroke-width:0.832073"
|
||||
id="path2-7"
|
||||
cx="256"
|
||||
cy="256"
|
||||
r="213.01056" />
|
||||
<rect
|
||||
style="fill:#b4d273;fill-opacity:1;fill-rule:evenodd"
|
||||
id="rect2"
|
||||
width="45.621445"
|
||||
height="300.92609"
|
||||
x="233.18927"
|
||||
y="105.53696"
|
||||
ry="22.810722" />
|
||||
<rect
|
||||
style="fill:#b4d273;fill-opacity:1;fill-rule:evenodd"
|
||||
id="rect2-6"
|
||||
width="45.621445"
|
||||
height="300.92609"
|
||||
x="233.18927"
|
||||
y="-406.46304"
|
||||
ry="22.810722"
|
||||
transform="rotate(90)" />
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.6 KiB |
@@ -0,0 +1,81 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
width="512"
|
||||
height="512"
|
||||
viewBox="0 0 512 512"
|
||||
version="1.1"
|
||||
id="svg1"
|
||||
inkscape:export-filename="round-delete.png"
|
||||
inkscape:export-xdpi="24"
|
||||
inkscape:export-ydpi="24"
|
||||
inkscape:version="1.4.4 (dcaf3e7d9e, 2026-05-05)"
|
||||
sodipodi:docname="textures.svg"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg">
|
||||
<sodipodi:namedview
|
||||
id="namedview1"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#000000"
|
||||
borderopacity="0.25"
|
||||
inkscape:showpageshadow="2"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pagecheckerboard="0"
|
||||
inkscape:deskcolor="#d1d1d1"
|
||||
inkscape:document-units="px"
|
||||
showguides="true"
|
||||
inkscape:zoom="1.1398148"
|
||||
inkscape:cx="87.73355"
|
||||
inkscape:cy="268.026"
|
||||
inkscape:window-width="2560"
|
||||
inkscape:window-height="1414"
|
||||
inkscape:window-x="2560"
|
||||
inkscape:window-y="1106"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="layer1">
|
||||
<sodipodi:guide
|
||||
position="0,256"
|
||||
orientation="0,1"
|
||||
id="guide1"
|
||||
inkscape:locked="false"
|
||||
inkscape:label=""
|
||||
inkscape:color="rgb(0,134,229)" />
|
||||
<sodipodi:guide
|
||||
position="256,256"
|
||||
orientation="1,0"
|
||||
id="guide2"
|
||||
inkscape:locked="false" />
|
||||
</sodipodi:namedview>
|
||||
<defs
|
||||
id="defs1" />
|
||||
<g
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1">
|
||||
<circle
|
||||
style="fill:#c35355;fill-opacity:1"
|
||||
id="path2"
|
||||
cx="256"
|
||||
cy="256"
|
||||
r="256" />
|
||||
<rect
|
||||
style="fill:#d6d6d6;fill-opacity:1;fill-rule:evenodd"
|
||||
id="rect2"
|
||||
width="419.79556"
|
||||
height="45.092152"
|
||||
x="-571.93646"
|
||||
y="-22.546076"
|
||||
transform="rotate(-135)" />
|
||||
<rect
|
||||
style="fill:#d6d6d6;fill-opacity:1;fill-rule:evenodd"
|
||||
id="rect2-0"
|
||||
width="419.79556"
|
||||
height="45.092152"
|
||||
x="-209.89778"
|
||||
y="339.49261"
|
||||
transform="rotate(-45)" />
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.2 KiB |
|
After Width: | Height: | Size: 12 KiB |
|
After Width: | Height: | Size: 17 KiB |
|
After Width: | Height: | Size: 16 KiB |
|
After Width: | Height: | Size: 12 KiB |
|
After Width: | Height: | Size: 16 KiB |
|
After Width: | Height: | Size: 16 KiB |
|
After Width: | Height: | Size: 13 KiB |
|
After Width: | Height: | Size: 12 KiB |
|
After Width: | Height: | Size: 20 KiB |
|
After Width: | Height: | Size: 22 KiB |
|
After Width: | Height: | Size: 23 KiB |
|
After Width: | Height: | Size: 33 KiB |
|
After Width: | Height: | Size: 31 KiB |
|
After Width: | Height: | Size: 20 KiB |
|
After Width: | Height: | Size: 28 KiB |
|
After Width: | Height: | Size: 29 KiB |
@@ -1,14 +1,17 @@
|
||||
#include "app-manager.h"
|
||||
|
||||
#include "datatypes.h"
|
||||
#include "interaction-manager.h"
|
||||
#include "nlohmann/json.hpp"
|
||||
#include "graph-manager.h"
|
||||
#include "signal-manager.h"
|
||||
#include "midi-node.h"
|
||||
#include "state.h"
|
||||
#include "ui.h"
|
||||
|
||||
#include <memory>
|
||||
#include <fstream>
|
||||
#include <raylib.h>
|
||||
|
||||
namespace VISEQ::APP{
|
||||
void AppManager::init(){
|
||||
@@ -18,10 +21,35 @@ namespace VISEQ::APP{
|
||||
canvas->camera.zoom = 1.0f;
|
||||
}
|
||||
|
||||
void AppManager::loadTextures(){
|
||||
TEXTURES::tex_connector = LoadTexture("resources/textures/connector.png");
|
||||
TEXTURES::tex_connector_hover = LoadTexture("resources/textures/connector_hover.png");
|
||||
TEXTURES::tex_connector_pressed = LoadTexture("resources/textures/connector_pressed.png");
|
||||
TEXTURES::tex_connector_connected = LoadTexture("resources/textures/connector_connected.png");
|
||||
TEXTURES::tex_delete = LoadTexture("resources/textures/delete.png");
|
||||
TEXTURES::tex_split = LoadTexture("resources/textures/split.png");
|
||||
TEXTURES::tex_blocker_open = LoadTexture("resources/textures/blocker_open.png");
|
||||
TEXTURES::tex_blocker_closed= LoadTexture("resources/textures/blocker_closed.png");
|
||||
TEXTURES::tex_delete_hover = LoadTexture("resources/textures/delete_hover.png");
|
||||
TEXTURES::tex_split_hover = LoadTexture("resources/textures/split_hover.png");
|
||||
TEXTURES::tex_blocker_open_hover = LoadTexture("resources/textures/blocker_open_hover.png");
|
||||
TEXTURES::tex_blocker_closed_hover = LoadTexture("resources/textures/blocker_closed_hover.png");
|
||||
TEXTURES::tex_delete_pressed = LoadTexture("resources/textures/delete_pressed.png");
|
||||
TEXTURES::tex_split_pressed = LoadTexture("resources/textures/split_pressed.png");
|
||||
TEXTURES::tex_blocker_open_pressed = LoadTexture("resources/textures/blocker_open_pressed.png");
|
||||
TEXTURES::tex_blocker_closed_pressed = LoadTexture("resources/textures/blocker_closed_pressed.png");
|
||||
}
|
||||
|
||||
void AppManager::close(){
|
||||
std::ofstream file("state.json");
|
||||
file << json(*this);
|
||||
std::cout << std::setw(4) << json(*this) << std::endl;
|
||||
|
||||
sm->midi.all_notes_off();
|
||||
|
||||
for(auto &p : sm->midi.midi_outs){
|
||||
p.second->close_port();
|
||||
}
|
||||
}
|
||||
|
||||
void AppManager::startSignals(){
|
||||
@@ -110,11 +138,19 @@ namespace VISEQ::APP{
|
||||
for(auto& n : gm->getMidiNodes()){
|
||||
auto nc = std::dynamic_pointer_cast<MidiNode>(n.lock());
|
||||
for(auto& mo : sm->midi.midi_out_ports){
|
||||
if(!nc->midi_outs.contains(mo.number) && mo.enabled){
|
||||
nc->midi_outs[mo.number] = {mo.number, mo.port.port_name, false};
|
||||
if(!nc->selected_midi_outs.contains(mo.number) && mo.enabled){
|
||||
nc->selected_midi_outs[mo.number] = {mo.number, false, mo.port.port_name};
|
||||
}
|
||||
if(nc->midi_outs.contains(mo.number) && !mo.enabled){
|
||||
nc->midi_outs.erase(mo.number);
|
||||
if(nc->selected_midi_outs.contains(mo.number) && !mo.enabled){
|
||||
nc->selected_midi_outs.erase(mo.number);
|
||||
}
|
||||
}
|
||||
for(auto& mo : sm->midi.virtual_midi_out_ports){
|
||||
if(!nc->selected_midi_outs.contains(mo.number) && mo.enabled){
|
||||
nc->selected_midi_outs[mo.number] = {mo.number, false, mo.name};
|
||||
}
|
||||
if(nc->selected_midi_outs.contains(mo.number) && !mo.enabled){
|
||||
nc->selected_midi_outs.erase(mo.number);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -139,8 +175,8 @@ namespace VISEQ::APP{
|
||||
canvas->drawStart();
|
||||
canvas->draw();
|
||||
|
||||
gm->drawNodes(SCREEN_MOUSE, canvas->camera);
|
||||
gm->drawEdges(SCREEN_MOUSE, canvas->camera);
|
||||
gm->drawNodes(SCREEN_MOUSE, canvas->camera);
|
||||
sm->drawSignals(SCREEN_MOUSE, canvas->camera);
|
||||
|
||||
im.draw();
|
||||
|
||||
@@ -30,6 +30,7 @@ namespace VISEQ::APP {
|
||||
UI::AppUI ui;
|
||||
|
||||
void init();
|
||||
void loadTextures();
|
||||
void close();
|
||||
void startSignals();
|
||||
void loadState();
|
||||
|
||||
@@ -12,6 +12,45 @@ inline bool ViButton(Vec2Df mp, float x, float y, float radius, Color color){
|
||||
return (Vector2Distance(mp, (Vector2){x,y}) < radius && IsMouseButtonPressed(MOUSE_BUTTON_LEFT));
|
||||
}
|
||||
|
||||
inline bool ViTexButton(Vec2Df mp, Vec2Df position, float rotation, float radius, Texture2D tex, Texture2D tex_hover, Texture2D tex_pressed, Color color){
|
||||
float scale = (radius*2.0f) / (float)tex.width;
|
||||
Vec2Df start_position = position - Vec2Df((tex.width*scale) / 2.0f, (tex.height*scale) / 2.0f);
|
||||
Vec2Df center_pos = start_position.rotateAround(position, rotation);
|
||||
bool hover = Vector2Distance(mp, position) < radius;
|
||||
bool pressed = hover && IsMouseButtonPressed(MOUSE_BUTTON_LEFT);
|
||||
|
||||
if(!hover && !pressed) DrawTexturePro(tex, Rectangle(0.0, 0.0, tex.width, tex.height), Rectangle(center_pos.x, center_pos.y, tex.width*scale, tex.height*scale), Vec2Df(0.0f,tex.height*scale/2.0f), rotation, color);
|
||||
if(hover) DrawTexturePro(tex_hover, Rectangle(0.0, 0.0, tex.width, tex.height), Rectangle(center_pos.x, center_pos.y, tex.width*scale, tex.height*scale), Vec2Df(0.0f,tex.height*scale/2.0f), rotation, color);
|
||||
if(pressed) DrawTexturePro(tex_pressed, Rectangle(0.0, 0.0, tex.width, tex.height), Rectangle(center_pos.x, center_pos.y, tex.width*scale, tex.height*scale), Vec2Df(0.0f,tex.height*scale/2.0f), rotation, color);
|
||||
|
||||
return pressed;
|
||||
}
|
||||
|
||||
inline bool ViTexButton(Vec2Df mp, Vec2Df position, float rotation, float radius, Texture2D tex, Texture2D tex_hover, Color color){
|
||||
float scale = (radius*2.0f) / (float)tex.width;
|
||||
Vec2Df start_position = position - Vec2Df((tex.width*scale) / 2.0f, (tex.height*scale) / 2.0f);
|
||||
Vec2Df center_pos = start_position.rotateAround(position, rotation);
|
||||
bool hover = Vector2Distance(mp, position) < radius;
|
||||
bool pressed = hover && IsMouseButtonPressed(MOUSE_BUTTON_LEFT);
|
||||
|
||||
if(!hover) DrawTexturePro(tex, Rectangle(0.0, 0.0, tex.width, tex.height), Rectangle(center_pos.x, center_pos.y, tex.width*scale, tex.height*scale), Vec2Df(0.0f,tex.height*scale/2.0f), rotation, color);
|
||||
if(hover) DrawTexturePro(tex_hover, Rectangle(0.0, 0.0, tex.width, tex.height), Rectangle(center_pos.x, center_pos.y, tex.width*scale, tex.height*scale), Vec2Df(0.0f,tex.height*scale/2.0f), rotation, color);
|
||||
|
||||
return pressed;
|
||||
}
|
||||
|
||||
inline bool ViTexButton(Vec2Df mp, Vec2Df position, float rotation, float radius, Texture2D tex, Color color){
|
||||
float scale = (radius*2.0f) / (float)tex.width;
|
||||
Vec2Df start_position = position - Vec2Df((tex.width*scale) / 2.0f, (tex.height*scale) / 2.0f);
|
||||
Vec2Df center_pos = start_position.rotateAround(position, rotation);
|
||||
bool hover = Vector2Distance(mp, position) < radius;
|
||||
bool pressed = hover && IsMouseButtonPressed(MOUSE_BUTTON_LEFT);
|
||||
|
||||
DrawTexturePro(tex, Rectangle(0.0, 0.0, tex.width, tex.height), Rectangle(center_pos.x, center_pos.y, tex.width*scale, tex.height*scale), Vec2Df(0.0f,tex.height*scale/2.0f), rotation, color);
|
||||
|
||||
return pressed;
|
||||
}
|
||||
|
||||
inline bool ViButton(Vec2Df mp, Vec2Df position, float radius, Color color){
|
||||
return ViButton(mp, position.x, position.y, radius, color);
|
||||
}
|
||||
@@ -30,7 +69,12 @@ inline bool ViSegButton(Vec2Df mp, float x, float y, float start_angle, float en
|
||||
|
||||
inline void DrawCenteredText(std::string text, Vec2Df position, float text_size, Color color){
|
||||
float offset = MeasureText(text.c_str(), text_size);
|
||||
DrawText(text.c_str(), position.x-offset/2.0f, position.y-text_size/2.0f, text_size, color);
|
||||
//DrawText(text.c_str(), position.x-offset/2.0f, position.y-text_size/2.0f, text_size, color);
|
||||
DrawTextEx(VISEQ::APP::inter, text.c_str(), Vec2Df(position.x-offset/2.0f, position.y-(float)text_size/2.0f+1), text_size, 2.0f, color);
|
||||
}
|
||||
|
||||
inline void DrawText(std::string text, Vec2Df position, float text_size, Color color){
|
||||
DrawText(text.c_str(), position.x, position.y-text_size/2.0f, text_size, color);
|
||||
}
|
||||
|
||||
namespace VISEQ::APP::UI{
|
||||
|
||||
@@ -21,14 +21,14 @@ namespace VISEQ::APP::CANVAS {
|
||||
}
|
||||
|
||||
void Canvas::pickUp() {
|
||||
std::cout << "canvas pickUp" << std::endl;
|
||||
//std::cout << "canvas pickUp" << std::endl;
|
||||
BASE::Draggable::pickUp();
|
||||
select_start = SCREEN_MOUSE;
|
||||
state->pushEvent({getPtr(), Interaction::DESELECT});
|
||||
}
|
||||
|
||||
void Canvas::putDown() {
|
||||
std::cout << "canvas putDown" << std::endl;
|
||||
//std::cout << "canvas putDown" << std::endl;
|
||||
BASE::Draggable::putDown();
|
||||
state->pushEvent({getPtr(), Interaction::SELECT});
|
||||
}
|
||||
|
||||
@@ -13,4 +13,11 @@ namespace VISEQ::APP {
|
||||
}
|
||||
}
|
||||
|
||||
std::shared_ptr<Clipboard> Clipboard::get() {
|
||||
if(!Clipboard::instance){
|
||||
Clipboard::instance.reset(new Clipboard());
|
||||
}
|
||||
return Clipboard::instance;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -14,5 +14,8 @@ namespace VISEQ::APP {
|
||||
|
||||
void copyNodes(GRAPH::NODES::VEC_SPTR_Node selected_nodes);
|
||||
|
||||
inline static std::shared_ptr<Clipboard> instance;
|
||||
static std::shared_ptr<Clipboard> get();
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
@@ -82,14 +82,14 @@ namespace VISEQ::GRAPH::NODES {
|
||||
|
||||
void ConfigNode::update() {
|
||||
Node::update();
|
||||
mode = state->node_mode;
|
||||
//mode = state->node_mode;
|
||||
}
|
||||
|
||||
void ConfigNode::interact(){
|
||||
float wheel = GetMouseWheelMove();
|
||||
|
||||
if(KEYS_DOWN.ctrl && !KEYS_DOWN.alt){
|
||||
switch(state->node_mode){
|
||||
switch(mode){
|
||||
case 0:{
|
||||
midiNote.note += KEYS_DOWN.shift ? ((wheel > 0) - (wheel < 0)) * 12 : wheel;
|
||||
break;}
|
||||
|
||||
@@ -0,0 +1,90 @@
|
||||
#include "connector.h"
|
||||
|
||||
#include "helper.h"
|
||||
#include "node.h"
|
||||
#include "raymath.h"
|
||||
#include "state.h"
|
||||
|
||||
#include "button.h"
|
||||
#include <execution>
|
||||
#include <memory>
|
||||
|
||||
|
||||
namespace VISEQ::GRAPH {
|
||||
GraphItemType Connector::getType() {
|
||||
return GraphItemType::CONNECTOR;
|
||||
}
|
||||
|
||||
std::shared_ptr<Connector> Connector::getPtr(){
|
||||
return shared_from_this();
|
||||
}
|
||||
|
||||
bool Connector::hovering() {
|
||||
return partner.expired() && CheckCollisionPointCircle(SCREEN_MOUSE, position, radius);
|
||||
}
|
||||
|
||||
void Connector::setParent(std::shared_ptr<GraphItem> _parent){
|
||||
parent = _parent;
|
||||
}
|
||||
|
||||
void Connector::setPosition(Vec2Df pos) {
|
||||
center_position = pos;
|
||||
parent_position = pos;
|
||||
}
|
||||
|
||||
void Connector::setOrbit(float r) {
|
||||
orbit = r;
|
||||
}
|
||||
|
||||
void Connector::update() {
|
||||
if(hovering()) state->pushEvent({getPtr(), APP::Interaction::HOVER});
|
||||
if(hovering() && clicked()) state->pushEvent({getPtr(), APP::Interaction::PICKUP});
|
||||
if(pickedUp()) state->pushEvent({getPtr(), APP::Interaction::DRAG});
|
||||
if(picked_up && released()) state->pushEvent({getPtr(), APP::Interaction::PUTDOWN});
|
||||
if(connected) {
|
||||
state->pushEvent({getPtr(), APP::Interaction::CONNECT});
|
||||
connected = false;
|
||||
}
|
||||
|
||||
if(partner.expired()) {
|
||||
position = center_position.orbitAlongVector(SCREEN_MOUSE, orbit);
|
||||
position_text = center_position.orbitAlongVector(SCREEN_MOUSE, orbit+10);
|
||||
}
|
||||
if(!partner.expired()) {
|
||||
position = center_position.orbitAlongVector(partner.lock()->position, orbit);
|
||||
position_text = center_position.orbitAlongVector(partner.lock()->position, orbit+10);
|
||||
}
|
||||
if(new_partner) {
|
||||
new_partner = false;
|
||||
state->pushEvent({getPtr(), APP::Interaction::CONNECT});
|
||||
}
|
||||
//parent_position = std::dynamic_pointer_cast<NODES::Node>(parent.lock())->position;
|
||||
}
|
||||
|
||||
void Connector::draw() {
|
||||
BASE::Connectable::draw();
|
||||
float opacity = Clamp((400.0f - Clamp(position.dist(SCREEN_MOUSE), 0.0f, 400.0f)) / 400.0f, 0.0f, 1.0f);
|
||||
float rotation = 0.0f;
|
||||
|
||||
if(partner.expired()) rotation = HELPER::GetRotation(parent_position, SCREEN_MOUSE) + 90.0f;
|
||||
|
||||
if(!partner.expired()) {
|
||||
rotation = HELPER::GetRotation(parent_position, partner.lock()->position) + 90.0f;
|
||||
opacity = 1.0f;
|
||||
}
|
||||
if(connecting) opacity = 1.0f;
|
||||
|
||||
if(partner.expired() && !connecting) ViTexButton(SCREEN_MOUSE, position, rotation, 8.0f,
|
||||
TEXTURES::tex_connector, TEXTURES::tex_connector_hover, TEXTURES::tex_connector_pressed,
|
||||
ColorLerp(Fade(VS_COLOR_WHITE, .0f), Fade(VS_COLOR_WHITE, 1.0f), opacity));
|
||||
|
||||
if(!partner.expired() || connecting) ViTexButton(SCREEN_MOUSE, position, rotation, 8.0f,
|
||||
TEXTURES::tex_connector_connected, TEXTURES::tex_connector_hover,
|
||||
ColorLerp(Fade(VS_COLOR_WHITE, .0f), Fade(VS_COLOR_WHITE, 1.0f), opacity));
|
||||
|
||||
//int partner_id = -1;
|
||||
//if(!partner.expired()) partner_id = std::dynamic_pointer_cast<Connector>(partner.lock())->id;
|
||||
//DrawTextPro(GetFontDefault(), std::format("{} {}", id, partner_id).c_str(), position_text, (Vector2){0,0}, rotation, 10.0f, 2.0f, VS_COLOR_PINK);
|
||||
//DrawText(std::format("{}", id), position + Vec2Df(100.0f,100.0f), 8.0f, Color(255, 0, 0));
|
||||
}
|
||||
}
|
||||
@@ -3,12 +3,10 @@
|
||||
#include "connectable.h"
|
||||
#include "datatypes.h"
|
||||
#include "graph-item.h"
|
||||
//#include "interaction-event.h"
|
||||
#include "raymath.h"
|
||||
#include "state.h"
|
||||
#include "vmath.h"
|
||||
#include <fcntl.h>
|
||||
#include <memory>
|
||||
#include <raylib.h>
|
||||
|
||||
namespace VISEQ::GRAPH {
|
||||
class Connector : public BASE::Connectable, public GraphItem, public std::enable_shared_from_this<Connector> {
|
||||
@@ -18,6 +16,8 @@ namespace VISEQ::GRAPH {
|
||||
Connector(std::shared_ptr<GraphItem> parent, Vec2Df center_position, float orbit) : orbit(orbit) {
|
||||
setPosition(center_position);
|
||||
setParent(parent);
|
||||
_id++;
|
||||
id = _id;
|
||||
}
|
||||
|
||||
std::weak_ptr<GraphItem> parent;
|
||||
@@ -27,58 +27,20 @@ namespace VISEQ::GRAPH {
|
||||
float radius = 8.0f;
|
||||
float orbit = 20.0f;
|
||||
Vec2Df center_position;
|
||||
Vec2Df parent_position;
|
||||
Vec2Df position_text;
|
||||
inline static int _id = 0;
|
||||
int id = 0;
|
||||
|
||||
GraphItemType getType() override{
|
||||
return GraphItemType::CONNECTOR;
|
||||
}
|
||||
GraphItemType getType() override;
|
||||
|
||||
std::shared_ptr<Connector> getPtr(){
|
||||
return shared_from_this();
|
||||
}
|
||||
std::shared_ptr<Connector> getPtr();
|
||||
|
||||
virtual bool hovering() override {
|
||||
return partner.expired() && CheckCollisionPointCircle(SCREEN_MOUSE, position, radius);
|
||||
}
|
||||
|
||||
void setParent(std::shared_ptr<GraphItem> _parent){
|
||||
parent = _parent;
|
||||
}
|
||||
|
||||
void setPosition(Vec2Df pos) override {
|
||||
center_position = pos;
|
||||
}
|
||||
void setOrbit(float r) {
|
||||
orbit = r;
|
||||
}
|
||||
|
||||
void update() override {
|
||||
if(hovering()) state->pushEvent({getPtr(), APP::Interaction::HOVER});
|
||||
if(hovering() && clicked()) state->pushEvent({getPtr(), APP::Interaction::PICKUP});
|
||||
if(pickedUp()) state->pushEvent({getPtr(), APP::Interaction::DRAG});
|
||||
if(picked_up && released()) state->pushEvent({getPtr(), APP::Interaction::PUTDOWN});
|
||||
if(connected) {
|
||||
state->pushEvent({getPtr(), APP::Interaction::CONNECT});
|
||||
connected = false;
|
||||
}
|
||||
|
||||
if(partner.expired()) position = center_position.orbitAlongVector(SCREEN_MOUSE, orbit);
|
||||
if(!partner.expired()) position = center_position .orbitAlongVector(partner.lock()->position, orbit);
|
||||
if(new_partner) {
|
||||
new_partner = false;
|
||||
state->pushEvent({getPtr(), APP::Interaction::CONNECT});
|
||||
}
|
||||
}
|
||||
|
||||
void draw() override {
|
||||
BASE::Connectable::draw();
|
||||
float opacity = 150.0f - Clamp(position.dist(SCREEN_MOUSE), 0.0f, 150.0f);
|
||||
|
||||
if(hovering()){
|
||||
DrawCircle(position.x, position.y, 8.0f, (Color){108, 203, 237, 255});
|
||||
} else {
|
||||
DrawCircle(position.x, position.y, 8.0f, (Color){108, 153, 187, (unsigned char)opacity});
|
||||
}
|
||||
|
||||
}
|
||||
virtual bool hovering() override;
|
||||
void setParent(std::shared_ptr<GraphItem> _parent);
|
||||
void setPosition(Vec2Df pos) override;
|
||||
void setOrbit(float r);
|
||||
void update() override;
|
||||
void draw() override;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
#define VS_COLOR_PURPLE (Color){158, 134, 200, 255}
|
||||
#define VS_COLOR_PINK (Color){176, 82, 121, 255}
|
||||
#define VS_COLOR_BLUE (Color){108, 153, 187, 255}
|
||||
#define VS_COLOR_LIGHTBLUE (Color){143, 206, 255, 255}
|
||||
|
||||
#define VS_COLOR_RED (Color){195, 83, 85, 255}
|
||||
#define VS_COLOR_BROWN (Color){84, 75, 61, 255}
|
||||
@@ -22,13 +23,36 @@
|
||||
|
||||
#include "nlohmann/json.hpp"
|
||||
using json = nlohmann::json;
|
||||
#include <raylib.h>
|
||||
|
||||
#include <cmath>
|
||||
#include <math.h>
|
||||
#include "libremidi/libremidi.hpp"
|
||||
|
||||
#define RANGE_FILTER(L) std::ranges::views::filter(L)
|
||||
|
||||
namespace VISEQ::APP{
|
||||
inline Font inter;
|
||||
}
|
||||
|
||||
namespace VISEQ::TEXTURES {
|
||||
inline Texture2D tex_connector;
|
||||
inline Texture2D tex_connector_hover;
|
||||
inline Texture2D tex_connector_pressed;
|
||||
inline Texture2D tex_connector_connected;
|
||||
inline Texture2D tex_delete;
|
||||
inline Texture2D tex_split;
|
||||
inline Texture2D tex_blocker_open;
|
||||
inline Texture2D tex_blocker_closed;
|
||||
inline Texture2D tex_delete_hover;
|
||||
inline Texture2D tex_split_hover;
|
||||
inline Texture2D tex_blocker_open_hover;
|
||||
inline Texture2D tex_blocker_closed_hover;
|
||||
inline Texture2D tex_delete_pressed;
|
||||
inline Texture2D tex_split_pressed;
|
||||
inline Texture2D tex_blocker_open_pressed;
|
||||
inline Texture2D tex_blocker_closed_pressed;
|
||||
}
|
||||
|
||||
namespace VISEQ::GRAPH::NODES {
|
||||
enum Distribution {GEOMETRIC, ROUNDROBIN, RANDOM};
|
||||
}
|
||||
@@ -89,6 +113,12 @@ namespace VISEQ::MIDI{
|
||||
bool enabled;
|
||||
};
|
||||
|
||||
struct VirtualMidiOutPort{
|
||||
int number;
|
||||
bool enabled;
|
||||
std::string name;
|
||||
};
|
||||
|
||||
struct MidiOut{
|
||||
libremidi::midi_out out;
|
||||
int number;
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include "moveable.h"
|
||||
#include "raylib.h"
|
||||
#include "selectable.h"
|
||||
#include "state.h"
|
||||
#include "vmath.h"
|
||||
|
||||
@@ -32,7 +32,7 @@ namespace VISEQ::GRAPH::EDGES {
|
||||
float speed = 0;
|
||||
float bpm = 120.0f;
|
||||
|
||||
float connector_offset = 8.0f;
|
||||
float connector_offset = 2.0f;
|
||||
float switches_offset = 25.0f;
|
||||
|
||||
virtual bool GActive();
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
#include "config-node.h"
|
||||
#include "datatypes.h"
|
||||
#include "helper.h"
|
||||
#include "state.h"
|
||||
#include "vmath.h"
|
||||
#include "raylib.h"
|
||||
@@ -52,7 +53,7 @@ namespace VISEQ::GRAPH{
|
||||
void GraphManager::addNode(SPTR_Node node){
|
||||
std::cout << "added node " << node->id << std::endl;
|
||||
nodes.insert(nodes.end(), node);
|
||||
node->update();
|
||||
nodes.back()->update();
|
||||
}
|
||||
|
||||
void GraphManager::addConnection(WPTR_Node from, WPTR_Node to){
|
||||
@@ -63,10 +64,19 @@ namespace VISEQ::GRAPH{
|
||||
edges.back()->edgeType = et;
|
||||
edges.back()->start = from;
|
||||
edges.back()->end = to;
|
||||
|
||||
from.lock()->update();
|
||||
to.lock()->update();
|
||||
|
||||
from.lock()->connectors.back()->partner = to.lock()->getConnector();
|
||||
to.lock()->connectors.back()->partner = from.lock()->getConnector();
|
||||
|
||||
edges.back()->start_conn = from.lock()->connectors.back();
|
||||
edges.back()->end_conn = to.lock()->connectors.back();
|
||||
|
||||
from.lock()->connections.push_back(edges.back());
|
||||
to.lock()->connections.push_back(edges.back());
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -115,24 +125,25 @@ namespace VISEQ::GRAPH{
|
||||
VEC_SPTR_Node GraphManager::getCopiesOfSelectedNodes(){
|
||||
VEC_SPTR_Node copied_nodes;
|
||||
for(auto n : selected_nodes){
|
||||
copied_nodes.insert(copied_nodes.end(), std::make_shared<Node>(*n));
|
||||
/*if(n->getNodeType() == NodeType::MIDINODE) copied_nodes.insert(copied_nodes.end(), std::make_shared<MidiNode>(*n));*/
|
||||
/*if(n->getNodeType() == NodeType::CONFIGNODE) copied_nodes.insert(copied_nodes.end(), std::make_shared<ConfigNode>(*n));*/
|
||||
//copied_nodes.insert(copied_nodes.end(), std::make_shared<Node>(*n));
|
||||
|
||||
if(n->getNodeType() == NodeType::MIDINODE) copied_nodes.insert(copied_nodes.end(), std::dynamic_pointer_cast<MidiNode>(n));
|
||||
if(n->getNodeType() == NodeType::CONFIGNODE) copied_nodes.insert(copied_nodes.end(), std::dynamic_pointer_cast<ConfigNode>(n));
|
||||
|
||||
copied_nodes.back()->deselect();
|
||||
}
|
||||
return copied_nodes;
|
||||
}
|
||||
|
||||
SPTR_Node GraphManager::copyNode(SPTR_Node n, Vec2Df position){
|
||||
SPTR_Node GraphManager::copyNode(const SPTR_Node n, Vec2Df position){
|
||||
std::cout << "copy basenode" << std::endl;
|
||||
nodes.insert(nodes.end(), std::make_shared<Node>(*n));
|
||||
/*if(n->getNodeType() == NodeType::MIDINODE) nodes.insert(nodes.end(), std::make_shared<MidiNode>(*n));*/
|
||||
/*if(n->getNodeType() == NodeType::CONFIGNODE) nodes.insert(nodes.end(), std::make_shared<ConfigNode>(*n));*/
|
||||
if(n->getNodeType() == NodeType::MIDINODE) nodes.insert(nodes.end(), std::dynamic_pointer_cast<MidiNode>(n));
|
||||
if(n->getNodeType() == NodeType::CONFIGNODE) nodes.insert(nodes.end(), std::dynamic_pointer_cast<ConfigNode>(n));
|
||||
nodes.back()->setPosition(position);
|
||||
return nodes.back();
|
||||
}
|
||||
|
||||
SPTR_Node GraphManager::copyNode(std::shared_ptr<MidiNode> n, Vec2Df position){
|
||||
SPTR_Node GraphManager::copyNode(const std::shared_ptr<MidiNode> n, Vec2Df position){
|
||||
std::cout << "copy midinode" << std::endl;
|
||||
nodes.insert(nodes.end(), std::make_shared<MidiNode>(*n));
|
||||
nodes.back()->clearConnectors();
|
||||
@@ -146,6 +157,12 @@ namespace VISEQ::GRAPH{
|
||||
}
|
||||
}
|
||||
|
||||
void GraphManager::cycleModeOfSelectedNodes(bool direction){
|
||||
for(auto n: selected_nodes){
|
||||
n->cycleMode(direction);
|
||||
}
|
||||
}
|
||||
|
||||
void GraphManager::reset(){
|
||||
counter.clear();
|
||||
}
|
||||
@@ -190,10 +207,15 @@ namespace VISEQ::GRAPH{
|
||||
return edges.back();
|
||||
}
|
||||
|
||||
WPTR_Node GraphManager::next(WPTR_Node current, WPTR_Node last){
|
||||
VEC_WPTR_Edge possible_connections = current.lock()->connections | RANGE_FILTER([current](WPTR_Edge c){
|
||||
return (c.lock()->getEdgeType() == EdgeType::MIDIEDGE) && ((c.lock()->start.lock() == current.lock() && c.lock()->pass_forward) || (c.lock()->end.lock() == current.lock() && c.lock()->pass_backward));
|
||||
VEC_WPTR_Edge GraphManager::getPassableConnections(WPTR_Node node){
|
||||
VEC_WPTR_Edge passable_connections = node.lock()->connections | RANGE_FILTER([node](WPTR_Edge c){
|
||||
return (c.lock()->getEdgeType() == EdgeType::MIDIEDGE) && ((c.lock()->start.lock() == node.lock() && c.lock()->pass_forward) || (c.lock()->end.lock() == node.lock() && c.lock()->pass_backward));
|
||||
}) | std::ranges::to<VEC_WPTR_Edge>();
|
||||
return passable_connections;
|
||||
}
|
||||
|
||||
WPTR_Node GraphManager::next(WPTR_Node current, WPTR_Node last){
|
||||
VEC_WPTR_Edge possible_connections = getPassableConnections(current);
|
||||
|
||||
if(possible_connections.empty()) return SPTR_Node(nullptr);
|
||||
|
||||
@@ -291,26 +313,32 @@ namespace VISEQ::GRAPH{
|
||||
|
||||
void GraphManager::pasteNodesAndEdges(VEC_SPTR_Node nodes, Vec2Df position){
|
||||
|
||||
deselect();
|
||||
std::cout << "nodes size " << nodes.size() << std::endl;
|
||||
VEC_SPTR_Edge copy_connections;
|
||||
for(auto c : edges){
|
||||
if(std::ranges::contains(nodes, c->start.lock()) && std::ranges::contains(nodes, c->end.lock())) {
|
||||
copy_connections.push_back(std::make_shared<Edge>(*c));
|
||||
}
|
||||
}
|
||||
std::cout << copy_connections.size() << std::endl;
|
||||
|
||||
std::cout << "copy_connections size " << copy_connections.size() << std::endl;
|
||||
Vec2Df insert_pos = nodes.begin()->get()->position;
|
||||
for(auto old_node : nodes){
|
||||
SPTR_Node new_node;
|
||||
|
||||
if(old_node->getNodeType() == NodeType::MIDINODE) {
|
||||
new_node = copyNode(std::dynamic_pointer_cast<MidiNode>(old_node), position + old_node->drag_offset);
|
||||
std::cout << "node type midi" << std::endl;
|
||||
new_node = copyNode(std::dynamic_pointer_cast<MidiNode>(old_node), (old_node->position - insert_pos) + position);
|
||||
} else {
|
||||
std::cout << "not node type midi" << std::endl;
|
||||
new_node = copyNode(old_node, position + old_node->drag_offset);
|
||||
}
|
||||
|
||||
old_node->selected = false;
|
||||
new_node->copied = false;
|
||||
new_node->selected = true;
|
||||
|
||||
|
||||
//TODO copy connectors
|
||||
|
||||
for(auto c : copy_connections){
|
||||
@@ -325,6 +353,7 @@ namespace VISEQ::GRAPH{
|
||||
}
|
||||
}
|
||||
std::ranges::copy(copy_connections.begin(), copy_connections.end(), std::back_inserter(edges));
|
||||
addToSelection();
|
||||
}
|
||||
|
||||
void GraphManager::update(){
|
||||
@@ -339,41 +368,41 @@ namespace VISEQ::GRAPH{
|
||||
float v1_v2_distance = v1_position.dist(&v2_position);
|
||||
|
||||
if(v1_v2_distance < 100) c->switches_offset = v1_v2_distance/2.3f;
|
||||
Vec2Df from_to_handle = c->start.lock()->position - ((c->start.lock()->position - c->end.lock()->position)).norm() * (c->start.lock()->radius + c->switches_offset);
|
||||
Vec2Df to_from_handle = c->end.lock()->position - ((c->end.lock()->position - c->start.lock()->position)).norm() * (c->end.lock()->radius + c->switches_offset);
|
||||
Vec2Df middle_handle = c->end.lock()->position - ((c->end.lock()->position - c->start.lock()->position))*0.4f;
|
||||
Vec2Df middle_handle_2 = c->end.lock()->position - ((c->end.lock()->position - c->start.lock()->position))*0.6f;
|
||||
Vec2Df flip_handle = middle_handle + (v1_position - v2_position).norm().orth() * (v1_v2_distance < 120.0f ? Clamp((120.0f - v1_v2_distance)*0.2, 0.f, 20.f) : 1.0f);
|
||||
Vec2Df flip_handle_2 = middle_handle_2 + (v1_position - v2_position).norm().orth() * (v1_v2_distance < 120.0f ? Clamp((120.0f - v1_v2_distance)*-0.2, -20.f, 0.f) : 1.0f);
|
||||
float from_radius = c->start.lock()->radius;
|
||||
float to_radius = c->end.lock()->radius;
|
||||
|
||||
Vec2Df from_to_handle = c->start.lock()->position - ((c->start.lock()->position - c->end.lock()->position)).norm() * (from_radius + 35.0f);
|
||||
Vec2Df to_from_handle = c->end.lock()->position - ((c->end.lock()->position - c->start.lock()->position)).norm() * (to_radius + 35.0f);
|
||||
//Vec2Df middle_handle_2 = c->end.lock()->position - ((c->end.lock()->position - c->start.lock()->position)).norm()*65.0f;
|
||||
//Vec2Df middle_handle = c->start.lock()->position - ((c->start.lock()->position - c->end.lock()->position)).norm()*65.0f;
|
||||
Vec2Df center_handle = c->end.lock()->position - ((c->end.lock()->position - c->start.lock()->position))*0.5f;
|
||||
|
||||
Vec2Df delete_position = center_handle + (c->start.lock()->position - c->end.lock()->position).norm().orth() * 12.0f;
|
||||
Vec2Df split_position = center_handle - (c->start.lock()->position - c->end.lock()->position).norm().orth() * 12.0f;
|
||||
|
||||
// Dynamic opacity by distance to mouse
|
||||
unsigned char opacity = 150.0f - Clamp(middle_handle.dist(mouse_pos), 0.0f, 150.0f);
|
||||
unsigned char opacity = 150.0f - Clamp(center_handle.dist(mouse_pos), 0.0f, 130.0f);
|
||||
unsigned char opacity_from = 250.0f - Clamp(from_to_handle.dist(mouse_pos), 0.0f, 220.0f);
|
||||
unsigned char opacity_to = 250.0f - Clamp(to_from_handle.dist(mouse_pos), 0.0f, 220.0f);
|
||||
|
||||
float midi_gate_v1 = 0.0f;
|
||||
float midi_gate_v2 = 0.0f;
|
||||
float opacity_normalized = Clamp((float)opacity / 255.0f, .0f, 1.0f);
|
||||
//float opacity_from_normalized = Clamp((float)opacity_from / 255.0f, .0f, 1.0f);
|
||||
//float opacity_to_normalized = Clamp((float)opacity_to / 255.0f, .0f, 1.0f);
|
||||
|
||||
if(c->start.lock()->getNodeType() == NodeType::MIDINODE){
|
||||
midi_gate_v1 = Clamp((4.f / 1000.f) * std::dynamic_pointer_cast<MidiNode>(c->start.lock())->getNotes().gate, 1.f, 4.f);
|
||||
}
|
||||
if(c->end.lock()->getNodeType() == NodeType::MIDINODE){
|
||||
midi_gate_v2 = Clamp((4.f / 1000.f) * std::dynamic_pointer_cast<MidiNode>(c->end.lock())->getNotes().gate, 1.f, 4.f);
|
||||
}
|
||||
// Line with small connector circles
|
||||
if(c->end.lock()->getNodeType() == NodeType::MIDINODE && c->start.lock()->getNodeType() == NodeType::MIDINODE){
|
||||
|
||||
Color col = {229, 181, 103, 255};
|
||||
if(c->GActive()) col = {108, 153, 187, 255};
|
||||
DrawLine(v1_position.x, v1_position.y, v2_position.x, v2_position.y, col);
|
||||
{
|
||||
if(state->draw_edge_lengths){
|
||||
float d = c->start.lock()->position.dist(c->end.lock()->position);
|
||||
std::string frac = MIDI::Fractions.at(std::clamp<int>(round(d/60) - 1, 0, 31));
|
||||
Vector2 text_length = MeasureTextEx(GetFontDefault(), std::format("{:.1f}",d).c_str(), 10.0f, 2.0f);
|
||||
Vector2 text_length_frac = MeasureTextEx(GetFontDefault(), frac.c_str(), 10.0f, 2.0f);
|
||||
|
||||
Vec2Df middle_handle = c->start.lock()->position + (c->end.lock()->position - c->start.lock()->position) * ((d - text_length.x)*0.5f)/d;
|
||||
Vec2Df middle_handle_frac = c->start.lock()->position + (c->end.lock()->position - c->start.lock()->position) * ((d - text_length_frac.x)*0.5f)/d;
|
||||
Vec2Df middle_handle = c->start.lock()->position + (c->end.lock()->position - c->start.lock()->position) * ((d - text_length.x)*0.35f)/d;
|
||||
Vec2Df middle_handle_frac = c->start.lock()->position + (c->end.lock()->position - c->start.lock()->position) * ((d - text_length_frac.x)*0.35f)/d;
|
||||
Vec2Df text_position = middle_handle + (c->start.lock()->position - c->end.lock()->position).norm().orth() * 12.0f;
|
||||
Vec2Df text_position_frac = middle_handle_frac - (c->start.lock()->position - c->end.lock()->position).norm().orth() * 4.0f;
|
||||
|
||||
@@ -381,38 +410,34 @@ namespace VISEQ::GRAPH{
|
||||
DrawTextPro(GetFontDefault(), std::format("{:.1f}",d).c_str(), text_position, (Vector2){0,0}, rotation, 10.0f, 2.0f, VS_COLOR_PINK);
|
||||
if( (int)d % 60 == 0) DrawTextPro(GetFontDefault(), frac.c_str(), text_position_frac, (Vector2){0,0}, rotation, 10.0f, 2.0f, VS_COLOR_PINK);
|
||||
}
|
||||
if(midi_gate_v1 == 4.0f) col = VS_COLOR_RED;
|
||||
DrawCircle(v1_position.x, v1_position.y, midi_gate_v1, col);
|
||||
|
||||
col = {229, 181, 103, 255};
|
||||
if(midi_gate_v2 == 4.0f) col = VS_COLOR_RED;
|
||||
DrawCircle(v2_position.x, v2_position.y, midi_gate_v2, col);
|
||||
|
||||
if(!c->start.lock()->picked_up && !c->end.lock()->picked_up){
|
||||
// On/Off switches on both sides
|
||||
if(ViButton(mouse_pos, from_to_handle.x, from_to_handle.y, 8.0f, c->pass_forward ? (Color){120, 210, 115, opacity_from} : (Color){232, 50, 32, opacity_from} )) c->pass_forward = !c->pass_forward;
|
||||
if(ViButton(mouse_pos, to_from_handle.x, to_from_handle.y, 8.0f, c->pass_backward ? (Color){120, 210, 115, opacity_to} : (Color){232, 50, 32, opacity_to} )) c->pass_backward = !c->pass_backward;
|
||||
|
||||
if(!c->pass_forward){
|
||||
Vec2Df block_point1 = (v1_position - v2_position).norm().orth()*4.0f + from_to_handle;
|
||||
Vec2Df block_point2 = (v1_position - v2_position).norm().orth()*-4.0f + from_to_handle;
|
||||
DrawLineEx(block_point1, block_point2, 2.0f, (Color){232,232,232,opacity_from});
|
||||
}
|
||||
if(ViTexButton(mouse_pos, from_to_handle, HELPER::GetRotation(from_to_handle, to_from_handle) + 90.0f, 8.0f,
|
||||
c->pass_forward ? TEXTURES::tex_blocker_open : TEXTURES::tex_blocker_closed,
|
||||
c->pass_forward ? TEXTURES::tex_blocker_open_hover : TEXTURES::tex_blocker_closed_hover,
|
||||
c->pass_forward ? TEXTURES::tex_blocker_open_pressed : TEXTURES::tex_blocker_closed_pressed,
|
||||
ColorLerp(Fade(VS_COLOR_WHITE, .0f), Fade(VS_COLOR_WHITE, 1.0f), 1.0))) c->pass_forward = !c->pass_forward;
|
||||
|
||||
if(!c->pass_backward){
|
||||
Vec2Df block_point1 = (v1_position - v2_position).norm().orth()*4.0f + to_from_handle;
|
||||
Vec2Df block_point2 = (v1_position - v2_position).norm().orth()*-4.0f + to_from_handle;
|
||||
DrawLineEx(block_point1, block_point2, 2.0f, (Color){232,232,232,opacity_to});
|
||||
}
|
||||
if(ViTexButton(mouse_pos, to_from_handle, HELPER::GetRotation(to_from_handle, from_to_handle) + 90.0f, 8.0f,
|
||||
c->pass_backward ? TEXTURES::tex_blocker_open : TEXTURES::tex_blocker_closed,
|
||||
c->pass_backward ? TEXTURES::tex_blocker_open_hover : TEXTURES::tex_blocker_closed_hover,
|
||||
c->pass_backward ? TEXTURES::tex_blocker_open_pressed : TEXTURES::tex_blocker_closed_pressed,
|
||||
ColorLerp(Fade(VS_COLOR_WHITE, .0f), Fade(VS_COLOR_WHITE, 1.0f), 1.0))) c->pass_backward = !c->pass_backward;
|
||||
|
||||
if(ViButton(mouse_pos, flip_handle_2.x, flip_handle_2.y, 8.0f, (Color){232, 125, 62, opacity} )) splitEdge(c);
|
||||
if(ViTexButton(mouse_pos, split_position, HELPER::GetRotation(from_to_handle, to_from_handle) + 90.0f, 8.0f,
|
||||
TEXTURES::tex_split, TEXTURES::tex_split_hover, TEXTURES::tex_split_pressed, ColorLerp(Fade(VS_COLOR_WHITE, .0f), Fade(VS_COLOR_WHITE, 1.0f), opacity_normalized) )) splitEdge(c);
|
||||
}
|
||||
}
|
||||
if(c->start.lock()->getNodeType() == NodeType::CONFIGNODE || c->end.lock()->getNodeType() == NodeType::CONFIGNODE){
|
||||
DrawLine(v1_position.x, v1_position.y, v2_position.x, v2_position.y, VS_COLOR_BLUE);
|
||||
}
|
||||
|
||||
if(ViButton(mouse_pos, flip_handle.x, flip_handle.y, 8.0f, (Color){232, 50, 32, opacity} )) removeEdge(c);
|
||||
if(IsWindowReady()){
|
||||
if(ViTexButton(mouse_pos, delete_position, HELPER::GetRotation(from_to_handle, to_from_handle), 8.0f,
|
||||
TEXTURES::tex_delete, TEXTURES::tex_delete_hover, TEXTURES::tex_delete_pressed,
|
||||
ColorLerp(Fade(VS_COLOR_WHITE, .0f), Fade(VS_COLOR_WHITE, 1.0f), opacity_normalized) )) removeEdge(c);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -56,6 +56,7 @@ namespace VISEQ::GRAPH {
|
||||
SPTR_Node copyNode(SPTR_Node n, Vec2Df position);
|
||||
SPTR_Node copyNode(std::shared_ptr<MidiNode> n, Vec2Df position);
|
||||
void setNodeMode(int mode);
|
||||
void cycleModeOfSelectedNodes(bool direction);
|
||||
void reset();
|
||||
WPTR_Node getNode(int i);
|
||||
WPTR_Node getFirstNode();
|
||||
@@ -66,6 +67,7 @@ namespace VISEQ::GRAPH {
|
||||
SPTR_Node getClosestNode(Vec2Df position);
|
||||
VEC_WPTR_Node getNodesByID(int _id);
|
||||
WPTR_Edge lastEdge();
|
||||
VEC_WPTR_Edge getPassableConnections(WPTR_Node node);
|
||||
WPTR_Node next(WPTR_Node current, WPTR_Node last);
|
||||
void splitEdge(SPTR_Edge edge);
|
||||
void splitEdges();
|
||||
|
||||
@@ -15,4 +15,8 @@ namespace VISEQ::HELPER{
|
||||
float rotation = Vector2Angle((Vector2){1,0}, (end - start)) * RAD2DEG;
|
||||
DrawTextPro(GetFontDefault(), text.c_str(), text_position, (Vector2){0,0}, rotation, size, 2.0f, col);
|
||||
}
|
||||
|
||||
inline float GetRotation(Vec2Df start, Vec2Df end){
|
||||
return Vector2Angle((Vector2){1,0}, (end - start)) * RAD2DEG;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
#pragma once
|
||||
|
||||
#include "datatypes.h"
|
||||
#include "raylib.h"
|
||||
#include "vmath.h"
|
||||
|
||||
namespace VISEQ::BASE {
|
||||
|
||||
class Interactable{
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include "interactable.h"
|
||||
#include <deque>
|
||||
#include <memory>
|
||||
|
||||
namespace VISEQ::APP{
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
#include "interaction-manager.h"
|
||||
|
||||
#include "clipboard.h"
|
||||
#include "connector.h"
|
||||
#include "datatypes.h"
|
||||
#include "node.h"
|
||||
@@ -14,11 +13,11 @@ namespace VISEQ::INTERACTION{
|
||||
void InteractionManager::update(){
|
||||
if(KEYS_DOWN.ctrl && IsKeyPressed(KEY_C)){
|
||||
VEC_SPTR_Node selected_nodes = gm->getCopiesOfSelectedNodes();
|
||||
if(!selected_nodes.empty()) cb.copyNodes(selected_nodes);
|
||||
if(!selected_nodes.empty()) cb->copyNodes(selected_nodes);
|
||||
}
|
||||
|
||||
if(KEYS_DOWN.ctrl && IsKeyPressed(KEY_V)){
|
||||
VEC_SPTR_Node paste_nodes = cb.pasteNodes();
|
||||
VEC_SPTR_Node paste_nodes = cb->pasteNodes();
|
||||
if(!paste_nodes.empty()) gm->pasteNodesAndEdges(paste_nodes, MOD_MOUSE);
|
||||
}
|
||||
|
||||
@@ -27,13 +26,16 @@ namespace VISEQ::INTERACTION{
|
||||
}
|
||||
|
||||
if(!KEYS_DOWN.shift && IsKeyPressed(KEY_TAB)) {
|
||||
state->node_mode = (state->node_mode + 1) % 7;
|
||||
gm->cycleModeOfSelectedNodes(true);
|
||||
}
|
||||
|
||||
if(KEYS_DOWN.shift && IsKeyPressed(KEY_TAB)) {
|
||||
state->node_mode -= state->node_mode > 0 ? 1 : -6;
|
||||
gm->cycleModeOfSelectedNodes(false);
|
||||
}
|
||||
|
||||
if(IsKeyPressed(KEY_V)){
|
||||
state->draw_edge_lengths = !state->draw_edge_lengths;
|
||||
}
|
||||
}
|
||||
|
||||
void InteractionManager::draw(){
|
||||
@@ -150,8 +152,8 @@ namespace VISEQ::INTERACTION{
|
||||
auto connector = std::dynamic_pointer_cast<Connector>(e.item);
|
||||
if(found && partner != e){
|
||||
auto connector_to = std::dynamic_pointer_cast<Connector>(partner.item);
|
||||
connector->partner = connector_to;
|
||||
connector_to->partner = connector;
|
||||
//connector->partner = connector_to;
|
||||
//connector_to->partner = connector;
|
||||
gm->addConnection(std::dynamic_pointer_cast<Node>(connector->parent.lock()), std::dynamic_pointer_cast<Node>(connector_to->parent.lock()));
|
||||
} else if (partner != e){
|
||||
if(KEYS_DOWN.alt){
|
||||
|
||||
@@ -56,13 +56,14 @@ namespace VISEQ::INTERACTION{
|
||||
std::shared_ptr<APP::CANVAS::Canvas> canvas;
|
||||
std::shared_ptr<GraphManager> gm;
|
||||
std::shared_ptr<SIGNAL::SignalManager> sm;
|
||||
VISEQ::APP::Clipboard cb;
|
||||
|
||||
std::shared_ptr<APP::State> state = APP::State::get();
|
||||
|
||||
Vec2Df scale_start;
|
||||
std::shared_ptr<ScaleHandle> scale_handle = std::make_shared<ScaleHandle>();
|
||||
|
||||
std::shared_ptr<APP::Clipboard> cb = APP::Clipboard::get();
|
||||
|
||||
void update();
|
||||
void draw();
|
||||
void removeNodes(VEC_SPTR_Node nodes);
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
* 2024 Sebastian Kujas
|
||||
*
|
||||
*/
|
||||
#define _USE_MATH_DEFINES
|
||||
|
||||
#define RAYGUI_IMPLEMENTATION
|
||||
#include <raylib.h>
|
||||
@@ -51,16 +52,19 @@ int main(){
|
||||
app.init();
|
||||
app.ui.init();
|
||||
|
||||
app.loadTextures();
|
||||
|
||||
app.loadState();
|
||||
|
||||
app.startSignals();
|
||||
|
||||
while(!WindowShouldClose()){
|
||||
app.update();
|
||||
app.draw();
|
||||
if(IsWindowReady()) app.draw();
|
||||
}
|
||||
|
||||
app.close();
|
||||
app.sm->midi.update();
|
||||
|
||||
CloseWindow();
|
||||
|
||||
|
||||
@@ -3,7 +3,8 @@
|
||||
#include "config-node.h"
|
||||
#include "datatypes.h"
|
||||
#include "edge.h"
|
||||
#include "node-handle.h"
|
||||
#include "interaction-event.h"
|
||||
#include "midi.h"
|
||||
#include "node.h"
|
||||
#include "raylib.h"
|
||||
#include "state.h"
|
||||
@@ -14,35 +15,10 @@
|
||||
namespace VISEQ::GRAPH::NODES {
|
||||
|
||||
void MidiNode::init(){
|
||||
float orbit_1 = radius + 25.0f;
|
||||
float orbit_2 = orbit_1 + 20.0f;
|
||||
float orbit_3 = orbit_2 + 20.0f;
|
||||
float orbit_4 = orbit_3 + 20.0f;
|
||||
float orbit_5 = orbit_4 + 30.0f;
|
||||
|
||||
midiHandles[NOTE].emplace_back(std::make_shared<NodeHandle<int>>(midiNote.note, position, VS_COLOR_GREEN, "NOTE", orbit_5, 12));
|
||||
midiHandles[NOTE].emplace_back(std::make_shared<NodeHandle<int>>(midiNote.channel, position, VS_COLOR_PINK, "CHANNEL", orbit_1, 16, 1, 16, 40, 150));
|
||||
midiHandles[NOTE].emplace_back(std::make_shared<NodeHandle<int>>(midiNote.gate, position, VS_COLOR_RED, "GATE", orbit_3, 30, 10, 30000, 40, 300));
|
||||
midiHandles[NOTE].back()->logScale = true;
|
||||
midiHandles[NOTE].emplace_back(std::make_shared<NodeHandle<int>>(midiNote.velocity, position, VS_COLOR_PURPLE, "VELOCITY", orbit_4, 32));
|
||||
|
||||
midiHandles[CC].emplace_back(std::make_shared<NodeHandle<int>>(midiCC.control, position, VS_COLOR_SUN, "CONTROL", orbit_3, 32));
|
||||
midiHandles[CC].emplace_back(std::make_shared<NodeHandle<int>>(midiCC.channel, position, VS_COLOR_PINK, "CHANNEL", orbit_1, 1, 1, 16, 40, 150));
|
||||
midiHandles[CC].emplace_back(std::make_shared<NodeHandle<int>>(midiCC.value, position, VS_COLOR_GREEN, "VALUE", orbit_4, 32));
|
||||
|
||||
midiHandles[PC].emplace_back(std::make_shared<NodeHandle<int>>(midiPC.program, position, VS_COLOR_SUN, "PROGRAM", orbit_3, 32));
|
||||
midiHandles[PC].emplace_back(std::make_shared<NodeHandle<int>>(midiPC.channel, position, VS_COLOR_PINK, "CHANNEL", orbit_1, 1, 1, 16, 40, 150));
|
||||
midiHandles[PC].emplace_back(std::make_shared<NodeHandle<int>>(midiPC.value, position, VS_COLOR_GREEN, "VALUE", orbit_4, 32));
|
||||
|
||||
midiHandles[PB].emplace_back(std::make_shared<NodeHandle<int>>(midiPitchBend.channel, position, VS_COLOR_PINK, "CHANNEL", orbit_1, 1, 1, 16, 40, 150));
|
||||
midiHandles[PB].emplace_back(std::make_shared<NodeHandle<int>>(midiPitchBend.value, position, VS_COLOR_GREEN, "VALUE", orbit_3, 256, -8192, 8192, 40, 300));
|
||||
|
||||
midiHandles[AT].emplace_back(std::make_shared<NodeHandle<int>>(midiAftertouch.channel, position, VS_COLOR_PINK, "CHANNEL", orbit_1, 1, 1, 16, 40, 150));
|
||||
midiHandles[AT].emplace_back(std::make_shared<NodeHandle<int>>(midiAftertouch.value, position, VS_COLOR_GREEN, "VALUE", orbit_3, 32));
|
||||
|
||||
midiHandles[PP].emplace_back(std::make_shared<NodeHandle<int>>(midiPolyPressure.channel, position, VS_COLOR_PINK, "CHANNEL", orbit_1, 1, 1, 16, 40, 150));
|
||||
midiHandles[PP].emplace_back(std::make_shared<NodeHandle<int>>(midiPolyPressure.value, position, VS_COLOR_GREEN, "VALUE", orbit_4, 32));
|
||||
midiHandles[PP].emplace_back(std::make_shared<NodeHandle<int>>(midiPolyPressure.note, position, VS_COLOR_SUN, "NOTE", orbit_5, 12));
|
||||
midiNote.note = 64;
|
||||
midiNote.channel = 1;
|
||||
midiNote.gate = 250;
|
||||
midiNote.velocity = 64;
|
||||
}
|
||||
|
||||
std::shared_ptr<MidiNode> MidiNode::getPtr(){
|
||||
@@ -54,7 +30,8 @@ namespace VISEQ::GRAPH::NODES {
|
||||
}
|
||||
|
||||
void MidiNode::setMidiPort(int midi_port, bool _state){
|
||||
midi_outs[midi_port].enabled = _state;
|
||||
selected_midi_outs[midi_port].enabled = _state;
|
||||
std::cout << midi_port << " " << _state << std::endl;
|
||||
}
|
||||
|
||||
void MidiNode::trigger() {
|
||||
@@ -128,40 +105,49 @@ namespace VISEQ::GRAPH::NODES {
|
||||
|
||||
void MidiNode::update() {
|
||||
Node::update();
|
||||
mode = state->node_mode;
|
||||
for(auto mh : midiHandles[NOTE]){
|
||||
mh->update(position);
|
||||
}
|
||||
for(auto mh : midiHandles[CC]){
|
||||
mh->update(position);
|
||||
}
|
||||
for(auto mh : midiHandles[PC]){
|
||||
mh->update(position);
|
||||
}
|
||||
for(auto mh : midiHandles[PB]){
|
||||
mh->update(position);
|
||||
}
|
||||
for(auto mh : midiHandles[AT]){
|
||||
mh->update(position);
|
||||
}
|
||||
for(auto mh : midiHandles[PP]){
|
||||
mh->update(position);
|
||||
}
|
||||
}
|
||||
|
||||
void MidiNode::modMidiNote(int incr){
|
||||
void MidiNode::modMidiChannel(int incr){
|
||||
|
||||
}
|
||||
|
||||
void MidiNode::modMidiNoteValue(int incr){
|
||||
midiNote.note += incr;
|
||||
if(midiNote.note < 0 ) midiNote.note = VISEQ::MIDI::Notes.size()-1;
|
||||
if(midiNote.note >= (int)VISEQ::MIDI::Notes.size()) midiNote.note = 0;
|
||||
}
|
||||
|
||||
void MidiNode::modMidiCC(int incr){
|
||||
void MidiNode::modMidiNoteVelocity(int incr){
|
||||
midiNote.velocity += incr;
|
||||
if(midiNote.velocity < 0 ) midiNote.velocity = 127;
|
||||
if(midiNote.velocity > 127 ) midiNote.velocity = 0;
|
||||
}
|
||||
|
||||
void MidiNode::modMidiNoteGate(int incr){
|
||||
midiNote.gate += incr;
|
||||
if(midiNote.gate < 0 ) midiNote.gate = 0;
|
||||
if(midiNote.gate > 20000) midiNote.gate = 20000;
|
||||
}
|
||||
|
||||
void MidiNode::modMidiCCValue(int incr){
|
||||
midiCC.value += incr;
|
||||
if(midiCC.value < 0 ) midiCC.value = 127;
|
||||
if(midiCC.value > 127 ) midiCC.value = 0;
|
||||
}
|
||||
|
||||
void MidiNode::modMidiCCControl(int incr){
|
||||
midiCC.control += incr;
|
||||
if(midiCC.control < 0 ) midiCC.control = 127;
|
||||
if(midiCC.control > 127 ) midiCC.control = 0;
|
||||
}
|
||||
|
||||
void MidiNode::modMidiPC(int incr){
|
||||
void MidiNode::modMidiPCValue(int incr){
|
||||
midiPC.value += incr;
|
||||
if(midiPC.value < 0 ) midiPC.value = 127;
|
||||
if(midiPC.value > 127 ) midiPC.value = 0;
|
||||
}
|
||||
|
||||
void MidiNode::modMidiPCProgram(int incr){
|
||||
midiPC.program += incr;
|
||||
if(midiPC.program < 0 ) midiPC.program = 127;
|
||||
if(midiPC.program > 127 ) midiPC.program = 0;
|
||||
@@ -179,88 +165,73 @@ namespace VISEQ::GRAPH::NODES {
|
||||
if(midiAftertouch.value > 127 ) midiAftertouch.value = 127;
|
||||
}
|
||||
|
||||
void MidiNode::modMidiPolyPressure(int incr){
|
||||
void MidiNode::modMidiPolyPressureValue(int incr){
|
||||
midiPolyPressure.value += incr;
|
||||
if(midiPolyPressure.value < 0 ) midiPolyPressure.value = 0;
|
||||
if(midiPolyPressure.value > 127 ) midiPolyPressure.value = 127;
|
||||
if(midiPolyPressure.value > 16383 ) midiPolyPressure.value = 16383;
|
||||
}
|
||||
|
||||
void MidiNode::modMidiPolyPressureNote(int incr){
|
||||
midiPolyPressure.note += incr;
|
||||
if(midiPolyPressure.note < 0 ) midiPolyPressure.note = VISEQ::MIDI::Notes.size()-1;
|
||||
if(midiPolyPressure.note >= (int)VISEQ::MIDI::Notes.size()) midiPolyPressure.note = 0;
|
||||
}
|
||||
|
||||
void MidiNode::interact(){
|
||||
float wheel = GetMouseWheelMove();
|
||||
|
||||
if(KEYS_DOWN.ctrl && !KEYS_DOWN.alt){
|
||||
switch(state->node_mode){
|
||||
case 0:{
|
||||
modMidiNote(wheel);
|
||||
break;}
|
||||
case 1:{
|
||||
modMidiCC(wheel);
|
||||
break;}
|
||||
case 2:{
|
||||
modMidiPC(wheel);
|
||||
break;}
|
||||
case 3:{
|
||||
modMidiPitchBend(wheel);
|
||||
break;}
|
||||
case 4:{
|
||||
modMidiAftertouch(wheel);
|
||||
break;}
|
||||
case 5:{
|
||||
modMidiPolyPressure(wheel);
|
||||
break;}
|
||||
};
|
||||
} else if(KEYS_DOWN.shift && !KEYS_DOWN.alt) {
|
||||
midiNote.velocity += wheel;
|
||||
if(midiNote.velocity < 0 ) midiNote.velocity = 127;
|
||||
if(midiNote.velocity > 127 ) midiNote.velocity = 0;
|
||||
} else if(KEYS_DOWN.alt) {
|
||||
switch(state->node_mode){
|
||||
case 0:{
|
||||
float incr = (float)wheel * (KEYS_DOWN.shift ? 100.0f : KEYS_DOWN.ctrl ? 1000.0f : 10.0f);
|
||||
midiNote.gate += incr;
|
||||
if(midiNote.gate < 0 ) midiNote.gate = 0;
|
||||
break;}
|
||||
case 1:{
|
||||
midiCC.value += wheel;
|
||||
if(midiCC.value < 0 ) midiCC.value = 0;
|
||||
if(midiCC.value > 127 ) midiCC.value = 127;
|
||||
break;}
|
||||
case 2:{
|
||||
midiPC.value += wheel;
|
||||
if(midiPC.value < 0 ) midiPC.value = 0;
|
||||
if(midiPC.value > 127 ) midiPC.value = 127;
|
||||
break;}
|
||||
case 3:{
|
||||
float incr = (float)wheel * (KEYS_DOWN.shift ? 100.0f : KEYS_DOWN.ctrl ? 1000.0f : 10.0f);
|
||||
midiPitchBend.value += incr;
|
||||
if(midiPitchBend.value < 0 ) midiPitchBend.value = 0;
|
||||
if(midiPitchBend.value > 16383 ) midiPitchBend.value = 16383;
|
||||
break;}
|
||||
case 4:{
|
||||
float incr = (float)wheel * (KEYS_DOWN.shift ? 100.0f : KEYS_DOWN.ctrl ? 1000.0f : 10.0f);
|
||||
midiAftertouch.value += incr;
|
||||
if(midiAftertouch.value < 0 ) midiAftertouch.value = 0;
|
||||
if(midiAftertouch.value > 127 ) midiAftertouch.value = 127;
|
||||
break;}
|
||||
case 5:{
|
||||
float incr = (float)wheel * (KEYS_DOWN.shift ? 100.0f : KEYS_DOWN.ctrl ? 1000.0f : 10.0f);
|
||||
midiPolyPressure.value += incr;
|
||||
if(midiPolyPressure.value < 0 ) midiPolyPressure.value = 0;
|
||||
if(midiPolyPressure.value > 127 ) midiPolyPressure.value = 127;
|
||||
break;}
|
||||
};
|
||||
}
|
||||
switch(mode){
|
||||
case NOTE:{
|
||||
if(state->isModChain(APP::CTRL)) modMidiNoteValue(wheel);
|
||||
if(state->isModChain(APP::CTRL, APP::SHIFT)) modMidiNoteValue(wheel*12);
|
||||
if(state->isModChain(APP::CTRL, APP::ALT)) modMidiNoteValue(wheel*12);
|
||||
if(state->isModChain(APP::CTRL, APP::SHIFT, APP::ALT)) modMidiNoteValue(wheel*24);
|
||||
if(state->isModChain(APP::CTRL, APP::ALT, APP::SHIFT)) modMidiNoteValue(wheel*24);
|
||||
|
||||
if(state->isModChain(APP::SHIFT)) modMidiNoteVelocity(wheel);
|
||||
if(state->isModChain(APP::SHIFT, APP::CTRL)) modMidiNoteVelocity(wheel*16);
|
||||
if(state->isModChain(APP::SHIFT, APP::ALT)) modMidiNoteVelocity(wheel*16);
|
||||
if(state->isModChain(APP::SHIFT, APP::CTRL, APP::ALT)) modMidiNoteVelocity(wheel*32);
|
||||
if(state->isModChain(APP::SHIFT, APP::ALT, APP::CTRL)) modMidiNoteVelocity(wheel*32);
|
||||
|
||||
if(state->isModChain(APP::ALT)) modMidiNoteGate(wheel*100);
|
||||
if(state->isModChain(APP::ALT, APP::CTRL)) modMidiNoteGate(wheel*1000);
|
||||
if(state->isModChain(APP::ALT, APP::SHIFT)) modMidiNoteGate(wheel*10);
|
||||
if(state->isModChain(APP::ALT, APP::SHIFT, APP::CTRL)) modMidiNoteGate(wheel);
|
||||
break;}
|
||||
case CC:{
|
||||
if(KEYS_DOWN.ctrl && !KEYS_DOWN.shift && !KEYS_DOWN.alt) modMidiCCValue(wheel);
|
||||
if(!KEYS_DOWN.ctrl && KEYS_DOWN.shift && !KEYS_DOWN.alt) modMidiCCControl(wheel);
|
||||
break;}
|
||||
case PC:{
|
||||
if(KEYS_DOWN.ctrl && !KEYS_DOWN.shift && !KEYS_DOWN.alt) modMidiPCValue(wheel);
|
||||
break;}
|
||||
case PB:{
|
||||
if(!KEYS_DOWN.ctrl && !KEYS_DOWN.shift && KEYS_DOWN.alt) modMidiPitchBend(wheel*64);
|
||||
if(KEYS_DOWN.ctrl && !KEYS_DOWN.shift && KEYS_DOWN.alt) modMidiPitchBend(wheel*2048);
|
||||
if(!KEYS_DOWN.ctrl && KEYS_DOWN.shift && KEYS_DOWN.alt) modMidiPitchBend(wheel*256);
|
||||
if(KEYS_DOWN.ctrl && KEYS_DOWN.shift && KEYS_DOWN.alt) modMidiPitchBend(wheel);
|
||||
break;}
|
||||
case AT:{
|
||||
if(!KEYS_DOWN.ctrl && !KEYS_DOWN.shift && KEYS_DOWN.alt) modMidiAftertouch(wheel*10);
|
||||
if(KEYS_DOWN.ctrl && !KEYS_DOWN.shift && KEYS_DOWN.alt) modMidiAftertouch(wheel*100);
|
||||
if(KEYS_DOWN.ctrl && KEYS_DOWN.shift && KEYS_DOWN.alt) modMidiAftertouch(wheel);
|
||||
break;}
|
||||
case PP:{
|
||||
if(!KEYS_DOWN.ctrl && KEYS_DOWN.shift && !KEYS_DOWN.alt) modMidiPolyPressureNote(wheel);
|
||||
if(!KEYS_DOWN.ctrl && !KEYS_DOWN.shift && !KEYS_DOWN.alt) modMidiPolyPressureNote(wheel*10);
|
||||
|
||||
if(!KEYS_DOWN.ctrl && !KEYS_DOWN.shift && KEYS_DOWN.alt) modMidiPolyPressureValue(wheel*64);
|
||||
if(KEYS_DOWN.ctrl && !KEYS_DOWN.shift && KEYS_DOWN.alt) modMidiPolyPressureValue(wheel*2048);
|
||||
if(!KEYS_DOWN.ctrl && KEYS_DOWN.shift && KEYS_DOWN.alt) modMidiPolyPressureValue(wheel*256);
|
||||
if(KEYS_DOWN.ctrl && KEYS_DOWN.shift && KEYS_DOWN.alt) modMidiPolyPressureValue(wheel);
|
||||
break;}
|
||||
};
|
||||
}
|
||||
|
||||
void MidiNode::draw(Vec2Df mouse, Camera2D cam) {
|
||||
Node::draw();
|
||||
|
||||
for(int i = 0; i < 6; ++i){
|
||||
for(auto mh : midiHandles[(Handles)i]){
|
||||
mh->lock();
|
||||
}
|
||||
}
|
||||
|
||||
if(hovering() || selected) interact();
|
||||
|
||||
last = time;
|
||||
@@ -272,60 +243,127 @@ namespace VISEQ::GRAPH::NODES {
|
||||
fade -= (time - last)*1000.0f;
|
||||
}
|
||||
|
||||
DrawRing(position, radius, radius + 4, 0, 360, 24, (Color){60, 60, 60, 255});
|
||||
DrawRing(position, radius, radius + 4, 0.0f - 90.0f, (360.0f/127.0f) * getNotes().velocity - 90.0f, 24, (Color){158, 134, 200, 255});
|
||||
DrawCircleLinesV(position, radius + 4, (Color){100, 100, 100, 255});
|
||||
switch((Handles)mode){
|
||||
case NOTE:{
|
||||
radius = (float)midiNote.velocity * 0.2f + 15.0f;
|
||||
break;}
|
||||
case CC:{
|
||||
radius = (float)midiCC.value * 0.2f + 15.0f;
|
||||
break;}
|
||||
case PC:{
|
||||
radius = (float)midiPC.value * 0.2f + 15.0f;
|
||||
break;}
|
||||
case PB:{
|
||||
radius = (float)midiPitchBend.value * 0.002f + 15.0f;
|
||||
break;}
|
||||
case AT:{
|
||||
radius = (float)midiAftertouch.value * 0.002f + 15.0f;
|
||||
break;}
|
||||
case PP:{
|
||||
radius = (float)midiPolyPressure.value * 0.002f + 15.0f;
|
||||
break;}
|
||||
}
|
||||
|
||||
if(!selected) DrawCircle(position.x, position.y, radius, state->settings.mode_colors[mode]);
|
||||
if(selected) DrawCircle(position.x, position.y, radius, VS_COLOR_LIGHTBLUE);
|
||||
|
||||
float trigger_alpha = (1.f / getNotes().gate) * fade;
|
||||
|
||||
if(!picked_up && !selected && !in_selection_rect && !hovering()) DrawCircle(position.x, position.y, radius, ColorLerp(state->mode_color, VS_COLOR_RED, trigger_alpha));
|
||||
if(picked_up || in_selection_rect || hovering()) DrawCircle(position.x, position.y, radius, (Color){108, 153, 187, 255});
|
||||
if(selected) DrawCircle(position.x, position.y, radius, (Color){255, 153, 187, 255});
|
||||
if(!selected && !pickedUp() && !hovering()) DrawRing(position, radius, radius + 3, 0, 360, 24, VS_COLOR_GREY);
|
||||
DrawRing(position, radius, radius + 3, 0, 360, 24, ColorLerp(VS_COLOR_GREY, VS_COLOR_RED, trigger_alpha));
|
||||
if(selected) DrawRing(position, radius, radius + 3, 0, 360, 24, VS_COLOR_RED);
|
||||
if(picked_up || (in_selection_rect && MOUSE_LEFT.down) || selected) DrawRing(position, radius, radius + 3, 0, 360, 24, VS_COLOR_LIGHTBLUE);
|
||||
if(hovering()) DrawRing(position, radius, radius + 3, 0, 360, 24, VS_COLOR_PINK);
|
||||
|
||||
DrawCircleLinesV(position, radius + 3, VS_COLOR_LIGHTGREY);
|
||||
|
||||
|
||||
//if(hovering()) DrawCircleLinesV(position, radius + 4, VS_COLOR_PINK);
|
||||
|
||||
if(distributionMode == Distribution::RANDOM) DrawCircle(position.x, position.y, radius/2.0f, VS_COLOR_PINK);
|
||||
if(distributionMode == Distribution::ROUNDROBIN) DrawCircle(position.x, position.y, radius/2.0f, VS_COLOR_YELLOW);
|
||||
|
||||
if(selected) DrawCircleLinesV(position, radius+8, (Color){158, 255, 210, 255});
|
||||
bool modified = false;
|
||||
if(selected && mode >= 0 && mode < 6){
|
||||
for(auto mh : midiHandles[(Handles)mode]){
|
||||
mh->unlock();
|
||||
mh->draw();
|
||||
std::string text = "";
|
||||
if(mh->hovering() || mh->picked_up){
|
||||
text = std::format("{}", mh->assignedValueRef);
|
||||
if(mh->name == "NOTE") text = MIDI::Notes[mh->assignedValueRef];
|
||||
if(mh->name == "GATE") text = std::format("{:.2f}", mh->assignedValueRef / 1000.0f);
|
||||
if(mh->name == "VALUE" && (Handles)mode == PB) text = std::format("{}", round(((float)mh->assignedValueRef / 8192.0f) * 100));
|
||||
DrawCenteredText(text, position, 12, WHITE);
|
||||
modified = true;
|
||||
|
||||
VMATH::Vec2D<float> desc_position = position + VMATH::Vec2D<float>(radius + 7.0f, radius + 7.0f);
|
||||
switch(mode){
|
||||
case NOTE:{
|
||||
if(state->isModChainStart(APP::CTRL) || state->modifier_chain.size() == 0) DrawCenteredText(MIDI::Notes[getNotes().note], position, 14, VS_COLOR_DARKGREY);
|
||||
if(state->isModChainStart(APP::SHIFT)) DrawCenteredText(std::format("{}", getNotes().velocity), position, 12, VS_COLOR_DARKGREY);
|
||||
|
||||
if(state->isModChain(APP::ALT)) DrawCenteredText(std::format("{:.1f}s", (float)getNotes().gate / 1000.f), position, 12, VS_COLOR_DARKGREY);
|
||||
if(state->isModChainStart(APP::ALT, APP::CTRL)) DrawCenteredText(std::format("{:.2f}s", (float)getNotes().gate / 1000.f), position, 12, VS_COLOR_DARKGREY);
|
||||
if(state->isModChain(APP::ALT, APP::SHIFT)) DrawCenteredText(std::format("{:.2f}s", (float)getNotes().gate / 1000.f), position, 12, VS_COLOR_DARKGREY);
|
||||
if(state->isModChain(APP::ALT, APP::SHIFT, APP::CTRL)) DrawCenteredText(std::format("{:.3f}s", (float)getNotes().gate / 1000.f), position, 12, VS_COLOR_DARKGREY);
|
||||
|
||||
if(selected || hovering()){
|
||||
if(state->isModChain(APP::CTRL)) DrawText("NOTE +1", desc_position, 8, VS_COLOR_WHITE);
|
||||
if(state->isModChain(APP::CTRL, APP::SHIFT)) DrawText("NOTE +12", desc_position, 8, VS_COLOR_WHITE);
|
||||
if(state->isModChain(APP::CTRL, APP::ALT)) DrawText("NOTE +12", desc_position, 8, VS_COLOR_WHITE);
|
||||
if(state->isModChain(APP::CTRL, APP::SHIFT, APP::ALT)) DrawText("NOTE +24", desc_position, 8, VS_COLOR_WHITE);
|
||||
if(state->isModChain(APP::CTRL, APP::ALT, APP::SHIFT)) DrawText("NOTE +24", desc_position, 8, VS_COLOR_WHITE);
|
||||
|
||||
if(state->isModChain(APP::SHIFT)) DrawText("VELOCITY +1", desc_position, 8, VS_COLOR_WHITE);
|
||||
if(state->isModChain(APP::SHIFT, APP::CTRL)) DrawText("VELOCITY +16", desc_position, 8, VS_COLOR_WHITE);
|
||||
if(state->isModChain(APP::SHIFT, APP::ALT)) DrawText("VELOCITY +16", desc_position, 8, VS_COLOR_WHITE);
|
||||
if(state->isModChain(APP::SHIFT, APP::CTRL, APP::ALT)) DrawText("VELOCITY +32", desc_position, 8, VS_COLOR_WHITE);
|
||||
if(state->isModChain(APP::SHIFT, APP::ALT, APP::CTRL)) DrawText("VELOCITY +32", desc_position, 8, VS_COLOR_WHITE);
|
||||
|
||||
if(state->isModChain(APP::ALT)) DrawText("GATE 0.1s", desc_position, 8, VS_COLOR_WHITE);
|
||||
if(state->isModChainStart(APP::ALT, APP::CTRL)) DrawText("GATE 1.0s", desc_position, 8, VS_COLOR_WHITE);
|
||||
if(state->isModChain(APP::ALT, APP::SHIFT)) DrawText("GATE 0.01s", desc_position, 8, VS_COLOR_WHITE);
|
||||
if(state->isModChain(APP::ALT, APP::SHIFT, APP::CTRL)) DrawText("GATE 0.001s", desc_position, 8, VS_COLOR_WHITE);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;}
|
||||
case CC:{
|
||||
if(!KEYS_DOWN.shift) DrawCenteredText(std::format("{}", getCC().value), position, 12, VS_COLOR_DARKGREY);
|
||||
if(!KEYS_DOWN.ctrl && KEYS_DOWN.shift && !KEYS_DOWN.alt) DrawCenteredText(std::format("{}", getCC().control), position, 12, VS_COLOR_WHITE);
|
||||
if(selected){
|
||||
if(!KEYS_DOWN.ctrl && !KEYS_DOWN.shift && !KEYS_DOWN.alt) DrawText("CC", desc_position, 8, VS_COLOR_WHITE);
|
||||
if(KEYS_DOWN.ctrl && !KEYS_DOWN.shift && !KEYS_DOWN.alt) DrawText("VALUE", desc_position, 8, VS_COLOR_WHITE);
|
||||
if(!KEYS_DOWN.ctrl && KEYS_DOWN.shift && !KEYS_DOWN.alt) DrawText("CONTROL", desc_position, 8, VS_COLOR_WHITE);
|
||||
}
|
||||
break;}
|
||||
case PC:{
|
||||
if(!KEYS_DOWN.shift) DrawCenteredText(std::format("{}", getPC().value), position, 12, VS_COLOR_DARKGREY);
|
||||
if(selected){
|
||||
if(!KEYS_DOWN.ctrl && !KEYS_DOWN.shift && !KEYS_DOWN.alt) DrawText("PROGRAM CHANGE", desc_position, 8, VS_COLOR_WHITE);
|
||||
if(KEYS_DOWN.ctrl && !KEYS_DOWN.shift && !KEYS_DOWN.alt) DrawText("PROGRAM", desc_position, 8, VS_COLOR_WHITE);
|
||||
}
|
||||
break;}
|
||||
case PB:{
|
||||
DrawCenteredText(std::format("{}", getPitchBend().value), position, 10, VS_COLOR_DARKGREY);
|
||||
if(selected){
|
||||
if(!KEYS_DOWN.ctrl && !KEYS_DOWN.shift && !KEYS_DOWN.alt) DrawText("PITCHBEND", desc_position, 8, VS_COLOR_WHITE);
|
||||
if(!KEYS_DOWN.ctrl && !KEYS_DOWN.shift && KEYS_DOWN.alt) DrawText("64", desc_position, 8, VS_COLOR_WHITE);
|
||||
if(KEYS_DOWN.ctrl && !KEYS_DOWN.shift && KEYS_DOWN.alt) DrawText("2048", desc_position, 8, VS_COLOR_WHITE);
|
||||
if(!KEYS_DOWN.ctrl && KEYS_DOWN.shift && KEYS_DOWN.alt) DrawText("256", desc_position, 8, VS_COLOR_WHITE);
|
||||
if(KEYS_DOWN.ctrl && KEYS_DOWN.shift && KEYS_DOWN.alt) DrawText("1", desc_position, 8, VS_COLOR_WHITE);
|
||||
}
|
||||
break;}
|
||||
case AT:{
|
||||
DrawCenteredText(std::format("{}", getAftertouch().value), position, 12, VS_COLOR_DARKGREY);
|
||||
if(selected){
|
||||
if(!KEYS_DOWN.ctrl && !KEYS_DOWN.shift && !KEYS_DOWN.alt) DrawText("AFTERTOUCH", desc_position, 8, VS_COLOR_WHITE);
|
||||
if(!KEYS_DOWN.ctrl && !KEYS_DOWN.shift && KEYS_DOWN.alt) DrawText("10", desc_position, 8, VS_COLOR_WHITE);
|
||||
if(KEYS_DOWN.ctrl && !KEYS_DOWN.shift && KEYS_DOWN.alt) DrawText("100", desc_position, 8, VS_COLOR_WHITE);
|
||||
if(KEYS_DOWN.ctrl && KEYS_DOWN.shift && KEYS_DOWN.alt) DrawText("1", desc_position, 8, VS_COLOR_WHITE);
|
||||
}
|
||||
break;}
|
||||
case PP:{
|
||||
if(!KEYS_DOWN.ctrl && KEYS_DOWN.shift && !KEYS_DOWN.alt) DrawCenteredText(MIDI::Notes[getPolyPressure().note], position, 12, VS_COLOR_DARKGREY);
|
||||
|
||||
if(!modified){
|
||||
switch((Handles)mode){
|
||||
case NOTE:{
|
||||
DrawCenteredText(MIDI::Notes[getNotes().note], position, 12, WHITE);
|
||||
break;}
|
||||
case CC:{
|
||||
DrawCenteredText(std::format("{}", getCC().value), position, 12, WHITE);
|
||||
break;}
|
||||
case PC:{
|
||||
DrawCenteredText(std::format("{}", getPC().value), position, 12, WHITE);
|
||||
break;}
|
||||
case PB:{
|
||||
DrawCenteredText(std::format("{}", round(((float)getPitchBend().value / 8192.0f) * 100)), position, 12, WHITE);
|
||||
break;}
|
||||
case AT:{
|
||||
DrawCenteredText(std::format("{}", getAftertouch().value), position, 12, WHITE);
|
||||
break;}
|
||||
case PP:{
|
||||
DrawCenteredText(std::format("{}", getPolyPressure().value), position, 12, WHITE);
|
||||
break;}
|
||||
}
|
||||
|
||||
}
|
||||
if(!KEYS_DOWN.ctrl && !KEYS_DOWN.shift && KEYS_DOWN.alt) DrawCenteredText(std::format("{}", getPolyPressure().value), position, 12, VS_COLOR_DARKGREY);
|
||||
if(KEYS_DOWN.ctrl && !KEYS_DOWN.shift && KEYS_DOWN.alt) DrawCenteredText(std::format("{}", getPolyPressure().value), position, 12, VS_COLOR_DARKGREY);
|
||||
if(KEYS_DOWN.ctrl && KEYS_DOWN.shift && KEYS_DOWN.alt) DrawCenteredText(std::format("{}", getPolyPressure().value), position, 12, VS_COLOR_DARKGREY);
|
||||
if(selected){
|
||||
if(!KEYS_DOWN.ctrl && !KEYS_DOWN.shift && !KEYS_DOWN.alt) DrawText("POLYPRESSURE", desc_position, 8, VS_COLOR_WHITE);
|
||||
if(!KEYS_DOWN.ctrl && !KEYS_DOWN.shift && KEYS_DOWN.alt) DrawText("64", desc_position, 8, VS_COLOR_WHITE);
|
||||
if(KEYS_DOWN.ctrl && !KEYS_DOWN.shift && KEYS_DOWN.alt) DrawText("2048", desc_position, 8, VS_COLOR_WHITE);
|
||||
if(!KEYS_DOWN.ctrl && KEYS_DOWN.shift && KEYS_DOWN.alt) DrawText("256", desc_position, 8, VS_COLOR_WHITE);
|
||||
if(KEYS_DOWN.ctrl && KEYS_DOWN.shift && KEYS_DOWN.alt) DrawText("1", desc_position, 8, VS_COLOR_WHITE);
|
||||
}
|
||||
break;}
|
||||
};
|
||||
|
||||
if(highlighted) DrawCircleLinesV(position, radius+2, (Color){255, 0, 0, 200});
|
||||
}
|
||||
@@ -334,15 +372,6 @@ namespace VISEQ::GRAPH::NODES {
|
||||
std::vector<int> conns;
|
||||
std::ranges::transform(N.connections.begin(), N.connections.end(), std::back_inserter(conns), [](VISEQ::GRAPH::EDGES::SPTR_Edge e){ return e->id;});
|
||||
|
||||
std::vector<std::vector<Vec2Df>> handles;
|
||||
|
||||
for(auto i : N.midiHandles){
|
||||
handles.emplace_back();
|
||||
for(auto n : i.second){
|
||||
handles.at(i.first).push_back(n->position);
|
||||
}
|
||||
}
|
||||
|
||||
j = json{
|
||||
{"id", N.id},
|
||||
{"position", N.position},
|
||||
@@ -354,7 +383,6 @@ namespace VISEQ::GRAPH::NODES {
|
||||
{"midiPitchBend", N.midiPitchBend},
|
||||
{"midiAftertouch", N.midiAftertouch},
|
||||
{"midiPolyPressure", N.midiPolyPressure},
|
||||
{"handles", handles},
|
||||
{"connections",conns}};
|
||||
|
||||
}
|
||||
@@ -372,20 +400,6 @@ namespace VISEQ::GRAPH::NODES {
|
||||
j.at("midiPitchBend").get_to(N.midiPitchBend);
|
||||
j.at("midiAftertouch").get_to(N.midiAftertouch);
|
||||
j.at("midiPolyPressure").get_to(N.midiPolyPressure);
|
||||
|
||||
std::vector<std::vector<Vec2Df>> handles;
|
||||
|
||||
j.at("handles").get_to(handles);
|
||||
|
||||
int i = 0;
|
||||
for(auto n : handles){
|
||||
int j = 0;
|
||||
for(auto nn : n){
|
||||
N.midiHandles[(Handles)i][j]->position = nn;
|
||||
j++;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
void to_json(json& j, const std::shared_ptr<MidiNode>& N){
|
||||
|
||||
@@ -27,14 +27,12 @@ namespace VISEQ::GRAPH::NODES {
|
||||
MIDI::MidiAftertouch midiAftertouch;
|
||||
MIDI::MidiPolyPressure midiPolyPressure;
|
||||
|
||||
std::map<Handles, std::vector<std::shared_ptr<NodeHandle<int>>>> midiHandles;
|
||||
|
||||
public:
|
||||
|
||||
struct NodeMidiOut{
|
||||
int i;
|
||||
std::string name;
|
||||
bool enabled;
|
||||
std::string name;
|
||||
};
|
||||
|
||||
MidiNode() {init();}
|
||||
@@ -48,10 +46,12 @@ namespace VISEQ::GRAPH::NODES {
|
||||
bool send_cc = false;
|
||||
bool send_pc = false;
|
||||
bool send_pitch_bend = false;
|
||||
bool send_aftertouch = false;
|
||||
bool send_polypressure = false;
|
||||
|
||||
int midi_out = -1;
|
||||
|
||||
std::map<int, NodeMidiOut> midi_outs;
|
||||
std::map<int, NodeMidiOut> selected_midi_outs;
|
||||
|
||||
bool gui_midi_channel_edit = false;
|
||||
bool gui_midi_note_edit = false;
|
||||
@@ -77,12 +77,18 @@ namespace VISEQ::GRAPH::NODES {
|
||||
MIDI::MidiPolyPressure getPolyPressure() const ;
|
||||
std::vector<std::weak_ptr<ConfigNode>> getConnectedConfigNodes() const ;
|
||||
void update() override ;
|
||||
void modMidiNote(int incr);
|
||||
void modMidiCC(int incr);
|
||||
void modMidiPC(int incr);
|
||||
void modMidiChannel(int incr);
|
||||
void modMidiNoteValue(int incr);
|
||||
void modMidiNoteVelocity(int incr);
|
||||
void modMidiNoteGate(int incr);
|
||||
void modMidiCCValue(int incr);
|
||||
void modMidiCCControl(int incr);
|
||||
void modMidiPCValue(int incr);
|
||||
void modMidiPCProgram(int incr);
|
||||
void modMidiPitchBend(int incr);
|
||||
void modMidiAftertouch(int incr);
|
||||
void modMidiPolyPressure(int incr);
|
||||
void modMidiPolyPressureValue(int incr);
|
||||
void modMidiPolyPressureNote(int incr);
|
||||
void interact();
|
||||
void draw(Vec2Df mouse, Camera2D cam) override ;
|
||||
|
||||
|
||||
@@ -4,27 +4,31 @@
|
||||
#include "raylib.h"
|
||||
|
||||
#include <iostream>
|
||||
#include <libremidi/message.hpp>
|
||||
#include <memory>
|
||||
#include <sstream>
|
||||
#include "datatypes.h"
|
||||
|
||||
namespace VISEQ::MIDI {
|
||||
|
||||
void Midi::init(){
|
||||
auto out_conf = libremidi::midi1::out_default_configuration();
|
||||
for(int i = 0; i < 5; i++){
|
||||
std::ostringstream port_name;
|
||||
port_name << "viseq midi out " << i;
|
||||
virtual_midi_out_ports.push_back({i+2000, false, port_name.str()});
|
||||
}
|
||||
}
|
||||
|
||||
void Midi::enumerate(){
|
||||
std::cout << (int)obs.get_current_api() << std::endl;
|
||||
|
||||
|
||||
int i = 0;
|
||||
midi_out_ports.clear();
|
||||
for(const libremidi::output_port& port : obs.get_output_ports()){
|
||||
midi_out_ports.push_back({port, i, false});
|
||||
i++;
|
||||
}
|
||||
|
||||
auto out_conf = libremidi::midi1::out_default_configuration();
|
||||
virtual_midi_out = libremidi::midi_out(libremidi::output_configuration(), out_conf);
|
||||
virtual_midi_out.open_virtual_port("viseq out");
|
||||
|
||||
//midi_out_ports.push_back({&virtual_midi_out, 99, false});
|
||||
}
|
||||
|
||||
void Midi::open_midi_out(MidiOutPort *out_port){
|
||||
@@ -42,6 +46,21 @@ namespace VISEQ::MIDI {
|
||||
}
|
||||
}
|
||||
|
||||
void Midi::open_midi_out(VirtualMidiOutPort *out_port){
|
||||
if(!midi_outs.contains(out_port->number)){
|
||||
auto out = std::make_shared<libremidi::midi_out>();
|
||||
out->open_virtual_port(out_port->name);
|
||||
midi_outs[out_port->number] = out;
|
||||
}
|
||||
}
|
||||
|
||||
void Midi::close_midi_out(VirtualMidiOutPort *out_port){
|
||||
if(midi_outs.contains(out_port->number)){
|
||||
midi_outs[out_port->number]->close_port();
|
||||
midi_outs.erase(out_port->number);
|
||||
}
|
||||
}
|
||||
|
||||
void Midi::note(int midi_out, int channel, int note, int velocity, int gate){
|
||||
if(midi_outs.contains(midi_out)){
|
||||
if(midi_outs[midi_out]->is_port_open()){
|
||||
@@ -49,8 +68,6 @@ namespace VISEQ::MIDI {
|
||||
notes.emplace_back(midi_out, channel, note, velocity, GetTime(), gate);
|
||||
}
|
||||
}
|
||||
virtual_midi_out.send_message(libremidi::channel_events::note_on(channel, note, velocity));
|
||||
notes.emplace_back(99, channel, note, velocity, GetTime(), gate);
|
||||
}
|
||||
|
||||
void Midi::cc(int midi_out, int channel, int cc, int value){
|
||||
@@ -61,6 +78,14 @@ namespace VISEQ::MIDI {
|
||||
}
|
||||
}
|
||||
|
||||
void Midi::pc(int midi_out, int channel, int value){
|
||||
if(midi_outs.contains(midi_out)){
|
||||
if(midi_outs[midi_out]->is_port_open()){
|
||||
midi_outs[midi_out]->send_message(libremidi::channel_events::program_change(channel, value));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Midi::pitch_bend(int midi_out, int channel, int pitch_value){
|
||||
if(midi_outs.contains(midi_out)){
|
||||
if(midi_outs[midi_out]->is_port_open()){
|
||||
@@ -69,17 +94,48 @@ namespace VISEQ::MIDI {
|
||||
}
|
||||
}
|
||||
|
||||
void Midi::aftertouch(int midi_out, int channel, int aftertouch_value){
|
||||
if(midi_outs.contains(midi_out)){
|
||||
if(midi_outs[midi_out]->is_port_open()){
|
||||
midi_outs[midi_out]->send_message(libremidi::channel_events::aftertouch(channel, aftertouch_value));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Midi::polypressure(int midi_out, int channel, int note, int polypressure_value){
|
||||
if(midi_outs.contains(midi_out)){
|
||||
if(midi_outs[midi_out]->is_port_open()){
|
||||
midi_outs[midi_out]->send_message(libremidi::channel_events::poly_pressure(channel, note, polypressure_value));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Midi::all_notes_off(){
|
||||
for(auto &n : notes){
|
||||
if(midi_outs.contains(n.midi_out) && midi_outs[n.midi_out]->is_port_open()) midi_outs[n.midi_out]->send_message(libremidi::channel_events::note_off(n.channel, n.note, n.velocity));
|
||||
n.erase = true;
|
||||
}
|
||||
std::erase_if(notes, [](const auto& item){return item.erase;});
|
||||
}
|
||||
|
||||
void Midi::update(){
|
||||
float time = GetTime();
|
||||
for(auto &n : notes){
|
||||
if(time - n.start >= (float)n.gate / 1000.0f){
|
||||
if(midi_outs.contains(n.midi_out) && midi_outs[n.midi_out]->is_port_open()) midi_outs[n.midi_out]->send_message(libremidi::channel_events::note_off(n.channel, n.note, n.velocity));
|
||||
virtual_midi_out.send_message(libremidi::channel_events::note_off(n.channel, n.note, n.velocity));
|
||||
n.erase = true;
|
||||
}
|
||||
}
|
||||
std::erase_if(notes, [](const auto& item){return item.erase;});
|
||||
|
||||
for(auto& p : virtual_midi_out_ports){
|
||||
if(p.enabled) {
|
||||
open_midi_out(&p);
|
||||
} else if(!p.enabled) {
|
||||
close_midi_out(&p);
|
||||
}
|
||||
}
|
||||
|
||||
for(auto& p : midi_out_ports){
|
||||
if(p.enabled) {
|
||||
open_midi_out(&p);
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include "libremidi/libremidi.hpp"
|
||||
#include "libremidi/observer_configuration.hpp"
|
||||
|
||||
#include <libremidi/configurations.hpp>
|
||||
#include <libremidi/defaults.hpp>
|
||||
@@ -26,6 +25,7 @@ namespace VISEQ::MIDI {
|
||||
|
||||
public:
|
||||
Midi() {
|
||||
init();
|
||||
enumerate();
|
||||
}
|
||||
|
||||
@@ -34,19 +34,27 @@ namespace VISEQ::MIDI {
|
||||
std::map<int, std::shared_ptr<libremidi::midi_out>> midi_outs;
|
||||
std::vector<libremidi::input_port> midi_in_ports;
|
||||
std::vector<MidiOutPort> midi_out_ports;
|
||||
std::vector<VirtualMidiOutPort> virtual_midi_out_ports;
|
||||
|
||||
libremidi::midi_out virtual_midi_out;
|
||||
|
||||
std::vector<NoteTimer> notes;
|
||||
|
||||
float timer;
|
||||
|
||||
void init();
|
||||
|
||||
void enumerate();
|
||||
void open_midi_out(MidiOutPort *out_port);
|
||||
void close_midi_out(MidiOutPort *out_port);
|
||||
void open_midi_out(VirtualMidiOutPort *out_port);
|
||||
void close_midi_out(VirtualMidiOutPort *out_port);
|
||||
void note(int midi_out, int channel, int note, int velocity, int gate);
|
||||
void cc(int midi_out, int channel, int cc, int value);
|
||||
void pc(int midi_out, int channel, int value);
|
||||
void pitch_bend(int midi_out, int channel, int pitch_value);
|
||||
void aftertouch(int midi_out, int channel, int aftertouch_value);
|
||||
void polypressure(int midi_out, int channel, int note, int polypressure_value);
|
||||
void all_notes_off();
|
||||
void update();
|
||||
};
|
||||
|
||||
|
||||
@@ -85,14 +85,14 @@ namespace VISEQ::GRAPH::NODES {
|
||||
|
||||
void ModNode::update() {
|
||||
Node::update();
|
||||
mode = state->node_mode;
|
||||
//mode = state->node_mode;
|
||||
}
|
||||
|
||||
void ModNode::interact(){
|
||||
float wheel = GetMouseWheelMove();
|
||||
|
||||
if(KEYS_DOWN.ctrl && !KEYS_DOWN.alt){
|
||||
switch(state->node_mode){
|
||||
switch(mode){
|
||||
case 0:{
|
||||
midiNote.note += KEYS_DOWN.shift ? ((wheel > 0) - (wheel < 0)) * 12 : wheel;
|
||||
break;}
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "state.h"
|
||||
//#include "state.h"
|
||||
#include "vmath.h"
|
||||
#include <memory>
|
||||
|
||||
namespace VISEQ::BASE {
|
||||
class Movable{
|
||||
@@ -14,7 +13,7 @@ namespace VISEQ::BASE {
|
||||
Movable(Vec2Df p, Vec2Df d, float s) : speed(s), position(p), direction(d) {}
|
||||
Movable(Vec2Df p, float s) : speed(s), position(p) {}
|
||||
|
||||
std::shared_ptr<APP::State> state = APP::State::get();
|
||||
// std::shared_ptr<APP::State> state = APP::State::get();
|
||||
|
||||
float speed = 960.0f;
|
||||
|
||||
|
||||
@@ -63,6 +63,16 @@ namespace VISEQ::GRAPH::NODES {
|
||||
c->update();
|
||||
}
|
||||
if(free_connectors == 0) addConnector();
|
||||
in_selection_rect = CheckCollisionPointRec(position, state->selection);
|
||||
}
|
||||
|
||||
std::weak_ptr<Connector> Node::getConnector(){
|
||||
for(auto c : connectors){
|
||||
if(c->partner.expired()) {
|
||||
return c;
|
||||
}
|
||||
}
|
||||
return connectors.back();
|
||||
}
|
||||
|
||||
void Node::draw(Vec2Df mp, Camera2D cam) {}
|
||||
@@ -73,6 +83,14 @@ namespace VISEQ::GRAPH::NODES {
|
||||
}
|
||||
}
|
||||
|
||||
void Node::cycleMode(bool direction){
|
||||
if(direction){
|
||||
mode = (mode + 1) % 6;
|
||||
} else {
|
||||
mode -= mode > 0 ? 1 : -5;
|
||||
}
|
||||
}
|
||||
|
||||
void to_json(json& j, const Node& N){
|
||||
if(N.getNodeType() == NodeType::MIDINODE){
|
||||
j = dynamic_cast<const MidiNode&>(N);
|
||||
|
||||
@@ -44,6 +44,7 @@ namespace VISEQ::GRAPH::NODES {
|
||||
std::shared_ptr<Node> getPtr();
|
||||
virtual bool hovering() override;
|
||||
void addConnector();
|
||||
std::weak_ptr<Connector> getConnector();
|
||||
void removeConnector(std::weak_ptr<Connector> connector);
|
||||
virtual NodeType getNodeType() const;
|
||||
void deselect() override;
|
||||
@@ -52,6 +53,7 @@ namespace VISEQ::GRAPH::NODES {
|
||||
void update() override;
|
||||
void draw(Vec2Df mp, Camera2D cam) override;
|
||||
void draw() override;
|
||||
virtual void cycleMode(bool direction);
|
||||
|
||||
friend void to_json(json& j, const Node& N);
|
||||
friend void from_json(const json& j, Node& N);
|
||||
|
||||
@@ -16,6 +16,7 @@ namespace VISEQ::BASE {
|
||||
bool erase = false;
|
||||
Vec2Df selection_offset;
|
||||
|
||||
void update();
|
||||
virtual bool clicked() override;
|
||||
|
||||
virtual bool select() = 0;
|
||||
|
||||
@@ -86,26 +86,29 @@ namespace VISEQ::SIGNAL {
|
||||
auto last = std::chrono::high_resolution_clock::now();
|
||||
while(loop){
|
||||
std::chrono::duration<double, std::micro> diff = std::chrono::high_resolution_clock::now() - last;
|
||||
if((int)diff.count() >= 250){
|
||||
if((int)diff.count() >= 100){
|
||||
mutex->lock();
|
||||
if(play){
|
||||
for(auto& s : signals){
|
||||
s->direction = (s->next.lock()->position - s->position).norm();
|
||||
s->update(diff.count());
|
||||
if(s->position.dist(s->next.lock()->position) < 0.6f) {
|
||||
if(round(s->position.dist(s->next.lock()->position)) == 0) {
|
||||
WPTR_Node next_node = gm->next(s->next, s->last);
|
||||
s->next.lock()->trigger();
|
||||
|
||||
if(next_node.lock() != s->next.lock() && !next_node.expired() && s->next.lock()->getNodeType() == NodeType::MIDINODE) {
|
||||
auto midinode = std::dynamic_pointer_cast<MidiNode>(s->next.lock());
|
||||
for(auto &m : midinode->midi_outs){
|
||||
for(auto &m : midinode->selected_midi_outs){
|
||||
if(m.second.enabled) {
|
||||
std::cout << std::chrono::high_resolution_clock::now() << " : " << diff.count() << " " << m.second.name << " " << m.second.i << " " << m.second.enabled << std::endl;
|
||||
if(midinode->send_note) midi.note(m.second.i, midinode->getNotes().channel, (int)Clamp(midinode->getNotes().note + s->midi_note_offset, 0, 127), midinode->getNotes().velocity, midinode->getNotes().gate);
|
||||
if(midinode->send_cc) midi.cc(m.second.i, midinode->getCC().channel, midinode->getCC().control, (int)Clamp(midinode->getCC().value + s->midi_cc_offset, 0, 127));
|
||||
if(midinode->send_pc) midi.pc(m.second.i, midinode->getPC().channel, midinode->getPC().value);
|
||||
if(midinode->send_pitch_bend) midi.pitch_bend(m.second.i, midinode->getPitchBend().channel, midinode->getPitchBend().value);
|
||||
if(midinode->send_aftertouch) midi.aftertouch(m.second.i, midinode->getAftertouch().channel, midinode->getAftertouch().value);
|
||||
if(midinode->send_polypressure) midi.polypressure(m.second.i, midinode->getPolyPressure().channel, midinode->getPolyPressure().note, midinode->getPolyPressure().value);
|
||||
}
|
||||
}
|
||||
if(midinode->send_note) midi.note(99, midinode->getNotes().channel, (int)Clamp(midinode->getNotes().note + s->midi_note_offset, 0, 127), midinode->getNotes().velocity, midinode->getNotes().gate);
|
||||
s->last = s->next;
|
||||
s->next = next_node;
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#include "raylib.h"
|
||||
#include "vmath.h"
|
||||
#include <memory>
|
||||
#include <ostream>
|
||||
|
||||
namespace VISEQ::APP{
|
||||
|
||||
@@ -54,6 +55,29 @@ namespace VISEQ::APP{
|
||||
keys_released.shift = IsKeyReleased(KEY_LEFT_SHIFT) || IsKeyReleased(KEY_RIGHT_SHIFT);
|
||||
keys_released.alt = IsKeyReleased(KEY_LEFT_ALT) || IsKeyReleased(KEY_RIGHT_ALT);
|
||||
|
||||
int n_modifier = keys_down.alt + keys_down.ctrl + keys_down.shift;
|
||||
|
||||
if(modifier_chain.size() < n_modifier){
|
||||
ModifierKeyNames modKey = keys_pressed.ctrl ? CTRL : keys_pressed.shift ? SHIFT : ALT;
|
||||
modifier_chain.push_back(modKey);
|
||||
//std::cout << modifier_chain.size() << " " << modKey << std::endl;
|
||||
for(ModifierKeyNames n : modifier_chain){
|
||||
std::cout << n << " ";
|
||||
}
|
||||
std::cout << std::endl;
|
||||
}
|
||||
|
||||
if(modifier_chain.size() > n_modifier){
|
||||
ModifierKeyNames modKey = keys_released.ctrl ? CTRL : keys_released.shift ? SHIFT : ALT;
|
||||
auto it = std::remove(modifier_chain.begin(), modifier_chain.end(), modKey);
|
||||
modifier_chain.erase(it);
|
||||
//std::cout << modifier_chain.size() << " " << modKey << std::endl;
|
||||
for(ModifierKeyNames n : modifier_chain){
|
||||
std::cout << n << " ";
|
||||
}
|
||||
std::cout << std::endl;
|
||||
}
|
||||
|
||||
screen_mouse = {round(mouse_pos.x), round(mouse_pos.y)};
|
||||
raw_mouse = {GetMousePosition().x, GetMousePosition().y};
|
||||
mod_mouse = {round(mouse_pos.x), round(mouse_pos.y)};
|
||||
@@ -73,4 +97,30 @@ namespace VISEQ::APP{
|
||||
}
|
||||
return State::instance;
|
||||
}
|
||||
|
||||
bool State::isModChainEmpty(){
|
||||
return modifier_chain.size() == 0;
|
||||
}
|
||||
|
||||
bool State::isModChainStart(ModifierKeyNames first){
|
||||
if(modifier_chain.size() < 1) return false;
|
||||
return std::equal(modifier_chain.begin(), modifier_chain.begin() + 1, std::vector<ModifierKeyNames>{first}.begin());
|
||||
}
|
||||
|
||||
bool State::isModChainStart(ModifierKeyNames first, ModifierKeyNames second){
|
||||
if(modifier_chain.size() < 2) return false;
|
||||
return std::equal(modifier_chain.begin(), modifier_chain.begin() + 2, std::vector<ModifierKeyNames>{first, second}.begin());
|
||||
}
|
||||
|
||||
bool State::isModChain(ModifierKeyNames first){
|
||||
return modifier_chain == std::vector<ModifierKeyNames>{first};
|
||||
}
|
||||
|
||||
bool State::isModChain(ModifierKeyNames first, ModifierKeyNames second){
|
||||
return modifier_chain == std::vector<ModifierKeyNames>{first, second};
|
||||
}
|
||||
|
||||
bool State::isModChain(ModifierKeyNames first, ModifierKeyNames second, ModifierKeyNames third){
|
||||
return modifier_chain == std::vector<ModifierKeyNames>{first, second, third};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#include "nlohmann/json.hpp"
|
||||
#include "raylib.h"
|
||||
#include "vmath.h"
|
||||
#include <deque>
|
||||
#include <memory>
|
||||
|
||||
#define STATE state->istate
|
||||
@@ -48,6 +49,8 @@ namespace VISEQ::APP{
|
||||
bool alt = false;
|
||||
};
|
||||
|
||||
enum ModifierKeyNames {CTRL, SHIFT, ALT};
|
||||
|
||||
class State{
|
||||
public:
|
||||
State(){}
|
||||
@@ -65,6 +68,7 @@ namespace VISEQ::APP{
|
||||
|
||||
int node_mode = 0;
|
||||
bool context_menu = false;
|
||||
bool draw_edge_lengths = false;
|
||||
|
||||
bool hovering = false;
|
||||
|
||||
@@ -78,6 +82,8 @@ namespace VISEQ::APP{
|
||||
ModifierKeys keys_pressed;
|
||||
ModifierKeys keys_released;
|
||||
|
||||
std::vector<ModifierKeyNames> modifier_chain;
|
||||
|
||||
Rectangle selection;
|
||||
Rectangle bounding_box;
|
||||
|
||||
@@ -95,6 +101,13 @@ namespace VISEQ::APP{
|
||||
static std::shared_ptr<State> get();
|
||||
|
||||
std::deque<InteractionEvent> event_queue;
|
||||
|
||||
bool isModChainEmpty();
|
||||
bool isModChainStart(ModifierKeyNames first);
|
||||
bool isModChainStart(ModifierKeyNames first, ModifierKeyNames second);
|
||||
bool isModChain(ModifierKeyNames first);
|
||||
bool isModChain(ModifierKeyNames first, ModifierKeyNames second);
|
||||
bool isModChain(ModifierKeyNames first, ModifierKeyNames second, ModifierKeyNames third);
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -6,13 +6,16 @@
|
||||
#include "raygui/raygui.h"
|
||||
|
||||
#include "datatypes.h"
|
||||
#include "vmath.h"
|
||||
|
||||
#include <memory>
|
||||
#include <ranges>
|
||||
#include <sstream>
|
||||
|
||||
namespace VISEQ::APP::UI{
|
||||
void AppUI::init(){
|
||||
GuiLoadStyleDark();
|
||||
inter = LoadFontEx("resources/fonts/Inter_28pt-Bold.ttf", 96, 0, 250);
|
||||
}
|
||||
|
||||
void AppUI::drawSideBar(){
|
||||
@@ -37,6 +40,11 @@ namespace VISEQ::APP::UI{
|
||||
if(GuiButton((Rectangle){200, (float)s_midi, 60, 20}, "RELOAD")) sm->midi.enumerate();
|
||||
|
||||
int i = 0;
|
||||
for(auto& vo : sm->midi.virtual_midi_out_ports){
|
||||
GuiCheckBox((Rectangle){20, (float)s_midi + 25 + i*20.0f, 20, 20}, vo.name.substr(0,32).c_str(), &vo.enabled);
|
||||
i++;
|
||||
}
|
||||
i++;
|
||||
for(auto& mo : sm->midi.midi_out_ports){
|
||||
GuiCheckBox((Rectangle){20, (float)s_midi + 25 + i*20.0f, 20, 20}, mo.port.port_name.substr(0,32).c_str(), &mo.enabled);
|
||||
i++;
|
||||
@@ -48,6 +56,11 @@ namespace VISEQ::APP::UI{
|
||||
gm->setMidiPortForAll(midis.number, true);
|
||||
}
|
||||
}
|
||||
for(auto &midis : sm->midi.virtual_midi_out_ports){
|
||||
if(midis.enabled){
|
||||
gm->setMidiPortForAll(midis.number, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int s_signal = s_midi + 100 + i*20;
|
||||
@@ -66,9 +79,11 @@ namespace VISEQ::APP::UI{
|
||||
s->multiplier = state->settings.bpm / 120.0f;
|
||||
float signal_bpm = round(state->settings.bpm * s->multiplier * (s->speed / state->settings.speed));
|
||||
if(GuiSpinner((Rectangle){70, (float)s_signal+70 + signal_configs*20, 100, 20}, "", &s_speed, 1, 16 * state->settings.grid * 4, s->ui_edit_speed)) s->ui_edit_speed = !s->ui_edit_speed;
|
||||
|
||||
GuiLabel((Rectangle){175, (float)s_signal+70 + signal_configs*20, 40, 20}, std::format("{}",signal_bpm).c_str());
|
||||
|
||||
if(GuiButton((Rectangle){200,(float)s_signal+70 + signal_configs*20, 30, 20}, "1/2")) s_speed = state->settings.speed / 2;
|
||||
//if(GuiButton((Rectangle){200,(float)s_signal+70 + signal_configs*20, 30, 20},"1/4")) s_speed = state->settings.speed / 4;
|
||||
GuiLabel((Rectangle){195, (float)s_signal+70 + signal_configs*20, 30, 20}, std::format("{}",signal_bpm).c_str());
|
||||
GuiToggle((Rectangle){240, (float)s_signal+70 + signal_configs*20, 20, 20},"P", &s->run);
|
||||
s->speed = s_speed;
|
||||
signal_configs++;
|
||||
@@ -82,19 +97,20 @@ namespace VISEQ::APP::UI{
|
||||
DrawText(std::format("{}", gm->getNodesSize()).c_str(), 20, state->settings.height - 70, 15, VS_COLOR_WHITE);
|
||||
DrawFPS(20, state->settings.height - 30);
|
||||
|
||||
std::string shorts[6] = {"NT","CC","PC","PB","AT","PP"};
|
||||
for(int i = 0; i < 6; ++i){
|
||||
Color col = state->settings.mode_colors[i];
|
||||
Vec2Df pos = {state->settings.width - (6.0f*75.0f) + i*75.0f, state->settings.height - 75.0f};
|
||||
DrawRing(pos, 30.0f, 34.0f, 0.0f, 360.0f, 24, state->node_mode == i ? VS_COLOR_WHITE : (Color){0,0,0,0});
|
||||
DrawCircleV(pos, 30.0f, col);
|
||||
DrawCenteredText(shorts[i], pos, 20, WHITE);
|
||||
}
|
||||
// std::string shorts[6] = {"NT","CC","PC","PB","AT","PP"};
|
||||
// for(int i = 0; i < 6; ++i){
|
||||
// Color col = state->settings.mode_colors[i];
|
||||
// Vec2Df pos = {state->settings.width - (6.0f*75.0f) + i*75.0f, state->settings.height - 75.0f};
|
||||
// DrawRing(pos, 30.0f, 34.0f, 0.0f, 360.0f, 24, state->node_mode == i ? VS_COLOR_WHITE : (Color){0,0,0,0});
|
||||
// DrawCircleV(pos, 30.0f, col);
|
||||
// DrawCenteredText(shorts[i], pos, 20, WHITE);
|
||||
// }
|
||||
}
|
||||
|
||||
void AppUI::DrawCenteredText(std::string text, Vec2Df position, int size, Color color){
|
||||
float offset = MeasureText(text.c_str(), size);
|
||||
DrawText(text.c_str(), position.x-offset/2.0f, position.y-(float)size/2.0f+1, size, color );
|
||||
//DrawText(text.c_str(), position.x-offset/2.0f, position.y-(float)size/2.0f+1, size, color );
|
||||
DrawTextEx(inter, text.c_str(), Vec2Df(position.x-offset/2.0f, position.y-(float)size/2.0f+1), size, 2.0f, color);
|
||||
}
|
||||
|
||||
void AppUI::drawContextMenu(Camera2D camera){
|
||||
@@ -119,7 +135,7 @@ namespace VISEQ::APP::UI{
|
||||
int i = 0;
|
||||
if(n->getNodeType() == NodeType::MIDINODE){
|
||||
std::shared_ptr<MidiNode> mn = std::dynamic_pointer_cast<MidiNode>(n);
|
||||
for(auto& mo : mn->midi_outs){
|
||||
for(auto& mo : mn->selected_midi_outs){
|
||||
GuiCheckBox((Rectangle){np.x + 20, np.y + y_midi + 20 + i*20.0f, 20, 20}, mo.second.name.c_str(), &mo.second.enabled);
|
||||
i++;
|
||||
}
|
||||
@@ -127,13 +143,20 @@ namespace VISEQ::APP::UI{
|
||||
int y_channel = y_midi + 30 + i*20;
|
||||
GuiCheckBox((Rectangle){np.x + 20, np.y + y_channel, 20, 20}, "NOTE", &mn->send_note);
|
||||
GuiCheckBox((Rectangle){np.x + 90, np.y + y_channel, 20, 20}, "CC", &mn->send_cc);
|
||||
GuiCheckBox((Rectangle){np.x + 160, np.y + y_channel, 20, 20}, "PITCH", &mn->send_pitch_bend);
|
||||
GuiCheckBox((Rectangle){np.x + 160, np.y + y_channel, 20, 20}, "PITCH-B", &mn->send_pitch_bend);
|
||||
|
||||
int y_cc_note = y_channel + 120;
|
||||
int y_send_bools = y_channel + 30;
|
||||
GuiCheckBox((Rectangle){np.x + 20, np.y + y_send_bools, 20, 20}, "PC", &mn->send_pc);
|
||||
GuiCheckBox((Rectangle){np.x + 90, np.y + y_send_bools, 20, 20}, "AT", &mn->send_aftertouch);
|
||||
GuiCheckBox((Rectangle){np.x + 160, np.y + y_send_bools, 20, 20}, "POLY-P", &mn->send_polypressure);
|
||||
|
||||
int y_cc_note = y_send_bools + 120;
|
||||
GuiLabel((Rectangle){np.x + 20, np.y + y_cc_note - 75, 220, 20}, "NOTE CHANNEL");
|
||||
GuiToggleGroup((Rectangle){np.x + 20, np.y + y_cc_note - 50, 25, 20}, "1;2;3;4;5;6;7;8\n9;10;11;12;13;14;15;16", &mn->midiNote.channel);
|
||||
|
||||
/*
|
||||
switch(state->node_mode){
|
||||
case 0:{
|
||||
GuiLabel((Rectangle){np.x + 20, np.y + y_cc_note - 75, 220, 20}, "NOTE CHANNEL");
|
||||
GuiToggleGroup((Rectangle){np.x + 20, np.y + y_cc_note - 50, 25, 20}, "1;2;3;4;5;6;7;8\n9;10;11;12;13;14;15;16", &mn->midiNote.channel);
|
||||
|
||||
GuiLabel((Rectangle){np.x + 20, np.y + y_cc_note , 100, 20}, "NOTE");
|
||||
float v = mn->midiNote.note;
|
||||
@@ -183,7 +206,7 @@ namespace VISEQ::APP::UI{
|
||||
GuiSlider((Rectangle){np.x + 20, np.y + y_cc_note + 30, 220, 20}, "", "", &v, 0, 16383);
|
||||
mn->midiPitchBend.value = round(v);
|
||||
break;}
|
||||
}
|
||||
}*/
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
#pragma once
|
||||
|
||||
#include "raylib.h"
|
||||
|
||||
#include <cmath>
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include "nlohmann/json.hpp"
|
||||
@@ -55,6 +57,14 @@ namespace VISEQ::VMATH{
|
||||
return Vec2D(-y, x);
|
||||
};
|
||||
|
||||
Vec2D rotate(float deg){
|
||||
return Vec2D(cos(deg*DEG2RAD) * x, sin(deg*DEG2RAD) * y);
|
||||
};
|
||||
|
||||
Vec2D rotateAround(Vec2D<T> v, float deg){
|
||||
return Vec2D(cos(deg*DEG2RAD) * (x - v.x), sin(deg*DEG2RAD) * (y-v.y)) + v;
|
||||
};
|
||||
|
||||
Vec2D norm() { return *this / length();};
|
||||
|
||||
Vec2D center(Vec2D v){
|
||||
@@ -164,7 +174,7 @@ namespace VISEQ::VMATH{
|
||||
|
||||
template<typename T>
|
||||
Vec2D<T> polarToCartesian(T r, T q) {
|
||||
return Vec2D<T>{r * cos(q), r * sin(q)};
|
||||
return Vec2D<T>{r * (T)cos(q), r * (T)sin(q)};
|
||||
}
|
||||
}
|
||||
|
||||
|
||||