Co-authored-by: raphaelcoeffic <1050031+raphaelcoeffic@users.noreply.github.com> Co-authored-by: Malte Langermann <malte@langermann.net>
140 lines
3.7 KiB
C++
140 lines
3.7 KiB
C++
/*
|
|
* Copyright (C) EdgeTX
|
|
*
|
|
* Based on code named
|
|
* opentx - https://github.com/opentx/opentx
|
|
* th9x - http://code.google.com/p/th9x
|
|
* er9x - http://code.google.com/p/er9x
|
|
* gruvin9x - http://code.google.com/p/gruvin9x
|
|
*
|
|
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License version 2 as
|
|
* published by the Free Software Foundation.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*/
|
|
|
|
#include "display.h"
|
|
#include "simu.h"
|
|
|
|
static void _set_pixel(uint8_t* pixel, const SDL_Color& color)
|
|
{
|
|
pixel[0] = color.a;
|
|
pixel[1] = color.b;
|
|
pixel[2] = color.g;
|
|
pixel[3] = color.r;
|
|
}
|
|
|
|
static void _blit_simu_screen_color(void* screen_buffer, Uint32 format, int w, int h, int pitch)
|
|
{
|
|
pixel_t* src_buffer = simuLcdBuf;
|
|
uint8_t* line_buffer = (uint8_t*)screen_buffer;
|
|
|
|
for (int y = 0; y < h; y++) {
|
|
for (int x = 0; x < w; x++) {
|
|
pixel_t z = *src_buffer++;
|
|
// Alpha
|
|
line_buffer[0] = SDL_ALPHA_OPAQUE;
|
|
// Blue
|
|
line_buffer[1] = (((z & 0x001F) << 3) & 0x00F8) + ((z & 0x001C) >> 2);
|
|
// Green
|
|
line_buffer[2] = ((z & 0x07E0) >> 3) + ((z & 0x0600) >> 9);
|
|
// Red
|
|
line_buffer[3] = ((z & 0xF800) >> 8) + ((z & 0xE000) >> 13);
|
|
line_buffer += SDL_BYTESPERPIXEL(format);
|
|
}
|
|
}
|
|
}
|
|
|
|
static void _blit_simu_screen_1bit(void* screen_buffer, Uint32 format, int w, int h, int pitch)
|
|
{
|
|
const SDL_Color on_color = {.r = 0, .g = 0, .b = 0};
|
|
|
|
uint8_t* line_buffer = (uint8_t*)screen_buffer;
|
|
|
|
for (int y = 0; y < h; y++) {
|
|
for (int x = 0; x < w; x++) {
|
|
SDL_Color c = on_color;
|
|
if (simuLcdBuf[x + (y / 8) * w] & (1 << (y % 8))) {
|
|
c.a = SDL_ALPHA_OPAQUE;
|
|
} else {
|
|
c.a = SDL_ALPHA_TRANSPARENT;
|
|
}
|
|
_set_pixel(line_buffer, c);
|
|
line_buffer += SDL_BYTESPERPIXEL(format);
|
|
}
|
|
}
|
|
}
|
|
|
|
// static inline uint8_t _4bit_blend(uint16_t px, uint16_t bg)
|
|
// {
|
|
// uint16_t c = bg * (16 - px);
|
|
// return c / 16;
|
|
// }
|
|
|
|
static void _blit_simu_screen_4bit(void* screen_buffer, Uint32 format, int w, int h, int pitch)
|
|
{
|
|
const SDL_Color on_color = {.r = 0, .g = 0, .b = 0};
|
|
|
|
uint8_t* line_buffer = (uint8_t*)screen_buffer;
|
|
|
|
for (int y = 0; y < h; y++) {
|
|
for (int x = 0; x < w; x++) {
|
|
|
|
pixel_t p = simuLcdBuf[y / 2 * LCD_W + x];
|
|
uint8_t z = (y & 1) ? (p >> 4) : (p & 0x0F);
|
|
|
|
SDL_Color c = on_color;
|
|
c.a = (uint16_t)z * SDL_ALPHA_OPAQUE / 16;
|
|
|
|
_set_pixel(line_buffer, c);
|
|
line_buffer += SDL_BYTESPERPIXEL(format);
|
|
}
|
|
}
|
|
}
|
|
|
|
void refreshDisplay(SDL_Texture* screen)
|
|
{
|
|
if (simuLcdRefresh) {
|
|
|
|
// fetch texture format
|
|
Uint32 format = 0;
|
|
int width = 0, height = 0;
|
|
|
|
if (SDL_QueryTexture(screen, &format, nullptr, &width, &height) != 0) {
|
|
SDL_Log("SDL_QueryTexture: %s", SDL_GetError());
|
|
return;
|
|
}
|
|
|
|
// raw pixel buffer
|
|
void* screen_buffer = nullptr;
|
|
|
|
// length of one row in bytes
|
|
int pitch = 0;
|
|
|
|
if (SDL_LockTexture(screen, nullptr, &screen_buffer, &pitch) != 0) {
|
|
SDL_Log("SDL_LockTexture: %s", SDL_GetError());
|
|
return;
|
|
}
|
|
|
|
if (LCD_DEPTH == 1) {
|
|
_blit_simu_screen_1bit(screen_buffer, format, width, height, pitch);
|
|
} else if (LCD_DEPTH == 4) {
|
|
_blit_simu_screen_4bit(screen_buffer, format, width, height, pitch);
|
|
} else if (LCD_DEPTH == 16) {
|
|
_blit_simu_screen_color(screen_buffer, format, width, height, pitch);
|
|
}
|
|
|
|
SDL_UnlockTexture(screen);
|
|
simuLcdRefresh = false;
|
|
lcdFlushed();
|
|
}
|
|
}
|
|
|
|
|