Compare commits

...

10 commits

Author SHA1 Message Date
010893d1a6 remove leftover assert, makes unix domain socket ipc work again :) 2024-12-16 14:26:47 +01:00
24797ac882 Merge #eh20 stuff 2023-04-22 09:47:49 +02:00
c74de66798 remove buggy DoomBytesPerPixel == 3 code 2023-04-22 09:47:45 +02:00
4af51529cf link against sdl_nyan 2023-04-22 09:47:29 +02:00
da225e85d0 ctrl: also listen on tcp 2023-04-11 01:22:00 +02:00
1f7b7de3f3 dp_doom: add '-dp-host' param to be able to use tcp as a transport 2023-04-11 01:19:41 +02:00
54fed45717 remove TODO, it's done! :) 2023-04-11 01:14:21 +02:00
6e8837733a add sdl_nyan (https://github.com/oxmox42/sdl_nyan) 2023-03-12 12:00:25 +01:00
a715b3c973 Squashed 'external/sdl_nyan/' content from commit 2307b735e
git-subtree-dir: external/sdl_nyan
git-subtree-split: 2307b735e7aab49024356c6b94bbafe0c35e7027
2023-03-12 12:00:25 +01:00
77592c0181 broken SDL input handling (WIP) 2023-03-11 12:44:36 +01:00
49 changed files with 9503 additions and 102 deletions

View file

@ -29,3 +29,5 @@ if (XLIB_HEADER)
endif()
target_link_libraries(imgui PUBLIC SDL2::SDL2)
add_subdirectory(sdl_nyan)

9
external/sdl_nyan/.gitignore vendored Normal file
View file

@ -0,0 +1,9 @@
build*/
.cache/
.clangd/
.cmake/
CMakeLists.txt.user*
compile_commands.json
**/*.swo
**/*.swp
.vscode/

13
external/sdl_nyan/CMakeLists.txt vendored Normal file
View file

@ -0,0 +1,13 @@
cmake_minimum_required(VERSION 3.14)
project(sdl-nyan)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
## Create binaries in the root of the build directory
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR})
set(CMAKE_VERBOSE_MAKEFILE ON CACHE BOOL "ON")
find_package(SDL2 REQUIRED)
add_subdirectory(src)

21
external/sdl_nyan/LICENSE vendored Normal file
View file

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2023 oxmox
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

40
external/sdl_nyan/README.md vendored Normal file
View file

@ -0,0 +1,40 @@
# sdl_nyan
Tiny SDL2-based library and demo application for rendering animated nyan cats.
Rainbows not included, cats only!
![Screenshot of sdl_nyan_demo. Shows individual nyan sprites and some spinning cats.](sdl_nyan_demo.png)
## Requirements and building
Requires CMake>=3.14, SDL2 and a c11/c++17 capable compiler.
git clone https://github.com/oxmox42/sdl_nyan
mkdir sdl_nyan/build && cd sdl_nyan/build/
cmake .. && make
./sdl_nyan_demo
## Usage
Only internal use in the demo application tested so far. Needs more CMake-foo to
be installable as "proper" library.
The nyan sprites have been converted to c code and are included in the library,
so there's no need to keep the `.png` files around.
Create a `SDL_Renderer` and call `make_nyan_sprite_sheet_from_mem()`. This
creates a texture containing all 12 rightward-facing nyan sprites.
Use `nyan_sprite_rect()` to get the `SDL_Rect` for a specific sprite. This can
be used as the `sourceRect` for `SDL_RenderCopy` or `SDL_RenderCopyEx`.
See the demo on how to make circly, spinny nyans.
Meow!
## External projects used in sdl_nyan
* Nyan sprites taken from https://github.com/splitbrain/nyan which does not have a license.
* Uses stb_image from https://github.com/nothings/stb (MIT | public domain).
* [image_to_c](https://github.com/bitbank2/image_to_c) was used to generate C code from the nyan sprites.

View file

@ -0,0 +1,8 @@
This is just a quick hack done in an evening. There's no license for my code,
do what ever you want with it. NO WARRANTIES whatsoever.
As for the Nyan graphics and sounds... I believe this little fun project to
be in the spirit of the original idea and hopefully be okay with the copyright
holders (if there are any). If not, just send me a mail (andi@splitbrain.org)
and I'll take it down.
For the orginal Nyan cat, please visit http://nyan.cat

View file

@ -0,0 +1,28 @@
<html>
<head>
<title>Canvas Nyan Cat</title>
<script type="text/javascript" src="nyan/nyan.js"></script>
<script type="text/javascript">
// you might want to use your favorite JS framework's DOMready
// implementation instead of window.onload
window.onload = function(){
nyan.init('nyan');
};
</script>
</head>
<body>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum accumsan libero ac purus pellentesque quis viverra quam mollis. Sed accumsan ultricies nisl, at egestas quam euismod in. Sed nec elit nunc, a porta quam. Vestibulum semper placerat arcu in semper. Duis semper ornare eros, et sollicitudin neque bibendum eget. Praesent non suscipit risus. Aliquam porta viverra odio in ultrices. Aenean ornare rutrum sodales. In scelerisque orci eu diam egestas a feugiat dolor ultrices. Suspendisse et ipsum augue, vestibulum feugiat nunc.</p>
<p>Proin commodo pretium justo non dapibus. Aliquam nec nulla sed dui fermentum dignissim. Nullam sit amet nunc risus, a feugiat tortor. Quisque justo turpis, dignissim ac sagittis a, imperdiet sit amet turpis. In pharetra, sem sed gravida eleifend, lorem tellus suscipit erat, ut fringilla lectus dui at eros. Nulla et urna erat. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Aliquam vel elit consectetur orci elementum pharetra at dapibus purus. Cras rutrum bibendum nisl, a mattis orci auctor ac. Mauris ut commodo neque. Phasellus et molestie sem. Nunc vitae ante sed orci tincidunt vestibulum et sit amet mauris. Pellentesque eu suscipit lectus. Praesent aliquet sem viverra odio dapibus in porta tortor porta.</p>
<p>Nullam id urna id mauris malesuada euismod. Donec pellentesque facilisis consequat. Nullam porttitor, eros sit amet suscipit sodales, lacus diam vestibulum velit, in consequat massa eros at lacus. Donec auctor, sem mattis sagittis aliquam, erat ipsum interdum purus, semper fermentum sapien leo ac libero. Fusce congue, ipsum in tempus viverra, libero arcu ultrices arcu, vitae tempor purus leo facilisis nisi. Proin vitae neque est, at ultrices magna. Sed interdum erat id nibh euismod commodo nec ac orci. Suspendisse potenti. Suspendisse quis tortor eros. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec commodo risus at diam facilisis iaculis. Aenean at neque nec dolor sollicitudin pharetra. Maecenas sit amet varius nisl. Sed ut luctus augue.</p>
<p>In vestibulum facilisis condimentum. Morbi non tincidunt mauris. Sed nec diam elit. Integer vestibulum nulla sit amet lorem bibendum in vulputate diam feugiat. Aenean faucibus scelerisque turpis, et posuere ligula rutrum ac. Aenean posuere vulputate congue. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus.</p>
<p>Maecenas commodo tincidunt accumsan. Phasellus vel rhoncus lacus. Proin quis neque ante, sed tristique tortor. Curabitur dapibus volutpat posuere. Etiam sagittis elementum risus in fermentum. Fusce fringilla, mi sit amet adipiscing tristique, ipsum justo lacinia lectus, at venenatis velit diam eget quam. Ut nec elementum neque. Sed quam risus, adipiscing vel tristique eu, ornare eget sapien. Nunc fermentum dolor ut sem pulvinar at venenatis arcu placerat. Nulla vestibulum diam et justo pharetra rutrum. Nullam vel odio nec magna auctor rutrum a quis magna. Donec ligula libero, sollicitudin vel rhoncus hendrerit, pharetra at mauris. Praesent cursus, ipsum sit amet rhoncus euismod, turpis nunc suscipit mauris, id cursus nibh nibh ac justo. Praesent nec erat vel sem facilisis semper eu ut massa. Suspendisse a sagittis leo.</p>
</body>
</html>

Binary file not shown.

After

Width:  |  Height:  |  Size: 480 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 483 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 494 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 489 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 488 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 488 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 483 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 403 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 489 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 480 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 488 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 488 B

View file

@ -0,0 +1,186 @@
/**
* A background canvas Nyan cat
*
* Does not work in IE
*/
var nyan = {
path: '',
wrapper: null,
canvas: null,
sound: null,
last: null,
step: 1,
timeout: null,
/**
* Call this when the DOM is ready
*
* @param string path - where the nyan cat files are located, no trailing slash!
*/
init: function (path){
nyan.path = path;
// keep out incompatible browsers
if(!document.createElement('audio').canPlayType) return;
if(!document.createElement('canvas').getContext) return;
// wrap around everythng in the body
// http://stackoverflow.com/questions/1577814
nyan.wrapper = document.createElement('div');
while (document.body.firstChild) {
nyan.wrapper.appendChild(document.body.firstChild);
}
nyan.setStyle(document.body,nyan.wrapper);
nyan.wrapper.style.zIndex = 5;
document.body.appendChild(nyan.wrapper);
// create the canvas
nyan.canvas = document.createElement('canvas');
nyan.setStyle(document.body,nyan.canvas);
nyan.canvas.style.zIndex = 1;
nyan.canvas.width = nyan.wrapper.offsetWidth;
nyan.canvas.height = nyan.wrapper.offsetHeight;
document.body.insertBefore(nyan.canvas,nyan.wrapper);
// add the audio object
nyan.sound = document.createElement('audio');
if(nyan.sound.canPlayType('audio/mpeg') != ''){
nyan.sound.src = nyan.path+'/nyanlooped.mp3';
}else{
nyan.sound.src = nyan.path+'/nyanlooped.ogg';
}
nyan.sound.addEventListener('ended',function(){
// loop around
// http://forestmist.org/2010/04/html5-audio-loops/
this.currentTime = 0;
}, false);
document.body.appendChild(nyan.sound);
// add mouse listener
nyan.wrapper.addEventListener('mousemove', nyan.onMouseMove);
},
/**
* Set the cursor to nyan cat in the correct animation step
*/
setCursor: function(step,left){
nyan.wrapper.style.cursor = 'url('+nyan.path+'/'+(left?'l':'r')+step+'.png), default';
},
/**
* Stops the madness
*/
stop: function(){
nyan.wrapper.style.cursor = 'auto';
nyan.sound.pause();
},
/**
* The real worker
*
* draws nyan cat, the rainbow and starts the audio
*/
onMouseMove: function(evt){
var mousePos = nyan.getMousePos(nyan.wrapper, evt);
if(!nyan.last){
nyan.last = mousePos;
return;
}
if(Math.abs(nyan.last.x - mousePos.x) >= 1 ||
Math.abs(nyan.last.y - mousePos.y) > 1) {
var context = nyan.canvas.getContext('2d');
// start sound and timeout
nyan.sound.play();
if(nyan.timeout) window.clearTimeout(nyan.timeout);
nyan.timeout = window.setTimeout(nyan.stop,500);
// red
context.beginPath();
context.rect(mousePos.x +5, mousePos.y +2, 15, 3);
context.fillStyle = 'rgba(255,0,0,0.5)';
context.fill();
// orange
context.beginPath();
context.rect(mousePos.x +5, mousePos.y +5, 15, 3);
context.fillStyle = 'rgba(255,153,0,0.5)';
context.fill();
// yellow
context.beginPath();
context.rect(mousePos.x +5, mousePos.y +8, 15, 3);
context.fillStyle = 'rgba(255,255,0,0.5)';
context.fill();
// geen
context.beginPath();
context.rect(mousePos.x +5, mousePos.y +11, 15, 3);
context.fillStyle = 'rgba(51,255,0,0.5)';
context.fill();
// blue
context.beginPath();
context.rect(mousePos.x +5, mousePos.y +14, 15, 3);
context.fillStyle = 'rgba(0,153,255,0.7)';
context.fill();
// purple
context.beginPath();
context.rect(mousePos.x +5, mousePos.y +17, 15, 3);
context.fillStyle = 'rgba(102,51,255,0.5)';
context.fill();
//animate
nyan.setCursor(nyan.step,((nyan.last.x - mousePos.x) > 0));
// animation counter
nyan.step++;
if(nyan.step > 12) nyan.step = 1;
// remember position
nyan.last = mousePos;
}
},
/**
* copy styles from body to our wrapper and canvas
*
* needed to keep any margins or paddings
*/
setStyle: function(from, to){
var style = window.getComputedStyle(from);
to.style.cssText = style.cssText;
to.style['position'] = 'absolute';
to.style['top'] = '0px';
to.style['left'] = '0px';
to.style['background'] = 'transparent none';
},
/**
* return mouse position relative to the given object
*/
getMousePos: function(obj, evt){
// get canvas position
var top = 0;
var left = 0;
while (obj && obj.tagName != 'BODY') {
top += obj.offsetTop;
left += obj.offsetLeft;
obj = obj.offsetParent;
}
// return relative mouse position
var mouseX = evt.clientX - left + window.pageXOffset;
var mouseY = evt.clientY - top + window.pageYOffset;
return {
x: mouseX,
y: mouseY
};
}
}

Binary file not shown.

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 477 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 468 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 486 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 484 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 476 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 477 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 468 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 395 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 484 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 477 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 476 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 477 B

BIN
external/sdl_nyan/sdl_nyan_demo.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.8 KiB

36
external/sdl_nyan/src/CMakeLists.txt vendored Normal file
View file

@ -0,0 +1,36 @@
set(SDL_NYAN_WARN_FLAGS -Wall -Wextra -Wpedantic)
# Source: log.c by rxi (https://github.com/rxi/log.c)
add_library(nyan_logc OBJECT log.c)
target_compile_features(nyan_logc PRIVATE c_std_11)
if (NOT WIN32)
target_compile_definitions(nyan_logc PRIVATE -DLOG_USE_COLOR)
endif()
target_compile_options(nyan_logc PUBLIC -fmacro-prefix-map=${CMAKE_CURRENT_SOURCE_DIR}=. PRIVATE ${SDL_NYAN_WARN_FLAGS})
find_program(CLANG_TIDY_EXECUTABLE clang-tidy)
if (CLANG_TIDY_EXECUTABLE)
set(CMAKE_C_CLANG_TIDY clang-tidy -p ${CMAKE_BINARY_DIR} --extra-arg=-std=c11)
set(CMAKE_CXX_CLANG_TIDY clang-tidy -p ${CMAKE_BINARY_DIR} --extra-arg=-std=c++17)
endif()
add_library(sdl_nyan STATIC sdl_nyan.cc)
target_compile_features(sdl_nyan PRIVATE cxx_std_17)
target_link_libraries(sdl_nyan
PRIVATE nyan_logc
PRIVATE SDL2::SDL2
)
target_include_directories(sdl_nyan
PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
)
add_executable(sdl_nyan_demo sdl_nyan_demo.cc)
target_compile_features(sdl_nyan_demo PRIVATE cxx_std_17)
target_link_libraries(sdl_nyan_demo
PRIVATE sdl_nyan
PRIVATE SDL2::SDL2
)
if (WIN32)
target_link_libraries(sdl_nyan_demo PRIVATE SDL2::SDL2main)
endif()

168
external/sdl_nyan/src/log.c vendored Normal file
View file

@ -0,0 +1,168 @@
/*
* Copyright (c) 2020 rxi
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
*/
#include "log.h"
#define MAX_CALLBACKS 32
typedef struct {
log_LogFn fn;
void *udata;
int level;
} Callback;
static struct {
void *udata;
log_LockFn lock;
int level;
bool quiet;
Callback callbacks[MAX_CALLBACKS];
} L;
static const char *level_strings[] = {
"TRACE", "DEBUG", "INFO", "WARN", "ERROR", "FATAL"
};
#ifdef LOG_USE_COLOR
static const char *level_colors[] = {
"\x1b[94m", "\x1b[36m", "\x1b[32m", "\x1b[33m", "\x1b[31m", "\x1b[35m"
};
#endif
static void stdout_callback(log_Event *ev) {
char buf[16];
buf[strftime(buf, sizeof(buf), "%H:%M:%S", ev->time)] = '\0';
#ifdef LOG_USE_COLOR
fprintf(
ev->udata, "%s %s%-5s\x1b[0m \x1b[90m%s:%d:\x1b[0m ",
buf, level_colors[ev->level], level_strings[ev->level],
ev->file, ev->line);
#else
fprintf(
ev->udata, "%s %-5s %s:%d: ",
buf, level_strings[ev->level], ev->file, ev->line);
#endif
vfprintf(ev->udata, ev->fmt, ev->ap);
fprintf(ev->udata, "\n");
fflush(ev->udata);
}
static void file_callback(log_Event *ev) {
char buf[64];
buf[strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S", ev->time)] = '\0';
fprintf(
ev->udata, "%s %-5s %s:%d: ",
buf, level_strings[ev->level], ev->file, ev->line);
vfprintf(ev->udata, ev->fmt, ev->ap);
fprintf(ev->udata, "\n");
fflush(ev->udata);
}
static void lock(void) {
if (L.lock) { L.lock(true, L.udata); }
}
static void unlock(void) {
if (L.lock) { L.lock(false, L.udata); }
}
const char* log_level_string(int level) {
return level_strings[level];
}
void log_set_lock(log_LockFn fn, void *udata) {
L.lock = fn;
L.udata = udata;
}
void log_set_level(int level) {
L.level = level;
}
void log_set_quiet(bool enable) {
L.quiet = enable;
}
int log_add_callback(log_LogFn fn, void *udata, int level) {
for (int i = 0; i < MAX_CALLBACKS; i++) {
if (!L.callbacks[i].fn) {
L.callbacks[i] = (Callback) { fn, udata, level };
return 0;
}
}
return -1;
}
int log_add_fp(FILE *fp, int level) {
return log_add_callback(file_callback, fp, level);
}
static void init_event(log_Event *ev, void *udata) {
if (!ev->time) {
time_t t = time(NULL);
ev->time = localtime(&t);
}
ev->udata = udata;
}
void log_log(int level, const char *file, int line, const char *fmt, ...) {
log_Event ev = {
.fmt = fmt,
.file = file,
.line = line,
.level = level,
};
lock();
if (!L.quiet && level >= L.level) {
init_event(&ev, stderr);
va_start(ev.ap, fmt);
stdout_callback(&ev);
va_end(ev.ap);
}
for (int i = 0; i < MAX_CALLBACKS && L.callbacks[i].fn; i++) {
Callback *cb = &L.callbacks[i];
if (level >= cb->level) {
init_event(&ev, cb->udata);
va_start(ev.ap, fmt);
cb->fn(&ev);
va_end(ev.ap);
}
}
unlock();
}

57
external/sdl_nyan/src/log.h vendored Normal file
View file

@ -0,0 +1,57 @@
/**
* Copyright (c) 2020 rxi
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the MIT license. See `log.c` for details.
*/
#ifndef LOG_H
#define LOG_H
#ifdef __cplusplus
extern "C" {
#endif
#include <stdio.h>
#include <stdarg.h>
#include <stdbool.h>
#include <time.h>
#define LOG_VERSION "0.1.0"
typedef struct {
va_list ap;
const char *fmt;
const char *file;
struct tm *time;
void *udata;
int line;
int level;
} log_Event;
typedef void (*log_LogFn)(log_Event *ev);
typedef void (*log_LockFn)(bool lock, void *udata);
enum { LOG_TRACE, LOG_DEBUG, LOG_INFO, LOG_WARN, LOG_ERROR, LOG_FATAL };
#define log_trace(...) log_log(LOG_TRACE, __FILE__, __LINE__, __VA_ARGS__)
#define log_debug(...) log_log(LOG_DEBUG, __FILE__, __LINE__, __VA_ARGS__)
#define log_info(...) log_log(LOG_INFO, __FILE__, __LINE__, __VA_ARGS__)
#define log_warn(...) log_log(LOG_WARN, __FILE__, __LINE__, __VA_ARGS__)
#define log_error(...) log_log(LOG_ERROR, __FILE__, __LINE__, __VA_ARGS__)
#define log_fatal(...) log_log(LOG_FATAL, __FILE__, __LINE__, __VA_ARGS__)
const char* log_level_string(int level);
void log_set_lock(log_LockFn fn, void *udata);
void log_set_level(int level);
void log_set_quiet(bool enable);
int log_add_callback(log_LogFn fn, void *udata, int level);
int log_add_fp(FILE *fp, int level);
void log_log(int level, const char *file, int line, const char *fmt, ...);
#ifdef __cplusplus
}
#endif
#endif

514
external/sdl_nyan/src/nyan_data_r.c vendored Normal file
View file

@ -0,0 +1,514 @@
// Created with image_to_c
// https://github.com/bitbank2/image_to_c
//
// r10
// Data size = 468 bytes
//
// PNG, Compression=Flate, Size: 36 x 26, 32-Bpp
//
// for non-Arduino builds...
#ifndef PROGMEM
#define PROGMEM
#endif
const uint8_t r10[] PROGMEM = {
0x89,0x50,0x4e,0x47,0x0d,0x0a,0x1a,0x0a,0x00,0x00,0x00,0x0d,0x49,0x48,0x44,0x52,
0x00,0x00,0x00,0x24,0x00,0x00,0x00,0x1a,0x08,0x06,0x00,0x00,0x00,0xdf,0x70,0xfe,
0x45,0x00,0x00,0x00,0x01,0x73,0x52,0x47,0x42,0x00,0xae,0xce,0x1c,0xe9,0x00,0x00,
0x00,0x06,0x62,0x4b,0x47,0x44,0x00,0xff,0x00,0xff,0x00,0xff,0xa0,0xbd,0xa7,0x93,
0x00,0x00,0x00,0x09,0x70,0x48,0x59,0x73,0x00,0x00,0x0b,0x13,0x00,0x00,0x0b,0x13,
0x01,0x00,0x9a,0x9c,0x18,0x00,0x00,0x00,0x07,0x74,0x49,0x4d,0x45,0x07,0xdc,0x02,
0x04,0x01,0x2e,0x01,0x21,0x48,0xe1,0x4e,0x00,0x00,0x00,0x1d,0x69,0x54,0x58,0x74,
0x43,0x6f,0x6d,0x6d,0x65,0x6e,0x74,0x00,0x00,0x00,0x00,0x00,0x43,0x72,0x65,0x61,
0x74,0x65,0x64,0x20,0x77,0x69,0x74,0x68,0x20,0x47,0x49,0x4d,0x50,0x64,0x2e,0x65,
0x07,0x00,0x00,0x01,0x2b,0x49,0x44,0x41,0x54,0x48,0xc7,0xed,0x96,0x4b,0x12,0xc2,
0x30,0x08,0x86,0x21,0xd3,0x8d,0xf7,0xf0,0x06,0xf6,0x06,0xde,0xc3,0x65,0x38,0x53,
0x72,0x26,0x3d,0x13,0x6e,0x1a,0x9b,0xa6,0xd0,0x42,0xe3,0x38,0x3a,0x23,0x9b,0x66,
0xda,0x3c,0x3e,0xe0,0x27,0x14,0xe0,0x6f,0x3f,0x66,0xe8,0x98,0xcb,0x9f,0x38,0xcf,
0x0a,0xc4,0x7c,0x4f,0xfd,0x34,0x23,0xed,0x9e,0x89,0x6e,0x98,0x47,0xf4,0x93,0x5c,
0xb2,0x19,0x2a,0xb8,0x36,0xd6,0x60,0x72,0x96,0xc7,0x07,0x9c,0x08,0x6e,0x18,0xe9,
0xc0,0x18,0xe5,0xf1,0x01,0xa8,0xe0,0x0e,0x7f,0xdc,0xdf,0x18,0x09,0x01,0x09,0x75,
0x07,0x96,0x85,0xb2,0x28,0x96,0xe1,0xed,0x65,0x4b,0x08,0x29,0xa5,0xd7,0x98,0x93,
0x5a,0x9c,0x5c,0xe6,0x11,0x11,0x17,0x5d,0x85,0x6e,0x82,0x8d,0x08,0xa4,0x94,0xe6,
0x48,0x29,0x30,0xad,0xf5,0x47,0x68,0x27,0x85,0x12,0x94,0x06,0x73,0x1c,0x28,0x67,
0x93,0x96,0x2c,0x00,0x1e,0x51,0xb3,0x7a,0x3b,0xb7,0x30,0x53,0xda,0x6a,0xfd,0x78,
0x6c,0x5a,0xc3,0x1a,0x10,0x97,0x1c,0xaf,0x36,0xd7,0xf4,0xa2,0x44,0xeb,0x1c,0x6f,
0x40,0x44,0xae,0x6f,0x41,0x12,0x9b,0xea,0x65,0xf4,0xdd,0xd2,0x57,0x3c,0xad,0xde,
0x15,0x08,0xe9,0x5b,0xab,0xa1,0xba,0x0c,0xbb,0xb4,0x14,0xe7,0x5c,0xa8,0x7a,0x2a,
0xcf,0x32,0x97,0x0c,0x1a,0xc2,0x45,0xcf,0x29,0xfd,0xa8,0x4e,0x9b,0x21,0x62,0xb5,
0x73,0xda,0x78,0xab,0xb9,0xb2,0xf0,0xde,0xd5,0x5c,0x5b,0x61,0x6f,0x45,0xbb,0xc9,
0x08,0x9a,0xbb,0x3d,0x00,0x80,0xe7,0xf7,0x03,0x47,0x32,0x57,0x5b,0x0d,0x63,0x01,
0xf2,0xeb,0xaa,0xf3,0xa7,0x6d,0x38,0xb0,0x98,0xa5,0x50,0x1b,0x9c,0x31,0xad,0x45,
0x4b,0xba,0x24,0x5d,0x19,0xf7,0x90,0xe6,0xb1,0xe3,0xfc,0xbf,0x7d,0xbf,0x3d,0x01,
0x02,0x72,0x88,0x5a,0x43,0x81,0x64,0x26,0x00,0x00,0x00,0x00,0x49,0x45,0x4e,0x44,
0xae,0x42,0x60,0x82};
// Created with image_to_c
// https://github.com/bitbank2/image_to_c
//
// r11
// Data size = 486 bytes
//
// PNG, Compression=Flate, Size: 36 x 26, 32-Bpp
//
// for non-Arduino builds...
#ifndef PROGMEM
#define PROGMEM
#endif
const uint8_t r11[] PROGMEM = {
0x89,0x50,0x4e,0x47,0x0d,0x0a,0x1a,0x0a,0x00,0x00,0x00,0x0d,0x49,0x48,0x44,0x52,
0x00,0x00,0x00,0x24,0x00,0x00,0x00,0x1a,0x08,0x06,0x00,0x00,0x00,0xdf,0x70,0xfe,
0x45,0x00,0x00,0x00,0x01,0x73,0x52,0x47,0x42,0x00,0xae,0xce,0x1c,0xe9,0x00,0x00,
0x00,0x06,0x62,0x4b,0x47,0x44,0x00,0xff,0x00,0xff,0x00,0xff,0xa0,0xbd,0xa7,0x93,
0x00,0x00,0x00,0x09,0x70,0x48,0x59,0x73,0x00,0x00,0x0b,0x13,0x00,0x00,0x0b,0x13,
0x01,0x00,0x9a,0x9c,0x18,0x00,0x00,0x00,0x07,0x74,0x49,0x4d,0x45,0x07,0xdc,0x02,
0x04,0x01,0x2e,0x01,0x21,0x48,0xe1,0x4e,0x00,0x00,0x00,0x1d,0x69,0x54,0x58,0x74,
0x43,0x6f,0x6d,0x6d,0x65,0x6e,0x74,0x00,0x00,0x00,0x00,0x00,0x43,0x72,0x65,0x61,
0x74,0x65,0x64,0x20,0x77,0x69,0x74,0x68,0x20,0x47,0x49,0x4d,0x50,0x64,0x2e,0x65,
0x07,0x00,0x00,0x01,0x3d,0x49,0x44,0x41,0x54,0x48,0xc7,0xed,0x96,0xcb,0x71,0x03,
0x31,0x08,0x86,0x41,0xb3,0x17,0xf7,0x91,0x0e,0xe2,0x0e,0xdc,0x47,0x8e,0xa2,0x26,
0x54,0x93,0x5d,0x13,0xb9,0x44,0x36,0xbb,0x11,0x08,0x76,0x3d,0x9e,0x49,0xc6,0x5c,
0xac,0x19,0xb1,0xe2,0xd3,0x6f,0x1e,0x02,0x78,0xdb,0x1f,0x33,0x4c,0xf8,0xca,0x2b,
0xe2,0x45,0x81,0x44,0xae,0x7c,0x9c,0xe6,0x4c,0xd3,0x98,0x98,0x86,0xb9,0xd5,0x3c,
0xc9,0x67,0x0b,0x43,0x95,0xd4,0xc1,0x16,0x4c,0x6b,0xe3,0xf5,0x8e,0x4b,0x94,0x34,
0xcc,0x28,0x60,0xad,0xe3,0xf5,0x0e,0xa8,0x92,0x96,0xbf,0xfa,0x07,0x23,0x21,0x20,
0xa1,0xaf,0xd8,0xa3,0x48,0x7e,0x15,0xca,0xf2,0xd4,0x92,0x25,0x04,0x66,0xbe,0xaf,
0x85,0xc5,0xba,0x80,0x74,0x3f,0x22,0x12,0x9d,0x53,0xe5,0x30,0x85,0xa1,0x00,0x33,
0xaf,0x95,0xda,0xec,0x59,0xb6,0x38,0x7d,0x06,0x8f,0xfe,0x85,0x23,0x28,0x0f,0x46,
0x03,0x89,0x76,0x24,0x22,0xbf,0x11,0xb6,0x36,0xcd,0xa5,0x28,0x80,0xd5,0x87,0x64,
0xf4,0xf1,0x0f,0x18,0xc8,0x95,0xfd,0x2a,0x69,0x0d,0xf0,0x46,0xe9,0xe0,0x9b,0x38,
0xa8,0x15,0x42,0x95,0x60,0xab,0xdb,0x75,0x28,0x57,0x99,0x5a,0x01,0xb4,0x1f,0x00,
0x7c,0xd4,0x2f,0xb8,0xe0,0x69,0x08,0xe9,0xed,0x95,0x81,0x62,0xa8,0x00,0x53,0x25,
0xaf,0xed,0x82,0x27,0x4b,0x89,0xe1,0x5e,0xa4,0xec,0x71,0x3a,0x54,0x07,0x8a,0xd5,
0x87,0xbc,0x66,0x3e,0xf5,0xdf,0xee,0x4b,0xbb,0x1a,0x63,0x9f,0x47,0xba,0xcc,0x27,
0x8a,0x69,0x85,0xad,0x75,0x76,0xb8,0xca,0x3d,0xa9,0x03,0x23,0x40,0x37,0xc6,0x59,
0x60,0xd5,0x18,0x57,0x1c,0x18,0x7d,0xff,0x44,0x9f,0x1f,0x78,0x8e,0x57,0xdb,0x16,
0xc6,0x03,0x92,0xe8,0x4d,0x9f,0xfd,0x60,0x5b,0x12,0xb7,0x10,0x4b,0x66,0x67,0x4e,
0x65,0xbf,0xb5,0x0f,0x35,0x7c,0x24,0x98,0x7f,0x32,0xa9,0x56,0x84,0xb7,0xfd,0x17,
0xfb,0x06,0x35,0x26,0x8f,0x02,0xfd,0xb4,0x15,0x54,0x00,0x00,0x00,0x00,0x49,0x45,
0x4e,0x44,0xae,0x42,0x60,0x82};
// Created with image_to_c
// https://github.com/bitbank2/image_to_c
//
// r12
// Data size = 484 bytes
//
// PNG, Compression=Flate, Size: 36 x 26, 32-Bpp
//
// for non-Arduino builds...
#ifndef PROGMEM
#define PROGMEM
#endif
const uint8_t r12[] PROGMEM = {
0x89,0x50,0x4e,0x47,0x0d,0x0a,0x1a,0x0a,0x00,0x00,0x00,0x0d,0x49,0x48,0x44,0x52,
0x00,0x00,0x00,0x24,0x00,0x00,0x00,0x1a,0x08,0x06,0x00,0x00,0x00,0xdf,0x70,0xfe,
0x45,0x00,0x00,0x00,0x01,0x73,0x52,0x47,0x42,0x00,0xae,0xce,0x1c,0xe9,0x00,0x00,
0x00,0x06,0x62,0x4b,0x47,0x44,0x00,0xff,0x00,0xff,0x00,0xff,0xa0,0xbd,0xa7,0x93,
0x00,0x00,0x00,0x09,0x70,0x48,0x59,0x73,0x00,0x00,0x0b,0x13,0x00,0x00,0x0b,0x13,
0x01,0x00,0x9a,0x9c,0x18,0x00,0x00,0x00,0x07,0x74,0x49,0x4d,0x45,0x07,0xdc,0x02,
0x04,0x01,0x2e,0x01,0x21,0x48,0xe1,0x4e,0x00,0x00,0x00,0x1d,0x69,0x54,0x58,0x74,
0x43,0x6f,0x6d,0x6d,0x65,0x6e,0x74,0x00,0x00,0x00,0x00,0x00,0x43,0x72,0x65,0x61,
0x74,0x65,0x64,0x20,0x77,0x69,0x74,0x68,0x20,0x47,0x49,0x4d,0x50,0x64,0x2e,0x65,
0x07,0x00,0x00,0x01,0x3b,0x49,0x44,0x41,0x54,0x48,0xc7,0xed,0x96,0xcb,0x8d,0x02,
0x31,0x0c,0x40,0xe3,0x88,0xcb,0xf6,0x41,0x07,0xd0,0x01,0x7d,0xec,0x31,0xae,0xc9,
0xa9,0x89,0xa9,0xc9,0x7b,0x21,0x99,0x4c,0xb0,0xc7,0xf6,0x20,0x56,0x42,0xc2,0xa7,
0x11,0x31,0xf1,0xf3,0x3f,0x29,0x7d,0xe5,0xc3,0x04,0x02,0xba,0xfc,0x1f,0xf6,0xbc,
0x40,0xcc,0x77,0x7a,0x9d,0xe6,0x8a,0xa6,0x4d,0x08,0xc3,0x2c,0x25,0x4e,0x72,0xa9,
0x6e,0xa8,0x1c,0xba,0x58,0x83,0xa9,0x55,0xfe,0x3e,0xe0,0x44,0x0e,0xc3,0x48,0x06,
0xcb,0x6a,0x10,0x16,0x4c,0x80,0xe0,0x81,0x62,0xa9,0x2e,0x73,0x38,0xfc,0x45,0xf7,
0x16,0x10,0x12,0x11,0x25,0x22,0x5a,0xa1,0x24,0x07,0x52,0xe2,0xa6,0x37,0x43,0x9d,
0xde,0xd5,0xbe,0x0d,0x8a,0x89,0xc5,0x33,0x4d,0x4e,0x4a,0x6b,0xfb,0xc7,0x41,0xad,
0x6a,0xd4,0x36,0x91,0x72,0xc0,0xcc,0x40,0xdc,0x94,0x11,0x91,0xdd,0x50,0xa5,0x98,
0x91,0x8a,0x48,0x36,0x06,0x21,0x9b,0x5d,0x35,0xd5,0xcf,0x91,0xd4,0x8e,0x76,0xf2,
0xe6,0x4e,0xc4,0xae,0x34,0x14,0x9d,0x1d,0x15,0x01,0xf0,0x5c,0x7e,0x53,0xbb,0x2f,
0x72,0x96,0x9f,0x1c,0x45,0x54,0x95,0x95,0x8e,0x11,0xd3,0x76,0x83,0x9f,0xa7,0xdf,
0xda,0xbd,0xd2,0x99,0x67,0x52,0xf7,0x30,0xf2,0x9d,0xcc,0xe1,0xd6,0x52,0xd6,0xb4,
0xaa,0xa7,0xfc,0xd6,0x28,0x74,0x96,0x6c,0xac,0x15,0x30,0x3b,0x6c,0x47,0xc6,0x48,
0x6b,0xdf,0xaf,0xed,0xb2,0xa5,0xec,0xb6,0xf9,0x5c,0xd8,0x7b,0x86,0x87,0x8e,0xde,
0x70,0x58,0x40,0xdc,0x53,0xe6,0xdc,0x4b,0x91,0x6e,0x9b,0x61,0xcc,0x1a,0x22,0xa2,
0xee,0x65,0xe4,0xf9,0xf1,0xd8,0xe8,0x87,0xde,0x47,0xb0,0x07,0xe3,0x09,0x7d,0x74,
0xe6,0x48,0x51,0x09,0xed,0xb2,0xe1,0x02,0xd6,0xf2,0xae,0x39,0x23,0xfd,0xf7,0xe8,
0x8b,0x91,0x05,0x1d,0x8e,0x8e,0x8b,0x49,0x8f,0x83,0xcd,0xf4,0x95,0xcf,0x90,0x3f,
0xbd,0xa2,0x95,0x2f,0x7f,0x64,0xeb,0xd7,0x00,0x00,0x00,0x00,0x49,0x45,0x4e,0x44,
0xae,0x42,0x60,0x82};
// Created with image_to_c
// https://github.com/bitbank2/image_to_c
//
// r1
// Data size = 477 bytes
//
// PNG, Compression=Flate, Size: 36 x 26, 32-Bpp
//
// for non-Arduino builds...
#ifndef PROGMEM
#define PROGMEM
#endif
const uint8_t r1[] PROGMEM = {
0x89,0x50,0x4e,0x47,0x0d,0x0a,0x1a,0x0a,0x00,0x00,0x00,0x0d,0x49,0x48,0x44,0x52,
0x00,0x00,0x00,0x24,0x00,0x00,0x00,0x1a,0x08,0x06,0x00,0x00,0x00,0xdf,0x70,0xfe,
0x45,0x00,0x00,0x00,0x01,0x73,0x52,0x47,0x42,0x00,0xae,0xce,0x1c,0xe9,0x00,0x00,
0x00,0x06,0x62,0x4b,0x47,0x44,0x00,0xff,0x00,0xff,0x00,0xff,0xa0,0xbd,0xa7,0x93,
0x00,0x00,0x00,0x09,0x70,0x48,0x59,0x73,0x00,0x00,0x0b,0x13,0x00,0x00,0x0b,0x13,
0x01,0x00,0x9a,0x9c,0x18,0x00,0x00,0x00,0x07,0x74,0x49,0x4d,0x45,0x07,0xdc,0x02,
0x04,0x01,0x2e,0x01,0x21,0x48,0xe1,0x4e,0x00,0x00,0x00,0x1d,0x69,0x54,0x58,0x74,
0x43,0x6f,0x6d,0x6d,0x65,0x6e,0x74,0x00,0x00,0x00,0x00,0x00,0x43,0x72,0x65,0x61,
0x74,0x65,0x64,0x20,0x77,0x69,0x74,0x68,0x20,0x47,0x49,0x4d,0x50,0x64,0x2e,0x65,
0x07,0x00,0x00,0x01,0x34,0x49,0x44,0x41,0x54,0x48,0xc7,0xed,0x96,0xcd,0x99,0x03,
0x21,0x08,0x86,0xc5,0x67,0x2e,0xdb,0x47,0x3a,0x48,0x3a,0xd8,0x3e,0xf6,0x28,0x35,
0x61,0x4d,0xd9,0x9a,0xd8,0xcb,0x3a,0x31,0x0a,0x08,0xf9,0x3b,0x0d,0x97,0xf1,0x19,
0x05,0x5f,0x3f,0x41,0x4d,0xe9,0x30,0xdb,0x20,0x30,0x96,0x3f,0x31,0x9f,0x17,0x88,
0xf9,0x4a,0xcf,0xd3,0x5c,0x70,0x39,0x27,0x84,0x61,0x7e,0x4b,0x9c,0xe4,0x5c,0xdd,
0x50,0x39,0x14,0x58,0x83,0xa9,0x55,0x6e,0x3f,0xb0,0x88,0x1c,0x86,0x91,0x26,0x2c,
0x45,0x6e,0x3f,0x00,0x95,0xc3,0xf2,0x17,0x3b,0x30,0x20,0x24,0x40,0xb0,0x15,0xbb,
0x15,0xc9,0x54,0x28,0xdb,0x4b,0x4b,0x16,0x21,0x11,0xd1,0xde,0x66,0x62,0x6d,0x01,
0xdc,0xc6,0x21,0x22,0xf7,0x39,0x95,0x05,0x62,0x0e,0x95,0xb8,0xa2,0x00,0x11,0xdd,
0x2b,0x35,0xf4,0x69,0xb6,0x49,0x03,0x11,0xb1,0x01,0xc2,0x33,0x5b,0x28,0x41,0x59,
0x30,0x13,0x10,0x22,0x26,0x22,0x4a,0x44,0xd4,0x43,0xc9,0xaa,0x14,0x5f,0x92,0xae,
0x00,0xac,0xa4,0x86,0x4e,0x1d,0x3b,0xd0,0x08,0x53,0xeb,0x5d,0xfe,0x44,0xec,0xdf,
0x87,0xb5,0x2a,0xb3,0xa1,0xb4,0x8a,0x11,0xd4,0x3a,0x95,0x9f,0x3d,0x4e,0xa4,0x2f,
0x6b,0xa7,0x37,0x22,0xce,0x4e,0xc5,0x7f,0xc0,0x7d,0xc3,0xd7,0xf4,0xaf,0xc5,0x93,
0xfa,0x56,0x65,0x0f,0xae,0x0b,0x55,0xc8,0xa5,0x72,0xdb,0x0b,0x35,0x9f,0xda,0xb7,
0x8d,0xc5,0xc0,0xc1,0x08,0xd3,0x7d,0xd4,0x6f,0xdb,0x42,0xb1,0x5e,0x61,0xad,0xfd,
0xd6,0xcb,0x75,0x4c,0x6c,0x6b,0xe2,0xe1,0x88,0x01,0x2f,0xd0,0xbe,0x65,0xde,0xe7,
0x07,0x5c,0xd0,0x5d,0x6d,0x23,0xcc,0x0a,0x88,0xbd,0xab,0x7d,0xe5,0x83,0x6d,0x0b,
0xac,0xa4,0x05,0x60,0x4d,0x6e,0xe5,0xae,0x8a,0xf8,0xd9,0x0a,0x39,0x2a,0xcf,0xeb,
0x3f,0xfa,0x42,0x3a,0xec,0xb0,0x37,0xd9,0x1f,0xe5,0x5f,0x90,0x9d,0xe7,0x7f,0xd5,
0x7b,0x00,0x00,0x00,0x00,0x49,0x45,0x4e,0x44,0xae,0x42,0x60,0x82};
// Created with image_to_c
// https://github.com/bitbank2/image_to_c
//
// r2
// Data size = 476 bytes
//
// PNG, Compression=Flate, Size: 36 x 26, 32-Bpp
//
// for non-Arduino builds...
#ifndef PROGMEM
#define PROGMEM
#endif
const uint8_t r2[] PROGMEM = {
0x89,0x50,0x4e,0x47,0x0d,0x0a,0x1a,0x0a,0x00,0x00,0x00,0x0d,0x49,0x48,0x44,0x52,
0x00,0x00,0x00,0x24,0x00,0x00,0x00,0x1a,0x08,0x06,0x00,0x00,0x00,0xdf,0x70,0xfe,
0x45,0x00,0x00,0x00,0x01,0x73,0x52,0x47,0x42,0x00,0xae,0xce,0x1c,0xe9,0x00,0x00,
0x00,0x06,0x62,0x4b,0x47,0x44,0x00,0xff,0x00,0xff,0x00,0xff,0xa0,0xbd,0xa7,0x93,
0x00,0x00,0x00,0x09,0x70,0x48,0x59,0x73,0x00,0x00,0x0b,0x13,0x00,0x00,0x0b,0x13,
0x01,0x00,0x9a,0x9c,0x18,0x00,0x00,0x00,0x07,0x74,0x49,0x4d,0x45,0x07,0xdc,0x02,
0x04,0x01,0x2e,0x01,0x21,0x48,0xe1,0x4e,0x00,0x00,0x00,0x1d,0x69,0x54,0x58,0x74,
0x43,0x6f,0x6d,0x6d,0x65,0x6e,0x74,0x00,0x00,0x00,0x00,0x00,0x43,0x72,0x65,0x61,
0x74,0x65,0x64,0x20,0x77,0x69,0x74,0x68,0x20,0x47,0x49,0x4d,0x50,0x64,0x2e,0x65,
0x07,0x00,0x00,0x01,0x33,0x49,0x44,0x41,0x54,0x48,0xc7,0xed,0x56,0xc1,0x0d,0x83,
0x30,0x0c,0xb4,0x23,0x3e,0xdd,0xa3,0x1b,0xb4,0x1b,0x74,0x8f,0x3e,0xe3,0x99,0xcc,
0x4c,0xed,0x4c,0xee,0x87,0x40,0x08,0x36,0xd8,0xd0,0xf6,0x85,0x25,0xa4,0x08,0x1c,
0xe7,0x72,0xe7,0x4b,0x00,0x38,0x63,0x3d,0x30,0x90,0x2b,0xff,0x58,0xcf,0x0b,0x48,
0xe4,0xc5,0xc7,0xd1,0xdc,0x69,0x73,0x4d,0x0c,0x83,0x79,0xe7,0x38,0x92,0x5b,0xef,
0x06,0x95,0x42,0x85,0x2d,0x30,0x7d,0xaf,0x8f,0x77,0x6c,0x22,0x85,0xc1,0x68,0x0b,
0xe6,0xac,0x8f,0x77,0x80,0x4a,0x61,0xfa,0xf3,0x76,0x61,0x24,0x04,0x24,0xb4,0x37,
0x30,0x37,0xca,0xcc,0x2c,0xdd,0xd7,0x6d,0x4b,0x08,0xcc,0x3c,0x8e,0x85,0x4d,0x73,
0x4a,0xc9,0x23,0x22,0x29,0x7d,0x95,0x0e,0x23,0x58,0x61,0x80,0x99,0x27,0xa6,0x0c,
0x30,0x6d,0x74,0xc6,0x59,0x83,0xdf,0x92,0x50,0x03,0x65,0x81,0x69,0x01,0xa9,0x14,
0x9a,0xac,0x64,0xbf,0x73,0xd6,0x00,0x44,0x9a,0x5a,0xcc,0xd3,0xb9,0x05,0x33,0xc8,
0x56,0xf7,0x4f,0x24,0x86,0x39,0xd2,0x02,0x42,0x22,0x1a,0x13,0xca,0xe3,0xea,0x17,
0x83,0xad,0x6b,0x7e,0x42,0xa9,0xe9,0xfd,0x96,0x16,0x26,0x21,0x32,0x8b,0x44,0x64,
0x02,0x00,0x78,0xe0,0x65,0xf1,0xae,0xd4,0xd6,0xbe,0x6d,0x35,0xef,0x28,0x97,0xbc,
0x58,0x3f,0xd8,0x9a,0x5e,0x2a,0x92,0x95,0x37,0xbd,0xc7,0x13,0x13,0x13,0x00,0x00,
0x98,0x36,0xee,0x39,0x5c,0xdc,0x47,0xb5,0x6c,0x0e,0xc6,0x6a,0xb6,0xad,0xf1,0x4f,
0x2f,0xd7,0xb6,0xb1,0x4d,0xf9,0x2b,0xf7,0x0d,0x39,0xe8,0x06,0x34,0xca,0x16,0xf8,
0xcd,0xf0,0xba,0xad,0x06,0xe3,0x01,0x24,0xcd,0x2e,0x7e,0xfe,0x93,0xd8,0xed,0x98,
0x2c,0x1a,0xd5,0x8e,0xcd,0xb8,0xe6,0xa2,0x47,0x2e,0x25,0x57,0xa2,0x4e,0xad,0xf2,
0x24,0xd8,0xc3,0x67,0x9c,0x11,0x8a,0x0f,0x8f,0x76,0x8b,0x35,0xbb,0xdf,0x39,0x63,
0x00,0x00,0x00,0x00,0x49,0x45,0x4e,0x44,0xae,0x42,0x60,0x82};
// Created with image_to_c
// https://github.com/bitbank2/image_to_c
//
// r3
// Data size = 477 bytes
//
// PNG, Compression=Flate, Size: 36 x 26, 32-Bpp
//
// for non-Arduino builds...
#ifndef PROGMEM
#define PROGMEM
#endif
const uint8_t r3[] PROGMEM = {
0x89,0x50,0x4e,0x47,0x0d,0x0a,0x1a,0x0a,0x00,0x00,0x00,0x0d,0x49,0x48,0x44,0x52,
0x00,0x00,0x00,0x24,0x00,0x00,0x00,0x1a,0x08,0x06,0x00,0x00,0x00,0xdf,0x70,0xfe,
0x45,0x00,0x00,0x00,0x01,0x73,0x52,0x47,0x42,0x00,0xae,0xce,0x1c,0xe9,0x00,0x00,
0x00,0x06,0x62,0x4b,0x47,0x44,0x00,0xff,0x00,0xff,0x00,0xff,0xa0,0xbd,0xa7,0x93,
0x00,0x00,0x00,0x09,0x70,0x48,0x59,0x73,0x00,0x00,0x0b,0x13,0x00,0x00,0x0b,0x13,
0x01,0x00,0x9a,0x9c,0x18,0x00,0x00,0x00,0x07,0x74,0x49,0x4d,0x45,0x07,0xdc,0x02,
0x04,0x01,0x2e,0x01,0x21,0x48,0xe1,0x4e,0x00,0x00,0x00,0x1d,0x69,0x54,0x58,0x74,
0x43,0x6f,0x6d,0x6d,0x65,0x6e,0x74,0x00,0x00,0x00,0x00,0x00,0x43,0x72,0x65,0x61,
0x74,0x65,0x64,0x20,0x77,0x69,0x74,0x68,0x20,0x47,0x49,0x4d,0x50,0x64,0x2e,0x65,
0x07,0x00,0x00,0x01,0x34,0x49,0x44,0x41,0x54,0x48,0xc7,0xed,0x96,0xc1,0x6d,0xc3,
0x30,0x0c,0x45,0x49,0x23,0x97,0xee,0xd1,0x0d,0x9a,0x0d,0xb2,0x47,0x8e,0xfa,0x33,
0x51,0x33,0xb5,0x33,0xb1,0x97,0x28,0x91,0x65,0xd2,0x26,0xed,0xb4,0x68,0x81,0x10,
0x10,0x2c,0xcb,0xb4,0xf4,0x48,0x7d,0x5a,0x26,0x7a,0xd9,0x3f,0x33,0x4e,0xf8,0xea,
0x6f,0xac,0x17,0x05,0x52,0xfd,0x94,0xe3,0x34,0x67,0x6c,0xae,0xc9,0x69,0x98,0xaf,
0x92,0x27,0xf9,0xa8,0x61,0xa8,0x29,0x35,0xb1,0x07,0x53,0xab,0xdd,0xdf,0x11,0xc4,
0x94,0x86,0xb1,0x16,0x2c,0xc5,0xee,0xef,0x80,0x9a,0xd2,0xe9,0x2f,0xdb,0x13,0x33,
0x98,0x18,0xec,0x07,0x30,0x2f,0x94,0x59,0xb1,0x9c,0x9e,0x5e,0xb6,0x60,0x12,0x91,
0x7b,0x5f,0xc5,0x2d,0x4e,0x6d,0x7e,0x00,0xb4,0xe9,0x6a,0x3a,0x4c,0xb0,0x92,0x01,
0x11,0x79,0x64,0xca,0x81,0x19,0xed,0x78,0x86,0x36,0xb6,0xd0,0x82,0xf2,0x60,0xf6,
0x03,0xd5,0x1a,0xd2,0x52,0x04,0x20,0x2b,0x6a,0x0d,0x65,0xe5,0xb6,0x6d,0xbd,0x7e,
0x32,0x76,0x7b,0x47,0x3d,0x20,0xb5,0xd4,0xbf,0xaa,0x17,0x27,0x5b,0xef,0xe5,0x4a,
0x00,0x52,0xcf,0x4e,0x63,0x36,0xc6,0x08,0x67,0x2f,0x95,0xdc,0x57,0xfa,0xc2,0x6f,
0x8b,0x31,0x00,0x24,0x22,0xe6,0xb3,0x85,0x86,0x7a,0x18,0x2f,0xb2,0x88,0x96,0xca,
0x63,0x42,0x57,0x4f,0xed,0xda,0x7c,0x61,0x68,0x88,0x01,0x50,0x6b,0x8b,0xb3,0xae,
0x9d,0x47,0xfd,0xb6,0x05,0x32,0xd6,0x07,0xe6,0xf5,0x7f,0xf4,0x70,0x1d,0x85,0xbd,
0x96,0xe9,0xee,0xc3,0x78,0x67,0x09,0x01,0x11,0x11,0x65,0x7e,0x3f,0xf8,0x8c,0x70,
0xb5,0xf5,0x30,0xe1,0x1f,0x33,0x11,0xd1,0xa1,0xfa,0x9e,0xd9,0xf6,0x1d,0xae,0x5d,
0xc4,0xdc,0xee,0x87,0x31,0xab,0x59,0x7e,0xe3,0x58,0x5e,0x43,0x8e,0xbf,0x06,0xe7,
0xb1,0xfc,0x34,0xc9,0xf0,0xb2,0xbf,0x6b,0xdf,0x3b,0x6d,0x9d,0xdf,0xee,0x13,0x74,
0x8a,0x00,0x00,0x00,0x00,0x49,0x45,0x4e,0x44,0xae,0x42,0x60,0x82};
// Created with image_to_c
// https://github.com/bitbank2/image_to_c
//
// r4
// Data size = 468 bytes
//
// PNG, Compression=Flate, Size: 36 x 26, 32-Bpp
//
// for non-Arduino builds...
#ifndef PROGMEM
#define PROGMEM
#endif
const uint8_t r4[] PROGMEM = {
0x89,0x50,0x4e,0x47,0x0d,0x0a,0x1a,0x0a,0x00,0x00,0x00,0x0d,0x49,0x48,0x44,0x52,
0x00,0x00,0x00,0x24,0x00,0x00,0x00,0x1a,0x08,0x06,0x00,0x00,0x00,0xdf,0x70,0xfe,
0x45,0x00,0x00,0x00,0x01,0x73,0x52,0x47,0x42,0x00,0xae,0xce,0x1c,0xe9,0x00,0x00,
0x00,0x06,0x62,0x4b,0x47,0x44,0x00,0xff,0x00,0xff,0x00,0xff,0xa0,0xbd,0xa7,0x93,
0x00,0x00,0x00,0x09,0x70,0x48,0x59,0x73,0x00,0x00,0x0b,0x13,0x00,0x00,0x0b,0x13,
0x01,0x00,0x9a,0x9c,0x18,0x00,0x00,0x00,0x07,0x74,0x49,0x4d,0x45,0x07,0xdc,0x02,
0x04,0x01,0x2e,0x01,0x21,0x48,0xe1,0x4e,0x00,0x00,0x00,0x1d,0x69,0x54,0x58,0x74,
0x43,0x6f,0x6d,0x6d,0x65,0x6e,0x74,0x00,0x00,0x00,0x00,0x00,0x43,0x72,0x65,0x61,
0x74,0x65,0x64,0x20,0x77,0x69,0x74,0x68,0x20,0x47,0x49,0x4d,0x50,0x64,0x2e,0x65,
0x07,0x00,0x00,0x01,0x2b,0x49,0x44,0x41,0x54,0x48,0xc7,0xed,0x96,0x4b,0x12,0xc2,
0x30,0x08,0x86,0x21,0xd3,0x8d,0xf7,0xf0,0x06,0xf6,0x06,0xde,0xc3,0x65,0x38,0x53,
0x72,0x26,0x3d,0x13,0x6e,0x1a,0x9b,0xa6,0xd0,0x42,0xe3,0x38,0x3a,0x23,0x9b,0x66,
0xda,0x3c,0x3e,0xe0,0x27,0x14,0xe0,0x6f,0x3f,0x66,0xe8,0x98,0xcb,0x9f,0x38,0xcf,
0x0a,0xc4,0x7c,0x4f,0xfd,0x34,0x23,0xed,0x9e,0x89,0x6e,0x98,0x47,0xf4,0x93,0x5c,
0xb2,0x19,0x2a,0xb8,0x36,0xd6,0x60,0x72,0x96,0xc7,0x07,0x9c,0x08,0x6e,0x18,0xe9,
0xc0,0x18,0xe5,0xf1,0x01,0xa8,0xe0,0x0e,0x7f,0xdc,0xdf,0x18,0x09,0x01,0x09,0x75,
0x07,0x96,0x85,0xb2,0x28,0x96,0xe1,0xed,0x65,0x4b,0x08,0x29,0xa5,0xd7,0x98,0x93,
0x5a,0x9c,0x5c,0xe6,0x11,0x11,0x17,0x5d,0x85,0x6e,0x82,0x8d,0x08,0xa4,0x94,0xe6,
0x48,0x29,0x30,0xad,0xf5,0x47,0x68,0x27,0x85,0x12,0x94,0x06,0x73,0x1c,0x28,0x67,
0x93,0x96,0x2c,0x00,0x1e,0x51,0xb3,0x7a,0x3b,0xb7,0x30,0x53,0xda,0x6a,0xfd,0x78,
0x6c,0x5a,0xc3,0x1a,0x10,0x97,0x1c,0xaf,0x36,0xd7,0xf4,0xa2,0x44,0xeb,0x1c,0x6f,
0x40,0x44,0xae,0x6f,0x41,0x12,0x9b,0xea,0x65,0xf4,0xdd,0xd2,0x57,0x3c,0xad,0xde,
0x15,0x08,0xe9,0x5b,0xab,0xa1,0xba,0x0c,0xbb,0xb4,0x14,0xe7,0x5c,0xa8,0x7a,0x2a,
0xcf,0x32,0x97,0x0c,0x1a,0xc2,0x45,0xcf,0x29,0xfd,0xa8,0x4e,0x9b,0x21,0x62,0xb5,
0x73,0xda,0x78,0xab,0xb9,0xb2,0xf0,0xde,0xd5,0x5c,0x5b,0x61,0x6f,0x45,0xbb,0xc9,
0x08,0x9a,0xbb,0x3d,0x00,0x80,0xe7,0xf7,0x03,0x47,0x32,0x57,0x5b,0x0d,0x63,0x01,
0xf2,0xeb,0xaa,0xf3,0xa7,0x6d,0x38,0xb0,0x98,0xa5,0x50,0x1b,0x9c,0x31,0xad,0x45,
0x4b,0xba,0x24,0x5d,0x19,0xf7,0x90,0xe6,0xb1,0xe3,0xfc,0xbf,0x7d,0xbf,0x3d,0x01,
0x02,0x72,0x88,0x5a,0x43,0x81,0x64,0x26,0x00,0x00,0x00,0x00,0x49,0x45,0x4e,0x44,
0xae,0x42,0x60,0x82};
// Created with image_to_c
// https://github.com/bitbank2/image_to_c
//
// r5
// Data size = 395 bytes
//
// PNG, Compression=Flate, Size: 36 x 26, 32-Bpp
//
// for non-Arduino builds...
#ifndef PROGMEM
#define PROGMEM
#endif
const uint8_t r5[] PROGMEM = {
0x89,0x50,0x4e,0x47,0x0d,0x0a,0x1a,0x0a,0x00,0x00,0x00,0x0d,0x49,0x48,0x44,0x52,
0x00,0x00,0x00,0x24,0x00,0x00,0x00,0x1a,0x08,0x06,0x00,0x00,0x00,0xdf,0x70,0xfe,
0x45,0x00,0x00,0x00,0x09,0x70,0x48,0x59,0x73,0x00,0x00,0x0b,0x13,0x00,0x00,0x0b,
0x13,0x01,0x00,0x9a,0x9c,0x18,0x00,0x00,0x01,0x3d,0x49,0x44,0x41,0x54,0x48,0xc7,
0xed,0x96,0xcb,0x71,0x03,0x31,0x08,0x86,0x41,0xb3,0x17,0xf7,0x91,0x0e,0xe2,0x0e,
0xdc,0x47,0x8e,0xa2,0x26,0x54,0x93,0x5d,0x13,0xb9,0x44,0x36,0xbb,0x11,0x08,0x76,
0x3d,0x9e,0x49,0xc6,0x5c,0xac,0x19,0xb1,0xe2,0xd3,0x6f,0x1e,0x02,0x78,0xdb,0x1f,
0x33,0x4c,0xf8,0xca,0x2b,0xe2,0x45,0x81,0x44,0xae,0x7c,0x9c,0xe6,0x4c,0xd3,0x98,
0x98,0x86,0xb9,0xd5,0x3c,0xc9,0x67,0x0b,0x43,0x95,0xd4,0xc1,0x16,0x4c,0x6b,0xe3,
0xf5,0x8e,0x4b,0x94,0x34,0xcc,0x28,0x60,0xad,0xe3,0xf5,0x0e,0xa8,0x92,0x96,0xbf,
0xfa,0x07,0x23,0x21,0x20,0xa1,0xaf,0xd8,0xa3,0x48,0x7e,0x15,0xca,0xf2,0xd4,0x92,
0x25,0x04,0x66,0xbe,0xaf,0x85,0xc5,0xba,0x80,0x74,0x3f,0x22,0x12,0x9d,0x53,0xe5,
0x30,0x85,0xa1,0x00,0x33,0xaf,0x95,0xda,0xec,0x59,0xb6,0x38,0x7d,0x06,0x8f,0xfe,
0x85,0x23,0x28,0x0f,0x46,0x03,0x89,0x76,0x24,0x22,0xbf,0x11,0xb6,0x36,0xcd,0xa5,
0x28,0x80,0xd5,0x87,0x64,0xf4,0xf1,0x0f,0x18,0xc8,0x95,0xfd,0x2a,0x69,0x0d,0xf0,
0x46,0xe9,0xe0,0x9b,0x38,0xa8,0x15,0x42,0x95,0x60,0xab,0xdb,0x75,0x28,0x57,0x99,
0x5a,0x01,0xb4,0x1f,0x00,0x7c,0xd4,0x2f,0xb8,0xe0,0x69,0x08,0xe9,0xed,0x95,0x81,
0x62,0xa8,0x00,0x53,0x25,0xaf,0xed,0x82,0x27,0x4b,0x89,0xe1,0x5e,0xa4,0xec,0x71,
0x3a,0x54,0x07,0x8a,0xd5,0x87,0xbc,0x66,0x3e,0xf5,0xdf,0xee,0x4b,0xbb,0x1a,0x63,
0x9f,0x47,0xba,0xcc,0x27,0x8a,0x69,0x85,0xad,0x75,0x76,0xb8,0xca,0x3d,0xa9,0x03,
0x23,0x40,0x37,0xc6,0x59,0x60,0xd5,0x18,0x57,0x1c,0x18,0x7d,0xff,0x44,0x9f,0x1f,
0x78,0x8e,0x57,0xdb,0x16,0xc6,0x03,0x92,0xe8,0x4d,0x9f,0xfd,0x60,0x5b,0x12,0xb7,
0x10,0x4b,0x66,0x67,0x4e,0x65,0xbf,0xb5,0x0f,0x35,0x7c,0x24,0x98,0x7f,0x32,0xa9,
0x56,0x84,0xb7,0xfd,0x17,0xfb,0x06,0x35,0x26,0x8f,0x02,0xfd,0xb4,0x15,0x54,0x00,
0x00,0x00,0x00,0x49,0x45,0x4e,0x44,0xae,0x42,0x60,0x82};
// Created with image_to_c
// https://github.com/bitbank2/image_to_c
//
// r6
// Data size = 484 bytes
//
// PNG, Compression=Flate, Size: 36 x 26, 32-Bpp
//
// for non-Arduino builds...
#ifndef PROGMEM
#define PROGMEM
#endif
const uint8_t r6[] PROGMEM = {
0x89,0x50,0x4e,0x47,0x0d,0x0a,0x1a,0x0a,0x00,0x00,0x00,0x0d,0x49,0x48,0x44,0x52,
0x00,0x00,0x00,0x24,0x00,0x00,0x00,0x1a,0x08,0x06,0x00,0x00,0x00,0xdf,0x70,0xfe,
0x45,0x00,0x00,0x00,0x01,0x73,0x52,0x47,0x42,0x00,0xae,0xce,0x1c,0xe9,0x00,0x00,
0x00,0x06,0x62,0x4b,0x47,0x44,0x00,0xff,0x00,0xff,0x00,0xff,0xa0,0xbd,0xa7,0x93,
0x00,0x00,0x00,0x09,0x70,0x48,0x59,0x73,0x00,0x00,0x0b,0x13,0x00,0x00,0x0b,0x13,
0x01,0x00,0x9a,0x9c,0x18,0x00,0x00,0x00,0x07,0x74,0x49,0x4d,0x45,0x07,0xdc,0x02,
0x04,0x01,0x2e,0x01,0x21,0x48,0xe1,0x4e,0x00,0x00,0x00,0x1d,0x69,0x54,0x58,0x74,
0x43,0x6f,0x6d,0x6d,0x65,0x6e,0x74,0x00,0x00,0x00,0x00,0x00,0x43,0x72,0x65,0x61,
0x74,0x65,0x64,0x20,0x77,0x69,0x74,0x68,0x20,0x47,0x49,0x4d,0x50,0x64,0x2e,0x65,
0x07,0x00,0x00,0x01,0x3b,0x49,0x44,0x41,0x54,0x48,0xc7,0xed,0x96,0xcb,0x8d,0x02,
0x31,0x0c,0x40,0xe3,0x88,0xcb,0xf6,0x41,0x07,0xd0,0x01,0x7d,0xec,0x31,0xae,0xc9,
0xa9,0x89,0xa9,0xc9,0x7b,0x21,0x99,0x4c,0xb0,0xc7,0xf6,0x20,0x56,0x42,0xc2,0xa7,
0x11,0x31,0xf1,0xf3,0x3f,0x29,0x7d,0xe5,0xc3,0x04,0x02,0xba,0xfc,0x1f,0xf6,0xbc,
0x40,0xcc,0x77,0x7a,0x9d,0xe6,0x8a,0xa6,0x4d,0x08,0xc3,0x2c,0x25,0x4e,0x72,0xa9,
0x6e,0xa8,0x1c,0xba,0x58,0x83,0xa9,0x55,0xfe,0x3e,0xe0,0x44,0x0e,0xc3,0x48,0x06,
0xcb,0x6a,0x10,0x16,0x4c,0x80,0xe0,0x81,0x62,0xa9,0x2e,0x73,0x38,0xfc,0x45,0xf7,
0x16,0x10,0x12,0x11,0x25,0x22,0x5a,0xa1,0x24,0x07,0x52,0xe2,0xa6,0x37,0x43,0x9d,
0xde,0xd5,0xbe,0x0d,0x8a,0x89,0xc5,0x33,0x4d,0x4e,0x4a,0x6b,0xfb,0xc7,0x41,0xad,
0x6a,0xd4,0x36,0x91,0x72,0xc0,0xcc,0x40,0xdc,0x94,0x11,0x91,0xdd,0x50,0xa5,0x98,
0x91,0x8a,0x48,0x36,0x06,0x21,0x9b,0x5d,0x35,0xd5,0xcf,0x91,0xd4,0x8e,0x76,0xf2,
0xe6,0x4e,0xc4,0xae,0x34,0x14,0x9d,0x1d,0x15,0x01,0xf0,0x5c,0x7e,0x53,0xbb,0x2f,
0x72,0x96,0x9f,0x1c,0x45,0x54,0x95,0x95,0x8e,0x11,0xd3,0x76,0x83,0x9f,0xa7,0xdf,
0xda,0xbd,0xd2,0x99,0x67,0x52,0xf7,0x30,0xf2,0x9d,0xcc,0xe1,0xd6,0x52,0xd6,0xb4,
0xaa,0xa7,0xfc,0xd6,0x28,0x74,0x96,0x6c,0xac,0x15,0x30,0x3b,0x6c,0x47,0xc6,0x48,
0x6b,0xdf,0xaf,0xed,0xb2,0xa5,0xec,0xb6,0xf9,0x5c,0xd8,0x7b,0x86,0x87,0x8e,0xde,
0x70,0x58,0x40,0xdc,0x53,0xe6,0xdc,0x4b,0x91,0x6e,0x9b,0x61,0xcc,0x1a,0x22,0xa2,
0xee,0x65,0xe4,0xf9,0xf1,0xd8,0xe8,0x87,0xde,0x47,0xb0,0x07,0xe3,0x09,0x7d,0x74,
0xe6,0x48,0x51,0x09,0xed,0xb2,0xe1,0x02,0xd6,0xf2,0xae,0x39,0x23,0xfd,0xf7,0xe8,
0x8b,0x91,0x05,0x1d,0x8e,0x8e,0x8b,0x49,0x8f,0x83,0xcd,0xf4,0x95,0xcf,0x90,0x3f,
0xbd,0xa2,0x95,0x2f,0x7f,0x64,0xeb,0xd7,0x00,0x00,0x00,0x00,0x49,0x45,0x4e,0x44,
0xae,0x42,0x60,0x82};
// Created with image_to_c
// https://github.com/bitbank2/image_to_c
//
// r7
// Data size = 477 bytes
//
// PNG, Compression=Flate, Size: 36 x 26, 32-Bpp
//
// for non-Arduino builds...
#ifndef PROGMEM
#define PROGMEM
#endif
const uint8_t r7[] PROGMEM = {
0x89,0x50,0x4e,0x47,0x0d,0x0a,0x1a,0x0a,0x00,0x00,0x00,0x0d,0x49,0x48,0x44,0x52,
0x00,0x00,0x00,0x24,0x00,0x00,0x00,0x1a,0x08,0x06,0x00,0x00,0x00,0xdf,0x70,0xfe,
0x45,0x00,0x00,0x00,0x01,0x73,0x52,0x47,0x42,0x00,0xae,0xce,0x1c,0xe9,0x00,0x00,
0x00,0x06,0x62,0x4b,0x47,0x44,0x00,0xff,0x00,0xff,0x00,0xff,0xa0,0xbd,0xa7,0x93,
0x00,0x00,0x00,0x09,0x70,0x48,0x59,0x73,0x00,0x00,0x0b,0x13,0x00,0x00,0x0b,0x13,
0x01,0x00,0x9a,0x9c,0x18,0x00,0x00,0x00,0x07,0x74,0x49,0x4d,0x45,0x07,0xdc,0x02,
0x04,0x01,0x2e,0x01,0x21,0x48,0xe1,0x4e,0x00,0x00,0x00,0x1d,0x69,0x54,0x58,0x74,
0x43,0x6f,0x6d,0x6d,0x65,0x6e,0x74,0x00,0x00,0x00,0x00,0x00,0x43,0x72,0x65,0x61,
0x74,0x65,0x64,0x20,0x77,0x69,0x74,0x68,0x20,0x47,0x49,0x4d,0x50,0x64,0x2e,0x65,
0x07,0x00,0x00,0x01,0x34,0x49,0x44,0x41,0x54,0x48,0xc7,0xed,0x96,0xcd,0x99,0x03,
0x21,0x08,0x86,0xc5,0x67,0x2e,0xdb,0x47,0x3a,0x48,0x3a,0xd8,0x3e,0xf6,0x28,0x35,
0x61,0x4d,0xd9,0x9a,0xd8,0xcb,0x3a,0x31,0x0a,0x08,0xf9,0x3b,0x0d,0x97,0xf1,0x19,
0x05,0x5f,0x3f,0x41,0x4d,0xe9,0x30,0xdb,0x20,0x30,0x96,0x3f,0x31,0x9f,0x17,0x88,
0xf9,0x4a,0xcf,0xd3,0x5c,0x70,0x39,0x27,0x84,0x61,0x7e,0x4b,0x9c,0xe4,0x5c,0xdd,
0x50,0x39,0x14,0x58,0x83,0xa9,0x55,0x6e,0x3f,0xb0,0x88,0x1c,0x86,0x91,0x26,0x2c,
0x45,0x6e,0x3f,0x00,0x95,0xc3,0xf2,0x17,0x3b,0x30,0x20,0x24,0x40,0xb0,0x15,0xbb,
0x15,0xc9,0x54,0x28,0xdb,0x4b,0x4b,0x16,0x21,0x11,0xd1,0xde,0x66,0x62,0x6d,0x01,
0xdc,0xc6,0x21,0x22,0xf7,0x39,0x95,0x05,0x62,0x0e,0x95,0xb8,0xa2,0x00,0x11,0xdd,
0x2b,0x35,0xf4,0x69,0xb6,0x49,0x03,0x11,0xb1,0x01,0xc2,0x33,0x5b,0x28,0x41,0x59,
0x30,0x13,0x10,0x22,0x26,0x22,0x4a,0x44,0xd4,0x43,0xc9,0xaa,0x14,0x5f,0x92,0xae,
0x00,0xac,0xa4,0x86,0x4e,0x1d,0x3b,0xd0,0x08,0x53,0xeb,0x5d,0xfe,0x44,0xec,0xdf,
0x87,0xb5,0x2a,0xb3,0xa1,0xb4,0x8a,0x11,0xd4,0x3a,0x95,0x9f,0x3d,0x4e,0xa4,0x2f,
0x6b,0xa7,0x37,0x22,0xce,0x4e,0xc5,0x7f,0xc0,0x7d,0xc3,0xd7,0xf4,0xaf,0xc5,0x93,
0xfa,0x56,0x65,0x0f,0xae,0x0b,0x55,0xc8,0xa5,0x72,0xdb,0x0b,0x35,0x9f,0xda,0xb7,
0x8d,0xc5,0xc0,0xc1,0x08,0xd3,0x7d,0xd4,0x6f,0xdb,0x42,0xb1,0x5e,0x61,0xad,0xfd,
0xd6,0xcb,0x75,0x4c,0x6c,0x6b,0xe2,0xe1,0x88,0x01,0x2f,0xd0,0xbe,0x65,0xde,0xe7,
0x07,0x5c,0xd0,0x5d,0x6d,0x23,0xcc,0x0a,0x88,0xbd,0xab,0x7d,0xe5,0x83,0x6d,0x0b,
0xac,0xa4,0x05,0x60,0x4d,0x6e,0xe5,0xae,0x8a,0xf8,0xd9,0x0a,0x39,0x2a,0xcf,0xeb,
0x3f,0xfa,0x42,0x3a,0xec,0xb0,0x37,0xd9,0x1f,0xe5,0x5f,0x90,0x9d,0xe7,0x7f,0xd5,
0x7b,0x00,0x00,0x00,0x00,0x49,0x45,0x4e,0x44,0xae,0x42,0x60,0x82};
// Created with image_to_c
// https://github.com/bitbank2/image_to_c
//
// r8
// Data size = 476 bytes
//
// PNG, Compression=Flate, Size: 36 x 26, 32-Bpp
//
// for non-Arduino builds...
#ifndef PROGMEM
#define PROGMEM
#endif
const uint8_t r8[] PROGMEM = {
0x89,0x50,0x4e,0x47,0x0d,0x0a,0x1a,0x0a,0x00,0x00,0x00,0x0d,0x49,0x48,0x44,0x52,
0x00,0x00,0x00,0x24,0x00,0x00,0x00,0x1a,0x08,0x06,0x00,0x00,0x00,0xdf,0x70,0xfe,
0x45,0x00,0x00,0x00,0x01,0x73,0x52,0x47,0x42,0x00,0xae,0xce,0x1c,0xe9,0x00,0x00,
0x00,0x06,0x62,0x4b,0x47,0x44,0x00,0xff,0x00,0xff,0x00,0xff,0xa0,0xbd,0xa7,0x93,
0x00,0x00,0x00,0x09,0x70,0x48,0x59,0x73,0x00,0x00,0x0b,0x13,0x00,0x00,0x0b,0x13,
0x01,0x00,0x9a,0x9c,0x18,0x00,0x00,0x00,0x07,0x74,0x49,0x4d,0x45,0x07,0xdc,0x02,
0x04,0x01,0x2e,0x01,0x21,0x48,0xe1,0x4e,0x00,0x00,0x00,0x1d,0x69,0x54,0x58,0x74,
0x43,0x6f,0x6d,0x6d,0x65,0x6e,0x74,0x00,0x00,0x00,0x00,0x00,0x43,0x72,0x65,0x61,
0x74,0x65,0x64,0x20,0x77,0x69,0x74,0x68,0x20,0x47,0x49,0x4d,0x50,0x64,0x2e,0x65,
0x07,0x00,0x00,0x01,0x33,0x49,0x44,0x41,0x54,0x48,0xc7,0xed,0x56,0xc1,0x0d,0x83,
0x30,0x0c,0xb4,0x23,0x3e,0xdd,0xa3,0x1b,0xb4,0x1b,0x74,0x8f,0x3e,0xe3,0x99,0xcc,
0x4c,0xed,0x4c,0xee,0x87,0x40,0x08,0x36,0xd8,0xd0,0xf6,0x85,0x25,0xa4,0x08,0x1c,
0xe7,0x72,0xe7,0x4b,0x00,0x38,0x63,0x3d,0x30,0x90,0x2b,0xff,0x58,0xcf,0x0b,0x48,
0xe4,0xc5,0xc7,0xd1,0xdc,0x69,0x73,0x4d,0x0c,0x83,0x79,0xe7,0x38,0x92,0x5b,0xef,
0x06,0x95,0x42,0x85,0x2d,0x30,0x7d,0xaf,0x8f,0x77,0x6c,0x22,0x85,0xc1,0x68,0x0b,
0xe6,0xac,0x8f,0x77,0x80,0x4a,0x61,0xfa,0xf3,0x76,0x61,0x24,0x04,0x24,0xb4,0x37,
0x30,0x37,0xca,0xcc,0x2c,0xdd,0xd7,0x6d,0x4b,0x08,0xcc,0x3c,0x8e,0x85,0x4d,0x73,
0x4a,0xc9,0x23,0x22,0x29,0x7d,0x95,0x0e,0x23,0x58,0x61,0x80,0x99,0x27,0xa6,0x0c,
0x30,0x6d,0x74,0xc6,0x59,0x83,0xdf,0x92,0x50,0x03,0x65,0x81,0x69,0x01,0xa9,0x14,
0x9a,0xac,0x64,0xbf,0x73,0xd6,0x00,0x44,0x9a,0x5a,0xcc,0xd3,0xb9,0x05,0x33,0xc8,
0x56,0xf7,0x4f,0x24,0x86,0x39,0xd2,0x02,0x42,0x22,0x1a,0x13,0xca,0xe3,0xea,0x17,
0x83,0xad,0x6b,0x7e,0x42,0xa9,0xe9,0xfd,0x96,0x16,0x26,0x21,0x32,0x8b,0x44,0x64,
0x02,0x00,0x78,0xe0,0x65,0xf1,0xae,0xd4,0xd6,0xbe,0x6d,0x35,0xef,0x28,0x97,0xbc,
0x58,0x3f,0xd8,0x9a,0x5e,0x2a,0x92,0x95,0x37,0xbd,0xc7,0x13,0x13,0x13,0x00,0x00,
0x98,0x36,0xee,0x39,0x5c,0xdc,0x47,0xb5,0x6c,0x0e,0xc6,0x6a,0xb6,0xad,0xf1,0x4f,
0x2f,0xd7,0xb6,0xb1,0x4d,0xf9,0x2b,0xf7,0x0d,0x39,0xe8,0x06,0x34,0xca,0x16,0xf8,
0xcd,0xf0,0xba,0xad,0x06,0xe3,0x01,0x24,0xcd,0x2e,0x7e,0xfe,0x93,0xd8,0xed,0x98,
0x2c,0x1a,0xd5,0x8e,0xcd,0xb8,0xe6,0xa2,0x47,0x2e,0x25,0x57,0xa2,0x4e,0xad,0xf2,
0x24,0xd8,0xc3,0x67,0x9c,0x11,0x8a,0x0f,0x8f,0x76,0x8b,0x35,0xbb,0xdf,0x39,0x63,
0x00,0x00,0x00,0x00,0x49,0x45,0x4e,0x44,0xae,0x42,0x60,0x82};
// Created with image_to_c
// https://github.com/bitbank2/image_to_c
//
// r9
// Data size = 477 bytes
//
// PNG, Compression=Flate, Size: 36 x 26, 32-Bpp
//
// for non-Arduino builds...
#ifndef PROGMEM
#define PROGMEM
#endif
const uint8_t r9[] PROGMEM = {
0x89,0x50,0x4e,0x47,0x0d,0x0a,0x1a,0x0a,0x00,0x00,0x00,0x0d,0x49,0x48,0x44,0x52,
0x00,0x00,0x00,0x24,0x00,0x00,0x00,0x1a,0x08,0x06,0x00,0x00,0x00,0xdf,0x70,0xfe,
0x45,0x00,0x00,0x00,0x01,0x73,0x52,0x47,0x42,0x00,0xae,0xce,0x1c,0xe9,0x00,0x00,
0x00,0x06,0x62,0x4b,0x47,0x44,0x00,0xff,0x00,0xff,0x00,0xff,0xa0,0xbd,0xa7,0x93,
0x00,0x00,0x00,0x09,0x70,0x48,0x59,0x73,0x00,0x00,0x0b,0x13,0x00,0x00,0x0b,0x13,
0x01,0x00,0x9a,0x9c,0x18,0x00,0x00,0x00,0x07,0x74,0x49,0x4d,0x45,0x07,0xdc,0x02,
0x04,0x01,0x2e,0x01,0x21,0x48,0xe1,0x4e,0x00,0x00,0x00,0x1d,0x69,0x54,0x58,0x74,
0x43,0x6f,0x6d,0x6d,0x65,0x6e,0x74,0x00,0x00,0x00,0x00,0x00,0x43,0x72,0x65,0x61,
0x74,0x65,0x64,0x20,0x77,0x69,0x74,0x68,0x20,0x47,0x49,0x4d,0x50,0x64,0x2e,0x65,
0x07,0x00,0x00,0x01,0x34,0x49,0x44,0x41,0x54,0x48,0xc7,0xed,0x96,0xc1,0x6d,0xc3,
0x30,0x0c,0x45,0x49,0x23,0x97,0xee,0xd1,0x0d,0x9a,0x0d,0xb2,0x47,0x8e,0xfa,0x33,
0x51,0x33,0xb5,0x33,0xb1,0x97,0x28,0x91,0x65,0xd2,0x26,0xed,0xb4,0x68,0x81,0x10,
0x10,0x2c,0xcb,0xb4,0xf4,0x48,0x7d,0x5a,0x26,0x7a,0xd9,0x3f,0x33,0x4e,0xf8,0xea,
0x6f,0xac,0x17,0x05,0x52,0xfd,0x94,0xe3,0x34,0x67,0x6c,0xae,0xc9,0x69,0x98,0xaf,
0x92,0x27,0xf9,0xa8,0x61,0xa8,0x29,0x35,0xb1,0x07,0x53,0xab,0xdd,0xdf,0x11,0xc4,
0x94,0x86,0xb1,0x16,0x2c,0xc5,0xee,0xef,0x80,0x9a,0xd2,0xe9,0x2f,0xdb,0x13,0x33,
0x98,0x18,0xec,0x07,0x30,0x2f,0x94,0x59,0xb1,0x9c,0x9e,0x5e,0xb6,0x60,0x12,0x91,
0x7b,0x5f,0xc5,0x2d,0x4e,0x6d,0x7e,0x00,0xb4,0xe9,0x6a,0x3a,0x4c,0xb0,0x92,0x01,
0x11,0x79,0x64,0xca,0x81,0x19,0xed,0x78,0x86,0x36,0xb6,0xd0,0x82,0xf2,0x60,0xf6,
0x03,0xd5,0x1a,0xd2,0x52,0x04,0x20,0x2b,0x6a,0x0d,0x65,0xe5,0xb6,0x6d,0xbd,0x7e,
0x32,0x76,0x7b,0x47,0x3d,0x20,0xb5,0xd4,0xbf,0xaa,0x17,0x27,0x5b,0xef,0xe5,0x4a,
0x00,0x52,0xcf,0x4e,0x63,0x36,0xc6,0x08,0x67,0x2f,0x95,0xdc,0x57,0xfa,0xc2,0x6f,
0x8b,0x31,0x00,0x24,0x22,0xe6,0xb3,0x85,0x86,0x7a,0x18,0x2f,0xb2,0x88,0x96,0xca,
0x63,0x42,0x57,0x4f,0xed,0xda,0x7c,0x61,0x68,0x88,0x01,0x50,0x6b,0x8b,0xb3,0xae,
0x9d,0x47,0xfd,0xb6,0x05,0x32,0xd6,0x07,0xe6,0xf5,0x7f,0xf4,0x70,0x1d,0x85,0xbd,
0x96,0xe9,0xee,0xc3,0x78,0x67,0x09,0x01,0x11,0x11,0x65,0x7e,0x3f,0xf8,0x8c,0x70,
0xb5,0xf5,0x30,0xe1,0x1f,0x33,0x11,0xd1,0xa1,0xfa,0x9e,0xd9,0xf6,0x1d,0xae,0x5d,
0xc4,0xdc,0xee,0x87,0x31,0xab,0x59,0x7e,0xe3,0x58,0x5e,0x43,0x8e,0xbf,0x06,0xe7,
0xb1,0xfc,0x34,0xc9,0xf0,0xb2,0xbf,0x6b,0xdf,0x3b,0x6d,0x9d,0xdf,0xee,0x13,0x74,
0x8a,0x00,0x00,0x00,0x00,0x49,0x45,0x4e,0x44,0xae,0x42,0x60,0x82};

21
external/sdl_nyan/src/nyan_types.h vendored Normal file
View file

@ -0,0 +1,21 @@
#ifndef SRC_DP_TYPES_H
#define SRC_DP_TYPES_H
#ifdef __cplusplus
#include <cstdint>
#else
#include <stdint.h>
#endif
typedef uint8_t u8;
typedef uint16_t u16;
typedef uint32_t u32;
typedef uint64_t u64;
typedef int8_t s8;
typedef int16_t s16;
typedef int32_t s32;
typedef int64_t s64;
#endif // SRC_DP_TYPES_H

102
external/sdl_nyan/src/sdl_nyan.cc vendored Normal file
View file

@ -0,0 +1,102 @@
#include "sdl_nyan.h"
#include <SDL.h>
#include <SDL_render.h>
#include <array>
#include <cassert>
#include <cstdarg>
#include <string>
#include "log.h"
#include "nyan_types.h"
#define STB_IMAGE_IMPLEMENTATION
#include "stb_image.h"
#include "nyan_data_r.c"
static const char *const NYAN_PATH = "../external/nyan/nyan";
static void nyan_sdl_fatal(const char *const msg)
{
log_fatal("%s: %s", msg, SDL_GetError());
abort();
}
static void nyan_sdl_error(const char *const msg)
{
log_error("%s: %s", msg, SDL_GetError());
}
template<size_t Size>
[[maybe_unused]] const char *aprintf(std::array<char, Size> &buf, const char *fmt, ...)
{
std::va_list args;
va_start(args, fmt);
std::vsnprintf(buf.data(), buf.size(), fmt, args);
va_end(args);
return buf.data();
}
static SDL_Texture *make_nyan_sprite_sheet_from_files(SDL_Renderer *renderer, const char dir = 'r')
{
static const auto textureRect = nyan_sheet_rect();
auto result = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STREAMING,
textureRect.w, textureRect.h);
if (!result)
nyan_sdl_fatal("make_nyan_sprite_sheet_from_files/SDL_CreateTexture");
if (SDL_SetTextureBlendMode(result, SDL_BLENDMODE_BLEND))
nyan_sdl_fatal("make_nyan_sprite_sheet_from_files/SDL_SetTextureBlendMode");
std::array<char, 1024> strBuf;
for (size_t i=0; i<NYAN_SPRITE_COUNT; ++i)
{
auto filename = aprintf(strBuf, "%s/%c%zu.png", NYAN_PATH, dir, i+1);
log_trace("make_nyan_sprite_sheet_from_files: loading %s", filename);
int w = 0, h = 0, bytes_per_pixel = 0;
u8 *data = stbi_load(filename, &w, &h, &bytes_per_pixel, 0);
assert(w == NYAN_SPRITE_WIDTH && h == NYAN_SPRITE_HEIGHT && bytes_per_pixel == NYAN_BBP);
auto destRect = nyan_sprite_rect(i);
if (SDL_UpdateTexture(result, &destRect, data, NYAN_BBP * NYAN_SPRITE_WIDTH))
nyan_sdl_fatal("make_nyan_sprite_sheet_from_files/SDL_UpdateTexture");
STBI_FREE(data);
}
return result;
}
SDL_Texture *make_nyan_sprite_sheet_from_mem(SDL_Renderer *renderer)
{
static const uint8_t *const data_ptrs[] = { r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, nullptr };
static const size_t data_sizes[] = {
sizeof(r1), sizeof(r2), sizeof(r3), sizeof(r4), sizeof(r5), sizeof(r6),
sizeof(r7), sizeof(r8), sizeof(r9), sizeof(r10), sizeof(r11), sizeof(r12)
};
static const auto textureRect = nyan_sheet_rect();
auto result = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STREAMING,
textureRect.w, textureRect.h);
if (!result)
nyan_sdl_fatal("make_nyan_sprite_sheet_from_mem/SDL_CreateTexture");
if (SDL_SetTextureBlendMode(result, SDL_BLENDMODE_BLEND))
nyan_sdl_fatal("make_nyan_sprite_sheet_from_mem/SDL_SetTextureBlendMode");
for (size_t i=0; data_ptrs[i]; ++i)
{
log_trace("make_nyan_sprite_sheet_from_mem: loading data %zu", i);
int w = 0, h = 0, bytes_per_pixel = 0;
u8 *data = stbi_load_from_memory(data_ptrs[i], data_sizes[i], &w, &h, &bytes_per_pixel, 0);
assert(w == NYAN_SPRITE_WIDTH && h == NYAN_SPRITE_HEIGHT && bytes_per_pixel == NYAN_BBP);
auto destRect = nyan_sprite_rect(i);
if (SDL_UpdateTexture(result, &destRect, data, NYAN_BBP * NYAN_SPRITE_WIDTH))
nyan_sdl_fatal("make_nyan_sprite_sheet_from_mem/SDL_UpdateTexture");
STBI_FREE(data);
}
return result;
}

31
external/sdl_nyan/src/sdl_nyan.h vendored Normal file
View file

@ -0,0 +1,31 @@
#ifndef SRC_SDL_NYAN_H
#define SRC_SDL_NYAN_H
#include <SDL_render.h>
#ifdef __cplusplus
extern "C" {
#endif
#define NYAN_SPRITE_COUNT 12u
#define NYAN_SPRITE_WIDTH 36u
#define NYAN_SPRITE_HEIGHT 26u
#define NYAN_BBP 4u
SDL_Texture *make_nyan_sprite_sheet_from_mem(SDL_Renderer *renderer);
static SDL_Rect nyan_sprite_rect(size_t index)
{
return SDL_Rect{ static_cast<int>(NYAN_SPRITE_WIDTH * index), 0, NYAN_SPRITE_WIDTH, NYAN_SPRITE_HEIGHT};
}
static constexpr SDL_Rect nyan_sheet_rect()
{
return { 0, 0, NYAN_SPRITE_COUNT * NYAN_SPRITE_WIDTH, NYAN_SPRITE_HEIGHT };
}
#ifdef __cplusplus
}
#endif
#endif // SRC_SDL_NYAN_H

152
external/sdl_nyan/src/sdl_nyan_demo.cc vendored Normal file
View file

@ -0,0 +1,152 @@
#include "log.h"
#include "nyan_types.h"
#include <sdl_nyan.h>
#include <SDL.h>
#include <SDL_render.h>
static void nyan_sdl_fatal(const char *const msg)
{
log_fatal("%s: %s", msg, SDL_GetError());
abort();
}
static void nyan_sdl_error(const char *const msg)
{
log_error("%s: %s", msg, SDL_GetError());
}
static const float NYAN_PI = 3.14159265358979323846f;
static const float NYAN_PI2 = 2.0f * NYAN_PI;
template<typename T> T deg2rad(T deg) { return deg * NYAN_PI / 180.0; }
template<typename T> T rad2deg(T deg) { return 180.0 * deg / NYAN_PI; }
struct NyanSpinnyCircle
{
SDL_Texture *nyanSheet = nullptr;
SDL_Point centerPos;
float radius = 100.0f;
float radiusBounce = 0.0f;
float radiusBounceIncrement = 0.4f;
float radiusBounceMax = 42.0f;
float angle = 0.0f;
float angularStep = 0.015f;
unsigned animSpeed = 48;
unsigned nyanCount = 13;
};
void do_circle_nyan_step(SDL_Renderer *renderer, NyanSpinnyCircle &nsc)
{
static constexpr SDL_Point rotCenter = {NYAN_SPRITE_WIDTH, NYAN_SPRITE_HEIGHT};
const size_t nyanSpriteIndex = (SDL_GetTicks() / nsc.animSpeed) % NYAN_SPRITE_COUNT;
const auto sourceRect = nyan_sprite_rect(nyanSpriteIndex);
const auto nyanRads = deg2rad(360.0f / nsc.nyanCount);
for (auto i=0u; i<nsc.nyanCount; ++i)
{
auto a = nsc.angle + nyanRads * i;
auto x = nsc.centerPos.x + std::cos(a) * (nsc.radius + nsc.radiusBounce);
auto y = nsc.centerPos.y + std::sin(a) * (nsc.radius + nsc.radiusBounce);
auto destRect = sourceRect;
destRect.x = x;
destRect.y = y;
float rotAngle = rad2deg(a) + 90.0f;
SDL_RenderCopyEx(renderer, nsc.nyanSheet, &sourceRect, &destRect, rotAngle, &rotCenter, SDL_FLIP_NONE);
}
nsc.angle = nsc.angle + nsc.angularStep;
if (nsc.angle >= NYAN_PI2) nsc.angle -= NYAN_PI2;
nsc.radiusBounce += nsc.radiusBounceIncrement;
if (nsc.radiusBounce <= -nsc.radiusBounceMax || nsc.radiusBounce > nsc.radiusBounceMax)
nsc.radiusBounceIncrement = - nsc.radiusBounceIncrement;
}
int main(int argc, char *argv[])
{
(void) argc;
(void) argv;
#ifndef NDEBUG
log_set_level(LOG_TRACE);
#else
log_set_level(LOG_DEBUG);
#endif
if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER))
nyan_sdl_fatal("SDL_Init");
#ifdef SDL_HINT_IME_SHOW_UI
SDL_SetHint(SDL_HINT_IME_SHOW_UI, "1");
#endif
const auto windowFlags = SDL_WINDOW_RESIZABLE | SDL_WINDOW_ALLOW_HIGHDPI | SDL_WINDOW_OPENGL;
auto window = SDL_CreateWindow("sdl_nyan", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 1280, 960, windowFlags);
if (!window)
nyan_sdl_fatal("SDL_CreateWindow");
auto renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_PRESENTVSYNC | SDL_RENDERER_ACCELERATED);
if (!renderer)
nyan_sdl_fatal("SDL_CreateRenderer");
//auto nyanSheet = make_nyan_sprite_sheet_from_files(renderer);
auto nyanSheet = make_nyan_sprite_sheet_from_mem(renderer);
NyanSpinnyCircle nsc;
nsc.nyanSheet = nyanSheet;
nsc.centerPos = { 420/2, 420/2 };
bool quit = false;
while (!quit)
{
SDL_Event event;
while (SDL_PollEvent(&event))
{
if (event.type == SDL_QUIT)
quit = true;
if (event.type == SDL_KEYDOWN && event.key.keysym.mod & KMOD_CTRL && event.key.keysym.sym == SDLK_q)
quit = true;
}
SDL_SetRenderDrawColor(renderer, 128, 128, 128, 255);
SDL_RenderClear(renderer);
auto sheetDestRect = nyan_sheet_rect();
sheetDestRect.w *= 3;
sheetDestRect.h *= 3;
SDL_RenderCopy(renderer, nyanSheet, nullptr, &sheetDestRect);
auto ticks = SDL_GetTicks();
size_t nyanSpriteIndex = (ticks / 48) % NYAN_SPRITE_COUNT;
auto sourceRect = nyan_sprite_rect(nyanSpriteIndex);
auto destRect = nyan_sprite_rect(0);
destRect.w *= 3;
destRect.h *= 3;
destRect.y += sheetDestRect.h;
SDL_RenderCopy(renderer, nyanSheet, &sourceRect, &destRect);
destRect.x = 420/2;
destRect.y = 420/2;
SDL_Point centerPoint = {NYAN_SPRITE_WIDTH, NYAN_SPRITE_HEIGHT};
double angle = (ticks / 4) % 360;
SDL_RenderCopyEx(renderer, nyanSheet, &sourceRect, &destRect, angle, &centerPoint, SDL_FLIP_NONE);
do_circle_nyan_step(renderer, nsc);
SDL_RenderPresent(renderer);
}
SDL_DestroyTexture(nyanSheet);
SDL_DestroyRenderer(renderer);
SDL_DestroyWindow(window);
SDL_Quit();
return 0;
}

7987
external/sdl_nyan/src/stb_image.h vendored Normal file

File diff suppressed because it is too large Load diff

View file

@ -35,6 +35,7 @@ target_compile_features(doompanning PRIVATE cxx_std_17)
target_link_libraries(doompanning
PRIVATE dp_common
PRIVATE imgui
PRIVATE sdl_nyan
)
add_executable(dp_imgui_demo dp_imgui_demo.cc)

View file

@ -1,4 +1,6 @@
#include <nng/nng.h>
#include <nng/protocol/pubsub0/pub.h>
#include <nng/protocol/pubsub0/sub.h>
#include <imgui.h>
#include <imgui_internal.h>
@ -23,10 +25,7 @@
#include "dp_util.hpp"
#include "doomlib.hpp"
#if DoomBytesPerPixel == 3
// FIXME: don't use, it's buggy
static const u32 DoomSdlTexturePixelFormat = SDL_PIXELFORMAT_RGB888;
#elif DoomBytesPerPixel == 4
#if DoomBytesPerPixel == 4
static const u32 DoomSdlTexturePixelFormat = SDL_PIXELFORMAT_ARGB8888;
#else
#error Unhandled DoomBytesPerPixel value. Which SDL_PIXELFORMAT to use?
@ -340,35 +339,8 @@ void do_networking(ControllerContext &ctx)
#endif
#if 0
// FIXME: buggy. black screen with tiny bar on top
//log_trace("Texture update for doom (pid=%d, texture=%p)", ds.id, ds.texture);
u8 *destPixels = nullptr;
int texturePitch = 0;
if (SDL_LockTexture(ds.texture, nullptr, reinterpret_cast<void **>(&destPixels), &texturePitch))
dp_sdl_fatal("SDL_LockTexture");
// When using 3 bytes per pixel (960 bytes per row), SDL yields
// a pitch of 1280 on my machine. This is likely done to get
// good alignment.
assert(DoomFramePitch <= texturePitch);
for (size_t row=0; row<DoomScreenHeight; ++row)
{
u8 *destRow = destPixels + row + texturePitch;
const u8 *sourceRow = sourcePixels + row * DoomFramePitch;
std::memcpy(destRow, sourceRow, DoomFramePitch);
}
SDL_UnlockTexture(ds.texture);
#else
// FIXME: buggy. sometimes crashes with DoomBytesPerPixel=3, hasn't crashed with DoomBytesPerPixel=4 yet.
// In the latter case SDL texture pitch equals DoomFramePitch...
if (SDL_UpdateTexture(ds.texture, nullptr, sourcePixels, DoomFramePitch))
dp_sdl_fatal("SDL_UpdateTexture");
#endif
}
else
{
@ -584,6 +556,9 @@ int doom_controller_loop(ControllerContext &ctx)
auto &io = ImGui::GetIO();
s32 mouseWheel = 0.0;
static const float ScaleStep = 0.01f;
static const s32 PanStep = 2;
while (SDL_PollEvent(&event))
{
ImGui_ImplSDL2_ProcessEvent(&event);
@ -606,9 +581,67 @@ int doom_controller_loop(ControllerContext &ctx)
if (auto doomEvent = doomevent_from_sdlevent(event))
post_doom_event(ctx, *doomEvent);
}
if (!io.WantCaptureKeyboard && (event.type == SDL_KEYDOWN))
{
// FIXME: it doesn't work like this. use buttonstate and update it in here, then handle everything later like was done with imgui io
const auto sym = event.key.keysym.sym;
const auto mod = event.key.keysym.mod;
const auto repeat = event.key.repeat;
// Ctrl-Q to quit
if (mod & KMOD_CTRL && sym == SDLK_q)
ctx.quit = true;
// keyboard zoom with - and =, reset with 0
if (sym == SDLK_EQUALS)
ctx.scaleFactor += ScaleStep;
if (sym == SDLK_MINUS)
ctx.scaleFactor -= ScaleStep;
if (sym == SDLK_0)
ctx.scaleFactor = 1.0;
s32 PanFactor = mod & KMOD_CTRL ? 10 : 1;
// hjkl scrolling and reset with g
if (sym == SDLK_h)
ctx.offsetX -= PanStep;
if (sym == SDLK_j)
ctx.offsetY += PanStep;
if (sym == SDLK_k)
ctx.offsetY -= PanStep;
if (sym == SDLK_l)
ctx.offsetX += PanStep;
if (sym == SDLK_g)
ctx.offsetX = ctx.offsetY = 0;
// Alt-Enter fullscreen toggle
if (mod == KMOD_ALT && sym == SDLK_RETURN && !repeat)
{
u32 flag = (ctx.isFullscreen ? 0 : SDL_WINDOW_FULLSCREEN_DESKTOP);
SDL_SetWindowFullscreen(ctx.window, flag);
ctx.isFullscreen = !ctx.isFullscreen;
}
// TODO: F1 - help
// F2 - toggle publish inputs to dooms
if (sym == SDLK_F2 && !repeat)
{
ctx.publishInputsMode = !ctx.publishInputsMode;
if (SDL_SetRelativeMouseMode(ctx.publishInputsMode ? SDL_TRUE : SDL_FALSE) < 0)
log_warn("SDL_SetRelativeMouseMode: %s", SDL_GetError());
io.SetAppAcceptingEvents(!ctx.publishInputsMode);
}
// F3 to toggle ImGui visibility (skips the call to run_ui() if true)
if (sym == SDLK_F3 && !repeat)
ctx.uiVisible = !ctx.uiVisible;
}
}
// Process input events not consumed by ImGui
#if 0
if (!io.WantCaptureKeyboard)
{
// TODO: make scaling scale with the current scale factor
@ -647,23 +680,21 @@ int doom_controller_loop(ControllerContext &ctx)
ctx.isFullscreen = !ctx.isFullscreen;
}
// F10 to toggle ImGui visibility (skips the call to run_ui() if true)
if (ImGui::IsKeyPressed(ImGuiKey_F10, false))
// TODO: F1 - help
// F2 - toggle publish inputs to dooms
if (ImGui::IsKeyPressed(ImGuiKey_F2, false))
{
ctx.uiVisible = !ctx.uiVisible;
// FIXME: sadly this has issues: after toggling the ui off and
// on again the mouse cursor is invisible. Even using
// SDL_ShowCursor() unconditionally did not fix it. I suspect
// it's caused by some interaction between SDL and ImGui.
//if (SDL_SetRelativeMouseMode(ctx.uiVisible ? SDL_TRUE : SDL_FALSE) < 0)
// log_warn("SDL_SetRelativeMouseMode: %s", SDL_GetError());
ctx.publishInputsMode = !ctx.publishInputsMode;
if (SDL_SetRelativeMouseMode(ctx.publishInputsMode ? SDL_TRUE : SDL_FALSE) < 0)
log_warn("SDL_SetRelativeMouseMode: %s", SDL_GetError());
}
// Ctrl-A to toggle sending input events to dooms.
if (io.KeyCtrl && ImGui::IsKeyPressed(ImGuiKey_A, false))
ctx.publishInputsMode = !ctx.publishInputsMode;
// F3 to toggle ImGui visibility (skips the call to run_ui() if true)
if (ImGui::IsKeyPressed(ImGuiKey_F3, false))
ctx.uiVisible = !ctx.uiVisible;
}
#endif
static ImVec2 panStartPos;
@ -681,7 +712,7 @@ int doom_controller_loop(ControllerContext &ctx)
if (ImGui::IsKeyReleased(ImGuiKey_MouseLeft))
ctx.isMousePanning = false;
if (ctx.isMousePanning)
if (ctx.isMousePanning && !ctx.publishInputsMode)
{
auto curPos = io.MousePos;
auto dx = curPos.x - panStartPos.x;
@ -775,8 +806,33 @@ int main(int argc, char *argv[])
nng_set_resolve_thread_max(1);
ControllerContext ctx;
ctx.pub = make_ctrl_pub(CtrlUrlIpc);
ctx.sub = make_ctrl_sub(DoomUrlIpc);
// ctrl pub socket: ctrl -> dooms
if (int res = nng_pub0_open(&ctx.pub))
dp_nng_fatal("ctrl/nng_pub0_open", res);
if (int res = nng_listen(ctx.pub, CtrlUrlIpc, nullptr, 0))
dp_nng_fatal("ctrl/nng_listen/ipc", res);
if (int res = nng_listen(ctx.pub, CtrlUrlTcp, nullptr, 0))
dp_nng_fatal("ctrl/nng_listen/tcp4", res);
// ctrl sub socket: dooms -> ctrl
if (int res = nng_sub0_open(&ctx.sub))
dp_nng_fatal("ctrl/nng_sub0_open", res);
if (int res = nng_setopt(ctx.sub, NNG_OPT_SUB_SUBSCRIBE, "", 0))
dp_nng_fatal("ctrl/subscribe", res);
if (int res = nng_socket_set_ms(ctx.sub, NNG_OPT_RECVTIMEO, 100))
dp_nng_fatal("ctrl/recvtimeo", res);
if (int res = nng_listen(ctx.sub, DoomUrlIpc, NULL, 0))
dp_nng_fatal("make_ctrl_sub/nng_listen", res);
if (int res = nng_listen(ctx.sub, DoomUrlTcp, nullptr, 0))
dp_nng_fatal("ctrl/nng_listen/tcp4", res);
ctx.window = window;
ctx.renderer = renderer;
ctx.inputs.head.msgType = DP_MT_Inputs;

View file

@ -28,41 +28,6 @@ void dp_nng_init_limits(int ncpu_max, int pool_thread_limit_max, int resolv_thre
nng_set_resolve_thread_max(resolv_thread_limit);
}
nng_socket make_ctrl_pub(const char *url)
{
nng_socket sock;
int res = 0;
if ((res = nng_pub0_open(&sock)))
dp_nng_fatal("make_ctrl_pub/nng_pub0_open", res);
if ((res = nng_listen(sock, url, NULL, 0)))
dp_nng_fatal("make_ctrl_pub/nng_listen", res);
return sock;
}
nng_socket make_ctrl_sub(const char *url)
{
nng_socket sock;
int res = 0;
if ((res = nng_sub0_open(&sock)))
dp_nng_fatal("make_ctrl_sub/nng_sub0_open", res);
if ((res = nng_setopt(sock, NNG_OPT_SUB_SUBSCRIBE, "", 0)))
dp_nng_fatal("make_ctrl_sub/subscribe", res);
if ((res = nng_socket_set_ms(sock, NNG_OPT_RECVTIMEO, 100)))
dp_nng_fatal("make_ctrl_sub/recvtimeo", res);
if ((res = nng_listen(sock, url, NULL, 0)))
dp_nng_fatal("make_ctrl_sub/nng_listen", res);
return sock;
}
nng_socket make_doom_pub(const char *url)
{
nng_socket sock;

View file

@ -116,14 +116,14 @@ static inline bool dp_nng_is_timeout(int res)
return res == NNG_ETIMEDOUT || res == NNG_EAGAIN;
}
// Controller listens, Dooms dial.
// Controller listens, dooms dial.
static const char *const CtrlUrlIpc = "ipc://666_ctrl.socket"; // controller publishes here
static const char *const DoomUrlIpc = "ipc://666_doom.socket"; // dooms publish here
static const char *const CtrlUrlTcp = "tcp4://:42666"; // controller publishes here
static const char *const DoomUrlTcp = "tcp4://:42667"; // dooms publish here
static const char *const CtrlUrlTcp = "tcp://:42666"; // controller publishes here
static const char *const DoomUrlTcp = "tcp://:42667"; // dooms publish here
static const int CtrlPort = 42666; // controller publishes on this port
static const int DoomPort = 42667; // dooms publish here
nng_socket make_ctrl_pub(const char *url);
nng_socket make_ctrl_sub(const char *url);
nng_socket make_doom_pub(const char *url);
nng_socket make_doom_sub(const char *url);

View file

@ -209,12 +209,6 @@ DoomContext g_doomContext;
//
void IB_StartTic (void)
{
/* TODO: post input events (could this be done in IB_FinishUpdate? try it)
case SDL_KEYDOWN:
event.type = ev_keydown;
event.data1 = xlatekey(sdl_event.key.keysym.sym);
D_PostEvent(&event);
*/
}
void IB_GetFramebuffer(unsigned char **pixels, size_t *pitch)
@ -313,12 +307,7 @@ void IB_FinishUpdate (void)
void IB_GetColor(unsigned char *bytes, unsigned char red, unsigned char green, unsigned char blue)
{
#if DoomBytesPerPixel == 3
// FIXME: this is buggy
bytes[0] = red;
bytes[1] = green;
bytes[2] = blue;
#elif DoomBytesPerPixel == 4
#if DoomBytesPerPixel == 4
bytes[0] = blue;
bytes[1] = green;
bytes[2] = red;
@ -352,11 +341,26 @@ void IB_InitGraphics(const char *title, size_t screen_width, size_t screen_heigh
signal(SIGINT, I_Quit_Wrapper);
dp_nng_init_limits(1, 1, 1);
g_doomContext.pub = make_doom_pub(DoomUrlIpc);
g_doomContext.sub = make_doom_sub(CtrlUrlIpc);
int p = M_CheckParm("-dp-host");
if (p)
{
// use tcp transport with the host given on the command line
char url[1024];
snprintf(url, 1024, "tcp://%s:%d", myargv[p+1], DoomPort);
g_doomContext.pub = make_doom_pub(url);
snprintf(url, 1024, "tcp://%s:%d", myargv[p+1], CtrlPort);
g_doomContext.sub = make_doom_sub(url);
}
else
{
// use unix domain sockets
g_doomContext.pub = make_doom_pub(DoomUrlIpc);
g_doomContext.sub = make_doom_sub(CtrlUrlIpc);
}
g_doomContext.id = getpid();
g_doomContext.state = DP_DS_Ready;
g_doomContext.f = do_doom_ready;