forked from jaildesigner-jailgames/jaildoctors_dilemma
Compare commits
5 Commits
29a2ebf221
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
| 908ffa6d55 | |||
| d230259e42 | |||
| a61c2e8d46 | |||
| 9bb9d26417 | |||
| a96ce4afc9 |
30
source/common/destsurface.cpp
Normal file
30
source/common/destsurface.cpp
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
#include "destsurface.h"
|
||||||
|
#include "systempalette.h"
|
||||||
|
|
||||||
|
namespace DestSurface
|
||||||
|
{
|
||||||
|
uint8_t *pixels = nullptr;
|
||||||
|
int width, height;
|
||||||
|
|
||||||
|
void init(int width, int height)
|
||||||
|
{
|
||||||
|
if (pixels==nullptr) pixels = new uint8_t[width*height];
|
||||||
|
DestSurface::width = width;
|
||||||
|
DestSurface::height = height;
|
||||||
|
}
|
||||||
|
|
||||||
|
void clear(uint32_t color)
|
||||||
|
{
|
||||||
|
SDL_memset(pixels, SystemPalette::getEntry(color), width*height);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t *getPixels()
|
||||||
|
{
|
||||||
|
return pixels;
|
||||||
|
}
|
||||||
|
|
||||||
|
int getWidth()
|
||||||
|
{
|
||||||
|
return width;
|
||||||
|
}
|
||||||
|
}
|
||||||
14
source/common/destsurface.h
Normal file
14
source/common/destsurface.h
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <SDL2/SDL.h>
|
||||||
|
|
||||||
|
namespace DestSurface
|
||||||
|
{
|
||||||
|
void init(int width, int height);
|
||||||
|
|
||||||
|
void clear(uint32_t color);
|
||||||
|
|
||||||
|
uint8_t *getPixels();
|
||||||
|
|
||||||
|
int getWidth();
|
||||||
|
}
|
||||||
@@ -1,6 +1,8 @@
|
|||||||
#include "screen.h"
|
#include "screen.h"
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
#include "destsurface.h"
|
||||||
|
#include "systempalette.h"
|
||||||
|
|
||||||
// Constructor
|
// Constructor
|
||||||
Screen::Screen(SDL_Window *window, SDL_Renderer *renderer, Asset *asset, options_t *options)
|
Screen::Screen(SDL_Window *window, SDL_Renderer *renderer, Asset *asset, options_t *options)
|
||||||
@@ -28,7 +30,7 @@ Screen::Screen(SDL_Window *window, SDL_Renderer *renderer, Asset *asset, options
|
|||||||
borderColor = {0x00, 0x00, 0x00};
|
borderColor = {0x00, 0x00, 0x00};
|
||||||
|
|
||||||
// Crea la textura donde se dibujan los graficos del juego
|
// Crea la textura donde se dibujan los graficos del juego
|
||||||
gameCanvas = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, gameCanvasWidth, gameCanvasHeight);
|
gameCanvas = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_STREAMING, gameCanvasWidth, gameCanvasHeight);
|
||||||
if (gameCanvas == nullptr)
|
if (gameCanvas == nullptr)
|
||||||
{
|
{
|
||||||
if (options->console)
|
if (options->console)
|
||||||
@@ -37,6 +39,8 @@ Screen::Screen(SDL_Window *window, SDL_Renderer *renderer, Asset *asset, options
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DestSurface::init(gameCanvasWidth, gameCanvasHeight);
|
||||||
|
|
||||||
// Establece el modo de video
|
// Establece el modo de video
|
||||||
setVideoMode(options->videoMode);
|
setVideoMode(options->videoMode);
|
||||||
|
|
||||||
@@ -53,26 +57,34 @@ Screen::~Screen()
|
|||||||
// Limpia la pantalla
|
// Limpia la pantalla
|
||||||
void Screen::clean(color_t color)
|
void Screen::clean(color_t color)
|
||||||
{
|
{
|
||||||
SDL_SetRenderDrawColor(renderer, color.r, color.g, color.b, 0xFF);
|
DestSurface::clear((color.r<<24) + (color.g<<16) + (color.b<<8) + 255);
|
||||||
SDL_RenderClear(renderer);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Prepara para empezar a dibujar en la textura de juego
|
// Prepara para empezar a dibujar en la textura de juego
|
||||||
void Screen::start()
|
void Screen::start()
|
||||||
{
|
{
|
||||||
SDL_SetRenderTarget(renderer, gameCanvas);
|
//SDL_SetRenderTarget(renderer, gameCanvas);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Vuelca el contenido del renderizador en pantalla
|
// Vuelca el contenido del renderizador en pantalla
|
||||||
void Screen::blit()
|
void Screen::blit()
|
||||||
{
|
{
|
||||||
// Vuelve a dejar el renderizador en modo normal
|
// Vuelve a dejar el renderizador en modo normal
|
||||||
SDL_SetRenderTarget(renderer, nullptr);
|
//SDL_SetRenderTarget(renderer, nullptr);
|
||||||
|
|
||||||
// Borra el contenido previo
|
// Borra el contenido previo
|
||||||
SDL_SetRenderDrawColor(renderer, borderColor.r, borderColor.g, borderColor.b, 0xFF);
|
SDL_SetRenderDrawColor(renderer, borderColor.r, borderColor.g, borderColor.b, 0xFF);
|
||||||
SDL_RenderClear(renderer);
|
SDL_RenderClear(renderer);
|
||||||
|
|
||||||
|
uint8_t *destSurface = DestSurface::getPixels();
|
||||||
|
|
||||||
|
Uint32 *pixels;
|
||||||
|
int pitch;
|
||||||
|
int size = gameCanvasWidth*gameCanvasHeight;
|
||||||
|
SDL_LockTexture(gameCanvas, NULL, (void**)&pixels, &pitch);
|
||||||
|
for (int i=0;i<size;++i) pixels[i] = SystemPalette::getRGBA(destSurface[i]);
|
||||||
|
SDL_UnlockTexture(gameCanvas);
|
||||||
|
|
||||||
// Copia la textura de juego en el renderizador en la posición adecuada
|
// Copia la textura de juego en el renderizador en la posición adecuada
|
||||||
SDL_RenderCopy(renderer, gameCanvas, nullptr, &dest);
|
SDL_RenderCopy(renderer, gameCanvas, nullptr, &dest);
|
||||||
|
|
||||||
|
|||||||
60
source/common/systempalette.cpp
Normal file
60
source/common/systempalette.cpp
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
#include "systempalette.h"
|
||||||
|
|
||||||
|
namespace SystemPalette
|
||||||
|
{
|
||||||
|
|
||||||
|
uint32_t entries[256]; // Las 256 entradas de la paleta
|
||||||
|
uint8_t numEntries; // El número de entradas existente actualmente
|
||||||
|
|
||||||
|
// Vacía la paleta
|
||||||
|
void Clear()
|
||||||
|
{
|
||||||
|
// Fijamos el color transparente en 0 y el blanco en 1
|
||||||
|
entries[0] = 0x00000000; // Transparente
|
||||||
|
entries[1] = 0xffffffff; // Blanco
|
||||||
|
|
||||||
|
numEntries = 2;
|
||||||
|
|
||||||
|
// Ya que 'getRGBA' no comprueba que el índice solicitado sea menor que
|
||||||
|
// 'numentries', rellenamos con 'negro' todas las entradas no usadas.
|
||||||
|
for (int i = 2; i < 256; ++i ) entries[i] = 0x000000ff;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Obtenemos el índice de la paleta para el color especificado. Si no existe se crea.
|
||||||
|
uint8_t getEntry(const uint32_t color)
|
||||||
|
{
|
||||||
|
// ATENCIÓN!!! Si intentamos introducir más de 256 colores empezará a
|
||||||
|
// sobreescribir los primeros colores. Al menos no corromperá la
|
||||||
|
// memoria. Pensar la mejor forma de controlar esto.
|
||||||
|
|
||||||
|
// Recorremos la paleta...
|
||||||
|
for (int i = 0; i < numEntries; ++i)
|
||||||
|
{
|
||||||
|
// Si encontramos el color, devolvemos su índice y salimos
|
||||||
|
if (entries[i] == color) return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Si no se ha encontrado, lo ponemos al final
|
||||||
|
entries[numEntries] = color;
|
||||||
|
|
||||||
|
// Y devolvemos su índice
|
||||||
|
return numEntries++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Versión de getEntry para obtener el color con los componentes R, G y B
|
||||||
|
uint8_t getEntry(const uint8_t r, const uint8_t g, const uint8_t b)
|
||||||
|
{
|
||||||
|
return getEntry( (r<<24) + (g<<16) + (b<<8) + 255 );
|
||||||
|
}
|
||||||
|
|
||||||
|
// Dado un índice, devolvemos su color
|
||||||
|
uint32_t getRGBA(const uint8_t entry)
|
||||||
|
{
|
||||||
|
// ATENCIÓN!!! No compruebo que el parámetro 'entry' sea menor que el
|
||||||
|
// miembro 'numEntries', por lo que se puede acceder a colores no
|
||||||
|
// definidos (por ejemplo tener 4 colores y acceder al color 8). La
|
||||||
|
// razón es que necesito que esta función sea lo más rápida posible.
|
||||||
|
// En cualquier caso, nunca se va a salir de la memoria ni nada raro.
|
||||||
|
return entries[entry];
|
||||||
|
}
|
||||||
|
}
|
||||||
17
source/common/systempalette.h
Normal file
17
source/common/systempalette.h
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
#pragma once
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
namespace SystemPalette
|
||||||
|
{
|
||||||
|
// Vacía la paleta
|
||||||
|
void Clear();
|
||||||
|
|
||||||
|
// Obtenemos el índice de la paleta para el color especificado. Si no existe se crea.
|
||||||
|
uint8_t getEntry(const uint32_t color);
|
||||||
|
|
||||||
|
// Versión de getEntry para obtener el color con los componentes R, G y B
|
||||||
|
uint8_t getEntry(const uint8_t r, const uint8_t g, const uint8_t b);
|
||||||
|
|
||||||
|
// Dado un índice, devolvemos su color
|
||||||
|
uint32_t getRGBA(const uint8_t entry);
|
||||||
|
}
|
||||||
@@ -3,6 +3,8 @@
|
|||||||
#define STB_IMAGE_IMPLEMENTATION
|
#define STB_IMAGE_IMPLEMENTATION
|
||||||
#include "stb_image.h"
|
#include "stb_image.h"
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
#include "systempalette.h"
|
||||||
|
#include "destsurface.h"
|
||||||
|
|
||||||
// Constructor
|
// Constructor
|
||||||
Texture::Texture(SDL_Renderer *renderer, std::string path, bool verbose)
|
Texture::Texture(SDL_Renderer *renderer, std::string path, bool verbose)
|
||||||
@@ -12,14 +14,15 @@ Texture::Texture(SDL_Renderer *renderer, std::string path, bool verbose)
|
|||||||
this->path = path;
|
this->path = path;
|
||||||
|
|
||||||
// Inicializa
|
// Inicializa
|
||||||
texture = nullptr;
|
this->pixels = nullptr;
|
||||||
width = 0;
|
this->width = 0;
|
||||||
height = 0;
|
this->height = 0;
|
||||||
|
this->color = 0xffffffff;
|
||||||
|
|
||||||
// Carga el fichero en la textura
|
// Carga el fichero en la textura
|
||||||
if (path != "")
|
if (path != "")
|
||||||
{
|
{
|
||||||
loadFromFile(path, renderer, verbose);
|
loadFromFile(path, verbose);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -31,7 +34,7 @@ Texture::~Texture()
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Carga una imagen desde un fichero
|
// Carga una imagen desde un fichero
|
||||||
bool Texture::loadFromFile(std::string path, SDL_Renderer *renderer, bool verbose)
|
bool Texture::loadFromFile(std::string path, bool verbose)
|
||||||
{
|
{
|
||||||
const std::string filename = path.substr(path.find_last_of("\\/") + 1);
|
const std::string filename = path.substr(path.find_last_of("\\/") + 1);
|
||||||
int req_format = STBI_rgb_alpha;
|
int req_format = STBI_rgb_alpha;
|
||||||
@@ -50,90 +53,39 @@ bool Texture::loadFromFile(std::string path, SDL_Renderer *renderer, bool verbos
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int depth, pitch;
|
|
||||||
Uint32 pixel_format;
|
|
||||||
if (req_format == STBI_rgb)
|
|
||||||
{
|
|
||||||
depth = 24;
|
|
||||||
pitch = 3 * width; // 3 bytes por pixel * pixels per linea
|
|
||||||
pixel_format = SDL_PIXELFORMAT_RGB24;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{ // STBI_rgb_alpha (RGBA)
|
|
||||||
depth = 32;
|
|
||||||
pitch = 4 * width;
|
|
||||||
pixel_format = SDL_PIXELFORMAT_RGBA32;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Limpia
|
// Limpia
|
||||||
unload();
|
unload();
|
||||||
|
|
||||||
// La textura final
|
this->width = width;
|
||||||
SDL_Texture *newTexture = nullptr;
|
this->height = height;
|
||||||
|
const int size = width*height;
|
||||||
// Carga la imagen desde una ruta específica
|
this->pixels = new uint8_t[size];
|
||||||
SDL_Surface *loadedSurface = SDL_CreateRGBSurfaceWithFormatFrom((void *)data, width, height, depth, pitch, pixel_format);
|
for (int i = 0; i < size; ++i) this->pixels[i] = SystemPalette::getEntry(data[i]);
|
||||||
if (loadedSurface == nullptr)
|
|
||||||
{
|
|
||||||
if (verbose)
|
|
||||||
{
|
|
||||||
std::cout << "Unable to load image " << path.c_str() << std::endl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Crea la textura desde los pixels de la surface
|
|
||||||
newTexture = SDL_CreateTextureFromSurface(renderer, loadedSurface);
|
|
||||||
if (newTexture == nullptr)
|
|
||||||
{
|
|
||||||
if (verbose)
|
|
||||||
{
|
|
||||||
std::cout << "Unable to create texture from " << path.c_str() << "! SDL Error: " << SDL_GetError() << std::endl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Obtiene las dimensiones de la imagen
|
|
||||||
this->width = loadedSurface->w;
|
|
||||||
this->height = loadedSurface->h;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Elimina la textura cargada
|
|
||||||
SDL_FreeSurface(loadedSurface);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Return success
|
// Return success
|
||||||
stbi_image_free(data);
|
stbi_image_free(data);
|
||||||
texture = newTexture;
|
return this->pixels != nullptr;
|
||||||
return texture != nullptr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Crea una textura en blanco
|
// Crea una textura en blanco
|
||||||
bool Texture::createBlank(SDL_Renderer *renderer, int width, int height, SDL_TextureAccess access)
|
bool Texture::createBlank(SDL_Renderer *renderer, int width, int height, SDL_TextureAccess access)
|
||||||
{
|
{
|
||||||
// Crea una textura sin inicializar
|
// Crea una textura sin inicializar
|
||||||
texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA8888, access, width, height);
|
this->pixels = new uint8_t[width*height];
|
||||||
if (texture == nullptr)
|
this->width = width;
|
||||||
{
|
this->height = height;
|
||||||
std::cout << "Unable to create blank texture! SDL Error: " << SDL_GetError() << std::endl;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
this->width = width;
|
|
||||||
this->height = height;
|
|
||||||
}
|
|
||||||
|
|
||||||
return texture != nullptr;
|
return this->pixels != nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Libera la memoria de la textura
|
// Libera la memoria de la textura
|
||||||
void Texture::unload()
|
void Texture::unload()
|
||||||
{
|
{
|
||||||
// Libera la textura si existe
|
// Libera la textura si existe
|
||||||
if (texture != nullptr)
|
if (pixels != nullptr)
|
||||||
{
|
{
|
||||||
SDL_DestroyTexture(texture);
|
delete[] pixels;
|
||||||
texture = nullptr;
|
pixels = nullptr;
|
||||||
width = 0;
|
width = 0;
|
||||||
height = 0;
|
height = 0;
|
||||||
}
|
}
|
||||||
@@ -142,19 +94,19 @@ void Texture::unload()
|
|||||||
// Establece el color para la modulacion
|
// Establece el color para la modulacion
|
||||||
void Texture::setColor(Uint8 red, Uint8 green, Uint8 blue)
|
void Texture::setColor(Uint8 red, Uint8 green, Uint8 blue)
|
||||||
{
|
{
|
||||||
SDL_SetTextureColorMod(texture, red, green, blue);
|
this->color = (red << 24) + (green << 16) + (blue << 8) + 255;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Establece el blending
|
// Establece el blending
|
||||||
void Texture::setBlendMode(SDL_BlendMode blending)
|
void Texture::setBlendMode(SDL_BlendMode blending)
|
||||||
{
|
{
|
||||||
SDL_SetTextureBlendMode(texture, blending);
|
//SDL_SetTextureBlendMode(texture, blending);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Establece el alpha para la modulación
|
// Establece el alpha para la modulación
|
||||||
void Texture::setAlpha(Uint8 alpha)
|
void Texture::setAlpha(Uint8 alpha)
|
||||||
{
|
{
|
||||||
SDL_SetTextureAlphaMod(texture, alpha);
|
//SDL_SetTextureAlphaMod(texture, alpha);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Renderiza la textura en un punto específico
|
// Renderiza la textura en un punto específico
|
||||||
@@ -174,13 +126,24 @@ void Texture::render(SDL_Renderer *renderer, int x, int y, SDL_Rect *clip, float
|
|||||||
renderQuad.h = renderQuad.h * zoomH;
|
renderQuad.h = renderQuad.h * zoomH;
|
||||||
|
|
||||||
// Renderiza a pantalla
|
// Renderiza a pantalla
|
||||||
SDL_RenderCopyEx(renderer, texture, clip, &renderQuad, angle, center, flip);
|
//SDL_RenderCopyEx(renderer, texture, clip, &renderQuad, angle, center, flip);
|
||||||
|
|
||||||
|
uint8_t *destSurface = DestSurface::getPixels();
|
||||||
|
int canvasWidth = DestSurface::getWidth();
|
||||||
|
|
||||||
|
int y_inc = 1, y_ini = 0, y_fin = renderQuad.h-1; if (flip && SDL_FLIP_VERTICAL==SDL_FLIP_VERTICAL) { auto tmp=y_ini; y_ini=y_fin; y_fin=tmp; y_inc=-1; }
|
||||||
|
int x_inc = 1, x_ini = 0, x_fin = renderQuad.w-1; if (flip && SDL_FLIP_HORIZONTAL==SDL_FLIP_HORIZONTAL) { auto tmp=x_ini; x_ini=x_fin; x_fin=tmp; x_inc=-1; }
|
||||||
|
for (int yy=y_ini; yy <= y_fin; yy += y_inc) {
|
||||||
|
for (int xx=x_ini; xx <= x_fin; xx += x_inc) {
|
||||||
|
destSurface[ x+xx + y+yy * canvasWidth ] = pixels[ clip->x+xx + clip->y+yy * width ];
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Establece la textura como objetivo de renderizado
|
// Establece la textura como objetivo de renderizado
|
||||||
void Texture::setAsRenderTarget(SDL_Renderer *renderer)
|
void Texture::setAsRenderTarget(SDL_Renderer *renderer)
|
||||||
{
|
{
|
||||||
SDL_SetRenderTarget(renderer, texture);
|
//SDL_SetRenderTarget(renderer, texture);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Obtiene el ancho de la imagen
|
// Obtiene el ancho de la imagen
|
||||||
@@ -204,5 +167,5 @@ bool Texture::reLoad()
|
|||||||
// Obtiene la textura
|
// Obtiene la textura
|
||||||
SDL_Texture *Texture::getSDLTexture()
|
SDL_Texture *Texture::getSDLTexture()
|
||||||
{
|
{
|
||||||
return texture;
|
return nullptr; //texture;
|
||||||
}
|
}
|
||||||
@@ -11,13 +11,14 @@ class Texture
|
|||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
// Objetos y punteros
|
// Objetos y punteros
|
||||||
SDL_Texture *texture; // La textura
|
uint8_t *pixels; // Los pixels de esta textura
|
||||||
SDL_Renderer *renderer; // Renderizador donde dibujar la textura
|
SDL_Renderer *renderer; // Renderizador donde dibujar la textura
|
||||||
|
|
||||||
// Variables
|
// Variables
|
||||||
int width; // Ancho de la imagen
|
int width; // Ancho de la imagen
|
||||||
int height; // Alto de la imagen
|
int height; // Alto de la imagen
|
||||||
std::string path; // Ruta de la imagen de la textura
|
std::string path; // Ruta de la imagen de la textura
|
||||||
|
uint32_t color; // Color para el pintado de 1 bit (sprites y tal)
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// Constructor
|
// Constructor
|
||||||
@@ -27,7 +28,7 @@ public:
|
|||||||
~Texture();
|
~Texture();
|
||||||
|
|
||||||
// Carga una imagen desde un fichero
|
// Carga una imagen desde un fichero
|
||||||
bool loadFromFile(std::string path, SDL_Renderer *renderer, bool verbose = false);
|
bool loadFromFile(std::string path, bool verbose = false);
|
||||||
|
|
||||||
// Crea una textura en blanco
|
// Crea una textura en blanco
|
||||||
bool createBlank(SDL_Renderer *renderer, int width, int height, SDL_TextureAccess = SDL_TEXTUREACCESS_STREAMING);
|
bool createBlank(SDL_Renderer *renderer, int width, int height, SDL_TextureAccess = SDL_TEXTUREACCESS_STREAMING);
|
||||||
|
|||||||
Reference in New Issue
Block a user