demo: Añadido efecto de fuego en el fondo

This commit is contained in:
2023-05-24 21:21:39 +02:00
parent bb6894e297
commit 5fa0c40102
3 changed files with 676 additions and 8 deletions

View File

@@ -15,7 +15,10 @@ Código fuente creado por JailDesigner
#include "units/texture.h" #include "units/texture.h"
#include "units/screen.h" #include "units/screen.h"
#include "units/input.h" #include "units/input.h"
#include "quickcg.h"
using namespace QuickCG;
// Punteros
SDL_Event *event; SDL_Event *event;
SDL_Window *window; SDL_Window *window;
SDL_Renderer *renderer; SDL_Renderer *renderer;
@@ -30,24 +33,36 @@ Text *debugText;
Texture *texture; Texture *texture;
MovingSprite *sprite; MovingSprite *sprite;
// Listas
enum e_fx // Tipos de efectos disponibles para el fondo enum e_fx // Tipos de efectos disponibles para el fondo
{ {
fx_fire, fx_fire,
fx_gradient fx_gradient
}; };
// Variables de uso general
Uint32 ticks = 0; // Variable para la frecuencia de actualización de la lógica del programa Uint32 ticks = 0; // Variable para la frecuencia de actualización de la lógica del programa
Uint32 ticksSpeed = 15; // Variable para la frecuencia de actualización de la lógica del programa const Uint32 ticksSpeed = 15; // Variable para la frecuencia de actualización de la lógica del programa
bool should_exit = false; // Variable para saber si ha terminado el progra,a bool should_exit = false; // Variable para saber si ha terminado el progra,a
int counter = 0; // Contador para lo que se necesite int counter = 0; // Contador para lo que se necesite
string controllerName; // Nombre del primer mando detectado
string inputPressed; // Texto con el último input que se ha pulsado
e_fx fx = fx_fire; // Efecto seleccionado para el fondo
int fxTotal = 2; // Cantidad total de efectos disponibles para el fondo
// Variables para el efecto del degradado
int gradColorMin = 64; // Minimo color más alto del degradado int gradColorMin = 64; // Minimo color más alto del degradado
int gradColorMax = 192; // Minimo color más alto del degradado int gradColorMax = 192; // Minimo color más alto del degradado
int gradCurrentColor = 192; // Color actual más alto del degradado int gradCurrentColor = 192; // Color actual más alto del degradado
int gradBreathDirection = 0; // Indica si gradCurrentColor crece o decrece int gradBreathDirection = 0; // Indica si gradCurrentColor crece o decrece
string controllerName; // Nombre del primer mando detectado
string inputPressed; // Texto con el último input que se ha pulsado // Variables para el efecto de fuego
e_fx fx = fx_gradient; // Efecto seleccionado para el fondo const int fireScreenWidth = 320; // Ancho del efecto de fuego
int fxTotal = 2; // Cantidad total de efectos disponibles para el fondo const int fireScreenHeight = 180; // Alto del efecto de fuego
Uint32 fire[fireScreenHeight][fireScreenWidth]; // Buffer con el fuego
Uint32 buffer[fireScreenHeight][fireScreenWidth]; // Buffer para dibujar en pantalla
ColorRGB palette[256]; // Paleta de color para el fuego
const int fireDesp = 240 - fireScreenHeight + 3; // Fila donde comienza a dibujarse el efecto de fuego
// Inicializa las opciones // Inicializa las opciones
void initOptions(); void initOptions();
@@ -240,6 +255,23 @@ void initSprite()
// Inicializa el efecto de fuego // Inicializa el efecto de fuego
void initFire() void initFire()
{ {
// Inicializa el buffer de fuego
for (int y = 0; y < fireScreenHeight; ++y)
for (int x = 0; x < fireScreenWidth; ++x)
fire[y][x] = 0;
// Inicializa la paleta
for (int x = 0; x < 256; ++x)
{
// HSLtoRGB is used to generate colors:
// Hue goes from 0 to 85: red to yellow
// Saturation is always the maximum: 255
// Lightness is 0..255 for x=0..128, and 255 for x=128..255
ColorRGB color = HSLtoRGB(ColorHSL(x / 3, 255, std::min(255, x * 2)));
// set the palette to the calculated RGB value
// palette[x] = RGBtoINT(color);
palette[x] = color;
}
} }
// Inicializa todo // Inicializa todo
@@ -399,6 +431,18 @@ void updateGradient()
// Actualiza el efecto de fuego // Actualiza el efecto de fuego
void updateFire() void updateFire()
{ {
// randomize the bottom row of the fire buffer
const int w = fireScreenWidth;
const int h = fireScreenHeight;
for (int x = 0; x < w; ++x)
fire[h - 1][x] = abs(32768 + rand()) % 256;
// do the fire calculations for every pixel, from top to bottom
for (int y = 0; y < h - 1; ++y)
for (int x = 0; x < w; ++x)
{
fire[y][x] =
((fire[(y + 1) % h][(x - 1 + w) % w] + fire[(y + 1) % h][(x) % w] + fire[(y + 1) % h][(x + 1) % w] + fire[(y + 2) % h][(x) % w]) * 32) / 129;
}
} }
// Actualiza el efecto de fondo // Actualiza el efecto de fondo
@@ -476,6 +520,13 @@ void renderGradient()
// Dibuja el efecto de fuego // Dibuja el efecto de fuego
void renderFire() void renderFire()
{ {
for (int y = 0; y < fireScreenHeight; ++y)
for (int x = 0; x < fireScreenWidth; ++x)
{
const ColorRGB c = palette[fire[y][x]];
SDL_SetRenderDrawColor(renderer, c.r, c.g, c.b, 255);
SDL_RenderDrawPoint(renderer, x, y + fireDesp);
}
} }
// Dibuja el efecto de fondo // Dibuja el efecto de fondo

428
quickcg.cpp Normal file
View File

@@ -0,0 +1,428 @@
/*
QuickCG 20191227
Copyright (c) 2004-2019, Lode Vandevenne
All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*
QuickCG is an SDL codebase that wraps some of the SDL functionality.
It' used by Lode's Computer Graphics Tutorial to work with simple C++ calls
to demonstrate graphical programs.
QuickCG can handle some things that standard C++ doesn't but that are commonly useful, such as:
-drawing graphics
-a bitmap font
-simplified saving and loading of files
-reading keyboard and mouse input
-playing sound
-color models
-loading images
*/
#include "quickcg.h"
#include <cstdlib>
#include <cmath>
#include <vector>
#include <map>
#include <iostream>
#include <fstream>
namespace QuickCG
{
////////////////////////////////////////////////////////////////////////////////
// COLOR STRUCTS/////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
ColorRGB::ColorRGB(Uint8 r, Uint8 g, Uint8 b)
{
this->r = r;
this->g = g;
this->b = b;
}
ColorRGB::ColorRGB(const ColorRGB8bit &color)
{
this->r = color.r;
this->g = color.g;
this->b = color.b;
}
ColorRGB::ColorRGB()
{
this->r = 0;
this->g = 0;
this->b = 0;
}
ColorRGB8bit::ColorRGB8bit(Uint8 r, Uint8 g, Uint8 b)
{
this->r = r;
this->g = g;
this->b = b;
}
ColorRGB8bit::ColorRGB8bit(const ColorRGB &color)
{
this->r = color.r;
this->g = color.g;
this->b = color.b;
}
ColorRGB8bit::ColorRGB8bit()
{
this->r = 0;
this->g = 0;
this->b = 0;
}
// Add two colors
ColorRGB operator+(const ColorRGB &color, const ColorRGB &color2)
{
ColorRGB c;
c.r = color.r + color2.r;
c.g = color.g + color2.g;
c.b = color.b + color2.b;
return c;
}
// Subtract two colors
ColorRGB operator-(const ColorRGB &color, const ColorRGB &color2)
{
ColorRGB c;
c.r = color.r - color2.r;
c.g = color.g - color2.g;
c.b = color.b - color2.b;
return c;
}
// Multiplies a color with an integer
ColorRGB operator*(const ColorRGB &color, int a)
{
ColorRGB c;
c.r = color.r * a;
c.g = color.g * a;
c.b = color.b * a;
return c;
}
// Multiplies a color with an integer
ColorRGB operator*(int a, const ColorRGB &color)
{
ColorRGB c;
c.r = color.r * a;
c.g = color.g * a;
c.b = color.b * a;
return c;
}
// Divides a color through an integer
ColorRGB operator/(const ColorRGB &color, int a)
{
if (a == 0)
return color;
ColorRGB c;
c.r = color.r / a;
c.g = color.g / a;
c.b = color.b / a;
return c;
}
// Are both colors equal?
bool operator==(const ColorRGB &color, const ColorRGB &color2)
{
return (color.r == color2.r && color.g == color2.g && color.b == color2.b);
}
// Are both colors not equal?
bool operator!=(const ColorRGB &color, const ColorRGB &color2)
{
return (!(color.r == color2.r && color.g == color2.g && color.b == color2.b));
}
ColorHSL::ColorHSL(Uint8 h, Uint8 s, Uint8 l)
{
this->h = h;
this->s = s;
this->l = l;
}
ColorHSL::ColorHSL()
{
this->h = 0;
this->s = 0;
this->l = 0;
}
ColorHSV::ColorHSV(Uint8 h, Uint8 s, Uint8 v)
{
this->h = h;
this->s = s;
this->v = v;
}
ColorHSV::ColorHSV()
{
this->h = 0;
this->s = 0;
this->v = 0;
}
////////////////////////////////////////////////////////////////////////////////
// COLOR CONVERSIONS/////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
/*
Convert colors from one type to another
r=red g=green b=blue h=hue s=saturation l=lightness v=value
Color components from the color structs are Uint8's between 0 and 255
color components used in the calculations are normalized between 0.0-1.0
*/
// Converts an RGB color to HSL color
ColorHSL RGBtoHSL(const ColorRGB &colorRGB)
{
float r, g, b, h = 0, s = 0, l; // this function works with floats between 0 and 1
r = colorRGB.r / 256.0;
g = colorRGB.g / 256.0;
b = colorRGB.b / 256.0;
float maxColor = std::max(r, std::max(g, b));
float minColor = std::min(r, std::min(g, b));
if (minColor == maxColor) // R = G = B, so it's a shade of grey
{
h = 0; // it doesn't matter what value it has
s = 0;
l = r; // doesn't matter if you pick r, g, or b
}
else
{
l = (minColor + maxColor) / 2;
if (l < 0.5)
s = (maxColor - minColor) / (maxColor + minColor);
if (l >= 0.5)
s = (maxColor - minColor) / (2.0 - maxColor - minColor);
if (r == maxColor)
h = (g - b) / (maxColor - minColor);
if (g == maxColor)
h = 2.0 + (b - r) / (maxColor - minColor);
if (b == maxColor)
h = 4.0 + (r - g) / (maxColor - minColor);
h /= 6; // to bring it to a number between 0 and 1
if (h < 0)
h += 1;
}
ColorHSL colorHSL;
colorHSL.h = int(h * 255.0);
colorHSL.s = int(s * 255.0);
colorHSL.l = int(l * 255.0);
return colorHSL;
}
// Converts an HSL color to RGB color
ColorRGB HSLtoRGB(const ColorHSL &colorHSL)
{
float r, g, b, h, s, l; // this function works with floats between 0 and 1
float temp1, temp2, tempr, tempg, tempb;
h = colorHSL.h / 256.0;
s = colorHSL.s / 256.0;
l = colorHSL.l / 256.0;
// If saturation is 0, the color is a shade of grey
if (s == 0)
r = g = b = l;
// If saturation > 0, more complex calculations are needed
else
{
// set the temporary values
if (l < 0.5)
temp2 = l * (1 + s);
else
temp2 = (l + s) - (l * s);
temp1 = 2 * l - temp2;
tempr = h + 1.0 / 3.0;
if (tempr > 1.0)
tempr--;
tempg = h;
tempb = h - 1.0 / 3.0;
if (tempb < 0.0)
tempb++;
// red
if (tempr < 1.0 / 6.0)
r = temp1 + (temp2 - temp1) * 6.0 * tempr;
else if (tempr < 0.5)
r = temp2;
else if (tempr < 2.0 / 3.0)
r = temp1 + (temp2 - temp1) * ((2.0 / 3.0) - tempr) * 6.0;
else
r = temp1;
// green
if (tempg < 1.0 / 6.0)
g = temp1 + (temp2 - temp1) * 6.0 * tempg;
else if (tempg < 0.5)
g = temp2;
else if (tempg < 2.0 / 3.0)
g = temp1 + (temp2 - temp1) * ((2.0 / 3.0) - tempg) * 6.0;
else
g = temp1;
// blue
if (tempb < 1.0 / 6.0)
b = temp1 + (temp2 - temp1) * 6.0 * tempb;
else if (tempb < 0.5)
b = temp2;
else if (tempb < 2.0 / 3.0)
b = temp1 + (temp2 - temp1) * ((2.0 / 3.0) - tempb) * 6.0;
else
b = temp1;
}
ColorRGB colorRGB;
colorRGB.r = int(r * 255.0);
colorRGB.g = int(g * 255.0);
colorRGB.b = int(b * 255.0);
return colorRGB;
}
// Converts an RGB color to HSV color
ColorHSV RGBtoHSV(const ColorRGB &colorRGB)
{
float r, g, b, h = 0.0, s = 0.0, v; // this function works with floats between 0 and 1
r = colorRGB.r / 256.0;
g = colorRGB.g / 256.0;
b = colorRGB.b / 256.0;
float maxColor = std::max(r, std::max(g, b));
float minColor = std::min(r, std::min(g, b));
v = maxColor;
if (maxColor != 0.0) // avoid division by zero when the color is black
{
s = (maxColor - minColor) / maxColor;
}
if (s == 0.0)
{
h = 0.0; // it doesn't matter what value it has
}
else
{
if (r == maxColor)
h = (g - b) / (maxColor - minColor);
if (g == maxColor)
h = 2.0 + (b - r) / (maxColor - minColor);
if (b == maxColor)
h = 4.0 + (r - g) / (maxColor - minColor);
h /= 6.0; // to bring it to a number between 0 and 1
if (h < 0.0)
h++;
}
ColorHSV colorHSV;
colorHSV.h = int(h * 255.0);
colorHSV.s = int(s * 255.0);
colorHSV.v = int(v * 255.0);
return colorHSV;
}
// Converts an HSV color to RGB color
ColorRGB HSVtoRGB(const ColorHSV &colorHSV)
{
float r, g, b, h, s, v; // this function works with floats between 0 and 1
h = colorHSV.h / 256.0;
s = colorHSV.s / 256.0;
v = colorHSV.v / 256.0;
// if saturation is 0, the color is a shade of grey
if (s == 0.0)
r = g = b = v;
// if saturation > 0, more complex calculations are needed
else
{
float f, p, q, t;
int i;
h *= 6.0; // to bring hue to a number between 0 and 6, better for the calculations
i = int(floor(h)); // e.g. 2.7 becomes 2 and 3.01 becomes 3 or 4.9999 becomes 4
f = h - i; // the fractional part of h
p = v * (1.0 - s);
q = v * (1.0 - (s * f));
t = v * (1.0 - (s * (1.0 - f)));
switch (i)
{
case 0:
r = v;
g = t;
b = p;
break;
case 1:
r = q;
g = v;
b = p;
break;
case 2:
r = p;
g = v;
b = t;
break;
case 3:
r = p;
g = q;
b = v;
break;
case 4:
r = t;
g = p;
b = v;
break;
case 5:
r = v;
g = p;
b = q;
break;
default:
r = g = b = 0;
break;
}
}
ColorRGB colorRGB;
colorRGB.r = int(r * 255.0);
colorRGB.g = int(g * 255.0);
colorRGB.b = int(b * 255.0);
return colorRGB;
}
Uint32 RGBtoINT(const ColorRGB &colorRGB)
{
return 65536 * colorRGB.r + 256 * colorRGB.g + colorRGB.b;
}
ColorRGB INTtoRGB(Uint32 colorINT)
{
ColorRGB colorRGB;
colorRGB.r = (colorINT / 65536) % 256;
colorRGB.g = (colorINT / 256) % 256;
colorRGB.b = colorINT % 256;
return colorRGB;
}
}

189
quickcg.h Normal file
View File

@@ -0,0 +1,189 @@
/*
QuickCG 20191227
Copyright (c) 2004-2019, Lode Vandevenne
All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*
QuickCG is an SDL 1.2 codebase that wraps some of the SDL 1.2 functionality.
It's used by Lode's Computer Graphics Tutorial to work with simple function calls
to demonstrate graphical programs. It may or may not be of industrial strength
for games, though I've actually used it for some.
QuickCG can handle some things that standard C++ does not but that are useful, such as:
-drawing graphics
-a bitmap font
-simplified saving and loading of files
-reading keyboard and mouse input
-playing sound
-color models
-loading images
Contact info:
My email address is (puzzle the account and domain together with an @ symbol):
Domain: gmail dot com.
Account: lode dot vandevenne.
*/
#ifndef _quickcg_h_included
#define _quickcg_h_included
#include <SDL2/SDL.h>
#include <string>
#include <sstream>
#include <iomanip>
#include <vector>
#include <algorithm> //std::min and std::max
namespace QuickCG
{
////////////////////////////////////////////////////////////////////////////////
// useful templates//////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
// don't know why, but the standard C++ abs sometimes gives cryptic errors? if so use this :D
template <typename T>
const T template_abs(const T &a)
{
return (a < 0) ? -a : a;
}
// usage: std::string str = valtostr(25454.91654654f);
template <typename T>
std::string valtostr(const T &val)
{
std::ostringstream sstream;
sstream << val;
return sstream.str();
}
// usage: double val = strtoval<double>("465498.654");
template <typename T>
T strtoval(const std::string &s)
{
std::istringstream sstream(s);
T val;
sstream >> val;
return val;
}
// length is decimal precision of the floating point number
template <typename T>
std::string valtostr(const T &val, int length, bool fixed = true)
{
std::ostringstream sstream;
if (fixed)
sstream << std::fixed;
sstream << std::setprecision(length) << val;
return sstream.str();
}
////////////////////////////////////////////////////////////////////////////////
// COLOR STRUCTS/////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
struct ColorRGB8bit;
// a color with 3 components: r, g and b
struct ColorRGB
{
int r;
int g;
int b;
ColorRGB(Uint8 r, Uint8 g, Uint8 b);
ColorRGB(const ColorRGB8bit &color);
ColorRGB();
};
ColorRGB operator+(const ColorRGB &color, const ColorRGB &color2);
ColorRGB operator-(const ColorRGB &color, const ColorRGB &color2);
ColorRGB operator*(const ColorRGB &color, int a);
ColorRGB operator*(int a, const ColorRGB &color);
ColorRGB operator/(const ColorRGB &color, int a);
bool operator==(const ColorRGB &color, const ColorRGB &color2);
bool operator!=(const ColorRGB &color, const ColorRGB &color2);
static const ColorRGB RGB_Black(0, 0, 0);
static const ColorRGB RGB_Red(255, 0, 0);
static const ColorRGB RGB_Green(0, 255, 0);
static const ColorRGB RGB_Blue(0, 0, 255);
static const ColorRGB RGB_Cyan(0, 255, 255);
static const ColorRGB RGB_Magenta(255, 0, 255);
static const ColorRGB RGB_Yellow(255, 255, 0);
static const ColorRGB RGB_White(255, 255, 255);
static const ColorRGB RGB_Gray(128, 128, 128);
static const ColorRGB RGB_Grey(192, 192, 192);
static const ColorRGB RGB_Maroon(128, 0, 0);
static const ColorRGB RGB_Darkgreen(0, 128, 0);
static const ColorRGB RGB_Navy(0, 0, 128);
static const ColorRGB RGB_Teal(0, 128, 128);
static const ColorRGB RGB_Purple(128, 0, 128);
static const ColorRGB RGB_Olive(128, 128, 0);
// a color with 3 components: r, g and b
struct ColorRGB8bit
{
Uint8 r;
Uint8 g;
Uint8 b;
ColorRGB8bit(Uint8 r, Uint8 g, Uint8 b);
ColorRGB8bit(const ColorRGB &color);
ColorRGB8bit();
};
// a color with 3 components: h, s and l
struct ColorHSL
{
int h;
int s;
int l;
ColorHSL(Uint8 h, Uint8 s, Uint8 l);
ColorHSL();
};
// a color with 3 components: h, s and v
struct ColorHSV
{
int h;
int s;
int v;
ColorHSV(Uint8 h, Uint8 s, Uint8 v);
ColorHSV();
};
////////////////////////////////////////////////////////////////////////////////
// COLOR CONVERSIONS/////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
ColorHSL RGBtoHSL(const ColorRGB &colorRGB);
ColorRGB HSLtoRGB(const ColorHSL &colorHSL);
ColorHSV RGBtoHSV(const ColorRGB &colorRGB);
ColorRGB HSVtoRGB(const ColorHSV &colorHSV);
Uint32 RGBtoINT(const ColorRGB &colorRGB);
ColorRGB INTtoRGB(Uint32 colorINT);
}
#endif