8 Commits

11 changed files with 223 additions and 83 deletions

View File

@@ -9,6 +9,7 @@ windowsRelease = $(executable)-$(version)-win32-x64.zip
macosIntelRelease = $(executable)-$(version)-macos-intel.dmg
macosAppleSiliconRelease = $(executable)-$(version)-macos-apple-silicon.dmg
linuxRelease = $(executable)-$(version)-linux.tar.gz
opendinguxRelease = $(executable).opk
windows:
@echo off
@@ -140,3 +141,32 @@ linux_release:
# Remove data
rm -rdf "$(releaseFolder)"
opendingux:
/opt/gcw0-toolchain/usr/bin/mipsel-linux-g++ -D GCWZERO -I/opt/gcw0-toolchain/usr/mipsel-gcw0-linux-uclibc/sysroot/usr/include/SDL2 -D_GNU_SOURCE=1 -D_REENTRANT -lSDL2 -lSDL2_mixer -lstdc++ -std=c++11 $(source) -o "$(executable)"
opendingux_release:
# Remove data
rm -rdf "$(releaseFolder)"
# Create folders
mkdir -p "$(releaseFolder)"
# Copy data
cp -R data "$(releaseFolder)"
cp -R default.gcw0.desktop "$(releaseFolder)"
cp -R icon.png "$(releaseFolder)"
# Delete data
rm -f "$(releaseFolder)/data/room/map.world"
rm -f "$(releaseFolder)/data/room/standard.tsx"
# Build
/opt/gcw0-toolchain/usr/bin/mipsel-linux-g++ -D GCWZERO -I/opt/gcw0-toolchain/usr/mipsel-gcw0-linux-uclibc/sysroot/usr/include/SDL2 -D_GNU_SOURCE=1 -D_REENTRANT -lSDL2 -lSDL2_mixer -lstdc++ -std=c++11 $(source) -o "$(releaseFolder)/$(executable)"
# Pack files
rm -f "$(opendinguxRelease)"
cd "$(releaseFolder)" && /opt/gcw0-toolchain/usr/bin/mksquashfs ./default.gcw0.desktop ./icon.png ./data ./$(executable) "../$(opendinguxRelease)" -all-root -noappend -no-exports -no-xattrs
# Remove data
rm -rdf "$(releaseFolder)"

3
build.txt Normal file
View File

@@ -0,0 +1,3 @@
/opt/gcw0-toolchain/usr/bin/mipsel-linux-g++ -D GCWZERO -I/opt/gcw0-toolchain/usr/mipsel-gcw0-linux-uclibc/sysroot/usr/include/SDL2 -D_GNU_SOURCE=1 -D_REENTRANT -lSDL2 -lstdc++ -std=c++11 source/*.cpp source/common/*.cpp -o jdd
sftp root@10.1.1.2:jdd <<< $'put jdd'
ssh root@10.1.1.2

10
default.gcw0.desktop Normal file
View File

@@ -0,0 +1,10 @@
[Desktop Entry]
Version=1.6
Type=Application
Name=JailDoctor's Dilemma
Comment=JailDoctor's Dilemma
Icon=icon
Exec=jaildoctors_dilemma
Categories=games;Game;SDL;
Terminal=false

BIN
icon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 873 B

View 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;
}
}

View 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();
}

View File

@@ -1,6 +1,8 @@
#include "screen.h"
#include <string>
#include <iostream>
#include "destsurface.h"
#include "systempalette.h"
// Constructor
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};
// 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 (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
setVideoMode(options->videoMode);
@@ -53,26 +57,34 @@ Screen::~Screen()
// Limpia la pantalla
void Screen::clean(color_t color)
{
SDL_SetRenderDrawColor(renderer, color.r, color.g, color.b, 0xFF);
SDL_RenderClear(renderer);
DestSurface::clear((color.r<<24) + (color.g<<16) + (color.b<<8) + 255);
}
// Prepara para empezar a dibujar en la textura de juego
void Screen::start()
{
SDL_SetRenderTarget(renderer, gameCanvas);
//SDL_SetRenderTarget(renderer, gameCanvas);
}
// Vuelca el contenido del renderizador en pantalla
void Screen::blit()
{
// Vuelve a dejar el renderizador en modo normal
SDL_SetRenderTarget(renderer, nullptr);
//SDL_SetRenderTarget(renderer, nullptr);
// Borra el contenido previo
SDL_SetRenderDrawColor(renderer, borderColor.r, borderColor.g, borderColor.b, 0xFF);
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
SDL_RenderCopy(renderer, gameCanvas, nullptr, &dest);

View 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];
}
}

View 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);
}

View File

@@ -3,6 +3,8 @@
#define STB_IMAGE_IMPLEMENTATION
#include "stb_image.h"
#include <iostream>
#include "systempalette.h"
#include "destsurface.h"
// Constructor
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;
// Inicializa
texture = nullptr;
width = 0;
height = 0;
this->pixels = nullptr;
this->width = 0;
this->height = 0;
this->color = 0xffffffff;
// Carga el fichero en la textura
if (path != "")
{
loadFromFile(path, renderer, verbose);
loadFromFile(path, verbose);
}
}
@@ -31,7 +34,7 @@ Texture::~Texture()
}
// 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);
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
unload();
// La textura final
SDL_Texture *newTexture = nullptr;
// Carga la imagen desde una ruta específica
SDL_Surface *loadedSurface = SDL_CreateRGBSurfaceWithFormatFrom((void *)data, width, height, depth, pitch, pixel_format);
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);
}
this->width = width;
this->height = height;
const int size = width*height;
this->pixels = new uint8_t[size];
for (int i = 0; i < size; ++i) this->pixels[i] = SystemPalette::getEntry(data[i]);
// Return success
stbi_image_free(data);
texture = newTexture;
return texture != nullptr;
return this->pixels != nullptr;
}
// Crea una textura en blanco
bool Texture::createBlank(SDL_Renderer *renderer, int width, int height, SDL_TextureAccess access)
{
// Crea una textura sin inicializar
texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA8888, access, width, height);
if (texture == nullptr)
{
std::cout << "Unable to create blank texture! SDL Error: " << SDL_GetError() << std::endl;
}
else
{
this->pixels = new uint8_t[width*height];
this->width = width;
this->height = height;
}
return texture != nullptr;
return this->pixels != nullptr;
}
// Libera la memoria de la textura
void Texture::unload()
{
// Libera la textura si existe
if (texture != nullptr)
if (pixels != nullptr)
{
SDL_DestroyTexture(texture);
texture = nullptr;
delete[] pixels;
pixels = nullptr;
width = 0;
height = 0;
}
@@ -142,19 +94,19 @@ void Texture::unload()
// Establece el color para la modulacion
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
void Texture::setBlendMode(SDL_BlendMode blending)
{
SDL_SetTextureBlendMode(texture, blending);
//SDL_SetTextureBlendMode(texture, blending);
}
// Establece el alpha para la modulación
void Texture::setAlpha(Uint8 alpha)
{
SDL_SetTextureAlphaMod(texture, alpha);
//SDL_SetTextureAlphaMod(texture, alpha);
}
// 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;
// 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
void Texture::setAsRenderTarget(SDL_Renderer *renderer)
{
SDL_SetRenderTarget(renderer, texture);
//SDL_SetRenderTarget(renderer, texture);
}
// Obtiene el ancho de la imagen
@@ -204,5 +167,5 @@ bool Texture::reLoad()
// Obtiene la textura
SDL_Texture *Texture::getSDLTexture()
{
return texture;
return nullptr; //texture;
}

View File

@@ -11,13 +11,14 @@ class Texture
{
private:
// Objetos y punteros
SDL_Texture *texture; // La textura
uint8_t *pixels; // Los pixels de esta textura
SDL_Renderer *renderer; // Renderizador donde dibujar la textura
// Variables
int width; // Ancho de la imagen
int height; // Alto de la imagen
std::string path; // Ruta de la imagen de la textura
uint32_t color; // Color para el pintado de 1 bit (sprites y tal)
public:
// Constructor
@@ -27,7 +28,7 @@ public:
~Texture();
// 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
bool createBlank(SDL_Renderer *renderer, int width, int height, SDL_TextureAccess = SDL_TEXTUREACCESS_STREAMING);