Add Library
This commit is contained in:
parent
e365b9dbd9
commit
3c47103b39
318 changed files with 56465 additions and 0 deletions
58
libraries/bitluni_ESP32Lib/src/Audio/AudioOutput.h
Normal file
58
libraries/bitluni_ESP32Lib/src/Audio/AudioOutput.h
Normal file
|
@ -0,0 +1,58 @@
|
|||
/*
|
||||
Author: bitluni 2019
|
||||
License:
|
||||
Creative Commons Attribution ShareAlike 4.0
|
||||
https://creativecommons.org/licenses/by-sa/4.0/
|
||||
|
||||
For further details check out:
|
||||
https://youtube.com/bitlunislab
|
||||
https://github.com/bitluni
|
||||
http://bitluni.net
|
||||
*/
|
||||
#include "soc/i2s_reg.h"
|
||||
#include "soc/timer_group_struct.h"
|
||||
#include "driver/periph_ctrl.h"
|
||||
#include "driver/timer.h"
|
||||
#include "AudioSystem.h"
|
||||
|
||||
class AudioOutput;
|
||||
void IRAM_ATTR timerInterrupt(AudioOutput *audioOutput);
|
||||
|
||||
class AudioOutput
|
||||
{
|
||||
public:
|
||||
AudioSystem *audioSystem;
|
||||
|
||||
void init(AudioSystem &audioSystem)
|
||||
{
|
||||
this->audioSystem = &audioSystem;
|
||||
timer_config_t config;
|
||||
config.alarm_en = 1;
|
||||
config.auto_reload = 1;
|
||||
config.counter_dir = TIMER_COUNT_UP;
|
||||
config.divider = 16;
|
||||
config.intr_type = TIMER_INTR_LEVEL;
|
||||
config.counter_en = TIMER_PAUSE;
|
||||
timer_init((timer_group_t)TIMER_GROUP_0, (timer_idx_t)TIMER_0, &config);
|
||||
timer_pause((timer_group_t)TIMER_GROUP_0, (timer_idx_t)TIMER_0);
|
||||
timer_set_counter_value((timer_group_t)TIMER_GROUP_0, (timer_idx_t)TIMER_0, 0x00000000ULL);
|
||||
timer_set_alarm_value((timer_group_t)TIMER_GROUP_0, (timer_idx_t)TIMER_0, 1.0/audioSystem.samplingRate * TIMER_BASE_CLK / config.divider);
|
||||
timer_enable_intr((timer_group_t)TIMER_GROUP_0, (timer_idx_t)TIMER_0);
|
||||
timer_isr_register((timer_group_t)TIMER_GROUP_0, (timer_idx_t)TIMER_0, (void (*)(void*))timerInterrupt, (void*) this, ESP_INTR_FLAG_IRAM, NULL);
|
||||
timer_start((timer_group_t)TIMER_GROUP_0, (timer_idx_t)TIMER_0);
|
||||
}
|
||||
};
|
||||
|
||||
void IRAM_ATTR timerInterrupt(AudioOutput *audioOutput)
|
||||
{
|
||||
uint32_t intStatus = TIMERG0.int_st_timers.val;
|
||||
if(intStatus & BIT(TIMER_0))
|
||||
{
|
||||
TIMERG0.hw_timer[TIMER_0].update = 1;
|
||||
TIMERG0.int_clr_timers.t0 = 1;
|
||||
TIMERG0.hw_timer[TIMER_0].config.alarm_en = 1;
|
||||
|
||||
WRITE_PERI_REG(I2S_CONF_SIGLE_DATA_REG(0), audioOutput->audioSystem->nextSample() << 24);
|
||||
}
|
||||
}
|
||||
|
209
libraries/bitluni_ESP32Lib/src/Audio/AudioSystem.h
Normal file
209
libraries/bitluni_ESP32Lib/src/Audio/AudioSystem.h
Normal file
|
@ -0,0 +1,209 @@
|
|||
/*
|
||||
Author: bitluni 2019
|
||||
License:
|
||||
Creative Commons Attribution ShareAlike 4.0
|
||||
https://creativecommons.org/licenses/by-sa/4.0/
|
||||
|
||||
For further details check out:
|
||||
https://youtube.com/bitlunislab
|
||||
https://github.com/bitluni
|
||||
http://bitluni.net
|
||||
*/
|
||||
#pragma once
|
||||
#include "../Tools/Log.h"
|
||||
|
||||
class Sound
|
||||
{
|
||||
public:
|
||||
const signed char *samples;
|
||||
int sampleCount;
|
||||
long long position;
|
||||
int positionIncrement;
|
||||
int volume;
|
||||
bool playing;
|
||||
int id;
|
||||
bool loop;
|
||||
Sound *next;
|
||||
|
||||
void remove(Sound **prevNext)
|
||||
{
|
||||
*prevNext = next;
|
||||
delete this;
|
||||
}
|
||||
|
||||
void insert(Sound **prevNext)
|
||||
{
|
||||
next = *prevNext;
|
||||
*prevNext = this;
|
||||
}
|
||||
|
||||
void init(const signed char *samples, int sampleCount, float volume = 1, float speed = 1, bool loop = false)
|
||||
{
|
||||
next = 0;
|
||||
id = 0;
|
||||
this->samples = samples;
|
||||
this->sampleCount = sampleCount;
|
||||
this->loop = loop;
|
||||
position = 0;
|
||||
positionIncrement = int(65536 * speed);
|
||||
this->volume = volume * 256;
|
||||
playing = true;
|
||||
}
|
||||
|
||||
///returns the next rendered sample. 16bit since it's scaled by volume
|
||||
int nextSample()
|
||||
{
|
||||
if(!playing) return 0;
|
||||
int s = samples[position >> 16] * volume;
|
||||
position += positionIncrement;
|
||||
if((position >> 16) >= sampleCount)
|
||||
{
|
||||
if(loop)
|
||||
position = 0;
|
||||
else
|
||||
playing = false;
|
||||
}
|
||||
return s;
|
||||
}
|
||||
};
|
||||
|
||||
class AudioSystem
|
||||
{
|
||||
public:
|
||||
Sound *sounds;
|
||||
int samplingRate;
|
||||
unsigned char *buffer;
|
||||
int bufferSize;
|
||||
bool swapped;
|
||||
int currentId;
|
||||
volatile int readPosition;
|
||||
int writePosition;
|
||||
int volume;
|
||||
|
||||
AudioSystem(int samplingRate, int bufferSize)
|
||||
{
|
||||
this->samplingRate = samplingRate;
|
||||
this->bufferSize = bufferSize;
|
||||
sounds = 0;
|
||||
buffer = (unsigned char*)malloc(bufferSize * sizeof(unsigned char));
|
||||
if(!buffer)
|
||||
ERROR("Not enough memory for audio buffer");
|
||||
for(int i = 0; i < bufferSize; i++)
|
||||
buffer[i] = 128;
|
||||
swapped = true;
|
||||
currentId = 0;
|
||||
readPosition = 0;
|
||||
writePosition = 0;
|
||||
volume = 256;
|
||||
}
|
||||
|
||||
///plays a sound, and returns an idividual id
|
||||
int play(Sound *sound)
|
||||
{
|
||||
sound->id = currentId;
|
||||
sound->insert(&sounds);
|
||||
return currentId++;
|
||||
}
|
||||
|
||||
///fills the buffer with all saounds that are currently playing
|
||||
void calcSamples()
|
||||
{
|
||||
int samples = readPosition - writePosition;
|
||||
if(samples < 0)
|
||||
samples += bufferSize;
|
||||
for(int i = 0; i < samples; i++)
|
||||
{
|
||||
int sample = 0;
|
||||
Sound **soundp = &sounds;
|
||||
while(*soundp)
|
||||
{
|
||||
sample += (*soundp)->nextSample();
|
||||
if(!(*soundp)->playing)
|
||||
(*soundp)->remove(soundp);
|
||||
else
|
||||
soundp = &(*soundp)->next;
|
||||
}
|
||||
if(sample >= (1 << 15))
|
||||
sample = (1 << 15) - 1;
|
||||
else if(sample < -(1 << 15))
|
||||
sample = -(1 << 15);
|
||||
sample = ((sample * volume) >> 16) + 128;
|
||||
buffer[writePosition] = sample;
|
||||
writePosition++;
|
||||
if(writePosition >= bufferSize)
|
||||
writePosition = 0;
|
||||
}
|
||||
}
|
||||
|
||||
inline unsigned char nextSample()
|
||||
{
|
||||
unsigned char s = buffer[readPosition];
|
||||
readPosition++;
|
||||
if(readPosition >= bufferSize)
|
||||
readPosition = 0;
|
||||
return s;
|
||||
}
|
||||
|
||||
///stops playing a sound with an individual id
|
||||
void stop(int id)
|
||||
{
|
||||
Sound **soundp = &sounds;
|
||||
while(*soundp)
|
||||
{
|
||||
if((*soundp)->id == id)
|
||||
{
|
||||
(*soundp)->remove(soundp);
|
||||
return;
|
||||
}
|
||||
soundp = &(*soundp)->next;
|
||||
}
|
||||
}
|
||||
|
||||
///stops playing all sounds of an specific sample pointer
|
||||
void stopBySample(const signed char *samples)
|
||||
{
|
||||
Sound **soundp = &sounds;
|
||||
while(*soundp)
|
||||
{
|
||||
if((*soundp)->samples == samples)
|
||||
(*soundp)->remove(soundp);
|
||||
else
|
||||
soundp = &(*soundp)->next;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
class Wavetable
|
||||
{
|
||||
public:
|
||||
const signed char *samples;
|
||||
int soundCount;
|
||||
const int *offsets;
|
||||
int samplingRate;
|
||||
|
||||
Wavetable(const signed char *samples, int soundCount, const int *offsets, int samplingRate)
|
||||
{
|
||||
this->samples = samples;
|
||||
this->soundCount = soundCount;
|
||||
this->offsets = offsets;
|
||||
this->samplingRate = samplingRate;
|
||||
}
|
||||
|
||||
int play(AudioSystem &audioSystem, int soundNumber, float amplitude = 1, float speed = 1, bool loop = false)
|
||||
{
|
||||
Sound *sound = new Sound();
|
||||
sound->init(&samples[offsets[soundNumber]], offsets[soundNumber + 1] - offsets[soundNumber], amplitude, speed * samplingRate / audioSystem.samplingRate, loop);
|
||||
return audioSystem.play(sound);
|
||||
}
|
||||
|
||||
void stop(AudioSystem &audioSystem, int id)
|
||||
{
|
||||
audioSystem.stop(id);
|
||||
}
|
||||
|
||||
void stop(AudioSystem &audioSystem)
|
||||
{
|
||||
for(int i = 0; i < soundCount; i++)
|
||||
audioSystem.stopBySample(&samples[offsets[i]]);
|
||||
}
|
||||
};
|
128
libraries/bitluni_ESP32Lib/src/Controller/GameControllers.h
Normal file
128
libraries/bitluni_ESP32Lib/src/Controller/GameControllers.h
Normal file
|
@ -0,0 +1,128 @@
|
|||
/*
|
||||
Author: bitluni 2019
|
||||
License:
|
||||
Creative Commons Attribution ShareAlike 4.0
|
||||
https://creativecommons.org/licenses/by-sa/4.0/
|
||||
|
||||
For further details check out:
|
||||
https://youtube.com/bitlunislab
|
||||
https://github.com/bitluni
|
||||
http://bitluni.net
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
const int MAX_CONTROLLERS = 4;
|
||||
|
||||
class GameControllers
|
||||
{
|
||||
public:
|
||||
|
||||
enum Type
|
||||
{
|
||||
NES = 0,
|
||||
SNES = 1,
|
||||
};
|
||||
|
||||
enum Button
|
||||
{
|
||||
B = 0,
|
||||
Y = 1,
|
||||
SELECT = 2,
|
||||
START = 3,
|
||||
UP = 4,
|
||||
DOWN = 5,
|
||||
LEFT = 6,
|
||||
RIGHT = 7,
|
||||
A = 8,
|
||||
X = 9,
|
||||
L = 10,
|
||||
R = 11,
|
||||
};
|
||||
|
||||
Type types[MAX_CONTROLLERS];
|
||||
int latchPin;
|
||||
int clockPin;
|
||||
int dataPins[MAX_CONTROLLERS];
|
||||
int buttons[MAX_CONTROLLERS][12];
|
||||
|
||||
///This has to be initialized once for the shared pins latch and clock
|
||||
void init(int latch, int clock)
|
||||
{
|
||||
latchPin = latch;
|
||||
clockPin = clock;
|
||||
pinMode(latchPin, OUTPUT);
|
||||
digitalWrite(latchPin, LOW);
|
||||
pinMode(clockPin, OUTPUT);
|
||||
digitalWrite(clockPin, HIGH);
|
||||
for(int c = 0; c < MAX_CONTROLLERS; c++)
|
||||
{
|
||||
for(int i = 0; i < 12; i++)
|
||||
buttons[c][i] = -1;
|
||||
types[c] = NES;
|
||||
dataPins[c] = -1;
|
||||
}
|
||||
}
|
||||
|
||||
///This sets the controller type and initializes its individual data pin
|
||||
void setController(int controller, Type type, int dataPin)
|
||||
{
|
||||
types[controller] = type;
|
||||
dataPins[controller] = dataPin;
|
||||
pinMode(dataPins[controller], INPUT_PULLUP);
|
||||
}
|
||||
|
||||
void poll()
|
||||
{
|
||||
digitalWrite(latchPin, HIGH);
|
||||
delayMicroseconds(12);
|
||||
digitalWrite(latchPin, LOW);
|
||||
delayMicroseconds(6);
|
||||
for(int i = 0; i < 12; i++)
|
||||
{
|
||||
for(int c = 0; c < MAX_CONTROLLERS; c++)
|
||||
if(dataPins[c] > -1)
|
||||
{
|
||||
if(digitalRead(dataPins[c]))
|
||||
buttons[c][i] = -1;
|
||||
else
|
||||
buttons[c][i]++;
|
||||
}
|
||||
digitalWrite(clockPin, LOW);
|
||||
delayMicroseconds(6);
|
||||
digitalWrite(clockPin, HIGH);
|
||||
delayMicroseconds(6);
|
||||
}
|
||||
}
|
||||
|
||||
int translate(int controller, Button b) const
|
||||
{
|
||||
if(types[controller] == SNES) return b;
|
||||
static const int translateToNES[] = {1, 8, 2, 3, 4, 5, 6, 7, 0, 8, 8, 8};
|
||||
return translateToNES[b];
|
||||
}
|
||||
|
||||
///button will be unpressed until released again
|
||||
void clear(int controller, Button b)
|
||||
{
|
||||
buttons[controller][translate(controller, b)] = 0x80000000;
|
||||
}
|
||||
|
||||
///returns if button is currently down
|
||||
bool down(int controller, Button b) const
|
||||
{
|
||||
return buttons[controller][translate(controller, b)] >= 0;
|
||||
}
|
||||
|
||||
///returns true if button state changed to down since previous poll. repeatAfterTics can be used to repeat after button was hold down for sme time
|
||||
bool pressed(int controller, Button b, int repeatAfterTics = 0x7fffffff) const
|
||||
{
|
||||
return buttons[controller][translate(controller, b)] == 0 || (buttons[controller][translate(controller, b)] >= repeatAfterTics);
|
||||
}
|
||||
|
||||
///returns the type of controller configured
|
||||
Type getType(int controller)
|
||||
{
|
||||
return types[controller];
|
||||
}
|
||||
};
|
||||
|
14
libraries/bitluni_ESP32Lib/src/ESP32Lib.h
Normal file
14
libraries/bitluni_ESP32Lib/src/ESP32Lib.h
Normal file
|
@ -0,0 +1,14 @@
|
|||
#pragma once
|
||||
|
||||
#include <VGA/VGA14BitI.h>
|
||||
#include <VGA/VGA14Bit.h>
|
||||
#include <VGA/VGA6BitI.h>
|
||||
#include <VGA/VGA6Bit.h>
|
||||
#include <VGA/VGA3BitI.h>
|
||||
#include <VGA/VGA3Bit.h>
|
||||
#include <Graphics/Sprites.h>
|
||||
#include <Graphics/Mesh.h>
|
||||
#include <Graphics/Sprites.h>
|
||||
#include <Graphics/Animation.h>
|
||||
#include <Controller/GameControllers.h>
|
||||
#include <Audio/AudioOutput.h>
|
31
libraries/bitluni_ESP32Lib/src/GfxWrapper.h
Normal file
31
libraries/bitluni_ESP32Lib/src/GfxWrapper.h
Normal file
|
@ -0,0 +1,31 @@
|
|||
/*
|
||||
Author: bitluni 2019
|
||||
License:
|
||||
Creative Commons Attribution ShareAlike 4.0
|
||||
https://creativecommons.org/licenses/by-sa/4.0/
|
||||
|
||||
For further details check out:
|
||||
https://youtube.com/bitlunislab
|
||||
https://github.com/bitluni
|
||||
http://bitluni.net
|
||||
*/
|
||||
#pragma once
|
||||
#include "Adafruit_GFX.h"
|
||||
|
||||
template<class Base>
|
||||
class GfxWrapper : public Adafruit_GFX
|
||||
{
|
||||
public:
|
||||
Base &base;
|
||||
typedef typename Base::Color Color;
|
||||
GfxWrapper(Base &vga, const int xres, const int yres)
|
||||
:base(vga),
|
||||
Adafruit_GFX(xres, yres)
|
||||
{
|
||||
}
|
||||
|
||||
virtual void drawPixel(int16_t x, int16_t y, uint16_t color)
|
||||
{
|
||||
base.dot(x, y, base.RGBA((color >> 8) & 0b11111000, (color >> 3) & 0b11111100, (color << 3) & 0b11111000));
|
||||
}
|
||||
};
|
86
libraries/bitluni_ESP32Lib/src/Graphics/Animation.h
Normal file
86
libraries/bitluni_ESP32Lib/src/Graphics/Animation.h
Normal file
|
@ -0,0 +1,86 @@
|
|||
/*
|
||||
Author: bitluni 2019
|
||||
License:
|
||||
Creative Commons Attribution ShareAlike 4.0
|
||||
https://creativecommons.org/licenses/by-sa/4.0/
|
||||
|
||||
For further details check out:
|
||||
https://youtube.com/bitlunislab
|
||||
https://github.com/bitluni
|
||||
http://bitluni.net
|
||||
*/
|
||||
#pragma once
|
||||
#include "Entity.h"
|
||||
|
||||
class Animation : public Entity
|
||||
{
|
||||
public:
|
||||
int start, end, frameDuration;
|
||||
int time;
|
||||
int drawMode;
|
||||
|
||||
Animation(Sprites &sprites, int x, int y, int start, int end, int frameDuration, int drawMode = 0)
|
||||
{
|
||||
this->x = x;
|
||||
this->y = y;
|
||||
this->sprites = &sprites;
|
||||
this->start = start;
|
||||
this->end = end;
|
||||
this->frameDuration = frameDuration;
|
||||
time = 0;
|
||||
this->drawMode = drawMode;
|
||||
}
|
||||
|
||||
virtual ~Animation()
|
||||
{
|
||||
}
|
||||
|
||||
bool act(int dt)
|
||||
{
|
||||
time += dt;
|
||||
return time < (end - start + 1) * frameDuration;
|
||||
}
|
||||
/*
|
||||
void draw(Graphics &g)
|
||||
{
|
||||
int current = time / frameDuration + start;
|
||||
if (drawMode == 0)
|
||||
this->sprites->drawMix(g, current, this->x, this->y);
|
||||
else if (drawMode == 1)
|
||||
this->sprites->drawAdd(g, current, this->x, this->y);
|
||||
}
|
||||
*/
|
||||
static void animationsAct(Animation **animations, int dt, int maxCount = 100)
|
||||
{
|
||||
for (int i = 0; i < maxCount; i++)
|
||||
{
|
||||
if (animations[i])
|
||||
if (!animations[i]->act(dt))
|
||||
{
|
||||
delete animations[i];
|
||||
animations[i] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
/*
|
||||
void animationsDraw(Graphics &g, Animation **animations, int maxCount = 100)
|
||||
{
|
||||
for (int i = 0; i < maxCount; i++)
|
||||
if (animations[i])
|
||||
if (animations[i])
|
||||
animations[i]->draw(g);
|
||||
}
|
||||
*/
|
||||
void animationsEmit(Animation **animations, Animation *e, int maxCount = 100)
|
||||
{
|
||||
for (int i = 0; i < maxCount; i++)
|
||||
{
|
||||
if (!animations[i])
|
||||
{
|
||||
animations[i] = e;
|
||||
return;
|
||||
}
|
||||
}
|
||||
delete e;
|
||||
}
|
||||
};
|
69
libraries/bitluni_ESP32Lib/src/Graphics/Engine3D.h
Normal file
69
libraries/bitluni_ESP32Lib/src/Graphics/Engine3D.h
Normal file
|
@ -0,0 +1,69 @@
|
|||
/*
|
||||
Author: bitluni 2019
|
||||
License:
|
||||
Creative Commons Attribution ShareAlike 4.0
|
||||
https://creativecommons.org/licenses/by-sa/4.0/
|
||||
|
||||
For further details check out:
|
||||
https://youtube.com/bitlunislab
|
||||
https://github.com/bitluni
|
||||
http://bitluni.net
|
||||
*/
|
||||
#pragma once
|
||||
#include <stdlib.h>
|
||||
#include "TriangleTree.h"
|
||||
#include "../Tools/Log.h"
|
||||
template<class Graphics>
|
||||
class Engine3D
|
||||
{
|
||||
public:
|
||||
typedef typename Graphics::Color Color;
|
||||
TriangleTree *triangleBuffer;
|
||||
TriangleTree *triangleRoot;
|
||||
int trinagleBufferSize;
|
||||
int triangleCount;
|
||||
|
||||
Engine3D(const int initialTrinagleBufferSize = 1)
|
||||
{
|
||||
trinagleBufferSize = initialTrinagleBufferSize;
|
||||
triangleBuffer = (TriangleTree*)malloc(sizeof(TriangleTree) * trinagleBufferSize);
|
||||
if(!triangleBuffer)
|
||||
ERROR("Not enough memory for triangleBuffer");
|
||||
triangleRoot = 0;
|
||||
triangleCount = 0;
|
||||
}
|
||||
|
||||
|
||||
void enqueueTriangle(short *v0, short *v1, short *v2, Color color)
|
||||
{
|
||||
if (triangleCount >= trinagleBufferSize)
|
||||
return;
|
||||
TriangleTree &t = triangleBuffer[triangleCount++];
|
||||
t.set(v0, v1, v2, color);
|
||||
if (triangleRoot)
|
||||
triangleRoot->add(&triangleRoot, t);
|
||||
else
|
||||
triangleRoot = &t;
|
||||
}
|
||||
|
||||
void drawTriangleTree(Graphics &g, TriangleTree *t)
|
||||
{
|
||||
if (t->left)
|
||||
drawTriangleTree(g, t->left);
|
||||
g.triangle(t->v[0], t->v[1], t->v[2], t->color);
|
||||
if (t->right)
|
||||
drawTriangleTree(g, t->right);
|
||||
}
|
||||
|
||||
virtual void begin()
|
||||
{
|
||||
triangleCount = 0;
|
||||
triangleRoot = 0;
|
||||
}
|
||||
|
||||
virtual void end(Graphics &g)
|
||||
{
|
||||
if (triangleRoot)
|
||||
drawTriangleTree(g, triangleRoot);
|
||||
}
|
||||
};
|
26
libraries/bitluni_ESP32Lib/src/Graphics/Entity.h
Normal file
26
libraries/bitluni_ESP32Lib/src/Graphics/Entity.h
Normal file
|
@ -0,0 +1,26 @@
|
|||
/*
|
||||
Author: bitluni 2019
|
||||
License:
|
||||
Creative Commons Attribution ShareAlike 4.0
|
||||
https://creativecommons.org/licenses/by-sa/4.0/
|
||||
|
||||
For further details check out:
|
||||
https://youtube.com/bitlunislab
|
||||
https://github.com/bitluni
|
||||
http://bitluni.net
|
||||
*/
|
||||
#pragma once
|
||||
#include "Graphics.h"
|
||||
#include "Sprites.h"
|
||||
|
||||
class Entity
|
||||
{
|
||||
public:
|
||||
int x, y;
|
||||
int vx, vy;
|
||||
int life;
|
||||
int faction;
|
||||
Sprites *sprites;
|
||||
virtual bool act(int dt);
|
||||
virtual void draw() = 0;
|
||||
};
|
35
libraries/bitluni_ESP32Lib/src/Graphics/Font.h
Normal file
35
libraries/bitluni_ESP32Lib/src/Graphics/Font.h
Normal file
|
@ -0,0 +1,35 @@
|
|||
/*
|
||||
Author: bitluni 2019
|
||||
License:
|
||||
Creative Commons Attribution ShareAlike 4.0
|
||||
https://creativecommons.org/licenses/by-sa/4.0/
|
||||
|
||||
For further details check out:
|
||||
https://youtube.com/bitlunislab
|
||||
https://github.com/bitluni
|
||||
http://bitluni.net
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
class Font
|
||||
{
|
||||
public:
|
||||
const int firstChar;
|
||||
const int charCount;
|
||||
const unsigned char *pixels;
|
||||
const int charWidth;
|
||||
const int charHeight;
|
||||
Font(int charWidth, int charHeight, const unsigned char *pixels, int firstChar = 32, int charCount = 96)
|
||||
:firstChar(firstChar),
|
||||
charCount(charCount),
|
||||
pixels(pixels),
|
||||
charWidth(charWidth),
|
||||
charHeight(charHeight)
|
||||
{
|
||||
}
|
||||
|
||||
bool valid(char ch) const
|
||||
{
|
||||
return ch >= firstChar && ch < firstChar + charCount;
|
||||
}
|
||||
};
|
698
libraries/bitluni_ESP32Lib/src/Graphics/Graphics.h
Normal file
698
libraries/bitluni_ESP32Lib/src/Graphics/Graphics.h
Normal file
|
@ -0,0 +1,698 @@
|
|||
/*
|
||||
Author: bitluni 2019
|
||||
License:
|
||||
Creative Commons Attribution ShareAlike 4.0
|
||||
https://creativecommons.org/licenses/by-sa/4.0/
|
||||
|
||||
For further details check out:
|
||||
https://youtube.com/bitlunislab
|
||||
https://github.com/bitluni
|
||||
http://bitluni.net
|
||||
*/
|
||||
#pragma once
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
#include "Font.h"
|
||||
#include "ImageDrawer.h"
|
||||
|
||||
template<typename Color>
|
||||
class Graphics: public ImageDrawer
|
||||
{
|
||||
public:
|
||||
int cursorX, cursorY, cursorBaseX;
|
||||
long frontColor, backColor;
|
||||
Font *font;
|
||||
int frameBufferCount;
|
||||
int currentFrameBuffer;
|
||||
Color **frameBuffers[3];
|
||||
Color **frontBuffer;
|
||||
Color **backBuffer;
|
||||
bool autoScroll;
|
||||
|
||||
int xres;
|
||||
int yres;
|
||||
|
||||
virtual void dotFast(int x, int y, Color color) = 0;
|
||||
virtual void dot(int x, int y, Color color) = 0;
|
||||
virtual void dotAdd(int x, int y, Color color) = 0;
|
||||
virtual void dotMix(int x, int y, Color color) = 0;
|
||||
virtual Color get(int x, int y) = 0;
|
||||
virtual Color** allocateFrameBuffer() = 0;
|
||||
virtual Color** allocateFrameBuffer(int xres, int yres, Color value)
|
||||
{
|
||||
Color** frame = (Color **)malloc(yres * sizeof(Color *));
|
||||
if(!frame)
|
||||
ERROR("Not enough memory for frame buffer");
|
||||
for (int y = 0; y < yres; y++)
|
||||
{
|
||||
frame[y] = (Color *)malloc(xres * sizeof(Color));
|
||||
if(!frame[y])
|
||||
ERROR("Not enough memory for frame buffer");
|
||||
for (int x = 0; x < xres; x++)
|
||||
frame[y][x] = value;
|
||||
}
|
||||
return frame;
|
||||
}
|
||||
virtual Color RGBA(int r, int g, int b, int a = 255) const = 0;
|
||||
virtual int R(Color c) const = 0;
|
||||
virtual int G(Color c) const = 0;
|
||||
virtual int B(Color c) const = 0;
|
||||
virtual int A(Color c) const = 0;
|
||||
Color RGB(unsigned long rgb) const
|
||||
{
|
||||
return RGBA(rgb & 255, (rgb >> 8) & 255, (rgb >> 16) & 255);
|
||||
}
|
||||
Color RGBA(unsigned long rgba) const
|
||||
{
|
||||
return RGBA(rgba & 255, (rgba >> 8) & 255, (rgba >> 16) & 255, rgba >> 24);
|
||||
}
|
||||
Color RGB(int r, int g, int b) const
|
||||
{
|
||||
return RGBA(r, g, b);
|
||||
}
|
||||
|
||||
void setFrameBufferCount(unsigned char i)
|
||||
{
|
||||
frameBufferCount = i > 3 ? 3 : i;
|
||||
}
|
||||
|
||||
virtual void show(bool vSync = false)
|
||||
{
|
||||
if(!frameBufferCount)
|
||||
return;
|
||||
currentFrameBuffer = (currentFrameBuffer + 1) % frameBufferCount;
|
||||
frontBuffer = frameBuffers[currentFrameBuffer];
|
||||
backBuffer = frameBuffers[(currentFrameBuffer + frameBufferCount - 1) % frameBufferCount];
|
||||
}
|
||||
|
||||
Graphics(int xres = 0, int yres = 0)
|
||||
{
|
||||
this->xres = xres;
|
||||
this->yres = yres;
|
||||
font = 0;
|
||||
cursorX = cursorY = cursorBaseX = 0;
|
||||
frontColor = -1;
|
||||
backColor = 0;
|
||||
frameBufferCount = 1;
|
||||
for(int i = 0; i < 3; i++)
|
||||
frameBuffers[i] = 0;
|
||||
frontBuffer = 0;
|
||||
backBuffer = 0;
|
||||
autoScroll = true;
|
||||
}
|
||||
|
||||
virtual bool allocateFrameBuffers()
|
||||
{
|
||||
if(yres <= 0 || xres <= 0)
|
||||
return false;
|
||||
for(int i = 0; i < frameBufferCount; i++)
|
||||
frameBuffers[i] = allocateFrameBuffer();
|
||||
currentFrameBuffer = 0;
|
||||
show();
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual void setResolution(int xres, int yres)
|
||||
{
|
||||
this->xres = xres;
|
||||
this->yres = yres;
|
||||
allocateFrameBuffers();
|
||||
}
|
||||
|
||||
virtual float pixelAspect() const
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
void setTextColor(long front, long back = 0)
|
||||
{
|
||||
frontColor = front;
|
||||
backColor = back;
|
||||
}
|
||||
|
||||
void setFont(Font &font)
|
||||
{
|
||||
this->font = &font;
|
||||
}
|
||||
|
||||
void setCursor(int x, int y)
|
||||
{
|
||||
cursorX = cursorBaseX = x;
|
||||
cursorY = y;
|
||||
}
|
||||
|
||||
virtual void drawChar(int x, int y, int ch)
|
||||
{
|
||||
if (!font)
|
||||
return;
|
||||
if (!font->valid(ch))
|
||||
return;
|
||||
const unsigned char *pix = &font->pixels[font->charWidth * font->charHeight * (ch - font->firstChar)];
|
||||
for (int py = 0; py < font->charHeight; py++)
|
||||
for (int px = 0; px < font->charWidth; px++)
|
||||
if (*(pix++))
|
||||
dotMix(px + x, py + y, frontColor);
|
||||
else
|
||||
dotMix(px + x, py + y, backColor);
|
||||
}
|
||||
|
||||
void print(const char ch)
|
||||
{
|
||||
if (!font)
|
||||
return;
|
||||
if (font->valid(ch))
|
||||
drawChar(cursorX, cursorY, ch);
|
||||
else
|
||||
drawChar(cursorX, cursorY, ' ');
|
||||
cursorX += font->charWidth;
|
||||
if (cursorX + font->charWidth > xres)
|
||||
{
|
||||
cursorX = cursorBaseX;
|
||||
cursorY += font->charHeight;
|
||||
if(autoScroll && cursorY + font->charHeight > yres)
|
||||
scroll(cursorY + font->charHeight - yres, backColor);
|
||||
}
|
||||
}
|
||||
|
||||
void println(const char ch)
|
||||
{
|
||||
print(ch);
|
||||
print("\n");
|
||||
}
|
||||
|
||||
void print(const char *str)
|
||||
{
|
||||
if (!font)
|
||||
return;
|
||||
while (*str)
|
||||
{
|
||||
if(*str == '\n')
|
||||
{
|
||||
cursorX = cursorBaseX;
|
||||
cursorY += font->charHeight;
|
||||
}
|
||||
else
|
||||
print(*str);
|
||||
str++;
|
||||
}
|
||||
}
|
||||
|
||||
void println(const char *str)
|
||||
{
|
||||
print(str);
|
||||
print("\n");
|
||||
}
|
||||
|
||||
void print(long number, int base = 10, int minCharacters = 1)
|
||||
{
|
||||
if(minCharacters < 1)
|
||||
minCharacters = 1;
|
||||
bool sign = number < 0;
|
||||
if (sign)
|
||||
number = -number;
|
||||
const char baseChars[] = "0123456789ABCDEF";
|
||||
char temp[33];
|
||||
temp[32] = 0;
|
||||
int i = 31;
|
||||
do
|
||||
{
|
||||
temp[i--] = baseChars[number % base];
|
||||
number /= base;
|
||||
} while (number > 0);
|
||||
if (sign)
|
||||
temp[i--] = '-';
|
||||
for (; i > 31 - minCharacters; i--)
|
||||
temp[i] = ' ';
|
||||
print(&temp[i + 1]);
|
||||
}
|
||||
|
||||
void print(unsigned long number, int base = 10, int minCharacters = 1)
|
||||
{
|
||||
if(minCharacters < 1)
|
||||
minCharacters = 1;
|
||||
const char baseChars[] = "0123456789ABCDEF";
|
||||
char temp[33];
|
||||
temp[32] = 0;
|
||||
int i = 31;
|
||||
do
|
||||
{
|
||||
temp[i--] = baseChars[number % base];
|
||||
number /= base;
|
||||
} while (number > 0);
|
||||
for (; i > 31 - minCharacters; i--)
|
||||
temp[i] = ' ';
|
||||
print(&temp[i + 1]);
|
||||
}
|
||||
|
||||
void println(long number, int base = 10, int minCharacters = 1)
|
||||
{
|
||||
print(number, base, minCharacters); print("\n");
|
||||
}
|
||||
|
||||
void println(unsigned long number, int base = 10, int minCharacters = 1)
|
||||
{
|
||||
print(number, base, minCharacters); print("\n");
|
||||
}
|
||||
|
||||
void print(int number, int base = 10, int minCharacters = 1)
|
||||
{
|
||||
print(long(number), base, minCharacters);
|
||||
}
|
||||
|
||||
void println(int number, int base = 10, int minCharacters = 1)
|
||||
{
|
||||
println(long(number), base, minCharacters);
|
||||
}
|
||||
|
||||
void print(unsigned int number, int base = 10, int minCharacters = 1)
|
||||
{
|
||||
print((unsigned long)(number), base, minCharacters);
|
||||
}
|
||||
|
||||
void println(unsigned int number, int base = 10, int minCharacters = 1)
|
||||
{
|
||||
println((unsigned long)(number), base, minCharacters);
|
||||
}
|
||||
|
||||
void print(short number, int base = 10, int minCharacters = 1)
|
||||
{
|
||||
print(long(number), base, minCharacters);
|
||||
}
|
||||
|
||||
void println(short number, int base = 10, int minCharacters = 1)
|
||||
{
|
||||
println(long(number), base, minCharacters);
|
||||
}
|
||||
|
||||
void print(unsigned short number, int base = 10, int minCharacters = 1)
|
||||
{
|
||||
print(long(number), base, minCharacters);
|
||||
}
|
||||
|
||||
void println(unsigned short number, int base = 10, int minCharacters = 1)
|
||||
{
|
||||
println(long(number), base, minCharacters);
|
||||
}
|
||||
|
||||
void print(unsigned char number, int base = 10, int minCharacters = 1)
|
||||
{
|
||||
print(long(number), base, minCharacters);
|
||||
}
|
||||
|
||||
void println(unsigned char number, int base = 10, int minCharacters = 1)
|
||||
{
|
||||
println(long(number), base, minCharacters);
|
||||
}
|
||||
|
||||
void println()
|
||||
{
|
||||
print("\n");
|
||||
}
|
||||
|
||||
void print(double number, int fractionalDigits = 2, int minCharacters = 1)
|
||||
{
|
||||
long p = long(pow(10, fractionalDigits));
|
||||
long long n = (double(number) * p + 0.5f);
|
||||
print(long(n / p), 10, minCharacters - 1 - fractionalDigits);
|
||||
if(fractionalDigits)
|
||||
{
|
||||
print(".");
|
||||
for(int i = 0; i < fractionalDigits; i++)
|
||||
{
|
||||
p /= 10;
|
||||
print(long(n / p) % 10);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void println(double number, int fractionalDigits = 2, int minCharacters = 1)
|
||||
{
|
||||
print(number, fractionalDigits, minCharacters);
|
||||
print("\n");
|
||||
}
|
||||
|
||||
virtual void clear(Color color = 0)
|
||||
{
|
||||
for (int y = 0; y < yres; y++)
|
||||
for (int x = 0; x < xres; x++)
|
||||
dotFast(x, y, color);
|
||||
}
|
||||
|
||||
virtual void xLine(int x0, int x1, int y, Color color)
|
||||
{
|
||||
if (y < 0 || y >= yres)
|
||||
return;
|
||||
if (x0 > x1)
|
||||
{
|
||||
int xb = x0;
|
||||
x0 = x1;
|
||||
x1 = xb;
|
||||
}
|
||||
if (x0 < 0)
|
||||
x0 = 0;
|
||||
if (x1 > xres)
|
||||
x1 = xres;
|
||||
for (int x = x0; x < x1; x++)
|
||||
dotFast(x, y, color);
|
||||
}
|
||||
|
||||
void triangle(short *v0, short *v1, short *v2, Color color)
|
||||
{
|
||||
short *v[3] = {v0, v1, v2};
|
||||
if (v[1][1] < v[0][1])
|
||||
{
|
||||
short *vb = v[0];
|
||||
v[0] = v[1];
|
||||
v[1] = vb;
|
||||
}
|
||||
if (v[2][1] < v[1][1])
|
||||
{
|
||||
short *vb = v[1];
|
||||
v[1] = v[2];
|
||||
v[2] = vb;
|
||||
}
|
||||
if (v[1][1] < v[0][1])
|
||||
{
|
||||
short *vb = v[0];
|
||||
v[0] = v[1];
|
||||
v[1] = vb;
|
||||
}
|
||||
int y = v[0][1];
|
||||
int xac = v[0][0] << 16;
|
||||
int xab = v[0][0] << 16;
|
||||
int xbc = v[1][0] << 16;
|
||||
int xaci = 0;
|
||||
int xabi = 0;
|
||||
int xbci = 0;
|
||||
if (v[1][1] != v[0][1])
|
||||
xabi = ((v[1][0] - v[0][0]) << 16) / (v[1][1] - v[0][1]);
|
||||
if (v[2][1] != v[0][1])
|
||||
xaci = ((v[2][0] - v[0][0]) << 16) / (v[2][1] - v[0][1]);
|
||||
if (v[2][1] != v[1][1])
|
||||
xbci = ((v[2][0] - v[1][0]) << 16) / (v[2][1] - v[1][1]);
|
||||
|
||||
for (; y < v[1][1] && y < yres; y++)
|
||||
{
|
||||
if (y >= 0)
|
||||
xLine(xab >> 16, xac >> 16, y, color);
|
||||
xab += xabi;
|
||||
xac += xaci;
|
||||
}
|
||||
for (; y < v[2][1] && y < yres; y++)
|
||||
{
|
||||
if (y >= 0)
|
||||
xLine(xbc >> 16, xac >> 16, y, color);
|
||||
xbc += xbci;
|
||||
xac += xaci;
|
||||
}
|
||||
}
|
||||
|
||||
void line(int x1, int y1, int x2, int y2, Color color)
|
||||
{
|
||||
int x, y, xe, ye;
|
||||
int dx = x2 - x1;
|
||||
int dy = y2 - y1;
|
||||
int dx1 = labs(dx);
|
||||
int dy1 = labs(dy);
|
||||
int px = 2 * dy1 - dx1;
|
||||
int py = 2 * dx1 - dy1;
|
||||
if (dy1 <= dx1)
|
||||
{
|
||||
if (dx >= 0)
|
||||
{
|
||||
x = x1;
|
||||
y = y1;
|
||||
xe = x2;
|
||||
}
|
||||
else
|
||||
{
|
||||
x = x2;
|
||||
y = y2;
|
||||
xe = x1;
|
||||
}
|
||||
dot(x, y, color);
|
||||
for (int i = 0; x < xe; i++)
|
||||
{
|
||||
x = x + 1;
|
||||
if (px < 0)
|
||||
{
|
||||
px = px + 2 * dy1;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((dx < 0 && dy < 0) || (dx > 0 && dy > 0))
|
||||
{
|
||||
y = y + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
y = y - 1;
|
||||
}
|
||||
px = px + 2 * (dy1 - dx1);
|
||||
}
|
||||
dot(x, y, color);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (dy >= 0)
|
||||
{
|
||||
x = x1;
|
||||
y = y1;
|
||||
ye = y2;
|
||||
}
|
||||
else
|
||||
{
|
||||
x = x2;
|
||||
y = y2;
|
||||
ye = y1;
|
||||
}
|
||||
dot(x, y, color);
|
||||
for (int i = 0; y < ye; i++)
|
||||
{
|
||||
y = y + 1;
|
||||
if (py <= 0)
|
||||
{
|
||||
py = py + 2 * dx1;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((dx < 0 && dy < 0) || (dx > 0 && dy > 0))
|
||||
{
|
||||
x = x + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
x = x - 1;
|
||||
}
|
||||
py = py + 2 * (dx1 - dy1);
|
||||
}
|
||||
dot(x, y, color);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void fillRect(int x, int y, int w, int h, Color color)
|
||||
{
|
||||
if (x < 0)
|
||||
{
|
||||
w += x;
|
||||
x = 0;
|
||||
}
|
||||
if (y < 0)
|
||||
{
|
||||
h += y;
|
||||
y = 0;
|
||||
}
|
||||
if (x + w > xres)
|
||||
w = xres - x;
|
||||
if (y + h > yres)
|
||||
h = yres - y;
|
||||
for (int j = y; j < y + h; j++)
|
||||
for (int i = x; i < x + w; i++)
|
||||
dotFast(i, j, color);
|
||||
}
|
||||
|
||||
void rect(int x, int y, int w, int h, Color color)
|
||||
{
|
||||
fillRect(x, y, w, 1, color);
|
||||
fillRect(x, y, 1, h, color);
|
||||
fillRect(x, y + h - 1, w, 1, color);
|
||||
fillRect(x + w - 1, y, 1, h, color);
|
||||
}
|
||||
|
||||
void circle(int x, int y, int r, Color color)
|
||||
{
|
||||
int oxr = r;
|
||||
for(int i = 0; i < r + 1; i++)
|
||||
{
|
||||
int xr = (int)sqrt(r * r - i * i);
|
||||
xLine(x - oxr, x - xr + 1, y + i, color);
|
||||
xLine(x + xr, x + oxr + 1, y + i, color);
|
||||
if(i)
|
||||
{
|
||||
xLine(x - oxr, x - xr + 1, y - i, color);
|
||||
xLine(x + xr, x + oxr + 1, y - i, color);
|
||||
}
|
||||
oxr = xr;
|
||||
}
|
||||
}
|
||||
|
||||
void fillCircle(int x, int y, int r, Color color)
|
||||
{
|
||||
for(int i = 0; i < r + 1; i++)
|
||||
{
|
||||
int xr = (int)sqrt(r * r - i * i);
|
||||
xLine(x - xr, x + xr + 1, y + i, color);
|
||||
if(i)
|
||||
xLine(x - xr, x + xr + 1, y - i, color);
|
||||
}
|
||||
}
|
||||
|
||||
void ellipse(int x, int y, int rx, int ry, Color color)
|
||||
{
|
||||
if(ry == 0)
|
||||
return;
|
||||
int oxr = rx;
|
||||
float f = float(rx) / ry;
|
||||
f *= f;
|
||||
for(int i = 0; i < ry + 1; i++)
|
||||
{
|
||||
float s = rx * rx - i * i * f;
|
||||
int xr = (int)sqrt(s <= 0 ? 0 : s);
|
||||
xLine(x - oxr, x - xr + 1, y + i, color);
|
||||
xLine(x + xr, x + oxr + 1, y + i, color);
|
||||
if(i)
|
||||
{
|
||||
xLine(x - oxr, x - xr + 1, y - i, color);
|
||||
xLine(x + xr, x + oxr + 1, y - i, color);
|
||||
}
|
||||
oxr = xr;
|
||||
}
|
||||
}
|
||||
|
||||
void fillEllipse(int x, int y, int rx, int ry, Color color)
|
||||
{
|
||||
if(ry == 0)
|
||||
return;
|
||||
float f = float(rx) / ry;
|
||||
f *= f;
|
||||
for(int i = 0; i < ry + 1; i++)
|
||||
{
|
||||
float s = rx * rx - i * i * f;
|
||||
int xr = (int)sqrt(s <= 0 ? 0 : s);
|
||||
xLine(x - xr, x + xr + 1, y + i, color);
|
||||
if(i)
|
||||
xLine(x - xr, x + xr + 1, y - i, color);
|
||||
}
|
||||
}
|
||||
|
||||
virtual void scroll(int dy, Color color)
|
||||
{
|
||||
if(dy > 0)
|
||||
{
|
||||
for(int d = 0; d < dy; d++)
|
||||
{
|
||||
Color *l = backBuffer[0];
|
||||
for(int i = 0; i < yres - 1; i++)
|
||||
{
|
||||
backBuffer[i] = backBuffer[i + 1];
|
||||
}
|
||||
backBuffer[yres - 1] = l;
|
||||
xLine(0, xres, yres - 1, color);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for(int d = 0; d < -dy; d++)
|
||||
{
|
||||
Color *l = backBuffer[yres - 1];
|
||||
for(int i = 1; i < yres; i++)
|
||||
{
|
||||
backBuffer[i] = backBuffer[i - 1];
|
||||
}
|
||||
backBuffer[0] = l;
|
||||
xLine(0, xres, 0, color);
|
||||
}
|
||||
}
|
||||
cursorY -= dy;
|
||||
}
|
||||
|
||||
virtual Color R5G5B4A2ToColor(unsigned short c)
|
||||
{
|
||||
int r = (((c << 1) & 0x3e) * 255 + 1) / 0x3e;
|
||||
int g = (((c >> 4) & 0x3e) * 255 + 1) / 0x3e;
|
||||
int b = (((c >> 9) & 0x1e) * 255 + 1) / 0x1e;
|
||||
int a = (((c >> 13) & 6) * 255 + 1) / 6;
|
||||
return RGBA(r, g, b, a);
|
||||
}
|
||||
|
||||
virtual Color R2G2B2A2ToColor(unsigned char c)
|
||||
{
|
||||
int r = ((int(c) & 3) * 255 + 1) / 3;
|
||||
int g = (((int(c) >> 2) & 3) * 255 + 1) / 3;
|
||||
int b = (((int(c) >> 4) & 3) * 255 + 1) / 3;
|
||||
int a = (((int(c) >> 6) & 3) * 255 + 1) / 3;
|
||||
return RGBA(r, g, b, a);
|
||||
}
|
||||
|
||||
virtual void imageR5G5B4A2(Image &image, int x, int y, int srcX, int srcY, int srcXres, int srcYres)
|
||||
{
|
||||
for (int py = 0; py < srcYres; py++)
|
||||
{
|
||||
int i = srcX + (py + srcY) * image.xres;
|
||||
for (int px = 0; px < srcXres; px++)
|
||||
dot(px + x, py + y, R5G5B4A2ToColor(((unsigned short*)image.pixels)[i++]));
|
||||
}
|
||||
}
|
||||
|
||||
virtual void imageAddR5G5B4A2(Image &image, int x, int y, int srcX, int srcY, int srcXres, int srcYres)
|
||||
{
|
||||
for (int py = 0; py < srcYres; py++)
|
||||
{
|
||||
int i = srcX + (py + srcY) * image.xres;
|
||||
for (int px = 0; px < srcXres; px++)
|
||||
dotAdd(px + x, py + y, R5G5B4A2ToColor(((unsigned short*)image.pixels)[i++]));
|
||||
}
|
||||
}
|
||||
|
||||
virtual void imageMixR5G5B4A2(Image &image, int x, int y, int srcX, int srcY, int srcXres, int srcYres)
|
||||
{
|
||||
for (int py = 0; py < srcYres; py++)
|
||||
{
|
||||
int i = srcX + (py + srcY) * image.xres;
|
||||
for (int px = 0; px < srcXres; px++)
|
||||
dotMix(px + x, py + y, R5G5B4A2ToColor(((unsigned short*)image.pixels)[i++]));
|
||||
}
|
||||
}
|
||||
|
||||
virtual void imageR2G2B2A2(Image &image, int x, int y, int srcX, int srcY, int srcXres, int srcYres)
|
||||
{
|
||||
for (int py = 0; py < srcYres; py++)
|
||||
{
|
||||
int i = srcX + (py + srcY) * image.xres;
|
||||
for (int px = 0; px < srcXres; px++)
|
||||
dot(px + x, py + y, R2G2B2A2ToColor(((unsigned char*)image.pixels)[i++]));
|
||||
}
|
||||
}
|
||||
|
||||
virtual void imageAddR2G2B2A2(Image &image, int x, int y, int srcX, int srcY, int srcXres, int srcYres)
|
||||
{
|
||||
for (int py = 0; py < srcYres; py++)
|
||||
{
|
||||
int i = srcX + (py + srcY) * image.xres;
|
||||
for (int px = 0; px < srcXres; px++)
|
||||
dotAdd(px + x, py + y, R2G2B2A2ToColor(((unsigned char*)image.pixels)[i++]));
|
||||
}
|
||||
}
|
||||
|
||||
virtual void imageMixR2G2B2A2(Image &image, int x, int y, int srcX, int srcY, int srcXres, int srcYres)
|
||||
{
|
||||
for (int py = 0; py < srcYres; py++)
|
||||
{
|
||||
int i = srcX + (py + srcY) * image.xres;
|
||||
for (int px = 0; px < srcXres; px++)
|
||||
dotMix(px + x, py + y, R2G2B2A2ToColor(((unsigned char*)image.pixels)[i++]));
|
||||
}
|
||||
}
|
||||
};
|
110
libraries/bitluni_ESP32Lib/src/Graphics/GraphicsR1G1B1A1.h
Normal file
110
libraries/bitluni_ESP32Lib/src/Graphics/GraphicsR1G1B1A1.h
Normal file
|
@ -0,0 +1,110 @@
|
|||
/*
|
||||
Author: bitluni 2019
|
||||
License:
|
||||
Creative Commons Attribution ShareAlike 4.0
|
||||
https://creativecommons.org/licenses/by-sa/4.0/
|
||||
|
||||
For further details check out:
|
||||
https://youtube.com/bitlunislab
|
||||
https://github.com/bitluni
|
||||
http://bitluni.net
|
||||
*/
|
||||
#pragma once
|
||||
#include "Graphics.h"
|
||||
|
||||
class GraphicsR1G1B1A1: public Graphics<unsigned char>
|
||||
{
|
||||
public:
|
||||
typedef unsigned char Color;
|
||||
GraphicsR1G1B1A1()
|
||||
{
|
||||
frontColor = 0xf;
|
||||
}
|
||||
|
||||
virtual int R(Color c) const
|
||||
{
|
||||
return (c & 1) * 255;
|
||||
}
|
||||
virtual int G(Color c) const
|
||||
{
|
||||
return (c & 2) ? 255 : 0;
|
||||
}
|
||||
virtual int B(Color c) const
|
||||
{
|
||||
return (c & 4) ? 255 : 0;
|
||||
}
|
||||
virtual int A(Color c) const
|
||||
{
|
||||
return (c & 8) ? 255 : 0;
|
||||
}
|
||||
|
||||
virtual Color RGBA(int r, int g, int b, int a = 255) const
|
||||
{
|
||||
return ((r >> 7) & 1) | ((g >> 6) & 2) | ((b >> 5) & 4) | ((a >> 4) & 8);
|
||||
}
|
||||
|
||||
virtual void dotFast(int x, int y, Color color)
|
||||
{
|
||||
if(x & 1)
|
||||
backBuffer[y][x >> 1] = (backBuffer[y][x >> 1] & 0xf) | (color << 4);
|
||||
else
|
||||
backBuffer[y][x >> 1] = (backBuffer[y][x >> 1] & 0xf0) | (color & 0xf);
|
||||
}
|
||||
|
||||
virtual void dot(int x, int y, Color color)
|
||||
{
|
||||
if ((unsigned int)x < xres && (unsigned int)y < yres)
|
||||
{
|
||||
if(x & 1)
|
||||
backBuffer[y][x >> 1] = (backBuffer[y][x >> 1] & 0xf) | (color << 4);
|
||||
else
|
||||
backBuffer[y][x >> 1] = (backBuffer[y][x >> 1] & 0xf0) | (color & 0xf);
|
||||
}
|
||||
}
|
||||
|
||||
virtual void dotAdd(int x, int y, Color color)
|
||||
{
|
||||
if ((unsigned int)x < xres && (unsigned int)y < yres)
|
||||
{
|
||||
if(x & 1)
|
||||
backBuffer[y][x >> 1] = backBuffer[y][x >> 1] | (color << 4);
|
||||
else
|
||||
backBuffer[y][x >> 1] = backBuffer[y][x >> 1] | (color & 0xf);
|
||||
}
|
||||
}
|
||||
|
||||
virtual void dotMix(int x, int y, Color color)
|
||||
{
|
||||
if ((unsigned int)x < xres && (unsigned int)y < yres && (color & 8) != 0)
|
||||
{
|
||||
if(x & 1)
|
||||
backBuffer[y][x >> 1] = (backBuffer[y][x >> 1] & 0xf) | (color << 4);
|
||||
else
|
||||
backBuffer[y][x >> 1] = (backBuffer[y][x >> 1] & 0xf0) | (color & 0xf);
|
||||
}
|
||||
}
|
||||
|
||||
virtual Color get(int x, int y)
|
||||
{
|
||||
if ((unsigned int)x < xres && (unsigned int)y < yres)
|
||||
{
|
||||
if(x & 1)
|
||||
return backBuffer[y][x >> 1] = backBuffer[y][x >> 1] >> 4;
|
||||
else
|
||||
return backBuffer[y][x >> 1] = backBuffer[y][x >> 1] & 0xf;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
virtual void clear(Color color = 0)
|
||||
{
|
||||
for (int y = 0; y < this->yres; y++)
|
||||
for (int x = 0; x < this->xres / 2; x++)
|
||||
this->backBuffer[y][x] = color | (color << 4);
|
||||
}
|
||||
|
||||
virtual Color** allocateFrameBuffer()
|
||||
{
|
||||
return Graphics<Color>::allocateFrameBuffer(xres / 2, yres, (Color)0);
|
||||
}
|
||||
};
|
|
@ -0,0 +1,91 @@
|
|||
/*
|
||||
Author: bitluni 2019
|
||||
License:
|
||||
Creative Commons Attribution ShareAlike 4.0
|
||||
https://creativecommons.org/licenses/by-sa/4.0/
|
||||
|
||||
For further details check out:
|
||||
https://youtube.com/bitlunislab
|
||||
https://github.com/bitluni
|
||||
http://bitluni.net
|
||||
*/
|
||||
#pragma once
|
||||
#include "Graphics.h"
|
||||
|
||||
class GraphicsR1G1B1A1X2S2Swapped: public Graphics<unsigned char>
|
||||
{
|
||||
public:
|
||||
typedef unsigned char Color;
|
||||
static const Color RGBAXMask = 0x3f;
|
||||
Color SBits;
|
||||
|
||||
GraphicsR1G1B1A1X2S2Swapped()
|
||||
{
|
||||
SBits = 0xc0;
|
||||
frontColor = 0xf;
|
||||
}
|
||||
|
||||
virtual int R(Color c) const
|
||||
{
|
||||
return (c & 1) * 255;
|
||||
}
|
||||
virtual int G(Color c) const
|
||||
{
|
||||
return (c & 2) ? 255 : 0;
|
||||
}
|
||||
virtual int B(Color c) const
|
||||
{
|
||||
return (c & 4) ? 255 : 0;
|
||||
}
|
||||
virtual int A(Color c) const
|
||||
{
|
||||
return (c & 8) ? 255 : 0;
|
||||
}
|
||||
|
||||
virtual Color RGBA(int r, int g, int b, int a = 255) const
|
||||
{
|
||||
return ((r >> 7) & 1) | ((g >> 6) & 2) | ((b >> 5) & 4) | ((a >> 4) & 8);
|
||||
}
|
||||
|
||||
virtual void dotFast(int x, int y, Color color)
|
||||
{
|
||||
backBuffer[y][x^2] = (color & RGBAXMask) | SBits;
|
||||
}
|
||||
|
||||
virtual void dot(int x, int y, Color color)
|
||||
{
|
||||
if ((unsigned int)x < xres && (unsigned int)y < yres)
|
||||
backBuffer[y][x^2] = (color & RGBAXMask) | SBits;
|
||||
}
|
||||
|
||||
virtual void dotAdd(int x, int y, Color color)
|
||||
{
|
||||
if ((unsigned int)x < xres && (unsigned int)y < yres)
|
||||
backBuffer[y][x^2] = backBuffer[y][x^2] | (color & RGBAXMask);
|
||||
}
|
||||
|
||||
virtual void dotMix(int x, int y, Color color)
|
||||
{
|
||||
if ((unsigned int)x < xres && (unsigned int)y < yres && (color & 8) != 0)
|
||||
backBuffer[y][x^2] = (color & RGBAXMask) | SBits;
|
||||
}
|
||||
|
||||
virtual Color get(int x, int y)
|
||||
{
|
||||
if ((unsigned int)x < xres && (unsigned int)y < yres)
|
||||
return backBuffer[y][x^2] & RGBAXMask;
|
||||
return 0;
|
||||
}
|
||||
|
||||
virtual void clear(Color color = 0)
|
||||
{
|
||||
for (int y = 0; y < this->yres; y++)
|
||||
for (int x = 0; x < this->xres; x++)
|
||||
backBuffer[y][x^2] = (color & RGBAXMask) | SBits;
|
||||
}
|
||||
|
||||
virtual Color** allocateFrameBuffer()
|
||||
{
|
||||
return Graphics<Color>::allocateFrameBuffer(xres, yres, (Color)SBits);
|
||||
}
|
||||
};
|
142
libraries/bitluni_ESP32Lib/src/Graphics/GraphicsR2G2B2A2.h
Normal file
142
libraries/bitluni_ESP32Lib/src/Graphics/GraphicsR2G2B2A2.h
Normal file
|
@ -0,0 +1,142 @@
|
|||
/*
|
||||
Author: bitluni 2019
|
||||
License:
|
||||
Creative Commons Attribution ShareAlike 4.0
|
||||
https://creativecommons.org/licenses/by-sa/4.0/
|
||||
|
||||
For further details check out:
|
||||
https://youtube.com/bitlunislab
|
||||
https://github.com/bitluni
|
||||
http://bitluni.net
|
||||
*/
|
||||
#pragma once
|
||||
#include "Graphics.h"
|
||||
|
||||
class GraphicsR2G2B2A2: public Graphics<unsigned char>
|
||||
{
|
||||
public:
|
||||
typedef unsigned char Color;
|
||||
static const Color RGBAXMask = 0x3f;
|
||||
Color SBits;
|
||||
|
||||
GraphicsR2G2B2A2()
|
||||
{
|
||||
SBits = 0xc0;
|
||||
frontColor = 0xff;
|
||||
}
|
||||
|
||||
virtual int R(Color c) const
|
||||
{
|
||||
return (((int)c & 3) * 255 + 1) / 3;
|
||||
}
|
||||
virtual int G(Color c) const
|
||||
{
|
||||
return (((int)(c >> 2) & 3) * 255 + 1) / 3;
|
||||
}
|
||||
virtual int B(Color c) const
|
||||
{
|
||||
return (((int)(c >> 4) & 3) * 255 + 1) / 3;
|
||||
}
|
||||
virtual int A(Color c) const
|
||||
{
|
||||
return (((int)(c >> 6) & 3) * 255 + 1) / 3;
|
||||
}
|
||||
|
||||
virtual Color RGBA(int r, int g, int b, int a = 255) const
|
||||
{
|
||||
return ((r >> 6) & 0b11) | ((g >> 4) & 0b1100) | ((b >> 2) & 0b110000) | (a & 0b11000000);
|
||||
}
|
||||
|
||||
virtual void dotFast(int x, int y, Color color)
|
||||
{
|
||||
backBuffer[y][x] = (color & RGBAXMask) | SBits;
|
||||
}
|
||||
|
||||
virtual void dot(int x, int y, Color color)
|
||||
{
|
||||
if ((unsigned int)x < xres && (unsigned int)y < yres)
|
||||
backBuffer[y][x] = (color & RGBAXMask) | SBits;
|
||||
}
|
||||
|
||||
virtual void dotAdd(int x, int y, Color color)
|
||||
{
|
||||
if ((unsigned int)x < xres && (unsigned int)y < yres)
|
||||
{
|
||||
int c0 = backBuffer[y][x^2];
|
||||
int c1 = color;
|
||||
int r = (c0 & 0b11) + (c1 & 0b11);
|
||||
if(r > 0b11) r = 0b11;
|
||||
int g = (c0 & 0b1100) + (c1 & 0b1100);
|
||||
if(g > 0b1100) g = 0b1100;
|
||||
int b = (c0 & 0b110000) + (c1 & 0b110000);
|
||||
if(b > 0b110000) b = 0b110000;
|
||||
backBuffer[y][x] = r | (g & 0b1100) | (b & 0b110000) | SBits;
|
||||
}
|
||||
}
|
||||
|
||||
virtual void dotMix(int x, int y, Color color)
|
||||
{
|
||||
if ((unsigned int)x < xres && (unsigned int)y < yres && (color >> 6) != 0)
|
||||
{
|
||||
unsigned int ai = (3 - ((int)color >> 6)) * (65536 / 3);
|
||||
unsigned int a = 65536 - ai;
|
||||
unsigned int co = backBuffer[y][x^2];
|
||||
unsigned int ro = (co & 0b11) * ai;
|
||||
unsigned int go = (co & 0b1100) * ai;
|
||||
unsigned int bo = (co & 0b110000) * ai;
|
||||
unsigned int r = (color & 0b11) * a + ro;
|
||||
unsigned int g = ((color & 0b1100) * a + go) & 0b11000000000000000000;
|
||||
unsigned int b = ((color & 0b110000) * a + bo) & 0b1100000000000000000000;
|
||||
backBuffer[y][x] = ((r | g | b) >> 16) | SBits;
|
||||
}
|
||||
}
|
||||
|
||||
virtual Color get(int x, int y)
|
||||
{
|
||||
if ((unsigned int)x < xres && (unsigned int)y < yres)
|
||||
return backBuffer[y][x] & RGBAXMask;
|
||||
return 0;
|
||||
}
|
||||
|
||||
virtual void clear(Color color = 0)
|
||||
{
|
||||
for (int y = 0; y < this->yres; y++)
|
||||
for (int x = 0; x < this->xres; x++)
|
||||
backBuffer[y][x] = (color & RGBAXMask) | SBits;
|
||||
}
|
||||
|
||||
virtual void imageR2G2B2A2(Image &image, int x, int y, int srcX, int srcY, int srcXres, int srcYres)
|
||||
{
|
||||
for (int py = 0; py < srcYres; py++)
|
||||
{
|
||||
int i = srcX + (py + srcY) * image.xres;
|
||||
for (int px = 0; px < srcXres; px++)
|
||||
dot(px + x, py + y, ((unsigned char*)image.pixels)[i++]);
|
||||
}
|
||||
}
|
||||
|
||||
virtual void imageAddR2G2B2A2(Image &image, int x, int y, int srcX, int srcY, int srcXres, int srcYres)
|
||||
{
|
||||
for (int py = 0; py < srcYres; py++)
|
||||
{
|
||||
int i = srcX + (py + srcY) * image.xres;
|
||||
for (int px = 0; px < srcXres; px++)
|
||||
dotAdd(px + x, py + y, ((unsigned char*)image.pixels)[i++]);
|
||||
}
|
||||
}
|
||||
|
||||
virtual void imageMixR2G2B2A2(Image &image, int x, int y, int srcX, int srcY, int srcXres, int srcYres)
|
||||
{
|
||||
for (int py = 0; py < srcYres; py++)
|
||||
{
|
||||
int i = srcX + (py + srcY) * image.xres;
|
||||
for (int px = 0; px < srcXres; px++)
|
||||
dotMix(px + x, py + y, ((unsigned char*)image.pixels)[i++]);
|
||||
}
|
||||
}
|
||||
|
||||
virtual Color** allocateFrameBuffer()
|
||||
{
|
||||
return Graphics<Color>::allocateFrameBuffer(xres, yres, (Color)SBits);
|
||||
}
|
||||
};
|
|
@ -0,0 +1,142 @@
|
|||
/*
|
||||
Author: bitluni 2019
|
||||
License:
|
||||
Creative Commons Attribution ShareAlike 4.0
|
||||
https://creativecommons.org/licenses/by-sa/4.0/
|
||||
|
||||
For further details check out:
|
||||
https://youtube.com/bitlunislab
|
||||
https://github.com/bitluni
|
||||
http://bitluni.net
|
||||
*/
|
||||
#pragma once
|
||||
#include "Graphics.h"
|
||||
|
||||
class GraphicsR2G2B2S2Swapped: public Graphics<unsigned char>
|
||||
{
|
||||
public:
|
||||
typedef unsigned char Color;
|
||||
static const Color RGBAXMask = 0x3f;
|
||||
Color SBits;
|
||||
|
||||
GraphicsR2G2B2S2Swapped()
|
||||
{
|
||||
SBits = 0xc0;
|
||||
frontColor = 0xff;
|
||||
}
|
||||
|
||||
virtual int R(Color c) const
|
||||
{
|
||||
return (((int)c & 3) * 255 + 1) / 3;
|
||||
}
|
||||
virtual int G(Color c) const
|
||||
{
|
||||
return (((int)(c >> 2) & 3) * 255 + 1) / 3;
|
||||
}
|
||||
virtual int B(Color c) const
|
||||
{
|
||||
return (((int)(c >> 4) & 3) * 255 + 1) / 3;
|
||||
}
|
||||
virtual int A(Color c) const
|
||||
{
|
||||
return (((int)(c >> 6) & 3) * 255 + 1) / 3;
|
||||
}
|
||||
|
||||
virtual Color RGBA(int r, int g, int b, int a = 255) const
|
||||
{
|
||||
return ((r >> 6) & 0b11) | ((g >> 4) & 0b1100) | ((b >> 2) & 0b110000) | (a & 0b11000000);
|
||||
}
|
||||
|
||||
virtual void dotFast(int x, int y, Color color)
|
||||
{
|
||||
backBuffer[y][x^2] = (color & RGBAXMask) | SBits;
|
||||
}
|
||||
|
||||
virtual void dot(int x, int y, Color color)
|
||||
{
|
||||
if ((unsigned int)x < xres && (unsigned int)y < yres)
|
||||
backBuffer[y][x^2] = (color & RGBAXMask) | SBits;
|
||||
}
|
||||
|
||||
virtual void dotAdd(int x, int y, Color color)
|
||||
{
|
||||
if ((unsigned int)x < xres && (unsigned int)y < yres)
|
||||
{
|
||||
int c0 = backBuffer[y][x^2];
|
||||
int c1 = color;
|
||||
int r = (c0 & 0b11) + (c1 & 0b11);
|
||||
if(r > 0b11) r = 0b11;
|
||||
int g = (c0 & 0b1100) + (c1 & 0b1100);
|
||||
if(g > 0b1100) g = 0b1100;
|
||||
int b = (c0 & 0b110000) + (c1 & 0b110000);
|
||||
if(b > 0b110000) b = 0b110000;
|
||||
backBuffer[y][x^2] = r | (g & 0b1100) | (b & 0b110000) | SBits;
|
||||
}
|
||||
}
|
||||
|
||||
virtual void dotMix(int x, int y, Color color)
|
||||
{
|
||||
if ((unsigned int)x < xres && (unsigned int)y < yres && (color >> 6) != 0)
|
||||
{
|
||||
unsigned int ai = (3 - ((int)color >> 6)) * (65536 / 3);
|
||||
unsigned int a = 65536 - ai;
|
||||
unsigned int co = backBuffer[y][x^2];
|
||||
unsigned int ro = (co & 0b11) * ai;
|
||||
unsigned int go = (co & 0b1100) * ai;
|
||||
unsigned int bo = (co & 0b110000) * ai;
|
||||
unsigned int r = (color & 0b11) * a + ro;
|
||||
unsigned int g = ((color & 0b1100) * a + go) & 0b11000000000000000000;
|
||||
unsigned int b = ((color & 0b110000) * a + bo) & 0b1100000000000000000000;
|
||||
backBuffer[y][x^2] = ((r | g | b) >> 16) | SBits;
|
||||
}
|
||||
}
|
||||
|
||||
virtual Color get(int x, int y)
|
||||
{
|
||||
if ((unsigned int)x < xres && (unsigned int)y < yres)
|
||||
return backBuffer[y][x^2] & RGBAXMask;
|
||||
return 0;
|
||||
}
|
||||
|
||||
virtual void clear(Color color = 0)
|
||||
{
|
||||
for (int y = 0; y < this->yres; y++)
|
||||
for (int x = 0; x < this->xres; x++)
|
||||
backBuffer[y][x^2] = (color & RGBAXMask) | SBits;
|
||||
}
|
||||
|
||||
virtual void imageR2G2B2A2(Image &image, int x, int y, int srcX, int srcY, int srcXres, int srcYres)
|
||||
{
|
||||
for (int py = 0; py < srcYres; py++)
|
||||
{
|
||||
int i = srcX + (py + srcY) * image.xres;
|
||||
for (int px = 0; px < srcXres; px++)
|
||||
dot(px + x, py + y, ((unsigned char*)image.pixels)[i++]);
|
||||
}
|
||||
}
|
||||
|
||||
virtual void imageAddR2G2B2A2(Image &image, int x, int y, int srcX, int srcY, int srcXres, int srcYres)
|
||||
{
|
||||
for (int py = 0; py < srcYres; py++)
|
||||
{
|
||||
int i = srcX + (py + srcY) * image.xres;
|
||||
for (int px = 0; px < srcXres; px++)
|
||||
dotAdd(px + x, py + y, ((unsigned char*)image.pixels)[i++]);
|
||||
}
|
||||
}
|
||||
|
||||
virtual void imageMixR2G2B2A2(Image &image, int x, int y, int srcX, int srcY, int srcXres, int srcYres)
|
||||
{
|
||||
for (int py = 0; py < srcYres; py++)
|
||||
{
|
||||
int i = srcX + (py + srcY) * image.xres;
|
||||
for (int px = 0; px < srcXres; px++)
|
||||
dotMix(px + x, py + y, ((unsigned char*)image.pixels)[i++]);
|
||||
}
|
||||
}
|
||||
|
||||
virtual Color** allocateFrameBuffer()
|
||||
{
|
||||
return Graphics<Color>::allocateFrameBuffer(xres, yres, (Color)SBits);
|
||||
}
|
||||
};
|
108
libraries/bitluni_ESP32Lib/src/Graphics/GraphicsR5G5B4A2.h
Normal file
108
libraries/bitluni_ESP32Lib/src/Graphics/GraphicsR5G5B4A2.h
Normal file
|
@ -0,0 +1,108 @@
|
|||
/*
|
||||
Author: bitluni 2019
|
||||
License:
|
||||
Creative Commons Attribution ShareAlike 4.0
|
||||
https://creativecommons.org/licenses/by-sa/4.0/
|
||||
|
||||
For further details check out:
|
||||
https://youtube.com/bitlunislab
|
||||
https://github.com/bitluni
|
||||
http://bitluni.net
|
||||
*/
|
||||
#pragma once
|
||||
#include "Graphics.h"
|
||||
|
||||
class GraphicsR5G5B4A2: public Graphics<unsigned short>
|
||||
{
|
||||
public:
|
||||
typedef unsigned short Color;
|
||||
GraphicsR5G5B4A2()
|
||||
{
|
||||
frontColor = 0xffff;
|
||||
}
|
||||
|
||||
virtual int R(Color c) const
|
||||
{
|
||||
return (((c << 1) & 0x3e) * 255 + 1) / 0x3e;
|
||||
}
|
||||
virtual int G(Color c) const
|
||||
{
|
||||
return (((c >> 4) & 0x3e) * 255 + 1) / 0x3e;
|
||||
}
|
||||
virtual int B(Color c) const
|
||||
{
|
||||
return (((c >> 9) & 0x1e) * 255 + 1) / 0x1e;
|
||||
}
|
||||
virtual int A(Color c) const
|
||||
{
|
||||
return (((c >> 13) & 6) * 255 + 1) / 6;
|
||||
}
|
||||
|
||||
virtual Color RGBA(int r, int g, int b, int a = 255) const
|
||||
{
|
||||
return ((r >> 3) & 0b11111) | ((g << 2) & 0b1111100000) | ((b << 6) & 0b11110000000000) | ((a << 8) & 0xc000);
|
||||
}
|
||||
|
||||
virtual void dotFast(int x, int y, Color color)
|
||||
{
|
||||
backBuffer[y][x] = color;
|
||||
}
|
||||
|
||||
virtual void dot(int x, int y, Color color)
|
||||
{
|
||||
if ((unsigned int)x < xres && (unsigned int)y < yres)
|
||||
backBuffer[y][x] = color;
|
||||
}
|
||||
|
||||
virtual void dotAdd(int x, int y, Color color)
|
||||
{
|
||||
if ((unsigned int)x < xres && (unsigned int)y < yres)
|
||||
{
|
||||
int c0 = backBuffer[y][x];
|
||||
int c1 = color;
|
||||
int r = (c0 & 0b11111) + (c1 & 0b11111);
|
||||
if(r > 0b11111) r = 0b11111;
|
||||
int g = (c0 & 0b1111100000) + (c1 & 0b1111100000);
|
||||
if(g > 0b1111100000) g = 0b1111100000;
|
||||
int b = (c0 & 0b11110000000000) + (c1 & 0b11110000000000);
|
||||
if(b > 0b11110000000000) b = 0b11110000000000;
|
||||
backBuffer[y][x] = r | (g & 0b1111100000) | (b & 0b11110000000000);
|
||||
}
|
||||
}
|
||||
|
||||
virtual void dotMix(int x, int y, Color color)
|
||||
{
|
||||
if ((unsigned int)x < xres && (unsigned int)y < yres && (color >> 14) != 0)
|
||||
{
|
||||
unsigned int ai = (3 - (color >> 14)) * (65536 / 3);
|
||||
unsigned int a = 65536 - ai;
|
||||
unsigned int co = backBuffer[y][x];
|
||||
unsigned int ro = (co & 0b11111) * ai;
|
||||
unsigned int go = (co & 0b1111100000) * ai;
|
||||
unsigned int bo = (co & 0b11110000000000) * ai;
|
||||
unsigned int r = (color & 0b11111) * a + ro;
|
||||
unsigned int g = ((color & 0b1111100000) * a + go) & 0b11111000000000000000000000;
|
||||
unsigned int b = ((color & 0b11110000000000) * a + bo) & 0b111100000000000000000000000000;
|
||||
backBuffer[y][x] = (r | g | b) >> 16;
|
||||
}
|
||||
}
|
||||
|
||||
virtual Color get(int x, int y)
|
||||
{
|
||||
if ((unsigned int)x < xres && (unsigned int)y < yres)
|
||||
return backBuffer[y][x];
|
||||
return 0;
|
||||
}
|
||||
|
||||
virtual void clear(Color color = 0)
|
||||
{
|
||||
for (int y = 0; y < this->yres; y++)
|
||||
for (int x = 0; x < this->xres; x++)
|
||||
backBuffer[y][x] = color;
|
||||
}
|
||||
|
||||
virtual Color** allocateFrameBuffer()
|
||||
{
|
||||
return Graphics<Color>::allocateFrameBuffer(xres, yres, (Color)0);
|
||||
}
|
||||
};
|
|
@ -0,0 +1,112 @@
|
|||
/*
|
||||
Author: bitluni 2019
|
||||
License:
|
||||
Creative Commons Attribution ShareAlike 4.0
|
||||
https://creativecommons.org/licenses/by-sa/4.0/
|
||||
|
||||
For further details check out:
|
||||
https://youtube.com/bitlunislab
|
||||
https://github.com/bitluni
|
||||
http://bitluni.net
|
||||
*/
|
||||
#pragma once
|
||||
#include "Graphics.h"
|
||||
|
||||
class GraphicsR5G5B4S2Swapped: public Graphics<unsigned short>
|
||||
{
|
||||
public:
|
||||
typedef unsigned short Color;
|
||||
static const Color RGBMask = 0x3fff;
|
||||
Color SBits;
|
||||
|
||||
GraphicsR5G5B4S2Swapped()
|
||||
{
|
||||
SBits = 0xc000;
|
||||
frontColor = 0xffff;
|
||||
}
|
||||
|
||||
virtual int R(Color c) const
|
||||
{
|
||||
return (((c << 1) & 0x3e) * 255 + 1) / 0x3e;
|
||||
}
|
||||
virtual int G(Color c) const
|
||||
{
|
||||
return (((c >> 4) & 0x3e) * 255 + 1) / 0x3e;
|
||||
}
|
||||
virtual int B(Color c) const
|
||||
{
|
||||
return (((c >> 9) & 0x1e) * 255 + 1) / 0x1e;
|
||||
}
|
||||
virtual int A(Color c) const
|
||||
{
|
||||
return (((c >> 13) & 6) * 255 + 1) / 6;
|
||||
}
|
||||
|
||||
virtual Color RGBA(int r, int g, int b, int a = 255) const
|
||||
{
|
||||
return ((r >> 3) & 0b11111) | ((g << 2) & 0b1111100000) | ((b << 6) & 0b11110000000000) | ((a << 8) & 0xc000);
|
||||
}
|
||||
|
||||
virtual void dotFast(int x, int y, Color color)
|
||||
{
|
||||
backBuffer[y][x^1] = (color & RGBMask) | SBits;
|
||||
}
|
||||
|
||||
virtual void dot(int x, int y, Color color)
|
||||
{
|
||||
if ((unsigned int)x < xres && (unsigned int)y < yres)
|
||||
backBuffer[y][x^1] = (color & RGBMask) | SBits;
|
||||
}
|
||||
|
||||
virtual void dotAdd(int x, int y, Color color)
|
||||
{
|
||||
if ((unsigned int)x < xres && (unsigned int)y < yres)
|
||||
{
|
||||
int c0 = backBuffer[y][x^1];
|
||||
int c1 = color;
|
||||
int r = (c0 & 0b11111) + (c1 & 0b11111);
|
||||
if(r > 0b11111) r = 0b11111;
|
||||
int g = (c0 & 0b1111100000) + (c1 & 0b1111100000);
|
||||
if(g > 0b1111100000) g = 0b1111100000;
|
||||
int b = (c0 & 0b11110000000000) + (c1 & 0b11110000000000);
|
||||
if(b > 0b11110000000000) b = 0b11110000000000;
|
||||
backBuffer[y][x^1] = r | (g & 0b1111100000) | (b & 0b11110000000000) | SBits;
|
||||
}
|
||||
}
|
||||
|
||||
virtual void dotMix(int x, int y, Color color)
|
||||
{
|
||||
if ((unsigned int)x < xres && (unsigned int)y < yres && (color >> 14) != 0)
|
||||
{
|
||||
unsigned int ai = (3 - (color >> 14)) * (65536 / 3);
|
||||
unsigned int a = 65536 - ai;
|
||||
unsigned int co = backBuffer[y][x^1];
|
||||
unsigned int ro = (co & 0b11111) * ai;
|
||||
unsigned int go = (co & 0b1111100000) * ai;
|
||||
unsigned int bo = (co & 0b11110000000000) * ai;
|
||||
unsigned int r = (color & 0b11111) * a + ro;
|
||||
unsigned int g = ((color & 0b1111100000) * a + go) & 0b11111000000000000000000000;
|
||||
unsigned int b = ((color & 0b11110000000000) * a + bo) & 0b111100000000000000000000000000;
|
||||
backBuffer[y][x^1] = ((r | g | b) >> 16) | SBits;
|
||||
}
|
||||
}
|
||||
|
||||
virtual Color get(int x, int y)
|
||||
{
|
||||
if ((unsigned int)x < xres && (unsigned int)y < yres)
|
||||
return backBuffer[y][x^1] & RGBMask;
|
||||
return 0;
|
||||
}
|
||||
|
||||
virtual void clear(Color color = 0)
|
||||
{
|
||||
for (int y = 0; y < this->yres; y++)
|
||||
for (int x = 0; x < this->xres; x++)
|
||||
backBuffer[y][x^1] = (color & RGBMask) | SBits;
|
||||
}
|
||||
|
||||
virtual Color** allocateFrameBuffer()
|
||||
{
|
||||
return Graphics<Color>::allocateFrameBuffer(xres, yres, (Color)SBits);
|
||||
}
|
||||
};
|
52
libraries/bitluni_ESP32Lib/src/Graphics/Image.h
Normal file
52
libraries/bitluni_ESP32Lib/src/Graphics/Image.h
Normal file
|
@ -0,0 +1,52 @@
|
|||
/*
|
||||
Author: bitluni 2019
|
||||
License:
|
||||
Creative Commons Attribution ShareAlike 4.0
|
||||
https://creativecommons.org/licenses/by-sa/4.0/
|
||||
|
||||
For further details check out:
|
||||
https://youtube.com/bitlunislab
|
||||
https://github.com/bitluni
|
||||
http://bitluni.net
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
class Image
|
||||
{
|
||||
public:
|
||||
enum PixelFormat
|
||||
{
|
||||
R8G8B8A8 = 1,
|
||||
R1G1B1A1 = 2,
|
||||
R2G2B2A2 = 3,
|
||||
R4G4B4A4 = 4,
|
||||
R5G5B5A1 = 5,
|
||||
R5G5B4A2 = 6
|
||||
};
|
||||
|
||||
int xres;
|
||||
int yres;
|
||||
PixelFormat pixelFormat;
|
||||
const void *pixels;
|
||||
|
||||
void init(int xres, int yres, const void *pixels, PixelFormat pixelFormat)
|
||||
{
|
||||
this->xres = xres;
|
||||
this->yres = yres;
|
||||
this->pixels = pixels;
|
||||
this->pixelFormat = pixelFormat;
|
||||
}
|
||||
|
||||
Image(){};
|
||||
|
||||
Image(int xres, int yres, const void *pixels, PixelFormat pixelFormat)
|
||||
{
|
||||
init(xres, yres, pixels, pixelFormat);
|
||||
}
|
||||
|
||||
/*
|
||||
Color get(int x, int y) const
|
||||
{
|
||||
return pixels[y * xres + x];
|
||||
}*/
|
||||
};
|
113
libraries/bitluni_ESP32Lib/src/Graphics/ImageDrawer.h
Normal file
113
libraries/bitluni_ESP32Lib/src/Graphics/ImageDrawer.h
Normal file
|
@ -0,0 +1,113 @@
|
|||
/*
|
||||
Author: bitluni 2019
|
||||
License:
|
||||
Creative Commons Attribution ShareAlike 4.0
|
||||
https://creativecommons.org/licenses/by-sa/4.0/
|
||||
|
||||
For further details check out:
|
||||
https://youtube.com/bitlunislab
|
||||
https://github.com/bitluni
|
||||
http://bitluni.net
|
||||
*/
|
||||
#pragma once
|
||||
#include "Image.h"
|
||||
class ImageDrawer
|
||||
{
|
||||
public:
|
||||
virtual void imageR5G5B4A2(Image &image, int x, int y, int srcX, int srcY, int srcXres, int srcYres) = 0;
|
||||
virtual void imageAddR5G5B4A2(Image &image, int x, int y, int srcX, int srcY, int srcXres, int srcYres) = 0;
|
||||
virtual void imageMixR5G5B4A2(Image &image, int x, int y, int srcX, int srcY, int srcXres, int srcYres) = 0;
|
||||
virtual void imageR2G2B2A2(Image &image, int x, int y, int srcX, int srcY, int srcXres, int srcYres) = 0;
|
||||
virtual void imageAddR2G2B2A2(Image &image, int x, int y, int srcX, int srcY, int srcXres, int srcYres) = 0;
|
||||
virtual void imageMixR2G2B2A2(Image &image, int x, int y, int srcX, int srcY, int srcXres, int srcYres) = 0;
|
||||
|
||||
void image(Image &image, int x, int y, int srcX, int srcY, int srcXres, int srcYres)
|
||||
{
|
||||
switch(image.pixelFormat)
|
||||
{
|
||||
case Image::R5G5B4A2:
|
||||
imageR5G5B4A2(image, x, y, srcX, srcY, srcXres, srcYres);
|
||||
break;
|
||||
case Image::R2G2B2A2:
|
||||
imageR2G2B2A2(image, x, y, srcX, srcY, srcXres, srcYres);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void imageAdd(Image &image, int x, int y, int srcX, int srcY, int srcXres, int srcYres)
|
||||
{
|
||||
switch(image.pixelFormat)
|
||||
{
|
||||
case Image::R5G5B4A2:
|
||||
imageAddR5G5B4A2(image, x, y, srcX, srcY, srcXres, srcYres);
|
||||
break;
|
||||
case Image::R2G2B2A2:
|
||||
imageAddR2G2B2A2(image, x, y, srcX, srcY, srcXres, srcYres);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void imageMix(Image &image, int x, int y, int srcX, int srcY, int srcXres, int srcYres)
|
||||
{
|
||||
switch(image.pixelFormat)
|
||||
{
|
||||
case Image::R5G5B4A2:
|
||||
imageMixR5G5B4A2(image, x, y, srcX, srcY, srcXres, srcYres);
|
||||
break;
|
||||
case Image::R2G2B2A2:
|
||||
imageMixR2G2B2A2(image, x, y, srcX, srcY, srcXres, srcYres);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void image(Image &image, int x, int y)
|
||||
{
|
||||
switch(image.pixelFormat)
|
||||
{
|
||||
case Image::R5G5B4A2:
|
||||
imageR5G5B4A2(image, x, y, 0, 0, image.xres, image.yres);
|
||||
break;
|
||||
case Image::R2G2B2A2:
|
||||
imageR2G2B2A2(image, x, y, 0, 0, image.xres, image.yres);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void imageAdd(Image &image, int x, int y)
|
||||
{
|
||||
switch(image.pixelFormat)
|
||||
{
|
||||
case Image::R5G5B4A2:
|
||||
imageAddR5G5B4A2(image, x, y, 0, 0, image.xres, image.yres);
|
||||
break;
|
||||
case Image::R2G2B2A2:
|
||||
imageAddR2G2B2A2(image, x, y, 0, 0, image.xres, image.yres);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void imageMix(Image &image, int x, int y)
|
||||
{
|
||||
switch(image.pixelFormat)
|
||||
{
|
||||
case Image::R5G5B4A2:
|
||||
imageMixR5G5B4A2(image, x, y, 0, 0, image.xres, image.yres);
|
||||
break;
|
||||
case Image::R2G2B2A2:
|
||||
imageMixR2G2B2A2(image, x, y, 0, 0, image.xres, image.yres);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
};
|
137
libraries/bitluni_ESP32Lib/src/Graphics/Mesh.h
Normal file
137
libraries/bitluni_ESP32Lib/src/Graphics/Mesh.h
Normal file
|
@ -0,0 +1,137 @@
|
|||
/*
|
||||
Author: bitluni 2019
|
||||
License:
|
||||
Creative Commons Attribution ShareAlike 4.0
|
||||
https://creativecommons.org/licenses/by-sa/4.0/
|
||||
|
||||
For further details check out:
|
||||
https://youtube.com/bitlunislab
|
||||
https://github.com/bitluni
|
||||
http://bitluni.net
|
||||
*/
|
||||
#pragma once
|
||||
#include "../Math/Matrix.h"
|
||||
#include "Engine3D.h"
|
||||
#include "../Tools/Log.h"
|
||||
|
||||
template <typename Graphics>
|
||||
class Mesh
|
||||
{
|
||||
public:
|
||||
typedef typename Graphics::Color Color;
|
||||
int vertexCount;
|
||||
int edgeCount;
|
||||
int triangleCount;
|
||||
const float (*vertices)[3];
|
||||
const unsigned short (*edges)[2];
|
||||
const unsigned short (*triangles)[3];
|
||||
const float (*triangleNormals)[3];
|
||||
short (*tvertices)[3];
|
||||
signed char (*tTriNormals)[3];
|
||||
|
||||
typedef Color (*triangleShader)(int trinangleNo, short *v0, short *v1, short *v2, const signed char *normal, Color color);
|
||||
|
||||
Mesh(int vertCount, const float verts[][3], int edgeCount_ = 0, const unsigned short edges_[][2] = 0, int triCount = 0, const unsigned short tris[][3] = 0, const float triNorms[][3] = 0)
|
||||
: vertexCount(vertCount),
|
||||
edgeCount(edgeCount_),
|
||||
triangleCount(triCount),
|
||||
vertices(verts),
|
||||
edges(edges_),
|
||||
triangles(tris),
|
||||
triangleNormals(triNorms)
|
||||
{
|
||||
tvertices = (short(*)[3])malloc(sizeof(short) * 3 * vertexCount);
|
||||
if(!tvertices)
|
||||
ERROR("Not enough memory for vertices");
|
||||
if (triangleNormals)
|
||||
{
|
||||
tTriNormals = (signed char(*)[3])malloc(sizeof(signed char) * 3 * triangleCount);
|
||||
if(!tTriNormals)
|
||||
ERROR("Not enough memory for triangle normals");
|
||||
}
|
||||
}
|
||||
|
||||
~Mesh()
|
||||
{
|
||||
delete (tvertices);
|
||||
}
|
||||
|
||||
static Color basicTriangleShader(int trinangleNo, short *v0, short *v1, short *v2, const signed char *normal, Color color)
|
||||
{
|
||||
return color;
|
||||
}
|
||||
|
||||
static Color basicTriangleShaderNormals(int trinangleNo, short *v0, short *v1, short *v2, const signed char *normal, Color color)
|
||||
{
|
||||
const float scaleN = 1.0f / 127.0f;
|
||||
const float nx = normal[0] * scaleN;
|
||||
const float ny = normal[1] * scaleN;
|
||||
const float nz = normal[2] * scaleN;
|
||||
|
||||
const float L[3] = {0, 0, -1};
|
||||
|
||||
float NdotL = nx * L[0] + ny * L[1] + nz * L[2];
|
||||
if(NdotL < 0) NdotL = 0;
|
||||
return int(NdotL * (color & 0x1f)) | (int(NdotL * ((color >> 5) & 0x1f)) << 5) | (int(NdotL * ((color >> 10) & 0xf)) << 10);
|
||||
}
|
||||
|
||||
void drawTriangles(Engine3D<Graphics> &e, Color color = -1, triangleShader ts = 0)
|
||||
{
|
||||
if(ts == 0)
|
||||
{
|
||||
if(tTriNormals)
|
||||
ts = basicTriangleShaderNormals;
|
||||
else
|
||||
ts = basicTriangleShader;
|
||||
}
|
||||
|
||||
for (int i = 0; i < triangleCount; i++)
|
||||
{
|
||||
short *v0 = tvertices[triangles[i][0]];
|
||||
short *v1 = tvertices[triangles[i][1]];
|
||||
short *v2 = tvertices[triangles[i][2]];
|
||||
int dx1 = v1[0] - v0[0];
|
||||
int dy1 = v1[1] - v0[1];
|
||||
int dx2 = v2[0] - v0[0];
|
||||
int dy2 = v2[1] - v0[1];
|
||||
if (dx1 * dy2 - dx2 * dy1 < 0)
|
||||
{
|
||||
Color c = ts(i, v0, v1, v2, tTriNormals ? tTriNormals[i] : 0, color);
|
||||
e.enqueueTriangle(tvertices[triangles[i][0]], tvertices[triangles[i][1]], tvertices[triangles[i][2]], c);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void drawEdges(Graphics &g, Color color)
|
||||
{
|
||||
for (int i = 0; i < edgeCount; i++)
|
||||
{
|
||||
g.line(tvertices[edges[i][0]][0], tvertices[edges[i][0]][1], tvertices[edges[i][1]][0], tvertices[edges[i][1]][1], color);
|
||||
}
|
||||
}
|
||||
|
||||
void drawVertices(Graphics &g, Color color)
|
||||
{
|
||||
for (int i = 0; i < vertexCount; i++)
|
||||
g.dot(tvertices[i][0], tvertices[i][1], color);
|
||||
}
|
||||
|
||||
void transform(Matrix m, Matrix normTrans = Matrix())
|
||||
{
|
||||
for (int i = 0; i < vertexCount; i++)
|
||||
{
|
||||
Vector v = m * Vector(vertices[i][0], vertices[i][1], vertices[i][2]);
|
||||
tvertices[i][0] = v[0] / v[3];
|
||||
tvertices[i][1] = v[1] / v[3];
|
||||
tvertices[i][2] = v[2];
|
||||
}
|
||||
if (triangleNormals)
|
||||
for (int i = 0; i < triangleCount; i++)
|
||||
{
|
||||
Vector v = normTrans * Vector(triangleNormals[i][0], triangleNormals[i][1], triangleNormals[i][2]);
|
||||
tTriNormals[i][0] = v[0] * 127;
|
||||
tTriNormals[i][1] = v[1] * 127;
|
||||
tTriNormals[i][2] = v[2] * 127;
|
||||
}
|
||||
}
|
||||
};
|
108
libraries/bitluni_ESP32Lib/src/Graphics/Sprites.h
Normal file
108
libraries/bitluni_ESP32Lib/src/Graphics/Sprites.h
Normal file
|
@ -0,0 +1,108 @@
|
|||
/*
|
||||
Author: bitluni 2019
|
||||
License:
|
||||
Creative Commons Attribution ShareAlike 4.0
|
||||
https://creativecommons.org/licenses/by-sa/4.0/
|
||||
|
||||
For further details check out:
|
||||
https://youtube.com/bitlunislab
|
||||
https://github.com/bitluni
|
||||
http://bitluni.net
|
||||
*/
|
||||
#pragma once
|
||||
#include "ImageDrawer.h"
|
||||
#include "Image.h"
|
||||
|
||||
class Sprite : public Image
|
||||
{
|
||||
public:
|
||||
typedef Image::PixelFormat PixelFormat;
|
||||
unsigned char pointCount;
|
||||
const signed short (*points)[2];
|
||||
|
||||
void init(int xres, int yres, const void *pixels, unsigned char pointCount, const signed short points[][2], PixelFormat pixelFormat)
|
||||
{
|
||||
static const signed short zeroPoint[][2] = {0, 0};
|
||||
Image::init(xres, yres, pixels, pixelFormat);
|
||||
if (pointCount)
|
||||
{
|
||||
this->pointCount = pointCount;
|
||||
this->points = points;
|
||||
}
|
||||
else
|
||||
{
|
||||
this->pointCount = 1;
|
||||
this->points = zeroPoint;
|
||||
}
|
||||
}
|
||||
void draw(ImageDrawer &g, int x, int y)
|
||||
{
|
||||
g.image(*this, x - points[0][0], y - points[0][1]);
|
||||
}
|
||||
|
||||
void drawMix(ImageDrawer &g, int x, int y)
|
||||
{
|
||||
g.imageMix(*this, x - points[0][0], y - points[0][1]);
|
||||
}
|
||||
|
||||
void drawAdd(ImageDrawer &g, int x, int y)
|
||||
{
|
||||
g.imageAdd(*this, x - points[0][0], y - points[0][1]);
|
||||
}
|
||||
};
|
||||
|
||||
class Sprites
|
||||
{
|
||||
public:
|
||||
typedef Image::PixelFormat PixelFormat;
|
||||
int count;
|
||||
Sprite *sprites;
|
||||
|
||||
Sprites(int count, const void* pixels, const int offsets[], const unsigned short resolutions[][2], const signed short points[][2], const short pointOffsets[], PixelFormat pixelFormat)
|
||||
{
|
||||
this->count = count;
|
||||
this->sprites = new Sprite[count];
|
||||
for (int i = 0; i < count; i++)
|
||||
this->sprites[i].init(resolutions[i][0], resolutions[i][1], (unsigned char*)pixels + offsets[i], pointOffsets[i + 1] - pointOffsets[i], &points[pointOffsets[i]], pixelFormat);
|
||||
}
|
||||
|
||||
void draw(ImageDrawer &g, int sprite, int x, int y)
|
||||
{
|
||||
sprites[sprite].draw(g, x, y);
|
||||
}
|
||||
|
||||
void drawMix(ImageDrawer &g, int sprite, int x, int y)
|
||||
{
|
||||
sprites[sprite].drawMix(g, x, y);
|
||||
}
|
||||
|
||||
void drawAdd(ImageDrawer &g, int sprite, int x, int y)
|
||||
{
|
||||
sprites[sprite].drawAdd(g, x, y);
|
||||
}
|
||||
|
||||
int xres(int sprite) const
|
||||
{
|
||||
return sprites[sprite].xres;
|
||||
}
|
||||
|
||||
int yres(int sprite) const
|
||||
{
|
||||
return sprites[sprite].yres;
|
||||
}
|
||||
|
||||
const short (*points(int sprite) const)[2]
|
||||
{
|
||||
return sprites[sprite].points;
|
||||
}
|
||||
|
||||
const short *point(int sprite, int point) const
|
||||
{
|
||||
return sprites[sprite].points[point];
|
||||
}
|
||||
|
||||
/*unsigned short get(int sprite, int x, int y) const
|
||||
{
|
||||
return sprites[sprite].get(x, y);
|
||||
}*/
|
||||
};
|
126
libraries/bitluni_ESP32Lib/src/Graphics/TriangleTree.h
Normal file
126
libraries/bitluni_ESP32Lib/src/Graphics/TriangleTree.h
Normal file
|
@ -0,0 +1,126 @@
|
|||
/*
|
||||
Author: bitluni 2019
|
||||
License:
|
||||
Creative Commons Attribution ShareAlike 4.0
|
||||
https://creativecommons.org/licenses/by-sa/4.0/
|
||||
|
||||
For further details check out:
|
||||
https://youtube.com/bitlunislab
|
||||
https://github.com/bitluni
|
||||
http://bitluni.net
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
class TriangleTree
|
||||
{
|
||||
public:
|
||||
short *v[3];
|
||||
int z;
|
||||
TriangleTree *left, *right;
|
||||
int depth;
|
||||
long color;
|
||||
|
||||
void set(short *v0, short *v1, short *v2, long color)
|
||||
{
|
||||
v[0] = v0;
|
||||
v[1] = v1;
|
||||
v[2] = v2;
|
||||
z = v[0][2] + v[1][2] + v[2][2];
|
||||
this->color = color;
|
||||
left = right = 0;
|
||||
depth = 1;
|
||||
}
|
||||
|
||||
int leftDepth() const
|
||||
{
|
||||
return left ? left->depth : 0;
|
||||
}
|
||||
|
||||
int rightDepth() const
|
||||
{
|
||||
return right ? right->depth : 0;
|
||||
}
|
||||
|
||||
void recalcDepth()
|
||||
{
|
||||
int l = leftDepth();
|
||||
int r = rightDepth();
|
||||
depth = l > r ? l : r;
|
||||
}
|
||||
|
||||
int add(TriangleTree **origin, TriangleTree &t)
|
||||
{
|
||||
int d = 1;
|
||||
if (t.z < z)
|
||||
{
|
||||
if (left)
|
||||
d = left->add(&left, t);
|
||||
else
|
||||
left = &t;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (right)
|
||||
d = right->add(&right, t);
|
||||
else
|
||||
right = &t;
|
||||
}
|
||||
if (depth < d + 1)
|
||||
depth = d + 1;
|
||||
int l = leftDepth();
|
||||
int r = rightDepth();
|
||||
if (l > r + 1)
|
||||
{
|
||||
int ll = left->leftDepth();
|
||||
int lr = left->rightDepth();
|
||||
if (ll < lr)
|
||||
{
|
||||
TriangleTree *tl = left;
|
||||
left = tl->right;
|
||||
tl->right = left->left;
|
||||
left->left = tl;
|
||||
left->left->recalcDepth();
|
||||
left->recalcDepth();
|
||||
ll = left->leftDepth();
|
||||
lr = left->rightDepth();
|
||||
l = leftDepth();
|
||||
recalcDepth();
|
||||
}
|
||||
{
|
||||
*origin = left;
|
||||
left = left->right;
|
||||
(*origin)->right = this;
|
||||
depth = lr > r ? lr + 1 : r + 1;
|
||||
(*origin)->depth = ll > depth ? ll + 1 : depth + 1;
|
||||
return (*origin)->depth + 1;
|
||||
}
|
||||
}
|
||||
if (r > l + 1)
|
||||
{
|
||||
int rl = right->leftDepth();
|
||||
int rr = right->rightDepth();
|
||||
if (rr < rl)
|
||||
{
|
||||
TriangleTree *tr = right;
|
||||
right = tr->left;
|
||||
tr->left = right->right;
|
||||
right->right = tr;
|
||||
right->right->recalcDepth();
|
||||
right->recalcDepth();
|
||||
rr = right->rightDepth();
|
||||
rl = right->leftDepth();
|
||||
r = rightDepth();
|
||||
recalcDepth();
|
||||
}
|
||||
{
|
||||
*origin = right;
|
||||
right = right->left;
|
||||
(*origin)->left = this;
|
||||
depth = rl > l ? rl + 1 : l + 1;
|
||||
(*origin)->depth = rr > depth ? rr + 1 : depth + 1;
|
||||
return (*origin)->depth + 1;
|
||||
}
|
||||
}
|
||||
return depth;
|
||||
}
|
||||
};
|
110
libraries/bitluni_ESP32Lib/src/I2S/DMABufferDescriptor.h
Normal file
110
libraries/bitluni_ESP32Lib/src/I2S/DMABufferDescriptor.h
Normal file
|
@ -0,0 +1,110 @@
|
|||
/*
|
||||
Author: bitluni 2019
|
||||
License:
|
||||
Creative Commons Attribution ShareAlike 4.0
|
||||
https://creativecommons.org/licenses/by-sa/4.0/
|
||||
|
||||
For further details check out:
|
||||
https://youtube.com/bitlunislab
|
||||
https://github.com/bitluni
|
||||
http://bitluni.net
|
||||
*/
|
||||
#pragma once
|
||||
#include "../Tools/Log.h"
|
||||
|
||||
class DMABufferDescriptor : protected lldesc_t
|
||||
{
|
||||
public:
|
||||
static void *allocateBuffer(int bytes, bool clear = true, unsigned long clearValue = 0)
|
||||
{
|
||||
bytes = (bytes + 3) & 0xfffffffc;
|
||||
void *b = heap_caps_malloc(bytes, MALLOC_CAP_DMA);
|
||||
if (!b)
|
||||
DEBUG_PRINTLN("Failed to alloc dma buffer");
|
||||
if (clear)
|
||||
for (int i = 0; i < bytes / 4; i++)
|
||||
((unsigned long *)b)[i] = clearValue;
|
||||
return b;
|
||||
}
|
||||
|
||||
static void **allocateDMABufferArray(int count, int bytes, bool clear = true, unsigned long clearValue = 0)
|
||||
{
|
||||
void **arr = (void **)malloc(count * sizeof(void *));
|
||||
if(!arr)
|
||||
ERROR("Not enough DMA memory");
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
arr[i] = DMABufferDescriptor::allocateBuffer(bytes, true, clearValue);
|
||||
if(!arr[i])
|
||||
ERROR("Not enough DMA memory");
|
||||
}
|
||||
return arr;
|
||||
}
|
||||
|
||||
void setBuffer(void *buffer, int bytes)
|
||||
{
|
||||
length = bytes;
|
||||
size = length;
|
||||
buf = (uint8_t *)buffer;
|
||||
}
|
||||
|
||||
void *buffer() const
|
||||
{
|
||||
return (void *)buf;
|
||||
}
|
||||
|
||||
void init()
|
||||
{
|
||||
length = 0;
|
||||
size = 0;
|
||||
owner = 1;
|
||||
sosf = 0;
|
||||
buf = (uint8_t *)0;
|
||||
offset = 0;
|
||||
empty = 0;
|
||||
eof = 1;
|
||||
qe.stqe_next = 0;
|
||||
}
|
||||
|
||||
static DMABufferDescriptor *allocateDescriptors(int count)
|
||||
{
|
||||
DMABufferDescriptor *b = (DMABufferDescriptor *)heap_caps_malloc(sizeof(DMABufferDescriptor) * count, MALLOC_CAP_DMA);
|
||||
if (!b)
|
||||
DEBUG_PRINTLN("Failed to alloc DMABufferDescriptors");
|
||||
for (int i = 0; i < count; i++)
|
||||
b[i].init();
|
||||
return b;
|
||||
}
|
||||
|
||||
static DMABufferDescriptor *allocateDescriptor(int bytes, bool allocBuffer = true, bool clear = true, unsigned long clearValue = 0)
|
||||
{
|
||||
bytes = (bytes + 3) & 0xfffffffc;
|
||||
DMABufferDescriptor *b = (DMABufferDescriptor *)heap_caps_malloc(sizeof(DMABufferDescriptor), MALLOC_CAP_DMA);
|
||||
if (!b)
|
||||
DEBUG_PRINTLN("Failed to alloc DMABufferDescriptor");
|
||||
b->init();
|
||||
if (allocateBuffer)
|
||||
b->setBuffer(allocateBuffer(bytes, clear, clearValue), bytes);
|
||||
return b;
|
||||
}
|
||||
|
||||
void next(DMABufferDescriptor &next)
|
||||
{
|
||||
qe.stqe_next = &next;
|
||||
}
|
||||
|
||||
int sampleCount() const
|
||||
{
|
||||
return length / 4;
|
||||
}
|
||||
|
||||
void destroy()
|
||||
{
|
||||
if (buf)
|
||||
{
|
||||
free((void *)buf);
|
||||
buf = 0;
|
||||
}
|
||||
free(this);
|
||||
}
|
||||
};
|
360
libraries/bitluni_ESP32Lib/src/I2S/I2S.cpp
Normal file
360
libraries/bitluni_ESP32Lib/src/I2S/I2S.cpp
Normal file
|
@ -0,0 +1,360 @@
|
|||
/*
|
||||
Author: bitluni 2019
|
||||
License:
|
||||
Creative Commons Attribution ShareAlike 4.0
|
||||
https://creativecommons.org/licenses/by-sa/4.0/
|
||||
|
||||
For further details check out:
|
||||
https://youtube.com/bitlunislab
|
||||
https://github.com/bitluni
|
||||
http://bitluni.net
|
||||
*/
|
||||
#include "I2S.h"
|
||||
#include "../Tools/Log.h"
|
||||
#include <soc/rtc.h>
|
||||
|
||||
i2s_dev_t *i2sDevices[] = {&I2S0, &I2S1};
|
||||
|
||||
I2S::I2S(const int i2sIndex)
|
||||
{
|
||||
this->i2sIndex = i2sIndex;
|
||||
interruptHandle = 0;
|
||||
dmaBufferDescriptorCount = 0;
|
||||
dmaBufferDescriptorActive = 0;
|
||||
dmaBufferDescriptors = 0;
|
||||
stopSignal = false;
|
||||
}
|
||||
|
||||
void IRAM_ATTR I2S::interruptStatic(void *arg)
|
||||
{
|
||||
volatile i2s_dev_t &i2s = *i2sDevices[((I2S *)arg)->i2sIndex];
|
||||
i2s.int_clr.val = i2s.int_raw.val;
|
||||
((I2S *)arg)->interrupt();
|
||||
}
|
||||
|
||||
void I2S::reset()
|
||||
{
|
||||
volatile i2s_dev_t &i2s = *i2sDevices[i2sIndex];
|
||||
const unsigned long lc_conf_reset_flags = I2S_IN_RST_M | I2S_OUT_RST_M | I2S_AHBM_RST_M | I2S_AHBM_FIFO_RST_M;
|
||||
i2s.lc_conf.val |= lc_conf_reset_flags;
|
||||
i2s.lc_conf.val &= ~lc_conf_reset_flags;
|
||||
|
||||
const uint32_t conf_reset_flags = I2S_RX_RESET_M | I2S_RX_FIFO_RESET_M | I2S_TX_RESET_M | I2S_TX_FIFO_RESET_M;
|
||||
i2s.conf.val |= conf_reset_flags;
|
||||
i2s.conf.val &= ~conf_reset_flags;
|
||||
while (i2s.state.rx_fifo_reset_back)
|
||||
;
|
||||
}
|
||||
|
||||
void I2S::i2sStop()
|
||||
{
|
||||
volatile i2s_dev_t &i2s = *i2sDevices[i2sIndex];
|
||||
esp_intr_disable(interruptHandle);
|
||||
reset();
|
||||
i2s.conf.rx_start = 0;
|
||||
i2s.conf.tx_start = 0;
|
||||
}
|
||||
|
||||
void I2S::startTX()
|
||||
{
|
||||
volatile i2s_dev_t &i2s = *i2sDevices[i2sIndex];
|
||||
DEBUG_PRINTLN("I2S TX");
|
||||
esp_intr_disable(interruptHandle);
|
||||
reset();
|
||||
i2s.lc_conf.val = I2S_OUT_DATA_BURST_EN | I2S_OUTDSCR_BURST_EN;
|
||||
dmaBufferDescriptorActive = 0;
|
||||
i2s.out_link.addr = (uint32_t)firstDescriptorAddress();
|
||||
i2s.out_link.start = 1;
|
||||
i2s.int_clr.val = i2s.int_raw.val;
|
||||
i2s.int_ena.val = 0;
|
||||
if(useInterrupt())
|
||||
{
|
||||
i2s.int_ena.out_eof = 1;
|
||||
//enable interrupt
|
||||
esp_intr_enable(interruptHandle);
|
||||
}
|
||||
//start transmission
|
||||
i2s.conf.tx_start = 1;
|
||||
}
|
||||
|
||||
void I2S::startRX()
|
||||
{
|
||||
volatile i2s_dev_t &i2s = *i2sDevices[i2sIndex];
|
||||
DEBUG_PRINTLN("I2S RX");
|
||||
esp_intr_disable(interruptHandle);
|
||||
reset();
|
||||
dmaBufferDescriptorActive = 0;
|
||||
i2s.rx_eof_num = dmaBufferDescriptors[0].sampleCount(); //TODO: replace with cont of sample to be recorded
|
||||
i2s.in_link.addr = (uint32_t)firstDescriptorAddress();
|
||||
i2s.in_link.start = 1;
|
||||
i2s.int_clr.val = i2s.int_raw.val;
|
||||
i2s.int_ena.val = 0;
|
||||
i2s.int_ena.in_done = 1;
|
||||
esp_intr_enable(interruptHandle);
|
||||
i2s.conf.rx_start = 1;
|
||||
}
|
||||
|
||||
void I2S::resetDMA()
|
||||
{
|
||||
volatile i2s_dev_t &i2s = *i2sDevices[i2sIndex];
|
||||
i2s.lc_conf.in_rst = 1;
|
||||
i2s.lc_conf.in_rst = 0;
|
||||
i2s.lc_conf.out_rst = 1;
|
||||
i2s.lc_conf.out_rst = 0;
|
||||
}
|
||||
|
||||
void I2S::resetFIFO()
|
||||
{
|
||||
volatile i2s_dev_t &i2s = *i2sDevices[i2sIndex];
|
||||
i2s.conf.rx_fifo_reset = 1;
|
||||
i2s.conf.rx_fifo_reset = 0;
|
||||
i2s.conf.tx_fifo_reset = 1;
|
||||
i2s.conf.tx_fifo_reset = 0;
|
||||
}
|
||||
|
||||
DMABufferDescriptor *I2S::firstDescriptorAddress() const
|
||||
{
|
||||
return &dmaBufferDescriptors[0];
|
||||
}
|
||||
|
||||
bool I2S::useInterrupt()
|
||||
{
|
||||
return false;
|
||||
};
|
||||
|
||||
bool I2S::initParallelInputMode(const int *pinMap, long sampleRate, const int bitCount, int wordSelect, int baseClock)
|
||||
{
|
||||
volatile i2s_dev_t &i2s = *i2sDevices[i2sIndex];
|
||||
//route peripherals
|
||||
const int deviceBaseIndex[] = {I2S0I_DATA_IN0_IDX, I2S1I_DATA_IN0_IDX};
|
||||
const int deviceClockIndex[] = {I2S0I_BCK_IN_IDX, I2S1I_BCK_IN_IDX};
|
||||
const int deviceWordSelectIndex[] = {I2S0I_WS_IN_IDX, I2S1I_WS_IN_IDX};
|
||||
const periph_module_t deviceModule[] = {PERIPH_I2S0_MODULE, PERIPH_I2S1_MODULE};
|
||||
//works only since indices of the pads are sequential
|
||||
for (int i = 0; i < bitCount; i++)
|
||||
if (pinMap[i] > -1)
|
||||
{
|
||||
PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[pinMap[i]], PIN_FUNC_GPIO);
|
||||
gpio_set_direction((gpio_num_t)pinMap[i], (gpio_mode_t)GPIO_MODE_DEF_INPUT);
|
||||
gpio_matrix_in(pinMap[i], deviceBaseIndex[i2sIndex] + i, false);
|
||||
}
|
||||
if (baseClock > -1)
|
||||
gpio_matrix_in(baseClock, deviceClockIndex[i2sIndex], false);
|
||||
if (wordSelect > -1)
|
||||
gpio_matrix_in(wordSelect, deviceWordSelectIndex[i2sIndex], false);
|
||||
|
||||
//enable I2S peripheral
|
||||
periph_module_enable(deviceModule[i2sIndex]);
|
||||
|
||||
//reset i2s
|
||||
i2s.conf.rx_reset = 1;
|
||||
i2s.conf.rx_reset = 0;
|
||||
i2s.conf.tx_reset = 1;
|
||||
i2s.conf.tx_reset = 0;
|
||||
|
||||
resetFIFO();
|
||||
resetDMA();
|
||||
|
||||
//parallel mode
|
||||
i2s.conf2.val = 0;
|
||||
i2s.conf2.lcd_en = 1;
|
||||
//from technical datasheet figure 64
|
||||
//i2s.conf2.lcd_tx_sdx2_en = 1;
|
||||
//i2s.conf2.lcd_tx_wrx2_en = 1;
|
||||
|
||||
i2s.sample_rate_conf.val = 0;
|
||||
i2s.sample_rate_conf.rx_bits_mod = 16;
|
||||
|
||||
//maximum rate
|
||||
i2s.clkm_conf.val = 0;
|
||||
i2s.clkm_conf.clka_en = 0;
|
||||
i2s.clkm_conf.clkm_div_num = 6; //3//80000000L / sampleRate;
|
||||
i2s.clkm_conf.clkm_div_a = 6; // 0;
|
||||
i2s.clkm_conf.clkm_div_b = 1; // 0;
|
||||
i2s.sample_rate_conf.rx_bck_div_num = 2;
|
||||
|
||||
i2s.fifo_conf.val = 0;
|
||||
i2s.fifo_conf.rx_fifo_mod_force_en = 1;
|
||||
i2s.fifo_conf.rx_fifo_mod = 1; //byte packing 0A0B_0B0C = 0, 0A0B_0C0D = 1, 0A00_0B00 = 3,
|
||||
i2s.fifo_conf.rx_data_num = 32;
|
||||
i2s.fifo_conf.dscr_en = 1; //fifo will use dma
|
||||
|
||||
i2s.conf1.val = 0;
|
||||
i2s.conf1.tx_stop_en = 1;
|
||||
i2s.conf1.tx_pcm_bypass = 1;
|
||||
|
||||
i2s.conf_chan.val = 0;
|
||||
i2s.conf_chan.rx_chan_mod = 0;
|
||||
|
||||
//high or low (stereo word order)
|
||||
i2s.conf.rx_right_first = 1;
|
||||
|
||||
i2s.timing.val = 0;
|
||||
|
||||
//clear serial mode flags
|
||||
i2s.conf.rx_msb_right = 0;
|
||||
i2s.conf.rx_msb_shift = 0;
|
||||
i2s.conf.rx_mono = 0;
|
||||
i2s.conf.rx_short_sync = 0;
|
||||
|
||||
//allocate disabled i2s interrupt
|
||||
const int interruptSource[] = {ETS_I2S0_INTR_SOURCE, ETS_I2S1_INTR_SOURCE};
|
||||
if(useInterrupt())
|
||||
esp_intr_alloc(interruptSource[i2sIndex], ESP_INTR_FLAG_INTRDISABLED | ESP_INTR_FLAG_LEVEL3 | ESP_INTR_FLAG_IRAM, &interruptStatic, this, &interruptHandle);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool I2S::initParallelOutputMode(const int *pinMap, long sampleRate, const int bitCount, int wordSelect, int baseClock)
|
||||
{
|
||||
volatile i2s_dev_t &i2s = *i2sDevices[i2sIndex];
|
||||
//route peripherals
|
||||
//in parallel mode only upper 16 bits are interesting in this case
|
||||
const int deviceBaseIndex[] = {I2S0O_DATA_OUT0_IDX, I2S1O_DATA_OUT0_IDX};
|
||||
const int deviceClockIndex[] = {I2S0O_BCK_OUT_IDX, I2S1O_BCK_OUT_IDX};
|
||||
const int deviceWordSelectIndex[] = {I2S0O_WS_OUT_IDX, I2S1O_WS_OUT_IDX};
|
||||
const periph_module_t deviceModule[] = {PERIPH_I2S0_MODULE, PERIPH_I2S1_MODULE};
|
||||
//works only since indices of the pads are sequential
|
||||
for (int i = 0; i < bitCount; i++)
|
||||
if (pinMap[i] > -1)
|
||||
{
|
||||
PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[pinMap[i]], PIN_FUNC_GPIO);
|
||||
gpio_set_direction((gpio_num_t)pinMap[i], (gpio_mode_t)GPIO_MODE_DEF_OUTPUT);
|
||||
if(i2sIndex == 1)
|
||||
{
|
||||
if(bitCount == 16)
|
||||
gpio_matrix_out(pinMap[i], deviceBaseIndex[i2sIndex] + i + 8, false, false);
|
||||
else
|
||||
gpio_matrix_out(pinMap[i], deviceBaseIndex[i2sIndex] + i, false, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
//there is something odd going on here in the two different I2S
|
||||
//the configuration seems to differ. Use i2s1 for high frequencies.
|
||||
gpio_matrix_out(pinMap[i], deviceBaseIndex[i2sIndex] + i + 24 - bitCount, false, false);
|
||||
}
|
||||
}
|
||||
if (baseClock > -1)
|
||||
gpio_matrix_out(baseClock, deviceClockIndex[i2sIndex], false, false);
|
||||
if (wordSelect > -1)
|
||||
gpio_matrix_out(wordSelect, deviceWordSelectIndex[i2sIndex], false, false);
|
||||
|
||||
//enable I2S peripheral
|
||||
periph_module_enable(deviceModule[i2sIndex]);
|
||||
|
||||
//reset i2s
|
||||
i2s.conf.tx_reset = 1;
|
||||
i2s.conf.tx_reset = 0;
|
||||
i2s.conf.rx_reset = 1;
|
||||
i2s.conf.rx_reset = 0;
|
||||
|
||||
resetFIFO();
|
||||
resetDMA();
|
||||
|
||||
//parallel mode
|
||||
i2s.conf2.val = 0;
|
||||
i2s.conf2.lcd_en = 1;
|
||||
//from technical datasheet figure 64
|
||||
i2s.conf2.lcd_tx_wrx2_en = 1;
|
||||
i2s.conf2.lcd_tx_sdx2_en = 0;
|
||||
|
||||
i2s.sample_rate_conf.val = 0;
|
||||
i2s.sample_rate_conf.tx_bits_mod = bitCount;
|
||||
//clock setup
|
||||
//xtal is 40M
|
||||
//chip revision 0
|
||||
//fxtal * (sdm2 + 4) / (2 * (odir + 2))
|
||||
//chip revision 1
|
||||
//fxtal * (sdm2 + (sdm1 / 256) + (sdm0 / 65536) + 4) / (2 * (odir + 2))
|
||||
//fxtal * (sdm2 + (sdm1 / 256) + (sdm0 / 65536) + 4) needs to be btween 350M and 500M
|
||||
//rtc_clk_apll_enable(enable, sdm0, sdm1, sdm2, odir);
|
||||
// 0-255 0-255 0-63 0-31
|
||||
//sdm seems to be simply a fixpoint number with 16bits fractional part
|
||||
//freq = 40000000L * (4 + sdm) / (2 * (odir + 2))
|
||||
//sdm = freq / (20000000L / (odir + 2)) - 4;
|
||||
|
||||
long freq = sampleRate * 2 * (bitCount / 8);
|
||||
int sdm, sdmn;
|
||||
int odir = -1;
|
||||
do
|
||||
{
|
||||
odir++;
|
||||
sdm = long((double(freq) / (20000000. / (odir + 2))) * 0x10000) - 0x40000;
|
||||
sdmn = long((double(freq) / (20000000. / (odir + 2 + 1))) * 0x10000) - 0x40000;
|
||||
}while(sdm < 0x8c0ecL && odir < 31 && sdmn < 0xA1fff); //0xA7fffL doesn't work on all mcus
|
||||
//DEBUG_PRINTLN(sdm & 255);
|
||||
//DEBUG_PRINTLN((sdm >> 8) & 255);
|
||||
//DEBUG_PRINTLN(sdm >> 16);
|
||||
//DEBUG_PRINTLN(odir);
|
||||
//sdm = 0xA1fff;
|
||||
//odir = 0;
|
||||
if(sdm > 0xA1fff) sdm = 0xA1fff;
|
||||
rtc_clk_apll_enable(true, sdm & 255, (sdm >> 8) & 255, sdm >> 16, odir);
|
||||
i2s.clkm_conf.val = 0;
|
||||
i2s.clkm_conf.clka_en = 1;
|
||||
i2s.clkm_conf.clkm_div_num = 2; //clockN;
|
||||
i2s.clkm_conf.clkm_div_a = 1; //clockA;
|
||||
i2s.clkm_conf.clkm_div_b = 0; //clockB;
|
||||
i2s.sample_rate_conf.tx_bck_div_num = 1;
|
||||
|
||||
i2s.fifo_conf.val = 0;
|
||||
i2s.fifo_conf.tx_fifo_mod_force_en = 1;
|
||||
i2s.fifo_conf.tx_fifo_mod = 1; //byte packing 0A0B_0B0C = 0, 0A0B_0C0D = 1, 0A00_0B00 = 3,
|
||||
i2s.fifo_conf.tx_data_num = 32; //fifo length
|
||||
i2s.fifo_conf.dscr_en = 1; //fifo will use dma
|
||||
|
||||
i2s.conf1.val = 0;
|
||||
i2s.conf1.tx_stop_en = 0;
|
||||
i2s.conf1.tx_pcm_bypass = 1;
|
||||
|
||||
i2s.conf_chan.val = 0;
|
||||
i2s.conf_chan.tx_chan_mod = 1;
|
||||
|
||||
//high or low (stereo word order)
|
||||
i2s.conf.tx_right_first = 1;
|
||||
|
||||
i2s.timing.val = 0;
|
||||
|
||||
//clear serial mode flags
|
||||
i2s.conf.tx_msb_right = 0;
|
||||
i2s.conf.tx_msb_shift = 0;
|
||||
i2s.conf.tx_mono = 0;
|
||||
i2s.conf.tx_short_sync = 0;
|
||||
|
||||
//allocate disabled i2s interrupt
|
||||
const int interruptSource[] = {ETS_I2S0_INTR_SOURCE, ETS_I2S1_INTR_SOURCE};
|
||||
if(useInterrupt())
|
||||
esp_intr_alloc(interruptSource[i2sIndex], ESP_INTR_FLAG_INTRDISABLED | ESP_INTR_FLAG_LEVEL3 | ESP_INTR_FLAG_IRAM, &interruptStatic, this, &interruptHandle);
|
||||
return true;
|
||||
}
|
||||
|
||||
/// simple ringbuffer of blocks of size bytes each
|
||||
void I2S::allocateDMABuffers(int count, int bytes)
|
||||
{
|
||||
dmaBufferDescriptorCount = count;
|
||||
dmaBufferDescriptors = DMABufferDescriptor::allocateDescriptors(count);
|
||||
for (int i = 0; i < dmaBufferDescriptorCount; i++)
|
||||
{
|
||||
dmaBufferDescriptors[i].setBuffer(DMABufferDescriptor::allocateBuffer(bytes, true), bytes);
|
||||
if (i)
|
||||
dmaBufferDescriptors[i - 1].next(dmaBufferDescriptors[i]);
|
||||
}
|
||||
dmaBufferDescriptors[dmaBufferDescriptorCount - 1].next(dmaBufferDescriptors[0]);
|
||||
}
|
||||
|
||||
void I2S::deleteDMABuffers()
|
||||
{
|
||||
if (!dmaBufferDescriptors)
|
||||
return;
|
||||
for (int i = 0; i < dmaBufferDescriptorCount; i++)
|
||||
free(dmaBufferDescriptors[i].buffer());
|
||||
free(dmaBufferDescriptors);
|
||||
dmaBufferDescriptors = 0;
|
||||
dmaBufferDescriptorCount = 0;
|
||||
}
|
||||
|
||||
void I2S::stop()
|
||||
{
|
||||
stopSignal = true;
|
||||
while (stopSignal)
|
||||
;
|
||||
}
|
60
libraries/bitluni_ESP32Lib/src/I2S/I2S.h
Normal file
60
libraries/bitluni_ESP32Lib/src/I2S/I2S.h
Normal file
|
@ -0,0 +1,60 @@
|
|||
/*
|
||||
Author: bitluni 2019
|
||||
License:
|
||||
Creative Commons Attribution ShareAlike 4.0
|
||||
https://creativecommons.org/licenses/by-sa/4.0/
|
||||
|
||||
For further details check out:
|
||||
https://youtube.com/bitlunislab
|
||||
https://github.com/bitluni
|
||||
http://bitluni.net
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "esp_heap_caps.h"
|
||||
#include "soc/soc.h"
|
||||
#include "soc/gpio_sig_map.h"
|
||||
#include "soc/i2s_reg.h"
|
||||
#include "soc/i2s_struct.h"
|
||||
#include "soc/io_mux_reg.h"
|
||||
#include "driver/gpio.h"
|
||||
#include "driver/periph_ctrl.h"
|
||||
#include "rom/lldesc.h"
|
||||
#include "DMABufferDescriptor.h"
|
||||
|
||||
class I2S
|
||||
{
|
||||
public:
|
||||
int i2sIndex;
|
||||
intr_handle_t interruptHandle;
|
||||
int dmaBufferDescriptorCount;
|
||||
int dmaBufferDescriptorActive;
|
||||
DMABufferDescriptor *dmaBufferDescriptors;
|
||||
volatile bool stopSignal;
|
||||
|
||||
/// hardware index [0, 1]
|
||||
I2S(const int i2sIndex = 0);
|
||||
void reset();
|
||||
|
||||
void stop();
|
||||
|
||||
void i2sStop();
|
||||
void startTX();
|
||||
void startRX();
|
||||
|
||||
void resetDMA();
|
||||
void resetFIFO();
|
||||
bool initParallelOutputMode(const int *pinMap, long APLLFreq = 1000000, const int bitCount = 8, int wordSelect = -1, int baseClock = -1);
|
||||
bool initParallelInputMode(const int *pinMap, long sampleRate = 1000000, const int bitCount = 8, int wordSelect = -1, int baseClock = -1);
|
||||
virtual DMABufferDescriptor *firstDescriptorAddress() const;
|
||||
|
||||
void allocateDMABuffers(int count, int bytes);
|
||||
void deleteDMABuffers();
|
||||
|
||||
protected:
|
||||
virtual void interrupt() = 0;
|
||||
virtual bool useInterrupt();
|
||||
|
||||
private:
|
||||
static void IRAM_ATTR interruptStatic(void *arg);
|
||||
};
|
199
libraries/bitluni_ESP32Lib/src/Math/Matrix.h
Normal file
199
libraries/bitluni_ESP32Lib/src/Math/Matrix.h
Normal file
|
@ -0,0 +1,199 @@
|
|||
/*
|
||||
Author: bitluni 2019
|
||||
License:
|
||||
Creative Commons Attribution ShareAlike 4.0
|
||||
https://creativecommons.org/licenses/by-sa/4.0/
|
||||
|
||||
For further details check out:
|
||||
https://youtube.com/bitlunislab
|
||||
https://github.com/bitluni
|
||||
http://bitluni.net
|
||||
*/
|
||||
#pragma once
|
||||
#include <math.h>
|
||||
|
||||
class Vector
|
||||
{
|
||||
public:
|
||||
float v[4];
|
||||
|
||||
Vector(float x = 0, float y = 0, float z = 0, float w = 1)
|
||||
{
|
||||
v[0] = x;
|
||||
v[1] = y;
|
||||
v[2] = z;
|
||||
v[3] = w;
|
||||
}
|
||||
|
||||
Vector operator*(float s) const
|
||||
{
|
||||
return Vector(v[0] * s, v[1] * s, v[2] * s, 1);
|
||||
}
|
||||
|
||||
Vector &operator*=(float s)
|
||||
{
|
||||
*this = *this * s;
|
||||
return *this;
|
||||
}
|
||||
|
||||
float operator[](int i) const
|
||||
{
|
||||
return v[i];
|
||||
}
|
||||
|
||||
Vector operator+(const Vector &v2) const
|
||||
{
|
||||
return Vector(v[0] + v2.v[0], v[1] + v2.v[1], v[2] + v2.v[2], 1);
|
||||
}
|
||||
|
||||
Vector operator-(const Vector &v2) const
|
||||
{
|
||||
return Vector(v[0] - v2.v[0], v[1] - v2.v[1], v[2] - v2.v[2], 1);
|
||||
}
|
||||
|
||||
Vector operator-() const
|
||||
{
|
||||
return Vector(-v[0], -v[1], -v[2], 1);
|
||||
}
|
||||
|
||||
void normalize()
|
||||
{
|
||||
float l2 = v[0] * v[0] + v[1] * v[1] + v[2] * v[2];
|
||||
if (!l2)
|
||||
return;
|
||||
//float rl = 1 / sqrt(l2);
|
||||
*this *= rsqrt(l2);//rl;
|
||||
}
|
||||
|
||||
float length() const
|
||||
{
|
||||
float l2 = v[0] * v[0] + v[1] * v[1] + v[2] * v[2];
|
||||
if (!l2) return 0.f;
|
||||
return sqrt(l2);
|
||||
}
|
||||
|
||||
float dot(const Vector &v2) const
|
||||
{
|
||||
return v[0] * v2.v[0] + v[1] * v2.v[1] + v[2] * v2.v[2];
|
||||
}
|
||||
|
||||
static float rsqrt(float x)
|
||||
{
|
||||
const float x2 = x * 0.5F;
|
||||
const float threehalfs = 1.5F;
|
||||
|
||||
union {
|
||||
float f;
|
||||
uint32_t i;
|
||||
} conv = {x};
|
||||
conv.i = 0x5f3759df - ( conv.i >> 1 );
|
||||
conv.f *= ( threehalfs - ( x2 * conv.f * conv.f ) );
|
||||
conv.f *= ( threehalfs - ( x2 * conv.f * conv.f ) );
|
||||
return conv.f;
|
||||
}
|
||||
|
||||
static float sqrt(float x)
|
||||
{
|
||||
return x * rsqrt(x);
|
||||
}
|
||||
};
|
||||
|
||||
class Matrix
|
||||
{
|
||||
public:
|
||||
float m[4][4];
|
||||
|
||||
Matrix()
|
||||
: Matrix(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1)
|
||||
{
|
||||
}
|
||||
|
||||
Matrix(float m00, float m01, float m02, float m03,
|
||||
float m10, float m11, float m12, float m13,
|
||||
float m20, float m21, float m22, float m23,
|
||||
float m30, float m31, float m32, float m33)
|
||||
{
|
||||
m[0][0] = m00;
|
||||
m[0][1] = m01;
|
||||
m[0][2] = m02;
|
||||
m[0][3] = m03;
|
||||
m[1][0] = m10;
|
||||
m[1][1] = m11;
|
||||
m[1][2] = m12;
|
||||
m[1][3] = m13;
|
||||
m[2][0] = m20;
|
||||
m[2][1] = m21;
|
||||
m[2][2] = m22;
|
||||
m[2][3] = m23;
|
||||
m[3][0] = m30;
|
||||
m[3][1] = m31;
|
||||
m[3][2] = m32;
|
||||
m[3][3] = m33;
|
||||
}
|
||||
|
||||
static Matrix identity()
|
||||
{
|
||||
return Matrix(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
|
||||
}
|
||||
|
||||
static Matrix scaling(float s)
|
||||
{
|
||||
return Matrix(s, 0, 0, 0, 0, s, 0, 0, 0, 0, s, 0, 0, 0, 0, 1);
|
||||
}
|
||||
|
||||
static Matrix scaling(float u, float v, float w)
|
||||
{
|
||||
return Matrix(u, 0, 0, 0, 0, v, 0, 0, 0, 0, w, 0, 0, 0, 0, 1);
|
||||
}
|
||||
|
||||
static Matrix translation(float x, float y, float z)
|
||||
{
|
||||
return Matrix(1, 0, 0, x, 0, 1, 0, y, 0, 0, 1, z, 0, 0, 0, 1);
|
||||
}
|
||||
|
||||
static Matrix rotation(float a, float x, float y, float z)
|
||||
{
|
||||
float cosa = cos(a);
|
||||
float rcosa = 1 - cosa;
|
||||
float sina = sin(a);
|
||||
return Matrix(
|
||||
x * x * rcosa + cosa, x * y * rcosa - z * sina, x * z * rcosa + y * sina, 0,
|
||||
y * x * rcosa + z * sina, y * y * rcosa + cosa, y * z * rcosa - x * sina, 0,
|
||||
z * x * rcosa - y * sina, z * y * rcosa + x * sina, z * z * rcosa + cosa, 0,
|
||||
0, 0, 0, 1);
|
||||
}
|
||||
|
||||
static Matrix perspective(float fov, float near, float far)
|
||||
{
|
||||
float scale = tan(fov * 0.5 * M_PI / 180);
|
||||
return Matrix(
|
||||
scale, 0, 0, 0,
|
||||
0, scale, 0, 0,
|
||||
0, 0, -far * near / (far - near), 0,
|
||||
0, 0, -1, 0);
|
||||
}
|
||||
|
||||
Vector operator*(const Vector &v)
|
||||
{
|
||||
return Vector(
|
||||
v.v[0] * m[0][0] + v.v[1] * m[0][1] + v.v[2] * m[0][2] + m[0][3],
|
||||
v.v[0] * m[1][0] + v.v[1] * m[1][1] + v.v[2] * m[1][2] + m[1][3],
|
||||
v.v[0] * m[2][0] + v.v[1] * m[2][1] + v.v[2] * m[2][2] + m[2][3],
|
||||
v.v[0] * m[3][0] + v.v[1] * m[3][1] + v.v[2] * m[3][2] + m[3][3]);
|
||||
}
|
||||
|
||||
Matrix operator*(const Matrix &m2)
|
||||
{
|
||||
Matrix mr;
|
||||
for (int y = 0; y < 4; y++)
|
||||
for (int x = 0; x < 4; x++)
|
||||
mr.m[y][x] = m[y][0] * m2.m[0][x] + m[y][1] * m2.m[1][x] + m[y][2] * m2.m[2][x] + m[y][3] * m2.m[3][x];
|
||||
return mr;
|
||||
}
|
||||
|
||||
Matrix &operator*=(const Matrix &m2)
|
||||
{
|
||||
*this = *this * m2;
|
||||
return *this;
|
||||
}
|
||||
};
|
179
libraries/bitluni_ESP32Lib/src/Math/MatrixFast.h
Normal file
179
libraries/bitluni_ESP32Lib/src/Math/MatrixFast.h
Normal file
|
@ -0,0 +1,179 @@
|
|||
/*
|
||||
Author: bitluni 2019
|
||||
License:
|
||||
Creative Commons Attribution ShareAlike 4.0
|
||||
https://creativecommons.org/licenses/by-sa/4.0/
|
||||
|
||||
For further details check out:
|
||||
https://youtube.com/bitlunislab
|
||||
https://github.com/bitluni
|
||||
http://bitluni.net
|
||||
*/
|
||||
#pragma once
|
||||
#include <math.h>
|
||||
|
||||
class Vector
|
||||
{
|
||||
public:
|
||||
float v[4];
|
||||
|
||||
Vector(float x = 0, float y = 0, float z = 0, float w = 1)
|
||||
{
|
||||
v[0] = x;
|
||||
v[1] = y;
|
||||
v[2] = z;
|
||||
v[3] = w;
|
||||
}
|
||||
|
||||
Vector operator*(float s) const
|
||||
{
|
||||
return Vector(v[0] * s, v[1] * s, v[2] * s, 1);
|
||||
}
|
||||
|
||||
Vector &operator*=(float s)
|
||||
{
|
||||
*this = *this * s;
|
||||
return *this;
|
||||
}
|
||||
|
||||
float operator[](int i) const
|
||||
{
|
||||
return v[i];
|
||||
}
|
||||
|
||||
Vector operator+(const Vector &v2) const
|
||||
{
|
||||
return Vector(v[0] + v2.v[0], v[1] + v2.v[1], v[2] + v2.v[2], 1);
|
||||
}
|
||||
|
||||
Vector operator-(const Vector &v2) const
|
||||
{
|
||||
return Vector(v[0] - v2.v[0], v[1] - v2.v[1], v[2] - v2.v[2], 1);
|
||||
}
|
||||
|
||||
Vector operator-() const
|
||||
{
|
||||
return Vector(-v[0], -v[1], -v[2], 1);
|
||||
}
|
||||
|
||||
void normalize()
|
||||
{
|
||||
float l2 = v[0] * v[0] + v[1] * v[1] + v[2] * v[2];
|
||||
if (!l2)
|
||||
return;
|
||||
float rl = 1 / sqrt(l2);
|
||||
*this *= rl;
|
||||
}
|
||||
|
||||
float length() const
|
||||
{
|
||||
float l2 = v[0] * v[0] + v[1] * v[1] + v[2] * v[2];
|
||||
if (!l2) return 0.f;
|
||||
return sqrt(l2);
|
||||
}
|
||||
|
||||
float dot(const Vector &v2) const
|
||||
{
|
||||
return v[0] * v2.v[0] + v[1] * v2.v[1] + v[2] * v2.v[2];
|
||||
}
|
||||
};
|
||||
|
||||
class Matrix
|
||||
{
|
||||
public:
|
||||
float m[4][4];
|
||||
|
||||
Matrix()
|
||||
: Matrix(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1)
|
||||
{
|
||||
}
|
||||
|
||||
Matrix(float m00, float m01, float m02, float m03,
|
||||
float m10, float m11, float m12, float m13,
|
||||
float m20, float m21, float m22, float m23,
|
||||
float m30, float m31, float m32, float m33)
|
||||
{
|
||||
m[0][0] = m00;
|
||||
m[0][1] = m01;
|
||||
m[0][2] = m02;
|
||||
m[0][3] = m03;
|
||||
m[1][0] = m10;
|
||||
m[1][1] = m11;
|
||||
m[1][2] = m12;
|
||||
m[1][3] = m13;
|
||||
m[2][0] = m20;
|
||||
m[2][1] = m21;
|
||||
m[2][2] = m22;
|
||||
m[2][3] = m23;
|
||||
m[3][0] = m30;
|
||||
m[3][1] = m31;
|
||||
m[3][2] = m32;
|
||||
m[3][3] = m33;
|
||||
}
|
||||
|
||||
static Matrix identity()
|
||||
{
|
||||
return Matrix(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
|
||||
}
|
||||
|
||||
static Matrix scaling(float s)
|
||||
{
|
||||
return Matrix(s, 0, 0, 0, 0, s, 0, 0, 0, 0, s, 0, 0, 0, 0, 1);
|
||||
}
|
||||
|
||||
static Matrix scaling(float u, float v, float w)
|
||||
{
|
||||
return Matrix(u, 0, 0, 0, 0, v, 0, 0, 0, 0, w, 0, 0, 0, 0, 1);
|
||||
}
|
||||
|
||||
static Matrix translation(float x, float y, float z)
|
||||
{
|
||||
return Matrix(1, 0, 0, x, 0, 1, 0, y, 0, 0, 1, z, 0, 0, 0, 1);
|
||||
}
|
||||
|
||||
static Matrix rotation(float a, float x, float y, float z)
|
||||
{
|
||||
float cosa = cos(a);
|
||||
float rcosa = 1 - cosa;
|
||||
float sina = sin(a);
|
||||
return Matrix(
|
||||
x * x * rcosa + cosa, x * y * rcosa - z * sina, x * z * rcosa + y * sina, 0,
|
||||
y * x * rcosa + z * sina, y * y * rcosa + cosa, y * z * rcosa - x * sina, 0,
|
||||
z * x * rcosa - y * sina, z * y * rcosa + x * sina, z * z * rcosa + cosa, 0,
|
||||
0, 0, 0, 1);
|
||||
}
|
||||
|
||||
static Matrix perspective(float fov, float near, float far)
|
||||
{
|
||||
float scale = tan(fov * 0.5 * M_PI / 180);
|
||||
return Matrix(
|
||||
scale, 0, 0, 0,
|
||||
0, scale, 0, 0,
|
||||
0, 0, -far * near / (far - near), 0,
|
||||
0, 0, -1, 0);
|
||||
}
|
||||
|
||||
Vector operator*(const Vector &v)
|
||||
{
|
||||
return Vector(
|
||||
v.v[0] * m[0][0] + v.v[1] * m[0][1] + v.v[2] * m[0][2] + m[0][3],
|
||||
v.v[0] * m[1][0] + v.v[1] * m[1][1] + v.v[2] * m[1][2] + m[1][3],
|
||||
v.v[0] * m[2][0] + v.v[1] * m[2][1] + v.v[2] * m[2][2] + m[2][3],
|
||||
v.v[0] * m[3][0] + v.v[1] * m[3][1] + v.v[2] * m[3][2] + m[3][3]);
|
||||
}
|
||||
|
||||
Matrix operator*(const Matrix &m2)
|
||||
{
|
||||
Matrix mr;
|
||||
for (int y = 0; y < 4; y++)
|
||||
for (int x = 0; x < 4; x++)
|
||||
mr.m[y][x] = m[y][0] * m2.m[0][x] + m[y][1] * m2.m[1][x] + m[y][2] * m2.m[2][x] + m[y][3] * m2.m[3][x];
|
||||
return mr;
|
||||
}
|
||||
|
||||
Matrix &operator*=(const Matrix &m2)
|
||||
{
|
||||
*this = *this * m2;
|
||||
return *this;
|
||||
}
|
||||
};
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
291
libraries/bitluni_ESP32Lib/src/Ressources/Font6x8.h
Normal file
291
libraries/bitluni_ESP32Lib/src/Ressources/Font6x8.h
Normal file
|
@ -0,0 +1,291 @@
|
|||
const unsigned char Font6x8Pixels[] = {
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 255, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 255, 0,
|
||||
0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 255, 0, 255, 0, 0, 0, 255, 0, 255, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 255, 0, 255, 0, 0, 255, 255, 255, 255,
|
||||
255, 0, 0, 255, 0, 255, 0, 0, 255, 255, 255, 255, 255, 0, 0, 255,
|
||||
0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 255, 0, 0, 0, 0, 255, 255, 255, 0, 0, 255, 0, 255, 0,
|
||||
0, 0, 0, 255, 255, 255, 0, 0, 0, 0, 255, 0, 255, 0, 0, 255,
|
||||
255, 255, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 255, 255, 0, 0, 255, 0, 255, 255, 0, 255,
|
||||
0, 0, 0, 0, 255, 0, 0, 0, 0, 255, 0, 255, 255, 0, 255, 0,
|
||||
0, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 255, 0, 255, 0,
|
||||
0, 0, 0, 255, 255, 0, 255, 0, 255, 0, 0, 255, 0, 0, 0, 255,
|
||||
255, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 255, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 255, 255, 0, 0, 0, 255, 0, 0, 0, 0, 0, 255, 0, 0,
|
||||
0, 0, 0, 255, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 255,
|
||||
0, 0, 0, 0, 0, 0, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 255, 255, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 255,
|
||||
0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0,
|
||||
0, 255, 0, 0, 0, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 255,
|
||||
0, 0, 0, 0, 255, 0, 0, 0, 0, 255, 0, 255, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0,
|
||||
0, 0, 0, 255, 255, 255, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
255, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 255, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 255, 0,
|
||||
0, 0, 0, 0, 255, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 255,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 255, 0, 255,
|
||||
0, 0, 0, 255, 0, 255, 0, 0, 0, 255, 0, 255, 0, 0, 0, 0,
|
||||
255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 255, 255, 0,
|
||||
0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 255,
|
||||
255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 255, 255, 0, 0, 0, 0, 0, 0, 255,
|
||||
0, 0, 0, 0, 255, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 255,
|
||||
255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 255, 255, 0, 0, 0, 0, 0, 0, 255,
|
||||
0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 255,
|
||||
255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 255, 0, 0, 0,
|
||||
0, 0, 255, 0, 255, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0,
|
||||
255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 0, 0, 0, 255, 0, 0,
|
||||
0, 0, 0, 255, 255, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 255,
|
||||
255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 0, 0, 0, 255, 0, 0,
|
||||
0, 0, 0, 255, 255, 0, 0, 0, 0, 255, 0, 255, 0, 0, 0, 0,
|
||||
255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 0, 0, 0, 0, 0, 255,
|
||||
0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0,
|
||||
255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 255, 0, 255,
|
||||
0, 0, 0, 0, 255, 0, 0, 0, 0, 255, 0, 255, 0, 0, 0, 0,
|
||||
255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 255, 0, 255,
|
||||
0, 0, 0, 0, 255, 255, 0, 0, 0, 0, 0, 255, 0, 0, 0, 255,
|
||||
255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
255, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0,
|
||||
0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0,
|
||||
0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 255, 255, 0, 0, 0, 0, 0, 0, 255,
|
||||
0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 255, 255, 255, 0, 0, 255, 0, 0, 0, 255, 0, 255, 0, 255, 255,
|
||||
255, 0, 255, 0, 255, 255, 0, 0, 255, 0, 0, 0, 0, 0, 0, 255,
|
||||
255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 255, 255, 0, 0, 0, 255, 0, 0, 255,
|
||||
0, 0, 255, 255, 255, 255, 0, 0, 255, 0, 0, 255, 0, 0, 255, 0,
|
||||
0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 255, 255, 255, 0, 0, 0, 255, 0, 0, 255,
|
||||
0, 0, 255, 255, 255, 0, 0, 0, 255, 0, 0, 255, 0, 0, 255, 255,
|
||||
255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 0, 0, 255, 0, 0, 0,
|
||||
0, 0, 255, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 255,
|
||||
255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 255, 255, 255, 0, 0, 0, 255, 0, 0, 255,
|
||||
0, 0, 255, 0, 0, 255, 0, 0, 255, 0, 0, 255, 0, 0, 255, 255,
|
||||
255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 255, 0, 0, 0,
|
||||
0, 0, 255, 255, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 255, 255,
|
||||
255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 255, 0, 0, 0,
|
||||
0, 0, 255, 255, 255, 0, 0, 0, 255, 0, 0, 0, 0, 0, 255, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 0, 0, 255, 0, 0, 0,
|
||||
0, 0, 255, 0, 255, 255, 0, 0, 255, 0, 0, 0, 255, 0, 0, 255,
|
||||
255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 255, 0, 0, 255, 0, 0, 255, 0, 0, 255,
|
||||
0, 0, 255, 255, 255, 255, 0, 0, 255, 0, 0, 255, 0, 0, 255, 0,
|
||||
0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 0, 0, 0, 0, 255, 0,
|
||||
0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 255,
|
||||
255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 0, 255,
|
||||
0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0,
|
||||
0, 255, 0, 0, 255, 0, 0, 255, 0, 0, 0, 255, 255, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 255, 0, 0, 255, 0, 0, 255, 0, 0, 255,
|
||||
0, 0, 255, 255, 255, 0, 0, 0, 255, 0, 0, 255, 0, 0, 255, 0,
|
||||
0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 255, 0, 0, 0,
|
||||
0, 0, 255, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 255, 255,
|
||||
255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 255, 0, 255, 255, 0, 255,
|
||||
255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 0, 0, 255, 0, 255, 0,
|
||||
0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 255, 0, 255, 255, 0, 0,
|
||||
255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 0, 255, 255, 0, 255, 0,
|
||||
0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 255, 255, 0, 0, 0, 255, 0, 0, 255,
|
||||
0, 0, 255, 0, 0, 255, 0, 0, 255, 0, 0, 255, 0, 0, 0, 255,
|
||||
255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 255, 255, 255, 0, 0, 0, 255, 0, 0, 255,
|
||||
0, 0, 255, 255, 255, 0, 0, 0, 255, 0, 0, 0, 0, 0, 255, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 255, 255, 0, 0, 0, 255, 0, 0, 255,
|
||||
0, 0, 255, 0, 0, 255, 0, 0, 255, 0, 255, 255, 0, 0, 0, 255,
|
||||
255, 255, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 255, 255, 255, 0, 0, 0, 255, 0, 0, 255,
|
||||
0, 0, 255, 255, 255, 0, 0, 0, 255, 0, 0, 255, 0, 0, 255, 0,
|
||||
0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 0, 0, 255, 0, 0, 0,
|
||||
0, 0, 0, 255, 255, 0, 0, 0, 0, 0, 0, 255, 0, 0, 255, 255,
|
||||
255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 0, 0, 0, 255, 0,
|
||||
0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0,
|
||||
255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 255, 0, 0, 255, 0, 0, 255, 0, 0, 255,
|
||||
0, 0, 255, 0, 0, 255, 0, 0, 255, 0, 0, 255, 0, 0, 0, 255,
|
||||
255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 255, 0, 255, 0, 0, 0,
|
||||
255, 0, 255, 0, 0, 0, 255, 0, 0, 255, 0, 255, 0, 0, 0, 0,
|
||||
255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 255, 0, 255, 0, 0, 0,
|
||||
255, 0, 255, 0, 255, 0, 255, 0, 255, 255, 0, 255, 255, 0, 255, 0,
|
||||
0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 255, 0, 255,
|
||||
0, 0, 0, 0, 255, 0, 0, 0, 0, 255, 0, 255, 0, 0, 255, 0,
|
||||
0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 255, 0, 255, 0, 0, 0,
|
||||
255, 0, 0, 255, 0, 255, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0,
|
||||
255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 0, 0, 0, 0, 255,
|
||||
0, 0, 0, 0, 255, 0, 0, 0, 0, 255, 0, 0, 0, 0, 255, 255,
|
||||
255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 255, 255, 255, 0, 0, 0, 255, 0, 0, 0, 0, 0, 255, 0, 0,
|
||||
0, 0, 0, 255, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 255,
|
||||
0, 0, 0, 0, 0, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 255, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 255, 0,
|
||||
0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0,
|
||||
0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 255, 255, 255, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 255,
|
||||
0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0,
|
||||
0, 255, 0, 0, 0, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 255, 0, 0, 0, 0, 255, 0, 255, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 255, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 0,
|
||||
0, 0, 255, 0, 0, 255, 0, 0, 255, 0, 0, 255, 0, 0, 0, 255,
|
||||
255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 255, 255, 255, 0,
|
||||
0, 0, 255, 0, 0, 255, 0, 0, 255, 0, 0, 255, 0, 0, 0, 255,
|
||||
255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 0,
|
||||
0, 0, 255, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 255,
|
||||
255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 255, 255, 255,
|
||||
0, 0, 255, 0, 0, 255, 0, 0, 255, 0, 0, 255, 0, 0, 0, 255,
|
||||
255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 0,
|
||||
0, 0, 255, 0, 255, 255, 0, 0, 255, 255, 0, 0, 0, 0, 0, 255,
|
||||
255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255,
|
||||
0, 0, 0, 255, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 255,
|
||||
255, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 0,
|
||||
0, 0, 255, 0, 0, 255, 0, 0, 255, 0, 0, 255, 0, 0, 0, 255,
|
||||
255, 255, 0, 0, 0, 0, 0, 255, 0, 0, 0, 255, 255, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 255, 0, 255, 0,
|
||||
0, 0, 255, 255, 0, 255, 0, 0, 255, 0, 0, 255, 0, 0, 255, 0,
|
||||
0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 255, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0,
|
||||
255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0,
|
||||
255, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 255, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 255, 0, 255, 255,
|
||||
0, 0, 255, 255, 0, 0, 0, 0, 255, 0, 255, 0, 0, 0, 255, 0,
|
||||
0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 255, 0, 0,
|
||||
0, 0, 0, 255, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0,
|
||||
255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 0, 255,
|
||||
0, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0,
|
||||
0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 255, 0,
|
||||
0, 0, 255, 255, 0, 255, 0, 0, 255, 0, 0, 255, 0, 0, 255, 0,
|
||||
0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 0,
|
||||
0, 0, 255, 0, 0, 255, 0, 0, 255, 0, 0, 255, 0, 0, 0, 255,
|
||||
255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 0,
|
||||
0, 0, 255, 0, 0, 255, 0, 0, 255, 0, 0, 255, 0, 0, 255, 255,
|
||||
255, 0, 0, 0, 255, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255,
|
||||
0, 0, 255, 0, 0, 255, 0, 0, 255, 0, 0, 255, 0, 0, 0, 255,
|
||||
255, 255, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 255, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255,
|
||||
0, 0, 0, 255, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 255,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255,
|
||||
0, 0, 0, 255, 255, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 255,
|
||||
255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 255, 255, 255, 0,
|
||||
0, 0, 0, 255, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0,
|
||||
255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 255,
|
||||
0, 0, 255, 0, 0, 255, 0, 0, 255, 0, 0, 255, 0, 0, 0, 255,
|
||||
255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 0,
|
||||
255, 0, 0, 255, 0, 0, 255, 0, 0, 255, 0, 255, 0, 0, 0, 0,
|
||||
255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0,
|
||||
255, 0, 255, 0, 0, 0, 255, 0, 255, 0, 255, 0, 255, 0, 0, 255,
|
||||
0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 255,
|
||||
0, 0, 0, 0, 255, 0, 0, 0, 0, 255, 0, 255, 0, 0, 255, 0,
|
||||
0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 255,
|
||||
0, 0, 255, 0, 0, 255, 0, 0, 255, 0, 0, 255, 0, 0, 0, 255,
|
||||
255, 255, 0, 0, 0, 0, 0, 255, 0, 0, 0, 255, 255, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255,
|
||||
0, 0, 0, 0, 255, 0, 0, 0, 0, 255, 0, 0, 0, 0, 255, 255,
|
||||
255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 255, 255, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 255, 0,
|
||||
0, 0, 0, 255, 255, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 255,
|
||||
0, 0, 0, 0, 0, 0, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 255, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 255, 0,
|
||||
0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0,
|
||||
255, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 255, 255, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 255, 0,
|
||||
0, 0, 0, 0, 255, 255, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0,
|
||||
0, 255, 0, 0, 0, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 255, 0, 255, 0, 0, 255, 0, 255, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, };
|
||||
Font Font6x8(6, 8, Font6x8Pixels, 32, 96);
|
||||
|
386
libraries/bitluni_ESP32Lib/src/Ressources/Font8x8.h
Normal file
386
libraries/bitluni_ESP32Lib/src/Ressources/Font8x8.h
Normal file
|
@ -0,0 +1,386 @@
|
|||
const unsigned char Font8x8Pixels[] = {
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 0, 0, 0,
|
||||
0, 0, 0, 255, 255, 0, 0, 0, 0, 0, 0, 255, 255, 0, 0, 0,
|
||||
0, 0, 0, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 255, 0, 0, 0,
|
||||
0, 0, 255, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 255, 0, 255, 0, 0, 0, 0, 255, 255, 255, 255, 255, 0, 0,
|
||||
0, 0, 255, 0, 255, 0, 0, 0, 0, 255, 255, 255, 255, 255, 0, 0,
|
||||
0, 0, 255, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0,
|
||||
0, 255, 255, 255, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0,
|
||||
0, 0, 0, 255, 0, 255, 255, 0, 0, 255, 0, 255, 0, 255, 255, 0,
|
||||
0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0,
|
||||
0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 0, 255, 0, 255, 0, 0,
|
||||
0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 255, 0, 255, 0, 0,
|
||||
0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0,
|
||||
0, 0, 0, 255, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 0, 0,
|
||||
0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 0, 0, 0,
|
||||
0, 0, 0, 255, 255, 0, 0, 0, 0, 0, 255, 255, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0,
|
||||
0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 0, 0, 0, 0, 0,
|
||||
0, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 0, 0,
|
||||
0, 0, 0, 0, 255, 255, 0, 0, 0, 0, 0, 255, 255, 0, 0, 0,
|
||||
0, 0, 0, 255, 255, 0, 0, 0, 0, 0, 255, 255, 0, 0, 0, 0,
|
||||
0, 0, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0,
|
||||
0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0,
|
||||
0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0,
|
||||
0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 0, 0, 0,
|
||||
0, 0, 255, 255, 255, 0, 0, 0, 0, 0, 0, 255, 255, 0, 0, 0,
|
||||
0, 0, 0, 255, 255, 0, 0, 0, 0, 0, 0, 255, 255, 0, 0, 0,
|
||||
0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0,
|
||||
0, 255, 0, 0, 255, 255, 255, 0, 0, 0, 0, 0, 255, 255, 255, 0,
|
||||
0, 0, 255, 255, 255, 255, 0, 0, 0, 255, 255, 255, 0, 0, 0, 0,
|
||||
0, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 0, 0,
|
||||
0, 0, 0, 0, 255, 255, 255, 0, 0, 0, 255, 255, 255, 255, 0, 0,
|
||||
0, 0, 0, 0, 255, 255, 255, 0, 0, 0, 0, 0, 255, 255, 255, 0,
|
||||
0, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0,
|
||||
0, 255, 255, 0, 255, 255, 0, 0, 0, 255, 0, 0, 255, 255, 0, 0,
|
||||
0, 255, 0, 0, 255, 255, 255, 0, 0, 255, 255, 255, 255, 255, 255, 0,
|
||||
0, 0, 0, 0, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 0, 0,
|
||||
0, 255, 255, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 0, 0,
|
||||
0, 0, 0, 0, 255, 255, 255, 0, 0, 255, 0, 0, 255, 255, 255, 0,
|
||||
0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0,
|
||||
0, 255, 255, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 0, 0,
|
||||
0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0,
|
||||
0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 0,
|
||||
0, 0, 0, 0, 0, 255, 255, 0, 0, 0, 0, 0, 255, 255, 0, 0,
|
||||
0, 0, 0, 255, 255, 0, 0, 0, 0, 0, 255, 255, 255, 0, 0, 0,
|
||||
0, 0, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0,
|
||||
0, 255, 0, 0, 255, 255, 255, 0, 0, 0, 255, 255, 255, 255, 0, 0,
|
||||
0, 255, 0, 0, 255, 255, 255, 0, 0, 255, 0, 0, 255, 255, 255, 0,
|
||||
0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0,
|
||||
0, 255, 0, 0, 255, 255, 255, 0, 0, 255, 0, 0, 255, 255, 255, 0,
|
||||
0, 0, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 255, 255, 255, 0,
|
||||
0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 255, 255, 0, 0, 0, 0, 0, 0, 255, 255, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 0, 0, 0,
|
||||
0, 0, 0, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 255, 255, 0, 0, 0, 0, 0, 0, 255, 255, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 0, 0, 0,
|
||||
0, 0, 0, 255, 255, 0, 0, 0, 0, 0, 255, 255, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 255, 255, 0, 0, 0, 0, 0, 255, 255, 0, 0, 0, 0,
|
||||
0, 0, 255, 255, 0, 0, 0, 0, 0, 0, 0, 255, 255, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 255, 255, 0, 0, 0, 0, 0, 0, 0, 255, 255, 0, 0, 0,
|
||||
0, 0, 0, 255, 255, 0, 0, 0, 0, 0, 255, 255, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0,
|
||||
0, 255, 0, 0, 255, 255, 255, 0, 0, 0, 0, 0, 255, 255, 255, 0,
|
||||
0, 0, 0, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0,
|
||||
0, 255, 0, 0, 255, 255, 255, 0, 0, 255, 0, 0, 255, 255, 255, 0,
|
||||
0, 255, 255, 255, 255, 255, 255, 0, 0, 255, 0, 0, 255, 255, 255, 0,
|
||||
0, 255, 0, 0, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 0, 0,
|
||||
0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 255, 255, 255, 0, 0,
|
||||
0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0,
|
||||
0, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0,
|
||||
0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 0, 0, 0,
|
||||
0, 255, 255, 0, 0, 0, 0, 0, 0, 255, 255, 0, 0, 255, 255, 0,
|
||||
0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 0, 0,
|
||||
0, 255, 0, 0, 255, 255, 255, 0, 0, 255, 0, 0, 255, 255, 255, 0,
|
||||
0, 255, 0, 0, 255, 255, 255, 0, 0, 255, 0, 0, 255, 255, 255, 0,
|
||||
0, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 0,
|
||||
0, 255, 255, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 0, 0,
|
||||
0, 255, 255, 0, 0, 0, 0, 0, 0, 255, 255, 0, 0, 0, 0, 0,
|
||||
0, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 0,
|
||||
0, 255, 255, 0, 0, 0, 0, 0, 0, 255, 255, 0, 0, 0, 0, 0,
|
||||
0, 255, 255, 255, 255, 255, 0, 0, 0, 255, 255, 0, 0, 0, 0, 0,
|
||||
0, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0,
|
||||
0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 0, 0, 0,
|
||||
0, 255, 255, 0, 255, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0,
|
||||
0, 0, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 255, 255, 0,
|
||||
0, 255, 0, 0, 0, 255, 255, 0, 0, 255, 255, 255, 255, 255, 255, 0,
|
||||
0, 255, 0, 0, 0, 255, 255, 0, 0, 255, 0, 0, 0, 255, 255, 0,
|
||||
0, 255, 0, 0, 0, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0,
|
||||
0, 0, 0, 255, 255, 0, 0, 0, 0, 0, 0, 255, 255, 0, 0, 0,
|
||||
0, 0, 0, 255, 255, 0, 0, 0, 0, 0, 0, 255, 255, 0, 0, 0,
|
||||
0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0,
|
||||
0, 0, 0, 0, 255, 255, 0, 0, 0, 0, 0, 0, 255, 255, 0, 0,
|
||||
0, 255, 255, 0, 255, 255, 0, 0, 0, 255, 255, 0, 255, 255, 0, 0,
|
||||
0, 0, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 0, 0, 255, 255, 0,
|
||||
0, 255, 255, 0, 255, 255, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0,
|
||||
0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 0, 255, 255, 0, 0,
|
||||
0, 255, 255, 0, 0, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 0, 0, 0, 0, 0,
|
||||
0, 255, 255, 0, 0, 0, 0, 0, 0, 255, 255, 0, 0, 0, 0, 0,
|
||||
0, 255, 255, 0, 0, 0, 0, 0, 0, 255, 255, 0, 0, 0, 0, 0,
|
||||
0, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 255, 255, 0,
|
||||
0, 255, 255, 0, 255, 255, 255, 0, 0, 255, 255, 255, 255, 255, 255, 0,
|
||||
0, 255, 0, 255, 0, 255, 255, 0, 0, 255, 0, 0, 0, 255, 255, 0,
|
||||
0, 255, 0, 0, 0, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 255, 255, 0,
|
||||
0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 255, 0, 255, 255, 0,
|
||||
0, 255, 0, 255, 255, 255, 255, 0, 0, 255, 0, 0, 255, 255, 255, 0,
|
||||
0, 255, 0, 0, 0, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0,
|
||||
0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0,
|
||||
0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0,
|
||||
0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 0, 0,
|
||||
0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0,
|
||||
0, 255, 255, 255, 255, 255, 0, 0, 0, 255, 255, 0, 0, 0, 0, 0,
|
||||
0, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0,
|
||||
0, 255, 255, 0, 0, 0, 255, 0, 0, 255, 255, 0, 0, 0, 255, 0,
|
||||
0, 255, 255, 0, 255, 0, 255, 0, 0, 255, 255, 0, 0, 255, 0, 0,
|
||||
0, 0, 255, 255, 255, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 0, 0,
|
||||
0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0,
|
||||
0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 0, 255, 0, 0, 0,
|
||||
0, 255, 255, 0, 0, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0,
|
||||
0, 255, 255, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0,
|
||||
0, 0, 0, 0, 255, 255, 255, 0, 0, 255, 0, 0, 255, 255, 255, 0,
|
||||
0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 0,
|
||||
0, 0, 0, 255, 255, 0, 0, 0, 0, 0, 0, 255, 255, 0, 0, 0,
|
||||
0, 0, 0, 255, 255, 0, 0, 0, 0, 0, 0, 255, 255, 0, 0, 0,
|
||||
0, 0, 0, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 255, 255, 0,
|
||||
0, 255, 0, 0, 0, 255, 255, 0, 0, 255, 0, 0, 0, 255, 255, 0,
|
||||
0, 255, 0, 0, 0, 255, 255, 0, 0, 255, 0, 0, 255, 255, 255, 0,
|
||||
0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 255, 255, 0,
|
||||
0, 255, 0, 0, 0, 255, 255, 0, 0, 255, 0, 0, 0, 255, 255, 0,
|
||||
0, 255, 0, 0, 0, 255, 255, 0, 0, 0, 255, 0, 255, 255, 0, 0,
|
||||
0, 0, 0, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 255, 255, 0,
|
||||
0, 255, 0, 0, 0, 255, 255, 0, 0, 255, 0, 255, 0, 255, 255, 0,
|
||||
0, 255, 255, 255, 255, 255, 255, 0, 0, 255, 255, 0, 255, 255, 255, 0,
|
||||
0, 255, 0, 0, 0, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 255, 255, 0,
|
||||
0, 0, 255, 0, 255, 255, 0, 0, 0, 0, 0, 255, 255, 0, 0, 0,
|
||||
0, 0, 255, 255, 255, 0, 0, 0, 0, 255, 255, 0, 0, 255, 0, 0,
|
||||
0, 255, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 0, 0, 255, 255, 0,
|
||||
0, 255, 255, 0, 0, 255, 255, 0, 0, 0, 255, 255, 255, 255, 0, 0,
|
||||
0, 0, 0, 255, 255, 0, 0, 0, 0, 0, 0, 255, 255, 0, 0, 0,
|
||||
0, 0, 0, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 0,
|
||||
0, 0, 0, 0, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 0, 0,
|
||||
0, 0, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 0, 0, 0, 0,
|
||||
0, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0,
|
||||
0, 255, 0, 0, 255, 255, 255, 0, 0, 255, 0, 0, 255, 255, 255, 0,
|
||||
0, 255, 255, 255, 255, 255, 255, 0, 0, 255, 0, 0, 255, 255, 255, 0,
|
||||
0, 255, 0, 0, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 0, 0,
|
||||
0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 255, 255, 255, 0, 0,
|
||||
0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0,
|
||||
0, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0,
|
||||
0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 0, 0, 0,
|
||||
0, 255, 255, 0, 0, 0, 0, 0, 0, 255, 255, 0, 0, 255, 255, 0,
|
||||
0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 0, 0,
|
||||
0, 255, 0, 0, 255, 255, 255, 0, 0, 255, 0, 0, 255, 255, 255, 0,
|
||||
0, 255, 0, 0, 255, 255, 255, 0, 0, 255, 0, 0, 255, 255, 255, 0,
|
||||
0, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 0,
|
||||
0, 255, 255, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 0, 0,
|
||||
0, 255, 255, 0, 0, 0, 0, 0, 0, 255, 255, 0, 0, 0, 0, 0,
|
||||
0, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 0,
|
||||
0, 255, 255, 0, 0, 0, 0, 0, 0, 255, 255, 0, 0, 0, 0, 0,
|
||||
0, 255, 255, 255, 255, 255, 0, 0, 0, 255, 255, 0, 0, 0, 0, 0,
|
||||
0, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0,
|
||||
0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 0, 0, 0,
|
||||
0, 255, 255, 0, 255, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0,
|
||||
0, 0, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 255, 255, 0,
|
||||
0, 255, 0, 0, 0, 255, 255, 0, 0, 255, 255, 255, 255, 255, 255, 0,
|
||||
0, 255, 0, 0, 0, 255, 255, 0, 0, 255, 0, 0, 0, 255, 255, 0,
|
||||
0, 255, 0, 0, 0, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0,
|
||||
0, 0, 0, 255, 255, 0, 0, 0, 0, 0, 0, 255, 255, 0, 0, 0,
|
||||
0, 0, 0, 255, 255, 0, 0, 0, 0, 0, 0, 255, 255, 0, 0, 0,
|
||||
0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0,
|
||||
0, 0, 0, 0, 255, 255, 0, 0, 0, 0, 0, 0, 255, 255, 0, 0,
|
||||
0, 255, 255, 0, 255, 255, 0, 0, 0, 255, 255, 0, 255, 255, 0, 0,
|
||||
0, 0, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 0, 0, 255, 255, 0,
|
||||
0, 255, 255, 0, 255, 255, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0,
|
||||
0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 0, 255, 255, 0, 0,
|
||||
0, 255, 255, 0, 0, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 0, 0, 0, 0, 0,
|
||||
0, 255, 255, 0, 0, 0, 0, 0, 0, 255, 255, 0, 0, 0, 0, 0,
|
||||
0, 255, 255, 0, 0, 0, 0, 0, 0, 255, 255, 0, 0, 0, 0, 0,
|
||||
0, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 255, 255, 0,
|
||||
0, 255, 255, 0, 255, 255, 255, 0, 0, 255, 255, 255, 255, 255, 255, 0,
|
||||
0, 255, 0, 255, 0, 255, 255, 0, 0, 255, 0, 0, 0, 255, 255, 0,
|
||||
0, 255, 0, 0, 0, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 255, 255, 0,
|
||||
0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 255, 0, 255, 255, 0,
|
||||
0, 255, 0, 255, 255, 255, 255, 0, 0, 255, 0, 0, 255, 255, 255, 0,
|
||||
0, 255, 0, 0, 0, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0,
|
||||
0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0,
|
||||
0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0,
|
||||
0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 0, 0,
|
||||
0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0,
|
||||
0, 255, 255, 255, 255, 255, 0, 0, 0, 255, 255, 0, 0, 0, 0, 0,
|
||||
0, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0,
|
||||
0, 255, 255, 0, 0, 0, 255, 0, 0, 255, 255, 0, 0, 0, 255, 0,
|
||||
0, 255, 255, 0, 255, 0, 255, 0, 0, 255, 255, 0, 0, 255, 0, 0,
|
||||
0, 0, 255, 255, 255, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 0, 0,
|
||||
0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0,
|
||||
0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 0, 255, 0, 0, 0,
|
||||
0, 255, 255, 0, 0, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0,
|
||||
0, 255, 255, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0,
|
||||
0, 0, 0, 0, 255, 255, 255, 0, 0, 255, 0, 0, 255, 255, 255, 0,
|
||||
0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 0,
|
||||
0, 0, 0, 255, 255, 0, 0, 0, 0, 0, 0, 255, 255, 0, 0, 0,
|
||||
0, 0, 0, 255, 255, 0, 0, 0, 0, 0, 0, 255, 255, 0, 0, 0,
|
||||
0, 0, 0, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 255, 255, 0,
|
||||
0, 255, 0, 0, 0, 255, 255, 0, 0, 255, 0, 0, 0, 255, 255, 0,
|
||||
0, 255, 0, 0, 0, 255, 255, 0, 0, 255, 0, 0, 255, 255, 255, 0,
|
||||
0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 255, 255, 0,
|
||||
0, 255, 0, 0, 0, 255, 255, 0, 0, 255, 0, 0, 0, 255, 255, 0,
|
||||
0, 255, 0, 0, 0, 255, 255, 0, 0, 0, 255, 0, 255, 255, 0, 0,
|
||||
0, 0, 0, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 255, 255, 0,
|
||||
0, 255, 0, 0, 0, 255, 255, 0, 0, 255, 0, 255, 0, 255, 255, 0,
|
||||
0, 255, 255, 255, 255, 255, 255, 0, 0, 255, 255, 0, 255, 255, 255, 0,
|
||||
0, 255, 0, 0, 0, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 255, 255, 0,
|
||||
0, 0, 255, 0, 255, 255, 0, 0, 0, 0, 0, 255, 255, 0, 0, 0,
|
||||
0, 0, 255, 255, 255, 0, 0, 0, 0, 255, 255, 0, 0, 255, 0, 0,
|
||||
0, 255, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 0, 0, 255, 255, 0,
|
||||
0, 255, 255, 0, 0, 255, 255, 0, 0, 0, 255, 255, 255, 255, 0, 0,
|
||||
0, 0, 0, 255, 255, 0, 0, 0, 0, 0, 0, 255, 255, 0, 0, 0,
|
||||
0, 0, 0, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 0,
|
||||
0, 0, 0, 0, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 0, 0,
|
||||
0, 0, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 0, 0, 0, 0,
|
||||
0, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 0, 0, 0, 0,
|
||||
0, 0, 255, 255, 255, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0,
|
||||
0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 0, 0, 0,
|
||||
0, 0, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
255, 0, 255, 0, 255, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 255, 0, 255, 0, 255, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, };
|
||||
Font Font8x8(8, 8, Font8x8Pixels, 32, 96);
|
26
libraries/bitluni_ESP32Lib/src/Tools/Log.h
Normal file
26
libraries/bitluni_ESP32Lib/src/Tools/Log.h
Normal file
|
@ -0,0 +1,26 @@
|
|||
/*
|
||||
Author: bitluni 2019
|
||||
License:
|
||||
Creative Commons Attribution ShareAlike 4.0
|
||||
https://creativecommons.org/licenses/by-sa/4.0/
|
||||
|
||||
For further details check out:
|
||||
https://youtube.com/bitlunislab
|
||||
https://github.com/bitluni
|
||||
http://bitluni.net
|
||||
*/
|
||||
#pragma once
|
||||
#include "Arduino.h"
|
||||
|
||||
|
||||
#define DEBUG_PRINTLN(a) Serial.println(a)
|
||||
#define DEBUG_PRINT(a) Serial.print(a)
|
||||
#define DEBUG_PRINTLNF(a, f) Serial.println(a, f)
|
||||
#define DEBUG_PRINTF(a, f) Serial.print(a, f)
|
||||
/*
|
||||
#define DEBUG_PRINTLN(a) ;
|
||||
#define DEBUG_PRINT(a) ;
|
||||
#define DEBUG_PRINTLNF(a, f) ;
|
||||
#define DEBUG_PRINTF(a, f) ;
|
||||
*/
|
||||
#define ERROR(a) {Serial.println((a)); delay(3000); throw 0;};
|
122
libraries/bitluni_ESP32Lib/src/VGA/Mode.h
Normal file
122
libraries/bitluni_ESP32Lib/src/VGA/Mode.h
Normal file
|
@ -0,0 +1,122 @@
|
|||
/*
|
||||
Author: bitluni 2019
|
||||
License:
|
||||
Creative Commons Attribution ShareAlike 4.0
|
||||
https://creativecommons.org/licenses/by-sa/4.0/
|
||||
|
||||
For further details check out:
|
||||
https://youtube.com/bitlunislab
|
||||
https://github.com/bitluni
|
||||
http://bitluni.net
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
class Mode
|
||||
{
|
||||
public:
|
||||
int hFront;
|
||||
int hSync;
|
||||
int hBack;
|
||||
int hRes;
|
||||
int vFront;
|
||||
int vSync;
|
||||
int vBack;
|
||||
int vRes;
|
||||
int vDiv;
|
||||
unsigned long pixelClock;
|
||||
int hSyncPolarity;
|
||||
int vSyncPolarity;
|
||||
float aspect;
|
||||
int activeLineCount;
|
||||
Mode(
|
||||
const int hFront = 0,
|
||||
const int hSync = 0,
|
||||
const int hBack = 0,
|
||||
const int hRes = 0,
|
||||
const int vFront = 0,
|
||||
const int vSync = 0,
|
||||
const int vBack = 0,
|
||||
const int vRes = 0,
|
||||
const int vDiv = 1,
|
||||
const unsigned long pixelClock = 0,
|
||||
const int hSyncPolarity = 1,
|
||||
const int vSyncPolarity = 1,
|
||||
const float aspect = 1.f)
|
||||
: hFront(hFront),
|
||||
hSync(hSync),
|
||||
hBack(hBack),
|
||||
hRes(hRes),
|
||||
vFront(vFront),
|
||||
vSync(vSync),
|
||||
vBack(vBack),
|
||||
vRes(vRes),
|
||||
vDiv(vDiv),
|
||||
pixelClock(pixelClock),
|
||||
hSyncPolarity(hSyncPolarity),
|
||||
vSyncPolarity(vSyncPolarity),
|
||||
aspect(aspect),
|
||||
activeLineCount(vRes / vDiv)
|
||||
{
|
||||
}
|
||||
|
||||
int maxXRes() const
|
||||
{
|
||||
return (int(hRes * 19673499. / pixelClock) & 0xfffffffe);
|
||||
}
|
||||
|
||||
int linesPerField() const
|
||||
{
|
||||
return vFront + vSync + vBack + vRes;
|
||||
}
|
||||
|
||||
int pixelsPerLine() const
|
||||
{
|
||||
return hFront + hSync + hBack + hRes;
|
||||
}
|
||||
|
||||
Mode custom(int xres, int yres, int fixedYDivider = 0) const
|
||||
{
|
||||
xres = (xres + 3) & 0xfffffffc;
|
||||
float f = float(xres) / hRes;
|
||||
int hs = int(hSync * f + 3) & 0xfffffffc;
|
||||
int hb = int((hSync + hBack - hs / f) * f + 3) & 0xfffffffc;
|
||||
int hr = xres;
|
||||
int hf = int((pixelsPerLine() - (hs + hb + hr) / f) * f + 3) & 0xfffffffc;
|
||||
|
||||
int vd = fixedYDivider ? fixedYDivider : (vRes / yres);
|
||||
int vr = yres * vd;
|
||||
int vf = vFront + vRes / 2 - vr / 2;
|
||||
int vb = vBack + vRes / 2 - (vr - vr / 2);
|
||||
long pc = long(pixelClock * f);
|
||||
return Mode(hf, hs, hb, hr, vf, vSync, vb, vr, vd, pc, hSyncPolarity, vSyncPolarity);
|
||||
}
|
||||
|
||||
template<class Output>
|
||||
void print(Output &output) const
|
||||
{
|
||||
output.print("hFront: ");
|
||||
output.println(hFront);
|
||||
output.print("hSync: ");
|
||||
output.println(hSync);
|
||||
output.print("hBack: ");
|
||||
output.println(hBack);
|
||||
output.print("hRes: ");
|
||||
output.println(hRes);
|
||||
output.print("vFront: ");
|
||||
output.println(vFront);
|
||||
output.print("vSync: ");
|
||||
output.println(vSync);
|
||||
output.print("vBack: ");
|
||||
output.println(vBack);
|
||||
output.print("vRes: ");
|
||||
output.println(vRes);
|
||||
output.print("vDiv: ");
|
||||
output.println(vDiv);
|
||||
output.print("pixelClock: ");
|
||||
output.println(pixelClock);
|
||||
output.print("hSyncPolarity: ");
|
||||
output.println(hSyncPolarity);
|
||||
output.print("vSyncPolarity: ");
|
||||
output.println(vSyncPolarity);
|
||||
}
|
||||
};
|
102
libraries/bitluni_ESP32Lib/src/VGA/PinConfig.h
Normal file
102
libraries/bitluni_ESP32Lib/src/VGA/PinConfig.h
Normal file
|
@ -0,0 +1,102 @@
|
|||
/*
|
||||
Author: bitluni 2019
|
||||
License:
|
||||
Creative Commons Attribution ShareAlike 4.0
|
||||
https://creativecommons.org/licenses/by-sa/4.0/
|
||||
|
||||
For further details check out:
|
||||
https://youtube.com/bitlunislab
|
||||
https://github.com/bitluni
|
||||
http://bitluni.net
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
class PinConfig
|
||||
{
|
||||
public:
|
||||
int r0, r1, r2, r3, r4;
|
||||
int g0, g1, g2, g3, g4;
|
||||
int b0, b1, b2, b3;
|
||||
int hSync, vSync, clock;
|
||||
PinConfig(
|
||||
const int r0 = -1,
|
||||
const int r1 = -1,
|
||||
const int r2 = -1,
|
||||
const int r3 = -1,
|
||||
const int r4 = -1,
|
||||
const int g0 = -1,
|
||||
const int g1 = -1,
|
||||
const int g2 = -1,
|
||||
const int g3 = -1,
|
||||
const int g4 = -1,
|
||||
const int b0 = -1,
|
||||
const int b1 = -1,
|
||||
const int b2 = -1,
|
||||
const int b3 = -1,
|
||||
const int hSync = -1,
|
||||
const int vSync = -1,
|
||||
const int clock = -1)
|
||||
: r0(r0),
|
||||
r1(r1),
|
||||
r2(r2),
|
||||
r3(r3),
|
||||
r4(r4),
|
||||
g0(g0),
|
||||
g1(g1),
|
||||
g2(g2),
|
||||
g3(g3),
|
||||
g4(g4),
|
||||
b0(b0),
|
||||
b1(b1),
|
||||
b2(b2),
|
||||
b3(b3),
|
||||
hSync(hSync),
|
||||
vSync(vSync),
|
||||
clock(clock)
|
||||
{
|
||||
}
|
||||
|
||||
void fill3Bit(int *pins) const
|
||||
{
|
||||
pins[0] = r4;
|
||||
pins[1] = g4;
|
||||
pins[2] = b3;
|
||||
pins[3] = -1;
|
||||
pins[4] = -1;
|
||||
pins[5] = -1;
|
||||
pins[6] = hSync;
|
||||
pins[7] = vSync;
|
||||
}
|
||||
|
||||
void fill6Bit(int *pins) const
|
||||
{
|
||||
pins[0] = r3;
|
||||
pins[1] = r4;
|
||||
pins[2] = g3;
|
||||
pins[3] = g4;
|
||||
pins[4] = b2;
|
||||
pins[5] = b3;
|
||||
pins[6] = hSync;
|
||||
pins[7] = vSync;
|
||||
}
|
||||
|
||||
void fill14Bit(int *pins) const
|
||||
{
|
||||
pins[0] = r0;
|
||||
pins[1] = r1;
|
||||
pins[2] = r2;
|
||||
pins[3] = r3;
|
||||
pins[4] = r4;
|
||||
pins[5] = g0;
|
||||
pins[6] = g1;
|
||||
pins[7] = g2;
|
||||
pins[8] = g3;
|
||||
pins[9] = g4;
|
||||
pins[10] = b0;
|
||||
pins[11] = b1;
|
||||
pins[12] = b2;
|
||||
pins[13] = b3;
|
||||
pins[14] = hSync;
|
||||
pins[15] = vSync;
|
||||
}
|
||||
};
|
225
libraries/bitluni_ESP32Lib/src/VGA/VGA.cpp
Normal file
225
libraries/bitluni_ESP32Lib/src/VGA/VGA.cpp
Normal file
|
@ -0,0 +1,225 @@
|
|||
/*
|
||||
Author: bitluni 2019
|
||||
License:
|
||||
Creative Commons Attribution ShareAlike 4.0
|
||||
https://creativecommons.org/licenses/by-sa/4.0/
|
||||
|
||||
For further details check out:
|
||||
https://youtube.com/bitlunislab
|
||||
https://github.com/bitluni
|
||||
http://bitluni.net
|
||||
*/
|
||||
#include "VGA.h"
|
||||
|
||||
//hfront hsync hback pixels vfront vsync vback lines divy pixelclock hpolaritynegative vpolaritynegative
|
||||
const Mode VGA::MODE320x480(8, 48, 24, 320, 11, 2, 31, 480, 1, 12587500, 1, 1);
|
||||
const Mode VGA::MODE320x240(8, 48, 24, 320, 11, 2, 31, 480, 2, 12587500, 1, 1);
|
||||
const Mode VGA::MODE320x400(8, 48, 24, 320, 12, 2, 35, 400, 1, 12587500, 1, 0);
|
||||
const Mode VGA::MODE320x200(8, 48, 24, 320, 12, 2, 35, 400, 2, 12587500, 1, 0);
|
||||
const Mode VGA::MODE360x400(8, 54, 28, 360, 11, 2, 32, 400, 1, 14161000, 1, 0);
|
||||
const Mode VGA::MODE360x200(8, 54, 28, 360, 11, 2, 32, 400, 2, 14161000, 1, 0);
|
||||
const Mode VGA::MODE360x350(8, 54, 28, 360, 11, 2, 32, 350, 1, 14161000, 1, 1);
|
||||
const Mode VGA::MODE360x175 (8, 54, 28, 360, 11, 2, 32, 350, 2, 14161000, 1, 1);
|
||||
|
||||
const Mode VGA::MODE320x350 (8, 48, 24, 320, 37, 2, 60, 350, 1, 12587500, 0, 1);
|
||||
const Mode VGA::MODE320x175(8, 48, 24, 320, 37, 2, 60, 350, 2, 12587500, 0, 1);
|
||||
|
||||
const Mode VGA::MODE400x300(12, 36, 64, 400, 1, 2, 22, 600, 2, 18000000, 0, 0);
|
||||
const Mode VGA::MODE400x150(12, 36, 64, 400, 1, 2, 22, 600, 4, 18000000, 0, 0);
|
||||
const Mode VGA::MODE400x100(12, 36, 64, 400, 1, 2, 22, 600, 6, 18000000, 0, 0);
|
||||
const Mode VGA::MODE200x150(6, 18, 32, 200, 1, 2, 22, 600, 4, 9000000, 0, 0);
|
||||
//const Mode VGA::MODE200x150(10, 32, 22, 200, 1, 4, 23, 600, 4, 10000000, 0, 0); //60Hz version
|
||||
|
||||
//500 pixels horizontal it's based on 640x480
|
||||
const Mode VGA::MODE500x480(12, 76, 38, 500, 11, 2, 31, 480, 1, 19667968, 1, 1);
|
||||
const Mode VGA::MODE500x240(12, 76, 38, 500, 11, 2, 31, 480, 2, 19667968, 1, 1);
|
||||
|
||||
//base modes for custom mode calculations
|
||||
const Mode VGA::MODE1280x1024(48, 112, 248, 1280, 1, 3, 38, 1024, 1, 108000000, 0, 0);
|
||||
const Mode VGA::MODE1280x960(80, 136, 216, 1280, 1, 3, 30, 960, 1, 101200000, 1, 0);
|
||||
const Mode VGA::MODE1280x800(64, 136, 200, 1280, 1, 3, 24, 800, 1, 83640000, 1, 0);
|
||||
const Mode VGA::MODE1024x768(24, 136, 160, 1024, 3, 6, 29, 768, 1, 65000000, 1, 1);
|
||||
const Mode VGA::MODE800x600(24, 72, 128, 800, 1, 2, 22, 600, 1, 36000000, 0, 0);
|
||||
const Mode VGA::MODE720x400(16, 108, 56, 720, 11, 2, 32, 400, 1, 28322000, 1, 0);
|
||||
const Mode VGA::MODE720x350(16, 108, 56, 720, 11, 2, 32, 350, 1, 28322000, 1, 1);
|
||||
const Mode VGA::MODE640x480(16, 96, 48, 640, 11, 2, 31, 480, 1, 25175000, 1, 1);
|
||||
const Mode VGA::MODE640x400(16, 96, 48, 640, 12, 2, 35, 400, 1, 25175000, 1, 0);
|
||||
const Mode VGA::MODE640x350(16, 96, 48, 640, 37, 2, 60, 350, 1, 25175000, 0, 1);
|
||||
|
||||
const PinConfig VGA::VGAv01(2, 4, 12, 13, 14, 15, 16, 17, 18, 19, 21, 22, 23, 27, 32, 33, -1);
|
||||
const PinConfig VGA::VGABlackEdition(2, 4, 12, 13, 14, 15, 16, 17, 18, 19, 21, 22, 23, 27, 32, 33, -1);
|
||||
const PinConfig VGA::VGAWhiteEdition(5, 14, 13, 15, 2, 19, 18, 17, 4, 16, 27, 22, 12, 21, 32, 33, -1);
|
||||
const PinConfig VGA::PicoVGA(-1, -1, -1, 18, 5, -1, -1, -1, 14, 4, -1, -1, 27, 15, 32, 33, -1);
|
||||
|
||||
VGA::VGA(const int i2sIndex)
|
||||
: I2S(i2sIndex)
|
||||
{
|
||||
lineBufferCount = 8;
|
||||
dmaBufferDescriptors = 0;
|
||||
}
|
||||
|
||||
bool VGA::init(const Mode &mode, const int *pinMap, const int bitCount, const int clockPin)
|
||||
{
|
||||
this->mode = mode;
|
||||
int xres = mode.hRes;
|
||||
int yres = mode.vRes / mode.vDiv;
|
||||
initSyncBits();
|
||||
propagateResolution(xres, yres);
|
||||
this->vsyncPin = vsyncPin;
|
||||
this->hsyncPin = hsyncPin;
|
||||
totalLines = mode.linesPerField();
|
||||
allocateLineBuffers();
|
||||
currentLine = 0;
|
||||
vSyncPassed = false;
|
||||
initParallelOutputMode(pinMap, mode.pixelClock, bitCount, clockPin);
|
||||
startTX();
|
||||
return true;
|
||||
}
|
||||
|
||||
void VGA::setLineBufferCount(int lineBufferCount)
|
||||
{
|
||||
this->lineBufferCount = lineBufferCount;
|
||||
}
|
||||
|
||||
void VGA::allocateLineBuffers()
|
||||
{
|
||||
allocateLineBuffers(lineBufferCount);
|
||||
}
|
||||
|
||||
/// simple ringbuffer of blocks of size bytes each
|
||||
void VGA::allocateLineBuffers(const int lines)
|
||||
{
|
||||
dmaBufferDescriptorCount = lines;
|
||||
dmaBufferDescriptors = DMABufferDescriptor::allocateDescriptors(dmaBufferDescriptorCount);
|
||||
int bytes = (mode.hFront + mode.hSync + mode.hBack + mode.hRes) * bytesPerSample();
|
||||
for (int i = 0; i < dmaBufferDescriptorCount; i++)
|
||||
{
|
||||
dmaBufferDescriptors[i].setBuffer(DMABufferDescriptor::allocateBuffer(bytes, true), bytes); //front porch + hsync + back porch + pixels
|
||||
if (i)
|
||||
dmaBufferDescriptors[i - 1].next(dmaBufferDescriptors[i]);
|
||||
}
|
||||
dmaBufferDescriptors[dmaBufferDescriptorCount - 1].next(dmaBufferDescriptors[0]);
|
||||
}
|
||||
|
||||
///complete ringbuffer from frame
|
||||
void VGA::allocateLineBuffers(void **frameBuffer)
|
||||
{
|
||||
dmaBufferDescriptorCount = totalLines * 2;
|
||||
int inactiveSamples = (mode.hFront + mode.hSync + mode.hBack + 3) & 0xfffffffc;
|
||||
vSyncInactiveBuffer = DMABufferDescriptor::allocateBuffer(inactiveSamples * bytesPerSample(), true);
|
||||
vSyncActiveBuffer = DMABufferDescriptor::allocateBuffer(mode.hRes * bytesPerSample(), true);
|
||||
inactiveBuffer = DMABufferDescriptor::allocateBuffer(inactiveSamples * bytesPerSample(), true);
|
||||
blankActiveBuffer = DMABufferDescriptor::allocateBuffer(mode.hRes * bytesPerSample(), true);
|
||||
if(bytesPerSample() == 1)
|
||||
{
|
||||
for (int i = 0; i < inactiveSamples; i++)
|
||||
{
|
||||
if (i >= mode.hFront && i < mode.hFront + mode.hSync)
|
||||
{
|
||||
((unsigned char *)vSyncInactiveBuffer)[i ^ 2] = hsyncBit | vsyncBit;
|
||||
((unsigned char *)inactiveBuffer)[i ^ 2] = hsyncBit | vsyncBitI;
|
||||
}
|
||||
else
|
||||
{
|
||||
((unsigned char *)vSyncInactiveBuffer)[i ^ 2] = hsyncBitI | vsyncBit;
|
||||
((unsigned char *)inactiveBuffer)[i ^ 2] = hsyncBitI | vsyncBitI;
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < mode.hRes; i++)
|
||||
{
|
||||
((unsigned char *)vSyncActiveBuffer)[i ^ 2] = hsyncBitI | vsyncBit;
|
||||
((unsigned char *)blankActiveBuffer)[i ^ 2] = hsyncBitI | vsyncBitI;
|
||||
}
|
||||
}
|
||||
else if(bytesPerSample() == 2)
|
||||
{
|
||||
for (int i = 0; i < inactiveSamples; i++)
|
||||
{
|
||||
if (i >= mode.hFront && i < mode.hFront + mode.hSync)
|
||||
{
|
||||
((unsigned short *)vSyncInactiveBuffer)[i ^ 1] = hsyncBit | vsyncBit;
|
||||
((unsigned short *)inactiveBuffer)[i ^ 1] = hsyncBit | vsyncBitI;
|
||||
}
|
||||
else
|
||||
{
|
||||
((unsigned short *)vSyncInactiveBuffer)[i ^ 1] = hsyncBitI | vsyncBit;
|
||||
((unsigned short *)inactiveBuffer)[i ^ 1] = hsyncBitI | vsyncBitI;
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < mode.hRes; i++)
|
||||
{
|
||||
((unsigned short *)vSyncActiveBuffer)[i ^ 1] = hsyncBitI | vsyncBit;
|
||||
((unsigned short *)blankActiveBuffer)[i ^ 1] = hsyncBitI | vsyncBitI;
|
||||
}
|
||||
}
|
||||
|
||||
dmaBufferDescriptors = DMABufferDescriptor::allocateDescriptors(dmaBufferDescriptorCount);
|
||||
for (int i = 0; i < dmaBufferDescriptorCount; i++)
|
||||
dmaBufferDescriptors[i].next(dmaBufferDescriptors[(i + 1) % dmaBufferDescriptorCount]);
|
||||
int d = 0;
|
||||
for (int i = 0; i < mode.vFront; i++)
|
||||
{
|
||||
dmaBufferDescriptors[d++].setBuffer(inactiveBuffer, inactiveSamples * bytesPerSample());
|
||||
dmaBufferDescriptors[d++].setBuffer(blankActiveBuffer, mode.hRes * bytesPerSample());
|
||||
}
|
||||
for (int i = 0; i < mode.vSync; i++)
|
||||
{
|
||||
dmaBufferDescriptors[d++].setBuffer(vSyncInactiveBuffer, inactiveSamples * bytesPerSample());
|
||||
dmaBufferDescriptors[d++].setBuffer(vSyncActiveBuffer, mode.hRes * bytesPerSample());
|
||||
}
|
||||
for (int i = 0; i < mode.vBack; i++)
|
||||
{
|
||||
dmaBufferDescriptors[d++].setBuffer(inactiveBuffer, inactiveSamples * bytesPerSample());
|
||||
dmaBufferDescriptors[d++].setBuffer(blankActiveBuffer, mode.hRes * bytesPerSample());
|
||||
}
|
||||
for (int i = 0; i < mode.vRes; i++)
|
||||
{
|
||||
dmaBufferDescriptors[d++].setBuffer(inactiveBuffer, inactiveSamples * bytesPerSample());
|
||||
dmaBufferDescriptors[d++].setBuffer(frameBuffer[i / mode.vDiv], mode.hRes * bytesPerSample());
|
||||
}
|
||||
}
|
||||
|
||||
void VGA::vSync()
|
||||
{
|
||||
vSyncPassed = true;
|
||||
}
|
||||
|
||||
void VGA::interrupt()
|
||||
{
|
||||
unsigned long *signal = (unsigned long *)dmaBufferDescriptors[dmaBufferDescriptorActive].buffer();
|
||||
unsigned long *pixels = &((unsigned long *)dmaBufferDescriptors[dmaBufferDescriptorActive].buffer())[(mode.hSync + mode.hBack) / 2];
|
||||
unsigned long base, baseh;
|
||||
if (currentLine >= mode.vFront && currentLine < mode.vFront + mode.vSync)
|
||||
{
|
||||
baseh = (vsyncBit | hsyncBit) | ((vsyncBit | hsyncBit) << 16);
|
||||
base = (vsyncBit | hsyncBitI) | ((vsyncBit | hsyncBitI) << 16);
|
||||
}
|
||||
else
|
||||
{
|
||||
baseh = (vsyncBitI | hsyncBit) | ((vsyncBitI | hsyncBit) << 16);
|
||||
base = (vsyncBitI | hsyncBitI) | ((vsyncBitI | hsyncBitI) << 16);
|
||||
}
|
||||
for (int i = 0; i < mode.hSync / 2; i++)
|
||||
signal[i] = baseh;
|
||||
for (int i = mode.hSync / 2; i < (mode.hSync + mode.hBack) / 2; i++)
|
||||
signal[i] = base;
|
||||
|
||||
int y = (currentLine - mode.vFront - mode.vSync - mode.vBack) / mode.vDiv;
|
||||
if (y >= 0 && y < mode.vRes)
|
||||
interruptPixelLine(y, pixels, base);
|
||||
else
|
||||
for (int i = 0; i < mode.hRes / 2; i++)
|
||||
{
|
||||
pixels[i] = base | (base << 16);
|
||||
}
|
||||
for (int i = 0; i < mode.hFront / 2; i++)
|
||||
signal[i + (mode.hSync + mode.hBack + mode.hRes) / 2] = base;
|
||||
currentLine = (currentLine + 1) % totalLines;
|
||||
dmaBufferDescriptorActive = (dmaBufferDescriptorActive + 1) % dmaBufferDescriptorCount;
|
||||
if (currentLine == 0)
|
||||
vSync();
|
||||
}
|
||||
|
||||
void VGA::interruptPixelLine(int y, unsigned long *pixels, unsigned long syncBits)
|
||||
{
|
||||
}
|
99
libraries/bitluni_ESP32Lib/src/VGA/VGA.h
Normal file
99
libraries/bitluni_ESP32Lib/src/VGA/VGA.h
Normal file
|
@ -0,0 +1,99 @@
|
|||
/*
|
||||
Author: bitluni 2019
|
||||
License:
|
||||
Creative Commons Attribution ShareAlike 4.0
|
||||
https://creativecommons.org/licenses/by-sa/4.0/
|
||||
|
||||
For further details check out:
|
||||
https://youtube.com/bitlunislab
|
||||
https://github.com/bitluni
|
||||
http://bitluni.net
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "../I2S/I2S.h"
|
||||
#include "Mode.h"
|
||||
#include "PinConfig.h"
|
||||
|
||||
class VGA : public I2S
|
||||
{
|
||||
public:
|
||||
VGA(const int i2sIndex = 0);
|
||||
void setLineBufferCount(int lineBufferCount);
|
||||
bool init(const Mode &mode, const int *pinMap, const int bitCount, const int clockPin = -1);
|
||||
virtual bool init(const Mode &mode, const PinConfig &pinConfig) = 0;
|
||||
|
||||
static const Mode MODE320x480;
|
||||
static const Mode MODE320x240;
|
||||
static const Mode MODE320x120;
|
||||
static const Mode MODE320x400;
|
||||
static const Mode MODE320x200;
|
||||
static const Mode MODE360x400;
|
||||
static const Mode MODE360x200;
|
||||
static const Mode MODE360x350;
|
||||
static const Mode MODE360x175;
|
||||
|
||||
static const Mode MODE320x350;
|
||||
static const Mode MODE320x175;
|
||||
|
||||
static const Mode MODE400x300;
|
||||
static const Mode MODE400x150;
|
||||
static const Mode MODE400x100;
|
||||
static const Mode MODE200x150;
|
||||
|
||||
static const Mode MODE500x480;
|
||||
static const Mode MODE500x240;
|
||||
|
||||
static const Mode MODE1280x1024;
|
||||
static const Mode MODE1280x960;
|
||||
static const Mode MODE1280x800;
|
||||
static const Mode MODE1024x768;
|
||||
static const Mode MODE800x600;
|
||||
static const Mode MODE720x400;
|
||||
static const Mode MODE720x350;
|
||||
static const Mode MODE640x480;
|
||||
static const Mode MODE640x400;
|
||||
static const Mode MODE640x350;
|
||||
|
||||
static const PinConfig VGAv01;
|
||||
static const PinConfig VGABlackEdition;
|
||||
static const PinConfig VGAWhiteEdition;
|
||||
static const PinConfig PicoVGA;
|
||||
|
||||
|
||||
Mode mode;
|
||||
|
||||
virtual int bytesPerSample() const = 0;
|
||||
|
||||
protected:
|
||||
|
||||
virtual void initSyncBits() = 0;
|
||||
virtual long syncBits(bool h, bool v) = 0;
|
||||
|
||||
int lineBufferCount;
|
||||
int vsyncPin;
|
||||
int hsyncPin;
|
||||
int currentLine;
|
||||
long vsyncBit;
|
||||
long hsyncBit;
|
||||
long vsyncBitI;
|
||||
long hsyncBitI;
|
||||
|
||||
int totalLines;
|
||||
volatile bool vSyncPassed;
|
||||
|
||||
void *vSyncInactiveBuffer;
|
||||
void *vSyncActiveBuffer;
|
||||
void *inactiveBuffer;
|
||||
void *blankActiveBuffer;
|
||||
|
||||
void allocateLineBuffers(const int lines);
|
||||
virtual void allocateLineBuffers();
|
||||
virtual void allocateLineBuffers(void **frameBuffer);
|
||||
virtual void propagateResolution(const int xres, const int yres) = 0;
|
||||
|
||||
protected:
|
||||
virtual void interrupt();
|
||||
virtual void vSync();
|
||||
virtual void interruptPixelLine(int y, unsigned long *pixels, unsigned long syncBits);
|
||||
};
|
126
libraries/bitluni_ESP32Lib/src/VGA/VGA14Bit.h
Normal file
126
libraries/bitluni_ESP32Lib/src/VGA/VGA14Bit.h
Normal file
|
@ -0,0 +1,126 @@
|
|||
/*
|
||||
Author: bitluni 2019
|
||||
License:
|
||||
Creative Commons Attribution ShareAlike 4.0
|
||||
https://creativecommons.org/licenses/by-sa/4.0/
|
||||
|
||||
For further details check out:
|
||||
https://youtube.com/bitlunislab
|
||||
https://github.com/bitluni
|
||||
http://bitluni.net
|
||||
*/
|
||||
#pragma once
|
||||
#include "VGA.h"
|
||||
#include "../Graphics/GraphicsR5G5B4S2Swapped.h"
|
||||
|
||||
class VGA14Bit : public VGA, public GraphicsR5G5B4S2Swapped
|
||||
{
|
||||
public:
|
||||
VGA14Bit(const int i2sIndex = 1)
|
||||
: VGA(i2sIndex)
|
||||
{
|
||||
}
|
||||
|
||||
bool init(Mode &mode,
|
||||
const int R0Pin, const int R1Pin, const int R2Pin, const int R3Pin, const int R4Pin,
|
||||
const int G0Pin, const int G1Pin, const int G2Pin, const int G3Pin, const int G4Pin,
|
||||
const int B0Pin, const int B1Pin, const int B2Pin, const int B3Pin,
|
||||
const int hsyncPin, const int vsyncPin, const int clockPin = -1)
|
||||
{
|
||||
int pinMap[16] = {
|
||||
R0Pin, R1Pin, R2Pin, R3Pin, R4Pin,
|
||||
G0Pin, G1Pin, G2Pin, G3Pin, G4Pin,
|
||||
B0Pin, B1Pin, B2Pin, B3Pin,
|
||||
hsyncPin, vsyncPin
|
||||
};
|
||||
|
||||
return VGA::init(mode, pinMap, 16, clockPin);
|
||||
}
|
||||
|
||||
bool init(const Mode &mode, const int *redPins, const int *greenPins, const int *bluePins, const int hsyncPin, const int vsyncPin, const int clockPin = -1)
|
||||
{
|
||||
int pinMap[16];
|
||||
for (int i = 0; i < 5; i++)
|
||||
{
|
||||
pinMap[i] = redPins[i];
|
||||
pinMap[i + 5] = greenPins[i];
|
||||
if (i < 4)
|
||||
pinMap[i + 10] = bluePins[i];
|
||||
}
|
||||
pinMap[14] = hsyncPin;
|
||||
pinMap[15] = vsyncPin;
|
||||
return VGA::init(mode, pinMap, 16, clockPin);
|
||||
}
|
||||
|
||||
bool init(const Mode &mode, const PinConfig &pinConfig)
|
||||
{
|
||||
int pins[16];
|
||||
pinConfig.fill14Bit(pins);
|
||||
return VGA::init(mode, pins, 16, pinConfig.clock);
|
||||
}
|
||||
|
||||
virtual void initSyncBits()
|
||||
{
|
||||
hsyncBitI = mode.hSyncPolarity ? 0x4000 : 0;
|
||||
vsyncBitI = mode.vSyncPolarity ? 0x8000 : 0;
|
||||
hsyncBit = hsyncBitI ^ 0x4000;
|
||||
vsyncBit = vsyncBitI ^ 0x8000;
|
||||
SBits = hsyncBitI | vsyncBitI;
|
||||
}
|
||||
|
||||
virtual long syncBits(bool hSync, bool vSync)
|
||||
{
|
||||
return ((hSync ? hsyncBit : hsyncBitI) | (vSync ? vsyncBit : vsyncBitI)) * 0x10001;
|
||||
}
|
||||
|
||||
virtual int bytesPerSample() const
|
||||
{
|
||||
return 2;
|
||||
}
|
||||
|
||||
virtual float pixelAspect() const
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
virtual void propagateResolution(const int xres, const int yres)
|
||||
{
|
||||
setResolution(xres, yres);
|
||||
}
|
||||
|
||||
virtual Color **allocateFrameBuffer()
|
||||
{
|
||||
return (Color **)DMABufferDescriptor::allocateDMABufferArray(yres, mode.hRes * bytesPerSample(), true, syncBits(false, false));
|
||||
}
|
||||
|
||||
virtual void allocateLineBuffers()
|
||||
{
|
||||
VGA::allocateLineBuffers((void **)frameBuffers[0]);
|
||||
}
|
||||
|
||||
virtual void show(bool vSync = false)
|
||||
{
|
||||
if (!frameBufferCount)
|
||||
return;
|
||||
if (vSync)
|
||||
{
|
||||
//TODO read the I2S docs to find out
|
||||
}
|
||||
Graphics::show(vSync);
|
||||
if(dmaBufferDescriptors)
|
||||
for (int i = 0; i < yres * mode.vDiv; i++)
|
||||
dmaBufferDescriptors[(mode.vFront + mode.vSync + mode.vBack + i) * 2 + 1].setBuffer(frontBuffer[i / mode.vDiv], mode.hRes * bytesPerSample());
|
||||
}
|
||||
|
||||
virtual void scroll(int dy, Color color)
|
||||
{
|
||||
Graphics::scroll(dy, color);
|
||||
if (frameBufferCount == 1)
|
||||
show();
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual void interrupt()
|
||||
{
|
||||
}
|
||||
};
|
117
libraries/bitluni_ESP32Lib/src/VGA/VGA14BitI.h
Normal file
117
libraries/bitluni_ESP32Lib/src/VGA/VGA14BitI.h
Normal file
|
@ -0,0 +1,117 @@
|
|||
/*
|
||||
Author: bitluni 2019
|
||||
License:
|
||||
Creative Commons Attribution ShareAlike 4.0
|
||||
https://creativecommons.org/licenses/by-sa/4.0/
|
||||
|
||||
For further details check out:
|
||||
https://youtube.com/bitlunislab
|
||||
https://github.com/bitluni
|
||||
http://bitluni.net
|
||||
*/
|
||||
#pragma once
|
||||
#include "VGA.h"
|
||||
#include "../Graphics/GraphicsR5G5B4A2.h"
|
||||
|
||||
class VGA14BitI : public VGA, public GraphicsR5G5B4A2
|
||||
{
|
||||
public:
|
||||
VGA14BitI(const int i2sIndex = 1)
|
||||
: VGA(i2sIndex)
|
||||
{
|
||||
}
|
||||
|
||||
bool init(const Mode &mode,
|
||||
const int R0Pin, const int R1Pin, const int R2Pin, const int R3Pin, const int R4Pin,
|
||||
const int G0Pin, const int G1Pin, const int G2Pin, const int G3Pin, const int G4Pin,
|
||||
const int B0Pin, const int B1Pin, const int B2Pin, const int B3Pin,
|
||||
const int hsyncPin, const int vsyncPin, const int clockPin = -1)
|
||||
{
|
||||
int pinMap[16] = {
|
||||
R0Pin, R1Pin, R2Pin, R3Pin, R4Pin,
|
||||
G0Pin, G1Pin, G2Pin, G3Pin, G4Pin,
|
||||
B0Pin, B1Pin, B2Pin, B3Pin,
|
||||
hsyncPin, vsyncPin
|
||||
};
|
||||
return VGA::init(mode, pinMap, 16, clockPin);
|
||||
}
|
||||
|
||||
bool init(const Mode &mode, const PinConfig &pinConfig)
|
||||
{
|
||||
int pins[16];
|
||||
pinConfig.fill14Bit(pins);
|
||||
return VGA::init(mode, pins, 16, pinConfig.clock);
|
||||
}
|
||||
|
||||
bool init(const Mode &mode, const int *redPins, const int *greenPins, const int *bluePins, const int hsyncPin, const int vsyncPin, const int clockPin = -1)
|
||||
{
|
||||
int pinMap[16];
|
||||
for (int i = 0; i < 5; i++)
|
||||
{
|
||||
pinMap[i] = redPins[i];
|
||||
pinMap[i + 5] = greenPins[i];
|
||||
if (i < 4)
|
||||
pinMap[i + 10] = bluePins[i];
|
||||
}
|
||||
pinMap[14] = hsyncPin;
|
||||
pinMap[15] = vsyncPin;
|
||||
return VGA::init(mode, pinMap, 16, clockPin);
|
||||
}
|
||||
|
||||
virtual void initSyncBits()
|
||||
{
|
||||
hsyncBitI = mode.hSyncPolarity ? 0x4000 : 0;
|
||||
vsyncBitI = mode.vSyncPolarity ? 0x8000 : 0;
|
||||
hsyncBit = hsyncBitI ^ 0x4000;
|
||||
vsyncBit = vsyncBitI ^ 0x8000;
|
||||
}
|
||||
|
||||
virtual long syncBits(bool hSync, bool vSync)
|
||||
{
|
||||
return ((hSync ? hsyncBit : hsyncBitI) | (vSync ? vsyncBit : vsyncBitI)) * 0x10001;
|
||||
}
|
||||
|
||||
virtual int bytesPerSample() const
|
||||
{
|
||||
return 2;
|
||||
}
|
||||
|
||||
virtual float pixelAspect() const
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
virtual void propagateResolution(const int xres, const int yres)
|
||||
{
|
||||
setResolution(xres, yres);
|
||||
}
|
||||
|
||||
virtual void show(bool vSync = false)
|
||||
{
|
||||
if (!frameBufferCount)
|
||||
return;
|
||||
if (vSync)
|
||||
{
|
||||
vSyncPassed = false;
|
||||
while (!vSyncPassed)
|
||||
delay(0);
|
||||
}
|
||||
Graphics::show(vSync);
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual bool useInterrupt()
|
||||
{
|
||||
return true;
|
||||
};
|
||||
|
||||
void interruptPixelLine(int y, unsigned long *pixels, unsigned long syncBits)
|
||||
{
|
||||
unsigned short *line = frontBuffer[y];
|
||||
for (int i = 0; i < mode.hRes / 2; i++)
|
||||
{
|
||||
//writing two pixels improves speed drastically (avoids memory reads)
|
||||
pixels[i] = syncBits | (line[i * 2 + 1] & 0x3fff) | ((line[i * 2] & 0x3fff) << 16);
|
||||
}
|
||||
}
|
||||
};
|
114
libraries/bitluni_ESP32Lib/src/VGA/VGA3Bit.h
Normal file
114
libraries/bitluni_ESP32Lib/src/VGA/VGA3Bit.h
Normal file
|
@ -0,0 +1,114 @@
|
|||
/*
|
||||
Author: bitluni 2019
|
||||
License:
|
||||
Creative Commons Attribution ShareAlike 4.0
|
||||
https://creativecommons.org/licenses/by-sa/4.0/
|
||||
|
||||
For further details check out:
|
||||
https://youtube.com/bitlunislab
|
||||
https://github.com/bitluni
|
||||
http://bitluni.net
|
||||
*/
|
||||
#pragma once
|
||||
#include "VGA.h"
|
||||
#include "../Graphics/GraphicsR1G1B1A1X2S2Swapped.h"
|
||||
|
||||
class VGA3Bit : public VGA, public GraphicsR1G1B1A1X2S2Swapped
|
||||
{
|
||||
public:
|
||||
VGA3Bit() //8 bit based modes only work with I2S1
|
||||
: VGA(1)
|
||||
{
|
||||
}
|
||||
|
||||
bool init(const Mode &mode, const int RPin, const int GPin, const int BPin, const int hsyncPin, const int vsyncPin, const int clockPin = -1)
|
||||
{
|
||||
int pinMap[8] = {
|
||||
RPin,
|
||||
GPin,
|
||||
BPin,
|
||||
-1, -1, -1,
|
||||
hsyncPin, vsyncPin
|
||||
};
|
||||
|
||||
return VGA::init(mode, pinMap, 8, clockPin);
|
||||
}
|
||||
|
||||
bool init(const Mode &mode, const PinConfig &pinConfig)
|
||||
{
|
||||
int pins[8];
|
||||
pinConfig.fill3Bit(pins);
|
||||
return VGA::init(mode, pins, 8, pinConfig.clock);
|
||||
}
|
||||
|
||||
|
||||
virtual void initSyncBits()
|
||||
{
|
||||
hsyncBitI = mode.hSyncPolarity ? 0x40 : 0;
|
||||
vsyncBitI = mode.vSyncPolarity ? 0x80 : 0;
|
||||
hsyncBit = hsyncBitI ^ 0x40;
|
||||
vsyncBit = vsyncBitI ^ 0x80;
|
||||
SBits = hsyncBitI | vsyncBitI;
|
||||
}
|
||||
|
||||
virtual long syncBits(bool hSync, bool vSync)
|
||||
{
|
||||
return ((hSync ? hsyncBit : hsyncBitI) | (vSync ? vsyncBit : vsyncBitI)) * 0x1010101;
|
||||
}
|
||||
|
||||
virtual int bytesPerSample() const
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
virtual float pixelAspect() const
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
virtual void propagateResolution(const int xres, const int yres)
|
||||
{
|
||||
setResolution(xres, yres);
|
||||
}
|
||||
|
||||
void *vSyncInactiveBuffer;
|
||||
void *vSyncActiveBuffer;
|
||||
void *inactiveBuffer;
|
||||
void *blankActiveBuffer;
|
||||
|
||||
virtual Color **allocateFrameBuffer()
|
||||
{
|
||||
return (Color **)DMABufferDescriptor::allocateDMABufferArray(yres, mode.hRes * bytesPerSample(), true, syncBits(false, false));
|
||||
}
|
||||
|
||||
virtual void allocateLineBuffers()
|
||||
{
|
||||
VGA::allocateLineBuffers((void **)frameBuffers[0]);
|
||||
}
|
||||
|
||||
virtual void show(bool vSync = false)
|
||||
{
|
||||
if (!frameBufferCount)
|
||||
return;
|
||||
if (vSync)
|
||||
{
|
||||
//TODO read the I2S docs to find out
|
||||
}
|
||||
Graphics::show(vSync);
|
||||
if(dmaBufferDescriptors)
|
||||
for (int i = 0; i < yres * mode.vDiv; i++)
|
||||
dmaBufferDescriptors[(mode.vFront + mode.vSync + mode.vBack + i) * 2 + 1].setBuffer(frontBuffer[i / mode.vDiv], mode.hRes * bytesPerSample());
|
||||
}
|
||||
|
||||
virtual void scroll(int dy, Color color)
|
||||
{
|
||||
Graphics::scroll(dy, color);
|
||||
if (frameBufferCount == 1)
|
||||
show();
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual void interrupt()
|
||||
{
|
||||
}
|
||||
};
|
139
libraries/bitluni_ESP32Lib/src/VGA/VGA3BitI.h
Normal file
139
libraries/bitluni_ESP32Lib/src/VGA/VGA3BitI.h
Normal file
|
@ -0,0 +1,139 @@
|
|||
/*
|
||||
Author: bitluni 2019
|
||||
License:
|
||||
Creative Commons Attribution ShareAlike 4.0
|
||||
https://creativecommons.org/licenses/by-sa/4.0/
|
||||
|
||||
For further details check out:
|
||||
https://youtube.com/bitlunislab
|
||||
https://github.com/bitluni
|
||||
http://bitluni.net
|
||||
*/
|
||||
#pragma once
|
||||
#include "VGA.h"
|
||||
#include "../Graphics/GraphicsR1G1B1A1.h"
|
||||
|
||||
class VGA3BitI : public VGA, public GraphicsR1G1B1A1
|
||||
{
|
||||
public:
|
||||
VGA3BitI() //8 bit based modes only work with I2S1
|
||||
: VGA(1)
|
||||
{
|
||||
}
|
||||
|
||||
bool init(const Mode &mode, const int RPin, const int GPin, const int BPin, const int hsyncPin, const int vsyncPin, const int clockPin = -1)
|
||||
{
|
||||
int pinMap[8] = {
|
||||
RPin,
|
||||
GPin,
|
||||
BPin,
|
||||
-1, -1, -1,
|
||||
hsyncPin, vsyncPin
|
||||
};
|
||||
return VGA::init(mode, pinMap, 8, clockPin);
|
||||
}
|
||||
|
||||
bool init(const Mode &mode, const PinConfig &pinConfig)
|
||||
{
|
||||
int pins[8];
|
||||
pinConfig.fill3Bit(pins);
|
||||
return VGA::init(mode, pins, 8, pinConfig.clock);
|
||||
}
|
||||
|
||||
virtual void initSyncBits()
|
||||
{
|
||||
hsyncBitI = mode.hSyncPolarity ? 0x40 : 0;
|
||||
vsyncBitI = mode.vSyncPolarity ? 0x80 : 0;
|
||||
hsyncBit = hsyncBitI ^ 0x40;
|
||||
vsyncBit = vsyncBitI ^ 0x80;
|
||||
}
|
||||
|
||||
virtual long syncBits(bool hSync, bool vSync)
|
||||
{
|
||||
return ((hSync ? hsyncBit : hsyncBitI) | (vSync ? vsyncBit : vsyncBitI)) * 0x1010101;
|
||||
}
|
||||
|
||||
virtual int bytesPerSample() const
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
virtual float pixelAspect() const
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
virtual void propagateResolution(const int xres, const int yres)
|
||||
{
|
||||
setResolution(xres, yres);
|
||||
}
|
||||
|
||||
virtual void show(bool vSync = false)
|
||||
{
|
||||
if (!frameBufferCount)
|
||||
return;
|
||||
if (vSync)
|
||||
{
|
||||
vSyncPassed = false;
|
||||
while (!vSyncPassed)
|
||||
delay(0);
|
||||
}
|
||||
Graphics::show(vSync);
|
||||
}
|
||||
|
||||
protected:
|
||||
bool useInterrupt()
|
||||
{
|
||||
return true;
|
||||
};
|
||||
|
||||
void interrupt()
|
||||
{
|
||||
unsigned long *signal = (unsigned long *)dmaBufferDescriptors[dmaBufferDescriptorActive].buffer();
|
||||
unsigned long *pixels = &((unsigned long *)dmaBufferDescriptors[dmaBufferDescriptorActive].buffer())[(mode.hSync + mode.hBack) / 4];
|
||||
unsigned long base, baseh;
|
||||
if (currentLine >= mode.vFront && currentLine < mode.vFront + mode.vSync)
|
||||
{
|
||||
baseh = syncBits(true, true);
|
||||
base = syncBits(false, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
baseh = syncBits(true, false);
|
||||
base = syncBits(false, false);
|
||||
}
|
||||
for (int i = 0; i < mode.hSync / 4; i++)
|
||||
signal[i] = baseh;
|
||||
for (int i = mode.hSync / 4; i < (mode.hSync + mode.hBack) / 4; i++)
|
||||
signal[i] = base;
|
||||
|
||||
int y = (currentLine - mode.vFront - mode.vSync - mode.vBack) / mode.vDiv;
|
||||
if (y >= 0 && y < mode.vRes)
|
||||
interruptPixelLine(y, pixels, base);
|
||||
else
|
||||
for (int i = 0; i < mode.hRes / 4; i++)
|
||||
{
|
||||
pixels[i] = base;
|
||||
}
|
||||
for (int i = 0; i < mode.hFront / 4; i++)
|
||||
signal[i + (mode.hSync + mode.hBack + mode.hRes) / 4] = base;
|
||||
currentLine = (currentLine + 1) % totalLines;
|
||||
dmaBufferDescriptorActive = (dmaBufferDescriptorActive + 1) % dmaBufferDescriptorCount;
|
||||
if (currentLine == 0)
|
||||
vSync();
|
||||
}
|
||||
|
||||
void interruptPixelLine(int y, unsigned long *pixels, unsigned long syncBits)
|
||||
{
|
||||
unsigned char *line = frontBuffer[y];
|
||||
int j = 0;
|
||||
for (int i = 0; i < mode.hRes / 4; i++)
|
||||
{
|
||||
int p0 = (line[j] >> 0) & 7;
|
||||
int p1 = (line[j++] >> 4) & 7;
|
||||
int p2 = (line[j] >> 0) & 7;
|
||||
int p3 = (line[j++] >> 4) & 7;
|
||||
pixels[i] = syncBits | (p2 << 0) | (p3 << 8) | (p0 << 16) | (p1 << 24);
|
||||
}
|
||||
}
|
||||
};
|
131
libraries/bitluni_ESP32Lib/src/VGA/VGA6Bit.h
Normal file
131
libraries/bitluni_ESP32Lib/src/VGA/VGA6Bit.h
Normal file
|
@ -0,0 +1,131 @@
|
|||
/*
|
||||
Author: bitluni 2019
|
||||
License:
|
||||
Creative Commons Attribution ShareAlike 4.0
|
||||
https://creativecommons.org/licenses/by-sa/4.0/
|
||||
|
||||
For further details check out:
|
||||
https://youtube.com/bitlunislab
|
||||
https://github.com/bitluni
|
||||
http://bitluni.net
|
||||
*/
|
||||
#pragma once
|
||||
#include "VGA.h"
|
||||
#include "../Graphics/GraphicsR2G2B2S2Swapped.h"
|
||||
|
||||
class VGA6Bit : public VGA, public GraphicsR2G2B2S2Swapped
|
||||
{
|
||||
public:
|
||||
VGA6Bit() //8 bit based modes only work with I2S1
|
||||
: VGA(1)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
bool init(Mode &mode,
|
||||
const int R0Pin, const int R1Pin,
|
||||
const int G0Pin, const int G1Pin,
|
||||
const int B0Pin, const int B1Pin,
|
||||
const int hsyncPin, const int vsyncPin, const int clockPin = -1)
|
||||
{
|
||||
int pinMap[8] = {
|
||||
R0Pin, R1Pin,
|
||||
G0Pin, G1Pin,
|
||||
B0Pin, B1Pin,
|
||||
hsyncPin, vsyncPin
|
||||
};
|
||||
|
||||
return VGA::init(mode, pinMap, 8, clockPin);
|
||||
}
|
||||
|
||||
bool init(const Mode &mode, const int *redPins, const int *greenPins, const int *bluePins, const int hsyncPin, const int vsyncPin, const int clockPin = -1)
|
||||
{
|
||||
int pinMap[8];
|
||||
for (int i = 0; i < 2; i++)
|
||||
{
|
||||
pinMap[i] = redPins[i];
|
||||
pinMap[i + 2] = greenPins[i];
|
||||
pinMap[i + 4] = bluePins[i];
|
||||
}
|
||||
pinMap[6] = hsyncPin;
|
||||
pinMap[7] = vsyncPin;
|
||||
return VGA::init(mode, pinMap, 8, clockPin);
|
||||
}
|
||||
|
||||
bool init(const Mode &mode, const PinConfig &pinConfig)
|
||||
{
|
||||
int pins[8];
|
||||
pinConfig.fill6Bit(pins);
|
||||
return VGA::init(mode, pins, 8, pinConfig.clock);
|
||||
}
|
||||
|
||||
virtual void initSyncBits()
|
||||
{
|
||||
hsyncBitI = mode.hSyncPolarity ? 0x40 : 0;
|
||||
vsyncBitI = mode.vSyncPolarity ? 0x80 : 0;
|
||||
hsyncBit = hsyncBitI ^ 0x40;
|
||||
vsyncBit = vsyncBitI ^ 0x80;
|
||||
SBits = hsyncBitI | vsyncBitI;
|
||||
}
|
||||
|
||||
virtual long syncBits(bool hSync, bool vSync)
|
||||
{
|
||||
return ((hSync ? hsyncBit : hsyncBitI) | (vSync ? vsyncBit : vsyncBitI)) * 0x1010101;
|
||||
}
|
||||
|
||||
virtual int bytesPerSample() const
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
virtual float pixelAspect() const
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
virtual void propagateResolution(const int xres, const int yres)
|
||||
{
|
||||
setResolution(xres, yres);
|
||||
}
|
||||
|
||||
void *vSyncInactiveBuffer;
|
||||
void *vSyncActiveBuffer;
|
||||
void *inactiveBuffer;
|
||||
void *blankActiveBuffer;
|
||||
|
||||
virtual Color **allocateFrameBuffer()
|
||||
{
|
||||
return (Color **)DMABufferDescriptor::allocateDMABufferArray(yres, mode.hRes * bytesPerSample(), true, syncBits(false, false));
|
||||
}
|
||||
|
||||
virtual void allocateLineBuffers()
|
||||
{
|
||||
VGA::allocateLineBuffers((void **)frameBuffers[0]);
|
||||
}
|
||||
|
||||
virtual void show(bool vSync = false)
|
||||
{
|
||||
if (!frameBufferCount)
|
||||
return;
|
||||
if (vSync)
|
||||
{
|
||||
//TODO read the I2S docs to find out
|
||||
}
|
||||
Graphics::show(vSync);
|
||||
if(dmaBufferDescriptors)
|
||||
for (int i = 0; i < yres * mode.vDiv; i++)
|
||||
dmaBufferDescriptors[(mode.vFront + mode.vSync + mode.vBack + i) * 2 + 1].setBuffer(frontBuffer[i / mode.vDiv], mode.hRes * bytesPerSample());
|
||||
}
|
||||
|
||||
virtual void scroll(int dy, Color color)
|
||||
{
|
||||
Graphics::scroll(dy, color);
|
||||
if (frameBufferCount == 1)
|
||||
show();
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual void interrupt()
|
||||
{
|
||||
}
|
||||
};
|
157
libraries/bitluni_ESP32Lib/src/VGA/VGA6BitI.h
Normal file
157
libraries/bitluni_ESP32Lib/src/VGA/VGA6BitI.h
Normal file
|
@ -0,0 +1,157 @@
|
|||
/*
|
||||
Author: bitluni 2019
|
||||
License:
|
||||
Creative Commons Attribution ShareAlike 4.0
|
||||
https://creativecommons.org/licenses/by-sa/4.0/
|
||||
|
||||
For further details check out:
|
||||
https://youtube.com/bitlunislab
|
||||
https://github.com/bitluni
|
||||
http://bitluni.net
|
||||
*/
|
||||
#pragma once
|
||||
#include "VGA.h"
|
||||
#include "../Graphics/GraphicsR2G2B2A2.h"
|
||||
|
||||
class VGA6BitI : public VGA, public GraphicsR2G2B2A2
|
||||
{
|
||||
public:
|
||||
VGA6BitI() //8 bit based modes only work with I2S1
|
||||
: VGA(1)
|
||||
{
|
||||
}
|
||||
|
||||
bool init(Mode &mode,
|
||||
const int R0Pin, const int R1Pin,
|
||||
const int G0Pin, const int G1Pin,
|
||||
const int B0Pin, const int B1Pin,
|
||||
const int hsyncPin, const int vsyncPin, const int clockPin = -1)
|
||||
{
|
||||
int pinMap[8] = {
|
||||
R0Pin, R1Pin,
|
||||
G0Pin, G1Pin,
|
||||
B0Pin, B1Pin,
|
||||
hsyncPin, vsyncPin
|
||||
};
|
||||
|
||||
return VGA::init(mode, pinMap, 8, clockPin);
|
||||
}
|
||||
|
||||
bool init(const Mode &mode, const int *redPins, const int *greenPins, const int *bluePins, const int hsyncPin, const int vsyncPin, const int clockPin = -1)
|
||||
{
|
||||
int pinMap[8];
|
||||
for (int i = 0; i < 2; i++)
|
||||
{
|
||||
pinMap[i] = redPins[i];
|
||||
pinMap[i + 2] = greenPins[i];
|
||||
pinMap[i + 4] = bluePins[i];
|
||||
}
|
||||
pinMap[6] = hsyncPin;
|
||||
pinMap[7] = vsyncPin;
|
||||
return VGA::init(mode, pinMap, 8, clockPin);
|
||||
}
|
||||
|
||||
bool init(const Mode &mode, const PinConfig &pinConfig)
|
||||
{
|
||||
int pins[8];
|
||||
pinConfig.fill6Bit(pins);
|
||||
return VGA::init(mode, pins, 8, pinConfig.clock);
|
||||
}
|
||||
|
||||
virtual void initSyncBits()
|
||||
{
|
||||
hsyncBitI = mode.hSyncPolarity ? 0x40 : 0;
|
||||
vsyncBitI = mode.vSyncPolarity ? 0x80 : 0;
|
||||
hsyncBit = hsyncBitI ^ 0x40;
|
||||
vsyncBit = vsyncBitI ^ 0x80;
|
||||
}
|
||||
|
||||
virtual long syncBits(bool hSync, bool vSync)
|
||||
{
|
||||
return ((hSync ? hsyncBit : hsyncBitI) | (vSync ? vsyncBit : vsyncBitI)) * 0x1010101;
|
||||
}
|
||||
|
||||
virtual int bytesPerSample() const
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
virtual float pixelAspect() const
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
virtual void propagateResolution(const int xres, const int yres)
|
||||
{
|
||||
setResolution(xres, yres);
|
||||
}
|
||||
|
||||
virtual void show(bool vSync = false)
|
||||
{
|
||||
if (!frameBufferCount)
|
||||
return;
|
||||
if (vSync)
|
||||
{
|
||||
vSyncPassed = false;
|
||||
while (!vSyncPassed)
|
||||
delay(0);
|
||||
}
|
||||
Graphics::show(vSync);
|
||||
}
|
||||
|
||||
protected:
|
||||
bool useInterrupt()
|
||||
{
|
||||
return true;
|
||||
};
|
||||
|
||||
void interrupt()
|
||||
{
|
||||
unsigned long *signal = (unsigned long *)dmaBufferDescriptors[dmaBufferDescriptorActive].buffer();
|
||||
unsigned long *pixels = &((unsigned long *)dmaBufferDescriptors[dmaBufferDescriptorActive].buffer())[(mode.hSync + mode.hBack) / 4];
|
||||
unsigned long base, baseh;
|
||||
if (currentLine >= mode.vFront && currentLine < mode.vFront + mode.vSync)
|
||||
{
|
||||
baseh = syncBits(true, true);
|
||||
base = syncBits(false, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
baseh = syncBits(true, false);
|
||||
base = syncBits(false, false);
|
||||
}
|
||||
for (int i = 0; i < mode.hSync / 4; i++)
|
||||
signal[i] = baseh;
|
||||
for (int i = mode.hSync / 4; i < (mode.hSync + mode.hBack) / 4; i++)
|
||||
signal[i] = base;
|
||||
|
||||
int y = (currentLine - mode.vFront - mode.vSync - mode.vBack) / mode.vDiv;
|
||||
if (y >= 0 && y < mode.vRes)
|
||||
interruptPixelLine(y, pixels, base);
|
||||
else
|
||||
for (int i = 0; i < mode.hRes / 4; i++)
|
||||
{
|
||||
pixels[i] = base;
|
||||
}
|
||||
for (int i = 0; i < mode.hFront / 4; i++)
|
||||
signal[i + (mode.hSync + mode.hBack + mode.hRes) / 4] = base;
|
||||
currentLine = (currentLine + 1) % totalLines;
|
||||
dmaBufferDescriptorActive = (dmaBufferDescriptorActive + 1) % dmaBufferDescriptorCount;
|
||||
if (currentLine == 0)
|
||||
vSync();
|
||||
}
|
||||
|
||||
void interruptPixelLine(int y, unsigned long *pixels, unsigned long syncBits)
|
||||
{
|
||||
unsigned char *line = frontBuffer[y];
|
||||
int j = 0;
|
||||
for (int i = 0; i < mode.hRes / 4; i++)
|
||||
{
|
||||
int p0 = (line[j] >> 0) & 7;
|
||||
int p1 = (line[j++] >> 4) & 7;
|
||||
int p2 = (line[j] >> 0) & 7;
|
||||
int p3 = (line[j++] >> 4) & 7;
|
||||
pixels[i] = syncBits | (p2 << 0) | (p3 << 8) | (p0 << 16) | (p1 << 24);
|
||||
}
|
||||
}
|
||||
};
|
Loading…
Add table
Add a link
Reference in a new issue